* feat: auto-poll Docker capabilities while Docker tab is active
When the Docker tab is visible and hasDocker is not yet true,
poll refreshCapabilities() at the process refresh interval.
Stop polling once hasDocker becomes true, or when switching
to a different tab.
* fix: use resolvedTab instead of activeTab for Docker auto-poll condition
The auto-poll useEffect condition used activeTab, which stays stale
when Docker becomes unavailable. Changed to resolvedTab which reflects
the actual displayed tab. Also updated the dep array.
* fix: replace setInterval with setTimeout recursion in Docker tab probe
Replace setInterval-based polling with setTimeout recursion in the Docker
tab capability probe effect. This ensures the next probe only starts after
the previous one finishes, avoiding overlapping probes when SSH timeout
exceeds the polling interval.
- Add dockerPollTimerRef to track the timeout handle
- Use async pollOnce() that awaits refreshCapabilities() before scheduling next
- Use cancelled flag in cleanup to prevent scheduling after unmount
- Keep same dependency array for correctness
* fix: stabilize docker poll timer by using useRef for refreshCapabilities
refreshCapabilities() can return a new reference on every render, causing
the useEffect to re-run on every render — cleanup cancels the polling timer,
then the effect immediately calls pollOnce(), effectively bypassing the
configured timeout interval.
Fix: store refreshCapabilities in a useRef (refreshRef), use
refreshRef.current() inside pollOnce(), and replace refreshCapabilities
with refreshRef in the useEffect dependency array.
Closes #PR1456 Codex P2 review item.
* fix: delay auto-poll first probe by one interval to avoid overlap with tab-switch probe
When switching to the Docker tab, two mechanisms were triggering probes:
1. tab-switch effect (line 67-76): immediate probe via refreshCapabilities()
2. auto-poll effect: pollOnce() executing immediately on mount
This caused duplicate probes that waste SSH channel resources.
Fix: pollOnce() no longer fires on mount. Instead, the effect schedules the
first probe with setTimeout(pollOnce, capabilitiesTtlMs), so the first probe
happens after one full interval. Subsequent probes continue at interval pace
via the setTimeout recursion in pollOnce itself.
The tab-switch effect still fires the immediate probe (the correct one),
so responsiveness on tab switch is preserved.
* fix: reset cancelledRef in effect body to prevent permanent stalling of Docker polling
The cancelledRef was set to true in the cleanup function when dependencies
changed, but never reset when the effect re-ran. This caused pollOnce to
always early-return on subsequent timer ticks, permanently halting
Docker capability probing after the first dependency change.
* fix(system-manager): replace cancelledRef with closure variables for per-effect cancellation
Each effect generation now has its own and closure
variables instead of shared / . This
prevents stale probes from surviving cleanup when the panel hides and
re-shows (Codex P2 review).
* fix: wrap refreshCapabilities in try/catch to keep polling on exception
If refreshCapabilities throws (instead of returning {success: false}),
the await would exit pollOnce without scheduling the next setTimeout,
silently killing Docker auto-detection polling.
* fix: add in-flight probe guard to prevent tab-switch and auto-poll concurrent probes
Add probingRef to track whether a capabilities probe is already in-flight.
- Tab-switch effect for Docker branch checks probingRef before starting a new probe
- Auto-poll pollOnce checks probingRef at entry and sets/clears it around the actual probe
- Tmux branch left unchanged as it has no auto-poll overlap risk
* fix: re-schedule next poll timer when probe is in-flight
When probingRef.current is true (tab-switch probe still running),
pollOnce was returning early without scheduling the next timer,
causing auto-poll to stop permanently afterward.
Now it schedules the next poll within the interval and returns,
so the polling loop keeps running until a slot where no probe is
active.
* fix: convert comments to ASCII-only English
- Line 105: translate Chinese comment to 'probe is in-flight, reschedule for next cycle'
- Line 113: replace em dash (U+2014) with ASCII dash
* feat: session inline rename, closeSession shortcut, pane zoom
* fix: sidebar inline rename with local state
* fix: add sessionDisplayName to terminalPropsAreEqual comparator
The Terminal component is wrapped with React.memo(…, terminalPropsAreEqual),
but the comparator was missing a check for sessionDisplayName. After renaming
a session, the pane title bar would show the old name until some other prop
changed and triggered a re-render.
Add prev.sessionDisplayName === next.sessionDisplayName to the comparator
so that display name changes cause the Terminal to re-render immediately.
* fix: add onStartSessionRename to TerminalLayerWorkspaceSection ctx destructuring and TerminalPanesHost props
* fix: add toggleWorkspaceViewMode to executeHotkeyActionImpl destructuring
The togglePaneZoom handler calls toggleWorkspaceViewMode() but it
wasn't destructured from getCtx(), causing a ReferenceError at runtime.
* fix: restore truncated ctx object in TerminalView render call
The TerminalView ctx object literal on line 1265 was truncated to
'showSele...' due to an editing tool truncation bug, causing
Parsing error: ',' expected on npm run lint / tsc --noEmit.
Restored the missing fields from the base commit:
showSelectionAIAction, snippets, status, statusDotTone, sudoHintRef,
sudoHintText: t("terminal.sudoHint.pressEnter"), t, termRef,
terminalBackend, terminalContextActions, terminalCwdTracker,
terminalPreviewVars, terminalSettings, timeLeft, toast, zmodem
Kept the PR's new additions (isVisible, onRename, sessionDisplayName)
intact.
* fix: add toggleWorkspaceViewMode to executeHotkeyAction context and add terminal.menu.rename translations
- Add toggleWorkspaceViewMode to the context getter in executeHotkeyAction (App.tsx)
- Add terminal.menu.rename translation for en (Rename), zh-CN (重命名), ru (Переименовать)
* fix: validate focusedSessionId before closing in closeSession hotkey
When closeSession hotkey fires, workspace.focusedSessionId may reference
a session that was already closed by another trigger (e.g., mouse click
on tab close button). Collect alive session IDs from the workspace root
and fall back to the first living pane if the stored focusedSessionId
is stale.
* fix(auto-poll): check useSessionCapabilities probing state in pollOnce
When auto-poll timer fires before the initial probe (from
useSessionCapabilities) completes, probingRef.current is still false
because the initial probe doesn't set it — causing a second overlapping
probe.
Add check so that any in-flight probe from any path
(initial/auto-poll/tab-switch) prevents auto-poll overlap.
PR #1459
* fix: address remaining Codex review issues
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add detach session from workspace with toolbar button and context menu
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: use customName in pane header display name for renamed sessions
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: refine workspace terminal detach interactions
* fix: preserve workspace detach tab ordering
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
718 lines
40 KiB
TypeScript
718 lines
40 KiB
TypeScript
import type { Messages } from '../types';
|
||
|
||
export const zhCNVaultMessages: Messages = {
|
||
// Select Host panel
|
||
'selectHost.title': '选择主机',
|
||
'selectHost.noHostsFound': '未找到主机',
|
||
'selectHost.newHost': '新建主机',
|
||
'selectHost.continue': '继续',
|
||
'selectHost.continueWithCount': '继续(已选 {count} 个)',
|
||
|
||
// Quick Connect
|
||
'quickConnect.knownHost.title': '确认要连接吗?',
|
||
'quickConnect.knownHost.authenticity': '无法验证 {hostname} 的真实性。',
|
||
'quickConnect.knownHost.fingerprintLabel': '{keyType} fingerprint (SHA256):',
|
||
'quickConnect.knownHost.addQuestion': '是否将它加入 Known Hosts?',
|
||
'quickConnect.knownHost.addAndContinue': '加入并继续',
|
||
'quickConnect.addKey': '添加 key',
|
||
'quickConnect.warning.unparsedOptions': '部分 SSH 参数已被忽略: {options}',
|
||
|
||
// Protocol select dialog
|
||
'protocolSelect.chooseProtocol': '选择协议',
|
||
'protocolSelect.port': '端口:',
|
||
// Host Details
|
||
'hostDetails.title.details': '主机详情',
|
||
'hostDetails.title.new': '新建主机',
|
||
'hostDetails.saveAria': '保存',
|
||
'hostDetails.section.address': '地址',
|
||
'hostDetails.hostname.placeholder': 'IP 或 主机名',
|
||
'hostDetails.section.general': '通用',
|
||
'hostDetails.section.sftp': 'SFTP 设置',
|
||
'hostDetails.sftp.sudo': 'Sudo 提权模式',
|
||
'hostDetails.sftp.sudo.desc': '使用保存的密码自动获取 Root 权限',
|
||
'hostDetails.sftp.sudo.passwordWarning': 'Sudo 模式需要密码。请在上方配置密码,或确保服务器允许免密 sudo。',
|
||
'hostDetails.sftp.encoding': '文件名编码',
|
||
'hostDetails.sftp.encoding.desc': '选择用于解码和发送 SFTP 文件名的编码。',
|
||
'hostDetails.label.placeholder': '名称(例如:Production Server)',
|
||
'hostDetails.notes.label': '备注',
|
||
'hostDetails.notes.placeholder': '硬件配置、项目、客户、地域、角色...',
|
||
'hostDetails.notes.help': '支持 Markdown。请勿在此存放密码或私钥。',
|
||
'hostDetails.notes.tab.edit': '编辑',
|
||
'hostDetails.notes.tab.preview': '预览',
|
||
'hostDetails.notes.preview.empty': '暂无内容可预览。',
|
||
'hostDetails.group.placeholder': '父级 Group',
|
||
'hostDetails.section.credentials': '凭据',
|
||
'hostDetails.section.portCredentials': '端口与凭据',
|
||
'hostDetails.section.appearance': '外观',
|
||
'hostDetails.distro.title': 'Linux 发行版',
|
||
'hostDetails.distro.desc': '可在连接后自动探测,也可以手动覆盖图标所用的发行版。',
|
||
'hostDetails.distro.mode': '来源',
|
||
'hostDetails.distro.mode.auto': '自动探测',
|
||
'hostDetails.distro.mode.manual': '手动覆盖',
|
||
'hostDetails.distro.detectedLabel': '当前值',
|
||
'hostDetails.distro.manualLabel': '手动指定',
|
||
'hostDetails.distro.pending': '首次连接后自动探测',
|
||
'hostDetails.distro.unknown': '未知',
|
||
'hostDetails.distro.option.linux': '通用 Linux',
|
||
'hostDetails.distro.option.ubuntu': 'Ubuntu',
|
||
'hostDetails.distro.option.debian': 'Debian',
|
||
'hostDetails.distro.option.centos': 'CentOS',
|
||
'hostDetails.distro.option.rocky': 'Rocky Linux',
|
||
'hostDetails.distro.option.fedora': 'Fedora',
|
||
'hostDetails.distro.option.arch': 'Arch Linux',
|
||
'hostDetails.distro.option.alpine': 'Alpine',
|
||
'hostDetails.distro.option.amazon': 'Amazon Linux',
|
||
'hostDetails.distro.option.opensuse': 'openSUSE / SLES',
|
||
'hostDetails.distro.option.redhat': 'Red Hat / RHEL',
|
||
'hostDetails.distro.option.almalinux': 'AlmaLinux',
|
||
'hostDetails.distro.option.alinux': '阿里云 Linux',
|
||
'hostDetails.distro.option.openeuler': 'openEuler',
|
||
'hostDetails.distro.option.oracle': 'Oracle Linux',
|
||
'hostDetails.distro.option.kali': 'Kali Linux',
|
||
'hostDetails.distro.option.cisco': '思科',
|
||
'hostDetails.distro.option.juniper': '瞻博网络',
|
||
'hostDetails.distro.option.huawei': '华为',
|
||
'hostDetails.distro.option.hpe': '慧与 / H3C',
|
||
'hostDetails.distro.option.mikrotik': 'MikroTik',
|
||
'hostDetails.distro.option.fortinet': '飞塔',
|
||
'hostDetails.distro.option.paloalto': 'Palo Alto Networks',
|
||
'hostDetails.distro.option.zyxel': '合勤',
|
||
'hostDetails.distro.option.ruijie': '锐捷',
|
||
'hostDetails.section.mosh': 'Mosh',
|
||
'hostDetails.section.et': 'EternalTerminal',
|
||
'hostDetails.et.port': 'ET 服务端口',
|
||
'hostDetails.et.port.desc': 'etserver 监听端口(默认 2022)',
|
||
'hostDetails.username.placeholder': '用户名',
|
||
'hostDetails.password.placeholder': '密码',
|
||
'hostDetails.password.show': '显示密码',
|
||
'hostDetails.password.hide': '隐藏密码',
|
||
'hostDetails.password.save': '保存密码',
|
||
'hostDetails.identity.suggestions': '身份',
|
||
'hostDetails.identity.missing': '身份不存在',
|
||
'hostDetails.credential.keyCertificate': '密钥 / 证书 / 本地密钥',
|
||
'hostDetails.credential.key': '密钥',
|
||
'hostDetails.credential.certificate': '证书',
|
||
'hostDetails.credential.localKeyFile': '本地密钥文件',
|
||
'hostDetails.credential.localKeyFilePlaceholder': '~/.ssh/id_ed25519',
|
||
'hostDetails.credential.browseKeyFile': '浏览…',
|
||
'hostDetails.credential.missing': '凭据不存在',
|
||
'hostDetails.keys.search': '搜索密钥…',
|
||
'hostDetails.keys.empty': '暂无密钥',
|
||
'hostDetails.certs.search': '搜索证书…',
|
||
'hostDetails.certs.empty': '暂无证书',
|
||
'hostDetails.agentForwarding': '转发 SSH 密钥',
|
||
'hostDetails.agentForwarding.desc': '允许远程服务器使用本地 SSH 密钥(例如用于 git 操作)',
|
||
'hostDetails.agentForwarding.agentNotRunning': 'SSH Agent 不可用',
|
||
'hostDetails.agentForwarding.agentNotRunningHint': '未检测到 SSH Agent。请启用 Windows OpenSSH Authentication Agent 服务,或使用兼容的 Agent(如 Bitwarden、1Password、gpg-agent)。',
|
||
'hostDetails.section.agentForwarding': 'SSH 代理',
|
||
'hostDetails.x11Forwarding': '转发 X11 图形应用',
|
||
'hostDetails.x11Forwarding.desc': '本机运行 X 服务时,让远程图形程序显示在本地桌面。',
|
||
'hostDetails.section.x11Forwarding': 'X11 转发',
|
||
'hostDetails.section.deviceType': '设备类型',
|
||
'hostDetails.deviceType': '网络设备模式',
|
||
'hostDetails.deviceType.desc': '适用于通过 SSH 连接的网络设备(交换机、路由器、防火墙)。命令将原样发送,不进行 Shell 包装,兼容华为 VRP、Cisco IOS 等厂商 CLI。',
|
||
'hostDetails.deviceType.warning': 'AI 代理命令将直接发送,无法获取退出码。仅建议在设备不运行标准 Shell 时启用。',
|
||
'hostDetails.section.sshAlgorithms': 'SSH 算法',
|
||
'hostDetails.section.terminalBehavior': '终端行为',
|
||
'hostDetails.lineTimestamps': '显示输出时间',
|
||
'hostDetails.lineTimestamps.desc': '在终端输出行旁边显示本地时间,不改变终端文本内容。',
|
||
'hostDetails.legacyAlgorithms': '允许旧版算法',
|
||
'hostDetails.legacyAlgorithms.desc': '启用已弃用的 SSH 算法(diffie-hellman-group1、ssh-dss、3des-cbc 等)以连接老旧网络设备。',
|
||
'hostDetails.legacyAlgorithms.warning': '这些算法存在已知安全漏洞,仅建议在老旧设备不支持现代加密时启用。',
|
||
'hostDetails.skipEcdsaHostKey': '跳过 ECDSA 主机密钥',
|
||
'hostDetails.skipEcdsaHostKey.desc': '某些老款华为 / 思科交换机的 ECDSA 主机密钥签名不规范,会导致连接报 "signature verification failed"。开启后客户端不再 advertise ecdsa-sha2-*,强制使用 RSA / Ed25519。',
|
||
'hostDetails.algorithms.advanced': '高级算法配置',
|
||
'hostDetails.algorithms.advanced.desc': '针对单个 host 自定义各分类的算法清单。不勾选 = 使用默认;勾选子集后将完全替换默认列表。配置错误可能导致无法连接。',
|
||
'hostDetails.algorithms.inheritedNotice': '当前组已设置以下分类的算法 override:{categories}。本面板的"恢复默认"只会回到组的设置,而不是 NetCatty 默认列表。若要忽略组的限制,请到组的算法设置里取消。',
|
||
'hostDetails.algorithms.customized': '已自定义',
|
||
'hostDetails.algorithms.reset': '恢复默认',
|
||
'hostDetails.algorithms.category.kex': '密钥交换 (KEX)',
|
||
'hostDetails.algorithms.category.cipher': '加密算法 (Cipher)',
|
||
'hostDetails.algorithms.category.hmac': '完整性算法 (HMAC)',
|
||
'hostDetails.algorithms.category.serverHostKey': '主机密钥 (Host Key)',
|
||
'hostDetails.algorithms.category.compress': '压缩 (Compression)',
|
||
'hostDetails.section.keepalive': '会话保活',
|
||
'hostDetails.keepalive.override': '为此主机单独配置',
|
||
'hostDetails.keepalive.desc': '为该主机使用专属的保活策略,而不是跟随全局设置。适用于不响应 keepalive@openssh.com 请求的老旧路由器 / 交换机——将间隔设为 0 可对该主机彻底关闭保活。',
|
||
'hostDetails.keepalive.interval': '间隔(秒)',
|
||
'hostDetails.keepalive.countMax': '最大无响应保活次数',
|
||
'hostDetails.keepalive.disabledHint': '间隔为 0 时该主机不发送保活包,仅依赖 TCP 层超时检测断连。',
|
||
'hostDetails.backspaceBehavior': 'Backspace 行为',
|
||
'hostDetails.backspaceBehavior.default': '默认',
|
||
'hostDetails.jumpHosts': '通过主机代理',
|
||
'hostDetails.jumpHosts.hops': '{count} 跳',
|
||
'hostDetails.jumpHosts.direct': '直连',
|
||
'hostDetails.jumpHosts.configure': '配置代理主机',
|
||
'hostDetails.proxy': '通过 HTTP/SOCKS5/命令代理',
|
||
'hostDetails.proxy.none': '无',
|
||
'hostDetails.proxy.edit': '编辑代理',
|
||
'hostDetails.proxy.configure': '配置代理',
|
||
'hostDetails.envVars': '环境变量',
|
||
'hostDetails.envVars.add': '添加环境变量',
|
||
'hostDetails.startupCommand': '启动命令',
|
||
'hostDetails.startupCommand.placeholder': '连接后执行的命令(例如:cd /app && ls)',
|
||
'hostDetails.startupCommand.help': 'SSH 连接建立后将自动执行该命令。',
|
||
'hostDetails.otherProtocols': '其他协议',
|
||
'hostDetails.telnetOn': 'Telnet on',
|
||
'hostDetails.port': '端口',
|
||
'hostDetails.telnet.credentials': '凭据',
|
||
'hostDetails.telnet.username': 'Telnet 用户名',
|
||
'hostDetails.telnet.password': 'Telnet 密码',
|
||
'hostDetails.charset.placeholder': '字符集(例如 UTF-8)',
|
||
'hostDetails.telnet.add': '添加 Telnet 协议',
|
||
'hostDetails.telnet.setDefault': '默认用 Telnet 连接',
|
||
'hostDetails.tags': '标签',
|
||
'hostDetails.group': '分组',
|
||
'hostDetails.selectGroup': '选择分组',
|
||
'hostDetails.addTag': '添加标签...',
|
||
'hostDetails.createTag': '创建标签',
|
||
'hostDetails.createGroup': '创建分组',
|
||
|
||
// Host form (legacy modal)
|
||
'hostForm.title.edit': '编辑主机',
|
||
'hostForm.title.new': '新建主机',
|
||
'hostForm.desc.edit': '更新该主机的连接信息',
|
||
'hostForm.desc.new': '创建一个新的 SSH 主机条目',
|
||
'hostForm.field.label': '名称',
|
||
'hostForm.placeholder.label': 'My Production Server',
|
||
'hostForm.field.hostname': 'Hostname / IP',
|
||
'hostForm.placeholder.hostname': '192.168.1.1',
|
||
'hostForm.field.port': '端口',
|
||
'hostForm.field.username': '用户名',
|
||
'hostForm.field.osType': '操作系统类型',
|
||
'hostForm.placeholder.selectOs': '选择操作系统',
|
||
'hostForm.field.group': '分组',
|
||
'hostForm.placeholder.group': '例如:AWS、DigitalOcean',
|
||
'hostForm.field.tags': '标签',
|
||
'hostForm.placeholder.addTag': '添加标签…',
|
||
'hostForm.auth.method': '认证方式',
|
||
'hostForm.auth.password': '密码',
|
||
'hostForm.auth.sshKey': 'SSH密钥',
|
||
'hostForm.auth.selectKey': '选择 SSH密钥',
|
||
'hostForm.auth.noKeys': '暂无密钥',
|
||
'hostForm.auth.noKeysHint': '钥匙串中未找到 SSH密钥,请先创建一个。',
|
||
'hostForm.saveHost': '保存主机',
|
||
|
||
// Connection logs
|
||
'logs.table.date': '日期',
|
||
'logs.table.user': '用户',
|
||
'logs.table.host': '主机',
|
||
'logs.table.saved': '收藏',
|
||
'logs.empty.title': '暂无连接日志',
|
||
'logs.empty.desc': '当你连接主机或打开本地终端后,这里会显示连接历史。',
|
||
'logs.loadMore': '加载更多 ({count} 条)',
|
||
'logs.ongoing': '进行中',
|
||
'logs.localTerminal': '本地终端',
|
||
'logs.action.save': '收藏',
|
||
'logs.action.unsave': '取消收藏',
|
||
'logs.action.delete': '删除',
|
||
|
||
// Log view
|
||
'logView.customizeAppearance': '自定义外观',
|
||
'logView.appearance': '外观',
|
||
'logView.readOnly': '只读',
|
||
'logView.export': '导出',
|
||
|
||
// Terminal toolbar / search / context menu / auth
|
||
'terminal.toolbar.openSftp': '打开 SFTP',
|
||
'terminal.toolbar.availableAfterConnect': '连接后可用',
|
||
'terminal.toolbar.sendYmodem': 'YMODEM 发送',
|
||
'terminal.toolbar.receiveYmodem': 'YMODEM 接收',
|
||
'terminal.toolbar.sftp': 'SFTP',
|
||
'terminal.toolbar.more': '更多操作',
|
||
'terminal.toolbar.scripts': '脚本',
|
||
'terminal.toolbar.history': '命令历史',
|
||
'terminal.toolbar.library': '库',
|
||
'terminal.toolbar.noSnippets': '暂无代码片段',
|
||
'terminal.toolbar.terminalSettings': '终端设置',
|
||
'terminal.toolbar.searchTerminal': '搜索终端',
|
||
'terminal.toolbar.search': '搜索',
|
||
'terminal.toolbar.broadcast': '广播',
|
||
'terminal.toolbar.broadcastEnable': '启用广播模式',
|
||
'terminal.toolbar.broadcastDisable': '关闭广播模式',
|
||
'terminal.toolbar.composeBar': '撰写栏',
|
||
'terminal.composeBar.placeholder': '在此输入命令,按回车发送...',
|
||
'terminal.composeBar.send': '发送',
|
||
'terminal.composeBar.close': '关闭撰写栏',
|
||
'terminal.composeBar.broadcasting': '正在广播到所有会话',
|
||
'terminal.composeBar.resize': '拖拽调整撰写栏高度',
|
||
'terminal.composeBar.manageSnippets': '管理快捷代码片段',
|
||
'terminal.composeBar.searchSnippets': '搜索代码片段...',
|
||
'terminal.composeBar.noPinnedSnippets': '点击 + 固定常用代码片段',
|
||
'terminal.composeBar.noMatchingSnippets': '没有匹配的代码片段',
|
||
'terminal.composeBar.pinnedCount': '已固定 {count} 个',
|
||
'terminal.composeBar.unpinSnippet': '从快捷栏移除 {label}',
|
||
'terminal.composeBar.snippetClickHint': '单击插入 · Shift+单击直接发送',
|
||
'terminal.toolbar.focus': '聚焦',
|
||
'terminal.toolbar.focusMode': '聚焦模式',
|
||
'terminal.toolbar.detach': '移出到独立标签',
|
||
'terminal.toolbar.encoding': '终端编码',
|
||
'terminal.toolbar.encoding.utf8': 'UTF-8',
|
||
'terminal.toolbar.encoding.gb18030': 'GB18030',
|
||
'terminal.toolbar.closeSession': '关闭会话',
|
||
'terminal.toolbar.hostHighlight.title': '主机关键字高亮',
|
||
'terminal.toolbar.hostHighlight.noRules': '此主机未定义自定义高亮规则',
|
||
'terminal.toolbar.hostHighlight.addRule': '添加新规则',
|
||
'terminal.toolbar.hostHighlight.labelPlaceholder': '标签(例如:错误)',
|
||
'terminal.toolbar.hostHighlight.patternPlaceholder': '正则表达式(例如:\\bfailed\\b)',
|
||
'terminal.toolbar.hostHighlight.invalidPattern': '无效的正则表达式',
|
||
'terminal.toolbar.hostHighlight.clearAll': '清除全部',
|
||
'terminal.toolbar.hostHighlight.changeColor': '更改高亮颜色',
|
||
'terminal.toolbar.hostHighlight.selectColor': '选择新规则的颜色',
|
||
'terminal.statusbar.copyHostname.label': '复制主机地址',
|
||
'terminal.statusbar.copyHostname.tooltip': '复制主机地址({hostname})',
|
||
'terminal.statusbar.copyHostname.toast': '已复制主机地址:{hostname}',
|
||
'terminal.statusbar.copyHostname.error': '复制主机地址失败',
|
||
'terminal.serverStats.cpu': 'CPU 使用率',
|
||
'terminal.serverStats.cpuCores': 'CPU 核心使用率',
|
||
'terminal.serverStats.memory': '内存使用',
|
||
'terminal.serverStats.memoryDetails': '内存详情',
|
||
'terminal.serverStats.memUsed': '已用',
|
||
'terminal.serverStats.memBuffers': '缓冲区',
|
||
'terminal.serverStats.memCached': '缓存',
|
||
'terminal.serverStats.memFree': '空闲',
|
||
'terminal.serverStats.swap': '交换空间',
|
||
'terminal.serverStats.swapUsed': '已用交换',
|
||
'terminal.serverStats.swapFree': '空闲交换',
|
||
'terminal.serverStats.swapTotal': '总计',
|
||
'terminal.serverStats.topProcesses': '内存占用前十进程',
|
||
'terminal.serverStats.disk': '磁盘使用(根分区)',
|
||
'terminal.serverStats.diskDetails': '已挂载磁盘',
|
||
'terminal.serverStats.network': '网络速度',
|
||
'terminal.serverStats.networkDetails': '网络接口',
|
||
'terminal.serverStats.noData': '暂无数据',
|
||
'terminal.dragDrop.localTitle': '拖放以插入路径',
|
||
'terminal.dragDrop.localMessage': '文件路径将被插入到终端',
|
||
'terminal.dragDrop.remoteTitle': '拖放以上传文件',
|
||
'terminal.dragDrop.remoteZmodemMessage': '文件将通过 ZMODEM(PTY)上传',
|
||
'terminal.dragDrop.remoteSftpMessage': '文件将通过 SFTP 上传',
|
||
'terminal.dragDrop.noFiles': '没有可上传的文件',
|
||
'terminal.dragDrop.notConnected': '无法拖放文件 - 终端未连接',
|
||
'terminal.dragDrop.errorTitle': '拖放错误',
|
||
'terminal.dragDrop.errorMessage': '处理拖放文件失败',
|
||
'terminal.search.placeholder': '搜索…',
|
||
'terminal.search.noResults': '无结果',
|
||
'terminal.search.prevMatch': '上一个匹配 (Shift+Enter)',
|
||
'terminal.search.nextMatch': '下一个匹配 (Enter)',
|
||
'terminal.menu.copy': '复制',
|
||
'terminal.menu.paste': '粘贴',
|
||
'terminal.menu.addSelectionToAI': '添加到对话',
|
||
'terminal.menu.pasteSelection': '粘贴选中文本',
|
||
'terminal.menu.selectAll': '全选',
|
||
'terminal.menu.reconnect': '重新连接',
|
||
'terminal.menu.sendYmodem': 'YMODEM 发送',
|
||
'terminal.menu.receiveYmodem': 'YMODEM 接收',
|
||
'terminal.menu.splitHorizontal': '水平分屏',
|
||
'terminal.menu.splitVertical': '垂直分屏',
|
||
'terminal.menu.clearBuffer': '清空缓冲区',
|
||
'terminal.menu.closeTerminal': '关闭终端',
|
||
'terminal.menu.rename': '重命名',
|
||
'terminal.menu.detach': '从工作区移出',
|
||
'terminal.menu.detachSession': '移出 {name}',
|
||
'terminal.ymodem.selectFile': '选择要发送的文件',
|
||
'terminal.ymodem.allFiles': '所有文件',
|
||
'terminal.ymodem.started': '正在通过 YMODEM 发送 {fileName}',
|
||
'terminal.ymodem.complete': 'YMODEM 已发送 {fileName}',
|
||
'terminal.ymodem.failed': 'YMODEM 发送失败',
|
||
'terminal.ymodem.selectReceiveDirectory': '选择接收文件保存位置',
|
||
'terminal.ymodem.receiveStarted': '正在通过 YMODEM 接收...',
|
||
'terminal.ymodem.receiveComplete': 'YMODEM 已接收 {fileName}',
|
||
'terminal.ymodem.receiveCompleteMultiple': 'YMODEM 已接收 {count} 个文件',
|
||
'terminal.ymodem.receiveEmpty': '没有接收到 YMODEM 文件',
|
||
'terminal.ymodem.receiveFailed': 'YMODEM 接收失败',
|
||
'terminal.ymodem.unavailable': 'YMODEM 当前不可用',
|
||
'terminal.selection.addToAI': '添加到对话',
|
||
'terminal.selection.addToAIDesc': '将选中的终端输出作为附件加入 AI 草稿',
|
||
'terminal.auth.password': '密码',
|
||
'terminal.auth.sshKey': 'SSH Key',
|
||
'terminal.auth.username': '用户名',
|
||
'terminal.auth.username.placeholder': 'root',
|
||
'terminal.auth.passwordLabel': '密码',
|
||
'terminal.auth.password.placeholder': '输入密码',
|
||
'terminal.auth.passphrase': '密码短语',
|
||
'terminal.auth.passphrase.placeholder': '可选:所选私钥的密码短语',
|
||
'terminal.auth.certificate': '证书',
|
||
'terminal.auth.selectKey': '选择密钥',
|
||
'terminal.auth.noKeysHint': '暂无密钥,请先在钥匙串中添加。',
|
||
'terminal.auth.continueSave': '继续并保存',
|
||
'terminal.auth.credentialsUnavailable': '当前设备无法解密已保存凭据,请重新输入并再次保存。',
|
||
'terminal.auth.jumpCredentialsUnavailable': '某个跳板机的已保存凭据无法在当前设备解密,请到主机设置中重新填写。',
|
||
'terminal.auth.proxyCredentialsUnavailable': '代理凭据无法在当前设备解密,请到主机设置中重新填写代理密码。',
|
||
'terminal.auth.keyUnavailableFallbackPassword': '已保存 SSH 密钥在当前设备不可用,改用密码认证。',
|
||
'terminal.connectionErrorTitle': '连接错误',
|
||
'terminal.progress.timeoutIn': '将在 {seconds}s 后超时',
|
||
'terminal.progress.disconnected': '已断开',
|
||
'terminal.progress.cancelling': '正在取消...',
|
||
'terminal.progress.startOver': '重新开始',
|
||
'terminal.connection.dismissDisconnectedDialog': '关闭断连提示',
|
||
'terminal.connection.chainOf': 'Chain {current} / {total}',
|
||
'terminal.connection.showLogs': '显示日志',
|
||
'terminal.connection.hideLogs': '隐藏日志',
|
||
'terminal.connection.protocol.ssh': 'SSH',
|
||
'terminal.connection.protocol.telnet': 'Telnet',
|
||
'terminal.connection.protocol.mosh': 'Mosh',
|
||
'terminal.connection.protocol.serial': '串口',
|
||
'terminal.connection.protocol.local': '本地终端',
|
||
'terminal.hostKey.unknownTitle': '确认主机指纹',
|
||
'terminal.hostKey.changedTitle': '主机指纹已变化',
|
||
'terminal.hostKey.unknownDescription': '尚未确认 {host} 的真实性。',
|
||
'terminal.hostKey.changedDescription': '{host} 的已保存指纹与当前服务器不一致。',
|
||
'terminal.hostKey.fingerprintLabel': '{keyType} 指纹为 SHA256:',
|
||
'terminal.hostKey.savedFingerprintLabel': '已保存的指纹',
|
||
'terminal.hostKey.unknownHint': '如果这个指纹属于你预期连接的服务器,可以记住它。',
|
||
'terminal.hostKey.changedHint': '只有在你确认这台主机确实变更过时才继续。',
|
||
'terminal.hostKey.addAndContinue': '记住并继续',
|
||
'terminal.hostKey.updateAndContinue': '更新并继续',
|
||
'terminal.themeModal.title': 'Terminal 外观',
|
||
'terminal.themeModal.tab.theme': '主题',
|
||
'terminal.themeModal.tab.font': '字体',
|
||
'terminal.themeModal.tab.custom': '自定义',
|
||
'terminal.themeModal.globalTheme': '全局主题',
|
||
'terminal.themeModal.globalFont': '全局字体',
|
||
'terminal.themeModal.fontSize': '字体大小',
|
||
'terminal.themeModal.fontWeight': '字体粗细',
|
||
'terminal.themeModal.livePreview': '实时预览',
|
||
'terminal.themeModal.themeType': '{type} 主题',
|
||
'terminal.hiddenTheme.title': '当前隐藏主题',
|
||
'terminal.hiddenTheme.desc': '这个主题已从手动选择列表中隐藏;当你选择其他可见主题后,它会被替换。',
|
||
'topTabs.toggleTheme.systemExitTitle': '当前正在跟随系统主题',
|
||
'topTabs.toggleTheme.systemExitMessage': '请到设置里选择固定的浅色或深色主题。',
|
||
'topTabs.toggleTheme.openSettings': '打开设置',
|
||
|
||
// Custom Themes
|
||
'terminal.customTheme.section': '自定义主题',
|
||
'terminal.customTheme.yourThemes': '我的主题',
|
||
'terminal.customTheme.new': '新建主题',
|
||
'terminal.customTheme.newDesc': '克隆当前主题并自定义',
|
||
'terminal.customTheme.newTitle': '新建自定义主题',
|
||
'terminal.customTheme.editTitle': '编辑主题',
|
||
'terminal.customTheme.import': '导入 .itermcolors',
|
||
'terminal.customTheme.importDesc': '从 iTerm2 配色方案文件导入',
|
||
'terminal.customTheme.importError': '无法解析所选文件,请确保它是有效的 .itermcolors XML 文件。',
|
||
'terminal.customTheme.delete': '删除主题',
|
||
'terminal.customTheme.confirmDelete': '确认删除',
|
||
'terminal.customTheme.name': '名称',
|
||
'terminal.customTheme.namePlaceholder': '我的自定义主题',
|
||
'terminal.customTheme.type': '类型',
|
||
'terminal.customTheme.group.general': '通用',
|
||
'terminal.customTheme.group.normal': '标准色',
|
||
'terminal.customTheme.group.bright': '高亮色',
|
||
'terminal.customTheme.color.background': '背景',
|
||
'terminal.customTheme.color.foreground': '前景',
|
||
'terminal.customTheme.color.cursor': '光标',
|
||
'terminal.customTheme.color.selection': '选区',
|
||
'terminal.customTheme.color.black': '黑色',
|
||
'terminal.customTheme.color.red': '红色',
|
||
'terminal.customTheme.color.green': '绿色',
|
||
'terminal.customTheme.color.yellow': '黄色',
|
||
'terminal.customTheme.color.blue': '蓝色',
|
||
'terminal.customTheme.color.magenta': '品红',
|
||
'terminal.customTheme.color.cyan': '青色',
|
||
'terminal.customTheme.color.white': '白色',
|
||
'terminal.customTheme.color.brightBlack': '亮黑',
|
||
'terminal.customTheme.color.brightRed': '亮红',
|
||
'terminal.customTheme.color.brightGreen': '亮绿',
|
||
'terminal.customTheme.color.brightYellow': '亮黄',
|
||
'terminal.customTheme.color.brightBlue': '亮蓝',
|
||
'terminal.customTheme.color.brightMagenta': '亮品红',
|
||
'terminal.customTheme.color.brightCyan': '亮青色',
|
||
'terminal.customTheme.color.brightWhite': '亮白',
|
||
|
||
'cloudSync.gate.title': '端到端加密同步',
|
||
'cloudSync.gate.desc':
|
||
'数据会在本地加密后再同步,云端不会看到明文。设置主密钥以启用安全同步。',
|
||
'cloudSync.gate.masterKey': '主密钥',
|
||
'cloudSync.gate.confirmMasterKey': '确认主密钥',
|
||
'cloudSync.gate.placeholder': '输入一个强密码',
|
||
'cloudSync.gate.confirmPlaceholder': '再次输入密码',
|
||
'cloudSync.gate.mismatch': '两次输入的密码不一致',
|
||
'cloudSync.gate.warning':
|
||
'我已了解:如果忘记主密钥,数据无法恢复,且没有密码重置功能。',
|
||
'cloudSync.gate.enableVault': '启用加密 Vault',
|
||
'cloudSync.gate.enabledToast': '已启用加密 Vault',
|
||
'cloudSync.gate.setupFailed': '设置主密钥失败',
|
||
'cloudSync.passwordStrength.tooShort': '太短',
|
||
'cloudSync.passwordStrength.weak': '弱',
|
||
'cloudSync.passwordStrength.moderate': '一般',
|
||
'cloudSync.passwordStrength.strong': '强',
|
||
'cloudSync.passwordStrength.veryStrong': '非常强',
|
||
'cloudSync.provider.notConnected': '未连接',
|
||
'cloudSync.provider.sync': '同步',
|
||
'cloudSync.provider.connect': '连接',
|
||
'cloudSync.provider.connecting': '连接中...',
|
||
'cloudSync.provider.webdav': 'WebDAV',
|
||
'cloudSync.provider.webdav.desc': '连接到自建 WebDAV 端点',
|
||
'cloudSync.provider.s3': 'S3 兼容存储',
|
||
'cloudSync.provider.s3.desc': '连接到 S3 兼容对象存储',
|
||
'cloudSync.provider.comingSoon': '即将支持',
|
||
'cloudSync.webdav.title': 'WebDAV 设置',
|
||
'cloudSync.webdav.desc': '配置 WebDAV 端点用于加密同步。',
|
||
'cloudSync.webdav.endpoint': '端点地址',
|
||
'cloudSync.webdav.authType': '认证方式',
|
||
'cloudSync.webdav.auth.basic': 'Basic',
|
||
'cloudSync.webdav.auth.digest': 'Digest',
|
||
'cloudSync.webdav.auth.token': 'Token',
|
||
'cloudSync.webdav.username': '用户名',
|
||
'cloudSync.webdav.password': '密码',
|
||
'cloudSync.webdav.token': 'Token',
|
||
'cloudSync.webdav.showSecret': '显示密钥',
|
||
'cloudSync.webdav.allowInsecure': '允许不安全的连接(忽略证书错误)',
|
||
'cloudSync.webdav.validation.endpoint': '请输入有效的 WebDAV 端点。',
|
||
'cloudSync.webdav.validation.credentials': '请输入用户名和密码。',
|
||
'cloudSync.webdav.validation.token': '请输入 Token。',
|
||
'cloudSync.s3.title': 'S3 设置',
|
||
'cloudSync.s3.desc': '连接到 S3 兼容对象存储以进行加密同步。',
|
||
'cloudSync.s3.endpoint': '端点地址',
|
||
'cloudSync.s3.region': 'Region',
|
||
'cloudSync.s3.bucket': 'Bucket',
|
||
'cloudSync.s3.accessKeyId': 'Access Key ID',
|
||
'cloudSync.s3.secretAccessKey': 'Secret Access Key',
|
||
'cloudSync.s3.sessionToken': 'Session Token(可选)',
|
||
'cloudSync.s3.prefix': 'Key 前缀(可选)',
|
||
'cloudSync.s3.forcePathStyle': '强制使用 path-style URL(适用于 MinIO/R2 等)',
|
||
'cloudSync.s3.showSecret': '显示密钥',
|
||
'cloudSync.s3.validation.required': '端点、Region、Bucket、Access Key 与 Secret 必填。',
|
||
'cloudSync.smb.title': 'SMB 设置',
|
||
'cloudSync.smb.desc': '连接到 SMB/CIFS 文件共享以进行加密同步。',
|
||
'cloudSync.smb.share': '共享路径',
|
||
'cloudSync.smb.username': '用户名',
|
||
'cloudSync.smb.password': '密码',
|
||
'cloudSync.smb.domain': '域(可选)',
|
||
'cloudSync.smb.domainPlaceholder': '例如:WORKGROUP',
|
||
'cloudSync.smb.port': '端口(可选)',
|
||
'cloudSync.smb.showSecret': '显示密码',
|
||
'cloudSync.smb.validation.share': '共享路径必填。',
|
||
'cloudSync.smb.validation.port': '端口必须是 1 到 65535 之间的数字。',
|
||
'cloudSync.connect.smb.success': 'SMB 已连接',
|
||
'cloudSync.connect.smb.failedTitle': 'SMB 连接失败',
|
||
'cloudSync.provider.smb': 'SMB 共享',
|
||
'cloudSync.connect.webdav.success': 'WebDAV 已连接',
|
||
'cloudSync.connect.webdav.failedTitle': 'WebDAV 连接失败',
|
||
'cloudSync.connect.s3.success': 'S3 已连接',
|
||
'cloudSync.connect.s3.failedTitle': 'S3 连接失败',
|
||
'cloudSync.lastSync.never': '从未',
|
||
'cloudSync.lastSync.justNow': '刚刚',
|
||
'cloudSync.lastSync.minutesAgo': '{minutes} 分钟前',
|
||
'cloudSync.changeKey': '更改 Key',
|
||
'cloudSync.providers.title': '云服务',
|
||
'cloudSync.syncAll': '同步所有已连接的服务',
|
||
'cloudSync.autoSync.title': '自动同步',
|
||
'cloudSync.autoSync.desc': '发生变更时自动同步',
|
||
'cloudSync.strategy.title': '同步策略',
|
||
'cloudSync.strategy.desc': '当本地和云端都发生变化时,选择如何处理。',
|
||
'cloudSync.strategy.smartMerge': '智能合并(推荐)',
|
||
'cloudSync.strategy.smartMergeDesc': '尽量保留两边的变化;如果无法安全判断,会再让你手动选择。',
|
||
'cloudSync.strategy.preferCloud': '云端优先',
|
||
'cloudSync.strategy.preferCloudDesc': '两边都有变化时,下载云端版本,并替换本地变化。',
|
||
'cloudSync.strategy.preferLocal': '本地优先',
|
||
'cloudSync.strategy.preferLocalDesc': '两边都有变化时,上传本地版本,并替换云端变化。',
|
||
'cloudSync.status.title': '同步状态',
|
||
'cloudSync.status.localVersion': '本地版本',
|
||
'cloudSync.status.remoteVersion': '远端版本',
|
||
'cloudSync.history.title': '同步历史',
|
||
'cloudSync.history.upload': '上传',
|
||
'cloudSync.history.download': '下载',
|
||
'cloudSync.history.resolved': '已解决',
|
||
'cloudSync.history.error': '错误',
|
||
'cloudSync.localBackups.title': '本地备份历史',
|
||
'cloudSync.localBackups.desc': 'Netcatty 会在版本变化前,以及恢复主机库前,自动留下一份本地恢复点。',
|
||
'cloudSync.localBackups.retentionTitle': '备份保留数量',
|
||
'cloudSync.localBackups.retentionDesc': '设置 Netcatty 最多保留多少份本地备份。',
|
||
'cloudSync.localBackups.maxCount': '最多保留',
|
||
'cloudSync.localBackups.maxSaved': '已保存保留数量:{count}',
|
||
'cloudSync.localBackups.maxInvalid': '请输入 1 到 100 之间的数字。',
|
||
'cloudSync.localBackups.empty': '还没有本地备份。',
|
||
'cloudSync.localBackups.reason.appVersionChange': '版本变化前',
|
||
'cloudSync.localBackups.reason.beforeRestore': '恢复前',
|
||
'cloudSync.localBackups.versionChange': '{from} -> {to}',
|
||
'cloudSync.localBackups.counts': '{hosts} 台主机,{keys} 个密钥,{snippets} 个代码片段',
|
||
'cloudSync.localBackups.restore': '恢复',
|
||
'cloudSync.localBackups.restoreSuccess': '已恢复本地备份。',
|
||
'cloudSync.localBackups.restoreFailedTitle': '恢复失败',
|
||
'cloudSync.localBackups.restoreMissing': '找不到这份备份。',
|
||
'cloudSync.localBackups.protectiveBackupFailed': '无法创建保护性备份,已中止恢复以避免覆盖当前数据。请先解决底层问题(例如钥匙串访问)后重试。详情:{message}',
|
||
'cloudSync.localBackups.restoreConfirmTitle': '确认恢复此备份?',
|
||
'cloudSync.localBackups.restoreConfirmDesc': '当前的主机、密钥、代码片段与设置将被替换为此备份中的内容。系统会先自动创建一个保护性快照,便于撤销。',
|
||
'cloudSync.localBackups.restoreConfirmButton': '恢复',
|
||
'cloudSync.localBackups.restoreConfirmCancel': '取消',
|
||
'cloudSync.localBackups.unavailableTitle': '无法使用本地备份',
|
||
'cloudSync.localBackups.unavailableDesc': '当前平台未提供受支持的安全密钥库,Netcatty 无法安全地写入本地备份。请在支持系统钥匙串的环境中运行,或改用云同步保留恢复点。',
|
||
'cloudSync.localBackups.lockedTitle': '需要主密钥',
|
||
'cloudSync.localBackups.lockedDesc': '请先配置或解锁主密钥再恢复备份,以确保恢复后的凭据仍保持加密。',
|
||
'cloudSync.revisionHistory.viewButton': '历史版本',
|
||
'cloudSync.revisionHistory.title': '主机库版本历史',
|
||
'cloudSync.revisionHistory.description': '浏览并恢复 Gist 修订历史中的旧版主机库数据。',
|
||
'cloudSync.revisionHistory.empty': '未找到修订记录。',
|
||
'cloudSync.revisionHistory.current': '当前版本',
|
||
'cloudSync.revisionHistory.revision': '修订',
|
||
'cloudSync.revisionHistory.revisionPreview': '修订内容',
|
||
'cloudSync.revisionHistory.device': '设备',
|
||
'cloudSync.revisionHistory.hosts': '主机',
|
||
'cloudSync.revisionHistory.keys': '密钥',
|
||
'cloudSync.revisionHistory.snippets': '代码片段',
|
||
'cloudSync.revisionHistory.identities': '身份',
|
||
'cloudSync.revisionHistory.restoreButton': '恢复此版本',
|
||
'cloudSync.revisionHistory.restored': '已从选中的修订恢复主机库数据。',
|
||
'cloudSync.revisionHistory.revisionNotFound': '修订未找到或不包含主机库数据。',
|
||
'cloudSync.revisionHistory.decryptFailed': '无法解密此修订。可能是使用了不同的主密钥加密的。',
|
||
'cloudSync.changeKey.title': '更改主密钥',
|
||
'cloudSync.changeKey.current': '当前主密钥',
|
||
'cloudSync.changeKey.new': '新的主密钥',
|
||
'cloudSync.changeKey.confirmNew': '确认新的主密钥',
|
||
'cloudSync.changeKey.currentPlaceholder': '输入当前主密钥',
|
||
'cloudSync.changeKey.newPlaceholder': '输入新的主密钥',
|
||
'cloudSync.changeKey.confirmPlaceholder': '再次输入新的主密钥',
|
||
'cloudSync.changeKey.fillAll': '请填写所有字段',
|
||
'cloudSync.changeKey.minLength': '新的主密钥至少 8 个字符',
|
||
'cloudSync.changeKey.notMatch': '两次输入的主密钥不一致',
|
||
'cloudSync.changeKey.incorrectCurrent': '当前主密钥不正确',
|
||
'cloudSync.changeKey.failed': '更改主密钥失败',
|
||
'cloudSync.changeKey.desc': '这将重新加密 Vault,请务必记住新的主密钥。',
|
||
'cloudSync.changeKey.showKeys': '显示主密钥',
|
||
'cloudSync.changeKey.updatedToast': '主密钥已更新',
|
||
'cloudSync.changeKey.updateButton': '更新主密钥',
|
||
'cloudSync.unlock.title': '输入主密钥',
|
||
'cloudSync.unlock.masterKey': '主密钥',
|
||
'cloudSync.unlock.desc': '仅需输入一次主密钥以启用加密同步,之后会通过系统 Keychain 安全存储。',
|
||
'cloudSync.unlock.placeholder': '输入你的主密钥',
|
||
'cloudSync.unlock.empty': '请输入主密钥',
|
||
'cloudSync.unlock.incorrect': '主密钥不正确',
|
||
'cloudSync.unlock.failed': '解锁 Vault 失败',
|
||
'cloudSync.unlock.showKey': '显示主密钥',
|
||
'cloudSync.unlock.notNow': '暂不',
|
||
'cloudSync.unlock.readyToast': 'Vault 已就绪',
|
||
'cloudSync.unlock.unlockButton': '解锁',
|
||
'cloudSync.header.vaultReady': 'Vault 已就绪',
|
||
'cloudSync.header.preparingVault': '正在准备 Vault...',
|
||
'cloudSync.header.providersConnected': '已连接 {count} 个 provider',
|
||
'cloudSync.githubFlow.title': '连接到 GitHub',
|
||
'cloudSync.githubFlow.desc': '复制下面的 code,并在 GitHub 页面输入以授权 Netcatty。',
|
||
'cloudSync.githubFlow.copyCode': '复制 code',
|
||
'cloudSync.githubFlow.copied': '已复制',
|
||
'cloudSync.githubFlow.openGitHub': '打开 GitHub',
|
||
'cloudSync.githubFlow.waiting': '等待授权...',
|
||
'cloudSync.conflict.title': '检测到版本冲突',
|
||
'cloudSync.conflict.desc': '选择保留哪个版本',
|
||
'cloudSync.conflict.local': '本地',
|
||
'cloudSync.conflict.cloud': '云端',
|
||
'cloudSync.conflict.detailsTitle': '发生变化的数据',
|
||
'cloudSync.conflict.detailsCounts': '本地 {local} · 云端 {cloud} · 冲突 {conflicts}',
|
||
'cloudSync.conflict.entity.hosts': '主机',
|
||
'cloudSync.conflict.entity.keys': '密钥',
|
||
'cloudSync.conflict.entity.identities': '身份',
|
||
'cloudSync.conflict.entity.proxyProfiles': '代理配置',
|
||
'cloudSync.conflict.entity.snippets': '片段',
|
||
'cloudSync.conflict.entity.customGroups': '分组',
|
||
'cloudSync.conflict.entity.snippetPackages': '片段包',
|
||
'cloudSync.conflict.entity.portForwardingRules': '端口转发',
|
||
'cloudSync.conflict.entity.groupConfigs': '分组设置',
|
||
'cloudSync.conflict.entity.settings': '设置',
|
||
'cloudSync.conflict.keepLocal': '覆盖云端(保留本地)',
|
||
'cloudSync.conflict.useCloud': '下载云端(覆盖本地)',
|
||
'cloudSync.connect.browserContinue': '请在浏览器中完成授权',
|
||
'cloudSync.connect.browserCancelled': '已取消上一个浏览器授权流程',
|
||
'cloudSync.connect.github.success': 'GitHub 已连接',
|
||
'cloudSync.connect.github.failedTitle': 'GitHub 连接失败',
|
||
'cloudSync.connect.github.timeout': '连接 GitHub 超时,请检查网络或代理设置。',
|
||
'cloudSync.connect.github.networkError': '无法访问 GitHub,请检查网络或代理设置。',
|
||
'cloudSync.connect.google.failedTitle': 'Google 连接失败',
|
||
'cloudSync.connect.onedrive.failedTitle': 'OneDrive 连接失败',
|
||
'cloudSync.sync.success': '已同步到 {provider}',
|
||
'cloudSync.sync.failed': '同步失败',
|
||
'cloudSync.sync.failedTitle': '同步失败',
|
||
'cloudSync.sync.errorTitle': '同步错误',
|
||
'cloudSync.resolve.downloaded': '已下载云端数据',
|
||
'cloudSync.resolve.uploaded': '已上传本地数据',
|
||
'cloudSync.resolve.failedTitle': '冲突处理失败',
|
||
'cloudSync.clearLocal.title': '清空本地数据',
|
||
'cloudSync.clearLocal.desc': '重置本地版本和同步历史。下次同步将从云端下载。',
|
||
'cloudSync.clearLocal.button': '清空',
|
||
'cloudSync.clearLocal.dialog.title': '清空本地 Vault 数据?',
|
||
'cloudSync.clearLocal.dialog.desc': '这将重置本地版本为 0 并清除同步历史。下次同步时会从云端下载数据,替换本地数据。',
|
||
'cloudSync.clearLocal.dialog.cancel': '取消',
|
||
'cloudSync.clearLocal.dialog.confirm': '确认清空',
|
||
'cloudSync.clearLocal.toast.title': '本地数据已清空',
|
||
'cloudSync.clearLocal.toast.desc': '本地版本已重置为 0。同步以从云端下载数据。',
|
||
|
||
// Common (additional)
|
||
'common.searchPlaceholder': '搜索...',
|
||
'common.import': '导入',
|
||
'common.generate': '生成',
|
||
'common.delete': '删除',
|
||
'common.edit': '编辑',
|
||
'sftp.context.openWithDefault': '系统默认程序打开',
|
||
'common.clear': '清除',
|
||
'common.optional': '可选',
|
||
'common.selectPlaceholder': '请选择...',
|
||
'common.error': '错误',
|
||
'common.validation': '验证',
|
||
'common.saveChanges': '保存修改',
|
||
'common.advanced': '高级',
|
||
'common.selectAHostPlaceholder': '选择主机...',
|
||
|
||
// Actions
|
||
'action.duplicate': '复制',
|
||
'action.open': '打开',
|
||
'action.copy': '复制',
|
||
'action.run': '运行',
|
||
'action.start': '启动',
|
||
'action.stop': '停止',
|
||
|
||
// Port Forwarding (form)
|
||
'pf.form.labelPlaceholder': '规则标签',
|
||
'pf.form.intermediateHost': '中转主机 *',
|
||
'pf.form.createRule': '创建规则',
|
||
'pf.form.openWizard': '打开向导',
|
||
'pf.form.openWizardTitle': '打开端口转发向导',
|
||
'pf.action.newForwarding': '新建转发',
|
||
'pf.view.grid': '网格',
|
||
'pf.view.list': '列表',
|
||
'pf.rule.summary.dynamic': 'SOCKS 监听于 {bindAddress}:{localPort}',
|
||
'pf.rule.summary.default': '{bindAddress}:{localPort} -> {remoteHost}:{remotePort}',
|
||
'pf.tooltip.relayHost': '中转主机',
|
||
'pf.tooltip.hostLabel': '主机',
|
||
'pf.tooltip.hostAddress': '地址',
|
||
'pf.tooltip.noHost': '未配置中转主机',
|
||
'pf.tooltip.localDesc': '本地端口转发:通过 SSH 隧道访问远程服务',
|
||
'pf.tooltip.remoteDesc': '远程端口转发:将本地服务暴露给远程主机',
|
||
'pf.tooltip.dynamicDesc': '动态 SOCKS 代理:通过 SSH 隧道转发流量',
|
||
'pf.deleteActive.title': '删除正在运行的端口转发?',
|
||
'pf.deleteActive.desc': '端口转发规则 "{label}" 当前正在运行。删除前将先关闭转发连接。',
|
||
'pf.deleteActive.confirm': '关闭并删除',
|
||
'pf.form.autoStart': '自动启动',
|
||
'pf.form.autoStartDesc': '应用启动时自动开启此规则',
|
||
|
||
// SFTP (pane + conflict)
|
||
'sftp.pane.local': '本地',
|
||
'sftp.pane.remote': '远端',
|
||
'sftp.pane.selectHost': '选择主机',
|
||
'sftp.pane.selectHostToStart': '先选择一个主机',
|
||
'sftp.pane.chooseFilesystem': '选择要浏览的本地或远端文件系统',
|
||
'sftp.tabs.addTab': '新建标签页',
|
||
'sftp.tabs.closeTab': '关闭标签页',
|
||
'sftp.tabs.newTab': '新标签页',
|
||
'sftp.tabs.copyDefaultPath': '复制标签页(默认路径)',
|
||
'sftp.tabs.copyCurrentPath': '复制并跳转到当前路径',
|
||
'sftp.conflict.title': '文件冲突',
|
||
'sftp.conflict.desc': '目标位置已存在同名文件',
|
||
'sftp.conflict.alreadyExistsSuffix': '已存在',
|
||
'sftp.conflict.existingFile': '已有文件',
|
||
'sftp.conflict.newFile': '新文件',
|
||
'sftp.conflict.size': '大小:',
|
||
'sftp.conflict.modified': '修改时间:',
|
||
'sftp.conflict.applyToAll': '将此操作应用到剩余的 {count} 个冲突',
|
||
'sftp.conflict.action.stop': '停止',
|
||
'sftp.conflict.action.skip': '跳过',
|
||
'sftp.conflict.action.keepBoth': '保留两者',
|
||
'sftp.conflict.action.duplicate': '创建副本',
|
||
'sftp.conflict.action.merge': '合并',
|
||
'sftp.conflict.action.replace': '替换',
|
||
|
||
// SFTP Upload Phases
|
||
'sftp.upload.phase.compressing': '正在压缩',
|
||
'sftp.upload.phase.uploading': '正在上传',
|
||
'sftp.upload.phase.extracting': '正在解压',
|
||
'sftp.upload.phase.compressed': '压缩传输',
|
||
|
||
};
|