feat: multi-language interface (zh-CN/zh-TW/en/ja), multilingual offline changelog, settings robustness
i18n - shared/i18n: dependency-free t() with flat per-namespace dictionaries (common/settings/workspace/terminal/ssh/panels/main), zh-CN fallback - language picker in Settings -> System; antd ConfigProvider locale follows it - main process tracks the language too: tray menu, close prompt, ssh/sftp/ zmodem errors and the log TUI marker are translated; tray rebuilds on change changelog - CHANGELOG.md (zh-CN canonical) + .zh-TW/.en/.ja, bundled via ?raw and read per interface language with per-version fallback to zh-CN (no network) - sync-changelog.cjs merges RELEASE_NOTES[.<lang>].md per release; release.cjs refuses to publish without a zh-CN entry for the version settings robustness - closeAction 'ask' survives the sanitizer (was silently coerced to 'tray', which made the 'ask every time' option dead) - highlight rules are repaired instead of dropped: string priority, 0/1 enabled, missing fg colour; unknown fields preserved - load-time warnings are written to settings-warnings.log (deduped, capped) terminal/UI - configurable terminal toolbar: open working directory (default on), session log recording (off), open logs folder (off) - global shortcut field records key combos (modifier or F-key required) - input suggestions + command history default to off, with a one-time reset migration for existing installs - settings dialog scrolling fixed (antd v6 renamed the tabs container), theme gallery nested scrollbar removed, joined segmented pickers with readable selected-state text tests: settings-store.mjs (15 checks) added; commands-store.mjs updated for the new off-by-default history setting
This commit is contained in:
1 parent
34094d607b
commit
4c6a29ef28
82 files changed
+3342
-608
No files matched your search
@@ -0,0 +1,17 @@
|
||||
/** Namespace: common (i18n plumbing, generic buttons/status). Owner: i18n infrastructure. */
|
||||
const common: Record<string, string> = {
|
||||
'common.ok': 'OK',
|
||||
'common.cancel': 'Cancel',
|
||||
'common.close': 'Close',
|
||||
'common.save': 'Save',
|
||||
'common.delete': 'Delete',
|
||||
'common.edit': 'Edit',
|
||||
'common.add': 'Add',
|
||||
'common.copy': 'Copy',
|
||||
'common.paste': 'Paste',
|
||||
'common.reset': 'Reset to defaults',
|
||||
'common.language': 'Language',
|
||||
'common.languageDesc': 'Switches the interface language immediately; saved permanently.'
|
||||
}
|
||||
|
||||
export default common
|
||||
@@ -0,0 +1,19 @@
|
||||
import common from './common'
|
||||
import settings from './settings'
|
||||
import workspace from './workspace'
|
||||
import terminal from './terminal'
|
||||
import ssh from './ssh'
|
||||
import panels from './panels'
|
||||
import main from './main'
|
||||
|
||||
/** English entries. Namespace files are owned per area — see the ownership map
|
||||
* in src/shared/i18n/index.ts. */
|
||||
export default {
|
||||
...common,
|
||||
...settings,
|
||||
...workspace,
|
||||
...terminal,
|
||||
...ssh,
|
||||
...panels,
|
||||
...main
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/** Namespace: main (main-process strings: tray, close prompt, updater). Owner: main process. */
|
||||
const main: Record<string, string> = {
|
||||
'main.tray.showWindow': 'Show main window',
|
||||
'main.tray.closeAction': 'Close button action',
|
||||
'main.tray.askEveryTime': 'Ask every time',
|
||||
'main.tray.minimizeToTray': 'Minimize to tray',
|
||||
'main.tray.exitDirectly': 'Exit directly',
|
||||
'main.tray.exit': 'Exit',
|
||||
'main.tray.balloonTitle': 'Minimized to tray',
|
||||
'main.tray.balloonContent': 'Terminal sessions keep running in the background. Click the tray icon to restore the window.',
|
||||
'main.tray.closeTitle': 'Close OpenTerminal',
|
||||
'main.tray.closeMessage': 'Minimize to tray, or exit now?',
|
||||
'main.tray.closeDetail': 'Minimizing to tray keeps your terminal sessions running.',
|
||||
'main.tray.rememberChoice': 'Remember my choice, never ask again',
|
||||
|
||||
'main.updater.feedFailed': 'Domestic feed: {gitea}; GitHub: {github}',
|
||||
|
||||
'main.ssh.connectTimeout': 'Connection timed out ({host}:{port})',
|
||||
'main.ssh.saveFingerprintFailed': 'Failed to save the host fingerprint: {detail}',
|
||||
'main.ssh.hostKeyRejected': 'The user rejected the host key',
|
||||
'main.ssh.connectFailed': 'Connection failed {host}:{port}: {detail}',
|
||||
'main.ssh.shellOpenFailed': 'Could not open the SSH shell ({host}:{port}): {detail}',
|
||||
'main.ssh.initFailed': 'SSH connection initialization failed ({host}:{port}): {detail}',
|
||||
'main.ssh.readKeyFailed': 'Could not read the private key file {path}: {detail}',
|
||||
|
||||
'main.sftp.sessionGone': 'The SSH session does not exist or has disconnected',
|
||||
'main.sftp.deleteFailed': 'Delete failed: {detail}',
|
||||
'main.sftp.invalidMode': 'Invalid permission value: {mode}',
|
||||
'main.sftp.invalidUidGid': 'Invalid uid/gid',
|
||||
'main.sftp.commandExitCode': 'Command exited with code {code}',
|
||||
'main.sftp.cancelled': 'Cancelled',
|
||||
|
||||
'main.zmodem.transferFailed': 'Transfer failed',
|
||||
'main.zmodem.transferTimeout': 'Transfer timed out',
|
||||
'main.zmodem.sendFailed': 'Sending failed',
|
||||
'main.zmodem.uploadFailed': 'Upload failed',
|
||||
'main.zmodem.receiveFailed': 'Receiving failed',
|
||||
'main.zmodem.abnormal': 'ZMODEM transfer error',
|
||||
'main.zmodem.cancelled': 'Cancelled',
|
||||
'main.zmodem.offerTimedOut': 'No files selected, cancelled',
|
||||
'main.zmodem.sessionInvalid': 'The session is no longer valid',
|
||||
'main.zmodem.sessionCreateFailed': 'Could not establish the ZMODEM session',
|
||||
'main.zmodem.noSaveDir': 'No save directory specified',
|
||||
'main.zmodem.noFiles': 'No files selected',
|
||||
|
||||
'main.ipc.connectionMissing': 'Connection bookmark not found ({id})',
|
||||
|
||||
'main.sysinfo.sessionGone': 'SSH session is missing or disconnected',
|
||||
'main.sysinfo.execFailed': 'SSH exec failed',
|
||||
'main.sysinfo.parseFailed': 'Parse failed: {message}',
|
||||
'main.pty.serviceNotReady': 'SSH session service is not initialised yet',
|
||||
'main.pty.missingConnectionId': 'SSH session is missing its connectionId',
|
||||
'main.log.tuiOmitted': 'full-screen (TUI) output omitted'
|
||||
}
|
||||
|
||||
export default main
|
||||
@@ -0,0 +1,36 @@
|
||||
/** Namespace: panels (command panel, session-log panel, transfer panel). Owner: panels area. */
|
||||
const panels: Record<string, string> = {
|
||||
// Command panel
|
||||
'panels.commands.sectionTitle': 'Commands',
|
||||
'panels.commands.target': 'Send to',
|
||||
'panels.commands.targetSsh': 'SSH server',
|
||||
'panels.commands.targetTerminal': 'Terminal',
|
||||
'panels.commands.tabHistory': 'History',
|
||||
'panels.commands.tabLibrary': 'Library',
|
||||
'panels.commands.historyTitle': 'Command history',
|
||||
'panels.commands.clearTitle': 'Clear all command history?',
|
||||
'panels.commands.clear': 'Clear',
|
||||
'panels.commands.noHistory': 'No command history',
|
||||
'panels.commands.loading': 'Loading…',
|
||||
'panels.commands.libraryTitle': 'Command library',
|
||||
'panels.commands.libraryEmpty': 'The command library is empty',
|
||||
'panels.commands.add': 'Add command',
|
||||
'panels.commands.name': 'Name',
|
||||
'panels.commands.optional': '(optional)',
|
||||
'panels.commands.command': 'Command',
|
||||
'panels.commands.commandPlaceholder': 'e.g. ls -la',
|
||||
'panels.commands.note': 'Note',
|
||||
'panels.commands.deleteTitle': 'Delete this command?',
|
||||
'panels.commands.deleteAria': 'Delete command',
|
||||
|
||||
// Transfer panel
|
||||
'panels.transfer.failed': 'Transfer failed',
|
||||
'panels.transfer.cancelled': 'Cancelled',
|
||||
'panels.transfer.done': 'Transfer complete',
|
||||
'panels.transfer.uploading': 'Uploading',
|
||||
'panels.transfer.downloading': 'Downloading',
|
||||
'panels.transfer.zmodemUploading': 'ZMODEM uploading',
|
||||
'panels.transfer.zmodemDownloading': 'ZMODEM downloading'
|
||||
}
|
||||
|
||||
export default panels
|
||||
@@ -0,0 +1,153 @@
|
||||
/** Namespace: settings (the settings dialog: font/cursor/render/highlight/theme/system/about). Owner: settings page. */
|
||||
const settings: Record<string, string> = {
|
||||
'settings.title': 'Settings',
|
||||
'settings.tabs.font': 'Font',
|
||||
'settings.tabs.cursor': 'Cursor & Scrollback',
|
||||
'settings.tabs.render': 'Rendering & Behavior',
|
||||
'settings.tabs.highlight': 'Highlighting',
|
||||
'settings.tabs.theme': 'Themes',
|
||||
'settings.tabs.system': 'System',
|
||||
'settings.tabs.about': 'About',
|
||||
'settings.resizeHandle': 'Drag to resize',
|
||||
'settings.preview': 'Preview',
|
||||
'settings.deleteConfirmDesc': 'This cannot be undone. Continue?',
|
||||
'settings.color.foreground': 'Foreground',
|
||||
'settings.color.background': 'Background',
|
||||
'settings.color.cursor': 'Cursor',
|
||||
'settings.color.selection': 'Selection',
|
||||
'settings.font.label': 'Font',
|
||||
'settings.font.desc': 'The built-in default or a system monospace font',
|
||||
'settings.font.placeholder': 'Select a font',
|
||||
'settings.font.default': 'Default',
|
||||
'settings.font.size': 'Font size',
|
||||
'settings.font.sizeDesc': 'Pixel size of the terminal text',
|
||||
'settings.font.weight': 'Weight',
|
||||
'settings.font.weightDesc': '400 is regular, 700 is bold',
|
||||
'settings.font.boldWeight': 'Bold weight',
|
||||
'settings.font.boldWeightDesc': 'Weight used for bold text',
|
||||
'settings.font.letterSpacing': 'Letter spacing',
|
||||
'settings.font.letterSpacingDesc': 'Horizontal distance between characters',
|
||||
'settings.font.lineHeight': 'Line height',
|
||||
'settings.font.lineHeightDesc': 'Vertical distance between adjacent lines',
|
||||
'settings.cursor.blink': 'Blinking cursor',
|
||||
'settings.cursor.blinkDesc': 'Whether the cursor blinks periodically',
|
||||
'settings.cursor.style': 'Cursor style',
|
||||
'settings.cursor.styleDesc': 'Shape used to draw the cursor',
|
||||
'settings.cursor.inactiveStyle': 'Inactive cursor style',
|
||||
'settings.cursor.inactiveStyleDesc': 'Cursor style while the window is unfocused',
|
||||
'settings.cursor.scrollback': 'Scrollback buffer',
|
||||
'settings.cursor.scrollbackDesc': 'How many lines you can scroll back',
|
||||
'settings.cursorStyle.bar': 'Bar',
|
||||
'settings.cursorStyle.block': 'Block',
|
||||
'settings.cursorStyle.underline': 'Underline',
|
||||
'settings.cursorStyle.outline': 'Outline',
|
||||
'settings.cursorStyle.none': 'None',
|
||||
'settings.rendererMode.auto': 'Automatic',
|
||||
'settings.rendererMode.autoHint': 'Prefer WebGL acceleration, falling back to DOM rendering if it fails',
|
||||
'settings.rendererMode.webgl': 'High-performance WebGL',
|
||||
'settings.rendererMode.webglHint':
|
||||
'Force GPU-accelerated rendering; best for high refresh rates and heavy scrolling',
|
||||
'settings.rendererMode.dom': 'Compatible DOM',
|
||||
'settings.rendererMode.domHint':
|
||||
'Pure CPU rendering with the widest compatibility; best without a GPU or over remote desktop',
|
||||
'settings.render.modeLabel': 'Renderer',
|
||||
'settings.render.modeHint': 'How terminal cells are accelerated; applies to every terminal',
|
||||
'settings.render.autoWrap': 'Auto wrap',
|
||||
'settings.render.autoWrapDesc': 'Wrap lines that exceed the width',
|
||||
'settings.render.copyOnSelect': 'Copy on select',
|
||||
'settings.render.copyOnSelectDesc': 'Copy text automatically when you select it with the mouse',
|
||||
'settings.render.pasteRiskConfirm': 'Confirm risky paste',
|
||||
'settings.render.pasteRiskConfirmDesc':
|
||||
'Ask before pasting multi-line text (or a very long single line); single lines paste directly',
|
||||
'settings.render.suggest': 'Input suggestions',
|
||||
'settings.render.suggestDesc':
|
||||
'Show command suggestions while typing; Tab accepts, Enter always runs the command right away',
|
||||
'settings.render.history': 'Record command history',
|
||||
'settings.render.historyDesc': 'When off, new commands are no longer recorded; saved history is kept',
|
||||
'settings.render.historyLimit': 'History limit',
|
||||
'settings.render.historyLimitDesc': 'Most commands to keep; duplicates are stored only once',
|
||||
'settings.render.recButton': 'Terminal toolbar · Record',
|
||||
'settings.render.recButtonDesc': 'Show the "Record session log" button in the top-right corner',
|
||||
'settings.render.openLogsButton': 'Terminal toolbar · Open log folder',
|
||||
'settings.render.openLogsButtonDesc': 'Show the "Open log folder" button in the top-right corner',
|
||||
'settings.render.openCwdButton': 'Terminal toolbar · Open workspace folder',
|
||||
'settings.render.openCwdButtonDesc':
|
||||
'Show the "Open current folder" button in the top-right corner (hidden in SSH sessions; the folder follows cd in real time and needs shell integration or the cd command)',
|
||||
'settings.system.launchAtLogin': 'Launch at startup',
|
||||
'settings.system.launchAtLoginDesc':
|
||||
'Start OpenTerminal when the system boots (in development mode the dev build is registered)',
|
||||
'settings.system.preventSleep': 'Prevent system sleep',
|
||||
'settings.system.preventSleepDesc':
|
||||
'While on, OpenTerminal keeps the system from sleeping automatically; when off, the system follows its own power settings',
|
||||
'settings.system.restoreSession': 'Restore last session on startup',
|
||||
'settings.system.restoreSessionDesc':
|
||||
'Restore the split layout on the next launch and return each terminal to its last directory; when off, OpenTerminal always starts with a single terminal',
|
||||
'settings.system.shellIntegration': 'Shell integration',
|
||||
'settings.system.shellIntegrationDesc':
|
||||
'Let the shell report its working directory (OSC 7) for more precise path tracking, including cd inside scripts; it wraps your prompt, so turn it off if the prompt theme looks wrong',
|
||||
'settings.system.closeAction': 'Close button behavior',
|
||||
'settings.system.closeActionDesc':
|
||||
'What happens when you click the window close button; after minimizing to the tray you can quit from the tray icon context menu',
|
||||
'settings.system.closeActionTray': 'Minimize to tray',
|
||||
'settings.system.closeActionExit': 'Quit directly',
|
||||
'settings.system.closeActionAsk': 'Ask every time',
|
||||
'settings.system.globalShortcut': 'Global show/hide shortcut',
|
||||
'settings.system.globalShortcutDesc':
|
||||
'Click the field, then press the key combination; Esc cancels, Backspace clears and disables it',
|
||||
'settings.system.globalShortcutHint':
|
||||
'Together with the global key this shows or hides the window from anywhere; if registration fails (a conflict with another app) it simply has no effect and the app reports no error.',
|
||||
'settings.system.shortcutRecording': 'Press the keys…',
|
||||
'settings.system.shortcutPlaceholder': 'Click and press a shortcut, leave empty to disable',
|
||||
'settings.highlight.alert':
|
||||
'Custom highlighting improves readability at a small performance cost. Rules are applied in priority order. PS: colors are injected as text is written to the terminal, so existing scrollback is unaffected',
|
||||
'settings.highlight.enabled': 'Enabled',
|
||||
'settings.highlight.pattern': 'Pattern',
|
||||
'settings.highlight.patternPlaceholder': 'e.g. \\b(ERROR|FAILED)\\b',
|
||||
'settings.highlight.invalidRegex': 'Invalid regular expression',
|
||||
'settings.highlight.priority': 'Priority',
|
||||
'settings.highlight.priorityHint': 'Lower values apply first',
|
||||
'settings.highlight.color': 'Color',
|
||||
'settings.highlight.clearBg': 'Clear',
|
||||
'settings.highlight.addBg': 'Add',
|
||||
'settings.highlight.palette': 'Palette',
|
||||
'settings.highlight.note': 'Note',
|
||||
'settings.highlight.notePlaceholder': 'Rule description (optional)',
|
||||
'settings.highlight.actions': 'Actions',
|
||||
'settings.highlight.addRule': '+ Add rule',
|
||||
'settings.highlight.empty': 'No highlight rules yet — click "+ Add rule" to create one',
|
||||
'settings.highlight.deleteTitle': 'Delete highlight rule',
|
||||
'settings.highlight.resetTitle': 'Restore default highlight rules',
|
||||
'settings.highlight.resetDesc': 'Replaces every current rule with the built-in presets. This cannot be undone.',
|
||||
'settings.highlight.resetOk': 'Restore',
|
||||
'settings.highlight.createTitle': 'New highlight rule',
|
||||
'settings.highlight.editTitle': 'Edit highlight rule',
|
||||
'settings.theme.accent': 'Tab accent color',
|
||||
'settings.theme.accentDesc': 'Accent color for the active tab border, the sidebar indicator, and SSH badges',
|
||||
'settings.theme.customBadge': 'Custom',
|
||||
'settings.theme.deleteTitle': 'Delete custom theme',
|
||||
'settings.theme.create': 'New theme',
|
||||
'settings.theme.editTitle': 'Edit theme',
|
||||
'settings.themeEditor.name': 'Name',
|
||||
'settings.themeEditor.namePlaceholder': 'Theme name',
|
||||
'settings.themeEditor.copySuffix': ' (copy)',
|
||||
'settings.about.currentVersion': 'Current version',
|
||||
'settings.about.statusIdle': 'Click to check for updates',
|
||||
'settings.about.statusChecking': 'Checking for updates…',
|
||||
'settings.about.statusAvailable': 'A new version is available',
|
||||
'settings.about.statusLatest': 'Already up to date',
|
||||
'settings.about.statusDownloading': 'Downloading…',
|
||||
'settings.about.statusDownloaded': 'Download complete — restart to install',
|
||||
'settings.about.statusError': 'Check failed',
|
||||
'settings.about.statusDev': 'Update checks are unavailable in development mode',
|
||||
'settings.about.channelStable': 'Stable channel',
|
||||
'settings.about.autoCheck': 'Check automatically at startup',
|
||||
'settings.about.download': 'Download update',
|
||||
'settings.about.downloadGithub': ' (GitHub source)',
|
||||
'settings.about.install': 'Restart and install',
|
||||
'settings.about.check': 'Check for updates',
|
||||
'settings.about.checkingButton': 'Checking',
|
||||
'settings.about.changelog': 'Changelog',
|
||||
'settings.about.changelogEmpty': 'No changelog available'
|
||||
}
|
||||
|
||||
export default settings
|
||||
@@ -0,0 +1,150 @@
|
||||
/** Namespace: ssh (ssh connections, host key prompt, file panel, zmodem, monitor). Owner: ssh area. */
|
||||
const ssh: Record<string, string> = {
|
||||
// Auth method / secret kind
|
||||
'ssh.auth.password': 'Password',
|
||||
'ssh.auth.privateKey': 'Private key',
|
||||
'ssh.auth.agent': 'Agent',
|
||||
'ssh.secret.passphrase': 'Passphrase',
|
||||
|
||||
// Connection dialog: auth fields
|
||||
'ssh.fields.agentDesc':
|
||||
'Authenticate with a key already loaded in the local SSH Agent; this app stores nothing for you.',
|
||||
'ssh.fields.askPasswordLabel': 'Ask for password on connect',
|
||||
'ssh.fields.askPasswordHint':
|
||||
'Prompts for the password on every connection instead of using the saved one',
|
||||
'ssh.fields.passwordPlaceholder': 'Leave empty to keep the saved password',
|
||||
'ssh.fields.keyPath': 'Private key path (path on the server, optional)',
|
||||
'ssh.fields.keyContent': 'Private key content',
|
||||
'ssh.fields.keyContentPlaceholder':
|
||||
'Paste the private key; leave empty to use the path above (leave empty while editing to keep the saved key)',
|
||||
'ssh.fields.askPassphraseLabel': 'Ask for passphrase on connect',
|
||||
'ssh.fields.askPassphraseHint': 'Prompts for the key passphrase on every connection',
|
||||
'ssh.fields.passphrase': 'Key passphrase',
|
||||
'ssh.fields.passphrasePlaceholder': 'Leave empty to keep the saved passphrase',
|
||||
|
||||
// Connection dialog
|
||||
'ssh.dialog.titleEdit': 'Edit connection',
|
||||
'ssh.dialog.titleNew': 'New connection',
|
||||
'ssh.dialog.saveFailed': 'Save failed. Check your input and try again.',
|
||||
'ssh.dialog.name': 'Name',
|
||||
'ssh.dialog.nameRequired': 'Please enter a connection name',
|
||||
'ssh.dialog.namePlaceholder': 'e.g. Production server',
|
||||
'ssh.dialog.group': 'Group',
|
||||
'ssh.dialog.groupPlaceholder': 'Pick or type a new group; leave empty for “Default”',
|
||||
'ssh.dialog.host': 'Host',
|
||||
'ssh.dialog.hostRequired': 'Please enter a host address',
|
||||
'ssh.dialog.hostPlaceholder': '192.168.1.10 or example.com',
|
||||
'ssh.dialog.port': 'Port',
|
||||
'ssh.dialog.portRange': 'Port must be between 1 and 65535',
|
||||
'ssh.dialog.username': 'Username',
|
||||
'ssh.dialog.usernameRequired': 'Please enter a username',
|
||||
'ssh.dialog.authMethod': 'Authentication',
|
||||
'ssh.dialog.savedSecret': 'A {kind} is saved; leave empty to keep it',
|
||||
'ssh.dialog.keepalive': 'Keepalive interval (seconds)',
|
||||
'ssh.dialog.keepaliveTooltip': '0 disables keepalive',
|
||||
'ssh.dialog.keepaliveMin': 'Cannot be negative',
|
||||
|
||||
// Connection sidebar
|
||||
'ssh.sidebar.defaultGroup': 'Default',
|
||||
'ssh.sidebar.timeJustNow': 'just now',
|
||||
'ssh.sidebar.timeMinutesAgo': '{n} min ago',
|
||||
'ssh.sidebar.timeHoursAgo': '{n} h ago',
|
||||
'ssh.sidebar.timeDaysAgo': '{n} d ago',
|
||||
'ssh.sidebar.modeTerminal': 'Terminal workspace',
|
||||
'ssh.sidebar.modeSsh': 'SSH workspace',
|
||||
'ssh.sidebar.title': 'Connections',
|
||||
'ssh.sidebar.newConnection': 'New connection',
|
||||
'ssh.sidebar.sectionTerminals': 'Terminals',
|
||||
'ssh.sidebar.noLocalTerminals': 'No local terminal open',
|
||||
'ssh.sidebar.local': 'Local',
|
||||
'ssh.sidebar.sectionServers': 'SSH servers',
|
||||
'ssh.sidebar.empty': 'No connections yet — click + to create one',
|
||||
'ssh.sidebar.loading': 'Loading…',
|
||||
'ssh.sidebar.recent': 'Recent sessions',
|
||||
'ssh.sidebar.dblClickConnect': 'Double-click to connect to {host}',
|
||||
'ssh.sidebar.deleteTitle': 'Delete this connection?',
|
||||
'ssh.sidebar.deleteDesc':
|
||||
'A deleted connection cannot be restored. Its saved key material is removed as well.',
|
||||
|
||||
// Host key verification
|
||||
'ssh.hostKey.changedTitle': 'Host fingerprint changed!',
|
||||
'ssh.hostKey.unknownHost': 'Unknown host',
|
||||
'ssh.hostKey.accept': 'Accept and connect',
|
||||
'ssh.hostKey.reject': 'Reject',
|
||||
'ssh.hostKey.mitmTitle': 'Possible man-in-the-middle attack',
|
||||
'ssh.hostKey.mitmDesc':
|
||||
'The remote host key fingerprint differs from the one recorded earlier. Unless you changed the server key yourself, someone may be impersonating this host.',
|
||||
'ssh.hostKey.firstConnect':
|
||||
'First connection to this host; its fingerprint has not been recorded yet.',
|
||||
'ssh.hostKey.target': 'Host: {target}',
|
||||
'ssh.hostKey.fingerprint': 'Fingerprint: {fingerprint}',
|
||||
|
||||
// SSH workspace: file panel container, host badge
|
||||
'ssh.bottomPanel.resize': 'Resize the file panel',
|
||||
'ssh.hostBadge.aria': 'SSH host {label}',
|
||||
|
||||
// ZMODEM
|
||||
'ssh.zmodem.done': 'ZMODEM transfer complete',
|
||||
'ssh.zmodem.failed': 'ZMODEM transfer failed: {message}',
|
||||
'ssh.zmodem.unknownError': 'unknown error',
|
||||
'ssh.zmodem.titleReceive': 'Download to local',
|
||||
'ssh.zmodem.titleSend': 'Upload to server',
|
||||
'ssh.zmodem.pickDir': 'Choose save folder',
|
||||
'ssh.zmodem.pickFiles': 'Choose files',
|
||||
'ssh.zmodem.receiveDesc':
|
||||
'An sz download request was detected (the remote side is sending files). Choose the local folder to save them in.',
|
||||
'ssh.zmodem.sendDesc':
|
||||
'An rz upload request was detected (the remote side is receiving files). Choose the files to upload.',
|
||||
|
||||
// File panel (SFTP)
|
||||
'ssh.file.up': 'Parent folder',
|
||||
'ssh.file.refresh': 'Refresh',
|
||||
'ssh.file.uploadFile': 'Upload files',
|
||||
'ssh.file.downloadSelected': 'Download selection',
|
||||
'ssh.file.permOwner': 'Permissions / owner',
|
||||
'ssh.file.open': 'Open',
|
||||
'ssh.file.download': 'Download',
|
||||
'ssh.file.upload': 'Upload…',
|
||||
'ssh.file.rename': 'Rename',
|
||||
'ssh.file.new': 'New',
|
||||
'ssh.file.newFolder': 'New folder',
|
||||
'ssh.file.copyPath': 'Copy path',
|
||||
'ssh.file.copyPathFailed': 'Failed to copy the path',
|
||||
'ssh.file.pathCopied': 'Path copied',
|
||||
'ssh.file.permission': 'Permissions…',
|
||||
'ssh.file.deleteTitle': 'Delete?',
|
||||
'ssh.file.loading': 'Loading…',
|
||||
'ssh.file.empty': 'Empty folder',
|
||||
'ssh.file.modeUnavailable': 'Permissions unavailable',
|
||||
'ssh.file.folderName': 'Folder name',
|
||||
'ssh.file.create': 'Create',
|
||||
'ssh.file.renameTitle': 'Rename {name}',
|
||||
'ssh.file.permTitle': 'Permissions · {name}',
|
||||
'ssh.file.permApplied': 'Permissions applied',
|
||||
'ssh.file.octal': 'Octal',
|
||||
'ssh.file.octalPlaceholder': 'e.g. 755',
|
||||
'ssh.file.keepEmpty': 'Leave empty to keep',
|
||||
'ssh.file.ownerHint': 'Leave UID/GID empty to keep the current owner',
|
||||
'ssh.file.permRowOwner': 'Owner',
|
||||
'ssh.file.permRowGroup': 'Group',
|
||||
'ssh.file.permRowOther': 'Other',
|
||||
'ssh.file.permColRead': 'Read',
|
||||
'ssh.file.permColWrite': 'Write',
|
||||
'ssh.file.permColExec': 'Execute',
|
||||
|
||||
// System monitor
|
||||
'ssh.monitor.collecting': 'Collecting…',
|
||||
'ssh.monitor.interrupted': 'Sampling stopped: {error}',
|
||||
'ssh.monitor.mem': 'Memory',
|
||||
'ssh.monitor.disks': 'Disks',
|
||||
'ssh.monitor.net': 'Network',
|
||||
'ssh.monitor.cores': '{n} cores',
|
||||
'ssh.monitor.loadavg': 'Load {value}',
|
||||
'ssh.monitor.uptime': 'Uptime',
|
||||
'ssh.monitor.uptimeSeconds': '{n}s',
|
||||
'ssh.monitor.uptimeMinutes': '{n} min',
|
||||
'ssh.monitor.uptimeHours': '{h} h {m} min',
|
||||
'ssh.monitor.uptimeDays': '{n} d'
|
||||
}
|
||||
|
||||
export default ssh
|
||||
@@ -0,0 +1,27 @@
|
||||
/** Namespace: terminal (terminal view: context menu, search, paste confirm, toolbar, hints). Owner: workspace/terminal. */
|
||||
const terminal: Record<string, string> = {
|
||||
'terminal.menu.find': 'Find',
|
||||
'terminal.menu.selectAll': 'Select all',
|
||||
'terminal.menu.clear': 'Clear',
|
||||
'terminal.search.placeholder': 'Search',
|
||||
'terminal.search.prev': 'Previous',
|
||||
'terminal.search.next': 'Next',
|
||||
'terminal.search.found': 'Found',
|
||||
'terminal.search.notFound': 'Not found',
|
||||
'terminal.suggest.hint': '↑/↓ select · Tab accept · Esc close',
|
||||
'terminal.rec.start': 'Start recording',
|
||||
'terminal.rec.stop': 'Stop recording',
|
||||
'terminal.rec.startLog': 'Start session log',
|
||||
'terminal.rec.stopLog': 'Stop session log',
|
||||
'terminal.rec.openLogs': 'Open logs folder',
|
||||
'terminal.rec.openCwd': 'Open working directory',
|
||||
'terminal.paste.title': 'Confirm paste',
|
||||
'terminal.paste.message': 'Multi-line or potentially risky input detected. Paste it into the terminal?',
|
||||
'terminal.paste.noPrompt': "Don't ask again this session",
|
||||
'terminal.paste.disableDetection': 'Disable paste detection from now on',
|
||||
'terminal.paste.hint':
|
||||
'You can turn it back on or change the detection policy in the general terminal settings.',
|
||||
'terminal.dead.message': 'Process exited (code {code})'
|
||||
}
|
||||
|
||||
export default terminal
|
||||
@@ -0,0 +1,61 @@
|
||||
/** Namespace: workspace (workspace shell: sidebar, tabs, layout menu, split, empty states). Owner: workspace. */
|
||||
const workspace: Record<string, string> = {
|
||||
'workspace.tab.terminalTitle': 'Terminal {n}',
|
||||
'workspace.tab.localTerminal': 'Local terminal',
|
||||
'workspace.tab.closeOthers': 'Close others',
|
||||
'workspace.tab.closeRight': 'Close to the right',
|
||||
'workspace.tab.broadcastTarget': 'Broadcast target',
|
||||
'workspace.tab.broadcastBadge': 'B',
|
||||
'workspace.tab.addInSplit': 'New terminal in this split',
|
||||
'workspace.newTerminal': 'New terminal',
|
||||
'workspace.empty.terminalTitle': 'No terminals',
|
||||
'workspace.empty.sshTitle': 'No SSH sessions',
|
||||
'workspace.empty.sshHint': 'Connect from the server list on the left',
|
||||
'workspace.rail.hideSidebar': 'Collapse sidebar',
|
||||
'workspace.rail.showSidebar': 'Expand sidebar',
|
||||
'workspace.rail.layout': 'Layout',
|
||||
'workspace.rail.settings': 'Settings',
|
||||
'workspace.rail.connecting': 'Connecting…',
|
||||
'workspace.rail.terminalWorkspace': 'Terminal workspace',
|
||||
'workspace.rail.sshWorkspace': 'SSH workspace',
|
||||
'workspace.panel.hideSidebar': 'Collapse sidebar',
|
||||
'workspace.panel.showSidebar': 'Expand sidebar',
|
||||
'workspace.layout.splitRight': 'Split horizontally',
|
||||
'workspace.layout.splitBelow': 'Split vertically',
|
||||
'workspace.layout.saveTemplate': 'Save as template',
|
||||
'workspace.layout.applyTemplate': 'Apply template',
|
||||
'workspace.template.saveTitle': 'Save layout template',
|
||||
'workspace.template.namePlaceholder': 'Template name',
|
||||
'workspace.template.applyTitle': 'Apply layout template',
|
||||
'workspace.template.empty': 'No saved templates',
|
||||
'workspace.template.apply': 'Apply',
|
||||
'workspace.template.deleteConfirm': 'Delete this template?',
|
||||
'workspace.broadcast.toggle': 'Broadcast input',
|
||||
'workspace.broadcast.activeTitle': 'Broadcasting ({count} targets)',
|
||||
'workspace.broadcast.popoverTerminal': 'Broadcast input (Terminal)',
|
||||
'workspace.broadcast.popoverSsh': 'Broadcast input (SSH)',
|
||||
'workspace.broadcast.switch': 'Broadcast switch',
|
||||
'workspace.broadcast.enabled': 'Enabled ({count})',
|
||||
'workspace.broadcast.needTwo': 'Select at least 2 targets',
|
||||
'workspace.broadcast.disabled': 'Disabled',
|
||||
'workspace.broadcast.emptySsh': 'No SSH server sessions',
|
||||
'workspace.broadcast.emptyTerminal': 'No terminals',
|
||||
'workspace.broadcast.hint':
|
||||
'Broadcasting turns on automatically once 2 or more terminals are picked, and turns off once fewer than 2 remain. Only sessions in the current mode can be picked.',
|
||||
'workspace.hint.sshFromList': 'Connect SSH sessions from the server list',
|
||||
'workspace.hint.connectSshFirst': 'Connect to an SSH server first',
|
||||
'workspace.hint.noActiveTerminal': 'No active terminal — open at least one local terminal or SSH session',
|
||||
'workspace.hint.noSessionInPanel': 'The active pane has no session available',
|
||||
'workspace.connect.failed': 'SSH connection failed',
|
||||
'workspace.connect.passwordTitle': 'Enter connection password',
|
||||
'workspace.connect.passwordPlaceholder': 'Password',
|
||||
'workspace.connect.passphraseTitle': 'Enter private key passphrase',
|
||||
'workspace.connect.passphrasePlaceholder': 'Passphrase',
|
||||
'workspace.connect.connecting': 'Connecting…',
|
||||
'workspace.connect.connectingNamed': 'Connecting to {name}',
|
||||
'workspace.connect.action': 'Connect',
|
||||
'workspace.error.title': 'The interface hit an error',
|
||||
'workspace.error.reload': 'Reload'
|
||||
}
|
||||
|
||||
export default workspace
|
||||
@@ -0,0 +1,17 @@
|
||||
/** 名前空間: common(i18n 基盤、汎用ボタン・状態)。担当: i18n 基盤。 */
|
||||
const common: Record<string, string> = {
|
||||
'common.ok': 'OK',
|
||||
'common.cancel': 'キャンセル',
|
||||
'common.close': '閉じる',
|
||||
'common.save': '保存',
|
||||
'common.delete': '削除',
|
||||
'common.edit': '編集',
|
||||
'common.add': '追加',
|
||||
'common.copy': 'コピー',
|
||||
'common.paste': '貼り付け',
|
||||
'common.reset': '既定値に戻す',
|
||||
'common.language': '表示言語',
|
||||
'common.languageDesc': '切り替えるとすぐに表示言語が反映され、保存後は永続化されます。'
|
||||
}
|
||||
|
||||
export default common
|
||||
@@ -0,0 +1,19 @@
|
||||
import common from './common'
|
||||
import settings from './settings'
|
||||
import workspace from './workspace'
|
||||
import terminal from './terminal'
|
||||
import ssh from './ssh'
|
||||
import panels from './panels'
|
||||
import main from './main'
|
||||
|
||||
/** 日本語の文言。名前空間ファイルは領域ごとに分担して保守します。詳細は
|
||||
* src/shared/i18n/index.ts の担当表を参照。 */
|
||||
export default {
|
||||
...common,
|
||||
...settings,
|
||||
...workspace,
|
||||
...terminal,
|
||||
...ssh,
|
||||
...panels,
|
||||
...main
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/** 名前空間: main(メインプロセスの文言: トレイ、終了確認、アップデータ)。担当: メインプロセス。 */
|
||||
const main: Record<string, string> = {
|
||||
'main.tray.showWindow': 'メインウィンドウを表示',
|
||||
'main.tray.closeAction': '閉じるボタンの動作',
|
||||
'main.tray.askEveryTime': '毎回確認する',
|
||||
'main.tray.minimizeToTray': 'トレイに最小化',
|
||||
'main.tray.exitDirectly': '直接終了',
|
||||
'main.tray.exit': '終了',
|
||||
'main.tray.balloonTitle': 'トレイに最小化しました',
|
||||
'main.tray.balloonContent': 'ターミナルセッションはバックグラウンドで実行中です。トレイアイコンをクリックするとウィンドウを復元できます。',
|
||||
'main.tray.closeTitle': 'OpenTerminal を終了',
|
||||
'main.tray.closeMessage': 'トレイに最小化しますか、それとも終了しますか?',
|
||||
'main.tray.closeDetail': 'トレイに最小化すると、ターミナルセッションは実行を続けます。',
|
||||
'main.tray.rememberChoice': '選択を記憶して今後確認しない',
|
||||
|
||||
'main.updater.feedFailed': '国内フィード: {gitea};GitHub: {github}',
|
||||
|
||||
'main.ssh.connectTimeout': '接続がタイムアウトしました ({host}:{port})',
|
||||
'main.ssh.saveFingerprintFailed': 'ホスト鍵のフィンガープリントを保存できませんでした: {detail}',
|
||||
'main.ssh.hostKeyRejected': 'ユーザーがホスト鍵を拒否しました',
|
||||
'main.ssh.connectFailed': '接続に失敗しました {host}:{port}: {detail}',
|
||||
'main.ssh.shellOpenFailed': 'SSH シェルを開けません ({host}:{port}): {detail}',
|
||||
'main.ssh.initFailed': 'SSH 接続の初期化に失敗しました ({host}:{port}): {detail}',
|
||||
'main.ssh.readKeyFailed': '秘密鍵ファイルを読み取れません {path}: {detail}',
|
||||
|
||||
'main.sftp.sessionGone': 'SSH セッションが存在しないか、切断されています',
|
||||
'main.sftp.deleteFailed': '削除に失敗しました: {detail}',
|
||||
'main.sftp.invalidMode': '不正なパーミッション値: {mode}',
|
||||
'main.sftp.invalidUidGid': '不正な uid/gid',
|
||||
'main.sftp.commandExitCode': 'コマンドの終了コード {code}',
|
||||
'main.sftp.cancelled': 'キャンセルしました',
|
||||
|
||||
'main.zmodem.transferFailed': '転送に失敗しました',
|
||||
'main.zmodem.transferTimeout': '転送がタイムアウトしました',
|
||||
'main.zmodem.sendFailed': '送信に失敗しました',
|
||||
'main.zmodem.uploadFailed': 'アップロードに失敗しました',
|
||||
'main.zmodem.receiveFailed': '受信に失敗しました',
|
||||
'main.zmodem.abnormal': 'ZMODEM 転送エラー',
|
||||
'main.zmodem.cancelled': 'キャンセルしました',
|
||||
'main.zmodem.offerTimedOut': 'ファイルが選択されなかったためキャンセルしました',
|
||||
'main.zmodem.sessionInvalid': 'セッションが無効になりました',
|
||||
'main.zmodem.sessionCreateFailed': 'ZMODEM セッションを確立できません',
|
||||
'main.zmodem.noSaveDir': '保存先ディレクトリが指定されていません',
|
||||
'main.zmodem.noFiles': 'ファイルが選択されていません',
|
||||
|
||||
'main.ipc.connectionMissing': '接続ブックマークが見つかりません ({id})',
|
||||
|
||||
'main.sysinfo.sessionGone': 'SSH セッションが存在しないか切断されています',
|
||||
'main.sysinfo.execFailed': 'SSH exec に失敗しました',
|
||||
'main.sysinfo.parseFailed': '解析に失敗しました: {message}',
|
||||
'main.pty.serviceNotReady': 'SSH セッションサービスが未初期化です',
|
||||
'main.pty.missingConnectionId': 'SSH セッションに connectionId がありません',
|
||||
'main.log.tuiOmitted': '全画面 (TUI) 出力を省略しました'
|
||||
}
|
||||
|
||||
export default main
|
||||
@@ -0,0 +1,36 @@
|
||||
/** 名前空間: panels(コマンドパネル、セッションログパネル、転送パネル)。担当: パネル。 */
|
||||
const panels: Record<string, string> = {
|
||||
// コマンドパネル
|
||||
'panels.commands.sectionTitle': 'コマンド',
|
||||
'panels.commands.target': '送信先',
|
||||
'panels.commands.targetSsh': 'SSH サーバー',
|
||||
'panels.commands.targetTerminal': 'ターミナル',
|
||||
'panels.commands.tabHistory': '履歴',
|
||||
'panels.commands.tabLibrary': 'コマンドライブラリ',
|
||||
'panels.commands.historyTitle': '履歴コマンド',
|
||||
'panels.commands.clearTitle': 'すべてのコマンド履歴を消去しますか?',
|
||||
'panels.commands.clear': '消去',
|
||||
'panels.commands.noHistory': 'コマンド履歴はありません',
|
||||
'panels.commands.loading': '読み込み中…',
|
||||
'panels.commands.libraryTitle': 'コマンドライブラリ',
|
||||
'panels.commands.libraryEmpty': 'コマンドライブラリは空です',
|
||||
'panels.commands.add': 'コマンドを追加',
|
||||
'panels.commands.name': '名前',
|
||||
'panels.commands.optional': '(任意)',
|
||||
'panels.commands.command': 'コマンド',
|
||||
'panels.commands.commandPlaceholder': '例:ls -la',
|
||||
'panels.commands.note': 'メモ',
|
||||
'panels.commands.deleteTitle': 'このコマンドを削除しますか?',
|
||||
'panels.commands.deleteAria': 'コマンドを削除',
|
||||
|
||||
// 転送パネル
|
||||
'panels.transfer.failed': '転送に失敗しました',
|
||||
'panels.transfer.cancelled': 'キャンセル済み',
|
||||
'panels.transfer.done': '転送が完了しました',
|
||||
'panels.transfer.uploading': 'アップロード中',
|
||||
'panels.transfer.downloading': 'ダウンロード中',
|
||||
'panels.transfer.zmodemUploading': 'ZMODEM アップロード中',
|
||||
'panels.transfer.zmodemDownloading': 'ZMODEM ダウンロード中'
|
||||
}
|
||||
|
||||
export default panels
|
||||
@@ -0,0 +1,150 @@
|
||||
/** 名前空間: settings(設定ダイアログ: フォント/カーソル/描画/ハイライト/テーマ/システム/情報)。担当: 設定画面。 */
|
||||
const settings: Record<string, string> = {
|
||||
'settings.title': '設定',
|
||||
'settings.tabs.font': 'フォント',
|
||||
'settings.tabs.cursor': 'カーソルとスクロール',
|
||||
'settings.tabs.render': '描画と動作',
|
||||
'settings.tabs.highlight': 'ハイライト',
|
||||
'settings.tabs.theme': 'テーマ',
|
||||
'settings.tabs.system': 'システム',
|
||||
'settings.tabs.about': 'このアプリについて',
|
||||
'settings.resizeHandle': 'ドラッグしてサイズ変更',
|
||||
'settings.preview': 'プレビュー',
|
||||
'settings.deleteConfirmDesc': '削除すると元に戻せません。続けますか?',
|
||||
'settings.color.foreground': '前景',
|
||||
'settings.color.background': '背景',
|
||||
'settings.color.cursor': 'カーソル',
|
||||
'settings.color.selection': '選択範囲',
|
||||
'settings.font.label': 'フォント',
|
||||
'settings.font.desc': '組み込みの既定フォント、またはシステムの等幅フォント',
|
||||
'settings.font.placeholder': 'フォントを選択',
|
||||
'settings.font.default': 'デフォルト',
|
||||
'settings.font.size': '文字サイズ',
|
||||
'settings.font.sizeDesc': 'ターミナル文字のピクセルサイズ',
|
||||
'settings.font.weight': '文字の太さ',
|
||||
'settings.font.weightDesc': '400 が標準、700 が太字',
|
||||
'settings.font.boldWeight': '太字の太さ',
|
||||
'settings.font.boldWeightDesc': '太字テキストに使う太さ',
|
||||
'settings.font.letterSpacing': '文字間隔',
|
||||
'settings.font.letterSpacingDesc': '文字どうしの水平方向の間隔',
|
||||
'settings.font.lineHeight': '行の高さ',
|
||||
'settings.font.lineHeightDesc': '隣り合う行の垂直方向の距離',
|
||||
'settings.cursor.blink': 'カーソルの点滅',
|
||||
'settings.cursor.blinkDesc': 'カーソルを定期的に点滅させるかどうか',
|
||||
'settings.cursor.style': 'カーソルの形状',
|
||||
'settings.cursor.styleDesc': 'カーソルの表示形状',
|
||||
'settings.cursor.inactiveStyle': '非アクティブ時のカーソル形状',
|
||||
'settings.cursor.inactiveStyleDesc': 'ウィンドウがフォーカスを失ったときのカーソル形状',
|
||||
'settings.cursor.scrollback': 'スクロールバック',
|
||||
'settings.cursor.scrollbackDesc': 'さかのぼって表示できる行数',
|
||||
'settings.cursorStyle.bar': '縦線 (bar)',
|
||||
'settings.cursorStyle.block': 'ブロック (block)',
|
||||
'settings.cursorStyle.underline': '下線 (underline)',
|
||||
'settings.cursorStyle.outline': '輪郭 (outline)',
|
||||
'settings.cursorStyle.none': 'なし (none)',
|
||||
'settings.rendererMode.auto': '自動',
|
||||
'settings.rendererMode.autoHint': 'WebGL による高速化を優先し、失敗したら DOM 描画に自動で切り替えます',
|
||||
'settings.rendererMode.webgl': '高性能 WebGL',
|
||||
'settings.rendererMode.webglHint': 'GPU 描画を強制します。高リフレッシュレートや大量行のスクロールに適します',
|
||||
'settings.rendererMode.dom': '互換 DOM',
|
||||
'settings.rendererMode.domHint': 'CPU のみで描画し、互換性を最優先します。GPU がない環境やリモートデスクトップに適します',
|
||||
'settings.render.modeLabel': '描画モード',
|
||||
'settings.render.modeHint': 'ターミナルセルの描画を高速化する方式。変更はすべてのターミナルに適用されます',
|
||||
'settings.render.autoWrap': '自動折り返し',
|
||||
'settings.render.autoWrapDesc': '幅を超えた行を自動で折り返します',
|
||||
'settings.render.copyOnSelect': '選択時にコピー',
|
||||
'settings.render.copyOnSelectDesc': 'マウスで文字を選択すると自動でコピーします',
|
||||
'settings.render.pasteRiskConfirm': '貼り付け前の確認',
|
||||
'settings.render.pasteRiskConfirmDesc':
|
||||
'複数行(または極端に長い 1 行)を貼り付ける前に確認します。1 行はそのまま貼り付けます',
|
||||
'settings.render.suggest': '入力候補',
|
||||
'settings.render.suggestDesc':
|
||||
'入力中にコマンド候補を表示します。Tab で確定、Enter は常にそのまま実行します',
|
||||
'settings.render.history': 'コマンド履歴を記録',
|
||||
'settings.render.historyDesc': 'オフにすると新しいコマンドを記録しません。保存済みの履歴は残ります',
|
||||
'settings.render.historyLimit': '履歴の上限件数',
|
||||
'settings.render.historyLimitDesc': 'コマンド履歴の最大件数。重複したコマンドは 1 件として記録します',
|
||||
'settings.render.recButton': 'ターミナルツールバー · 記録',
|
||||
'settings.render.recButtonDesc': '右上に「セッションログを記録」ボタンを表示します',
|
||||
'settings.render.openLogsButton': 'ターミナルツールバー · ログフォルダーを開く',
|
||||
'settings.render.openLogsButtonDesc': '右上に「ログフォルダーを開く」ボタンを表示します',
|
||||
'settings.render.openCwdButton': 'ターミナルツールバー · ワークスペースフォルダーを開く',
|
||||
'settings.render.openCwdButtonDesc':
|
||||
'右上に「現在のフォルダーを開く」ボタンを表示します(SSH セッションでは非表示。フォルダーは cd に追従するため、shell 統合を有効にするか cd コマンドを使ってください)',
|
||||
'settings.system.launchAtLogin': 'スタートアップ時に起動',
|
||||
'settings.system.launchAtLoginDesc': 'OS の起動時に自動で起動します(開発モードでは開発版が登録されます)',
|
||||
'settings.system.preventSleep': 'スリープを防止',
|
||||
'settings.system.preventSleepDesc':
|
||||
'オンにすると OpenTerminal がシステムの自動スリープを防ぎます。オフにすると OS の設定どおりにスリープします',
|
||||
'settings.system.restoreSession': '起動時に前回のセッションを復元',
|
||||
'settings.system.restoreSessionDesc':
|
||||
'次回の起動で分割レイアウトを復元し、各ターミナルを前回のディレクトリに戻します。オフにすると毎回 1 つのターミナルで起動します',
|
||||
'settings.system.shellIntegration': 'Shell 統合',
|
||||
'settings.system.shellIntegrationDesc':
|
||||
'shell に作業ディレクトリを報告させ(OSC 7)、パスの記憶をより正確にします(スクリプト内の cd も含みます)。プロンプトをラップするため、プロンプトの表示が崩れる場合はオフにしてください',
|
||||
'settings.system.closeAction': '閉じるボタンの動作',
|
||||
'settings.system.closeActionDesc':
|
||||
'ウィンドウの閉じるボタンを押したときの動作。タスクトレイに最小化した後は、トレイアイコンの右クリックメニューから終了できます',
|
||||
'settings.system.closeActionTray': 'タスクトレイに最小化',
|
||||
'settings.system.closeActionExit': 'そのまま終了',
|
||||
'settings.system.closeActionAsk': '毎回確認する',
|
||||
'settings.system.globalShortcut': 'グローバル呼び出しショートカット',
|
||||
'settings.system.globalShortcutDesc':
|
||||
'入力欄をクリックしてからキーの組み合わせを押します。Esc で取り消し、Backspace でクリアして無効化します',
|
||||
'settings.system.globalShortcutHint':
|
||||
'グローバルキーと組み合わせると、どの画面からでもウィンドウを呼び出し/非表示にできます。登録に失敗した場合(他のソフトとの競合)は効果がなく、アプリにエラーは表示されません。',
|
||||
'settings.system.shortcutRecording': 'キーを押してください…',
|
||||
'settings.system.shortcutPlaceholder': 'クリックしてショートカットを押す。空欄で無効',
|
||||
'settings.highlight.alert':
|
||||
'独自のハイライトは見やすさを高めますが、わずかに性能を消費します。ルールは優先順に適用されます。PS: ハイライトはターミナルへの書き込み時に色を注入するため、既存のスクロールバックには反映されません',
|
||||
'settings.highlight.enabled': '有効',
|
||||
'settings.highlight.pattern': '正規表現',
|
||||
'settings.highlight.patternPlaceholder': '例: \\b(ERROR|FAILED)\\b',
|
||||
'settings.highlight.invalidRegex': '正規表現が無効です',
|
||||
'settings.highlight.priority': '優先度',
|
||||
'settings.highlight.priorityHint': '値が小さいほど先に適用されます',
|
||||
'settings.highlight.color': '色',
|
||||
'settings.highlight.clearBg': 'クリア',
|
||||
'settings.highlight.addBg': '追加',
|
||||
'settings.highlight.palette': 'パレット',
|
||||
'settings.highlight.note': 'メモ',
|
||||
'settings.highlight.notePlaceholder': 'ルールの説明(任意)',
|
||||
'settings.highlight.actions': '操作',
|
||||
'settings.highlight.addRule': '+ ルールを追加',
|
||||
'settings.highlight.empty': 'ハイライトルールがありません。「+ ルールを追加」から作成できます',
|
||||
'settings.highlight.deleteTitle': 'ハイライトルールを削除',
|
||||
'settings.highlight.resetTitle': '既定のハイライトルールに戻す',
|
||||
'settings.highlight.resetDesc': '現在のすべてのルールを組み込みのプリセットに置き換えます。元に戻せません。',
|
||||
'settings.highlight.resetOk': '元に戻す',
|
||||
'settings.highlight.createTitle': 'ハイライトルールを作成',
|
||||
'settings.highlight.editTitle': 'ハイライトルールを編集',
|
||||
'settings.theme.accent': 'タブのアクセントカラー',
|
||||
'settings.theme.accentDesc': 'アクティブなタブの枠線、サイドバーのインジケーター、SSH バッジのアクセントカラー',
|
||||
'settings.theme.customBadge': 'カスタム',
|
||||
'settings.theme.deleteTitle': 'カスタムテーマを削除',
|
||||
'settings.theme.create': '新しいテーマ',
|
||||
'settings.theme.editTitle': 'テーマを編集',
|
||||
'settings.themeEditor.name': '名前',
|
||||
'settings.themeEditor.namePlaceholder': 'テーマ名',
|
||||
'settings.themeEditor.copySuffix': '(コピー)',
|
||||
'settings.about.currentVersion': '現在のバージョン',
|
||||
'settings.about.statusIdle': 'クリックして更新を確認',
|
||||
'settings.about.statusChecking': '更新を確認しています…',
|
||||
'settings.about.statusAvailable': '新しいバージョンがあります',
|
||||
'settings.about.statusLatest': '最新バージョンです',
|
||||
'settings.about.statusDownloading': 'ダウンロードしています…',
|
||||
'settings.about.statusDownloaded': 'ダウンロード完了。再起動してインストールできます',
|
||||
'settings.about.statusError': '確認に失敗しました',
|
||||
'settings.about.statusDev': '開発モードでは更新を確認できません',
|
||||
'settings.about.channelStable': '安定版チャンネル',
|
||||
'settings.about.autoCheck': '起動時に自動で確認',
|
||||
'settings.about.download': '更新をダウンロード',
|
||||
'settings.about.downloadGithub': '(GitHub ソース)',
|
||||
'settings.about.install': '再起動してインストール',
|
||||
'settings.about.check': '更新を確認',
|
||||
'settings.about.checkingButton': '確認中',
|
||||
'settings.about.changelog': '更新履歴',
|
||||
'settings.about.changelogEmpty': '更新履歴はありません'
|
||||
}
|
||||
|
||||
export default settings
|
||||
@@ -0,0 +1,152 @@
|
||||
/** 名前空間: ssh(SSH 接続管理、ホストキー、ファイルパネル、zmodem、システム監視)。担当: SSH。 */
|
||||
const ssh: Record<string, string> = {
|
||||
// 認証方式 / シークレットの種類
|
||||
'ssh.auth.password': 'パスワード',
|
||||
'ssh.auth.privateKey': '秘密鍵',
|
||||
'ssh.auth.agent': 'Agent',
|
||||
'ssh.secret.passphrase': 'パスフレーズ',
|
||||
|
||||
// 接続ダイアログ: 認証関連フィールド
|
||||
'ssh.fields.agentDesc':
|
||||
'ローカルの SSH Agent に読み込み済みの鍵で認証します。本アプリ内に鍵を保存する必要はありません。',
|
||||
'ssh.fields.askPasswordLabel': '接続時にパスワードを確認',
|
||||
'ssh.fields.askPasswordHint':
|
||||
'オンにすると毎回の接続でパスワード入力ダイアログを表示し、保存済みのパスワードを使いません',
|
||||
'ssh.fields.passwordPlaceholder': '編集時に空欄のままにすると保存済みのパスワードを保持します',
|
||||
'ssh.fields.keyPath': '秘密鍵のパス(サーバー上の秘密鍵のパス、省略可)',
|
||||
'ssh.fields.keyContent': '秘密鍵の内容',
|
||||
'ssh.fields.keyContentPlaceholder':
|
||||
'秘密鍵の内容を貼り付けます。空欄の場合は上のパスを使用します(編集時に空欄のままにすると保存済みの秘密鍵を保持します)',
|
||||
'ssh.fields.askPassphraseLabel': '接続時にパスフレーズを確認',
|
||||
'ssh.fields.askPassphraseHint': 'オンにすると毎回の接続で秘密鍵のパスフレーズ入力を求めます',
|
||||
'ssh.fields.passphrase': '秘密鍵のパスフレーズ',
|
||||
'ssh.fields.passphrasePlaceholder':
|
||||
'編集時に空欄のままにすると保存済みのパスフレーズを保持します',
|
||||
|
||||
// 接続ダイアログ
|
||||
'ssh.dialog.titleEdit': '接続を編集',
|
||||
'ssh.dialog.titleNew': '新規接続',
|
||||
'ssh.dialog.saveFailed': '保存に失敗しました。入力を確認して再試行してください',
|
||||
'ssh.dialog.name': '名前',
|
||||
'ssh.dialog.nameRequired': '接続名を入力してください',
|
||||
'ssh.dialog.namePlaceholder': '例:本番サーバー',
|
||||
'ssh.dialog.group': 'グループ',
|
||||
'ssh.dialog.groupPlaceholder':
|
||||
'グループを選択または入力してください。空欄の場合は「デフォルト」に入ります',
|
||||
'ssh.dialog.host': 'ホスト',
|
||||
'ssh.dialog.hostRequired': 'ホストアドレスを入力してください',
|
||||
'ssh.dialog.hostPlaceholder': '192.168.1.10 または example.com',
|
||||
'ssh.dialog.port': 'ポート',
|
||||
'ssh.dialog.portRange': 'ポートは 1〜65535 の範囲で指定してください',
|
||||
'ssh.dialog.username': 'ユーザー名',
|
||||
'ssh.dialog.usernameRequired': 'ユーザー名を入力してください',
|
||||
'ssh.dialog.authMethod': '認証方式',
|
||||
'ssh.dialog.savedSecret': '{kind}は保存済みです。空欄のままにすると現在の値を使用します',
|
||||
'ssh.dialog.keepalive': 'Keepalive 間隔(秒)',
|
||||
'ssh.dialog.keepaliveTooltip': '0 で keepalive を無効にします',
|
||||
'ssh.dialog.keepaliveMin': '負の値は指定できません',
|
||||
|
||||
// 接続サイドバー
|
||||
'ssh.sidebar.defaultGroup': 'デフォルト',
|
||||
'ssh.sidebar.timeJustNow': 'たった今',
|
||||
'ssh.sidebar.timeMinutesAgo': '{n} 分前',
|
||||
'ssh.sidebar.timeHoursAgo': '{n} 時間前',
|
||||
'ssh.sidebar.timeDaysAgo': '{n} 日前',
|
||||
'ssh.sidebar.modeTerminal': 'ターミナルワークスペース',
|
||||
'ssh.sidebar.modeSsh': 'SSH ワークスペース',
|
||||
'ssh.sidebar.title': '接続',
|
||||
'ssh.sidebar.newConnection': '新規接続',
|
||||
'ssh.sidebar.sectionTerminals': 'ターミナル',
|
||||
'ssh.sidebar.noLocalTerminals': '開いているローカルターミナルはありません',
|
||||
'ssh.sidebar.local': 'ローカル',
|
||||
'ssh.sidebar.sectionServers': 'SSH サーバー',
|
||||
'ssh.sidebar.empty': '接続がありません。+ をクリックして作成',
|
||||
'ssh.sidebar.loading': '読み込み中…',
|
||||
'ssh.sidebar.recent': '最近のセッション',
|
||||
'ssh.sidebar.dblClickConnect': '{host} にダブルクリックで接続',
|
||||
'ssh.sidebar.deleteTitle': 'この接続を削除しますか?',
|
||||
'ssh.sidebar.deleteDesc':
|
||||
'削除した接続は復元できません。保存済みの鍵データも同時に削除されます。',
|
||||
|
||||
// ホストキーの確認
|
||||
'ssh.hostKey.changedTitle': 'ホストのフィンガープリントが変更されました!',
|
||||
'ssh.hostKey.unknownHost': '未知のホスト',
|
||||
'ssh.hostKey.accept': '承認して接続',
|
||||
'ssh.hostKey.reject': '拒否',
|
||||
'ssh.hostKey.mitmTitle': '中間者攻撃の可能性があります',
|
||||
'ssh.hostKey.mitmDesc':
|
||||
'リモートホストの鍵フィンガープリントが以前の記録と一致しません。ご自身でサーバー鍵を変更していない場合、誰かがこのホストになりすましている可能性があります。',
|
||||
'ssh.hostKey.firstConnect':
|
||||
'このホストへの初回接続です。フィンガープリントはまだ記録されていません。',
|
||||
'ssh.hostKey.target': 'ホスト:{target}',
|
||||
'ssh.hostKey.fingerprint': 'フィンガープリント:{fingerprint}',
|
||||
|
||||
// SSH ワークスペース: ファイルパネル、ホストバッジ
|
||||
'ssh.bottomPanel.resize': 'ファイルパネルの高さを調整',
|
||||
'ssh.hostBadge.aria': 'SSH ホスト {label}',
|
||||
|
||||
// ZMODEM
|
||||
'ssh.zmodem.done': 'ZMODEM 転送が完了しました',
|
||||
'ssh.zmodem.failed': 'ZMODEM 転送に失敗しました:{message}',
|
||||
'ssh.zmodem.unknownError': '不明なエラー',
|
||||
'ssh.zmodem.titleReceive': 'ローカルにダウンロード',
|
||||
'ssh.zmodem.titleSend': 'サーバーへアップロード',
|
||||
'ssh.zmodem.pickDir': '保存先フォルダを選択',
|
||||
'ssh.zmodem.pickFiles': 'ファイルを選択',
|
||||
'ssh.zmodem.receiveDesc':
|
||||
'sz のダウンロード要求を検出しました(リモートがファイルを送信中)。ローカルの保存先フォルダを選択してください。',
|
||||
'ssh.zmodem.sendDesc':
|
||||
'rz のアップロード要求を検出しました(リモートがファイルを受信中)。アップロードするファイルを選択してください。',
|
||||
|
||||
// ファイルパネル(SFTP)
|
||||
'ssh.file.up': '親フォルダへ',
|
||||
'ssh.file.refresh': '更新',
|
||||
'ssh.file.uploadFile': 'ファイルをアップロード',
|
||||
'ssh.file.downloadSelected': '選択項目をダウンロード',
|
||||
'ssh.file.permOwner': '権限 / 所有者',
|
||||
'ssh.file.open': '開く',
|
||||
'ssh.file.download': 'ダウンロード',
|
||||
'ssh.file.upload': 'アップロード…',
|
||||
'ssh.file.rename': '名前を変更',
|
||||
'ssh.file.new': '新規作成',
|
||||
'ssh.file.newFolder': '新しいフォルダ',
|
||||
'ssh.file.copyPath': 'パスをコピー',
|
||||
'ssh.file.copyPathFailed': 'パスのコピーに失敗しました',
|
||||
'ssh.file.pathCopied': 'パスをコピーしました',
|
||||
'ssh.file.permission': 'ファイル権限…',
|
||||
'ssh.file.deleteTitle': '削除しますか?',
|
||||
'ssh.file.loading': '読み込み中…',
|
||||
'ssh.file.empty': '空のフォルダ',
|
||||
'ssh.file.modeUnavailable': '権限を取得できません',
|
||||
'ssh.file.folderName': 'フォルダ名',
|
||||
'ssh.file.create': '作成',
|
||||
'ssh.file.renameTitle': '{name} の名前を変更',
|
||||
'ssh.file.permTitle': '権限 · {name}',
|
||||
'ssh.file.permApplied': '権限を適用しました',
|
||||
'ssh.file.octal': '8 進数',
|
||||
'ssh.file.octalPlaceholder': '例:755',
|
||||
'ssh.file.keepEmpty': '変更しない場合は空欄',
|
||||
'ssh.file.ownerHint': 'UID/GID を空欄にすると所有者を変更しません',
|
||||
'ssh.file.permRowOwner': '所有者',
|
||||
'ssh.file.permRowGroup': 'グループ',
|
||||
'ssh.file.permRowOther': 'その他',
|
||||
'ssh.file.permColRead': '読み取り',
|
||||
'ssh.file.permColWrite': '書き込み',
|
||||
'ssh.file.permColExec': '実行',
|
||||
|
||||
// システム監視
|
||||
'ssh.monitor.collecting': '取得中…',
|
||||
'ssh.monitor.interrupted': '取得が中断されました:{error}',
|
||||
'ssh.monitor.mem': 'メモリ',
|
||||
'ssh.monitor.disks': 'ディスク',
|
||||
'ssh.monitor.net': 'ネットワーク',
|
||||
'ssh.monitor.cores': '{n} コア',
|
||||
'ssh.monitor.loadavg': '負荷 {value}',
|
||||
'ssh.monitor.uptime': '稼働時間',
|
||||
'ssh.monitor.uptimeSeconds': '{n}秒',
|
||||
'ssh.monitor.uptimeMinutes': '{n}分',
|
||||
'ssh.monitor.uptimeHours': '{h}時間{m}分',
|
||||
'ssh.monitor.uptimeDays': '{n}日'
|
||||
}
|
||||
|
||||
export default ssh
|
||||
@@ -0,0 +1,26 @@
|
||||
/** 名前空間: terminal(ターミナル表示:コンテキストメニュー、検索、貼り付け確認、ツールバー、ヒント)。担当: ワークスペース/ターミナル。 */
|
||||
const terminal: Record<string, string> = {
|
||||
'terminal.menu.find': '検索',
|
||||
'terminal.menu.selectAll': 'すべて選択',
|
||||
'terminal.menu.clear': '画面クリア',
|
||||
'terminal.search.placeholder': '検索',
|
||||
'terminal.search.prev': '前へ',
|
||||
'terminal.search.next': '次へ',
|
||||
'terminal.search.found': '見つかりました',
|
||||
'terminal.search.notFound': '見つかりません',
|
||||
'terminal.suggest.hint': '↑/↓ 選択 · Tab で確定 · Esc で閉じる',
|
||||
'terminal.rec.start': '記録開始',
|
||||
'terminal.rec.stop': '記録停止',
|
||||
'terminal.rec.startLog': 'セッションログの記録を開始',
|
||||
'terminal.rec.stopLog': 'セッションログの記録を停止',
|
||||
'terminal.rec.openLogs': 'ログフォルダーを開く',
|
||||
'terminal.rec.openCwd': 'ワークスペースフォルダーを開く',
|
||||
'terminal.paste.title': '貼り付けの確認',
|
||||
'terminal.paste.message': '複数行または危険な可能性のあるコマンドを検出しました。ターミナルに貼り付けますか?',
|
||||
'terminal.paste.noPrompt': 'このセッションでは表示しない',
|
||||
'terminal.paste.disableDetection': '今後の貼り付けチェックを無効にする',
|
||||
'terminal.paste.hint': '一般のターミナル設定で再度有効にするか、検出ポリシーを変更できます。',
|
||||
'terminal.dead.message': 'プロセスが終了しました (コード {code})'
|
||||
}
|
||||
|
||||
export default terminal
|
||||
@@ -0,0 +1,62 @@
|
||||
/** 名前空間: workspace(ワークスペース外装:サイドバー、タブ、レイアウトメニュー、分割、空状態)。担当: ワークスペース。 */
|
||||
const workspace: Record<string, string> = {
|
||||
'workspace.tab.terminalTitle': 'ターミナル {n}',
|
||||
'workspace.tab.localTerminal': 'ローカルターミナル',
|
||||
'workspace.tab.closeOthers': 'ほかを閉じる',
|
||||
'workspace.tab.closeRight': '右側を閉じる',
|
||||
'workspace.tab.broadcastTarget': 'ブロードキャスト対象',
|
||||
'workspace.tab.broadcastBadge': '配',
|
||||
'workspace.tab.addInSplit': 'この分割に新しいターミナル',
|
||||
'workspace.newTerminal': '新規ターミナル',
|
||||
'workspace.empty.terminalTitle': 'ターミナルがありません',
|
||||
'workspace.empty.sshTitle': 'SSH セッションがありません',
|
||||
'workspace.empty.sshHint': '左側のサーバー一覧から接続してください',
|
||||
'workspace.rail.hideSidebar': 'サイドバーを折りたたむ',
|
||||
'workspace.rail.showSidebar': 'サイドバーを展開',
|
||||
'workspace.rail.layout': 'レイアウト',
|
||||
'workspace.rail.settings': '設定',
|
||||
'workspace.rail.connecting': '接続中…',
|
||||
'workspace.rail.terminalWorkspace': 'ターミナルワークスペース',
|
||||
'workspace.rail.sshWorkspace': 'SSH ワークスペース',
|
||||
'workspace.panel.hideSidebar': 'サイドバーを折りたたむ',
|
||||
'workspace.panel.showSidebar': 'サイドバーを展開',
|
||||
'workspace.layout.splitRight': '水平分割',
|
||||
'workspace.layout.splitBelow': '垂直分割',
|
||||
'workspace.layout.saveTemplate': 'テンプレートとして保存',
|
||||
'workspace.layout.applyTemplate': 'テンプレートを適用',
|
||||
'workspace.template.saveTitle': 'レイアウトテンプレートを保存',
|
||||
'workspace.template.namePlaceholder': 'テンプレート名',
|
||||
'workspace.template.applyTitle': 'レイアウトテンプレートを適用',
|
||||
'workspace.template.empty': '保存済みのテンプレートはありません',
|
||||
'workspace.template.apply': '適用',
|
||||
'workspace.template.deleteConfirm': 'このテンプレートを削除しますか?',
|
||||
'workspace.broadcast.toggle': 'ブロードキャスト入力',
|
||||
'workspace.broadcast.activeTitle': 'ブロードキャスト中({count} 件の対象)',
|
||||
'workspace.broadcast.popoverTerminal': 'ブロードキャスト入力(ターミナル)',
|
||||
'workspace.broadcast.popoverSsh': 'ブロードキャスト入力(SSH)',
|
||||
'workspace.broadcast.switch': 'ブロードキャストスイッチ',
|
||||
'workspace.broadcast.enabled': '有効({count})',
|
||||
'workspace.broadcast.needTwo': '対象を 2 つ以上選択してください',
|
||||
'workspace.broadcast.disabled': '無効',
|
||||
'workspace.broadcast.emptySsh': 'SSH サーバーセッションがありません',
|
||||
'workspace.broadcast.emptyTerminal': 'ターミナルがありません',
|
||||
'workspace.broadcast.hint':
|
||||
'ターミナルを 2 つ以上選ぶとブロードキャストが自動的に有効になり、対象が 2 つ未満になると自動的に解除されます。選択できるのは現在のモードのセッションだけです。',
|
||||
'workspace.hint.sshFromList': 'SSH セッションはサーバー一覧から接続してください',
|
||||
'workspace.hint.connectSshFirst': '先に SSH サーバーへ接続してください',
|
||||
'workspace.hint.noActiveTerminal':
|
||||
'有効なターミナルがありません。ローカルターミナルまたは SSH セッションを 1 つ以上開いてください',
|
||||
'workspace.hint.noSessionInPanel': '現在アクティブなパネルに利用できるセッションがありません',
|
||||
'workspace.connect.failed': 'SSH 接続に失敗しました',
|
||||
'workspace.connect.passwordTitle': '接続パスワードを入力',
|
||||
'workspace.connect.passwordPlaceholder': 'パスワード',
|
||||
'workspace.connect.passphraseTitle': '秘密鍵のパスフレーズを入力',
|
||||
'workspace.connect.passphrasePlaceholder': 'パスフレーズ',
|
||||
'workspace.connect.connecting': '接続中…',
|
||||
'workspace.connect.connectingNamed': '{name} に接続しています',
|
||||
'workspace.connect.action': '接続',
|
||||
'workspace.error.title': '画面でエラーが発生しました',
|
||||
'workspace.error.reload': '再読み込み'
|
||||
}
|
||||
|
||||
export default workspace
|
||||
@@ -0,0 +1,17 @@
|
||||
/** 命名空间:通用(i18n 基础设施、通用按钮与状态)。归属:i18n 基础设施维护者。 */
|
||||
const common: Record<string, string> = {
|
||||
'common.ok': '确定',
|
||||
'common.cancel': '取消',
|
||||
'common.close': '关闭',
|
||||
'common.save': '保存',
|
||||
'common.delete': '删除',
|
||||
'common.edit': '编辑',
|
||||
'common.add': '新增',
|
||||
'common.copy': '复制',
|
||||
'common.paste': '粘贴',
|
||||
'common.reset': '恢复默认',
|
||||
'common.language': '界面语言',
|
||||
'common.languageDesc': '切换后立即预览界面语言,保存后永久生效。'
|
||||
}
|
||||
|
||||
export default common
|
||||
@@ -0,0 +1,18 @@
|
||||
import common from './common'
|
||||
import settings from './settings'
|
||||
import workspace from './workspace'
|
||||
import terminal from './terminal'
|
||||
import ssh from './ssh'
|
||||
import panels from './panels'
|
||||
import main from './main'
|
||||
|
||||
/** 简体中文词条。命名空间文件按区域分工维护,详见 src/shared/i18n/index.ts 的归属表。 */
|
||||
export default {
|
||||
...common,
|
||||
...settings,
|
||||
...workspace,
|
||||
...terminal,
|
||||
...ssh,
|
||||
...panels,
|
||||
...main
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/** 命名空间:main(主进程文案:托盘、关闭询问、更新器)。归属:主进程维护者。 */
|
||||
const main: Record<string, string> = {
|
||||
'main.tray.showWindow': '显示主窗口',
|
||||
'main.tray.closeAction': '关闭按钮行为',
|
||||
'main.tray.askEveryTime': '每次询问',
|
||||
'main.tray.minimizeToTray': '最小化到托盘',
|
||||
'main.tray.exitDirectly': '直接退出',
|
||||
'main.tray.exit': '退出',
|
||||
'main.tray.balloonTitle': '已最小化到托盘',
|
||||
'main.tray.balloonContent': '终端会话仍在后台运行,点击托盘图标可恢复窗口。',
|
||||
'main.tray.closeTitle': '关闭 OpenTerminal',
|
||||
'main.tray.closeMessage': '最小化到托盘,还是直接退出?',
|
||||
'main.tray.closeDetail': '最小化到托盘时终端会话保持运行。',
|
||||
'main.tray.rememberChoice': '记住我的选择,不再询问',
|
||||
|
||||
'main.updater.feedFailed': '国内源: {gitea};GitHub: {github}',
|
||||
|
||||
'main.ssh.connectTimeout': '连接超时 ({host}:{port})',
|
||||
'main.ssh.saveFingerprintFailed': '保存主机指纹失败: {detail}',
|
||||
'main.ssh.hostKeyRejected': '用户拒绝了主机指纹',
|
||||
'main.ssh.connectFailed': '连接失败 {host}:{port}: {detail}',
|
||||
'main.ssh.shellOpenFailed': '无法打开 SSH shell ({host}:{port}): {detail}',
|
||||
'main.ssh.initFailed': 'SSH 连接初始化失败 ({host}:{port}): {detail}',
|
||||
'main.ssh.readKeyFailed': '无法读取私钥文件 {path}: {detail}',
|
||||
|
||||
'main.sftp.sessionGone': 'SSH 会话不存在或已断开',
|
||||
'main.sftp.deleteFailed': '删除失败: {detail}',
|
||||
'main.sftp.invalidMode': '非法权限值: {mode}',
|
||||
'main.sftp.invalidUidGid': '非法 uid/gid',
|
||||
'main.sftp.commandExitCode': '命令退出码 {code}',
|
||||
'main.sftp.cancelled': '已取消',
|
||||
|
||||
'main.zmodem.transferFailed': '传输失败',
|
||||
'main.zmodem.transferTimeout': '传输超时',
|
||||
'main.zmodem.sendFailed': '发送失败',
|
||||
'main.zmodem.uploadFailed': '上传失败',
|
||||
'main.zmodem.receiveFailed': '接收失败',
|
||||
'main.zmodem.abnormal': 'ZMODEM 传输异常',
|
||||
'main.zmodem.cancelled': '已取消',
|
||||
'main.zmodem.offerTimedOut': '未选择文件,已取消',
|
||||
'main.zmodem.sessionInvalid': '会话已失效',
|
||||
'main.zmodem.sessionCreateFailed': '无法建立 ZMODEM 会话',
|
||||
'main.zmodem.noSaveDir': '未指定保存目录',
|
||||
'main.zmodem.noFiles': '未选择文件',
|
||||
|
||||
'main.ipc.connectionMissing': '连接书签不存在 ({id})',
|
||||
|
||||
'main.sysinfo.sessionGone': 'SSH 会话不存在或已断开',
|
||||
'main.sysinfo.execFailed': 'SSH exec 失败',
|
||||
'main.sysinfo.parseFailed': '解析失败: {message}',
|
||||
'main.pty.serviceNotReady': 'SSH 会话服务尚未初始化',
|
||||
'main.pty.missingConnectionId': 'SSH 会话缺少 connectionId',
|
||||
'main.log.tuiOmitted': '全屏界面(TUI)输出已省略'
|
||||
}
|
||||
|
||||
export default main
|
||||
@@ -0,0 +1,36 @@
|
||||
/** 命名空间:panels(命令面板、会话日志面板、传输面板)。归属:SSH/面板维护者。 */
|
||||
const panels: Record<string, string> = {
|
||||
// 命令面板
|
||||
'panels.commands.sectionTitle': '命令',
|
||||
'panels.commands.target': '发送目标',
|
||||
'panels.commands.targetSsh': 'SSH 服务器',
|
||||
'panels.commands.targetTerminal': '终端',
|
||||
'panels.commands.tabHistory': '历史',
|
||||
'panels.commands.tabLibrary': '命令库',
|
||||
'panels.commands.historyTitle': '历史命令',
|
||||
'panels.commands.clearTitle': '清空全部命令历史?',
|
||||
'panels.commands.clear': '清空',
|
||||
'panels.commands.noHistory': '暂无历史命令',
|
||||
'panels.commands.loading': '加载中…',
|
||||
'panels.commands.libraryTitle': '命令库',
|
||||
'panels.commands.libraryEmpty': '命令库为空',
|
||||
'panels.commands.add': '新增命令',
|
||||
'panels.commands.name': '名称',
|
||||
'panels.commands.optional': '(可选)',
|
||||
'panels.commands.command': '命令',
|
||||
'panels.commands.commandPlaceholder': '如 ls -la',
|
||||
'panels.commands.note': '备注',
|
||||
'panels.commands.deleteTitle': '删除该命令?',
|
||||
'panels.commands.deleteAria': '删除命令',
|
||||
|
||||
// 传输面板
|
||||
'panels.transfer.failed': '传输失败',
|
||||
'panels.transfer.cancelled': '已取消',
|
||||
'panels.transfer.done': '传输完成',
|
||||
'panels.transfer.uploading': '上传中',
|
||||
'panels.transfer.downloading': '下载中',
|
||||
'panels.transfer.zmodemUploading': 'ZMODEM 上传中',
|
||||
'panels.transfer.zmodemDownloading': 'ZMODEM 下载中'
|
||||
}
|
||||
|
||||
export default panels
|
||||
@@ -0,0 +1,147 @@
|
||||
/** 命名空间:settings(设置弹窗:字体/光标/渲染/高亮/主题/系统/关于)。归属:设置页维护者。 */
|
||||
const settings: Record<string, string> = {
|
||||
'settings.title': '设置',
|
||||
'settings.tabs.font': '字体',
|
||||
'settings.tabs.cursor': '光标与滚动',
|
||||
'settings.tabs.render': '渲染与行为',
|
||||
'settings.tabs.highlight': '高亮',
|
||||
'settings.tabs.theme': '主题',
|
||||
'settings.tabs.system': '系统',
|
||||
'settings.tabs.about': '关于',
|
||||
'settings.resizeHandle': '拖拽调整大小',
|
||||
'settings.preview': '预览',
|
||||
'settings.deleteConfirmDesc': '删除后无法恢复,确定继续?',
|
||||
'settings.color.foreground': '前景',
|
||||
'settings.color.background': '背景',
|
||||
'settings.color.cursor': '光标',
|
||||
'settings.color.selection': '选区',
|
||||
'settings.font.label': '字体',
|
||||
'settings.font.desc': '内置默认字体或系统等宽字体',
|
||||
'settings.font.placeholder': '选择字体',
|
||||
'settings.font.default': '默认',
|
||||
'settings.font.size': '字号',
|
||||
'settings.font.sizeDesc': '终端文字的像素大小',
|
||||
'settings.font.weight': '字重',
|
||||
'settings.font.weightDesc': '400 为常规,700 为粗体',
|
||||
'settings.font.boldWeight': '粗体字重',
|
||||
'settings.font.boldWeightDesc': '粗体文字所用的字重',
|
||||
'settings.font.letterSpacing': '字间距',
|
||||
'settings.font.letterSpacingDesc': '字符之间的水平间距',
|
||||
'settings.font.lineHeight': '行高',
|
||||
'settings.font.lineHeightDesc': '相邻两行之间的垂直距离',
|
||||
'settings.cursor.blink': '光标闪烁',
|
||||
'settings.cursor.blinkDesc': '光标是否周期性闪烁',
|
||||
'settings.cursor.style': '光标样式',
|
||||
'settings.cursor.styleDesc': '光标的显示形状',
|
||||
'settings.cursor.inactiveStyle': '非活动光标样式',
|
||||
'settings.cursor.inactiveStyleDesc': '窗口失焦时光标样式',
|
||||
'settings.cursor.scrollback': '滚动缓冲区',
|
||||
'settings.cursor.scrollbackDesc': '屏幕上可回滚的行数',
|
||||
'settings.cursorStyle.bar': '竖线 (bar)',
|
||||
'settings.cursorStyle.block': '方块 (block)',
|
||||
'settings.cursorStyle.underline': '下划线 (underline)',
|
||||
'settings.cursorStyle.outline': '轮廓 (outline)',
|
||||
'settings.cursorStyle.none': '无 (none)',
|
||||
'settings.rendererMode.auto': '自动',
|
||||
'settings.rendererMode.autoHint': '优先使用 WebGL 加速,失败时自动回退到 DOM 渲染',
|
||||
'settings.rendererMode.webgl': '高性能 WebGL',
|
||||
'settings.rendererMode.webglHint': '强制使用 GPU 加速渲染,适合高刷新率与大行数滚动',
|
||||
'settings.rendererMode.dom': '兼容 DOM',
|
||||
'settings.rendererMode.domHint': '纯 CPU 渲染,兼容性最好,适合无 GPU 或远程桌面环境',
|
||||
'settings.render.modeLabel': '渲染模式',
|
||||
'settings.render.modeHint': '终端单元渲染加速方式,改动将应用到所有终端',
|
||||
'settings.render.autoWrap': '自动换行',
|
||||
'settings.render.autoWrapDesc': '超出宽度时自动折行',
|
||||
'settings.render.copyOnSelect': '选中即复制',
|
||||
'settings.render.copyOnSelectDesc': '鼠标选中文字时自动复制',
|
||||
'settings.render.pasteRiskConfirm': '粘贴风险确认',
|
||||
'settings.render.pasteRiskConfirmDesc': '多行文本(或超长单行)粘贴前弹出确认;单行直接粘贴',
|
||||
'settings.render.suggest': '输入建议',
|
||||
'settings.render.suggestDesc': '输入时弹出命令建议;Tab 接受,回车始终直接执行',
|
||||
'settings.render.history': '记录命令历史',
|
||||
'settings.render.historyDesc': '关闭后不再记录新命令;已保存的历史仍然保留',
|
||||
'settings.render.historyLimit': '历史条数上限',
|
||||
'settings.render.historyLimitDesc': '命令历史最多保留多少条,重复命令只记一次',
|
||||
'settings.render.recButton': '终端工具栏 · 录制',
|
||||
'settings.render.recButtonDesc': '右上角显示「记录会话日志」按钮',
|
||||
'settings.render.openLogsButton': '终端工具栏 · 打开日志目录',
|
||||
'settings.render.openLogsButtonDesc': '右上角显示「打开日志目录」按钮',
|
||||
'settings.render.openCwdButton': '终端工具栏 · 打开工作区目录',
|
||||
'settings.render.openCwdButtonDesc':
|
||||
'右上角显示「打开当前目录」按钮(SSH 会话不显示;目录随 cd 实时跟踪,需开启 shell 集成或使用 cd 命令)',
|
||||
'settings.system.launchAtLogin': '开机时自启动',
|
||||
'settings.system.launchAtLoginDesc': '开机时自动启动软件(开发模式下注册的是开发版程序)',
|
||||
'settings.system.preventSleep': '阻止系统休眠',
|
||||
'settings.system.preventSleepDesc':
|
||||
'开启后 OpenTerminal 将阻止系统自动休眠;关闭则允许系统按系统设置休眠',
|
||||
'settings.system.restoreSession': '启动时恢复上次会话',
|
||||
'settings.system.restoreSessionDesc':
|
||||
'下次启动恢复分屏布局,并让每个终端回到它上次所在的目录;关闭则每次都以单个终端启动',
|
||||
'settings.system.shellIntegration': 'Shell 集成',
|
||||
'settings.system.shellIntegrationDesc':
|
||||
'让 shell 主动上报工作目录(OSC 7),路径记忆更精确(含脚本内的 cd);会包装你的命令提示符,遇到提示符主题异常时关掉即可',
|
||||
'settings.system.closeAction': '关闭按钮行为',
|
||||
'settings.system.closeActionDesc':
|
||||
'点击窗口关闭按钮时的动作;最小化到托盘后可在托盘图标右键菜单中退出',
|
||||
'settings.system.closeActionTray': '最小化到托盘',
|
||||
'settings.system.closeActionExit': '直接退出',
|
||||
'settings.system.closeActionAsk': '每次询问',
|
||||
'settings.system.globalShortcut': '全局唤起快捷键',
|
||||
'settings.system.globalShortcutDesc': '点击输入框后直接按下组合键;Esc 取消,退格清空禁用',
|
||||
'settings.system.globalShortcutHint':
|
||||
'配合全局键可在任何界面唤起/隐藏窗口;若注册失败(与其他软件冲突)则不生效,应用不会报错。',
|
||||
'settings.system.shortcutRecording': '按下组合键…',
|
||||
'settings.system.shortcutPlaceholder': '点击后按下快捷键,留空禁用',
|
||||
'settings.highlight.alert':
|
||||
'自定义高亮可增强显示效果,但会略微增加性能消耗。规则按优先级顺序应用。PS: 高亮在写入终端时注入颜色,对已有回滚内容不生效',
|
||||
'settings.highlight.enabled': '启用',
|
||||
'settings.highlight.pattern': '正则',
|
||||
'settings.highlight.patternPlaceholder': '例如 \\b(ERROR|FAILED)\\b',
|
||||
'settings.highlight.invalidRegex': '正则表达式无效',
|
||||
'settings.highlight.priority': '优先级',
|
||||
'settings.highlight.priorityHint': '值越小越先应用',
|
||||
'settings.highlight.color': '颜色',
|
||||
'settings.highlight.clearBg': '清空',
|
||||
'settings.highlight.addBg': '添加',
|
||||
'settings.highlight.palette': '色板',
|
||||
'settings.highlight.note': '备注',
|
||||
'settings.highlight.notePlaceholder': '规则说明(可选)',
|
||||
'settings.highlight.actions': '操作',
|
||||
'settings.highlight.addRule': '+ 新增规则',
|
||||
'settings.highlight.empty': '暂无高亮规则,点击「+ 新增规则」创建',
|
||||
'settings.highlight.deleteTitle': '删除高亮规则',
|
||||
'settings.highlight.resetTitle': '恢复默认高亮规则',
|
||||
'settings.highlight.resetDesc': '将替换当前全部规则为内置预设,不可恢复。',
|
||||
'settings.highlight.resetOk': '恢复',
|
||||
'settings.highlight.createTitle': '新建高亮规则',
|
||||
'settings.highlight.editTitle': '编辑高亮规则',
|
||||
'settings.theme.accent': '标签强调色',
|
||||
'settings.theme.accentDesc': '活动标签边框、侧栏指示条与 SSH 徽章的强调颜色',
|
||||
'settings.theme.customBadge': '自定义',
|
||||
'settings.theme.deleteTitle': '删除自定义主题',
|
||||
'settings.theme.create': '新建主题',
|
||||
'settings.theme.editTitle': '编辑主题',
|
||||
'settings.themeEditor.name': '名称',
|
||||
'settings.themeEditor.namePlaceholder': '主题名称',
|
||||
'settings.themeEditor.copySuffix': '(副本)',
|
||||
'settings.about.currentVersion': '当前版本',
|
||||
'settings.about.statusIdle': '点击检查更新',
|
||||
'settings.about.statusChecking': '正在检查更新…',
|
||||
'settings.about.statusAvailable': '发现新版本',
|
||||
'settings.about.statusLatest': '已经是最新版本',
|
||||
'settings.about.statusDownloading': '正在下载…',
|
||||
'settings.about.statusDownloaded': '下载完成,可重启安装',
|
||||
'settings.about.statusError': '检查失败',
|
||||
'settings.about.statusDev': '开发模式不支持更新检查',
|
||||
'settings.about.channelStable': '稳定更新通道',
|
||||
'settings.about.autoCheck': '启动时自动检查',
|
||||
'settings.about.download': '下载更新',
|
||||
'settings.about.downloadGithub': '(GitHub 源)',
|
||||
'settings.about.install': '重启安装',
|
||||
'settings.about.check': '检查更新',
|
||||
'settings.about.checkingButton': '检查中',
|
||||
'settings.about.changelog': '更新日志',
|
||||
'settings.about.changelogEmpty': '暂无更新日志'
|
||||
}
|
||||
|
||||
export default settings
|
||||
@@ -0,0 +1,144 @@
|
||||
/** 命名空间:ssh(SSH 连接管理、主机密钥、文件面板、zmodem、系统监控)。归属:SSH 维护者。 */
|
||||
const ssh: Record<string, string> = {
|
||||
// 认证方式 / 密钥种类
|
||||
'ssh.auth.password': '密码',
|
||||
'ssh.auth.privateKey': '私钥',
|
||||
'ssh.auth.agent': 'Agent',
|
||||
'ssh.secret.passphrase': '口令',
|
||||
|
||||
// 连接编辑弹窗:认证相关字段
|
||||
'ssh.fields.agentDesc': '使用本机 SSH Agent 中已加载的密钥进行认证,无需在本应用内保存任何密钥。',
|
||||
'ssh.fields.askPasswordLabel': '连接时询问密码',
|
||||
'ssh.fields.askPasswordHint': '开启后每次连接弹出对话框输入密码,不再使用已保存的密码',
|
||||
'ssh.fields.passwordPlaceholder': '编辑时留空表示保留已保存的密码',
|
||||
'ssh.fields.keyPath': '私钥路径(服务器上的本地私钥路径,可留空)',
|
||||
'ssh.fields.keyContent': '私钥内容',
|
||||
'ssh.fields.keyContentPlaceholder':
|
||||
'粘贴私钥内容;留空则使用上面的路径(编辑时留空表示保留已保存的私钥)',
|
||||
'ssh.fields.askPassphraseLabel': '连接时询问口令',
|
||||
'ssh.fields.askPassphraseHint': '开启后每次连接提示输入私钥口令',
|
||||
'ssh.fields.passphrase': '私钥口令',
|
||||
'ssh.fields.passphrasePlaceholder': '编辑时留空表示保留已保存的口令',
|
||||
|
||||
// 连接编辑弹窗
|
||||
'ssh.dialog.titleEdit': '编辑连接',
|
||||
'ssh.dialog.titleNew': '新建连接',
|
||||
'ssh.dialog.saveFailed': '保存失败,请检查输入后重试',
|
||||
'ssh.dialog.name': '名称',
|
||||
'ssh.dialog.nameRequired': '请输入连接名称',
|
||||
'ssh.dialog.namePlaceholder': '例如:生产服务器',
|
||||
'ssh.dialog.group': '分组',
|
||||
'ssh.dialog.groupPlaceholder': '选择或输入新分组,留空归入“默认”',
|
||||
'ssh.dialog.host': '主机',
|
||||
'ssh.dialog.hostRequired': '请输入主机地址',
|
||||
'ssh.dialog.hostPlaceholder': '192.168.1.10 或 example.com',
|
||||
'ssh.dialog.port': '端口',
|
||||
'ssh.dialog.portRange': '端口需在 1–65535 之间',
|
||||
'ssh.dialog.username': '用户名',
|
||||
'ssh.dialog.usernameRequired': '请输入用户名',
|
||||
'ssh.dialog.authMethod': '认证方式',
|
||||
'ssh.dialog.savedSecret': '已保存{kind},留空将保留原值',
|
||||
'ssh.dialog.keepalive': 'Keepalive 间隔(秒)',
|
||||
'ssh.dialog.keepaliveTooltip': '0 表示关闭 keepalive',
|
||||
'ssh.dialog.keepaliveMin': '不能为负数',
|
||||
|
||||
// 连接侧栏
|
||||
'ssh.sidebar.defaultGroup': '默认',
|
||||
'ssh.sidebar.timeJustNow': '刚刚',
|
||||
'ssh.sidebar.timeMinutesAgo': '{n} 分钟前',
|
||||
'ssh.sidebar.timeHoursAgo': '{n} 小时前',
|
||||
'ssh.sidebar.timeDaysAgo': '{n} 天前',
|
||||
'ssh.sidebar.modeTerminal': '终端工作区',
|
||||
'ssh.sidebar.modeSsh': 'SSH 工作区',
|
||||
'ssh.sidebar.title': '连接',
|
||||
'ssh.sidebar.newConnection': '新建连接',
|
||||
'ssh.sidebar.sectionTerminals': '终端',
|
||||
'ssh.sidebar.noLocalTerminals': '无打开的本地终端',
|
||||
'ssh.sidebar.local': '本地',
|
||||
'ssh.sidebar.sectionServers': 'SSH 服务器',
|
||||
'ssh.sidebar.empty': '暂无连接,点击+新建',
|
||||
'ssh.sidebar.loading': '加载中…',
|
||||
'ssh.sidebar.recent': '最近会话',
|
||||
'ssh.sidebar.dblClickConnect': '双击连接 {host}',
|
||||
'ssh.sidebar.deleteTitle': '删除该连接?',
|
||||
'ssh.sidebar.deleteDesc': '连接配置删除后不可恢复。已保存的密钥数据会同步删除。',
|
||||
|
||||
// 主机密钥确认
|
||||
'ssh.hostKey.changedTitle': '主机指纹已变更!',
|
||||
'ssh.hostKey.unknownHost': '未知主机',
|
||||
'ssh.hostKey.accept': '接受并连接',
|
||||
'ssh.hostKey.reject': '拒绝',
|
||||
'ssh.hostKey.mitmTitle': '可能遭受中间人攻击',
|
||||
'ssh.hostKey.mitmDesc':
|
||||
'远程主机的密钥指纹与之前记录的不一致。如果这不是你本人更换了服务器密钥,可能有人正在冒充该主机。',
|
||||
'ssh.hostKey.firstConnect': '首次连接该主机,尚未记录其指纹。',
|
||||
'ssh.hostKey.target': '主机:{target}',
|
||||
'ssh.hostKey.fingerprint': '指纹:{fingerprint}',
|
||||
|
||||
// SSH 工作区:文件面板容器、主机徽标
|
||||
'ssh.bottomPanel.resize': '调整文件面板高度',
|
||||
'ssh.hostBadge.aria': 'SSH 主机 {label}',
|
||||
|
||||
// ZMODEM
|
||||
'ssh.zmodem.done': 'ZMODEM 传输完成',
|
||||
'ssh.zmodem.failed': 'ZMODEM 传输失败:{message}',
|
||||
'ssh.zmodem.unknownError': '未知错误',
|
||||
'ssh.zmodem.titleReceive': '下载到本地',
|
||||
'ssh.zmodem.titleSend': '上传到服务器',
|
||||
'ssh.zmodem.pickDir': '选择保存目录',
|
||||
'ssh.zmodem.pickFiles': '选择文件',
|
||||
'ssh.zmodem.receiveDesc': '检测到 sz 下载请求(远端正在发送文件),请选择保存在本地的目录。',
|
||||
'ssh.zmodem.sendDesc': '检测到 rz 上传请求(远端正在接收文件),请选择要上传的文件。',
|
||||
|
||||
// 文件面板(SFTP)
|
||||
'ssh.file.up': '上一级',
|
||||
'ssh.file.refresh': '刷新',
|
||||
'ssh.file.uploadFile': '上传文件',
|
||||
'ssh.file.downloadSelected': '下载选中项',
|
||||
'ssh.file.permOwner': '权限 / 属主',
|
||||
'ssh.file.open': '打开',
|
||||
'ssh.file.download': '下载',
|
||||
'ssh.file.upload': '上传…',
|
||||
'ssh.file.rename': '重命名',
|
||||
'ssh.file.new': '新建',
|
||||
'ssh.file.newFolder': '新建文件夹',
|
||||
'ssh.file.copyPath': '复制路径',
|
||||
'ssh.file.copyPathFailed': '复制路径失败',
|
||||
'ssh.file.pathCopied': '已复制路径',
|
||||
'ssh.file.permission': '文件权限…',
|
||||
'ssh.file.deleteTitle': '确认删除?',
|
||||
'ssh.file.loading': '加载中…',
|
||||
'ssh.file.empty': '空目录',
|
||||
'ssh.file.modeUnavailable': '权限不可用',
|
||||
'ssh.file.folderName': '文件夹名称',
|
||||
'ssh.file.create': '创建',
|
||||
'ssh.file.renameTitle': '重命名 {name}',
|
||||
'ssh.file.permTitle': '权限 · {name}',
|
||||
'ssh.file.permApplied': '已应用权限',
|
||||
'ssh.file.octal': '八进制',
|
||||
'ssh.file.octalPlaceholder': '如 755',
|
||||
'ssh.file.keepEmpty': '不改则留空',
|
||||
'ssh.file.ownerHint': 'UID/GID 留空表示不修改属主',
|
||||
'ssh.file.permRowOwner': '所有者',
|
||||
'ssh.file.permRowGroup': '组',
|
||||
'ssh.file.permRowOther': '其他',
|
||||
'ssh.file.permColRead': '读',
|
||||
'ssh.file.permColWrite': '写',
|
||||
'ssh.file.permColExec': '执行',
|
||||
|
||||
// 系统监控
|
||||
'ssh.monitor.collecting': '采集中…',
|
||||
'ssh.monitor.interrupted': '采集中断:{error}',
|
||||
'ssh.monitor.mem': '内存',
|
||||
'ssh.monitor.disks': '磁盘',
|
||||
'ssh.monitor.net': '网络',
|
||||
'ssh.monitor.cores': '{n} 核',
|
||||
'ssh.monitor.loadavg': '负载 {value}',
|
||||
'ssh.monitor.uptime': '运行时间',
|
||||
'ssh.monitor.uptimeSeconds': '{n}秒',
|
||||
'ssh.monitor.uptimeMinutes': '{n}分钟',
|
||||
'ssh.monitor.uptimeHours': '{h}小时{m}分',
|
||||
'ssh.monitor.uptimeDays': '{n}天'
|
||||
}
|
||||
|
||||
export default ssh
|
||||
@@ -0,0 +1,26 @@
|
||||
/** 命名空间:terminal(终端视图:右键菜单、搜索、粘贴确认、工具条、提示)。归属:工作区/终端维护者。 */
|
||||
const terminal: Record<string, string> = {
|
||||
'terminal.menu.find': '查找',
|
||||
'terminal.menu.selectAll': '全选',
|
||||
'terminal.menu.clear': '清屏',
|
||||
'terminal.search.placeholder': '搜索',
|
||||
'terminal.search.prev': '上一个',
|
||||
'terminal.search.next': '下一个',
|
||||
'terminal.search.found': '已找到',
|
||||
'terminal.search.notFound': '未找到',
|
||||
'terminal.suggest.hint': '↑/↓ 选择 · Tab 接受 · Esc 关闭',
|
||||
'terminal.rec.start': '开始记录',
|
||||
'terminal.rec.stop': '停止记录',
|
||||
'terminal.rec.startLog': '开始记录会话日志',
|
||||
'terminal.rec.stopLog': '停止记录会话日志',
|
||||
'terminal.rec.openLogs': '打开日志目录',
|
||||
'terminal.rec.openCwd': '打开工作区目录',
|
||||
'terminal.paste.title': '确认粘贴',
|
||||
'terminal.paste.message': '检测到多行或潜在危险命令,确定要粘贴到终端吗?',
|
||||
'terminal.paste.noPrompt': '本次会话不再提示',
|
||||
'terminal.paste.disableDetection': '关闭后续粘贴检测',
|
||||
'terminal.paste.hint': '可在通用终端设置中重新开启或切换检测策略。',
|
||||
'terminal.dead.message': '进程已退出 (代码 {code})'
|
||||
}
|
||||
|
||||
export default terminal
|
||||
@@ -0,0 +1,60 @@
|
||||
/** 命名空间:workspace(工作区外壳:侧栏、标签、布局菜单、分屏、空状态)。归属:工作区维护者。 */
|
||||
const workspace: Record<string, string> = {
|
||||
'workspace.tab.terminalTitle': '终端 {n}',
|
||||
'workspace.tab.localTerminal': '本地终端',
|
||||
'workspace.tab.closeOthers': '关闭其他',
|
||||
'workspace.tab.closeRight': '关闭右侧',
|
||||
'workspace.tab.broadcastTarget': '广播目标',
|
||||
'workspace.tab.broadcastBadge': '播',
|
||||
'workspace.tab.addInSplit': '在此分屏中新建终端',
|
||||
'workspace.newTerminal': '新建终端',
|
||||
'workspace.empty.terminalTitle': '暂无终端',
|
||||
'workspace.empty.sshTitle': '暂无 SSH 会话',
|
||||
'workspace.empty.sshHint': '请从左侧服务器列表连接',
|
||||
'workspace.rail.hideSidebar': '收起侧栏',
|
||||
'workspace.rail.showSidebar': '展开侧栏',
|
||||
'workspace.rail.layout': '布局',
|
||||
'workspace.rail.settings': '设置',
|
||||
'workspace.rail.connecting': '正在连接…',
|
||||
'workspace.rail.terminalWorkspace': '终端工作区',
|
||||
'workspace.rail.sshWorkspace': 'SSH 工作区',
|
||||
'workspace.panel.hideSidebar': '收起侧边栏',
|
||||
'workspace.panel.showSidebar': '展开侧边栏',
|
||||
'workspace.layout.splitRight': '水平分屏',
|
||||
'workspace.layout.splitBelow': '垂直分屏',
|
||||
'workspace.layout.saveTemplate': '保存为模板',
|
||||
'workspace.layout.applyTemplate': '应用模板',
|
||||
'workspace.template.saveTitle': '保存布局模板',
|
||||
'workspace.template.namePlaceholder': '模板名称',
|
||||
'workspace.template.applyTitle': '应用布局模板',
|
||||
'workspace.template.empty': '暂无已保存的模板',
|
||||
'workspace.template.apply': '应用',
|
||||
'workspace.template.deleteConfirm': '删除该模板?',
|
||||
'workspace.broadcast.toggle': '广播输入',
|
||||
'workspace.broadcast.activeTitle': '广播中 ({count} 个目标)',
|
||||
'workspace.broadcast.popoverTerminal': '广播输入(终端)',
|
||||
'workspace.broadcast.popoverSsh': '广播输入(SSH)',
|
||||
'workspace.broadcast.switch': '广播开关',
|
||||
'workspace.broadcast.enabled': '已启用 ({count})',
|
||||
'workspace.broadcast.needTwo': '需至少选择 2 个目标',
|
||||
'workspace.broadcast.disabled': '未启用',
|
||||
'workspace.broadcast.emptySsh': '暂无 SSH 服务器会话',
|
||||
'workspace.broadcast.emptyTerminal': '暂无终端',
|
||||
'workspace.broadcast.hint': '选择 ≥2 个终端后广播自动开启;关闭任意一个使目标少于 2 个时自动关闭。仅当前模式组的会话可被勾选。',
|
||||
'workspace.hint.sshFromList': 'SSH 会话请从服务器列表连接',
|
||||
'workspace.hint.connectSshFirst': '请先连接 SSH 服务器',
|
||||
'workspace.hint.noActiveTerminal': '没有激活的终端:请至少打开一个本地终端或 SSH 会话',
|
||||
'workspace.hint.noSessionInPanel': '当前激活面板没有可用的会话',
|
||||
'workspace.connect.failed': 'SSH 连接失败',
|
||||
'workspace.connect.passwordTitle': '输入连接密码',
|
||||
'workspace.connect.passwordPlaceholder': '密码',
|
||||
'workspace.connect.passphraseTitle': '输入私钥口令',
|
||||
'workspace.connect.passphrasePlaceholder': '私钥口令',
|
||||
'workspace.connect.connecting': '连接中…',
|
||||
'workspace.connect.connectingNamed': '正在连接 {name}',
|
||||
'workspace.connect.action': '连接',
|
||||
'workspace.error.title': '界面出现异常',
|
||||
'workspace.error.reload': '重新加载'
|
||||
}
|
||||
|
||||
export default workspace
|
||||
@@ -0,0 +1,17 @@
|
||||
/** 命名空間:通用(i18n 基礎設施、通用按鈕與狀態)。歸屬:i18n 基礎設施維護者。 */
|
||||
const common: Record<string, string> = {
|
||||
'common.ok': '確定',
|
||||
'common.cancel': '取消',
|
||||
'common.close': '關閉',
|
||||
'common.save': '儲存',
|
||||
'common.delete': '刪除',
|
||||
'common.edit': '編輯',
|
||||
'common.add': '新增',
|
||||
'common.copy': '複製',
|
||||
'common.paste': '貼上',
|
||||
'common.reset': '恢復預設',
|
||||
'common.language': '介面語言',
|
||||
'common.languageDesc': '切換後立即預覽介面語言,儲存後永久生效。'
|
||||
}
|
||||
|
||||
export default common
|
||||
@@ -0,0 +1,18 @@
|
||||
import common from './common'
|
||||
import settings from './settings'
|
||||
import workspace from './workspace'
|
||||
import terminal from './terminal'
|
||||
import ssh from './ssh'
|
||||
import panels from './panels'
|
||||
import main from './main'
|
||||
|
||||
/** 繁體中文詞條。命名空間檔案依區域分工維護,詳見 src/shared/i18n/index.ts 的歸屬表。 */
|
||||
export default {
|
||||
...common,
|
||||
...settings,
|
||||
...workspace,
|
||||
...terminal,
|
||||
...ssh,
|
||||
...panels,
|
||||
...main
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/** 命名空間:main(主程序文案:系統匣、關閉詢問、更新器)。歸屬:主程序維護者。 */
|
||||
const main: Record<string, string> = {
|
||||
'main.tray.showWindow': '顯示主視窗',
|
||||
'main.tray.closeAction': '關閉按鈕行為',
|
||||
'main.tray.askEveryTime': '每次詢問',
|
||||
'main.tray.minimizeToTray': '最小化到系統匣',
|
||||
'main.tray.exitDirectly': '直接結束',
|
||||
'main.tray.exit': '結束',
|
||||
'main.tray.balloonTitle': '已最小化到系統匣',
|
||||
'main.tray.balloonContent': '終端機連線仍在背景執行,點擊系統匣圖示即可還原視窗。',
|
||||
'main.tray.closeTitle': '關閉 OpenTerminal',
|
||||
'main.tray.closeMessage': '要最小化到系統匣,還是直接結束?',
|
||||
'main.tray.closeDetail': '最小化到系統匣時,終端機連線會繼續執行。',
|
||||
'main.tray.rememberChoice': '記住我的選擇,不再詢問',
|
||||
|
||||
'main.updater.feedFailed': '國內來源: {gitea};GitHub: {github}',
|
||||
|
||||
'main.ssh.connectTimeout': '連線逾時 ({host}:{port})',
|
||||
'main.ssh.saveFingerprintFailed': '儲存主機指紋失敗: {detail}',
|
||||
'main.ssh.hostKeyRejected': '使用者拒絕了主機指紋',
|
||||
'main.ssh.connectFailed': '連線失敗 {host}:{port}: {detail}',
|
||||
'main.ssh.shellOpenFailed': '無法開啟 SSH shell ({host}:{port}): {detail}',
|
||||
'main.ssh.initFailed': 'SSH 連線初始化失敗 ({host}:{port}): {detail}',
|
||||
'main.ssh.readKeyFailed': '無法讀取私密金鑰檔案 {path}: {detail}',
|
||||
|
||||
'main.sftp.sessionGone': 'SSH 連線不存在或已中斷',
|
||||
'main.sftp.deleteFailed': '刪除失敗: {detail}',
|
||||
'main.sftp.invalidMode': '權限值無效: {mode}',
|
||||
'main.sftp.invalidUidGid': 'uid/gid 無效',
|
||||
'main.sftp.commandExitCode': '指令結束碼 {code}',
|
||||
'main.sftp.cancelled': '已取消',
|
||||
|
||||
'main.zmodem.transferFailed': '傳輸失敗',
|
||||
'main.zmodem.transferTimeout': '傳輸逾時',
|
||||
'main.zmodem.sendFailed': '傳送失敗',
|
||||
'main.zmodem.uploadFailed': '上傳失敗',
|
||||
'main.zmodem.receiveFailed': '接收失敗',
|
||||
'main.zmodem.abnormal': 'ZMODEM 傳輸異常',
|
||||
'main.zmodem.cancelled': '已取消',
|
||||
'main.zmodem.offerTimedOut': '未選擇檔案,已取消',
|
||||
'main.zmodem.sessionInvalid': '連線已失效',
|
||||
'main.zmodem.sessionCreateFailed': '無法建立 ZMODEM 連線',
|
||||
'main.zmodem.noSaveDir': '未指定儲存目錄',
|
||||
'main.zmodem.noFiles': '未選擇檔案',
|
||||
|
||||
'main.ipc.connectionMissing': '連線書籤不存在 ({id})',
|
||||
|
||||
'main.sysinfo.sessionGone': 'SSH 工作階段不存在或已中斷',
|
||||
'main.sysinfo.execFailed': 'SSH exec 失敗',
|
||||
'main.sysinfo.parseFailed': '解析失敗: {message}',
|
||||
'main.pty.serviceNotReady': 'SSH 工作階段服務尚未初始化',
|
||||
'main.pty.missingConnectionId': 'SSH 工作階段缺少 connectionId',
|
||||
'main.log.tuiOmitted': '全螢幕介面(TUI)輸出已省略'
|
||||
}
|
||||
|
||||
export default main
|
||||
@@ -0,0 +1,36 @@
|
||||
/** 命名空間:panels(命令面板、工作階段日誌面板、傳輸面板)。歸屬:SSH/面板維護者。 */
|
||||
const panels: Record<string, string> = {
|
||||
// 命令面板
|
||||
'panels.commands.sectionTitle': '命令',
|
||||
'panels.commands.target': '傳送目標',
|
||||
'panels.commands.targetSsh': 'SSH 伺服器',
|
||||
'panels.commands.targetTerminal': '終端機',
|
||||
'panels.commands.tabHistory': '歷史',
|
||||
'panels.commands.tabLibrary': '命令庫',
|
||||
'panels.commands.historyTitle': '歷史命令',
|
||||
'panels.commands.clearTitle': '清空全部命令歷史?',
|
||||
'panels.commands.clear': '清空',
|
||||
'panels.commands.noHistory': '尚無歷史命令',
|
||||
'panels.commands.loading': '載入中…',
|
||||
'panels.commands.libraryTitle': '命令庫',
|
||||
'panels.commands.libraryEmpty': '命令庫為空',
|
||||
'panels.commands.add': '新增命令',
|
||||
'panels.commands.name': '名稱',
|
||||
'panels.commands.optional': '(選填)',
|
||||
'panels.commands.command': '命令',
|
||||
'panels.commands.commandPlaceholder': '如 ls -la',
|
||||
'panels.commands.note': '備註',
|
||||
'panels.commands.deleteTitle': '刪除該命令?',
|
||||
'panels.commands.deleteAria': '刪除命令',
|
||||
|
||||
// 傳輸面板
|
||||
'panels.transfer.failed': '傳輸失敗',
|
||||
'panels.transfer.cancelled': '已取消',
|
||||
'panels.transfer.done': '傳輸完成',
|
||||
'panels.transfer.uploading': '上傳中',
|
||||
'panels.transfer.downloading': '下載中',
|
||||
'panels.transfer.zmodemUploading': 'ZMODEM 上傳中',
|
||||
'panels.transfer.zmodemDownloading': 'ZMODEM 下載中'
|
||||
}
|
||||
|
||||
export default panels
|
||||
@@ -0,0 +1,147 @@
|
||||
/** 命名空間:settings(設定對話框:字型/游標/渲染/高亮/主題/系統/關於)。歸屬:設定頁維護者。 */
|
||||
const settings: Record<string, string> = {
|
||||
'settings.title': '設定',
|
||||
'settings.tabs.font': '字型',
|
||||
'settings.tabs.cursor': '游標與捲動',
|
||||
'settings.tabs.render': '渲染與行為',
|
||||
'settings.tabs.highlight': '高亮',
|
||||
'settings.tabs.theme': '主題',
|
||||
'settings.tabs.system': '系統',
|
||||
'settings.tabs.about': '關於',
|
||||
'settings.resizeHandle': '拖曳調整大小',
|
||||
'settings.preview': '預覽',
|
||||
'settings.deleteConfirmDesc': '刪除後無法復原,確定要繼續嗎?',
|
||||
'settings.color.foreground': '前景',
|
||||
'settings.color.background': '背景',
|
||||
'settings.color.cursor': '游標',
|
||||
'settings.color.selection': '選取區',
|
||||
'settings.font.label': '字型',
|
||||
'settings.font.desc': '內建預設字型或系統等寬字型',
|
||||
'settings.font.placeholder': '選擇字型',
|
||||
'settings.font.default': '預設',
|
||||
'settings.font.size': '字型大小',
|
||||
'settings.font.sizeDesc': '終端文字的像素大小',
|
||||
'settings.font.weight': '字重',
|
||||
'settings.font.weightDesc': '400 為一般,700 為粗體',
|
||||
'settings.font.boldWeight': '粗體字重',
|
||||
'settings.font.boldWeightDesc': '粗體文字所使用的字重',
|
||||
'settings.font.letterSpacing': '字元間距',
|
||||
'settings.font.letterSpacingDesc': '字元之間的水平間距',
|
||||
'settings.font.lineHeight': '行高',
|
||||
'settings.font.lineHeightDesc': '相鄰兩行之間的垂直距離',
|
||||
'settings.cursor.blink': '游標閃爍',
|
||||
'settings.cursor.blinkDesc': '游標是否週期性閃爍',
|
||||
'settings.cursor.style': '游標樣式',
|
||||
'settings.cursor.styleDesc': '游標的顯示形狀',
|
||||
'settings.cursor.inactiveStyle': '非作用中游標樣式',
|
||||
'settings.cursor.inactiveStyleDesc': '視窗失焦時的游標樣式',
|
||||
'settings.cursor.scrollback': '捲動緩衝區',
|
||||
'settings.cursor.scrollbackDesc': '畫面上可往回捲動的行數',
|
||||
'settings.cursorStyle.bar': '直線 (bar)',
|
||||
'settings.cursorStyle.block': '方塊 (block)',
|
||||
'settings.cursorStyle.underline': '底線 (underline)',
|
||||
'settings.cursorStyle.outline': '外框 (outline)',
|
||||
'settings.cursorStyle.none': '無 (none)',
|
||||
'settings.rendererMode.auto': '自動',
|
||||
'settings.rendererMode.autoHint': '優先使用 WebGL 加速,失敗時自動退回 DOM 渲染',
|
||||
'settings.rendererMode.webgl': '高效能 WebGL',
|
||||
'settings.rendererMode.webglHint': '強制使用 GPU 加速渲染,適合高更新率與大量行數捲動',
|
||||
'settings.rendererMode.dom': '相容 DOM',
|
||||
'settings.rendererMode.domHint': '純 CPU 渲染,相容性最佳,適合沒有 GPU 或遠端桌面的環境',
|
||||
'settings.render.modeLabel': '渲染模式',
|
||||
'settings.render.modeHint': '終端儲存格的渲染加速方式,變更將套用到所有終端',
|
||||
'settings.render.autoWrap': '自動換行',
|
||||
'settings.render.autoWrapDesc': '超出寬度時自動折行',
|
||||
'settings.render.copyOnSelect': '選取即複製',
|
||||
'settings.render.copyOnSelectDesc': '以滑鼠選取文字時自動複製',
|
||||
'settings.render.pasteRiskConfirm': '貼上風險確認',
|
||||
'settings.render.pasteRiskConfirmDesc': '多行文字(或超長單行)貼上前彈出確認;單行直接貼上',
|
||||
'settings.render.suggest': '輸入建議',
|
||||
'settings.render.suggestDesc': '輸入時顯示指令建議;Tab 接受,Enter 一律直接執行',
|
||||
'settings.render.history': '記錄指令歷史',
|
||||
'settings.render.historyDesc': '關閉後不再記錄新指令;已儲存的歷史仍會保留',
|
||||
'settings.render.historyLimit': '歷史筆數上限',
|
||||
'settings.render.historyLimitDesc': '指令歷史最多保留幾筆,重複的指令只記一次',
|
||||
'settings.render.recButton': '終端工具列 · 錄製',
|
||||
'settings.render.recButtonDesc': '右上角顯示「記錄工作階段日誌」按鈕',
|
||||
'settings.render.openLogsButton': '終端工具列 · 開啟日誌目錄',
|
||||
'settings.render.openLogsButtonDesc': '右上角顯示「開啟日誌目錄」按鈕',
|
||||
'settings.render.openCwdButton': '終端工具列 · 開啟工作區目錄',
|
||||
'settings.render.openCwdButtonDesc':
|
||||
'右上角顯示「開啟目前目錄」按鈕(SSH 工作階段不顯示;目錄會隨 cd 即時追蹤,需開啟 shell 整合或使用 cd 指令)',
|
||||
'settings.system.launchAtLogin': '開機時自動啟動',
|
||||
'settings.system.launchAtLoginDesc': '開機時自動啟動程式(開發模式下註冊的是開發版程式)',
|
||||
'settings.system.preventSleep': '防止系統休眠',
|
||||
'settings.system.preventSleepDesc':
|
||||
'開啟後 OpenTerminal 會防止系統自動休眠;關閉則允許系統依本身的設定休眠',
|
||||
'settings.system.restoreSession': '啟動時還原上次工作階段',
|
||||
'settings.system.restoreSessionDesc':
|
||||
'下次啟動時還原分割版面,並讓每個終端回到上次所在的目錄;關閉則每次都以單一終端啟動',
|
||||
'settings.system.shellIntegration': 'Shell 整合',
|
||||
'settings.system.shellIntegrationDesc':
|
||||
'讓 shell 主動回報工作目錄(OSC 7),路徑記憶更精確(含指令碼內的 cd);會包裝你的命令提示字元,提示字元主題顯示異常時關閉即可',
|
||||
'settings.system.closeAction': '關閉按鈕行為',
|
||||
'settings.system.closeActionDesc':
|
||||
'點擊視窗關閉按鈕時的動作;最小化至系統匣後,可從系統匣圖示的右鍵選單結束',
|
||||
'settings.system.closeActionTray': '最小化至系統匣',
|
||||
'settings.system.closeActionExit': '直接結束',
|
||||
'settings.system.closeActionAsk': '每次詢問',
|
||||
'settings.system.globalShortcut': '全域喚出快速鍵',
|
||||
'settings.system.globalShortcutDesc': '點擊輸入框後直接按下組合鍵;Esc 取消,Backspace 清除並停用',
|
||||
'settings.system.globalShortcutHint':
|
||||
'搭配全域鍵可在任何畫面喚出/隱藏視窗;若註冊失敗(與其他軟體衝突)則不會生效,應用程式也不會報錯。',
|
||||
'settings.system.shortcutRecording': '請按下組合鍵…',
|
||||
'settings.system.shortcutPlaceholder': '點擊後按下快速鍵,留空為停用',
|
||||
'settings.highlight.alert':
|
||||
'自訂高亮可強化顯示效果,但會略微增加效能負擔。規則依優先順序套用。PS:高亮是在寫入終端時注入顏色,對既有的回捲內容不生效',
|
||||
'settings.highlight.enabled': '啟用',
|
||||
'settings.highlight.pattern': '正規表示式',
|
||||
'settings.highlight.patternPlaceholder': '例如 \\b(ERROR|FAILED)\\b',
|
||||
'settings.highlight.invalidRegex': '正規表示式無效',
|
||||
'settings.highlight.priority': '優先順序',
|
||||
'settings.highlight.priorityHint': '值越小越先套用',
|
||||
'settings.highlight.color': '顏色',
|
||||
'settings.highlight.clearBg': '清除',
|
||||
'settings.highlight.addBg': '新增',
|
||||
'settings.highlight.palette': '色盤',
|
||||
'settings.highlight.note': '備註',
|
||||
'settings.highlight.notePlaceholder': '規則說明(選填)',
|
||||
'settings.highlight.actions': '操作',
|
||||
'settings.highlight.addRule': '+ 新增規則',
|
||||
'settings.highlight.empty': '尚無高亮規則,點擊「+ 新增規則」建立',
|
||||
'settings.highlight.deleteTitle': '刪除高亮規則',
|
||||
'settings.highlight.resetTitle': '還原預設高亮規則',
|
||||
'settings.highlight.resetDesc': '會將目前所有規則取代為內建預設,無法復原。',
|
||||
'settings.highlight.resetOk': '還原',
|
||||
'settings.highlight.createTitle': '新增高亮規則',
|
||||
'settings.highlight.editTitle': '編輯高亮規則',
|
||||
'settings.theme.accent': '標籤強調色',
|
||||
'settings.theme.accentDesc': '作用中標籤的邊框、側邊欄指示條與 SSH 徽章的強調顏色',
|
||||
'settings.theme.customBadge': '自訂',
|
||||
'settings.theme.deleteTitle': '刪除自訂主題',
|
||||
'settings.theme.create': '新增主題',
|
||||
'settings.theme.editTitle': '編輯主題',
|
||||
'settings.themeEditor.name': '名稱',
|
||||
'settings.themeEditor.namePlaceholder': '主題名稱',
|
||||
'settings.themeEditor.copySuffix': '(副本)',
|
||||
'settings.about.currentVersion': '目前版本',
|
||||
'settings.about.statusIdle': '點擊檢查更新',
|
||||
'settings.about.statusChecking': '正在檢查更新…',
|
||||
'settings.about.statusAvailable': '發現新版本',
|
||||
'settings.about.statusLatest': '目前已是最新版本',
|
||||
'settings.about.statusDownloading': '正在下載…',
|
||||
'settings.about.statusDownloaded': '下載完成,可重新啟動安裝',
|
||||
'settings.about.statusError': '檢查失敗',
|
||||
'settings.about.statusDev': '開發模式不支援檢查更新',
|
||||
'settings.about.channelStable': '穩定更新通道',
|
||||
'settings.about.autoCheck': '啟動時自動檢查',
|
||||
'settings.about.download': '下載更新',
|
||||
'settings.about.downloadGithub': '(GitHub 來源)',
|
||||
'settings.about.install': '重新啟動安裝',
|
||||
'settings.about.check': '檢查更新',
|
||||
'settings.about.checkingButton': '檢查中',
|
||||
'settings.about.changelog': '更新日誌',
|
||||
'settings.about.changelogEmpty': '暫無更新日誌'
|
||||
}
|
||||
|
||||
export default settings
|
||||
@@ -0,0 +1,144 @@
|
||||
/** 命名空間:ssh(SSH 連線管理、主機金鑰、檔案面板、zmodem、系統監控)。歸屬:SSH 維護者。 */
|
||||
const ssh: Record<string, string> = {
|
||||
// 認證方式 / 金鑰種類
|
||||
'ssh.auth.password': '密碼',
|
||||
'ssh.auth.privateKey': '私鑰',
|
||||
'ssh.auth.agent': 'Agent',
|
||||
'ssh.secret.passphrase': '口令',
|
||||
|
||||
// 連線編輯對話框:認證相關欄位
|
||||
'ssh.fields.agentDesc': '使用本機 SSH Agent 中已載入的金鑰進行認證,無須在本應用程式內儲存任何金鑰。',
|
||||
'ssh.fields.askPasswordLabel': '連線時詢問密碼',
|
||||
'ssh.fields.askPasswordHint': '開啟後每次連線彈出對話框輸入密碼,不再使用已儲存的密碼',
|
||||
'ssh.fields.passwordPlaceholder': '編輯時留空表示保留已儲存的密碼',
|
||||
'ssh.fields.keyPath': '私鑰路徑(伺服器上的本機私鑰路徑,可留空)',
|
||||
'ssh.fields.keyContent': '私鑰內容',
|
||||
'ssh.fields.keyContentPlaceholder':
|
||||
'貼上私鑰內容;留空則使用上面的路徑(編輯時留空表示保留已儲存的私鑰)',
|
||||
'ssh.fields.askPassphraseLabel': '連線時詢問口令',
|
||||
'ssh.fields.askPassphraseHint': '開啟後每次連線提示輸入私鑰口令',
|
||||
'ssh.fields.passphrase': '私鑰口令',
|
||||
'ssh.fields.passphrasePlaceholder': '編輯時留空表示保留已儲存的口令',
|
||||
|
||||
// 連線編輯對話框
|
||||
'ssh.dialog.titleEdit': '編輯連線',
|
||||
'ssh.dialog.titleNew': '新增連線',
|
||||
'ssh.dialog.saveFailed': '儲存失敗,請檢查輸入後重試',
|
||||
'ssh.dialog.name': '名稱',
|
||||
'ssh.dialog.nameRequired': '請輸入連線名稱',
|
||||
'ssh.dialog.namePlaceholder': '例如:正式環境伺服器',
|
||||
'ssh.dialog.group': '分組',
|
||||
'ssh.dialog.groupPlaceholder': '選擇或輸入新分組,留空歸入「預設」',
|
||||
'ssh.dialog.host': '主機',
|
||||
'ssh.dialog.hostRequired': '請輸入主機位址',
|
||||
'ssh.dialog.hostPlaceholder': '192.168.1.10 或 example.com',
|
||||
'ssh.dialog.port': '連接埠',
|
||||
'ssh.dialog.portRange': '連接埠需在 1–65535 之間',
|
||||
'ssh.dialog.username': '使用者名稱',
|
||||
'ssh.dialog.usernameRequired': '請輸入使用者名稱',
|
||||
'ssh.dialog.authMethod': '認證方式',
|
||||
'ssh.dialog.savedSecret': '已儲存{kind},留空將保留原值',
|
||||
'ssh.dialog.keepalive': 'Keepalive 間隔(秒)',
|
||||
'ssh.dialog.keepaliveTooltip': '0 表示關閉 keepalive',
|
||||
'ssh.dialog.keepaliveMin': '不能為負數',
|
||||
|
||||
// 連線側欄
|
||||
'ssh.sidebar.defaultGroup': '預設',
|
||||
'ssh.sidebar.timeJustNow': '剛剛',
|
||||
'ssh.sidebar.timeMinutesAgo': '{n} 分鐘前',
|
||||
'ssh.sidebar.timeHoursAgo': '{n} 小時前',
|
||||
'ssh.sidebar.timeDaysAgo': '{n} 天前',
|
||||
'ssh.sidebar.modeTerminal': '終端機工作區',
|
||||
'ssh.sidebar.modeSsh': 'SSH 工作區',
|
||||
'ssh.sidebar.title': '連線',
|
||||
'ssh.sidebar.newConnection': '新增連線',
|
||||
'ssh.sidebar.sectionTerminals': '終端機',
|
||||
'ssh.sidebar.noLocalTerminals': '沒有開啟的本機終端機',
|
||||
'ssh.sidebar.local': '本機',
|
||||
'ssh.sidebar.sectionServers': 'SSH 伺服器',
|
||||
'ssh.sidebar.empty': '尚無連線,點擊+新增',
|
||||
'ssh.sidebar.loading': '載入中…',
|
||||
'ssh.sidebar.recent': '最近工作階段',
|
||||
'ssh.sidebar.dblClickConnect': '雙擊連線 {host}',
|
||||
'ssh.sidebar.deleteTitle': '刪除該連線?',
|
||||
'ssh.sidebar.deleteDesc': '連線設定刪除後無法復原。已儲存的金鑰資料會一併刪除。',
|
||||
|
||||
// 主機金鑰確認
|
||||
'ssh.hostKey.changedTitle': '主機指紋已變更!',
|
||||
'ssh.hostKey.unknownHost': '未知主機',
|
||||
'ssh.hostKey.accept': '接受並連線',
|
||||
'ssh.hostKey.reject': '拒絕',
|
||||
'ssh.hostKey.mitmTitle': '可能遭受中間人攻擊',
|
||||
'ssh.hostKey.mitmDesc':
|
||||
'遠端主機的金鑰指紋與先前記錄的不一致。如果這不是您本人更換了伺服器金鑰,可能有人正在冒充該主機。',
|
||||
'ssh.hostKey.firstConnect': '首次連線該主機,尚未記錄其指紋。',
|
||||
'ssh.hostKey.target': '主機:{target}',
|
||||
'ssh.hostKey.fingerprint': '指紋:{fingerprint}',
|
||||
|
||||
// SSH 工作區:檔案面板容器、主機徽章
|
||||
'ssh.bottomPanel.resize': '調整檔案面板高度',
|
||||
'ssh.hostBadge.aria': 'SSH 主機 {label}',
|
||||
|
||||
// ZMODEM
|
||||
'ssh.zmodem.done': 'ZMODEM 傳輸完成',
|
||||
'ssh.zmodem.failed': 'ZMODEM 傳輸失敗:{message}',
|
||||
'ssh.zmodem.unknownError': '未知錯誤',
|
||||
'ssh.zmodem.titleReceive': '下載到本機',
|
||||
'ssh.zmodem.titleSend': '上傳到伺服器',
|
||||
'ssh.zmodem.pickDir': '選擇儲存目錄',
|
||||
'ssh.zmodem.pickFiles': '選擇檔案',
|
||||
'ssh.zmodem.receiveDesc': '偵測到 sz 下載請求(遠端正在傳送檔案),請選擇儲存在本機的目錄。',
|
||||
'ssh.zmodem.sendDesc': '偵測到 rz 上傳請求(遠端正在接收檔案),請選擇要上傳的檔案。',
|
||||
|
||||
// 檔案面板(SFTP)
|
||||
'ssh.file.up': '上一層',
|
||||
'ssh.file.refresh': '重新整理',
|
||||
'ssh.file.uploadFile': '上傳檔案',
|
||||
'ssh.file.downloadSelected': '下載選取項目',
|
||||
'ssh.file.permOwner': '權限 / 擁有者',
|
||||
'ssh.file.open': '開啟',
|
||||
'ssh.file.download': '下載',
|
||||
'ssh.file.upload': '上傳…',
|
||||
'ssh.file.rename': '重新命名',
|
||||
'ssh.file.new': '新增',
|
||||
'ssh.file.newFolder': '新增資料夾',
|
||||
'ssh.file.copyPath': '複製路徑',
|
||||
'ssh.file.copyPathFailed': '複製路徑失敗',
|
||||
'ssh.file.pathCopied': '已複製路徑',
|
||||
'ssh.file.permission': '檔案權限…',
|
||||
'ssh.file.deleteTitle': '確認刪除?',
|
||||
'ssh.file.loading': '載入中…',
|
||||
'ssh.file.empty': '空目錄',
|
||||
'ssh.file.modeUnavailable': '權限不可用',
|
||||
'ssh.file.folderName': '資料夾名稱',
|
||||
'ssh.file.create': '建立',
|
||||
'ssh.file.renameTitle': '重新命名 {name}',
|
||||
'ssh.file.permTitle': '權限 · {name}',
|
||||
'ssh.file.permApplied': '已套用權限',
|
||||
'ssh.file.octal': '八進位',
|
||||
'ssh.file.octalPlaceholder': '如 755',
|
||||
'ssh.file.keepEmpty': '不修改則留空',
|
||||
'ssh.file.ownerHint': 'UID/GID 留空表示不修改擁有者',
|
||||
'ssh.file.permRowOwner': '擁有者',
|
||||
'ssh.file.permRowGroup': '群組',
|
||||
'ssh.file.permRowOther': '其他',
|
||||
'ssh.file.permColRead': '讀取',
|
||||
'ssh.file.permColWrite': '寫入',
|
||||
'ssh.file.permColExec': '執行',
|
||||
|
||||
// 系統監控
|
||||
'ssh.monitor.collecting': '採集中…',
|
||||
'ssh.monitor.interrupted': '採集中斷:{error}',
|
||||
'ssh.monitor.mem': '記憶體',
|
||||
'ssh.monitor.disks': '磁碟',
|
||||
'ssh.monitor.net': '網路',
|
||||
'ssh.monitor.cores': '{n} 核心',
|
||||
'ssh.monitor.loadavg': '負載 {value}',
|
||||
'ssh.monitor.uptime': '運作時間',
|
||||
'ssh.monitor.uptimeSeconds': '{n} 秒',
|
||||
'ssh.monitor.uptimeMinutes': '{n} 分鐘',
|
||||
'ssh.monitor.uptimeHours': '{h} 小時 {m} 分',
|
||||
'ssh.monitor.uptimeDays': '{n} 天'
|
||||
}
|
||||
|
||||
export default ssh
|
||||
@@ -0,0 +1,26 @@
|
||||
/** 命名空間:terminal(終端機檢視:右鍵選單、搜尋、貼上確認、工具列、提示)。歸屬:工作區/終端機維護者。 */
|
||||
const terminal: Record<string, string> = {
|
||||
'terminal.menu.find': '尋找',
|
||||
'terminal.menu.selectAll': '全選',
|
||||
'terminal.menu.clear': '清除畫面',
|
||||
'terminal.search.placeholder': '搜尋',
|
||||
'terminal.search.prev': '上一個',
|
||||
'terminal.search.next': '下一個',
|
||||
'terminal.search.found': '已找到',
|
||||
'terminal.search.notFound': '未找到',
|
||||
'terminal.suggest.hint': '↑/↓ 選擇 · Tab 接受 · Esc 關閉',
|
||||
'terminal.rec.start': '開始錄製',
|
||||
'terminal.rec.stop': '停止錄製',
|
||||
'terminal.rec.startLog': '開始錄製工作階段日誌',
|
||||
'terminal.rec.stopLog': '停止錄製工作階段日誌',
|
||||
'terminal.rec.openLogs': '開啟日誌目錄',
|
||||
'terminal.rec.openCwd': '開啟工作區目錄',
|
||||
'terminal.paste.title': '確認貼上',
|
||||
'terminal.paste.message': '偵測到多行或潛在危險命令,確定要貼到終端機嗎?',
|
||||
'terminal.paste.noPrompt': '本次工作階段不再提示',
|
||||
'terminal.paste.disableDetection': '關閉後續貼上偵測',
|
||||
'terminal.paste.hint': '可在一般終端機設定中重新開啟或切換偵測策略。',
|
||||
'terminal.dead.message': '處理程序已結束 (代碼 {code})'
|
||||
}
|
||||
|
||||
export default terminal
|
||||
@@ -0,0 +1,60 @@
|
||||
/** 命名空間:workspace(工作區外殼:側邊欄、分頁、版面配置選單、分割、空狀態)。歸屬:工作區維護者。 */
|
||||
const workspace: Record<string, string> = {
|
||||
'workspace.tab.terminalTitle': '終端機 {n}',
|
||||
'workspace.tab.localTerminal': '本機終端機',
|
||||
'workspace.tab.closeOthers': '關閉其他',
|
||||
'workspace.tab.closeRight': '關閉右側',
|
||||
'workspace.tab.broadcastTarget': '廣播目標',
|
||||
'workspace.tab.broadcastBadge': '播',
|
||||
'workspace.tab.addInSplit': '在此分割中新增終端機',
|
||||
'workspace.newTerminal': '新增終端機',
|
||||
'workspace.empty.terminalTitle': '尚無終端機',
|
||||
'workspace.empty.sshTitle': '尚無 SSH 工作階段',
|
||||
'workspace.empty.sshHint': '請從左側伺服器清單連線',
|
||||
'workspace.rail.hideSidebar': '收合側邊欄',
|
||||
'workspace.rail.showSidebar': '展開側邊欄',
|
||||
'workspace.rail.layout': '版面配置',
|
||||
'workspace.rail.settings': '設定',
|
||||
'workspace.rail.connecting': '連線中…',
|
||||
'workspace.rail.terminalWorkspace': '終端機工作區',
|
||||
'workspace.rail.sshWorkspace': 'SSH 工作區',
|
||||
'workspace.panel.hideSidebar': '收合側邊欄',
|
||||
'workspace.panel.showSidebar': '展開側邊欄',
|
||||
'workspace.layout.splitRight': '水平分割',
|
||||
'workspace.layout.splitBelow': '垂直分割',
|
||||
'workspace.layout.saveTemplate': '儲存為範本',
|
||||
'workspace.layout.applyTemplate': '套用範本',
|
||||
'workspace.template.saveTitle': '儲存版面配置範本',
|
||||
'workspace.template.namePlaceholder': '範本名稱',
|
||||
'workspace.template.applyTitle': '套用版面配置範本',
|
||||
'workspace.template.empty': '尚無已儲存的範本',
|
||||
'workspace.template.apply': '套用',
|
||||
'workspace.template.deleteConfirm': '刪除這個範本?',
|
||||
'workspace.broadcast.toggle': '廣播輸入',
|
||||
'workspace.broadcast.activeTitle': '廣播中({count} 個目標)',
|
||||
'workspace.broadcast.popoverTerminal': '廣播輸入(終端機)',
|
||||
'workspace.broadcast.popoverSsh': '廣播輸入(SSH)',
|
||||
'workspace.broadcast.switch': '廣播開關',
|
||||
'workspace.broadcast.enabled': '已啟用({count})',
|
||||
'workspace.broadcast.needTwo': '需至少選擇 2 個目標',
|
||||
'workspace.broadcast.disabled': '未啟用',
|
||||
'workspace.broadcast.emptySsh': '尚無 SSH 伺服器工作階段',
|
||||
'workspace.broadcast.emptyTerminal': '尚無終端機',
|
||||
'workspace.broadcast.hint': '選擇 ≥2 個終端機後會自動開啟廣播;關閉任一個使目標少於 2 個時會自動關閉。僅目前模式群組的工作階段可被勾選。',
|
||||
'workspace.hint.sshFromList': 'SSH 工作階段請從伺服器清單連線',
|
||||
'workspace.hint.connectSshFirst': '請先連線 SSH 伺服器',
|
||||
'workspace.hint.noActiveTerminal': '沒有作用中的終端機:請至少開啟一個本機終端機或 SSH 工作階段',
|
||||
'workspace.hint.noSessionInPanel': '目前作用中的面板沒有可用的工作階段',
|
||||
'workspace.connect.failed': 'SSH 連線失敗',
|
||||
'workspace.connect.passwordTitle': '輸入連線密碼',
|
||||
'workspace.connect.passwordPlaceholder': '密碼',
|
||||
'workspace.connect.passphraseTitle': '輸入私密金鑰密語',
|
||||
'workspace.connect.passphrasePlaceholder': '私密金鑰密語',
|
||||
'workspace.connect.connecting': '連線中…',
|
||||
'workspace.connect.connectingNamed': '正在連線 {name}',
|
||||
'workspace.connect.action': '連線',
|
||||
'workspace.error.title': '介面發生異常',
|
||||
'workspace.error.reload': '重新載入'
|
||||
}
|
||||
|
||||
export default workspace
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Tiny dependency-free i18n core, shared by the renderer and the main process.
|
||||
*
|
||||
* Dictionaries are flat `key -> text` maps split by namespace, one file per
|
||||
* language per namespace (`dicts/<lang>/<namespace>.ts`). Ownership map — each
|
||||
* namespace is translated by whoever owns that area, so parallel work never
|
||||
* edits the same file:
|
||||
*
|
||||
* common — i18n plumbing: language names, generic buttons/status
|
||||
* settings — the settings dialog (font/cursor/render/highlight/theme/system/about)
|
||||
* workspace — workspace shell: sidebar, tabs, layout menu, split, empty state
|
||||
* terminal — terminal view internals: context menu, search, paste confirm, toolbar
|
||||
* ssh — ssh connections, host key prompt, file panel, zmodem, monitor
|
||||
* panels — command panel, session-log panel, transfer panel
|
||||
* main — main-process strings: tray, close prompt, updater
|
||||
*
|
||||
* Missing keys fall back to zh-CN, then to the key itself (so a missing
|
||||
* translation is visible, never blank).
|
||||
*/
|
||||
|
||||
import zhCN from './dicts/zh-CN'
|
||||
import zhTW from './dicts/zh-TW'
|
||||
import en from './dicts/en'
|
||||
import ja from './dicts/ja'
|
||||
|
||||
export type Language = 'zh-CN' | 'zh-TW' | 'en' | 'ja'
|
||||
|
||||
export interface LanguageOption {
|
||||
value: Language
|
||||
/** Language names are shown in their own script, so this is not translated. */
|
||||
label: string
|
||||
}
|
||||
|
||||
export const LANGUAGES: LanguageOption[] = [
|
||||
{ value: 'zh-CN', label: '简体中文' },
|
||||
{ value: 'zh-TW', label: '繁體中文' },
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'ja', label: '日本語' }
|
||||
]
|
||||
|
||||
export const DEFAULT_LANGUAGE: Language = 'zh-CN'
|
||||
|
||||
export function isLanguage(value: unknown): value is Language {
|
||||
return typeof value === 'string' && LANGUAGES.some((l) => l.value === value)
|
||||
}
|
||||
|
||||
export type Dict = Record<string, string>
|
||||
|
||||
const DICTS: Record<Language, Dict> = {
|
||||
'zh-CN': zhCN,
|
||||
'zh-TW': zhTW,
|
||||
en,
|
||||
ja
|
||||
}
|
||||
|
||||
let current: Language = DEFAULT_LANGUAGE
|
||||
const listeners = new Set<(lang: Language) => void>()
|
||||
|
||||
/** Switch the active language and notify subscribers (renderer re-render,
|
||||
* main-process tray rebuild). Both processes call this on settings load/save. */
|
||||
export function setLanguage(lang: Language): void {
|
||||
if (current === lang) return
|
||||
current = lang
|
||||
for (const listener of listeners) listener(lang)
|
||||
}
|
||||
|
||||
export function getLanguage(): Language {
|
||||
return current
|
||||
}
|
||||
|
||||
export function onLanguageChange(cb: (lang: Language) => void): () => void {
|
||||
listeners.add(cb)
|
||||
return () => listeners.delete(cb)
|
||||
}
|
||||
|
||||
/** Translate `key`; `{name}` placeholders are filled from `vars`. */
|
||||
export function t(key: string, vars?: Record<string, string | number>): string {
|
||||
const raw = DICTS[current][key] ?? DICTS[DEFAULT_LANGUAGE][key] ?? key
|
||||
if (!vars) return raw
|
||||
return raw.replace(/\{(\w+)\}/g, (match, name: string) =>
|
||||
vars[name] === undefined ? match : String(vars[name])
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { TerminalTheme } from './theme'
|
||||
import type { Language } from './i18n'
|
||||
|
||||
/** One terminal keyword-highlight rule (regex → ANSI color injection). */
|
||||
export interface HighlightRule {
|
||||
@@ -72,6 +73,8 @@ export interface SystemSettings {
|
||||
* to parsing typed `cd` commands.
|
||||
*/
|
||||
shellIntegration?: boolean
|
||||
/** interface language (see @shared/i18n); missing = 简体中文 */
|
||||
language?: Language
|
||||
}
|
||||
|
||||
export interface AppSettings {
|
||||
@@ -133,5 +136,5 @@ export const DEFAULT_SETTINGS: AppSettings = {
|
||||
},
|
||||
customThemes: [],
|
||||
highlightRules: DEFAULT_HIGHLIGHT_RULES,
|
||||
system: { launchAtLogin: false, preventSleep: false, globalShowHide: '', closeAction: 'tray', autoCheckUpdate: true, restoreSession: true, shellIntegration: false }
|
||||
system: { launchAtLogin: false, preventSleep: false, globalShowHide: '', closeAction: 'tray', autoCheckUpdate: true, restoreSession: true, shellIntegration: false, language: 'zh-CN' }
|
||||
}
|
||||
Reference in new issue
Block a user