@hyzyn/dsh-tty 0.26.0 → 0.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +37 -1
- package/README.md +31 -1
- package/client.js +26 -11
- package/lib/index.d.ts +4 -0
- package/lib/index.js +44 -5
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
package/client.js
CHANGED
|
@@ -1000,11 +1000,12 @@ void main() {
|
|
|
1000
1000
|
|
|
1001
1001
|
/* ---- \u5DE5\u5177\u6309\u94AE ---- */
|
|
1002
1002
|
/*
|
|
1003
|
-
* \u5BF9\u9F50\u5BBF\u4E3B Button size="sm"\uFF08ui-primitives/Button.module.css \u7684
|
|
1004
|
-
*
|
|
1005
|
-
* border-l3\uFF08\u5BBF\u4E3B .outline \u7528\u7684\u6863\u4F4D\uFF1B\u539F\u5148\u7684 --tt-border \u662F l1\uFF0C
|
|
1006
|
-
* \
|
|
1007
|
-
* \
|
|
1003
|
+
* \u5BF9\u9F50\u5BBF\u4E3B Button variant="outline" size="sm"\uFF08ui-primitives/Button.module.css \u7684
|
|
1004
|
+
* .button + .sm + .outline\uFF09\uFF1AH28 \u2192 R8(--dsw-radius-sm)\u300112px \u4E0E 18px \u6210\u5BF9\u7684\u5B57\u53F7/\u884C\u9AD8\u3001
|
|
1005
|
+
* 0.5px \u4E2D\u6027\u53D1\u4E1D\u63CF\u8FB9\u53D6 border-l3\uFF08\u5BBF\u4E3B .outline \u7528\u7684\u6863\u4F4D\uFF1B\u539F\u5148\u7684 --tt-border \u662F l1\uFF0C
|
|
1006
|
+
* \u6BD4\u5B98\u65B9\u6DE1\u4E00\u6863\uFF09\u3002\u5E95\u8272\u4E0E\u6587\u5B57\u8272\u4E5F\u6309\u5B98\u65B9 outline \u53D6\uFF1Atransparent \u5E95 + label-primary \u5B57\u2014\u2014
|
|
1007
|
+
* \u5B9E\u5FC3\u5E95\uFF08\u539F\u5148\u7684 --tt-input\uFF09\u4F1A\u8BA9\u6309\u94AE\u5728\u884C\u5E95\u4E0A\u6D6E\u6210\u4E0D\u900F\u660E\u767D\u5757\uFF0C\u4E0E\u5BBF\u4E3B\u5E76\u6392\u89C2\u611F\u5BF9\u4E0D\u4E0A
|
|
1008
|
+
* \uFF08docker \u7684 .dk_btn \u540C\u4E00\u8F6E\u6539\u7684\u540C\u4E00\u5904\uFF0C\u89C1\u90A3\u6761\u6CE8\u91CA\uFF09\uFF1B\u6587\u5B57\u7528 label-2 \u4F1A\u6BD4\u5BBF\u4E3B\u6DE1\u4E00\u6863\u3002
|
|
1008
1009
|
*/
|
|
1009
1010
|
.tt_toolBtn {
|
|
1010
1011
|
box-sizing: border-box;
|
|
@@ -1017,8 +1018,8 @@ void main() {
|
|
|
1017
1018
|
padding: 0 10px;
|
|
1018
1019
|
border: 0.5px solid var(--dsw-alias-border-l3, var(--tt-border-strong));
|
|
1019
1020
|
border-radius: var(--dsw-radius-sm);
|
|
1020
|
-
background:
|
|
1021
|
-
color: var(--tt-label
|
|
1021
|
+
background: transparent;
|
|
1022
|
+
color: var(--tt-label);
|
|
1022
1023
|
font-size: 12px;
|
|
1023
1024
|
font-family: inherit;
|
|
1024
1025
|
line-height: 18px;
|
|
@@ -1028,11 +1029,10 @@ void main() {
|
|
|
1028
1029
|
}
|
|
1029
1030
|
.tt_toolBtn:hover:not(:disabled) {
|
|
1030
1031
|
/*
|
|
1031
|
-
* \u53EA\u6362\u5E95\u3001\u4E0D\u52A8\u63CF\u8FB9\uFF1A\u5B98\u65B9 .outline:hover \
|
|
1032
|
-
* \
|
|
1032
|
+
* \u53EA\u6362\u5E95\u3001\u4E0D\u52A8\u63CF\u8FB9\u4E0E\u6587\u5B57\uFF1A\u5B98\u65B9 .outline:hover \u53EA\u8986\u76D6 background\u2014\u2014\u6587\u5B57\u8272\u82E5\u5728\u8FD9\u91CC
|
|
1033
|
+
* \u62AC\u5230 label\uFF0C\u4E0B\u9762 .tt_btnDanger \u7684\u7EA2\u5B57\u4F1A\u5728\u60AC\u505C\u65F6\u88AB\u8FD9\u6761\u66F4\u9AD8\u6743\u91CD\u7684\u89C4\u5219\u76D6\u56DE\u7070\u8272\u3002
|
|
1033
1034
|
*/
|
|
1034
1035
|
background: var(--dsw-alias-interactive-bg-hover, var(--tt-hover));
|
|
1035
|
-
color: var(--tt-label);
|
|
1036
1036
|
}
|
|
1037
1037
|
.tt_toolBtn:active:not(:disabled) {
|
|
1038
1038
|
/* \u5B98\u65B9 .ghost:active \u7684\u6309\u4E0B\u5E95\uFF1A\u6BD4 hover \u518D\u6DF1\u4E00\u6863 */
|
|
@@ -1047,6 +1047,21 @@ void main() {
|
|
|
1047
1047
|
opacity: .4;
|
|
1048
1048
|
cursor: not-allowed;
|
|
1049
1049
|
}
|
|
1050
|
+
/*
|
|
1051
|
+
* \u5371\u9669\u53D8\u4F53\uFF08\u5220\u9664\u8FD9\u7C7B\u4E0D\u53EF\u9006\u52A8\u4F5C\uFF09\uFF1D\u5BBF\u4E3B plugin-manager\u300C\u5378\u8F7D\u300D\u7684 .danger \u914D\u65B9
|
|
1052
|
+
* \uFF08conventions \xA7 \u5BA2\u6237\u7AEF\u534A\u4F53 \u68C0\u67E5\u5341\u4E00\uFF09\uFF1A\u63CF\u8FB9\u6309\u94AE\u9AA8\u67B6\u4E0D\u53D8\uFF0C\u7EA2\u5B57 + 30% \u7EA2\u63CF\u8FB9 +
|
|
1053
|
+
* hover \u5E95\u6362 8% \u7EA2\u3002--tt-danger \u5728\u672C\u5305\u5B9A\u4E49\u4E3A state-error-primary \u7684\u522B\u540D\uFF0C
|
|
1054
|
+
* \u6309\u68C0\u67E5\u5341\u4E00\u7684\u522B\u540D\u5C55\u5F00\u53E3\u5F84\u4E0E\u5B98\u65B9 token \u7B49\u6548\u3002
|
|
1055
|
+
* hover \u5FC5\u987B\u5E26 :not(:disabled) \u5E76\u5199\u5728\u4E0A\u9762\u7684 .tt_toolBtn:hover \u4E4B\u540E\u2014\u2014\u540C\u6743\u91CD
|
|
1056
|
+
* (0,3,0) \u4E0B\u6E90\u7801\u987A\u5E8F\u51B3\u5B9A\u80DC\u8D1F\uFF0C\u4F4D\u7F6E\u9519\u4E86\u7EA2\u8272\u60AC\u505C\u5E95\u4F1A\u88AB\u7070\u8272\u76D6\u6389\u3002
|
|
1057
|
+
*/
|
|
1058
|
+
.tt_btnDanger {
|
|
1059
|
+
color: var(--tt-danger);
|
|
1060
|
+
border-color: color-mix(in srgb, var(--tt-danger) 30%, transparent);
|
|
1061
|
+
}
|
|
1062
|
+
.tt_btnDanger:hover:not(:disabled) {
|
|
1063
|
+
background: color-mix(in srgb, var(--tt-danger) 8%, transparent);
|
|
1064
|
+
}
|
|
1050
1065
|
/*
|
|
1051
1066
|
* \u56FE\u6807\u6309\u94AE\uFF1A\u6B63\u65B9\u5F62\uFF0C\u8FB9\u957F\u5C31\u662F\u672C\u5305\u7D27\u51D1\u6863 --tt-h-sm\u3002
|
|
1052
1067
|
* \u539F\u5148 width \u53D6\u7684\u662F --tt-h-md(28) \u800C\u9AD8\u5EA6\u6765\u81EA .tt_toolBtn(28)\u2014\u2014\u4F46\u5B83\u5728 .tt_toolGroup \u91CC
|
|
@@ -3469,7 +3484,7 @@ void main() {
|
|
|
3469
3484
|
}
|
|
3470
3485
|
}
|
|
3471
3486
|
`;function eo(e){let t=typeof e=="string"?e.trim():"";if(t==="")return;let r=t,s="",o=r.lastIndexOf("@");o>0&&(s=r.slice(0,o).trim(),r=r.slice(o+1).trim());let i=r,n=22,a=/^\[([^\]]+)\](?::(\d+))?$/.exec(r)??/^([^:]+):(\d+)$/.exec(r);if(a!==null){i=a[1];let l=Number(a[2]);Number.isInteger(l)&&l>=1&&l<=65535&&(n=l)}if(i==="")return;let d={host:i,port:n};return s!==""&&(d.username=s),d}function to(e){if(e===null||typeof e!="object")return"";let t=e,r=typeof t.host=="string"?t.host.trim():"";if(r==="")return"";let s=Number.isInteger(t.port)&&Number(t.port)>=1&&Number(t.port)<=65535?Number(t.port):22,o=typeof t.username=="string"&&t.username.trim()!==""?t.username.trim()+"@":"",i=r.includes(":")&&!r.startsWith("[")?`[${r}]`:r;return`${o}${i}${s===22?"":":"+String(s)}`}var ro="\0global";function Wr(e,t){return e===null?ro:typeof e=="string"&&e!==""?e:typeof t=="string"&&t!==""?t:ro}function so(e,t){return e===ro?!0:typeof t=="string"&&t!==""&&e===t}var Cp="/api/dsh-tty/ws";function oc(e,t){let r=new URL(t??e,e);return(r.protocol==="https:"?"wss:":"ws:")+"//"+r.host+Cp}function io(e){return String(e??"").trim().toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_+|_+$/g,"")}function ac(e,t,r,s){let o=io(r),i=io(e);if(o===""||i==="")return"";let n=io(t),a=["DSH_TTY",o,i];return n!==""&&n!=="22"&&a.push(n),a.push(s),a.join("_")}function gi(e){let t=Number(e);return Number.isInteger(t)&&t>=1&&t<=65535?t:0}function lc(e,t,r){return`${e}-${t==="remote"?"R":"L"}${String(r)}`}function cc(e,t=[],r=s=>s){let s=e??{},o=String(s.bookName??"")||String(t[0]??"")||"";if(o==="")return{ok:!1,error:r("error.tunnelNoBook")};if(s.direction==="remote"){let d=gi(s.remotePort),l=gi(s.localTargetPort);return d<1||l<1?{ok:!1,error:r("error.tunnelRemotePortRequired")}:{ok:!0,tunnel:{name:lc(o,"remote",d),bookName:o,direction:"remote",remotePort:d,localTargetHost:"",localTargetPort:l,enabled:!0}}}let i=gi(s.localPort),n=String(s.remoteHost??"").trim(),a=gi(s.remotePort);return i<1||n===""||a<1?{ok:!1,error:r("error.tunnelLocalRequired")}:{ok:!0,tunnel:{name:lc(o,"local",i),bookName:o,direction:"local",localPort:i,remoteHost:n,remotePort:a,enabled:!0}}}function hc(e,t){return(Array.isArray(e)?e:[]).find(r=>String(r?.name??"")===String(t))}function xp(e,t,r){return(Array.isArray(e)?e:[]).find(s=>String(s?.name??"")!==String(t)&&String(s?.name??"")===String(r))}function dc(e,t,r,s){let o=Array.isArray(e)?e:[],i=o.find(d=>String(d?.name??"")===String(t));if(i===void 0)return{ok:!1,reason:"missing",error:s("error.tunnelMissing",{name:String(t)})};if(xp(o,t,r.name)!==void 0)return{ok:!1,reason:"clash",error:s("error.tunnelClash",{name:String(r.name)})};let a={...r,enabled:i.enabled!==!1};return{ok:!0,tunnels:o.map(d=>String(d?.name??"")===String(t)?a:d)}}function kp(e){let t=e?.byId;if(!(t===null||typeof t!="object"))for(let r of Object.keys(t)){let s=t[r]?.retainedBy?.mainView??0;if(typeof s=="number"&&s>0)return r}}function Ep(e){let t=e?.current;return typeof t=="string"&&t!==""?t:kp(e)}function uc(e){let t=Ep(e);if(t===void 0)return;let r=e?.byId?.[t]?.cwd;return typeof r=="string"&&r!==""?r:void 0}function Lp(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e>0&&t>0}function fc(e,t){if(e==null)return;let r=Math.floor(Number(e.cols)),s=Math.floor(Number(e.rows));if(!(!Number.isFinite(r)||!Number.isFinite(s))&&!(r<20||s<3)&&!(t==null||!Lp(Number(t.width),Number(t.height))))return{cols:Math.min(500,r),rows:Math.min(200,s)}}function pc(e){return e!==null&&typeof e=="object"&&e.exited!==!0}function _c(e){if(!Array.isArray(e))return 0;let t=0;for(let r of e)pc(r)&&(t+=1);return t}function vi(e){let t=new Set;if(!Array.isArray(e))return t;for(let r of e)pc(r)&&typeof r.sid=="string"&&r.sid!==""&&t.add(r.sid);return t}function mc(e){let t=Number(e?.received),r=Number(e?.attempt),s=Number.isInteger(e?.maxAttempts)?e.maxAttempts:3,o=e?.total===null||e?.total===void 0?null:Number(e.total);return e?.canceled===!0?{resume:!1,reason:"canceled"}:!Number.isFinite(t)||t<=0?{resume:!1,reason:"noProgress"}:!Number.isInteger(r)||r<1?{resume:!1,reason:"badAttempt"}:r>s?{resume:!1,reason:"attemptsExhausted"}:o!==null&&Number.isFinite(o)&&o>0&&t>=o?{resume:!1,reason:"complete"}:{resume:!0,offset:t}}function Tp(e){return typeof e!="string"||e===""||e==="."||e===".."?!1:e.startsWith(".")}function bi(e,t){let s=(Array.isArray(e)?e:[]).filter(o=>o!==null&&typeof o=="object"&&typeof o.name=="string"&&o.name!=="");return t===!0?s:s.filter(o=>!Tp(o.name))}function gc(e,t){return e!=="remote"?{accept:!1,reason:"wrongPane"}:(Array.isArray(t?.types)?t.types:[]).includes("Files")?Number(t?.files?.length??0)>0?{accept:!0}:{accept:!1,reason:"empty"}:{accept:!1,reason:"notFiles"}}function vc(e){let t=new Set;for(let r of Array.isArray(e)?e:[]){let s=typeof r?.relPath=="string"?r.relPath:"",o=s.lastIndexOf("/");o<=0||t.add(s.slice(0,o))}return[...t].sort((r,s)=>r.split("/").length-s.split("/").length||r.localeCompare(s))}function bc(e,t){return e==null?{text:"",state:""}:e.exited===!0?{text:e.statusText??t("status.exited"),state:e.statusState??""}:e.live===!0?{text:e.statusText??t("status.connected"),state:e.statusState??"connected"}:e.errored===!0?{text:e.statusText??t("status.errored"),state:e.statusState??"error"}:{text:e.statusText??t("status.connectingEllipsis"),state:e.statusState??""}}function wc(e,t){return typeof e!="string"||e===""?!0:e===t}function yc(e,t){return e===null?!1:e!==t}function Ze(e){if(!Number.isFinite(e)||e<=0)return"";if(e<1024)return String(e)+" B";let t=["KB","MB","GB","TB"],r=e,s=-1;do r/=1024,s+=1;while(r>=1024&&s<t.length-1);return(r>=100?r.toFixed(0):r.toFixed(1))+" "+t[s]}function gs(e){if(!Number.isFinite(e)||e<=0)return"";if(e<1024)return"<1 KB/s";let t=["KB","MB","GB","TB"],r=e,s=-1;do r/=1024,s+=1;while(r>=1024&&s<t.length-1);return(r>=100?r.toFixed(0):r.toFixed(1))+" "+t[s]+"/s"}function Cc(e){return Number.isFinite(e)?e>=90?"danger":e>=70?"warn":"":""}function Sc(e,t){return!Number.isFinite(e)||e<0?t("list.none"):e<1024?Math.round(e)+" B/s":gs(e)||t("list.none")}function Rp(e,t){if(!Number.isFinite(e)||e<0)return t("list.none");let r=Math.floor(e),s=Math.floor(r/604800),o=Math.floor(r%604800/86400),i=Math.floor(r%86400/3600),n=Math.floor(r%3600/60),a=[];return s>0&&a.push(s+"w"),(s>0||o>0)&&a.push(o+"d"),(s>0||o>0||i>0)&&a.push(i+"h"),(s>0||o>0||i>0||n>0)&&a.push(n+"m"),a.length>0?a.join(""):r+"s"}function Mp(e,t,r){return!Number.isFinite(e)||!Number.isFinite(t)||t<=0?r("list.none"):(Ze(e)||"0 B")+"/"+(Ze(t)||"0 B")}function xc(e,t){let r=e[t];return Number.isFinite(r)?t==="tempC"?r>-100&&r<200?r:null:t==="cores"?r>=1&&r<=4096?r:null:t==="cpuPct"||t==="memPct"||t==="diskPct"?r>=0&&r<=100?r:null:t==="uptimeSec"?r>=0&&r<=100*365*24*3600?r:null:t==="tcpConns"?r>=0&&r<=1e7?r:null:t==="rxRate"||t==="txRate"?r>=0&&r<=2**40?r:null:r>=0&&r<=2**50?r:null:null}var Ap=["cpuPct","cores","memUsed","memTotal","memPct","diskUsed","diskTotal","diskPct","uptimeSec","tcpConns","rxRate","txRate","tempC"];function kc(e){return e===null||typeof e!="object"||Array.isArray(e)?!1:Ap.some(t=>xc(e,t)!==null)}var Dp=8e3;function Ec(e,t=Date.now()){return t-(e||0)<=Dp}var Lc=23;function no(e){return[{key:"cpuPct",label:"CPU",kind:"pct",slot:4},{key:"memPct",label:e("meta.mem"),kind:"pct",slot:4},{key:"diskPct",label:e("meta.disk"),kind:"pct",slot:4},{key:"cores",label:e("meta.cores"),kind:"count",slot:4},{key:"mem",label:e("meta.mem"),kind:"pair",slot:17,used:"memUsed",total:"memTotal"},{key:"uptimeSec",label:e("meta.uptime"),kind:"uptime",slot:13},{key:"tcpConns",label:"TCP",kind:"count",slot:6},{key:"disk",label:e("meta.disk"),kind:"pair",slot:17,used:"diskUsed",total:"diskTotal"},{key:"tempC",label:e("meta.temp"),kind:"temp",slot:8},{key:"net",label:e("meta.net"),kind:"net",slot:Lc}]}function Tc(e,t){let r=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{},s=i=>xc(r,i),o=(i,n,a,d=i.slot)=>({key:i.key,label:i.label,kind:i.kind,slot:d,pct:a??null,value:n,title:i.label+": "+n});return no(t).map(i=>{if(i.kind==="pct"){let a=s(i.key);return o(i,a===null?t("list.none"):Math.round(a)+"%",a)}if(i.kind==="pair")return o(i,Mp(s(i.used),s(i.total),t),null);if(i.kind==="uptime")return o(i,Rp(s(i.key),t),null);if(i.kind==="temp"){let a=s(i.key);return o(i,a===null?t("list.none"):a.toFixed(1)+"\xB0C",null)}if(i.kind==="net"){let a=s("rxRate"),d=s("txRate");return a===null&&d===null?o(i,t("list.none"),null,0):o(i,"\u2193"+Sc(a,t)+" \u2191"+Sc(d,t),null,Lc)}let n=s(i.key);return o(i,n===null?t("list.none"):String(n),null)})}var oo="tty",Ri={"error.credServiceMissing":"\u5BBF\u4E3B\u672A\u63D0\u4F9B\u51ED\u636E\u670D\u52A1\uFF08remote.credentials\uFF09","error.credServiceIncomplete":"\u51ED\u636E\u670D\u52A1\u4E0D\u5B8C\u6574","error.credStoreUnavailable":"\u5BBF\u4E3B\u672A\u63D0\u4F9B\u51ED\u636E\u670D\u52A1\uFF08remote.credentials\uFF09\uFF0C\u65E0\u6CD5\u5B58\u5165","error.credStoreFailed":"\u5B58\u5165\u51ED\u636E\u5B58\u50A8\u5931\u8D25\uFF1A{error}","error.credClearUnavailable":"\u5BBF\u4E3B\u672A\u63D0\u4F9B\u51ED\u636E\u670D\u52A1\uFF08remote.credentials\uFF09\uFF0C\u65E0\u6CD5\u6E05\u9664","error.credClearFailed":"\u6E05\u9664\u5931\u8D25\uFF1A{error}","error.credRefNeedsHost":"\u5148\u586B\u300C\u4E3B\u673A\u300D\u548C\u300C\u7528\u6237\u540D\u300D\u518D\u5B58\u5165\u2014\u2014\u5F15\u7528\u540D\u7531\u8FD9\u4E24\u8005\u6D3E\u751F","btn.reopen":"\u91CD\u65B0\u6253\u5F00","btn.reopenTitle":"\u4EE5\u539F\u8FDE\u63A5\u4FE1\u606F\u91CD\u5F00\u4F1A\u8BDD","btn.sftpTitle":"\u6253\u5F00\u8BE5\u8FDE\u63A5\u7684\u6587\u4EF6\u6D4F\u89C8\uFF08SFTP\uFF09","btn.tunnels":"\u96A7\u9053 {count}","btn.tunnelsTitle":"\u67E5\u770B\u8BE5\u8FDE\u63A5\u7684\u7AEF\u53E3\u8F6C\u53D1\u96A7\u9053","btn.more":"\u66F4\u591A","btn.moreTitle":"\u66F4\u591A\u64CD\u4F5C\uFF08\u7AEF\u53E3\u8F6C\u53D1\u2026\uFF09","btn.reopenSession":"\u91CD\u65B0\u6253\u5F00\u4F1A\u8BDD","status.exited":"\u4F1A\u8BDD\u5DF2\u9000\u51FA","status.ended":"\u4F1A\u8BDD\u5DF2\u7ED3\u675F","btn.clickReopen":"\u70B9\u51FB\u91CD\u65B0\u6253\u5F00","btn.clickRerun":"\u70B9\u51FB\u91CD\u65B0\u6267\u884C","msg.passwordNotStored":"\u51FA\u4E8E\u5B89\u5168\u8003\u8651\uFF0C\u660E\u6587\u5BC6\u7801/\u53E3\u4EE4\u4E0D\u968F\u6D4F\u89C8\u5668\u5B58\u50A8\u4FDD\u7559\uFF0C\u672C\u6B21\u8FDE\u63A5\u9700\u8981\u91CD\u65B0\u8F93\u5165\uFF1A\u91CD\u5F00\u6807\u7B7E\u65F6\u518D\u586B\u4E00\u6B21\uFF0C\u6216\u5728\u8BBE\u7F6E\u5361\u7247\u628A\u51ED\u636E\u6362\u6210 env: \u5F15\u7528\uFF08\u503C\u5B58\u5BBF\u4E3B\u51ED\u636E\u5B58\u50A8\uFF09\u3002","error.terminalNeedsCommand":"ttyTerminal \u9700\u8981 command","error.terminalCommandSingleLine":"command \u5FC5\u987B\u662F\u5355\u884C","error.terminalNeedsHost":"ttyTerminal.mount \u9700\u8981 HTMLElement \u4F5C\u4E3A\u6302\u8F7D\u70B9","error.panelNotReady":"ttyPanel.mountPane\uFF1A\u7EC8\u7AEF\u9762\u677F\u672A\u5C31\u7EEA","panel.dragHeight":"\u62D6\u52A8\u8C03\u6574\u9AD8\u5EA6","panel.dragWidth":"\u62D6\u52A8\u8C03\u6574\u5BBD\u5EA6","btn.closePane":"\u5173\u95ED\u4FA7\u680F","btn.expandPane":"\u5C55\u5F00\u4FA7\u680F","btn.collapsePane":"\u6536\u8D77\u4FA7\u680F","panel.tabLabel":"\u7EC8\u7AEF {n}","btn.close":"\u5173\u95ED","btn.closeTabAria":"\u5173\u95ED\u6807\u7B7E\uFF1A{label}","btn.newTab":"\u65B0\u5EFA\uFF08\u672C\u5730 / SSH\uFF09","btn.tabList":"\u6807\u7B7E\u5217\u8868","btn.tabListTitle":"\u6807\u7B7E\u5217\u8868\uFF08{n} \u4E2A\uFF09","list.tabsAllVisible":"\u6CA1\u6709\u85CF\u5728\u89C6\u91CE\u5916\u7684\u6807\u7B7E","meta.tunnelRemote":"\u8FDC\u7A0B:{host}:{port} \u2192 \u672C\u673A:{local}","meta.tunnelLocal":"\u672C\u673A:{local} \u2192 {host}:{port}","status.tmuxPersistedTitle":"\u5DF2\u7531 tmux \u6258\u7BA1 \u2014 \u65AD\u7EBF / \u5BBF\u4E3B\u91CD\u542F\u540E\u6309\u540D\u63A5\u56DE\u73B0\u573A","status.notPersisted":"\u672A\u6301\u4E45\u5316","status.tmuxUnavailableTitle":"\u8BF7\u6C42\u4E86\u6301\u4E45\u4F1A\u8BDD\uFF0C\u4F46 tmux \u4E0D\u53EF\u7528 \u2014 \u5F53\u524D\u4E3A\u666E\u901A\u4F1A\u8BDD","status.connected":"\u5DF2\u8FDE\u63A5","status.connecting":"\u8FDE\u63A5\u4E2D","status.errored":"\u8FDE\u63A5\u51FA\u9519","panel.tunnels":"\u7AEF\u53E3\u8F6C\u53D1","hint.tunnelsSettings":"\u5728 \u8BBE\u7F6E \u2192 \u63D2\u4EF6 \u2192 \u7EC8\u7AEF\u9762\u677F \u91CC\u914D\u7F6E","panel.tunnelsFor":"\u7AEF\u53E3\u8F6C\u53D1 \u2014 {name}","list.loading":"\u52A0\u8F7D\u4E2D\u2026","hint.tunnelsCard":"\u589E\u5220/\u542F\u505C\u5728 \u63D2\u4EF6\u914D\u7F6E \u2192 \u7EC8\u7AEF\u9762\u677F \u7684\u7AEF\u53E3\u8F6C\u53D1\u533A\u5757\u7EF4\u62A4","list.noActiveTunnels":"\u8BE5\u8FDE\u63A5\u6682\u65E0\u542F\u7528\u7684\u96A7\u9053","status.fatalSuffix":"\uFF08\u4E0D\u91CD\u8BD5\uFF0C\u9700\u4FEE\u914D\u7F6E\uFF09","msg.maxSessions":"\u4F1A\u8BDD\u6570\u5DF2\u8FBE\u4E0A\u9650\uFF08\u5171 {live} \u4E2A / \u4E0A\u9650 {max}\uFF1A\u672C\u7A97\u53E3 {own} \u4E2A{others}\uFF09\u2014\u2014\u5173\u95ED\u4E0D\u7528\u7684\u7A97\u53E3/\u6807\u7B7E\uFF0C\u6216\u5728\u8BBE\u7F6E\u5361\u7247\u8C03\u5927\u300C\u5E76\u53D1\u4F1A\u8BDD\u4E0A\u9650\u300D","msg.maxSessionsOthers":" + \u5176\u4ED6\u7A97\u53E3 {count} \u4E2A","error.probeHttp":"\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25\uFF08HTTP {status}\uFF09","msg.probing":"\u8FDE\u63A5\u6D4B\u8BD5\u4E2D\u2026","meta.reachable":"\u901A","meta.unreachable":"\u4E0D\u901A","meta.probeBanner":"banner \u6B63\u5E38","meta.hostKeyMatched":"\u4E3B\u673A\u5BC6\u94A5\u5339\u914D","meta.hostKeyRecorded":"\u4E3B\u673A\u5BC6\u94A5\u5DF2\u8BB0\u5F55\uFF08TOFU\uFF09","meta.hostKeyMismatch":"\u4E3B\u673A\u5BC6\u94A5\u4E0D\u5339\u914D\uFF01","meta.authOkMs":"\u8BA4\u8BC1\u901A\u8FC7\uFF08{ms}ms\uFF09","meta.authOk":"\u8BA4\u8BC1\u901A\u8FC7","meta.probeOk":"\u2705 \u8FDE\u63A5\u6210\u529F\uFF1A{detail}","error.unknown":"\u672A\u77E5\u9519\u8BEF","btn.maxSessionsTitle":"\u4F1A\u8BDD\u6570\u5DF2\u8FBE\u4E0A\u9650\u2014\u2014\u70B9\u51FB\u67E5\u770B\u600E\u4E48\u529E","option.localTerminal":"\u672C\u5730\u7EC8\u7AEF","hint.tmuxHosted":"tmux \u6258\u7BA1 \xB7 \u5BBF\u4E3B\u91CD\u542F\u540E\u53EF\u6062\u590D","hint.openInSessionCwd":"\u5728\u5F53\u524D\u4F1A\u8BDD\u5DE5\u4F5C\u76EE\u5F55\u6253\u5F00","panel.sshBook":"SSH \u8FDE\u63A5\u7C3F","btn.sftpFileBrowse":"SFTP \u6587\u4EF6\u6D4F\u89C8","btn.editConnection":"\u7F16\u8F91\u8FDE\u63A5","list.emptySshBook":"\uFF08\u7A7A \u2014 \u5728\u8BBE\u7F6E\u5361\u7247\u6216\u300CSSH \u8FDE\u63A5\u2026\u300D\u91CC\u4FDD\u5B58\uFF09","option.sshConnect":"SSH \u8FDE\u63A5\u2026","hint.sshConnect":"\u624B\u52A8\u586B\u5199\u4E3B\u673A / \u7528\u6237 / \u8BA4\u8BC1\u65B9\u5F0F","panel.editConnection":"\u7F16\u8F91\u8FDE\u63A5 \xB7 {name}","panel.sshConnect":"SSH \u8FDE\u63A5","section.jump":"\u8DF3\u677F\u673A","field.jumpHost":"\u8DF3\u677F\u673A\uFF08[\u7528\u6237@]\u4E3B\u673A[:\u7AEF\u53E3]\uFF0C\u7559\u7A7A = \u76F4\u8FDE\uFF09","placeholder.jumpHost":"\u4F8B\u5982 bastion.corp:2222","check.jumpOwnCred":"\u8DF3\u677F\u673A\u4F7F\u7528\u72EC\u7ACB\u51ED\u636E","field.jumpUsername":"\u8DF3\u677F\u673A\u7528\u6237\u540D\uFF08\u7559\u7A7A\u6CBF\u7528\u76EE\u6807\uFF09","field.jumpAuth":"\u8DF3\u677F\u673A\u8BA4\u8BC1\u65B9\u5F0F\uFF08\u7559\u7A7A\u6CBF\u7528\u76EE\u6807\uFF09","hint.jumpInherit":"\u7559\u7A7A\u51ED\u636E = \u6CBF\u7528\u4E0A\u9762\u90A3\u53F0\u4E3B\u673A\u7684\u8BA4\u8BC1\u65B9\u5F0F\u4E0E\u94A5\u5319\uFF1B\u8DF3\u677F\u673A\u8FDE\u4E0D\u4E0A\u65F6\u9519\u8BEF\u6587\u6848\u4F1A\u70B9\u540D\u5B83\uFF08\u4E0D\u4F1A\u4F2A\u88C5\u6210\u76EE\u6807\u8D85\u65F6\uFF09\u3002","meta.jumpStage":"\u8DF3\u677F\u673A {label}","meta.viaJump":"\u21E2 \u7ECF {label}","meta.viaProxy":"\u21E2 \u7ECF\u4EE3\u7406\u547D\u4EE4","section.proxyCommand":"\u4EE3\u7406\u547D\u4EE4","field.proxyCommand":"\u4EE3\u7406\u547D\u4EE4\uFF08ProxyCommand\uFF0C\u7559\u7A7A = \u4E0D\u7528\uFF09","placeholder.proxyCommand":"\u4F8B\u5982 ssh -W %h:%p bastion","hint.proxyCommand":"\u672C\u673A\u6267\u884C\u7684\u547D\u4EE4\uFF0C\u5B83\u7684 stdin/stdout \u5C31\u662F\u5230\u76EE\u6807\u7684 SSH \u4F20\u8F93\uFF08\u7B49\u4EF7\u4E8E OpenSSH \u7684 ProxyCommand\uFF09\u3002\u652F\u6301 %h \u76EE\u6807\u4E3B\u673A\u3001%p \u7AEF\u53E3\u3001%r \u7528\u6237\u540D\u3001%n \u4E3B\u673A\u3001%% \u5B57\u9762 %\uFF1B\u5176\u4F59\u5199\u6CD5\u539F\u6837\u4FDD\u7559\u3002\u4E0E\u8DF3\u677F\u673A\u540C\u65F6\u586B\u65F6\u8DF3\u677F\u673A\u4F18\u5148\uFF08OpenSSH \u8BED\u4E49\uFF09\u3002\u9700\u8981\u4E0B\u9762\u90A3\u4E2A\u5F00\u5173\uFF0C~/.ssh/config \u5BFC\u5165\u4E0D\u4F1A\u81EA\u52A8\u5E26\u5165\u5B83\u3002","hint.proxyCommandDisabled":"\u26A0 \u5F53\u524D\u300C\u5141\u8BB8 ProxyCommand\u300D\u672A\u6253\u5F00\uFF1A\u8FD9\u6761\u547D\u4EE4\u4E0D\u4F1A\u6267\u884C\uFF0C\u8FDE\u63A5\u4F1A\u660E\u786E\u5931\u8D25\uFF08\u4E0D\u4F1A\u9000\u56DE\u76F4\u8FDE\uFF09\u3002\u5230 \u63D2\u4EF6\u914D\u7F6E \u2192 \u7EC8\u7AEF\u9762\u677F \u6253\u5F00\u5F00\u5173\u540E\u751F\u6548\u3002","hint.proxyCommandNotGranted":"\u26A0 \u8FD9\u6761\u80FD\u529B\u672A\u83B7\u5BBF\u4E3B\u6388\u6743\uFF1A\u70B9\u8FD9\u4E2A\u5F00\u5173\u4F1A\u5C31\u5730\u53D1\u8D77\u4E00\u6B21\u6388\u6743\uFF08\u9762\u677F\u7ED9\u4E00\u6761\u5728\u5BBF\u4E3B\u7EC8\u7AEF\u6267\u884C\u7684\u547D\u4EE4\uFF0C\u514D\u91CD\u542F\uFF09\uFF1B\u4E5F\u53EF\u4EE5\u8D70\u6700\u4E25\u7684\u90A3\u6761\u2014\u2014\u5728\u300C\u542F\u52A8 dsh \u7684\u90A3\u4E2A\u73AF\u5883\u300D\u91CC export DSH_TTY_ALLOW_PROXY_COMMAND=1 \u540E\u91CD\u542F\u5BBF\u4E3B\uFF08\u542F\u52A8\u4E4B\u540E\u518D\u8BBE\u4E0D\u7B97\u6388\u6743\uFF09\u3002\u8FD9\u6837\u5B89\u6392\u662F\u56E0\u4E3A\u8DE8\u7AD9\u9875\u9762\u4E0E\u9875\u5185\u811A\u672C\u90FD\u80FD\u53D1\u56DE\u73AF\u8BF7\u6C42\u2014\u2014\u82E5\u914D\u7F6E\u754C\u9762\u80FD\u51ED\u7A7A\u63D0\u6743\uFF0C\u8FD9\u9053\u95F8\u95E8\u7B49\u4E8E\u6CA1\u6709\uFF1B\u5173\u6389\u5B83\u5219\u968F\u65F6\u53EF\u7528\u3002","badge.notEffective":"\u672A\u751F\u6548\uFF1A\u672A\u83B7\u5BBF\u4E3B\u6388\u6743","elev.title":"\u5C31\u5730\u6388\u6743\uFF08\u514D\u91CD\u542F\uFF09","elev.lockedWhy":"\u672C\u673A\u4EFB\u610F\u8FDB\u7A0B\u90FD\u80FD\u53D1\u56DE\u73AF\u8BF7\u6C42\uFF0C\u6240\u4EE5\u300C\u6253\u5F00\u5371\u9669\u80FD\u529B\u300D\u8FD9\u4EF6\u4E8B\u4E0D\u80FD\u7531\u8FD9\u4E2A\u9875\u9762\u81EA\u5DF1\u8BF4\u4E86\u7B97\u2014\u2014\u5FC5\u987B\u5728\u5BBF\u4E3B\u7684\u6587\u4EF6\u7CFB\u7EDF\u4E0A\u786E\u8BA4\u4E00\u6B21\u3002","elev.step":"\u5728\u5BBF\u4E3B\u7684\u7EC8\u7AEF\u91CC\u6267\u884C\u4E0B\u4E00\u6761\u547D\u4EE4\uFF0C\u5F00\u5173\u4F1A\u81EA\u52A8\u89E3\u9501\uFF1A","elev.copy":"\u590D\u5236\u547D\u4EE4","elev.copied":"\u5DF2\u590D\u5236","elev.copyManual":"\u5F53\u524D\u73AF\u5883\u62FF\u4E0D\u5230\u526A\u8D34\u677F\uFF0C\u8BF7\u624B\u52A8\u9009\u4E2D\u4E0A\u9762\u90A3\u6761\u547D\u4EE4\u590D\u5236\u3002","elev.expiresIn":"{sec} \u79D2\u540E\u5931\u6548","elev.expired":"\u672C\u6B21\u786E\u8BA4\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002","elev.waiting":"\u7B49\u5F85\u786E\u8BA4\u2026\u6267\u884C\u5B8C\u547D\u4EE4\u8FD9\u91CC\u4F1A\u81EA\u52A8\u53D8\u6210\u5DF2\u6388\u6743\u3002","elev.regenerate":"\u91CD\u65B0\u751F\u6210","elev.loading":"\u6B63\u5728\u751F\u6210\u786E\u8BA4\u547D\u4EE4\u2026","elev.granted":"\u5DF2\u6388\u6743\u5E76\u751F\u6548\u3002","elev.grantedNeedSave":"\u5DF2\u6388\u6743\u3002\u70B9\u300C\u4FDD\u5B58\u300D\u540E\u751F\u6548\u3002","elev.grantedAt":"\u5DF2\u6388\u6743 \xB7 {time}","elev.revoke":"\u64A4\u9500\u5BBF\u4E3B\u6388\u6743","elev.revoked":"\u5DF2\u64A4\u9500\u5BBF\u4E3B\u6388\u6743\uFF08\u914D\u7F6E\u5F00\u5173\u4FDD\u6301\u4E0D\u53D8\uFF0C\u91CD\u65B0\u6388\u6743\u540E\u4F1A\u7ACB\u523B\u751F\u6548\uFF09\u3002","elev.viaEnv":"\u7531\u542F\u52A8\u73AF\u5883\u53D8\u91CF\u6388\u6743\uFF1B\u8981\u64A4\u9500\u9700\u5728\u542F\u52A8\u73AF\u5883\u91CC\u53BB\u6389\u5B83\u5E76\u91CD\u542F\u5BBF\u4E3B\u3002","elev.close":"\u6536\u8D77","elev.disableFirst":"\u5148\u5173\u6389\u8FD9\u4E2A\u914D\u7F6E\u5F00\u5173","elev.otherWay":"\u53E6\u4E00\u79CD\u65B9\u5F0F\uFF08\u6700\u5F3A\uFF0C\u9700\u8981\u91CD\u542F\u5BBF\u4E3B\uFF09","elev.envHow":"\u5728\u300C\u542F\u52A8 dsh \u7684\u90A3\u4E2A\u73AF\u5883\u300D\u91CC export {env}=1\uFF0C\u7136\u540E\u91CD\u542F\u5BBF\u4E3B\u3002\u6CE8\u610F\uFF1A\u542F\u52A8\u4E4B\u540E\u518D\u8BBE\u3001\u6216\u5199\u8FDB\u522B\u7684\u914D\u7F6E\u6587\u4EF6\u90FD\u4E0D\u7B97\u6388\u6743\u2014\u2014\u8FD9\u9053\u95F8\u95E8\u9632\u7684\u5C31\u662F\u300C\u8FD0\u884C\u671F\u80FD\u6539\u7684\u4E1C\u897F\u5192\u5145\u6388\u6743\u300D\u3002","elev.error":"\u5C31\u5730\u6388\u6743\u6CA1\u6210\u529F\uFF1A","meta.probeProxy":"\u4EE3\u7406\u547D\u4EE4","meta.probeProxyOff":"\u4EE3\u7406\u547D\u4EE4\uFF08\u672A\u542F\u7528\uFF09","meta.probeTcpSkipped":"\u76F4\u8FDE\u9884\u68C0\u5DF2\u8DF3\u8FC7\uFF08\u8D70\u4EE3\u7406\u547D\u4EE4\uFF09","section.connection":"\u8FDE\u63A5","field.host":"\u4E3B\u673A","placeholder.host":"example.com \u6216 IP","field.port":"\u7AEF\u53E3","field.username":"\u7528\u6237\u540D","section.auth":"\u8BA4\u8BC1","field.authMethod":"\u8BA4\u8BC1\u65B9\u5F0F","option.authInherit":"\uFF08\u6CBF\u7528\u76EE\u6807\uFF09","option.authAgent":"agent \u2014 \u4F7F\u7528\u672C\u673A ssh-agent","option.authKey":"key \u2014 \u79C1\u94A5\u6587\u4EF6","option.authPassword":"password \u2014 \u5BC6\u7801","field.keyPath":"\u79C1\u94A5\u8DEF\u5F84","field.hostKeyAlias":"\u4E3B\u673A\u5BC6\u94A5\u522B\u540D","field.passphrase":"\u79C1\u94A5\u53E3\u4EE4\uFF08\u53EF\u7A7A\uFF09","field.password":"\u5BC6\u7801","placeholder.credRef":"\u6216\uFF1A\u9009\u62E9\u51ED\u636E\u5B58\u50A8\u91CC\u7684\u5F15\u7528\u540D","hint.credRefCandidates":"\u5019\u9009 = \u51ED\u636E\u5B58\u50A8\u91CC\u5DF2\u6709\u7684\u5F15\u7528\u540D + \u672C\u673A\u8FDE\u63A5\u7C3F\u91CC\u5728\u7528\u7684\u5F15\u7528\u540D","list.credOverwrite":"{name}\uFF08\u518D\u70B9\u8986\u76D6\u5DF2\u586B\uFF09","list.moreMatches":"\u8FD8\u6709 {count} \u4E2A \u2014 \u7EE7\u7EED\u8F93\u5165\u7B5B\u9009","list.noCredRef":"\u6CA1\u6709\u5339\u914D\u7684\u5F15\u7528","check.rememberCredential":"\u4FDD\u5B58\u65F6\u5B58\u5165\u51ED\u636E\u5B58\u50A8","hint.rememberCredential":"\u52FE\u9009\u540E\uFF0C\u70B9\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\u6216\u300C\u8FDE\u63A5\uFF08\u5E76\u4FDD\u5B58\uFF09\u300D\u65F6\u628A\u5BC6\u7801\u5199\u8FDB\u5B98\u65B9\u51ED\u636E\u5B58\u50A8\uFF0C\u5B57\u6BB5\u91CC\u53EA\u7559 env: \u5F15\u7528\uFF08\u503C\u5728 ~/.dsh/.credentials.yaml\uFF0C\u4E0D\u8FDB\u73AF\u5883\u3001\u4E0D\u56DE\u4F20\u6D4F\u89C8\u5668\uFF1B\u6321\u4E0D\u4F4F\u540C\u7528\u6237\u8FDB\u7A0B\u4E0E agent\uFF09\u3002\u4E0D\u52FE\u9009\u5219\u6309\u73B0\u72B6\u660E\u6587\u5199\u8FDB\u8BBE\u7F6E\u6587\u4EF6\u3002\u80FD\u7528\u5BC6\u94A5 / agent \u5C31\u522B\u5B58\u5BC6\u7801\u3002","btn.clearCredential":"\u6E05\u9664\u5DF2\u5B58\u51ED\u636E","error.credPlainUnavailable":"\u5BBF\u4E3B\u672A\u63D0\u4F9B\u51ED\u636E\u670D\u52A1\uFF08remote.credentials\uFF09\uFF0C\u53EA\u80FD\u660E\u6587\u4FDD\u5B58","error.credPlainIncomplete":"\u51ED\u636E\u670D\u52A1\u4E0D\u5B8C\u6574\uFF0C\u53EA\u80FD\u660E\u6587\u4FDD\u5B58","status.credUnreported":"\u5F15\u7528 {ref}\uFF1A\u5BBF\u4E3B\u672A\u62A5\u544A\u72B6\u6001","error.credStatusFailed":"\u8BFB\u53D6\u51ED\u636E\u72B6\u6001\u5931\u8D25\uFF1A{error}","status.credStored":"\u5DF2\u5B58\u5165{source} \xB7 {ref}","meta.credSource":"\uFF08\u6765\u6E90 {source}\uFF09","status.credUnknown":"\u5F15\u7528 {ref}\uFF1A\u5B58\u50A8\u91CC\u8FD8\u6CA1\u6709\u8FD9\u4E2A\u503C","hint.noCredRefPassphrase":"\u8FD8\u6CA1\u6709\u522B\u7684\u8FDE\u63A5\u7528\u8FC7\u51ED\u636E\u5F15\u7528 \u2014 \u53EF\u5728\u79C1\u94A5\u53E3\u4EE4\u6846\u76F4\u63A5\u624B\u8F93 env:NAME","hint.noCredRefPassword":"\u8FD8\u6CA1\u6709\u522B\u7684\u8FDE\u63A5\u7528\u8FC7\u51ED\u636E\u5F15\u7528 \u2014 \u52FE\u4E0A\u9762\u7684\u300C\u4FDD\u5B58\u65F6\u5B58\u5165\u51ED\u636E\u5B58\u50A8\u300D\u65B0\u5EFA\u4E00\u4E2A\uFF0C\u6216\u76F4\u63A5\u5728\u5BC6\u7801\u6846\u624B\u8F93 env:NAME","section.options":"\u9009\u9879","check.agentForward":"agent forwarding\uFF08\u8FDC\u7A0B\u53EF\u7528\u672C\u5730 ssh-agent \u94A5\u5319\uFF0C\u5982\u8FDC\u7A0B git clone\uFF09","hint.hostKeyAlias":"\u7559\u7A7A = \u6309\u4E3B\u673A\u5730\u5740\u8BB0\u4F4F\u6307\u7EB9\u3002\u540C\u4E00\u53F0\u4E3B\u673A\u7ECF\u4E0D\u540C\u5730\u5740\uFF08\u8DF3\u677F\u673A\u540E / \u7AEF\u53E3\u8F6C\u53D1\uFF09\u89E6\u8FBE\u65F6\uFF0C\u586B\u540C\u4E00\u4E2A\u522B\u540D\u53EF\u8BA9\u5B83\u4EEC\u5171\u7528\u4E00\u6761\u4E3B\u673A\u5BC6\u94A5\u8BB0\u5F55\uFF0C\u907F\u514D\u6BCF\u6B21\u5207\u6362\u5730\u5740\u90FD\u62A5\u300C\u6307\u7EB9\u53D8\u66F4\u300D\uFF1B\u53EA\u5F71\u54CD\u6307\u7EB9\u8BB0\u5728\u54EA\uFF0C\u4E0D\u6539\u8FDE\u63A5\u5730\u5740","placeholder.hostKeyAlias":"\u7559\u7A7A = \u6309\u4E3B\u673A\u5730\u5740","check.persist":"\u6301\u4E45\u4F1A\u8BDD\uFF08tmux \u6258\u7BA1\uFF0C\u65AD\u7EBF/\u91CD\u542F\u540E\u6062\u590D\u73B0\u573A\uFF1B\u8FDC\u7A0B\u9700\u5B89\u88C5 tmux\uFF09","check.saveToBook":"\u4FDD\u5B58\u5230\u8FDE\u63A5\u7C3F\uFF08\u540C\u540D\u8986\u76D6\uFF09","field.bookName":"\u8FDE\u63A5\u7C3F\u540D\u79F0","placeholder.bookName":"\u7559\u7A7A\u5219\u7528\u4E3B\u673A\u540D","error.hostUserRequired":"\u4E3B\u673A\u4E0E\u7528\u6237\u540D\u5FC5\u586B","error.keyPathRequired":"auth=key \u9700\u8981\u79C1\u94A5\u8DEF\u5F84","error.passwordRequired":"auth=password \u9700\u8981\u5BC6\u7801","btn.cancel":"\u53D6\u6D88","btn.connect":"\u8FDE\u63A5","btn.fileBrowse":"\u6587\u4EF6\u6D4F\u89C8","btn.browseTitle":"\u4E0D\u52A8\u7EC8\u7AEF\uFF0C\u76F4\u63A5\u4EE5\u5F53\u524D\u586B\u5199\u7684\u4FE1\u606F\u6253\u5F00 SFTP \u6587\u4EF6\u6D4F\u89C8","btn.probe":"\u8BD5\u8FDE","btn.probeTitle":"\u6309\u5F53\u524D\u586B\u5199\u8BCA\u65AD\u8FDE\u63A5\uFF08TCP \u2192 \u4E3B\u673A\u5BC6\u94A5 \u2192 \u8BA4\u8BC1\uFF09\uFF1B\u4E0D\u4F1A\u65B0\u5EFA\u4F1A\u8BDD\uFF0C\u4E5F\u4E0D\u8BB0\u5F55\u4E3B\u673A\u6307\u7EB9","error.saveCredFailed":"\u4FDD\u5B58\u5931\u8D25\uFF1A{error}","btn.saveEdit":"\u4FDD\u5B58\u4FEE\u6539","error.saveBookFailed":"\u4FDD\u5B58\u8FDE\u63A5\u7C3F\u5931\u8D25\uFF1A{error}","error.bookNameTaken":"\u8FDE\u63A5\u7C3F\u91CC\u5DF2\u6709\u540C\u540D\u6761\u76EE: {name}","panel.sftpDual":"SFTP \u53CC\u680F \xB7 {label}","status.failed":"\u5931\u8D25","status.done":"\u5B8C\u6210","placeholder.localPath":"\u672C\u673A\u8DEF\u5F84\uFF08\u56DE\u8F66\u8DF3\u8F6C\uFF09","placeholder.remotePath":"\u8FDC\u7A0B\u8DEF\u5F84\uFF08\u56DE\u8F66\u8DF3\u8F6C\uFF09","btn.refresh":"\u5237\u65B0","btn.mkdir":"\u65B0\u5EFA\u76EE\u5F55","btn.hiddenFiles":"\u9690\u85CF\u6587\u4EF6","btn.hiddenFilesTitle":"\u663E\u793A / \u9690\u85CF\u4EE5 . \u5F00\u5934\u7684\u6587\u4EF6\uFF08.env\u3001.gitignore \u7B49\uFF09","error.dirNotReady":"\u76EE\u5F55\u5C1A\u672A\u5B9A\u4F4D\u5B8C\u6210","meta.dir":"\u76EE\u5F55","btn.transferTo":"\u4F20\u8F93\u5230{target}\uFF1A{path}","meta.local":"\u672C\u673A","meta.remote":"\u8FDC\u7A0B","error.transferDirsNotReady":"\u4E24\u4FA7\u76EE\u5F55\u5C1A\u672A\u5B9A\u4F4D\u5B8C\u6210\uFF0C\u7B49\u5217\u8868\u52A0\u8F7D\u540E\u518D\u4F20\u8F93","msg.transferring":"\u4F20\u8F93 {name}\u2026","error.transferFailed":"\u4F20\u8F93\u5931\u8D25","error.noTaskId":"\u670D\u52A1\u7AEF\u672A\u8FD4\u56DE\u4EFB\u52A1 id","msg.transferCanceled":"\u5DF2\u53D6\u6D88\u4F20\u8F93 {name}","msg.transferred":"\u5DF2\u4F20\u8F93 {name}","btn.download":"\u4E0B\u8F7D {name}","btn.rename":"\u91CD\u547D\u540D {name}","placeholder.newName":"\u65B0\u540D\u79F0","btn.deleteEntry":"\u5220\u9664 {name}","btn.deleteEntryDir":"\u5220\u9664 {name}\uFF08\u542B\u5185\u5BB9\uFF09","msg.deleted":"\u5DF2\u5220\u9664 {name}","list.parentDir":"..\uFF08\u4E0A\u7EA7\u76EE\u5F55\uFF09","list.emptyDir":"\uFF08\u7A7A\u76EE\u5F55\uFF09","list.hiddenOnly":"\uFF08\u8FD9\u91CC\u53EA\u6709\u9690\u85CF\u6587\u4EF6 \u2014 \u70B9\u680F\u4E0A\u7684\u300C\u9690\u85CF\u6587\u4EF6\u300D\u663E\u793A\uFF09","error.dropOnLocalPane":"\u62D6\u5230\u672C\u673A\u680F\u6CA1\u6709\u53EF\u6267\u884C\u7684\u52A8\u4F5C\uFF1A\u672C\u673A\u6587\u4EF6\u8981\u4F20\u5230\u5BF9\u9762\uFF0C\u8BF7\u62D6\u5230\u53F3\u4FA7\u300C\u8FDC\u7A0B\u300D\u680F","list.truncated":"\u2026\u5176\u4F59 {rest} \u9879\u672A\u6E32\u67D3\uFF08\u5171 {total} \u9879\uFF09\u2014\u2014\u7528\u4E0A\u65B9\u8DEF\u5F84\u6846\u8DF3\u8F6C\u5230\u5B50\u76EE\u5F55\u5B9A\u4F4D","list.itemCount":"{count} \u9879","placeholder.newDirName":"\u65B0\u76EE\u5F55\u540D\uFF08\u76F8\u5BF9\u5F53\u524D\u76EE\u5F55\uFF09","msg.creatingDir":"\u521B\u5EFA\u76EE\u5F55 {name}\u2026","btn.ok":"\u786E\u5B9A","btn.confirm":"\u786E\u8BA4?","btn.cancelTransfer":"\u53D6\u6D88\u4F20\u8F93","msg.downloadCanceled":"\u5DF2\u53D6\u6D88\u4E0B\u8F7D {name}","msg.downloadResuming":"\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u4ECE {offset} \u5904\u7EED\u4F20 {name}\u2026","error.downloadFailed":"\u4E0B\u8F7D\u5931\u8D25","msg.downloaded":"\u5DF2\u4E0B\u8F7D {name}\uFF08{size}\uFF09","error.downloadTooBig":"\u6587\u4EF6\u8D85\u8FC7\u4E0B\u8F7D\u4E0A\u9650\uFF08{size}\uFF09\uFF1A\u8BF7\u7528\u53CC\u680F \u21E6 \u76F4\u4F20\u6216\u7EC8\u7AEF scp/rsync","msg.canceled":"\u5DF2\u53D6\u6D88","btn.upload":"\u4E0A\u4F20","btn.uploadTitle":"\u9009\u62E9\u6587\u4EF6\u4E0A\u4F20\uFF1B\u4E5F\u53EF\u4EE5\u628A\u6587\u4EF6 / \u6587\u4EF6\u5939\u76F4\u63A5\u62D6\u8FDB\u5217\u8868","msg.uploading":"\u4E0A\u4F20\u4E2D\u2026","msg.uploadDone":"\u4E0A\u4F20\u5B8C\u6210","error.uploadFailed":"\u4E0A\u4F20\u5931\u8D25","error.networkError":"\u7F51\u7EDC\u9519\u8BEF","error.uploadCountExceeded":"\u6587\u4EF6\u6570\u8D85\u8FC7\u4E0A\u9650\uFF08{max}\uFF09\uFF1A\u672C\u6B21 {count} \u4E2A\uFF0C\u8BF7\u5206\u6279\u4E0A\u4F20","status.overLimit":"\u8D85\u9650","error.uploadTooBig":"\u6587\u4EF6\u8D85\u8FC7\u4E0A\u4F20\u4E0A\u9650\uFF08{size}\uFF09\uFF1A{name}\uFF0C\u8BF7\u7528\u53CC\u680F \u21E8 \u76F4\u4F20\u6216\u7EC8\u7AEF scp/rsync","error.uploadTotalTooBig":"\u6587\u4EF6\u603B\u5927\u5C0F\u8D85\u8FC7\u4E0A\u4F20\u4E0A\u9650\uFF1A\u8BF7\u5206\u6279\u4E0A\u4F20\uFF08\u6216\u7528\u53CC\u680F \u21E8 \u76F4\u4F20\uFF09","msg.uploadCanceled":"\u5DF2\u53D6\u6D88\u4E0A\u4F20\uFF08\u5DF2\u4F20 {done}/{total} \u4E2A\uFF09","status.allDone":"\u5168\u90E8\u5B8C\u6210","msg.uploadDoneCount":"\u4E0A\u4F20\u5B8C\u6210 {count} \u4E2A\u6587\u4EF6","error.connectFailed":"\u8FDE\u63A5\u5931\u8D25\uFF1A{error}","status.connectingEllipsis":"\u8FDE\u63A5\u4E2D\u2026","status.connectedPid":"\u5DF2\u8FDE\u63A5 pid={pid}","status.connectedSsh":"SSH {target}\u5DF2\u8FDE\u63A5","status.exitedWith":"\u5DF2\u9000\u51FA {detail}","status.error":"\u9519\u8BEF\uFF1A{message}","status.retryHint":"{message} \xB7 \u70B9\u51FB\u91CD\u8BD5","btn.clickRetry":"\u70B9\u51FB\u91CD\u8BD5","status.disconnectedReconnecting":"\u8FDE\u63A5\u65AD\u5F00 \u2014 \u81EA\u52A8\u91CD\u8FDE\u4E2D","status.disconnected":"\u8FDE\u63A5\u65AD\u5F00","status.reconnecting":"\u81EA\u52A8\u91CD\u8FDE\u4E2D\u2026","error.copyFailed":"\u590D\u5236\u5931\u8D25\uFF1A\u5F53\u524D\u73AF\u5883\u4E0D\u5141\u8BB8\u8BBF\u95EE\u526A\u8D34\u677F\uFF08http \u8BBF\u95EE\u65F6\u8BF7\u6539\u7528 localhost \u6216\u7EC8\u7AEF\u5185\u5FEB\u6377\u952E\uFF09","error.pasteFailed":"\u6D4F\u89C8\u5668\u4E0D\u5141\u8BB8\u7F51\u9875\u8BFB\u53D6\u526A\u8D34\u677F\uFF08http \u8BBF\u95EE\u65F6\u5E38\u89C1\uFF09\uFF1A\u8BF7\u5728\u7EC8\u7AEF\u91CC\u6309 Ctrl+V / Cmd+V \u7C98\u8D34","status.initializing":"\u521D\u59CB\u5316\u2026","placeholder.search":"\u641C\u7D22 (Enter \u4E0B\u4E00\u4E2A, Shift+Enter \u4E0A\u4E00\u4E2A)","btn.searchTitle":"\u641C\u7D22 (Ctrl+F)","btn.clearTitle":"\u6E05\u5C4F","btn.copyTitle":"\u590D\u5236\u9009\u4E2D\u5185\u5BB9","btn.pasteTitle":"\u7C98\u8D34","btn.minimizeTitle":"\u6700\u5C0F\u5316\uFF08\u4F1A\u8BDD\u4FDD\u6301\u8FD0\u884C\uFF0C\u72B6\u6001\u5E76\u5165\u4FA7\u8FB9\u680F\u5165\u53E3\uFF09","btn.closePanelTitle":"\u5173\u95ED\u9762\u677F\uFF08\u7ED3\u675F\u4F1A\u8BDD\uFF0C\u6807\u7B7E\u4FDD\u7559\uFF0C\u91CD\u5F00\u5373\u6062\u590D\u5217\u8868\uFF09","btn.restoreDock":"\u70B9\u51FB\u6062\u590D\u7EC8\u7AEF\u7A97\u53E3","panel.title":"\u7EC8\u7AEF","status.minimized":"\u7EC8\u7AEF\u5DF2\u6700\u5C0F\u5316 \u2014 \u70B9\u51FB\u6062\u590D","error.configLoadFailed":"\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25","error.saveTunnelFailed":"\u4FDD\u5B58\u96A7\u9053\u5931\u8D25","error.tunnelNameTaken":"\u5DF2\u5B58\u5728\u540C\u540D\u96A7\u9053\u300C{name}\u300D\u2014\u2014\u540C\u4E00\u300C\u8FDE\u63A5\u7C3F\u6761\u76EE + \u65B9\u5411 + \u7AEF\u53E3\u300D\u53EA\u80FD\u6709\u4E00\u6761\u3002\u6539\u7AEF\u53E3\u4F1A\u5F97\u5230\u65B0\u540D\u5B57\uFF0C\u6216\u5148\u5220\u6389\u65E7\u7684\u90A3\u6761\u3002","msg.tunnelApplied":"\u96A7\u9053\u300C{name}\u300D\u5DF2\u751F\u6548","msg.tunnelUpdated":"\u96A7\u9053\u300C{name}\u300D\u5DF2\u66F4\u65B0","error.nameHostUserRequired":"\u540D\u79F0\u3001\u4E3B\u673A\u3001\u7528\u6237\u540D\u5FC5\u586B","msg.hostEdited":"\u5DF2\u4FEE\u6539\u6761\u76EE\u300C{name}\u300D\u2014 \u968F\u300C\u4FDD\u5B58\u300D\u5199\u5165\u914D\u7F6E","error.probeFailed":"\u274C \u8FDE\u63A5\u5931\u8D25\uFF1A{error}","error.hostKeyDeleteFailed":"\u5220\u9664\u4E3B\u673A\u5BC6\u94A5\u8BB0\u5F55\u5931\u8D25","msg.hostKeyDeleted":"\u5DF2\u5220\u9664\u4E3B\u673A\u5BC6\u94A5\u8BB0\u5F55\uFF08\u4E0B\u6B21\u8FDE\u63A5\u91CD\u65B0\u8BB0\u5F55\u6307\u7EB9\uFF09","error.sshConfigReadFailed":"\u8BFB\u53D6 ~/.ssh/config \u5931\u8D25","msg.proxySkipped":"{count} \u6761\u7528\u4E86\u8DF3\u677F\u673A\u4F46\u89E3\u6790\u4E0D\u51FA\u8DF3\u677F\u673A\uFF08\u522B\u540D\u7F3A\u5931 / \u522B\u540D\u81EA\u5DF1\u8FD8\u4F9D\u8D56\u8DF3\u677F\u673A\uFF09\u672A\u5BFC\u5165\uFF1A{names}","msg.proxyCommandSkipped":"{count} \u6761\u53EA\u914D\u4E86\u4EE3\u7406\u547D\u4EE4\uFF08ProxyCommand\uFF09\u672A\u5BFC\u5165\uFF1A{names} \u2014\u2014 \u4EE3\u7406\u547D\u4EE4\u662F\u300C\u672C\u673A\u6267\u884C\u4E00\u6761\u547D\u4EE4\u300D\u90A3\u4E00\u6863\uFF0C\u5BFC\u5165\u4E0D\u4F1A\u81EA\u52A8\u5E26\u5165\uFF1B\u9700\u8981\u65F6\u5728\u8FDE\u63A5\u7C3F\u91CC\u624B\u586B\u5E76\u6253\u5F00\u300C\u5141\u8BB8 ProxyCommand\u300D","msg.skippedNotConcrete":"{count} \u6761\u4E0D\u662F\u5177\u4F53\u4E3B\u673A\uFF08\u901A\u914D / \u65E0 User\uFF09","list.separator":"\u3001","meta.etc":" \u7B49","msg.importOverflow":"\u8D85\u8FC7\u5BFC\u5165\u4E0A\u9650\u7684 {count} \u6761\u672A\u5BFC\u5165","list.separatorFull":"\uFF1B","msg.noNewEntries":"\u6CA1\u6709\u65B0\u6761\u76EE\uFF08{count} \u6761\u540C\u540D\u8DF3\u8FC7\uFF09","msg.noImportableHosts":"~/.ssh/config \u91CC\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u5177\u4F53\u4E3B\u673A","msg.importedHosts":"\u5DF2\u5BFC\u5165 {added} \u6761\uFF08\u540C\u540D\u8DF3\u8FC7 {skipped} \u6761\uFF09\uFF0C\u968F\u300C\u4FDD\u5B58\u300D\u5199\u5165\u914D\u7F6E","error.knownHostsReadFailed":"\u8BFB\u53D6 ~/.ssh/known_hosts \u5931\u8D25","msg.noNewFingerprints":"\u6CA1\u6709\u65B0\u6307\u7EB9\uFF08{count} \u6761\u5DF2\u5B58\u5728\uFF09","msg.noImportableKnownHosts":"known_hosts \u91CC\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u5177\u4F53\u4E3B\u673A","error.saveHostKeysFailed":"\u4FDD\u5B58 hostKeys \u5931\u8D25","msg.importedFingerprints":"\u5DF2\u5BFC\u5165 {added} \u6761\u4E3B\u673A\u7684\u6307\u7EB9\uFF08\u8DF3\u8FC7 {skipped} \u6761\u5DF2\u5B58\u5728\uFF09","hint.knownHostsTruncated":"\uFF1B\u6CE8\u610F\uFF1Aknown_hosts \u8D85\u8FC7 500 \u6761\u4E3B\u673A\uFF0C\u672C\u6B21\u4EC5\u5BFC\u5165\u524D 500 \u6761","error.saveFailed":"\u4FDD\u5B58\u5931\u8D25","msg.saved":"\u5DF2\u4FDD\u5B58\u5E76\u70ED\u751F\u6548","check.rememberCredentialApply":"\u5E94\u7528\u65F6\u5B58\u5165\u51ED\u636E\u5B58\u50A8","hint.appliedOnSave":"\u968F\u5361\u7247\u300C\u4FDD\u5B58\u300D\u5199\u5165\u914D\u7F6E","card.name":"\u7EC8\u7AEF\u9762\u677F","card.desc":"xterm \u7EC8\u7AEF\u9762\u677F\uFF1A\u591A\u6807\u7B7E\u9875\u3001\u65AD\u7EBF\u81EA\u52A8\u91CD\u8FDE\u3001cwd \u8DDF\u968F\u4F1A\u8BDD\u3001SSH \u8FDE\u63A5\u7C3F\u4E0E\u4E3B\u673A\u6307\u7EB9\u9489\u624E\u3001tmux \u4F1A\u8BDD\u6301\u4E45\u5316\u3002","card.descFull":"xterm \u7EC8\u7AEF\u9762\u677F\uFF1A\u591A\u6807\u7B7E\u9875\u3001\u65AD\u7EBF\u81EA\u52A8\u91CD\u8FDE\u3001cwd \u8DDF\u968F\u4F1A\u8BDD\u3001SSH \u8FDE\u63A5\u7C3F\u4E0E\u4E3B\u673A\u6307\u7EB9\u9489\u624E\u3001tmux \u4F1A\u8BDD\u6301\u4E45\u5316\uFF1Bshell / TERM / \u5E76\u53D1\u4E0A\u9650\u7B49\u4FDD\u5B58\u5373\u70ED\u751F\u6548\u3002","list.loadingConfig":"\u52A0\u8F7D\u914D\u7F6E\u4E2D\u2026","section.basic":"\u57FA\u7840","check.enabled":"\u542F\u7528\u63D2\u4EF6\uFF08\u4FDD\u5B58\u5373\u70ED\u751F\u6548\uFF1A\u5DE5\u5177\u4E0E\u9762\u677F\u5165\u53E3\u7ACB\u523B\u6536\u8D77\uFF0C\u4F1A\u8BDD\u8F6C\u4FDD\u6D3B\uFF09","check.announce":"\u5411 agent \u516C\u544A\u7EC8\u7AEF\u9762\u677F\u80FD\u529B","check.shellIntegration":"shell \u96C6\u6210\uFF08OSC 133/7 \u6CE8\u5165\uFF09","check.shellIntegrationWindows":"shell \u96C6\u6210\uFF08OSC 133/7 \u6CE8\u5165\uFF0Ctty_capture{last} \u4E0E cwd \u8DDF\u968F\u4F9D\u8D56\u5B83\uFF09","hint.shellIntegrationWindows":"Windows \u5BBF\u4E3B\u4E0A\u4E0D\u9002\u7528\uFF1A\u6CE8\u5165\u8D70\u7684\u662F POSIX \u7684 `-c` \u5305\u88C5\u5C42\u4E0E rc \u6869\uFF0Ccmd / PowerShell \u4E0A\u90FD\u4E0D\u6210\u7ACB\uFF08\u5B9E\u6D4B cmd \u5FFD\u7565 `-c` \u7A7A\u8DD1\u3001PowerShell \u62A5 export \u4E0D\u5B58\u5728\uFF09\u3002\u56E0\u6B64\u300C\u672C\u5730\u300D\u6807\u7B7E\u7684 cwd \u8DDF\u968F\u4E0E tty_capture{last} \u4E0D\u53EF\u7528\uFF1B\u8FDC\u7A0B Linux / macOS \u4E3B\u673A\u7167\u65E7\u652F\u6301\u3002","section.sftp":"SFTP \u6587\u4EF6\u4F20\u8F93","field.sftpStyle":"SFTP \u6587\u4EF6\u6D4F\u89C8\u98CE\u683C","option.sftpDialog":"\u5355\u7A97\u4F53 \u2014 \u8FDC\u7A0B\u76EE\u5F55 + \u4E0A\u4F20/\u4E0B\u8F7D/\u62D6\u62FD","option.sftpDual":"\u53CC\u680F \u2014 \u5DE6\u672C\u673A / \u53F3\u8FDC\u7A0B\uFF0C\u9009\u4E2D\u76F4\u4F20","hint.sftpDual":"\u53CC\u680F\u5728\u672C\u673A\u4E0E\u8FDC\u7A0B\u4E4B\u95F4\u5BF9\u62F7\u6587\u4EF6\uFF08\u76EE\u5F55\u9012\u5F52\u3001\u540C\u540D\u8986\u76D6\uFF09\uFF1B\u91CD\u65B0\u6253\u5F00 SFTP \u540E\u751F\u6548","field.sftpLimits":"SFTP \u4F20\u8F93\u9650\u5236\uFF080 = \u4E0D\u9650\uFF09","field.downloadLimit":"\u4E0B\u8F7D\u4E0A\u9650 (MB)","field.uploadLimit":"\u4E0A\u4F20\u4E0A\u9650 (MB)","field.uploadCountLimit":"\u6279\u91CF\u6587\u4EF6\u6570\u4E0A\u9650","hint.sftpLimits":"\u6D4F\u89C8\u5668\u4FA7\u4FDD\u62A4\uFF1A\u5355\u4E2A\u6587\u4EF6\u8D85\u8FC7\u4E0A\u9650\u65F6\u4E2D\u6B62\u4E0B\u8F7D/\u4E0A\u4F20\uFF08\u5927\u6587\u4EF6\u8BF7\u7528\u53CC\u680F \u21E8/\u21E6 \u76F4\u4F20\u6216\u7EC8\u7AEF scp/rsync\uFF0C\u4E0D\u5360\u6D4F\u89C8\u5668\u5185\u5B58\uFF09\uFF1B\u6587\u4EF6\u6570\u4E0A\u9650\u9488\u5BF9\u4E00\u6B21\u6279\u91CF/\u62D6\u62FD\u4E0A\u4F20\uFF1B\u4FDD\u5B58\u5373\u70ED\u751F\u6548","section.session":"\u4F1A\u8BDD","field.persistence":"\u4F1A\u8BDD\u6301\u4E45\u5316\uFF08tmux\uFF09","option.persistOff":"\u5173\u95ED \u2014 \u4F1A\u8BDD\u968F\u9762\u677F/\u5BBF\u4E3B\u7ED3\u675F\uFF08\u9ED8\u8BA4\uFF09","option.persistTmux":"tmux \u2014 \u65B0\u5F00\u7684\u7EC8\u7AEF/SSH \u6807\u7B7E\u9ED8\u8BA4\u6301\u4E45\u5316","hint.persistence":"\u5F00\u542F\u540E\u6240\u6709\u65B0\u6807\u7B7E\uFF08\u672C\u5730/SSH \u8FDE\u63A5\u7C3F/SSH \u8FDE\u63A5\u5BF9\u8BDD\u6846\uFF09\u9ED8\u8BA4\u7531 tmux \u6258\u7BA1\u3001\u53EF\u8DE8\u5BBF\u4E3B\u91CD\u542F\u6062\u590D\uFF1B\u9700\u672C\u673A/\u8FDC\u7A0B\u5B89\u88C5 tmux\uFF1BSSH \u5BF9\u8BDD\u6846\u53EF\u5BF9\u5355\u6B21\u8FDE\u63A5\u53D6\u6D88\u52FE\u9009\uFF1B\u5DF2\u6709\u6807\u7B7E\u4E0D\u53D7\u5F71\u54CD","hint.persistenceWindows":"\uFF1BWindows \u5BBF\u4E3B\u4E0A tmux \u4E0D\u53EF\u7528\uFF0C\u672C\u5730\u6807\u7B7E\u4F1A\u7167\u5E38\u6253\u5F00\u4F46\u4E0D\u53D7\u6258\u7BA1","check.endOnPageClose":"\u5173\u95ED\u9875\u9762\u540E\u7ED3\u675F\u6301\u4E45\u4F1A\u8BDD\uFF08\u4E0D\u4FDD\u6D3B\uFF09","check.statsEnabled":"\u670D\u52A1\u5668\u72B6\u6001\u6761\uFF08CPU / \u5185\u5B58 / \u78C1\u76D8 / \u5728\u7EBF / TCP / \u7F51\u901F\uFF1B\u91C7\u4E0D\u5230\u7684\u9879\u663E\u793A\u300C\u65E0\u300D\uFF09","hint.statsEnabled":"\u9ED8\u8BA4\u5173\u95ED\uFF1A\u6574\u4E2A\u9875\u9762\u5173\u95ED\u65F6\u6301\u4E45\u4F1A\u8BDD\u7559\u5B58\uFF08\u4FDD\u6D3B\u671F\u540E\u53EF\u518D\u6062\u590D\uFF09\uFF1B\u5F00\u542F\u5219\u9875\u9762\u65AD\u5F00\u4E14\u4FDD\u6D3B\u671F\u7ED3\u675F\u65F6\u8FDE tmux \u4F1A\u8BDD\u4E00\u8D77\u7ED3\u675F\u2014\u2014\u6CE8\u610F\u5237\u65B0\u9875\u9762\u5728\u4FDD\u6D3B\u671F\u5185\u4E0D\u53D7\u5F71\u54CD","check.allowProxyCommand":"\u5141\u8BB8 ProxyCommand\uFF08\u672C\u673A\u6267\u884C\u547D\u4EE4\uFF1B\u9ED8\u8BA4\u5173\uFF09","hint.allowProxyCommand":"\u6253\u5F00\u540E\uFF0C\u8FDE\u63A5\u7C3F\u6761\u76EE\u91CC\u586B\u7684\u4EE3\u7406\u547D\u4EE4\u4F1A\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u6267\u884C\uFF0C\u5B83\u7684 stdin/stdout \u5F53\u4F5C\u5230\u76EE\u6807\u7684 SSH \u4F20\u8F93\uFF08\u7B49\u4EF7\u4E8E OpenSSH \u7684 ProxyCommand\uFF09\u3002\u8FD9\u662F\u672C\u63D2\u4EF6\u552F\u4E00\u300C\u914D\u7F6E\u91CC\u5199\u4E00\u884C\u5C31\u5728\u672C\u673A\u8DD1\u547D\u4EE4\u300D\u7684\u5F00\u5173\uFF0C\u6240\u4EE5\u9ED8\u8BA4\u5173\uFF1A\u5173\u7740\u65F6\u643A\u5E26\u4EE3\u7406\u547D\u4EE4\u7684\u8FDE\u63A5\u4F1A\u660E\u786E\u5931\u8D25\uFF08\u4E0D\u4F1A\u9000\u56DE\u76F4\u8FDE\uFF09\u3002~/.ssh/config \u5BFC\u5165\u6C38\u4E0D\u81EA\u52A8\u5E26\u5165\u4EE3\u7406\u547D\u4EE4\u3002","field.maxSessions":"\u5E76\u53D1\u4F1A\u8BDD\u4E0A\u9650\uFF081~16\uFF09","hint.maxSessions":"\u8D85\u8FC7\u4E0A\u9650\u7684\u65B0\u6807\u7B7E\u4F1A\u88AB\u62D2\u7EDD\uFF1B\u4FDD\u5B58\u5373\u70ED\u751F\u6548","field.shell":"Shell \u8DEF\u5F84\uFF08\u9ED8\u8BA4 $SHELL\uFF09","field.shellWindows":"Shell \u8DEF\u5F84\uFF08\u9ED8\u8BA4 %COMSPEC%\uFF09","placeholder.shell":"\u7559\u7A7A\u4F7F\u7528 $SHELL","placeholder.shellWindows":"\u7559\u7A7A\u4F7F\u7528 %COMSPEC%\uFF08\u4E5F\u53EF\u586B powershell.exe / pwsh.exe \u5B8C\u6574\u8DEF\u5F84\uFF09","list.noShellCandidate":"\u6CA1\u6709\u5339\u914D\u7684\u5019\u9009 \u2014 \u76F4\u63A5\u8F93\u5165\u4EFB\u610F\u8DEF\u5F84\u5373\u53EF","hint.shellCandidatesWindows":"Windows \u5BBF\u4E3B\uFF1A\u5019\u9009\u6765\u81EA %COMSPEC% \u4E0E\u5DF2\u5B89\u88C5\u7684 PowerShell\uFF08Windows PowerShell 5.1 / PowerShell 7\uFF09\uFF0C\u4E5F\u53EF\u76F4\u63A5\u8F93\u5165\u4EFB\u610F\u8DEF\u5F84\uFF1Bcmd / PowerShell \u6CA1\u6709 POSIX \u7684\u547D\u4EE4\u8FB9\u754C\u94A9\u5B50\uFF0C\u6240\u4EE5\u8FD9\u4E24\u8005\u4E0D\u652F\u6301 shell \u96C6\u6210","hint.shellCandidates":"\u53EF\u4E0B\u62C9\u9009\u62E9\u672C\u673A\u5DF2\u5B89\u88C5 shell\uFF08$SHELL \u4F18\u5148\uFF09\uFF0C\u4E5F\u53EF\u76F4\u63A5\u8F93\u5165\u4EFB\u610F\u8DEF\u5F84\uFF1Bzsh / bash \u652F\u6301 shell \u96C6\u6210","hint.term":"TUI \u7A0B\u5E8F\u4F9D\u8D56\u6B64\u503C","field.cwd":"\u515C\u5E95\u5DE5\u4F5C\u76EE\u5F55\uFF08\u5BA2\u6237\u7AEF\u5F53\u524D\u4F1A\u8BDD cwd \u4F18\u5148\uFF09","placeholder.cwd":"\u7559\u7A7A\u4F7F\u7528\u5BBF\u4E3B\u8FDB\u7A0B\u542F\u52A8\u76EE\u5F55","field.grace":"\u65AD\u7EBF\u4FDD\u6D3B\uFF08\u79D2\uFF0C0 = \u7ACB\u5373\u7ED3\u675F\uFF09","hint.grace":"\u5237\u65B0\u9875\u9762/\u7F51\u7EDC\u6296\u52A8\u540E\u4F1A\u8BDD\u4FDD\u6D3B\u7B49\u5F85\u91CD\u8FDE\uFF0C\u8D85\u65F6\u540E\u7ED3\u675F\uFF1B\u4FDD\u5B58\u5373\u70ED\u751F\u6548","section.assist":"AI \u8F85\u52A9","check.assistEnabled":"\u5931\u8D25\u5373\u89E3\u91CA\uFF08\u547D\u4EE4\u975E\u96F6\u9000\u51FA\u65F6\u95EE\u6A21\u578B\u300C\u4E3A\u4EC0\u4E48 / \u4E0B\u4E00\u6B65\u300D\uFF09","hint.assistEnabled":"\u9ED8\u8BA4\u5173\u3002\u5F00\u542F\u540E\uFF0C\u547D\u4EE4\u4EE5\u975E\u96F6\u72B6\u6001\u7ED3\u675F\u65F6\u7EC8\u7AEF\u53F3\u4E0B\u89D2\u4F1A\u51FA\u73B0\u4E00\u679A\u5FBD\u6807\uFF1B\u70B9\u5B83\u624D\u628A\u90A3\u6761\u547D\u4EE4\u7684\u300C\u8F93\u51FA\u5C3E\u90E8\u300D\uFF08\u5265\u79BB\u989C\u8272\u4E0E\u8FDB\u5EA6\u6761\u3001\u6298\u6389\u91CD\u590D\u884C\u3001\u5BC6\u94A5/token \u5DF2\u906E\u76D6\uFF09\u8FDE\u540C\u5F53\u524D\u5C4F\u5E55\u53D1\u7ED9\u6A21\u578B\uFF0C\u4E0D\u53D1 scrollback\u3002\u6A21\u578B\u7ED9\u7684\u547D\u4EE4\u53EA\u4F1A\u300C\u586B\u5165\u300D\u547D\u4EE4\u884C\uFF0C\u6C38\u4E0D\u66FF\u4F60\u56DE\u8F66\u3002","field.assistRoute":"\u6A21\u578B\u8DEF\u7531\uFF08\u53EF\u9009\uFF09","hint.assistRoute":"\u7559\u7A7A\u8DDF\u968F\u5BBF\u4E3B\u9ED8\u8BA4\u6A21\u578B","option.followHostModel":"\u8DDF\u968F\u5BBF\u4E3B\u9ED8\u8BA4\u6A21\u578B","list.modelLoading":"\u6B63\u5728\u53D6\u5019\u9009\u2026","list.noModelCandidate":"\u5BBF\u4E3B\u6CA1\u6709\u53EF\u7528\u7684\u6A21\u578B","list.modelCatalogFailed":"\u62FF\u4E0D\u5230\u5019\u9009\uFF1A\u5BBF\u4E3B\u53EF\u80FD\u8FD8\u6CA1\u91CD\u542F\uFF0C\u6216\u6CA1\u6709\u63D0\u4F9B\u6A21\u578B\u76EE\u5F55\uFF08\u624B\u8F93\u8BF7\u6309 provider/model\uFF09","badge.assistFailed":"\u547D\u4EE4\u5931\u8D25\uFF08{code}\uFF09\xB7 \u89E3\u91CA\u4E00\u4E0B","panel.assistTitle":"\u8FD9\u6761\u547D\u4EE4\u4E3A\u4EC0\u4E48\u5931\u8D25","panel.assistCommand":"\u5EFA\u8BAE\u547D\u4EE4","status.assistThinking":"\u6B63\u5728\u95EE\u6A21\u578B\u2026","error.assistRequest":"\u89E3\u91CA\u5931\u8D25\uFF1A{message}","btn.assistFill":"\u586B\u5165\u547D\u4EE4\u884C","btn.assistCopy":"\u590D\u5236\u7B54\u6848","btn.assistCopyError":"\u590D\u5236\u62A5\u9519","btn.assistClose":"\u5173\u95ED","hint.assistFillNoEnter":"\u53EA\u5199\u8FDB\u547D\u4EE4\u884C\uFF0C\u4E0D\u4F1A\u66FF\u4F60\u56DE\u8F66","hint.assistNoCommand":"\u6A21\u578B\u6CA1\u7ED9\u51FA\u53EF\u76F4\u63A5\u586B\u7684\u547D\u4EE4 \u2014 \u7528\u300C\u590D\u5236\u300D\u81EA\u5DF1\u6311","section.ssh":"SSH \u8FDE\u63A5","btn.probeRowTitle":"\u8BD5\u8FDE\u8BE5\u6761\u76EE\uFF1ATCP \u2192 \u4E3B\u673A\u5BC6\u94A5 \u2192 \u8BA4\u8BC1\u9010\u6BB5\u8BCA\u65AD","msg.testing":"\u6D4B\u8BD5\u4E2D\u2026","btn.test":"\u6D4B\u8BD5","btn.edit":"\u7F16\u8F91","btn.delete":"\u5220\u9664","list.emptySshHosts":"\u6682\u65E0\u6761\u76EE \u2014 \u7EC8\u7AEF\u9762\u677F\u300C+\u300D\u2192 SSH \u8FDE\u63A5\u2026 \u52FE\u9009\u300C\u4FDD\u5B58\u5230\u8FDE\u63A5\u7C3F\u300D\u5373\u53EF\u6DFB\u52A0","btn.importSshConfig":"\u4ECE ~/.ssh/config \u5BFC\u5165","hint.importSshConfig":"\u540C\u540D\u8DF3\u8FC7\uFF1B\u968F\u300C\u4FDD\u5B58\u300D\u5199\u5165\u914D\u7F6E","hint.sshBook":"\u968F\u300C\u4FDD\u5B58\u300D\u4E00\u5E76\u5199\u5165\u914D\u7F6E\uFF1B\u5BC6\u7801/\u53E3\u4EE4\u652F\u6301 env:VAR \u5F15\u7528\uFF0C\u907F\u514D\u660E\u6587\u5165\u5E93","check.tunnelEnabled":"\u542F\u7528","list.emptyTunnels":"\u6682\u65E0\u96A7\u9053 \u2014 \u628A\u8FDC\u7A0B\u6570\u636E\u5E93/\u5185\u90E8\u670D\u52A1\u6620\u5C04\u5230\u672C\u5730\u7AEF\u53E3","field.direction":"\u8F6C\u53D1\u65B9\u5411","option.localForwardTitle":"\u672C\u5730\u8F6C\u53D1 -L\uFF1A\u672C\u673A\u76D1\u542C\uFF0C\u8FDE\u5230 SSH \u670D\u52A1\u5668\u4FA7\u7684\u76EE\u6807","option.localForward":"\u672C\u5730 -L","option.remoteForwardTitle":"\u8FDC\u7A0B\u8F6C\u53D1 -R\uFF1ASSH \u670D\u52A1\u5668\u4FA7\u76D1\u542C\uFF0C\u62E8\u56DE\u672C\u673A\u670D\u52A1","option.remoteForward":"\u8FDC\u7A0B -R","option.selectBook":"\u9009\u62E9\u8FDE\u63A5\u7C3F\u6761\u76EE","hint.tunnelViaBook":"\u7ECF {book} \u8FDE\u63A5 \u2014 \u96A7\u9053\u7684\u4E3B\u673A\u4E0E\u8BA4\u8BC1\u53D6\u81EA\u8BE5\u8FDE\u63A5\u7C3F\u6761\u76EE","hint.tunnelBookEmpty":"\u9009\u62E9\u8FD9\u6761\u96A7\u9053\u8981\u8D70\u54EA\u53F0 SSH \u8FDE\u63A5\uFF08\u4E3B\u673A\u4E0E\u8BA4\u8BC1\u53D6\u81EA\u8FDE\u63A5\u7C3F\uFF09","hint.localListenFixed":"\u672C\u673A\u76D1\u542C\u5730\u5740\u56FA\u5B9A 127.0.0.1\uFF08\u4E0D\u66B4\u9732\u5230\u5C40\u57DF\u7F51\uFF09","placeholder.localPort":"\u672C\u673A\u7AEF\u53E3","field.localListenPort":"\u672C\u673A\u76D1\u542C\u7AEF\u53E3","hint.flowLocalToRemote":"\u6570\u636E\u6D41\u5411\uFF1A\u672C\u673A \u2192 SSH \u670D\u52A1\u5668\u4FA7","placeholder.remoteHost":"\u670D\u52A1\u5668\u4FA7\u4E3B\u673A","hint.remoteHostTitle":"\u76EE\u6807\u4E3B\u673A\u540D\u6216 IP\uFF08\u7531 SSH \u670D\u52A1\u5668\u4FA7\u8BBF\u95EE\uFF1B127.0.0.1 = \u670D\u52A1\u5668\u81EA\u8EAB\uFF09","field.remoteHost":"\u670D\u52A1\u5668\u4FA7\u76EE\u6807\u4E3B\u673A","placeholder.port":"\u7AEF\u53E3","field.remotePort":"\u670D\u52A1\u5668\u4FA7\u76EE\u6807\u7AEF\u53E3","placeholder.remoteListenHost":"\u670D\u52A1\u5668\u4FA7\u76D1\u542C\u5730\u5740","hint.remoteListenHost":"\u670D\u52A1\u5668\u4FA7\u76D1\u542C\u5730\u5740\uFF08\u7F3A\u7701 127.0.0.1\uFF1B\u7559\u7A7A\u5373\u53EA\u8BA9\u670D\u52A1\u5668\u81EA\u5DF1\u8BBF\u95EE\uFF09","field.remoteListenHost":"\u670D\u52A1\u5668\u4FA7\u76D1\u542C\u5730\u5740","placeholder.listenPort":"\u76D1\u542C\u7AEF\u53E3","field.remoteListenPort":"\u670D\u52A1\u5668\u4FA7\u76D1\u542C\u7AEF\u53E3","hint.flowRemoteToLocal":"\u6570\u636E\u6D41\u5411\uFF1A\u672C\u673A \u2190 SSH \u670D\u52A1\u5668\u4FA7","hint.localDialFixed":"\u672C\u673A\u62E8\u53F7\u5730\u5740\u56FA\u5B9A 127.0.0.1","placeholder.localTargetPort":"\u672C\u673A\u670D\u52A1\u7AEF\u53E3","field.localTargetPort":"\u672C\u673A\u76EE\u6807\u7AEF\u53E3","hint.tunnelLocalSummary":"\u5DE6\uFF1A\u672C\u673A\u76D1\u542C\uFF08\u56FA\u5B9A 127.0.0.1\uFF09\u2192 \u53F3\uFF1A\u7531 SSH \u670D\u52A1\u5668\u4FA7\u8BBF\u95EE\u7684\u76EE\u6807","hint.tunnelRemoteSummary":"\u5DE6\uFF1ASSH \u670D\u52A1\u5668\u4FA7\u76D1\u542C \u2192 \u53F3\uFF1A\u672C\u673A\u88AB\u8BBF\u95EE\u7684\u670D\u52A1\uFF08\u56FA\u5B9A 127.0.0.1\uFF09","btn.addTunnel":"\u6DFB\u52A0\u96A7\u9053","hint.tunnelAdd":"\u6DFB\u52A0\u540E\u7ACB\u5373\u751F\u6548\uFF1B\u65AD\u7EBF\u81EA\u52A8\u91CD\u8FDE\uFF1B\u672C\u5730\u7AEF\u53E3\u5EFA\u8BAE 1024 \u4EE5\u4E0A\uFF1B\u8FDC\u7A0B\u4E3B\u673A\u7531 SSH \u670D\u52A1\u5668\u4FA7\u8BBF\u95EE\uFF08127.0.0.1 = \u670D\u52A1\u5668\u81EA\u8EAB\uFF09","hint.tunnelEditing":"\u6B63\u5728\u7F16\u8F91\u300C{name}\u300D\u2014\u2014\u6539\u7AEF\u53E3/\u6761\u76EE\u4F1A\u6309\u89C4\u5219\u751F\u6210\u65B0\u540D\u5B57\uFF1B\u4FDD\u5B58\u540E\u7ACB\u5373\u751F\u6548","panel.hostKeys":"SSH \u4E3B\u673A\u5BC6\u94A5\u8BB0\u5F55\uFF08TOFU\uFF09","btn.importKnownHosts":"\u4ECE known_hosts \u5BFC\u5165","list.emptyHostKeys":"\u6682\u65E0\u8BB0\u5F55 \u2014 \u9996\u6B21 SSH \u8FDE\u63A5\u6210\u529F\u540E\u81EA\u52A8\u8BB0\u5F55\u4E3B\u673A\u6307\u7EB9","hint.hostKeys":"\u4E00\u673A\u591A\u628A\u94A5\u5319\uFF08\u5982 rsa + ed25519\uFF09\u5404\u8BB0\u4E00\u6761\u6307\u7EB9\uFF0C\u4EFB\u4E00\u5339\u914D\u5373\u653E\u884C\uFF1B\u6307\u7EB9\u53D8\u66F4\u65F6\u8FDE\u63A5\u4F1A\u88AB\u62D2\u7EDD\uFF08\u9632\u4E2D\u95F4\u4EBA\uFF09\uFF0C\u786E\u8BA4\u5B89\u5168\u540E\u5220\u9664\u5BF9\u5E94\u8BB0\u5F55\u5373\u53EF\u91CD\u8FDE","msg.saving":"\u4FDD\u5B58\u4E2D\u2026","btn.save":"\u4FDD\u5B58","list.none":"\u65E0","meta.mem":"\u5185\u5B58","meta.disk":"\u78C1\u76D8","meta.cores":"\u6838\u5FC3","meta.uptime":"\u5728\u7EBF","meta.temp":"CPU\u6E29\u5EA6","meta.net":"\u7F51\u7EDC","error.tunnelNoBook":"\u8BF7\u5148\u5728\u8FDE\u63A5\u7C3F\u91CC\u6DFB\u52A0 SSH \u6761\u76EE","error.tunnelRemotePortRequired":"\u8FDC\u7A0B\u76D1\u542C\u7AEF\u53E3\u4E0E\u672C\u5730\u76EE\u6807\u7AEF\u53E3\u5FC5\u586B\uFF081~65535\uFF09","error.tunnelLocalRequired":"\u672C\u5730\u7AEF\u53E3\u3001\u8FDC\u7A0B\u4E3B\u673A\u3001\u8FDC\u7A0B\u7AEF\u53E3\u5FC5\u586B","error.tunnelMissing":"\u96A7\u9053\u300C{name}\u300D\u5DF2\u4E0D\u5B58\u5728\uFF08\u53EF\u80FD\u88AB\u53E6\u4E00\u4E2A\u7A97\u53E3\u5220\u9664\uFF09","error.tunnelClash":"\u5DF2\u5B58\u5728\u540C\u540D\u96A7\u9053\u300C{name}\u300D\u2014\u2014\u8BF7\u5148\u5904\u7406\u90A3\u6761\u540C\u540D\u7684\u3002","msg.renaming":"\u91CD\u547D\u540D {name}\u2026","msg.deleting":"\u5220\u9664 {name}\u2026","msg.downloading":"\u4E0B\u8F7D {name}\u2026","msg.uploadingName":"\u4E0A\u4F20 {name}","error.invalidTaskState":"\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u975E\u6CD5\u7684\u4EFB\u52A1\u72B6\u6001","hint.rememberCredentialApply":"\u52FE\u9009\u540E\uFF0C\u70B9\u300C\u5E94\u7528\u300D\u65F6\u628A\u5BC6\u7801\u5199\u8FDB\u5B98\u65B9\u51ED\u636E\u5B58\u50A8\uFF0C\u5B57\u6BB5\u91CC\u53EA\u7559 env: \u5F15\u7528\uFF08\u503C\u5728 ~/.dsh/.credentials.yaml\uFF0C\u4E0D\u8FDB\u73AF\u5883\u3001\u4E0D\u56DE\u4F20\u6D4F\u89C8\u5668\uFF1B\u6321\u4E0D\u4F4F\u540C\u7528\u6237\u8FDB\u7A0B\u4E0E agent\uFF09\u3002\u4E0D\u52FE\u9009\u5219\u6309\u73B0\u72B6\u660E\u6587\u5199\u8FDB\u8BBE\u7F6E\u6587\u4EF6\u3002\u80FD\u7528\u5BC6\u94A5 / agent \u5C31\u522B\u5B58\u5BC6\u7801\u3002","hint.noCredRefPasswordApply":"\u8FD8\u6CA1\u6709\u522B\u7684\u8FDE\u63A5\u7528\u8FC7\u51ED\u636E\u5F15\u7528 \u2014 \u52FE\u4E0A\u9762\u7684\u300C\u5E94\u7528\u65F6\u5B58\u5165\u51ED\u636E\u5B58\u50A8\u300D\u65B0\u5EFA\u4E00\u4E2A\uFF0C\u6216\u76F4\u63A5\u5728\u5BC6\u7801\u6846\u624B\u8F93 env:NAME","hint.bookNameConflict":"\u540C\u540D\u51B2\u7A81\u4F1A\u88AB\u62D2\u7EDD","btn.apply":"\u5E94\u7528"},Op={"error.credServiceMissing":"The host does not provide the credential service (remote.credentials)","error.credServiceIncomplete":"The credential service is incomplete","error.credStoreUnavailable":"The host does not provide the credential service (remote.credentials); cannot store","error.credStoreFailed":"Failed to store the credential: {error}","error.credClearUnavailable":"The host does not provide the credential service (remote.credentials); cannot clear","error.credClearFailed":"Failed to clear: {error}","error.credRefNeedsHost":"Fill in host and username first \u2014 the reference name is derived from them","btn.reopen":"Reopen","btn.reopenTitle":"Reopen the session with the original connection settings","btn.sftpTitle":"Open the SFTP file browser for this connection","btn.tunnels":"Tunnels {count}","btn.tunnelsTitle":"View the port-forwarding tunnels of this connection","btn.more":"More","btn.moreTitle":"More actions (port forwarding\u2026)","btn.reopenSession":"Reopen session","status.exited":"Session exited","status.ended":"Session ended","btn.clickReopen":"Click to reopen","btn.clickRerun":"Click to run again","msg.passwordNotStored":"For security, plaintext passwords/passphrases are not kept in browser storage, so this connection needs them again: re-enter them when reopening the tab, or switch the credential to an env: reference in the settings card (the value lives in the host credential store).","error.terminalNeedsCommand":"ttyTerminal requires a command","error.terminalCommandSingleLine":"command must be a single line","error.terminalNeedsHost":"ttyTerminal.mount requires an HTMLElement as the mount point","error.panelNotReady":"ttyPanel.mountPane: the terminal panel is not ready","panel.dragHeight":"Drag to resize height","panel.dragWidth":"Drag to resize width","btn.closePane":"Close the side pane","btn.expandPane":"Expand the side pane","btn.collapsePane":"Collapse the side pane","panel.tabLabel":"Terminal {n}","btn.close":"Close","btn.closeTabAria":"Close tab: {label}","btn.newTab":"New (local / SSH)","btn.tabList":"Tab list","btn.tabListTitle":"Tab list ({n})","list.tabsAllVisible":"No tabs are out of view","meta.tunnelRemote":"remote:{host}:{port} \u2192 local:{local}","meta.tunnelLocal":"local:{local} \u2192 {host}:{port}","status.tmuxPersistedTitle":"Hosted by tmux \u2014 the session is reattached by name after a disconnect or host restart","status.notPersisted":"Not persisted","status.tmuxUnavailableTitle":"A persistent session was requested but tmux is unavailable \u2014 this is a plain session","status.connected":"Connected","status.connecting":"Connecting","status.errored":"Connection error","panel.tunnels":"Port forwarding","hint.tunnelsSettings":"Configure in Settings \u2192 Plugins \u2192 Terminal panel","panel.tunnelsFor":"Port forwarding \u2014 {name}","list.loading":"Loading\u2026","hint.tunnelsCard":"Add, remove, enable, or disable tunnels in the port-forwarding section of Settings \u2192 Plugins \u2192 Terminal panel","list.noActiveTunnels":"No enabled tunnels for this connection","status.fatalSuffix":" (no retry; fix the config)","msg.maxSessions":"Session limit reached ({live} total / max {max}: {own} in this window{others}) \u2014 close unused windows or tabs, or raise \u201CConcurrent session limit\u201D in the settings card","msg.maxSessionsOthers":" + {count} in other windows","error.probeHttp":"Connection test failed (HTTP {status})","msg.probing":"Testing the connection\u2026","meta.reachable":"reachable","meta.unreachable":"unreachable","meta.probeBanner":"banner ok","meta.hostKeyMatched":"Host key matched","meta.hostKeyRecorded":"Host key recorded (TOFU)","meta.hostKeyMismatch":"Host key mismatch!","meta.authOkMs":"Authenticated ({ms}ms)","meta.authOk":"Authenticated","meta.probeOk":"\u2705 Connected: {detail}","error.unknown":"Unknown error","btn.maxSessionsTitle":"Session limit reached \u2014 click to see what to do","option.localTerminal":"Local terminal","hint.tmuxHosted":"Hosted by tmux \xB7 recoverable after a host restart","hint.openInSessionCwd":"Open in the current session working directory","panel.sshBook":"SSH host book","btn.sftpFileBrowse":"SFTP file browser","btn.editConnection":"Edit connection","list.emptySshBook":"(empty \u2014 save one in the settings card or via \u201CSSH connection\u2026\u201D)","option.sshConnect":"SSH connection\u2026","hint.sshConnect":"Fill in host, user, and authentication manually","panel.editConnection":"Edit connection \xB7 {name}","panel.sshConnect":"SSH connection","section.jump":"Jump host","field.jumpHost":"Jump host ([user@]host[:port]; empty = direct)","placeholder.jumpHost":"e.g. bastion.corp:2222","check.jumpOwnCred":"Use separate credentials for the jump host","field.jumpUsername":"Jump host user (empty = same as the target)","field.jumpAuth":"Jump host auth (empty = same as the target)","hint.jumpInherit":"Empty credentials reuse the target host\u2019s auth method and keys. When the jump host itself is unreachable the error names it (it will not masquerade as a target timeout).","meta.jumpStage":"Jump host {label}","meta.viaJump":"\u21E2 via {label}","meta.viaProxy":"\u21E2 via proxy command","section.proxyCommand":"Proxy command","field.proxyCommand":"Proxy command (ProxyCommand; empty = unused)","placeholder.proxyCommand":"e.g. ssh -W %h:%p bastion","hint.proxyCommand":"A command run on this machine whose stdin/stdout become the SSH transport to the target (the same idea as OpenSSH\u2019s ProxyCommand). Supports %h host, %p port, %r user, %n host and %% for a literal %; anything else is left as written. If a jump host is set too, the jump host wins (OpenSSH semantics). It needs the switch below, and importing ~/.ssh/config never fills it in.","hint.proxyCommandDisabled":"\u26A0 \u201CAllow ProxyCommand\u201D is off right now: this command will not run and the connection fails explicitly (it does not fall back to a direct connection). Turn it on in Plugin settings \u2192 Terminal panel.","hint.proxyCommandNotGranted":"\u26A0 Not granted by the host: clicking this switch starts a grant in place (the panel shows one command to run in a terminal on the host \u2014 no restart), or use the strictest route \u2014 export DSH_TTY_ALLOW_PROXY_COMMAND=1 in the environment that launched dsh and restart the host (setting it after launch does not count). The reason: cross-site pages and in-page scripts can both send loopback requests, so if the settings UI could raise it out of thin air this gate would be pointless. Turning it off always works.","badge.notEffective":"Not effective: not granted by the host","elev.title":"Grant in place (no restart)","elev.lockedWhy":"Any local process can send loopback requests, so \u201Cturn on a dangerous capability\u201D cannot be decided by this page alone \u2014 it has to be confirmed on the host\u2019s filesystem once.","elev.step":"Run the command below in a terminal on the host and the switch unlocks by itself:","elev.copy":"Copy command","elev.copied":"Copied","elev.copyManual":"The clipboard is unavailable here \u2014 select the command above and copy it manually.","elev.expiresIn":"expires in {sec}s","elev.expired":"This confirmation has expired \u2014 generate a new one.","elev.waiting":"Waiting for confirmation\u2026 once you run the command this turns into \u201Cgranted\u201D automatically.","elev.regenerate":"Generate a new one","elev.loading":"Generating the confirmation command\u2026","elev.granted":"Granted and now in effect.","elev.grantedNeedSave":"Granted. Press \u201CSave\u201D to apply.","elev.grantedAt":"Granted \xB7 {time}","elev.revoke":"Revoke host grant","elev.revoked":"Host grant revoked (the config switch is left untouched; granting again takes effect immediately).","elev.viaEnv":"Granted by a launch environment variable; to revoke, remove it from the launch environment and restart the host.","elev.close":"Collapse","elev.disableFirst":"Turn this config switch off first","elev.otherWay":"The other way (strongest, needs a host restart)","elev.envHow":"In the environment that launched dsh: export {env}=1, then restart the host. Setting it after launch \u2014 or writing it into some other config file \u2014 does not count as a grant; that is exactly what this gate guards against.","elev.error":"In-place grant failed: ","meta.probeProxy":"Proxy command","meta.probeProxyOff":"Proxy command (disabled)","meta.probeTcpSkipped":"Direct TCP check skipped (using the proxy command)","section.connection":"Connection","field.host":"Host","placeholder.host":"example.com or IP","field.port":"Port","field.username":"Username","section.auth":"Authentication","field.authMethod":"Auth method","option.authInherit":"(same as the target)","option.authAgent":"agent \u2014 use the local ssh-agent","option.authKey":"key \u2014 private key file","option.authPassword":"password \u2014 password","field.keyPath":"Private key path","field.hostKeyAlias":"Host key alias","field.passphrase":"Key passphrase (optional)","field.password":"Password","placeholder.credRef":"Or: pick a reference name from the credential store","hint.credRefCandidates":"Candidates = reference names already in the credential store + those in use by the local host book","list.credOverwrite":"{name} (click again to overwrite)","list.moreMatches":"{count} more \u2014 keep typing to filter","list.noCredRef":"No matching reference","check.rememberCredential":"Store in the credential store on save","hint.rememberCredential":"When checked, \u201CSave changes\u201D or \u201CConnect (and save)\u201D writes the password into the official credential store and leaves only an env: reference in the field (the value lives in ~/.dsh/.credentials.yaml; it is not put into the environment and is not sent back to the browser; it does not protect against same-user processes or the agent). Unchecked keeps today's plaintext write into the settings file. If a key or the agent works, do not store a password.","btn.clearCredential":"Clear stored credential","error.credPlainUnavailable":"The host does not provide the credential service (remote.credentials); plaintext save only","error.credPlainIncomplete":"The credential service is incomplete; plaintext save only","status.credUnreported":"Reference {ref}: the host reported no status","error.credStatusFailed":"Failed to read the credential status: {error}","status.credStored":"Stored{source} \xB7 {ref}","meta.credSource":" (source: {source})","status.credUnknown":"Reference {ref}: the store does not have this value yet","hint.noCredRefPassphrase":"No other connection uses a credential reference yet \u2014 you can type env:NAME straight into the passphrase box","hint.noCredRefPassword":"No other connection uses a credential reference yet \u2014 check \u201CStore in the credential store on save\u201D above to create one, or type env:NAME straight into the password box","section.options":"Options","check.agentForward":"agent forwarding (the remote side can use local ssh-agent keys, e.g. remote git clone)","hint.hostKeyAlias":"Empty = pin the fingerprint by host address. When one host is reached through different addresses (behind a bastion / via port forwarding), give them the same alias so they share one host-key record instead of reporting a fingerprint change on every switch; it only decides where the fingerprint is stored, never the connection address","placeholder.hostKeyAlias":"Empty = by host address","check.persist":"Persistent session (hosted by tmux, survives a disconnect/restart; tmux must be installed on the remote)","check.saveToBook":"Save to the host book (overwrite the same name)","field.bookName":"Host book name","placeholder.bookName":"Leave empty to use the host name","error.hostUserRequired":"Host and username are required","error.keyPathRequired":"auth=key requires a private key path","error.passwordRequired":"auth=password requires a password","btn.cancel":"Cancel","btn.connect":"Connect","btn.fileBrowse":"File browser","btn.browseTitle":"Open the SFTP file browser with the values currently filled in, without touching a terminal","btn.probe":"Test","btn.probeTitle":"Diagnose the connection with the values currently filled in (TCP \u2192 host key \u2192 authentication); no session is created and no host fingerprint is recorded","error.saveCredFailed":"Save failed: {error}","btn.saveEdit":"Save changes","error.saveBookFailed":"Failed to save the host book: {error}","error.bookNameTaken":"The host book already has an entry named: {name}","panel.sftpDual":"SFTP dual pane \xB7 {label}","status.failed":"Failed","status.done":"Done","placeholder.localPath":"Local path (Enter to go)","placeholder.remotePath":"Remote path (Enter to go)","btn.refresh":"Refresh","btn.mkdir":"New folder","btn.hiddenFiles":"Hidden files","btn.hiddenFilesTitle":"Show / hide dot-files (.env, .gitignore, \u2026)","error.dirNotReady":"The directory is not resolved yet","meta.dir":"folder","btn.transferTo":"Transfer to {target}: {path}","meta.local":"local","meta.remote":"remote","error.transferDirsNotReady":"Both directories are not resolved yet; wait for the lists to load before transferring","msg.transferring":"Transferring {name}\u2026","error.transferFailed":"Transfer failed","error.noTaskId":"The server returned no task id","msg.transferCanceled":"Transfer canceled: {name}","msg.transferred":"Transferred {name}","btn.download":"Download {name}","btn.rename":"Rename {name}","placeholder.newName":"New name","btn.deleteEntry":"Delete {name}","btn.deleteEntryDir":"Delete {name} (with contents)","msg.deleted":"Deleted {name}","list.parentDir":".. (parent folder)","list.emptyDir":"(empty folder)","list.hiddenOnly":"(only hidden files here \u2014 click \u201CHidden files\u201D on the pane header to show them)","error.dropOnLocalPane":"Dropping onto the local pane has no action: to send local files to the other side, drop them on the right-hand \u201CRemote\u201D pane","list.truncated":"\u2026{rest} more not rendered ({total} total) \u2014 use the path box above to jump to a subfolder","list.itemCount":"{count} items","placeholder.newDirName":"New folder name (relative to the current folder)","msg.creatingDir":"Creating folder {name}\u2026","btn.ok":"OK","btn.confirm":"Confirm?","btn.cancelTransfer":"Cancel transfer","msg.downloadCanceled":"Download canceled: {name}","msg.downloadResuming":"Connection dropped \u2014 resuming {name} from {offset}\u2026","error.downloadFailed":"Download failed","msg.downloaded":"Downloaded {name} ({size})","error.downloadTooBig":"The file exceeds the download limit ({size}); use dual-pane \u21E6 direct transfer or scp/rsync in the terminal","msg.canceled":"Canceled","btn.upload":"Upload","btn.uploadTitle":"Pick files to upload, or drag files/folders straight into the list","msg.uploading":"Uploading\u2026","msg.uploadDone":"Upload finished","error.uploadFailed":"Upload failed","error.networkError":"Network error","error.uploadCountExceeded":"Too many files (limit {max}): {count} this time \u2014 upload in batches","status.overLimit":"Over the limit","error.uploadTooBig":"The file exceeds the upload limit ({size}): {name} \u2014 use dual-pane \u21E8 direct transfer or scp/rsync in the terminal","error.uploadTotalTooBig":"The total size exceeds the upload limit: upload in batches (or use dual-pane \u21E8 direct transfer)","msg.uploadCanceled":"Upload canceled ({done}/{total} done)","status.allDone":"All done","msg.uploadDoneCount":"Uploaded {count} files","error.connectFailed":"Connection failed: {error}","status.connectingEllipsis":"Connecting\u2026","status.connectedPid":"Connected pid={pid}","status.connectedSsh":"SSH {target}connected","status.exitedWith":"Exited {detail}","status.error":"Error: {message}","status.retryHint":"{message} \xB7 click to retry","btn.clickRetry":"Click to retry","status.disconnectedReconnecting":"Disconnected \u2014 reconnecting","status.disconnected":"Disconnected","status.reconnecting":"Reconnecting\u2026","error.copyFailed":"Copy failed: this environment does not allow clipboard access (over http, use localhost or the terminal's own shortcuts)","error.pasteFailed":"The browser does not allow pages to read the clipboard (common over http): paste with Ctrl+V / Cmd+V inside the terminal","status.initializing":"Initializing\u2026","placeholder.search":"Search (Enter next, Shift+Enter previous)","btn.searchTitle":"Search (Ctrl+F)","btn.clearTitle":"Clear","btn.copyTitle":"Copy selection","btn.pasteTitle":"Paste","btn.minimizeTitle":"Minimize (sessions keep running; the status moves into the sidebar entry)","btn.closePanelTitle":"Close the panel (ends sessions; tabs are kept and the list comes back on reopen)","btn.restoreDock":"Click to restore the terminal window","panel.title":"Terminal","status.minimized":"Terminal minimized \u2014 click to restore","error.configLoadFailed":"Failed to load the config","error.saveTunnelFailed":"Failed to save the tunnel","error.tunnelNameTaken":"A tunnel named \u201C{name}\u201D already exists \u2014 each \u201Chost book entry + direction + port\u201D combination can appear once. Change the port to get a new name, or delete the old one first.","msg.tunnelApplied":"Tunnel \u201C{name}\u201D is active","msg.tunnelUpdated":"Tunnel \u201C{name}\u201D updated","error.nameHostUserRequired":"Name, host, and username are required","msg.hostEdited":"Entry \u201C{name}\u201D updated \u2014 written to the config on \u201CSave\u201D","error.probeFailed":"\u274C Connection failed: {error}","error.hostKeyDeleteFailed":"Failed to delete the host key record","msg.hostKeyDeleted":"Host key record deleted (the fingerprint is recorded again on the next connection)","error.sshConfigReadFailed":"Failed to read ~/.ssh/config","msg.proxySkipped":"{count} entries use a jump host that could not be resolved (missing alias, or the alias itself needs a jump host) and were not imported: {names}","msg.proxyCommandSkipped":"{count} entries only set a proxy command (ProxyCommand) and were not imported: {names} \u2014 a proxy command is local command execution, so importing never fills it in; add it by hand on the connection-book entry and turn on \u201CAllow ProxyCommand\u201D","msg.skippedNotConcrete":"{count} entries are not a concrete host (wildcard / no User)","list.separator":", ","meta.etc":" etc.","msg.importOverflow":"{count} entries beyond the import limit were not imported","list.separatorFull":"; ","msg.noNewEntries":"No new entries ({count} skipped as duplicates)","msg.noImportableHosts":"~/.ssh/config has no concrete hosts to import","msg.importedHosts":"Imported {added} (skipped {skipped} duplicates); written to the config on \u201CSave\u201D","error.knownHostsReadFailed":"Failed to read ~/.ssh/known_hosts","msg.noNewFingerprints":"No new fingerprints ({count} already exist)","msg.noImportableKnownHosts":"known_hosts has no concrete hosts to import","error.saveHostKeysFailed":"Failed to save hostKeys","msg.importedFingerprints":"Imported fingerprints for {added} hosts (skipped {skipped} that already existed)","hint.knownHostsTruncated":"; note: known_hosts has more than 500 hosts \u2014 only the first 500 were imported","error.saveFailed":"Save failed","msg.saved":"Saved and applied live","check.rememberCredentialApply":"Store in the credential store on apply","hint.appliedOnSave":"Written to the config with the card's \u201CSave\u201D","card.name":"Terminal panel","card.desc":"xterm terminal panel: multiple tabs, automatic reconnect after a drop, cwd follows the session, SSH host book with host-key pinning, tmux session persistence.","card.descFull":"xterm terminal panel: multiple tabs, automatic reconnect after a drop, cwd follows the session, SSH host book with host-key pinning, tmux session persistence; shell / TERM / concurrency limits apply live on save.","list.loadingConfig":"Loading the config\u2026","section.basic":"Basics","check.enabled":"Enable the plugin (applies live on save: tools and the panel entry are withdrawn immediately, sessions move to keepalive)","check.announce":"Announce the terminal panel capabilities to the agent","check.shellIntegration":"Shell integration (OSC 133/7 injection)","check.shellIntegrationWindows":"Shell integration (OSC 133/7 injection; tty_capture{last} and cwd following depend on it)","hint.shellIntegrationWindows":"Not applicable on Windows hosts: injection relies on the POSIX `-c` wrapper and rc stubs, which do not hold for cmd / PowerShell (cmd ignores `-c` and exits, PowerShell reports that export does not exist). So cwd following and tty_capture{last} are unavailable for \u201Clocal\u201D tabs; remote Linux / macOS hosts are unaffected.","section.sftp":"SFTP file transfer","field.sftpStyle":"SFTP file browser style","option.sftpDialog":"Single pane \u2014 remote directory + upload/download/drag","option.sftpDual":"Dual pane \u2014 local on the left, remote on the right, direct transfer on selection","hint.sftpDual":"Dual pane copies files between local and remote (recursive, overwriting same names); takes effect after reopening SFTP","field.sftpLimits":"SFTP transfer limits (0 = unlimited)","field.downloadLimit":"Download limit (MB)","field.uploadLimit":"Upload limit (MB)","field.uploadCountLimit":"Batch file count limit","hint.sftpLimits":"Browser-side guard: a single file over the limit aborts the download/upload (for large files use dual-pane \u21E8/\u21E6 direct transfer or scp/rsync in the terminal; they do not consume browser memory); the file count limit applies to one batch/drag upload; applies live on save","section.session":"Sessions","field.persistence":"Session persistence (tmux)","option.persistOff":"Off \u2014 sessions end with the panel/host (default)","option.persistTmux":"tmux \u2014 new terminal/SSH tabs are persistent by default","hint.persistence":"When on, all new tabs (local / SSH host book / SSH connection dialog) are hosted by tmux by default and survive a host restart; tmux must be installed locally/remotely; the SSH dialog can opt out per connection; existing tabs are unaffected","hint.persistenceWindows":"; tmux is unavailable on Windows hosts, so local tabs still open but are not hosted","check.endOnPageClose":"End persistent sessions when the page closes (no keepalive)","check.statsEnabled":"Server stats bar (CPU / memory / disk / uptime / TCP / network; items that cannot be sampled show \u201CN/A\u201D)","hint.statsEnabled":"Off by default: persistent sessions survive closing the whole page (recoverable after the keepalive window); when on, they end together with the tmux session once the page disconnects and the keepalive window expires \u2014 note that refreshing the page within the keepalive window is unaffected","check.allowProxyCommand":"Allow ProxyCommand (runs a command on this machine; off by default)","hint.allowProxyCommand":"When on, a proxy command set on a connection-book entry runs on this machine, and its stdin/stdout become the SSH transport to the target (the same idea as OpenSSH\u2019s ProxyCommand). This is the only switch in this plugin that turns a settings field into local command execution, so it is off by default: while off, a connection carrying a proxy command fails explicitly (it does not fall back to a direct connection). Importing ~/.ssh/config never fills one in.","field.maxSessions":"Concurrent session limit (1\u201316)","hint.maxSessions":"New tabs beyond the limit are rejected; applies live on save","field.shell":"Shell path (defaults to $SHELL)","field.shellWindows":"Shell path (defaults to %COMSPEC%)","placeholder.shell":"Leave empty to use $SHELL","placeholder.shellWindows":"Leave empty to use %COMSPEC% (or enter the full path to powershell.exe / pwsh.exe)","list.noShellCandidate":"No matching candidate \u2014 just type any path","hint.shellCandidatesWindows":"Windows host: candidates come from %COMSPEC% and the installed PowerShell (Windows PowerShell 5.1 / PowerShell 7), and you can type any path; cmd / PowerShell have no POSIX command-boundary hooks, so shell integration is unsupported for them","hint.shellCandidates":"Pick an installed shell from the list ($SHELL first) or type any path; zsh / bash support shell integration","hint.term":"TUI programs depend on this value","field.cwd":"Fallback working directory (the client's current session cwd wins)","placeholder.cwd":"Leave empty to use the host process start directory","field.grace":"Disconnect keepalive (seconds, 0 = end immediately)","hint.grace":"Sessions are kept alive for reconnect after a page refresh or network hiccup and end on timeout; applies live on save","section.assist":"AI assist","check.assistEnabled":'Explain failures (ask the model "why / what next" when a command exits non-zero)',"hint.assistEnabled":"Off by default. When on, a chip appears in the corner of the terminal after a command exits non-zero; clicking it sends that command's output tail (colors and progress bars stripped, repeated lines collapsed, keys/tokens masked) together with the current screen to the model \u2014 never the scrollback. A suggested command is only ever typed into the prompt line, never submitted for you.","field.assistRoute":"Model route (optional)","hint.assistRoute":"Empty follows the host default model","option.followHostModel":"Follow the host default model","list.modelLoading":"Loading candidates\u2026","list.noModelCandidate":"The host advertises no models","list.modelCatalogFailed":"Candidates unavailable \u2014 the host may not have restarted, or serves no model catalog (type provider/model to enter one manually)","badge.assistFailed":"Command failed ({code}) \xB7 explain","panel.assistTitle":"Why this command failed","panel.assistCommand":"Suggested command","status.assistThinking":"Asking the model\u2026","error.assistRequest":"Explanation failed: {message}","btn.assistFill":"Insert command","btn.assistCopy":"Copy answer","btn.assistCopyError":"Copy error","btn.assistClose":"Close","hint.assistFillNoEnter":"Types it into the prompt line; never submits","hint.assistNoCommand":"The model gave no directly-insertable command \u2014 use Copy and pick one yourself","section.ssh":"SSH connections","btn.probeRowTitle":"Test this entry: per-stage diagnosis of TCP \u2192 host key \u2192 authentication","msg.testing":"Testing\u2026","btn.test":"Test","btn.edit":"Edit","btn.delete":"Delete","list.emptySshHosts":"No entries \u2014 add one via the terminal panel's \u201C+\u201D \u2192 SSH connection\u2026 and check \u201CSave to the host book\u201D","btn.importSshConfig":"Import from ~/.ssh/config","hint.importSshConfig":"Same names are skipped; written to the config on \u201CSave\u201D","hint.sshBook":"Written to the config together with \u201CSave\u201D; passwords/passphrases support env:VAR references to avoid plaintext storage","check.tunnelEnabled":"Enable","list.emptyTunnels":"No tunnels \u2014 map a remote database or internal service to a local port","field.direction":"Forwarding direction","option.localForwardTitle":"Local forward -L: listen locally and connect to a target on the SSH server side","option.localForward":"Local -L","option.remoteForwardTitle":"Remote forward -R: listen on the SSH server side and dial back to a local service","option.remoteForward":"Remote -R","option.selectBook":"Pick a host book entry","hint.tunnelViaBook":"Connects via {book} \u2014 the tunnel's host and credentials come from that host book entry","hint.tunnelBookEmpty":"Pick which SSH connection this tunnel uses (host and credentials come from the host book)","hint.localListenFixed":"The local listen address is fixed to 127.0.0.1 (not exposed to the LAN)","placeholder.localPort":"Local port","field.localListenPort":"Local listen port","hint.flowLocalToRemote":"Traffic flow: local \u2192 SSH server side","placeholder.remoteHost":"Server-side host","hint.remoteHostTitle":"Target host name or IP (reached from the SSH server side; 127.0.0.1 = the server itself)","field.remoteHost":"Server-side target host","placeholder.port":"Port","field.remotePort":"Server-side target port","placeholder.remoteListenHost":"Server-side listen address","hint.remoteListenHost":"Server-side listen address (defaults to 127.0.0.1; leave empty to allow only the server itself)","field.remoteListenHost":"Server-side listen address","placeholder.listenPort":"Listen port","field.remoteListenPort":"Server-side listen port","hint.flowRemoteToLocal":"Traffic flow: local \u2190 SSH server side","hint.localDialFixed":"The local dial address is fixed to 127.0.0.1","placeholder.localTargetPort":"Local service port","field.localTargetPort":"Local target port","hint.tunnelLocalSummary":"Left: local listener (fixed 127.0.0.1) \u2192 Right: target reached from the SSH server side","hint.tunnelRemoteSummary":"Left: SSH server-side listener \u2192 Right: local service being reached (fixed 127.0.0.1)","btn.addTunnel":"Add tunnel","hint.tunnelAdd":"Takes effect immediately; reconnects automatically after a drop; prefer local ports above 1024; remote hosts are reached from the SSH server side (127.0.0.1 = the server itself)","hint.tunnelEditing":"Editing \u201C{name}\u201D \u2014 changing the port/entry derives a new name by rule; takes effect immediately on save","panel.hostKeys":"SSH host key records (TOFU)","btn.importKnownHosts":"Import from known_hosts","list.emptyHostKeys":"No records \u2014 the host fingerprint is recorded automatically after the first successful SSH connection","hint.hostKeys":"A host with several keys (e.g. rsa + ed25519) gets one fingerprint each and any match is accepted; a changed fingerprint rejects the connection (MITM protection) \u2014 delete that record once you are sure it is safe, then reconnect","msg.saving":"Saving\u2026","btn.save":"Save","list.none":"N/A","meta.mem":"Memory","meta.disk":"Disk","meta.cores":"Cores","meta.uptime":"Uptime","meta.temp":"CPU temp","meta.net":"Network","error.tunnelNoBook":"Add an SSH entry to the host book first","error.tunnelRemotePortRequired":"A remote listen port and a local target port are required (1\u201365535)","error.tunnelLocalRequired":"Local port, remote host, and remote port are required","error.tunnelMissing":"Tunnel \u201C{name}\u201D no longer exists (it may have been deleted by another window)","error.tunnelClash":"A tunnel named \u201C{name}\u201D already exists \u2014 handle that one first.","msg.renaming":"Renaming {name}\u2026","msg.deleting":"Deleting {name}\u2026","msg.downloading":"Downloading {name}\u2026","msg.uploadingName":"Uploading {name}","error.invalidTaskState":"The server returned an invalid task state","hint.rememberCredentialApply":"When checked, \u201CApply\u201D writes the password into the official credential store and leaves only an env: reference in the field (the value lives in ~/.dsh/.credentials.yaml; it is not put into the environment and is not sent back to the browser; it does not protect against same-user processes or the agent). Unchecked keeps today's plaintext write into the settings file. If a key or the agent works, do not store a password.","hint.noCredRefPasswordApply":"No other connection uses a credential reference yet \u2014 check \u201CStore in the credential store on apply\u201D above to create one, or type env:NAME straight into the password box","hint.bookNameConflict":"A same-name conflict is rejected","btn.apply":"Apply"};function Ip(e,t){return t===void 0?e:String(e).replace(/\{(\w+)\}/g,(r,s)=>t[s]===void 0?"":String(t[s]))}function Hc(e,t){return Ip(Ri[e]!==void 0?Ri[e]:e,t)}var w=Hc;function Np(e){e.inject(["locale"],t=>{let r=t.locale.register(oo,"zh",Ri),s=t.locale.register(oo,"en",Op);return w=t.locale.bind(oo),()=>{s(),r(),w=Hc}})}function Hp(){return oc(document.baseURI,globalThis.__DSH_TRANSPORT__?.streamBaseUrl)}function Zr(){return Ot!==null&&typeof Ot.describe=="function"?Ot:null}function $r(e){let t=String(e??"").trim();return t.startsWith("env:")?t.slice(4).trim():""}function Fp(){let e=new Set;for(let t of Gt)for(let r of[t?.password,t?.passphrase]){let s=$r(r);s!==""&&e.add(s)}return[...e]}async function Wp(){try{let t=await(await fetch("/api/dsh-tty/credential-refs",{cache:"no-store"})).json();if(t.ok&&Array.isArray(t.names))return t.names.filter(r=>typeof r=="string"&&r!=="")}catch{}return[]}async function Fc(){return[...new Set([...Fp(),...await Wp()])].sort()}async function Wc(e){let t=Zr();if(t===null)return{error:w(Ot===null?"error.credServiceMissing":"error.credServiceIncomplete")};try{let r=await t.describe([e]),s=r?.ok===!0?r.value?.[e]:void 0;return s===void 0?{unreported:!0}:{view:{configured:s.configured===!0,writable:s.writable===!0,source:typeof s.source=="string"?s.source:""}}}catch(r){return{error:r instanceof Error?r.message:String(r)}}}async function Up(e,t){let r=Zr();if(r===null||typeof r.set!="function")return{error:w("error.credStoreUnavailable")};try{return await r.set(e,t),{value:"env:"+e}}catch(s){return{error:w("error.credStoreFailed",{error:s instanceof Error?s.message:String(s)})}}}async function Uc(e){let t=Zr();if(t===null||typeof t.unset!="function")return{error:w("error.credClearUnavailable")};try{return await t.unset(e),{}}catch(r){return{error:w("error.credClearFailed",{error:r instanceof Error?r.message:String(r)})}}}async function zc(e,t,r,s,o,i){if(e!==!0)return{};let n=String(t??"").trim();if(n===""||n.startsWith("env:"))return{};let a=ac(r,s,o,i);return a===""?{error:w("error.credRefNeedsHost")}:Up(a,n)}function Ki(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"t"+Date.now().toString(36)+Math.random().toString(36).slice(2,10)}var wi;function Is(){document.getElementById("dsh-tty-style")||(wi=document.createElement("style"),wi.id="dsh-tty-style",wi.textContent=nc+`
|
|
3472
|
-
`+ic,document.head.appendChild(wi))}var Gi='<svg viewBox="0 0 16 16" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 5l3.5 3L3 11"/><path d="M8.5 11H13"/></svg>',zp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="7" cy="7" r="4.4"/><path d="M10.4 10.4L14 14"/></svg>',jp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.5 4.5h11"/><path d="M6 4.5V3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v1.5"/><path d="M4.5 4.5l.7 8.1a1 1 0 0 0 1 .9h3.6a1 1 0 0 0 1-.9l.7-8.1"/></svg>',$p='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.4"/><path d="M3.5 10.5h-1v-8h8v1"/></svg>',qp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3.5" y="3" width="9" height="11" rx="1.4"/><rect x="5.5" y="1.5" width="5" height="3" rx="1" class="tt_iconPasteHole"/></svg>',Kp='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.5 8a5.5 5.5 0 1 1-1.6-3.9"/><path d="M13.7 1.8v2.7H11"/></svg>',Gp='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1.8 12.8V4.2a1 1 0 0 1 1-1h3l1.4 1.6h6a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H2.8a1 1 0 0 1-1-1z"/></svg>',jc='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 5.5L2 8l2.5 2.5"/><path d="M11.5 5.5L14 8l-2.5 2.5"/><path d="M2.8 8h10.4"/></svg>',$c='<svg viewBox="0 0 16 16" width="13" height="13" fill="currentColor" stroke="none" aria-hidden="true"><circle cx="3.4" cy="8" r="1.35"/><circle cx="8" cy="8" r="1.35"/><circle cx="12.6" cy="8" r="1.35"/></svg>',Vp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4 8h8"/></svg>',Vi='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 4.5l7 7"/><path d="M11.5 4.5l-7 7"/></svg>',Yi='<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7"/></svg>',Yp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M8 3.6v8.8"/><path d="M3.6 8h8.8"/></svg>',Rs='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12.4V3.9a.9.9 0 0 1 .9-.9h2.9l1.4 1.6h5.9a.9.9 0 0 1 .9.9v6.9a.9.9 0 0 1-.9.9H2.9a.9.9 0 0 1-.9-.9z"/></svg>',qc='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 2.6h4.4l3.6 3.6v7.2a.9.9 0 0 1-.9.9H4.9a.9.9 0 0 1-.9-.9V3.5a.9.9 0 0 1 .9-.9z"/><path d="M8.2 2.7v3.4h3.4"/></svg>',Kc='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6.4 9.6l3.2-3.2"/><path d="M9.2 4.6l1-1a2.5 2.5 0 0 1 3.5 3.5l-1 1"/><path d="M6.8 11.4l-1 1a2.5 2.5 0 0 1-3.5-3.5l1-1"/></svg>',Ao='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 12.6V4.2"/><path d="M4.4 7.8L8 4.2l3.6 3.6"/></svg>',Gc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v7.2"/><path d="M5 7.4L8 10.4l3-3"/><path d="M3.4 12.8h9.2"/></svg>',Xp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 10.4V3.2"/><path d="M5 6.2L8 3.2l3 3"/><path d="M3.4 12.8h9.2"/></svg>',Do='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11.2 2.9l1.9 1.9-7.3 7.3-2.4.5.5-2.4z"/></svg>',qr='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4.6h10"/><path d="M6.2 4.6V3.4a.8.8 0 0 1 .8-.8h2a.8.8 0 0 1 .8.8v1.2"/><path d="M4.6 4.6l.6 8a.9.9 0 0 0 .9.8h3.8a.9.9 0 0 0 .9-.8l.6-8"/></svg>',Po='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.2 8a5.2 5.2 0 1 1-1.5-3.7"/><path d="M13.4 2.2v2.6h-2.6"/></svg>',Vc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12.4V3.9a.9.9 0 0 1 .9-.9h2.9l1.4 1.6h5.9a.9.9 0 0 1 .9.9v6.9a.9.9 0 0 1-.9.9H2.9a.9.9 0 0 1-.9-.9z"/><path d="M8 6.6v3.6"/><path d="M6.2 8.4h3.6"/></svg>',Yc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.4 8h9"/><path d="M9.2 4.8L12.4 8l-3.2 3.2"/></svg>',Xc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12.6 8h-9"/><path d="M6.8 4.8L3.6 8l3.2 3.2"/></svg>',Jp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3.4v9"/><path d="M4.8 9.2L8 12.4l3.2-3.2"/></svg>',Zp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.4" y="3.2" width="11.2" height="4" rx="1.2"/><rect x="2.4" y="8.8" width="11.2" height="4" rx="1.2"/><path d="M5 5.2h.01"/><path d="M5 10.8h.01"/></svg>',Qp='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 2.6l5.8 10.4H2.2z"/><path d="M8 6.4v3.2"/><path d="M8 11.6h.01"/></svg>',e_='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="8" cy="8" r="5.6"/><path d="M8 7.2v3.6"/><path d="M8 5.1h.01"/></svg>',Jc='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.6"/><path d="M6 6l4 4"/><path d="M10 6l-4 4"/></svg>',t_='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 2.8v5"/><path d="M11.6 4.6a5.2 5.2 0 1 1-7.2 0"/></svg>',Zc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="5.6" cy="6" r="2.8"/><path d="M7.8 7.9l5.4 5.4"/><path d="M10.6 10.7l1.2-1.2"/></svg>',Qc=null,Ae=null,ue=null,Mi=null,Ms=null,Ot=null,mr=null,yr=null,Re=null,Bt=null,ws=null,ys=null,Ai=null,_t=null,Ss=null,lt=null,mt=null,st=null,Kr=null,As=!1,Cs=null,Ve=!1,Qe=null,Di=null,Qr=null,Sr=null,Pi=null,gr=null,xs=1e3,Bi="dsh-tty:tabs",fe=new Map,Ns=new Set,Bo=()=>Ns.size>0,uo=new Set,ke=null,Hs=0,yi=!1,gt=null,Oi=!1,cr=new Map,vr=null,Cr=null,Gr=null,ir=null,Ii=null,ct=null,Vr=null,Gt=[],Ni=!0,St=null,Ct=null,ks=null,bs=null,fo=null,po=new Set;function Xi(e){return po.add(e),()=>po.delete(e)}Xi(({tab:e,addAction:t})=>{wr&&e.exited&&t(Kp,w("btn.reopen"),w("btn.reopenTitle"),()=>Fi(e.sid))});Xi(({tab:e,addAction:t})=>{wr&&t(Gp,"SFTP",w("btn.sftpTitle"),()=>Qi(e.spawnSpec,e.sid))});Xi(({bookName:e,addAction:t})=>{if(!wr)return;let r=e!==""?bh(e):0;if(r>0){t(jc,w("btn.tunnels",{count:r}),w("btn.tunnelsTitle"),s=>uh(s.currentTarget,e));return}e!==""&&t($c,w("btn.more"),w("btn.moreTitle"),s=>A_(s.currentTarget,e))});function Fs(e,t){if(mr===null)return;mr.textContent=e.split("\u2014\u2014")[0],mr.title=e,yr.dataset.state=t,Mi!==null&&(Mi.style.display=t==="connected"?"none":""),Qr!==null&&(Qr.textContent=e),Sr!==null&&(Sr.dataset.state=t);let r=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot");r!==null&&(r.dataset.state=t)}function ao(e,t,r){let s=typeof e=="string"&&e!==""?e:null;if(s!==null){let o=fe.get(s);o!==void 0&&(o.statusText=t,o.statusState=r)}wc(s,ke)&&(Ms=s,Fs(t,r))}function Si(e,t){Ms=null,Fs(e,t)}function Oo(){if(!yc(Ms,ke))return;let e=ke===null?void 0:fe.get(ke);Ms=e===void 0?null:ke;let t=bc(e,w);Fs(t.text,t.state)}function Pe(e){Ae!==null&&Ae.readyState===WebSocket.OPEN&&Ae.send(JSON.stringify(e))}function r_(){let e=[],t=document.createDocumentFragment();for(let r of no(w)){let s=document.createElement("span");s.className="tt_statsItem";let o=document.createElement("span");o.className="tt_statsLabel",o.textContent=r.label,s.appendChild(o);let i=null,n=null;r.kind==="pct"&&(i=document.createElement("span"),i.className="tt_statsMeter",n=document.createElement("span"),n.className="tt_statsMeterFill",i.appendChild(n),s.appendChild(i));let a=document.createElement("span");a.className="tt_statsValue",s.appendChild(a),t.appendChild(s),e.push({item:s,value:a,meter:i,fill:n,slot:null})}return St!==null&&St.appendChild(t),e}function s_(e,t){let r=Tc(t!==void 0?t.stats:null,w);for(let s=0;s<e.length;s+=1){let o=e[s],i=r[s];if(i!==void 0&&(o.slot!==i.slot&&(o.slot=i.slot,o.value.style.minWidth=i.slot>0?i.slot+"ch":""),o.value.textContent!==i.value&&(o.value.textContent=i.value),o.item.getAttribute("title")!==i.title&&o.item.setAttribute("title",i.title),o.fill!==null&&o.meter!==null)){let n=i.pct===null?"0%":Math.max(0,Math.min(100,i.pct)).toFixed(1)+"%";o.fill.style.width!==n&&(o.fill.style.width=n);let a=Cc(i.pct);o.meter.dataset.level!==a&&(o.meter.dataset.level=a)}}}function Ji(){bs=null,fo=null}function i_(){if(ue===null||Ve||!Ni)return!1;let e=vt();return e===void 0||e.embedded===!0||e.exited===!0||e.stats===null||e.stats===void 0?!1:Ec(e.statsAt)}function Rc(){if(Ve)return;let e=vt();if(!(e===void 0||e.embedded===!0||e.fit===null)){try{e.fit.fit()}catch{return}try{e.spawned&&!e.exited&&rs(e)}catch{}}}function xr(){try{n_()}catch(e){console.warn("[dsh-tty] \u72B6\u6001\u6761\u6E32\u67D3\u5931\u8D25\uFF08\u5DF2\u6536\u8D77\uFF09: "+(e instanceof Error?e.message:String(e)));try{St!==null&&(St.hidden=!0,St.textContent=""),Ji(),lt!==null&&delete lt.dataset.stats}catch{}}}function n_(){if(lt===null||St===null)return;let e=i_(),t=lt.dataset.stats!==void 0!==e;if(!e){t&&delete lt.dataset.stats,St.hidden=!0,bs!==null&&(St.textContent="",Ji()),t&&Rc();return}St.hidden=!1,bs===null&&(bs=r_());let r=vt(),s=r===void 0?"":r.sid+":"+String(r.statsAt||0);s!==fo&&(fo=s,s_(bs,r)),t&&(lt.dataset.stats="",Rc())}function eh(){ks===null&&(ks=setInterval(()=>xr(),1e3))}function th(){ks!==null&&(clearInterval(ks),ks=null)}function rh(){if(ue===null||Ve||!Ni)return null;let e=vt();return e===void 0||e.embedded===!0||e.exited===!0?null:e.sid}function Ws(){let e=rh();e!==Ct&&(Ct!==null&&Pe({t:"statsOff",sid:Ct}),Ct=e,e!==null&&Pe({t:"statsOn",sid:e}))}function o_(e){if(e!==rh()){Ws();return}Ct!==null&&Ct!==e&&Pe({t:"statsOff",sid:Ct}),Ct=e,Pe({t:"statsOn",sid:e})}function vt(){return ke!==null?fe.get(ke):void 0}function _o(){try{return uc(Qc?.list?.getSnapshot?.())}catch{return}}function a_(e){if(!(e.term===null||e.exited)){try{if(e.term.buffer.active.length<=e.term.rows)return}catch{return}e.term.reset(),Pe({t:"refresh",sid:e.sid})}}var Ci=null;function sh(e){Ci!==null&&clearTimeout(Ci),Ci=setTimeout(()=>{Ci=null;let t=vt();t!==void 0&&a_(t)},e??200)}var l_=["password","passphrase"];function Mc(e){if(e===null||typeof e!="object"||e.t!=="ssh")return e;let t=e.credsStripped===!0,r={...e};for(let s of l_){let o=r[s];typeof o=="string"&&o!==""&&!o.startsWith("env:")&&(delete r[s],t=!0)}return t&&(r.credsStripped=!0),r}var ih=1;function lr(){try{let e=[...fe.values()].filter(t=>!t.exited&&t.embedded!==!0).map(t=>({sid:t.sid,spawnSpec:Mc(t.spawnSpec),label:t.label}));e.length===0||ue===null?sessionStorage.removeItem(Bi):sessionStorage.setItem(Bi,JSON.stringify({v:ih,tabs:e})),c_([...fe.values()].filter(t=>t.embedded!==!0).map(t=>({spawnSpec:Mc(t.spawnSpec),label:t.label})))}catch(e){console.warn("[dsh-tty] \u6807\u7B7E\u6301\u4E45\u5316\u5931\u8D25\uFF08\u672C\u6B21\u5237\u65B0\u540E\u6807\u7B7E\u5217\u8868\u53EF\u80FD\u4E22\u5931\uFF09: "+(e instanceof Error?e.message:String(e)))}}var mo="dsh-tty:persist-specs";function c_(e){try{let t=e.filter(r=>zs(r.spawnSpec)).map(r=>({spawnSpec:r.spawnSpec,label:r.label}));t.length===0?localStorage.removeItem(mo):localStorage.setItem(mo,JSON.stringify(t))}catch{}}function h_(){try{let e=localStorage.getItem(mo);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>r!==null&&typeof r=="object"&&zs(r.spawnSpec)):[]}catch{return[]}}function d_(){try{let e=sessionStorage.getItem(Bi);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>r!==null&&typeof r=="object"&&typeof r.sid=="string"&&r.sid!==""&&r.spawnSpec!==null&&typeof r.spawnSpec=="object"):t!==null&&typeof t=="object"&&t.v===ih&&Array.isArray(t.tabs)?t.tabs.filter(r=>r!==null&&typeof r=="object"&&typeof r.sid=="string"&&r.sid!==""&&r.spawnSpec!==null&&typeof r.spawnSpec=="object"):[]}catch{return[]}}function Hi(e,t){let r=Ae;return new Promise(s=>{let o=null,i=n=>{let a;try{a=JSON.parse(n.data)}catch{return}a.t===e&&(o!==null&&clearTimeout(o),r.removeEventListener("message",i),s(r===Ae?a:null))};o=setTimeout(()=>{r.removeEventListener("message",i),s(null)},t),r.addEventListener("message",i)})}function u_(e){return e===void 0?null:e.embedded===!0?e.controller!==void 0&&e.controller!==null?e.controller.hostEl:null:e.termEl}function nh(e){if(e===void 0||e.fit===null||e.fit===void 0)return;let t;try{t=e.fit.proposeDimensions()}catch{return}let r=u_(e);return fc(t,r==null?null:{width:r.clientWidth,height:r.clientHeight})}function rs(e){if(e===void 0||e.fit===void 0)return;let t=nh(e);t!==void 0&&(e.lastDims=t,Pe({t:"resize",sid:e.sid,cols:t.cols,rows:t.rows}))}function f_(e){if(e===void 0||e.fit===void 0)return;let t=e.term,r=t!==null&&t.buffer!==void 0?t.buffer.active:null,s=r==null?null:{atBottom:r.viewportY>=r.baseY,line:r.viewportY};try{e.fit.fit()}catch{return}if(s!==null)try{s.atBottom?t.scrollToBottom():t.scrollToLine(Math.min(s.line,t.buffer.active.baseY))}catch{}e.exited||rs(e)}function Ur(e,t,r,s){if(e.overlayEl===null||e.overlayEl===void 0)return;let o=e.overlayEl;if(t===""||t===void 0){o.textContent="";return}let i=s==="error"||s==="info"?s:"exited";o.innerHTML='<div class="tt_overlayCard" data-kind="'+i+'"><span class="tt_overlayIcon">'+(i==="error"?Jc:i==="info"?Po:t_)+'</span><span class="tt_overlayText"><span class="tt_overlayMain"></span>'+(r===void 0||r===""?"":'<span class="tt_overlayHint"></span>')+"</span></div>",o.querySelector(".tt_overlayMain").textContent=t,r!==void 0&&r!==""&&(o.querySelector(".tt_overlayHint").textContent=r)}function Te(e,t=""){try{let r=getComputedStyle(document.body).getPropertyValue(e).trim();return r!==""?r:t}catch{return t}}function ss(e){let t=Te("--tt-accent"),r={};r.background=Te("--tt-term-bg"),r.foreground=Te("--tt-term-fg"),r.cursor=t,r.cursorAccent=Te("--tt-term-cursor-accent"),r.selectionBackground=Te("--tt-term-selection"),r.black=Te("--tt-an-black"),r.red=Te("--tt-an-red"),r.green=Te("--tt-an-green"),r.yellow=Te("--tt-an-yellow"),r.blue=Te("--tt-an-blue"),r.magenta=Te("--tt-an-magenta"),r.cyan=Te("--tt-an-cyan"),r.white=Te("--tt-an-white"),r.brightBlack=Te("--tt-an-bright-black"),r.brightRed=Te("--tt-an-bright-red"),r.brightGreen=Te("--tt-an-bright-green"),r.brightYellow=Te("--tt-an-bright-yellow"),r.brightBlue=Te("--tt-an-bright-blue"),r.brightMagenta=Te("--tt-an-bright-magenta"),r.brightCyan=Te("--tt-an-bright-cyan"),r.brightWhite=Te("--tt-an-bright-white");let s=new Ic.Terminal({cursorBlink:!0,cursorStyle:"bar",cursorInactiveStyle:"outline",fontSize:13,fontFamily:'"JetBrains Mono", "SF Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace',fontWeight:400,fontWeightBold:600,lineHeight:1.35,scrollback:5e3,convertEol:!1,allowProposedApi:!0,theme:r}),o=new Nc.FitAddon,i=new Ba;s.loadAddon(o),s.loadAddon(i),s.loadAddon(new Oa);let n=document.createElement("div");n.className="tt_term";let a=document.createElement("div");a.className="tt_overlay",a.addEventListener("click",()=>{a.textContent="",Fi(e.sid)}),a.setAttribute("role","button"),a.setAttribute("aria-label",w("btn.reopenSession")),a.tabIndex=0,a.addEventListener("keydown",d=>{(d.key==="Enter"||d.key===" "||d.key==="Spacebar")&&(d.preventDefault(),a.textContent="",Fi(e.sid))}),n.appendChild(a),s.open(n);try{o.fit()}catch{}try{let d=new sc;d.onContextLoss(()=>{try{d.dispose()}catch{}}),s.loadAddon(d)}catch{}s.onData(d=>{Pe({t:"input",sid:e.sid,d}),cr.delete(e.sid)&&kr()}),s.onResize(()=>{zs(e.spawnSpec)&&sh(200)}),s.attachCustomKeyEventHandler(d=>e.embedded===!0?!0:(d.ctrlKey||d.metaKey)&&d.key.toLowerCase()==="f"?(d.preventDefault(),Bh(),!1):!0),e.term=s,e.fit=o,e.search=i,e.termEl=n,e.overlayEl=a}function Ac(e){return e===null||typeof e!="object"?"":["t","name","host","port","username","command","cwd","persist","persistName"].map(r=>r+"="+String(e[r]??"")).join("\0")}function p_(e){let t=Ac(e);if(t==="")return null;for(let r of fe.values())if(r.exited!==!0&&r.embedded!==!0&&Ac(r.spawnSpec)===t)return r;return null}function Ds(e,t){let r=Ki(),s={sid:r,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e??om(),label:t};return ss(s),fe.set(r,s),Hs+=1,ht(),Yt(r),Zi(s),lr(),s}function __(e){if(Array.isArray(e))for(let t of e){if(t===null||typeof t!="object"||t.owner!=="agent"||t.exited===!0)continue;let r=typeof t.sid=="string"?t.sid:"";if(r===""||fe.has(r))continue;let s={sid:r,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,agentOwned:!0,spawnSpec:{t:"spawn",cwd:typeof t.cwd=="string"?t.cwd:_o()},label:"agent"+(t.kind==="ssh"&&typeof t.target=="string"&&t.target!==""?" \xB7 "+t.target:"")};ss(s),fe.set(r,s),Hs+=1,ht(),m_()&&s.termEl!==null&<!==null&&ke===null&&Yt(r),Pe({t:"attach",sid:r}),g_()}}function m_(){return ue!==null&&Ve!==!0}function g_(){try{lr()}catch{}}function v_(e){if(__(e),!Array.isArray(e))return;let t=vi(e.filter(r=>r!==null&&typeof r=="object"&&r.owner==="agent"));for(let[r,s]of[...fe])s.agentOwned===!0&&(t.has(r)||s.exited!==!0&&s.live===!0&&(s.exited=!0,s.live=!1,ht()))}function b_(e){if(fe.has(e.sid))return fe.get(e.sid);let t={sid:e.sid,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e.spawnSpec,label:typeof e.label=="string"?e.label:void 0};ss(t),fe.set(t.sid,t),Hs+=1,ht(),Yt(t.sid),Pe({t:"attach",sid:t.sid})}function w_(e){if(!(e?.spawnSpec?.credsStripped!==!0||e.term===null))try{e.term.writeln("\x1B[2m[dsh-tty] "+w("msg.passwordNotStored")+"\x1B[0m")}catch{}}function Zi(e){w_(e);let t=nh(e);t!==void 0&&(e.lastDims=t);let r=t!==void 0?t:e.lastDims!==void 0?e.lastDims:{cols:80,rows:24},s={...e.spawnSpec,sid:e.sid,cols:r.cols,rows:r.rows};if(Ae===null||Ae.readyState!==WebSocket.OPEN){uo.add({tab:e,frame:s});return}Pe(s)}function Dc(e){let t={sid:Ki(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e.spawnSpec,label:typeof e.label=="string"?e.label:void 0};ss(t),fe.set(t.sid,t),Hs+=1,ht(),Yt(t.sid),Zi(t)}function Fi(e){let t=fe.get(e);if(t===void 0)return;if(t.embedded===!0){ch(t);return}let r=t.spawnSpec,s=t.label;if(Pe({t:"kill",sid:e}),t.term!==null)try{t.term.dispose()}catch{}t.termEl!==null&&t.termEl.remove(),fe.delete(e);let o={sid:Ki(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:r,label:s};ss(o),fe.set(o.sid,o),ht(),Yt(o.sid),Zi(o),lr()}function go(e){let t=fe.get(e);if(t!==void 0){if(xt!==null&&xt.ownerKey===e&&Ls(!0),Pe({t:"kill",sid:e}),fe.delete(e),Cr===e&&kt(),cr.delete(e),kr(),Ns.delete(e),t.term!==null)try{t.term.dispose()}catch{}if(t.termEl!==null&&t.termEl.remove(),ke===e){ke=null;let r=[...fe.entries()].filter(([,s])=>s.embedded!==!0).map(([s])=>s).pop()??null;r!==null&&Yt(r)}ht(),Oo(),[...fe.values()].some(r=>r.embedded!==!0)?lr():Os()}}function oh(e){let t=typeof e?.command=="string"?e.command.trim():"";if(t==="")throw new Error(w("error.terminalNeedsCommand"));if(/[\r\n\0]/.test(t))throw new Error(w("error.terminalCommandSingleLine"));return t}function ah(e,t){return typeof e?.book=="string"&&e.book!==""?{t:"ssh",name:e.book,command:t}:e?.spec!==null&&typeof e?.spec=="object"?{t:"ssh",...e.spec,command:t}:{t:"spawn",...typeof e?.cwd=="string"&&e.cwd!==""?{cwd:e.cwd}:{},command:t}}function y_(e){let t=e.controller;t===void 0||t.observer!==null||(t.observer=new ResizeObserver(()=>{if(!(t.disposed||t.tab!==e||e.term===null)){try{e.fit.fit()}catch{return}e.spawned&&!e.exited&&rs(e)}}),t.observer.observe(t.hostEl))}function lh(e,t,r){let s={sid:Ki(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,embedded:!0,controller:e,spawnSpec:t,label:r};return ss(s),fe.set(s.sid,s),Ns.add(s.sid),e.hostEl.appendChild(s.termEl),y_(s),Zi(s),s}function ch(e){let t=e.controller;if(!(t===void 0||t.disposed)){e.exited||Pe({t:"kill",sid:e.sid});try{e.term?.dispose()}catch{}return e.termEl?.remove(),fe.delete(e.sid),Ns.delete(e.sid),t.observer!==null&&(t.observer.disconnect(),t.observer=null),t.tab=lh(t,e.spawnSpec,e.label),ke===e.sid&&(ke=t.tab.sid,Oo()),t.tab}}function S_(e,t){if(!(e instanceof HTMLElement))throw new Error(w("error.terminalNeedsHost"));let r=oh(t),s=ah(t,r),o=typeof t?.label=="string"&&t.label!==""?t.label:void 0;Is();let i={hostEl:e,tab:null,observer:null,disposed:!1};return i.tab=lh(i,s,o),lm(),()=>C_(i)}function C_(e){if(e.disposed)return;e.disposed=!0,e.observer!==null&&(e.observer.disconnect(),e.observer=null);let t=e.tab;if(t!==null){t.exited||Pe({t:"kill",sid:t.sid});try{t.term?.dispose()}catch{}t.termEl?.remove(),fe.delete(t.sid),Ns.delete(t.sid),e.tab=null}if(ue===null&&!Bo()&&Ae!==null){As=!0;try{Ae.close()}catch{}Ae=null}}var x_=460,k_=280,E_=320,L_=160,xt=null,zr=x_,jr=E_;function Io(){let e=ue!==null?ue.querySelector(".tt_modal"):null,t=e!==null?e:ue;return t!==null?t.getBoundingClientRect():null}var No=e=>e==="bottom"?L_:k_;function T_(e){let t=Io();if(t===null)return 900;let r=e==="bottom"?t.height:t.width;return Math.max(No(e),Math.round(r*.72))}function Es(e,t){return Math.min(T_(e),Math.max(No(e),Math.round(t)))}function ki(){let e=xt;if(e!==null){if(e.collapsed){e.el.style.width="",e.el.style.height="",e.el.style.flexBasis="";return}if(e.side==="bottom"){jr=Es("bottom",jr),e.el.style.width="",e.el.style.height=String(jr)+"px",e.el.style.flexBasis=String(jr)+"px";return}zr=Es("right",zr),e.el.style.height="",e.el.style.width=String(zr)+"px",e.el.style.flexBasis=String(zr)+"px"}}function Ls(e){let t=xt;if(t!==null){if(xt=null,t.disposed=!0,e&&t.onClose!==null)try{t.onClose()}catch(r){console.warn("[dsh-tty] ttyPanel.onClose \u629B\u9519\uFF1A"+(r instanceof Error?r.message:String(r)))}try{t.el.remove()}catch{}mt!==null&&delete mt.dataset.side}}function hh(e){if(To(),mt===null)throw new Error(w("error.panelNotReady"));xt!==null&&Ls(!0),Is();let t=Wr(e?.ownerSid,ke),r=e?.side==="bottom"?"bottom":"right",s=Math.max(r==="bottom"?120:200,Math.round(typeof e?.min=="number"&&Number.isFinite(e.min)?e.min:No(r)));if(typeof e?.size=="number"&&Number.isFinite(e.size)){let c=Es(r,e.size);r==="bottom"?jr=c:zr=c}let o=document.createElement("div");o.className="tt_dockPane",o.dataset.side=r,mt.dataset.side=r,o.innerHTML='<div class="tt_dockPaneResize" title="'+w(r==="bottom"?"panel.dragHeight":"panel.dragWidth")+'"></div><div class="tt_dockPaneHead"><span class="tt_dockPaneTitle"></span><span class="tt_dockPaneHint"></span><span class="tt_dockPaneSpacer"></span><button class="tt_dockPaneFold" type="button"></button><button class="tt_dockPaneClose" type="button" title="'+w("btn.closePane")+'">'+Vi+'</button></div><div class="tt_dockPaneBody"></div>',mt.appendChild(o);let i=o.querySelector(".tt_dockPaneTitle"),n=o.querySelector(".tt_dockPaneHint"),a=o.querySelector(".tt_dockPaneBody"),d=o.querySelector(".tt_dockPaneFold"),l=o.querySelector(".tt_dockPaneClose"),_=o.querySelector(".tt_dockPaneResize"),m={el:o,element:a,disposed:!1,collapsed:!1,side:r,minSize:s,ownerKey:t,onClose:typeof e?.onClose=="function"?e.onClose:null},y=()=>r==="bottom"?m.collapsed?Ao:Jp:m.collapsed?Xc:Yc,p=c=>{m.collapsed=c===!0,m.collapsed?o.dataset.collapsed="1":delete o.dataset.collapsed,d.innerHTML=y(),d.title=m.collapsed?w("btn.expandPane"):w("btn.collapsePane"),d.setAttribute("aria-label",d.title),ki()};return m.setTitle=c=>{i.textContent=typeof c=="string"?c:""},m.setHint=c=>{n.textContent=typeof c=="string"?c:""},m.isCollapsed=()=>m.collapsed===!0,m.collapse=()=>p(!0),m.expand=()=>p(!1),m.toggle=()=>p(!m.collapsed),m.dispose=()=>{m.disposed||xt!==m||Ls(!1)},_.addEventListener("mousedown",c=>{if(c.button!==0||m.collapsed)return;c.preventDefault();let u=c.clientX,h=c.clientY,f=o.getBoundingClientRect(),v=g=>{r==="bottom"?jr=Es("bottom",Math.max(s,f.height+(h-g.clientY))):zr=Es("right",Math.max(s,f.width+(u-g.clientX))),ki()},S=()=>{document.removeEventListener("mousemove",v),document.removeEventListener("mouseup",S),document.body.style.userSelect=""};document.body.style.userSelect="none",document.addEventListener("mousemove",v),document.addEventListener("mouseup",S)}),_.addEventListener("dblclick",()=>p(!m.collapsed)),d.addEventListener("click",()=>p(!m.collapsed)),l.addEventListener("click",()=>Ls(!0)),m.setTitle(typeof e?.title=="string"?e.title:""),m.setHint(typeof e?.hint=="string"?e.hint:""),p(e?.collapsed===!0),xt=m,ki(),dh(),m}function dh(){let e=xt;if(e!==null){if(so(e.ownerKey,ke)){delete e.el.dataset.dockHidden,mt!==null&&(mt.dataset.side=e.side);return}e.el.dataset.dockHidden="1",mt!==null&&delete mt.dataset.side}}function Yt(e){let t=fe.get(e);if(t!==void 0&&t.embedded!==!0){ke=e,kt(),kr();for(let[r,s]of fe)s.embedded!==!0&&s.termEl!==null&&(s.termEl.style.display=r===e?"":"none");t.embedded!==!0&<!==null&&t.termEl!==null&&t.termEl.parentElement!==lt&<.appendChild(t.termEl),Ws(),xr(),ht(),br(),dh();try{t.fit.fit()}catch{}t.spawned&&!t.exited&&rs(t),Ur(t,t.exited?w("status.exited"):"",t.exited?w("btn.clickReopen"):"","exited"),Oo()}}function lo(e){if(Re===null)return;let t=fe.get(e);if(t===void 0)return;let s=Re.querySelector(`[data-sid="${e}"]`)?.querySelector(".tt_tabDot");if(s==null)return;s.dataset.state=Wi(t);let o=ct===null?null:ct.querySelector('[data-sid="'+e+'"] .tt_tabDot');o!==null&&(o.dataset.state=Wi(t))}var co=!1;function ht(){if(Re===null)return;if(Re.querySelector(".tt_tabRename")!==null){co||(co=!0,setTimeout(()=>{co=!1,ht()},1e3));return}Re.textContent="";for(let[t,r]of fe){if(r.embedded===!0)continue;let s=document.createElement("button");s.className="tt_tab",s.dataset.sid=t,t===ke&&(s.dataset.active="");let o=document.createElement("span");o.className="tt_tabDot",o.dataset.state=Wi(r),s.appendChild(o);let i=document.createElement("span");i.className="tt_tabLabel",i.textContent=r.label||w("panel.tabLabel",{n:Ho(t)}),i.addEventListener("dblclick",a=>{a.stopPropagation(),D_(t,s)});let n=document.createElement("span");n.className="tt_tabClose",n.title=w("btn.close"),n.innerHTML=Yi,n.setAttribute("role","button"),n.setAttribute("aria-label",w("btn.closeTabAria",{label:r.label||""})),n.tabIndex=0,n.addEventListener("keydown",a=>{(a.key==="Enter"||a.key===" "||a.key==="Spacebar")&&(a.preventDefault(),a.stopPropagation(),go(t))}),s.title=i.textContent,s.appendChild(i),s.appendChild(n),s.addEventListener("click",a=>{if(a.target.closest(".tt_tabClose")!==null){a.stopPropagation(),go(t);return}Yt(t)}),Re.appendChild(s)}let e=Re.querySelector("[data-active]");e!==null&&typeof e.scrollIntoView=="function"&&e.scrollIntoView({block:"nearest",inline:"nearest"}),vo(),ct!==null&&fe.size===0&&Xt()}function vo(){if(Re===null)return;let e=Re.scrollWidth-Re.clientWidth,t=e>1;if(Bt!==null&&(Bt.hidden=!t,t?Bt.title=w("btn.tabListTitle",{n:fe.size}):ct!==null&&Xt()),!t){delete Re.dataset.edge;return}let r=Re.scrollLeft>1,s=Re.scrollLeft<e-1;Re.dataset.edge=r&&s?"both":s?"end":"start",ct!==null&&Ch()}function Wi(e){return e.exited?"exited":e.live===!0?"connected":e.errored===!0?"error":"connecting"}function R_(e){if(Re===null||Math.abs(e.deltaY)<=Math.abs(e.deltaX))return;let t=Re.scrollWidth-Re.clientWidth;if(t<=1)return;let r=Math.max(0,Math.min(t,Re.scrollLeft+e.deltaY));r!==Re.scrollLeft&&(e.preventDefault(),Re.scrollLeft=r)}function M_(e){return e?.direction==="remote"?w("meta.tunnelRemote",{host:e.remoteHost||"127.0.0.1",port:String(e.remotePort??0),local:String(e.localTargetPort??0)}):w("meta.tunnelLocal",{local:String(e?.localPort??0),host:e?.remoteHost??"?",port:String(e?.remotePort??0)})}function br(){if(ws===null||Ai===null||Ss===null||ys===null)return;Ss.textContent="";let e=vt(),t=e?.spawnSpec??{};if(e===void 0||t.t!=="ssh"){ws.dataset.hidden="";return}delete ws.dataset.hidden;let r=Number(t.port);Ai.textContent=typeof e.target=="string"&&e.target!==""?e.target:typeof t.name=="string"&&t.name!==""?t.name:String(t.username??"")+"@"+String(t.host??"")+(Number.isInteger(r)&&r!==22?":"+r:""),_t!==null&&(e.persistTmux===!0?(_t.textContent="tmux",_t.dataset.state="ok",_t.title=w("status.tmuxPersistedTitle")):t.persist===!0&&e.spawned===!0?(_t.textContent=w("status.notPersisted"),_t.dataset.state="warn",_t.title=w("status.tmuxUnavailableTitle")):(_t.textContent="",delete _t.dataset.state,_t.removeAttribute("title")));let s=e.exited?"exited":e.live===!0?"connected":e.errored===!0?"error":"connecting";ys.dataset.state=s,ys.title=w(s==="connected"?"status.connected":s==="connecting"?"status.connecting":s==="error"?"status.errored":"status.exited");let o=(n,a,d,l)=>{let _=document.createElement("button");_.type="button",_.className="tt_toolBtn tt_connAct",_.title=d,_.innerHTML=n+"<span></span>",_.lastElementChild.textContent=a,_.addEventListener("click",l),Ss.appendChild(_)};if(typeof t.command=="string"&&t.command!=="")return;let i=typeof t.name=="string"?t.name:"";for(let n of po)try{n({tab:e,spec:t,bookName:i,addAction:o})}catch(a){console.warn("[dsh-tty] connbar action failed: "+(a instanceof Error?a.message:String(a)))}}function A_(e,t){if(Yr!==null){Ei();return}let r=document.createElement("div");r.className="tt_addMenu tt_connMore",Yr=r,ko(r,w("panel.tunnels"),w("hint.tunnelsSettings"),()=>{Ei(),uh(e,t)},void 0,jc),document.body.appendChild(r);let s=e.getBoundingClientRect(),o=r.offsetWidth,n=s.left+o>window.innerWidth-8?s.right-o:s.left;r.style.left=Math.max(8,Math.min(n,window.innerWidth-o-8))+"px",r.style.top=s.bottom+6+"px";let a=d=>{Yr===r&&(r.contains(d.target)||e.contains(d.target)||Ei())};Ti=a,setTimeout(()=>document.addEventListener("mousedown",a,!0),0)}function Ei(){Ti!==null&&(document.removeEventListener("mousedown",Ti,!0),Ti=null),Yr!==null&&(Yr.remove(),Yr=null)}var pr=null,Li=null,Yr=null,Ti=null;function Ui(){Li!==null&&(document.removeEventListener("mousedown",Li,!0),Li=null),pr!==null&&(pr.remove(),pr=null)}function uh(e,t){if(pr!==null){Ui();return}let r=document.createElement("div");r.className="tt_tunnelPop";let s=document.createElement("div");s.className="tt_tunnelPopTitle",s.textContent=w("panel.tunnelsFor",{name:t}),r.appendChild(s);let o=document.createElement("div");o.textContent=w("list.loading"),r.appendChild(o);let i=document.createElement("span");i.className="tt_cardHint",i.textContent=w("hint.tunnelsCard"),r.appendChild(i),document.body.appendChild(r),pr=r;let n=e.getBoundingClientRect();r.style.top=String(n.bottom+6)+"px",r.style.left=String(Math.max(8,n.right-340))+"px";let a=d=>{pr===r&&(r.contains(d.target)||e.contains(d.target)||Ui())};Li=a,setTimeout(()=>document.addEventListener("mousedown",a,!0),0),(async()=>{let d=[];try{let m=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();m.ok&&Array.isArray(m.tunnels)&&(d=m.tunnels)}catch{}if(pr!==r)return;o.textContent="";let l=Fo.filter(_=>_?.bookName===t&&_?.enabled!==!1);if(l.length===0){let _=document.createElement("span");_.className="tt_cardHint",_.textContent=w("list.noActiveTunnels"),o.appendChild(_);return}for(let _ of l){let m=d.find(h=>h?.name===_?.name),y=m?.state??"stopped",p=document.createElement("div");p.className="tt_tunnelPopRow";let c=document.createElement("span");c.className="tt_connDot",c.dataset.state=y==="active"?"connected":y==="error"?"error":"connecting";let u=document.createElement("span");u.className="tt_connTarget",u.title=String(m?.error??m?.lastForwardError??""),u.textContent=M_(_)+" \xB7 "+y+(m?.fatal===!0?w("status.fatalSuffix"):""),p.appendChild(c),p.appendChild(u),o.appendChild(p)}})()}function Ho(e){let t=1;for(let r of fe.keys()){if(r===e)return String(t);t+=1}return String(t)}function D_(e,t){let r=fe.get(e);if(r===void 0||t.querySelector(".tt_tabRename")!==null)return;let s=t.querySelector(".tt_tabLabel");if(s===null)return;let o=document.createElement("input");o.className="tt_tabRename",o.value=r.label||w("panel.tabLabel",{n:Ho(e)}),s.replaceWith(o),o.focus(),o.select();let i=!1,n=()=>{if(i)return;i=!0;let d=o.value.trim();r.label=d!==""?d:void 0,ht(),lr()},a=()=>{i||(i=!0,ht())};o.addEventListener("keydown",d=>{d.stopPropagation(),d.key==="Enter"?n():d.key==="Escape"&&a()}),o.addEventListener("blur",n),o.addEventListener("click",d=>d.stopPropagation())}var Fo=[],fh="dialog",ar="off",Kt={maxDownloadMb:1024,maxUploadMb:2048,maxUploadFiles:1e3},ph="dsh-tty:show-hidden",_r=(()=>{try{return localStorage.getItem(ph)==="1"}catch{return!1}})();function P_(e){_r=e===!0;try{localStorage.setItem(ph,_r?"1":"0")}catch{}for(let t of bo)try{t(_r)}catch{}}var bo=new Set,wo=null,Xr=null,_h=!1,mh=!1,or=null,zi=null,wr=!1;function gh(e){wr=e,zi!==null&&zi.set(e)}function B_(e){gh(!(e!==null&&typeof e=="object"&&e.enabled===!1)),e!==null&&typeof e=="object"&&typeof e.statsEnabled=="boolean"&&e.statsEnabled!==Ni&&(Ni=e.statsEnabled,Ws(),xr())}function Ps(e){B_(e),e!==null&&typeof e=="object"&&Array.isArray(e.sshHosts)&&(Gt=e.sshHosts),e!==null&&typeof e=="object"&&Array.isArray(e.tunnels)&&(Fo=e.tunnels),e!==null&&typeof e=="object"&&(e.sftpStyle==="dual"||e.sftpStyle==="dialog")&&(fh=e.sftpStyle),e!==null&&typeof e=="object"&&(e.persistence==="tmux"||e.persistence==="off")&&(ar=e.persistence),e!==null&&typeof e=="object"&&typeof e.sftpLimits=="object"&&e.sftpLimits!==null&&(Kt={...Kt,...e.sftpLimits}),e!==null&&typeof e=="object"&&Number.isInteger(e.maxSessions)&&e.maxSessions>=1&&(Xr=e.maxSessions),e!==null&&typeof e=="object"&&typeof e.allowProxyCommand=="boolean"&&(_h=e.allowProxyCommand),e!==null&&typeof e=="object"&&typeof e.assistEnabled=="boolean"&&(Oi=e.assistEnabled,Oi||kt(),kr()),e!==null&&typeof e=="object"&&typeof e.allowProxyCommandGranted=="boolean"&&(mh=e.allowProxyCommandGranted)}function O_(e,t){let r=t==="error"||t==="info"?t:"warn",s=document.createElement("div");s.className="tt_toast",s.dataset.kind=r,s.innerHTML='<span class="tt_toastIcon">'+(r==="error"?Jc:r==="info"?e_:Qp)+'</span><span class="tt_toastText"></span>',s.lastElementChild.textContent=e,document.body.appendChild(s),setTimeout(()=>s.remove(),4e3)}async function vh(){try{Pe({t:"sessions"});let e=await Hi("sessions",3e3);if(e!==null&&Array.isArray(e.list))return or=_c(e.list),or}catch{}return null}async function ji(){if(await vh(),Xr===null||or===null||or<Xr)return null;let e=[...fe.values()].filter(o=>!o.exited).length,t=Math.max(0,or-e),r=t>0?w("msg.maxSessionsOthers",{count:t}):"",s=w("msg.maxSessions",{live:or,max:Xr,own:e,others:r});return O_(s),s}function I_(){return Xr!==null&&or!==null&&or>=Xr}function Wo(){return Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4)}function bh(e){return Fo.filter(t=>t?.bookName===e&&t?.enabled!==!1).length}function yo(e){let t=Number(e?.port),r=Number.isInteger(t)&&t!==22?":"+t:"",s=e?.auth==="key"?"key":e?.auth==="password"?"password":"agent",o=e?.agentForward===!0?" \xB7 fwd":"";return String(e?.username??"")+"@"+String(e?.host??"")+r+" \xB7 "+s+o}async function So(e,t){let r=await fetch("/api/dsh-tty/probe",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...e,bookRecord:t===!0})}),s=await r.json().catch(()=>({}));return s&&s.ok===!1&&s.error?{error:String(s.error)}:s&&s.result?{result:s.result}:{error:String(s&&s.error?s.error:w("error.probeHttp",{status:r.status}))}}function Co(e,t){if(!e)return w("msg.probing");let r=e,s=typeof r.tcp?.ms=="number"?r.tcp.ms:null,o=typeof r.auth?.ms=="number"?r.auth.ms:null,i=[];if(r.jump!==null&&typeof r.jump=="object"&&typeof r.jump.label=="string"&&r.jump.label!==""){let _=typeof r.jump.tcp?.ms=="number"?r.jump.tcp.ms:null,m=r.jump.tcp?.ok?_!==null?_+"ms":w("meta.reachable"):w("meta.unreachable");i.push(w("meta.jumpStage",{label:r.jump.label})+" "+m)}r.proxy!==null&&typeof r.proxy=="object"&&i.push(r.proxy.active===!0?w("meta.probeProxy"):w("meta.probeProxyOff")),r.tcp?.ok?i.push("TCP "+(s!==null?s+"ms":w("meta.reachable"))):r.tcp?.skipped===!0&&i.push(w("meta.probeTcpSkipped")),r.banner?.ok&&i.push(w("meta.probeBanner"));let n=r.hostkey?.state;if(n==="matched"?i.push(w("meta.hostKeyMatched")):n==="recorded"?i.push(w("meta.hostKeyRecorded")):n==="mismatch"&&i.push(w("meta.hostKeyMismatch")),r.auth?.ok){let _=o!==null?w("meta.authOkMs",{ms:o}):w("meta.authOk");return w("meta.probeOk",{detail:_+(i.length?" \xB7 "+i.join(" \xB7 "):"")})}let a=r.tcp?.skipped===!0?"":r.tcp?.error,l=(r.auth?.error||a||w("error.unknown"))+(i.length?" \xB7 "+i.join(" \xB7 "):"");return t?.prefix!==void 0?t.prefix+l:w("error.probeFailed",{detail:l})}async function Uo(){try{let t=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json();if(t.ok&&typeof t.config=="object"&&t.config!==null){let r=Gt;Ps(t.config),gt!==null&&Gt!==r&&Eo(gt)}}catch{}}function wh(e){gt!==null&&(e.target instanceof Element&&(gt.contains(e.target)||e.target.closest(".tt_tabAdd")!==null)||yt())}function Us(e,t){let r=t.getBoundingClientRect(),s=e.offsetWidth,o=e.offsetHeight,n=r.left+s>window.innerWidth-8?r.right-s:r.left;e.style.left=Math.max(8,Math.min(n,window.innerWidth-s-8))+"px";let a=r.bottom+6,d=r.top-o-6;e.style.top=(a+o>window.innerHeight-8&&d>=8?d:Math.min(a,Math.max(8,window.innerHeight-o-8)))+"px"}function N_(e){if(gt!==null){yt();return}Xt(),Uo(),vh().then(()=>{gt!==null&&Eo(gt)});let t=document.createElement("div");t.className="tt_addMenu",gt=t,Eo(t),document.body.appendChild(t),Us(t,e),document.addEventListener("mousedown",wh,!0)}function yt(){gt!==null&&(document.removeEventListener("mousedown",wh,!0),gt.remove(),gt=null)}function H_(e){if(ct!==null){Xt();return}yt();let t=document.createElement("div");t.className="tt_addMenu tt_tabMenu",ct=t,Ch(),document.body.appendChild(t),Us(t,e),document.addEventListener("mousedown",yh,!0),document.addEventListener("keydown",Sh,!0)}function Xt(){ct!==null&&(document.removeEventListener("mousedown",yh,!0),document.removeEventListener("keydown",Sh,!0),ct.remove(),ct=null)}function yh(e){ct!==null&&(e.target instanceof Element&&(ct.contains(e.target)||e.target.closest(".tt_tabMore")!==null)||Xt())}function Sh(e){e.key==="Escape"&&(e.preventDefault(),e.stopPropagation(),Xt())}function Ch(){let e=ct;if(e===null)return;e.textContent="";let t=U_();if(t.length===0){let s=document.createElement("div");s.className="tt_addMenuTitle",s.textContent=w("list.tabsAllVisible"),e.appendChild(s);return}for(let[s,o]of t){let i=o.label||w("panel.tabLabel",{n:Ho(s)}),n=z_(o),a=document.createElement("div");a.className="tt_addMenuRow tt_tabMenuRow",a.dataset.sid=s;let d=document.createElement("button");d.type="button",d.className="tt_addMenuItem tt_tabMenuItem",s===ke&&(d.dataset.active="");let l=document.createElement("span");l.className="tt_tabDot",l.dataset.state=Wi(o),d.appendChild(l);let _=document.createElement("span");_.className="tt_addMenuText tt_tabMenuText";let m=document.createElement("span");if(m.className="tt_addMenuMain",m.textContent=i,_.appendChild(m),n!==""){let p=document.createElement("span");p.className="tt_tabMenuMeta",p.textContent=n,_.appendChild(p)}d.appendChild(_),d.title=n===""?i:i+" \xB7 "+n,d.addEventListener("click",()=>{Yt(s),Xt()}),a.appendChild(d);let y=document.createElement("button");y.type="button",y.className="tt_addMenuEdit",y.innerHTML=Yi,y.title=w("btn.close"),y.setAttribute("aria-label",w("btn.closeTabAria",{label:i})),y.addEventListener("click",()=>{go(s)}),a.appendChild(y),e.appendChild(a)}let r=e.querySelector(".tt_tabMenuItem[data-active]");r!==null&&typeof r.scrollIntoView=="function"&&r.scrollIntoView({block:"nearest"})}var F_=40;function W_(e,t){let r=e.getBoundingClientRect();return Math.max(0,Math.min(r.right,t.right)-Math.max(r.left,t.left))}function U_(){let e=[];if(Re===null)return e;let t=Re.getBoundingClientRect();for(let[r,s]of fe){if(s.embedded===!0)continue;let o=Re.querySelector('[data-sid="'+r+'"]');o!==null&&W_(o,t)<F_&&e.push([r,s])}return e}function z_(e){return typeof e.target=="string"?e.target:""}function j_(){return w("panel.assistTitle")===Ri["panel.assistTitle"]?"zh":"en"}function $_(e){let t=e!=null&&typeof e.exitCode=="number"?String(e.exitCode):"?";return w("badge.assistFailed",{code:t})}function kr(){if(ir===null)return;let e=ke===null?void 0:cr.get(ke),t=Oi&&e!==void 0&&e.dismissed!==!0;if(ir.hidden=!t,t){let r=ir.querySelector(".tt_assistBadgeText");r!==null&&(r.textContent=$_(e))}}function kt(){Gr!==null&&(Gr.abort(),Gr=null),vr!==null&&(vr.remove(),vr=null),Cr=null,Ii=null}function q_(e){vr!==null&&(e.target instanceof Element&&(vr.contains(e.target)||e.target.closest(".tt_assistBadge")!==null)||kt())}function K_(e){e.key==="Escape"&&(e.preventDefault(),e.stopPropagation(),kt())}function G_(e){let t=ke;if(t===null)return;kt();let r=document.createElement("div");r.className="tt_addMenu tt_assistMenu",vr=r,Cr=t,Ii=e,document.body.appendChild(r),document.addEventListener("mousedown",q_,!0),document.addEventListener("keydown",K_,!0),xo(),Us(r,e),V_(t)}async function V_(e){let t=cr.get(e);if(t===void 0||t.busy===!0||(t.error===null||t.error===void 0)&&t.answer!==null&&t.answer!==void 0)return;t.busy=!0,t.answer=null,t.command="",t.error=null,xo();let r=new AbortController;Gr=r;try{let s=await fetch("/api/dsh-tty/assist",{method:"POST",cache:"no-store",headers:{"content-type":"application/json"},body:JSON.stringify({sid:e,kind:"failure",lang:j_()}),signal:r.signal}),o=await s.json().catch(()=>null);if(Cr!==e)return;t.busy=!1,s.ok&&o!==null&&o.ok===!0?(t.answer=String(o.answer!==void 0?o.answer:""),t.command=String(o.command!==void 0?o.command:"")):t.error=o!==null&&o.error!==void 0?String(o.error):"HTTP "+String(s.status)}catch(s){if(r.signal.aborted||Cr!==e)return;t.busy=!1,t.error=s instanceof Error?s.message:String(s)}finally{Gr===r&&(Gr=null),t.busy=!1,xo()}}function xo(){let e=vr;if(e===null)return;let t=Cr,r=t===null?void 0:cr.get(t);e.textContent="";let s=document.createElement("div");s.className="tt_assistHead";let o=document.createElement("span");if(o.className="tt_assistTitle",o.textContent=w("panel.assistTitle"),s.appendChild(o),r!==void 0&&typeof r.exitCode=="number"){let m=document.createElement("span");m.className="tt_assistCode",m.textContent="exit="+String(r.exitCode),s.appendChild(m)}e.appendChild(s);let i=r!==void 0&&typeof r.error=="string"&&r.error!=="",n=document.createElement("div");if(n.className="tt_assistBody",r===void 0||r.busy===!0){n.classList.add("tt_assistMuted","tt_assistBusy");let m=document.createElement("span");m.className="tt_assistSpin",n.appendChild(m),n.appendChild(document.createTextNode(w("status.assistThinking")))}else if(i)n.textContent=w("error.assistRequest",{message:r.error}),n.classList.add("tt_assistError");else{let m=r.answer!==null&&r.answer!==void 0?r.answer:"";n.textContent=m,n.classList.add("tt_assistAnswer"),m===""&&(n.hidden=!0)}if(e.appendChild(n),r===void 0||r.busy===!0)return;let a=r.command!=="";if(a){let m=document.createElement("div");m.className="tt_assistCmdWrap";let y=document.createElement("span");y.className="tt_assistCmdLabel",y.textContent=w("panel.assistCommand"),m.appendChild(y);let p=document.createElement("div");p.className="tt_assistCmd",p.textContent=r.command,m.appendChild(p),e.appendChild(m)}let d=document.createElement("div");if(d.className="tt_assistFoot",a){let m=document.createElement("button");m.type="button",m.className="tt_toolBtn tt_assistFill",m.textContent=w("btn.assistFill"),m.title=w("hint.assistFillNoEnter"),m.addEventListener("click",Y_),d.appendChild(m)}let l=document.createElement("button");l.type="button",l.className="tt_toolBtn",l.textContent=w(i?"btn.assistCopyError":"btn.assistCopy"),l.addEventListener("click",()=>{if(i){Ro(w("error.assistRequest",{message:r.error}));return}Ro(r.answer!==null&&r.answer!==void 0?r.answer:"")}),d.appendChild(l);let _=document.createElement("button");if(_.type="button",_.className="tt_toolBtn tt_assistClose",_.textContent=w("btn.assistClose"),_.addEventListener("click",()=>{kt()}),d.appendChild(_),e.appendChild(d),!i){let m=document.createElement("span");m.className="tt_assistNote",m.textContent=w(a?"hint.assistFillNoEnter":"hint.assistNoCommand"),e.appendChild(m)}Ii!==null&&Us(e,Ii)}function Y_(){let e=Cr,t=e===null?void 0:cr.get(e);if(e===null||t===void 0||t.command==="")return;Pe({t:"input",sid:e,d:""+t.command});let r=fe.get(e);kt(),X_(e),r!==void 0&&r.term!==null&&r.term.focus()}function X_(e){let t=cr.get(e);t!==void 0&&(t.dismissed=!0),kr()}function ko(e,t,r,s,o,i){let n=document.createElement("button");if(n.type="button",n.className="tt_addMenuItem",o===!0&&(n.setAttribute("data-soldout",""),n.title=w("btn.maxSessionsTitle")),i!==void 0){let l=document.createElement("span");l.className="tt_addMenuIcon",l.innerHTML=i,n.appendChild(l)}let a=document.createElement("span");a.className="tt_addMenuText";let d=document.createElement("span");if(d.className="tt_addMenuMain",d.textContent=t,a.appendChild(d),r!==""){let l=document.createElement("span");l.className="tt_addMenuSub",l.textContent=r,a.appendChild(l)}n.appendChild(a),n.addEventListener("click",s),e.appendChild(n)}function Eo(e){e.textContent="";let t=I_();ko(e,w("option.localTerminal"),w(ar==="tmux"?"hint.tmuxHosted":"hint.openInSessionCwd"),async()=>{await ji()||(yt(),Ds())},t,Gi);let r=document.createElement("div");r.className="tt_addMenuSep",e.appendChild(r);let s=document.createElement("div");s.className="tt_addMenuTitle",s.textContent=w("panel.sshBook"),e.appendChild(s);for(let i of Gt){if(i===null||typeof i!="object"||typeof i.name!="string"||i.name==="")continue;let n=document.createElement("div");n.className="tt_addMenuRow";let a=document.createElement("button");a.type="button",a.className="tt_addMenuItem",t&&(a.setAttribute("data-soldout",""),a.title=w("btn.maxSessionsTitle"));let d=document.createElement("span");d.className="tt_addMenuIcon",d.innerHTML=Zp;let l=document.createElement("span");l.className="tt_addMenuText";let _=document.createElement("span");_.className="tt_addMenuMain",_.textContent=i.name;let m=document.createElement("span");m.className="tt_addMenuSub";let y=bh(i.name),p=to(i.jump);m.textContent=yo(i)+(p===""?"":" "+w("meta.viaJump",{label:p}))+(typeof i.proxyCommand=="string"&&i.proxyCommand.trim()!==""?" "+w("meta.viaProxy"):"")+(y>0?" \xB7 \u21C4"+String(y):""),l.appendChild(_),l.appendChild(m),a.appendChild(d),a.appendChild(l),a.addEventListener("click",async()=>{if(await ji())return;yt();let h=ar==="tmux"&&i.persist!==!1?{persist:!0,persistName:Wo()}:{};Ds({t:"ssh",name:i.name,...h},i.name)});let c=document.createElement("button");c.type="button",c.className="tt_addMenuEdit",c.title=w("btn.sftpFileBrowse"),c.innerHTML=Rs,c.addEventListener("click",()=>{yt(),Qi({name:i.name})});let u=document.createElement("button");u.type="button",u.className="tt_addMenuEdit",u.title=w("btn.editConnection"),u.innerHTML=Do,u.addEventListener("click",()=>{yt(),Pc(i)}),n.appendChild(a),n.appendChild(c),n.appendChild(u),e.appendChild(n)}if(Gt.length===0){let i=document.createElement("div");i.className="tt_addMenuTitle",i.textContent=w("list.emptySshBook"),e.appendChild(i)}let o=document.createElement("div");o.className="tt_addMenuSep",e.appendChild(o),ko(e,w("option.sshConnect"),w("hint.sshConnect"),()=>{yt(),Pc()},!1,Zc)}function Pc(e){if(Vr!==null)return;let t=e!==null&&typeof e=="object"?e:null,r=t!==null,s=document.createElement("div");s.className="tt_sshBackdrop";let o=document.createElement("div");o.className="tt_sshCard";let i=document.createElement("div");i.className="tt_sshTitle",i.innerHTML=Zc+"<span></span>",i.lastElementChild.textContent=r?w("panel.editConnection",{name:String(t.name??"")}):w("panel.sshConnect"),o.appendChild(i);let n=Q=>{let se=document.createElement("div");return se.className="tt_sshSection",se.textContent=Q,se},a={},d=(Q,se,oe)=>{let re=document.createElement("label");re.className="tt_sshRow";let ne=document.createElement("span");ne.className="tt_cardLabel",ne.textContent=se,re.appendChild(ne);let ce;if(oe?.select!==void 0){ce=document.createElement("select");for(let le of oe.select){let ge=document.createElement("option");ge.value=le.value,ge.textContent=le.label,ce.appendChild(ge)}}else ce=document.createElement("input"),ce.type=oe?.type??"text",ce.placeholder=oe?.placeholder??"";return ce.className="tt_cardInput",ce.autocomplete="off",ce.spellcheck=!1,re.appendChild(ce),a[Q]=ce,re};o.appendChild(n(w("section.connection")));let l=document.createElement("div");l.className="tt_sshGrid",l.appendChild(d("host",w("field.host"),{placeholder:w("placeholder.host")})),l.appendChild(d("port",w("field.port"),{placeholder:"22"})),o.appendChild(l),o.appendChild(d("username",w("field.username"),{placeholder:"root"})),o.appendChild(n(w("section.auth"))),o.appendChild(d("auth",w("field.authMethod"),{select:[{value:"agent",label:w("option.authAgent")},{value:"key",label:w("option.authKey")},{value:"password",label:w("option.authPassword")}]}));let _=d("keyPath",w("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),m=d("passphrase",w("field.passphrase"),{type:"password"}),y=d("password",w("field.password"),{type:"password"}),p=(Q,se)=>{let oe=document.createElement("div");oe.className="tt_sshRow tt_envRow";let re=document.createElement("input");re.type="text",re.className="tt_cardInput",re.placeholder=w("placeholder.credRef"),re.title=w("hint.credRefCandidates"),re.autocomplete="off",re.spellcheck=!1;let ne=document.createElement("span");ne.className="tt_cardHint tt_envEmpty",ne.textContent=se,ne.hidden=!0,re.hidden=!0;let ce=document.createElement("div");ce.className="tt_envList",ce.dataset.hidden="";let le=[],ge=()=>{if(ce.textContent="",le.length===0){let ye=document.createElement("span");ye.className="tt_cardHint",ye.textContent=se,ce.appendChild(ye);return}let we=re.value.trim().toUpperCase(),Le=we===""?le:le.filter(ye=>ye.toUpperCase().includes(we));for(let ye of Le.slice(0,30)){let be=document.createElement("button");be.type="button",be.className="tt_envItem",be.textContent=ye;let xe="env:"+ye,Fe=null,tt=()=>{Fe!==null&&(clearTimeout(Fe),Fe=null),be.textContent=ye,delete be.dataset.danger};be.addEventListener("mousedown",Er=>Er.preventDefault()),be.addEventListener("click",()=>{let Er=Q.value;if(Er===""||Er.startsWith("env:")||Fe!==null){tt(),Q.value=xe,Q.focus(),Q.dispatchEvent(new Event("change"));return}be.textContent=w("list.credOverwrite",{name:ye}),be.dataset.danger="",Fe=setTimeout(tt,4e3)}),ce.appendChild(be)}if(Le.length>30){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=w("list.moreMatches",{count:Le.length-30}),ce.appendChild(ye)}else if(Le.length===0){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=w("list.noCredRef"),ce.appendChild(ye)}};return re.addEventListener("input",ge),re.addEventListener("focus",()=>{le.length>0&&delete ce.dataset.hidden}),re.addEventListener("blur",()=>{re.value.trim()===""&&(ce.dataset.hidden="")}),oe.appendChild(re),oe.appendChild(ne),oe.appendChild(ce),{row:oe,setNames(we){le=Array.isArray(we)?we:[];let Le=le.length>0;re.hidden=!Le,ne.hidden=Le,ge()}}},c=(Q,se)=>{let oe=document.createElement("div");oe.className="tt_sshRow tt_credRow";let re=document.createElement("label");re.className="tt_credToggle";let ne=document.createElement("input");ne.type="checkbox",ne.className="tt_cardCheckbox";let ce=document.createElement("span");ce.textContent=w("check.rememberCredential"),re.appendChild(ne),re.appendChild(ce),ne.checked=Ot!==null,re.title=w("hint.rememberCredential");let le=document.createElement("button");le.type="button",le.className="tt_toolBtn tt_credClear",le.textContent=w("btn.clearCredential"),le.dataset.hidden="";let ge=document.createElement("span");ge.className="tt_credStatus",oe.appendChild(re),oe.appendChild(le),oe.appendChild(ge);let we=(be,xe)=>{ge.textContent=be,ge.dataset.kind=xe},Le=async()=>{let be=$r(Q.value),xe=be!=="";if(re.hidden=xe,le.hidden=!xe,ge.hidden=!1,Zr()===null){ne.disabled=!0,ne.checked=!1,le.disabled=!0,we(w(Ot===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),"muted");return}if(ne.disabled=!1,!xe){ge.hidden=!0,we("","plain");return}let Fe=await Wc(be);if(Fe.unreported===!0){we(w("status.credUnreported",{ref:be}),"plain");return}if(Fe.error!==void 0){we(w("error.credStatusFailed",{error:Fe.error}),"error");return}let tt=Fe.view;we(tt.configured?w("status.credStored",{ref:be,source:tt.source!==""?w("meta.credSource",{source:tt.source}):""}):w("status.credUnknown",{ref:be}),tt.configured?"ok":"plain"),le.disabled=tt.configured!==!0||tt.writable!==!0};le.addEventListener("click",()=>{(async()=>{let be=$r(Q.value);if(be==="")return;let xe=await Uc(be);if(xe.error!==void 0){we(xe.error,"error");return}Q.value="",await Le()})()});let ye=async()=>{let be=await zc(ne.checked===!0,Q.value,a.host.value,a.port.value,a.username.value,se);return be.value!==void 0&&(Q.value=be.value,await Le()),be};return Q.addEventListener("change",()=>{Le()}),{row:oe,refresh:Le,storeIfRequested:ye}},u=p(a.passphrase,w("hint.noCredRefPassphrase")),h=p(a.password,w("hint.noCredRefPassword")),f=c(a.password,"PASSWORD");(async()=>{let Q=await Fc();u.setNames(Q),h.setNames(Q)})(),o.appendChild(_),o.appendChild(m),o.appendChild(u.row),o.appendChild(y),o.appendChild(f.row),o.appendChild(h.row),o.appendChild(n(w("section.jump")));let v=d("jumpHost",w("field.jumpHost"),{placeholder:w("placeholder.jumpHost")});o.appendChild(v);let S=document.createElement("label");S.className="tt_sshRow";let g=document.createElement("input");g.type="checkbox",g.className="tt_cardCheckbox";let x=document.createElement("span");x.className="tt_cardLabel",x.textContent=w("check.jumpOwnCred"),S.appendChild(g),S.appendChild(x),o.appendChild(S);let b=d("jumpUsername",w("field.jumpUsername"),{placeholder:"root"}),E=d("jumpAuth",w("field.jumpAuth"),{select:[{value:"",label:w("option.authInherit")},{value:"agent",label:w("option.authAgent")},{value:"key",label:w("option.authKey")},{value:"password",label:w("option.authPassword")}]}),P=d("jumpKeyPath",w("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),O=d("jumpPassphrase",w("field.passphrase"),{type:"password"}),F=d("jumpPassword",w("field.password"),{type:"password"});for(let Q of[b,E,P,O,F])o.appendChild(Q);let A=document.createElement("div");A.className="tt_cardHint",A.textContent=w("hint.jumpInherit"),o.appendChild(A),o.appendChild(n(w("section.proxyCommand")));let V=d("proxyCommand",w("field.proxyCommand"),{placeholder:w("placeholder.proxyCommand")});o.appendChild(V);let B=document.createElement("div");B.className="tt_cardHint",B.textContent=w("hint.proxyCommand"),o.appendChild(B);let M=document.createElement("div");M.className="tt_cardHint tt_sshProbeWarn",M.textContent=w("hint.proxyCommandDisabled"),o.appendChild(M);let U=()=>{let Q=a.proxyCommand.value.trim()!=="",se=mh,oe=se&&_h;M.textContent=w(se?"hint.proxyCommandDisabled":"hint.proxyCommandNotGranted"),M.style.display=Q&&!oe?"":"none"};a.proxyCommand.addEventListener("input",U),U();let I=()=>{let Q=eo(a.jumpHost.value);if(Q===void 0)return;if(g.checked!==!0)return Q;let se={...Q},oe=a.jumpUsername.value.trim();oe!==""&&(se.username=oe);let re=a.jumpAuth.value;(re==="agent"||re==="key"||re==="password")&&(se.auth=re);let ne=a.jumpKeyPath.value.trim();return ne!==""&&(se.keyPath=ne),a.jumpPassphrase.value!==""&&(se.passphrase=a.jumpPassphrase.value),a.jumpPassword.value!==""&&(se.password=a.jumpPassword.value),se},C=()=>{let Q=a.proxyCommand.value.trim();return Q===""?void 0:Q},L=()=>{let Q=eo(a.jumpHost.value)!==void 0,se=Q&&g.checked===!0;S.style.display=Q?"":"none";for(let oe of[b,E,P,O,F])oe.style.display=se?"":"none";P.style.display=se&&a.jumpAuth.value==="key"?"":"none",O.style.display=se&&a.jumpAuth.value==="key"?"":"none",F.style.display=se&&a.jumpAuth.value==="password"?"":"none",A.style.display=Q?"":"none"};a.jumpHost.addEventListener("input",L),a.jumpAuth.addEventListener("change",L),g.addEventListener("change",L),o.appendChild(n(w("section.options")));let T=document.createElement("label");T.className="tt_cardRow";let D=document.createElement("input");D.type="checkbox",D.className="tt_cardCheckbox";let N=document.createElement("span");N.className="tt_cardLabel",N.textContent=w("check.agentForward"),T.appendChild(D),T.appendChild(N),o.appendChild(T),o.appendChild(d("hostKeyAlias",w("field.hostKeyAlias"),{placeholder:w("placeholder.hostKeyAlias")}));let G=document.createElement("span");G.className="tt_cardHint",G.textContent=w("hint.hostKeyAlias"),o.appendChild(G);let $=document.createElement("label");$.className="tt_cardRow";let Y=document.createElement("input");Y.type="checkbox",Y.className="tt_cardCheckbox";let H=document.createElement("span");H.className="tt_cardLabel",H.textContent=w("check.persist"),$.appendChild(Y),$.appendChild(H),Y.checked=ar==="tmux",ar==="tmux"&&o.appendChild($);let k=document.createElement("label");k.className="tt_cardRow";let W=document.createElement("input");W.type="checkbox",W.className="tt_cardCheckbox";let q=document.createElement("span");q.className="tt_cardLabel",q.textContent=w("check.saveToBook"),k.appendChild(W),k.appendChild(q),o.appendChild(k);let j=d("name",w("field.bookName"),{placeholder:w("placeholder.bookName")});if(j.style.display="none",o.appendChild(j),W.addEventListener("change",()=>{j.style.display=W.checked?"":"none",W.checked&&a.name.value.trim()===""&&a.host.value.trim()!==""&&(a.name.value=a.host.value.trim()),W.checked&&a.name.focus()}),r){k.style.display="none",a.name.value=String(t.name??""),j.style.display="",a.host.value=String(t.host??""),a.port.value=String(t.port??22),a.username.value=String(t.username??""),a.auth.value=t.auth==="key"||t.auth==="password"?String(t.auth):"agent",a.keyPath.value=String(t.keyPath??""),a.passphrase.value=String(t.passphrase??""),a.password.value=String(t.password??"");let Q=t.jump!==null&&typeof t.jump=="object"?t.jump:null;if(a.jumpHost.value=to(Q),Q!==null){let se=Q.auth!==void 0||Q.keyPath!==void 0||Q.password!==void 0||Q.passphrase!==void 0;g.checked=se,se&&(a.jumpUsername.value=String(Q.username??""),a.jumpAuth.value=Q.auth==="key"||Q.auth==="password"?String(Q.auth):"",a.jumpKeyPath.value=String(Q.keyPath??""),a.jumpPassphrase.value=String(Q.passphrase??""),a.jumpPassword.value=String(Q.password??""))}D.checked=t.agentForward===!0,a.hostKeyAlias.value=String(t.hostKeyAlias??""),a.proxyCommand.value=String(t.proxyCommand??""),U(),Y.checked=ar==="tmux"}let X=document.createElement("div");X.className="tt_sshStatus";let J=document.createElement("div");J.className="tt_sshError";let ae=document.createElement("div");ae.className="tt_sshProbeResult",X.appendChild(J),X.appendChild(ae),o.appendChild(X),L();let he=()=>a.hostKeyAlias.value.trim(),_e=()=>{J.textContent="";let Q=a.host.value.trim(),se=a.username.value.trim(),oe=Number(a.port.value);if((!Number.isInteger(oe)||oe<1||oe>65535)&&(oe=22),Q===""||se==="")return J.textContent=w("error.hostUserRequired"),null;let re=a.auth.value,ne={host:Q,port:oe,username:se,auth:re},ce=I();ce!==void 0&&(ne.jump=ce);let le=C();if(le!==void 0&&(ne.proxyCommand=le),re==="key"){let we=a.keyPath.value.trim();if(we==="")return J.textContent=w("error.keyPathRequired"),null;ne.keyPath=we;let Le=a.passphrase.value;Le!==""&&(ne.passphrase=Le)}if(re==="password"){let we=a.password.value;if(we==="")return J.textContent=w("error.passwordRequired"),null;ne.password=we}D.checked&&(ne.agentForward=!0);let ge=he();return ge!==""&&(ne.hostKeyAlias=ge),ne},Z=document.createElement("div");Z.className="tt_sshActions";let Ce=document.createElement("div");Ce.className="tt_sshActionsGroup";let He=document.createElement("div");He.className="tt_sshActionsGroup",Z.appendChild(Ce),Z.appendChild(He);let Ee=document.createElement("button");Ee.type="button",Ee.className="tt_toolBtn",Ee.textContent=w("btn.cancel");let Oe=document.createElement("button");Oe.type="button",Oe.className="tt_cardSave",Oe.textContent=w("btn.connect"),Ce.appendChild(Ee);let Ue=document.createElement("button");Ue.type="button",Ue.className="tt_toolBtn",Ue.textContent=w("btn.fileBrowse"),Ue.title=w("btn.browseTitle"),Ue.addEventListener("click",()=>{J.textContent="";let Q=a.host.value.trim(),se=a.username.value.trim(),oe=Number(a.port.value);if((!Number.isInteger(oe)||oe<1||oe>65535)&&(oe=22),Q===""||se===""){J.textContent=w("error.hostUserRequired");return}let re=a.auth.value,ne={host:Q,port:oe,username:se,auth:re},ce=I();ce!==void 0&&(ne.jump=ce);let le=C();if(le!==void 0&&(ne.proxyCommand=le),re==="key"){let we=a.keyPath.value.trim();if(we===""){J.textContent=w("error.keyPathRequired");return}ne.keyPath=we;let Le=a.passphrase.value;Le!==""&&(ne.passphrase=Le)}if(re==="password"){let we=a.password.value;if(we===""){J.textContent=w("error.passwordRequired");return}ne.password=we}D.checked&&(ne.agentForward=!0);let ge=he();ge!==""&&(ne.hostKeyAlias=ge),nr(),Qi(ne)}),Ce.appendChild(Ue);let te=null;r&&(te=document.createElement("button"),te.type="button",te.className="tt_toolBtn",te.textContent=w("btn.saveEdit"),te.addEventListener("click",()=>{J.textContent="";let Q=a.host.value.trim(),se=a.username.value.trim();if(Q===""||se===""){J.textContent=w("error.hostUserRequired");return}let oe=Number(a.port.value);(!Number.isInteger(oe)||oe<1||oe>65535)&&(oe=22);let re=a.auth.value,ce={name:a.name.value.trim()||Q,host:Q,port:oe,username:se,auth:re,keyPath:re==="key"?a.keyPath.value.trim():"",passphrase:a.passphrase.value,password:a.password.value,agentForward:D.checked,hostKeyAlias:he(),persist:Y.checked},le=I();if(le!==void 0&&(ce.jump=le),ce.proxyCommand=a.proxyCommand.value.trim(),re==="key"&&ce.keyPath===""){J.textContent=w("error.keyPathRequired");return}te!==null&&(te.disabled=!0),(async()=>{let ge=await f.storeIfRequested();if(ge.error!==void 0){J.textContent=ge.error,te!==null&&(te.disabled=!1);return}ge.value!==void 0&&(ce.password=ge.value);let we=await Z_(String(t.name??""),ce);if(te!==null&&(te.disabled=!1),we!==void 0){J.textContent=w("error.saveCredFailed",{error:we});return}nr()})()}),Ce.appendChild(te));let de=document.createElement("button");de.type="button",de.className="tt_toolBtn",de.textContent=w("btn.probe"),de.title=w("btn.probeTitle"),de.addEventListener("click",()=>{let Q=_e();Q!==null&&(ae.className="tt_sshProbeResult",ae.textContent=w("msg.probing"),de.disabled=!0,So(Q,!1).then(se=>{de.disabled=!1,se.result?(ae.className="tt_sshProbeResult"+(se.result.auth?.ok===!0?" tt_sshProbeOk":" tt_sshProbeBad"),ae.textContent=Co(se.result)):(ae.className="tt_sshProbeResult tt_sshProbeBad",ae.textContent=w("error.probeFailed",{detail:String(se.error||w("error.unknown"))}))}))}),Ce.appendChild(de),He.appendChild(Oe),o.appendChild(Z);let ve=()=>{_.style.display=a.auth.value==="key"?"":"none",m.style.display=a.auth.value==="key"?"":"none",u.row.style.display=a.auth.value==="key"?"":"none",y.style.display=a.auth.value==="password"?"":"none",h.row.style.display=a.auth.value==="password"?"":"none",f.row.style.display=a.auth.value==="password"?"":"none"};a.auth.addEventListener("change",ve),ve(),f.refresh(),Ee.addEventListener("click",()=>nr()),s.addEventListener("mousedown",Q=>{Q.target===s&&nr()}),Oe.addEventListener("click",async()=>{J.textContent="";let Q=await ji();if(Q!==null){J.textContent=Q;return}let se=a.host.value.trim(),oe=a.username.value.trim(),re=Number(a.port.value);if((!Number.isInteger(re)||re<1||re>65535)&&(re=22),se===""||oe===""){J.textContent=w("error.hostUserRequired");return}let ne=a.auth.value,ce={t:"ssh",host:se,port:re,username:oe,auth:ne},le=I();le!==void 0&&(ce.jump=le);let ge=C();if(ge!==void 0&&(ce.proxyCommand=ge),ne==="key"){let xe=a.keyPath.value.trim();xe!==""&&(ce.keyPath=xe);let Fe=a.passphrase.value;Fe!==""&&(ce.passphrase=Fe)}if(ne==="password"){let xe=a.password.value;xe!==""&&(ce.password=xe)}D.checked&&(ce.agentForward=!0);let we=he();we!==""&&(ce.hostKeyAlias=we),Y.checked&&(ce.persist=!0,ce.persistName=Wo());let Le=re!==22?oe+"@"+se+":"+re:oe+"@"+se,ye=xe=>{nr(),ue!==null&&Ds(ce,xe!==""?xe:Le)};if(!W.checked){ye("");return}let be=a.name.value.trim()||se;Oe.disabled=!0,(async()=>{let xe=await f.storeIfRequested();if(xe.error!==void 0){J.textContent=xe.error,Oe.disabled=!1;return}let Fe=xe.value??ce.password??"",tt=await J_({name:be,host:se,port:re,username:oe,auth:ne,keyPath:ce.keyPath??"",passphrase:ce.passphrase??"",password:Fe,agentForward:D.checked,hostKeyAlias:he(),persist:Y.checked,...le!==void 0?{jump:le}:{},proxyCommand:a.proxyCommand.value.trim()});if(Oe.disabled=!1,tt!==void 0){J.textContent=w("error.saveBookFailed",{error:tt});return}ye(be)})()}),s.appendChild(o),document.body.appendChild(s),Vr=s,a.host.focus()}function nr(){Vr!==null&&(Vr.remove(),Vr=null)}async function J_(e){let t=[...Gt.filter(r=>r?.name!==e.name),e];try{let r=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({sshHosts:t})}),s=await r.json().catch(()=>({}));if(!r.ok||!s.ok)return String(s.error||"HTTP "+r.status);Ps(s.config);return}catch(r){return String(r&&r.message?r.message:r)}}async function Z_(e,t){if(t.name!==e&&Gt.some(s=>s?.name===t.name))return w("error.bookNameTaken",{name:t.name});let r=Gt.map(s=>s?.name===e?t:s);try{let s=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({sshHosts:r})}),o=await s.json().catch(()=>({}));if(!s.ok||!o.ok)return String(o.error||"HTTP "+s.status);Ps(o.config);return}catch(s){return String(s&&s.message?s.message:s)}}function Q_(e,t,r){let s=Wr(r,ke);if(kh(s))return;let o=document.createElement("div");o.className="tt_sftpDualCard";let i=document.createElement("div");i.className="tt_sftpTitleRow";let n=document.createElement("div");n.className="tt_sshTitle",n.innerHTML=Rs+"<span></span>",n.lastElementChild.textContent=w("panel.sftpDual",{label:t});let a=document.createElement("button");a.type="button",a.className="tt_close",a.title=w("btn.close"),a.innerHTML=Vi,a.addEventListener("click",()=>ts(s)),i.appendChild(n),i.appendChild(a),o.appendChild(i);let d=document.createElement("div");d.className="tt_sftpStatus";let l=(N,G)=>{d.textContent=N,G===void 0?delete d.dataset.state:d.dataset.state=G},_=!1,m=(N,G)=>{if(!(_||p.local.busy||p.remote.busy)){_=!0;for(let $ of[p.local,p.remote])$.setBusy(!0);l(N,"busy"),Promise.resolve().then(G).catch($=>{($===null||typeof $!="object"||$.name!=="TransferCanceledError")&&M.fail(w("status.failed")),l(String($&&$.message?$.message:$),"error")}).finally(()=>{_=!1;for(let $ of[p.local,p.remote])$.setBusy(!1)})}},y=N=>{p[N].bar.after(h),h.style.display="",f.focus(),f.select()},p={},c=(N,G)=>{if(N===void 0||N==="")throw new Error(w("error.dirNotReady"));return N.endsWith("/")||N.endsWith("\\")?N+G:N+"/"+G},u=(N,G)=>{let $={kind:N,path:"",busy:!1},Y=document.createElement("div");Y.className="tt_sftpPane";let H=document.createElement("div");H.className="tt_sftpPaneHead";let k=document.createElement("span");k.textContent=G;let W=document.createElement("span");W.className="tt_sftpPaneMeta",H.appendChild(k),H.appendChild(W),Y.appendChild(H);let q=document.createElement("div");q.className="tt_sftpBar";let j=document.createElement("input");j.type="text",j.className="tt_sftpPath",j.placeholder=w(N==="local"?"placeholder.localPath":"placeholder.remotePath"),j.spellcheck=!1,j.autocomplete="off";let X=document.createElement("button");X.type="button",X.className="tt_toolBtn",X.innerHTML=Po+"<span>"+w("btn.refresh")+"</span>";let J=document.createElement("button");J.type="button",J.className="tt_toolBtn",J.innerHTML=Vc+"<span>"+w("btn.mkdir")+"</span>";let ae=document.createElement("button");ae.type="button",ae.className="tt_toolBtn tt_toolToggle",ae.textContent=w("btn.hiddenFiles"),ae.title=w("btn.hiddenFilesTitle"),_r&&(ae.dataset.on=""),q.appendChild(j),q.appendChild(X),q.appendChild(J),q.appendChild(ae),Y.appendChild(q);let he=document.createElement("div");he.className="tt_sftpList",Y.appendChild(he),$.bar=q;let _e=te=>{$.busy=te;for(let de of[X,J])de.disabled=te;j.disabled=te},Z=async(te,de)=>{let ve=N==="local"?"/api/dsh-tty/local-fs/":"/api/dsh-tty/sftp/",Q=N==="local"?de:{...e,...de},se=await fetch(ve+te,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q)}),oe=await se.json().catch(()=>({}));if(!se.ok||oe.ok!==!0)throw new Error(String(oe.error||"HTTP "+se.status));return oe},Ce=(te,de)=>{if(!($.busy||_))return _e(!0),l(te,"busy"),Promise.resolve().then(de).catch(ve=>l(String(ve&&ve.message?ve.message:ve),"error")).finally(()=>_e(!1))},He=(te,de)=>{if(te===void 0||te==="")throw new Error(w("error.dirNotReady"));return te.endsWith("/")||te.endsWith("\\")?te+de:te+"/"+de},Ee=te=>{let de=He($.path,te.name),ve=[];te.isDir===!0?ve.push(w("meta.dir")):ve.push(Ze(Number(te.size))||"\u2014");let Q=Th(Number(te.mtime));Q!==""&&ve.push(Q);let se=b(te.isDir?Rs:te.isSymlink?Kc:qc,te.name,ve.join(" \xB7 "),te.isDir===!0?"dir":te.isSymlink===!0?"link":"file"),oe=()=>$.loadDir($.path),re=N==="local"?p.remote:p.local;return te.isDir===!0&&se.addEventListener("click",ne=>{ne.target instanceof Element&&ne.target.closest(".tt_sftpAct")!==null||$.loadDir(de)}),E(se,N==="local"?Yc:Xc,w("btn.transferTo",{target:w(N==="local"?"meta.remote":"meta.local"),path:re.path}),()=>{if($.path===""||re.path===""){l(w("error.transferDirsNotReady"),"error");return}M.reset(),M.pulse(0),m(w("msg.transferring",{name:te.name}),async()=>{let ne=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"start",direction:N==="local"?"up":"down",...e,localPath:N==="local"?de:He(re.path,te.name),remotePath:N==="local"?He(re.path,te.name):de})}),ce=await ne.json().catch(()=>({}));if(!ne.ok||ce.ok!==!0)throw M.fail(w("error.transferFailed")),new Error(String(ce.error||"HTTP "+ne.status));let le=ce.job?.id;if(typeof le!="string"||le==="")throw M.fail(w("error.transferFailed")),new Error(w("error.noTaskId"));await U(le,te.name)==="canceled"?(M.reset(),l(w("msg.transferCanceled",{name:te.name}))):(M.done(w("status.done")),setTimeout(()=>M.reset(),1500),l(w("msg.transferred",{name:te.name}))),await re.loadDir(re.path)})}),N!=="local"&&te.isDir!==!0&&E(se,Gc,w("btn.download",{name:te.name}),()=>{O(te,de)}),E(se,Do,w("btn.rename",{name:te.name}),()=>{f.placeholder=w("placeholder.newName"),f.value=te.name,y(N),g=async()=>{let ne=f.value.trim();ne===""||ne===te.name||(x(),await $.runTask(w("msg.renaming",{name:te.name}),async()=>{await Z("rename",{from:de,to:He($.path,ne)}),await oe()}))}}),P(se,()=>$.runTask(w("msg.deleting",{name:te.name}),async()=>{await Z("remove",{path:de,recursive:te.isDir===!0}),await oe(),l(w("msg.deleted",{name:te.name}))}),te),se},Oe=te=>{if(he.textContent="",$.path!==""&&$.path!=="/"&&/^[A-Za-z]:[\\/]?$/.test($.path)===!1){let Q=b(Ao,w("list.parentDir"),"","up");Q.addEventListener("click",()=>{let se=N==="local"?rm($.path):Rh($.path);se!==null&&$.loadDir(se)}),he.appendChild(Q)}let de=bi(te,_r);if(de.length===0){let Q=document.createElement("div");Q.className="tt_addMenuTitle",Q.textContent=te.length>0?w("list.hiddenOnly"):w("list.emptyDir"),he.appendChild(Q);return}let ve=500;for(let Q of de.slice(0,ve))Q===null||typeof Q!="object"||typeof Q.name!="string"||Q.name===""||he.appendChild(Ee(Q));if(de.length>ve){let Q=document.createElement("div");Q.className="tt_addMenuTitle",Q.textContent=w("list.truncated",{rest:de.length-ve,total:de.length}),he.appendChild(Q)}};$.loadDir=async te=>{try{let de=await Z("list",{path:te??$.path});$.path=typeof de.path=="string"&&de.path!==""?de.path:$.path,j.value=$.path;let ve=Array.isArray(de.entries)?de.entries:[];$.rawEntries=ve,Oe(ve),W.textContent=w("list.itemCount",{count:bi(ve,_r).length}),l($.path)}catch(de){l(String(de&&de.message?de.message:de),"error")}},$.runTask=Ce,$.setBusy=_e,p[N]=$,ae.addEventListener("click",()=>{P_(!_r)});let Ue=te=>{ae!==null&&(te?ae.dataset.on="":delete ae.dataset.on),$.rawEntries=$.rawEntries??[],Oe($.rawEntries),W.textContent=w("list.itemCount",{count:bi($.rawEntries,te).length})};return bo.add(Ue),$.onShowHidden=Ue,X.addEventListener("click",()=>{$.runTask(w("list.loading"),()=>$.loadDir($.path))}),J.addEventListener("click",()=>{$.busy||_||(f.placeholder=w("placeholder.newDirName"),f.value="",y(N),g=async()=>{let te=f.value.trim();te!==""&&(x(),await $.runTask(w("msg.creatingDir",{name:te}),async()=>{await Z("mkdir",{path:He($.path,te),parents:!0}),await $.loadDir($.path)}))})}),j.addEventListener("keydown",te=>{if(te.key!=="Enter"||(te.preventDefault(),$.busy||_))return;let de=j.value.trim();de!==""&&$.runTask(w("list.loading"),()=>$.loadDir(de))}),Y},h=document.createElement("div");h.className="tt_sftpEditor",h.style.display="none";let f=document.createElement("input");f.type="text",f.className="tt_cardInput",f.spellcheck=!1,f.autocomplete="off";let v=document.createElement("button");v.type="button",v.className="tt_toolBtn",v.textContent=w("btn.ok");let S=document.createElement("button");S.type="button",S.className="tt_toolBtn",S.textContent=w("btn.cancel"),h.appendChild(f),h.appendChild(v),h.appendChild(S);let g=null,x=()=>{h.style.display="none",f.value="",g=null};v.addEventListener("click",()=>{g?.()}),S.addEventListener("click",x),f.addEventListener("keydown",N=>{N.key==="Enter"?(N.preventDefault(),g?.()):N.key==="Escape"&&(N.stopPropagation(),x())});let b=(N,G,$,Y)=>{let H=document.createElement("button");H.type="button",H.className="tt_sftpRow";let k=document.createElement("span");k.className="tt_sftpIcon",k.innerHTML=N,Y!==void 0&&(k.dataset.kind=Y);let W=document.createElement("span");if(W.className="tt_sftpName",W.textContent=G,W.title=G,H.appendChild(k),H.appendChild(W),$!==""){let q=document.createElement("span");q.className="tt_sftpMeta",q.textContent=$,H.appendChild(q)}return H},E=(N,G,$,Y)=>{let H=document.createElement("button");H.type="button",H.className="tt_sftpAct",H.innerHTML=G,H.title=$,H.addEventListener("click",k=>{k.stopPropagation(),Y()}),N.appendChild(H)},P=(N,G,$)=>{let Y=document.createElement("button");Y.type="button",Y.className="tt_sftpAct",Y.innerHTML=qr,Y.title=$.isDir?w("btn.deleteEntryDir",{name:$.name}):w("btn.deleteEntry",{name:$.name});let H=null;Y.addEventListener("click",k=>{if(k.stopPropagation(),H!==null){clearTimeout(H),H=null,Y.innerHTML=qr,delete Y.dataset.danger,G();return}Y.textContent=w("btn.confirm"),Y.dataset.danger="",H=setTimeout(()=>{H=null,Y.innerHTML=qr,delete Y.dataset.danger},4e3)}),N.appendChild(Y)},O=(N,G)=>p.remote.runTask(w("msg.downloading",{name:N.name}),async()=>{M.reset();let $;try{$=await Ah({makeBody:Y=>({...e,path:G,...Y>0?{offset:Y}:{}}),onProgress:(Y,H)=>M.set(Y,H),maxMb:Kt.maxDownloadMb,registerCancel:Y=>M.setCancel(Y),onResume:Y=>l(w("msg.downloadResuming",{name:N.name,offset:Ze(Y)||String(Y)+" B"}),"busy")})}catch(Y){if(Jr(Y)){M.reset(),l(w("msg.downloadCanceled",{name:N.name}));return}throw M.fail(w("error.downloadFailed")),Y}M.done(w("status.done")),Dh($,N.name),setTimeout(()=>M.reset(),1500),l(w("msg.downloaded",{name:N.name,size:Ze($.size)||String($.size)+" B"}))}),F=u("local",w("meta.local")),A=u("remote",w("meta.remote"));p.local.wrap=F,p.remote.wrap=A;let V=document.createElement("div");V.className="tt_sftpDual",V.appendChild(F),V.appendChild(A),o.appendChild(V),o.appendChild(h);let B=document.createElement("div");B.className="tt_sftpFoot";let M=Mh();B.appendChild(M.el),B.appendChild(d),o.appendChild(B);let U=async(N,G)=>{let $=!1;M.setCancel(()=>{$||($=!0,fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"cancel",job:N})}).catch(()=>{}))});try{for(;;){await new Promise(W=>setTimeout(W,400));let Y=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"status",job:N})}),H=await Y.json().catch(()=>({}));if(!Y.ok||H.ok!==!0){if($)return"canceled";throw new Error(String(H.error||"HTTP "+Y.status))}let k=H.job;if(k===null||typeof k!="object")throw new Error(w("error.invalidTaskState"));if(k.state==="running"){let W=typeof k.current=="string"&&k.current!==""?k.current:G;l(w("msg.transferring",{name:W}),"busy"),Number.isFinite(k.total)&&k.total>0?M.set(Number(k.bytes)||0,k.total):M.pulse(Number(k.bytes)||0);continue}if(k.state==="canceled")return"canceled";if(k.state!=="done")throw new Error(String(k.error||w("error.transferFailed")));return"done"}}finally{M.setCancel(null)}},I=(N,G)=>{G?N.wrap.dataset.drag="":delete N.wrap.dataset.drag},C=N=>Array.isArray(N?.types)&&N.types.includes("Files");for(let N of[p.local,p.remote]){let G=N.wrap,$=0;G.addEventListener("dragenter",Y=>{N.kind!=="remote"||!C(Y.dataTransfer)||(Y.preventDefault(),$+=1,I(N,!0))}),G.addEventListener("dragover",Y=>{N.kind==="remote"&&(Y.preventDefault(),Y.dataTransfer!==null&&(Y.dataTransfer.dropEffect="copy"))}),G.addEventListener("dragleave",()=>{$=Math.max(0,$-1),$===0&&I(N,!1)}),G.addEventListener("drop",Y=>{$=0,I(N,!1);let H=gc(N.kind,Y.dataTransfer);if(!H.accept){H.reason==="wrongPane"&&(Y.preventDefault(),l(w("error.dropOnLocalPane"),"error"));return}Y.preventDefault(),!(_||p.remote.busy)&&Ph(Y.dataTransfer).then(k=>{(k.length>0||k._limitExceeded===!0)&&L(p.remote,k)})})}let L=async(N,G)=>{let $=Kt;if($.maxUploadFiles>0&&G.length>$.maxUploadFiles){l(w("error.uploadCountExceeded",{max:$.maxUploadFiles,count:G.length}),"error");return}let Y=$.maxUploadMb>0?$.maxUploadMb*1024*1024:0,H=G.find(k=>Y>0&&(k.file?.size??0)>Y);if(H!==void 0){l(w("error.uploadTooBig",{size:Ze(Y),name:String(H.relPath??"")}),"error");return}if(G._limitExceeded===!0){l(w("error.uploadTotalTooBig"),"error");return}await m(w("msg.uploading"),async()=>{if(N.path===""){l(w("error.transferDirsNotReady"),"error");return}for(let q of vc(G))await fetch("/api/dsh-tty/sftp/mkdir",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...e,path:c(N.path,q),parents:!0})}).catch(()=>{});M.reset();let k={stopped:!1,abort:null};M.setCancel(()=>k.abort?.());let W=0;try{let q=0;for(let j of G){if(k.stopped)break;q+=1,k.abort=null;try{await Lh(j.file,c(N.path,j.relPath),{spec:e,label:`${String(q)}/${String(G.length)} ${j.relPath}`,cancelRef:k,onProgress:(X,J)=>Number.isFinite(J)&&J>0?M.set(X,J):M.pulse(X),onLabel:X=>l(w("msg.uploadingName",{name:X}),"busy")}),W+=1}catch(X){if(Jr(X)||k.stopped)break;throw X}}}finally{M.setCancel(null)}k.stopped?(M.reset(),l(w("msg.uploadCanceled",{done:W,total:G.length}))):(M.done(w("status.allDone")),setTimeout(()=>M.reset(),1500),l(w("msg.uploadDoneCount",{count:G.length}))),await N.loadDir(N.path)})},T=Io(),D=T===null?420:Math.round(T.height*.56);Eh(o,w("panel.sftpDual",{label:t}),D,s),p.local.loadDir(""),p.remote.loadDir(""),wo=()=>{for(let N of[p.local,p.remote])N!==void 0&&typeof N.onShowHidden=="function"&&bo.delete(N.onShowHidden)}}var Vt=null,It=null;function xh(){return It!==null&&so(It.ownerKey,ke)?It.ownerKey:Wr(void 0,ke)}var kh=(e=xh())=>Vt!==null||It!==null&&It.ownerKey===e;function Eh(e,t,r,s){let o=Wr(s,ke),i=xt!==null&&xt.ownerKey===o;if(ue!==null&&!Ve&&mt!==null&&!i)try{let a=hh({title:t,side:"bottom",size:r,min:200,ownerSid:o,onClose:()=>ts(o)});a.element.appendChild(e),It=a;return}catch(a){console.warn("[dsh-tty] SFTP \u6302\u5230\u7EC8\u7AEF\u6302\u8F7D\u4F4D\u5931\u8D25\uFF0C\u56DE\u9000\u5BF9\u8BDD\u6846\uFF1A"+(a instanceof Error?a.message:String(a)))}let n=document.createElement("div");n.className="tt_sshBackdrop",n.appendChild(e),n.addEventListener("mousedown",a=>{a.target===n&&ts()}),document.body.appendChild(n),Vt=n}var Ts=null;function em(){let e=Ts;if(Ts=null,e!==null)try{e.click()}catch{}}function tm(e){let t=new TextEncoder().encode(e),r="";for(let s of t)r+=String.fromCharCode(s);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Lh(e,t,r){let{spec:s,label:o="",cancelRef:i,onProgress:n,onLabel:a,onDone:d}=r;return o!==""&&typeof a=="function"&&a(o),new Promise((l,_)=>{let m=tm(JSON.stringify({...s,path:t})),y=new XMLHttpRequest;i.abort=()=>{i.stopped=!0,y.abort()},y.open("POST","/api/dsh-tty/sftp/upload"),y.setRequestHeader("x-dsh-sftp-meta",m),y.upload.addEventListener("progress",u=>{u.lengthComputable?n(u.loaded,u.total):n(0,NaN)});let p=!1,c=u=>{p||(p=!0,u===null?l():_(u))};y.addEventListener("load",()=>{if(y.status===200){d?.(),c(null);return}if(i.stopped)return;let u="HTTP "+y.status;try{let h=JSON.parse(y.responseText);h!==null&&typeof h=="object"&&typeof h.error=="string"&&(u=h.error)}catch{}c(new Error(u))}),y.addEventListener("error",()=>{if(i.stopped){c(new es);return}c(new Error(w("error.networkError")))}),y.addEventListener("abort",()=>{c(new es)}),y.send(e)})}function Th(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let r=s=>String(s).padStart(2,"0");return t.getFullYear()+"-"+r(t.getMonth()+1)+"-"+r(t.getDate())+" "+r(t.getHours())+":"+r(t.getMinutes())}function Rh(e){let t=String(e).replace(/\/+$/,""),r=t.lastIndexOf("/");return r<=0?"/":t.slice(0,r)}function rm(e){let t=String(e).trim();if(t===""||(t=t.replace(/[\\/]+$/,""),t===""))return null;let r=t.match(/^([A-Za-z]:)(.*)$/);if(r!==null){let o=r[2];if(o==="")return null;let i=Math.max(o.lastIndexOf("\\"),o.lastIndexOf("/"));return i<=0?r[1]+"\\":r[1]+o.slice(0,i)}if(t.startsWith("\\\\")||t.startsWith("//")){let o=t.slice(2);if(o.split(/[\\/]/).filter(a=>a!=="").length<=2)return null;let n=Math.max(o.lastIndexOf("\\"),o.lastIndexOf("/"));return t.slice(0,2)+o.slice(0,n)}let s=t.lastIndexOf("/");return s<=0?s===0?"/":null:t.slice(0,s)}function vs(e,t){return e.endsWith("/")?e+t:e+"/"+t}function Mh(){let e=document.createElement("div");e.className="tt_sftpProgress";let t=document.createElement("div");t.className="tt_sftpTrack";let r=document.createElement("div");r.className="tt_sftpFill",t.appendChild(r);let s=document.createElement("span");s.className="tt_sftpPct",s.textContent="";let o=document.createElement("button");o.type="button",o.className="tt_sftpCancel",o.title=w("btn.cancelTransfer"),o.innerHTML=Yi,o.style.display="none";let i=null;o.addEventListener("click",p=>{p.stopPropagation();let c=i;c!==null&&(o.disabled=!0,c())}),e.appendChild(t),e.appendChild(s),e.appendChild(o);let n=p=>{s.textContent=p},a="",d=-1,l=p=>{p!==a&&(a=p,s.textContent=p)},_=p=>{let c=Math.round(p);c!==d&&(d=c,r.style.width=c+"%")},m=()=>{i=null,Ts===o&&(Ts=null),o.style.display="none",o.disabled=!1};return{el:e,reset(){delete e.dataset.active,delete e.dataset.state,a="",d=-1,this._last=void 0,this._lastAt=0,this._rate=void 0,r.style.width="0%",s.textContent="",m()},setCancel(p){if(p==null){m();return}i=p,Ts=o,o.disabled=!1,o.style.display=""},set(p,c){e.dataset.active="",delete e.dataset.state;let u=Date.now();if(this._last!==void 0&&u>this._lastAt){let h=(p-this._last)/((u-this._lastAt)/1e3);this._rate=this._rate===void 0?h:this._rate*.7+h*.3}if(this._last=p,this._lastAt=u,Number.isFinite(c)&&c>0){let h=Math.min(100,Math.max(0,p/c*100));_(h);let f=this._rate!==void 0&&this._rate>=0?gs(this._rate):"";l(Math.round(h)+"%"+(f!==""?" \xB7 "+f:""))}else{r.style.width="";let h=this._rate!==void 0&&this._rate>=0?gs(this._rate):"";l(Ze(p)+(h!==""?" \xB7 "+h:""))}},pulse(p){e.dataset.active="",delete e.dataset.state,r.style.width="45%",r.style.transition="none",setTimeout(()=>{r.style.transition="width .15s linear"},30);let c=Date.now();if(this._last!==void 0&&c>this._lastAt){let h=(p-this._last)/((c-this._lastAt)/1e3);this._rate=this._rate===void 0?h:this._rate*.7+h*.3}this._last=p,this._lastAt=c;let u=this._rate!==void 0&&this._rate>=0?gs(this._rate):"";l((Number.isFinite(p)?Ze(p):"\u2026")+(u!==""?" \xB7 "+u:""))},done(p){e.dataset.active="",e.dataset.state="done",r.style.width="100%",d=100,m(),l(p!==void 0&&p!==""?p:w("status.done"))},fail(p){e.dataset.active="",e.dataset.state="error",m(),l(p!==void 0&&p!==""?p:w("status.failed"))},text(p){delete e.dataset.state,p===void 0||p===""?(e.dataset.active="",a="",s.textContent=""):(e.dataset.active="",r.style.width="",d=-1,l(p))}}}async function sm(e,t,r,s=0,o=null,i=0){let n=s>0?s*1024*1024:0,a=Number.isFinite(i)&&i>0?i:0,d=typeof AbortController=="function"?new AbortController:null,l=!1;d!==null&&(t={...t,signal:d.signal},typeof o=="function"&&o(()=>{l=!0,d.abort()}));let _=a,m=null,y;try{if(y=await fetch(e,t),!y.ok){let S="HTTP "+y.status;try{let g=await y.json();g!==null&&typeof g=="object"&&typeof g.error=="string"&&(S=g.error)}catch{}throw new Error(S)}let p=Number(y.headers.get("content-length")),c=y.headers.get("content-range")??"",u=Number(/\/(\d+)\s*$/.exec(c)?.[1]);Number.isFinite(u)&&u>0?m=u:Number.isFinite(p)&&p>0&&(m=a+p);let h=y.body;if(h===null||typeof h.getReader!="function"){let S=await y.blob();if(n>0&&a+S.size>n)throw new Error(w("error.downloadTooBig",{size:Ze(n)}));return m!==null&&r(m,m),S}if(n>0&&m!==null&&m>n){try{await h.cancel()}catch{}throw new Error(w("error.downloadTooBig",{size:Ze(n)}))}let f=h.getReader(),v=[];for(;;){let{done:S,value:g}=await f.read();if(S)break;if(g!==void 0&&g.byteLength>0){if(_+=g.byteLength,n>0&&_>n){try{await f.cancel()}catch{}throw new Error(w("error.downloadTooBig",{size:Ze(n)}))}v.push(g),r(_,m!==null?m:NaN)}}return new Blob(v,{type:"application/octet-stream"})}catch(p){if(l||p!==null&&typeof p=="object"&&p.name==="AbortError")throw new es;if(p!==null&&typeof p=="object")throw p.received=_,p.total=m,p;let c=new Error(String(p));throw c.received=_,c.total=m,c}}async function Ah({url:e="/api/dsh-tty/sftp/download",makeBody:t,onProgress:r,maxMb:s=0,registerCancel:o=null,onResume:i=null}){let n=0,a=0;for(;;)try{return await sm(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t(n))},r,s,o,n)}catch(d){if(Jr(d))throw d;a+=1;let l=mc({received:d?.received??0,total:d?.total??null,attempt:a});if(!l.resume)throw d;n=l.offset,typeof i=="function"&&i(n)}}var es=class extends Error{constructor(){super(w("msg.canceled")),this.name="TransferCanceledError"}};function Jr(e){return e instanceof es}function Dh(e,t){let r=URL.createObjectURL(e),s=document.createElement("a");s.href=r,s.download=t,s.click(),setTimeout(()=>URL.revokeObjectURL(r),3e4)}async function Ph(e){if(e==null)return[];let t=typeof e.items<"u"?[...e.items]:[],r=[];for(let l of t){let _=typeof l.webkitGetAsEntry=="function"?l.webkitGetAsEntry():null;_!==null&&r.push(_)}if(r.length===0)return[...e.files??[]].map(l=>({relPath:l.name,file:l}));let s=[],o=Kt.maxUploadFiles,i=Kt.maxUploadMb>0?Kt.maxUploadMb*1024*1024:0,n=()=>o>0&&s.length>=o,a=0,d=(l,_)=>new Promise(m=>{if(n()){m();return}if(l.isFile===!0){l.file(c=>{i>0&&a+(c.size??0)>i?s._limitExceeded=!0:(s.push({relPath:_+l.name,file:c}),a+=c.size??0),m()},()=>m());return}if(l.isDirectory!==!0){m();return}let y=l.createReader(),p=()=>{y.readEntries(async c=>{if(c.length===0){m();return}for(let u of c){if(n())break;await d(u,_+l.name+"/")}if(n()){m();return}p()},()=>m())};p()});for(let l of r)await d(l,"");return s}function Qi(e,t){let r=Wr(t,ke);if(kh(r))return;let s=e!==null&&typeof e=="object"?e:{},o={};if(typeof s.name=="string"&&s.name!=="")o.name=s.name;else{for(let W of["host","username","auth","keyPath","passphrase","password"])typeof s[W]=="string"&&s[W]!==""&&(o[W]=s[W]);let k=Number(s.port);Number.isInteger(k)&&k>=1&&k<=65535&&(o.port=k),s.agentForward===!0&&(o.agentForward=!0)}let i=o.name??(o.username!==void 0?o.username+"@"+String(o.host??""):String(o.host??""));if(fh==="dual"){Q_(o,i,r);return}let n=document.createElement("div");n.className="tt_sftpCard";let a=document.createElement("div");a.className="tt_sftpTitleRow";let d=document.createElement("div");d.className="tt_sshTitle",d.innerHTML=Rs+"<span></span>",d.lastElementChild.textContent="SFTP \xB7 "+i;let l=document.createElement("button");l.type="button",l.className="tt_close",l.title=w("btn.close"),l.innerHTML=Vi,l.addEventListener("click",()=>ts(r)),a.appendChild(d),a.appendChild(l),n.appendChild(a);let _=document.createElement("div");_.className="tt_sftpBar";let m=document.createElement("input");m.type="text",m.className="tt_sftpPath",m.placeholder=w("placeholder.remotePath"),m.spellcheck=!1,m.autocomplete="off";let y=document.createElement("button");y.type="button",y.className="tt_toolBtn",y.innerHTML=Po+"<span>"+w("btn.refresh")+"</span>";let p=document.createElement("button");p.type="button",p.className="tt_toolBtn",p.innerHTML=Vc+"<span>"+w("btn.mkdir")+"</span>";let c=document.createElement("button");c.type="button",c.className="tt_toolBtn",c.innerHTML=Xp+"<span>"+w("btn.upload")+"</span>",c.title=w("btn.uploadTitle");let u=document.createElement("input");u.type="file",u.multiple=!0,u.style.display="none",_.appendChild(m),_.appendChild(y),_.appendChild(p),_.appendChild(c),n.appendChild(_),n.appendChild(u);let h=document.createElement("div");h.className="tt_sftpEditor",h.style.display="none";let f=document.createElement("input");f.type="text",f.className="tt_cardInput",f.spellcheck=!1,f.autocomplete="off";let v=document.createElement("button");v.type="button",v.className="tt_toolBtn",v.textContent=w("btn.ok");let S=document.createElement("button");S.type="button",S.className="tt_toolBtn",S.textContent=w("btn.cancel"),h.appendChild(f),h.appendChild(v),h.appendChild(S),n.appendChild(h);let g=null,x=()=>{h.style.display="none",g=null};v.addEventListener("click",()=>{g?.()}),S.addEventListener("click",x),f.addEventListener("keydown",k=>{k.key==="Enter"?(k.preventDefault(),g?.()):k.key==="Escape"&&(k.stopPropagation(),x())});let b=document.createElement("div");b.className="tt_sftpList",n.appendChild(b);let E=document.createElement("div");E.className="tt_sftpFoot";let P=document.createElement("div");P.className="tt_sftpStatus";let O=Mh();E.appendChild(O.el),E.appendChild(P),n.appendChild(E);let F={path:"",busy:!1},A=(k,W)=>{P.textContent=k,W===void 0?delete P.dataset.state:P.dataset.state=W},V=k=>{F.busy=k;for(let W of[y,p,c])W.disabled=k;m.disabled=k},B=async(k,W)=>{let q=await fetch("/api/dsh-tty/sftp/"+k,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...o,...W})}),j=await q.json().catch(()=>({}));if(!q.ok||j.ok!==!0)throw new Error(String(j.error||"HTTP "+q.status));return j},M=async(k,W)=>{if(!F.busy){V(!0),A(k,"busy");try{await W()}catch(q){A(String(q&&q.message?q.message:q),"error")}finally{V(!1)}}},U=(k,W,q,j)=>{let X=document.createElement("button");X.type="button",X.className="tt_sftpRow";let J=document.createElement("span");J.className="tt_sftpIcon",J.innerHTML=k,j!==void 0&&(J.dataset.kind=j);let ae=document.createElement("span");if(ae.className="tt_sftpName",ae.textContent=W,ae.title=W,X.appendChild(J),X.appendChild(ae),q!==""){let he=document.createElement("span");he.className="tt_sftpMeta",he.textContent=q,X.appendChild(he)}return X},I=(k,W,q,j)=>{let X=document.createElement("button");X.type="button",X.className="tt_sftpAct",X.innerHTML=W,X.title=q,X.addEventListener("click",J=>{J.stopPropagation(),j()}),k.appendChild(X)},C=(k,W,q)=>{let j=document.createElement("button");j.type="button",j.className="tt_sftpAct",j.innerHTML=qr,j.title=W.isDir?w("btn.deleteEntryDir",{name:W.name}):w("btn.deleteEntry",{name:W.name});let X=null;j.addEventListener("click",J=>{if(J.stopPropagation(),!F.busy){if(X!==null){clearTimeout(X),X=null,j.innerHTML=qr,delete j.dataset.danger,M(w("msg.deleting",{name:W.name}),async()=>{await B("remove",{path:q,recursive:W.isDir===!0}),await T(F.path),A(w("msg.deleted",{name:W.name}))});return}j.textContent=w("btn.confirm"),j.dataset.danger="",X=setTimeout(()=>{X=null,j.innerHTML=qr,delete j.dataset.danger},4e3)}}),k.appendChild(j)},L=k=>{if(b.textContent="",F.path!==""&&F.path!=="/"){let j=U(Ao,w("list.parentDir"),"","up");j.addEventListener("click",()=>{M(w("list.loading"),()=>T(Rh(F.path)))}),b.appendChild(j)}let W=Array.isArray(k)?k:[];if(W.length===0){let j=document.createElement("div");j.className="tt_addMenuTitle",j.textContent=w("list.emptyDir"),b.appendChild(j);return}let q=500;for(let j of W.slice(0,q)){if(j===null||typeof j!="object"||typeof j.name!="string"||j.name==="")continue;let X=vs(F.path,j.name),J=[];j.isDir===!0?J.push(w("meta.dir")):J.push(Ze(Number(j.size))||"\u2014");let ae=Th(Number(j.mtime));ae!==""&&J.push(ae);let he=U(j.isDir?Rs:j.isSymlink?Kc:qc,j.name,J.join(" \xB7 "),j.isDir===!0?"dir":j.isSymlink===!0?"link":"file");j.isDir===!0?he.addEventListener("click",_e=>{_e.target instanceof Element&&_e.target.closest(".tt_sftpAct")!==null||M(w("list.loading"),()=>T(X))}):(he.addEventListener("click",_e=>{_e.target instanceof Element&&_e.target.closest(".tt_sftpAct")!==null||D(j,X)}),I(he,Gc,w("btn.download",{name:j.name}),()=>{D(j,X)})),I(he,Do,w("btn.rename",{name:j.name}),()=>{f.placeholder=w("placeholder.newName"),f.value=j.name,h.style.display="",f.focus(),f.select(),g=async()=>{let _e=f.value.trim();_e===""||_e===j.name||(x(),await M(w("msg.renaming",{name:j.name}),async()=>{await B("rename",{from:X,to:vs(F.path,_e)}),await T(F.path)}))}}),C(he,j,X),b.appendChild(he)}if(W.length>q){let j=document.createElement("div");j.className="tt_addMenuTitle",j.textContent=w("list.truncated",{rest:W.length-q,total:W.length}),b.appendChild(j)}},T=async k=>{try{let W=await B("list",{path:k??F.path});F.path=typeof W.path=="string"&&W.path!==""?W.path:"/",m.value=F.path;let q=Array.isArray(W.entries)?W.entries.length:0;L(W.entries),A(F.path+" \u2014 "+w("list.itemCount",{count:q}))}catch(W){A(String(W&&W.message?W.message:W),"error")}},D=(k,W)=>M(w("msg.downloading",{name:k.name}),async()=>{O.reset();let q;try{q=await Ah({makeBody:j=>({...o,path:W,...j>0?{offset:j}:{}}),onProgress:(j,X)=>O.set(j,X),maxMb:Kt.maxDownloadMb,registerCancel:j=>O.setCancel(j),onResume:j=>A(w("msg.downloadResuming",{name:k.name,offset:Ze(j)||String(j)+" B"}),"busy")})}catch(j){if(Jr(j)){O.reset(),A(w("msg.downloadCanceled",{name:k.name}));return}throw O.fail(w("error.downloadFailed")),j}O.done(w("status.done")),Dh(q,k.name),setTimeout(()=>O.reset(),1500),A(w("msg.downloaded",{name:k.name,size:Ze(q.size)||String(q.size)+" B"}))}),N=(k,W,q,j,X)=>Lh(k,vs(F.path,W),{spec:o,label:(j>1?String(q)+"/"+String(j)+" ":"")+W,cancelRef:X,onProgress:(J,ae)=>{Number.isFinite(ae)&&ae>0?O.set(J,ae):O.pulse(J)},onLabel:J=>A(w("msg.uploadingName",{name:J}),"busy"),onDone:()=>{j===1&&O.done(w("msg.uploadDone"))}}).catch(J=>{throw Jr(J)||O.fail(w("error.uploadFailed")),J}),G=async k=>M(w("msg.uploading"),async()=>{let W=Kt;if(W.maxUploadFiles>0&&k.length>W.maxUploadFiles){A(w("error.uploadCountExceeded",{max:W.maxUploadFiles,count:k.length}),"error"),O.fail(w("status.overLimit"));return}let q=W.maxUploadMb>0?W.maxUploadMb*1024*1024:0,j=k.find(_e=>q>0&&(_e.file?.size??0)>q);if(j!==void 0){A(w("error.uploadTooBig",{size:Ze(q),name:String(j.relPath??"")}),"error"),O.fail(w("status.overLimit"));return}if(k._limitExceeded===!0){A(w("error.uploadTotalTooBig"),"error"),O.fail(w("status.overLimit"));return}let X=new Set;for(let _e of k){let Z=_e.relPath.lastIndexOf("/");if(Z<=0)continue;let Ce=_e.relPath.slice(0,Z);X.has(Ce)||(X.add(Ce),await B("mkdir",{path:vs(F.path,Ce),parents:!0}).catch(()=>{}))}O.reset();let J={stopped:!1,abort:null};O.setCancel(()=>J.abort?.());let ae=0,he=0;try{for(let _e of k){if(J.stopped)break;ae+=1,J.abort=null;try{await N(_e.file,_e.relPath,ae,k.length,J),he+=1}catch(Z){if(Jr(Z)||J.stopped)break;throw Z}}}finally{O.setCancel(null)}if(J.stopped){O.reset(),A(w("msg.uploadCanceled",{done:he,total:k.length})),await T(F.path);return}O.done(w("status.allDone")),setTimeout(()=>O.reset(),1500),A(w("msg.uploadDoneCount",{count:k.length})),await T(F.path)});y.addEventListener("click",()=>{M(w("list.loading"),()=>T(F.path))}),p.addEventListener("click",()=>{F.busy||(f.placeholder=w("placeholder.newDirName"),f.value="",h.style.display="",f.focus(),g=async()=>{let k=f.value.trim();k!==""&&(x(),await M(w("msg.creatingDir",{name:k}),async()=>{await B("mkdir",{path:vs(F.path,k)}),await T(F.path)}))})}),c.addEventListener("click",()=>{F.busy===!1&&u.click()}),u.addEventListener("change",()=>{let k=[...u.files??[]].map(W=>({relPath:W.name,file:W}));u.value="",k.length>0&&G(k)});let $=0,Y=k=>{k?b.dataset.drag="":delete b.dataset.drag};n.addEventListener("dragenter",k=>{k.preventDefault(),$+=1,Y(!0)}),n.addEventListener("dragover",k=>{k.preventDefault()}),n.addEventListener("dragleave",()=>{$=Math.max(0,$-1),$===0&&Y(!1)}),n.addEventListener("drop",k=>{k.preventDefault(),$=0,Y(!1),!F.busy&&Ph(k.dataTransfer).then(W=>{(W.length>0||W._limitExceeded===!0)&&G(W)})}),m.addEventListener("keydown",k=>{if(k.key!=="Enter"||(k.preventDefault(),F.busy))return;let W=m.value.trim();W!==""&&M(w("list.loading"),()=>T(W))});let H=Io();Eh(n,"SFTP \xB7 "+i,H===null?340:Math.round(H.height*.46),r),M(w("status.connectingEllipsis"),()=>T(""))}function ts(e){let t=e===void 0?xh():e,r=Vt,s=It!==null&&It.ownerKey===t?It:null;if(r===null&&s===null)return;em();let o=wo;wo=null,o?.(),Vt=null,s!==null&&(It=null),r!==null&&r.remove(),s!==null&&s.dispose()}function Bh(){if(st===null)return;let e=st.style.display==="none"||st.style.display==="";st.style.display=e?"":"none";let t=ue!==null?ue.querySelector("[data-act=search]"):null;t!==null&&(e?t.dataset.on="":delete t.dataset.on),e&&st.focus()}function im(){return{matchBackground:Te("--tt-term-search-match"),matchBorder:Te("--tt-term-search-match-border"),activeMatchBackground:Te("--tt-term-search-active"),activeMatchBorder:Te("--tt-term-search-active-border"),matchOverviewRuler:Te("--tt-term-search-match-border"),activeMatchColorOverviewRuler:Te("--tt-term-search-active-border")}}function nm(e){let t=vt();if(t===void 0||t.search===void 0)return;let r=st.value;if(r==="")return;let s={decorations:im()};e?t.search.findPrevious(r,s):t.search.findNext(r,s)}function Bc(){As||ue===null&&!Bo()||gr!==null||(gr=setTimeout(()=>{gr=null,$i()},xs),xs=Math.min(xs*2,5e3))}function zs(e){return e!==null&&typeof e=="object"&&e.persist===!0&&typeof e.persistName=="string"&&e.persistName!==""}function Lo(e){return zs(e)||e!==null&&typeof e=="object"&&typeof e.command=="string"&&e.command!==""}function om(){return ar==="tmux"?{t:"spawn",cwd:_o(),persist:!0,persistName:Wo()}:{t:"spawn",cwd:_o()}}async function Oh(){if(!ho){ho=!0;try{await am()}finally{ho=!1}}}var ho=!1;async function am(){if(await Uo(),ue===null){await cm();return}let e=d_(),t=h_();if(![...fe.values()].some(n=>n.embedded!==!0)){if(e.length>0||t.length>0){Pe({t:"sessions"});let n=await Hi("sessions",4e3),a=new Map;if(n!==null&&Array.isArray(n.list))for(let l of n.list)l!==null&&typeof l=="object"&&l.attachable===!0&&a.set(l.sid,l);let d=new Set;for(let l of e){if(a.has(l.sid))b_(l);else if(Lo(l.spawnSpec))Dc(l);else continue;zs(l.spawnSpec)&&d.add(l.spawnSpec.persistName)}for(let l of t){let _=l.spawnSpec.persistName;d.has(_)||(Dc(l),d.add(_))}lr()}if(![...fe.values()].some(n=>n.embedded!==!0)){if(await ji())return;Ds()}return}let r=[...fe.values()].filter(n=>!n.exited&&(n.embedded!==!0||n.spawned===!0)),s=r.filter(n=>Lo(n.spawnSpec)),o=null;if(s.length>0){Pe({t:"sessions"});let n=await Hi("sessions",4e3),a=vi(n!==null?n.list:[]);o=s.filter(d=>!a.has(d.sid));for(let d of o)Fi(d.sid)}let i=o!==null?new Set(o.map(n=>n.sid)):new Set;for(let n of r)i.has(n.sid)||Pe({t:"attach",sid:n.sid})}function lm(){Ae!==null&&(Ae.readyState===WebSocket.OPEN||Ae.readyState===WebSocket.CONNECTING)||$i()}async function cm(){let e=[...fe.values()].filter(s=>s.embedded===!0&&!s.exited);if(e.length===0)return;Pe({t:"sessions"});let t=await Hi("sessions",4e3),r=vi(t!==null?t.list:[]);for(let s of e)s.spawned===!0&&(r.has(s.sid)?Pe({t:"attach",sid:s.sid}):Lo(s.spawnSpec)?ch(s):(s.exited=!0,s.live=!1,Ur(s,w("status.ended"),w("btn.clickRerun"),"exited")))}function $i(){if(Ae!==null){try{Ae.close()}catch{}Ae=null}As=!1,clearTimeout(gr),gr=null,yi=!0,Si(w("status.connectingEllipsis"),"");try{Ae=new WebSocket(Hp())}catch(e){yi=!1,Si(w("error.connectFailed",{error:e.message}),"error"),Bc();return}Ae.onopen=()=>{yi=!1,xs=1e3,Ct=null,Si(w("status.connected"),"connected");for(let e of[...uo])uo.delete(e),fe.has(e.tab.sid)&&Pe(e.frame);Oh()},Ae.onmessage=e=>{let t;try{t=JSON.parse(e.data)}catch{return}let r=t.sid;if(t.t==="ready"){let s=typeof t.target=="string"?t.target:"";ao(r,t.kind==="ssh"?w("status.connectedSsh",{target:s!==""?s+" ":""}):w("status.connectedPid",{pid:t.pid}),"connected");let o=fe.get(r);if(o!==void 0){if(o.exited=!1,o.spawned=!0,o.live=!0,o.errored=!1,o.target=s,o.persistTmux=t.persist===!0,t.kind==="ssh"&&s!==""&&!o.label&&(o.label=s,ht()),br(),lo(r),Ur(o,""),rs(o),t.persist===!0){let i=document.fonts!==void 0&&document.fonts.ready!==void 0?document.fonts.ready:Promise.resolve();Promise.race([i,new Promise(n=>setTimeout(n,500))]).then(()=>sh(150))}Bs(),o_(r),lr()}}else if(t.t==="sessions")v_(t.list);else if(t.t==="data"){let s=fe.get(r);s!==void 0&&s.term!==null&&(s.term.write(String(t.d??"")),pm())}else if(t.t==="exit"){let s=fe.get(r);if(s!==void 0){s.exited=!0,s.live=!1,s.stats=null,r===ke&&xr();let o=t.code!==null&&t.code!==void 0?"code="+t.code:"",i=t.signal!==null&&t.signal!==void 0?"signal="+t.signal:"";ao(r,w("status.exitedWith",{detail:[o,i].filter(Boolean).join(" ")}),""),br(),lo(r),Ur(s,w("status.exited"),w("btn.clickReopen"),"exited"),Bs(),lr()}}else if(t.t==="stats")try{let s=fe.get(r);if(s!==void 0){let o=t.stats;s.stats=kc(o)?o:null,s.statsAt=Date.now(),r===ke&&xr()}}catch(s){console.warn("[dsh-tty] stats \u5E27\u5904\u7406\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09: "+(s instanceof Error?s.message:String(s)))}else if(t.t==="hint"){if(!Oi||t.kind!=="failure"||typeof r!="string"||r==="")return;cr.set(r,{exitCode:typeof t.exitCode=="number"?t.exitCode:null,at:typeof t.at=="number"?t.at:Date.now(),dismissed:!1,busy:!1,answer:null,command:"",error:null}),r===ke&&kr()}else if(t.t==="error")if(ao(r,w("status.error",{message:String(t.m??"")}),"error"),typeof r=="string"){let s=fe.get(r);s!==void 0&&(s.live||(s.errored=!0),br(),lo(r),Ur(s,w("status.errored"),w("status.retryHint",{message:String(t.m??"")}),"error"))}else hm(w("btn.clickRetry"))},Ae.onclose=()=>{if(yi=!1,!As){Si(w("status.disconnectedReconnecting"),"error");for(let e of fe.values())e.exited||Ur(e,w("status.disconnected"),w("status.reconnecting"),"info");Bc()}},Ae.onerror=()=>{}}function hm(e){Kr!==null&&(Kr.textContent=e)}function To(){(ue===null||Ve)&&Mo()}var xi="DSH_TTY_ALLOW_PROXY_COMMAND";function dm(e){let t=new Date(Number(e)*1e3);if(Number.isNaN(t.getTime()))return String(e);let r=s=>String(s).padStart(2,"0");return`${String(t.getFullYear())}-${r(t.getMonth()+1)}-${r(t.getDate())} ${r(t.getHours())}:${r(t.getMinutes())}:${r(t.getSeconds())}`}function zo(){return typeof navigator<"u"&&navigator.clipboard!==void 0&&typeof navigator.clipboard.writeText=="function"}async function Ro(e){if(zo())try{return await navigator.clipboard.writeText(e),!0}catch{}let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let r=!1;try{r=document.execCommand("copy")}catch{r=!1}return t.remove(),r||Fs(w("error.copyFailed"),"error"),r}async function um(e){if(zo()&&typeof navigator.clipboard.readText=="function")try{let s=await navigator.clipboard.readText();return s!==""&&Pe({t:"input",sid:e.sid,d:s}),!0}catch{}let t=document.createElement("textarea");t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.focus();let r=!1;try{r=document.execCommand("paste");let s=r?t.value:"";s!==""&&Pe({t:"input",sid:e.sid,d:s})}catch{r=!1}return t.remove(),r||Fs(w("error.pasteFailed"),"error"),r}function Mo(){if(ue!==null){Ve&&Ih();return}Is(),ue=document.createElement("div"),ue.className="tt_modalBackdrop",ue.innerHTML='<div class="tt_modal"><div class="tt_header"><span class="tt_titleIcon">'+Gi+'</span><div class="tt_tabbar"><div class="tt_tabs"></div><button type="button" class="tt_tabMore" hidden></button><button type="button" class="tt_tabAdd"></button></div><div class="tt_status"><span class="tt_statusDot"></span><span class="tt_statusText">'+w("status.initializing")+'</span></div><input class="tt_searchInput" style="display:none" placeholder="'+w("placeholder.search")+'" /><span class="tt_toolGroup"><button class="tt_toolBtn tt_iconBtn" data-act="search" title="'+w("btn.searchTitle")+'">'+zp+'</button><button class="tt_toolBtn tt_iconBtn" data-act="clear" title="'+w("btn.clearTitle")+'">'+jp+'</button><button class="tt_toolBtn tt_iconBtn" data-act="copy" title="'+w("btn.copyTitle")+'">'+$p+'</button><button class="tt_toolBtn tt_iconBtn" data-act="paste" title="'+w("btn.pasteTitle")+'">'+qp+'</button></span><span class="tt_winGroup"><button class="tt_min" title="'+w("btn.minimizeTitle")+'">'+Vp+'</button><button class="tt_close" title="'+w("btn.closePanelTitle")+'">'+Vi+'</button></span></div><div class="tt_connbar" data-hidden><div class="tt_connArea"><span class="tt_connDot"></span><span class="tt_connTarget">\u2014</span><span class="tt_connBadge"></span></div><div class="tt_connActions"></div></div><div class="tt_work"><div class="tt_body"><div class="tt_statsBar" hidden></div><button type="button" class="tt_assistBadge" hidden><span class="tt_assistDot"></span><span class="tt_assistBadgeText"></span></button><div class="tt_overlay"></div></div></div></div>',document.body.appendChild(ue),Mi=ue.querySelector(".tt_status"),mr=ue.querySelector(".tt_statusText"),yr=ue.querySelector(".tt_statusDot"),Re=ue.querySelector(".tt_tabs");let e=ue.querySelector(".tt_tabAdd");e!==null&&(e.title=w("btn.newTab"),e.innerHTML=Yp,e.addEventListener("click",()=>{N_(e)})),Bt=ue.querySelector(".tt_tabMore"),Bt!==null&&(Bt.innerHTML=$c,Bt.title=w("btn.tabList"),Bt.addEventListener("click",()=>{H_(Bt)})),Re.addEventListener("scroll",vo),Re.addEventListener("wheel",R_,{passive:!1}),ws=ue.querySelector(".tt_connbar"),ys=ue.querySelector(".tt_connDot"),Ai=ue.querySelector(".tt_connTarget"),_t=ue.querySelector(".tt_connBadge"),Ss=ue.querySelector(".tt_connActions"),mt=ue.querySelector(".tt_work"),lt=ue.querySelector(".tt_body"),St=ue.querySelector(".tt_statsBar"),Ji(),Ct=null,eh(),Kr=ue.querySelector(".tt_body > .tt_overlay"),ir=ue.querySelector(".tt_assistBadge"),ir!==null&&ir.addEventListener("click",()=>{ir!==null&&G_(ir)}),kt(),kr(),st=ue.querySelector(".tt_searchInput"),Kr.addEventListener("click",()=>{Kr.textContent="",$i()});let t=ue.querySelector("[data-act=search]");t.addEventListener("click",()=>{Bh(),st.style.display!=="none"&&st.focus()}),t.dataset.on="",st.addEventListener("keydown",r=>{r.key==="Enter"?(r.preventDefault(),nm(r.shiftKey)):r.key==="Escape"&&(r.stopPropagation(),st.style.display="none")}),ue.querySelector("[data-act=clear]").addEventListener("click",()=>{let r=vt();r!==void 0&&r.term!==null&&r.term.clear()}),ue.querySelector("[data-act=copy]").addEventListener("click",()=>{let r=vt();if(r===void 0||r.term===null)return;let s=r.term.getSelection();s!==""&&Ro(s)}),ue.querySelector("[data-act=paste]").addEventListener("click",()=>{let r=vt();r!==void 0&&um(r)}),ue.querySelector(".tt_min").addEventListener("click",()=>{qi()}),ue.querySelector(".tt_close").addEventListener("click",()=>{Os()}),ue.addEventListener("mousedown",r=>{r.target===ue&&qi()}),document.addEventListener("keydown",Nh),Cs=new ResizeObserver(()=>{Ve||(ki(),f_(vt()),vo())}),Cs.observe(lt),ht(),br(),Ae!==null&&Ae.readyState===WebSocket.OPEN?Oh():$i()}function fm(){Qe=document.createElement("div"),Qe.className="tt_dock",Qe.title=w("btn.restoreDock"),Qe.innerHTML='<span class="tt_dockTitle">'+Gi+"<span>"+w("panel.title")+'</span><span class="tt_dockCount"></span></span><span class="tt_dockStatus"></span><span class="tt_dockDot"></span><button class="tt_dockClose" title="'+w("btn.closePanelTitle")+'">'+Yi+"</button>",Di=Qe.querySelector(".tt_dockCount"),Qr=Qe.querySelector(".tt_dockStatus"),Sr=Qe.querySelector(".tt_dockDot");let e=[...fe.values()].filter(t=>!t.exited).length;Di.textContent=fe.size>0?"\xB7 "+e+"/"+fe.size:"",mr!==null&&(Qr.textContent=mr.textContent),yr!==null&&(Sr.dataset.state=yr.dataset.state??""),Qe.addEventListener("click",t=>{if(t.target.closest(".tt_dockClose")!==null){t.stopPropagation(),Os();return}Ih()}),document.body.appendChild(Qe)}function qi(){ue===null||Ve||(yt(),Xt(),kt(),nr(),Ve=!0,Vt!==null&&(Vt.style.display="none"),st!==null&&(st.style.display="none"),ue.dataset.minimized="",th(),Ws(),xr(),document.querySelector("[data-dsh-tty-entry]")!==null?Bs():(fm(),Qe.classList.add("tt_dockCompact")))}function Bs(){let e=document.querySelector("[data-dsh-tty-entry]");if(e===null)return;let t=e.querySelector(".tt_sidebarEntryBadge");if(!Ve){t!==null&&t.remove(),delete e.dataset.minimized,e.removeAttribute("title");return}t===null&&(t=document.createElement("span"),t.className="tt_sidebarEntryBadge",t.innerHTML='<span class="tt_sidebarBadgeDot"></span><span class="tt_sidebarBadgeCount"></span>',e.appendChild(t)),e.dataset.minimized="",e.title=w("status.minimized");let r=[...fe.values()].filter(o=>!o.exited).length;t.querySelector(".tt_sidebarBadgeCount").textContent=r+"/"+fe.size;let s=t.querySelector(".tt_sidebarBadgeDot");s!==null&&yr!==null&&(s.dataset.state=yr.dataset.state??"")}function pm(){if(!Ve)return;let e=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot")??Sr;e!==null&&(e.dataset.active="",clearTimeout(Pi),Pi=setTimeout(()=>{delete e.dataset.active},900))}function Ih(){if(ue===null||!Ve)return;Ve=!1,delete ue.dataset.minimized,Vt!==null&&(Vt.style.display=""),clearTimeout(Pi),Qe!==null&&(Qe.remove(),Qe=null),Di=null,Qr=null,Sr=null,Bs(),eh(),Ws(),xr();let e=vt();if(e!==void 0&&e.fit!==void 0){try{e.fit.fit()}catch{}e.spawned&&!e.exited&&rs(e)}e!==void 0&&e.term!==null&&e.term.focus()}function Os(){if(ue===null)return;Ls(!0);let e=Bo();if(As=!e,Ve=!1,yt(),Xt(),kt(),Ei(),Ui(),nr(),ts(),clearTimeout(Pi),clearTimeout(gr),gr=null,xs=1e3,Qe!==null&&(Qe.remove(),Qe=null),Di=null,Qr=null,Sr=null,Bs(),Ae!==null){for(let t of fe.values())!t.exited&&t.embedded!==!0&&Pe({t:"kill",sid:t.sid});if(!e){try{Ae.close()}catch{}Ae=null}}Cs!==null&&(Cs.disconnect(),Cs=null);for(let[t,r]of[...fe])if(r.embedded!==!0){if(r.term!==null)try{r.term.dispose()}catch{}fe.delete(t)}ke=null,Ms=null,document.removeEventListener("keydown",Nh),ue.remove(),ue=null,mt=null,Mi=null,mr=null,yr=null,Re=null,Bt=null,ws=null,ys=null,Ai=null,_t=null,Ss=null,Ui(),th(),St=null,Ji(),Ct=null,lt=null,Kr=null,st=null,Hs=0;try{sessionStorage.removeItem(Bi)}catch{}}function Nh(e){if(e.key==="Escape"&&ue!==null){if(e.preventDefault(),Vt!==null){ts();return}if(Vr!==null){nr();return}if(gt!==null){yt();return}qi()}}function _m(){let e=document.querySelector('[data-pane="sidebar"], [class*="sidebarCol"]');if(e!==null)return e.querySelector('[class*="logoRow"]')?.parentElement??e.firstElementChild}function mm(e){let t=e.querySelector('button[class*="newSession"]');if(t!==null)return t;for(let r of e.children)if(r.tagName==="BUTTON")return r}function gm(){let e=document.createElement("div");return e.dataset.dshTtyEntry="",e.className="tt_sidebarEntry",e.setAttribute("role","button"),e.setAttribute("aria-label",w("panel.title")),e.tabIndex=0,e.innerHTML='<span class="tt_sidebarEntryIcon">'+Gi+'</span><span class="tt_sidebarEntryLabel">'+w("panel.title")+"</span>",e.addEventListener("click",t=>{t.preventDefault(),Mo()}),e.addEventListener("keydown",t=>{(t.key==="Enter"||t.key===" "||t.key==="Spacebar")&&(t.preventDefault(),Mo())}),e}function Oc(e,t){let r=mm(e);if(r===void 0)return!1;if(t.parentElement!==e){let s=r.closest('[class*="logoRow"]'),o=s!==null&&s.parentElement===e?s:r,i=Array.from(e.children).filter(n=>n instanceof HTMLElement&&n.matches("[data-dsh-global-search-entry], [data-dsh-rss-entry], [data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-tty-entry]"));if(i.length>0){let n=i[i.length-1];e.insertBefore(t,n.nextSibling)}else e.insertBefore(t,o.nextElementSibling)}return!0}function vm(){if(Is(),typeof document<"u"&&document.querySelector("[data-dsh-tty-entry]")!==null)return()=>{};let e=gm(),t,r=!1,s=()=>{if(t!==void 0&&!t.isConnected&&(i.disconnect(),t=void 0,r=!1),r){if(document.body.contains(e))return;i.disconnect(),t=void 0,r=!1}t??(t=_m()),t!==void 0&&(r=Oc(t,e),r&&i.observe(t,{childList:!0,subtree:!0}))},o=new MutationObserver(()=>{s()});o.observe(document.body,{childList:!0,subtree:!0});let i=new MutationObserver(()=>{if(t===void 0||!t.isConnected){r=!1,s();return}t.contains(e)||(r=Oc(t,e))});return s(),()=>{o.disconnect(),i.disconnect(),e.remove()}}window.__ModuleLoader__.load({id:"@hyzyn/dsh-tty",factory:e=>{let t={},r=e("react"),{jsx:s,jsxs:o}=e("react/jsx-runtime"),i="M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 9.13382 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z";function n(d){let l=d&&d.view,_=l==="page",[m,y]=r.useState(_),[p,c]=r.useState(null),[u,h]=r.useState(!1),[f,v]=r.useState(!1),[S,g]=r.useState({kind:"",text:""}),[x,b]=r.useState(null),[E,P]=r.useState(""),[O,F]=r.useState(!1),[A,V]=r.useState(Date.now()),B=r.useRef(null),M=r.useRef(null),[U,I]=r.useState([]),[C,L]=r.useState(!1),[T,D]=r.useState({groups:[],loading:!1,failed:!1}),[N,G]=r.useState(!1),$=r.useRef(null),Y=r.useRef(0),H=R=>s("div",{className:"tt_cardSection",children:R}),k=async()=>{try{let z=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json();z.ok&&typeof z.config=="object"&&z.config!==null?(B.current=z.config,M.current=JSON.stringify(J(z.config)),c(z.config),Ps(z.config)):g({kind:"error",text:String(z.error||w("error.configLoadFailed"))})}catch(R){g({kind:"error",text:String(R&&R.message?R.message:R)})}},W=async()=>{try{let z=await(await fetch("/api/dsh-tty/shells",{cache:"no-store"})).json();z.ok&&Array.isArray(z.shells)&&I(z.shells)}catch{}};r.useLayoutEffect(()=>{if(!N)return;let R=()=>{let z=$.current,K=z===null||z.parentElement===null?null:z.parentElement.querySelector(".tt_routeList");z===null||K===null||(K.style.width=String(Math.round(z.getBoundingClientRect().width))+"px",Us(K,z))};return R(),window.addEventListener("scroll",R,!0),window.addEventListener("resize",R),()=>{window.removeEventListener("scroll",R,!0),window.removeEventListener("resize",R)}},[N,T.loading,T.failed,T.groups]);let q=async()=>{let R=Y.current+1;Y.current=R,D(z=>({...z,loading:!0}));try{let K=await(await fetch("/api/dsh-tty/model-catalog",{cache:"no-store"})).json();if(K.ok===!0&&R===Y.current){D({groups:Array.isArray(K.groups)?K.groups:[],loading:!1,failed:!1});return}}catch{}R===Y.current&&D({groups:[],loading:!1,failed:!0})};r.useEffect(()=>{m&&!u&&(h(!0),k(),W(),q())},[m]);let j=(R,z)=>c(K=>{let ee={...K||{},[R]:z};return B.current=ee,ee}),X=new Set(["toolsRegistered","platform","allowProxyCommandGranted","allowProxyCommandGrantSource","allowProxyCommandGrantedAt"]),J=R=>{let z={};for(let[K,ee]of Object.entries(R||{}))X.has(K)||ee!==void 0&&(z[K]=ee);return z.sshHosts=Array.isArray(R?.sshHosts)?R.sshHosts:[],z.tunnels=Array.isArray(R?.tunnels)?R.tunnels:[],R?.sftpLimits&&typeof R.sftpLimits=="object"&&(z.sftpLimits={maxDownloadMb:Number(R.sftpLimits.maxDownloadMb)||0,maxUploadMb:Number(R.sftpLimits.maxUploadMb)||0,maxUploadFiles:Number(R.sftpLimits.maxUploadFiles)||0}),z};B.current=p;let ae=(R,z)=>c(K=>({...K||{},sftpLimits:{...K?.sftpLimits??{},[R]:z}})),[he,_e]=r.useState(null),[Z,Ce]=r.useState(null),[He,Ee]=r.useState(""),[Oe,Ue]=r.useState(null),[te,de]=r.useState(""),[ve,Q]=r.useState(""),[se,oe]=r.useState(""),re=r.useRef(null),[ne,ce]=r.useState(!1),[le,ge]=r.useState({text:"",kind:""}),[we,Le]=r.useState(!1),[ye,be]=r.useState({running:!1,ok:!1,text:""}),[xe,Fe]=r.useState({}),[tt,Er]=r.useState([]),[it,hr]=r.useState({direction:"local",localPort:"",remoteHost:"",remotePort:"",localTargetPort:"",bookName:""}),[Et,is]=r.useState(null);r.useEffect(()=>{if(!m)return;let R=!0,z=async()=>{try{let ie=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();R&&ie.ok&&Array.isArray(ie.tunnels)&&Er(ie.tunnels)}catch{}};z();let K=setInterval(z,2e3);return()=>{R=!1,clearInterval(K)}},[m]);let dr=R=>z=>hr(K=>({...K||{},[R]:z.target.value})),jo=(R,z)=>hr(K=>({...K||{},[R]:z})),Hh=R=>R?.direction==="remote"?w("meta.tunnelRemote",{host:R.remoteHost||"127.0.0.1",port:String(R.remotePort??0),local:String(R.localTargetPort??0)}):w("meta.tunnelLocal",{local:String(R?.localPort??0),host:R?.remoteHost??"?",port:String(R?.remotePort??0)}),$o=(p?.sshHosts??[]).find(R=>R?.name===it?.bookName),en=async R=>{try{let z=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({tunnels:R})}),K=await z.json().catch(()=>({}));return!z.ok||!K.ok?(g({kind:"error",text:String(K.error||w("error.saveTunnelFailed"))}),{ok:!1,warnings:[]}):{ok:!0,warnings:Array.isArray(K.warnings)?K.warnings.map(ie=>String(ie)).filter(ie=>ie!==""):[]}}catch(z){return g({kind:"error",text:String(z&&z.message?z.message:z)}),{ok:!1,warnings:[]}}},qo=(R,z)=>{if(R.warnings.length>0){g({kind:"warn",text:R.warnings.join(" ")});return}g({kind:"ok",text:z})},Ko=()=>cc(it,(Array.isArray(p?.sshHosts)?p.sshHosts:[]).map(R=>R?.name),w),Fh=R=>{g({kind:"",text:""}),is(String(R?.name??"")),hr({direction:R?.direction==="remote"?"remote":"local",bookName:String(R?.bookName??""),localPort:R?.localPort?String(R.localPort):"",remoteHost:String(R?.remoteHost??""),remotePort:R?.remotePort?String(R.remotePort):"",localTargetPort:R?.localTargetPort?String(R.localTargetPort):""})},Wh=()=>{is(null),g({kind:"",text:""}),hr(R=>({...R||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))},Uh=()=>{g({kind:"",text:""});let R=Ko();if(!R.ok){g({kind:"error",text:R.error});return}let z=R.tunnel,K=Array.isArray(p?.tunnels)?p.tunnels:[];if(hc(K,z.name)!==void 0){g({kind:"error",text:w("error.tunnelNameTaken",{name:z.name})});return}let ee=[...K,z];c(ie=>({...ie||{},tunnels:ee})),hr(ie=>({...ie||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),en(ee).then(ie=>{ie.ok&&qo(ie,w("msg.tunnelApplied",{name:z.name}))})},zh=()=>{if(Et===null)return;g({kind:"",text:""});let R=Ko();if(!R.ok){g({kind:"error",text:R.error});return}let z=Array.isArray(p?.tunnels)?p.tunnels:[],K=dc(z,Et,R.tunnel,w);if(!K.ok){K.reason==="missing"&&is(null),g({kind:"error",text:K.error});return}let ee=K.tunnels;c(ie=>({...ie||{},tunnels:ee})),en(ee).then(ie=>{if(ie.ok!==!0){c(pe=>({...pe||{},tunnels:z}));return}is(null),hr(pe=>({...pe||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),qo(ie,w("msg.tunnelUpdated",{name:R.tunnel.name}))})},Go=(R,z)=>{c(K=>({...K||{},tunnels:R})),en(R).then(K=>{if(K.ok!==!0){c(ee=>({...ee||{},tunnels:z}));return}K.warnings.length>0&&g({kind:"warn",text:K.warnings.join(" ")})})},jh=R=>{let z=Array.isArray(p?.tunnels)?p.tunnels:[];Et!==null&&String(R??"")===Et&&(is(null),hr(K=>({...K||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))),Go(z.filter(K=>K?.name!==R),z)},$h=(R,z)=>{let K=Array.isArray(p?.tunnels)?p.tunnels:[];Go(K.map(ee=>ee?.name===R?{...ee,enabled:z}:ee),K)},qh=R=>{_e(R?.name??null),Ee(""),be({running:!1,ok:!1,text:""}),de(""),Q(""),rn(),ce(Ot!==null),Ce({name:R?.name??"",host:R?.host??"",port:String(R?.port??22),username:R?.username??"",auth:R?.auth==="key"||R?.auth==="password"?R.auth:"agent",keyPath:R?.keyPath??"",passphrase:R?.passphrase??"",password:R?.password??"",agentForward:R?.agentForward===!0,hostKeyAlias:R?.hostKeyAlias??"",persist:R?.persist!==!1}),Fc().then(z=>Ue(z)),sn(R?.password??"")},Vo=()=>{_e(null),Ce(null),Ee(""),be({running:!1,ok:!1,text:""}),de(""),Q(""),rn()},Kh=async()=>{if(Z===null)return;let R=Z.name.trim(),z=Z.host.trim(),K=Z.username.trim();if(R===""||z===""||K===""){Ee(w("error.nameHostUserRequired"));return}let ee=Number(Z.port);if((!Number.isInteger(ee)||ee<1||ee>65535)&&(ee=22),(p?.sshHosts??[]).some(pe=>pe?.name===R&&R!==he)){Ee(w("error.bookNameTaken",{name:R}));return}if(Z.auth==="key"&&Z.keyPath.trim()===""){Ee(w("error.keyPathRequired"));return}Ee("");let ie=Z.password;if(Z.auth==="password"){let pe=await zc(ne,Z.password,z,ee,K,"PASSWORD");if(pe.error!==void 0){Ee(pe.error);return}pe.value!==void 0&&(ie=pe.value)}c(pe=>({...pe||{},sshHosts:(Array.isArray(pe?.sshHosts)?pe.sshHosts:[]).map(Se=>Se?.name===he?{name:R,host:z,port:ee,username:K,auth:Z.auth,keyPath:Z.keyPath.trim(),passphrase:Z.passphrase,password:ie,agentForward:Z.agentForward,hostKeyAlias:String(Z.hostKeyAlias??"").trim(),persist:Z.persist===!0}:Se)})),Fe(pe=>{let Se={...pe};return delete Se[R],he!==R&&delete Se[he],Se}),_e(null),Ce(null),be({running:!1,ok:!1,text:""}),g({kind:"ok",text:w("msg.hostEdited",{name:R})})},Gh=R=>{he===R&&Vo(),Fe(z=>{let K={...z};return delete K[R],K}),c(z=>({...z||{},sshHosts:(Array.isArray(z?.sshHosts)?z.sshHosts:[]).filter(K=>K?.name!==R)}))},Vh=async R=>{let z=R?.name??"";if(z==="")return;let K={host:R?.host??"",port:Number(R?.port)||22,username:R?.username??"",auth:R?.auth==="key"||R?.auth==="password"?R.auth:"agent",keyPath:R?.keyPath??"",passphrase:R?.passphrase??"",password:R?.password??"",agentForward:R?.agentForward===!0,hostKeyAlias:typeof R?.hostKeyAlias=="string"?R.hostKeyAlias:""};Fe(ie=>({...ie,[z]:{running:!0,text:w("msg.probing")}}));let ee=await So(K,!0);Fe(ie=>{let pe=ie[z]||{};if(ee.result){let Se=ee.result.auth?.ok===!0;return{...ie,[z]:{running:!1,ok:Se,text:Co(ee.result)}}}return{...ie,[z]:{running:!1,ok:!1,text:w("error.probeFailed",{detail:String(ee.error||w("error.unknown"))})}}})},Yh=async R=>{let z=(Array.isArray(p?.hostKeys)?p.hostKeys:[]).filter(K=>!(K?.host===R?.host&&Number(K?.port)===Number(R?.port)));c(K=>({...K||{},hostKeys:z}));try{let K=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:z})}),ee=await K.json().catch(()=>({}));!K.ok||!ee.ok?g({kind:"error",text:String(ee.error||w("error.hostKeyDeleteFailed"))}):g({kind:"ok",text:w("msg.hostKeyDeleted")})}catch(K){g({kind:"error",text:String(K&&K.message?K.message:K)})}},Xh=async()=>{g({kind:"",text:""});try{let z=await(await fetch("/api/dsh-tty/ssh-config",{cache:"no-store"})).json();if(!z.ok){g({kind:"error",text:String(z.error||w("error.sshConfigReadFailed"))});return}let K=Array.isArray(z.entries)?z.entries:[],ee=[...Array.isArray(p?.sshHosts)?p.sshHosts:[]],ie=new Set(ee.map(Be=>Be?.name)),pe=0,Se=0;for(let Be of K)if(!(Be===null||typeof Be!="object"||typeof Be.name!="string")){if(ie.has(Be.name)){Se+=1;continue}ie.add(Be.name),ee.push({name:Be.name,host:String(Be.host??Be.name),port:Number(Be.port)||22,username:String(Be.username??""),auth:Be.auth==="key"?"key":"agent",keyPath:String(Be.keyPath??""),passphrase:"",password:"",agentForward:!1,hostKeyAlias:typeof Be.hostKeyAlias=="string"?Be.hostKeyAlias:""}),pe+=1}c(Be=>({...Be||{},sshHosts:ee}));let me=Array.isArray(z.proxy)?z.proxy.filter(Be=>typeof Be=="string"):[],Ye=Number.isInteger(z.proxyCount)?z.proxyCount:me.length,ur=Array.isArray(z.proxyCommand)?z.proxyCommand.filter(Be=>typeof Be=="string"):[],et=Number.isInteger(z.proxyCommandCount)?z.proxyCommandCount:ur.length,Tr=Number.isInteger(z.skippedOther)?z.skippedOther:0,Jt=Number.isInteger(z.droppedOverflow)?z.droppedOverflow:0,bt=[];Ye>0&&bt.push(w("msg.proxySkipped",{count:Ye,names:me.slice(0,5).join(w("list.separator"))+(Ye>5?w("meta.etc"):"")})),et>0&&bt.push(w("msg.proxyCommandSkipped",{count:et,names:ur.slice(0,5).join(w("list.separator"))+(et>5?w("meta.etc"):"")})),Tr>0&&bt.push(w("msg.skippedNotConcrete",{count:Tr})),Jt>0&&bt.push(w("msg.importOverflow",{count:Jt}));let ra=bt.length>0?w("list.separatorFull")+bt.join(w("list.separatorFull")):"";if(pe===0){let Be=Se>0?w("msg.noNewEntries",{count:Se}):w("msg.noImportableHosts");g({kind:bt.length>0?"error":"ok",text:Be+ra})}else g({kind:bt.length>0?"error":"ok",text:w("msg.importedHosts",{added:pe,skipped:Se})+ra})}catch(R){g({kind:"error",text:String(R&&R.message?R.message:R)})}},Yo=R=>R===null||typeof R!="object"?[]:Array.isArray(R.fingerprints)?R.fingerprints.filter(z=>typeof z=="string"&&z!==""):typeof R.fingerprint=="string"&&R.fingerprint!==""?[R.fingerprint]:[],Jh=async()=>{g({kind:"",text:""});try{let z=await(await fetch("/api/dsh-tty/known-hosts",{cache:"no-store"})).json();if(!z.ok){g({kind:"error",text:String(z.error||w("error.knownHostsReadFailed"))});return}let K=Array.isArray(z.entries)?z.entries:[],ee=[...Array.isArray(p?.hostKeys)?p.hostKeys:[]],ie=new Map;for(let me of ee)me===null||typeof me!="object"||ie.set(String(me.host??"")+":"+String(me.port??22),{record:me,fps:new Set(Yo(me))});let pe=0,Se=0;for(let me of K){if(me===null||typeof me!="object"||typeof me.host!="string")continue;let Ye=Array.isArray(me.fingerprints)?me.fingerprints.filter(Jt=>typeof Jt=="string"&&Jt!==""):[];if(typeof me.fingerprint=="string"&&me.fingerprint!==""&&Ye.push(me.fingerprint),Ye.length===0)continue;let ur=me.host+":"+String(me.port??22),et=ie.get(ur);if(et!==void 0){let Jt=!1;for(let bt of Ye)et.fps.has(bt)||et.fps.size>=8||(et.fps.add(bt),Jt=!0);if(!Jt){Se+=1;continue}delete et.record.fingerprint,et.record.fingerprints=[...et.fps],pe+=1;continue}let Tr={host:me.host,port:Number(me.port)||22,fingerprints:[...new Set(Ye)].slice(0,8)};ie.set(ur,{record:Tr,fps:new Set(Tr.fingerprints)}),ee.push(Tr),pe+=1}if(pe===0){g({kind:"ok",text:Se>0?w("msg.noNewFingerprints",{count:Se}):w("msg.noImportableKnownHosts")});return}c(me=>({...me||{},hostKeys:ee}));try{let me=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:ee})}),Ye=await me.json().catch(()=>({}));if(!me.ok||!Ye.ok){g({kind:"error",text:String(Ye.error||w("error.saveHostKeysFailed"))});return}g({kind:"ok",text:w("msg.importedFingerprints",{added:pe,skipped:Se})+(z.truncated===!0?w("hint.knownHostsTruncated"):"")})}catch(me){g({kind:"error",text:String(me&&me.message?me.message:me)})}}catch(R){g({kind:"error",text:String(R&&R.message?R.message:R)})}},Xo=async R=>{let z=R??B.current??p;v(!0),g({kind:"",text:""});let K=J(z);try{let ee=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(K)}),ie=await ee.json();!ee.ok||!ie.ok?g({kind:"error",text:String(ie.error||w("error.saveFailed"))}):(g({kind:"ok",text:w("msg.saved")}),M.current=JSON.stringify(K),ie.config&&(B.current=ie.config,c(ie.config),Ps(ie.config)))}catch(ee){g({kind:"error",text:String(ee&&ee.message?ee.message:ee)})}v(!1)},tn=R=>"/api/dsh-tty/elevate"+R,Jo=async()=>{try{let z=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json(),K=z&&typeof z.config=="object"&&z.config!==null?z.config:null;if(K===null)return;c(ee=>{if(ee===null)return ee;let ie={...ee,allowProxyCommandGranted:K.allowProxyCommandGranted===!0,allowProxyCommandGrantSource:K.allowProxyCommandGrantSource??null,allowProxyCommandGrantedAt:Number.isFinite(K.allowProxyCommandGrantedAt)?K.allowProxyCommandGrantedAt:null};return B.current=ie,ie})}catch{}},Zo=async()=>{b(null),F(!1);let R=B.current||{},z=M.current!==null&&JSON.stringify(J(R))===M.current,K={...R,allowProxyCommand:!0};B.current=K,c(K),await Jo(),z?(await Xo(K),P(w("elev.granted"))):P(w("elev.grantedNeedSave"))},Qo=async()=>{F(!1),P(""),b({phase:"loading"});try{let R=await fetch(tn(""),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:xi})}),z=await R.json().catch(()=>({}));if(!R.ok){b({phase:"error",error:String(z.error||R.status)});return}if(z.status==="granted"){await Zo();return}b({phase:"pending",command:String(z.command??""),expiresAt:Number(z.expiresAt)||0})}catch(R){b({phase:"error",error:String(R&&R.message?R.message:R)})}},Zh=async()=>{P("");try{let R=await fetch(tn("/revoke"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:xi})}),z=await R.json().catch(()=>({}));if(!R.ok){P(w("elev.error")+String(z.error||R.status));return}await Jo(),P(w("elev.revoked"))}catch(R){P(w("elev.error")+String(R&&R.message?R.message:R))}},Qh=async()=>{let R=x===null?"":String(x.command??"");if(R!==""){if(zo())try{await navigator.clipboard.writeText(R),F(!0);return}catch{}F(!1),P(w("elev.copyManual"))}};r.useEffect(()=>{if(x===null||x.phase!=="pending")return;let R=setInterval(()=>V(Date.now()),1e3),z=setInterval(()=>{fetch(tn("/status"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:xi})}).then(K=>K.json()).then(K=>{K.status==="granted"&&Zo()}).catch(()=>{})},1500);return()=>{clearInterval(R),clearInterval(z)}},[x]);let ed=()=>{if(p.allowProxyCommandGrantSource==="env")return s("span",{className:"tt_cardHint",children:w("elev.viaEnv")});let R=p.allowProxyCommandGrantedAt;return o("span",{className:"tt_capState",children:[Number.isFinite(R)?s("span",{children:w("elev.grantedAt",{time:dm(R)})}):null,s("button",{type:"button",className:"tt_toolBtn tt_capRevoke",onClick:()=>{Zh()},children:w("elev.revoke")})]})},td=()=>{let R=String(x.command??""),z=x.expiresAt>0?Math.max(0,Math.ceil((x.expiresAt-A)/1e3)):0,K=x.phase==="pending"&&x.expiresAt>0&&z===0,ee=()=>{b(null),F(!1)};return o("div",{className:"tt_elevPanel",children:[o("div",{className:"tt_elevHead",children:[s("span",{className:"tt_cardLabel",children:w("elev.title")}),s("button",{type:"button",className:"tt_toolBtn",onClick:ee,children:w("elev.close")})]}),s("span",{className:"tt_cardHint",children:w("elev.lockedWhy")}),x.phase==="error"?s("span",{className:"tt_cardHint tt_sshProbeWarn",children:w("elev.error")+String(x.error??"")}):null,x.phase==="loading"?s("span",{className:"tt_cardHint",children:w("elev.loading")}):null,R===""?null:o("div",{className:"tt_elevSteps",children:[s("span",{className:"tt_cardHint",children:w("elev.step")}),s("div",{className:"tt_elevCommand",children:s("code",{children:R})}),o("div",{className:"tt_elevActions",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Qh()},children:w(O?"elev.copied":"elev.copy")}),K?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Qo()},children:w("elev.regenerate")}):s("span",{className:"tt_cardHint",children:w("elev.expiresIn",{sec:z})})]}),s("span",{className:"tt_cardHint",children:w(K?"elev.expired":"elev.waiting")})]}),p.allowProxyCommand===!0&&p.allowProxyCommandGranted!==!0?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{j("allowProxyCommand",!1),ee()},children:w("elev.disableFirst")}):null,s("span",{className:"tt_cardHint",children:w("elev.otherWay")}),s("span",{className:"tt_cardHint",children:w("elev.envHow",{env:xi})})]})},rd=()=>{let R=p.allowProxyCommandGranted===!0,z=p.allowProxyCommand===!0;return o("div",{className:"tt_capBlock",children:[o("label",{className:"tt_cardField tt_cardRow tt_cardToggle tt_cardDanger",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:z,onChange:K=>{if(!R){Qo();return}j("allowProxyCommand",K.target.checked)}}),s("span",{className:"tt_cardLabel",children:w("check.allowProxyCommand")}),z&&!R?s("span",{className:"tt_badgeWarn",children:w("badge.notEffective")}):null]}),s("span",{className:"tt_cardHint",children:w("hint.allowProxyCommand")}),R?ed():s("span",{className:"tt_cardHint tt_sshProbeWarn",children:w("hint.proxyCommandNotGranted")}),E===""?null:s("span",{className:"tt_cardHint",children:E}),x===null?null:td()]})},rn=()=>{re.current!==null&&(clearTimeout(re.current),re.current=null),oe("")},sn=async R=>{let z=$r(R);if(Zr()===null){ce(!1),Le(!1),ge({text:w(Ot===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),kind:"muted"});return}if(z===""){Le(!1),ge({text:"",kind:""});return}let K=await Wc(z);if(K.unreported===!0){Le(!1),ge({text:w("status.credUnreported",{ref:z}),kind:"plain"});return}if(K.error!==void 0){Le(!1),ge({text:w("error.credStatusFailed",{error:K.error}),kind:"error"});return}let ee=K.view;ge({text:ee.configured?w("status.credStored",{ref:z,source:ee.source!==""?w("meta.credSource",{source:ee.source}):""}):w("status.credUnknown",{ref:z}),kind:ee.configured?"ok":"plain"}),Le(ee.configured===!0&&ee.writable===!0)},sd=async()=>{let R=$r(Z?.password??"");if(R==="")return;let z=await Uc(R);if(z.error!==void 0){ge({text:z.error,kind:"error"});return}Ce(K=>({...K||{},password:""})),ge({text:"",kind:""}),Le(!1)},id=(R,z)=>{let K=String(Z?.[R]??"");if(K===""||K.startsWith("env:")||se===z){rn(),Ce(ee=>({...ee||{},[R]:"env:"+z})),de(""),R==="password"&&sn("env:"+z);return}oe(z),re.current!==null&&clearTimeout(re.current),re.current=setTimeout(()=>{re.current=null,oe("")},4e3)},ea=(R,z)=>{if(Oe===null)return null;if(Oe.length===0)return s("span",{className:"tt_cardHint",children:z});let K=te===R,ee=ve.trim().toUpperCase(),ie=ee===""?Oe:Oe.filter(pe=>pe.toUpperCase().includes(ee));return o("div",{className:"tt_credPicker",children:[s("input",{className:"tt_cardInput",value:K?ve:"",placeholder:w("placeholder.credRef"),title:w("hint.credRefCandidates"),autoComplete:"off",spellCheck:!1,onFocus:()=>{de(R),Q("")},onBlur:pe=>{pe.currentTarget.parentElement.contains(pe.relatedTarget)||de("")},onChange:pe=>{Q(pe.target.value),de(R)}}),...K?[s("div",{className:"tt_envList",children:[...ie.length===0?[s("span",{className:"tt_envMore",children:w("list.noCredRef")})]:ie.slice(0,30).map(pe=>s("button",{type:"button",className:"tt_envItem","data-danger":se===pe?"":void 0,onMouseDown:Se=>Se.preventDefault(),onClick:()=>id(R,pe),children:se===pe?w("list.credOverwrite",{name:pe}):pe},pe)),...ie.length>30?[s("span",{className:"tt_envMore",children:w("list.moreMatches",{count:ie.length-30})})]:[]]},"cred-list-"+R)]:[]]})},nd=()=>{let z=$r(Z?.password??"")!=="",K=Zr()===null;return o("div",{className:"tt_sshRow tt_credRow",children:[z?s("button",{type:"button",className:"tt_toolBtn tt_credClear",disabled:we!==!0,onClick:()=>{sd()},children:w("btn.clearCredential")}):s("label",{className:"tt_credToggle",title:w("hint.rememberCredentialApply"),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:ne,disabled:K,onChange:ee=>ce(ee.target.checked)}),s("span",{children:w("check.rememberCredentialApply")})]}),le.text===""?null:s("span",{className:"tt_credStatus","data-kind":le.kind,children:le.text}),K&&le.text===""?s("span",{className:"tt_credStatus","data-kind":"muted",children:w("error.credPlainUnavailable")}):null]})},ta=()=>{let R=String(Z?.host??"").trim(),z=String(Z?.username??"").trim(),K=Number(Z?.port);if((!Number.isInteger(K)||K<1||K>65535)&&(K=22),R===""||z==="")return Ee(w("error.hostUserRequired")),null;let ee=Z?.auth,ie={host:R,port:K,username:z,auth:ee};if(ee==="key"){let Se=String(Z?.keyPath??"").trim();if(Se==="")return Ee(w("error.keyPathRequired")),null;ie.keyPath=Se,Z?.passphrase!==""&&(ie.passphrase=Z.passphrase)}if(ee==="password"){let Se=String(Z?.password??"");if(Se==="")return Ee(w("error.passwordRequired")),null;ie.password=Se}Z?.agentForward===!0&&(ie.agentForward=!0);let pe=String(Z?.hostKeyAlias??"").trim();return pe!==""&&(ie.hostKeyAlias=pe),ie},od=()=>{Ee("");let R=ta();R!==null&&(be({running:!0,ok:!1,text:w("msg.probing")}),So(R,!1).then(z=>{if(z.result){let K=z.result.auth?.ok===!0;be({running:!1,ok:K,text:Co(z.result)});return}be({running:!1,ok:!1,text:w("error.probeFailed",{detail:String(z.error||w("error.unknown"))})})}))},ad=()=>{Ee("");let R=ta();R!==null&&Qi(R)},ld=()=>{if(Z===null)return null;let R=(z,K,ee,ie,pe)=>o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:z}),s("input",{className:"tt_cardInput",type:ie??"text",value:Z[K]??"",placeholder:ee??"",autoComplete:"off",spellCheck:!1,onChange:Se=>{let me=Se.target.value;Ce(Ye=>({...Ye||{},[K]:me}))},...pe??{}})]});return o("div",{className:"tt_sshEdit",children:[s("div",{className:"tt_sshSection",children:w("section.connection")}),o("div",{className:"tt_sshGrid",children:[R(w("field.bookName"),"name",w("hint.bookNameConflict")),R(w("field.port"),"port","22")]}),R(w("field.host"),"host",w("placeholder.host")),R(w("field.username"),"username","root"),s("div",{className:"tt_sshSection",children:w("section.auth")}),o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.authMethod")}),o("select",{className:"tt_cardInput",value:Z.auth,onChange:z=>Ce(K=>({...K||{},auth:z.target.value})),children:[s("option",{value:"agent",children:w("option.authAgent")}),s("option",{value:"key",children:w("option.authKey")}),s("option",{value:"password",children:w("option.authPassword")})]})]}),...Z.auth==="key"?[R(w("field.keyPath"),"keyPath","~/.ssh/id_ed25519"),R(w("field.passphrase"),"passphrase","","password"),ea("passphrase",w("hint.noCredRefPassphrase"))]:[],...Z.auth==="password"?[R(w("field.password"),"password","","password",{onBlur:()=>{sn(Z.password)}}),nd(),ea("password",w("hint.noCredRefPasswordApply"))]:[],s("div",{className:"tt_sshSection",children:w("section.options")}),o("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:Z.agentForward===!0,onChange:z=>Ce(K=>({...K||{},agentForward:z.target.checked}))}),s("span",{className:"tt_cardLabel",children:w("check.agentForward")})]}),R(w("field.hostKeyAlias"),"hostKeyAlias",w("placeholder.hostKeyAlias")),s("span",{className:"tt_cardHint",children:w("hint.hostKeyAlias")}),ar==="tmux"?o("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:Z.persist===!0,onChange:z=>Ce(K=>({...K||{},persist:z.target.checked}))}),s("span",{className:"tt_cardLabel",children:w("check.persist")})]}):null,ye.text!==""?s("div",{className:"tt_sshProbeResult"+(!ye.running&&ye.ok?" tt_sshProbeOk":"")+(!ye.running&&!ye.ok?" tt_sshProbeBad":""),children:ye.text}):null,He!==""?s("span",{className:"tt_cardMessage tt_cardMessageError",children:He}):null,o("div",{className:"tt_sshActions",children:[o("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:Vo,children:w("btn.cancel")}),s("button",{type:"button",className:"tt_toolBtn",title:w("btn.browseTitle"),onClick:ad,children:w("btn.fileBrowse")}),s("button",{type:"button",className:"tt_toolBtn",disabled:ye.running,title:w("btn.probeTitle"),onClick:od,children:ye.running?w("msg.probing"):w("btn.probe")})]}),o("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_cardSave",onClick:()=>{Kh()},children:w("btn.apply")}),s("span",{className:"tt_cardHint",children:w("hint.appliedOnSave")})]})]})]})},cd=R=>{let z=typeof R?.assistProvider=="string"?R.assistProvider.trim():"",K=typeof R?.assistModel=="string"?R.assistModel.trim():"";return z!==""&&K!==""?z+"/"+K:z!==""?z:K},hd=()=>{if(T.loading)return s("span",{className:"tt_envMore",children:w("list.modelLoading")});if(T.failed)return s("span",{className:"tt_envMore",children:w("list.modelCatalogFailed")});let R=[],z=(p?.assistProvider??"")===""&&(p?.assistModel??"")==="";R.push(s("button",{type:"button",className:"tt_envItem",...z?{"data-active":""}:{},onMouseDown:K=>K.preventDefault(),onClick:()=>{c(K=>({...K||{},assistProvider:"",assistModel:""})),G(!1)},children:w("option.followHostModel")},"assist-route-default"));for(let K of T.groups){let ee=String(K.id??"");if(ee==="")continue;let ie=String(K.name??ee),pe=Array.isArray(K.models)?K.models:[];if(pe.length!==0){R.push(s("span",{className:"tt_envMore",children:ie},"group-"+ee));for(let Se of pe){let me=String(Se.id??"");if(me==="")continue;let Ye=String(Se.name??"")===""?me:String(Se.name),ur=(p?.assistProvider??"")===ee&&(p?.assistModel??"")===me;R.push(s("button",{type:"button",className:"tt_envItem",...ur?{"data-active":""}:{},title:ee+"/"+me,onMouseDown:et=>et.preventDefault(),onClick:()=>{c(et=>({...et||{},assistProvider:ee,assistModel:me})),G(!1)},children:Ye===me?me:Ye},ee+"/"+me))}}}return T.groups.length===0&&R.push(s("span",{className:"tt_envMore",children:w("list.noModelCandidate")},"assist-route-empty")),R},ns=(R,z,K,ee)=>o("label",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:R}),s("input",{className:"tt_cardInput",value:p[z]??"",placeholder:K??"",onChange:ie=>j(z,ie.target.value)}),ee?s("span",{className:"tt_cardHint",children:ee}):null]}),Lr=(R,z,K,ee)=>o("label",{className:"tt_cardField tt_cardRow tt_cardToggle"+(typeof K=="string"&&K!==""?" "+K:""),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:p[z]===!0,disabled:ee===!0&&p[z]!==!0,onChange:ie=>j(z,ie.target.checked)}),s("span",{className:"tt_cardLabel",children:R})]}),os=p?.platform==="win32";return l==="summary"?w("card.desc"):o(_?"div":"li",{className:_?"tt_pageHost":m?"tt_card tt_cardOpen":"tt_card",children:[_?null:o("button",{type:"button",className:"tt_cardHeader","aria-expanded":m,onClick:()=>y(R=>!R),children:[o("span",{className:"tt_cardHeadText",children:[s("span",{className:"tt_cardName",children:w("card.name")}),s("span",{className:"tt_cardDescription",children:w("card.descFull")})]}),s("span",{className:"dshkit_badge",children:"Kit"}),s("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:m?"tt_cardChevron tt_cardChevronOpen":"tt_cardChevron",children:s("path",{d:i,fill:"currentColor"})})]}),_||m?o("div",{className:"tt_cardBody",children:[p===null?s("div",{className:"tt_cardMessage",children:w("list.loadingConfig")}):o("div",{children:[H(w("section.basic")),Lr(w("check.enabled"),"enabled"),Lr(w("check.announce"),"announceToAgent"),os?o("div",{className:"tt_cardField",children:[o("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:!1,disabled:!0}),s("span",{className:"tt_cardLabel",children:w("check.shellIntegration")})]}),s("span",{className:"tt_cardHint",children:w("hint.shellIntegrationWindows")})]}):Lr(w("check.shellIntegrationWindows"),"shellIntegration"),H(w("section.sftp")),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("field.sftpStyle")}),o("select",{className:"tt_cardInput",value:p.sftpStyle==="dual"?"dual":"dialog",onChange:R=>j("sftpStyle",R.target.value),children:[s("option",{value:"dialog",children:w("option.sftpDialog")}),s("option",{value:"dual",children:w("option.sftpDual")})]}),s("span",{className:"tt_cardHint",children:w("hint.sftpDual")})]}),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("field.sftpLimits")}),o("div",{className:"tt_limitGrid",children:[o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.downloadLimit")}),s("input",{className:"tt_cardInput",type:"number",min:0,value:String(Number.isFinite(Number(p?.sftpLimits?.maxDownloadMb))?Number(p.sftpLimits.maxDownloadMb):1024),onChange:R=>ae("maxDownloadMb",Number(R.target.value)||0)})]}),o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.uploadLimit")}),s("input",{className:"tt_cardInput",type:"number",min:0,value:String(Number.isFinite(Number(p?.sftpLimits?.maxUploadMb))?Number(p.sftpLimits.maxUploadMb):2048),onChange:R=>ae("maxUploadMb",Number(R.target.value)||0)})]}),o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.uploadCountLimit")}),s("input",{className:"tt_cardInput",type:"number",min:0,value:String(Number.isFinite(Number(p?.sftpLimits?.maxUploadFiles))?Number(p.sftpLimits.maxUploadFiles):1e3),onChange:R=>ae("maxUploadFiles",Number(R.target.value)||0)})]})]}),s("span",{className:"tt_cardHint",children:w("hint.sftpLimits")})]}),H(w("section.session")),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("field.persistence")}),o("select",{className:"tt_cardInput",value:p.persistence==="tmux"?"tmux":"off",onChange:R=>j("persistence",R.target.value),children:[s("option",{value:"off",children:w("option.persistOff")}),s("option",{value:"tmux",children:w("option.persistTmux")})]}),s("span",{className:"tt_cardHint",children:w("hint.persistence")+(os?w("hint.persistenceWindows"):"")}),Lr(w("check.endOnPageClose"),"endOnPageClose"),Lr(w("check.statsEnabled"),"statsEnabled"),s("span",{className:"tt_cardHint",children:w("hint.statsEnabled")}),rd()]}),H(w("section.assist")),Lr(w("check.assistEnabled"),"assistEnabled"),s("span",{className:"tt_cardHint",children:w("hint.assistEnabled")}),o("div",{className:"tt_cardField",onBlur:R=>{R.currentTarget.contains(R.relatedTarget)||G(!1)},children:[s("span",{className:"tt_cardLabel",children:w("field.assistRoute")}),s("input",{className:"tt_cardInput tt_routeInput",ref:$,readOnly:!0,value:cd(p),autoComplete:"off",spellCheck:!1,onFocus:()=>{G(!0),T.groups.length===0&&!T.loading&&q()},onClick:()=>{G(!0),T.groups.length===0&&!T.loading&&q()},onKeyDown:R=>{R.key==="Escape"&&G(!1)}}),...N?[s("div",{className:"tt_envList tt_routeList",children:hd()},"assist-route-list")]:[],s("span",{className:"tt_cardHint",children:w("hint.assistRoute")})]},"assist-route-field"),ns(w("field.maxSessions"),"maxSessions","4",w("hint.maxSessions")),o("div",{className:"tt_cardField",onBlur:R=>{R.currentTarget.contains(R.relatedTarget)||L(!1)},children:[s("span",{className:"tt_cardLabel",children:w(os?"field.shellWindows":"field.shell")}),s("input",{className:"tt_cardInput",value:p.shell??"",placeholder:w(os?"placeholder.shellWindows":"placeholder.shell"),autoComplete:"off",spellCheck:!1,onFocus:()=>L(!0),onClick:()=>L(!0),onKeyDown:R=>{R.key==="Escape"&&L(!1)},onChange:R=>{j("shell",R.target.value),L(!0)}}),...C?[s("div",{className:"tt_envList tt_shellList",children:(()=>{let R=(p.shell??"").trim().toLowerCase(),z=R===""?U:U.filter(K=>K.toLowerCase().includes(R));return z.length===0?s("span",{className:"tt_envMore",children:w("list.noShellCandidate")}):z.map(K=>s("button",{type:"button",className:"tt_envItem",onMouseDown:ee=>ee.preventDefault(),onClick:()=>{j("shell",K),L(!1)},children:K},K))})()},"shell-list")]:[],s("span",{className:"tt_cardHint",children:w(os?"hint.shellCandidatesWindows":"hint.shellCandidates")})]},"shell-field"),ns("TERM","term","xterm-256color",w("hint.term")),ns("COLORTERM","colorTerm","truecolor",""),ns(w("field.cwd"),"cwd","",w("placeholder.cwd")),ns(w("field.grace"),"reconnectGraceSec","120",w("hint.grace")),H(w("section.ssh")),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("panel.sshBook")}),...Array.isArray(p.sshHosts)&&p.sshHosts.length>0?[s("div",{className:"tt_hostList","data-editing":he!==null?"":void 0,children:p.sshHosts.map(R=>o("div",{children:[o("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:R?.name??""}),s("span",{className:"tt_sshHostTarget",children:yo(R??{})})]}),s("button",{type:"button",className:"tt_toolBtn",disabled:xe[R?.name]?.running===!0,onClick:()=>{Vh(R)},title:w("btn.probeRowTitle"),children:xe[R?.name]?.running===!0?w("msg.testing"):w("btn.test")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>qh(R),children:w("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Gh(R?.name),children:w("btn.delete")})]}),xe[R?.name]&&xe[R?.name].text?s("div",{className:"tt_sshProbeResult"+(xe[R?.name].ok?" tt_sshProbeOk":" tt_sshProbeBad"),children:xe[R?.name].text}):null,he===R?.name?ld():null]},String(R?.name??"")))})]:[s("span",{className:"tt_cardHint",children:w("list.emptySshHosts")})],o("div",{className:"tt_cardRow",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Xh()},children:w("btn.importSshConfig")}),s("span",{className:"tt_cardHint",children:w("hint.importSshConfig")})]}),s("span",{className:"tt_cardHint",children:w("hint.sshBook")})]}),o("div",{className:"tt_cardField",children:[o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("panel.tunnels")}),...Array.isArray(p.tunnels)&&p.tunnels.length>0?[s("div",{children:p.tunnels.map(R=>{let z=tt.find(ie=>ie.name===R?.name),K=z?.state??"stopped",ee=Et!==null&&String(R?.name??"")===Et;return o("div",{className:"tt_sshHostRow","data-editing":ee?"":void 0,children:[s("span",{className:"tt_tunnelDot","data-state":K,title:K}),s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:(R?.name??"")+" \xB7 "+Hh(R??{})}),s("span",{className:"tt_sshHostTarget",children:(R?.bookName??"")+(z?.error?" \xB7 "+z.error:"")+(z?.lastForwardError?" \xB7 "+z.lastForwardError:"")})]}),s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:R?.enabled!==!1,title:w("check.tunnelEnabled"),onChange:ie=>$h(R?.name,ie.target.checked)}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Fh(R),children:w("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>jh(R?.name),children:w("btn.delete")})]},String(R?.name??""))})})]:[s("span",{className:"tt_cardHint",children:w("list.emptyTunnels")})],o("div",{className:"tt_sshEdit",children:[o("div",{className:"tt_cardRow tt_tunnelHead",children:[o("div",{className:"tt_segmented",role:"group","aria-label":w("field.direction"),children:[s("button",{type:"button",className:"tt_segmentedBtn","data-active":it.direction!=="remote"?"":void 0,title:w("option.localForwardTitle"),onClick:()=>jo("direction","local"),children:w("option.localForward")}),s("button",{type:"button",className:"tt_segmentedBtn","data-active":it.direction==="remote"?"":void 0,title:w("option.remoteForwardTitle"),onClick:()=>jo("direction","remote"),children:w("option.remoteForward")})]}),o("select",{className:"tt_cardInput",value:it.bookName,onChange:dr("bookName"),children:[s("option",{value:"",children:w("option.selectBook")}),...Array.isArray(p?.sshHosts)?p.sshHosts.map(R=>s("option",{value:R?.name??"",children:R?.name??""})):[]]})]}),s("span",{className:"tt_cardHint",children:$o!==void 0?w("hint.tunnelViaBook",{book:yo($o)}):w("hint.tunnelBookEmpty")}),it.direction==="local"?o("div",{className:"tt_tunnelEndpoints",children:[o("div",{className:"tt_tunnelHop",children:[o("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:w("hint.localListenFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.localPort"),value:it.localPort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.localListenPort"),onChange:dr("localPort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"local",title:w("hint.flowLocalToRemote"),"aria-hidden":"true",children:"\u2192"})]}),o("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:w("placeholder.remoteHost"),title:w("hint.remoteHostTitle"),value:it.remoteHost,autoComplete:"off","aria-label":w("field.remoteHost"),onChange:dr("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.port"),value:it.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.remotePort"),onChange:dr("remotePort")})]})]}):o("div",{className:"tt_tunnelEndpoints",children:[o("div",{className:"tt_tunnelHop",children:[o("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:w("placeholder.remoteListenHost"),title:w("hint.remoteListenHost"),value:it.remoteHost,autoComplete:"off","aria-label":w("field.remoteListenHost"),onChange:dr("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.listenPort"),value:it.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.remoteListenPort"),onChange:dr("remotePort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"remote",title:w("hint.flowRemoteToLocal"),"aria-hidden":"true",children:"\u2192"})]}),o("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:w("hint.localDialFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.localTargetPort"),value:it.localTargetPort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.localTargetPort"),onChange:dr("localTargetPort")})]})]}),s("div",{className:"tt_tunnelEndpoints",children:[s("span",{className:"tt_tunnelEndLabel",children:it.direction==="local"?w("hint.tunnelLocalSummary"):w("hint.tunnelRemoteSummary")})]}),s("div",{className:"tt_cardRow tt_tunnelActions",children:[Et===null?s("button",{type:"button",className:"tt_cardSave",onClick:Uh,children:w("btn.addTunnel")}):s("button",{type:"button",className:"tt_cardSave",onClick:zh,children:w("btn.saveEdit")}),Et===null?null:s("button",{type:"button",className:"tt_toolBtn",onClick:Wh,children:w("btn.cancel")}),s("span",{className:"tt_cardHint",children:Et===null?w("hint.tunnelAdd"):w("hint.tunnelEditing",{name:Et})})]})]})]}),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("panel.hostKeys")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Jh()},children:w("btn.importKnownHosts")})]}),...Array.isArray(p.hostKeys)&&p.hostKeys.length>0?[s("div",{className:"tt_hostList",children:p.hostKeys.map((R,z)=>o("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:String(R?.host??"")+":"+String(R?.port??22)}),s("span",{className:"tt_sshHostTarget",children:Yo(R).map(K=>"sha256:"+K).join(" / ")})]}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Yh(R)},children:w("btn.delete")})]},String(R?.host??"")+":"+String(R?.port??22)+"#"+String(z)))})]:[s("span",{className:"tt_cardHint",children:w("list.emptyHostKeys")})],s("span",{className:"tt_cardHint",children:w("hint.hostKeys")})]}),o("div",{className:"tt_cardField tt_cardRow",children:[s("button",{className:"tt_cardSave",disabled:f,onClick:()=>{Xo()},children:w(f?"msg.saving":"btn.save")}),s("span",{className:"tt_cardMessage"+(S.kind==="ok"?" tt_cardMessageOk":S.kind==="error"?" tt_cardMessageError":S.kind==="warn"?" tt_cardMessageWarn":""),children:S.text})]})]})]}):null]})}t.inject=["slots","sessions"];let a=["@hyzyn/dsh-tty#tty","@hyzyn/dsh-all#tty"];return t.apply=d=>{Np(d),Qc=d.sessions,d.inject(["remote","remote.credentials"],S=>(Ot=S.remote?.credentials??S["remote.credentials"]??null,()=>{Ot=null}));let l=!1,_=()=>{};zi={set(S){if(S!==l){if(l=S,S){_=vm();return}_(),_=()=>{},Os(),br()}}},gh(!0),Uo();let m="@hyzyn/dsh-all",p=[...new Set(a.map(S=>S.split("#")[0]))].find(S=>S!==m),c=!1,u=[];p!==void 0&&d.slots.inject("plugins.bundle.config",()=>{for(c=!0;u.length>0;){let S=u.pop();typeof S=="function"&&S()}return d.slots.register({name:"plugins.bundle.config",key:p},n)});for(let S of a)d.slots.inject("plugins.row.config",()=>{let g=S.split("#")[0]===p;if(g&&c)return;let x=d.slots.register({name:"plugins.row.config",key:S},n);return g&&u.push(x),x});d.slots.inject("settings.kit.item",()=>d.slots.register({name:"settings.kit.item",id:"tty",order:80,label:()=>w("card.name")},n)),d.slots.inject("settings.plugin.item",()=>d.slots.register({name:"settings.plugin.item",key:"tty",order:100},n));let h=d.provide("ttyConnbar",{version:1,addAction:Xi,requestRender(){br()}}),f=d.provide("ttyTerminal",{version:3,open(S){if(!wr)return;let g=oh(S),x=ah(S,g),b=typeof S?.label=="string"&&S.label!==""?S.label:void 0;if(Is(),S?.reuse!==!1){let E=p_(x);if(E!==null)return To(),Yt(E.sid),E}return To(),Ds(x,b)},mount(S,g){return wr?S_(S,g):()=>{}}}),v=d.provide("ttyPanel",{version:2,isOpen(){return ue!==null&&!Ve},mountPane(S){return hh(S)},minimize(){return qi(),ue!==null&&Ve}});return()=>{zi=null,wr=!1,_(),v(),f(),h(),Os()}},t}});})();
|
|
3487
|
+
`+ic,document.head.appendChild(wi))}var Gi='<svg viewBox="0 0 16 16" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 5l3.5 3L3 11"/><path d="M8.5 11H13"/></svg>',zp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="7" cy="7" r="4.4"/><path d="M10.4 10.4L14 14"/></svg>',jp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.5 4.5h11"/><path d="M6 4.5V3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v1.5"/><path d="M4.5 4.5l.7 8.1a1 1 0 0 0 1 .9h3.6a1 1 0 0 0 1-.9l.7-8.1"/></svg>',$p='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.4"/><path d="M3.5 10.5h-1v-8h8v1"/></svg>',qp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3.5" y="3" width="9" height="11" rx="1.4"/><rect x="5.5" y="1.5" width="5" height="3" rx="1" class="tt_iconPasteHole"/></svg>',Kp='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.5 8a5.5 5.5 0 1 1-1.6-3.9"/><path d="M13.7 1.8v2.7H11"/></svg>',Gp='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1.8 12.8V4.2a1 1 0 0 1 1-1h3l1.4 1.6h6a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H2.8a1 1 0 0 1-1-1z"/></svg>',jc='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 5.5L2 8l2.5 2.5"/><path d="M11.5 5.5L14 8l-2.5 2.5"/><path d="M2.8 8h10.4"/></svg>',$c='<svg viewBox="0 0 16 16" width="13" height="13" fill="currentColor" stroke="none" aria-hidden="true"><circle cx="3.4" cy="8" r="1.35"/><circle cx="8" cy="8" r="1.35"/><circle cx="12.6" cy="8" r="1.35"/></svg>',Vp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4 8h8"/></svg>',Vi='<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 4.5l7 7"/><path d="M11.5 4.5l-7 7"/></svg>',Yi='<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7"/></svg>',Yp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M8 3.6v8.8"/><path d="M3.6 8h8.8"/></svg>',Rs='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12.4V3.9a.9.9 0 0 1 .9-.9h2.9l1.4 1.6h5.9a.9.9 0 0 1 .9.9v6.9a.9.9 0 0 1-.9.9H2.9a.9.9 0 0 1-.9-.9z"/></svg>',qc='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 2.6h4.4l3.6 3.6v7.2a.9.9 0 0 1-.9.9H4.9a.9.9 0 0 1-.9-.9V3.5a.9.9 0 0 1 .9-.9z"/><path d="M8.2 2.7v3.4h3.4"/></svg>',Kc='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6.4 9.6l3.2-3.2"/><path d="M9.2 4.6l1-1a2.5 2.5 0 0 1 3.5 3.5l-1 1"/><path d="M6.8 11.4l-1 1a2.5 2.5 0 0 1-3.5-3.5l1-1"/></svg>',Ao='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 12.6V4.2"/><path d="M4.4 7.8L8 4.2l3.6 3.6"/></svg>',Gc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v7.2"/><path d="M5 7.4L8 10.4l3-3"/><path d="M3.4 12.8h9.2"/></svg>',Xp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 10.4V3.2"/><path d="M5 6.2L8 3.2l3 3"/><path d="M3.4 12.8h9.2"/></svg>',Do='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11.2 2.9l1.9 1.9-7.3 7.3-2.4.5.5-2.4z"/></svg>',qr='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4.6h10"/><path d="M6.2 4.6V3.4a.8.8 0 0 1 .8-.8h2a.8.8 0 0 1 .8.8v1.2"/><path d="M4.6 4.6l.6 8a.9.9 0 0 0 .9.8h3.8a.9.9 0 0 0 .9-.8l.6-8"/></svg>',Po='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.2 8a5.2 5.2 0 1 1-1.5-3.7"/><path d="M13.4 2.2v2.6h-2.6"/></svg>',Vc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12.4V3.9a.9.9 0 0 1 .9-.9h2.9l1.4 1.6h5.9a.9.9 0 0 1 .9.9v6.9a.9.9 0 0 1-.9.9H2.9a.9.9 0 0 1-.9-.9z"/><path d="M8 6.6v3.6"/><path d="M6.2 8.4h3.6"/></svg>',Yc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.4 8h9"/><path d="M9.2 4.8L12.4 8l-3.2 3.2"/></svg>',Xc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12.6 8h-9"/><path d="M6.8 4.8L3.6 8l3.2 3.2"/></svg>',Jp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3.4v9"/><path d="M4.8 9.2L8 12.4l3.2-3.2"/></svg>',Zp='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.4" y="3.2" width="11.2" height="4" rx="1.2"/><rect x="2.4" y="8.8" width="11.2" height="4" rx="1.2"/><path d="M5 5.2h.01"/><path d="M5 10.8h.01"/></svg>',Qp='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 2.6l5.8 10.4H2.2z"/><path d="M8 6.4v3.2"/><path d="M8 11.6h.01"/></svg>',e_='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="8" cy="8" r="5.6"/><path d="M8 7.2v3.6"/><path d="M8 5.1h.01"/></svg>',Jc='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.6"/><path d="M6 6l4 4"/><path d="M10 6l-4 4"/></svg>',t_='<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 2.8v5"/><path d="M11.6 4.6a5.2 5.2 0 1 1-7.2 0"/></svg>',Zc='<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="5.6" cy="6" r="2.8"/><path d="M7.8 7.9l5.4 5.4"/><path d="M10.6 10.7l1.2-1.2"/></svg>',Qc=null,Ae=null,ue=null,Mi=null,Ms=null,Ot=null,mr=null,yr=null,Re=null,Bt=null,ws=null,ys=null,Ai=null,_t=null,Ss=null,lt=null,mt=null,st=null,Kr=null,As=!1,Cs=null,Ve=!1,Qe=null,Di=null,Qr=null,Sr=null,Pi=null,gr=null,xs=1e3,Bi="dsh-tty:tabs",fe=new Map,Ns=new Set,Bo=()=>Ns.size>0,uo=new Set,ke=null,Hs=0,yi=!1,gt=null,Oi=!1,cr=new Map,vr=null,Cr=null,Gr=null,ir=null,Ii=null,ct=null,Vr=null,Gt=[],Ni=!0,St=null,Ct=null,ks=null,bs=null,fo=null,po=new Set;function Xi(e){return po.add(e),()=>po.delete(e)}Xi(({tab:e,addAction:t})=>{wr&&e.exited&&t(Kp,w("btn.reopen"),w("btn.reopenTitle"),()=>Fi(e.sid))});Xi(({tab:e,addAction:t})=>{wr&&t(Gp,"SFTP",w("btn.sftpTitle"),()=>Qi(e.spawnSpec,e.sid))});Xi(({bookName:e,addAction:t})=>{if(!wr)return;let r=e!==""?bh(e):0;if(r>0){t(jc,w("btn.tunnels",{count:r}),w("btn.tunnelsTitle"),s=>uh(s.currentTarget,e));return}e!==""&&t($c,w("btn.more"),w("btn.moreTitle"),s=>A_(s.currentTarget,e))});function Fs(e,t){if(mr===null)return;mr.textContent=e.split("\u2014\u2014")[0],mr.title=e,yr.dataset.state=t,Mi!==null&&(Mi.style.display=t==="connected"?"none":""),Qr!==null&&(Qr.textContent=e),Sr!==null&&(Sr.dataset.state=t);let r=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot");r!==null&&(r.dataset.state=t)}function ao(e,t,r){let s=typeof e=="string"&&e!==""?e:null;if(s!==null){let o=fe.get(s);o!==void 0&&(o.statusText=t,o.statusState=r)}wc(s,ke)&&(Ms=s,Fs(t,r))}function Si(e,t){Ms=null,Fs(e,t)}function Oo(){if(!yc(Ms,ke))return;let e=ke===null?void 0:fe.get(ke);Ms=e===void 0?null:ke;let t=bc(e,w);Fs(t.text,t.state)}function Pe(e){Ae!==null&&Ae.readyState===WebSocket.OPEN&&Ae.send(JSON.stringify(e))}function r_(){let e=[],t=document.createDocumentFragment();for(let r of no(w)){let s=document.createElement("span");s.className="tt_statsItem";let o=document.createElement("span");o.className="tt_statsLabel",o.textContent=r.label,s.appendChild(o);let i=null,n=null;r.kind==="pct"&&(i=document.createElement("span"),i.className="tt_statsMeter",n=document.createElement("span"),n.className="tt_statsMeterFill",i.appendChild(n),s.appendChild(i));let a=document.createElement("span");a.className="tt_statsValue",s.appendChild(a),t.appendChild(s),e.push({item:s,value:a,meter:i,fill:n,slot:null})}return St!==null&&St.appendChild(t),e}function s_(e,t){let r=Tc(t!==void 0?t.stats:null,w);for(let s=0;s<e.length;s+=1){let o=e[s],i=r[s];if(i!==void 0&&(o.slot!==i.slot&&(o.slot=i.slot,o.value.style.minWidth=i.slot>0?i.slot+"ch":""),o.value.textContent!==i.value&&(o.value.textContent=i.value),o.item.getAttribute("title")!==i.title&&o.item.setAttribute("title",i.title),o.fill!==null&&o.meter!==null)){let n=i.pct===null?"0%":Math.max(0,Math.min(100,i.pct)).toFixed(1)+"%";o.fill.style.width!==n&&(o.fill.style.width=n);let a=Cc(i.pct);o.meter.dataset.level!==a&&(o.meter.dataset.level=a)}}}function Ji(){bs=null,fo=null}function i_(){if(ue===null||Ve||!Ni)return!1;let e=vt();return e===void 0||e.embedded===!0||e.exited===!0||e.stats===null||e.stats===void 0?!1:Ec(e.statsAt)}function Rc(){if(Ve)return;let e=vt();if(!(e===void 0||e.embedded===!0||e.fit===null)){try{e.fit.fit()}catch{return}try{e.spawned&&!e.exited&&rs(e)}catch{}}}function xr(){try{n_()}catch(e){console.warn("[dsh-tty] \u72B6\u6001\u6761\u6E32\u67D3\u5931\u8D25\uFF08\u5DF2\u6536\u8D77\uFF09: "+(e instanceof Error?e.message:String(e)));try{St!==null&&(St.hidden=!0,St.textContent=""),Ji(),lt!==null&&delete lt.dataset.stats}catch{}}}function n_(){if(lt===null||St===null)return;let e=i_(),t=lt.dataset.stats!==void 0!==e;if(!e){t&&delete lt.dataset.stats,St.hidden=!0,bs!==null&&(St.textContent="",Ji()),t&&Rc();return}St.hidden=!1,bs===null&&(bs=r_());let r=vt(),s=r===void 0?"":r.sid+":"+String(r.statsAt||0);s!==fo&&(fo=s,s_(bs,r)),t&&(lt.dataset.stats="",Rc())}function eh(){ks===null&&(ks=setInterval(()=>xr(),1e3))}function th(){ks!==null&&(clearInterval(ks),ks=null)}function rh(){if(ue===null||Ve||!Ni)return null;let e=vt();return e===void 0||e.embedded===!0||e.exited===!0?null:e.sid}function Ws(){let e=rh();e!==Ct&&(Ct!==null&&Pe({t:"statsOff",sid:Ct}),Ct=e,e!==null&&Pe({t:"statsOn",sid:e}))}function o_(e){if(e!==rh()){Ws();return}Ct!==null&&Ct!==e&&Pe({t:"statsOff",sid:Ct}),Ct=e,Pe({t:"statsOn",sid:e})}function vt(){return ke!==null?fe.get(ke):void 0}function _o(){try{return uc(Qc?.list?.getSnapshot?.())}catch{return}}function a_(e){if(!(e.term===null||e.exited)){try{if(e.term.buffer.active.length<=e.term.rows)return}catch{return}e.term.reset(),Pe({t:"refresh",sid:e.sid})}}var Ci=null;function sh(e){Ci!==null&&clearTimeout(Ci),Ci=setTimeout(()=>{Ci=null;let t=vt();t!==void 0&&a_(t)},e??200)}var l_=["password","passphrase"];function Mc(e){if(e===null||typeof e!="object"||e.t!=="ssh")return e;let t=e.credsStripped===!0,r={...e};for(let s of l_){let o=r[s];typeof o=="string"&&o!==""&&!o.startsWith("env:")&&(delete r[s],t=!0)}return t&&(r.credsStripped=!0),r}var ih=1;function lr(){try{let e=[...fe.values()].filter(t=>!t.exited&&t.embedded!==!0).map(t=>({sid:t.sid,spawnSpec:Mc(t.spawnSpec),label:t.label}));e.length===0||ue===null?sessionStorage.removeItem(Bi):sessionStorage.setItem(Bi,JSON.stringify({v:ih,tabs:e})),c_([...fe.values()].filter(t=>t.embedded!==!0).map(t=>({spawnSpec:Mc(t.spawnSpec),label:t.label})))}catch(e){console.warn("[dsh-tty] \u6807\u7B7E\u6301\u4E45\u5316\u5931\u8D25\uFF08\u672C\u6B21\u5237\u65B0\u540E\u6807\u7B7E\u5217\u8868\u53EF\u80FD\u4E22\u5931\uFF09: "+(e instanceof Error?e.message:String(e)))}}var mo="dsh-tty:persist-specs";function c_(e){try{let t=e.filter(r=>zs(r.spawnSpec)).map(r=>({spawnSpec:r.spawnSpec,label:r.label}));t.length===0?localStorage.removeItem(mo):localStorage.setItem(mo,JSON.stringify(t))}catch{}}function h_(){try{let e=localStorage.getItem(mo);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>r!==null&&typeof r=="object"&&zs(r.spawnSpec)):[]}catch{return[]}}function d_(){try{let e=sessionStorage.getItem(Bi);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>r!==null&&typeof r=="object"&&typeof r.sid=="string"&&r.sid!==""&&r.spawnSpec!==null&&typeof r.spawnSpec=="object"):t!==null&&typeof t=="object"&&t.v===ih&&Array.isArray(t.tabs)?t.tabs.filter(r=>r!==null&&typeof r=="object"&&typeof r.sid=="string"&&r.sid!==""&&r.spawnSpec!==null&&typeof r.spawnSpec=="object"):[]}catch{return[]}}function Hi(e,t){let r=Ae;return new Promise(s=>{let o=null,i=n=>{let a;try{a=JSON.parse(n.data)}catch{return}a.t===e&&(o!==null&&clearTimeout(o),r.removeEventListener("message",i),s(r===Ae?a:null))};o=setTimeout(()=>{r.removeEventListener("message",i),s(null)},t),r.addEventListener("message",i)})}function u_(e){return e===void 0?null:e.embedded===!0?e.controller!==void 0&&e.controller!==null?e.controller.hostEl:null:e.termEl}function nh(e){if(e===void 0||e.fit===null||e.fit===void 0)return;let t;try{t=e.fit.proposeDimensions()}catch{return}let r=u_(e);return fc(t,r==null?null:{width:r.clientWidth,height:r.clientHeight})}function rs(e){if(e===void 0||e.fit===void 0)return;let t=nh(e);t!==void 0&&(e.lastDims=t,Pe({t:"resize",sid:e.sid,cols:t.cols,rows:t.rows}))}function f_(e){if(e===void 0||e.fit===void 0)return;let t=e.term,r=t!==null&&t.buffer!==void 0?t.buffer.active:null,s=r==null?null:{atBottom:r.viewportY>=r.baseY,line:r.viewportY};try{e.fit.fit()}catch{return}if(s!==null)try{s.atBottom?t.scrollToBottom():t.scrollToLine(Math.min(s.line,t.buffer.active.baseY))}catch{}e.exited||rs(e)}function Ur(e,t,r,s){if(e.overlayEl===null||e.overlayEl===void 0)return;let o=e.overlayEl;if(t===""||t===void 0){o.textContent="";return}let i=s==="error"||s==="info"?s:"exited";o.innerHTML='<div class="tt_overlayCard" data-kind="'+i+'"><span class="tt_overlayIcon">'+(i==="error"?Jc:i==="info"?Po:t_)+'</span><span class="tt_overlayText"><span class="tt_overlayMain"></span>'+(r===void 0||r===""?"":'<span class="tt_overlayHint"></span>')+"</span></div>",o.querySelector(".tt_overlayMain").textContent=t,r!==void 0&&r!==""&&(o.querySelector(".tt_overlayHint").textContent=r)}function Te(e,t=""){try{let r=getComputedStyle(document.body).getPropertyValue(e).trim();return r!==""?r:t}catch{return t}}function ss(e){let t=Te("--tt-accent"),r={};r.background=Te("--tt-term-bg"),r.foreground=Te("--tt-term-fg"),r.cursor=t,r.cursorAccent=Te("--tt-term-cursor-accent"),r.selectionBackground=Te("--tt-term-selection"),r.black=Te("--tt-an-black"),r.red=Te("--tt-an-red"),r.green=Te("--tt-an-green"),r.yellow=Te("--tt-an-yellow"),r.blue=Te("--tt-an-blue"),r.magenta=Te("--tt-an-magenta"),r.cyan=Te("--tt-an-cyan"),r.white=Te("--tt-an-white"),r.brightBlack=Te("--tt-an-bright-black"),r.brightRed=Te("--tt-an-bright-red"),r.brightGreen=Te("--tt-an-bright-green"),r.brightYellow=Te("--tt-an-bright-yellow"),r.brightBlue=Te("--tt-an-bright-blue"),r.brightMagenta=Te("--tt-an-bright-magenta"),r.brightCyan=Te("--tt-an-bright-cyan"),r.brightWhite=Te("--tt-an-bright-white");let s=new Ic.Terminal({cursorBlink:!0,cursorStyle:"bar",cursorInactiveStyle:"outline",fontSize:13,fontFamily:'"JetBrains Mono", "SF Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace',fontWeight:400,fontWeightBold:600,lineHeight:1.35,scrollback:5e3,convertEol:!1,allowProposedApi:!0,theme:r}),o=new Nc.FitAddon,i=new Ba;s.loadAddon(o),s.loadAddon(i),s.loadAddon(new Oa);let n=document.createElement("div");n.className="tt_term";let a=document.createElement("div");a.className="tt_overlay",a.addEventListener("click",()=>{a.textContent="",Fi(e.sid)}),a.setAttribute("role","button"),a.setAttribute("aria-label",w("btn.reopenSession")),a.tabIndex=0,a.addEventListener("keydown",d=>{(d.key==="Enter"||d.key===" "||d.key==="Spacebar")&&(d.preventDefault(),a.textContent="",Fi(e.sid))}),n.appendChild(a),s.open(n);try{o.fit()}catch{}try{let d=new sc;d.onContextLoss(()=>{try{d.dispose()}catch{}}),s.loadAddon(d)}catch{}s.onData(d=>{Pe({t:"input",sid:e.sid,d}),cr.delete(e.sid)&&kr()}),s.onResize(()=>{zs(e.spawnSpec)&&sh(200)}),s.attachCustomKeyEventHandler(d=>e.embedded===!0?!0:(d.ctrlKey||d.metaKey)&&d.key.toLowerCase()==="f"?(d.preventDefault(),Bh(),!1):!0),e.term=s,e.fit=o,e.search=i,e.termEl=n,e.overlayEl=a}function Ac(e){return e===null||typeof e!="object"?"":["t","name","host","port","username","command","cwd","persist","persistName"].map(r=>r+"="+String(e[r]??"")).join("\0")}function p_(e){let t=Ac(e);if(t==="")return null;for(let r of fe.values())if(r.exited!==!0&&r.embedded!==!0&&Ac(r.spawnSpec)===t)return r;return null}function Ds(e,t){let r=Ki(),s={sid:r,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e??om(),label:t};return ss(s),fe.set(r,s),Hs+=1,ht(),Yt(r),Zi(s),lr(),s}function __(e){if(Array.isArray(e))for(let t of e){if(t===null||typeof t!="object"||t.owner!=="agent"||t.exited===!0)continue;let r=typeof t.sid=="string"?t.sid:"";if(r===""||fe.has(r))continue;let s={sid:r,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,agentOwned:!0,spawnSpec:{t:"spawn",cwd:typeof t.cwd=="string"?t.cwd:_o()},label:"agent"+(t.kind==="ssh"&&typeof t.target=="string"&&t.target!==""?" \xB7 "+t.target:"")};ss(s),fe.set(r,s),Hs+=1,ht(),m_()&&s.termEl!==null&<!==null&&ke===null&&Yt(r),Pe({t:"attach",sid:r}),g_()}}function m_(){return ue!==null&&Ve!==!0}function g_(){try{lr()}catch{}}function v_(e){if(__(e),!Array.isArray(e))return;let t=vi(e.filter(r=>r!==null&&typeof r=="object"&&r.owner==="agent"));for(let[r,s]of[...fe])s.agentOwned===!0&&(t.has(r)||s.exited!==!0&&s.live===!0&&(s.exited=!0,s.live=!1,ht()))}function b_(e){if(fe.has(e.sid))return fe.get(e.sid);let t={sid:e.sid,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e.spawnSpec,label:typeof e.label=="string"?e.label:void 0};ss(t),fe.set(t.sid,t),Hs+=1,ht(),Yt(t.sid),Pe({t:"attach",sid:t.sid})}function w_(e){if(!(e?.spawnSpec?.credsStripped!==!0||e.term===null))try{e.term.writeln("\x1B[2m[dsh-tty] "+w("msg.passwordNotStored")+"\x1B[0m")}catch{}}function Zi(e){w_(e);let t=nh(e);t!==void 0&&(e.lastDims=t);let r=t!==void 0?t:e.lastDims!==void 0?e.lastDims:{cols:80,rows:24},s={...e.spawnSpec,sid:e.sid,cols:r.cols,rows:r.rows};if(Ae===null||Ae.readyState!==WebSocket.OPEN){uo.add({tab:e,frame:s});return}Pe(s)}function Dc(e){let t={sid:Ki(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e.spawnSpec,label:typeof e.label=="string"?e.label:void 0};ss(t),fe.set(t.sid,t),Hs+=1,ht(),Yt(t.sid),Zi(t)}function Fi(e){let t=fe.get(e);if(t===void 0)return;if(t.embedded===!0){ch(t);return}let r=t.spawnSpec,s=t.label;if(Pe({t:"kill",sid:e}),t.term!==null)try{t.term.dispose()}catch{}t.termEl!==null&&t.termEl.remove(),fe.delete(e);let o={sid:Ki(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:r,label:s};ss(o),fe.set(o.sid,o),ht(),Yt(o.sid),Zi(o),lr()}function go(e){let t=fe.get(e);if(t!==void 0){if(xt!==null&&xt.ownerKey===e&&Ls(!0),Pe({t:"kill",sid:e}),fe.delete(e),Cr===e&&kt(),cr.delete(e),kr(),Ns.delete(e),t.term!==null)try{t.term.dispose()}catch{}if(t.termEl!==null&&t.termEl.remove(),ke===e){ke=null;let r=[...fe.entries()].filter(([,s])=>s.embedded!==!0).map(([s])=>s).pop()??null;r!==null&&Yt(r)}ht(),Oo(),[...fe.values()].some(r=>r.embedded!==!0)?lr():Os()}}function oh(e){let t=typeof e?.command=="string"?e.command.trim():"";if(t==="")throw new Error(w("error.terminalNeedsCommand"));if(/[\r\n\0]/.test(t))throw new Error(w("error.terminalCommandSingleLine"));return t}function ah(e,t){return typeof e?.book=="string"&&e.book!==""?{t:"ssh",name:e.book,command:t}:e?.spec!==null&&typeof e?.spec=="object"?{t:"ssh",...e.spec,command:t}:{t:"spawn",...typeof e?.cwd=="string"&&e.cwd!==""?{cwd:e.cwd}:{},command:t}}function y_(e){let t=e.controller;t===void 0||t.observer!==null||(t.observer=new ResizeObserver(()=>{if(!(t.disposed||t.tab!==e||e.term===null)){try{e.fit.fit()}catch{return}e.spawned&&!e.exited&&rs(e)}}),t.observer.observe(t.hostEl))}function lh(e,t,r){let s={sid:Ki(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,embedded:!0,controller:e,spawnSpec:t,label:r};return ss(s),fe.set(s.sid,s),Ns.add(s.sid),e.hostEl.appendChild(s.termEl),y_(s),Zi(s),s}function ch(e){let t=e.controller;if(!(t===void 0||t.disposed)){e.exited||Pe({t:"kill",sid:e.sid});try{e.term?.dispose()}catch{}return e.termEl?.remove(),fe.delete(e.sid),Ns.delete(e.sid),t.observer!==null&&(t.observer.disconnect(),t.observer=null),t.tab=lh(t,e.spawnSpec,e.label),ke===e.sid&&(ke=t.tab.sid,Oo()),t.tab}}function S_(e,t){if(!(e instanceof HTMLElement))throw new Error(w("error.terminalNeedsHost"));let r=oh(t),s=ah(t,r),o=typeof t?.label=="string"&&t.label!==""?t.label:void 0;Is();let i={hostEl:e,tab:null,observer:null,disposed:!1};return i.tab=lh(i,s,o),lm(),()=>C_(i)}function C_(e){if(e.disposed)return;e.disposed=!0,e.observer!==null&&(e.observer.disconnect(),e.observer=null);let t=e.tab;if(t!==null){t.exited||Pe({t:"kill",sid:t.sid});try{t.term?.dispose()}catch{}t.termEl?.remove(),fe.delete(t.sid),Ns.delete(t.sid),e.tab=null}if(ue===null&&!Bo()&&Ae!==null){As=!0;try{Ae.close()}catch{}Ae=null}}var x_=460,k_=280,E_=320,L_=160,xt=null,zr=x_,jr=E_;function Io(){let e=ue!==null?ue.querySelector(".tt_modal"):null,t=e!==null?e:ue;return t!==null?t.getBoundingClientRect():null}var No=e=>e==="bottom"?L_:k_;function T_(e){let t=Io();if(t===null)return 900;let r=e==="bottom"?t.height:t.width;return Math.max(No(e),Math.round(r*.72))}function Es(e,t){return Math.min(T_(e),Math.max(No(e),Math.round(t)))}function ki(){let e=xt;if(e!==null){if(e.collapsed){e.el.style.width="",e.el.style.height="",e.el.style.flexBasis="";return}if(e.side==="bottom"){jr=Es("bottom",jr),e.el.style.width="",e.el.style.height=String(jr)+"px",e.el.style.flexBasis=String(jr)+"px";return}zr=Es("right",zr),e.el.style.height="",e.el.style.width=String(zr)+"px",e.el.style.flexBasis=String(zr)+"px"}}function Ls(e){let t=xt;if(t!==null){if(xt=null,t.disposed=!0,e&&t.onClose!==null)try{t.onClose()}catch(r){console.warn("[dsh-tty] ttyPanel.onClose \u629B\u9519\uFF1A"+(r instanceof Error?r.message:String(r)))}try{t.el.remove()}catch{}mt!==null&&delete mt.dataset.side}}function hh(e){if(To(),mt===null)throw new Error(w("error.panelNotReady"));xt!==null&&Ls(!0),Is();let t=Wr(e?.ownerSid,ke),r=e?.side==="bottom"?"bottom":"right",s=Math.max(r==="bottom"?120:200,Math.round(typeof e?.min=="number"&&Number.isFinite(e.min)?e.min:No(r)));if(typeof e?.size=="number"&&Number.isFinite(e.size)){let c=Es(r,e.size);r==="bottom"?jr=c:zr=c}let o=document.createElement("div");o.className="tt_dockPane",o.dataset.side=r,mt.dataset.side=r,o.innerHTML='<div class="tt_dockPaneResize" title="'+w(r==="bottom"?"panel.dragHeight":"panel.dragWidth")+'"></div><div class="tt_dockPaneHead"><span class="tt_dockPaneTitle"></span><span class="tt_dockPaneHint"></span><span class="tt_dockPaneSpacer"></span><button class="tt_dockPaneFold" type="button"></button><button class="tt_dockPaneClose" type="button" title="'+w("btn.closePane")+'">'+Vi+'</button></div><div class="tt_dockPaneBody"></div>',mt.appendChild(o);let i=o.querySelector(".tt_dockPaneTitle"),n=o.querySelector(".tt_dockPaneHint"),a=o.querySelector(".tt_dockPaneBody"),d=o.querySelector(".tt_dockPaneFold"),l=o.querySelector(".tt_dockPaneClose"),_=o.querySelector(".tt_dockPaneResize"),m={el:o,element:a,disposed:!1,collapsed:!1,side:r,minSize:s,ownerKey:t,onClose:typeof e?.onClose=="function"?e.onClose:null},y=()=>r==="bottom"?m.collapsed?Ao:Jp:m.collapsed?Xc:Yc,p=c=>{m.collapsed=c===!0,m.collapsed?o.dataset.collapsed="1":delete o.dataset.collapsed,d.innerHTML=y(),d.title=m.collapsed?w("btn.expandPane"):w("btn.collapsePane"),d.setAttribute("aria-label",d.title),ki()};return m.setTitle=c=>{i.textContent=typeof c=="string"?c:""},m.setHint=c=>{n.textContent=typeof c=="string"?c:""},m.isCollapsed=()=>m.collapsed===!0,m.collapse=()=>p(!0),m.expand=()=>p(!1),m.toggle=()=>p(!m.collapsed),m.dispose=()=>{m.disposed||xt!==m||Ls(!1)},_.addEventListener("mousedown",c=>{if(c.button!==0||m.collapsed)return;c.preventDefault();let u=c.clientX,h=c.clientY,f=o.getBoundingClientRect(),v=g=>{r==="bottom"?jr=Es("bottom",Math.max(s,f.height+(h-g.clientY))):zr=Es("right",Math.max(s,f.width+(u-g.clientX))),ki()},S=()=>{document.removeEventListener("mousemove",v),document.removeEventListener("mouseup",S),document.body.style.userSelect=""};document.body.style.userSelect="none",document.addEventListener("mousemove",v),document.addEventListener("mouseup",S)}),_.addEventListener("dblclick",()=>p(!m.collapsed)),d.addEventListener("click",()=>p(!m.collapsed)),l.addEventListener("click",()=>Ls(!0)),m.setTitle(typeof e?.title=="string"?e.title:""),m.setHint(typeof e?.hint=="string"?e.hint:""),p(e?.collapsed===!0),xt=m,ki(),dh(),m}function dh(){let e=xt;if(e!==null){if(so(e.ownerKey,ke)){delete e.el.dataset.dockHidden,mt!==null&&(mt.dataset.side=e.side);return}e.el.dataset.dockHidden="1",mt!==null&&delete mt.dataset.side}}function Yt(e){let t=fe.get(e);if(t!==void 0&&t.embedded!==!0){ke=e,kt(),kr();for(let[r,s]of fe)s.embedded!==!0&&s.termEl!==null&&(s.termEl.style.display=r===e?"":"none");t.embedded!==!0&<!==null&&t.termEl!==null&&t.termEl.parentElement!==lt&<.appendChild(t.termEl),Ws(),xr(),ht(),br(),dh();try{t.fit.fit()}catch{}t.spawned&&!t.exited&&rs(t),Ur(t,t.exited?w("status.exited"):"",t.exited?w("btn.clickReopen"):"","exited"),Oo()}}function lo(e){if(Re===null)return;let t=fe.get(e);if(t===void 0)return;let s=Re.querySelector(`[data-sid="${e}"]`)?.querySelector(".tt_tabDot");if(s==null)return;s.dataset.state=Wi(t);let o=ct===null?null:ct.querySelector('[data-sid="'+e+'"] .tt_tabDot');o!==null&&(o.dataset.state=Wi(t))}var co=!1;function ht(){if(Re===null)return;if(Re.querySelector(".tt_tabRename")!==null){co||(co=!0,setTimeout(()=>{co=!1,ht()},1e3));return}Re.textContent="";for(let[t,r]of fe){if(r.embedded===!0)continue;let s=document.createElement("button");s.className="tt_tab",s.dataset.sid=t,t===ke&&(s.dataset.active="");let o=document.createElement("span");o.className="tt_tabDot",o.dataset.state=Wi(r),s.appendChild(o);let i=document.createElement("span");i.className="tt_tabLabel",i.textContent=r.label||w("panel.tabLabel",{n:Ho(t)}),i.addEventListener("dblclick",a=>{a.stopPropagation(),D_(t,s)});let n=document.createElement("span");n.className="tt_tabClose",n.title=w("btn.close"),n.innerHTML=Yi,n.setAttribute("role","button"),n.setAttribute("aria-label",w("btn.closeTabAria",{label:r.label||""})),n.tabIndex=0,n.addEventListener("keydown",a=>{(a.key==="Enter"||a.key===" "||a.key==="Spacebar")&&(a.preventDefault(),a.stopPropagation(),go(t))}),s.title=i.textContent,s.appendChild(i),s.appendChild(n),s.addEventListener("click",a=>{if(a.target.closest(".tt_tabClose")!==null){a.stopPropagation(),go(t);return}Yt(t)}),Re.appendChild(s)}let e=Re.querySelector("[data-active]");e!==null&&typeof e.scrollIntoView=="function"&&e.scrollIntoView({block:"nearest",inline:"nearest"}),vo(),ct!==null&&fe.size===0&&Xt()}function vo(){if(Re===null)return;let e=Re.scrollWidth-Re.clientWidth,t=e>1;if(Bt!==null&&(Bt.hidden=!t,t?Bt.title=w("btn.tabListTitle",{n:fe.size}):ct!==null&&Xt()),!t){delete Re.dataset.edge;return}let r=Re.scrollLeft>1,s=Re.scrollLeft<e-1;Re.dataset.edge=r&&s?"both":s?"end":"start",ct!==null&&Ch()}function Wi(e){return e.exited?"exited":e.live===!0?"connected":e.errored===!0?"error":"connecting"}function R_(e){if(Re===null||Math.abs(e.deltaY)<=Math.abs(e.deltaX))return;let t=Re.scrollWidth-Re.clientWidth;if(t<=1)return;let r=Math.max(0,Math.min(t,Re.scrollLeft+e.deltaY));r!==Re.scrollLeft&&(e.preventDefault(),Re.scrollLeft=r)}function M_(e){return e?.direction==="remote"?w("meta.tunnelRemote",{host:e.remoteHost||"127.0.0.1",port:String(e.remotePort??0),local:String(e.localTargetPort??0)}):w("meta.tunnelLocal",{local:String(e?.localPort??0),host:e?.remoteHost??"?",port:String(e?.remotePort??0)})}function br(){if(ws===null||Ai===null||Ss===null||ys===null)return;Ss.textContent="";let e=vt(),t=e?.spawnSpec??{};if(e===void 0||t.t!=="ssh"){ws.dataset.hidden="";return}delete ws.dataset.hidden;let r=Number(t.port);Ai.textContent=typeof e.target=="string"&&e.target!==""?e.target:typeof t.name=="string"&&t.name!==""?t.name:String(t.username??"")+"@"+String(t.host??"")+(Number.isInteger(r)&&r!==22?":"+r:""),_t!==null&&(e.persistTmux===!0?(_t.textContent="tmux",_t.dataset.state="ok",_t.title=w("status.tmuxPersistedTitle")):t.persist===!0&&e.spawned===!0?(_t.textContent=w("status.notPersisted"),_t.dataset.state="warn",_t.title=w("status.tmuxUnavailableTitle")):(_t.textContent="",delete _t.dataset.state,_t.removeAttribute("title")));let s=e.exited?"exited":e.live===!0?"connected":e.errored===!0?"error":"connecting";ys.dataset.state=s,ys.title=w(s==="connected"?"status.connected":s==="connecting"?"status.connecting":s==="error"?"status.errored":"status.exited");let o=(n,a,d,l)=>{let _=document.createElement("button");_.type="button",_.className="tt_toolBtn tt_connAct",_.title=d,_.innerHTML=n+"<span></span>",_.lastElementChild.textContent=a,_.addEventListener("click",l),Ss.appendChild(_)};if(typeof t.command=="string"&&t.command!=="")return;let i=typeof t.name=="string"?t.name:"";for(let n of po)try{n({tab:e,spec:t,bookName:i,addAction:o})}catch(a){console.warn("[dsh-tty] connbar action failed: "+(a instanceof Error?a.message:String(a)))}}function A_(e,t){if(Yr!==null){Ei();return}let r=document.createElement("div");r.className="tt_addMenu tt_connMore",Yr=r,ko(r,w("panel.tunnels"),w("hint.tunnelsSettings"),()=>{Ei(),uh(e,t)},void 0,jc),document.body.appendChild(r);let s=e.getBoundingClientRect(),o=r.offsetWidth,n=s.left+o>window.innerWidth-8?s.right-o:s.left;r.style.left=Math.max(8,Math.min(n,window.innerWidth-o-8))+"px",r.style.top=s.bottom+6+"px";let a=d=>{Yr===r&&(r.contains(d.target)||e.contains(d.target)||Ei())};Ti=a,setTimeout(()=>document.addEventListener("mousedown",a,!0),0)}function Ei(){Ti!==null&&(document.removeEventListener("mousedown",Ti,!0),Ti=null),Yr!==null&&(Yr.remove(),Yr=null)}var pr=null,Li=null,Yr=null,Ti=null;function Ui(){Li!==null&&(document.removeEventListener("mousedown",Li,!0),Li=null),pr!==null&&(pr.remove(),pr=null)}function uh(e,t){if(pr!==null){Ui();return}let r=document.createElement("div");r.className="tt_tunnelPop";let s=document.createElement("div");s.className="tt_tunnelPopTitle",s.textContent=w("panel.tunnelsFor",{name:t}),r.appendChild(s);let o=document.createElement("div");o.textContent=w("list.loading"),r.appendChild(o);let i=document.createElement("span");i.className="tt_cardHint",i.textContent=w("hint.tunnelsCard"),r.appendChild(i),document.body.appendChild(r),pr=r;let n=e.getBoundingClientRect();r.style.top=String(n.bottom+6)+"px",r.style.left=String(Math.max(8,n.right-340))+"px";let a=d=>{pr===r&&(r.contains(d.target)||e.contains(d.target)||Ui())};Li=a,setTimeout(()=>document.addEventListener("mousedown",a,!0),0),(async()=>{let d=[];try{let m=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();m.ok&&Array.isArray(m.tunnels)&&(d=m.tunnels)}catch{}if(pr!==r)return;o.textContent="";let l=Fo.filter(_=>_?.bookName===t&&_?.enabled!==!1);if(l.length===0){let _=document.createElement("span");_.className="tt_cardHint",_.textContent=w("list.noActiveTunnels"),o.appendChild(_);return}for(let _ of l){let m=d.find(h=>h?.name===_?.name),y=m?.state??"stopped",p=document.createElement("div");p.className="tt_tunnelPopRow";let c=document.createElement("span");c.className="tt_connDot",c.dataset.state=y==="active"?"connected":y==="error"?"error":"connecting";let u=document.createElement("span");u.className="tt_connTarget",u.title=String(m?.error??m?.lastForwardError??""),u.textContent=M_(_)+" \xB7 "+y+(m?.fatal===!0?w("status.fatalSuffix"):""),p.appendChild(c),p.appendChild(u),o.appendChild(p)}})()}function Ho(e){let t=1;for(let r of fe.keys()){if(r===e)return String(t);t+=1}return String(t)}function D_(e,t){let r=fe.get(e);if(r===void 0||t.querySelector(".tt_tabRename")!==null)return;let s=t.querySelector(".tt_tabLabel");if(s===null)return;let o=document.createElement("input");o.className="tt_tabRename",o.value=r.label||w("panel.tabLabel",{n:Ho(e)}),s.replaceWith(o),o.focus(),o.select();let i=!1,n=()=>{if(i)return;i=!0;let d=o.value.trim();r.label=d!==""?d:void 0,ht(),lr()},a=()=>{i||(i=!0,ht())};o.addEventListener("keydown",d=>{d.stopPropagation(),d.key==="Enter"?n():d.key==="Escape"&&a()}),o.addEventListener("blur",n),o.addEventListener("click",d=>d.stopPropagation())}var Fo=[],fh="dialog",ar="off",Kt={maxDownloadMb:1024,maxUploadMb:2048,maxUploadFiles:1e3},ph="dsh-tty:show-hidden",_r=(()=>{try{return localStorage.getItem(ph)==="1"}catch{return!1}})();function P_(e){_r=e===!0;try{localStorage.setItem(ph,_r?"1":"0")}catch{}for(let t of bo)try{t(_r)}catch{}}var bo=new Set,wo=null,Xr=null,_h=!1,mh=!1,or=null,zi=null,wr=!1;function gh(e){wr=e,zi!==null&&zi.set(e)}function B_(e){gh(!(e!==null&&typeof e=="object"&&e.enabled===!1)),e!==null&&typeof e=="object"&&typeof e.statsEnabled=="boolean"&&e.statsEnabled!==Ni&&(Ni=e.statsEnabled,Ws(),xr())}function Ps(e){B_(e),e!==null&&typeof e=="object"&&Array.isArray(e.sshHosts)&&(Gt=e.sshHosts),e!==null&&typeof e=="object"&&Array.isArray(e.tunnels)&&(Fo=e.tunnels),e!==null&&typeof e=="object"&&(e.sftpStyle==="dual"||e.sftpStyle==="dialog")&&(fh=e.sftpStyle),e!==null&&typeof e=="object"&&(e.persistence==="tmux"||e.persistence==="off")&&(ar=e.persistence),e!==null&&typeof e=="object"&&typeof e.sftpLimits=="object"&&e.sftpLimits!==null&&(Kt={...Kt,...e.sftpLimits}),e!==null&&typeof e=="object"&&Number.isInteger(e.maxSessions)&&e.maxSessions>=1&&(Xr=e.maxSessions),e!==null&&typeof e=="object"&&typeof e.allowProxyCommand=="boolean"&&(_h=e.allowProxyCommand),e!==null&&typeof e=="object"&&typeof e.assistEnabled=="boolean"&&(Oi=e.assistEnabled,Oi||kt(),kr()),e!==null&&typeof e=="object"&&typeof e.allowProxyCommandGranted=="boolean"&&(mh=e.allowProxyCommandGranted)}function O_(e,t){let r=t==="error"||t==="info"?t:"warn",s=document.createElement("div");s.className="tt_toast",s.dataset.kind=r,s.innerHTML='<span class="tt_toastIcon">'+(r==="error"?Jc:r==="info"?e_:Qp)+'</span><span class="tt_toastText"></span>',s.lastElementChild.textContent=e,document.body.appendChild(s),setTimeout(()=>s.remove(),4e3)}async function vh(){try{Pe({t:"sessions"});let e=await Hi("sessions",3e3);if(e!==null&&Array.isArray(e.list))return or=_c(e.list),or}catch{}return null}async function ji(){if(await vh(),Xr===null||or===null||or<Xr)return null;let e=[...fe.values()].filter(o=>!o.exited).length,t=Math.max(0,or-e),r=t>0?w("msg.maxSessionsOthers",{count:t}):"",s=w("msg.maxSessions",{live:or,max:Xr,own:e,others:r});return O_(s),s}function I_(){return Xr!==null&&or!==null&&or>=Xr}function Wo(){return Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4)}function bh(e){return Fo.filter(t=>t?.bookName===e&&t?.enabled!==!1).length}function yo(e){let t=Number(e?.port),r=Number.isInteger(t)&&t!==22?":"+t:"",s=e?.auth==="key"?"key":e?.auth==="password"?"password":"agent",o=e?.agentForward===!0?" \xB7 fwd":"";return String(e?.username??"")+"@"+String(e?.host??"")+r+" \xB7 "+s+o}async function So(e,t){let r=await fetch("/api/dsh-tty/probe",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...e,bookRecord:t===!0})}),s=await r.json().catch(()=>({}));return s&&s.ok===!1&&s.error?{error:String(s.error)}:s&&s.result?{result:s.result}:{error:String(s&&s.error?s.error:w("error.probeHttp",{status:r.status}))}}function Co(e,t){if(!e)return w("msg.probing");let r=e,s=typeof r.tcp?.ms=="number"?r.tcp.ms:null,o=typeof r.auth?.ms=="number"?r.auth.ms:null,i=[];if(r.jump!==null&&typeof r.jump=="object"&&typeof r.jump.label=="string"&&r.jump.label!==""){let _=typeof r.jump.tcp?.ms=="number"?r.jump.tcp.ms:null,m=r.jump.tcp?.ok?_!==null?_+"ms":w("meta.reachable"):w("meta.unreachable");i.push(w("meta.jumpStage",{label:r.jump.label})+" "+m)}r.proxy!==null&&typeof r.proxy=="object"&&i.push(r.proxy.active===!0?w("meta.probeProxy"):w("meta.probeProxyOff")),r.tcp?.ok?i.push("TCP "+(s!==null?s+"ms":w("meta.reachable"))):r.tcp?.skipped===!0&&i.push(w("meta.probeTcpSkipped")),r.banner?.ok&&i.push(w("meta.probeBanner"));let n=r.hostkey?.state;if(n==="matched"?i.push(w("meta.hostKeyMatched")):n==="recorded"?i.push(w("meta.hostKeyRecorded")):n==="mismatch"&&i.push(w("meta.hostKeyMismatch")),r.auth?.ok){let _=o!==null?w("meta.authOkMs",{ms:o}):w("meta.authOk");return w("meta.probeOk",{detail:_+(i.length?" \xB7 "+i.join(" \xB7 "):"")})}let a=r.tcp?.skipped===!0?"":r.tcp?.error,l=(r.auth?.error||a||w("error.unknown"))+(i.length?" \xB7 "+i.join(" \xB7 "):"");return t?.prefix!==void 0?t.prefix+l:w("error.probeFailed",{detail:l})}async function Uo(){try{let t=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json();if(t.ok&&typeof t.config=="object"&&t.config!==null){let r=Gt;Ps(t.config),gt!==null&&Gt!==r&&Eo(gt)}}catch{}}function wh(e){gt!==null&&(e.target instanceof Element&&(gt.contains(e.target)||e.target.closest(".tt_tabAdd")!==null)||yt())}function Us(e,t){let r=t.getBoundingClientRect(),s=e.offsetWidth,o=e.offsetHeight,n=r.left+s>window.innerWidth-8?r.right-s:r.left;e.style.left=Math.max(8,Math.min(n,window.innerWidth-s-8))+"px";let a=r.bottom+6,d=r.top-o-6;e.style.top=(a+o>window.innerHeight-8&&d>=8?d:Math.min(a,Math.max(8,window.innerHeight-o-8)))+"px"}function N_(e){if(gt!==null){yt();return}Xt(),Uo(),vh().then(()=>{gt!==null&&Eo(gt)});let t=document.createElement("div");t.className="tt_addMenu",gt=t,Eo(t),document.body.appendChild(t),Us(t,e),document.addEventListener("mousedown",wh,!0)}function yt(){gt!==null&&(document.removeEventListener("mousedown",wh,!0),gt.remove(),gt=null)}function H_(e){if(ct!==null){Xt();return}yt();let t=document.createElement("div");t.className="tt_addMenu tt_tabMenu",ct=t,Ch(),document.body.appendChild(t),Us(t,e),document.addEventListener("mousedown",yh,!0),document.addEventListener("keydown",Sh,!0)}function Xt(){ct!==null&&(document.removeEventListener("mousedown",yh,!0),document.removeEventListener("keydown",Sh,!0),ct.remove(),ct=null)}function yh(e){ct!==null&&(e.target instanceof Element&&(ct.contains(e.target)||e.target.closest(".tt_tabMore")!==null)||Xt())}function Sh(e){e.key==="Escape"&&(e.preventDefault(),e.stopPropagation(),Xt())}function Ch(){let e=ct;if(e===null)return;e.textContent="";let t=U_();if(t.length===0){let s=document.createElement("div");s.className="tt_addMenuTitle",s.textContent=w("list.tabsAllVisible"),e.appendChild(s);return}for(let[s,o]of t){let i=o.label||w("panel.tabLabel",{n:Ho(s)}),n=z_(o),a=document.createElement("div");a.className="tt_addMenuRow tt_tabMenuRow",a.dataset.sid=s;let d=document.createElement("button");d.type="button",d.className="tt_addMenuItem tt_tabMenuItem",s===ke&&(d.dataset.active="");let l=document.createElement("span");l.className="tt_tabDot",l.dataset.state=Wi(o),d.appendChild(l);let _=document.createElement("span");_.className="tt_addMenuText tt_tabMenuText";let m=document.createElement("span");if(m.className="tt_addMenuMain",m.textContent=i,_.appendChild(m),n!==""){let p=document.createElement("span");p.className="tt_tabMenuMeta",p.textContent=n,_.appendChild(p)}d.appendChild(_),d.title=n===""?i:i+" \xB7 "+n,d.addEventListener("click",()=>{Yt(s),Xt()}),a.appendChild(d);let y=document.createElement("button");y.type="button",y.className="tt_addMenuEdit",y.innerHTML=Yi,y.title=w("btn.close"),y.setAttribute("aria-label",w("btn.closeTabAria",{label:i})),y.addEventListener("click",()=>{go(s)}),a.appendChild(y),e.appendChild(a)}let r=e.querySelector(".tt_tabMenuItem[data-active]");r!==null&&typeof r.scrollIntoView=="function"&&r.scrollIntoView({block:"nearest"})}var F_=40;function W_(e,t){let r=e.getBoundingClientRect();return Math.max(0,Math.min(r.right,t.right)-Math.max(r.left,t.left))}function U_(){let e=[];if(Re===null)return e;let t=Re.getBoundingClientRect();for(let[r,s]of fe){if(s.embedded===!0)continue;let o=Re.querySelector('[data-sid="'+r+'"]');o!==null&&W_(o,t)<F_&&e.push([r,s])}return e}function z_(e){return typeof e.target=="string"?e.target:""}function j_(){return w("panel.assistTitle")===Ri["panel.assistTitle"]?"zh":"en"}function $_(e){let t=e!=null&&typeof e.exitCode=="number"?String(e.exitCode):"?";return w("badge.assistFailed",{code:t})}function kr(){if(ir===null)return;let e=ke===null?void 0:cr.get(ke),t=Oi&&e!==void 0&&e.dismissed!==!0;if(ir.hidden=!t,t){let r=ir.querySelector(".tt_assistBadgeText");r!==null&&(r.textContent=$_(e))}}function kt(){Gr!==null&&(Gr.abort(),Gr=null),vr!==null&&(vr.remove(),vr=null),Cr=null,Ii=null}function q_(e){vr!==null&&(e.target instanceof Element&&(vr.contains(e.target)||e.target.closest(".tt_assistBadge")!==null)||kt())}function K_(e){e.key==="Escape"&&(e.preventDefault(),e.stopPropagation(),kt())}function G_(e){let t=ke;if(t===null)return;kt();let r=document.createElement("div");r.className="tt_addMenu tt_assistMenu",vr=r,Cr=t,Ii=e,document.body.appendChild(r),document.addEventListener("mousedown",q_,!0),document.addEventListener("keydown",K_,!0),xo(),Us(r,e),V_(t)}async function V_(e){let t=cr.get(e);if(t===void 0||t.busy===!0||(t.error===null||t.error===void 0)&&t.answer!==null&&t.answer!==void 0)return;t.busy=!0,t.answer=null,t.command="",t.error=null,xo();let r=new AbortController;Gr=r;try{let s=await fetch("/api/dsh-tty/assist",{method:"POST",cache:"no-store",headers:{"content-type":"application/json"},body:JSON.stringify({sid:e,kind:"failure",lang:j_()}),signal:r.signal}),o=await s.json().catch(()=>null);if(Cr!==e)return;t.busy=!1,s.ok&&o!==null&&o.ok===!0?(t.answer=String(o.answer!==void 0?o.answer:""),t.command=String(o.command!==void 0?o.command:"")):t.error=o!==null&&o.error!==void 0?String(o.error):"HTTP "+String(s.status)}catch(s){if(r.signal.aborted||Cr!==e)return;t.busy=!1,t.error=s instanceof Error?s.message:String(s)}finally{Gr===r&&(Gr=null),t.busy=!1,xo()}}function xo(){let e=vr;if(e===null)return;let t=Cr,r=t===null?void 0:cr.get(t);e.textContent="";let s=document.createElement("div");s.className="tt_assistHead";let o=document.createElement("span");if(o.className="tt_assistTitle",o.textContent=w("panel.assistTitle"),s.appendChild(o),r!==void 0&&typeof r.exitCode=="number"){let m=document.createElement("span");m.className="tt_assistCode",m.textContent="exit="+String(r.exitCode),s.appendChild(m)}e.appendChild(s);let i=r!==void 0&&typeof r.error=="string"&&r.error!=="",n=document.createElement("div");if(n.className="tt_assistBody",r===void 0||r.busy===!0){n.classList.add("tt_assistMuted","tt_assistBusy");let m=document.createElement("span");m.className="tt_assistSpin",n.appendChild(m),n.appendChild(document.createTextNode(w("status.assistThinking")))}else if(i)n.textContent=w("error.assistRequest",{message:r.error}),n.classList.add("tt_assistError");else{let m=r.answer!==null&&r.answer!==void 0?r.answer:"";n.textContent=m,n.classList.add("tt_assistAnswer"),m===""&&(n.hidden=!0)}if(e.appendChild(n),r===void 0||r.busy===!0)return;let a=r.command!=="";if(a){let m=document.createElement("div");m.className="tt_assistCmdWrap";let y=document.createElement("span");y.className="tt_assistCmdLabel",y.textContent=w("panel.assistCommand"),m.appendChild(y);let p=document.createElement("div");p.className="tt_assistCmd",p.textContent=r.command,m.appendChild(p),e.appendChild(m)}let d=document.createElement("div");if(d.className="tt_assistFoot",a){let m=document.createElement("button");m.type="button",m.className="tt_toolBtn tt_assistFill",m.textContent=w("btn.assistFill"),m.title=w("hint.assistFillNoEnter"),m.addEventListener("click",Y_),d.appendChild(m)}let l=document.createElement("button");l.type="button",l.className="tt_toolBtn",l.textContent=w(i?"btn.assistCopyError":"btn.assistCopy"),l.addEventListener("click",()=>{if(i){Ro(w("error.assistRequest",{message:r.error}));return}Ro(r.answer!==null&&r.answer!==void 0?r.answer:"")}),d.appendChild(l);let _=document.createElement("button");if(_.type="button",_.className="tt_toolBtn tt_assistClose",_.textContent=w("btn.assistClose"),_.addEventListener("click",()=>{kt()}),d.appendChild(_),e.appendChild(d),!i){let m=document.createElement("span");m.className="tt_assistNote",m.textContent=w(a?"hint.assistFillNoEnter":"hint.assistNoCommand"),e.appendChild(m)}Ii!==null&&Us(e,Ii)}function Y_(){let e=Cr,t=e===null?void 0:cr.get(e);if(e===null||t===void 0||t.command==="")return;Pe({t:"input",sid:e,d:""+t.command});let r=fe.get(e);kt(),X_(e),r!==void 0&&r.term!==null&&r.term.focus()}function X_(e){let t=cr.get(e);t!==void 0&&(t.dismissed=!0),kr()}function ko(e,t,r,s,o,i){let n=document.createElement("button");if(n.type="button",n.className="tt_addMenuItem",o===!0&&(n.setAttribute("data-soldout",""),n.title=w("btn.maxSessionsTitle")),i!==void 0){let l=document.createElement("span");l.className="tt_addMenuIcon",l.innerHTML=i,n.appendChild(l)}let a=document.createElement("span");a.className="tt_addMenuText";let d=document.createElement("span");if(d.className="tt_addMenuMain",d.textContent=t,a.appendChild(d),r!==""){let l=document.createElement("span");l.className="tt_addMenuSub",l.textContent=r,a.appendChild(l)}n.appendChild(a),n.addEventListener("click",s),e.appendChild(n)}function Eo(e){e.textContent="";let t=I_();ko(e,w("option.localTerminal"),w(ar==="tmux"?"hint.tmuxHosted":"hint.openInSessionCwd"),async()=>{await ji()||(yt(),Ds())},t,Gi);let r=document.createElement("div");r.className="tt_addMenuSep",e.appendChild(r);let s=document.createElement("div");s.className="tt_addMenuTitle",s.textContent=w("panel.sshBook"),e.appendChild(s);for(let i of Gt){if(i===null||typeof i!="object"||typeof i.name!="string"||i.name==="")continue;let n=document.createElement("div");n.className="tt_addMenuRow";let a=document.createElement("button");a.type="button",a.className="tt_addMenuItem",t&&(a.setAttribute("data-soldout",""),a.title=w("btn.maxSessionsTitle"));let d=document.createElement("span");d.className="tt_addMenuIcon",d.innerHTML=Zp;let l=document.createElement("span");l.className="tt_addMenuText";let _=document.createElement("span");_.className="tt_addMenuMain",_.textContent=i.name;let m=document.createElement("span");m.className="tt_addMenuSub";let y=bh(i.name),p=to(i.jump);m.textContent=yo(i)+(p===""?"":" "+w("meta.viaJump",{label:p}))+(typeof i.proxyCommand=="string"&&i.proxyCommand.trim()!==""?" "+w("meta.viaProxy"):"")+(y>0?" \xB7 \u21C4"+String(y):""),l.appendChild(_),l.appendChild(m),a.appendChild(d),a.appendChild(l),a.addEventListener("click",async()=>{if(await ji())return;yt();let h=ar==="tmux"&&i.persist!==!1?{persist:!0,persistName:Wo()}:{};Ds({t:"ssh",name:i.name,...h},i.name)});let c=document.createElement("button");c.type="button",c.className="tt_addMenuEdit",c.title=w("btn.sftpFileBrowse"),c.innerHTML=Rs,c.addEventListener("click",()=>{yt(),Qi({name:i.name})});let u=document.createElement("button");u.type="button",u.className="tt_addMenuEdit",u.title=w("btn.editConnection"),u.innerHTML=Do,u.addEventListener("click",()=>{yt(),Pc(i)}),n.appendChild(a),n.appendChild(c),n.appendChild(u),e.appendChild(n)}if(Gt.length===0){let i=document.createElement("div");i.className="tt_addMenuTitle",i.textContent=w("list.emptySshBook"),e.appendChild(i)}let o=document.createElement("div");o.className="tt_addMenuSep",e.appendChild(o),ko(e,w("option.sshConnect"),w("hint.sshConnect"),()=>{yt(),Pc()},!1,Zc)}function Pc(e){if(Vr!==null)return;let t=e!==null&&typeof e=="object"?e:null,r=t!==null,s=document.createElement("div");s.className="tt_sshBackdrop";let o=document.createElement("div");o.className="tt_sshCard";let i=document.createElement("div");i.className="tt_sshTitle",i.innerHTML=Zc+"<span></span>",i.lastElementChild.textContent=r?w("panel.editConnection",{name:String(t.name??"")}):w("panel.sshConnect"),o.appendChild(i);let n=Q=>{let se=document.createElement("div");return se.className="tt_sshSection",se.textContent=Q,se},a={},d=(Q,se,oe)=>{let re=document.createElement("label");re.className="tt_sshRow";let ne=document.createElement("span");ne.className="tt_cardLabel",ne.textContent=se,re.appendChild(ne);let ce;if(oe?.select!==void 0){ce=document.createElement("select");for(let le of oe.select){let ge=document.createElement("option");ge.value=le.value,ge.textContent=le.label,ce.appendChild(ge)}}else ce=document.createElement("input"),ce.type=oe?.type??"text",ce.placeholder=oe?.placeholder??"";return ce.className="tt_cardInput",ce.autocomplete="off",ce.spellcheck=!1,re.appendChild(ce),a[Q]=ce,re};o.appendChild(n(w("section.connection")));let l=document.createElement("div");l.className="tt_sshGrid",l.appendChild(d("host",w("field.host"),{placeholder:w("placeholder.host")})),l.appendChild(d("port",w("field.port"),{placeholder:"22"})),o.appendChild(l),o.appendChild(d("username",w("field.username"),{placeholder:"root"})),o.appendChild(n(w("section.auth"))),o.appendChild(d("auth",w("field.authMethod"),{select:[{value:"agent",label:w("option.authAgent")},{value:"key",label:w("option.authKey")},{value:"password",label:w("option.authPassword")}]}));let _=d("keyPath",w("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),m=d("passphrase",w("field.passphrase"),{type:"password"}),y=d("password",w("field.password"),{type:"password"}),p=(Q,se)=>{let oe=document.createElement("div");oe.className="tt_sshRow tt_envRow";let re=document.createElement("input");re.type="text",re.className="tt_cardInput",re.placeholder=w("placeholder.credRef"),re.title=w("hint.credRefCandidates"),re.autocomplete="off",re.spellcheck=!1;let ne=document.createElement("span");ne.className="tt_cardHint tt_envEmpty",ne.textContent=se,ne.hidden=!0,re.hidden=!0;let ce=document.createElement("div");ce.className="tt_envList",ce.dataset.hidden="";let le=[],ge=()=>{if(ce.textContent="",le.length===0){let ye=document.createElement("span");ye.className="tt_cardHint",ye.textContent=se,ce.appendChild(ye);return}let we=re.value.trim().toUpperCase(),Le=we===""?le:le.filter(ye=>ye.toUpperCase().includes(we));for(let ye of Le.slice(0,30)){let be=document.createElement("button");be.type="button",be.className="tt_envItem",be.textContent=ye;let xe="env:"+ye,Fe=null,tt=()=>{Fe!==null&&(clearTimeout(Fe),Fe=null),be.textContent=ye,delete be.dataset.danger};be.addEventListener("mousedown",Er=>Er.preventDefault()),be.addEventListener("click",()=>{let Er=Q.value;if(Er===""||Er.startsWith("env:")||Fe!==null){tt(),Q.value=xe,Q.focus(),Q.dispatchEvent(new Event("change"));return}be.textContent=w("list.credOverwrite",{name:ye}),be.dataset.danger="",Fe=setTimeout(tt,4e3)}),ce.appendChild(be)}if(Le.length>30){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=w("list.moreMatches",{count:Le.length-30}),ce.appendChild(ye)}else if(Le.length===0){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=w("list.noCredRef"),ce.appendChild(ye)}};return re.addEventListener("input",ge),re.addEventListener("focus",()=>{le.length>0&&delete ce.dataset.hidden}),re.addEventListener("blur",()=>{re.value.trim()===""&&(ce.dataset.hidden="")}),oe.appendChild(re),oe.appendChild(ne),oe.appendChild(ce),{row:oe,setNames(we){le=Array.isArray(we)?we:[];let Le=le.length>0;re.hidden=!Le,ne.hidden=Le,ge()}}},c=(Q,se)=>{let oe=document.createElement("div");oe.className="tt_sshRow tt_credRow";let re=document.createElement("label");re.className="tt_credToggle";let ne=document.createElement("input");ne.type="checkbox",ne.className="tt_cardCheckbox";let ce=document.createElement("span");ce.textContent=w("check.rememberCredential"),re.appendChild(ne),re.appendChild(ce),ne.checked=Ot!==null,re.title=w("hint.rememberCredential");let le=document.createElement("button");le.type="button",le.className="tt_toolBtn tt_credClear",le.textContent=w("btn.clearCredential"),le.dataset.hidden="";let ge=document.createElement("span");ge.className="tt_credStatus",oe.appendChild(re),oe.appendChild(le),oe.appendChild(ge);let we=(be,xe)=>{ge.textContent=be,ge.dataset.kind=xe},Le=async()=>{let be=$r(Q.value),xe=be!=="";if(re.hidden=xe,le.hidden=!xe,ge.hidden=!1,Zr()===null){ne.disabled=!0,ne.checked=!1,le.disabled=!0,we(w(Ot===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),"muted");return}if(ne.disabled=!1,!xe){ge.hidden=!0,we("","plain");return}let Fe=await Wc(be);if(Fe.unreported===!0){we(w("status.credUnreported",{ref:be}),"plain");return}if(Fe.error!==void 0){we(w("error.credStatusFailed",{error:Fe.error}),"error");return}let tt=Fe.view;we(tt.configured?w("status.credStored",{ref:be,source:tt.source!==""?w("meta.credSource",{source:tt.source}):""}):w("status.credUnknown",{ref:be}),tt.configured?"ok":"plain"),le.disabled=tt.configured!==!0||tt.writable!==!0};le.addEventListener("click",()=>{(async()=>{let be=$r(Q.value);if(be==="")return;let xe=await Uc(be);if(xe.error!==void 0){we(xe.error,"error");return}Q.value="",await Le()})()});let ye=async()=>{let be=await zc(ne.checked===!0,Q.value,a.host.value,a.port.value,a.username.value,se);return be.value!==void 0&&(Q.value=be.value,await Le()),be};return Q.addEventListener("change",()=>{Le()}),{row:oe,refresh:Le,storeIfRequested:ye}},u=p(a.passphrase,w("hint.noCredRefPassphrase")),h=p(a.password,w("hint.noCredRefPassword")),f=c(a.password,"PASSWORD");(async()=>{let Q=await Fc();u.setNames(Q),h.setNames(Q)})(),o.appendChild(_),o.appendChild(m),o.appendChild(u.row),o.appendChild(y),o.appendChild(f.row),o.appendChild(h.row),o.appendChild(n(w("section.jump")));let v=d("jumpHost",w("field.jumpHost"),{placeholder:w("placeholder.jumpHost")});o.appendChild(v);let S=document.createElement("label");S.className="tt_sshRow";let g=document.createElement("input");g.type="checkbox",g.className="tt_cardCheckbox";let x=document.createElement("span");x.className="tt_cardLabel",x.textContent=w("check.jumpOwnCred"),S.appendChild(g),S.appendChild(x),o.appendChild(S);let b=d("jumpUsername",w("field.jumpUsername"),{placeholder:"root"}),E=d("jumpAuth",w("field.jumpAuth"),{select:[{value:"",label:w("option.authInherit")},{value:"agent",label:w("option.authAgent")},{value:"key",label:w("option.authKey")},{value:"password",label:w("option.authPassword")}]}),P=d("jumpKeyPath",w("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),O=d("jumpPassphrase",w("field.passphrase"),{type:"password"}),F=d("jumpPassword",w("field.password"),{type:"password"});for(let Q of[b,E,P,O,F])o.appendChild(Q);let A=document.createElement("div");A.className="tt_cardHint",A.textContent=w("hint.jumpInherit"),o.appendChild(A),o.appendChild(n(w("section.proxyCommand")));let V=d("proxyCommand",w("field.proxyCommand"),{placeholder:w("placeholder.proxyCommand")});o.appendChild(V);let B=document.createElement("div");B.className="tt_cardHint",B.textContent=w("hint.proxyCommand"),o.appendChild(B);let M=document.createElement("div");M.className="tt_cardHint tt_sshProbeWarn",M.textContent=w("hint.proxyCommandDisabled"),o.appendChild(M);let U=()=>{let Q=a.proxyCommand.value.trim()!=="",se=mh,oe=se&&_h;M.textContent=w(se?"hint.proxyCommandDisabled":"hint.proxyCommandNotGranted"),M.style.display=Q&&!oe?"":"none"};a.proxyCommand.addEventListener("input",U),U();let I=()=>{let Q=eo(a.jumpHost.value);if(Q===void 0)return;if(g.checked!==!0)return Q;let se={...Q},oe=a.jumpUsername.value.trim();oe!==""&&(se.username=oe);let re=a.jumpAuth.value;(re==="agent"||re==="key"||re==="password")&&(se.auth=re);let ne=a.jumpKeyPath.value.trim();return ne!==""&&(se.keyPath=ne),a.jumpPassphrase.value!==""&&(se.passphrase=a.jumpPassphrase.value),a.jumpPassword.value!==""&&(se.password=a.jumpPassword.value),se},C=()=>{let Q=a.proxyCommand.value.trim();return Q===""?void 0:Q},L=()=>{let Q=eo(a.jumpHost.value)!==void 0,se=Q&&g.checked===!0;S.style.display=Q?"":"none";for(let oe of[b,E,P,O,F])oe.style.display=se?"":"none";P.style.display=se&&a.jumpAuth.value==="key"?"":"none",O.style.display=se&&a.jumpAuth.value==="key"?"":"none",F.style.display=se&&a.jumpAuth.value==="password"?"":"none",A.style.display=Q?"":"none"};a.jumpHost.addEventListener("input",L),a.jumpAuth.addEventListener("change",L),g.addEventListener("change",L),o.appendChild(n(w("section.options")));let T=document.createElement("label");T.className="tt_cardRow";let D=document.createElement("input");D.type="checkbox",D.className="tt_cardCheckbox";let N=document.createElement("span");N.className="tt_cardLabel",N.textContent=w("check.agentForward"),T.appendChild(D),T.appendChild(N),o.appendChild(T),o.appendChild(d("hostKeyAlias",w("field.hostKeyAlias"),{placeholder:w("placeholder.hostKeyAlias")}));let G=document.createElement("span");G.className="tt_cardHint",G.textContent=w("hint.hostKeyAlias"),o.appendChild(G);let $=document.createElement("label");$.className="tt_cardRow";let Y=document.createElement("input");Y.type="checkbox",Y.className="tt_cardCheckbox";let H=document.createElement("span");H.className="tt_cardLabel",H.textContent=w("check.persist"),$.appendChild(Y),$.appendChild(H),Y.checked=ar==="tmux",ar==="tmux"&&o.appendChild($);let k=document.createElement("label");k.className="tt_cardRow";let W=document.createElement("input");W.type="checkbox",W.className="tt_cardCheckbox";let q=document.createElement("span");q.className="tt_cardLabel",q.textContent=w("check.saveToBook"),k.appendChild(W),k.appendChild(q),o.appendChild(k);let j=d("name",w("field.bookName"),{placeholder:w("placeholder.bookName")});if(j.style.display="none",o.appendChild(j),W.addEventListener("change",()=>{j.style.display=W.checked?"":"none",W.checked&&a.name.value.trim()===""&&a.host.value.trim()!==""&&(a.name.value=a.host.value.trim()),W.checked&&a.name.focus()}),r){k.style.display="none",a.name.value=String(t.name??""),j.style.display="",a.host.value=String(t.host??""),a.port.value=String(t.port??22),a.username.value=String(t.username??""),a.auth.value=t.auth==="key"||t.auth==="password"?String(t.auth):"agent",a.keyPath.value=String(t.keyPath??""),a.passphrase.value=String(t.passphrase??""),a.password.value=String(t.password??"");let Q=t.jump!==null&&typeof t.jump=="object"?t.jump:null;if(a.jumpHost.value=to(Q),Q!==null){let se=Q.auth!==void 0||Q.keyPath!==void 0||Q.password!==void 0||Q.passphrase!==void 0;g.checked=se,se&&(a.jumpUsername.value=String(Q.username??""),a.jumpAuth.value=Q.auth==="key"||Q.auth==="password"?String(Q.auth):"",a.jumpKeyPath.value=String(Q.keyPath??""),a.jumpPassphrase.value=String(Q.passphrase??""),a.jumpPassword.value=String(Q.password??""))}D.checked=t.agentForward===!0,a.hostKeyAlias.value=String(t.hostKeyAlias??""),a.proxyCommand.value=String(t.proxyCommand??""),U(),Y.checked=ar==="tmux"}let X=document.createElement("div");X.className="tt_sshStatus";let J=document.createElement("div");J.className="tt_sshError";let ae=document.createElement("div");ae.className="tt_sshProbeResult",X.appendChild(J),X.appendChild(ae),o.appendChild(X),L();let he=()=>a.hostKeyAlias.value.trim(),_e=()=>{J.textContent="";let Q=a.host.value.trim(),se=a.username.value.trim(),oe=Number(a.port.value);if((!Number.isInteger(oe)||oe<1||oe>65535)&&(oe=22),Q===""||se==="")return J.textContent=w("error.hostUserRequired"),null;let re=a.auth.value,ne={host:Q,port:oe,username:se,auth:re},ce=I();ce!==void 0&&(ne.jump=ce);let le=C();if(le!==void 0&&(ne.proxyCommand=le),re==="key"){let we=a.keyPath.value.trim();if(we==="")return J.textContent=w("error.keyPathRequired"),null;ne.keyPath=we;let Le=a.passphrase.value;Le!==""&&(ne.passphrase=Le)}if(re==="password"){let we=a.password.value;if(we==="")return J.textContent=w("error.passwordRequired"),null;ne.password=we}D.checked&&(ne.agentForward=!0);let ge=he();return ge!==""&&(ne.hostKeyAlias=ge),ne},Z=document.createElement("div");Z.className="tt_sshActions";let Ce=document.createElement("div");Ce.className="tt_sshActionsGroup";let He=document.createElement("div");He.className="tt_sshActionsGroup",Z.appendChild(Ce),Z.appendChild(He);let Ee=document.createElement("button");Ee.type="button",Ee.className="tt_toolBtn",Ee.textContent=w("btn.cancel");let Oe=document.createElement("button");Oe.type="button",Oe.className="tt_cardSave",Oe.textContent=w("btn.connect"),Ce.appendChild(Ee);let Ue=document.createElement("button");Ue.type="button",Ue.className="tt_toolBtn",Ue.textContent=w("btn.fileBrowse"),Ue.title=w("btn.browseTitle"),Ue.addEventListener("click",()=>{J.textContent="";let Q=a.host.value.trim(),se=a.username.value.trim(),oe=Number(a.port.value);if((!Number.isInteger(oe)||oe<1||oe>65535)&&(oe=22),Q===""||se===""){J.textContent=w("error.hostUserRequired");return}let re=a.auth.value,ne={host:Q,port:oe,username:se,auth:re},ce=I();ce!==void 0&&(ne.jump=ce);let le=C();if(le!==void 0&&(ne.proxyCommand=le),re==="key"){let we=a.keyPath.value.trim();if(we===""){J.textContent=w("error.keyPathRequired");return}ne.keyPath=we;let Le=a.passphrase.value;Le!==""&&(ne.passphrase=Le)}if(re==="password"){let we=a.password.value;if(we===""){J.textContent=w("error.passwordRequired");return}ne.password=we}D.checked&&(ne.agentForward=!0);let ge=he();ge!==""&&(ne.hostKeyAlias=ge),nr(),Qi(ne)}),Ce.appendChild(Ue);let te=null;r&&(te=document.createElement("button"),te.type="button",te.className="tt_toolBtn",te.textContent=w("btn.saveEdit"),te.addEventListener("click",()=>{J.textContent="";let Q=a.host.value.trim(),se=a.username.value.trim();if(Q===""||se===""){J.textContent=w("error.hostUserRequired");return}let oe=Number(a.port.value);(!Number.isInteger(oe)||oe<1||oe>65535)&&(oe=22);let re=a.auth.value,ce={name:a.name.value.trim()||Q,host:Q,port:oe,username:se,auth:re,keyPath:re==="key"?a.keyPath.value.trim():"",passphrase:a.passphrase.value,password:a.password.value,agentForward:D.checked,hostKeyAlias:he(),persist:Y.checked},le=I();if(le!==void 0&&(ce.jump=le),ce.proxyCommand=a.proxyCommand.value.trim(),re==="key"&&ce.keyPath===""){J.textContent=w("error.keyPathRequired");return}te!==null&&(te.disabled=!0),(async()=>{let ge=await f.storeIfRequested();if(ge.error!==void 0){J.textContent=ge.error,te!==null&&(te.disabled=!1);return}ge.value!==void 0&&(ce.password=ge.value);let we=await Z_(String(t.name??""),ce);if(te!==null&&(te.disabled=!1),we!==void 0){J.textContent=w("error.saveCredFailed",{error:we});return}nr()})()}),Ce.appendChild(te));let de=document.createElement("button");de.type="button",de.className="tt_toolBtn",de.textContent=w("btn.probe"),de.title=w("btn.probeTitle"),de.addEventListener("click",()=>{let Q=_e();Q!==null&&(ae.className="tt_sshProbeResult",ae.textContent=w("msg.probing"),de.disabled=!0,So(Q,!1).then(se=>{de.disabled=!1,se.result?(ae.className="tt_sshProbeResult"+(se.result.auth?.ok===!0?" tt_sshProbeOk":" tt_sshProbeBad"),ae.textContent=Co(se.result)):(ae.className="tt_sshProbeResult tt_sshProbeBad",ae.textContent=w("error.probeFailed",{detail:String(se.error||w("error.unknown"))}))}))}),Ce.appendChild(de),He.appendChild(Oe),o.appendChild(Z);let ve=()=>{_.style.display=a.auth.value==="key"?"":"none",m.style.display=a.auth.value==="key"?"":"none",u.row.style.display=a.auth.value==="key"?"":"none",y.style.display=a.auth.value==="password"?"":"none",h.row.style.display=a.auth.value==="password"?"":"none",f.row.style.display=a.auth.value==="password"?"":"none"};a.auth.addEventListener("change",ve),ve(),f.refresh(),Ee.addEventListener("click",()=>nr()),s.addEventListener("mousedown",Q=>{Q.target===s&&nr()}),Oe.addEventListener("click",async()=>{J.textContent="";let Q=await ji();if(Q!==null){J.textContent=Q;return}let se=a.host.value.trim(),oe=a.username.value.trim(),re=Number(a.port.value);if((!Number.isInteger(re)||re<1||re>65535)&&(re=22),se===""||oe===""){J.textContent=w("error.hostUserRequired");return}let ne=a.auth.value,ce={t:"ssh",host:se,port:re,username:oe,auth:ne},le=I();le!==void 0&&(ce.jump=le);let ge=C();if(ge!==void 0&&(ce.proxyCommand=ge),ne==="key"){let xe=a.keyPath.value.trim();xe!==""&&(ce.keyPath=xe);let Fe=a.passphrase.value;Fe!==""&&(ce.passphrase=Fe)}if(ne==="password"){let xe=a.password.value;xe!==""&&(ce.password=xe)}D.checked&&(ce.agentForward=!0);let we=he();we!==""&&(ce.hostKeyAlias=we),Y.checked&&(ce.persist=!0,ce.persistName=Wo());let Le=re!==22?oe+"@"+se+":"+re:oe+"@"+se,ye=xe=>{nr(),ue!==null&&Ds(ce,xe!==""?xe:Le)};if(!W.checked){ye("");return}let be=a.name.value.trim()||se;Oe.disabled=!0,(async()=>{let xe=await f.storeIfRequested();if(xe.error!==void 0){J.textContent=xe.error,Oe.disabled=!1;return}let Fe=xe.value??ce.password??"",tt=await J_({name:be,host:se,port:re,username:oe,auth:ne,keyPath:ce.keyPath??"",passphrase:ce.passphrase??"",password:Fe,agentForward:D.checked,hostKeyAlias:he(),persist:Y.checked,...le!==void 0?{jump:le}:{},proxyCommand:a.proxyCommand.value.trim()});if(Oe.disabled=!1,tt!==void 0){J.textContent=w("error.saveBookFailed",{error:tt});return}ye(be)})()}),s.appendChild(o),document.body.appendChild(s),Vr=s,a.host.focus()}function nr(){Vr!==null&&(Vr.remove(),Vr=null)}async function J_(e){let t=[...Gt.filter(r=>r?.name!==e.name),e];try{let r=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({sshHosts:t})}),s=await r.json().catch(()=>({}));if(!r.ok||!s.ok)return String(s.error||"HTTP "+r.status);Ps(s.config);return}catch(r){return String(r&&r.message?r.message:r)}}async function Z_(e,t){if(t.name!==e&&Gt.some(s=>s?.name===t.name))return w("error.bookNameTaken",{name:t.name});let r=Gt.map(s=>s?.name===e?t:s);try{let s=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({sshHosts:r})}),o=await s.json().catch(()=>({}));if(!s.ok||!o.ok)return String(o.error||"HTTP "+s.status);Ps(o.config);return}catch(s){return String(s&&s.message?s.message:s)}}function Q_(e,t,r){let s=Wr(r,ke);if(kh(s))return;let o=document.createElement("div");o.className="tt_sftpDualCard";let i=document.createElement("div");i.className="tt_sftpTitleRow";let n=document.createElement("div");n.className="tt_sshTitle",n.innerHTML=Rs+"<span></span>",n.lastElementChild.textContent=w("panel.sftpDual",{label:t});let a=document.createElement("button");a.type="button",a.className="tt_close",a.title=w("btn.close"),a.innerHTML=Vi,a.addEventListener("click",()=>ts(s)),i.appendChild(n),i.appendChild(a),o.appendChild(i);let d=document.createElement("div");d.className="tt_sftpStatus";let l=(N,G)=>{d.textContent=N,G===void 0?delete d.dataset.state:d.dataset.state=G},_=!1,m=(N,G)=>{if(!(_||p.local.busy||p.remote.busy)){_=!0;for(let $ of[p.local,p.remote])$.setBusy(!0);l(N,"busy"),Promise.resolve().then(G).catch($=>{($===null||typeof $!="object"||$.name!=="TransferCanceledError")&&M.fail(w("status.failed")),l(String($&&$.message?$.message:$),"error")}).finally(()=>{_=!1;for(let $ of[p.local,p.remote])$.setBusy(!1)})}},y=N=>{p[N].bar.after(h),h.style.display="",f.focus(),f.select()},p={},c=(N,G)=>{if(N===void 0||N==="")throw new Error(w("error.dirNotReady"));return N.endsWith("/")||N.endsWith("\\")?N+G:N+"/"+G},u=(N,G)=>{let $={kind:N,path:"",busy:!1},Y=document.createElement("div");Y.className="tt_sftpPane";let H=document.createElement("div");H.className="tt_sftpPaneHead";let k=document.createElement("span");k.textContent=G;let W=document.createElement("span");W.className="tt_sftpPaneMeta",H.appendChild(k),H.appendChild(W),Y.appendChild(H);let q=document.createElement("div");q.className="tt_sftpBar";let j=document.createElement("input");j.type="text",j.className="tt_sftpPath",j.placeholder=w(N==="local"?"placeholder.localPath":"placeholder.remotePath"),j.spellcheck=!1,j.autocomplete="off";let X=document.createElement("button");X.type="button",X.className="tt_toolBtn",X.innerHTML=Po+"<span>"+w("btn.refresh")+"</span>";let J=document.createElement("button");J.type="button",J.className="tt_toolBtn",J.innerHTML=Vc+"<span>"+w("btn.mkdir")+"</span>";let ae=document.createElement("button");ae.type="button",ae.className="tt_toolBtn tt_toolToggle",ae.textContent=w("btn.hiddenFiles"),ae.title=w("btn.hiddenFilesTitle"),_r&&(ae.dataset.on=""),q.appendChild(j),q.appendChild(X),q.appendChild(J),q.appendChild(ae),Y.appendChild(q);let he=document.createElement("div");he.className="tt_sftpList",Y.appendChild(he),$.bar=q;let _e=te=>{$.busy=te;for(let de of[X,J])de.disabled=te;j.disabled=te},Z=async(te,de)=>{let ve=N==="local"?"/api/dsh-tty/local-fs/":"/api/dsh-tty/sftp/",Q=N==="local"?de:{...e,...de},se=await fetch(ve+te,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q)}),oe=await se.json().catch(()=>({}));if(!se.ok||oe.ok!==!0)throw new Error(String(oe.error||"HTTP "+se.status));return oe},Ce=(te,de)=>{if(!($.busy||_))return _e(!0),l(te,"busy"),Promise.resolve().then(de).catch(ve=>l(String(ve&&ve.message?ve.message:ve),"error")).finally(()=>_e(!1))},He=(te,de)=>{if(te===void 0||te==="")throw new Error(w("error.dirNotReady"));return te.endsWith("/")||te.endsWith("\\")?te+de:te+"/"+de},Ee=te=>{let de=He($.path,te.name),ve=[];te.isDir===!0?ve.push(w("meta.dir")):ve.push(Ze(Number(te.size))||"\u2014");let Q=Th(Number(te.mtime));Q!==""&&ve.push(Q);let se=b(te.isDir?Rs:te.isSymlink?Kc:qc,te.name,ve.join(" \xB7 "),te.isDir===!0?"dir":te.isSymlink===!0?"link":"file"),oe=()=>$.loadDir($.path),re=N==="local"?p.remote:p.local;return te.isDir===!0&&se.addEventListener("click",ne=>{ne.target instanceof Element&&ne.target.closest(".tt_sftpAct")!==null||$.loadDir(de)}),E(se,N==="local"?Yc:Xc,w("btn.transferTo",{target:w(N==="local"?"meta.remote":"meta.local"),path:re.path}),()=>{if($.path===""||re.path===""){l(w("error.transferDirsNotReady"),"error");return}M.reset(),M.pulse(0),m(w("msg.transferring",{name:te.name}),async()=>{let ne=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"start",direction:N==="local"?"up":"down",...e,localPath:N==="local"?de:He(re.path,te.name),remotePath:N==="local"?He(re.path,te.name):de})}),ce=await ne.json().catch(()=>({}));if(!ne.ok||ce.ok!==!0)throw M.fail(w("error.transferFailed")),new Error(String(ce.error||"HTTP "+ne.status));let le=ce.job?.id;if(typeof le!="string"||le==="")throw M.fail(w("error.transferFailed")),new Error(w("error.noTaskId"));await U(le,te.name)==="canceled"?(M.reset(),l(w("msg.transferCanceled",{name:te.name}))):(M.done(w("status.done")),setTimeout(()=>M.reset(),1500),l(w("msg.transferred",{name:te.name}))),await re.loadDir(re.path)})}),N!=="local"&&te.isDir!==!0&&E(se,Gc,w("btn.download",{name:te.name}),()=>{O(te,de)}),E(se,Do,w("btn.rename",{name:te.name}),()=>{f.placeholder=w("placeholder.newName"),f.value=te.name,y(N),g=async()=>{let ne=f.value.trim();ne===""||ne===te.name||(x(),await $.runTask(w("msg.renaming",{name:te.name}),async()=>{await Z("rename",{from:de,to:He($.path,ne)}),await oe()}))}}),P(se,()=>$.runTask(w("msg.deleting",{name:te.name}),async()=>{await Z("remove",{path:de,recursive:te.isDir===!0}),await oe(),l(w("msg.deleted",{name:te.name}))}),te),se},Oe=te=>{if(he.textContent="",$.path!==""&&$.path!=="/"&&/^[A-Za-z]:[\\/]?$/.test($.path)===!1){let Q=b(Ao,w("list.parentDir"),"","up");Q.addEventListener("click",()=>{let se=N==="local"?rm($.path):Rh($.path);se!==null&&$.loadDir(se)}),he.appendChild(Q)}let de=bi(te,_r);if(de.length===0){let Q=document.createElement("div");Q.className="tt_addMenuTitle",Q.textContent=te.length>0?w("list.hiddenOnly"):w("list.emptyDir"),he.appendChild(Q);return}let ve=500;for(let Q of de.slice(0,ve))Q===null||typeof Q!="object"||typeof Q.name!="string"||Q.name===""||he.appendChild(Ee(Q));if(de.length>ve){let Q=document.createElement("div");Q.className="tt_addMenuTitle",Q.textContent=w("list.truncated",{rest:de.length-ve,total:de.length}),he.appendChild(Q)}};$.loadDir=async te=>{try{let de=await Z("list",{path:te??$.path});$.path=typeof de.path=="string"&&de.path!==""?de.path:$.path,j.value=$.path;let ve=Array.isArray(de.entries)?de.entries:[];$.rawEntries=ve,Oe(ve),W.textContent=w("list.itemCount",{count:bi(ve,_r).length}),l($.path)}catch(de){l(String(de&&de.message?de.message:de),"error")}},$.runTask=Ce,$.setBusy=_e,p[N]=$,ae.addEventListener("click",()=>{P_(!_r)});let Ue=te=>{ae!==null&&(te?ae.dataset.on="":delete ae.dataset.on),$.rawEntries=$.rawEntries??[],Oe($.rawEntries),W.textContent=w("list.itemCount",{count:bi($.rawEntries,te).length})};return bo.add(Ue),$.onShowHidden=Ue,X.addEventListener("click",()=>{$.runTask(w("list.loading"),()=>$.loadDir($.path))}),J.addEventListener("click",()=>{$.busy||_||(f.placeholder=w("placeholder.newDirName"),f.value="",y(N),g=async()=>{let te=f.value.trim();te!==""&&(x(),await $.runTask(w("msg.creatingDir",{name:te}),async()=>{await Z("mkdir",{path:He($.path,te),parents:!0}),await $.loadDir($.path)}))})}),j.addEventListener("keydown",te=>{if(te.key!=="Enter"||(te.preventDefault(),$.busy||_))return;let de=j.value.trim();de!==""&&$.runTask(w("list.loading"),()=>$.loadDir(de))}),Y},h=document.createElement("div");h.className="tt_sftpEditor",h.style.display="none";let f=document.createElement("input");f.type="text",f.className="tt_cardInput",f.spellcheck=!1,f.autocomplete="off";let v=document.createElement("button");v.type="button",v.className="tt_toolBtn",v.textContent=w("btn.ok");let S=document.createElement("button");S.type="button",S.className="tt_toolBtn",S.textContent=w("btn.cancel"),h.appendChild(f),h.appendChild(v),h.appendChild(S);let g=null,x=()=>{h.style.display="none",f.value="",g=null};v.addEventListener("click",()=>{g?.()}),S.addEventListener("click",x),f.addEventListener("keydown",N=>{N.key==="Enter"?(N.preventDefault(),g?.()):N.key==="Escape"&&(N.stopPropagation(),x())});let b=(N,G,$,Y)=>{let H=document.createElement("button");H.type="button",H.className="tt_sftpRow";let k=document.createElement("span");k.className="tt_sftpIcon",k.innerHTML=N,Y!==void 0&&(k.dataset.kind=Y);let W=document.createElement("span");if(W.className="tt_sftpName",W.textContent=G,W.title=G,H.appendChild(k),H.appendChild(W),$!==""){let q=document.createElement("span");q.className="tt_sftpMeta",q.textContent=$,H.appendChild(q)}return H},E=(N,G,$,Y)=>{let H=document.createElement("button");H.type="button",H.className="tt_sftpAct",H.innerHTML=G,H.title=$,H.addEventListener("click",k=>{k.stopPropagation(),Y()}),N.appendChild(H)},P=(N,G,$)=>{let Y=document.createElement("button");Y.type="button",Y.className="tt_sftpAct",Y.innerHTML=qr,Y.title=$.isDir?w("btn.deleteEntryDir",{name:$.name}):w("btn.deleteEntry",{name:$.name});let H=null;Y.addEventListener("click",k=>{if(k.stopPropagation(),H!==null){clearTimeout(H),H=null,Y.innerHTML=qr,delete Y.dataset.danger,G();return}Y.textContent=w("btn.confirm"),Y.dataset.danger="",H=setTimeout(()=>{H=null,Y.innerHTML=qr,delete Y.dataset.danger},4e3)}),N.appendChild(Y)},O=(N,G)=>p.remote.runTask(w("msg.downloading",{name:N.name}),async()=>{M.reset();let $;try{$=await Ah({makeBody:Y=>({...e,path:G,...Y>0?{offset:Y}:{}}),onProgress:(Y,H)=>M.set(Y,H),maxMb:Kt.maxDownloadMb,registerCancel:Y=>M.setCancel(Y),onResume:Y=>l(w("msg.downloadResuming",{name:N.name,offset:Ze(Y)||String(Y)+" B"}),"busy")})}catch(Y){if(Jr(Y)){M.reset(),l(w("msg.downloadCanceled",{name:N.name}));return}throw M.fail(w("error.downloadFailed")),Y}M.done(w("status.done")),Dh($,N.name),setTimeout(()=>M.reset(),1500),l(w("msg.downloaded",{name:N.name,size:Ze($.size)||String($.size)+" B"}))}),F=u("local",w("meta.local")),A=u("remote",w("meta.remote"));p.local.wrap=F,p.remote.wrap=A;let V=document.createElement("div");V.className="tt_sftpDual",V.appendChild(F),V.appendChild(A),o.appendChild(V),o.appendChild(h);let B=document.createElement("div");B.className="tt_sftpFoot";let M=Mh();B.appendChild(M.el),B.appendChild(d),o.appendChild(B);let U=async(N,G)=>{let $=!1;M.setCancel(()=>{$||($=!0,fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"cancel",job:N})}).catch(()=>{}))});try{for(;;){await new Promise(W=>setTimeout(W,400));let Y=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"status",job:N})}),H=await Y.json().catch(()=>({}));if(!Y.ok||H.ok!==!0){if($)return"canceled";throw new Error(String(H.error||"HTTP "+Y.status))}let k=H.job;if(k===null||typeof k!="object")throw new Error(w("error.invalidTaskState"));if(k.state==="running"){let W=typeof k.current=="string"&&k.current!==""?k.current:G;l(w("msg.transferring",{name:W}),"busy"),Number.isFinite(k.total)&&k.total>0?M.set(Number(k.bytes)||0,k.total):M.pulse(Number(k.bytes)||0);continue}if(k.state==="canceled")return"canceled";if(k.state!=="done")throw new Error(String(k.error||w("error.transferFailed")));return"done"}}finally{M.setCancel(null)}},I=(N,G)=>{G?N.wrap.dataset.drag="":delete N.wrap.dataset.drag},C=N=>Array.isArray(N?.types)&&N.types.includes("Files");for(let N of[p.local,p.remote]){let G=N.wrap,$=0;G.addEventListener("dragenter",Y=>{N.kind!=="remote"||!C(Y.dataTransfer)||(Y.preventDefault(),$+=1,I(N,!0))}),G.addEventListener("dragover",Y=>{N.kind==="remote"&&(Y.preventDefault(),Y.dataTransfer!==null&&(Y.dataTransfer.dropEffect="copy"))}),G.addEventListener("dragleave",()=>{$=Math.max(0,$-1),$===0&&I(N,!1)}),G.addEventListener("drop",Y=>{$=0,I(N,!1);let H=gc(N.kind,Y.dataTransfer);if(!H.accept){H.reason==="wrongPane"&&(Y.preventDefault(),l(w("error.dropOnLocalPane"),"error"));return}Y.preventDefault(),!(_||p.remote.busy)&&Ph(Y.dataTransfer).then(k=>{(k.length>0||k._limitExceeded===!0)&&L(p.remote,k)})})}let L=async(N,G)=>{let $=Kt;if($.maxUploadFiles>0&&G.length>$.maxUploadFiles){l(w("error.uploadCountExceeded",{max:$.maxUploadFiles,count:G.length}),"error");return}let Y=$.maxUploadMb>0?$.maxUploadMb*1024*1024:0,H=G.find(k=>Y>0&&(k.file?.size??0)>Y);if(H!==void 0){l(w("error.uploadTooBig",{size:Ze(Y),name:String(H.relPath??"")}),"error");return}if(G._limitExceeded===!0){l(w("error.uploadTotalTooBig"),"error");return}await m(w("msg.uploading"),async()=>{if(N.path===""){l(w("error.transferDirsNotReady"),"error");return}for(let q of vc(G))await fetch("/api/dsh-tty/sftp/mkdir",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...e,path:c(N.path,q),parents:!0})}).catch(()=>{});M.reset();let k={stopped:!1,abort:null};M.setCancel(()=>k.abort?.());let W=0;try{let q=0;for(let j of G){if(k.stopped)break;q+=1,k.abort=null;try{await Lh(j.file,c(N.path,j.relPath),{spec:e,label:`${String(q)}/${String(G.length)} ${j.relPath}`,cancelRef:k,onProgress:(X,J)=>Number.isFinite(J)&&J>0?M.set(X,J):M.pulse(X),onLabel:X=>l(w("msg.uploadingName",{name:X}),"busy")}),W+=1}catch(X){if(Jr(X)||k.stopped)break;throw X}}}finally{M.setCancel(null)}k.stopped?(M.reset(),l(w("msg.uploadCanceled",{done:W,total:G.length}))):(M.done(w("status.allDone")),setTimeout(()=>M.reset(),1500),l(w("msg.uploadDoneCount",{count:G.length}))),await N.loadDir(N.path)})},T=Io(),D=T===null?420:Math.round(T.height*.56);Eh(o,w("panel.sftpDual",{label:t}),D,s),p.local.loadDir(""),p.remote.loadDir(""),wo=()=>{for(let N of[p.local,p.remote])N!==void 0&&typeof N.onShowHidden=="function"&&bo.delete(N.onShowHidden)}}var Vt=null,It=null;function xh(){return It!==null&&so(It.ownerKey,ke)?It.ownerKey:Wr(void 0,ke)}var kh=(e=xh())=>Vt!==null||It!==null&&It.ownerKey===e;function Eh(e,t,r,s){let o=Wr(s,ke),i=xt!==null&&xt.ownerKey===o;if(ue!==null&&!Ve&&mt!==null&&!i)try{let a=hh({title:t,side:"bottom",size:r,min:200,ownerSid:o,onClose:()=>ts(o)});a.element.appendChild(e),It=a;return}catch(a){console.warn("[dsh-tty] SFTP \u6302\u5230\u7EC8\u7AEF\u6302\u8F7D\u4F4D\u5931\u8D25\uFF0C\u56DE\u9000\u5BF9\u8BDD\u6846\uFF1A"+(a instanceof Error?a.message:String(a)))}let n=document.createElement("div");n.className="tt_sshBackdrop",n.appendChild(e),n.addEventListener("mousedown",a=>{a.target===n&&ts()}),document.body.appendChild(n),Vt=n}var Ts=null;function em(){let e=Ts;if(Ts=null,e!==null)try{e.click()}catch{}}function tm(e){let t=new TextEncoder().encode(e),r="";for(let s of t)r+=String.fromCharCode(s);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Lh(e,t,r){let{spec:s,label:o="",cancelRef:i,onProgress:n,onLabel:a,onDone:d}=r;return o!==""&&typeof a=="function"&&a(o),new Promise((l,_)=>{let m=tm(JSON.stringify({...s,path:t})),y=new XMLHttpRequest;i.abort=()=>{i.stopped=!0,y.abort()},y.open("POST","/api/dsh-tty/sftp/upload"),y.setRequestHeader("x-dsh-sftp-meta",m),y.upload.addEventListener("progress",u=>{u.lengthComputable?n(u.loaded,u.total):n(0,NaN)});let p=!1,c=u=>{p||(p=!0,u===null?l():_(u))};y.addEventListener("load",()=>{if(y.status===200){d?.(),c(null);return}if(i.stopped)return;let u="HTTP "+y.status;try{let h=JSON.parse(y.responseText);h!==null&&typeof h=="object"&&typeof h.error=="string"&&(u=h.error)}catch{}c(new Error(u))}),y.addEventListener("error",()=>{if(i.stopped){c(new es);return}c(new Error(w("error.networkError")))}),y.addEventListener("abort",()=>{c(new es)}),y.send(e)})}function Th(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let r=s=>String(s).padStart(2,"0");return t.getFullYear()+"-"+r(t.getMonth()+1)+"-"+r(t.getDate())+" "+r(t.getHours())+":"+r(t.getMinutes())}function Rh(e){let t=String(e).replace(/\/+$/,""),r=t.lastIndexOf("/");return r<=0?"/":t.slice(0,r)}function rm(e){let t=String(e).trim();if(t===""||(t=t.replace(/[\\/]+$/,""),t===""))return null;let r=t.match(/^([A-Za-z]:)(.*)$/);if(r!==null){let o=r[2];if(o==="")return null;let i=Math.max(o.lastIndexOf("\\"),o.lastIndexOf("/"));return i<=0?r[1]+"\\":r[1]+o.slice(0,i)}if(t.startsWith("\\\\")||t.startsWith("//")){let o=t.slice(2);if(o.split(/[\\/]/).filter(a=>a!=="").length<=2)return null;let n=Math.max(o.lastIndexOf("\\"),o.lastIndexOf("/"));return t.slice(0,2)+o.slice(0,n)}let s=t.lastIndexOf("/");return s<=0?s===0?"/":null:t.slice(0,s)}function vs(e,t){return e.endsWith("/")?e+t:e+"/"+t}function Mh(){let e=document.createElement("div");e.className="tt_sftpProgress";let t=document.createElement("div");t.className="tt_sftpTrack";let r=document.createElement("div");r.className="tt_sftpFill",t.appendChild(r);let s=document.createElement("span");s.className="tt_sftpPct",s.textContent="";let o=document.createElement("button");o.type="button",o.className="tt_sftpCancel",o.title=w("btn.cancelTransfer"),o.innerHTML=Yi,o.style.display="none";let i=null;o.addEventListener("click",p=>{p.stopPropagation();let c=i;c!==null&&(o.disabled=!0,c())}),e.appendChild(t),e.appendChild(s),e.appendChild(o);let n=p=>{s.textContent=p},a="",d=-1,l=p=>{p!==a&&(a=p,s.textContent=p)},_=p=>{let c=Math.round(p);c!==d&&(d=c,r.style.width=c+"%")},m=()=>{i=null,Ts===o&&(Ts=null),o.style.display="none",o.disabled=!1};return{el:e,reset(){delete e.dataset.active,delete e.dataset.state,a="",d=-1,this._last=void 0,this._lastAt=0,this._rate=void 0,r.style.width="0%",s.textContent="",m()},setCancel(p){if(p==null){m();return}i=p,Ts=o,o.disabled=!1,o.style.display=""},set(p,c){e.dataset.active="",delete e.dataset.state;let u=Date.now();if(this._last!==void 0&&u>this._lastAt){let h=(p-this._last)/((u-this._lastAt)/1e3);this._rate=this._rate===void 0?h:this._rate*.7+h*.3}if(this._last=p,this._lastAt=u,Number.isFinite(c)&&c>0){let h=Math.min(100,Math.max(0,p/c*100));_(h);let f=this._rate!==void 0&&this._rate>=0?gs(this._rate):"";l(Math.round(h)+"%"+(f!==""?" \xB7 "+f:""))}else{r.style.width="";let h=this._rate!==void 0&&this._rate>=0?gs(this._rate):"";l(Ze(p)+(h!==""?" \xB7 "+h:""))}},pulse(p){e.dataset.active="",delete e.dataset.state,r.style.width="45%",r.style.transition="none",setTimeout(()=>{r.style.transition="width .15s linear"},30);let c=Date.now();if(this._last!==void 0&&c>this._lastAt){let h=(p-this._last)/((c-this._lastAt)/1e3);this._rate=this._rate===void 0?h:this._rate*.7+h*.3}this._last=p,this._lastAt=c;let u=this._rate!==void 0&&this._rate>=0?gs(this._rate):"";l((Number.isFinite(p)?Ze(p):"\u2026")+(u!==""?" \xB7 "+u:""))},done(p){e.dataset.active="",e.dataset.state="done",r.style.width="100%",d=100,m(),l(p!==void 0&&p!==""?p:w("status.done"))},fail(p){e.dataset.active="",e.dataset.state="error",m(),l(p!==void 0&&p!==""?p:w("status.failed"))},text(p){delete e.dataset.state,p===void 0||p===""?(e.dataset.active="",a="",s.textContent=""):(e.dataset.active="",r.style.width="",d=-1,l(p))}}}async function sm(e,t,r,s=0,o=null,i=0){let n=s>0?s*1024*1024:0,a=Number.isFinite(i)&&i>0?i:0,d=typeof AbortController=="function"?new AbortController:null,l=!1;d!==null&&(t={...t,signal:d.signal},typeof o=="function"&&o(()=>{l=!0,d.abort()}));let _=a,m=null,y;try{if(y=await fetch(e,t),!y.ok){let S="HTTP "+y.status;try{let g=await y.json();g!==null&&typeof g=="object"&&typeof g.error=="string"&&(S=g.error)}catch{}throw new Error(S)}let p=Number(y.headers.get("content-length")),c=y.headers.get("content-range")??"",u=Number(/\/(\d+)\s*$/.exec(c)?.[1]);Number.isFinite(u)&&u>0?m=u:Number.isFinite(p)&&p>0&&(m=a+p);let h=y.body;if(h===null||typeof h.getReader!="function"){let S=await y.blob();if(n>0&&a+S.size>n)throw new Error(w("error.downloadTooBig",{size:Ze(n)}));return m!==null&&r(m,m),S}if(n>0&&m!==null&&m>n){try{await h.cancel()}catch{}throw new Error(w("error.downloadTooBig",{size:Ze(n)}))}let f=h.getReader(),v=[];for(;;){let{done:S,value:g}=await f.read();if(S)break;if(g!==void 0&&g.byteLength>0){if(_+=g.byteLength,n>0&&_>n){try{await f.cancel()}catch{}throw new Error(w("error.downloadTooBig",{size:Ze(n)}))}v.push(g),r(_,m!==null?m:NaN)}}return new Blob(v,{type:"application/octet-stream"})}catch(p){if(l||p!==null&&typeof p=="object"&&p.name==="AbortError")throw new es;if(p!==null&&typeof p=="object")throw p.received=_,p.total=m,p;let c=new Error(String(p));throw c.received=_,c.total=m,c}}async function Ah({url:e="/api/dsh-tty/sftp/download",makeBody:t,onProgress:r,maxMb:s=0,registerCancel:o=null,onResume:i=null}){let n=0,a=0;for(;;)try{return await sm(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t(n))},r,s,o,n)}catch(d){if(Jr(d))throw d;a+=1;let l=mc({received:d?.received??0,total:d?.total??null,attempt:a});if(!l.resume)throw d;n=l.offset,typeof i=="function"&&i(n)}}var es=class extends Error{constructor(){super(w("msg.canceled")),this.name="TransferCanceledError"}};function Jr(e){return e instanceof es}function Dh(e,t){let r=URL.createObjectURL(e),s=document.createElement("a");s.href=r,s.download=t,s.click(),setTimeout(()=>URL.revokeObjectURL(r),3e4)}async function Ph(e){if(e==null)return[];let t=typeof e.items<"u"?[...e.items]:[],r=[];for(let l of t){let _=typeof l.webkitGetAsEntry=="function"?l.webkitGetAsEntry():null;_!==null&&r.push(_)}if(r.length===0)return[...e.files??[]].map(l=>({relPath:l.name,file:l}));let s=[],o=Kt.maxUploadFiles,i=Kt.maxUploadMb>0?Kt.maxUploadMb*1024*1024:0,n=()=>o>0&&s.length>=o,a=0,d=(l,_)=>new Promise(m=>{if(n()){m();return}if(l.isFile===!0){l.file(c=>{i>0&&a+(c.size??0)>i?s._limitExceeded=!0:(s.push({relPath:_+l.name,file:c}),a+=c.size??0),m()},()=>m());return}if(l.isDirectory!==!0){m();return}let y=l.createReader(),p=()=>{y.readEntries(async c=>{if(c.length===0){m();return}for(let u of c){if(n())break;await d(u,_+l.name+"/")}if(n()){m();return}p()},()=>m())};p()});for(let l of r)await d(l,"");return s}function Qi(e,t){let r=Wr(t,ke);if(kh(r))return;let s=e!==null&&typeof e=="object"?e:{},o={};if(typeof s.name=="string"&&s.name!=="")o.name=s.name;else{for(let W of["host","username","auth","keyPath","passphrase","password"])typeof s[W]=="string"&&s[W]!==""&&(o[W]=s[W]);let k=Number(s.port);Number.isInteger(k)&&k>=1&&k<=65535&&(o.port=k),s.agentForward===!0&&(o.agentForward=!0)}let i=o.name??(o.username!==void 0?o.username+"@"+String(o.host??""):String(o.host??""));if(fh==="dual"){Q_(o,i,r);return}let n=document.createElement("div");n.className="tt_sftpCard";let a=document.createElement("div");a.className="tt_sftpTitleRow";let d=document.createElement("div");d.className="tt_sshTitle",d.innerHTML=Rs+"<span></span>",d.lastElementChild.textContent="SFTP \xB7 "+i;let l=document.createElement("button");l.type="button",l.className="tt_close",l.title=w("btn.close"),l.innerHTML=Vi,l.addEventListener("click",()=>ts(r)),a.appendChild(d),a.appendChild(l),n.appendChild(a);let _=document.createElement("div");_.className="tt_sftpBar";let m=document.createElement("input");m.type="text",m.className="tt_sftpPath",m.placeholder=w("placeholder.remotePath"),m.spellcheck=!1,m.autocomplete="off";let y=document.createElement("button");y.type="button",y.className="tt_toolBtn",y.innerHTML=Po+"<span>"+w("btn.refresh")+"</span>";let p=document.createElement("button");p.type="button",p.className="tt_toolBtn",p.innerHTML=Vc+"<span>"+w("btn.mkdir")+"</span>";let c=document.createElement("button");c.type="button",c.className="tt_toolBtn",c.innerHTML=Xp+"<span>"+w("btn.upload")+"</span>",c.title=w("btn.uploadTitle");let u=document.createElement("input");u.type="file",u.multiple=!0,u.style.display="none",_.appendChild(m),_.appendChild(y),_.appendChild(p),_.appendChild(c),n.appendChild(_),n.appendChild(u);let h=document.createElement("div");h.className="tt_sftpEditor",h.style.display="none";let f=document.createElement("input");f.type="text",f.className="tt_cardInput",f.spellcheck=!1,f.autocomplete="off";let v=document.createElement("button");v.type="button",v.className="tt_toolBtn",v.textContent=w("btn.ok");let S=document.createElement("button");S.type="button",S.className="tt_toolBtn",S.textContent=w("btn.cancel"),h.appendChild(f),h.appendChild(v),h.appendChild(S),n.appendChild(h);let g=null,x=()=>{h.style.display="none",g=null};v.addEventListener("click",()=>{g?.()}),S.addEventListener("click",x),f.addEventListener("keydown",k=>{k.key==="Enter"?(k.preventDefault(),g?.()):k.key==="Escape"&&(k.stopPropagation(),x())});let b=document.createElement("div");b.className="tt_sftpList",n.appendChild(b);let E=document.createElement("div");E.className="tt_sftpFoot";let P=document.createElement("div");P.className="tt_sftpStatus";let O=Mh();E.appendChild(O.el),E.appendChild(P),n.appendChild(E);let F={path:"",busy:!1},A=(k,W)=>{P.textContent=k,W===void 0?delete P.dataset.state:P.dataset.state=W},V=k=>{F.busy=k;for(let W of[y,p,c])W.disabled=k;m.disabled=k},B=async(k,W)=>{let q=await fetch("/api/dsh-tty/sftp/"+k,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...o,...W})}),j=await q.json().catch(()=>({}));if(!q.ok||j.ok!==!0)throw new Error(String(j.error||"HTTP "+q.status));return j},M=async(k,W)=>{if(!F.busy){V(!0),A(k,"busy");try{await W()}catch(q){A(String(q&&q.message?q.message:q),"error")}finally{V(!1)}}},U=(k,W,q,j)=>{let X=document.createElement("button");X.type="button",X.className="tt_sftpRow";let J=document.createElement("span");J.className="tt_sftpIcon",J.innerHTML=k,j!==void 0&&(J.dataset.kind=j);let ae=document.createElement("span");if(ae.className="tt_sftpName",ae.textContent=W,ae.title=W,X.appendChild(J),X.appendChild(ae),q!==""){let he=document.createElement("span");he.className="tt_sftpMeta",he.textContent=q,X.appendChild(he)}return X},I=(k,W,q,j)=>{let X=document.createElement("button");X.type="button",X.className="tt_sftpAct",X.innerHTML=W,X.title=q,X.addEventListener("click",J=>{J.stopPropagation(),j()}),k.appendChild(X)},C=(k,W,q)=>{let j=document.createElement("button");j.type="button",j.className="tt_sftpAct",j.innerHTML=qr,j.title=W.isDir?w("btn.deleteEntryDir",{name:W.name}):w("btn.deleteEntry",{name:W.name});let X=null;j.addEventListener("click",J=>{if(J.stopPropagation(),!F.busy){if(X!==null){clearTimeout(X),X=null,j.innerHTML=qr,delete j.dataset.danger,M(w("msg.deleting",{name:W.name}),async()=>{await B("remove",{path:q,recursive:W.isDir===!0}),await T(F.path),A(w("msg.deleted",{name:W.name}))});return}j.textContent=w("btn.confirm"),j.dataset.danger="",X=setTimeout(()=>{X=null,j.innerHTML=qr,delete j.dataset.danger},4e3)}}),k.appendChild(j)},L=k=>{if(b.textContent="",F.path!==""&&F.path!=="/"){let j=U(Ao,w("list.parentDir"),"","up");j.addEventListener("click",()=>{M(w("list.loading"),()=>T(Rh(F.path)))}),b.appendChild(j)}let W=Array.isArray(k)?k:[];if(W.length===0){let j=document.createElement("div");j.className="tt_addMenuTitle",j.textContent=w("list.emptyDir"),b.appendChild(j);return}let q=500;for(let j of W.slice(0,q)){if(j===null||typeof j!="object"||typeof j.name!="string"||j.name==="")continue;let X=vs(F.path,j.name),J=[];j.isDir===!0?J.push(w("meta.dir")):J.push(Ze(Number(j.size))||"\u2014");let ae=Th(Number(j.mtime));ae!==""&&J.push(ae);let he=U(j.isDir?Rs:j.isSymlink?Kc:qc,j.name,J.join(" \xB7 "),j.isDir===!0?"dir":j.isSymlink===!0?"link":"file");j.isDir===!0?he.addEventListener("click",_e=>{_e.target instanceof Element&&_e.target.closest(".tt_sftpAct")!==null||M(w("list.loading"),()=>T(X))}):(he.addEventListener("click",_e=>{_e.target instanceof Element&&_e.target.closest(".tt_sftpAct")!==null||D(j,X)}),I(he,Gc,w("btn.download",{name:j.name}),()=>{D(j,X)})),I(he,Do,w("btn.rename",{name:j.name}),()=>{f.placeholder=w("placeholder.newName"),f.value=j.name,h.style.display="",f.focus(),f.select(),g=async()=>{let _e=f.value.trim();_e===""||_e===j.name||(x(),await M(w("msg.renaming",{name:j.name}),async()=>{await B("rename",{from:X,to:vs(F.path,_e)}),await T(F.path)}))}}),C(he,j,X),b.appendChild(he)}if(W.length>q){let j=document.createElement("div");j.className="tt_addMenuTitle",j.textContent=w("list.truncated",{rest:W.length-q,total:W.length}),b.appendChild(j)}},T=async k=>{try{let W=await B("list",{path:k??F.path});F.path=typeof W.path=="string"&&W.path!==""?W.path:"/",m.value=F.path;let q=Array.isArray(W.entries)?W.entries.length:0;L(W.entries),A(F.path+" \u2014 "+w("list.itemCount",{count:q}))}catch(W){A(String(W&&W.message?W.message:W),"error")}},D=(k,W)=>M(w("msg.downloading",{name:k.name}),async()=>{O.reset();let q;try{q=await Ah({makeBody:j=>({...o,path:W,...j>0?{offset:j}:{}}),onProgress:(j,X)=>O.set(j,X),maxMb:Kt.maxDownloadMb,registerCancel:j=>O.setCancel(j),onResume:j=>A(w("msg.downloadResuming",{name:k.name,offset:Ze(j)||String(j)+" B"}),"busy")})}catch(j){if(Jr(j)){O.reset(),A(w("msg.downloadCanceled",{name:k.name}));return}throw O.fail(w("error.downloadFailed")),j}O.done(w("status.done")),Dh(q,k.name),setTimeout(()=>O.reset(),1500),A(w("msg.downloaded",{name:k.name,size:Ze(q.size)||String(q.size)+" B"}))}),N=(k,W,q,j,X)=>Lh(k,vs(F.path,W),{spec:o,label:(j>1?String(q)+"/"+String(j)+" ":"")+W,cancelRef:X,onProgress:(J,ae)=>{Number.isFinite(ae)&&ae>0?O.set(J,ae):O.pulse(J)},onLabel:J=>A(w("msg.uploadingName",{name:J}),"busy"),onDone:()=>{j===1&&O.done(w("msg.uploadDone"))}}).catch(J=>{throw Jr(J)||O.fail(w("error.uploadFailed")),J}),G=async k=>M(w("msg.uploading"),async()=>{let W=Kt;if(W.maxUploadFiles>0&&k.length>W.maxUploadFiles){A(w("error.uploadCountExceeded",{max:W.maxUploadFiles,count:k.length}),"error"),O.fail(w("status.overLimit"));return}let q=W.maxUploadMb>0?W.maxUploadMb*1024*1024:0,j=k.find(_e=>q>0&&(_e.file?.size??0)>q);if(j!==void 0){A(w("error.uploadTooBig",{size:Ze(q),name:String(j.relPath??"")}),"error"),O.fail(w("status.overLimit"));return}if(k._limitExceeded===!0){A(w("error.uploadTotalTooBig"),"error"),O.fail(w("status.overLimit"));return}let X=new Set;for(let _e of k){let Z=_e.relPath.lastIndexOf("/");if(Z<=0)continue;let Ce=_e.relPath.slice(0,Z);X.has(Ce)||(X.add(Ce),await B("mkdir",{path:vs(F.path,Ce),parents:!0}).catch(()=>{}))}O.reset();let J={stopped:!1,abort:null};O.setCancel(()=>J.abort?.());let ae=0,he=0;try{for(let _e of k){if(J.stopped)break;ae+=1,J.abort=null;try{await N(_e.file,_e.relPath,ae,k.length,J),he+=1}catch(Z){if(Jr(Z)||J.stopped)break;throw Z}}}finally{O.setCancel(null)}if(J.stopped){O.reset(),A(w("msg.uploadCanceled",{done:he,total:k.length})),await T(F.path);return}O.done(w("status.allDone")),setTimeout(()=>O.reset(),1500),A(w("msg.uploadDoneCount",{count:k.length})),await T(F.path)});y.addEventListener("click",()=>{M(w("list.loading"),()=>T(F.path))}),p.addEventListener("click",()=>{F.busy||(f.placeholder=w("placeholder.newDirName"),f.value="",h.style.display="",f.focus(),g=async()=>{let k=f.value.trim();k!==""&&(x(),await M(w("msg.creatingDir",{name:k}),async()=>{await B("mkdir",{path:vs(F.path,k)}),await T(F.path)}))})}),c.addEventListener("click",()=>{F.busy===!1&&u.click()}),u.addEventListener("change",()=>{let k=[...u.files??[]].map(W=>({relPath:W.name,file:W}));u.value="",k.length>0&&G(k)});let $=0,Y=k=>{k?b.dataset.drag="":delete b.dataset.drag};n.addEventListener("dragenter",k=>{k.preventDefault(),$+=1,Y(!0)}),n.addEventListener("dragover",k=>{k.preventDefault()}),n.addEventListener("dragleave",()=>{$=Math.max(0,$-1),$===0&&Y(!1)}),n.addEventListener("drop",k=>{k.preventDefault(),$=0,Y(!1),!F.busy&&Ph(k.dataTransfer).then(W=>{(W.length>0||W._limitExceeded===!0)&&G(W)})}),m.addEventListener("keydown",k=>{if(k.key!=="Enter"||(k.preventDefault(),F.busy))return;let W=m.value.trim();W!==""&&M(w("list.loading"),()=>T(W))});let H=Io();Eh(n,"SFTP \xB7 "+i,H===null?340:Math.round(H.height*.46),r),M(w("status.connectingEllipsis"),()=>T(""))}function ts(e){let t=e===void 0?xh():e,r=Vt,s=It!==null&&It.ownerKey===t?It:null;if(r===null&&s===null)return;em();let o=wo;wo=null,o?.(),Vt=null,s!==null&&(It=null),r!==null&&r.remove(),s!==null&&s.dispose()}function Bh(){if(st===null)return;let e=st.style.display==="none"||st.style.display==="";st.style.display=e?"":"none";let t=ue!==null?ue.querySelector("[data-act=search]"):null;t!==null&&(e?t.dataset.on="":delete t.dataset.on),e&&st.focus()}function im(){return{matchBackground:Te("--tt-term-search-match"),matchBorder:Te("--tt-term-search-match-border"),activeMatchBackground:Te("--tt-term-search-active"),activeMatchBorder:Te("--tt-term-search-active-border"),matchOverviewRuler:Te("--tt-term-search-match-border"),activeMatchColorOverviewRuler:Te("--tt-term-search-active-border")}}function nm(e){let t=vt();if(t===void 0||t.search===void 0)return;let r=st.value;if(r==="")return;let s={decorations:im()};e?t.search.findPrevious(r,s):t.search.findNext(r,s)}function Bc(){As||ue===null&&!Bo()||gr!==null||(gr=setTimeout(()=>{gr=null,$i()},xs),xs=Math.min(xs*2,5e3))}function zs(e){return e!==null&&typeof e=="object"&&e.persist===!0&&typeof e.persistName=="string"&&e.persistName!==""}function Lo(e){return zs(e)||e!==null&&typeof e=="object"&&typeof e.command=="string"&&e.command!==""}function om(){return ar==="tmux"?{t:"spawn",cwd:_o(),persist:!0,persistName:Wo()}:{t:"spawn",cwd:_o()}}async function Oh(){if(!ho){ho=!0;try{await am()}finally{ho=!1}}}var ho=!1;async function am(){if(await Uo(),ue===null){await cm();return}let e=d_(),t=h_();if(![...fe.values()].some(n=>n.embedded!==!0)){if(e.length>0||t.length>0){Pe({t:"sessions"});let n=await Hi("sessions",4e3),a=new Map;if(n!==null&&Array.isArray(n.list))for(let l of n.list)l!==null&&typeof l=="object"&&l.attachable===!0&&a.set(l.sid,l);let d=new Set;for(let l of e){if(a.has(l.sid))b_(l);else if(Lo(l.spawnSpec))Dc(l);else continue;zs(l.spawnSpec)&&d.add(l.spawnSpec.persistName)}for(let l of t){let _=l.spawnSpec.persistName;d.has(_)||(Dc(l),d.add(_))}lr()}if(![...fe.values()].some(n=>n.embedded!==!0)){if(await ji())return;Ds()}return}let r=[...fe.values()].filter(n=>!n.exited&&(n.embedded!==!0||n.spawned===!0)),s=r.filter(n=>Lo(n.spawnSpec)),o=null;if(s.length>0){Pe({t:"sessions"});let n=await Hi("sessions",4e3),a=vi(n!==null?n.list:[]);o=s.filter(d=>!a.has(d.sid));for(let d of o)Fi(d.sid)}let i=o!==null?new Set(o.map(n=>n.sid)):new Set;for(let n of r)i.has(n.sid)||Pe({t:"attach",sid:n.sid})}function lm(){Ae!==null&&(Ae.readyState===WebSocket.OPEN||Ae.readyState===WebSocket.CONNECTING)||$i()}async function cm(){let e=[...fe.values()].filter(s=>s.embedded===!0&&!s.exited);if(e.length===0)return;Pe({t:"sessions"});let t=await Hi("sessions",4e3),r=vi(t!==null?t.list:[]);for(let s of e)s.spawned===!0&&(r.has(s.sid)?Pe({t:"attach",sid:s.sid}):Lo(s.spawnSpec)?ch(s):(s.exited=!0,s.live=!1,Ur(s,w("status.ended"),w("btn.clickRerun"),"exited")))}function $i(){if(Ae!==null){try{Ae.close()}catch{}Ae=null}As=!1,clearTimeout(gr),gr=null,yi=!0,Si(w("status.connectingEllipsis"),"");try{Ae=new WebSocket(Hp())}catch(e){yi=!1,Si(w("error.connectFailed",{error:e.message}),"error"),Bc();return}Ae.onopen=()=>{yi=!1,xs=1e3,Ct=null,Si(w("status.connected"),"connected");for(let e of[...uo])uo.delete(e),fe.has(e.tab.sid)&&Pe(e.frame);Oh()},Ae.onmessage=e=>{let t;try{t=JSON.parse(e.data)}catch{return}let r=t.sid;if(t.t==="ready"){let s=typeof t.target=="string"?t.target:"";ao(r,t.kind==="ssh"?w("status.connectedSsh",{target:s!==""?s+" ":""}):w("status.connectedPid",{pid:t.pid}),"connected");let o=fe.get(r);if(o!==void 0){if(o.exited=!1,o.spawned=!0,o.live=!0,o.errored=!1,o.target=s,o.persistTmux=t.persist===!0,t.kind==="ssh"&&s!==""&&!o.label&&(o.label=s,ht()),br(),lo(r),Ur(o,""),rs(o),t.persist===!0){let i=document.fonts!==void 0&&document.fonts.ready!==void 0?document.fonts.ready:Promise.resolve();Promise.race([i,new Promise(n=>setTimeout(n,500))]).then(()=>sh(150))}Bs(),o_(r),lr()}}else if(t.t==="sessions")v_(t.list);else if(t.t==="data"){let s=fe.get(r);s!==void 0&&s.term!==null&&(s.term.write(String(t.d??"")),pm())}else if(t.t==="exit"){let s=fe.get(r);if(s!==void 0){s.exited=!0,s.live=!1,s.stats=null,r===ke&&xr();let o=t.code!==null&&t.code!==void 0?"code="+t.code:"",i=t.signal!==null&&t.signal!==void 0?"signal="+t.signal:"";ao(r,w("status.exitedWith",{detail:[o,i].filter(Boolean).join(" ")}),""),br(),lo(r),Ur(s,w("status.exited"),w("btn.clickReopen"),"exited"),Bs(),lr()}}else if(t.t==="stats")try{let s=fe.get(r);if(s!==void 0){let o=t.stats;s.stats=kc(o)?o:null,s.statsAt=Date.now(),r===ke&&xr()}}catch(s){console.warn("[dsh-tty] stats \u5E27\u5904\u7406\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09: "+(s instanceof Error?s.message:String(s)))}else if(t.t==="hint"){if(!Oi||t.kind!=="failure"||typeof r!="string"||r==="")return;cr.set(r,{exitCode:typeof t.exitCode=="number"?t.exitCode:null,at:typeof t.at=="number"?t.at:Date.now(),dismissed:!1,busy:!1,answer:null,command:"",error:null}),r===ke&&kr()}else if(t.t==="error")if(ao(r,w("status.error",{message:String(t.m??"")}),"error"),typeof r=="string"){let s=fe.get(r);s!==void 0&&(s.live||(s.errored=!0),br(),lo(r),Ur(s,w("status.errored"),w("status.retryHint",{message:String(t.m??"")}),"error"))}else hm(w("btn.clickRetry"))},Ae.onclose=()=>{if(yi=!1,!As){Si(w("status.disconnectedReconnecting"),"error");for(let e of fe.values())e.exited||Ur(e,w("status.disconnected"),w("status.reconnecting"),"info");Bc()}},Ae.onerror=()=>{}}function hm(e){Kr!==null&&(Kr.textContent=e)}function To(){(ue===null||Ve)&&Mo()}var xi="DSH_TTY_ALLOW_PROXY_COMMAND";function dm(e){let t=new Date(Number(e)*1e3);if(Number.isNaN(t.getTime()))return String(e);let r=s=>String(s).padStart(2,"0");return`${String(t.getFullYear())}-${r(t.getMonth()+1)}-${r(t.getDate())} ${r(t.getHours())}:${r(t.getMinutes())}:${r(t.getSeconds())}`}function zo(){return typeof navigator<"u"&&navigator.clipboard!==void 0&&typeof navigator.clipboard.writeText=="function"}async function Ro(e){if(zo())try{return await navigator.clipboard.writeText(e),!0}catch{}let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let r=!1;try{r=document.execCommand("copy")}catch{r=!1}return t.remove(),r||Fs(w("error.copyFailed"),"error"),r}async function um(e){if(zo()&&typeof navigator.clipboard.readText=="function")try{let s=await navigator.clipboard.readText();return s!==""&&Pe({t:"input",sid:e.sid,d:s}),!0}catch{}let t=document.createElement("textarea");t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.focus();let r=!1;try{r=document.execCommand("paste");let s=r?t.value:"";s!==""&&Pe({t:"input",sid:e.sid,d:s})}catch{r=!1}return t.remove(),r||Fs(w("error.pasteFailed"),"error"),r}function Mo(){if(ue!==null){Ve&&Ih();return}Is(),ue=document.createElement("div"),ue.className="tt_modalBackdrop",ue.innerHTML='<div class="tt_modal"><div class="tt_header"><span class="tt_titleIcon">'+Gi+'</span><div class="tt_tabbar"><div class="tt_tabs"></div><button type="button" class="tt_tabMore" hidden></button><button type="button" class="tt_tabAdd"></button></div><div class="tt_status"><span class="tt_statusDot"></span><span class="tt_statusText">'+w("status.initializing")+'</span></div><input class="tt_searchInput" style="display:none" placeholder="'+w("placeholder.search")+'" /><span class="tt_toolGroup"><button class="tt_toolBtn tt_iconBtn" data-act="search" title="'+w("btn.searchTitle")+'">'+zp+'</button><button class="tt_toolBtn tt_iconBtn" data-act="clear" title="'+w("btn.clearTitle")+'">'+jp+'</button><button class="tt_toolBtn tt_iconBtn" data-act="copy" title="'+w("btn.copyTitle")+'">'+$p+'</button><button class="tt_toolBtn tt_iconBtn" data-act="paste" title="'+w("btn.pasteTitle")+'">'+qp+'</button></span><span class="tt_winGroup"><button class="tt_min" title="'+w("btn.minimizeTitle")+'">'+Vp+'</button><button class="tt_close" title="'+w("btn.closePanelTitle")+'">'+Vi+'</button></span></div><div class="tt_connbar" data-hidden><div class="tt_connArea"><span class="tt_connDot"></span><span class="tt_connTarget">\u2014</span><span class="tt_connBadge"></span></div><div class="tt_connActions"></div></div><div class="tt_work"><div class="tt_body"><div class="tt_statsBar" hidden></div><button type="button" class="tt_assistBadge" hidden><span class="tt_assistDot"></span><span class="tt_assistBadgeText"></span></button><div class="tt_overlay"></div></div></div></div>',document.body.appendChild(ue),Mi=ue.querySelector(".tt_status"),mr=ue.querySelector(".tt_statusText"),yr=ue.querySelector(".tt_statusDot"),Re=ue.querySelector(".tt_tabs");let e=ue.querySelector(".tt_tabAdd");e!==null&&(e.title=w("btn.newTab"),e.innerHTML=Yp,e.addEventListener("click",()=>{N_(e)})),Bt=ue.querySelector(".tt_tabMore"),Bt!==null&&(Bt.innerHTML=$c,Bt.title=w("btn.tabList"),Bt.addEventListener("click",()=>{H_(Bt)})),Re.addEventListener("scroll",vo),Re.addEventListener("wheel",R_,{passive:!1}),ws=ue.querySelector(".tt_connbar"),ys=ue.querySelector(".tt_connDot"),Ai=ue.querySelector(".tt_connTarget"),_t=ue.querySelector(".tt_connBadge"),Ss=ue.querySelector(".tt_connActions"),mt=ue.querySelector(".tt_work"),lt=ue.querySelector(".tt_body"),St=ue.querySelector(".tt_statsBar"),Ji(),Ct=null,eh(),Kr=ue.querySelector(".tt_body > .tt_overlay"),ir=ue.querySelector(".tt_assistBadge"),ir!==null&&ir.addEventListener("click",()=>{ir!==null&&G_(ir)}),kt(),kr(),st=ue.querySelector(".tt_searchInput"),Kr.addEventListener("click",()=>{Kr.textContent="",$i()});let t=ue.querySelector("[data-act=search]");t.addEventListener("click",()=>{Bh(),st.style.display!=="none"&&st.focus()}),t.dataset.on="",st.addEventListener("keydown",r=>{r.key==="Enter"?(r.preventDefault(),nm(r.shiftKey)):r.key==="Escape"&&(r.stopPropagation(),st.style.display="none")}),ue.querySelector("[data-act=clear]").addEventListener("click",()=>{let r=vt();r!==void 0&&r.term!==null&&r.term.clear()}),ue.querySelector("[data-act=copy]").addEventListener("click",()=>{let r=vt();if(r===void 0||r.term===null)return;let s=r.term.getSelection();s!==""&&Ro(s)}),ue.querySelector("[data-act=paste]").addEventListener("click",()=>{let r=vt();r!==void 0&&um(r)}),ue.querySelector(".tt_min").addEventListener("click",()=>{qi()}),ue.querySelector(".tt_close").addEventListener("click",()=>{Os()}),ue.addEventListener("mousedown",r=>{r.target===ue&&qi()}),document.addEventListener("keydown",Nh),Cs=new ResizeObserver(()=>{Ve||(ki(),f_(vt()),vo())}),Cs.observe(lt),ht(),br(),Ae!==null&&Ae.readyState===WebSocket.OPEN?Oh():$i()}function fm(){Qe=document.createElement("div"),Qe.className="tt_dock",Qe.title=w("btn.restoreDock"),Qe.innerHTML='<span class="tt_dockTitle">'+Gi+"<span>"+w("panel.title")+'</span><span class="tt_dockCount"></span></span><span class="tt_dockStatus"></span><span class="tt_dockDot"></span><button class="tt_dockClose" title="'+w("btn.closePanelTitle")+'">'+Yi+"</button>",Di=Qe.querySelector(".tt_dockCount"),Qr=Qe.querySelector(".tt_dockStatus"),Sr=Qe.querySelector(".tt_dockDot");let e=[...fe.values()].filter(t=>!t.exited).length;Di.textContent=fe.size>0?"\xB7 "+e+"/"+fe.size:"",mr!==null&&(Qr.textContent=mr.textContent),yr!==null&&(Sr.dataset.state=yr.dataset.state??""),Qe.addEventListener("click",t=>{if(t.target.closest(".tt_dockClose")!==null){t.stopPropagation(),Os();return}Ih()}),document.body.appendChild(Qe)}function qi(){ue===null||Ve||(yt(),Xt(),kt(),nr(),Ve=!0,Vt!==null&&(Vt.style.display="none"),st!==null&&(st.style.display="none"),ue.dataset.minimized="",th(),Ws(),xr(),document.querySelector("[data-dsh-tty-entry]")!==null?Bs():(fm(),Qe.classList.add("tt_dockCompact")))}function Bs(){let e=document.querySelector("[data-dsh-tty-entry]");if(e===null)return;let t=e.querySelector(".tt_sidebarEntryBadge");if(!Ve){t!==null&&t.remove(),delete e.dataset.minimized,e.removeAttribute("title");return}t===null&&(t=document.createElement("span"),t.className="tt_sidebarEntryBadge",t.innerHTML='<span class="tt_sidebarBadgeDot"></span><span class="tt_sidebarBadgeCount"></span>',e.appendChild(t)),e.dataset.minimized="",e.title=w("status.minimized");let r=[...fe.values()].filter(o=>!o.exited).length;t.querySelector(".tt_sidebarBadgeCount").textContent=r+"/"+fe.size;let s=t.querySelector(".tt_sidebarBadgeDot");s!==null&&yr!==null&&(s.dataset.state=yr.dataset.state??"")}function pm(){if(!Ve)return;let e=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot")??Sr;e!==null&&(e.dataset.active="",clearTimeout(Pi),Pi=setTimeout(()=>{delete e.dataset.active},900))}function Ih(){if(ue===null||!Ve)return;Ve=!1,delete ue.dataset.minimized,Vt!==null&&(Vt.style.display=""),clearTimeout(Pi),Qe!==null&&(Qe.remove(),Qe=null),Di=null,Qr=null,Sr=null,Bs(),eh(),Ws(),xr();let e=vt();if(e!==void 0&&e.fit!==void 0){try{e.fit.fit()}catch{}e.spawned&&!e.exited&&rs(e)}e!==void 0&&e.term!==null&&e.term.focus()}function Os(){if(ue===null)return;Ls(!0);let e=Bo();if(As=!e,Ve=!1,yt(),Xt(),kt(),Ei(),Ui(),nr(),ts(),clearTimeout(Pi),clearTimeout(gr),gr=null,xs=1e3,Qe!==null&&(Qe.remove(),Qe=null),Di=null,Qr=null,Sr=null,Bs(),Ae!==null){for(let t of fe.values())!t.exited&&t.embedded!==!0&&Pe({t:"kill",sid:t.sid});if(!e){try{Ae.close()}catch{}Ae=null}}Cs!==null&&(Cs.disconnect(),Cs=null);for(let[t,r]of[...fe])if(r.embedded!==!0){if(r.term!==null)try{r.term.dispose()}catch{}fe.delete(t)}ke=null,Ms=null,document.removeEventListener("keydown",Nh),ue.remove(),ue=null,mt=null,Mi=null,mr=null,yr=null,Re=null,Bt=null,ws=null,ys=null,Ai=null,_t=null,Ss=null,Ui(),th(),St=null,Ji(),Ct=null,lt=null,Kr=null,st=null,Hs=0;try{sessionStorage.removeItem(Bi)}catch{}}function Nh(e){if(e.key==="Escape"&&ue!==null){if(e.preventDefault(),Vt!==null){ts();return}if(Vr!==null){nr();return}if(gt!==null){yt();return}qi()}}function _m(){let e=document.querySelector('[data-pane="sidebar"], [class*="sidebarCol"]');if(e!==null)return e.querySelector('[class*="logoRow"]')?.parentElement??e.firstElementChild}function mm(e){let t=e.querySelector('button[class*="newSession"]');if(t!==null)return t;for(let r of e.children)if(r.tagName==="BUTTON")return r}function gm(){let e=document.createElement("div");return e.dataset.dshTtyEntry="",e.className="tt_sidebarEntry",e.setAttribute("role","button"),e.setAttribute("aria-label",w("panel.title")),e.tabIndex=0,e.innerHTML='<span class="tt_sidebarEntryIcon">'+Gi+'</span><span class="tt_sidebarEntryLabel">'+w("panel.title")+"</span>",e.addEventListener("click",t=>{t.preventDefault(),Mo()}),e.addEventListener("keydown",t=>{(t.key==="Enter"||t.key===" "||t.key==="Spacebar")&&(t.preventDefault(),Mo())}),e}function Oc(e,t){let r=mm(e);if(r===void 0)return!1;if(t.parentElement!==e){let s=r.closest('[class*="logoRow"]'),o=s!==null&&s.parentElement===e?s:r,i=Array.from(e.children).filter(n=>n instanceof HTMLElement&&n.matches("[data-dsh-global-search-entry], [data-dsh-rss-entry], [data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-tty-entry]"));if(i.length>0){let n=i[i.length-1];e.insertBefore(t,n.nextSibling)}else e.insertBefore(t,o.nextElementSibling)}return!0}function vm(){if(Is(),typeof document<"u"&&document.querySelector("[data-dsh-tty-entry]")!==null)return()=>{};let e=gm(),t,r=!1,s=()=>{if(t!==void 0&&!t.isConnected&&(i.disconnect(),t=void 0,r=!1),r){if(document.body.contains(e))return;i.disconnect(),t=void 0,r=!1}t??(t=_m()),t!==void 0&&(r=Oc(t,e),r&&i.observe(t,{childList:!0,subtree:!0}))},o=new MutationObserver(()=>{s()});o.observe(document.body,{childList:!0,subtree:!0});let i=new MutationObserver(()=>{if(t===void 0||!t.isConnected){r=!1,s();return}t.contains(e)||(r=Oc(t,e))});return s(),()=>{o.disconnect(),i.disconnect(),e.remove()}}window.__ModuleLoader__.load({id:"@hyzyn/dsh-tty",factory:e=>{let t={},r=e("react"),{jsx:s,jsxs:o}=e("react/jsx-runtime"),i="M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 9.13382 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z";function n(d){let l=d&&d.view,_=l==="page",[m,y]=r.useState(_),[p,c]=r.useState(null),[u,h]=r.useState(!1),[f,v]=r.useState(!1),[S,g]=r.useState({kind:"",text:""}),[x,b]=r.useState(null),[E,P]=r.useState(""),[O,F]=r.useState(!1),[A,V]=r.useState(Date.now()),B=r.useRef(null),M=r.useRef(null),[U,I]=r.useState([]),[C,L]=r.useState(!1),[T,D]=r.useState({groups:[],loading:!1,failed:!1}),[N,G]=r.useState(!1),$=r.useRef(null),Y=r.useRef(0),H=R=>s("div",{className:"tt_cardSection",children:R}),k=async()=>{try{let z=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json();z.ok&&typeof z.config=="object"&&z.config!==null?(B.current=z.config,M.current=JSON.stringify(J(z.config)),c(z.config),Ps(z.config)):g({kind:"error",text:String(z.error||w("error.configLoadFailed"))})}catch(R){g({kind:"error",text:String(R&&R.message?R.message:R)})}},W=async()=>{try{let z=await(await fetch("/api/dsh-tty/shells",{cache:"no-store"})).json();z.ok&&Array.isArray(z.shells)&&I(z.shells)}catch{}};r.useLayoutEffect(()=>{if(!N)return;let R=()=>{let z=$.current,K=z===null||z.parentElement===null?null:z.parentElement.querySelector(".tt_routeList");z===null||K===null||(K.style.width=String(Math.round(z.getBoundingClientRect().width))+"px",Us(K,z))};return R(),window.addEventListener("scroll",R,!0),window.addEventListener("resize",R),()=>{window.removeEventListener("scroll",R,!0),window.removeEventListener("resize",R)}},[N,T.loading,T.failed,T.groups]);let q=async()=>{let R=Y.current+1;Y.current=R,D(z=>({...z,loading:!0}));try{let K=await(await fetch("/api/dsh-tty/model-catalog",{cache:"no-store"})).json();if(K.ok===!0&&R===Y.current){D({groups:Array.isArray(K.groups)?K.groups:[],loading:!1,failed:!1});return}}catch{}R===Y.current&&D({groups:[],loading:!1,failed:!0})};r.useEffect(()=>{m&&!u&&(h(!0),k(),W(),q())},[m]);let j=(R,z)=>c(K=>{let ee={...K||{},[R]:z};return B.current=ee,ee}),X=new Set(["toolsRegistered","platform","allowProxyCommandGranted","allowProxyCommandGrantSource","allowProxyCommandGrantedAt"]),J=R=>{let z={};for(let[K,ee]of Object.entries(R||{}))X.has(K)||ee!==void 0&&(z[K]=ee);return z.sshHosts=Array.isArray(R?.sshHosts)?R.sshHosts:[],z.tunnels=Array.isArray(R?.tunnels)?R.tunnels:[],R?.sftpLimits&&typeof R.sftpLimits=="object"&&(z.sftpLimits={maxDownloadMb:Number(R.sftpLimits.maxDownloadMb)||0,maxUploadMb:Number(R.sftpLimits.maxUploadMb)||0,maxUploadFiles:Number(R.sftpLimits.maxUploadFiles)||0}),z};B.current=p;let ae=(R,z)=>c(K=>({...K||{},sftpLimits:{...K?.sftpLimits??{},[R]:z}})),[he,_e]=r.useState(null),[Z,Ce]=r.useState(null),[He,Ee]=r.useState(""),[Oe,Ue]=r.useState(null),[te,de]=r.useState(""),[ve,Q]=r.useState(""),[se,oe]=r.useState(""),re=r.useRef(null),[ne,ce]=r.useState(!1),[le,ge]=r.useState({text:"",kind:""}),[we,Le]=r.useState(!1),[ye,be]=r.useState({running:!1,ok:!1,text:""}),[xe,Fe]=r.useState({}),[tt,Er]=r.useState([]),[it,hr]=r.useState({direction:"local",localPort:"",remoteHost:"",remotePort:"",localTargetPort:"",bookName:""}),[Et,is]=r.useState(null);r.useEffect(()=>{if(!m)return;let R=!0,z=async()=>{try{let ie=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();R&&ie.ok&&Array.isArray(ie.tunnels)&&Er(ie.tunnels)}catch{}};z();let K=setInterval(z,2e3);return()=>{R=!1,clearInterval(K)}},[m]);let dr=R=>z=>hr(K=>({...K||{},[R]:z.target.value})),jo=(R,z)=>hr(K=>({...K||{},[R]:z})),Hh=R=>R?.direction==="remote"?w("meta.tunnelRemote",{host:R.remoteHost||"127.0.0.1",port:String(R.remotePort??0),local:String(R.localTargetPort??0)}):w("meta.tunnelLocal",{local:String(R?.localPort??0),host:R?.remoteHost??"?",port:String(R?.remotePort??0)}),$o=(p?.sshHosts??[]).find(R=>R?.name===it?.bookName),en=async R=>{try{let z=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({tunnels:R})}),K=await z.json().catch(()=>({}));return!z.ok||!K.ok?(g({kind:"error",text:String(K.error||w("error.saveTunnelFailed"))}),{ok:!1,warnings:[]}):{ok:!0,warnings:Array.isArray(K.warnings)?K.warnings.map(ie=>String(ie)).filter(ie=>ie!==""):[]}}catch(z){return g({kind:"error",text:String(z&&z.message?z.message:z)}),{ok:!1,warnings:[]}}},qo=(R,z)=>{if(R.warnings.length>0){g({kind:"warn",text:R.warnings.join(" ")});return}g({kind:"ok",text:z})},Ko=()=>cc(it,(Array.isArray(p?.sshHosts)?p.sshHosts:[]).map(R=>R?.name),w),Fh=R=>{g({kind:"",text:""}),is(String(R?.name??"")),hr({direction:R?.direction==="remote"?"remote":"local",bookName:String(R?.bookName??""),localPort:R?.localPort?String(R.localPort):"",remoteHost:String(R?.remoteHost??""),remotePort:R?.remotePort?String(R.remotePort):"",localTargetPort:R?.localTargetPort?String(R.localTargetPort):""})},Wh=()=>{is(null),g({kind:"",text:""}),hr(R=>({...R||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))},Uh=()=>{g({kind:"",text:""});let R=Ko();if(!R.ok){g({kind:"error",text:R.error});return}let z=R.tunnel,K=Array.isArray(p?.tunnels)?p.tunnels:[];if(hc(K,z.name)!==void 0){g({kind:"error",text:w("error.tunnelNameTaken",{name:z.name})});return}let ee=[...K,z];c(ie=>({...ie||{},tunnels:ee})),hr(ie=>({...ie||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),en(ee).then(ie=>{ie.ok&&qo(ie,w("msg.tunnelApplied",{name:z.name}))})},zh=()=>{if(Et===null)return;g({kind:"",text:""});let R=Ko();if(!R.ok){g({kind:"error",text:R.error});return}let z=Array.isArray(p?.tunnels)?p.tunnels:[],K=dc(z,Et,R.tunnel,w);if(!K.ok){K.reason==="missing"&&is(null),g({kind:"error",text:K.error});return}let ee=K.tunnels;c(ie=>({...ie||{},tunnels:ee})),en(ee).then(ie=>{if(ie.ok!==!0){c(pe=>({...pe||{},tunnels:z}));return}is(null),hr(pe=>({...pe||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),qo(ie,w("msg.tunnelUpdated",{name:R.tunnel.name}))})},Go=(R,z)=>{c(K=>({...K||{},tunnels:R})),en(R).then(K=>{if(K.ok!==!0){c(ee=>({...ee||{},tunnels:z}));return}K.warnings.length>0&&g({kind:"warn",text:K.warnings.join(" ")})})},jh=R=>{let z=Array.isArray(p?.tunnels)?p.tunnels:[];Et!==null&&String(R??"")===Et&&(is(null),hr(K=>({...K||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))),Go(z.filter(K=>K?.name!==R),z)},$h=(R,z)=>{let K=Array.isArray(p?.tunnels)?p.tunnels:[];Go(K.map(ee=>ee?.name===R?{...ee,enabled:z}:ee),K)},qh=R=>{_e(R?.name??null),Ee(""),be({running:!1,ok:!1,text:""}),de(""),Q(""),rn(),ce(Ot!==null),Ce({name:R?.name??"",host:R?.host??"",port:String(R?.port??22),username:R?.username??"",auth:R?.auth==="key"||R?.auth==="password"?R.auth:"agent",keyPath:R?.keyPath??"",passphrase:R?.passphrase??"",password:R?.password??"",agentForward:R?.agentForward===!0,hostKeyAlias:R?.hostKeyAlias??"",persist:R?.persist!==!1}),Fc().then(z=>Ue(z)),sn(R?.password??"")},Vo=()=>{_e(null),Ce(null),Ee(""),be({running:!1,ok:!1,text:""}),de(""),Q(""),rn()},Kh=async()=>{if(Z===null)return;let R=Z.name.trim(),z=Z.host.trim(),K=Z.username.trim();if(R===""||z===""||K===""){Ee(w("error.nameHostUserRequired"));return}let ee=Number(Z.port);if((!Number.isInteger(ee)||ee<1||ee>65535)&&(ee=22),(p?.sshHosts??[]).some(pe=>pe?.name===R&&R!==he)){Ee(w("error.bookNameTaken",{name:R}));return}if(Z.auth==="key"&&Z.keyPath.trim()===""){Ee(w("error.keyPathRequired"));return}Ee("");let ie=Z.password;if(Z.auth==="password"){let pe=await zc(ne,Z.password,z,ee,K,"PASSWORD");if(pe.error!==void 0){Ee(pe.error);return}pe.value!==void 0&&(ie=pe.value)}c(pe=>({...pe||{},sshHosts:(Array.isArray(pe?.sshHosts)?pe.sshHosts:[]).map(Se=>Se?.name===he?{name:R,host:z,port:ee,username:K,auth:Z.auth,keyPath:Z.keyPath.trim(),passphrase:Z.passphrase,password:ie,agentForward:Z.agentForward,hostKeyAlias:String(Z.hostKeyAlias??"").trim(),persist:Z.persist===!0}:Se)})),Fe(pe=>{let Se={...pe};return delete Se[R],he!==R&&delete Se[he],Se}),_e(null),Ce(null),be({running:!1,ok:!1,text:""}),g({kind:"ok",text:w("msg.hostEdited",{name:R})})},Gh=R=>{he===R&&Vo(),Fe(z=>{let K={...z};return delete K[R],K}),c(z=>({...z||{},sshHosts:(Array.isArray(z?.sshHosts)?z.sshHosts:[]).filter(K=>K?.name!==R)}))},Vh=async R=>{let z=R?.name??"";if(z==="")return;let K={host:R?.host??"",port:Number(R?.port)||22,username:R?.username??"",auth:R?.auth==="key"||R?.auth==="password"?R.auth:"agent",keyPath:R?.keyPath??"",passphrase:R?.passphrase??"",password:R?.password??"",agentForward:R?.agentForward===!0,hostKeyAlias:typeof R?.hostKeyAlias=="string"?R.hostKeyAlias:""};Fe(ie=>({...ie,[z]:{running:!0,text:w("msg.probing")}}));let ee=await So(K,!0);Fe(ie=>{let pe=ie[z]||{};if(ee.result){let Se=ee.result.auth?.ok===!0;return{...ie,[z]:{running:!1,ok:Se,text:Co(ee.result)}}}return{...ie,[z]:{running:!1,ok:!1,text:w("error.probeFailed",{detail:String(ee.error||w("error.unknown"))})}}})},Yh=async R=>{let z=(Array.isArray(p?.hostKeys)?p.hostKeys:[]).filter(K=>!(K?.host===R?.host&&Number(K?.port)===Number(R?.port)));c(K=>({...K||{},hostKeys:z}));try{let K=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:z})}),ee=await K.json().catch(()=>({}));!K.ok||!ee.ok?g({kind:"error",text:String(ee.error||w("error.hostKeyDeleteFailed"))}):g({kind:"ok",text:w("msg.hostKeyDeleted")})}catch(K){g({kind:"error",text:String(K&&K.message?K.message:K)})}},Xh=async()=>{g({kind:"",text:""});try{let z=await(await fetch("/api/dsh-tty/ssh-config",{cache:"no-store"})).json();if(!z.ok){g({kind:"error",text:String(z.error||w("error.sshConfigReadFailed"))});return}let K=Array.isArray(z.entries)?z.entries:[],ee=[...Array.isArray(p?.sshHosts)?p.sshHosts:[]],ie=new Set(ee.map(Be=>Be?.name)),pe=0,Se=0;for(let Be of K)if(!(Be===null||typeof Be!="object"||typeof Be.name!="string")){if(ie.has(Be.name)){Se+=1;continue}ie.add(Be.name),ee.push({name:Be.name,host:String(Be.host??Be.name),port:Number(Be.port)||22,username:String(Be.username??""),auth:Be.auth==="key"?"key":"agent",keyPath:String(Be.keyPath??""),passphrase:"",password:"",agentForward:!1,hostKeyAlias:typeof Be.hostKeyAlias=="string"?Be.hostKeyAlias:""}),pe+=1}c(Be=>({...Be||{},sshHosts:ee}));let me=Array.isArray(z.proxy)?z.proxy.filter(Be=>typeof Be=="string"):[],Ye=Number.isInteger(z.proxyCount)?z.proxyCount:me.length,ur=Array.isArray(z.proxyCommand)?z.proxyCommand.filter(Be=>typeof Be=="string"):[],et=Number.isInteger(z.proxyCommandCount)?z.proxyCommandCount:ur.length,Tr=Number.isInteger(z.skippedOther)?z.skippedOther:0,Jt=Number.isInteger(z.droppedOverflow)?z.droppedOverflow:0,bt=[];Ye>0&&bt.push(w("msg.proxySkipped",{count:Ye,names:me.slice(0,5).join(w("list.separator"))+(Ye>5?w("meta.etc"):"")})),et>0&&bt.push(w("msg.proxyCommandSkipped",{count:et,names:ur.slice(0,5).join(w("list.separator"))+(et>5?w("meta.etc"):"")})),Tr>0&&bt.push(w("msg.skippedNotConcrete",{count:Tr})),Jt>0&&bt.push(w("msg.importOverflow",{count:Jt}));let ra=bt.length>0?w("list.separatorFull")+bt.join(w("list.separatorFull")):"";if(pe===0){let Be=Se>0?w("msg.noNewEntries",{count:Se}):w("msg.noImportableHosts");g({kind:bt.length>0?"error":"ok",text:Be+ra})}else g({kind:bt.length>0?"error":"ok",text:w("msg.importedHosts",{added:pe,skipped:Se})+ra})}catch(R){g({kind:"error",text:String(R&&R.message?R.message:R)})}},Yo=R=>R===null||typeof R!="object"?[]:Array.isArray(R.fingerprints)?R.fingerprints.filter(z=>typeof z=="string"&&z!==""):typeof R.fingerprint=="string"&&R.fingerprint!==""?[R.fingerprint]:[],Jh=async()=>{g({kind:"",text:""});try{let z=await(await fetch("/api/dsh-tty/known-hosts",{cache:"no-store"})).json();if(!z.ok){g({kind:"error",text:String(z.error||w("error.knownHostsReadFailed"))});return}let K=Array.isArray(z.entries)?z.entries:[],ee=[...Array.isArray(p?.hostKeys)?p.hostKeys:[]],ie=new Map;for(let me of ee)me===null||typeof me!="object"||ie.set(String(me.host??"")+":"+String(me.port??22),{record:me,fps:new Set(Yo(me))});let pe=0,Se=0;for(let me of K){if(me===null||typeof me!="object"||typeof me.host!="string")continue;let Ye=Array.isArray(me.fingerprints)?me.fingerprints.filter(Jt=>typeof Jt=="string"&&Jt!==""):[];if(typeof me.fingerprint=="string"&&me.fingerprint!==""&&Ye.push(me.fingerprint),Ye.length===0)continue;let ur=me.host+":"+String(me.port??22),et=ie.get(ur);if(et!==void 0){let Jt=!1;for(let bt of Ye)et.fps.has(bt)||et.fps.size>=8||(et.fps.add(bt),Jt=!0);if(!Jt){Se+=1;continue}delete et.record.fingerprint,et.record.fingerprints=[...et.fps],pe+=1;continue}let Tr={host:me.host,port:Number(me.port)||22,fingerprints:[...new Set(Ye)].slice(0,8)};ie.set(ur,{record:Tr,fps:new Set(Tr.fingerprints)}),ee.push(Tr),pe+=1}if(pe===0){g({kind:"ok",text:Se>0?w("msg.noNewFingerprints",{count:Se}):w("msg.noImportableKnownHosts")});return}c(me=>({...me||{},hostKeys:ee}));try{let me=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:ee})}),Ye=await me.json().catch(()=>({}));if(!me.ok||!Ye.ok){g({kind:"error",text:String(Ye.error||w("error.saveHostKeysFailed"))});return}g({kind:"ok",text:w("msg.importedFingerprints",{added:pe,skipped:Se})+(z.truncated===!0?w("hint.knownHostsTruncated"):"")})}catch(me){g({kind:"error",text:String(me&&me.message?me.message:me)})}}catch(R){g({kind:"error",text:String(R&&R.message?R.message:R)})}},Xo=async R=>{let z=R??B.current??p;v(!0),g({kind:"",text:""});let K=J(z);try{let ee=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(K)}),ie=await ee.json();!ee.ok||!ie.ok?g({kind:"error",text:String(ie.error||w("error.saveFailed"))}):(g({kind:"ok",text:w("msg.saved")}),M.current=JSON.stringify(K),ie.config&&(B.current=ie.config,c(ie.config),Ps(ie.config)))}catch(ee){g({kind:"error",text:String(ee&&ee.message?ee.message:ee)})}v(!1)},tn=R=>"/api/dsh-tty/elevate"+R,Jo=async()=>{try{let z=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json(),K=z&&typeof z.config=="object"&&z.config!==null?z.config:null;if(K===null)return;c(ee=>{if(ee===null)return ee;let ie={...ee,allowProxyCommandGranted:K.allowProxyCommandGranted===!0,allowProxyCommandGrantSource:K.allowProxyCommandGrantSource??null,allowProxyCommandGrantedAt:Number.isFinite(K.allowProxyCommandGrantedAt)?K.allowProxyCommandGrantedAt:null};return B.current=ie,ie})}catch{}},Zo=async()=>{b(null),F(!1);let R=B.current||{},z=M.current!==null&&JSON.stringify(J(R))===M.current,K={...R,allowProxyCommand:!0};B.current=K,c(K),await Jo(),z?(await Xo(K),P(w("elev.granted"))):P(w("elev.grantedNeedSave"))},Qo=async()=>{F(!1),P(""),b({phase:"loading"});try{let R=await fetch(tn(""),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:xi})}),z=await R.json().catch(()=>({}));if(!R.ok){b({phase:"error",error:String(z.error||R.status)});return}if(z.status==="granted"){await Zo();return}b({phase:"pending",command:String(z.command??""),expiresAt:Number(z.expiresAt)||0})}catch(R){b({phase:"error",error:String(R&&R.message?R.message:R)})}},Zh=async()=>{P("");try{let R=await fetch(tn("/revoke"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:xi})}),z=await R.json().catch(()=>({}));if(!R.ok){P(w("elev.error")+String(z.error||R.status));return}await Jo(),P(w("elev.revoked"))}catch(R){P(w("elev.error")+String(R&&R.message?R.message:R))}},Qh=async()=>{let R=x===null?"":String(x.command??"");if(R!==""){if(zo())try{await navigator.clipboard.writeText(R),F(!0);return}catch{}F(!1),P(w("elev.copyManual"))}};r.useEffect(()=>{if(x===null||x.phase!=="pending")return;let R=setInterval(()=>V(Date.now()),1e3),z=setInterval(()=>{fetch(tn("/status"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:xi})}).then(K=>K.json()).then(K=>{K.status==="granted"&&Zo()}).catch(()=>{})},1500);return()=>{clearInterval(R),clearInterval(z)}},[x]);let ed=()=>{if(p.allowProxyCommandGrantSource==="env")return s("span",{className:"tt_cardHint",children:w("elev.viaEnv")});let R=p.allowProxyCommandGrantedAt;return o("span",{className:"tt_capState",children:[Number.isFinite(R)?s("span",{children:w("elev.grantedAt",{time:dm(R)})}):null,s("button",{type:"button",className:"tt_toolBtn tt_capRevoke",onClick:()=>{Zh()},children:w("elev.revoke")})]})},td=()=>{let R=String(x.command??""),z=x.expiresAt>0?Math.max(0,Math.ceil((x.expiresAt-A)/1e3)):0,K=x.phase==="pending"&&x.expiresAt>0&&z===0,ee=()=>{b(null),F(!1)};return o("div",{className:"tt_elevPanel",children:[o("div",{className:"tt_elevHead",children:[s("span",{className:"tt_cardLabel",children:w("elev.title")}),s("button",{type:"button",className:"tt_toolBtn",onClick:ee,children:w("elev.close")})]}),s("span",{className:"tt_cardHint",children:w("elev.lockedWhy")}),x.phase==="error"?s("span",{className:"tt_cardHint tt_sshProbeWarn",children:w("elev.error")+String(x.error??"")}):null,x.phase==="loading"?s("span",{className:"tt_cardHint",children:w("elev.loading")}):null,R===""?null:o("div",{className:"tt_elevSteps",children:[s("span",{className:"tt_cardHint",children:w("elev.step")}),s("div",{className:"tt_elevCommand",children:s("code",{children:R})}),o("div",{className:"tt_elevActions",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Qh()},children:w(O?"elev.copied":"elev.copy")}),K?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Qo()},children:w("elev.regenerate")}):s("span",{className:"tt_cardHint",children:w("elev.expiresIn",{sec:z})})]}),s("span",{className:"tt_cardHint",children:w(K?"elev.expired":"elev.waiting")})]}),p.allowProxyCommand===!0&&p.allowProxyCommandGranted!==!0?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{j("allowProxyCommand",!1),ee()},children:w("elev.disableFirst")}):null,s("span",{className:"tt_cardHint",children:w("elev.otherWay")}),s("span",{className:"tt_cardHint",children:w("elev.envHow",{env:xi})})]})},rd=()=>{let R=p.allowProxyCommandGranted===!0,z=p.allowProxyCommand===!0;return o("div",{className:"tt_capBlock",children:[o("label",{className:"tt_cardField tt_cardRow tt_cardToggle tt_cardDanger",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:z,onChange:K=>{if(!R){Qo();return}j("allowProxyCommand",K.target.checked)}}),s("span",{className:"tt_cardLabel",children:w("check.allowProxyCommand")}),z&&!R?s("span",{className:"tt_badgeWarn",children:w("badge.notEffective")}):null]}),s("span",{className:"tt_cardHint",children:w("hint.allowProxyCommand")}),R?ed():s("span",{className:"tt_cardHint tt_sshProbeWarn",children:w("hint.proxyCommandNotGranted")}),E===""?null:s("span",{className:"tt_cardHint",children:E}),x===null?null:td()]})},rn=()=>{re.current!==null&&(clearTimeout(re.current),re.current=null),oe("")},sn=async R=>{let z=$r(R);if(Zr()===null){ce(!1),Le(!1),ge({text:w(Ot===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),kind:"muted"});return}if(z===""){Le(!1),ge({text:"",kind:""});return}let K=await Wc(z);if(K.unreported===!0){Le(!1),ge({text:w("status.credUnreported",{ref:z}),kind:"plain"});return}if(K.error!==void 0){Le(!1),ge({text:w("error.credStatusFailed",{error:K.error}),kind:"error"});return}let ee=K.view;ge({text:ee.configured?w("status.credStored",{ref:z,source:ee.source!==""?w("meta.credSource",{source:ee.source}):""}):w("status.credUnknown",{ref:z}),kind:ee.configured?"ok":"plain"}),Le(ee.configured===!0&&ee.writable===!0)},sd=async()=>{let R=$r(Z?.password??"");if(R==="")return;let z=await Uc(R);if(z.error!==void 0){ge({text:z.error,kind:"error"});return}Ce(K=>({...K||{},password:""})),ge({text:"",kind:""}),Le(!1)},id=(R,z)=>{let K=String(Z?.[R]??"");if(K===""||K.startsWith("env:")||se===z){rn(),Ce(ee=>({...ee||{},[R]:"env:"+z})),de(""),R==="password"&&sn("env:"+z);return}oe(z),re.current!==null&&clearTimeout(re.current),re.current=setTimeout(()=>{re.current=null,oe("")},4e3)},ea=(R,z)=>{if(Oe===null)return null;if(Oe.length===0)return s("span",{className:"tt_cardHint",children:z});let K=te===R,ee=ve.trim().toUpperCase(),ie=ee===""?Oe:Oe.filter(pe=>pe.toUpperCase().includes(ee));return o("div",{className:"tt_credPicker",children:[s("input",{className:"tt_cardInput",value:K?ve:"",placeholder:w("placeholder.credRef"),title:w("hint.credRefCandidates"),autoComplete:"off",spellCheck:!1,onFocus:()=>{de(R),Q("")},onBlur:pe=>{pe.currentTarget.parentElement.contains(pe.relatedTarget)||de("")},onChange:pe=>{Q(pe.target.value),de(R)}}),...K?[s("div",{className:"tt_envList",children:[...ie.length===0?[s("span",{className:"tt_envMore",children:w("list.noCredRef")})]:ie.slice(0,30).map(pe=>s("button",{type:"button",className:"tt_envItem","data-danger":se===pe?"":void 0,onMouseDown:Se=>Se.preventDefault(),onClick:()=>id(R,pe),children:se===pe?w("list.credOverwrite",{name:pe}):pe},pe)),...ie.length>30?[s("span",{className:"tt_envMore",children:w("list.moreMatches",{count:ie.length-30})})]:[]]},"cred-list-"+R)]:[]]})},nd=()=>{let z=$r(Z?.password??"")!=="",K=Zr()===null;return o("div",{className:"tt_sshRow tt_credRow",children:[z?s("button",{type:"button",className:"tt_toolBtn tt_credClear",disabled:we!==!0,onClick:()=>{sd()},children:w("btn.clearCredential")}):s("label",{className:"tt_credToggle",title:w("hint.rememberCredentialApply"),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:ne,disabled:K,onChange:ee=>ce(ee.target.checked)}),s("span",{children:w("check.rememberCredentialApply")})]}),le.text===""?null:s("span",{className:"tt_credStatus","data-kind":le.kind,children:le.text}),K&&le.text===""?s("span",{className:"tt_credStatus","data-kind":"muted",children:w("error.credPlainUnavailable")}):null]})},ta=()=>{let R=String(Z?.host??"").trim(),z=String(Z?.username??"").trim(),K=Number(Z?.port);if((!Number.isInteger(K)||K<1||K>65535)&&(K=22),R===""||z==="")return Ee(w("error.hostUserRequired")),null;let ee=Z?.auth,ie={host:R,port:K,username:z,auth:ee};if(ee==="key"){let Se=String(Z?.keyPath??"").trim();if(Se==="")return Ee(w("error.keyPathRequired")),null;ie.keyPath=Se,Z?.passphrase!==""&&(ie.passphrase=Z.passphrase)}if(ee==="password"){let Se=String(Z?.password??"");if(Se==="")return Ee(w("error.passwordRequired")),null;ie.password=Se}Z?.agentForward===!0&&(ie.agentForward=!0);let pe=String(Z?.hostKeyAlias??"").trim();return pe!==""&&(ie.hostKeyAlias=pe),ie},od=()=>{Ee("");let R=ta();R!==null&&(be({running:!0,ok:!1,text:w("msg.probing")}),So(R,!1).then(z=>{if(z.result){let K=z.result.auth?.ok===!0;be({running:!1,ok:K,text:Co(z.result)});return}be({running:!1,ok:!1,text:w("error.probeFailed",{detail:String(z.error||w("error.unknown"))})})}))},ad=()=>{Ee("");let R=ta();R!==null&&Qi(R)},ld=()=>{if(Z===null)return null;let R=(z,K,ee,ie,pe)=>o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:z}),s("input",{className:"tt_cardInput",type:ie??"text",value:Z[K]??"",placeholder:ee??"",autoComplete:"off",spellCheck:!1,onChange:Se=>{let me=Se.target.value;Ce(Ye=>({...Ye||{},[K]:me}))},...pe??{}})]});return o("div",{className:"tt_sshEdit",children:[s("div",{className:"tt_sshSection",children:w("section.connection")}),o("div",{className:"tt_sshGrid",children:[R(w("field.bookName"),"name",w("hint.bookNameConflict")),R(w("field.port"),"port","22")]}),R(w("field.host"),"host",w("placeholder.host")),R(w("field.username"),"username","root"),s("div",{className:"tt_sshSection",children:w("section.auth")}),o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.authMethod")}),o("select",{className:"tt_cardInput",value:Z.auth,onChange:z=>Ce(K=>({...K||{},auth:z.target.value})),children:[s("option",{value:"agent",children:w("option.authAgent")}),s("option",{value:"key",children:w("option.authKey")}),s("option",{value:"password",children:w("option.authPassword")})]})]}),...Z.auth==="key"?[R(w("field.keyPath"),"keyPath","~/.ssh/id_ed25519"),R(w("field.passphrase"),"passphrase","","password"),ea("passphrase",w("hint.noCredRefPassphrase"))]:[],...Z.auth==="password"?[R(w("field.password"),"password","","password",{onBlur:()=>{sn(Z.password)}}),nd(),ea("password",w("hint.noCredRefPasswordApply"))]:[],s("div",{className:"tt_sshSection",children:w("section.options")}),o("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:Z.agentForward===!0,onChange:z=>Ce(K=>({...K||{},agentForward:z.target.checked}))}),s("span",{className:"tt_cardLabel",children:w("check.agentForward")})]}),R(w("field.hostKeyAlias"),"hostKeyAlias",w("placeholder.hostKeyAlias")),s("span",{className:"tt_cardHint",children:w("hint.hostKeyAlias")}),ar==="tmux"?o("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:Z.persist===!0,onChange:z=>Ce(K=>({...K||{},persist:z.target.checked}))}),s("span",{className:"tt_cardLabel",children:w("check.persist")})]}):null,ye.text!==""?s("div",{className:"tt_sshProbeResult"+(!ye.running&&ye.ok?" tt_sshProbeOk":"")+(!ye.running&&!ye.ok?" tt_sshProbeBad":""),children:ye.text}):null,He!==""?s("span",{className:"tt_cardMessage tt_cardMessageError",children:He}):null,o("div",{className:"tt_sshActions",children:[o("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:Vo,children:w("btn.cancel")}),s("button",{type:"button",className:"tt_toolBtn",title:w("btn.browseTitle"),onClick:ad,children:w("btn.fileBrowse")}),s("button",{type:"button",className:"tt_toolBtn",disabled:ye.running,title:w("btn.probeTitle"),onClick:od,children:ye.running?w("msg.probing"):w("btn.probe")})]}),o("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_cardSave",onClick:()=>{Kh()},children:w("btn.apply")}),s("span",{className:"tt_cardHint",children:w("hint.appliedOnSave")})]})]})]})},cd=R=>{let z=typeof R?.assistProvider=="string"?R.assistProvider.trim():"",K=typeof R?.assistModel=="string"?R.assistModel.trim():"";return z!==""&&K!==""?z+"/"+K:z!==""?z:K},hd=()=>{if(T.loading)return s("span",{className:"tt_envMore",children:w("list.modelLoading")});if(T.failed)return s("span",{className:"tt_envMore",children:w("list.modelCatalogFailed")});let R=[],z=(p?.assistProvider??"")===""&&(p?.assistModel??"")==="";R.push(s("button",{type:"button",className:"tt_envItem",...z?{"data-active":""}:{},onMouseDown:K=>K.preventDefault(),onClick:()=>{c(K=>({...K||{},assistProvider:"",assistModel:""})),G(!1)},children:w("option.followHostModel")},"assist-route-default"));for(let K of T.groups){let ee=String(K.id??"");if(ee==="")continue;let ie=String(K.name??ee),pe=Array.isArray(K.models)?K.models:[];if(pe.length!==0){R.push(s("span",{className:"tt_envMore",children:ie},"group-"+ee));for(let Se of pe){let me=String(Se.id??"");if(me==="")continue;let Ye=String(Se.name??"")===""?me:String(Se.name),ur=(p?.assistProvider??"")===ee&&(p?.assistModel??"")===me;R.push(s("button",{type:"button",className:"tt_envItem",...ur?{"data-active":""}:{},title:ee+"/"+me,onMouseDown:et=>et.preventDefault(),onClick:()=>{c(et=>({...et||{},assistProvider:ee,assistModel:me})),G(!1)},children:Ye===me?me:Ye},ee+"/"+me))}}}return T.groups.length===0&&R.push(s("span",{className:"tt_envMore",children:w("list.noModelCandidate")},"assist-route-empty")),R},ns=(R,z,K,ee)=>o("label",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:R}),s("input",{className:"tt_cardInput",value:p[z]??"",placeholder:K??"",onChange:ie=>j(z,ie.target.value)}),ee?s("span",{className:"tt_cardHint",children:ee}):null]}),Lr=(R,z,K,ee)=>o("label",{className:"tt_cardField tt_cardRow tt_cardToggle"+(typeof K=="string"&&K!==""?" "+K:""),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:p[z]===!0,disabled:ee===!0&&p[z]!==!0,onChange:ie=>j(z,ie.target.checked)}),s("span",{className:"tt_cardLabel",children:R})]}),os=p?.platform==="win32";return l==="summary"?w("card.desc"):o(_?"div":"li",{className:_?"tt_pageHost":m?"tt_card tt_cardOpen":"tt_card",children:[_?null:o("button",{type:"button",className:"tt_cardHeader","aria-expanded":m,onClick:()=>y(R=>!R),children:[o("span",{className:"tt_cardHeadText",children:[s("span",{className:"tt_cardName",children:w("card.name")}),s("span",{className:"tt_cardDescription",children:w("card.descFull")})]}),s("span",{className:"dshkit_badge",children:"Kit"}),s("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:m?"tt_cardChevron tt_cardChevronOpen":"tt_cardChevron",children:s("path",{d:i,fill:"currentColor"})})]}),_||m?o("div",{className:"tt_cardBody",children:[p===null?s("div",{className:"tt_cardMessage",children:w("list.loadingConfig")}):o("div",{children:[H(w("section.basic")),Lr(w("check.enabled"),"enabled"),Lr(w("check.announce"),"announceToAgent"),os?o("div",{className:"tt_cardField",children:[o("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:!1,disabled:!0}),s("span",{className:"tt_cardLabel",children:w("check.shellIntegration")})]}),s("span",{className:"tt_cardHint",children:w("hint.shellIntegrationWindows")})]}):Lr(w("check.shellIntegrationWindows"),"shellIntegration"),H(w("section.sftp")),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("field.sftpStyle")}),o("select",{className:"tt_cardInput",value:p.sftpStyle==="dual"?"dual":"dialog",onChange:R=>j("sftpStyle",R.target.value),children:[s("option",{value:"dialog",children:w("option.sftpDialog")}),s("option",{value:"dual",children:w("option.sftpDual")})]}),s("span",{className:"tt_cardHint",children:w("hint.sftpDual")})]}),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("field.sftpLimits")}),o("div",{className:"tt_limitGrid",children:[o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.downloadLimit")}),s("input",{className:"tt_cardInput",type:"number",min:0,value:String(Number.isFinite(Number(p?.sftpLimits?.maxDownloadMb))?Number(p.sftpLimits.maxDownloadMb):1024),onChange:R=>ae("maxDownloadMb",Number(R.target.value)||0)})]}),o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.uploadLimit")}),s("input",{className:"tt_cardInput",type:"number",min:0,value:String(Number.isFinite(Number(p?.sftpLimits?.maxUploadMb))?Number(p.sftpLimits.maxUploadMb):2048),onChange:R=>ae("maxUploadMb",Number(R.target.value)||0)})]}),o("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:w("field.uploadCountLimit")}),s("input",{className:"tt_cardInput",type:"number",min:0,value:String(Number.isFinite(Number(p?.sftpLimits?.maxUploadFiles))?Number(p.sftpLimits.maxUploadFiles):1e3),onChange:R=>ae("maxUploadFiles",Number(R.target.value)||0)})]})]}),s("span",{className:"tt_cardHint",children:w("hint.sftpLimits")})]}),H(w("section.session")),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("field.persistence")}),o("select",{className:"tt_cardInput",value:p.persistence==="tmux"?"tmux":"off",onChange:R=>j("persistence",R.target.value),children:[s("option",{value:"off",children:w("option.persistOff")}),s("option",{value:"tmux",children:w("option.persistTmux")})]}),s("span",{className:"tt_cardHint",children:w("hint.persistence")+(os?w("hint.persistenceWindows"):"")}),Lr(w("check.endOnPageClose"),"endOnPageClose"),Lr(w("check.statsEnabled"),"statsEnabled"),s("span",{className:"tt_cardHint",children:w("hint.statsEnabled")}),rd()]}),H(w("section.assist")),Lr(w("check.assistEnabled"),"assistEnabled"),s("span",{className:"tt_cardHint",children:w("hint.assistEnabled")}),o("div",{className:"tt_cardField",onBlur:R=>{R.currentTarget.contains(R.relatedTarget)||G(!1)},children:[s("span",{className:"tt_cardLabel",children:w("field.assistRoute")}),s("input",{className:"tt_cardInput tt_routeInput",ref:$,readOnly:!0,value:cd(p),autoComplete:"off",spellCheck:!1,onFocus:()=>{G(!0),T.groups.length===0&&!T.loading&&q()},onClick:()=>{G(!0),T.groups.length===0&&!T.loading&&q()},onKeyDown:R=>{R.key==="Escape"&&G(!1)}}),...N?[s("div",{className:"tt_envList tt_routeList",children:hd()},"assist-route-list")]:[],s("span",{className:"tt_cardHint",children:w("hint.assistRoute")})]},"assist-route-field"),ns(w("field.maxSessions"),"maxSessions","4",w("hint.maxSessions")),o("div",{className:"tt_cardField",onBlur:R=>{R.currentTarget.contains(R.relatedTarget)||L(!1)},children:[s("span",{className:"tt_cardLabel",children:w(os?"field.shellWindows":"field.shell")}),s("input",{className:"tt_cardInput",value:p.shell??"",placeholder:w(os?"placeholder.shellWindows":"placeholder.shell"),autoComplete:"off",spellCheck:!1,onFocus:()=>L(!0),onClick:()=>L(!0),onKeyDown:R=>{R.key==="Escape"&&L(!1)},onChange:R=>{j("shell",R.target.value),L(!0)}}),...C?[s("div",{className:"tt_envList tt_shellList",children:(()=>{let R=(p.shell??"").trim().toLowerCase(),z=R===""?U:U.filter(K=>K.toLowerCase().includes(R));return z.length===0?s("span",{className:"tt_envMore",children:w("list.noShellCandidate")}):z.map(K=>s("button",{type:"button",className:"tt_envItem",onMouseDown:ee=>ee.preventDefault(),onClick:()=>{j("shell",K),L(!1)},children:K},K))})()},"shell-list")]:[],s("span",{className:"tt_cardHint",children:w(os?"hint.shellCandidatesWindows":"hint.shellCandidates")})]},"shell-field"),ns("TERM","term","xterm-256color",w("hint.term")),ns("COLORTERM","colorTerm","truecolor",""),ns(w("field.cwd"),"cwd","",w("placeholder.cwd")),ns(w("field.grace"),"reconnectGraceSec","120",w("hint.grace")),H(w("section.ssh")),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("panel.sshBook")}),...Array.isArray(p.sshHosts)&&p.sshHosts.length>0?[s("div",{className:"tt_hostList","data-editing":he!==null?"":void 0,children:p.sshHosts.map(R=>o("div",{children:[o("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:R?.name??""}),s("span",{className:"tt_sshHostTarget",children:yo(R??{})})]}),s("button",{type:"button",className:"tt_toolBtn",disabled:xe[R?.name]?.running===!0,onClick:()=>{Vh(R)},title:w("btn.probeRowTitle"),children:xe[R?.name]?.running===!0?w("msg.testing"):w("btn.test")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>qh(R),children:w("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn tt_btnDanger",onClick:()=>Gh(R?.name),children:w("btn.delete")})]}),xe[R?.name]&&xe[R?.name].text?s("div",{className:"tt_sshProbeResult"+(xe[R?.name].ok?" tt_sshProbeOk":" tt_sshProbeBad"),children:xe[R?.name].text}):null,he===R?.name?ld():null]},String(R?.name??"")))})]:[s("span",{className:"tt_cardHint",children:w("list.emptySshHosts")})],o("div",{className:"tt_cardRow",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Xh()},children:w("btn.importSshConfig")}),s("span",{className:"tt_cardHint",children:w("hint.importSshConfig")})]}),s("span",{className:"tt_cardHint",children:w("hint.sshBook")})]}),o("div",{className:"tt_cardField",children:[o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("panel.tunnels")}),...Array.isArray(p.tunnels)&&p.tunnels.length>0?[s("div",{children:p.tunnels.map(R=>{let z=tt.find(ie=>ie.name===R?.name),K=z?.state??"stopped",ee=Et!==null&&String(R?.name??"")===Et;return o("div",{className:"tt_sshHostRow","data-editing":ee?"":void 0,children:[s("span",{className:"tt_tunnelDot","data-state":K,title:K}),s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:(R?.name??"")+" \xB7 "+Hh(R??{})}),s("span",{className:"tt_sshHostTarget",children:(R?.bookName??"")+(z?.error?" \xB7 "+z.error:"")+(z?.lastForwardError?" \xB7 "+z.lastForwardError:"")})]}),s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:R?.enabled!==!1,title:w("check.tunnelEnabled"),onChange:ie=>$h(R?.name,ie.target.checked)}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Fh(R),children:w("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn tt_btnDanger",onClick:()=>jh(R?.name),children:w("btn.delete")})]},String(R?.name??""))})})]:[s("span",{className:"tt_cardHint",children:w("list.emptyTunnels")})],o("div",{className:"tt_sshEdit",children:[o("div",{className:"tt_cardRow tt_tunnelHead",children:[o("div",{className:"tt_segmented",role:"group","aria-label":w("field.direction"),children:[s("button",{type:"button",className:"tt_segmentedBtn","data-active":it.direction!=="remote"?"":void 0,title:w("option.localForwardTitle"),onClick:()=>jo("direction","local"),children:w("option.localForward")}),s("button",{type:"button",className:"tt_segmentedBtn","data-active":it.direction==="remote"?"":void 0,title:w("option.remoteForwardTitle"),onClick:()=>jo("direction","remote"),children:w("option.remoteForward")})]}),o("select",{className:"tt_cardInput",value:it.bookName,onChange:dr("bookName"),children:[s("option",{value:"",children:w("option.selectBook")}),...Array.isArray(p?.sshHosts)?p.sshHosts.map(R=>s("option",{value:R?.name??"",children:R?.name??""})):[]]})]}),s("span",{className:"tt_cardHint",children:$o!==void 0?w("hint.tunnelViaBook",{book:yo($o)}):w("hint.tunnelBookEmpty")}),it.direction==="local"?o("div",{className:"tt_tunnelEndpoints",children:[o("div",{className:"tt_tunnelHop",children:[o("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:w("hint.localListenFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.localPort"),value:it.localPort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.localListenPort"),onChange:dr("localPort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"local",title:w("hint.flowLocalToRemote"),"aria-hidden":"true",children:"\u2192"})]}),o("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:w("placeholder.remoteHost"),title:w("hint.remoteHostTitle"),value:it.remoteHost,autoComplete:"off","aria-label":w("field.remoteHost"),onChange:dr("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.port"),value:it.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.remotePort"),onChange:dr("remotePort")})]})]}):o("div",{className:"tt_tunnelEndpoints",children:[o("div",{className:"tt_tunnelHop",children:[o("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:w("placeholder.remoteListenHost"),title:w("hint.remoteListenHost"),value:it.remoteHost,autoComplete:"off","aria-label":w("field.remoteListenHost"),onChange:dr("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.listenPort"),value:it.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.remoteListenPort"),onChange:dr("remotePort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"remote",title:w("hint.flowRemoteToLocal"),"aria-hidden":"true",children:"\u2192"})]}),o("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:w("hint.localDialFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:w("placeholder.localTargetPort"),value:it.localTargetPort,autoComplete:"off",inputMode:"numeric","aria-label":w("field.localTargetPort"),onChange:dr("localTargetPort")})]})]}),s("div",{className:"tt_tunnelEndpoints",children:[s("span",{className:"tt_tunnelEndLabel",children:it.direction==="local"?w("hint.tunnelLocalSummary"):w("hint.tunnelRemoteSummary")})]}),s("div",{className:"tt_cardRow tt_tunnelActions",children:[Et===null?s("button",{type:"button",className:"tt_cardSave",onClick:Uh,children:w("btn.addTunnel")}):s("button",{type:"button",className:"tt_cardSave",onClick:zh,children:w("btn.saveEdit")}),Et===null?null:s("button",{type:"button",className:"tt_toolBtn",onClick:Wh,children:w("btn.cancel")}),s("span",{className:"tt_cardHint",children:Et===null?w("hint.tunnelAdd"):w("hint.tunnelEditing",{name:Et})})]})]})]}),o("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:w("panel.hostKeys")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{Jh()},children:w("btn.importKnownHosts")})]}),...Array.isArray(p.hostKeys)&&p.hostKeys.length>0?[s("div",{className:"tt_hostList",children:p.hostKeys.map((R,z)=>o("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:String(R?.host??"")+":"+String(R?.port??22)}),s("span",{className:"tt_sshHostTarget",children:Yo(R).map(K=>"sha256:"+K).join(" / ")})]}),s("button",{type:"button",className:"tt_toolBtn tt_btnDanger",onClick:()=>{Yh(R)},children:w("btn.delete")})]},String(R?.host??"")+":"+String(R?.port??22)+"#"+String(z)))})]:[s("span",{className:"tt_cardHint",children:w("list.emptyHostKeys")})],s("span",{className:"tt_cardHint",children:w("hint.hostKeys")})]}),o("div",{className:"tt_cardField tt_cardRow",children:[s("button",{className:"tt_cardSave",disabled:f,onClick:()=>{Xo()},children:w(f?"msg.saving":"btn.save")}),s("span",{className:"tt_cardMessage"+(S.kind==="ok"?" tt_cardMessageOk":S.kind==="error"?" tt_cardMessageError":S.kind==="warn"?" tt_cardMessageWarn":""),children:S.text})]})]})]}):null]})}t.inject=["slots","sessions"];let a=["@hyzyn/dsh-tty#tty","@hyzyn/dsh-all#tty"];return t.apply=d=>{Np(d),Qc=d.sessions,d.inject(["remote","remote.credentials"],S=>(Ot=S.remote?.credentials??S["remote.credentials"]??null,()=>{Ot=null}));let l=!1,_=()=>{};zi={set(S){if(S!==l){if(l=S,S){_=vm();return}_(),_=()=>{},Os(),br()}}},gh(!0),Uo();let m="@hyzyn/dsh-all",p=[...new Set(a.map(S=>S.split("#")[0]))].find(S=>S!==m),c=!1,u=[];p!==void 0&&d.slots.inject("plugins.bundle.config",()=>{for(c=!0;u.length>0;){let S=u.pop();typeof S=="function"&&S()}return d.slots.register({name:"plugins.bundle.config",key:p},n)});for(let S of a)d.slots.inject("plugins.row.config",()=>{let g=S.split("#")[0]===p;if(g&&c)return;let x=d.slots.register({name:"plugins.row.config",key:S},n);return g&&u.push(x),x});d.slots.inject("settings.kit.item",()=>d.slots.register({name:"settings.kit.item",id:"tty",order:80,label:()=>w("card.name")},n)),d.slots.inject("settings.plugin.item",()=>d.slots.register({name:"settings.plugin.item",key:"tty",order:100},n));let h=d.provide("ttyConnbar",{version:1,addAction:Xi,requestRender(){br()}}),f=d.provide("ttyTerminal",{version:3,open(S){if(!wr)return;let g=oh(S),x=ah(S,g),b=typeof S?.label=="string"&&S.label!==""?S.label:void 0;if(Is(),S?.reuse!==!1){let E=p_(x);if(E!==null)return To(),Yt(E.sid),E}return To(),Ds(x,b)},mount(S,g){return wr?S_(S,g):()=>{}}}),v=d.provide("ttyPanel",{version:2,isOpen(){return ue!==null&&!Ve},mountPane(S){return hh(S)},minimize(){return qi(),ue!==null&&Ve}});return()=>{zi=null,wr=!1,_(),v(),f(),h(),Os()}},t}});})();
|
|
3473
3488
|
/*! Bundled license information:
|
|
3474
3489
|
|
|
3475
3490
|
@xterm/addon-search/lib/addon-search.mjs:
|