dsh-mobile 0.3.12 → 0.3.13
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 +6 -0
- package/README.en.md +9 -8
- package/README.md +9 -8
- package/lib/client.js +161 -21
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +50 -28
- package/lib/index.mjs +55 -5
- package/lib/index.mjs.map +1 -1
- package/lib/mobile-layout.js +6 -2
- package/lib/mobile-layout.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
Notable changes to DSH Mobile are recorded here. GitHub Releases remain the source for downloadable packages and complete generated commit notes.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
## 0.3.13 - 2026-09-08
|
|
7
|
+
|
|
8
|
+
- Third-party WebSocket approval is interception-driven and generic: whenever a plugin's WebSocket connection is blocked, the diagnostics view groups the rejected paths by directory with attempt counts and offers per-path or allow-all approval, behind the same local-admin trust as pairing, and both the sidebar entry and the in-panel diagnostics button carry a red badge until reviewed. Manual path entry is tucked under an “advanced” disclosure that most users never need to open (thanks @idoall for reporting #47). Badge changes are announced to screen readers and the disclosure has a visible focus ring.
|
|
9
|
+
- Panel polish: number the FRP VPS deployment group as step 2, restyle its deploy-changes list, align the path input with sibling fields, and auto-expand the VPS group until FRP is configured.
|
|
10
|
+
- Adapted to DeepSeek Harness 0.1.3-alpha.2: the front-end layout contract renamed the right details slot from `details` to `rightbar` and now hands the occupant resolved column geometry; the mobile layout registers and renders the slot under its new name with the real width, viewport, and eligibility values. The mobile page requires a host exposing the `rightbar` seat — 0.1.3-alpha.2 or later.
|
|
11
|
+
|
|
6
12
|
## 0.3.12 - 2026-09-07
|
|
7
13
|
|
|
8
14
|
- Document remote notification limits: browser permission is per origin, OS toasts stay on the computer, and server-side channels (e.g. dsh-messager webhooks) are the reliable push path to the phone (thanks @idoall for reporting #46). No code change since 0.3.11.
|
package/README.en.md
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
|
|
20
20
|
> DSH Mobile is a DeepSeek Harness community plugin; the native app supports Android only.
|
|
21
21
|
>
|
|
22
|
-
> **0.3.
|
|
22
|
+
> **0.3.13 update**: interception-driven, plugin-agnostic WebSocket approval — grouped blocked paths, dual red badges, manual entry under an advanced disclosure (#47) — plus panel polish (FRP step numbering, deploy-notes layout, approval button) and adaptation to DeepSeek Harness 0.1.3-alpha.2 (layout right-bar slot rename). [Details](CHANGELOG.md).
|
|
23
23
|
>
|
|
24
|
-
> **Upgrade reminder**:
|
|
24
|
+
> **Upgrade reminder**: check your desktop DeepSeek Harness version before updating the plugin — **0.1.3-alpha.2 or later** pairs with plugin **0.3.13**; on an earlier desktop (0.1.2 line or 0.1.3-alpha.1) stay on plugin **0.3.12**. Existing 0.3.3-0.3.12 apps and paired devices remain compatible without re-pairing. [Compatibility notes](#compatibility).
|
|
25
25
|
|
|
26
26
|
<p align="center">
|
|
27
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
28
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
29
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.
|
|
27
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.13/dsh-mobile-android-v0.3.13.apk"><img src="assets/brand/app-icon-rounded.svg" alt="DSH Mobile Android app icon" width="72" height="72"></a><br>
|
|
28
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.13/dsh-mobile-android-v0.3.13.apk"><strong>Download Android app 0.3.13</strong></a><br>
|
|
29
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.13">Release notes and checksums</a></sub>
|
|
30
30
|
</p>
|
|
31
31
|
|
|
32
32
|
DSH Mobile is a DeepSeek Harness plugin that lets a mobile browser or the Android app connect over a protected LAN or an optional Tailscale Funnel, cpolar, or self-hosted FRP remote path. Local and remote access keep the same sessions, Workspaces, messages, and tools while using separate switches and paired-device stores without modifying DeepSeek Harness source.
|
|
@@ -43,6 +43,7 @@ It also lets you customize the phone from a DSH conversation: `/mobile <what you
|
|
|
43
43
|
- **Image attachments**: use the top row of the composer plus menu to select an image or take a photo; PNG, JPEG, WebP, and GIF files up to 8 MiB are supported, plus full-resolution JPEG capture.
|
|
44
44
|
- **Auto-discovery, no re-pairing**: Wi-Fi, hotspot, or IP changes normally recover automatically.
|
|
45
45
|
- **One-click connection diagnostics**: check versions, gateway, network interface, firewall, and the remote path; stable reason codes are localized in the UI, and the copied report excludes credentials and complete addresses.
|
|
46
|
+
- **One-click approval for third-party plugin WebSockets**: the diagnostics view groups blocked plugin connections by directory (with attempt counts); allowing a path unblocks that exact path while everything unapproved stays blocked, and a red badge marks the sidebar entry until reviewed (#47). If a plugin keeps failing to connect (for example a terminal reporting 1006), first look at the diagnostics view for blocked connections and approve them in one click — manual configuration is usually unnecessary.
|
|
46
47
|
- **Faster reconnection**: trusted connections race during restore, revisioned assets are reused, and mobile boot batches are compressed.
|
|
47
48
|
- **Three pairing options**: scan a QR code, paste a pairing link, or enter a key.
|
|
48
49
|
|
|
@@ -200,14 +201,14 @@ The table below lists, for each plugin version, the DeepSeek Harness version it
|
|
|
200
201
|
|
|
201
202
|
| DSH Mobile plugin | Verified DeepSeek Harness version |
|
|
202
203
|
| --- | --- |
|
|
203
|
-
| `0.3.
|
|
204
|
-
| `0.3.9` | `0.1.3-alpha.1` |
|
|
204
|
+
| `0.3.13` | `0.1.3-alpha.2` |
|
|
205
|
+
| `0.3.9`-`0.3.12` | `0.1.3-alpha.1` |
|
|
205
206
|
| `0.3.6`-`0.3.8` | `0.1.2-rc.1` |
|
|
206
207
|
| `0.3.4`, `0.3.5` | `0.1.2-alpha.2` |
|
|
207
208
|
| `0.3.0`-`0.3.3` | `0.1.2-alpha.1` |
|
|
208
209
|
| `0.1.4`, `0.2.x` | `0.1.1-rc.2` |
|
|
209
210
|
|
|
210
|
-
Existing 0.3.3-0.3.
|
|
211
|
+
Existing 0.3.3-0.3.13 apps do not need re-pairing. Earlier apps use a different status-bar strategy, so updating both is recommended. App 0.1.3 or earlier requires reinstalling and pairing again.
|
|
211
212
|
|
|
212
213
|
## Uninstall
|
|
213
214
|
|
package/README.md
CHANGED
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
|
|
27
27
|
> DSH Mobile 是 DeepSeek Harness 社区插件,原生 App 仅支持 Android。
|
|
28
28
|
>
|
|
29
|
-
> **0.3.
|
|
29
|
+
> **0.3.13 更新**:第三方插件 WebSocket 连接拦截即通用一键放行——按目录分组、红点双入口、手动配置收进高级项(#47)+ 面板修整(FRP 步骤编号、部署说明排版、批准按钮)+ 适配 DeepSeek Harness 0.1.3-alpha.2(布局右栏插槽更名)。[详细记录](CHANGELOG.md)。
|
|
30
30
|
>
|
|
31
|
-
>
|
|
31
|
+
> **升级提醒**:先看电脑端 DeepSeek Harness 版本再升插件——**0.1.3-alpha.2 及以上**用插件 **0.3.13**;电脑端为更早版本(0.1.2 线或 0.1.3-alpha.1)时请保持插件 **0.3.12**。现有 0.3.3-0.3.12 App 可继续使用,无需重新配对。[兼容说明](#兼容性)。
|
|
32
32
|
|
|
33
33
|
<p align="center">
|
|
34
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
35
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.
|
|
36
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.
|
|
34
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.13/dsh-mobile-android-v0.3.13.apk"><img src="assets/brand/app-icon-rounded.svg" alt="DSH Mobile 安卓应用图标" width="72" height="72"></a><br>
|
|
35
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/v0.3.13/dsh-mobile-android-v0.3.13.apk"><strong>下载 Android App 0.3.13</strong></a><br>
|
|
36
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.3.13">版本说明与校验文件</a></sub>
|
|
37
37
|
</p>
|
|
38
38
|
|
|
39
39
|
DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App 通过局域网,或可选的 Tailscale Funnel、cpolar、自建 FRP 远程通道连接电脑,继续使用同一份会话、工作区、消息和工具。局域网与远程访问分别启停、分别管理设备,且都不修改 DeepSeek Harness 源码。
|
|
@@ -50,6 +50,7 @@ DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App
|
|
|
50
50
|
- **图片附件**:在已打开会话的输入栏加号菜单顶部选择图片或拍照;支持 PNG、JPEG、WebP、GIF(不超过 8 MiB)和完整分辨率 JPEG。
|
|
51
51
|
- **自动发现、无需重新配对**:切换 Wi-Fi、热点或 IP 后通常自动恢复。
|
|
52
52
|
- **一键连接诊断**:检查版本、网关、网卡、防火墙和远程通道;稳定的原因码在界面中本地化,并生成不含凭据与完整地址的脱敏报告。
|
|
53
|
+
- **第三方插件 WebSocket 一键放行**:诊断页按目录分组记录被拦截的插件连接(含次数),点允许即放行确切路径,未批准的一律拦截;有新拦截时侧栏红点提醒(#47)。若某插件的连接一直失败(如终端报 1006),先到诊断页看看有没有被拦的连接,一键放行即可,通常无需手动配置。
|
|
53
54
|
- **更快恢复连接**:远程重开会并行恢复可信连接、复用版本化资源,并压缩移动端启动批次。
|
|
54
55
|
- **三种配对方式**:扫码、配对链接、密钥。
|
|
55
56
|
|
|
@@ -209,14 +210,14 @@ flowchart LR
|
|
|
209
210
|
|
|
210
211
|
| DSH Mobile 插件 | 验证支持的 DeepSeek Harness 版本 |
|
|
211
212
|
| --- | --- |
|
|
212
|
-
| `0.3.
|
|
213
|
-
| `0.3.9` | `0.1.3-alpha.1` |
|
|
213
|
+
| `0.3.13` | `0.1.3-alpha.2` |
|
|
214
|
+
| `0.3.9`-`0.3.12` | `0.1.3-alpha.1` |
|
|
214
215
|
| `0.3.6`-`0.3.8` | `0.1.2-rc.1` |
|
|
215
216
|
| `0.3.4`、`0.3.5` | `0.1.2-alpha.2` |
|
|
216
217
|
| `0.3.0`-`0.3.3` | `0.1.2-alpha.1` |
|
|
217
218
|
| `0.1.4`、`0.2.x` | `0.1.1-rc.2` |
|
|
218
219
|
|
|
219
|
-
现有 0.3.3-0.3.
|
|
220
|
+
现有 0.3.3-0.3.13 App 无需重新配对;更早的 App 使用不同的状态栏策略,建议同步升级;App 0.1.3 及更早版本需卸载重装并重新配对。
|
|
220
221
|
|
|
221
222
|
## 卸载
|
|
222
223
|
|
package/lib/client.js
CHANGED
|
@@ -153,12 +153,20 @@ window.__ModuleLoader__.load({
|
|
|
153
153
|
resetTailscaleConfirm: "Sign out of Tailscale on this computer and remove all remote paired devices? Local network configuration is unchanged.",
|
|
154
154
|
requestFailed: "Request failed: {error}",
|
|
155
155
|
wsPathsTitle: "Third-party WebSocket paths",
|
|
156
|
-
wsPathsIntro: "
|
|
156
|
+
wsPathsIntro: "When an installed plugin cannot connect (say a sidebar terminal or a live panel), it is usually because its connection paths have not been approved yet. Everything that needs your attention is listed below — one click on “Allow” fixes it.",
|
|
157
157
|
wsPathsPlaceholder: "/sidebar/ws/terminal",
|
|
158
158
|
wsPathsAdd: "Allow path",
|
|
159
159
|
wsPathsRemove: "Remove",
|
|
160
|
-
wsPathsEmpty: "
|
|
161
|
-
wsPathsInvalid: "Enter an exact path starting with / (no query string)."
|
|
160
|
+
wsPathsEmpty: "Nothing to configure right now. If a plugin cannot connect later, one-click options appear here.",
|
|
161
|
+
wsPathsInvalid: "Enter an exact path starting with / (no query string).",
|
|
162
|
+
wsPathsDetected: "A plugin connection was blocked — press Allow to let it through",
|
|
163
|
+
wsPathsAllow: "Allow",
|
|
164
|
+
wsPathsAllowAll: "Allow all",
|
|
165
|
+
wsPathsGroupMeta: "{n} paths · blocked {m} times",
|
|
166
|
+
wsPathsNewBlocked: "New blocked third-party connections — open diagnostics to review",
|
|
167
|
+
wsPathsAdvancedToggle: "Add paths manually (advanced)",
|
|
168
|
+
wsPathsAnnounce: "{n} plugin connections waiting to be approved",
|
|
169
|
+
wsPathsAdvancedHint: "Manual entries are rarely necessary: use the buttons above. Only fill this in when you know the exact path."
|
|
162
170
|
},
|
|
163
171
|
it: {
|
|
164
172
|
mobileAccess: "Accesso mobile",
|
|
@@ -306,12 +314,20 @@ window.__ModuleLoader__.load({
|
|
|
306
314
|
resetTailscaleConfirm: "Uscire da Tailscale su questo computer e rimuovere tutti i dispositivi remoti? La configurazione della rete locale resta invariata.",
|
|
307
315
|
requestFailed: "Richiesta non riuscita: {error}",
|
|
308
316
|
wsPathsTitle: "Percorsi WebSocket di terze parti",
|
|
309
|
-
wsPathsIntro: "
|
|
317
|
+
wsPathsIntro: "Quando un plugin installato non riesce a connettersi (per esempio un terminale laterale o un pannello live), di solito è perché i suoi percorsi di connessione non sono ancora stati approvati. Tutto ciò che richiede attenzione è elencato qui sotto: un clic su “Consenti” risolve.",
|
|
310
318
|
wsPathsPlaceholder: "/sidebar/ws/terminal",
|
|
311
319
|
wsPathsAdd: "Consenti percorso",
|
|
312
320
|
wsPathsRemove: "Rimuovi",
|
|
313
|
-
wsPathsEmpty: "
|
|
314
|
-
wsPathsInvalid: "Inserisci un percorso esatto che inizi con / (senza query)."
|
|
321
|
+
wsPathsEmpty: "Non serve configurare nulla per ora. Se in seguito un plugin non riesce a connettersi, qui compariranno opzioni con un clic.",
|
|
322
|
+
wsPathsInvalid: "Inserisci un percorso esatto che inizi con / (senza query).",
|
|
323
|
+
wsPathsDetected: "Una connessione di un plugin è stata bloccata — premi Consenti per lasciarla passare",
|
|
324
|
+
wsPathsAllow: "Consenti",
|
|
325
|
+
wsPathsAllowAll: "Consenti tutti",
|
|
326
|
+
wsPathsGroupMeta: "{n} percorsi · bloccati {m} volte",
|
|
327
|
+
wsPathsNewBlocked: "Nuove connessioni di terze parti bloccate — apri la diagnostica",
|
|
328
|
+
wsPathsAdvancedToggle: "Aggiungi percorsi manualmente (avanzato)",
|
|
329
|
+
wsPathsAnnounce: "{n} connessioni di plugin in attesa di approvazione",
|
|
330
|
+
wsPathsAdvancedHint: "Le voci manuali servono raramente: usa i pulsanti qui sopra. Compila solo se conosci il percorso esatto."
|
|
315
331
|
},
|
|
316
332
|
zh: {}
|
|
317
333
|
};
|
|
@@ -461,12 +477,20 @@ window.__ModuleLoader__.load({
|
|
|
461
477
|
resetTailscaleConfirm: "退出电脑上的 Tailscale 登录并移除所有远程配对设备?局域网配置不会改变。",
|
|
462
478
|
requestFailed: "请求失败:{error}",
|
|
463
479
|
wsPathsTitle: "第三方 WebSocket 路径",
|
|
464
|
-
wsPathsIntro: "
|
|
480
|
+
wsPathsIntro: "插件(如侧边栏终端、实时面板)连不上时,通常是它的连接路径还没放行。下面列出需要处理的项,点「允许」即可。",
|
|
465
481
|
wsPathsPlaceholder: "/sidebar/ws/terminal",
|
|
466
482
|
wsPathsAdd: "允许该路径",
|
|
467
483
|
wsPathsRemove: "移除",
|
|
468
|
-
wsPathsEmpty: "
|
|
469
|
-
wsPathsInvalid: "请输入以 / 开头的确切路径(不带 query)。"
|
|
484
|
+
wsPathsEmpty: "目前无需任何设置。以后有插件连不上,会在这里出现可一键放行的选项。",
|
|
485
|
+
wsPathsInvalid: "请输入以 / 开头的确切路径(不带 query)。",
|
|
486
|
+
wsPathsDetected: "有插件连接被拦截——点「允许」放行",
|
|
487
|
+
wsPathsAllow: "允许",
|
|
488
|
+
wsPathsAllowAll: "全部允许",
|
|
489
|
+
wsPathsGroupMeta: "{n} 条路径 · 共拦截 {m} 次",
|
|
490
|
+
wsPathsNewBlocked: "发现被拦截的第三方连接,去诊断页查看",
|
|
491
|
+
wsPathsAdvancedToggle: "手动添加路径(高级)",
|
|
492
|
+
wsPathsAnnounce: "{n} 条插件连接等待放行",
|
|
493
|
+
wsPathsAdvancedHint: "通常不需要手动填写:用上方按钮即可。只有当你确切知道所需路径时才填。"
|
|
470
494
|
});
|
|
471
495
|
Object.assign(MOBILE_CONTROL_MESSAGES.en, {
|
|
472
496
|
selfHostedConnections: "Self-hosted connection",
|
|
@@ -489,7 +513,6 @@ window.__ModuleLoader__.load({
|
|
|
489
513
|
copyServerTemplate: "Copy server template",
|
|
490
514
|
templateCopied: "Server template copied. Save frps.toml and the Caddy snippet on the VPS, then add the import line to the Caddyfile.",
|
|
491
515
|
templateCopyFailed: "Could not copy the template. Check the four fields above.",
|
|
492
|
-
vpsDeployTitle: "Deploy the VPS automatically",
|
|
493
516
|
vpsDeployText: "Use an existing OpenSSH key or agent. The VPS must be Ubuntu/Debian with systemd; existing Caddy site configuration is never overwritten.",
|
|
494
517
|
vpsDeployChangesTitle: "Automatic deployment will change the following on the VPS (manual template changes nothing by itself):",
|
|
495
518
|
vpsDeployChangePackages: "Install Caddy from its official APT repository, plus a Python venv and Certbot for public-IPv4 certificates.",
|
|
@@ -578,7 +601,6 @@ window.__ModuleLoader__.load({
|
|
|
578
601
|
copyServerTemplate: "Copia modello server",
|
|
579
602
|
templateCopied: "Modello server copiato. Salva frps.toml e lo snippet Caddy sul VPS, poi aggiungi la riga import al Caddyfile.",
|
|
580
603
|
templateCopyFailed: "Impossibile copiare il modello. Controlla i quattro campi sopra.",
|
|
581
|
-
vpsDeployTitle: "Prepara automaticamente il VPS",
|
|
582
604
|
vpsDeployText: "Usa una chiave OpenSSH o un agent esistente. Il VPS deve essere Ubuntu/Debian con systemd; una configurazione Caddy non vuota non viene sovrascritta.",
|
|
583
605
|
vpsDeployChangesTitle: "Il deploy automatico modifica quanto segue sul VPS (il modello manuale da solo non cambia nulla):",
|
|
584
606
|
vpsDeployChangePackages: "Installa Caddy dal repository APT ufficiale, più un venv Python e Certbot per i certificati IPv4 pubblici.",
|
|
@@ -667,7 +689,6 @@ window.__ModuleLoader__.load({
|
|
|
667
689
|
copyServerTemplate: "复制手动部署模板",
|
|
668
690
|
templateCopied: "服务器模板已复制,请在 VPS 上保存 frps.toml 和 Caddy 片段,并在 Caddyfile 里加一行 import。",
|
|
669
691
|
templateCopyFailed: "无法复制模板,请检查上方连接信息。",
|
|
670
|
-
vpsDeployTitle: "中转服务器部署",
|
|
671
692
|
vpsDeployText: "填写 SSH 登录信息。服务器需为带 systemd 的 Ubuntu/Debian;不会覆盖已有的 Caddy 站点配置。",
|
|
672
693
|
vpsDeployChangesTitle: "自动部署会在 VPS 上做这些改动(只复制手动模板不会改变任何东西):",
|
|
673
694
|
vpsDeployChangePackages: "从官方 APT 源安装 Caddy,并安装 Python venv 与 Certbot(公网 IP 证书用)。",
|
|
@@ -2447,7 +2468,7 @@ window.__ModuleLoader__.load({
|
|
|
2447
2468
|
frpConnectionGroup.append(frpConnectionSummary, frpStep1);
|
|
2448
2469
|
const frpVpsGroup = element("details", "dsh-mobile-control__frp-group");
|
|
2449
2470
|
const frpVpsSummary = element("summary");
|
|
2450
|
-
frpVpsSummary.textContent = t("
|
|
2471
|
+
frpVpsSummary.textContent = t("frpStep2Title");
|
|
2451
2472
|
frpVpsGroup.append(frpVpsSummary, frpStep2);
|
|
2452
2473
|
const frpComponentGroup = element("details", "dsh-mobile-control__frp-group");
|
|
2453
2474
|
const frpComponentSummary = element("summary");
|
|
@@ -2553,21 +2574,34 @@ window.__ModuleLoader__.load({
|
|
|
2553
2574
|
wsPathsTitle.textContent = t("wsPathsTitle");
|
|
2554
2575
|
const wsPathsIntro = element("p", "dsh-mobile-control__intro");
|
|
2555
2576
|
wsPathsIntro.textContent = t("wsPathsIntro");
|
|
2577
|
+
const wsPathsDetected = element("div", "dsh-mobile-control__ws-paths-detected");
|
|
2578
|
+
wsPathsDetected.hidden = true;
|
|
2579
|
+
const wsPathsDetectedTitle = element("p", "dsh-mobile-control__ws-paths-detected-title");
|
|
2580
|
+
wsPathsDetectedTitle.textContent = t("wsPathsDetected");
|
|
2581
|
+
const wsPathsDetectedList = element("ul", "dsh-mobile-control__ws-paths-list");
|
|
2582
|
+
wsPathsDetected.append(wsPathsDetectedTitle, wsPathsDetectedList);
|
|
2556
2583
|
const wsPathsList = element("ul", "dsh-mobile-control__ws-paths-list");
|
|
2584
|
+
const wsPathsAdvanced = element("details", "dsh-mobile-control__ws-paths-advanced");
|
|
2585
|
+
const wsPathsAdvancedSummary = element("summary");
|
|
2586
|
+
wsPathsAdvancedSummary.textContent = t("wsPathsAdvancedToggle");
|
|
2587
|
+
const wsPathsAdvancedHint = element("p", "dsh-mobile-control__intro");
|
|
2588
|
+
wsPathsAdvancedHint.textContent = t("wsPathsAdvancedHint");
|
|
2557
2589
|
const wsPathsRow = element("div", "dsh-mobile-control__ws-paths-row");
|
|
2558
2590
|
const wsPathsInput = element("input", "dsh-mobile-control__ws-paths-input");
|
|
2559
2591
|
wsPathsInput.type = "text";
|
|
2560
2592
|
wsPathsInput.placeholder = t("wsPathsPlaceholder");
|
|
2561
2593
|
wsPathsInput.setAttribute("aria-label", t("wsPathsTitle"));
|
|
2562
|
-
const wsPathsAdd = element("button", "dsh-mobile-
|
|
2594
|
+
const wsPathsAdd = element("button", "dsh-mobile-control__primary");
|
|
2563
2595
|
wsPathsAdd.type = "button";
|
|
2564
2596
|
wsPathsAdd.textContent = t("wsPathsAdd");
|
|
2565
2597
|
const wsPathsStatus = element("p", "dsh-mobile-control__status");
|
|
2566
2598
|
wsPathsStatus.hidden = true;
|
|
2567
2599
|
wsPathsStatus.setAttribute("aria-live", "polite");
|
|
2568
2600
|
wsPathsRow.append(wsPathsInput, wsPathsAdd);
|
|
2569
|
-
|
|
2601
|
+
wsPathsAdvanced.append(wsPathsAdvancedSummary, wsPathsAdvancedHint, wsPathsRow, wsPathsStatus);
|
|
2602
|
+
wsPathsSection.append(wsPathsTitle, wsPathsIntro, wsPathsDetected, wsPathsList, wsPathsAdvanced);
|
|
2570
2603
|
let wsPathsCurrent = [];
|
|
2604
|
+
let wsPathsBlocked = [];
|
|
2571
2605
|
let wsPathsLoaded = false;
|
|
2572
2606
|
const renderWsPaths = (paths) => {
|
|
2573
2607
|
wsPathsCurrent = [...paths];
|
|
@@ -2592,11 +2626,103 @@ window.__ModuleLoader__.load({
|
|
|
2592
2626
|
wsPathsList.append(item);
|
|
2593
2627
|
}
|
|
2594
2628
|
};
|
|
2629
|
+
const wsGroupOf = (path) => {
|
|
2630
|
+
const slash = path.lastIndexOf("/");
|
|
2631
|
+
return slash > 0 ? path.slice(0, slash) : "/";
|
|
2632
|
+
};
|
|
2633
|
+
let wsPathsSeenAttempts = 0;
|
|
2634
|
+
let wsDotAnnounced = 0;
|
|
2635
|
+
const wsDotStatus = element("p", "dsh-mobile-control__ws-sr-status");
|
|
2636
|
+
wsDotStatus.setAttribute("role", "status");
|
|
2637
|
+
wsDotStatus.setAttribute("aria-atomic", "true");
|
|
2638
|
+
const wsBlockedTotal = (blocked) => blocked.reduce((sum, entry) => sum + entry.attempts, 0);
|
|
2639
|
+
const renderWsDot = () => {
|
|
2640
|
+
for (const stale of document.querySelectorAll(".dsh-mobile-control__ws-dot")) stale.remove();
|
|
2641
|
+
if (!wsDotStatus.isConnected) root.append(wsDotStatus);
|
|
2642
|
+
const pendingCount = wsPathsBlocked.filter((entry) => !wsPathsCurrent.includes(entry.path)).length;
|
|
2643
|
+
if (pendingCount === 0 || wsBlockedTotal(wsPathsBlocked) <= wsPathsSeenAttempts) {
|
|
2644
|
+
if (pendingCount === 0 && wsDotAnnounced !== 0) {
|
|
2645
|
+
wsDotAnnounced = 0;
|
|
2646
|
+
wsDotStatus.textContent = "";
|
|
2647
|
+
}
|
|
2648
|
+
return;
|
|
2649
|
+
}
|
|
2650
|
+
if (wsDotAnnounced !== pendingCount) {
|
|
2651
|
+
wsDotAnnounced = pendingCount;
|
|
2652
|
+
wsDotStatus.textContent = t("wsPathsAnnounce", { n: String(pendingCount) });
|
|
2653
|
+
}
|
|
2654
|
+
for (const trigger of document.querySelectorAll(".dsh-mobile-control__trigger, .dsh-mobile-control__diagnostic-entry")) {
|
|
2655
|
+
const dot = element("span", "dsh-mobile-control__ws-dot");
|
|
2656
|
+
dot.textContent = String(pendingCount);
|
|
2657
|
+
dot.title = t("wsPathsNewBlocked");
|
|
2658
|
+
dot.setAttribute("aria-hidden", "true");
|
|
2659
|
+
dot.addEventListener("click", (event) => {
|
|
2660
|
+
event.stopPropagation();
|
|
2661
|
+
setOpen(true);
|
|
2662
|
+
selectView("diagnostics");
|
|
2663
|
+
});
|
|
2664
|
+
trigger.append(dot);
|
|
2665
|
+
}
|
|
2666
|
+
};
|
|
2667
|
+
const renderWsBlocked = (blocked) => {
|
|
2668
|
+
wsPathsDetectedList.replaceChildren();
|
|
2669
|
+
const pending = blocked.filter((entry) => !wsPathsCurrent.includes(entry.path));
|
|
2670
|
+
wsPathsDetected.hidden = pending.length === 0;
|
|
2671
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2672
|
+
for (const entry of pending) {
|
|
2673
|
+
const group = wsGroupOf(entry.path);
|
|
2674
|
+
const list = groups.get(group);
|
|
2675
|
+
if (list) list.push(entry);
|
|
2676
|
+
else groups.set(group, [entry]);
|
|
2677
|
+
}
|
|
2678
|
+
for (const [group, entries] of groups) {
|
|
2679
|
+
const groupItem = element("li", "dsh-mobile-control__ws-paths-group");
|
|
2680
|
+
const groupHead = element("div", "dsh-mobile-control__ws-paths-group-head");
|
|
2681
|
+
const groupLabel = element("code");
|
|
2682
|
+
groupLabel.textContent = `${group}/*`;
|
|
2683
|
+
const groupCount = element("span", "dsh-mobile-control__ws-count");
|
|
2684
|
+
groupCount.textContent = t("wsPathsGroupMeta", {
|
|
2685
|
+
n: entries.length,
|
|
2686
|
+
m: entries.reduce((sum, entry) => sum + entry.attempts, 0)
|
|
2687
|
+
});
|
|
2688
|
+
groupHead.append(groupLabel, groupCount);
|
|
2689
|
+
if (entries.length > 1) {
|
|
2690
|
+
const allowAll = element("button", "dsh-mobile-control__primary");
|
|
2691
|
+
allowAll.type = "button";
|
|
2692
|
+
allowAll.textContent = t("wsPathsAllowAll");
|
|
2693
|
+
allowAll.addEventListener("click", () => {
|
|
2694
|
+
saveWsPaths([...wsPathsCurrent, ...entries.map((entry) => entry.path)]);
|
|
2695
|
+
});
|
|
2696
|
+
groupHead.append(allowAll);
|
|
2697
|
+
}
|
|
2698
|
+
groupItem.append(groupHead);
|
|
2699
|
+
for (const entry of entries) {
|
|
2700
|
+
const item = element("div", "dsh-mobile-control__ws-paths-item is-child");
|
|
2701
|
+
const label = element("code");
|
|
2702
|
+
label.textContent = `${entry.path} ×${String(entry.attempts)}`;
|
|
2703
|
+
const allow = element("button", "dsh-mobile-control__primary");
|
|
2704
|
+
allow.type = "button";
|
|
2705
|
+
allow.textContent = t("wsPathsAllow");
|
|
2706
|
+
allow.setAttribute("aria-label", `${t("wsPathsAllow")}: ${entry.path}`);
|
|
2707
|
+
allow.addEventListener("click", () => {
|
|
2708
|
+
saveWsPaths([...wsPathsCurrent, entry.path]);
|
|
2709
|
+
});
|
|
2710
|
+
item.append(label, allow);
|
|
2711
|
+
groupItem.append(item);
|
|
2712
|
+
}
|
|
2713
|
+
wsPathsDetectedList.append(groupItem);
|
|
2714
|
+
}
|
|
2715
|
+
renderWsDot();
|
|
2716
|
+
};
|
|
2595
2717
|
const loadWsPaths = () => {
|
|
2596
2718
|
controlRequestJson("/api/mobile-access/remote/websocket-paths").then((data) => {
|
|
2597
2719
|
wsPathsLoaded = true;
|
|
2598
2720
|
wsPathsStatus.hidden = true;
|
|
2599
2721
|
renderWsPaths(Array.isArray(data.paths) ? data.paths.filter((entry) => typeof entry === "string") : []);
|
|
2722
|
+
controlRequestJson("/api/mobile-access/remote/websocket-paths/blocked").then((blocked) => {
|
|
2723
|
+
wsPathsBlocked = (Array.isArray(blocked.blocked) ? blocked.blocked : []).filter((entry) => typeof entry === "object" && entry !== null && typeof entry.path === "string" && typeof entry.attempts === "number");
|
|
2724
|
+
renderWsBlocked(wsPathsBlocked);
|
|
2725
|
+
}, () => {});
|
|
2600
2726
|
}, (error) => {
|
|
2601
2727
|
wsPathsStatus.hidden = false;
|
|
2602
2728
|
wsPathsStatus.textContent = t("requestFailed", { error: String(error) });
|
|
@@ -2610,6 +2736,7 @@ window.__ModuleLoader__.load({
|
|
|
2610
2736
|
}).then((data) => {
|
|
2611
2737
|
wsPathsLoaded = true;
|
|
2612
2738
|
renderWsPaths(Array.isArray(data.paths) ? data.paths.filter((entry) => typeof entry === "string") : []);
|
|
2739
|
+
renderWsBlocked(wsPathsBlocked);
|
|
2613
2740
|
}, (error) => {
|
|
2614
2741
|
wsPathsStatus.hidden = false;
|
|
2615
2742
|
wsPathsStatus.textContent = t("requestFailed", { error: String(error) });
|
|
@@ -2626,7 +2753,7 @@ window.__ModuleLoader__.load({
|
|
|
2626
2753
|
saveWsPaths([...wsPathsCurrent, value]);
|
|
2627
2754
|
});
|
|
2628
2755
|
const remoteWorkspace = element("section", "dsh-mobile-control__remote-workspace");
|
|
2629
|
-
remoteWorkspace.append(providerSetupHeader, remoteStatus, remoteAccess, remoteGuide, providerSetupBody, remoteActions, remoteQr, remoteManageRow, remoteDevicePanel
|
|
2756
|
+
remoteWorkspace.append(providerSetupHeader, remoteStatus, remoteAccess, remoteGuide, providerSetupBody, remoteActions, remoteQr, remoteManageRow, remoteDevicePanel);
|
|
2630
2757
|
const diagnosticsView = element("div", "dsh-mobile-control__view is-diagnostics");
|
|
2631
2758
|
diagnosticsView.hidden = true;
|
|
2632
2759
|
const diagnosticsIntro = element("p", "dsh-mobile-control__intro");
|
|
@@ -2672,7 +2799,7 @@ window.__ModuleLoader__.load({
|
|
|
2672
2799
|
actions.append(toggle, pair, linkPair);
|
|
2673
2800
|
lanView.append(access, qrBox, status, extensionStatus, actions, manageRow, devicePanel);
|
|
2674
2801
|
remoteView.append(remoteIntro, providerSection, remoteWorkspace);
|
|
2675
|
-
diagnosticsView.append(diagnosticsIntro, diagnosticsSummary, diagnosticsToolbar, diagnosticsFeedback, diagnosticsChecks, diagnosticsDetails);
|
|
2802
|
+
diagnosticsView.append(diagnosticsIntro, diagnosticsSummary, diagnosticsToolbar, diagnosticsFeedback, diagnosticsChecks, wsPathsSection, diagnosticsDetails);
|
|
2676
2803
|
panel.append(header, releaseNotice, appDownload, switcher, lanView, remoteView, diagnosticsView);
|
|
2677
2804
|
root.append(panel);
|
|
2678
2805
|
document.body.append(root);
|
|
@@ -2756,6 +2883,11 @@ window.__ModuleLoader__.load({
|
|
|
2756
2883
|
diagnosticsEntry.setAttribute("aria-pressed", String(view === "diagnostics"));
|
|
2757
2884
|
diagnosticsEntry.textContent = view === "diagnostics" ? t("back") : t("diagnostics");
|
|
2758
2885
|
diagnosticsEntry.setAttribute("aria-label", view === "diagnostics" ? t("backToMobile") : t("openDiagnostics"));
|
|
2886
|
+
if (view === "diagnostics") {
|
|
2887
|
+
wsPathsSeenAttempts = wsBlockedTotal(wsPathsBlocked);
|
|
2888
|
+
renderWsDot();
|
|
2889
|
+
if (!wsPathsLoaded) loadWsPaths();
|
|
2890
|
+
}
|
|
2759
2891
|
updatePlugin.hidden = view === "diagnostics" || !pluginUpdateAvailable;
|
|
2760
2892
|
appDownload.hidden = view === "diagnostics";
|
|
2761
2893
|
switcher.hidden = view === "diagnostics";
|
|
@@ -2767,7 +2899,6 @@ window.__ModuleLoader__.load({
|
|
|
2767
2899
|
remoteTab.addEventListener("click", () => {
|
|
2768
2900
|
selectView("remote");
|
|
2769
2901
|
loadRemote();
|
|
2770
|
-
if (!wsPathsLoaded) loadWsPaths();
|
|
2771
2902
|
});
|
|
2772
2903
|
const setOpen = (open) => {
|
|
2773
2904
|
panel.hidden = !open;
|
|
@@ -2984,7 +3115,7 @@ window.__ModuleLoader__.load({
|
|
|
2984
3115
|
if (!frpLayoutInitialized) {
|
|
2985
3116
|
frpConnectionGroup.open = !frpConfigured;
|
|
2986
3117
|
frpComponentGroup.open = !frpInstalled;
|
|
2987
|
-
frpVpsGroup.open =
|
|
3118
|
+
frpVpsGroup.open = !frpConfigured;
|
|
2988
3119
|
frpLayoutInitialized = true;
|
|
2989
3120
|
}
|
|
2990
3121
|
selfHostedBadge.textContent = frpConfigured && frpInstalled ? t("ready") : t("advanced");
|
|
@@ -3900,10 +4031,19 @@ window.__ModuleLoader__.load({
|
|
|
3900
4031
|
const remotePoll = window.setInterval(() => {
|
|
3901
4032
|
if (!panel.hidden && !remoteView.hidden) loadRemote();
|
|
3902
4033
|
}, 1500);
|
|
4034
|
+
const pollWsBlocked = () => {
|
|
4035
|
+
controlRequestJson("/api/mobile-access/remote/websocket-paths/blocked").then((blocked) => {
|
|
4036
|
+
wsPathsBlocked = (Array.isArray(blocked.blocked) ? blocked.blocked : []).filter((entry) => typeof entry === "object" && entry !== null && typeof entry.path === "string" && typeof entry.attempts === "number");
|
|
4037
|
+
renderWsDot();
|
|
4038
|
+
if (!diagnosticsView.hidden) renderWsBlocked(wsPathsBlocked);
|
|
4039
|
+
}, () => {});
|
|
4040
|
+
};
|
|
4041
|
+
const wsBlockedPoll = window.setInterval(pollWsBlocked, 2e4);
|
|
3903
4042
|
return {
|
|
3904
4043
|
remove: () => {
|
|
3905
4044
|
lifecycle.abort();
|
|
3906
4045
|
window.clearInterval(remotePoll);
|
|
4046
|
+
window.clearInterval(wsBlockedPoll);
|
|
3907
4047
|
window.removeEventListener("focus", retryAfterSetup);
|
|
3908
4048
|
document.removeEventListener("visibilitychange", retryAfterSetup);
|
|
3909
4049
|
document.removeEventListener("pointerdown", dismiss);
|
|
@@ -5087,7 +5227,7 @@ window.__ModuleLoader__.load({
|
|
|
5087
5227
|
.dsh-mobile-control__provider-section{position:relative;margin:0 0 14px}.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;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.dsh-mobile-control__provider{display:flex;min-width:0;flex-direction:column;gap:6px;min-height:94px;padding:10px 11px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);text-align:left;cursor:pointer;touch-action:manipulation;transition:border-color 160ms ease,background-color 160ms ease,box-shadow 160ms ease}.dsh-mobile-control__provider:hover{border-color:#6f96db;background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-bg-layer-1,#f8fbff))}.dsh-mobile-control__provider.is-selected{border-color:#2563eb;background:var(--dsw-alias-interactive-bg-active,var(--dsw-alias-bg-layer-1,#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;min-width:0;align-items:flex-start;justify-content:space-between;gap:5px}.dsh-mobile-control__provider-top strong{min-width:0;font-size:12px;line-height:1.3}.dsh-mobile-control__provider-badge{flex:none;padding:2px 5px;border-radius:999px;background:#e8f0ff;color:#1d4ed8;font:650 9px/1.25 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:10px;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:var(--dsw-alias-label-secondary,#475569);cursor:pointer;touch-action:manipulation}.dsh-mobile-control__provider-info-button:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f5f9);color:#2563eb}.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}
|
|
5088
5228
|
.dsh-mobile-control__self-hosted{margin:8px 0 0;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:12px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__self-hosted-summary{display:flex;box-sizing:border-box;min-height:48px;align-items:center;justify-content:space-between;gap:10px;padding:8px 11px;cursor:pointer;list-style-position:inside}.dsh-mobile-control__self-hosted-summary>span:first-child{display:flex;min-width:0;flex-direction:column;gap:1px}.dsh-mobile-control__self-hosted-summary strong{font-size:11px}.dsh-mobile-control__self-hosted-summary span span{color:var(--dsw-alias-label-secondary,#606873);font-size:9px;line-height:1.35}.dsh-mobile-control__provider-badge.is-frp{background:#eef0f3;color:#475569}.dsh-mobile-control__self-hosted-body{padding:0 8px 8px}.dsh-mobile-control__provider.is-frp{width:100%;min-height:64px;background:var(--dsw-alias-bg-layer-2,#fff)}
|
|
5089
5229
|
.dsh-mobile-control__cpolar-setup{margin:0 0 12px;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#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:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2,#fff));color:var(--dsw-alias-label-primary,#16181d);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:var(--dsw-alias-bg-layer-1,#f3f5f8);color:var(--dsw-alias-label-secondary,#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:#dc2626;font:12px/1.3 system-ui;cursor:pointer}
|
|
5090
|
-
.dsh-mobile-control__frp-setup{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__frp-setup[hidden]{display:none}.dsh-mobile-control__frp-step{padding:11px 0}.dsh-mobile-control__frp-step + .dsh-mobile-control__frp-step{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__frp-step>strong{display:block;margin-bottom:3px;font-size:12px;line-height:1.4}.dsh-mobile-control__frp-step>p{margin:0 0 9px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__frp-step>.dsh-mobile-control__frp-requirement{padding:8px 9px;border-radius:9px;background:var(--dsw-alias-bg-layer-1,#f3f5f8);color:var(--dsw-alias-label-primary,#384152);font-size:11px}.dsh-mobile-control__frp-fields{display:grid;grid-template-columns:minmax(0,1fr) 96px;gap:8px}.dsh-mobile-control__field{display:flex;min-width:0;flex-direction:column;gap:5px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px}.dsh-mobile-control__field:nth-child(3),.dsh-mobile-control__field:nth-child(4){grid-column:1/-1}.dsh-mobile-control__field input{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:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:16px/1.4 system-ui}.dsh-mobile-control__frp-action{box-sizing:border-box;width:100%;min-height:44px;padding:9px 12px;border-radius:10px;font:650 12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__frp-action:disabled{cursor:not-allowed;opacity:.5}.dsh-mobile-control__remote-workspace{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:15px;background:var(--dsw-alias-bg-layer-1,#f7f8fa)}.dsh-mobile-control__stage-header{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}.dsh-mobile-control__stage-header .dsh-mobile-control__section-title{margin:0}.dsh-mobile-control__stage-meta{display:flex;min-width:0;align-items:center;justify-content:flex-end;gap:5px}.dsh-mobile-control__stage-value{max-width:115px;overflow:hidden;color:var(--dsw-alias-label-primary,#16181d);font:650 10px/1.3 system-ui;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__state-badge{flex:none;padding:3px 7px;border-radius:999px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-secondary,#606873);font:650 9px/1.25 system-ui}.dsh-mobile-control__state-badge.is-ready{background:#e6f7f0;color:#087454}.dsh-mobile-control__state-badge.is-busy{background:#e8f0ff;color:#1d4ed8}.dsh-mobile-control__state-badge.is-attention{background:#fff4dc;color:#935100}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__status{box-sizing:border-box;margin:0 0 10px;padding:9px 10px;border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);font-size:11px;line-height:1.45}.dsh-mobile-control__provider-setup-body{margin:0 0 10px}.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__cpolar-setup{margin:0}.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__cpolar-setup>.dsh-mobile-control__section-title,.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__frp-setup>.dsh-mobile-control__section-title{display:none}.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__details{margin:0;padding:9px 10px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__actions{margin-top:2px}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__qr{margin:10px 0 0}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__manage-row{margin-top:10px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}
|
|
5230
|
+
.dsh-mobile-control__frp-setup{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__frp-setup[hidden]{display:none}.dsh-mobile-control__frp-step{padding:11px 0}.dsh-mobile-control__frp-step + .dsh-mobile-control__frp-step{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__frp-step>strong{display:block;margin-bottom:3px;font-size:12px;line-height:1.4}.dsh-mobile-control__frp-step>p{margin:0 0 9px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__frp-changes{margin:0 0 9px;padding:0;list-style:none;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.dsh-mobile-control__frp-changes li{position:relative;margin:0;padding-left:12px}.dsh-mobile-control__frp-changes li+li{margin-top:5px}.dsh-mobile-control__frp-changes li::before{content:"•";position:absolute;left:2px;color:var(--dsw-alias-label-tertiary,#98a1ad)}.dsh-mobile-control__frp-step>.dsh-mobile-control__frp-requirement{padding:8px 9px;border-radius:9px;background:var(--dsw-alias-bg-layer-1,#f3f5f8);color:var(--dsw-alias-label-primary,#384152);font-size:11px}.dsh-mobile-control__frp-fields{display:grid;grid-template-columns:minmax(0,1fr) 96px;gap:8px}.dsh-mobile-control__field{display:flex;min-width:0;flex-direction:column;gap:5px;color:var(--dsw-alias-label-secondary,#606873);font-size:11px}.dsh-mobile-control__field:nth-child(3),.dsh-mobile-control__field:nth-child(4){grid-column:1/-1}.dsh-mobile-control__field input{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:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:16px/1.4 system-ui}.dsh-mobile-control__frp-action{box-sizing:border-box;width:100%;min-height:44px;padding:9px 12px;border-radius:10px;font:650 12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__frp-action:disabled{cursor:not-allowed;opacity:.5}.dsh-mobile-control__remote-workspace{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:15px;background:var(--dsw-alias-bg-layer-1,#f7f8fa)}.dsh-mobile-control__stage-header{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}.dsh-mobile-control__stage-header .dsh-mobile-control__section-title{margin:0}.dsh-mobile-control__stage-meta{display:flex;min-width:0;align-items:center;justify-content:flex-end;gap:5px}.dsh-mobile-control__stage-value{max-width:115px;overflow:hidden;color:var(--dsw-alias-label-primary,#16181d);font:650 10px/1.3 system-ui;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__state-badge{flex:none;padding:3px 7px;border-radius:999px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-secondary,#606873);font:650 9px/1.25 system-ui}.dsh-mobile-control__state-badge.is-ready{background:#e6f7f0;color:#087454}.dsh-mobile-control__state-badge.is-busy{background:#e8f0ff;color:#1d4ed8}.dsh-mobile-control__state-badge.is-attention{background:#fff4dc;color:#935100}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__status{box-sizing:border-box;margin:0 0 10px;padding:9px 10px;border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);font-size:11px;line-height:1.45}.dsh-mobile-control__provider-setup-body{margin:0 0 10px}.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__cpolar-setup{margin:0}.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__cpolar-setup>.dsh-mobile-control__section-title,.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__frp-setup>.dsh-mobile-control__section-title{display:none}.dsh-mobile-control__provider-setup-body>.dsh-mobile-control__details{margin:0;padding:9px 10px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__actions{margin-top:2px}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__qr{margin:10px 0 0}.dsh-mobile-control__remote-workspace>.dsh-mobile-control__manage-row{margin-top:10px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}
|
|
5091
5231
|
.dsh-mobile-control__frp-overview{display:grid;grid-template-columns:32px minmax(0,1fr);align-items:center;gap:10px;margin:0 0 10px;padding:10px;border:1px solid #a9dfc9;border-radius:11px;background:#edf9f4}.dsh-mobile-control__frp-overview[hidden]{display:none}.dsh-mobile-control__frp-overview-mark{display:grid;width:32px;height:32px;place-items:center;border-radius:50%;background:#087454;color:#fff;font:700 15px/1 system-ui}.dsh-mobile-control__frp-overview-body{display:flex;min-width:0;flex-direction:column;gap:2px}.dsh-mobile-control__frp-overview-body strong{color:#075d46;font-size:12px;line-height:1.35}.dsh-mobile-control__frp-overview-body span{overflow:hidden;color:#357061;font:10px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__frp-group{margin:8px 0 0;overflow:hidden;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__frp-group>summary{box-sizing:border-box;min-height:44px;padding:12px 34px 10px 12px;color:var(--dsw-alias-label-primary,#16181d);font:650 12px/1.4 system-ui;cursor:pointer}.dsh-mobile-control__frp-group[open]>summary{border-bottom:1px solid var(--dsw-alias-border-subtle,#e1e5eb);background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__frp-group>.dsh-mobile-control__frp-step{padding:12px}.dsh-mobile-control__frp-group>.dsh-mobile-control__frp-step>strong:first-child{display:none}.dsh-mobile-control__frp-group .dsh-mobile-control__frp-step{border-top:0}.dsh-mobile-control__frp-setup>.dsh-mobile-control__frp-step{margin-bottom:8px;padding:10px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}
|
|
5092
5232
|
.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}
|
|
5093
5233
|
.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}
|
|
@@ -5102,7 +5242,7 @@ window.__ModuleLoader__.load({
|
|
|
5102
5242
|
.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}
|
|
5103
5243
|
.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}
|
|
5104
5244
|
.dsh-mobile-control__trigger{box-sizing:border-box;flex:none;display:flex;align-items:center;gap:8px;width:calc(100% + 4px);height:42px;margin:4px -2px;padding:0 10px 0 8px;border:0;border-radius:12px;background:transparent;color:var(--dsw-alias-label-primary,#16181d);font-family:inherit;font-size:14px;line-height:22px;cursor:pointer;overflow:hidden}.dsh-mobile-control__trigger:hover{background:var(--dsw-alias-interactive-bg-hover,#f1f3f6)}.dsh-mobile-control__trigger:active,.dsh-mobile-control__trigger[aria-expanded="true"]{background:var(--dsw-alias-interactive-bg-active,#e8ebf0)}.dsh-mobile-control__trigger:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,currentColor);outline-offset:2px}.dsh-mobile-control__trigger.is-rail{width:36px;height:36px;margin:8px 0 10px;padding:0;justify-content:center;gap:0;border-radius:50%}.dsh-mobile-control__trigger-icon{display:block;flex:none}.dsh-mobile-control__trigger-label{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
|
|
5105
|
-
.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}.dsh-mobile-control__ws-paths{margin:10px 0 0;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__ws-paths-list{margin:0 0 8px;padding:0;list-style:none}.dsh-mobile-control__ws-paths-empty{color:var(--dsw-alias-label-secondary,#606873);font-size:12px}.dsh-mobile-control__ws-paths-item{display:flex;align-items:center;gap:8px;padding:6px 0}.dsh-mobile-control__ws-paths-item + .dsh-mobile-control__ws-paths-item{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__ws-paths-item code{flex:1 1 0;min-width:0;overflow:hidden;font:11px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__ws-paths-remove{flex:none;min-height:28px;padding:4px 8px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:8px;background:transparent;color:inherit;font:12px/1.2 system-ui;cursor:pointer}.dsh-mobile-control__ws-paths-row{display:flex;gap:8px}.dsh-mobile-control__ws-paths-row input{flex:1 1 0;min-width:0;box-sizing:border-box;min-height:
|
|
5245
|
+
.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}.dsh-mobile-control__ws-paths{margin:10px 0 0;padding:12px;border:1px solid var(--dsw-alias-border-subtle,#dbe1e8);border-radius:13px;background:var(--dsw-alias-bg-layer-2,#fff)}.dsh-mobile-control__ws-paths-list{margin:0 0 8px;padding:0;list-style:none}.dsh-mobile-control__ws-paths-empty{color:var(--dsw-alias-label-secondary,#606873);font-size:12px}.dsh-mobile-control__ws-paths-item{display:flex;align-items:center;gap:8px;padding:6px 0}.dsh-mobile-control__ws-paths-item + .dsh-mobile-control__ws-paths-item{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__ws-paths-item code{flex:1 1 0;min-width:0;overflow:hidden;font:11px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__ws-paths-remove{flex:none;min-height:28px;padding:4px 8px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:8px;background:transparent;color:inherit;font:12px/1.2 system-ui;cursor:pointer}.dsh-mobile-control__trigger,.dsh-mobile-control__diagnostic-entry{position:relative}.dsh-mobile-control__ws-dot{position:absolute;top:2px;right:2px;z-index:1;min-width:16px;height:16px;padding:0 4px;border-radius:999px;background:#dc2626;color:#fff;font:650 10px/16px system-ui;text-align:center;cursor:pointer}.dsh-mobile-control__ws-dot::after{content:'';position:absolute;inset:-5px}.dsh-mobile-control__ws-sr-status{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.dsh-mobile-control__ws-paths-row{display:flex;gap:8px}.dsh-mobile-control__ws-paths-row .dsh-mobile-control__primary{width:auto;flex:none;padding:9px 14px;border-radius:10px}.dsh-mobile-control__ws-paths-group{padding:6px 0}.dsh-mobile-control__ws-paths-group + .dsh-mobile-control__ws-paths-group{border-top:1px solid var(--dsw-alias-border-subtle,#e1e5eb)}.dsh-mobile-control__ws-paths-group-head{display:flex;align-items:center;gap:8px}.dsh-mobile-control__ws-count{flex:none;padding:1px 7px;border-radius:999px;background:#e8f0ff;color:#1d4ed8;font:650 10px/1.6 system-ui}.dsh-mobile-control__ws-paths-item.is-child{padding-left:12px}.dsh-mobile-control__ws-paths-group-head .dsh-mobile-control__primary,.dsh-mobile-control__ws-paths-item .dsh-mobile-control__primary{width:auto;flex:none;min-height:34px;padding:6px 12px;border-radius:10px}.dsh-mobile-control__ws-paths-row input{flex:1 1 0;min-width:0;box-sizing:border-box;min-height:44px;padding:9px 10px;border:1px solid var(--dsw-alias-border-normal,#cfd5dd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:16px/1.4 system-ui}.dsh-mobile-control__ws-paths-row button{flex:none}.dsh-mobile-control__ws-paths-detected-title{margin:0 0 2px;font:600 12px/1.4 system-ui}.dsh-mobile-control__ws-paths-advanced{margin-top:8px}.dsh-mobile-control__ws-paths-advanced summary{cursor:pointer;color:var(--dsw-alias-label-secondary,#606873);font:12px/1.4 system-ui;user-select:none}.dsh-mobile-control__ws-paths-advanced summary:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,currentColor);outline-offset:2px;border-radius:4px}.dsh-mobile-control__ws-paths-advanced[open] summary{margin-bottom:6px}.dsh-mobile-control__ws-paths-advanced .dsh-mobile-control__status{margin:6px 0 0}
|
|
5106
5246
|
@media (max-width:359px){.dsh-mobile-control__provider-choices{grid-template-columns:1fr}.dsh-mobile-control__provider{min-height:68px}}@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}}
|
|
5107
5247
|
`;
|
|
5108
5248
|
/** Mount the desktop control or mobile feature enhancements. */
|