@hyzyn/dsh-tty 0.22.0-rc.1 → 0.22.0
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 +68 -10
- package/README.md +57 -10
- package/client.js +16 -1
- package/lib/index.d.ts +144 -25
- package/lib/index.js +445 -64
- package/lib/index.js.map +1 -1
- package/lib/shell-integration.d.ts +11 -0
- package/lib/shell-integration.js +52 -1
- package/lib/shell-integration.js.map +1 -1
- package/package.json +2 -2
- package/scripts/integration.mjs +132 -1
- package/scripts/windows-smoke.mjs +100 -1
package/client.js
CHANGED
|
@@ -2006,6 +2006,10 @@ void main() {
|
|
|
2006
2006
|
/* \u6388\u6743\u9762\u677F\uFF1A\u4E00\u6BB5\u8BF4\u660E + \u4E00\u6761\u8981\u590D\u5236\u5230\u5BBF\u4E3B\u7EC8\u7AEF\u7684\u547D\u4EE4\u3002\u5DE6\u4FA7\u8272\u6761\u628A\u5B83\u4E0E\u666E\u901A\u8BBE\u7F6E\u9879\u533A\u5206\u5F00 */
|
|
2007
2007
|
.tt_elevPanel {
|
|
2008
2008
|
display: grid;
|
|
2009
|
+
/* \u5355\u5217\u4E14\u5141\u8BB8\u538B\u5230\u6BD4\u5185\u5BB9\u7A84\uFF1A\u547D\u4EE4\u4E32\u662F\u9762\u677F\u91CC\u6700\u5BBD\u7684\u4E1C\u897F\uFF0Cauto \u8F68\u9053\u4F1A\u6309 max-content \u6491\u5F00\uFF0C
|
|
2010
|
+
\u7A84\u680F\uFF08Windows 125%~150% \u7F29\u653E\uFF09\u4E0B\u6574\u5757\u9762\u677F\u4F1A\u9876\u51FA\u5361\u7247\u53F3\u8FB9\u754C */
|
|
2011
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2012
|
+
min-width: 0;
|
|
2009
2013
|
gap: var(--tt-gap-sm);
|
|
2010
2014
|
padding: 10px 12px;
|
|
2011
2015
|
border: 1px solid color-mix(in srgb, var(--tt-accent) 34%, transparent);
|
|
@@ -2021,6 +2025,8 @@ void main() {
|
|
|
2021
2025
|
}
|
|
2022
2026
|
.tt_elevSteps {
|
|
2023
2027
|
display: grid;
|
|
2028
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2029
|
+
min-width: 0;
|
|
2024
2030
|
gap: var(--tt-gap-sm);
|
|
2025
2031
|
}
|
|
2026
2032
|
.tt_elevCommand {
|
|
@@ -2028,6 +2034,15 @@ void main() {
|
|
|
2028
2034
|
align-items: center;
|
|
2029
2035
|
gap: var(--tt-gap-sm);
|
|
2030
2036
|
flex-wrap: wrap;
|
|
2037
|
+
min-width: 0;
|
|
2038
|
+
}
|
|
2039
|
+
/* \u547D\u4EE4\u7684\u52A8\u4F5C\u884C\uFF1A\u590D\u5236 / \uFF08\u8FC7\u671F\u65F6\uFF09\u91CD\u65B0\u751F\u6210 / \u5012\u8BA1\u65F6\u5E76\u6392\uFF0C\u7D27\u8D34\u547D\u4EE4\uFF0C\u4E0D\u4E0E\u8BF4\u660E\u6587\u5B57\u6DF7\u6392 */
|
|
2040
|
+
.tt_elevActions {
|
|
2041
|
+
display: flex;
|
|
2042
|
+
flex-wrap: wrap;
|
|
2043
|
+
align-items: center;
|
|
2044
|
+
gap: var(--tt-gap-sm);
|
|
2045
|
+
min-width: 0;
|
|
2031
2046
|
}
|
|
2032
2047
|
.tt_elevCommand code {
|
|
2033
2048
|
flex: 1 1 auto;
|
|
@@ -2808,7 +2823,7 @@ void main() {
|
|
|
2808
2823
|
}
|
|
2809
2824
|
}
|
|
2810
2825
|
`;function En(e){let t=typeof e=="string"?e.trim():"";if(t==="")return;let r=t,s="",a=r.lastIndexOf("@");a>0&&(s=r.slice(0,a).trim(),r=r.slice(a+1).trim());let i=r,n=22,o=/^\[([^\]]+)\](?::(\d+))?$/.exec(r)??/^([^:]+):(\d+)$/.exec(r);if(o!==null){i=o[1];let l=Number(o[2]);Number.isInteger(l)&&l>=1&&l<=65535&&(n=l)}if(i==="")return;let u={host:i,port:n};return s!==""&&(u.username=s),u}function Ln(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,a=typeof t.username=="string"&&t.username.trim()!==""?t.username.trim()+"@":"",i=r.includes(":")&&!r.startsWith("[")?`[${r}]`:r;return`${a}${i}${s===22?"":":"+String(s)}`}var Tn="\0global";function yr(e,t){return e===null?Tn:typeof e=="string"&&e!==""?e:typeof t=="string"&&t!==""?t:Tn}function Rn(e,t){return e===Tn?!0:typeof t=="string"&&t!==""&&e===t}var Tf="/api/dsh-tty/ws";function kl(e,t){let r=new URL(t??e,e);return(r.protocol==="https:"?"wss:":"ws:")+"//"+r.host+Tf}function Mn(e){return String(e??"").trim().toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_+|_+$/g,"")}function El(e,t,r,s){let a=Mn(r),i=Mn(e);if(a===""||i==="")return"";let n=Mn(t),o=["DSH_TTY",a,i];return n!==""&&n!=="22"&&o.push(n),o.push(s),o.join("_")}function Ji(e){let t=Number(e);return Number.isInteger(t)&&t>=1&&t<=65535?t:0}function Ll(e,t,r){return`${e}-${t==="remote"?"R":"L"}${String(r)}`}function Tl(e,t=[],r=s=>s){let s=e??{},a=String(s.bookName??"")||String(t[0]??"")||"";if(a==="")return{ok:!1,error:r("error.tunnelNoBook")};if(s.direction==="remote"){let u=Ji(s.remotePort),l=Ji(s.localTargetPort);return u<1||l<1?{ok:!1,error:r("error.tunnelRemotePortRequired")}:{ok:!0,tunnel:{name:Ll(a,"remote",u),bookName:a,direction:"remote",remotePort:u,localTargetHost:"",localTargetPort:l,enabled:!0}}}let i=Ji(s.localPort),n=String(s.remoteHost??"").trim(),o=Ji(s.remotePort);return i<1||n===""||o<1?{ok:!1,error:r("error.tunnelLocalRequired")}:{ok:!0,tunnel:{name:Ll(a,"local",i),bookName:a,direction:"local",localPort:i,remoteHost:n,remotePort:o,enabled:!0}}}function Rl(e,t){return(Array.isArray(e)?e:[]).find(r=>String(r?.name??"")===String(t))}function Rf(e,t,r){return(Array.isArray(e)?e:[]).find(s=>String(s?.name??"")!==String(t)&&String(s?.name??"")===String(r))}function Ml(e,t,r,s){let a=Array.isArray(e)?e:[],i=a.find(u=>String(u?.name??"")===String(t));if(i===void 0)return{ok:!1,reason:"missing",error:s("error.tunnelMissing",{name:String(t)})};if(Rf(a,t,r.name)!==void 0)return{ok:!1,reason:"clash",error:s("error.tunnelClash",{name:String(r.name)})};let o={...r,enabled:i.enabled!==!1};return{ok:!0,tunnels:a.map(u=>String(u?.name??"")===String(t)?o:u)}}function Mf(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 Af(e){let t=e?.current;return typeof t=="string"&&t!==""?t:Mf(e)}function Al(e){let t=Af(e);if(t===void 0)return;let r=e?.byId?.[t]?.cwd;return typeof r=="string"&&r!==""?r:void 0}function Dl(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 Pl(e,t){return typeof e!="string"||e===""?!0:e===t}function Bl(e,t){return e===null?!1:e!==t}function tt(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 Xr(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 Il(e){return Number.isFinite(e)?e>=90?"danger":e>=70?"warn":"":""}function Ol(e,t){return!Number.isFinite(e)||e<0?t("list.none"):e<1024?Math.round(e)+" B/s":Xr(e)||t("list.none")}function Df(e,t){if(!Number.isFinite(e)||e<0)return t("list.none");let r=Math.floor(e),s=Math.floor(r/604800),a=Math.floor(r%604800/86400),i=Math.floor(r%86400/3600),n=Math.floor(r%3600/60),o=[];return s>0&&o.push(s+"w"),(s>0||a>0)&&o.push(a+"d"),(s>0||a>0||i>0)&&o.push(i+"h"),(s>0||a>0||i>0||n>0)&&o.push(n+"m"),o.length>0?o.join(""):r+"s"}function Pf(e,t,r){return!Number.isFinite(e)||!Number.isFinite(t)||t<=0?r("list.none"):(tt(e)||"0 B")+"/"+(tt(t)||"0 B")}function Nl(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 Bf=["cpuPct","cores","memUsed","memTotal","memPct","diskUsed","diskTotal","diskPct","uptimeSec","tcpConns","rxRate","txRate","tempC"];function Hl(e){return e===null||typeof e!="object"||Array.isArray(e)?!1:Bf.some(t=>Nl(e,t)!==null)}var Of=8e3;function Fl(e,t=Date.now()){return t-(e||0)<=Of}var Wl=23;function An(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:Wl}]}function Ul(e,t){let r=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{},s=i=>Nl(r,i),a=(i,n,o,u=i.slot)=>({key:i.key,label:i.label,kind:i.kind,slot:u,pct:o??null,value:n,title:i.label+": "+n});return An(t).map(i=>{if(i.kind==="pct"){let o=s(i.key);return a(i,o===null?t("list.none"):Math.round(o)+"%",o)}if(i.kind==="pair")return a(i,Pf(s(i.used),s(i.total),t),null);if(i.kind==="uptime")return a(i,Df(s(i.key),t),null);if(i.kind==="temp"){let o=s(i.key);return a(i,o===null?t("list.none"):o.toFixed(1)+"\xB0C",null)}if(i.kind==="net"){let o=s("rxRate"),u=s("txRate");return o===null&&u===null?a(i,t("list.none"),null,0):a(i,"\u2193"+Ol(o,t)+" \u2191"+Ol(u,t),null,Wl)}let n=s(i.key);return a(i,n===null?t("list.none"):String(n),null)})}var Dn="tty",Nn={"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","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.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","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","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.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}","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.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"},If={"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)","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.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)","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","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.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}","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.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 Nf(e,t){return t===void 0?e:String(e).replace(/\{(\w+)\}/g,(r,s)=>t[s]===void 0?"":String(t[s]))}function Zl(e,t){return Nf(Nn[e]!==void 0?Nn[e]:e,t)}var S=Zl;function Hf(e){e.inject(["locale"],t=>{let r=t.locale.register(Dn,"zh",Nn),s=t.locale.register(Dn,"en",If);return S=t.locale.bind(Dn),()=>{s(),r(),S=Zl}})}function Ff(){return kl(document.baseURI,globalThis.__DSH_TRANSPORT__?.streamBaseUrl)}function Ar(){return Lt!==null&&typeof Lt.describe=="function"?Lt:null}function kr(e){let t=String(e??"").trim();return t.startsWith("env:")?t.slice(4).trim():""}function Wf(){let e=new Set;for(let t of Ht)for(let r of[t?.password,t?.passphrase]){let s=kr(r);s!==""&&e.add(s)}return[...e]}async function Uf(){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 Ql(){return[...new Set([...Wf(),...await Uf()])].sort()}async function ec(e){let t=Ar();if(t===null)return{error:S(Lt===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 jf(e,t){let r=Ar();if(r===null||typeof r.set!="function")return{error:S("error.credStoreUnavailable")};try{return await r.set(e,t),{value:"env:"+e}}catch(s){return{error:S("error.credStoreFailed",{error:s instanceof Error?s.message:String(s)})}}}async function tc(e){let t=Ar();if(t===null||typeof t.unset!="function")return{error:S("error.credClearUnavailable")};try{return await t.unset(e),{}}catch(r){return{error:S("error.credClearFailed",{error:r instanceof Error?r.message:String(r)})}}}async function rc(e,t,r,s,a,i){if(e!==!0)return{};let n=String(t??"").trim();if(n===""||n.startsWith("env:"))return{};let o=El(r,s,a,i);return o===""?{error:S("error.credRefNeedsHost")}:jf(o,n)}function bs(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"t"+Date.now().toString(36)+Math.random().toString(36).slice(2,10)}var Xi;function mi(){document.getElementById("dsh-tty-style")||(Xi=document.createElement("style"),Xi.id="dsh-tty-style",Xi.textContent=xl+`
|
|
2811
|
-
`+Cl,document.head.appendChild(Xi))}var ws='<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>',zf='<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>',$f='<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>',qf='<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>',Kf='<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" fill="var(--dsw-alias-bg-base,#fff)"/></svg>',Gf='<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>',Vf='<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>',ic='<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>',Yf='<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>',Jf='<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>',ys='<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>',Xf='<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>',ci='<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>',sc='<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>',nc='<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>',Zn='<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>',oc='<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>',Zf='<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>',Qn='<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>',Er='<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>',eo='<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>',ac='<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>',lc='<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>',cc='<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>',Qf='<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>',ep='<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>',tp='<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>',rp='<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>',hc='<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>',ip='<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>',dc='<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>',uc=null,Ee=null,ce=null,os=null,hi=null,Lt=null,rr=null,or=null,kt=null,ei=null,ti=null,as=null,lt=null,ri=null,rt=null,ct=null,Je=null,Lr=null,di=!1,ii=null,qe=!1,Ve=null,ls=null,Dr=null,ar=null,cs=null,ir=null,si=1e3,hs="dsh-tty:tabs",ue=new Map,gi=new Set,to=()=>gi.size>0,Hn=new Set,Re=null,vi=0,Zi=!1,ht=null,Tr=null,Ht=[],ds=!0,_t=null,mt=null,ni=null,Qr=null,Fn=null,Wn=new Set;function Ss(e){return Wn.add(e),()=>Wn.delete(e)}Ss(({tab:e,addAction:t})=>{nr&&e.exited&&t(Gf,S("btn.reopen"),S("btn.reopenTitle"),()=>fs(e.sid))});Ss(({tab:e,addAction:t})=>{nr&&t(Vf,"SFTP",S("btn.sftpTitle"),()=>ks(e.spawnSpec,e.sid))});Ss(({bookName:e,addAction:t})=>{if(!nr)return;let r=e!==""?Ac(e):0;if(r>0){t(ic,S("btn.tunnels",{count:r}),S("btn.tunnelsTitle"),s=>xc(s.currentTarget,e));return}e!==""&&t(Yf,S("btn.more"),S("btn.moreTitle"),s=>Dp(s.currentTarget,e))});function bi(e,t){if(rr===null)return;rr.textContent=e.split("\u2014\u2014")[0],rr.title=e,or.dataset.state=t,os!==null&&(os.style.display=t==="connected"?"none":""),Dr!==null&&(Dr.textContent=e),ar!==null&&(ar.dataset.state=t);let r=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot");r!==null&&(r.dataset.state=t)}function Pn(e,t,r){let s=typeof e=="string"&&e!==""?e:null;if(s!==null){let a=ue.get(s);a!==void 0&&(a.statusText=t,a.statusState=r)}Pl(s,Re)&&(hi=s,bi(t,r))}function Qi(e,t){hi=null,bi(e,t)}function ro(){if(!Bl(hi,Re))return;let e=Re===null?void 0:ue.get(Re);hi=e===void 0?null:Re;let t=Dl(e,S);bi(t.text,t.state)}function Me(e){Ee!==null&&Ee.readyState===WebSocket.OPEN&&Ee.send(JSON.stringify(e))}function sp(){let e=[],t=document.createDocumentFragment();for(let r of An(S)){let s=document.createElement("span");s.className="tt_statsItem";let a=document.createElement("span");a.className="tt_statsLabel",a.textContent=r.label,s.appendChild(a);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 o=document.createElement("span");o.className="tt_statsValue",s.appendChild(o),t.appendChild(s),e.push({item:s,value:o,meter:i,fill:n,slot:null})}return _t!==null&&_t.appendChild(t),e}function np(e,t){let r=Ul(t!==void 0?t.stats:null,S);for(let s=0;s<e.length;s+=1){let a=e[s],i=r[s];if(i!==void 0&&(a.slot!==i.slot&&(a.slot=i.slot,a.value.style.minWidth=i.slot>0?i.slot+"ch":""),a.value.textContent!==i.value&&(a.value.textContent=i.value),a.item.getAttribute("title")!==i.title&&a.item.setAttribute("title",i.title),a.fill!==null&&a.meter!==null)){let n=i.pct===null?"0%":Math.max(0,Math.min(100,i.pct)).toFixed(1)+"%";a.fill.style.width!==n&&(a.fill.style.width=n);let o=Il(i.pct);a.meter.dataset.level!==o&&(a.meter.dataset.level=o)}}}function Cs(){Qr=null,Fn=null}function op(){if(ce===null||qe||!ds)return!1;let e=dt();return e===void 0||e.embedded===!0||e.exited===!0||e.stats===null||e.stats===void 0?!1:Fl(e.statsAt)}function jl(){if(qe)return;let e=dt();if(!(e===void 0||e.embedded===!0||e.fit===null)){try{e.fit.fit()}catch{return}try{e.spawned&&!e.exited&&Or(e)}catch{}}}function lr(){try{ap()}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{_t!==null&&(_t.hidden=!0,_t.textContent=""),Cs(),rt!==null&&delete rt.dataset.stats}catch{}}}function ap(){if(rt===null||_t===null)return;let e=op(),t=rt.dataset.stats!==void 0!==e;if(!e){t&&delete rt.dataset.stats,_t.hidden=!0,Qr!==null&&(_t.textContent="",Cs()),t&&jl();return}_t.hidden=!1,Qr===null&&(Qr=sp());let r=dt(),s=r===void 0?"":r.sid+":"+String(r.statsAt||0);s!==Fn&&(Fn=s,np(Qr,r)),t&&(rt.dataset.stats="",jl())}function fc(){ni===null&&(ni=setInterval(()=>lr(),1e3))}function pc(){ni!==null&&(clearInterval(ni),ni=null)}function _c(){if(ce===null||qe||!ds)return null;let e=dt();return e===void 0||e.embedded===!0||e.exited===!0?null:e.sid}function wi(){let e=_c();e!==mt&&(mt!==null&&Me({t:"statsOff",sid:mt}),mt=e,e!==null&&Me({t:"statsOn",sid:e}))}function lp(e){if(e!==_c()){wi();return}mt!==null&&mt!==e&&Me({t:"statsOff",sid:mt}),mt=e,Me({t:"statsOn",sid:e})}function dt(){return Re!==null?ue.get(Re):void 0}function Un(){try{return Al(uc?.list?.getSnapshot?.())}catch{return}}function cp(e){if(!(e.term===null||e.exited)){try{if(e.term.buffer.active.length<=e.term.rows)return}catch{return}e.term.reset(),Me({t:"refresh",sid:e.sid})}}var es=null;function mc(e){es!==null&&clearTimeout(es),es=setTimeout(()=>{es=null;let t=dt();t!==void 0&&cp(t)},e??200)}var hp=["password","passphrase"];function zl(e){if(e===null||typeof e!="object"||e.t!=="ssh")return e;let t=e.credsStripped===!0,r={...e};for(let s of hp){let a=r[s];typeof a=="string"&&a!==""&&!a.startsWith("env:")&&(delete r[s],t=!0)}return t&&(r.credsStripped=!0),r}var gc=1;function Xt(){try{let e=[...ue.values()].filter(t=>!t.exited&&t.embedded!==!0).map(t=>({sid:t.sid,spawnSpec:zl(t.spawnSpec),label:t.label}));e.length===0||ce===null?sessionStorage.removeItem(hs):sessionStorage.setItem(hs,JSON.stringify({v:gc,tabs:e})),dp([...ue.values()].filter(t=>t.embedded!==!0).map(t=>({spawnSpec:zl(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 jn="dsh-tty:persist-specs";function dp(e){try{let t=e.filter(r=>yi(r.spawnSpec)).map(r=>({spawnSpec:r.spawnSpec,label:r.label}));t.length===0?localStorage.removeItem(jn):localStorage.setItem(jn,JSON.stringify(t))}catch{}}function up(){try{let e=localStorage.getItem(jn);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>r!==null&&typeof r=="object"&&yi(r.spawnSpec)):[]}catch{return[]}}function fp(){try{let e=sessionStorage.getItem(hs);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===gc&&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 us(e,t){let r=Ee;return new Promise(s=>{let a=null,i=n=>{let o;try{o=JSON.parse(n.data)}catch{return}o.t===e&&(a!==null&&clearTimeout(a),r.removeEventListener("message",i),s(r===Ee?o:null))};a=setTimeout(()=>{r.removeEventListener("message",i),s(null)},t),r.addEventListener("message",i)})}function Or(e){if(e===void 0||e.fit===void 0)return;let t=e.fit.proposeDimensions();t!==void 0&&Me({t:"resize",sid:e.sid,cols:t.cols,rows:t.rows})}function pp(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||Or(e)}function Sr(e,t,r,s){if(e.overlayEl===null||e.overlayEl===void 0)return;let a=e.overlayEl;if(t===""||t===void 0){a.textContent="";return}let i=s==="error"||s==="info"?s:"exited";a.innerHTML='<div class="tt_overlayCard" data-kind="'+i+'"><span class="tt_overlayIcon">'+(i==="error"?hc:i==="info"?eo:ip)+'</span><span class="tt_overlayText"><span class="tt_overlayMain"></span>'+(r===void 0||r===""?"":'<span class="tt_overlayHint"></span>')+"</span></div>",a.querySelector(".tt_overlayMain").textContent=t,r!==void 0&&r!==""&&(a.querySelector(".tt_overlayHint").textContent=r)}function _p(e,t){try{let r=getComputedStyle(document.documentElement).getPropertyValue(e).trim();return r!==""?r:t}catch{return t}}function Ir(e){let t=_p("--dsw-alias-state-business-primary","#7c9cff"),r=new Jl.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:{background:"#0b0e14",foreground:"#d7dce5",cursor:t,cursorAccent:"#0b0e14",selectionBackground:"rgba(124, 156, 255, .30)",black:"#1b2028",red:"#f07178",green:"#7ec699",yellow:"#e6b673",blue:"#7aa2f7",magenta:"#c792ea",cyan:"#7fdbca",white:"#c8d0dc",brightBlack:"#556070",brightRed:"#ff8b92",brightGreen:"#9fe0b4",brightYellow:"#f5cc8c",brightBlue:"#9ab8ff",brightMagenta:"#dbb3ff",brightCyan:"#a3f0e2",brightWhite:"#eef2f8"}}),s=new Xl.FitAddon,a=new Qo;r.loadAddon(s),r.loadAddon(a),r.loadAddon(new ea);let i=document.createElement("div");i.className="tt_term";let n=document.createElement("div");n.className="tt_overlay",n.addEventListener("click",()=>{n.textContent="",fs(e.sid)}),n.setAttribute("role","button"),n.setAttribute("aria-label",S("btn.reopenSession")),n.tabIndex=0,n.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" "||o.key==="Spacebar")&&(o.preventDefault(),n.textContent="",fs(e.sid))}),i.appendChild(n),r.open(i);try{s.fit()}catch{}try{let o=new Sl;o.onContextLoss(()=>{try{o.dispose()}catch{}}),r.loadAddon(o)}catch{}r.onData(o=>{Me({t:"input",sid:e.sid,d:o})}),r.onResize(()=>{yi(e.spawnSpec)&&mc(200)}),r.attachCustomKeyEventHandler(o=>e.embedded===!0?!0:(o.ctrlKey||o.metaKey)&&o.key.toLowerCase()==="f"?(o.preventDefault(),Uc(),!1):!0),e.term=r,e.fit=s,e.search=a,e.termEl=i,e.overlayEl=n}function $l(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 mp(e){let t=$l(e);if(t==="")return null;for(let r of ue.values())if(r.exited!==!0&&r.embedded!==!0&&$l(r.spawnSpec)===t)return r;return null}function ui(e,t){let r=bs(),s={sid:r,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e??Gp(),label:t};return Ir(s),ue.set(r,s),vi+=1,it(),Zt(r),xs(s),Xt(),s}function gp(e){if(Array.isArray(e))for(let t of e){if(t===null||typeof t!="object"||t.owner!=="agent")continue;let r=typeof t.sid=="string"?t.sid:"";if(r===""||ue.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:Un()},label:"agent"+(t.kind==="ssh"&&typeof t.target=="string"&&t.target!==""?" \xB7 "+t.target:"")};Ir(s),ue.set(r,s),vi+=1,it(),vp()&&s.termEl!==null&&rt!==null&&Re===null&&Zt(r),Me({t:"attach",sid:r}),bp()}}function vp(){return ce!==null&&qe!==!0}function bp(){try{Xt()}catch{}}function wp(e){if(gp(e),!Array.isArray(e))return;let t=new Set(e.filter(r=>r!==null&&typeof r=="object"&&r.owner==="agent").map(r=>r.sid));for(let[r,s]of[...ue])s.agentOwned===!0&&(t.has(r)||s.exited!==!0&&s.live===!0&&(s.exited=!0,s.live=!1,it()))}function yp(e){if(ue.has(e.sid))return ue.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};Ir(t),ue.set(t.sid,t),vi+=1,it(),Zt(t.sid),Me({t:"attach",sid:t.sid})}function Sp(e){if(!(e?.spawnSpec?.credsStripped!==!0||e.term===null))try{e.term.writeln("\x1B[2m[dsh-tty] "+S("msg.passwordNotStored")+"\x1B[0m")}catch{}}function xs(e){Sp(e);let t=e.fit!==null?e.fit.proposeDimensions():void 0,r={...e.spawnSpec,sid:e.sid,cols:t!==void 0?t.cols:80,rows:t!==void 0?t.rows:24};if(Ee===null||Ee.readyState!==WebSocket.OPEN){Hn.add({tab:e,frame:r});return}Me(r)}function ql(e){let t={sid:bs(),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};Ir(t),ue.set(t.sid,t),vi+=1,it(),Zt(t.sid),xs(t)}function fs(e){let t=ue.get(e);if(t===void 0)return;if(t.embedded===!0){yc(t);return}let r=t.spawnSpec,s=t.label;if(t.exited||Me({t:"kill",sid:e}),t.term!==null)try{t.term.dispose()}catch{}t.termEl!==null&&t.termEl.remove(),ue.delete(e);let a={sid:bs(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:r,label:s};Ir(a),ue.set(a.sid,a),it(),Zt(a.sid),xs(a),Xt()}function Kl(e){let t=ue.get(e);if(t!==void 0){if(gt!==null&>.ownerKey===e&&ai(!0),t.exited||Me({t:"kill",sid:e}),ue.delete(e),gi.delete(e),t.term!==null)try{t.term.dispose()}catch{}if(t.termEl!==null&&t.termEl.remove(),Re===e){Re=null;let r=[...ue.entries()].filter(([,s])=>s.embedded!==!0).map(([s])=>s).pop()??null;r!==null&&Zt(r)}it(),ro(),[...ue.values()].some(r=>r.embedded!==!0)?Xt():_i()}}function vc(e){let t=typeof e?.command=="string"?e.command.trim():"";if(t==="")throw new Error(S("error.terminalNeedsCommand"));if(/[\r\n\0]/.test(t))throw new Error(S("error.terminalCommandSingleLine"));return t}function bc(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 Cp(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&&Or(e)}}),t.observer.observe(t.hostEl))}function wc(e,t,r){let s={sid:bs(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,embedded:!0,controller:e,spawnSpec:t,label:r};return Ir(s),ue.set(s.sid,s),gi.add(s.sid),e.hostEl.appendChild(s.termEl),Cp(s),xs(s),s}function yc(e){let t=e.controller;if(!(t===void 0||t.disposed)){e.exited||Me({t:"kill",sid:e.sid});try{e.term?.dispose()}catch{}return e.termEl?.remove(),ue.delete(e.sid),gi.delete(e.sid),t.observer!==null&&(t.observer.disconnect(),t.observer=null),t.tab=wc(t,e.spawnSpec,e.label),Re===e.sid&&(Re=t.tab.sid,ro()),t.tab}}function xp(e,t){if(!(e instanceof HTMLElement))throw new Error(S("error.terminalNeedsHost"));let r=vc(t),s=bc(t,r),a=typeof t?.label=="string"&&t.label!==""?t.label:void 0;mi();let i={hostEl:e,tab:null,observer:null,disposed:!1};return i.tab=wc(i,s,a),Yp(),()=>kp(i)}function kp(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||Me({t:"kill",sid:t.sid});try{t.term?.dispose()}catch{}t.termEl?.remove(),ue.delete(t.sid),gi.delete(t.sid),e.tab=null}if(ce===null&&!to()&&Ee!==null){di=!0;try{Ee.close()}catch{}Ee=null}}var Ep=460,Lp=280,Tp=320,Rp=160,gt=null,Cr=Ep,xr=Tp;function io(){let e=ce!==null?ce.querySelector(".tt_modal"):null,t=e!==null?e:ce;return t!==null?t.getBoundingClientRect():null}var so=e=>e==="bottom"?Rp:Lp;function Mp(e){let t=io();if(t===null)return 900;let r=e==="bottom"?t.height:t.width;return Math.max(so(e),Math.round(r*.72))}function oi(e,t){return Math.min(Mp(e),Math.max(so(e),Math.round(t)))}function rs(){let e=gt;if(e!==null){if(e.collapsed){e.el.style.width="",e.el.style.height="",e.el.style.flexBasis="";return}if(e.side==="bottom"){xr=oi("bottom",xr),e.el.style.width="",e.el.style.height=String(xr)+"px",e.el.style.flexBasis=String(xr)+"px";return}Cr=oi("right",Cr),e.el.style.height="",e.el.style.width=String(Cr)+"px",e.el.style.flexBasis=String(Cr)+"px"}}function ai(e){let t=gt;if(t!==null){if(gt=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{}ct!==null&&delete ct.dataset.side}}function Sc(e){if(Jn(),ct===null)throw new Error(S("error.panelNotReady"));gt!==null&&ai(!0),mi();let t=yr(e?.ownerSid,Re),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:so(r)));if(typeof e?.size=="number"&&Number.isFinite(e.size)){let c=oi(r,e.size);r==="bottom"?xr=c:Cr=c}let a=document.createElement("div");a.className="tt_dockPane",a.dataset.side=r,ct.dataset.side=r,a.innerHTML='<div class="tt_dockPaneResize" title="'+S(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="'+S("btn.closePane")+'">'+ys+'</button></div><div class="tt_dockPaneBody"></div>',ct.appendChild(a);let i=a.querySelector(".tt_dockPaneTitle"),n=a.querySelector(".tt_dockPaneHint"),o=a.querySelector(".tt_dockPaneBody"),u=a.querySelector(".tt_dockPaneFold"),l=a.querySelector(".tt_dockPaneClose"),_=a.querySelector(".tt_dockPaneResize"),m={el:a,element:o,disposed:!1,collapsed:!1,side:r,minSize:s,ownerKey:t,onClose:typeof e?.onClose=="function"?e.onClose:null},w=()=>r==="bottom"?m.collapsed?Zn:Qf:m.collapsed?cc:lc,p=c=>{m.collapsed=c===!0,m.collapsed?a.dataset.collapsed="1":delete a.dataset.collapsed,u.innerHTML=w(),u.title=m.collapsed?S("btn.expandPane"):S("btn.collapsePane"),u.setAttribute("aria-label",u.title),rs()};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||gt!==m||ai(!1)},_.addEventListener("mousedown",c=>{if(c.button!==0||m.collapsed)return;c.preventDefault();let d=c.clientX,h=c.clientY,f=a.getBoundingClientRect(),g=v=>{r==="bottom"?xr=oi("bottom",Math.max(s,f.height+(h-v.clientY))):Cr=oi("right",Math.max(s,f.width+(d-v.clientX))),rs()},C=()=>{document.removeEventListener("mousemove",g),document.removeEventListener("mouseup",C),document.body.style.userSelect=""};document.body.style.userSelect="none",document.addEventListener("mousemove",g),document.addEventListener("mouseup",C)}),_.addEventListener("dblclick",()=>p(!m.collapsed)),u.addEventListener("click",()=>p(!m.collapsed)),l.addEventListener("click",()=>ai(!0)),m.setTitle(typeof e?.title=="string"?e.title:""),m.setHint(typeof e?.hint=="string"?e.hint:""),p(e?.collapsed===!0),gt=m,rs(),Cc(),m}function Cc(){let e=gt;if(e!==null){if(Rn(e.ownerKey,Re)){delete e.el.dataset.dockHidden,ct!==null&&(ct.dataset.side=e.side);return}e.el.dataset.dockHidden="1",ct!==null&&delete ct.dataset.side}}function Zt(e){let t=ue.get(e);if(t!==void 0&&t.embedded!==!0){Re=e;for(let[r,s]of ue)s.embedded!==!0&&s.termEl!==null&&(s.termEl.style.display=r===e?"":"none");t.embedded!==!0&&rt!==null&&t.termEl!==null&&t.termEl.parentElement!==rt&&rt.appendChild(t.termEl),wi(),lr(),it(),sr(),Cc();try{t.fit.fit()}catch{}t.spawned&&!t.exited&&Or(t),Sr(t,t.exited?S("status.exited"):"",t.exited?S("btn.clickReopen"):"","exited"),ro()}}function Bn(e){if(kt===null)return;let t=ue.get(e);if(t===void 0)return;let s=kt.querySelector(`[data-sid="${e}"]`)?.querySelector(".tt_tabDot");s!=null&&(s.dataset.state=t.exited?"exited":t.live===!0?"connected":t.errored===!0?"error":"connecting")}var On=!1;function it(){if(kt===null)return;if(kt.querySelector(".tt_tabRename")!==null){On||(On=!0,setTimeout(()=>{On=!1,it()},1e3));return}kt.textContent="";for(let[r,s]of ue){if(s.embedded===!0)continue;let a=document.createElement("button");a.className="tt_tab",a.dataset.sid=r,r===Re&&(a.dataset.active="");let i=document.createElement("span");i.className="tt_tabDot",i.dataset.state=s.exited?"exited":s.live===!0?"connected":s.errored===!0?"error":"connecting",a.appendChild(i);let n=document.createElement("span");n.className="tt_tabLabel",n.textContent=s.label||S("panel.tabLabel",{n:kc(r)}),n.addEventListener("dblclick",u=>{u.stopPropagation(),Pp(r,a)});let o=document.createElement("span");o.className="tt_tabClose",o.title=S("btn.close"),o.textContent="\u2715",o.setAttribute("role","button"),o.setAttribute("aria-label",S("btn.closeTabAria",{label:s.label||""})),o.tabIndex=0,o.addEventListener("keydown",u=>{(u.key==="Enter"||u.key===" "||u.key==="Spacebar")&&(u.preventDefault(),u.stopPropagation(),Kl(r))}),a.title=n.textContent,a.appendChild(n),a.appendChild(o),a.addEventListener("click",u=>{if(u.target.closest(".tt_tabClose")!==null){u.stopPropagation(),Kl(r);return}Zt(r)}),kt.appendChild(a)}let e=kt.querySelector("[data-active]");e!==null&&typeof e.scrollIntoView=="function"&&e.scrollIntoView({block:"nearest",inline:"nearest"});let t=document.createElement("button");t.className="tt_tabAdd",t.title=S("btn.newTab"),t.innerHTML=Xf,t.addEventListener("click",()=>{Np(t)}),kt.appendChild(t)}function Ap(e){return e?.direction==="remote"?S("meta.tunnelRemote",{host:e.remoteHost||"127.0.0.1",port:String(e.remotePort??0),local:String(e.localTargetPort??0)}):S("meta.tunnelLocal",{local:String(e?.localPort??0),host:e?.remoteHost??"?",port:String(e?.remotePort??0)})}function sr(){if(ei===null||as===null||ri===null||ti===null)return;ri.textContent="";let e=dt(),t=e?.spawnSpec??{};if(e===void 0||t.t!=="ssh"){ei.dataset.hidden="";return}delete ei.dataset.hidden;let r=Number(t.port);as.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:""),lt!==null&&(e.persistTmux===!0?(lt.textContent="tmux",lt.dataset.state="ok",lt.title=S("status.tmuxPersistedTitle")):t.persist===!0&&e.spawned===!0?(lt.textContent=S("status.notPersisted"),lt.dataset.state="warn",lt.title=S("status.tmuxUnavailableTitle")):(lt.textContent="",delete lt.dataset.state,lt.removeAttribute("title")));let s=e.exited?"exited":e.live===!0?"connected":e.errored===!0?"error":"connecting";ti.dataset.state=s,ti.title=S(s==="connected"?"status.connected":s==="connecting"?"status.connecting":s==="error"?"status.errored":"status.exited");let a=(n,o,u,l)=>{let _=document.createElement("button");_.type="button",_.className="tt_toolBtn tt_connAct",_.title=u,_.innerHTML=n+"<span></span>",_.lastElementChild.textContent=o,_.addEventListener("click",l),ri.appendChild(_)};if(typeof t.command=="string"&&t.command!=="")return;let i=typeof t.name=="string"?t.name:"";for(let n of Wn)try{n({tab:e,spec:t,bookName:i,addAction:a})}catch(o){console.warn("[dsh-tty] connbar action failed: "+(o instanceof Error?o.message:String(o)))}}function Dp(e,t){if(Rr!==null){is();return}let r=document.createElement("div");r.className="tt_addMenu tt_connMore",Rr=r,Kn(r,S("panel.tunnels"),S("hint.tunnelsSettings"),()=>{is(),xc(e,t)},void 0,ic),document.body.appendChild(r);let s=e.getBoundingClientRect(),a=r.offsetWidth,n=s.left+a>window.innerWidth-8?s.right-a:s.left;r.style.left=Math.max(8,Math.min(n,window.innerWidth-a-8))+"px",r.style.top=s.bottom+6+"px";let o=u=>{Rr===r&&(r.contains(u.target)||e.contains(u.target)||is())};ns=o,setTimeout(()=>document.addEventListener("mousedown",o,!0),0)}function is(){ns!==null&&(document.removeEventListener("mousedown",ns,!0),ns=null),Rr!==null&&(Rr.remove(),Rr=null)}var tr=null,ss=null,Rr=null,ns=null;function ps(){ss!==null&&(document.removeEventListener("mousedown",ss,!0),ss=null),tr!==null&&(tr.remove(),tr=null)}function xc(e,t){if(tr!==null){ps();return}let r=document.createElement("div");r.className="tt_tunnelPop";let s=document.createElement("div");s.className="tt_tunnelPopTitle",s.textContent=S("panel.tunnelsFor",{name:t}),r.appendChild(s);let a=document.createElement("div");a.textContent=S("list.loading"),r.appendChild(a);let i=document.createElement("span");i.className="tt_cardHint",i.textContent=S("hint.tunnelsCard"),r.appendChild(i),document.body.appendChild(r),tr=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 o=u=>{tr===r&&(r.contains(u.target)||e.contains(u.target)||ps())};ss=o,setTimeout(()=>document.addEventListener("mousedown",o,!0),0),(async()=>{let u=[];try{let m=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();m.ok&&Array.isArray(m.tunnels)&&(u=m.tunnels)}catch{}if(tr!==r)return;a.textContent="";let l=no.filter(_=>_?.bookName===t&&_?.enabled!==!1);if(l.length===0){let _=document.createElement("span");_.className="tt_cardHint",_.textContent=S("list.noActiveTunnels"),a.appendChild(_);return}for(let _ of l){let m=u.find(h=>h?.name===_?.name),w=m?.state??"stopped",p=document.createElement("div");p.className="tt_tunnelPopRow";let c=document.createElement("span");c.className="tt_connDot",c.dataset.state=w==="active"?"connected":w==="error"?"error":"connecting";let d=document.createElement("span");d.className="tt_connTarget",d.title=String(m?.error??m?.lastForwardError??""),d.textContent=Ap(_)+" \xB7 "+w+(m?.fatal===!0?S("status.fatalSuffix"):""),p.appendChild(c),p.appendChild(d),a.appendChild(p)}})()}function kc(e){let t=1;for(let r of ue.keys()){if(r===e)return String(t);t+=1}return String(t)}function Pp(e,t){let r=ue.get(e);if(r===void 0||t.querySelector(".tt_tabRename")!==null)return;let s=t.querySelector(".tt_tabLabel");if(s===null)return;let a=document.createElement("input");a.className="tt_tabRename",a.value=r.label||S("panel.tabLabel",{n:kc(e)}),s.replaceWith(a),a.focus(),a.select();let i=!1,n=()=>{if(i)return;i=!0;let u=a.value.trim();r.label=u!==""?u:void 0,it(),Xt()},o=()=>{i||(i=!0,it())};a.addEventListener("keydown",u=>{u.stopPropagation(),u.key==="Enter"?n():u.key==="Escape"&&o()}),a.addEventListener("blur",n),a.addEventListener("click",u=>u.stopPropagation())}var no=[],Ec="dialog",Yt="off",Jt={maxDownloadMb:1024,maxUploadMb:2048,maxUploadFiles:1e3},Mr=null,Lc=!1,Tc=!1,Vt=null,_s=null,nr=!1;function Rc(e){nr=e,_s!==null&&_s.set(e)}function Bp(e){Rc(!(e!==null&&typeof e=="object"&&e.enabled===!1)),e!==null&&typeof e=="object"&&typeof e.statsEnabled=="boolean"&&e.statsEnabled!==ds&&(ds=e.statsEnabled,wi(),lr())}function fi(e){Bp(e),e!==null&&typeof e=="object"&&Array.isArray(e.sshHosts)&&(Ht=e.sshHosts),e!==null&&typeof e=="object"&&Array.isArray(e.tunnels)&&(no=e.tunnels),e!==null&&typeof e=="object"&&(e.sftpStyle==="dual"||e.sftpStyle==="dialog")&&(Ec=e.sftpStyle),e!==null&&typeof e=="object"&&(e.persistence==="tmux"||e.persistence==="off")&&(Yt=e.persistence),e!==null&&typeof e=="object"&&typeof e.sftpLimits=="object"&&e.sftpLimits!==null&&(Jt={...Jt,...e.sftpLimits}),e!==null&&typeof e=="object"&&Number.isInteger(e.maxSessions)&&e.maxSessions>=1&&(Mr=e.maxSessions),e!==null&&typeof e=="object"&&typeof e.allowProxyCommand=="boolean"&&(Lc=e.allowProxyCommand),e!==null&&typeof e=="object"&&typeof e.allowProxyCommandGranted=="boolean"&&(Tc=e.allowProxyCommandGranted)}function Op(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"?hc:r==="info"?rp:tp)+'</span><span class="tt_toastText"></span>',s.lastElementChild.textContent=e,document.body.appendChild(s),setTimeout(()=>s.remove(),4e3)}async function Mc(){try{Me({t:"sessions"});let e=await us("sessions",3e3);if(e!==null&&Array.isArray(e.list))return Vt=e.list.length,Vt}catch{}return null}async function ms(){if(await Mc(),Mr===null||Vt===null||Vt<Mr)return null;let e=[...ue.values()].filter(a=>!a.exited).length,t=Math.max(0,Vt-e),r=t>0?S("msg.maxSessionsOthers",{count:t}):"",s=S("msg.maxSessions",{live:Vt,max:Mr,own:e,others:r});return Op(s),s}function Ip(){return Mr!==null&&Vt!==null&&Vt>=Mr}function oo(){return Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4)}function Ac(e){return no.filter(t=>t?.bookName===e&&t?.enabled!==!1).length}function zn(e){let t=Number(e?.port),r=Number.isInteger(t)&&t!==22?":"+t:"",s=e?.auth==="key"?"key":e?.auth==="password"?"password":"agent",a=e?.agentForward===!0?" \xB7 fwd":"";return String(e?.username??"")+"@"+String(e?.host??"")+r+" \xB7 "+s+a}async function $n(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:S("error.probeHttp",{status:r.status}))}}function qn(e,t){if(!e)return S("msg.probing");let r=e,s=typeof r.tcp?.ms=="number"?r.tcp.ms:null,a=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":S("meta.reachable"):S("meta.unreachable");i.push(S("meta.jumpStage",{label:r.jump.label})+" "+m)}r.proxy!==null&&typeof r.proxy=="object"&&i.push(r.proxy.active===!0?S("meta.probeProxy"):S("meta.probeProxyOff")),r.tcp?.ok?i.push("TCP "+(s!==null?s+"ms":S("meta.reachable"))):r.tcp?.skipped===!0&&i.push(S("meta.probeTcpSkipped")),r.banner?.ok&&i.push(S("meta.probeBanner"));let n=r.hostkey?.state;if(n==="matched"?i.push(S("meta.hostKeyMatched")):n==="recorded"?i.push(S("meta.hostKeyRecorded")):n==="mismatch"&&i.push(S("meta.hostKeyMismatch")),r.auth?.ok){let _=a!==null?S("meta.authOkMs",{ms:a}):S("meta.authOk");return S("meta.probeOk",{detail:_+(i.length?" \xB7 "+i.join(" \xB7 "):"")})}let o=r.tcp?.skipped===!0?"":r.tcp?.error,l=(r.auth?.error||o||S("error.unknown"))+(i.length?" \xB7 "+i.join(" \xB7 "):"");return t?.prefix!==void 0?t.prefix+l:S("error.probeFailed",{detail:l})}async function ao(){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=Ht;fi(t.config),ht!==null&&Ht!==r&&Gn(ht)}}catch{}}function Dc(e){ht!==null&&(e.target instanceof Element&&(ht.contains(e.target)||e.target.closest(".tt_tabAdd")!==null)||Et())}function Np(e){if(ht!==null){Et();return}ao(),Mc().then(()=>{ht!==null&&Gn(ht)});let t=document.createElement("div");t.className="tt_addMenu",ht=t,Gn(t),document.body.appendChild(t);let r=e.getBoundingClientRect(),s=t.offsetWidth,i=r.left+s>window.innerWidth-8?r.right-s:r.left;t.style.left=Math.max(8,Math.min(i,window.innerWidth-s-8))+"px",t.style.top=r.bottom+6+"px",document.addEventListener("mousedown",Dc,!0)}function Et(){ht!==null&&(document.removeEventListener("mousedown",Dc,!0),ht.remove(),ht=null)}function Kn(e,t,r,s,a,i){let n=document.createElement("button");if(n.type="button",n.className="tt_addMenuItem",a===!0&&(n.setAttribute("data-soldout",""),n.title=S("btn.maxSessionsTitle")),i!==void 0){let l=document.createElement("span");l.className="tt_addMenuIcon",l.innerHTML=i,n.appendChild(l)}let o=document.createElement("span");o.className="tt_addMenuText";let u=document.createElement("span");if(u.className="tt_addMenuMain",u.textContent=t,o.appendChild(u),r!==""){let l=document.createElement("span");l.className="tt_addMenuSub",l.textContent=r,o.appendChild(l)}n.appendChild(o),n.addEventListener("click",s),e.appendChild(n)}function Gn(e){e.textContent="";let t=Ip();Kn(e,S("option.localTerminal"),S(Yt==="tmux"?"hint.tmuxHosted":"hint.openInSessionCwd"),async()=>{await ms()||(Et(),ui())},t,ws);let r=document.createElement("div");r.className="tt_addMenuSep",e.appendChild(r);let s=document.createElement("div");s.className="tt_addMenuTitle",s.textContent=S("panel.sshBook"),e.appendChild(s);for(let i of Ht){if(i===null||typeof i!="object"||typeof i.name!="string"||i.name==="")continue;let n=document.createElement("div");n.className="tt_addMenuRow";let o=document.createElement("button");o.type="button",o.className="tt_addMenuItem",t&&(o.setAttribute("data-soldout",""),o.title=S("btn.maxSessionsTitle"));let u=document.createElement("span");u.className="tt_addMenuIcon",u.innerHTML=ep;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 w=Ac(i.name),p=Ln(i.jump);m.textContent=zn(i)+(p===""?"":" "+S("meta.viaJump",{label:p}))+(typeof i.proxyCommand=="string"&&i.proxyCommand.trim()!==""?" "+S("meta.viaProxy"):"")+(w>0?" \xB7 \u21C4"+String(w):""),l.appendChild(_),l.appendChild(m),o.appendChild(u),o.appendChild(l),o.addEventListener("click",async()=>{if(await ms())return;Et();let h=Yt==="tmux"&&i.persist!==!1?{persist:!0,persistName:oo()}:{};ui({t:"ssh",name:i.name,...h},i.name)});let c=document.createElement("button");c.type="button",c.className="tt_addMenuEdit",c.title=S("btn.sftpFileBrowse"),c.innerHTML=ci,c.addEventListener("click",()=>{Et(),ks({name:i.name})});let d=document.createElement("button");d.type="button",d.className="tt_addMenuEdit",d.title=S("btn.editConnection"),d.innerHTML=Qn,d.addEventListener("click",()=>{Et(),Gl(i)}),n.appendChild(o),n.appendChild(c),n.appendChild(d),e.appendChild(n)}if(Ht.length===0){let i=document.createElement("div");i.className="tt_addMenuTitle",i.textContent=S("list.emptySshBook"),e.appendChild(i)}let a=document.createElement("div");a.className="tt_addMenuSep",e.appendChild(a),Kn(e,S("option.sshConnect"),S("hint.sshConnect"),()=>{Et(),Gl()},!1,dc)}function Gl(e){if(Tr!==null)return;let t=e!==null&&typeof e=="object"?e:null,r=t!==null,s=document.createElement("div");s.className="tt_sshBackdrop";let a=document.createElement("div");a.className="tt_sshCard";let i=document.createElement("div");i.className="tt_sshTitle",i.innerHTML=dc+"<span></span>",i.lastElementChild.textContent=r?S("panel.editConnection",{name:String(t.name??"")}):S("panel.sshConnect"),a.appendChild(i);let n=Z=>{let te=document.createElement("div");return te.className="tt_sshSection",te.textContent=Z,te},o={},u=(Z,te,le)=>{let ie=document.createElement("label");ie.className="tt_sshRow";let ne=document.createElement("span");ne.className="tt_cardLabel",ne.textContent=te,ie.appendChild(ne);let oe;if(le?.select!==void 0){oe=document.createElement("select");for(let pe of le.select){let we=document.createElement("option");we.value=pe.value,we.textContent=pe.label,oe.appendChild(we)}}else oe=document.createElement("input"),oe.type=le?.type??"text",oe.placeholder=le?.placeholder??"";return oe.className="tt_cardInput",oe.autocomplete="off",oe.spellcheck=!1,ie.appendChild(oe),o[Z]=oe,ie};a.appendChild(n(S("section.connection")));let l=document.createElement("div");l.className="tt_sshGrid",l.appendChild(u("host",S("field.host"),{placeholder:S("placeholder.host")})),l.appendChild(u("port",S("field.port"),{placeholder:"22"})),a.appendChild(l),a.appendChild(u("username",S("field.username"),{placeholder:"root"})),a.appendChild(n(S("section.auth"))),a.appendChild(u("auth",S("field.authMethod"),{select:[{value:"agent",label:S("option.authAgent")},{value:"key",label:S("option.authKey")},{value:"password",label:S("option.authPassword")}]}));let _=u("keyPath",S("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),m=u("passphrase",S("field.passphrase"),{type:"password"}),w=u("password",S("field.password"),{type:"password"}),p=(Z,te)=>{let le=document.createElement("div");le.className="tt_sshRow tt_envRow";let ie=document.createElement("input");ie.type="text",ie.className="tt_cardInput",ie.placeholder=S("placeholder.credRef"),ie.title=S("hint.credRefCandidates"),ie.autocomplete="off",ie.spellcheck=!1;let ne=document.createElement("span");ne.className="tt_cardHint tt_envEmpty",ne.textContent=te,ne.hidden=!0,ie.hidden=!0;let oe=document.createElement("div");oe.className="tt_envList",oe.dataset.hidden="";let pe=[],we=()=>{if(oe.textContent="",pe.length===0){let ye=document.createElement("span");ye.className="tt_cardHint",ye.textContent=te,oe.appendChild(ye);return}let _e=ie.value.trim().toUpperCase(),Ie=_e===""?pe:pe.filter(ye=>ye.toUpperCase().includes(_e));for(let ye of Ie.slice(0,30)){let ve=document.createElement("button");ve.type="button",ve.className="tt_envItem",ve.textContent=ye;let xe="env:"+ye,Ne=null,je=()=>{Ne!==null&&(clearTimeout(Ne),Ne=null),ve.textContent=ye,delete ve.dataset.danger};ve.addEventListener("mousedown",Qt=>Qt.preventDefault()),ve.addEventListener("click",()=>{let Qt=Z.value;if(Qt===""||Qt.startsWith("env:")||Ne!==null){je(),Z.value=xe,Z.focus(),Z.dispatchEvent(new Event("change"));return}ve.textContent=S("list.credOverwrite",{name:ye}),ve.dataset.danger="",Ne=setTimeout(je,4e3)}),oe.appendChild(ve)}if(Ie.length>30){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=S("list.moreMatches",{count:Ie.length-30}),oe.appendChild(ye)}else if(Ie.length===0){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=S("list.noCredRef"),oe.appendChild(ye)}};return ie.addEventListener("input",we),ie.addEventListener("focus",()=>{pe.length>0&&delete oe.dataset.hidden}),ie.addEventListener("blur",()=>{ie.value.trim()===""&&(oe.dataset.hidden="")}),le.appendChild(ie),le.appendChild(ne),le.appendChild(oe),{row:le,setNames(_e){pe=Array.isArray(_e)?_e:[];let Ie=pe.length>0;ie.hidden=!Ie,ne.hidden=Ie,we()}}},c=(Z,te)=>{let le=document.createElement("div");le.className="tt_sshRow tt_credRow";let ie=document.createElement("label");ie.className="tt_credToggle";let ne=document.createElement("input");ne.type="checkbox",ne.className="tt_cardCheckbox";let oe=document.createElement("span");oe.textContent=S("check.rememberCredential"),ie.appendChild(ne),ie.appendChild(oe),ne.checked=Lt!==null,ie.title=S("hint.rememberCredential");let pe=document.createElement("button");pe.type="button",pe.className="tt_toolBtn tt_credClear",pe.textContent=S("btn.clearCredential"),pe.dataset.hidden="";let we=document.createElement("span");we.className="tt_credStatus",le.appendChild(ie),le.appendChild(pe),le.appendChild(we);let _e=(ve,xe)=>{we.textContent=ve,we.dataset.kind=xe},Ie=async()=>{let ve=kr(Z.value),xe=ve!=="";if(ie.hidden=xe,pe.hidden=!xe,we.hidden=!1,Ar()===null){ne.disabled=!0,ne.checked=!1,pe.disabled=!0,_e(S(Lt===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),"muted");return}if(ne.disabled=!1,!xe){we.hidden=!0,_e("","plain");return}let Ne=await ec(ve);if(Ne.unreported===!0){_e(S("status.credUnreported",{ref:ve}),"plain");return}if(Ne.error!==void 0){_e(S("error.credStatusFailed",{error:Ne.error}),"error");return}let je=Ne.view;_e(je.configured?S("status.credStored",{ref:ve,source:je.source!==""?S("meta.credSource",{source:je.source}):""}):S("status.credUnknown",{ref:ve}),je.configured?"ok":"plain"),pe.disabled=je.configured!==!0||je.writable!==!0};pe.addEventListener("click",()=>{(async()=>{let ve=kr(Z.value);if(ve==="")return;let xe=await tc(ve);if(xe.error!==void 0){_e(xe.error,"error");return}Z.value="",await Ie()})()});let ye=async()=>{let ve=await rc(ne.checked===!0,Z.value,o.host.value,o.port.value,o.username.value,te);return ve.value!==void 0&&(Z.value=ve.value,await Ie()),ve};return Z.addEventListener("change",()=>{Ie()}),{row:le,refresh:Ie,storeIfRequested:ye}},d=p(o.passphrase,S("hint.noCredRefPassphrase")),h=p(o.password,S("hint.noCredRefPassword")),f=c(o.password,"PASSWORD");(async()=>{let Z=await Ql();d.setNames(Z),h.setNames(Z)})(),a.appendChild(_),a.appendChild(m),a.appendChild(d.row),a.appendChild(w),a.appendChild(f.row),a.appendChild(h.row),a.appendChild(n(S("section.jump")));let g=u("jumpHost",S("field.jumpHost"),{placeholder:S("placeholder.jumpHost")});a.appendChild(g);let C=document.createElement("label");C.className="tt_sshRow";let v=document.createElement("input");v.type="checkbox";let x=document.createElement("span");x.className="tt_cardLabel",x.textContent=S("check.jumpOwnCred"),C.appendChild(v),C.appendChild(x),a.appendChild(C);let b=u("jumpUsername",S("field.jumpUsername"),{placeholder:"root"}),E=u("jumpAuth",S("field.jumpAuth"),{select:[{value:"",label:S("option.authInherit")},{value:"agent",label:S("option.authAgent")},{value:"key",label:S("option.authKey")},{value:"password",label:S("option.authPassword")}]}),O=u("jumpKeyPath",S("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),B=u("jumpPassphrase",S("field.passphrase"),{type:"password"}),H=u("jumpPassword",S("field.password"),{type:"password"});for(let Z of[b,E,O,B,H])a.appendChild(Z);let M=document.createElement("div");M.className="tt_cardHint",M.textContent=S("hint.jumpInherit"),a.appendChild(M),a.appendChild(n(S("section.proxyCommand")));let K=u("proxyCommand",S("field.proxyCommand"),{placeholder:S("placeholder.proxyCommand")});a.appendChild(K);let P=document.createElement("div");P.className="tt_cardHint",P.textContent=S("hint.proxyCommand"),a.appendChild(P);let D=document.createElement("div");D.className="tt_cardHint tt_sshProbeWarn",D.textContent=S("hint.proxyCommandDisabled"),a.appendChild(D);let F=()=>{let Z=o.proxyCommand.value.trim()!=="",te=Tc,le=te&&Lc;D.textContent=S(te?"hint.proxyCommandDisabled":"hint.proxyCommandNotGranted"),D.style.display=Z&&!le?"":"none"};o.proxyCommand.addEventListener("input",F),F();let N=()=>{let Z=En(o.jumpHost.value);if(Z===void 0)return;if(v.checked!==!0)return Z;let te={...Z},le=o.jumpUsername.value.trim();le!==""&&(te.username=le);let ie=o.jumpAuth.value;(ie==="agent"||ie==="key"||ie==="password")&&(te.auth=ie);let ne=o.jumpKeyPath.value.trim();return ne!==""&&(te.keyPath=ne),o.jumpPassphrase.value!==""&&(te.passphrase=o.jumpPassphrase.value),o.jumpPassword.value!==""&&(te.password=o.jumpPassword.value),te},y=()=>{let Z=o.proxyCommand.value.trim();return Z===""?void 0:Z},T=()=>{let Z=En(o.jumpHost.value)!==void 0,te=Z&&v.checked===!0;C.style.display=Z?"":"none";for(let le of[b,E,O,B,H])le.style.display=te?"":"none";O.style.display=te&&o.jumpAuth.value==="key"?"":"none",B.style.display=te&&o.jumpAuth.value==="key"?"":"none",H.style.display=te&&o.jumpAuth.value==="password"?"":"none",M.style.display=Z?"":"none"};o.jumpHost.addEventListener("input",T),o.jumpAuth.addEventListener("change",T),v.addEventListener("change",T),a.appendChild(n(S("section.options")));let k=document.createElement("label");k.className="tt_cardRow";let R=document.createElement("input");R.type="checkbox",R.className="tt_cardCheckbox";let U=document.createElement("span");U.className="tt_cardLabel",U.textContent=S("check.agentForward"),k.appendChild(R),k.appendChild(U),a.appendChild(k);let G=document.createElement("label");G.className="tt_cardRow";let J=document.createElement("input");J.type="checkbox",J.className="tt_cardCheckbox";let X=document.createElement("span");X.className="tt_cardLabel",X.textContent=S("check.persist"),G.appendChild(J),G.appendChild(X),J.checked=Yt==="tmux",Yt==="tmux"&&a.appendChild(G);let W=document.createElement("label");W.className="tt_cardRow";let L=document.createElement("input");L.type="checkbox",L.className="tt_cardCheckbox";let I=document.createElement("span");I.className="tt_cardLabel",I.textContent=S("check.saveToBook"),W.appendChild(L),W.appendChild(I),a.appendChild(W);let z=u("name",S("field.bookName"),{placeholder:S("placeholder.bookName")});if(z.style.display="none",a.appendChild(z),L.addEventListener("change",()=>{z.style.display=L.checked?"":"none",L.checked&&o.name.value.trim()===""&&o.host.value.trim()!==""&&(o.name.value=o.host.value.trim()),L.checked&&o.name.focus()}),r){W.style.display="none",o.name.value=String(t.name??""),z.style.display="",o.host.value=String(t.host??""),o.port.value=String(t.port??22),o.username.value=String(t.username??""),o.auth.value=t.auth==="key"||t.auth==="password"?String(t.auth):"agent",o.keyPath.value=String(t.keyPath??""),o.passphrase.value=String(t.passphrase??""),o.password.value=String(t.password??"");let Z=t.jump!==null&&typeof t.jump=="object"?t.jump:null;if(o.jumpHost.value=Ln(Z),Z!==null){let te=Z.auth!==void 0||Z.keyPath!==void 0||Z.password!==void 0||Z.passphrase!==void 0;v.checked=te,te&&(o.jumpUsername.value=String(Z.username??""),o.jumpAuth.value=Z.auth==="key"||Z.auth==="password"?String(Z.auth):"",o.jumpKeyPath.value=String(Z.keyPath??""),o.jumpPassphrase.value=String(Z.passphrase??""),o.jumpPassword.value=String(Z.password??""))}R.checked=t.agentForward===!0,o.proxyCommand.value=String(t.proxyCommand??""),F(),J.checked=Yt==="tmux"}let $=document.createElement("div");$.className="tt_sshStatus";let q=document.createElement("div");q.className="tt_sshError";let ee=document.createElement("div");ee.className="tt_sshProbeResult",$.appendChild(q),$.appendChild(ee),a.appendChild($),T();let he=()=>{q.textContent="";let Z=o.host.value.trim(),te=o.username.value.trim(),le=Number(o.port.value);if((!Number.isInteger(le)||le<1||le>65535)&&(le=22),Z===""||te==="")return q.textContent=S("error.hostUserRequired"),null;let ie=o.auth.value,ne={host:Z,port:le,username:te,auth:ie},oe=N();oe!==void 0&&(ne.jump=oe);let pe=y();if(pe!==void 0&&(ne.proxyCommand=pe),ie==="key"){let we=o.keyPath.value.trim();if(we==="")return q.textContent=S("error.keyPathRequired"),null;ne.keyPath=we;let _e=o.passphrase.value;_e!==""&&(ne.passphrase=_e)}if(ie==="password"){let we=o.password.value;if(we==="")return q.textContent=S("error.passwordRequired"),null;ne.password=we}return R.checked&&(ne.agentForward=!0),ne},de=document.createElement("div");de.className="tt_sshActions";let re=document.createElement("div");re.className="tt_sshActionsGroup";let Y=document.createElement("div");Y.className="tt_sshActionsGroup",de.appendChild(re),de.appendChild(Y);let se=document.createElement("button");se.type="button",se.className="tt_toolBtn",se.textContent=S("btn.cancel");let be=document.createElement("button");be.type="button",be.className="tt_cardSave",be.textContent=S("btn.connect"),re.appendChild(se);let fe=document.createElement("button");fe.type="button",fe.className="tt_toolBtn",fe.textContent=S("btn.fileBrowse"),fe.title=S("btn.browseTitle"),fe.addEventListener("click",()=>{q.textContent="";let Z=o.host.value.trim(),te=o.username.value.trim(),le=Number(o.port.value);if((!Number.isInteger(le)||le<1||le>65535)&&(le=22),Z===""||te===""){q.textContent=S("error.hostUserRequired");return}let ie=o.auth.value,ne={host:Z,port:le,username:te,auth:ie},oe=N();oe!==void 0&&(ne.jump=oe);let pe=y();if(pe!==void 0&&(ne.proxyCommand=pe),ie==="key"){let we=o.keyPath.value.trim();if(we===""){q.textContent=S("error.keyPathRequired");return}ne.keyPath=we;let _e=o.passphrase.value;_e!==""&&(ne.passphrase=_e)}if(ie==="password"){let we=o.password.value;if(we===""){q.textContent=S("error.passwordRequired");return}ne.password=we}R.checked&&(ne.agentForward=!0),Gt(),ks(ne)}),re.appendChild(fe);let ge=null;r&&(ge=document.createElement("button"),ge.type="button",ge.className="tt_toolBtn",ge.textContent=S("btn.saveEdit"),ge.addEventListener("click",()=>{q.textContent="";let Z=o.host.value.trim(),te=o.username.value.trim();if(Z===""||te===""){q.textContent=S("error.hostUserRequired");return}let le=Number(o.port.value);(!Number.isInteger(le)||le<1||le>65535)&&(le=22);let ie=o.auth.value,oe={name:o.name.value.trim()||Z,host:Z,port:le,username:te,auth:ie,keyPath:ie==="key"?o.keyPath.value.trim():"",passphrase:o.passphrase.value,password:o.password.value,agentForward:R.checked,persist:J.checked},pe=N();if(pe!==void 0&&(oe.jump=pe),oe.proxyCommand=o.proxyCommand.value.trim(),ie==="key"&&oe.keyPath===""){q.textContent=S("error.keyPathRequired");return}ge!==null&&(ge.disabled=!0),(async()=>{let we=await f.storeIfRequested();if(we.error!==void 0){q.textContent=we.error,ge!==null&&(ge.disabled=!1);return}we.value!==void 0&&(oe.password=we.value);let _e=await Fp(String(t.name??""),oe);if(ge!==null&&(ge.disabled=!1),_e!==void 0){q.textContent=S("error.saveCredFailed",{error:_e});return}Gt()})()}),re.appendChild(ge));let Le=document.createElement("button");Le.type="button",Le.className="tt_toolBtn",Le.textContent=S("btn.probe"),Le.title=S("btn.probeTitle"),Le.addEventListener("click",()=>{let Z=he();Z!==null&&(ee.className="tt_sshProbeResult",ee.textContent=S("msg.probing"),Le.disabled=!0,$n(Z,!1).then(te=>{Le.disabled=!1,te.result?(ee.className="tt_sshProbeResult"+(te.result.auth?.ok===!0?" tt_sshProbeOk":" tt_sshProbeBad"),ee.textContent=qn(te.result)):(ee.className="tt_sshProbeResult tt_sshProbeBad",ee.textContent=S("error.probeFailed",{detail:String(te.error||S("error.unknown"))}))}))}),re.appendChild(Le),Y.appendChild(be),a.appendChild(de);let Ce=()=>{_.style.display=o.auth.value==="key"?"":"none",m.style.display=o.auth.value==="key"?"":"none",d.row.style.display=o.auth.value==="key"?"":"none",w.style.display=o.auth.value==="password"?"":"none",h.row.style.display=o.auth.value==="password"?"":"none",f.row.style.display=o.auth.value==="password"?"":"none"};o.auth.addEventListener("change",Ce),Ce(),f.refresh(),se.addEventListener("click",()=>Gt()),s.addEventListener("mousedown",Z=>{Z.target===s&&Gt()}),be.addEventListener("click",async()=>{q.textContent="";let Z=await ms();if(Z!==null){q.textContent=Z;return}let te=o.host.value.trim(),le=o.username.value.trim(),ie=Number(o.port.value);if((!Number.isInteger(ie)||ie<1||ie>65535)&&(ie=22),te===""||le===""){q.textContent=S("error.hostUserRequired");return}let ne=o.auth.value,oe={t:"ssh",host:te,port:ie,username:le,auth:ne},pe=N();pe!==void 0&&(oe.jump=pe);let we=y();if(we!==void 0&&(oe.proxyCommand=we),ne==="key"){let ve=o.keyPath.value.trim();ve!==""&&(oe.keyPath=ve);let xe=o.passphrase.value;xe!==""&&(oe.passphrase=xe)}if(ne==="password"){let ve=o.password.value;ve!==""&&(oe.password=ve)}R.checked&&(oe.agentForward=!0),J.checked&&(oe.persist=!0,oe.persistName=oo());let _e=ie!==22?le+"@"+te+":"+ie:le+"@"+te,Ie=ve=>{Gt(),ce!==null&&ui(oe,ve!==""?ve:_e)};if(!L.checked){Ie("");return}let ye=o.name.value.trim()||te;be.disabled=!0,(async()=>{let ve=await f.storeIfRequested();if(ve.error!==void 0){q.textContent=ve.error,be.disabled=!1;return}let xe=ve.value??oe.password??"",Ne=await Hp({name:ye,host:te,port:ie,username:le,auth:ne,keyPath:oe.keyPath??"",passphrase:oe.passphrase??"",password:xe,agentForward:R.checked,persist:J.checked,...pe!==void 0?{jump:pe}:{},proxyCommand:o.proxyCommand.value.trim()});if(be.disabled=!1,Ne!==void 0){q.textContent=S("error.saveBookFailed",{error:Ne});return}Ie(ye)})()}),s.appendChild(a),document.body.appendChild(s),Tr=s,o.host.focus()}function Gt(){Tr!==null&&(Tr.remove(),Tr=null)}async function Hp(e){let t=[...Ht.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);fi(s.config);return}catch(r){return String(r&&r.message?r.message:r)}}async function Fp(e,t){if(t.name!==e&&Ht.some(s=>s?.name===t.name))return S("error.bookNameTaken",{name:t.name});let r=Ht.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})}),a=await s.json().catch(()=>({}));if(!s.ok||!a.ok)return String(a.error||"HTTP "+s.status);fi(a.config);return}catch(s){return String(s&&s.message?s.message:s)}}function Wp(e,t,r){let s=yr(r,Re);if(Bc(s))return;let a=document.createElement("div");a.className="tt_sftpDualCard";let i=document.createElement("div");i.className="tt_sftpTitleRow";let n=document.createElement("div");n.className="tt_sshTitle",n.innerHTML=ci+"<span></span>",n.lastElementChild.textContent=S("panel.sftpDual",{label:t});let o=document.createElement("button");o.type="button",o.className="tt_close",o.title=S("btn.close"),o.innerHTML=ys,o.addEventListener("click",()=>Br(s)),i.appendChild(n),i.appendChild(o),a.appendChild(i);let u=document.createElement("div");u.className="tt_sftpStatus";let l=(y,T)=>{u.textContent=y,T===void 0?delete u.dataset.state:u.dataset.state=T},_=!1,m=(y,T)=>{if(!(_||p.local.busy||p.remote.busy)){_=!0;for(let k of[p.local,p.remote])k.setBusy(!0);l(y,"busy"),Promise.resolve().then(T).catch(k=>{(k===null||typeof k!="object"||k.name!=="TransferCanceledError")&&P.fail(S("status.failed")),l(String(k&&k.message?k.message:k),"error")}).finally(()=>{_=!1;for(let k of[p.local,p.remote])k.setBusy(!1)})}},w=y=>{p[y].bar.after(d),d.style.display="",h.focus(),h.select()},p={},c=(y,T)=>{let k={kind:y,path:"",busy:!1},R=document.createElement("div");R.className="tt_sftpPane";let U=document.createElement("div");U.className="tt_sftpPaneHead";let G=document.createElement("span");G.textContent=T;let J=document.createElement("span");J.className="tt_sftpPaneMeta",U.appendChild(G),U.appendChild(J),R.appendChild(U);let X=document.createElement("div");X.className="tt_sftpBar";let W=document.createElement("input");W.type="text",W.className="tt_sftpPath",W.placeholder=S(y==="local"?"placeholder.localPath":"placeholder.remotePath"),W.spellcheck=!1,W.autocomplete="off";let L=document.createElement("button");L.type="button",L.className="tt_toolBtn",L.innerHTML=eo+"<span>"+S("btn.refresh")+"</span>";let I=document.createElement("button");I.type="button",I.className="tt_toolBtn",I.innerHTML=ac+"<span>"+S("btn.mkdir")+"</span>",X.appendChild(W),X.appendChild(L),X.appendChild(I),R.appendChild(X);let z=document.createElement("div");z.className="tt_sftpList",R.appendChild(z),k.bar=X;let $=Y=>{k.busy=Y;for(let se of[L,I])se.disabled=Y;W.disabled=Y},q=async(Y,se)=>{let be=y==="local"?"/api/dsh-tty/local-fs/":"/api/dsh-tty/sftp/",fe=y==="local"?se:{...e,...se},ge=await fetch(be+Y,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(fe)}),Le=await ge.json().catch(()=>({}));if(!ge.ok||Le.ok!==!0)throw new Error(String(Le.error||"HTTP "+ge.status));return Le},ee=(Y,se)=>{if(!(k.busy||_))return $(!0),l(Y,"busy"),Promise.resolve().then(se).catch(be=>l(String(be&&be.message?be.message:be),"error")).finally(()=>$(!1))},he=(Y,se)=>{if(Y===void 0||Y==="")throw new Error(S("error.dirNotReady"));return Y.endsWith("/")||Y.endsWith("\\")?Y+se:Y+"/"+se},de=Y=>{let se=he(k.path,Y.name),be=[];Y.isDir===!0?be.push(S("meta.dir")):be.push(tt(Number(Y.size))||"\u2014");let fe=Ic(Number(Y.mtime));fe!==""&&be.push(fe);let ge=x(Y.isDir?ci:Y.isSymlink?nc:sc,Y.name,be.join(" \xB7 "),Y.isDir===!0?"dir":Y.isSymlink===!0?"link":"file"),Le=()=>k.loadDir(k.path),Ce=y==="local"?p.remote:p.local;return Y.isDir===!0&&ge.addEventListener("click",Z=>{Z.target instanceof Element&&Z.target.closest(".tt_sftpAct")!==null||k.loadDir(se)}),b(ge,y==="local"?lc:cc,S("btn.transferTo",{target:S(y==="local"?"meta.remote":"meta.local"),path:Ce.path}),()=>{if(k.path===""||Ce.path===""){l(S("error.transferDirsNotReady"),"error");return}P.reset(),P.pulse(0),m(S("msg.transferring",{name:Y.name}),async()=>{let Z=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"start",direction:y==="local"?"up":"down",...e,localPath:y==="local"?se:he(Ce.path,Y.name),remotePath:y==="local"?he(Ce.path,Y.name):se})}),te=await Z.json().catch(()=>({}));if(!Z.ok||te.ok!==!0)throw P.fail(S("error.transferFailed")),new Error(String(te.error||"HTTP "+Z.status));let le=te.job?.id;if(typeof le!="string"||le==="")throw P.fail(S("error.transferFailed")),new Error(S("error.noTaskId"));await D(le,Y.name)==="canceled"?(P.reset(),l(S("msg.transferCanceled",{name:Y.name}))):(P.done(S("status.done")),setTimeout(()=>P.reset(),1500),l(S("msg.transferred",{name:Y.name}))),await Ce.loadDir(Ce.path)})}),y!=="local"&&Y.isDir!==!0&&b(ge,oc,S("btn.download",{name:Y.name}),()=>{O(Y,se)}),b(ge,Qn,S("btn.rename",{name:Y.name}),()=>{h.placeholder=S("placeholder.newName"),h.value=Y.name,w(y),C=async()=>{let Z=h.value.trim();Z===""||Z===Y.name||(v(),await k.runTask(S("msg.renaming",{name:Y.name}),async()=>{await q("rename",{from:se,to:he(k.path,Z)}),await Le()}))}}),E(ge,()=>k.runTask(S("msg.deleting",{name:Y.name}),async()=>{await q("remove",{path:se,recursive:Y.isDir===!0}),await Le(),l(S("msg.deleted",{name:Y.name}))}),Y),ge},re=Y=>{if(z.textContent="",k.path!==""&&k.path!=="/"&&/^[A-Za-z]:[\\/]?$/.test(k.path)===!1){let fe=x(Zn,S("list.parentDir"),"","up");fe.addEventListener("click",()=>{let ge=y==="local"?zp(k.path):Nc(k.path);ge!==null&&k.loadDir(ge)}),z.appendChild(fe)}let se=Array.isArray(Y)?Y:[];if(se.length===0){let fe=document.createElement("div");fe.className="tt_addMenuTitle",fe.textContent=S("list.emptyDir"),z.appendChild(fe);return}let be=500;for(let fe of se.slice(0,be))fe===null||typeof fe!="object"||typeof fe.name!="string"||fe.name===""||z.appendChild(de(fe));if(se.length>be){let fe=document.createElement("div");fe.className="tt_addMenuTitle",fe.textContent=S("list.truncated",{rest:se.length-be,total:se.length}),z.appendChild(fe)}};return k.loadDir=async Y=>{try{let se=await q("list",{path:Y??k.path});k.path=typeof se.path=="string"&&se.path!==""?se.path:k.path,W.value=k.path;let be=Array.isArray(se.entries)?se.entries.length:0;re(se.entries),J.textContent=S("list.itemCount",{count:be}),l(k.path)}catch(se){l(String(se&&se.message?se.message:se),"error")}},k.runTask=ee,k.setBusy=$,p[y]=k,L.addEventListener("click",()=>{k.runTask(S("list.loading"),()=>k.loadDir(k.path))}),I.addEventListener("click",()=>{k.busy||_||(h.placeholder=S("placeholder.newDirName"),h.value="",w(y),C=async()=>{let Y=h.value.trim();Y!==""&&(v(),await k.runTask(S("msg.creatingDir",{name:Y}),async()=>{await q("mkdir",{path:he(k.path,Y),parents:!0}),await k.loadDir(k.path)}))})}),W.addEventListener("keydown",Y=>{if(Y.key!=="Enter"||(Y.preventDefault(),k.busy||_))return;let se=W.value.trim();se!==""&&k.runTask(S("list.loading"),()=>k.loadDir(se))}),R},d=document.createElement("div");d.className="tt_sftpEditor",d.style.display="none";let h=document.createElement("input");h.type="text",h.className="tt_cardInput",h.spellcheck=!1,h.autocomplete="off";let f=document.createElement("button");f.type="button",f.className="tt_toolBtn",f.textContent=S("btn.ok");let g=document.createElement("button");g.type="button",g.className="tt_toolBtn",g.textContent=S("btn.cancel"),d.appendChild(h),d.appendChild(f),d.appendChild(g);let C=null,v=()=>{d.style.display="none",h.value="",C=null};f.addEventListener("click",()=>{C?.()}),g.addEventListener("click",v),h.addEventListener("keydown",y=>{y.key==="Enter"?(y.preventDefault(),C?.()):y.key==="Escape"&&(y.stopPropagation(),v())});let x=(y,T,k,R)=>{let U=document.createElement("button");U.type="button",U.className="tt_sftpRow";let G=document.createElement("span");G.className="tt_sftpIcon",G.innerHTML=y,R!==void 0&&(G.dataset.kind=R);let J=document.createElement("span");if(J.className="tt_sftpName",J.textContent=T,J.title=T,U.appendChild(G),U.appendChild(J),k!==""){let X=document.createElement("span");X.className="tt_sftpMeta",X.textContent=k,U.appendChild(X)}return U},b=(y,T,k,R)=>{let U=document.createElement("button");U.type="button",U.className="tt_sftpAct",U.innerHTML=T,U.title=k,U.addEventListener("click",G=>{G.stopPropagation(),R()}),y.appendChild(U)},E=(y,T,k)=>{let R=document.createElement("button");R.type="button",R.className="tt_sftpAct",R.innerHTML=Er,R.title=k.isDir?S("btn.deleteEntryDir",{name:k.name}):S("btn.deleteEntry",{name:k.name});let U=null;R.addEventListener("click",G=>{if(G.stopPropagation(),U!==null){clearTimeout(U),U=null,R.innerHTML=Er,delete R.dataset.danger,T();return}R.textContent=S("btn.confirm"),R.dataset.danger="",U=setTimeout(()=>{U=null,R.innerHTML=Er,delete R.dataset.danger},4e3)}),y.appendChild(R)},O=(y,T)=>p.remote.runTask(S("msg.downloading",{name:y.name}),async()=>{P.reset();let k;try{k=await Fc("/api/dsh-tty/sftp/download",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...e,path:T})},(R,U)=>{P.set(R,U)},Jt.maxDownloadMb,R=>P.setCancel(R))}catch(R){if(Vn(R)){P.reset(),l(S("msg.downloadCanceled",{name:y.name}));return}throw P.fail(S("error.downloadFailed")),R}P.done(S("status.done")),Wc(k,y.name),setTimeout(()=>P.reset(),1500),l(S("msg.downloaded",{name:y.name,size:tt(k.size)||String(k.size)+" B"}))}),B=c("local",S("meta.local")),H=c("remote",S("meta.remote"));p.local.wrap=B,p.remote.wrap=H;let M=document.createElement("div");M.className="tt_sftpDual",M.appendChild(B),M.appendChild(H),a.appendChild(M),a.appendChild(d);let K=document.createElement("div");K.className="tt_sftpFoot";let P=Hc();K.appendChild(P.el),K.appendChild(u),a.appendChild(K);let D=async(y,T)=>{let k=!1;P.setCancel(()=>{k||(k=!0,fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"cancel",job:y})}).catch(()=>{}))});try{for(;;){await new Promise(J=>setTimeout(J,400));let R=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"status",job:y})}),U=await R.json().catch(()=>({}));if(!R.ok||U.ok!==!0){if(k)return"canceled";throw new Error(String(U.error||"HTTP "+R.status))}let G=U.job;if(G===null||typeof G!="object")throw new Error(S("error.invalidTaskState"));if(G.state==="running"){let J=typeof G.current=="string"&&G.current!==""?G.current:T;l(S("msg.transferring",{name:J}),"busy"),Number.isFinite(G.total)&&G.total>0?P.set(Number(G.bytes)||0,G.total):P.pulse(Number(G.bytes)||0);continue}if(G.state==="canceled")return"canceled";if(G.state!=="done")throw new Error(String(G.error||S("error.transferFailed")));return"done"}}finally{P.setCancel(null)}},F=io(),N=F===null?420:Math.round(F.height*.56);Oc(a,S("panel.sftpDual",{label:t}),N,s),p.local.loadDir(""),p.remote.loadDir("")}var Ft=null,Tt=null;function Pc(){return Tt!==null&&Rn(Tt.ownerKey,Re)?Tt.ownerKey:yr(void 0,Re)}var Bc=(e=Pc())=>Ft!==null||Tt!==null&&Tt.ownerKey===e;function Oc(e,t,r,s){let a=yr(s,Re),i=gt!==null&>.ownerKey===a;if(ce!==null&&!qe&&ct!==null&&!i)try{let o=Sc({title:t,side:"bottom",size:r,min:200,ownerSid:a,onClose:()=>Br(a)});o.element.appendChild(e),Tt=o;return}catch(o){console.warn("[dsh-tty] SFTP \u6302\u5230\u7EC8\u7AEF\u6302\u8F7D\u4F4D\u5931\u8D25\uFF0C\u56DE\u9000\u5BF9\u8BDD\u6846\uFF1A"+(o instanceof Error?o.message:String(o)))}let n=document.createElement("div");n.className="tt_sshBackdrop",n.appendChild(e),n.addEventListener("mousedown",o=>{o.target===n&&Br()}),document.body.appendChild(n),Ft=n}var li=null;function Up(){let e=li;if(li=null,e!==null)try{e.click()}catch{}}function jp(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 Ic(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 Nc(e){let t=String(e).replace(/\/+$/,""),r=t.lastIndexOf("/");return r<=0?"/":t.slice(0,r)}function zp(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 a=r[2];if(a==="")return null;let i=Math.max(a.lastIndexOf("\\"),a.lastIndexOf("/"));return i<=0?r[1]+"\\":r[1]+a.slice(0,i)}if(t.startsWith("\\\\")||t.startsWith("//")){let a=t.slice(2);if(a.split(/[\\/]/).filter(o=>o!=="").length<=2)return null;let n=Math.max(a.lastIndexOf("\\"),a.lastIndexOf("/"));return t.slice(0,2)+a.slice(0,n)}let s=t.lastIndexOf("/");return s<=0?s===0?"/":null:t.slice(0,s)}function Zr(e,t){return e.endsWith("/")?e+t:e+"/"+t}function Hc(){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 a=document.createElement("button");a.type="button",a.className="tt_sftpCancel",a.title=S("btn.cancelTransfer"),a.textContent="\u2715",a.style.display="none";let i=null;a.addEventListener("click",p=>{p.stopPropagation();let c=i;c!==null&&(a.disabled=!0,c())}),e.appendChild(t),e.appendChild(s),e.appendChild(a);let n=p=>{s.textContent=p},o="",u=-1,l=p=>{p!==o&&(o=p,s.textContent=p)},_=p=>{let c=Math.round(p);c!==u&&(u=c,r.style.width=c+"%")},m=()=>{i=null,li===a&&(li=null),a.style.display="none",a.disabled=!1};return{el:e,reset(){delete e.dataset.active,delete e.dataset.state,o="",u=-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,li=a,a.disabled=!1,a.style.display=""},set(p,c){e.dataset.active="",delete e.dataset.state;let d=Date.now();if(this._last!==void 0&&d>this._lastAt){let h=(p-this._last)/((d-this._lastAt)/1e3);this._rate=this._rate===void 0?h:this._rate*.7+h*.3}if(this._last=p,this._lastAt=d,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?Xr(this._rate):"";l(Math.round(h)+"%"+(f!==""?" \xB7 "+f:""))}else{r.style.width="";let h=this._rate!==void 0&&this._rate>=0?Xr(this._rate):"";l(tt(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 d=this._rate!==void 0&&this._rate>=0?Xr(this._rate):"";l((Number.isFinite(p)?tt(p):"\u2026")+(d!==""?" \xB7 "+d:""))},done(p){e.dataset.active="",e.dataset.state="done",r.style.width="100%",u=100,m(),l(p!==void 0&&p!==""?p:S("status.done"))},fail(p){e.dataset.active="",e.dataset.state="error",m(),l(p!==void 0&&p!==""?p:S("status.failed"))},text(p){delete e.dataset.state,p===void 0||p===""?(e.dataset.active="",o="",s.textContent=""):(e.dataset.active="",r.style.width="",u=-1,l(p))}}}async function Fc(e,t,r,s=0,a=null){let i=s>0?s*1024*1024:0,n=typeof AbortController=="function"?new AbortController:null,o=!1;n!==null&&(t={...t,signal:n.signal},typeof a=="function"&&a(()=>{o=!0,n.abort()}));let u=await fetch(e,t);if(!u.ok){let d="HTTP "+u.status;try{let h=await u.json();h!==null&&typeof h=="object"&&typeof h.error=="string"&&(d=h.error)}catch{}throw new Error(d)}let l=Number(u.headers.get("content-length")),_=Number.isFinite(l)&&l>0;if(i>0&&_&&l>i){try{await u.body?.cancel()}catch{}throw new Error(S("error.downloadTooBig",{size:tt(i)}))}let m=u.body;if(m===null||typeof m.getReader!="function"){let d=await u.blob();if(i>0&&d.size>i)throw new Error(S("error.downloadTooBig",{size:tt(i)}));return _&&r(l,l),d}let w=m.getReader(),p=[],c=0;try{for(;;){let{done:d,value:h}=await w.read();if(d)break;if(h!==void 0&&h.byteLength>0){if(c+=h.byteLength,i>0&&c>i){try{await w.cancel()}catch{}throw new Error(S("error.downloadTooBig",{size:tt(i)}))}p.push(h),r(c,_?l:NaN)}}}catch(d){if(o||d!==null&&typeof d=="object"&&d.name==="AbortError"){try{await w.cancel()}catch{}throw new Pr}throw d}return new Blob(p,{type:"application/octet-stream"})}var Pr=class extends Error{constructor(){super(S("msg.canceled")),this.name="TransferCanceledError"}};function Vn(e){return e instanceof Pr}function Wc(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 $p(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=[],a=Jt.maxUploadFiles,i=Jt.maxUploadMb>0?Jt.maxUploadMb*1024*1024:0,n=()=>a>0&&s.length>=a,o=0,u=(l,_)=>new Promise(m=>{if(n()){m();return}if(l.isFile===!0){l.file(c=>{i>0&&o+(c.size??0)>i?s._limitExceeded=!0:(s.push({relPath:_+l.name,file:c}),o+=c.size??0),m()},()=>m());return}if(l.isDirectory!==!0){m();return}let w=l.createReader(),p=()=>{w.readEntries(async c=>{if(c.length===0){m();return}for(let d of c){if(n())break;await u(d,_+l.name+"/")}if(n()){m();return}p()},()=>m())};p()});for(let l of r)await u(l,"");return s}function ks(e,t){let r=yr(t,Re);if(Bc(r))return;let s=e!==null&&typeof e=="object"?e:{},a={};if(typeof s.name=="string"&&s.name!=="")a.name=s.name;else{for(let I of["host","username","auth","keyPath","passphrase","password"])typeof s[I]=="string"&&s[I]!==""&&(a[I]=s[I]);let L=Number(s.port);Number.isInteger(L)&&L>=1&&L<=65535&&(a.port=L),s.agentForward===!0&&(a.agentForward=!0)}let i=a.name??(a.username!==void 0?a.username+"@"+String(a.host??""):String(a.host??""));if(Ec==="dual"){Wp(a,i,r);return}let n=document.createElement("div");n.className="tt_sftpCard";let o=document.createElement("div");o.className="tt_sftpTitleRow";let u=document.createElement("div");u.className="tt_sshTitle",u.innerHTML=ci+"<span></span>",u.lastElementChild.textContent="SFTP \xB7 "+i;let l=document.createElement("button");l.type="button",l.className="tt_close",l.title=S("btn.close"),l.innerHTML=ys,l.addEventListener("click",()=>Br(r)),o.appendChild(u),o.appendChild(l),n.appendChild(o);let _=document.createElement("div");_.className="tt_sftpBar";let m=document.createElement("input");m.type="text",m.className="tt_sftpPath",m.placeholder=S("placeholder.remotePath"),m.spellcheck=!1,m.autocomplete="off";let w=document.createElement("button");w.type="button",w.className="tt_toolBtn",w.innerHTML=eo+"<span>"+S("btn.refresh")+"</span>";let p=document.createElement("button");p.type="button",p.className="tt_toolBtn",p.innerHTML=ac+"<span>"+S("btn.mkdir")+"</span>";let c=document.createElement("button");c.type="button",c.className="tt_toolBtn",c.innerHTML=Zf+"<span>"+S("btn.upload")+"</span>",c.title=S("btn.uploadTitle");let d=document.createElement("input");d.type="file",d.multiple=!0,d.style.display="none",_.appendChild(m),_.appendChild(w),_.appendChild(p),_.appendChild(c),n.appendChild(_),n.appendChild(d);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 g=document.createElement("button");g.type="button",g.className="tt_toolBtn",g.textContent=S("btn.ok");let C=document.createElement("button");C.type="button",C.className="tt_toolBtn",C.textContent=S("btn.cancel"),h.appendChild(f),h.appendChild(g),h.appendChild(C),n.appendChild(h);let v=null,x=()=>{h.style.display="none",v=null};g.addEventListener("click",()=>{v?.()}),C.addEventListener("click",x),f.addEventListener("keydown",L=>{L.key==="Enter"?(L.preventDefault(),v?.()):L.key==="Escape"&&(L.stopPropagation(),x())});let b=document.createElement("div");b.className="tt_sftpList",n.appendChild(b);let E=document.createElement("div");E.className="tt_sftpFoot";let O=document.createElement("div");O.className="tt_sftpStatus";let B=Hc();E.appendChild(B.el),E.appendChild(O),n.appendChild(E);let H={path:"",busy:!1},M=(L,I)=>{O.textContent=L,I===void 0?delete O.dataset.state:O.dataset.state=I},K=L=>{H.busy=L;for(let I of[w,p,c])I.disabled=L;m.disabled=L},P=async(L,I)=>{let z=await fetch("/api/dsh-tty/sftp/"+L,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...a,...I})}),$=await z.json().catch(()=>({}));if(!z.ok||$.ok!==!0)throw new Error(String($.error||"HTTP "+z.status));return $},D=async(L,I)=>{if(!H.busy){K(!0),M(L,"busy");try{await I()}catch(z){M(String(z&&z.message?z.message:z),"error")}finally{K(!1)}}},F=(L,I,z,$)=>{let q=document.createElement("button");q.type="button",q.className="tt_sftpRow";let ee=document.createElement("span");ee.className="tt_sftpIcon",ee.innerHTML=L,$!==void 0&&(ee.dataset.kind=$);let he=document.createElement("span");if(he.className="tt_sftpName",he.textContent=I,he.title=I,q.appendChild(ee),q.appendChild(he),z!==""){let de=document.createElement("span");de.className="tt_sftpMeta",de.textContent=z,q.appendChild(de)}return q},N=(L,I,z,$)=>{let q=document.createElement("button");q.type="button",q.className="tt_sftpAct",q.innerHTML=I,q.title=z,q.addEventListener("click",ee=>{ee.stopPropagation(),$()}),L.appendChild(q)},y=(L,I,z)=>{let $=document.createElement("button");$.type="button",$.className="tt_sftpAct",$.innerHTML=Er,$.title=I.isDir?S("btn.deleteEntryDir",{name:I.name}):S("btn.deleteEntry",{name:I.name});let q=null;$.addEventListener("click",ee=>{if(ee.stopPropagation(),!H.busy){if(q!==null){clearTimeout(q),q=null,$.innerHTML=Er,delete $.dataset.danger,D(S("msg.deleting",{name:I.name}),async()=>{await P("remove",{path:z,recursive:I.isDir===!0}),await k(H.path),M(S("msg.deleted",{name:I.name}))});return}$.textContent=S("btn.confirm"),$.dataset.danger="",q=setTimeout(()=>{q=null,$.innerHTML=Er,delete $.dataset.danger},4e3)}}),L.appendChild($)},T=L=>{if(b.textContent="",H.path!==""&&H.path!=="/"){let $=F(Zn,S("list.parentDir"),"","up");$.addEventListener("click",()=>{D(S("list.loading"),()=>k(Nc(H.path)))}),b.appendChild($)}let I=Array.isArray(L)?L:[];if(I.length===0){let $=document.createElement("div");$.className="tt_addMenuTitle",$.textContent=S("list.emptyDir"),b.appendChild($);return}let z=500;for(let $ of I.slice(0,z)){if($===null||typeof $!="object"||typeof $.name!="string"||$.name==="")continue;let q=Zr(H.path,$.name),ee=[];$.isDir===!0?ee.push(S("meta.dir")):ee.push(tt(Number($.size))||"\u2014");let he=Ic(Number($.mtime));he!==""&&ee.push(he);let de=F($.isDir?ci:$.isSymlink?nc:sc,$.name,ee.join(" \xB7 "),$.isDir===!0?"dir":$.isSymlink===!0?"link":"file");$.isDir===!0?de.addEventListener("click",re=>{re.target instanceof Element&&re.target.closest(".tt_sftpAct")!==null||D(S("list.loading"),()=>k(q))}):(de.addEventListener("click",re=>{re.target instanceof Element&&re.target.closest(".tt_sftpAct")!==null||R($,q)}),N(de,oc,S("btn.download",{name:$.name}),()=>{R($,q)})),N(de,Qn,S("btn.rename",{name:$.name}),()=>{f.placeholder=S("placeholder.newName"),f.value=$.name,h.style.display="",f.focus(),f.select(),v=async()=>{let re=f.value.trim();re===""||re===$.name||(x(),await D(S("msg.renaming",{name:$.name}),async()=>{await P("rename",{from:q,to:Zr(H.path,re)}),await k(H.path)}))}}),y(de,$,q),b.appendChild(de)}if(I.length>z){let $=document.createElement("div");$.className="tt_addMenuTitle",$.textContent=S("list.truncated",{rest:I.length-z,total:I.length}),b.appendChild($)}},k=async L=>{try{let I=await P("list",{path:L??H.path});H.path=typeof I.path=="string"&&I.path!==""?I.path:"/",m.value=H.path;let z=Array.isArray(I.entries)?I.entries.length:0;T(I.entries),M(H.path+" \u2014 "+S("list.itemCount",{count:z}))}catch(I){M(String(I&&I.message?I.message:I),"error")}},R=(L,I)=>D(S("msg.downloading",{name:L.name}),async()=>{B.reset();let z;try{z=await Fc("/api/dsh-tty/sftp/download",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...a,path:I})},($,q)=>{B.set($,q)},Jt.maxDownloadMb,$=>B.setCancel($))}catch($){if(Vn($)){B.reset(),M(S("msg.downloadCanceled",{name:L.name}));return}throw B.fail(S("error.downloadFailed")),$}B.done(S("status.done")),Wc(z,L.name),setTimeout(()=>B.reset(),1500),M(S("msg.downloaded",{name:L.name,size:tt(z.size)||String(z.size)+" B"}))}),U=(L,I,z,$,q)=>new Promise((ee,he)=>{let de=jp(JSON.stringify({...a,path:Zr(H.path,I)})),re=new XMLHttpRequest;q.abort=()=>{q.stopped=!0,re.abort()},re.open("POST","/api/dsh-tty/sftp/upload"),re.setRequestHeader("x-dsh-sftp-meta",de);let Y=$>1?String(z)+"/"+String($)+" ":"";M(S("msg.uploadingName",{name:Y+I}),"busy"),re.upload.addEventListener("progress",fe=>{fe.lengthComputable?B.set(fe.loaded,fe.total):B.pulse(0)});let se=!1,be=fe=>{se||(se=!0,fe===null?ee():he(fe))};re.addEventListener("load",()=>{if(re.status===200){$===1&&B.done(S("msg.uploadDone")),be(null);return}if(q.stopped)return;B.fail(S("error.uploadFailed"));let fe="HTTP "+re.status;try{let ge=JSON.parse(re.responseText);ge!==null&&typeof ge=="object"&&typeof ge.error=="string"&&(fe=ge.error)}catch{}be(new Error(fe))}),re.addEventListener("error",()=>{if(q.stopped){be(new Pr);return}B.fail(S("error.uploadFailed")),be(new Error(S("error.networkError")))}),re.addEventListener("abort",()=>{be(new Pr)}),re.send(L)}),G=async L=>D(S("msg.uploading"),async()=>{let I=Jt;if(I.maxUploadFiles>0&&L.length>I.maxUploadFiles){M(S("error.uploadCountExceeded",{max:I.maxUploadFiles,count:L.length}),"error"),B.fail(S("status.overLimit"));return}let z=I.maxUploadMb>0?I.maxUploadMb*1024*1024:0,$=L.find(re=>z>0&&(re.file?.size??0)>z);if($!==void 0){M(S("error.uploadTooBig",{size:tt(z),name:String($.relPath??"")}),"error"),B.fail(S("status.overLimit"));return}if(L._limitExceeded===!0){M(S("error.uploadTotalTooBig"),"error"),B.fail(S("status.overLimit"));return}let q=new Set;for(let re of L){let Y=re.relPath.lastIndexOf("/");if(Y<=0)continue;let se=re.relPath.slice(0,Y);q.has(se)||(q.add(se),await P("mkdir",{path:Zr(H.path,se),parents:!0}).catch(()=>{}))}B.reset();let ee={stopped:!1,abort:null};B.setCancel(()=>ee.abort?.());let he=0,de=0;try{for(let re of L){if(ee.stopped)break;he+=1,ee.abort=null;try{await U(re.file,re.relPath,he,L.length,ee),de+=1}catch(Y){if(Vn(Y)||ee.stopped)break;throw Y}}}finally{B.setCancel(null)}if(ee.stopped){B.reset(),M(S("msg.uploadCanceled",{done:de,total:L.length})),await k(H.path);return}B.done(S("status.allDone")),setTimeout(()=>B.reset(),1500),M(S("msg.uploadDoneCount",{count:L.length})),await k(H.path)});w.addEventListener("click",()=>{D(S("list.loading"),()=>k(H.path))}),p.addEventListener("click",()=>{H.busy||(f.placeholder=S("placeholder.newDirName"),f.value="",h.style.display="",f.focus(),v=async()=>{let L=f.value.trim();L!==""&&(x(),await D(S("msg.creatingDir",{name:L}),async()=>{await P("mkdir",{path:Zr(H.path,L)}),await k(H.path)}))})}),c.addEventListener("click",()=>{H.busy===!1&&d.click()}),d.addEventListener("change",()=>{let L=[...d.files??[]].map(I=>({relPath:I.name,file:I}));d.value="",L.length>0&&G(L)});let J=0,X=L=>{L?b.dataset.drag="":delete b.dataset.drag};n.addEventListener("dragenter",L=>{L.preventDefault(),J+=1,X(!0)}),n.addEventListener("dragover",L=>{L.preventDefault()}),n.addEventListener("dragleave",()=>{J=Math.max(0,J-1),J===0&&X(!1)}),n.addEventListener("drop",L=>{L.preventDefault(),J=0,X(!1),!H.busy&&$p(L.dataTransfer).then(I=>{(I.length>0||I._limitExceeded===!0)&&G(I)})}),m.addEventListener("keydown",L=>{if(L.key!=="Enter"||(L.preventDefault(),H.busy))return;let I=m.value.trim();I!==""&&D(S("list.loading"),()=>k(I))});let W=io();Oc(n,"SFTP \xB7 "+i,W===null?340:Math.round(W.height*.46),r),D(S("status.connectingEllipsis"),()=>k(""))}function Br(e){let t=e===void 0?Pc():e,r=Ft,s=Tt!==null&&Tt.ownerKey===t?Tt:null;r===null&&s===null||(Up(),Ft=null,s!==null&&(Tt=null),r!==null&&r.remove(),s!==null&&s.dispose())}function Uc(){if(Je===null)return;let e=Je.style.display==="none"||Je.style.display==="";Je.style.display=e?"":"none";let t=ce!==null?ce.querySelector("[data-act=search]"):null;t!==null&&(e?t.dataset.on="":delete t.dataset.on),e&&Je.focus()}var qp={matchBackground:"#3d2b00",matchBorder:"#8a5a00",activeMatchBackground:"#b06a00",activeMatchBorder:"#ffb84d",matchOverviewRuler:"#8a5a00",activeMatchColorOverviewRuler:"#ffb84d"};function Kp(e){let t=dt();if(t===void 0||t.search===void 0)return;let r=Je.value;if(r==="")return;let s={decorations:qp};e?t.search.findPrevious(r,s):t.search.findNext(r,s)}function Vl(){di||ce===null&&!to()||ir!==null||(ir=setTimeout(()=>{ir=null,gs()},si),si=Math.min(si*2,5e3))}function yi(e){return e!==null&&typeof e=="object"&&e.persist===!0&&typeof e.persistName=="string"&&e.persistName!==""}function Yn(e){return yi(e)||e!==null&&typeof e=="object"&&typeof e.command=="string"&&e.command!==""}function Gp(){return Yt==="tmux"?{t:"spawn",cwd:Un(),persist:!0,persistName:oo()}:{t:"spawn",cwd:Un()}}async function jc(){if(!In){In=!0;try{await Vp()}finally{In=!1}}}var In=!1;async function Vp(){if(await ao(),ce===null){await Jp();return}let e=fp(),t=up();if(![...ue.values()].some(n=>n.embedded!==!0)){if(e.length>0||t.length>0){Me({t:"sessions"});let n=await us("sessions",4e3),o=new Map;if(n!==null&&Array.isArray(n.list))for(let l of n.list)l!==null&&typeof l=="object"&&l.attachable===!0&&o.set(l.sid,l);let u=new Set;for(let l of e){if(o.has(l.sid))yp(l);else if(Yn(l.spawnSpec))ql(l);else continue;yi(l.spawnSpec)&&u.add(l.spawnSpec.persistName)}for(let l of t){let _=l.spawnSpec.persistName;u.has(_)||(ql(l),u.add(_))}Xt()}if(![...ue.values()].some(n=>n.embedded!==!0)){if(await ms())return;ui()}return}let r=[...ue.values()].filter(n=>!n.exited&&(n.embedded!==!0||n.spawned===!0)),s=r.filter(n=>Yn(n.spawnSpec)),a=null;if(s.length>0){Me({t:"sessions"});let n=await us("sessions",4e3),o=new Set((n!==null&&Array.isArray(n.list)?n.list:[]).map(u=>u?.sid).filter(u=>typeof u=="string"));a=s.filter(u=>!o.has(u.sid));for(let u of a)fs(u.sid)}let i=a!==null?new Set(a.map(n=>n.sid)):new Set;for(let n of r)i.has(n.sid)||Me({t:"attach",sid:n.sid})}function Yp(){Ee!==null&&(Ee.readyState===WebSocket.OPEN||Ee.readyState===WebSocket.CONNECTING)||gs()}async function Jp(){let e=[...ue.values()].filter(s=>s.embedded===!0&&!s.exited);if(e.length===0)return;Me({t:"sessions"});let t=await us("sessions",4e3),r=new Set((t!==null&&Array.isArray(t.list)?t.list:[]).map(s=>s?.sid).filter(s=>typeof s=="string"));for(let s of e)s.spawned===!0&&(r.has(s.sid)?Me({t:"attach",sid:s.sid}):Yn(s.spawnSpec)?yc(s):(s.exited=!0,s.live=!1,Sr(s,S("status.ended"),S("btn.clickRerun"),"exited")))}function gs(){if(Ee!==null){try{Ee.close()}catch{}Ee=null}di=!1,clearTimeout(ir),ir=null,Zi=!0,Qi(S("status.connectingEllipsis"),"");try{Ee=new WebSocket(Ff())}catch(e){Zi=!1,Qi(S("error.connectFailed",{error:e.message}),"error"),Vl();return}Ee.onopen=()=>{Zi=!1,si=1e3,mt=null,Qi(S("status.connected"),"connected");for(let e of[...Hn])Hn.delete(e),ue.has(e.tab.sid)&&Me(e.frame);jc()},Ee.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:"";Pn(r,t.kind==="ssh"?S("status.connectedSsh",{target:s!==""?s+" ":""}):S("status.connectedPid",{pid:t.pid}),"connected");let a=ue.get(r);if(a!==void 0){if(a.exited=!1,a.spawned=!0,a.live=!0,a.errored=!1,a.target=s,a.persistTmux=t.persist===!0,t.kind==="ssh"&&s!==""&&!a.label&&(a.label=s,it()),sr(),Bn(r),Sr(a,""),Or(a),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(()=>mc(150))}pi(),lp(r),Xt()}}else if(t.t==="sessions")wp(t.list);else if(t.t==="data"){let s=ue.get(r);s!==void 0&&s.term!==null&&(s.term.write(String(t.d??"")),r_())}else if(t.t==="exit"){let s=ue.get(r);if(s!==void 0){s.exited=!0,s.live=!1,s.stats=null,r===Re&&lr();let a=t.code!==null&&t.code!==void 0?"code="+t.code:"",i=t.signal!==null&&t.signal!==void 0?"signal="+t.signal:"";Pn(r,S("status.exitedWith",{detail:[a,i].filter(Boolean).join(" ")}),""),sr(),Bn(r),Sr(s,S("status.exited"),S("btn.clickReopen"),"exited"),pi(),Xt()}}else if(t.t==="stats")try{let s=ue.get(r);if(s!==void 0){let a=t.stats;s.stats=Hl(a)?a:null,s.statsAt=Date.now(),r===Re&&lr()}}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==="error")if(Pn(r,S("status.error",{message:String(t.m??"")}),"error"),typeof r=="string"){let s=ue.get(r);s!==void 0&&(s.live||(s.errored=!0),sr(),Bn(r),Sr(s,S("status.errored"),S("status.retryHint",{message:String(t.m??"")}),"error"))}else Xp(S("btn.clickRetry"))},Ee.onclose=()=>{if(Zi=!1,!di){Qi(S("status.disconnectedReconnecting"),"error");for(let e of ue.values())e.exited||Sr(e,S("status.disconnected"),S("status.reconnecting"),"info");Vl()}},Ee.onerror=()=>{}}function Xp(e){Lr!==null&&(Lr.textContent=e)}function Jn(){(ce===null||qe)&&Xn()}var ts="DSH_TTY_ALLOW_PROXY_COMMAND";function Zp(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 lo(){return typeof navigator<"u"&&navigator.clipboard!==void 0&&typeof navigator.clipboard.writeText=="function"}async function Qp(e){if(lo())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||bi(S("error.copyFailed"),"error"),r}async function e_(e){if(lo()&&typeof navigator.clipboard.readText=="function")try{let s=await navigator.clipboard.readText();return s!==""&&Me({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!==""&&Me({t:"input",sid:e.sid,d:s})}catch{r=!1}return t.remove(),r||bi(S("error.pasteFailed"),"error"),r}function Xn(){if(ce!==null){qe&&zc();return}mi(),ce=document.createElement("div"),ce.className="tt_modalBackdrop",ce.innerHTML='<div class="tt_modal"><div class="tt_header"><span class="tt_titleIcon">'+ws+'</span><div class="tt_tabs"></div><div class="tt_status"><span class="tt_statusDot"></span><span class="tt_statusText">'+S("status.initializing")+'</span></div><input class="tt_searchInput" style="display:none" placeholder="'+S("placeholder.search")+'" /><span class="tt_toolGroup"><button class="tt_toolBtn tt_iconBtn" data-act="search" title="'+S("btn.searchTitle")+'">'+zf+'</button><button class="tt_toolBtn tt_iconBtn" data-act="clear" title="'+S("btn.clearTitle")+'">'+$f+'</button><button class="tt_toolBtn tt_iconBtn" data-act="copy" title="'+S("btn.copyTitle")+'">'+qf+'</button><button class="tt_toolBtn tt_iconBtn" data-act="paste" title="'+S("btn.pasteTitle")+'">'+Kf+'</button></span><span class="tt_winGroup"><button class="tt_min" title="'+S("btn.minimizeTitle")+'">'+Jf+'</button><button class="tt_close" title="'+S("btn.closePanelTitle")+'">'+ys+'</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><div class="tt_overlay"></div></div></div></div>',document.body.appendChild(ce),os=ce.querySelector(".tt_status"),rr=ce.querySelector(".tt_statusText"),or=ce.querySelector(".tt_statusDot"),kt=ce.querySelector(".tt_tabs"),ei=ce.querySelector(".tt_connbar"),ti=ce.querySelector(".tt_connDot"),as=ce.querySelector(".tt_connTarget"),lt=ce.querySelector(".tt_connBadge"),ri=ce.querySelector(".tt_connActions"),ct=ce.querySelector(".tt_work"),rt=ce.querySelector(".tt_body"),_t=ce.querySelector(".tt_statsBar"),Cs(),mt=null,fc(),Lr=ce.querySelector(".tt_body > .tt_overlay"),Je=ce.querySelector(".tt_searchInput"),Lr.addEventListener("click",()=>{Lr.textContent="",gs()});let e=ce.querySelector("[data-act=search]");e.addEventListener("click",()=>{Uc(),Je.style.display!=="none"&&Je.focus()}),e.dataset.on="",Je.addEventListener("keydown",t=>{t.key==="Enter"?(t.preventDefault(),Kp(t.shiftKey)):t.key==="Escape"&&(t.stopPropagation(),Je.style.display="none")}),ce.querySelector("[data-act=clear]").addEventListener("click",()=>{let t=dt();t!==void 0&&t.term!==null&&t.term.clear()}),ce.querySelector("[data-act=copy]").addEventListener("click",()=>{let t=dt();if(t===void 0||t.term===null)return;let r=t.term.getSelection();r!==""&&Qp(r)}),ce.querySelector("[data-act=paste]").addEventListener("click",()=>{let t=dt();t!==void 0&&e_(t)}),ce.querySelector(".tt_min").addEventListener("click",()=>{vs()}),ce.querySelector(".tt_close").addEventListener("click",()=>{_i()}),ce.addEventListener("mousedown",t=>{t.target===ce&&vs()}),document.addEventListener("keydown",$c),ii=new ResizeObserver(()=>{qe||(rs(),pp(dt()))}),ii.observe(rt),it(),sr(),Ee!==null&&Ee.readyState===WebSocket.OPEN?jc():gs()}function t_(){Ve=document.createElement("div"),Ve.className="tt_dock",Ve.title=S("btn.restoreDock"),Ve.innerHTML='<span class="tt_dockTitle">'+ws+"<span>"+S("panel.title")+'</span><span class="tt_dockCount"></span></span><span class="tt_dockStatus"></span><span class="tt_dockDot"></span><button class="tt_dockClose" title="'+S("btn.closePanelTitle")+'">\u2715</button>',ls=Ve.querySelector(".tt_dockCount"),Dr=Ve.querySelector(".tt_dockStatus"),ar=Ve.querySelector(".tt_dockDot");let e=[...ue.values()].filter(t=>!t.exited).length;ls.textContent=ue.size>0?"\xB7 "+e+"/"+ue.size:"",rr!==null&&(Dr.textContent=rr.textContent),or!==null&&(ar.dataset.state=or.dataset.state??""),Ve.addEventListener("click",t=>{if(t.target.closest(".tt_dockClose")!==null){t.stopPropagation(),_i();return}zc()}),document.body.appendChild(Ve)}function vs(){ce===null||qe||(Et(),Gt(),qe=!0,Ft!==null&&(Ft.style.display="none"),Je!==null&&(Je.style.display="none"),ce.dataset.minimized="",pc(),wi(),lr(),document.querySelector("[data-dsh-tty-entry]")!==null?pi():(t_(),Ve.classList.add("tt_dockCompact")))}function pi(){let e=document.querySelector("[data-dsh-tty-entry]");if(e===null)return;let t=e.querySelector(".tt_sidebarEntryBadge");if(!qe){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=S("status.minimized");let r=[...ue.values()].filter(a=>!a.exited).length;t.querySelector(".tt_sidebarBadgeCount").textContent=r+"/"+ue.size;let s=t.querySelector(".tt_sidebarBadgeDot");s!==null&&or!==null&&(s.dataset.state=or.dataset.state??"")}function r_(){if(!qe)return;let e=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot")??ar;e!==null&&(e.dataset.active="",clearTimeout(cs),cs=setTimeout(()=>{delete e.dataset.active},900))}function zc(){if(ce===null||!qe)return;qe=!1,delete ce.dataset.minimized,Ft!==null&&(Ft.style.display=""),clearTimeout(cs),Ve!==null&&(Ve.remove(),Ve=null),ls=null,Dr=null,ar=null,pi(),fc(),wi(),lr();let e=dt();if(e!==void 0&&e.fit!==void 0){try{e.fit.fit()}catch{}e.spawned&&!e.exited&&Or(e)}e!==void 0&&e.term!==null&&e.term.focus()}function _i(){if(ce===null)return;ai(!0);let e=to();if(di=!e,qe=!1,Et(),is(),ps(),Gt(),Br(),clearTimeout(cs),clearTimeout(ir),ir=null,si=1e3,Ve!==null&&(Ve.remove(),Ve=null),ls=null,Dr=null,ar=null,pi(),Ee!==null){for(let t of ue.values())!t.exited&&t.embedded!==!0&&Me({t:"kill",sid:t.sid});if(!e){try{Ee.close()}catch{}Ee=null}}ii!==null&&(ii.disconnect(),ii=null);for(let[t,r]of[...ue])if(r.embedded!==!0){if(r.term!==null)try{r.term.dispose()}catch{}ue.delete(t)}Re=null,hi=null,document.removeEventListener("keydown",$c),ce.remove(),ce=null,ct=null,os=null,rr=null,or=null,kt=null,ei=null,ti=null,as=null,lt=null,ri=null,ps(),pc(),_t=null,Cs(),mt=null,rt=null,Lr=null,Je=null,vi=0;try{sessionStorage.removeItem(hs)}catch{}}function $c(e){if(e.key==="Escape"&&ce!==null){if(e.preventDefault(),Ft!==null){Br();return}if(Tr!==null){Gt();return}if(ht!==null){Et();return}vs()}}function i_(){let e=document.querySelector('[data-pane="sidebar"], [class*="sidebarCol"]');if(e!==null)return e.querySelector('[class*="logoRow"]')?.parentElement??e.firstElementChild}function s_(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 n_(){let e=document.createElement("div");return e.dataset.dshTtyEntry="",e.className="tt_sidebarEntry",e.setAttribute("role","button"),e.setAttribute("aria-label",S("panel.title")),e.tabIndex=0,e.innerHTML='<span class="tt_sidebarEntryIcon">'+ws+'</span><span class="tt_sidebarEntryLabel">'+S("panel.title")+"</span>",e.addEventListener("click",t=>{t.preventDefault(),Xn()}),e.addEventListener("keydown",t=>{(t.key==="Enter"||t.key===" "||t.key==="Spacebar")&&(t.preventDefault(),Xn())}),e}function Yl(e,t){let r=s_(e);if(r===void 0)return!1;if(t.parentElement!==e){let s=r.closest('[class*="logoRow"]'),a=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,a.nextElementSibling)}return!0}function o_(){if(mi(),typeof document<"u"&&document.querySelector("[data-dsh-tty-entry]")!==null)return()=>{};let e=n_(),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=i_()),t!==void 0&&(r=Yl(t,e),r&&i.observe(t,{childList:!0,subtree:!0}))},a=new MutationObserver(()=>{s()});a.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=Yl(t,e))});return s(),()=>{a.disconnect(),i.disconnect(),e.remove()}}window.__ModuleLoader__.load({id:"@hyzyn/dsh-tty",factory:e=>{let t={},r=e("react"),{jsx:s,jsxs:a}=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(u){let l=u&&u.view,_=l==="page",[m,w]=r.useState(_),[p,c]=r.useState(null),[d,h]=r.useState(!1),[f,g]=r.useState(!1),[C,v]=r.useState({kind:"",text:""}),[x,b]=r.useState(null),[E,O]=r.useState(""),[B,H]=r.useState(!1),[M,K]=r.useState(Date.now()),P=r.useRef(null),D=r.useRef(null),[F,N]=r.useState([]),[y,T]=r.useState(!1),k=A=>s("div",{className:"tt_cardSection",children:A}),R=async()=>{try{let j=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json();j.ok&&typeof j.config=="object"&&j.config!==null?(P.current=j.config,D.current=JSON.stringify(J(j.config)),c(j.config),fi(j.config)):v({kind:"error",text:String(j.error||S("error.configLoadFailed"))})}catch(A){v({kind:"error",text:String(A&&A.message?A.message:A)})}},U=async()=>{try{let j=await(await fetch("/api/dsh-tty/shells",{cache:"no-store"})).json();j.ok&&Array.isArray(j.shells)&&N(j.shells)}catch{}};r.useEffect(()=>{m&&!d&&(h(!0),R(),U())},[m]);let G=(A,j)=>c(V=>{let Q={...V||{},[A]:j};return P.current=Q,Q}),J=A=>{let j={};for(let V of["enabled","announceToAgent","maxSessions","shell","term","colorTerm","cwd","reconnectGraceSec","shellIntegration","sftpStyle","persistence","endOnPageClose","statsEnabled","allowProxyCommand"]){let Q=(A||{})[V];Q!==void 0&&Q!==""&&(j[V]=Q)}return j.sshHosts=Array.isArray(A?.sshHosts)?A.sshHosts:[],j.tunnels=Array.isArray(A?.tunnels)?A.tunnels:[],A?.sftpLimits&&typeof A.sftpLimits=="object"&&(j.sftpLimits={maxDownloadMb:Number(A.sftpLimits.maxDownloadMb)||0,maxUploadMb:Number(A.sftpLimits.maxUploadMb)||0,maxUploadFiles:Number(A.sftpLimits.maxUploadFiles)||0}),j};P.current=p;let X=(A,j)=>c(V=>({...V||{},sftpLimits:{...V?.sftpLimits??{},[A]:j}})),[W,L]=r.useState(null),[I,z]=r.useState(null),[$,q]=r.useState(""),[ee,he]=r.useState(null),[de,re]=r.useState(""),[Y,se]=r.useState(""),[be,fe]=r.useState(""),ge=r.useRef(null),[Le,Ce]=r.useState(!1),[Z,te]=r.useState({text:"",kind:""}),[le,ie]=r.useState(!1),[ne,oe]=r.useState({running:!1,ok:!1,text:""}),[pe,we]=r.useState({}),[_e,Ie]=r.useState([]),[ye,ve]=r.useState({direction:"local",localPort:"",remoteHost:"",remotePort:"",localTargetPort:"",bookName:""}),[xe,Ne]=r.useState(null);r.useEffect(()=>{if(!m)return;let A=!0,j=async()=>{try{let ae=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();A&&ae.ok&&Array.isArray(ae.tunnels)&&Ie(ae.tunnels)}catch{}};j();let V=setInterval(j,2e3);return()=>{A=!1,clearInterval(V)}},[m]);let je=A=>j=>ve(V=>({...V||{},[A]:j.target.value})),Qt=(A,j)=>ve(V=>({...V||{},[A]:j})),qc=A=>A?.direction==="remote"?S("meta.tunnelRemote",{host:A.remoteHost||"127.0.0.1",port:String(A.remotePort??0),local:String(A.localTargetPort??0)}):S("meta.tunnelLocal",{local:String(A?.localPort??0),host:A?.remoteHost??"?",port:String(A?.remotePort??0)}),co=(p?.sshHosts??[]).find(A=>A?.name===ye?.bookName),Es=async A=>{try{let j=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({tunnels:A})}),V=await j.json().catch(()=>({}));return!j.ok||!V.ok?(v({kind:"error",text:String(V.error||S("error.saveTunnelFailed"))}),!1):!0}catch(j){return v({kind:"error",text:String(j&&j.message?j.message:j)}),!1}},ho=()=>Tl(ye,(Array.isArray(p?.sshHosts)?p.sshHosts:[]).map(A=>A?.name),S),Kc=A=>{v({kind:"",text:""}),Ne(String(A?.name??"")),ve({direction:A?.direction==="remote"?"remote":"local",bookName:String(A?.bookName??""),localPort:A?.localPort?String(A.localPort):"",remoteHost:String(A?.remoteHost??""),remotePort:A?.remotePort?String(A.remotePort):"",localTargetPort:A?.localTargetPort?String(A.localTargetPort):""})},Gc=()=>{Ne(null),v({kind:"",text:""}),ve(A=>({...A||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))},Vc=()=>{v({kind:"",text:""});let A=ho();if(!A.ok){v({kind:"error",text:A.error});return}let j=A.tunnel,V=Array.isArray(p?.tunnels)?p.tunnels:[];if(Rl(V,j.name)!==void 0){v({kind:"error",text:S("error.tunnelNameTaken",{name:j.name})});return}let Q=[...V,j];c(ae=>({...ae||{},tunnels:Q})),ve(ae=>({...ae||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),Es(Q).then(ae=>{ae&&v({kind:"ok",text:S("msg.tunnelApplied",{name:j.name})})})},Yc=()=>{if(xe===null)return;v({kind:"",text:""});let A=ho();if(!A.ok){v({kind:"error",text:A.error});return}let j=Array.isArray(p?.tunnels)?p.tunnels:[],V=Ml(j,xe,A.tunnel,S);if(!V.ok){V.reason==="missing"&&Ne(null),v({kind:"error",text:V.error});return}let Q=V.tunnels;c(ae=>({...ae||{},tunnels:Q})),Es(Q).then(ae=>{if(ae!==!0){c(me=>({...me||{},tunnels:j}));return}Ne(null),ve(me=>({...me||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),v({kind:"ok",text:S("msg.tunnelUpdated",{name:A.tunnel.name})})})},uo=(A,j)=>{c(V=>({...V||{},tunnels:A})),Es(A).then(V=>{V!==!0&&c(Q=>({...Q||{},tunnels:j}))})},Jc=A=>{let j=Array.isArray(p?.tunnels)?p.tunnels:[];xe!==null&&String(A??"")===xe&&(Ne(null),ve(V=>({...V||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))),uo(j.filter(V=>V?.name!==A),j)},Xc=(A,j)=>{let V=Array.isArray(p?.tunnels)?p.tunnels:[];uo(V.map(Q=>Q?.name===A?{...Q,enabled:j}:Q),V)},Zc=A=>{L(A?.name??null),q(""),oe({running:!1,ok:!1,text:""}),re(""),se(""),Ts(),Ce(Lt!==null),z({name:A?.name??"",host:A?.host??"",port:String(A?.port??22),username:A?.username??"",auth:A?.auth==="key"||A?.auth==="password"?A.auth:"agent",keyPath:A?.keyPath??"",passphrase:A?.passphrase??"",password:A?.password??"",agentForward:A?.agentForward===!0,persist:A?.persist!==!1}),Ql().then(j=>he(j)),Rs(A?.password??"")},fo=()=>{L(null),z(null),q(""),oe({running:!1,ok:!1,text:""}),re(""),se(""),Ts()},Qc=async()=>{if(I===null)return;let A=I.name.trim(),j=I.host.trim(),V=I.username.trim();if(A===""||j===""||V===""){q(S("error.nameHostUserRequired"));return}let Q=Number(I.port);if((!Number.isInteger(Q)||Q<1||Q>65535)&&(Q=22),(p?.sshHosts??[]).some(me=>me?.name===A&&A!==W)){q(S("error.bookNameTaken",{name:A}));return}if(I.auth==="key"&&I.keyPath.trim()===""){q(S("error.keyPathRequired"));return}q("");let ae=I.password;if(I.auth==="password"){let me=await rc(Le,I.password,j,Q,V,"PASSWORD");if(me.error!==void 0){q(me.error);return}me.value!==void 0&&(ae=me.value)}c(me=>({...me||{},sshHosts:(Array.isArray(me?.sshHosts)?me.sshHosts:[]).map(Ae=>Ae?.name===W?{name:A,host:j,port:Q,username:V,auth:I.auth,keyPath:I.keyPath.trim(),passphrase:I.passphrase,password:ae,agentForward:I.agentForward,persist:I.persist===!0}:Ae)})),we(me=>{let Ae={...me};return delete Ae[A],W!==A&&delete Ae[W],Ae}),L(null),z(null),oe({running:!1,ok:!1,text:""}),v({kind:"ok",text:S("msg.hostEdited",{name:A})})},eh=A=>{W===A&&fo(),we(j=>{let V={...j};return delete V[A],V}),c(j=>({...j||{},sshHosts:(Array.isArray(j?.sshHosts)?j.sshHosts:[]).filter(V=>V?.name!==A)}))},th=async A=>{let j=A?.name??"";if(j==="")return;let V={host:A?.host??"",port:Number(A?.port)||22,username:A?.username??"",auth:A?.auth==="key"||A?.auth==="password"?A.auth:"agent",keyPath:A?.keyPath??"",passphrase:A?.passphrase??"",password:A?.password??"",agentForward:A?.agentForward===!0};we(ae=>({...ae,[j]:{running:!0,text:S("msg.probing")}}));let Q=await $n(V,!0);we(ae=>{let me=ae[j]||{};if(Q.result){let Ae=Q.result.auth?.ok===!0;return{...ae,[j]:{running:!1,ok:Ae,text:qn(Q.result)}}}return{...ae,[j]:{running:!1,ok:!1,text:S("error.probeFailed",{detail:String(Q.error||S("error.unknown"))})}}})},rh=async A=>{let j=(Array.isArray(p?.hostKeys)?p.hostKeys:[]).filter(V=>!(V?.host===A?.host&&Number(V?.port)===Number(A?.port)));c(V=>({...V||{},hostKeys:j}));try{let V=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:j})}),Q=await V.json().catch(()=>({}));!V.ok||!Q.ok?v({kind:"error",text:String(Q.error||S("error.hostKeyDeleteFailed"))}):v({kind:"ok",text:S("msg.hostKeyDeleted")})}catch(V){v({kind:"error",text:String(V&&V.message?V.message:V)})}},ih=async()=>{v({kind:"",text:""});try{let j=await(await fetch("/api/dsh-tty/ssh-config",{cache:"no-store"})).json();if(!j.ok){v({kind:"error",text:String(j.error||S("error.sshConfigReadFailed"))});return}let V=Array.isArray(j.entries)?j.entries:[],Q=[...Array.isArray(p?.sshHosts)?p.sshHosts:[]],ae=new Set(Q.map(De=>De?.name)),me=0,Ae=0;for(let De of V)if(!(De===null||typeof De!="object"||typeof De.name!="string")){if(ae.has(De.name)){Ae+=1;continue}ae.add(De.name),Q.push({name:De.name,host:String(De.host??De.name),port:Number(De.port)||22,username:String(De.username??""),auth:De.auth==="key"?"key":"agent",keyPath:String(De.keyPath??""),passphrase:"",password:"",agentForward:!1}),me+=1}c(De=>({...De||{},sshHosts:Q}));let Se=Array.isArray(j.proxy)?j.proxy.filter(De=>typeof De=="string"):[],Xe=Number.isInteger(j.proxyCount)?j.proxyCount:Se.length,Wr=Array.isArray(j.proxyCommand)?j.proxyCommand.filter(De=>typeof De=="string"):[],ut=Number.isInteger(j.proxyCommandCount)?j.proxyCommandCount:Wr.length,cr=Number.isInteger(j.skippedOther)?j.skippedOther:0,Wt=Number.isInteger(j.droppedOverflow)?j.droppedOverflow:0,ft=[];Xe>0&&ft.push(S("msg.proxySkipped",{count:Xe,names:Se.slice(0,5).join(S("list.separator"))+(Xe>5?S("meta.etc"):"")})),ut>0&&ft.push(S("msg.proxyCommandSkipped",{count:ut,names:Wr.slice(0,5).join(S("list.separator"))+(ut>5?S("meta.etc"):"")})),cr>0&&ft.push(S("msg.skippedNotConcrete",{count:cr})),Wt>0&&ft.push(S("msg.importOverflow",{count:Wt}));let yo=ft.length>0?S("list.separatorFull")+ft.join(S("list.separatorFull")):"";if(me===0){let De=Ae>0?S("msg.noNewEntries",{count:Ae}):S("msg.noImportableHosts");v({kind:ft.length>0?"error":"ok",text:De+yo})}else v({kind:ft.length>0?"error":"ok",text:S("msg.importedHosts",{added:me,skipped:Ae})+yo})}catch(A){v({kind:"error",text:String(A&&A.message?A.message:A)})}},po=A=>A===null||typeof A!="object"?[]:Array.isArray(A.fingerprints)?A.fingerprints.filter(j=>typeof j=="string"&&j!==""):typeof A.fingerprint=="string"&&A.fingerprint!==""?[A.fingerprint]:[],sh=async()=>{v({kind:"",text:""});try{let j=await(await fetch("/api/dsh-tty/known-hosts",{cache:"no-store"})).json();if(!j.ok){v({kind:"error",text:String(j.error||S("error.knownHostsReadFailed"))});return}let V=Array.isArray(j.entries)?j.entries:[],Q=[...Array.isArray(p?.hostKeys)?p.hostKeys:[]],ae=new Map;for(let Se of Q)Se===null||typeof Se!="object"||ae.set(String(Se.host??"")+":"+String(Se.port??22),{record:Se,fps:new Set(po(Se))});let me=0,Ae=0;for(let Se of V){if(Se===null||typeof Se!="object"||typeof Se.host!="string")continue;let Xe=Array.isArray(Se.fingerprints)?Se.fingerprints.filter(Wt=>typeof Wt=="string"&&Wt!==""):[];if(typeof Se.fingerprint=="string"&&Se.fingerprint!==""&&Xe.push(Se.fingerprint),Xe.length===0)continue;let Wr=Se.host+":"+String(Se.port??22),ut=ae.get(Wr);if(ut!==void 0){let Wt=!1;for(let ft of Xe)ut.fps.has(ft)||ut.fps.size>=8||(ut.fps.add(ft),Wt=!0);if(!Wt){Ae+=1;continue}delete ut.record.fingerprint,ut.record.fingerprints=[...ut.fps],me+=1;continue}let cr={host:Se.host,port:Number(Se.port)||22,fingerprints:[...new Set(Xe)].slice(0,8)};ae.set(Wr,{record:cr,fps:new Set(cr.fingerprints)}),Q.push(cr),me+=1}if(me===0){v({kind:"ok",text:Ae>0?S("msg.noNewFingerprints",{count:Ae}):S("msg.noImportableKnownHosts")});return}c(Se=>({...Se||{},hostKeys:Q}));try{let Se=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:Q})}),Xe=await Se.json().catch(()=>({}));if(!Se.ok||!Xe.ok){v({kind:"error",text:String(Xe.error||S("error.saveHostKeysFailed"))});return}v({kind:"ok",text:S("msg.importedFingerprints",{added:me,skipped:Ae})+(j.truncated===!0?S("hint.knownHostsTruncated"):"")})}catch(Se){v({kind:"error",text:String(Se&&Se.message?Se.message:Se)})}}catch(A){v({kind:"error",text:String(A&&A.message?A.message:A)})}},_o=async A=>{let j=A??P.current??p;g(!0),v({kind:"",text:""});let V=J(j);try{let Q=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(V)}),ae=await Q.json();!Q.ok||!ae.ok?v({kind:"error",text:String(ae.error||S("error.saveFailed"))}):(v({kind:"ok",text:S("msg.saved")}),D.current=JSON.stringify(V),ae.config&&(P.current=ae.config,c(ae.config),fi(ae.config)))}catch(Q){v({kind:"error",text:String(Q&&Q.message?Q.message:Q)})}g(!1)},Ls=A=>"/api/dsh-tty/elevate"+A,mo=async()=>{try{let j=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json(),V=j&&typeof j.config=="object"&&j.config!==null?j.config:null;if(V===null)return;c(Q=>{if(Q===null)return Q;let ae={...Q,allowProxyCommandGranted:V.allowProxyCommandGranted===!0,allowProxyCommandGrantSource:V.allowProxyCommandGrantSource??null,allowProxyCommandGrantedAt:Number.isFinite(V.allowProxyCommandGrantedAt)?V.allowProxyCommandGrantedAt:null};return P.current=ae,ae})}catch{}},go=async()=>{b(null),H(!1);let A=P.current||{},j=D.current!==null&&JSON.stringify(J(A))===D.current,V={...A,allowProxyCommand:!0};P.current=V,c(V),await mo(),j?(await _o(V),O(S("elev.granted"))):O(S("elev.grantedNeedSave"))},vo=async()=>{H(!1),O(""),b({phase:"loading"});try{let A=await fetch(Ls(""),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:ts})}),j=await A.json().catch(()=>({}));if(!A.ok){b({phase:"error",error:String(j.error||A.status)});return}if(j.status==="granted"){await go();return}b({phase:"pending",command:String(j.command??""),expiresAt:Number(j.expiresAt)||0})}catch(A){b({phase:"error",error:String(A&&A.message?A.message:A)})}},nh=async()=>{O("");try{let A=await fetch(Ls("/revoke"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:ts})}),j=await A.json().catch(()=>({}));if(!A.ok){O(S("elev.error")+String(j.error||A.status));return}await mo(),O(S("elev.revoked"))}catch(A){O(S("elev.error")+String(A&&A.message?A.message:A))}},oh=async()=>{let A=x===null?"":String(x.command??"");if(A!==""){if(lo())try{await navigator.clipboard.writeText(A),H(!0);return}catch{}H(!1),O(S("elev.copyManual"))}};r.useEffect(()=>{if(x===null||x.phase!=="pending")return;let A=setInterval(()=>K(Date.now()),1e3),j=setInterval(()=>{fetch(Ls("/status"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:ts})}).then(V=>V.json()).then(V=>{V.status==="granted"&&go()}).catch(()=>{})},1500);return()=>{clearInterval(A),clearInterval(j)}},[x]);let ah=()=>{if(p.allowProxyCommandGrantSource==="env")return s("span",{className:"tt_cardHint",children:S("elev.viaEnv")});let A=p.allowProxyCommandGrantedAt;return a("span",{className:"tt_capState",children:[Number.isFinite(A)?s("span",{children:S("elev.grantedAt",{time:Zp(A)})}):null,s("button",{type:"button",className:"tt_toolBtn tt_capRevoke",onClick:()=>{nh()},children:S("elev.revoke")})]})},lh=()=>{let A=String(x.command??""),j=x.expiresAt>0?Math.max(0,Math.ceil((x.expiresAt-M)/1e3)):0,V=x.phase==="pending"&&x.expiresAt>0&&j===0,Q=()=>{b(null),H(!1)};return a("div",{className:"tt_elevPanel",children:[a("div",{className:"tt_elevHead",children:[s("span",{className:"tt_cardLabel",children:S("elev.title")}),s("button",{type:"button",className:"tt_toolBtn",onClick:Q,children:S("elev.close")})]}),s("span",{className:"tt_cardHint",children:S("elev.lockedWhy")}),x.phase==="error"?s("span",{className:"tt_cardHint tt_sshProbeWarn",children:S("elev.error")+String(x.error??"")}):null,x.phase==="loading"?s("span",{className:"tt_cardHint",children:S("elev.loading")}):null,A===""?null:a("div",{className:"tt_elevSteps",children:[s("span",{className:"tt_cardHint",children:S("elev.step")}),a("div",{className:"tt_elevCommand",children:[s("code",{children:A}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{oh()},children:S(B?"elev.copied":"elev.copy")})]}),s("span",{className:"tt_cardHint",children:S(V?"elev.expired":"elev.waiting")}),V?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{vo()},children:S("elev.regenerate")}):s("span",{className:"tt_cardHint",children:S("elev.expiresIn",{sec:j})})]}),p.allowProxyCommand===!0&&p.allowProxyCommandGranted!==!0?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{G("allowProxyCommand",!1),Q()},children:S("elev.disableFirst")}):null,s("span",{className:"tt_cardHint",children:S("elev.otherWay")}),s("span",{className:"tt_cardHint",children:S("elev.envHow",{env:ts})})]})},ch=()=>{let A=p.allowProxyCommandGranted===!0,j=p.allowProxyCommand===!0;return a("div",{className:"tt_capBlock",children:[a("label",{className:"tt_cardField tt_cardRow tt_cardToggle tt_cardDanger",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:j,onChange:V=>{if(!A){vo();return}G("allowProxyCommand",V.target.checked)}}),s("span",{className:"tt_cardLabel",children:S("check.allowProxyCommand")}),j&&!A?s("span",{className:"tt_badgeWarn",children:S("badge.notEffective")}):null]}),s("span",{className:"tt_cardHint",children:S("hint.allowProxyCommand")}),A?ah():s("span",{className:"tt_cardHint tt_sshProbeWarn",children:S("hint.proxyCommandNotGranted")}),E===""?null:s("span",{className:"tt_cardHint",children:E}),x===null?null:lh()]})},Ts=()=>{ge.current!==null&&(clearTimeout(ge.current),ge.current=null),fe("")},Rs=async A=>{let j=kr(A);if(Ar()===null){Ce(!1),ie(!1),te({text:S(Lt===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),kind:"muted"});return}if(j===""){ie(!1),te({text:"",kind:""});return}let V=await ec(j);if(V.unreported===!0){ie(!1),te({text:S("status.credUnreported",{ref:j}),kind:"plain"});return}if(V.error!==void 0){ie(!1),te({text:S("error.credStatusFailed",{error:V.error}),kind:"error"});return}let Q=V.view;te({text:Q.configured?S("status.credStored",{ref:j,source:Q.source!==""?S("meta.credSource",{source:Q.source}):""}):S("status.credUnknown",{ref:j}),kind:Q.configured?"ok":"plain"}),ie(Q.configured===!0&&Q.writable===!0)},hh=async()=>{let A=kr(I?.password??"");if(A==="")return;let j=await tc(A);if(j.error!==void 0){te({text:j.error,kind:"error"});return}z(V=>({...V||{},password:""})),te({text:"",kind:""}),ie(!1)},dh=(A,j)=>{let V=String(I?.[A]??"");if(V===""||V.startsWith("env:")||be===j){Ts(),z(Q=>({...Q||{},[A]:"env:"+j})),re(""),A==="password"&&Rs("env:"+j);return}fe(j),ge.current!==null&&clearTimeout(ge.current),ge.current=setTimeout(()=>{ge.current=null,fe("")},4e3)},bo=(A,j)=>{if(ee===null)return null;if(ee.length===0)return s("span",{className:"tt_cardHint",children:j});let V=de===A,Q=Y.trim().toUpperCase(),ae=Q===""?ee:ee.filter(me=>me.toUpperCase().includes(Q));return a("div",{className:"tt_credPicker",children:[s("input",{className:"tt_cardInput",value:V?Y:"",placeholder:S("placeholder.credRef"),title:S("hint.credRefCandidates"),autoComplete:"off",spellCheck:!1,onFocus:()=>{re(A),se("")},onBlur:me=>{me.currentTarget.parentElement.contains(me.relatedTarget)||re("")},onChange:me=>{se(me.target.value),re(A)}}),...V?[s("div",{className:"tt_envList",children:[...ae.length===0?[s("span",{className:"tt_envMore",children:S("list.noCredRef")})]:ae.slice(0,30).map(me=>s("button",{type:"button",className:"tt_envItem","data-danger":be===me?"":void 0,onMouseDown:Ae=>Ae.preventDefault(),onClick:()=>dh(A,me),children:be===me?S("list.credOverwrite",{name:me}):me},me)),...ae.length>30?[s("span",{className:"tt_envMore",children:S("list.moreMatches",{count:ae.length-30})})]:[]]},"cred-list-"+A)]:[]]})},uh=()=>{let j=kr(I?.password??"")!=="",V=Ar()===null;return a("div",{className:"tt_sshRow tt_credRow",children:[j?s("button",{type:"button",className:"tt_toolBtn tt_credClear",disabled:le!==!0,onClick:()=>{hh()},children:S("btn.clearCredential")}):s("label",{className:"tt_credToggle",title:S("hint.rememberCredentialApply"),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:Le,disabled:V,onChange:Q=>Ce(Q.target.checked)}),s("span",{children:S("check.rememberCredentialApply")})]}),Z.text===""?null:s("span",{className:"tt_credStatus","data-kind":Z.kind,children:Z.text}),V&&Z.text===""?s("span",{className:"tt_credStatus","data-kind":"muted",children:S("error.credPlainUnavailable")}):null]})},wo=()=>{let A=String(I?.host??"").trim(),j=String(I?.username??"").trim(),V=Number(I?.port);if((!Number.isInteger(V)||V<1||V>65535)&&(V=22),A===""||j==="")return q(S("error.hostUserRequired")),null;let Q=I?.auth,ae={host:A,port:V,username:j,auth:Q};if(Q==="key"){let me=String(I?.keyPath??"").trim();if(me==="")return q(S("error.keyPathRequired")),null;ae.keyPath=me,I?.passphrase!==""&&(ae.passphrase=I.passphrase)}if(Q==="password"){let me=String(I?.password??"");if(me==="")return q(S("error.passwordRequired")),null;ae.password=me}return I?.agentForward===!0&&(ae.agentForward=!0),ae},fh=()=>{q("");let A=wo();A!==null&&(oe({running:!0,ok:!1,text:S("msg.probing")}),$n(A,!1).then(j=>{if(j.result){let V=j.result.auth?.ok===!0;oe({running:!1,ok:V,text:qn(j.result)});return}oe({running:!1,ok:!1,text:S("error.probeFailed",{detail:String(j.error||S("error.unknown"))})})}))},ph=()=>{q("");let A=wo();A!==null&&ks(A)},_h=()=>{if(I===null)return null;let A=(j,V,Q,ae,me)=>a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:j}),s("input",{className:"tt_cardInput",type:ae??"text",value:I[V]??"",placeholder:Q??"",autoComplete:"off",spellCheck:!1,onChange:Ae=>{let Se=Ae.target.value;z(Xe=>({...Xe||{},[V]:Se}))},...me??{}})]});return a("div",{className:"tt_sshEdit",children:[s("div",{className:"tt_sshSection",children:S("section.connection")}),a("div",{className:"tt_sshGrid",children:[A(S("field.bookName"),"name",S("hint.bookNameConflict")),A(S("field.port"),"port","22")]}),A(S("field.host"),"host",S("placeholder.host")),A(S("field.username"),"username","root"),s("div",{className:"tt_sshSection",children:S("section.auth")}),a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("field.authMethod")}),a("select",{className:"tt_cardInput",value:I.auth,onChange:j=>z(V=>({...V||{},auth:j.target.value})),children:[s("option",{value:"agent",children:S("option.authAgent")}),s("option",{value:"key",children:S("option.authKey")}),s("option",{value:"password",children:S("option.authPassword")})]})]}),...I.auth==="key"?[A(S("field.keyPath"),"keyPath","~/.ssh/id_ed25519"),A(S("field.passphrase"),"passphrase","","password"),bo("passphrase",S("hint.noCredRefPassphrase"))]:[],...I.auth==="password"?[A(S("field.password"),"password","","password",{onBlur:()=>{Rs(I.password)}}),uh(),bo("password",S("hint.noCredRefPasswordApply"))]:[],s("div",{className:"tt_sshSection",children:S("section.options")}),a("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:I.agentForward===!0,onChange:j=>z(V=>({...V||{},agentForward:j.target.checked}))}),s("span",{className:"tt_cardLabel",children:S("check.agentForward")})]}),Yt==="tmux"?a("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:I.persist===!0,onChange:j=>z(V=>({...V||{},persist:j.target.checked}))}),s("span",{className:"tt_cardLabel",children:S("check.persist")})]}):null,ne.text!==""?s("div",{className:"tt_sshProbeResult"+(!ne.running&&ne.ok?" tt_sshProbeOk":"")+(!ne.running&&!ne.ok?" tt_sshProbeBad":""),children:ne.text}):null,$!==""?s("span",{className:"tt_cardMessage tt_cardMessageError",children:$}):null,a("div",{className:"tt_sshActions",children:[a("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:fo,children:S("btn.cancel")}),s("button",{type:"button",className:"tt_toolBtn",title:S("btn.browseTitle"),onClick:ph,children:S("btn.fileBrowse")}),s("button",{type:"button",className:"tt_toolBtn",disabled:ne.running,title:S("btn.probeTitle"),onClick:fh,children:ne.running?S("msg.probing"):S("btn.probe")})]}),a("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_cardSave",onClick:()=>{Qc()},children:S("btn.apply")}),s("span",{className:"tt_cardHint",children:S("hint.appliedOnSave")})]})]})]})},Nr=(A,j,V,Q)=>a("label",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:A}),s("input",{className:"tt_cardInput",value:p[j]??"",placeholder:V??"",onChange:ae=>G(j,ae.target.value)}),Q?s("span",{className:"tt_cardHint",children:Q}):null]}),Hr=(A,j,V,Q)=>a("label",{className:"tt_cardField tt_cardRow tt_cardToggle"+(typeof V=="string"&&V!==""?" "+V:""),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:p[j]===!0,disabled:Q===!0&&p[j]!==!0,onChange:ae=>G(j,ae.target.checked)}),s("span",{className:"tt_cardLabel",children:A})]}),Fr=p?.platform==="win32";return l==="summary"?S("card.desc"):a(_?"div":"li",{className:_?"tt_pageHost":m?"tt_card tt_cardOpen":"tt_card",children:[_?null:a("button",{type:"button",className:"tt_cardHeader","aria-expanded":m,onClick:()=>w(A=>!A),children:[a("span",{className:"tt_cardHeadText",children:[s("span",{className:"tt_cardName",children:S("card.name")}),s("span",{className:"tt_cardDescription",children:S("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?a("div",{className:"tt_cardBody",children:[p===null?s("div",{className:"tt_cardMessage",children:S("list.loadingConfig")}):a("div",{children:[k(S("section.basic")),Hr(S("check.enabled"),"enabled"),Hr(S("check.announce"),"announceToAgent"),Fr?a("div",{className:"tt_cardField",children:[a("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:!1,disabled:!0}),s("span",{className:"tt_cardLabel",children:S("check.shellIntegration")})]}),s("span",{className:"tt_cardHint",children:S("hint.shellIntegrationWindows")})]}):Hr(S("check.shellIntegrationWindows"),"shellIntegration"),k(S("section.sftp")),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("field.sftpStyle")}),a("select",{className:"tt_cardInput",value:p.sftpStyle==="dual"?"dual":"dialog",onChange:A=>G("sftpStyle",A.target.value),children:[s("option",{value:"dialog",children:S("option.sftpDialog")}),s("option",{value:"dual",children:S("option.sftpDual")})]}),s("span",{className:"tt_cardHint",children:S("hint.sftpDual")})]}),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("field.sftpLimits")}),a("div",{className:"tt_limitGrid",children:[a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("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:A=>X("maxDownloadMb",Number(A.target.value)||0)})]}),a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("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:A=>X("maxUploadMb",Number(A.target.value)||0)})]}),a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("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:A=>X("maxUploadFiles",Number(A.target.value)||0)})]})]}),s("span",{className:"tt_cardHint",children:S("hint.sftpLimits")})]}),k(S("section.session")),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("field.persistence")}),a("select",{className:"tt_cardInput",value:p.persistence==="tmux"?"tmux":"off",onChange:A=>G("persistence",A.target.value),children:[s("option",{value:"off",children:S("option.persistOff")}),s("option",{value:"tmux",children:S("option.persistTmux")})]}),s("span",{className:"tt_cardHint",children:S("hint.persistence")+(Fr?S("hint.persistenceWindows"):"")}),Hr(S("check.endOnPageClose"),"endOnPageClose"),Hr(S("check.statsEnabled"),"statsEnabled"),s("span",{className:"tt_cardHint",children:S("hint.statsEnabled")}),ch()]}),Nr(S("field.maxSessions"),"maxSessions","4",S("hint.maxSessions")),a("div",{className:"tt_cardField",onBlur:A=>{A.currentTarget.contains(A.relatedTarget)||T(!1)},children:[s("span",{className:"tt_cardLabel",children:S(Fr?"field.shellWindows":"field.shell")}),s("input",{className:"tt_cardInput",value:p.shell??"",placeholder:S(Fr?"placeholder.shellWindows":"placeholder.shell"),autoComplete:"off",spellCheck:!1,onFocus:()=>T(!0),onClick:()=>T(!0),onKeyDown:A=>{A.key==="Escape"&&T(!1)},onChange:A=>{G("shell",A.target.value),T(!0)}}),...y?[s("div",{className:"tt_envList tt_shellList",children:(()=>{let A=(p.shell??"").trim().toLowerCase(),j=A===""?F:F.filter(V=>V.toLowerCase().includes(A));return j.length===0?s("span",{className:"tt_envMore",children:S("list.noShellCandidate")}):j.map(V=>s("button",{type:"button",className:"tt_envItem",onMouseDown:Q=>Q.preventDefault(),onClick:()=>{G("shell",V),T(!1)},children:V},V))})()},"shell-list")]:[],s("span",{className:"tt_cardHint",children:S(Fr?"hint.shellCandidatesWindows":"hint.shellCandidates")})]},"shell-field"),Nr("TERM","term","xterm-256color",S("hint.term")),Nr("COLORTERM","colorTerm","truecolor",""),Nr(S("field.cwd"),"cwd","",S("placeholder.cwd")),Nr(S("field.grace"),"reconnectGraceSec","120",S("hint.grace")),k(S("section.ssh")),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("panel.sshBook")}),...Array.isArray(p.sshHosts)&&p.sshHosts.length>0?[s("div",{className:"tt_hostList","data-editing":W!==null?"":void 0,children:p.sshHosts.map(A=>a("div",{children:[a("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:A?.name??""}),s("span",{className:"tt_sshHostTarget",children:zn(A??{})})]}),s("button",{type:"button",className:"tt_toolBtn",disabled:pe[A?.name]?.running===!0,onClick:()=>{th(A)},title:S("btn.probeRowTitle"),children:pe[A?.name]?.running===!0?S("msg.testing"):S("btn.test")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Zc(A),children:S("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>eh(A?.name),children:S("btn.delete")})]}),pe[A?.name]&&pe[A?.name].text?s("div",{className:"tt_sshProbeResult"+(pe[A?.name].ok?" tt_sshProbeOk":" tt_sshProbeBad"),children:pe[A?.name].text}):null,W===A?.name?_h():null]},String(A?.name??"")))})]:[s("span",{className:"tt_cardHint",children:S("list.emptySshHosts")})],a("div",{className:"tt_cardRow",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{ih()},children:S("btn.importSshConfig")}),s("span",{className:"tt_cardHint",children:S("hint.importSshConfig")})]}),s("span",{className:"tt_cardHint",children:S("hint.sshBook")})]}),a("div",{className:"tt_cardField",children:[a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("panel.tunnels")}),...Array.isArray(p.tunnels)&&p.tunnels.length>0?[s("div",{children:p.tunnels.map(A=>{let j=_e.find(ae=>ae.name===A?.name),V=j?.state??"stopped",Q=xe!==null&&String(A?.name??"")===xe;return a("div",{className:"tt_sshHostRow","data-editing":Q?"":void 0,children:[s("span",{className:"tt_tunnelDot","data-state":V,title:V}),s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:(A?.name??"")+" \xB7 "+qc(A??{})}),s("span",{className:"tt_sshHostTarget",children:(A?.bookName??"")+(j?.error?" \xB7 "+j.error:"")+(j?.lastForwardError?" \xB7 "+j.lastForwardError:"")})]}),s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:A?.enabled!==!1,title:S("check.tunnelEnabled"),onChange:ae=>Xc(A?.name,ae.target.checked)}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Kc(A),children:S("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Jc(A?.name),children:S("btn.delete")})]},String(A?.name??""))})})]:[s("span",{className:"tt_cardHint",children:S("list.emptyTunnels")})],a("div",{className:"tt_sshEdit",children:[a("div",{className:"tt_cardRow tt_tunnelHead",children:[a("div",{className:"tt_segmented",role:"group","aria-label":S("field.direction"),children:[s("button",{type:"button",className:"tt_segmentedBtn","data-active":ye.direction!=="remote"?"":void 0,title:S("option.localForwardTitle"),onClick:()=>Qt("direction","local"),children:S("option.localForward")}),s("button",{type:"button",className:"tt_segmentedBtn","data-active":ye.direction==="remote"?"":void 0,title:S("option.remoteForwardTitle"),onClick:()=>Qt("direction","remote"),children:S("option.remoteForward")})]}),a("select",{className:"tt_cardInput",value:ye.bookName,onChange:je("bookName"),children:[s("option",{value:"",children:S("option.selectBook")}),...Array.isArray(p?.sshHosts)?p.sshHosts.map(A=>s("option",{value:A?.name??"",children:A?.name??""})):[]]})]}),s("span",{className:"tt_cardHint",children:co!==void 0?S("hint.tunnelViaBook",{book:zn(co)}):S("hint.tunnelBookEmpty")}),ye.direction==="local"?a("div",{className:"tt_tunnelEndpoints",children:[a("div",{className:"tt_tunnelHop",children:[a("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:S("hint.localListenFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.localPort"),value:ye.localPort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.localListenPort"),onChange:je("localPort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"local",title:S("hint.flowLocalToRemote"),"aria-hidden":"true",children:"\u2192"})]}),a("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:S("placeholder.remoteHost"),title:S("hint.remoteHostTitle"),value:ye.remoteHost,autoComplete:"off","aria-label":S("field.remoteHost"),onChange:je("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.port"),value:ye.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.remotePort"),onChange:je("remotePort")})]})]}):a("div",{className:"tt_tunnelEndpoints",children:[a("div",{className:"tt_tunnelHop",children:[a("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:S("placeholder.remoteListenHost"),title:S("hint.remoteListenHost"),value:ye.remoteHost,autoComplete:"off","aria-label":S("field.remoteListenHost"),onChange:je("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.listenPort"),value:ye.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.remoteListenPort"),onChange:je("remotePort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"remote",title:S("hint.flowRemoteToLocal"),"aria-hidden":"true",children:"\u2192"})]}),a("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:S("hint.localDialFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.localTargetPort"),value:ye.localTargetPort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.localTargetPort"),onChange:je("localTargetPort")})]})]}),s("div",{className:"tt_tunnelEndpoints",children:[s("span",{className:"tt_tunnelEndLabel",children:ye.direction==="local"?S("hint.tunnelLocalSummary"):S("hint.tunnelRemoteSummary")})]}),s("div",{className:"tt_cardRow tt_tunnelActions",children:[xe===null?s("button",{type:"button",className:"tt_cardSave",onClick:Vc,children:S("btn.addTunnel")}):s("button",{type:"button",className:"tt_cardSave",onClick:Yc,children:S("btn.saveEdit")}),xe===null?null:s("button",{type:"button",className:"tt_toolBtn",onClick:Gc,children:S("btn.cancel")}),s("span",{className:"tt_cardHint",children:xe===null?S("hint.tunnelAdd"):S("hint.tunnelEditing",{name:xe})})]})]})]}),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("panel.hostKeys")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{sh()},children:S("btn.importKnownHosts")})]}),...Array.isArray(p.hostKeys)&&p.hostKeys.length>0?[s("div",{className:"tt_hostList",children:p.hostKeys.map((A,j)=>a("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:String(A?.host??"")+":"+String(A?.port??22)}),s("span",{className:"tt_sshHostTarget",children:po(A).map(V=>"sha256:"+V).join(" / ")})]}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{rh(A)},children:S("btn.delete")})]},String(A?.host??"")+":"+String(A?.port??22)+"#"+String(j)))})]:[s("span",{className:"tt_cardHint",children:S("list.emptyHostKeys")})],s("span",{className:"tt_cardHint",children:S("hint.hostKeys")})]}),a("div",{className:"tt_cardField tt_cardRow",children:[s("button",{className:"tt_cardSave",disabled:f,onClick:()=>{_o()},children:S(f?"msg.saving":"btn.save")}),s("span",{className:"tt_cardMessage"+(C.kind==="ok"?" tt_cardMessageOk":C.kind==="error"?" tt_cardMessageError":""),children:C.text})]})]})]}):null]})}t.inject=["slots","sessions"];let o=["@hyzyn/dsh-tty#tty","@hyzyn/dsh-all#tty"];return t.apply=u=>{Hf(u),uc=u.sessions,u.inject(["remote","remote.credentials"],c=>(Lt=c.remote?.credentials??c["remote.credentials"]??null,()=>{Lt=null}));let l=!1,_=()=>{};_s={set(c){if(c!==l){if(l=c,c){_=o_();return}_(),_=()=>{},_i(),sr()}}},Rc(!0),ao();for(let c of o)u.slots.inject("plugins.row.config",()=>u.slots.register({name:"plugins.row.config",key:c},n));u.slots.inject("settings.kit.item",()=>u.slots.register({name:"settings.kit.item",id:"tty",order:80,label:()=>S("card.name")},n)),u.slots.inject("settings.plugin.item",()=>u.slots.register({name:"settings.plugin.item",key:"tty",order:100},n));let m=u.provide("ttyConnbar",{version:1,addAction:Ss,requestRender(){sr()}}),w=u.provide("ttyTerminal",{version:3,open(c){if(!nr)return;let d=vc(c),h=bc(c,d),f=typeof c?.label=="string"&&c.label!==""?c.label:void 0;if(mi(),c?.reuse!==!1){let g=mp(h);if(g!==null)return Jn(),Zt(g.sid),g}return Jn(),ui(h,f)},mount(c,d){return nr?xp(c,d):()=>{}}}),p=u.provide("ttyPanel",{version:2,isOpen(){return ce!==null&&!qe},mountPane(c){return Sc(c)},minimize(){return vs(),ce!==null&&qe}});return()=>{_s=null,nr=!1,_(),p(),w(),m(),_i()}},t}});})();
|
|
2826
|
+
`+Cl,document.head.appendChild(Xi))}var ws='<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>',zf='<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>',$f='<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>',qf='<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>',Kf='<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" fill="var(--dsw-alias-bg-base,#fff)"/></svg>',Gf='<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>',Vf='<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>',ic='<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>',Yf='<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>',Jf='<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>',ys='<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>',Xf='<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>',ci='<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>',sc='<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>',nc='<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>',Zn='<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>',oc='<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>',Zf='<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>',Qn='<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>',Er='<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>',eo='<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>',ac='<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>',lc='<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>',cc='<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>',Qf='<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>',ep='<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>',tp='<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>',rp='<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>',hc='<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>',ip='<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>',dc='<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>',uc=null,Ee=null,ce=null,os=null,hi=null,Lt=null,rr=null,or=null,kt=null,ei=null,ti=null,as=null,lt=null,ri=null,rt=null,ct=null,Je=null,Lr=null,di=!1,ii=null,qe=!1,Ve=null,ls=null,Dr=null,ar=null,cs=null,ir=null,si=1e3,hs="dsh-tty:tabs",ue=new Map,gi=new Set,to=()=>gi.size>0,Hn=new Set,Re=null,vi=0,Zi=!1,ht=null,Tr=null,Ht=[],ds=!0,_t=null,mt=null,ni=null,Qr=null,Fn=null,Wn=new Set;function Ss(e){return Wn.add(e),()=>Wn.delete(e)}Ss(({tab:e,addAction:t})=>{nr&&e.exited&&t(Gf,S("btn.reopen"),S("btn.reopenTitle"),()=>fs(e.sid))});Ss(({tab:e,addAction:t})=>{nr&&t(Vf,"SFTP",S("btn.sftpTitle"),()=>ks(e.spawnSpec,e.sid))});Ss(({bookName:e,addAction:t})=>{if(!nr)return;let r=e!==""?Ac(e):0;if(r>0){t(ic,S("btn.tunnels",{count:r}),S("btn.tunnelsTitle"),s=>xc(s.currentTarget,e));return}e!==""&&t(Yf,S("btn.more"),S("btn.moreTitle"),s=>Dp(s.currentTarget,e))});function bi(e,t){if(rr===null)return;rr.textContent=e.split("\u2014\u2014")[0],rr.title=e,or.dataset.state=t,os!==null&&(os.style.display=t==="connected"?"none":""),Dr!==null&&(Dr.textContent=e),ar!==null&&(ar.dataset.state=t);let r=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot");r!==null&&(r.dataset.state=t)}function Pn(e,t,r){let s=typeof e=="string"&&e!==""?e:null;if(s!==null){let a=ue.get(s);a!==void 0&&(a.statusText=t,a.statusState=r)}Pl(s,Re)&&(hi=s,bi(t,r))}function Qi(e,t){hi=null,bi(e,t)}function ro(){if(!Bl(hi,Re))return;let e=Re===null?void 0:ue.get(Re);hi=e===void 0?null:Re;let t=Dl(e,S);bi(t.text,t.state)}function Me(e){Ee!==null&&Ee.readyState===WebSocket.OPEN&&Ee.send(JSON.stringify(e))}function sp(){let e=[],t=document.createDocumentFragment();for(let r of An(S)){let s=document.createElement("span");s.className="tt_statsItem";let a=document.createElement("span");a.className="tt_statsLabel",a.textContent=r.label,s.appendChild(a);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 o=document.createElement("span");o.className="tt_statsValue",s.appendChild(o),t.appendChild(s),e.push({item:s,value:o,meter:i,fill:n,slot:null})}return _t!==null&&_t.appendChild(t),e}function np(e,t){let r=Ul(t!==void 0?t.stats:null,S);for(let s=0;s<e.length;s+=1){let a=e[s],i=r[s];if(i!==void 0&&(a.slot!==i.slot&&(a.slot=i.slot,a.value.style.minWidth=i.slot>0?i.slot+"ch":""),a.value.textContent!==i.value&&(a.value.textContent=i.value),a.item.getAttribute("title")!==i.title&&a.item.setAttribute("title",i.title),a.fill!==null&&a.meter!==null)){let n=i.pct===null?"0%":Math.max(0,Math.min(100,i.pct)).toFixed(1)+"%";a.fill.style.width!==n&&(a.fill.style.width=n);let o=Il(i.pct);a.meter.dataset.level!==o&&(a.meter.dataset.level=o)}}}function Cs(){Qr=null,Fn=null}function op(){if(ce===null||qe||!ds)return!1;let e=dt();return e===void 0||e.embedded===!0||e.exited===!0||e.stats===null||e.stats===void 0?!1:Fl(e.statsAt)}function jl(){if(qe)return;let e=dt();if(!(e===void 0||e.embedded===!0||e.fit===null)){try{e.fit.fit()}catch{return}try{e.spawned&&!e.exited&&Or(e)}catch{}}}function lr(){try{ap()}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{_t!==null&&(_t.hidden=!0,_t.textContent=""),Cs(),rt!==null&&delete rt.dataset.stats}catch{}}}function ap(){if(rt===null||_t===null)return;let e=op(),t=rt.dataset.stats!==void 0!==e;if(!e){t&&delete rt.dataset.stats,_t.hidden=!0,Qr!==null&&(_t.textContent="",Cs()),t&&jl();return}_t.hidden=!1,Qr===null&&(Qr=sp());let r=dt(),s=r===void 0?"":r.sid+":"+String(r.statsAt||0);s!==Fn&&(Fn=s,np(Qr,r)),t&&(rt.dataset.stats="",jl())}function fc(){ni===null&&(ni=setInterval(()=>lr(),1e3))}function pc(){ni!==null&&(clearInterval(ni),ni=null)}function _c(){if(ce===null||qe||!ds)return null;let e=dt();return e===void 0||e.embedded===!0||e.exited===!0?null:e.sid}function wi(){let e=_c();e!==mt&&(mt!==null&&Me({t:"statsOff",sid:mt}),mt=e,e!==null&&Me({t:"statsOn",sid:e}))}function lp(e){if(e!==_c()){wi();return}mt!==null&&mt!==e&&Me({t:"statsOff",sid:mt}),mt=e,Me({t:"statsOn",sid:e})}function dt(){return Re!==null?ue.get(Re):void 0}function Un(){try{return Al(uc?.list?.getSnapshot?.())}catch{return}}function cp(e){if(!(e.term===null||e.exited)){try{if(e.term.buffer.active.length<=e.term.rows)return}catch{return}e.term.reset(),Me({t:"refresh",sid:e.sid})}}var es=null;function mc(e){es!==null&&clearTimeout(es),es=setTimeout(()=>{es=null;let t=dt();t!==void 0&&cp(t)},e??200)}var hp=["password","passphrase"];function zl(e){if(e===null||typeof e!="object"||e.t!=="ssh")return e;let t=e.credsStripped===!0,r={...e};for(let s of hp){let a=r[s];typeof a=="string"&&a!==""&&!a.startsWith("env:")&&(delete r[s],t=!0)}return t&&(r.credsStripped=!0),r}var gc=1;function Xt(){try{let e=[...ue.values()].filter(t=>!t.exited&&t.embedded!==!0).map(t=>({sid:t.sid,spawnSpec:zl(t.spawnSpec),label:t.label}));e.length===0||ce===null?sessionStorage.removeItem(hs):sessionStorage.setItem(hs,JSON.stringify({v:gc,tabs:e})),dp([...ue.values()].filter(t=>t.embedded!==!0).map(t=>({spawnSpec:zl(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 jn="dsh-tty:persist-specs";function dp(e){try{let t=e.filter(r=>yi(r.spawnSpec)).map(r=>({spawnSpec:r.spawnSpec,label:r.label}));t.length===0?localStorage.removeItem(jn):localStorage.setItem(jn,JSON.stringify(t))}catch{}}function up(){try{let e=localStorage.getItem(jn);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>r!==null&&typeof r=="object"&&yi(r.spawnSpec)):[]}catch{return[]}}function fp(){try{let e=sessionStorage.getItem(hs);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===gc&&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 us(e,t){let r=Ee;return new Promise(s=>{let a=null,i=n=>{let o;try{o=JSON.parse(n.data)}catch{return}o.t===e&&(a!==null&&clearTimeout(a),r.removeEventListener("message",i),s(r===Ee?o:null))};a=setTimeout(()=>{r.removeEventListener("message",i),s(null)},t),r.addEventListener("message",i)})}function Or(e){if(e===void 0||e.fit===void 0)return;let t=e.fit.proposeDimensions();t!==void 0&&Me({t:"resize",sid:e.sid,cols:t.cols,rows:t.rows})}function pp(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||Or(e)}function Sr(e,t,r,s){if(e.overlayEl===null||e.overlayEl===void 0)return;let a=e.overlayEl;if(t===""||t===void 0){a.textContent="";return}let i=s==="error"||s==="info"?s:"exited";a.innerHTML='<div class="tt_overlayCard" data-kind="'+i+'"><span class="tt_overlayIcon">'+(i==="error"?hc:i==="info"?eo:ip)+'</span><span class="tt_overlayText"><span class="tt_overlayMain"></span>'+(r===void 0||r===""?"":'<span class="tt_overlayHint"></span>')+"</span></div>",a.querySelector(".tt_overlayMain").textContent=t,r!==void 0&&r!==""&&(a.querySelector(".tt_overlayHint").textContent=r)}function _p(e,t){try{let r=getComputedStyle(document.documentElement).getPropertyValue(e).trim();return r!==""?r:t}catch{return t}}function Ir(e){let t=_p("--dsw-alias-state-business-primary","#7c9cff"),r=new Jl.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:{background:"#0b0e14",foreground:"#d7dce5",cursor:t,cursorAccent:"#0b0e14",selectionBackground:"rgba(124, 156, 255, .30)",black:"#1b2028",red:"#f07178",green:"#7ec699",yellow:"#e6b673",blue:"#7aa2f7",magenta:"#c792ea",cyan:"#7fdbca",white:"#c8d0dc",brightBlack:"#556070",brightRed:"#ff8b92",brightGreen:"#9fe0b4",brightYellow:"#f5cc8c",brightBlue:"#9ab8ff",brightMagenta:"#dbb3ff",brightCyan:"#a3f0e2",brightWhite:"#eef2f8"}}),s=new Xl.FitAddon,a=new Qo;r.loadAddon(s),r.loadAddon(a),r.loadAddon(new ea);let i=document.createElement("div");i.className="tt_term";let n=document.createElement("div");n.className="tt_overlay",n.addEventListener("click",()=>{n.textContent="",fs(e.sid)}),n.setAttribute("role","button"),n.setAttribute("aria-label",S("btn.reopenSession")),n.tabIndex=0,n.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" "||o.key==="Spacebar")&&(o.preventDefault(),n.textContent="",fs(e.sid))}),i.appendChild(n),r.open(i);try{s.fit()}catch{}try{let o=new Sl;o.onContextLoss(()=>{try{o.dispose()}catch{}}),r.loadAddon(o)}catch{}r.onData(o=>{Me({t:"input",sid:e.sid,d:o})}),r.onResize(()=>{yi(e.spawnSpec)&&mc(200)}),r.attachCustomKeyEventHandler(o=>e.embedded===!0?!0:(o.ctrlKey||o.metaKey)&&o.key.toLowerCase()==="f"?(o.preventDefault(),Uc(),!1):!0),e.term=r,e.fit=s,e.search=a,e.termEl=i,e.overlayEl=n}function $l(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 mp(e){let t=$l(e);if(t==="")return null;for(let r of ue.values())if(r.exited!==!0&&r.embedded!==!0&&$l(r.spawnSpec)===t)return r;return null}function ui(e,t){let r=bs(),s={sid:r,term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:e??Gp(),label:t};return Ir(s),ue.set(r,s),vi+=1,it(),Zt(r),xs(s),Xt(),s}function gp(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===""||ue.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:Un()},label:"agent"+(t.kind==="ssh"&&typeof t.target=="string"&&t.target!==""?" \xB7 "+t.target:"")};Ir(s),ue.set(r,s),vi+=1,it(),vp()&&s.termEl!==null&&rt!==null&&Re===null&&Zt(r),Me({t:"attach",sid:r}),bp()}}function vp(){return ce!==null&&qe!==!0}function bp(){try{Xt()}catch{}}function wp(e){if(gp(e),!Array.isArray(e))return;let t=new Set(e.filter(r=>r!==null&&typeof r=="object"&&r.owner==="agent").map(r=>r.sid));for(let[r,s]of[...ue])s.agentOwned===!0&&(t.has(r)||s.exited!==!0&&s.live===!0&&(s.exited=!0,s.live=!1,it()))}function yp(e){if(ue.has(e.sid))return ue.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};Ir(t),ue.set(t.sid,t),vi+=1,it(),Zt(t.sid),Me({t:"attach",sid:t.sid})}function Sp(e){if(!(e?.spawnSpec?.credsStripped!==!0||e.term===null))try{e.term.writeln("\x1B[2m[dsh-tty] "+S("msg.passwordNotStored")+"\x1B[0m")}catch{}}function xs(e){Sp(e);let t=e.fit!==null?e.fit.proposeDimensions():void 0,r={...e.spawnSpec,sid:e.sid,cols:t!==void 0?t.cols:80,rows:t!==void 0?t.rows:24};if(Ee===null||Ee.readyState!==WebSocket.OPEN){Hn.add({tab:e,frame:r});return}Me(r)}function ql(e){let t={sid:bs(),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};Ir(t),ue.set(t.sid,t),vi+=1,it(),Zt(t.sid),xs(t)}function fs(e){let t=ue.get(e);if(t===void 0)return;if(t.embedded===!0){yc(t);return}let r=t.spawnSpec,s=t.label;if(Me({t:"kill",sid:e}),t.term!==null)try{t.term.dispose()}catch{}t.termEl!==null&&t.termEl.remove(),ue.delete(e);let a={sid:bs(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,spawnSpec:r,label:s};Ir(a),ue.set(a.sid,a),it(),Zt(a.sid),xs(a),Xt()}function Kl(e){let t=ue.get(e);if(t!==void 0){if(gt!==null&>.ownerKey===e&&ai(!0),Me({t:"kill",sid:e}),ue.delete(e),gi.delete(e),t.term!==null)try{t.term.dispose()}catch{}if(t.termEl!==null&&t.termEl.remove(),Re===e){Re=null;let r=[...ue.entries()].filter(([,s])=>s.embedded!==!0).map(([s])=>s).pop()??null;r!==null&&Zt(r)}it(),ro(),[...ue.values()].some(r=>r.embedded!==!0)?Xt():_i()}}function vc(e){let t=typeof e?.command=="string"?e.command.trim():"";if(t==="")throw new Error(S("error.terminalNeedsCommand"));if(/[\r\n\0]/.test(t))throw new Error(S("error.terminalCommandSingleLine"));return t}function bc(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 Cp(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&&Or(e)}}),t.observer.observe(t.hostEl))}function wc(e,t,r){let s={sid:bs(),term:null,fit:null,search:null,termEl:null,overlayEl:null,exited:!1,spawned:!1,embedded:!0,controller:e,spawnSpec:t,label:r};return Ir(s),ue.set(s.sid,s),gi.add(s.sid),e.hostEl.appendChild(s.termEl),Cp(s),xs(s),s}function yc(e){let t=e.controller;if(!(t===void 0||t.disposed)){e.exited||Me({t:"kill",sid:e.sid});try{e.term?.dispose()}catch{}return e.termEl?.remove(),ue.delete(e.sid),gi.delete(e.sid),t.observer!==null&&(t.observer.disconnect(),t.observer=null),t.tab=wc(t,e.spawnSpec,e.label),Re===e.sid&&(Re=t.tab.sid,ro()),t.tab}}function xp(e,t){if(!(e instanceof HTMLElement))throw new Error(S("error.terminalNeedsHost"));let r=vc(t),s=bc(t,r),a=typeof t?.label=="string"&&t.label!==""?t.label:void 0;mi();let i={hostEl:e,tab:null,observer:null,disposed:!1};return i.tab=wc(i,s,a),Yp(),()=>kp(i)}function kp(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||Me({t:"kill",sid:t.sid});try{t.term?.dispose()}catch{}t.termEl?.remove(),ue.delete(t.sid),gi.delete(t.sid),e.tab=null}if(ce===null&&!to()&&Ee!==null){di=!0;try{Ee.close()}catch{}Ee=null}}var Ep=460,Lp=280,Tp=320,Rp=160,gt=null,Cr=Ep,xr=Tp;function io(){let e=ce!==null?ce.querySelector(".tt_modal"):null,t=e!==null?e:ce;return t!==null?t.getBoundingClientRect():null}var so=e=>e==="bottom"?Rp:Lp;function Mp(e){let t=io();if(t===null)return 900;let r=e==="bottom"?t.height:t.width;return Math.max(so(e),Math.round(r*.72))}function oi(e,t){return Math.min(Mp(e),Math.max(so(e),Math.round(t)))}function rs(){let e=gt;if(e!==null){if(e.collapsed){e.el.style.width="",e.el.style.height="",e.el.style.flexBasis="";return}if(e.side==="bottom"){xr=oi("bottom",xr),e.el.style.width="",e.el.style.height=String(xr)+"px",e.el.style.flexBasis=String(xr)+"px";return}Cr=oi("right",Cr),e.el.style.height="",e.el.style.width=String(Cr)+"px",e.el.style.flexBasis=String(Cr)+"px"}}function ai(e){let t=gt;if(t!==null){if(gt=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{}ct!==null&&delete ct.dataset.side}}function Sc(e){if(Jn(),ct===null)throw new Error(S("error.panelNotReady"));gt!==null&&ai(!0),mi();let t=yr(e?.ownerSid,Re),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:so(r)));if(typeof e?.size=="number"&&Number.isFinite(e.size)){let c=oi(r,e.size);r==="bottom"?xr=c:Cr=c}let a=document.createElement("div");a.className="tt_dockPane",a.dataset.side=r,ct.dataset.side=r,a.innerHTML='<div class="tt_dockPaneResize" title="'+S(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="'+S("btn.closePane")+'">'+ys+'</button></div><div class="tt_dockPaneBody"></div>',ct.appendChild(a);let i=a.querySelector(".tt_dockPaneTitle"),n=a.querySelector(".tt_dockPaneHint"),o=a.querySelector(".tt_dockPaneBody"),u=a.querySelector(".tt_dockPaneFold"),l=a.querySelector(".tt_dockPaneClose"),_=a.querySelector(".tt_dockPaneResize"),m={el:a,element:o,disposed:!1,collapsed:!1,side:r,minSize:s,ownerKey:t,onClose:typeof e?.onClose=="function"?e.onClose:null},w=()=>r==="bottom"?m.collapsed?Zn:Qf:m.collapsed?cc:lc,p=c=>{m.collapsed=c===!0,m.collapsed?a.dataset.collapsed="1":delete a.dataset.collapsed,u.innerHTML=w(),u.title=m.collapsed?S("btn.expandPane"):S("btn.collapsePane"),u.setAttribute("aria-label",u.title),rs()};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||gt!==m||ai(!1)},_.addEventListener("mousedown",c=>{if(c.button!==0||m.collapsed)return;c.preventDefault();let d=c.clientX,h=c.clientY,f=a.getBoundingClientRect(),g=v=>{r==="bottom"?xr=oi("bottom",Math.max(s,f.height+(h-v.clientY))):Cr=oi("right",Math.max(s,f.width+(d-v.clientX))),rs()},C=()=>{document.removeEventListener("mousemove",g),document.removeEventListener("mouseup",C),document.body.style.userSelect=""};document.body.style.userSelect="none",document.addEventListener("mousemove",g),document.addEventListener("mouseup",C)}),_.addEventListener("dblclick",()=>p(!m.collapsed)),u.addEventListener("click",()=>p(!m.collapsed)),l.addEventListener("click",()=>ai(!0)),m.setTitle(typeof e?.title=="string"?e.title:""),m.setHint(typeof e?.hint=="string"?e.hint:""),p(e?.collapsed===!0),gt=m,rs(),Cc(),m}function Cc(){let e=gt;if(e!==null){if(Rn(e.ownerKey,Re)){delete e.el.dataset.dockHidden,ct!==null&&(ct.dataset.side=e.side);return}e.el.dataset.dockHidden="1",ct!==null&&delete ct.dataset.side}}function Zt(e){let t=ue.get(e);if(t!==void 0&&t.embedded!==!0){Re=e;for(let[r,s]of ue)s.embedded!==!0&&s.termEl!==null&&(s.termEl.style.display=r===e?"":"none");t.embedded!==!0&&rt!==null&&t.termEl!==null&&t.termEl.parentElement!==rt&&rt.appendChild(t.termEl),wi(),lr(),it(),sr(),Cc();try{t.fit.fit()}catch{}t.spawned&&!t.exited&&Or(t),Sr(t,t.exited?S("status.exited"):"",t.exited?S("btn.clickReopen"):"","exited"),ro()}}function Bn(e){if(kt===null)return;let t=ue.get(e);if(t===void 0)return;let s=kt.querySelector(`[data-sid="${e}"]`)?.querySelector(".tt_tabDot");s!=null&&(s.dataset.state=t.exited?"exited":t.live===!0?"connected":t.errored===!0?"error":"connecting")}var On=!1;function it(){if(kt===null)return;if(kt.querySelector(".tt_tabRename")!==null){On||(On=!0,setTimeout(()=>{On=!1,it()},1e3));return}kt.textContent="";for(let[r,s]of ue){if(s.embedded===!0)continue;let a=document.createElement("button");a.className="tt_tab",a.dataset.sid=r,r===Re&&(a.dataset.active="");let i=document.createElement("span");i.className="tt_tabDot",i.dataset.state=s.exited?"exited":s.live===!0?"connected":s.errored===!0?"error":"connecting",a.appendChild(i);let n=document.createElement("span");n.className="tt_tabLabel",n.textContent=s.label||S("panel.tabLabel",{n:kc(r)}),n.addEventListener("dblclick",u=>{u.stopPropagation(),Pp(r,a)});let o=document.createElement("span");o.className="tt_tabClose",o.title=S("btn.close"),o.textContent="\u2715",o.setAttribute("role","button"),o.setAttribute("aria-label",S("btn.closeTabAria",{label:s.label||""})),o.tabIndex=0,o.addEventListener("keydown",u=>{(u.key==="Enter"||u.key===" "||u.key==="Spacebar")&&(u.preventDefault(),u.stopPropagation(),Kl(r))}),a.title=n.textContent,a.appendChild(n),a.appendChild(o),a.addEventListener("click",u=>{if(u.target.closest(".tt_tabClose")!==null){u.stopPropagation(),Kl(r);return}Zt(r)}),kt.appendChild(a)}let e=kt.querySelector("[data-active]");e!==null&&typeof e.scrollIntoView=="function"&&e.scrollIntoView({block:"nearest",inline:"nearest"});let t=document.createElement("button");t.className="tt_tabAdd",t.title=S("btn.newTab"),t.innerHTML=Xf,t.addEventListener("click",()=>{Np(t)}),kt.appendChild(t)}function Ap(e){return e?.direction==="remote"?S("meta.tunnelRemote",{host:e.remoteHost||"127.0.0.1",port:String(e.remotePort??0),local:String(e.localTargetPort??0)}):S("meta.tunnelLocal",{local:String(e?.localPort??0),host:e?.remoteHost??"?",port:String(e?.remotePort??0)})}function sr(){if(ei===null||as===null||ri===null||ti===null)return;ri.textContent="";let e=dt(),t=e?.spawnSpec??{};if(e===void 0||t.t!=="ssh"){ei.dataset.hidden="";return}delete ei.dataset.hidden;let r=Number(t.port);as.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:""),lt!==null&&(e.persistTmux===!0?(lt.textContent="tmux",lt.dataset.state="ok",lt.title=S("status.tmuxPersistedTitle")):t.persist===!0&&e.spawned===!0?(lt.textContent=S("status.notPersisted"),lt.dataset.state="warn",lt.title=S("status.tmuxUnavailableTitle")):(lt.textContent="",delete lt.dataset.state,lt.removeAttribute("title")));let s=e.exited?"exited":e.live===!0?"connected":e.errored===!0?"error":"connecting";ti.dataset.state=s,ti.title=S(s==="connected"?"status.connected":s==="connecting"?"status.connecting":s==="error"?"status.errored":"status.exited");let a=(n,o,u,l)=>{let _=document.createElement("button");_.type="button",_.className="tt_toolBtn tt_connAct",_.title=u,_.innerHTML=n+"<span></span>",_.lastElementChild.textContent=o,_.addEventListener("click",l),ri.appendChild(_)};if(typeof t.command=="string"&&t.command!=="")return;let i=typeof t.name=="string"?t.name:"";for(let n of Wn)try{n({tab:e,spec:t,bookName:i,addAction:a})}catch(o){console.warn("[dsh-tty] connbar action failed: "+(o instanceof Error?o.message:String(o)))}}function Dp(e,t){if(Rr!==null){is();return}let r=document.createElement("div");r.className="tt_addMenu tt_connMore",Rr=r,Kn(r,S("panel.tunnels"),S("hint.tunnelsSettings"),()=>{is(),xc(e,t)},void 0,ic),document.body.appendChild(r);let s=e.getBoundingClientRect(),a=r.offsetWidth,n=s.left+a>window.innerWidth-8?s.right-a:s.left;r.style.left=Math.max(8,Math.min(n,window.innerWidth-a-8))+"px",r.style.top=s.bottom+6+"px";let o=u=>{Rr===r&&(r.contains(u.target)||e.contains(u.target)||is())};ns=o,setTimeout(()=>document.addEventListener("mousedown",o,!0),0)}function is(){ns!==null&&(document.removeEventListener("mousedown",ns,!0),ns=null),Rr!==null&&(Rr.remove(),Rr=null)}var tr=null,ss=null,Rr=null,ns=null;function ps(){ss!==null&&(document.removeEventListener("mousedown",ss,!0),ss=null),tr!==null&&(tr.remove(),tr=null)}function xc(e,t){if(tr!==null){ps();return}let r=document.createElement("div");r.className="tt_tunnelPop";let s=document.createElement("div");s.className="tt_tunnelPopTitle",s.textContent=S("panel.tunnelsFor",{name:t}),r.appendChild(s);let a=document.createElement("div");a.textContent=S("list.loading"),r.appendChild(a);let i=document.createElement("span");i.className="tt_cardHint",i.textContent=S("hint.tunnelsCard"),r.appendChild(i),document.body.appendChild(r),tr=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 o=u=>{tr===r&&(r.contains(u.target)||e.contains(u.target)||ps())};ss=o,setTimeout(()=>document.addEventListener("mousedown",o,!0),0),(async()=>{let u=[];try{let m=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();m.ok&&Array.isArray(m.tunnels)&&(u=m.tunnels)}catch{}if(tr!==r)return;a.textContent="";let l=no.filter(_=>_?.bookName===t&&_?.enabled!==!1);if(l.length===0){let _=document.createElement("span");_.className="tt_cardHint",_.textContent=S("list.noActiveTunnels"),a.appendChild(_);return}for(let _ of l){let m=u.find(h=>h?.name===_?.name),w=m?.state??"stopped",p=document.createElement("div");p.className="tt_tunnelPopRow";let c=document.createElement("span");c.className="tt_connDot",c.dataset.state=w==="active"?"connected":w==="error"?"error":"connecting";let d=document.createElement("span");d.className="tt_connTarget",d.title=String(m?.error??m?.lastForwardError??""),d.textContent=Ap(_)+" \xB7 "+w+(m?.fatal===!0?S("status.fatalSuffix"):""),p.appendChild(c),p.appendChild(d),a.appendChild(p)}})()}function kc(e){let t=1;for(let r of ue.keys()){if(r===e)return String(t);t+=1}return String(t)}function Pp(e,t){let r=ue.get(e);if(r===void 0||t.querySelector(".tt_tabRename")!==null)return;let s=t.querySelector(".tt_tabLabel");if(s===null)return;let a=document.createElement("input");a.className="tt_tabRename",a.value=r.label||S("panel.tabLabel",{n:kc(e)}),s.replaceWith(a),a.focus(),a.select();let i=!1,n=()=>{if(i)return;i=!0;let u=a.value.trim();r.label=u!==""?u:void 0,it(),Xt()},o=()=>{i||(i=!0,it())};a.addEventListener("keydown",u=>{u.stopPropagation(),u.key==="Enter"?n():u.key==="Escape"&&o()}),a.addEventListener("blur",n),a.addEventListener("click",u=>u.stopPropagation())}var no=[],Ec="dialog",Yt="off",Jt={maxDownloadMb:1024,maxUploadMb:2048,maxUploadFiles:1e3},Mr=null,Lc=!1,Tc=!1,Vt=null,_s=null,nr=!1;function Rc(e){nr=e,_s!==null&&_s.set(e)}function Bp(e){Rc(!(e!==null&&typeof e=="object"&&e.enabled===!1)),e!==null&&typeof e=="object"&&typeof e.statsEnabled=="boolean"&&e.statsEnabled!==ds&&(ds=e.statsEnabled,wi(),lr())}function fi(e){Bp(e),e!==null&&typeof e=="object"&&Array.isArray(e.sshHosts)&&(Ht=e.sshHosts),e!==null&&typeof e=="object"&&Array.isArray(e.tunnels)&&(no=e.tunnels),e!==null&&typeof e=="object"&&(e.sftpStyle==="dual"||e.sftpStyle==="dialog")&&(Ec=e.sftpStyle),e!==null&&typeof e=="object"&&(e.persistence==="tmux"||e.persistence==="off")&&(Yt=e.persistence),e!==null&&typeof e=="object"&&typeof e.sftpLimits=="object"&&e.sftpLimits!==null&&(Jt={...Jt,...e.sftpLimits}),e!==null&&typeof e=="object"&&Number.isInteger(e.maxSessions)&&e.maxSessions>=1&&(Mr=e.maxSessions),e!==null&&typeof e=="object"&&typeof e.allowProxyCommand=="boolean"&&(Lc=e.allowProxyCommand),e!==null&&typeof e=="object"&&typeof e.allowProxyCommandGranted=="boolean"&&(Tc=e.allowProxyCommandGranted)}function Op(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"?hc:r==="info"?rp:tp)+'</span><span class="tt_toastText"></span>',s.lastElementChild.textContent=e,document.body.appendChild(s),setTimeout(()=>s.remove(),4e3)}async function Mc(){try{Me({t:"sessions"});let e=await us("sessions",3e3);if(e!==null&&Array.isArray(e.list))return Vt=e.list.length,Vt}catch{}return null}async function ms(){if(await Mc(),Mr===null||Vt===null||Vt<Mr)return null;let e=[...ue.values()].filter(a=>!a.exited).length,t=Math.max(0,Vt-e),r=t>0?S("msg.maxSessionsOthers",{count:t}):"",s=S("msg.maxSessions",{live:Vt,max:Mr,own:e,others:r});return Op(s),s}function Ip(){return Mr!==null&&Vt!==null&&Vt>=Mr}function oo(){return Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4)}function Ac(e){return no.filter(t=>t?.bookName===e&&t?.enabled!==!1).length}function zn(e){let t=Number(e?.port),r=Number.isInteger(t)&&t!==22?":"+t:"",s=e?.auth==="key"?"key":e?.auth==="password"?"password":"agent",a=e?.agentForward===!0?" \xB7 fwd":"";return String(e?.username??"")+"@"+String(e?.host??"")+r+" \xB7 "+s+a}async function $n(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:S("error.probeHttp",{status:r.status}))}}function qn(e,t){if(!e)return S("msg.probing");let r=e,s=typeof r.tcp?.ms=="number"?r.tcp.ms:null,a=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":S("meta.reachable"):S("meta.unreachable");i.push(S("meta.jumpStage",{label:r.jump.label})+" "+m)}r.proxy!==null&&typeof r.proxy=="object"&&i.push(r.proxy.active===!0?S("meta.probeProxy"):S("meta.probeProxyOff")),r.tcp?.ok?i.push("TCP "+(s!==null?s+"ms":S("meta.reachable"))):r.tcp?.skipped===!0&&i.push(S("meta.probeTcpSkipped")),r.banner?.ok&&i.push(S("meta.probeBanner"));let n=r.hostkey?.state;if(n==="matched"?i.push(S("meta.hostKeyMatched")):n==="recorded"?i.push(S("meta.hostKeyRecorded")):n==="mismatch"&&i.push(S("meta.hostKeyMismatch")),r.auth?.ok){let _=a!==null?S("meta.authOkMs",{ms:a}):S("meta.authOk");return S("meta.probeOk",{detail:_+(i.length?" \xB7 "+i.join(" \xB7 "):"")})}let o=r.tcp?.skipped===!0?"":r.tcp?.error,l=(r.auth?.error||o||S("error.unknown"))+(i.length?" \xB7 "+i.join(" \xB7 "):"");return t?.prefix!==void 0?t.prefix+l:S("error.probeFailed",{detail:l})}async function ao(){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=Ht;fi(t.config),ht!==null&&Ht!==r&&Gn(ht)}}catch{}}function Dc(e){ht!==null&&(e.target instanceof Element&&(ht.contains(e.target)||e.target.closest(".tt_tabAdd")!==null)||Et())}function Np(e){if(ht!==null){Et();return}ao(),Mc().then(()=>{ht!==null&&Gn(ht)});let t=document.createElement("div");t.className="tt_addMenu",ht=t,Gn(t),document.body.appendChild(t);let r=e.getBoundingClientRect(),s=t.offsetWidth,i=r.left+s>window.innerWidth-8?r.right-s:r.left;t.style.left=Math.max(8,Math.min(i,window.innerWidth-s-8))+"px",t.style.top=r.bottom+6+"px",document.addEventListener("mousedown",Dc,!0)}function Et(){ht!==null&&(document.removeEventListener("mousedown",Dc,!0),ht.remove(),ht=null)}function Kn(e,t,r,s,a,i){let n=document.createElement("button");if(n.type="button",n.className="tt_addMenuItem",a===!0&&(n.setAttribute("data-soldout",""),n.title=S("btn.maxSessionsTitle")),i!==void 0){let l=document.createElement("span");l.className="tt_addMenuIcon",l.innerHTML=i,n.appendChild(l)}let o=document.createElement("span");o.className="tt_addMenuText";let u=document.createElement("span");if(u.className="tt_addMenuMain",u.textContent=t,o.appendChild(u),r!==""){let l=document.createElement("span");l.className="tt_addMenuSub",l.textContent=r,o.appendChild(l)}n.appendChild(o),n.addEventListener("click",s),e.appendChild(n)}function Gn(e){e.textContent="";let t=Ip();Kn(e,S("option.localTerminal"),S(Yt==="tmux"?"hint.tmuxHosted":"hint.openInSessionCwd"),async()=>{await ms()||(Et(),ui())},t,ws);let r=document.createElement("div");r.className="tt_addMenuSep",e.appendChild(r);let s=document.createElement("div");s.className="tt_addMenuTitle",s.textContent=S("panel.sshBook"),e.appendChild(s);for(let i of Ht){if(i===null||typeof i!="object"||typeof i.name!="string"||i.name==="")continue;let n=document.createElement("div");n.className="tt_addMenuRow";let o=document.createElement("button");o.type="button",o.className="tt_addMenuItem",t&&(o.setAttribute("data-soldout",""),o.title=S("btn.maxSessionsTitle"));let u=document.createElement("span");u.className="tt_addMenuIcon",u.innerHTML=ep;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 w=Ac(i.name),p=Ln(i.jump);m.textContent=zn(i)+(p===""?"":" "+S("meta.viaJump",{label:p}))+(typeof i.proxyCommand=="string"&&i.proxyCommand.trim()!==""?" "+S("meta.viaProxy"):"")+(w>0?" \xB7 \u21C4"+String(w):""),l.appendChild(_),l.appendChild(m),o.appendChild(u),o.appendChild(l),o.addEventListener("click",async()=>{if(await ms())return;Et();let h=Yt==="tmux"&&i.persist!==!1?{persist:!0,persistName:oo()}:{};ui({t:"ssh",name:i.name,...h},i.name)});let c=document.createElement("button");c.type="button",c.className="tt_addMenuEdit",c.title=S("btn.sftpFileBrowse"),c.innerHTML=ci,c.addEventListener("click",()=>{Et(),ks({name:i.name})});let d=document.createElement("button");d.type="button",d.className="tt_addMenuEdit",d.title=S("btn.editConnection"),d.innerHTML=Qn,d.addEventListener("click",()=>{Et(),Gl(i)}),n.appendChild(o),n.appendChild(c),n.appendChild(d),e.appendChild(n)}if(Ht.length===0){let i=document.createElement("div");i.className="tt_addMenuTitle",i.textContent=S("list.emptySshBook"),e.appendChild(i)}let a=document.createElement("div");a.className="tt_addMenuSep",e.appendChild(a),Kn(e,S("option.sshConnect"),S("hint.sshConnect"),()=>{Et(),Gl()},!1,dc)}function Gl(e){if(Tr!==null)return;let t=e!==null&&typeof e=="object"?e:null,r=t!==null,s=document.createElement("div");s.className="tt_sshBackdrop";let a=document.createElement("div");a.className="tt_sshCard";let i=document.createElement("div");i.className="tt_sshTitle",i.innerHTML=dc+"<span></span>",i.lastElementChild.textContent=r?S("panel.editConnection",{name:String(t.name??"")}):S("panel.sshConnect"),a.appendChild(i);let n=Z=>{let te=document.createElement("div");return te.className="tt_sshSection",te.textContent=Z,te},o={},u=(Z,te,le)=>{let ie=document.createElement("label");ie.className="tt_sshRow";let ne=document.createElement("span");ne.className="tt_cardLabel",ne.textContent=te,ie.appendChild(ne);let oe;if(le?.select!==void 0){oe=document.createElement("select");for(let pe of le.select){let we=document.createElement("option");we.value=pe.value,we.textContent=pe.label,oe.appendChild(we)}}else oe=document.createElement("input"),oe.type=le?.type??"text",oe.placeholder=le?.placeholder??"";return oe.className="tt_cardInput",oe.autocomplete="off",oe.spellcheck=!1,ie.appendChild(oe),o[Z]=oe,ie};a.appendChild(n(S("section.connection")));let l=document.createElement("div");l.className="tt_sshGrid",l.appendChild(u("host",S("field.host"),{placeholder:S("placeholder.host")})),l.appendChild(u("port",S("field.port"),{placeholder:"22"})),a.appendChild(l),a.appendChild(u("username",S("field.username"),{placeholder:"root"})),a.appendChild(n(S("section.auth"))),a.appendChild(u("auth",S("field.authMethod"),{select:[{value:"agent",label:S("option.authAgent")},{value:"key",label:S("option.authKey")},{value:"password",label:S("option.authPassword")}]}));let _=u("keyPath",S("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),m=u("passphrase",S("field.passphrase"),{type:"password"}),w=u("password",S("field.password"),{type:"password"}),p=(Z,te)=>{let le=document.createElement("div");le.className="tt_sshRow tt_envRow";let ie=document.createElement("input");ie.type="text",ie.className="tt_cardInput",ie.placeholder=S("placeholder.credRef"),ie.title=S("hint.credRefCandidates"),ie.autocomplete="off",ie.spellcheck=!1;let ne=document.createElement("span");ne.className="tt_cardHint tt_envEmpty",ne.textContent=te,ne.hidden=!0,ie.hidden=!0;let oe=document.createElement("div");oe.className="tt_envList",oe.dataset.hidden="";let pe=[],we=()=>{if(oe.textContent="",pe.length===0){let ye=document.createElement("span");ye.className="tt_cardHint",ye.textContent=te,oe.appendChild(ye);return}let _e=ie.value.trim().toUpperCase(),Ie=_e===""?pe:pe.filter(ye=>ye.toUpperCase().includes(_e));for(let ye of Ie.slice(0,30)){let ve=document.createElement("button");ve.type="button",ve.className="tt_envItem",ve.textContent=ye;let xe="env:"+ye,Ne=null,je=()=>{Ne!==null&&(clearTimeout(Ne),Ne=null),ve.textContent=ye,delete ve.dataset.danger};ve.addEventListener("mousedown",Qt=>Qt.preventDefault()),ve.addEventListener("click",()=>{let Qt=Z.value;if(Qt===""||Qt.startsWith("env:")||Ne!==null){je(),Z.value=xe,Z.focus(),Z.dispatchEvent(new Event("change"));return}ve.textContent=S("list.credOverwrite",{name:ye}),ve.dataset.danger="",Ne=setTimeout(je,4e3)}),oe.appendChild(ve)}if(Ie.length>30){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=S("list.moreMatches",{count:Ie.length-30}),oe.appendChild(ye)}else if(Ie.length===0){let ye=document.createElement("span");ye.className="tt_envMore",ye.textContent=S("list.noCredRef"),oe.appendChild(ye)}};return ie.addEventListener("input",we),ie.addEventListener("focus",()=>{pe.length>0&&delete oe.dataset.hidden}),ie.addEventListener("blur",()=>{ie.value.trim()===""&&(oe.dataset.hidden="")}),le.appendChild(ie),le.appendChild(ne),le.appendChild(oe),{row:le,setNames(_e){pe=Array.isArray(_e)?_e:[];let Ie=pe.length>0;ie.hidden=!Ie,ne.hidden=Ie,we()}}},c=(Z,te)=>{let le=document.createElement("div");le.className="tt_sshRow tt_credRow";let ie=document.createElement("label");ie.className="tt_credToggle";let ne=document.createElement("input");ne.type="checkbox",ne.className="tt_cardCheckbox";let oe=document.createElement("span");oe.textContent=S("check.rememberCredential"),ie.appendChild(ne),ie.appendChild(oe),ne.checked=Lt!==null,ie.title=S("hint.rememberCredential");let pe=document.createElement("button");pe.type="button",pe.className="tt_toolBtn tt_credClear",pe.textContent=S("btn.clearCredential"),pe.dataset.hidden="";let we=document.createElement("span");we.className="tt_credStatus",le.appendChild(ie),le.appendChild(pe),le.appendChild(we);let _e=(ve,xe)=>{we.textContent=ve,we.dataset.kind=xe},Ie=async()=>{let ve=kr(Z.value),xe=ve!=="";if(ie.hidden=xe,pe.hidden=!xe,we.hidden=!1,Ar()===null){ne.disabled=!0,ne.checked=!1,pe.disabled=!0,_e(S(Lt===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),"muted");return}if(ne.disabled=!1,!xe){we.hidden=!0,_e("","plain");return}let Ne=await ec(ve);if(Ne.unreported===!0){_e(S("status.credUnreported",{ref:ve}),"plain");return}if(Ne.error!==void 0){_e(S("error.credStatusFailed",{error:Ne.error}),"error");return}let je=Ne.view;_e(je.configured?S("status.credStored",{ref:ve,source:je.source!==""?S("meta.credSource",{source:je.source}):""}):S("status.credUnknown",{ref:ve}),je.configured?"ok":"plain"),pe.disabled=je.configured!==!0||je.writable!==!0};pe.addEventListener("click",()=>{(async()=>{let ve=kr(Z.value);if(ve==="")return;let xe=await tc(ve);if(xe.error!==void 0){_e(xe.error,"error");return}Z.value="",await Ie()})()});let ye=async()=>{let ve=await rc(ne.checked===!0,Z.value,o.host.value,o.port.value,o.username.value,te);return ve.value!==void 0&&(Z.value=ve.value,await Ie()),ve};return Z.addEventListener("change",()=>{Ie()}),{row:le,refresh:Ie,storeIfRequested:ye}},d=p(o.passphrase,S("hint.noCredRefPassphrase")),h=p(o.password,S("hint.noCredRefPassword")),f=c(o.password,"PASSWORD");(async()=>{let Z=await Ql();d.setNames(Z),h.setNames(Z)})(),a.appendChild(_),a.appendChild(m),a.appendChild(d.row),a.appendChild(w),a.appendChild(f.row),a.appendChild(h.row),a.appendChild(n(S("section.jump")));let g=u("jumpHost",S("field.jumpHost"),{placeholder:S("placeholder.jumpHost")});a.appendChild(g);let C=document.createElement("label");C.className="tt_sshRow";let v=document.createElement("input");v.type="checkbox";let x=document.createElement("span");x.className="tt_cardLabel",x.textContent=S("check.jumpOwnCred"),C.appendChild(v),C.appendChild(x),a.appendChild(C);let b=u("jumpUsername",S("field.jumpUsername"),{placeholder:"root"}),E=u("jumpAuth",S("field.jumpAuth"),{select:[{value:"",label:S("option.authInherit")},{value:"agent",label:S("option.authAgent")},{value:"key",label:S("option.authKey")},{value:"password",label:S("option.authPassword")}]}),O=u("jumpKeyPath",S("field.keyPath"),{placeholder:"~/.ssh/id_ed25519"}),B=u("jumpPassphrase",S("field.passphrase"),{type:"password"}),H=u("jumpPassword",S("field.password"),{type:"password"});for(let Z of[b,E,O,B,H])a.appendChild(Z);let M=document.createElement("div");M.className="tt_cardHint",M.textContent=S("hint.jumpInherit"),a.appendChild(M),a.appendChild(n(S("section.proxyCommand")));let K=u("proxyCommand",S("field.proxyCommand"),{placeholder:S("placeholder.proxyCommand")});a.appendChild(K);let P=document.createElement("div");P.className="tt_cardHint",P.textContent=S("hint.proxyCommand"),a.appendChild(P);let D=document.createElement("div");D.className="tt_cardHint tt_sshProbeWarn",D.textContent=S("hint.proxyCommandDisabled"),a.appendChild(D);let F=()=>{let Z=o.proxyCommand.value.trim()!=="",te=Tc,le=te&&Lc;D.textContent=S(te?"hint.proxyCommandDisabled":"hint.proxyCommandNotGranted"),D.style.display=Z&&!le?"":"none"};o.proxyCommand.addEventListener("input",F),F();let N=()=>{let Z=En(o.jumpHost.value);if(Z===void 0)return;if(v.checked!==!0)return Z;let te={...Z},le=o.jumpUsername.value.trim();le!==""&&(te.username=le);let ie=o.jumpAuth.value;(ie==="agent"||ie==="key"||ie==="password")&&(te.auth=ie);let ne=o.jumpKeyPath.value.trim();return ne!==""&&(te.keyPath=ne),o.jumpPassphrase.value!==""&&(te.passphrase=o.jumpPassphrase.value),o.jumpPassword.value!==""&&(te.password=o.jumpPassword.value),te},y=()=>{let Z=o.proxyCommand.value.trim();return Z===""?void 0:Z},T=()=>{let Z=En(o.jumpHost.value)!==void 0,te=Z&&v.checked===!0;C.style.display=Z?"":"none";for(let le of[b,E,O,B,H])le.style.display=te?"":"none";O.style.display=te&&o.jumpAuth.value==="key"?"":"none",B.style.display=te&&o.jumpAuth.value==="key"?"":"none",H.style.display=te&&o.jumpAuth.value==="password"?"":"none",M.style.display=Z?"":"none"};o.jumpHost.addEventListener("input",T),o.jumpAuth.addEventListener("change",T),v.addEventListener("change",T),a.appendChild(n(S("section.options")));let k=document.createElement("label");k.className="tt_cardRow";let R=document.createElement("input");R.type="checkbox",R.className="tt_cardCheckbox";let U=document.createElement("span");U.className="tt_cardLabel",U.textContent=S("check.agentForward"),k.appendChild(R),k.appendChild(U),a.appendChild(k);let G=document.createElement("label");G.className="tt_cardRow";let J=document.createElement("input");J.type="checkbox",J.className="tt_cardCheckbox";let X=document.createElement("span");X.className="tt_cardLabel",X.textContent=S("check.persist"),G.appendChild(J),G.appendChild(X),J.checked=Yt==="tmux",Yt==="tmux"&&a.appendChild(G);let W=document.createElement("label");W.className="tt_cardRow";let L=document.createElement("input");L.type="checkbox",L.className="tt_cardCheckbox";let I=document.createElement("span");I.className="tt_cardLabel",I.textContent=S("check.saveToBook"),W.appendChild(L),W.appendChild(I),a.appendChild(W);let z=u("name",S("field.bookName"),{placeholder:S("placeholder.bookName")});if(z.style.display="none",a.appendChild(z),L.addEventListener("change",()=>{z.style.display=L.checked?"":"none",L.checked&&o.name.value.trim()===""&&o.host.value.trim()!==""&&(o.name.value=o.host.value.trim()),L.checked&&o.name.focus()}),r){W.style.display="none",o.name.value=String(t.name??""),z.style.display="",o.host.value=String(t.host??""),o.port.value=String(t.port??22),o.username.value=String(t.username??""),o.auth.value=t.auth==="key"||t.auth==="password"?String(t.auth):"agent",o.keyPath.value=String(t.keyPath??""),o.passphrase.value=String(t.passphrase??""),o.password.value=String(t.password??"");let Z=t.jump!==null&&typeof t.jump=="object"?t.jump:null;if(o.jumpHost.value=Ln(Z),Z!==null){let te=Z.auth!==void 0||Z.keyPath!==void 0||Z.password!==void 0||Z.passphrase!==void 0;v.checked=te,te&&(o.jumpUsername.value=String(Z.username??""),o.jumpAuth.value=Z.auth==="key"||Z.auth==="password"?String(Z.auth):"",o.jumpKeyPath.value=String(Z.keyPath??""),o.jumpPassphrase.value=String(Z.passphrase??""),o.jumpPassword.value=String(Z.password??""))}R.checked=t.agentForward===!0,o.proxyCommand.value=String(t.proxyCommand??""),F(),J.checked=Yt==="tmux"}let $=document.createElement("div");$.className="tt_sshStatus";let q=document.createElement("div");q.className="tt_sshError";let ee=document.createElement("div");ee.className="tt_sshProbeResult",$.appendChild(q),$.appendChild(ee),a.appendChild($),T();let he=()=>{q.textContent="";let Z=o.host.value.trim(),te=o.username.value.trim(),le=Number(o.port.value);if((!Number.isInteger(le)||le<1||le>65535)&&(le=22),Z===""||te==="")return q.textContent=S("error.hostUserRequired"),null;let ie=o.auth.value,ne={host:Z,port:le,username:te,auth:ie},oe=N();oe!==void 0&&(ne.jump=oe);let pe=y();if(pe!==void 0&&(ne.proxyCommand=pe),ie==="key"){let we=o.keyPath.value.trim();if(we==="")return q.textContent=S("error.keyPathRequired"),null;ne.keyPath=we;let _e=o.passphrase.value;_e!==""&&(ne.passphrase=_e)}if(ie==="password"){let we=o.password.value;if(we==="")return q.textContent=S("error.passwordRequired"),null;ne.password=we}return R.checked&&(ne.agentForward=!0),ne},de=document.createElement("div");de.className="tt_sshActions";let re=document.createElement("div");re.className="tt_sshActionsGroup";let Y=document.createElement("div");Y.className="tt_sshActionsGroup",de.appendChild(re),de.appendChild(Y);let se=document.createElement("button");se.type="button",se.className="tt_toolBtn",se.textContent=S("btn.cancel");let be=document.createElement("button");be.type="button",be.className="tt_cardSave",be.textContent=S("btn.connect"),re.appendChild(se);let fe=document.createElement("button");fe.type="button",fe.className="tt_toolBtn",fe.textContent=S("btn.fileBrowse"),fe.title=S("btn.browseTitle"),fe.addEventListener("click",()=>{q.textContent="";let Z=o.host.value.trim(),te=o.username.value.trim(),le=Number(o.port.value);if((!Number.isInteger(le)||le<1||le>65535)&&(le=22),Z===""||te===""){q.textContent=S("error.hostUserRequired");return}let ie=o.auth.value,ne={host:Z,port:le,username:te,auth:ie},oe=N();oe!==void 0&&(ne.jump=oe);let pe=y();if(pe!==void 0&&(ne.proxyCommand=pe),ie==="key"){let we=o.keyPath.value.trim();if(we===""){q.textContent=S("error.keyPathRequired");return}ne.keyPath=we;let _e=o.passphrase.value;_e!==""&&(ne.passphrase=_e)}if(ie==="password"){let we=o.password.value;if(we===""){q.textContent=S("error.passwordRequired");return}ne.password=we}R.checked&&(ne.agentForward=!0),Gt(),ks(ne)}),re.appendChild(fe);let ge=null;r&&(ge=document.createElement("button"),ge.type="button",ge.className="tt_toolBtn",ge.textContent=S("btn.saveEdit"),ge.addEventListener("click",()=>{q.textContent="";let Z=o.host.value.trim(),te=o.username.value.trim();if(Z===""||te===""){q.textContent=S("error.hostUserRequired");return}let le=Number(o.port.value);(!Number.isInteger(le)||le<1||le>65535)&&(le=22);let ie=o.auth.value,oe={name:o.name.value.trim()||Z,host:Z,port:le,username:te,auth:ie,keyPath:ie==="key"?o.keyPath.value.trim():"",passphrase:o.passphrase.value,password:o.password.value,agentForward:R.checked,persist:J.checked},pe=N();if(pe!==void 0&&(oe.jump=pe),oe.proxyCommand=o.proxyCommand.value.trim(),ie==="key"&&oe.keyPath===""){q.textContent=S("error.keyPathRequired");return}ge!==null&&(ge.disabled=!0),(async()=>{let we=await f.storeIfRequested();if(we.error!==void 0){q.textContent=we.error,ge!==null&&(ge.disabled=!1);return}we.value!==void 0&&(oe.password=we.value);let _e=await Fp(String(t.name??""),oe);if(ge!==null&&(ge.disabled=!1),_e!==void 0){q.textContent=S("error.saveCredFailed",{error:_e});return}Gt()})()}),re.appendChild(ge));let Le=document.createElement("button");Le.type="button",Le.className="tt_toolBtn",Le.textContent=S("btn.probe"),Le.title=S("btn.probeTitle"),Le.addEventListener("click",()=>{let Z=he();Z!==null&&(ee.className="tt_sshProbeResult",ee.textContent=S("msg.probing"),Le.disabled=!0,$n(Z,!1).then(te=>{Le.disabled=!1,te.result?(ee.className="tt_sshProbeResult"+(te.result.auth?.ok===!0?" tt_sshProbeOk":" tt_sshProbeBad"),ee.textContent=qn(te.result)):(ee.className="tt_sshProbeResult tt_sshProbeBad",ee.textContent=S("error.probeFailed",{detail:String(te.error||S("error.unknown"))}))}))}),re.appendChild(Le),Y.appendChild(be),a.appendChild(de);let Ce=()=>{_.style.display=o.auth.value==="key"?"":"none",m.style.display=o.auth.value==="key"?"":"none",d.row.style.display=o.auth.value==="key"?"":"none",w.style.display=o.auth.value==="password"?"":"none",h.row.style.display=o.auth.value==="password"?"":"none",f.row.style.display=o.auth.value==="password"?"":"none"};o.auth.addEventListener("change",Ce),Ce(),f.refresh(),se.addEventListener("click",()=>Gt()),s.addEventListener("mousedown",Z=>{Z.target===s&&Gt()}),be.addEventListener("click",async()=>{q.textContent="";let Z=await ms();if(Z!==null){q.textContent=Z;return}let te=o.host.value.trim(),le=o.username.value.trim(),ie=Number(o.port.value);if((!Number.isInteger(ie)||ie<1||ie>65535)&&(ie=22),te===""||le===""){q.textContent=S("error.hostUserRequired");return}let ne=o.auth.value,oe={t:"ssh",host:te,port:ie,username:le,auth:ne},pe=N();pe!==void 0&&(oe.jump=pe);let we=y();if(we!==void 0&&(oe.proxyCommand=we),ne==="key"){let ve=o.keyPath.value.trim();ve!==""&&(oe.keyPath=ve);let xe=o.passphrase.value;xe!==""&&(oe.passphrase=xe)}if(ne==="password"){let ve=o.password.value;ve!==""&&(oe.password=ve)}R.checked&&(oe.agentForward=!0),J.checked&&(oe.persist=!0,oe.persistName=oo());let _e=ie!==22?le+"@"+te+":"+ie:le+"@"+te,Ie=ve=>{Gt(),ce!==null&&ui(oe,ve!==""?ve:_e)};if(!L.checked){Ie("");return}let ye=o.name.value.trim()||te;be.disabled=!0,(async()=>{let ve=await f.storeIfRequested();if(ve.error!==void 0){q.textContent=ve.error,be.disabled=!1;return}let xe=ve.value??oe.password??"",Ne=await Hp({name:ye,host:te,port:ie,username:le,auth:ne,keyPath:oe.keyPath??"",passphrase:oe.passphrase??"",password:xe,agentForward:R.checked,persist:J.checked,...pe!==void 0?{jump:pe}:{},proxyCommand:o.proxyCommand.value.trim()});if(be.disabled=!1,Ne!==void 0){q.textContent=S("error.saveBookFailed",{error:Ne});return}Ie(ye)})()}),s.appendChild(a),document.body.appendChild(s),Tr=s,o.host.focus()}function Gt(){Tr!==null&&(Tr.remove(),Tr=null)}async function Hp(e){let t=[...Ht.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);fi(s.config);return}catch(r){return String(r&&r.message?r.message:r)}}async function Fp(e,t){if(t.name!==e&&Ht.some(s=>s?.name===t.name))return S("error.bookNameTaken",{name:t.name});let r=Ht.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})}),a=await s.json().catch(()=>({}));if(!s.ok||!a.ok)return String(a.error||"HTTP "+s.status);fi(a.config);return}catch(s){return String(s&&s.message?s.message:s)}}function Wp(e,t,r){let s=yr(r,Re);if(Bc(s))return;let a=document.createElement("div");a.className="tt_sftpDualCard";let i=document.createElement("div");i.className="tt_sftpTitleRow";let n=document.createElement("div");n.className="tt_sshTitle",n.innerHTML=ci+"<span></span>",n.lastElementChild.textContent=S("panel.sftpDual",{label:t});let o=document.createElement("button");o.type="button",o.className="tt_close",o.title=S("btn.close"),o.innerHTML=ys,o.addEventListener("click",()=>Br(s)),i.appendChild(n),i.appendChild(o),a.appendChild(i);let u=document.createElement("div");u.className="tt_sftpStatus";let l=(y,T)=>{u.textContent=y,T===void 0?delete u.dataset.state:u.dataset.state=T},_=!1,m=(y,T)=>{if(!(_||p.local.busy||p.remote.busy)){_=!0;for(let k of[p.local,p.remote])k.setBusy(!0);l(y,"busy"),Promise.resolve().then(T).catch(k=>{(k===null||typeof k!="object"||k.name!=="TransferCanceledError")&&P.fail(S("status.failed")),l(String(k&&k.message?k.message:k),"error")}).finally(()=>{_=!1;for(let k of[p.local,p.remote])k.setBusy(!1)})}},w=y=>{p[y].bar.after(d),d.style.display="",h.focus(),h.select()},p={},c=(y,T)=>{let k={kind:y,path:"",busy:!1},R=document.createElement("div");R.className="tt_sftpPane";let U=document.createElement("div");U.className="tt_sftpPaneHead";let G=document.createElement("span");G.textContent=T;let J=document.createElement("span");J.className="tt_sftpPaneMeta",U.appendChild(G),U.appendChild(J),R.appendChild(U);let X=document.createElement("div");X.className="tt_sftpBar";let W=document.createElement("input");W.type="text",W.className="tt_sftpPath",W.placeholder=S(y==="local"?"placeholder.localPath":"placeholder.remotePath"),W.spellcheck=!1,W.autocomplete="off";let L=document.createElement("button");L.type="button",L.className="tt_toolBtn",L.innerHTML=eo+"<span>"+S("btn.refresh")+"</span>";let I=document.createElement("button");I.type="button",I.className="tt_toolBtn",I.innerHTML=ac+"<span>"+S("btn.mkdir")+"</span>",X.appendChild(W),X.appendChild(L),X.appendChild(I),R.appendChild(X);let z=document.createElement("div");z.className="tt_sftpList",R.appendChild(z),k.bar=X;let $=Y=>{k.busy=Y;for(let se of[L,I])se.disabled=Y;W.disabled=Y},q=async(Y,se)=>{let be=y==="local"?"/api/dsh-tty/local-fs/":"/api/dsh-tty/sftp/",fe=y==="local"?se:{...e,...se},ge=await fetch(be+Y,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(fe)}),Le=await ge.json().catch(()=>({}));if(!ge.ok||Le.ok!==!0)throw new Error(String(Le.error||"HTTP "+ge.status));return Le},ee=(Y,se)=>{if(!(k.busy||_))return $(!0),l(Y,"busy"),Promise.resolve().then(se).catch(be=>l(String(be&&be.message?be.message:be),"error")).finally(()=>$(!1))},he=(Y,se)=>{if(Y===void 0||Y==="")throw new Error(S("error.dirNotReady"));return Y.endsWith("/")||Y.endsWith("\\")?Y+se:Y+"/"+se},de=Y=>{let se=he(k.path,Y.name),be=[];Y.isDir===!0?be.push(S("meta.dir")):be.push(tt(Number(Y.size))||"\u2014");let fe=Ic(Number(Y.mtime));fe!==""&&be.push(fe);let ge=x(Y.isDir?ci:Y.isSymlink?nc:sc,Y.name,be.join(" \xB7 "),Y.isDir===!0?"dir":Y.isSymlink===!0?"link":"file"),Le=()=>k.loadDir(k.path),Ce=y==="local"?p.remote:p.local;return Y.isDir===!0&&ge.addEventListener("click",Z=>{Z.target instanceof Element&&Z.target.closest(".tt_sftpAct")!==null||k.loadDir(se)}),b(ge,y==="local"?lc:cc,S("btn.transferTo",{target:S(y==="local"?"meta.remote":"meta.local"),path:Ce.path}),()=>{if(k.path===""||Ce.path===""){l(S("error.transferDirsNotReady"),"error");return}P.reset(),P.pulse(0),m(S("msg.transferring",{name:Y.name}),async()=>{let Z=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"start",direction:y==="local"?"up":"down",...e,localPath:y==="local"?se:he(Ce.path,Y.name),remotePath:y==="local"?he(Ce.path,Y.name):se})}),te=await Z.json().catch(()=>({}));if(!Z.ok||te.ok!==!0)throw P.fail(S("error.transferFailed")),new Error(String(te.error||"HTTP "+Z.status));let le=te.job?.id;if(typeof le!="string"||le==="")throw P.fail(S("error.transferFailed")),new Error(S("error.noTaskId"));await D(le,Y.name)==="canceled"?(P.reset(),l(S("msg.transferCanceled",{name:Y.name}))):(P.done(S("status.done")),setTimeout(()=>P.reset(),1500),l(S("msg.transferred",{name:Y.name}))),await Ce.loadDir(Ce.path)})}),y!=="local"&&Y.isDir!==!0&&b(ge,oc,S("btn.download",{name:Y.name}),()=>{O(Y,se)}),b(ge,Qn,S("btn.rename",{name:Y.name}),()=>{h.placeholder=S("placeholder.newName"),h.value=Y.name,w(y),C=async()=>{let Z=h.value.trim();Z===""||Z===Y.name||(v(),await k.runTask(S("msg.renaming",{name:Y.name}),async()=>{await q("rename",{from:se,to:he(k.path,Z)}),await Le()}))}}),E(ge,()=>k.runTask(S("msg.deleting",{name:Y.name}),async()=>{await q("remove",{path:se,recursive:Y.isDir===!0}),await Le(),l(S("msg.deleted",{name:Y.name}))}),Y),ge},re=Y=>{if(z.textContent="",k.path!==""&&k.path!=="/"&&/^[A-Za-z]:[\\/]?$/.test(k.path)===!1){let fe=x(Zn,S("list.parentDir"),"","up");fe.addEventListener("click",()=>{let ge=y==="local"?zp(k.path):Nc(k.path);ge!==null&&k.loadDir(ge)}),z.appendChild(fe)}let se=Array.isArray(Y)?Y:[];if(se.length===0){let fe=document.createElement("div");fe.className="tt_addMenuTitle",fe.textContent=S("list.emptyDir"),z.appendChild(fe);return}let be=500;for(let fe of se.slice(0,be))fe===null||typeof fe!="object"||typeof fe.name!="string"||fe.name===""||z.appendChild(de(fe));if(se.length>be){let fe=document.createElement("div");fe.className="tt_addMenuTitle",fe.textContent=S("list.truncated",{rest:se.length-be,total:se.length}),z.appendChild(fe)}};return k.loadDir=async Y=>{try{let se=await q("list",{path:Y??k.path});k.path=typeof se.path=="string"&&se.path!==""?se.path:k.path,W.value=k.path;let be=Array.isArray(se.entries)?se.entries.length:0;re(se.entries),J.textContent=S("list.itemCount",{count:be}),l(k.path)}catch(se){l(String(se&&se.message?se.message:se),"error")}},k.runTask=ee,k.setBusy=$,p[y]=k,L.addEventListener("click",()=>{k.runTask(S("list.loading"),()=>k.loadDir(k.path))}),I.addEventListener("click",()=>{k.busy||_||(h.placeholder=S("placeholder.newDirName"),h.value="",w(y),C=async()=>{let Y=h.value.trim();Y!==""&&(v(),await k.runTask(S("msg.creatingDir",{name:Y}),async()=>{await q("mkdir",{path:he(k.path,Y),parents:!0}),await k.loadDir(k.path)}))})}),W.addEventListener("keydown",Y=>{if(Y.key!=="Enter"||(Y.preventDefault(),k.busy||_))return;let se=W.value.trim();se!==""&&k.runTask(S("list.loading"),()=>k.loadDir(se))}),R},d=document.createElement("div");d.className="tt_sftpEditor",d.style.display="none";let h=document.createElement("input");h.type="text",h.className="tt_cardInput",h.spellcheck=!1,h.autocomplete="off";let f=document.createElement("button");f.type="button",f.className="tt_toolBtn",f.textContent=S("btn.ok");let g=document.createElement("button");g.type="button",g.className="tt_toolBtn",g.textContent=S("btn.cancel"),d.appendChild(h),d.appendChild(f),d.appendChild(g);let C=null,v=()=>{d.style.display="none",h.value="",C=null};f.addEventListener("click",()=>{C?.()}),g.addEventListener("click",v),h.addEventListener("keydown",y=>{y.key==="Enter"?(y.preventDefault(),C?.()):y.key==="Escape"&&(y.stopPropagation(),v())});let x=(y,T,k,R)=>{let U=document.createElement("button");U.type="button",U.className="tt_sftpRow";let G=document.createElement("span");G.className="tt_sftpIcon",G.innerHTML=y,R!==void 0&&(G.dataset.kind=R);let J=document.createElement("span");if(J.className="tt_sftpName",J.textContent=T,J.title=T,U.appendChild(G),U.appendChild(J),k!==""){let X=document.createElement("span");X.className="tt_sftpMeta",X.textContent=k,U.appendChild(X)}return U},b=(y,T,k,R)=>{let U=document.createElement("button");U.type="button",U.className="tt_sftpAct",U.innerHTML=T,U.title=k,U.addEventListener("click",G=>{G.stopPropagation(),R()}),y.appendChild(U)},E=(y,T,k)=>{let R=document.createElement("button");R.type="button",R.className="tt_sftpAct",R.innerHTML=Er,R.title=k.isDir?S("btn.deleteEntryDir",{name:k.name}):S("btn.deleteEntry",{name:k.name});let U=null;R.addEventListener("click",G=>{if(G.stopPropagation(),U!==null){clearTimeout(U),U=null,R.innerHTML=Er,delete R.dataset.danger,T();return}R.textContent=S("btn.confirm"),R.dataset.danger="",U=setTimeout(()=>{U=null,R.innerHTML=Er,delete R.dataset.danger},4e3)}),y.appendChild(R)},O=(y,T)=>p.remote.runTask(S("msg.downloading",{name:y.name}),async()=>{P.reset();let k;try{k=await Fc("/api/dsh-tty/sftp/download",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...e,path:T})},(R,U)=>{P.set(R,U)},Jt.maxDownloadMb,R=>P.setCancel(R))}catch(R){if(Vn(R)){P.reset(),l(S("msg.downloadCanceled",{name:y.name}));return}throw P.fail(S("error.downloadFailed")),R}P.done(S("status.done")),Wc(k,y.name),setTimeout(()=>P.reset(),1500),l(S("msg.downloaded",{name:y.name,size:tt(k.size)||String(k.size)+" B"}))}),B=c("local",S("meta.local")),H=c("remote",S("meta.remote"));p.local.wrap=B,p.remote.wrap=H;let M=document.createElement("div");M.className="tt_sftpDual",M.appendChild(B),M.appendChild(H),a.appendChild(M),a.appendChild(d);let K=document.createElement("div");K.className="tt_sftpFoot";let P=Hc();K.appendChild(P.el),K.appendChild(u),a.appendChild(K);let D=async(y,T)=>{let k=!1;P.setCancel(()=>{k||(k=!0,fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"cancel",job:y})}).catch(()=>{}))});try{for(;;){await new Promise(J=>setTimeout(J,400));let R=await fetch("/api/dsh-tty/local-fs/transfer",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"status",job:y})}),U=await R.json().catch(()=>({}));if(!R.ok||U.ok!==!0){if(k)return"canceled";throw new Error(String(U.error||"HTTP "+R.status))}let G=U.job;if(G===null||typeof G!="object")throw new Error(S("error.invalidTaskState"));if(G.state==="running"){let J=typeof G.current=="string"&&G.current!==""?G.current:T;l(S("msg.transferring",{name:J}),"busy"),Number.isFinite(G.total)&&G.total>0?P.set(Number(G.bytes)||0,G.total):P.pulse(Number(G.bytes)||0);continue}if(G.state==="canceled")return"canceled";if(G.state!=="done")throw new Error(String(G.error||S("error.transferFailed")));return"done"}}finally{P.setCancel(null)}},F=io(),N=F===null?420:Math.round(F.height*.56);Oc(a,S("panel.sftpDual",{label:t}),N,s),p.local.loadDir(""),p.remote.loadDir("")}var Ft=null,Tt=null;function Pc(){return Tt!==null&&Rn(Tt.ownerKey,Re)?Tt.ownerKey:yr(void 0,Re)}var Bc=(e=Pc())=>Ft!==null||Tt!==null&&Tt.ownerKey===e;function Oc(e,t,r,s){let a=yr(s,Re),i=gt!==null&>.ownerKey===a;if(ce!==null&&!qe&&ct!==null&&!i)try{let o=Sc({title:t,side:"bottom",size:r,min:200,ownerSid:a,onClose:()=>Br(a)});o.element.appendChild(e),Tt=o;return}catch(o){console.warn("[dsh-tty] SFTP \u6302\u5230\u7EC8\u7AEF\u6302\u8F7D\u4F4D\u5931\u8D25\uFF0C\u56DE\u9000\u5BF9\u8BDD\u6846\uFF1A"+(o instanceof Error?o.message:String(o)))}let n=document.createElement("div");n.className="tt_sshBackdrop",n.appendChild(e),n.addEventListener("mousedown",o=>{o.target===n&&Br()}),document.body.appendChild(n),Ft=n}var li=null;function Up(){let e=li;if(li=null,e!==null)try{e.click()}catch{}}function jp(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 Ic(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 Nc(e){let t=String(e).replace(/\/+$/,""),r=t.lastIndexOf("/");return r<=0?"/":t.slice(0,r)}function zp(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 a=r[2];if(a==="")return null;let i=Math.max(a.lastIndexOf("\\"),a.lastIndexOf("/"));return i<=0?r[1]+"\\":r[1]+a.slice(0,i)}if(t.startsWith("\\\\")||t.startsWith("//")){let a=t.slice(2);if(a.split(/[\\/]/).filter(o=>o!=="").length<=2)return null;let n=Math.max(a.lastIndexOf("\\"),a.lastIndexOf("/"));return t.slice(0,2)+a.slice(0,n)}let s=t.lastIndexOf("/");return s<=0?s===0?"/":null:t.slice(0,s)}function Zr(e,t){return e.endsWith("/")?e+t:e+"/"+t}function Hc(){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 a=document.createElement("button");a.type="button",a.className="tt_sftpCancel",a.title=S("btn.cancelTransfer"),a.textContent="\u2715",a.style.display="none";let i=null;a.addEventListener("click",p=>{p.stopPropagation();let c=i;c!==null&&(a.disabled=!0,c())}),e.appendChild(t),e.appendChild(s),e.appendChild(a);let n=p=>{s.textContent=p},o="",u=-1,l=p=>{p!==o&&(o=p,s.textContent=p)},_=p=>{let c=Math.round(p);c!==u&&(u=c,r.style.width=c+"%")},m=()=>{i=null,li===a&&(li=null),a.style.display="none",a.disabled=!1};return{el:e,reset(){delete e.dataset.active,delete e.dataset.state,o="",u=-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,li=a,a.disabled=!1,a.style.display=""},set(p,c){e.dataset.active="",delete e.dataset.state;let d=Date.now();if(this._last!==void 0&&d>this._lastAt){let h=(p-this._last)/((d-this._lastAt)/1e3);this._rate=this._rate===void 0?h:this._rate*.7+h*.3}if(this._last=p,this._lastAt=d,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?Xr(this._rate):"";l(Math.round(h)+"%"+(f!==""?" \xB7 "+f:""))}else{r.style.width="";let h=this._rate!==void 0&&this._rate>=0?Xr(this._rate):"";l(tt(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 d=this._rate!==void 0&&this._rate>=0?Xr(this._rate):"";l((Number.isFinite(p)?tt(p):"\u2026")+(d!==""?" \xB7 "+d:""))},done(p){e.dataset.active="",e.dataset.state="done",r.style.width="100%",u=100,m(),l(p!==void 0&&p!==""?p:S("status.done"))},fail(p){e.dataset.active="",e.dataset.state="error",m(),l(p!==void 0&&p!==""?p:S("status.failed"))},text(p){delete e.dataset.state,p===void 0||p===""?(e.dataset.active="",o="",s.textContent=""):(e.dataset.active="",r.style.width="",u=-1,l(p))}}}async function Fc(e,t,r,s=0,a=null){let i=s>0?s*1024*1024:0,n=typeof AbortController=="function"?new AbortController:null,o=!1;n!==null&&(t={...t,signal:n.signal},typeof a=="function"&&a(()=>{o=!0,n.abort()}));let u=await fetch(e,t);if(!u.ok){let d="HTTP "+u.status;try{let h=await u.json();h!==null&&typeof h=="object"&&typeof h.error=="string"&&(d=h.error)}catch{}throw new Error(d)}let l=Number(u.headers.get("content-length")),_=Number.isFinite(l)&&l>0;if(i>0&&_&&l>i){try{await u.body?.cancel()}catch{}throw new Error(S("error.downloadTooBig",{size:tt(i)}))}let m=u.body;if(m===null||typeof m.getReader!="function"){let d=await u.blob();if(i>0&&d.size>i)throw new Error(S("error.downloadTooBig",{size:tt(i)}));return _&&r(l,l),d}let w=m.getReader(),p=[],c=0;try{for(;;){let{done:d,value:h}=await w.read();if(d)break;if(h!==void 0&&h.byteLength>0){if(c+=h.byteLength,i>0&&c>i){try{await w.cancel()}catch{}throw new Error(S("error.downloadTooBig",{size:tt(i)}))}p.push(h),r(c,_?l:NaN)}}}catch(d){if(o||d!==null&&typeof d=="object"&&d.name==="AbortError"){try{await w.cancel()}catch{}throw new Pr}throw d}return new Blob(p,{type:"application/octet-stream"})}var Pr=class extends Error{constructor(){super(S("msg.canceled")),this.name="TransferCanceledError"}};function Vn(e){return e instanceof Pr}function Wc(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 $p(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=[],a=Jt.maxUploadFiles,i=Jt.maxUploadMb>0?Jt.maxUploadMb*1024*1024:0,n=()=>a>0&&s.length>=a,o=0,u=(l,_)=>new Promise(m=>{if(n()){m();return}if(l.isFile===!0){l.file(c=>{i>0&&o+(c.size??0)>i?s._limitExceeded=!0:(s.push({relPath:_+l.name,file:c}),o+=c.size??0),m()},()=>m());return}if(l.isDirectory!==!0){m();return}let w=l.createReader(),p=()=>{w.readEntries(async c=>{if(c.length===0){m();return}for(let d of c){if(n())break;await u(d,_+l.name+"/")}if(n()){m();return}p()},()=>m())};p()});for(let l of r)await u(l,"");return s}function ks(e,t){let r=yr(t,Re);if(Bc(r))return;let s=e!==null&&typeof e=="object"?e:{},a={};if(typeof s.name=="string"&&s.name!=="")a.name=s.name;else{for(let I of["host","username","auth","keyPath","passphrase","password"])typeof s[I]=="string"&&s[I]!==""&&(a[I]=s[I]);let L=Number(s.port);Number.isInteger(L)&&L>=1&&L<=65535&&(a.port=L),s.agentForward===!0&&(a.agentForward=!0)}let i=a.name??(a.username!==void 0?a.username+"@"+String(a.host??""):String(a.host??""));if(Ec==="dual"){Wp(a,i,r);return}let n=document.createElement("div");n.className="tt_sftpCard";let o=document.createElement("div");o.className="tt_sftpTitleRow";let u=document.createElement("div");u.className="tt_sshTitle",u.innerHTML=ci+"<span></span>",u.lastElementChild.textContent="SFTP \xB7 "+i;let l=document.createElement("button");l.type="button",l.className="tt_close",l.title=S("btn.close"),l.innerHTML=ys,l.addEventListener("click",()=>Br(r)),o.appendChild(u),o.appendChild(l),n.appendChild(o);let _=document.createElement("div");_.className="tt_sftpBar";let m=document.createElement("input");m.type="text",m.className="tt_sftpPath",m.placeholder=S("placeholder.remotePath"),m.spellcheck=!1,m.autocomplete="off";let w=document.createElement("button");w.type="button",w.className="tt_toolBtn",w.innerHTML=eo+"<span>"+S("btn.refresh")+"</span>";let p=document.createElement("button");p.type="button",p.className="tt_toolBtn",p.innerHTML=ac+"<span>"+S("btn.mkdir")+"</span>";let c=document.createElement("button");c.type="button",c.className="tt_toolBtn",c.innerHTML=Zf+"<span>"+S("btn.upload")+"</span>",c.title=S("btn.uploadTitle");let d=document.createElement("input");d.type="file",d.multiple=!0,d.style.display="none",_.appendChild(m),_.appendChild(w),_.appendChild(p),_.appendChild(c),n.appendChild(_),n.appendChild(d);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 g=document.createElement("button");g.type="button",g.className="tt_toolBtn",g.textContent=S("btn.ok");let C=document.createElement("button");C.type="button",C.className="tt_toolBtn",C.textContent=S("btn.cancel"),h.appendChild(f),h.appendChild(g),h.appendChild(C),n.appendChild(h);let v=null,x=()=>{h.style.display="none",v=null};g.addEventListener("click",()=>{v?.()}),C.addEventListener("click",x),f.addEventListener("keydown",L=>{L.key==="Enter"?(L.preventDefault(),v?.()):L.key==="Escape"&&(L.stopPropagation(),x())});let b=document.createElement("div");b.className="tt_sftpList",n.appendChild(b);let E=document.createElement("div");E.className="tt_sftpFoot";let O=document.createElement("div");O.className="tt_sftpStatus";let B=Hc();E.appendChild(B.el),E.appendChild(O),n.appendChild(E);let H={path:"",busy:!1},M=(L,I)=>{O.textContent=L,I===void 0?delete O.dataset.state:O.dataset.state=I},K=L=>{H.busy=L;for(let I of[w,p,c])I.disabled=L;m.disabled=L},P=async(L,I)=>{let z=await fetch("/api/dsh-tty/sftp/"+L,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...a,...I})}),$=await z.json().catch(()=>({}));if(!z.ok||$.ok!==!0)throw new Error(String($.error||"HTTP "+z.status));return $},D=async(L,I)=>{if(!H.busy){K(!0),M(L,"busy");try{await I()}catch(z){M(String(z&&z.message?z.message:z),"error")}finally{K(!1)}}},F=(L,I,z,$)=>{let q=document.createElement("button");q.type="button",q.className="tt_sftpRow";let ee=document.createElement("span");ee.className="tt_sftpIcon",ee.innerHTML=L,$!==void 0&&(ee.dataset.kind=$);let he=document.createElement("span");if(he.className="tt_sftpName",he.textContent=I,he.title=I,q.appendChild(ee),q.appendChild(he),z!==""){let de=document.createElement("span");de.className="tt_sftpMeta",de.textContent=z,q.appendChild(de)}return q},N=(L,I,z,$)=>{let q=document.createElement("button");q.type="button",q.className="tt_sftpAct",q.innerHTML=I,q.title=z,q.addEventListener("click",ee=>{ee.stopPropagation(),$()}),L.appendChild(q)},y=(L,I,z)=>{let $=document.createElement("button");$.type="button",$.className="tt_sftpAct",$.innerHTML=Er,$.title=I.isDir?S("btn.deleteEntryDir",{name:I.name}):S("btn.deleteEntry",{name:I.name});let q=null;$.addEventListener("click",ee=>{if(ee.stopPropagation(),!H.busy){if(q!==null){clearTimeout(q),q=null,$.innerHTML=Er,delete $.dataset.danger,D(S("msg.deleting",{name:I.name}),async()=>{await P("remove",{path:z,recursive:I.isDir===!0}),await k(H.path),M(S("msg.deleted",{name:I.name}))});return}$.textContent=S("btn.confirm"),$.dataset.danger="",q=setTimeout(()=>{q=null,$.innerHTML=Er,delete $.dataset.danger},4e3)}}),L.appendChild($)},T=L=>{if(b.textContent="",H.path!==""&&H.path!=="/"){let $=F(Zn,S("list.parentDir"),"","up");$.addEventListener("click",()=>{D(S("list.loading"),()=>k(Nc(H.path)))}),b.appendChild($)}let I=Array.isArray(L)?L:[];if(I.length===0){let $=document.createElement("div");$.className="tt_addMenuTitle",$.textContent=S("list.emptyDir"),b.appendChild($);return}let z=500;for(let $ of I.slice(0,z)){if($===null||typeof $!="object"||typeof $.name!="string"||$.name==="")continue;let q=Zr(H.path,$.name),ee=[];$.isDir===!0?ee.push(S("meta.dir")):ee.push(tt(Number($.size))||"\u2014");let he=Ic(Number($.mtime));he!==""&&ee.push(he);let de=F($.isDir?ci:$.isSymlink?nc:sc,$.name,ee.join(" \xB7 "),$.isDir===!0?"dir":$.isSymlink===!0?"link":"file");$.isDir===!0?de.addEventListener("click",re=>{re.target instanceof Element&&re.target.closest(".tt_sftpAct")!==null||D(S("list.loading"),()=>k(q))}):(de.addEventListener("click",re=>{re.target instanceof Element&&re.target.closest(".tt_sftpAct")!==null||R($,q)}),N(de,oc,S("btn.download",{name:$.name}),()=>{R($,q)})),N(de,Qn,S("btn.rename",{name:$.name}),()=>{f.placeholder=S("placeholder.newName"),f.value=$.name,h.style.display="",f.focus(),f.select(),v=async()=>{let re=f.value.trim();re===""||re===$.name||(x(),await D(S("msg.renaming",{name:$.name}),async()=>{await P("rename",{from:q,to:Zr(H.path,re)}),await k(H.path)}))}}),y(de,$,q),b.appendChild(de)}if(I.length>z){let $=document.createElement("div");$.className="tt_addMenuTitle",$.textContent=S("list.truncated",{rest:I.length-z,total:I.length}),b.appendChild($)}},k=async L=>{try{let I=await P("list",{path:L??H.path});H.path=typeof I.path=="string"&&I.path!==""?I.path:"/",m.value=H.path;let z=Array.isArray(I.entries)?I.entries.length:0;T(I.entries),M(H.path+" \u2014 "+S("list.itemCount",{count:z}))}catch(I){M(String(I&&I.message?I.message:I),"error")}},R=(L,I)=>D(S("msg.downloading",{name:L.name}),async()=>{B.reset();let z;try{z=await Fc("/api/dsh-tty/sftp/download",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...a,path:I})},($,q)=>{B.set($,q)},Jt.maxDownloadMb,$=>B.setCancel($))}catch($){if(Vn($)){B.reset(),M(S("msg.downloadCanceled",{name:L.name}));return}throw B.fail(S("error.downloadFailed")),$}B.done(S("status.done")),Wc(z,L.name),setTimeout(()=>B.reset(),1500),M(S("msg.downloaded",{name:L.name,size:tt(z.size)||String(z.size)+" B"}))}),U=(L,I,z,$,q)=>new Promise((ee,he)=>{let de=jp(JSON.stringify({...a,path:Zr(H.path,I)})),re=new XMLHttpRequest;q.abort=()=>{q.stopped=!0,re.abort()},re.open("POST","/api/dsh-tty/sftp/upload"),re.setRequestHeader("x-dsh-sftp-meta",de);let Y=$>1?String(z)+"/"+String($)+" ":"";M(S("msg.uploadingName",{name:Y+I}),"busy"),re.upload.addEventListener("progress",fe=>{fe.lengthComputable?B.set(fe.loaded,fe.total):B.pulse(0)});let se=!1,be=fe=>{se||(se=!0,fe===null?ee():he(fe))};re.addEventListener("load",()=>{if(re.status===200){$===1&&B.done(S("msg.uploadDone")),be(null);return}if(q.stopped)return;B.fail(S("error.uploadFailed"));let fe="HTTP "+re.status;try{let ge=JSON.parse(re.responseText);ge!==null&&typeof ge=="object"&&typeof ge.error=="string"&&(fe=ge.error)}catch{}be(new Error(fe))}),re.addEventListener("error",()=>{if(q.stopped){be(new Pr);return}B.fail(S("error.uploadFailed")),be(new Error(S("error.networkError")))}),re.addEventListener("abort",()=>{be(new Pr)}),re.send(L)}),G=async L=>D(S("msg.uploading"),async()=>{let I=Jt;if(I.maxUploadFiles>0&&L.length>I.maxUploadFiles){M(S("error.uploadCountExceeded",{max:I.maxUploadFiles,count:L.length}),"error"),B.fail(S("status.overLimit"));return}let z=I.maxUploadMb>0?I.maxUploadMb*1024*1024:0,$=L.find(re=>z>0&&(re.file?.size??0)>z);if($!==void 0){M(S("error.uploadTooBig",{size:tt(z),name:String($.relPath??"")}),"error"),B.fail(S("status.overLimit"));return}if(L._limitExceeded===!0){M(S("error.uploadTotalTooBig"),"error"),B.fail(S("status.overLimit"));return}let q=new Set;for(let re of L){let Y=re.relPath.lastIndexOf("/");if(Y<=0)continue;let se=re.relPath.slice(0,Y);q.has(se)||(q.add(se),await P("mkdir",{path:Zr(H.path,se),parents:!0}).catch(()=>{}))}B.reset();let ee={stopped:!1,abort:null};B.setCancel(()=>ee.abort?.());let he=0,de=0;try{for(let re of L){if(ee.stopped)break;he+=1,ee.abort=null;try{await U(re.file,re.relPath,he,L.length,ee),de+=1}catch(Y){if(Vn(Y)||ee.stopped)break;throw Y}}}finally{B.setCancel(null)}if(ee.stopped){B.reset(),M(S("msg.uploadCanceled",{done:de,total:L.length})),await k(H.path);return}B.done(S("status.allDone")),setTimeout(()=>B.reset(),1500),M(S("msg.uploadDoneCount",{count:L.length})),await k(H.path)});w.addEventListener("click",()=>{D(S("list.loading"),()=>k(H.path))}),p.addEventListener("click",()=>{H.busy||(f.placeholder=S("placeholder.newDirName"),f.value="",h.style.display="",f.focus(),v=async()=>{let L=f.value.trim();L!==""&&(x(),await D(S("msg.creatingDir",{name:L}),async()=>{await P("mkdir",{path:Zr(H.path,L)}),await k(H.path)}))})}),c.addEventListener("click",()=>{H.busy===!1&&d.click()}),d.addEventListener("change",()=>{let L=[...d.files??[]].map(I=>({relPath:I.name,file:I}));d.value="",L.length>0&&G(L)});let J=0,X=L=>{L?b.dataset.drag="":delete b.dataset.drag};n.addEventListener("dragenter",L=>{L.preventDefault(),J+=1,X(!0)}),n.addEventListener("dragover",L=>{L.preventDefault()}),n.addEventListener("dragleave",()=>{J=Math.max(0,J-1),J===0&&X(!1)}),n.addEventListener("drop",L=>{L.preventDefault(),J=0,X(!1),!H.busy&&$p(L.dataTransfer).then(I=>{(I.length>0||I._limitExceeded===!0)&&G(I)})}),m.addEventListener("keydown",L=>{if(L.key!=="Enter"||(L.preventDefault(),H.busy))return;let I=m.value.trim();I!==""&&D(S("list.loading"),()=>k(I))});let W=io();Oc(n,"SFTP \xB7 "+i,W===null?340:Math.round(W.height*.46),r),D(S("status.connectingEllipsis"),()=>k(""))}function Br(e){let t=e===void 0?Pc():e,r=Ft,s=Tt!==null&&Tt.ownerKey===t?Tt:null;r===null&&s===null||(Up(),Ft=null,s!==null&&(Tt=null),r!==null&&r.remove(),s!==null&&s.dispose())}function Uc(){if(Je===null)return;let e=Je.style.display==="none"||Je.style.display==="";Je.style.display=e?"":"none";let t=ce!==null?ce.querySelector("[data-act=search]"):null;t!==null&&(e?t.dataset.on="":delete t.dataset.on),e&&Je.focus()}var qp={matchBackground:"#3d2b00",matchBorder:"#8a5a00",activeMatchBackground:"#b06a00",activeMatchBorder:"#ffb84d",matchOverviewRuler:"#8a5a00",activeMatchColorOverviewRuler:"#ffb84d"};function Kp(e){let t=dt();if(t===void 0||t.search===void 0)return;let r=Je.value;if(r==="")return;let s={decorations:qp};e?t.search.findPrevious(r,s):t.search.findNext(r,s)}function Vl(){di||ce===null&&!to()||ir!==null||(ir=setTimeout(()=>{ir=null,gs()},si),si=Math.min(si*2,5e3))}function yi(e){return e!==null&&typeof e=="object"&&e.persist===!0&&typeof e.persistName=="string"&&e.persistName!==""}function Yn(e){return yi(e)||e!==null&&typeof e=="object"&&typeof e.command=="string"&&e.command!==""}function Gp(){return Yt==="tmux"?{t:"spawn",cwd:Un(),persist:!0,persistName:oo()}:{t:"spawn",cwd:Un()}}async function jc(){if(!In){In=!0;try{await Vp()}finally{In=!1}}}var In=!1;async function Vp(){if(await ao(),ce===null){await Jp();return}let e=fp(),t=up();if(![...ue.values()].some(n=>n.embedded!==!0)){if(e.length>0||t.length>0){Me({t:"sessions"});let n=await us("sessions",4e3),o=new Map;if(n!==null&&Array.isArray(n.list))for(let l of n.list)l!==null&&typeof l=="object"&&l.attachable===!0&&o.set(l.sid,l);let u=new Set;for(let l of e){if(o.has(l.sid))yp(l);else if(Yn(l.spawnSpec))ql(l);else continue;yi(l.spawnSpec)&&u.add(l.spawnSpec.persistName)}for(let l of t){let _=l.spawnSpec.persistName;u.has(_)||(ql(l),u.add(_))}Xt()}if(![...ue.values()].some(n=>n.embedded!==!0)){if(await ms())return;ui()}return}let r=[...ue.values()].filter(n=>!n.exited&&(n.embedded!==!0||n.spawned===!0)),s=r.filter(n=>Yn(n.spawnSpec)),a=null;if(s.length>0){Me({t:"sessions"});let n=await us("sessions",4e3),o=new Set((n!==null&&Array.isArray(n.list)?n.list:[]).map(u=>u?.sid).filter(u=>typeof u=="string"));a=s.filter(u=>!o.has(u.sid));for(let u of a)fs(u.sid)}let i=a!==null?new Set(a.map(n=>n.sid)):new Set;for(let n of r)i.has(n.sid)||Me({t:"attach",sid:n.sid})}function Yp(){Ee!==null&&(Ee.readyState===WebSocket.OPEN||Ee.readyState===WebSocket.CONNECTING)||gs()}async function Jp(){let e=[...ue.values()].filter(s=>s.embedded===!0&&!s.exited);if(e.length===0)return;Me({t:"sessions"});let t=await us("sessions",4e3),r=new Set((t!==null&&Array.isArray(t.list)?t.list:[]).map(s=>s?.sid).filter(s=>typeof s=="string"));for(let s of e)s.spawned===!0&&(r.has(s.sid)?Me({t:"attach",sid:s.sid}):Yn(s.spawnSpec)?yc(s):(s.exited=!0,s.live=!1,Sr(s,S("status.ended"),S("btn.clickRerun"),"exited")))}function gs(){if(Ee!==null){try{Ee.close()}catch{}Ee=null}di=!1,clearTimeout(ir),ir=null,Zi=!0,Qi(S("status.connectingEllipsis"),"");try{Ee=new WebSocket(Ff())}catch(e){Zi=!1,Qi(S("error.connectFailed",{error:e.message}),"error"),Vl();return}Ee.onopen=()=>{Zi=!1,si=1e3,mt=null,Qi(S("status.connected"),"connected");for(let e of[...Hn])Hn.delete(e),ue.has(e.tab.sid)&&Me(e.frame);jc()},Ee.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:"";Pn(r,t.kind==="ssh"?S("status.connectedSsh",{target:s!==""?s+" ":""}):S("status.connectedPid",{pid:t.pid}),"connected");let a=ue.get(r);if(a!==void 0){if(a.exited=!1,a.spawned=!0,a.live=!0,a.errored=!1,a.target=s,a.persistTmux=t.persist===!0,t.kind==="ssh"&&s!==""&&!a.label&&(a.label=s,it()),sr(),Bn(r),Sr(a,""),Or(a),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(()=>mc(150))}pi(),lp(r),Xt()}}else if(t.t==="sessions")wp(t.list);else if(t.t==="data"){let s=ue.get(r);s!==void 0&&s.term!==null&&(s.term.write(String(t.d??"")),r_())}else if(t.t==="exit"){let s=ue.get(r);if(s!==void 0){s.exited=!0,s.live=!1,s.stats=null,r===Re&&lr();let a=t.code!==null&&t.code!==void 0?"code="+t.code:"",i=t.signal!==null&&t.signal!==void 0?"signal="+t.signal:"";Pn(r,S("status.exitedWith",{detail:[a,i].filter(Boolean).join(" ")}),""),sr(),Bn(r),Sr(s,S("status.exited"),S("btn.clickReopen"),"exited"),pi(),Xt()}}else if(t.t==="stats")try{let s=ue.get(r);if(s!==void 0){let a=t.stats;s.stats=Hl(a)?a:null,s.statsAt=Date.now(),r===Re&&lr()}}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==="error")if(Pn(r,S("status.error",{message:String(t.m??"")}),"error"),typeof r=="string"){let s=ue.get(r);s!==void 0&&(s.live||(s.errored=!0),sr(),Bn(r),Sr(s,S("status.errored"),S("status.retryHint",{message:String(t.m??"")}),"error"))}else Xp(S("btn.clickRetry"))},Ee.onclose=()=>{if(Zi=!1,!di){Qi(S("status.disconnectedReconnecting"),"error");for(let e of ue.values())e.exited||Sr(e,S("status.disconnected"),S("status.reconnecting"),"info");Vl()}},Ee.onerror=()=>{}}function Xp(e){Lr!==null&&(Lr.textContent=e)}function Jn(){(ce===null||qe)&&Xn()}var ts="DSH_TTY_ALLOW_PROXY_COMMAND";function Zp(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 lo(){return typeof navigator<"u"&&navigator.clipboard!==void 0&&typeof navigator.clipboard.writeText=="function"}async function Qp(e){if(lo())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||bi(S("error.copyFailed"),"error"),r}async function e_(e){if(lo()&&typeof navigator.clipboard.readText=="function")try{let s=await navigator.clipboard.readText();return s!==""&&Me({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!==""&&Me({t:"input",sid:e.sid,d:s})}catch{r=!1}return t.remove(),r||bi(S("error.pasteFailed"),"error"),r}function Xn(){if(ce!==null){qe&&zc();return}mi(),ce=document.createElement("div"),ce.className="tt_modalBackdrop",ce.innerHTML='<div class="tt_modal"><div class="tt_header"><span class="tt_titleIcon">'+ws+'</span><div class="tt_tabs"></div><div class="tt_status"><span class="tt_statusDot"></span><span class="tt_statusText">'+S("status.initializing")+'</span></div><input class="tt_searchInput" style="display:none" placeholder="'+S("placeholder.search")+'" /><span class="tt_toolGroup"><button class="tt_toolBtn tt_iconBtn" data-act="search" title="'+S("btn.searchTitle")+'">'+zf+'</button><button class="tt_toolBtn tt_iconBtn" data-act="clear" title="'+S("btn.clearTitle")+'">'+$f+'</button><button class="tt_toolBtn tt_iconBtn" data-act="copy" title="'+S("btn.copyTitle")+'">'+qf+'</button><button class="tt_toolBtn tt_iconBtn" data-act="paste" title="'+S("btn.pasteTitle")+'">'+Kf+'</button></span><span class="tt_winGroup"><button class="tt_min" title="'+S("btn.minimizeTitle")+'">'+Jf+'</button><button class="tt_close" title="'+S("btn.closePanelTitle")+'">'+ys+'</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><div class="tt_overlay"></div></div></div></div>',document.body.appendChild(ce),os=ce.querySelector(".tt_status"),rr=ce.querySelector(".tt_statusText"),or=ce.querySelector(".tt_statusDot"),kt=ce.querySelector(".tt_tabs"),ei=ce.querySelector(".tt_connbar"),ti=ce.querySelector(".tt_connDot"),as=ce.querySelector(".tt_connTarget"),lt=ce.querySelector(".tt_connBadge"),ri=ce.querySelector(".tt_connActions"),ct=ce.querySelector(".tt_work"),rt=ce.querySelector(".tt_body"),_t=ce.querySelector(".tt_statsBar"),Cs(),mt=null,fc(),Lr=ce.querySelector(".tt_body > .tt_overlay"),Je=ce.querySelector(".tt_searchInput"),Lr.addEventListener("click",()=>{Lr.textContent="",gs()});let e=ce.querySelector("[data-act=search]");e.addEventListener("click",()=>{Uc(),Je.style.display!=="none"&&Je.focus()}),e.dataset.on="",Je.addEventListener("keydown",t=>{t.key==="Enter"?(t.preventDefault(),Kp(t.shiftKey)):t.key==="Escape"&&(t.stopPropagation(),Je.style.display="none")}),ce.querySelector("[data-act=clear]").addEventListener("click",()=>{let t=dt();t!==void 0&&t.term!==null&&t.term.clear()}),ce.querySelector("[data-act=copy]").addEventListener("click",()=>{let t=dt();if(t===void 0||t.term===null)return;let r=t.term.getSelection();r!==""&&Qp(r)}),ce.querySelector("[data-act=paste]").addEventListener("click",()=>{let t=dt();t!==void 0&&e_(t)}),ce.querySelector(".tt_min").addEventListener("click",()=>{vs()}),ce.querySelector(".tt_close").addEventListener("click",()=>{_i()}),ce.addEventListener("mousedown",t=>{t.target===ce&&vs()}),document.addEventListener("keydown",$c),ii=new ResizeObserver(()=>{qe||(rs(),pp(dt()))}),ii.observe(rt),it(),sr(),Ee!==null&&Ee.readyState===WebSocket.OPEN?jc():gs()}function t_(){Ve=document.createElement("div"),Ve.className="tt_dock",Ve.title=S("btn.restoreDock"),Ve.innerHTML='<span class="tt_dockTitle">'+ws+"<span>"+S("panel.title")+'</span><span class="tt_dockCount"></span></span><span class="tt_dockStatus"></span><span class="tt_dockDot"></span><button class="tt_dockClose" title="'+S("btn.closePanelTitle")+'">\u2715</button>',ls=Ve.querySelector(".tt_dockCount"),Dr=Ve.querySelector(".tt_dockStatus"),ar=Ve.querySelector(".tt_dockDot");let e=[...ue.values()].filter(t=>!t.exited).length;ls.textContent=ue.size>0?"\xB7 "+e+"/"+ue.size:"",rr!==null&&(Dr.textContent=rr.textContent),or!==null&&(ar.dataset.state=or.dataset.state??""),Ve.addEventListener("click",t=>{if(t.target.closest(".tt_dockClose")!==null){t.stopPropagation(),_i();return}zc()}),document.body.appendChild(Ve)}function vs(){ce===null||qe||(Et(),Gt(),qe=!0,Ft!==null&&(Ft.style.display="none"),Je!==null&&(Je.style.display="none"),ce.dataset.minimized="",pc(),wi(),lr(),document.querySelector("[data-dsh-tty-entry]")!==null?pi():(t_(),Ve.classList.add("tt_dockCompact")))}function pi(){let e=document.querySelector("[data-dsh-tty-entry]");if(e===null)return;let t=e.querySelector(".tt_sidebarEntryBadge");if(!qe){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=S("status.minimized");let r=[...ue.values()].filter(a=>!a.exited).length;t.querySelector(".tt_sidebarBadgeCount").textContent=r+"/"+ue.size;let s=t.querySelector(".tt_sidebarBadgeDot");s!==null&&or!==null&&(s.dataset.state=or.dataset.state??"")}function r_(){if(!qe)return;let e=document.querySelector("[data-dsh-tty-entry] .tt_sidebarBadgeDot")??ar;e!==null&&(e.dataset.active="",clearTimeout(cs),cs=setTimeout(()=>{delete e.dataset.active},900))}function zc(){if(ce===null||!qe)return;qe=!1,delete ce.dataset.minimized,Ft!==null&&(Ft.style.display=""),clearTimeout(cs),Ve!==null&&(Ve.remove(),Ve=null),ls=null,Dr=null,ar=null,pi(),fc(),wi(),lr();let e=dt();if(e!==void 0&&e.fit!==void 0){try{e.fit.fit()}catch{}e.spawned&&!e.exited&&Or(e)}e!==void 0&&e.term!==null&&e.term.focus()}function _i(){if(ce===null)return;ai(!0);let e=to();if(di=!e,qe=!1,Et(),is(),ps(),Gt(),Br(),clearTimeout(cs),clearTimeout(ir),ir=null,si=1e3,Ve!==null&&(Ve.remove(),Ve=null),ls=null,Dr=null,ar=null,pi(),Ee!==null){for(let t of ue.values())!t.exited&&t.embedded!==!0&&Me({t:"kill",sid:t.sid});if(!e){try{Ee.close()}catch{}Ee=null}}ii!==null&&(ii.disconnect(),ii=null);for(let[t,r]of[...ue])if(r.embedded!==!0){if(r.term!==null)try{r.term.dispose()}catch{}ue.delete(t)}Re=null,hi=null,document.removeEventListener("keydown",$c),ce.remove(),ce=null,ct=null,os=null,rr=null,or=null,kt=null,ei=null,ti=null,as=null,lt=null,ri=null,ps(),pc(),_t=null,Cs(),mt=null,rt=null,Lr=null,Je=null,vi=0;try{sessionStorage.removeItem(hs)}catch{}}function $c(e){if(e.key==="Escape"&&ce!==null){if(e.preventDefault(),Ft!==null){Br();return}if(Tr!==null){Gt();return}if(ht!==null){Et();return}vs()}}function i_(){let e=document.querySelector('[data-pane="sidebar"], [class*="sidebarCol"]');if(e!==null)return e.querySelector('[class*="logoRow"]')?.parentElement??e.firstElementChild}function s_(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 n_(){let e=document.createElement("div");return e.dataset.dshTtyEntry="",e.className="tt_sidebarEntry",e.setAttribute("role","button"),e.setAttribute("aria-label",S("panel.title")),e.tabIndex=0,e.innerHTML='<span class="tt_sidebarEntryIcon">'+ws+'</span><span class="tt_sidebarEntryLabel">'+S("panel.title")+"</span>",e.addEventListener("click",t=>{t.preventDefault(),Xn()}),e.addEventListener("keydown",t=>{(t.key==="Enter"||t.key===" "||t.key==="Spacebar")&&(t.preventDefault(),Xn())}),e}function Yl(e,t){let r=s_(e);if(r===void 0)return!1;if(t.parentElement!==e){let s=r.closest('[class*="logoRow"]'),a=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,a.nextElementSibling)}return!0}function o_(){if(mi(),typeof document<"u"&&document.querySelector("[data-dsh-tty-entry]")!==null)return()=>{};let e=n_(),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=i_()),t!==void 0&&(r=Yl(t,e),r&&i.observe(t,{childList:!0,subtree:!0}))},a=new MutationObserver(()=>{s()});a.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=Yl(t,e))});return s(),()=>{a.disconnect(),i.disconnect(),e.remove()}}window.__ModuleLoader__.load({id:"@hyzyn/dsh-tty",factory:e=>{let t={},r=e("react"),{jsx:s,jsxs:a}=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(u){let l=u&&u.view,_=l==="page",[m,w]=r.useState(_),[p,c]=r.useState(null),[d,h]=r.useState(!1),[f,g]=r.useState(!1),[C,v]=r.useState({kind:"",text:""}),[x,b]=r.useState(null),[E,O]=r.useState(""),[B,H]=r.useState(!1),[M,K]=r.useState(Date.now()),P=r.useRef(null),D=r.useRef(null),[F,N]=r.useState([]),[y,T]=r.useState(!1),k=A=>s("div",{className:"tt_cardSection",children:A}),R=async()=>{try{let j=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json();j.ok&&typeof j.config=="object"&&j.config!==null?(P.current=j.config,D.current=JSON.stringify(J(j.config)),c(j.config),fi(j.config)):v({kind:"error",text:String(j.error||S("error.configLoadFailed"))})}catch(A){v({kind:"error",text:String(A&&A.message?A.message:A)})}},U=async()=>{try{let j=await(await fetch("/api/dsh-tty/shells",{cache:"no-store"})).json();j.ok&&Array.isArray(j.shells)&&N(j.shells)}catch{}};r.useEffect(()=>{m&&!d&&(h(!0),R(),U())},[m]);let G=(A,j)=>c(V=>{let Q={...V||{},[A]:j};return P.current=Q,Q}),J=A=>{let j={};for(let V of["enabled","announceToAgent","maxSessions","shell","term","colorTerm","cwd","reconnectGraceSec","shellIntegration","sftpStyle","persistence","endOnPageClose","statsEnabled","allowProxyCommand"]){let Q=(A||{})[V];Q!==void 0&&Q!==""&&(j[V]=Q)}return j.sshHosts=Array.isArray(A?.sshHosts)?A.sshHosts:[],j.tunnels=Array.isArray(A?.tunnels)?A.tunnels:[],A?.sftpLimits&&typeof A.sftpLimits=="object"&&(j.sftpLimits={maxDownloadMb:Number(A.sftpLimits.maxDownloadMb)||0,maxUploadMb:Number(A.sftpLimits.maxUploadMb)||0,maxUploadFiles:Number(A.sftpLimits.maxUploadFiles)||0}),j};P.current=p;let X=(A,j)=>c(V=>({...V||{},sftpLimits:{...V?.sftpLimits??{},[A]:j}})),[W,L]=r.useState(null),[I,z]=r.useState(null),[$,q]=r.useState(""),[ee,he]=r.useState(null),[de,re]=r.useState(""),[Y,se]=r.useState(""),[be,fe]=r.useState(""),ge=r.useRef(null),[Le,Ce]=r.useState(!1),[Z,te]=r.useState({text:"",kind:""}),[le,ie]=r.useState(!1),[ne,oe]=r.useState({running:!1,ok:!1,text:""}),[pe,we]=r.useState({}),[_e,Ie]=r.useState([]),[ye,ve]=r.useState({direction:"local",localPort:"",remoteHost:"",remotePort:"",localTargetPort:"",bookName:""}),[xe,Ne]=r.useState(null);r.useEffect(()=>{if(!m)return;let A=!0,j=async()=>{try{let ae=await(await fetch("/api/dsh-tty/tunnels",{cache:"no-store"})).json();A&&ae.ok&&Array.isArray(ae.tunnels)&&Ie(ae.tunnels)}catch{}};j();let V=setInterval(j,2e3);return()=>{A=!1,clearInterval(V)}},[m]);let je=A=>j=>ve(V=>({...V||{},[A]:j.target.value})),Qt=(A,j)=>ve(V=>({...V||{},[A]:j})),qc=A=>A?.direction==="remote"?S("meta.tunnelRemote",{host:A.remoteHost||"127.0.0.1",port:String(A.remotePort??0),local:String(A.localTargetPort??0)}):S("meta.tunnelLocal",{local:String(A?.localPort??0),host:A?.remoteHost??"?",port:String(A?.remotePort??0)}),co=(p?.sshHosts??[]).find(A=>A?.name===ye?.bookName),Es=async A=>{try{let j=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({tunnels:A})}),V=await j.json().catch(()=>({}));return!j.ok||!V.ok?(v({kind:"error",text:String(V.error||S("error.saveTunnelFailed"))}),!1):!0}catch(j){return v({kind:"error",text:String(j&&j.message?j.message:j)}),!1}},ho=()=>Tl(ye,(Array.isArray(p?.sshHosts)?p.sshHosts:[]).map(A=>A?.name),S),Kc=A=>{v({kind:"",text:""}),Ne(String(A?.name??"")),ve({direction:A?.direction==="remote"?"remote":"local",bookName:String(A?.bookName??""),localPort:A?.localPort?String(A.localPort):"",remoteHost:String(A?.remoteHost??""),remotePort:A?.remotePort?String(A.remotePort):"",localTargetPort:A?.localTargetPort?String(A.localTargetPort):""})},Gc=()=>{Ne(null),v({kind:"",text:""}),ve(A=>({...A||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))},Vc=()=>{v({kind:"",text:""});let A=ho();if(!A.ok){v({kind:"error",text:A.error});return}let j=A.tunnel,V=Array.isArray(p?.tunnels)?p.tunnels:[];if(Rl(V,j.name)!==void 0){v({kind:"error",text:S("error.tunnelNameTaken",{name:j.name})});return}let Q=[...V,j];c(ae=>({...ae||{},tunnels:Q})),ve(ae=>({...ae||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),Es(Q).then(ae=>{ae&&v({kind:"ok",text:S("msg.tunnelApplied",{name:j.name})})})},Yc=()=>{if(xe===null)return;v({kind:"",text:""});let A=ho();if(!A.ok){v({kind:"error",text:A.error});return}let j=Array.isArray(p?.tunnels)?p.tunnels:[],V=Ml(j,xe,A.tunnel,S);if(!V.ok){V.reason==="missing"&&Ne(null),v({kind:"error",text:V.error});return}let Q=V.tunnels;c(ae=>({...ae||{},tunnels:Q})),Es(Q).then(ae=>{if(ae!==!0){c(me=>({...me||{},tunnels:j}));return}Ne(null),ve(me=>({...me||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""})),v({kind:"ok",text:S("msg.tunnelUpdated",{name:A.tunnel.name})})})},uo=(A,j)=>{c(V=>({...V||{},tunnels:A})),Es(A).then(V=>{V!==!0&&c(Q=>({...Q||{},tunnels:j}))})},Jc=A=>{let j=Array.isArray(p?.tunnels)?p.tunnels:[];xe!==null&&String(A??"")===xe&&(Ne(null),ve(V=>({...V||{},localPort:"",remoteHost:"",remotePort:"",localTargetPort:""}))),uo(j.filter(V=>V?.name!==A),j)},Xc=(A,j)=>{let V=Array.isArray(p?.tunnels)?p.tunnels:[];uo(V.map(Q=>Q?.name===A?{...Q,enabled:j}:Q),V)},Zc=A=>{L(A?.name??null),q(""),oe({running:!1,ok:!1,text:""}),re(""),se(""),Ts(),Ce(Lt!==null),z({name:A?.name??"",host:A?.host??"",port:String(A?.port??22),username:A?.username??"",auth:A?.auth==="key"||A?.auth==="password"?A.auth:"agent",keyPath:A?.keyPath??"",passphrase:A?.passphrase??"",password:A?.password??"",agentForward:A?.agentForward===!0,persist:A?.persist!==!1}),Ql().then(j=>he(j)),Rs(A?.password??"")},fo=()=>{L(null),z(null),q(""),oe({running:!1,ok:!1,text:""}),re(""),se(""),Ts()},Qc=async()=>{if(I===null)return;let A=I.name.trim(),j=I.host.trim(),V=I.username.trim();if(A===""||j===""||V===""){q(S("error.nameHostUserRequired"));return}let Q=Number(I.port);if((!Number.isInteger(Q)||Q<1||Q>65535)&&(Q=22),(p?.sshHosts??[]).some(me=>me?.name===A&&A!==W)){q(S("error.bookNameTaken",{name:A}));return}if(I.auth==="key"&&I.keyPath.trim()===""){q(S("error.keyPathRequired"));return}q("");let ae=I.password;if(I.auth==="password"){let me=await rc(Le,I.password,j,Q,V,"PASSWORD");if(me.error!==void 0){q(me.error);return}me.value!==void 0&&(ae=me.value)}c(me=>({...me||{},sshHosts:(Array.isArray(me?.sshHosts)?me.sshHosts:[]).map(Ae=>Ae?.name===W?{name:A,host:j,port:Q,username:V,auth:I.auth,keyPath:I.keyPath.trim(),passphrase:I.passphrase,password:ae,agentForward:I.agentForward,persist:I.persist===!0}:Ae)})),we(me=>{let Ae={...me};return delete Ae[A],W!==A&&delete Ae[W],Ae}),L(null),z(null),oe({running:!1,ok:!1,text:""}),v({kind:"ok",text:S("msg.hostEdited",{name:A})})},eh=A=>{W===A&&fo(),we(j=>{let V={...j};return delete V[A],V}),c(j=>({...j||{},sshHosts:(Array.isArray(j?.sshHosts)?j.sshHosts:[]).filter(V=>V?.name!==A)}))},th=async A=>{let j=A?.name??"";if(j==="")return;let V={host:A?.host??"",port:Number(A?.port)||22,username:A?.username??"",auth:A?.auth==="key"||A?.auth==="password"?A.auth:"agent",keyPath:A?.keyPath??"",passphrase:A?.passphrase??"",password:A?.password??"",agentForward:A?.agentForward===!0};we(ae=>({...ae,[j]:{running:!0,text:S("msg.probing")}}));let Q=await $n(V,!0);we(ae=>{let me=ae[j]||{};if(Q.result){let Ae=Q.result.auth?.ok===!0;return{...ae,[j]:{running:!1,ok:Ae,text:qn(Q.result)}}}return{...ae,[j]:{running:!1,ok:!1,text:S("error.probeFailed",{detail:String(Q.error||S("error.unknown"))})}}})},rh=async A=>{let j=(Array.isArray(p?.hostKeys)?p.hostKeys:[]).filter(V=>!(V?.host===A?.host&&Number(V?.port)===Number(A?.port)));c(V=>({...V||{},hostKeys:j}));try{let V=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:j})}),Q=await V.json().catch(()=>({}));!V.ok||!Q.ok?v({kind:"error",text:String(Q.error||S("error.hostKeyDeleteFailed"))}):v({kind:"ok",text:S("msg.hostKeyDeleted")})}catch(V){v({kind:"error",text:String(V&&V.message?V.message:V)})}},ih=async()=>{v({kind:"",text:""});try{let j=await(await fetch("/api/dsh-tty/ssh-config",{cache:"no-store"})).json();if(!j.ok){v({kind:"error",text:String(j.error||S("error.sshConfigReadFailed"))});return}let V=Array.isArray(j.entries)?j.entries:[],Q=[...Array.isArray(p?.sshHosts)?p.sshHosts:[]],ae=new Set(Q.map(De=>De?.name)),me=0,Ae=0;for(let De of V)if(!(De===null||typeof De!="object"||typeof De.name!="string")){if(ae.has(De.name)){Ae+=1;continue}ae.add(De.name),Q.push({name:De.name,host:String(De.host??De.name),port:Number(De.port)||22,username:String(De.username??""),auth:De.auth==="key"?"key":"agent",keyPath:String(De.keyPath??""),passphrase:"",password:"",agentForward:!1}),me+=1}c(De=>({...De||{},sshHosts:Q}));let Se=Array.isArray(j.proxy)?j.proxy.filter(De=>typeof De=="string"):[],Xe=Number.isInteger(j.proxyCount)?j.proxyCount:Se.length,Wr=Array.isArray(j.proxyCommand)?j.proxyCommand.filter(De=>typeof De=="string"):[],ut=Number.isInteger(j.proxyCommandCount)?j.proxyCommandCount:Wr.length,cr=Number.isInteger(j.skippedOther)?j.skippedOther:0,Wt=Number.isInteger(j.droppedOverflow)?j.droppedOverflow:0,ft=[];Xe>0&&ft.push(S("msg.proxySkipped",{count:Xe,names:Se.slice(0,5).join(S("list.separator"))+(Xe>5?S("meta.etc"):"")})),ut>0&&ft.push(S("msg.proxyCommandSkipped",{count:ut,names:Wr.slice(0,5).join(S("list.separator"))+(ut>5?S("meta.etc"):"")})),cr>0&&ft.push(S("msg.skippedNotConcrete",{count:cr})),Wt>0&&ft.push(S("msg.importOverflow",{count:Wt}));let yo=ft.length>0?S("list.separatorFull")+ft.join(S("list.separatorFull")):"";if(me===0){let De=Ae>0?S("msg.noNewEntries",{count:Ae}):S("msg.noImportableHosts");v({kind:ft.length>0?"error":"ok",text:De+yo})}else v({kind:ft.length>0?"error":"ok",text:S("msg.importedHosts",{added:me,skipped:Ae})+yo})}catch(A){v({kind:"error",text:String(A&&A.message?A.message:A)})}},po=A=>A===null||typeof A!="object"?[]:Array.isArray(A.fingerprints)?A.fingerprints.filter(j=>typeof j=="string"&&j!==""):typeof A.fingerprint=="string"&&A.fingerprint!==""?[A.fingerprint]:[],sh=async()=>{v({kind:"",text:""});try{let j=await(await fetch("/api/dsh-tty/known-hosts",{cache:"no-store"})).json();if(!j.ok){v({kind:"error",text:String(j.error||S("error.knownHostsReadFailed"))});return}let V=Array.isArray(j.entries)?j.entries:[],Q=[...Array.isArray(p?.hostKeys)?p.hostKeys:[]],ae=new Map;for(let Se of Q)Se===null||typeof Se!="object"||ae.set(String(Se.host??"")+":"+String(Se.port??22),{record:Se,fps:new Set(po(Se))});let me=0,Ae=0;for(let Se of V){if(Se===null||typeof Se!="object"||typeof Se.host!="string")continue;let Xe=Array.isArray(Se.fingerprints)?Se.fingerprints.filter(Wt=>typeof Wt=="string"&&Wt!==""):[];if(typeof Se.fingerprint=="string"&&Se.fingerprint!==""&&Xe.push(Se.fingerprint),Xe.length===0)continue;let Wr=Se.host+":"+String(Se.port??22),ut=ae.get(Wr);if(ut!==void 0){let Wt=!1;for(let ft of Xe)ut.fps.has(ft)||ut.fps.size>=8||(ut.fps.add(ft),Wt=!0);if(!Wt){Ae+=1;continue}delete ut.record.fingerprint,ut.record.fingerprints=[...ut.fps],me+=1;continue}let cr={host:Se.host,port:Number(Se.port)||22,fingerprints:[...new Set(Xe)].slice(0,8)};ae.set(Wr,{record:cr,fps:new Set(cr.fingerprints)}),Q.push(cr),me+=1}if(me===0){v({kind:"ok",text:Ae>0?S("msg.noNewFingerprints",{count:Ae}):S("msg.noImportableKnownHosts")});return}c(Se=>({...Se||{},hostKeys:Q}));try{let Se=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hostKeys:Q})}),Xe=await Se.json().catch(()=>({}));if(!Se.ok||!Xe.ok){v({kind:"error",text:String(Xe.error||S("error.saveHostKeysFailed"))});return}v({kind:"ok",text:S("msg.importedFingerprints",{added:me,skipped:Ae})+(j.truncated===!0?S("hint.knownHostsTruncated"):"")})}catch(Se){v({kind:"error",text:String(Se&&Se.message?Se.message:Se)})}}catch(A){v({kind:"error",text:String(A&&A.message?A.message:A)})}},_o=async A=>{let j=A??P.current??p;g(!0),v({kind:"",text:""});let V=J(j);try{let Q=await fetch("/api/dsh-tty/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(V)}),ae=await Q.json();!Q.ok||!ae.ok?v({kind:"error",text:String(ae.error||S("error.saveFailed"))}):(v({kind:"ok",text:S("msg.saved")}),D.current=JSON.stringify(V),ae.config&&(P.current=ae.config,c(ae.config),fi(ae.config)))}catch(Q){v({kind:"error",text:String(Q&&Q.message?Q.message:Q)})}g(!1)},Ls=A=>"/api/dsh-tty/elevate"+A,mo=async()=>{try{let j=await(await fetch("/api/dsh-tty/config",{cache:"no-store"})).json(),V=j&&typeof j.config=="object"&&j.config!==null?j.config:null;if(V===null)return;c(Q=>{if(Q===null)return Q;let ae={...Q,allowProxyCommandGranted:V.allowProxyCommandGranted===!0,allowProxyCommandGrantSource:V.allowProxyCommandGrantSource??null,allowProxyCommandGrantedAt:Number.isFinite(V.allowProxyCommandGrantedAt)?V.allowProxyCommandGrantedAt:null};return P.current=ae,ae})}catch{}},go=async()=>{b(null),H(!1);let A=P.current||{},j=D.current!==null&&JSON.stringify(J(A))===D.current,V={...A,allowProxyCommand:!0};P.current=V,c(V),await mo(),j?(await _o(V),O(S("elev.granted"))):O(S("elev.grantedNeedSave"))},vo=async()=>{H(!1),O(""),b({phase:"loading"});try{let A=await fetch(Ls(""),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:ts})}),j=await A.json().catch(()=>({}));if(!A.ok){b({phase:"error",error:String(j.error||A.status)});return}if(j.status==="granted"){await go();return}b({phase:"pending",command:String(j.command??""),expiresAt:Number(j.expiresAt)||0})}catch(A){b({phase:"error",error:String(A&&A.message?A.message:A)})}},nh=async()=>{O("");try{let A=await fetch(Ls("/revoke"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:ts})}),j=await A.json().catch(()=>({}));if(!A.ok){O(S("elev.error")+String(j.error||A.status));return}await mo(),O(S("elev.revoked"))}catch(A){O(S("elev.error")+String(A&&A.message?A.message:A))}},oh=async()=>{let A=x===null?"":String(x.command??"");if(A!==""){if(lo())try{await navigator.clipboard.writeText(A),H(!0);return}catch{}H(!1),O(S("elev.copyManual"))}};r.useEffect(()=>{if(x===null||x.phase!=="pending")return;let A=setInterval(()=>K(Date.now()),1e3),j=setInterval(()=>{fetch(Ls("/status"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({capability:ts})}).then(V=>V.json()).then(V=>{V.status==="granted"&&go()}).catch(()=>{})},1500);return()=>{clearInterval(A),clearInterval(j)}},[x]);let ah=()=>{if(p.allowProxyCommandGrantSource==="env")return s("span",{className:"tt_cardHint",children:S("elev.viaEnv")});let A=p.allowProxyCommandGrantedAt;return a("span",{className:"tt_capState",children:[Number.isFinite(A)?s("span",{children:S("elev.grantedAt",{time:Zp(A)})}):null,s("button",{type:"button",className:"tt_toolBtn tt_capRevoke",onClick:()=>{nh()},children:S("elev.revoke")})]})},lh=()=>{let A=String(x.command??""),j=x.expiresAt>0?Math.max(0,Math.ceil((x.expiresAt-M)/1e3)):0,V=x.phase==="pending"&&x.expiresAt>0&&j===0,Q=()=>{b(null),H(!1)};return a("div",{className:"tt_elevPanel",children:[a("div",{className:"tt_elevHead",children:[s("span",{className:"tt_cardLabel",children:S("elev.title")}),s("button",{type:"button",className:"tt_toolBtn",onClick:Q,children:S("elev.close")})]}),s("span",{className:"tt_cardHint",children:S("elev.lockedWhy")}),x.phase==="error"?s("span",{className:"tt_cardHint tt_sshProbeWarn",children:S("elev.error")+String(x.error??"")}):null,x.phase==="loading"?s("span",{className:"tt_cardHint",children:S("elev.loading")}):null,A===""?null:a("div",{className:"tt_elevSteps",children:[s("span",{className:"tt_cardHint",children:S("elev.step")}),s("div",{className:"tt_elevCommand",children:s("code",{children:A})}),a("div",{className:"tt_elevActions",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{oh()},children:S(B?"elev.copied":"elev.copy")}),V?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{vo()},children:S("elev.regenerate")}):s("span",{className:"tt_cardHint",children:S("elev.expiresIn",{sec:j})})]}),s("span",{className:"tt_cardHint",children:S(V?"elev.expired":"elev.waiting")})]}),p.allowProxyCommand===!0&&p.allowProxyCommandGranted!==!0?s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{G("allowProxyCommand",!1),Q()},children:S("elev.disableFirst")}):null,s("span",{className:"tt_cardHint",children:S("elev.otherWay")}),s("span",{className:"tt_cardHint",children:S("elev.envHow",{env:ts})})]})},ch=()=>{let A=p.allowProxyCommandGranted===!0,j=p.allowProxyCommand===!0;return a("div",{className:"tt_capBlock",children:[a("label",{className:"tt_cardField tt_cardRow tt_cardToggle tt_cardDanger",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:j,onChange:V=>{if(!A){vo();return}G("allowProxyCommand",V.target.checked)}}),s("span",{className:"tt_cardLabel",children:S("check.allowProxyCommand")}),j&&!A?s("span",{className:"tt_badgeWarn",children:S("badge.notEffective")}):null]}),s("span",{className:"tt_cardHint",children:S("hint.allowProxyCommand")}),A?ah():s("span",{className:"tt_cardHint tt_sshProbeWarn",children:S("hint.proxyCommandNotGranted")}),E===""?null:s("span",{className:"tt_cardHint",children:E}),x===null?null:lh()]})},Ts=()=>{ge.current!==null&&(clearTimeout(ge.current),ge.current=null),fe("")},Rs=async A=>{let j=kr(A);if(Ar()===null){Ce(!1),ie(!1),te({text:S(Lt===null?"error.credPlainUnavailable":"error.credPlainIncomplete"),kind:"muted"});return}if(j===""){ie(!1),te({text:"",kind:""});return}let V=await ec(j);if(V.unreported===!0){ie(!1),te({text:S("status.credUnreported",{ref:j}),kind:"plain"});return}if(V.error!==void 0){ie(!1),te({text:S("error.credStatusFailed",{error:V.error}),kind:"error"});return}let Q=V.view;te({text:Q.configured?S("status.credStored",{ref:j,source:Q.source!==""?S("meta.credSource",{source:Q.source}):""}):S("status.credUnknown",{ref:j}),kind:Q.configured?"ok":"plain"}),ie(Q.configured===!0&&Q.writable===!0)},hh=async()=>{let A=kr(I?.password??"");if(A==="")return;let j=await tc(A);if(j.error!==void 0){te({text:j.error,kind:"error"});return}z(V=>({...V||{},password:""})),te({text:"",kind:""}),ie(!1)},dh=(A,j)=>{let V=String(I?.[A]??"");if(V===""||V.startsWith("env:")||be===j){Ts(),z(Q=>({...Q||{},[A]:"env:"+j})),re(""),A==="password"&&Rs("env:"+j);return}fe(j),ge.current!==null&&clearTimeout(ge.current),ge.current=setTimeout(()=>{ge.current=null,fe("")},4e3)},bo=(A,j)=>{if(ee===null)return null;if(ee.length===0)return s("span",{className:"tt_cardHint",children:j});let V=de===A,Q=Y.trim().toUpperCase(),ae=Q===""?ee:ee.filter(me=>me.toUpperCase().includes(Q));return a("div",{className:"tt_credPicker",children:[s("input",{className:"tt_cardInput",value:V?Y:"",placeholder:S("placeholder.credRef"),title:S("hint.credRefCandidates"),autoComplete:"off",spellCheck:!1,onFocus:()=>{re(A),se("")},onBlur:me=>{me.currentTarget.parentElement.contains(me.relatedTarget)||re("")},onChange:me=>{se(me.target.value),re(A)}}),...V?[s("div",{className:"tt_envList",children:[...ae.length===0?[s("span",{className:"tt_envMore",children:S("list.noCredRef")})]:ae.slice(0,30).map(me=>s("button",{type:"button",className:"tt_envItem","data-danger":be===me?"":void 0,onMouseDown:Ae=>Ae.preventDefault(),onClick:()=>dh(A,me),children:be===me?S("list.credOverwrite",{name:me}):me},me)),...ae.length>30?[s("span",{className:"tt_envMore",children:S("list.moreMatches",{count:ae.length-30})})]:[]]},"cred-list-"+A)]:[]]})},uh=()=>{let j=kr(I?.password??"")!=="",V=Ar()===null;return a("div",{className:"tt_sshRow tt_credRow",children:[j?s("button",{type:"button",className:"tt_toolBtn tt_credClear",disabled:le!==!0,onClick:()=>{hh()},children:S("btn.clearCredential")}):s("label",{className:"tt_credToggle",title:S("hint.rememberCredentialApply"),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:Le,disabled:V,onChange:Q=>Ce(Q.target.checked)}),s("span",{children:S("check.rememberCredentialApply")})]}),Z.text===""?null:s("span",{className:"tt_credStatus","data-kind":Z.kind,children:Z.text}),V&&Z.text===""?s("span",{className:"tt_credStatus","data-kind":"muted",children:S("error.credPlainUnavailable")}):null]})},wo=()=>{let A=String(I?.host??"").trim(),j=String(I?.username??"").trim(),V=Number(I?.port);if((!Number.isInteger(V)||V<1||V>65535)&&(V=22),A===""||j==="")return q(S("error.hostUserRequired")),null;let Q=I?.auth,ae={host:A,port:V,username:j,auth:Q};if(Q==="key"){let me=String(I?.keyPath??"").trim();if(me==="")return q(S("error.keyPathRequired")),null;ae.keyPath=me,I?.passphrase!==""&&(ae.passphrase=I.passphrase)}if(Q==="password"){let me=String(I?.password??"");if(me==="")return q(S("error.passwordRequired")),null;ae.password=me}return I?.agentForward===!0&&(ae.agentForward=!0),ae},fh=()=>{q("");let A=wo();A!==null&&(oe({running:!0,ok:!1,text:S("msg.probing")}),$n(A,!1).then(j=>{if(j.result){let V=j.result.auth?.ok===!0;oe({running:!1,ok:V,text:qn(j.result)});return}oe({running:!1,ok:!1,text:S("error.probeFailed",{detail:String(j.error||S("error.unknown"))})})}))},ph=()=>{q("");let A=wo();A!==null&&ks(A)},_h=()=>{if(I===null)return null;let A=(j,V,Q,ae,me)=>a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:j}),s("input",{className:"tt_cardInput",type:ae??"text",value:I[V]??"",placeholder:Q??"",autoComplete:"off",spellCheck:!1,onChange:Ae=>{let Se=Ae.target.value;z(Xe=>({...Xe||{},[V]:Se}))},...me??{}})]});return a("div",{className:"tt_sshEdit",children:[s("div",{className:"tt_sshSection",children:S("section.connection")}),a("div",{className:"tt_sshGrid",children:[A(S("field.bookName"),"name",S("hint.bookNameConflict")),A(S("field.port"),"port","22")]}),A(S("field.host"),"host",S("placeholder.host")),A(S("field.username"),"username","root"),s("div",{className:"tt_sshSection",children:S("section.auth")}),a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("field.authMethod")}),a("select",{className:"tt_cardInput",value:I.auth,onChange:j=>z(V=>({...V||{},auth:j.target.value})),children:[s("option",{value:"agent",children:S("option.authAgent")}),s("option",{value:"key",children:S("option.authKey")}),s("option",{value:"password",children:S("option.authPassword")})]})]}),...I.auth==="key"?[A(S("field.keyPath"),"keyPath","~/.ssh/id_ed25519"),A(S("field.passphrase"),"passphrase","","password"),bo("passphrase",S("hint.noCredRefPassphrase"))]:[],...I.auth==="password"?[A(S("field.password"),"password","","password",{onBlur:()=>{Rs(I.password)}}),uh(),bo("password",S("hint.noCredRefPasswordApply"))]:[],s("div",{className:"tt_sshSection",children:S("section.options")}),a("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:I.agentForward===!0,onChange:j=>z(V=>({...V||{},agentForward:j.target.checked}))}),s("span",{className:"tt_cardLabel",children:S("check.agentForward")})]}),Yt==="tmux"?a("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:I.persist===!0,onChange:j=>z(V=>({...V||{},persist:j.target.checked}))}),s("span",{className:"tt_cardLabel",children:S("check.persist")})]}):null,ne.text!==""?s("div",{className:"tt_sshProbeResult"+(!ne.running&&ne.ok?" tt_sshProbeOk":"")+(!ne.running&&!ne.ok?" tt_sshProbeBad":""),children:ne.text}):null,$!==""?s("span",{className:"tt_cardMessage tt_cardMessageError",children:$}):null,a("div",{className:"tt_sshActions",children:[a("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:fo,children:S("btn.cancel")}),s("button",{type:"button",className:"tt_toolBtn",title:S("btn.browseTitle"),onClick:ph,children:S("btn.fileBrowse")}),s("button",{type:"button",className:"tt_toolBtn",disabled:ne.running,title:S("btn.probeTitle"),onClick:fh,children:ne.running?S("msg.probing"):S("btn.probe")})]}),a("div",{className:"tt_sshActionsGroup",children:[s("button",{type:"button",className:"tt_cardSave",onClick:()=>{Qc()},children:S("btn.apply")}),s("span",{className:"tt_cardHint",children:S("hint.appliedOnSave")})]})]})]})},Nr=(A,j,V,Q)=>a("label",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:A}),s("input",{className:"tt_cardInput",value:p[j]??"",placeholder:V??"",onChange:ae=>G(j,ae.target.value)}),Q?s("span",{className:"tt_cardHint",children:Q}):null]}),Hr=(A,j,V,Q)=>a("label",{className:"tt_cardField tt_cardRow tt_cardToggle"+(typeof V=="string"&&V!==""?" "+V:""),children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:p[j]===!0,disabled:Q===!0&&p[j]!==!0,onChange:ae=>G(j,ae.target.checked)}),s("span",{className:"tt_cardLabel",children:A})]}),Fr=p?.platform==="win32";return l==="summary"?S("card.desc"):a(_?"div":"li",{className:_?"tt_pageHost":m?"tt_card tt_cardOpen":"tt_card",children:[_?null:a("button",{type:"button",className:"tt_cardHeader","aria-expanded":m,onClick:()=>w(A=>!A),children:[a("span",{className:"tt_cardHeadText",children:[s("span",{className:"tt_cardName",children:S("card.name")}),s("span",{className:"tt_cardDescription",children:S("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?a("div",{className:"tt_cardBody",children:[p===null?s("div",{className:"tt_cardMessage",children:S("list.loadingConfig")}):a("div",{children:[k(S("section.basic")),Hr(S("check.enabled"),"enabled"),Hr(S("check.announce"),"announceToAgent"),Fr?a("div",{className:"tt_cardField",children:[a("label",{className:"tt_cardRow",children:[s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:!1,disabled:!0}),s("span",{className:"tt_cardLabel",children:S("check.shellIntegration")})]}),s("span",{className:"tt_cardHint",children:S("hint.shellIntegrationWindows")})]}):Hr(S("check.shellIntegrationWindows"),"shellIntegration"),k(S("section.sftp")),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("field.sftpStyle")}),a("select",{className:"tt_cardInput",value:p.sftpStyle==="dual"?"dual":"dialog",onChange:A=>G("sftpStyle",A.target.value),children:[s("option",{value:"dialog",children:S("option.sftpDialog")}),s("option",{value:"dual",children:S("option.sftpDual")})]}),s("span",{className:"tt_cardHint",children:S("hint.sftpDual")})]}),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("field.sftpLimits")}),a("div",{className:"tt_limitGrid",children:[a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("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:A=>X("maxDownloadMb",Number(A.target.value)||0)})]}),a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("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:A=>X("maxUploadMb",Number(A.target.value)||0)})]}),a("label",{className:"tt_sshRow",children:[s("span",{className:"tt_cardLabel",children:S("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:A=>X("maxUploadFiles",Number(A.target.value)||0)})]})]}),s("span",{className:"tt_cardHint",children:S("hint.sftpLimits")})]}),k(S("section.session")),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("field.persistence")}),a("select",{className:"tt_cardInput",value:p.persistence==="tmux"?"tmux":"off",onChange:A=>G("persistence",A.target.value),children:[s("option",{value:"off",children:S("option.persistOff")}),s("option",{value:"tmux",children:S("option.persistTmux")})]}),s("span",{className:"tt_cardHint",children:S("hint.persistence")+(Fr?S("hint.persistenceWindows"):"")}),Hr(S("check.endOnPageClose"),"endOnPageClose"),Hr(S("check.statsEnabled"),"statsEnabled"),s("span",{className:"tt_cardHint",children:S("hint.statsEnabled")}),ch()]}),Nr(S("field.maxSessions"),"maxSessions","4",S("hint.maxSessions")),a("div",{className:"tt_cardField",onBlur:A=>{A.currentTarget.contains(A.relatedTarget)||T(!1)},children:[s("span",{className:"tt_cardLabel",children:S(Fr?"field.shellWindows":"field.shell")}),s("input",{className:"tt_cardInput",value:p.shell??"",placeholder:S(Fr?"placeholder.shellWindows":"placeholder.shell"),autoComplete:"off",spellCheck:!1,onFocus:()=>T(!0),onClick:()=>T(!0),onKeyDown:A=>{A.key==="Escape"&&T(!1)},onChange:A=>{G("shell",A.target.value),T(!0)}}),...y?[s("div",{className:"tt_envList tt_shellList",children:(()=>{let A=(p.shell??"").trim().toLowerCase(),j=A===""?F:F.filter(V=>V.toLowerCase().includes(A));return j.length===0?s("span",{className:"tt_envMore",children:S("list.noShellCandidate")}):j.map(V=>s("button",{type:"button",className:"tt_envItem",onMouseDown:Q=>Q.preventDefault(),onClick:()=>{G("shell",V),T(!1)},children:V},V))})()},"shell-list")]:[],s("span",{className:"tt_cardHint",children:S(Fr?"hint.shellCandidatesWindows":"hint.shellCandidates")})]},"shell-field"),Nr("TERM","term","xterm-256color",S("hint.term")),Nr("COLORTERM","colorTerm","truecolor",""),Nr(S("field.cwd"),"cwd","",S("placeholder.cwd")),Nr(S("field.grace"),"reconnectGraceSec","120",S("hint.grace")),k(S("section.ssh")),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("panel.sshBook")}),...Array.isArray(p.sshHosts)&&p.sshHosts.length>0?[s("div",{className:"tt_hostList","data-editing":W!==null?"":void 0,children:p.sshHosts.map(A=>a("div",{children:[a("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:A?.name??""}),s("span",{className:"tt_sshHostTarget",children:zn(A??{})})]}),s("button",{type:"button",className:"tt_toolBtn",disabled:pe[A?.name]?.running===!0,onClick:()=>{th(A)},title:S("btn.probeRowTitle"),children:pe[A?.name]?.running===!0?S("msg.testing"):S("btn.test")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Zc(A),children:S("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>eh(A?.name),children:S("btn.delete")})]}),pe[A?.name]&&pe[A?.name].text?s("div",{className:"tt_sshProbeResult"+(pe[A?.name].ok?" tt_sshProbeOk":" tt_sshProbeBad"),children:pe[A?.name].text}):null,W===A?.name?_h():null]},String(A?.name??"")))})]:[s("span",{className:"tt_cardHint",children:S("list.emptySshHosts")})],a("div",{className:"tt_cardRow",children:[s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{ih()},children:S("btn.importSshConfig")}),s("span",{className:"tt_cardHint",children:S("hint.importSshConfig")})]}),s("span",{className:"tt_cardHint",children:S("hint.sshBook")})]}),a("div",{className:"tt_cardField",children:[a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("panel.tunnels")}),...Array.isArray(p.tunnels)&&p.tunnels.length>0?[s("div",{children:p.tunnels.map(A=>{let j=_e.find(ae=>ae.name===A?.name),V=j?.state??"stopped",Q=xe!==null&&String(A?.name??"")===xe;return a("div",{className:"tt_sshHostRow","data-editing":Q?"":void 0,children:[s("span",{className:"tt_tunnelDot","data-state":V,title:V}),s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:(A?.name??"")+" \xB7 "+qc(A??{})}),s("span",{className:"tt_sshHostTarget",children:(A?.bookName??"")+(j?.error?" \xB7 "+j.error:"")+(j?.lastForwardError?" \xB7 "+j.lastForwardError:"")})]}),s("input",{type:"checkbox",className:"tt_cardCheckbox",checked:A?.enabled!==!1,title:S("check.tunnelEnabled"),onChange:ae=>Xc(A?.name,ae.target.checked)}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Kc(A),children:S("btn.edit")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>Jc(A?.name),children:S("btn.delete")})]},String(A?.name??""))})})]:[s("span",{className:"tt_cardHint",children:S("list.emptyTunnels")})],a("div",{className:"tt_sshEdit",children:[a("div",{className:"tt_cardRow tt_tunnelHead",children:[a("div",{className:"tt_segmented",role:"group","aria-label":S("field.direction"),children:[s("button",{type:"button",className:"tt_segmentedBtn","data-active":ye.direction!=="remote"?"":void 0,title:S("option.localForwardTitle"),onClick:()=>Qt("direction","local"),children:S("option.localForward")}),s("button",{type:"button",className:"tt_segmentedBtn","data-active":ye.direction==="remote"?"":void 0,title:S("option.remoteForwardTitle"),onClick:()=>Qt("direction","remote"),children:S("option.remoteForward")})]}),a("select",{className:"tt_cardInput",value:ye.bookName,onChange:je("bookName"),children:[s("option",{value:"",children:S("option.selectBook")}),...Array.isArray(p?.sshHosts)?p.sshHosts.map(A=>s("option",{value:A?.name??"",children:A?.name??""})):[]]})]}),s("span",{className:"tt_cardHint",children:co!==void 0?S("hint.tunnelViaBook",{book:zn(co)}):S("hint.tunnelBookEmpty")}),ye.direction==="local"?a("div",{className:"tt_tunnelEndpoints",children:[a("div",{className:"tt_tunnelHop",children:[a("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:S("hint.localListenFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.localPort"),value:ye.localPort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.localListenPort"),onChange:je("localPort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"local",title:S("hint.flowLocalToRemote"),"aria-hidden":"true",children:"\u2192"})]}),a("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:S("placeholder.remoteHost"),title:S("hint.remoteHostTitle"),value:ye.remoteHost,autoComplete:"off","aria-label":S("field.remoteHost"),onChange:je("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.port"),value:ye.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.remotePort"),onChange:je("remotePort")})]})]}):a("div",{className:"tt_tunnelEndpoints",children:[a("div",{className:"tt_tunnelHop",children:[a("div",{className:"tt_tunnelEndpoint",children:[s("input",{className:"tt_cardInput tt_tunnelHost",placeholder:S("placeholder.remoteListenHost"),title:S("hint.remoteListenHost"),value:ye.remoteHost,autoComplete:"off","aria-label":S("field.remoteListenHost"),onChange:je("remoteHost")}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.listenPort"),value:ye.remotePort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.remoteListenPort"),onChange:je("remotePort")})]}),s("span",{className:"tt_tunnelArrow","data-direction":"remote",title:S("hint.flowRemoteToLocal"),"aria-hidden":"true",children:"\u2192"})]}),a("div",{className:"tt_tunnelEndpoint",children:[s("span",{className:"tt_tunnelEndpointStatic",title:S("hint.localDialFixed"),children:"127.0.0.1"}),s("span",{className:"tt_tunnelColon",children:":"}),s("input",{className:"tt_cardInput tt_tunnelPort",placeholder:S("placeholder.localTargetPort"),value:ye.localTargetPort,autoComplete:"off",inputMode:"numeric","aria-label":S("field.localTargetPort"),onChange:je("localTargetPort")})]})]}),s("div",{className:"tt_tunnelEndpoints",children:[s("span",{className:"tt_tunnelEndLabel",children:ye.direction==="local"?S("hint.tunnelLocalSummary"):S("hint.tunnelRemoteSummary")})]}),s("div",{className:"tt_cardRow tt_tunnelActions",children:[xe===null?s("button",{type:"button",className:"tt_cardSave",onClick:Vc,children:S("btn.addTunnel")}):s("button",{type:"button",className:"tt_cardSave",onClick:Yc,children:S("btn.saveEdit")}),xe===null?null:s("button",{type:"button",className:"tt_toolBtn",onClick:Gc,children:S("btn.cancel")}),s("span",{className:"tt_cardHint",children:xe===null?S("hint.tunnelAdd"):S("hint.tunnelEditing",{name:xe})})]})]})]}),a("div",{className:"tt_cardField",children:[s("span",{className:"tt_cardLabel",children:S("panel.hostKeys")}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{sh()},children:S("btn.importKnownHosts")})]}),...Array.isArray(p.hostKeys)&&p.hostKeys.length>0?[s("div",{className:"tt_hostList",children:p.hostKeys.map((A,j)=>a("div",{className:"tt_sshHostRow",children:[s("div",{className:"tt_sshHostMeta",children:[s("span",{className:"tt_sshHostName",children:String(A?.host??"")+":"+String(A?.port??22)}),s("span",{className:"tt_sshHostTarget",children:po(A).map(V=>"sha256:"+V).join(" / ")})]}),s("button",{type:"button",className:"tt_toolBtn",onClick:()=>{rh(A)},children:S("btn.delete")})]},String(A?.host??"")+":"+String(A?.port??22)+"#"+String(j)))})]:[s("span",{className:"tt_cardHint",children:S("list.emptyHostKeys")})],s("span",{className:"tt_cardHint",children:S("hint.hostKeys")})]}),a("div",{className:"tt_cardField tt_cardRow",children:[s("button",{className:"tt_cardSave",disabled:f,onClick:()=>{_o()},children:S(f?"msg.saving":"btn.save")}),s("span",{className:"tt_cardMessage"+(C.kind==="ok"?" tt_cardMessageOk":C.kind==="error"?" tt_cardMessageError":""),children:C.text})]})]})]}):null]})}t.inject=["slots","sessions"];let o=["@hyzyn/dsh-tty#tty","@hyzyn/dsh-all#tty"];return t.apply=u=>{Hf(u),uc=u.sessions,u.inject(["remote","remote.credentials"],c=>(Lt=c.remote?.credentials??c["remote.credentials"]??null,()=>{Lt=null}));let l=!1,_=()=>{};_s={set(c){if(c!==l){if(l=c,c){_=o_();return}_(),_=()=>{},_i(),sr()}}},Rc(!0),ao();for(let c of o)u.slots.inject("plugins.row.config",()=>u.slots.register({name:"plugins.row.config",key:c},n));u.slots.inject("settings.kit.item",()=>u.slots.register({name:"settings.kit.item",id:"tty",order:80,label:()=>S("card.name")},n)),u.slots.inject("settings.plugin.item",()=>u.slots.register({name:"settings.plugin.item",key:"tty",order:100},n));let m=u.provide("ttyConnbar",{version:1,addAction:Ss,requestRender(){sr()}}),w=u.provide("ttyTerminal",{version:3,open(c){if(!nr)return;let d=vc(c),h=bc(c,d),f=typeof c?.label=="string"&&c.label!==""?c.label:void 0;if(mi(),c?.reuse!==!1){let g=mp(h);if(g!==null)return Jn(),Zt(g.sid),g}return Jn(),ui(h,f)},mount(c,d){return nr?xp(c,d):()=>{}}}),p=u.provide("ttyPanel",{version:2,isOpen(){return ce!==null&&!qe},mountPane(c){return Sc(c)},minimize(){return vs(),ce!==null&&qe}});return()=>{_s=null,nr=!1,_(),p(),w(),m(),_i()}},t}});})();
|
|
2812
2827
|
/*! Bundled license information:
|
|
2813
2828
|
|
|
2814
2829
|
@xterm/addon-search/lib/addon-search.mjs:
|