dsh-deeppilot 0.9.13 → 0.9.15
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/COMPATIBILITY.md +113 -19
- package/README.md +34 -23
- package/README.zh-CN.md +26 -19
- package/bin/SHA256SUMS +6 -6
- package/bin/darwin-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/darwin-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/windows-amd64/dsh-deeppilot-tunnel.exe +0 -0
- package/bin/windows-arm64/dsh-deeppilot-tunnel.exe +0 -0
- package/docs/DSH_022_FEATURES.md +38 -3
- package/docs/DSH_RELEASE_MEMORY.md +191 -2
- package/docs/NPM_PUBLISHING.md +48 -1
- package/lib/client.js +582 -468
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +350 -33
- package/lib/index.js +1858 -128
- package/lib/index.js.map +1 -1
- package/locale/en.json +2 -1
- package/locale/zh.json +2 -1
- package/package.json +31 -23
package/lib/client.js
CHANGED
|
@@ -4,14 +4,14 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
-
|
|
7
|
+
// \0rolldown/runtime.js
|
|
8
8
|
var __create = Object.create;
|
|
9
9
|
var __defProp = Object.defineProperty;
|
|
10
10
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
11
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
12
|
var __getProtoOf = Object.getPrototypeOf;
|
|
13
13
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
14
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
|
|
15
15
|
var __copyProps = (to, from, except, desc) => {
|
|
16
16
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
17
17
|
key = keys[i];
|
|
@@ -26,9 +26,9 @@ window.__ModuleLoader__.load({
|
|
|
26
26
|
value: mod,
|
|
27
27
|
enumerable: true
|
|
28
28
|
}) : target, mod));
|
|
29
|
-
//#endregion
|
|
30
29
|
let react = require("react");
|
|
31
|
-
|
|
30
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
31
|
+
// src/client/snapshot-store.ts
|
|
32
32
|
function createSnapshotStore(initial) {
|
|
33
33
|
let snapshot = initial;
|
|
34
34
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -45,8 +45,7 @@ window.__ModuleLoader__.load({
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
//#region src/tailscale-version.ts
|
|
48
|
+
// src/tailscale-version.ts
|
|
50
49
|
/**
|
|
51
50
|
* 内嵌 helper 上报的 tailscale.com 模块版本。
|
|
52
51
|
*
|
|
@@ -69,8 +68,7 @@ window.__ModuleLoader__.load({
|
|
|
69
68
|
function isTailscaleVersion(value) {
|
|
70
69
|
return typeof value === "string" && value.length <= MAX_TAILSCALE_VERSION_LENGTH && TAILSCALE_VERSION_PATTERN.test(value);
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
//#region src/device-auth.ts
|
|
71
|
+
// src/device-auth.ts
|
|
74
72
|
const DEVICE_SCOPES = [
|
|
75
73
|
"sessions.read",
|
|
76
74
|
"prompt.send",
|
|
@@ -85,8 +83,7 @@ window.__ModuleLoader__.load({
|
|
|
85
83
|
const allowed = new Set(DEVICE_SCOPES);
|
|
86
84
|
return [...new Set(value.filter((scope) => typeof scope === "string" && allowed.has(scope)))];
|
|
87
85
|
}
|
|
88
|
-
|
|
89
|
-
//#region src/report-wire.ts
|
|
86
|
+
// src/report-wire.ts
|
|
90
87
|
/** The npm package identity both contribution registrations claim. */
|
|
91
88
|
const REPORT_REMOTE_PACKAGE = "dsh-deeppilot";
|
|
92
89
|
/** Canonical `<namespace>/<method>` endpoint of the report Remote. */
|
|
@@ -464,8 +461,7 @@ window.__ModuleLoader__.load({
|
|
|
464
461
|
}
|
|
465
462
|
]
|
|
466
463
|
};
|
|
467
|
-
|
|
468
|
-
//#region src/client/report-mount.ts
|
|
464
|
+
// src/client/report-mount.ts
|
|
469
465
|
/** Mount the contribution and resolve the namespace service it installs. */
|
|
470
466
|
async function mountReportRemote(remote, resolveNamespace) {
|
|
471
467
|
const dispose = await remote.$mount(REPORT_REMOTE_CONTRIBUTION);
|
|
@@ -479,8 +475,7 @@ window.__ModuleLoader__.load({
|
|
|
479
475
|
dispose
|
|
480
476
|
};
|
|
481
477
|
}
|
|
482
|
-
|
|
483
|
-
//#region src/client/i18n.ts
|
|
478
|
+
// src/client/i18n.ts
|
|
484
479
|
/** Single namespace shared with the host's locale registry, so other
|
|
485
480
|
* host-side modules (if any) can translate the same keys. */
|
|
486
481
|
const DEEPPILOT_LOCALE_NS = "settings.deeppilot";
|
|
@@ -498,11 +493,39 @@ window.__ModuleLoader__.load({
|
|
|
498
493
|
*/
|
|
499
494
|
const TABLES = {
|
|
500
495
|
zh: {
|
|
496
|
+
"local.options": "局域网连接选项",
|
|
497
|
+
"remote.options": "远程连接选项",
|
|
498
|
+
"local.errorDetails": "局域网连接异常,请检查连接选项({message})。",
|
|
499
|
+
"remote.errorDetails": "远程连接异常,请检查授权与连接选项({message})。",
|
|
500
|
+
"pair.add": "添加手机",
|
|
501
|
+
"pair.close": "收起",
|
|
502
|
+
"devices.count": "{count} 台",
|
|
503
|
+
"devices.moreAria": "设备“{name}”的更多操作",
|
|
504
|
+
"tools.title": "工具与信息",
|
|
505
|
+
"diag.reportFailed": "读取连接状态失败",
|
|
506
|
+
"diagnostics.historyCount": "{count} 条历史失败记录",
|
|
507
|
+
"diagnostics.kind.upgrade": "连接请求被拒绝",
|
|
508
|
+
"diagnostics.kind.pair": "配对请求被拒绝",
|
|
509
|
+
"diagnostics.kind.auth": "设备认证失败",
|
|
510
|
+
"diagnostics.kind.opened": "连接已建立",
|
|
511
|
+
"diagnostics.kind.closed": "连接异常断开",
|
|
512
|
+
"diagnostics.kind.error": "连接发生错误",
|
|
513
|
+
"diagnostics.kind.identity": "设备身份异常",
|
|
514
|
+
"diagnostics.kind.storage": "设备信息保存失败",
|
|
515
|
+
"diagnostics.kind.unknown": "连接异常",
|
|
516
|
+
"push.outcome.sent": "已发送",
|
|
517
|
+
"push.outcome.failed": "发送失败",
|
|
518
|
+
"push.outcome.invalid": "设备推送凭据无效",
|
|
519
|
+
"push.environment.development": "开发环境",
|
|
520
|
+
"push.environment.production": "正式环境",
|
|
521
|
+
"push.environment.other": "其他环境({environment})",
|
|
522
|
+
"push.outcome.other": "推送状态({outcome})",
|
|
523
|
+
"push.resultDetail": "推送结果({message})",
|
|
501
524
|
"nav": "DeepPilot",
|
|
502
525
|
"meta.title": "DeepPilot",
|
|
503
|
-
"meta.intro": "
|
|
526
|
+
"meta.intro": "在手机上使用这台电脑的 DSH。",
|
|
504
527
|
"meta.refresh": "刷新",
|
|
505
|
-
"master.title": "
|
|
528
|
+
"master.title": "允许手机连接",
|
|
506
529
|
"master.loading": "正在读取配置…",
|
|
507
530
|
"master.on": "已开启:接受手机连接。",
|
|
508
531
|
"master.off": "已关闭:不接受手机连接。",
|
|
@@ -515,11 +538,11 @@ window.__ModuleLoader__.load({
|
|
|
515
538
|
"connection.optionsSummary": "连接选项",
|
|
516
539
|
"pair.description": "选择连接方式并生成一次性配对信息。",
|
|
517
540
|
"devices.description": "管理已经配对的 iPhone。",
|
|
518
|
-
"troubleshooting.summary": "
|
|
541
|
+
"troubleshooting.summary": "诊断工具",
|
|
519
542
|
"troubleshooting.title": "诊断工具",
|
|
520
543
|
"troubleshooting.description": "仅在排查连接或推送问题时使用。",
|
|
521
544
|
"troubleshooting.debugTitle": "调试日志",
|
|
522
|
-
"troubleshooting.debugDescription": "
|
|
545
|
+
"troubleshooting.debugDescription": "开启后,新的手机连接会在 DSH 终端输出诊断日志;已连接手机需重连后生效。日志不包含配对码、推送凭据或消息内容。",
|
|
523
546
|
"diagnostics.title": "连接诊断",
|
|
524
547
|
"diagnostics.description": "最近的连接失败事件;可一键复制后发给维护者排查。",
|
|
525
548
|
"diagnostics.recent": "最近失败",
|
|
@@ -563,7 +586,7 @@ window.__ModuleLoader__.load({
|
|
|
563
586
|
"local.portApplied": "局域网端口已保存,监听器正在重新加载。",
|
|
564
587
|
"local.portInvalid": "请输入 1024–65535 之间的整数。",
|
|
565
588
|
"local.portFailed": "局域网端口保存失败:",
|
|
566
|
-
"remote.title": "
|
|
589
|
+
"remote.title": "远程连接",
|
|
567
590
|
"remote.on": "已配置:内嵌 Funnel 会自动启动并同步状态。",
|
|
568
591
|
"remote.off": "关闭:仅保留局域网连接。",
|
|
569
592
|
"remote.openAuth": "打开授权页面",
|
|
@@ -611,12 +634,12 @@ window.__ModuleLoader__.load({
|
|
|
611
634
|
"panel.tokenRotateWarning": "更换会使当前 Token 立即失效、断开所有手机连接;5 秒内再次点击确认。",
|
|
612
635
|
"panel.tokenRotated": "新 Token 已生效,旧 Token 已失效;请重新配对所有设备。",
|
|
613
636
|
"panel.tokenRotateFailed": "更换失败:",
|
|
614
|
-
"pair.qrPanelTitle": "
|
|
637
|
+
"pair.qrPanelTitle": "添加手机",
|
|
615
638
|
"pair.kind.public": "公网",
|
|
616
639
|
"pair.kind.lan": "内网",
|
|
617
640
|
"pair.noAddress": "没有可用地址",
|
|
618
641
|
"pair.noAddressHelp": "没有可用的局域网或远程入口。请确认局域网连接已启动,或启用远程连接。",
|
|
619
|
-
"pair.disabledHelp": "
|
|
642
|
+
"pair.disabledHelp": "请先开启“允许手机连接”,再添加手机。",
|
|
620
643
|
"pair.qrAlt": "DeepPilot 配对二维码",
|
|
621
644
|
"pair.qrShow": "显示二维码",
|
|
622
645
|
"pair.qrHide": "隐藏二维码",
|
|
@@ -627,7 +650,7 @@ window.__ModuleLoader__.load({
|
|
|
627
650
|
"pair.infoLabel": "配对信息(复制一次,粘贴到 App 即可)",
|
|
628
651
|
"pair.infoCopyDone": "配对信息已复制",
|
|
629
652
|
"pair.infoCopyFailed": "配对信息复制失败:",
|
|
630
|
-
"pair.qrHint": "
|
|
653
|
+
"pair.qrHint": "二维码与「配对信息」内容相同:包含{kind}地址、一次性配对码、证书指纹(内网时)与主机标识。在局域网与公网之间切换会立即生成对应的新配对信息,配对码 5 分钟后失效。",
|
|
631
654
|
"advanced.summary": "高级信息",
|
|
632
655
|
"advanced.protocolVersion": "协议版本",
|
|
633
656
|
"advanced.serverVersion": "服务器版本",
|
|
@@ -653,9 +676,9 @@ window.__ModuleLoader__.load({
|
|
|
653
676
|
"push.pushNotEnabled": "推送未启用",
|
|
654
677
|
"push.relayStep.health": "服务可达",
|
|
655
678
|
"push.relayStep.enroll": "自动注册",
|
|
656
|
-
"push.prefix.ok": "
|
|
657
|
-
"push.prefix.fail": "
|
|
658
|
-
"devices.title": "
|
|
679
|
+
"push.prefix.ok": "通过:",
|
|
680
|
+
"push.prefix.fail": "未通过:",
|
|
681
|
+
"devices.title": "已配对设备",
|
|
659
682
|
"devices.col.name": "设备",
|
|
660
683
|
"devices.col.appVersion": "App 版本",
|
|
661
684
|
"devices.col.push": "离线推送",
|
|
@@ -686,13 +709,13 @@ window.__ModuleLoader__.load({
|
|
|
686
709
|
"devices.pushNotRegistered": "未注册",
|
|
687
710
|
"devices.pushEnvProduction": "生产",
|
|
688
711
|
"devices.pushEnvDevelopment": "开发",
|
|
689
|
-
"devices.empty": "
|
|
712
|
+
"devices.empty": "还没有配对设备。点击“添加手机”,然后在 DeepPilot 中扫码连接。",
|
|
690
713
|
"help.remoteTitle": "远程连接帮助",
|
|
691
714
|
"help.recommended": "推荐设置流程",
|
|
692
|
-
"help.step1": "
|
|
715
|
+
"help.step1": "先打开“允许手机连接”,再打开“远程连接”。",
|
|
693
716
|
"help.step2": "状态变为\"等待 Tailscale 授权\"后,点击\"打开授权页面\"。",
|
|
694
717
|
"help.step3": "使用有权管理此 Tailnet 的账号登录,并按授权页提示启用 Funnel。通常需要 Owner、Admin 或 Network admin 权限。",
|
|
695
|
-
"help.step4": "
|
|
718
|
+
"help.step4": "返回此页面并点击“刷新”。远程连接显示“已就绪”后,点击“添加手机”并扫码。",
|
|
696
719
|
"help.funnelHint": "插件已内嵌 Tailscale 网络组件,这台电脑和手机都不需要另外安装 Tailscale App;但首次启用仍需由 Tailnet 管理员授权。",
|
|
697
720
|
"help.httpsTitle": "授权页未自动完成时:开启 HTTPS",
|
|
698
721
|
"help.httpsStep1": "打开 Tailscale 管理后台的 Network → DNS。",
|
|
@@ -751,11 +774,39 @@ window.__ModuleLoader__.load({
|
|
|
751
774
|
"update.badge": "有新版本"
|
|
752
775
|
},
|
|
753
776
|
en: {
|
|
777
|
+
"local.options": "LAN connection options",
|
|
778
|
+
"remote.options": "Remote connection options",
|
|
779
|
+
"local.errorDetails": "LAN connection failed. Check the connection options ({message}).",
|
|
780
|
+
"remote.errorDetails": "Remote connection failed. Check authorization and connection options ({message}).",
|
|
781
|
+
"pair.add": "Add phone",
|
|
782
|
+
"pair.close": "Collapse",
|
|
783
|
+
"devices.count": "{count} devices",
|
|
784
|
+
"devices.moreAria": "More actions for “{name}”",
|
|
785
|
+
"tools.title": "Tools and information",
|
|
786
|
+
"diag.reportFailed": "Failed to read connection status",
|
|
787
|
+
"diagnostics.historyCount": "{count} past failures",
|
|
788
|
+
"diagnostics.kind.upgrade": "Connection request rejected",
|
|
789
|
+
"diagnostics.kind.pair": "Pairing request rejected",
|
|
790
|
+
"diagnostics.kind.auth": "Device authentication failed",
|
|
791
|
+
"diagnostics.kind.opened": "Connection opened",
|
|
792
|
+
"diagnostics.kind.closed": "Connection closed unexpectedly",
|
|
793
|
+
"diagnostics.kind.error": "Connection error",
|
|
794
|
+
"diagnostics.kind.identity": "Device identity error",
|
|
795
|
+
"diagnostics.kind.storage": "Saving device information failed",
|
|
796
|
+
"diagnostics.kind.unknown": "Connection problem",
|
|
797
|
+
"push.outcome.sent": "Sent",
|
|
798
|
+
"push.outcome.failed": "Failed to send",
|
|
799
|
+
"push.outcome.invalid": "Invalid push credentials",
|
|
800
|
+
"push.environment.development": "Development",
|
|
801
|
+
"push.environment.production": "Production",
|
|
802
|
+
"push.environment.other": "Other environment ({environment})",
|
|
803
|
+
"push.outcome.other": "Push status ({outcome})",
|
|
804
|
+
"push.resultDetail": "Push result ({message})",
|
|
754
805
|
"nav": "DeepPilot",
|
|
755
806
|
"meta.title": "DeepPilot",
|
|
756
|
-
"meta.intro": "
|
|
807
|
+
"meta.intro": "Use this computer’s DSH from your phone.",
|
|
757
808
|
"meta.refresh": "Refresh",
|
|
758
|
-
"master.title": "
|
|
809
|
+
"master.title": "Allow phone connections",
|
|
759
810
|
"master.loading": "Loading settings…",
|
|
760
811
|
"master.on": "On: accepting phone connections.",
|
|
761
812
|
"master.off": "Off: not accepting phone connections.",
|
|
@@ -768,11 +819,11 @@ window.__ModuleLoader__.load({
|
|
|
768
819
|
"connection.optionsSummary": "Connection options",
|
|
769
820
|
"pair.description": "Choose a connection type and generate one-time pairing information.",
|
|
770
821
|
"devices.description": "Manage iPhones that are already paired.",
|
|
771
|
-
"troubleshooting.summary": "
|
|
822
|
+
"troubleshooting.summary": "Diagnostic tools",
|
|
772
823
|
"troubleshooting.title": "Diagnostic tools",
|
|
773
824
|
"troubleshooting.description": "Use these only when diagnosing connection or push issues.",
|
|
774
825
|
"troubleshooting.debugTitle": "Debug logging",
|
|
775
|
-
"troubleshooting.debugDescription": "
|
|
826
|
+
"troubleshooting.debugDescription": "New phone connections write diagnostic logs to the DSH terminal. Connected phones must reconnect to pick up the change. Logs exclude pairing codes, push credentials, and message content.",
|
|
776
827
|
"diagnostics.title": "Connection diagnostics",
|
|
777
828
|
"diagnostics.description": "Recent connection failures; copy them for troubleshooting.",
|
|
778
829
|
"diagnostics.recent": "Recent failures",
|
|
@@ -816,7 +867,7 @@ window.__ModuleLoader__.load({
|
|
|
816
867
|
"local.portApplied": "LAN port saved; the listener is reloading.",
|
|
817
868
|
"local.portInvalid": "Enter an integer from 1024 to 65535.",
|
|
818
869
|
"local.portFailed": "Failed to save LAN port: ",
|
|
819
|
-
"remote.title": "Remote connection
|
|
870
|
+
"remote.title": "Remote connection",
|
|
820
871
|
"remote.on": "Configured: the embedded Funnel will start and sync state automatically.",
|
|
821
872
|
"remote.off": "Off: LAN connections only.",
|
|
822
873
|
"remote.openAuth": "Open authorization page",
|
|
@@ -864,12 +915,12 @@ window.__ModuleLoader__.load({
|
|
|
864
915
|
"panel.tokenRotateWarning": "Rotation invalidates the current token immediately and drops every paired phone. Click again within 5s to confirm.",
|
|
865
916
|
"panel.tokenRotated": "New token active, old token invalidated. Please re-pair every device.",
|
|
866
917
|
"panel.tokenRotateFailed": "Rotation failed: ",
|
|
867
|
-
"pair.qrPanelTitle": "
|
|
918
|
+
"pair.qrPanelTitle": "Add phone",
|
|
868
919
|
"pair.kind.public": "Public",
|
|
869
920
|
"pair.kind.lan": "LAN",
|
|
870
921
|
"pair.noAddress": "No address available",
|
|
871
922
|
"pair.noAddressHelp": "No LAN or remote endpoint is available. Make sure LAN is running or enable remote access.",
|
|
872
|
-
"pair.disabledHelp": "
|
|
923
|
+
"pair.disabledHelp": "Turn on “Allow phone connections” before adding a phone.",
|
|
873
924
|
"pair.qrAlt": "DeepPilot pairing QR code",
|
|
874
925
|
"pair.qrShow": "Show QR code",
|
|
875
926
|
"pair.qrHide": "Hide QR code",
|
|
@@ -880,7 +931,7 @@ window.__ModuleLoader__.load({
|
|
|
880
931
|
"pair.infoLabel": "Pairing info (copy once, paste it in the app)",
|
|
881
932
|
"pair.infoCopyDone": "Pairing info copied",
|
|
882
933
|
"pair.infoCopyFailed": "Failed to copy pairing info: ",
|
|
883
|
-
"pair.qrHint": "The QR code and the pairing info
|
|
934
|
+
"pair.qrHint": "The QR code and the pairing info carry the same {kind} address, single-use code, certificate fingerprint (for LAN) and host identity. Switching between LAN and public issues a matching new string immediately; the code expires after 5 minutes.",
|
|
884
935
|
"advanced.summary": "Advanced info",
|
|
885
936
|
"advanced.protocolVersion": "Protocol version",
|
|
886
937
|
"advanced.serverVersion": "Server version",
|
|
@@ -906,9 +957,9 @@ window.__ModuleLoader__.load({
|
|
|
906
957
|
"push.pushNotEnabled": "Push not enabled",
|
|
907
958
|
"push.relayStep.health": "Service reachable",
|
|
908
959
|
"push.relayStep.enroll": "Auto enrollment",
|
|
909
|
-
"push.prefix.ok": "
|
|
910
|
-
"push.prefix.fail": "
|
|
911
|
-
"devices.title": "
|
|
960
|
+
"push.prefix.ok": "Passed: ",
|
|
961
|
+
"push.prefix.fail": "Failed: ",
|
|
962
|
+
"devices.title": "Paired devices",
|
|
912
963
|
"devices.col.name": "Device",
|
|
913
964
|
"devices.col.appVersion": "App version",
|
|
914
965
|
"devices.col.push": "Push",
|
|
@@ -939,13 +990,13 @@ window.__ModuleLoader__.load({
|
|
|
939
990
|
"devices.pushNotRegistered": "Not registered",
|
|
940
991
|
"devices.pushEnvProduction": "Production",
|
|
941
992
|
"devices.pushEnvDevelopment": "Development",
|
|
942
|
-
"devices.empty": "No
|
|
993
|
+
"devices.empty": "No paired devices yet. Click “Add phone”, then scan the QR code in DeepPilot.",
|
|
943
994
|
"help.remoteTitle": "Remote connection help",
|
|
944
995
|
"help.recommended": "Recommended setup",
|
|
945
|
-
"help.step1": "Turn on
|
|
996
|
+
"help.step1": "Turn on “Allow phone connections”, then “Remote connection”.",
|
|
946
997
|
"help.step2": "When the status shows \"Awaiting Tailscale authorization\", click \"Open authorization page\".",
|
|
947
998
|
"help.step3": "Sign in with an account that can manage this Tailnet and follow the on-page prompts to enable Funnel. Owner / Admin / Network admin is usually required.",
|
|
948
|
-
"help.step4": "
|
|
999
|
+
"help.step4": "Return and click “Refresh”. Once the remote connection is ready, click “Add phone” and scan the QR code.",
|
|
949
1000
|
"help.funnelHint": "The plugin bundles the Tailscale networking stack, so neither this computer nor the phone needs the Tailscale app — but a Tailnet administrator must approve first-time use.",
|
|
950
1001
|
"help.httpsTitle": "If authorization does not complete: enable HTTPS",
|
|
951
1002
|
"help.httpsStep1": "Open the Tailscale admin console → Network → DNS.",
|
|
@@ -1066,172 +1117,150 @@ window.__ModuleLoader__.load({
|
|
|
1066
1117
|
en: TABLES.en
|
|
1067
1118
|
});
|
|
1068
1119
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
".pbb-testItem{display:flex;align-items:center;gap:12px;padding:11px;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;background:var(--dsw-alias-bg-module-platform)}",
|
|
1214
|
-
".pbb-testTitle{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary)}",
|
|
1215
|
-
".pbb-testDescription{font-size:12px;color:var(--dsw-alias-label-tertiary);line-height:1.5}",
|
|
1216
|
-
".pbb-runtimeList{display:flex;flex-direction:column;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;overflow:hidden}",
|
|
1217
|
-
".pbb-runtimeList>.pbb-runtimeRow,.pbb-runtimeRow{display:flex;align-items:center;gap:10px;padding:9px 10px;border-top:1px solid var(--dsw-alias-border-l2)}",
|
|
1218
|
-
".pbb-runtimeList>.pbb-runtimeRow:first-child{border-top:0}",
|
|
1219
|
-
".pbb-runtimeList>.pbb-runtimeRow>.pbb-row{flex:1;min-width:0}",
|
|
1220
|
-
".pbb-updateRow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,#4176e6) 35%,var(--dsw-alias-border-l3));border-radius:8px;color:var(--dsw-alias-label-primary);font-size:13px;text-decoration:none;cursor:pointer;transition:background-color 160ms " + EASE + "}",
|
|
1221
|
-
".pbb-disclosure{padding:0}",
|
|
1222
|
-
".pbb-disclosure>summary{list-style:none;display:flex;align-items:center;gap:10px;padding:13px 18px;cursor:pointer;color:var(--dsw-alias-label-primary)}",
|
|
1223
|
-
".pbb-disclosure>summary::-webkit-details-marker{display:none}",
|
|
1224
|
-
".pbb-disclosure[open]>summary .pbb-chev{transform:rotate(90deg)}",
|
|
1225
|
-
".pbb-disclosureTitle{font-size:13px;font-weight:500;flex:1}",
|
|
1226
|
-
".pbb-disclosureMeta{font-size:12px;color:var(--dsw-alias-label-tertiary);max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
|
|
1227
|
-
".pbb-disclosureBody{display:flex;flex-direction:column;gap:12px;padding:2px 18px 16px}",
|
|
1228
|
-
".pbb-diagnostics>summary{color:var(--dsw-alias-label-secondary)}",
|
|
1229
|
-
"@media (hover:hover) and (pointer:fine){.pbb-refresh:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.pbb-cardHead:hover{background:var(--dsw-alias-bg-module-platform)}.pbb-action:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}.pbb-buttonPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-interactive-bg-hover-solid))}.pbb-actionDangerGhost:hover:not(:disabled){color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 9%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent)}.pbb-expand:hover{color:var(--dsw-alias-label-primary)}.pbb-updateRow:hover{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,#4176e6) 8%,transparent)}}",
|
|
1230
|
-
"@media (prefers-reduced-motion:reduce){.pbb-section *{animation-duration:.01ms!important;animation-delay:0s!important;transition-duration:.01ms!important;transition-delay:0s!important}}",
|
|
1231
|
-
"@container pbb (max-width:640px){.pbb-statusStrip{grid-template-columns:repeat(2,1fr)}.pbb-statusCell:nth-child(3){border-left:0}.pbb-statusCell:nth-child(n+3){border-top:1px solid var(--dsw-alias-border-l2)}.pbb-cardSummary{display:none}}",
|
|
1232
|
-
"@container pbb (max-width:480px){.pbb-testGrid{grid-template-columns:1fr}.pbb-testItem:last-child:nth-child(odd){grid-column:auto}.pbb-qrPanel{grid-template-columns:1fr}.pbb-limitRow{align-items:flex-start;flex-direction:column}.pbb-limitControl{align-self:flex-end}.pbb-deviceRow{grid-template-columns:minmax(0,1fr)}.pbb-deviceActions{grid-row:auto;grid-column:auto;justify-content:flex-start}}",
|
|
1233
|
-
"@media (pointer:coarse){.pbb-action{min-height:32px;padding:7px 10px;font-size:13px}.pbb-buttonPrimary{font-size:14px}.pbb-cardHead{min-height:56px}.pbb-expand{padding:5px 0}.pbb-refresh{padding:5px 0}}"
|
|
1234
|
-
].join("\n");
|
|
1120
|
+
// src/client/styles.ts
|
|
1121
|
+
const CSS = String.raw`
|
|
1122
|
+
.pbb-section{--pbb-ink:var(--dsw-alias-label-primary,#0f1115);--pbb-secondary:var(--dsw-alias-label-secondary,#61666b);--pbb-line:var(--dsw-alias-settings-card-stroke,var(--dsw-alias-border-l3,#e4e5e7));--pbb-fill:var(--dsw-alias-settings-card-fill,var(--dsw-alias-bg-layer-2,#fff));--pbb-soft:var(--dsw-alias-bg-module-platform,#f5f6f8);container:pbb/inline-size;max-width:760px;color:var(--pbb-ink);font-size:14px;line-height:20px;display:flex;flex-direction:column;gap:20px}
|
|
1123
|
+
.pbb-section *{box-sizing:border-box}
|
|
1124
|
+
.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton),.pbb-section input{font-family:inherit}
|
|
1125
|
+
.pbb-icon{display:block;flex:none;color:inherit}
|
|
1126
|
+
.pbb-pageHeader{display:flex;align-items:flex-start;gap:12px;min-height:56px}
|
|
1127
|
+
.pbb-pageHeader>div{min-width:0;flex:1;padding-top:2px}
|
|
1128
|
+
.pbb-title{margin:0;font-size:20px;line-height:27px;font-weight:600;letter-spacing:-.3px}
|
|
1129
|
+
.pbb-intro{color:var(--pbb-secondary);font-size:14px;line-height:20px;margin:5px 0 0}
|
|
1130
|
+
.pbb-refresh{display:inline-flex;align-items:center;justify-content:center;gap:5px;height:28px;padding:0 7px;flex:none;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);font-size:12px;cursor:pointer}
|
|
1131
|
+
.pbb-card{border:1px solid var(--pbb-line);border-radius:18px;background:var(--pbb-fill)}
|
|
1132
|
+
.pbb-cardTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--pbb-ink)}
|
|
1133
|
+
.pbb-cardBody{display:flex;flex-direction:column;gap:12px;padding:4px 16px 16px}
|
|
1134
|
+
.pbb-connections>.pbb-cardBody{padding:0;gap:0}
|
|
1135
|
+
.pbb-row{display:flex;align-items:center;gap:8px;min-width:0}
|
|
1136
|
+
.pbb-masterRow{display:flex;align-items:center;gap:12px;min-height:66px;padding:11px 16px}
|
|
1137
|
+
.pbb-controlText{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px}
|
|
1138
|
+
.pbb-masterRow>.pbb-controlText{gap:4px}
|
|
1139
|
+
.pbb-controlTitle{font-size:14px;line-height:20px;font-weight:400;color:var(--pbb-ink)}
|
|
1140
|
+
.pbb-masterRow .pbb-controlTitle{font-weight:600}
|
|
1141
|
+
.pbb-controlDescription,.pbb-diag,.pbb-label,.pbb-value{font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1142
|
+
.pbb-serviceSummary,.pbb-channelState{display:flex;align-items:center;flex-wrap:wrap;gap:6px;font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1143
|
+
.pbb-serviceSummary{gap:5px}
|
|
1144
|
+
.pbb-serviceState{display:inline-flex}
|
|
1145
|
+
.pbb-metaDivider{height:10px;border-left:1px solid var(--pbb-line);margin:0 2px}
|
|
1146
|
+
.pbb-channel{position:relative}
|
|
1147
|
+
.pbb-channel::before{content:"";position:absolute;top:0;left:16px;right:16px;border-top:1px solid var(--pbb-line)}
|
|
1148
|
+
.pbb-channel+.pbb-channel::before{left:46px}
|
|
1149
|
+
.pbb-channelRow{gap:12px;min-height:60px;padding:8px 16px}
|
|
1150
|
+
.pbb-channelRow>.pbb-icon{color:var(--pbb-secondary)}
|
|
1151
|
+
.pbb-channelBody{display:flex;flex-direction:column;gap:12px;padding:2px 16px 14px 46px}
|
|
1152
|
+
.pbb-channel>.pbb-diag,.pbb-channel>.pbb-rowAction{margin:0;padding:0 16px 8px 46px}
|
|
1153
|
+
.pbb-fold[hidden]{display:none}
|
|
1154
|
+
.pbb-action:disabled,.pbb-refresh:disabled,.pbb-menuAction:disabled,.pbb-targetButton:disabled{opacity:.5;cursor:default}
|
|
1155
|
+
.pbb-action{display:inline-flex;align-items:center;justify-content:center;gap:5px;flex:none;height:28px;max-width:100%;padding:0 9px;border:1px solid var(--pbb-line);border-radius:6px;background:transparent;color:var(--pbb-secondary);font:inherit;font-size:14px;line-height:20px;text-decoration:none;cursor:pointer;white-space:nowrap}
|
|
1156
|
+
.pbb-addAction{display:flex;margin-left:auto}
|
|
1157
|
+
.pbb-buttonPrimary{background:var(--dsw-alias-button-primary-fill,var(--pbb-ink));border-color:transparent;color:var(--dsw-alias-label-primary-foreground,#fff)}
|
|
1158
|
+
.pbb-actionDangerGhost{color:var(--dsw-alias-state-error-primary,#bc2222);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary,#bc2222) 35%,transparent)}
|
|
1159
|
+
.pbb-iconButton{display:flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);cursor:pointer}
|
|
1160
|
+
.pbb-chev{display:inline-flex;flex:none;color:var(--pbb-secondary)}
|
|
1161
|
+
.pbb-chevIcon{width:14px;height:14px;display:block}
|
|
1162
|
+
[aria-expanded="true"]>.pbb-chev,.pbb-helpDisclosure[open]>summary>.pbb-chev,.pbb-disclosure[open]>summary>.pbb-chev{transform:rotate(90deg)}
|
|
1163
|
+
.pbb-diag{margin:0;overflow-wrap:anywhere}
|
|
1164
|
+
.pbb-diagBad,.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1165
|
+
.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}
|
|
1166
|
+
.pbb-label{flex:1;min-width:0;font-weight:500;color:var(--pbb-ink)}
|
|
1167
|
+
.pbb-value{text-align:right;overflow-wrap:anywhere}
|
|
1168
|
+
.pbb-token{max-width:100%;font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--pbb-secondary);overflow-wrap:anywhere}
|
|
1169
|
+
.pbb-empty{margin:0;padding:16px;font-size:14px;line-height:20px;color:var(--pbb-secondary)}
|
|
1170
|
+
.pbb-limitRow{display:flex;align-items:center;gap:12px}
|
|
1171
|
+
.pbb-limitControl{display:flex;align-items:center;gap:8px;flex:none}
|
|
1172
|
+
.pbb-numberInput,.pbb-deviceNameInput{min-width:0;height:28px;border:1px solid var(--pbb-line);border-radius:6px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));color:var(--pbb-ink);font:inherit;font-size:14px;line-height:20px;padding:3px 8px;caret-color:var(--pbb-ink)}
|
|
1173
|
+
.pbb-numberInput{width:72px}
|
|
1174
|
+
.pbb-numberInput:disabled,.pbb-deviceNameInput:disabled{opacity:.5}
|
|
1175
|
+
.pbb-endpoint{user-select:all}
|
|
1176
|
+
.pbb-devicesSection{display:flex;flex-direction:column;gap:8px}
|
|
1177
|
+
.pbb-devicesHeader{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 2px}
|
|
1178
|
+
.pbb-deviceCount{font-size:12px;line-height:18px;color:var(--pbb-secondary);white-space:nowrap}
|
|
1179
|
+
.pbb-devicesCard{overflow:visible}
|
|
1180
|
+
.pbb-deviceList{display:flex;flex-direction:column}
|
|
1181
|
+
.pbb-deviceRow{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:12px;row-gap:0;min-height:56px;padding:6px 14px 6px 16px}
|
|
1182
|
+
.pbb-deviceRow+.pbb-deviceRow::before{content:"";position:absolute;top:0;left:46px;right:16px;border-top:1px solid var(--pbb-line)}
|
|
1183
|
+
.pbb-deviceRow:has(details[open]){z-index:2}
|
|
1184
|
+
.pbb-deviceMain{display:flex;align-items:center;gap:12px;min-width:0}
|
|
1185
|
+
.pbb-deviceMain>.pbb-icon{color:var(--pbb-secondary)}
|
|
1186
|
+
.pbb-deviceText{display:flex;flex-direction:column;gap:2px;min-width:0}
|
|
1187
|
+
.pbb-deviceName{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1188
|
+
.pbb-deviceMeta{display:flex;flex-wrap:wrap;gap:0 6px;color:var(--pbb-secondary);font-size:12px;line-height:18px}
|
|
1189
|
+
.pbb-deviceMeta>*+*::before{content:"\00B7";margin-right:6px}
|
|
1190
|
+
.pbb-deviceActions{grid-row:1;grid-column:2;display:flex;align-items:center}
|
|
1191
|
+
.pbb-deviceRenameForm,.pbb-deviceConfirm{grid-column:1/-1;display:flex;gap:8px;padding:8px 0;min-width:0}
|
|
1192
|
+
.pbb-deviceRenameForm{flex-wrap:wrap}
|
|
1193
|
+
.pbb-deviceNameInput{flex:1}
|
|
1194
|
+
.pbb-deviceRenameActions{display:flex;align-items:center;gap:5px;flex:none}
|
|
1195
|
+
.pbb-deviceConfirm{flex-direction:column}
|
|
1196
|
+
.pbb-deviceMessage{padding:10px 16px}
|
|
1197
|
+
.pbb-deviceMenu{position:relative}
|
|
1198
|
+
.pbb-deviceMenu>summary{list-style:none}
|
|
1199
|
+
.pbb-deviceMenu>summary::-webkit-details-marker{display:none}
|
|
1200
|
+
.pbb-deviceMenuBody{position:absolute;z-index:3;top:34px;right:0;width:250px;max-width:calc(100cqw - 32px);padding:5px;border:1px solid var(--pbb-line);border-radius:10px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));box-shadow:0 8px 24px color-mix(in srgb,var(--pbb-ink) 12%,transparent)}
|
|
1201
|
+
.pbb-deviceMenuInfo{display:flex;flex-direction:column;gap:3px;padding:7px 8px 10px;border-bottom:1px solid var(--pbb-line)}
|
|
1202
|
+
.pbb-menuAction{display:block;width:100%;min-height:32px;padding:5px 8px;border:0;border-radius:5px;background:transparent;color:var(--pbb-ink);text-align:left;font:inherit;font-size:14px;cursor:pointer}
|
|
1203
|
+
.pbb-menuDanger{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1204
|
+
.pbb-actionBusy{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--pbb-secondary)}
|
|
1205
|
+
.pbb-actionBusy::before{content:"";width:10px;height:10px;border:1.5px solid var(--pbb-line);border-top-color:currentColor;border-radius:50%;animation:pbb-spin .7s linear infinite}
|
|
1206
|
+
@keyframes pbb-spin{to{transform:rotate(360deg)}}
|
|
1207
|
+
.pbb-rowAction{display:flex;flex-wrap:wrap;gap:8px}
|
|
1208
|
+
.pbb-pairingPanel{border:1px solid var(--pbb-line);border-radius:16px;padding:16px;background:var(--pbb-fill)}
|
|
1209
|
+
.pbb-pairingHeader{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}
|
|
1210
|
+
.pbb-pairingBody{display:flex;flex-direction:column;gap:10px}
|
|
1211
|
+
.pbb-targetList{display:flex;flex-wrap:wrap;gap:4px;min-width:0}
|
|
1212
|
+
.pbb-targetButton{max-width:100%;padding:5px 9px;border:1px solid transparent;border-radius:7px;background:var(--pbb-soft);color:var(--pbb-secondary);font:inherit;font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}
|
|
1213
|
+
.pbb-targetSelected{color:var(--pbb-ink);border-color:var(--pbb-line);background:var(--pbb-fill)}
|
|
1214
|
+
.pbb-qrPanel{display:grid;grid-template-columns:224px minmax(0,1fr);gap:20px;align-items:start}
|
|
1215
|
+
.pbb-qrImage{display:block;width:224px;height:224px;max-width:100%;padding:8px;border-radius:12px;background:#fff}
|
|
1216
|
+
.pbb-countdown{margin-top:10px;display:flex;flex-direction:column;gap:6px}
|
|
1217
|
+
.pbb-countdownBar{height:4px;border-radius:99px;background:var(--pbb-soft);overflow:hidden}
|
|
1218
|
+
.pbb-countdownBar i{display:block;width:100%;height:100%;transform-origin:left center;background:var(--dsw-alias-state-business-primary,#4176e6);border-radius:99px}
|
|
1219
|
+
.pbb-countdownText{font-size:12px;line-height:18px;color:var(--pbb-secondary);font-variant-numeric:tabular-nums}
|
|
1220
|
+
.pbb-pairInfo,.pbb-pairCodeBlock{display:flex;flex-direction:column;gap:8px;min-width:0}
|
|
1221
|
+
.pbb-pairCodeLabel,.pbb-qrHint{font-size:12px;line-height:18px;color:var(--pbb-secondary);margin:0}
|
|
1222
|
+
.pbb-pairCodeRow{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
|
|
1223
|
+
.pbb-pairCode{font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;overflow-wrap:anywhere;user-select:all}
|
|
1224
|
+
.pbb-tools{border-radius:16px;overflow:hidden}
|
|
1225
|
+
.pbb-toolSection+.pbb-toolSection{border-top:1px solid var(--pbb-line)}
|
|
1226
|
+
.pbb-cardHead{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:0 16px;border:0;background:transparent;color:var(--pbb-secondary);font:inherit;text-align:left;cursor:pointer}
|
|
1227
|
+
.pbb-cardHead>.pbb-cardTitle{flex:1;font-weight:400}
|
|
1228
|
+
.pbb-toolMeta{max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1229
|
+
.pbb-toolMeta.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}
|
|
1230
|
+
.pbb-toolMeta.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1231
|
+
.pbb-testGrid{display:flex;flex-direction:column;gap:0}
|
|
1232
|
+
.pbb-testItem{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--pbb-line)}
|
|
1233
|
+
.pbb-testTitle{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}
|
|
1234
|
+
.pbb-testDescription{font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1235
|
+
.pbb-helpBody,.pbb-disclosureBody{display:flex;flex-direction:column;gap:14px}
|
|
1236
|
+
.pbb-helpSection{display:flex;flex-direction:column;gap:6px}
|
|
1237
|
+
.pbb-helpHeading{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}
|
|
1238
|
+
.pbb-helpList{margin:0;padding-left:20px;font-size:14px;line-height:22px;color:var(--pbb-secondary)}
|
|
1239
|
+
.pbb-helpList li+li{margin-top:4px}
|
|
1240
|
+
.pbb-helpText{margin:0;font-size:14px;line-height:22px;color:var(--pbb-secondary)}
|
|
1241
|
+
.pbb-helpCode{display:block;margin:0;padding:10px;border:1px solid var(--pbb-line);border-radius:8px;background:var(--pbb-soft);color:var(--pbb-ink);font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
1242
|
+
.pbb-helpLink{color:var(--pbb-ink);text-decoration:underline;text-underline-offset:3px}
|
|
1243
|
+
.pbb-helpDisclosure>summary{display:flex;align-items:center;gap:6px;min-height:28px;list-style:none;cursor:pointer;color:var(--pbb-secondary);font-size:12px}
|
|
1244
|
+
.pbb-helpDisclosure>summary::-webkit-details-marker{display:none}
|
|
1245
|
+
.pbb-helpDisclosure[open]>.pbb-helpBody{padding-top:10px}
|
|
1246
|
+
.pbb-runtimeList{display:flex;flex-direction:column}
|
|
1247
|
+
.pbb-runtimeRow{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--pbb-line)}
|
|
1248
|
+
.pbb-runtimeRow>.pbb-row{flex:1;min-width:0}
|
|
1249
|
+
.pbb-updateRow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;color:var(--pbb-ink);font-size:14px;text-decoration:none}
|
|
1250
|
+
.pbb-resultRow{display:flex;align-items:flex-start;gap:6px}
|
|
1251
|
+
.pbb-resultIcon{display:inline-flex;flex:none;margin-top:3px;color:var(--dsw-alias-state-success-primary,#287a45)}
|
|
1252
|
+
.pbb-resultIconBad{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1253
|
+
.pbb-disclosure>summary{list-style:none;display:flex;align-items:center;gap:10px;min-height:44px;padding:0 16px;cursor:pointer;font-size:14px}
|
|
1254
|
+
.pbb-disclosure>summary::-webkit-details-marker{display:none}
|
|
1255
|
+
.pbb-disclosureBody{padding:2px 16px 16px}
|
|
1256
|
+
.pbb-disclosureTitle{flex:1}
|
|
1257
|
+
.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton,input,summary,a):focus-visible{outline:2px solid var(--dsw-focus-ring-color,#5276b4);outline-offset:2px}
|
|
1258
|
+
@media (hover:hover) and (pointer:fine){.pbb-refresh:hover:not(:disabled),.pbb-iconButton:hover,.pbb-action:hover:not(:disabled),.pbb-cardHead:hover,.pbb-menuAction:hover:not(:disabled){background:var(--pbb-soft)}.pbb-buttonPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,#30343b)}.pbb-action:active:not(:disabled),.pbb-refresh:active:not(:disabled),.pbb-iconButton:active{transform:scale(.97)}}
|
|
1259
|
+
@media (prefers-reduced-motion:reduce){.pbb-action,.pbb-refresh,.pbb-iconButton{transition:none;transform:none!important}.pbb-actionBusy::before{animation:none}}
|
|
1260
|
+
@container pbb (max-width:480px){.pbb-qrPanel{grid-template-columns:1fr}.pbb-limitRow{align-items:flex-start;flex-direction:column}.pbb-limitControl{align-self:flex-end}.pbb-deviceMeta{column-gap:4px}.pbb-toolMeta{max-width:42%}.pbb-channelRow{gap:8px}.pbb-testItem{flex-wrap:wrap}.pbb-testItem>.pbb-controlText{flex-basis:65%}}
|
|
1261
|
+
@container pbb (max-width:340px){.pbb-devicesHeader{flex-wrap:wrap}.pbb-deviceRow{column-gap:6px;padding-right:10px}.pbb-channelBody{padding-left:16px}.pbb-toolMeta{max-width:38%}}
|
|
1262
|
+
@media (pointer:coarse){.pbb-action,.pbb-iconButton,.pbb-refresh,.pbb-targetButton,.pbb-menuAction,.pbb-helpDisclosure>summary{min-width:44px;min-height:44px}.pbb-numberInput,.pbb-deviceNameInput{height:44px;font-size:16px}.pbb-deviceMenuBody{top:48px}}
|
|
1263
|
+
`;
|
|
1235
1264
|
/**
|
|
1236
1265
|
* Client bundle id, identical to the `window.__ModuleLoader__.load({ id })`
|
|
1237
1266
|
* identity emitted by tsdown.config.ts. DSH's module system owns style
|
|
@@ -1259,15 +1288,109 @@ window.__ModuleLoader__.load({
|
|
|
1259
1288
|
tag.textContent = CSS;
|
|
1260
1289
|
document.head.appendChild(tag);
|
|
1261
1290
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1291
|
+
// src/client/settings-icons.ts
|
|
1292
|
+
/** 设置页的小图标共用线宽与 currentColor,随宿主主题变色,不额外引入图标包。 */
|
|
1293
|
+
function settingsIcon(name, size = 18) {
|
|
1294
|
+
const path = (d) => (0, react.createElement)("path", { d });
|
|
1295
|
+
const circle = (cx, cy, r) => (0, react.createElement)("circle", {
|
|
1296
|
+
cx,
|
|
1297
|
+
cy,
|
|
1298
|
+
r
|
|
1299
|
+
});
|
|
1300
|
+
return (0, react.createElement)("svg", {
|
|
1301
|
+
className: "pbb-icon",
|
|
1302
|
+
viewBox: "0 0 24 24",
|
|
1303
|
+
width: size,
|
|
1304
|
+
height: size,
|
|
1305
|
+
fill: "none",
|
|
1306
|
+
stroke: "currentColor",
|
|
1307
|
+
strokeWidth: 1.6,
|
|
1308
|
+
strokeLinecap: "round",
|
|
1309
|
+
strokeLinejoin: "round",
|
|
1310
|
+
"aria-hidden": true
|
|
1311
|
+
}, ...{
|
|
1312
|
+
phone: () => [(0, react.createElement)("rect", {
|
|
1313
|
+
x: 6.5,
|
|
1314
|
+
y: 2.5,
|
|
1315
|
+
width: 11,
|
|
1316
|
+
height: 19,
|
|
1317
|
+
rx: 2.2
|
|
1318
|
+
}), path("M10 5h4M11 18.5h2")],
|
|
1319
|
+
wifi: () => [path("M2 8.8a16 16 0 0 1 20 0M5 12.1a11 11 0 0 1 14 0M8.3 15.5a6 6 0 0 1 7.4 0"), circle(12, 19, .7)],
|
|
1320
|
+
globe: () => [circle(12, 12, 9), path("M3 12h18M12 3a17 17 0 0 1 0 18 17 17 0 0 1 0-18")],
|
|
1321
|
+
refresh: () => [path("M20 7v5h-5M4 17v-5h5M6.1 7a7 7 0 0 1 11.5-1L20 9M4 15l2.4 3A7 7 0 0 0 18 17")],
|
|
1322
|
+
plus: () => [path("M12 5v14M5 12h14")],
|
|
1323
|
+
more: () => [
|
|
1324
|
+
circle(5, 12, 1.2),
|
|
1325
|
+
circle(12, 12, 1.2),
|
|
1326
|
+
circle(19, 12, 1.2)
|
|
1327
|
+
],
|
|
1328
|
+
activity: () => [path("M3 12h4l3-7 4 14 3-7h4")],
|
|
1329
|
+
info: () => [circle(12, 12, 9), path("M12 11v6M12 7h.01")],
|
|
1330
|
+
ready: () => [circle(12, 12, 9), path("m8 12 3 3 5-6")],
|
|
1331
|
+
attention: () => [circle(12, 12, 9), path("M12 7v6M12 17h.01")]
|
|
1332
|
+
}[name]());
|
|
1333
|
+
}
|
|
1334
|
+
// src/client/device-actions.ts
|
|
1335
|
+
/**
|
|
1336
|
+
* 原生 disclosure(折叠控件)负责 Enter/Space 与焦点顺序;操作仍是普通按钮,
|
|
1337
|
+
* 不冒充需要方向键导航的 ARIA menu。详情只在展开时进入无障碍读取顺序。
|
|
1338
|
+
*/
|
|
1339
|
+
function DeviceActions(props) {
|
|
1340
|
+
const ref = (0, react.useRef)(null);
|
|
1341
|
+
const close = (restoreFocus = false) => {
|
|
1342
|
+
const details = ref.current;
|
|
1343
|
+
if (details === null) return;
|
|
1344
|
+
details.open = false;
|
|
1345
|
+
if (restoreFocus) details.querySelector("summary")?.focus();
|
|
1346
|
+
};
|
|
1347
|
+
(0, react.useEffect)(() => {
|
|
1348
|
+
const outside = (event) => {
|
|
1349
|
+
if (event.target instanceof Node && !ref.current?.contains(event.target)) close();
|
|
1350
|
+
};
|
|
1351
|
+
document.addEventListener("pointerdown", outside);
|
|
1352
|
+
return () => document.removeEventListener("pointerdown", outside);
|
|
1353
|
+
}, []);
|
|
1354
|
+
const act = (action) => {
|
|
1355
|
+
close();
|
|
1356
|
+
action();
|
|
1357
|
+
};
|
|
1358
|
+
return (0, react.createElement)("details", {
|
|
1359
|
+
ref,
|
|
1360
|
+
className: "pbb-deviceMenu",
|
|
1361
|
+
onKeyDown: (event) => {
|
|
1362
|
+
if (event.key !== "Escape" || !ref.current?.open) return;
|
|
1363
|
+
event.preventDefault();
|
|
1364
|
+
event.stopPropagation();
|
|
1365
|
+
close(true);
|
|
1366
|
+
}
|
|
1367
|
+
}, (0, react.createElement)("summary", {
|
|
1368
|
+
className: "pbb-iconButton",
|
|
1369
|
+
"aria-label": props.t("devices.moreAria", { name: props.name })
|
|
1370
|
+
}, settingsIcon("more", 16)), (0, react.createElement)("div", {
|
|
1371
|
+
className: "pbb-deviceMenuBody",
|
|
1372
|
+
"aria-label": props.t("devices.col.actions")
|
|
1373
|
+
}, (0, react.createElement)("div", { className: "pbb-deviceMenuInfo" }, props.customName ? (0, react.createElement)("span", { className: "pbb-diag" }, props.t("devices.customBadge")) : null, (0, react.createElement)("span", { className: "pbb-diag" }, props.t("devices.col.fingerprint")), (0, react.createElement)("code", { className: "pbb-token" }, props.fingerprint || "—")), (0, react.createElement)("button", {
|
|
1374
|
+
type: "button",
|
|
1375
|
+
className: "pbb-menuAction",
|
|
1376
|
+
disabled: !props.canRename,
|
|
1377
|
+
"aria-label": props.t("devices.renameAria", { name: props.name }),
|
|
1378
|
+
onClick: () => act(props.onRename)
|
|
1379
|
+
}, props.t("devices.rename")), (0, react.createElement)("button", {
|
|
1380
|
+
type: "button",
|
|
1381
|
+
className: "pbb-menuAction pbb-menuDanger",
|
|
1382
|
+
disabled: !props.canRevoke,
|
|
1383
|
+
"aria-label": props.t("devices.revokeAria", { name: props.name }),
|
|
1384
|
+
onClick: () => act(props.onRevoke)
|
|
1385
|
+
}, props.t("devices.revoke"))));
|
|
1386
|
+
}
|
|
1387
|
+
// node_modules/qrcode/lib/can-promise.js
|
|
1264
1388
|
var require_can_promise = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1265
1389
|
module.exports = function() {
|
|
1266
1390
|
return typeof Promise === "function" && Promise.prototype && Promise.prototype.then;
|
|
1267
1391
|
};
|
|
1268
1392
|
}));
|
|
1269
|
-
|
|
1270
|
-
//#region node_modules/qrcode/lib/core/utils.js
|
|
1393
|
+
// node_modules/qrcode/lib/core/utils.js
|
|
1271
1394
|
var require_utils$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1272
1395
|
let toSJISFunction;
|
|
1273
1396
|
const CODEWORDS_COUNT = [
|
|
@@ -1358,8 +1481,7 @@ window.__ModuleLoader__.load({
|
|
|
1358
1481
|
return toSJISFunction(kanji);
|
|
1359
1482
|
};
|
|
1360
1483
|
}));
|
|
1361
|
-
|
|
1362
|
-
//#region node_modules/qrcode/lib/core/error-correction-level.js
|
|
1484
|
+
// node_modules/qrcode/lib/core/error-correction-level.js
|
|
1363
1485
|
var require_error_correction_level = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1364
1486
|
exports.L = { bit: 1 };
|
|
1365
1487
|
exports.M = { bit: 0 };
|
|
@@ -1391,8 +1513,7 @@ window.__ModuleLoader__.load({
|
|
|
1391
1513
|
}
|
|
1392
1514
|
};
|
|
1393
1515
|
}));
|
|
1394
|
-
|
|
1395
|
-
//#region node_modules/qrcode/lib/core/bit-buffer.js
|
|
1516
|
+
// node_modules/qrcode/lib/core/bit-buffer.js
|
|
1396
1517
|
var require_bit_buffer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1397
1518
|
function BitBuffer() {
|
|
1398
1519
|
this.buffer = [];
|
|
@@ -1418,8 +1539,7 @@ window.__ModuleLoader__.load({
|
|
|
1418
1539
|
};
|
|
1419
1540
|
module.exports = BitBuffer;
|
|
1420
1541
|
}));
|
|
1421
|
-
|
|
1422
|
-
//#region node_modules/qrcode/lib/core/bit-matrix.js
|
|
1542
|
+
// node_modules/qrcode/lib/core/bit-matrix.js
|
|
1423
1543
|
var require_bit_matrix = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1424
1544
|
/**
|
|
1425
1545
|
* Helper class to handle QR Code symbol modules
|
|
@@ -1479,8 +1599,7 @@ window.__ModuleLoader__.load({
|
|
|
1479
1599
|
};
|
|
1480
1600
|
module.exports = BitMatrix;
|
|
1481
1601
|
}));
|
|
1482
|
-
|
|
1483
|
-
//#region node_modules/qrcode/lib/core/alignment-pattern.js
|
|
1602
|
+
// node_modules/qrcode/lib/core/alignment-pattern.js
|
|
1484
1603
|
var require_alignment_pattern = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1485
1604
|
/**
|
|
1486
1605
|
* Alignment pattern are fixed reference pattern in defined positions
|
|
@@ -1547,8 +1666,7 @@ window.__ModuleLoader__.load({
|
|
|
1547
1666
|
return coords;
|
|
1548
1667
|
};
|
|
1549
1668
|
}));
|
|
1550
|
-
|
|
1551
|
-
//#region node_modules/qrcode/lib/core/finder-pattern.js
|
|
1669
|
+
// node_modules/qrcode/lib/core/finder-pattern.js
|
|
1552
1670
|
var require_finder_pattern = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1553
1671
|
const getSymbolSize = require_utils$1().getSymbolSize;
|
|
1554
1672
|
const FINDER_PATTERN_SIZE = 7;
|
|
@@ -1568,8 +1686,7 @@ window.__ModuleLoader__.load({
|
|
|
1568
1686
|
];
|
|
1569
1687
|
};
|
|
1570
1688
|
}));
|
|
1571
|
-
|
|
1572
|
-
//#region node_modules/qrcode/lib/core/mask-pattern.js
|
|
1689
|
+
// node_modules/qrcode/lib/core/mask-pattern.js
|
|
1573
1690
|
var require_mask_pattern = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1574
1691
|
/**
|
|
1575
1692
|
* Data mask pattern reference
|
|
@@ -1632,18 +1749,18 @@ window.__ModuleLoader__.load({
|
|
|
1632
1749
|
sameCountCol = sameCountRow = 0;
|
|
1633
1750
|
lastCol = lastRow = null;
|
|
1634
1751
|
for (let col = 0; col < size; col++) {
|
|
1635
|
-
let module
|
|
1636
|
-
if (module
|
|
1752
|
+
let module = data.get(row, col);
|
|
1753
|
+
if (module === lastCol) sameCountCol++;
|
|
1637
1754
|
else {
|
|
1638
1755
|
if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5);
|
|
1639
|
-
lastCol = module
|
|
1756
|
+
lastCol = module;
|
|
1640
1757
|
sameCountCol = 1;
|
|
1641
1758
|
}
|
|
1642
|
-
module
|
|
1643
|
-
if (module
|
|
1759
|
+
module = data.get(col, row);
|
|
1760
|
+
if (module === lastRow) sameCountRow++;
|
|
1644
1761
|
else {
|
|
1645
1762
|
if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5);
|
|
1646
|
-
lastRow = module
|
|
1763
|
+
lastRow = module;
|
|
1647
1764
|
sameCountRow = 1;
|
|
1648
1765
|
}
|
|
1649
1766
|
}
|
|
@@ -1759,8 +1876,7 @@ window.__ModuleLoader__.load({
|
|
|
1759
1876
|
return bestPattern;
|
|
1760
1877
|
};
|
|
1761
1878
|
}));
|
|
1762
|
-
|
|
1763
|
-
//#region node_modules/qrcode/lib/core/error-correction-code.js
|
|
1879
|
+
// node_modules/qrcode/lib/core/error-correction-code.js
|
|
1764
1880
|
var require_error_correction_code = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1765
1881
|
const ECLevel = require_error_correction_level();
|
|
1766
1882
|
const EC_BLOCKS_TABLE = [
|
|
@@ -2122,8 +2238,7 @@ window.__ModuleLoader__.load({
|
|
|
2122
2238
|
}
|
|
2123
2239
|
};
|
|
2124
2240
|
}));
|
|
2125
|
-
|
|
2126
|
-
//#region node_modules/qrcode/lib/core/galois-field.js
|
|
2241
|
+
// node_modules/qrcode/lib/core/galois-field.js
|
|
2127
2242
|
var require_galois_field = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2128
2243
|
const EXP_TABLE = /* @__PURE__ */ new Uint8Array(512);
|
|
2129
2244
|
const LOG_TABLE = /* @__PURE__ */ new Uint8Array(256);
|
|
@@ -2168,8 +2283,7 @@ window.__ModuleLoader__.load({
|
|
|
2168
2283
|
return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]];
|
|
2169
2284
|
};
|
|
2170
2285
|
}));
|
|
2171
|
-
|
|
2172
|
-
//#region node_modules/qrcode/lib/core/polynomial.js
|
|
2286
|
+
// node_modules/qrcode/lib/core/polynomial.js
|
|
2173
2287
|
var require_polynomial = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2174
2288
|
const GF = require_galois_field();
|
|
2175
2289
|
/**
|
|
@@ -2215,8 +2329,7 @@ window.__ModuleLoader__.load({
|
|
|
2215
2329
|
return poly;
|
|
2216
2330
|
};
|
|
2217
2331
|
}));
|
|
2218
|
-
|
|
2219
|
-
//#region node_modules/qrcode/lib/core/reed-solomon-encoder.js
|
|
2332
|
+
// node_modules/qrcode/lib/core/reed-solomon-encoder.js
|
|
2220
2333
|
var require_reed_solomon_encoder = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2221
2334
|
const Polynomial = require_polynomial();
|
|
2222
2335
|
function ReedSolomonEncoder(degree) {
|
|
@@ -2255,8 +2368,7 @@ window.__ModuleLoader__.load({
|
|
|
2255
2368
|
};
|
|
2256
2369
|
module.exports = ReedSolomonEncoder;
|
|
2257
2370
|
}));
|
|
2258
|
-
|
|
2259
|
-
//#region node_modules/qrcode/lib/core/version-check.js
|
|
2371
|
+
// node_modules/qrcode/lib/core/version-check.js
|
|
2260
2372
|
var require_version_check = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2261
2373
|
/**
|
|
2262
2374
|
* Check if QR Code version is valid
|
|
@@ -2268,8 +2380,7 @@ window.__ModuleLoader__.load({
|
|
|
2268
2380
|
return !isNaN(version) && version >= 1 && version <= 40;
|
|
2269
2381
|
};
|
|
2270
2382
|
}));
|
|
2271
|
-
|
|
2272
|
-
//#region node_modules/qrcode/lib/core/regex.js
|
|
2383
|
+
// node_modules/qrcode/lib/core/regex.js
|
|
2273
2384
|
var require_regex = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2274
2385
|
const numeric = "[0-9]+";
|
|
2275
2386
|
const alphanumeric = "[A-Z $%*+\\-./:]+";
|
|
@@ -2294,8 +2405,7 @@ window.__ModuleLoader__.load({
|
|
|
2294
2405
|
return TEST_ALPHANUMERIC.test(str);
|
|
2295
2406
|
};
|
|
2296
2407
|
}));
|
|
2297
|
-
|
|
2298
|
-
//#region node_modules/qrcode/lib/core/mode.js
|
|
2408
|
+
// node_modules/qrcode/lib/core/mode.js
|
|
2299
2409
|
var require_mode = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2300
2410
|
const VersionCheck = require_version_check();
|
|
2301
2411
|
const Regex = require_regex();
|
|
@@ -2451,8 +2561,7 @@ window.__ModuleLoader__.load({
|
|
|
2451
2561
|
}
|
|
2452
2562
|
};
|
|
2453
2563
|
}));
|
|
2454
|
-
|
|
2455
|
-
//#region node_modules/qrcode/lib/core/version.js
|
|
2564
|
+
// node_modules/qrcode/lib/core/version.js
|
|
2456
2565
|
var require_version = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2457
2566
|
const Utils = require_utils$1();
|
|
2458
2567
|
const ECCode = require_error_correction_code();
|
|
@@ -2548,8 +2657,7 @@ window.__ModuleLoader__.load({
|
|
|
2548
2657
|
return version << 12 | d;
|
|
2549
2658
|
};
|
|
2550
2659
|
}));
|
|
2551
|
-
|
|
2552
|
-
//#region node_modules/qrcode/lib/core/format-info.js
|
|
2660
|
+
// node_modules/qrcode/lib/core/format-info.js
|
|
2553
2661
|
var require_format_info = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2554
2662
|
const Utils = require_utils$1();
|
|
2555
2663
|
const G15 = 1335;
|
|
@@ -2572,8 +2680,7 @@ window.__ModuleLoader__.load({
|
|
|
2572
2680
|
return (data << 10 | d) ^ G15_MASK;
|
|
2573
2681
|
};
|
|
2574
2682
|
}));
|
|
2575
|
-
|
|
2576
|
-
//#region node_modules/qrcode/lib/core/numeric-data.js
|
|
2683
|
+
// node_modules/qrcode/lib/core/numeric-data.js
|
|
2577
2684
|
var require_numeric_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2578
2685
|
const Mode = require_mode();
|
|
2579
2686
|
function NumericData(data) {
|
|
@@ -2605,8 +2712,7 @@ window.__ModuleLoader__.load({
|
|
|
2605
2712
|
};
|
|
2606
2713
|
module.exports = NumericData;
|
|
2607
2714
|
}));
|
|
2608
|
-
|
|
2609
|
-
//#region node_modules/qrcode/lib/core/alphanumeric-data.js
|
|
2715
|
+
// node_modules/qrcode/lib/core/alphanumeric-data.js
|
|
2610
2716
|
var require_alphanumeric_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2611
2717
|
const Mode = require_mode();
|
|
2612
2718
|
/**
|
|
@@ -2689,8 +2795,7 @@ window.__ModuleLoader__.load({
|
|
|
2689
2795
|
};
|
|
2690
2796
|
module.exports = AlphanumericData;
|
|
2691
2797
|
}));
|
|
2692
|
-
|
|
2693
|
-
//#region node_modules/qrcode/lib/core/byte-data.js
|
|
2798
|
+
// node_modules/qrcode/lib/core/byte-data.js
|
|
2694
2799
|
var require_byte_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2695
2800
|
const Mode = require_mode();
|
|
2696
2801
|
function ByteData(data) {
|
|
@@ -2712,8 +2817,7 @@ window.__ModuleLoader__.load({
|
|
|
2712
2817
|
};
|
|
2713
2818
|
module.exports = ByteData;
|
|
2714
2819
|
}));
|
|
2715
|
-
|
|
2716
|
-
//#region node_modules/qrcode/lib/core/kanji-data.js
|
|
2820
|
+
// node_modules/qrcode/lib/core/kanji-data.js
|
|
2717
2821
|
var require_kanji_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2718
2822
|
const Mode = require_mode();
|
|
2719
2823
|
const Utils = require_utils$1();
|
|
@@ -2743,8 +2847,7 @@ window.__ModuleLoader__.load({
|
|
|
2743
2847
|
};
|
|
2744
2848
|
module.exports = KanjiData;
|
|
2745
2849
|
}));
|
|
2746
|
-
|
|
2747
|
-
//#region node_modules/dijkstrajs/dijkstra.js
|
|
2850
|
+
// node_modules/dijkstrajs/dijkstra.js
|
|
2748
2851
|
var require_dijkstra = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2749
2852
|
/******************************************************************************
|
|
2750
2853
|
* Created 2008-08-19.
|
|
@@ -2859,8 +2962,7 @@ window.__ModuleLoader__.load({
|
|
|
2859
2962
|
};
|
|
2860
2963
|
if (typeof module !== "undefined") module.exports = dijkstra;
|
|
2861
2964
|
}));
|
|
2862
|
-
|
|
2863
|
-
//#region node_modules/qrcode/lib/core/segments.js
|
|
2965
|
+
// node_modules/qrcode/lib/core/segments.js
|
|
2864
2966
|
var require_segments = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2865
2967
|
const Mode = require_mode();
|
|
2866
2968
|
const NumericData = require_numeric_data();
|
|
@@ -3138,8 +3240,7 @@ window.__ModuleLoader__.load({
|
|
|
3138
3240
|
return exports.fromArray(getSegmentsFromString(data, Utils.isKanjiModeEnabled()));
|
|
3139
3241
|
};
|
|
3140
3242
|
}));
|
|
3141
|
-
|
|
3142
|
-
//#region node_modules/qrcode/lib/core/qrcode.js
|
|
3243
|
+
// node_modules/qrcode/lib/core/qrcode.js
|
|
3143
3244
|
var require_qrcode = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3144
3245
|
const Utils = require_utils$1();
|
|
3145
3246
|
const ECLevel = require_error_correction_level();
|
|
@@ -3434,8 +3535,7 @@ window.__ModuleLoader__.load({
|
|
|
3434
3535
|
return createSymbol(data, version, errorCorrectionLevel, mask);
|
|
3435
3536
|
};
|
|
3436
3537
|
}));
|
|
3437
|
-
|
|
3438
|
-
//#region node_modules/qrcode/lib/renderer/utils.js
|
|
3538
|
+
// node_modules/qrcode/lib/renderer/utils.js
|
|
3439
3539
|
var require_utils = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3440
3540
|
function hex2rgba(hex) {
|
|
3441
3541
|
if (typeof hex === "number") hex = hex.toString();
|
|
@@ -3502,8 +3602,7 @@ window.__ModuleLoader__.load({
|
|
|
3502
3602
|
}
|
|
3503
3603
|
};
|
|
3504
3604
|
}));
|
|
3505
|
-
|
|
3506
|
-
//#region node_modules/qrcode/lib/renderer/canvas.js
|
|
3605
|
+
// node_modules/qrcode/lib/renderer/canvas.js
|
|
3507
3606
|
var require_canvas = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3508
3607
|
const Utils = require_utils();
|
|
3509
3608
|
function clearCanvas(ctx, canvas, size) {
|
|
@@ -3551,8 +3650,7 @@ window.__ModuleLoader__.load({
|
|
|
3551
3650
|
return canvasEl.toDataURL(type, rendererOpts.quality);
|
|
3552
3651
|
};
|
|
3553
3652
|
}));
|
|
3554
|
-
|
|
3555
|
-
//#region node_modules/qrcode/lib/renderer/svg-tag.js
|
|
3653
|
+
// node_modules/qrcode/lib/renderer/svg-tag.js
|
|
3556
3654
|
var require_svg_tag = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3557
3655
|
const Utils = require_utils();
|
|
3558
3656
|
function getColorAttrib(color, attrib) {
|
|
@@ -3602,8 +3700,7 @@ window.__ModuleLoader__.load({
|
|
|
3602
3700
|
return svgTag;
|
|
3603
3701
|
};
|
|
3604
3702
|
}));
|
|
3605
|
-
|
|
3606
|
-
//#region src/pairing-qr.ts
|
|
3703
|
+
// src/pairing-qr.ts
|
|
3607
3704
|
var import_browser = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3608
3705
|
const canPromise = require_can_promise();
|
|
3609
3706
|
const QRCode = require_qrcode();
|
|
@@ -3729,8 +3826,7 @@ window.__ModuleLoader__.load({
|
|
|
3729
3826
|
if (!grant.audience.startsWith("deeppilot:")) throw new TypeError("pairing audience is invalid");
|
|
3730
3827
|
if (tlsFingerprint !== void 0 && !isLanTlsFingerprint(tlsFingerprint)) throw new TypeError("pairing TLS fingerprint is invalid");
|
|
3731
3828
|
}
|
|
3732
|
-
|
|
3733
|
-
//#region src/client/pairing-panel.ts
|
|
3829
|
+
// src/client/pairing-panel.ts
|
|
3734
3830
|
const initialPairingPanelState = {
|
|
3735
3831
|
target: null,
|
|
3736
3832
|
busy: false,
|
|
@@ -3804,16 +3900,14 @@ window.__ModuleLoader__.load({
|
|
|
3804
3900
|
function normalizeFunnelConnectionLimit(value) {
|
|
3805
3901
|
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 16 ? value : 8;
|
|
3806
3902
|
}
|
|
3807
|
-
|
|
3808
|
-
//#region src/local-policy.ts
|
|
3903
|
+
// src/local-policy.ts
|
|
3809
3904
|
const DEFAULT_LOCAL_PORT = 3098;
|
|
3810
3905
|
const MIN_LOCAL_PORT = 1024;
|
|
3811
3906
|
const MAX_LOCAL_PORT = 65535;
|
|
3812
3907
|
function normalizeLocalPort(value) {
|
|
3813
3908
|
return typeof value === "number" && Number.isInteger(value) && value >= 1024 && value <= 65535 ? value : DEFAULT_LOCAL_PORT;
|
|
3814
3909
|
}
|
|
3815
|
-
|
|
3816
|
-
//#region src/client/settings-props.ts
|
|
3910
|
+
// src/client/settings-props.ts
|
|
3817
3911
|
const MISSING_REPORT_HOOK = () => ({
|
|
3818
3912
|
status: "loading",
|
|
3819
3913
|
report: null,
|
|
@@ -3948,17 +4042,7 @@ window.__ModuleLoader__.load({
|
|
|
3948
4042
|
reportHookMissing: !isFn(source.useDeepPilotReport)
|
|
3949
4043
|
};
|
|
3950
4044
|
}
|
|
3951
|
-
|
|
3952
|
-
//#region src/client/settings-view-models.ts
|
|
3953
|
-
/**
|
|
3954
|
-
* 设置页的 view model:把原先住在渲染函数里的三块逻辑变成可单测的纯模块。
|
|
3955
|
-
*
|
|
3956
|
-
* 迁移前 `settings-page.ts` 是一个 1059 行的组件,funnel phase → {dot, label}、
|
|
3957
|
-
端口/连接数草稿的编辑与合法性、serviceStatus 派生全在渲染函数里,没有任何
|
|
3958
|
-
直接测试。这里按 pairing-panel.ts 的形状把它们拆成 state / action / reduce /
|
|
3959
|
-
view 四件套——shape 与该先例一致,但**不继承它唯一的泄漏**:view model 只返回
|
|
3960
|
-
语义值,i18n key 的映射留在页面(措辞归页面,测试不跟着措辞漂)。
|
|
3961
|
-
*/
|
|
4045
|
+
// src/client/settings-view-models.ts
|
|
3962
4046
|
const REMOTE_PHASE_META = {
|
|
3963
4047
|
disabled: {
|
|
3964
4048
|
dot: "",
|
|
@@ -4093,26 +4177,10 @@ window.__ModuleLoader__.load({
|
|
|
4093
4177
|
function deviceLabel(device) {
|
|
4094
4178
|
return (device.customName ?? device.deviceName).trim();
|
|
4095
4179
|
}
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
disabled: "phase.disabled",
|
|
4101
|
-
starting: "phase.starting",
|
|
4102
|
-
login_required: "phase.login_required",
|
|
4103
|
-
online: "phase.online",
|
|
4104
|
-
error: "phase.error",
|
|
4105
|
-
unavailable: "phase.unavailable",
|
|
4106
|
-
stopped: "phase.stopped"
|
|
4107
|
-
};
|
|
4108
|
-
const LOCAL_LABEL_KEY = {
|
|
4109
|
-
disabled: "local.phaseDisabled",
|
|
4110
|
-
starting: "local.phaseStarting",
|
|
4111
|
-
online: "local.phaseOnline",
|
|
4112
|
-
error: "local.phaseError",
|
|
4113
|
-
stopped: "local.phaseStopped"
|
|
4114
|
-
};
|
|
4115
|
-
/** 状态条用的短状态:列标签已经写明是哪条通道,值只说状态,免得在窄格里被截断。 */
|
|
4180
|
+
// src/client/settings-page.ts
|
|
4181
|
+
/** 中文结论由调用处提供,原始上游信息统一放入括号,保留排查依据。 */
|
|
4182
|
+
const errorDetails = (error) => "(" + (error instanceof Error ? error.message : String(error)) + ")";
|
|
4183
|
+
/** 通道标题旁的短状态;完整端点和参数放入对应的连接选项。 */
|
|
4116
4184
|
const CHANNEL_STATE_KEY = {
|
|
4117
4185
|
disabled: "channel.state.disabled",
|
|
4118
4186
|
starting: "channel.state.starting",
|
|
@@ -4129,21 +4197,6 @@ window.__ModuleLoader__.load({
|
|
|
4129
4197
|
attention: "status.attention",
|
|
4130
4198
|
ready: "status.ready"
|
|
4131
4199
|
};
|
|
4132
|
-
/** Inline trash icon for the compact destructive row action. Kept as a tiny
|
|
4133
|
-
* element (no icon dependency) so the client bundle stays dependency-free
|
|
4134
|
-
* apart from React. */
|
|
4135
|
-
const TrashIcon = () => (0, react.createElement)("svg", {
|
|
4136
|
-
className: "pbb-actionIcon",
|
|
4137
|
-
viewBox: "0 0 16 16",
|
|
4138
|
-
width: 13,
|
|
4139
|
-
height: 13,
|
|
4140
|
-
fill: "none",
|
|
4141
|
-
stroke: "currentColor",
|
|
4142
|
-
strokeWidth: 1.5,
|
|
4143
|
-
strokeLinecap: "round",
|
|
4144
|
-
strokeLinejoin: "round",
|
|
4145
|
-
"aria-hidden": true
|
|
4146
|
-
}, (0, react.createElement)("path", { d: "M2.5 4.5h11" }), (0, react.createElement)("path", { d: "M6.5 2.5h3" }), (0, react.createElement)("path", { d: "M4 4.5l.6 8.2a1 1 0 0 0 1 .9h4.8a1 1 0 0 0 1-.9l.6-8.2" }), (0, react.createElement)("path", { d: "M6.6 7v4.2" }), (0, react.createElement)("path", { d: "M9.4 7v4.2" }));
|
|
4147
4200
|
/** Chevron icon (linear, currentColor). CSS rotates it 90° while its owner is
|
|
4148
4201
|
* expanded, so collapsed always means "points right, more content behind". */
|
|
4149
4202
|
const ChevronIcon = () => (0, react.createElement)("svg", {
|
|
@@ -4158,8 +4211,7 @@ window.__ModuleLoader__.load({
|
|
|
4158
4211
|
strokeLinejoin: "round",
|
|
4159
4212
|
"aria-hidden": true
|
|
4160
4213
|
}, (0, react.createElement)("path", { d: "M6 3.5 10.5 8 6 12.5" }));
|
|
4161
|
-
/**
|
|
4162
|
-
* dingbats '✓'/'✗', which the repo's visual rules reject as character icons. */
|
|
4214
|
+
/** 诊断结果使用线性 SVG,与页面其余图标保持一致。 */
|
|
4163
4215
|
const CheckIcon = () => (0, react.createElement)("svg", {
|
|
4164
4216
|
viewBox: "0 0 16 16",
|
|
4165
4217
|
width: 12,
|
|
@@ -4226,6 +4278,13 @@ window.__ModuleLoader__.load({
|
|
|
4226
4278
|
const [remoteLimitDraft, dispatchRemoteLimitDraft] = (0, react.useReducer)((state, action) => numericDraftReduce(state, action, REMOTE_LIMIT_RANGE), initialNumericDraft(REMOTE_LIMIT_RANGE));
|
|
4227
4279
|
const [localPortDraft, dispatchLocalPortDraft] = (0, react.useReducer)((state, action) => numericDraftReduce(state, action, LOCAL_PORT_RANGE), initialNumericDraft(LOCAL_PORT_RANGE));
|
|
4228
4280
|
const [selectedPairingHost, setSelectedPairingHost] = (0, react.useState)(null);
|
|
4281
|
+
const [pairingOpen, setPairingOpen] = (0, react.useState)(false);
|
|
4282
|
+
const pageId = (0, react.useId)();
|
|
4283
|
+
const localOptionsId = pageId + "-local";
|
|
4284
|
+
const remoteOptionsId = pageId + "-remote";
|
|
4285
|
+
const troubleshootingId = pageId + "-troubleshooting";
|
|
4286
|
+
const systemId = pageId + "-system";
|
|
4287
|
+
const pairingId = pageId + "-pairing";
|
|
4229
4288
|
const [pairingPanel, dispatchPairingPanel] = (0, react.useReducer)(pairingPanelReduce, initialPairingPanelState);
|
|
4230
4289
|
const qrRequestId = (0, react.useRef)(0);
|
|
4231
4290
|
const [troubleshootingOpen, setTroubleshootingOpen] = (0, react.useState)(false);
|
|
@@ -4236,7 +4295,6 @@ window.__ModuleLoader__.load({
|
|
|
4236
4295
|
const [pushTestResult, setPushTestResult] = (0, react.useState)(null);
|
|
4237
4296
|
const [pushTestError, setPushTestError] = (0, react.useState)("");
|
|
4238
4297
|
const [deviceBusy, setDeviceBusy] = (0, react.useState)(null);
|
|
4239
|
-
const [deviceBusyAction, setDeviceBusyAction] = (0, react.useState)(null);
|
|
4240
4298
|
const [deviceMessage, setDeviceMessage] = (0, react.useState)("");
|
|
4241
4299
|
const [editingDeviceId, setEditingDeviceId] = (0, react.useState)(null);
|
|
4242
4300
|
const [deviceNameDraft, setDeviceNameDraft] = (0, react.useState)("");
|
|
@@ -4270,7 +4328,7 @@ window.__ModuleLoader__.load({
|
|
|
4270
4328
|
setPushTestResult(result);
|
|
4271
4329
|
setPushTestBusy(false);
|
|
4272
4330
|
}, (error) => {
|
|
4273
|
-
setPushTestError(
|
|
4331
|
+
setPushTestError(translateWith(props.t, "push.pushFailed") + errorDetails(error));
|
|
4274
4332
|
setPushTestBusy(false);
|
|
4275
4333
|
});
|
|
4276
4334
|
};
|
|
@@ -4287,7 +4345,7 @@ window.__ModuleLoader__.load({
|
|
|
4287
4345
|
setRelayTestResult(result);
|
|
4288
4346
|
setRelayTestBusy(false);
|
|
4289
4347
|
}, (error) => {
|
|
4290
|
-
setRelayTestError(
|
|
4348
|
+
setRelayTestError(translateWith(props.t, "push.relayBad") + errorDetails(error));
|
|
4291
4349
|
setRelayTestBusy(false);
|
|
4292
4350
|
});
|
|
4293
4351
|
};
|
|
@@ -4323,7 +4381,7 @@ window.__ModuleLoader__.load({
|
|
|
4323
4381
|
const reportState = props.useDeepPilotReport((s) => s);
|
|
4324
4382
|
hooks.report = reportState.report;
|
|
4325
4383
|
if (reportState.status === "error" && reportState.message) {
|
|
4326
|
-
diag.push(reportState.message);
|
|
4384
|
+
diag.push(translateWith(props.t, "diag.reportFailed") + errorDetails(reportState.message));
|
|
4327
4385
|
failed = true;
|
|
4328
4386
|
}
|
|
4329
4387
|
const enabledState = props.useDeepPilotEnabled((s) => s);
|
|
@@ -4364,7 +4422,7 @@ window.__ModuleLoader__.load({
|
|
|
4364
4422
|
try {
|
|
4365
4423
|
readHooks();
|
|
4366
4424
|
} catch (error) {
|
|
4367
|
-
diag.push(translateWith(props.t, "diag.renderError") + (error
|
|
4425
|
+
diag.push(translateWith(props.t, "diag.renderError") + errorDetails(error));
|
|
4368
4426
|
failed = true;
|
|
4369
4427
|
}
|
|
4370
4428
|
const report = hooks.report;
|
|
@@ -4411,7 +4469,7 @@ window.__ModuleLoader__.load({
|
|
|
4411
4469
|
}, (error) => {
|
|
4412
4470
|
dispatchLocalPortDraft({
|
|
4413
4471
|
type: "failed",
|
|
4414
|
-
message: translateWith(props.t, "local.portFailed") + (error
|
|
4472
|
+
message: translateWith(props.t, "local.portFailed") + errorDetails(error)
|
|
4415
4473
|
});
|
|
4416
4474
|
});
|
|
4417
4475
|
};
|
|
@@ -4432,7 +4490,7 @@ window.__ModuleLoader__.load({
|
|
|
4432
4490
|
}, (error) => {
|
|
4433
4491
|
dispatchRemoteLimitDraft({
|
|
4434
4492
|
type: "failed",
|
|
4435
|
-
message: translateWith(props.t, "remote.limitFailed") + (error
|
|
4493
|
+
message: translateWith(props.t, "remote.limitFailed") + errorDetails(error)
|
|
4436
4494
|
});
|
|
4437
4495
|
});
|
|
4438
4496
|
};
|
|
@@ -4482,7 +4540,7 @@ window.__ModuleLoader__.load({
|
|
|
4482
4540
|
dispatchPairingPanel({
|
|
4483
4541
|
type: "failed",
|
|
4484
4542
|
requestId,
|
|
4485
|
-
message: translateWith(props.t, "pair.qrFailed") + (error
|
|
4543
|
+
message: translateWith(props.t, "pair.qrFailed") + errorDetails(error)
|
|
4486
4544
|
});
|
|
4487
4545
|
});
|
|
4488
4546
|
};
|
|
@@ -4505,7 +4563,7 @@ window.__ModuleLoader__.load({
|
|
|
4505
4563
|
}, (error) => {
|
|
4506
4564
|
dispatchPairingPanel({
|
|
4507
4565
|
type: "notice",
|
|
4508
|
-
message: translateWith(props.t, "pair.infoCopyFailed") + (error
|
|
4566
|
+
message: translateWith(props.t, "pair.infoCopyFailed") + errorDetails(error)
|
|
4509
4567
|
});
|
|
4510
4568
|
});
|
|
4511
4569
|
};
|
|
@@ -4526,15 +4584,13 @@ window.__ModuleLoader__.load({
|
|
|
4526
4584
|
const revokeDevice = (deviceId, _name) => {
|
|
4527
4585
|
if (!can("revokeDevice")) return;
|
|
4528
4586
|
setDeviceBusy(deviceId);
|
|
4529
|
-
setDeviceBusyAction("revoke");
|
|
4530
4587
|
setDeviceMessage("");
|
|
4531
4588
|
props.revokeDevice(deviceId).then(() => {
|
|
4532
4589
|
setDeviceMessage(translateWith(props.t, "devices.revoked"));
|
|
4533
4590
|
}, (error) => {
|
|
4534
|
-
setDeviceMessage(translateWith(props.t, "devices.revokeFailed") + (error
|
|
4591
|
+
setDeviceMessage(translateWith(props.t, "devices.revokeFailed") + errorDetails(error));
|
|
4535
4592
|
}).finally(() => {
|
|
4536
4593
|
setDeviceBusy(null);
|
|
4537
|
-
setDeviceBusyAction(null);
|
|
4538
4594
|
});
|
|
4539
4595
|
};
|
|
4540
4596
|
const deviceLabel$1 = (device) => deviceLabel(device) || translateWith(props.t, "devices.unnamed");
|
|
@@ -4557,17 +4613,15 @@ window.__ModuleLoader__.load({
|
|
|
4557
4613
|
return;
|
|
4558
4614
|
}
|
|
4559
4615
|
setDeviceBusy(deviceId);
|
|
4560
|
-
setDeviceBusyAction("rename");
|
|
4561
4616
|
setDeviceMessage("");
|
|
4562
4617
|
props.setDeviceName(deviceId, normalized === "" ? null : normalized).then(() => {
|
|
4563
4618
|
setDeviceMessage(normalized === "" ? translateWith(props.t, "devices.nameCleared") : translateWith(props.t, "devices.renamed"));
|
|
4564
4619
|
setEditingDeviceId(null);
|
|
4565
4620
|
setDeviceNameDraft("");
|
|
4566
4621
|
}, (error) => {
|
|
4567
|
-
setDeviceMessage(translateWith(props.t, "devices.renameFailed") + (error
|
|
4622
|
+
setDeviceMessage(translateWith(props.t, "devices.renameFailed") + errorDetails(error));
|
|
4568
4623
|
}).finally(() => {
|
|
4569
4624
|
setDeviceBusy(null);
|
|
4570
|
-
setDeviceBusyAction(null);
|
|
4571
4625
|
});
|
|
4572
4626
|
};
|
|
4573
4627
|
const visibleDevices$1 = visibleDevices(report);
|
|
@@ -4583,10 +4637,10 @@ window.__ModuleLoader__.load({
|
|
|
4583
4637
|
"data-armed": armed || void 0,
|
|
4584
4638
|
"aria-busy": busy,
|
|
4585
4639
|
"aria-label": translateWith(props.t, "devices.col.name") + ": " + label
|
|
4586
|
-
}, (0, react.createElement)("div", { className: "pbb-deviceMain" }, (0, react.createElement)("div", { className: "pbb-
|
|
4640
|
+
}, (0, react.createElement)("div", { className: "pbb-deviceMain" }, settingsIcon("phone"), (0, react.createElement)("div", { className: "pbb-deviceText" }, (0, react.createElement)("span", {
|
|
4587
4641
|
className: "pbb-deviceName",
|
|
4588
4642
|
title: label
|
|
4589
|
-
}, label),
|
|
4643
|
+
}, label), (0, react.createElement)("div", { className: "pbb-deviceMeta" }, (0, react.createElement)("span", null, d.appVersion), (0, react.createElement)("span", null, translateWith(props.t, "devices.col.lastSeen") + " " + formatLastSeen(d.lastSeenTs))))), editing ? (0, react.createElement)("form", {
|
|
4590
4644
|
className: "pbb-deviceRenameForm",
|
|
4591
4645
|
onSubmit: (event) => {
|
|
4592
4646
|
event.preventDefault();
|
|
@@ -4624,25 +4678,22 @@ window.__ModuleLoader__.load({
|
|
|
4624
4678
|
title: translateWith(props.t, "devices.nameCancel"),
|
|
4625
4679
|
"aria-label": translateWith(props.t, "devices.nameCancel"),
|
|
4626
4680
|
onClick: cancelDeviceRename
|
|
4627
|
-
}, translateWith(props.t, "devices.nameCancel"))), deviceNameDraft.length > 64 ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "devices.nameInvalid")) : null) : null, armed ? null : (0, react.createElement)("div", {
|
|
4628
|
-
className: "pbb-
|
|
4629
|
-
|
|
4630
|
-
},
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
disabled: busy,
|
|
4640
|
-
"aria-label": busy && deviceBusyAction === "revoke" ? translateWith(props.t, "devices.deleting", { name: label }) : translateWith(props.t, "devices.revokeAria", { name: label }),
|
|
4641
|
-
onClick: () => {
|
|
4681
|
+
}, translateWith(props.t, "devices.nameCancel"))), deviceNameDraft.length > 64 ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "devices.nameInvalid")) : null) : null, armed || editing ? null : (0, react.createElement)("div", { className: "pbb-deviceActions" }, busy ? (0, react.createElement)("span", {
|
|
4682
|
+
className: "pbb-actionBusy",
|
|
4683
|
+
role: "status"
|
|
4684
|
+
}, translateWith(props.t, "devices.deleting")) : (0, react.createElement)(DeviceActions, {
|
|
4685
|
+
name: label,
|
|
4686
|
+
fingerprint,
|
|
4687
|
+
customName: d.customName,
|
|
4688
|
+
canRename: editingDeviceId === null && can("setDeviceName"),
|
|
4689
|
+
canRevoke: can("revokeDevice"),
|
|
4690
|
+
t: props.t,
|
|
4691
|
+
onRename: () => beginDeviceRename(d),
|
|
4692
|
+
onRevoke: () => {
|
|
4642
4693
|
cancelDeviceRename();
|
|
4643
4694
|
setArmedRevokeDeviceId(d.deviceId);
|
|
4644
4695
|
}
|
|
4645
|
-
}
|
|
4696
|
+
})), armed && !busy ? (0, react.createElement)("div", { className: "pbb-deviceConfirm" }, (0, react.createElement)("p", {
|
|
4646
4697
|
className: "pbb-diag pbb-diagBad",
|
|
4647
4698
|
role: "alert"
|
|
4648
4699
|
}, translateWith(props.t, "devices.revokeConfirm", { name: label })), (0, react.createElement)("div", { className: "pbb-rowAction" }, (0, react.createElement)("button", {
|
|
@@ -4660,27 +4711,32 @@ window.__ModuleLoader__.load({
|
|
|
4660
4711
|
}, translateWith(props.t, "devices.nameCancel")))) : null);
|
|
4661
4712
|
})) : (0, react.createElement)("p", { className: "pbb-empty" }, translateWith(props.t, "devices.empty"));
|
|
4662
4713
|
const switchTitle = translateWith(props.t, "master.title");
|
|
4663
|
-
const switchDesc = switchReady ? enabled ? translateWith(props.t, "master.on") : translateWith(props.t, "master.off") : translateWith(props.t, "master.loading");
|
|
4664
4714
|
const localMeta = report === null ? null : LOCAL_PHASE_META[report.local.phase];
|
|
4665
4715
|
const remoteMeta = report === null ? null : REMOTE_PHASE_META[report.remote.phase];
|
|
4666
4716
|
const service = serviceStatus({
|
|
4667
4717
|
enabled,
|
|
4668
|
-
switchReady,
|
|
4718
|
+
switchReady: switchReady && report !== null,
|
|
4669
4719
|
localDot: localMeta?.dot,
|
|
4670
4720
|
remoteDot: remoteMeta?.dot
|
|
4671
4721
|
});
|
|
4672
4722
|
const serviceStatusText = translateWith(props.t, SERVICE_STATUS_KEY[service.kind]);
|
|
4673
|
-
const serviceDot = service.dot;
|
|
4674
|
-
const localPhaseText = localMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, LOCAL_LABEL_KEY[localMeta.label]);
|
|
4675
|
-
const remotePhaseText = remoteMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, REMOTE_LABEL_KEY[remoteMeta.label]);
|
|
4676
4723
|
const localStateText = localMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, CHANNEL_STATE_KEY[localMeta.label]);
|
|
4677
4724
|
const remoteStateText = remoteMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, CHANNEL_STATE_KEY[remoteMeta.label]);
|
|
4678
4725
|
/** 一条失败事件的单行文本:时间 · 类型 · 分因,附带可选排查字段。 */
|
|
4679
4726
|
const diagnosticLine = (failure) => {
|
|
4680
4727
|
const base = translateWith(props.t, "diagnostics.item", {
|
|
4681
4728
|
time: new Date(failure.ts).toLocaleString(),
|
|
4682
|
-
kind:
|
|
4683
|
-
|
|
4729
|
+
kind: translateWith(props.t, {
|
|
4730
|
+
"upgrade-rejected": "diagnostics.kind.upgrade",
|
|
4731
|
+
"pair-rejected": "diagnostics.kind.pair",
|
|
4732
|
+
"auth-failed": "diagnostics.kind.auth",
|
|
4733
|
+
"connection-opened": "diagnostics.kind.opened",
|
|
4734
|
+
"connection-closed": "diagnostics.kind.closed",
|
|
4735
|
+
"connection-error": "diagnostics.kind.error",
|
|
4736
|
+
identity: "diagnostics.kind.identity",
|
|
4737
|
+
storage: "diagnostics.kind.storage"
|
|
4738
|
+
}[failure.kind] ?? "diagnostics.kind.unknown"),
|
|
4739
|
+
reason: "(" + failure.kind + " / " + failure.reason + ")"
|
|
4684
4740
|
});
|
|
4685
4741
|
const extras = [];
|
|
4686
4742
|
if (failure.attemptId !== void 0) extras.push(translateWith(props.t, "diagnostics.attempt", { id: failure.attemptId }));
|
|
@@ -4717,12 +4773,12 @@ window.__ModuleLoader__.load({
|
|
|
4717
4773
|
});
|
|
4718
4774
|
}, (error) => {
|
|
4719
4775
|
setDiagnosticsCopy({
|
|
4720
|
-
message: translateWith(props.t, "diagnostics.copyFailed") + (error
|
|
4776
|
+
message: translateWith(props.t, "diagnostics.copyFailed") + errorDetails(error),
|
|
4721
4777
|
failed: true
|
|
4722
4778
|
});
|
|
4723
4779
|
});
|
|
4724
4780
|
};
|
|
4725
|
-
const diagnosticsSection = report === null ? null : (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-
|
|
4781
|
+
const diagnosticsSection = report === null ? null : (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "diagnostics.title")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "diagnostics.description"))), (0, react.createElement)("button", {
|
|
4726
4782
|
type: "button",
|
|
4727
4783
|
className: "pbb-action",
|
|
4728
4784
|
onClick: copyDiagnostics,
|
|
@@ -4734,14 +4790,10 @@ window.__ModuleLoader__.load({
|
|
|
4734
4790
|
className: "pbb-diag",
|
|
4735
4791
|
key: String(index)
|
|
4736
4792
|
}, diagnosticLine(failure)))));
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
title: label + " · " + value + (sub === "" ? "" : " · " + sub)
|
|
4742
|
-
}, (0, react.createElement)("div", { className: "pbb-statusLabel" }, label), (0, react.createElement)("div", { className: "pbb-statusValue" }, dot === null ? null : (0, react.createElement)("span", { className: "pbb-dot" + dot }), value), (0, react.createElement)("div", { className: "pbb-statusSub" }, sub));
|
|
4743
|
-
/** 折叠区:grid-rows 0fr→1fr 平滑开合(mockup 的做法),不用 <details> 的瞬时跳变。 */
|
|
4744
|
-
const fold = (open, body) => (0, react.createElement)("div", { className: "pbb-fold" + (open ? "" : " pbb-foldClosed") }, (0, react.createElement)("div", null, body));
|
|
4793
|
+
const fold = (open, body) => (0, react.createElement)("div", {
|
|
4794
|
+
className: "pbb-fold",
|
|
4795
|
+
hidden: !open
|
|
4796
|
+
}, body);
|
|
4745
4797
|
/** 配对倒计时:仅在 QR 面板打开且 grant 在场时每秒刷新一次。 */
|
|
4746
4798
|
(0, react.useEffect)(() => {
|
|
4747
4799
|
if (!panel.open || pairingPanel.grant === null) return;
|
|
@@ -4751,44 +4803,19 @@ window.__ModuleLoader__.load({
|
|
|
4751
4803
|
const grantRemainingMs = pairingPanel.grant === null ? 0 : Math.max(0, pairingPanel.grant.expiresAt - nowMs);
|
|
4752
4804
|
const grantRemainingText = String(Math.floor(grantRemainingMs / 6e4)) + ":" + String(Math.floor(grantRemainingMs / 1e3) % 60).padStart(2, "0");
|
|
4753
4805
|
const grantRemainingPct = Math.min(100, grantRemainingMs / 3e5 * 100);
|
|
4754
|
-
const localDesc = localSwitchReady ? localEnabled ? translateWith(props.t, "local.on", { port: localPort }) : translateWith(props.t, "local.off") : translateWith(props.t, "master.loading");
|
|
4755
|
-
const remoteDesc = remoteSwitchReady ? remoteEnabled ? translateWith(props.t, "remote.on") : translateWith(props.t, "remote.off") : translateWith(props.t, "master.loading");
|
|
4756
|
-
/** 端点 → 状态条副行只暴露 host[:port],去掉协议前缀让一行能放下。 */
|
|
4757
|
-
const endpointHost = (value) => {
|
|
4758
|
-
if (value === void 0 || value === "") return void 0;
|
|
4759
|
-
try {
|
|
4760
|
-
return new URL(value).host;
|
|
4761
|
-
} catch {
|
|
4762
|
-
return value;
|
|
4763
|
-
}
|
|
4764
|
-
};
|
|
4765
|
-
const localStatusSub = !localSwitchReady ? translateWith(props.t, "master.loading") : report !== null && report.local.phase === "online" ? endpointHost(report.local.endpoints[0]) ?? localDesc : report !== null && report.local.phase === "error" ? report.local.message !== void 0 && report.local.message !== "" ? report.local.message : localDesc : report !== null && (report.local.phase === "disabled" || report.local.phase === "stopped") ? translateWith(props.t, "local.off") : localDesc;
|
|
4766
|
-
const remoteStatusSub = !remoteSwitchReady ? translateWith(props.t, "master.loading") : report !== null && report.remote.phase === "online" ? endpointHost(report.remote.publicURL) ?? remoteDesc : report !== null && report.remote.phase === "error" ? report.remote.message !== void 0 && report.remote.message !== "" ? report.remote.message : remoteDesc : report !== null && report.remote.phase === "disabled" ? translateWith(props.t, "remote.off") : remoteDesc;
|
|
4767
|
-
const isOffPhase = (phase) => phase === "disabled" || phase === "stopped";
|
|
4768
|
-
const localSettled = report === null || (localEnabled ? report.local.phase === "online" : isOffPhase(report.local.phase));
|
|
4769
|
-
const remoteSettled = report === null || (remoteEnabled ? report.remote.phase === "online" : isOffPhase(report.remote.phase));
|
|
4770
|
-
const localChannelDesc = localSettled ? localDesc : localPhaseText + " · " + localDesc;
|
|
4771
|
-
const remoteChannelDesc = remoteSettled ? remoteDesc : remotePhaseText + " · " + remoteDesc;
|
|
4772
4806
|
const recentFailures = report?.diagnostics?.recentFailures ?? [];
|
|
4773
4807
|
const troubleGood = relayTestResult !== null ? relayTestResult.overall === "ok" : pushTestResult !== null ? pushTestResult.overall === "sent" : false;
|
|
4774
4808
|
const troubleBad = relayTestResult !== null ? relayTestResult.overall !== "ok" : pushTestResult !== null ? pushTestResult.overall !== "sent" : recentFailures.length > 0;
|
|
4775
|
-
const troubleConclusion = relayTestResult !== null ? relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad") : pushTestResult !== null ? pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : translateWith(props.t, "push.pushFailed") : recentFailures.length > 0 ? translateWith(props.t, "diagnostics.
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
if (can("refresh")) props.refresh();
|
|
4781
|
-
}
|
|
4782
|
-
}, translateWith(props.t, "meta.refresh"))), (0, react.createElement)("section", { className: "pbb-statusStrip" }, statusCell(translateWith(props.t, "master.title"), serviceDot, serviceStatusText, switchDesc), statusCell(translateWith(props.t, "local.title"), localMeta?.dot ?? "", localStateText, localStatusSub), statusCell(translateWith(props.t, "remote.title"), remoteMeta?.dot ?? "", remoteStateText, remoteStatusSub), statusCell(translateWith(props.t, "panel.activeConnections"), null, report === null ? translateWith(props.t, "status.loading") : String(report.activeConnections), translateWith(props.t, "panel.identity") + " · " + (report !== null && report.pairingReady ? translateWith(props.t, "panel.identityReady") : translateWith(props.t, "panel.identityNotReady")))), report === null ? null : (0, react.createElement)("div", { className: "pbb-card" }, (0, react.createElement)("div", { className: "pbb-cardHeader" }, (0, react.createElement)("div", null, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "pair.qrPanelTitle")), (0, react.createElement)("p", { className: "pbb-cardDescription" }, translateWith(props.t, "pair.description"))), pairingTarget === null ? (0, react.createElement)("span", { className: "pbb-statusBadge" + (enabled ? " pbb-bad" : "") }, enabled ? translateWith(props.t, "pair.noAddress") : translateWith(props.t, "status.off")) : (0, react.createElement)("button", {
|
|
4809
|
+
const troubleConclusion = relayTestResult !== null ? relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad") : pushTestResult !== null ? pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : translateWith(props.t, "push.pushFailed") : recentFailures.length > 0 ? translateWith(props.t, "diagnostics.historyCount", { count: recentFailures.length }) : "";
|
|
4810
|
+
const pairingSection = (0, react.createElement)("div", {
|
|
4811
|
+
id: pairingId,
|
|
4812
|
+
hidden: !pairingOpen
|
|
4813
|
+
}, !pairingOpen || report === null ? null : (0, react.createElement)("div", { className: "pbb-pairingPanel" }, (0, react.createElement)("div", { className: "pbb-pairingHeader" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "pair.qrPanelTitle")), !panel.open && pairingTarget !== null ? (0, react.createElement)("button", {
|
|
4783
4814
|
type: "button",
|
|
4784
|
-
className: "pbb-action
|
|
4785
|
-
disabled: panel.busy ||
|
|
4786
|
-
onClick: () =>
|
|
4787
|
-
|
|
4788
|
-
if (panel.open) hidePairingQR();
|
|
4789
|
-
else showPairingQR(pairingTarget);
|
|
4790
|
-
}
|
|
4791
|
-
}, translateWith(props.t, panel.action))), (0, react.createElement)("div", { className: "pbb-pairingBody" }, pairingTarget === null ? (0, react.createElement)("p", { className: "pbb-diag" }, enabled ? translateWith(props.t, "pair.noAddressHelp") : translateWith(props.t, "pair.disabledHelp")) : null, pairingTargets.length < 2 ? null : (0, react.createElement)("div", { className: "pbb-targetList" }, pairingTargets.map((target) => (0, react.createElement)("button", {
|
|
4815
|
+
className: "pbb-action",
|
|
4816
|
+
disabled: panel.busy || !report.pairingReady,
|
|
4817
|
+
onClick: () => showPairingQR(pairingTarget)
|
|
4818
|
+
}, translateWith(props.t, "pair.qrShow")) : null), (0, react.createElement)("div", { className: "pbb-pairingBody" }, pairingTarget === null ? (0, react.createElement)("p", { className: "pbb-diag" }, enabled ? translateWith(props.t, "pair.noAddressHelp") : translateWith(props.t, "pair.disabledHelp")) : null, pairingTargets.length < 2 ? null : (0, react.createElement)("div", { className: "pbb-targetList" }, pairingTargets.map((target) => (0, react.createElement)("button", {
|
|
4792
4819
|
type: "button",
|
|
4793
4820
|
key: target.host,
|
|
4794
4821
|
className: "pbb-targetButton" + (target.host === pairingTarget?.host ? " pbb-targetSelected" : ""),
|
|
@@ -4818,35 +4845,49 @@ window.__ModuleLoader__.load({
|
|
|
4818
4845
|
className: "pbb-action pbb-buttonPrimary",
|
|
4819
4846
|
onClick: copyPairingInfo,
|
|
4820
4847
|
"data-testid": "pairingInfoCopy"
|
|
4821
|
-
}, translateWith(props.t, "panel.tokenAction.copy")))), (0, react.createElement)("p", { className: "pbb-qrHint" }, translateWith(props.t, "pair.qrHint", { kind: panel.target?.kind === "public" ? translateWith(props.t, "pair.kind.public") : translateWith(props.t, "pair.kind.lan") })))) : null))
|
|
4848
|
+
}, translateWith(props.t, "panel.tokenAction.copy")))), (0, react.createElement)("p", { className: "pbb-qrHint" }, translateWith(props.t, "pair.qrHint", { kind: panel.target?.kind === "public" ? translateWith(props.t, "pair.kind.public") : translateWith(props.t, "pair.kind.lan") })))) : null)));
|
|
4849
|
+
return (0, react.createElement)("div", { className: "pbb-section" }, (0, react.createElement)("header", { className: "pbb-pageHeader" }, (0, react.createElement)("div", null, (0, react.createElement)("h2", { className: "pbb-title" }, "DeepPilot"), (0, react.createElement)("p", { className: "pbb-intro" }, translateWith(props.t, "meta.intro"))), (0, react.createElement)("button", {
|
|
4822
4850
|
type: "button",
|
|
4823
|
-
|
|
4824
|
-
"
|
|
4825
|
-
|
|
4851
|
+
className: "pbb-refresh",
|
|
4852
|
+
disabled: !can("refresh"),
|
|
4853
|
+
onClick: () => props.refresh?.()
|
|
4854
|
+
}, settingsIcon("refresh", 14), translateWith(props.t, "meta.refresh"))), (0, react.createElement)("section", {
|
|
4855
|
+
className: "pbb-card pbb-connections",
|
|
4856
|
+
"aria-label": translateWith(props.t, "connection.title")
|
|
4857
|
+
}, (0, react.createElement)("div", { className: "pbb-cardBody" }, (0, react.createElement)("div", { className: "pbb-masterRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, switchTitle), (0, react.createElement)("div", { className: "pbb-serviceSummary" }, (0, react.createElement)("span", { className: "pbb-serviceState" + (service.kind === "ready" ? " pbb-ok" : service.kind === "attention" ? " pbb-bad" : "") }, settingsIcon(service.kind === "ready" ? "ready" : service.kind === "attention" ? "attention" : "info", 13)), (0, react.createElement)("span", null, serviceStatusText), (0, react.createElement)("span", {
|
|
4858
|
+
className: "pbb-metaDivider",
|
|
4859
|
+
"aria-hidden": true
|
|
4860
|
+
}), (0, react.createElement)("span", null, translateWith(props.t, "panel.activeConnections") + " " + (report === null ? "—" : String(report.activeConnections))))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
4861
|
+
checked: enabled,
|
|
4862
|
+
label: switchTitle,
|
|
4826
4863
|
disabled: !switchReady,
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
if (can("setEnabled")) props.setDeepPilotEnabled(!enabled);
|
|
4864
|
+
onChange: (next) => {
|
|
4865
|
+
if (can("setEnabled")) props.setDeepPilotEnabled(next);
|
|
4830
4866
|
}
|
|
4831
|
-
})), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
"aria-checked": localEnabled,
|
|
4835
|
-
"aria-label": translateWith(props.t, "local.title"),
|
|
4867
|
+
})), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row pbb-channelRow" }, settingsIcon("wifi"), (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "local.title")), (0, react.createElement)("div", { className: "pbb-channelState" }, (0, react.createElement)("span", { className: localMeta?.label === "online" ? "pbb-ok" : localMeta?.label === "error" ? "pbb-bad" : void 0 }, localStateText))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
4868
|
+
checked: localEnabled,
|
|
4869
|
+
label: translateWith(props.t, "local.title"),
|
|
4836
4870
|
disabled: !localSwitchReady,
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
if (can("setLocalEnabled")) props.setDeepPilotLocalEnabled(!localEnabled);
|
|
4871
|
+
onChange: (next) => {
|
|
4872
|
+
if (can("setLocalEnabled")) props.setDeepPilotLocalEnabled(next);
|
|
4840
4873
|
}
|
|
4841
|
-
})
|
|
4874
|
+
}), (0, react.createElement)("button", {
|
|
4842
4875
|
type: "button",
|
|
4843
|
-
className: "pbb-expand",
|
|
4876
|
+
className: "pbb-iconButton pbb-expand",
|
|
4877
|
+
"aria-label": translateWith(props.t, "local.options"),
|
|
4844
4878
|
"aria-expanded": localOptionsOpen,
|
|
4879
|
+
"aria-controls": localOptionsId,
|
|
4845
4880
|
onClick: () => setLocalOptionsOpen(!localOptionsOpen)
|
|
4846
|
-
},
|
|
4847
|
-
className: "pbb-
|
|
4881
|
+
}, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()))), report !== null && report.local.message && report.local.phase === "error" ? (0, react.createElement)("p", {
|
|
4882
|
+
className: "pbb-diag pbb-diagBad",
|
|
4883
|
+
role: "alert"
|
|
4884
|
+
}, translateWith(props.t, "local.errorDetails", { message: report.local.message })) : null, report !== null && report.local.tlsIdentityRegenerated === true ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "local.tlsRegenerated")) : null, fold(localOptionsOpen, (0, react.createElement)("div", {
|
|
4885
|
+
className: "pbb-channelBody",
|
|
4886
|
+
id: localOptionsId
|
|
4887
|
+
}, report !== null && report.local.phase === "online" ? (0, react.createElement)("p", { className: "pbb-diag pbb-endpoint" }, report.local.endpoints.join(" · ")) : null, (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("label", {
|
|
4888
|
+
className: "pbb-controlTitle",
|
|
4848
4889
|
htmlFor: "deeppilot-local-port"
|
|
4849
|
-
}, translateWith(props.t, "local.portTitle")), (0, react.createElement)("span", { className: "pbb-
|
|
4890
|
+
}, translateWith(props.t, "local.portTitle")), (0, react.createElement)("span", { className: "pbb-controlDescription" }, translateWith(props.t, "local.portDescription")), !localPortView.valid ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "local.portInvalid")) : localPortDraft.message ? (0, react.createElement)("p", { className: "pbb-diag" + (localPortDraft.failed ? " pbb-diagBad" : "") }, localPortDraft.message) : null), (0, react.createElement)("div", { className: "pbb-limitControl" }, (0, react.createElement)("input", {
|
|
4850
4891
|
id: "deeppilot-local-port",
|
|
4851
4892
|
className: "pbb-numberInput",
|
|
4852
4893
|
type: "number",
|
|
@@ -4872,30 +4913,38 @@ window.__ModuleLoader__.load({
|
|
|
4872
4913
|
className: "pbb-action",
|
|
4873
4914
|
disabled: !localPortReady || !localPortView.valid || localPortView.unchanged,
|
|
4874
4915
|
onClick: applyLocalPort
|
|
4875
|
-
}, translateWith(props.t, "remote.limitApply")))), report !== null && report.local.phase === "online" && report.local.tlsFingerprint ? (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4916
|
+
}, translateWith(props.t, "remote.limitApply")))), report !== null && report.local.phase === "online" && report.local.tlsFingerprint ? (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "local.tlsFingerprint")), (0, react.createElement)("code", { className: "pbb-token" }, report.local.tlsFingerprint))) : null))), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row pbb-channelRow" }, settingsIcon("globe"), (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "remote.title")), (0, react.createElement)("div", { className: "pbb-channelState" }, (0, react.createElement)("span", { className: remoteMeta?.label === "online" ? "pbb-ok" : remoteMeta?.label === "error" || remoteMeta?.label === "unavailable" ? "pbb-bad" : void 0 }, remoteStateText), (0, react.createElement)("span", {
|
|
4917
|
+
className: "pbb-metaDivider",
|
|
4918
|
+
"aria-hidden": true
|
|
4919
|
+
}), (0, react.createElement)("span", null, "Tailscale Funnel"))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
4920
|
+
checked: remoteEnabled,
|
|
4921
|
+
label: translateWith(props.t, "remote.title"),
|
|
4880
4922
|
disabled: !remoteSwitchReady,
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
if (can("setRemoteEnabled")) props.setDeepPilotRemoteEnabled(!remoteEnabled);
|
|
4923
|
+
onChange: (next) => {
|
|
4924
|
+
if (can("setRemoteEnabled")) props.setDeepPilotRemoteEnabled(next);
|
|
4884
4925
|
}
|
|
4885
|
-
})
|
|
4926
|
+
}), (0, react.createElement)("button", {
|
|
4927
|
+
type: "button",
|
|
4928
|
+
className: "pbb-iconButton pbb-expand",
|
|
4929
|
+
"aria-label": translateWith(props.t, "remote.options"),
|
|
4930
|
+
"aria-expanded": remoteOptionsOpen,
|
|
4931
|
+
"aria-controls": remoteOptionsId,
|
|
4932
|
+
onClick: () => setRemoteOptionsOpen(!remoteOptionsOpen)
|
|
4933
|
+
}, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()))), report !== null && report.remote.phase === "login_required" && typeof report.remote.authURL === "string" && report.remote.authURL.startsWith("https://") ? (0, react.createElement)("div", { className: "pbb-rowAction" }, (0, react.createElement)("a", {
|
|
4886
4934
|
className: "pbb-action pbb-buttonPrimary",
|
|
4887
4935
|
href: report.remote.authURL,
|
|
4888
4936
|
target: "_blank",
|
|
4889
4937
|
rel: "noreferrer"
|
|
4890
|
-
}, translateWith(props.t, "remote.openAuth"))) : null, report !== null && report.remote.message && (report.remote.phase === "error" || report.remote.phase === "unavailable") ? (0, react.createElement)("p", {
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4938
|
+
}, translateWith(props.t, "remote.openAuth"))) : null, report !== null && report.remote.message && (report.remote.phase === "error" || report.remote.phase === "unavailable") ? (0, react.createElement)("p", {
|
|
4939
|
+
className: "pbb-diag pbb-diagBad",
|
|
4940
|
+
role: "alert"
|
|
4941
|
+
}, translateWith(props.t, "remote.errorDetails", { message: report.remote.message })) : null, fold(remoteOptionsOpen, (0, react.createElement)("div", {
|
|
4942
|
+
className: "pbb-channelBody",
|
|
4943
|
+
id: remoteOptionsId
|
|
4944
|
+
}, report !== null && report.remote.phase === "online" ? (0, react.createElement)("p", { className: "pbb-diag pbb-endpoint" }, report.remote.publicURL) : null, (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("label", {
|
|
4945
|
+
className: "pbb-controlTitle",
|
|
4897
4946
|
htmlFor: "deeppilot-funnel-source-limit"
|
|
4898
|
-
}, translateWith(props.t, "remote.limitTitle")), (0, react.createElement)("span", { className: "pbb-
|
|
4947
|
+
}, translateWith(props.t, "remote.limitTitle")), (0, react.createElement)("span", { className: "pbb-controlDescription" }, translateWith(props.t, "remote.limitDescription")), !remoteLimitView.valid ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "remote.limitInvalid")) : remoteLimitDraft.message ? (0, react.createElement)("p", { className: "pbb-diag" + (remoteLimitDraft.failed ? " pbb-diagBad" : "") }, remoteLimitDraft.message) : null), (0, react.createElement)("div", { className: "pbb-limitControl" }, (0, react.createElement)("input", {
|
|
4899
4948
|
id: "deeppilot-funnel-source-limit",
|
|
4900
4949
|
className: "pbb-numberInput",
|
|
4901
4950
|
type: "number",
|
|
@@ -4921,62 +4970,125 @@ window.__ModuleLoader__.load({
|
|
|
4921
4970
|
className: "pbb-action",
|
|
4922
4971
|
disabled: !remoteConnectionLimitReady || !remoteLimitView.valid || remoteLimitView.unchanged,
|
|
4923
4972
|
onClick: applyRemoteLimit
|
|
4924
|
-
}, translateWith(props.t, "remote.limitApply")))), (0, react.createElement)("
|
|
4973
|
+
}, translateWith(props.t, "remote.limitApply")))), (0, react.createElement)("details", { className: "pbb-helpDisclosure" }, (0, react.createElement)("summary", null, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()), translateWith(props.t, "help.remoteTitle")), (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.recommended")), (0, react.createElement)("ol", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.step1")), (0, react.createElement)("li", null, translateWith(props.t, "help.step2")), (0, react.createElement)("li", null, translateWith(props.t, "help.step3")), (0, react.createElement)("li", null, translateWith(props.t, "help.step4"))), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.funnelHint"))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.httpsTitle")), (0, react.createElement)("ol", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.httpsStep1")), (0, react.createElement)("li", null, translateWith(props.t, "help.httpsStep2")), (0, react.createElement)("li", null, translateWith(props.t, "help.httpsStep3"))), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.httpsHint"))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.allowTitle")), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.allowBody")), (0, react.createElement)("code", { className: "pbb-helpCode" }, "\"nodeAttrs\": [\n {\n \"target\": [\"autogroup:member\"],\n \"attr\": [\"funnel\"],\n },\n],"), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.allowHint"))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.faqTitle")), (0, react.createElement)("ul", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.faq1")), (0, react.createElement)("li", null, translateWith(props.t, "help.faq2")), (0, react.createElement)("li", null, translateWith(props.t, "help.faq3")), (0, react.createElement)("li", null, translateWith(props.t, "help.faq4")))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.securityTitle")), (0, react.createElement)("ul", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.security1")), (0, react.createElement)("li", null, translateWith(props.t, "help.security2")), (0, react.createElement)("li", null, translateWith(props.t, "help.security3")), (0, react.createElement)("li", null, translateWith(props.t, "help.security4")), (0, react.createElement)("li", null, translateWith(props.t, "help.security5"))), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.docsPrefix"), (0, react.createElement)("a", {
|
|
4925
4974
|
className: "pbb-helpLink",
|
|
4926
4975
|
href: "https://tailscale.com/docs/features/tailscale-funnel",
|
|
4927
4976
|
target: "_blank",
|
|
4928
4977
|
rel: "noreferrer"
|
|
4929
|
-
}, translateWith(props.t, "help.funnelDocs"))))))))))
|
|
4930
|
-
className: "pbb-
|
|
4978
|
+
}, translateWith(props.t, "help.funnelDocs"))))))))))), (0, react.createElement)("section", {
|
|
4979
|
+
className: "pbb-devicesSection",
|
|
4980
|
+
"aria-label": translateWith(props.t, "devices.title")
|
|
4981
|
+
}, (0, react.createElement)("div", { className: "pbb-devicesHeader" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "devices.title")), (0, react.createElement)("span", { className: "pbb-deviceCount" }, translateWith(props.t, "devices.count", { count: visibleDevices$1.length })), (0, react.createElement)("div", { className: "pbb-addAction" }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4982
|
+
variant: "outline",
|
|
4983
|
+
size: "sm",
|
|
4984
|
+
icon: settingsIcon("plus", 16),
|
|
4985
|
+
disabled: panel.busy || report === null || !report.pairingReady || !can("beginPairing"),
|
|
4986
|
+
"aria-expanded": pairingOpen,
|
|
4987
|
+
"aria-controls": pairingId,
|
|
4988
|
+
onClick: () => {
|
|
4989
|
+
if (pairingOpen) {
|
|
4990
|
+
hidePairingQR();
|
|
4991
|
+
setPairingOpen(false);
|
|
4992
|
+
return;
|
|
4993
|
+
}
|
|
4994
|
+
setPairingOpen(true);
|
|
4995
|
+
if (pairingTarget !== null && report?.pairingReady) showPairingQR(pairingTarget);
|
|
4996
|
+
}
|
|
4997
|
+
}, translateWith(props.t, pairingOpen ? "pair.close" : "pair.add")))), pairingSection, (0, react.createElement)("div", { className: "pbb-card pbb-devicesCard" }, deviceMessage ? (0, react.createElement)("p", {
|
|
4998
|
+
className: "pbb-diag pbb-deviceMessage" + (deviceMessage.startsWith(translateWith(props.t, "devices.renameFailed")) || deviceMessage.startsWith(translateWith(props.t, "devices.revokeFailed")) ? " pbb-diagBad" : ""),
|
|
4931
4999
|
role: "status"
|
|
4932
|
-
}, deviceMessage) : null, deviceRows)), (0, react.createElement)("
|
|
5000
|
+
}, deviceMessage) : null, deviceRows)), (0, react.createElement)("section", {
|
|
5001
|
+
className: "pbb-card pbb-tools",
|
|
5002
|
+
"aria-label": translateWith(props.t, "tools.title")
|
|
5003
|
+
}, (0, react.createElement)("div", { className: "pbb-toolSection" }, (0, react.createElement)("button", {
|
|
4933
5004
|
type: "button",
|
|
4934
5005
|
className: "pbb-cardHead",
|
|
4935
5006
|
"aria-expanded": troubleshootingOpen,
|
|
5007
|
+
"aria-controls": troubleshootingId,
|
|
4936
5008
|
onClick: () => setTroubleshootingOpen(!troubleshootingOpen)
|
|
4937
|
-
}, (
|
|
5009
|
+
}, settingsIcon("activity", 17), (0, react.createElement)("span", { className: "pbb-cardTitle" }, translateWith(props.t, "troubleshooting.summary")), (0, react.createElement)("span", { className: "pbb-toolMeta" + (troubleGood ? " pbb-ok" : troubleBad && relayTestResult !== null ? " pbb-bad" : "") }, troubleConclusion), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())), fold(troubleshootingOpen, (0, react.createElement)("div", {
|
|
5010
|
+
className: "pbb-cardBody",
|
|
5011
|
+
id: troubleshootingId
|
|
5012
|
+
}, (0, react.createElement)("div", { className: "pbb-testGrid" }, (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "push.relayTitle")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "push.relayDefault"))), (0, react.createElement)("button", {
|
|
4938
5013
|
type: "button",
|
|
4939
5014
|
className: "pbb-action",
|
|
4940
5015
|
disabled: relayTestBusy,
|
|
4941
5016
|
onClick: runRelayTest
|
|
4942
|
-
}, relayTestBusy ? translateWith(props.t, "push.relayTesting") : translateWith(props.t, "push.testRelay"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-
|
|
5017
|
+
}, relayTestBusy ? translateWith(props.t, "push.relayTesting") : translateWith(props.t, "push.testRelay"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "push.testPush")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "push.pushDefault"))), (0, react.createElement)("button", {
|
|
4943
5018
|
type: "button",
|
|
4944
5019
|
className: "pbb-action",
|
|
4945
5020
|
disabled: pushTestBusy,
|
|
4946
5021
|
onClick: sendPushTest
|
|
4947
|
-
}, pushTestBusy ? translateWith(props.t, "push.pushSending") : translateWith(props.t, "push.testPush"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
"aria-checked": debugEnabled,
|
|
4951
|
-
"aria-label": translateWith(props.t, "troubleshooting.debugTitle"),
|
|
5022
|
+
}, pushTestBusy ? translateWith(props.t, "push.pushSending") : translateWith(props.t, "push.testPush"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "troubleshooting.debugTitle")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "troubleshooting.debugDescription"))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
5023
|
+
checked: debugEnabled,
|
|
5024
|
+
label: translateWith(props.t, "troubleshooting.debugTitle"),
|
|
4952
5025
|
disabled: !debugSwitchReady,
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
if (can("setDebug")) props.setDeepPilotDebug(!debugEnabled);
|
|
5026
|
+
onChange: (next) => {
|
|
5027
|
+
if (can("setDebug")) props.setDeepPilotDebug(next);
|
|
4956
5028
|
}
|
|
4957
5029
|
}))), relayTestError ? (0, react.createElement)("p", {
|
|
4958
5030
|
className: "pbb-diag pbb-diagBad",
|
|
4959
5031
|
role: "alert"
|
|
4960
|
-
}, relayTestError) : null, relayTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("span", { className: "pbb-label" }, relayTestResult.url || translateWith(props.t, "push.relayUrlEmpty")), (0, react.createElement)("code", { className: "pbb-token " + (relayTestResult.overall === "ok" ? "pbb-ok" : "pbb-bad") }, relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad"))), relayTestResult.steps.map((step, index) => resultRow(step.ok, (step.id === "health" ? translateWith(props.t, "push.relayStep.health") : translateWith(props.t, "push.relayStep.enroll")) + (step.latencyMs !== void 0 ? ` (${String(step.latencyMs)}ms)` : "") + "
|
|
5032
|
+
}, relayTestError) : null, relayTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("span", { className: "pbb-label" }, relayTestResult.url || translateWith(props.t, "push.relayUrlEmpty")), (0, react.createElement)("code", { className: "pbb-token " + (relayTestResult.overall === "ok" ? "pbb-ok" : "pbb-bad") }, relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad"))), relayTestResult.steps.map((step, index) => resultRow(step.ok, (step.id === "health" ? translateWith(props.t, "push.relayStep.health") : translateWith(props.t, "push.relayStep.enroll")) + (step.latencyMs !== void 0 ? ` (${String(step.latencyMs)}ms)` : "") + "(" + step.message + ")", String(index)))), pushTestError ? (0, react.createElement)("p", {
|
|
4961
5033
|
className: "pbb-diag pbb-diagBad",
|
|
4962
5034
|
role: "alert"
|
|
4963
|
-
}, pushTestError) : null, pushTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("code", { className: "pbb-token " + (pushTestResult.overall === "sent" ? "pbb-ok" : pushTestResult.overall === "failed" ? "pbb-bad" : "") }, pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : pushTestResult.overall === "failed" ? translateWith(props.t, "push.pushFailed") : pushTestResult.overall === "no-targets" ? translateWith(props.t, "push.pushNoTargets") : translateWith(props.t, "push.pushNotEnabled"))), pushTestResult.message ? (0, react.createElement)("p", { className: "pbb-diag" }, pushTestResult.message) : null, pushTestResult.results.map((r, index) => resultRow(r.outcome === "sent", r.name + "
|
|
5035
|
+
}, pushTestError) : null, pushTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("code", { className: "pbb-token " + (pushTestResult.overall === "sent" ? "pbb-ok" : pushTestResult.overall === "failed" ? "pbb-bad" : "") }, pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : pushTestResult.overall === "failed" ? translateWith(props.t, "push.pushFailed") : pushTestResult.overall === "no-targets" ? translateWith(props.t, "push.pushNoTargets") : translateWith(props.t, "push.pushNotEnabled"))), pushTestResult.message ? (0, react.createElement)("p", { className: "pbb-diag" }, translateWith(props.t, "push.resultDetail", { message: pushTestResult.message })) : null, pushTestResult.results.map((r, index) => resultRow(r.outcome === "sent", r.name + "(" + translateWith(props.t, r.environment === "production" ? "push.environment.production" : r.environment === "development" ? "push.environment.development" : "push.environment.other", { environment: r.environment }) + ") · " + translateWith(props.t, r.outcome === "sent" ? "push.outcome.sent" : r.outcome === "invalid-token" ? "push.outcome.invalid" : r.outcome === "failed" ? "push.outcome.failed" : "push.outcome.other", { outcome: r.outcome }) + (r.reason ? "(" + r.reason + ")" : "") + (r.tokenFingerprint ? " token:" + r.tokenFingerprint + "…" : ""), String(index)))), diagnosticsSection))), report === null ? null : (0, react.createElement)("div", { className: "pbb-toolSection" }, (0, react.createElement)("button", {
|
|
4964
5036
|
type: "button",
|
|
4965
5037
|
className: "pbb-cardHead",
|
|
4966
5038
|
"aria-expanded": systemOpen,
|
|
5039
|
+
"aria-controls": systemId,
|
|
4967
5040
|
onClick: () => setSystemOpen(!systemOpen)
|
|
4968
|
-
}, (
|
|
5041
|
+
}, settingsIcon("info", 17), (0, react.createElement)("span", { className: "pbb-cardTitle" }, translateWith(props.t, "system.summary")), (0, react.createElement)("span", { className: "pbb-toolMeta" + (report.updateAvailable === true ? " pbb-ok" : "") }, "v" + report.pluginVersion + (report.updateAvailable === true ? " · " + translateWith(props.t, "update.badge") : "")), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())), fold(systemOpen, (0, react.createElement)("div", {
|
|
5042
|
+
className: "pbb-cardBody",
|
|
5043
|
+
id: systemId
|
|
5044
|
+
}, (0, react.createElement)("div", { className: "pbb-sectionIntro" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "system.title"))), (0, react.createElement)("div", { className: "pbb-runtimeList" }, (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, "DeepPilot"), (0, react.createElement)("span", { className: "pbb-value" }, "v" + report.pluginVersion)), (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, translateWith(props.t, "advanced.tailscaleVersion")), (0, react.createElement)("span", { className: "pbb-value" }, report.remote.tailscaleVersion ?? translateWith(props.t, "advanced.tailscaleVersionUnknown"))), (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, translateWith(props.t, "panel.identity")), (0, react.createElement)("span", { className: "pbb-value" }, translateWith(props.t, report.pairingReady ? "panel.identityReady" : "panel.identityNotReady"))), advancedRows, report.updateAvailable === true ? (0, react.createElement)("a", {
|
|
4969
5045
|
className: "pbb-updateRow",
|
|
4970
5046
|
href: typeof report.releaseUrl === "string" && /^https:\/\//.test(report.releaseUrl) ? report.releaseUrl : "https://github.com/Mars-Sea/dsh-deeppilot/releases",
|
|
4971
5047
|
target: "_blank",
|
|
4972
5048
|
rel: "noreferrer"
|
|
4973
|
-
}, (0, react.createElement)("span", null, translateWith(props.t, "update.badge")), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())) : null)))), diag.length > 0 ? (0, react.createElement)("details", {
|
|
5049
|
+
}, (0, react.createElement)("span", null, translateWith(props.t, "update.badge")), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())) : null))))), diag.length > 0 ? (0, react.createElement)("details", {
|
|
4974
5050
|
className: "pbb-card pbb-disclosure pbb-diagnostics",
|
|
4975
5051
|
open: failed
|
|
4976
5052
|
}, (0, react.createElement)("summary", null, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()), (0, react.createElement)("span", { className: "pbb-disclosureTitle" }, translateWith(props.t, "diag.summary"))), (0, react.createElement)("div", { className: "pbb-disclosureBody" }, (0, react.createElement)("p", { className: "pbb-diag" + (failed ? " pbb-diagBad" : "") }, translateWith(props.t, "diag.prefix") + diag.join(" | ")))) : null);
|
|
4977
5053
|
}
|
|
4978
|
-
|
|
4979
|
-
|
|
5054
|
+
// src/client/nav-icon.ts
|
|
5055
|
+
/**
|
|
5056
|
+
* 设置页左侧导航里 DeepPilot 一行的图标。
|
|
5057
|
+
*
|
|
5058
|
+
* DSH 0.2.2 的设置壳为每个 `settings.section` 渲染
|
|
5059
|
+
* `renderSlot('settings.section.icon', { size, active }, { only: id, fallback })`:
|
|
5060
|
+
* 有同 id 的图标贡献就用它,否则画默认齿轮。壳负责按钮、文字和装饰性外框
|
|
5061
|
+
* (外框已 `aria-hidden`),图标只需按 `size` 画一个随文字颜色变化的线性 SVG。
|
|
5062
|
+
*
|
|
5063
|
+
* 不用 `icon.svg`:那是插件管理页的彩色品牌图(渐变填充、白底),放进导航行
|
|
5064
|
+
* 会和内置单色线性图标格格不入,也违反「图标统一用线性单色 SVG」的要求。
|
|
5065
|
+
* 这里画一部手机(DeepPilot 的职责是把手机接到这台电脑的 DSH),描边沿用
|
|
5066
|
+
* 设置页其他图标的 16×16 视图框和 1.5 线宽。
|
|
5067
|
+
*/
|
|
5068
|
+
/** 导航行默认边长;壳当前固定传 16。 */
|
|
5069
|
+
const DEFAULT_NAV_ICON_SIZE = 16;
|
|
5070
|
+
const DeepPilotNavIcon = ({ size }) => {
|
|
5071
|
+
const edge = typeof size === "number" && size > 0 ? size : DEFAULT_NAV_ICON_SIZE;
|
|
5072
|
+
return (0, react.createElement)("svg", {
|
|
5073
|
+
viewBox: "0 0 16 16",
|
|
5074
|
+
width: edge,
|
|
5075
|
+
height: edge,
|
|
5076
|
+
fill: "none",
|
|
5077
|
+
stroke: "currentColor",
|
|
5078
|
+
strokeWidth: 1.5,
|
|
5079
|
+
strokeLinecap: "round",
|
|
5080
|
+
strokeLinejoin: "round",
|
|
5081
|
+
"aria-hidden": true,
|
|
5082
|
+
focusable: "false"
|
|
5083
|
+
}, (0, react.createElement)("rect", {
|
|
5084
|
+
x: 4.25,
|
|
5085
|
+
y: 1.75,
|
|
5086
|
+
width: 7.5,
|
|
5087
|
+
height: 12.5,
|
|
5088
|
+
rx: 1.75
|
|
5089
|
+
}), (0, react.createElement)("path", { d: "M7 11.75h2" }));
|
|
5090
|
+
};
|
|
5091
|
+
// src/client/config-form.ts
|
|
4980
5092
|
/**
|
|
4981
5093
|
* Deep-unwrap live-update references in a snapshot section.
|
|
4982
5094
|
*
|
|
@@ -5029,8 +5141,7 @@ window.__ModuleLoader__.load({
|
|
|
5029
5141
|
function bindConfigForm(ctx) {
|
|
5030
5142
|
return adaptConfigForm(ctx.get("configForms"), "deeppilot");
|
|
5031
5143
|
}
|
|
5032
|
-
|
|
5033
|
-
//#region src/client/index.ts
|
|
5144
|
+
// src/client/index.ts
|
|
5034
5145
|
/** Polls the report remote and owns the page state transitions. */
|
|
5035
5146
|
var ReportController = class {
|
|
5036
5147
|
fetchReport;
|
|
@@ -5482,8 +5593,11 @@ window.__ModuleLoader__.load({
|
|
|
5482
5593
|
t: (key, vars) => t(ctx, key, vars)
|
|
5483
5594
|
})
|
|
5484
5595
|
}, DeepPilotSettingsPage));
|
|
5596
|
+
anyCtx.slots?.inject("settings.section.icon", () => anyCtx.slots.register({
|
|
5597
|
+
name: "settings.section.icon",
|
|
5598
|
+
id: "deeppilot"
|
|
5599
|
+
}, DeepPilotNavIcon));
|
|
5485
5600
|
}
|
|
5486
|
-
//#endregion
|
|
5487
5601
|
exports.DeepPilotSettingsPage = DeepPilotSettingsPage;
|
|
5488
5602
|
exports.apply = apply;
|
|
5489
5603
|
exports.inject = inject;
|