dsh-mobile 0.3.0 → 0.3.2
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/CHANGELOG.md +14 -0
- package/README.en.md +13 -8
- package/README.md +13 -8
- package/THIRD_PARTY_NOTICES.md +2 -0
- package/bin/dsh-mobile-funnel-win32-x64.exe +0 -0
- package/lib/client.js +2321 -412
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +32 -9
- package/lib/index.mjs +500 -114
- package/lib/mobile-layout.js +54 -10
- package/lib/mobile-layout.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["createElement"],"sources":["../src/native-mobile.ts","../src/client.ts"],"sourcesContent":["/** Mobile feature and compatibility rules applied to DSH React surfaces. */\nexport const NATIVE_MOBILE_STYLES = `\n@media (max-width:720px) {\n html.dsh-native-mobile-active,html.dsh-native-mobile-active body { width:100%; height:100%; overflow:hidden; }\n html.dsh-native-mobile-active { --dsh-mobile-motion-duration:200ms; --dsh-mobile-motion-ease:cubic-bezier(.22,1,.36,1); }\n html.dsh-native-mobile-active :is(a,button,[role=\"button\"],[role=\"tab\"],[tabindex]) { -webkit-tap-highlight-color:transparent; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [role=\"treeitem\"] { -webkit-tap-highlight-color:transparent; touch-action:manipulation; }\n html.dsh-native-mobile-active[data-dsh-mobile-input=\"touch\"] :is(a,button,[role=\"button\"],[role=\"tab\"],[tabindex]):focus { outline:none !important; }\n html.dsh-native-mobile-active [role=\"tooltip\"] { display:none !important; }\n /* Touch has no persistent hover affordance: keep workspace rows neutral after a tap. */\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] { --dsw-alias-interactive-bg-hover:transparent !important; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [role=\"treeitem\"]:is(:hover,:active,:focus,[aria-selected=\"true\"]),\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_sessionRow\"][class*=\"_selected\"],\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_searchResultRow\"][class*=\"_selected\"] { background:transparent !important; outline:0 !important; box-shadow:none !important; }\n /* Sidebar row menus are hover-only on desktop. Touch has no hover, so keep\n the ellipsis action visible and give it a reliable hit target. */\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_rowActions\"] { display:inline-flex !important; align-items:center !important; gap:8px !important; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_sessionRow\"] [class*=\"_time\"] { display:none !important; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_rowActions\"] button { box-sizing:border-box !important; width:32px !important; min-width:32px !important; height:32px !important; min-height:32px !important; }\n [data-dsh-mobile-frame] { grid-template-columns:0 minmax(0,1fr) 0 !important; width:100% !important; height:100dvh !important; overflow:hidden !important; }\n [data-dsh-mobile-center] { grid-column:2 !important; width:100vw !important; min-width:0 !important; }\n [data-dsh-mobile-center] > * { min-width:0 !important; }\n [data-dsh-mobile-header] { box-sizing:border-box !important; width:calc(100% - 16px) !important; margin:0 8px !important; min-width:0; padding-top:max(4px,env(safe-area-inset-top)) !important; padding-right:8px !important; padding-left:42px !important; }\n [data-dsh-mobile-header] [class*=\"_titleRow\"] { box-sizing:border-box !important; display:flex !important; align-items:center !important; min-width:0; min-height:32px !important; height:32px !important; gap:6px !important; padding:0 6px !important; }\n [data-dsh-mobile-header] [class*=\"_titleCluster\"] { min-width:0; }\n [data-dsh-mobile-header] [class*=\"_crumbs\"] { min-width:0; overflow:hidden; }\n [data-dsh-mobile-header] [class*=\"_crumb\"] { max-width:46vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n [data-dsh-mobile-header] [class*=\"_headerActions\"] { min-width:0; overflow-x:auto; scrollbar-width:none; }\n [data-dsh-mobile-header] [class*=\"_headerActions\"]::-webkit-scrollbar { display:none; }\n [data-dsh-mobile-header] [class*=\"_headerUtilities\"] { gap:2px !important; }\n [data-dsh-mobile-header] [class*=\"_sessionLogButton\"] { width:40px; min-width:40px; padding:0 !important; overflow:hidden; color:transparent; font-size:0 !important; }\n [data-dsh-mobile-header] [class*=\"_sessionLogButton\"] > * { display:none !important; }\n [data-dsh-mobile-header] [class*=\"_sessionLogButton\"]::after { color:var(--dsw-text, #171a21); content:\"日志\"; font-size:11px; font-weight:600; }\n [data-dsh-mobile-header] [class*=\"_tabs\"] { box-sizing:border-box !important; width:max-content !important; max-width:calc(100% - 58px) !important; min-height:28px !important; height:28px !important; margin-top:0 !important; padding-left:6px !important; padding-right:6px !important; overflow-x:auto; scrollbar-width:none; }\n [data-dsh-mobile-header] [class*=\"_tab\"] { padding-bottom:5px !important; }\n [data-dsh-mobile-header] [class*=\"_tabs\"]::-webkit-scrollbar { display:none; }\n [data-dsh-mobile-sidebar] { position:fixed !important; z-index:240 !important; inset:0 auto 0 0 !important; width:0 !important; overflow:visible !important; }\n [data-dsh-mobile-sidebar-root] { position:fixed !important; z-index:241 !important; inset:max(env(safe-area-inset-top),0px) auto 0 0 !important; height:auto !important; transition:width 180ms var(--dsh-mobile-motion-ease),box-shadow 180ms ease !important; }\n [data-dsh-mobile-sidebar][data-open=\"true\"] [data-dsh-mobile-sidebar-root] { width:min(88vw,340px) !important; padding-top:0 !important; box-shadow:18px 0 46px rgb(15 23 42 / 18%); }\n [data-dsh-mobile-sidebar][data-open=\"true\"] [data-dsh-mobile-sidebar-root] [class*=\"_logoRow\"] { height:52px !important; padding:4px 0 4px 4px !important; margin-bottom:4px !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] { width:0 !important; border:0 !important; background:transparent !important; box-shadow:none !important; overflow:visible !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] > :not(:has([data-dsh-mobile-toggle])) { display:none !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] > :has([data-dsh-mobile-toggle]) { position:fixed !important; z-index:244 !important; top:env(safe-area-inset-top) !important; left:0 !important; box-sizing:border-box !important; width:50px !important; height:52px !important; padding:4px !important; border:0 !important; background:transparent !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] > :has([data-dsh-mobile-toggle]) > :not([data-dsh-mobile-toggle]) { display:none !important; }\n [data-dsh-mobile-toggle] { width:44px !important; height:44px !important; min-width:44px !important; min-height:44px !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-toggle] > svg[class*=\"_railFish\"] { transform:translateY(-4px) !important; }\n .dsh-native-mobile-backdrop { position:fixed; z-index:235; inset:env(safe-area-inset-top) 0 0; border:0; background:rgb(15 23 42 / 32%); }\n .dsh-native-mobile-backdrop:not([hidden]) { animation:dsh-mobile-fade-in var(--dsh-mobile-motion-duration) ease-out; }\n .dsh-native-mobile-backdrop[hidden] { display:none; }\n [data-dsh-mobile-details] { position:fixed !important; z-index:250 !important; inset:0 0 0 auto !important; width:min(94vw,460px) !important; max-width:none !important; transform:translateX(100%); transition:transform var(--dsh-mobile-motion-duration) var(--dsh-mobile-motion-ease); background:var(--dsw-bg, #fff); box-shadow:-18px 0 46px rgb(15 23 42 / 18%); }\n [data-dsh-mobile-details][data-open=\"true\"] { transform:translateX(0); }\n [data-dsh-mobile-handle] { display:none !important; }\n [data-dsh-mobile-settings] { flex-direction:column !important; width:100vw !important; height:100dvh !important; max-width:none !important; border-radius:0 !important; animation:dsh-mobile-panel-in var(--dsh-mobile-motion-duration) var(--dsh-mobile-motion-ease); }\n [data-dsh-mobile-settings-nav] { flex:none !important; width:100% !important; padding:max(14px,env(safe-area-inset-top)) 12px 8px !important; gap:10px !important; border-bottom:1px solid var(--dsw-alias-border-subtle,#e8ebef); }\n [data-dsh-mobile-settings-nav] [class*=\"_navTitle\"] { padding:0 8px !important; font-size:18px !important; line-height:28px !important; }\n [data-dsh-mobile-settings-list] { flex-direction:row !important; gap:4px !important; overflow-x:auto !important; scrollbar-width:none; }\n [data-dsh-mobile-settings-list]::-webkit-scrollbar { display:none; }\n [data-dsh-mobile-settings-list] [class*=\"_navCell\"] { flex:0 0 auto !important; min-width:max-content !important; height:44px !important; padding:10px 12px !important; }\n [data-dsh-mobile-settings-list] [aria-current=\"true\"] { border-color:transparent !important; outline:0 !important; box-shadow:none !important; }\n [data-dsh-mobile-settings-content] { flex:1 1 auto !important; width:100% !important; min-height:0 !important; }\n [data-dsh-mobile-settings-header] { height:48px !important; min-height:48px !important; padding:10px 12px 6px !important; }\n [data-dsh-mobile-settings-header] [class*=\"_close\"] { width:36px !important; height:36px !important; }\n [data-dsh-mobile-settings-options] { box-sizing:border-box !important; width:100% !important; padding:4px 16px max(24px,env(safe-area-inset-bottom)) !important; overflow-x:hidden !important; }\n [data-dsh-mobile-settings-options] > * { width:100% !important; min-width:0 !important; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] > [class*=\"_row\"] { flex-direction:column !important; align-items:stretch !important; gap:12px !important; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] [class*=\"_rowText\"] { width:100% !important; padding-right:0 !important; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] [class*=\"_selector\"] { box-sizing:border-box !important; align-self:flex-start !important; justify-content:space-between !important; min-width:0 !important; min-height:44px !important; max-width:100% !important; }\n [data-dsh-mobile-settings-options] :is(input,select,textarea,button) { max-width:100%; }\n [data-dsh-mobile-settings-options] :is(input,select,textarea) { box-sizing:border-box; width:100%; min-width:0; }\n [data-dsh-mobile-settings-options] [class*=\"_head\"] { min-width:0; flex-wrap:wrap; }\n /* Provider names may shrink, but their edit/delete actions remain horizontal\n and retain a full touch target on narrow screens. */\n [data-dsh-mobile-settings-options] [class*=\"_rowHead\"]:has(> [class*=\"_rowIdentity\"]) { flex-wrap:nowrap !important; align-items:center !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowIdentity\"] { flex:1 1 auto !important; min-width:0 !important; overflow:hidden !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowName\"] { min-width:0 !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowActions\"] { flex:0 0 auto !important; flex-wrap:nowrap !important; width:max-content !important; min-width:max-content !important; max-width:none !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowActions\"] button { flex:none !important; width:auto !important; min-width:44px !important; max-width:none !important; min-height:44px !important; padding-inline:10px !important; white-space:nowrap !important; word-break:keep-all !important; writing-mode:horizontal-tb !important; }\n [data-dsh-mobile-settings-content][data-dsh-mobile-view-transition=\"true\"],\n [data-dsh-mobile-view][data-dsh-mobile-view-transition=\"true\"] { animation:dsh-mobile-view-in var(--dsh-mobile-motion-duration) var(--dsh-mobile-motion-ease); }\n [data-dsh-mobile-center] textarea { font-size:16px !important; }\n /* Markdown tables use content-sized columns. Small tables fill the phone;\n wider tables keep readable cells and scroll inside their own region. */\n [data-dsh-mobile-table-scroll] { box-sizing:border-box; width:100%; max-width:100%; overflow-x:auto; overscroll-behavior-x:contain; -webkit-overflow-scrolling:touch; }\n [data-dsh-mobile-table-scroll] table { display:table !important; width:max-content !important; min-width:100% !important; max-width:none !important; table-layout:auto !important; }\n [data-dsh-mobile-table-scroll] :is(th,td) { box-sizing:border-box; min-width:8ch; max-width:32ch; overflow-wrap:anywhere; word-break:break-word; vertical-align:top; }\n [data-dsh-mobile-center] pre { max-width:100%; overflow-x:auto; }\n [data-dsh-mobile-center] :is(img,video,canvas,svg) { max-width:100%; }\n [data-dsh-mobile-message-scroll] { box-sizing:border-box !important; width:100% !important; padding:8px 10px 20px !important; }\n [data-dsh-mobile-history-loader] { position:relative !important; min-height:1px !important; }\n [data-dsh-mobile-history-loader] button:not(:disabled) { position:absolute !important; width:1px !important; height:1px !important; margin:-1px !important; padding:0 !important; clip-path:inset(50%) !important; opacity:0 !important; overflow:hidden !important; pointer-events:none !important; }\n [data-dsh-mobile-history-loader] button:disabled { min-height:28px !important; padding:4px 12px !important; }\n [data-dsh-mobile-message-column] { box-sizing:border-box !important; width:100% !important; max-width:none !important; margin:0 !important; padding:0 !important; gap:10px !important; }\n [data-dsh-mobile-message-column] > * { width:100% !important; max-width:100% !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] { box-sizing:border-box !important; display:grid !important; grid-template-columns:16px minmax(0,1fr) !important; grid-auto-rows:auto !important; align-items:center !important; column-gap:6px !important; width:100% !important; height:auto !important; min-height:40px !important; padding:4px 0 !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > [class*=\"_leading\"] { grid-column:1 !important; grid-row:1 !important; margin-right:0 !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > [class*=\"_title\"] { grid-column:2 !important; grid-row:1 !important; min-width:0 !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > :is([class*=\"_sep\"],[class*=\"_separator\"]) { display:none !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > :is([class*=\"_summary\"],[class*=\"_fileLink\"]) { grid-column:2 !important; grid-row:2 !important; width:100% !important; min-width:0 !important; max-width:100% !important; overflow:hidden !important; line-height:19px !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > [class*=\"_summarySuffix\"] { grid-column:2 !important; grid-row:3 !important; margin-left:0 !important; }\n [data-dsh-mobile-message-column] [data-context-fields] > * { display:grid !important; grid-template-columns:minmax(72px,30%) minmax(0,1fr) !important; gap:4px 10px !important; }\n [data-dsh-mobile-message-column] [class*=\"_ioSection\"] { grid-template-columns:1fr !important; row-gap:4px !important; }\n [data-dsh-mobile-message-column] [class*=\"_body\"] { max-width:100% !important; overflow-wrap:anywhere; }\n [data-dsh-mobile-center] [data-composer-card] ~ [class*=\"_root\"],\n [data-dsh-mobile-center] [data-composer-card] ~ * [class*=\"_root\"] { box-sizing:border-box !important; width:100% !important; max-width:100% !important; margin-bottom:-6px !important; padding:3px 4px 0 !important; font-size:11px !important; line-height:18px !important; white-space:normal !important; overflow:visible !important; text-overflow:clip !important; }\n [data-dsh-mobile-center] [data-composer-card] ~ [class*=\"_root\"] [class*=\"_sep\"],\n [data-dsh-mobile-center] [data-composer-card] ~ * [class*=\"_root\"] [class*=\"_sep\"] { margin:0 6px !important; }\n /* Message runtime details are inline on desktop. Give the clock/runtime\n label its own wrapping row on narrow screens so TTFT and throughput do\n not push the action buttons or clip at the viewport edge. */\n [data-dsh-mobile-center] [class*=\"_actions\"]:has(> [class*=\"_timeStart\"]),\n [data-dsh-mobile-center] [class*=\"_actions\"]:has(> [class*=\"_timeEnd\"]) { box-sizing:border-box !important; width:100% !important; flex-wrap:wrap !important; justify-content:flex-end !important; height:auto !important; min-height:28px !important; row-gap:2px !important; }\n [data-dsh-mobile-center] [class*=\"_timeStart\"],\n [data-dsh-mobile-center] [class*=\"_timeEnd\"] { box-sizing:border-box !important; flex:1 1 100% !important; order:2 !important; min-width:0 !important; max-width:100% !important; padding:0 !important; line-height:20px !important; text-align:center !important; white-space:normal !important; overflow-wrap:anywhere !important; }\n [data-dsh-mobile-center] [class*=\"_timeStart\"] { box-sizing:border-box !important; flex:1 1 100% !important; order:2 !important; min-width:0 !important; max-width:100% !important; padding:0 !important; line-height:20px !important; text-align:center !important; white-space:normal !important; overflow-wrap:anywhere !important; }\n [data-dsh-mobile-center] [class*=\"_timeStart\"] [class*=\"_runTimeDot\"],\n [data-dsh-mobile-center] [class*=\"_timeEnd\"] [class*=\"_runTimeDot\"] { margin:0 6px !important; }\n /* Keep the context meter's legend rows as readable label/value pairs.\n Generic mobile flex rules can otherwise place the rows side by side and\n break Chinese labels in the middle of a word. */\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"],\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] { width:min(264px,calc(100vw - 32px)) !important; min-width:0 !important; max-width:calc(100vw - 32px) !important; }\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"] [class*=\"_rows\"],\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] [class*=\"_rows\"] { display:block !important; }\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"] [class*=\"_rows\"] > [class*=\"_row\"],\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] [class*=\"_rows\"] > [class*=\"_row\"] { display:flex !important; align-items:center !important; justify-content:space-between !important; width:100% !important; min-width:0 !important; white-space:nowrap !important; }\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"] :is(dt,dd),\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] :is(dt,dd) { white-space:nowrap !important; word-break:keep-all !important; }\n .dsh-mobile-branch-toast { position:fixed; z-index:300; top:max(12px,env(safe-area-inset-top)); left:50%; max-width:calc(100vw - 32px); box-sizing:border-box; padding:7px 14px; border:1px solid rgb(15 23 42 / 10%); border-radius:999px; background:rgb(15 23 42 / 92%); color:#fff; font-size:13px; line-height:20px; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; opacity:0; pointer-events:none; transform:translate(-50%,-8px); transition:opacity 160ms ease,transform 160ms ease; }\n .dsh-mobile-branch-toast[data-visible=\"true\"] { opacity:1; transform:translate(-50%,0); }\n [data-dsh-mobile-center] [class*=\"_composer\"] { padding-left:8px !important; padding-right:8px !important; padding-bottom:max(8px,env(safe-area-inset-bottom)) !important; }\n /* The desktop composer intentionally wraps whole toolbar groups. On a phone,\n dynamic model and status labels made that row alternate between one and\n two lines. Keep two stable columns and let only the model label shrink. */\n [data-dsh-mobile-composer-row] { display:grid !important; grid-template-columns:max-content minmax(0,1fr) !important; align-items:center !important; gap:4px 8px !important; }\n [data-dsh-mobile-composer-tools] { display:flex !important; flex-wrap:nowrap !important; width:max-content !important; min-width:0 !important; max-width:max-content !important; gap:6px !important; }\n [data-dsh-mobile-composer-trailing] { display:flex !important; flex-wrap:nowrap !important; width:100% !important; min-width:0 !important; max-width:100% !important; gap:6px !important; margin-left:0 !important; justify-content:flex-end !important; }\n [data-dsh-mobile-composer-model] { flex:1 1 0 !important; width:auto !important; min-width:0 !important; max-width:none !important; }\n [data-dsh-mobile-composer-model-trigger] { box-sizing:border-box !important; width:100% !important; max-width:100% !important; min-width:0 !important; padding-left:6px !important; padding-right:4px !important; }\n [data-dsh-mobile-composer-model-label] { flex:1 1 auto !important; max-width:none !important; min-width:0 !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-center] [class*=\"_root\"]:has(> [class*=\"_card\"] textarea) { box-sizing:border-box !important; width:100% !important; padding:0 0 8px !important; }\n [data-dsh-mobile-center] [class*=\"_root\"]:has(> [class*=\"_card\"] textarea) > [class=\"\"]:last-child { display:none !important; }\n}\n@keyframes dsh-mobile-fade-in { from { opacity:0; } }\n@keyframes dsh-mobile-panel-in { from { opacity:.72; transform:translateY(6px); } }\n@keyframes dsh-mobile-view-in { from { opacity:.58; transform:translateY(5px); } }\n@media (max-width:420px) {\n [data-dsh-mobile-header] [class*=\"_headerActions\"] { max-width:42vw; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] [class*=\"_selector\"] { align-self:stretch !important; width:100% !important; }\n [data-dsh-mobile-message-column] [data-context-fields] > * { grid-template-columns:1fr !important; }\n}\n@media (prefers-reduced-motion:reduce) {\n [data-dsh-mobile-sidebar-root],[data-dsh-mobile-details] { transition:none !important; }\n .dsh-native-mobile-backdrop:not([hidden]),[data-dsh-mobile-settings],\n [data-dsh-mobile-settings-content][data-dsh-mobile-view-transition=\"true\"],\n [data-dsh-mobile-view][data-dsh-mobile-view-transition=\"true\"] { animation:none !important; }\n}\n`\n\nfunction classToken(element: Element, suffix: string): boolean {\n return Array.from(element.classList).some(value => value.endsWith(suffix))\n}\n\nfunction firstByClassSuffix(root: ParentNode, suffix: string): HTMLElement | undefined {\n return Array.from(root.querySelectorAll<HTMLElement>('[class]')).find(element => classToken(element, suffix))\n}\n\nconst AUTO_HISTORY_THRESHOLD_PX = 64\n\n/** Whether a user-driven scroll moved upward into the automatic history-loading zone. */\nexport function shouldAutoLoadEarlier(previousTop: number, currentTop: number): boolean {\n return currentTop <= AUTO_HISTORY_THRESHOLD_PX && currentTop < previousTop - 0.5\n}\n\n/** Add mobile semantics without replacing feature trees. */\nexport function installNativeMobileSurface(): () => void {\n document.documentElement.classList.add('dsh-native-mobile-active')\n const setInputMode = (mode: 'keyboard' | 'touch'): void => {\n document.documentElement.dataset.dshMobileInput = mode\n }\n const onPointerDown = (event: PointerEvent): void => {\n if (event.pointerType === 'touch' || event.pointerType === 'pen') setInputMode('touch')\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Tab' || event.key.startsWith('Arrow')) setInputMode('keyboard')\n }\n document.addEventListener('pointerdown', onPointerDown, true)\n document.addEventListener('keydown', onKeyDown, true)\n const backdrop = document.createElement('button')\n backdrop.type = 'button'\n backdrop.className = 'dsh-native-mobile-backdrop'\n backdrop.hidden = true\n backdrop.setAttribute('aria-label', '关闭工作区导航')\n document.body.append(backdrop)\n const branchToast = document.createElement('div')\n branchToast.className = 'dsh-mobile-branch-toast'\n branchToast.setAttribute('role', 'status')\n branchToast.setAttribute('aria-live', 'polite')\n document.body.append(branchToast)\n let branchToastTimer = 0\n const showBranchToast = (): void => {\n const header = document.querySelector<HTMLElement>('[data-dsh-mobile-header]')\n const title = header === null ? undefined : header.querySelector<HTMLElement>('[class*=\"_crumbCurrent\"]')?.textContent?.trim()\n branchToast.textContent = title === undefined ? '当前分支' : `当前分支:${title}`\n branchToast.dataset.visible = 'true'\n if (branchToastTimer !== 0) window.clearTimeout(branchToastTimer)\n branchToastTimer = window.setTimeout(() => {\n branchToast.removeAttribute('data-visible')\n branchToastTimer = 0\n }, 1600)\n }\n const onBranchClick = (event: MouseEvent): void => {\n if (!(event.target instanceof Element)) return\n const branch = event.target.closest<HTMLButtonElement>('button[aria-label*=\"分支\"],button[aria-label*=\"Branch\"],button[aria-label*=\"branch\"]')\n if (branch === null || branch.hasAttribute('disabled') || branch.getAttribute('aria-disabled') === 'true') return\n window.setTimeout(showBranchToast, 80)\n }\n document.addEventListener('click', onBranchClick, true)\n let frame: HTMLElement | undefined\n let sidebar: HTMLElement | undefined\n let sidebarRoot: HTMLElement | undefined\n let toggle: HTMLButtonElement | undefined\n let viewArea: HTMLElement | undefined\n let scheduled = 0\n let transitionFrame = 0\n let transitionRestartFrame = 0\n let transitionTimer = 0\n let transitionTarget: HTMLElement | undefined\n let historyScroller: HTMLElement | undefined\n let historyPreviousTop = 0\n const historyLoadButton = (): HTMLButtonElement | undefined => {\n const loader = historyScroller === undefined ? undefined : firstByClassSuffix(historyScroller, '_older')\n return loader?.querySelector<HTMLButtonElement>('button') ?? undefined\n }\n const onHistoryScroll = (): void => {\n if (historyScroller === undefined) return\n const currentTop = Math.max(0, historyScroller.scrollTop)\n const shouldLoad = shouldAutoLoadEarlier(historyPreviousTop, currentTop)\n historyPreviousTop = currentTop\n if (!shouldLoad) return\n const button = historyLoadButton()\n if (button === undefined || button.disabled || button.getAttribute('aria-disabled') === 'true') return\n button.click()\n }\n const bindHistoryScroller = (next: HTMLElement | undefined): void => {\n if (historyScroller === next) return\n historyScroller?.removeEventListener('scroll', onHistoryScroll)\n historyScroller = next\n historyPreviousTop = next?.scrollTop ?? 0\n historyScroller?.addEventListener('scroll', onHistoryScroll, { passive: true })\n }\n const animateNavigation = (event: MouseEvent): void => {\n if (!(event.target instanceof Element)) return\n const trigger = event.target.closest<HTMLElement>('button,a,[role=\"tab\"],[aria-selected]')\n if (trigger === null || trigger.hasAttribute('disabled') || trigger.getAttribute('aria-disabled') === 'true') return\n if (trigger.getAttribute('aria-selected') === 'true' || trigger.getAttribute('aria-current') === 'true') return\n const settingsNavigation = trigger.closest('[data-dsh-mobile-settings-list]') !== null\n const conversationNavigation = trigger.matches('[role=\"tab\"]')\n const sidebarNavigation = trigger.closest('[data-dsh-mobile-sidebar-root]') !== null\n && trigger.closest('[data-dsh-mobile-toggle]') === null\n if (!settingsNavigation && !conversationNavigation && !sidebarNavigation) return\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n if (transitionFrame !== 0) cancelAnimationFrame(transitionFrame)\n if (transitionRestartFrame !== 0) cancelAnimationFrame(transitionRestartFrame)\n transitionFrame = requestAnimationFrame(() => {\n transitionFrame = 0\n const target = settingsNavigation\n ? document.querySelector<HTMLElement>('[data-dsh-mobile-settings-content]')\n : viewArea\n if (target === null || target === undefined) return\n transitionTarget?.removeAttribute('data-dsh-mobile-view-transition')\n target.removeAttribute('data-dsh-mobile-view-transition')\n transitionRestartFrame = requestAnimationFrame(() => {\n transitionRestartFrame = 0\n transitionTarget = target\n target.dataset.dshMobileViewTransition = 'true'\n if (transitionTimer !== 0) clearTimeout(transitionTimer)\n transitionTimer = window.setTimeout(() => {\n target.removeAttribute('data-dsh-mobile-view-transition')\n if (transitionTarget === target) transitionTarget = undefined\n transitionTimer = 0\n }, 240)\n })\n })\n }\n document.addEventListener('click', animateNavigation)\n\n const sync = (): void => {\n scheduled = 0\n frame = firstByClassSuffix(document, '_frame')\n const dedicatedCenter = document.querySelector<HTMLElement>('.dshm-main') ?? undefined\n if (frame !== undefined) frame.dataset.dshMobileFrame = 'true'\n sidebar = frame === undefined\n ? document.querySelector<HTMLElement>('.dshm-drawer') ?? undefined\n : firstByClassSuffix(frame, '_sidebarCol')\n const center = frame === undefined ? dedicatedCenter : firstByClassSuffix(frame, '_centerCol')\n const details = frame === undefined ? undefined : firstByClassSuffix(frame, '_detailsCol')\n const handle = frame === undefined ? undefined : firstByClassSuffix(frame, '_handle')\n if (center === undefined) {\n bindHistoryScroller(undefined)\n return\n }\n if (center !== undefined) {\n center.dataset.dshMobileCenter = 'true'\n center.querySelector<HTMLElement>('header')?.setAttribute('data-dsh-mobile-header', 'true')\n viewArea = firstByClassSuffix(center, '_viewArea')\n if (viewArea !== undefined) viewArea.dataset.dshMobileView = 'true'\n const conversation = center.querySelector<HTMLElement>('[data-conversation-scroll]')\n bindHistoryScroller(conversation ?? undefined)\n const historyLoader = conversation === null ? undefined : firstByClassSuffix(conversation, '_older')\n if (historyLoader !== undefined) {\n historyLoader.dataset.dshMobileHistoryLoader = 'true'\n historyLoader.setAttribute('aria-live', 'polite')\n const button = historyLoader.querySelector<HTMLButtonElement>('button')\n if (button !== null) {\n button.tabIndex = -1\n if (button.disabled) button.removeAttribute('aria-hidden')\n else button.setAttribute('aria-hidden', 'true')\n }\n }\n const messageColumn = conversation === null ? undefined : firstByClassSuffix(conversation, '_column')\n const messageScroll = messageColumn?.parentElement\n if (messageColumn !== undefined && messageScroll !== null && messageScroll !== undefined && classToken(messageScroll, '_scroll')) {\n messageColumn.dataset.dshMobileMessageColumn = 'true'\n messageScroll.dataset.dshMobileMessageScroll = 'true'\n }\n for (const table of center.querySelectorAll<HTMLTableElement>('table')) {\n const parent = table.parentElement\n if (parent?.dataset.dshMobileTableScroll === 'true') continue\n const wrapper = document.createElement('div')\n wrapper.dataset.dshMobileTableScroll = 'true'\n table.before(wrapper)\n wrapper.append(table)\n }\n const composerCard = center.querySelector<HTMLElement>('[data-composer-card]')\n const composerRow = composerCard?.querySelector<HTMLElement>(':scope > [data-input-scroll]')?.nextElementSibling\n if (composerRow instanceof HTMLElement) {\n composerRow.dataset.dshMobileComposerRow = 'true'\n const groups = Array.from(composerRow.children).filter((child): child is HTMLElement => child instanceof HTMLElement)\n const composerTools = groups[0]\n const composerTrailing = groups.at(-1)\n if (composerTools !== undefined) composerTools.dataset.dshMobileComposerTools = 'true'\n if (composerTrailing !== undefined && composerTrailing !== composerTools) {\n composerTrailing.dataset.dshMobileComposerTrailing = 'true'\n const modelTrigger = composerTrailing.querySelector<HTMLButtonElement>('button[aria-label^=\"选择模型\"],button[aria-label^=\"Select model\"]')\n if (modelTrigger !== null) {\n modelTrigger.dataset.dshMobileComposerModelTrigger = 'true'\n modelTrigger.parentElement?.setAttribute('data-dsh-mobile-composer-model', 'true')\n modelTrigger.querySelector<HTMLElement>('[class*=\"_triggerLabel\"]')?.setAttribute('data-dsh-mobile-composer-model-label', 'true')\n }\n }\n }\n }\n if (handle !== undefined) handle.dataset.dshMobileHandle = 'true'\n if (details !== undefined) {\n details.dataset.dshMobileDetails = 'true'\n const lastColumn = frame?.style.gridTemplateColumns.trim().split(/\\s+/).at(-1)\n details.dataset.open = String(lastColumn !== undefined && lastColumn !== '0px' && lastColumn !== '0')\n }\n const settings = Array.from(document.querySelectorAll<HTMLElement>('[role=\"dialog\"]')).find(dialog => {\n const directNav = Array.from(dialog.children).find(child => child instanceof HTMLElement && classToken(child, '_nav'))\n return directNav !== undefined\n })\n if (settings !== undefined) {\n settings.dataset.dshMobileSettings = 'true'\n const nav = Array.from(settings.children).find(child => child instanceof HTMLElement && classToken(child, '_nav')) as HTMLElement | undefined\n const content = Array.from(settings.children).find(child => child instanceof HTMLElement && classToken(child, '_content')) as HTMLElement | undefined\n if (nav !== undefined) {\n nav.dataset.dshMobileSettingsNav = 'true'\n firstByClassSuffix(nav, '_navList')?.setAttribute('data-dsh-mobile-settings-list', 'true')\n }\n if (content !== undefined) {\n content.dataset.dshMobileSettingsContent = 'true'\n firstByClassSuffix(content, '_header')?.setAttribute('data-dsh-mobile-settings-header', 'true')\n firstByClassSuffix(content, '_options')?.setAttribute('data-dsh-mobile-settings-options', 'true')\n }\n }\n if (sidebar === undefined) return\n sidebar.dataset.dshMobileSidebar = 'true'\n toggle = firstByClassSuffix(sidebar, '_toggle') as HTMLButtonElement | undefined\n let candidate = toggle?.parentElement\n while (candidate !== undefined && candidate !== null && candidate !== sidebar && !classToken(candidate, '_root')) candidate = candidate.parentElement\n sidebarRoot = candidate !== sidebar && candidate !== null ? candidate : undefined\n if (sidebarRoot === undefined) return\n sidebarRoot.dataset.dshMobileSidebarRoot = 'true'\n for (const brand of sidebarRoot.querySelectorAll<HTMLElement>('[class*=\"_fallbackBrandName\"]')) {\n if (brand.textContent?.trim() === 'DSH Local Build') brand.textContent = 'DeepSeek Harness'\n }\n if (toggle !== undefined) toggle.dataset.dshMobileToggle = 'true'\n const collapsed = classToken(sidebarRoot, '_collapsed')\n sidebar.dataset.open = String(!collapsed)\n backdrop.hidden = collapsed\n }\n const schedule = (): void => { if (scheduled === 0) scheduled = requestAnimationFrame(sync) }\n const observer = new MutationObserver(schedule)\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'style', 'disabled'] })\n backdrop.addEventListener('click', () => { if (sidebar?.dataset.open === 'true') toggle?.click() })\n sync()\n return () => {\n observer.disconnect()\n document.removeEventListener('click', onBranchClick, true)\n if (branchToastTimer !== 0) window.clearTimeout(branchToastTimer)\n branchToast.remove()\n if (scheduled !== 0) cancelAnimationFrame(scheduled)\n if (transitionFrame !== 0) cancelAnimationFrame(transitionFrame)\n if (transitionRestartFrame !== 0) cancelAnimationFrame(transitionRestartFrame)\n if (transitionTimer !== 0) clearTimeout(transitionTimer)\n transitionTarget?.removeAttribute('data-dsh-mobile-view-transition')\n historyScroller?.removeEventListener('scroll', onHistoryScroll)\n document.removeEventListener('pointerdown', onPointerDown, true)\n document.removeEventListener('keydown', onKeyDown, true)\n document.removeEventListener('click', animateNavigation)\n backdrop.remove()\n document.documentElement.classList.remove('dsh-native-mobile-active')\n delete document.documentElement.dataset.dshMobileInput\n }\n}\n","import { createElement } from 'react'\nimport { installNativeMobileSurface, NATIVE_MOBILE_STYLES } from './native-mobile.js'\n\ninterface ClientContext {\n effect(effect: () => void | (() => void), label?: string): void\n get(name: 'connection'): MobileConnectionHandle\n slots: {\n inject(key: string, callback: () => (() => void)): () => void\n register<Props>(options: { name: string; id: string; order?: number; label?: string }, component: (props: Props) => unknown): () => void\n }\n}\n\ninterface MobileConnectionHandle {\n isLoopback: boolean\n}\n\ninterface MobileExtensionContext {\n readonly document: Document\n readonly request: (path: string, init?: RequestInit) => Promise<Response>\n readonly root: HTMLElement\n readonly window: Window\n}\n\ntype MobileExtensionMount = (context: MobileExtensionContext) => void | (() => void)\ntype MobileSurfacePlacement = 'page' | 'sidebar-action' | 'header-action' | 'composer-dock' | 'settings-section' | 'overlay'\ninterface MobileSurface {\n readonly id: string\n readonly placement: MobileSurfacePlacement\n readonly label: string\n mount(container: HTMLElement): void | (() => void)\n}\ninterface MobileClientApi {\n readonly host: {\n invoke(action: string, input: unknown): Promise<unknown>\n fetch(path: string, init?: RequestInit): Promise<Response>\n }\n readonly ui: {\n registerSurface(surface: MobileSurface): () => void\n open(surfaceId: string): void\n close(surfaceId: string): void\n toast(message: string): void\n }\n readonly native: {\n capabilities(): Promise<readonly string[]>\n invoke(action: string, input?: unknown): Promise<unknown>\n }\n readonly signal: AbortSignal\n readonly document: Document\n readonly window: Window\n}\ninterface MobileClientDefinition {\n readonly apiVersion: 1\n readonly id: string\n activate(api: MobileClientApi): void | (() => void) | Promise<void | (() => void)>\n}\n\ndeclare global {\n interface Window {\n dshMobile?: {\n register(mount: MobileExtensionMount): void\n define(definition: MobileClientDefinition): void\n }\n __DSH_MOBILE_FRONTEND__?: 'dedicated'\n __DSH_MOBILE_NATIVE__?: {\n capabilities(): Promise<readonly string[]> | readonly string[]\n invoke(action: string, input?: unknown): Promise<unknown>\n }\n }\n}\n\nconst queuedDefinitions: MobileClientDefinition[] = []\nlet queuedLegacyMount: MobileExtensionMount | undefined\nif (typeof window !== 'undefined' && window.dshMobile === undefined) {\n window.dshMobile = {\n register: mount => { queuedLegacyMount = mount },\n define: definition => { queuedDefinitions.push(definition) },\n }\n}\n\nfunction isLoopbackHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1' || hostname === '[::1]'\n}\n\n/**\n * Match DSH's client-side privilege hint to the authenticated mobile gateway.\n * The gateway authenticates the paired device and forwards allowed requests to\n * DSH's loopback listener, so settings RPCs receive the same Host-side checks\n * as the desktop page even though the phone's visible URL is a LAN address.\n */\nexport function trustAuthenticatedGatewayConnection(connection: MobileConnectionHandle): () => void {\n const previous = connection.isLoopback\n connection.isLoopback = true\n return () => { connection.isLoopback = previous }\n}\n\nfunction element<K extends keyof HTMLElementTagNameMap>(tag: K, className?: string): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag)\n if (className !== undefined) node.className = className\n return node\n}\n\nconst CONTROL_REQUEST_TIMEOUT_MS = 15_000\nconst LONG_CONTROL_REQUEST_TIMEOUT_MS = 130_000\n\nasync function requestJson(\n path: string,\n init?: RequestInit,\n timeoutMs = CONTROL_REQUEST_TIMEOUT_MS,\n): Promise<Record<string, unknown>> {\n const controller = new AbortController()\n const upstreamSignal = init?.signal\n const abortFromUpstream = (): void => { controller.abort(upstreamSignal?.reason) }\n if (upstreamSignal?.aborted === true) abortFromUpstream()\n else upstreamSignal?.addEventListener('abort', abortFromUpstream, { once: true })\n const timer = window.setTimeout(() => { controller.abort() }, timeoutMs)\n try {\n const response = await fetch(path, {\n ...init,\n signal: controller.signal,\n headers: { 'content-type': 'application/json', ...init?.headers },\n })\n const body = await response.json() as Record<string, unknown>\n if (!response.ok) throw new Error(typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`)\n return body\n } catch (error) {\n if (controller.signal.aborted && upstreamSignal?.aborted !== true) {\n throw new Error('操作超时,请确认 DSH 仍在运行后重试。')\n }\n throw error\n } finally {\n clearTimeout(timer)\n upstreamSignal?.removeEventListener('abort', abortFromUpstream)\n }\n}\n\nfunction officialFunnelSetupUrl(value: unknown): string {\n if (typeof value !== 'string' || value.length > 2048) return ''\n let url: URL\n try { url = new URL(value) } catch { return '' }\n const normalized = url.toString().replace(/\\/$/u, '')\n if (normalized === 'https://tailscale.com/s/no-funnel' || normalized === 'https://tailscale.com/s/https') return normalized\n if (url.protocol !== 'https:' || url.hostname !== 'login.tailscale.com' || url.port !== ''\n || url.username !== '' || url.password !== '') return ''\n return url.toString()\n}\n\nfunction installControl(): { remove: () => void; toggle: () => void } {\n const root = element('div', 'dsh-mobile-control')\n const panel = element('section', 'dsh-mobile-control__panel'); panel.hidden = true\n panel.setAttribute('aria-label', '移动访问')\n const header = element('header', 'dsh-mobile-control__header')\n const title = element('h2'); title.textContent = '移动访问'\n const headerActions = element('div', 'dsh-mobile-control__header-actions')\n const diagnosticsEntry = element('button', 'dsh-mobile-control__diagnostic-entry'); diagnosticsEntry.type = 'button'; diagnosticsEntry.textContent = '诊断'; diagnosticsEntry.setAttribute('aria-label', '打开连接诊断'); diagnosticsEntry.setAttribute('aria-pressed', 'false')\n const close = element('button', 'dsh-mobile-control__close'); close.type = 'button'; close.textContent = '×'; close.setAttribute('aria-label', '收起移动访问')\n headerActions.append(diagnosticsEntry, close)\n const appDownload = element('a', 'dsh-mobile-control__app-download'); appDownload.href = 'https://github.com/saya-ch/dsh-mobile/releases/latest'; appDownload.target = '_blank'; appDownload.rel = 'noopener noreferrer'; appDownload.textContent = '下载 Android App'; appDownload.setAttribute('aria-label', '前往 GitHub Releases 下载最新版 Android App')\n const switcher = element('div', 'dsh-mobile-control__switcher')\n const lanTab = element('button', 'dsh-mobile-control__tab is-active'); lanTab.type = 'button'; lanTab.textContent = '局域网'\n const remoteTab = element('button', 'dsh-mobile-control__tab'); remoteTab.type = 'button'; remoteTab.textContent = '远程'\n lanTab.setAttribute('aria-pressed', 'true'); remoteTab.setAttribute('aria-pressed', 'false'); switcher.append(lanTab, remoteTab)\n const lanView = element('div', 'dsh-mobile-control__view')\n const access = element('div', 'dsh-mobile-control__access'); access.hidden = true\n const accessLabel = element('span', 'dsh-mobile-control__access-label'); accessLabel.textContent = '浏览器访问'\n const accessLink = element('a', 'dsh-mobile-control__access-link'); accessLink.target = '_blank'; accessLink.rel = 'noreferrer'\n access.append(accessLabel, accessLink)\n const qrBox = element('div', 'dsh-mobile-control__qr'); qrBox.hidden = true\n const status = element('p', 'dsh-mobile-control__status'); status.textContent = '正在读取状态…'\n const extensionStatus = element('p', 'dsh-mobile-control__extensions'); extensionStatus.hidden = true\n const actions = element('div', 'dsh-mobile-control__actions')\n const toggle = element('button', 'dsh-mobile-control__secondary'); toggle.type = 'button'\n const pair = element('button', 'dsh-mobile-control__primary'); pair.type = 'button'; pair.textContent = '生成并复制密钥'\n const linkPair = element('button', 'dsh-mobile-control__secondary'); linkPair.type = 'button'; linkPair.textContent = '复制配对链接'\n const manageRow = element('div', 'dsh-mobile-control__manage-row')\n const manageDevices = element('button', 'dsh-mobile-control__manage'); manageDevices.type = 'button'; manageDevices.textContent = '管理配对设备'\n const resetAll = element('button', 'dsh-mobile-control__manage'); resetAll.type = 'button'; resetAll.textContent = '清除所有设备'\n manageRow.append(manageDevices, resetAll)\n const devicePanel = element('div', 'dsh-mobile-control__devices'); devicePanel.hidden = true\n const remoteView = element('div', 'dsh-mobile-control__view is-remote'); remoteView.hidden = true\n const remoteIntro = element('p', 'dsh-mobile-control__intro'); remoteIntro.textContent = '选择更适合你的远程通道。切换或关闭远程访问不会影响局域网。'\n const providerSection = element('section', 'dsh-mobile-control__provider-section')\n const providerHeading = element('h3', 'dsh-mobile-control__section-title'); providerHeading.textContent = '选择连接方式'\n const providerInfo = element('div', 'dsh-mobile-control__provider-info')\n const providerInfoButton = element('button', 'dsh-mobile-control__provider-info-button'); providerInfoButton.type = 'button'; providerInfoButton.setAttribute('aria-label', '查看远程连接安全与网络说明'); providerInfoButton.setAttribute('aria-expanded', 'false'); providerInfoButton.setAttribute('aria-controls', 'dsh-mobile-provider-info'); providerInfoButton.setAttribute('aria-describedby', 'dsh-mobile-provider-info')\n const providerInfoGlyph = element('span', 'dsh-mobile-control__provider-info-glyph'); providerInfoGlyph.textContent = 'i'; providerInfoGlyph.setAttribute('aria-hidden', 'true')\n const providerInfoPopover = element('div', 'dsh-mobile-control__provider-info-popover'); providerInfoPopover.id = 'dsh-mobile-provider-info'; providerInfoPopover.setAttribute('role', 'tooltip'); providerInfoPopover.hidden = true\n const providerInfoTitle = element('strong'); providerInfoTitle.textContent = '你始终可以放心'\n const providerInfoText = element('span'); providerInfoText.textContent = '只有已配对设备能进入 DSH。cpolar 按需安装并可彻底清理;Tailscale 在中国大陆网络下可能连接缓慢、中断或无法使用,国内网络建议优先尝试 cpolar。'\n providerInfoButton.append(providerInfoGlyph); providerInfoPopover.append(providerInfoTitle, providerInfoText); providerInfo.append(providerInfoButton, providerInfoPopover)\n const providerChoices = element('div', 'dsh-mobile-control__provider-choices'); providerChoices.setAttribute('role', 'radiogroup'); providerChoices.setAttribute('aria-label', '远程连接方式')\n const tailscaleChoice = element('button', 'dsh-mobile-control__provider'); tailscaleChoice.type = 'button'; tailscaleChoice.setAttribute('role', 'radio'); tailscaleChoice.setAttribute('aria-checked', 'true')\n const tailscaleChoiceTop = element('span', 'dsh-mobile-control__provider-top')\n const tailscaleChoiceName = element('strong'); tailscaleChoiceName.textContent = 'Tailscale Funnel'\n const tailscaleChoiceBadge = element('span', 'dsh-mobile-control__provider-badge'); tailscaleChoiceBadge.textContent = '内置'\n const tailscaleChoiceDescription = element('span', 'dsh-mobile-control__provider-description'); tailscaleChoiceDescription.textContent = '覆盖更广;中国大陆网络可能不稳定,首次需登录并允许 Funnel。'\n tailscaleChoiceTop.append(tailscaleChoiceName, tailscaleChoiceBadge); tailscaleChoice.append(tailscaleChoiceTop, tailscaleChoiceDescription)\n const cpolarChoice = element('button', 'dsh-mobile-control__provider'); cpolarChoice.type = 'button'; cpolarChoice.setAttribute('role', 'radio'); cpolarChoice.setAttribute('aria-checked', 'false')\n const cpolarChoiceTop = element('span', 'dsh-mobile-control__provider-top')\n const cpolarChoiceName = element('strong'); cpolarChoiceName.textContent = 'cpolar'\n const cpolarChoiceBadge = element('span', 'dsh-mobile-control__provider-badge is-cpolar'); cpolarChoiceBadge.textContent = '国内网络优先'\n const cpolarChoiceDescription = element('span', 'dsh-mobile-control__provider-description'); cpolarChoiceDescription.textContent = '按需安装官方组件,适合国内网络环境。'\n cpolarChoiceTop.append(cpolarChoiceName, cpolarChoiceBadge); cpolarChoice.append(cpolarChoiceTop, cpolarChoiceDescription)\n providerChoices.append(cpolarChoice, tailscaleChoice); providerSection.append(providerHeading, providerInfo, providerChoices)\n const cpolarSetup = element('section', 'dsh-mobile-control__cpolar-setup'); cpolarSetup.hidden = true\n const cpolarSetupTitle = element('h3', 'dsh-mobile-control__section-title'); cpolarSetupTitle.textContent = '准备 cpolar'\n const cpolarComponentStatus = element('p', 'dsh-mobile-control__component-status'); cpolarComponentStatus.textContent = '正在检查组件…'\n const cpolarInstall = element('button', 'dsh-mobile-control__primary'); cpolarInstall.type = 'button'; cpolarInstall.textContent = '安装官方组件'\n const cpolarAccount = element('div', 'dsh-mobile-control__cpolar-account'); cpolarAccount.hidden = true\n const cpolarAccountText = element('p', 'dsh-mobile-control__component-note'); cpolarAccountText.textContent = '登录 cpolar 官网后复制 Authtoken。令牌只保存在本机插件私有目录,不会显示在页面或日志中。'\n const cpolarAccountLinks = element('div', 'dsh-mobile-control__link-row')\n const cpolarSignup = element('a', 'dsh-mobile-control__text-link'); cpolarSignup.href = 'https://dashboard.cpolar.com/signup'; cpolarSignup.target = '_blank'; cpolarSignup.rel = 'noopener noreferrer'; cpolarSignup.textContent = '注册 cpolar'\n const cpolarDashboard = element('a', 'dsh-mobile-control__text-link'); cpolarDashboard.href = 'https://dashboard.cpolar.com/auth'; cpolarDashboard.target = '_blank'; cpolarDashboard.rel = 'noopener noreferrer'; cpolarDashboard.textContent = '打开控制台获取令牌'\n cpolarAccountLinks.append(cpolarSignup, cpolarDashboard)\n const cpolarTokenLabel = element('label', 'dsh-mobile-control__token-label'); cpolarTokenLabel.textContent = 'Authtoken'\n const cpolarToken = element('input', 'dsh-mobile-control__token'); cpolarToken.type = 'password'; cpolarToken.autocomplete = 'off'; cpolarToken.spellcheck = false; cpolarToken.placeholder = '粘贴 cpolar Authtoken'; cpolarTokenLabel.append(cpolarToken)\n const cpolarConfigure = element('button', 'dsh-mobile-control__primary dsh-mobile-control__cpolar-connect'); cpolarConfigure.type = 'button'; cpolarConfigure.textContent = '保存并连接'\n cpolarAccount.append(cpolarAccountText, cpolarAccountLinks, cpolarTokenLabel, cpolarConfigure)\n const cpolarDetails = element('details', 'dsh-mobile-control__details')\n const cpolarDetailsSummary = element('summary'); cpolarDetailsSummary.textContent = '组件来源与清理说明'\n const cpolarDetailsBody = element('div', 'dsh-mobile-control__details-body')\n const cpolarDetailsText = element('p'); cpolarDetailsText.textContent = '仅在你点击安装后从 cpolar 官网下载并校验固定版本。不会写入系统服务、开机启动、注册表或 PATH。'\n const cpolarStorage = element('code', 'dsh-mobile-control__storage'); cpolarStorage.textContent = '插件私有目录'\n const cpolarOfficial = element('a', 'dsh-mobile-control__text-link'); cpolarOfficial.href = 'https://www.cpolar.com/download'; cpolarOfficial.target = '_blank'; cpolarOfficial.rel = 'noopener noreferrer'; cpolarOfficial.textContent = '官方下载安装页'\n const cpolarTerms = element('a', 'dsh-mobile-control__text-link'); cpolarTerms.href = 'https://www.cpolar.com/tos'; cpolarTerms.target = '_blank'; cpolarTerms.rel = 'noopener noreferrer'; cpolarTerms.textContent = '服务条款'\n const cpolarPurge = element('button', 'dsh-mobile-control__danger'); cpolarPurge.type = 'button'; cpolarPurge.textContent = '彻底移除 cpolar 组件与配置'\n cpolarDetailsBody.append(cpolarDetailsText, cpolarStorage, cpolarOfficial, cpolarTerms, cpolarPurge); cpolarDetails.append(cpolarDetailsSummary, cpolarDetailsBody)\n cpolarSetup.append(cpolarSetupTitle, cpolarComponentStatus, cpolarInstall, cpolarAccount, cpolarDetails)\n const tailscaleInfo = element('details', 'dsh-mobile-control__details')\n const tailscaleInfoSummary = element('summary'); tailscaleInfoSummary.textContent = 'Tailscale 使用说明'\n const tailscaleInfoBody = element('div', 'dsh-mobile-control__details-body')\n const tailscaleInfoText = element('p'); tailscaleInfoText.textContent = '运行组件已随插件提供。首次连接会打开 Tailscale 官方登录和 Funnel 授权页;插件不会接触你的账号密码。'\n tailscaleInfoBody.append(tailscaleInfoText); tailscaleInfo.append(tailscaleInfoSummary, tailscaleInfoBody)\n const remoteAccess = element('div', 'dsh-mobile-control__access'); remoteAccess.hidden = true\n const remoteAccessLabel = element('span', 'dsh-mobile-control__access-label'); remoteAccessLabel.textContent = '远程地址'\n const remoteAccessLink = element('a', 'dsh-mobile-control__access-link'); remoteAccessLink.target = '_blank'; remoteAccessLink.rel = 'noreferrer'; remoteAccess.append(remoteAccessLabel, remoteAccessLink)\n const remoteQr = element('div', 'dsh-mobile-control__qr'); remoteQr.hidden = true\n const remoteStatus = element('p', 'dsh-mobile-control__status'); remoteStatus.textContent = '正在读取远程状态…'; remoteStatus.setAttribute('aria-live', 'polite')\n const remoteGuide = element('section', 'dsh-mobile-control__guide'); remoteGuide.hidden = true; remoteGuide.setAttribute('aria-label', 'Tailscale Funnel 启用步骤')\n const remoteGuideTitle = element('h3', 'dsh-mobile-control__guide-title'); remoteGuideTitle.textContent = '远程访问设置 · 第 2 步'\n const remoteGuideSummary = element('p', 'dsh-mobile-control__guide-summary'); remoteGuideSummary.textContent = 'Tailscale 登录已完成。还需为这台电脑允许 Funnel,官方页面会同时启用 HTTPS。'\n const remoteGuideSteps = element('ol', 'dsh-mobile-control__guide-steps')\n for (const text of ['打开当前节点的 Tailscale 官方授权页。', '确认启用 Funnel;无需再次登录 DSH。', '返回 DSH,插件会自动检查并建立连接。']) {\n const item = element('li'); item.textContent = text; remoteGuideSteps.append(item)\n }\n const remoteGuideNote = element('p', 'dsh-mobile-control__guide-note'); remoteGuideNote.textContent = '需要使用 Owner、Admin 或 Network admin 账号。'\n const remoteGuideActions = element('div', 'dsh-mobile-control__guide-actions')\n const remoteSetup = element('button', 'dsh-mobile-control__primary'); remoteSetup.type = 'button'; remoteSetup.textContent = '继续完成 Funnel 授权'\n const remoteSetupRetry = element('button', 'dsh-mobile-control__secondary'); remoteSetupRetry.type = 'button'; remoteSetupRetry.textContent = '已完成,立即重试'\n remoteGuideActions.append(remoteSetup, remoteSetupRetry); remoteGuide.append(remoteGuideTitle, remoteGuideSummary, remoteGuideSteps, remoteGuideNote, remoteGuideActions)\n const remoteActions = element('div', 'dsh-mobile-control__actions')\n const remoteToggle = element('button', 'dsh-mobile-control__primary'); remoteToggle.type = 'button'; remoteToggle.textContent = '启用远程访问'\n const remoteLogin = element('button', 'dsh-mobile-control__primary'); remoteLogin.type = 'button'; remoteLogin.textContent = '继续登录'; remoteLogin.hidden = true\n const remoteReconnect = element('button', 'dsh-mobile-control__secondary'); remoteReconnect.type = 'button'; remoteReconnect.textContent = '重新连接'; remoteReconnect.hidden = true\n const remotePair = element('button', 'dsh-mobile-control__secondary'); remotePair.type = 'button'; remotePair.textContent = '生成远程配对二维码'; remotePair.disabled = true\n remoteActions.append(remoteToggle, remoteLogin, remoteReconnect, remotePair)\n const remoteManageRow = element('div', 'dsh-mobile-control__manage-row')\n const remoteDevices = element('button', 'dsh-mobile-control__manage'); remoteDevices.type = 'button'; remoteDevices.textContent = '管理远程设备'; remoteDevices.disabled = true\n const remoteReset = element('button', 'dsh-mobile-control__manage'); remoteReset.type = 'button'; remoteReset.textContent = '退出并清除远程登录'\n remoteManageRow.append(remoteDevices, remoteReset)\n const remoteDevicePanel = element('div', 'dsh-mobile-control__devices'); remoteDevicePanel.hidden = true\n const diagnosticsView = element('div', 'dsh-mobile-control__view is-diagnostics'); diagnosticsView.hidden = true\n const diagnosticsIntro = element('p', 'dsh-mobile-control__intro'); diagnosticsIntro.textContent = '检查版本、网关、网卡、防火墙和远程通道。报告自动脱敏,不读取对话或凭据。'\n const diagnosticsSummary = element('section', 'dsh-mobile-control__diagnostic-summary is-idle'); diagnosticsSummary.setAttribute('aria-live', 'polite')\n const diagnosticsSummaryMain = element('div', 'dsh-mobile-control__diagnostic-summary-main')\n const diagnosticsSummaryIcon = element('span', 'dsh-mobile-control__diagnostic-summary-icon'); diagnosticsSummaryIcon.setAttribute('aria-hidden', 'true')\n const diagnosticsSummaryBody = element('div', 'dsh-mobile-control__diagnostic-summary-body')\n const diagnosticsSummaryTitle = element('strong'); diagnosticsSummaryTitle.textContent = '尚未检查'\n const diagnosticsSummaryText = element('span'); diagnosticsSummaryText.textContent = '点击下方按钮开始。'\n const diagnosticsSummaryMeta = element('span', 'dsh-mobile-control__diagnostic-summary-meta'); diagnosticsSummaryMeta.textContent = '等待运行 · 仅收集连接状态'\n diagnosticsSummaryBody.append(diagnosticsSummaryTitle, diagnosticsSummaryText)\n diagnosticsSummaryMain.append(diagnosticsSummaryIcon, diagnosticsSummaryBody)\n diagnosticsSummary.append(diagnosticsSummaryMain, diagnosticsSummaryMeta)\n const diagnosticsToolbar = element('div', 'dsh-mobile-control__diagnostic-toolbar')\n const diagnosticsRun = element('button', 'dsh-mobile-control__primary dsh-mobile-control__diagnostic-run'); diagnosticsRun.type = 'button'; diagnosticsRun.textContent = '开始检查'\n const diagnosticsCopy = element('button', 'dsh-mobile-control__secondary dsh-mobile-control__diagnostic-copy'); diagnosticsCopy.type = 'button'; diagnosticsCopy.textContent = '复制脱敏报告'; diagnosticsCopy.disabled = true; diagnosticsCopy.hidden = true\n diagnosticsToolbar.append(diagnosticsRun, diagnosticsCopy)\n const diagnosticsFeedback = element('p', 'dsh-mobile-control__diagnostic-feedback'); diagnosticsFeedback.hidden = true; diagnosticsFeedback.setAttribute('role', 'status'); diagnosticsFeedback.setAttribute('aria-live', 'polite')\n const diagnosticsChecks = element('div', 'dsh-mobile-control__diagnostic-checks'); diagnosticsChecks.hidden = true\n const diagnosticsDetails = element('details', 'dsh-mobile-control__details dsh-mobile-control__diagnostic-details'); diagnosticsDetails.hidden = true\n const diagnosticsDetailsSummary = element('summary'); diagnosticsDetailsSummary.textContent = '高级诊断详情'\n const diagnosticsReport = element('pre', 'dsh-mobile-control__diagnostic-report')\n diagnosticsDetails.append(diagnosticsDetailsSummary, diagnosticsReport)\n header.append(title, headerActions); actions.append(toggle, pair, linkPair)\n lanView.append(access, qrBox, status, extensionStatus, actions, manageRow, devicePanel)\n remoteView.append(remoteIntro, providerSection, cpolarSetup, tailscaleInfo, remoteAccess, remoteQr, remoteStatus, remoteGuide, remoteActions, remoteManageRow, remoteDevicePanel)\n diagnosticsView.append(diagnosticsIntro, diagnosticsSummary, diagnosticsToolbar, diagnosticsFeedback, diagnosticsChecks, diagnosticsDetails)\n panel.append(header, appDownload, switcher, lanView, remoteView, diagnosticsView); root.append(panel); document.body.append(root)\n let running = false\n let origin = ''\n let remoteRunning = false\n let remoteReady = false\n let remoteProvider: 'tailscale' | 'cpolar' = 'tailscale'\n let remoteLoginUrl = ''\n let remoteSetupUrl = ''\n let remoteSetupPending = false\n let remoteSetupOpenedAt = 0\n let remoteReconnectBusy = false\n let remoteProviderBusy = false\n let cpolarInstalled = false\n let cpolarConfigured = false\n let providerInfoPinned = false\n let providerInfoHovered = false\n let previousAccessView: 'lan' | 'remote' = 'lan'\n let diagnosticsBusy = false\n let copiedDiagnosticReport = ''\n const syncProviderInfo = (): void => {\n const open = providerInfoPinned || providerInfoHovered || providerInfo.contains(document.activeElement)\n providerInfoPopover.hidden = !open\n providerInfoButton.setAttribute('aria-expanded', String(open))\n }\n providerInfo.addEventListener('pointerenter', () => { providerInfoHovered = true; syncProviderInfo() })\n providerInfo.addEventListener('pointerleave', () => { providerInfoHovered = false; syncProviderInfo() })\n providerInfo.addEventListener('focusin', syncProviderInfo)\n providerInfo.addEventListener('focusout', () => { window.setTimeout(syncProviderInfo, 0) })\n providerInfoButton.addEventListener('click', () => { providerInfoPinned = !providerInfoPinned; syncProviderInfo() })\n providerInfoButton.addEventListener('keydown', event => {\n if (event.key !== 'Escape') return\n providerInfoPinned = false\n providerInfoHovered = false\n providerInfoPopover.hidden = true\n providerInfoButton.setAttribute('aria-expanded', 'false')\n })\n const selectView = (view: 'lan' | 'remote' | 'diagnostics'): void => {\n if (view !== 'diagnostics') previousAccessView = view\n lanView.hidden = view !== 'lan'\n remoteView.hidden = view !== 'remote'\n diagnosticsView.hidden = view !== 'diagnostics'\n lanTab.classList.toggle('is-active', view === 'lan')\n remoteTab.classList.toggle('is-active', view === 'remote')\n lanTab.setAttribute('aria-pressed', String(view === 'lan'))\n remoteTab.setAttribute('aria-pressed', String(view === 'remote'))\n diagnosticsEntry.setAttribute('aria-pressed', String(view === 'diagnostics'))\n diagnosticsEntry.textContent = view === 'diagnostics' ? '返回' : '诊断'\n diagnosticsEntry.setAttribute('aria-label', view === 'diagnostics' ? '返回移动访问' : '打开连接诊断')\n appDownload.hidden = view === 'diagnostics'\n switcher.hidden = view === 'diagnostics'\n title.textContent = view === 'lan' ? '局域网访问' : view === 'remote' ? '远程访问' : '连接诊断'\n }\n lanTab.addEventListener('click', () => { selectView('lan') })\n remoteTab.addEventListener('click', () => { selectView('remote'); loadRemote() })\n const setOpen = (open: boolean): void => {\n panel.hidden = !open\n for (const trigger of document.querySelectorAll('.dsh-mobile-control__trigger')) trigger.setAttribute('aria-expanded', String(open))\n }\n const render = (data: Record<string, unknown>): void => {\n running = data.running === true\n origin = running && typeof data.origin === 'string' ? data.origin : ''\n access.hidden = origin === ''\n accessLink.href = origin\n accessLink.textContent = origin\n accessLink.title = origin\n status.classList.toggle('is-running', running)\n status.textContent = running ? '局域网访问已开启。' : '局域网访问已关闭。'\n const extensionData = data.extensions\n if (extensionData !== null && typeof extensionData === 'object') {\n const loaded = typeof (extensionData as { loaded?: unknown }).loaded === 'number' ? (extensionData as { loaded: number }).loaded : 0\n const failed = typeof (extensionData as { failed?: unknown }).failed === 'number' ? (extensionData as { failed: number }).failed : 0\n extensionStatus.hidden = false\n extensionStatus.textContent = failed === 0 ? `扩展:${String(loaded)} 个已加载` : `扩展:${String(loaded)} 个已加载,${String(failed)} 个加载失败`\n } else extensionStatus.hidden = true\n if (!running) qrBox.hidden = true\n toggle.textContent = running ? '关闭局域网访问' : '开启局域网访问'\n pair.disabled = !running\n linkPair.disabled = !running\n manageDevices.disabled = !running\n resetAll.disabled = !running\n }\n const showQr = (svg: string, target: HTMLDivElement = qrBox): void => {\n target.replaceChildren()\n if (svg === '') { target.hidden = true; return }\n const image = element('img')\n image.alt = '配对二维码'\n image.width = 176\n image.height = 176\n image.src = `data:image/svg+xml;base64,${btoa(svg)}`\n target.hidden = false\n target.append(image)\n }\n const openPairing = (target: 'key' | 'link'): void => {\n void requestJson('/api/mobile-access/lan/pairing/open', { method: 'POST', body: '{}' }).then(async data => {\n const value = target === 'key'\n ? (typeof data.appKey === 'string' ? data.appKey : '')\n : (typeof data.pairUrl === 'string' ? data.pairUrl : '')\n showQr(typeof data.qrSvg === 'string' ? data.qrSvg : '')\n if (value === '') { status.textContent = '无法生成配对密钥。'; return }\n try {\n await navigator.clipboard.writeText(value)\n status.textContent = target === 'key'\n ? '配对密钥已复制,请粘贴到 Android App。'\n : '配对链接已复制,发给手机后 App 粘贴或浏览器打开即可配对。'\n } catch {\n status.textContent = `请复制${target === 'key' ? '配对密钥' : '配对链接'}:${value}`\n status.classList.add('is-key')\n }\n }, error => { status.textContent = String(error) }).finally(() => {\n pair.disabled = !running\n linkPair.disabled = !running\n })\n }\n toggle.addEventListener('click', () => { toggle.disabled = true; void requestJson('/api/mobile-access/lan/control', { method: 'POST', body: JSON.stringify({ running: !running }) }).then(render, error => { status.textContent = String(error) }).finally(() => { toggle.disabled = false }) })\n const formatTime = (ms: unknown): string => typeof ms === 'number' ? new Date(ms).toLocaleString() : ''\n const renderDevices = (data: Record<string, unknown>): void => {\n const devices = Array.isArray(data.devices) ? data.devices as Record<string, unknown>[] : []\n devicePanel.replaceChildren()\n if (devices.length === 0) {\n const empty = element('p', 'dsh-mobile-control__device-empty'); empty.textContent = '暂无配对设备。'\n devicePanel.append(empty)\n return\n }\n for (const device of devices) {\n const row = element('div', 'dsh-mobile-control__device')\n const label = element('span', 'dsh-mobile-control__device-label')\n label.textContent = typeof device.label === 'string' ? device.label : '设备'\n const meta = element('span', 'dsh-mobile-control__device-meta'); meta.textContent = `到期 ${formatTime(device.expiresAt)}`\n const revoke = element('button', 'dsh-mobile-control__device-revoke'); revoke.type = 'button'; revoke.textContent = '撤销'\n const id = typeof device.id === 'string' ? device.id : ''\n revoke.addEventListener('click', () => {\n void requestJson('/api/mobile-access/lan/devices/revoke', { method: 'POST', body: JSON.stringify({ deviceId: id }) })\n .then(loadDevices, error => { status.textContent = String(error) })\n })\n row.append(label, meta, revoke)\n devicePanel.append(row)\n }\n }\n const loadDevices = (): void => {\n void requestJson('/api/mobile-access/lan/devices').then(renderDevices, error => { status.textContent = String(error) })\n }\n manageDevices.addEventListener('click', () => {\n const show = devicePanel.hidden\n devicePanel.hidden = !show\n if (show) loadDevices()\n })\n resetAll.addEventListener('click', () => {\n if (!window.confirm('确定要移除所有配对设备吗?此操作会立即终止已连接设备。')) return\n void requestJson('/api/mobile-access/lan/devices/reset', { method: 'POST', body: JSON.stringify({ confirm: true }) })\n .then(loadDevices, error => { status.textContent = String(error) })\n })\n const renderRemote = (data: Record<string, unknown>): void => {\n remoteRunning = data.running === true\n remoteProvider = data.provider === 'cpolar' ? 'cpolar' : 'tailscale'\n const cpolar = remoteProvider === 'cpolar'\n tailscaleChoice.classList.toggle('is-selected', !cpolar)\n cpolarChoice.classList.toggle('is-selected', cpolar)\n tailscaleChoice.setAttribute('aria-checked', String(!cpolar))\n cpolarChoice.setAttribute('aria-checked', String(cpolar))\n tailscaleChoice.disabled = remoteProviderBusy\n cpolarChoice.disabled = remoteProviderBusy\n cpolarSetup.hidden = !cpolar\n tailscaleInfo.hidden = cpolar\n remoteReset.textContent = cpolar ? '关闭并清除远程设备' : '退出并清除远程登录'\n const providers = data.providers !== null && typeof data.providers === 'object' ? data.providers as Record<string, unknown> : {}\n const cpolarProvider = providers.cpolar !== null && typeof providers.cpolar === 'object' ? providers.cpolar as Record<string, unknown> : {}\n const component = cpolarProvider.component !== null && typeof cpolarProvider.component === 'object'\n ? cpolarProvider.component as Record<string, unknown>\n : {}\n cpolarInstalled = component.installed === true\n cpolarConfigured = component.configured === true\n cpolarChoiceBadge.textContent = cpolarConfigured ? '已就绪' : cpolarInstalled ? '已安装' : '国内网络优先'\n const cpolarSupported = component.supported !== false\n const componentVersion = typeof component.version === 'string' ? component.version : ''\n const componentDownloadBytes = typeof component.downloadBytes === 'number' ? component.downloadBytes : 0\n const componentStorage = typeof component.storagePath === 'string' ? component.storagePath : 'DSH Mobile 插件私有目录'\n cpolarStorage.textContent = componentStorage\n cpolarStorage.title = componentStorage\n cpolarInstall.hidden = cpolarInstalled || !cpolarSupported\n cpolarInstall.textContent = componentDownloadBytes > 0\n ? `安装官方组件 · ${(componentDownloadBytes / 1024 / 1024).toFixed(1)} MB`\n : '安装官方组件'\n cpolarInstall.disabled = remoteProviderBusy\n cpolarAccount.hidden = !cpolarInstalled || cpolarConfigured\n cpolarConfigure.disabled = remoteProviderBusy\n cpolarPurge.hidden = !cpolarInstalled && !cpolarConfigured\n cpolarComponentStatus.textContent = !cpolarSupported\n ? '当前仅支持 Windows x64。你仍可选择内置的 Tailscale Funnel。'\n : !cpolarInstalled\n ? '尚未安装。只有点击下方按钮后,才会从 cpolar 官网下载固定版本。'\n : !cpolarConfigured\n ? `官方组件 ${componentVersion} 已校验,下一步只需保存账号令牌。`\n : `官方组件 ${componentVersion} 与本机账号配置已就绪。`\n const state = typeof data.state === 'string' ? data.state : 'error'\n const errorCode = typeof data.errorCode === 'string' ? data.errorCode : ''\n const remoteOrigin = typeof data.origin === 'string' ? data.origin : ''\n remoteLoginUrl = typeof data.loginUrl === 'string' ? data.loginUrl : ''\n const candidateSetupUrl = cpolar ? '' : officialFunnelSetupUrl(data.setupUrl)\n const fallbackSetupUrls: Record<string, string> = {\n funnel_permission_required: 'https://tailscale.com/s/no-funnel',\n funnel_https_required: 'https://tailscale.com/s/https',\n funnel_start_failed: 'https://tailscale.com/s/no-funnel',\n }\n remoteSetupUrl = candidateSetupUrl !== '' ? candidateSetupUrl : (fallbackSetupUrls[errorCode] ?? '')\n const needsFunnelSetup = state === 'error' && remoteSetupUrl !== ''\n remoteReady = remoteRunning && state === 'ready' && remoteOrigin !== ''\n remoteAccess.hidden = !remoteReady\n remoteAccessLink.href = remoteOrigin\n remoteAccessLink.textContent = remoteOrigin\n remoteAccessLink.title = remoteOrigin\n remoteStatus.classList.toggle('is-running', remoteReady)\n const labels: Record<string, string> = {\n off: '远程访问未启用。局域网访问不受影响。',\n unavailable: cpolar ? 'cpolar 尚未安装或未完成本机账号配置。' : '当前电脑缺少 Funnel 运行组件,请重新安装完整插件包。',\n starting: cpolar ? '正在连接 cpolar 国内节点…' : '正在启动 Tailscale 安全通道…',\n 'needs-login': '需要在浏览器完成一次 Tailscale 登录。插件不会读取你的密码。',\n connecting: cpolar ? '公网地址已分配,正在启动 DSH 认证网关…' : '登录完成,正在建立公开 HTTPS 地址…',\n ready: '远程访问已就绪。只有已配对设备可以进入 DSH。',\n error: '远程连接未建立。可重新连接,局域网访问仍可正常使用。',\n }\n const errorLabels: Record<string, string> = {\n funnel_permission_required: '登录已完成。请继续授权 Funnel,完成后会自动建立远程连接。',\n funnel_https_required: '登录已完成。请继续授权 Funnel,官方页面会同时启用 HTTPS。',\n funnel_start_failed: '登录已完成。请继续完成 Tailscale Funnel 的首次授权。',\n funnel_start_timeout: 'Tailscale 组件启动超时,请检查网络后重新连接。',\n tailscale_dns_missing: 'Tailscale 暂未提供远程地址。请重新连接并确认已完成登录。',\n gateway_start_failed: '远程网关启动失败。请重新连接,局域网访问不受影响。',\n control_channel_failed: '远程组件连接中断。请重新连接。',\n cpolar_component_missing: 'cpolar 官方组件尚未安装。请先完成上方准备步骤。',\n cpolar_component_invalid: 'cpolar 组件校验失败。请彻底移除后重新安装。',\n cpolar_config_missing: 'cpolar 尚未保存账号令牌。请先完成上方准备步骤。',\n cpolar_config_invalid: 'cpolar 本机配置无效。请重新保存账号令牌。',\n cpolar_port_unavailable: '无法分配本机远程网关端口,请重试。',\n cpolar_launch_failed: 'cpolar 客户端未能启动。',\n cpolar_start_timeout: '连接 cpolar 国内节点超时,请重新连接。',\n cpolar_stopped: 'cpolar 连接已停止。',\n cpolar_exited: 'cpolar 连接意外退出,请重新连接。',\n cpolar_invalid_output: 'cpolar 返回了无法识别的状态。',\n cpolar_invalid_origin: 'cpolar 返回的公网地址未通过校验。',\n }\n remoteStatus.textContent = remoteSetupPending && needsFunnelSetup\n ? 'Tailscale 官方页面已打开。完成启用后返回 DSH,这里会自动重新连接。'\n : (state === 'error' ? (errorLabels[errorCode] ?? labels.error!) : (labels[state] ?? labels.error!))\n remoteGuide.hidden = !needsFunnelSetup\n remoteSetup.disabled = remoteSetupUrl === '' || remoteReconnectBusy\n remoteSetupRetry.disabled = remoteReconnectBusy\n remoteToggle.textContent = remoteRunning ? '关闭远程访问' : '启用远程访问'\n remoteToggle.disabled = remoteProviderBusy || (cpolar && (!cpolarInstalled || !cpolarConfigured))\n remoteLogin.hidden = cpolar || state !== 'needs-login' || remoteLoginUrl === ''\n remoteReconnect.hidden = needsFunnelSetup || (state !== 'error' && state !== 'unavailable')\n || (cpolar && (!cpolarInstalled || !cpolarConfigured))\n remoteActions.hidden = cpolar && (!cpolarInstalled || !cpolarConfigured)\n remotePair.disabled = !remoteReady\n remoteDevices.disabled = !remoteReady\n if (!remoteReady) remoteQr.hidden = true\n if (!needsFunnelSetup) remoteSetupPending = false\n }\n let remoteLoadInFlight = false\n const loadRemote = (): void => {\n if (remoteLoadInFlight) return\n remoteLoadInFlight = true\n void requestJson('/api/mobile-access/remote/control')\n .then(renderRemote, error => { remoteStatus.textContent = String(error) })\n .finally(() => { remoteLoadInFlight = false })\n }\n const chooseRemoteProvider = (provider: 'tailscale' | 'cpolar'): void => {\n if (remoteProviderBusy || provider === remoteProvider) return\n if (remoteRunning && !window.confirm('切换连接方式会先关闭当前远程通道。局域网和配对设备不会受影响,是否继续?')) return\n remoteProviderBusy = true\n tailscaleChoice.disabled = true\n cpolarChoice.disabled = true\n remoteStatus.textContent = provider === 'cpolar' ? '正在切换到 cpolar…' : '正在切换到 Tailscale Funnel…'\n void requestJson('/api/mobile-access/remote/provider', { method: 'POST', body: JSON.stringify({ provider }) })\n .then(renderRemote, error => { remoteStatus.textContent = String(error) })\n .finally(() => { remoteProviderBusy = false; loadRemote() })\n }\n tailscaleChoice.addEventListener('click', () => { chooseRemoteProvider('tailscale') })\n cpolarChoice.addEventListener('click', () => { chooseRemoteProvider('cpolar') })\n cpolarInstall.addEventListener('click', () => {\n if (remoteProviderBusy) return\n const accepted = window.confirm('将从 cpolar 官方网站下载并校验固定版本(约 7.3 MB),仅解压到 DSH Mobile 私有目录。不会安装系统服务、写入 PATH/注册表或设置开机启动。是否继续?')\n if (!accepted) return\n remoteProviderBusy = true\n cpolarInstall.disabled = true\n cpolarInstall.textContent = '正在下载并校验…'\n remoteStatus.textContent = '正在安装 cpolar 官方组件。完成前请保持 DSH 运行。'\n void requestJson('/api/mobile-access/remote/cpolar/component/install', { method: 'POST', body: JSON.stringify({ confirm: true }) }, LONG_CONTROL_REQUEST_TIMEOUT_MS)\n .then(renderRemote, error => { remoteStatus.textContent = `组件安装失败:${String(error)}` })\n .finally(() => { remoteProviderBusy = false; loadRemote() })\n })\n cpolarConfigure.addEventListener('click', () => {\n if (remoteProviderBusy) return\n const authtoken = cpolarToken.value.trim()\n if (authtoken.length < 20 || /\\s/u.test(authtoken)) {\n remoteStatus.textContent = '请粘贴 cpolar 控制台提供的完整 Authtoken。'\n cpolarToken.focus()\n return\n }\n remoteProviderBusy = true\n cpolarConfigure.disabled = true\n cpolarConfigure.setAttribute('aria-busy', 'true')\n cpolarConfigure.textContent = '正在保存…'\n void requestJson('/api/mobile-access/remote/cpolar/configure', { method: 'POST', body: JSON.stringify({ authtoken }) }, LONG_CONTROL_REQUEST_TIMEOUT_MS)\n .then(() => {\n cpolarToken.value = ''\n remoteStatus.textContent = '账号配置已保存,正在建立 cpolar 远程通道…'\n return requestJson('/api/mobile-access/remote/control', { method: 'POST', body: JSON.stringify({ running: true }) })\n })\n .then(renderRemote, error => { remoteStatus.textContent = `配置失败:${String(error)}` })\n .finally(() => { remoteProviderBusy = false; cpolarConfigure.setAttribute('aria-busy', 'false'); cpolarConfigure.textContent = '保存并连接'; loadRemote() })\n })\n cpolarPurge.addEventListener('click', () => {\n if (remoteProviderBusy) return\n if (!window.confirm('彻底移除 DSH Mobile 私有目录中的 cpolar 组件、令牌配置和运行日志?不会影响局域网、DSH 数据或系统中的其他程序。')) return\n remoteProviderBusy = true\n cpolarPurge.disabled = true\n remoteStatus.textContent = '正在关闭通道并清理 DSH Mobile 管理的 cpolar 文件…'\n void requestJson('/api/mobile-access/remote/cpolar/component/purge', { method: 'POST', body: JSON.stringify({ confirm: true }) }, LONG_CONTROL_REQUEST_TIMEOUT_MS)\n .then(renderRemote, error => { remoteStatus.textContent = `清理失败:${String(error)}` })\n .finally(() => { remoteProviderBusy = false; cpolarPurge.disabled = false; loadRemote() })\n })\n remoteToggle.addEventListener('click', () => {\n remoteToggle.disabled = true\n void requestJson('/api/mobile-access/remote/control', { method: 'POST', body: JSON.stringify({ running: !remoteRunning }) })\n .then(renderRemote, error => { remoteStatus.textContent = String(error) })\n .finally(loadRemote)\n })\n remoteLogin.addEventListener('click', () => {\n if (remoteLoginUrl !== '') window.open(remoteLoginUrl, '_blank', 'noopener,noreferrer')\n })\n const reconnectRemote = (): void => {\n if (remoteReconnectBusy) return\n remoteReconnectBusy = true\n remoteReconnect.disabled = true\n remoteSetup.disabled = true\n remoteSetupRetry.disabled = true\n remoteStatus.textContent = remoteProvider === 'cpolar' ? '正在重新连接 cpolar 国内节点…' : '正在确认 Tailscale 设置并重新连接…'\n void requestJson('/api/mobile-access/remote/reconnect', { method: 'POST', body: '{}' })\n .then(renderRemote, error => { remoteStatus.textContent = String(error) })\n .finally(() => {\n remoteReconnectBusy = false\n remoteReconnect.disabled = false\n remoteSetup.disabled = remoteSetupUrl === ''\n remoteSetupRetry.disabled = false\n })\n }\n remoteReconnect.addEventListener('click', reconnectRemote)\n remoteSetupRetry.addEventListener('click', () => { remoteSetupPending = false; reconnectRemote() })\n remoteSetup.addEventListener('click', () => {\n if (remoteSetupUrl === '') return\n remoteSetupPending = true\n remoteSetupOpenedAt = Date.now()\n remoteStatus.textContent = 'Tailscale 官方页面已打开。完成启用后返回 DSH,这里会自动重新连接。'\n window.open(remoteSetupUrl, '_blank', 'noopener,noreferrer')\n })\n const retryAfterSetup = (): void => {\n if (!remoteSetupPending || document.visibilityState === 'hidden' || Date.now() - remoteSetupOpenedAt < 800) return\n remoteSetupPending = false\n reconnectRemote()\n }\n window.addEventListener('focus', retryAfterSetup)\n document.addEventListener('visibilitychange', retryAfterSetup)\n remotePair.addEventListener('click', () => {\n remotePair.disabled = true\n void requestJson('/api/mobile-access/remote/pairing/open', { method: 'POST', body: '{}' }).then(async data => {\n const pairUrl = typeof data.pairUrl === 'string' ? data.pairUrl : ''\n showQr(typeof data.qrSvg === 'string' ? data.qrSvg : '', remoteQr)\n if (pairUrl !== '') {\n try { await navigator.clipboard.writeText(pairUrl) } catch { /* QR remains the primary remote handoff. */ }\n }\n remoteStatus.textContent = '远程配对二维码已生成。请在 App 的“远程访问”中扫描。'\n }, error => { remoteStatus.textContent = String(error) }).finally(() => { remotePair.disabled = !remoteReady })\n })\n const renderRemoteDevices = (data: Record<string, unknown>): void => {\n const devices = Array.isArray(data.devices) ? data.devices as Record<string, unknown>[] : []\n remoteDevicePanel.replaceChildren()\n if (devices.length === 0) {\n const empty = element('p', 'dsh-mobile-control__device-empty'); empty.textContent = '暂无远程配对设备。'; remoteDevicePanel.append(empty); return\n }\n for (const device of devices) {\n const row = element('div', 'dsh-mobile-control__device')\n const label = element('span', 'dsh-mobile-control__device-label'); label.textContent = typeof device.label === 'string' ? device.label : '设备'\n const meta = element('span', 'dsh-mobile-control__device-meta'); meta.textContent = `到期 ${formatTime(device.expiresAt)}`\n const revoke = element('button', 'dsh-mobile-control__device-revoke'); revoke.type = 'button'; revoke.textContent = '撤销'\n const id = typeof device.id === 'string' ? device.id : ''\n revoke.addEventListener('click', () => {\n void requestJson('/api/mobile-access/remote/devices/revoke', { method: 'POST', body: JSON.stringify({ deviceId: id }) })\n .then(loadRemoteDevices, error => { remoteStatus.textContent = String(error) })\n })\n row.append(label, meta, revoke); remoteDevicePanel.append(row)\n }\n }\n const loadRemoteDevices = (): void => {\n void requestJson('/api/mobile-access/remote/devices').then(renderRemoteDevices, error => { remoteStatus.textContent = String(error) })\n }\n remoteDevices.addEventListener('click', () => {\n const show = remoteDevicePanel.hidden\n remoteDevicePanel.hidden = !show\n if (show) loadRemoteDevices()\n })\n remoteReset.addEventListener('click', () => {\n const prompt = remoteProvider === 'cpolar'\n ? '关闭 cpolar 远程通道并移除所有远程配对设备?不会修改你的 cpolar 账号或其他隧道。'\n : '退出电脑上的 Tailscale 登录并移除所有远程配对设备?局域网配置不会改变。'\n if (!window.confirm(prompt)) return\n void requestJson('/api/mobile-access/remote/reset', { method: 'POST', body: JSON.stringify({ confirm: true }) })\n .then(renderRemote, error => { remoteStatus.textContent = String(error) })\n })\n const renderDiagnostics = (data: Record<string, unknown>): void => {\n const overall = data.overall === 'error' ? 'error' : data.overall === 'attention' ? 'attention' : 'ok'\n diagnosticsSummary.className = `dsh-mobile-control__diagnostic-summary is-${overall}`\n diagnosticsSummaryTitle.textContent = overall === 'ok' ? '检查完成' : overall === 'attention' ? '有项目需要留意' : '发现连接问题'\n diagnosticsSummaryText.textContent = typeof data.summary === 'string' ? data.summary : '检查已完成。'\n const entries = Array.isArray(data.checks) ? data.checks as Record<string, unknown>[] : []\n diagnosticsChecks.replaceChildren()\n const statusLabels: Record<string, string> = { ok: '正常', warning: '注意', error: '问题', info: '说明' }\n const statusOf = (entry: Record<string, unknown>): 'ok' | 'warning' | 'error' | 'info' => entry.status === 'ok' || entry.status === 'warning' || entry.status === 'error' ? entry.status : 'info'\n const appendGroup = (label: string, groupEntries: Record<string, unknown>[]): void => {\n if (groupEntries.length === 0) return\n const group = element('section', 'dsh-mobile-control__diagnostic-group')\n const groupHeader = element('header', 'dsh-mobile-control__diagnostic-group-header')\n const groupTitle = element('h3'); groupTitle.textContent = label\n const groupCount = element('span'); groupCount.textContent = `${String(groupEntries.length)} 项`\n const list = element('div', 'dsh-mobile-control__diagnostic-list'); list.setAttribute('role', 'list')\n groupHeader.append(groupTitle, groupCount)\n for (const entry of groupEntries) {\n const state = statusOf(entry)\n const row = element('section', `dsh-mobile-control__diagnostic-check is-${state}`); row.setAttribute('role', 'listitem')\n const marker = element('span', 'dsh-mobile-control__diagnostic-marker'); marker.setAttribute('aria-hidden', 'true')\n const rowBody = element('div', 'dsh-mobile-control__diagnostic-check-body')\n const rowHeader = element('div', 'dsh-mobile-control__diagnostic-check-header')\n const rowTitle = element('strong'); rowTitle.textContent = typeof entry.label === 'string' ? entry.label : '检查项'\n const badge = element('span', 'dsh-mobile-control__diagnostic-badge'); badge.textContent = statusLabels[state]!\n const detail = element('p'); detail.textContent = typeof entry.detail === 'string' ? entry.detail : ''\n rowHeader.append(rowTitle, badge); rowBody.append(rowHeader, detail)\n if (typeof entry.action === 'string' && entry.action !== '') {\n const action = element('p', 'dsh-mobile-control__diagnostic-action')\n const actionLabel = element('span'); actionLabel.textContent = '建议'\n action.append(actionLabel, document.createTextNode(entry.action)); rowBody.append(action)\n }\n row.append(marker, rowBody); list.append(row)\n }\n group.append(groupHeader, list); diagnosticsChecks.append(group)\n }\n const issues = entries.filter(entry => statusOf(entry) === 'error' || statusOf(entry) === 'warning')\n const otherChecks = entries.filter(entry => statusOf(entry) !== 'error' && statusOf(entry) !== 'warning')\n appendGroup('需要处理', issues)\n appendGroup(issues.length === 0 ? '检查详情' : '其他检查', otherChecks)\n diagnosticsSummaryMeta.textContent = issues.length === 0\n ? `${String(entries.length)} 项检查 · 未发现阻断问题`\n : `${String(entries.length)} 项检查 · ${String(issues.length)} 项需要处理`\n diagnosticsChecks.hidden = entries.length === 0\n copiedDiagnosticReport = typeof data.report === 'string' ? data.report : ''\n diagnosticsReport.textContent = copiedDiagnosticReport\n diagnosticsDetails.hidden = copiedDiagnosticReport === ''\n diagnosticsCopy.disabled = copiedDiagnosticReport === ''\n diagnosticsCopy.hidden = copiedDiagnosticReport === ''\n diagnosticsToolbar.classList.toggle('has-report', copiedDiagnosticReport !== '')\n }\n const loadDiagnostics = (): void => {\n if (diagnosticsBusy) return\n diagnosticsBusy = true\n diagnosticsRun.disabled = true\n diagnosticsRun.setAttribute('aria-busy', 'true')\n diagnosticsRun.textContent = '正在检查…'\n diagnosticsSummary.className = 'dsh-mobile-control__diagnostic-summary is-running'\n diagnosticsSummaryTitle.textContent = '正在检查连接'\n diagnosticsSummaryText.textContent = '通常几秒内完成。远程通道会执行一次真实可达性测试。'\n diagnosticsSummaryMeta.textContent = '正在运行 · 请保持 DSH 在线'\n diagnosticsFeedback.hidden = true\n diagnosticsChecks.classList.add('is-refreshing')\n diagnosticsChecks.setAttribute('aria-busy', 'true')\n void requestJson('/api/mobile-access/diagnostics').then(renderDiagnostics, error => {\n diagnosticsSummary.className = 'dsh-mobile-control__diagnostic-summary is-error'\n diagnosticsSummaryTitle.textContent = '检查未完成'\n diagnosticsSummaryText.textContent = `无法读取诊断结果:${String(error)}`\n diagnosticsSummaryMeta.textContent = '诊断服务暂不可用 · 请稍后重试'\n }).finally(() => {\n diagnosticsBusy = false\n diagnosticsRun.disabled = false\n diagnosticsRun.setAttribute('aria-busy', 'false')\n diagnosticsRun.textContent = '重新检查'\n diagnosticsChecks.classList.remove('is-refreshing')\n diagnosticsChecks.setAttribute('aria-busy', 'false')\n })\n }\n diagnosticsEntry.addEventListener('click', () => {\n if (!diagnosticsView.hidden) { selectView(previousAccessView); return }\n selectView('diagnostics'); loadDiagnostics()\n })\n diagnosticsRun.addEventListener('click', loadDiagnostics)\n diagnosticsCopy.addEventListener('click', () => {\n if (copiedDiagnosticReport === '') return\n void navigator.clipboard.writeText(copiedDiagnosticReport).then(() => {\n diagnosticsFeedback.textContent = '脱敏报告已复制,可直接粘贴到 Issue。'\n diagnosticsFeedback.hidden = false\n }, () => {\n diagnosticsDetails.open = true\n diagnosticsFeedback.textContent = '浏览器未允许复制,已展开详情,请手动复制。'\n diagnosticsFeedback.hidden = false\n })\n })\n pair.addEventListener('click', () => { pair.disabled = true; openPairing('key') })\n linkPair.addEventListener('click', () => { linkPair.disabled = true; openPairing('link') })\n close.addEventListener('click', () => { setOpen(false) })\n const dismiss = (event: PointerEvent): void => {\n if (panel.hidden || !(event.target instanceof Node)) return\n if (!providerInfo.contains(event.target)) {\n providerInfoPinned = false\n providerInfoHovered = false\n syncProviderInfo()\n }\n if (!panel.contains(event.target) && !document.querySelector('.dsh-mobile-control__trigger')?.contains(event.target)) setOpen(false)\n }\n document.addEventListener('pointerdown', dismiss)\n void requestJson('/api/mobile-access/lan/control').then(render, error => { status.textContent = String(error) })\n loadRemote()\n const remotePoll = window.setInterval(() => { if (!panel.hidden && !remoteView.hidden) loadRemote() }, 1_500)\n return { remove: () => { window.clearInterval(remotePoll); window.removeEventListener('focus', retryAfterSetup); document.removeEventListener('visibilitychange', retryAfterSetup); document.removeEventListener('pointerdown', dismiss); root.remove() }, toggle: () => { setOpen(panel.hidden !== false) } }\n}\n\nfunction mobileRequest(path: string, init: RequestInit = {}): Promise<Response> {\n const target = new URL(path, location.href)\n if (target.origin !== location.origin) throw new TypeError('mobile extension requests must stay on the DSH origin')\n const headers = new Headers(init.headers)\n const method = (init.method ?? 'GET').toUpperCase()\n if (method !== 'GET' && method !== 'HEAD') {\n const csrf = document.cookie.split(';').map(value => value.trim()).find(value => value.startsWith('dsh_ma_csrf='))?.slice(12)\n if (csrf !== undefined) headers.set('x-dsh-mobile-csrf', csrf)\n }\n return fetch(target, { ...init, headers, credentials: 'same-origin', cache: 'no-store', redirect: 'error' })\n}\n\nfunction installCustomAssets(): () => void {\n const legacyStyle = element('style'); legacyStyle.dataset.plugin = 'dsh-mobile-custom'; document.head.append(legacyStyle)\n const previous = window.dshMobile\n let legacyMount: MobileExtensionMount | undefined = queuedLegacyMount\n let legacySource = ''\n let legacyRoot: HTMLElement | undefined\n let legacyDispose: (() => void) | undefined\n const definitions = new Map<string, MobileClientDefinition>()\n const active = new Map<string, { readonly controller: AbortController; readonly dispose: () => void; readonly surfaces: Map<string, { readonly dispose: () => void; readonly container: HTMLElement }> }>()\n const styleNodes = new Map<string, HTMLStyleElement>()\n const styleEtags = new Map<string, string>()\n const scriptDigests = new Map<string, string>()\n const manifestExtensionIds = new Set<string>()\n const managedDefinitionIds = new Set<string>()\n const activationQueues = new Map<string, Promise<boolean>>()\n let manifestEtag = ''\n let expectedDefinitionId: string | undefined\n const SURFACE_HOST_STYLES: Readonly<Record<string, string>> = {\n 'sidebar-action': 'position:fixed;z-index:1100;top:calc(env(safe-area-inset-top) + 8px);left:8px;display:flex;flex-direction:column;gap:6px;pointer-events:none',\n 'header-action': 'position:fixed;z-index:1100;top:calc(env(safe-area-inset-top) + 8px);right:8px;display:flex;flex-direction:column;gap:6px;pointer-events:none',\n 'composer-dock': 'position:fixed;z-index:1100;bottom:calc(env(safe-area-inset-bottom) + 8px);left:50%;transform:translateX(-50%);display:flex;flex-direction:column;gap:6px;pointer-events:none',\n 'settings-section': 'position:fixed;z-index:1100;inset:auto 8px calc(env(safe-area-inset-bottom) + 72px) 8px;max-height:40vh;overflow:auto;pointer-events:none',\n }\n const surfaceHost = (placement: string): HTMLElement | undefined => {\n const existing = document.querySelector<HTMLElement>(`[data-dsh-mobile-surface-host=\"${placement}\"]`)\n if (existing !== null) return existing\n const style = SURFACE_HOST_STYLES[placement]\n if (style === undefined) return undefined\n const host = element('div'); host.dataset.dshMobileSurfaceHost = placement; host.style.cssText = style\n document.body.append(host); return host\n }\n const shellLayer = (): HTMLElement => {\n const existing = document.querySelector<HTMLElement>('[data-dsh-mobile-extension-layer]')\n if (existing !== null) return existing\n const layer = element('div'); layer.dataset.dshMobileExtensionLayer = 'true'; layer.style.cssText = 'position:fixed;inset:0;z-index:1200;pointer-events:none;overflow:hidden'\n document.body.append(layer); return layer\n }\n const toast = (message: string): void => {\n const node = element('div'); node.textContent = message; node.style.cssText = 'position:absolute;top:16px;left:50%;transform:translateX(-50%);padding:9px 14px;border-radius:999px;background:#1f2937;color:white;font:14px system-ui;pointer-events:auto;box-shadow:0 8px 24px #0003'\n shellLayer().append(node); window.setTimeout(() => node.remove(), 2600)\n }\n const materializeNativeFile = (value: unknown): unknown => {\n if (typeof value !== 'object' || value === null || !('base64' in value) || !('name' in value)) return value\n const candidate = value as { base64?: unknown; name?: unknown; type?: unknown }\n if (typeof candidate.base64 !== 'string' || typeof candidate.name !== 'string') return value\n try {\n const encoded = atob(candidate.base64)\n const bytes = Uint8Array.from(encoded, character => character.charCodeAt(0))\n return new File([bytes], candidate.name, { type: typeof candidate.type === 'string' ? candidate.type : 'application/octet-stream' })\n } catch {\n return value\n }\n }\n const invokeNative = async (action: string, input?: unknown): Promise<unknown> => {\n const bridge = window.__DSH_MOBILE_NATIVE__\n if (bridge !== undefined) return materializeNativeFile(await bridge.invoke(action, input))\n if (action === 'share' && typeof navigator.share === 'function') { await navigator.share((input ?? {}) as ShareData); return { ok: true } }\n if (action === 'clipboard.read' && navigator.clipboard !== undefined) return { text: await navigator.clipboard.readText() }\n if (action === 'clipboard.write' && navigator.clipboard !== undefined) { await navigator.clipboard.writeText(typeof input === 'object' && input !== null && 'text' in input ? String((input as { text: unknown }).text) : ''); return { ok: true } }\n if (action === 'files.pick' || action === 'camera.capture') {\n const inputElement = element('input'); inputElement.type = 'file'; inputElement.accept = action === 'camera.capture' ? 'image/*' : '*/*'; if (action === 'camera.capture') inputElement.capture = 'environment';\n return new Promise<File | undefined>(resolve => { inputElement.onchange = () => resolve(inputElement.files?.[0]); inputElement.click() })\n }\n throw new Error('native capability is unavailable')\n }\n const makeApi = (id: string, controller: AbortController): MobileClientApi => {\n const surfaces = active.get(id)?.surfaces ?? new Map()\n const mountSurface = (surface: MobileSurface): (() => void) => {\n if (!/^[a-z][a-z0-9-]{0,63}$/u.test(surface.id) || surface.label.length > 120) throw new Error('invalid mobile surface')\n const container = element('section'); container.dataset.dshMobileSurface = surface.id; container.hidden = surface.placement === 'page' || surface.placement === 'overlay'; container.style.cssText = surface.placement === 'page' || surface.placement === 'overlay' ? 'position:absolute;inset:0;overflow:auto;background:var(--dsw-alias-bg-layer-1,#fff);padding:16px;pointer-events:auto' : 'pointer-events:auto'\n const host = surface.placement === 'page' || surface.placement === 'overlay' ? shellLayer() : surfaceHost(surface.placement) ?? shellLayer()\n host.append(container)\n const mounted = surface.mount(container)\n const dispose = (): void => { if (typeof mounted === 'function') mounted(); container.remove() }\n surfaces.set(surface.id, { dispose, container });\n return () => { if (surfaces.get(surface.id)?.dispose === dispose) surfaces.delete(surface.id); dispose() }\n }\n return {\n host: {\n invoke: (action: string, input: unknown) => mobileRequest(`/mobile-access/extensions/${encodeURIComponent(id)}/actions/${encodeURIComponent(action)}`, { method: 'POST', body: JSON.stringify(input ?? {}) }).then(async response => { const value = await response.json() as unknown; if (!response.ok) throw new Error(typeof value === 'object' && value !== null && 'error' in value ? String((value as { error: unknown }).error) : `HTTP ${String(response.status)}`); return value }),\n fetch: (path: string, init?: RequestInit) => {\n if (!path.startsWith('/') || path.startsWith('//') || path.includes('://')\n || path.split('/').some(part => part === '..' || part === '.')) throw new TypeError('extension routes must be relative')\n return mobileRequest(`/mobile-access/extensions/${encodeURIComponent(id)}/routes${path}`, init)\n },\n },\n ui: { registerSurface: mountSurface, open: id => { const entry = surfaces.get(id); if (entry !== undefined) entry.container.hidden = false }, close: id => { const entry = surfaces.get(id); if (entry !== undefined) entry.container.hidden = true }, toast },\n native: { capabilities: async () => { const bridge = window.__DSH_MOBILE_NATIVE__; return bridge === undefined ? ['files.pick', 'camera.capture', 'share', 'clipboard.read', 'clipboard.write'] : bridge.capabilities() }, invoke: invokeNative },\n signal: controller.signal, document, window,\n }\n }\n const activateDefinitionNow = async (definition: MobileClientDefinition): Promise<boolean> => {\n const previousActive = active.get(definition.id)\n const controller = new AbortController()\n const surfaces = new Map<string, { readonly dispose: () => void; readonly container: HTMLElement }>()\n active.set(definition.id, { controller, surfaces, dispose: () => { controller.abort(); for (const surface of surfaces.values()) surface.dispose(); surfaces.clear() } })\n try {\n const cleanup = await definition.activate(makeApi(definition.id, controller))\n const current = active.get(definition.id)\n if (current === undefined || current.controller !== controller) { if (typeof cleanup === 'function') cleanup(); return false }\n const oldDispose = current.dispose\n active.set(definition.id, { ...current, dispose: () => { if (typeof cleanup === 'function') cleanup(); oldDispose() } })\n previousActive?.dispose()\n return true\n } catch {\n const current = active.get(definition.id)\n if (current?.controller === controller) {\n current.dispose(); active.delete(definition.id); if (previousActive !== undefined) active.set(definition.id, previousActive)\n }\n return false\n }\n }\n const activateDefinition = (definition: MobileClientDefinition): Promise<boolean> => {\n const previous = activationQueues.get(definition.id) ?? Promise.resolve(true)\n const task = previous.then(\n () => definitions.get(definition.id) === definition ? activateDefinitionNow(definition) : false,\n () => definitions.get(definition.id) === definition ? activateDefinitionNow(definition) : false,\n )\n activationQueues.set(definition.id, task)\n void task.finally(() => { if (activationQueues.get(definition.id) === task) activationQueues.delete(definition.id) })\n return task\n }\n const define = (definition: MobileClientDefinition): void => {\n if (definition.apiVersion !== 1 || !/^[a-z][a-z0-9-]{0,63}$/u.test(definition.id) || typeof definition.activate !== 'function') return\n if (expectedDefinitionId !== undefined && definition.id !== expectedDefinitionId) return\n definitions.set(definition.id, definition)\n if (started && expectedDefinitionId === undefined) void activateDefinition(definition)\n }\n let started = false\n window.dshMobile = Object.freeze({ register: mount => { legacyMount = mount }, define })\n for (const definition of queuedDefinitions.splice(0)) define(definition)\n let legacyJsEtag = ''\n let legacyJsModified = ''\n const refreshLegacy = async (signal?: AbortSignal): Promise<boolean> => {\n const previousMount = legacyMount\n let pendingRoot: HTMLElement | undefined\n try {\n const headers: Record<string, string> = {}\n if (legacyJsEtag !== '') headers['if-none-match'] = legacyJsEtag\n if (legacyJsModified !== '') headers['if-modified-since'] = legacyJsModified\n const response = await fetch('/mobile-access/custom.js', { credentials: 'same-origin', cache: 'no-store', headers, ...(signal === undefined ? {} : { signal }) })\n if (response.status === 304) return true\n if (!response.ok) return false\n legacyJsEtag = response.headers.get('etag') ?? ''\n legacyJsModified = response.headers.get('last-modified') ?? ''\n const next = await response.text(); if (next === legacySource) return true; legacyMount = undefined\n const script = element('script'); script.textContent = `${next}\\n//# sourceURL=dsh-mobile-custom.js`; document.head.append(script); script.remove()\n const mount = legacyMount as MobileExtensionMount | undefined\n if (mount === undefined) { legacySource = next; return true }\n const nextRoot = element('div'); pendingRoot = nextRoot; nextRoot.dataset.dshMobileExtension = 'true'; document.body.append(nextRoot)\n const nextDispose = mount({ document, request: mobileRequest, root: nextRoot, window })\n legacyDispose?.(); legacyRoot?.remove(); legacyRoot = nextRoot; pendingRoot = undefined; legacyDispose = typeof nextDispose === 'function' ? nextDispose : undefined; legacySource = next\n return true\n } catch { pendingRoot?.remove(); legacyMount = previousMount; return false }\n }\n let legacyScriptRevision = ''\n let legacyStyleRevision = ''\n const refreshExtensions = async (signal?: AbortSignal): Promise<boolean> => {\n try {\n const headers: Record<string, string> = {}\n if (manifestEtag !== '') headers['if-none-match'] = manifestEtag\n const response = await fetch('/mobile-access/extensions/manifest', { credentials: 'same-origin', cache: 'no-store', headers, ...(signal === undefined ? {} : { signal }) })\n if (response.status === 404) {\n const results = await Promise.all([refreshLegacy(signal), refreshCssLegacy(legacyStyle, signal)])\n return results.every(Boolean)\n }\n if (response.status === 304) return true\n if (!response.ok) return false\n const nextManifestEtag = response.headers.get('etag') ?? ''\n const payload = await response.json() as { extensions?: unknown; legacy?: { scriptRevision?: unknown; styleRevision?: unknown } }\n const scriptRevision = typeof payload.legacy?.scriptRevision === 'string' ? payload.legacy.scriptRevision : ''\n const styleRevision = typeof payload.legacy?.styleRevision === 'string' ? payload.legacy.styleRevision : ''\n let refreshComplete = true\n if (scriptRevision === '' || scriptRevision !== legacyScriptRevision) {\n if (await refreshLegacy(signal)) legacyScriptRevision = scriptRevision\n else refreshComplete = false\n }\n if (styleRevision === '' || styleRevision !== legacyStyleRevision) {\n if (await refreshCssLegacy(legacyStyle, signal)) legacyStyleRevision = styleRevision\n else refreshComplete = false\n }\n const entries = Array.isArray(payload.extensions) ? payload.extensions as Record<string, unknown>[] : []\n const seen = new Set<string>()\n for (const entry of entries) {\n if (typeof entry.id !== 'string') continue\n seen.add(entry.id)\n try {\n let pendingCss: string | undefined\n let pendingStyleEtag: string | undefined\n const cssUrl = typeof entry.styleUrl === 'string' ? entry.styleUrl : undefined\n if (cssUrl !== undefined) {\n const cssHeaders: Record<string, string> = {}\n const storedEtag = styleEtags.get(entry.id)\n if (storedEtag !== undefined) cssHeaders['if-none-match'] = storedEtag\n const cssResponse = await fetch(cssUrl, { credentials: 'same-origin', cache: 'no-store', headers: cssHeaders, ...(signal === undefined ? {} : { signal }) })\n if (cssResponse.status !== 304) {\n if (!cssResponse.ok) throw new Error('mobile extension style failed to load')\n pendingStyleEtag = cssResponse.headers.get('etag') ?? undefined\n pendingCss = await cssResponse.text()\n }\n }\n\n const scriptUrl = typeof entry.scriptUrl === 'string' ? entry.scriptUrl : undefined\n if (scriptUrl !== undefined) {\n const scriptHeaders: Record<string, string> = {}\n const storedDigest = scriptDigests.get(entry.id)\n if (storedDigest !== undefined) scriptHeaders['if-none-match'] = storedDigest\n const scriptResponse = await fetch(scriptUrl, { credentials: 'same-origin', cache: 'no-store', headers: scriptHeaders, ...(signal === undefined ? {} : { signal }) })\n if (scriptResponse.status !== 304) {\n if (!scriptResponse.ok) throw new Error('mobile extension script failed to load')\n const source = await scriptResponse.text()\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(source))\n const key = [...new Uint8Array(digest)].map(value => value.toString(16).padStart(2, '0')).join('')\n if (scriptDigests.get(entry.id) !== key) {\n const previousDefinition = definitions.get(entry.id)\n try {\n expectedDefinitionId = entry.id\n try {\n const script = element('script'); script.textContent = `${source}\\n//# sourceURL=dsh-mobile-extension-${entry.id}.js`; document.head.append(script); script.remove()\n } finally { expectedDefinitionId = undefined }\n const nextDefinition = definitions.get(entry.id)\n if (nextDefinition === undefined || nextDefinition === previousDefinition) throw new Error('mobile extension did not define its manifest id')\n if (!await activateDefinition(nextDefinition)) throw new Error('mobile extension activation failed')\n managedDefinitionIds.add(entry.id)\n scriptDigests.set(entry.id, key)\n } catch (error) {\n if (previousDefinition === undefined) definitions.delete(entry.id)\n else definitions.set(entry.id, previousDefinition)\n throw error\n }\n }\n }\n const definition = definitions.get(entry.id)\n if (definition !== undefined && !active.has(entry.id) && !await activateDefinition(definition)) throw new Error('mobile extension activation failed')\n }\n\n if (pendingCss !== undefined) {\n const oldStyle = styleNodes.get(entry.id)\n if (oldStyle?.textContent !== pendingCss) {\n const node = element('style'); node.dataset.dshMobileExtensionStyle = entry.id; node.textContent = pendingCss; document.head.append(node); styleNodes.set(entry.id, node); oldStyle?.remove()\n }\n if (pendingStyleEtag !== undefined && pendingStyleEtag !== '') styleEtags.set(entry.id, pendingStyleEtag)\n }\n } catch {\n refreshComplete = false\n }\n }\n for (const id of manifestExtensionIds) {\n if (seen.has(id)) continue\n active.get(id)?.dispose(); active.delete(id)\n styleNodes.get(id)?.remove(); styleNodes.delete(id); styleEtags.delete(id); scriptDigests.delete(id)\n if (managedDefinitionIds.delete(id)) definitions.delete(id)\n }\n manifestExtensionIds.clear(); for (const id of seen) manifestExtensionIds.add(id)\n manifestEtag = refreshComplete ? nextManifestEtag : ''\n return refreshComplete\n } catch { return false }\n }\n started = true\n for (const definition of definitions.values()) void activateDefinition(definition)\n const remoteOrigin = window.location.hostname.endsWith('.ts.net') || window.location.hostname.includes('.cpolar.')\n const refreshIntervalMs = remoteOrigin ? 15_000 : 3_000\n const refreshTimeoutMs = remoteOrigin ? 20_000 : 8_000\n let stopped = false\n let refreshTimer: number | undefined\n let refreshFailures = 0\n let refreshController: AbortController | undefined\n const scheduleRefresh = (delayMs: number): void => {\n if (stopped || document.visibilityState === 'hidden' || !navigator.onLine) return\n if (refreshTimer !== undefined) clearTimeout(refreshTimer)\n refreshTimer = window.setTimeout(runRefresh, delayMs)\n }\n const runRefresh = (): void => {\n if (stopped || refreshController !== undefined) return\n refreshController = new AbortController()\n const controller = refreshController\n const timeout = window.setTimeout(() => { controller.abort() }, refreshTimeoutMs)\n void refreshExtensions(controller.signal).then(success => {\n refreshFailures = success ? 0 : refreshFailures + 1\n }).finally(() => {\n clearTimeout(timeout)\n if (refreshController === controller) refreshController = undefined\n const backoff = Math.min(60_000, refreshIntervalMs * (2 ** Math.min(refreshFailures, 3)))\n scheduleRefresh(backoff)\n })\n }\n const resumeRefresh = (): void => {\n if (document.visibilityState !== 'hidden' && navigator.onLine) scheduleRefresh(0)\n }\n document.addEventListener('visibilitychange', resumeRefresh)\n window.addEventListener('online', resumeRefresh)\n scheduleRefresh(0)\n return () => { stopped = true; if (refreshTimer !== undefined) clearTimeout(refreshTimer); refreshController?.abort(); document.removeEventListener('visibilitychange', resumeRefresh); window.removeEventListener('online', resumeRefresh); started = false; legacyDispose?.(); legacyRoot?.remove(); legacyStyle.remove(); for (const current of active.values()) current.dispose(); for (const node of styleNodes.values()) node.remove(); const layer = document.querySelector('[data-dsh-mobile-extension-layer]'); layer?.remove(); for (const host of document.querySelectorAll('[data-dsh-mobile-surface-host]')) host.remove(); if (previous === undefined) delete window.dshMobile; else window.dshMobile = previous }\n}\n\nlet cssEtag = ''\nlet cssModified = ''\nasync function refreshCssLegacy(style: HTMLStyleElement, signal?: AbortSignal): Promise<boolean> {\n try {\n const headers: Record<string, string> = {}\n if (cssEtag !== '') headers['if-none-match'] = cssEtag\n if (cssModified !== '') headers['if-modified-since'] = cssModified\n const response = await fetch('/mobile-access/custom.css', { credentials: 'same-origin', cache: 'no-store', headers, ...(signal === undefined ? {} : { signal }) })\n if (response.status === 304) return true\n if (response.ok) {\n cssEtag = response.headers.get('etag') ?? ''\n cssModified = response.headers.get('last-modified') ?? ''\n style.textContent = await response.text()\n return true\n }\n return false\n } catch { return false }\n}\n\nconst CONTROL_STYLES = `\n.dsh-mobile-control{position:fixed;z-index:1000;left:16px;bottom:112px;font:14px/1.45 system-ui;color:var(--dsw-alias-label-primary,#16181d)}\n.dsh-mobile-control__panel{box-sizing:border-box;width:min(380px,calc(100vw - 32px));max-height:calc(100vh - 140px);overflow-y:auto;padding:16px;border:1px solid var(--dsw-alias-border-subtle,#e1e5eb);border-radius:18px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:0 18px 50px rgb(15 23 42 / 18%)}\n.dsh-mobile-control__header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}.dsh-mobile-control__panel h2{margin:0;font-size:17px;line-height:24px}.dsh-mobile-control__header-actions{display:flex;align-items:center;gap:2px}.dsh-mobile-control__diagnostic-entry,.dsh-mobile-control__close{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:44px;padding:0;border:0;border-radius:10px;background:transparent;color:inherit;cursor:pointer}.dsh-mobile-control__diagnostic-entry{padding:0 9px;color:#2563eb;font:650 12px/1 system-ui}.dsh-mobile-control__close{font-size:24px;line-height:1}.dsh-mobile-control__diagnostic-entry:hover,.dsh-mobile-control__close:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f3f6)}\n.dsh-mobile-control__app-download{display:flex;align-items:center;justify-content:space-between;box-sizing:border-box;min-height:38px;margin:0 0 10px;padding:8px 11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f7f8fa);color:var(--dsw-alias-label-primary,#16181d);font:600 12px/1.3 system-ui;text-decoration:none}.dsh-mobile-control__app-download[hidden]{display:none}.dsh-mobile-control__app-download::after{color:#2563eb;font-size:14px;content:\"↗\"}.dsh-mobile-control__app-download:hover{border-color:#9fb9e8;background:#f5f8ff;color:#1d4ed8}\n.dsh-mobile-control__switcher{display:grid;grid-template-columns:repeat(2,1fr);gap:4px;margin:0 0 14px;padding:4px;border-radius:12px;background:var(--dsw-alias-bg-layer-1,#f3f5f8)}.dsh-mobile-control__switcher[hidden]{display:none}.dsh-mobile-control__tab{min-height:36px;border:0;border-radius:9px;background:transparent;color:var(--dsw-alias-label-secondary,#606873);font:600 13px/1 system-ui;cursor:pointer}.dsh-mobile-control__tab.is-active{background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);box-shadow:0 1px 3px rgb(15 23 42 / 10%)}.dsh-mobile-control__view[hidden]{display:none}.dsh-mobile-control__intro{margin:0 0 12px;color:var(--dsw-alias-label-secondary,#606873);font-size:12px;line-height:1.55}.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions button[hidden]{display:none}\n.dsh-mobile-control__provider-section{position:relative;margin:0 0 12px}.dsh-mobile-control__section-title{margin:0 0 8px;color:var(--dsw-alias-label-primary,#16181d);font:650 13px/1.4 system-ui}.dsh-mobile-control__provider-section>.dsh-mobile-control__section-title{padding-right:42px}.dsh-mobile-control__provider-choices{display:grid;gap:8px}.dsh-mobile-control__provider{display:flex;flex-direction:column;gap:5px;min-height:68px;padding:11px 12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:#fff;color:inherit;text-align:left;cursor:pointer;transition:border-color 160ms ease,background-color 160ms ease,box-shadow 160ms ease}.dsh-mobile-control__provider:hover{border-color:#9fb9e8;background:#f8fbff}.dsh-mobile-control__provider.is-selected{border-color:#2563eb;background:#f5f8ff;box-shadow:0 0 0 1px #2563eb inset}.dsh-mobile-control__provider:disabled{cursor:wait;opacity:.62}.dsh-mobile-control__provider-top{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsh-mobile-control__provider-top strong{font-size:13px}.dsh-mobile-control__provider-badge{flex:none;padding:3px 7px;border-radius:999px;background:#e8f0ff;color:#1d4ed8;font:650 10px/1.2 system-ui}.dsh-mobile-control__provider-badge.is-cpolar{background:#eaf8f2;color:#087454}.dsh-mobile-control__provider-description{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.45}.dsh-mobile-control__provider-info{position:absolute;z-index:5;top:-13px;right:-8px}.dsh-mobile-control__provider-info-button{display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:transparent;color:#475569;cursor:pointer;touch-action:manipulation}.dsh-mobile-control__provider-info-button:hover{background:#f1f5f9;color:#1d4ed8}.dsh-mobile-control__provider-info-glyph{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:18px;height:18px;border:1.5px solid currentColor;border-radius:50%;font:700 12px/1 system-ui}.dsh-mobile-control__provider-info-popover{position:absolute;z-index:6;top:38px;right:4px;box-sizing:border-box;width:min(292px,calc(100vw - 72px));padding:10px 12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:0 10px 28px rgb(15 23 42 / 16%)}.dsh-mobile-control__provider-info-popover[hidden]{display:none}.dsh-mobile-control__provider-info-popover strong,.dsh-mobile-control__provider-info-popover span{display:block}.dsh-mobile-control__provider-info-popover strong{margin-bottom:3px;font-size:12px}.dsh-mobile-control__provider-info-popover span{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.55}\n.dsh-mobile-control__cpolar-setup{margin:0 0 12px;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:#fff}.dsh-mobile-control__cpolar-setup[hidden],.dsh-mobile-control__cpolar-account[hidden],.dsh-mobile-control__details[hidden],.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions[hidden],.dsh-mobile-control__danger[hidden]{display:none}.dsh-mobile-control__component-status,.dsh-mobile-control__component-note{margin:0 0 10px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.55}.dsh-mobile-control__cpolar-setup>.dsh-mobile-control__primary{width:100%;min-height:44px;padding:9px 12px;border-radius:10px;font:600 12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__cpolar-account{margin-top:10px}.dsh-mobile-control__link-row{display:flex;flex-wrap:wrap;gap:6px 12px;margin:0 0 10px}.dsh-mobile-control__text-link{color:#2563eb;font-size:11px;text-decoration:none}.dsh-mobile-control__text-link:hover{text-decoration:underline}.dsh-mobile-control__token-label{display:flex;flex-direction:column;gap:5px;margin:0 0 8px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px}.dsh-mobile-control__token{box-sizing:border-box;width:100%;min-height:44px;padding:9px 10px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:10px;background:#fff;color:inherit;font:16px/1.4 system-ui}.dsh-mobile-control__cpolar-connect{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:100%;min-height:44px;padding:10px 14px;border-radius:12px;font:650 13px/1.2 system-ui;cursor:pointer;transition:background-color 160ms ease,border-color 160ms ease,opacity 160ms ease}.dsh-mobile-control__cpolar-connect:hover:not(:disabled){border-color:#1d4ed8;background:#1d4ed8}.dsh-mobile-control__cpolar-connect:active:not(:disabled){border-color:#1e40af;background:#1e40af}.dsh-mobile-control__cpolar-connect:disabled{cursor:wait;opacity:.55}.dsh-mobile-control__details{margin:10px 0 0;border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb);padding-top:9px}.dsh-mobile-control__details>summary{min-height:30px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:30px;cursor:pointer}.dsh-mobile-control__details-body{display:flex;flex-wrap:wrap;align-items:center;gap:7px 12px;padding:4px 0}.dsh-mobile-control__details-body p{flex:1 0 100%;margin:0;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__storage{display:block;flex:1 0 100%;max-width:100%;overflow:hidden;padding:7px 8px;border-radius:8px;background:#f3f5f8;color:#475569;font:10px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__danger{flex:1 0 100%;min-height:38px;margin-top:3px;padding:7px 10px;border:1px solid #dc2626;border-radius:9px;background:transparent;color:#b91c1c;font:12px/1.3 system-ui;cursor:pointer}\n.dsh-mobile-control__access{display:flex;align-items:baseline;gap:6px;min-width:0;margin:0 0 12px}.dsh-mobile-control__access[hidden]{display:none}.dsh-mobile-control__access-label{flex:none;color:var(--dsw-alias-label-secondary,#606873);white-space:nowrap}.dsh-mobile-control__access-label::after{content:\":\"}.dsh-mobile-control__access-link{min-width:0;overflow:hidden;color:#2563eb;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__access-link:hover{text-decoration:underline}.dsh-mobile-control__qr{display:flex;justify-content:center;margin:0 0 12px}.dsh-mobile-control__qr[hidden]{display:none}.dsh-mobile-control__qr img{border-radius:12px;background:#fff;padding:8px}\n.dsh-mobile-control__status{margin:0 0 14px;overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary,#606873)}.dsh-mobile-control__status::before{display:inline-block;width:8px;height:8px;margin-right:7px;border-radius:50%;background:#98a1ad;content:\"\"}.dsh-mobile-control__status.is-running::before{background:#16a36a}.dsh-mobile-control__status.is-key{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;word-break:break-all}\n.dsh-mobile-control__guide{margin:0 0 14px;padding:12px;border:1px solid #bfdbfe;border-radius:12px;background:#eff6ff}.dsh-mobile-control__guide[hidden]{display:none}.dsh-mobile-control__guide-title{margin:0;color:#172554;font:650 13px/1.45 system-ui}.dsh-mobile-control__guide-summary,.dsh-mobile-control__guide-note{margin:4px 0 0;color:#475569;font-size:12px;line-height:1.5}.dsh-mobile-control__guide-steps{margin:8px 0 0;padding-left:20px;color:#1e293b;font-size:12px;line-height:1.6}.dsh-mobile-control__guide-note{color:#64748b}.dsh-mobile-control__guide-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px}.dsh-mobile-control__guide-actions button{min-width:0;min-height:44px;padding:8px;border-radius:10px;font:12px/1.25 system-ui;cursor:pointer}.dsh-mobile-control__guide-actions button:disabled{cursor:not-allowed;opacity:.45}\n.dsh-mobile-control__extensions{margin:0 0 12px;color:var(--dsw-alias-label-secondary,#606873);font-size:12px}\n.dsh-mobile-control__view.is-diagnostics{--dsh-diagnostic-ok:#087454;--dsh-diagnostic-warning:#a35b00;--dsh-diagnostic-error:#c62828;--dsh-diagnostic-info:#526071}.dsh-mobile-control__diagnostic-summary{box-sizing:border-box;margin:0;padding:13px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:16px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__diagnostic-summary-main{display:grid;grid-template-columns:36px minmax(0,1fr);align-items:center;gap:11px}.dsh-mobile-control__diagnostic-summary-icon{position:relative;display:block;width:36px;height:36px;border-radius:50%;background:#e8edf3;color:var(--dsh-diagnostic-info)}.dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-summary-icon::after{position:absolute;content:\"\"}.dsh-mobile-control__diagnostic-summary-body{display:flex;min-width:0;flex-direction:column;gap:2px}.dsh-mobile-control__diagnostic-summary-body strong{font-size:13px;line-height:1.35}.dsh-mobile-control__diagnostic-summary-body span{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__diagnostic-summary-meta{display:block;margin-top:11px;padding-top:9px;border-top:1px solid var(--dsw-alias-border-subtle,#dbe1e8);color:var(--dsw-alias-label-secondary,#606873);font-size:10px;line-height:1.45}.dsh-mobile-control__diagnostic-summary.is-ok .dsh-mobile-control__diagnostic-summary-icon{background:#e6f7f0;color:var(--dsh-diagnostic-ok)}.dsh-mobile-control__diagnostic-summary.is-ok .dsh-mobile-control__diagnostic-summary-icon::before{top:10px;left:10px;width:13px;height:7px;border-bottom:2px solid currentColor;border-left:2px solid currentColor;transform:rotate(-45deg)}.dsh-mobile-control__diagnostic-summary.is-attention .dsh-mobile-control__diagnostic-summary-icon{background:#fff4dc;color:var(--dsh-diagnostic-warning)}.dsh-mobile-control__diagnostic-summary.is-error .dsh-mobile-control__diagnostic-summary-icon{background:#fdecec;color:var(--dsh-diagnostic-error)}.dsh-mobile-control__diagnostic-summary.is-attention .dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-summary.is-error .dsh-mobile-control__diagnostic-summary-icon::before{top:8px;left:17px;width:2px;height:13px;border-radius:2px;background:currentColor}.dsh-mobile-control__diagnostic-summary.is-attention .dsh-mobile-control__diagnostic-summary-icon::after,.dsh-mobile-control__diagnostic-summary.is-error .dsh-mobile-control__diagnostic-summary-icon::after{bottom:8px;left:17px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon{background:#e8f0ff;color:#2563eb}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon::before{inset:9px;border:2px solid rgb(37 99 235 / 24%);border-top-color:currentColor;border-radius:50%;animation:dsh-diagnostic-spin .8s linear infinite}\n.dsh-mobile-control__diagnostic-summary.is-idle .dsh-mobile-control__diagnostic-summary-icon::before{top:8px;left:17px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-summary.is-idle .dsh-mobile-control__diagnostic-summary-icon::after{top:13px;left:17px;width:2px;height:11px;border-radius:2px;background:currentColor}\n.dsh-mobile-control__diagnostic-toolbar{display:grid;grid-template-columns:1fr;gap:8px;margin-top:10px}.dsh-mobile-control__diagnostic-toolbar.has-report{grid-template-columns:1fr 1fr}.dsh-mobile-control__diagnostic-run,.dsh-mobile-control__diagnostic-copy{box-sizing:border-box;width:100%;min-height:44px;padding:9px 10px;border-radius:11px;font:650 12px/1.3 system-ui;cursor:pointer;touch-action:manipulation}.dsh-mobile-control__diagnostic-copy[hidden]{display:none}.dsh-mobile-control__diagnostic-run:disabled{cursor:wait;opacity:.58}.dsh-mobile-control__diagnostic-feedback{margin:8px 0 0;padding:8px 10px;border-radius:9px;background:#eff6ff;color:#1d4ed8;font-size:11px;line-height:1.45}.dsh-mobile-control__diagnostic-feedback[hidden]{display:none}\n.dsh-mobile-control__diagnostic-checks{display:grid;gap:12px;margin-top:12px;animation:dsh-diagnostic-reveal 160ms ease-out both}.dsh-mobile-control__diagnostic-checks[hidden]{display:none}.dsh-mobile-control__diagnostic-group{overflow:hidden;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__diagnostic-group-header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 11px;border-bottom:1px solid var(--dsw-alias-border-subtle,#e1e5eb);background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__diagnostic-group-header h3{margin:0;font:650 11px/1.4 system-ui}.dsh-mobile-control__diagnostic-group-header span{color:var(--dsw-alias-label-secondary,#606873);font-size:10px}.dsh-mobile-control__diagnostic-list{display:flex;flex-direction:column}.dsh-mobile-control__diagnostic-check{display:grid;grid-template-columns:26px minmax(0,1fr);gap:9px;padding:11px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__diagnostic-check + .dsh-mobile-control__diagnostic-check{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__diagnostic-marker{position:relative;width:26px;height:26px;border-radius:50%;background:#edf1f5;color:var(--dsh-diagnostic-info)}.dsh-mobile-control__diagnostic-marker::before,.dsh-mobile-control__diagnostic-marker::after{position:absolute;content:\"\"}.dsh-mobile-control__diagnostic-check.is-ok .dsh-mobile-control__diagnostic-marker{background:#e6f7f0;color:var(--dsh-diagnostic-ok)}.dsh-mobile-control__diagnostic-check.is-ok .dsh-mobile-control__diagnostic-marker::before{top:7px;left:7px;width:9px;height:5px;border-bottom:1.8px solid currentColor;border-left:1.8px solid currentColor;transform:rotate(-45deg)}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-marker{background:#fff4dc;color:var(--dsh-diagnostic-warning)}.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-marker{background:#fdecec;color:var(--dsh-diagnostic-error)}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-marker::before,.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-marker::before{top:6px;left:12px;width:2px;height:9px;border-radius:2px;background:currentColor}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-marker::after,.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-marker::after{bottom:6px;left:12px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-check.is-info .dsh-mobile-control__diagnostic-marker::before{top:6px;left:12px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-check.is-info .dsh-mobile-control__diagnostic-marker::after{top:10px;left:12px;width:2px;height:9px;border-radius:2px;background:currentColor}.dsh-mobile-control__diagnostic-check-body{min-width:0}.dsh-mobile-control__diagnostic-check-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.dsh-mobile-control__diagnostic-check-header strong{min-width:0;font-size:12px;line-height:1.4}.dsh-mobile-control__diagnostic-badge{flex:none;padding:2px 6px;border-radius:999px;background:#edf1f5;color:var(--dsh-diagnostic-info);font:650 10px/1.3 system-ui}.dsh-mobile-control__diagnostic-check.is-ok .dsh-mobile-control__diagnostic-badge{background:#e6f7f0;color:var(--dsh-diagnostic-ok)}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-badge{background:#fff4dc;color:var(--dsh-diagnostic-warning)}.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-badge{background:#fdecec;color:var(--dsh-diagnostic-error)}.dsh-mobile-control__diagnostic-check p{margin:4px 0 0;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5;overflow-wrap:anywhere}.dsh-mobile-control__diagnostic-check .dsh-mobile-control__diagnostic-action{margin-top:7px;padding:7px 8px;border-radius:8px;background:var(--dsw-alias-bg-layer-1,#f8fafc);color:var(--dsw-alias-label-primary,#16181d)}.dsh-mobile-control__diagnostic-action span{display:inline-block;margin-right:6px;color:#2563eb;font-weight:700}.dsh-mobile-control__diagnostic-details{margin-top:12px}.dsh-mobile-control__diagnostic-details[hidden]{display:none}.dsh-mobile-control__diagnostic-details>summary{box-sizing:border-box;min-height:44px;line-height:44px}.dsh-mobile-control__diagnostic-report{box-sizing:border-box;max-height:220px;margin:4px 0 0;overflow:auto;padding:10px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:10px;background:var(--dsw-alias-bg-layer-1,#f3f5f8);color:var(--dsw-alias-label-secondary,#606873);font:10px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}\n.dsh-mobile-control__diagnostic-checks{transition:opacity 150ms ease}.dsh-mobile-control__diagnostic-checks.is-refreshing{opacity:.52}\n@keyframes dsh-diagnostic-spin{to{transform:rotate(360deg)}}@keyframes dsh-diagnostic-reveal{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n.dsh-mobile-control__actions{display:flex;flex-wrap:nowrap;gap:6px}.dsh-mobile-control__actions button{flex:1 1 0;min-width:0;min-height:40px;padding:8px 4px;border-radius:10px;font:12px/1.2 system-ui;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dsh-mobile-control__secondary{border:1px solid var(--dsw-alias-border-normal,#cfd5dd);background:transparent;color:inherit}.dsh-mobile-control__primary{border:1px solid #2563eb;background:#2563eb;color:#fff}.dsh-mobile-control__actions button:disabled{cursor:not-allowed;opacity:.45}\n.dsh-mobile-control button:focus-visible,.dsh-mobile-control a:focus-visible,.dsh-mobile-control input:focus-visible,.dsh-mobile-control summary:focus-visible{outline:3px solid rgb(37 99 235 / 28%);outline-offset:2px}\n.dsh-mobile-control__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:calc(100% + 8px);height:34px;margin:4px -4px;padding:6px 2px 6px 10px;border:0;border-radius:12px;background:transparent;color:var(--dsw-alias-label-primary,#16181d);font:14px/22px system-ui;cursor:pointer}.dsh-mobile-control__trigger:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f3f6)}.dsh-mobile-control__trigger.is-rail{width:36px;height:36px;margin:8px 0 10px;padding:0;justify-content:center;border-radius:50%}.dsh-mobile-control__trigger-icon{position:relative;box-sizing:border-box;flex:none;width:14px;height:19px;border:1.7px solid currentColor;border-radius:3px}.dsh-mobile-control__trigger-icon::after{position:absolute;right:4px;bottom:2px;width:4px;height:1.5px;border-radius:2px;background:currentColor;content:\"\"}.dsh-mobile-control__trigger-label{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}\n.dsh-mobile-control__manage-row{display:flex;justify-content:space-between;gap:8px;margin-top:10px}.dsh-mobile-control__manage{flex:1 1 0;min-width:0;min-height:34px;padding:6px 8px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:10px;background:transparent;color:inherit;font:12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__devices{margin-top:10px;border:1px solid var(--dsw-alias-border-subtle,#e1e5eb);border-radius:10px;padding:8px;max-height:220px;overflow-y:auto}.dsh-mobile-control__device-empty{color:var(--dsw-alias-label-secondary,#606873);font-size:12px;margin:0}.dsh-mobile-control__device{display:flex;align-items:center;gap:8px;padding:6px 2px}.dsh-mobile-control__device + .dsh-mobile-control__device{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__device-label{flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.dsh-mobile-control__device-meta{flex:none;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;white-space:nowrap}.dsh-mobile-control__device-revoke{flex:none;min-height:28px;padding:4px 8px;border:1px solid #dc2626;border-radius:8px;background:transparent;color:#dc2626;font:12px/1.2 system-ui;cursor:pointer}\n@media (prefers-reduced-motion:reduce){.dsh-mobile-control__provider,.dsh-mobile-control__cpolar-connect{transition:none}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-checks{animation:none}}\n`\n\n/** Mount the desktop control or mobile feature enhancements. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n if (window.__DSH_MOBILE_FRONTEND__ !== 'dedicated') return\n return trustAuthenticatedGatewayConnection(ctx.get('connection'))\n }, 'dsh-mobile: authenticated gateway client trust')\n\n ctx.effect(() => {\n const loopback = isLoopbackHost(location.hostname) && !new URLSearchParams(location.search).has('dsh-mobile-preview')\n const style = element('style'); style.dataset.plugin = 'dsh-mobile'; style.textContent = loopback\n ? CONTROL_STYLES\n : NATIVE_MOBILE_STYLES\n document.head.append(style)\n if (!loopback) {\n const removeCustom = installCustomAssets()\n const removeSurface = installNativeMobileSurface()\n return () => { removeCustom(); removeSurface(); style.remove() }\n }\n const control = installControl()\n const disposeSlot = ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register<{ wide: boolean }>({ name: 'sidebar.footer.action', id: 'dsh-mobile' }, ({ wide }) => createElement('button', {\n 'aria-expanded': false,\n 'aria-label': '移动访问',\n className: `dsh-mobile-control__trigger${wide ? '' : ' is-rail'}`,\n type: 'button',\n title: '移动访问',\n onClick: control.toggle,\n }, createElement('span', { 'aria-hidden': true, className: 'dsh-mobile-control__trigger-icon' }), wide ? createElement('span', { className: 'dsh-mobile-control__trigger-label' }, '移动访问') : undefined)))\n return () => { disposeSlot(); control.remove(); style.remove() }\n }, 'dsh-mobile: stock mobile adaptation and local control')\n}\n\n/** Client services required by the mobile adaptation. */\nexport const inject: readonly string[] = ['slots']\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["createElement"],"sources":["../src/client-messages.ts","../src/native-mobile.ts","../src/client.ts"],"sourcesContent":["export type MobileControlLocale = 'it' | 'en' | 'zh'\n\nexport const MOBILE_CONTROL_MESSAGES = {\n en: {\n mobileAccess: 'Mobile access', collapseMobileAccess: 'Collapse Mobile access', downloadAndroid: 'Download Android app', downloadAndroidAria: 'Download the latest Android app from GitHub Releases',\n lan: 'Local network', remote: 'Remote', lanAccess: 'Local network access', remoteAccess: 'Remote access', browserAccess: 'Browser access', remoteAddress: 'Remote address', loadingStatus: 'Loading status…', loadingRemoteStatus: 'Loading remote status…',\n generateCopyKey: 'Generate and copy key', copyPairLink: 'Copy pairing link', managePairedDevices: 'Manage paired devices', clearAllDevices: 'Clear all devices', pairingQr: 'Pairing QR code',\n remoteIntro: 'Choose the remote channel that suits you. Switching or disabling remote access does not affect the local network.', chooseProvider: 'Choose connection method', providerInfoAria: 'View remote connection security and network information', providerGroupAria: 'Remote connection method', providerSafeTitle: 'You remain protected', providerSafeText: 'Only paired devices can access DSH. cpolar is installed on demand and can be removed completely; Tailscale may be slow or unavailable on mainland China networks, where cpolar is recommended.',\n builtIn: 'Built in', mainlandPreferred: 'Preferred in mainland China', tailscaleDescription: 'Wider coverage; mainland China networks may be unstable. The first connection requires login and Funnel authorization.', cpolarDescription: 'Installs the official component on demand and is suitable for mainland China networks.',\n prepareCpolar: 'Prepare cpolar', checkingComponent: 'Checking component…', installOfficial: 'Install official component', cpolarAccountNote: 'Sign in to the cpolar website and copy the Authtoken. The token is stored only in the plugin private directory and is never shown on the page or in logs.', registerCpolar: 'Register with cpolar', openDashboard: 'Open dashboard to get token', tokenPlaceholder: 'Paste cpolar Authtoken', saveConnect: 'Save and connect', saving: 'Saving…', componentDetails: 'Component source and cleanup', componentDetailsText: 'Downloaded from the official cpolar website and verified at a fixed version only after you choose Install. It does not add a system service, startup item, registry entry, or PATH entry.', pluginPrivateDirectory: 'Plugin private directory', officialDownload: 'Official download page', terms: 'Terms of service', purgeCpolar: 'Completely remove cpolar component and configuration', tailscaleHelp: 'How to use Tailscale', tailscaleHelpText: 'The runtime component is included with the plugin. The first connection opens the official Tailscale login and Funnel authorization pages; the plugin never accesses your account password.',\n funnelGuideAria: 'Steps to enable Tailscale Funnel', funnelGuideTitle: 'Remote access setup · Step 2', funnelGuideSummary: 'Tailscale login is complete. Funnel must still be allowed for this computer; the official page also enables HTTPS.', funnelStep1: 'Open the official Tailscale authorization page for this node.', funnelStep2: 'Confirm Funnel; you do not need to sign in to DSH again.', funnelStep3: 'Return to DSH; the plugin checks and connects automatically.', funnelGuideNote: 'Requires an Owner, Admin, or Network admin account.', continueFunnel: 'Continue Funnel authorization', retryNow: 'Done, retry now',\n enableRemote: 'Enable remote access', disableRemote: 'Disable remote access', continueLogin: 'Continue login', reconnect: 'Reconnect', generateRemoteQr: 'Generate remote pairing QR code', manageRemoteDevices: 'Manage remote devices', resetRemoteLogin: 'Sign out and clear remote login', resetRemoteDevices: 'Disable and clear remote devices',\n lanOn: 'Local network access is on.', lanOff: 'Local network access is off.', enableLan: 'Enable local network access', disableLan: 'Disable local network access', extensionsLoaded: 'Extensions: {loaded} loaded', extensionsFailed: 'Extensions: {loaded} loaded, {failed} failed',\n keyGenerationFailed: 'Could not generate a pairing key.', keyCopied: 'Pairing key copied. Paste it into the Android app.', linkCopied: 'Pairing link copied. Send it to the phone and paste it into the app or open it in a browser.', copySecret: 'Copy {kind}: {value}', pairingKey: 'pairing key', pairingLink: 'pairing link', noDevices: 'No paired devices.', noRemoteDevices: 'No remote paired devices.', device: 'Device', expires: 'Expires {time}', revoke: 'Revoke', confirmResetDevices: 'Remove all paired devices? Connected devices will be disconnected immediately.',\n ready: 'Ready', installed: 'Installed', installWithSize: 'Install official component · {size} MB', cpolarUnsupported: 'Only Windows x64 is currently supported. You can still use the built-in Tailscale Funnel.', cpolarNotInstalled: 'Not installed. A fixed version is downloaded from the official cpolar website only after you click the button below.', cpolarNeedsToken: 'Official component {version} is verified. Save the account token to continue.', cpolarReady: 'Official component {version} and the local account configuration are ready.',\n remoteOff: 'Remote access is disabled. Local network access is unaffected.', remoteUnavailableCpolar: 'cpolar is not installed or its local account is not configured.', remoteUnavailableTailscale: 'This computer is missing the Funnel runtime component. Reinstall the complete plugin package.', remoteStartingCpolar: 'Connecting to a cpolar node…', remoteStartingTailscale: 'Starting the secure Tailscale channel…', remoteNeedsLogin: 'Complete a one-time Tailscale login in the browser. The plugin never reads your password.', remoteConnectingCpolar: 'Public address allocated; starting the DSH authentication gateway…', remoteConnectingTailscale: 'Login complete; creating the public HTTPS address…', remoteReady: 'Remote access is ready. Only paired devices can access DSH.', remoteError: 'The remote connection was not established. Reconnect; local network access still works.',\n funnelPermission: 'Login is complete. Authorize Funnel to establish the remote connection automatically.', funnelHttps: 'Login is complete. Authorize Funnel; the official page also enables HTTPS.', funnelStart: 'Login is complete. Finish the initial Tailscale Funnel authorization.', tailscaleDnsMissing: 'Tailscale has not provided a remote address. Reconnect and confirm login is complete.', gatewayStartFailed: 'The remote gateway failed to start. Reconnect; local network access is unaffected.', controlChannelFailed: 'The remote component connection was interrupted. Reconnect.', cpolarMissing: 'The official cpolar component is not installed. Complete the preparation steps above.', cpolarInvalid: 'cpolar component verification failed. Remove it completely and reinstall.', cpolarConfigMissing: 'No cpolar account token is saved. Complete the preparation steps above.', cpolarConfigInvalid: 'The local cpolar configuration is invalid. Save the account token again.', cpolarPortUnavailable: 'Could not allocate a local remote-gateway port. Try again.', cpolarLaunchFailed: 'The cpolar client failed to start.', cpolarTimeout: 'Timed out connecting to a cpolar node. Reconnect.', cpolarStopped: 'The cpolar connection stopped.', cpolarExited: 'The cpolar connection exited unexpectedly. Reconnect.', cpolarOutputInvalid: 'cpolar returned an unrecognized status.', cpolarOriginInvalid: 'The public address returned by cpolar failed validation.', setupOpened: 'The official Tailscale page is open. Return to DSH after enabling Funnel; reconnection is automatic.',\n switchProviderConfirm: 'Switching connection method first disables the current remote channel. Local network access and paired devices are unaffected. Continue?', switchingCpolar: 'Switching to cpolar…', switchingTailscale: 'Switching to Tailscale Funnel…', installConfirm: 'Download and verify a fixed version from the official cpolar website (about 7.3 MB) and extract it only to the DSH Mobile private directory? No system service, PATH/registry entry, or startup item is added.', downloading: 'Downloading and verifying…', installingCpolar: 'Installing the official cpolar component. Keep DSH running until it completes.', installFailed: 'Component installation failed: {error}', invalidToken: 'Paste the complete Authtoken from the cpolar dashboard.', configuredConnecting: 'Account configuration saved; connecting through cpolar…', configureFailed: 'Configuration failed: {error}', purgeConfirm: 'Completely remove the cpolar component, token configuration, and runtime logs from the DSH Mobile private directory? Local network access, DSH data, and other system programs are unaffected.', purging: 'Stopping the channel and removing cpolar files managed by DSH Mobile…', purgeFailed: 'Cleanup failed: {error}', reconnectingCpolar: 'Reconnecting to a cpolar node…', reconnectingTailscale: 'Checking Tailscale settings and reconnecting…', remoteQrReady: 'Remote pairing QR code generated. Scan it from “Remote access” in the app.', resetCpolarConfirm: 'Disable the cpolar remote channel and remove all remote paired devices? Your cpolar account and other tunnels are unchanged.', resetTailscaleConfirm: 'Sign out of Tailscale on this computer and remove all remote paired devices? Local network configuration is unchanged.', requestFailed: 'Request failed: {error}',\n },\n it: {\n mobileAccess: 'Accesso mobile', collapseMobileAccess: 'Riduci Accesso mobile', downloadAndroid: 'Scarica app Android', downloadAndroidAria: 'Scarica l’ultima app Android da GitHub Releases',\n lan: 'Rete locale', remote: 'Remoto', lanAccess: 'Accesso rete locale', remoteAccess: 'Accesso remoto', browserAccess: 'Accesso browser', remoteAddress: 'Indirizzo remoto', loadingStatus: 'Lettura stato…', loadingRemoteStatus: 'Lettura stato remoto…',\n generateCopyKey: 'Genera e copia chiave', copyPairLink: 'Copia link di abbinamento', managePairedDevices: 'Gestisci dispositivi abbinati', clearAllDevices: 'Rimuovi tutti i dispositivi', pairingQr: 'Codice QR di abbinamento', remoteIntro: 'Scegli il canale remoto più adatto. Cambiare o disattivare l’accesso remoto non influisce sulla rete locale.', chooseProvider: 'Scegli metodo di connessione', providerInfoAria: 'Informazioni su sicurezza e rete della connessione remota', providerGroupAria: 'Metodo di connessione remota', providerSafeTitle: 'La protezione resta attiva', providerSafeText: 'Solo i dispositivi abbinati possono accedere a DSH. cpolar viene installato su richiesta e può essere rimosso completamente; Tailscale può essere lento o non disponibile nelle reti della Cina continentale, dove è consigliato cpolar.',\n builtIn: 'Integrato', mainlandPreferred: 'Preferito in Cina continentale', tailscaleDescription: 'Copertura più ampia; le reti della Cina continentale possono essere instabili. Il primo collegamento richiede accesso e autorizzazione Funnel.', cpolarDescription: 'Installa su richiesta il componente ufficiale, adatto alle reti della Cina continentale.', prepareCpolar: 'Prepara cpolar', checkingComponent: 'Controllo componente…', installOfficial: 'Installa componente ufficiale', cpolarAccountNote: 'Accedi al sito cpolar e copia l’Authtoken. Il token resta solo nella directory privata del plugin e non viene mostrato nella pagina o nei log.', registerCpolar: 'Registrati su cpolar', openDashboard: 'Apri la dashboard per il token', tokenPlaceholder: 'Incolla Authtoken cpolar', saveConnect: 'Salva e connetti', saving: 'Salvataggio…', componentDetails: 'Origine e rimozione del componente', componentDetailsText: 'Viene scaricato dal sito ufficiale cpolar e verificato a una versione fissa solo dopo aver scelto Installa. Non aggiunge servizi di sistema, avvio automatico, voci di registro o PATH.', pluginPrivateDirectory: 'Directory privata del plugin', officialDownload: 'Pagina download ufficiale', terms: 'Termini di servizio', purgeCpolar: 'Rimuovi completamente componente e configurazione cpolar', tailscaleHelp: 'Guida a Tailscale', tailscaleHelpText: 'Il componente runtime è incluso nel plugin. Il primo collegamento apre le pagine ufficiali di accesso Tailscale e autorizzazione Funnel; il plugin non accede mai alla password.', funnelGuideAria: 'Passaggi per abilitare Tailscale Funnel', funnelGuideTitle: 'Configurazione accesso remoto · Passaggio 2', funnelGuideSummary: 'L’accesso Tailscale è completato. Devi ancora consentire Funnel per questo computer; la pagina ufficiale abilita anche HTTPS.', funnelStep1: 'Apri la pagina ufficiale di autorizzazione Tailscale per questo nodo.', funnelStep2: 'Conferma Funnel; non serve accedere di nuovo a DSH.', funnelStep3: 'Torna in DSH; il plugin controlla e si connette automaticamente.', funnelGuideNote: 'Richiede un account Owner, Admin o Network admin.', continueFunnel: 'Continua autorizzazione Funnel', retryNow: 'Fatto, riprova ora', enableRemote: 'Attiva accesso remoto', disableRemote: 'Disattiva accesso remoto', continueLogin: 'Continua accesso', reconnect: 'Riconnetti', generateRemoteQr: 'Genera QR di abbinamento remoto', manageRemoteDevices: 'Gestisci dispositivi remoti', resetRemoteLogin: 'Esci e rimuovi accesso remoto', resetRemoteDevices: 'Disattiva e rimuovi dispositivi remoti',\n lanOn: 'Accesso dalla rete locale attivo.', lanOff: 'Accesso dalla rete locale disattivato.', enableLan: 'Attiva accesso rete locale', disableLan: 'Disattiva accesso rete locale', extensionsLoaded: 'Estensioni: {loaded} caricate', extensionsFailed: 'Estensioni: {loaded} caricate, {failed} non riuscite', keyGenerationFailed: 'Impossibile generare la chiave di abbinamento.', keyCopied: 'Chiave di abbinamento copiata. Incollala nell’app Android.', linkCopied: 'Link di abbinamento copiato. Invialo al telefono e incollalo nell’app oppure aprilo nel browser.', copySecret: 'Copia {kind}: {value}', pairingKey: 'chiave di abbinamento', pairingLink: 'link di abbinamento', noDevices: 'Nessun dispositivo abbinato.', noRemoteDevices: 'Nessun dispositivo remoto abbinato.', device: 'Dispositivo', expires: 'Scade {time}', revoke: 'Revoca', confirmResetDevices: 'Rimuovere tutti i dispositivi abbinati? I dispositivi connessi verranno disconnessi subito.', ready: 'Pronto', installed: 'Installato', installWithSize: 'Installa componente ufficiale · {size} MB', cpolarUnsupported: 'Attualmente è supportato solo Windows x64. Puoi comunque usare Tailscale Funnel integrato.', cpolarNotInstalled: 'Non installato. Una versione fissa viene scaricata dal sito ufficiale cpolar solo dopo aver premuto il pulsante.', cpolarNeedsToken: 'Componente ufficiale {version} verificato. Salva il token account per continuare.', cpolarReady: 'Componente ufficiale {version} e configurazione account locale pronti.',\n remoteOff: 'Accesso remoto disattivato. La rete locale non è interessata.', remoteUnavailableCpolar: 'cpolar non è installato o l’account locale non è configurato.', remoteUnavailableTailscale: 'Su questo computer manca il componente runtime Funnel. Reinstalla il pacchetto completo del plugin.', remoteStartingCpolar: 'Connessione a un nodo cpolar…', remoteStartingTailscale: 'Avvio del canale sicuro Tailscale…', remoteNeedsLogin: 'Completa una volta l’accesso Tailscale nel browser. Il plugin non legge mai la password.', remoteConnectingCpolar: 'Indirizzo pubblico assegnato; avvio del gateway di autenticazione DSH…', remoteConnectingTailscale: 'Accesso completato; creazione dell’indirizzo HTTPS pubblico…', remoteReady: 'Accesso remoto pronto. Solo i dispositivi abbinati possono accedere a DSH.', remoteError: 'Connessione remota non stabilita. Riconnettiti; la rete locale continua a funzionare.', funnelPermission: 'Accesso completato. Autorizza Funnel per stabilire automaticamente la connessione remota.', funnelHttps: 'Accesso completato. Autorizza Funnel; la pagina ufficiale abilita anche HTTPS.', funnelStart: 'Accesso completato. Termina la prima autorizzazione Tailscale Funnel.', tailscaleDnsMissing: 'Tailscale non ha fornito un indirizzo remoto. Riconnettiti e verifica di aver completato l’accesso.', gatewayStartFailed: 'Avvio del gateway remoto non riuscito. Riconnettiti; la rete locale non è interessata.', controlChannelFailed: 'Connessione al componente remoto interrotta. Riconnettiti.', cpolarMissing: 'Il componente ufficiale cpolar non è installato. Completa i passaggi sopra.', cpolarInvalid: 'Verifica del componente cpolar non riuscita. Rimuovilo completamente e reinstallalo.', cpolarConfigMissing: 'Nessun token account cpolar salvato. Completa i passaggi sopra.', cpolarConfigInvalid: 'Configurazione locale cpolar non valida. Salva nuovamente il token.', cpolarPortUnavailable: 'Impossibile assegnare una porta locale al gateway remoto. Riprova.', cpolarLaunchFailed: 'Avvio del client cpolar non riuscito.', cpolarTimeout: 'Connessione al nodo cpolar scaduta. Riconnettiti.', cpolarStopped: 'Connessione cpolar arrestata.', cpolarExited: 'Connessione cpolar terminata inaspettatamente. Riconnettiti.', cpolarOutputInvalid: 'cpolar ha restituito uno stato non riconosciuto.', cpolarOriginInvalid: 'L’indirizzo pubblico restituito da cpolar non ha superato la verifica.', setupOpened: 'La pagina ufficiale Tailscale è aperta. Torna in DSH dopo aver abilitato Funnel; la riconnessione è automatica.',\n switchProviderConfirm: 'Il cambio di metodo disattiva prima il canale remoto corrente. Rete locale e dispositivi abbinati non sono interessati. Continuare?', switchingCpolar: 'Passaggio a cpolar…', switchingTailscale: 'Passaggio a Tailscale Funnel…', installConfirm: 'Scaricare e verificare una versione fissa dal sito ufficiale cpolar (circa 7,3 MB), estraendola solo nella directory privata DSH Mobile? Non vengono aggiunti servizi, PATH/registro o avvio automatico.', downloading: 'Download e verifica…', installingCpolar: 'Installazione del componente ufficiale cpolar. Mantieni DSH in esecuzione fino al termine.', installFailed: 'Installazione componente non riuscita: {error}', invalidToken: 'Incolla l’Authtoken completo dalla dashboard cpolar.', configuredConnecting: 'Configurazione account salvata; connessione tramite cpolar…', configureFailed: 'Configurazione non riuscita: {error}', purgeConfirm: 'Rimuovere completamente componente cpolar, configurazione token e log runtime dalla directory privata DSH Mobile? Rete locale, dati DSH e altri programmi non sono interessati.', purging: 'Arresto del canale e rimozione dei file cpolar gestiti da DSH Mobile…', purgeFailed: 'Pulizia non riuscita: {error}', reconnectingCpolar: 'Riconnessione a un nodo cpolar…', reconnectingTailscale: 'Controllo impostazioni Tailscale e riconnessione…', remoteQrReady: 'QR di abbinamento remoto generato. Scansionalo da “Accesso remoto” nell’app.', resetCpolarConfirm: 'Disattivare il canale remoto cpolar e rimuovere tutti i dispositivi remoti? Account cpolar e altri tunnel restano invariati.', resetTailscaleConfirm: 'Uscire da Tailscale su questo computer e rimuovere tutti i dispositivi remoti? La configurazione della rete locale resta invariata.', requestFailed: 'Richiesta non riuscita: {error}',\n },\n zh: {} as Record<string, string>,\n} satisfies Record<MobileControlLocale, Record<string, string>>\n\nObject.assign(MOBILE_CONTROL_MESSAGES.zh, {\n mobileAccess: '移动访问', collapseMobileAccess: '收起移动访问', downloadAndroid: '下载 Android App', downloadAndroidAria: '前往 GitHub Releases 下载最新版 Android App', lan: '局域网', remote: '远程', lanAccess: '局域网访问', remoteAccess: '远程访问', browserAccess: '浏览器访问', remoteAddress: '远程地址', loadingStatus: '正在读取状态…', loadingRemoteStatus: '正在读取远程状态…',\n generateCopyKey: '生成并复制密钥', copyPairLink: '复制配对链接', managePairedDevices: '管理配对设备', clearAllDevices: '清除所有设备', pairingQr: '配对二维码', remoteIntro: '选择更适合你的远程通道。切换或关闭远程访问不会影响局域网。', chooseProvider: '选择连接方式', providerInfoAria: '查看远程连接安全与网络说明', providerGroupAria: '远程连接方式', providerSafeTitle: '你始终可以放心', providerSafeText: '只有已配对设备能进入 DSH。cpolar 按需安装并可彻底清理;Tailscale 在中国大陆网络下可能连接缓慢、中断或无法使用,国内网络建议优先尝试 cpolar。', builtIn: '内置', mainlandPreferred: '国内网络优先', tailscaleDescription: '覆盖更广;中国大陆网络可能不稳定,首次需登录并允许 Funnel。', cpolarDescription: '按需安装官方组件,适合国内网络环境。',\n prepareCpolar: '准备 cpolar', checkingComponent: '正在检查组件…', installOfficial: '安装官方组件', cpolarAccountNote: '登录 cpolar 官网后复制 Authtoken。令牌只保存在本机插件私有目录,不会显示在页面或日志中。', registerCpolar: '注册 cpolar', openDashboard: '打开控制台获取令牌', tokenPlaceholder: '粘贴 cpolar Authtoken', saveConnect: '保存并连接', saving: '正在保存…', componentDetails: '组件来源与清理说明', componentDetailsText: '仅在你点击安装后从 cpolar 官网下载并校验固定版本。不会写入系统服务、开机启动、注册表或 PATH。', pluginPrivateDirectory: '插件私有目录', officialDownload: '官方下载安装页', terms: '服务条款', purgeCpolar: '彻底移除 cpolar 组件与配置', tailscaleHelp: 'Tailscale 使用说明', tailscaleHelpText: '运行组件已随插件提供。首次连接会打开 Tailscale 官方登录和 Funnel 授权页;插件不会接触你的账号密码。', funnelGuideAria: 'Tailscale Funnel 启用步骤', funnelGuideTitle: '远程访问设置 · 第 2 步', funnelGuideSummary: 'Tailscale 登录已完成。还需为这台电脑允许 Funnel,官方页面会同时启用 HTTPS。', funnelStep1: '打开当前节点的 Tailscale 官方授权页。', funnelStep2: '确认启用 Funnel;无需再次登录 DSH。', funnelStep3: '返回 DSH,插件会自动检查并建立连接。', funnelGuideNote: '需要使用 Owner、Admin 或 Network admin 账号。', continueFunnel: '继续完成 Funnel 授权', retryNow: '已完成,立即重试',\n enableRemote: '启用远程访问', disableRemote: '关闭远程访问', continueLogin: '继续登录', reconnect: '重新连接', generateRemoteQr: '生成远程配对二维码', manageRemoteDevices: '管理远程设备', resetRemoteLogin: '退出并清除远程登录', resetRemoteDevices: '关闭并清除远程设备', lanOn: '局域网访问已开启。', lanOff: '局域网访问已关闭。', enableLan: '开启局域网访问', disableLan: '关闭局域网访问', extensionsLoaded: '扩展:{loaded} 个已加载', extensionsFailed: '扩展:{loaded} 个已加载,{failed} 个加载失败', keyGenerationFailed: '无法生成配对密钥。', keyCopied: '配对密钥已复制,请粘贴到 Android App。', linkCopied: '配对链接已复制,发给手机后 App 粘贴或浏览器打开即可配对。', copySecret: '请复制{kind}:{value}', pairingKey: '配对密钥', pairingLink: '配对链接', noDevices: '暂无配对设备。', noRemoteDevices: '暂无远程配对设备。', device: '设备', expires: '到期 {time}', revoke: '撤销', confirmResetDevices: '确定要移除所有配对设备吗?此操作会立即终止已连接设备。', ready: '已就绪', installed: '已安装', installWithSize: '安装官方组件 · {size} MB',\n cpolarUnsupported: '当前仅支持 Windows x64。你仍可选择内置的 Tailscale Funnel。', cpolarNotInstalled: '尚未安装。只有点击下方按钮后,才会从 cpolar 官网下载固定版本。', cpolarNeedsToken: '官方组件 {version} 已校验,下一步只需保存账号令牌。', cpolarReady: '官方组件 {version} 与本机账号配置已就绪。', remoteOff: '远程访问未启用。局域网访问不受影响。', remoteUnavailableCpolar: 'cpolar 尚未安装或未完成本机账号配置。', remoteUnavailableTailscale: '当前电脑缺少 Funnel 运行组件,请重新安装完整插件包。', remoteStartingCpolar: '正在连接 cpolar 国内节点…', remoteStartingTailscale: '正在启动 Tailscale 安全通道…', remoteNeedsLogin: '需要在浏览器完成一次 Tailscale 登录。插件不会读取你的密码。', remoteConnectingCpolar: '公网地址已分配,正在启动 DSH 认证网关…', remoteConnectingTailscale: '登录完成,正在建立公开 HTTPS 地址…', remoteReady: '远程访问已就绪。只有已配对设备可以进入 DSH。', remoteError: '远程连接未建立。可重新连接,局域网访问仍可正常使用。',\n funnelPermission: '登录已完成。请继续授权 Funnel,完成后会自动建立远程连接。', funnelHttps: '登录已完成。请继续授权 Funnel,官方页面会同时启用 HTTPS。', funnelStart: '登录已完成。请继续完成 Tailscale Funnel 的首次授权。', tailscaleDnsMissing: 'Tailscale 暂未提供远程地址。请重新连接并确认已完成登录。', gatewayStartFailed: '远程网关启动失败。请重新连接,局域网访问不受影响。', controlChannelFailed: '远程组件连接中断。请重新连接。', cpolarMissing: 'cpolar 官方组件尚未安装。请先完成上方准备步骤。', cpolarInvalid: 'cpolar 组件校验失败。请彻底移除后重新安装。', cpolarConfigMissing: 'cpolar 尚未保存账号令牌。请先完成上方准备步骤。', cpolarConfigInvalid: 'cpolar 本机配置无效。请重新保存账号令牌。', cpolarPortUnavailable: '无法分配本机远程网关端口,请重试。', cpolarLaunchFailed: 'cpolar 客户端未能启动。', cpolarTimeout: '连接 cpolar 国内节点超时,请重新连接。', cpolarStopped: 'cpolar 连接已停止。', cpolarExited: 'cpolar 连接意外退出,请重新连接。', cpolarOutputInvalid: 'cpolar 返回了无法识别的状态。', cpolarOriginInvalid: 'cpolar 返回的公网地址未通过校验。', setupOpened: 'Tailscale 官方页面已打开。完成启用后返回 DSH,这里会自动重新连接。',\n switchProviderConfirm: '切换连接方式会先关闭当前远程通道。局域网和配对设备不会受影响,是否继续?', switchingCpolar: '正在切换到 cpolar…', switchingTailscale: '正在切换到 Tailscale Funnel…', installConfirm: '将从 cpolar 官方网站下载并校验固定版本(约 7.3 MB),仅解压到 DSH Mobile 私有目录。不会安装系统服务、写入 PATH/注册表或设置开机启动。是否继续?', downloading: '正在下载并校验…', installingCpolar: '正在安装 cpolar 官方组件。完成前请保持 DSH 运行。', installFailed: '组件安装失败:{error}', invalidToken: '请粘贴 cpolar 控制台提供的完整 Authtoken。', configuredConnecting: '账号配置已保存,正在建立 cpolar 远程通道…', configureFailed: '配置失败:{error}', purgeConfirm: '彻底移除 DSH Mobile 私有目录中的 cpolar 组件、令牌配置和运行日志?不会影响局域网、DSH 数据或系统中的其他程序。', purging: '正在关闭通道并清理 DSH Mobile 管理的 cpolar 文件…', purgeFailed: '清理失败:{error}', reconnectingCpolar: '正在重新连接 cpolar 国内节点…', reconnectingTailscale: '正在确认 Tailscale 设置并重新连接…', remoteQrReady: '远程配对二维码已生成。请在 App 的“远程访问”中扫描。', resetCpolarConfirm: '关闭 cpolar 远程通道并移除所有远程配对设备?不会修改你的 cpolar 账号或其他隧道。', resetTailscaleConfirm: '退出电脑上的 Tailscale 登录并移除所有远程配对设备?局域网配置不会改变。', requestFailed: '请求失败:{error}',\n})\n\nObject.assign(MOBILE_CONTROL_MESSAGES.en, {\n requestTimeout: 'The operation timed out. Confirm that DSH is still running, then try again.',\n diagnostics: 'Diagnostics', openDiagnostics: 'Open connection diagnostics', back: 'Back', backToMobile: 'Back to Mobile access', connectionDiagnostics: 'Connection diagnostics',\n diagnosticsIntro: 'Check versions, gateway, network adapter, firewall, and remote channel. The report is automatically redacted and never reads conversations or credentials.',\n diagnosticsNotRun: 'Not checked yet', diagnosticsStartHint: 'Select the button below to begin.', diagnosticsIdleMeta: 'Waiting to run · connection status only', diagnosticsStart: 'Start check', diagnosticsCopy: 'Copy redacted report', diagnosticsAdvanced: 'Advanced diagnostic details',\n diagnosticsComplete: 'Check complete', diagnosticsAttention: 'Some items need attention', diagnosticsProblem: 'Connection problems found', diagnosticsCompleteFallback: 'The check is complete.',\n diagnosticStatusOk: 'OK', diagnosticStatusWarning: 'Attention', diagnosticStatusError: 'Problem', diagnosticStatusInfo: 'Info', diagnosticItems: '{count} items', diagnosticCheck: 'Check', diagnosticAction: 'Suggested action',\n diagnosticNeedsAction: 'Needs action', diagnosticDetails: 'Check details', diagnosticOther: 'Other checks', diagnosticNoBlockers: '{count} checks · no blocking issues found', diagnosticNeedsCount: '{count} checks · {issues} need attention',\n diagnosticsChecking: 'Checking…', diagnosticsCheckingTitle: 'Checking connection', diagnosticsCheckingText: 'This usually takes a few seconds. The remote channel performs a real reachability test.', diagnosticsRunningMeta: 'Running · keep DSH online',\n diagnosticsIncomplete: 'Check not completed', diagnosticsReadFailed: 'Could not read diagnostics: {error}', diagnosticsUnavailable: 'Diagnostics service unavailable · try again later', diagnosticsRetry: 'Check again', diagnosticsCopied: 'Redacted report copied. You can paste it directly into an issue.', diagnosticsCopyManual: 'Clipboard access was denied. Details are expanded for manual copying.',\n diagnosticLabelVersions: 'Version compatibility', diagnosticLabelNetwork: 'Local network adapter', diagnosticLabelLan: 'Local network gateway', diagnosticLabelFirewall: 'Windows Firewall', diagnosticLabelRemote: 'Remote channel', diagnosticLabelPhone: 'Phone network',\n funnelTimeout: 'The Tailscale component timed out while starting. Check the network, then reconnect.',\n})\nObject.assign(MOBILE_CONTROL_MESSAGES.it, {\n requestTimeout: 'Operazione scaduta. Verifica che DSH sia ancora in esecuzione e riprova.',\n diagnostics: 'Diagnostica', openDiagnostics: 'Apri diagnostica connessione', back: 'Indietro', backToMobile: 'Torna ad Accesso mobile', connectionDiagnostics: 'Diagnostica connessione',\n diagnosticsIntro: 'Controlla versioni, gateway, scheda di rete, firewall e canale remoto. Il report viene anonimizzato automaticamente e non legge conversazioni o credenziali.',\n diagnosticsNotRun: 'Controllo non eseguito', diagnosticsStartHint: 'Premi il pulsante sotto per iniziare.', diagnosticsIdleMeta: 'In attesa · solo stato connessione', diagnosticsStart: 'Avvia controllo', diagnosticsCopy: 'Copia report anonimizzato', diagnosticsAdvanced: 'Dettagli diagnostici avanzati',\n diagnosticsComplete: 'Controllo completato', diagnosticsAttention: 'Alcuni elementi richiedono attenzione', diagnosticsProblem: 'Rilevati problemi di connessione', diagnosticsCompleteFallback: 'Controllo completato.',\n diagnosticStatusOk: 'OK', diagnosticStatusWarning: 'Attenzione', diagnosticStatusError: 'Problema', diagnosticStatusInfo: 'Informazione', diagnosticItems: '{count} elementi', diagnosticCheck: 'Controllo', diagnosticAction: 'Suggerimento',\n diagnosticNeedsAction: 'Da risolvere', diagnosticDetails: 'Dettagli controllo', diagnosticOther: 'Altri controlli', diagnosticNoBlockers: '{count} controlli · nessun problema bloccante', diagnosticNeedsCount: '{count} controlli · {issues} richiedono attenzione',\n diagnosticsChecking: 'Controllo…', diagnosticsCheckingTitle: 'Controllo connessione', diagnosticsCheckingText: 'Di solito richiede pochi secondi. Il canale remoto esegue un test reale di raggiungibilità.', diagnosticsRunningMeta: 'In esecuzione · mantieni DSH online',\n diagnosticsIncomplete: 'Controllo non completato', diagnosticsReadFailed: 'Impossibile leggere la diagnostica: {error}', diagnosticsUnavailable: 'Servizio diagnostico non disponibile · riprova più tardi', diagnosticsRetry: 'Ripeti controllo', diagnosticsCopied: 'Report anonimizzato copiato. Puoi incollarlo direttamente in una issue.', diagnosticsCopyManual: 'Il browser ha negato la copia. I dettagli sono stati aperti per la copia manuale.',\n diagnosticLabelVersions: 'Compatibilità versioni', diagnosticLabelNetwork: 'Scheda rete locale', diagnosticLabelLan: 'Gateway rete locale', diagnosticLabelFirewall: 'Windows Firewall', diagnosticLabelRemote: 'Canale remoto', diagnosticLabelPhone: 'Rete telefono',\n funnelTimeout: 'Avvio del componente Tailscale scaduto. Controlla la rete e riconnettiti.',\n})\nObject.assign(MOBILE_CONTROL_MESSAGES.zh, {\n requestTimeout: '操作超时,请确认 DSH 仍在运行后重试。',\n diagnostics: '诊断', openDiagnostics: '打开连接诊断', back: '返回', backToMobile: '返回移动访问', connectionDiagnostics: '连接诊断',\n diagnosticsIntro: '检查版本、网关、网卡、防火墙和远程通道。报告自动脱敏,不读取对话或凭据。', diagnosticsNotRun: '尚未检查', diagnosticsStartHint: '点击下方按钮开始。', diagnosticsIdleMeta: '等待运行 · 仅收集连接状态', diagnosticsStart: '开始检查', diagnosticsCopy: '复制脱敏报告', diagnosticsAdvanced: '高级诊断详情',\n diagnosticsComplete: '检查完成', diagnosticsAttention: '有项目需要留意', diagnosticsProblem: '发现连接问题', diagnosticsCompleteFallback: '检查已完成。', diagnosticStatusOk: '正常', diagnosticStatusWarning: '注意', diagnosticStatusError: '问题', diagnosticStatusInfo: '说明', diagnosticItems: '{count} 项', diagnosticCheck: '检查项', diagnosticAction: '建议', diagnosticNeedsAction: '需要处理', diagnosticDetails: '检查详情', diagnosticOther: '其他检查', diagnosticNoBlockers: '{count} 项检查 · 未发现阻断问题', diagnosticNeedsCount: '{count} 项检查 · {issues} 项需要处理',\n diagnosticsChecking: '正在检查…', diagnosticsCheckingTitle: '正在检查连接', diagnosticsCheckingText: '通常几秒内完成。远程通道会执行一次真实可达性测试。', diagnosticsRunningMeta: '正在运行 · 请保持 DSH 在线', diagnosticsIncomplete: '检查未完成', diagnosticsReadFailed: '无法读取诊断结果:{error}', diagnosticsUnavailable: '诊断服务暂不可用 · 请稍后重试', diagnosticsRetry: '重新检查', diagnosticsCopied: '脱敏报告已复制,可直接粘贴到 Issue。', diagnosticsCopyManual: '浏览器未允许复制,已展开详情,请手动复制。',\n diagnosticLabelVersions: '版本兼容', diagnosticLabelNetwork: '局域网网卡', diagnosticLabelLan: '局域网网关', diagnosticLabelFirewall: 'Windows 防火墙', diagnosticLabelRemote: '远程通道', diagnosticLabelPhone: '手机网络', funnelTimeout: 'Tailscale 组件启动超时,请检查网络后重新连接。',\n})\n\nexport const LOCALIZED_DIAGNOSTIC_COPY = {\n en: {\n versions: 'Installed plugin, DSH, and minimum Android app versions are shown.',\n networkOk: 'The configured local network adapter is available.', networkError: 'The saved local network adapter is unavailable.', networkInfo: 'A fixed local network configuration is in use.', networkAction: 'Run dsh-mobile setup again.',\n lanOk: 'The local gateway is listening and pairing is available.', lanInfo: 'Local network access is currently off.', lanAction: 'Enable local network access when the phone must connect directly.',\n firewallOk: 'Local TCP and discovery firewall rules are enabled.', firewallWarning: 'The complete local network firewall rules were not found.', firewallInfo: 'The system did not allow the plugin to read firewall status.', firewallAction: 'Run dsh-mobile setup as administrator and check the firewall rules.',\n remoteOk: 'The remote public address passed the reachability check.', remoteWarning: 'The remote channel needs attention or is still connecting.', remoteError: 'The remote connection is not currently reachable.', remoteInfo: 'Remote access is currently off.', remoteAction: 'Return to Remote access, follow the provider guidance, and reconnect.',\n phone: 'The computer cannot determine whether the router isolates the phone.', phoneAction: 'Confirm the phone and computer use the same network, then disable guest-network or AP isolation.',\n reportTitle: 'DSH Mobile diagnostic report', generated: 'Generated',\n },\n it: {\n versions: 'Sono indicate le versioni installate di plugin e DSH e la versione minima dell’app Android.',\n networkOk: 'La scheda di rete locale configurata è disponibile.', networkError: 'La scheda di rete locale salvata non è disponibile.', networkInfo: 'È in uso una configurazione di rete locale fissa.', networkAction: 'Esegui di nuovo dsh-mobile setup.',\n lanOk: 'Il gateway locale è in ascolto e l’abbinamento è disponibile.', lanInfo: 'L’accesso dalla rete locale è disattivato.', lanAction: 'Attiva l’accesso locale quando il telefono deve collegarsi direttamente.',\n firewallOk: 'Le regole firewall TCP locale e di rilevamento sono attive.', firewallWarning: 'Le regole firewall complete per la rete locale non sono state trovate.', firewallInfo: 'Il sistema non ha consentito al plugin di leggere lo stato del firewall.', firewallAction: 'Esegui dsh-mobile setup come amministratore e controlla le regole firewall.',\n remoteOk: 'L’indirizzo pubblico remoto ha superato il test di raggiungibilità.', remoteWarning: 'Il canale remoto richiede attenzione o è ancora in connessione.', remoteError: 'La connessione remota non è al momento raggiungibile.', remoteInfo: 'L’accesso remoto è disattivato.', remoteAction: 'Torna ad Accesso remoto, segui le indicazioni del provider e riconnettiti.',\n phone: 'Il computer non può stabilire se il router isola il telefono.', phoneAction: 'Verifica che telefono e computer usino la stessa rete, poi disattiva rete ospiti o isolamento AP.',\n reportTitle: 'Report diagnostico DSH Mobile', generated: 'Generato',\n },\n zh: { reportTitle: 'DSH Mobile 诊断报告', generated: '生成时间' },\n} as const\n\nexport const DIAGNOSTIC_REASON_MESSAGES = {\n en: {\n 'versions-current': ['Installed plugin, DSH, and minimum Android app versions are shown.', ''],\n 'network-unavailable': ['The saved local network adapter is unavailable.', 'Run dsh-mobile setup again.'],\n 'network-interface': ['Using network interface {interfaceName}.', ''],\n 'network-fixed': ['A fixed local network configuration is in use.', ''],\n 'lan-ready': ['The local gateway is listening at {endpointSuffix}; pairing is available.', ''],\n 'lan-off': ['Local network access is currently off.', 'Enable local network access when the phone must connect directly.'],\n 'firewall-ready': ['Local TCP and discovery firewall rules are enabled.', ''],\n 'firewall-missing': ['The complete local network firewall rules were not found.', 'Run dsh-mobile setup as administrator and check the firewall rules.'],\n 'firewall-unknown': ['The system did not allow the plugin to read firewall status.', 'If the phone cannot find this computer, run setup as administrator.'],\n 'remote-off': ['Remote access through {provider} is currently off.', ''],\n 'remote-ready': ['{provider} endpoint {endpointSuffix} is reachable in about {latencyMs} ms.', ''],\n 'remote-rate-limited': ['{provider} endpoint {endpointSuffix} is reachable, but this check observed rate limiting.', 'Try again later; older sessions load on demand to reduce traffic.'],\n 'remote-fake-ip': ['The Tailscale address is intercepted by the current VPN or DNS proxy, so TLS was not established.', 'Switch VPN node or proxy mode; if it still fails, use cpolar.'],\n 'remote-unreachable': ['{provider} reports ready, but endpoint {endpointSuffix} is not reachable.', 'Reconnect, then check the provider status if it still fails.'],\n 'remote-needs-login': ['Tailscale is waiting for login to finish.', 'Return to Remote access and continue login.'],\n 'remote-connecting': ['The {provider} remote channel is still connecting.', 'Wait briefly, then check again.'],\n 'remote-controller-error': ['The {provider} controller reported {controllerCode}.', 'Return to Remote access and reconnect.'],\n 'phone-network-unknown': ['The computer cannot determine whether the router isolates the phone.', 'Confirm the phone and computer use the same network, then disable guest-network or AP isolation.'],\n },\n it: {\n 'versions-current': ['Sono indicate le versioni installate di plugin e DSH e la versione minima dell’app Android.', ''],\n 'network-unavailable': ['La scheda di rete locale salvata non è disponibile.', 'Esegui di nuovo dsh-mobile setup.'],\n 'network-interface': ['È in uso l’interfaccia di rete {interfaceName}.', ''],\n 'network-fixed': ['È in uso una configurazione di rete locale fissa.', ''],\n 'lan-ready': ['Il gateway locale è in ascolto su {endpointSuffix}; l’abbinamento è disponibile.', ''],\n 'lan-off': ['L’accesso dalla rete locale è disattivato.', 'Attiva l’accesso locale quando il telefono deve collegarsi direttamente.'],\n 'firewall-ready': ['Le regole firewall TCP locale e di rilevamento sono attive.', ''],\n 'firewall-missing': ['Le regole firewall complete per la rete locale non sono state trovate.', 'Esegui dsh-mobile setup come amministratore e controlla le regole firewall.'],\n 'firewall-unknown': ['Il sistema non ha consentito al plugin di leggere lo stato del firewall.', 'Se il telefono non trova il computer, esegui setup come amministratore.'],\n 'remote-off': ['L’accesso remoto tramite {provider} è disattivato.', ''],\n 'remote-ready': ['L’endpoint {provider} {endpointSuffix} è raggiungibile in circa {latencyMs} ms.', ''],\n 'remote-rate-limited': ['L’endpoint {provider} {endpointSuffix} è raggiungibile, ma il controllo ha rilevato una limitazione temporanea.', 'Riprova più tardi; le sessioni precedenti vengono caricate su richiesta per ridurre il traffico.'],\n 'remote-fake-ip': ['L’indirizzo Tailscale è intercettato dalla VPN o dal proxy DNS corrente e TLS non è stato stabilito.', 'Cambia nodo VPN o modalità proxy; se il problema continua, usa cpolar.'],\n 'remote-unreachable': ['{provider} risulta pronto, ma l’endpoint {endpointSuffix} non è raggiungibile.', 'Riconnettiti; se il problema continua, controlla lo stato del provider.'],\n 'remote-needs-login': ['Tailscale attende il completamento dell’accesso.', 'Torna ad Accesso remoto e continua l’accesso.'],\n 'remote-connecting': ['Il canale remoto {provider} è ancora in connessione.', 'Attendi qualche istante e ripeti il controllo.'],\n 'remote-controller-error': ['Il controller {provider} ha segnalato {controllerCode}.', 'Torna ad Accesso remoto e riconnettiti.'],\n 'phone-network-unknown': ['Il computer non può stabilire se il router isola il telefono.', 'Verifica che telefono e computer usino la stessa rete, poi disattiva rete ospiti o isolamento AP.'],\n },\n zh: {\n 'versions-current': ['已显示插件、DSH 和 Android App 最低版本。', ''],\n 'network-unavailable': ['已保存的局域网网卡当前不可用。', '重新运行 dsh-mobile setup。'],\n 'network-interface': ['正在使用网卡 {interfaceName}。', ''],\n 'network-fixed': ['当前使用固定局域网配置。', ''],\n 'lan-ready': ['局域网网关正在监听 {endpointSuffix},配对入口可用。', ''],\n 'lan-off': ['局域网访问当前未开启。', '手机需要直连时开启局域网访问。'],\n 'firewall-ready': ['局域网 TCP 与发现防火墙规则已启用。', ''],\n 'firewall-missing': ['未找到完整的局域网防火墙规则。', '以管理员身份运行 dsh-mobile setup 并检查防火墙规则。'],\n 'firewall-unknown': ['系统未允许插件读取防火墙状态。', '若手机找不到电脑,请以管理员身份运行 setup。'],\n 'remote-off': ['{provider} 远程访问当前未启用。', ''],\n 'remote-ready': ['{provider} 端点 {endpointSuffix} 可达,往返约 {latencyMs} ms。', ''],\n 'remote-rate-limited': ['{provider} 端点 {endpointSuffix} 可达,但本次检查观察到服务限流。', '稍后重试;旧会话会按需加载以减少流量。'],\n 'remote-fake-ip': ['Tailscale 地址被当前 VPN 或 DNS 代理接管,TLS 链路未建立。', '切换 VPN 节点或代理模式;仍失败时改用 cpolar。'],\n 'remote-unreachable': ['{provider} 显示已就绪,但端点 {endpointSuffix} 暂不可达。', '点击重新连接;仍失败时检查提供方状态。'],\n 'remote-needs-login': ['Tailscale 正在等待完成登录。', '返回远程访问并继续登录。'],\n 'remote-connecting': ['{provider} 远程通道仍在连接。', '等待片刻后重新检查。'],\n 'remote-controller-error': ['{provider} 控制器报告 {controllerCode}。', '返回远程访问并重新连接。'],\n 'phone-network-unknown': ['电脑无法判断路由器是否隔离了手机。', '确认手机与电脑使用同一网络,并关闭访客网络或 AP 隔离。'],\n },\n} as const\n","/** Mobile feature and compatibility rules applied to DSH React surfaces. */\nexport const NATIVE_MOBILE_STYLES = `\n@media (max-width:720px) {\n html.dsh-native-mobile-active,html.dsh-native-mobile-active body { width:100%; height:100%; overflow:hidden; }\n html.dsh-native-mobile-active { --dsh-mobile-motion-duration:200ms; --dsh-mobile-motion-ease:cubic-bezier(.22,1,.36,1); }\n html.dsh-native-mobile-active :is(a,button,[role=\"button\"],[role=\"tab\"],[tabindex]) { -webkit-tap-highlight-color:transparent; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [role=\"treeitem\"] { -webkit-tap-highlight-color:transparent; touch-action:manipulation; }\n html.dsh-native-mobile-active[data-dsh-mobile-input=\"touch\"] :is(a,button,[role=\"button\"],[role=\"tab\"],[tabindex]):focus { outline:none !important; }\n html.dsh-native-mobile-active [role=\"tooltip\"] { display:none !important; }\n /* Touch has no persistent hover affordance: keep workspace rows neutral after a tap. */\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] { --dsw-alias-interactive-bg-hover:transparent !important; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [role=\"treeitem\"]:is(:hover,:active,:focus,[aria-selected=\"true\"]),\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_sessionRow\"][class*=\"_selected\"],\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_searchResultRow\"][class*=\"_selected\"] { background:transparent !important; outline:0 !important; box-shadow:none !important; }\n /* Sidebar row menus are hover-only on desktop. Touch has no hover, so keep\n the ellipsis action visible and give it a reliable hit target. */\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_rowActions\"] { display:inline-flex !important; align-items:center !important; gap:8px !important; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_sessionRow\"] [class*=\"_time\"] { display:none !important; }\n html.dsh-native-mobile-active [data-dsh-mobile-sidebar] [class*=\"_rowActions\"] button { box-sizing:border-box !important; width:32px !important; min-width:32px !important; height:32px !important; min-height:32px !important; }\n [data-dsh-mobile-frame] { grid-template-columns:0 minmax(0,1fr) 0 !important; width:100% !important; height:100dvh !important; overflow:hidden !important; }\n [data-dsh-mobile-center] { grid-column:2 !important; width:100vw !important; min-width:0 !important; }\n [data-dsh-mobile-center] > * { min-width:0 !important; }\n [data-dsh-mobile-header] { box-sizing:border-box !important; width:calc(100% - 16px) !important; margin:0 8px !important; min-width:0; padding-top:max(4px,env(safe-area-inset-top)) !important; padding-right:8px !important; padding-left:42px !important; }\n [data-dsh-mobile-header] [class*=\"_titleRow\"] { box-sizing:border-box !important; display:flex !important; align-items:center !important; min-width:0; min-height:32px !important; height:32px !important; gap:6px !important; padding:0 6px !important; }\n [data-dsh-mobile-header] [class*=\"_titleCluster\"] { min-width:0; }\n [data-dsh-mobile-header] [class*=\"_crumbs\"] { min-width:0; overflow:hidden; }\n [data-dsh-mobile-header] [class*=\"_crumb\"] { max-width:46vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n [data-dsh-mobile-header] [class*=\"_headerActions\"] { min-width:0; overflow-x:auto; scrollbar-width:none; }\n [data-dsh-mobile-header] [class*=\"_headerActions\"]::-webkit-scrollbar { display:none; }\n [data-dsh-mobile-header] [class*=\"_headerUtilities\"] { gap:2px !important; }\n [data-dsh-mobile-header] [class*=\"_sessionLogButton\"] { width:40px; min-width:40px; padding:0 !important; overflow:hidden; color:transparent; font-size:0 !important; }\n [data-dsh-mobile-header] [class*=\"_sessionLogButton\"] > * { display:none !important; }\n [data-dsh-mobile-header] [class*=\"_sessionLogButton\"]::after { color:var(--dsw-text, #171a21); content:\"Log\"; font-size:11px; font-weight:600; }\n html[data-dsh-mobile-language=\"zh\"] [data-dsh-mobile-header] [class*=\"_sessionLogButton\"]::after { content:\"日志\"; }\n [data-dsh-mobile-header] [class*=\"_tabs\"] { box-sizing:border-box !important; width:max-content !important; max-width:calc(100% - 58px) !important; min-height:28px !important; height:28px !important; margin-top:0 !important; padding-left:6px !important; padding-right:6px !important; overflow-x:auto; scrollbar-width:none; }\n [data-dsh-mobile-header] [class*=\"_tab\"] { padding-bottom:5px !important; }\n [data-dsh-mobile-header] [class*=\"_tabs\"]::-webkit-scrollbar { display:none; }\n [data-dsh-mobile-sidebar] { position:fixed !important; z-index:240 !important; inset:0 auto 0 0 !important; width:0 !important; overflow:visible !important; }\n [data-dsh-mobile-sidebar-root] { position:fixed !important; z-index:241 !important; inset:max(env(safe-area-inset-top),0px) auto 0 0 !important; height:auto !important; transition:width 180ms var(--dsh-mobile-motion-ease),box-shadow 180ms ease !important; }\n [data-dsh-mobile-sidebar][data-open=\"true\"] [data-dsh-mobile-sidebar-root] { width:min(88vw,340px) !important; padding-top:0 !important; box-shadow:18px 0 46px rgb(15 23 42 / 18%); }\n [data-dsh-mobile-sidebar][data-open=\"true\"] [data-dsh-mobile-sidebar-root] [class*=\"_logoRow\"] { height:52px !important; padding:4px 0 4px 4px !important; margin-bottom:4px !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] { width:0 !important; border:0 !important; background:transparent !important; box-shadow:none !important; overflow:visible !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] > :not(:has([data-dsh-mobile-toggle])) { display:none !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] > :has([data-dsh-mobile-toggle]) { position:fixed !important; z-index:244 !important; top:env(safe-area-inset-top) !important; left:0 !important; box-sizing:border-box !important; width:50px !important; height:52px !important; padding:4px !important; border:0 !important; background:transparent !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-sidebar-root] > :has([data-dsh-mobile-toggle]) > :not([data-dsh-mobile-toggle]) { display:none !important; }\n [data-dsh-mobile-toggle] { width:44px !important; height:44px !important; min-width:44px !important; min-height:44px !important; }\n [data-dsh-mobile-sidebar][data-open=\"false\"] [data-dsh-mobile-toggle] > svg[class*=\"_railFish\"] { transform:translateY(-4px) !important; }\n .dsh-native-mobile-backdrop { position:fixed; z-index:235; inset:env(safe-area-inset-top) 0 0; border:0; background:rgb(15 23 42 / 32%); }\n .dsh-native-mobile-backdrop:not([hidden]) { animation:dsh-mobile-fade-in var(--dsh-mobile-motion-duration) ease-out; }\n .dsh-native-mobile-backdrop[hidden] { display:none; }\n [data-dsh-mobile-details] { position:fixed !important; z-index:250 !important; inset:0 0 0 auto !important; width:min(94vw,460px) !important; max-width:none !important; transform:translateX(100%); transition:transform var(--dsh-mobile-motion-duration) var(--dsh-mobile-motion-ease); background:var(--dsw-bg, #fff); box-shadow:-18px 0 46px rgb(15 23 42 / 18%); }\n [data-dsh-mobile-details][data-open=\"true\"] { transform:translateX(0); }\n [data-dsh-mobile-handle] { display:none !important; }\n [data-dsh-mobile-settings] { flex-direction:column !important; width:100vw !important; height:100dvh !important; max-width:none !important; border-radius:0 !important; animation:dsh-mobile-panel-in var(--dsh-mobile-motion-duration) var(--dsh-mobile-motion-ease); }\n [data-dsh-mobile-settings-nav] { flex:none !important; width:100% !important; padding:max(14px,env(safe-area-inset-top)) 12px 8px !important; gap:10px !important; border-bottom:1px solid var(--dsw-alias-border-subtle,#e8ebef); }\n [data-dsh-mobile-settings-nav] [class*=\"_navTitle\"] { padding:0 8px !important; font-size:18px !important; line-height:28px !important; }\n [data-dsh-mobile-settings-list] { flex-direction:row !important; gap:4px !important; overflow-x:auto !important; scrollbar-width:none; }\n [data-dsh-mobile-settings-list]::-webkit-scrollbar { display:none; }\n [data-dsh-mobile-settings-list] [class*=\"_navCell\"] { flex:0 0 auto !important; min-width:max-content !important; height:44px !important; padding:10px 12px !important; }\n [data-dsh-mobile-settings-list] [aria-current=\"true\"] { border-color:transparent !important; outline:0 !important; box-shadow:none !important; }\n [data-dsh-mobile-settings-content] { flex:1 1 auto !important; width:100% !important; min-height:0 !important; }\n [data-dsh-mobile-settings-header] { height:48px !important; min-height:48px !important; padding:10px 12px 6px !important; }\n [data-dsh-mobile-settings-header] [class*=\"_close\"] { width:36px !important; height:36px !important; }\n [data-dsh-mobile-settings-options] { box-sizing:border-box !important; width:100% !important; padding:4px 16px max(24px,env(safe-area-inset-bottom)) !important; overflow-x:hidden !important; }\n [data-dsh-mobile-settings-options] > * { width:100% !important; min-width:0 !important; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] > [class*=\"_row\"] { flex-direction:column !important; align-items:stretch !important; gap:12px !important; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] [class*=\"_rowText\"] { width:100% !important; padding-right:0 !important; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] [class*=\"_selector\"] { box-sizing:border-box !important; align-self:flex-start !important; justify-content:space-between !important; min-width:0 !important; min-height:44px !important; max-width:100% !important; }\n [data-dsh-mobile-settings-options] :is(input,select,textarea,button) { max-width:100%; }\n [data-dsh-mobile-settings-options] :is(input,select,textarea) { box-sizing:border-box; width:100%; min-width:0; }\n [data-dsh-mobile-settings-options] [class*=\"_head\"] { min-width:0; flex-wrap:wrap; }\n /* Provider names may shrink, but their edit/delete actions remain horizontal\n and retain a full touch target on narrow screens. */\n [data-dsh-mobile-settings-options] [class*=\"_rowHead\"]:has(> [class*=\"_rowIdentity\"]) { flex-wrap:nowrap !important; align-items:center !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowIdentity\"] { flex:1 1 auto !important; min-width:0 !important; overflow:hidden !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowName\"] { min-width:0 !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowActions\"] { flex:0 0 auto !important; flex-wrap:nowrap !important; width:max-content !important; min-width:max-content !important; max-width:none !important; }\n [data-dsh-mobile-settings-options] [class*=\"_rowActions\"] button { flex:none !important; width:auto !important; min-width:44px !important; max-width:none !important; min-height:44px !important; padding-inline:10px !important; white-space:nowrap !important; word-break:keep-all !important; writing-mode:horizontal-tb !important; }\n [data-dsh-mobile-settings-content][data-dsh-mobile-view-transition=\"true\"],\n [data-dsh-mobile-view][data-dsh-mobile-view-transition=\"true\"] { animation:dsh-mobile-view-in var(--dsh-mobile-motion-duration) var(--dsh-mobile-motion-ease); }\n [data-dsh-mobile-center] textarea { font-size:16px !important; }\n /* Markdown tables use content-sized columns. Small tables fill the phone;\n wider tables keep readable cells and scroll inside their own region. */\n [data-dsh-mobile-table-scroll] { box-sizing:border-box; width:100%; max-width:100%; overflow-x:auto; overscroll-behavior-x:contain; -webkit-overflow-scrolling:touch; }\n [data-dsh-mobile-table-scroll] table { display:table !important; width:max-content !important; min-width:100% !important; max-width:none !important; table-layout:auto !important; }\n [data-dsh-mobile-table-scroll] :is(th,td) { box-sizing:border-box; min-width:8ch; max-width:32ch; overflow-wrap:anywhere; word-break:break-word; vertical-align:top; }\n [data-dsh-mobile-center] pre { max-width:100%; overflow-x:auto; }\n [data-dsh-mobile-center] :is(img,video,canvas,svg) { max-width:100%; }\n [data-dsh-mobile-message-scroll] { box-sizing:border-box !important; width:100% !important; padding:8px 10px 20px !important; }\n [data-dsh-mobile-history-loader] { position:relative !important; min-height:1px !important; }\n [data-dsh-mobile-history-loader] button:not(:disabled) { position:absolute !important; width:1px !important; height:1px !important; margin:-1px !important; padding:0 !important; clip-path:inset(50%) !important; opacity:0 !important; overflow:hidden !important; pointer-events:none !important; }\n [data-dsh-mobile-history-loader] button:disabled { min-height:28px !important; padding:4px 12px !important; }\n [data-dsh-mobile-message-column] { box-sizing:border-box !important; width:100% !important; max-width:none !important; margin:0 !important; padding:0 !important; gap:10px !important; }\n [data-dsh-mobile-message-column] > * { width:100% !important; max-width:100% !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] { box-sizing:border-box !important; display:grid !important; grid-template-columns:16px minmax(0,1fr) !important; grid-auto-rows:auto !important; align-items:center !important; column-gap:6px !important; width:100% !important; height:auto !important; min-height:40px !important; padding:4px 0 !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > [class*=\"_leading\"] { grid-column:1 !important; grid-row:1 !important; margin-right:0 !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > [class*=\"_title\"] { grid-column:2 !important; grid-row:1 !important; min-width:0 !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > :is([class*=\"_sep\"],[class*=\"_separator\"]) { display:none !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > :is([class*=\"_summary\"],[class*=\"_fileLink\"]) { grid-column:2 !important; grid-row:2 !important; width:100% !important; min-width:0 !important; max-width:100% !important; overflow:hidden !important; line-height:19px !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-message-column] [data-disclosure-row] > [class*=\"_summarySuffix\"] { grid-column:2 !important; grid-row:3 !important; margin-left:0 !important; }\n [data-dsh-mobile-message-column] [data-context-fields] > * { display:grid !important; grid-template-columns:minmax(72px,30%) minmax(0,1fr) !important; gap:4px 10px !important; }\n [data-dsh-mobile-message-column] [class*=\"_ioSection\"] { grid-template-columns:1fr !important; row-gap:4px !important; }\n [data-dsh-mobile-message-column] [class*=\"_body\"] { max-width:100% !important; overflow-wrap:anywhere; }\n [data-dsh-mobile-center] [data-composer-card] ~ [class*=\"_root\"],\n [data-dsh-mobile-center] [data-composer-card] ~ * [class*=\"_root\"] { box-sizing:border-box !important; width:100% !important; max-width:100% !important; margin-bottom:-6px !important; padding:3px 4px 0 !important; font-size:11px !important; line-height:18px !important; white-space:normal !important; overflow:visible !important; text-overflow:clip !important; }\n [data-dsh-mobile-center] [data-composer-card] ~ [class*=\"_root\"] [class*=\"_sep\"],\n [data-dsh-mobile-center] [data-composer-card] ~ * [class*=\"_root\"] [class*=\"_sep\"] { margin:0 6px !important; }\n /* Message runtime details are inline on desktop. Give the clock/runtime\n label its own wrapping row on narrow screens so TTFT and throughput do\n not push the action buttons or clip at the viewport edge. */\n [data-dsh-mobile-center] [class*=\"_actions\"]:has(> [class*=\"_timeStart\"]),\n [data-dsh-mobile-center] [class*=\"_actions\"]:has(> [class*=\"_timeEnd\"]) { box-sizing:border-box !important; width:100% !important; flex-wrap:wrap !important; justify-content:flex-end !important; height:auto !important; min-height:28px !important; row-gap:2px !important; }\n [data-dsh-mobile-center] [class*=\"_timeStart\"],\n [data-dsh-mobile-center] [class*=\"_timeEnd\"] { box-sizing:border-box !important; flex:1 1 100% !important; order:2 !important; min-width:0 !important; max-width:100% !important; padding:0 !important; line-height:20px !important; text-align:center !important; white-space:normal !important; overflow-wrap:anywhere !important; }\n [data-dsh-mobile-center] [class*=\"_timeStart\"] { box-sizing:border-box !important; flex:1 1 100% !important; order:2 !important; min-width:0 !important; max-width:100% !important; padding:0 !important; line-height:20px !important; text-align:center !important; white-space:normal !important; overflow-wrap:anywhere !important; }\n [data-dsh-mobile-center] [class*=\"_timeStart\"] [class*=\"_runTimeDot\"],\n [data-dsh-mobile-center] [class*=\"_timeEnd\"] [class*=\"_runTimeDot\"] { margin:0 6px !important; }\n /* Keep the context meter's legend rows as readable label/value pairs.\n Generic mobile flex rules can otherwise place the rows side by side and\n break Chinese labels in the middle of a word. */\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"],\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] { width:min(264px,calc(100vw - 32px)) !important; min-width:0 !important; max-width:calc(100vw - 32px) !important; }\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"] [class*=\"_rows\"],\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] [class*=\"_rows\"] { display:block !important; }\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"] [class*=\"_rows\"] > [class*=\"_row\"],\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] [class*=\"_rows\"] > [class*=\"_row\"] { display:flex !important; align-items:center !important; justify-content:space-between !important; width:100% !important; min-width:0 !important; white-space:nowrap !important; }\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"上下文\"] :is(dt,dd),\n [data-dsh-mobile-center] [role=\"dialog\"][aria-label*=\"Context\"] :is(dt,dd) { white-space:nowrap !important; word-break:keep-all !important; }\n .dsh-mobile-branch-toast,.dsh-mobile-media-toast { position:fixed; z-index:330; top:max(12px,env(safe-area-inset-top)); left:50%; max-width:calc(100vw - 32px); box-sizing:border-box; padding:7px 14px; border:1px solid rgb(15 23 42 / 10%); border-radius:999px; background:rgb(15 23 42 / 92%); color:#fff; font-size:13px; line-height:20px; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; opacity:0; pointer-events:none; transform:translate(-50%,-8px); transition:opacity 160ms ease,transform 160ms ease; }\n .dsh-mobile-branch-toast[data-visible=\"true\"],.dsh-mobile-media-toast[data-visible=\"true\"] { opacity:1; transform:translate(-50%,0); }\n .dsh-mobile-media-shortcuts { box-sizing:border-box; display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; width:100%; padding:4px 4px 8px; margin-bottom:4px; border-bottom:1px solid var(--dsw-alias-border-inverted,var(--dsw-alias-border-subtle,rgb(148 163 184 / 28%))); }\n .dsh-mobile-media-action { box-sizing:border-box; display:flex; align-items:center; justify-content:flex-start; gap:8px; width:100%; min-width:0; min-height:44px; padding:8px 10px; border:0; border-radius:10px; background:var(--dsw-alias-interactive-bg-hover,rgb(148 163 184 / 12%)); color:var(--dsw-alias-label-primary,inherit); cursor:pointer; font:inherit; font-size:14px; line-height:22px; text-align:left; touch-action:manipulation; }\n .dsh-mobile-media-action:active { opacity:.72; }\n .dsh-mobile-media-action:focus-visible { outline:2px solid var(--dsw-alias-interactive-border-focus,#4c82f7); outline-offset:1px; }\n .dsh-mobile-media-action:disabled { cursor:default; opacity:.38; }\n .dsh-mobile-media-action svg { flex:none; width:16px; height:16px; color:var(--dsw-alias-label-tertiary,currentColor); }\n .dsh-mobile-media-action span { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n [data-dsh-mobile-center] [class*=\"_composer\"] { padding-left:8px !important; padding-right:8px !important; padding-bottom:max(8px,env(safe-area-inset-bottom)) !important; }\n /* The desktop composer intentionally wraps whole toolbar groups. On a phone,\n dynamic model and status labels made that row alternate between one and\n two lines. Keep two stable columns and let only the model label shrink. */\n [data-dsh-mobile-composer-row] { display:grid !important; grid-template-columns:max-content minmax(0,1fr) !important; align-items:center !important; gap:4px 8px !important; }\n [data-dsh-mobile-composer-tools] { display:flex !important; flex-wrap:nowrap !important; width:max-content !important; min-width:0 !important; max-width:max-content !important; gap:6px !important; }\n [data-dsh-mobile-composer-trailing] { display:flex !important; flex-wrap:nowrap !important; width:100% !important; min-width:0 !important; max-width:100% !important; gap:6px !important; margin-left:0 !important; justify-content:flex-end !important; }\n [data-dsh-mobile-composer-model] { flex:1 1 0 !important; width:auto !important; min-width:0 !important; max-width:none !important; }\n [data-dsh-mobile-composer-model-trigger] { box-sizing:border-box !important; width:100% !important; max-width:100% !important; min-width:0 !important; padding-left:6px !important; padding-right:4px !important; }\n [data-dsh-mobile-composer-model-label] { flex:1 1 auto !important; max-width:none !important; min-width:0 !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n [data-dsh-mobile-center] [class*=\"_root\"]:has(> [class*=\"_card\"] textarea) { box-sizing:border-box !important; width:100% !important; padding:0 0 8px !important; }\n [data-dsh-mobile-center] [class*=\"_root\"]:has(> [class*=\"_card\"] textarea) > [class=\"\"]:last-child { display:none !important; }\n}\n@keyframes dsh-mobile-fade-in { from { opacity:0; } }\n@keyframes dsh-mobile-panel-in { from { opacity:.72; transform:translateY(6px); } }\n@keyframes dsh-mobile-view-in { from { opacity:.58; transform:translateY(5px); } }\n@media (max-width:420px) {\n [data-dsh-mobile-header] [class*=\"_headerActions\"] { max-width:42vw; }\n [data-dsh-mobile-settings-options] [data-slot=\"settings.general.item\"] [class*=\"_selector\"] { align-self:stretch !important; width:100% !important; }\n [data-dsh-mobile-message-column] [data-context-fields] > * { grid-template-columns:1fr !important; }\n}\n@media (prefers-reduced-motion:reduce) {\n [data-dsh-mobile-sidebar-root],[data-dsh-mobile-details] { transition:none !important; }\n .dsh-native-mobile-backdrop:not([hidden]),[data-dsh-mobile-settings],\n [data-dsh-mobile-settings-content][data-dsh-mobile-view-transition=\"true\"],\n [data-dsh-mobile-view][data-dsh-mobile-view-transition=\"true\"] { animation:none !important; }\n}\n`\n\nfunction classToken(element: Element, suffix: string): boolean {\n return Array.from(element.classList).some(value => value.endsWith(suffix))\n}\n\nfunction firstByClassSuffix(root: ParentNode, suffix: string): HTMLElement | undefined {\n return Array.from(root.querySelectorAll<HTMLElement>('[class]')).find(element => classToken(element, suffix))\n}\n\nconst AUTO_HISTORY_THRESHOLD_PX = 64\n\nexport type NativeMobileLanguage = 'it' | 'en' | 'zh'\n\ninterface FileDropTarget { dispatchEvent(event: Event): boolean }\n\nfunction controlledFileDragEvent(type: 'dragover' | 'drop', files: readonly File[], initialDropEffect: DataTransfer['dropEffect']): DragEvent {\n const event = new Event(type, { bubbles: true, cancelable: true }) as DragEvent\n const dataTransfer = {\n dropEffect: initialDropEffect,\n effectAllowed: 'copy',\n files: Object.freeze([...files]),\n types: Object.freeze(['Files']),\n } as unknown as DataTransfer\n Object.defineProperty(event, 'dataTransfer', { value: dataTransfer })\n return event\n}\n\n/** Ask the official document dragover listener whether the current composer accepts files. */\nexport function preflightComposerImageDrop(target: FileDropTarget, files: readonly File[]): boolean {\n if (files.length === 0) return false\n const event = controlledFileDragEvent('dragover', files, 'none')\n target.dispatchEvent(event)\n return event.dataTransfer?.dropEffect === 'copy'\n}\n\n/** Dispatch a real drop only after a fresh official-listener preflight; the result is not an attachment ACK. */\nexport function dispatchComposerImageDrop(target: FileDropTarget, files: readonly File[]): boolean {\n if (!preflightComposerImageDrop(target, files)) return false\n target.dispatchEvent(controlledFileDragEvent('drop', files, 'copy'))\n return true\n}\n\n/** Apply the resolved locale independently from the document's possibly different lang attribute. */\nexport function applyNativeMobileLanguageMarker(root: Pick<HTMLElement, 'dataset'>, language: NativeMobileLanguage): () => void {\n const previous = root.dataset.dshMobileLanguage\n root.dataset.dshMobileLanguage = language\n return () => {\n if (root.dataset.dshMobileLanguage !== language) return\n if (previous === undefined) delete root.dataset.dshMobileLanguage\n else root.dataset.dshMobileLanguage = previous\n }\n}\n\n/** Resolve the supported language used by native-mobile controls. */\nexport function resolveNativeMobileLanguage(\n documentLanguage: string,\n browserLanguages: readonly string[],\n): NativeMobileLanguage {\n return [documentLanguage, ...browserLanguages]\n .map(value => value.trim().toLowerCase().split(/[-_]/u)[0])\n .find((value): value is NativeMobileLanguage => value === 'it' || value === 'en' || value === 'zh') ?? 'en'\n}\n\n/** Whether a user-driven scroll moved upward into the automatic history-loading zone. */\nexport function shouldAutoLoadEarlier(previousTop: number, currentTop: number): boolean {\n return currentTop <= AUTO_HISTORY_THRESHOLD_PX && currentTop < previousTop - 0.5\n}\n\ninterface ComposerMediaOrigin {\n readonly generation: number\n readonly href: string\n readonly composer: object | null\n readonly sessionRoot: object | null\n readonly sessionId: string | null\n}\n\n/** Check that an asynchronous picker result still belongs to its originating session and composer. */\nexport function isComposerMediaOriginCurrent(\n origin: ComposerMediaOrigin,\n current: ComposerMediaOrigin & { readonly disposed: boolean; readonly composerConnected: boolean },\n): boolean {\n return !current.disposed\n && origin.generation === current.generation\n && origin.href === current.href\n && origin.composer !== null\n && current.composerConnected\n && origin.composer === current.composer\n && origin.sessionRoot !== null\n && origin.sessionRoot === current.sessionRoot\n && origin.sessionId !== null\n && origin.sessionId === current.sessionId\n}\n\n/** Add mobile semantics without replacing feature trees. */\nexport function installNativeMobileSurface(): () => void {\n document.documentElement.classList.add('dsh-native-mobile-active')\n const browserLanguages = navigator.languages.length > 0 ? navigator.languages : [navigator.language]\n const language = resolveNativeMobileLanguage(document.documentElement.lang, browserLanguages)\n const restoreLanguageMarker = applyNativeMobileLanguageMarker(document.documentElement, language)\n const label = (italian: string, english: string, chinese: string): string => language === 'it' ? italian : language === 'zh' ? chinese : english\n const mediaIcon = (kind: 'attachment' | 'camera'): SVGSVGElement => {\n const namespace = 'http://www.w3.org/2000/svg'\n const icon = document.createElementNS(namespace, 'svg')\n icon.setAttribute('viewBox', '0 0 16 16')\n icon.setAttribute('fill', 'none')\n icon.setAttribute('aria-hidden', 'true')\n if (kind === 'attachment') {\n const path = document.createElementNS(namespace, 'path')\n // DSH IconPaperclipOutline16, kept in the same currentColor icon language as the composer.\n path.setAttribute('d', 'M5.5498 9.75V5H6.9502V9.75C6.9502 10.3299 7.4201 10.7998 8 10.7998C8.5799 10.7998 9.0498 10.3299 9.0498 9.75V4.5C9.0498 2.9536 7.7964 1.7002 6.25 1.7002C4.7036 1.7002 3.4502 2.9536 3.4502 4.5V9.75C3.4502 12.2629 5.4871 14.2998 8 14.2998C10.5129 14.2998 12.5498 12.2629 12.5498 9.75V4H13.9502V9.75C13.9502 13.0361 11.2861 15.7002 8 15.7002C4.71391 15.7002 2.0498 13.0361 2.0498 9.75V4.5C2.04981 2.1804 3.9304 0.299806 6.25 0.299805C8.5696 0.299805 10.4502 2.1804 10.4502 4.5V9.75C10.4502 11.1031 9.3531 12.2002 8 12.2002C6.6469 12.2002 5.5498 11.1031 5.5498 9.75Z')\n path.setAttribute('fill', 'currentColor')\n icon.append(path)\n return icon\n }\n const body = document.createElementNS(namespace, 'path')\n body.setAttribute('d', 'M5.15 3.2 6.05 2h3.9l.9 1.2h1.45c1.05 0 1.9.85 1.9 1.9v6c0 1.05-.85 1.9-1.9 1.9H3.7a1.9 1.9 0 0 1-1.9-1.9v-6c0-1.05.85-1.9 1.9-1.9h1.45Zm-1.45 1.3a.6.6 0 0 0-.6.6v6c0 .33.27.6.6.6h8.6a.6.6 0 0 0 .6-.6v-6a.6.6 0 0 0-.6-.6h-2.1l-.9-1.2H6.7l-.9 1.2H3.7Z')\n body.setAttribute('fill', 'currentColor')\n const lens = document.createElementNS(namespace, 'circle')\n lens.setAttribute('cx', '8')\n lens.setAttribute('cy', '8.1')\n lens.setAttribute('r', '2.15')\n lens.setAttribute('stroke', 'currentColor')\n lens.setAttribute('stroke-width', '1.3')\n icon.append(body, lens)\n return icon\n }\n const createMediaAction = (kind: 'attachment' | 'camera', text: string): HTMLButtonElement => {\n const button = document.createElement('button')\n button.type = 'button'\n button.className = 'dsh-mobile-media-action'\n button.lang = language\n button.dataset.dshMobileMediaAction = kind\n button.append(mediaIcon(kind))\n const caption = document.createElement('span')\n caption.textContent = text\n button.append(caption)\n return button\n }\n const setInputMode = (mode: 'keyboard' | 'touch'): void => {\n document.documentElement.dataset.dshMobileInput = mode\n }\n const onPointerDown = (event: PointerEvent): void => {\n if (event.pointerType === 'touch' || event.pointerType === 'pen') setInputMode('touch')\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Tab' || event.key.startsWith('Arrow')) setInputMode('keyboard')\n }\n document.addEventListener('pointerdown', onPointerDown, true)\n document.addEventListener('keydown', onKeyDown, true)\n const backdrop = document.createElement('button')\n backdrop.type = 'button'\n backdrop.className = 'dsh-native-mobile-backdrop'\n backdrop.lang = language\n backdrop.hidden = true\n backdrop.setAttribute('aria-label', label('Chiudi navigazione area di lavoro', 'Close workspace navigation', '关闭工作区导航'))\n document.body.append(backdrop)\n const branchToast = document.createElement('div')\n branchToast.className = 'dsh-mobile-branch-toast'\n branchToast.lang = language\n branchToast.setAttribute('role', 'status')\n branchToast.setAttribute('aria-live', 'polite')\n document.body.append(branchToast)\n const mediaToast = document.createElement('div')\n mediaToast.className = 'dsh-mobile-media-toast'\n mediaToast.lang = language\n mediaToast.setAttribute('role', 'status')\n mediaToast.setAttribute('aria-live', 'polite')\n document.body.append(mediaToast)\n const mediaActions = document.createElement('div')\n mediaActions.className = 'dsh-mobile-media-shortcuts'\n mediaActions.lang = language\n mediaActions.dataset.dshMobileMediaShortcuts = 'true'\n mediaActions.setAttribute('role', 'group')\n mediaActions.setAttribute('aria-label', label('Aggiungi immagine', 'Add image', '添加图片'))\n const fileButton = createMediaAction('attachment', label('Scegli immagine', 'Choose image', '选择图片'))\n const cameraButton = createMediaAction('camera', label('Scatta foto', 'Take photo', '拍照'))\n fileButton.disabled = true\n cameraButton.disabled = true\n mediaActions.append(fileButton, cameraButton)\n let branchToastTimer = 0\n let mediaToastTimer = 0\n const showMediaToast = (message: string): void => {\n mediaToast.textContent = message\n mediaToast.dataset.visible = 'true'\n if (mediaToastTimer !== 0) window.clearTimeout(mediaToastTimer)\n mediaToastTimer = window.setTimeout(() => {\n mediaToast.removeAttribute('data-visible')\n mediaToastTimer = 0\n }, 2200)\n }\n let mediaRequestGeneration = 0\n let disposed = false\n let boundComposer: Element | null = null\n let boundSessionRoot: Element | null = null\n let boundSessionId: string | null = null\n const preflightFile = new File([], 'dsh-mobile-preflight.png', { type: 'image/png' })\n const canAcceptComposerDrop = (): boolean => preflightComposerImageDrop(document, [preflightFile])\n const mediaPickerAbortController = new AbortController()\n const browserPickerCleanups = new Set<() => void>()\n const sessionTokens = new WeakMap<Element, string>()\n let nextSessionToken = 0\n type MediaRequestContext = ComposerMediaOrigin & { readonly composer: Element | null; readonly sessionRoot: Element | null }\n const currentSessionOrigin = (): { readonly sessionRoot: Element | null; readonly sessionId: string | null } => {\n const dedicatedRoot = boundComposer?.closest('[data-dsh-mobile-session]') ?? null\n const dedicatedId = dedicatedRoot?.getAttribute('data-dsh-mobile-session')\n if (dedicatedRoot !== null && typeof dedicatedId === 'string' && dedicatedId !== '') {\n return { sessionRoot: dedicatedRoot, sessionId: dedicatedId }\n }\n const selectedRow = document.querySelector<Element>('[role=\"treeitem\"][aria-selected=\"true\"]')\n if (selectedRow === null) return { sessionRoot: null, sessionId: null }\n let token = sessionTokens.get(selectedRow)\n if (token === undefined) { token = `stock-${String(++nextSessionToken)}`; sessionTokens.set(selectedRow, token) }\n const identity = selectedRow.getAttribute('data-session-id')\n ?? selectedRow.getAttribute('aria-label')\n ?? selectedRow.textContent?.trim()\n ?? ''\n return { sessionRoot: selectedRow, sessionId: `${token}:${identity}` }\n }\n const mediaRequestContext = (): MediaRequestContext => {\n const session = currentSessionOrigin()\n return {\n generation: ++mediaRequestGeneration,\n href: window.location.href,\n composer: boundComposer,\n ...session,\n }\n }\n const mediaRequestIsCurrent = (context: MediaRequestContext): boolean => {\n const session = currentSessionOrigin()\n const composer = boundComposer\n return isComposerMediaOriginCurrent(context, {\n generation: mediaRequestGeneration,\n href: window.location.href,\n composer,\n sessionRoot: session.sessionRoot,\n sessionId: session.sessionId,\n disposed,\n composerConnected: context.composer?.isConnected === true,\n })\n }\n const deliverImages = (files: readonly File[], context: ReturnType<typeof mediaRequestContext>): void => {\n if (files.length === 0 || !mediaRequestIsCurrent(context)) return\n dispatchComposerImageDrop(document, files)\n }\n const launchBrowserPicker = (camera: boolean, context: ReturnType<typeof mediaRequestContext>): void => {\n const input = document.createElement('input')\n input.type = 'file'\n input.accept = 'image/png,image/jpeg,image/webp,image/gif'\n if (camera) input.capture = 'environment'\n input.hidden = true\n const signal = mediaPickerAbortController.signal\n let cleanupTimer = 0\n let watchdogTimer = 0\n let cleaned = false\n const scheduleCleanup = (): void => {\n if (!cleaned && cleanupTimer === 0) cleanupTimer = window.setTimeout(cleanup, 1000)\n }\n const onVisibilityChange = (): void => {\n if (document.visibilityState === 'visible') scheduleCleanup()\n }\n const onChange = (): void => {\n if (cleaned) return\n const files = input.files === null ? [] : [...input.files]\n cleanup()\n deliverImages(files, context)\n }\n const cleanup = (): void => {\n if (cleaned) return\n cleaned = true\n if (cleanupTimer !== 0) window.clearTimeout(cleanupTimer)\n if (watchdogTimer !== 0) window.clearTimeout(watchdogTimer)\n cleanupTimer = 0\n watchdogTimer = 0\n input.removeEventListener('change', onChange)\n input.removeEventListener('cancel', cleanup)\n window.removeEventListener('focus', scheduleCleanup)\n document.removeEventListener('visibilitychange', onVisibilityChange)\n signal.removeEventListener('abort', cleanup)\n browserPickerCleanups.delete(cleanup)\n input.remove()\n }\n input.addEventListener('change', onChange)\n input.addEventListener('cancel', cleanup)\n window.addEventListener('focus', scheduleCleanup)\n document.addEventListener('visibilitychange', onVisibilityChange)\n signal.addEventListener('abort', cleanup, { once: true })\n watchdogTimer = window.setTimeout(cleanup, 300_000)\n browserPickerCleanups.add(cleanup)\n if (signal.aborted) { cleanup(); return }\n try {\n document.body.append(input)\n input.click()\n } catch {\n cleanup()\n if (mediaRequestIsCurrent(context)) showMediaToast(label('Impossibile aprire il selettore immagini', 'Could not open the image picker', '无法打开图片选择器'))\n }\n }\n const dismissCommandMenu = (): void => {\n const trigger = boundComposer?.querySelector<HTMLButtonElement>('button[aria-haspopup=\"listbox\"][aria-expanded=\"true\"]')\n trigger?.click()\n }\n const setMediaActionsDisabled = (disabled: boolean, title: string): void => {\n for (const button of [fileButton, cameraButton]) {\n if (button.disabled !== disabled) button.disabled = disabled\n if (button.title !== title) button.title = title\n }\n }\n const quietMediaPointer = (event: PointerEvent): void => {\n event.preventDefault()\n event.stopPropagation()\n const active = document.activeElement\n if (active instanceof HTMLElement && (active.matches('input,textarea') || active.isContentEditable)) active.blur()\n }\n const pickImage = (camera: boolean): void => {\n if (!canAcceptComposerDrop()) {\n setMediaActionsDisabled(true, label('Allegati immagine non disponibili', 'Image attachments are unavailable', '图片附件不可用'))\n dismissCommandMenu()\n return\n }\n const context = mediaRequestContext()\n dismissCommandMenu()\n const bridge = window.__DSH_MOBILE_NATIVE__\n if (bridge === undefined) {\n launchBrowserPicker(camera, context)\n return\n }\n const action = camera ? 'camera.capture' : 'files.pick'\n const input = camera ? {} : { accept: ['image/png', 'image/jpeg', 'image/webp', 'image/gif'] }\n void Promise.resolve().then(() => bridge.invoke(action, input)).then(value => {\n if (!mediaRequestIsCurrent(context)) return\n if (value instanceof File) deliverImages([value], context)\n else showMediaToast(label('Il file selezionato non è utilizzabile', 'The selected file is unavailable', '所选文件不可用'))\n }).catch((error: unknown) => {\n if (!mediaRequestIsCurrent(context)) return\n const code = typeof error === 'object' && error !== null && 'code' in error ? String(error.code) : ''\n if (code === 'cancelled') return\n showMediaToast(code === 'payload_too_large'\n ? label('L’immagine supera il limite di 8 MiB', 'The image exceeds the 8 MiB limit', '图片超过 8 MiB 限制')\n : label('Impossibile aggiungere l’immagine', 'Could not attach the image', '无法附加图片'))\n })\n }\n const chooseImage = (): void => { pickImage(false) }\n const takePhoto = (): void => { pickImage(true) }\n fileButton.addEventListener('pointerdown', quietMediaPointer)\n cameraButton.addEventListener('pointerdown', quietMediaPointer)\n fileButton.addEventListener('click', chooseImage)\n cameraButton.addEventListener('click', takePhoto)\n const showBranchToast = (): void => {\n const header = document.querySelector<HTMLElement>('[data-dsh-mobile-header]')\n const title = header === null ? undefined : header.querySelector<HTMLElement>('[class*=\"_crumbCurrent\"]')?.textContent?.trim()\n const prefix = label('Ramo corrente', 'Current branch', '当前分支')\n branchToast.textContent = title === undefined ? prefix : `${prefix}: ${title}`\n branchToast.dataset.visible = 'true'\n if (branchToastTimer !== 0) window.clearTimeout(branchToastTimer)\n branchToastTimer = window.setTimeout(() => {\n branchToast.removeAttribute('data-visible')\n branchToastTimer = 0\n }, 1600)\n }\n const onBranchClick = (event: MouseEvent): void => {\n if (!(event.target instanceof Element)) return\n const branch = event.target.closest<HTMLButtonElement>('button[aria-label*=\"分支\"],button[aria-label*=\"Branch\"],button[aria-label*=\"branch\"],button[aria-label*=\"Ramo\"],button[aria-label*=\"ramo\"]')\n if (branch === null || branch.hasAttribute('disabled') || branch.getAttribute('aria-disabled') === 'true') return\n window.setTimeout(showBranchToast, 80)\n }\n document.addEventListener('click', onBranchClick, true)\n let frame: HTMLElement | undefined\n let sidebar: HTMLElement | undefined\n let sidebarRoot: HTMLElement | undefined\n let toggle: HTMLButtonElement | undefined\n let viewArea: HTMLElement | undefined\n let scheduled = 0\n let transitionFrame = 0\n let transitionRestartFrame = 0\n let transitionTimer = 0\n let transitionTarget: HTMLElement | undefined\n let historyScroller: HTMLElement | undefined\n let historyPreviousTop = 0\n const historyLoadButton = (): HTMLButtonElement | undefined => {\n const loader = historyScroller === undefined ? undefined : firstByClassSuffix(historyScroller, '_older')\n return loader?.querySelector<HTMLButtonElement>('button') ?? undefined\n }\n const onHistoryScroll = (): void => {\n if (historyScroller === undefined) return\n const currentTop = Math.max(0, historyScroller.scrollTop)\n const shouldLoad = shouldAutoLoadEarlier(historyPreviousTop, currentTop)\n historyPreviousTop = currentTop\n if (!shouldLoad) return\n const button = historyLoadButton()\n if (button === undefined || button.disabled || button.getAttribute('aria-disabled') === 'true') return\n button.click()\n }\n const bindHistoryScroller = (next: HTMLElement | undefined): void => {\n if (historyScroller === next) return\n historyScroller?.removeEventListener('scroll', onHistoryScroll)\n historyScroller = next\n historyPreviousTop = next?.scrollTop ?? 0\n historyScroller?.addEventListener('scroll', onHistoryScroll, { passive: true })\n }\n const animateNavigation = (event: MouseEvent): void => {\n if (!(event.target instanceof Element)) return\n const trigger = event.target.closest<HTMLElement>('button,a,[role=\"tab\"],[aria-selected]')\n if (trigger === null || trigger.hasAttribute('disabled') || trigger.getAttribute('aria-disabled') === 'true') return\n if (trigger.getAttribute('aria-selected') === 'true' || trigger.getAttribute('aria-current') === 'true') return\n const settingsNavigation = trigger.closest('[data-dsh-mobile-settings-list]') !== null\n const conversationNavigation = trigger.matches('[role=\"tab\"]')\n const sidebarNavigation = trigger.closest('[data-dsh-mobile-sidebar-root]') !== null\n && trigger.closest('[data-dsh-mobile-toggle]') === null\n if (!settingsNavigation && !conversationNavigation && !sidebarNavigation) return\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n if (transitionFrame !== 0) cancelAnimationFrame(transitionFrame)\n if (transitionRestartFrame !== 0) cancelAnimationFrame(transitionRestartFrame)\n transitionFrame = requestAnimationFrame(() => {\n transitionFrame = 0\n const target = settingsNavigation\n ? document.querySelector<HTMLElement>('[data-dsh-mobile-settings-content]')\n : viewArea\n if (target === null || target === undefined) return\n transitionTarget?.removeAttribute('data-dsh-mobile-view-transition')\n target.removeAttribute('data-dsh-mobile-view-transition')\n transitionRestartFrame = requestAnimationFrame(() => {\n transitionRestartFrame = 0\n transitionTarget = target\n target.dataset.dshMobileViewTransition = 'true'\n if (transitionTimer !== 0) clearTimeout(transitionTimer)\n transitionTimer = window.setTimeout(() => {\n target.removeAttribute('data-dsh-mobile-view-transition')\n if (transitionTarget === target) transitionTarget = undefined\n transitionTimer = 0\n }, 240)\n })\n })\n }\n document.addEventListener('click', animateNavigation)\n const syncMediaBinding = (composer: Element | null): void => {\n const previousComposer = boundComposer\n boundComposer = composer\n const session = currentSessionOrigin()\n if (composer === previousComposer && session.sessionRoot === boundSessionRoot && session.sessionId === boundSessionId) return\n boundSessionRoot = session.sessionRoot\n boundSessionId = session.sessionId\n mediaRequestGeneration += 1\n }\n\n const sync = (): void => {\n scheduled = 0\n frame = firstByClassSuffix(document, '_frame')\n const dedicatedCenter = document.querySelector<HTMLElement>('.dshm-main') ?? undefined\n if (frame !== undefined) frame.dataset.dshMobileFrame = 'true'\n sidebar = frame === undefined\n ? document.querySelector<HTMLElement>('.dshm-drawer') ?? undefined\n : firstByClassSuffix(frame, '_sidebarCol')\n const center = frame === undefined ? dedicatedCenter : firstByClassSuffix(frame, '_centerCol')\n const details = frame === undefined ? undefined : firstByClassSuffix(frame, '_detailsCol')\n const handle = frame === undefined ? undefined : firstByClassSuffix(frame, '_handle')\n if (center === undefined) {\n bindHistoryScroller(undefined)\n syncMediaBinding(null)\n setMediaActionsDisabled(true, label('Apri prima una sessione', 'Open a session first', '请先打开会话'))\n mediaActions.remove()\n return\n }\n if (center !== undefined) {\n center.dataset.dshMobileCenter = 'true'\n center.querySelector<HTMLElement>('header')?.setAttribute('data-dsh-mobile-header', 'true')\n viewArea = firstByClassSuffix(center, '_viewArea')\n if (viewArea !== undefined) viewArea.dataset.dshMobileView = 'true'\n const conversation = center.querySelector<HTMLElement>('[data-conversation-scroll]')\n bindHistoryScroller(conversation ?? undefined)\n const historyLoader = conversation === null ? undefined : firstByClassSuffix(conversation, '_older')\n if (historyLoader !== undefined) {\n historyLoader.dataset.dshMobileHistoryLoader = 'true'\n historyLoader.setAttribute('aria-live', 'polite')\n const button = historyLoader.querySelector<HTMLButtonElement>('button')\n if (button !== null) {\n button.tabIndex = -1\n if (button.disabled) button.removeAttribute('aria-hidden')\n else button.setAttribute('aria-hidden', 'true')\n }\n }\n const messageColumn = conversation === null ? undefined : firstByClassSuffix(conversation, '_column')\n const messageScroll = messageColumn?.parentElement\n if (messageColumn !== undefined && messageScroll !== null && messageScroll !== undefined && classToken(messageScroll, '_scroll')) {\n messageColumn.dataset.dshMobileMessageColumn = 'true'\n messageScroll.dataset.dshMobileMessageScroll = 'true'\n }\n for (const table of center.querySelectorAll<HTMLTableElement>('table')) {\n const parent = table.parentElement\n if (parent?.dataset.dshMobileTableScroll === 'true') continue\n const wrapper = document.createElement('div')\n wrapper.dataset.dshMobileTableScroll = 'true'\n table.before(wrapper)\n wrapper.append(table)\n }\n const composerCard = center.querySelector<HTMLElement>('[data-composer-card]')\n const composerRow = composerCard?.querySelector<HTMLElement>(':scope > [data-input-scroll]')?.nextElementSibling\n if (!(composerRow instanceof HTMLElement)) {\n syncMediaBinding(null)\n setMediaActionsDisabled(true, label('Apri prima una sessione', 'Open a session first', '请先打开会话'))\n mediaActions.remove()\n }\n if (composerRow instanceof HTMLElement) {\n composerRow.dataset.dshMobileComposerRow = 'true'\n const groups = Array.from(composerRow.children).filter((child): child is HTMLElement => child instanceof HTMLElement)\n const composerTools = groups[0]\n const composerTrailing = groups.at(-1)\n if (composerTools !== undefined) {\n composerTools.dataset.dshMobileComposerTools = 'true'\n syncMediaBinding(composerCard ?? null)\n const composerInput = composerCard?.querySelector<HTMLTextAreaElement>('textarea')\n const composerEditor = composerCard?.querySelector<HTMLElement>('[contenteditable=\"true\"],[contenteditable=\"plaintext-only\"]')\n const composerBusy = composerCard?.getAttribute('aria-busy') === 'true'\n || composerInput?.disabled === true\n || composerInput?.readOnly === true\n || composerEditor?.getAttribute('aria-disabled') === 'true'\n const attachmentBlocked = !canAcceptComposerDrop()\n const mediaDisabled = conversation === null || currentSessionOrigin().sessionId === null || composerBusy || attachmentBlocked\n const mediaTitle = composerBusy\n ? label('Attendi il completamento della risposta', 'Wait for the response to finish', '请等待回复完成')\n : attachmentBlocked\n ? label('Allegati immagine non disponibili', 'Image attachments are unavailable', '图片附件不可用')\n : mediaDisabled\n ? label('Apri prima una sessione', 'Open a session first', '请先打开会话')\n : label('Allega screenshot, immagine o foto', 'Attach screenshot, image, or photo', '附加截图、图片或照片')\n setMediaActionsDisabled(mediaDisabled, mediaTitle)\n const commandMenu = composerCard?.querySelector<HTMLElement>('[data-trigger-menu]') ?? null\n if (commandMenu !== null && (mediaActions.parentElement !== commandMenu || commandMenu.firstElementChild !== mediaActions)) {\n commandMenu.prepend(mediaActions)\n }\n }\n if (composerTrailing !== undefined && composerTrailing !== composerTools) {\n composerTrailing.dataset.dshMobileComposerTrailing = 'true'\n const modelTrigger = composerTrailing.querySelector<HTMLButtonElement>('button[aria-label^=\"选择模型\"],button[aria-label^=\"Select model\"],button[aria-label^=\"Seleziona modello\"]')\n if (modelTrigger !== null) {\n modelTrigger.dataset.dshMobileComposerModelTrigger = 'true'\n modelTrigger.parentElement?.setAttribute('data-dsh-mobile-composer-model', 'true')\n modelTrigger.querySelector<HTMLElement>('[class*=\"_triggerLabel\"]')?.setAttribute('data-dsh-mobile-composer-model-label', 'true')\n }\n }\n }\n }\n if (handle !== undefined) handle.dataset.dshMobileHandle = 'true'\n if (details !== undefined) {\n details.dataset.dshMobileDetails = 'true'\n const lastColumn = frame?.style.gridTemplateColumns.trim().split(/\\s+/).at(-1)\n details.dataset.open = String(lastColumn !== undefined && lastColumn !== '0px' && lastColumn !== '0')\n }\n const settings = Array.from(document.querySelectorAll<HTMLElement>('[role=\"dialog\"]')).find(dialog => {\n const directNav = Array.from(dialog.children).find(child => child instanceof HTMLElement && classToken(child, '_nav'))\n return directNav !== undefined\n })\n if (settings !== undefined) {\n settings.dataset.dshMobileSettings = 'true'\n const nav = Array.from(settings.children).find(child => child instanceof HTMLElement && classToken(child, '_nav')) as HTMLElement | undefined\n const content = Array.from(settings.children).find(child => child instanceof HTMLElement && classToken(child, '_content')) as HTMLElement | undefined\n if (nav !== undefined) {\n nav.dataset.dshMobileSettingsNav = 'true'\n firstByClassSuffix(nav, '_navList')?.setAttribute('data-dsh-mobile-settings-list', 'true')\n }\n if (content !== undefined) {\n content.dataset.dshMobileSettingsContent = 'true'\n firstByClassSuffix(content, '_header')?.setAttribute('data-dsh-mobile-settings-header', 'true')\n firstByClassSuffix(content, '_options')?.setAttribute('data-dsh-mobile-settings-options', 'true')\n }\n }\n if (sidebar === undefined) return\n sidebar.dataset.dshMobileSidebar = 'true'\n toggle = firstByClassSuffix(sidebar, '_toggle') as HTMLButtonElement | undefined\n let candidate = toggle?.parentElement\n while (candidate !== undefined && candidate !== null && candidate !== sidebar && !classToken(candidate, '_root')) candidate = candidate.parentElement\n sidebarRoot = candidate !== sidebar && candidate !== null ? candidate : undefined\n if (sidebarRoot === undefined) return\n sidebarRoot.dataset.dshMobileSidebarRoot = 'true'\n for (const brand of sidebarRoot.querySelectorAll<HTMLElement>('[class*=\"_fallbackBrandName\"]')) {\n if (brand.textContent?.trim() === 'DSH Local Build') brand.textContent = 'DeepSeek Harness'\n }\n if (toggle !== undefined) toggle.dataset.dshMobileToggle = 'true'\n const collapsed = classToken(sidebarRoot, '_collapsed')\n sidebar.dataset.open = String(!collapsed)\n backdrop.hidden = collapsed\n }\n const schedule = (): void => { if (scheduled === 0) scheduled = requestAnimationFrame(sync) }\n const observer = new MutationObserver(schedule)\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'style', 'disabled', 'readonly', 'aria-busy', 'aria-selected', 'data-dsh-mobile-session'] })\n backdrop.addEventListener('click', () => { if (sidebar?.dataset.open === 'true') toggle?.click() })\n sync()\n return () => {\n disposed = true\n mediaRequestGeneration += 1\n mediaPickerAbortController.abort()\n restoreLanguageMarker()\n for (const cleanup of [...browserPickerCleanups]) cleanup()\n observer.disconnect()\n document.removeEventListener('click', onBranchClick, true)\n fileButton.removeEventListener('pointerdown', quietMediaPointer)\n cameraButton.removeEventListener('pointerdown', quietMediaPointer)\n fileButton.removeEventListener('click', chooseImage)\n cameraButton.removeEventListener('click', takePhoto)\n if (branchToastTimer !== 0) window.clearTimeout(branchToastTimer)\n if (mediaToastTimer !== 0) window.clearTimeout(mediaToastTimer)\n branchToast.remove()\n mediaToast.remove()\n mediaActions.remove()\n if (scheduled !== 0) cancelAnimationFrame(scheduled)\n if (transitionFrame !== 0) cancelAnimationFrame(transitionFrame)\n if (transitionRestartFrame !== 0) cancelAnimationFrame(transitionRestartFrame)\n if (transitionTimer !== 0) clearTimeout(transitionTimer)\n transitionTarget?.removeAttribute('data-dsh-mobile-view-transition')\n historyScroller?.removeEventListener('scroll', onHistoryScroll)\n document.removeEventListener('pointerdown', onPointerDown, true)\n document.removeEventListener('keydown', onKeyDown, true)\n document.removeEventListener('click', animateNavigation)\n backdrop.remove()\n document.documentElement.classList.remove('dsh-native-mobile-active')\n delete document.documentElement.dataset.dshMobileInput\n }\n}\n","import { createElement } from 'react'\nimport {\n DIAGNOSTIC_REASON_MESSAGES,\n LOCALIZED_DIAGNOSTIC_COPY,\n MOBILE_CONTROL_MESSAGES,\n type MobileControlLocale,\n} from './client-messages.js'\nimport { installNativeMobileSurface, NATIVE_MOBILE_STYLES } from './native-mobile.js'\n\nexport { DIAGNOSTIC_REASON_MESSAGES, MOBILE_CONTROL_MESSAGES } from './client-messages.js'\nexport type { MobileControlLocale } from './client-messages.js'\n\ninterface ClientContext {\n effect(effect: () => void | (() => void), label?: string): void\n get(name: 'connection'): MobileConnectionHandle\n slots: {\n inject(key: string, callback: () => (() => void)): () => void\n register<Props>(options: { name: string; id: string; order?: number; label?: string }, component: (props: Props) => unknown): () => void\n }\n}\n\ninterface MobileConnectionHandle {\n isLoopback: boolean\n}\n\ninterface MobileExtensionContext {\n readonly document: Document\n readonly request: (path: string, init?: RequestInit) => Promise<Response>\n readonly root: HTMLElement\n readonly window: Window\n}\n\ntype MobileExtensionMount = (context: MobileExtensionContext) => void | (() => void)\ntype MobileSurfacePlacement = 'page' | 'sidebar-action' | 'header-action' | 'composer-dock' | 'settings-section' | 'overlay'\ninterface MobileSurface {\n readonly id: string\n readonly placement: MobileSurfacePlacement\n readonly label: string\n mount(container: HTMLElement): void | (() => void)\n}\ninterface MobileClientApi {\n readonly host: {\n invoke(action: string, input: unknown): Promise<unknown>\n fetch(path: string, init?: RequestInit): Promise<Response>\n assetUrl(path: string): string\n }\n readonly ui: {\n registerSurface(surface: MobileSurface): () => void\n open(surfaceId: string): void\n close(surfaceId: string): void\n toast(message: string): void\n }\n readonly native: {\n capabilities(): Promise<readonly string[]>\n invoke(action: string, input?: unknown): Promise<unknown>\n }\n readonly signal: AbortSignal\n readonly document: Document\n readonly window: Window\n}\ninterface MobileClientDefinition {\n readonly apiVersion: 1\n readonly id: string\n activate(api: MobileClientApi): void | (() => void) | Promise<void | (() => void)>\n}\n\ndeclare global {\n interface Window {\n dshMobile?: {\n register(mount: MobileExtensionMount): void\n define(definition: MobileClientDefinition): void\n }\n __DSH_MOBILE_FRONTEND__?: 'dedicated'\n __DSH_MOBILE_NATIVE__?: {\n capabilities(): Promise<readonly string[]> | readonly string[]\n invoke(action: string, input?: unknown): Promise<unknown>\n }\n }\n}\n\nconst queuedDefinitions: MobileClientDefinition[] = []\nlet queuedLegacyMount: MobileExtensionMount | undefined\nif (typeof window !== 'undefined' && window.dshMobile === undefined) {\n window.dshMobile = {\n register: mount => { queuedLegacyMount = mount },\n define: definition => { queuedDefinitions.push(definition) },\n }\n}\n\nfunction isLoopbackHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1' || hostname === '[::1]'\n}\n\nexport function selectMobileControlLocale(documentLanguage = '', navigatorLanguages: readonly string[] = []): MobileControlLocale {\n for (const value of [documentLanguage, ...navigatorLanguages]) {\n const language = value.trim().toLowerCase().split(/[-_]/u)[0]\n if (language === 'it' || language === 'en' || language === 'zh') return language\n }\n return 'en'\n}\n\nexport function selectedMobileControlLocale(): MobileControlLocale {\n return selectMobileControlLocale(document.documentElement.lang, navigator.languages?.length ? navigator.languages : [navigator.language])\n}\n\n/** Remount one plugin-owned surface when DSH changes the document language. */\nexport function installDshLanguageBoundSurface(install: () => () => void): () => void {\n let locale = selectedMobileControlLocale()\n let dispose = install()\n const observer = new MutationObserver(() => {\n const next = selectedMobileControlLocale()\n if (next === locale) return\n dispose()\n locale = next\n dispose = install()\n })\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['lang'] })\n return () => {\n observer.disconnect()\n dispose()\n }\n}\n\nfunction controlTranslator(locale = selectedMobileControlLocale()): (key: string, values?: Readonly<Record<string, string | number>>) => string {\n const messages = MOBILE_CONTROL_MESSAGES as Record<MobileControlLocale, Record<string, string>>\n return (key, values = {}) => {\n const template = messages[locale][key] ?? messages.en[key] ?? key\n return template.replace(/\\{(\\w+)\\}/gu, (_match: string, name: string) => String(values[name] ?? `{${name}}`))\n }\n}\n\nexport function normalizeDiagnosticOverall(value: unknown): 'ok' | 'attention' | 'error' {\n return value === 'ok' ? 'ok' : value === 'attention' ? 'attention' : 'error'\n}\n\nexport function normalizeDiagnosticStatus(value: unknown): 'ok' | 'warning' | 'error' | 'info' {\n return value === 'ok' || value === 'warning' || value === 'error' || value === 'info' ? value : 'error'\n}\n\nexport function diagnosticOverallForChecks(value: unknown, statuses: readonly unknown[]): 'ok' | 'attention' | 'error' {\n const normalized = statuses.map(normalizeDiagnosticStatus)\n const payloadOverall = normalizeDiagnosticOverall(value)\n if (payloadOverall === 'error' || normalized.includes('error')) return 'error'\n if (payloadOverall === 'attention' || normalized.includes('warning')) return 'attention'\n return 'ok'\n}\n\nexport function validateDiagnosticChecks(value: unknown): { readonly entries: readonly Record<string, unknown>[]; readonly malformed: boolean } {\n if (!Array.isArray(value)) return { entries: [], malformed: true }\n const entries: Record<string, unknown>[] = []\n let malformed = false\n for (const candidate of value) {\n if (typeof candidate !== 'object' || candidate === null || Array.isArray(candidate)) { malformed = true; continue }\n entries.push(candidate as Record<string, unknown>)\n }\n return { entries, malformed }\n}\n\nexport function diagnosticEntriesForRender(data: Readonly<Record<string, unknown>>): readonly Record<string, unknown>[] {\n const overallKnown = data.overall === 'ok' || data.overall === 'attention' || data.overall === 'error'\n const validated = validateDiagnosticChecks(data.checks)\n const statusesKnown = validated.entries.every(entry => entry.status === 'ok' || entry.status === 'warning' || entry.status === 'error' || entry.status === 'info')\n if (!overallKnown || validated.malformed || validated.entries.length === 0 || !statusesKnown) {\n throw new TypeError('diagnostics envelope is unavailable')\n }\n return validated.entries\n}\n\nexport function renderDiagnosticPayloadSafely(\n data: Record<string, unknown>,\n render: (data: Record<string, unknown>) => void,\n onFailure: (error: unknown) => void,\n): void {\n try { render(data) } catch (error) { onFailure(error) }\n}\n\nexport function diagnosticServerCopy(entry: Readonly<Record<string, unknown>>): { readonly label: string; readonly detail: string; readonly action: string } {\n return {\n label: typeof entry.label === 'string' ? entry.label : '',\n detail: typeof entry.detail === 'string' ? entry.detail : '',\n action: typeof entry.action === 'string' ? entry.action : '',\n }\n}\n\n/**\n * Match DSH's client-side privilege hint to the authenticated mobile gateway.\n * The gateway authenticates the paired device and forwards allowed requests to\n * DSH's loopback listener, so settings RPCs receive the same Host-side checks\n * as the desktop page even though the phone's visible URL is a LAN address.\n */\nexport function trustAuthenticatedGatewayConnection(connection: MobileConnectionHandle): () => void {\n const previous = connection.isLoopback\n connection.isLoopback = true\n return () => { connection.isLoopback = previous }\n}\n\nfunction element<K extends keyof HTMLElementTagNameMap>(tag: K, className?: string): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag)\n if (className !== undefined) node.className = className\n return node\n}\n\nconst CONTROL_REQUEST_TIMEOUT_MS = 15_000\nconst LONG_CONTROL_REQUEST_TIMEOUT_MS = 130_000\n\nasync function requestJson(\n path: string,\n init?: RequestInit,\n timeoutMs = CONTROL_REQUEST_TIMEOUT_MS,\n): Promise<Record<string, unknown>> {\n const controller = new AbortController()\n const upstreamSignal = init?.signal\n const abortFromUpstream = (): void => { controller.abort(upstreamSignal?.reason) }\n if (upstreamSignal?.aborted === true) abortFromUpstream()\n else upstreamSignal?.addEventListener('abort', abortFromUpstream, { once: true })\n const timer = window.setTimeout(() => { controller.abort() }, timeoutMs)\n try {\n const response = await fetch(path, {\n ...init,\n signal: controller.signal,\n headers: { 'content-type': 'application/json', ...init?.headers },\n })\n const body = await response.json() as Record<string, unknown>\n if (!response.ok) throw new Error(typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`)\n return body\n } catch (error) {\n if (controller.signal.aborted && upstreamSignal?.aborted !== true) {\n throw new Error(controlTranslator()('requestTimeout'))\n }\n throw error\n } finally {\n clearTimeout(timer)\n upstreamSignal?.removeEventListener('abort', abortFromUpstream)\n }\n}\n\nfunction officialFunnelSetupUrl(value: unknown): string {\n if (typeof value !== 'string' || value.length > 2048) return ''\n let url: URL\n try { url = new URL(value) } catch { return '' }\n const normalized = url.toString().replace(/\\/$/u, '')\n if (normalized === 'https://tailscale.com/s/no-funnel' || normalized === 'https://tailscale.com/s/https') return normalized\n if (url.protocol !== 'https:' || url.hostname !== 'login.tailscale.com' || url.port !== ''\n || url.username !== '' || url.password !== '') return ''\n return url.toString()\n}\n\nfunction installControl(): { remove: () => void; toggle: () => void } {\n const locale = selectedMobileControlLocale()\n const localeTag = locale === 'it' ? 'it-IT' : locale === 'zh' ? 'zh-CN' : 'en-US'\n const t = controlTranslator(locale)\n const lifecycle = new AbortController()\n const controlRequestJson = (path: string, init?: RequestInit, timeoutMs?: number): Promise<Record<string, unknown>> => requestJson(path, { ...init, signal: lifecycle.signal }, timeoutMs)\n const root = element('div', 'dsh-mobile-control'); root.lang = locale\n const panel = element('section', 'dsh-mobile-control__panel'); panel.hidden = true; panel.lang = locale\n panel.setAttribute('aria-label', t('mobileAccess'))\n const header = element('header', 'dsh-mobile-control__header')\n const title = element('h2'); title.textContent = t('mobileAccess')\n const headerActions = element('div', 'dsh-mobile-control__header-actions')\n const diagnosticsEntry = element('button', 'dsh-mobile-control__diagnostic-entry'); diagnosticsEntry.type = 'button'; diagnosticsEntry.textContent = t('diagnostics'); diagnosticsEntry.setAttribute('aria-label', t('openDiagnostics')); diagnosticsEntry.setAttribute('aria-pressed', 'false')\n const close = element('button', 'dsh-mobile-control__close'); close.type = 'button'; close.textContent = '×'; close.setAttribute('aria-label', t('collapseMobileAccess'))\n headerActions.append(diagnosticsEntry, close)\n const appDownload = element('a', 'dsh-mobile-control__app-download'); appDownload.href = 'https://github.com/saya-ch/dsh-mobile/releases/latest'; appDownload.target = '_blank'; appDownload.rel = 'noopener noreferrer'; appDownload.textContent = t('downloadAndroid'); appDownload.setAttribute('aria-label', t('downloadAndroidAria'))\n const switcher = element('div', 'dsh-mobile-control__switcher')\n const lanTab = element('button', 'dsh-mobile-control__tab is-active'); lanTab.type = 'button'; lanTab.textContent = t('lan')\n const remoteTab = element('button', 'dsh-mobile-control__tab'); remoteTab.type = 'button'; remoteTab.textContent = t('remote')\n lanTab.setAttribute('aria-pressed', 'true'); remoteTab.setAttribute('aria-pressed', 'false'); switcher.append(lanTab, remoteTab)\n const lanView = element('div', 'dsh-mobile-control__view')\n const access = element('div', 'dsh-mobile-control__access'); access.hidden = true\n const accessLabel = element('span', 'dsh-mobile-control__access-label'); accessLabel.textContent = t('browserAccess')\n const accessLink = element('a', 'dsh-mobile-control__access-link'); accessLink.target = '_blank'; accessLink.rel = 'noreferrer'\n access.append(accessLabel, accessLink)\n const qrBox = element('div', 'dsh-mobile-control__qr'); qrBox.hidden = true\n const status = element('p', 'dsh-mobile-control__status'); status.textContent = t('loadingStatus')\n const extensionStatus = element('p', 'dsh-mobile-control__extensions'); extensionStatus.hidden = true\n const actions = element('div', 'dsh-mobile-control__actions')\n const toggle = element('button', 'dsh-mobile-control__secondary'); toggle.type = 'button'\n const pair = element('button', 'dsh-mobile-control__primary'); pair.type = 'button'; pair.textContent = t('generateCopyKey')\n const linkPair = element('button', 'dsh-mobile-control__secondary'); linkPair.type = 'button'; linkPair.textContent = t('copyPairLink')\n const manageRow = element('div', 'dsh-mobile-control__manage-row')\n const manageDevices = element('button', 'dsh-mobile-control__manage'); manageDevices.type = 'button'; manageDevices.textContent = t('managePairedDevices')\n const resetAll = element('button', 'dsh-mobile-control__manage'); resetAll.type = 'button'; resetAll.textContent = t('clearAllDevices')\n manageRow.append(manageDevices, resetAll)\n const devicePanel = element('div', 'dsh-mobile-control__devices'); devicePanel.hidden = true\n const remoteView = element('div', 'dsh-mobile-control__view is-remote'); remoteView.hidden = true\n const remoteIntro = element('p', 'dsh-mobile-control__intro'); remoteIntro.textContent = t('remoteIntro')\n const providerSection = element('section', 'dsh-mobile-control__provider-section')\n const providerHeading = element('h3', 'dsh-mobile-control__section-title'); providerHeading.textContent = t('chooseProvider')\n const providerInfo = element('div', 'dsh-mobile-control__provider-info')\n const providerInfoButton = element('button', 'dsh-mobile-control__provider-info-button'); providerInfoButton.type = 'button'; providerInfoButton.setAttribute('aria-label', t('providerInfoAria')); providerInfoButton.setAttribute('aria-expanded', 'false'); providerInfoButton.setAttribute('aria-controls', 'dsh-mobile-provider-info'); providerInfoButton.setAttribute('aria-describedby', 'dsh-mobile-provider-info')\n const providerInfoGlyph = element('span', 'dsh-mobile-control__provider-info-glyph'); providerInfoGlyph.textContent = 'i'; providerInfoGlyph.setAttribute('aria-hidden', 'true')\n const providerInfoPopover = element('div', 'dsh-mobile-control__provider-info-popover'); providerInfoPopover.id = 'dsh-mobile-provider-info'; providerInfoPopover.setAttribute('role', 'tooltip'); providerInfoPopover.hidden = true\n const providerInfoTitle = element('strong'); providerInfoTitle.textContent = t('providerSafeTitle')\n const providerInfoText = element('span'); providerInfoText.textContent = t('providerSafeText')\n providerInfoButton.append(providerInfoGlyph); providerInfoPopover.append(providerInfoTitle, providerInfoText); providerInfo.append(providerInfoButton, providerInfoPopover)\n const providerChoices = element('div', 'dsh-mobile-control__provider-choices'); providerChoices.setAttribute('role', 'radiogroup'); providerChoices.setAttribute('aria-label', t('providerGroupAria'))\n const tailscaleChoice = element('button', 'dsh-mobile-control__provider'); tailscaleChoice.type = 'button'; tailscaleChoice.setAttribute('role', 'radio'); tailscaleChoice.setAttribute('aria-checked', 'true')\n const tailscaleChoiceTop = element('span', 'dsh-mobile-control__provider-top')\n const tailscaleChoiceName = element('strong'); tailscaleChoiceName.textContent = 'Tailscale Funnel'\n const tailscaleChoiceBadge = element('span', 'dsh-mobile-control__provider-badge'); tailscaleChoiceBadge.textContent = t('builtIn')\n const tailscaleChoiceDescription = element('span', 'dsh-mobile-control__provider-description'); tailscaleChoiceDescription.textContent = t('tailscaleDescription')\n tailscaleChoiceTop.append(tailscaleChoiceName, tailscaleChoiceBadge); tailscaleChoice.append(tailscaleChoiceTop, tailscaleChoiceDescription)\n const cpolarChoice = element('button', 'dsh-mobile-control__provider'); cpolarChoice.type = 'button'; cpolarChoice.setAttribute('role', 'radio'); cpolarChoice.setAttribute('aria-checked', 'false')\n const cpolarChoiceTop = element('span', 'dsh-mobile-control__provider-top')\n const cpolarChoiceName = element('strong'); cpolarChoiceName.textContent = 'cpolar'\n const cpolarChoiceBadge = element('span', 'dsh-mobile-control__provider-badge is-cpolar'); cpolarChoiceBadge.textContent = t('mainlandPreferred')\n const cpolarChoiceDescription = element('span', 'dsh-mobile-control__provider-description'); cpolarChoiceDescription.textContent = t('cpolarDescription')\n cpolarChoiceTop.append(cpolarChoiceName, cpolarChoiceBadge); cpolarChoice.append(cpolarChoiceTop, cpolarChoiceDescription)\n providerChoices.append(cpolarChoice, tailscaleChoice); providerSection.append(providerHeading, providerInfo, providerChoices)\n const cpolarSetup = element('section', 'dsh-mobile-control__cpolar-setup'); cpolarSetup.hidden = true\n const cpolarSetupTitle = element('h3', 'dsh-mobile-control__section-title'); cpolarSetupTitle.textContent = t('prepareCpolar')\n const cpolarComponentStatus = element('p', 'dsh-mobile-control__component-status'); cpolarComponentStatus.textContent = t('checkingComponent')\n const cpolarInstall = element('button', 'dsh-mobile-control__primary'); cpolarInstall.type = 'button'; cpolarInstall.textContent = t('installOfficial')\n const cpolarAccount = element('div', 'dsh-mobile-control__cpolar-account'); cpolarAccount.hidden = true\n const cpolarAccountText = element('p', 'dsh-mobile-control__component-note'); cpolarAccountText.textContent = t('cpolarAccountNote')\n const cpolarAccountLinks = element('div', 'dsh-mobile-control__link-row')\n const cpolarSignup = element('a', 'dsh-mobile-control__text-link'); cpolarSignup.href = 'https://dashboard.cpolar.com/signup'; cpolarSignup.target = '_blank'; cpolarSignup.rel = 'noopener noreferrer'; cpolarSignup.textContent = t('registerCpolar')\n const cpolarDashboard = element('a', 'dsh-mobile-control__text-link'); cpolarDashboard.href = 'https://dashboard.cpolar.com/auth'; cpolarDashboard.target = '_blank'; cpolarDashboard.rel = 'noopener noreferrer'; cpolarDashboard.textContent = t('openDashboard')\n cpolarAccountLinks.append(cpolarSignup, cpolarDashboard)\n const cpolarTokenLabel = element('label', 'dsh-mobile-control__token-label'); cpolarTokenLabel.textContent = 'Authtoken'\n const cpolarToken = element('input', 'dsh-mobile-control__token'); cpolarToken.type = 'password'; cpolarToken.autocomplete = 'off'; cpolarToken.spellcheck = false; cpolarToken.placeholder = t('tokenPlaceholder'); cpolarTokenLabel.append(cpolarToken)\n const cpolarConfigure = element('button', 'dsh-mobile-control__primary dsh-mobile-control__cpolar-connect'); cpolarConfigure.type = 'button'; cpolarConfigure.textContent = t('saveConnect')\n cpolarAccount.append(cpolarAccountText, cpolarAccountLinks, cpolarTokenLabel, cpolarConfigure)\n const cpolarDetails = element('details', 'dsh-mobile-control__details')\n const cpolarDetailsSummary = element('summary'); cpolarDetailsSummary.textContent = t('componentDetails')\n const cpolarDetailsBody = element('div', 'dsh-mobile-control__details-body')\n const cpolarDetailsText = element('p'); cpolarDetailsText.textContent = t('componentDetailsText')\n const cpolarStorage = element('code', 'dsh-mobile-control__storage'); cpolarStorage.textContent = t('pluginPrivateDirectory')\n const cpolarOfficial = element('a', 'dsh-mobile-control__text-link'); cpolarOfficial.href = 'https://www.cpolar.com/download'; cpolarOfficial.target = '_blank'; cpolarOfficial.rel = 'noopener noreferrer'; cpolarOfficial.textContent = t('officialDownload')\n const cpolarTerms = element('a', 'dsh-mobile-control__text-link'); cpolarTerms.href = 'https://www.cpolar.com/tos'; cpolarTerms.target = '_blank'; cpolarTerms.rel = 'noopener noreferrer'; cpolarTerms.textContent = t('terms')\n const cpolarPurge = element('button', 'dsh-mobile-control__danger'); cpolarPurge.type = 'button'; cpolarPurge.textContent = t('purgeCpolar')\n cpolarDetailsBody.append(cpolarDetailsText, cpolarStorage, cpolarOfficial, cpolarTerms, cpolarPurge); cpolarDetails.append(cpolarDetailsSummary, cpolarDetailsBody)\n cpolarSetup.append(cpolarSetupTitle, cpolarComponentStatus, cpolarInstall, cpolarAccount, cpolarDetails)\n const tailscaleInfo = element('details', 'dsh-mobile-control__details')\n const tailscaleInfoSummary = element('summary'); tailscaleInfoSummary.textContent = t('tailscaleHelp')\n const tailscaleInfoBody = element('div', 'dsh-mobile-control__details-body')\n const tailscaleInfoText = element('p'); tailscaleInfoText.textContent = t('tailscaleHelpText')\n tailscaleInfoBody.append(tailscaleInfoText); tailscaleInfo.append(tailscaleInfoSummary, tailscaleInfoBody)\n const remoteAccess = element('div', 'dsh-mobile-control__access'); remoteAccess.hidden = true\n const remoteAccessLabel = element('span', 'dsh-mobile-control__access-label'); remoteAccessLabel.textContent = t('remoteAddress')\n const remoteAccessLink = element('a', 'dsh-mobile-control__access-link'); remoteAccessLink.target = '_blank'; remoteAccessLink.rel = 'noreferrer'; remoteAccess.append(remoteAccessLabel, remoteAccessLink)\n const remoteQr = element('div', 'dsh-mobile-control__qr'); remoteQr.hidden = true\n const remoteStatus = element('p', 'dsh-mobile-control__status'); remoteStatus.textContent = t('loadingRemoteStatus'); remoteStatus.setAttribute('aria-live', 'polite')\n const remoteGuide = element('section', 'dsh-mobile-control__guide'); remoteGuide.hidden = true; remoteGuide.setAttribute('aria-label', t('funnelGuideAria'))\n const remoteGuideTitle = element('h3', 'dsh-mobile-control__guide-title'); remoteGuideTitle.textContent = t('funnelGuideTitle')\n const remoteGuideSummary = element('p', 'dsh-mobile-control__guide-summary'); remoteGuideSummary.textContent = t('funnelGuideSummary')\n const remoteGuideSteps = element('ol', 'dsh-mobile-control__guide-steps')\n for (const text of [t('funnelStep1'), t('funnelStep2'), t('funnelStep3')]) {\n const item = element('li'); item.textContent = text; remoteGuideSteps.append(item)\n }\n const remoteGuideNote = element('p', 'dsh-mobile-control__guide-note'); remoteGuideNote.textContent = t('funnelGuideNote')\n const remoteGuideActions = element('div', 'dsh-mobile-control__guide-actions')\n const remoteSetup = element('button', 'dsh-mobile-control__primary'); remoteSetup.type = 'button'; remoteSetup.textContent = t('continueFunnel')\n const remoteSetupRetry = element('button', 'dsh-mobile-control__secondary'); remoteSetupRetry.type = 'button'; remoteSetupRetry.textContent = t('retryNow')\n remoteGuideActions.append(remoteSetup, remoteSetupRetry); remoteGuide.append(remoteGuideTitle, remoteGuideSummary, remoteGuideSteps, remoteGuideNote, remoteGuideActions)\n const remoteActions = element('div', 'dsh-mobile-control__actions')\n const remoteToggle = element('button', 'dsh-mobile-control__primary'); remoteToggle.type = 'button'; remoteToggle.textContent = t('enableRemote')\n const remoteLogin = element('button', 'dsh-mobile-control__primary'); remoteLogin.type = 'button'; remoteLogin.textContent = t('continueLogin'); remoteLogin.hidden = true\n const remoteReconnect = element('button', 'dsh-mobile-control__secondary'); remoteReconnect.type = 'button'; remoteReconnect.textContent = t('reconnect'); remoteReconnect.hidden = true\n const remotePair = element('button', 'dsh-mobile-control__secondary'); remotePair.type = 'button'; remotePair.textContent = t('generateRemoteQr'); remotePair.disabled = true\n remoteActions.append(remoteToggle, remoteLogin, remoteReconnect, remotePair)\n const remoteManageRow = element('div', 'dsh-mobile-control__manage-row')\n const remoteDevices = element('button', 'dsh-mobile-control__manage'); remoteDevices.type = 'button'; remoteDevices.textContent = t('manageRemoteDevices'); remoteDevices.disabled = true\n const remoteReset = element('button', 'dsh-mobile-control__manage'); remoteReset.type = 'button'; remoteReset.textContent = t('resetRemoteLogin')\n remoteManageRow.append(remoteDevices, remoteReset)\n const remoteDevicePanel = element('div', 'dsh-mobile-control__devices'); remoteDevicePanel.hidden = true\n const diagnosticsView = element('div', 'dsh-mobile-control__view is-diagnostics'); diagnosticsView.hidden = true\n const diagnosticsIntro = element('p', 'dsh-mobile-control__intro'); diagnosticsIntro.textContent = t('diagnosticsIntro')\n const diagnosticsSummary = element('section', 'dsh-mobile-control__diagnostic-summary is-idle'); diagnosticsSummary.setAttribute('aria-live', 'polite')\n const diagnosticsSummaryMain = element('div', 'dsh-mobile-control__diagnostic-summary-main')\n const diagnosticsSummaryIcon = element('span', 'dsh-mobile-control__diagnostic-summary-icon'); diagnosticsSummaryIcon.setAttribute('aria-hidden', 'true')\n const diagnosticsSummaryBody = element('div', 'dsh-mobile-control__diagnostic-summary-body')\n const diagnosticsSummaryTitle = element('strong'); diagnosticsSummaryTitle.textContent = t('diagnosticsNotRun')\n const diagnosticsSummaryText = element('span'); diagnosticsSummaryText.textContent = t('diagnosticsStartHint')\n const diagnosticsSummaryMeta = element('span', 'dsh-mobile-control__diagnostic-summary-meta'); diagnosticsSummaryMeta.textContent = t('diagnosticsIdleMeta')\n diagnosticsSummaryBody.append(diagnosticsSummaryTitle, diagnosticsSummaryText)\n diagnosticsSummaryMain.append(diagnosticsSummaryIcon, diagnosticsSummaryBody)\n diagnosticsSummary.append(diagnosticsSummaryMain, diagnosticsSummaryMeta)\n const diagnosticsToolbar = element('div', 'dsh-mobile-control__diagnostic-toolbar')\n const diagnosticsRun = element('button', 'dsh-mobile-control__primary dsh-mobile-control__diagnostic-run'); diagnosticsRun.type = 'button'; diagnosticsRun.textContent = t('diagnosticsStart')\n const diagnosticsCopy = element('button', 'dsh-mobile-control__secondary dsh-mobile-control__diagnostic-copy'); diagnosticsCopy.type = 'button'; diagnosticsCopy.textContent = t('diagnosticsCopy'); diagnosticsCopy.disabled = true; diagnosticsCopy.hidden = true\n diagnosticsToolbar.append(diagnosticsRun, diagnosticsCopy)\n const diagnosticsFeedback = element('p', 'dsh-mobile-control__diagnostic-feedback'); diagnosticsFeedback.hidden = true; diagnosticsFeedback.setAttribute('role', 'status'); diagnosticsFeedback.setAttribute('aria-live', 'polite')\n const diagnosticsChecks = element('div', 'dsh-mobile-control__diagnostic-checks'); diagnosticsChecks.hidden = true\n const diagnosticsDetails = element('details', 'dsh-mobile-control__details dsh-mobile-control__diagnostic-details'); diagnosticsDetails.hidden = true\n const diagnosticsDetailsSummary = element('summary'); diagnosticsDetailsSummary.textContent = t('diagnosticsAdvanced')\n const diagnosticsReport = element('pre', 'dsh-mobile-control__diagnostic-report')\n diagnosticsDetails.append(diagnosticsDetailsSummary, diagnosticsReport)\n header.append(title, headerActions); actions.append(toggle, pair, linkPair)\n lanView.append(access, qrBox, status, extensionStatus, actions, manageRow, devicePanel)\n remoteView.append(remoteIntro, providerSection, cpolarSetup, tailscaleInfo, remoteAccess, remoteQr, remoteStatus, remoteGuide, remoteActions, remoteManageRow, remoteDevicePanel)\n diagnosticsView.append(diagnosticsIntro, diagnosticsSummary, diagnosticsToolbar, diagnosticsFeedback, diagnosticsChecks, diagnosticsDetails)\n panel.append(header, appDownload, switcher, lanView, remoteView, diagnosticsView); root.append(panel); document.body.append(root)\n let running = false\n let origin = ''\n let remoteRunning = false\n let remoteReady = false\n let remoteProvider: 'tailscale' | 'cpolar' = 'tailscale'\n let remoteLoginUrl = ''\n let remoteSetupUrl = ''\n let remoteSetupPending = false\n let remoteSetupOpenedAt = 0\n let remoteReconnectBusy = false\n let remoteProviderBusy = false\n let cpolarInstalled = false\n let cpolarConfigured = false\n let providerInfoPinned = false\n let providerInfoHovered = false\n let previousAccessView: 'lan' | 'remote' = 'lan'\n let diagnosticsBusy = false\n let copiedDiagnosticReport = ''\n const syncProviderInfo = (): void => {\n const open = providerInfoPinned || providerInfoHovered || providerInfo.contains(document.activeElement)\n providerInfoPopover.hidden = !open\n providerInfoButton.setAttribute('aria-expanded', String(open))\n }\n providerInfo.addEventListener('pointerenter', () => { providerInfoHovered = true; syncProviderInfo() })\n providerInfo.addEventListener('pointerleave', () => { providerInfoHovered = false; syncProviderInfo() })\n providerInfo.addEventListener('focusin', syncProviderInfo)\n providerInfo.addEventListener('focusout', () => { window.setTimeout(syncProviderInfo, 0) })\n providerInfoButton.addEventListener('click', () => { providerInfoPinned = !providerInfoPinned; syncProviderInfo() })\n providerInfoButton.addEventListener('keydown', event => {\n if (event.key !== 'Escape') return\n providerInfoPinned = false\n providerInfoHovered = false\n providerInfoPopover.hidden = true\n providerInfoButton.setAttribute('aria-expanded', 'false')\n })\n const selectView = (view: 'lan' | 'remote' | 'diagnostics'): void => {\n if (view !== 'diagnostics') previousAccessView = view\n lanView.hidden = view !== 'lan'\n remoteView.hidden = view !== 'remote'\n diagnosticsView.hidden = view !== 'diagnostics'\n lanTab.classList.toggle('is-active', view === 'lan')\n remoteTab.classList.toggle('is-active', view === 'remote')\n lanTab.setAttribute('aria-pressed', String(view === 'lan'))\n remoteTab.setAttribute('aria-pressed', String(view === 'remote'))\n diagnosticsEntry.setAttribute('aria-pressed', String(view === 'diagnostics'))\n diagnosticsEntry.textContent = view === 'diagnostics' ? t('back') : t('diagnostics')\n diagnosticsEntry.setAttribute('aria-label', view === 'diagnostics' ? t('backToMobile') : t('openDiagnostics'))\n appDownload.hidden = view === 'diagnostics'\n switcher.hidden = view === 'diagnostics'\n title.textContent = view === 'lan' ? t('lanAccess') : view === 'remote' ? t('remoteAccess') : t('connectionDiagnostics')\n }\n lanTab.addEventListener('click', () => { selectView('lan') })\n remoteTab.addEventListener('click', () => { selectView('remote'); loadRemote() })\n const setOpen = (open: boolean): void => {\n panel.hidden = !open\n for (const trigger of document.querySelectorAll('.dsh-mobile-control__trigger')) trigger.setAttribute('aria-expanded', String(open))\n }\n const render = (data: Record<string, unknown>): void => {\n running = data.running === true\n origin = running && typeof data.origin === 'string' ? data.origin : ''\n access.hidden = origin === ''\n accessLink.href = origin\n accessLink.textContent = origin\n accessLink.title = origin\n status.classList.toggle('is-running', running)\n status.textContent = running ? t('lanOn') : t('lanOff')\n const extensionData = data.extensions\n if (extensionData !== null && typeof extensionData === 'object') {\n const loaded = typeof (extensionData as { loaded?: unknown }).loaded === 'number' ? (extensionData as { loaded: number }).loaded : 0\n const failed = typeof (extensionData as { failed?: unknown }).failed === 'number' ? (extensionData as { failed: number }).failed : 0\n extensionStatus.hidden = false\n extensionStatus.textContent = failed === 0 ? t('extensionsLoaded', { loaded }) : t('extensionsFailed', { loaded, failed })\n } else extensionStatus.hidden = true\n if (!running) qrBox.hidden = true\n toggle.textContent = running ? t('disableLan') : t('enableLan')\n pair.disabled = !running\n linkPair.disabled = !running\n manageDevices.disabled = !running\n resetAll.disabled = !running\n }\n const showQr = (svg: string, target: HTMLDivElement = qrBox): void => {\n target.replaceChildren()\n if (svg === '') { target.hidden = true; return }\n const image = element('img')\n image.alt = t('pairingQr')\n image.width = 176\n image.height = 176\n image.src = `data:image/svg+xml;base64,${btoa(svg)}`\n target.hidden = false\n target.append(image)\n }\n const openPairing = (target: 'key' | 'link'): void => {\n void controlRequestJson('/api/mobile-access/lan/pairing/open', { method: 'POST', body: '{}' }).then(async data => {\n const value = target === 'key'\n ? (typeof data.appKey === 'string' ? data.appKey : '')\n : (typeof data.pairUrl === 'string' ? data.pairUrl : '')\n showQr(typeof data.qrSvg === 'string' ? data.qrSvg : '')\n if (value === '') { status.textContent = t('keyGenerationFailed'); return }\n try {\n await navigator.clipboard.writeText(value)\n status.textContent = target === 'key'\n ? t('keyCopied')\n : t('linkCopied')\n } catch {\n status.textContent = t('copySecret', { kind: target === 'key' ? t('pairingKey') : t('pairingLink'), value })\n status.classList.add('is-key')\n }\n }, error => { status.textContent = t('requestFailed', { error: String(error) }) }).finally(() => {\n pair.disabled = !running\n linkPair.disabled = !running\n })\n }\n toggle.addEventListener('click', () => { toggle.disabled = true; void controlRequestJson('/api/mobile-access/lan/control', { method: 'POST', body: JSON.stringify({ running: !running }) }).then(render, error => { status.textContent = t('requestFailed', { error: String(error) }) }).finally(() => { toggle.disabled = false }) })\n const formatTime = (ms: unknown): string => typeof ms === 'number' ? new Date(ms).toLocaleString(localeTag) : ''\n const formatMegabytes = (bytes: number): string => new Intl.NumberFormat(localeTag, { minimumFractionDigits: 1, maximumFractionDigits: 1 }).format(bytes / 1024 / 1024)\n const renderDevices = (data: Record<string, unknown>): void => {\n const devices = Array.isArray(data.devices) ? data.devices as Record<string, unknown>[] : []\n devicePanel.replaceChildren()\n if (devices.length === 0) {\n const empty = element('p', 'dsh-mobile-control__device-empty'); empty.textContent = t('noDevices')\n devicePanel.append(empty)\n return\n }\n for (const device of devices) {\n const row = element('div', 'dsh-mobile-control__device')\n const label = element('span', 'dsh-mobile-control__device-label')\n label.textContent = typeof device.label === 'string' ? device.label : t('device')\n const meta = element('span', 'dsh-mobile-control__device-meta'); meta.textContent = t('expires', { time: formatTime(device.expiresAt) })\n const revoke = element('button', 'dsh-mobile-control__device-revoke'); revoke.type = 'button'; revoke.textContent = t('revoke')\n const id = typeof device.id === 'string' ? device.id : ''\n revoke.addEventListener('click', () => {\n void controlRequestJson('/api/mobile-access/lan/devices/revoke', { method: 'POST', body: JSON.stringify({ deviceId: id }) })\n .then(loadDevices, error => { status.textContent = t('requestFailed', { error: String(error) }) })\n })\n row.append(label, meta, revoke)\n devicePanel.append(row)\n }\n }\n const loadDevices = (): void => {\n void controlRequestJson('/api/mobile-access/lan/devices').then(renderDevices, error => { status.textContent = t('requestFailed', { error: String(error) }) })\n }\n manageDevices.addEventListener('click', () => {\n const show = devicePanel.hidden\n devicePanel.hidden = !show\n if (show) loadDevices()\n })\n resetAll.addEventListener('click', () => {\n if (!window.confirm(t('confirmResetDevices'))) return\n void controlRequestJson('/api/mobile-access/lan/devices/reset', { method: 'POST', body: JSON.stringify({ confirm: true }) })\n .then(loadDevices, error => { status.textContent = t('requestFailed', { error: String(error) }) })\n })\n const renderRemote = (data: Record<string, unknown>): void => {\n remoteRunning = data.running === true\n remoteProvider = data.provider === 'cpolar' ? 'cpolar' : 'tailscale'\n const cpolar = remoteProvider === 'cpolar'\n tailscaleChoice.classList.toggle('is-selected', !cpolar)\n cpolarChoice.classList.toggle('is-selected', cpolar)\n tailscaleChoice.setAttribute('aria-checked', String(!cpolar))\n cpolarChoice.setAttribute('aria-checked', String(cpolar))\n tailscaleChoice.disabled = remoteProviderBusy\n cpolarChoice.disabled = remoteProviderBusy\n cpolarSetup.hidden = !cpolar\n tailscaleInfo.hidden = cpolar\n remoteReset.textContent = cpolar ? t('resetRemoteDevices') : t('resetRemoteLogin')\n const providers = data.providers !== null && typeof data.providers === 'object' ? data.providers as Record<string, unknown> : {}\n const cpolarProvider = providers.cpolar !== null && typeof providers.cpolar === 'object' ? providers.cpolar as Record<string, unknown> : {}\n const component = cpolarProvider.component !== null && typeof cpolarProvider.component === 'object'\n ? cpolarProvider.component as Record<string, unknown>\n : {}\n cpolarInstalled = component.installed === true\n cpolarConfigured = component.configured === true\n cpolarChoiceBadge.textContent = cpolarConfigured ? t('ready') : cpolarInstalled ? t('installed') : t('mainlandPreferred')\n const cpolarSupported = component.supported !== false\n const componentVersion = typeof component.version === 'string' ? component.version : ''\n const componentDownloadBytes = typeof component.downloadBytes === 'number' ? component.downloadBytes : 0\n const componentStorage = typeof component.storagePath === 'string' ? component.storagePath : `DSH Mobile ${t('pluginPrivateDirectory')}`\n cpolarStorage.textContent = componentStorage\n cpolarStorage.title = componentStorage\n cpolarInstall.hidden = cpolarInstalled || !cpolarSupported\n cpolarInstall.textContent = componentDownloadBytes > 0\n ? t('installWithSize', { size: formatMegabytes(componentDownloadBytes) })\n : t('installOfficial')\n cpolarInstall.disabled = remoteProviderBusy\n cpolarAccount.hidden = !cpolarInstalled || cpolarConfigured\n cpolarConfigure.disabled = remoteProviderBusy\n cpolarPurge.hidden = !cpolarInstalled && !cpolarConfigured\n cpolarComponentStatus.textContent = !cpolarSupported\n ? t('cpolarUnsupported')\n : !cpolarInstalled\n ? t('cpolarNotInstalled')\n : !cpolarConfigured\n ? t('cpolarNeedsToken', { version: componentVersion })\n : t('cpolarReady', { version: componentVersion })\n const state = typeof data.state === 'string' ? data.state : 'error'\n const errorCode = typeof data.errorCode === 'string' ? data.errorCode : ''\n const remoteOrigin = typeof data.origin === 'string' ? data.origin : ''\n remoteLoginUrl = typeof data.loginUrl === 'string' ? data.loginUrl : ''\n const candidateSetupUrl = cpolar ? '' : officialFunnelSetupUrl(data.setupUrl)\n const fallbackSetupUrls: Record<string, string> = {\n funnel_permission_required: 'https://tailscale.com/s/no-funnel',\n funnel_https_required: 'https://tailscale.com/s/https',\n funnel_start_failed: 'https://tailscale.com/s/no-funnel',\n }\n remoteSetupUrl = candidateSetupUrl !== '' ? candidateSetupUrl : (fallbackSetupUrls[errorCode] ?? '')\n const needsFunnelSetup = state === 'error' && remoteSetupUrl !== ''\n remoteReady = remoteRunning && state === 'ready' && remoteOrigin !== ''\n remoteAccess.hidden = !remoteReady\n remoteAccessLink.href = remoteOrigin\n remoteAccessLink.textContent = remoteOrigin\n remoteAccessLink.title = remoteOrigin\n remoteStatus.classList.toggle('is-running', remoteReady)\n const labels: Record<string, string> = {\n off: t('remoteOff'),\n unavailable: cpolar ? t('remoteUnavailableCpolar') : t('remoteUnavailableTailscale'),\n starting: cpolar ? t('remoteStartingCpolar') : t('remoteStartingTailscale'),\n 'needs-login': t('remoteNeedsLogin'),\n connecting: cpolar ? t('remoteConnectingCpolar') : t('remoteConnectingTailscale'),\n ready: t('remoteReady'),\n error: t('remoteError'),\n }\n const errorLabels: Record<string, string> = {\n funnel_permission_required: t('funnelPermission'),\n funnel_https_required: t('funnelHttps'),\n funnel_start_failed: t('funnelStart'),\n funnel_start_timeout: t('funnelTimeout'),\n tailscale_dns_missing: t('tailscaleDnsMissing'),\n gateway_start_failed: t('gatewayStartFailed'),\n control_channel_failed: t('controlChannelFailed'),\n cpolar_component_missing: t('cpolarMissing'),\n cpolar_component_invalid: t('cpolarInvalid'),\n cpolar_config_missing: t('cpolarConfigMissing'),\n cpolar_config_invalid: t('cpolarConfigInvalid'),\n cpolar_port_unavailable: t('cpolarPortUnavailable'),\n cpolar_launch_failed: t('cpolarLaunchFailed'),\n cpolar_start_timeout: t('cpolarTimeout'),\n cpolar_stopped: t('cpolarStopped'),\n cpolar_exited: t('cpolarExited'),\n cpolar_invalid_output: t('cpolarOutputInvalid'),\n cpolar_invalid_origin: t('cpolarOriginInvalid'),\n }\n remoteStatus.textContent = remoteSetupPending && needsFunnelSetup\n ? t('setupOpened')\n : (state === 'error' ? (errorLabels[errorCode] ?? labels.error!) : (labels[state] ?? labels.error!))\n remoteGuide.hidden = !needsFunnelSetup\n remoteSetup.disabled = remoteSetupUrl === '' || remoteReconnectBusy\n remoteSetupRetry.disabled = remoteReconnectBusy\n remoteToggle.textContent = remoteRunning ? t('disableRemote') : t('enableRemote')\n remoteToggle.disabled = remoteProviderBusy || (cpolar && (!cpolarInstalled || !cpolarConfigured))\n remoteLogin.hidden = cpolar || state !== 'needs-login' || remoteLoginUrl === ''\n remoteReconnect.hidden = needsFunnelSetup || (state !== 'error' && state !== 'unavailable')\n || (cpolar && (!cpolarInstalled || !cpolarConfigured))\n remoteActions.hidden = cpolar && (!cpolarInstalled || !cpolarConfigured)\n remotePair.disabled = !remoteReady\n remoteDevices.disabled = !remoteReady\n if (!remoteReady) remoteQr.hidden = true\n if (!needsFunnelSetup) remoteSetupPending = false\n }\n let remoteLoadInFlight = false\n const loadRemote = (): void => {\n if (remoteLoadInFlight) return\n remoteLoadInFlight = true\n void controlRequestJson('/api/mobile-access/remote/control')\n .then(renderRemote, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n .finally(() => { remoteLoadInFlight = false })\n }\n const chooseRemoteProvider = (provider: 'tailscale' | 'cpolar'): void => {\n if (remoteProviderBusy || provider === remoteProvider) return\n if (remoteRunning && !window.confirm(t('switchProviderConfirm'))) return\n remoteProviderBusy = true\n tailscaleChoice.disabled = true\n cpolarChoice.disabled = true\n remoteStatus.textContent = provider === 'cpolar' ? t('switchingCpolar') : t('switchingTailscale')\n void controlRequestJson('/api/mobile-access/remote/provider', { method: 'POST', body: JSON.stringify({ provider }) })\n .then(renderRemote, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n .finally(() => { remoteProviderBusy = false; loadRemote() })\n }\n tailscaleChoice.addEventListener('click', () => { chooseRemoteProvider('tailscale') })\n cpolarChoice.addEventListener('click', () => { chooseRemoteProvider('cpolar') })\n cpolarInstall.addEventListener('click', () => {\n if (remoteProviderBusy) return\n const accepted = window.confirm(t('installConfirm'))\n if (!accepted) return\n remoteProviderBusy = true\n cpolarInstall.disabled = true\n cpolarInstall.textContent = t('downloading')\n remoteStatus.textContent = t('installingCpolar')\n void controlRequestJson('/api/mobile-access/remote/cpolar/component/install', { method: 'POST', body: JSON.stringify({ confirm: true }) }, LONG_CONTROL_REQUEST_TIMEOUT_MS)\n .then(renderRemote, error => { remoteStatus.textContent = t('installFailed', { error: String(error) }) })\n .finally(() => { remoteProviderBusy = false; loadRemote() })\n })\n cpolarConfigure.addEventListener('click', () => {\n if (remoteProviderBusy) return\n const authtoken = cpolarToken.value.trim()\n if (authtoken.length < 20 || /\\s/u.test(authtoken)) {\n remoteStatus.textContent = t('invalidToken')\n cpolarToken.focus()\n return\n }\n remoteProviderBusy = true\n cpolarConfigure.disabled = true\n cpolarConfigure.setAttribute('aria-busy', 'true')\n cpolarConfigure.textContent = t('saving')\n void controlRequestJson('/api/mobile-access/remote/cpolar/configure', { method: 'POST', body: JSON.stringify({ authtoken }) }, LONG_CONTROL_REQUEST_TIMEOUT_MS)\n .then(() => {\n cpolarToken.value = ''\n remoteStatus.textContent = t('configuredConnecting')\n return controlRequestJson('/api/mobile-access/remote/control', { method: 'POST', body: JSON.stringify({ running: true }) })\n })\n .then(renderRemote, error => { remoteStatus.textContent = t('configureFailed', { error: String(error) }) })\n .finally(() => { remoteProviderBusy = false; cpolarConfigure.setAttribute('aria-busy', 'false'); cpolarConfigure.textContent = t('saveConnect'); loadRemote() })\n })\n cpolarPurge.addEventListener('click', () => {\n if (remoteProviderBusy) return\n if (!window.confirm(t('purgeConfirm'))) return\n remoteProviderBusy = true\n cpolarPurge.disabled = true\n remoteStatus.textContent = t('purging')\n void controlRequestJson('/api/mobile-access/remote/cpolar/component/purge', { method: 'POST', body: JSON.stringify({ confirm: true }) }, LONG_CONTROL_REQUEST_TIMEOUT_MS)\n .then(renderRemote, error => { remoteStatus.textContent = t('purgeFailed', { error: String(error) }) })\n .finally(() => { remoteProviderBusy = false; cpolarPurge.disabled = false; loadRemote() })\n })\n remoteToggle.addEventListener('click', () => {\n remoteToggle.disabled = true\n void controlRequestJson('/api/mobile-access/remote/control', { method: 'POST', body: JSON.stringify({ running: !remoteRunning }) })\n .then(renderRemote, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n .finally(loadRemote)\n })\n remoteLogin.addEventListener('click', () => {\n if (remoteLoginUrl !== '') window.open(remoteLoginUrl, '_blank', 'noopener,noreferrer')\n })\n const reconnectRemote = (): void => {\n if (remoteReconnectBusy) return\n remoteReconnectBusy = true\n remoteReconnect.disabled = true\n remoteSetup.disabled = true\n remoteSetupRetry.disabled = true\n remoteStatus.textContent = remoteProvider === 'cpolar' ? t('reconnectingCpolar') : t('reconnectingTailscale')\n void controlRequestJson('/api/mobile-access/remote/reconnect', { method: 'POST', body: '{}' })\n .then(renderRemote, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n .finally(() => {\n remoteReconnectBusy = false\n remoteReconnect.disabled = false\n remoteSetup.disabled = remoteSetupUrl === ''\n remoteSetupRetry.disabled = false\n })\n }\n remoteReconnect.addEventListener('click', reconnectRemote)\n remoteSetupRetry.addEventListener('click', () => { remoteSetupPending = false; reconnectRemote() })\n remoteSetup.addEventListener('click', () => {\n if (remoteSetupUrl === '') return\n remoteSetupPending = true\n remoteSetupOpenedAt = Date.now()\n remoteStatus.textContent = t('setupOpened')\n window.open(remoteSetupUrl, '_blank', 'noopener,noreferrer')\n })\n const retryAfterSetup = (): void => {\n if (!remoteSetupPending || document.visibilityState === 'hidden' || Date.now() - remoteSetupOpenedAt < 800) return\n remoteSetupPending = false\n reconnectRemote()\n }\n window.addEventListener('focus', retryAfterSetup)\n document.addEventListener('visibilitychange', retryAfterSetup)\n remotePair.addEventListener('click', () => {\n remotePair.disabled = true\n void controlRequestJson('/api/mobile-access/remote/pairing/open', { method: 'POST', body: '{}' }).then(async data => {\n const pairUrl = typeof data.pairUrl === 'string' ? data.pairUrl : ''\n showQr(typeof data.qrSvg === 'string' ? data.qrSvg : '', remoteQr)\n if (pairUrl !== '') {\n try { await navigator.clipboard.writeText(pairUrl) } catch { /* QR remains the primary remote handoff. */ }\n }\n remoteStatus.textContent = t('remoteQrReady')\n }, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) }).finally(() => { remotePair.disabled = !remoteReady })\n })\n const renderRemoteDevices = (data: Record<string, unknown>): void => {\n const devices = Array.isArray(data.devices) ? data.devices as Record<string, unknown>[] : []\n remoteDevicePanel.replaceChildren()\n if (devices.length === 0) {\n const empty = element('p', 'dsh-mobile-control__device-empty'); empty.textContent = t('noRemoteDevices'); remoteDevicePanel.append(empty); return\n }\n for (const device of devices) {\n const row = element('div', 'dsh-mobile-control__device')\n const label = element('span', 'dsh-mobile-control__device-label'); label.textContent = typeof device.label === 'string' ? device.label : t('device')\n const meta = element('span', 'dsh-mobile-control__device-meta'); meta.textContent = t('expires', { time: formatTime(device.expiresAt) })\n const revoke = element('button', 'dsh-mobile-control__device-revoke'); revoke.type = 'button'; revoke.textContent = t('revoke')\n const id = typeof device.id === 'string' ? device.id : ''\n revoke.addEventListener('click', () => {\n void controlRequestJson('/api/mobile-access/remote/devices/revoke', { method: 'POST', body: JSON.stringify({ deviceId: id }) })\n .then(loadRemoteDevices, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n })\n row.append(label, meta, revoke); remoteDevicePanel.append(row)\n }\n }\n const loadRemoteDevices = (): void => {\n void controlRequestJson('/api/mobile-access/remote/devices').then(renderRemoteDevices, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n }\n remoteDevices.addEventListener('click', () => {\n const show = remoteDevicePanel.hidden\n remoteDevicePanel.hidden = !show\n if (show) loadRemoteDevices()\n })\n remoteReset.addEventListener('click', () => {\n const prompt = remoteProvider === 'cpolar'\n ? t('resetCpolarConfirm')\n : t('resetTailscaleConfirm')\n if (!window.confirm(prompt)) return\n void controlRequestJson('/api/mobile-access/remote/reset', { method: 'POST', body: JSON.stringify({ confirm: true }) })\n .then(renderRemote, error => { remoteStatus.textContent = t('requestFailed', { error: String(error) }) })\n })\n const renderDiagnostics = (data: Record<string, unknown>): void => {\n const entries = [...diagnosticEntriesForRender(data)]\n const overall = diagnosticOverallForChecks(data.overall, entries.map(entry => entry.status))\n diagnosticsSummary.className = `dsh-mobile-control__diagnostic-summary is-${overall}`\n diagnosticsSummaryTitle.textContent = overall === 'ok' ? t('diagnosticsComplete') : overall === 'attention' ? t('diagnosticsAttention') : t('diagnosticsProblem')\n diagnosticsSummaryText.textContent = locale === 'zh' && data.overall === overall && typeof data.summary === 'string' ? data.summary : t('diagnosticsCompleteFallback')\n diagnosticsChecks.replaceChildren()\n const statusLabels: Record<string, string> = { ok: t('diagnosticStatusOk'), warning: t('diagnosticStatusWarning'), error: t('diagnosticStatusError'), info: t('diagnosticStatusInfo') }\n const diagnosticLabelKeys: Record<string, string> = {\n versions: 'diagnosticLabelVersions', network: 'diagnosticLabelNetwork', lan: 'diagnosticLabelLan',\n firewall: 'diagnosticLabelFirewall', remote: 'diagnosticLabelRemote', 'phone-network': 'diagnosticLabelPhone',\n }\n const statusOf = (entry: Record<string, unknown>): 'ok' | 'warning' | 'error' | 'info' => normalizeDiagnosticStatus(entry.status)\n const localizedEntryCopy = (entry: Record<string, unknown>): { readonly detail: string; readonly action: string } => {\n const serverCopy = diagnosticServerCopy(entry)\n const reason = typeof entry.reason === 'string' ? entry.reason : ''\n const catalog = DIAGNOSTIC_REASON_MESSAGES[locale] as Readonly<Record<string, readonly [string, string]>>\n const templates = catalog[reason]\n if (templates === undefined) return serverCopy\n const facts = entry.facts !== null && typeof entry.facts === 'object' ? entry.facts as Record<string, unknown> : {}\n const values: Record<string, string> = {\n provider: facts.provider === 'tailscale' || facts.provider === 'cpolar' ? facts.provider : '',\n latencyMs: typeof facts.latencyMs === 'number' && Number.isFinite(facts.latencyMs) ? new Intl.NumberFormat(localeTag).format(facts.latencyMs) : '',\n interfaceName: typeof facts.interfaceName === 'string' ? facts.interfaceName : '',\n endpointSuffix: typeof facts.endpointSuffix === 'string' ? facts.endpointSuffix : '',\n controllerCode: typeof facts.controllerCode === 'string' ? facts.controllerCode : '',\n }\n const interpolate = (template: string): string => template.replace(/\\{(\\w+)\\}/gu, (_match, key: string) => values[key] ?? '')\n let detail = interpolate(templates[0])\n let action = interpolate(templates[1])\n if (reason === 'versions-current') {\n const versions = data.versions !== null && typeof data.versions === 'object' ? data.versions as Record<string, unknown> : {}\n if ([versions.plugin, versions.dsh, versions.minimumAndroidApp].every(value => typeof value === 'string')) {\n detail += ` plugin ${String(versions.plugin)}, DSH ${String(versions.dsh)}, Android ${String(versions.minimumAndroidApp)}.`\n }\n }\n if (reason === 'remote-controller-error') {\n const controllerActionKeys: Readonly<Record<string, string>> = {\n component_missing: 'remoteUnavailableTailscale', funnel_permission_required: 'funnelPermission', funnel_https_required: 'funnelHttps', funnel_start_failed: 'funnelStart', funnel_start_timeout: 'funnelTimeout', tailscale_dns_missing: 'tailscaleDnsMissing',\n sidecar_launch_failed: 'remoteUnavailableTailscale', sidecar_stopped: 'controlChannelFailed', sidecar_exited: 'controlChannelFailed', control_channel_failed: 'controlChannelFailed',\n cpolar_component_missing: 'cpolarMissing', cpolar_component_invalid: 'cpolarInvalid', cpolar_config_missing: 'cpolarConfigMissing', cpolar_config_invalid: 'cpolarConfigInvalid', cpolar_start_timeout: 'cpolarTimeout', cpolar_stopped: 'cpolarStopped', cpolar_exited: 'cpolarExited', gateway_start_failed: 'gatewayStartFailed',\n }\n const actionKey = controllerActionKeys[values.controllerCode ?? '']\n if (actionKey !== undefined) action = t(actionKey)\n }\n return { detail, action }\n }\n const appendGroup = (label: string, groupEntries: Record<string, unknown>[]): void => {\n if (groupEntries.length === 0) return\n const group = element('section', 'dsh-mobile-control__diagnostic-group')\n const groupHeader = element('header', 'dsh-mobile-control__diagnostic-group-header')\n const groupTitle = element('h3'); groupTitle.textContent = label\n const groupCount = element('span'); groupCount.textContent = t('diagnosticItems', { count: groupEntries.length })\n const list = element('div', 'dsh-mobile-control__diagnostic-list'); list.setAttribute('role', 'list')\n groupHeader.append(groupTitle, groupCount)\n for (const entry of groupEntries) {\n const state = statusOf(entry)\n const row = element('section', `dsh-mobile-control__diagnostic-check is-${state}`); row.setAttribute('role', 'listitem')\n const marker = element('span', 'dsh-mobile-control__diagnostic-marker'); marker.setAttribute('aria-hidden', 'true')\n const rowBody = element('div', 'dsh-mobile-control__diagnostic-check-body')\n const rowHeader = element('div', 'dsh-mobile-control__diagnostic-check-header')\n const labelKey = typeof entry.id === 'string' ? diagnosticLabelKeys[entry.id] : undefined\n const rowTitle = element('strong'); rowTitle.textContent = locale !== 'zh' && labelKey !== undefined ? t(labelKey) : typeof entry.label === 'string' ? entry.label : t('diagnosticCheck')\n const badge = element('span', 'dsh-mobile-control__diagnostic-badge'); badge.textContent = statusLabels[state]!\n const localizedCopy = localizedEntryCopy(entry)\n const detail = element('p'); detail.textContent = localizedCopy.detail\n rowHeader.append(rowTitle, badge); rowBody.append(rowHeader, detail)\n if (localizedCopy.action !== '') {\n const action = element('p', 'dsh-mobile-control__diagnostic-action')\n const actionLabel = element('span'); actionLabel.textContent = t('diagnosticAction')\n action.append(actionLabel, document.createTextNode(localizedCopy.action)); rowBody.append(action)\n }\n row.append(marker, rowBody); list.append(row)\n }\n group.append(groupHeader, list); diagnosticsChecks.append(group)\n }\n const issues = entries.filter(entry => statusOf(entry) === 'error' || statusOf(entry) === 'warning')\n const otherChecks = entries.filter(entry => statusOf(entry) !== 'error' && statusOf(entry) !== 'warning')\n appendGroup(t('diagnosticNeedsAction'), issues)\n appendGroup(issues.length === 0 ? t('diagnosticDetails') : t('diagnosticOther'), otherChecks)\n diagnosticsSummaryMeta.textContent = issues.length === 0\n ? t('diagnosticNoBlockers', { count: entries.length })\n : t('diagnosticNeedsCount', { count: entries.length, issues: issues.length })\n diagnosticsChecks.hidden = entries.length === 0\n const reportCopy = LOCALIZED_DIAGNOSTIC_COPY[locale]\n const generatedAt = typeof data.generatedAt === 'number' ? new Date(data.generatedAt).toLocaleString(localeTag) : new Date().toLocaleString(localeTag)\n const lines = entries.map(entry => {\n const state = statusOf(entry)\n const labelKey = typeof entry.id === 'string' ? diagnosticLabelKeys[entry.id] : undefined\n const label = labelKey === undefined && typeof entry.label === 'string' ? entry.label : labelKey === undefined ? t('diagnosticCheck') : t(labelKey)\n const localizedCopy = localizedEntryCopy(entry)\n return `[${statusLabels[state]!}] ${label}: ${localizedCopy.detail}${localizedCopy.action === '' ? '' : ` ${localizedCopy.action}`}`\n })\n copiedDiagnosticReport = [reportCopy.reportTitle, `${reportCopy.generated}: ${generatedAt}`, ...lines].join('\\n')\n diagnosticsReport.textContent = copiedDiagnosticReport\n diagnosticsDetails.hidden = copiedDiagnosticReport === ''\n diagnosticsCopy.disabled = copiedDiagnosticReport === ''\n diagnosticsCopy.hidden = copiedDiagnosticReport === ''\n diagnosticsToolbar.classList.toggle('has-report', copiedDiagnosticReport !== '')\n }\n const showDiagnosticsFailure = (error: unknown): void => {\n diagnosticsSummary.className = 'dsh-mobile-control__diagnostic-summary is-error'\n diagnosticsSummaryTitle.textContent = t('diagnosticsIncomplete')\n diagnosticsSummaryText.textContent = t('diagnosticsReadFailed', { error: String(error) })\n diagnosticsSummaryMeta.textContent = t('diagnosticsUnavailable')\n diagnosticsChecks.replaceChildren()\n diagnosticsChecks.hidden = true\n copiedDiagnosticReport = ''\n diagnosticsReport.textContent = ''\n diagnosticsDetails.hidden = true\n diagnosticsCopy.disabled = true\n diagnosticsCopy.hidden = true\n diagnosticsToolbar.classList.remove('has-report')\n }\n const loadDiagnostics = (): void => {\n if (diagnosticsBusy) return\n diagnosticsBusy = true\n diagnosticsRun.disabled = true\n diagnosticsRun.setAttribute('aria-busy', 'true')\n diagnosticsRun.textContent = t('diagnosticsChecking')\n diagnosticsSummary.className = 'dsh-mobile-control__diagnostic-summary is-running'\n diagnosticsSummaryTitle.textContent = t('diagnosticsCheckingTitle')\n diagnosticsSummaryText.textContent = t('diagnosticsCheckingText')\n diagnosticsSummaryMeta.textContent = t('diagnosticsRunningMeta')\n diagnosticsFeedback.hidden = true\n diagnosticsChecks.classList.add('is-refreshing')\n diagnosticsChecks.setAttribute('aria-busy', 'true')\n void controlRequestJson('/api/mobile-access/diagnostics').then(\n data => { renderDiagnosticPayloadSafely(data, renderDiagnostics, showDiagnosticsFailure) },\n showDiagnosticsFailure,\n ).finally(() => {\n diagnosticsBusy = false\n diagnosticsRun.disabled = false\n diagnosticsRun.setAttribute('aria-busy', 'false')\n diagnosticsRun.textContent = t('diagnosticsRetry')\n diagnosticsChecks.classList.remove('is-refreshing')\n diagnosticsChecks.setAttribute('aria-busy', 'false')\n })\n }\n diagnosticsEntry.addEventListener('click', () => {\n if (!diagnosticsView.hidden) { selectView(previousAccessView); return }\n selectView('diagnostics'); loadDiagnostics()\n })\n diagnosticsRun.addEventListener('click', loadDiagnostics)\n diagnosticsCopy.addEventListener('click', () => {\n if (copiedDiagnosticReport === '') return\n void navigator.clipboard.writeText(copiedDiagnosticReport).then(() => {\n diagnosticsFeedback.textContent = t('diagnosticsCopied')\n diagnosticsFeedback.hidden = false\n }, () => {\n diagnosticsDetails.open = true\n diagnosticsFeedback.textContent = t('diagnosticsCopyManual')\n diagnosticsFeedback.hidden = false\n })\n })\n pair.addEventListener('click', () => { pair.disabled = true; openPairing('key') })\n linkPair.addEventListener('click', () => { linkPair.disabled = true; openPairing('link') })\n close.addEventListener('click', () => { setOpen(false) })\n const dismiss = (event: PointerEvent): void => {\n if (panel.hidden || !(event.target instanceof Node)) return\n if (!providerInfo.contains(event.target)) {\n providerInfoPinned = false\n providerInfoHovered = false\n syncProviderInfo()\n }\n if (!panel.contains(event.target) && !document.querySelector('.dsh-mobile-control__trigger')?.contains(event.target)) setOpen(false)\n }\n document.addEventListener('pointerdown', dismiss)\n void controlRequestJson('/api/mobile-access/lan/control').then(render, error => { status.textContent = t('requestFailed', { error: String(error) }) })\n loadRemote()\n const remotePoll = window.setInterval(() => { if (!panel.hidden && !remoteView.hidden) loadRemote() }, 1_500)\n return { remove: () => { lifecycle.abort(); window.clearInterval(remotePoll); window.removeEventListener('focus', retryAfterSetup); document.removeEventListener('visibilitychange', retryAfterSetup); document.removeEventListener('pointerdown', dismiss); root.remove() }, toggle: () => { setOpen(panel.hidden !== false) } }\n}\n\nfunction mobileRequest(path: string, init: RequestInit = {}): Promise<Response> {\n const target = new URL(path, location.href)\n if (target.origin !== location.origin) throw new TypeError('mobile extension requests must stay on the DSH origin')\n const headers = new Headers(init.headers)\n const method = (init.method ?? 'GET').toUpperCase()\n if (method !== 'GET' && method !== 'HEAD') {\n const csrf = document.cookie.split(';').map(value => value.trim()).find(value => value.startsWith('dsh_ma_csrf='))?.slice(12)\n if (csrf !== undefined) headers.set('x-dsh-mobile-csrf', csrf)\n }\n return fetch(target, { ...init, headers, credentials: 'same-origin', cache: 'no-store', redirect: 'error' })\n}\n\nexport interface CombinedClientSignal {\n readonly signal: AbortSignal\n readonly cleanup: () => void\n}\n\n/** Combine extension and caller abort lifetimes and expose deterministic listener cleanup. */\nexport function combineClientSignalLifetime(first: AbortSignal, second: AbortSignal): CombinedClientSignal {\n if (first.aborted || second.aborted) {\n const aborted = new AbortController()\n aborted.abort(first.aborted ? first.reason : second.reason)\n return { signal: aborted.signal, cleanup: () => undefined }\n }\n const controller = new AbortController()\n const cleanup = (): void => {\n first.removeEventListener('abort', abortFirst)\n second.removeEventListener('abort', abortSecond)\n }\n const abortFirst = (): void => { cleanup(); controller.abort(first.reason) }\n const abortSecond = (): void => { cleanup(); controller.abort(second.reason) }\n first.addEventListener('abort', abortFirst, { once: true })\n second.addEventListener('abort', abortSecond, { once: true })\n return { signal: controller.signal, cleanup }\n}\n\n/** Combine extension and caller abort lifetimes on WebViews without AbortSignal.any. */\nexport function combineClientSignals(first: AbortSignal, second: AbortSignal): AbortSignal {\n return combineClientSignalLifetime(first, second).signal\n}\n\n/** Keep a combined request lifetime until a streamed response is consumed or cancelled. */\nexport function bindClientResponseLifetime(response: Response, cleanup: () => void): Response {\n if (response.body === null) {\n cleanup()\n return response\n }\n const reader = response.body.getReader()\n let released = false\n const release = (): void => {\n if (released) return\n released = true\n cleanup()\n }\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const result = await reader.read()\n if (result.done) {\n release()\n controller.close()\n } else controller.enqueue(result.value)\n } catch (error) {\n release()\n controller.error(error)\n }\n },\n async cancel(reason) {\n try { await reader.cancel(reason) } finally { release() }\n },\n })\n try {\n const retained = new Response(body, { headers: response.headers, status: response.status, statusText: response.statusText })\n Object.defineProperties(retained, {\n redirected: { configurable: true, value: response.redirected },\n type: { configurable: true, value: response.type },\n url: { configurable: true, value: response.url },\n })\n return retained\n } catch (error) {\n void reader.cancel(error)\n release()\n throw error\n }\n}\n\n/** Dispose an old UI when its replacement Host generation cannot be activated. */\nexport function failClosedExtensionGenerationReplacement(\n hasActive: boolean,\n activeGeneration: string | undefined,\n replacementGeneration: string | undefined,\n dispose: () => void,\n): boolean {\n if (!hasActive || activeGeneration === replacementGeneration) return false\n dispose()\n return true\n}\n\n/** Resolve one SDK route and prove its normalized path remains in the current extension namespace. */\nexport function extensionRouteUrl(id: string, path: string, baseUrl: string): URL {\n const rawPathname = path.split(/[?#]/u, 1)[0] ?? ''\n if (!/^[a-z][a-z0-9-]{0,63}$/u.test(id) || !path.startsWith('/') || path.startsWith('//')\n || rawPathname.includes('\\\\') || rawPathname.includes('\\0') || /%(?:2f|5c)/iu.test(rawPathname)) {\n throw new TypeError('extension routes must be relative')\n }\n const origin = new URL(baseUrl).origin\n const prefix = `/mobile-access/extensions/${id}/routes`\n let target: URL\n try { target = new URL(`${prefix}${path}`, origin) } catch { throw new TypeError('extension routes must be relative') }\n let decodedPathname: string\n try { decodedPathname = decodeURIComponent(target.pathname) } catch { throw new TypeError('extension routes must be relative') }\n if (target.origin !== origin || target.hash !== '' || decodedPathname.includes('\\\\')\n || decodedPathname !== prefix && !decodedPathname.startsWith(`${prefix}/`)) {\n throw new TypeError('extension routes must be relative')\n }\n const relative = decodedPathname.slice(prefix.length)\n if (relative.split('/').some(part => part === '.' || part === '..')) throw new TypeError('extension routes must be relative')\n return target\n}\n\n/** Resolve one generation-pinned static asset URL in the current extension namespace. */\nexport function extensionAssetUrl(id: string, generation: string | undefined, path: string, baseUrl: string): URL {\n if (!/^[a-z][a-z0-9-]{0,63}$/u.test(id) || generation !== undefined && !/^[a-f\\d]{64}$/u.test(generation)) {\n throw new TypeError('extension asset path is invalid')\n }\n const normalized = path.replaceAll('\\\\', '/')\n if (normalized.length === 0 || normalized.startsWith('/') || normalized.split('/').some(part => part === '' || part === '.' || part === '..')) {\n throw new TypeError('extension asset path is invalid')\n }\n const target = new URL(`/mobile-access/extensions/${id}/assets/${normalized.split('/').map(encodeURIComponent).join('/')}`, new URL(baseUrl).origin)\n if (generation !== undefined) target.searchParams.set('generation', generation)\n return target\n}\n\n/** Add the immutable Host generation selected for one activated mobile UI. */\nexport function extensionGenerationHeaders(generation: string | undefined, headers?: HeadersInit): Headers {\n const result = new Headers(headers)\n if (generation !== undefined) result.set('x-dsh-mobile-extension-generation', generation)\n return result\n}\n\nexport function registerUniqueDisposable<T extends { readonly dispose: () => void }>(\n entries: Map<string, T>,\n claimedIds: Set<string>,\n id: string,\n mount: () => T,\n): () => void {\n if (claimedIds.has(id)) throw new Error(`duplicate lifecycle id: ${id}`)\n claimedIds.add(id)\n let mounted: T\n try { mounted = mount() } catch (error) { claimedIds.delete(id); throw error }\n let disposed = false\n const dispose = (): void => {\n if (disposed) return\n disposed = true\n mounted.dispose()\n }\n const entry = { ...mounted, dispose } as T\n entries.set(id, entry)\n return () => {\n if (entries.get(id) === entry) { entries.delete(id); claimedIds.delete(id) }\n dispose()\n }\n}\n\n/** Dispose resources omitted by a successfully fetched authoritative manifest. */\nexport function reconcileRemovedExtensions(currentIds: Iterable<string>, seen: ReadonlySet<string>, dispose: (id: string) => void): void {\n for (const id of new Set(currentIds)) if (!seen.has(id)) dispose(id)\n}\n\n/** Reconcile managed resources against one validated authoritative id set. */\nexport function publishAuthoritativeExtensionIds(\n authoritativeIds: Set<string>,\n seen: ReadonlySet<string>,\n managedIdSources: readonly Iterable<string>[],\n dispose: (id: string) => void,\n): void {\n const current = new Set(authoritativeIds)\n for (const source of managedIdSources) for (const id of source) current.add(id)\n reconcileRemovedExtensions(current, seen, dispose)\n authoritativeIds.clear()\n for (const id of seen) authoritativeIds.add(id)\n}\n\ninterface MobileExtensionManifestEntry {\n readonly id: string\n readonly generation?: string\n readonly scriptUrl?: string\n readonly styleUrl?: string\n readonly assetsUrl?: string\n}\ninterface MobileExtensionManifest {\n readonly extensions: readonly MobileExtensionManifestEntry[]\n readonly legacy: { readonly scriptRevision: string; readonly styleRevision: string }\n}\n\nfunction validManifestResourceUrl(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith('/') && !value.startsWith('//') && !value.includes('://')\n && !value.split('/').some(part => part === '..' || part === '.')\n}\n\n/** Validate the manifest before treating it as authoritative state. */\nexport function parseMobileExtensionManifest(payload: unknown): MobileExtensionManifest | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined\n const candidate = payload as { protocol?: unknown; extensions?: unknown; legacy?: unknown }\n if (candidate.protocol !== 1 || !Array.isArray(candidate.extensions) || typeof candidate.legacy !== 'object' || candidate.legacy === null) return undefined\n const legacy = candidate.legacy as { scriptRevision?: unknown; styleRevision?: unknown }\n if (typeof legacy.scriptRevision !== 'string' || typeof legacy.styleRevision !== 'string') return undefined\n const ids = new Set<string>()\n const extensions: MobileExtensionManifestEntry[] = []\n for (const value of candidate.extensions) {\n if (typeof value !== 'object' || value === null) return undefined\n const entry = value as { id?: unknown; generation?: unknown; scriptUrl?: unknown; styleUrl?: unknown; assetsUrl?: unknown }\n if (typeof entry.id !== 'string' || !/^[a-z][a-z0-9-]{0,63}$/u.test(entry.id) || ids.has(entry.id)) return undefined\n if (entry.generation !== undefined && (typeof entry.generation !== 'string' || !/^[a-f\\d]{64}$/u.test(entry.generation))) return undefined\n if (entry.scriptUrl !== undefined && !validManifestResourceUrl(entry.scriptUrl)) return undefined\n if (entry.styleUrl !== undefined && !validManifestResourceUrl(entry.styleUrl)) return undefined\n if (entry.assetsUrl !== undefined && !validManifestResourceUrl(entry.assetsUrl)) return undefined\n ids.add(entry.id)\n extensions.push({\n id: entry.id,\n ...(entry.generation === undefined ? {} : { generation: entry.generation }),\n ...(entry.scriptUrl === undefined ? {} : { scriptUrl: entry.scriptUrl }),\n ...(entry.styleUrl === undefined ? {} : { styleUrl: entry.styleUrl }),\n ...(entry.assetsUrl === undefined ? {} : { assetsUrl: entry.assetsUrl }),\n })\n }\n return { extensions, legacy: { scriptRevision: legacy.scriptRevision, styleRevision: legacy.styleRevision } }\n}\n\n/** A missing manifest is authoritative before optional legacy resources finish refreshing. */\nexport async function handleMissingExtensionManifest(\n clearManifestResources: () => void,\n refreshLegacyResources: () => Promise<readonly boolean[]>,\n signal: AbortSignal,\n): Promise<boolean> {\n clearManifestResources()\n const results = await refreshLegacyResources()\n return !signal.aborted && results.every(Boolean)\n}\n\ninterface LifecycleSchedulerRuntime {\n readonly document: Pick<Document, 'visibilityState' | 'addEventListener' | 'removeEventListener'>\n readonly window: Pick<Window, 'addEventListener' | 'removeEventListener' | 'setTimeout' | 'clearTimeout'>\n}\n\nexport interface LifecycleRefreshController {\n (): void\n refresh(): void\n}\n\nfunction refreshAborted(signal: AbortSignal): boolean { return signal.aborted }\n\n/** Run one coalesced refresh cycle, slowing down when the page is hidden. */\nexport function startLifecycleRefreshScheduler(\n refresh: (signal: AbortSignal) => void | Promise<void>,\n options: { readonly visibleIntervalMs?: number; readonly hiddenIntervalMs?: number; readonly cycleTimeoutMs?: number } = {},\n runtime: LifecycleSchedulerRuntime = { document, window },\n): LifecycleRefreshController {\n const visibleIntervalMs = options.visibleIntervalMs ?? 45_000\n const hiddenIntervalMs = options.hiddenIntervalMs ?? 300_000\n const cycleTimeoutMs = options.cycleTimeoutMs ?? 30_000\n let timer: number | undefined\n let cycleTimer: number | undefined\n let running = false\n let queued = false\n let disposed = false\n let controller: AbortController | undefined\n const clearTimer = (): void => {\n if (timer === undefined) return\n runtime.window.clearTimeout(timer)\n timer = undefined\n }\n const clearCycleTimer = (): void => {\n if (cycleTimer === undefined) return\n runtime.window.clearTimeout(cycleTimer)\n cycleTimer = undefined\n }\n const schedule = (): void => {\n if (disposed) return\n clearTimer()\n const delay = runtime.document.visibilityState === 'hidden' ? hiddenIntervalMs : visibleIntervalMs\n timer = runtime.window.setTimeout(run, delay)\n }\n const run = (): void => {\n if (disposed) return\n clearTimer()\n if (running) { queued = true; return }\n running = true\n const current = new AbortController()\n controller = current\n const refreshPromise = Promise.resolve().then(() => refresh(current.signal))\n const timeoutPromise = new Promise<void>(resolve => {\n cycleTimer = runtime.window.setTimeout(() => {\n cycleTimer = undefined\n current.abort(new DOMException('mobile extension refresh timed out', 'TimeoutError'))\n resolve()\n }, cycleTimeoutMs)\n })\n void Promise.race([refreshPromise, timeoutPromise]).catch(() => { /* Keep the last good resources during reconnects. */ }).finally(() => {\n clearCycleTimer()\n if (controller === current) controller = undefined\n running = false\n if (disposed) return\n if (queued) { queued = false; run() } else schedule()\n })\n void refreshPromise.catch(() => { /* A timed-out refresh may reject after the scheduler has moved on. */ })\n }\n const onVisibilityChange = (): void => {\n if (runtime.document.visibilityState === 'hidden') schedule()\n else run()\n }\n runtime.document.addEventListener('visibilitychange', onVisibilityChange)\n runtime.window.addEventListener('focus', run)\n runtime.window.addEventListener('online', run)\n run()\n const stop = (): void => {\n disposed = true\n queued = false\n controller?.abort()\n controller = undefined\n clearCycleTimer()\n clearTimer()\n runtime.document.removeEventListener('visibilitychange', onVisibilityChange)\n runtime.window.removeEventListener('focus', run)\n runtime.window.removeEventListener('online', run)\n }\n return Object.assign(stop, { refresh: run })\n}\n\ninterface ExtensionEventRuntime {\n readonly window: Pick<Window, 'addEventListener' | 'removeEventListener' | 'setTimeout' | 'clearTimeout'>\n readonly create: (url: string) => Pick<EventSource, 'close' | 'onopen' | 'onerror' | 'addEventListener'>\n}\n\n/** Maintain one authenticated same-origin extension event stream with bounded reconnect backoff. */\nexport function startExtensionChangeStream(\n changed: () => void,\n runtime: ExtensionEventRuntime = {\n window,\n create: url => new EventSource(url, { withCredentials: true }),\n },\n): () => void {\n let source: ReturnType<ExtensionEventRuntime['create']> | undefined\n let timer: number | undefined\n let disposed = false\n let retryMs = 1_000\n const clearTimer = (): void => {\n if (timer === undefined) return\n runtime.window.clearTimeout(timer)\n timer = undefined\n }\n const connect = (): void => {\n if (disposed || source !== undefined) return\n clearTimer()\n const next = runtime.create('/mobile-access/extensions/events')\n source = next\n next.onopen = () => { retryMs = 1_000 }\n next.addEventListener('extensions-changed', changed)\n next.onerror = () => {\n if (source !== next) return\n next.close()\n source = undefined\n if (disposed) return\n const delay = retryMs\n retryMs = Math.min(30_000, retryMs * 2)\n timer = runtime.window.setTimeout(connect, delay)\n }\n }\n const reconnectNow = (): void => {\n if (disposed) return\n source?.close()\n source = undefined\n retryMs = 1_000\n connect()\n }\n runtime.window.addEventListener('online', reconnectNow)\n connect()\n return () => {\n disposed = true\n clearTimer()\n source?.close()\n source = undefined\n runtime.window.removeEventListener('online', reconnectNow)\n }\n}\n\nexport interface ActivationWork<T> {\n readonly result: Promise<T>\n readonly cancel: () => void\n readonly commit?: (value: T) => void\n readonly dispose: (value: T) => void\n}\n\ninterface PendingActivation<T> {\n readonly key: object\n readonly generation: number\n readonly controller: AbortController\n readonly cancel: () => void\n readonly completion: Promise<boolean>\n}\n\n/** Keep at most one activation in flight per id and commit only its latest generation. */\nexport class PerIdActivationLifecycle<T> {\n private readonly active = new Map<string, { readonly value: T; readonly dispose: () => void }>()\n private readonly pending = new Map<string, PendingActivation<T>>()\n private readonly generations = new Map<string, number>()\n private disposed = false\n\n hasActive(id: string): boolean { return this.active.has(id) }\n getActive(id: string): T | undefined { return this.active.get(id)?.value }\n pendingCount(): number { return this.pending.size }\n\n async activate(\n id: string,\n key: object,\n cycleSignal: AbortSignal | undefined,\n create: (controller: AbortController, generation: number) => ActivationWork<T>,\n ): Promise<boolean> {\n if (this.disposed || cycleSignal?.aborted === true) return false\n const existing = this.pending.get(id)\n if (existing !== undefined) {\n if (existing.key === key && !existing.controller.signal.aborted) return this.waitFor(existing, cycleSignal)\n existing.cancel()\n }\n const generation = (this.generations.get(id) ?? 0) + 1\n this.generations.set(id, generation)\n const controller = new AbortController()\n let work: ActivationWork<T>\n try { work = create(controller, generation) } catch {\n controller.abort(new DOMException('mobile extension activation failed to start', 'AbortError'))\n return false\n }\n let cancelled = false\n let pending = {} as PendingActivation<T>\n const cancel = (): void => {\n if (cancelled) return\n cancelled = true\n if (this.pending.get(id) === pending) this.pending.delete(id)\n if (this.generations.get(id) === generation) this.generations.set(id, generation + 1)\n controller.abort(new DOMException('mobile extension activation cancelled', 'AbortError'))\n work.cancel()\n }\n const completion = Promise.resolve(work.result).then(value => {\n const current = this.pending.get(id)\n const canCommit = !this.disposed && current === pending && current.generation === this.generations.get(id)\n && !controller.signal.aborted\n if (!canCommit) {\n try { work.dispose(value) } catch { /* A stale extension disposer must not break lifecycle cleanup. */ }\n return false\n }\n try { work.commit?.(value) } catch {\n try { work.dispose(value) } catch { /* Keep the previous active extension intact. */ }\n return false\n }\n const previous = this.active.get(id)\n let valueDisposed = false\n const dispose = (): void => {\n if (valueDisposed) return\n valueDisposed = true\n controller.abort(new DOMException('mobile extension deactivated', 'AbortError'))\n try { work.dispose(value) } catch { /* Disposers are isolated per extension. */ }\n }\n this.active.set(id, { value, dispose })\n previous?.dispose()\n return true\n }, () => {\n cancel()\n return false\n }).finally(() => {\n if (this.pending.get(id) === pending) this.pending.delete(id)\n })\n Object.assign(pending, { key, generation, controller, cancel, completion })\n this.pending.set(id, pending)\n return this.waitFor(pending, cycleSignal)\n }\n\n remove(id: string): void {\n this.generations.set(id, (this.generations.get(id) ?? 0) + 1)\n this.active.get(id)?.dispose()\n this.active.delete(id)\n this.pending.get(id)?.cancel()\n }\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n for (const current of this.active.values()) current.dispose()\n this.active.clear()\n for (const current of this.pending.values()) current.cancel()\n }\n\n private waitFor(pending: PendingActivation<T>, signal: AbortSignal | undefined): Promise<boolean> {\n if (signal === undefined) return pending.completion\n if (signal.aborted) { pending.cancel(); return Promise.resolve(false) }\n return new Promise<boolean>(resolve => {\n let settled = false\n const finish = (value: boolean): void => {\n if (settled) return\n settled = true\n signal.removeEventListener('abort', onAbort)\n resolve(value)\n }\n const onAbort = (): void => { pending.cancel(); finish(false) }\n signal.addEventListener('abort', onAbort, { once: true })\n void pending.completion.then(finish)\n })\n }\n}\n\nfunction installCustomAssets(): () => void {\n const legacyStyle = element('style'); legacyStyle.dataset.plugin = 'dsh-mobile-custom'; document.head.append(legacyStyle)\n const legacyCssState = { etag: '', modified: '' }\n const previous = window.dshMobile\n let legacyMount: MobileExtensionMount | undefined = queuedLegacyMount\n let legacySource = ''\n let legacyRoot: HTMLElement | undefined\n let legacyDispose: (() => void) | undefined\n const definitions = new Map<string, MobileClientDefinition>()\n type ExtensionSurfaceEntry = { readonly dispose: () => void; readonly container: HTMLElement; readonly host: () => HTMLElement }\n type ActiveExtension = { readonly controller: AbortController; readonly surfaces: Map<string, ExtensionSurfaceEntry>; readonly cleanup?: () => void }\n const activations = new PerIdActivationLifecycle<ActiveExtension>()\n const styleNodes = new Map<string, HTMLStyleElement>()\n const styleEtags = new Map<string, string>()\n const scriptDigests = new Map<string, string>()\n const activeHostGenerations = new Map<string, string | undefined>()\n const activationKeys = new Map<string, { readonly definition: MobileClientDefinition; readonly generation?: string }>()\n const manifestExtensionIds = new Set<string>()\n const managedDefinitionIds = new Set<string>()\n let manifestEtag = ''\n let disposed = false\n let expectedDefinitionId: string | undefined\n const SURFACE_HOST_STYLES: Readonly<Record<string, string>> = {\n 'sidebar-action': 'position:fixed;z-index:1100;top:calc(env(safe-area-inset-top) + 8px);left:8px;display:flex;flex-direction:column;gap:6px;pointer-events:none',\n 'header-action': 'position:fixed;z-index:1100;top:calc(env(safe-area-inset-top) + 8px);right:8px;display:flex;flex-direction:column;gap:6px;pointer-events:none',\n 'composer-dock': 'position:fixed;z-index:1100;bottom:calc(env(safe-area-inset-bottom) + 8px);left:50%;transform:translateX(-50%);display:flex;flex-direction:column;gap:6px;pointer-events:none',\n 'settings-section': 'position:fixed;z-index:1100;inset:auto 8px calc(env(safe-area-inset-bottom) + 72px) 8px;max-height:40vh;overflow:auto;pointer-events:none',\n }\n const surfaceHost = (placement: string): HTMLElement | undefined => {\n const existing = document.querySelector<HTMLElement>(`[data-dsh-mobile-surface-host=\"${placement}\"]`)\n if (existing !== null) return existing\n const style = SURFACE_HOST_STYLES[placement]\n if (style === undefined) return undefined\n const host = element('div'); host.dataset.dshMobileSurfaceHost = placement; host.style.cssText = style\n document.body.append(host); return host\n }\n const shellLayer = (): HTMLElement => {\n const existing = document.querySelector<HTMLElement>('[data-dsh-mobile-extension-layer]')\n if (existing !== null) return existing\n const layer = element('div'); layer.dataset.dshMobileExtensionLayer = 'true'; layer.style.cssText = 'position:fixed;inset:0;z-index:1200;pointer-events:none;overflow:hidden'\n document.body.append(layer); return layer\n }\n const toast = (message: string): void => {\n const node = element('div'); node.textContent = message; node.style.cssText = 'position:absolute;top:16px;left:50%;transform:translateX(-50%);padding:9px 14px;border-radius:999px;background:#1f2937;color:white;font:14px system-ui;pointer-events:auto;box-shadow:0 8px 24px #0003'\n shellLayer().append(node); window.setTimeout(() => node.remove(), 2600)\n }\n const materializeNativeFile = (value: unknown): unknown => {\n if (typeof value !== 'object' || value === null || !('base64' in value) || !('name' in value)) return value\n const candidate = value as { base64?: unknown; name?: unknown; type?: unknown }\n if (typeof candidate.base64 !== 'string' || typeof candidate.name !== 'string') return value\n try {\n const encoded = atob(candidate.base64)\n const bytes = Uint8Array.from(encoded, character => character.charCodeAt(0))\n return new File([bytes], candidate.name, { type: typeof candidate.type === 'string' ? candidate.type : 'application/octet-stream' })\n } catch {\n return value\n }\n }\n const invokeNative = async (action: string, input: unknown, signal: AbortSignal): Promise<unknown> => {\n const abortReason = (): unknown => signal.reason ?? new DOMException('mobile extension disposed', 'AbortError')\n if (signal.aborted) throw abortReason()\n const bridge = window.__DSH_MOBILE_NATIVE__\n if (bridge !== undefined) {\n return new Promise<unknown>((resolve, reject) => {\n let settled = false\n const finish = (callback: () => void): void => { if (settled) return; settled = true; signal.removeEventListener('abort', onAbort); callback() }\n const onAbort = (): void => { finish(() => { reject(abortReason()) }) }\n signal.addEventListener('abort', onAbort, { once: true })\n void Promise.resolve().then(() => bridge.invoke(action, input)).then(\n value => { finish(() => { resolve(materializeNativeFile(value)) }) },\n error => { finish(() => { reject(error) }) },\n )\n })\n }\n if (action === 'share' && typeof navigator.share === 'function') { await navigator.share((input ?? {}) as ShareData); return { ok: true } }\n if (action === 'clipboard.read' && navigator.clipboard !== undefined) return { text: await navigator.clipboard.readText() }\n if (action === 'clipboard.write' && navigator.clipboard !== undefined) { await navigator.clipboard.writeText(typeof input === 'object' && input !== null && 'text' in input ? String((input as { text: unknown }).text) : ''); return { ok: true } }\n if (action === 'files.pick' || action === 'camera.capture') {\n const inputElement = element('input')\n inputElement.type = 'file'\n inputElement.accept = action === 'camera.capture' ? 'image/*' : '*/*'\n if (action === 'camera.capture') inputElement.capture = 'environment'\n inputElement.hidden = true\n return new Promise<File | undefined>((resolve, reject) => {\n let settled = false\n let cleaned = false\n let cleanupTimer = 0\n let watchdogTimer = 0\n const cleanup = (): void => {\n if (cleaned) return\n cleaned = true\n if (cleanupTimer !== 0) window.clearTimeout(cleanupTimer)\n if (watchdogTimer !== 0) window.clearTimeout(watchdogTimer)\n window.removeEventListener('focus', scheduleCancel)\n document.removeEventListener('visibilitychange', onVisibilityChange)\n signal.removeEventListener('abort', onAbort)\n inputElement.removeEventListener('change', onChange)\n inputElement.removeEventListener('cancel', onCancel)\n inputElement.remove()\n }\n const finish = (callback: () => void): void => { if (settled) return; settled = true; cleanup(); callback() }\n const onChange = (): void => { const file = inputElement.files?.[0]; finish(() => { resolve(file) }) }\n const onCancel = (): void => { finish(() => { resolve(undefined) }) }\n const onAbort = (): void => { finish(() => { reject(abortReason()) }) }\n const scheduleCancel = (): void => { if (!settled && cleanupTimer === 0) cleanupTimer = window.setTimeout(onCancel, 1000) }\n const onVisibilityChange = (): void => { if (document.visibilityState === 'visible') scheduleCancel() }\n inputElement.addEventListener('change', onChange, { once: true })\n inputElement.addEventListener('cancel', onCancel, { once: true })\n window.addEventListener('focus', scheduleCancel)\n document.addEventListener('visibilitychange', onVisibilityChange)\n signal.addEventListener('abort', onAbort, { once: true })\n watchdogTimer = window.setTimeout(onCancel, 300_000)\n try {\n document.body.append(inputElement)\n inputElement.click()\n } catch (error) {\n finish(() => { reject(error) })\n }\n })\n }\n throw new Error('native capability is unavailable')\n }\n const makeApi = (id: string, hostGeneration: string | undefined, controller: AbortController, surfaces: Map<string, ExtensionSurfaceEntry>, surfaceIds: Set<string>): MobileClientApi => {\n const ensureCurrent = (): void => { if (controller.signal.aborted) throw controller.signal.reason }\n const requestSignal = (signal?: AbortSignal | null): CombinedClientSignal => signal === undefined || signal === null\n ? { signal: controller.signal, cleanup: () => undefined }\n : combineClientSignalLifetime(controller.signal, signal)\n const mountSurface = (surface: MobileSurface): (() => void) => {\n ensureCurrent()\n if (!/^[a-z][a-z0-9-]{0,63}$/u.test(surface.id) || surface.label.length > 120) throw new Error('invalid mobile surface')\n return registerUniqueDisposable(surfaces, surfaceIds, surface.id, () => {\n const container = element('section'); container.dataset.dshMobileSurface = surface.id; container.hidden = surface.placement === 'page' || surface.placement === 'overlay'; container.style.cssText = surface.placement === 'page' || surface.placement === 'overlay' ? 'position:absolute;inset:0;overflow:auto;background:var(--dsw-alias-bg-layer-1,#fff);padding:16px;pointer-events:auto' : 'pointer-events:auto'\n const host = (): HTMLElement => surface.placement === 'page' || surface.placement === 'overlay' ? shellLayer() : surfaceHost(surface.placement) ?? shellLayer()\n const mounted = surface.mount(container)\n const dispose = (): void => { try { if (typeof mounted === 'function') mounted() } finally { container.remove() } }\n return { dispose, container, host }\n })\n }\n return {\n host: {\n invoke: (action: string, input: unknown) => {\n ensureCurrent()\n return mobileRequest(`/mobile-access/extensions/${encodeURIComponent(id)}/actions/${encodeURIComponent(action)}`, { method: 'POST', headers: extensionGenerationHeaders(hostGeneration), body: JSON.stringify(input ?? {}), signal: controller.signal }).then(async response => { const value = await response.json() as unknown; if (!response.ok) throw new Error(typeof value === 'object' && value !== null && 'error' in value ? String((value as { error: unknown }).error) : `HTTP ${String(response.status)}`); return value })\n },\n fetch: (path: string, init?: RequestInit) => {\n ensureCurrent()\n const target = extensionRouteUrl(id, path, location.href)\n const headers = extensionGenerationHeaders(hostGeneration, init?.headers)\n const lifetime = requestSignal(init?.signal)\n return mobileRequest(target.href, { ...init, headers, signal: lifetime.signal }).then(\n response => bindClientResponseLifetime(response, lifetime.cleanup),\n error => { lifetime.cleanup(); throw error },\n )\n },\n assetUrl: path => { ensureCurrent(); return extensionAssetUrl(id, hostGeneration, path, location.href).href },\n },\n ui: {\n registerSurface: mountSurface,\n open: surfaceId => { ensureCurrent(); const entry = surfaces.get(surfaceId); if (entry !== undefined) entry.container.hidden = false },\n close: surfaceId => { ensureCurrent(); const entry = surfaces.get(surfaceId); if (entry !== undefined) entry.container.hidden = true },\n toast: message => { ensureCurrent(); toast(message) },\n },\n native: {\n capabilities: async () => { ensureCurrent(); const bridge = window.__DSH_MOBILE_NATIVE__; return bridge === undefined ? ['files.pick', 'camera.capture', 'share', 'clipboard.read', 'clipboard.write'] : bridge.capabilities() },\n invoke: (action, input) => invokeNative(action, input, controller.signal),\n },\n signal: controller.signal, document, window,\n }\n }\n const activateDefinition = (definition: MobileClientDefinition, cycleSignal?: AbortSignal, commitGeneration?: () => void, hostGeneration?: string): Promise<boolean> => {\n const previousKey = activationKeys.get(definition.id)\n const key = previousKey?.definition === definition && previousKey.generation === hostGeneration\n ? previousKey\n : { definition, ...(hostGeneration === undefined ? {} : { generation: hostGeneration }) }\n activationKeys.set(definition.id, key)\n return activations.activate(\n definition.id,\n key,\n cycleSignal,\n controller => {\n const surfaces = new Map<string, ExtensionSurfaceEntry>()\n const surfaceIds = new Set<string>()\n let pendingDisposed = false\n const disposePending = (): void => {\n if (pendingDisposed) return\n pendingDisposed = true\n for (const surface of surfaces.values()) {\n try { surface.dispose() } catch { /* Dispose every staged surface independently. */ }\n }\n surfaces.clear()\n surfaceIds.clear()\n }\n const result = Promise.resolve().then(() => definition.activate(makeApi(definition.id, hostGeneration, controller, surfaces, surfaceIds))).then(cleanup => ({\n controller,\n surfaces,\n ...(typeof cleanup === 'function' ? { cleanup } : {}),\n }))\n return {\n result,\n cancel: disposePending,\n commit: value => {\n if (definitions.get(definition.id) !== definition || controller.signal.aborted) throw new Error('stale mobile extension activation')\n for (const surface of value.surfaces.values()) surface.host().append(surface.container)\n activeHostGenerations.set(definition.id, hostGeneration)\n commitGeneration?.()\n },\n dispose: value => {\n controller.abort(new DOMException('mobile extension disposed', 'AbortError'))\n try { value.cleanup?.() } finally { disposePending() }\n },\n }\n },\n )\n }\n const define = (definition: MobileClientDefinition): void => {\n if (disposed || definition.apiVersion !== 1 || !/^[a-z][a-z0-9-]{0,63}$/u.test(definition.id) || typeof definition.activate !== 'function') return\n if (expectedDefinitionId !== undefined && definition.id !== expectedDefinitionId) return\n definitions.set(definition.id, definition)\n if (started && expectedDefinitionId === undefined) void activateDefinition(definition)\n }\n let started = false\n window.dshMobile = Object.freeze({ register: mount => { legacyMount = mount }, define })\n for (const definition of queuedDefinitions.splice(0)) define(definition)\n let legacyJsEtag = ''\n let legacyJsModified = ''\n const refreshLegacy = async (signal: AbortSignal): Promise<boolean> => {\n const previousMount = legacyMount\n let pendingRoot: HTMLElement | undefined\n try {\n const headers: Record<string, string> = {}\n if (legacyJsEtag !== '') headers['if-none-match'] = legacyJsEtag\n if (legacyJsModified !== '') headers['if-modified-since'] = legacyJsModified\n const response = await fetch('/mobile-access/custom.js', { credentials: 'same-origin', cache: 'no-store', headers, signal })\n if (response.status === 304) return true\n if (!response.ok) return false\n const nextEtag = response.headers.get('etag') ?? ''\n const nextModified = response.headers.get('last-modified') ?? ''\n const next = await response.text()\n if (refreshAborted(signal)) return false\n if (next === legacySource) { legacyJsEtag = nextEtag; legacyJsModified = nextModified; return true }\n legacyMount = undefined\n const script = element('script'); script.textContent = `${next}\\n//# sourceURL=dsh-mobile-custom.js`; document.head.append(script); script.remove()\n if (refreshAborted(signal)) { legacyMount = previousMount; return false }\n const mount = legacyMount as MobileExtensionMount | undefined\n if (mount === undefined) {\n legacyDispose?.(); legacyDispose = undefined\n legacyRoot?.remove(); legacyRoot = undefined\n legacySource = next; legacyJsEtag = nextEtag; legacyJsModified = nextModified\n return true\n }\n const nextRoot = element('div'); pendingRoot = nextRoot; nextRoot.dataset.dshMobileExtension = 'true'; document.body.append(nextRoot)\n const nextDispose = mount({ document, request: mobileRequest, root: nextRoot, window })\n if (refreshAborted(signal)) { if (typeof nextDispose === 'function') nextDispose(); pendingRoot.remove(); pendingRoot = undefined; legacyMount = previousMount; return false }\n legacyDispose?.(); legacyRoot?.remove(); legacyRoot = nextRoot; pendingRoot = undefined; legacyDispose = typeof nextDispose === 'function' ? nextDispose : undefined; legacySource = next\n legacyJsEtag = nextEtag; legacyJsModified = nextModified\n return true\n } catch { pendingRoot?.remove(); legacyMount = previousMount; return false }\n }\n let legacyScriptRevision = ''\n let legacyStyleRevision = ''\n const disposeManifestExtension = (id: string): void => {\n activations.remove(id)\n styleNodes.get(id)?.remove(); styleNodes.delete(id); styleEtags.delete(id); scriptDigests.delete(id); activeHostGenerations.delete(id); activationKeys.delete(id)\n if (managedDefinitionIds.delete(id)) definitions.delete(id)\n }\n const managedManifestIdSources = (): readonly Iterable<string>[] => [styleNodes.keys(), styleEtags.keys(), scriptDigests.keys(), managedDefinitionIds]\n const clearManifestExtensions = (): void => {\n publishAuthoritativeExtensionIds(manifestExtensionIds, new Set(), managedManifestIdSources(), disposeManifestExtension)\n manifestEtag = ''\n }\n const refreshExtensions = async (signal: AbortSignal): Promise<boolean> => {\n try {\n const headers: Record<string, string> = {}\n if (manifestEtag !== '') headers['if-none-match'] = manifestEtag\n const response = await fetch('/mobile-access/extensions/manifest', { credentials: 'same-origin', cache: 'no-store', headers, signal })\n if (response.status === 404) {\n legacyScriptRevision = ''\n legacyStyleRevision = ''\n return handleMissingExtensionManifest(\n clearManifestExtensions,\n () => Promise.all([refreshLegacy(signal), refreshCssLegacy(legacyStyle, signal, legacyCssState)]),\n signal,\n )\n }\n if (response.status === 304) return true\n if (!response.ok) return false\n const nextManifestEtag = response.headers.get('etag') ?? ''\n const payload = parseMobileExtensionManifest(await response.json())\n if (refreshAborted(signal) || payload === undefined) return false\n const entries = payload.extensions\n const seen = new Set(entries.map(entry => entry.id))\n const scriptRevision = payload.legacy.scriptRevision\n const styleRevision = payload.legacy.styleRevision\n let refreshComplete = true\n if (scriptRevision === '' || scriptRevision !== legacyScriptRevision) {\n if (await refreshLegacy(signal)) legacyScriptRevision = scriptRevision\n else refreshComplete = false\n }\n if (styleRevision === '' || styleRevision !== legacyStyleRevision) {\n if (await refreshCssLegacy(legacyStyle, signal, legacyCssState)) legacyStyleRevision = styleRevision\n else refreshComplete = false\n }\n const commitStyle = (id: string, change: 'retain' | 'remove' | 'replace', css?: string, etag?: string): void => {\n if (change === 'retain') return\n const oldStyle = styleNodes.get(id)\n if (change === 'remove') {\n oldStyle?.remove()\n styleNodes.delete(id)\n styleEtags.delete(id)\n return\n }\n if (oldStyle?.textContent !== css) {\n const node = element('style'); node.dataset.dshMobileExtensionStyle = id; node.textContent = css ?? ''; document.head.append(node); styleNodes.set(id, node); oldStyle?.remove()\n }\n if (etag !== undefined && etag !== '') styleEtags.set(id, etag)\n }\n for (const entry of entries) {\n const hadActiveGeneration = activations.hasActive(entry.id)\n const previousHostGeneration = activeHostGenerations.get(entry.id)\n let previousDefinition: MobileClientDefinition | undefined\n let evaluatedDefinition = false\n try {\n let styleChange: 'retain' | 'remove' | 'replace' = entry.styleUrl === undefined ? 'remove' : 'retain'\n let pendingCss: string | undefined\n let pendingStyleEtag: string | undefined\n const cssUrl = typeof entry.styleUrl === 'string' ? entry.styleUrl : undefined\n if (cssUrl !== undefined) {\n const cssHeaders: Record<string, string> = {}\n const storedEtag = styleEtags.get(entry.id)\n if (storedEtag !== undefined) cssHeaders['if-none-match'] = storedEtag\n const cssResponse = await fetch(cssUrl, { credentials: 'same-origin', cache: 'no-store', headers: cssHeaders, signal })\n if (cssResponse.status !== 304) {\n if (!cssResponse.ok) throw new Error('mobile extension style failed to load')\n pendingStyleEtag = cssResponse.headers.get('etag') ?? undefined\n pendingCss = await cssResponse.text()\n styleChange = 'replace'\n if (refreshAborted(signal)) return false\n }\n }\n\n const scriptUrl = typeof entry.scriptUrl === 'string' ? entry.scriptUrl : undefined\n if (scriptUrl === undefined) {\n if (refreshAborted(signal)) return false\n commitStyle(entry.id, styleChange, pendingCss, pendingStyleEtag)\n activations.remove(entry.id)\n activeHostGenerations.delete(entry.id)\n scriptDigests.delete(entry.id)\n if (managedDefinitionIds.delete(entry.id)) definitions.delete(entry.id)\n } else {\n const scriptHeaders: Record<string, string> = {}\n const storedDigest = scriptDigests.get(entry.id)\n if (storedDigest !== undefined) scriptHeaders['if-none-match'] = storedDigest\n const scriptResponse = await fetch(scriptUrl, { credentials: 'same-origin', cache: 'no-store', headers: scriptHeaders, signal })\n let nextDigest: string | undefined\n if (scriptResponse.status !== 304) {\n if (!scriptResponse.ok) throw new Error('mobile extension script failed to load')\n const source = await scriptResponse.text()\n if (refreshAborted(signal)) return false\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(source))\n if (refreshAborted(signal)) return false\n const key = [...new Uint8Array(digest)].map(value => value.toString(16).padStart(2, '0')).join('')\n if (scriptDigests.get(entry.id) !== key) {\n previousDefinition = definitions.get(entry.id)\n try {\n expectedDefinitionId = entry.id\n try {\n const script = element('script'); script.textContent = `${source}\\n//# sourceURL=dsh-mobile-extension-${entry.id}.js`; document.head.append(script); script.remove()\n } finally { expectedDefinitionId = undefined }\n const nextDefinition = definitions.get(entry.id)\n if (nextDefinition === undefined || nextDefinition === previousDefinition) throw new Error('mobile extension did not define its manifest id')\n evaluatedDefinition = true\n nextDigest = key\n } catch (error) {\n if (previousDefinition === undefined) definitions.delete(entry.id)\n else definitions.set(entry.id, previousDefinition)\n throw error\n }\n }\n }\n const definition = definitions.get(entry.id)\n const commitGeneration = (): void => { commitStyle(entry.id, styleChange, pendingCss, pendingStyleEtag) }\n if (definition === undefined) throw new Error('mobile extension definition is unavailable')\n if (evaluatedDefinition || !activations.hasActive(entry.id) || activeHostGenerations.get(entry.id) !== entry.generation) {\n if (!await activateDefinition(definition, signal, commitGeneration, entry.generation)) throw new Error('mobile extension activation failed')\n } else {\n if (refreshAborted(signal)) return false\n commitGeneration()\n }\n managedDefinitionIds.add(entry.id)\n if (nextDigest !== undefined) scriptDigests.set(entry.id, nextDigest)\n }\n } catch {\n if (evaluatedDefinition) {\n if (previousDefinition === undefined) definitions.delete(entry.id)\n else definitions.set(entry.id, previousDefinition)\n }\n failClosedExtensionGenerationReplacement(\n hadActiveGeneration,\n previousHostGeneration,\n entry.generation,\n () => { disposeManifestExtension(entry.id) },\n )\n refreshComplete = false\n }\n }\n if (refreshAborted(signal)) return false\n if (refreshComplete) {\n publishAuthoritativeExtensionIds(manifestExtensionIds, seen, managedManifestIdSources(), disposeManifestExtension)\n manifestEtag = nextManifestEtag\n } else manifestEtag = ''\n return refreshComplete\n } catch { return false }\n }\n started = true\n for (const definition of definitions.values()) void activateDefinition(definition)\n const stopRefresh = startLifecycleRefreshScheduler(async signal => {\n await refreshExtensions(signal)\n })\n const stopEvents = startExtensionChangeStream(() => { stopRefresh.refresh() })\n return () => { disposed = true; stopEvents(); stopRefresh(); started = false; legacyDispose?.(); legacyDispose = undefined; legacyRoot?.remove(); legacyRoot = undefined; legacyStyle.remove(); activations.dispose(); for (const node of styleNodes.values()) node.remove(); styleNodes.clear(); const layer = document.querySelector('[data-dsh-mobile-extension-layer]'); layer?.remove(); for (const host of document.querySelectorAll('[data-dsh-mobile-surface-host]')) host.remove(); if (previous === undefined) delete window.dshMobile; else window.dshMobile = previous }\n}\n\ninterface LegacyCssState { etag: string; modified: string }\nasync function refreshCssLegacy(style: HTMLStyleElement, signal: AbortSignal, state: LegacyCssState): Promise<boolean> {\n try {\n const headers: Record<string, string> = {}\n if (state.etag !== '') headers['if-none-match'] = state.etag\n if (state.modified !== '') headers['if-modified-since'] = state.modified\n let response = await fetch('/mobile-access/custom.css', { credentials: 'same-origin', cache: 'no-store', headers, signal })\n if (response.status === 304 && style.textContent === '') {\n state.etag = ''\n state.modified = ''\n response = await fetch('/mobile-access/custom.css', { credentials: 'same-origin', cache: 'no-store', signal })\n }\n if (response.status === 304) return true\n if (response.ok) {\n const nextEtag = response.headers.get('etag') ?? ''\n const nextModified = response.headers.get('last-modified') ?? ''\n const css = await response.text()\n if (refreshAborted(signal)) return false\n style.textContent = css\n state.etag = nextEtag\n state.modified = nextModified\n return true\n }\n return false\n } catch { return false }\n}\n\nconst CONTROL_STYLES = `\n.dsh-mobile-control{position:fixed;z-index:1000;left:16px;bottom:112px;font:14px/1.45 system-ui;color:var(--dsw-alias-label-primary,#16181d)}\n.dsh-mobile-control__panel{box-sizing:border-box;width:min(380px,calc(100vw - 32px));max-height:calc(100vh - 140px);overflow-y:auto;padding:16px;border:1px solid var(--dsw-alias-border-subtle,#e1e5eb);border-radius:18px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:0 18px 50px rgb(15 23 42 / 18%)}\n.dsh-mobile-control__header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}.dsh-mobile-control__panel h2{margin:0;font-size:17px;line-height:24px}.dsh-mobile-control__header-actions{display:flex;align-items:center;gap:2px}.dsh-mobile-control__diagnostic-entry,.dsh-mobile-control__close{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:44px;padding:0;border:0;border-radius:10px;background:transparent;color:inherit;cursor:pointer}.dsh-mobile-control__diagnostic-entry{padding:0 9px;color:#2563eb;font:650 12px/1 system-ui}.dsh-mobile-control__close{font-size:24px;line-height:1}.dsh-mobile-control__diagnostic-entry:hover,.dsh-mobile-control__close:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f3f6)}\n.dsh-mobile-control__app-download{display:flex;align-items:center;justify-content:space-between;box-sizing:border-box;min-height:38px;margin:0 0 10px;padding:8px 11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f7f8fa);color:var(--dsw-alias-label-primary,#16181d);font:600 12px/1.3 system-ui;text-decoration:none}.dsh-mobile-control__app-download[hidden]{display:none}.dsh-mobile-control__app-download::after{color:#2563eb;font-size:14px;content:\"↗\"}.dsh-mobile-control__app-download:hover{border-color:#9fb9e8;background:#f5f8ff;color:#1d4ed8}\n.dsh-mobile-control__switcher{display:grid;grid-template-columns:repeat(2,1fr);gap:4px;margin:0 0 14px;padding:4px;border-radius:12px;background:var(--dsw-alias-bg-layer-1,#f3f5f8)}.dsh-mobile-control__switcher[hidden]{display:none}.dsh-mobile-control__tab{min-height:36px;border:0;border-radius:9px;background:transparent;color:var(--dsw-alias-label-secondary,#606873);font:600 13px/1 system-ui;cursor:pointer}.dsh-mobile-control__tab.is-active{background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);box-shadow:0 1px 3px rgb(15 23 42 / 10%)}.dsh-mobile-control__view[hidden]{display:none}.dsh-mobile-control__intro{margin:0 0 12px;color:var(--dsw-alias-label-secondary,#606873);font-size:12px;line-height:1.55}.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions button[hidden]{display:none}\n.dsh-mobile-control__provider-section{position:relative;margin:0 0 12px}.dsh-mobile-control__section-title{margin:0 0 8px;color:var(--dsw-alias-label-primary,#16181d);font:650 13px/1.4 system-ui}.dsh-mobile-control__provider-section>.dsh-mobile-control__section-title{padding-right:42px}.dsh-mobile-control__provider-choices{display:grid;gap:8px}.dsh-mobile-control__provider{display:flex;flex-direction:column;gap:5px;min-height:68px;padding:11px 12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:#fff;color:inherit;text-align:left;cursor:pointer;transition:border-color 160ms ease,background-color 160ms ease,box-shadow 160ms ease}.dsh-mobile-control__provider:hover{border-color:#9fb9e8;background:#f8fbff}.dsh-mobile-control__provider.is-selected{border-color:#2563eb;background:#f5f8ff;box-shadow:0 0 0 1px #2563eb inset}.dsh-mobile-control__provider:disabled{cursor:wait;opacity:.62}.dsh-mobile-control__provider-top{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsh-mobile-control__provider-top strong{font-size:13px}.dsh-mobile-control__provider-badge{flex:none;padding:3px 7px;border-radius:999px;background:#e8f0ff;color:#1d4ed8;font:650 10px/1.2 system-ui}.dsh-mobile-control__provider-badge.is-cpolar{background:#eaf8f2;color:#087454}.dsh-mobile-control__provider-description{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.45}.dsh-mobile-control__provider-info{position:absolute;z-index:5;top:-13px;right:-8px}.dsh-mobile-control__provider-info-button{display:flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:transparent;color:#475569;cursor:pointer;touch-action:manipulation}.dsh-mobile-control__provider-info-button:hover{background:#f1f5f9;color:#1d4ed8}.dsh-mobile-control__provider-info-glyph{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:18px;height:18px;border:1.5px solid currentColor;border-radius:50%;font:700 12px/1 system-ui}.dsh-mobile-control__provider-info-popover{position:absolute;z-index:6;top:38px;right:4px;box-sizing:border-box;width:min(292px,calc(100vw - 72px));padding:10px 12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:0 10px 28px rgb(15 23 42 / 16%)}.dsh-mobile-control__provider-info-popover[hidden]{display:none}.dsh-mobile-control__provider-info-popover strong,.dsh-mobile-control__provider-info-popover span{display:block}.dsh-mobile-control__provider-info-popover strong{margin-bottom:3px;font-size:12px}.dsh-mobile-control__provider-info-popover span{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.55}\n.dsh-mobile-control__cpolar-setup{margin:0 0 12px;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:#fff}.dsh-mobile-control__cpolar-setup[hidden],.dsh-mobile-control__cpolar-account[hidden],.dsh-mobile-control__details[hidden],.dsh-mobile-control__view.is-remote .dsh-mobile-control__actions[hidden],.dsh-mobile-control__danger[hidden]{display:none}.dsh-mobile-control__component-status,.dsh-mobile-control__component-note{margin:0 0 10px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.55}.dsh-mobile-control__cpolar-setup>.dsh-mobile-control__primary{width:100%;min-height:44px;padding:9px 12px;border-radius:10px;font:600 12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__cpolar-account{margin-top:10px}.dsh-mobile-control__link-row{display:flex;flex-wrap:wrap;gap:6px 12px;margin:0 0 10px}.dsh-mobile-control__text-link{color:#2563eb;font-size:11px;text-decoration:none}.dsh-mobile-control__text-link:hover{text-decoration:underline}.dsh-mobile-control__token-label{display:flex;flex-direction:column;gap:5px;margin:0 0 8px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px}.dsh-mobile-control__token{box-sizing:border-box;width:100%;min-height:44px;padding:9px 10px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:10px;background:#fff;color:inherit;font:16px/1.4 system-ui}.dsh-mobile-control__cpolar-connect{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:100%;min-height:44px;padding:10px 14px;border-radius:12px;font:650 13px/1.2 system-ui;cursor:pointer;transition:background-color 160ms ease,border-color 160ms ease,opacity 160ms ease}.dsh-mobile-control__cpolar-connect:hover:not(:disabled){border-color:#1d4ed8;background:#1d4ed8}.dsh-mobile-control__cpolar-connect:active:not(:disabled){border-color:#1e40af;background:#1e40af}.dsh-mobile-control__cpolar-connect:disabled{cursor:wait;opacity:.55}.dsh-mobile-control__details{margin:10px 0 0;border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb);padding-top:9px}.dsh-mobile-control__details>summary{min-height:30px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:30px;cursor:pointer}.dsh-mobile-control__details-body{display:flex;flex-wrap:wrap;align-items:center;gap:7px 12px;padding:4px 0}.dsh-mobile-control__details-body p{flex:1 0 100%;margin:0;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__storage{display:block;flex:1 0 100%;max-width:100%;overflow:hidden;padding:7px 8px;border-radius:8px;background:#f3f5f8;color:#475569;font:10px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__danger{flex:1 0 100%;min-height:38px;margin-top:3px;padding:7px 10px;border:1px solid #dc2626;border-radius:9px;background:transparent;color:#b91c1c;font:12px/1.3 system-ui;cursor:pointer}\n.dsh-mobile-control__access{display:flex;align-items:baseline;gap:6px;min-width:0;margin:0 0 12px}.dsh-mobile-control__access[hidden]{display:none}.dsh-mobile-control__access-label{flex:none;color:var(--dsw-alias-label-secondary,#606873);white-space:nowrap}.dsh-mobile-control__access-label::after{content:\":\"}.dsh-mobile-control__access-link{min-width:0;overflow:hidden;color:#2563eb;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__access-link:hover{text-decoration:underline}.dsh-mobile-control__qr{display:flex;justify-content:center;margin:0 0 12px}.dsh-mobile-control__qr[hidden]{display:none}.dsh-mobile-control__qr img{border-radius:12px;background:#fff;padding:8px}\n.dsh-mobile-control__status{margin:0 0 14px;overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary,#606873)}.dsh-mobile-control__status::before{display:inline-block;width:8px;height:8px;margin-right:7px;border-radius:50%;background:#98a1ad;content:\"\"}.dsh-mobile-control__status.is-running::before{background:#16a36a}.dsh-mobile-control__status.is-key{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;word-break:break-all}\n.dsh-mobile-control__guide{margin:0 0 14px;padding:12px;border:1px solid #bfdbfe;border-radius:12px;background:#eff6ff}.dsh-mobile-control__guide[hidden]{display:none}.dsh-mobile-control__guide-title{margin:0;color:#172554;font:650 13px/1.45 system-ui}.dsh-mobile-control__guide-summary,.dsh-mobile-control__guide-note{margin:4px 0 0;color:#475569;font-size:12px;line-height:1.5}.dsh-mobile-control__guide-steps{margin:8px 0 0;padding-left:20px;color:#1e293b;font-size:12px;line-height:1.6}.dsh-mobile-control__guide-note{color:#64748b}.dsh-mobile-control__guide-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px}.dsh-mobile-control__guide-actions button{min-width:0;min-height:44px;padding:8px;border-radius:10px;font:12px/1.25 system-ui;cursor:pointer}.dsh-mobile-control__guide-actions button:disabled{cursor:not-allowed;opacity:.45}\n.dsh-mobile-control__extensions{margin:0 0 12px;color:var(--dsw-alias-label-secondary,#606873);font-size:12px}\n.dsh-mobile-control__view.is-diagnostics{--dsh-diagnostic-ok:#087454;--dsh-diagnostic-warning:#a35b00;--dsh-diagnostic-error:#c62828;--dsh-diagnostic-info:#526071}.dsh-mobile-control__diagnostic-summary{box-sizing:border-box;margin:0;padding:13px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:16px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__diagnostic-summary-main{display:grid;grid-template-columns:36px minmax(0,1fr);align-items:center;gap:11px}.dsh-mobile-control__diagnostic-summary-icon{position:relative;display:block;width:36px;height:36px;border-radius:50%;background:#e8edf3;color:var(--dsh-diagnostic-info)}.dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-summary-icon::after{position:absolute;content:\"\"}.dsh-mobile-control__diagnostic-summary-body{display:flex;min-width:0;flex-direction:column;gap:2px}.dsh-mobile-control__diagnostic-summary-body strong{font-size:13px;line-height:1.35}.dsh-mobile-control__diagnostic-summary-body span{color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__diagnostic-summary-meta{display:block;margin-top:11px;padding-top:9px;border-top:1px solid var(--dsw-alias-border-subtle,#dbe1e8);color:var(--dsw-alias-label-secondary,#606873);font-size:10px;line-height:1.45}.dsh-mobile-control__diagnostic-summary.is-ok .dsh-mobile-control__diagnostic-summary-icon{background:#e6f7f0;color:var(--dsh-diagnostic-ok)}.dsh-mobile-control__diagnostic-summary.is-ok .dsh-mobile-control__diagnostic-summary-icon::before{top:10px;left:10px;width:13px;height:7px;border-bottom:2px solid currentColor;border-left:2px solid currentColor;transform:rotate(-45deg)}.dsh-mobile-control__diagnostic-summary.is-attention .dsh-mobile-control__diagnostic-summary-icon{background:#fff4dc;color:var(--dsh-diagnostic-warning)}.dsh-mobile-control__diagnostic-summary.is-error .dsh-mobile-control__diagnostic-summary-icon{background:#fdecec;color:var(--dsh-diagnostic-error)}.dsh-mobile-control__diagnostic-summary.is-attention .dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-summary.is-error .dsh-mobile-control__diagnostic-summary-icon::before{top:8px;left:17px;width:2px;height:13px;border-radius:2px;background:currentColor}.dsh-mobile-control__diagnostic-summary.is-attention .dsh-mobile-control__diagnostic-summary-icon::after,.dsh-mobile-control__diagnostic-summary.is-error .dsh-mobile-control__diagnostic-summary-icon::after{bottom:8px;left:17px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon{background:#e8f0ff;color:#2563eb}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon::before{inset:9px;border:2px solid rgb(37 99 235 / 24%);border-top-color:currentColor;border-radius:50%;animation:dsh-diagnostic-spin .8s linear infinite}\n.dsh-mobile-control__diagnostic-summary.is-idle .dsh-mobile-control__diagnostic-summary-icon::before{top:8px;left:17px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-summary.is-idle .dsh-mobile-control__diagnostic-summary-icon::after{top:13px;left:17px;width:2px;height:11px;border-radius:2px;background:currentColor}\n.dsh-mobile-control__diagnostic-toolbar{display:grid;grid-template-columns:1fr;gap:8px;margin-top:10px}.dsh-mobile-control__diagnostic-toolbar.has-report{grid-template-columns:1fr 1fr}.dsh-mobile-control__diagnostic-run,.dsh-mobile-control__diagnostic-copy{box-sizing:border-box;width:100%;min-height:44px;padding:9px 10px;border-radius:11px;font:650 12px/1.3 system-ui;cursor:pointer;touch-action:manipulation}.dsh-mobile-control__diagnostic-copy[hidden]{display:none}.dsh-mobile-control__diagnostic-run:disabled{cursor:wait;opacity:.58}.dsh-mobile-control__diagnostic-feedback{margin:8px 0 0;padding:8px 10px;border-radius:9px;background:#eff6ff;color:#1d4ed8;font-size:11px;line-height:1.45}.dsh-mobile-control__diagnostic-feedback[hidden]{display:none}\n.dsh-mobile-control__diagnostic-checks{display:grid;gap:12px;margin-top:12px;animation:dsh-diagnostic-reveal 160ms ease-out both}.dsh-mobile-control__diagnostic-checks[hidden]{display:none}.dsh-mobile-control__diagnostic-group{overflow:hidden;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__diagnostic-group-header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 11px;border-bottom:1px solid var(--dsw-alias-border-subtle,#e1e5eb);background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__diagnostic-group-header h3{margin:0;font:650 11px/1.4 system-ui}.dsh-mobile-control__diagnostic-group-header span{color:var(--dsw-alias-label-secondary,#606873);font-size:10px}.dsh-mobile-control__diagnostic-list{display:flex;flex-direction:column}.dsh-mobile-control__diagnostic-check{display:grid;grid-template-columns:26px minmax(0,1fr);gap:9px;padding:11px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__diagnostic-check + .dsh-mobile-control__diagnostic-check{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__diagnostic-marker{position:relative;width:26px;height:26px;border-radius:50%;background:#edf1f5;color:var(--dsh-diagnostic-info)}.dsh-mobile-control__diagnostic-marker::before,.dsh-mobile-control__diagnostic-marker::after{position:absolute;content:\"\"}.dsh-mobile-control__diagnostic-check.is-ok .dsh-mobile-control__diagnostic-marker{background:#e6f7f0;color:var(--dsh-diagnostic-ok)}.dsh-mobile-control__diagnostic-check.is-ok .dsh-mobile-control__diagnostic-marker::before{top:7px;left:7px;width:9px;height:5px;border-bottom:1.8px solid currentColor;border-left:1.8px solid currentColor;transform:rotate(-45deg)}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-marker{background:#fff4dc;color:var(--dsh-diagnostic-warning)}.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-marker{background:#fdecec;color:var(--dsh-diagnostic-error)}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-marker::before,.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-marker::before{top:6px;left:12px;width:2px;height:9px;border-radius:2px;background:currentColor}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-marker::after,.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-marker::after{bottom:6px;left:12px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-check.is-info .dsh-mobile-control__diagnostic-marker::before{top:6px;left:12px;width:2px;height:2px;border-radius:50%;background:currentColor}.dsh-mobile-control__diagnostic-check.is-info .dsh-mobile-control__diagnostic-marker::after{top:10px;left:12px;width:2px;height:9px;border-radius:2px;background:currentColor}.dsh-mobile-control__diagnostic-check-body{min-width:0}.dsh-mobile-control__diagnostic-check-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.dsh-mobile-control__diagnostic-check-header strong{min-width:0;font-size:12px;line-height:1.4}.dsh-mobile-control__diagnostic-badge{flex:none;padding:2px 6px;border-radius:999px;background:#edf1f5;color:var(--dsh-diagnostic-info);font:650 10px/1.3 system-ui}.dsh-mobile-control__diagnostic-check.is-ok .dsh-mobile-control__diagnostic-badge{background:#e6f7f0;color:var(--dsh-diagnostic-ok)}.dsh-mobile-control__diagnostic-check.is-warning .dsh-mobile-control__diagnostic-badge{background:#fff4dc;color:var(--dsh-diagnostic-warning)}.dsh-mobile-control__diagnostic-check.is-error .dsh-mobile-control__diagnostic-badge{background:#fdecec;color:var(--dsh-diagnostic-error)}.dsh-mobile-control__diagnostic-check p{margin:4px 0 0;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5;overflow-wrap:anywhere}.dsh-mobile-control__diagnostic-check .dsh-mobile-control__diagnostic-action{margin-top:7px;padding:7px 8px;border-radius:8px;background:var(--dsw-alias-bg-layer-1,#f8fafc);color:var(--dsw-alias-label-primary,#16181d)}.dsh-mobile-control__diagnostic-action span{display:inline-block;margin-right:6px;color:#2563eb;font-weight:700}.dsh-mobile-control__diagnostic-details{margin-top:12px}.dsh-mobile-control__diagnostic-details[hidden]{display:none}.dsh-mobile-control__diagnostic-details>summary{box-sizing:border-box;min-height:44px;line-height:44px}.dsh-mobile-control__diagnostic-report{box-sizing:border-box;max-height:220px;margin:4px 0 0;overflow:auto;padding:10px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:10px;background:var(--dsw-alias-bg-layer-1,#f3f5f8);color:var(--dsw-alias-label-secondary,#606873);font:10px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}\n.dsh-mobile-control__diagnostic-checks{transition:opacity 150ms ease}.dsh-mobile-control__diagnostic-checks.is-refreshing{opacity:.52}\n@keyframes dsh-diagnostic-spin{to{transform:rotate(360deg)}}@keyframes dsh-diagnostic-reveal{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n.dsh-mobile-control__actions{display:flex;flex-wrap:nowrap;gap:6px}.dsh-mobile-control__actions button{flex:1 1 0;min-width:0;min-height:40px;padding:8px 4px;border-radius:10px;font:12px/1.2 system-ui;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dsh-mobile-control__secondary{border:1px solid var(--dsw-alias-border-normal,#cfd5dd);background:transparent;color:inherit}.dsh-mobile-control__primary{border:1px solid #2563eb;background:#2563eb;color:#fff}.dsh-mobile-control__actions button:disabled{cursor:not-allowed;opacity:.45}\n.dsh-mobile-control button:focus-visible,.dsh-mobile-control a:focus-visible,.dsh-mobile-control input:focus-visible,.dsh-mobile-control summary:focus-visible{outline:3px solid rgb(37 99 235 / 28%);outline-offset:2px}\n.dsh-mobile-control__trigger{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:calc(100% + 8px);height:34px;margin:4px -4px;padding:6px 2px 6px 10px;border:0;border-radius:12px;background:transparent;color:var(--dsw-alias-label-primary,#16181d);font:14px/22px system-ui;cursor:pointer}.dsh-mobile-control__trigger:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f3f6)}.dsh-mobile-control__trigger.is-rail{width:36px;height:36px;margin:8px 0 10px;padding:0;justify-content:center;border-radius:50%}.dsh-mobile-control__trigger-icon{position:relative;box-sizing:border-box;flex:none;width:14px;height:19px;border:1.7px solid currentColor;border-radius:3px}.dsh-mobile-control__trigger-icon::after{position:absolute;right:4px;bottom:2px;width:4px;height:1.5px;border-radius:2px;background:currentColor;content:\"\"}.dsh-mobile-control__trigger-label{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}\n.dsh-mobile-control__manage-row{display:flex;justify-content:space-between;gap:8px;margin-top:10px}.dsh-mobile-control__manage{flex:1 1 0;min-width:0;min-height:34px;padding:6px 8px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:10px;background:transparent;color:inherit;font:12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__devices{margin-top:10px;border:1px solid var(--dsw-alias-border-subtle,#e1e5eb);border-radius:10px;padding:8px;max-height:220px;overflow-y:auto}.dsh-mobile-control__device-empty{color:var(--dsw-alias-label-secondary,#606873);font-size:12px;margin:0}.dsh-mobile-control__device{display:flex;align-items:center;gap:8px;padding:6px 2px}.dsh-mobile-control__device + .dsh-mobile-control__device{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__device-label{flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}.dsh-mobile-control__device-meta{flex:none;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;white-space:nowrap}.dsh-mobile-control__device-revoke{flex:none;min-height:28px;padding:4px 8px;border:1px solid #dc2626;border-radius:8px;background:transparent;color:#dc2626;font:12px/1.2 system-ui;cursor:pointer}\n@media (prefers-reduced-motion:reduce){.dsh-mobile-control__provider,.dsh-mobile-control__cpolar-connect{transition:none}.dsh-mobile-control__diagnostic-summary.is-running .dsh-mobile-control__diagnostic-summary-icon::before,.dsh-mobile-control__diagnostic-checks{animation:none}}\n`\n\n/** Mount the desktop control or mobile feature enhancements. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n if (window.__DSH_MOBILE_FRONTEND__ !== 'dedicated') return\n return trustAuthenticatedGatewayConnection(ctx.get('connection'))\n }, 'dsh-mobile: authenticated gateway client trust')\n\n ctx.effect(() => {\n const loopback = isLoopbackHost(location.hostname) && !new URLSearchParams(location.search).has('dsh-mobile-preview')\n const style = element('style'); style.dataset.plugin = 'dsh-mobile'; style.textContent = loopback\n ? CONTROL_STYLES\n : NATIVE_MOBILE_STYLES\n document.head.append(style)\n if (!loopback) {\n const removeCustom = installCustomAssets()\n const removeSurface = installDshLanguageBoundSurface(installNativeMobileSurface)\n return () => { removeCustom(); removeSurface(); style.remove() }\n }\n const removeControl = installDshLanguageBoundSurface(() => {\n const control = installControl()\n const triggerLocale = selectedMobileControlLocale()\n const t = controlTranslator(triggerLocale)\n const disposeSlot = ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register<{ wide: boolean }>({ name: 'sidebar.footer.action', id: 'dsh-mobile' }, ({ wide }) => createElement('button', {\n 'aria-expanded': false,\n 'aria-label': t('mobileAccess'),\n className: `dsh-mobile-control__trigger${wide ? '' : ' is-rail'}`,\n lang: triggerLocale,\n type: 'button',\n title: t('mobileAccess'),\n onClick: control.toggle,\n }, createElement('span', { 'aria-hidden': true, className: 'dsh-mobile-control__trigger-icon' }), wide ? createElement('span', { className: 'dsh-mobile-control__trigger-label' }, t('mobileAccess')) : undefined)))\n return () => { disposeSlot(); control.remove() }\n })\n return () => { removeControl(); style.remove() }\n }, 'dsh-mobile: stock mobile adaptation and local control')\n}\n\n/** Client services required by the mobile adaptation. */\nexport const inject: readonly string[] = ['slots']\n"],"mappings":"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"}
|