dsh-mobile 0.8.0 → 0.8.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 +29 -0
- package/CONTRIBUTORS.md +24 -2
- package/README.en.md +8 -5
- package/README.md +10 -5
- package/SECURITY.md +1 -1
- package/apps/mobile/README.md +8 -4
- package/apps/mobile/README.zh-CN.md +8 -4
- package/apps/mobile/release.json +3 -3
- package/docs/CLIENT_MODULES.en.md +6 -2
- package/docs/CLIENT_MODULES.md +6 -2
- package/docs/CONNECTION_DIAGNOSTICS.en.md +50 -0
- package/docs/CONNECTION_DIAGNOSTICS.md +50 -0
- package/docs/IROH.en.md +6 -0
- package/docs/IROH.md +6 -0
- package/docs/MOBILE_PLUGIN_ADAPTATION.en.md +18 -0
- package/docs/MOBILE_PLUGIN_ADAPTATION.md +18 -0
- package/docs/MOBILE_PLUGIN_BASELINE.en.md +117 -0
- package/docs/MOBILE_PLUGIN_BASELINE.md +117 -0
- package/docs/README.md +2 -0
- package/docs/SKIN_COMPATIBILITY.en.md +1 -1
- package/docs/SKIN_COMPATIBILITY.md +1 -1
- package/docs/SLOW_CONNECTIONS.en.md +3 -1
- package/docs/SLOW_CONNECTIONS.md +3 -1
- package/lib/cli.js +6 -12
- package/lib/cli.js.map +1 -1
- package/lib/client.js +428 -126
- package/lib/client.js.map +1 -1
- package/lib/extension-worker-runtime.mjs +4 -8
- package/lib/extension-worker-runtime.mjs.map +1 -1
- package/lib/index.d.mts +16 -89
- package/lib/index.mjs +519 -253
- package/lib/index.mjs.map +1 -1
- package/lib/mobile-compat.js +2 -2
- package/lib/mobile-compat.js.map +1 -1
- package/lib/mobile-layout.js +13 -6
- package/lib/mobile-layout.js.map +1 -1
- package/package.json +10 -6
- package/packages/question-fixes/lib/client.js +1 -2
- package/packages/question-fixes/lib/index.mjs +1 -2
- package/packages/question-fixes/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -5,7 +5,7 @@ window.__ModuleLoader__.load({
|
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
|
-
|
|
8
|
+
// src/client-messages.ts
|
|
9
9
|
const frpFormMessages = {
|
|
10
10
|
en: {
|
|
11
11
|
frpServerAddressInvalid: "Enter the frps IP address or full hostname only, without https://, a port, or a path.",
|
|
@@ -803,7 +803,22 @@ window.__ModuleLoader__.load({
|
|
|
803
803
|
lanSetupConfiguring: "Creating private certificates and local network rules…",
|
|
804
804
|
lanSetupRequired: "Local network setup has not been completed. Choose a network above to continue.",
|
|
805
805
|
lanSetupRestart: "Setup complete for {origin}. Restart DSH once to start local network access.",
|
|
806
|
-
lanSetupFailed: "Setup was not completed. Confirm the network selection and approve the Windows prompt, then try again."
|
|
806
|
+
lanSetupFailed: "Setup was not completed. Confirm the network selection and approve the Windows prompt, then try again.",
|
|
807
|
+
lanChangeTitle: "Change network",
|
|
808
|
+
lanChangeIntro: "Move local network access to another interface. The private CA and paired devices are kept; connected phones reconnect with the new address.",
|
|
809
|
+
lanChangeSelect: "New network",
|
|
810
|
+
lanChangeRefresh: "Scan again",
|
|
811
|
+
lanChangeConfirm: "Change network",
|
|
812
|
+
lanChangeBusy: "Changing network…",
|
|
813
|
+
lanChangeOk: "Network saved. If local access is stopped, enable it before connecting to the new address.",
|
|
814
|
+
lanChangeOkDisconnected: "Network changed and the listener restarted. Connected phones were disconnected; generate a new pairing QR to reconnect.",
|
|
815
|
+
lanChangeCurrent: "current",
|
|
816
|
+
lanChangeUnchanged: "That is already the current network.",
|
|
817
|
+
lanChangeUnavailable: "That network is no longer available. Scan again.",
|
|
818
|
+
lanChangeUnsupported: "This setup uses a fixed address, so it cannot change networks here.",
|
|
819
|
+
lanChangeFailed: "The change did not complete. Refresh the status before retrying; the previous configuration may have been restored.",
|
|
820
|
+
lanChangeRefreshFailed: "Could not refresh network status. A submitted change may have completed; check the current status before retrying.",
|
|
821
|
+
lanChangeRecoveryRequired: "The previous network could not be restored. Check local network configuration before enabling access again."
|
|
807
822
|
});
|
|
808
823
|
Object.assign(MOBILE_CONTROL_MESSAGES.it, {
|
|
809
824
|
lanSetupTitle: "Completa la configurazione della rete locale",
|
|
@@ -818,7 +833,22 @@ window.__ModuleLoader__.load({
|
|
|
818
833
|
lanSetupConfiguring: "Creazione dei certificati privati e delle regole di rete locale…",
|
|
819
834
|
lanSetupRequired: "La configurazione della rete locale non è completa. Scegli una rete qui sopra per continuare.",
|
|
820
835
|
lanSetupRestart: "Configurazione completata per {origin}. Riavvia DSH una volta per attivare l’accesso locale.",
|
|
821
|
-
lanSetupFailed: "Configurazione non completata. Controlla la rete e approva la richiesta di Windows, quindi riprova."
|
|
836
|
+
lanSetupFailed: "Configurazione non completata. Controlla la rete e approva la richiesta di Windows, quindi riprova.",
|
|
837
|
+
lanChangeTitle: "Cambia rete",
|
|
838
|
+
lanChangeIntro: "Sposta l’accesso alla rete locale su un’altra interfaccia. La CA privata e i dispositivi abbinati restano; i telefoni collegati si riconnettono con il nuovo indirizzo.",
|
|
839
|
+
lanChangeSelect: "Nuova rete",
|
|
840
|
+
lanChangeRefresh: "Cerca di nuovo",
|
|
841
|
+
lanChangeConfirm: "Cambia rete",
|
|
842
|
+
lanChangeBusy: "Cambio della rete…",
|
|
843
|
+
lanChangeOk: "Rete salvata. Se l’accesso locale è disattivato, attivalo prima di collegarti al nuovo indirizzo.",
|
|
844
|
+
lanChangeOkDisconnected: "Rete cambiata e listener riavviato. I telefoni collegati sono stati disconnessi; genera un nuovo QR di abbinamento per riconnetterti.",
|
|
845
|
+
lanChangeCurrent: "attuale",
|
|
846
|
+
lanChangeUnchanged: "Questa è già la rete attuale.",
|
|
847
|
+
lanChangeUnavailable: "La rete non è più disponibile. Cerca di nuovo.",
|
|
848
|
+
lanChangeUnsupported: "Questa configurazione usa un indirizzo fisso: non può cambiare rete qui.",
|
|
849
|
+
lanChangeFailed: "Cambio non completato. Aggiorna lo stato prima di riprovare; la configurazione precedente potrebbe essere stata ripristinata.",
|
|
850
|
+
lanChangeRefreshFailed: "Impossibile aggiornare lo stato. Una modifica inviata potrebbe essere stata completata; verifica prima di riprovare.",
|
|
851
|
+
lanChangeRecoveryRequired: "Impossibile ripristinare la rete precedente. Controlla la configurazione locale prima di riattivare l’accesso."
|
|
822
852
|
});
|
|
823
853
|
Object.assign(MOBILE_CONTROL_MESSAGES.zh, {
|
|
824
854
|
lanSetupTitle: "完成局域网配置",
|
|
@@ -833,7 +863,22 @@ window.__ModuleLoader__.load({
|
|
|
833
863
|
lanSetupConfiguring: "正在生成私有证书并配置局域网规则…",
|
|
834
864
|
lanSetupRequired: "尚未完成局域网配置,请选择上方网络继续。",
|
|
835
865
|
lanSetupRestart: "已为 {origin} 完成配置。请重启一次 DSH,局域网访问会自动开启。",
|
|
836
|
-
lanSetupFailed: "配置未完成。请确认网卡选择并允许 Windows 授权提示,然后重试。"
|
|
866
|
+
lanSetupFailed: "配置未完成。请确认网卡选择并允许 Windows 授权提示,然后重试。",
|
|
867
|
+
lanChangeTitle: "更换网络",
|
|
868
|
+
lanChangeIntro: "把局域网访问切换到另一块网卡。私有 CA 与已配对设备都会保留,已连接的手机需要用新地址重新连接。",
|
|
869
|
+
lanChangeSelect: "新网络",
|
|
870
|
+
lanChangeRefresh: "重新扫描",
|
|
871
|
+
lanChangeConfirm: "更换网络",
|
|
872
|
+
lanChangeBusy: "正在更换网络…",
|
|
873
|
+
lanChangeOk: "网络配置已保存。若局域网访问已关闭,请开启后再用新地址连接。",
|
|
874
|
+
lanChangeOkDisconnected: "网络已更换并重启监听,已连接的手机已断开;请生成新的配对二维码重新连接。",
|
|
875
|
+
lanChangeCurrent: "当前",
|
|
876
|
+
lanChangeUnchanged: "这已经是当前网络。",
|
|
877
|
+
lanChangeUnavailable: "该网络已不可用,请重新扫描。",
|
|
878
|
+
lanChangeUnsupported: "当前配置使用固定地址,无法在这里更换网络。",
|
|
879
|
+
lanChangeFailed: "更换未完成。请先刷新状态再决定是否重试;先前配置可能已恢复。",
|
|
880
|
+
lanChangeRefreshFailed: "无法刷新网络状态,已提交的更换可能已完成;请先确认当前状态,不要重复提交。",
|
|
881
|
+
lanChangeRecoveryRequired: "无法恢复先前网络,请先检查局域网配置,再决定是否重新开启访问。"
|
|
837
882
|
});
|
|
838
883
|
Object.assign(MOBILE_CONTROL_MESSAGES.en, {
|
|
839
884
|
selfHostedConnections: "Self-hosted connection",
|
|
@@ -1821,6 +1866,93 @@ window.__ModuleLoader__.load({
|
|
|
1821
1866
|
cloudflaredTunnelSettingsInvalid: "隧道设置未通过校验。",
|
|
1822
1867
|
cloudflaredTunnelConfigMissing: "使用命名隧道需要同时填写令牌、公网域名和端口。"
|
|
1823
1868
|
});
|
|
1869
|
+
/** Measurement boundaries shared by diagnostic cards and copied reports. */
|
|
1870
|
+
const DIAGNOSTIC_SCOPE_MESSAGES = {
|
|
1871
|
+
en: {
|
|
1872
|
+
scripts: "Page scripts",
|
|
1873
|
+
configuration: "Configuration",
|
|
1874
|
+
computer: "Computer-side check",
|
|
1875
|
+
phone: "Phone not tested",
|
|
1876
|
+
versions: "Version information",
|
|
1877
|
+
provider: "Local channel state",
|
|
1878
|
+
dns: "System DNS",
|
|
1879
|
+
coverage: "Computer-side checks only. Phone reachability, authenticated pages, resources and WebSockets have not been verified."
|
|
1880
|
+
},
|
|
1881
|
+
it: {
|
|
1882
|
+
scripts: "Script pagina",
|
|
1883
|
+
configuration: "Configurazione",
|
|
1884
|
+
computer: "Controllo dal computer",
|
|
1885
|
+
phone: "Telefono non verificato",
|
|
1886
|
+
versions: "Informazioni versioni",
|
|
1887
|
+
provider: "Stato del canale locale",
|
|
1888
|
+
dns: "DNS di sistema",
|
|
1889
|
+
coverage: "Solo controlli dal computer. Raggiungibilità dal telefono, pagine autenticate, risorse e WebSocket non verificati."
|
|
1890
|
+
},
|
|
1891
|
+
zh: {
|
|
1892
|
+
scripts: "页面脚本",
|
|
1893
|
+
configuration: "配置信息",
|
|
1894
|
+
computer: "电脑侧检查",
|
|
1895
|
+
phone: "手机尚未验证",
|
|
1896
|
+
versions: "版本信息",
|
|
1897
|
+
provider: "本机通道状态",
|
|
1898
|
+
dns: "系统 DNS",
|
|
1899
|
+
coverage: "仅为电脑侧检查。手机可达性、认证页面、资源加载和 WebSocket 尚未验证。"
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
/** Fixed DNS/egress observations never imply acceptance from another network. */
|
|
1903
|
+
const DIAGNOSTIC_NETWORK_MESSAGES = {
|
|
1904
|
+
en: {
|
|
1905
|
+
"remote-service-ready": ["{provider} reports its local component ready; public and phone paths are not verified.", ""],
|
|
1906
|
+
"plugin-inspection-unavailable": ["Active page scripts could not be inspected; absence of a competing remote channel is unverified.", "Other network checks are independent. Keep the reproduction environment and inspect the relevant plugins."],
|
|
1907
|
+
"firewall-inactive": ["LAN is off, so LAN firewall rules were not probed. This does not assess the remote entry.", "Enable LAN first if you need a local connection."],
|
|
1908
|
+
"remote-tailnet-shadowed": ["System DNS returned tailnet addresses and this Funnel-only listener does not accept that private path. This failed check does not establish a public Funnel outage.", "Compare from outside the tailnet. If you voluntarily change device DNS for a test, consider other private services and restore it afterward."],
|
|
1909
|
+
"dns-public": ["System DNS returned ordinary public-address results. This does not establish endpoint reachability.", ""],
|
|
1910
|
+
"dns-tailnet": ["System DNS returned tailnet addresses, not Fake-IP. This is a private path, not an independent public-path test.", ""],
|
|
1911
|
+
"dns-fake-ip": ["System DNS returned Fake-IP-range addresses; proxy routing may affect the measurement.", "Check the DNS/routing policy without disabling certificate verification."],
|
|
1912
|
+
"dns-private": ["System DNS returned private/local addresses. This does not test the public ingress.", ""],
|
|
1913
|
+
"dns-mixed": ["System DNS returned mixed address categories; do not attribute the failure to a single private address.", "Compare the actual routes and address families."],
|
|
1914
|
+
"dns-unknown": ["System DNS context was unavailable or exceeded its wait budget; no public DNS service was queried.", ""],
|
|
1915
|
+
"remote-dns-failed": ["The computer-side endpoint probe failed during name resolution.", "Check system DNS; compare from the phone network before judging the public service."],
|
|
1916
|
+
"remote-connect-failed": ["The computer-side endpoint probe could not establish or retain its connection.", "Check the current route and ingress, then compare from another network."],
|
|
1917
|
+
"remote-tls-failed": ["The computer-side TLS identity check failed.", "Check the certificate, hostname and proxy route. Do not disable certificate verification."],
|
|
1918
|
+
"remote-probe-timeout": ["The computer-side endpoint probe exceeded its wait budget.", "A timeout does not locate the failed hop. Compare from another network."],
|
|
1919
|
+
"remote-http-failed": ["The computer reached an HTTP endpoint but did not receive a successful health status.", "Check the ingress route and provider access policy; no credentials were sent by this probe."]
|
|
1920
|
+
},
|
|
1921
|
+
it: {
|
|
1922
|
+
"remote-service-ready": ["{provider} segnala il componente locale pronto; i percorsi pubblico e del telefono non sono verificati.", ""],
|
|
1923
|
+
"plugin-inspection-unavailable": ["Script attivi non verificati; non è confermata l’assenza di un altro canale remoto.", "Gli altri controlli sono indipendenti. Mantieni il caso riproducibile e controlla i plugin coinvolti."],
|
|
1924
|
+
"firewall-inactive": ["LAN disattivata: regole firewall locali non verificate. Il canale remoto non viene valutato da questo controllo.", "Abilita LAN prima di verificare una connessione locale."],
|
|
1925
|
+
"remote-tailnet-shadowed": ["Il DNS restituisce indirizzi tailnet e questo listener solo Funnel non accetta il percorso privato. Il controllo fallito non prova un guasto pubblico.", "Confronta da una rete esterna alla tailnet. Se modifichi volontariamente il DNS del dispositivo, valuta gli altri servizi privati e ripristinalo dopo il test."],
|
|
1926
|
+
"dns-public": ["Il DNS di sistema restituisce indirizzi pubblici ordinari; non prova la raggiungibilità.", ""],
|
|
1927
|
+
"dns-tailnet": ["Il DNS restituisce indirizzi tailnet, non Fake-IP. È un percorso privato, non un test pubblico indipendente.", ""],
|
|
1928
|
+
"dns-fake-ip": ["Il DNS restituisce indirizzi Fake-IP; il routing del proxy può influire sulla misura.", "Controlla DNS e routing senza disabilitare la verifica dei certificati."],
|
|
1929
|
+
"dns-private": ["Il DNS restituisce indirizzi privati/locali; non verifica l’ingresso pubblico.", ""],
|
|
1930
|
+
"dns-mixed": ["Il DNS restituisce categorie miste; non attribuire il problema a un solo indirizzo privato.", "Confronta percorsi e famiglie IP effettivi."],
|
|
1931
|
+
"dns-unknown": ["Il contesto DNS non è disponibile o ha superato il tempo previsto; nessun DNS pubblico è stato interrogato.", ""],
|
|
1932
|
+
"remote-dns-failed": ["La risoluzione del nome è fallita nel controllo dal computer.", "Controlla il DNS di sistema e confronta dalla rete del telefono."],
|
|
1933
|
+
"remote-connect-failed": ["Il controllo dal computer non ha stabilito o mantenuto la connessione.", "Controlla percorso e ingresso, poi confronta da un’altra rete."],
|
|
1934
|
+
"remote-tls-failed": ["La verifica TLS dal computer è fallita.", "Controlla certificato, nome host e proxy. Non disabilitare la verifica TLS."],
|
|
1935
|
+
"remote-probe-timeout": ["Il controllo dal computer ha superato il tempo previsto.", "Il timeout non identifica il punto guasto; confronta da un’altra rete."],
|
|
1936
|
+
"remote-http-failed": ["Il computer ha raggiunto HTTP ma senza uno stato di salute riuscito.", "Controlla percorso e criteri di accesso. Il test non invia credenziali."]
|
|
1937
|
+
},
|
|
1938
|
+
zh: {
|
|
1939
|
+
"remote-service-ready": ["{provider} 报告本机组件已就绪;公网与手机路径尚未验证。", ""],
|
|
1940
|
+
"plugin-inspection-unavailable": ["本次未能检查活动页面脚本,不能据此认定不存在其他远程通道。", "其余网络项目独立检查;保留复现环境并核对相关插件。"],
|
|
1941
|
+
"firewall-inactive": ["局域网未启用,本次没有探测局域网防火墙规则,不用于判断远程入口。", "需要局域网连接时,先启用再检查。"],
|
|
1942
|
+
"remote-tailnet-shadowed": ["系统 DNS 返回 tailnet 地址,而当前 Funnel-only 监听不接受此私网路径。本次失败不能证明公网 Funnel 故障。", "用 tailnet 外的网络对照。若自愿临时调整设备 DNS,注意其他私网服务的影响,并在测试后恢复。"],
|
|
1943
|
+
"dns-public": ["系统 DNS 返回普通公网地址类别;这本身不证明端点可达。", ""],
|
|
1944
|
+
"dns-tailnet": ["系统 DNS 返回 tailnet 地址,不是 Fake-IP。这是私网路径,不是独立的公网验证。", ""],
|
|
1945
|
+
"dns-fake-ip": ["系统 DNS 返回 Fake-IP 网段;代理路由可能影响本次测量。", "核对 DNS 和路由策略,不要关闭证书验证。"],
|
|
1946
|
+
"dns-private": ["系统 DNS 返回私网或本机地址,不是在验证公网入口。", ""],
|
|
1947
|
+
"dns-mixed": ["系统 DNS 返回混合地址类别,不能只凭其中一个私网地址归因。", "对照实际路由与 IPv4/IPv6 路径。"],
|
|
1948
|
+
"dns-unknown": ["系统 DNS 信息不可用或等待超时;没有查询公共 DNS 服务。", ""],
|
|
1949
|
+
"remote-dns-failed": ["电脑出口探测在名称解析阶段失败。", "检查系统 DNS,并用手机当前网络对照后再判断公网状态。"],
|
|
1950
|
+
"remote-connect-failed": ["电脑出口探测无法建立或保持连接。", "核对当前路由和入口,再用其他网络对照。"],
|
|
1951
|
+
"remote-tls-failed": ["电脑出口探测的 TLS 身份验证失败。", "检查证书、主机名和代理路由,不要关闭证书验证。"],
|
|
1952
|
+
"remote-probe-timeout": ["电脑出口探测超过了等待预算。", "超时不能定位具体故障节点,请用其他网络对照。"],
|
|
1953
|
+
"remote-http-failed": ["电脑已到达 HTTP 入口,但未得到成功的健康状态。", "检查入口路由与服务商访问策略;本次探测不发送配对凭据。"]
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
1824
1956
|
const DIAGNOSTIC_REASON_MESSAGES = {
|
|
1825
1957
|
en: {
|
|
1826
1958
|
"lan-setup-required": ["Local network setup has not been completed.", "Return to Local network and choose a network to finish setup."],
|
|
@@ -1828,24 +1960,24 @@ window.__ModuleLoader__.load({
|
|
|
1828
1960
|
"network-unavailable": ["The saved local network adapter is unavailable.", "Run dsh-mobile setup again."],
|
|
1829
1961
|
"network-interface": ["Using network interface {interfaceName}.", ""],
|
|
1830
1962
|
"network-fixed": ["A fixed local network configuration is in use.", ""],
|
|
1831
|
-
"lan-ready": ["The
|
|
1963
|
+
"lan-ready": ["The computer gateway is listening at {endpointSuffix}; phone reachability is unverified.", ""],
|
|
1832
1964
|
"lan-off": ["Local network access is currently off.", "Enable local network access when the phone must connect directly."],
|
|
1833
|
-
"firewall-ready": ["
|
|
1965
|
+
"firewall-ready": ["Enabled local TCP/discovery rules were found; this does not prove the phone route is permitted.", ""],
|
|
1834
1966
|
"firewall-missing": ["The complete local network firewall rules were not found.", "Run dsh-mobile setup as administrator and check the firewall rules."],
|
|
1835
1967
|
"firewall-unknown": ["The system did not allow the plugin to read firewall status.", "If the phone cannot find this computer, run setup as administrator."],
|
|
1836
1968
|
"remote-off": ["Remote access through {provider} is currently off.", ""],
|
|
1837
1969
|
"remote-origin-ready": ["The private HTTP backend is listening; public HTTPS is not verified.", "Verify your reverse proxy, public certificate, external Host including port, and WebSocket access from your phone. Keep the HTTP backend private."],
|
|
1838
|
-
"remote-ready": ["{provider} endpoint {endpointSuffix}
|
|
1970
|
+
"remote-ready": ["Computer-side HTTP reached {provider} endpoint {endpointSuffix} in about {latencyMs} ms; phone and independent public-path reachability are unverified.", ""],
|
|
1839
1971
|
"remote-ready-via-proxy": ["The computer reached {provider} endpoint {endpointSuffix} through its configured proxy in about {latencyMs} ms; phone reachability is not verified.", "Test the connection from the phone’s network."],
|
|
1840
1972
|
"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."],
|
|
1841
1973
|
"remote-rate-limited-via-proxy": ["The computer reached {provider} endpoint {endpointSuffix} through its proxy, but the service rate-limited this check; phone reachability is not verified.", "Try again later and test from the phone’s network."],
|
|
1842
|
-
"remote-fake-ip": ["
|
|
1843
|
-
"remote-unreachable": ["{provider}
|
|
1974
|
+
"remote-fake-ip": ["System DNS returned Fake-IP-range addresses and the computer-side probe failed; this does not prove a public outage.", "Check DNS/proxy routing and compare another network without disabling certificate checks."],
|
|
1975
|
+
"remote-unreachable": ["The computer-side probe of {provider} endpoint {endpointSuffix} failed; this does not establish failure from other networks.", "Compare DNS, routing, TLS and ingress from the phone network before reconnecting."],
|
|
1844
1976
|
"remote-needs-login": ["Tailscale is waiting for login to finish.", "Return to Remote access and continue login."],
|
|
1845
1977
|
"remote-connecting": ["The {provider} remote channel is still connecting.", "Wait briefly, then check again."],
|
|
1846
1978
|
"remote-controller-error": ["The {provider} controller reported {controllerCode}.", "Return to Remote access and reconnect."],
|
|
1847
1979
|
"competing-remote-channel": ["Another remote plugin is injecting its own request channel; the phone may show that plugin’s pairing screen.", "Turn off dsh-remote-web-ui remote access on the computer, refresh, and pair using the current DSH Mobile QR code. Do not mix pairing codes."],
|
|
1848
|
-
"phone-network-unknown": ["The
|
|
1980
|
+
"phone-network-unknown": ["The phone network, paired page, resources and WebSocket have not been tested by this computer.", "Test from the current phone network; record the failing stage without sharing pairing secrets."]
|
|
1849
1981
|
},
|
|
1850
1982
|
it: {
|
|
1851
1983
|
"lan-setup-required": ["La configurazione della rete locale non è completa.", "Torna a Rete locale e scegli una rete per completare la configurazione."],
|
|
@@ -1853,24 +1985,24 @@ window.__ModuleLoader__.load({
|
|
|
1853
1985
|
"network-unavailable": ["La scheda di rete locale salvata non è disponibile.", "Esegui di nuovo dsh-mobile setup."],
|
|
1854
1986
|
"network-interface": ["È in uso l’interfaccia di rete {interfaceName}.", ""],
|
|
1855
1987
|
"network-fixed": ["È in uso una configurazione di rete locale fissa.", ""],
|
|
1856
|
-
"lan-ready": ["Il gateway
|
|
1988
|
+
"lan-ready": ["Il gateway del computer è in ascolto su {endpointSuffix}; il telefono non è verificato.", ""],
|
|
1857
1989
|
"lan-off": ["L’accesso dalla rete locale è disattivato.", "Attiva l’accesso locale quando il telefono deve collegarsi direttamente."],
|
|
1858
|
-
"firewall-ready": ["
|
|
1990
|
+
"firewall-ready": ["Trovate regole TCP/discovery abilitate; il percorso dal telefono non è verificato.", ""],
|
|
1859
1991
|
"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."],
|
|
1860
1992
|
"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."],
|
|
1861
1993
|
"remote-off": ["L’accesso remoto tramite {provider} è disattivato.", ""],
|
|
1862
1994
|
"remote-origin-ready": ["Il backend HTTP privato è in ascolto; HTTPS pubblico non è verificato.", "Verifica dal telefono reverse proxy, certificato pubblico, Host esterno inclusa la porta e accesso WebSocket. Mantieni privato il backend HTTP."],
|
|
1863
|
-
"remote-ready": ["
|
|
1995
|
+
"remote-ready": ["HTTP dal computer ha raggiunto {provider} su {endpointSuffix} in circa {latencyMs} ms; telefono e percorso pubblico indipendente non verificati.", ""],
|
|
1864
1996
|
"remote-ready-via-proxy": ["Il computer ha raggiunto l’endpoint {provider} {endpointSuffix} tramite il proxy configurato in circa {latencyMs} ms; la raggiungibilità dal telefono non è verificata.", "Prova la connessione dalla rete del telefono."],
|
|
1865
1997
|
"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."],
|
|
1866
1998
|
"remote-rate-limited-via-proxy": ["Il computer ha raggiunto l’endpoint {provider} {endpointSuffix} tramite proxy, ma il servizio ha limitato questo controllo; la raggiungibilità dal telefono non è verificata.", "Riprova più tardi e verifica dalla rete del telefono."],
|
|
1867
|
-
"remote-fake-ip": ["
|
|
1868
|
-
"remote-unreachable": ["
|
|
1999
|
+
"remote-fake-ip": ["Il DNS restituisce indirizzi Fake-IP e il controllo dal computer è fallito; non prova un guasto pubblico.", "Controlla DNS e routing e confronta una rete alternativa senza disabilitare TLS."],
|
|
2000
|
+
"remote-unreachable": ["Il controllo dal computer di {provider} su {endpointSuffix} è fallito; altre reti non sono verificate.", "Confronta DNS, routing, TLS e ingresso dalla rete del telefono."],
|
|
1869
2001
|
"remote-needs-login": ["Tailscale attende il completamento dell’accesso.", "Torna ad Accesso remoto e continua l’accesso."],
|
|
1870
2002
|
"remote-connecting": ["Il canale remoto {provider} è ancora in connessione.", "Attendi qualche istante e ripeti il controllo."],
|
|
1871
2003
|
"remote-controller-error": ["Il controller {provider} ha segnalato {controllerCode}.", "Torna ad Accesso remoto e riconnettiti."],
|
|
1872
2004
|
"competing-remote-channel": ["Un altro plugin remoto sta inserendo il proprio canale di richieste; sul telefono potrebbe apparire la sua schermata di abbinamento.", "Disattiva l’accesso remoto di dsh-remote-web-ui sul computer, aggiorna la pagina e usa il codice QR corrente di DSH Mobile. Non mescolare i codici."],
|
|
1873
|
-
"phone-network-unknown": ["
|
|
2005
|
+
"phone-network-unknown": ["Rete del telefono, pagina abbinata, risorse e WebSocket non sono stati verificati dal computer.", "Verifica dalla rete del telefono e indica la fase del problema senza condividere credenziali."]
|
|
1874
2006
|
},
|
|
1875
2007
|
zh: {
|
|
1876
2008
|
"lan-setup-required": ["尚未完成局域网初始化。", "返回局域网页选择网卡并完成配置。"],
|
|
@@ -1878,24 +2010,24 @@ window.__ModuleLoader__.load({
|
|
|
1878
2010
|
"network-unavailable": ["已保存的局域网网卡当前不可用。", "重新运行 dsh-mobile setup。"],
|
|
1879
2011
|
"network-interface": ["正在使用网卡 {interfaceName}。", ""],
|
|
1880
2012
|
"network-fixed": ["当前使用固定局域网配置。", ""],
|
|
1881
|
-
"lan-ready": ["
|
|
2013
|
+
"lan-ready": ["电脑网关已监听 {endpointSuffix};手机能否到达尚未验证。", ""],
|
|
1882
2014
|
"lan-off": ["局域网访问当前未开启。", "手机需要直连时开启局域网访问。"],
|
|
1883
|
-
"firewall-ready": ["
|
|
2015
|
+
"firewall-ready": ["已发现启用的局域网 TCP 与发现规则;这不证明手机路由或全部防火墙策略已放行。", ""],
|
|
1884
2016
|
"firewall-missing": ["未找到完整的局域网防火墙规则。", "以管理员身份运行 dsh-mobile setup 并检查防火墙规则。"],
|
|
1885
2017
|
"firewall-unknown": ["系统未允许插件读取防火墙状态。", "若手机找不到电脑,请以管理员身份运行 setup。"],
|
|
1886
2018
|
"remote-off": ["{provider} 远程访问当前未启用。", ""],
|
|
1887
2019
|
"remote-origin-ready": ["私有 HTTP 后端已监听;尚未验证公网 HTTPS。", "请用手机核对反向代理、公网证书、含端口的外部 Host 及 WebSocket 访问。HTTP 后端必须留在私网。"],
|
|
1888
|
-
"remote-ready": ["{provider}
|
|
2020
|
+
"remote-ready": ["电脑当前出口可访问 {provider} 入口 {endpointSuffix},约 {latencyMs} ms;公网及手机路径未独立验证。", ""],
|
|
1889
2021
|
"remote-ready-via-proxy": ["电脑经已配置代理访问 {provider} 端点 {endpointSuffix},约 {latencyMs} ms;尚未验证手机网络是否可达。", "请用手机当前网络实际连接测试。"],
|
|
1890
2022
|
"remote-rate-limited": ["{provider} 端点 {endpointSuffix} 可达,但本次检查观察到服务限流。", "稍后重试;旧会话会按需加载以减少流量。"],
|
|
1891
2023
|
"remote-rate-limited-via-proxy": ["电脑经代理访问 {provider} 端点 {endpointSuffix} 时遇到限流;尚未验证手机网络是否可达。", "稍后重试,并用手机当前网络实际连接测试。"],
|
|
1892
|
-
"remote-fake-ip": ["
|
|
1893
|
-
"remote-unreachable": ["{provider}
|
|
2024
|
+
"remote-fake-ip": ["系统 DNS 返回 Fake-IP 网段,电脑出口探测未成功;这不是公网故障的证明。", "核对 DNS 与代理路由,用其他网络对照,不要关闭证书验证。"],
|
|
2025
|
+
"remote-unreachable": ["电脑当前出口无法完成 {provider} 入口 {endpointSuffix} 的探测;这不证明其他网络也失败。", "先对照手机网络及 DNS、路由、证书和入口,再决定是否重连。"],
|
|
1894
2026
|
"remote-needs-login": ["Tailscale 正在等待完成登录。", "返回远程访问并继续登录。"],
|
|
1895
2027
|
"remote-connecting": ["{provider} 远程通道仍在连接。", "等待片刻后重新检查。"],
|
|
1896
2028
|
"remote-controller-error": ["{provider} 控制器报告 {controllerCode}。", "返回远程访问并重新连接。"],
|
|
1897
2029
|
"competing-remote-channel": ["检测到另一个远程插件注入自己的请求通道;手机可能显示它的配对页面。", "在电脑端关闭 dsh-remote-web-ui 的远程访问并刷新,再用 DSH Mobile 当前二维码配对;不要混用配对码。"],
|
|
1898
|
-
"phone-network-unknown": ["
|
|
2030
|
+
"phone-network-unknown": ["电脑没有验证手机网络、配对后的页面、资源和 WebSocket。", "请用手机当前网络实际连接,记录失败阶段,不要提供配对密钥。"]
|
|
1899
2031
|
}
|
|
1900
2032
|
};
|
|
1901
2033
|
Object.assign(MOBILE_CONTROL_MESSAGES.en, {
|
|
@@ -2183,8 +2315,7 @@ window.__ModuleLoader__.load({
|
|
|
2183
2315
|
if (publicIpv4Address(publicHost)) lines.push(manualIpCertificateGuide(publicHost), "");
|
|
2184
2316
|
return lines.join("\n");
|
|
2185
2317
|
}
|
|
2186
|
-
|
|
2187
|
-
//#region src/ip.ts
|
|
2318
|
+
// src/ip.ts
|
|
2188
2319
|
/**
|
|
2189
2320
|
* Browser-safe IP literal classification.
|
|
2190
2321
|
*
|
|
@@ -2265,8 +2396,7 @@ window.__ModuleLoader__.load({
|
|
|
2265
2396
|
if (leftGroups < 0 || rightGroups < 0) return 0;
|
|
2266
2397
|
return leftGroups + rightGroups >= 8 ? 0 : 6;
|
|
2267
2398
|
}
|
|
2268
|
-
|
|
2269
|
-
//#region src/network.ts
|
|
2399
|
+
// src/network.ts
|
|
2270
2400
|
/**
|
|
2271
2401
|
* IPv4 ranges that are never a public VPS endpoint (IANA special-purpose,
|
|
2272
2402
|
* private, shared, loopback, link-local, documentation, benchmark, multicast,
|
|
@@ -2524,8 +2654,7 @@ window.__ModuleLoader__.load({
|
|
|
2524
2654
|
""
|
|
2525
2655
|
].join("\n");
|
|
2526
2656
|
}
|
|
2527
|
-
|
|
2528
|
-
//#region src/frp-attach.ts
|
|
2657
|
+
// src/frp-attach.ts
|
|
2529
2658
|
/** Default proof path used to confirm the public entry answered from this computer. */
|
|
2530
2659
|
const FRP_ATTACH_DISCOVERY_PATH = "/mobile-access/discovery";
|
|
2531
2660
|
/** Declaration printed above the VPS half of an attach template. */
|
|
@@ -2722,8 +2851,7 @@ window.__ModuleLoader__.load({
|
|
|
2722
2851
|
function createFrpAttachTemplate(settings, options = {}) {
|
|
2723
2852
|
return createFrpAttachTemplateParts(settings, options).text;
|
|
2724
2853
|
}
|
|
2725
|
-
|
|
2726
|
-
//#region src/frp-form-validation.ts
|
|
2854
|
+
// src/frp-form-validation.ts
|
|
2727
2855
|
/** Field ownership for errors returned by the Host parser. */
|
|
2728
2856
|
const FRP_FORM_ERRORS = {
|
|
2729
2857
|
frp_server_address_invalid: {
|
|
@@ -2801,8 +2929,7 @@ window.__ModuleLoader__.load({
|
|
|
2801
2929
|
}
|
|
2802
2930
|
return issues;
|
|
2803
2931
|
}
|
|
2804
|
-
|
|
2805
|
-
//#region node_modules/@noble/hashes/esm/utils.js
|
|
2932
|
+
// node_modules/@noble/hashes/esm/utils.js
|
|
2806
2933
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2807
2934
|
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
|
2808
2935
|
function isBytes(a) {
|
|
@@ -2878,8 +3005,7 @@ window.__ModuleLoader__.load({
|
|
|
2878
3005
|
hashC.create = () => hashCons();
|
|
2879
3006
|
return hashC;
|
|
2880
3007
|
}
|
|
2881
|
-
|
|
2882
|
-
//#region node_modules/@noble/hashes/esm/_md.js
|
|
3008
|
+
// node_modules/@noble/hashes/esm/_md.js
|
|
2883
3009
|
/**
|
|
2884
3010
|
* Internal Merkle-Damgard hash utils.
|
|
2885
3011
|
* @module
|
|
@@ -3007,8 +3133,7 @@ window.__ModuleLoader__.load({
|
|
|
3007
3133
|
528734635,
|
|
3008
3134
|
1541459225
|
|
3009
3135
|
]);
|
|
3010
|
-
|
|
3011
|
-
//#region node_modules/@noble/hashes/esm/sha2.js
|
|
3136
|
+
// node_modules/@noble/hashes/esm/sha2.js
|
|
3012
3137
|
/**
|
|
3013
3138
|
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
|
3014
3139
|
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
|
@@ -3164,8 +3289,7 @@ window.__ModuleLoader__.load({
|
|
|
3164
3289
|
clean(this.buffer);
|
|
3165
3290
|
}
|
|
3166
3291
|
};
|
|
3167
|
-
|
|
3168
|
-
//#region node_modules/@noble/hashes/esm/sha256.js
|
|
3292
|
+
// node_modules/@noble/hashes/esm/sha256.js
|
|
3169
3293
|
/**
|
|
3170
3294
|
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
|
3171
3295
|
*
|
|
@@ -3476,8 +3600,7 @@ window.__ModuleLoader__.load({
|
|
|
3476
3600
|
if (anchorTimer !== 0) window.clearTimeout(anchorTimer);
|
|
3477
3601
|
};
|
|
3478
3602
|
}
|
|
3479
|
-
|
|
3480
|
-
//#region src/mobile-composer-toolbar.ts
|
|
3603
|
+
// src/mobile-composer-toolbar.ts
|
|
3481
3604
|
/**
|
|
3482
3605
|
* Compact the stock InputBar without changing its React ownership, handlers,
|
|
3483
3606
|
* activity tree or the two groups observed by DSH's model-width controller.
|
|
@@ -3512,8 +3635,7 @@ window.__ModuleLoader__.load({
|
|
|
3512
3635
|
[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; }
|
|
3513
3636
|
}
|
|
3514
3637
|
`;
|
|
3515
|
-
|
|
3516
|
-
//#region src/browser-file-picker.ts
|
|
3638
|
+
// src/browser-file-picker.ts
|
|
3517
3639
|
/** Browser chooser lifetime shared by camera controls and the extension SDK. */
|
|
3518
3640
|
const BROWSER_FILE_PICKER_DEADLINE_MS = 3e5;
|
|
3519
3641
|
const browserEnvironment = {
|
|
@@ -3633,8 +3755,7 @@ window.__ModuleLoader__.load({
|
|
|
3633
3755
|
}
|
|
3634
3756
|
});
|
|
3635
3757
|
}
|
|
3636
|
-
|
|
3637
|
-
//#region src/mobile-sidebar-scroll.ts
|
|
3758
|
+
// src/mobile-sidebar-scroll.ts
|
|
3638
3759
|
function sidebarRestoreTop(snapshot, anchorTop) {
|
|
3639
3760
|
return Math.max(0, anchorTop === void 0 || snapshot.offset === void 0 ? snapshot.top : anchorTop - snapshot.offset);
|
|
3640
3761
|
}
|
|
@@ -3790,8 +3911,7 @@ window.__ModuleLoader__.load({
|
|
|
3790
3911
|
}
|
|
3791
3912
|
};
|
|
3792
3913
|
}
|
|
3793
|
-
|
|
3794
|
-
//#region src/native-mobile.ts
|
|
3914
|
+
// src/native-mobile.ts
|
|
3795
3915
|
/**
|
|
3796
3916
|
* Viewport below which the injected chrome becomes an overlay drawer: the
|
|
3797
3917
|
* sidebar slides in as a sheet, the right panel as a drawer, and the scrim dims
|
|
@@ -3933,7 +4053,7 @@ window.__ModuleLoader__.load({
|
|
|
3933
4053
|
[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-alias-bg-layer-1, #fff); box-shadow:-18px 0 46px rgb(15 23 42 / 18%); }
|
|
3934
4054
|
[data-dsh-mobile-details][data-open="true"] { transform:translateX(0); }
|
|
3935
4055
|
[data-dsh-mobile-handle] { display:none !important; }
|
|
3936
|
-
[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); }
|
|
4056
|
+
[data-dsh-mobile-settings="true"] { 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); }
|
|
3937
4057
|
[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-l2,#e8ebef); }
|
|
3938
4058
|
[data-dsh-mobile-settings-nav] [class*="_navTitle"] { padding:0 8px !important; font-size:18px !important; line-height:28px !important; }
|
|
3939
4059
|
[data-dsh-mobile-settings-list] { flex-direction:row !important; gap:4px !important; overflow-x:auto !important; scrollbar-width:none; }
|
|
@@ -4131,6 +4251,14 @@ window.__ModuleLoader__.load({
|
|
|
4131
4251
|
});
|
|
4132
4252
|
}
|
|
4133
4253
|
/**
|
|
4254
|
+
* Detect upstream ownership before applying legacy frame geometry.
|
|
4255
|
+
* @param frame - the stock frame's element lookup, if mounted.
|
|
4256
|
+
* @returns whether it provides the responsive sidebar opener.
|
|
4257
|
+
*/
|
|
4258
|
+
function stockOwnsMobileDrawer(frame) {
|
|
4259
|
+
return frame?.querySelector("[data-sidebar-opener]") != null;
|
|
4260
|
+
}
|
|
4261
|
+
/**
|
|
4134
4262
|
* Mirror the classes of the stock Add-menu item on an injected attachment action.
|
|
4135
4263
|
*
|
|
4136
4264
|
* An empty class name is not nullish: trusting it would strip the plugin's own
|
|
@@ -4150,7 +4278,17 @@ window.__ModuleLoader__.load({
|
|
|
4150
4278
|
const children = Array.from(dialog.children);
|
|
4151
4279
|
const nav = children.find((child) => classToken(child, "_nav"));
|
|
4152
4280
|
const content = children.find((child) => classToken(child, "_content"));
|
|
4153
|
-
if (nav === void 0
|
|
4281
|
+
if (nav === void 0) continue;
|
|
4282
|
+
if (content === void 0) {
|
|
4283
|
+
const header = children.find((child) => classToken(child, "_header"));
|
|
4284
|
+
const options = children.find((child) => classToken(child, "_options"));
|
|
4285
|
+
const title = children.find((child) => classToken(child, "_navTitle"));
|
|
4286
|
+
if (dialog.getAttribute("data-shortcut-modal") !== "settings" || header === void 0 || options === void 0 || title === void 0) continue;
|
|
4287
|
+
dialog.dataset.dshMobileSettings = "grid";
|
|
4288
|
+
header.setAttribute("data-dsh-mobile-settings-header", "true");
|
|
4289
|
+
marked += 1;
|
|
4290
|
+
continue;
|
|
4291
|
+
}
|
|
4154
4292
|
dialog.dataset.dshMobileSettings = "true";
|
|
4155
4293
|
nav.dataset.dshMobileSettingsNav = "true";
|
|
4156
4294
|
content.dataset.dshMobileSettingsContent = "true";
|
|
@@ -5409,11 +5547,27 @@ window.__ModuleLoader__.load({
|
|
|
5409
5547
|
const nextFrame = resolveNativeMobileFrame(document, dedicatedCenter);
|
|
5410
5548
|
if (frame !== nextFrame) frame?.removeAttribute("data-dsh-mobile-frame");
|
|
5411
5549
|
frame = nextFrame;
|
|
5412
|
-
|
|
5413
|
-
|
|
5550
|
+
const nativeDrawer = stockOwnsMobileDrawer(frame);
|
|
5551
|
+
if (frame !== void 0) {
|
|
5552
|
+
if (nativeDrawer) frame.removeAttribute("data-dsh-mobile-frame");
|
|
5553
|
+
else frame.dataset.dshMobileFrame = "true";
|
|
5554
|
+
}
|
|
5555
|
+
if (nativeDrawer) {
|
|
5556
|
+
sidebar?.removeAttribute("data-dsh-mobile-sidebar");
|
|
5557
|
+
sidebarRoot?.removeAttribute("data-dsh-mobile-sidebar-root");
|
|
5558
|
+
toggle?.removeAttribute("data-dsh-mobile-toggle");
|
|
5559
|
+
for (const node of frame.querySelectorAll("[data-dsh-mobile-details],[data-dsh-mobile-handle]")) {
|
|
5560
|
+
node.removeAttribute("data-dsh-mobile-details");
|
|
5561
|
+
node.removeAttribute("data-dsh-mobile-handle");
|
|
5562
|
+
}
|
|
5563
|
+
sidebarRoot = void 0;
|
|
5564
|
+
toggle = void 0;
|
|
5565
|
+
backdrop.hidden = true;
|
|
5566
|
+
}
|
|
5567
|
+
sidebar = nativeDrawer ? void 0 : frame === void 0 ? document.querySelector(".dshm-drawer") ?? void 0 : firstByClassSuffix(frame, "_sidebarCol");
|
|
5414
5568
|
const center = frame === void 0 ? dedicatedCenter : firstByClassSuffix(frame, "_centerCol");
|
|
5415
|
-
const details = frame === void 0 ? void 0 : firstByClassSuffix(frame, "_detailsCol");
|
|
5416
|
-
const handle = frame === void 0 ? void 0 : firstByClassSuffix(frame, "_handle");
|
|
5569
|
+
const details = frame === void 0 || nativeDrawer ? void 0 : firstByClassSuffix(frame, "_detailsCol");
|
|
5570
|
+
const handle = frame === void 0 || nativeDrawer ? void 0 : firstByClassSuffix(frame, "_handle");
|
|
5417
5571
|
markNativeMobileSettings(document);
|
|
5418
5572
|
if (center === void 0) {
|
|
5419
5573
|
syncPanHeader(void 0);
|
|
@@ -5427,12 +5581,15 @@ window.__ModuleLoader__.load({
|
|
|
5427
5581
|
return;
|
|
5428
5582
|
}
|
|
5429
5583
|
if (center !== void 0) {
|
|
5430
|
-
center.
|
|
5584
|
+
if (nativeDrawer) center.removeAttribute("data-dsh-mobile-center");
|
|
5585
|
+
else center.dataset.dshMobileCenter = "true";
|
|
5431
5586
|
const header = center.querySelector("header") ?? void 0;
|
|
5432
|
-
header?.
|
|
5433
|
-
|
|
5587
|
+
if (nativeDrawer) header?.removeAttribute("data-dsh-mobile-header");
|
|
5588
|
+
else header?.setAttribute("data-dsh-mobile-header", "true");
|
|
5589
|
+
syncPanHeader(nativeDrawer ? void 0 : header);
|
|
5434
5590
|
viewArea = firstByClassSuffix(center, "_viewArea");
|
|
5435
|
-
if (
|
|
5591
|
+
if (nativeDrawer) viewArea?.removeAttribute("data-dsh-mobile-view");
|
|
5592
|
+
else if (viewArea !== void 0) viewArea.dataset.dshMobileView = "true";
|
|
5436
5593
|
const conversation = center.querySelector("[data-conversation-scroll]");
|
|
5437
5594
|
const composerCard = center.querySelector("[data-composer-card]");
|
|
5438
5595
|
bindHistoryScroller(conversation ?? void 0, composerCard ?? null);
|
|
@@ -5641,8 +5798,7 @@ window.__ModuleLoader__.load({
|
|
|
5641
5798
|
delete document.documentElement.dataset.dshMobileInput;
|
|
5642
5799
|
};
|
|
5643
5800
|
}
|
|
5644
|
-
|
|
5645
|
-
//#region src/voice-session.ts
|
|
5801
|
+
// src/voice-session.ts
|
|
5646
5802
|
/** Screen wake-lock ownership and mobile composer focus during DSH dictation. */
|
|
5647
5803
|
/** Voice phases during which the user is dictating. */
|
|
5648
5804
|
const DICTATING_PHASES = [
|
|
@@ -6099,8 +6255,7 @@ window.__ModuleLoader__.load({
|
|
|
6099
6255
|
}
|
|
6100
6256
|
};
|
|
6101
6257
|
}
|
|
6102
|
-
|
|
6103
|
-
//#region src/mobile-font-capabilities.ts
|
|
6258
|
+
// src/mobile-font-capabilities.ts
|
|
6104
6259
|
const NO_ADVANCED_MOBILE_TYPOGRAPHY = Object.freeze({
|
|
6105
6260
|
codeSize: false,
|
|
6106
6261
|
textFamily: false,
|
|
@@ -6156,8 +6311,7 @@ window.__ModuleLoader__.load({
|
|
|
6156
6311
|
code.remove();
|
|
6157
6312
|
}
|
|
6158
6313
|
}
|
|
6159
|
-
|
|
6160
|
-
//#region src/mobile-font.ts
|
|
6314
|
+
// src/mobile-font.ts
|
|
6161
6315
|
/** Device-local typography for authenticated mobile pages, without Host settings writes. */
|
|
6162
6316
|
const MOBILE_FONT_STORAGE_KEY = "dsh-mobile.content-font-size.v1";
|
|
6163
6317
|
const MOBILE_TYPOGRAPHY_STORAGE_KEY = "dsh-mobile.typography.v1";
|
|
@@ -6583,8 +6737,7 @@ window.__ModuleLoader__.load({
|
|
|
6583
6737
|
}
|
|
6584
6738
|
}, copy.reset)));
|
|
6585
6739
|
}
|
|
6586
|
-
|
|
6587
|
-
//#region src/mobile-display-scale.ts
|
|
6740
|
+
// src/mobile-display-scale.ts
|
|
6588
6741
|
/** Native App page scaling in DSH General settings, independent from local typography. */
|
|
6589
6742
|
/** Validate the native reply before displaying or reusing its values in a request. */
|
|
6590
6743
|
function parseMobileDisplayScale(value) {
|
|
@@ -6801,8 +6954,7 @@ window.__ModuleLoader__.load({
|
|
|
6801
6954
|
}
|
|
6802
6955
|
}, copy.reset)));
|
|
6803
6956
|
}
|
|
6804
|
-
|
|
6805
|
-
//#region src/mobile-native-settings-action.ts
|
|
6957
|
+
// src/mobile-native-settings-action.ts
|
|
6806
6958
|
/** Own capability discovery and explicit calls; native actions retain the App's own timeout. */
|
|
6807
6959
|
var MobileNativeSettingsActionController = class {
|
|
6808
6960
|
action;
|
|
@@ -6911,8 +7063,7 @@ window.__ModuleLoader__.load({
|
|
|
6911
7063
|
for (const listener of this.listeners) listener();
|
|
6912
7064
|
}
|
|
6913
7065
|
};
|
|
6914
|
-
|
|
6915
|
-
//#region src/local-admin-host.ts
|
|
7066
|
+
// src/local-admin-host.ts
|
|
6916
7067
|
/** Browser-safe desktop-admin Host checks. Do not import Node APIs here. */
|
|
6917
7068
|
const DESKTOP_ADMIN_HEADER = "x-dsh-mobile-desktop-admin";
|
|
6918
7069
|
const DESKTOP_ADMIN_MARKER = "dsh-app://app";
|
|
@@ -6976,8 +7127,7 @@ window.__ModuleLoader__.load({
|
|
|
6976
7127
|
const query = search.startsWith("?") ? search.slice(1) : search;
|
|
6977
7128
|
return (protocol === "dsh-app:" ? hostname === "app" : (protocol === "" || protocol === "http:" || protocol === "https:") && isLocalAdminHostname(hostname)) && frontend !== "dedicated" && !new URLSearchParams(query).has("dsh-mobile-preview");
|
|
6978
7129
|
}
|
|
6979
|
-
|
|
6980
|
-
//#region src/client-module-presentation.ts
|
|
7130
|
+
// src/client-module-presentation.ts
|
|
6981
7131
|
/** Group boot-protected entries before considering their package namespace.
|
|
6982
7132
|
* @param entry - Catalog entry with server-owned required and dependency fields.
|
|
6983
7133
|
* @returns Display group, never an authorization or compatibility decision.
|
|
@@ -7054,6 +7204,21 @@ window.__ModuleLoader__.load({
|
|
|
7054
7204
|
}
|
|
7055
7205
|
return entries.filter((entry) => !keep.has(entry.id)).map((entry) => entry.id);
|
|
7056
7206
|
}
|
|
7207
|
+
/**
|
|
7208
|
+
* Describe the optional modules removed by the minimal preset without treating unmeasured sizes as zero.
|
|
7209
|
+
* @param entries - The complete displayed catalog, including required dependencies.
|
|
7210
|
+
* @returns Excluded count, known gzip bytes when measured, and the number still unmeasured.
|
|
7211
|
+
*/
|
|
7212
|
+
function clientModuleMinimalImpact(entries) {
|
|
7213
|
+
const excluded = new Set(clientModuleMinimalExclusion(entries));
|
|
7214
|
+
const rows = entries.filter((entry) => excluded.has(entry.id));
|
|
7215
|
+
const measured = rows.filter((entry) => entry.gzipBytes !== void 0);
|
|
7216
|
+
return {
|
|
7217
|
+
count: rows.length,
|
|
7218
|
+
...measured.length === 0 ? {} : { gzipBytes: measured.reduce((sum, entry) => sum + entry.gzipBytes, 0) },
|
|
7219
|
+
unknown: rows.length - measured.length
|
|
7220
|
+
};
|
|
7221
|
+
}
|
|
7057
7222
|
/** Editable selections retain unknown server exclusions and never cascade dependencies. */
|
|
7058
7223
|
var ClientModuleDraft = class {
|
|
7059
7224
|
initial;
|
|
@@ -7181,8 +7346,7 @@ window.__ModuleLoader__.load({
|
|
|
7181
7346
|
return filter === "loaded" ? [] : this.invalidExclusions.filter((entry) => matchesQuery(entry.id, query));
|
|
7182
7347
|
}
|
|
7183
7348
|
};
|
|
7184
|
-
|
|
7185
|
-
//#region src/client-module-ui.ts
|
|
7349
|
+
// src/client-module-ui.ts
|
|
7186
7350
|
/** Device-local module selection and the computer's defaults share a read-only catalog. */
|
|
7187
7351
|
const CLIENT_MODULE_COPY = {
|
|
7188
7352
|
zh: {
|
|
@@ -7211,6 +7375,7 @@ window.__ModuleLoader__.load({
|
|
|
7211
7375
|
failed: "暂时无法读取模块。请确认移动访问已启用后重试。",
|
|
7212
7376
|
saveFailed: "未确认保存成功,已保留你的选择。可重新保存,或重新读取已保存设置。",
|
|
7213
7377
|
conflict: "无法保存:",
|
|
7378
|
+
catalogChanged: "模块目录已变化(插件或版本有更新),本次保存已取消。请点「重新读取」,确认后再保存。",
|
|
7214
7379
|
computerSource: "当前来源:电脑默认设置",
|
|
7215
7380
|
deviceSource: "当前来源:本设备设置",
|
|
7216
7381
|
pluginSource: "当前来源:插件默认设置",
|
|
@@ -7240,6 +7405,7 @@ window.__ModuleLoader__.load({
|
|
|
7240
7405
|
totalUnknown: "勾选合计:部分模块未测到体积",
|
|
7241
7406
|
minimal: "仅必需(最小加载)",
|
|
7242
7407
|
minimalConfirm: "把除了启动必需项及其依赖之外全部设为不加载?保存后下次打开生效。",
|
|
7408
|
+
minimalDetail: "将排除 {count} 个可选模块;已测 gzip 合计 {size},另有 {unknown} 项体积未知。启动必需项及其依赖会保留。",
|
|
7243
7409
|
retry: "重新读取",
|
|
7244
7410
|
saving: "正在保存…",
|
|
7245
7411
|
readTimeout: "读取超时。当前页面和已保存设置未变,请重试。",
|
|
@@ -7277,6 +7443,7 @@ window.__ModuleLoader__.load({
|
|
|
7277
7443
|
failed: "Could not read modules. Enable mobile access and try again.",
|
|
7278
7444
|
saveFailed: "Saving was not confirmed. Your choices are kept. Save again or reread the saved settings.",
|
|
7279
7445
|
conflict: "Could not save: ",
|
|
7446
|
+
catalogChanged: "The module catalog changed (a plugin or version update). This save was cancelled; reread the settings, then confirm again.",
|
|
7280
7447
|
computerSource: "Source: computer defaults",
|
|
7281
7448
|
deviceSource: "Source: this device’s settings",
|
|
7282
7449
|
pluginSource: "Source: plugin defaults",
|
|
@@ -7306,6 +7473,7 @@ window.__ModuleLoader__.load({
|
|
|
7306
7473
|
totalUnknown: "Selection total: some sizes are unknown",
|
|
7307
7474
|
minimal: "Required only (minimal load)",
|
|
7308
7475
|
minimalConfirm: "Mark everything except required modules and their dependencies as not loaded? Applies on the next open after saving.",
|
|
7476
|
+
minimalDetail: "This excludes {count} optional modules; measured gzip total: {size}; {unknown} remain unmeasured. Required modules and their dependencies stay loaded.",
|
|
7309
7477
|
retry: "Reread settings",
|
|
7310
7478
|
saving: "Saving…",
|
|
7311
7479
|
readTimeout: "Reading timed out. This page and saved settings are unchanged; try again.",
|
|
@@ -7343,6 +7511,7 @@ window.__ModuleLoader__.load({
|
|
|
7343
7511
|
failed: "Impossibile leggere i moduli. Abilita accesso mobile e riprova.",
|
|
7344
7512
|
saveFailed: "Salvataggio non confermato. Le scelte restano; salva di nuovo o rileggi le impostazioni salvate.",
|
|
7345
7513
|
conflict: "Impossibile salvare: ",
|
|
7514
|
+
catalogChanged: "Il catalogo dei moduli è cambiato (aggiornamento di plugin o versione). Salvataggio annullato: rileggi le impostazioni e conferma di nuovo.",
|
|
7346
7515
|
computerSource: "Origine: predefiniti del computer",
|
|
7347
7516
|
deviceSource: "Origine: impostazioni del dispositivo",
|
|
7348
7517
|
pluginSource: "Origine: predefiniti del plugin",
|
|
@@ -7372,6 +7541,7 @@ window.__ModuleLoader__.load({
|
|
|
7372
7541
|
totalUnknown: "Totale selezione: alcune dimensioni sono sconosciute",
|
|
7373
7542
|
minimal: "Solo obbligatori (caricamento minimo)",
|
|
7374
7543
|
minimalConfirm: "Impostare come non caricati tutti i moduli tranne gli obbligatori e le loro dipendenze? Vale alla prossima apertura dopo il salvataggio.",
|
|
7544
|
+
minimalDetail: "Verranno esclusi {count} moduli facoltativi; totale gzip misurato: {size}; {unknown} non misurati. Gli obbligatori e le loro dipendenze restano caricati.",
|
|
7375
7545
|
retry: "Rileggi impostazioni",
|
|
7376
7546
|
saving: "Salvataggio…",
|
|
7377
7547
|
readTimeout: "Lettura scaduta. Pagina e impostazioni salvate non cambiano; riprova.",
|
|
@@ -7386,9 +7556,11 @@ window.__ModuleLoader__.load({
|
|
|
7386
7556
|
};
|
|
7387
7557
|
var ClientModuleUiConflict = class extends Error {
|
|
7388
7558
|
detail;
|
|
7389
|
-
|
|
7559
|
+
code;
|
|
7560
|
+
constructor(detail, code = "invalid_selection") {
|
|
7390
7561
|
super("client_module_conflict");
|
|
7391
7562
|
this.detail = detail;
|
|
7563
|
+
this.code = code;
|
|
7392
7564
|
}
|
|
7393
7565
|
};
|
|
7394
7566
|
/** A deadline does not imply that a POST was rolled back by the server. */
|
|
@@ -7448,12 +7620,16 @@ window.__ModuleLoader__.load({
|
|
|
7448
7620
|
};
|
|
7449
7621
|
});
|
|
7450
7622
|
if (new Set(entries.map((entry) => entry.id)).size !== entries.length) throw new Error("invalid_module_catalog");
|
|
7623
|
+
const revision = value.revision;
|
|
7624
|
+
if (revision !== void 0 && (typeof revision !== "string" || revision === "" || revision.length > 64)) throw new Error("invalid_module_catalog");
|
|
7625
|
+
const excludedClientModules = value.excludedClientModules.map((id) => {
|
|
7626
|
+
if (typeof id !== "string") throw new Error("invalid_module_catalog");
|
|
7627
|
+
return id;
|
|
7628
|
+
});
|
|
7451
7629
|
return {
|
|
7452
7630
|
entries,
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
return id;
|
|
7456
|
-
}),
|
|
7631
|
+
...typeof revision === "string" ? { revision } : {},
|
|
7632
|
+
excludedClientModules,
|
|
7457
7633
|
source: value.source === "device" ? "device" : value.source === "computer" ? "computer" : "plugin"
|
|
7458
7634
|
};
|
|
7459
7635
|
}
|
|
@@ -7500,7 +7676,9 @@ window.__ModuleLoader__.load({
|
|
|
7500
7676
|
const value = await response.json();
|
|
7501
7677
|
if (!response.ok) {
|
|
7502
7678
|
const detail = typeof value === "object" && value !== null && "detail" in value && typeof value.detail === "string" ? value.detail.slice(0, 512) : "";
|
|
7503
|
-
|
|
7679
|
+
const code = typeof value === "object" && value !== null && "error" in value && typeof value.error === "string" ? value.error : "";
|
|
7680
|
+
if (response.status === 409 && detail !== "" && code === "client_module_catalog_changed") throw new ClientModuleUiConflict(detail, "catalog_changed");
|
|
7681
|
+
if (response.status === 409 && detail !== "" && code === "excluded_client_modules_invalid") throw new ClientModuleUiConflict(detail);
|
|
7504
7682
|
throw new Error("client_module_request_failed");
|
|
7505
7683
|
}
|
|
7506
7684
|
return parseClientModuleView(value);
|
|
@@ -7660,6 +7838,7 @@ window.__ModuleLoader__.load({
|
|
|
7660
7838
|
let measurementController;
|
|
7661
7839
|
let generation = 0;
|
|
7662
7840
|
let draft;
|
|
7841
|
+
let catalogRevision;
|
|
7663
7842
|
let unconfirmedWrite = false;
|
|
7664
7843
|
const expansion = /* @__PURE__ */ new Map([
|
|
7665
7844
|
["extensions", true],
|
|
@@ -7831,12 +8010,13 @@ window.__ModuleLoader__.load({
|
|
|
7831
8010
|
};
|
|
7832
8011
|
const render = (view) => {
|
|
7833
8012
|
draft = new ClientModuleDraft(view.entries, view.excludedClientModules);
|
|
8013
|
+
catalogRevision = view.revision;
|
|
7834
8014
|
source.textContent = view.source === "device" ? copy.deviceSource : view.source === "computer" ? copy.computerSource : copy.pluginSource;
|
|
7835
8015
|
renderList();
|
|
7836
8016
|
};
|
|
7837
8017
|
const failed = (error, mutation) => {
|
|
7838
8018
|
status.classList.add("dsh-module-error");
|
|
7839
|
-
status.textContent = error instanceof ClientModuleUiConflict ? `${copy.conflict}${error.detail}` : error instanceof ClientModuleRequestTimeout ? error.mutation ? copy.writeTimeout : copy.readTimeout : mutation ? copy.saveFailed : copy.failed;
|
|
8019
|
+
status.textContent = error instanceof ClientModuleUiConflict ? error.code === "catalog_changed" ? copy.catalogChanged : `${copy.conflict}${error.detail}` : error instanceof ClientModuleRequestTimeout ? error.mutation ? copy.writeTimeout : copy.readTimeout : mutation ? copy.saveFailed : copy.failed;
|
|
7840
8020
|
status.focus({ preventScroll: true });
|
|
7841
8021
|
};
|
|
7842
8022
|
const runRequest = (payload) => {
|
|
@@ -7878,13 +8058,24 @@ window.__ModuleLoader__.load({
|
|
|
7878
8058
|
search.addEventListener("input", renderList);
|
|
7879
8059
|
filter.addEventListener("change", renderList);
|
|
7880
8060
|
save.addEventListener("click", () => {
|
|
7881
|
-
if ((draft?.changeCount ?? 0) > 0) runRequest({
|
|
8061
|
+
if ((draft?.changeCount ?? 0) > 0) runRequest({
|
|
8062
|
+
excludedClientModules: draft?.excludedIds,
|
|
8063
|
+
...catalogRevision === void 0 ? {} : { revision: catalogRevision }
|
|
8064
|
+
});
|
|
7882
8065
|
});
|
|
7883
8066
|
reset.addEventListener("click", () => {
|
|
7884
8067
|
if (busy === void 0 && draft !== void 0 && window.confirm(copy.resetConfirm)) runRequest({ reset: true });
|
|
7885
8068
|
});
|
|
7886
8069
|
minimal.addEventListener("click", () => {
|
|
7887
|
-
if (busy !== void 0 || draft === void 0
|
|
8070
|
+
if (busy !== void 0 || draft === void 0) return;
|
|
8071
|
+
const impact = clientModuleMinimalImpact(draft.entries);
|
|
8072
|
+
const detail = copy.minimalDetail.replace("{count}", String(impact.count)).replace("{size}", impact.gzipBytes === void 0 ? "—" : formatClientModuleSize({
|
|
8073
|
+
id: "",
|
|
8074
|
+
required: false,
|
|
8075
|
+
dependencies: [],
|
|
8076
|
+
gzipBytes: impact.gzipBytes
|
|
8077
|
+
}) ?? "—").replace("{unknown}", String(impact.unknown));
|
|
8078
|
+
if (!window.confirm(`${copy.minimalConfirm}\n\n${detail}`)) return;
|
|
7888
8079
|
if (draft.applyMinimalSelection()) {
|
|
7889
8080
|
renderList();
|
|
7890
8081
|
search.focus({ preventScroll: true });
|
|
@@ -7963,8 +8154,7 @@ window.__ModuleLoader__.load({
|
|
|
7963
8154
|
}
|
|
7964
8155
|
}, copy.open));
|
|
7965
8156
|
}
|
|
7966
|
-
|
|
7967
|
-
//#region src/extension-recovery-ui.ts
|
|
8157
|
+
// src/extension-recovery-ui.ts
|
|
7968
8158
|
/** Validate the Host response and select only stopped workers, never in-process hosts. */
|
|
7969
8159
|
function parseUnavailableExtensionHosts(payload) {
|
|
7970
8160
|
if (typeof payload !== "object" || payload === null || !("hosts" in payload) || !Array.isArray(payload.hosts)) return void 0;
|
|
@@ -8166,8 +8356,7 @@ window.__ModuleLoader__.load({
|
|
|
8166
8356
|
.dsh-mobile-control__extension-recovery button:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active,var(--dsw-alias-interactive-bg-hover))}
|
|
8167
8357
|
.dsh-mobile-control__extension-recovery .dsh-mobile-control__extension-recovery-error{color:var(--dsw-alias-label-primary)}
|
|
8168
8358
|
`;
|
|
8169
|
-
|
|
8170
|
-
//#region src/native-capability.ts
|
|
8359
|
+
// src/native-capability.ts
|
|
8171
8360
|
/** Cancel queued calls before native effects start; started effects are not rolled back. */
|
|
8172
8361
|
function invokeBoundNativeCapability(bridge, currentBridge, action, input, signal) {
|
|
8173
8362
|
const abortReason = () => signal.reason ?? new DOMException("mobile extension disposed", "AbortError");
|
|
@@ -8201,8 +8390,7 @@ window.__ModuleLoader__.load({
|
|
|
8201
8390
|
});
|
|
8202
8391
|
});
|
|
8203
8392
|
}
|
|
8204
|
-
|
|
8205
|
-
//#region src/mobile-custom-assets.ts
|
|
8393
|
+
// src/mobile-custom-assets.ts
|
|
8206
8394
|
const COPY = {
|
|
8207
8395
|
en: {
|
|
8208
8396
|
gateway_required: "Custom mobile CSS, scripts and extensions require a paired DSH Mobile access entry. This page is not using the Mobile gateway.",
|
|
@@ -8342,8 +8530,7 @@ window.__ModuleLoader__.load({
|
|
|
8342
8530
|
reader.releaseLock();
|
|
8343
8531
|
}
|
|
8344
8532
|
}
|
|
8345
|
-
|
|
8346
|
-
//#region src/mobile-customization-notice.ts
|
|
8533
|
+
// src/mobile-customization-notice.ts
|
|
8347
8534
|
/** Copy for the notice, per locale, kept beside the existing dictionaries. */
|
|
8348
8535
|
const NOTICE_COPY = {
|
|
8349
8536
|
en: {
|
|
@@ -8461,8 +8648,7 @@ window.__ModuleLoader__.load({
|
|
|
8461
8648
|
style.remove();
|
|
8462
8649
|
};
|
|
8463
8650
|
}
|
|
8464
|
-
|
|
8465
|
-
//#region src/extension-limits.ts
|
|
8651
|
+
// src/extension-limits.ts
|
|
8466
8652
|
/** Maximum sizes accepted for legacy mobile customization resources. */
|
|
8467
8653
|
const LEGACY_CUSTOM_ASSET_LIMIT = 262144;
|
|
8468
8654
|
/** Maximum sizes enforced when reading local extension files. */
|
|
@@ -8475,8 +8661,7 @@ window.__ModuleLoader__.load({
|
|
|
8475
8661
|
assetBytes: 33554432,
|
|
8476
8662
|
assetDepth: 8
|
|
8477
8663
|
});
|
|
8478
|
-
|
|
8479
|
-
//#region src/client-recovery.ts
|
|
8664
|
+
// src/client-recovery.ts
|
|
8480
8665
|
/** Only a visible, disconnected public transport needs an immediate resume nudge. */
|
|
8481
8666
|
function shouldNudgeReconnect(visibility, connection) {
|
|
8482
8667
|
return visibility === "visible" && connection !== "connected";
|
|
@@ -8656,15 +8841,13 @@ window.__ModuleLoader__.load({
|
|
|
8656
8841
|
onRejected?.(rejected, retry);
|
|
8657
8842
|
return dispose;
|
|
8658
8843
|
}
|
|
8659
|
-
|
|
8660
|
-
//#region src/browser-ui-locale.ts
|
|
8844
|
+
// src/browser-ui-locale.ts
|
|
8661
8845
|
const UI_LOCALE_COOKIE = "dsh_ma_ui_locale";
|
|
8662
8846
|
/** Host-only, non-secret preference, independent of the short authentication session. */
|
|
8663
8847
|
function browserUiLocaleCookie(locale, secure) {
|
|
8664
8848
|
return `${UI_LOCALE_COOKIE}=${locale}; Path=/mobile-access; Max-Age=31536000; SameSite=Lax${secure ? "; Secure" : ""}`;
|
|
8665
8849
|
}
|
|
8666
|
-
|
|
8667
|
-
//#region src/mobile-ui-locale.ts
|
|
8850
|
+
// src/mobile-ui-locale.ts
|
|
8668
8851
|
/** Remember the DSH display language only on authenticated Mobile Gateway documents. */
|
|
8669
8852
|
function installMobileUiLocalePersistence(page, view) {
|
|
8670
8853
|
if (page.querySelector("meta[name=\"dsh-mobile-gateway\"][content=\"authenticated\"]") === null) return () => {};
|
|
@@ -8693,8 +8876,7 @@ window.__ModuleLoader__.load({
|
|
|
8693
8876
|
observer.disconnect();
|
|
8694
8877
|
};
|
|
8695
8878
|
}
|
|
8696
|
-
|
|
8697
|
-
//#region src/mobile-push/browser-api.ts
|
|
8879
|
+
// src/mobile-push/browser-api.ts
|
|
8698
8880
|
function apiError(code) {
|
|
8699
8881
|
return Object.assign(/* @__PURE__ */ new Error(code === "stale_generation" ? "Push settings changed elsewhere." : "Push request failed."), { code });
|
|
8700
8882
|
}
|
|
@@ -8760,16 +8942,14 @@ window.__ModuleLoader__.load({
|
|
|
8760
8942
|
}
|
|
8761
8943
|
};
|
|
8762
8944
|
}
|
|
8763
|
-
|
|
8764
|
-
//#region src/mobile-push/installation-id.ts
|
|
8945
|
+
// src/mobile-push/installation-id.ts
|
|
8765
8946
|
/** Browser-safe installation-id validation shared by the browser controller and the Gateway. */
|
|
8766
8947
|
const INSTALLATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
8767
8948
|
/** True only for a UUID-shaped installation id with an allowed version and variant nibble. */
|
|
8768
8949
|
function isPushInstallationId(value) {
|
|
8769
8950
|
return typeof value === "string" && INSTALLATION_ID.test(value);
|
|
8770
8951
|
}
|
|
8771
|
-
|
|
8772
|
-
//#region src/mobile-push/client.ts
|
|
8952
|
+
// src/mobile-push/client.ts
|
|
8773
8953
|
const ID_KEY = "dsh-mobile-push-installation";
|
|
8774
8954
|
const defaults = Object.freeze({
|
|
8775
8955
|
question: true,
|
|
@@ -9204,8 +9384,7 @@ window.__ModuleLoader__.load({
|
|
|
9204
9384
|
locale: view.document.documentElement.lang.toLowerCase().startsWith("zh") ? "zh-CN" : view.document.documentElement.lang.toLowerCase().startsWith("it") ? "it" : "en"
|
|
9205
9385
|
};
|
|
9206
9386
|
}
|
|
9207
|
-
|
|
9208
|
-
//#region src/mobile-push/switch-component.ts
|
|
9387
|
+
// src/mobile-push/switch-component.ts
|
|
9209
9388
|
/**
|
|
9210
9389
|
* Lazily require the public Switch from the DSH module loader at category render time.
|
|
9211
9390
|
*
|
|
@@ -9225,8 +9404,7 @@ window.__ModuleLoader__.load({
|
|
|
9225
9404
|
return;
|
|
9226
9405
|
}
|
|
9227
9406
|
}
|
|
9228
|
-
|
|
9229
|
-
//#region src/mobile-push/settings.ts
|
|
9407
|
+
// src/mobile-push/settings.ts
|
|
9230
9408
|
const MOBILE_PUSH_SETTINGS_COPY = {
|
|
9231
9409
|
en: {
|
|
9232
9410
|
title: "Web push notifications",
|
|
@@ -9386,8 +9564,7 @@ window.__ModuleLoader__.load({
|
|
|
9386
9564
|
disabled: true
|
|
9387
9565
|
}, copy.busy)));
|
|
9388
9566
|
}
|
|
9389
|
-
|
|
9390
|
-
//#region src/mobile-push/navigation.ts
|
|
9567
|
+
// src/mobile-push/navigation.ts
|
|
9391
9568
|
const REF_PARAMETER = "mobile-push";
|
|
9392
9569
|
/**
|
|
9393
9570
|
* Consume one authenticated tap reference after the public Workspace and Session
|
|
@@ -9466,8 +9643,7 @@ window.__ModuleLoader__.load({
|
|
|
9466
9643
|
const snapshot = ctx.sessions.list.getSnapshot();
|
|
9467
9644
|
return snapshot.phase === "ready" && snapshot.ids.includes(sessionId) && snapshot.byId[sessionId] !== void 0;
|
|
9468
9645
|
}
|
|
9469
|
-
|
|
9470
|
-
//#region src/mobile-directory-browser.ts
|
|
9646
|
+
// src/mobile-directory-browser.ts
|
|
9471
9647
|
/** Expected Gateway or response-validation failure for one read-only listing. */
|
|
9472
9648
|
var MobileDirectoryReadError = class extends Error {
|
|
9473
9649
|
code;
|
|
@@ -9861,8 +10037,7 @@ window.__ModuleLoader__.load({
|
|
|
9861
10037
|
for (const listener of this.listeners) listener();
|
|
9862
10038
|
}
|
|
9863
10039
|
};
|
|
9864
|
-
|
|
9865
|
-
//#region src/mobile-directory-picker.ts
|
|
10040
|
+
// src/mobile-directory-picker.ts
|
|
9866
10041
|
/** Dedicated Mobile directory-flow occupant; stock DSH retains its own chooser. */
|
|
9867
10042
|
const MESSAGES = {
|
|
9868
10043
|
zh: {
|
|
@@ -10534,8 +10709,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
10534
10709
|
if (failures.length > 0) throw new AggregateError(failures, "Mobile directory picker disposal failed");
|
|
10535
10710
|
};
|
|
10536
10711
|
}
|
|
10537
|
-
|
|
10538
|
-
//#region src/client.ts
|
|
10712
|
+
// src/client.ts
|
|
10539
10713
|
/** Map a host-reported provider onto the UI union, defaulting to the built-in one. */
|
|
10540
10714
|
function parseMobileRemoteProvider(value) {
|
|
10541
10715
|
return value === "cpolar" || value === "cloudflared" || value === "frp" || value === "origin" || value === "iroh" ? value : "tailscale";
|
|
@@ -10619,7 +10793,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
10619
10793
|
const wrapper = top.parentElement;
|
|
10620
10794
|
const mask = wrapper?.firstElementChild;
|
|
10621
10795
|
const maskStyle = mask === void 0 || mask === null ? void 0 : view.getComputedStyle(mask);
|
|
10622
|
-
if (wrapper?.getAttribute("role") === "presentation" && wrapper.children.length === 2 && wrapper.lastElementChild === top && mask?.tagName === "DIV" && mask.getAttribute("aria-hidden") === "
|
|
10796
|
+
if (wrapper?.getAttribute("role") === "presentation" && wrapper.children.length === 2 && wrapper.lastElementChild === top && mask?.tagName === "DIV" && mask.getAttribute("aria-hidden") !== "false" && mask.getAttribute("role") === null && mask.getAttribute("tabindex") === null && mask.getAttribute("contenteditable") === null && mask.children.length === 0 && (mask.textContent ?? "").trim() === "" && mask.isConnected && !mask.hidden && maskStyle?.display !== "none" && maskStyle?.visibility !== "hidden" && mask.getClientRects().length > 0) {
|
|
10623
10797
|
mask.click();
|
|
10624
10798
|
return;
|
|
10625
10799
|
}
|
|
@@ -11227,7 +11401,8 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
11227
11401
|
const facts = entry.facts !== null && typeof entry.facts === "object" ? entry.facts : {};
|
|
11228
11402
|
const copyReason = facts.viaProxy === true && (reason === "remote-ready" || reason === "remote-rate-limited") ? `${reason}-via-proxy` : reason;
|
|
11229
11403
|
const catalog = DIAGNOSTIC_REASON_MESSAGES[locale];
|
|
11230
|
-
const
|
|
11404
|
+
const networkCatalog = DIAGNOSTIC_NETWORK_MESSAGES[locale];
|
|
11405
|
+
const templates = Object.prototype.hasOwnProperty.call(networkCatalog, copyReason) ? networkCatalog[copyReason] : Object.prototype.hasOwnProperty.call(catalog, copyReason) ? catalog[copyReason] : void 0;
|
|
11231
11406
|
if (templates === void 0) return serverCopy;
|
|
11232
11407
|
const providerNames = {
|
|
11233
11408
|
tailscale: "Tailscale Funnel",
|
|
@@ -11250,6 +11425,15 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
11250
11425
|
const interpolate = (template) => template.replace(/\{(\w+)\}/gu, (_match, key) => values[key] ?? "");
|
|
11251
11426
|
let detail = reason === "remote-controller-error" && controllerCode === "" ? t("remoteError") : interpolate(templates[0]);
|
|
11252
11427
|
let action = interpolate(templates[1]);
|
|
11428
|
+
if (reason.startsWith("dns-")) {
|
|
11429
|
+
const families = {
|
|
11430
|
+
ipv4: "IPv4",
|
|
11431
|
+
ipv6: "IPv6",
|
|
11432
|
+
dual: "IPv4 + IPv6"
|
|
11433
|
+
};
|
|
11434
|
+
const family = typeof facts.dnsFamily === "string" && Object.hasOwn(families, facts.dnsFamily) ? families[facts.dnsFamily] : void 0;
|
|
11435
|
+
if (family !== void 0) detail += ` (${family})`;
|
|
11436
|
+
}
|
|
11253
11437
|
if (reason === "versions-current") {
|
|
11254
11438
|
const fields = versions !== null && typeof versions === "object" ? versions : {};
|
|
11255
11439
|
if ([
|
|
@@ -11395,6 +11579,31 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
11395
11579
|
const lanSetupStatus = element("p", "dsh-mobile-control__status");
|
|
11396
11580
|
lanSetupStatus.setAttribute("role", "status");
|
|
11397
11581
|
lanSetupStatus.setAttribute("aria-live", "polite");
|
|
11582
|
+
const lanChange = element("section", "dsh-mobile-control__lan-setup");
|
|
11583
|
+
lanChange.hidden = true;
|
|
11584
|
+
const lanChangeTitle = element("h3", "dsh-mobile-control__section-title");
|
|
11585
|
+
lanChangeTitle.textContent = t("lanChangeTitle");
|
|
11586
|
+
const lanChangeIntro = element("p", "dsh-mobile-control__intro");
|
|
11587
|
+
lanChangeIntro.textContent = t("lanChangeIntro");
|
|
11588
|
+
const lanChangeForm = element("div", "dsh-mobile-control__lan-setup-form");
|
|
11589
|
+
const lanChangeLabel = element("label", "dsh-mobile-control__field");
|
|
11590
|
+
lanChangeLabel.textContent = t("lanChangeSelect");
|
|
11591
|
+
const lanChangeSelect = element("select");
|
|
11592
|
+
lanChangeSelect.setAttribute("aria-label", t("lanChangeSelect"));
|
|
11593
|
+
lanChangeLabel.append(lanChangeSelect);
|
|
11594
|
+
const lanChangeActions = element("div", "dsh-mobile-control__lan-setup-actions");
|
|
11595
|
+
const lanChangeRefresh = element("button", "dsh-mobile-control__secondary");
|
|
11596
|
+
lanChangeRefresh.type = "button";
|
|
11597
|
+
lanChangeRefresh.textContent = t("lanChangeRefresh");
|
|
11598
|
+
const lanChangeConfirm = element("button", "dsh-mobile-control__primary");
|
|
11599
|
+
lanChangeConfirm.type = "button";
|
|
11600
|
+
lanChangeConfirm.textContent = t("lanChangeConfirm");
|
|
11601
|
+
lanChangeActions.append(lanChangeRefresh, lanChangeConfirm);
|
|
11602
|
+
const lanChangeStatus = element("p", "dsh-mobile-control__status");
|
|
11603
|
+
lanChangeStatus.setAttribute("role", "status");
|
|
11604
|
+
lanChangeStatus.setAttribute("aria-live", "polite");
|
|
11605
|
+
lanChangeForm.append(lanChangeLabel, lanChangeActions);
|
|
11606
|
+
lanChange.append(lanChangeTitle, lanChangeIntro, lanChangeForm, lanChangeStatus);
|
|
11398
11607
|
const trustedNetworks = element("details", "dsh-mobile-control__details");
|
|
11399
11608
|
const trustedNetworksSummary = element("summary");
|
|
11400
11609
|
trustedNetworksSummary.textContent = t("trustedNetworksTitle");
|
|
@@ -12730,7 +12939,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
12730
12939
|
diagnosticsDetails.append(diagnosticsDetailsSummary, diagnosticsReport);
|
|
12731
12940
|
header.append(title, headerActions);
|
|
12732
12941
|
actions.append(toggle, pair, linkPair);
|
|
12733
|
-
lanView.append(lanSetup, access, qrBox, lanPairingValidity, status, extensionStatus, actions, trustedNetworks);
|
|
12942
|
+
lanView.append(lanSetup, lanChange, access, qrBox, lanPairingValidity, status, extensionStatus, actions, trustedNetworks);
|
|
12734
12943
|
const channelPane = element("div", "dsh-mobile-control__channel-pane");
|
|
12735
12944
|
channelPane.append(lanView, remoteWorkspace);
|
|
12736
12945
|
const remoteColumns = element("div", "dsh-mobile-control__remote-columns");
|
|
@@ -12745,6 +12954,9 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
12745
12954
|
let lanConfigured = true;
|
|
12746
12955
|
let lanRestartRequired = false;
|
|
12747
12956
|
let lanSetupLoaded = false;
|
|
12957
|
+
let lanChangeLoaded = false;
|
|
12958
|
+
let lanChangeBusy = false;
|
|
12959
|
+
let lanChangeRequest;
|
|
12748
12960
|
let remoteRunning = false;
|
|
12749
12961
|
let remoteReady = false;
|
|
12750
12962
|
let remoteProvider = "tailscale";
|
|
@@ -12961,6 +13173,8 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
12961
13173
|
lanChoiceBadge.textContent = running ? t("lanBadgeOn") : t("lanBadgeOff");
|
|
12962
13174
|
origin = running && typeof data.origin === "string" ? data.origin : "";
|
|
12963
13175
|
lanSetup.hidden = lanConfigured && !lanRestartRequired;
|
|
13176
|
+
lanChange.hidden = !lanConfigured || lanRestartRequired || data.rebindSupported !== true;
|
|
13177
|
+
if (!lanChange.hidden && !lanChangeLoaded) loadLanChange();
|
|
12964
13178
|
lanSetupForm.hidden = lanRestartRequired;
|
|
12965
13179
|
lanSetupIntro.hidden = lanRestartRequired;
|
|
12966
13180
|
status.hidden = !lanConfigured || lanRestartRequired;
|
|
@@ -12974,7 +13188,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
12974
13188
|
accessLink.textContent = origin;
|
|
12975
13189
|
accessLink.title = origin;
|
|
12976
13190
|
status.classList.toggle("is-running", running);
|
|
12977
|
-
status.textContent = !lanConfigured ? t("lanSetupRequired") : lanRestartRequired ? t("lanSetupRestart", { origin: typeof data.pendingOrigin === "string" ? data.pendingOrigin : "" }) : running ? t("lanOn") : t("lanOff");
|
|
13191
|
+
status.textContent = data.recoveryRequired === true ? t("lanChangeRecoveryRequired") : !lanConfigured ? t("lanSetupRequired") : lanRestartRequired ? t("lanSetupRestart", { origin: typeof data.pendingOrigin === "string" ? data.pendingOrigin : "" }) : running ? t("lanOn") : t("lanOff");
|
|
12978
13192
|
const extensionData = data.extensions;
|
|
12979
13193
|
if (extensionData !== null && typeof extensionData === "object") {
|
|
12980
13194
|
const loaded = typeof extensionData.loaded === "number" ? extensionData.loaded : 0;
|
|
@@ -13065,6 +13279,80 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
13065
13279
|
lanSetupConfigure.disabled = lanRestartRequired || lanSetupSelect.options.length === 0;
|
|
13066
13280
|
});
|
|
13067
13281
|
});
|
|
13282
|
+
const syncLanChange = () => {
|
|
13283
|
+
const waiting = lanChangeBusy || lanChangeRequest !== void 0;
|
|
13284
|
+
lanChangeSelect.disabled = waiting;
|
|
13285
|
+
lanChangeRefresh.disabled = waiting;
|
|
13286
|
+
lanChangeConfirm.disabled = waiting || lanChangeSelect.options.length === 0;
|
|
13287
|
+
};
|
|
13288
|
+
const renderLanChange = (data) => {
|
|
13289
|
+
const networks = Array.isArray(data.networks) ? data.networks.filter((entry) => typeof entry === "object" && entry !== null) : [];
|
|
13290
|
+
lanChangeSelect.replaceChildren();
|
|
13291
|
+
for (const network of networks) {
|
|
13292
|
+
const name = typeof network.name === "string" ? network.name : "";
|
|
13293
|
+
const address = typeof network.address === "string" ? network.address : "";
|
|
13294
|
+
if (name === "") continue;
|
|
13295
|
+
const option = element("option");
|
|
13296
|
+
option.value = name;
|
|
13297
|
+
option.textContent = `${name} · ${address}${network.current === true ? ` · ${t("lanChangeCurrent")}` : ""}`;
|
|
13298
|
+
if (network.current === true) option.selected = true;
|
|
13299
|
+
lanChangeSelect.append(option);
|
|
13300
|
+
}
|
|
13301
|
+
syncLanChange();
|
|
13302
|
+
};
|
|
13303
|
+
const loadLanChange = () => {
|
|
13304
|
+
if (lanChangeRequest !== void 0) return lanChangeRequest;
|
|
13305
|
+
lanChangeLoaded = true;
|
|
13306
|
+
lanChangeRequest = Promise.all([controlRequestJson("/api/mobile-access/lan/networks"), controlRequestJson("/api/mobile-access/lan/control")]).then(([data, control]) => {
|
|
13307
|
+
if (!lifecycle.signal.aborted) {
|
|
13308
|
+
renderLanChange(data);
|
|
13309
|
+
render(control);
|
|
13310
|
+
}
|
|
13311
|
+
}, () => {
|
|
13312
|
+
if (!lifecycle.signal.aborted) lanChangeStatus.textContent = t("lanChangeRefreshFailed");
|
|
13313
|
+
}).finally(() => {
|
|
13314
|
+
lanChangeRequest = void 0;
|
|
13315
|
+
if (!lifecycle.signal.aborted) syncLanChange();
|
|
13316
|
+
});
|
|
13317
|
+
syncLanChange();
|
|
13318
|
+
return lanChangeRequest;
|
|
13319
|
+
};
|
|
13320
|
+
lanChangeRefresh.addEventListener("click", () => {
|
|
13321
|
+
loadLanChange();
|
|
13322
|
+
});
|
|
13323
|
+
lanChangeSelect.addEventListener("change", syncLanChange);
|
|
13324
|
+
lanChangeConfirm.addEventListener("click", () => {
|
|
13325
|
+
if (lanChangeSelect.value === "" || lanChangeBusy || lanChangeRequest !== void 0) return;
|
|
13326
|
+
lanChangeBusy = true;
|
|
13327
|
+
syncLanChange();
|
|
13328
|
+
lanChangeConfirm.textContent = t("lanChangeBusy");
|
|
13329
|
+
lanChangeStatus.textContent = t("lanChangeBusy");
|
|
13330
|
+
controlRequestJson("/api/mobile-access/lan/rebind", {
|
|
13331
|
+
method: "POST",
|
|
13332
|
+
body: JSON.stringify({ networkInterface: lanChangeSelect.value })
|
|
13333
|
+
}, LONG_CONTROL_REQUEST_TIMEOUT_MS).then(async (data) => {
|
|
13334
|
+
if (lifecycle.signal.aborted) return;
|
|
13335
|
+
lanChangeStatus.textContent = data.disconnected === true && data.ready === true ? t("lanChangeOkDisconnected") : t("lanChangeOk");
|
|
13336
|
+
try {
|
|
13337
|
+
const control = await controlRequestJson("/api/mobile-access/lan/control");
|
|
13338
|
+
if (lifecycle.signal.aborted) return;
|
|
13339
|
+
render(control);
|
|
13340
|
+
await loadLanChange();
|
|
13341
|
+
if (!lifecycle.signal.aborted && data.ready === true) openPairing("key");
|
|
13342
|
+
} catch {
|
|
13343
|
+
if (!lifecycle.signal.aborted) lanChangeStatus.textContent = t("lanChangeRefreshFailed");
|
|
13344
|
+
}
|
|
13345
|
+
}, (error) => {
|
|
13346
|
+
if (lifecycle.signal.aborted) return;
|
|
13347
|
+
const text = String(error);
|
|
13348
|
+
lanChangeStatus.textContent = text.includes("lan_rebind_unchanged") ? t("lanChangeUnchanged") : text.includes("lan_rebind_network_unavailable") ? t("lanChangeUnavailable") : text.includes("lan_rebind_unsupported") ? t("lanChangeUnsupported") : text.includes("lan_rebind_recovery_required") ? t("lanChangeRecoveryRequired") : t("lanChangeFailed");
|
|
13349
|
+
}).finally(() => {
|
|
13350
|
+
lanChangeBusy = false;
|
|
13351
|
+
if (lifecycle.signal.aborted) return;
|
|
13352
|
+
lanChangeConfirm.textContent = t("lanChangeConfirm");
|
|
13353
|
+
syncLanChange();
|
|
13354
|
+
});
|
|
13355
|
+
});
|
|
13068
13356
|
const clearQrTarget = (target) => {
|
|
13069
13357
|
if (typeof target.replaceChildren === "function") {
|
|
13070
13358
|
target.replaceChildren();
|
|
@@ -13384,6 +13672,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
13384
13672
|
const attachSelected = frpMode.value === "attach";
|
|
13385
13673
|
const selfSignedSelected = attachSelected && frpEntryTls.value === "self-signed";
|
|
13386
13674
|
frpStep2Title.textContent = t(attachSelected ? "frpStep2TitleAttach" : "frpStep2Title");
|
|
13675
|
+
frpVpsSummary.textContent = t(attachSelected ? "frpStep2TitleAttach" : "frpStep2Title");
|
|
13387
13676
|
frpStep2Text.textContent = attachSelected && configuredFrpProxyName === void 0 ? t("loadingRemoteStatus") : t(attachSelected ? "frpStep2TextAttach" : "frpStep2Text");
|
|
13388
13677
|
frpStep4Text.textContent = t(attachSelected ? "frpStep4TextAttach" : "frpStep4Text");
|
|
13389
13678
|
frpAppRequirement.textContent = t(selfSignedSelected ? "frpAppRequirementSelfSigned" : "frpAppRequirement");
|
|
@@ -15091,11 +15380,13 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
15091
15380
|
});
|
|
15092
15381
|
});
|
|
15093
15382
|
const renderDiagnostics = (data) => {
|
|
15383
|
+
const scopeCopy = DIAGNOSTIC_SCOPE_MESSAGES[locale];
|
|
15384
|
+
const scopeOf = (entry) => entry.scope === "configuration" || entry.id === "versions" ? scopeCopy.configuration : entry.scope === "phone" || entry.id === "phone-network" ? scopeCopy.phone : scopeCopy.computer;
|
|
15094
15385
|
const entries = [...diagnosticEntriesForRender(data)];
|
|
15095
15386
|
const overall = diagnosticOverallForChecks(data.overall, entries.map((entry) => entry.status));
|
|
15096
15387
|
diagnosticsSummary.className = `dsh-mobile-control__diagnostic-summary is-${overall}`;
|
|
15097
|
-
diagnosticsSummaryTitle.textContent = overall === "ok" ? t("diagnosticsComplete") : overall === "attention" ? t("diagnosticsAttention") : t("diagnosticsProblem")
|
|
15098
|
-
diagnosticsSummaryText.textContent =
|
|
15388
|
+
diagnosticsSummaryTitle.textContent = `${scopeCopy.computer} · ${overall === "ok" ? t("diagnosticsComplete") : overall === "attention" ? t("diagnosticsAttention") : t("diagnosticsProblem")}`;
|
|
15389
|
+
diagnosticsSummaryText.textContent = scopeCopy.coverage;
|
|
15099
15390
|
diagnosticsChecks.replaceChildren();
|
|
15100
15391
|
const statusLabels = {
|
|
15101
15392
|
ok: t("diagnosticStatusOk"),
|
|
@@ -15140,8 +15431,14 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
15140
15431
|
const localizedCopy = localizedEntryCopy(entry);
|
|
15141
15432
|
const detail = element("p");
|
|
15142
15433
|
detail.textContent = localizedCopy.detail;
|
|
15434
|
+
if (entry.id === "versions") rowTitle.textContent = scopeCopy.versions;
|
|
15435
|
+
else if (entry.id === "remote-service") rowTitle.textContent = scopeCopy.provider;
|
|
15436
|
+
else if (entry.id === "remote-dns") rowTitle.textContent = scopeCopy.dns;
|
|
15437
|
+
else if (entry.id === "plugin-inspection" || entry.id === "remote-plugin-conflict") rowTitle.textContent = scopeCopy.scripts;
|
|
15438
|
+
const scope = element("small", "dsh-mobile-control__diagnostic-scope");
|
|
15439
|
+
scope.textContent = scopeOf(entry);
|
|
15143
15440
|
rowHeader.append(rowTitle, badge);
|
|
15144
|
-
rowBody.append(rowHeader, detail);
|
|
15441
|
+
rowBody.append(rowHeader, scope, detail);
|
|
15145
15442
|
if (localizedCopy.action !== "") {
|
|
15146
15443
|
const action = element("p", "dsh-mobile-control__diagnostic-action");
|
|
15147
15444
|
const actionLabel = element("span");
|
|
@@ -15171,11 +15468,13 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
15171
15468
|
const labelKey = typeof entry.id === "string" ? diagnosticLabelKeys[entry.id] : void 0;
|
|
15172
15469
|
const label = labelKey === void 0 && typeof entry.label === "string" ? entry.label : labelKey === void 0 ? t("diagnosticCheck") : t(labelKey);
|
|
15173
15470
|
const localizedCopy = localizedEntryCopy(entry);
|
|
15174
|
-
|
|
15471
|
+
const scopedLabel = entry.id === "versions" ? scopeCopy.versions : entry.id === "remote-service" ? scopeCopy.provider : entry.id === "remote-dns" ? scopeCopy.dns : entry.id === "plugin-inspection" || entry.id === "remote-plugin-conflict" ? scopeCopy.scripts : label;
|
|
15472
|
+
return `[${statusLabels[state]}][${scopeOf(entry)}] ${scopedLabel}: ${localizedCopy.detail}${localizedCopy.action === "" ? "" : ` ${localizedCopy.action}`}`;
|
|
15175
15473
|
});
|
|
15176
15474
|
copiedDiagnosticReport = [
|
|
15177
15475
|
reportCopy.reportTitle,
|
|
15178
15476
|
`${reportCopy.generated}: ${generatedAt}`,
|
|
15477
|
+
scopeCopy.coverage,
|
|
15179
15478
|
...lines
|
|
15180
15479
|
].join("\n");
|
|
15181
15480
|
diagnosticsReport.textContent = copiedDiagnosticReport;
|
|
@@ -16285,6 +16584,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
16285
16584
|
manifestEtag = "";
|
|
16286
16585
|
};
|
|
16287
16586
|
const refreshExtensions = async (signal) => {
|
|
16587
|
+
let failureStage = "manifest_unavailable";
|
|
16288
16588
|
try {
|
|
16289
16589
|
const headers = {};
|
|
16290
16590
|
if (manifestEtag !== "") headers["if-none-match"] = manifestEtag;
|
|
@@ -16327,6 +16627,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
16327
16627
|
failed("manifest_invalid", signal);
|
|
16328
16628
|
return false;
|
|
16329
16629
|
}
|
|
16630
|
+
failureStage = "resource_unavailable";
|
|
16330
16631
|
events?.setEnabled(true);
|
|
16331
16632
|
const entries = payload.extensions;
|
|
16332
16633
|
const seen = new Set(entries.map((entry) => entry.id));
|
|
@@ -16486,7 +16787,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
16486
16787
|
} else manifestEtag = "";
|
|
16487
16788
|
return refreshComplete;
|
|
16488
16789
|
} catch {
|
|
16489
|
-
failed(
|
|
16790
|
+
failed(failureStage, signal);
|
|
16490
16791
|
return false;
|
|
16491
16792
|
}
|
|
16492
16793
|
};
|
|
@@ -16618,7 +16919,7 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
16618
16919
|
style rule of its own. */
|
|
16619
16920
|
.dsh-mobile-control__cpolar-setup{margin:0 0 12px;padding:12px;border:1px solid var(--dsw-alias-border-l2,#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__progress{box-sizing:border-box;width:100%;height:6px;margin:0 0 10px}.dsh-mobile-control__progress[hidden]{display:none}.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:var(--dsw-alias-label-primary-bluish,#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-l3,#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-l2,#e1e5eb);padding-top:9px}.dsh-mobile-control__details>summary{min-height:36px;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:11px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;text-overflow:ellipsis;white-space:nowrap}.dsh-mobile-control__danger{flex:1 0 100%;min-height:44px;margin-top:3px;padding:7px 10px;border:1px solid var(--dsw-alias-state-error-primary,#dc2626);border-radius:9px;background:transparent;color:var(--dsw-alias-label-primary,#dc2626);font:12px/1.3 system-ui;cursor:pointer}
|
|
16620
16921
|
.dsh-mobile-control__danger:hover:not(:disabled),.dsh-mobile-control__device-revoke:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgb(220 38 38 / 8%))}
|
|
16621
|
-
.dsh-mobile-control__frp-setup{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-l2,#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-l2,#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__frp-fields>.dsh-mobile-control__field:nth-child(5),.dsh-mobile-control__frp-fields>.dsh-mobile-control__field:nth-child(6){grid-column:1/-1}.dsh-mobile-control__frp-fields>.dsh-mobile-control__field[hidden]{display:none}.dsh-mobile-control__frp-fields select{box-sizing:border-box;width:100%;min-height:44px;padding:9px 32px 9px 10px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:14px/1.4 system-ui}.dsh-mobile-control__frp-fields select:disabled{cursor:not-allowed;opacity:.55}.dsh-mobile-control__frp-hint{margin:0;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.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-l3,#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-l2,#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 11px/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 11px/1.25 system-ui}.dsh-mobile-control__state-badge.is-ready{background:var(--dsw-alias-state-success-tertiary,#e6f7f0);color:var(--dsw-alias-label-primary,#087454)}.dsh-mobile-control__state-badge.is-busy{background:var(--dsw-alias-state-business-tertiary,#e8f0ff);color:var(--dsw-alias-label-primary,#1d4ed8)}.dsh-mobile-control__state-badge.is-attention{background:var(--dsw-alias-state-warn-tertiary,#fff4dc);color:var(--dsw-alias-label-primary,#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-l2,#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-l2,#e1e5eb)}
|
|
16922
|
+
.dsh-mobile-control__frp-setup{margin:0;padding:12px;border:1px solid var(--dsw-alias-border-l2,#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-l2,#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__frp-fields[hidden]{display:none}.dsh-mobile-control__frp-fields>.dsh-mobile-control__field:nth-child(5),.dsh-mobile-control__frp-fields>.dsh-mobile-control__field:nth-child(6){grid-column:1/-1}.dsh-mobile-control__frp-fields>.dsh-mobile-control__field[hidden]{display:none}.dsh-mobile-control__frp-fields select{box-sizing:border-box;width:100%;min-height:44px;padding:9px 32px 9px 10px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:14px/1.4 system-ui}.dsh-mobile-control__frp-fields select:disabled{cursor:not-allowed;opacity:.55}.dsh-mobile-control__frp-hint{margin:0;color:var(--dsw-alias-label-secondary,#606873);font-size:11px;line-height:1.5}.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-l3,#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-l2,#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 11px/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 11px/1.25 system-ui}.dsh-mobile-control__state-badge.is-ready{background:var(--dsw-alias-state-success-tertiary,#e6f7f0);color:var(--dsw-alias-label-primary,#087454)}.dsh-mobile-control__state-badge.is-busy{background:var(--dsw-alias-state-business-tertiary,#e8f0ff);color:var(--dsw-alias-label-primary,#1d4ed8)}.dsh-mobile-control__state-badge.is-attention{background:var(--dsw-alias-state-warn-tertiary,#fff4dc);color:var(--dsw-alias-label-primary,#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-l2,#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-l2,#e1e5eb)}
|
|
16622
16923
|
.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 var(--dsw-alias-state-success-primary,#a9dfc9);border-radius:11px;background:var(--dsw-alias-state-success-tertiary,#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:var(--dsw-alias-label-primary,#075d46);font-size:12px;line-height:1.35}.dsh-mobile-control__frp-overview-body span{overflow:hidden;color:var(--dsw-alias-label-secondary,#357061);font:11px/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-l2,#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-l2,#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-l2,#dbe1e8);border-radius:11px;background:var(--dsw-alias-bg-layer-1,#f8fafc)}.dsh-mobile-control__tunnel{margin:0 0 10px}.dsh-mobile-control__tunnel[hidden]{display:none}
|
|
16623
16924
|
.dsh-mobile-control__lan-setup{box-sizing:border-box;margin:0 0 12px;padding:14px;border:1px solid #6f96db;border-radius:15px;background:var(--dsw-alias-bg-layer-1,#f5f8ff)}.dsh-mobile-control__lan-setup[hidden],.dsh-mobile-control__lan-setup-form[hidden]{display:none}.dsh-mobile-control__lan-setup>.dsh-mobile-control__section-title{margin-bottom:5px}.dsh-mobile-control__lan-setup>.dsh-mobile-control__intro{margin-bottom:12px}.dsh-mobile-control__lan-setup-form{display:grid;gap:9px}.dsh-mobile-control__lan-setup .dsh-mobile-control__field select{box-sizing:border-box;width:100%;min-height:44px;padding:9px 32px 9px 10px;border:1px solid var(--dsw-alias-border-l3,#cfd5dd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:14px/1.4 system-ui}.dsh-mobile-control__lan-setup .dsh-mobile-control__component-note{margin:0}.dsh-mobile-control__lan-setup-actions{display:grid;grid-template-columns:1fr 1.35fr;gap:8px}.dsh-mobile-control__lan-setup-actions button{box-sizing:border-box;min-width:0;min-height:44px;padding:9px 10px;border-radius:10px;font:650 12px/1.3 system-ui;cursor:pointer}.dsh-mobile-control__lan-setup-actions button:disabled{cursor:wait;opacity:.55}.dsh-mobile-control__lan-setup>.dsh-mobile-control__status{margin:10px 0 0;line-height:1.5}.dsh-mobile-control__lan-setup>.dsh-mobile-control__status:empty{display:none}
|
|
16624
16925
|
.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:var(--dsw-alias-label-primary-bluish,#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}.dsh-mobile-control__qr.is-expandable{cursor:zoom-in}.dsh-mobile-control__qr.is-expandable:focus-visible{outline:3px solid var(--dsw-alias-state-business-primary,#2563eb);outline-offset:2px;border-radius:12px}.dsh-mobile-control__qr-zoom{position:fixed;inset:0;z-index:1001;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.72)}.dsh-mobile-control__qr-zoom[hidden]{display:none}.dsh-mobile-control__qr-zoom-image{width:min(84vw,360px);height:min(84vw,360px);border-radius:12px;background:#fff;padding:12px}.dsh-mobile-control__qr-zoom-close{position:absolute;top:12px;right:16px;min-width:44px;min-height:44px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2,#dbe1e8);background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#16181d);font:600 18px/1 system-ui;cursor:pointer}
|
|
@@ -16983,9 +17284,10 @@ dialog.dshm-picker[open]{display:grid;place-items:center}dialog.dshm-picker::bac
|
|
|
16983
17284
|
}
|
|
16984
17285
|
/** Client services required by the mobile adaptation. */
|
|
16985
17286
|
const inject = ["slots"];
|
|
16986
|
-
//#endregion
|
|
16987
17287
|
exports.CONTROL_STYLES = CONTROL_STYLES;
|
|
17288
|
+
exports.DIAGNOSTIC_NETWORK_MESSAGES = DIAGNOSTIC_NETWORK_MESSAGES;
|
|
16988
17289
|
exports.DIAGNOSTIC_REASON_MESSAGES = DIAGNOSTIC_REASON_MESSAGES;
|
|
17290
|
+
exports.DIAGNOSTIC_SCOPE_MESSAGES = DIAGNOSTIC_SCOPE_MESSAGES;
|
|
16989
17291
|
exports.LOCALIZED_DIAGNOSTIC_COPY = LOCALIZED_DIAGNOSTIC_COPY;
|
|
16990
17292
|
exports.MOBILE_CONTROL_MESSAGES = MOBILE_CONTROL_MESSAGES;
|
|
16991
17293
|
exports.PerIdActivationLifecycle = PerIdActivationLifecycle;
|