60 Commits

Author SHA1 Message Date
LukeGus
c7872770a1 feat: begin dashboard overhaul by splitting into cards and adding customization 2026-01-16 03:08:10 -06:00
LukeGus
004ddcb2bb feat: added -r and -l support for tunnels 2026-01-15 02:23:13 -06:00
Aditya Tawade
8eeef84b8a Enter Key for Quick Login (#513) 2026-01-15 02:03:04 -06:00
LukeGus
dc88ae5e8b feat: added quick connection system (ad-hoc) 2026-01-15 02:02:48 -06:00
LukeGus
cb478477e9 feat: add copy password button and fixed new line carriage issues and backend crash for auth key 2026-01-15 01:40:02 -06:00
LukeGus
b7bd1e50b3 feat: fix sudo password dialog ui, add totp/pass reset limiting, and refreshed users screen when auth is outdated 2026-01-14 18:14:51 -06:00
ZacharyZcR
230ab2f737 fix: add sudo support for listFiles and improve permission error handling (#512)
* feat: add sudo support for file manager operations

* fix: add sudo support for listFiles and improve permission error handling

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
2026-01-14 17:54:27 -06:00
ZacharyZcR
042bf255ef feat: add sudo support for file manager operations (#509) 2026-01-14 14:54:20 -06:00
ZacharyZcR
f7e99b5af5 feat: add toggle for password reset feature in admin settings (#508) 2026-01-14 14:49:38 -06:00
LukeGus
8fa093ae60 feat: re-added missing users.ts route from merge 2026-01-14 14:48:58 -06:00
LukeGus
dd62b77c79 feat: added sidebar management and improved some host manager UI/UX 2026-01-14 01:23:58 -06:00
LukeGus
264682c5ad feat: added close button on tab dropdown 2026-01-14 00:26:55 -06:00
LukeGus
7210381f17 feat: added toggle for command pallete 2026-01-13 23:57:21 -06:00
LukeGus
c0f4f1d74b feat: update credential editor to use submitting system and add health monitor 2026-01-13 23:48:58 -06:00
LukeGus
f957959a86 feat: update readme 2026-01-13 01:17:48 -06:00
LukeGus
a54dbe5b46 feat: update readme 2026-01-13 01:09:59 -06:00
Luke Gustafson
ac1cf82bba New Crowdin updates (#506)
* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Afrikaans)

* New translations en.json (Arabic)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Serbian (Cyrillic))

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (English)

* New translations en.json (Vietnamese)

* New translations en.json (German)

* New translations en.json (Norwegian)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Arabic)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Swedish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Finnish)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Bulgarian)

* New translations en.json (Indonesian)

* New translations en.json (Hindi)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Afrikaans)

* New translations en.json (Arabic)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Dutch)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Serbian (Cyrillic))

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Vietnamese)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Bulgarian)

* New translations en.json (Indonesian)

* New translations en.json (Hindi)

* New translations en.json (Bengali)

* New translations en.json (Thai)
2026-01-13 00:55:19 -06:00
LukeGus
de556e3911 feat: remove locales 2026-01-13 00:55:10 -06:00
LukeGus
9be6b945c8 feat: add crowdin i18n 2026-01-13 00:39:35 -06:00
Luke Gustafson
1aebbee21e New Crowdin updates (#505)
* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Afrikaans)

* New translations en.json (Arabic)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Serbian (Cyrillic))

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (English)

* New translations en.json (Vietnamese)

* New translations en.json (German)

* New translations en.json (Norwegian)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Arabic)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Swedish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Finnish)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Bulgarian)

* New translations en.json (Indonesian)

* New translations en.json (Hindi)
2026-01-13 00:09:26 -06:00
ZacharyZcR
80c09aef7d feat: add option to disable update checker (#502)
* feat: add option to disable update checker

Add a new setting in User Profile > Settings to disable automatic
update checking on startup and dashboard.

- Adds 'Disable Update Check' toggle in profile settings
- Skips GitHub API calls when disabled (reduces network requests)
- Works for both web app and Electron client

Fixes Termix-SSH/Support#410

* feat: remove locales

---------

Co-authored-by: LukeGus <bugattiguy527@gmail.com>
2026-01-13 00:02:23 -06:00
Luke Gustafson
115a1fd7f0 New Crowdin updates (#504)
* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Afrikaans)

* New translations en.json (Arabic)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Serbian (Cyrillic))

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (English)

* New translations en.json (Vietnamese)

* New translations en.json (German)

* New translations en.json (Norwegian)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Arabic)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Swedish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Finnish)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)
2026-01-12 23:59:17 -06:00
LukeGus
a1c260ad22 Merge remote-tracking branch 'origin/dev-1.10.1' into dev-1.10.1 2026-01-12 23:58:52 -06:00
LukeGus
18aa4f4877 feat: remove locales 2026-01-12 23:58:45 -06:00
ZacharyZcR
8fc038e59b feat: add Ctrl+Alt key remapping for browser-blocked shortcuts (#501)
Browsers intercept Ctrl+W/T/N/Q, making them unusable in terminal.
This adds Ctrl+Alt+<key> as an alternative that sends Ctrl+<key>.

- Ctrl+Alt+W → Ctrl+W (nano search, delete word)
- Ctrl+Alt+T → Ctrl+T (transpose chars)
- Ctrl+Alt+N → Ctrl+N (next line)
- Ctrl+Alt+Q → Ctrl+Q (XON flow control)

Fixes Termix-SSH/Support#407
2026-01-12 23:58:13 -06:00
ZacharyZcR
aea87be4d3 feat: support URL routes to open terminal directly (#156) (#503)
* fix: resolve merge conflict artifacts in dev-1.10.1

- Fix missing closing tags in AppView.tsx NetworkGraphView
- Fix incomplete catch blocks in server-stats.ts and db/index.ts
- Fix missing closing brace in en.json ports section
- Fix HostManagerApp.tsx import path
- Fix stats-widgets.ts type definition
- Fix schema.ts networkTopology table definition
- Add type annotations in user-data-import.ts

* feat: support URL routes to open terminal directly (#156)

- Add /terminal/{hostNameOrId} route for new format
- Keep /hosts/{id}/terminal for backward compatibility
- Smart detection: numeric IDs for ID lookup, otherwise name lookup
- Clean URL after opening to prevent duplicate on refresh
- Show toast error when host not found

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
2026-01-12 23:57:09 -06:00
LukeGus
7caa32b364 feat: remove locales 2026-01-12 23:41:28 -06:00
LukeGus
868ac39b71 feat: add workflow/config to auto generate openapi json 2026-01-12 19:28:25 -06:00
LukeGus
8ae8520c44 feat: fix network stats merge and add openapi jsdocs comments 2026-01-12 19:12:08 -06:00
Luke Gustafson
8ce4c6f364 Merge pull request #478 from SteveJos/feature/add-network-graph
Feature request: Network graph
2026-01-12 03:06:02 -05:00
Luke Gustafson
a9a1a4b3d5 Merge branch 'dev-1.10.1' into feature/add-network-graph 2026-01-12 03:05:50 -05:00
ZacharyZcR
2e3f7e10c7 feat: add listening ports widget for server stats (#483)
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
2026-01-12 01:46:05 -06:00
Luke Gustafson
d821373b15 New Crowdin updates (#472)
* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Afrikaans)

* New translations en.json (Arabic)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Dutch)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Serbian (Cyrillic))

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (English)

* New translations en.json (Vietnamese)

* New translations en.json (German)
2026-01-12 01:41:46 -06:00
Nunzio Marfè
816172d67b Feature: PWA (#479)
* feat: add PWA support with offline capabilities

- Add web app manifest with icons and theme configuration
- Add service worker with cache-first strategy for static assets
- Add useServiceWorker hook for SW registration
- Add PWA meta tags and Apple-specific tags to index.html
- Update vite.config.ts for optimal asset caching

* Update package-lock.json
2026-01-12 01:36:03 -06:00
ZacharyZcR
ceff07c685 feat: add firewall status widget for server stats (#484) 2026-01-12 01:31:21 -06:00
ZacharyZcR
1eb28dec8b fix: skip existing hosts and credentials during JSON import (#485)
Added duplicate detection for SSH hosts (by ip+port+username) and
credentials (by name) during import. Existing items are now skipped
by default, or updated if replaceExisting option is enabled.

This matches the existing behavior of importDismissedAlerts.

Fixes #389
2026-01-12 01:31:04 -06:00
ZacharyZcR
2b6361cbb6 fix: nginx permission denied on restricted kernels (#486) 2026-01-12 01:30:51 -06:00
ZacharyZcR
e6870f962a fix: delete all related data when removing user (#487) 2026-01-12 01:30:40 -06:00
ZacharyZcR
99b0181c45 fix: set default lineHeight to 1.0 for TUI apps compatibility (#488) 2026-01-12 01:30:27 -06:00
ZacharyZcR
58945288e0 fix: add shell creation timeout and improve error handling (#489) 2026-01-12 01:30:13 -06:00
ZacharyZcR
afb66a1098 fix: prevent session reset when updating host properties (#490) 2026-01-12 01:30:01 -06:00
ZacharyZcR
5f080be4ee fix: use correct MIME types for image preview (#491) 2026-01-12 01:29:35 -06:00
ZacharyZcR
4648549e74 fix: owner should not be marked as shared when host is shared to their role (#492) 2026-01-12 01:29:24 -06:00
ZacharyZcR
f5d948aa45 feat: add Docker container healthcheck (#493) 2026-01-12 01:29:02 -06:00
ZacharyZcR
81d506afba fix: restore SSH connection timeout to 120s for 2FA authentication (#494)
The timeout was reduced from 120s to 30s in v1.10, causing 2FA login
failures. Users with keyboard-interactive authentication (TOTP/2FA)
need sufficient time to enter their verification codes before the
SSH connection times out.

Fixes #404
2026-01-12 01:28:38 -06:00
ZacharyZcR
4150faa558 fix: use SFTP readdir for file listing to support non-Linux systems (#495)
The file manager now uses SFTP readdir as the primary method for
listing files, with ls -la as a fallback. This enables compatibility
with MikroTik RouterOS and other non-Linux systems that don't have
standard shell commands.

Fixes #317
2026-01-12 01:28:17 -06:00
ZacharyZcR
7ecfb4d685 fix: prevent long container names from overflowing card (#496)
Added min-w-0 to CardTitle to allow text truncation in flexbox.
Without this, flex items have min-width: auto which prevents
the truncate class from working properly.

Fixes #411
2026-01-12 01:27:58 -06:00
LukeGus
614f2f84ec fix: update readme 2026-01-12 00:29:14 -06:00
LukeGus
af63fe1b7b Merge remote-tracking branch 'origin/dev-1.10.1' into dev-1.10.1 2026-01-12 00:22:09 -06:00
LukeGus
4896b71b01 fix: remove top tech 2026-01-12 00:21:59 -06:00
Nunzio Marfè
69f3f88ae5 Handle enter button (#481)
* Update Crowdin configuration file

* Update Crowdin configuration file

* Update Linux Portable section with AUR link (#474)

* fix: file manager incorrectly decoding/encoding when editing files (#476)

* fix: electron build errors and skip macos job

* fix: testflight submit failure

* fix: made submit job match build type

* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)

* Update Crowdin configuration file

* Update Crowdin configuration file

* fix: resolve Vite build warnings for mixed static/dynamic imports

- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
  - react-vendor: React and React DOM
  - ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
  - monaco: Monaco Editor
  - codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB

This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI <ci@termix.dev>
Co-authored-by: Claude <noreply@anthropic.com>

* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)

---------

Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI <ci@termix.dev>
Co-authored-by: Claude <noreply@anthropic.com>

* fix: build error on docker (#477)

* fix: electron build errors and skip macos job

* fix: testflight submit failure

* fix: made submit job match build type

* fix: resolve Vite build warnings for mixed static/dynamic imports (#473)

* Update Crowdin configuration file

* Update Crowdin configuration file

* fix: resolve Vite build warnings for mixed static/dynamic imports

- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
  - react-vendor: React and React DOM
  - ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
  - monaco: Monaco Editor
  - codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB

This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI <ci@termix.dev>
Co-authored-by: Claude <noreply@anthropic.com>

* fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent)

* fix: build error on docker

---------

Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI <ci@termix.dev>
Co-authored-by: Claude <noreply@anthropic.com>

* Increase max old space size for npm builds

* Increase Node.js memory limit in Dockerfile

* Remove NODE_OPTIONS from build commands in Dockerfile

* Change runner to blacksmith-4vcpu-ubuntu-2404

* fix: build error on docker

* Add handle on enter button;

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Gaylord Julien <g.j@mailbox.org>
Co-authored-by: Jefferson Nunn <89030989+jeffersonwarrior@users.noreply.github.com>
Co-authored-by: Termix CI <ci@termix.dev>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: LukeGus <bugattiguy527@gmail.com>
2026-01-04 10:29:11 -05:00
LukeGus
d632f2b91f fix: build error on docker 2026-01-02 01:52:25 -06:00
LukeGus
5366cb24ef Merge remote-tracking branch 'origin/dev-1.10.1' into dev-1.10.1 2026-01-02 00:32:33 -06:00
LukeGus
177e783f92 fix: file manager incorrectly decoding/encoding when editing files (made base64/utf8 dependent) 2026-01-02 00:32:22 -06:00
Jefferson Nunn
1a2179c345 fix: resolve Vite build warnings for mixed static/dynamic imports (#473)
* Update Crowdin configuration file

* Update Crowdin configuration file

* fix: resolve Vite build warnings for mixed static/dynamic imports

- Convert all dynamic imports of main-axios.ts to static imports (10 files)
- Convert all dynamic imports of sonner to static imports (4 files)
- Add manual chunking configuration to vite.config.ts for better bundle splitting
  - react-vendor: React and React DOM
  - ui-vendor: Radix UI, lucide-react, clsx, tailwind-merge
  - monaco: Monaco Editor
  - codemirror: CodeMirror and related packages
- Increase chunkSizeWarningLimit to 1000kB

This resolves Vite warnings about mixed import strategies preventing
proper code-splitting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: Termix CI <ci@termix.dev>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-01 18:43:38 -06:00
LukeGus
bdf9ea282e fix: made submit job match build type 2025-12-31 23:33:17 -06:00
LukeGus
6feb8405ce fix: testflight submit failure 2025-12-31 23:29:46 -06:00
LukeGus
2ee1318ded fix: electron build errors and skip macos job 2025-12-31 22:54:32 -06:00
Steven Josefs
0216a2d2fe Fixing PR442:
- Fixed:
    - UI design elemets
    - UI and button colors
    - JSON export
    - recent activity is default again
- Removed:
    - Online/Offline UI labels
    - left-click menu on hosts
- Added:
    - small pulsing dot inside the hosts to indicate online status like in the left bar
2025-12-30 18:20:57 +01:00
Steven Josefs
8106999d1e Feature request network graph 2025-12-07 20:50:03 +01:00
149 changed files with 74437 additions and 46249 deletions

View File

@@ -17,7 +17,7 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: blacksmith-4vcpu-ubuntu-2404
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v5

View File

@@ -356,7 +356,7 @@ jobs:
build-macos: build-macos:
runs-on: macos-latest runs-on: macos-latest
if: github.event.inputs.build_type == 'macos' || github.event.inputs.build_type == 'all' if: (github.event.inputs.build_type == 'macos' || github.event.inputs.build_type == 'all') && github.event.inputs.artifact_destination != 'submit'
needs: [] needs: []
permissions: permissions:
contents: write contents: write
@@ -584,7 +584,7 @@ jobs:
submit-to-chocolatey: submit-to-chocolatey:
runs-on: windows-latest runs-on: windows-latest
if: github.event.inputs.artifact_destination == 'submit' if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'windows' || github.event.inputs.build_type == '')
permissions: permissions:
contents: read contents: read
@@ -689,7 +689,7 @@ jobs:
submit-to-flatpak: submit-to-flatpak:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event.inputs.artifact_destination == 'submit' if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'linux' || github.event.inputs.build_type == '')
needs: [] needs: []
permissions: permissions:
contents: read contents: read
@@ -776,7 +776,7 @@ jobs:
submit-to-homebrew: submit-to-homebrew:
runs-on: macos-latest runs-on: macos-latest
if: github.event.inputs.artifact_destination == 'submit' if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'macos')
needs: [] needs: []
permissions: permissions:
contents: read contents: read
@@ -801,11 +801,20 @@ jobs:
URL="https://github.com/Termix-SSH/Termix/releases/download/release-$VERSION-tag/$DMG_NAME" URL="https://github.com/Termix-SSH/Termix/releases/download/release-$VERSION-tag/$DMG_NAME"
mkdir -p release_asset mkdir -p release_asset
PATH="release_asset/$DMG_NAME" DOWNLOAD_PATH="release_asset/$DMG_NAME"
echo "Downloading DMG from $URL" echo "Downloading DMG from $URL"
curl -L -o "$PATH" "$URL"
CHECKSUM=$(shasum -a 256 "$PATH" | awk '{print $1}') if command -v curl &> /dev/null; then
curl -L -o "$DOWNLOAD_PATH" "$URL"
elif command -v wget &> /dev/null; then
wget -O "$DOWNLOAD_PATH" "$URL"
else
echo "Neither curl nor wget is available, installing curl"
brew install curl
curl -L -o "$DOWNLOAD_PATH" "$URL"
fi
CHECKSUM=$(shasum -a 256 "$DOWNLOAD_PATH" | awk '{print $1}')
echo "dmg_name=$DMG_NAME" >> $GITHUB_OUTPUT echo "dmg_name=$DMG_NAME" >> $GITHUB_OUTPUT
echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT
@@ -872,7 +881,7 @@ jobs:
submit-to-testflight: submit-to-testflight:
runs-on: macos-latest runs-on: macos-latest
if: github.event.inputs.artifact_destination == 'submit' if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'macos')
needs: [] needs: []
permissions: permissions:
contents: write contents: write
@@ -977,7 +986,7 @@ jobs:
- name: Deploy to App Store Connect (TestFlight) - name: Deploy to App Store Connect (TestFlight)
if: steps.check_asc_creds.outputs.has_credentials == 'true' if: steps.check_asc_creds.outputs.has_credentials == 'true'
run: | run: |
PKG_FILE=$(find artifact-mas -name "*.pkg" -type f | head -n 1) PKG_FILE=$(find release -name "termix_macos_universal_mas.pkg" -type f | head -n 1)
if [ -z "$PKG_FILE" ]; then if [ -z "$PKG_FILE" ]; then
echo "PKG file not found, exiting." echo "PKG file not found, exiting."
exit 1 exit 1

32
.github/workflows/openapi.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Generate OpenAPI Specification
on:
workflow_dispatch:
jobs:
generate-openapi:
name: Generate OpenAPI JSON
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Generate OpenAPI specification
run: npm run generate:openapi
- name: Upload OpenAPI artifact
uses: actions/upload-artifact@v4
with:
name: openapi-spec
path: openapi.json
retention-days: 90

View File

@@ -1,437 +0,0 @@
name: Auto Translate
on:
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
translate-zh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t zh --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-zh
path: src/locales/zh.json
continue-on-error: true
translate-ru:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ru --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-ru
path: src/locales/ru.json
continue-on-error: true
translate-pt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t pt --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-pt
path: src/locales/pt.json
continue-on-error: true
translate-fr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t fr --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-fr
path: src/locales/fr.json
continue-on-error: true
translate-es:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t es --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-es
path: src/locales/es.json
continue-on-error: true
translate-de:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t de --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-de
path: src/locales/de.json
continue-on-error: true
translate-hi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t hi --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-hi
path: src/locales/hi.json
continue-on-error: true
translate-bn:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t bn --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-bn
path: src/locales/bn.json
continue-on-error: true
translate-ja:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ja --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-ja
path: src/locales/ja.json
continue-on-error: true
translate-vi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t vi --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-vi
path: src/locales/vi.json
continue-on-error: true
translate-tr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t tr --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-tr
path: src/locales/tr.json
continue-on-error: true
translate-ko:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ko --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-ko
path: src/locales/ko.json
continue-on-error: true
translate-it:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t it --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-it
path: src/locales/it.json
continue-on-error: true
translate-he:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t he --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-he
path: src/locales/he.json
continue-on-error: true
translate-ar:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ar --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-ar
path: src/locales/ar.json
continue-on-error: true
translate-pl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t pl --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-pl
path: src/locales/pl.json
continue-on-error: true
translate-nl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t nl --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-nl
path: src/locales/nl.json
continue-on-error: true
translate-sv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t sv --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-sv
path: src/locales/sv.json
continue-on-error: true
translate-id:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t id --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-id
path: src/locales/id.json
continue-on-error: true
translate-th:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t th --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-th
path: src/locales/th.json
continue-on-error: true
translate-uk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t uk --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-uk
path: src/locales/uk.json
continue-on-error: true
translate-cs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t cs --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-cs
path: src/locales/cs.json
continue-on-error: true
translate-ro:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t ro --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-ro
path: src/locales/ro.json
continue-on-error: true
translate-el:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t el --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-el
path: src/locales/el.json
continue-on-error: true
translate-nb:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx i18n-auto-translation -k ${{ secrets.GOOGLE_TRANSLATE_API_KEY }} -d "src/locales" -f en -t nb --maxLinesPerRequest 1
- uses: actions/upload-artifact@v4
with:
name: translations-nb
path: src/locales/nb.json
continue-on-error: true
create-pr:
needs:
[
translate-zh,
translate-ru,
translate-pt,
translate-fr,
translate-es,
translate-de,
translate-hi,
translate-bn,
translate-ja,
translate-vi,
translate-tr,
translate-ko,
translate-it,
translate-he,
translate-ar,
translate-pl,
translate-nl,
translate-sv,
translate-id,
translate-th,
translate-uk,
translate-cs,
translate-ro,
translate-el,
translate-nb,
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GHCR_TOKEN }}
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: translations-temp
- name: Move translations to src/locales
run: |
cp translations-temp/translations-zh/zh.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-ru/ru.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-pt/pt.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-fr/fr.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-es/es.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-de/de.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-hi/hi.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-bn/bn.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-ja/ja.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-vi/vi.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-tr/tr.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-ko/ko.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-it/it.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-he/he.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-ar/ar.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-pl/pl.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-nl/nl.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-sv/sv.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-id/id.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-th/th.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-uk/uk.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-cs/cs.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-ro/ro.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-el/el.json src/locales/ 2>/dev/null || true
cp translations-temp/translations-nb/nb.json src/locales/ 2>/dev/null || true
rm -rf translations-temp
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GHCR_TOKEN }}
commit-message: "chore: auto-translate to multiple languages"
branch: translations-update
delete-branch: true
title: "chore: Update translations for all languages"

View File

@@ -16,17 +16,6 @@
<small style="color: #666;">Achieved on September 1st, 2025</small> <small style="color: #666;">Achieved on September 1st, 2025</small>
</p> </p>
#### Top Technologies
[![React Badge](https://img.shields.io/badge/-React-61DBFB?style=flat-square&labelColor=black&logo=react&logoColor=61DBFB)](#)
[![TypeScript Badge](https://img.shields.io/badge/-TypeScript-3178C6?style=flat-square&labelColor=black&logo=typescript&logoColor=3178C6)](#)
[![Node.js Badge](https://img.shields.io/badge/-Node.js-3C873A?style=flat-square&labelColor=black&logo=node.js&logoColor=3C873A)](#)
[![Vite Badge](https://img.shields.io/badge/-Vite-646CFF?style=flat-square&labelColor=black&logo=vite&logoColor=646CFF)](#)
[![Tailwind CSS Badge](https://img.shields.io/badge/-TailwindCSS-38B2AC?style=flat-square&labelColor=black&logo=tailwindcss&logoColor=38B2AC)](#)
[![Docker Badge](https://img.shields.io/badge/-Docker-2496ED?style=flat-square&labelColor=black&logo=docker&logoColor=2496ED)](#)
[![SQLite Badge](https://img.shields.io/badge/-SQLite-003B57?style=flat-square&labelColor=black&logo=sqlite&logoColor=003B57)](#)
[![Radix UI Badge](https://img.shields.io/badge/-Radix%20UI-161618?style=flat-square&labelColor=black&logo=radixui&logoColor=161618)](#)
<br /> <br />
<p align="center"> <p align="center">
<a href="https://github.com/Termix-SSH/Termix"> <a href="https://github.com/Termix-SSH/Termix">
@@ -85,6 +74,7 @@ Supported Devices:
- Chocolatey Package Manager - Chocolatey Package Manager
- Linux (x64/ia32) - Linux (x64/ia32)
- Portable - Portable
- AUR
- AppImage - AppImage
- Deb - Deb
- Flatpak - Flatpak
@@ -120,6 +110,18 @@ volumes:
driver: local driver: local
``` ```
# Sponsors
<p align="left">
<a href="https://www.digitalocean.com/">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="50" alt="DigitalOcean">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://crowdin.com/">
<img src="https://support.crowdin.com/assets/logos/core-logo/svg/crowdin-core-logo-cDark.svg" height="50" alt="Crowdin">
</a>
</p>
# Support # Support
If you need help or want to request a feature with Termix, visit the [Issues](https://github.com/Termix-SSH/Support/issues) page, log in, and press `New Issue`. If you need help or want to request a feature with Termix, visit the [Issues](https://github.com/Termix-SSH/Support/issues) page, log in, and press `New Issue`.

3
crowdin.yml Normal file
View File

@@ -0,0 +1,3 @@
files:
- source: /src/locales/en.json
translation: /src/locales/translated/%two_letters_code%.json

View File

@@ -19,7 +19,7 @@ COPY . .
RUN find public/fonts -name "*.ttf" ! -name "*Regular.ttf" ! -name "*Bold.ttf" ! -name "*Italic.ttf" -delete RUN find public/fonts -name "*.ttf" ! -name "*Regular.ttf" ! -name "*Bold.ttf" ! -name "*Italic.ttf" -delete
RUN npm cache clean --force && \ RUN npm cache clean --force && \
npm run build NODE_OPTIONS="--max-old-space-size=2048" npm run build
# Stage 3: Build backend # Stage 3: Build backend
FROM deps AS backend-builder FROM deps AS backend-builder
@@ -74,6 +74,9 @@ VOLUME ["/app/data"]
EXPOSE ${PORT} 30001 30002 30003 30004 30005 30006 EXPOSE ${PORT} 30001 30002 30003 30004 30005 30006
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD node -e "require('http').get('http://localhost:30001/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
COPY docker/entrypoint.sh /entrypoint.sh COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh RUN chmod +x /entrypoint.sh

View File

@@ -1,3 +1,5 @@
worker_processes 1;
master_process off;
pid /app/nginx/nginx.pid; pid /app/nginx/nginx.pid;
error_log /app/nginx/logs/error.log warn; error_log /app/nginx/logs/error.log warn;
@@ -199,6 +201,18 @@ http {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
location /ssh/quick-connect {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/ { location /ssh/ {
proxy_pass http://127.0.0.1:30001; proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1; proxy_http_version 1.1;
@@ -286,6 +300,15 @@ http {
proxy_buffering off; proxy_buffering off;
} }
location ~ ^/network-topology(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /health { location /health {
proxy_pass http://127.0.0.1:30001; proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1; proxy_http_version 1.1;
@@ -335,6 +358,15 @@ http {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
location ~ ^/dashboard/preferences(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /docker/console/ { location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/; proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1; proxy_http_version 1.1;

View File

@@ -1,3 +1,5 @@
worker_processes 1;
master_process off;
pid /app/nginx/nginx.pid; pid /app/nginx/nginx.pid;
error_log /app/nginx/logs/error.log warn; error_log /app/nginx/logs/error.log warn;
@@ -188,6 +190,18 @@ http {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
location /ssh/quick-connect {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ssh/ { location /ssh/ {
proxy_pass http://127.0.0.1:30001; proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1; proxy_http_version 1.1;
@@ -275,6 +289,15 @@ http {
proxy_buffering off; proxy_buffering off;
} }
location ~ ^/network-topology(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /health { location /health {
proxy_pass http://127.0.0.1:30001; proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1; proxy_http_version 1.1;
@@ -324,6 +347,15 @@ http {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
location ~ ^/dashboard/preferences(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /docker/console/ { location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/; proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1; proxy_http_version 1.1;

View File

@@ -4,6 +4,13 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" /> <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- PWA Meta Tags -->
<meta name="theme-color" content="#09090b" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Termix" />
<link rel="apple-touch-icon" href="/icons/512x512.png" />
<link rel="manifest" href="/manifest.json" />
<title>Termix</title> <title>Termix</title>
<style> <style>
.hide-scrollbar { .hide-scrollbar {

File diff suppressed because it is too large Load Diff

262
package-lock.json generated
View File

@@ -34,6 +34,7 @@
"@tailwindcss/vite": "^4.1.14", "@tailwindcss/vite": "^4.1.14",
"@types/bcryptjs": "^2.4.6", "@types/bcryptjs": "^2.4.6",
"@types/cookie-parser": "^1.4.9", "@types/cookie-parser": "^1.4.9",
"@types/cytoscape": "^3.21.9",
"@types/jszip": "^3.4.0", "@types/jszip": "^3.4.0",
"@types/multer": "^2.0.0", "@types/multer": "^2.0.0",
"@types/qrcode": "^1.5.5", "@types/qrcode": "^1.5.5",
@@ -56,6 +57,7 @@
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",
"cors": "^2.8.5", "cors": "^2.8.5",
"cytoscape": "^3.33.1",
"dotenv": "^17.2.0", "dotenv": "^17.2.0",
"drizzle-orm": "^0.44.3", "drizzle-orm": "^0.44.3",
"express": "^5.1.0", "express": "^5.1.0",
@@ -72,6 +74,7 @@
"node-fetch": "^3.3.2", "node-fetch": "^3.3.2",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "^19.1.0", "react": "^19.1.0",
"react-cytoscapejs": "^2.0.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-h5-audio-player": "^3.10.1", "react-h5-audio-player": "^3.10.1",
"react-hook-form": "^7.60.0", "react-hook-form": "^7.60.0",
@@ -122,11 +125,60 @@
"husky": "^9.1.7", "husky": "^9.1.7",
"lint-staged": "^16.2.3", "lint-staged": "^16.2.3",
"prettier": "3.6.2", "prettier": "3.6.2",
"swagger-jsdoc": "^6.2.8",
"typescript": "~5.9.2", "typescript": "~5.9.2",
"typescript-eslint": "^8.40.0", "typescript-eslint": "^8.40.0",
"vite": "^7.1.5" "vite": "^7.1.5"
} }
}, },
"node_modules/@apidevtools/json-schema-ref-parser": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz",
"integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jsdevtools/ono": "^7.1.3",
"@types/json-schema": "^7.0.6",
"call-me-maybe": "^1.0.1",
"js-yaml": "^4.1.0"
}
},
"node_modules/@apidevtools/openapi-schemas": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
"integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/@apidevtools/swagger-methods": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
"integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==",
"dev": true,
"license": "MIT"
},
"node_modules/@apidevtools/swagger-parser": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz",
"integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@apidevtools/openapi-schemas": "^2.0.4",
"@apidevtools/swagger-methods": "^3.0.2",
"@jsdevtools/ono": "^7.1.3",
"call-me-maybe": "^1.0.1",
"z-schema": "^5.0.1"
},
"peerDependencies": {
"openapi-types": ">=7"
}
},
"node_modules/@babel/code-frame": { "node_modules/@babel/code-frame": {
"version": "7.27.1", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
@@ -2619,6 +2671,13 @@
"url": "https://opencollective.com/js-sdsl" "url": "https://opencollective.com/js-sdsl"
} }
}, },
"node_modules/@jsdevtools/ono": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
"dev": true,
"license": "MIT"
},
"node_modules/@lezer/common": { "node_modules/@lezer/common": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.3.0.tgz", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.3.0.tgz",
@@ -5228,6 +5287,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/cytoscape": {
"version": "3.21.9",
"resolved": "https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.21.9.tgz",
"integrity": "sha512-JyrG4tllI6jvuISPjHK9j2Xv/LTbnLekLke5otGStjFluIyA9JjgnvgZrSBsp8cEDpiTjwgZUZwpPv8TSBcoLw==",
"license": "MIT"
},
"node_modules/@types/d3-array": { "node_modules/@types/d3-array": {
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
@@ -6958,6 +7023,13 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/call-me-maybe": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
"integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==",
"dev": true,
"license": "MIT"
},
"node_modules/callsites": { "node_modules/callsites": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -7776,6 +7848,15 @@
"integrity": "sha512-cjrsQufETwxjvwZbYbKBCJNvmQ2++G9AvT45zDi7NXL9k2PdVcs2h0jQz96J6G4TMKRCcEsoJ+QTgQD00Igtjw==", "integrity": "sha512-cjrsQufETwxjvwZbYbKBCJNvmQ2++G9AvT45zDi7NXL9k2PdVcs2h0jQz96J6G4TMKRCcEsoJ+QTgQD00Igtjw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/cytoscape": {
"version": "3.33.1",
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz",
"integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==",
"license": "MIT",
"engines": {
"node": ">=0.10"
}
},
"node_modules/d3-array": { "node_modules/d3-array": {
"version": "3.2.4", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
@@ -8304,6 +8385,19 @@
"license": "MIT", "license": "MIT",
"optional": true "optional": true
}, },
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"esutils": "^2.0.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/dompurify": { "node_modules/dompurify": {
"version": "3.1.7", "version": "3.1.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
@@ -12195,6 +12289,14 @@
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.includes": { "node_modules/lodash.includes": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@@ -12207,6 +12309,14 @@
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
"deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.isinteger": { "node_modules/lodash.isinteger": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
@@ -14068,6 +14178,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/openapi-types": {
"version": "12.1.3",
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/optionator": { "node_modules/optionator": {
"version": "0.9.4", "version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -15109,6 +15227,19 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-cytoscapejs": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/react-cytoscapejs/-/react-cytoscapejs-2.0.0.tgz",
"integrity": "sha512-t3SSl1DQy7+JQjN+8QHi1anEJlM3i3aAeydHTsJwmjo/isyKK7Rs7oCvU6kZsB9NwZidzZQR21Vm2PcBLG/Tjg==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"cytoscape": "^3.2.19",
"react": ">=15.0.0"
}
},
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "19.2.0", "version": "19.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
@@ -16717,6 +16848,95 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/swagger-jsdoc": {
"version": "6.2.8",
"resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz",
"integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"commander": "6.2.0",
"doctrine": "3.0.0",
"glob": "7.1.6",
"lodash.mergewith": "^4.6.2",
"swagger-parser": "^10.0.3",
"yaml": "2.0.0-1"
},
"bin": {
"swagger-jsdoc": "bin/swagger-jsdoc.js"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/swagger-jsdoc/node_modules/commander": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
"integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/swagger-jsdoc/node_modules/glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/swagger-jsdoc/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/swagger-jsdoc/node_modules/yaml": {
"version": "2.0.0-1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
"integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">= 6"
}
},
"node_modules/swagger-parser": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz",
"integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@apidevtools/swagger-parser": "10.0.3"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tailwind-merge": { "node_modules/tailwind-merge": {
"version": "3.3.1", "version": "3.3.1",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz",
@@ -17566,6 +17786,16 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/validator": {
"version": "13.15.26",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz",
"integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/vary": { "node_modules/vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -18120,6 +18350,38 @@
"integrity": "sha512-YHDIOAqgRpfl1Ois9HcB8UFtWOxK8KJrV5TXpImj4BKYP1rWT04f/fMM9tQ9SYZlBKukT7NR+9wcI3UpB5BMDQ==", "integrity": "sha512-YHDIOAqgRpfl1Ois9HcB8UFtWOxK8KJrV5TXpImj4BKYP1rWT04f/fMM9tQ9SYZlBKukT7NR+9wcI3UpB5BMDQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/z-schema": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz",
"integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
"validator": "^13.7.0"
},
"bin": {
"z-schema": "bin/z-schema"
},
"engines": {
"node": ">=8.0.0"
},
"optionalDependencies": {
"commander": "^9.4.1"
}
},
"node_modules/z-schema/node_modules/commander": {
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"dev": true,
"license": "MIT",
"optional": true,
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/zod": { "node_modules/zod": {
"version": "4.1.12", "version": "4.1.12",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",

View File

@@ -1,7 +1,7 @@
{ {
"name": "termix", "name": "termix",
"private": true, "private": true,
"version": "1.10.0", "version": "1.10.1",
"description": "A web-based server management platform with SSH terminal, tunneling, and file editing capabilities", "description": "A web-based server management platform with SSH terminal, tunneling, and file editing capabilities",
"author": "Karmaa", "author": "Karmaa",
"main": "electron/main.cjs", "main": "electron/main.cjs",
@@ -17,6 +17,7 @@
"build": "vite build && tsc -p tsconfig.node.json", "build": "vite build && tsc -p tsconfig.node.json",
"build:backend": "tsc -p tsconfig.node.json", "build:backend": "tsc -p tsconfig.node.json",
"dev:backend": "tsc -p tsconfig.node.json && node ./dist/backend/backend/starter.js", "dev:backend": "tsc -p tsconfig.node.json && node ./dist/backend/backend/starter.js",
"generate:openapi": "tsc -p tsconfig.node.json && node ./dist/backend/backend/swagger.js",
"preview": "vite preview", "preview": "vite preview",
"electron:dev": "concurrently \"npm run dev\" \"powershell -c \\\"Start-Sleep -Seconds 5\\\" && electron .\"", "electron:dev": "concurrently \"npm run dev\" \"powershell -c \\\"Start-Sleep -Seconds 5\\\" && electron .\"",
"build:win-portable": "npm run build && electron-builder --win --dir", "build:win-portable": "npm run build && electron-builder --win --dir",
@@ -53,6 +54,7 @@
"@tailwindcss/vite": "^4.1.14", "@tailwindcss/vite": "^4.1.14",
"@types/bcryptjs": "^2.4.6", "@types/bcryptjs": "^2.4.6",
"@types/cookie-parser": "^1.4.9", "@types/cookie-parser": "^1.4.9",
"@types/cytoscape": "^3.21.9",
"@types/jszip": "^3.4.0", "@types/jszip": "^3.4.0",
"@types/multer": "^2.0.0", "@types/multer": "^2.0.0",
"@types/qrcode": "^1.5.5", "@types/qrcode": "^1.5.5",
@@ -75,6 +77,7 @@
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",
"cors": "^2.8.5", "cors": "^2.8.5",
"cytoscape": "^3.33.1",
"dotenv": "^17.2.0", "dotenv": "^17.2.0",
"drizzle-orm": "^0.44.3", "drizzle-orm": "^0.44.3",
"express": "^5.1.0", "express": "^5.1.0",
@@ -91,6 +94,7 @@
"node-fetch": "^3.3.2", "node-fetch": "^3.3.2",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "^19.1.0", "react": "^19.1.0",
"react-cytoscapejs": "^2.0.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-h5-audio-player": "^3.10.1", "react-h5-audio-player": "^3.10.1",
"react-hook-form": "^7.60.0", "react-hook-form": "^7.60.0",
@@ -141,6 +145,7 @@
"husky": "^9.1.7", "husky": "^9.1.7",
"lint-staged": "^16.2.3", "lint-staged": "^16.2.3",
"prettier": "3.6.2", "prettier": "3.6.2",
"swagger-jsdoc": "^6.2.8",
"typescript": "~5.9.2", "typescript": "~5.9.2",
"typescript-eslint": "^8.40.0", "typescript-eslint": "^8.40.0",
"vite": "^7.1.5" "vite": "^7.1.5"

40
public/manifest.json Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "Termix",
"short_name": "Termix",
"description": "A web-based server management platform with SSH terminal, tunneling, and file editing capabilities",
"theme_color": "#09090b",
"background_color": "#09090b",
"display": "standalone",
"orientation": "any",
"scope": "/",
"start_url": "/",
"icons": [
{
"src": "/icons/48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "/icons/64x64.png",
"sizes": "64x64",
"type": "image/png"
},
{
"src": "/icons/128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/icons/256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "/icons/512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
],
"categories": ["utilities", "developer", "productivity"]
}

120
public/sw.js Normal file
View File

@@ -0,0 +1,120 @@
/**
* Termix Service Worker
* Handles caching for offline PWA support
*/
const CACHE_NAME = "termix-v1";
const STATIC_ASSETS = [
"/",
"/index.html",
"/manifest.json",
"/favicon.ico",
"/icons/48x48.png",
"/icons/128x128.png",
"/icons/256x256.png",
"/icons/512x512.png",
];
// Install event - cache static assets
self.addEventListener("install", (event) => {
event.waitUntil(
caches
.open(CACHE_NAME)
.then((cache) => {
console.log("[SW] Caching static assets");
return cache.addAll(STATIC_ASSETS);
})
.then(() => {
// Activate immediately without waiting
return self.skipWaiting();
}),
);
});
// Activate event - clean up old caches
self.addEventListener("activate", (event) => {
event.waitUntil(
caches
.keys()
.then((cacheNames) => {
return Promise.all(
cacheNames
.filter((name) => name !== CACHE_NAME)
.map((name) => {
console.log("[SW] Deleting old cache:", name);
return caches.delete(name);
}),
);
})
.then(() => {
// Take control of all pages immediately
return self.clients.claim();
}),
);
});
// Fetch event - serve from cache, fall back to network
self.addEventListener("fetch", (event) => {
const { request } = event;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== "GET") {
return;
}
// Skip API requests - these must be online
if (url.pathname.startsWith("/api/") || url.pathname.startsWith("/ws")) {
return;
}
// Skip cross-origin requests
if (url.origin !== self.location.origin) {
return;
}
// For navigation requests (HTML), use network-first
if (request.mode === "navigate") {
event.respondWith(
fetch(request)
.then((response) => {
// Clone and cache the response
const responseClone = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(request, responseClone);
});
return response;
})
.catch(() => {
// Offline: return cached index.html
return caches.match("/index.html");
}),
);
return;
}
// For all other assets, use cache-first
event.respondWith(
caches.match(request).then((cachedResponse) => {
if (cachedResponse) {
return cachedResponse;
}
// Not in cache, fetch from network
return fetch(request).then((response) => {
// Don't cache non-successful responses
if (!response || response.status !== 200 || response.type !== "basic") {
return response;
}
// Clone and cache the response
const responseClone = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(request, responseClone);
});
return response;
});
}),
);
});

View File

@@ -1,9 +1,14 @@
import express from "express"; import express from "express";
import cors from "cors"; import cors from "cors";
import cookieParser from "cookie-parser"; import cookieParser from "cookie-parser";
import { getDb } from "./database/db/index.js"; import { getDb, DatabaseSaveTrigger } from "./database/db/index.js";
import { recentActivity, sshData, hostAccess } from "./database/db/schema.js"; import {
import { eq, and, desc, or } from "drizzle-orm"; recentActivity,
sshData,
hostAccess,
dashboardPreferences,
} from "./database/db/schema.js";
import { eq, and, desc, or, sql } from "drizzle-orm";
import { dashboardLogger } from "./utils/logger.js"; import { dashboardLogger } from "./utils/logger.js";
import { SimpleDBOps } from "./utils/simple-db-ops.js"; import { SimpleDBOps } from "./utils/simple-db-ops.js";
import { AuthManager } from "./utils/auth-manager.js"; import { AuthManager } from "./utils/auth-manager.js";
@@ -58,6 +63,31 @@ app.use(express.json({ limit: "1mb" }));
app.use(authManager.createAuthMiddleware()); app.use(authManager.createAuthMiddleware());
/**
* @openapi
* /uptime:
* get:
* summary: Get server uptime
* description: Returns the uptime of the server in various formats.
* tags:
* - Dashboard
* responses:
* 200:
* description: Server uptime information.
* content:
* application/json:
* schema:
* type: object
* properties:
* uptimeMs:
* type: number
* uptimeSeconds:
* type: number
* formatted:
* type: string
* 500:
* description: Failed to get uptime.
*/
app.get("/uptime", async (req, res) => { app.get("/uptime", async (req, res) => {
try { try {
const uptimeMs = Date.now() - serverStartTime; const uptimeMs = Date.now() - serverStartTime;
@@ -77,6 +107,28 @@ app.get("/uptime", async (req, res) => {
} }
}); });
/**
* @openapi
* /activity/recent:
* get:
* summary: Get recent activity
* description: Fetches the most recent activities for the authenticated user.
* tags:
* - Dashboard
* parameters:
* - in: query
* name: limit
* schema:
* type: integer
* description: The maximum number of activities to return.
* responses:
* 200:
* description: A list of recent activities.
* 401:
* description: Session expired.
* 500:
* description: Failed to get recent activity.
*/
app.get("/activity/recent", async (req, res) => { app.get("/activity/recent", async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -108,6 +160,40 @@ app.get("/activity/recent", async (req, res) => {
} }
}); });
/**
* @openapi
* /activity/log:
* post:
* summary: Log a new activity
* description: Logs a new user activity, such as accessing a terminal or file manager. This endpoint is rate-limited.
* tags:
* - Dashboard
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* type:
* type: string
* enum: [terminal, file_manager, server_stats, tunnel, docker]
* hostId:
* type: integer
* hostName:
* type: string
* responses:
* 200:
* description: Activity logged successfully or rate-limited.
* 400:
* description: Invalid request body.
* 401:
* description: Session expired.
* 404:
* description: Host not found or access denied.
* 500:
* description: Failed to log activity.
*/
app.post("/activity/log", async (req, res) => { app.post("/activity/log", async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -224,6 +310,22 @@ app.post("/activity/log", async (req, res) => {
} }
}); });
/**
* @openapi
* /activity/reset:
* delete:
* summary: Reset recent activity
* description: Clears all recent activity for the authenticated user.
* tags:
* - Dashboard
* responses:
* 200:
* description: Recent activity cleared.
* 401:
* description: Session expired.
* 500:
* description: Failed to reset activity.
*/
app.delete("/activity/reset", async (req, res) => { app.delete("/activity/reset", async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -253,6 +355,166 @@ app.delete("/activity/reset", async (req, res) => {
} }
}); });
/**
* @openapi
* /dashboard/preferences:
* get:
* summary: Get dashboard layout preferences
* description: Returns the user's customized dashboard layout settings. If no preferences exist, returns default layout.
* tags:
* - Dashboard
* responses:
* 200:
* description: Dashboard preferences retrieved
* content:
* application/json:
* schema:
* type: object
* properties:
* cards:
* type: array
* items:
* type: object
* properties:
* id:
* type: string
* enabled:
* type: boolean
* order:
* type: integer
* gridColumns:
* type: integer
* 401:
* description: Session expired
* 500:
* description: Failed to get preferences
*/
app.get("/dashboard/preferences", async (req, res) => {
try {
const userId = (req as AuthenticatedRequest).userId;
if (!SimpleDBOps.isUserDataUnlocked(userId)) {
return res.status(401).json({
error: "Session expired - please log in again",
code: "SESSION_EXPIRED",
});
}
const preferences = await getDb()
.select()
.from(dashboardPreferences)
.where(eq(dashboardPreferences.userId, userId));
if (preferences.length === 0) {
const defaultLayout = {
cards: [
{ id: "server_overview", enabled: true, order: 1 },
{ id: "recent_activity", enabled: true, order: 2 },
{ id: "network_graph", enabled: false, order: 3 },
{ id: "quick_actions", enabled: true, order: 4 },
{ id: "server_stats", enabled: true, order: 5 },
],
gridColumns: 2,
};
return res.json(defaultLayout);
}
const layout = JSON.parse(preferences[0].layout as string);
res.json(layout);
} catch (err) {
dashboardLogger.error("Failed to get dashboard preferences", err);
res.status(500).json({ error: "Failed to get dashboard preferences" });
}
});
/**
* @openapi
* /dashboard/preferences:
* post:
* summary: Save dashboard layout preferences
* description: Saves or updates the user's customized dashboard layout settings.
* tags:
* - Dashboard
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* cards:
* type: array
* items:
* type: object
* properties:
* id:
* type: string
* enabled:
* type: boolean
* order:
* type: integer
* gridColumns:
* type: integer
* responses:
* 200:
* description: Preferences saved successfully
* 400:
* description: Invalid request body
* 401:
* description: Session expired
* 500:
* description: Failed to save preferences
*/
app.post("/dashboard/preferences", async (req, res) => {
try {
const userId = (req as AuthenticatedRequest).userId;
if (!SimpleDBOps.isUserDataUnlocked(userId)) {
return res.status(401).json({
error: "Session expired - please log in again",
code: "SESSION_EXPIRED",
});
}
const { cards, gridColumns } = req.body;
if (!cards || !Array.isArray(cards) || typeof gridColumns !== "number") {
return res.status(400).json({
error:
"Invalid request body. Expected { cards: Array, gridColumns: number }",
});
}
const layout = JSON.stringify({ cards, gridColumns });
const existing = await getDb()
.select()
.from(dashboardPreferences)
.where(eq(dashboardPreferences.userId, userId));
if (existing.length > 0) {
await getDb()
.update(dashboardPreferences)
.set({ layout, updatedAt: sql`CURRENT_TIMESTAMP` })
.where(eq(dashboardPreferences.userId, userId));
} else {
await getDb().insert(dashboardPreferences).values({ userId, layout });
}
await DatabaseSaveTrigger.triggerSave("dashboard_preferences_updated");
dashboardLogger.success("Dashboard preferences saved", {
operation: "save_dashboard_preferences",
userId,
});
res.json({ success: true, message: "Dashboard preferences saved" });
} catch (err) {
dashboardLogger.error("Failed to save dashboard preferences", err);
res.status(500).json({ error: "Failed to save dashboard preferences" });
}
});
const PORT = 30006; const PORT = 30006;
app.listen(PORT, async () => { app.listen(PORT, async () => {
try { try {

View File

@@ -8,6 +8,7 @@ import alertRoutes from "./routes/alerts.js";
import credentialsRoutes from "./routes/credentials.js"; import credentialsRoutes from "./routes/credentials.js";
import snippetsRoutes from "./routes/snippets.js"; import snippetsRoutes from "./routes/snippets.js";
import terminalRoutes from "./routes/terminal.js"; import terminalRoutes from "./routes/terminal.js";
import networkTopologyRoutes from "./routes/network-topology.js";
import rbacRoutes from "./routes/rbac.js"; import rbacRoutes from "./routes/rbac.js";
import cors from "cors"; import cors from "cors";
import fetch from "node-fetch"; import fetch from "node-fetch";
@@ -205,10 +206,46 @@ app.use(bodyParser.urlencoded({ limit: "1gb", extended: true }));
app.use(bodyParser.raw({ limit: "5gb", type: "application/octet-stream" })); app.use(bodyParser.raw({ limit: "5gb", type: "application/octet-stream" }));
app.use(cookieParser()); app.use(cookieParser());
/**
* @openapi
* /health:
* get:
* summary: Health check
* description: Returns the health status of the server.
* tags:
* - General
* responses:
* 200:
* description: Server is healthy.
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: string
* example: ok
*/
app.get("/health", (req, res) => { app.get("/health", (req, res) => {
res.json({ status: "ok" }); res.json({ status: "ok" });
}); });
/**
* @openapi
* /version:
* get:
* summary: Get version information
* description: Returns the local and remote version of the application.
* tags:
* - General
* responses:
* 200:
* description: Version information.
* 404:
* description: Local version not set.
* 500:
* description: Fetch error.
*/
app.get("/version", authenticateJWT, async (req, res) => { app.get("/version", authenticateJWT, async (req, res) => {
let localVersion = process.env.VERSION; let localVersion = process.env.VERSION;
@@ -307,6 +344,31 @@ app.get("/version", authenticateJWT, async (req, res) => {
} }
}); });
/**
* @openapi
* /releases/rss:
* get:
* summary: Get releases in RSS format
* description: Returns the latest releases from the GitHub repository in an RSS-like JSON format.
* tags:
* - General
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* description: The page number of the releases to fetch.
* - in: query
* name: per_page
* schema:
* type: integer
* description: The number of releases to fetch per page.
* responses:
* 200:
* description: Releases in RSS format.
* 500:
* description: Failed to generate RSS format.
*/
app.get("/releases/rss", authenticateJWT, async (req, res) => { app.get("/releases/rss", authenticateJWT, async (req, res) => {
try { try {
const page = parseInt(req.query.page as string) || 1; const page = parseInt(req.query.page as string) || 1;
@@ -363,6 +425,20 @@ app.get("/releases/rss", authenticateJWT, async (req, res) => {
} }
}); });
/**
* @openapi
* /encryption/status:
* get:
* summary: Get encryption status
* description: Returns the security status of the application.
* tags:
* - Encryption
* responses:
* 200:
* description: Security status.
* 500:
* description: Failed to get security status.
*/
app.get("/encryption/status", requireAdmin, async (req, res) => { app.get("/encryption/status", requireAdmin, async (req, res) => {
try { try {
const securityStatus = { const securityStatus = {
@@ -384,6 +460,20 @@ app.get("/encryption/status", requireAdmin, async (req, res) => {
} }
}); });
/**
* @openapi
* /encryption/initialize:
* post:
* summary: Initialize security system
* description: Initializes the security system for the application.
* tags:
* - Encryption
* responses:
* 200:
* description: Security system initialized successfully.
* 500:
* description: Failed to initialize security system.
*/
app.post("/encryption/initialize", requireAdmin, async (req, res) => { app.post("/encryption/initialize", requireAdmin, async (req, res) => {
try { try {
const authManager = AuthManager.getInstance(); const authManager = AuthManager.getInstance();
@@ -407,6 +497,20 @@ app.post("/encryption/initialize", requireAdmin, async (req, res) => {
} }
}); });
/**
* @openapi
* /encryption/regenerate:
* post:
* summary: Regenerate JWT secret
* description: Regenerates the system JWT secret. This will invalidate all existing JWT tokens.
* tags:
* - Encryption
* responses:
* 200:
* description: System JWT secret regenerated.
* 500:
* description: Failed to regenerate JWT secret.
*/
app.post("/encryption/regenerate", requireAdmin, async (req, res) => { app.post("/encryption/regenerate", requireAdmin, async (req, res) => {
try { try {
apiLogger.warn("System JWT secret regenerated via API", { apiLogger.warn("System JWT secret regenerated via API", {
@@ -428,6 +532,20 @@ app.post("/encryption/regenerate", requireAdmin, async (req, res) => {
} }
}); });
/**
* @openapi
* /encryption/regenerate-jwt:
* post:
* summary: Regenerate JWT secret
* description: Regenerates the JWT secret. This will invalidate all existing JWT tokens.
* tags:
* - Encryption
* responses:
* 200:
* description: New JWT secret generated.
* 500:
* description: Failed to regenerate JWT secret.
*/
app.post("/encryption/regenerate-jwt", requireAdmin, async (req, res) => { app.post("/encryption/regenerate-jwt", requireAdmin, async (req, res) => {
try { try {
apiLogger.warn("JWT secret regenerated via API", { apiLogger.warn("JWT secret regenerated via API", {
@@ -448,6 +566,33 @@ app.post("/encryption/regenerate-jwt", requireAdmin, async (req, res) => {
} }
}); });
/**
* @openapi
* /database/export:
* post:
* summary: Export user data
* description: Exports the user's data as a SQLite database file.
* tags:
* - Database
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* password:
* type: string
* responses:
* 200:
* description: User data exported successfully.
* 400:
* description: Password required for export.
* 401:
* description: Invalid password.
* 500:
* description: Failed to export user data.
*/
app.post("/database/export", authenticateJWT, async (req, res) => { app.post("/database/export", authenticateJWT, async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -898,6 +1043,36 @@ app.post("/database/export", authenticateJWT, async (req, res) => {
} }
}); });
/**
* @openapi
* /database/import:
* post:
* summary: Import user data
* description: Imports user data from a SQLite database file.
* tags:
* - Database
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* properties:
* file:
* type: string
* format: binary
* password:
* type: string
* responses:
* 200:
* description: Incremental import completed successfully.
* 400:
* description: No file uploaded or password required for import.
* 401:
* description: Invalid password.
* 500:
* description: Failed to import SQLite data.
*/
app.post( app.post(
"/database/import", "/database/import",
authenticateJWT, authenticateJWT,
@@ -1362,6 +1537,31 @@ app.post(
}, },
); );
/**
* @openapi
* /database/export/preview:
* post:
* summary: Preview user data export
* description: Generates a preview of the user data export, including statistics about the data.
* tags:
* - Database
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* scope:
* type: string
* includeCredentials:
* type: boolean
* responses:
* 200:
* description: Export preview generated successfully.
* 500:
* description: Failed to generate export preview.
*/
app.post("/database/export/preview", authenticateJWT, async (req, res) => { app.post("/database/export/preview", authenticateJWT, async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -1397,6 +1597,33 @@ app.post("/database/export/preview", authenticateJWT, async (req, res) => {
} }
}); });
/**
* @openapi
* /database/restore:
* post:
* summary: Restore database from backup
* description: Restores the database from an encrypted backup file.
* tags:
* - Database
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* backupPath:
* type: string
* targetPath:
* type: string
* responses:
* 200:
* description: Database restored successfully.
* 400:
* description: Backup path is required or invalid encrypted backup file.
* 500:
* description: Database restore failed.
*/
app.post("/database/restore", requireAdmin, async (req, res) => { app.post("/database/restore", requireAdmin, async (req, res) => {
try { try {
const { backupPath, targetPath } = req.body; const { backupPath, targetPath } = req.body;
@@ -1437,6 +1664,7 @@ app.use("/alerts", alertRoutes);
app.use("/credentials", credentialsRoutes); app.use("/credentials", credentialsRoutes);
app.use("/snippets", snippetsRoutes); app.use("/snippets", snippetsRoutes);
app.use("/terminal", terminalRoutes); app.use("/terminal", terminalRoutes);
app.use("/network-topology", networkTopologyRoutes);
app.use("/rbac", rbacRoutes); app.use("/rbac", rbacRoutes);
app.use( app.use(
@@ -1477,6 +1705,20 @@ async function initializeSecurity() {
} }
} }
/**
* @openapi
* /database/migration/status:
* get:
* summary: Get database migration status
* description: Returns the status of the database migration.
* tags:
* - Database
* responses:
* 200:
* description: Migration status.
* 500:
* description: Failed to get migration status.
*/
app.get( app.get(
"/database/migration/status", "/database/migration/status",
authenticateJWT, authenticateJWT,
@@ -1530,6 +1772,20 @@ app.get(
}, },
); );
/**
* @openapi
* /database/migration/history:
* get:
* summary: Get database migration history
* description: Returns the history of database migrations.
* tags:
* - Database
* responses:
* 200:
* description: Migration history.
* 500:
* description: Failed to get migration history.
*/
app.get( app.get(
"/database/migration/history", "/database/migration/history",
authenticateJWT, authenticateJWT,

View File

@@ -585,6 +585,32 @@ const migrateSchema = () => {
addColumnIfNotExists("ssh_data", "socks5_password", "TEXT"); addColumnIfNotExists("ssh_data", "socks5_password", "TEXT");
addColumnIfNotExists("ssh_data", "socks5_proxy_chain", "TEXT"); addColumnIfNotExists("ssh_data", "socks5_proxy_chain", "TEXT");
addColumnIfNotExists(
"ssh_data",
"show_terminal_in_sidebar",
"INTEGER NOT NULL DEFAULT 1",
);
addColumnIfNotExists(
"ssh_data",
"show_file_manager_in_sidebar",
"INTEGER NOT NULL DEFAULT 0",
);
addColumnIfNotExists(
"ssh_data",
"show_tunnel_in_sidebar",
"INTEGER NOT NULL DEFAULT 0",
);
addColumnIfNotExists(
"ssh_data",
"show_docker_in_sidebar",
"INTEGER NOT NULL DEFAULT 0",
);
addColumnIfNotExists(
"ssh_data",
"show_server_stats_in_sidebar",
"INTEGER NOT NULL DEFAULT 0",
);
addColumnIfNotExists("ssh_credentials", "private_key", "TEXT"); addColumnIfNotExists("ssh_credentials", "private_key", "TEXT");
addColumnIfNotExists("ssh_credentials", "public_key", "TEXT"); addColumnIfNotExists("ssh_credentials", "public_key", "TEXT");
addColumnIfNotExists("ssh_credentials", "detected_key_type", "TEXT"); addColumnIfNotExists("ssh_credentials", "detected_key_type", "TEXT");
@@ -653,6 +679,54 @@ const migrateSchema = () => {
} }
} }
try {
sqlite
.prepare("SELECT id FROM network_topology LIMIT 1")
.get();
} catch {
try {
sqlite.exec(`
CREATE TABLE IF NOT EXISTS network_topology (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
topology TEXT,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
`);
} catch (createError) {
databaseLogger.warn("Failed to create network_topology table", {
operation: "schema_migration",
error: createError,
});
}
}
try {
sqlite
.prepare("SELECT id FROM dashboard_preferences LIMIT 1")
.get();
} catch {
try {
sqlite.exec(`
CREATE TABLE IF NOT EXISTS dashboard_preferences (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL UNIQUE,
layout TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
`);
} catch (createError) {
databaseLogger.warn("Failed to create dashboard_preferences table", {
operation: "schema_migration",
error: createError,
});
}
}
try { try {
sqlite.prepare("SELECT id FROM host_access LIMIT 1").get(); sqlite.prepare("SELECT id FROM host_access LIMIT 1").get();
} catch { } catch {

View File

@@ -90,6 +90,21 @@ export const sshData = sqliteTable("ssh_data", {
enableDocker: integer("enable_docker", { mode: "boolean" }) enableDocker: integer("enable_docker", { mode: "boolean" })
.notNull() .notNull()
.default(false), .default(false),
showTerminalInSidebar: integer("show_terminal_in_sidebar", { mode: "boolean" })
.notNull()
.default(true),
showFileManagerInSidebar: integer("show_file_manager_in_sidebar", { mode: "boolean" })
.notNull()
.default(false),
showTunnelInSidebar: integer("show_tunnel_in_sidebar", { mode: "boolean" })
.notNull()
.default(false),
showDockerInSidebar: integer("show_docker_in_sidebar", { mode: "boolean" })
.notNull()
.default(false),
showServerStatsInSidebar: integer("show_server_stats_in_sidebar", { mode: "boolean" })
.notNull()
.default(false),
defaultPath: text("default_path"), defaultPath: text("default_path"),
statsConfig: text("stats_config"), statsConfig: text("stats_config"),
terminalConfig: text("terminal_config"), terminalConfig: text("terminal_config"),
@@ -295,6 +310,35 @@ export const commandHistory = sqliteTable("command_history", {
.default(sql`CURRENT_TIMESTAMP`), .default(sql`CURRENT_TIMESTAMP`),
}); });
export const networkTopology = sqliteTable("network_topology", {
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
topology: text("topology"),
createdAt: text("created_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text("updated_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
});
export const dashboardPreferences = sqliteTable("dashboard_preferences", {
id: integer("id").primaryKey({ autoIncrement: true }),
userId: text("user_id")
.notNull()
.unique()
.references(() => users.id, { onDelete: "cascade" }),
layout: text("layout").notNull(),
createdAt: text("created_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text("updated_at")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
});
export const hostAccess = sqliteTable("host_access", { export const hostAccess = sqliteTable("host_access", {
id: integer("id").primaryKey({ autoIncrement: true }), id: integer("id").primaryKey({ autoIncrement: true }),
hostId: integer("host_id") hostId: integer("host_id")

View File

@@ -99,8 +99,20 @@ const router = express.Router();
const authManager = AuthManager.getInstance(); const authManager = AuthManager.getInstance();
const authenticateJWT = authManager.createAuthMiddleware(); const authenticateJWT = authManager.createAuthMiddleware();
// Route: Get alerts for the authenticated user (excluding dismissed ones) /**
// GET /alerts * @openapi
* /alerts:
* get:
* summary: Get active alerts
* description: Fetches active alerts for the authenticated user, excluding those that have been dismissed.
* tags:
* - Alerts
* responses:
* 200:
* description: A list of active alerts.
* 500:
* description: Failed to fetch alerts.
*/
router.get("/", authenticateJWT, async (req, res) => { router.get("/", authenticateJWT, async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -131,8 +143,33 @@ router.get("/", authenticateJWT, async (req, res) => {
} }
}); });
// Route: Dismiss an alert for the authenticated user /**
// POST /alerts/dismiss * @openapi
* /alerts/dismiss:
* post:
* summary: Dismiss an alert
* description: Marks an alert as dismissed for the authenticated user.
* tags:
* - Alerts
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* alertId:
* type: string
* responses:
* 200:
* description: Alert dismissed successfully.
* 400:
* description: Alert ID is required.
* 409:
* description: Alert already dismissed.
* 500:
* description: Failed to dismiss alert.
*/
router.post("/dismiss", authenticateJWT, async (req, res) => { router.post("/dismiss", authenticateJWT, async (req, res) => {
try { try {
const { alertId } = req.body; const { alertId } = req.body;
@@ -170,8 +207,20 @@ router.post("/dismiss", authenticateJWT, async (req, res) => {
} }
}); });
// Route: Get dismissed alerts for a user /**
// GET /alerts/dismissed/:userId * @openapi
* /alerts/dismissed:
* get:
* summary: Get dismissed alerts
* description: Fetches a list of alerts that have been dismissed by the authenticated user.
* tags:
* - Alerts
* responses:
* 200:
* description: A list of dismissed alerts.
* 500:
* description: Failed to fetch dismissed alerts.
*/
router.get("/dismissed", authenticateJWT, async (req, res) => { router.get("/dismissed", authenticateJWT, async (req, res) => {
try { try {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -194,8 +243,33 @@ router.get("/dismissed", authenticateJWT, async (req, res) => {
} }
}); });
// Route: Undismiss an alert for the authenticated user (remove from dismissed list) /**
// DELETE /alerts/dismiss * @openapi
* /alerts/dismiss:
* delete:
* summary: Undismiss an alert
* description: Removes an alert from the dismissed list for the authenticated user.
* tags:
* - Alerts
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* alertId:
* type: string
* responses:
* 200:
* description: Alert undismissed successfully.
* 400:
* description: Alert ID is required.
* 404:
* description: Dismissed alert not found.
* 500:
* description: Failed to undismiss alert.
*/
router.delete("/dismiss", authenticateJWT, async (req, res) => { router.delete("/dismiss", authenticateJWT, async (req, res) => {
try { try {
const { alertId } = req.body; const { alertId } = req.body;

View File

@@ -84,8 +84,52 @@ const authManager = AuthManager.getInstance();
const authenticateJWT = authManager.createAuthMiddleware(); const authenticateJWT = authManager.createAuthMiddleware();
const requireDataAccess = authManager.createDataAccessMiddleware(); const requireDataAccess = authManager.createDataAccessMiddleware();
// Create a new credential /**
// POST /credentials * @openapi
* /credentials:
* post:
* summary: Create a new credential
* description: Creates a new SSH credential for the authenticated user.
* tags:
* - Credentials
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* description:
* type: string
* folder:
* type: string
* tags:
* type: array
* items:
* type: string
* authType:
* type: string
* enum: [password, key]
* username:
* type: string
* password:
* type: string
* key:
* type: string
* keyPassword:
* type: string
* keyType:
* type: string
* responses:
* 201:
* description: Credential created successfully.
* 400:
* description: Invalid request body.
* 500:
* description: Failed to create credential.
*/
router.post( router.post(
"/", "/",
authenticateJWT, authenticateJWT,
@@ -231,8 +275,22 @@ router.post(
}, },
); );
// Get all credentials for the authenticated user /**
// GET /credentials * @openapi
* /credentials:
* get:
* summary: Get all credentials
* description: Retrieves all SSH credentials for the authenticated user.
* tags:
* - Credentials
* responses:
* 200:
* description: A list of credentials.
* 400:
* description: Invalid userId.
* 500:
* description: Failed to fetch credentials.
*/
router.get( router.get(
"/", "/",
authenticateJWT, authenticateJWT,
@@ -264,8 +322,22 @@ router.get(
}, },
); );
// Get all unique credential folders for the authenticated user /**
// GET /credentials/folders * @openapi
* /credentials/folders:
* get:
* summary: Get credential folders
* description: Retrieves all unique credential folders for the authenticated user.
* tags:
* - Credentials
* responses:
* 200:
* description: A list of folder names.
* 400:
* description: Invalid userId.
* 500:
* description: Failed to fetch credential folders.
*/
router.get( router.get(
"/folders", "/folders",
authenticateJWT, authenticateJWT,
@@ -302,8 +374,30 @@ router.get(
}, },
); );
// Get a specific credential by ID (with plain text secrets) /**
// GET /credentials/:id * @openapi
* /credentials/{id}:
* get:
* summary: Get a specific credential
* description: Retrieves a specific credential by its ID, including secrets.
* tags:
* - Credentials
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: The requested credential.
* 400:
* description: Invalid request.
* 404:
* description: Credential not found.
* 500:
* description: Failed to fetch credential.
*/
router.get( router.get(
"/:id", "/:id",
authenticateJWT, authenticateJWT,
@@ -366,8 +460,41 @@ router.get(
}, },
); );
// Update a credential /**
// PUT /credentials/:id * @openapi
* /credentials/{id}:
* put:
* summary: Update a credential
* description: Updates a specific credential by its ID.
* tags:
* - Credentials
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* description:
* type: string
* responses:
* 200:
* description: The updated credential.
* 400:
* description: Invalid request.
* 404:
* description: Credential not found.
* 500:
* description: Failed to update credential.
*/
router.put( router.put(
"/:id", "/:id",
authenticateJWT, authenticateJWT,
@@ -510,8 +637,30 @@ router.put(
}, },
); );
// Delete a credential /**
// DELETE /credentials/:id * @openapi
* /credentials/{id}:
* delete:
* summary: Delete a credential
* description: Deletes a specific credential by its ID.
* tags:
* - Credentials
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Credential deleted successfully.
* 400:
* description: Invalid request.
* 404:
* description: Credential not found.
* 500:
* description: Failed to delete credential.
*/
router.delete( router.delete(
"/:id", "/:id",
authenticateJWT, authenticateJWT,
@@ -626,8 +775,35 @@ router.delete(
}, },
); );
// Apply a credential to an SSH host (for quick application) /**
// POST /credentials/:id/apply-to-host/:hostId * @openapi
* /credentials/{id}/apply-to-host/{hostId}:
* post:
* summary: Apply a credential to a host
* description: Applies a credential to an SSH host for quick application.
* tags:
* - Credentials
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* - in: path
* name: hostId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Credential applied to host successfully.
* 400:
* description: Invalid request.
* 404:
* description: Credential not found.
* 500:
* description: Failed to apply credential to host.
*/
router.post( router.post(
"/:id/apply-to-host/:hostId", "/:id/apply-to-host/:hostId",
authenticateJWT, authenticateJWT,
@@ -705,8 +881,28 @@ router.post(
}, },
); );
// Get hosts using a specific credential /**
// GET /credentials/:id/hosts * @openapi
* /credentials/{id}/hosts:
* get:
* summary: Get hosts using a credential
* description: Retrieves a list of hosts that are using a specific credential.
* tags:
* - Credentials
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: A list of hosts.
* 400:
* description: Invalid request.
* 500:
* description: Failed to fetch hosts using credential.
*/
router.get( router.get(
"/:id/hosts", "/:id/hosts",
authenticateJWT, authenticateJWT,
@@ -800,8 +996,33 @@ function formatSSHHostOutput(
}; };
} }
// Rename a credential folder /**
// PUT /credentials/folders/rename * @openapi
* /credentials/folders/rename:
* put:
* summary: Rename a credential folder
* description: Renames a credential folder for the authenticated user.
* tags:
* - Credentials
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* oldName:
* type: string
* newName:
* type: string
* responses:
* 200:
* description: Folder renamed successfully.
* 400:
* description: Both oldName and newName are required.
* 500:
* description: Failed to rename folder.
*/
router.put( router.put(
"/folders/rename", "/folders/rename",
authenticateJWT, authenticateJWT,
@@ -840,8 +1061,33 @@ router.put(
}, },
); );
// Detect SSH key type endpoint /**
// POST /credentials/detect-key-type * @openapi
* /credentials/detect-key-type:
* post:
* summary: Detect SSH key type
* description: Detects the type of an SSH private key.
* tags:
* - Credentials
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* privateKey:
* type: string
* keyPassword:
* type: string
* responses:
* 200:
* description: Key type detection result.
* 400:
* description: Private key is required.
* 500:
* description: Failed to detect key type.
*/
router.post( router.post(
"/detect-key-type", "/detect-key-type",
authenticateJWT, authenticateJWT,
@@ -874,8 +1120,31 @@ router.post(
}, },
); );
// Detect SSH public key type endpoint /**
// POST /credentials/detect-public-key-type * @openapi
* /credentials/detect-public-key-type:
* post:
* summary: Detect SSH public key type
* description: Detects the type of an SSH public key.
* tags:
* - Credentials
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* publicKey:
* type: string
* responses:
* 200:
* description: Key type detection result.
* 400:
* description: Public key is required.
* 500:
* description: Failed to detect public key type.
*/
router.post( router.post(
"/detect-public-key-type", "/detect-public-key-type",
authenticateJWT, authenticateJWT,
@@ -909,8 +1178,35 @@ router.post(
}, },
); );
// Validate SSH key pair endpoint /**
// POST /credentials/validate-key-pair * @openapi
* /credentials/validate-key-pair:
* post:
* summary: Validate SSH key pair
* description: Validates if a given SSH private key and public key match.
* tags:
* - Credentials
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* privateKey:
* type: string
* publicKey:
* type: string
* keyPassword:
* type: string
* responses:
* 200:
* description: Key pair validation result.
* 400:
* description: Private key and public key are required.
* 500:
* description: Failed to validate key pair.
*/
router.post( router.post(
"/validate-key-pair", "/validate-key-pair",
authenticateJWT, authenticateJWT,
@@ -953,8 +1249,32 @@ router.post(
}, },
); );
// Generate new SSH key pair endpoint /**
// POST /credentials/generate-key-pair * @openapi
* /credentials/generate-key-pair:
* post:
* summary: Generate new SSH key pair
* description: Generates a new SSH key pair.
* tags:
* - Credentials
* requestBody:
* content:
* application/json:
* schema:
* type: object
* properties:
* keyType:
* type: string
* keySize:
* type: integer
* passphrase:
* type: string
* responses:
* 200:
* description: The new key pair.
* 500:
* description: Failed to generate SSH key pair.
*/
router.post( router.post(
"/generate-key-pair", "/generate-key-pair",
authenticateJWT, authenticateJWT,
@@ -996,8 +1316,33 @@ router.post(
}, },
); );
// Generate public key from private key endpoint /**
// POST /credentials/generate-public-key * @openapi
* /credentials/generate-public-key:
* post:
* summary: Generate public key from private key
* description: Generates a public key from a given private key.
* tags:
* - Credentials
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* privateKey:
* type: string
* keyPassword:
* type: string
* responses:
* 200:
* description: The generated public key.
* 400:
* description: Private key is required.
* 500:
* description: Failed to generate public key.
*/
router.post( router.post(
"/generate-public-key", "/generate-public-key",
authenticateJWT, authenticateJWT,
@@ -1283,7 +1628,7 @@ async function deploySSHKeyToHost(
.replace(/'/g, "'\\''"); .replace(/'/g, "'\\''");
conn.exec( conn.exec(
`printf '%s\\n' '${escapedKey} ${credData.name}@Termix' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys`, `printf '%s\n' '${escapedKey} ${credData.name}@Termix' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys`,
(err, stream) => { (err, stream) => {
if (err) { if (err) {
clearTimeout(addTimeout); clearTimeout(addTimeout);
@@ -1502,8 +1847,41 @@ async function deploySSHKeyToHost(
}); });
} }
// Deploy SSH Key to Host endpoint /**
// POST /credentials/:id/deploy-to-host * @openapi
* /credentials/{id}/deploy-to-host:
* post:
* summary: Deploy SSH key to a host
* description: Deploys an SSH public key to a target host's authorized_keys file.
* tags:
* - Credentials
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* targetHostId:
* type: integer
* responses:
* 200:
* description: SSH key deployed successfully.
* 400:
* description: Credential ID and target host ID are required.
* 401:
* description: Authentication required.
* 404:
* description: Credential or target host not found.
* 500:
* description: Failed to deploy SSH key.
*/
router.post( router.post(
"/:id/deploy-to-host", "/:id/deploy-to-host",
authenticateJWT, authenticateJWT,

View File

@@ -0,0 +1,142 @@
import express from "express";
import { eq } from "drizzle-orm";
import { getDb } from "../db/index.js";
import { networkTopology } from "../db/schema.js";
import { AuthManager } from "../../utils/auth-manager.js";
import type { AuthenticatedRequest } from "../../../types/index.js";
const router = express.Router();
const authManager = AuthManager.getInstance();
const authenticateJWT = authManager.createAuthMiddleware();
/**
* @openapi
* /network-topology:
* get:
* summary: Get network topology
* description: Retrieves the network topology for the authenticated user.
* tags:
* - Network Topology
* responses:
* 200:
* description: The network topology.
* 401:
* description: User not authenticated.
* 500:
* description: Failed to fetch network topology.
*/
router.get(
"/",
authenticateJWT,
async (req: express.Request, res: express.Response) => {
try {
const userId = (req as AuthenticatedRequest).userId;
if (!userId) {
return res.status(401).json({ error: "User not authenticated" });
}
const db = getDb();
const result = await db
.select()
.from(networkTopology)
.where(eq(networkTopology.userId, userId));
if (result.length > 0) {
const topologyStr = result[0].topology;
const topology = topologyStr ? JSON.parse(topologyStr) : null;
return res.json(topology);
} else {
return res.json(null);
}
} catch (error) {
console.error("Error fetching network topology:", error);
return res
.status(500)
.json({
error: "Failed to fetch network topology",
details: (error as Error).message,
});
}
},
);
/**
* @openapi
* /network-topology:
* post:
* summary: Save network topology
* description: Saves the network topology for the authenticated user.
* tags:
* - Network Topology
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* topology:
* type: object
* responses:
* 200:
* description: Network topology saved successfully.
* 400:
* description: Topology data is required.
* 401:
* description: User not authenticated.
* 500:
* description: Failed to save network topology.
*/
router.post(
"/",
authenticateJWT,
async (req: express.Request, res: express.Response) => {
try {
const userId = (req as AuthenticatedRequest).userId;
if (!userId) {
return res.status(401).json({ error: "User not authenticated" });
}
const { topology } = req.body;
if (!topology) {
return res.status(400).json({ error: "Topology data is required" });
}
const db = getDb();
// Ensure topology is a string
const topologyStr =
typeof topology === "string" ? topology : JSON.stringify(topology);
const existing = await db
.select()
.from(networkTopology)
.where(eq(networkTopology.userId, userId));
if (existing.length > 0) {
// Update existing record
await db
.update(networkTopology)
.set({ topology: topologyStr })
.where(eq(networkTopology.userId, userId));
} else {
// Insert new record
await db
.insert(networkTopology)
.values({ userId, topology: topologyStr });
}
return res.json({ success: true });
} catch (error) {
console.error("Error saving network topology:", error);
return res
.status(500)
.json({
error: "Failed to save network topology",
details: (error as Error).message,
});
}
},
);
export default router;

View File

@@ -27,8 +27,51 @@ function isNonEmptyString(value: unknown): value is string {
return typeof value === "string" && value.trim().length > 0; return typeof value === "string" && value.trim().length > 0;
} }
//Share a host with a user or role /**
//POST /rbac/host/:id/share * @openapi
* /rbac/host/{id}/share:
* post:
* summary: Share a host
* description: Shares a host with a user or a role.
* tags:
* - RBAC
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* targetType:
* type: string
* enum: [user, role]
* targetUserId:
* type: string
* targetRoleId:
* type: integer
* durationHours:
* type: number
* permissionLevel:
* type: string
* enum: [view]
* responses:
* 200:
* description: Host shared successfully.
* 400:
* description: Invalid request body.
* 403:
* description: Not host owner.
* 404:
* description: Target user or role not found.
* 500:
* description: Failed to share host.
*/
router.post( router.post(
"/host/:id/share", "/host/:id/share",
authenticateJWT, authenticateJWT,
@@ -227,8 +270,35 @@ router.post(
}, },
); );
// Revoke host access /**
// DELETE /rbac/host/:id/access/:accessId * @openapi
* /rbac/host/{id}/access/{accessId}:
* delete:
* summary: Revoke host access
* description: Revokes a user's or role's access to a host.
* tags:
* - RBAC
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* - in: path
* name: accessId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Access revoked successfully.
* 400:
* description: Invalid ID.
* 403:
* description: Not host owner.
* 500:
* description: Failed to revoke access.
*/
router.delete( router.delete(
"/host/:id/access/:accessId", "/host/:id/access/:accessId",
authenticateJWT, authenticateJWT,
@@ -267,8 +337,30 @@ router.delete(
}, },
); );
// Get host access list /**
// GET /rbac/host/:id/access * @openapi
* /rbac/host/{id}/access:
* get:
* summary: Get host access list
* description: Retrieves the list of users and roles that have access to a host.
* tags:
* - RBAC
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: The access list for the host.
* 400:
* description: Invalid host ID.
* 403:
* description: Not host owner.
* 500:
* description: Failed to get access list.
*/
router.get( router.get(
"/host/:id/access", "/host/:id/access",
authenticateJWT, authenticateJWT,
@@ -338,8 +430,20 @@ router.get(
}, },
); );
// Get user's shared hosts (hosts shared WITH this user) /**
// GET /rbac/shared-hosts * @openapi
* /rbac/shared-hosts:
* get:
* summary: Get shared hosts
* description: Retrieves the list of hosts that have been shared with the authenticated user.
* tags:
* - RBAC
* responses:
* 200:
* description: A list of shared hosts.
* 500:
* description: Failed to get shared hosts.
*/
router.get( router.get(
"/shared-hosts", "/shared-hosts",
authenticateJWT, authenticateJWT,
@@ -385,8 +489,20 @@ router.get(
}, },
); );
// Get all roles /**
// GET /rbac/roles * @openapi
* /rbac/roles:
* get:
* summary: Get all roles
* description: Retrieves a list of all roles.
* tags:
* - RBAC
* responses:
* 200:
* description: A list of roles.
* 500:
* description: Failed to get roles.
*/
router.get( router.get(
"/roles", "/roles",
authenticateJWT, authenticateJWT,
@@ -413,8 +529,20 @@ router.get(
}, },
); );
// Get all roles /**
// GET /rbac/roles * @openapi
* /rbac/roles:
* get:
* summary: Get all roles
* description: Retrieves a list of all roles.
* tags:
* - RBAC
* responses:
* 200:
* description: A list of roles.
* 500:
* description: Failed to get roles.
*/
router.get( router.get(
"/roles", "/roles",
authenticateJWT, authenticateJWT,
@@ -443,8 +571,37 @@ router.get(
}, },
); );
// Create new role /**
// POST /rbac/roles * @openapi
* /rbac/roles:
* post:
* summary: Create a new role
* description: Creates a new role.
* tags:
* - RBAC
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* displayName:
* type: string
* description:
* type: string
* responses:
* 201:
* description: Role created successfully.
* 400:
* description: Invalid request body.
* 409:
* description: A role with this name already exists.
* 500:
* description: Failed to create role.
*/
router.post( router.post(
"/roles", "/roles",
authenticateJWT, authenticateJWT,
@@ -503,8 +660,41 @@ router.post(
}, },
); );
// Update role /**
// PUT /rbac/roles/:id * @openapi
* /rbac/roles/{id}:
* put:
* summary: Update a role
* description: Updates a role by its ID.
* tags:
* - RBAC
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* displayName:
* type: string
* description:
* type: string
* responses:
* 200:
* description: Role updated successfully.
* 400:
* description: Invalid request body or role ID.
* 404:
* description: Role not found.
* 500:
* description: Failed to update role.
*/
router.put( router.put(
"/roles/:id", "/roles/:id",
authenticateJWT, authenticateJWT,
@@ -570,8 +760,32 @@ router.put(
}, },
); );
// Delete role /**
// DELETE /rbac/roles/:id * @openapi
* /rbac/roles/{id}:
* delete:
* summary: Delete a role
* description: Deletes a role by its ID.
* tags:
* - RBAC
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Role deleted successfully.
* 400:
* description: Invalid role ID.
* 403:
* description: Cannot delete system roles.
* 404:
* description: Role not found.
* 500:
* description: Failed to delete role.
*/
router.delete( router.delete(
"/roles/:id", "/roles/:id",
authenticateJWT, authenticateJWT,
@@ -634,8 +848,43 @@ router.delete(
}, },
); );
// Assign role to user /**
// POST /rbac/users/:userId/roles * @openapi
* /rbac/users/{userId}/roles:
* post:
* summary: Assign a role to a user
* description: Assigns a role to a user.
* tags:
* - RBAC
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* roleId:
* type: integer
* responses:
* 200:
* description: Role assigned successfully.
* 400:
* description: Role ID is required.
* 403:
* description: System roles cannot be manually assigned.
* 404:
* description: User or role not found.
* 409:
* description: Role already assigned.
* 500:
* description: Failed to assign role.
*/
router.post( router.post(
"/users/:userId/roles", "/users/:userId/roles",
authenticateJWT, authenticateJWT,
@@ -746,8 +995,37 @@ router.post(
}, },
); );
// Remove role from user /**
// DELETE /rbac/users/:userId/roles/:roleId * @openapi
* /rbac/users/{userId}/roles/{roleId}:
* delete:
* summary: Remove a role from a user
* description: Removes a role from a user.
* tags:
* - RBAC
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: string
* - in: path
* name: roleId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Role removed successfully.
* 400:
* description: Invalid role ID.
* 403:
* description: System roles cannot be removed.
* 404:
* description: Role not found.
* 500:
* description: Failed to remove role.
*/
router.delete( router.delete(
"/users/:userId/roles/:roleId", "/users/:userId/roles/:roleId",
authenticateJWT, authenticateJWT,
@@ -805,8 +1083,28 @@ router.delete(
}, },
); );
// Get user's roles /**
// GET /rbac/users/:userId/roles * @openapi
* /rbac/users/{userId}/roles:
* get:
* summary: Get user's roles
* description: Retrieves a list of roles for a specific user.
* tags:
* - RBAC
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: A list of roles.
* 403:
* description: Access denied.
* 500:
* description: Failed to get user roles.
*/
router.get( router.get(
"/users/:userId/roles", "/users/:userId/roles",
authenticateJWT, authenticateJWT,

View File

@@ -17,8 +17,22 @@ const authManager = AuthManager.getInstance();
const authenticateJWT = authManager.createAuthMiddleware(); const authenticateJWT = authManager.createAuthMiddleware();
const requireDataAccess = authManager.createDataAccessMiddleware(); const requireDataAccess = authManager.createDataAccessMiddleware();
// Get all snippet folders /**
// GET /snippets/folders * @openapi
* /snippets/folders:
* get:
* summary: Get all snippet folders
* description: Retrieves all snippet folders for the authenticated user.
* tags:
* - Snippets
* responses:
* 200:
* description: A list of snippet folders.
* 400:
* description: Invalid userId.
* 500:
* description: Failed to fetch snippet folders.
*/
router.get( router.get(
"/folders", "/folders",
authenticateJWT, authenticateJWT,
@@ -46,8 +60,37 @@ router.get(
}, },
); );
// Create a new snippet folder /**
// POST /snippets/folders * @openapi
* /snippets/folders:
* post:
* summary: Create a new snippet folder
* description: Creates a new snippet folder for the authenticated user.
* tags:
* - Snippets
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* color:
* type: string
* icon:
* type: string
* responses:
* 201:
* description: Snippet folder created successfully.
* 400:
* description: Folder name is required.
* 409:
* description: Folder with this name already exists.
* 500:
* description: Failed to create snippet folder.
*/
router.post( router.post(
"/folders", "/folders",
authenticateJWT, authenticateJWT,
@@ -110,8 +153,41 @@ router.post(
}, },
); );
// Update snippet folder metadata (color, icon) /**
// PUT /snippets/folders/:name/metadata * @openapi
* /snippets/folders/{name}/metadata:
* put:
* summary: Update snippet folder metadata
* description: Updates the metadata (color, icon) of a snippet folder.
* tags:
* - Snippets
* parameters:
* - in: path
* name: name
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* color:
* type: string
* icon:
* type: string
* responses:
* 200:
* description: Snippet folder metadata updated successfully.
* 400:
* description: Invalid request.
* 404:
* description: Folder not found.
* 500:
* description: Failed to update snippet folder metadata.
*/
router.put( router.put(
"/folders/:name/metadata", "/folders/:name/metadata",
authenticateJWT, authenticateJWT,
@@ -194,8 +270,37 @@ router.put(
}, },
); );
// Rename snippet folder /**
// PUT /snippets/folders/rename * @openapi
* /snippets/folders/rename:
* put:
* summary: Rename a snippet folder
* description: Renames a snippet folder for the authenticated user.
* tags:
* - Snippets
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* oldName:
* type: string
* newName:
* type: string
* responses:
* 200:
* description: Folder renamed successfully.
* 400:
* description: Invalid request.
* 404:
* description: Folder not found.
* 409:
* description: Folder with new name already exists.
* 500:
* description: Failed to rename snippet folder.
*/
router.put( router.put(
"/folders/rename", "/folders/rename",
authenticateJWT, authenticateJWT,
@@ -282,8 +387,28 @@ router.put(
}, },
); );
// Delete snippet folder /**
// DELETE /snippets/folders/:name * @openapi
* /snippets/folders/{name}:
* delete:
* summary: Delete a snippet folder
* description: Deletes a snippet folder and moves its snippets to the root.
* tags:
* - Snippets
* parameters:
* - in: path
* name: name
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Snippet folder deleted successfully.
* 400:
* description: Invalid request.
* 500:
* description: Failed to delete snippet folder.
*/
router.delete( router.delete(
"/folders/:name", "/folders/:name",
authenticateJWT, authenticateJWT,
@@ -338,8 +463,40 @@ router.delete(
}, },
); );
// Reorder snippets (bulk update) /**
// PUT /snippets/reorder * @openapi
* /snippets/reorder:
* put:
* summary: Reorder snippets
* description: Bulk updates the order and folder of snippets.
* tags:
* - Snippets
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* snippets:
* type: array
* items:
* type: object
* properties:
* id:
* type: integer
* order:
* type: integer
* folder:
* type: string
* responses:
* 200:
* description: Snippets reordered successfully.
* 400:
* description: Invalid request.
* 500:
* description: Failed to reorder snippets.
*/
router.put( router.put(
"/reorder", "/reorder",
authenticateJWT, authenticateJWT,
@@ -405,8 +562,35 @@ router.put(
}, },
); );
// Execute a snippet on a host /**
// POST /snippets/execute * @openapi
* /snippets/execute:
* post:
* summary: Execute a snippet on a host
* description: Executes a snippet on a specified host.
* tags:
* - Snippets
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* snippetId:
* type: integer
* hostId:
* type: integer
* responses:
* 200:
* description: Snippet executed successfully.
* 400:
* description: Snippet ID and Host ID are required.
* 404:
* description: Snippet or host not found.
* 500:
* description: Failed to execute snippet.
*/
router.post( router.post(
"/execute", "/execute",
authenticateJWT, authenticateJWT,
@@ -662,8 +846,22 @@ router.post(
}, },
); );
// Get all snippets for the authenticated user /**
// GET /snippets * @openapi
* /snippets:
* get:
* summary: Get all snippets
* description: Retrieves all snippets for the authenticated user.
* tags:
* - Snippets
* responses:
* 200:
* description: A list of snippets.
* 400:
* description: Invalid userId.
* 500:
* description: Failed to fetch snippets.
*/
router.get( router.get(
"/", "/",
authenticateJWT, authenticateJWT,
@@ -696,8 +894,30 @@ router.get(
}, },
); );
// Get a specific snippet by ID /**
// GET /snippets/:id * @openapi
* /snippets/{id}:
* get:
* summary: Get a specific snippet
* description: Retrieves a specific snippet by its ID.
* tags:
* - Snippets
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: The requested snippet.
* 400:
* description: Invalid request parameters.
* 404:
* description: Snippet not found.
* 500:
* description: Failed to fetch snippet.
*/
router.get( router.get(
"/:id", "/:id",
authenticateJWT, authenticateJWT,
@@ -735,8 +955,39 @@ router.get(
}, },
); );
// Create a new snippet /**
// POST /snippets * @openapi
* /snippets:
* post:
* summary: Create a new snippet
* description: Creates a new snippet for the authenticated user.
* tags:
* - Snippets
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* content:
* type: string
* description:
* type: string
* folder:
* type: string
* order:
* type: integer
* responses:
* 201:
* description: Snippet created successfully.
* 400:
* description: Name and content are required.
* 500:
* description: Failed to create snippet.
*/
router.post( router.post(
"/", "/",
authenticateJWT, authenticateJWT,
@@ -806,8 +1057,47 @@ router.post(
}, },
); );
// Update a snippet /**
// PUT /snippets/:id * @openapi
* /snippets/{id}:
* put:
* summary: Update a snippet
* description: Updates a specific snippet by its ID.
* tags:
* - Snippets
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* content:
* type: string
* description:
* type: string
* folder:
* type: string
* order:
* type: integer
* responses:
* 200:
* description: The updated snippet.
* 400:
* description: Invalid request.
* 404:
* description: Snippet not found.
* 500:
* description: Failed to update snippet.
*/
router.put( router.put(
"/:id", "/:id",
authenticateJWT, authenticateJWT,
@@ -883,8 +1173,30 @@ router.put(
}, },
); );
// Delete a snippet /**
// DELETE /snippets/:id * @openapi
* /snippets/{id}:
* delete:
* summary: Delete a snippet
* description: Deletes a specific snippet by its ID.
* tags:
* - Snippets
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Snippet deleted successfully.
* 400:
* description: Invalid request.
* 404:
* description: Snippet not found.
* 500:
* description: Failed to delete snippet.
*/
router.delete( router.delete(
"/:id", "/:id",
authenticateJWT, authenticateJWT,

File diff suppressed because it is too large Load Diff

View File

@@ -17,8 +17,33 @@ const authManager = AuthManager.getInstance();
const authenticateJWT = authManager.createAuthMiddleware(); const authenticateJWT = authManager.createAuthMiddleware();
const requireDataAccess = authManager.createDataAccessMiddleware(); const requireDataAccess = authManager.createDataAccessMiddleware();
// Save command to history /**
// POST /terminal/command_history * @openapi
* /terminal/command_history:
* post:
* summary: Save command to history
* description: Saves a command to the command history for a specific host.
* tags:
* - Terminal
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* hostId:
* type: integer
* command:
* type: string
* responses:
* 201:
* description: Command saved successfully.
* 400:
* description: Missing required parameters.
* 500:
* description: Failed to save command.
*/
router.post( router.post(
"/command_history", "/command_history",
authenticateJWT, authenticateJWT,
@@ -59,8 +84,28 @@ router.post(
}, },
); );
// Get command history for a specific host /**
// GET /terminal/command_history/:hostId * @openapi
* /terminal/command_history/{hostId}:
* get:
* summary: Get command history
* description: Retrieves the command history for a specific host.
* tags:
* - Terminal
* parameters:
* - in: path
* name: hostId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: A list of commands.
* 400:
* description: Invalid request parameters.
* 500:
* description: Failed to fetch history.
*/
router.get( router.get(
"/command_history/:hostId", "/command_history/:hostId",
authenticateJWT, authenticateJWT,
@@ -107,8 +152,33 @@ router.get(
}, },
); );
// Delete a specific command from history /**
// POST /terminal/command_history/delete * @openapi
* /terminal/command_history/delete:
* post:
* summary: Delete a specific command from history
* description: Deletes a specific command from the history of a host.
* tags:
* - Terminal
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* hostId:
* type: integer
* command:
* type: string
* responses:
* 200:
* description: Command deleted successfully.
* 400:
* description: Missing required parameters.
* 500:
* description: Failed to delete command.
*/
router.post( router.post(
"/command_history/delete", "/command_history/delete",
authenticateJWT, authenticateJWT,
@@ -150,8 +220,28 @@ router.post(
}, },
); );
// Clear command history for a specific host (optional feature) /**
// DELETE /terminal/command_history/:hostId * @openapi
* /terminal/command_history/{hostId}:
* delete:
* summary: Clear command history
* description: Clears the entire command history for a specific host.
* tags:
* - Terminal
* parameters:
* - in: path
* name: hostId
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Command history cleared successfully.
* 400:
* description: Invalid request.
* 500:
* description: Failed to clear history.
*/
router.delete( router.delete(
"/command_history/:hostId", "/command_history/:hostId",
authenticateJWT, authenticateJWT,

File diff suppressed because it is too large Load Diff

View File

@@ -365,7 +365,34 @@ app.use(express.urlencoded({ limit: "100mb", extended: true }));
const authManager = AuthManager.getInstance(); const authManager = AuthManager.getInstance();
app.use(authManager.createAuthMiddleware()); app.use(authManager.createAuthMiddleware());
// POST /docker/ssh/connect - Establish SSH session /**
* @openapi
* /docker/ssh/connect:
* post:
* summary: Establish SSH session for Docker
* description: Establishes an SSH session to a host for Docker operations.
* tags:
* - Docker
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* responses:
* 200:
* description: SSH connection established.
* 400:
* description: Missing sessionId or hostId.
* 401:
* description: Authentication required.
* 403:
* description: Docker is not enabled for this host.
* 404:
* description: Host not found.
* 500:
* description: SSH connection failed.
*/
app.post("/docker/ssh/connect", async (req, res) => { app.post("/docker/ssh/connect", async (req, res) => {
const { const {
sessionId, sessionId,
@@ -929,7 +956,29 @@ app.post("/docker/ssh/connect", async (req, res) => {
} }
}); });
// POST /docker/ssh/disconnect - Close SSH session /**
* @openapi
* /docker/ssh/disconnect:
* post:
* summary: Disconnect SSH session
* description: Closes an active SSH session for Docker operations.
* tags:
* - Docker
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* sessionId:
* type: string
* responses:
* 200:
* description: SSH session disconnected.
* 400:
* description: Session ID is required.
*/
app.post("/docker/ssh/disconnect", async (req, res) => { app.post("/docker/ssh/disconnect", async (req, res) => {
const { sessionId } = req.body; const { sessionId } = req.body;
@@ -942,7 +991,35 @@ app.post("/docker/ssh/disconnect", async (req, res) => {
res.json({ success: true, message: "SSH session disconnected" }); res.json({ success: true, message: "SSH session disconnected" });
}); });
// POST /docker/ssh/connect-totp - Verify TOTP and complete connection /**
* @openapi
* /docker/ssh/connect-totp:
* post:
* summary: Verify TOTP and complete connection
* description: Verifies the TOTP code and completes the SSH connection.
* tags:
* - Docker
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* sessionId:
* type: string
* totpCode:
* type: string
* responses:
* 200:
* description: TOTP verified, SSH connection established.
* 400:
* description: Session ID and TOTP code required.
* 401:
* description: Invalid TOTP code.
* 404:
* description: TOTP session expired.
*/
app.post("/docker/ssh/connect-totp", async (req, res) => { app.post("/docker/ssh/connect-totp", async (req, res) => {
const { sessionId, totpCode } = req.body; const { sessionId, totpCode } = req.body;
const userId = (req as any).userId; const userId = (req as any).userId;
@@ -1105,7 +1182,29 @@ app.post("/docker/ssh/connect-totp", async (req, res) => {
session.finish(responses); session.finish(responses);
}); });
// POST /docker/ssh/keepalive - Keep session alive /**
* @openapi
* /docker/ssh/keepalive:
* post:
* summary: Keep SSH session alive
* description: Keeps an active SSH session alive.
* tags:
* - Docker
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* sessionId:
* type: string
* responses:
* 200:
* description: Session keepalive successful.
* 400:
* description: Session ID is required or session not found.
*/
app.post("/docker/ssh/keepalive", async (req, res) => { app.post("/docker/ssh/keepalive", async (req, res) => {
const { sessionId } = req.body; const { sessionId } = req.body;
@@ -1133,7 +1232,26 @@ app.post("/docker/ssh/keepalive", async (req, res) => {
}); });
}); });
// GET /docker/ssh/status - Check session status /**
* @openapi
* /docker/ssh/status:
* get:
* summary: Check SSH session status
* description: Checks the status of an active SSH session.
* tags:
* - Docker
* parameters:
* - in: query
* name: sessionId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Session status.
* 400:
* description: Session ID is required.
*/
app.get("/docker/ssh/status", async (req, res) => { app.get("/docker/ssh/status", async (req, res) => {
const sessionId = req.query.sessionId as string; const sessionId = req.query.sessionId as string;
@@ -1146,7 +1264,28 @@ app.get("/docker/ssh/status", async (req, res) => {
res.json({ success: true, connected: isConnected }); res.json({ success: true, connected: isConnected });
}); });
// GET /docker/validate/:sessionId - Validate Docker availability /**
* @openapi
* /docker/validate/{sessionId}:
* get:
* summary: Validate Docker availability
* description: Validates if Docker is available on the host.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Docker availability status.
* 400:
* description: SSH session not found or not connected.
* 500:
* description: Validation failed.
*/
app.get("/docker/validate/:sessionId", async (req, res) => { app.get("/docker/validate/:sessionId", async (req, res) => {
const { sessionId } = req.params; const { sessionId } = req.params;
const userId = (req as any).userId; const userId = (req as any).userId;
@@ -1236,7 +1375,32 @@ app.get("/docker/validate/:sessionId", async (req, res) => {
} }
}); });
// GET /docker/containers/:sessionId - List all containers /**
* @openapi
* /docker/containers/{sessionId}:
* get:
* summary: List all containers
* description: Lists all Docker containers on the host.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: query
* name: all
* schema:
* type: boolean
* responses:
* 200:
* description: A list of containers.
* 400:
* description: SSH session not found or not connected.
* 500:
* description: Failed to list containers.
*/
app.get("/docker/containers/:sessionId", async (req, res) => { app.get("/docker/containers/:sessionId", async (req, res) => {
const { sessionId } = req.params; const { sessionId } = req.params;
const all = req.query.all !== "false"; const all = req.query.all !== "false";
@@ -1297,7 +1461,35 @@ app.get("/docker/containers/:sessionId", async (req, res) => {
} }
}); });
// GET /docker/containers/:sessionId/:containerId - Get container details /**
* @openapi
* /docker/containers/{sessionId}/{containerId}:
* get:
* summary: Get container details
* description: Retrieves detailed information about a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container details.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to get container details.
*/
app.get("/docker/containers/:sessionId/:containerId", async (req, res) => { app.get("/docker/containers/:sessionId/:containerId", async (req, res) => {
const { sessionId, containerId } = req.params; const { sessionId, containerId } = req.params;
const userId = (req as any).userId; const userId = (req as any).userId;
@@ -1356,7 +1548,35 @@ app.get("/docker/containers/:sessionId/:containerId", async (req, res) => {
} }
}); });
// POST /docker/containers/:sessionId/:containerId/start - Start container /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/start:
* post:
* summary: Start container
* description: Starts a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container started successfully.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to start container.
*/
app.post( app.post(
"/docker/containers/:sessionId/:containerId/start", "/docker/containers/:sessionId/:containerId/start",
async (req, res) => { async (req, res) => {
@@ -1414,7 +1634,35 @@ app.post(
}, },
); );
// POST /docker/containers/:sessionId/:containerId/stop - Stop container /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/stop:
* post:
* summary: Stop container
* description: Stops a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container stopped successfully.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to stop container.
*/
app.post( app.post(
"/docker/containers/:sessionId/:containerId/stop", "/docker/containers/:sessionId/:containerId/stop",
async (req, res) => { async (req, res) => {
@@ -1472,7 +1720,35 @@ app.post(
}, },
); );
// POST /docker/containers/:sessionId/:containerId/restart - Restart container /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/restart:
* post:
* summary: Restart container
* description: Restarts a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container restarted successfully.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to restart container.
*/
app.post( app.post(
"/docker/containers/:sessionId/:containerId/restart", "/docker/containers/:sessionId/:containerId/restart",
async (req, res) => { async (req, res) => {
@@ -1530,7 +1806,35 @@ app.post(
}, },
); );
// POST /docker/containers/:sessionId/:containerId/pause - Pause container /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/pause:
* post:
* summary: Pause container
* description: Pauses a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container paused successfully.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to pause container.
*/
app.post( app.post(
"/docker/containers/:sessionId/:containerId/pause", "/docker/containers/:sessionId/:containerId/pause",
async (req, res) => { async (req, res) => {
@@ -1588,7 +1892,35 @@ app.post(
}, },
); );
// POST /docker/containers/:sessionId/:containerId/unpause - Unpause container /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/unpause:
* post:
* summary: Unpause container
* description: Unpauses a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container unpaused successfully.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to unpause container.
*/
app.post( app.post(
"/docker/containers/:sessionId/:containerId/unpause", "/docker/containers/:sessionId/:containerId/unpause",
async (req, res) => { async (req, res) => {
@@ -1646,7 +1978,39 @@ app.post(
}, },
); );
// DELETE /docker/containers/:sessionId/:containerId/remove - Remove container /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/remove:
* delete:
* summary: Remove container
* description: Removes a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* - in: query
* name: force
* schema:
* type: boolean
* responses:
* 200:
* description: Container removed successfully.
* 400:
* description: SSH session not found or not connected, or cannot remove a running container.
* 404:
* description: Container not found.
* 500:
* description: Failed to remove container.
*/
app.delete( app.delete(
"/docker/containers/:sessionId/:containerId/remove", "/docker/containers/:sessionId/:containerId/remove",
async (req, res) => { async (req, res) => {
@@ -1718,7 +2082,51 @@ app.delete(
}, },
); );
// GET /docker/containers/:sessionId/:containerId/logs - Get container logs /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/logs:
* get:
* summary: Get container logs
* description: Retrieves logs for a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* - in: query
* name: tail
* schema:
* type: integer
* - in: query
* name: timestamps
* schema:
* type: boolean
* - in: query
* name: since
* schema:
* type: string
* - in: query
* name: until
* schema:
* type: string
* responses:
* 200:
* description: Container logs.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to get container logs.
*/
app.get("/docker/containers/:sessionId/:containerId/logs", async (req, res) => { app.get("/docker/containers/:sessionId/:containerId/logs", async (req, res) => {
const { sessionId, containerId } = req.params; const { sessionId, containerId } = req.params;
const tail = req.query.tail ? parseInt(req.query.tail as string) : 100; const tail = req.query.tail ? parseInt(req.query.tail as string) : 100;
@@ -1795,7 +2203,35 @@ app.get("/docker/containers/:sessionId/:containerId/logs", async (req, res) => {
} }
}); });
// GET /docker/containers/:sessionId/:containerId/stats - Get container stats /**
* @openapi
* /docker/containers/{sessionId}/{containerId}/stats:
* get:
* summary: Get container stats
* description: Retrieves stats for a specific container.
* tags:
* - Docker
* parameters:
* - in: path
* name: sessionId
* required: true
* schema:
* type: string
* - in: path
* name: containerId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Container stats.
* 400:
* description: SSH session not found or not connected.
* 404:
* description: Container not found.
* 500:
* description: Failed to get container stats.
*/
app.get( app.get(
"/docker/containers/:sessionId/:containerId/stats", "/docker/containers/:sessionId/:containerId/stats",
async (req, res) => { async (req, res) => {

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,8 @@ import { collectUptimeMetrics } from "./widgets/uptime-collector.js";
import { collectProcessesMetrics } from "./widgets/processes-collector.js"; import { collectProcessesMetrics } from "./widgets/processes-collector.js";
import { collectSystemMetrics } from "./widgets/system-collector.js"; import { collectSystemMetrics } from "./widgets/system-collector.js";
import { collectLoginStats } from "./widgets/login-stats-collector.js"; import { collectLoginStats } from "./widgets/login-stats-collector.js";
import { collectPortsMetrics } from "./widgets/ports-collector.js";
import { collectFirewallMetrics } from "./widgets/firewall-collector.js";
import { createSocks5Connection } from "../utils/socks5-helper.js"; import { createSocks5Connection } from "../utils/socks5-helper.js";
async function resolveJumpHost( async function resolveJumpHost(
@@ -1782,6 +1784,62 @@ async function collectMetrics(host: SSHHostWithCredentials): Promise<{
login_stats = await collectLoginStats(client); login_stats = await collectLoginStats(client);
} catch (e) {} } catch (e) {}
let ports: {
source: "ss" | "netstat" | "none";
ports: Array<{
protocol: "tcp" | "udp";
localAddress: string;
localPort: number;
state?: string;
pid?: number;
process?: string;
}>;
} = {
source: "none",
ports: [],
};
try {
ports = await collectPortsMetrics(client);
} catch (e) {
statsLogger.debug("Failed to collect ports metrics", {
operation: "ports_metrics_failed",
error: e instanceof Error ? e.message : String(e),
});
}
let firewall: {
type: "iptables" | "nftables" | "none";
status: "active" | "inactive" | "unknown";
chains: Array<{
name: string;
policy: string;
rules: Array<{
chain: string;
target: string;
protocol: string;
source: string;
destination: string;
dport?: string;
sport?: string;
state?: string;
interface?: string;
extra?: string;
}>;
}>;
} = {
type: "none",
status: "unknown",
chains: [],
};
try {
firewall = await collectFirewallMetrics(client);
} catch (e) {
statsLogger.debug("Failed to collect firewall metrics", {
operation: "firewall_metrics_failed",
error: e instanceof Error ? e.message : String(e),
});
}
const result = { const result = {
cpu, cpu,
memory, memory,
@@ -1791,6 +1849,8 @@ async function collectMetrics(host: SSHHostWithCredentials): Promise<{
processes, processes,
system, system,
login_stats, login_stats,
ports,
firewall,
}; };
metricsCache.set(host.id, result); metricsCache.set(host.id, result);
@@ -1864,6 +1924,20 @@ function tcpPing(
}); });
} }
/**
* @openapi
* /status:
* get:
* summary: Get all host statuses
* description: Retrieves the status of all hosts for the authenticated user.
* tags:
* - Server Stats
* responses:
* 200:
* description: A map of host IDs to their status entries.
* 401:
* description: Session expired - please log in again.
*/
app.get("/status", async (req, res) => { app.get("/status", async (req, res) => {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -1886,6 +1960,28 @@ app.get("/status", async (req, res) => {
res.json(result); res.json(result);
}); });
/**
* @openapi
* /status/{id}:
* get:
* summary: Get host status by ID
* description: Retrieves the status of a specific host by its ID.
* tags:
* - Server Stats
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Host status entry.
* 401:
* description: Session expired - please log in again.
* 404:
* description: Status not available.
*/
app.get("/status/:id", validateHostId, async (req, res) => { app.get("/status/:id", validateHostId, async (req, res) => {
const id = Number(req.params.id); const id = Number(req.params.id);
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -1910,6 +2006,20 @@ app.get("/status/:id", validateHostId, async (req, res) => {
res.json(statusEntry); res.json(statusEntry);
}); });
/**
* @openapi
* /clear-connections:
* post:
* summary: Clear all SSH connections
* description: Clears all SSH connections from the connection pool.
* tags:
* - Server Stats
* responses:
* 200:
* description: All SSH connections cleared.
* 401:
* description: Session expired - please log in again.
*/
app.post("/clear-connections", async (req, res) => { app.post("/clear-connections", async (req, res) => {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -1924,6 +2034,20 @@ app.post("/clear-connections", async (req, res) => {
res.json({ message: "All SSH connections cleared" }); res.json({ message: "All SSH connections cleared" });
}); });
/**
* @openapi
* /refresh:
* post:
* summary: Refresh polling
* description: Clears all SSH connections and refreshes host polling.
* tags:
* - Server Stats
* responses:
* 200:
* description: Polling refreshed.
* 401:
* description: Session expired - please log in again.
*/
app.post("/refresh", async (req, res) => { app.post("/refresh", async (req, res) => {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -1940,6 +2064,35 @@ app.post("/refresh", async (req, res) => {
res.json({ message: "Polling refreshed" }); res.json({ message: "Polling refreshed" });
}); });
/**
* @openapi
* /host-updated:
* post:
* summary: Start polling for updated host
* description: Starts polling for a specific host after it has been updated.
* tags:
* - Server Stats
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* hostId:
* type: integer
* responses:
* 200:
* description: Host polling started.
* 400:
* description: Invalid hostId.
* 401:
* description: Session expired - please log in again.
* 404:
* description: Host not found.
* 500:
* description: Failed to start polling.
*/
app.post("/host-updated", async (req, res) => { app.post("/host-updated", async (req, res) => {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
const { hostId } = req.body; const { hostId } = req.body;
@@ -1975,6 +2128,33 @@ app.post("/host-updated", async (req, res) => {
} }
}); });
/**
* @openapi
* /host-deleted:
* post:
* summary: Stop polling for deleted host
* description: Stops polling for a specific host after it has been deleted.
* tags:
* - Server Stats
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* hostId:
* type: integer
* responses:
* 200:
* description: Host polling stopped.
* 400:
* description: Invalid hostId.
* 401:
* description: Session expired - please log in again.
* 500:
* description: Failed to stop polling.
*/
app.post("/host-deleted", async (req, res) => { app.post("/host-deleted", async (req, res) => {
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
const { hostId } = req.body; const { hostId } = req.body;
@@ -2003,6 +2183,28 @@ app.post("/host-deleted", async (req, res) => {
} }
}); });
/**
* @openapi
* /metrics/{id}:
* get:
* summary: Get host metrics
* description: Retrieves current metrics for a specific host including CPU, memory, disk, network, processes, and system information.
* tags:
* - Server Stats
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Host metrics data.
* 401:
* description: Session expired - please log in again.
* 404:
* description: Metrics not available.
*/
app.get("/metrics/:id", validateHostId, async (req, res) => { app.get("/metrics/:id", validateHostId, async (req, res) => {
const id = Number(req.params.id); const id = Number(req.params.id);
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -2040,6 +2242,30 @@ app.get("/metrics/:id", validateHostId, async (req, res) => {
}); });
}); });
/**
* @openapi
* /metrics/start/{id}:
* post:
* summary: Start metrics collection
* description: Establishes an SSH connection and starts collecting metrics for a specific host.
* tags:
* - Server Stats
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Metrics collection started successfully, or TOTP required.
* 401:
* description: Session expired - please log in again.
* 404:
* description: Host not found.
* 500:
* description: Failed to start metrics collection.
*/
app.post("/metrics/start/:id", validateHostId, async (req, res) => { app.post("/metrics/start/:id", validateHostId, async (req, res) => {
const id = Number(req.params.id); const id = Number(req.params.id);
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -2219,6 +2445,37 @@ app.post("/metrics/start/:id", validateHostId, async (req, res) => {
} }
}); });
/**
* @openapi
* /metrics/stop/{id}:
* post:
* summary: Stop metrics collection
* description: Stops metrics collection for a specific host and cleans up the SSH session.
* tags:
* - Server Stats
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: false
* content:
* application/json:
* schema:
* type: object
* properties:
* viewerSessionId:
* type: string
* responses:
* 200:
* description: Metrics collection stopped successfully.
* 401:
* description: Session expired - please log in again.
* 500:
* description: Failed to stop metrics collection.
*/
app.post("/metrics/stop/:id", validateHostId, async (req, res) => { app.post("/metrics/stop/:id", validateHostId, async (req, res) => {
const id = Number(req.params.id); const id = Number(req.params.id);
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -2261,6 +2518,37 @@ app.post("/metrics/stop/:id", validateHostId, async (req, res) => {
} }
}); });
/**
* @openapi
* /metrics/connect-totp:
* post:
* summary: Complete TOTP verification for metrics
* description: Verifies the TOTP code and completes the metrics SSH connection.
* tags:
* - Server Stats
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* sessionId:
* type: string
* totpCode:
* type: string
* responses:
* 200:
* description: TOTP verified, metrics connection established.
* 400:
* description: Missing sessionId or totpCode.
* 401:
* description: Session expired or invalid TOTP code.
* 404:
* description: TOTP session not found or expired.
* 500:
* description: Failed to verify TOTP.
*/
app.post("/metrics/connect-totp", async (req, res) => { app.post("/metrics/connect-totp", async (req, res) => {
const { sessionId, totpCode } = req.body; const { sessionId, totpCode } = req.body;
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -2396,6 +2684,35 @@ app.post("/metrics/connect-totp", async (req, res) => {
} }
}); });
/**
* @openapi
* /metrics/heartbeat:
* post:
* summary: Update viewer heartbeat
* description: Updates the heartbeat timestamp for a metrics viewer session to keep it alive.
* tags:
* - Server Stats
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* viewerSessionId:
* type: string
* responses:
* 200:
* description: Heartbeat updated successfully.
* 400:
* description: Invalid viewerSessionId.
* 401:
* description: Session expired - please log in again.
* 404:
* description: Viewer session not found.
* 500:
* description: Failed to update heartbeat.
*/
app.post("/metrics/heartbeat", async (req, res) => { app.post("/metrics/heartbeat", async (req, res) => {
const { viewerSessionId } = req.body; const { viewerSessionId } = req.body;
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -2428,6 +2745,33 @@ app.post("/metrics/heartbeat", async (req, res) => {
} }
}); });
/**
* @openapi
* /metrics/register-viewer:
* post:
* summary: Register metrics viewer
* description: Registers a new viewer session for a host to track who is viewing metrics.
* tags:
* - Server Stats
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* hostId:
* type: integer
* responses:
* 200:
* description: Viewer registered successfully.
* 400:
* description: Invalid hostId.
* 401:
* description: Session expired - please log in again.
* 500:
* description: Failed to register viewer.
*/
app.post("/metrics/register-viewer", async (req, res) => { app.post("/metrics/register-viewer", async (req, res) => {
const { hostId } = req.body; const { hostId } = req.body;
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;
@@ -2458,6 +2802,35 @@ app.post("/metrics/register-viewer", async (req, res) => {
} }
}); });
/**
* @openapi
* /metrics/unregister-viewer:
* post:
* summary: Unregister metrics viewer
* description: Unregisters a viewer session when they stop viewing metrics for a host.
* tags:
* - Server Stats
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* hostId:
* type: integer
* viewerSessionId:
* type: string
* responses:
* 200:
* description: Viewer unregistered successfully.
* 400:
* description: Invalid hostId or viewerSessionId.
* 401:
* description: Session expired - please log in again.
* 500:
* description: Failed to unregister viewer.
*/
app.post("/metrics/unregister-viewer", async (req, res) => { app.post("/metrics/unregister-viewer", async (req, res) => {
const { hostId, viewerSessionId } = req.body; const { hostId, viewerSessionId } = req.body;
const userId = (req as AuthenticatedRequest).userId; const userId = (req as AuthenticatedRequest).userId;

View File

@@ -648,7 +648,7 @@ wss.on("connection", async (ws: WebSocket, req) => {
); );
cleanupSSH(connectionTimeout); cleanupSSH(connectionTimeout);
} }
}, 30000); }, 120000);
let resolvedCredentials = { password, key, keyPassword, keyType, authType }; let resolvedCredentials = { password, key, keyPassword, keyType, authType };
let authMethodNotAvailable = false; let authMethodNotAvailable = false;
@@ -761,6 +761,36 @@ wss.on("connection", async (ws: WebSocket, req) => {
return; return;
} }
sshLogger.info("Creating shell", {
operation: "ssh_shell_start",
hostId: id,
ip,
port,
username,
});
let shellCallbackReceived = false;
const shellTimeout = setTimeout(() => {
if (!shellCallbackReceived && isShellInitializing) {
sshLogger.error("Shell creation timeout - no response from server", {
operation: "ssh_shell_timeout",
hostId: id,
ip,
port,
username,
});
isShellInitializing = false;
ws.send(
JSON.stringify({
type: "error",
message:
"Shell creation timeout. The server may not support interactive shells or the connection was interrupted.",
}),
);
cleanupSSH(connectionTimeout);
}
}, 15000);
conn.shell( conn.shell(
{ {
rows: data.rows, rows: data.rows,
@@ -768,6 +798,8 @@ wss.on("connection", async (ws: WebSocket, req) => {
term: "xterm-256color", term: "xterm-256color",
} as PseudoTtyOptions, } as PseudoTtyOptions,
(err, stream) => { (err, stream) => {
shellCallbackReceived = true;
clearTimeout(shellTimeout);
isShellInitializing = false; isShellInitializing = false;
if (err) { if (err) {
@@ -784,6 +816,7 @@ wss.on("connection", async (ws: WebSocket, req) => {
message: "Shell error: " + err.message, message: "Shell error: " + err.message,
}), }),
); );
cleanupSSH(connectionTimeout);
return; return;
} }
@@ -969,6 +1002,31 @@ wss.on("connection", async (ws: WebSocket, req) => {
sshConn.on("close", () => { sshConn.on("close", () => {
clearTimeout(connectionTimeout); clearTimeout(connectionTimeout);
if (isShellInitializing || (isConnected && !sshStream)) {
sshLogger.warn("SSH connection closed during shell initialization", {
operation: "ssh_close_during_init",
hostId: id,
ip,
port,
username,
isShellInitializing,
hasStream: !!sshStream,
});
ws.send(
JSON.stringify({
type: "error",
message:
"Connection closed during shell initialization. The server may have rejected the shell request.",
}),
);
} else if (!sshStream) {
ws.send(
JSON.stringify({
type: "disconnected",
message: "Connection closed",
}),
);
}
cleanupSSH(connectionTimeout); cleanupSSH(connectionTimeout);
}); });
@@ -1115,10 +1173,10 @@ wss.on("connection", async (ws: WebSocket, req) => {
tryKeyboard: true, tryKeyboard: true,
keepaliveInterval: 30000, keepaliveInterval: 30000,
keepaliveCountMax: 3, keepaliveCountMax: 3,
readyTimeout: 30000, readyTimeout: 120000,
tcpKeepAlive: true, tcpKeepAlive: true,
tcpKeepAliveInitialDelay: 30000, tcpKeepAliveInitialDelay: 30000,
timeout: 30000, timeout: 120000,
env: { env: {
TERM: "xterm-256color", TERM: "xterm-256color",
LANG: "en_US.UTF-8", LANG: "en_US.UTF-8",

View File

@@ -828,15 +828,22 @@ async function connectSSHTunnel(
return; return;
} }
const tunnelType = tunnelConfig.tunnelType || "remote";
const tunnelFlag = tunnelType === "local" ? "-L" : "-R";
const portMapping =
tunnelType === "local"
? `${tunnelConfig.sourcePort}:${tunnelConfig.endpointIP}:${tunnelConfig.endpointPort}`
: `${tunnelConfig.endpointPort}:localhost:${tunnelConfig.sourcePort}`;
let tunnelCmd: string; let tunnelCmd: string;
if ( if (
resolvedEndpointCredentials.authMethod === "key" && resolvedEndpointCredentials.authMethod === "key" &&
resolvedEndpointCredentials.sshKey resolvedEndpointCredentials.sshKey
) { ) {
const keyFilePath = `/tmp/tunnel_key_${tunnelName.replace(/[^a-zA-Z0-9]/g, "_")}`; const keyFilePath = `/tmp/tunnel_key_${tunnelName.replace(/[^a-zA-Z0-9]/g, "_")}`;
tunnelCmd = `echo '${resolvedEndpointCredentials.sshKey}' > ${keyFilePath} && chmod 600 ${keyFilePath} && exec -a "${tunnelMarker}" ssh -i ${keyFilePath} -N -o StrictHostKeyChecking=no -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o GatewayPorts=yes -R ${tunnelConfig.endpointPort}:localhost:${tunnelConfig.sourcePort} ${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP} && rm -f ${keyFilePath}`; tunnelCmd = `echo '${resolvedEndpointCredentials.sshKey}' > ${keyFilePath} && chmod 600 ${keyFilePath} && exec -a "${tunnelMarker}" ssh -i ${keyFilePath} -N -o StrictHostKeyChecking=no -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o GatewayPorts=yes ${tunnelFlag} ${portMapping} ${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP} && rm -f ${keyFilePath}`;
} else { } else {
tunnelCmd = `exec -a "${tunnelMarker}" sshpass -p '${resolvedEndpointCredentials.password || ""}' ssh -N -o StrictHostKeyChecking=no -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o GatewayPorts=yes -R ${tunnelConfig.endpointPort}:localhost:${tunnelConfig.sourcePort} ${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}`; tunnelCmd = `exec -a "${tunnelMarker}" sshpass -p '${resolvedEndpointCredentials.password || ""}' ssh -N -o StrictHostKeyChecking=no -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o GatewayPorts=yes ${tunnelFlag} ${portMapping} ${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}`;
} }
conn.exec(tunnelCmd, (err, stream) => { conn.exec(tunnelCmd, (err, stream) => {
@@ -1302,7 +1309,9 @@ async function killRemoteTunnelByMarker(
} }
conn.on("ready", () => { conn.on("ready", () => {
const checkCmd = `ps aux | grep -E '(${tunnelMarker}|ssh.*-R.*${tunnelConfig.endpointPort}:localhost:${tunnelConfig.sourcePort}.*${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}|sshpass.*ssh.*-R.*${tunnelConfig.endpointPort})' | grep -v grep`; const tunnelType = tunnelConfig.tunnelType || "remote";
const tunnelFlag = tunnelType === "local" ? "-L" : "-R";
const checkCmd = `ps aux | grep -E '(${tunnelMarker}|ssh.*${tunnelFlag}.*${tunnelConfig.endpointPort}:.*:${tunnelConfig.sourcePort}.*${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}|sshpass.*ssh.*${tunnelFlag})' | grep -v grep`;
conn.exec(checkCmd, (_err, stream) => { conn.exec(checkCmd, (_err, stream) => {
let foundProcesses = false; let foundProcesses = false;
@@ -1323,8 +1332,8 @@ async function killRemoteTunnelByMarker(
const killCmds = [ const killCmds = [
`pkill -TERM -f '${tunnelMarker}'`, `pkill -TERM -f '${tunnelMarker}'`,
`sleep 1 && pkill -f 'ssh.*-R.*${tunnelConfig.endpointPort}:localhost:${tunnelConfig.sourcePort}.*${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}'`, `sleep 1 && pkill -f 'ssh.*${tunnelFlag}.*${tunnelConfig.endpointPort}:.*:${tunnelConfig.sourcePort}.*${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}'`,
`sleep 1 && pkill -f 'sshpass.*ssh.*-R.*${tunnelConfig.endpointPort}'`, `sleep 1 && pkill -f 'sshpass.*ssh.*${tunnelFlag}.*${tunnelConfig.endpointPort}'`,
`sleep 2 && pkill -9 -f '${tunnelMarker}'`, `sleep 2 && pkill -9 -f '${tunnelMarker}'`,
]; ];
@@ -1450,10 +1459,42 @@ async function killRemoteTunnelByMarker(
} }
} }
/**
* @openapi
* /ssh/tunnel/status:
* get:
* summary: Get all tunnel statuses
* description: Retrieves the status of all SSH tunnels.
* tags:
* - SSH Tunnels
* responses:
* 200:
* description: A list of all tunnel statuses.
*/
app.get("/ssh/tunnel/status", (req, res) => { app.get("/ssh/tunnel/status", (req, res) => {
res.json(getAllTunnelStatus()); res.json(getAllTunnelStatus());
}); });
/**
* @openapi
* /ssh/tunnel/status/{tunnelName}:
* get:
* summary: Get tunnel status by name
* description: Retrieves the status of a specific SSH tunnel by its name.
* tags:
* - SSH Tunnels
* parameters:
* - in: path
* name: tunnelName
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Tunnel status.
* 404:
* description: Tunnel not found.
*/
app.get("/ssh/tunnel/status/:tunnelName", (req, res) => { app.get("/ssh/tunnel/status/:tunnelName", (req, res) => {
const { tunnelName } = req.params; const { tunnelName } = req.params;
const status = connectionStatus.get(tunnelName); const status = connectionStatus.get(tunnelName);
@@ -1465,6 +1506,39 @@ app.get("/ssh/tunnel/status/:tunnelName", (req, res) => {
res.json({ name: tunnelName, status }); res.json({ name: tunnelName, status });
}); });
/**
* @openapi
* /ssh/tunnel/connect:
* post:
* summary: Connect SSH tunnel
* description: Establishes an SSH tunnel connection with the specified configuration.
* tags:
* - SSH Tunnels
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* sourceHostId:
* type: integer
* tunnelIndex:
* type: integer
* responses:
* 200:
* description: Connection request received.
* 400:
* description: Invalid tunnel configuration.
* 401:
* description: Authentication required.
* 403:
* description: Access denied to this host.
* 500:
* description: Failed to connect tunnel.
*/
app.post( app.post(
"/ssh/tunnel/connect", "/ssh/tunnel/connect",
authenticateJWT, authenticateJWT,
@@ -1619,6 +1693,35 @@ app.post(
}, },
); );
/**
* @openapi
* /ssh/tunnel/disconnect:
* post:
* summary: Disconnect SSH tunnel
* description: Disconnects an active SSH tunnel.
* tags:
* - SSH Tunnels
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* tunnelName:
* type: string
* responses:
* 200:
* description: Disconnect request received.
* 400:
* description: Tunnel name required.
* 401:
* description: Authentication required.
* 403:
* description: Access denied.
* 500:
* description: Failed to disconnect tunnel.
*/
app.post( app.post(
"/ssh/tunnel/disconnect", "/ssh/tunnel/disconnect",
authenticateJWT, authenticateJWT,
@@ -1683,6 +1786,35 @@ app.post(
}, },
); );
/**
* @openapi
* /ssh/tunnel/cancel:
* post:
* summary: Cancel tunnel retry
* description: Cancels the retry mechanism for a failed SSH tunnel connection.
* tags:
* - SSH Tunnels
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* tunnelName:
* type: string
* responses:
* 200:
* description: Cancel request received.
* 400:
* description: Tunnel name required.
* 401:
* description: Authentication required.
* 403:
* description: Access denied.
* 500:
* description: Failed to cancel tunnel retry.
*/
app.post( app.post(
"/ssh/tunnel/cancel", "/ssh/tunnel/cancel",
authenticateJWT, authenticateJWT,
@@ -1806,6 +1938,7 @@ async function initializeAutoStartTunnels(): Promise<void> {
tunnelConnection.endpointHost, tunnelConnection.endpointHost,
tunnelConnection.endpointPort, tunnelConnection.endpointPort,
), ),
tunnelType: tunnelConnection.tunnelType || "remote",
sourceHostId: host.id, sourceHostId: host.id,
tunnelIndex: tunnelIndex, tunnelIndex: tunnelIndex,
hostName: host.name || `${host.username}@${host.ip}`, hostName: host.name || `${host.username}@${host.ip}`,

View File

@@ -0,0 +1,254 @@
import type { Client } from "ssh2";
import { execCommand } from "./common-utils.js";
import type {
FirewallMetrics,
FirewallChain,
FirewallRule,
} from "../../../types/stats-widgets.js";
function parseIptablesRule(line: string): FirewallRule | null {
if (!line.startsWith("-A ")) return null;
const rule: FirewallRule = {
chain: "",
target: "",
protocol: "all",
source: "0.0.0.0/0",
destination: "0.0.0.0/0",
};
const chainMatch = line.match(/^-A\s+(\S+)/);
if (chainMatch) {
rule.chain = chainMatch[1];
}
const targetMatch = line.match(/-j\s+(\S+)/);
if (targetMatch) {
rule.target = targetMatch[1];
}
const protocolMatch = line.match(/-p\s+(\S+)/);
if (protocolMatch) {
rule.protocol = protocolMatch[1];
}
const sourceMatch = line.match(/-s\s+(\S+)/);
if (sourceMatch) {
rule.source = sourceMatch[1];
}
const destMatch = line.match(/-d\s+(\S+)/);
if (destMatch) {
rule.destination = destMatch[1];
}
const dportMatch = line.match(/--dport\s+(\S+)/);
if (dportMatch) {
rule.dport = dportMatch[1];
}
const sportMatch = line.match(/--sport\s+(\S+)/);
if (sportMatch) {
rule.sport = sportMatch[1];
}
const stateMatch = line.match(/--state\s+(\S+)/);
if (stateMatch) {
rule.state = stateMatch[1];
}
const interfaceMatch = line.match(/-i\s+(\S+)/);
if (interfaceMatch) {
rule.interface = interfaceMatch[1];
}
return rule;
}
function parseIptablesOutput(output: string): FirewallChain[] {
const chains: Map<string, FirewallChain> = new Map();
const lines = output.split("\n");
for (const line of lines) {
const trimmed = line.trim();
const policyMatch = trimmed.match(/^:(\S+)\s+(\S+)/);
if (policyMatch) {
const [, chainName, policy] = policyMatch;
chains.set(chainName, {
name: chainName,
policy: policy,
rules: [],
});
continue;
}
const rule = parseIptablesRule(trimmed);
if (rule) {
let chain = chains.get(rule.chain);
if (!chain) {
chain = {
name: rule.chain,
policy: "ACCEPT",
rules: [],
};
chains.set(rule.chain, chain);
}
chain.rules.push(rule);
}
}
return Array.from(chains.values());
}
function parseNftablesOutput(output: string): FirewallChain[] {
const chains: FirewallChain[] = [];
let currentChain: FirewallChain | null = null;
const lines = output.split("\n");
for (const line of lines) {
const trimmed = line.trim();
const chainMatch = trimmed.match(
/chain\s+(\S+)\s*\{?\s*(?:type\s+\S+\s+hook\s+(\S+))?/,
);
if (chainMatch) {
if (currentChain) {
chains.push(currentChain);
}
currentChain = {
name: chainMatch[1].toUpperCase(),
policy: "ACCEPT",
rules: [],
};
continue;
}
if (currentChain && trimmed.startsWith("policy ")) {
const policyMatch = trimmed.match(/policy\s+(\S+)/);
if (policyMatch) {
currentChain.policy = policyMatch[1].toUpperCase();
}
continue;
}
if (currentChain && trimmed && !trimmed.startsWith("}")) {
const rule: FirewallRule = {
chain: currentChain.name,
target: "",
protocol: "all",
source: "0.0.0.0/0",
destination: "0.0.0.0/0",
};
if (trimmed.includes("accept")) rule.target = "ACCEPT";
else if (trimmed.includes("drop")) rule.target = "DROP";
else if (trimmed.includes("reject")) rule.target = "REJECT";
const tcpMatch = trimmed.match(/tcp\s+dport\s+(\S+)/);
if (tcpMatch) {
rule.protocol = "tcp";
rule.dport = tcpMatch[1];
}
const udpMatch = trimmed.match(/udp\s+dport\s+(\S+)/);
if (udpMatch) {
rule.protocol = "udp";
rule.dport = udpMatch[1];
}
const saddrMatch = trimmed.match(/saddr\s+(\S+)/);
if (saddrMatch) {
rule.source = saddrMatch[1];
}
const daddrMatch = trimmed.match(/daddr\s+(\S+)/);
if (daddrMatch) {
rule.destination = daddrMatch[1];
}
const iifMatch = trimmed.match(/iif\s+"?(\S+)"?/);
if (iifMatch) {
rule.interface = iifMatch[1].replace(/"/g, "");
}
const ctStateMatch = trimmed.match(/ct\s+state\s+(\S+)/);
if (ctStateMatch) {
rule.state = ctStateMatch[1].toUpperCase();
}
if (rule.target) {
currentChain.rules.push(rule);
}
}
if (trimmed === "}") {
if (currentChain) {
chains.push(currentChain);
currentChain = null;
}
}
}
if (currentChain) {
chains.push(currentChain);
}
return chains;
}
export async function collectFirewallMetrics(
client: Client,
): Promise<FirewallMetrics> {
try {
const iptablesResult = await execCommand(
client,
"iptables-save 2>/dev/null",
15000,
);
if (iptablesResult.stdout && iptablesResult.stdout.includes("*filter")) {
const chains = parseIptablesOutput(iptablesResult.stdout);
const hasRules = chains.some((c) => c.rules.length > 0);
return {
type: "iptables",
status: hasRules ? "active" : "inactive",
chains: chains.filter(
(c) =>
c.name === "INPUT" || c.name === "OUTPUT" || c.name === "FORWARD",
),
};
}
const nftResult = await execCommand(
client,
"nft list ruleset 2>/dev/null",
15000,
);
if (nftResult.stdout && nftResult.stdout.trim()) {
const chains = parseNftablesOutput(nftResult.stdout);
const hasRules = chains.some((c) => c.rules.length > 0);
return {
type: "nftables",
status: hasRules ? "active" : "inactive",
chains,
};
}
return {
type: "none",
status: "unknown",
chains: [],
};
} catch {
return {
type: "none",
status: "unknown",
chains: [],
};
}
}

View File

@@ -0,0 +1,155 @@
import type { Client } from "ssh2";
import { execCommand } from "./common-utils.js";
import type { PortsMetrics, ListeningPort } from "../../../types/stats-widgets.js";
function parseSsOutput(output: string): ListeningPort[] {
const ports: ListeningPort[] = [];
const lines = output.split("\n").slice(1);
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) continue;
const parts = trimmed.split(/\s+/);
if (parts.length < 5) continue;
const protocol = parts[0]?.toLowerCase();
if (protocol !== "tcp" && protocol !== "udp") continue;
const state = parts[1];
const localAddr = parts[4];
if (!localAddr) continue;
const lastColon = localAddr.lastIndexOf(":");
if (lastColon === -1) continue;
const address = localAddr.substring(0, lastColon);
const portStr = localAddr.substring(lastColon + 1);
const port = parseInt(portStr, 10);
if (isNaN(port)) continue;
const portEntry: ListeningPort = {
protocol: protocol as "tcp" | "udp",
localAddress: address.replace(/^\[|\]$/g, ""),
localPort: port,
state: protocol === "tcp" ? state : undefined,
};
const processInfo = parts[6];
if (processInfo && processInfo.startsWith("users:")) {
const pidMatch = processInfo.match(/pid=(\d+)/);
const nameMatch = processInfo.match(/\("([^"]+)"/);
if (pidMatch) portEntry.pid = parseInt(pidMatch[1], 10);
if (nameMatch) portEntry.process = nameMatch[1];
}
ports.push(portEntry);
}
return ports;
}
function parseNetstatOutput(output: string): ListeningPort[] {
const ports: ListeningPort[] = [];
const lines = output.split("\n");
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) continue;
const parts = trimmed.split(/\s+/);
if (parts.length < 4) continue;
const proto = parts[0]?.toLowerCase();
if (!proto) continue;
let protocol: "tcp" | "udp";
if (proto.startsWith("tcp")) {
protocol = "tcp";
} else if (proto.startsWith("udp")) {
protocol = "udp";
} else {
continue;
}
const localAddr = parts[3];
if (!localAddr) continue;
const lastColon = localAddr.lastIndexOf(":");
if (lastColon === -1) continue;
const address = localAddr.substring(0, lastColon);
const portStr = localAddr.substring(lastColon + 1);
const port = parseInt(portStr, 10);
if (isNaN(port)) continue;
const portEntry: ListeningPort = {
protocol,
localAddress: address,
localPort: port,
};
if (protocol === "tcp" && parts.length >= 6) {
portEntry.state = parts[5];
}
const pidProgram = parts[parts.length - 1];
if (pidProgram && pidProgram.includes("/")) {
const [pidStr, process] = pidProgram.split("/");
const pid = parseInt(pidStr, 10);
if (!isNaN(pid)) portEntry.pid = pid;
if (process) portEntry.process = process;
}
ports.push(portEntry);
}
return ports;
}
export async function collectPortsMetrics(
client: Client,
): Promise<PortsMetrics> {
try {
const ssResult = await execCommand(
client,
"ss -tulnp 2>/dev/null",
15000,
);
if (ssResult.stdout && ssResult.stdout.includes("Local")) {
const ports = parseSsOutput(ssResult.stdout);
return {
source: "ss",
ports: ports.sort((a, b) => a.localPort - b.localPort),
};
}
const netstatResult = await execCommand(
client,
"netstat -tulnp 2>/dev/null",
15000,
);
if (netstatResult.stdout && netstatResult.stdout.includes("Local")) {
const ports = parseNetstatOutput(netstatResult.stdout);
return {
source: "netstat",
ports: ports.sort((a, b) => a.localPort - b.localPort),
};
}
return {
source: "none",
ports: [],
};
} catch {
return {
source: "none",
ports: [],
};
}
}

145
src/backend/swagger.ts Normal file
View File

@@ -0,0 +1,145 @@
import swaggerJSDoc from "swagger-jsdoc";
import path from "path";
import { fileURLToPath } from "url";
import { promises as fs } from "fs";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.join(__dirname, "..", "..", "..");
const swaggerOptions: swaggerJSDoc.Options = {
definition: {
openapi: "3.0.3",
info: {
title: "Termix API",
version: "0.0.0",
description: "Termix Backend API Reference",
},
servers: [
{
url: "http://localhost:30001",
description: "Main database and authentication server",
},
{
url: "http://localhost:30003",
description: "SSH tunnel management server",
},
{
url: "http://localhost:30004",
description: "SSH file manager server",
},
{
url: "http://localhost:30005",
description: "Server statistics and monitoring server",
},
{
url: "http://localhost:30006",
description: "Dashboard server",
},
{
url: "http://localhost:30007",
description: "Docker management server",
},
],
components: {
securitySchemes: {
bearerAuth: {
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
},
},
schemas: {
Error: {
type: "object",
properties: {
error: { type: "string" },
details: { type: "string" },
},
},
},
},
security: [
{
bearerAuth: [],
},
],
tags: [
{
name: "Alerts",
description: "System alerts and notifications management",
},
{
name: "Credentials",
description: "SSH credential management",
},
{
name: "Network Topology",
description: "Network topology visualization and management",
},
{
name: "RBAC",
description: "Role-based access control for host sharing",
},
{
name: "Snippets",
description: "Command snippet management",
},
{
name: "Terminal",
description: "Terminal command history",
},
{
name: "Users",
description: "User management and authentication",
},
{
name: "Dashboard",
description: "Dashboard statistics and activity",
},
{
name: "Docker",
description: "Docker container management",
},
{
name: "SSH Tunnels",
description: "SSH tunnel connection management",
},
{
name: "Server Stats",
description: "Server status monitoring and metrics collection",
},
{
name: "File Manager",
description: "SSH file management operations",
},
],
},
apis: [
path.join(projectRoot, "src", "backend", "database", "routes", "*.ts"),
path.join(projectRoot, "src", "backend", "dashboard.ts"),
path.join(projectRoot, "src", "backend", "ssh", "*.ts"),
],
};
async function generateOpenAPISpec() {
try {
const swaggerSpec = swaggerJSDoc(swaggerOptions);
const outputPath = path.join(projectRoot, "openapi.json");
await fs.writeFile(
outputPath,
JSON.stringify(swaggerSpec, null, 2),
"utf-8",
);
} catch (error) {
console.error("Failed to generate OpenAPI specification:", error);
process.exit(1);
}
}
generateOpenAPISpec();
export { swaggerOptions, generateOpenAPISpec };

View File

@@ -32,7 +32,6 @@ class FieldCrypto {
"key", "key",
"key_password", "key_password",
"keyPassword", "keyPassword",
"keyType",
"autostartPassword", "autostartPassword",
"autostartKey", "autostartKey",
"autostartKeyPassword", "autostartKeyPassword",
@@ -46,7 +45,6 @@ class FieldCrypto {
"key", "key",
"public_key", "public_key",
"publicKey", "publicKey",
"keyType",
]), ]),
}; };

View File

@@ -7,11 +7,21 @@ interface LoginAttempt {
class LoginRateLimiter { class LoginRateLimiter {
private ipAttempts = new Map<string, LoginAttempt>(); private ipAttempts = new Map<string, LoginAttempt>();
private usernameAttempts = new Map<string, LoginAttempt>(); private usernameAttempts = new Map<string, LoginAttempt>();
private totpAttempts = new Map<string, LoginAttempt>();
private resetCodeAttempts = new Map<string, LoginAttempt>();
private readonly MAX_ATTEMPTS = 5; private readonly MAX_ATTEMPTS = 5;
private readonly WINDOW_MS = 10 * 60 * 1000; private readonly WINDOW_MS = 10 * 60 * 1000;
private readonly LOCKOUT_MS = 10 * 60 * 1000; private readonly LOCKOUT_MS = 10 * 60 * 1000;
private readonly TOTP_MAX_ATTEMPTS = 5;
private readonly TOTP_WINDOW_MS = 1 * 60 * 1000;
private readonly TOTP_LOCKOUT_MS = 5 * 60 * 1000;
private readonly RESET_CODE_MAX_ATTEMPTS = 5;
private readonly RESET_CODE_WINDOW_MS = 1 * 60 * 1000;
private readonly RESET_CODE_LOCKOUT_MS = 5 * 60 * 1000;
constructor() { constructor() {
setInterval(() => this.cleanup(), 5 * 60 * 1000); setInterval(() => this.cleanup(), 5 * 60 * 1000);
} }
@@ -40,6 +50,28 @@ class LoginRateLimiter {
this.usernameAttempts.delete(username); this.usernameAttempts.delete(username);
} }
} }
for (const [userId, attempt] of this.totpAttempts.entries()) {
if (attempt.lockedUntil && attempt.lockedUntil < now) {
this.totpAttempts.delete(userId);
} else if (
!attempt.lockedUntil &&
now - attempt.firstAttempt > this.TOTP_WINDOW_MS
) {
this.totpAttempts.delete(userId);
}
}
for (const [username, attempt] of this.resetCodeAttempts.entries()) {
if (attempt.lockedUntil && attempt.lockedUntil < now) {
this.resetCodeAttempts.delete(username);
} else if (
!attempt.lockedUntil &&
now - attempt.firstAttempt > this.RESET_CODE_WINDOW_MS
) {
this.resetCodeAttempts.delete(username);
}
}
} }
recordFailedAttempt(ip: string, username?: string): void { recordFailedAttempt(ip: string, username?: string): void {
@@ -141,6 +173,114 @@ class LoginRateLimiter {
return minRemaining; return minRemaining;
} }
recordFailedTOTPAttempt(userId: string): void {
const now = Date.now();
const totpAttempt = this.totpAttempts.get(userId);
if (!totpAttempt) {
this.totpAttempts.set(userId, {
count: 1,
firstAttempt: now,
});
} else if (now - totpAttempt.firstAttempt > this.TOTP_WINDOW_MS) {
this.totpAttempts.set(userId, {
count: 1,
firstAttempt: now,
});
} else {
totpAttempt.count++;
if (totpAttempt.count >= this.TOTP_MAX_ATTEMPTS) {
totpAttempt.lockedUntil = now + this.TOTP_LOCKOUT_MS;
}
}
}
resetTOTPAttempts(userId: string): void {
this.totpAttempts.delete(userId);
}
isTOTPLocked(userId: string): { locked: boolean; remainingTime?: number } {
const now = Date.now();
const totpAttempt = this.totpAttempts.get(userId);
if (totpAttempt?.lockedUntil && totpAttempt.lockedUntil > now) {
return {
locked: true,
remainingTime: Math.ceil((totpAttempt.lockedUntil - now) / 1000),
};
}
return { locked: false };
}
getRemainingTOTPAttempts(userId: string): number {
const now = Date.now();
const totpAttempt = this.totpAttempts.get(userId);
if (totpAttempt && now - totpAttempt.firstAttempt <= this.TOTP_WINDOW_MS) {
return Math.max(0, this.TOTP_MAX_ATTEMPTS - totpAttempt.count);
}
return this.TOTP_MAX_ATTEMPTS;
}
recordResetCodeAttempt(username: string): void {
const now = Date.now();
const resetAttempt = this.resetCodeAttempts.get(username);
if (!resetAttempt) {
this.resetCodeAttempts.set(username, {
count: 1,
firstAttempt: now,
});
} else if (now - resetAttempt.firstAttempt > this.RESET_CODE_WINDOW_MS) {
this.resetCodeAttempts.set(username, {
count: 1,
firstAttempt: now,
});
} else {
resetAttempt.count++;
if (resetAttempt.count >= this.RESET_CODE_MAX_ATTEMPTS) {
resetAttempt.lockedUntil = now + this.RESET_CODE_LOCKOUT_MS;
}
}
}
resetResetCodeAttempts(username: string): void {
this.resetCodeAttempts.delete(username);
}
isResetCodeLocked(username: string): {
locked: boolean;
remainingTime?: number;
} {
const now = Date.now();
const resetAttempt = this.resetCodeAttempts.get(username);
if (resetAttempt?.lockedUntil && resetAttempt.lockedUntil > now) {
return {
locked: true,
remainingTime: Math.ceil((resetAttempt.lockedUntil - now) / 1000),
};
}
return { locked: false };
}
getRemainingResetCodeAttempts(username: string): number {
const now = Date.now();
const resetAttempt = this.resetCodeAttempts.get(username);
if (
resetAttempt &&
now - resetAttempt.firstAttempt <= this.RESET_CODE_WINDOW_MS
) {
return Math.max(0, this.RESET_CODE_MAX_ATTEMPTS - resetAttempt.count);
}
return this.RESET_CODE_MAX_ATTEMPTS;
}
} }
export const loginRateLimiter = new LoginRateLimiter(); export const loginRateLimiter = new LoginRateLimiter();

View File

@@ -177,30 +177,57 @@ class UserDataImport {
continue; continue;
} }
const tempId = `import-ssh-${targetUserId}-${Date.now()}-${imported}`; const existing = await getDb()
const newHostData = { .select()
.from(sshData)
.where(
and(
eq(sshData.userId, targetUserId),
eq(sshData.ip, host.ip as string),
eq(sshData.port, host.port as number),
eq(sshData.username, host.username as string),
),
);
if (existing.length > 0 && !options.replaceExisting) {
skipped++;
continue;
}
const newHostData: any = {
...host, ...host,
id: tempId,
userId: targetUserId, userId: targetUserId,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}; };
let processedHostData = newHostData; if (existing.length === 0) {
newHostData.createdAt = new Date().toISOString();
}
let processedHostData: any = newHostData;
if (options.userDataKey) { if (options.userDataKey) {
processedHostData = DataCrypto.encryptRecord( processedHostData = DataCrypto.encryptRecord(
"ssh_data", "ssh_data",
newHostData, newHostData,
targetUserId, targetUserId,
options.userDataKey, options.userDataKey,
); ) as Record<string, unknown>;
} }
delete processedHostData.id; delete processedHostData.id;
await getDb() if (existing.length > 0 && options.replaceExisting) {
.insert(sshData) await getDb()
.values(processedHostData as unknown as typeof sshData.$inferInsert); .update(sshData)
.set(processedHostData as unknown as typeof sshData.$inferInsert)
.where(eq(sshData.id, existing[0].id));
} else {
await getDb()
.insert(sshData)
.values(
processedHostData as unknown as typeof sshData.$inferInsert,
);
}
imported++; imported++;
} catch (error) { } catch (error) {
errors.push( errors.push(
@@ -233,34 +260,59 @@ class UserDataImport {
continue; continue;
} }
const tempCredId = `import-cred-${targetUserId}-${Date.now()}-${imported}`; const existing = await getDb()
const newCredentialData = { .select()
.from(sshCredentials)
.where(
and(
eq(sshCredentials.userId, targetUserId),
eq(sshCredentials.name, credential.name as string),
),
);
if (existing.length > 0 && !options.replaceExisting) {
skipped++;
continue;
}
const newCredentialData: any = {
...credential, ...credential,
id: tempCredId,
userId: targetUserId, userId: targetUserId,
usageCount: 0,
lastUsed: null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}; };
let processedCredentialData = newCredentialData; if (existing.length === 0) {
newCredentialData.usageCount = 0;
newCredentialData.lastUsed = null;
newCredentialData.createdAt = new Date().toISOString();
}
let processedCredentialData: any = newCredentialData;
if (options.userDataKey) { if (options.userDataKey) {
processedCredentialData = DataCrypto.encryptRecord( processedCredentialData = DataCrypto.encryptRecord(
"ssh_credentials", "ssh_credentials",
newCredentialData, newCredentialData,
targetUserId, targetUserId,
options.userDataKey, options.userDataKey,
); ) as Record<string, unknown>;
} }
delete processedCredentialData.id; delete processedCredentialData.id;
await getDb() if (existing.length > 0 && options.replaceExisting) {
.insert(sshCredentials) await getDb()
.values( .update(sshCredentials)
processedCredentialData as unknown as typeof sshCredentials.$inferInsert, .set(
); processedCredentialData as unknown as typeof sshCredentials.$inferInsert,
)
.where(eq(sshCredentials.id, existing[0].id));
} else {
await getDb()
.insert(sshCredentials)
.values(
processedCredentialData as unknown as typeof sshCredentials.$inferInsert,
);
}
imported++; imported++;
} catch (error) { } catch (error) {
errors.push( errors.push(

View File

@@ -36,7 +36,7 @@ function TooltipTrigger({
function TooltipContent({ function TooltipContent({
className, className,
sideOffset = 0, sideOffset = 4,
children, children,
...props ...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) { }: React.ComponentProps<typeof TooltipPrimitive.Content>) {
@@ -46,7 +46,7 @@ function TooltipContent({
data-slot="tooltip-content" data-slot="tooltip-content"
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", "bg-elevated text-foreground border border-edge-medium shadow-lg animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
className, className,
)} )}
{...props} {...props}

View File

@@ -745,7 +745,7 @@ export const DEFAULT_TERMINAL_CONFIG = {
fontSize: 14, fontSize: 14,
fontFamily: "Caskaydia Cove Nerd Font Mono", fontFamily: "Caskaydia Cove Nerd Font Mono",
letterSpacing: 0, letterSpacing: 0,
lineHeight: 1.2, lineHeight: 1.0,
theme: "termix", theme: "termix",
scrollback: 10000, scrollback: 10000,

View File

@@ -1,4 +1,4 @@
import { useState } from "react"; import { useState, useEffect, useCallback } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
interface ConfirmationOptions { interface ConfirmationOptions {
@@ -9,10 +9,47 @@ interface ConfirmationOptions {
variant?: "default" | "destructive"; variant?: "default" | "destructive";
} }
interface ToastConfirmOptions {
confirmOnEnter?: boolean;
duration?: number;
}
export function useConfirmation() { export function useConfirmation() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [options, setOptions] = useState<ConfirmationOptions | null>(null); const [options, setOptions] = useState<ConfirmationOptions | null>(null);
const [onConfirm, setOnConfirm] = useState<(() => void) | null>(null); const [onConfirm, setOnConfirm] = useState<(() => void) | null>(null);
const [activeToastId, setActiveToastId] = useState<string | number | null>(null);
const [pendingConfirmCallback, setPendingConfirmCallback] = useState<(() => void) | null>(null);
const [pendingResolve, setPendingResolve] = useState<((value: boolean) => void) | null>(null);
const handleEnterKey = useCallback((event: KeyboardEvent) => {
if (event.key === "Enter" && activeToastId !== null) {
event.preventDefault();
event.stopPropagation();
if (pendingConfirmCallback) {
pendingConfirmCallback();
}
if (pendingResolve) {
pendingResolve(true);
}
toast.dismiss(activeToastId);
setActiveToastId(null);
setPendingConfirmCallback(null);
setPendingResolve(null);
}
}, [activeToastId, pendingConfirmCallback, pendingResolve]);
useEffect(() => {
if (activeToastId !== null) {
// Use capture phase to intercept Enter before terminal receives it
window.addEventListener("keydown", handleEnterKey, true);
return () => {
window.removeEventListener("keydown", handleEnterKey, true);
};
}
}, [activeToastId, handleEnterKey]);
const confirm = (opts: ConfirmationOptions, callback: () => void) => { const confirm = (opts: ConfirmationOptions, callback: () => void) => {
setOptions(opts); setOptions(opts);
@@ -40,6 +77,7 @@ export function useConfirmation() {
callback?: () => void, callback?: () => void,
variantOrConfirmLabel: "default" | "destructive" | string = "Confirm", variantOrConfirmLabel: "default" | "destructive" | string = "Confirm",
cancelLabel: string = "Cancel", cancelLabel: string = "Cancel",
toastOptions: ToastConfirmOptions = { confirmOnEnter: false },
): Promise<boolean> => { ): Promise<boolean> => {
return new Promise((resolve) => { return new Promise((resolve) => {
const isVariant = const isVariant =
@@ -47,43 +85,56 @@ export function useConfirmation() {
variantOrConfirmLabel === "destructive"; variantOrConfirmLabel === "destructive";
const confirmLabel = isVariant ? "Confirm" : variantOrConfirmLabel; const confirmLabel = isVariant ? "Confirm" : variantOrConfirmLabel;
if (typeof opts === "string") { const { confirmOnEnter = false, duration = 8000 } = toastOptions;
toast(opts, {
action: {
label: confirmLabel,
onClick: () => {
if (callback) callback();
resolve(true);
},
},
cancel: {
label: cancelLabel,
onClick: () => {
resolve(false);
},
},
} as any);
} else if (typeof opts === "object") {
const actualConfirmLabel = opts.confirmText || confirmLabel;
const actualCancelLabel = opts.cancelText || cancelLabel;
toast(opts.description, { const handleToastConfirm = () => {
action: { if (callback) callback();
label: actualConfirmLabel, resolve(true);
onClick: () => { setActiveToastId(null);
if (callback) callback(); setPendingConfirmCallback(null);
resolve(true); setPendingResolve(null);
}, };
},
cancel: { const handleToastCancel = () => {
label: actualCancelLabel,
onClick: () => {
resolve(false);
},
},
} as any);
} else {
resolve(false); resolve(false);
setActiveToastId(null);
setPendingConfirmCallback(null);
setPendingResolve(null);
};
const message = typeof opts === "string" ? opts : opts.description;
const actualConfirmLabel = typeof opts === "object" && opts.confirmText ? opts.confirmText : confirmLabel;
const actualCancelLabel = typeof opts === "object" && opts.cancelText ? opts.cancelText : cancelLabel;
const toastId = toast(message, {
duration,
action: {
label: confirmOnEnter ? `${actualConfirmLabel}` : actualConfirmLabel,
onClick: handleToastConfirm,
},
cancel: {
label: actualCancelLabel,
onClick: handleToastCancel,
},
onDismiss: () => {
setActiveToastId(null);
setPendingConfirmCallback(null);
setPendingResolve(null);
},
onAutoClose: () => {
resolve(false);
setActiveToastId(null);
setPendingConfirmCallback(null);
setPendingResolve(null);
},
} as any);
if (confirmOnEnter) {
setActiveToastId(toastId);
setPendingConfirmCallback(() => () => {
if (callback) callback();
});
setPendingResolve(() => resolve);
} }
}); });
}; };

View File

@@ -0,0 +1,71 @@
import { useEffect, useState, useCallback } from "react";
import { isElectron } from "@/ui/main-axios";
interface ServiceWorkerState {
isSupported: boolean;
isRegistered: boolean;
updateAvailable: boolean;
}
/**
* Hook to manage PWA Service Worker registration.
* Only registers in production web environment (not in Electron).
*/
export function useServiceWorker(): ServiceWorkerState {
const [state, setState] = useState<ServiceWorkerState>({
isSupported: false,
isRegistered: false,
updateAvailable: false,
});
const handleUpdateFound = useCallback(
(registration: ServiceWorkerRegistration) => {
const newWorker = registration.installing;
if (!newWorker) return;
newWorker.addEventListener("statechange", () => {
if (
newWorker.state === "installed" &&
navigator.serviceWorker.controller
) {
setState((prev) => ({ ...prev, updateAvailable: true }));
console.log("[SW] Update available");
}
});
},
[],
);
useEffect(() => {
const isSupported =
"serviceWorker" in navigator && !isElectron() && import.meta.env.PROD;
setState((prev) => ({ ...prev, isSupported }));
if (!isSupported) return;
const registerSW = async () => {
try {
const registration = await navigator.serviceWorker.register("/sw.js");
console.log("[SW] Registered:", registration.scope);
setState((prev) => ({ ...prev, isRegistered: true }));
registration.addEventListener("updatefound", () =>
handleUpdateFound(registration),
);
} catch (error) {
console.error("[SW] Registration failed:", error);
}
};
if (document.readyState === "complete") {
registerSW();
} else {
window.addEventListener("load", registerSW);
return () => window.removeEventListener("load", registerSW);
}
}, [handleUpdateFound]);
return state;
}

View File

@@ -3,31 +3,38 @@ import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector"; import LanguageDetector from "i18next-browser-languagedetector";
import enTranslation from "../locales/en.json"; import enTranslation from "../locales/en.json";
import zhTranslation from "../locales/zh.json"; import afTranslation from "../locales/translated/af.json";
import deTranslation from "../locales/de.json"; import arTranslation from "../locales/translated/ar.json";
import ptTranslation from "../locales/pt.json"; import bnTranslation from "../locales/translated/bn.json";
import ruTranslation from "../locales/ru.json"; import bgTranslation from "../locales/translated/bg.json";
import frTranslation from "../locales/fr.json"; import caTranslation from "../locales/translated/ca.json";
import koTranslation from "../locales/ko.json"; import csTranslation from "../locales/translated/cs.json";
import itTranslation from "../locales/it.json"; import daTranslation from "../locales/translated/da.json";
import esTranslation from "../locales/es.json"; import deTranslation from "../locales/translated/de.json";
import hiTranslation from "../locales/hi.json"; import elTranslation from "../locales/translated/el.json";
import bnTranslation from "../locales/bn.json"; import esTranslation from "../locales/translated/es.json";
import jaTranslation from "../locales/ja.json"; import fiTranslation from "../locales/translated/fi.json";
import viTranslation from "../locales/vi.json"; import frTranslation from "../locales/translated/fr.json";
import trTranslation from "../locales/tr.json"; import heTranslation from "../locales/translated/he.json";
import heTranslation from "../locales/he.json"; import hiTranslation from "../locales/translated/hi.json";
import arTranslation from "../locales/ar.json"; import huTranslation from "../locales/translated/hu.json";
import plTranslation from "../locales/pl.json"; import idTranslation from "../locales/translated/id.json";
import nlTranslation from "../locales/nl.json"; import itTranslation from "../locales/translated/it.json";
import svTranslation from "../locales/sv.json"; import jaTranslation from "../locales/translated/ja.json";
import idTranslation from "../locales/id.json"; import koTranslation from "../locales/translated/ko.json";
import thTranslation from "../locales/th.json"; import nlTranslation from "../locales/translated/nl.json";
import ukTranslation from "../locales/uk.json"; import noTranslation from "../locales/translated/no.json";
import csTranslation from "../locales/cs.json"; import plTranslation from "../locales/translated/pl.json";
import roTranslation from "../locales/ro.json"; import ptTranslation from "../locales/translated/pt.json";
import elTranslation from "../locales/el.json"; import roTranslation from "../locales/translated/ro.json";
import nbTranslation from "../locales/nb.json"; import ruTranslation from "../locales/translated/ru.json";
import srTranslation from "../locales/translated/sr.json";
import svTranslation from "../locales/translated/sv.json";
import thTranslation from "../locales/translated/th.json";
import trTranslation from "../locales/translated/tr.json";
import ukTranslation from "../locales/translated/uk.json";
import viTranslation from "../locales/translated/vi.json";
import zhTranslation from "../locales/translated/zh.json";
i18n i18n
.use(LanguageDetector) .use(LanguageDetector)
@@ -35,31 +42,38 @@ i18n
.init({ .init({
supportedLngs: [ supportedLngs: [
"en", "en",
"zh", "af",
"de",
"pt",
"ru",
"fr",
"ko",
"it",
"es",
"hi",
"bn",
"ja",
"vi",
"tr",
"he",
"ar", "ar",
"pl", "bn",
"nl", "bg",
"sv", "ca",
"id",
"th",
"uk",
"cs", "cs",
"ro", "da",
"de",
"el", "el",
"nb", "es",
"fi",
"fr",
"he",
"hi",
"hu",
"id",
"it",
"ja",
"ko",
"nl",
"no",
"pl",
"pt",
"ro",
"ru",
"sr",
"sv",
"th",
"tr",
"uk",
"vi",
"zh",
], ],
fallbackLng: "en", fallbackLng: "en",
debug: false, debug: false,
@@ -76,80 +90,101 @@ i18n
en: { en: {
translation: enTranslation, translation: enTranslation,
}, },
zh: { af: {
translation: zhTranslation, translation: afTranslation,
},
de: {
translation: deTranslation,
},
pt: {
translation: ptTranslation,
},
ru: {
translation: ruTranslation,
},
fr: {
translation: frTranslation,
},
ko: {
translation: koTranslation,
},
it: {
translation: itTranslation,
},
es: {
translation: esTranslation,
},
hi: {
translation: hiTranslation,
},
bn: {
translation: bnTranslation,
},
ja: {
translation: jaTranslation,
},
vi: {
translation: viTranslation,
},
tr: {
translation: trTranslation,
},
he: {
translation: heTranslation,
}, },
ar: { ar: {
translation: arTranslation, translation: arTranslation,
}, },
pl: { bn: {
translation: plTranslation, translation: bnTranslation,
}, },
nl: { bg: {
translation: nlTranslation, translation: bgTranslation,
}, },
sv: { ca: {
translation: svTranslation, translation: caTranslation,
},
id: {
translation: idTranslation,
},
th: {
translation: thTranslation,
},
uk: {
translation: ukTranslation,
}, },
cs: { cs: {
translation: csTranslation, translation: csTranslation,
}, },
ro: { da: {
translation: roTranslation, translation: daTranslation,
},
de: {
translation: deTranslation,
}, },
el: { el: {
translation: elTranslation, translation: elTranslation,
}, },
nb: { es: {
translation: nbTranslation, translation: esTranslation,
},
fi: {
translation: fiTranslation,
},
fr: {
translation: frTranslation,
},
he: {
translation: heTranslation,
},
hi: {
translation: hiTranslation,
},
hu: {
translation: huTranslation,
},
id: {
translation: idTranslation,
},
it: {
translation: itTranslation,
},
ja: {
translation: jaTranslation,
},
ko: {
translation: koTranslation,
},
nl: {
translation: nlTranslation,
},
no: {
translation: noTranslation,
},
pl: {
translation: plTranslation,
},
pt: {
translation: ptTranslation,
},
ro: {
translation: roTranslation,
},
ru: {
translation: ruTranslation,
},
sr: {
translation: srTranslation,
},
sv: {
translation: svTranslation,
},
th: {
translation: thTranslation,
},
tr: {
translation: trTranslation,
},
uk: {
translation: ukTranslation,
},
vi: {
translation: viTranslation,
},
zh: {
translation: zhTranslation,
}, },
}, },

View File

@@ -0,0 +1,104 @@
type EventListener = (...args: any[]) => void;
class DatabaseHealthMonitor {
private static instance: DatabaseHealthMonitor;
private dbHealthy: boolean = true;
private lastCheckTime: number = 0;
private checkInProgress: boolean = false;
private listeners: Map<string, EventListener[]> = new Map();
private constructor() {}
static getInstance(): DatabaseHealthMonitor {
if (!DatabaseHealthMonitor.instance) {
DatabaseHealthMonitor.instance = new DatabaseHealthMonitor();
}
return DatabaseHealthMonitor.instance;
}
on(event: string, listener: EventListener): void {
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event)!.push(listener);
}
off(event: string, listener: EventListener): void {
const eventListeners = this.listeners.get(event);
if (eventListeners) {
const index = eventListeners.indexOf(listener);
if (index !== -1) {
eventListeners.splice(index, 1);
}
}
}
private emit(event: string, ...args: any[]): void {
const eventListeners = this.listeners.get(event);
if (eventListeners) {
eventListeners.forEach((listener) => listener(...args));
}
}
reportDatabaseError(error: any, wasAuthenticated: boolean = false) {
const errorMessage = error?.response?.data?.error || error?.message || "";
const errorCode = error?.response?.data?.code || error?.code;
const httpStatus = error?.response?.status;
const isDatabaseError =
errorMessage.toLowerCase().includes("database") ||
errorMessage.toLowerCase().includes("sqlite") ||
errorMessage.toLowerCase().includes("drizzle") ||
errorCode === "DATABASE_ERROR" ||
errorCode === "DB_CONNECTION_FAILED";
const isBackendUnreachable =
errorCode === "ERR_NETWORK" ||
errorCode === "ECONNREFUSED" ||
(errorMessage.toLowerCase().includes("network error") &&
error?.response === undefined);
const isAuthenticationLost =
wasAuthenticated &&
httpStatus === 401 &&
(errorCode === "AUTH_REQUIRED" ||
errorCode === "SESSION_EXPIRED" ||
errorCode === "SESSION_NOT_FOUND" ||
errorMessage === "Missing authentication token" ||
errorMessage === "Invalid token" ||
errorMessage === "Authentication required");
if (
(isDatabaseError || isBackendUnreachable || isAuthenticationLost) &&
this.dbHealthy
) {
this.dbHealthy = false;
this.emit("database-connection-lost", {
error: errorMessage || "Backend server unreachable",
code: errorCode,
timestamp: Date.now(),
});
}
}
reportDatabaseSuccess() {
if (!this.dbHealthy) {
this.dbHealthy = true;
this.emit("database-connection-restored", {
timestamp: Date.now(),
});
}
}
isDatabaseHealthy(): boolean {
return this.dbHealthy;
}
reset() {
this.dbHealthy = true;
this.lastCheckTime = 0;
this.checkInProgress = false;
}
}
export const dbHealthMonitor = DatabaseHealthMonitor.getInstance();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,8 @@
"passwordRequired": "Password is required", "passwordRequired": "Password is required",
"sshKeyRequired": "SSH key is required", "sshKeyRequired": "SSH key is required",
"credentialAddedSuccessfully": "Credential \"{{name}}\" added successfully", "credentialAddedSuccessfully": "Credential \"{{name}}\" added successfully",
"savingCredential": "Saving credential...",
"updatingCredential": "Updating credential...",
"general": "General", "general": "General",
"description": "Description", "description": "Description",
"folder": "Folder", "folder": "Folder",
@@ -184,6 +186,32 @@
"renameFolder": "Rename folder", "renameFolder": "Rename folder",
"idLabel": "ID:" "idLabel": "ID:"
}, },
"quickConnect": {
"title": "Quick Connect",
"description": "Connect directly to a terminal or file manager session without saving a host configuration",
"ipAddress": "IP Address or Hostname",
"port": "Port",
"username": "Username",
"password": "Password",
"key": "SSH Private Key",
"keyPassword": "Key Password (Optional)",
"keyType": "Key Type",
"uploadFile": "Upload File",
"pasteKey": "Paste Key",
"credential": "Credential",
"overrideUsername": "Override Credential Username",
"overrideUsernameDesc": "Use a different username than the one stored in the credential",
"connectTerminal": "Connect to Terminal",
"connectFileManager": "Connect to File Manager",
"cancel": "Cancel",
"passwordRequired": "Password is required",
"keyRequired": "SSH key is required",
"credentialRequired": "Credential selection is required",
"connectionEstablished": "Connection established successfully",
"connectionFailed": "Failed to establish connection",
"autoDetect": "Auto Detect",
"authentication": "Authentication"
},
"dragIndicator": { "dragIndicator": {
"error": "Error: {{error}}", "error": "Error: {{error}}",
"dragging": "Dragging {{fileName}}", "dragging": "Dragging {{fileName}}",
@@ -464,6 +492,7 @@
"retry": "Retry", "retry": "Retry",
"checking": "Checking...", "checking": "Checking...",
"checkingDatabase": "Checking database connection...", "checkingDatabase": "Checking database connection...",
"checkingAuthentication": "Checking authentication...",
"actions": "Actions", "actions": "Actions",
"remove": "Remove", "remove": "Remove",
"revoke": "Revoke", "revoke": "Revoke",
@@ -489,7 +518,12 @@
"hostManager": "Host Manager", "hostManager": "Host Manager",
"cannotSplitTab": "Cannot split this tab", "cannotSplitTab": "Cannot split this tab",
"tabNavigation": "Tab Navigation", "tabNavigation": "Tab Navigation",
"hostTabTitle": "{{username}}@{{ip}}:{{port}}" "hostTabTitle": "{{username}}@{{ip}}:{{port}}",
"copyPassword": "Copy Password",
"copySudoPassword": "Copy Sudo Password",
"passwordCopied": "Password copied to clipboard",
"sudoPasswordCopied": "Sudo password copied to clipboard",
"noPasswordAvailable": "No password available"
}, },
"admin": { "admin": {
"title": "Admin Settings", "title": "Admin Settings",
@@ -537,6 +571,7 @@
"userRegistration": "User Registration", "userRegistration": "User Registration",
"allowNewAccountRegistration": "Allow new account registration", "allowNewAccountRegistration": "Allow new account registration",
"allowPasswordLogin": "Allow username/password login", "allowPasswordLogin": "Allow username/password login",
"allowPasswordReset": "Allow password reset via reset code",
"missingRequiredFields": "Missing required fields: {{fields}}", "missingRequiredFields": "Missing required fields: {{fields}}",
"oidcConfigurationUpdated": "OIDC configuration updated successfully!", "oidcConfigurationUpdated": "OIDC configuration updated successfully!",
"failedToFetchOidcConfig": "Failed to fetch OIDC configuration", "failedToFetchOidcConfig": "Failed to fetch OIDC configuration",
@@ -856,6 +891,13 @@
"autoStartContainer": "Auto Start on Container Launch", "autoStartContainer": "Auto Start on Container Launch",
"autoStartDesc": "Automatically start this tunnel when the container launches", "autoStartDesc": "Automatically start this tunnel when the container launches",
"addConnection": "Add Tunnel Connection", "addConnection": "Add Tunnel Connection",
"tunnelType": "Tunnel Type",
"tunnelTypeLocal": "Local (-L)",
"tunnelTypeRemote": "Remote (-R)",
"tunnelTypeLocalDesc": "Forward local port to remote endpoint",
"tunnelTypeRemoteDesc": "Forward remote port to local machine",
"tunnelForwardDescriptionLocal": "This tunnel will forward traffic from local port {{sourcePort}} to port {{endpointPort}} on the endpoint machine.",
"tunnelForwardDescriptionRemote": "This tunnel will forward traffic from port {{sourcePort}} on the source machine (current connection details in general tab) to port {{endpointPort}} on the endpoint machine.",
"sshpassRequired": "Sshpass Required For Password Authentication", "sshpassRequired": "Sshpass Required For Password Authentication",
"sshpassRequiredDesc": "For password authentication in tunnels, sshpass must be installed on the system.", "sshpassRequiredDesc": "For password authentication in tunnels, sshpass must be installed on the system.",
"otherInstallMethods": "Other installation methods:", "otherInstallMethods": "Other installation methods:",
@@ -1106,6 +1148,19 @@
"quickActionName": "Action name", "quickActionName": "Action name",
"noSnippetFound": "No snippet found", "noSnippetFound": "No snippet found",
"quickActionsOrder": "Quick action buttons will appear in the order listed above on the Server Stats page", "quickActionsOrder": "Quick action buttons will appear in the order listed above on the Server Stats page",
"sidebarCustomization": "Sidebar Button Customization",
"sidebarCustomizationDesc": "Choose which actions appear as quick buttons in the sidebar. Actions not shown as buttons will appear in the dropdown menu.",
"showTerminalInSidebar": "Show Terminal Button",
"showTerminalInSidebarDesc": "Display terminal as a quick button in the sidebar",
"showFileManagerInSidebar": "Show File Manager Button",
"showFileManagerInSidebarDesc": "Display file manager as a quick button in the sidebar",
"showTunnelInSidebar": "Show Tunnel Button",
"showTunnelInSidebarDesc": "Display tunnel management as a quick button in the sidebar",
"showDockerInSidebar": "Show Docker Button",
"showDockerInSidebarDesc": "Display docker management as a quick button in the sidebar",
"showServerStatsInSidebar": "Show Server Stats Button",
"showServerStatsInSidebarDesc": "Display server statistics as a quick button in the sidebar",
"atLeastOneActionRequired": "At least one enabled action must be shown in the sidebar",
"advancedAuthSettings": "Advanced Authentication Settings", "advancedAuthSettings": "Advanced Authentication Settings",
"sudoPasswordAutoFill": "Sudo Password Auto-Fill", "sudoPasswordAutoFill": "Sudo Password Auto-Fill",
"sudoPasswordAutoFillDesc": "Automatically offer to insert SSH password when sudo prompts for password", "sudoPasswordAutoFillDesc": "Automatically offer to insert SSH password when sudo prompts for password",
@@ -1360,6 +1415,12 @@
"itemDeletedSuccessfully": "{{type}} deleted successfully", "itemDeletedSuccessfully": "{{type}} deleted successfully",
"itemsDeletedSuccessfully": "{{count}} items deleted successfully", "itemsDeletedSuccessfully": "{{count}} items deleted successfully",
"failedToDeleteItems": "Failed to delete items", "failedToDeleteItems": "Failed to delete items",
"sudoPasswordRequired": "Administrator Password Required",
"enterSudoPassword": "Enter sudo password to continue this operation",
"sudoPassword": "Sudo password",
"sudoOperationFailed": "Sudo operation failed",
"sudoAuthFailed": "Sudo authentication failed",
"deleteOperation": "Delete files/folders",
"dragFilesToUpload": "Drop files here to upload", "dragFilesToUpload": "Drop files here to upload",
"emptyFolder": "This folder is empty", "emptyFolder": "This folder is empty",
"itemCount": "{{count}} items", "itemCount": "{{count}} items",
@@ -1731,7 +1792,34 @@
"executingQuickAction": "Executing {{name}}...", "executingQuickAction": "Executing {{name}}...",
"quickActionSuccess": "{{name}} completed successfully", "quickActionSuccess": "{{name}} completed successfully",
"quickActionFailed": "{{name}} failed", "quickActionFailed": "{{name}} failed",
"quickActionError": "Failed to execute {{name}}" "quickActionError": "Failed to execute {{name}}",
"ports": {
"title": "Listening Ports",
"protocol": "Protocol",
"port": "Port",
"address": "Address",
"state": "State",
"process": "Process",
"noData": "No listening ports data"
},
"firewall": {
"title": "Firewall",
"active": "Active",
"inactive": "Inactive",
"notDetected": "Not Detected",
"policy": "Policy",
"rules": "rules",
"noRules": "No rules",
"noData": "No firewall data available",
"action": "Action",
"protocol": "Proto",
"port": "Port",
"source": "Source",
"accept": "ACCEPT",
"drop": "DROP",
"reject": "REJECT",
"anywhere": "Anywhere"
}
}, },
"auth": { "auth": {
"tagline": "SSH SERVER MANAGER", "tagline": "SSH SERVER MANAGER",
@@ -1841,7 +1929,8 @@
"authenticationDisabled": "Authentication Disabled", "authenticationDisabled": "Authentication Disabled",
"authenticationDisabledDesc": "All authentication methods are currently disabled. Please contact your administrator.", "authenticationDisabledDesc": "All authentication methods are currently disabled. Please contact your administrator.",
"passwordResetSuccess": "Password Reset Successful", "passwordResetSuccess": "Password Reset Successful",
"passwordResetSuccessDesc": "Your password has been reset successfully. You can now log in with your new password." "passwordResetSuccessDesc": "Your password has been reset successfully. You can now log in with your new password.",
"attemptsRemaining": "attempts remaining"
}, },
"errors": { "errors": {
"notFound": "Page not found", "notFound": "Page not found",
@@ -1873,7 +1962,11 @@
"emailExists": "Email already exists", "emailExists": "Email already exists",
"loadFailed": "Failed to load data", "loadFailed": "Failed to load data",
"saveError": "Failed to save", "saveError": "Failed to save",
"sessionExpired": "Session expired - please log in again" "sessionExpired": "Session expired - please log in again",
"totpRateLimited": "Rate limited: Too many TOTP verification attempts. Please try again later.",
"totpRateLimitedWithTime": "Rate limited: Too many TOTP verification attempts. Please wait {{time}} seconds before trying again.",
"resetCodeRateLimited": "Rate limited: Too many verification attempts. Please try again later.",
"resetCodeRateLimitedWithTime": "Rate limited: Too many verification attempts. Please wait {{time}} seconds before trying again."
}, },
"messages": { "messages": {
"saveSuccess": "Saved successfully", "saveSuccess": "Saved successfully",
@@ -1931,6 +2024,9 @@
"terminalSettings": "Terminal", "terminalSettings": "Terminal",
"hostSidebarSettings": "Host & Sidebar", "hostSidebarSettings": "Host & Sidebar",
"snippetsSettings": "Snippets", "snippetsSettings": "Snippets",
"updateSettings": "Updates",
"disableUpdateCheck": "Disable Update Check",
"disableUpdateCheckDesc": "Stop checking for new versions on startup and dashboard. Reduces network requests.",
"currentPassword": "Current Password", "currentPassword": "Current Password",
"passwordChangedSuccess": "Password changed successfully! Please log in again.", "passwordChangedSuccess": "Password changed successfully! Please log in again.",
"failedToChangePassword": "Failed to change password. Please check your current password and try again.", "failedToChangePassword": "Failed to change password. Please check your current password and try again.",
@@ -1939,7 +2035,9 @@
"themeDark": "Dark", "themeDark": "Dark",
"themeSystem": "System", "themeSystem": "System",
"appearanceDesc": "Select the color theme for the application", "appearanceDesc": "Select the color theme for the application",
"terminalSyntaxHighlightingDesc": "Automatically highlight commands, paths, IPs, and log levels in terminal output" "terminalSyntaxHighlightingDesc": "Automatically highlight commands, paths, IPs, and log levels in terminal output",
"enableCommandPaletteShortcut": "Enable Command Palette Shortcut",
"enableCommandPaletteShortcutDesc": "Double-tap left Shift to open the Command Palette for quick access to hosts"
}, },
"user": { "user": {
"failedToLoadVersionInfo": "Failed to load version information" "failedToLoadVersionInfo": "Failed to load version information"
@@ -2163,7 +2261,20 @@
"noServerData": "No server data available", "noServerData": "No server data available",
"cpu": "CPU", "cpu": "CPU",
"ram": "RAM", "ram": "RAM",
"notAvailable": "N/A" "notAvailable": "N/A",
"customizeLayout": "Customize Dashboard",
"dashboardSettings": "Dashboard Settings",
"enableDisableCards": "Enable/Disable Cards",
"gridColumns": "Grid Columns",
"column": "Column",
"columns": "Columns",
"resetLayout": "Reset to Default",
"serverOverviewCard": "Server Overview",
"recentActivityCard": "Recent Activity",
"networkGraphCard": "Network Graph",
"quickActionsCard": "Quick Actions",
"serverStatsCard": "Server Stats",
"networkGraph": "Network Graph"
}, },
"rbac": { "rbac": {
"shareHost": "Share Host", "shareHost": "Share Host",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@
"failedToFetchCredentials": "শংসাপত্রগুলি আনতে ব্যর্থ হয়েছে", "failedToFetchCredentials": "শংসাপত্রগুলি আনতে ব্যর্থ হয়েছে",
"credentialDeletedSuccessfully": "শংসাপত্র সফলভাবে মুছে ফেলা হয়েছে", "credentialDeletedSuccessfully": "শংসাপত্র সফলভাবে মুছে ফেলা হয়েছে",
"failedToDeleteCredential": "শংসাপত্র মুছে ফেলা যায়নি", "failedToDeleteCredential": "শংসাপত্র মুছে ফেলা যায়নি",
"confirmDeleteCredential": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" শংসাপত্র মুছে ফেলতে চান?", "confirmDeleteCredential": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" শংসাপত্রটি মুছে ফেলতে চান?",
"credentialCreatedSuccessfully": "শংসাপত্র সফলভাবে তৈরি করা হয়েছে", "credentialCreatedSuccessfully": "শংসাপত্র সফলভাবে তৈরি করা হয়েছে",
"credentialUpdatedSuccessfully": "শংসাপত্র সফলভাবে আপডেট করা হয়েছে", "credentialUpdatedSuccessfully": "শংসাপত্র সফলভাবে আপডেট করা হয়েছে",
"failedToSaveCredential": "শংসাপত্র সংরক্ষণ করা যায়নি", "failedToSaveCredential": "শংসাপত্র সংরক্ষণ করা যায়নি",
@@ -43,7 +43,7 @@
"refresh": "রিফ্রেশ করুন", "refresh": "রিফ্রেশ করুন",
"passwordRequired": "পাসওয়ার্ড প্রয়োজন।", "passwordRequired": "পাসওয়ার্ড প্রয়োজন।",
"sshKeyRequired": "SSH কী প্রয়োজন", "sshKeyRequired": "SSH কী প্রয়োজন",
"credentialAddedSuccessfully": "\"{{name}}\" প্রমাণপত্র সফলভাবে যোগ করা হয়েছে", "credentialAddedSuccessfully": "\"{{name}}\" শংসাপত্র সফলভাবে যোগ করা হয়েছে",
"general": "সাধারণ", "general": "সাধারণ",
"description": "বিবরণ", "description": "বিবরণ",
"folder": "ফোল্ডার", "folder": "ফোল্ডার",
@@ -96,7 +96,7 @@
"deploymentProcess": "স্থাপনার প্রক্রিয়া", "deploymentProcess": "স্থাপনার প্রক্রিয়া",
"deploymentProcessDescription": "এটি বিদ্যমান কীগুলিকে ওভাররাইট না করেই টার্গেট হোস্টের ~/.ssh/authorized_keys ফাইলে নিরাপদে পাবলিক কী যুক্ত করবে। এই অপারেশনটি বিপরীতমুখী।", "deploymentProcessDescription": "এটি বিদ্যমান কীগুলিকে ওভাররাইট না করেই টার্গেট হোস্টের ~/.ssh/authorized_keys ফাইলে নিরাপদে পাবলিক কী যুক্ত করবে। এই অপারেশনটি বিপরীতমুখী।",
"chooseHostToDeploy": "স্থাপনের জন্য একটি হোস্ট বেছে নিন...", "chooseHostToDeploy": "স্থাপনের জন্য একটি হোস্ট বেছে নিন...",
"deploying": "মোতায়েন করা হচ্ছে...", "deploying": "স্থাপন করা হচ্ছে...",
"name": "নাম", "name": "নাম",
"noHostsAvailable": "কোনও হোস্ট উপলব্ধ নেই", "noHostsAvailable": "কোনও হোস্ট উপলব্ধ নেই",
"noHostsMatchSearch": "আপনার অনুসন্ধানের সাথে কোনও হোস্ট মেলেনি।", "noHostsMatchSearch": "আপনার অনুসন্ধানের সাথে কোনও হোস্ট মেলেনি।",
@@ -119,7 +119,7 @@
"passwordAuthentication": "পাসওয়ার্ড প্রমাণীকরণ", "passwordAuthentication": "পাসওয়ার্ড প্রমাণীকরণ",
"keyAuthentication": "কী প্রমাণীকরণ", "keyAuthentication": "কী প্রমাণীকরণ",
"securityReminder": "নিরাপত্তা অনুস্মারক", "securityReminder": "নিরাপত্তা অনুস্মারক",
"securityReminderText": "আপনার শংসাপত্রগুলি কখনও শেয়ার করবেন না। সমস্ত ডেটা বিশ্রামে এনক্রিপ্ট করা থাকে।", "securityReminderText": "আপনার পরিচয়পত্র কখনও শেয়ার করবেন না। সমস্ত ডেটা স্থিরভাবে এনক্রিপ্ট করা থাকে।",
"hostsUsingCredential": "এই শংসাপত্র ব্যবহার করে হোস্টরা", "hostsUsingCredential": "এই শংসাপত্র ব্যবহার করে হোস্টরা",
"noHostsUsingCredential": "বর্তমানে কোনও হোস্ট এই শংসাপত্র ব্যবহার করছে না।", "noHostsUsingCredential": "বর্তমানে কোনও হোস্ট এই শংসাপত্র ব্যবহার করছে না।",
"timesUsed": "ব্যবহৃত সময়", "timesUsed": "ব্যবহৃত সময়",
@@ -136,12 +136,12 @@
"listView": "তালিকা", "listView": "তালিকা",
"folderView": "ফোল্ডার", "folderView": "ফোল্ডার",
"unknownCredential": "অজানা", "unknownCredential": "অজানা",
"confirmRemoveFromFolder": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" ফোল্ডার থেকে \"{{folder}}\" মুছে ফেলতে চান? শংসাপত্রটি \"অশ্রেণীবদ্ধ\" এ সরানো হবে।", "confirmRemoveFromFolder": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" ফোল্ডার থেকে \"{{folder}}\" সরাতে চান? শংসাপত্রটি \"অশ্রেণীবদ্ধ\" এ সরানো হবে।",
"removedFromFolder": "ফোল্ডার থেকে \"{{name}}\" শংসাপত্র সফলভাবে সরানো হয়েছে", "removedFromFolder": "\"{{name}}\" শংসাপত্রটি ফোল্ডার থেকে সফলভাবে সরানো হয়েছে",
"failedToRemoveFromFolder": "ফোল্ডার থেকে শংসাপত্র সরানো যায়নি", "failedToRemoveFromFolder": "ফোল্ডার থেকে শংসাপত্র সরানো যায়নি",
"folderRenamed": "\"{{oldName}}\" ফোল্ডারটির নাম পরিবর্তন করে \"{{newName}}\" করা হয়েছে", "folderRenamed": "\"{{oldName}}\" ফোল্ডারর নাম পরিবর্তন করে \"{{newName}}\" করা হয়েছে",
"failedToRenameFolder": "ফোল্ডারের নাম পরিবর্তন করা যায়নি", "failedToRenameFolder": "ফোল্ডারের নাম পরিবর্তন করা যায়নি",
"movedToFolder": "\"{{name}}\" প্রমাণপত্র সফলভাবে \"{{folder}}}\" এ সরানো হয়েছে", "movedToFolder": "\"{{name}}\" শংসাপত্র সফলভাবে \"{{folder}}\" এ সরানো হয়েছে",
"failedToMoveToFolder": "শংসাপত্র ফোল্ডারে সরানো যায়নি", "failedToMoveToFolder": "শংসাপত্র ফোল্ডারে সরানো যায়নি",
"sshPublicKey": "SSH পাবলিক কী", "sshPublicKey": "SSH পাবলিক কী",
"publicKeyNote": "পাবলিক কী ঐচ্ছিক কিন্তু কী যাচাইকরণের জন্য সুপারিশ করা হয়", "publicKeyNote": "পাবলিক কী ঐচ্ছিক কিন্তু কী যাচাইকরণের জন্য সুপারিশ করা হয়",
@@ -166,7 +166,7 @@
"keyTypeDsa": "ডিএসএ (এসএসএইচ)", "keyTypeDsa": "ডিএসএ (এসএসএইচ)",
"keyTypeRsaSha256": "আরএসএ-এসএইচএ২-২৫৬", "keyTypeRsaSha256": "আরএসএ-এসএইচএ২-২৫৬",
"keyTypeRsaSha512": "আরএসএ-এসএইচএ২-৫১২", "keyTypeRsaSha512": "আরএসএ-এসএইচএ২-৫১২",
"keyPairGeneratedSuccessfully": "{{keyType}} কী জোড়া সফলভাবে তৈরি হয়েছে", "keyPairGeneratedSuccessfully": "{{keyType}} কী জোড়া সফলভাবে তৈরি করা হয়েছে",
"failedToGenerateKeyPair": "কী জোড়া তৈরি করতে ব্যর্থ হয়েছে", "failedToGenerateKeyPair": "কী জোড়া তৈরি করতে ব্যর্থ হয়েছে",
"generateKeyPairNote": "সরাসরি একটি নতুন SSH কী জোড়া তৈরি করুন। এটি ফর্মে বিদ্যমান যেকোনো কী প্রতিস্থাপন করবে।", "generateKeyPairNote": "সরাসরি একটি নতুন SSH কী জোড়া তৈরি করুন। এটি ফর্মে বিদ্যমান যেকোনো কী প্রতিস্থাপন করবে।",
"invalidKey": "অবৈধ কী", "invalidKey": "অবৈধ কী",
@@ -187,10 +187,10 @@
"dragIndicator": { "dragIndicator": {
"error": "ত্রুটি: {{error}}", "error": "ত্রুটি: {{error}}",
"dragging": "টেনে আনা হচ্ছে {{fileName}}", "dragging": "টেনে আনা হচ্ছে {{fileName}}",
"preparing": "প্রস্তুতি নিচ্ছে {{fileName}}", "preparing": "প্রস্তুতি {{fileName}}",
"readySingle": "ডাউনলোড করার জন্য প্রস্তুত {{fileName}}", "readySingle": "ডাউনলোড করার জন্য প্রস্তুত {{fileName}}",
"readyMultiple": "{{count}} ফাইল ডাউনলোড করার জন্য প্রস্তুত", "readyMultiple": "{{count}} ফাইল ডাউনলোড করার জন্য প্রস্তুত",
"batchDrag": "{{count}} ফাইলগুলি ডেস্কটপে টেনে আনুন", "batchDrag": "{{count}} ফাইলগুলিকে ডেস্কটপে টেনে আনুন",
"dragToDesktop": "ডেস্কটপে টেনে আনুন", "dragToDesktop": "ডেস্কটপে টেনে আনুন",
"canDragAnywhere": "আপনি আপনার ডেস্কটপের যেকোনো জায়গায় ফাইল টেনে আনতে পারেন" "canDragAnywhere": "আপনি আপনার ডেস্কটপের যেকোনো জায়গায় ফাইল টেনে আনতে পারেন"
}, },
@@ -202,7 +202,7 @@
"stopKeyRecording": "কী রেকর্ডিং বন্ধ করুন", "stopKeyRecording": "কী রেকর্ডিং বন্ধ করুন",
"selectTerminals": "টার্মিনাল নির্বাচন করুন:", "selectTerminals": "টার্মিনাল নির্বাচন করুন:",
"typeCommands": "কমান্ড টাইপ করুন (সকল কী সমর্থিত):", "typeCommands": "কমান্ড টাইপ করুন (সকল কী সমর্থিত):",
"commandsWillBeSent": "কমান্ডগুলি {{count}} নির্বাচিত টার্মিনালে পাঠানো হবে।", "commandsWillBeSent": "কমান্ডগুলি নির্বাচিত টার্মিনালে {{count}} পাঠানো হবে।",
"settings": "সেটিংস", "settings": "সেটিংস",
"enableRightClickCopyPaste": "রাইট-ক্লিক কপি/পেস্ট সক্ষম করুন", "enableRightClickCopyPaste": "রাইট-ক্লিক কপি/পেস্ট সক্ষম করুন",
"shareIdeas": "ssh টুলের জন্য পরবর্তীতে কী করা উচিত সে সম্পর্কে আপনার কি কোন ধারণা আছে? সেগুলি শেয়ার করুন", "shareIdeas": "ssh টুলের জন্য পরবর্তীতে কী করা উচিত সে সম্পর্কে আপনার কি কোন ধারণা আছে? সেগুলি শেয়ার করুন",
@@ -230,7 +230,7 @@
"createDescription": "দ্রুত কার্যকর করার জন্য একটি নতুন কমান্ড স্নিপেট তৈরি করুন", "createDescription": "দ্রুত কার্যকর করার জন্য একটি নতুন কমান্ড স্নিপেট তৈরি করুন",
"editDescription": "এই কমান্ড স্নিপেটটি সম্পাদনা করুন", "editDescription": "এই কমান্ড স্নিপেটটি সম্পাদনা করুন",
"deleteConfirmTitle": "স্নিপেট মুছুন", "deleteConfirmTitle": "স্নিপেট মুছুন",
"deleteConfirmDescription": "তুমি কি নিশ্চিত যে তুমি \"{{name}}\" মুছে ফেলতে চা?", "deleteConfirmDescription": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" মুছে ফেলতে চা?",
"createSuccess": "স্নিপেট সফলভাবে তৈরি করা হয়েছে", "createSuccess": "স্নিপেট সফলভাবে তৈরি করা হয়েছে",
"updateSuccess": "স্নিপেট সফলভাবে আপডেট করা হয়েছে", "updateSuccess": "স্নিপেট সফলভাবে আপডেট করা হয়েছে",
"deleteSuccess": "স্নিপেট সফলভাবে মুছে ফেলা হয়েছে", "deleteSuccess": "স্নিপেট সফলভাবে মুছে ফেলা হয়েছে",
@@ -239,7 +239,7 @@
"deleteFailed": "স্নিপেট মুছে ফেলা যায়নি", "deleteFailed": "স্নিপেট মুছে ফেলা যায়নি",
"failedToFetch": "স্নিপেটগুলি আনা যায়নি", "failedToFetch": "স্নিপেটগুলি আনা যায়নি",
"executeSuccess": "কার্যকর করা হচ্ছে: {{name}}", "executeSuccess": "কার্যকর করা হচ্ছে: {{name}}",
"copySuccess": "ক্লিপবোর্ডে \"{{name}}\" কপি করা হয়েছে", "copySuccess": "\"{{name}}\" ক্লিপবোর্ডে কপি করা হয়েছে",
"runTooltip": "টার্মিনালে এই স্নিপেটটি কার্যকর করুন।", "runTooltip": "টার্মিনালে এই স্নিপেটটি কার্যকর করুন।",
"copyTooltip": "ক্লিপবোর্ডে স্নিপেট কপি করুন", "copyTooltip": "ক্লিপবোর্ডে স্নিপেট কপি করুন",
"editTooltip": "এই স্নিপেটটি সম্পাদনা করুন", "editTooltip": "এই স্নিপেটটি সম্পাদনা করুন",
@@ -248,7 +248,7 @@
"reorderSameFolder": "শুধুমাত্র একই ফোল্ডারের মধ্যে স্নিপেটগুলি পুনরায় সাজাতে পারে", "reorderSameFolder": "শুধুমাত্র একই ফোল্ডারের মধ্যে স্নিপেটগুলি পুনরায় সাজাতে পারে",
"reorderSuccess": "স্নিপেটগুলি সফলভাবে পুনঃক্রম করা হয়েছে", "reorderSuccess": "স্নিপেটগুলি সফলভাবে পুনঃক্রম করা হয়েছে",
"reorderFailed": "স্নিপেটগুলি পুনঃক্রম করতে ব্যর্থ হয়েছে", "reorderFailed": "স্নিপেটগুলি পুনঃক্রম করতে ব্যর্থ হয়েছে",
"deleteFolderConfirm": "\"{{name}}\" ফোল্ডারটি মুছে ফেলবেন? সমস্ত স্নিপেট অশ্রেণীবদ্ধে সরানো হবে।", "deleteFolderConfirm": "\"{{name}}\" ফোল্ডারটি মুছবেন? সমস্ত স্নিপেট অশ্রেণীবদ্ধে সরানো হবে।",
"deleteFolderSuccess": "ফোল্ডারটি সফলভাবে মুছে ফেলা হয়েছে", "deleteFolderSuccess": "ফোল্ডারটি সফলভাবে মুছে ফেলা হয়েছে",
"deleteFolderFailed": "ফোল্ডারটি মুছে ফেলা যায়নি", "deleteFolderFailed": "ফোল্ডারটি মুছে ফেলা যায়নি",
"updateFolderSuccess": "ফোল্ডারটি সফলভাবে আপডেট করা হয়েছে", "updateFolderSuccess": "ফোল্ডারটি সফলভাবে আপডেট করা হয়েছে",
@@ -256,7 +256,7 @@
"updateFolderFailed": "ফোল্ডার আপডেট করতে ব্যর্থ হয়েছে", "updateFolderFailed": "ফোল্ডার আপডেট করতে ব্যর্থ হয়েছে",
"createFolderFailed": "ফোল্ডার তৈরি করতে ব্যর্থ হয়েছে", "createFolderFailed": "ফোল্ডার তৈরি করতে ব্যর্থ হয়েছে",
"selectTerminals": "টার্মিনাল নির্বাচন করুন (ঐচ্ছিক)", "selectTerminals": "টার্মিনাল নির্বাচন করুন (ঐচ্ছিক)",
"executeOnSelected": "নির্বাচিত {{count}} টার্মিনালে কার্যকর করুন", "executeOnSelected": "নির্বাচিত টার্মিনাল(গুলি) তে {{count}} কার্যকর করুন",
"executeOnCurrent": "বর্তমান টার্মিনালে এক্সিকিউট করুন (একাধিক নির্বাচন করতে ক্লিক করুন)", "executeOnCurrent": "বর্তমান টার্মিনালে এক্সিকিউট করুন (একাধিক নির্বাচন করতে ক্লিক করুন)",
"folder": "ফোল্ডার", "folder": "ফোল্ডার",
"selectFolder": "একটি ফোল্ডার নির্বাচন করুন অথবা খালি রাখুন", "selectFolder": "একটি ফোল্ডার নির্বাচন করুন অথবা খালি রাখুন",
@@ -308,7 +308,7 @@
"cleared": "স্প্লিট স্ক্রিন সাফ করা হয়েছে", "cleared": "স্প্লিট স্ক্রিন সাফ করা হয়েছে",
"error": { "error": {
"noAssignments": "লেআউটে কমপক্ষে একটি ট্যাব বরাদ্দ করুন।", "noAssignments": "লেআউটে কমপক্ষে একটি ট্যাব বরাদ্দ করুন।",
"fillAllSlots": "আবেদন করার আগে অনুগ্রহ করে সমস্ত {{count}} স্থান পূরণ করুন।" "fillAllSlots": "আবেদন করার আগে দয়া করে সমস্ত {{count}} স্লট পূরণ করুন।"
} }
}, },
"homepage": { "homepage": {
@@ -343,10 +343,10 @@
"error": "সংস্করণ পরীক্ষা ত্রুটি", "error": "সংস্করণ পরীক্ষা ত্রুটি",
"checkFailed": "আপডেটগুলি পরীক্ষা করা যায়নি", "checkFailed": "আপডেটগুলি পরীক্ষা করা যায়নি",
"upToDate": "অ্যাপটি আপ টু ডেট আছে", "upToDate": "অ্যাপটি আপ টু ডেট আছে",
"currentVersion": "আপনি {{version}} সংস্করণটি চালাচ্ছেন", "currentVersion": "তুমি {{version}}সংস্করণটি চালাচ্ছ",
"updateAvailable": "আপডেট উপলব্ধ", "updateAvailable": "আপডেট উপলব্ধ",
"newVersionAvailable": "একটি নতুন সংস্করণ উপলব্ধ! আপনি {{current}} ব্যবহার করছেন, কিন্তু {{latest}} উপলব্ধ।", "newVersionAvailable": "একটি নতুন সংস্করণ উপলব্ধ! আপনি {{current}}ব্যবহার করছেন, কিন্তু {{latest}} উপলব্ধ।",
"releasedOn": "{{date}} তারিখে মুক্তি পেয়েছে", "releasedOn": "মুক্তিপ্রাপ্ত {{date}}",
"downloadUpdate": "আপডেট ডাউনলোড করুন", "downloadUpdate": "আপডেট ডাউনলোড করুন",
"dismiss": "খারিজ করুন", "dismiss": "খারিজ করুন",
"checking": "আপডেটের জন্য চেক করা হচ্ছে...", "checking": "আপডেটের জন্য চেক করা হচ্ছে...",
@@ -382,7 +382,7 @@
"home": "হোম", "home": "হোম",
"expired": "মেয়াদোত্তীর্ণ", "expired": "মেয়াদোত্তীর্ণ",
"expiresToday": "আজ মেয়াদ শেষ হবে", "expiresToday": "আজ মেয়াদ শেষ হবে",
"expiresTomorrow": "{{days}} দিনের মধ্যে মেয়াদ শেষ হবে", "expiresTomorrow": "{{days}} দিনে মেয়াদ শেষ হবে",
"updateAvailable": "আপডেট উপলব্ধ", "updateAvailable": "আপডেট উপলব্ধ",
"sshPath": "SSH পাথ", "sshPath": "SSH পাথ",
"localPath": "স্থানীয় পথ", "localPath": "স্থানীয় পথ",
@@ -498,7 +498,7 @@
"userManagement": "ব্যবহারকারী ব্যবস্থাপনা", "userManagement": "ব্যবহারকারী ব্যবস্থাপনা",
"makeAdmin": "অ্যাডমিন করুন", "makeAdmin": "অ্যাডমিন করুন",
"removeAdmin": "অ্যাডমিন সরান", "removeAdmin": "অ্যাডমিন সরান",
"deleteUser": "ব্যবহারকারী {{username}} মুছে ফেলবেন? এটি পূর্বাবস্থায় ফেরানো যাবে না।", "deleteUser": "ব্যবহারকারী {{username}}মুছে ফেলবেন? এটি পূর্বাবস্থায় ফেরানো যাবে না।",
"allowRegistration": "নিবন্ধনের অনুমতি দিন", "allowRegistration": "নিবন্ধনের অনুমতি দিন",
"oidcSettings": "OIDC সেটিংস", "oidcSettings": "OIDC সেটিংস",
"clientId": "ক্লায়েন্ট আইডি", "clientId": "ক্লায়েন্ট আইডি",
@@ -509,7 +509,7 @@
"updateSettings": "সেটিংস আপডেট করুন", "updateSettings": "সেটিংস আপডেট করুন",
"confirmDelete": "আপনি কি নিশ্চিত যে আপনি এই ব্যবহারকারীকে মুছে ফেলতে চান?", "confirmDelete": "আপনি কি নিশ্চিত যে আপনি এই ব্যবহারকারীকে মুছে ফেলতে চান?",
"confirmMakeAdmin": "তুমি কি নিশ্চিত যে তুমি {{username}} কে একজন অ্যাডমিন বানাতে চাও?", "confirmMakeAdmin": "তুমি কি নিশ্চিত যে তুমি {{username}} কে একজন অ্যাডমিন বানাতে চাও?",
"confirmRemoveAdmin": "আপনি কি নিশ্চিত যে আপনি {{username}} থেকে অ্যাডমিন স্ট্যাটাসটি সরাতে চান?", "confirmRemoveAdmin": "আপনি কি নিশ্চিত যে আপনি {{username}}থেকে অ্যাডমিন স্ট্যাটাসটি সরাতে চান?",
"externalAuthentication": "বাহ্যিক প্রমাণীকরণ (OIDC)", "externalAuthentication": "বাহ্যিক প্রমাণীকরণ (OIDC)",
"configureExternalProvider": "OIDC/OAuth2 প্রমাণীকরণের জন্য বহিরাগত পরিচয় প্রদানকারী কনফিগার করুন।", "configureExternalProvider": "OIDC/OAuth2 প্রমাণীকরণের জন্য বহিরাগত পরিচয় প্রদানকারী কনফিগার করুন।",
"userIdentifierPath": "ব্যবহারকারী শনাক্তকারী পথ", "userIdentifierPath": "ব্যবহারকারী শনাক্তকারী পথ",
@@ -547,10 +547,10 @@
"failedToUpdateOidcConfig": "OIDC কনফিগারেশন আপডেট করতে ব্যর্থ হয়েছে", "failedToUpdateOidcConfig": "OIDC কনফিগারেশন আপডেট করতে ব্যর্থ হয়েছে",
"failedToDisableOidcConfig": "OIDC কনফিগারেশন নিষ্ক্রিয় করতে ব্যর্থ হয়েছে", "failedToDisableOidcConfig": "OIDC কনফিগারেশন নিষ্ক্রিয় করতে ব্যর্থ হয়েছে",
"enterUsernameToMakeAdmin": "অ্যাডমিন করতে ব্যবহারকারীর নাম লিখুন", "enterUsernameToMakeAdmin": "অ্যাডমিন করতে ব্যবহারকারীর নাম লিখুন",
"userIsNowAdmin": "ব্যবহারকারী {{username}} এখন একজন প্রশাসক", "userIsNowAdmin": "ব্যবহারকারী {{username}} এখন একজন অ্যাডমিন",
"failedToMakeUserAdmin": "ব্যবহারকারীকে প্রশাসক করা যায়নি", "failedToMakeUserAdmin": "ব্যবহারকারীকে প্রশাসক করা যায়নি",
"removeAdminStatus": "{{username}} থেকে অ্যাডমিন স্ট্যাটাস সরাবেন?", "removeAdminStatus": "{{username}}থেকে অ্যাডমিন স্ট্যাটাস সরাবেন?",
"adminStatusRemoved": "{{username}} থেকে অ্যাডমিন স্ট্যাটাস সরানো হয়েছে", "adminStatusRemoved": "{{username}}থেকে অ্যাডমিন স্ট্যাটাস সরানো হয়েছে",
"failedToRemoveAdminStatus": "অ্যাডমিন স্ট্যাটাস সরাতে ব্যর্থ হয়েছে", "failedToRemoveAdminStatus": "অ্যাডমিন স্ট্যাটাস সরাতে ব্যর্থ হয়েছে",
"userDeletedSuccessfully": "ব্যবহারকারী {{username}} সফলভাবে মুছে ফেলা হয়েছে", "userDeletedSuccessfully": "ব্যবহারকারী {{username}} সফলভাবে মুছে ফেলা হয়েছে",
"failedToDeleteUser": "ব্যবহারকারী মুছে ফেলা যায়নি", "failedToDeleteUser": "ব্যবহারকারী মুছে ফেলা যায়নি",
@@ -581,21 +581,21 @@
"administratorRole": "প্রশাসকের ভূমিকা", "administratorRole": "প্রশাসকের ভূমিকা",
"administratorRoleDescription": "সম্পূর্ণ সিস্টেম অ্যাক্সেস এবং পরিচালনার সুবিধা প্রদান করুন", "administratorRoleDescription": "সম্পূর্ণ সিস্টেম অ্যাক্সেস এবং পরিচালনার সুবিধা প্রদান করুন",
"passwordManagement": "পাসওয়ার্ড ব্যবস্থাপনা", "passwordManagement": "পাসওয়ার্ড ব্যবস্থাপনা",
"passwordResetWarning": "ব্যবহারকারীর পাসওয়ার্ড রিসেট করলে তাদের সমস্ত ডেটা (SSH হোস্ট, শংসাপত্র, সেটিংস) মুছে যাবে। এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।", "passwordResetWarning": "ব্যবহারকারীর পাসওয়ার্ড রিসেট করলে তার সমস্ত ডেটা (SSH হোস্ট, শংসাপত্র, সেটিংস) মুছে যাবে। এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।",
"resetUserPassword": "ব্যবহারকারীর পাসওয়ার্ড রিসেট করুন", "resetUserPassword": "ব্যবহারকারীর পাসওয়ার্ড রিসেট করুন",
"resettingPassword": "রিসেট করা হচ্ছে...", "resettingPassword": "রিসেট করা হচ্ছে...",
"passwordResetInitiated": "{{username}} এর জন্য পাসওয়ার্ড রিসেট শুরু হয়েছে। রিসেট কোড পাঠানো হয়েছে।", "passwordResetInitiated": "{{username}}এর জন্য পাসওয়ার্ড রিসেট শুরু হয়েছে। রিসেট কোড পাঠানো হয়েছে।",
"failedToResetPassword": "পাসওয়ার্ড রিসেট শুরু করা যায়নি", "failedToResetPassword": "পাসওয়ার্ড রিসেট শুরু করা যায়নি",
"sessionManagement": "সেশন ম্যানেজমেন্ট", "sessionManagement": "সেশন ম্যানেজমেন্ট",
"revokeAllSessions": "সকল সেশন প্রত্যাহার করুন", "revokeAllSessions": "সকল সেশন প্রত্যাহার করুন",
"revokeAllSessionsDescription": "সমস্ত ডিভাইস এবং সেশন থেকে জোর করে লগআউট করুন", "revokeAllSessionsDescription": "সকল ডিভাইস এবং সেশন থেকে জোর করে লগআউট করুন",
"revoking": "প্রত্যাহার করা হচ্ছে...", "revoking": "প্রত্যাহার করা হচ্ছে...",
"revoke": "সব প্রত্যাহার করুন", "revoke": "সব প্রত্যাহার করুন",
"dangerZone": "বিপদ অঞ্চল", "dangerZone": "বিপদ অঞ্চল",
"deleteUserTitle": "ব্যবহারকারীর অ্যাকাউন্ট মুছুন", "deleteUserTitle": "ব্যবহারকারীর অ্যাকাউন্ট মুছুন",
"deleteUserWarning": "এই ব্যবহারকারীর অ্যাকাউন্ট এবং এর সাথে সম্পর্কিত সমস্ত ডেটা স্থায়ীভাবে মুছে ফেলুন। এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।", "deleteUserWarning": "এই ব্যবহারকারীর অ্যাকাউন্ট এবং এর সাথে সম্পর্কিত সমস্ত ডেটা স্থায়ীভাবে মুছে ফেলুন। এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।",
"deleting": "মুছে ফেলা হচ্ছে...", "deleting": "মুছে ফেলা হচ্ছে...",
"cannotDeleteSelf": "আপনি নিজের অ্যাকাউন্ট মুছে ফেলতে পারবেন না", "cannotDeleteSelf": "আপনি নিজের অ্যাকাউন্ট মুছে ফেলতে পারবেন না",
"cannotRemoveLastAdmin": "শেষ প্রশাসককে সরানো যাচ্ছে না", "cannotRemoveLastAdmin": "শেষ প্রশাসককে সরানো যাচ্ছে না",
"cannotRemoveOwnAdmin": "আপনি আপনার নিজস্ব প্রশাসকের অধিকারগুলি সরাতে পারবেন না।", "cannotRemoveOwnAdmin": "আপনি আপনার নিজস্ব প্রশাসকের অধিকারগুলি সরাতে পারবেন না।",
"cannotModifyOwnAdminStatus": "আপনি আপনার নিজের অ্যাডমিন স্ট্যাটাস পরিবর্তন করতে পারবেন না।", "cannotModifyOwnAdminStatus": "আপনি আপনার নিজের অ্যাডমিন স্ট্যাটাস পরিবর্তন করতে পারবেন না।",
@@ -611,12 +611,12 @@
"linkTargetUsernamePlaceholder": "পাসওয়ার্ড অ্যাকাউন্টের ব্যবহারকারীর নাম লিখুন", "linkTargetUsernamePlaceholder": "পাসওয়ার্ড অ্যাকাউন্টের ব্যবহারকারীর নাম লিখুন",
"linkAccountsButton": "অ্যাকাউন্ট লিঙ্ক করুন", "linkAccountsButton": "অ্যাকাউন্ট লিঙ্ক করুন",
"linkingAccounts": "লিঙ্ক করা হচ্ছে...", "linkingAccounts": "লিঙ্ক করা হচ্ছে...",
"accountsLinkedSuccessfully": "OIDC ব্যবহারকারী {{oidcUsername}} কে {{targetUsername}} এর সাথে লিঙ্ক করা হয়েছে", "accountsLinkedSuccessfully": "OIDC ব্যবহারকারী {{oidcUsername}} কে {{targetUsername}}এর সাথে লিঙ্ক করা হয়েছে",
"failedToLinkAccounts": "অ্যাকাউন্ট লিঙ্ক করা যায়নি", "failedToLinkAccounts": "অ্যাকাউন্ট লিঙ্ক করা যায়নি",
"linkTargetUsernameRequired": "লক্ষ্য ব্যবহারকারীর নাম প্রয়োজন", "linkTargetUsernameRequired": "লক্ষ্য ব্যবহারকারীর নাম প্রয়োজন",
"unlinkOIDCTitle": "OIDC প্রমাণীকরণ আনলিঙ্ক করুন", "unlinkOIDCTitle": "OIDC প্রমাণীকরণ আনলিঙ্ক করুন",
"unlinkOIDCDescription": "{{username}} থেকে OIDC প্রমাণীকরণ সরাবেন? এর পরে ব্যবহারকারী কেবল ব্যবহারকারীর নাম/পাসওয়ার্ড দিয়ে লগইন করতে পারবেন।", "unlinkOIDCDescription": "{{username}}থেকে OIDC প্রমাণীকরণ সরান? এর পরে ব্যবহারকারী কেবল ব্যবহারকারীর নাম/পাসওয়ার্ড দিয়ে লগইন করতে পারবেন।",
"unlinkOIDCSuccess": "{{username}} থেকে OIDC আনলিঙ্ক করা হয়েছে", "unlinkOIDCSuccess": "OIDC {{username}}থেকে আনলিঙ্ক করা হয়েছে",
"failedToUnlinkOIDC": "OIDC লিঙ্কমুক্ত করতে ব্যর্থ হয়েছে", "failedToUnlinkOIDC": "OIDC লিঙ্কমুক্ত করতে ব্যর্থ হয়েছে",
"databaseSecurity": "ডাটাবেস নিরাপত্তা", "databaseSecurity": "ডাটাবেস নিরাপত্তা",
"encryptionStatus": "এনক্রিপশন স্ট্যাটাস", "encryptionStatus": "এনক্রিপশন স্ট্যাটাস",
@@ -631,7 +631,7 @@
"deviceProtectedMasterKey": "পরিবেশ-সুরক্ষিত মাস্টার কী", "deviceProtectedMasterKey": "পরিবেশ-সুরক্ষিত মাস্টার কী",
"legacyKeyStorage": "লিগ্যাসি কী স্টোরেজ", "legacyKeyStorage": "লিগ্যাসি কী স্টোরেজ",
"masterKeyEncryptedWithDeviceFingerprint": "পরিবেশগত ফিঙ্গারপ্রিন্ট সহ এনক্রিপ্ট করা মাস্টার কী (KEK সুরক্ষা সক্রিয়)", "masterKeyEncryptedWithDeviceFingerprint": "পরিবেশগত ফিঙ্গারপ্রিন্ট সহ এনক্রিপ্ট করা মাস্টার কী (KEK সুরক্ষা সক্রিয়)",
"keyNotProtectedByDeviceBinding": "কী পরিবেশগত বাঁধাই দ্বারা সুরক্ষিত নয় (আপগ্রেড করার প্রস্তাব দেওয়া হয়েছে)", "keyNotProtectedByDeviceBinding": "কী পরিবেশগত বাঁধাই দ্বারা সুরক্ষিত নয় (আপগ্রেড করার পরামর্শ দেওয়া হচ্ছে)",
"valid": "বৈধ", "valid": "বৈধ",
"initializeDatabaseEncryption": "ডাটাবেস এনক্রিপশন শুরু করুন", "initializeDatabaseEncryption": "ডাটাবেস এনক্রিপশন শুরু করুন",
"enableAes256EncryptionWithDeviceBinding": "পরিবেশ-ভিত্তিক মাস্টার কী সুরক্ষা সহ AES-256 এনক্রিপশন সক্ষম করুন। এটি SSH কী, পাসওয়ার্ড এবং প্রমাণীকরণ টোকেনের জন্য এন্টারপ্রাইজ-গ্রেড সুরক্ষা তৈরি করে।", "enableAes256EncryptionWithDeviceBinding": "পরিবেশ-ভিত্তিক মাস্টার কী সুরক্ষা সহ AES-256 এনক্রিপশন সক্ষম করুন। এটি SSH কী, পাসওয়ার্ড এবং প্রমাণীকরণ টোকেনের জন্য এন্টারপ্রাইজ-গ্রেড সুরক্ষা তৈরি করে।",
@@ -713,7 +713,7 @@
"activeSecurityFeatures": "বর্তমানে সক্রিয় নিরাপত্তা ব্যবস্থা এবং সুরক্ষা", "activeSecurityFeatures": "বর্তমানে সক্রিয় নিরাপত্তা ব্যবস্থা এবং সুরক্ষা",
"deviceBindingTechnology": "উন্নত হার্ডওয়্যার-ভিত্তিক কী সুরক্ষা প্রযুক্তি", "deviceBindingTechnology": "উন্নত হার্ডওয়্যার-ভিত্তিক কী সুরক্ষা প্রযুক্তি",
"backupAndRecovery": "নিরাপদ ব্যাকআপ তৈরি এবং ডাটাবেস পুনরুদ্ধারের বিকল্পগুলি", "backupAndRecovery": "নিরাপদ ব্যাকআপ তৈরি এবং ডাটাবেস পুনরুদ্ধারের বিকল্পগুলি",
"crossSystemDataTransfer": "বিভিন্ন সিস্টেমে ডাটাবেস রপ্তানি এবং আমদানি করুন", "crossSystemDataTransfer": "বিভিন্ন সিস্টেম জুড়ে ডাটাবেস রপ্তানি এবং আমদানি করুন",
"noMigrationNeeded": "কোনও স্থানান্তরের প্রয়োজন নেই", "noMigrationNeeded": "কোনও স্থানান্তরের প্রয়োজন নেই",
"encryptionKey": "এনক্রিপশন কী", "encryptionKey": "এনক্রিপশন কী",
"keyProtection": "চাবি সুরক্ষা", "keyProtection": "চাবি সুরক্ষা",
@@ -785,15 +785,15 @@
"downloadSample": "নমুনা ডাউনলোড করুন", "downloadSample": "নমুনা ডাউনলোড করুন",
"formatGuide": "ফর্ম্যাট গাইড", "formatGuide": "ফর্ম্যাট গাইড",
"exportCredentialWarning": "সতর্কতা: হোস্ট \"{{name}}\" শংসাপত্র প্রমাণীকরণ ব্যবহার করে। রপ্তানি করা ফাইলটিতে শংসাপত্রের ডেটা অন্তর্ভুক্ত থাকবে না এবং আমদানির পরে ম্যানুয়ালি পুনরায় কনফিগার করতে হবে। আপনি কি চালিয়ে যেতে চান?", "exportCredentialWarning": "সতর্কতা: হোস্ট \"{{name}}\" শংসাপত্র প্রমাণীকরণ ব্যবহার করে। রপ্তানি করা ফাইলটিতে শংসাপত্রের ডেটা অন্তর্ভুক্ত থাকবে না এবং আমদানির পরে ম্যানুয়ালি পুনরায় কনফিগার করতে হবে। আপনি কি চালিয়ে যেতে চান?",
"exportSensitiveDataWarning": "সতর্কতা: হোস্ট \"{{name}}\"-এ সংবেদনশীল প্রমাণীকরণ ডেটা (পাসওয়ার্ড/SSH কী) রয়েছে। এক্সপোর্ট করা ফাইলটিতে এই ডেটা প্লেইন টেক্সটে অন্তর্ভুক্ত থাকবে। দয়া করে ফাইলটি সুরক্ষিত রাখুন এবং ব্যবহারের পরে এটি মুছে ফেলুন। আপনি কি চালিয়ে যেতে চান?", "exportSensitiveDataWarning": "সতর্কতা: \"{{name}}\" হোস্টে সংবেদনশীল প্রমাণীকরণ ডেটা (পাসওয়ার্ড/SSH কী) রয়েছে। এক্সপোর্ট করা ফাইলটিতে এই ডেটা প্লেইন টেক্সটে অন্তর্ভুক্ত থাকবে। দয়া করে ফাইলটি সুরক্ষিত রাখুন এবং ব্যবহারের পরে এটি মুছে ফেলুন। আপনি কি চালিয়ে যেতে চান?",
"uncategorized": "শ্রেণীবদ্ধ নয়", "uncategorized": "শ্রেণীবদ্ধ নয়",
"confirmDelete": "তুমি কি নিশ্চিত যে তুমি \"{{name}}\" মুছে ফেলতে চা?", "confirmDelete": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" মুছে ফেলতে চা?",
"failedToDeleteHost": "হোস্ট মুছে ফেলা যায়নি", "failedToDeleteHost": "হোস্ট মুছে ফেলা যায়নি",
"failedToExportHost": "হোস্ট এক্সপোর্ট করতে ব্যর্থ হয়েছে। অনুগ্রহ করে নিশ্চিত করুন যে আপনি লগ ইন করেছেন এবং হোস্ট ডেটাতে অ্যাক্সেস আছে।", "failedToExportHost": "হোস্ট এক্সপোর্ট করা যায়নি। অনুগ্রহ করে নিশ্চিত করুন যে আপনি লগ ইন করেছেন এবং হোস্ট ডেটাতে অ্যাক্সেস আছে।",
"jsonMustContainHosts": "JSON-এ অবশ্যই একটি \"হোস্ট\" অ্যারে থাকতে হবে অথবা হোস্টের একটি অ্যারে হতে হবে", "jsonMustContainHosts": "JSON-এ অবশ্যই একটি \"হোস্ট\" অ্যারে থাকতে হবে অথবা হোস্টের একটি অ্যারে হতে হবে",
"noHostsInJson": "JSON ফাইলে কোনও হোস্ট পাওয়া যায়নি", "noHostsInJson": "JSON ফাইলে কোনও হোস্ট পাওয়া যায়নি",
"maxHostsAllowed": "প্রতি আমদানিতে সর্বোচ্চ ১০০টি হোস্ট অনুমোদিত", "maxHostsAllowed": "প্রতি আমদানিতে সর্বোচ্চ ১০০টি হোস্ট অনুমোদিত",
"importCompleted": "আমদানি সম্পন্ন হয়েছে: {{success}} সফল, {{failed}} ব্যর্থ হয়েছে", "importCompleted": "আমদানি সম্পন্ন হয়েছে: {{success}} সফল, {{failed}} ব্যর্থ",
"importFailed": "আমদানি ব্যর্থ হয়েছে", "importFailed": "আমদানি ব্যর্থ হয়েছে",
"importError": "আমদানি ত্রুটি", "importError": "আমদানি ত্রুটি",
"failedToImportJson": "JSON ফাইল আমদানি করা যায়নি", "failedToImportJson": "JSON ফাইল আমদানি করা যায়নি",
@@ -816,9 +816,9 @@
"editHost": "হোস্ট সম্পাদনা করুন", "editHost": "হোস্ট সম্পাদনা করুন",
"cloneHost": "ক্লোন হোস্ট", "cloneHost": "ক্লোন হোস্ট",
"updateHost": "হোস্ট আপডেট করুন", "updateHost": "হোস্ট আপডেট করুন",
"hostUpdatedSuccessfully": "হোস্ট \"{{name}}\" সফলভাবে আপডেট হয়েছে!", "hostUpdatedSuccessfully": "\"{{name}}\" হোস্ট সফলভাবে আপডেট হয়েছে!",
"hostAddedSuccessfully": "হোস্ট \"{{name}}\" সফলভাবে যোগ করা হয়েছে!", "hostAddedSuccessfully": "\"{{name}}\" হোস্ট সফলভাবে যোগ করা হয়েছে!",
"hostDeletedSuccessfully": "হোস্ট \"{{name}}\" সফলভাবে মুছে ফেলা হয়েছে!", "hostDeletedSuccessfully": "\"{{name}}\" হোস্টটি সফলভাবে মুছে ফেলা হয়েছে!",
"failedToSaveHost": "হোস্ট সংরক্ষণ করতে ব্যর্থ হয়েছে। দয়া করে আবার চেষ্টা করুন।", "failedToSaveHost": "হোস্ট সংরক্ষণ করতে ব্যর্থ হয়েছে। দয়া করে আবার চেষ্টা করুন।",
"savingHost": "হোস্ট সংরক্ষণ করা হচ্ছে...", "savingHost": "হোস্ট সংরক্ষণ করা হচ্ছে...",
"updatingHost": "হোস্ট আপডেট করা হচ্ছে...", "updatingHost": "হোস্ট আপডেট করা হচ্ছে...",
@@ -837,10 +837,10 @@
"connection": "সংযোগ", "connection": "সংযোগ",
"remove": "অপসারণ", "remove": "অপসারণ",
"sourcePort": "সোর্স পোর্ট", "sourcePort": "সোর্স পোর্ট",
"sourcePortDesc": "(উৎসটি সাধারণ ট্যাবে বর্তমান সংযোগের বিবরণ উল্লেখ করে)", "sourcePortDesc": " (উৎসটি সাধারণ ট্যাবে বর্তমান সংযোগের বিবরণ উল্লেখ করে)",
"endpointPort": "এন্ডপয়েন্ট পোর্ট", "endpointPort": "এন্ডপয়েন্ট পোর্ট",
"endpointSshConfig": "এন্ডপয়েন্ট SSH কনফিগারেশন", "endpointSshConfig": "এন্ডপয়েন্ট SSH কনফিগারেশন",
"tunnelForwardDescription": "এই টানেলটি সোর্স মেশিনের {{sourcePort}} পোর্ট (সাধারণ ট্যাবে বর্তমান সংযোগের বিবরণ) থেকে ট্র্যাফিককে এন্ডপয়েন্ট মেশিনের {{endpointPort}} পোর্টে ফরোয়ার্ড করবে।", "tunnelForwardDescription": "এই টানেলটি সোর্স মেশিনের {{sourcePort}} পোর্ট থেকে ট্র্যাফিককে এন্ডপয়েন্ট মেশিনের {{endpointPort}} পোর্টে ফরোয়ার্ড করবে।",
"maxRetries": "সর্বোচ্চ পুনঃপ্রচেষ্টা", "maxRetries": "সর্বোচ্চ পুনঃপ্রচেষ্টা",
"maxRetriesDescription": "টানেল সংযোগের জন্য সর্বোচ্চ সংখ্যক পুনঃপ্রচেষ্টা।", "maxRetriesDescription": "টানেল সংযোগের জন্য সর্বোচ্চ সংখ্যক পুনঃপ্রচেষ্টা।",
"retryInterval": "পুনরায় চেষ্টা করার ব্যবধান (সেকেন্ড)", "retryInterval": "পুনরায় চেষ্টা করার ব্যবধান (সেকেন্ড)",
@@ -916,10 +916,10 @@
"customCommandsDesc": "এই সার্ভারের জন্য কাস্টম শাটডাউন এবং রিবুট কমান্ড নির্ধারণ করুন", "customCommandsDesc": "এই সার্ভারের জন্য কাস্টম শাটডাউন এবং রিবুট কমান্ড নির্ধারণ করুন",
"shutdownCommand": "শাটডাউন কমান্ড", "shutdownCommand": "শাটডাউন কমান্ড",
"rebootCommand": "কমান্ড রিবুট করুন", "rebootCommand": "কমান্ড রিবুট করুন",
"confirmRemoveFromFolder": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" ফোল্ডার থেকে \"{{folder}}\" মুছে ফেলতে চান? হোস্টটি \"কোন ফোল্ডার নেই\" তে সরানো হবে", "confirmRemoveFromFolder": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" ফোল্ডার থেকে \"{{folder}}\" সরাতে চান? হোস্টটি \"কোন ফোল্ডার নেই\" তে সরানো হবে?",
"removedFromFolder": "ফোল্ডার থেকে হোস্ট \"{{name}}\" সফলভাবে সরানো হয়েছে", "removedFromFolder": "\"{{name}}\" হোস্টটি ফোল্ডার থেকে সফলভাবে সরানো হয়েছে",
"failedToRemoveFromFolder": "ফোল্ডার থেকে হোস্ট সরানো যায়নি", "failedToRemoveFromFolder": "ফোল্ডার থেকে হোস্ট সরানো যায়নি",
"folderRenamed": "\"{{oldName}}\" ফোল্ডারটির নাম পরিবর্তন করে \"{{newName}}\" করা হয়েছে", "folderRenamed": "\"{{oldName}}\" ফোল্ডারর নাম পরিবর্তন করে \"{{newName}}\" করা হয়েছে",
"failedToRenameFolder": "ফোল্ডারের নাম পরিবর্তন করা যায়নি", "failedToRenameFolder": "ফোল্ডারের নাম পরিবর্তন করা যায়নি",
"editFolderAppearance": "ফোল্ডারের উপস্থিতি সম্পাদনা করুন", "editFolderAppearance": "ফোল্ডারের উপস্থিতি সম্পাদনা করুন",
"editFolderAppearanceDesc": "ফোল্ডারের রঙ এবং আইকন কাস্টমাইজ করুন", "editFolderAppearanceDesc": "ফোল্ডারের রঙ এবং আইকন কাস্টমাইজ করুন",
@@ -929,21 +929,21 @@
"folderAppearanceUpdated": "ফোল্ডারের উপস্থিতি সফলভাবে আপডেট করা হয়েছে", "folderAppearanceUpdated": "ফোল্ডারের উপস্থিতি সফলভাবে আপডেট করা হয়েছে",
"failedToUpdateFolderAppearance": "ফোল্ডারের উপস্থিতি আপডেট করা যায়নি", "failedToUpdateFolderAppearance": "ফোল্ডারের উপস্থিতি আপডেট করা যায়নি",
"deleteAllHostsInFolder": "ফোল্ডারে থাকা সকল হোস্ট মুছে ফেলুন", "deleteAllHostsInFolder": "ফোল্ডারে থাকা সকল হোস্ট মুছে ফেলুন",
"confirmDeleteAllHostsInFolder": "আপনি কি নিশ্চিত যে আপনি \"{{count}}\" ফোল্ডারে সমস্ত {{folder}} হোস্ট মুছে ফেলতে চান? এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।", "confirmDeleteAllHostsInFolder": "\"{{folder}}\" ফোল্ডারে থাকা সমস্ত {{count}} হোস্ট মুছে ফেলার বিষয়ে আপনি কি নিশ্চিত? এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।",
"allHostsInFolderDeleted": "\"{{count}}\" ফোল্ডার থেকে {{folder}} হোস্ট সফলভাবে মুছে ফেলা হয়েছে", "allHostsInFolderDeleted": "\"{{folder}}\" ফোল্ডার থেকে {{count}} হোস্টগুলি সফলভাবে মুছে ফেলা হয়েছে",
"failedToDeleteHostsInFolder": "ফোল্ডারে হোস্ট মুছে ফেলা যায়নি", "failedToDeleteHostsInFolder": "ফোল্ডারে হোস্ট মুছে ফেলা যায়নি",
"movedToFolder": "হোস্ট \"{{name}}\" সফলভাবে \"{{folder}}\" সরানো হয়েছে", "movedToFolder": "\"{{name}}\" হোস্টটি সফলভাবে \"{{folder}}\" তে সরানো হয়েছে",
"failedToMoveToFolder": "হোস্টকে ফোল্ডারে সরানো যায়নি", "failedToMoveToFolder": "হোস্টকে ফোল্ডারে সরানো যায়নি",
"clickToRenameFolder": "ফোল্ডারের নাম পরিবর্তন করতে ক্লিক করুন", "clickToRenameFolder": "ফোল্ডারের নাম পরিবর্তন করতে ক্লিক করুন",
"renameFolder": "ফোল্ডারটির নাম পরিবর্তন করুন", "renameFolder": "ফোল্ডারটির নাম পরিবর্তন করুন",
"removeFromFolder": "\"{{folder}}\" ফোল্ডার থেকে সরান", "removeFromFolder": "\"{{folder}}\" ফোল্ডার থেকে সরান",
"editHostTooltip": "হোস্ট সম্পাদনা করুন", "editHostTooltip": "হোস্ট সম্পাদনা করুন",
"deleteHostTooltip": "হোস্ট মুছুন", "deleteHostTooltip": "হোস্ট মুছুন",
"exportHostTooltip": "হোস্ট রপ্তানি করুন", "exportHostTooltip": "হোস্ট রপ্তানি করুন",
"cloneHostTooltip": "ক্লোন হোস্ট", "cloneHostTooltip": "ক্লোন হোস্ট",
"clickToEditHost": "হোস্ট সম্পাদনা করতে ক্লিক করুন", "clickToEditHost": "হোস্ট সম্পাদনা করতে ক্লিক করুন",
"dragToMoveBetweenFolders": "ফোল্ডার থেকে অন্য ফোল্ডারে যেতে টেনে আনুন", "dragToMoveBetweenFolders": "ফোল্ডার থেকে অন্য ফোল্ডারে যেতে টেনে আনুন",
"exportedHostConfig": "{{name}} এর জন্য হোস্ট কনফিগারেশন রপ্তানি করা হয়েছে", "exportedHostConfig": "{{name}}এর জন্য হোস্ট কনফিগারেশন রপ্তানি করা হয়েছে",
"openTerminal": "টার্মিনাল খুলুন", "openTerminal": "টার্মিনাল খুলুন",
"openFileManager": "ফাইল ম্যানেজার খুলুন", "openFileManager": "ফাইল ম্যানেজার খুলুন",
"openTunnels": "খোলা টানেল", "openTunnels": "খোলা টানেল",
@@ -982,7 +982,7 @@
"selectFont": "ফন্ট নির্বাচন করুন", "selectFont": "ফন্ট নির্বাচন করুন",
"selectFontDesc": "টার্মিনালে ব্যবহার করার জন্য ফন্ট নির্বাচন করুন", "selectFontDesc": "টার্মিনালে ব্যবহার করার জন্য ফন্ট নির্বাচন করুন",
"fontSize": "ফন্ট সাইজ", "fontSize": "ফন্ট সাইজ",
"fontSizeValue": "ফন্ট সাইজ: {{value}}px", "fontSizeValue": "ফন্ট সাইজ: {{value}}পিক্সেল",
"adjustFontSize": "টার্মিনাল ফন্টের আকার সামঞ্জস্য করুন", "adjustFontSize": "টার্মিনাল ফন্টের আকার সামঞ্জস্য করুন",
"letterSpacing": "অক্ষরের ব্যবধান", "letterSpacing": "অক্ষরের ব্যবধান",
"letterSpacingValue": "অক্ষরের ব্যবধান: {{value}}px", "letterSpacingValue": "অক্ষরের ব্যবধান: {{value}}px",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "শব্দ", "bellStyleSound": "শব্দ",
"bellStyleVisual": "ভিজ্যুয়াল", "bellStyleVisual": "ভিজ্যুয়াল",
"bellStyleBoth": "উভয়ই", "bellStyleBoth": "উভয়ই",
"bellStyleDesc": "টার্মিনাল বেল (BEL অক্ষর, \\x07) কীভাবে পরিচালনা করবেন। প্রোগ্রামগুলি কাজ সম্পন্ন করার সময়, ত্রুটির সম্মুখীন হওয়ার সময় বা বিজ্ঞপ্তির জন্য এটি ট্রিগার করে। \"সাউন্ড\" একটি অডিও বিপ বাজায়, \"ভিজ্যুয়াল\" স্ক্রিনটি সংক্ষিপ্তভাবে ফ্ল্যাশ করে, \"উভয়\" উভয়ই করে, \"কোনটিই নয়\" বেল সতর্কতা অক্ষম করে।", "bellStyleDesc": "টার্মিনাল বেল (BEL অক্ষর, \\x07) কীভাবে পরিচালনা করবেন। প্রোগ্রামগুলি কাজ সম্পন্ন করার সময়, ত্রুটির সম্মুখীন হওয়ার সময় বা বিজ্ঞপ্তির জন্য এটি ট্রিগার করে। \"সাউন্ড\" একটি অডিও বিপ বাজায়, \"ভিজ্যুয়াল\" স্ক্রিনটি সংক্ষিপ্তভাবে ফ্ল্যাশ করে, \"উভয়\" উভয়ই করে, \"কিছুই নয়\" বেল সতর্কতা অক্ষম করে।",
"rightClickSelectsWord": "রাইট ক্লিক করলে শব্দ নির্বাচন করা হয়", "rightClickSelectsWord": "রাইট ক্লিক করলে শব্দ নির্বাচন করা হয়",
"rightClickSelectsWordDesc": "ডান-ক্লিক করলে কার্সারের নীচের শব্দটি নির্বাচন করা হয়", "rightClickSelectsWordDesc": "ডান-ক্লিক করলে কার্সারের নীচের শব্দটি নির্বাচন করা হয়",
"fastScrollModifier": "দ্রুত স্ক্রোল সংশোধক", "fastScrollModifier": "দ্রুত স্ক্রোল সংশোধক",
@@ -1049,15 +1049,15 @@
"noServerFound": "কোন সার্ভার পাওয়া যায়নি।", "noServerFound": "কোন সার্ভার পাওয়া যায়নি।",
"jumpHostsOrder": "সংযোগগুলি ক্রমানুসারে তৈরি করা হবে: জাম্প হোস্ট ১ → জাম্প হোস্ট ২ → ... → টার্গেট সার্ভার", "jumpHostsOrder": "সংযোগগুলি ক্রমানুসারে তৈরি করা হবে: জাম্প হোস্ট ১ → জাম্প হোস্ট ২ → ... → টার্গেট সার্ভার",
"socks5Proxy": "SOCKS5 প্রক্সি", "socks5Proxy": "SOCKS5 প্রক্সি",
"socks5Description": "SSH সংযোগের জন্য SOCKS5 প্রক্সি কনফিগার করুন। সমস্ত ট্র্যাফিক নির্দিষ্ট প্রক্সি সার্ভারের মাধ্যমে রাউটেড হবে।", "socks5Description": "SSH সংযোগের জন্য SOCKS5 প্রক্সি কনফিগার করুন। সমস্ত ট্র্যাফিক নির্দিষ্ট প্রক্সি সার্ভারের মাধ্যমে রাউট করা হবে।",
"enableSocks5": "SOCKS5 প্রক্সি সক্ষম করুন", "enableSocks5": "SOCKS5 প্রক্সি সক্ষম করুন",
"enableSocks5Description": "এই SSH সংযোগের জন্য SOCKS5 প্রক্সি ব্যবহার করুন", "enableSocks5Description": "এই SSH সংযোগের জন্য SOCKS5 প্রক্সি ব্যবহার করুন",
"socks5Host": "প্রক্সি হোস্ট", "socks5Host": "প্রক্সি হোস্ট",
"socks5Port": "প্রক্সি পোর্ট", "socks5Port": "প্রক্সি পোর্ট",
"socks5Username": "প্রক্সি ব্যবহারকারীর নাম", "socks5Username": "প্রক্সি ব্যবহারকারীর নাম",
"socks5Password": "প্রক্সি পাসওয়ার্ড", "socks5Password": "প্রক্সি পাসওয়ার্ড",
"socks5UsernameOptional": "ঐচ্ছিক: যদি প্রক্সির প্রমাণীকরণের প্রয়োজন না হয় তবে খালি রাখুন", "socks5UsernameOptional": "ঐচ্ছিক: প্রক্সির প্রমাণীকরণের প্রয়োজন না হে খালি রাখুন",
"socks5PasswordOptional": "ঐচ্ছিক: যদি প্রক্সির প্রমাণীকরণের প্রয়োজন না হয় তবে খালি রাখুন", "socks5PasswordOptional": "ঐচ্ছিক: প্রক্সির প্রমাণীকরণের প্রয়োজন না হে খালি রাখুন",
"socks5ProxyChain": "প্রক্সি চেইন", "socks5ProxyChain": "প্রক্সি চেইন",
"socks5ProxyChainDescription": "SOCKS প্রক্সির একটি চেইন কনফিগার করুন। চেইনের প্রতিটি প্রক্সি পূর্ববর্তীটির মাধ্যমে সংযুক্ত হবে।", "socks5ProxyChainDescription": "SOCKS প্রক্সির একটি চেইন কনফিগার করুন। চেইনের প্রতিটি প্রক্সি পূর্ববর্তীটির মাধ্যমে সংযুক্ত হবে।",
"socks5ProxyMode": "প্রক্সি মোড", "socks5ProxyMode": "প্রক্সি মোড",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "প্রক্সি চেইন প্রিসেট তৈরি করা হয়েছে", "socks5PresetCreated": "প্রক্সি চেইন প্রিসেট তৈরি করা হয়েছে",
"socks5PresetUpdated": "প্রক্সি চেইন প্রিসেট আপডেট করা হয়েছে", "socks5PresetUpdated": "প্রক্সি চেইন প্রিসেট আপডেট করা হয়েছে",
"socks5PresetDeleted": "প্রক্সি চেইন প্রিসেট মুছে ফেলা হয়েছে", "socks5PresetDeleted": "প্রক্সি চেইন প্রিসেট মুছে ফেলা হয়েছে",
"socks5PresetSaved": "প্রিসেট \"{{name}}\" সফলভাবে সংরক্ষিত হয়েছে", "socks5PresetSaved": "\"{{name}}\" প্রিসেট সফলভাবে সংরক্ষণ করা হয়েছে",
"socks5PresetSaveError": "প্রিসেট সংরক্ষণ করা যায়নি", "socks5PresetSaveError": "প্রিসেট সংরক্ষণ করা যায়নি",
"socks5PresetNameRequired": "প্রিসেট নাম প্রয়োজন", "socks5PresetNameRequired": "প্রিসেট নাম প্রয়োজন",
"socks5EmptyChainError": "একটি খালি প্রক্সি চেইন সংরক্ষণ করা যাচ্ছে না", "socks5EmptyChainError": "একটি খালি প্রক্সি চেইন সংরক্ষণ করা যাচ্ছে না",
@@ -1095,7 +1095,7 @@
"addQuickAction": "দ্রুত পদক্ষেপ যোগ করুন", "addQuickAction": "দ্রুত পদক্ষেপ যোগ করুন",
"quickActionName": "অ্যাকশনের নাম", "quickActionName": "অ্যাকশনের নাম",
"noSnippetFound": "কোনও স্নিপেট পাওয়া যায়নি", "noSnippetFound": "কোনও স্নিপেট পাওয়া যায়নি",
"quickActionsOrder": "সার্ভার স্ট্যাটাস পৃষ্ঠায় উপরে তালিকাভুক্ত ক্রমে দ্রুত পদক্ষেপের বোতামগুলি প্রদর্শিত হবে।", "quickActionsOrder": "সার্ভার পরিসংখ্যান পৃষ্ঠায় উপরে তালিকাভুক্ত ক্রমে দ্রুত পদক্ষেপের বোতামগুলি প্রদর্শিত হবে।",
"advancedAuthSettings": "উন্নত প্রমাণীকরণ সেটিংস", "advancedAuthSettings": "উন্নত প্রমাণীকরণ সেটিংস",
"sudoPasswordAutoFill": "সুডো পাসওয়ার্ড অটো-ফিল", "sudoPasswordAutoFill": "সুডো পাসওয়ার্ড অটো-ফিল",
"sudoPasswordAutoFillDesc": "sudo পাসওয়ার্ডের জন্য অনুরোধ করলে স্বয়ংক্রিয়ভাবে SSH পাসওয়ার্ড সন্নিবেশ করার প্রস্তাব দেয়", "sudoPasswordAutoFillDesc": "sudo পাসওয়ার্ডের জন্য অনুরোধ করলে স্বয়ংক্রিয়ভাবে SSH পাসওয়ার্ড সন্নিবেশ করার প্রস্তাব দেয়",
@@ -1119,7 +1119,7 @@
"validating": "ডকার যাচাই করা হচ্ছে...", "validating": "ডকার যাচাই করা হচ্ছে...",
"error": "ত্রুটি", "error": "ত্রুটি",
"errorCode": "ত্রুটি কোড: {{code}}", "errorCode": "ত্রুটি কোড: {{code}}",
"version": "ডকার v{{version}}", "version": "ডকার বনাম{{version}}",
"current": "বর্তমান", "current": "বর্তমান",
"used_limit": "ব্যবহৃত / সীমা", "used_limit": "ব্যবহৃত / সীমা",
"percentage": "শতাংশ", "percentage": "শতাংশ",
@@ -1133,7 +1133,7 @@
"console": "কনসোল", "console": "কনসোল",
"containerMustBeRunning": "কনসোলের সাথে সংযোগ স্থাপনের জন্য কন্টেইনারটি অবশ্যই চলমান থাকতে হবে", "containerMustBeRunning": "কনসোলের সাথে সংযোগ স্থাপনের জন্য কন্টেইনারটি অবশ্যই চলমান থাকতে হবে",
"authenticationRequired": "প্রমাণীকরণ প্রয়োজন", "authenticationRequired": "প্রমাণীকরণ প্রয়োজন",
"connectedTo": "{{containerName}} এর সাথে সংযুক্ত", "connectedTo": "{{containerName}}এর সাথে সংযুক্ত",
"disconnected": "সংযোগ বিচ্ছিন্ন", "disconnected": "সংযোগ বিচ্ছিন্ন",
"consoleError": "কনসোল ত্রুটি", "consoleError": "কনসোল ত্রুটি",
"errorMessage": "ত্রুটি: {{message}}", "errorMessage": "ত্রুটি: {{message}}",
@@ -1150,7 +1150,7 @@
"disconnect": "সংযোগ বিচ্ছিন্ন করুন", "disconnect": "সংযোগ বিচ্ছিন্ন করুন",
"notConnected": "সংযুক্ত নেই", "notConnected": "সংযুক্ত নেই",
"clickToConnect": "একটি ইন্টারেক্টিভ শেল শুরু করতে Connect এ ক্লিক করুন।", "clickToConnect": "একটি ইন্টারেক্টিভ শেল শুরু করতে Connect এ ক্লিক করুন।",
"connectingTo": "{{containerName}} এর সাথে সংযোগ স্থাপন করা হচ্ছে...", "connectingTo": "{{containerName}}এর সাথে সংযুক্ত হচ্ছে ...",
"containerMustBeRunningToViewStats": "পরিসংখ্যান দেখার জন্য কন্টেইনারটি অবশ্যই চলমান থাকতে হবে", "containerMustBeRunningToViewStats": "পরিসংখ্যান দেখার জন্য কন্টেইনারটি অবশ্যই চলমান থাকতে হবে",
"failedToFetchStats": "পরিসংখ্যান আনতে ব্যর্থ হয়েছে", "failedToFetchStats": "পরিসংখ্যান আনতে ব্যর্থ হয়েছে",
"noContainersFound": "কোনও কন্টেইনার পাওয়া যায়নি", "noContainersFound": "কোনও কন্টেইনার পাওয়া যায়নি",
@@ -1162,15 +1162,15 @@
"noContainersMatchFilters": "আপনার ফিল্টারের সাথে কোনও কন্টেইনার মেলে না", "noContainersMatchFilters": "আপনার ফিল্টারের সাথে কোনও কন্টেইনার মেলে না",
"noContainersMatchFiltersHint": "আপনার অনুসন্ধান বা ফিল্টার সামঞ্জস্য করার চেষ্টা করুন", "noContainersMatchFiltersHint": "আপনার অনুসন্ধান বা ফিল্টার সামঞ্জস্য করার চেষ্টা করুন",
"containerStarted": "কন্টেইনার {{name}} শুরু হয়েছে", "containerStarted": "কন্টেইনার {{name}} শুরু হয়েছে",
"failedToStartContainer": "কন্টেইনার চালু করতে ব্যর্থ: {{error}}", "failedToStartContainer": "কন্টেইনার শুরু করতে ব্যর্থ: {{error}}",
"containerStopped": "{{name}} ন্টেইনার থামানো হয়েছে", "containerStopped": "কন্টেইনার {{name}} ন্ধ করা হয়েছে",
"failedToStopContainer": "কন্টেইনার থামাতে ব্যর্থ: {{error}}", "failedToStopContainer": "কন্টেইনার থামাতে ব্যর্থ হয়েছে: {{error}}",
"containerRestarted": "কন্টেইনার {{name}} পুনরায় চালু হয়েছে", "containerRestarted": "কন্টেইনার {{name}} পুনরায় চালু হয়েছে",
"failedToRestartContainer": "কন্টেইনারটি পুনরায় চালু করতে ব্যর্থ হয়েছে: {{error}}", "failedToRestartContainer": "কন্টেইনারটি পুনরায় চালু করতে ব্যর্থ হয়েছে: {{error}}",
"containerUnpaused": "{{name}} কন্টেইনারটি আনপজ করা হয়েছে", "containerUnpaused": "কন্টেইনার {{name}} অব্যবহৃত",
"containerPaused": "{{name}} কন্টেইনার থামানো হয়েছে", "containerPaused": "কন্টেইনার {{name}} থামানো হয়েছে",
"failedToTogglePauseContainer": "{{action}} কন্টেইনারে ব্যর্থ হয়েছে: {{error}}", "failedToTogglePauseContainer": "{{action}} কন্টেইনারে ব্যর্থ: {{error}}",
"containerRemoved": "{{name}} কন্টেইনার সরানো হয়েছে", "containerRemoved": "কন্টেইনার {{name}} সরানো হয়েছে",
"failedToRemoveContainer": "কন্টেইনার সরানো যায়নি: {{error}}", "failedToRemoveContainer": "কন্টেইনার সরানো যায়নি: {{error}}",
"image": "ছবি:", "image": "ছবি:",
"idLabel": "আইডি:", "idLabel": "আইডি:",
@@ -1183,7 +1183,7 @@
"pause": "বিরতি", "pause": "বিরতি",
"restart": "পুনরারম্ভ করুন", "restart": "পুনরারম্ভ করুন",
"removeContainer": "কন্টেইনার সরান", "removeContainer": "কন্টেইনার সরান",
"confirmRemoveContainer": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" কন্টেইনারটি সরাতে চান?", "confirmRemoveContainer": "Are you sure you want to remove container \"{{name}}\"?",
"runningContainerWarning": "সতর্কতা: এই কন্টেইনারটি বর্তমানে চলছে এবং জোর করে সরিয়ে ফেলা হবে।", "runningContainerWarning": "সতর্কতা: এই কন্টেইনারটি বর্তমানে চলছে এবং জোর করে সরিয়ে ফেলা হবে।",
"removing": "অপসারণ:", "removing": "অপসারণ:",
"containerNotFound": "কন্টেইনারটি পাওয়া যায়নি", "containerNotFound": "কন্টেইনারটি পাওয়া যায়নি",
@@ -1191,7 +1191,7 @@
"logs": "লগ", "logs": "লগ",
"stats": "পরিসংখ্যান", "stats": "পরিসংখ্যান",
"consoleTab": "কনসোল", "consoleTab": "কনসোল",
"failedToFetchLogs": "লগগুলি আনা যায়নি: {{error}}", "failedToFetchLogs": "লগগুলি আনতে ব্যর্থ হয়েছে: {{error}}",
"failedToDownloadLogs": "লগ ডাউনলোড করতে ব্যর্থ: {{error}}", "failedToDownloadLogs": "লগ ডাউনলোড করতে ব্যর্থ: {{error}}",
"linesToShow": "দেখানোর জন্য লাইনগুলি", "linesToShow": "দেখানোর জন্য লাইনগুলি",
"last50Lines": "শেষ ৫০টি লাইন", "last50Lines": "শেষ ৫০টি লাইন",
@@ -1254,26 +1254,26 @@
"uploadFile": "ফাইল আপলোড করুন", "uploadFile": "ফাইল আপলোড করুন",
"downloadFile": "ডাউনলোড করুন", "downloadFile": "ডাউনলোড করুন",
"extractArchive": "আর্কাইভ এক্সট্র্যাক্ট করুন", "extractArchive": "আর্কাইভ এক্সট্র্যাক্ট করুন",
"extractingArchive": "{{name}} বের করা হচ্ছে...", "extractingArchive": "এক্সট্রাক্ট করা হচ্ছে {{name}}...",
"archiveExtractedSuccessfully": "{{name}} সফলভাবে বের করা হয়েছে", "archiveExtractedSuccessfully": "{{name}} সফলভাবে বের করা হয়েছে",
"extractFailed": "এক্সট্র্যাক্ট করা যায়নি", "extractFailed": "এক্সট্র্যাক্ট করা যায়নি",
"compressFile": "ফাইল কম্প্রেস করুন", "compressFile": "ফাইল কম্প্রেস করুন",
"compressFiles": "ফাইল কম্প্রেস করুন", "compressFiles": "ফাইল কম্প্রেস করুন",
"compressFilesDesc": "{{count}} টি আইটেম একটি আর্কাইভে সঙ্কুচিত করুন", "compressFilesDesc": "{{count}} আইটেমগুলিকে একটি আর্কাইভে সঙ্কুচিত করুন",
"archiveName": "আর্কাইভের নাম", "archiveName": "আর্কাইভের নাম",
"enterArchiveName": "সংরক্ষণাগারের নাম লিখুন...", "enterArchiveName": "সংরক্ষণাগারের নাম লিখুন...",
"compressionFormat": "কম্প্রেশন ফর্ম্যাট", "compressionFormat": "কম্প্রেশন ফর্ম্যাট",
"selectedFiles": "নির্বাচিত ফাইলগুলি", "selectedFiles": "নির্বাচিত ফাইলগুলি",
"andMoreFiles": "এবং {{count}} আরও...", "andMoreFiles": "এবং {{count}} আরও...",
"compress": "সংকুচিত করুন", "compress": "সংকুচিত করুন",
"compressingFiles": "{{count}}টি আইটেমকে {{name}}... এ সংকুচিত করা হচ্ছে", "compressingFiles": "{{count}} আইটেমগুলিকে {{name}}এ সংকুচিত করা হচ্ছে ...",
"filesCompressedSuccessfully": "{{name}} সফলভাবে তৈরি করা হয়েছে", "filesCompressedSuccessfully": "{{name}} সফলভাবে তৈরি করা হয়েছে",
"compressFailed": "কম্প্রেশন ব্যর্থ হয়েছে", "compressFailed": "কম্প্রেশন ব্যর্থ হয়েছে",
"edit": "সম্পাদনা", "edit": "সম্পাদনা",
"preview": "প্রিভিউ", "preview": "প্রিভিউ",
"previous": "পূর্ববর্তী", "previous": "পূর্ববর্তী",
"next": "পরবর্তী", "next": "পরবর্তী",
"pageXOfY": "{{current}} পৃষ্ঠা {{total}}", "pageXOfY": "{{current}} এর {{total}}পৃষ্ঠা",
"zoomOut": "জুম কমান", "zoomOut": "জুম কমান",
"zoomIn": "জুম ইন", "zoomIn": "জুম ইন",
"newFile": "নতুন ফাইল", "newFile": "নতুন ফাইল",
@@ -1289,13 +1289,13 @@
"chooseFile": "ফাইল নির্বাচন করুন", "chooseFile": "ফাইল নির্বাচন করুন",
"uploading": "আপলোড হচ্ছে...", "uploading": "আপলোড হচ্ছে...",
"downloading": "ডাউনলোড হচ্ছে...", "downloading": "ডাউনলোড হচ্ছে...",
"uploadingFile": "{{name}} আপলোড করা হচ্ছে...", "uploadingFile": "আপলোড করা হচ্ছে {{name}}...",
"uploadingLargeFile": "বড় ফাইল আপলোড করা হচ্ছে {{name}} ({{size}})...", "uploadingLargeFile": "বড় ফাইল আপলোড করা হচ্ছে {{name}} ({{size}})...",
"downloadingFile": "{{name}} ডাউনলোড হচ্ছে...", "downloadingFile": "ডাউনলোড করা হচ্ছে {{name}}...",
"creatingFile": "{{name}} তৈরি করা হচ্ছে...", "creatingFile": "{{name}}তৈরি করা হচ্ছে ...",
"creatingFolder": "{{name}} তৈরি করা হচ্ছে...", "creatingFolder": "{{name}}তৈরি করা হচ্ছে ...",
"deletingItem": "{{type}} {{name}} মুছে ফেলা হচ্ছে...", "deletingItem": "মুছে ফেলা হচ্ছে {{type}} {{name}}...",
"renamingItem": "{{type}} {{oldName}} এর নাম পরিবর্তন করে {{newName}} করা হচ্ছে...", "renamingItem": "{{type}} {{oldName}} নাম পরিবর্তন করে {{newName}}করা হচ্ছে ...",
"createNewFile": "নতুন ফাইল তৈরি করুন", "createNewFile": "নতুন ফাইল তৈরি করুন",
"fileName": "ফাইলের নাম", "fileName": "ফাইলের নাম",
"creating": "তৈরি করা হচ্ছে...", "creating": "তৈরি করা হচ্ছে...",
@@ -1311,25 +1311,25 @@
"newName": "নতুন নাম", "newName": "নতুন নাম",
"thisIsDirectoryRename": "এটি একটি ডিরেক্টরি।", "thisIsDirectoryRename": "এটি একটি ডিরেক্টরি।",
"renaming": "নাম পরিবর্তন করা হচ্ছে...", "renaming": "নাম পরিবর্তন করা হচ্ছে...",
"fileUploadedSuccessfully": "\"{{name}}}\" ফাইলটি সফলভাবে আপলোড করা হয়েছে", "fileUploadedSuccessfully": "\"{{name}}\" ফাইলটি সফলভাবে আপলোড করা হয়েছে",
"failedToUploadFile": "ফাইল আপলোড করা যায়নি", "failedToUploadFile": "ফাইল আপলোড করা যায়নি",
"fileDownloadedSuccessfully": "\"{{name}}\" ফাইলটি সফলভাবে ডাউনলোড করা হয়েছে", "fileDownloadedSuccessfully": "\"{{name}}\" ফাইলটি সফলভাবে ডাউনলোড করা হয়েছে",
"failedToDownloadFile": "ফাইল ডাউনলোড করতে ব্যর্থ হয়েছে", "failedToDownloadFile": "ফাইল ডাউনলোড করতে ব্যর্থ হয়েছে",
"noFileContent": "কোনও ফাইলের বিষয়বস্তু পাওয়া যায়নি", "noFileContent": "কোনও ফাইলের বিষয়বস্তু পাওয়া যায়নি",
"filePath": "ফাইল পাথ", "filePath": "ফাইল পাথ",
"fileCreatedSuccessfully": "\"{{name}}}\" ফাইলটি সফলভাবে তৈরি করা হয়েছে", "fileCreatedSuccessfully": "\"{{name}}\" ফাইলটি সফলভাবে তৈরি করা হয়েছে",
"failedToCreateFile": "ফাইল তৈরি করা যায়নি", "failedToCreateFile": "ফাইল তৈরি করা যায়নি",
"folderCreatedSuccessfully": "\"{{name}}\" ফোল্ডারটি সফলভাবে তৈরি করা হয়েছে", "folderCreatedSuccessfully": "\"{{name}}\" ফোল্ডারটি সফলভাবে তৈরি করা হয়েছে",
"failedToCreateFolder": "ফোল্ডার তৈরি করতে ব্যর্থ হয়েছে", "failedToCreateFolder": "ফোল্ডার তৈরি করতে ব্যর্থ হয়েছে",
"failedToCreateItem": "আইটেম তৈরি করা যায়নি", "failedToCreateItem": "আইটেম তৈরি করা যায়নি",
"operationFailed": "{{operation}} {{name}}: {{error}} এর জন্য অপারেশন ব্যর্থ হয়েছে", "operationFailed": "{{operation}} {{name}}এর জন্য অপারেশন ব্যর্থ হয়েছে : {{error}}",
"failedToResolveSymlink": "সিমলিঙ্ক সমাধান করা যায়নি", "failedToResolveSymlink": "সিমলিঙ্ক সমাধান করা যায়নি",
"itemDeletedSuccessfully": "{{type}} সফলভাবে মুছে ফেলা হয়েছে", "itemDeletedSuccessfully": "{{type}} সফলভাবে মুছে ফেলা হয়েছে",
"itemsDeletedSuccessfully": "{{count}}টি আইটেম সফলভাবে মুছে ফেলা হয়েছে", "itemsDeletedSuccessfully": "{{count}} আইটেমগুলি সফলভাবে মুছে ফেলা হয়েছে",
"failedToDeleteItems": "আইটেমগুলি মোছা যায়নি", "failedToDeleteItems": "আইটেমগুলি মোছা যায়নি",
"dragFilesToUpload": "আপলোড করার জন্য ফাইলগুলি এখানে ফেলে দিন", "dragFilesToUpload": "আপলোড করার জন্য ফাইলগুলি এখানে ফেলে দিন",
"emptyFolder": "এই ফোল্ডারটি খালি।", "emptyFolder": "এই ফোল্ডারটি খালি।",
"itemCount": "{{count}}টি আইটেম", "itemCount": "{{count}} আইটেম",
"selectedCount": "{{count}} নির্বাচিত", "selectedCount": "{{count}} নির্বাচিত",
"searchFiles": "ফাইলগুলি অনুসন্ধান করুন...", "searchFiles": "ফাইলগুলি অনুসন্ধান করুন...",
"upload": "আপলোড করুন", "upload": "আপলোড করুন",
@@ -1347,25 +1347,25 @@
"delete": "মুছে ফেলুন", "delete": "মুছে ফেলুন",
"properties": "বৈশিষ্ট্য", "properties": "বৈশিষ্ট্য",
"refresh": "রিফ্রেশ করুন", "refresh": "রিফ্রেশ করুন",
"downloadFiles": "ব্রাউজারে {{count}} ফাইল ডাউনলোড করুন", "downloadFiles": "{{count}} ফাইলগুলি ব্রাউজারে ডাউনলোড করুন",
"copyFiles": "{{count}} টি আইটেম কপি করুন", "copyFiles": "{{count}} আইটেমগুলি কপি করুন",
"cutFiles": "{{count}}টি আইটেম কাটুন", "cutFiles": "{{count}} আইটেম কাটুন",
"deleteFiles": "{{count}}টি আইটেম মুছুন", "deleteFiles": "{{count}} আইটেম মুছুন",
"filesCopiedToClipboard": "{{count}}টি আইটেম ক্লিপবোর্ডে কপি করা হয়েছে", "filesCopiedToClipboard": "{{count}} আইটেমগুলি ক্লিপবোর্ডে কপি করা হয়েছে",
"filesCutToClipboard": "{{count}}টি আইটেম ক্লিপবোর্ডে কাটা হয়েছে", "filesCutToClipboard": "{{count}} ক্লিপবোর্ডে কাটা আইটেম",
"pathCopiedToClipboard": "ক্লিপবোর্ডে পাথ কপি করা হয়েছে", "pathCopiedToClipboard": "ক্লিপবোর্ডে পাথ কপি করা হয়েছে",
"pathsCopiedToClipboard": "{{count}} পাথ ক্লিপবোর্ডে কপি করা হয়েছে", "pathsCopiedToClipboard": "{{count}} ক্লিপবোর্ডে পাথ কপি করা হয়েছে",
"failedToCopyPath": "ক্লিপবোর্ডে পাথ কপি করতে ব্যর্থ হয়েছে", "failedToCopyPath": "ক্লিপবোর্ডে পাথ কপি করতে ব্যর্থ হয়েছে",
"movedItems": "{{count}}টি আইটেম সরানো হয়েছে", "movedItems": "{{count}} আইটেমগুলি সরানো হয়েছে",
"failedToDeleteItem": "আইটেমটি মোছা যায়নি", "failedToDeleteItem": "আইটেমটি মোছা যায়নি",
"itemRenamedSuccessfully": "{{type}} সফলভাবে পুনঃনামকরণ করা হয়েছে", "itemRenamedSuccessfully": "{{type}} নাম পরিবর্তন করা হয়েছে",
"failedToRenameItem": "আইটেমটির নাম পরিবর্তন করা যায়নি", "failedToRenameItem": "আইটেমটির নাম পরিবর্তন করা যায়নি",
"download": "ডাউনলোড করুন", "download": "ডাউনলোড করুন",
"permissions": "অনুমতিসমূহ", "permissions": "অনুমতিসমূহ",
"size": "আকার", "size": "আকার",
"modified": "পরিবর্তিত", "modified": "পরিবর্তিত",
"path": "পথ", "path": "পথ",
"confirmDelete": "আপনি কি নিশ্চিত যে আপনি {{name}} মুছে ফেলতে চান?", "confirmDelete": "আপনি কি নিশ্চিত যে আপনি {{name}}মুছে ফেলতে চান?",
"uploadSuccess": "ফাইলটি সফলভাবে আপলোড করা হয়েছে", "uploadSuccess": "ফাইলটি সফলভাবে আপলোড করা হয়েছে",
"uploadFailed": "ফাইল আপলোড ব্যর্থ হয়েছে", "uploadFailed": "ফাইল আপলোড ব্যর্থ হয়েছে",
"downloadSuccess": "ফাইলটি সফলভাবে ডাউনলোড হয়েছে", "downloadSuccess": "ফাইলটি সফলভাবে ডাউনলোড হয়েছে",
@@ -1388,9 +1388,9 @@
"connectToServer": "একটি সার্ভারের সাথে সংযোগ করুন", "connectToServer": "একটি সার্ভারের সাথে সংযোগ করুন",
"selectServerToEdit": "ফাইল সম্পাদনা শুরু করতে সাইডবার থেকে একটি সার্ভার নির্বাচন করুন।", "selectServerToEdit": "ফাইল সম্পাদনা শুরু করতে সাইডবার থেকে একটি সার্ভার নির্বাচন করুন।",
"fileOperations": "ফাইল অপারেশন", "fileOperations": "ফাইল অপারেশন",
"confirmDeleteMessage": "আপনি কি নিশ্চিত যে আপনি {{name}} মুছে ফেলতে চান?", "confirmDeleteMessage": "আপনি কি নিশ্চিত যে আপনি {{name}}মুছে ফেলতে চান?",
"confirmDeleteSingleItem": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" স্থায়ীভাবে মুছে ফেলতে চান?", "confirmDeleteSingleItem": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" স্থায়ীভাবে মুছে ফেলতে চান?",
"confirmDeleteMultipleItems": "আপনি কি নিশ্চিত যে আপনি {{count}} টি আইটেম স্থায়ীভাবে মুছে ফেলতে চান?", "confirmDeleteMultipleItems": "আপনি কি নিশ্চিত যে আপনি {{count}} আইটেমগুলি স্থায়ীভাবে মুছে ফেলতে চান?",
"confirmDeleteMultipleItemsWithFolders": "আপনি কি নিশ্চিত যে আপনি {{count}} আইটেমগুলি স্থায়ীভাবে মুছে ফেলতে চান? এর মধ্যে ফোল্ডার এবং তাদের সামগ্রী অন্তর্ভুক্ত।", "confirmDeleteMultipleItemsWithFolders": "আপনি কি নিশ্চিত যে আপনি {{count}} আইটেমগুলি স্থায়ীভাবে মুছে ফেলতে চান? এর মধ্যে ফোল্ডার এবং তাদের সামগ্রী অন্তর্ভুক্ত।",
"confirmDeleteFolder": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" ফোল্ডারটি এবং এর সমস্ত বিষয়বস্তু স্থায়ীভাবে মুছে ফেলতে চান?", "confirmDeleteFolder": "আপনি কি নিশ্চিত যে আপনি \"{{name}}\" ফোল্ডারটি এবং এর সমস্ত বিষয়বস্তু স্থায়ীভাবে মুছে ফেলতে চান?",
"deleteDirectoryWarning": "এটি ফোল্ডার এবং এর সমস্ত বিষয়বস্তু মুছে ফেলবে।", "deleteDirectoryWarning": "এটি ফোল্ডার এবং এর সমস্ত বিষয়বস্তু মুছে ফেলবে।",
@@ -1422,7 +1422,7 @@
"openTerminalInFolder": "এই ফোল্ডারে টার্মিনাল খুলুন", "openTerminalInFolder": "এই ফোল্ডারে টার্মিনাল খুলুন",
"openTerminalInFileLocation": "ফাইলের অবস্থানে টার্মিনাল খুলুন", "openTerminalInFileLocation": "ফাইলের অবস্থানে টার্মিনাল খুলুন",
"terminalWithPath": "টার্মিনাল - {{host}}:{{path}}", "terminalWithPath": "টার্মিনাল - {{host}}:{{path}}",
"runningFile": "চলমান - {{file}}", "runningFile": "দৌড়ান - {{file}}",
"onlyRunExecutableFiles": "শুধুমাত্র এক্সিকিউটেবল ফাইল চালানো যাবে", "onlyRunExecutableFiles": "শুধুমাত্র এক্সিকিউটেবল ফাইল চালানো যাবে",
"noHostSelected": "কোনও হোস্ট নির্বাচিত হয়নি", "noHostSelected": "কোনও হোস্ট নির্বাচিত হয়নি",
"starred": "তারকাচিহ্নিত", "starred": "তারকাচিহ্নিত",
@@ -1432,7 +1432,7 @@
"removeFailed": "সরানো ব্যর্থ হয়েছে", "removeFailed": "সরানো ব্যর্থ হয়েছে",
"unpinnedSuccessfully": "\"{{name}}\" সফলভাবে আনপিন করা হয়েছে", "unpinnedSuccessfully": "\"{{name}}\" সফলভাবে আনপিন করা হয়েছে",
"unpinFailed": "আনপিন করা যায়নি", "unpinFailed": "আনপিন করা যায়নি",
"removedShortcut": "\"{{name}}\" শর্টকাটটি সরানো হয়েছে", "removedShortcut": "\"{{name}}\" শর্টকাটটি সরানো হয়েছে",
"removeShortcutFailed": "শর্টকাট সরানো যায়নি", "removeShortcutFailed": "শর্টকাট সরানো যায়নি",
"clearedAllRecentFiles": "সাম্প্রতিক সব ফাইল সাফ করা হয়েছে", "clearedAllRecentFiles": "সাম্প্রতিক সব ফাইল সাফ করা হয়েছে",
"clearFailed": "সাফ করা যায়নি", "clearFailed": "সাফ করা যায়নি",
@@ -1445,11 +1445,11 @@
"addToShortcuts": "শর্টকাটে যোগ করুন", "addToShortcuts": "শর্টকাটে যোগ করুন",
"downloadToDefaultLocation": "ডিফল্ট অবস্থানে ডাউনলোড করুন", "downloadToDefaultLocation": "ডিফল্ট অবস্থানে ডাউনলোড করুন",
"pasteFailed": "আটকানো ব্যর্থ হয়েছে", "pasteFailed": "আটকানো ব্যর্থ হয়েছে",
"noUndoableActions": "কোনও পূর্বাবস্থায় ফেরানো যাবে না", "noUndoableActions": "কোনও পূর্বাবস্থায়ী পদক্ষেপ নেই",
"undoCopySuccess": "কপি করার কাজ বাতিল করা হয়েছে: {{count}} কপি করা ফাইল মুছে ফেলা হয়েছে", "undoCopySuccess": "কপি করার কাজ বাতিল করা হয়েছে: {{count}} কপি করা ফাইল মুছে ফেলা হয়েছে",
"undoCopyFailedDelete": "পূর্বাবস্থায় ফেরানো যায়নি: কোনও কপি করা ফাইল মোছা যায়নি", "undoCopyFailedDelete": "পূর্বাবস্থায় ফেরানো যায়নি: কোনও কপি করা ফাইল মোছা যায়নি",
"undoCopyFailedNoInfo": "পূর্বাবস্থায় ফেরানো যায়নি: কপি করা ফাইলের তথ্য খুঁজে পাওয়া যায়নি", "undoCopyFailedNoInfo": "পূর্বাবস্থায় ফেরানো যায়নি: কপি করা ফাইলের তথ্য খুঁজে পাওয়া যায়নি",
"undoMoveSuccess": "সরানোর কাজটি বাতিল করা হয়েছে: {{count}} ফাইলগুলিকে মূল স্থানে ফিরিয়ে আনা হয়েছে", "undoMoveSuccess": "সরানোর কাজটি পূর্বাবস্থায় ফেরানো হয়েছে: {{count}} ফাইলগুলিকে মূল স্থানে ফিরিয়ে আনা হয়েছে",
"undoMoveFailedMove": "পূর্বাবস্থায় ফেরানো যায়নি: কোনও ফাইল পিছনে সরানো যায়নি", "undoMoveFailedMove": "পূর্বাবস্থায় ফেরানো যায়নি: কোনও ফাইল পিছনে সরানো যায়নি",
"undoMoveFailedNoInfo": "পূর্বাবস্থায় ফেরানো যায়নি: সরানো ফাইলের তথ্য খুঁজে পাওয়া যায়নি", "undoMoveFailedNoInfo": "পূর্বাবস্থায় ফেরানো যায়নি: সরানো ফাইলের তথ্য খুঁজে পাওয়া যায়নি",
"undoDeleteNotSupported": "মুছে ফেলার কাজটি পূর্বাবস্থায় ফেরানো যাবে না: সার্ভার থেকে ফাইলগুলি স্থায়ীভাবে মুছে ফেলা হয়েছে", "undoDeleteNotSupported": "মুছে ফেলার কাজটি পূর্বাবস্থায় ফেরানো যাবে না: সার্ভার থেকে ফাইলগুলি স্থায়ীভাবে মুছে ফেলা হয়েছে",
@@ -1491,36 +1491,36 @@
"unknownSize": "অজানা আকার", "unknownSize": "অজানা আকার",
"fileIsEmpty": "ফাইল খালি।", "fileIsEmpty": "ফাইল খালি।",
"largeFileWarning": "বড় ফাইলের সতর্কতা", "largeFileWarning": "বড় ফাইলের সতর্কতা",
"largeFileWarningDesc": "এই ফাইলটির আকার {{size}}, যা টেক্সট হিসেবে খোলার সময় পারফরম্যান্সের সমস্যা তৈরি করতে পারে।", "largeFileWarningDesc": "এই ফাইলটি {{size}} আকারের, যা টেক্সট হিসেবে খোলার সময় কর্মক্ষমতা সংক্রান্ত সমস্যা সৃষ্টি করতে পারে।",
"fileNotFoundAndRemoved": "\"{{name}}\" ফাইলটি পাওয়া যায়নি এবং সাম্প্রতিক/পিন করা ফাইলগুলি থেকে সরানো হয়েছে", "fileNotFoundAndRemoved": "\"{{name}}\" ফাইলটি পাওয়া যায়নি এবং সাম্প্রতিক/পিন করা ফাইলগুলি থেকে সরানো হয়েছে",
"failedToLoadFile": "ফাইল লোড করতে ব্যর্থ: {{error}}", "failedToLoadFile": "ফাইল লোড করতে ব্যর্থ: {{error}}",
"serverErrorOccurred": "সার্ভার ত্রুটি ঘটেছে। অনুগ্রহ করে পরে আবার চেষ্টা করুন।", "serverErrorOccurred": "সার্ভার ত্রুটি ঘটেছে। অনুগ্রহ করে পরে আবার চেষ্টা করুন।",
"autoSaveFailed": "অটো-সেভ ব্যর্থ হয়েছে", "autoSaveFailed": "অটো-সেভ ব্যর্থ হয়েছে",
"fileAutoSaved": "ফাইল স্বয়ংক্রিয়ভাবে সংরক্ষিত হয়েছে", "fileAutoSaved": "ফাইল স্বয়ংক্রিয়ভাবে সংরক্ষিত হয়েছে",
"moveFileFailed": "{{name}} সরানো যায়নি", "moveFileFailed": "সরানো যায়নি {{name}}",
"moveOperationFailed": "সরানোর কাজ ব্যর্থ হয়েছে", "moveOperationFailed": "সরানোর কাজ ব্যর্থ হয়েছে",
"canOnlyCompareFiles": "শুধুমাত্র দুটি ফাইলের তুলনা করা যাবে", "canOnlyCompareFiles": "শুধুমাত্র দুটি ফাইলের তুলনা করা যাবে",
"comparingFiles": "ফাইলগুলির তুলনা: {{file1}} এবং {{file2}}", "comparingFiles": "ফাইল তুলনা করা হচ্ছে: {{file1}} এবং {{file2}}",
"dragFailed": "টেনে আনার কাজ ব্যর্থ হয়েছে", "dragFailed": "টেনে আনার কাজ ব্যর্থ হয়েছে",
"filePinnedSuccessfully": "\"{{name}}}\" ফাইলটি সফলভাবে পিন করা হয়েছে", "filePinnedSuccessfully": "\"{{name}}\" ফাইলটি সফলভাবে পিন করা হয়েছে",
"pinFileFailed": "ফাইল পিন করা যায়নি", "pinFileFailed": "ফাইল পিন করা যায়নি",
"fileUnpinnedSuccessfully": "\"{{name}}}\" ফাইলটি সফলভাবে আনপিন করা হয়েছে", "fileUnpinnedSuccessfully": "\"{{name}}\" ফাইলটি সফলভাবে আনপিন করা হয়েছে",
"unpinFileFailed": "ফাইল আনপিন করা যায়নি", "unpinFileFailed": "ফাইল আনপিন করা যায়নি",
"shortcutAddedSuccessfully": "ফোল্ডার শর্টকাট \"{{name}}\" সফলভাবে যোগ করা হয়েছে", "shortcutAddedSuccessfully": "\"{{name}}\" ফোল্ডারের শর্টকাট সফলভাবে যোগ করা হয়েছে",
"addShortcutFailed": "শর্টকাট যোগ করা যায়নি", "addShortcutFailed": "শর্টকাট যোগ করা যায়নি",
"operationCompletedSuccessfully": "{{operation}} {{count}}টি আইটেম সফলভাবে সংগ্রহ করা হয়েছে", "operationCompletedSuccessfully": "{{operation}} {{count}} আইটেমগুলি সফলভাবে",
"operationCompleted": "{{operation}} {{count}} আইটেম", "operationCompleted": "{{operation}} {{count}} আইটেম",
"downloadFileSuccess": "{{name}} ফাইলটি সফলভাবে ডাউনলোড করা হয়েছে", "downloadFileSuccess": "{{name}} ফাইলটি সফলভাবে ডাউনলোড করা হয়েছে",
"downloadFileFailed": "ডাউনলোড ব্যর্থ হয়েছে", "downloadFileFailed": "ডাউনলোড ব্যর্থ হয়েছে",
"moveTo": "{{name}} এ যান", "moveTo": "{{name}}এ যান",
"diffCompareWith": "{{name}} এর সাথে পার্থক্য তুলনা করুন", "diffCompareWith": "{{name}}এর সাথে পার্থক্য তুলনা করুন",
"dragOutsideToDownload": "({{count}} ফাইল) ডাউনলোড করতে উইন্ডোর বাইরে টেনে আনুন", "dragOutsideToDownload": "({{count}} ফাইল) ডাউনলোড করতে উইন্ডোর বাইরে টেনে আনুন",
"newFolderDefault": "নতুন ফোল্ডার", "newFolderDefault": "নতুন ফোল্ডার",
"newFileDefault": "নতুন ফাইল.টেক্সট", "newFileDefault": "নতুন ফাইল.টেক্সট",
"successfullyMovedItems": "{{count}} টি আইটেম সফলভাবে {{target}} এ সরানো হয়েছে", "successfullyMovedItems": "{{count}} আইটেমগুলিকে {{target}}এ সফলভাবে সরানো হয়েছে",
"move": "সরান", "move": "সরান",
"searchInFile": "ফাইলে অনুসন্ধান করুন (Ctrl+F)", "searchInFile": "ফাইলে অনুসন্ধান করুন (Ctrl+F)",
"showKeyboardShortcuts": "কীবোর্ড শর্টকাটগুলি দেখান", "showKeyboardShortcuts": "কীবোর্ড শর্টকাট দেখান",
"startWritingMarkdown": "তোমার মার্কডাউন কন্টেন্ট লেখা শুরু করো...", "startWritingMarkdown": "তোমার মার্কডাউন কন্টেন্ট লেখা শুরু করো...",
"loadingFileComparison": "ফাইল তুলনা লোড হচ্ছে...", "loadingFileComparison": "ফাইল তুলনা লোড হচ্ছে...",
"reload": "পুনরায় লোড করুন", "reload": "পুনরায় লোড করুন",
@@ -1529,7 +1529,7 @@
"inline": "ইনলাইন", "inline": "ইনলাইন",
"fileComparison": "ফাইল তুলনা: {{file1}} বনাম {{file2}}", "fileComparison": "ফাইল তুলনা: {{file1}} বনাম {{file2}}",
"fileTooLarge": "ফাইলটি খুব বড়: {{error}}", "fileTooLarge": "ফাইলটি খুব বড়: {{error}}",
"sshConnectionFailed": "SSH সংযোগ ব্যর্থ হয়েছে। অনুগ্রহ করে {{name}} ({{ip}}:{{port}}) এ আপনার সংযোগ পরীক্ষা করুন।", "sshConnectionFailed": "SSH সংযোগ ব্যর্থ হয়েছে। অনুগ্রহ করে আপনার সংযোগ {{name}} ({{ip}}:{{port}}) এ পরীক্ষা করুন।",
"loadFileFailed": "ফাইল লোড করতে ব্যর্থ: {{error}}", "loadFileFailed": "ফাইল লোড করতে ব্যর্থ: {{error}}",
"connectedSuccessfully": "সফলভাবে সংযুক্ত হয়েছে", "connectedSuccessfully": "সফলভাবে সংযুক্ত হয়েছে",
"totpVerificationFailed": "TOTP যাচাইকরণ ব্যর্থ হয়েছে", "totpVerificationFailed": "TOTP যাচাইকরণ ব্যর্থ হয়েছে",
@@ -1573,10 +1573,10 @@
"disconnect": "সংযোগ বিচ্ছিন্ন করুন", "disconnect": "সংযোগ বিচ্ছিন্ন করুন",
"cancel": "বাতিল করুন", "cancel": "বাতিল করুন",
"port": "বন্দর", "port": "বন্দর",
"attempt": "{{current}} এর {{max}} প্রচেষ্টা", "attempt": "{{current}} এর {{max}}প্রচেষ্টা",
"nextRetryIn": "পরবর্তী চেষ্টা {{seconds}} সেকেন্ডের মধ্যে", "nextRetryIn": "পরবর্তী চেষ্টা {{seconds}} সেকেন্ডের মধ্যে",
"checkDockerLogs": "ত্রুটির কারণে আপনার ডকার লগগুলি পরীক্ষা করুন, যোগদান করুন", "checkDockerLogs": "ত্রুটির কারণের জন্য আপনার ডকার লগগুলি পরীক্ষা করুন, যোগদান করুন",
"orCreate": "অথবা একটি তৈরি করুন", "orCreate": "অথবা একটি তৈরি করুন ",
"noTunnelConnections": "কোনও টানেল সংযোগ কনফিগার করা হয়নি", "noTunnelConnections": "কোনও টানেল সংযোগ কনফিগার করা হয়নি",
"tunnelConnections": "টানেল সংযোগ", "tunnelConnections": "টানেল সংযোগ",
"addTunnel": "টানেল যোগ করুন", "addTunnel": "টানেল যোগ করুন",
@@ -1650,7 +1650,7 @@
"totpInvalidCode": "অবৈধ যাচাইকরণ কোড", "totpInvalidCode": "অবৈধ যাচাইকরণ কোড",
"totpCancelled": "মেট্রিক্স সংগ্রহ বাতিল করা হয়েছে", "totpCancelled": "মেট্রিক্স সংগ্রহ বাতিল করা হয়েছে",
"authenticationFailed": "প্রমাণীকরণ ব্যর্থ হয়েছে", "authenticationFailed": "প্রমাণীকরণ ব্যর্থ হয়েছে",
"noneAuthNotSupported": "সার্ভার পরিসংখ্যা 'কিছুই নয়' প্রমাণীকরণ প্রকার সমর্থন করে না।", "noneAuthNotSupported": "সার্ভার স্ট্যাটস 'কিছুই নয়' প্রমাণীকরণ প্রকার সমর্থন করে না।",
"load": "লোড", "load": "লোড",
"editLayout": "লেআউট সম্পাদনা করুন", "editLayout": "লেআউট সম্পাদনা করুন",
"cancelEdit": "বাতিল করুন", "cancelEdit": "বাতিল করুন",
@@ -1678,11 +1678,11 @@
"noRecentLoginData": "কোনও সাম্প্রতিক লগইন ডেটা নেই", "noRecentLoginData": "কোনও সাম্প্রতিক লগইন ডেটা নেই",
"from": "থেকে", "from": "থেকে",
"quickActions": "দ্রুত পদক্ষেপ", "quickActions": "দ্রুত পদক্ষেপ",
"executeQuickAction": "{{name}} কার্যকর করুন", "executeQuickAction": "কার্যকর করুন {{name}}",
"executingQuickAction": "{{name}} কার্যকর করা হচ্ছে...", "executingQuickAction": "কার্যকর করা হচ্ছে {{name}}...",
"quickActionSuccess": "{{name}} সফলভাবে সম্পন্ন হয়েছে", "quickActionSuccess": "{{name}} সফলভাবে সম্পন্ন হয়েছে",
"quickActionFailed": "{{name}} ব্যর্থ হয়েছে", "quickActionFailed": "{{name}} ব্যর্থ হয়েছে",
"quickActionError": "{{name}} কার্যকর করা যায়নি" "quickActionError": "{{name}}চালানো যায়নি"
}, },
"auth": { "auth": {
"tagline": "SSH সার্ভার ম্যানেজার", "tagline": "SSH সার্ভার ম্যানেজার",
@@ -1696,7 +1696,7 @@
"registerButton": "নিবন্ধন", "registerButton": "নিবন্ধন",
"forgotPassword": "পাসওয়ার্ড ভুলে গেছেন?", "forgotPassword": "পাসওয়ার্ড ভুলে গেছেন?",
"rememberMe": "আমাকে মনে রেখো", "rememberMe": "আমাকে মনে রেখো",
"noAccount": "আপনার কি কোন অ্যাকাউন্ট নেই?", "noAccount": "কোন অ্যাকাউন্ট নেই?",
"hasAccount": "ইতিমধ্যে একটি অ্যাকাউন্ট আছে?", "hasAccount": "ইতিমধ্যে একটি অ্যাকাউন্ট আছে?",
"loginSuccess": "লগইন সফল হয়েছে", "loginSuccess": "লগইন সফল হয়েছে",
"loginFailed": "লগইন ব্যর্থ হয়েছে", "loginFailed": "লগইন ব্যর্থ হয়েছে",
@@ -1800,7 +1800,7 @@
"forbidden": "অ্যাক্সেস নিষিদ্ধ", "forbidden": "অ্যাক্সেস নিষিদ্ধ",
"serverError": "সার্ভার ত্রুটি", "serverError": "সার্ভার ত্রুটি",
"networkError": "নেটওয়ার্ক ত্রুটি", "networkError": "নেটওয়ার্ক ত্রুটি",
"databaseConnection": "ডাটাবেসের সাথে সংযোগ করা যায়নি।", "databaseConnection": "ডাটাবেসের সাথে সংযোগ স্থাপন করা যায়নি।",
"unknownError": "অজানা ত্রুটি", "unknownError": "অজানা ত্রুটি",
"loginFailed": "লগইন ব্যর্থ হয়েছে", "loginFailed": "লগইন ব্যর্থ হয়েছে",
"failedPasswordReset": "পাসওয়ার্ড রিসেট শুরু করা যায়নি", "failedPasswordReset": "পাসওয়ার্ড রিসেট শুরু করা যায়নি",
@@ -1811,11 +1811,11 @@
"failedUserInfo": "OIDC লগইন করার পরে ব্যবহারকারীর তথ্য পেতে ব্যর্থ হয়েছে।", "failedUserInfo": "OIDC লগইন করার পরে ব্যবহারকারীর তথ্য পেতে ব্যর্থ হয়েছে।",
"oidcAuthFailed": "OIDC প্রমাণীকরণ ব্যর্থ হয়েছে", "oidcAuthFailed": "OIDC প্রমাণীকরণ ব্যর্থ হয়েছে",
"noTokenReceived": "লগইন থেকে কোনও টোকেন পাওয়া যায়নি", "noTokenReceived": "লগইন থেকে কোনও টোকেন পাওয়া যায়নি",
"invalidAuthUrl": "ব্যাকএন্ড থেকে অবৈধ অনুমোদন URL প্রাপ্ত হয়েছে", "invalidAuthUrl": "ব্যাকএন্ড থেকে অবৈধ অনুমোদনের URL পাওয়া গেছে",
"invalidInput": "অবৈধ ইনপুট", "invalidInput": "অবৈধ ইনপুট",
"requiredField": "এই ক্ষেত্রটি আবশ্যক", "requiredField": "এই ক্ষেত্রটি আবশ্যক",
"minLength": "সর্বনিম্ন দৈর্ঘ্য {{min}}", "minLength": "সর্বনিম্ন দৈর্ঘ্য হল {{min}}",
"maxLength": "সর্বোচ্চ দৈর্ঘ্য {{max}}", "maxLength": "সর্বোচ্চ দৈর্ঘ্য হল {{max}}",
"invalidEmail": "অবৈধ ইমেল ঠিকানা", "invalidEmail": "অবৈধ ইমেল ঠিকানা",
"passwordMismatch": "পাসওয়ার্ড মিলছে না।", "passwordMismatch": "পাসওয়ার্ড মিলছে না।",
"passwordLoginDisabled": "ব্যবহারকারীর নাম/পাসওয়ার্ড লগইন বর্তমানে অক্ষম করা আছে।", "passwordLoginDisabled": "ব্যবহারকারীর নাম/পাসওয়ার্ড লগইন বর্তমানে অক্ষম করা আছে।",
@@ -1865,7 +1865,7 @@
"local": "স্থানীয়", "local": "স্থানীয়",
"external": "বাহ্যিক (OIDC)", "external": "বাহ্যিক (OIDC)",
"externalAndLocal": "দ্বৈত প্রমাণীকরণ", "externalAndLocal": "দ্বৈত প্রমাণীকরণ",
"selectPreferredLanguage": "ইন্টারফেসের জন্য আপনার পছন্দের ভাষা নির্বাচন করুন", "selectPreferredLanguage": "ইন্টারফেসের জন্য আপনার পছন্দের ভাষা নির্বাচন করুন",
"fileColorCoding": "ফাইলের রঙ কোডিং", "fileColorCoding": "ফাইলের রঙ কোডিং",
"fileColorCodingDesc": "প্রকার অনুসারে রঙ-কোড ফাইল: ফোল্ডার (লাল), ফাইল (নীল), সিমলিঙ্ক (সবুজ)", "fileColorCodingDesc": "প্রকার অনুসারে রঙ-কোড ফাইল: ফোল্ডার (লাল), ফাইল (নীল), সিমলিঙ্ক (সবুজ)",
"commandAutocomplete": "কমান্ড স্বয়ংসম্পূর্ণ", "commandAutocomplete": "কমান্ড স্বয়ংসম্পূর্ণ",
@@ -1942,7 +1942,7 @@
"socks5Username": "প্রক্সি ব্যবহারকারীর নাম", "socks5Username": "প্রক্সি ব্যবহারকারীর নাম",
"socks5Password": "প্রক্সি পাসওয়ার্ড", "socks5Password": "প্রক্সি পাসওয়ার্ড",
"socks5PresetName": "যেমন, ওয়ার্ক ভিপিএন চেইন", "socks5PresetName": "যেমন, ওয়ার্ক ভিপিএন চেইন",
"socks5PresetDescription": "উদাহরণস্বরূপ, কাজের সার্ভার অ্যাক্সেস করার জন্য প্রক্সি চেইন", "socks5PresetDescription": "যেমন, কাজের সার্ভার অ্যাক্সেস করার জন্য প্রক্সি চেইন",
"moshCommand": "মোশ ইউজার@সার্ভার", "moshCommand": "মোশ ইউজার@সার্ভার",
"defaultPort": "২২", "defaultPort": "২২",
"defaultEndpointPort": "২২৪", "defaultEndpointPort": "২২৪",
@@ -1955,16 +1955,16 @@
"passwordRequired": "পাসওয়ার্ড প্রয়োজন।", "passwordRequired": "পাসওয়ার্ড প্রয়োজন।",
"failedToDeleteAccount": "অ্যাকাউন্ট মুছে ফেলা যায়নি", "failedToDeleteAccount": "অ্যাকাউন্ট মুছে ফেলা যায়নি",
"failedToMakeUserAdmin": "ব্যবহারকারীকে প্রশাসক করা যায়নি", "failedToMakeUserAdmin": "ব্যবহারকারীকে প্রশাসক করা যায়নি",
"userIsNowAdmin": "ব্যবহারকারী {{username}} এখন একজন প্রশাসক", "userIsNowAdmin": "ব্যবহারকারী {{username}} এখন একজন অ্যাডমিন",
"removeAdminConfirm": "আপনি কি নিশ্চিত যে আপনি {{username}} থেকে অ্যাডমিন স্ট্যাটাসটি সরাতে চান?", "removeAdminConfirm": "আপনি কি নিশ্চিত যে আপনি {{username}}থেকে অ্যাডমিন স্ট্যাটাসটি সরাতে চান?",
"deleteUserConfirm": "আপনি কি নিশ্চিত যে আপনি {{username}} ব্যবহারকারী মুছে ফেলতে চান? এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।", "deleteUserConfirm": "আপনি কি নিশ্চিত যে আপনি ব্যবহারকারী {{username}}মুছে ফেলতে চান? এই ক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না।",
"deleteAccount": "অ্যাকাউন্ট মুছুন", "deleteAccount": "অ্যাকাউন্ট মুছুন",
"closeDeleteAccount": "অ্যাকাউন্ট মুছুন বন্ধ করুন", "closeDeleteAccount": "অ্যাকাউন্ট মুছুন বন্ধ করুন",
"deleteAccountWarning": "এই কাজটি পূর্বাবস্থায় ফেরানো যাবে না। এটি আপনার অ্যাকাউন্ট এবং এর সাথে সম্পর্কিত সমস্ত ডেটা স্থায়ীভাবে মুছে ফেলবে।", "deleteAccountWarning": "এই কাজটি পূর্বাবস্থায় ফেরানো যাবে না। এটি আপনার অ্যাকাউন্ট এবং এর সাথে সম্পর্কিত সমস্ত ডেটা স্থায়ীভাবে মুছে ফেলবে।",
"deleteAccountWarningDetails": "আপনার অ্যাকাউন্ট মুছে ফেললে SSH হোস্ট, কনফিগারেশন এবং সেটিংস সহ আপনার সমস্ত ডেটা মুছে যাবে। এই পদক্ষেপটি অপরিবর্তনীয়।", "deleteAccountWarningDetails": "আপনার অ্যাকাউন্ট মুছে ফেললে SSH হোস্ট, কনফিগারেশন এবং সেটিংস সহ আপনার সমস্ত ডেটা মুছে যাবে। এই পদক্ষেপটি অপরিবর্তনীয়।",
"deleteAccountWarningShort": "এই ক্রিয়াটি আর উল্টানো যাবে না এবং আপনার অ্যাকাউন্ট স্থায়ীভাবে মুছে ফেলা হবে।", "deleteAccountWarningShort": "এই ক্রিয়াটি আর উল্টানো যাবে না এবং আপনার অ্যাকাউন্ট স্থায়ীভাবে মুছে যাবে।",
"cannotDeleteAccount": "অ্যাকাউন্ট মুছে ফেলা যাচ্ছে না", "cannotDeleteAccount": "অ্যাকাউন্ট মুছে ফেলা যাচ্ছে না",
"lastAdminWarning": "আপনিই শেষ অ্যাডমিন ব্যবহারকারী। আপনি আপনার অ্যাকাউন্ট মুছে ফেলতে পারবেন না কারণ এতে সিস্টেমে কোনও অ্যাডমিনিস্ট্রেটর থাকবে না। অনুগ্রহ করে প্রথমে অন্য একজন ব্যবহারকারীকে অ্যাডমিন করুন, অথবা সিস্টেম সাপোর্টের সাথে যোগাযোগ করুন।", "lastAdminWarning": "আপনিই শেষ অ্যাডমিন ব্যবহারকারী। আপনি আপনার অ্যাকাউন্ট মুছে ফেলতে পারবেন না কারণ এটি সিস্টেমে কোনও অ্যাডমিনিস্ট্রেটর ছাড়াই ছেড়ে দেবে। অনুগ্রহ করে প্রথমে অন্য একজন ব্যবহারকারীকে অ্যাডমিন করুন, অথবা সিস্টেম সহায়তার সাথে যোগাযোগ করুন।",
"confirmPassword": "পাসওয়ার্ড নিশ্চিত করুন", "confirmPassword": "পাসওয়ার্ড নিশ্চিত করুন",
"deleting": "মুছে ফেলা হচ্ছে...", "deleting": "মুছে ফেলা হচ্ছে...",
"cancel": "বাতিল করুন" "cancel": "বাতিল করুন"
@@ -2149,12 +2149,12 @@
"lastAccessed": "শেষবার অ্যাক্সেস করা হয়েছে", "lastAccessed": "শেষবার অ্যাক্সেস করা হয়েছে",
"accessCount": "অ্যাক্সেসের সংখ্যা", "accessCount": "অ্যাক্সেসের সংখ্যা",
"revokeAccess": "অ্যাক্সেস প্রত্যাহার করুন", "revokeAccess": "অ্যাক্সেস প্রত্যাহার করুন",
"confirmRevokeAccess": "আপনি কি নিশ্চিত যে আপনি {{username}} এর অ্যাক্সেস প্রত্যাহার করতে চান?", "confirmRevokeAccess": "আপনি কি নিশ্চিত যে আপনি {{username}}এর অ্যাক্সেস প্রত্যাহার করতে চান?",
"hostSharedSuccessfully": "হোস্টটি {{username}} এর সাথে সফলভাবে শেয়ার করা হয়েছে", "hostSharedSuccessfully": "হোস্ট {{username}}এর সাথে সফলভাবে শেয়ার করা হয়েছে",
"hostAccessUpdated": "হোস্ট অ্যাক্সেস আপডেট করা হয়েছে", "hostAccessUpdated": "হোস্ট অ্যাক্সেস আপডেট করা হয়েছে",
"failedToShareHost": "হোস্ট শেয়ার করতে ব্যর্থ হয়েছে", "failedToShareHost": "হোস্ট শেয়ার করতে ব্যর্থ হয়েছে",
"accessRevokedSuccessfully": "অ্যাক্সেস সফলভাবে প্রত্যাহার করা হয়েছে", "accessRevokedSuccessfully": "অ্যাক্সেস সফলভাবে প্রত্যাহার করা হয়েছে",
"failedToRevokeAccess": "অ্যাক্সেস প্রত্যাহার করা যায়নি", "failedToRevokeAccess": "অ্যাক্সেস প্রত্যাহার করা যায়নিfdfg",
"shared": "ভাগ করা হয়েছে", "shared": "ভাগ করা হয়েছে",
"sharedHosts": "শেয়ার্ড হোস্ট", "sharedHosts": "শেয়ার্ড হোস্ট",
"sharedWithMe": "আমার সাথে শেয়ার করা হয়েছে", "sharedWithMe": "আমার সাথে শেয়ার করা হয়েছে",
@@ -2167,8 +2167,8 @@
"manageAccessFor": "এর জন্য অ্যাক্সেস পরিচালনা করুন", "manageAccessFor": "এর জন্য অ্যাক্সেস পরিচালনা করুন",
"totalAccessRecords": "{{count}} অ্যাক্সেস রেকর্ড(গুলি)", "totalAccessRecords": "{{count}} অ্যাক্সেস রেকর্ড(গুলি)",
"neverAccessed": "কখনোই না", "neverAccessed": "কখনোই না",
"timesAccessed": "{{count}} বার", "timesAccessed": "{{count}} সময়(গুলি)",
"daysRemaining": "{{days}} দিন", "daysRemaining": "{{days}} দিন(গুলি)",
"hoursRemaining": "{{hours}} ঘন্টা", "hoursRemaining": "{{hours}} ঘন্টা",
"failedToFetchAccessList": "অ্যাক্সেস তালিকা আনা যায়নি", "failedToFetchAccessList": "অ্যাক্সেস তালিকা আনা যায়নি",
"currentAccess": "বর্তমান অ্যাক্সেস", "currentAccess": "বর্তমান অ্যাক্সেস",
@@ -2177,7 +2177,7 @@
"tempUserRecommended": "উন্নত নিরাপত্তার জন্য আমরা 'অস্থায়ী ব্যবহারকারী তৈরি করুন' সক্ষম করার পরামর্শ দিচ্ছি।", "tempUserRecommended": "উন্নত নিরাপত্তার জন্য আমরা 'অস্থায়ী ব্যবহারকারী তৈরি করুন' সক্ষম করার পরামর্শ দিচ্ছি।",
"roleManagement": "ভূমিকা ব্যবস্থাপনা", "roleManagement": "ভূমিকা ব্যবস্থাপনা",
"manageRoles": "ভূমিকা পরিচালনা করুন", "manageRoles": "ভূমিকা পরিচালনা করুন",
"manageRolesFor": "{{username}} এর জন্য ভূমিকা পরিচালনা করুন", "manageRolesFor": "{{username}}এর জন্য ভূমিকা পরিচালনা করুন",
"assignRole": "ভূমিকা বরাদ্দ করুন", "assignRole": "ভূমিকা বরাদ্দ করুন",
"removeRole": "ভূমিকা সরান", "removeRole": "ভূমিকা সরান",
"userRoles": "ব্যবহারকারীর ভূমিকা", "userRoles": "ব্যবহারকারীর ভূমিকা",
@@ -2211,10 +2211,10 @@
"downloadRecording": "রেকর্ডিং ডাউনলোড করুন", "downloadRecording": "রেকর্ডিং ডাউনলোড করুন",
"dangerousCommand": "বিপজ্জনক কমান্ড সনাক্ত করা হয়েছে", "dangerousCommand": "বিপজ্জনক কমান্ড সনাক্ত করা হয়েছে",
"commandBlocked": "কমান্ড ব্লক করা হয়েছে", "commandBlocked": "কমান্ড ব্লক করা হয়েছে",
"terminateSession": "সেশন বন্ধ করুন", "terminateSession": "সেশন শেষ করুন",
"sessionTerminated": "হোস্ট মালিক সেশনটি সমাপ্ত করেছেন", "sessionTerminated": "হোস্ট মালিক সেশনটি বন্ধ করে দিয়েছেন",
"sharedAccessExpired": "এই হোস্টে আপনার শেয়ার করা অ্যাক্সেসের মেয়াদ শেষ হয়ে গেছে", "sharedAccessExpired": "এই হোস্টে আপনার শেয়ার করা অ্যাক্সেসের মেয়াদ শেষ হয়ে গেছে",
"sharedAccessExpiresIn": "শেয়ার করা অ্যাক্সেসের মেয়াদ {{hours}} ঘন্টার মধ্যে শেষ হয়ে যাবে", "sharedAccessExpiresIn": "শেয়ার করা অ্যাক্সেসের মেয়াদ {{hours}} ঘন্টার মধ্যে শেষ হবে",
"roles": { "roles": {
"label": "ভূমিকা", "label": "ভূমিকা",
"admin": "প্রশাসক", "admin": "প্রশাসক",
@@ -2310,16 +2310,16 @@
"errorCode": "ত্রুটি কোড: {{code}}", "errorCode": "ত্রুটি কোড: {{code}}",
"version": "ডকার {{version}}", "version": "ডকার {{version}}",
"containerStarted": "কন্টেইনার {{name}} শুরু হয়েছে", "containerStarted": "কন্টেইনার {{name}} শুরু হয়েছে",
"failedToStartContainer": "{{name}} কন্টেইনারটি চালু করতে ব্যর্থ হয়েছে", "failedToStartContainer": "কন্টেইনার চালু করতে ব্যর্থ হয়েছে {{name}}",
"containerStopped": "{{name}} ন্টেইনার থামানো হয়েছে", "containerStopped": "কন্টেইনার {{name}} ন্ধ করা হয়েছে",
"failedToStopContainer": "কন্টেইনার থামাতে ব্যর্থ হয়েছে {{name}}", "failedToStopContainer": "কন্টেইনার থামাতে ব্যর্থ হয়েছে {{name}}",
"containerRestarted": "কন্টেইনার {{name}} পুনরায় চালু হয়েছে", "containerRestarted": "কন্টেইনার {{name}} পুনরায় চালু হয়েছে",
"failedToRestartContainer": "{{name}} কন্টেইনারটি পুনরায় চালু করতে ব্যর্থ হয়েছে", "failedToRestartContainer": "কন্টেইনারটি পুনরায় চালু করতে ব্যর্থ হয়েছে {{name}}",
"containerPaused": "{{name}} কন্টেইনার থামানো হয়েছে", "containerPaused": "কন্টেইনার {{name}} থামানো হয়েছে",
"containerUnpaused": "{{name}} কন্টেইনারটি আনপজ করা হয়েছে", "containerUnpaused": "কন্টেইনার {{name}} অব্যবহৃত",
"failedToTogglePauseContainer": "{{name}} কন্টেইনারের জন্য পজ স্ট্যাটাস টগল করা যায়নি", "failedToTogglePauseContainer": "কন্টেইনারের জন্য পজ স্ট্যাটাস টগল করা যায়নি {{name}}",
"containerRemoved": "{{name}} কন্টেইনার সরানো হয়েছে", "containerRemoved": "কন্টেইনার {{name}} সরানো হয়েছে",
"failedToRemoveContainer": "{{name}} কন্টেইনার সরানো যায়নি", "failedToRemoveContainer": "কন্টেইনার সরানো যায়নি {{name}}",
"image": "ভাবমূর্তি", "image": "ভাবমূর্তি",
"idLabel": "আইডি", "idLabel": "আইডি",
"ports": "বন্দর", "ports": "বন্দর",
@@ -2372,7 +2372,7 @@
"authenticationRequired": "প্রমাণীকরণ প্রয়োজন", "authenticationRequired": "প্রমাণীকরণ প্রয়োজন",
"verificationCodePrompt": "যাচাইকরণ কোড লিখুন", "verificationCodePrompt": "যাচাইকরণ কোড লিখুন",
"totpVerificationFailed": "TOTP যাচাইকরণ ব্যর্থ হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।", "totpVerificationFailed": "TOTP যাচাইকরণ ব্যর্থ হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।",
"connectedTo": "{{containerName}} এর সাথে সংযুক্ত", "connectedTo": "{{containerName}}এর সাথে সংযুক্ত",
"disconnected": "সংযোগ বিচ্ছিন্ন", "disconnected": "সংযোগ বিচ্ছিন্ন",
"consoleError": "কনসোল ত্রুটি", "consoleError": "কনসোল ত্রুটি",
"errorMessage": "ত্রুটি: {{message}}", "errorMessage": "ত্রুটি: {{message}}",
@@ -2387,7 +2387,7 @@
"disconnect": "সংযোগ বিচ্ছিন্ন করুন", "disconnect": "সংযোগ বিচ্ছিন্ন করুন",
"notConnected": "সংযুক্ত নেই", "notConnected": "সংযুক্ত নেই",
"clickToConnect": "শেল সেশন শুরু করতে সংযোগে ক্লিক করুন", "clickToConnect": "শেল সেশন শুরু করতে সংযোগে ক্লিক করুন",
"connectingTo": "{{containerName}} এর সাথে সংযোগ করা হচ্ছে...", "connectingTo": "{{containerName}}এর সাথে সংযুক্ত হচ্ছে ...",
"containerNotFound": "কন্টেইনারটি পাওয়া যায়নি", "containerNotFound": "কন্টেইনারটি পাওয়া যায়নি",
"backToList": "তালিকায় ফিরে যান", "backToList": "তালিকায় ফিরে যান",
"logs": "লগ", "logs": "লগ",
@@ -2397,6 +2397,6 @@
}, },
"theme": { "theme": {
"switchToLight": "আলোতে স্যুইচ করুন", "switchToLight": "আলোতে স্যুইচ করুন",
"switchToDark": "ডার্ক এ স্যুইচ করুন" "switchToDark": "ডার্ক-এ স্যুইচ করুন"
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -39,7 +39,7 @@
"noCredentials": "אין אישורים", "noCredentials": "אין אישורים",
"noCredentialsMessage": "עדיין לא הוספת אישורים. לחץ על \"הוסף אישור\" כדי להתחיל.", "noCredentialsMessage": "עדיין לא הוספת אישורים. לחץ על \"הוסף אישור\" כדי להתחיל.",
"sshCredentials": "אישורי SSH", "sshCredentials": "אישורי SSH",
"credentialsCount": "פרטי גישה של {{count}}", "credentialsCount": "אישורים {{count}}",
"refresh": "לְרַעֲנֵן", "refresh": "לְרַעֲנֵן",
"passwordRequired": "נדרשת סיסמה", "passwordRequired": "נדרשת סיסמה",
"sshKeyRequired": "נדרש מפתח SSH", "sshKeyRequired": "נדרש מפתח SSH",
@@ -136,12 +136,12 @@
"listView": "רְשִׁימָה", "listView": "רְשִׁימָה",
"folderView": "תיקיות", "folderView": "תיקיות",
"unknownCredential": "לֹא יְדוּעַ", "unknownCredential": "לֹא יְדוּעַ",
"confirmRemoveFromFolder": "האם אתה בטוח שברצונך להסיר את \"{{name}}\" מהתיקייה \"{{folder}}\"? פרטי הגישה יועברו לתיקייה \"לא מסווג\".", "confirmRemoveFromFolder": "האם אתה בטוח שברצונך להסיר את \"{{name}}\" מהתיקייה \"{{folder}}\"? פרטי הכניסה יועברו לקטגוריה \"לא מסווג\".",
"removedFromFolder": "פרטי הכניסה \"{{name}}\" הוסרו בהצלחה מהתיקייה", "removedFromFolder": "פרטי הכניסה \"{{name}}\" הוסרו בהצלחה מהתיקייה",
"failedToRemoveFromFolder": "הסרת האישורים מהתיקייה נכשלה", "failedToRemoveFromFolder": "הסרת האישורים מהתיקייה נכשלה",
"folderRenamed": "שם התיקייה \"{{oldName}}\" שונה בהצלחה ל-\"{{newName}}\"", "folderRenamed": "תיקיית \"{{oldName}}\" שמה שונה בהצלחה ל- \"{{newName}}\"",
"failedToRenameFolder": "נכשל שינוי שם התיקייה", "failedToRenameFolder": "נכשל שינוי שם התיקייה",
"movedToFolder": "פרטי הכניסה \"{{name}}\" הועברו בהצלחה ל-\"{{folder}}\"", "movedToFolder": "פרטי הכניסה \"{{name}}\" הועברו בהצלחה ל- \"{{folder}}\"",
"failedToMoveToFolder": "העברת האישורים לתיקייה נכשלה", "failedToMoveToFolder": "העברת האישורים לתיקייה נכשלה",
"sshPublicKey": "מפתח ציבורי של SSH", "sshPublicKey": "מפתח ציבורי של SSH",
"publicKeyNote": "מפתח ציבורי הוא אופציונלי אך מומלץ לאימות מפתח", "publicKeyNote": "מפתח ציבורי הוא אופציונלי אך מומלץ לאימות מפתח",
@@ -187,9 +187,9 @@
"dragIndicator": { "dragIndicator": {
"error": "שגיאה: {{error}}", "error": "שגיאה: {{error}}",
"dragging": "גרירה {{fileName}}", "dragging": "גרירה {{fileName}}",
"preparing": "מכין את {{fileName}}", "preparing": "מכין {{fileName}}",
"readySingle": "מוכן להורדה {{fileName}}", "readySingle": "מוכן להורדה {{fileName}}",
"readyMultiple": "מוכן להוריד את הקבצים של {{count}}", "readyMultiple": "מוכן להוריד {{count}} קבצים",
"batchDrag": "גרור {{count}} קבצים לשולחן העבודה", "batchDrag": "גרור {{count}} קבצים לשולחן העבודה",
"dragToDesktop": "גרור לשולחן העבודה", "dragToDesktop": "גרור לשולחן העבודה",
"canDragAnywhere": "ניתן לגרור קבצים לכל מקום בשולחן העבודה" "canDragAnywhere": "ניתן לגרור קבצים לכל מקום בשולחן העבודה"
@@ -202,7 +202,7 @@
"stopKeyRecording": "עצירת הקלטת מפתח", "stopKeyRecording": "עצירת הקלטת מפתח",
"selectTerminals": "בחר טרמינלים:", "selectTerminals": "בחר טרמינלים:",
"typeCommands": "פקודות הקלדה (כל המקשים נתמכים):", "typeCommands": "פקודות הקלדה (כל המקשים נתמכים):",
"commandsWillBeSent": "פקודות יישלחו ל-{{count}} טרמינל(ים) שנבחר(ים).", "commandsWillBeSent": "פקודות יישלחו אל {{count}} הטרמינל/ים שנבחרו.",
"settings": "הגדרות", "settings": "הגדרות",
"enableRightClickCopyPaste": "הפעלת העתקה/הדבקה באמצעות לחיצה ימנית", "enableRightClickCopyPaste": "הפעלת העתקה/הדבקה באמצעות לחיצה ימנית",
"shareIdeas": "יש לכם רעיונות לגבי מה שצריך לבוא בהמשך עבור כלי SSH? שתפו אותם ב", "shareIdeas": "יש לכם רעיונות לגבי מה שצריך לבוא בהמשך עבור כלי SSH? שתפו אותם ב",
@@ -224,7 +224,7 @@
"content": "פְּקוּדָה", "content": "פְּקוּדָה",
"namePlaceholder": "לדוגמה, הפעל מחדש את Nginx", "namePlaceholder": "לדוגמה, הפעל מחדש את Nginx",
"descriptionPlaceholder": "תיאור אופציונלי", "descriptionPlaceholder": "תיאור אופציונלי",
"contentPlaceholder": "לדוגמה, sudo systemctl restart nginx", "contentPlaceholder": "לדוגמה, sudo systemctl הפעל מחדש את nginx",
"nameRequired": "שם נדרש", "nameRequired": "שם נדרש",
"contentRequired": "נדרשת פקודה", "contentRequired": "נדרשת פקודה",
"createDescription": "צור קטע פקודה חדש לביצוע מהיר", "createDescription": "צור קטע פקודה חדש לביצוע מהיר",
@@ -256,7 +256,7 @@
"updateFolderFailed": "עדכון התיקייה נכשל", "updateFolderFailed": "עדכון התיקייה נכשל",
"createFolderFailed": "יצירת התיקייה נכשלה", "createFolderFailed": "יצירת התיקייה נכשלה",
"selectTerminals": "בחירת טרמינלים (אופציונלי)", "selectTerminals": "בחירת טרמינלים (אופציונלי)",
"executeOnSelected": "בצע ב-{{count}} טרמינלים נבחרים", "executeOnSelected": "בצע ב- {{count}} טרמינל/ים שנבחרו",
"executeOnCurrent": "בצע במסוף הנוכחי (לחץ כדי לבחור מספר אפשרויות)", "executeOnCurrent": "בצע במסוף הנוכחי (לחץ כדי לבחור מספר אפשרויות)",
"folder": "תיקייה", "folder": "תיקייה",
"selectFolder": "בחר תיקייה או השאר ריק", "selectFolder": "בחר תיקייה או השאר ריק",
@@ -335,7 +335,7 @@
"saveConfig": "שמור תצורה", "saveConfig": "שמור תצורה",
"helpText": "הזן את כתובת ה-URL שבה פועל שרת ה-Termix שלך (לדוגמה, http://localhost:30001 או https://your-server.com)", "helpText": "הזן את כתובת ה-URL שבה פועל שרת ה-Termix שלך (לדוגמה, http://localhost:30001 או https://your-server.com)",
"warning": "אַזהָרָה", "warning": "אַזהָרָה",
"notValidatedWarning": "כתובת ה-URL לא אומתה - ודא שהיא נכונה", "notValidatedWarning": "כתובת האתר לא אומתה - ודא שהיא נכונה",
"changeServer": "שנה שרת", "changeServer": "שנה שרת",
"mustIncludeProtocol": "כתובת השרת חייבת להתחיל ב-http:// או https://" "mustIncludeProtocol": "כתובת השרת חייבת להתחיל ב-http:// או https://"
}, },
@@ -345,7 +345,7 @@
"upToDate": "האפליקציה מעודכנת", "upToDate": "האפליקציה מעודכנת",
"currentVersion": "אתה משתמש בגרסה {{version}}", "currentVersion": "אתה משתמש בגרסה {{version}}",
"updateAvailable": "עדכון זמין", "updateAvailable": "עדכון זמין",
"newVersionAvailable": "גרסה חדשה זמינה! אתה משתמש ב-{{current}}, אך {{latest}} זמין.", "newVersionAvailable": "גרסה חדשה זמינה! אתה מפעיל {{current}}, אבל {{latest}} זמין.",
"releasedOn": "יצא לאור בתאריך {{date}}", "releasedOn": "יצא לאור בתאריך {{date}}",
"downloadUpdate": "הורד עדכון", "downloadUpdate": "הורד עדכון",
"dismiss": "לְפַטֵר", "dismiss": "לְפַטֵר",
@@ -387,7 +387,7 @@
"sshPath": "נתיב SSH", "sshPath": "נתיב SSH",
"localPath": "נתיב מקומי", "localPath": "נתיב מקומי",
"appName": "טרמיקס", "appName": "טרמיקס",
"resetSidebarWidth": "איפוס רוחב הסרגל הצדדי", "resetSidebarWidth": "איפוס רוחב הצד",
"dragToResizeSidebar": "גרור כדי לשנות את גודל הצד", "dragToResizeSidebar": "גרור כדי לשנות את גודל הצד",
"noAuthCredentials": "אין אישורי אימות זמינים עבור מארח SSH זה", "noAuthCredentials": "אין אישורי אימות זמינים עבור מארח SSH זה",
"noReleases": "אין פרסומים", "noReleases": "אין פרסומים",
@@ -456,7 +456,7 @@
"enterNewPassword": "הזן את הסיסמה החדשה שלך עבור המשתמש:", "enterNewPassword": "הזן את הסיסמה החדשה שלך עבור המשתמש:",
"passwordsDoNotMatch": "הסיסמאות אינן תואמות", "passwordsDoNotMatch": "הסיסמאות אינן תואמות",
"passwordMinLength": "הסיסמה חייבת להיות באורך של לפחות 6 תווים", "passwordMinLength": "הסיסמה חייבת להיות באורך של לפחות 6 תווים",
"passwordResetSuccess": "איפוס הסיסמה הצליח! כעת תוכל להתחבר עם הסיסמה החדשה שלך.", "passwordResetSuccess": "איפוס הסיסמה בוצע בהצלחה! כעת תוכל להתחבר עם הסיסמה החדשה שלך.",
"failedToInitiatePasswordReset": "נכשלה הפעלת איפוס הסיסמה", "failedToInitiatePasswordReset": "נכשלה הפעלת איפוס הסיסמה",
"failedToVerifyResetCode": "נכשל אימות קוד האיפוס", "failedToVerifyResetCode": "נכשל אימות קוד האיפוס",
"failedToCompletePasswordReset": "נכשל השלמת איפוס הסיסמה", "failedToCompletePasswordReset": "נכשל השלמת איפוס הסיסמה",
@@ -509,7 +509,7 @@
"updateSettings": "עדכון הגדרות", "updateSettings": "עדכון הגדרות",
"confirmDelete": "האם אתה בטוח שאתה רוצה למחוק את המשתמש הזה?", "confirmDelete": "האם אתה בטוח שאתה רוצה למחוק את המשתמש הזה?",
"confirmMakeAdmin": "האם אתה בטוח שאתה רוצה להפוך את {{username}} למנהל?", "confirmMakeAdmin": "האם אתה בטוח שאתה רוצה להפוך את {{username}} למנהל?",
"confirmRemoveAdmin": "האם אתה בטוח שברצונך להסיר את סטטוס המנהל מ-{{username}}?", "confirmRemoveAdmin": "האם אתה בטוח שברצונך להסיר את סטטוס המנהל מ- {{username}}?",
"externalAuthentication": "אימות חיצוני (OIDC)", "externalAuthentication": "אימות חיצוני (OIDC)",
"configureExternalProvider": "הגדר ספק זהויות חיצוני עבור אימות OIDC/OAuth2.", "configureExternalProvider": "הגדר ספק זהויות חיצוני עבור אימות OIDC/OAuth2.",
"userIdentifierPath": "נתיב מזהה המשתמש", "userIdentifierPath": "נתיב מזהה המשתמש",
@@ -549,8 +549,8 @@
"enterUsernameToMakeAdmin": "הזן שם משתמש כדי להפוך למנהל", "enterUsernameToMakeAdmin": "הזן שם משתמש כדי להפוך למנהל",
"userIsNowAdmin": "משתמש {{username}} הוא כעת מנהל", "userIsNowAdmin": "משתמש {{username}} הוא כעת מנהל",
"failedToMakeUserAdmin": "נכשל בהפיכת המשתמש למנהל", "failedToMakeUserAdmin": "נכשל בהפיכת המשתמש למנהל",
"removeAdminStatus": "להסיר את סטטוס המנהל מ-{{username}}?", "removeAdminStatus": "להסיר סטטוס מנהל מ- {{username}}?",
"adminStatusRemoved": "סטטוס מנהל הוסר מ-{{username}}", "adminStatusRemoved": "סטטוס מנהל הוסר מ- {{username}}",
"failedToRemoveAdminStatus": "הסרת סטטוס מנהל נכשלה", "failedToRemoveAdminStatus": "הסרת סטטוס מנהל נכשלה",
"userDeletedSuccessfully": "משתמש {{username}} נמחק בהצלחה", "userDeletedSuccessfully": "משתמש {{username}} נמחק בהצלחה",
"failedToDeleteUser": "מחיקת המשתמש נכשלה", "failedToDeleteUser": "מחיקת המשתמש נכשלה",
@@ -564,7 +564,7 @@
"sessionsRevokedSuccessfully": "הפעילויות בוטלו בהצלחה", "sessionsRevokedSuccessfully": "הפעילויות בוטלו בהצלחה",
"linkToPasswordAccount": "קישור לחשבון סיסמה", "linkToPasswordAccount": "קישור לחשבון סיסמה",
"linkOIDCDialogTitle": "קישור חשבון OIDC לחשבון סיסמה", "linkOIDCDialogTitle": "קישור חשבון OIDC לחשבון סיסמה",
"linkOIDCDialogDescription": "קשר את {{username}} (משתמש OIDC) לחשבון סיסמה קיים. פעולה זו תאפשר אימות כפול עבור חשבון הסיסמה.", "linkOIDCDialogDescription": "קשר {{username}} (משתמש OIDC) לחשבון סיסמה קיים. פעולה זו תאפשר אימות כפול עבור חשבון הסיסמה.",
"createUser": "צור משתמש", "createUser": "צור משתמש",
"createUserDescription": "צור משתמש מקומי חדש עם שם משתמש וסיסמה", "createUserDescription": "צור משתמש מקומי חדש עם שם משתמש וסיסמה",
"enterUsername": "הזן שם משתמש", "enterUsername": "הזן שם משתמש",
@@ -577,11 +577,11 @@
"adminStatus": "סטטוס מנהל", "adminStatus": "סטטוס מנהל",
"userId": "מזהה משתמש", "userId": "מזהה משתמש",
"regularUser": "משתמש רגיל", "regularUser": "משתמש רגיל",
"adminPrivileges": "הרשאות מנהל מערכת", "adminPrivileges": "הרשאות מנהל",
"administratorRole": "תפקיד מנהל", "administratorRole": "תפקיד מנהל",
"administratorRoleDescription": "הענקת גישה מלאה למערכת והרשאות ניהול", "administratorRoleDescription": "הענקת גישה מלאה למערכת והרשאות ניהול",
"passwordManagement": "ניהול סיסמאות", "passwordManagement": "ניהול סיסמאות",
"passwordResetWarning": "איפוס סיסמת משתמש ימחק את כל הנתונים שלו (מארחי SSH, אישורים, הגדרות). פעולה זו אינה ניתנת לביטול.", "passwordResetWarning": "איפוס סיסמת משתמש ימחק את כל הנתונים שלו (מארחי SSH, פרטי כניסה, הגדרות). פעולה זו אינה ניתנת לביטול.",
"resetUserPassword": "איפוס סיסמת משתמש", "resetUserPassword": "איפוס סיסמת משתמש",
"resettingPassword": "איפוס...", "resettingPassword": "איפוס...",
"passwordResetInitiated": "איפוס סיסמה החל עבור {{username}}. קוד איפוס נשלח.", "passwordResetInitiated": "איפוס סיסמה החל עבור {{username}}. קוד איפוס נשלח.",
@@ -611,12 +611,12 @@
"linkTargetUsernamePlaceholder": "הזן שם משתמש של סיסמת חשבון", "linkTargetUsernamePlaceholder": "הזן שם משתמש של סיסמת חשבון",
"linkAccountsButton": "קישור חשבונות", "linkAccountsButton": "קישור חשבונות",
"linkingAccounts": "מְקַשֵׁר...", "linkingAccounts": "מְקַשֵׁר...",
"accountsLinkedSuccessfully": "משתמש OIDC {{oidcUsername}} קושר ל-{{targetUsername}}", "accountsLinkedSuccessfully": "משתמש OIDC {{oidcUsername}} קושר ל- {{targetUsername}}",
"failedToLinkAccounts": "קישור החשבונות נכשל", "failedToLinkAccounts": "קישור החשבונות נכשל",
"linkTargetUsernameRequired": "נדרש שם משתמש של היעד", "linkTargetUsernameRequired": "נדרש שם משתמש של היעד",
"unlinkOIDCTitle": "ניתוק אימות OIDC", "unlinkOIDCTitle": "ניתוק קישור אימות OIDC",
"unlinkOIDCDescription": "להסיר אימות OIDC מ-{{username}}? המשתמש יוכל להתחבר רק באמצעות שם משתמש/סיסמה לאחר מכן.", "unlinkOIDCDescription": "להסיר אימות OIDC מ- {{username}}? המשתמש יוכל להתחבר רק באמצעות שם משתמש/סיסמה לאחר מכן.",
"unlinkOIDCSuccess": "OIDC נותק מ-{{username}}", "unlinkOIDCSuccess": "OIDC נותק מ- {{username}}",
"failedToUnlinkOIDC": "נכשל ניתוק ה-OIDC", "failedToUnlinkOIDC": "נכשל ניתוק ה-OIDC",
"databaseSecurity": "אבטחת מסד נתונים", "databaseSecurity": "אבטחת מסד נתונים",
"encryptionStatus": "סטטוס הצפנה", "encryptionStatus": "סטטוס הצפנה",
@@ -628,13 +628,13 @@
"migrationStatus": "סטטוס הגירה", "migrationStatus": "סטטוס הגירה",
"migrationCompleted": "ההגירה הושלמה", "migrationCompleted": "ההגירה הושלמה",
"migrationRequired": "נדרשת הגירה", "migrationRequired": "נדרשת הגירה",
"deviceProtectedMasterKey": "מפתח ראשי מוגן סביבה", "deviceProtectedMasterKey": "מפתח ראשי מוגן לסביבה",
"legacyKeyStorage": "אחסון מפתחות מדור קודם", "legacyKeyStorage": "אחסון מפתחות מדור קודם",
"masterKeyEncryptedWithDeviceFingerprint": "מפתח ראשי מוצפן עם טביעת אצבע סביבתית (הגנת KEK פעילה)", "masterKeyEncryptedWithDeviceFingerprint": "מפתח ראשי מוצפן עם טביעת אצבע סביבתית (הגנת KEK פעילה)",
"keyNotProtectedByDeviceBinding": "המפתח אינו מוגן על ידי קשירת סביבה (מומלץ לשדרג)", "keyNotProtectedByDeviceBinding": "המפתח אינו מוגן על ידי קשירת סביבה (מומלץ לשדרג)",
"valid": "תָקֵף", "valid": "תָקֵף",
"initializeDatabaseEncryption": "אתחול הצפנת מסד נתונים", "initializeDatabaseEncryption": "אתחול הצפנת מסד נתונים",
"enableAes256EncryptionWithDeviceBinding": "הפעל הצפנת AES-256 עם הגנה על מפתחות ראשיים תלוית סביבה. פעולה זו יוצרת אבטחה ברמה ארגונית עבור מפתחות SSH, סיסמאות ואסימוני אימות.", "enableAes256EncryptionWithDeviceBinding": "הפעל הצפנת AES-256 עם הגנה על מפתחות ראשיים תלוית סביבה. פעולה זו יוצרת אבטחה ברמה ארגונית עבור מפתחות SSH, סיסמאות וטוקני אימות.",
"featuresEnabled": "תכונות מופעלות:", "featuresEnabled": "תכונות מופעלות:",
"aes256GcmAuthenticatedEncryption": "הצפנה מאומתת AES-256-GCM", "aes256GcmAuthenticatedEncryption": "הצפנה מאומתת AES-256-GCM",
"deviceFingerprintMasterKeyProtection": "הגנה סביבתית על מפתח ראשי באמצעות טביעות אצבע (KEK)", "deviceFingerprintMasterKeyProtection": "הגנה סביבתית על מפתח ראשי באמצעות טביעות אצבע (KEK)",
@@ -695,7 +695,7 @@
"exportForMigration": "ייצוא לצורך הגירה", "exportForMigration": "ייצוא לצורך הגירה",
"exportDatabaseForHardwareMigration": "ייצוא מסד נתונים כקובץ SQLite עם נתונים מפוענחים לצורך הגירה לחומרה חדשה", "exportDatabaseForHardwareMigration": "ייצוא מסד נתונים כקובץ SQLite עם נתונים מפוענחים לצורך הגירה לחומרה חדשה",
"exportDatabase": "ייצוא מסד נתונים של SQLite", "exportDatabase": "ייצוא מסד נתונים של SQLite",
"exporting": "מייצא...", "exporting": "ייצוא...",
"exportCreated": "ייצוא SQLite נוצר", "exportCreated": "ייצוא SQLite נוצר",
"exportContainsDecryptedData": "ייצוא SQLite מכיל נתונים מפוענחים - יש לשמור על אבטחה!", "exportContainsDecryptedData": "ייצוא SQLite מכיל נתונים מפוענחים - יש לשמור על אבטחה!",
"databaseExportedSuccessfully": "מסד הנתונים SQLite יוצא בהצלחה", "databaseExportedSuccessfully": "מסד הנתונים SQLite יוצא בהצלחה",
@@ -756,7 +756,7 @@
"revokeAllUserSessionsTitle": "ביטול כל ההפעלות עבור משתמש זה", "revokeAllUserSessionsTitle": "ביטול כל ההפעלות עבור משתמש זה",
"revokeAll": "בטל הכל", "revokeAll": "בטל הכל",
"linkOidcToPasswordAccount": "קישור חשבון OIDC לחשבון סיסמה", "linkOidcToPasswordAccount": "קישור חשבון OIDC לחשבון סיסמה",
"linkOidcToPasswordAccountDescription": "קשר את {{username}} (משתמש OIDC) לחשבון סיסמה קיים. פעולה זו תאפשר אימות כפול עבור חשבון הסיסמה.", "linkOidcToPasswordAccountDescription": "קשר {{username}} (משתמש OIDC) לחשבון סיסמה קיים. פעולה זו תאפשר אימות כפול עבור חשבון הסיסמה.",
"linkOidcWarningTitle": "אזהרה: נתוני משתמש OIDC יימחקו", "linkOidcWarningTitle": "אזהרה: נתוני משתמש OIDC יימחקו",
"linkOidcWarningDescription": "פעולה זו תביא ל:", "linkOidcWarningDescription": "פעולה זו תביא ל:",
"linkOidcActionDeleteUser": "מחיקת חשבון המשתמש של OIDC וכל הנתונים שלו", "linkOidcActionDeleteUser": "מחיקת חשבון המשתמש של OIDC וכל הנתונים שלו",
@@ -777,23 +777,23 @@
"retry": "נסה שוב", "retry": "נסה שוב",
"refresh": "לְרַעֲנֵן", "refresh": "לְרַעֲנֵן",
"optional": "אופציונלי", "optional": "אופציונלי",
"hostsCount": "מארחים", "hostsCount": "{{count}} hosts",
"importJson": "ייבוא JSON", "importJson": "ייבוא JSON",
"importing": "מייבא...", "importing": "מייבא...",
"importJsonTitle": "ייבוא מארחי SSH מ-JSON", "importJsonTitle": "ייבוא מארחי SSH מ-JSON",
"importJsonDesc": "העלה קובץ JSON לייבוא בכמות גדולה של מארחי SSH מרובים (מקסימום 100).", "importJsonDesc": "העלה קובץ JSON לייבוא בכמות גדולה של מארחי SSH מרובים (מקסימום 100).",
"downloadSample": "הורד דוגמה", "downloadSample": "הורד דוגמה",
"formatGuide": "מדריך פורמט", "formatGuide": "מדריך פורמט",
"exportCredentialWarning": "אזהרה: המארח \"{{count}}\" משתמש באימות אישורים. הקובץ המיוצא לא יכלול את נתוני האישורים ויהיה צורך להגדיר אותו מחדש באופן ידני לאחר הייבוא. האם ברצונך להמשיך?", "exportCredentialWarning": "אזהרה: המארח \"{{name}}\" משתמש באימות אישורים. הקובץ המיוצא לא יכלול את נתוני האישורים ויהיה צורך להגדיר אותו מחדש באופן ידני לאחר הייבוא. האם ברצונך להמשיך?",
"exportSensitiveDataWarning": "אזהרה: המארח \"{{name}}\" מכיל נתוני אימות רגישים (סיסמה/מפתח SSH). הקובץ המיוצא יכלול נתונים אלה בטקסט רגיל. אנא שמור את הקובץ מאובטח ומחק אותו לאחר השימוש. האם ברצונך להמשיך?", "exportSensitiveDataWarning": "אזהרה: המארח \"{{name}}\" מכיל נתוני אימות רגישים (סיסמה/מפתח SSH). הקובץ המיוצא יכלול נתונים אלה בטקסט רגיל. אנא שמור את הקובץ מאובטח ומחק אותו לאחר השימוש. האם ברצונך להמשיך?",
"uncategorized": "ללא קטגוריה", "uncategorized": "ללא קטגוריה",
"confirmDelete": "האם אתה בטוח שברצונך למחוק את \"{{name}}\"?", "confirmDelete": "האם אתה בטוח שאתה רוצה למחוק את \"{{name}}\"?",
"failedToDeleteHost": "מחיקת המארח נכשלה", "failedToDeleteHost": "מחיקת המארח נכשלה",
"failedToExportHost": "ייצוא המארח נכשל. אנא ודא שאתה מחובר ויש לך גישה לנתוני המארח.", "failedToExportHost": "ייצוא המארח נכשל. אנא ודא שאתה מחובר ויש לך גישה לנתוני המארח.",
"jsonMustContainHosts": "JSON חייב להכיל מערך של \"hosts\" או להיות מערך של hosts", "jsonMustContainHosts": "JSON חייב להכיל מערך \"hosts\" או להיות מערך של hosts",
"noHostsInJson": "לא נמצאו מארחים בקובץ JSON", "noHostsInJson": "לא נמצאו מארחים בקובץ JSON",
"maxHostsAllowed": "מקסימום 100 מארחים מותרים לכל ייבוא", "maxHostsAllowed": "מקסימום 100 מארחים מותרים לכל ייבוא",
"importCompleted": "ייבוא הושלם: {{name}} הצליח, {{success}} נכשל", "importCompleted": "ייבוא הושלם: {{success}} הצליח, {{failed}} נכשל",
"importFailed": "הייבוא נכשל", "importFailed": "הייבוא נכשל",
"importError": "שגיאת ייבוא", "importError": "שגיאת ייבוא",
"failedToImportJson": "ייבוא קובץ JSON נכשל", "failedToImportJson": "ייבוא קובץ JSON נכשל",
@@ -816,7 +816,7 @@
"editHost": "עריכת מארח", "editHost": "עריכת מארח",
"cloneHost": "מארח משוכפל", "cloneHost": "מארח משוכפל",
"updateHost": "עדכון מארח", "updateHost": "עדכון מארח",
"hostUpdatedSuccessfully": "המארח \"{{failed}}\" עודכן בהצלחה!", "hostUpdatedSuccessfully": "המארח \"{{name}}\" עודכן בהצלחה!",
"hostAddedSuccessfully": "המארח \"{{name}}\" נוסף בהצלחה!", "hostAddedSuccessfully": "המארח \"{{name}}\" נוסף בהצלחה!",
"hostDeletedSuccessfully": "המארח \"{{name}}\" נמחק בהצלחה!", "hostDeletedSuccessfully": "המארח \"{{name}}\" נמחק בהצלחה!",
"failedToSaveHost": "שמירת המארח נכשלה. אנא נסה שוב.", "failedToSaveHost": "שמירת המארח נכשלה. אנא נסה שוב.",
@@ -837,10 +837,10 @@
"connection": "קֶשֶׁר", "connection": "קֶשֶׁר",
"remove": "לְהַסִיר", "remove": "לְהַסִיר",
"sourcePort": "יציאת מקור", "sourcePort": "יציאת מקור",
"sourcePortDesc": "(המקור מתייחס לפרטי החיבור הנוכחיים בלשונית כללי)", "sourcePortDesc": " (המקור מתייחס לפרטי החיבור הנוכחיים בלשונית כללי)",
"endpointPort": "יציאת נקודת קצה", "endpointPort": "יציאת נקודת קצה",
"endpointSshConfig": "תצורת SSH של נקודת קצה", "endpointSshConfig": "תצורת SSH של נקודת קצה",
"tunnelForwardDescription": "מנהרה זו תעביר תעבורה מפורט {{name}} במחשב המקור (פרטי החיבור הנוכחיים בכרטיסייה הכללית) לפורט {{sourcePort}} במחשב נקודת הקצה.", "tunnelForwardDescription": "מנהרה זו תעביר תעבורה מפורט {{sourcePort}} במחשב המקור (פרטי החיבור הנוכחיים בכרטיסייה הכללית) לפורט {{endpointPort}} במחשב נקודת הקצה.",
"maxRetries": "מקסימום ניסיונות חוזרים", "maxRetries": "מקסימום ניסיונות חוזרים",
"maxRetriesDescription": "מספר מרבי של ניסיונות חוזרים עבור חיבור מנהרה.", "maxRetriesDescription": "מספר מרבי של ניסיונות חוזרים עבור חיבור מנהרה.",
"retryInterval": "מרווח זמן לניסיון חוזר (שניות)", "retryInterval": "מרווח זמן לניסיון חוזר (שניות)",
@@ -871,7 +871,7 @@
"selectCredential": "בחר אישור", "selectCredential": "בחר אישור",
"selectCredentialPlaceholder": "בחר אישור...", "selectCredentialPlaceholder": "בחר אישור...",
"credentialRequired": "נדרשת אישור בעת שימוש באימות אישורים", "credentialRequired": "נדרשת אישור בעת שימוש באימות אישורים",
"credentialDescription": "בחירת פרטי כניסה תגרום להחלפת שם המשתמש הנוכחי ותשתמש בפרטי האימות של פרטי הכניסה.", "credentialDescription": "בחירת שם אישור תדרוס את שם המשתמש הנוכחי ותשתמש בפרטי האימות של שם האישור.",
"cannotChangeAuthAsSharedUser": "לא ניתן לשנות אימות כמשתמש משותף", "cannotChangeAuthAsSharedUser": "לא ניתן לשנות אימות כמשתמש משותף",
"sshPrivateKey": "מפתח פרטי SSH", "sshPrivateKey": "מפתח פרטי SSH",
"keyPassword": "סיסמת מפתח", "keyPassword": "סיסמת מפתח",
@@ -916,10 +916,10 @@
"customCommandsDesc": "הגדר פקודות כיבוי והפעלה מחדש מותאמות אישית עבור שרת זה", "customCommandsDesc": "הגדר פקודות כיבוי והפעלה מחדש מותאמות אישית עבור שרת זה",
"shutdownCommand": "פקודת כיבוי", "shutdownCommand": "פקודת כיבוי",
"rebootCommand": "פקודת אתחול מחדש", "rebootCommand": "פקודת אתחול מחדש",
"confirmRemoveFromFolder": "האם אתה בטוח שברצונך להסיר את \"{{endpointPort}}\" מהתיקייה \"{{name}}\"? המארח יועבר ל-\"אין תיקייה\".", "confirmRemoveFromFolder": "האם אתה בטוח שברצונך להסיר את \"{{name}}\" מהתיקייה \"{{folder}}\"? המארח יועבר ל\"אין תיקייה\".",
"removedFromFolder": "המארח \"{{folder}}\" הוסר בהצלחה מהתיקייה", "removedFromFolder": "המארח \"{{name}}\" הוסר בהצלחה מהתיקייה",
"failedToRemoveFromFolder": "נכשלה הסרת המארח מהתיקייה", "failedToRemoveFromFolder": "נכשלה הסרת המארח מהתיקייה",
"folderRenamed": "שם התיקייה \"{{name}}\" שונה בהצלחה ל-\"{{oldName}}\"", "folderRenamed": "תיקיית \"{{oldName}}\" שמה שונה בהצלחה ל- \"{{newName}}\"",
"failedToRenameFolder": "נכשל שינוי שם התיקייה", "failedToRenameFolder": "נכשל שינוי שם התיקייה",
"editFolderAppearance": "עריכת מראה התיקייה", "editFolderAppearance": "עריכת מראה התיקייה",
"editFolderAppearanceDesc": "התאם אישית את הצבע והסמל עבור התיקייה", "editFolderAppearanceDesc": "התאם אישית את הצבע והסמל עבור התיקייה",
@@ -929,10 +929,10 @@
"folderAppearanceUpdated": "מראה התיקייה עודכן בהצלחה", "folderAppearanceUpdated": "מראה התיקייה עודכן בהצלחה",
"failedToUpdateFolderAppearance": "נכשל עדכון מראה התיקייה", "failedToUpdateFolderAppearance": "נכשל עדכון מראה התיקייה",
"deleteAllHostsInFolder": "מחק את כל המארחים בתיקייה", "deleteAllHostsInFolder": "מחק את כל המארחים בתיקייה",
"confirmDeleteAllHostsInFolder": "האם אתה בטוח שברצונך למחוק את כל המארחים {{newName}} בתיקייה \"{{count}}\"? לא ניתן לבטל פעולה זו.", "confirmDeleteAllHostsInFolder": "האם אתה בטוח שברצונך למחוק את כל המארחים {{count}} בתיקייה \"{{folder}}\"? לא ניתן לבטל פעולה זו.",
"allHostsInFolderDeleted": "מחיקת {{folder}} מארחים מהתיקייה \"{{count}}\" הצליחה", "allHostsInFolderDeleted": "מחיקת {{count}} hosts מהתיקייה \"{{folder}}\" הצליחה",
"failedToDeleteHostsInFolder": "נכשלה מחיקת המארחים בתיקייה", "failedToDeleteHostsInFolder": "נכשלה מחיקת המארחים בתיקייה",
"movedToFolder": "המארח \"{{folder}}\" הועבר ל-\"{{name}}\" בהצלחה", "movedToFolder": "המארח \"{{name}}\" הועבר ל- \"{{folder}}\" בהצלחה",
"failedToMoveToFolder": "נכשלה העברת המארח לתיקייה", "failedToMoveToFolder": "נכשלה העברת המארח לתיקייה",
"clickToRenameFolder": "לחץ כדי לשנות את שם התיקייה", "clickToRenameFolder": "לחץ כדי לשנות את שם התיקייה",
"renameFolder": "שינוי שם התיקייה", "renameFolder": "שינוי שם התיקייה",
@@ -943,7 +943,7 @@
"cloneHostTooltip": "מארח משוכפל", "cloneHostTooltip": "מארח משוכפל",
"clickToEditHost": "לחץ כדי לערוך את המארח", "clickToEditHost": "לחץ כדי לערוך את המארח",
"dragToMoveBetweenFolders": "גרור כדי לעבור בין תיקיות", "dragToMoveBetweenFolders": "גרור כדי לעבור בין תיקיות",
"exportedHostConfig": "ייצוא תצורת מארח עבור {{folder}}", "exportedHostConfig": "ייצוא תצורת מארח עבור {{name}}",
"openTerminal": "פתח את הטרמינל", "openTerminal": "פתח את הטרמינל",
"openFileManager": "פתח את מנהל הקבצים", "openFileManager": "פתח את מנהל הקבצים",
"openTunnels": "מנהרות פתוחות", "openTunnels": "מנהרות פתוחות",
@@ -982,10 +982,10 @@
"selectFont": "בחירת גופן", "selectFont": "בחירת גופן",
"selectFontDesc": "בחר את הגופן לשימוש בטרמינל", "selectFontDesc": "בחר את הגופן לשימוש בטרמינל",
"fontSize": "גודל גופן", "fontSize": "גודל גופן",
"fontSizeValue": "גודל גופן: {{name}} פיקסלים", "fontSizeValue": "גודל גופן: {{value}}פיקסלים",
"adjustFontSize": "התאם את גודל הגופן של הטרמינל", "adjustFontSize": "התאם את גודל הגופן של הטרמינל",
"letterSpacing": "ריווח אותיות", "letterSpacing": "ריווח אותיות",
"letterSpacingValue": "ריווח בין אותיות: {{value}}px", "letterSpacingValue": "ריווח בין אותיות: {{value}}פיקסלים",
"adjustLetterSpacing": "התאמת מרווח בין תווים", "adjustLetterSpacing": "התאמת מרווח בין תווים",
"lineHeight": "גובה הקו", "lineHeight": "גובה הקו",
"lineHeightValue": "גובה שורה: {{value}}", "lineHeightValue": "גובה שורה: {{value}}",
@@ -1001,13 +1001,13 @@
"scrollbackBuffer": "מאגר גלילה לאחור", "scrollbackBuffer": "מאגר גלילה לאחור",
"scrollbackBufferValue": "מאגר גלילה לאחור: {{value}} שורות", "scrollbackBufferValue": "מאגר גלילה לאחור: {{value}} שורות",
"scrollbackBufferDesc": "מספר השורות לשמירה בהיסטוריית הגלילה לאחור", "scrollbackBufferDesc": "מספר השורות לשמירה בהיסטוריית הגלילה לאחור",
"bellStyle": "סגנון בל", "bellStyle": "סגנון פעמון",
"selectBellStyle": "בחר סגנון פעמון", "selectBellStyle": "בחר סגנון פעמון",
"bellStyleNone": "אַף לֹא אֶחָד", "bellStyleNone": "אַף לֹא אֶחָד",
"bellStyleSound": "קוֹל", "bellStyleSound": "קוֹל",
"bellStyleVisual": "חָזוּתִי", "bellStyleVisual": "חָזוּתִי",
"bellStyleBoth": "שְׁנֵיהֶם", "bellStyleBoth": "שְׁנֵיהֶם",
"bellStyleDesc": "כיצד לטפל בפעמון הטרמינל (תו BEL, \\x07). תוכניות מפעילות זאת בעת השלמת משימות, נתקלות בשגיאות או לקבלת התראות. \"Sound\" משמיע צפצוף קולי, \"Visual\" מהבהב את המסך לזמן קצר, \"Both\" עושה את שניהם, \"None\" מבטל התראות פעמון.", "bellStyleDesc": "כיצד לטפל בפעמון הטרמינל (תו BEL, \\x07). תוכניות מפעילות זאת בעת השלמת משימות, נתקלות בשגיאות או לקבלת התראות. \"צליל\" משמיע צפצוף קולי, \"חזותי\" מהבהב את המסך לזמן קצר, \"שניהם\" עושה את שניהם, \"ללא\" מבטל התראות פעמון.",
"rightClickSelectsWord": "לחיצה ימנית בוחרת מילה", "rightClickSelectsWord": "לחיצה ימנית בוחרת מילה",
"rightClickSelectsWordDesc": "לחיצה ימנית בוחרת את המילה שמתחת לסמן", "rightClickSelectsWordDesc": "לחיצה ימנית בוחרת את המילה שמתחת לסמן",
"fastScrollModifier": "שינוי גלילה מהירה", "fastScrollModifier": "שינוי גלילה מהירה",
@@ -1056,8 +1056,8 @@
"socks5Port": "יציאת פרוקסי", "socks5Port": "יציאת פרוקסי",
"socks5Username": "שם משתמש פרוקסי", "socks5Username": "שם משתמש פרוקסי",
"socks5Password": "סיסמת פרוקסי", "socks5Password": "סיסמת פרוקסי",
"socks5UsernameOptional": "אופציונלי: השאר ריק אם הפרוקסי אינו דורש אימות", "socks5UsernameOptional": "אופציונלי: השאר ריק אם פרוקסי אינו דורש אימות",
"socks5PasswordOptional": "אופציונלי: השאר ריק אם הפרוקסי אינו דורש אימות", "socks5PasswordOptional": "אופציונלי: השאר ריק אם פרוקסי אינו דורש אימות",
"socks5ProxyChain": "שרשרת פרוקסי", "socks5ProxyChain": "שרשרת פרוקסי",
"socks5ProxyChainDescription": "הגדר שרשרת של פרוקסי SOCKS. כל פרוקסי בשרשרת יתחבר דרך הקודם.", "socks5ProxyChainDescription": "הגדר שרשרת של פרוקסי SOCKS. כל פרוקסי בשרשרת יתחבר דרך הקודם.",
"socks5ProxyMode": "מצב פרוקסי", "socks5ProxyMode": "מצב פרוקסי",
@@ -1066,7 +1066,7 @@
"socks5UsePreset": "השתמש בהגדרות קבועות מראש ששמרתי", "socks5UsePreset": "השתמש בהגדרות קבועות מראש ששמרתי",
"socks5SelectPreset": "בחר הגדרה קבועה מראש", "socks5SelectPreset": "בחר הגדרה קבועה מראש",
"socks5ManagePresets": "ניהול הגדרות קבועות מראש", "socks5ManagePresets": "ניהול הגדרות קבועות מראש",
"socks5ProxyNode": "פרוקסי {{value}}", "socks5ProxyNode": "פרוקסי {{number}}",
"socks5AddProxy": "הוסף פרוקסי לשרשרת", "socks5AddProxy": "הוסף פרוקסי לשרשרת",
"socks5RemoveProxy": "הסר פרוקסי", "socks5RemoveProxy": "הסר פרוקסי",
"socks5ProxyType": "סוג פרוקסי", "socks5ProxyType": "סוג פרוקסי",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "נוצרה הגדרת תצורה מוגדרת מראש של שרשרת פרוקסי", "socks5PresetCreated": "נוצרה הגדרת תצורה מוגדרת מראש של שרשרת פרוקסי",
"socks5PresetUpdated": "הגדרת שרשרת פרוקסי עודכנה", "socks5PresetUpdated": "הגדרת שרשרת פרוקסי עודכנה",
"socks5PresetDeleted": "הגדרת שרשרת פרוקסי נמחקה", "socks5PresetDeleted": "הגדרת שרשרת פרוקסי נמחקה",
"socks5PresetSaved": "ההגדרה הקבועה מראש \"{{number}}\" נשמרה בהצלחה", "socks5PresetSaved": "ההגדרה הקבועה מראש \"{{name}}\" נשמרה בהצלחה",
"socks5PresetSaveError": "נכשלה שמירת ההגדרה הקבועה מראש", "socks5PresetSaveError": "נכשלה שמירת ההגדרה הקבועה מראש",
"socks5PresetNameRequired": "נדרש שם מוגדר מראש", "socks5PresetNameRequired": "נדרש שם מוגדר מראש",
"socks5EmptyChainError": "לא ניתן לשמור שרשרת פרוקסי ריקה", "socks5EmptyChainError": "לא ניתן לשמור שרשרת פרוקסי ריקה",
@@ -1105,7 +1105,7 @@
"socks5": "גרביים5", "socks5": "גרביים5",
"executeSnippetOnConnect": "בצע קטע קוד כאשר הטרמינל מתחבר", "executeSnippetOnConnect": "בצע קטע קוד כאשר הטרמינל מתחבר",
"autoMosh": "אוטו-MOSH", "autoMosh": "אוטו-MOSH",
"autoMoshDesc": "הפעלת פקודת MOSH באופן אוטומטי בעת התחברות", "autoMoshDesc": "הפעלת פקודת MOSH באופן אוטומטי בעת חיבור",
"moshCommand": "פיקוד MOSH", "moshCommand": "פיקוד MOSH",
"moshCommandDesc": "פקודת MOSH לביצוע", "moshCommandDesc": "פקודת MOSH לביצוע",
"environmentVariables": "משתני סביבה", "environmentVariables": "משתני סביבה",
@@ -1118,8 +1118,8 @@
"notEnabled": "Docker אינו מופעל עבור מארח זה. הפעל אותו בהגדרות המארח כדי להשתמש בתכונות Docker.", "notEnabled": "Docker אינו מופעל עבור מארח זה. הפעל אותו בהגדרות המארח כדי להשתמש בתכונות Docker.",
"validating": "מאמת את Docker...", "validating": "מאמת את Docker...",
"error": "שְׁגִיאָה", "error": "שְׁגִיאָה",
"errorCode": "קוד שגיאה: {{name}}", "errorCode": "קוד שגיאה: {{code}}",
"version": "דוקר גרסה {{code}}", "version": "דוקר נגד{{version}}",
"current": "נוֹכְחִי", "current": "נוֹכְחִי",
"used_limit": "בשימוש / מגבלה", "used_limit": "בשימוש / מגבלה",
"percentage": "אֲחוּזִים", "percentage": "אֲחוּזִים",
@@ -1133,10 +1133,10 @@
"console": "לְנַחֵם", "console": "לְנַחֵם",
"containerMustBeRunning": "המכולה חייבת לפעול כדי להתחבר לקונסולה", "containerMustBeRunning": "המכולה חייבת לפעול כדי להתחבר לקונסולה",
"authenticationRequired": "נדרש אימות", "authenticationRequired": "נדרש אימות",
"connectedTo": "מחובר ל-{{version}}", "connectedTo": "מחובר אל {{containerName}}",
"disconnected": "מְנוּתָק", "disconnected": "מְנוּתָק",
"consoleError": "שגיאת קונסולה", "consoleError": "שגיאת קונסולה",
"errorMessage": "שגיאה: {{containerName}}", "errorMessage": "שגיאה: {{message}}",
"failedToConnect": "נכשלה ההתחברות לקונסולה", "failedToConnect": "נכשלה ההתחברות לקונסולה",
"disconnectedFromContainer": "ניתוק מקונסולת המכולה.", "disconnectedFromContainer": "ניתוק מקונסולת המכולה.",
"containerNotRunning": "המכולה לא פועלת", "containerNotRunning": "המכולה לא פועלת",
@@ -1150,28 +1150,28 @@
"disconnect": "לְנַתֵק", "disconnect": "לְנַתֵק",
"notConnected": "לא מחובר", "notConnected": "לא מחובר",
"clickToConnect": "לחץ על התחבר כדי להפעיל מעטפת אינטראקטיבית", "clickToConnect": "לחץ על התחבר כדי להפעיל מעטפת אינטראקטיבית",
"connectingTo": "מתחבר אל {{message}}...", "connectingTo": "מתחבר אל {{containerName}}...",
"containerMustBeRunningToViewStats": "יש להפעיל את המיכל כדי להציג נתונים סטטיסטיים", "containerMustBeRunningToViewStats": "יש להפעיל את המיכל כדי להציג נתונים סטטיסטיים",
"failedToFetchStats": "נכשלה שליפת הנתונים הסטטיסטיים", "failedToFetchStats": "נכשלה שליפת הנתונים הסטטיסטיים",
"noContainersFound": "לא נמצאו מכולות", "noContainersFound": "לא נמצאו מכולות",
"noContainersFoundHint": "התחל על ידי יצירת קונטיינרים בשרת שלך", "noContainersFoundHint": "התחל על ידי יצירת קונטיינרים בשרת שלך",
"searchPlaceholder": "חיפוש לפי שם, תמונה או תעודת זהות...", "searchPlaceholder": "חיפוש לפי שם, תמונה או תעודת זהות...",
"filterByStatusPlaceholder": "סנן לפי סטטוס", "filterByStatusPlaceholder": "סנן לפי סטטוס",
"allContainersCount": "הכל ({{containerName}})", "allContainersCount": "הכל ({{count}})",
"statusCount": "{{count}} ({{status}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "אין מכולות התואמות את המסננים שלך", "noContainersMatchFilters": "אין מכולות התואמות את המסננים שלך",
"noContainersMatchFiltersHint": "נסה להתאים את החיפוש או הסינון שלך", "noContainersMatchFiltersHint": "נסה להתאים את החיפוש או הסינון שלך",
"containerStarted": "מיכל {{count}} הופעל", "containerStarted": "מיכל {{name}} הופעל",
"failedToStartContainer": "נכשל בהפעלת המכולה: {{name}}", "failedToStartContainer": "נכשל בהפעלת המכולה: {{error}}",
"containerStopped": "מיכל {{error}} נעצר", "containerStopped": "מיכל {{name}} נעצר",
"failedToStopContainer": "עצירת המכולה נכשלה: {{name}}", "failedToStopContainer": "נכשלה עצירת המכולה: {{error}}",
"containerRestarted": "מיכל {{error}} הופעל מחדש", "containerRestarted": "מיכל {{name}} הופעל מחדש",
"failedToRestartContainer": "נכשלה ההפעלה מחדש של המכולה: {{name}}", "failedToRestartContainer": "נכשלה ההפעלה מחדש של המכולה: {{error}}",
"containerUnpaused": "מיכל {{error}} בוטל", "containerUnpaused": "השהיית המיכל {{name}} בוטלה",
"containerPaused": "מיכל {{name}} הושהה", "containerPaused": "מיכל {{name}} הושהה",
"failedToTogglePauseContainer": "נכשל בביצוע {{name}} של המכולה: {{action}}", "failedToTogglePauseContainer": "נכשל ביצירת {{action}} של המכולה: {{error}}",
"containerRemoved": "מיכל {{error}} הוסר", "containerRemoved": "המיכל {{name}} הוסר",
"failedToRemoveContainer": "הסרת המיכל נכשלה: {{name}}", "failedToRemoveContainer": "נכשלה הסרת המיכל: {{error}}",
"image": "תְמוּנָה:", "image": "תְמוּנָה:",
"idLabel": "תְעוּדַת זֶהוּת:", "idLabel": "תְעוּדַת זֶהוּת:",
"ports": "יציאות:", "ports": "יציאות:",
@@ -1183,7 +1183,7 @@
"pause": "הַפסָקָה", "pause": "הַפסָקָה",
"restart": "הפעלה מחדש", "restart": "הפעלה מחדש",
"removeContainer": "הסר את המיכל", "removeContainer": "הסר את המיכל",
"confirmRemoveContainer": "האם אתה בטוח שברצונך להסיר את המיכל \"{{error}}\"?", "confirmRemoveContainer": "האם אתה בטוח שברצונך להסיר את המכולה \"{{name}}\"?",
"runningContainerWarning": "אזהרה: מיכל זה פועל כעת ויוסר בכוח.", "runningContainerWarning": "אזהרה: מיכל זה פועל כעת ויוסר בכוח.",
"removing": "הסרה:", "removing": "הסרה:",
"containerNotFound": "המיכל לא נמצא", "containerNotFound": "המיכל לא נמצא",
@@ -1191,7 +1191,7 @@
"logs": "יומני רישום", "logs": "יומני רישום",
"stats": "סטטיסטיקות", "stats": "סטטיסטיקות",
"consoleTab": "לְנַחֵם", "consoleTab": "לְנַחֵם",
"failedToFetchLogs": "נכשלה אחזור היומנים: {{name}}", "failedToFetchLogs": "נכשלה אחזור הלוגים: {{error}}",
"failedToDownloadLogs": "הורדת יומני רישום נכשלה: {{error}}", "failedToDownloadLogs": "הורדת יומני רישום נכשלה: {{error}}",
"linesToShow": "קווים להצגה", "linesToShow": "קווים להצגה",
"last50Lines": "50 השורות האחרונות", "last50Lines": "50 השורות האחרונות",
@@ -1219,7 +1219,7 @@
"reconnect": "התחבר מחדש", "reconnect": "התחבר מחדש",
"sessionEnded": "הסשן הסתיים", "sessionEnded": "הסשן הסתיים",
"connectionLost": "החיבור אבד", "connectionLost": "החיבור אבד",
"error": "שגיאה: {{error}}", "error": "שגיאה: {{message}}",
"disconnected": "מְנוּתָק", "disconnected": "מְנוּתָק",
"connectionClosed": "החיבור נסגר", "connectionClosed": "החיבור נסגר",
"connectionError": "שגיאת חיבור: {{message}}", "connectionError": "שגיאת חיבור: {{message}}",
@@ -1230,13 +1230,13 @@
"messageParseError": "נכשל בניתוח הודעת השרת", "messageParseError": "נכשל בניתוח הודעת השרת",
"websocketError": "שגיאת חיבור WebSocket", "websocketError": "שגיאת חיבור WebSocket",
"connecting": "מְקַשֵׁר...", "connecting": "מְקַשֵׁר...",
"reconnecting": "מתחבר מחדש... ({{message}}/{{attempt}})", "reconnecting": "מתחבר מחדש... ({{attempt}}/{{max}})",
"reconnected": "התחבר מחדש בהצלחה", "reconnected": "התחבר מחדש בהצלחה",
"maxReconnectAttemptsReached": "הגעת למספר המקסימלי של ניסיונות חיבור מחדש", "maxReconnectAttemptsReached": "הגעת למספר המקסימלי של ניסיונות חיבור מחדש",
"connectionTimeout": "זמן קצוב לחיבור", "connectionTimeout": "זמן קצוב לחיבור",
"terminalTitle": "טרמינל - {{max}}", "terminalTitle": "טרמינל - {{host}}",
"terminalWithPath": "טרמינל - {{host}}:{{host}}", "terminalWithPath": "טרמינל - {{host}}:{{path}}",
"runTitle": "ריצה {{path}} - {{command}}", "runTitle": "ריצה {{command}} - {{host}}",
"totpRequired": "נדרש אימות דו-שלבי", "totpRequired": "נדרש אימות דו-שלבי",
"totpCodeLabel": "קוד אימות", "totpCodeLabel": "קוד אימות",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
@@ -1254,26 +1254,26 @@
"uploadFile": "העלאת קובץ", "uploadFile": "העלאת קובץ",
"downloadFile": "הורדה", "downloadFile": "הורדה",
"extractArchive": "ארכיון תמצית", "extractArchive": "ארכיון תמצית",
"extractingArchive": "מחלץ את {{host}}...", "extractingArchive": "מחלץ {{name}}...",
"archiveExtractedSuccessfully": "{{name}} חולץ בהצלחה", "archiveExtractedSuccessfully": "{{name}} חולץ בהצלחה",
"extractFailed": "החילוץ נכשל", "extractFailed": "החילוץ נכשל",
"compressFile": "דחיסת קובץ", "compressFile": "דחיסת קובץ",
"compressFiles": "דחיסת קבצים", "compressFiles": "דחיסת קבצים",
"compressFilesDesc": "דחיסת {{name}} פריטים לתוך ארכיון", "compressFilesDesc": "דחיסת {{count}} פריטים לתוך ארכיון",
"archiveName": "שם הארכיון", "archiveName": "שם הארכיון",
"enterArchiveName": "הזן שם ארכיון...", "enterArchiveName": "הזן שם ארכיון...",
"compressionFormat": "פורמט דחיסה", "compressionFormat": "פורמט דחיסה",
"selectedFiles": "קבצים נבחרים", "selectedFiles": "קבצים נבחרים",
"andMoreFiles": "ועוד {{count}}...", "andMoreFiles": "ועוד {{count}} ...",
"compress": "לִדחוֹס", "compress": "לִדחוֹס",
"compressingFiles": "דחיסת {{count}} פריטים לתוך {{count}}...", "compressingFiles": "דחיסת {{count}} פריטים לתוך {{name}}...",
"filesCompressedSuccessfully": "{{name}} נוצר בהצלחה", "filesCompressedSuccessfully": "{{name}} נוצר בהצלחה",
"compressFailed": "הדחיסה נכשלה", "compressFailed": "הדחיסה נכשלה",
"edit": "לַעֲרוֹך", "edit": "לַעֲרוֹך",
"preview": "תצוגה מקדימה", "preview": "תצוגה מקדימה",
"previous": "קוֹדֵם", "previous": "קוֹדֵם",
"next": "הַבָּא", "next": "הַבָּא",
"pageXOfY": "עמוד {{name}} מתוך {{current}}", "pageXOfY": "עמוד {{current}} מתוך {{total}}",
"zoomOut": "התקרבות", "zoomOut": "התקרבות",
"zoomIn": "לְהִתְמַקֵד", "zoomIn": "לְהִתְמַקֵד",
"newFile": "קובץ חדש", "newFile": "קובץ חדש",
@@ -1289,13 +1289,13 @@
"chooseFile": "בחר קובץ", "chooseFile": "בחר קובץ",
"uploading": "מעלה...", "uploading": "מעלה...",
"downloading": "מוריד...", "downloading": "מוריד...",
"uploadingFile": "מעלה את {{total}}...", "uploadingFile": "מעלה {{name}}...",
"uploadingLargeFile": "מעלה קובץ גדול {{name}} ({{name}})...", "uploadingLargeFile": "מעלה קובץ גדול {{name}} ({{size}})...",
"downloadingFile": "מוריד את {{size}}...", "downloadingFile": "מוריד {{name}}...",
"creatingFile": "יוצר את {{name}}...", "creatingFile": "יוצר {{name}}...",
"creatingFolder": "יוצר את {{name}}...", "creatingFolder": "יוצר {{name}}...",
"deletingItem": "מוחק את {{name}} {{type}}...", "deletingItem": "מוחק {{type}} {{name}}...",
"renamingItem": "שינוי שם {{name}} {{type}} ל- {{oldName}}...", "renamingItem": "שינוי השם של {{type}} {{oldName}} ל- {{newName}}...",
"createNewFile": "צור קובץ חדש", "createNewFile": "צור קובץ חדש",
"fileName": "שם הקובץ", "fileName": "שם הקובץ",
"creating": "יוצר...", "creating": "יוצר...",
@@ -1311,7 +1311,7 @@
"newName": "שם חדש", "newName": "שם חדש",
"thisIsDirectoryRename": "זוהי ספרייה", "thisIsDirectoryRename": "זוהי ספרייה",
"renaming": "שינוי שם...", "renaming": "שינוי שם...",
"fileUploadedSuccessfully": "הקובץ \"{{newName}}\" הועלה בהצלחה", "fileUploadedSuccessfully": "הקובץ \"{{name}}\" הועלה בהצלחה",
"failedToUploadFile": "העלאת הקובץ נכשלה", "failedToUploadFile": "העלאת הקובץ נכשלה",
"fileDownloadedSuccessfully": "הקובץ \"{{name}}\" הורד בהצלחה", "fileDownloadedSuccessfully": "הקובץ \"{{name}}\" הורד בהצלחה",
"failedToDownloadFile": "הורדת הקובץ נכשלה", "failedToDownloadFile": "הורדת הקובץ נכשלה",
@@ -1319,18 +1319,18 @@
"filePath": "נתיב הקובץ", "filePath": "נתיב הקובץ",
"fileCreatedSuccessfully": "הקובץ \"{{name}}\" נוצר בהצלחה", "fileCreatedSuccessfully": "הקובץ \"{{name}}\" נוצר בהצלחה",
"failedToCreateFile": "יצירת הקובץ נכשלה", "failedToCreateFile": "יצירת הקובץ נכשלה",
"folderCreatedSuccessfully": "התיקייה \"{{name}}\" נוצרה בהצלחה", "folderCreatedSuccessfully": "תיקייה \"{{name}}\" נוצרה בהצלחה",
"failedToCreateFolder": "יצירת התיקייה נכשלה", "failedToCreateFolder": "יצירת התיקייה נכשלה",
"failedToCreateItem": "יצירת הפריט נכשלה", "failedToCreateItem": "יצירת הפריט נכשלה",
"operationFailed": "פעולת {{name}} נכשלה עבור {{operation}}: {{name}}", "operationFailed": "הפעולה {{operation}} נכשלה עבור {{name}}: {{error}}",
"failedToResolveSymlink": "נכשל בפענוח הסימבילינק", "failedToResolveSymlink": "נכשל בפענוח הקישור הסימלי",
"itemDeletedSuccessfully": "{{error}} נמחק בהצלחה", "itemDeletedSuccessfully": "{{type}} נמחק בהצלחה",
"itemsDeletedSuccessfully": "{{type}} פריטים נמחקו בהצלחה", "itemsDeletedSuccessfully": "{{count}} פריטים נמחקו בהצלחה",
"failedToDeleteItems": "מחיקת הפריטים נכשלה", "failedToDeleteItems": "מחיקת הפריטים נכשלה",
"dragFilesToUpload": "שחררו קבצים כאן כדי להעלות", "dragFilesToUpload": "שחררו קבצים כאן כדי להעלות",
"emptyFolder": "תיקייה זו ריקה", "emptyFolder": "תיקייה זו ריקה",
"itemCount": "פריטים", "itemCount": "פריטים {{count}}",
"selectedCount": "נבחרו", "selectedCount": "{{count}} נבחר",
"searchFiles": "חיפוש קבצים...", "searchFiles": "חיפוש קבצים...",
"upload": "העלאה", "upload": "העלאה",
"selectHostToStart": "בחר מארח כדי להתחיל בניהול קבצים", "selectHostToStart": "בחר מארח כדי להתחיל בניהול קבצים",
@@ -1347,25 +1347,25 @@
"delete": "לִמְחוֹק", "delete": "לִמְחוֹק",
"properties": "נכסים", "properties": "נכסים",
"refresh": "לְרַעֲנֵן", "refresh": "לְרַעֲנֵן",
"downloadFiles": "הורד קבצים לדפדפן", "downloadFiles": "הורד {{count}} קבצים לדפדפן",
"copyFiles": "העתקת {{count}} פריטים", "copyFiles": "העתקת {{count}} פריטים",
"cutFiles": "גזור {{count}} פריטים", "cutFiles": "גזור {{count}} פריטים",
"deleteFiles": "מחיקת {{count}} פריטים", "deleteFiles": "מחיקת {{count}} פריטים",
"filesCopiedToClipboard": "פריטים הועתקו ללוח", "filesCopiedToClipboard": "{{count}} פריטים הועתקו ללוח",
"filesCutToClipboard": "{{count}} פריטים נחתכו ללוח", "filesCutToClipboard": "{{count}} פריטים נחתכו ללוח",
"pathCopiedToClipboard": "הנתיב הועתק ללוח", "pathCopiedToClipboard": "הנתיב הועתק ללוח",
"pathsCopiedToClipboard": "{{count}} נתיבים הועתקו ללוח", "pathsCopiedToClipboard": "נתיבים {{count}} הועתקו ללוח",
"failedToCopyPath": "נכשלה העתקת הנתיב ללוח", "failedToCopyPath": "נכשלה העתקת הנתיב ללוח",
"movedItems": "הועברו {{count}} פריטים", "movedItems": "הועבר {{count}} פריטים",
"failedToDeleteItem": "מחיקת הפריט נכשלה", "failedToDeleteItem": "מחיקת הפריט נכשלה",
"itemRenamedSuccessfully": "שם השינוי של {{count}} הצליח", "itemRenamedSuccessfully": "שם השינוי של {{type}} הצליח",
"failedToRenameItem": "שינוי שם הפריט נכשל", "failedToRenameItem": "שינוי שם הפריט נכשל",
"download": "הורדה", "download": "הורדה",
"permissions": "הרשאות", "permissions": "הרשאות",
"size": "גוֹדֶל", "size": "גוֹדֶל",
"modified": "שונה", "modified": "שונה",
"path": "נָתִיב", "path": "נָתִיב",
"confirmDelete": "האם אתה בטוח שאתה רוצה למחוק את {{count}}?", "confirmDelete": "האם אתה בטוח שאתה רוצה למחוק {{name}}?",
"uploadSuccess": "הקובץ הועלה בהצלחה", "uploadSuccess": "הקובץ הועלה בהצלחה",
"uploadFailed": "העלאת הקובץ נכשלה", "uploadFailed": "העלאת הקובץ נכשלה",
"downloadSuccess": "הקובץ הורד בהצלחה", "downloadSuccess": "הקובץ הורד בהצלחה",
@@ -1388,10 +1388,10 @@
"connectToServer": "התחברות לשרת", "connectToServer": "התחברות לשרת",
"selectServerToEdit": "בחר שרת מסרגל הצד כדי להתחיל לערוך קבצים", "selectServerToEdit": "בחר שרת מסרגל הצד כדי להתחיל לערוך קבצים",
"fileOperations": "פעולות קבצים", "fileOperations": "פעולות קבצים",
"confirmDeleteMessage": "האם אתה בטוח שאתה רוצה למחוק את {{count}}?", "confirmDeleteMessage": "האם אתה בטוח שאתה רוצה למחוק {{name}}?",
"confirmDeleteSingleItem": "האם אתה בטוח שברצונך למחוק לצמיתות את \"{{count}}\"?", "confirmDeleteSingleItem": "האם אתה בטוח שברצונך למחוק לצמיתות את \"{{name}}\"?",
"confirmDeleteMultipleItems": "האם אתה בטוח שברצונך למחוק לצמיתות {{count}} פריטים?", "confirmDeleteMultipleItems": "האם אתה בטוח שברצונך למחוק לצמיתות {{count}} פריטים?",
"confirmDeleteMultipleItemsWithFolders": "האם אתה בטוח שברצונך למחוק לצמיתות את הפריטים {{type}}? זה כולל תיקיות ותוכן שלהן.", "confirmDeleteMultipleItemsWithFolders": "האם אתה בטוח שברצונך למחוק לצמיתות את הפריטים {{count}} ? זה כולל תיקיות ותוכן שלהן.",
"confirmDeleteFolder": "האם אתה בטוח שברצונך למחוק לצמיתות את התיקייה \"{{name}}\" ואת כל תוכנה?", "confirmDeleteFolder": "האם אתה בטוח שברצונך למחוק לצמיתות את התיקייה \"{{name}}\" ואת כל תוכנה?",
"deleteDirectoryWarning": "פעולה זו תמחק את התיקייה וכל תוכנה.", "deleteDirectoryWarning": "פעולה זו תמחק את התיקייה וכל תוכנה.",
"actionCannotBeUndone": "לא ניתן לבטל פעולה זו.", "actionCannotBeUndone": "לא ניתן לבטל פעולה זו.",
@@ -1421,18 +1421,18 @@
"selectLocationToSave": "בחר מיקום לשמירה", "selectLocationToSave": "בחר מיקום לשמירה",
"openTerminalInFolder": "פתח את הטרמינל בתיקייה זו", "openTerminalInFolder": "פתח את הטרמינל בתיקייה זו",
"openTerminalInFileLocation": "פתיחת מסוף במיקום הקובץ", "openTerminalInFileLocation": "פתיחת מסוף במיקום הקובץ",
"terminalWithPath": "טרמינל - {{name}}:{{name}}", "terminalWithPath": "טרמינל - {{host}}:{{path}}",
"runningFile": "ריצה - {{count}}", "runningFile": "ריצה - {{file}}",
"onlyRunExecutableFiles": "יכול להריץ רק קבצי הפעלה", "onlyRunExecutableFiles": "יכול להריץ רק קבצי הפעלה",
"noHostSelected": "לא נבחר מארח", "noHostSelected": "לא נבחר מארח",
"starred": "מסומן בכוכב", "starred": "מסומן בכוכב",
"shortcuts": "קיצורי דרך", "shortcuts": "קיצורי דרך",
"directories": "מדריכים", "directories": "מדריכים",
"removedFromRecentFiles": "הוסר \"{{count}}\" מהקבצים האחרונים", "removedFromRecentFiles": "הוסר \"{{name}}\" מהקבצים האחרונים",
"removeFailed": "ההסרה נכשלה", "removeFailed": "ההסרה נכשלה",
"unpinnedSuccessfully": "ביטול ההצמדה של \"{{name}}\" בוטל בהצלחה", "unpinnedSuccessfully": "ביטול ההצמדה של \"{{name}}\" בוטל בהצלחה",
"unpinFailed": "ביטול ההצמדה נכשל", "unpinFailed": "ביטול ההצמדה נכשל",
"removedShortcut": "קיצור הדרך \"{{host}}\" הוסר", "removedShortcut": "קיצור הדרך \"{{name}}\" הוסר",
"removeShortcutFailed": "הסרת קיצור הדרך נכשלה", "removeShortcutFailed": "הסרת קיצור הדרך נכשלה",
"clearedAllRecentFiles": "ניקה את כל הקבצים האחרונים", "clearedAllRecentFiles": "ניקה את כל הקבצים האחרונים",
"clearFailed": "ניקוי נכשל", "clearFailed": "ניקוי נכשל",
@@ -1440,16 +1440,16 @@
"clearAllRecentFiles": "נקה את כל הקבצים האחרונים", "clearAllRecentFiles": "נקה את כל הקבצים האחרונים",
"unpinFile": "ביטול הצמדת קובץ", "unpinFile": "ביטול הצמדת קובץ",
"removeShortcut": "הסר קיצור דרך", "removeShortcut": "הסר קיצור דרך",
"saveFilesToSystem": "שמור {{path}} קבצים כ...", "saveFilesToSystem": "שמור {{count}} קבצים בתור...",
"pinFile": "קובץ הצמדה", "pinFile": "קובץ הצמדה",
"addToShortcuts": "הוסף לקיצורי דרך", "addToShortcuts": "הוסף לקיצורי דרך",
"downloadToDefaultLocation": "הורדה למיקום ברירת המחדל", "downloadToDefaultLocation": "הורדה למיקום ברירת המחדל",
"pasteFailed": "ההדבקה נכשלה", "pasteFailed": "ההדבקה נכשלה",
"noUndoableActions": "אין פעולות שניתן לבטל", "noUndoableActions": "אין פעולות שניתן לבטל",
"undoCopySuccess": "פעולת העתקה שבוטלה: מחיקת {{file}} קבצים שהועתקו", "undoCopySuccess": "פעולת העתקה שבוטלה: מחיקת {{count}} קבצים שהועתקו",
"undoCopyFailedDelete": "ביטול נכשל: לא ניתן היה למחוק קבצים שהועתקו", "undoCopyFailedDelete": "ביטול נכשל: לא ניתן היה למחוק קבצים שהועתקו",
"undoCopyFailedNoInfo": "ביטול נכשל: לא ניתן היה למצוא את פרטי הקובץ שהועתק", "undoCopyFailedNoInfo": "ביטול נכשל: לא ניתן היה למצוא את פרטי הקובץ שהועתק",
"undoMoveSuccess": "פעולת העברה בוטלה: העבירו {{name}} קבצים בחזרה למיקום המקורי", "undoMoveSuccess": "פעולת העברה שבוטלה: העבירו {{count}} קבצים חזרה למיקום המקורי",
"undoMoveFailedMove": "ביטול נכשל: לא ניתן היה להעביר קבצים בחזרה", "undoMoveFailedMove": "ביטול נכשל: לא ניתן היה להעביר קבצים בחזרה",
"undoMoveFailedNoInfo": "ביטול נכשל: לא ניתן היה למצוא מידע על הקובץ שהועבר", "undoMoveFailedNoInfo": "ביטול נכשל: לא ניתן היה למצוא מידע על הקובץ שהועבר",
"undoDeleteNotSupported": "לא ניתן לבטל את פעולת המחיקה: הקבצים נמחקו לצמיתות מהשרת", "undoDeleteNotSupported": "לא ניתן לבטל את פעולת המחיקה: הקבצים נמחקו לצמיתות מהשרת",
@@ -1480,7 +1480,7 @@
"goToLine": "עבור אל שורה", "goToLine": "עבור אל שורה",
"moveLineUp": "הזזת שורה למעלה", "moveLineUp": "הזזת שורה למעלה",
"moveLineDown": "הזזת שורה למטה", "moveLineDown": "הזזת שורה למטה",
"toggleComment": "הפעלה/כיבוי תגובה", "toggleComment": חלף/הפעל תגובה",
"indent": "לְשַׁנֵן", "indent": "לְשַׁנֵן",
"outdent": "הזחה החוצה", "outdent": "הזחה החוצה",
"autoComplete": "השלמה אוטומטית", "autoComplete": "השלמה אוטומטית",
@@ -1491,33 +1491,33 @@
"unknownSize": "גודל לא ידוע", "unknownSize": "גודל לא ידוע",
"fileIsEmpty": "הקובץ ריק", "fileIsEmpty": "הקובץ ריק",
"largeFileWarning": "אזהרת קובץ גדול", "largeFileWarning": "אזהרת קובץ גדול",
"largeFileWarningDesc": "קובץ זה בגודל {{name}}, דבר שעשוי לגרום לבעיות ביצועים בעת פתיחה כטקסט.", "largeFileWarningDesc": "קובץ זה הוא בגודל {{size}} , דבר שעלול לגרום לבעיות ביצועים בעת פתיחתו כטקסט.",
"fileNotFoundAndRemoved": "הקובץ \"{{name}}\" לא נמצא והוסר מהקבצים האחרונים/המוצמדים", "fileNotFoundAndRemoved": "הקובץ \"{{name}}\" לא נמצא והוסר מהקבצים האחרונים/המוצמדים",
"failedToLoadFile": "טעינת הקובץ נכשלה: {{count}}", "failedToLoadFile": "טעינת הקובץ נכשלה: {{error}}",
"serverErrorOccurred": "אירעה שגיאת שרת. אנא נסה שוב מאוחר יותר.", "serverErrorOccurred": "אירעה שגיאת שרת. אנא נסה שוב מאוחר יותר.",
"autoSaveFailed": "השמירה האוטומטית נכשלה", "autoSaveFailed": "השמירה האוטומטית נכשלה",
"fileAutoSaved": "קובץ נשמר אוטומטית", "fileAutoSaved": "קובץ נשמר אוטומטית",
"moveFileFailed": "נכשל בהזזת {{count}}", "moveFileFailed": "נכשל בהזזת {{name}}",
"moveOperationFailed": "פעולת ההעברה נכשלה", "moveOperationFailed": "פעולת ההעברה נכשלה",
"canOnlyCompareFiles": "ניתן להשוות רק שני קבצים", "canOnlyCompareFiles": "ניתן להשוות רק שני קבצים",
"comparingFiles": "השוואת קבצים: {{count}} ו-{{size}}", "comparingFiles": "השוואת קבצים: {{file1}} ו- {{file2}}",
"dragFailed": "פעולת הגרירה נכשלה", "dragFailed": "פעולת הגרירה נכשלה",
"filePinnedSuccessfully": "הקובץ \"{{name}}\" הוצמד בהצלחה", "filePinnedSuccessfully": "הקובץ \"{{name}}\" הוצמד בהצלחה",
"pinFileFailed": "נכשל בהצמדת הקובץ", "pinFileFailed": "נכשל בהצמדת הקובץ",
"fileUnpinnedSuccessfully": "הקובץ \"{{error}}\" נותק בהצלחה", "fileUnpinnedSuccessfully": "הקובץ \"{{name}}\" נותק בהצלחה",
"unpinFileFailed": "נכשל ניתוק הקובץ", "unpinFileFailed": "נכשל ניתוק הקובץ",
"shortcutAddedSuccessfully": "קיצור הדרך לתיקייה \"{{name}}\" נוסף בהצלחה", "shortcutAddedSuccessfully": "קיצור דרך לתיקייה \"{{name}}\" נוסף בהצלחה",
"addShortcutFailed": "הוספת קיצור דרך נכשלה", "addShortcutFailed": "הוספת קיצור דרך נכשלה",
"operationCompletedSuccessfully": "פריטים {{file1}} {{file2}} בהצלחה", "operationCompletedSuccessfully": "{{operation}} {{count}} פריטים הצליחו",
"operationCompleted": "פריטים", "operationCompleted": "{{operation}} {{count}} פריטים",
"downloadFileSuccess": "קובץ {{name}} הורד בהצלחה", "downloadFileSuccess": "הקובץ {{name}} הורד בהצלחה",
"downloadFileFailed": "ההורדה נכשלה", "downloadFileFailed": "ההורדה נכשלה",
"moveTo": "העבר אל {{name}}", "moveTo": "מעבר אל {{name}}",
"diffCompareWith": "השוואה שונה עם {{name}}", "diffCompareWith": "השוואת הבדלים עם {{name}}",
"dragOutsideToDownload": "גרור את הקבצים אל מחוץ לחלון כדי להוריד אותם ({{operation}} קבצים)", "dragOutsideToDownload": "גרור את הקבצים אל מחוץ לחלון כדי להוריד אותם ({{count}} )",
"newFolderDefault": "תיקייה חדשה", "newFolderDefault": "תיקייה חדשה",
"newFileDefault": "קובץ חדש.txt", "newFileDefault": "קובץ חדש.txt",
"successfullyMovedItems": "הועבר בהצלחה {{count}} פריטים אל {{operation}}", "successfullyMovedItems": "הועבר בהצלחה {{count}} פריטים אל {{target}}",
"move": "מַהֲלָך", "move": "מַהֲלָך",
"searchInFile": "חיפוש בקובץ (Ctrl+F)", "searchInFile": "חיפוש בקובץ (Ctrl+F)",
"showKeyboardShortcuts": "הצג קיצורי מקלדת", "showKeyboardShortcuts": "הצג קיצורי מקלדת",
@@ -1527,10 +1527,10 @@
"compare": "לְהַשְׁווֹת", "compare": "לְהַשְׁווֹת",
"sideBySide": "זֶה בְּצַד זֶה", "sideBySide": "זֶה בְּצַד זֶה",
"inline": "מוטבע", "inline": "מוטבע",
"fileComparison": "השוואת קבצים: {{count}} לעומת {{name}}", "fileComparison": "השוואת קבצים: {{file1}} לעומת {{file2}}",
"fileTooLarge": "קובץ גדול מדי: {{name}}", "fileTooLarge": "קובץ גדול מדי: {{error}}",
"sshConnectionFailed": "חיבור SSH נכשל. אנא בדוק את החיבור שלך אל {{name}} ({{count}}:{{count}})", "sshConnectionFailed": "חיבור SSH נכשל. אנא בדוק את החיבור שלך אל {{name}} ({{ip}}:{{port}})",
"loadFileFailed": "טעינת הקובץ נכשלה: {{target}}", "loadFileFailed": "טעינת הקובץ נכשלה: {{error}}",
"connectedSuccessfully": "התחבר בהצלחה", "connectedSuccessfully": "התחבר בהצלחה",
"totpVerificationFailed": "אימות TOTP נכשל", "totpVerificationFailed": "אימות TOTP נכשל",
"verificationCodePrompt": "קוד אימות:", "verificationCodePrompt": "קוד אימות:",
@@ -1573,10 +1573,10 @@
"disconnect": "לְנַתֵק", "disconnect": "לְנַתֵק",
"cancel": "לְבַטֵל", "cancel": "לְבַטֵל",
"port": "נָמָל", "port": "נָמָל",
"attempt": "ניסיון {{file1}} מתוך {{file2}}", "attempt": "ניסיון {{current}} מתוך {{max}}",
"nextRetryIn": "ניסיון חוזר הבא בעוד {{error}} שניות", "nextRetryIn": "ניסיון חוזר הבא בעוד {{seconds}} שניות",
"checkDockerLogs": "בדוק את יומני ה-Docker שלך כדי למצוא את סיבת השגיאה, הצטרף ל-", "checkDockerLogs": "בדוק את יומני ה-Docker שלך כדי למצוא את סיבת השגיאה, הצטרף ל-",
"orCreate": "או ליצור", "orCreate": "או ליצור ",
"noTunnelConnections": "לא הוגדרו חיבורי מנהרה", "noTunnelConnections": "לא הוגדרו חיבורי מנהרה",
"tunnelConnections": "חיבורי מנהרה", "tunnelConnections": "חיבורי מנהרה",
"addTunnel": "הוסף מנהרה", "addTunnel": "הוסף מנהרה",
@@ -1598,7 +1598,7 @@
"remote": "מְרוּחָק", "remote": "מְרוּחָק",
"dynamic": "דִינָמִי", "dynamic": "דִינָמִי",
"unknownConnectionStatus": "לֹא יְדוּעַ", "unknownConnectionStatus": "לֹא יְדוּעַ",
"portMapping": "פורט {{name}} → {{ip}}:{{port}}", "portMapping": "פורט {{sourcePort}} → {{endpointHost}}:{{endpointPort}}",
"endpointHostNotFound": "מארח נקודת הקצה לא נמצא", "endpointHostNotFound": "מארח נקודת הקצה לא נמצא",
"discord": "מַחֲלוֹקֶת", "discord": "מַחֲלוֹקֶת",
"githubIssue": "בעיית GitHub", "githubIssue": "בעיית GitHub",
@@ -1611,7 +1611,7 @@
"disk": "דִיסק", "disk": "דִיסק",
"network": "רֶשֶׁת", "network": "רֶשֶׁת",
"uptime": "זמן פעולה", "uptime": "זמן פעולה",
"loadAverage": "ממוצע: {{error}}, {{current}}, {{max}}", "loadAverage": "ממוצע: {{avg1}}, {{avg5}}, {{avg15}}",
"processes": "תהליכים", "processes": "תהליכים",
"connections": "חיבורים", "connections": "חיבורים",
"usage": "נוֹהָג", "usage": "נוֹהָג",
@@ -1624,8 +1624,8 @@
"refreshStatus": "רענון סטטוס", "refreshStatus": "רענון סטטוס",
"fileManagerAlreadyOpen": "מנהל הקבצים כבר פתוח עבור מארח זה", "fileManagerAlreadyOpen": "מנהל הקבצים כבר פתוח עבור מארח זה",
"openFileManager": "פתח את מנהל הקבצים", "openFileManager": "פתח את מנהל הקבצים",
"cpuCores_one": "מעבד {{seconds}}", "cpuCores_one": "מעבד {{count}}",
"cpuCores_other": "מעבדים (CPUs)", "cpuCores_other": "מעבדים {{count}}",
"naCpus": "מעבדים לא רלוונטיים", "naCpus": "מעבדים לא רלוונטיים",
"loadAverageNA": "ממוצע: לא רלוונטי", "loadAverageNA": "ממוצע: לא רלוונטי",
"cpuUsage": "שימוש במעבד", "cpuUsage": "שימוש במעבד",
@@ -1645,12 +1645,12 @@
"cannotFetchMetrics": "לא ניתן לאחזר מדדים משרת לא מקוון", "cannotFetchMetrics": "לא ניתן לאחזר מדדים משרת לא מקוון",
"totpRequired": "נדרש אימות TOTP", "totpRequired": "נדרש אימות TOTP",
"totpUnavailable": "סטטיסטיקות שרת אינן זמינות עבור שרתים התומכים ב-TOTP", "totpUnavailable": "סטטיסטיקות שרת אינן זמינות עבור שרתים התומכים ב-TOTP",
"totpVerified": "TOTP אומת, איסוף המדדים החל", "totpVerified": "TOTP אומת, איסוף מדדים החל",
"totpFailed": "אימות TOTP נכשל", "totpFailed": "אימות TOTP נכשל",
"totpInvalidCode": "קוד אימות לא תקין", "totpInvalidCode": "קוד אימות לא תקין",
"totpCancelled": "איסוף המדדים בוטל", "totpCancelled": "איסוף המדדים בוטל",
"authenticationFailed": "האימות נכשל", "authenticationFailed": "האימות נכשל",
"noneAuthNotSupported": "סטטיסטיקות השרת אינן תומכות בסוג האימות 'ללא'.", "noneAuthNotSupported": "סטטיסטיקות השרת אינן תומכות בסוג אימות 'ללא'.",
"load": "לִטעוֹן", "load": "לִטעוֹן",
"editLayout": "עריכת פריסה", "editLayout": "עריכת פריסה",
"cancelEdit": "לְבַטֵל", "cancelEdit": "לְבַטֵל",
@@ -1678,11 +1678,11 @@
"noRecentLoginData": "אין נתוני התחברות אחרונים", "noRecentLoginData": "אין נתוני התחברות אחרונים",
"from": "מִן", "from": "מִן",
"quickActions": "פעולות מהירות", "quickActions": "פעולות מהירות",
"executeQuickAction": "בצע {{sourcePort}}", "executeQuickAction": "בצע {{name}}",
"executingQuickAction": "מבצע את {{endpointHost}}...", "executingQuickAction": "מבצע {{name}}...",
"quickActionSuccess": "{{endpointPort}} הושלם בהצלחה", "quickActionSuccess": "{{name}} הושלם בהצלחה",
"quickActionFailed": "{{avg1}} נכשל", "quickActionFailed": "{{name}} נכשל",
"quickActionError": "נכשל בביצוע {{avg5}}" "quickActionError": "נכשל בביצוע {{name}}"
}, },
"auth": { "auth": {
"tagline": "מנהל שרתי SSH", "tagline": "מנהל שרתי SSH",
@@ -1765,7 +1765,7 @@
"enableTwoFactorButton": "הפעל אימות דו-שלבי", "enableTwoFactorButton": "הפעל אימות דו-שלבי",
"addExtraSecurityLayer": "הוסף שכבת אבטחה נוספת לחשבונך", "addExtraSecurityLayer": "הוסף שכבת אבטחה נוספת לחשבונך",
"firstUser": "משתמש ראשון", "firstUser": "משתמש ראשון",
"firstUserMessage": "אתה המשתמש הראשון ותהפוך למנהל. תוכל לצפות בהגדרות מנהל המערכת בתפריט הנפתח של המשתמשים בסרגל הצד. אם אתה חושב שזו טעות, בדוק את יומני ה-docker או צור בעיה ב-GitHub.", "firstUserMessage": "אתה המשתמש הראשון ותהפוך למנהל. תוכל לצפות בהגדרות מנהל המערכת בתפריט הנפתח של המשתמש בסרגל הצד. אם אתה חושב שזו טעות, בדוק את יומני ה-docker או צור בעיה ב-GitHub.",
"external": "חִיצוֹנִי", "external": "חִיצוֹנִי",
"loginWithExternal": "התחברות עם ספק חיצוני", "loginWithExternal": "התחברות עם ספק חיצוני",
"loginWithExternalDesc": "התחבר באמצעות ספק הזהויות החיצוני שתצורתו נקבעה", "loginWithExternalDesc": "התחבר באמצעות ספק הזהויות החיצוני שתצורתו נקבעה",
@@ -1788,7 +1788,7 @@
"loggingInToDesktopAppViaWeb": "כניסה לאפליקציית שולחן העבודה דרך ממשק האינטרנט", "loggingInToDesktopAppViaWeb": "כניסה לאפליקציית שולחן העבודה דרך ממשק האינטרנט",
"loadingServer": "טוען שרת...", "loadingServer": "טוען שרת...",
"authenticating": "מאמת...", "authenticating": "מאמת...",
"dataLossWarning": "איפוס הסיסמה שלך בדרך זו ימחק את כל מארחי ה-SSH השמורים, פרטי הגישה ונתונים מוצפנים אחרים. לא ניתן לבטל פעולה זו. השתמש באפשרות זו רק אם שכחת את הסיסמה שלך ואינך מחובר.", "dataLossWarning": "איפוס הסיסמה שלך בדרך זו ימחק את כל מארחי ה-SSH השמורים, פרטי הגישה ונתונים מוצפנים אחרים. פעולה זו אינה ניתנת לביטול. השתמש באפשרות זו רק אם שכחת את הסיסמה שלך ואינך מחובר.",
"authenticationDisabled": "אימות מושבת", "authenticationDisabled": "אימות מושבת",
"authenticationDisabledDesc": "כל שיטות האימות מושבתות כעת. אנא צור קשר עם מנהל המערכת שלך.", "authenticationDisabledDesc": "כל שיטות האימות מושבתות כעת. אנא צור קשר עם מנהל המערכת שלך.",
"passwordResetSuccess": "איפוס הסיסמה הצליח", "passwordResetSuccess": "איפוס הסיסמה הצליח",
@@ -1814,8 +1814,8 @@
"invalidAuthUrl": "כתובת URL לא חוקית להרשאה התקבלה מה-backend", "invalidAuthUrl": "כתובת URL לא חוקית להרשאה התקבלה מה-backend",
"invalidInput": "קלט לא חוקי", "invalidInput": "קלט לא חוקי",
"requiredField": "שדה זה נדרש", "requiredField": "שדה זה נדרש",
"minLength": "אורך מינימלי הוא {{avg15}}", "minLength": "אורך מינימלי הוא {{min}}",
"maxLength": "האורך המקסימלי הוא {{count}}", "maxLength": "האורך המקסימלי הוא {{max}}",
"invalidEmail": "כתובת דוא\"ל לא חוקית", "invalidEmail": "כתובת דוא\"ל לא חוקית",
"passwordMismatch": "הסיסמאות אינן תואמות", "passwordMismatch": "הסיסמאות אינן תואמות",
"passwordLoginDisabled": "כניסה באמצעות שם משתמש/סיסמה מושבתת כעת", "passwordLoginDisabled": "כניסה באמצעות שם משתמש/סיסמה מושבתת כעת",
@@ -1835,7 +1835,7 @@
"updateError": "העדכון נכשל", "updateError": "העדכון נכשל",
"copySuccess": "הועתק ללוח", "copySuccess": "הועתק ללוח",
"copyError": "ההעתקה נכשלה", "copyError": "ההעתקה נכשלה",
"copiedToClipboard": "{{count}} הועתק ללוח", "copiedToClipboard": "{{item}} הועתק ללוח",
"connectionEstablished": "נוצר חיבור", "connectionEstablished": "נוצר חיבור",
"connectionClosed": "החיבור נסגר", "connectionClosed": "החיבור נסגר",
"reconnecting": "מתחבר מחדש...", "reconnecting": "מתחבר מחדש...",
@@ -1955,9 +1955,9 @@
"passwordRequired": "נדרשת סיסמה", "passwordRequired": "נדרשת סיסמה",
"failedToDeleteAccount": "מחיקת החשבון נכשלה", "failedToDeleteAccount": "מחיקת החשבון נכשלה",
"failedToMakeUserAdmin": "נכשל בהפיכת המשתמש למנהל", "failedToMakeUserAdmin": "נכשל בהפיכת המשתמש למנהל",
"userIsNowAdmin": "משתמש {{name}} הוא כעת מנהל", "userIsNowAdmin": "משתמש {{username}} הוא כעת מנהל",
"removeAdminConfirm": "האם אתה בטוח שברצונך להסיר את סטטוס המנהל מ-{{name}}?", "removeAdminConfirm": "האם אתה בטוח שברצונך להסיר את סטטוס המנהל מ- {{username}}?",
"deleteUserConfirm": "האם אתה בטוח שברצונך למחוק את המשתמש {{name}}? פעולה זו אינה ניתנת לביטול.", "deleteUserConfirm": "האם אתה בטוח שברצונך למחוק את המשתמש {{username}}? פעולה זו אינה ניתנת לביטול.",
"deleteAccount": "מחיקת חשבון", "deleteAccount": "מחיקת חשבון",
"closeDeleteAccount": "סגור מחק חשבון", "closeDeleteAccount": "סגור מחק חשבון",
"deleteAccountWarning": "לא ניתן לבטל פעולה זו. פעולה זו תמחק לצמיתות את חשבונך ואת כל הנתונים המשויכים.", "deleteAccountWarning": "לא ניתן לבטל פעולה זו. פעולה זו תמחק לצמיתות את חשבונך ואת כל הנתונים המשויכים.",
@@ -1997,7 +1997,7 @@
"error": "שְׁגִיאָה", "error": "שְׁגִיאָה",
"warning": "אַזהָרָה", "warning": "אַזהָרָה",
"deleteAccount": "מחיקת חשבון", "deleteAccount": "מחיקת חשבון",
"closeDeleteAccount": "סגור מחיקת חשבון", "closeDeleteAccount": "סגור מחק חשבון",
"cannotDeleteAccount": "לא ניתן למחוק חשבון", "cannotDeleteAccount": "לא ניתן למחוק חשבון",
"confirmPassword": "אשר סיסמה", "confirmPassword": "אשר סיסמה",
"deleting": "מוחק...", "deleting": "מוחק...",
@@ -2079,7 +2079,7 @@
"selectHostToStart": "בחר מארח כדי להתחיל את הפעלת הטרמינל שלך", "selectHostToStart": "בחר מארח כדי להתחיל את הפעלת הטרמינל שלך",
"limitedSupportMessage": "תמיכת האתר בנייד עדיין בעיצומה. השתמשו באפליקציה לנייד לחוויית משתמש טובה יותר.", "limitedSupportMessage": "תמיכת האתר בנייד עדיין בעיצומה. השתמשו באפליקציה לנייד לחוויית משתמש טובה יותר.",
"mobileAppInProgress": "אפליקציית מובייל נמצאת בתהליך פיתוח", "mobileAppInProgress": "אפליקציית מובייל נמצאת בתהליך פיתוח",
"mobileAppInProgressDesc": "אנחנו עובדים על אפליקציה ייעודית לנייד כדי לספק חוויית שימוש טובה יותר במכשירים ניידים.", "mobileAppInProgressDesc": "אנחנו עובדים על אפליקציה ייעודית למובייל כדי לספק חוויה טובה יותר במכשירים ניידים.",
"viewMobileAppDocs": "התקנת אפליקציה לנייד", "viewMobileAppDocs": "התקנת אפליקציה לנייד",
"mobileAppDocumentation": "תיעוד אפליקציה לנייד" "mobileAppDocumentation": "תיעוד אפליקציה לנייד"
}, },
@@ -2137,22 +2137,22 @@
"fullDesc": "אין הגבלות (לא מומלץ)" "fullDesc": "אין הגבלות (לא מומלץ)"
}, },
"blockedCommands": "פקודות חסומות", "blockedCommands": "פקודות חסומות",
"blockedCommandsPlaceholder": "הזן פקודות לחסימה, לדוגמה, passwd, rm, dd", "blockedCommandsPlaceholder": "הזן פקודות לחסימה, למשל, passwd, rm, dd",
"maxSessionDuration": "משך זמן מקסימלי של סשן (דקות)", "maxSessionDuration": "משך מקסימלי של סשן (בדקות)",
"createTempUser": "צור משתמש זמני", "createTempUser": "צור משתמש זמני",
"createTempUserDesc": "יוצר משתמש מוגבל בשרת במקום לשתף את פרטי הגישה שלך. דורש גישת sudo. האפשרות הבטוחה ביותר.", "createTempUserDesc": "יוצר משתמש מוגבל בשרת במקום לשתף את פרטי הגישה שלך. דורש גישת sudo. האפשרות הבטוחה ביותר.",
"expiresAt": "פג תוקף ב", "expiresAt": "פג תוקף ב",
"expiresIn": "פג תוקף בעוד {{name}} שעות", "expiresIn": "פג תוקף בעוד {{hours}} שעות",
"expired": "פג תוקף", "expired": "פג תוקף",
"grantedBy": "הוענק על ידי", "grantedBy": "הוענק על ידי",
"accessLevel": "רמת גישה", "accessLevel": "רמת גישה",
"lastAccessed": "גישה אחרונה", "lastAccessed": "גישה אחרונה",
"accessCount": "ספירת גישה", "accessCount": "ספירת גישה",
"revokeAccess": "ביטול גישה", "revokeAccess": "ביטול גישה",
"confirmRevokeAccess": "האם אתה בטוח שברצונך לבטל גישה עבור {{name}}?", "confirmRevokeAccess": "האם אתה בטוח שברצונך לבטל את הגישה עבור {{username}}?",
"hostSharedSuccessfully": "מארח שותף בהצלחה עם {{min}}", "hostSharedSuccessfully": "מארח שותף בהצלחה עם {{username}}",
"hostAccessUpdated": "גישת המארח עודכנה", "hostAccessUpdated": "גישת המארח עודכנה",
"failedToShareHost": "נכשל בשיתוף המארח", "failedToShareHost": "נכשל שיתוף המארח",
"accessRevokedSuccessfully": "הגישה בוטלה בהצלחה", "accessRevokedSuccessfully": "הגישה בוטלה בהצלחה",
"failedToRevokeAccess": "ביטול הגישה נכשל", "failedToRevokeAccess": "ביטול הגישה נכשל",
"shared": "מְשׁוּתָף", "shared": "מְשׁוּתָף",
@@ -2165,16 +2165,16 @@
"noAccessGranted": "לא הוענקה גישה למארח זה", "noAccessGranted": "לא הוענקה גישה למארח זה",
"noAccessGrantedMessage": "אף משתמש לא קיבל עדיין גישה למארח זה", "noAccessGrantedMessage": "אף משתמש לא קיבל עדיין גישה למארח זה",
"manageAccessFor": "ניהול גישה עבור", "manageAccessFor": "ניהול גישה עבור",
"totalAccessRecords": "רשומות גישה {{max}}", "totalAccessRecords": "{{count}} גישה לרשומות",
"neverAccessed": "לְעוֹלָם לֹא", "neverAccessed": "לְעוֹלָם לֹא",
"timesAccessed": "{{item}} פעמים", "timesAccessed": "{{count}} זמן/פעמים",
"daysRemaining": "{{username}} יום(ים)", "daysRemaining": "{{days}} day(s)",
"hoursRemaining": "שעה (225)", "hoursRemaining": "שעה/שעות {{hours}}",
"failedToFetchAccessList": "נכשלה אחזור רשימת הגישה", "failedToFetchAccessList": "נכשלה אחזור רשימת הגישה",
"currentAccess": "גישה נוכחית", "currentAccess": "גישה נוכחית",
"securityWarning": "אזהרת אבטחה", "securityWarning": "אזהרת אבטחה",
"securityWarningMessage": "שיתוף אישורים מעניק למשתמש גישה מלאה לביצוע כל פעולה בשרת, כולל שינוי סיסמאות ומחיקת קבצים. יש לשתף רק עם משתמשים מהימנים.", "securityWarningMessage": "שיתוף אישורים מעניק למשתמש גישה מלאה לביצוע כל פעולה בשרת, כולל שינוי סיסמאות ומחיקת קבצים. יש לשתף רק עם משתמשים מהימנים.",
"tempUserRecommended": "אנו ממליצים להפעיל את האפשרות 'צור משתמש זמני' לשיפור האבטחה.", "tempUserRecommended": "אנו ממליצים להפעיל את 'צור משתמש זמני' לשיפור האבטחה.",
"roleManagement": "ניהול תפקידים", "roleManagement": "ניהול תפקידים",
"manageRoles": "ניהול תפקידים", "manageRoles": "ניהול תפקידים",
"manageRolesFor": "ניהול תפקידים עבור {{username}}", "manageRolesFor": "ניהול תפקידים עבור {{username}}",
@@ -2184,9 +2184,9 @@
"permissions": "הרשאות", "permissions": "הרשאות",
"systemRole": "תפקיד המערכת", "systemRole": "תפקיד המערכת",
"customRole": "תפקיד מותאם אישית", "customRole": "תפקיד מותאם אישית",
"roleAssignedSuccessfully": "תפקיד שהוקצה ל-{{username}} בהצלחה", "roleAssignedSuccessfully": "תפקיד שהוקצה בהצלחה ל- {{username}}",
"failedToAssignRole": "הקצאת התפקיד נכשלה", "failedToAssignRole": "הקצאת התפקיד נכשלה",
"roleRemovedSuccessfully": "התפקיד הוסר בהצלחה מ-{{hours}}", "roleRemovedSuccessfully": "התפקיד הוסר בהצלחה מ- {{username}}",
"failedToRemoveRole": "הסרת התפקיד נכשלה", "failedToRemoveRole": "הסרת התפקיד נכשלה",
"cannotRemoveSystemRole": "לא ניתן להסיר את תפקיד המערכת", "cannotRemoveSystemRole": "לא ניתן להסיר את תפקיד המערכת",
"cannotShareWithSelf": "לא ניתן לשתף את המארח עם עצמך", "cannotShareWithSelf": "לא ניתן לשתף את המארח עם עצמך",
@@ -2214,7 +2214,7 @@
"terminateSession": "סיום סשן", "terminateSession": "סיום סשן",
"sessionTerminated": "הסשן הסתיים על ידי בעל המארח", "sessionTerminated": "הסשן הסתיים על ידי בעל המארח",
"sharedAccessExpired": "הגישה המשותפת שלך למארח זה פגה", "sharedAccessExpired": "הגישה המשותפת שלך למארח זה פגה",
"sharedAccessExpiresIn": "תוקף הגישה המשותפת פג בעוד {{username}} שעות", "sharedAccessExpiresIn": "תוקף הגישה המשותפת פג בעוד {{hours}} שעות",
"roles": { "roles": {
"label": "תפקידים", "label": "תפקידים",
"admin": "מְנַהֵל", "admin": "מְנַהֵל",
@@ -2244,15 +2244,15 @@
"failedToSaveRole": "שמירת התפקיד נכשלה", "failedToSaveRole": "שמירת התפקיד נכשלה",
"failedToDeleteRole": "מחיקת התפקיד נכשלה", "failedToDeleteRole": "מחיקת התפקיד נכשלה",
"roleDisplayNameRequired": "נדרש שם תצוגה של התפקיד", "roleDisplayNameRequired": "נדרש שם תצוגה של התפקיד",
"roleNameRequired": "נדרש שם תפקיד", "roleNameRequired": "שם תפקיד נדרש",
"roleNameHint": "השתמשו רק באותיות קטנות, מספרים, קווים תחתונים ומקפים", "roleNameHint": "השתמשו רק באותיות קטנות, מספרים, קווים תחתונים ומקפים",
"displayNamePlaceholder": "מפתח", "displayNamePlaceholder": "מפתח",
"descriptionPlaceholder": "מפתחי תוכנה ומהנדסים", "descriptionPlaceholder": "מפתחי תוכנה ומהנדסים",
"confirmDeleteRole": "מחיקת תפקיד", "confirmDeleteRole": "מחיקת תפקיד",
"confirmDeleteRoleDescription": "האם אתה בטוח שברצונך למחוק את התפקיד '{{username}}'? לא ניתן לבטל פעולה זו.", "confirmDeleteRoleDescription": "האם אתה בטוח שברצונך למחוק את התפקיד '{{name}}'? לא ניתן לבטל פעולה זו.",
"confirmRemoveRole": "הסר תפקיד", "confirmRemoveRole": "הסר תפקיד",
"confirmRemoveRoleDescription": "האם אתה בטוח שברצונך להסיר את התפקיד הזה מהמשתמש?", "confirmRemoveRoleDescription": "האם אתה בטוח שברצונך להסיר את התפקיד הזה מהמשתמש?",
"editRoleDescription": "עדכון פרטי תפקיד", "editRoleDescription": "עדכון פרטי התפקיד",
"createRoleDescription": "צור תפקיד מותאם אישית חדש לקיבוץ משתמשים", "createRoleDescription": "צור תפקיד מותאם אישית חדש לקיבוץ משתמשים",
"assignRolesDescription": "ניהול הקצאות תפקידים עבור משתמשים", "assignRolesDescription": "ניהול הקצאות תפקידים עבור משתמשים",
"noRoles": "לא נמצאו תפקידים", "noRoles": "לא נמצאו תפקידים",
@@ -2307,19 +2307,19 @@
"validating": "מאמת את Docker...", "validating": "מאמת את Docker...",
"connectingToHost": "מתחבר למארח...", "connectingToHost": "מתחבר למארח...",
"error": "שְׁגִיאָה", "error": "שְׁגִיאָה",
"errorCode": "קוד שגיאה: {{count}}", "errorCode": "קוד שגיאה: {{code}}",
"version": "דוקר {{count}}", "version": "דוקר {{version}}",
"containerStarted": "מיכל {{days}} הופעל", "containerStarted": "מיכל {{name}} הופעל",
"failedToStartContainer": "נכשל בהפעלת המכולה {{hours}}", "failedToStartContainer": "נכשל בהפעלת המכולה {{name}}",
"containerStopped": "מיכל {{username}} נעצר", "containerStopped": "מיכל {{name}} נעצר",
"failedToStopContainer": "נכשלה עצירת המכולה {{username}}", "failedToStopContainer": "נכשלה עצירת המכולה {{name}}",
"containerRestarted": "מיכל {{username}} הופעל מחדש", "containerRestarted": "מיכל {{name}} הופעל מחדש",
"failedToRestartContainer": "נכשל בהפעלה מחדש של המיכל {{hours}}", "failedToRestartContainer": "נכשלה ההפעלה מחדש של המכולה {{name}}",
"containerPaused": "מיכל {{name}} הושהה", "containerPaused": "מיכל {{name}} הושהה",
"containerUnpaused": "מיכל {{code}} בוטל", "containerUnpaused": "השהיית המיכל {{name}} בוטלה",
"failedToTogglePauseContainer": "נכשל בהחלפת מצב השהייה עבור המכולה {{version}}", "failedToTogglePauseContainer": "נכשל הניסיון להחליף את מצב ההשהיה עבור המכולה {{name}}",
"containerRemoved": "מיכל {{name}} הוסר", "containerRemoved": "המיכל {{name}} הוסר",
"failedToRemoveContainer": "הסרת המיכל {{name}} נכשלה", "failedToRemoveContainer": "נכשלה הסרת המיכל {{name}}",
"image": "תְמוּנָה", "image": "תְמוּנָה",
"idLabel": "תְעוּדַת זֶהוּת", "idLabel": "תְעוּדַת זֶהוּת",
"ports": "נמלים", "ports": "נמלים",
@@ -2340,8 +2340,8 @@
"noContainersFoundHint": "אין מכולות Docker זמינות במארח זה", "noContainersFoundHint": "אין מכולות Docker זמינות במארח זה",
"searchPlaceholder": "חיפוש מכולות...", "searchPlaceholder": "חיפוש מכולות...",
"filterByStatusPlaceholder": "סנן לפי סטטוס", "filterByStatusPlaceholder": "סנן לפי סטטוס",
"allContainersCount": "הכל ({{name}})", "allContainersCount": "הכל ({{count}})",
"statusCount": "{{name}} ({{name}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "אין מכולות התואמות את המסננים שלך", "noContainersMatchFilters": "אין מכולות התואמות את המסננים שלך",
"noContainersMatchFiltersHint": "נסה להתאים את קריטריוני החיפוש או הסינון שלך", "noContainersMatchFiltersHint": "נסה להתאים את קריטריוני החיפוש או הסינון שלך",
"containerMustBeRunningToViewStats": "יש להפעיל את המכולה כדי להציג נתונים סטטיסטיים", "containerMustBeRunningToViewStats": "יש להפעיל את המכולה כדי להציג נתונים סטטיסטיים",
@@ -2372,10 +2372,10 @@
"authenticationRequired": "נדרש אימות", "authenticationRequired": "נדרש אימות",
"verificationCodePrompt": "הזן קוד אימות", "verificationCodePrompt": "הזן קוד אימות",
"totpVerificationFailed": "אימות TOTP נכשל. אנא נסה שוב.", "totpVerificationFailed": "אימות TOTP נכשל. אנא נסה שוב.",
"connectedTo": "מחובר ל-{{name}}", "connectedTo": "מחובר אל {{containerName}}",
"disconnected": "מְנוּתָק", "disconnected": "מְנוּתָק",
"consoleError": "שגיאת קונסולה", "consoleError": "שגיאת קונסולה",
"errorMessage": "שגיאה: {{name}}", "errorMessage": "שגיאה: {{message}}",
"failedToConnect": "נכשל החיבור למכולה", "failedToConnect": "נכשל החיבור למכולה",
"console": "לְנַחֵם", "console": "לְנַחֵם",
"selectShell": "בחר מעטפת", "selectShell": "בחר מעטפת",
@@ -2387,7 +2387,7 @@
"disconnect": "לְנַתֵק", "disconnect": "לְנַתֵק",
"notConnected": "לא מחובר", "notConnected": "לא מחובר",
"clickToConnect": "לחץ על התחבר כדי להתחיל סשן מעטפת", "clickToConnect": "לחץ על התחבר כדי להתחיל סשן מעטפת",
"connectingTo": "מתחבר אל {{name}}...", "connectingTo": "מתחבר אל {{containerName}}...",
"containerNotFound": "המיכל לא נמצא", "containerNotFound": "המיכל לא נמצא",
"backToList": "חזרה לרשימה", "backToList": "חזרה לרשימה",
"logs": "יומני רישום", "logs": "יומני רישום",
@@ -2399,4 +2399,4 @@
"switchToLight": "מעבר לתאורה", "switchToLight": "מעבר לתאורה",
"switchToDark": "עבור למצב כהה" "switchToDark": "עבור למצב כהה"
} }
} }

View File

@@ -43,7 +43,7 @@
"refresh": "ताज़ा करना", "refresh": "ताज़ा करना",
"passwordRequired": "पासवर्ड आवश्यक है", "passwordRequired": "पासवर्ड आवश्यक है",
"sshKeyRequired": "SSH कुंजी आवश्यक है", "sshKeyRequired": "SSH कुंजी आवश्यक है",
"credentialAddedSuccessfully": "क्रेडेंशियल \"{{name}}\" सफलतापूर्वक जोड़ दिया गया", "credentialAddedSuccessfully": "क्रेडेंशियल \"{{name}}\" सफलतापूर्वक जोड़ा गया",
"general": "सामान्य", "general": "सामान्य",
"description": "विवरण", "description": "विवरण",
"folder": "फ़ोल्डर", "folder": "फ़ोल्डर",
@@ -128,7 +128,7 @@
"created": "बनाया था", "created": "बनाया था",
"lastModified": "अंतिम बार संशोधित", "lastModified": "अंतिम बार संशोधित",
"usageStatistics": "उपयोग के आँकड़े", "usageStatistics": "उपयोग के आँकड़े",
"copiedToClipboard": "{{field}} क्लिपबोर्ड पर कॉपी किया गया", "copiedToClipboard": "{{field}} क्लिपबोर्ड पर कॉपी हो गया",
"failedToCopy": "क्लिपबोर्ड पर कॉपी करने में विफल", "failedToCopy": "क्लिपबोर्ड पर कॉपी करने में विफल",
"sshKey": "एसएसएच कुंजी", "sshKey": "एसएसएच कुंजी",
"createCredentialDescription": "सुरक्षित पहुँच के लिए एक नया SSH क्रेडेंशियल बनाएँ", "createCredentialDescription": "सुरक्षित पहुँच के लिए एक नया SSH क्रेडेंशियल बनाएँ",
@@ -139,9 +139,9 @@
"confirmRemoveFromFolder": "क्या आप वाकई \"{{name}}\" को फ़ोल्डर \"{{folder}}\" से हटाना चाहते हैं? क्रेडेंशियल को \"अवर्गीकृत\" में स्थानांतरित कर दिया जाएगा।", "confirmRemoveFromFolder": "क्या आप वाकई \"{{name}}\" को फ़ोल्डर \"{{folder}}\" से हटाना चाहते हैं? क्रेडेंशियल को \"अवर्गीकृत\" में स्थानांतरित कर दिया जाएगा।",
"removedFromFolder": "क्रेडेंशियल \"{{name}}\" फ़ोल्डर से सफलतापूर्वक हटा दिया गया", "removedFromFolder": "क्रेडेंशियल \"{{name}}\" फ़ोल्डर से सफलतापूर्वक हटा दिया गया",
"failedToRemoveFromFolder": "फ़ोल्डर से क्रेडेंशियल हटाने में विफल।", "failedToRemoveFromFolder": "फ़ोल्डर से क्रेडेंशियल हटाने में विफल।",
"folderRenamed": "फ़ोल्डर \"{{oldName}}\" का नाम सफलतापूर्वक बदलकर \"{{newName}}\" कर दिया गया है", "folderRenamed": "फ़ोल्डर \"{{oldName}}\" का नाम बदलकर \"{{newName}}\" सफलतापूर्वक कर दिया गया है",
"failedToRenameFolder": "फ़ोल्डर का नाम बदलने में विफल", "failedToRenameFolder": "फ़ोल्डर का नाम बदलने में विफल",
"movedToFolder": "क्रेडेंशियल \"{{name}}\" को सफलतापूर्वक \"{{folder}}\" में स्थानांतरित कर दिया गया है।", "movedToFolder": "क्रेडेंशियल \"{{name}}\" सफलतापूर्वक \"{{folder}}\" में स्थानांतरित हो गया",
"failedToMoveToFolder": "क्रेडेंशियल को फ़ोल्डर में स्थानांतरित करने में विफल।", "failedToMoveToFolder": "क्रेडेंशियल को फ़ोल्डर में स्थानांतरित करने में विफल।",
"sshPublicKey": "एसएसएच सार्वजनिक कुंजी", "sshPublicKey": "एसएसएच सार्वजनिक कुंजी",
"publicKeyNote": "सार्वजनिक कुंजी वैकल्पिक है लेकिन कुंजी सत्यापन के लिए इसकी अनुशंसा की जाती है।", "publicKeyNote": "सार्वजनिक कुंजी वैकल्पिक है लेकिन कुंजी सत्यापन के लिए इसकी अनुशंसा की जाती है।",
@@ -189,7 +189,7 @@
"dragging": "खींचना {{fileName}}", "dragging": "खींचना {{fileName}}",
"preparing": "तैयारी {{fileName}}", "preparing": "तैयारी {{fileName}}",
"readySingle": "डाउनलोड करने के लिए तैयार {{fileName}}", "readySingle": "डाउनलोड करने के लिए तैयार {{fileName}}",
"readyMultiple": "{{count}} फ़ाइलें डाउनलोड करने के लिए तैयार हैं", "readyMultiple": "डाउनलोड करने के लिए तैयार {{count}} फ़ाइलें",
"batchDrag": "{{count}} फ़ाइलों को डेस्कटॉप पर खींचें", "batchDrag": "{{count}} फ़ाइलों को डेस्कटॉप पर खींचें",
"dragToDesktop": "डेस्कटॉप पर खींचें", "dragToDesktop": "डेस्कटॉप पर खींचें",
"canDragAnywhere": "आप फ़ाइलों को अपने डेस्कटॉप पर कहीं भी खींच सकते हैं।" "canDragAnywhere": "आप फ़ाइलों को अपने डेस्कटॉप पर कहीं भी खींच सकते हैं।"
@@ -202,7 +202,7 @@
"stopKeyRecording": "रिकॉर्डिंग रोकें", "stopKeyRecording": "रिकॉर्डिंग रोकें",
"selectTerminals": "टर्मिनल चुनें:", "selectTerminals": "टर्मिनल चुनें:",
"typeCommands": "कमांड टाइप करें (सभी कुंजियाँ समर्थित हैं):", "typeCommands": "कमांड टाइप करें (सभी कुंजियाँ समर्थित हैं):",
"commandsWillBeSent": "कमांड {{count}} चयनित टर्मिनल(ओं) को भेजे जाएंगे।", "commandsWillBeSent": "Commands will be sent to {{count}} selected terminal(s).",
"settings": "सेटिंग्स", "settings": "सेटिंग्स",
"enableRightClickCopyPaste": "दाएँ क्लिक करके कॉपी/पेस्ट करने की सुविधा चालू करें", "enableRightClickCopyPaste": "दाएँ क्लिक करके कॉपी/पेस्ट करने की सुविधा चालू करें",
"shareIdeas": "SSH टूल्स के लिए आगे क्या होना चाहिए, इस बारे में आपके पास कोई विचार हैं? उन्हें साझा करें।", "shareIdeas": "SSH टूल्स के लिए आगे क्या होना चाहिए, इस बारे में आपके पास कोई विचार हैं? उन्हें साझा करें।",
@@ -240,7 +240,7 @@
"failedToFetch": "स्निपेट लाने में विफल", "failedToFetch": "स्निपेट लाने में विफल",
"executeSuccess": "निष्पादन: {{name}}", "executeSuccess": "निष्पादन: {{name}}",
"copySuccess": "क्लिपबोर्ड पर \"{{name}}\" कॉपी किया गया", "copySuccess": "क्लिपबोर्ड पर \"{{name}}\" कॉपी किया गया",
"runTooltip": "इस कोड स्निपेट को टर्मिनल में चलाएँ।", "runTooltip": "टर्मिनल में इस कोड स्निपेट को चलाएँ।",
"copyTooltip": "इस अंश को क्लिपबोर्ड पर कॉपी करें", "copyTooltip": "इस अंश को क्लिपबोर्ड पर कॉपी करें",
"editTooltip": "इस अंश को संपादित करें", "editTooltip": "इस अंश को संपादित करें",
"deleteTooltip": "इस अंश को हटा दें", "deleteTooltip": "इस अंश को हटा दें",
@@ -280,7 +280,7 @@
"empty": "अभी तक कोई कमांड हिस्ट्री उपलब्ध नहीं है", "empty": "अभी तक कोई कमांड हिस्ट्री उपलब्ध नहीं है",
"emptyHint": "टर्मिनल का इतिहास बनाने के लिए सक्रिय टर्मिनल में कमांड निष्पादित करें।", "emptyHint": "टर्मिनल का इतिहास बनाने के लिए सक्रिय टर्मिनल में कमांड निष्पादित करें।",
"noResults": "कोई कमांड नहीं मिली", "noResults": "कोई कमांड नहीं मिली",
"noResultsHint": "\"{{query}}\" से मेल खाने वाल कोई कमांड नहीं है", "noResultsHint": "\"{{query}}\" से मेल खाने वाल कोई कमांड नहीं है",
"deleteSuccess": "कमांड इतिहास से हटा दी गई", "deleteSuccess": "कमांड इतिहास से हटा दी गई",
"deleteFailed": "कमांड को हटाने में विफलता।", "deleteFailed": "कमांड को हटाने में विफलता।",
"deleteTooltip": "डिलीट कमांड", "deleteTooltip": "डिलीट कमांड",
@@ -308,7 +308,7 @@
"cleared": "स्प्लिट स्क्रीन साफ़ हो गई", "cleared": "स्प्लिट स्क्रीन साफ़ हो गई",
"error": { "error": {
"noAssignments": "कृपया लेआउट में कम से कम एक टैब असाइन करें", "noAssignments": "कृपया लेआउट में कम से कम एक टैब असाइन करें",
"fillAllSlots": "आवेदन करने से पहले कृपया सभी {{count}} स्लॉट भरें" "fillAllSlots": "आवेदन करने से पहले कृपया सभी {{count}} रिक्त स्थान भरें"
} }
}, },
"homepage": { "homepage": {
@@ -333,7 +333,7 @@
"saveError": "कॉन्फ़िगरेशन सहेजने में त्रुटि", "saveError": "कॉन्फ़िगरेशन सहेजने में त्रुटि",
"saving": "सहेजा जा रहा है...", "saving": "सहेजा जा रहा है...",
"saveConfig": "कॉन्फ़िगरेशन सहेजें", "saveConfig": "कॉन्फ़िगरेशन सहेजें",
"helpText": "उस URL को दर्ज करें जहां आपका टर्मिक्स सर्वर चल रहा है (उदाहरण के लिए, http://localhost:30001 या https://your-server.com)", "helpText": "वह URL दर्ज करें जहां आपका टर्मिक्स सर्वर चल रहा है (उदाहरण के लिए, http://localhost:30001 या https://your-server.com)",
"warning": "चेतावनी", "warning": "चेतावनी",
"notValidatedWarning": "यूआरएल सत्यापित नहीं हुआ है - कृपया सुनिश्चित करें कि यह सही है।", "notValidatedWarning": "यूआरएल सत्यापित नहीं हुआ है - कृपया सुनिश्चित करें कि यह सही है।",
"changeServer": "सर्वर बदलें", "changeServer": "सर्वर बदलें",
@@ -343,10 +343,10 @@
"error": "संस्करण जाँच त्रुटि", "error": "संस्करण जाँच त्रुटि",
"checkFailed": "अपडेट की जाँच करने में विफल", "checkFailed": "अपडेट की जाँच करने में विफल",
"upToDate": "ऐप अपडेटेड है", "upToDate": "ऐप अपडेटेड है",
"currentVersion": "आप संस्करण {{version}} चला रहे हैं", "currentVersion": "आप संस्करण {{version}}चला रहे हैं",
"updateAvailable": "उपलब्ध अद्यतन", "updateAvailable": "उपलब्ध अद्यतन",
"newVersionAvailable": "एक नया संस्करण उपलब्ध है! आप {{current}} चला रहे हैं, लेकिन {{latest}} उपलब्ध है।", "newVersionAvailable": "एक नया संस्करण उपलब्ध है! आप {{current}}चला रहे हैं, लेकिन {{latest}} भी उपलब्ध है।",
"releasedOn": "{{date}} को जारी किया गया", "releasedOn": "{{date}}को जारी किया गया",
"downloadUpdate": "अपडेट डाउनलोड करें", "downloadUpdate": "अपडेट डाउनलोड करें",
"dismiss": "नकार देना", "dismiss": "नकार देना",
"checking": "अपडेट के लिए जांच कर रहा है...", "checking": "अपडेट के लिए जांच कर रहा है...",
@@ -498,7 +498,7 @@
"userManagement": "प्रयोक्ता प्रबंधन", "userManagement": "प्रयोक्ता प्रबंधन",
"makeAdmin": "व्यवस्थापक बनाएं", "makeAdmin": "व्यवस्थापक बनाएं",
"removeAdmin": "व्यवस्थापक को हटाएँ", "removeAdmin": "व्यवस्थापक को हटाएँ",
"deleteUser": "उपयोगकर्ता {{username}} को हटाएँ? इसे पूर्ववत नहीं किया जा सकता।", "deleteUser": "उपयोगकर्ता {{username}}को हटाएँ? इसे पूर्ववत नहीं किया जा सकता।",
"allowRegistration": "पंजीकरण की अनुमति दें", "allowRegistration": "पंजीकरण की अनुमति दें",
"oidcSettings": "ओआईडीसी सेटिंग्स", "oidcSettings": "ओआईडीसी सेटिंग्स",
"clientId": "क्लाइंट आईडी", "clientId": "क्लाइंट आईडी",
@@ -508,8 +508,8 @@
"tokenUrl": "टोकन यूआरएल", "tokenUrl": "टोकन यूआरएल",
"updateSettings": "सेटिंग्स अपडेट करें", "updateSettings": "सेटिंग्स अपडेट करें",
"confirmDelete": "क्या आप वाकई इस उपयोगकर्ता को हटाना चाहते हैं?", "confirmDelete": "क्या आप वाकई इस उपयोगकर्ता को हटाना चाहते हैं?",
"confirmMakeAdmin": "क्या आप वाकई {{username}} को व्यवस्थापक बनाना चाहते हैं?", "confirmMakeAdmin": "क्या आप वाकई {{username}} को एडमिन बनाना चाहते हैं?",
"confirmRemoveAdmin": "क्या आप वाकई {{username}} से व्यवस्थापक का दर्जा हटाना चाहते हैं?", "confirmRemoveAdmin": "क्या आप वाकई {{username}}से व्यवस्थापक का दर्जा हटाना चाहते हैं?",
"externalAuthentication": "बाह्य प्रमाणीकरण (OIDC)", "externalAuthentication": "बाह्य प्रमाणीकरण (OIDC)",
"configureExternalProvider": "OIDC/OAuth2 प्रमाणीकरण के लिए बाहरी पहचान प्रदाता को कॉन्फ़िगर करें।", "configureExternalProvider": "OIDC/OAuth2 प्रमाणीकरण के लिए बाहरी पहचान प्रदाता को कॉन्फ़िगर करें।",
"userIdentifierPath": "उपयोगकर्ता पहचानकर्ता पथ", "userIdentifierPath": "उपयोगकर्ता पहचानकर्ता पथ",
@@ -549,8 +549,8 @@
"enterUsernameToMakeAdmin": "व्यवस्थापक बनने के लिए उपयोगकर्ता नाम दर्ज करें", "enterUsernameToMakeAdmin": "व्यवस्थापक बनने के लिए उपयोगकर्ता नाम दर्ज करें",
"userIsNowAdmin": "उपयोगकर्ता {{username}} अब व्यवस्थापक है", "userIsNowAdmin": "उपयोगकर्ता {{username}} अब व्यवस्थापक है",
"failedToMakeUserAdmin": "उपयोगकर्ता को व्यवस्थापक बनाने में विफल", "failedToMakeUserAdmin": "उपयोगकर्ता को व्यवस्थापक बनाने में विफल",
"removeAdminStatus": "{{username}} से व्यवस्थापक का दर्जा हटाएँ?", "removeAdminStatus": "{{username}}से व्यवस्थापक का दर्जा हटाएँ?",
"adminStatusRemoved": "{{username}} से व्यवस्थापक का दर्जा हटा दिया गया है", "adminStatusRemoved": "{{username}}से व्यवस्थापक का दर्जा हटा दिया गया है",
"failedToRemoveAdminStatus": "व्यवस्थापक का दर्जा हटाने में विफल", "failedToRemoveAdminStatus": "व्यवस्थापक का दर्जा हटाने में विफल",
"userDeletedSuccessfully": "उपयोगकर्ता {{username}} सफलतापूर्वक हटा दिया गया", "userDeletedSuccessfully": "उपयोगकर्ता {{username}} सफलतापूर्वक हटा दिया गया",
"failedToDeleteUser": "उपयोगकर्ता को हटाने में विफल", "failedToDeleteUser": "उपयोगकर्ता को हटाने में विफल",
@@ -584,7 +584,7 @@
"passwordResetWarning": "किसी उपयोगकर्ता का पासवर्ड रीसेट करने से उनका सारा डेटा (SSH होस्ट, क्रेडेंशियल, सेटिंग्स) डिलीट हो जाएगा। इस कार्रवाई को पूर्ववत नहीं किया जा सकता है।", "passwordResetWarning": "किसी उपयोगकर्ता का पासवर्ड रीसेट करने से उनका सारा डेटा (SSH होस्ट, क्रेडेंशियल, सेटिंग्स) डिलीट हो जाएगा। इस कार्रवाई को पूर्ववत नहीं किया जा सकता है।",
"resetUserPassword": "उपयोगकर्ता पासवर्ड रीसेट करें", "resetUserPassword": "उपयोगकर्ता पासवर्ड रीसेट करें",
"resettingPassword": "रीसेट हो रहा है...", "resettingPassword": "रीसेट हो रहा है...",
"passwordResetInitiated": "{{username}} के लिए पासवर्ड रीसेट शुरू किया गया। रीसेट कोड भेजा गया।", "passwordResetInitiated": "{{username}}के लिए पासवर्ड रीसेट शुरू किया गया। रीसेट कोड भेजा गया।",
"failedToResetPassword": "पासवर्ड रीसेट शुरू करने में विफल", "failedToResetPassword": "पासवर्ड रीसेट शुरू करने में विफल",
"sessionManagement": "सत्र प्रबंधन", "sessionManagement": "सत्र प्रबंधन",
"revokeAllSessions": "सभी सत्र रद्द करें", "revokeAllSessions": "सभी सत्र रद्द करें",
@@ -611,12 +611,12 @@
"linkTargetUsernamePlaceholder": "पासवर्ड खाते का उपयोगकर्ता नाम दर्ज करें", "linkTargetUsernamePlaceholder": "पासवर्ड खाते का उपयोगकर्ता नाम दर्ज करें",
"linkAccountsButton": "खाते लिंक करें", "linkAccountsButton": "खाते लिंक करें",
"linkingAccounts": "लिंक हो रहा है...", "linkingAccounts": "लिंक हो रहा है...",
"accountsLinkedSuccessfully": "OIDC उपयोगकर्ता {{oidcUsername}} को {{targetUsername}} से जोड़ा गया है", "accountsLinkedSuccessfully": "OIDC उपयोगकर्ता {{oidcUsername}} को {{targetUsername}}से लिंक किया गया है",
"failedToLinkAccounts": "खातों को लिंक करने में विफल", "failedToLinkAccounts": "खातों को लिंक करने में विफल",
"linkTargetUsernameRequired": "लक्षित उपयोगकर्ता नाम आवश्यक है", "linkTargetUsernameRequired": "लक्षित उपयोगकर्ता नाम आवश्यक है",
"unlinkOIDCTitle": "OIDC प्रमाणीकरण को अनलिंक करें", "unlinkOIDCTitle": "OIDC प्रमाणीकरण को अनलिंक करें",
"unlinkOIDCDescription": "{{username}} से OIDC प्रमाणीकरण हटाएँ? इसके बाद उपयोगकर्ता केवल उपयोगकर्ता नाम/पासवर्ड से ही लॉगिन कर पाएगा।", "unlinkOIDCDescription": "{{username}}से OIDC प्रमाणीकरण हटाएँ? इसके बाद उपयोगकर्ता केवल उपयोगकर्ता नाम/पासवर्ड से ही लॉगिन कर पाएगा।",
"unlinkOIDCSuccess": "OIDC {{username}} से अनलिंक हो गया", "unlinkOIDCSuccess": "OIDC को {{username}}से अनलिंक कर दिया गया है",
"failedToUnlinkOIDC": "OIDC को अनलिंक करने में विफल", "failedToUnlinkOIDC": "OIDC को अनलिंक करने में विफल",
"databaseSecurity": "डेटाबेस सुरक्षा", "databaseSecurity": "डेटाबेस सुरक्षा",
"encryptionStatus": "एन्क्रिप्शन स्थिति", "encryptionStatus": "एन्क्रिप्शन स्थिति",
@@ -661,7 +661,7 @@
"loadingEncryptionStatus": "एन्क्रिप्शन स्थिति लोड हो रही है...", "loadingEncryptionStatus": "एन्क्रिप्शन स्थिति लोड हो रही है...",
"testMigrationDescription": "यह सुनिश्चित करें कि मौजूदा डेटा को बिना किसी बदलाव के सुरक्षित रूप से एन्क्रिप्टेड फॉर्मेट में माइग्रेट किया जा सकता है।", "testMigrationDescription": "यह सुनिश्चित करें कि मौजूदा डेटा को बिना किसी बदलाव के सुरक्षित रूप से एन्क्रिप्टेड फॉर्मेट में माइग्रेट किया जा सकता है।",
"serverMigrationGuide": "सर्वर माइग्रेशन गाइड", "serverMigrationGuide": "सर्वर माइग्रेशन गाइड",
"migrationInstructions": "एन्क्रिप्टेड डेटा को नए सर्वर पर माइग्रेट करने के लिए: 1) डेटाबेस फ़ाइलों का बैकअप लें, 2) नए सर्वर पर DB_ENCRYPTION_KEY=\"आपकी कुंजी\" नामक पर्यावरण चर सेट करें, 3) डेटाबेस फ़ाइलों को पुनर्स्थापित करें।", "migrationInstructions": "एन्क्रिप्टेड डेटा को नए सर्वर पर माइग्रेट करने के लिए: 1) डेटाबेस फ़ाइलों का बैकअप लें, 2) नए सर्वर पर DB_ENCRYPTION_KEY=\"your-key\" नामक पर्यावरण चर सेट करें, 3) डेटाबेस फ़ाइलों को पुनर्स्थापित करें।",
"environmentProtection": "पर्यावरण संरक्षण", "environmentProtection": "पर्यावरण संरक्षण",
"environmentProtectionDesc": "सर्वर परिवेश संबंधी जानकारी (होस्टनेम, पाथ आदि) के आधार पर एन्क्रिप्शन कुंजियों की सुरक्षा करता है, जिन्हें परिवेश चर के माध्यम से स्थानांतरित किया जा सकता है।", "environmentProtectionDesc": "सर्वर परिवेश संबंधी जानकारी (होस्टनेम, पाथ आदि) के आधार पर एन्क्रिप्शन कुंजियों की सुरक्षा करता है, जिन्हें परिवेश चर के माध्यम से स्थानांतरित किया जा सकता है।",
"verificationCompleted": "संगतता सत्यापन पूर्ण हो गया - कोई डेटा परिवर्तित नहीं हुआ", "verificationCompleted": "संगतता सत्यापन पूर्ण हो गया - कोई डेटा परिवर्तित नहीं हुआ",
@@ -743,7 +743,7 @@
"passwordLoginAndRegistrationDisabled": "पासवर्ड लॉगिन और नए खाते का पंजीकरण सफलतापूर्वक अक्षम कर दिया गया है।", "passwordLoginAndRegistrationDisabled": "पासवर्ड लॉगिन और नए खाते का पंजीकरण सफलतापूर्वक अक्षम कर दिया गया है।",
"requiresPasswordLogin": "पासवर्ड लॉगिन सक्षम होना आवश्यक है", "requiresPasswordLogin": "पासवर्ड लॉगिन सक्षम होना आवश्यक है",
"passwordLoginDisabledWarning": "पासवर्ड लॉगिन अक्षम है। सुनिश्चित करें कि OIDC ठीक से कॉन्फ़िगर किया गया है, अन्यथा आप Termix में लॉगिन नहीं कर पाएंगे।", "passwordLoginDisabledWarning": "पासवर्ड लॉगिन अक्षम है। सुनिश्चित करें कि OIDC ठीक से कॉन्फ़िगर किया गया है, अन्यथा आप Termix में लॉगिन नहीं कर पाएंगे।",
"oidcRequiredWarning": "महत्वपूर्ण: पासवर्ड लॉगिन अक्षम है। यदि आप OIDC को रीसेट या गलत तरीके से कॉन्फ़िगर करते हैं, तो आप Termix तक अपनी पहुँच खो देंगे और आपका इंस्टेंस खराब हो जाएगा। केवल तभी आगे बढ़ें जब आप पूरी तरह से आश्वस्त हों।", "oidcRequiredWarning": "गंभीर चेतावनी: पासवर्ड लॉगिन अक्षम है। यदि आप OIDC को रीसेट या गलत तरीके से कॉन्फ़िगर करते हैं, तो आप Termix तक पूरी पहुँच खो देंगे और आपका इंस्टेंस खराब हो जाएगा। केवल तभी आगे बढ़ें जब आप पूरी तरह से आश्वस्त हों।",
"confirmDisableOIDCWarning": "चेतावनी: आप पासवर्ड लॉगिन को अक्षम करते हुए OIDC को अक्षम करने जा रहे हैं। इससे आपका Termix इंस्टेंस पूरी तरह से क्षतिग्रस्त हो जाएगा और आप सभी एक्सेस खो देंगे। क्या आप आगे बढ़ना चाहते हैं?", "confirmDisableOIDCWarning": "चेतावनी: आप पासवर्ड लॉगिन को अक्षम करते हुए OIDC को अक्षम करने जा रहे हैं। इससे आपका Termix इंस्टेंस पूरी तरह से क्षतिग्रस्त हो जाएगा और आप सभी एक्सेस खो देंगे। क्या आप आगे बढ़ना चाहते हैं?",
"failedToUpdatePasswordLoginStatus": "पासवर्ड लॉगिन स्थिति अपडेट करने में विफल", "failedToUpdatePasswordLoginStatus": "पासवर्ड लॉगिन स्थिति अपडेट करने में विफल",
"loadingSessions": "सेशन लोड हो रहे हैं...", "loadingSessions": "सेशन लोड हो रहे हैं...",
@@ -785,15 +785,15 @@
"downloadSample": "नमूना डाउनलोड करें", "downloadSample": "नमूना डाउनलोड करें",
"formatGuide": "प्रारूप मार्गदर्शिका", "formatGuide": "प्रारूप मार्गदर्शिका",
"exportCredentialWarning": "चेतावनी: होस्ट \"{{name}}\" क्रेडेंशियल प्रमाणीकरण का उपयोग करता है। निर्यात की गई फ़ाइल में क्रेडेंशियल डेटा शामिल नहीं होगा और आयात के बाद इसे मैन्युअल रूप से पुनः कॉन्फ़िगर करना होगा। क्या आप जारी रखना चाहते हैं?", "exportCredentialWarning": "चेतावनी: होस्ट \"{{name}}\" क्रेडेंशियल प्रमाणीकरण का उपयोग करता है। निर्यात की गई फ़ाइल में क्रेडेंशियल डेटा शामिल नहीं होगा और आयात के बाद इसे मैन्युअल रूप से पुनः कॉन्फ़िगर करना होगा। क्या आप जारी रखना चाहते हैं?",
"exportSensitiveDataWarning": "चेतावनी: होस्ट \"{{name}}\" में संवेदनशील प्रमाणीकरण डेटा (पासवर्ड/एसएसएच कुंजी) शामिल है। निर्यात की गई फ़ाइल में यह डेटा सादे टेक्स्ट में होगा। कृपया फ़ाइल को सुरक्षित रखें और उपयोग के बाद इसे हटा दें। क्या आप जारी रखना चाहते हैं?", "exportSensitiveDataWarning": "चेतावनी: होस्ट \"{{name}}\" में संवेदनशील प्रमाणीकरण डेटा (पासवर्ड/एसएसएच कुंजी) मौजूद है। निर्यात की गई फ़ाइल में यह डेटा सादे टेक्स्ट में शामिल होगा। कृपया फ़ाइल को सुरक्षित रखें और उपयोग के बाद इसे हटा दें। क्या आप जारी रखना चाहते हैं?",
"uncategorized": "अवर्गीकृत", "uncategorized": "अवर्गीकृत",
"confirmDelete": "क्या आप वाकई \"{{name}}\" को हटाना चाहते हैं?", "confirmDelete": "क्या आप वाकई \"{{name}}\" को हटाना चाहते हैं?",
"failedToDeleteHost": "होस्ट को हटाने में विफल", "failedToDeleteHost": "होस्ट को हटाने में विफल",
"failedToExportHost": "होस्ट को निर्यात करने में विफलता। कृपया सुनिश्चित करें कि आप लॉग इन हैं और आपके पास होस्ट डेटा तक पहुंच है।", "failedToExportHost": "होस्ट को निर्यात करने में विफलता। कृपया सुनिश्चित करें कि आप लॉग इन हैं और आपके पास होस्ट डेटा तक पहुंच है।",
"jsonMustContainHosts": "JSON में एक \"होस्ट\" ऐरे होना चाहिए या वह होस्ट्स का ऐरे होना चाहिए।", "jsonMustContainHosts": "JSON में \"होस्ट\" ऐरे होना चाहिए या वह होस्ट्स का ऐरे होना चाहिए।",
"noHostsInJson": "JSON फ़ाइल में कोई होस्ट नहीं मिला", "noHostsInJson": "JSON फ़ाइल में कोई होस्ट नहीं मिला",
"maxHostsAllowed": "प्रति आयात अधिकतम 100 होस्ट की अनुमति है", "maxHostsAllowed": "प्रति आयात अधिकतम 100 होस्ट की अनुमति है",
"importCompleted": "आयात पूर्ण हुआ: {{success}} सफल, {{failed}} असफल", "importCompleted": "Import completed: {{success}} successful, {{failed}} failed",
"importFailed": "आयात विफल", "importFailed": "आयात विफल",
"importError": "आयात त्रुटि", "importError": "आयात त्रुटि",
"failedToImportJson": "JSON फ़ाइल आयात करने में विफल", "failedToImportJson": "JSON फ़ाइल आयात करने में विफल",
@@ -837,7 +837,7 @@
"connection": "संबंध", "connection": "संबंध",
"remove": "निकालना", "remove": "निकालना",
"sourcePort": "स्रोत पोर्ट", "sourcePort": "स्रोत पोर्ट",
"sourcePortDesc": "(स्रोत से तात्पर्य सामान्य टैब में वर्तमान कनेक्शन विवरण से है)", "sourcePortDesc": " (स्रोत से तात्पर्य सामान्य टैब में वर्तमान कनेक्शन विवरण से है)",
"endpointPort": "एंडपॉइंट पोर्ट", "endpointPort": "एंडपॉइंट पोर्ट",
"endpointSshConfig": "एंडपॉइंट एसएसएच कॉन्फ़िगरेशन", "endpointSshConfig": "एंडपॉइंट एसएसएच कॉन्फ़िगरेशन",
"tunnelForwardDescription": "यह टनल स्रोत मशीन पर पोर्ट {{sourcePort}} (सामान्य टैब में वर्तमान कनेक्शन विवरण) से एंडपॉइंट मशीन पर पोर्ट {{endpointPort}} तक ट्रैफ़िक अग्रेषित करेगा।", "tunnelForwardDescription": "यह टनल स्रोत मशीन पर पोर्ट {{sourcePort}} (सामान्य टैब में वर्तमान कनेक्शन विवरण) से एंडपॉइंट मशीन पर पोर्ट {{endpointPort}} तक ट्रैफ़िक अग्रेषित करेगा।",
@@ -848,7 +848,7 @@
"autoStartContainer": "कंटेनर लॉन्च होने पर ऑटो स्टार्ट", "autoStartContainer": "कंटेनर लॉन्च होने पर ऑटो स्टार्ट",
"autoStartDesc": "कंटेनर लॉन्च होने पर यह टनल स्वचालित रूप से शुरू हो जाएगी", "autoStartDesc": "कंटेनर लॉन्च होने पर यह टनल स्वचालित रूप से शुरू हो जाएगी",
"addConnection": "टनल कनेक्शन जोड़ें", "addConnection": "टनल कनेक्शन जोड़ें",
"sshpassRequired": "पासवर्ड प्रमाणीकरण के लिए एसएसएचपीएएसएस आवश्यक है", "sshpassRequired": "पासवर्ड प्रमाणीकरण के लिए एसएसएचपस आवश्यक है",
"sshpassRequiredDesc": "टनल में पासवर्ड प्रमाणीकरण के लिए, सिस्टम पर sshpass स्थापित होना आवश्यक है।", "sshpassRequiredDesc": "टनल में पासवर्ड प्रमाणीकरण के लिए, सिस्टम पर sshpass स्थापित होना आवश्यक है।",
"otherInstallMethods": "स्थापना के अन्य तरीके:", "otherInstallMethods": "स्थापना के अन्य तरीके:",
"debianUbuntuEquivalent": "(डेबियन/उबंटू) या आपके ऑपरेटिंग सिस्टम के लिए समकक्ष संस्करण।", "debianUbuntuEquivalent": "(डेबियन/उबंटू) या आपके ऑपरेटिंग सिस्टम के लिए समकक्ष संस्करण।",
@@ -916,10 +916,10 @@
"customCommandsDesc": "इस सर्वर के लिए कस्टम शटडाउन और रीबूट कमांड परिभाषित करें", "customCommandsDesc": "इस सर्वर के लिए कस्टम शटडाउन और रीबूट कमांड परिभाषित करें",
"shutdownCommand": "शटडाउन कमांड", "shutdownCommand": "शटडाउन कमांड",
"rebootCommand": "रिबूट कमांड", "rebootCommand": "रिबूट कमांड",
"confirmRemoveFromFolder": "क्या आप वाकई \"{{name}}\" को फ़ोल्डर \"{{folder}}\" से हटाना चाहते हैं? होस्ट को \"नो फ़ोल्डर\" में ले जाया जाएगा।", "confirmRemoveFromFolder": "क्या आप वाकई \"{{name}}\" को फ़ोल्डर \"{{folder}}\" से हटाना चाहते हैं? होस्ट को \"नो फ़ोल्डर\" में स्थानांतरित कर दिया जाएगा।",
"removedFromFolder": "होस्ट \"{{name}}\" फ़ोल्डर से सफलतापूर्वक हटा दिया गया", "removedFromFolder": "होस्ट \"{{name}}\" फ़ोल्डर से सफलतापूर्वक हटा दिया गया",
"failedToRemoveFromFolder": "फ़ोल्डर से होस्ट को हटाने में विफल", "failedToRemoveFromFolder": "फ़ोल्डर से होस्ट को हटाने में विफल",
"folderRenamed": "फ़ोल्डर \"{{oldName}}\" का नाम सफलतापूर्वक बदलकर \"{{newName}}\" कर दिया गया है", "folderRenamed": "फ़ोल्डर \"{{oldName}}\" का नाम बदलकर \"{{newName}}\" सफलतापूर्वक कर दिया गया है",
"failedToRenameFolder": "फ़ोल्डर का नाम बदलने में विफल", "failedToRenameFolder": "फ़ोल्डर का नाम बदलने में विफल",
"editFolderAppearance": "फ़ोल्डर का स्वरूप संपादित करें", "editFolderAppearance": "फ़ोल्डर का स्वरूप संपादित करें",
"editFolderAppearanceDesc": "फ़ोल्डर के लिए रंग और आइकन को अनुकूलित करें", "editFolderAppearanceDesc": "फ़ोल्डर के लिए रंग और आइकन को अनुकूलित करें",
@@ -929,10 +929,10 @@
"folderAppearanceUpdated": "फ़ोल्डर का स्वरूप सफलतापूर्वक अपडेट हो गया", "folderAppearanceUpdated": "फ़ोल्डर का स्वरूप सफलतापूर्वक अपडेट हो गया",
"failedToUpdateFolderAppearance": "फ़ोल्डर की दिखावट को अपडेट करने में विफलता", "failedToUpdateFolderAppearance": "फ़ोल्डर की दिखावट को अपडेट करने में विफलता",
"deleteAllHostsInFolder": "फ़ोल्डर में मौजूद सभी होस्ट को हटा दें", "deleteAllHostsInFolder": "फ़ोल्डर में मौजूद सभी होस्ट को हटा दें",
"confirmDeleteAllHostsInFolder": "क्या आप वाकई फोल्डर \"{{count}}\" में मौजूद सभी होस्ट को हटाना चाहते हैं? यह कार्रवाई पूर्ववत नहीं की जा सकती।", "confirmDeleteAllHostsInFolder": "क्या आप वाकई फोल्डर \"{{folder}}\" में मौजूद सभी {{count}} होस्ट को हटाना चाहते हैं? यह कार्रवाई पूर्ववत नहीं की जा सकती।",
"allHostsInFolderDeleted": "फ़ोल्डर \"{{folder}}\" से {{count}} होस्ट सफलतापूर्वक हटा दिए गए", "allHostsInFolderDeleted": "फ़ोल्डर \"{{folder}}\" से {{count}} होस्ट सफलतापूर्वक हटा दिए गए",
"failedToDeleteHostsInFolder": "फ़ोल्डर में होस्ट को हटाने में विफल रहा", "failedToDeleteHostsInFolder": "फ़ोल्डर में होस्ट को हटाने में विफल रहा",
"movedToFolder": "होस्ट \"{{folder}}\" सफलतापूर्वक \"{{name}}\" पर स्थानांतरित हो गया", "movedToFolder": "होस्ट \"{{name}}\" सफलतापूर्वक \"{{folder}}\" पर स्थानांतरित हो गया",
"failedToMoveToFolder": "होस्ट को फ़ोल्डर में ले जाने में विफल", "failedToMoveToFolder": "होस्ट को फ़ोल्डर में ले जाने में विफल",
"clickToRenameFolder": "फ़ोल्डर का नाम बदलने के लिए क्लिक करें", "clickToRenameFolder": "फ़ोल्डर का नाम बदलने के लिए क्लिक करें",
"renameFolder": "फ़ोल्डर का नाम बदलें", "renameFolder": "फ़ोल्डर का नाम बदलें",
@@ -943,7 +943,7 @@
"cloneHostTooltip": "क्लोन होस्ट", "cloneHostTooltip": "क्लोन होस्ट",
"clickToEditHost": "होस्ट को संपादित करने के लिए क्लिक करें", "clickToEditHost": "होस्ट को संपादित करने के लिए क्लिक करें",
"dragToMoveBetweenFolders": "फ़ोल्डरों के बीच जाने के लिए ड्रैग करें", "dragToMoveBetweenFolders": "फ़ोल्डरों के बीच जाने के लिए ड्रैग करें",
"exportedHostConfig": "{{folder}} के लिए निर्यातित होस्ट कॉन्फ़िगरेशन", "exportedHostConfig": "{{name}}के लिए निर्यातित होस्ट कॉन्फ़िगरेशन",
"openTerminal": "टर्मिनल खोलें", "openTerminal": "टर्मिनल खोलें",
"openFileManager": "फ़ाइल प्रबंधक खोलें", "openFileManager": "फ़ाइल प्रबंधक खोलें",
"openTunnels": "खुली सुरंगें", "openTunnels": "खुली सुरंगें",
@@ -961,7 +961,7 @@
"metricsEnabled": "मैट्रिक्स मॉनिटरिंग सक्षम करें", "metricsEnabled": "मैट्रिक्स मॉनिटरिंग सक्षम करें",
"metricsEnabledDesc": "सीपीयू, रैम, डिस्क और अन्य सिस्टम सांख्यिकी एकत्र करें", "metricsEnabledDesc": "सीपीयू, रैम, डिस्क और अन्य सिस्टम सांख्यिकी एकत्र करें",
"metricsInterval": "मैट्रिक्स संग्रह अंतराल", "metricsInterval": "मैट्रिक्स संग्रह अंतराल",
"metricsIntervalDesc": "सर्वर सांख्यिकी कितनी बार एकत्र करें (5 सेकंड - 1 घंटा)", "metricsIntervalDesc": "सर्वर सांख्यिकी को कितनी बार एकत्र करना है (5 सेकंड - 1 घंटा)",
"intervalSeconds": "सेकंड", "intervalSeconds": "सेकंड",
"intervalMinutes": "मिनट", "intervalMinutes": "मिनट",
"intervalValidation": "निगरानी अंतराल 5 सेकंड और 1 घंटे (3600 सेकंड) के बीच होना चाहिए।", "intervalValidation": "निगरानी अंतराल 5 सेकंड और 1 घंटे (3600 सेकंड) के बीच होना चाहिए।",
@@ -982,13 +982,13 @@
"selectFont": "फ़ॉन्ट चुनें", "selectFont": "फ़ॉन्ट चुनें",
"selectFontDesc": "टर्मिनल में उपयोग करने के लिए फ़ॉन्ट का चयन करें", "selectFontDesc": "टर्मिनल में उपयोग करने के लिए फ़ॉन्ट का चयन करें",
"fontSize": "फ़ॉन्ट आकार", "fontSize": "फ़ॉन्ट आकार",
"fontSizeValue": "फ़ॉन्ट का आकार: {{name}}px", "fontSizeValue": "फ़ॉन्ट आकार: {{value}}px",
"adjustFontSize": "टर्मिनल फ़ॉन्ट का आकार समायोजित करें", "adjustFontSize": "टर्मिनल फ़ॉन्ट का आकार समायोजित करें",
"letterSpacing": "पत्र अंतराल", "letterSpacing": "पत्र अंतराल",
"letterSpacingValue": "अक्षरों के बीच की दूरी: {{value}}px", "letterSpacingValue": "अक्षरों के बीच की दूरी: {{value}}px",
"adjustLetterSpacing": "अक्षरों के बीच की दूरी समायोजित करें", "adjustLetterSpacing": "अक्षरों के बीच की दूरी समायोजित करें",
"lineHeight": "ऊंची लाईन", "lineHeight": "ऊंची लाईन",
"lineHeightValue": "पंक्ति की ऊँचाई: {{value}}", "lineHeightValue": "लाइन की ऊँचाई: {{value}}",
"adjustLineHeight": "पंक्तियों के बीच की दूरी समायोजित करें", "adjustLineHeight": "पंक्तियों के बीच की दूरी समायोजित करें",
"cursorStyle": "कर्सर शैली", "cursorStyle": "कर्सर शैली",
"selectCursorStyle": "कर्सर शैली का चयन करें", "selectCursorStyle": "कर्सर शैली का चयन करें",
@@ -997,7 +997,7 @@
"cursorStyleBar": "छड़", "cursorStyleBar": "छड़",
"chooseCursorAppearance": "कर्सर का स्वरूप चुनें", "chooseCursorAppearance": "कर्सर का स्वरूप चुनें",
"cursorBlink": "कर्सर ब्लिंक", "cursorBlink": "कर्सर ब्लिंक",
"enableCursorBlink": "कर्सर ब्लिंकिंग एनीमेशन को सक्षम करें", "enableCursorBlink": "कर्सर ब्लिंकिंग एनीमेशन सक्षम करें",
"scrollbackBuffer": "स्क्रॉलबैक बफर", "scrollbackBuffer": "स्क्रॉलबैक बफर",
"scrollbackBufferValue": "स्क्रॉलबैक बफर: {{value}} पंक्तियाँ", "scrollbackBufferValue": "स्क्रॉलबैक बफर: {{value}} पंक्तियाँ",
"scrollbackBufferDesc": "स्क्रॉलबैक इतिहास में रखी जाने वाली पंक्तियों की संख्या", "scrollbackBufferDesc": "स्क्रॉलबैक इतिहास में रखी जाने वाली पंक्तियों की संख्या",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "आवाज़", "bellStyleSound": "आवाज़",
"bellStyleVisual": "तस्वीर", "bellStyleVisual": "तस्वीर",
"bellStyleBoth": "दोनों", "bellStyleBoth": "दोनों",
"bellStyleDesc": "टर्मिनल बेल (BEL कैरेक्टर, \\x07) को कैसे हैंडल करें। प्रोग्राम कार्य पूरा होने, त्रुटियाँ आने या सूचनाओं के लिए इसे ट्रिगर करते हैं। \"साउंड\" एक ऑडियो बीप बजाता है, \"विजुअल\" स्क्रीन को थोड़ी देर के लिए फ्लैश करता है, \"बोथ\" दोनों करता है, और \"नन\" बेल अलर्ट को निष्क्रिय कर देता है।", "bellStyleDesc": "टर्मिनल बेल (BEL कैरेक्टर, \\x07) को कैसे हैंडल करें। प्रोग्राम कार्य पूरा होने पर, त्रुटियाँ आने पर या सूचनाओं के लिए इसे ट्रिगर करते हैं। \"साउंड\" एक ऑडियो बीप बजाता है, \"विजुअल\" स्क्रीन को थोड़ी देर के लिए फ्लैश करता है, \"बोथ\" दोनों करता है, और \"नन\" बेल अलर्ट को डिसेबल कर देता है।",
"rightClickSelectsWord": "दायाँ क्लिक करने पर वर्ड का चयन होता है", "rightClickSelectsWord": "दायाँ क्लिक करने पर वर्ड का चयन होता है",
"rightClickSelectsWordDesc": "दाएँ क्लिक करने से कर्सर के नीचे का शब्द चयनित हो जाता है।", "rightClickSelectsWordDesc": "दाएँ क्लिक करने से कर्सर के नीचे का शब्द चयनित हो जाता है।",
"fastScrollModifier": "फास्ट स्क्रॉल मॉडिफायर", "fastScrollModifier": "फास्ट स्क्रॉल मॉडिफायर",
@@ -1066,7 +1066,7 @@
"socks5UsePreset": "सहेजे गए प्रीसेट का उपयोग करें", "socks5UsePreset": "सहेजे गए प्रीसेट का उपयोग करें",
"socks5SelectPreset": "प्रीसेट चुनें", "socks5SelectPreset": "प्रीसेट चुनें",
"socks5ManagePresets": "प्रीसेट प्रबंधित करें", "socks5ManagePresets": "प्रीसेट प्रबंधित करें",
"socks5ProxyNode": "प्रॉक्सी {{value}}", "socks5ProxyNode": "प्रॉक्सी {{number}}",
"socks5AddProxy": "चेन में प्रॉक्सी जोड़ें", "socks5AddProxy": "चेन में प्रॉक्सी जोड़ें",
"socks5RemoveProxy": "प्रॉक्सी हटाएं", "socks5RemoveProxy": "प्रॉक्सी हटाएं",
"socks5ProxyType": "प्रॉक्सी प्रकार", "socks5ProxyType": "प्रॉक्सी प्रकार",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "प्रॉक्सी चेन प्रीसेट बनाया गया", "socks5PresetCreated": "प्रॉक्सी चेन प्रीसेट बनाया गया",
"socks5PresetUpdated": "प्रॉक्सी चेन प्रीसेट अपडेट किया गया", "socks5PresetUpdated": "प्रॉक्सी चेन प्रीसेट अपडेट किया गया",
"socks5PresetDeleted": "प्रॉक्सी चेन प्रीसेट हटा दिया गया", "socks5PresetDeleted": "प्रॉक्सी चेन प्रीसेट हटा दिया गया",
"socks5PresetSaved": "प्रीसेट \"{{number}}\" सफलतापूर्वक सहेजा गया", "socks5PresetSaved": "प्रीसेट \"{{name}}\" सफलतापूर्वक सहेजा गया",
"socks5PresetSaveError": "प्रीसेट सहेजने में विफल", "socks5PresetSaveError": "प्रीसेट सहेजने में विफल",
"socks5PresetNameRequired": "प्रीसेट नाम आवश्यक है", "socks5PresetNameRequired": "प्रीसेट नाम आवश्यक है",
"socks5EmptyChainError": "खाली प्रॉक्सी चेन को सहेजा नहीं जा सकता", "socks5EmptyChainError": "खाली प्रॉक्सी चेन को सहेजा नहीं जा सकता",
@@ -1086,7 +1086,7 @@
"socks5HostDescription": "SOCKS प्रॉक्सी सर्वर का होस्टनाम या IP पता", "socks5HostDescription": "SOCKS प्रॉक्सी सर्वर का होस्टनाम या IP पता",
"socks5PortDescription": "SOCKS प्रॉक्सी सर्वर का पोर्ट नंबर (डिफ़ॉल्ट: 1080)", "socks5PortDescription": "SOCKS प्रॉक्सी सर्वर का पोर्ट नंबर (डिफ़ॉल्ट: 1080)",
"addProxyNode": "प्रॉक्सी नोड जोड़ें", "addProxyNode": "प्रॉक्सी नोड जोड़ें",
"noProxyNodes": "कोई प्रॉक्सी नोड कॉन्फ़िगर नहीं किया गया है। एक प्रॉक्सी नोड जोड़ने के लिए \"प्रॉक्सी नोड जोड़ें\" पर क्लिक करें।", "noProxyNodes": "कोई प्रॉक्सी नोड कॉन्फ़िगर नहीं किया गया है। एक प्रॉक्सी नोड जोड़ने के लिए 'प्रॉक्सी नोड जोड़ें' पर क्लिक करें।",
"proxyNode": "प्रॉक्सी नोड", "proxyNode": "प्रॉक्सी नोड",
"proxyType": "प्रॉक्सी प्रकार", "proxyType": "प्रॉक्सी प्रकार",
"quickActions": "त्वरित कार्रवाइयां", "quickActions": "त्वरित कार्रवाइयां",
@@ -1118,8 +1118,8 @@
"notEnabled": "इस होस्ट के लिए डॉकर सक्षम नहीं है। डॉकर सुविधाओं का उपयोग करने के लिए इसे होस्ट सेटिंग्स में सक्षम करें।", "notEnabled": "इस होस्ट के लिए डॉकर सक्षम नहीं है। डॉकर सुविधाओं का उपयोग करने के लिए इसे होस्ट सेटिंग्स में सक्षम करें।",
"validating": "डॉकर का सत्यापन किया जा रहा है...", "validating": "डॉकर का सत्यापन किया जा रहा है...",
"error": "गलती", "error": "गलती",
"errorCode": "त्रुटि कोड: {{name}}", "errorCode": "त्रुटि कोड: {{code}}",
"version": "डॉकर v{{code}}", "version": "डॉकर v{{version}}",
"current": "मौजूदा", "current": "मौजूदा",
"used_limit": "उपयोग किया गया / सीमा", "used_limit": "उपयोग किया गया / सीमा",
"percentage": "को PERCENTAGE", "percentage": "को PERCENTAGE",
@@ -1133,10 +1133,10 @@
"console": "सांत्वना देना", "console": "सांत्वना देना",
"containerMustBeRunning": "कंसोल से कनेक्ट करने के लिए कंटेनर का चालू होना आवश्यक है।", "containerMustBeRunning": "कंसोल से कनेक्ट करने के लिए कंटेनर का चालू होना आवश्यक है।",
"authenticationRequired": "प्रमाणित करना", "authenticationRequired": "प्रमाणित करना",
"connectedTo": "{{version}} से जुड़ा हुआ है", "connectedTo": "{{containerName}}से जुड़ा हुआ",
"disconnected": "डिस्कनेक्ट किया गया", "disconnected": "डिस्कनेक्ट किया गया",
"consoleError": "कंसोल त्रुटि", "consoleError": "कंसोल त्रुटि",
"errorMessage": "त्रुटि: {{containerName}}", "errorMessage": "त्रुटि: {{message}}",
"failedToConnect": "कंसोल से कनेक्ट करने में विफल", "failedToConnect": "कंसोल से कनेक्ट करने में विफल",
"disconnectedFromContainer": "कंटेनर कंसोल से संपर्क टूट गया।", "disconnectedFromContainer": "कंटेनर कंसोल से संपर्क टूट गया।",
"containerNotRunning": "कंटेनर नहीं चल रहा है", "containerNotRunning": "कंटेनर नहीं चल रहा है",
@@ -1150,28 +1150,28 @@
"disconnect": "डिस्कनेक्ट", "disconnect": "डिस्कनेक्ट",
"notConnected": "जुड़े नहीं हैं", "notConnected": "जुड़े नहीं हैं",
"clickToConnect": "इंटरेक्टिव शेल शुरू करने के लिए कनेक्ट पर क्लिक करें", "clickToConnect": "इंटरेक्टिव शेल शुरू करने के लिए कनेक्ट पर क्लिक करें",
"connectingTo": "{{message}} से कनेक्ट हो रहा है...", "connectingTo": "{{containerName}}से कनेक्ट हो रहा है...",
"containerMustBeRunningToViewStats": "आंकड़े देखने के लिए कंटेनर का चालू होना आवश्यक है।", "containerMustBeRunningToViewStats": "आंकड़े देखने के लिए कंटेनर का चालू होना आवश्यक है।",
"failedToFetchStats": "आंकड़े प्राप्त करने में विफल", "failedToFetchStats": "आंकड़े प्राप्त करने में विफल",
"noContainersFound": "कोई कंटेनर नहीं मिला", "noContainersFound": "कोई कंटेनर नहीं मिला",
"noContainersFoundHint": "सबसे पहले अपने सर्वर पर कंटेनर बनाएं।", "noContainersFoundHint": "सबसे पहले अपने सर्वर पर कंटेनर बनाएं।",
"searchPlaceholder": "नाम, छवि या आईडी के आधार पर खोजें...", "searchPlaceholder": "नाम, छवि या आईडी के आधार पर खोजें...",
"filterByStatusPlaceholder": "स्थिति के अनुसार फ़िल्टर करें", "filterByStatusPlaceholder": "स्थिति के अनुसार फ़िल्टर करें",
"allContainersCount": "सभी ({{containerName}})", "allContainersCount": "सभी ({{count}})",
"statusCount": "{{count}} ({{status}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "आपके फ़िल्टर से कोई कंटेनर मेल नहीं खाता।", "noContainersMatchFilters": "आपके फ़िल्टर से कोई कंटेनर मेल नहीं खाता।",
"noContainersMatchFiltersHint": "अपनी खोज या फ़िल्टर को समायोजित करने का प्रयास करें", "noContainersMatchFiltersHint": "अपनी खोज या फ़िल्टर को समायोजित करने का प्रयास करें",
"containerStarted": "कंटेनर {{count}} शुरू हो गया", "containerStarted": "कंटेनर {{name}} शुरू हो गया",
"failedToStartContainer": "कंटेनर शुरू करने में विफल: {{name}}", "failedToStartContainer": "कंटेनर शुरू करने में विफल: {{error}}",
"containerStopped": "कंटेनर {{error}} रुक गया", "containerStopped": "कंटेनर {{name}} रुक गया",
"failedToStopContainer": "कंटेनर को रोकने में विफल: {{name}}", "failedToStopContainer": "कंटेनर को रोकने में विफल: {{error}}",
"containerRestarted": "कंटेनर {{error}} पुनः आरंभ हो गया", "containerRestarted": "कंटेनर {{name}} पुनः आरंभ हुआ",
"failedToRestartContainer": "कंटेनर को पुनः आरंभ करने में विफल: {{name}}", "failedToRestartContainer": "कंटेनर को पुनः आरंभ करने में विफल: {{error}}",
"containerUnpaused": "कंटेनर {{error}} अनपॉज़ किया गया", "containerUnpaused": "कंटेनर {{name}} अनपॉज़ किया गया",
"containerPaused": "कंटेनर {{name}} रुका हुआ है", "containerPaused": "कंटेनर {{name}} रुका हुआ है",
"failedToTogglePauseContainer": "{{name}} कंटेनर विफल: {{action}}", "failedToTogglePauseContainer": "{{action}} कंटेनर में प्रवेश करने में विफल: {{error}}",
"containerRemoved": "कंटेनर {{error}} हटा दिया गया", "containerRemoved": "कंटेनर {{name}} हटा दिया गया",
"failedToRemoveContainer": "कंटेनर हटाने में विफल: {{name}}", "failedToRemoveContainer": "कंटेनर हटाने में विफल: {{error}}",
"image": "छवि:", "image": "छवि:",
"idLabel": "पहचान:", "idLabel": "पहचान:",
"ports": "बंदरगाह:", "ports": "बंदरगाह:",
@@ -1183,7 +1183,7 @@
"pause": "विराम", "pause": "विराम",
"restart": "पुनः आरंभ करें", "restart": "पुनः आरंभ करें",
"removeContainer": "कंटेनर हटाएँ", "removeContainer": "कंटेनर हटाएँ",
"confirmRemoveContainer": "क्या आप वाकई कंटेनर \"{{error}}\" को हटाना चाहते हैं?", "confirmRemoveContainer": "क्या आप वाकई कंटेनर \"{{name}}\" को हटाना चाहते हैं?",
"runningContainerWarning": "चेतावनी: यह कंटेनर वर्तमान में चल रहा है और इसे जबरन हटा दिया जाएगा।", "runningContainerWarning": "चेतावनी: यह कंटेनर वर्तमान में चल रहा है और इसे जबरन हटा दिया जाएगा।",
"removing": "हटाना:", "removing": "हटाना:",
"containerNotFound": "कंटेनर नहीं मिला", "containerNotFound": "कंटेनर नहीं मिला",
@@ -1191,7 +1191,7 @@
"logs": "लॉग्स", "logs": "लॉग्स",
"stats": "आँकड़े", "stats": "आँकड़े",
"consoleTab": "सांत्वना देना", "consoleTab": "सांत्वना देना",
"failedToFetchLogs": "लॉग प्राप्त करने में विफल: {{name}}", "failedToFetchLogs": "लॉग प्राप्त करने में विफल: {{error}}",
"failedToDownloadLogs": "लॉग डाउनलोड करने में विफल: {{error}}", "failedToDownloadLogs": "लॉग डाउनलोड करने में विफल: {{error}}",
"linesToShow": "दिखाने के लिए रेखाएँ", "linesToShow": "दिखाने के लिए रेखाएँ",
"last50Lines": "अंतिम 50 पंक्तियाँ", "last50Lines": "अंतिम 50 पंक्तियाँ",
@@ -1219,7 +1219,7 @@
"reconnect": "रिकनेक्ट", "reconnect": "रिकनेक्ट",
"sessionEnded": "सत्र समाप्त हुआ", "sessionEnded": "सत्र समाप्त हुआ",
"connectionLost": "कनेक्शन टूट गया", "connectionLost": "कनेक्शन टूट गया",
"error": "त्रुटि: {{error}}", "error": "त्रुटि: {{message}}",
"disconnected": "डिस्कनेक्ट किया गया", "disconnected": "डिस्कनेक्ट किया गया",
"connectionClosed": "कनेक्शन बंद हो गया", "connectionClosed": "कनेक्शन बंद हो गया",
"connectionError": "कनेक्शन त्रुटि: {{message}}", "connectionError": "कनेक्शन त्रुटि: {{message}}",
@@ -1230,13 +1230,13 @@
"messageParseError": "सर्वर संदेश को पार्स करने में विफल", "messageParseError": "सर्वर संदेश को पार्स करने में विफल",
"websocketError": "वेबसॉकेट कनेक्शन त्रुटि", "websocketError": "वेबसॉकेट कनेक्शन त्रुटि",
"connecting": "कनेक्ट हो रहा है...", "connecting": "कनेक्ट हो रहा है...",
"reconnecting": "पुनः कनेक्ट हो रहा है... ({{message}}/{{attempt}})", "reconnecting": "पुनः कनेक्ट हो रहा है... ({{attempt}}/{{max}})",
"reconnected": "सफलतापूर्वक पुनः कनेक्ट हो गया", "reconnected": "सफलतापूर्वक पुनः कनेक्ट हो गया",
"maxReconnectAttemptsReached": "अधिकतम पुनः कनेक्शन प्रयासों की सीमा पूरी हो गई है।", "maxReconnectAttemptsReached": "अधिकतम पुनः कनेक्शन प्रयासों की सीमा पूरी हो गई है।",
"connectionTimeout": "रिश्तों का समय बाहर", "connectionTimeout": "रिश्तों का समय बाहर",
"terminalTitle": "टर्मिनल - {{max}}", "terminalTitle": "टर्मिनल - {{host}}",
"terminalWithPath": "टर्मिनल - {{host}}:{{host}}", "terminalWithPath": "टर्मिनल - {{host}}:{{path}}",
"runTitle": "चल रहा है {{path}} - {{command}}", "runTitle": "चल रहा है {{command}} - {{host}}",
"totpRequired": "दो-कारक प्रमाणीकरण आवश्यक है", "totpRequired": "दो-कारक प्रमाणीकरण आवश्यक है",
"totpCodeLabel": "सत्यापन कोड", "totpCodeLabel": "सत्यापन कोड",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
@@ -1254,26 +1254,26 @@
"uploadFile": "फ़ाइल अपलोड करें", "uploadFile": "फ़ाइल अपलोड करें",
"downloadFile": "डाउनलोड करना", "downloadFile": "डाउनलोड करना",
"extractArchive": "संग्रह निकालें", "extractArchive": "संग्रह निकालें",
"extractingArchive": "{{host}} को निकाला जा रहा है...", "extractingArchive": "{{name}}का निष्कर्षण ...",
"archiveExtractedSuccessfully": "{{name}} सफलतापूर्वक निकाला गया", "archiveExtractedSuccessfully": "{{name}} सफलतापूर्वक निकाला गया",
"extractFailed": "निष्कर्षण विफल रहा", "extractFailed": "निष्कर्षण विफल रहा",
"compressFile": "फ़ाइल को संपीड़ित करें", "compressFile": "फ़ाइल को संपीड़ित करें",
"compressFiles": "फ़ाइलों को संपीड़ित करें", "compressFiles": "फ़ाइलों को संपीड़ित करें",
"compressFilesDesc": "{{name}} आइटमों को एक संग्रह में संपीड़ित करें", "compressFilesDesc": "{{count}} आइटमों को एक संग्रह में संपीड़ित करें",
"archiveName": "संग्रह नाम", "archiveName": "संग्रह नाम",
"enterArchiveName": "आर्काइव का नाम दर्ज करें...", "enterArchiveName": "आर्काइव का नाम दर्ज करें...",
"compressionFormat": "संपीड़न प्रारूप", "compressionFormat": "संपीड़न प्रारूप",
"selectedFiles": "चयनित फ़ाइलें", "selectedFiles": "चयनित फ़ाइलें",
"andMoreFiles": "और {{count}} और...", "andMoreFiles": "और {{count}} अधिक...",
"compress": "संकुचित करें", "compress": "संकुचित करें",
"compressingFiles": "{{count}} आइटमों को {{count}} में संपीड़ित किया जा रहा है...", "compressingFiles": "{{count}} आइटमों को {{name}}में संपीड़ित करना...",
"filesCompressedSuccessfully": "{{name}} सफलतापूर्वक बनाया गया", "filesCompressedSuccessfully": "{{name}} सफलतापूर्वक निर्मित",
"compressFailed": "संपीड़न विफल रहा", "compressFailed": "संपीड़न विफल रहा",
"edit": "संपादन करना", "edit": "संपादन करना",
"preview": "पूर्व दर्शन", "preview": "पूर्व दर्शन",
"previous": "पहले का", "previous": "पहले का",
"next": "अगला", "next": "अगला",
"pageXOfY": "पृष्ठ {{name}} का {{current}}", "pageXOfY": "पृष्ठ {{current}} का {{total}}",
"zoomOut": "ज़ूम आउट", "zoomOut": "ज़ूम आउट",
"zoomIn": "ज़ूम इन", "zoomIn": "ज़ूम इन",
"newFile": "नई फ़ाइल", "newFile": "नई फ़ाइल",
@@ -1289,13 +1289,13 @@
"chooseFile": "फाइलें चुनें", "chooseFile": "फाइलें चुनें",
"uploading": "अपलोड हो रहा है...", "uploading": "अपलोड हो रहा है...",
"downloading": "डाउनलोड हो रहा है...", "downloading": "डाउनलोड हो रहा है...",
"uploadingFile": "{{total}} अपलोड हो रहा है...", "uploadingFile": "अपलोड हो रहा है {{name}}...",
"uploadingLargeFile": "बड़ी फ़ाइल {{name}} ({{name}}) अपलोड की जा रही है...", "uploadingLargeFile": "बड़ी फ़ाइल अपलोड हो रही है {{name}} ({{size}})...",
"downloadingFile": "{{size}} डाउनलोड हो रहा है...", "downloadingFile": "डाउनलोड हो रहा है {{name}}...",
"creatingFile": "{{name}} का निर्माण हो रहा है...", "creatingFile": "{{name}}का निर्माण हो रहा है...",
"creatingFolder": "{{name}} का निर्माण हो रहा है...", "creatingFolder": "{{name}}का निर्माण हो रहा है...",
"deletingItem": "{{name}} {{type}} को हटाया जा रहा है...", "deletingItem": "{{type}} {{name}}को हटा रहा है...",
"renamingItem": "{{name}} {{type}} का नाम बदलकर {{oldName}} किया जा रहा है...", "renamingItem": "{{type}} {{oldName}} का नाम बदलकर {{newName}}किया जा रहा है...",
"createNewFile": "नई फ़ाइल बनाएँ", "createNewFile": "नई फ़ाइल बनाएँ",
"fileName": "फ़ाइल नाम", "fileName": "फ़ाइल नाम",
"creating": "सृजन...", "creating": "सृजन...",
@@ -1311,7 +1311,7 @@
"newName": "नया नाम", "newName": "नया नाम",
"thisIsDirectoryRename": "यह एक निर्देशिका है", "thisIsDirectoryRename": "यह एक निर्देशिका है",
"renaming": "नाम बदला जा रहा है...", "renaming": "नाम बदला जा रहा है...",
"fileUploadedSuccessfully": "फ़ाइल \"{{newName}}\" सफलतापूर्वक अपलोड हो गई", "fileUploadedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक अपलोड हो गई",
"failedToUploadFile": "फ़ाइल अपलोड करने में विफल", "failedToUploadFile": "फ़ाइल अपलोड करने में विफल",
"fileDownloadedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक डाउनलोड हो गई", "fileDownloadedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक डाउनलोड हो गई",
"failedToDownloadFile": "फ़ाइल डाउनलोड करने में विफल", "failedToDownloadFile": "फ़ाइल डाउनलोड करने में विफल",
@@ -1322,10 +1322,10 @@
"folderCreatedSuccessfully": "फ़ोल्डर \"{{name}}\" सफलतापूर्वक बनाया गया", "folderCreatedSuccessfully": "फ़ोल्डर \"{{name}}\" सफलतापूर्वक बनाया गया",
"failedToCreateFolder": "फ़ोल्डर बनाने में विफल", "failedToCreateFolder": "फ़ोल्डर बनाने में विफल",
"failedToCreateItem": "आइटम बनाने में विफल", "failedToCreateItem": "आइटम बनाने में विफल",
"operationFailed": "{{name}} ऑपरेशन {{operation}} के लिए विफल रहा: {{name}}", "operationFailed": "{{operation}} ऑपरेशन {{name}}के लिए विफल रहा : {{error}}",
"failedToResolveSymlink": "सिम्लिंक को हल करने में विफल", "failedToResolveSymlink": "सिम्लिंक को हल करने में विफल",
"itemDeletedSuccessfully": "{{error}} सफलतापूर्वक हटा दिया गया", "itemDeletedSuccessfully": "{{type}} सफलतापूर्वक हटा दिया गया",
"itemsDeletedSuccessfully": "{{type}} आइटम सफलतापूर्वक हटा दिए गए", "itemsDeletedSuccessfully": "{{count}} आइटम सफलतापूर्वक हटा दिए गए",
"failedToDeleteItems": "आइटम हटाने में विफल", "failedToDeleteItems": "आइटम हटाने में विफल",
"dragFilesToUpload": "फ़ाइलें अपलोड करने के लिए उन्हें यहाँ ड्रॉप करें", "dragFilesToUpload": "फ़ाइलें अपलोड करने के लिए उन्हें यहाँ ड्रॉप करें",
"emptyFolder": "यह फ़ोल्डर खाली है", "emptyFolder": "यह फ़ोल्डर खाली है",
@@ -1335,7 +1335,7 @@
"upload": "अपलोड करें", "upload": "अपलोड करें",
"selectHostToStart": "फ़ाइल प्रबंधन शुरू करने के लिए एक होस्ट चुनें", "selectHostToStart": "फ़ाइल प्रबंधन शुरू करने के लिए एक होस्ट चुनें",
"failedToConnect": "एसएसएच से कनेक्ट करने में विफल", "failedToConnect": "एसएसएच से कनेक्ट करने में विफल",
"failedToLoadDirectory": "डायरेक्टरी लोड करने में विफल", "failedToLoadDirectory": "निर्देशिका लोड करने में विफल",
"noSSHConnection": "कोई SSH कनेक्शन उपलब्ध नहीं है", "noSSHConnection": "कोई SSH कनेक्शन उपलब्ध नहीं है",
"enterFolderName": "फ़ोल्डर का नाम दर्ज करें:", "enterFolderName": "फ़ोल्डर का नाम दर्ज करें:",
"enterFileName": "फ़ाइल का नाम दर्ज करें:", "enterFileName": "फ़ाइल का नाम दर्ज करें:",
@@ -1348,24 +1348,24 @@
"properties": "गुण", "properties": "गुण",
"refresh": "ताज़ा करना", "refresh": "ताज़ा करना",
"downloadFiles": "ब्राउज़र में {{count}} फ़ाइलें डाउनलोड करें", "downloadFiles": "ब्राउज़र में {{count}} फ़ाइलें डाउनलोड करें",
"copyFiles": "{{count}} आइटम कॉपी करें", "copyFiles": "आइटम कॉपी करें {{count}}",
"cutFiles": "{{count}} आइटम काटें", "cutFiles": "{{count}} आइटम काटें",
"deleteFiles": "{{count}} आइटम हटाएं", "deleteFiles": "{{count}} आइटम हटाएं",
"filesCopiedToClipboard": "{{count}} आइटम क्लिपबोर्ड पर कॉपी किए गए", "filesCopiedToClipboard": "{{count}} आइटम क्लिपबोर्ड पर कॉपी हो गए",
"filesCutToClipboard": "क्लिपबोर्ड पर {{count}} आइटम काटे गए", "filesCutToClipboard": "{{count}} आइटम क्लिपबोर्ड पर सेव हो गए",
"pathCopiedToClipboard": "पथ क्लिपबोर्ड पर कॉपी हो गया", "pathCopiedToClipboard": "पथ क्लिपबोर्ड पर कॉपी हो गया",
"pathsCopiedToClipboard": "क्लिपबोर्ड पर {{count}} पथ कॉपी किए गए", "pathsCopiedToClipboard": "{{count}} पथ क्लिपबोर्ड पर कॉपी किए गए",
"failedToCopyPath": "क्लिपबोर्ड पर पथ कॉपी करने में विफल", "failedToCopyPath": "क्लिपबोर्ड पर पथ कॉपी करने में विफल",
"movedItems": "{{count}} आइटम स्थानांतरित किए गए", "movedItems": "{{count}} आइटम स्थानांतरित किए गए",
"failedToDeleteItem": "आइटम हटाने में विफल", "failedToDeleteItem": "आइटम हटाने में विफल",
"itemRenamedSuccessfully": "{{count}} का नाम सफलतापूर्वक बदल दिया गया", "itemRenamedSuccessfully": "{{type}} का नाम सफलतापूर्वक बदल दिया गया",
"failedToRenameItem": "आइटम का नाम बदलने में विफल", "failedToRenameItem": "आइटम का नाम बदलने में विफल",
"download": "डाउनलोड करना", "download": "डाउनलोड करना",
"permissions": "अनुमतियां", "permissions": "अनुमतियां",
"size": "आकार", "size": "आकार",
"modified": "संशोधित", "modified": "संशोधित",
"path": "पथ", "path": "पथ",
"confirmDelete": "क्या आप वाकई {{type}} को हटाना चाहते हैं?", "confirmDelete": "क्या आप वाकई {{name}}को हटाना चाहते हैं?",
"uploadSuccess": "फ़ाइल सफलतापूर्वक अपलोड की गई", "uploadSuccess": "फ़ाइल सफलतापूर्वक अपलोड की गई",
"uploadFailed": "फ़ाइल अपलोड विफल", "uploadFailed": "फ़ाइल अपलोड विफल",
"downloadSuccess": "फ़ाइल सफलतापूर्वक डाउनलोड हो गई", "downloadSuccess": "फ़ाइल सफलतापूर्वक डाउनलोड हो गई",
@@ -1388,11 +1388,11 @@
"connectToServer": "सर्वर से कनेक्ट करें", "connectToServer": "सर्वर से कनेक्ट करें",
"selectServerToEdit": "फ़ाइलों को संपादित करना शुरू करने के लिए साइडबार से एक सर्वर चुनें।", "selectServerToEdit": "फ़ाइलों को संपादित करना शुरू करने के लिए साइडबार से एक सर्वर चुनें।",
"fileOperations": "फ़ाइल संचालन", "fileOperations": "फ़ाइल संचालन",
"confirmDeleteMessage": "क्या आप वाकई {{name}} को हटाना चाहते हैं?", "confirmDeleteMessage": "क्या आप वाकई {{name}}को हटाना चाहते हैं?",
"confirmDeleteSingleItem": "क्या आप वाकई \"{{name}}\" को स्थायी रूप से हटाना चाहते हैं?", "confirmDeleteSingleItem": "क्या आप वाकई \"{{name}}\" को स्थायी रूप से हटाना चाहते हैं?",
"confirmDeleteMultipleItems": "क्या आप वाकई {{name}} आइटम को स्थायी रूप से हटाना चाहते हैं?", "confirmDeleteMultipleItems": "क्या आप वाकई {{count}} आइटम को स्थायी रूप से हटाना चाहते हैं?",
"confirmDeleteMultipleItemsWithFolders": "क्या आप वाकई {{count}} आइटम को स्थायी रूप से हटाना चाहते हैं? इसमें फ़ोल्डर और उनकी सामग्री शामिल है।", "confirmDeleteMultipleItemsWithFolders": "क्या आप वाकई {{count}} आइटम को स्थायी रूप से हटाना चाहते हैं? इसमें फ़ोल्डर और उनकी सामग्री शामिल है।",
"confirmDeleteFolder": "क्या आप वाकई फोल्डर \"{{count}}\" और उसकी सभी सामग्री को स्थायी रूप से हटाना चाहते हैं?", "confirmDeleteFolder": "क्या आप वाकई फोल्डर \"{{name}}\" और उसकी सभी सामग्री को स्थायी रूप से हटाना चाहते हैं?",
"deleteDirectoryWarning": "इससे फोल्डर और उसके अंदर की सभी सामग्री डिलीट हो जाएगी।", "deleteDirectoryWarning": "इससे फोल्डर और उसके अंदर की सभी सामग्री डिलीट हो जाएगी।",
"actionCannotBeUndone": "इस एक्शन को वापस नहीं किया जा सकता।", "actionCannotBeUndone": "इस एक्शन को वापस नहीं किया जा सकता।",
"permanentDeleteWarning": "यह कार्रवाई पूर्ववत नहीं की जा सकती। आइटम सर्वर से स्थायी रूप से हटा दिए जाएंगे।", "permanentDeleteWarning": "यह कार्रवाई पूर्ववत नहीं की जा सकती। आइटम सर्वर से स्थायी रूप से हटा दिए जाएंगे।",
@@ -1421,14 +1421,14 @@
"selectLocationToSave": "सहेजने के लिए स्थान चुनें", "selectLocationToSave": "सहेजने के लिए स्थान चुनें",
"openTerminalInFolder": "इस फ़ोल्डर में टर्मिनल खोलें", "openTerminalInFolder": "इस फ़ोल्डर में टर्मिनल खोलें",
"openTerminalInFileLocation": "फ़ाइल स्थान पर टर्मिनल खोलें", "openTerminalInFileLocation": "फ़ाइल स्थान पर टर्मिनल खोलें",
"terminalWithPath": "टर्मिनल - {{name}}:{{host}}", "terminalWithPath": "टर्मिनल - {{host}}:{{path}}",
"runningFile": "चल रहा है - {{path}}", "runningFile": "दौड़ना - {{file}}",
"onlyRunExecutableFiles": "केवल निष्पादन योग्य फ़ाइलें ही चला सकते हैं", "onlyRunExecutableFiles": "केवल निष्पादन योग्य फ़ाइलें ही चला सकते हैं",
"noHostSelected": "कोई होस्ट चयनित नहीं है", "noHostSelected": "कोई होस्ट चयनित नहीं है",
"starred": "तारांकित", "starred": "तारांकित",
"shortcuts": "शॉर्टकट", "shortcuts": "शॉर्टकट",
"directories": "निर्देशिका", "directories": "निर्देशिका",
"removedFromRecentFiles": "हाल की फ़ाइलों से \"{{file}}\" हटा दिया गया", "removedFromRecentFiles": "हाल की फ़ाइलों से \"{{name}}\" हटा दिया गया है",
"removeFailed": "हटाने में विफलता", "removeFailed": "हटाने में विफलता",
"unpinnedSuccessfully": "\"{{name}}\" को सफलतापूर्वक अनपिन कर दिया गया", "unpinnedSuccessfully": "\"{{name}}\" को सफलतापूर्वक अनपिन कर दिया गया",
"unpinFailed": "अनपिन विफल", "unpinFailed": "अनपिन विफल",
@@ -1437,10 +1437,10 @@
"clearedAllRecentFiles": "सभी हालिया फ़ाइलें हटा दी गईं", "clearedAllRecentFiles": "सभी हालिया फ़ाइलें हटा दी गईं",
"clearFailed": "क्लियर विफल", "clearFailed": "क्लियर विफल",
"removeFromRecentFiles": "हाल की फ़ाइलों से हटाएँ", "removeFromRecentFiles": "हाल की फ़ाइलों से हटाएँ",
"clearAllRecentFiles": "सभी हाल की फ़ाइलें साफ़ करें", "clearAllRecentFiles": "सभी हालिया फ़ाइलें साफ़ करें",
"unpinFile": "फ़ाइल को अनपिन करें", "unpinFile": "फ़ाइल को अनपिन करें",
"removeShortcut": "शॉर्टकट हटाएँ", "removeShortcut": "शॉर्टकट हटाएँ",
"saveFilesToSystem": "{{name}} फ़ाइलों को इस रूप में सहेजें...", "saveFilesToSystem": "{{count}} फ़ाइलों को इस रूप में सहेजें...",
"pinFile": "पिन फ़ाइल", "pinFile": "पिन फ़ाइल",
"addToShortcuts": "शॉर्टकट में जोड़ें", "addToShortcuts": "शॉर्टकट में जोड़ें",
"downloadToDefaultLocation": "डिफ़ॉल्ट स्थान पर डाउनलोड करें", "downloadToDefaultLocation": "डिफ़ॉल्ट स्थान पर डाउनलोड करें",
@@ -1449,7 +1449,7 @@
"undoCopySuccess": "कॉपी करने की प्रक्रिया पूर्ववत की गई: कॉपी की गई {{count}} फ़ाइलें हटाई गईं", "undoCopySuccess": "कॉपी करने की प्रक्रिया पूर्ववत की गई: कॉपी की गई {{count}} फ़ाइलें हटाई गईं",
"undoCopyFailedDelete": "पूर्ववत करने का प्रयास विफल: प्रतिलिपि की गई कोई भी फ़ाइल हटाई नहीं जा सकी", "undoCopyFailedDelete": "पूर्ववत करने का प्रयास विफल: प्रतिलिपि की गई कोई भी फ़ाइल हटाई नहीं जा सकी",
"undoCopyFailedNoInfo": "पूर्ववत करने में विफल: प्रतिलिपि की गई फ़ाइल की जानकारी नहीं मिल सकी", "undoCopyFailedNoInfo": "पूर्ववत करने में विफल: प्रतिलिपि की गई फ़ाइल की जानकारी नहीं मिल सकी",
"undoMoveSuccess": "स्थानांतरण प्रक्रिया को पूर्ववत किया गया: {{count}} फ़ाइलें वापस मूल स्थान पर स्थानांतरित कर दी गईं", "undoMoveSuccess": "स्थानांतरण प्रक्रिया को पूर्ववत किया गया: {{count}} फ़ाइलों को वापस मूल स्थान पर स्थानांतरित कर दिया गया",
"undoMoveFailedMove": "पूर्ववत करने में विफल: कोई भी फ़ाइल वापस नहीं ले जा सका", "undoMoveFailedMove": "पूर्ववत करने में विफल: कोई भी फ़ाइल वापस नहीं ले जा सका",
"undoMoveFailedNoInfo": "पूर्ववत करने में विफल: स्थानांतरित फ़ाइल की जानकारी नहीं मिल सकी", "undoMoveFailedNoInfo": "पूर्ववत करने में विफल: स्थानांतरित फ़ाइल की जानकारी नहीं मिल सकी",
"undoDeleteNotSupported": "डिलीट ऑपरेशन को पूर्ववत नहीं किया जा सकता: फ़ाइलें सर्वर से स्थायी रूप से हटा दी गई हैं।", "undoDeleteNotSupported": "डिलीट ऑपरेशन को पूर्ववत नहीं किया जा सकता: फ़ाइलें सर्वर से स्थायी रूप से हटा दी गई हैं।",
@@ -1491,33 +1491,33 @@
"unknownSize": "अज्ञात आकार", "unknownSize": "अज्ञात आकार",
"fileIsEmpty": "फ़ाइल खाली है", "fileIsEmpty": "फ़ाइल खाली है",
"largeFileWarning": "बड़ी फ़ाइल संबंधी चेतावनी", "largeFileWarning": "बड़ी फ़ाइल संबंधी चेतावनी",
"largeFileWarningDesc": "इस फ़ाइल का आकार {{count}} है, जिससे टेक्स्ट के रूप में खोलने पर प्रदर्शन संबंधी समस्याएँ उत्पन्न हो सकती हैं।", "largeFileWarningDesc": "इस फ़ाइल का आकार {{size}} है, जिससे टेक्स्ट के रूप में खोलने पर प्रदर्शन संबंधी समस्याएँ उत्पन्न हो सकती हैं।",
"fileNotFoundAndRemoved": "फ़ाइल \"{{size}}\" नहीं मिली और इसे हाल ही में/पिन की गई फ़ाइलों से हटा दिया गया है", "fileNotFoundAndRemoved": "फ़ाइल \"{{name}}\" नहीं मिली और इसे हाल ही में/पिन की गई फ़ाइलों से हटा दिया गया है",
"failedToLoadFile": "फ़ाइल लोड करने में विफल: {{name}}", "failedToLoadFile": "फ़ाइल लोड करने में विफल: {{error}}",
"serverErrorOccurred": "सर्वर में त्रुटि आ गई है। कृपया बाद में पुनः प्रयास करें।", "serverErrorOccurred": "सर्वर में त्रुटि आ गई है। कृपया बाद में पुनः प्रयास करें।",
"autoSaveFailed": "ऑटो-सेव विफल रहा", "autoSaveFailed": "ऑटो-सेव विफल रहा",
"fileAutoSaved": "फ़ाइल स्वतः सहेजी गई", "fileAutoSaved": "फ़ाइल स्वतः सहेजी गई",
"moveFileFailed": "{{error}} को स्थानांतरित करने में विफल", "moveFileFailed": "{{name}}को स्थानांतरित करने में विफल",
"moveOperationFailed": "स्थानांतरण प्रक्रिया विफल रही", "moveOperationFailed": "स्थानांतरण प्रक्रिया विफल रही",
"canOnlyCompareFiles": "केवल दो फाइलों की तुलना की जा सकती है", "canOnlyCompareFiles": "केवल दो फाइलों की तुलना की जा सकती है",
"comparingFiles": "फ़ाइलों की तुलना: {{name}} और {{file1}}", "comparingFiles": "फ़ाइलों की तुलना: {{file1}} और {{file2}}",
"dragFailed": "ड्रैग ऑपरेशन विफल रहा", "dragFailed": "ड्रैग ऑपरेशन विफल रहा",
"filePinnedSuccessfully": "फ़ाइल \"{{file2}}\" सफलतापूर्वक पिन हो गई", "filePinnedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक पिन कर दी गई",
"pinFileFailed": "फ़ाइल को पिन करने में विफल", "pinFileFailed": "फ़ाइल को पिन करने में विफल",
"fileUnpinnedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक अनपिन कर दी गई", "fileUnpinnedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक अनपिन कर दी गई",
"unpinFileFailed": "फ़ाइल को अनपिन करने में विफल", "unpinFileFailed": "फ़ाइल को अनपिन करने में विफल",
"shortcutAddedSuccessfully": "फ़ोल्डर शॉर्टकट \"{{name}}\" सफलतापूर्वक जोड़ दिया गया", "shortcutAddedSuccessfully": "फ़ोल्डर शॉर्टकट \"{{name}}\" सफलतापूर्वक जोड़ दिया गया",
"addShortcutFailed": "शॉर्टकट जोड़ने में विफल", "addShortcutFailed": "शॉर्टकट जोड़ने में विफल",
"operationCompletedSuccessfully": "{{name}} {{operation}} आइटम सफलतापूर्वक", "operationCompletedSuccessfully": "{{operation}} {{count}} आइटम सफलतापूर्वक",
"operationCompleted": "{{count}} {{operation}} आइटम", "operationCompleted": "{{operation}} {{count}} आइटम",
"downloadFileSuccess": "फ़ाइल {{count}} सफलतापूर्वक डाउनलोड हो गई", "downloadFileSuccess": "फ़ाइल {{name}} सफलतापूर्वक डाउनलोड हो गई",
"downloadFileFailed": "डाउनलोड विफल रहा", "downloadFileFailed": "डाउनलोड विफल रहा",
"moveTo": "{{name}} पर जाएँ", "moveTo": "{{name}}पर जाएँ",
"diffCompareWith": "{{name}} के साथ अंतर की तुलना करें", "diffCompareWith": "{{name}}के साथ अंतर की तुलना करें",
"dragOutsideToDownload": "डाउनलोड करने के लिए विंडो के बाहर खींचें ({{name}} फ़ाइलें)", "dragOutsideToDownload": "फ़ाइलें डाउनलोड करने के लिए विंडो के बाहर खींचें ({{count}} फ़ाइलें)",
"newFolderDefault": "नया फ़ोल्डर", "newFolderDefault": "नया फ़ोल्डर",
"newFileDefault": "NewFile.txt", "newFileDefault": "NewFile.txt",
"successfullyMovedItems": "{{count}} आइटम सफलतापूर्वक {{count}} में स्थानांतरित कर दिए गए।", "successfullyMovedItems": "{{count}} आइटम सफलतापूर्वक {{target}}में स्थानांतरित कर दिए गए हैं।",
"move": "कदम", "move": "कदम",
"searchInFile": "फ़ाइल में खोजें (Ctrl+F)", "searchInFile": "फ़ाइल में खोजें (Ctrl+F)",
"showKeyboardShortcuts": "कीबोर्ड शॉर्टकट दिखाएँ", "showKeyboardShortcuts": "कीबोर्ड शॉर्टकट दिखाएँ",
@@ -1527,10 +1527,10 @@
"compare": "तुलना करना", "compare": "तुलना करना",
"sideBySide": "अगल बगल", "sideBySide": "अगल बगल",
"inline": "इन - लाइन", "inline": "इन - लाइन",
"fileComparison": "फ़ाइल तुलना: {{target}} बनाम {{file1}}", "fileComparison": "फ़ाइल तुलना: {{file1}} बनाम {{file2}}",
"fileTooLarge": "फ़ाइल का आकार बहुत बड़ है: {{file2}}", "fileTooLarge": "फ़ाइल बहुत बड़ है: {{error}}",
"sshConnectionFailed": "SSH कनेक्शन विफल हो गया। कृपया {{error}} ({{name}}:{{ip}}) से अपना कनेक्शन जांचें।", "sshConnectionFailed": "SSH कनेक्शन विफल हो गया। कृपया {{name}} ({{ip}}:{{port}}) से अपना कनेक्शन जांचें।",
"loadFileFailed": "फ़ाइल लोड करने में विफल: {{port}}", "loadFileFailed": "फ़ाइल लोड करने में विफल: {{error}}",
"connectedSuccessfully": "सफलतापूर्वक कनेक्ट हो गया", "connectedSuccessfully": "सफलतापूर्वक कनेक्ट हो गया",
"totpVerificationFailed": "टीओटीपी सत्यापन विफल रहा", "totpVerificationFailed": "टीओटीपी सत्यापन विफल रहा",
"verificationCodePrompt": "सत्यापन कोड:", "verificationCodePrompt": "सत्यापन कोड:",
@@ -1573,10 +1573,10 @@
"disconnect": "डिस्कनेक्ट", "disconnect": "डिस्कनेक्ट",
"cancel": "रद्द करना", "cancel": "रद्द करना",
"port": "पत्तन", "port": "पत्तन",
"attempt": "{{error}} का प्रयास {{current}}", "attempt": "प्रयास {{current}} का {{max}}",
"nextRetryIn": "अगला प्रयास {{max}} सेकंड में होगा", "nextRetryIn": "अगला प्रयास {{seconds}} सेकंड में होगा",
"checkDockerLogs": "त्रुटि का कारण जानने के लिए अपने डॉकर लॉग की जाँच करें, और फिर शामिल हों।", "checkDockerLogs": "त्रुटि का कारण जानने के लिए अपने डॉकर लॉग की जाँच करें, और फिर शामिल हों।",
"orCreate": "या बनाएँ", "orCreate": "या बनाएँ ",
"noTunnelConnections": "कोई टनल कनेक्शन कॉन्फ़िगर नहीं किया गया है", "noTunnelConnections": "कोई टनल कनेक्शन कॉन्फ़िगर नहीं किया गया है",
"tunnelConnections": "सुरंग कनेक्शन", "tunnelConnections": "सुरंग कनेक्शन",
"addTunnel": "सुरंग जोड़ें", "addTunnel": "सुरंग जोड़ें",
@@ -1598,7 +1598,7 @@
"remote": "दूर", "remote": "दूर",
"dynamic": "गतिशील", "dynamic": "गतिशील",
"unknownConnectionStatus": "अज्ञात", "unknownConnectionStatus": "अज्ञात",
"portMapping": "पोर्ट {{seconds}} → {{sourcePort}}:{{endpointHost}}", "portMapping": "पोर्ट {{sourcePort}} → {{endpointHost}}:{{endpointPort}}",
"endpointHostNotFound": "एंडपॉइंट होस्ट नहीं मिला", "endpointHostNotFound": "एंडपॉइंट होस्ट नहीं मिला",
"discord": "कलह", "discord": "कलह",
"githubIssue": "GitHub समस्या", "githubIssue": "GitHub समस्या",
@@ -1611,7 +1611,7 @@
"disk": "डिस्क", "disk": "डिस्क",
"network": "नेटवर्क", "network": "नेटवर्क",
"uptime": "अपटाइम", "uptime": "अपटाइम",
"loadAverage": "औसत: {{endpointPort}}, {{avg1}}, {{avg5}}", "loadAverage": "औसत: {{avg1}}, {{avg5}}, {{avg15}}",
"processes": "प्रक्रियाओं", "processes": "प्रक्रियाओं",
"connections": "कनेक्शन", "connections": "कनेक्शन",
"usage": "प्रयोग", "usage": "प्रयोग",
@@ -1624,7 +1624,7 @@
"refreshStatus": "स्थिति रीफ़्रेश करें", "refreshStatus": "स्थिति रीफ़्रेश करें",
"fileManagerAlreadyOpen": "इस होस्ट के लिए फ़ाइल प्रबंधक पहले से ही खुला हुआ है।", "fileManagerAlreadyOpen": "इस होस्ट के लिए फ़ाइल प्रबंधक पहले से ही खुला हुआ है।",
"openFileManager": "फ़ाइल प्रबंधक खोलें", "openFileManager": "फ़ाइल प्रबंधक खोलें",
"cpuCores_one": "{{avg15}} सीपीयू", "cpuCores_one": "{{count}} सीपीयू",
"cpuCores_other": "{{count}} सीपीयू", "cpuCores_other": "{{count}} सीपीयू",
"naCpus": "लागू नहीं सीपीयू(ओं)", "naCpus": "लागू नहीं सीपीयू(ओं)",
"loadAverageNA": "औसत: लागू नहीं", "loadAverageNA": "औसत: लागू नहीं",
@@ -1678,11 +1678,11 @@
"noRecentLoginData": "हाल ही में लॉगिन का कोई डेटा उपलब्ध नहीं है", "noRecentLoginData": "हाल ही में लॉगिन का कोई डेटा उपलब्ध नहीं है",
"from": "से", "from": "से",
"quickActions": "त्वरित कार्रवाइयां", "quickActions": "त्वरित कार्रवाइयां",
"executeQuickAction": "निष्पादित करें {{count}}", "executeQuickAction": "{{name}}निष्पादित करें",
"executingQuickAction": "{{name}} निष्पादित हो रहा है...", "executingQuickAction": "{{name}}निष्पादित किया जा रहा है...",
"quickActionSuccess": "{{name}} सफलतापूर्वक पूर्ण हुआ", "quickActionSuccess": "{{name}} सफलतापूर्वक पूर हुआ",
"quickActionFailed": "{{name}} असफल", "quickActionFailed": "{{name}} असफल",
"quickActionError": "{{name}} को निष्पादित करने में विफल रहा" "quickActionError": "{{name}}को निष्पादित करने में विफल"
}, },
"auth": { "auth": {
"tagline": "एसएसएच सर्वर प्रबंधक", "tagline": "एसएसएच सर्वर प्रबंधक",
@@ -1804,7 +1804,7 @@
"unknownError": "अज्ञात त्रुटि", "unknownError": "अज्ञात त्रुटि",
"loginFailed": "लॉगिन विफल", "loginFailed": "लॉगिन विफल",
"failedPasswordReset": "पासवर्ड रीसेट शुरू करने में विफल", "failedPasswordReset": "पासवर्ड रीसेट शुरू करने में विफल",
"failedVerifyCode": "रीसेट कोड सत्यापित करने में विफल", "failedVerifyCode": "रीसेट कोड को सत्यापित करने में विफल",
"failedCompleteReset": "पासवर्ड रीसेट करने में विफलता", "failedCompleteReset": "पासवर्ड रीसेट करने में विफलता",
"invalidTotpCode": "अमान्य टीओटीपी कोड", "invalidTotpCode": "अमान्य टीओटीपी कोड",
"failedOidcLogin": "OIDC लॉगिन शुरू करने में विफल", "failedOidcLogin": "OIDC लॉगिन शुरू करने में विफल",
@@ -1814,8 +1814,8 @@
"invalidAuthUrl": "बैकएंड से अमान्य प्राधिकरण यूआरएल प्राप्त हुआ।", "invalidAuthUrl": "बैकएंड से अमान्य प्राधिकरण यूआरएल प्राप्त हुआ।",
"invalidInput": "अमान्य निवेश", "invalidInput": "अमान्य निवेश",
"requiredField": "यह फ़ील्ड आवश्यक है", "requiredField": "यह फ़ील्ड आवश्यक है",
"minLength": "न्यूनतम लंबाई {{name}} है", "minLength": "न्यूनतम लंबाई {{min}}है",
"maxLength": "अधिकतम लंबाई {{min}} है", "maxLength": "अधिकतम लंबाई {{max}}है",
"invalidEmail": "अमान्य ईमेल पता", "invalidEmail": "अमान्य ईमेल पता",
"passwordMismatch": "सांकेतिक शब्द मेल नहीं खाते", "passwordMismatch": "सांकेतिक शब्द मेल नहीं खाते",
"passwordLoginDisabled": "उपयोगकर्ता नाम/पासवर्ड लॉगिन वर्तमान में अक्षम है", "passwordLoginDisabled": "उपयोगकर्ता नाम/पासवर्ड लॉगिन वर्तमान में अक्षम है",
@@ -1835,7 +1835,7 @@
"updateError": "अपडेट करने में विफल", "updateError": "अपडेट करने में विफल",
"copySuccess": "क्लिपबोर्ड पर कॉपी हो गया", "copySuccess": "क्लिपबोर्ड पर कॉपी हो गया",
"copyError": "कॉपी करने में विफल", "copyError": "कॉपी करने में विफल",
"copiedToClipboard": "{{max}} क्लिपबोर्ड पर कॉपी हो गया", "copiedToClipboard": "{{item}} क्लिपबोर्ड पर कॉपी हो गया",
"connectionEstablished": "कनेक्शन स्थापित हो गया", "connectionEstablished": "कनेक्शन स्थापित हो गया",
"connectionClosed": "कनेक्शन बंद हो गया", "connectionClosed": "कनेक्शन बंद हो गया",
"reconnecting": "पुनः संपर्क स्थापित हो रहा है...", "reconnecting": "पुनः संपर्क स्थापित हो रहा है...",
@@ -1845,7 +1845,7 @@
"databaseConnected": "डेटाबेस सफलतापूर्वक कनेक्ट हो गया", "databaseConnected": "डेटाबेस सफलतापूर्वक कनेक्ट हो गया",
"databaseConnectionFailed": "डेटाबेस सर्वर से कनेक्ट करने में विफल।", "databaseConnectionFailed": "डेटाबेस सर्वर से कनेक्ट करने में विफल।",
"checkServerConnection": "कृपया अपने सर्वर कनेक्शन की जांच करें और पुनः प्रयास करें।", "checkServerConnection": "कृपया अपने सर्वर कनेक्शन की जांच करें और पुनः प्रयास करें।",
"resetCodeSent": "रीसेट कोड डॉकर लॉग्स में भेजा गया", "resetCodeSent": "रीसेट कोड डॉकर लॉग्स को भेजा गया",
"codeVerified": "कोड सफलतापूर्वक सत्यापित हो गया", "codeVerified": "कोड सफलतापूर्वक सत्यापित हो गया",
"passwordResetSuccess": "पासवर्ड सफलतापूर्वक रीसेट हो गया", "passwordResetSuccess": "पासवर्ड सफलतापूर्वक रीसेट हो गया",
"loginSuccess": "लॉग इन सफल", "loginSuccess": "लॉग इन सफल",
@@ -1871,13 +1871,13 @@
"commandAutocomplete": "कमांड ऑटो-कंप्लीट", "commandAutocomplete": "कमांड ऑटो-कंप्लीट",
"commandAutocompleteDesc": "अपने कमांड इतिहास के आधार पर टर्मिनल कमांड के लिए टैब कुंजी स्वतः पूर्ण होने के सुझाव सक्षम करें", "commandAutocompleteDesc": "अपने कमांड इतिहास के आधार पर टर्मिनल कमांड के लिए टैब कुंजी स्वतः पूर्ण होने के सुझाव सक्षम करें",
"defaultSnippetFoldersCollapsed": "डिफ़ॉल्ट रूप से स्निपेट फ़ोल्डर को संक्षिप्त करें", "defaultSnippetFoldersCollapsed": "डिफ़ॉल्ट रूप से स्निपेट फ़ोल्डर को संक्षिप्त करें",
"defaultSnippetFoldersCollapsedDesc": "जब यह विकल्प चालू होगा, तो स्निपेट टैब खोलने पर सभी स्निपेट फ़ोल्डर सिकुड़े हुए दिखाई देंगे।", "defaultSnippetFoldersCollapsedDesc": "इस विकल्प को चालू करने पर, स्निपेट टैब खोलने पर सभी स्निपेट फ़ोल्डर सिकुड़ जाएंगे।",
"terminalSyntaxHighlighting": "टर्मिनल सिंटैक्स हाइलाइटिंग", "terminalSyntaxHighlighting": "टर्मिनल सिंटैक्स हाइलाइटिंग",
"showHostTags": "शो होस्ट टैग", "showHostTags": "शो होस्ट टैग",
"showHostTagsDesc": "साइडबार में प्रत्येक होस्ट के नीचे टैग प्रदर्शित करें। सभी टैग छिपाने के लिए इसे अक्षम करें।", "showHostTagsDesc": "साइडबार में प्रत्येक होस्ट के नीचे टैग प्रदर्शित करें। सभी टैग छिपाने के लिए इसे अक्षम करें।",
"account": "खाता", "account": "खाता",
"appearance": "उपस्थिति", "appearance": "उपस्थिति",
"languageLocalization": "भाषा एवं स्थानीयकरण", "languageLocalization": "भाषा और स्थानीयकरण",
"fileManagerSettings": "फ़ाइल मैनेजर", "fileManagerSettings": "फ़ाइल मैनेजर",
"terminalSettings": "टर्मिनल", "terminalSettings": "टर्मिनल",
"hostSidebarSettings": "होस्ट और साइडबार", "hostSidebarSettings": "होस्ट और साइडबार",
@@ -1955,9 +1955,9 @@
"passwordRequired": "पासवर्ड आवश्यक है", "passwordRequired": "पासवर्ड आवश्यक है",
"failedToDeleteAccount": "खाता हटाने में विफल", "failedToDeleteAccount": "खाता हटाने में विफल",
"failedToMakeUserAdmin": "उपयोगकर्ता को व्यवस्थापक बनाने में विफल", "failedToMakeUserAdmin": "उपयोगकर्ता को व्यवस्थापक बनाने में विफल",
"userIsNowAdmin": "उपयोगकर्ता {{item}} अब व्यवस्थापक है", "userIsNowAdmin": "उपयोगकर्ता {{username}} अब व्यवस्थापक है",
"removeAdminConfirm": "क्या आप वाकई {{username}} से व्यवस्थापक का दर्जा हटाना चाहते हैं?", "removeAdminConfirm": "क्या आप वाकई {{username}}से व्यवस्थापक का दर्जा हटाना चाहते हैं?",
"deleteUserConfirm": "क्या आप वाकई उपयोगकर्ता {{username}} को हटाना चाहते हैं? यह कार्रवाई पूर्ववत नहीं की जा सकती।", "deleteUserConfirm": "क्या आप वाकई उपयोगकर्ता {{username}}को हटाना चाहते हैं? यह कार्रवाई पूर्ववत नहीं की जा सकती।",
"deleteAccount": "खाता हटा दो", "deleteAccount": "खाता हटा दो",
"closeDeleteAccount": "खाता बंद करें हटाएं", "closeDeleteAccount": "खाता बंद करें हटाएं",
"deleteAccountWarning": "यह कार्रवाई पूर्ववत नहीं की जा सकती। इससे आपका खाता और उससे संबंधित सभी डेटा स्थायी रूप से हटा दिया जाएगा।", "deleteAccountWarning": "यह कार्रवाई पूर्ववत नहीं की जा सकती। इससे आपका खाता और उससे संबंधित सभी डेटा स्थायी रूप से हटा दिया जाएगा।",
@@ -2056,7 +2056,7 @@
"webServerProduction": "वेब सर्वर - उत्पादन", "webServerProduction": "वेब सर्वर - उत्पादन",
"unknownError": "अज्ञात त्रुटि", "unknownError": "अज्ञात त्रुटि",
"failedToInitiatePasswordReset": "पासवर्ड रीसेट शुरू करने में विफल", "failedToInitiatePasswordReset": "पासवर्ड रीसेट शुरू करने में विफल",
"failedToVerifyResetCode": "रीसेट कोड को सत्यापित करने में विफल", "failedToVerifyResetCode": "रीसेट कोड सत्यापित करने में विफल",
"failedToCompletePasswordReset": "पासवर्ड रीसेट करने में विफलता", "failedToCompletePasswordReset": "पासवर्ड रीसेट करने में विफलता",
"invalidTotpCode": "अमान्य टीओटीपी कोड", "invalidTotpCode": "अमान्य टीओटीपी कोड",
"failedToStartOidcLogin": "OIDC लॉगिन शुरू करने में विफल", "failedToStartOidcLogin": "OIDC लॉगिन शुरू करने में विफल",
@@ -2140,17 +2140,17 @@
"blockedCommandsPlaceholder": "ब्लॉक करने के लिए कमांड दर्ज करें, उदाहरण के लिए, passwd, rm, dd", "blockedCommandsPlaceholder": "ब्लॉक करने के लिए कमांड दर्ज करें, उदाहरण के लिए, passwd, rm, dd",
"maxSessionDuration": "अधिकतम सत्र अवधि (मिनटों में)", "maxSessionDuration": "अधिकतम सत्र अवधि (मिनटों में)",
"createTempUser": "अस्थायी उपयोगकर्ता बनाएँ", "createTempUser": "अस्थायी उपयोगकर्ता बनाएँ",
"createTempUserDesc": "यह आपके क्रेडेंशियल्स को साझा करने के बजाय सर्वर पर एक प्रतिबंधित उपयोगकर्ता बनाता है। इसके लिए sudo एक्सेस आवश्यक है। यह सबसे सुरक्षित विकल्प है।", "createTempUserDesc": "यह आपके क्रेडेंशियल्स साझा करने के बजाय सर्वर पर एक प्रतिबंधित उपयोगकर्ता बनाता है। इसके लिए sudo एक्सेस आवश्यक है। यह सबसे सुरक्षित विकल्प है।",
"expiresAt": "समाप्ति तिथि", "expiresAt": "समाप्ति तिथि",
"expiresIn": "{{username}} घंटों में समाप्त हो जाएगा", "expiresIn": "{{hours}} घंटों में समाप्त हो जाएगा",
"expired": "खत्म हो चुका", "expired": "खत्म हो चुका",
"grantedBy": "अनुमती देना", "grantedBy": "अनुमती देना",
"accessLevel": "पहुँच स्तर", "accessLevel": "पहुँच स्तर",
"lastAccessed": "अंतिम बार देखा गया", "lastAccessed": "अंतिम बार देखा गया",
"accessCount": "पहुँच गणना", "accessCount": "पहुँच गणना",
"revokeAccess": "एक्सेस अक्षम करें", "revokeAccess": "एक्सेस अक्षम करें",
"confirmRevokeAccess": "क्या आप वाकई {{hours}} के लिए पहुँच रद्द करना चाहते हैं?", "confirmRevokeAccess": "क्या आप वाकई {{username}}के लिए पहुँच रद्द करना चाहते हैं?",
"hostSharedSuccessfully": "होस्ट ने {{username}} के साथ सफलतापूर्वक साझा किया", "hostSharedSuccessfully": "होस्ट ने {{username}}के साथ सफलतापूर्वक साझा किया",
"hostAccessUpdated": "होस्ट एक्सेस अपडेट किया गया", "hostAccessUpdated": "होस्ट एक्सेस अपडेट किया गया",
"failedToShareHost": "होस्ट साझा करने में विफल", "failedToShareHost": "होस्ट साझा करने में विफल",
"accessRevokedSuccessfully": "पहुँच सफलतापूर्वक रद्द कर दी गई", "accessRevokedSuccessfully": "पहुँच सफलतापूर्वक रद्द कर दी गई",
@@ -2165,11 +2165,11 @@
"noAccessGranted": "इस होस्ट के लिए कोई एक्सेस प्रदान नहीं किया गया है।", "noAccessGranted": "इस होस्ट के लिए कोई एक्सेस प्रदान नहीं किया गया है।",
"noAccessGrantedMessage": "अभी तक किसी भी उपयोगकर्ता को इस होस्ट तक पहुंच प्रदान नहीं की गई है।", "noAccessGrantedMessage": "अभी तक किसी भी उपयोगकर्ता को इस होस्ट तक पहुंच प्रदान नहीं की गई है।",
"manageAccessFor": "इसके लिए पहुंच प्रबंधित करें", "manageAccessFor": "इसके लिए पहुंच प्रबंधित करें",
"totalAccessRecords": "{{username}} एक्सेस रिकॉर्ड(ओं)", "totalAccessRecords": "{{count}} रिकॉर्ड तक पहुंचें",
"neverAccessed": "कभी नहीं", "neverAccessed": "कभी नहीं",
"timesAccessed": "{{count}} बार", "timesAccessed": "{{count}} बार(s)",
"daysRemaining": "{{count}} दिन", "daysRemaining": "{{days}} दिन(दिन)",
"hoursRemaining": "{{days}} घंटे", "hoursRemaining": "{{hours}} घंटे",
"failedToFetchAccessList": "एक्सेस सूची प्राप्त करने में विफल", "failedToFetchAccessList": "एक्सेस सूची प्राप्त करने में विफल",
"currentAccess": "वर्तमान पहुंच", "currentAccess": "वर्तमान पहुंच",
"securityWarning": "सुरक्षा चेतावनी", "securityWarning": "सुरक्षा चेतावनी",
@@ -2177,7 +2177,7 @@
"tempUserRecommended": "बेहतर सुरक्षा के लिए हम 'अस्थायी उपयोगकर्ता बनाएं' विकल्प को सक्षम करने की सलाह देते हैं।", "tempUserRecommended": "बेहतर सुरक्षा के लिए हम 'अस्थायी उपयोगकर्ता बनाएं' विकल्प को सक्षम करने की सलाह देते हैं।",
"roleManagement": "भूमिका प्रबंधन", "roleManagement": "भूमिका प्रबंधन",
"manageRoles": "भूमिकाएँ प्रबंधित करें", "manageRoles": "भूमिकाएँ प्रबंधित करें",
"manageRolesFor": "{{hours}} के लिए भूमिकाएँ प्रबंधित करें", "manageRolesFor": "{{username}}के लिए भूमिकाएँ प्रबंधित करें",
"assignRole": "भूमिका सौंपें", "assignRole": "भूमिका सौंपें",
"removeRole": "भूमिका हटाएँ", "removeRole": "भूमिका हटाएँ",
"userRoles": "उपयोगकर्ता भूमिका", "userRoles": "उपयोगकर्ता भूमिका",
@@ -2213,8 +2213,8 @@
"commandBlocked": "कमांड अवरुद्ध", "commandBlocked": "कमांड अवरुद्ध",
"terminateSession": "सत्र समाप्त करें", "terminateSession": "सत्र समाप्त करें",
"sessionTerminated": "होस्ट के मालिक द्वारा सत्र समाप्त कर दिया गया", "sessionTerminated": "होस्ट के मालिक द्वारा सत्र समाप्त कर दिया गया",
"sharedAccessExpired": "इस होस्ट पर आपकी साझा पहुंच समाप्त हो गई है।", "sharedAccessExpired": "इस होस्ट तक आपकी साझा पहुंच समाप्त हो गई है।",
"sharedAccessExpiresIn": "साझा पहुंच {{username}} घंटों में समाप्त हो जाएगी", "sharedAccessExpiresIn": "साझा पहुंच {{hours}} घंटों में समाप्त हो जाएगी",
"roles": { "roles": {
"label": "भूमिकाएँ", "label": "भूमिकाएँ",
"admin": "प्रशासक", "admin": "प्रशासक",
@@ -2249,7 +2249,7 @@
"displayNamePlaceholder": "डेवलपर", "displayNamePlaceholder": "डेवलपर",
"descriptionPlaceholder": "सॉफ्टवेयर डेवलपर और इंजीनियर", "descriptionPlaceholder": "सॉफ्टवेयर डेवलपर और इंजीनियर",
"confirmDeleteRole": "भूमिका हटाएं", "confirmDeleteRole": "भूमिका हटाएं",
"confirmDeleteRoleDescription": "क्या आप वाकई '{{hours}}' भूमिका को हटाना चाहते हैं? यह क्रिया पूर्ववत नहीं की जा सकती।", "confirmDeleteRoleDescription": "क्या आप वाकई '{{name}}' भूमिका को हटाना चाहते हैं? यह कार्रवाई पूर्ववत नहीं की जा सकती।",
"confirmRemoveRole": "भूमिका हटाएँ", "confirmRemoveRole": "भूमिका हटाएँ",
"confirmRemoveRoleDescription": "क्या आप वाकई इस भूमिका को उपयोगकर्ता से हटाना चाहते हैं?", "confirmRemoveRoleDescription": "क्या आप वाकई इस भूमिका को उपयोगकर्ता से हटाना चाहते हैं?",
"editRoleDescription": "भूमिका संबंधी जानकारी अपडेट करें", "editRoleDescription": "भूमिका संबंधी जानकारी अपडेट करें",
@@ -2307,19 +2307,19 @@
"validating": "डॉकर का सत्यापन किया जा रहा है...", "validating": "डॉकर का सत्यापन किया जा रहा है...",
"connectingToHost": "होस्ट से कनेक्ट हो रहा है...", "connectingToHost": "होस्ट से कनेक्ट हो रहा है...",
"error": "गलती", "error": "गलती",
"errorCode": "त्रुटि कोड: {{name}}", "errorCode": "त्रुटि कोड: {{code}}",
"version": "डॉकर {{code}}", "version": "डॉकर {{version}}",
"containerStarted": "कंटेनर {{version}} शुरू हो गया", "containerStarted": "कंटेनर {{name}} शुरू हो गया",
"failedToStartContainer": "कंटेनर {{name}} को प्रारंभ करने में विफल", "failedToStartContainer": "कंटेनर {{name}}को प्रारंभ करने में विफल",
"containerStopped": "कंटेनर {{name}} रुक गया", "containerStopped": "कंटेनर {{name}} रुक गया",
"failedToStopContainer": "कंटेनर {{name}} को रोकने में विफल", "failedToStopContainer": "कंटेनर {{name}}को रोकने में विफल",
"containerRestarted": "कंटेनर {{name}} पुनः आरंभ हो गया", "containerRestarted": "कंटेनर {{name}} पुनः आरंभ हुआ",
"failedToRestartContainer": "कंटेनर {{name}} को पुनः आरंभ करने में विफल रहा", "failedToRestartContainer": "कंटेनर {{name}}को पुनः आरंभ करने में विफल रहा",
"containerPaused": "कंटेनर {{name}} रुका हुआ है", "containerPaused": "कंटेनर {{name}} रुका हुआ है",
"containerUnpaused": "कंटेनर {{name}} अनपॉज़ किया गया", "containerUnpaused": "कंटेनर {{name}} अनपॉज़ किया गया",
"failedToTogglePauseContainer": "कंटेनर {{name}} के लिए पॉज़ स्थिति को टॉगल करने में विफल।", "failedToTogglePauseContainer": "कंटेनर {{name}}के लिए पॉज़ स्थिति को टॉगल करने में विफल।",
"containerRemoved": "कंटेनर {{name}} हटा दिया गया", "containerRemoved": "कंटेनर {{name}} हटा दिया गया",
"failedToRemoveContainer": "कंटेनर {{name}} को हटाने में विफल रहा", "failedToRemoveContainer": "कंटेनर {{name}}को हटाने में विफल",
"image": "छवि", "image": "छवि",
"idLabel": "पहचान", "idLabel": "पहचान",
"ports": "बंदरगाहों", "ports": "बंदरगाहों",
@@ -2340,8 +2340,8 @@
"noContainersFoundHint": "इस होस्ट पर कोई डॉकर कंटेनर उपलब्ध नहीं हैं।", "noContainersFoundHint": "इस होस्ट पर कोई डॉकर कंटेनर उपलब्ध नहीं हैं।",
"searchPlaceholder": "कंटेनर खोजें...", "searchPlaceholder": "कंटेनर खोजें...",
"filterByStatusPlaceholder": "स्थिति के अनुसार फ़िल्टर करें", "filterByStatusPlaceholder": "स्थिति के अनुसार फ़िल्टर करें",
"allContainersCount": "सभी ({{name}})", "allContainersCount": "सभी ({{count}})",
"statusCount": "{{count}} ({{status}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "आपके फ़िल्टर से कोई कंटेनर मेल नहीं खाता।", "noContainersMatchFilters": "आपके फ़िल्टर से कोई कंटेनर मेल नहीं खाता।",
"noContainersMatchFiltersHint": "अपनी खोज या फ़िल्टर के मानदंडों को समायोजित करने का प्रयास करें", "noContainersMatchFiltersHint": "अपनी खोज या फ़िल्टर के मानदंडों को समायोजित करने का प्रयास करें",
"containerMustBeRunningToViewStats": "आंकड़े देखने के लिए कंटेनर का चालू होना आवश्यक है।", "containerMustBeRunningToViewStats": "आंकड़े देखने के लिए कंटेनर का चालू होना आवश्यक है।",
@@ -2372,10 +2372,10 @@
"authenticationRequired": "प्रमाणित करना", "authenticationRequired": "प्रमाणित करना",
"verificationCodePrompt": "सत्यापन कोड दर्ज करें", "verificationCodePrompt": "सत्यापन कोड दर्ज करें",
"totpVerificationFailed": "टीओटीपी सत्यापन विफल रहा। कृपया पुनः प्रयास करें।", "totpVerificationFailed": "टीओटीपी सत्यापन विफल रहा। कृपया पुनः प्रयास करें।",
"connectedTo": "{{count}} से जुड़ा हुआ है", "connectedTo": "{{containerName}}से जुड़ा हुआ",
"disconnected": "डिस्कनेक्ट किया गया", "disconnected": "डिस्कनेक्ट किया गया",
"consoleError": "कंसोल त्रुटि", "consoleError": "कंसोल त्रुटि",
"errorMessage": "त्रुटि: {{containerName}}", "errorMessage": "त्रुटि: {{message}}",
"failedToConnect": "कंटेनर से कनेक्ट करने में विफल", "failedToConnect": "कंटेनर से कनेक्ट करने में विफल",
"console": "सांत्वना देना", "console": "सांत्वना देना",
"selectShell": "शेल का चयन करें", "selectShell": "शेल का चयन करें",
@@ -2387,7 +2387,7 @@
"disconnect": "डिस्कनेक्ट", "disconnect": "डिस्कनेक्ट",
"notConnected": "जुड़े नहीं हैं", "notConnected": "जुड़े नहीं हैं",
"clickToConnect": "शेल सेशन शुरू करने के लिए कनेक्ट पर क्लिक करें", "clickToConnect": "शेल सेशन शुरू करने के लिए कनेक्ट पर क्लिक करें",
"connectingTo": "{{message}} से कनेक्ट हो रहा है...", "connectingTo": "{{containerName}}से कनेक्ट हो रहा है...",
"containerNotFound": "कंटेनर नहीं मिला", "containerNotFound": "कंटेनर नहीं मिला",
"backToList": "सूची पर वापस जाएं", "backToList": "सूची पर वापस जाएं",
"logs": "लॉग्स", "logs": "लॉग्स",
@@ -2399,4 +2399,4 @@
"switchToLight": "लाइट पर स्विच करें", "switchToLight": "लाइट पर स्विच करें",
"switchToDark": "डार्क मोड पर स्विच करें" "switchToDark": "डार्क मोड पर स्विच करें"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@
"passwordAuthDescription": "Gunakan autentikasi kata sandi.", "passwordAuthDescription": "Gunakan autentikasi kata sandi.",
"sshKeyAuthDescription": "Gunakan autentikasi kunci SSH", "sshKeyAuthDescription": "Gunakan autentikasi kunci SSH",
"passwordIsRequired": "Kata sandi diperlukan", "passwordIsRequired": "Kata sandi diperlukan",
"sshKeyIsRequired": "Kunci SSH diperlukan", "sshKeyIsRequired": "Kunci SSH diperlukan.",
"sshKeyType": "Jenis Kunci SSH", "sshKeyType": "Jenis Kunci SSH",
"privateKey": "Kunci Pribadi", "privateKey": "Kunci Pribadi",
"enterPassword": "Masukkan kata sandi", "enterPassword": "Masukkan kata sandi",
@@ -139,7 +139,7 @@
"confirmRemoveFromFolder": "Apakah Anda yakin ingin menghapus \"{{name}}\" dari folder \"{{folder}}\"? Kredensial akan dipindahkan ke \"Tidak Berkategori\".", "confirmRemoveFromFolder": "Apakah Anda yakin ingin menghapus \"{{name}}\" dari folder \"{{folder}}\"? Kredensial akan dipindahkan ke \"Tidak Berkategori\".",
"removedFromFolder": "Kredensial \"{{name}}\" berhasil dihapus dari folder", "removedFromFolder": "Kredensial \"{{name}}\" berhasil dihapus dari folder",
"failedToRemoveFromFolder": "Gagal menghapus kredensial dari folder.", "failedToRemoveFromFolder": "Gagal menghapus kredensial dari folder.",
"folderRenamed": "Folder \"{{{oldName}}\" berhasil diganti namanya menjadi \"{{{newName}}\"", "folderRenamed": "Folder \"{{oldName}}\" berhasil diganti namanya menjadi \"{{newName}}\"",
"failedToRenameFolder": "Gagal mengganti nama folder", "failedToRenameFolder": "Gagal mengganti nama folder",
"movedToFolder": "Kredensial \"{{name}}\" berhasil dipindahkan ke \"{{folder}}\"", "movedToFolder": "Kredensial \"{{name}}\" berhasil dipindahkan ke \"{{folder}}\"",
"failedToMoveToFolder": "Gagal memindahkan kredensial ke folder.", "failedToMoveToFolder": "Gagal memindahkan kredensial ke folder.",
@@ -187,10 +187,10 @@
"dragIndicator": { "dragIndicator": {
"error": "Kesalahan: {{error}}", "error": "Kesalahan: {{error}}",
"dragging": "Menyeret {{fileName}}", "dragging": "Menyeret {{fileName}}",
"preparing": "Mempersiapkan 14", "preparing": "Mempersiapkan {{fileName}}",
"readySingle": "Siap untuk diunduh {{fileName}}", "readySingle": "Siap untuk diunduh {{fileName}}",
"readyMultiple": "Siap mengunduh {{fileName}} file", "readyMultiple": "Siap mengunduh {{count}} file",
"batchDrag": "Seret {{count}} berkas ke desktop", "batchDrag": "Seret {{count}} file ke desktop",
"dragToDesktop": "Seret ke desktop", "dragToDesktop": "Seret ke desktop",
"canDragAnywhere": "Anda dapat menyeret file ke mana saja di desktop Anda." "canDragAnywhere": "Anda dapat menyeret file ke mana saja di desktop Anda."
}, },
@@ -222,7 +222,7 @@
"name": "Nama", "name": "Nama",
"description": "Keterangan", "description": "Keterangan",
"content": "Memerintah", "content": "Memerintah",
"namePlaceholder": "Contoh: Restart Nginx", "namePlaceholder": "misalnya, Restart Nginx",
"descriptionPlaceholder": "Deskripsi opsional", "descriptionPlaceholder": "Deskripsi opsional",
"contentPlaceholder": "misalnya, sudo systemctl restart nginx", "contentPlaceholder": "misalnya, sudo systemctl restart nginx",
"nameRequired": "Nama wajib diisi.", "nameRequired": "Nama wajib diisi.",
@@ -230,7 +230,7 @@
"createDescription": "Buat cuplikan perintah baru untuk eksekusi cepat.", "createDescription": "Buat cuplikan perintah baru untuk eksekusi cepat.",
"editDescription": "Edit cuplikan perintah ini", "editDescription": "Edit cuplikan perintah ini",
"deleteConfirmTitle": "Hapus Cuplikan", "deleteConfirmTitle": "Hapus Cuplikan",
"deleteConfirmDescription": "Apakah Anda yakin ingin menghapus \"{{count}}\"?", "deleteConfirmDescription": "Apakah Anda yakin ingin menghapus \"{{name}}\"?",
"createSuccess": "Cuplikan berhasil dibuat.", "createSuccess": "Cuplikan berhasil dibuat.",
"updateSuccess": "Cuplikan berhasil diperbarui.", "updateSuccess": "Cuplikan berhasil diperbarui.",
"deleteSuccess": "Cuplikan berhasil dihapus", "deleteSuccess": "Cuplikan berhasil dihapus",
@@ -256,7 +256,7 @@
"updateFolderFailed": "Gagal memperbarui folder", "updateFolderFailed": "Gagal memperbarui folder",
"createFolderFailed": "Gagal membuat folder", "createFolderFailed": "Gagal membuat folder",
"selectTerminals": "Pilih Terminal (opsional)", "selectTerminals": "Pilih Terminal (opsional)",
"executeOnSelected": "Jalankan pada {{name}} terminal yang dipilih", "executeOnSelected": "Jalankan pada {{count}} terminal yang dipilih",
"executeOnCurrent": "Jalankan di terminal saat ini (klik untuk memilih beberapa)", "executeOnCurrent": "Jalankan di terminal saat ini (klik untuk memilih beberapa)",
"folder": "Map", "folder": "Map",
"selectFolder": "Pilih folder atau biarkan kosong.", "selectFolder": "Pilih folder atau biarkan kosong.",
@@ -280,7 +280,7 @@
"empty": "Belum ada riwayat perintah.", "empty": "Belum ada riwayat perintah.",
"emptyHint": "Jalankan perintah di terminal aktif untuk membangun riwayatnya.", "emptyHint": "Jalankan perintah di terminal aktif untuk membangun riwayatnya.",
"noResults": "Tidak ada perintah yang ditemukan", "noResults": "Tidak ada perintah yang ditemukan",
"noResultsHint": "Tidak ada perintah yang cocok dengan \"{{{count}}\"", "noResultsHint": "Tidak ada perintah yang cocok dengan \"{{query}}\"",
"deleteSuccess": "Perintah dihapus dari riwayat", "deleteSuccess": "Perintah dihapus dari riwayat",
"deleteFailed": "Perintah penghapusan gagal.", "deleteFailed": "Perintah penghapusan gagal.",
"deleteTooltip": "Perintah hapus", "deleteTooltip": "Perintah hapus",
@@ -308,7 +308,7 @@
"cleared": "Layar terpisah telah dibersihkan.", "cleared": "Layar terpisah telah dibersihkan.",
"error": { "error": {
"noAssignments": "Harap tetapkan setidaknya satu tab ke tata letak.", "noAssignments": "Harap tetapkan setidaknya satu tab ke tata letak.",
"fillAllSlots": "Harap isi semua {{query}} slot sebelum mendaftar." "fillAllSlots": "Harap isi semua {{count}} slot sebelum mendaftar"
} }
}, },
"homepage": { "homepage": {
@@ -343,10 +343,10 @@
"error": "Kesalahan Pemeriksaan Versi", "error": "Kesalahan Pemeriksaan Versi",
"checkFailed": "Gagal memeriksa pembaruan.", "checkFailed": "Gagal memeriksa pembaruan.",
"upToDate": "Aplikasi sudah diperbarui.", "upToDate": "Aplikasi sudah diperbarui.",
"currentVersion": "Anda menjalankan versi {{count}}", "currentVersion": "Anda menjalankan versi {{version}}",
"updateAvailable": "Pembaruan Tersedia", "updateAvailable": "Pembaruan Tersedia",
"newVersionAvailable": "Versi baru tersedia! Anda menjalankan {{version}}, tetapi {{current}} tersedia.", "newVersionAvailable": "Versi baru tersedia! Anda menjalankan {{current}}, tetapi {{latest}} tersedia.",
"releasedOn": "Dirilis pada {{latest}}", "releasedOn": "Dirilis pada {{date}}",
"downloadUpdate": "Unduh Pembaruan", "downloadUpdate": "Unduh Pembaruan",
"dismiss": "Membubarkan", "dismiss": "Membubarkan",
"checking": "Memeriksa pembaruan...", "checking": "Memeriksa pembaruan...",
@@ -354,7 +354,7 @@
"checkingUpdates": "Memeriksa pembaruan...", "checkingUpdates": "Memeriksa pembaruan...",
"refresh": "Menyegarkan", "refresh": "Menyegarkan",
"updateRequired": "Pembaruan Diperlukan", "updateRequired": "Pembaruan Diperlukan",
"updateDismissed": "Pemberitahuan pembaruan ditolak", "updateDismissed": "Pemberitahuan pembaruan ditolak.",
"noUpdatesFound": "Tidak ada pembaruan yang ditemukan." "noUpdatesFound": "Tidak ada pembaruan yang ditemukan."
}, },
"common": { "common": {
@@ -382,7 +382,7 @@
"home": "Rumah", "home": "Rumah",
"expired": "Kedaluwarsa", "expired": "Kedaluwarsa",
"expiresToday": "Berakhir hari ini", "expiresToday": "Berakhir hari ini",
"expiresTomorrow": "Berakhir dalam {{date}} hari", "expiresTomorrow": "Berakhir dalam {{days}} hari",
"updateAvailable": "Pembaruan Tersedia", "updateAvailable": "Pembaruan Tersedia",
"sshPath": "Jalur SSH", "sshPath": "Jalur SSH",
"localPath": "Jalur Lokal", "localPath": "Jalur Lokal",
@@ -392,7 +392,7 @@
"noAuthCredentials": "Tidak ada kredensial otentikasi yang tersedia untuk host SSH ini.", "noAuthCredentials": "Tidak ada kredensial otentikasi yang tersedia untuk host SSH ini.",
"noReleases": "Tidak ada rilis", "noReleases": "Tidak ada rilis",
"updatesAndReleases": "Pembaruan & Rilis", "updatesAndReleases": "Pembaruan & Rilis",
"newVersionAvailable": "Versi baru ({{days}}) tersedia.", "newVersionAvailable": "Versi baru ({{version}}) tersedia.",
"failedToFetchUpdateInfo": "Gagal mengambil informasi pembaruan.", "failedToFetchUpdateInfo": "Gagal mengambil informasi pembaruan.",
"preRelease": "Pra-rilis", "preRelease": "Pra-rilis",
"loginFailed": "Login gagal.", "loginFailed": "Login gagal.",
@@ -489,7 +489,7 @@
"hostManager": "Manajer Host", "hostManager": "Manajer Host",
"cannotSplitTab": "Tidak dapat memisahkan tab ini", "cannotSplitTab": "Tidak dapat memisahkan tab ini",
"tabNavigation": "Navigasi Tab", "tabNavigation": "Navigasi Tab",
"hostTabTitle": "{{version}}@{{username}}:{{ip}}" "hostTabTitle": "{{username}}@{{ip}}:{{port}}"
}, },
"admin": { "admin": {
"title": "Pengaturan Admin", "title": "Pengaturan Admin",
@@ -498,7 +498,7 @@
"userManagement": "Manajemen Pengguna", "userManagement": "Manajemen Pengguna",
"makeAdmin": "Jadikan Admin", "makeAdmin": "Jadikan Admin",
"removeAdmin": "Hapus Admin", "removeAdmin": "Hapus Admin",
"deleteUser": "Hapus pengguna {{port}}? Tindakan ini tidak dapat dibatalkan.", "deleteUser": "Hapus pengguna {{username}}? Tindakan ini tidak dapat dibatalkan.",
"allowRegistration": "Izinkan Pendaftaran", "allowRegistration": "Izinkan Pendaftaran",
"oidcSettings": "Pengaturan OIDC", "oidcSettings": "Pengaturan OIDC",
"clientId": "ID Klien", "clientId": "ID Klien",
@@ -537,7 +537,7 @@
"userRegistration": "Pendaftaran Pengguna", "userRegistration": "Pendaftaran Pengguna",
"allowNewAccountRegistration": "Izinkan pendaftaran akun baru", "allowNewAccountRegistration": "Izinkan pendaftaran akun baru",
"allowPasswordLogin": "Izinkan login menggunakan nama pengguna/kata sandi.", "allowPasswordLogin": "Izinkan login menggunakan nama pengguna/kata sandi.",
"missingRequiredFields": "Kolom yang wajib diisi belum terisi: {{username}}", "missingRequiredFields": "Kolom yang wajib diisi belum terisi: {{fields}}",
"oidcConfigurationUpdated": "Konfigurasi OIDC berhasil diperbarui!", "oidcConfigurationUpdated": "Konfigurasi OIDC berhasil diperbarui!",
"failedToFetchOidcConfig": "Gagal mengambil konfigurasi OIDC", "failedToFetchOidcConfig": "Gagal mengambil konfigurasi OIDC",
"failedToFetchRegistrationStatus": "Gagal mengambil status pendaftaran", "failedToFetchRegistrationStatus": "Gagal mengambil status pendaftaran",
@@ -547,7 +547,7 @@
"failedToUpdateOidcConfig": "Gagal memperbarui konfigurasi OIDC", "failedToUpdateOidcConfig": "Gagal memperbarui konfigurasi OIDC",
"failedToDisableOidcConfig": "Gagal menonaktifkan konfigurasi OIDC.", "failedToDisableOidcConfig": "Gagal menonaktifkan konfigurasi OIDC.",
"enterUsernameToMakeAdmin": "Masukkan nama pengguna untuk menjadi admin", "enterUsernameToMakeAdmin": "Masukkan nama pengguna untuk menjadi admin",
"userIsNowAdmin": "Pengguna {{fields}} sekarang menjadi admin", "userIsNowAdmin": "Pengguna {{username}} sekarang menjadi admin",
"failedToMakeUserAdmin": "Gagal menjadikan pengguna sebagai admin.", "failedToMakeUserAdmin": "Gagal menjadikan pengguna sebagai admin.",
"removeAdminStatus": "Hapus status admin dari {{username}}?", "removeAdminStatus": "Hapus status admin dari {{username}}?",
"adminStatusRemoved": "Status admin dihapus dari {{username}}", "adminStatusRemoved": "Status admin dihapus dari {{username}}",
@@ -611,11 +611,11 @@
"linkTargetUsernamePlaceholder": "Masukkan nama pengguna atau kata sandi akun Anda.", "linkTargetUsernamePlaceholder": "Masukkan nama pengguna atau kata sandi akun Anda.",
"linkAccountsButton": "Tautkan Akun", "linkAccountsButton": "Tautkan Akun",
"linkingAccounts": "Menghubungkan...", "linkingAccounts": "Menghubungkan...",
"accountsLinkedSuccessfully": "Pengguna OIDC {{username}} telah dihubungkan ke {{oidcUsername}}", "accountsLinkedSuccessfully": "Pengguna OIDC {{oidcUsername}} telah dihubungkan ke {{targetUsername}}",
"failedToLinkAccounts": "Gagal menautkan akun", "failedToLinkAccounts": "Gagal menautkan akun",
"linkTargetUsernameRequired": "Nama pengguna target wajib diisi.", "linkTargetUsernameRequired": "Nama pengguna target wajib diisi.",
"unlinkOIDCTitle": "Lepaskan Otentikasi OIDC", "unlinkOIDCTitle": "Lepaskan Otentikasi OIDC",
"unlinkOIDCDescription": "Hapus otentikasi OIDC dari {{targetUsername}}? Pengguna hanya akan dapat masuk dengan nama pengguna/kata sandi setelah ini.", "unlinkOIDCDescription": "Hapus otentikasi OIDC dari {{username}}? Pengguna hanya akan dapat masuk dengan nama pengguna/kata sandi setelah ini.",
"unlinkOIDCSuccess": "OIDC tidak terhubung dari {{username}}", "unlinkOIDCSuccess": "OIDC tidak terhubung dari {{username}}",
"failedToUnlinkOIDC": "Gagal melepaskan tautan OIDC", "failedToUnlinkOIDC": "Gagal melepaskan tautan OIDC",
"databaseSecurity": "Keamanan Basis Data", "databaseSecurity": "Keamanan Basis Data",
@@ -661,7 +661,7 @@
"loadingEncryptionStatus": "Memuat status enkripsi...", "loadingEncryptionStatus": "Memuat status enkripsi...",
"testMigrationDescription": "Pastikan bahwa data yang ada dapat dimigrasikan dengan aman ke format terenkripsi tanpa benar-benar memodifikasi data apa pun.", "testMigrationDescription": "Pastikan bahwa data yang ada dapat dimigrasikan dengan aman ke format terenkripsi tanpa benar-benar memodifikasi data apa pun.",
"serverMigrationGuide": "Panduan Migrasi Server", "serverMigrationGuide": "Panduan Migrasi Server",
"migrationInstructions": "Untuk memigrasikan data terenkripsi ke server baru: 1) Cadangkan file basis data, 2) Atur variabel lingkungan DB_ENCRYPTION_KEY=\"kunci-Anda\" pada server baru, 3) Pulihkan file basis data", "migrationInstructions": "Untuk memindahkan data terenkripsi ke server baru: 1) Cadangkan file basis data, 2) Atur variabel lingkungan DB_ENCRYPTION_KEY=\"kunci-Anda\" pada server baru, 3) Pulihkan file basis data",
"environmentProtection": "Perlindungan Lingkungan", "environmentProtection": "Perlindungan Lingkungan",
"environmentProtectionDesc": "Melindungi kunci enkripsi berdasarkan informasi lingkungan server (nama host, jalur, dll.), dapat dipindahkan melalui variabel lingkungan.", "environmentProtectionDesc": "Melindungi kunci enkripsi berdasarkan informasi lingkungan server (nama host, jalur, dll.), dapat dipindahkan melalui variabel lingkungan.",
"verificationCompleted": "Verifikasi kompatibilitas selesai - tidak ada data yang diubah.", "verificationCompleted": "Verifikasi kompatibilitas selesai - tidak ada data yang diubah.",
@@ -777,23 +777,23 @@
"retry": "Mencoba kembali", "retry": "Mencoba kembali",
"refresh": "Menyegarkan", "refresh": "Menyegarkan",
"optional": "Opsional", "optional": "Opsional",
"hostsCount": "{{username}} tuan rumah", "hostsCount": "{{count}} tuan rumah",
"importJson": "Impor JSON", "importJson": "Impor JSON",
"importing": "Pengimporan...", "importing": "Pengimporan...",
"importJsonTitle": "Impor Host SSH dari JSON", "importJsonTitle": "Impor Host SSH dari JSON",
"importJsonDesc": "Unggah file JSON untuk mengimpor beberapa host SSH secara massal (maksimal 100).", "importJsonDesc": "Unggah file JSON untuk mengimpor beberapa host SSH secara massal (maksimal 100).",
"downloadSample": "Unduh Sampel", "downloadSample": "Unduh Sampel",
"formatGuide": "Panduan Format", "formatGuide": "Panduan Format",
"exportCredentialWarning": "Peringatan: Host \"{{count}}\" menggunakan otentikasi kredensial. File yang diekspor tidak akan menyertakan data kredensial dan perlu dikonfigurasi ulang secara manual setelah impor. Apakah Anda ingin melanjutkan?", "exportCredentialWarning": "Peringatan: Host \"{{name}}\" menggunakan otentikasi kredensial. File yang diekspor tidak akan menyertakan data kredensial dan perlu dikonfigurasi ulang secara manual setelah impor. Apakah Anda ingin melanjutkan?",
"exportSensitiveDataWarning": "Peringatan: Host \"{{name}}\" berisi data otentikasi sensitif (kata sandi/kunci SSH). File yang diekspor akan menyertakan data ini dalam bentuk teks biasa. Harap simpan file ini dengan aman dan hapus setelah digunakan. Apakah Anda ingin melanjutkan?", "exportSensitiveDataWarning": "Peringatan: Host \"{{name}}\" berisi data otentikasi sensitif (kata sandi/kunci SSH). File yang diekspor akan menyertakan data ini dalam bentuk teks biasa. Harap simpan file ini dengan aman dan hapus setelah digunakan. Apakah Anda ingin melanjutkan?",
"uncategorized": "Tidak dikategorikan", "uncategorized": "Tidak dikategorikan",
"confirmDelete": "Apakah Anda yakin ingin menghapus \"{{name}}\"?", "confirmDelete": "Apakah Anda yakin ingin menghapus \"{{name}}\" ?",
"failedToDeleteHost": "Gagal menghapus host", "failedToDeleteHost": "Gagal menghapus host",
"failedToExportHost": "Ekspor host gagal. Pastikan Anda sudah login dan memiliki akses ke data host.", "failedToExportHost": "Ekspor host gagal. Pastikan Anda sudah login dan memiliki akses ke data host.",
"jsonMustContainHosts": "JSON harus berisi array \"hosts\" atau berupa array host.", "jsonMustContainHosts": "JSON harus berisi array \"hosts\" atau berupa array host.",
"noHostsInJson": "Tidak ditemukan host dalam file JSON.", "noHostsInJson": "Tidak ditemukan host dalam file JSON.",
"maxHostsAllowed": "Maksimal 100 host diperbolehkan per impor.", "maxHostsAllowed": "Maksimal 100 host diperbolehkan per impor.",
"importCompleted": "Impor selesai: {{name}} berhasil, {{success}} gagal", "importCompleted": "Impor selesai: {{success}} berhasil, {{failed}} gagal",
"importFailed": "Impor gagal", "importFailed": "Impor gagal",
"importError": "Kesalahan impor", "importError": "Kesalahan impor",
"failedToImportJson": "Gagal mengimpor file JSON", "failedToImportJson": "Gagal mengimpor file JSON",
@@ -816,9 +816,9 @@
"editHost": "Edit Host", "editHost": "Edit Host",
"cloneHost": "Kloning Host", "cloneHost": "Kloning Host",
"updateHost": "Perbarui Host", "updateHost": "Perbarui Host",
"hostUpdatedSuccessfully": "Host \"{{{failed}}\" berhasil diperbarui!", "hostUpdatedSuccessfully": "Host \"{{name}}\" berhasil diperbarui!",
"hostAddedSuccessfully": "Host \"{{{name}}\" berhasil ditambahkan!", "hostAddedSuccessfully": "Host \"{{name}}\" berhasil ditambahkan!",
"hostDeletedSuccessfully": "Host \"{{{name}}\" berhasil dihapus!", "hostDeletedSuccessfully": "Host \"{{name}}\" berhasil dihapus!",
"failedToSaveHost": "Gagal menyimpan host. Silakan coba lagi.", "failedToSaveHost": "Gagal menyimpan host. Silakan coba lagi.",
"savingHost": "Menyimpan host...", "savingHost": "Menyimpan host...",
"updatingHost": "Memperbarui host...", "updatingHost": "Memperbarui host...",
@@ -837,10 +837,10 @@
"connection": "Koneksi", "connection": "Koneksi",
"remove": "Menghapus", "remove": "Menghapus",
"sourcePort": "Port Sumber", "sourcePort": "Port Sumber",
"sourcePortDesc": "(Sumber mengacu pada Detail Koneksi Saat Ini di tab Umum)", "sourcePortDesc": " (Sumber mengacu pada Detail Koneksi Saat Ini di tab Umum)",
"endpointPort": "Port Titik Akhir", "endpointPort": "Port Titik Akhir",
"endpointSshConfig": "Konfigurasi SSH Titik Akhir", "endpointSshConfig": "Konfigurasi Endpoint SSH",
"tunnelForwardDescription": "Terowongan ini akan meneruskan lalu lintas dari port {{name}} pada mesin sumber (detail koneksi saat ini di tab umum) ke port {{sourcePort}} pada mesin titik akhir.", "tunnelForwardDescription": "Terowongan ini akan meneruskan lalu lintas dari port {{sourcePort}} pada mesin sumber (detail koneksi saat ini di tab umum) ke port {{endpointPort}} pada mesin titik akhir.",
"maxRetries": "Jumlah Percobaan Maksimum", "maxRetries": "Jumlah Percobaan Maksimum",
"maxRetriesDescription": "Jumlah maksimum percobaan ulang untuk koneksi terowongan.", "maxRetriesDescription": "Jumlah maksimum percobaan ulang untuk koneksi terowongan.",
"retryInterval": "Interval Percobaan Ulang (detik)", "retryInterval": "Interval Percobaan Ulang (detik)",
@@ -916,10 +916,10 @@
"customCommandsDesc": "Tetapkan perintah pematian dan memulai ulang khusus untuk server ini.", "customCommandsDesc": "Tetapkan perintah pematian dan memulai ulang khusus untuk server ini.",
"shutdownCommand": "Perintah Matikan", "shutdownCommand": "Perintah Matikan",
"rebootCommand": "Perintah Reboot", "rebootCommand": "Perintah Reboot",
"confirmRemoveFromFolder": "Apakah Anda yakin ingin menghapus \"{{endpointPort}}\" dari folder \"{{name}}\"? Host akan dipindahkan ke \"Tidak Ada Folder\".", "confirmRemoveFromFolder": "Apakah Anda yakin ingin menghapus \"{{name}}\" dari folder \"{{folder}}\"? Host akan dipindahkan ke \"Tidak Ada Folder\".",
"removedFromFolder": "Host \"{{{folder}}\" berhasil dihapus dari folder", "removedFromFolder": "Host \"{{name}}\" berhasil dihapus dari folder",
"failedToRemoveFromFolder": "Gagal menghapus host dari folder.", "failedToRemoveFromFolder": "Gagal menghapus host dari folder.",
"folderRenamed": "Folder \"{{{name}}\" berhasil diganti namanya menjadi \"{{{oldName}}\"", "folderRenamed": "Folder \"{{oldName}}\" berhasil diganti namanya menjadi \"{{newName}}\"",
"failedToRenameFolder": "Gagal mengganti nama folder", "failedToRenameFolder": "Gagal mengganti nama folder",
"editFolderAppearance": "Edit Tampilan Folder", "editFolderAppearance": "Edit Tampilan Folder",
"editFolderAppearanceDesc": "Sesuaikan warna dan ikon untuk folder.", "editFolderAppearanceDesc": "Sesuaikan warna dan ikon untuk folder.",
@@ -929,21 +929,21 @@
"folderAppearanceUpdated": "Tampilan folder berhasil diperbarui.", "folderAppearanceUpdated": "Tampilan folder berhasil diperbarui.",
"failedToUpdateFolderAppearance": "Gagal memperbarui tampilan folder", "failedToUpdateFolderAppearance": "Gagal memperbarui tampilan folder",
"deleteAllHostsInFolder": "Hapus Semua Host di Folder", "deleteAllHostsInFolder": "Hapus Semua Host di Folder",
"confirmDeleteAllHostsInFolder": "Apakah Anda yakin ingin menghapus semua {{newName}} host di folder \"{{count}}\"? Tindakan ini tidak dapat dibatalkan.", "confirmDeleteAllHostsInFolder": "Apakah Anda yakin ingin menghapus semua host {{count}} di folder \"{{folder}}\"? Tindakan ini tidak dapat dibatalkan.",
"allHostsInFolderDeleted": "Host sebanyak {{folder}} dari folder \"{{count}}\" berhasil dihapus.", "allHostsInFolderDeleted": "Host {{count}} dari folder \"{{folder}}\" berhasil dihapus",
"failedToDeleteHostsInFolder": "Gagal menghapus host di dalam folder.", "failedToDeleteHostsInFolder": "Gagal menghapus host di dalam folder.",
"movedToFolder": "Host \"{{folder}}\" berhasil dipindahkan ke \"{{name}}\"", "movedToFolder": "Host \"{{name}}\" berhasil dipindahkan ke \"{{folder}}\"",
"failedToMoveToFolder": "Gagal memindahkan host ke folder", "failedToMoveToFolder": "Gagal memindahkan host ke folder",
"clickToRenameFolder": "Klik untuk mengganti nama folder", "clickToRenameFolder": "Klik untuk mengganti nama folder",
"renameFolder": "Ganti nama folder", "renameFolder": "Ganti nama folder",
"removeFromFolder": "Hapus dari folder \"{{{folder}}\"", "removeFromFolder": "Hapus dari folder \"{{folder}}\"",
"editHostTooltip": "Edit host", "editHostTooltip": "Edit host",
"deleteHostTooltip": "Hapus host", "deleteHostTooltip": "Hapus host",
"exportHostTooltip": "Ekspor host", "exportHostTooltip": "Ekspor host",
"cloneHostTooltip": "Kloning host", "cloneHostTooltip": "Kloning host",
"clickToEditHost": "Klik untuk mengedit host", "clickToEditHost": "Klik untuk mengedit host",
"dragToMoveBetweenFolders": "Seret untuk berpindah antar folder", "dragToMoveBetweenFolders": "Seret untuk berpindah antar folder",
"exportedHostConfig": "Konfigurasi host yang diekspor untuk {{folder}}", "exportedHostConfig": "Konfigurasi host yang diekspor untuk {{name}}",
"openTerminal": "Terminal Terbuka", "openTerminal": "Terminal Terbuka",
"openFileManager": "Buka Pengelola File", "openFileManager": "Buka Pengelola File",
"openTunnels": "Terowongan Terbuka", "openTunnels": "Terowongan Terbuka",
@@ -982,7 +982,7 @@
"selectFont": "Pilih font", "selectFont": "Pilih font",
"selectFontDesc": "Pilih font yang akan digunakan di terminal.", "selectFontDesc": "Pilih font yang akan digunakan di terminal.",
"fontSize": "Ukuran Huruf", "fontSize": "Ukuran Huruf",
"fontSizeValue": "Ukuran Huruf: {{name}}px", "fontSizeValue": "Ukuran Huruf: {{value}}px",
"adjustFontSize": "Sesuaikan ukuran font terminal", "adjustFontSize": "Sesuaikan ukuran font terminal",
"letterSpacing": "Jarak Antar Huruf", "letterSpacing": "Jarak Antar Huruf",
"letterSpacingValue": "Jarak Antar Huruf: {{value}}px", "letterSpacingValue": "Jarak Antar Huruf: {{value}}px",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "Suara", "bellStyleSound": "Suara",
"bellStyleVisual": "Visual", "bellStyleVisual": "Visual",
"bellStyleBoth": "Keduanya", "bellStyleBoth": "Keduanya",
"bellStyleDesc": "Cara menangani bel terminal (karakter BEL, \\x07). Program memicu ini saat menyelesaikan tugas, menemukan kesalahan, atau untuk pemberitahuan. \"Sound\" memutar bunyi bip audio, \"Visual\" membuat layar berkedip sebentar, \"Both\" melakukan keduanya, \"None\" menonaktifkan peringatan bel.", "bellStyleDesc": "Cara menangani bel terminal (karakter BEL, \\x07). Program memicu ini saat menyelesaikan tugas, menemukan kesalahan, atau untuk pemberitahuan. \"Suara\" memutar bunyi bip audio, \"Visual\" membuat layar berkedip sebentar, \"Keduanya\" melakukan keduanya, \"Tidak ada\" menonaktifkan peringatan bel.",
"rightClickSelectsWord": "Klik kanan memilih Word", "rightClickSelectsWord": "Klik kanan memilih Word",
"rightClickSelectsWordDesc": "Mengklik kanan akan memilih kata di bawah kursor.", "rightClickSelectsWordDesc": "Mengklik kanan akan memilih kata di bawah kursor.",
"fastScrollModifier": "Pengubah Gulir Cepat", "fastScrollModifier": "Pengubah Gulir Cepat",
@@ -1066,7 +1066,7 @@
"socks5UsePreset": "Gunakan Preset yang Tersimpan", "socks5UsePreset": "Gunakan Preset yang Tersimpan",
"socks5SelectPreset": "Pilih Preset", "socks5SelectPreset": "Pilih Preset",
"socks5ManagePresets": "Kelola Preset", "socks5ManagePresets": "Kelola Preset",
"socks5ProxyNode": "Proksi {{value}}", "socks5ProxyNode": "Proksi {{number}}",
"socks5AddProxy": "Tambahkan Proxy ke Rantai", "socks5AddProxy": "Tambahkan Proxy ke Rantai",
"socks5RemoveProxy": "Hapus Proxy", "socks5RemoveProxy": "Hapus Proxy",
"socks5ProxyType": "Jenis Proksi", "socks5ProxyType": "Jenis Proksi",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "Preset rantai proxy telah dibuat.", "socks5PresetCreated": "Preset rantai proxy telah dibuat.",
"socks5PresetUpdated": "Preset rantai proxy telah diperbarui.", "socks5PresetUpdated": "Preset rantai proxy telah diperbarui.",
"socks5PresetDeleted": "Pengaturan awal rantai proxy telah dihapus.", "socks5PresetDeleted": "Pengaturan awal rantai proxy telah dihapus.",
"socks5PresetSaved": "Preset \"{{{number}}\" berhasil disimpan", "socks5PresetSaved": "Preset \"{{name}}\" berhasil disimpan",
"socks5PresetSaveError": "Gagal menyimpan preset.", "socks5PresetSaveError": "Gagal menyimpan preset.",
"socks5PresetNameRequired": "Nama preset wajib diisi.", "socks5PresetNameRequired": "Nama preset wajib diisi.",
"socks5EmptyChainError": "Tidak dapat menyimpan rantai proksi kosong.", "socks5EmptyChainError": "Tidak dapat menyimpan rantai proksi kosong.",
@@ -1118,8 +1118,8 @@
"notEnabled": "Docker belum diaktifkan untuk host ini. Aktifkan di Pengaturan Host untuk menggunakan fitur Docker.", "notEnabled": "Docker belum diaktifkan untuk host ini. Aktifkan di Pengaturan Host untuk menggunakan fitur Docker.",
"validating": "Memvalidasi Docker...", "validating": "Memvalidasi Docker...",
"error": "Kesalahan", "error": "Kesalahan",
"errorCode": "Kode kesalahan: {{name}}", "errorCode": "Kode kesalahan: {{code}}",
"version": "Docker v{{code}}", "version": "Docker v{{version}}",
"current": "Saat ini", "current": "Saat ini",
"used_limit": "Digunakan / Batas", "used_limit": "Digunakan / Batas",
"percentage": "Persentase", "percentage": "Persentase",
@@ -1133,10 +1133,10 @@
"console": "Menghibur", "console": "Menghibur",
"containerMustBeRunning": "Kontainer harus berjalan agar dapat terhubung ke konsol.", "containerMustBeRunning": "Kontainer harus berjalan agar dapat terhubung ke konsol.",
"authenticationRequired": "Diperlukan otentikasi.", "authenticationRequired": "Diperlukan otentikasi.",
"connectedTo": "Terhubung ke {{version}}", "connectedTo": "Terhubung ke {{containerName}}",
"disconnected": "Terputus", "disconnected": "Terputus",
"consoleError": "Kesalahan konsol", "consoleError": "Kesalahan konsol",
"errorMessage": "Kesalahan: {{containerName}}", "errorMessage": "Kesalahan: {{message}}",
"failedToConnect": "Gagal terhubung ke konsol", "failedToConnect": "Gagal terhubung ke konsol",
"disconnectedFromContainer": "Terputus dari konsol kontainer.", "disconnectedFromContainer": "Terputus dari konsol kontainer.",
"containerNotRunning": "Kontainer tidak berjalan", "containerNotRunning": "Kontainer tidak berjalan",
@@ -1150,28 +1150,28 @@
"disconnect": "Memutuskan", "disconnect": "Memutuskan",
"notConnected": "Tidak terhubung", "notConnected": "Tidak terhubung",
"clickToConnect": "Klik Sambungkan untuk memulai shell interaktif.", "clickToConnect": "Klik Sambungkan untuk memulai shell interaktif.",
"connectingTo": "Menghubungkan ke {{message}}...", "connectingTo": "Menghubungkan ke {{containerName}}...",
"containerMustBeRunningToViewStats": "Kontainer harus berjalan agar statistik dapat dilihat.", "containerMustBeRunningToViewStats": "Kontainer harus berjalan agar statistik dapat dilihat.",
"failedToFetchStats": "Gagal mengambil statistik.", "failedToFetchStats": "Gagal mengambil statistik.",
"noContainersFound": "Tidak ditemukan wadah apa pun", "noContainersFound": "Tidak ditemukan wadah apa pun",
"noContainersFoundHint": "Mulailah dengan membuat kontainer di server Anda.", "noContainersFoundHint": "Mulailah dengan membuat kontainer di server Anda.",
"searchPlaceholder": "Cari berdasarkan nama, gambar, atau ID...", "searchPlaceholder": "Cari berdasarkan nama, gambar, atau ID...",
"filterByStatusPlaceholder": "Saring berdasarkan status", "filterByStatusPlaceholder": "Saring berdasarkan status",
"allContainersCount": "Semua ({{containerName}})", "allContainersCount": "Semua ({{count}})",
"statusCount": "{{count}} ({{status}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "Tidak ada wadah yang sesuai dengan filter Anda.", "noContainersMatchFilters": "Tidak ada wadah yang sesuai dengan filter Anda.",
"noContainersMatchFiltersHint": "Cobalah menyesuaikan pencarian atau filter Anda.", "noContainersMatchFiltersHint": "Cobalah menyesuaikan pencarian atau filter Anda.",
"containerStarted": "Kontainer {{count}} dimulai", "containerStarted": "Kontainer {{name}} dimulai",
"failedToStartContainer": "Gagal memulai kontainer: {{name}}", "failedToStartContainer": "Gagal memulai kontainer: {{error}}",
"containerStopped": "Kontainer {{error}} berhenti", "containerStopped": "Kontainer {{name}} berhenti",
"failedToStopContainer": "Gagal menghentikan kontainer: {{name}}", "failedToStopContainer": "Gagal menghentikan kontainer: {{error}}",
"containerRestarted": "Kontainer {{error}} dimulai ulang", "containerRestarted": "Kontainer {{name}} dimulai ulang",
"failedToRestartContainer": "Gagal memulai ulang kontainer: {{name}}", "failedToRestartContainer": "Gagal memulai ulang kontainer: {{error}}",
"containerUnpaused": "Kontainer {{error}} tidak dijeda", "containerUnpaused": "Kontainer {{name}} tidak dijeda",
"containerPaused": "Kontainer {{name}} berhenti sementara", "containerPaused": "Kontainer {{name}} berhenti",
"failedToTogglePauseContainer": "Gagal ke kontainer {{name}}: {{action}}", "failedToTogglePauseContainer": "Gagal ke kontainer {{action}} : {{error}}",
"containerRemoved": "Kontainer {{error}} dihapus", "containerRemoved": "Kontainer {{name}} dihapus",
"failedToRemoveContainer": "Gagal menghapus kontainer: {{name}}", "failedToRemoveContainer": "Gagal menghapus kontainer: {{error}}",
"image": "Gambar:", "image": "Gambar:",
"idLabel": "PENGENAL:", "idLabel": "PENGENAL:",
"ports": "Pelabuhan:", "ports": "Pelabuhan:",
@@ -1183,7 +1183,7 @@
"pause": "Berhenti sebentar", "pause": "Berhenti sebentar",
"restart": "Mulai ulang", "restart": "Mulai ulang",
"removeContainer": "Lepaskan Kontainer", "removeContainer": "Lepaskan Kontainer",
"confirmRemoveContainer": "Apakah Anda yakin ingin menghapus kontainer \"{{error}}\"?", "confirmRemoveContainer": "Apakah Anda yakin ingin menghapus kontainer \"{{name}}\"?",
"runningContainerWarning": "Peringatan: Kontainer ini sedang berjalan dan akan dihapus secara paksa.", "runningContainerWarning": "Peringatan: Kontainer ini sedang berjalan dan akan dihapus secara paksa.",
"removing": "Menghapus:", "removing": "Menghapus:",
"containerNotFound": "Kontainer tidak ditemukan", "containerNotFound": "Kontainer tidak ditemukan",
@@ -1191,7 +1191,7 @@
"logs": "Log", "logs": "Log",
"stats": "Statistik", "stats": "Statistik",
"consoleTab": "Menghibur", "consoleTab": "Menghibur",
"failedToFetchLogs": "Gagal mengambil log: {{name}}", "failedToFetchLogs": "Gagal mengambil log: {{error}}",
"failedToDownloadLogs": "Gagal mengunduh log: {{error}}", "failedToDownloadLogs": "Gagal mengunduh log: {{error}}",
"linesToShow": "Garis untuk menunjukkan", "linesToShow": "Garis untuk menunjukkan",
"last50Lines": "50 baris terakhir", "last50Lines": "50 baris terakhir",
@@ -1219,7 +1219,7 @@
"reconnect": "Terhubung kembali", "reconnect": "Terhubung kembali",
"sessionEnded": "Sesi Berakhir", "sessionEnded": "Sesi Berakhir",
"connectionLost": "Koneksi Terputus", "connectionLost": "Koneksi Terputus",
"error": "KESALAHAN: {{error}}", "error": "KESALAHAN: {{message}}",
"disconnected": "Terputus", "disconnected": "Terputus",
"connectionClosed": "Koneksi terputus", "connectionClosed": "Koneksi terputus",
"connectionError": "Kesalahan koneksi: {{message}}", "connectionError": "Kesalahan koneksi: {{message}}",
@@ -1230,18 +1230,18 @@
"messageParseError": "Gagal mengurai pesan server", "messageParseError": "Gagal mengurai pesan server",
"websocketError": "Kesalahan koneksi WebSocket", "websocketError": "Kesalahan koneksi WebSocket",
"connecting": "Menghubungkan...", "connecting": "Menghubungkan...",
"reconnecting": "Menghubungkan kembali... ({{message}}/{{attempt}})", "reconnecting": "Menghubungkan kembali... ({{attempt}}/{{max}})",
"reconnected": "Berhasil terhubung kembali", "reconnected": "Berhasil terhubung kembali",
"maxReconnectAttemptsReached": "Upaya penyambungan kembali maksimum telah tercapai.", "maxReconnectAttemptsReached": "Upaya penyambungan kembali maksimum telah tercapai.",
"connectionTimeout": "Waktu habis koneksi", "connectionTimeout": "Waktu habis koneksi",
"terminalTitle": "Terminal - {{max}}", "terminalTitle": "Terminal - {{host}}",
"terminalWithPath": "Terminal - {{host}}:{{host}}", "terminalWithPath": "Terminal - {{host}}:{{path}}",
"runTitle": "Menjalankan {{path}} - {{command}}", "runTitle": "Menjalankan {{command}} - {{host}}",
"totpRequired": "Diperlukan Otentikasi Dua Faktor", "totpRequired": "Diperlukan Otentikasi Dua Faktor",
"totpCodeLabel": "Kode Verifikasi", "totpCodeLabel": "Kode Verifikasi",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
"totpVerify": "Memeriksa", "totpVerify": "Memeriksa",
"sudoPasswordPopupTitle": "Masukkan Kata Sandi?", "sudoPasswordPopupTitle": "Masukkan kata sandi?",
"sudoPasswordPopupHint": "Tekan Enter untuk memasukkan, Esc untuk menutup.", "sudoPasswordPopupHint": "Tekan Enter untuk memasukkan, Esc untuk menutup.",
"sudoPasswordPopupConfirm": "Menyisipkan", "sudoPasswordPopupConfirm": "Menyisipkan",
"sudoPasswordPopupDismiss": "Membubarkan" "sudoPasswordPopupDismiss": "Membubarkan"
@@ -1254,26 +1254,26 @@
"uploadFile": "Unggah File", "uploadFile": "Unggah File",
"downloadFile": "Unduh", "downloadFile": "Unduh",
"extractArchive": "Ekstrak Arsip", "extractArchive": "Ekstrak Arsip",
"extractingArchive": "Mengekstrak {{host}}...", "extractingArchive": "Mengekstrak {{name}}...",
"archiveExtractedSuccessfully": "{{name}} berhasil diekstrak", "archiveExtractedSuccessfully": "{{name}} berhasil diekstrak",
"extractFailed": "Ekstraksi gagal", "extractFailed": "Ekstraksi gagal",
"compressFile": "Kompres File", "compressFile": "Kompres File",
"compressFiles": "Kompres File", "compressFiles": "Kompres File",
"compressFilesDesc": "Kompres {{name}} item ke dalam arsip", "compressFilesDesc": "Kompres {{count}} item ke dalam arsip",
"archiveName": "Nama Arsip", "archiveName": "Nama Arsip",
"enterArchiveName": "Masukkan nama arsip...", "enterArchiveName": "Masukkan nama arsip...",
"compressionFormat": "Format Kompresi", "compressionFormat": "Format Kompresi",
"selectedFiles": "File terpilih", "selectedFiles": "File terpilih",
"andMoreFiles": "dan {{count}} lainnya...", "andMoreFiles": "dan {{count}} lagi...",
"compress": "Kompres", "compress": "Kompres",
"compressingFiles": "Mengompres {{count}} item menjadi {{count}}...", "compressingFiles": "Mengompres {{count}} item menjadi {{name}}...",
"filesCompressedSuccessfully": "{{name}} berhasil dibuat", "filesCompressedSuccessfully": "{{name}} berhasil dibuat",
"compressFailed": "Kompresi gagal", "compressFailed": "Kompresi gagal",
"edit": "Edit", "edit": "Edit",
"preview": "Pratinjau", "preview": "Pratinjau",
"previous": "Sebelumnya", "previous": "Sebelumnya",
"next": "Berikutnya", "next": "Berikutnya",
"pageXOfY": "Halaman {{name}} dari {{current}}", "pageXOfY": "Halaman {{current}} dari {{total}}",
"zoomOut": "Perkecil tampilan", "zoomOut": "Perkecil tampilan",
"zoomIn": "Perbesar", "zoomIn": "Perbesar",
"newFile": "Berkas Baru", "newFile": "Berkas Baru",
@@ -1289,13 +1289,13 @@
"chooseFile": "Pilih File", "chooseFile": "Pilih File",
"uploading": "Sedang mengunggah...", "uploading": "Sedang mengunggah...",
"downloading": "Sedang mengunduh...", "downloading": "Sedang mengunduh...",
"uploadingFile": "Mengunggah {{total}}...", "uploadingFile": "Mengunggah {{name}}...",
"uploadingLargeFile": "Mengunggah file besar {{name}} ({{name}})...", "uploadingLargeFile": "Mengunggah file besar {{name}} ({{size}})...",
"downloadingFile": "Mengunduh {{size}}...", "downloadingFile": "Mengunduh {{name}}...",
"creatingFile": "Membuat {{name}}...", "creatingFile": "Membuat {{name}}...",
"creatingFolder": "Membuat {{name}}...", "creatingFolder": "Membuat {{name}}...",
"deletingItem": "Menghapus {{name}} {{type}}...", "deletingItem": "Menghapus {{type}} {{name}}...",
"renamingItem": "Mengganti nama {{name}} {{type}} menjadi {{oldName}}...", "renamingItem": "Mengganti nama {{type}} {{oldName}} menjadi {{newName}}...",
"createNewFile": "Buat File Baru", "createNewFile": "Buat File Baru",
"fileName": "Nama File", "fileName": "Nama File",
"creating": "Membuat...", "creating": "Membuat...",
@@ -1311,21 +1311,21 @@
"newName": "Nama Baru", "newName": "Nama Baru",
"thisIsDirectoryRename": "Ini adalah direktori", "thisIsDirectoryRename": "Ini adalah direktori",
"renaming": "Mengganti nama...", "renaming": "Mengganti nama...",
"fileUploadedSuccessfully": "Berkas \"{{{newName}}\" berhasil diunggah", "fileUploadedSuccessfully": "Berkas \"{{name}}\" berhasil diunggah",
"failedToUploadFile": "Gagal mengunggah file", "failedToUploadFile": "Gagal mengunggah file",
"fileDownloadedSuccessfully": "Berkas \"{{{name}}\" berhasil diunduh", "fileDownloadedSuccessfully": "File \"{{name}}\" berhasil diunduh",
"failedToDownloadFile": "Gagal mengunduh file", "failedToDownloadFile": "Gagal mengunduh file",
"noFileContent": "Tidak ada konten file yang diterima.", "noFileContent": "Tidak ada konten file yang diterima.",
"filePath": "Jalur File", "filePath": "Jalur File",
"fileCreatedSuccessfully": "Berkas \"{{{name}}\" berhasil dibuat", "fileCreatedSuccessfully": "File \"{{name}}\" berhasil dibuat",
"failedToCreateFile": "Gagal membuat file", "failedToCreateFile": "Gagal membuat file",
"folderCreatedSuccessfully": "Folder \"{{{name}}\" berhasil dibuat", "folderCreatedSuccessfully": "Folder \"{{name}}\" berhasil dibuat",
"failedToCreateFolder": "Gagal membuat folder", "failedToCreateFolder": "Gagal membuat folder",
"failedToCreateItem": "Gagal membuat item", "failedToCreateItem": "Gagal membuat item",
"operationFailed": "Operasi {{name}} gagal untuk {{operation}}: {{name}}", "operationFailed": "Operasi {{operation}} gagal untuk {{name}}: {{error}}",
"failedToResolveSymlink": "Gagal menyelesaikan symlink", "failedToResolveSymlink": "Gagal menyelesaikan symlink",
"itemDeletedSuccessfully": "{{error}} berhasil dihapus", "itemDeletedSuccessfully": "{{type}} berhasil dihapus",
"itemsDeletedSuccessfully": "{{type}} item berhasil dihapus", "itemsDeletedSuccessfully": "{{count}} item berhasil dihapus",
"failedToDeleteItems": "Gagal menghapus item", "failedToDeleteItems": "Gagal menghapus item",
"dragFilesToUpload": "Seret file ke sini untuk mengunggah", "dragFilesToUpload": "Seret file ke sini untuk mengunggah",
"emptyFolder": "Folder ini kosong", "emptyFolder": "Folder ini kosong",
@@ -1347,25 +1347,25 @@
"delete": "Menghapus", "delete": "Menghapus",
"properties": "Properti", "properties": "Properti",
"refresh": "Menyegarkan", "refresh": "Menyegarkan",
"downloadFiles": "Unduh {{count}} berkas ke Browser", "downloadFiles": "Unduh {{count}} file ke Browser",
"copyFiles": "Salin {{count}} item", "copyFiles": "Salin {{count}} item",
"cutFiles": "Potong {{count}} item", "cutFiles": "Potong {{count}} item",
"deleteFiles": "Hapus {{count}} item", "deleteFiles": "Hapus {{count}} item",
"filesCopiedToClipboard": "{{count}} item disalin ke papan klip", "filesCopiedToClipboard": "{{count}} item disalin ke papan klip",
"filesCutToClipboard": "{{count}} item disalin ke papan klip", "filesCutToClipboard": "{{count}} item dipotong ke papan klip",
"pathCopiedToClipboard": "Jalur disalin ke papan klip", "pathCopiedToClipboard": "Jalur disalin ke papan klip",
"pathsCopiedToClipboard": "{{count}} jalur disalin ke papan klip", "pathsCopiedToClipboard": "{{count}} jalur disalin ke papan klip",
"failedToCopyPath": "Gagal menyalin jalur ke papan klip.", "failedToCopyPath": "Gagal menyalin jalur ke papan klip.",
"movedItems": "Memindahkan {{count}} item", "movedItems": "Memindahkan {{count}} item",
"failedToDeleteItem": "Gagal menghapus item", "failedToDeleteItem": "Gagal menghapus item",
"itemRenamedSuccessfully": "{{count}} berhasil diganti namanya", "itemRenamedSuccessfully": "{{type}} berhasil diganti namanya",
"failedToRenameItem": "Gagal mengganti nama item", "failedToRenameItem": "Gagal mengganti nama item",
"download": "Unduh", "download": "Unduh",
"permissions": "Izin", "permissions": "Izin",
"size": "Ukuran", "size": "Ukuran",
"modified": "Dimodifikasi", "modified": "Dimodifikasi",
"path": "Jalur", "path": "Jalur",
"confirmDelete": "Apakah Anda yakin ingin menghapus {{type}}?", "confirmDelete": "Apakah Anda yakin ingin menghapus {{name}}?",
"uploadSuccess": "File berhasil diunggah.", "uploadSuccess": "File berhasil diunggah.",
"uploadFailed": "Unggahan berkas gagal", "uploadFailed": "Unggahan berkas gagal",
"downloadSuccess": "File berhasil diunduh.", "downloadSuccess": "File berhasil diunduh.",
@@ -1390,9 +1390,9 @@
"fileOperations": "Operasi File", "fileOperations": "Operasi File",
"confirmDeleteMessage": "Apakah Anda yakin ingin menghapus {{name}}?", "confirmDeleteMessage": "Apakah Anda yakin ingin menghapus {{name}}?",
"confirmDeleteSingleItem": "Apakah Anda yakin ingin menghapus \"{{name}}\" secara permanen?", "confirmDeleteSingleItem": "Apakah Anda yakin ingin menghapus \"{{name}}\" secara permanen?",
"confirmDeleteMultipleItems": "Apakah Anda yakin ingin menghapus {{name}} item secara permanen?", "confirmDeleteMultipleItems": "Apakah Anda yakin ingin menghapus {{count}} item secara permanen?",
"confirmDeleteMultipleItemsWithFolders": "Apakah Anda yakin ingin menghapus {{count}} item secara permanen? Ini termasuk folder dan isinya.", "confirmDeleteMultipleItemsWithFolders": "Apakah Anda yakin ingin menghapus {{count}} item secara permanen? Ini termasuk folder dan isinya.",
"confirmDeleteFolder": "Apakah Anda yakin ingin menghapus folder \"{{count}}{{name}}\" dan seluruh isinya secara permanen?", "confirmDeleteFolder": "Apakah Anda yakin ingin menghapus folder \"{{name}}\" beserta seluruh isinya secara permanen?",
"deleteDirectoryWarning": "Ini akan menghapus folder dan semua isinya.", "deleteDirectoryWarning": "Ini akan menghapus folder dan semua isinya.",
"actionCannotBeUndone": "Tindakan ini tidak dapat dibatalkan.", "actionCannotBeUndone": "Tindakan ini tidak dapat dibatalkan.",
"permanentDeleteWarning": "Tindakan ini tidak dapat dibatalkan. Item tersebut akan dihapus secara permanen dari server.", "permanentDeleteWarning": "Tindakan ini tidak dapat dibatalkan. Item tersebut akan dihapus secara permanen dari server.",
@@ -1433,7 +1433,7 @@
"unpinnedSuccessfully": "Pin \"{{name}}\" berhasil dilepas", "unpinnedSuccessfully": "Pin \"{{name}}\" berhasil dilepas",
"unpinFailed": "Gagal membuka pin", "unpinFailed": "Gagal membuka pin",
"removedShortcut": "Pintasan \"{{name}}\" telah dihapus", "removedShortcut": "Pintasan \"{{name}}\" telah dihapus",
"removeShortcutFailed": "Penghapusan pintasan gagal", "removeShortcutFailed": "Penghapusan pintasan gagal.",
"clearedAllRecentFiles": "Semua file terbaru telah dihapus.", "clearedAllRecentFiles": "Semua file terbaru telah dihapus.",
"clearFailed": "Hapus gagal", "clearFailed": "Hapus gagal",
"removeFromRecentFiles": "Hapus dari berkas terbaru", "removeFromRecentFiles": "Hapus dari berkas terbaru",
@@ -1449,7 +1449,7 @@
"undoCopySuccess": "Batalkan operasi penyalinan: Menghapus {{count}} file yang disalin", "undoCopySuccess": "Batalkan operasi penyalinan: Menghapus {{count}} file yang disalin",
"undoCopyFailedDelete": "Pembatalan gagal: Tidak dapat menghapus file yang disalin.", "undoCopyFailedDelete": "Pembatalan gagal: Tidak dapat menghapus file yang disalin.",
"undoCopyFailedNoInfo": "Pembatalan gagal: Informasi file yang disalin tidak ditemukan.", "undoCopyFailedNoInfo": "Pembatalan gagal: Informasi file yang disalin tidak ditemukan.",
"undoMoveSuccess": "Operasi pemindahan dibatalkan: Memindahkan {{count}} file kembali ke lokasi semula", "undoMoveSuccess": "Operasi pemindahan dibatalkan: {{count}} berkas dipindahkan kembali ke lokasi semula",
"undoMoveFailedMove": "Pembatalan gagal: Tidak dapat memindahkan file apa pun kembali.", "undoMoveFailedMove": "Pembatalan gagal: Tidak dapat memindahkan file apa pun kembali.",
"undoMoveFailedNoInfo": "Pembatalan gagal: Informasi file yang dipindahkan tidak ditemukan.", "undoMoveFailedNoInfo": "Pembatalan gagal: Informasi file yang dipindahkan tidak ditemukan.",
"undoDeleteNotSupported": "Operasi penghapusan tidak dapat dibatalkan: File telah dihapus secara permanen dari server.", "undoDeleteNotSupported": "Operasi penghapusan tidak dapat dibatalkan: File telah dihapus secara permanen dari server.",
@@ -1491,7 +1491,7 @@
"unknownSize": "Ukuran tidak diketahui", "unknownSize": "Ukuran tidak diketahui",
"fileIsEmpty": "Berkas kosong", "fileIsEmpty": "Berkas kosong",
"largeFileWarning": "Peringatan Ukuran File Besar", "largeFileWarning": "Peringatan Ukuran File Besar",
"largeFileWarningDesc": "File ini berukuran {{size}}, yang dapat menyebabkan masalah kinerja saat dibuka sebagai teks.", "largeFileWarningDesc": "File ini berukuran {{size}} , yang dapat menyebabkan masalah kinerja saat dibuka sebagai teks.",
"fileNotFoundAndRemoved": "Berkas \"{{name}}\" tidak ditemukan dan telah dihapus dari berkas terbaru/yang disematkan", "fileNotFoundAndRemoved": "Berkas \"{{name}}\" tidak ditemukan dan telah dihapus dari berkas terbaru/yang disematkan",
"failedToLoadFile": "Gagal memuat file: {{error}}", "failedToLoadFile": "Gagal memuat file: {{error}}",
"serverErrorOccurred": "Terjadi kesalahan server. Silakan coba lagi nanti.", "serverErrorOccurred": "Terjadi kesalahan server. Silakan coba lagi nanti.",
@@ -1502,22 +1502,22 @@
"canOnlyCompareFiles": "Hanya dapat membandingkan dua file.", "canOnlyCompareFiles": "Hanya dapat membandingkan dua file.",
"comparingFiles": "Membandingkan berkas: {{file1}} dan {{file2}}", "comparingFiles": "Membandingkan berkas: {{file1}} dan {{file2}}",
"dragFailed": "Operasi seret gagal", "dragFailed": "Operasi seret gagal",
"filePinnedSuccessfully": "Berkas \"{{{name}}\" berhasil disematkan", "filePinnedSuccessfully": "Berkas \"{{name}}\" berhasil disematkan",
"pinFileFailed": "Gagal menyematkan file", "pinFileFailed": "Gagal menyematkan file",
"fileUnpinnedSuccessfully": "Berkas \"{{{name}}\" berhasil dilepas pinnya", "fileUnpinnedSuccessfully": "Berkas \"{{name}}\" berhasil dilepas pinnya",
"unpinFileFailed": "Gagal melepaskan pin file", "unpinFileFailed": "Gagal melepaskan pin file",
"shortcutAddedSuccessfully": "Pintasan folder \"{{{name}}\" berhasil ditambahkan", "shortcutAddedSuccessfully": "Pintasan folder \"{{name}}\" berhasil ditambahkan",
"addShortcutFailed": "Gagal menambahkan pintasan", "addShortcutFailed": "Gagal menambahkan pintasan",
"operationCompletedSuccessfully": "{{operation}} {{count}} item berhasil", "operationCompletedSuccessfully": "{{operation}} {{count}} item berhasil",
"operationCompleted": "{{operation}} {{count}} item", "operationCompleted": "{{operation}} {{count}} item",
"downloadFileSuccess": "Berkas {{name}} berhasil diunduh", "downloadFileSuccess": "File {{name}} berhasil diunduh",
"downloadFileFailed": "Pengunduhan gagal", "downloadFileFailed": "Pengunduhan gagal",
"moveTo": "Pindah ke {{name}}", "moveTo": "Pindah ke {{name}}",
"diffCompareWith": "Bandingkan perbedaan dengan {{name}}", "diffCompareWith": "Bandingkan perbedaan dengan {{name}}",
"dragOutsideToDownload": "Seret ke luar jendela untuk mengunduh (187 file)", "dragOutsideToDownload": "Seret ke luar jendela untuk mengunduh ({{count}} file)",
"newFolderDefault": "Folder Baru", "newFolderDefault": "Folder Baru",
"newFileDefault": "File Baru.txt", "newFileDefault": "File Baru.txt",
"successfullyMovedItems": "Berhasil memindahkan {{count}} item ke {{count}}", "successfullyMovedItems": "Berhasil memindahkan {{count}} item ke {{target}}",
"move": "Bergerak", "move": "Bergerak",
"searchInFile": "Cari di dalam file (Ctrl+F)", "searchInFile": "Cari di dalam file (Ctrl+F)",
"showKeyboardShortcuts": "Tampilkan pintasan keyboard", "showKeyboardShortcuts": "Tampilkan pintasan keyboard",
@@ -1527,10 +1527,10 @@
"compare": "Membandingkan", "compare": "Membandingkan",
"sideBySide": "Berdampingan", "sideBySide": "Berdampingan",
"inline": "Sejajar", "inline": "Sejajar",
"fileComparison": "Perbandingan Berkas: {{target}} vs {{file1}}", "fileComparison": "Perbandingan File: {{file1}} vs {{file2}}",
"fileTooLarge": "Ukuran berkas terlalu besar: {{file2}}", "fileTooLarge": "Ukuran file terlalu besar: {{error}}",
"sshConnectionFailed": "Koneksi SSH gagal. Silakan periksa koneksi Anda ke {{error}} ({{name}}:{{ip}})", "sshConnectionFailed": "Koneksi SSH gagal. Silakan periksa koneksi Anda ke {{name}} ({{ip}}:{{port}})",
"loadFileFailed": "Gagal memuat file: {{port}}", "loadFileFailed": "Gagal memuat file: {{error}}",
"connectedSuccessfully": "Terhubung berhasil", "connectedSuccessfully": "Terhubung berhasil",
"totpVerificationFailed": "Verifikasi TOTP gagal", "totpVerificationFailed": "Verifikasi TOTP gagal",
"verificationCodePrompt": "Kode verifikasi:", "verificationCodePrompt": "Kode verifikasi:",
@@ -1573,10 +1573,10 @@
"disconnect": "Memutuskan", "disconnect": "Memutuskan",
"cancel": "Membatalkan", "cancel": "Membatalkan",
"port": "Pelabuhan", "port": "Pelabuhan",
"attempt": "Percobaan {{error}} dari {{current}}", "attempt": "Percobaan {{current}} dari {{max}}",
"nextRetryIn": "Percobaan berikutnya dalam {{max}} detik", "nextRetryIn": "Percobaan berikutnya dalam {{seconds}} detik",
"checkDockerLogs": "Periksa log Docker Anda untuk mengetahui penyebab kesalahan, bergabunglah dengan", "checkDockerLogs": "Periksa log Docker Anda untuk mengetahui penyebab kesalahan, bergabunglah dengan",
"orCreate": "atau membuat", "orCreate": "atau membuat ",
"noTunnelConnections": "Tidak ada koneksi terowongan yang dikonfigurasi.", "noTunnelConnections": "Tidak ada koneksi terowongan yang dikonfigurasi.",
"tunnelConnections": "Koneksi Terowongan", "tunnelConnections": "Koneksi Terowongan",
"addTunnel": "Tambahkan Terowongan", "addTunnel": "Tambahkan Terowongan",
@@ -1598,7 +1598,7 @@
"remote": "Terpencil", "remote": "Terpencil",
"dynamic": "Dinamis", "dynamic": "Dinamis",
"unknownConnectionStatus": "Tidak dikenal", "unknownConnectionStatus": "Tidak dikenal",
"portMapping": "Pelabuhan {{seconds}} → {{sourcePort}}:{{endpointHost}}", "portMapping": "Port {{sourcePort}} → {{endpointHost}}:{{endpointPort}}",
"endpointHostNotFound": "Host titik akhir tidak ditemukan", "endpointHostNotFound": "Host titik akhir tidak ditemukan",
"discord": "Perselisihan", "discord": "Perselisihan",
"githubIssue": "Masalah GitHub", "githubIssue": "Masalah GitHub",
@@ -1611,7 +1611,7 @@
"disk": "Disk", "disk": "Disk",
"network": "Jaringan", "network": "Jaringan",
"uptime": "Waktu aktif", "uptime": "Waktu aktif",
"loadAverage": "Rata-rata: {{endpointPort}}, {{avg1}}, {{avg5}}", "loadAverage": "Rata-rata: {{avg1}}, {{avg5}}, {{avg15}}",
"processes": "Proses", "processes": "Proses",
"connections": "Koneksi", "connections": "Koneksi",
"usage": "Penggunaan", "usage": "Penggunaan",
@@ -1624,8 +1624,8 @@
"refreshStatus": "Perbarui Status", "refreshStatus": "Perbarui Status",
"fileManagerAlreadyOpen": "Pengelola berkas sudah terbuka untuk host ini.", "fileManagerAlreadyOpen": "Pengelola berkas sudah terbuka untuk host ini.",
"openFileManager": "Buka Pengelola File", "openFileManager": "Buka Pengelola File",
"cpuCores_one": "CPU 206", "cpuCores_one": "{{count}} CPU",
"cpuCores_other": "{{avg15}} CPU", "cpuCores_other": "{{count}} CPU",
"naCpus": "CPU tidak tersedia", "naCpus": "CPU tidak tersedia",
"loadAverageNA": "Rata-rata: Tidak tersedia", "loadAverageNA": "Rata-rata: Tidak tersedia",
"cpuUsage": "Penggunaan CPU", "cpuUsage": "Penggunaan CPU",
@@ -1650,7 +1650,7 @@
"totpInvalidCode": "Kode verifikasi tidak valid", "totpInvalidCode": "Kode verifikasi tidak valid",
"totpCancelled": "Pengumpulan metrik dibatalkan", "totpCancelled": "Pengumpulan metrik dibatalkan",
"authenticationFailed": "Autentikasi gagal", "authenticationFailed": "Autentikasi gagal",
"noneAuthNotSupported": "Statistik Server tidak mendukung tipe otentikasi 'none'.", "noneAuthNotSupported": "Statistik Server tidak mendukung tipe autentikasi 'none'.",
"load": "Memuat", "load": "Memuat",
"editLayout": "Edit Tata Letak", "editLayout": "Edit Tata Letak",
"cancelEdit": "Membatalkan", "cancelEdit": "Membatalkan",
@@ -1669,7 +1669,7 @@
"noInterfacesFound": "Tidak ditemukan antarmuka jaringan.", "noInterfacesFound": "Tidak ditemukan antarmuka jaringan.",
"totalProcesses": "Proses Total", "totalProcesses": "Proses Total",
"running": "Berlari", "running": "Berlari",
"noProcessesFound": "Tidak ada proses yang ditemukan", "noProcessesFound": "Tidak ada proses yang ditemukan.",
"loginStats": "Statistik Login SSH", "loginStats": "Statistik Login SSH",
"totalLogins": "Total Login", "totalLogins": "Total Login",
"uniqueIPs": "IP Unik", "uniqueIPs": "IP Unik",
@@ -1678,8 +1678,8 @@
"noRecentLoginData": "Tidak ada data login terbaru.", "noRecentLoginData": "Tidak ada data login terbaru.",
"from": "dari", "from": "dari",
"quickActions": "Tindakan Cepat", "quickActions": "Tindakan Cepat",
"executeQuickAction": "Jalankan {{count}}", "executeQuickAction": "Eksekusi {{name}}",
"executingQuickAction": "Menjalankan {{count}}...", "executingQuickAction": "Menjalankan {{name}}...",
"quickActionSuccess": "{{name}} berhasil diselesaikan", "quickActionSuccess": "{{name}} berhasil diselesaikan",
"quickActionFailed": "{{name}} gagal", "quickActionFailed": "{{name}} gagal",
"quickActionError": "Gagal mengeksekusi {{name}}" "quickActionError": "Gagal mengeksekusi {{name}}"
@@ -1695,7 +1695,7 @@
"loginButton": "Login", "loginButton": "Login",
"registerButton": "Daftar", "registerButton": "Daftar",
"forgotPassword": "Lupa kata sandi?", "forgotPassword": "Lupa kata sandi?",
"rememberMe": "Ingat Aku", "rememberMe": "Ingatlah Aku",
"noAccount": "Belum punya akun?", "noAccount": "Belum punya akun?",
"hasAccount": "Sudah punya akun?", "hasAccount": "Sudah punya akun?",
"loginSuccess": "Login berhasil.", "loginSuccess": "Login berhasil.",
@@ -1745,7 +1745,7 @@
"sshNoKeyboardInteractiveDescription": "Server ini tidak mendukung autentikasi interaktif keyboard. Harap berikan kata sandi atau kunci SSH Anda.", "sshNoKeyboardInteractiveDescription": "Server ini tidak mendukung autentikasi interaktif keyboard. Harap berikan kata sandi atau kunci SSH Anda.",
"sshAuthFailedDescription": "Kredensial yang diberikan salah. Silakan coba lagi dengan kredensial yang valid.", "sshAuthFailedDescription": "Kredensial yang diberikan salah. Silakan coba lagi dengan kredensial yang valid.",
"sshTimeoutDescription": "Upaya otentikasi telah habis waktu. Silakan coba lagi.", "sshTimeoutDescription": "Upaya otentikasi telah habis waktu. Silakan coba lagi.",
"sshProvideCredentialsDescription": "Harap berikan kredensial SSH Anda untuk terhubung ke server ini.", "sshProvideCredentialsDescription": "Silakan berikan kredensial SSH Anda untuk terhubung ke server ini.",
"sshPasswordDescription": "Masukkan kata sandi untuk koneksi SSH ini.", "sshPasswordDescription": "Masukkan kata sandi untuk koneksi SSH ini.",
"sshKeyPasswordDescription": "Jika kunci SSH Anda dienkripsi, masukkan kata sandi di sini.", "sshKeyPasswordDescription": "Jika kunci SSH Anda dienkripsi, masukkan kata sandi di sini.",
"step1ScanQR": "Langkah 1: Pindai kode QR dengan aplikasi otentikasi Anda", "step1ScanQR": "Langkah 1: Pindai kode QR dengan aplikasi otentikasi Anda",
@@ -1786,7 +1786,7 @@
"desktopApp": "Aplikasi Desktop", "desktopApp": "Aplikasi Desktop",
"loggingInToDesktopApp": "Masuk ke aplikasi desktop", "loggingInToDesktopApp": "Masuk ke aplikasi desktop",
"loggingInToDesktopAppViaWeb": "Masuk ke aplikasi desktop melalui antarmuka web.", "loggingInToDesktopAppViaWeb": "Masuk ke aplikasi desktop melalui antarmuka web.",
"loadingServer": "Memuat server...", "loadingServer": "Sedang memuat server...",
"authenticating": "Sedang melakukan autentikasi...", "authenticating": "Sedang melakukan autentikasi...",
"dataLossWarning": "Mengatur ulang kata sandi Anda dengan cara ini akan menghapus semua host SSH, kredensial, dan data terenkripsi lainnya yang telah Anda simpan. Tindakan ini tidak dapat dibatalkan. Gunakan cara ini hanya jika Anda lupa kata sandi dan belum masuk.", "dataLossWarning": "Mengatur ulang kata sandi Anda dengan cara ini akan menghapus semua host SSH, kredensial, dan data terenkripsi lainnya yang telah Anda simpan. Tindakan ini tidak dapat dibatalkan. Gunakan cara ini hanya jika Anda lupa kata sandi dan belum masuk.",
"authenticationDisabled": "Autentikasi Dinonaktifkan", "authenticationDisabled": "Autentikasi Dinonaktifkan",
@@ -1814,8 +1814,8 @@
"invalidAuthUrl": "URL otorisasi yang diterima dari backend tidak valid.", "invalidAuthUrl": "URL otorisasi yang diterima dari backend tidak valid.",
"invalidInput": "Masukan tidak valid", "invalidInput": "Masukan tidak valid",
"requiredField": "Kolom ini wajib diisi.", "requiredField": "Kolom ini wajib diisi.",
"minLength": "Panjang minimumnya adalah {{name}}", "minLength": "Panjang minimum adalah {{min}}",
"maxLength": "Panjang maksimumnya adalah {{name}}", "maxLength": "Panjang maksimumnya adalah {{max}}",
"invalidEmail": "Alamat email tidak valid", "invalidEmail": "Alamat email tidak valid",
"passwordMismatch": "Kata sandi tidak cocok", "passwordMismatch": "Kata sandi tidak cocok",
"passwordLoginDisabled": "Login menggunakan nama pengguna/kata sandi saat ini dinonaktifkan.", "passwordLoginDisabled": "Login menggunakan nama pengguna/kata sandi saat ini dinonaktifkan.",
@@ -1835,7 +1835,7 @@
"updateError": "Pembaruan gagal", "updateError": "Pembaruan gagal",
"copySuccess": "Disalin ke papan klip", "copySuccess": "Disalin ke papan klip",
"copyError": "Gagal menyalin", "copyError": "Gagal menyalin",
"copiedToClipboard": "{{min}} disalin ke papan klip", "copiedToClipboard": "{{item}} disalin ke papan klip",
"connectionEstablished": "Koneksi berhasil terjalin.", "connectionEstablished": "Koneksi berhasil terjalin.",
"connectionClosed": "Koneksi terputus", "connectionClosed": "Koneksi terputus",
"reconnecting": "Menghubungkan kembali...", "reconnecting": "Menghubungkan kembali...",
@@ -1866,7 +1866,7 @@
"external": "Eksternal (OIDC)", "external": "Eksternal (OIDC)",
"externalAndLocal": "Otorisasi Ganda", "externalAndLocal": "Otorisasi Ganda",
"selectPreferredLanguage": "Pilih bahasa pilihan Anda untuk antarmuka.", "selectPreferredLanguage": "Pilih bahasa pilihan Anda untuk antarmuka.",
"fileColorCoding": "Pengkodean Warna Berkas", "fileColorCoding": "Pengkodean Warna File",
"fileColorCodingDesc": "Beri kode warna pada file berdasarkan jenisnya: folder (merah), file (biru), symlink (hijau)", "fileColorCodingDesc": "Beri kode warna pada file berdasarkan jenisnya: folder (merah), file (biru), symlink (hijau)",
"commandAutocomplete": "Pelengkapan Otomatis Perintah", "commandAutocomplete": "Pelengkapan Otomatis Perintah",
"commandAutocompleteDesc": "Aktifkan saran pelengkapan otomatis tombol Tab untuk perintah terminal berdasarkan riwayat perintah Anda.", "commandAutocompleteDesc": "Aktifkan saran pelengkapan otomatis tombol Tab untuk perintah terminal berdasarkan riwayat perintah Anda.",
@@ -1883,7 +1883,7 @@
"hostSidebarSettings": "Host & Sidebar", "hostSidebarSettings": "Host & Sidebar",
"snippetsSettings": "Cuplikan", "snippetsSettings": "Cuplikan",
"currentPassword": "Kata Sandi Saat Ini", "currentPassword": "Kata Sandi Saat Ini",
"passwordChangedSuccess": "Kata sandi berhasil diubah! Silakan masuk lagi.", "passwordChangedSuccess": "Kata sandi berhasil diubah! Silakan masuk kembali.",
"failedToChangePassword": "Perubahan kata sandi gagal. Silakan periksa kata sandi Anda saat ini dan coba lagi.", "failedToChangePassword": "Perubahan kata sandi gagal. Silakan periksa kata sandi Anda saat ini dan coba lagi.",
"theme": "Tema", "theme": "Tema",
"themeLight": "Lampu", "themeLight": "Lampu",
@@ -1939,10 +1939,10 @@
"currentPath": "Masukkan jalur saat ini ke item", "currentPath": "Masukkan jalur saat ini ke item",
"newName": "Masukkan nama baru", "newName": "Masukkan nama baru",
"socks5Host": "127.0.0.1", "socks5Host": "127.0.0.1",
"socks5Username": "nama pengguna proksi", "socks5Username": "nama pengguna proxy",
"socks5Password": "kata sandi proxy", "socks5Password": "kata sandi proxy",
"socks5PresetName": "misalnya, Rantai VPN Kantor", "socks5PresetName": "misalnya, Rantai VPN Kantor",
"socks5PresetDescription": "misalnya, Rantai proxy untuk mengakses server kerja", "socks5PresetDescription": "Contoh: Rantai proxy untuk mengakses server kerja",
"moshCommand": "mosh user@server", "moshCommand": "mosh user@server",
"defaultPort": "22", "defaultPort": "22",
"defaultEndpointPort": "224", "defaultEndpointPort": "224",
@@ -1955,8 +1955,8 @@
"passwordRequired": "Kata sandi diperlukan", "passwordRequired": "Kata sandi diperlukan",
"failedToDeleteAccount": "Gagal menghapus akun", "failedToDeleteAccount": "Gagal menghapus akun",
"failedToMakeUserAdmin": "Gagal menjadikan pengguna sebagai admin.", "failedToMakeUserAdmin": "Gagal menjadikan pengguna sebagai admin.",
"userIsNowAdmin": "Pengguna {{max}} sekarang menjadi admin", "userIsNowAdmin": "Pengguna {{username}} sekarang menjadi admin",
"removeAdminConfirm": "Apakah Anda yakin ingin menghapus status admin dari {{item}}?", "removeAdminConfirm": "Apakah Anda yakin ingin menghapus status admin dari {{username}}?",
"deleteUserConfirm": "Apakah Anda yakin ingin menghapus pengguna {{username}}? Tindakan ini tidak dapat dibatalkan.", "deleteUserConfirm": "Apakah Anda yakin ingin menghapus pengguna {{username}}? Tindakan ini tidak dapat dibatalkan.",
"deleteAccount": "Hapus Akun", "deleteAccount": "Hapus Akun",
"closeDeleteAccount": "Tutup Hapus Akun", "closeDeleteAccount": "Tutup Hapus Akun",
@@ -2142,7 +2142,7 @@
"createTempUser": "Buat Pengguna Sementara", "createTempUser": "Buat Pengguna Sementara",
"createTempUserDesc": "Membuat pengguna terbatas di server sebagai pengganti berbagi kredensial Anda. Membutuhkan akses sudo. Opsi paling aman.", "createTempUserDesc": "Membuat pengguna terbatas di server sebagai pengganti berbagi kredensial Anda. Membutuhkan akses sudo. Opsi paling aman.",
"expiresAt": "Berakhir pada", "expiresAt": "Berakhir pada",
"expiresIn": "Berakhir dalam {{username}} jam", "expiresIn": "Berakhir dalam {{hours}} jam",
"expired": "Kedaluwarsa", "expired": "Kedaluwarsa",
"grantedBy": "Diberikan Oleh", "grantedBy": "Diberikan Oleh",
"accessLevel": "Tingkat Akses", "accessLevel": "Tingkat Akses",
@@ -2150,10 +2150,10 @@
"accessCount": "Jumlah Akses", "accessCount": "Jumlah Akses",
"revokeAccess": "Cabut Akses", "revokeAccess": "Cabut Akses",
"confirmRevokeAccess": "Apakah Anda yakin ingin mencabut akses untuk {{username}}?", "confirmRevokeAccess": "Apakah Anda yakin ingin mencabut akses untuk {{username}}?",
"hostSharedSuccessfully": "Host berhasil berbagi dengan {{hours}}", "hostSharedSuccessfully": "Host berhasil berbagi dengan {{username}}",
"hostAccessUpdated": "Akses host diperbarui", "hostAccessUpdated": "Akses host diperbarui",
"failedToShareHost": "Gagal berbagi host", "failedToShareHost": "Gagal berbagi host",
"accessRevokedSuccessfully": "Akses berhasil dicabut", "accessRevokedSuccessfully": "Akses berhasil dicabut.",
"failedToRevokeAccess": "Gagal mencabut akses", "failedToRevokeAccess": "Gagal mencabut akses",
"shared": "Dibagikan", "shared": "Dibagikan",
"sharedHosts": "Penyedia Layanan Hosting Bersama", "sharedHosts": "Penyedia Layanan Hosting Bersama",
@@ -2165,26 +2165,26 @@
"noAccessGranted": "Akses belum diberikan untuk host ini.", "noAccessGranted": "Akses belum diberikan untuk host ini.",
"noAccessGrantedMessage": "Belum ada pengguna yang diberikan akses ke host ini.", "noAccessGrantedMessage": "Belum ada pengguna yang diberikan akses ke host ini.",
"manageAccessFor": "Kelola akses untuk", "manageAccessFor": "Kelola akses untuk",
"totalAccessRecords": "{{username}} catatan akses", "totalAccessRecords": "{{count}} catatan akses",
"neverAccessed": "Tidak pernah", "neverAccessed": "Tidak pernah",
"timesAccessed": "{{username}} kali", "timesAccessed": "{{count}} waktu",
"daysRemaining": "{{count}} hari", "daysRemaining": "{{days}} hari",
"hoursRemaining": "{{count}} jam", "hoursRemaining": "{{hours}} jam",
"failedToFetchAccessList": "Gagal mengambil daftar akses", "failedToFetchAccessList": "Gagal mengambil daftar akses",
"currentAccess": "Akses Saat Ini", "currentAccess": "Akses Saat Ini",
"securityWarning": "Peringatan Keamanan", "securityWarning": "Peringatan Keamanan",
"securityWarningMessage": "Berbagi kredensial memberi pengguna akses penuh untuk melakukan operasi apa pun di server, termasuk mengubah kata sandi dan menghapus file. Bagikan hanya dengan pengguna tepercaya.", "securityWarningMessage": "Berbagi kredensial memberi pengguna akses penuh untuk melakukan operasi apa pun di server, termasuk mengubah kata sandi dan menghapus file. Bagikan hanya dengan pengguna tepercaya.",
"tempUserRecommended": "Kami menyarankan untuk mengaktifkan 'Buat Pengguna Sementara' untuk keamanan yang lebih baik.", "tempUserRecommended": "Kami menyarankan untuk mengaktifkan 'Buat Pengguna Sementara' demi keamanan yang lebih baik.",
"roleManagement": "Manajemen Peran", "roleManagement": "Manajemen Peran",
"manageRoles": "Kelola Peran", "manageRoles": "Kelola Peran",
"manageRolesFor": "Kelola peran untuk {{days}}", "manageRolesFor": "Kelola peran untuk {{username}}",
"assignRole": "Tetapkan Peran", "assignRole": "Tetapkan Peran",
"removeRole": "Hapus Peran", "removeRole": "Hapus Peran",
"userRoles": "Peran Pengguna", "userRoles": "Peran Pengguna",
"permissions": "Izin", "permissions": "Izin",
"systemRole": "Peran Sistem", "systemRole": "Peran Sistem",
"customRole": "Peran Kustom", "customRole": "Peran Kustom",
"roleAssignedSuccessfully": "Peran berhasil diberikan kepada {{hours}}", "roleAssignedSuccessfully": "Peran berhasil diberikan kepada {{username}}",
"failedToAssignRole": "Gagal menetapkan peran", "failedToAssignRole": "Gagal menetapkan peran",
"roleRemovedSuccessfully": "Peran berhasil dihapus dari {{username}}", "roleRemovedSuccessfully": "Peran berhasil dihapus dari {{username}}",
"failedToRemoveRole": "Gagal menghapus peran", "failedToRemoveRole": "Gagal menghapus peran",
@@ -2193,7 +2193,7 @@
"noCustomRolesToAssign": "Tidak ada peran khusus yang tersedia. Peran sistem ditetapkan secara otomatis.", "noCustomRolesToAssign": "Tidak ada peran khusus yang tersedia. Peran sistem ditetapkan secara otomatis.",
"credentialSharingWarning": "Autentikasi Kredensial Tidak Didukung untuk Berbagi", "credentialSharingWarning": "Autentikasi Kredensial Tidak Didukung untuk Berbagi",
"credentialRequired": "Kredensial diperlukan saat berbagi host.", "credentialRequired": "Kredensial diperlukan saat berbagi host.",
"credentialRequiredDescription": "Host ini tidak menggunakan autentikasi berbasis kredensial. Untuk berbagi host, karena enkripsi per pengguna, host harus menggunakan autentikasi berbasis kredensial.", "credentialRequiredDescription": "Host ini tidak menggunakan autentikasi berbasis kredensial. Untuk dapat berbagi host, karena enkripsi per pengguna, host harus menggunakan autentikasi berbasis kredensial.",
"auditLogs": "Catatan Audit", "auditLogs": "Catatan Audit",
"viewAuditLogs": "Lihat Log Audit", "viewAuditLogs": "Lihat Log Audit",
"action": "Tindakan", "action": "Tindakan",
@@ -2214,7 +2214,7 @@
"terminateSession": "Akhiri Sesi", "terminateSession": "Akhiri Sesi",
"sessionTerminated": "Sesi diakhiri oleh pemilik host.", "sessionTerminated": "Sesi diakhiri oleh pemilik host.",
"sharedAccessExpired": "Akses bersama Anda ke host ini telah kedaluwarsa.", "sharedAccessExpired": "Akses bersama Anda ke host ini telah kedaluwarsa.",
"sharedAccessExpiresIn": "Akses bersama akan berakhir dalam {{username}} jam", "sharedAccessExpiresIn": "Akses bersama akan berakhir dalam {{hours}} jam",
"roles": { "roles": {
"label": "Peran", "label": "Peran",
"admin": "Administrator", "admin": "Administrator",
@@ -2249,7 +2249,7 @@
"displayNamePlaceholder": "Pengembang", "displayNamePlaceholder": "Pengembang",
"descriptionPlaceholder": "Pengembang dan insinyur perangkat lunak", "descriptionPlaceholder": "Pengembang dan insinyur perangkat lunak",
"confirmDeleteRole": "Hapus Peran", "confirmDeleteRole": "Hapus Peran",
"confirmDeleteRoleDescription": "Apakah Anda yakin ingin menghapus peran '{{username}}'? Tindakan ini tidak dapat dibatalkan.", "confirmDeleteRoleDescription": "Apakah Anda yakin ingin menghapus peran '{{name}}'? Tindakan ini tidak dapat dibatalkan.",
"confirmRemoveRole": "Hapus Peran", "confirmRemoveRole": "Hapus Peran",
"confirmRemoveRoleDescription": "Apakah Anda yakin ingin menghapus peran ini dari pengguna?", "confirmRemoveRoleDescription": "Apakah Anda yakin ingin menghapus peran ini dari pengguna?",
"editRoleDescription": "Perbarui informasi peran", "editRoleDescription": "Perbarui informasi peran",
@@ -2307,15 +2307,15 @@
"validating": "Memvalidasi Docker...", "validating": "Memvalidasi Docker...",
"connectingToHost": "Menghubungkan ke host...", "connectingToHost": "Menghubungkan ke host...",
"error": "Kesalahan", "error": "Kesalahan",
"errorCode": "Kode kesalahan: {{hours}}", "errorCode": "Kode kesalahan: {{code}}",
"version": "Docker {{name}}", "version": "Docker {{version}}",
"containerStarted": "Kontainer {{code}} dimulai", "containerStarted": "Kontainer {{name}} dimulai",
"failedToStartContainer": "Gagal memulai kontainer {{version}}", "failedToStartContainer": "Gagal memulai kontainer {{name}}",
"containerStopped": "Kontainer {{name}} berhenti", "containerStopped": "Kontainer {{name}} berhenti",
"failedToStopContainer": "Gagal menghentikan kontainer {{name}}", "failedToStopContainer": "Gagal menghentikan kontainer {{name}}",
"containerRestarted": "Kontainer {{name}} dihidupkan kembali", "containerRestarted": "Kontainer {{name}} dimulai ulang",
"failedToRestartContainer": "Gagal memulai ulang kontainer {{name}}", "failedToRestartContainer": "Gagal memulai ulang kontainer {{name}}",
"containerPaused": "Kontainer {{name}} berhenti sementara", "containerPaused": "Kontainer {{name}} berhenti",
"containerUnpaused": "Kontainer {{name}} tidak dijeda", "containerUnpaused": "Kontainer {{name}} tidak dijeda",
"failedToTogglePauseContainer": "Gagal mengubah status jeda untuk kontainer {{name}}", "failedToTogglePauseContainer": "Gagal mengubah status jeda untuk kontainer {{name}}",
"containerRemoved": "Kontainer {{name}} dihapus", "containerRemoved": "Kontainer {{name}} dihapus",
@@ -2340,8 +2340,8 @@
"noContainersFoundHint": "Tidak ada kontainer Docker yang tersedia di host ini.", "noContainersFoundHint": "Tidak ada kontainer Docker yang tersedia di host ini.",
"searchPlaceholder": "Cari kontainer...", "searchPlaceholder": "Cari kontainer...",
"filterByStatusPlaceholder": "Saring berdasarkan status", "filterByStatusPlaceholder": "Saring berdasarkan status",
"allContainersCount": "Semua ({{name}})", "allContainersCount": "Semua ({{count}})",
"statusCount": "{{name}} ({{count}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "Tidak ada wadah yang sesuai dengan filter Anda.", "noContainersMatchFilters": "Tidak ada wadah yang sesuai dengan filter Anda.",
"noContainersMatchFiltersHint": "Cobalah menyesuaikan kriteria pencarian atau filter Anda.", "noContainersMatchFiltersHint": "Cobalah menyesuaikan kriteria pencarian atau filter Anda.",
"containerMustBeRunningToViewStats": "Kontainer harus berjalan agar statistik dapat dilihat.", "containerMustBeRunningToViewStats": "Kontainer harus berjalan agar statistik dapat dilihat.",
@@ -2372,10 +2372,10 @@
"authenticationRequired": "Diperlukan otentikasi.", "authenticationRequired": "Diperlukan otentikasi.",
"verificationCodePrompt": "Masukkan kode verifikasi", "verificationCodePrompt": "Masukkan kode verifikasi",
"totpVerificationFailed": "Verifikasi TOTP gagal. Silakan coba lagi.", "totpVerificationFailed": "Verifikasi TOTP gagal. Silakan coba lagi.",
"connectedTo": "Terhubung ke {{status}}", "connectedTo": "Terhubung ke {{containerName}}",
"disconnected": "Terputus", "disconnected": "Terputus",
"consoleError": "Kesalahan konsol", "consoleError": "Kesalahan konsol",
"errorMessage": "Kesalahan: {{count}}", "errorMessage": "Kesalahan: {{message}}",
"failedToConnect": "Gagal terhubung ke kontainer", "failedToConnect": "Gagal terhubung ke kontainer",
"console": "Menghibur", "console": "Menghibur",
"selectShell": "Pilih cangkang", "selectShell": "Pilih cangkang",
@@ -2399,4 +2399,4 @@
"switchToLight": "Beralih ke Cahaya", "switchToLight": "Beralih ke Cahaya",
"switchToDark": "Beralih ke Gelap" "switchToDark": "Beralih ke Gelap"
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -128,7 +128,7 @@
"created": "생성됨", "created": "생성됨",
"lastModified": "최종 수정일", "lastModified": "최종 수정일",
"usageStatistics": "사용 통계", "usageStatistics": "사용 통계",
"copiedToClipboard": "{{field}} 클립보드에 복사되었습니다", "copiedToClipboard": "{{field}} 클립보드에 복사",
"failedToCopy": "클립보드에 복사하는 데 실패했습니다.", "failedToCopy": "클립보드에 복사하는 데 실패했습니다.",
"sshKey": "SSH 키", "sshKey": "SSH 키",
"createCredentialDescription": "안전한 접속을 위해 새 SSH 자격 증명을 생성하세요.", "createCredentialDescription": "안전한 접속을 위해 새 SSH 자격 증명을 생성하세요.",
@@ -136,7 +136,7 @@
"listView": "목록", "listView": "목록",
"folderView": "폴더", "folderView": "폴더",
"unknownCredential": "알려지지 않은", "unknownCredential": "알려지지 않은",
"confirmRemoveFromFolder": "\"{{name}}\"를 \"{{folder}}\" 폴더에서 제하시겠습니까? 자격 증명은 \"분류되지 않음\"으로 이동됩니다.", "confirmRemoveFromFolder": "\"{{folder}}\" 폴더에서 \"{{name}}\"을 삭제하시겠습니까? 자격 증명은 \"분류되지 않음\"으로 이동됩니다.",
"removedFromFolder": "자격 증명 \"{{name}}\"이 폴더에서 성공적으로 제거되었습니다.", "removedFromFolder": "자격 증명 \"{{name}}\"이 폴더에서 성공적으로 제거되었습니다.",
"failedToRemoveFromFolder": "폴더에서 자격 증명을 제거하는 데 실패했습니다.", "failedToRemoveFromFolder": "폴더에서 자격 증명을 제거하는 데 실패했습니다.",
"folderRenamed": "폴더 \"{{oldName}}\"의 이름이 \"{{newName}}\"로 성공적으로 변경되었습니다.", "folderRenamed": "폴더 \"{{oldName}}\"의 이름이 \"{{newName}}\"로 성공적으로 변경되었습니다.",
@@ -186,11 +186,11 @@
}, },
"dragIndicator": { "dragIndicator": {
"error": "오류: {{error}}", "error": "오류: {{error}}",
"dragging": "{{fileName}}을 끌어당기기", "dragging": "드래그 중 {{fileName}}",
"preparing": "{{fileName}} 준비 중", "preparing": "{{fileName}}준비 중",
"readySingle": "다운로드 준비 완료 {{fileName}}", "readySingle": "다운로드 준비 완료 {{fileName}}",
"readyMultiple": "{{count}}개의 파일을 다운로드할 준비가 되었습니다.", "readyMultiple": "{{count}} 파일을 다운로드할 준비가 되었습니다.",
"batchDrag": "{{count}}개의 파일을 바탕 화면으로 드래그하세요.", "batchDrag": "{{count}} 파일을 바탕 화면으로 드래그하세요.",
"dragToDesktop": "바탕화면으로 드래그하세요", "dragToDesktop": "바탕화면으로 드래그하세요",
"canDragAnywhere": "바탕화면 어디든 파일을 드래그해서 옮길 수 있습니다." "canDragAnywhere": "바탕화면 어디든 파일을 드래그해서 옮길 수 있습니다."
}, },
@@ -202,7 +202,7 @@
"stopKeyRecording": "키 녹음 중지", "stopKeyRecording": "키 녹음 중지",
"selectTerminals": "터미널을 선택하세요:", "selectTerminals": "터미널을 선택하세요:",
"typeCommands": "명령어를 입력하세요(모든 키 지원):", "typeCommands": "명령어를 입력하세요(모든 키 지원):",
"commandsWillBeSent": "명령은 선택된 {{count}}개의 터미널로 전송됩니다.", "commandsWillBeSent": "명령은 {{count}} 선택된 터미널로 전송됩니다.",
"settings": "설정", "settings": "설정",
"enableRightClickCopyPaste": "마우스 오른쪽 버튼을 클릭하여 복사/붙여넣기를 활성화합니다.", "enableRightClickCopyPaste": "마우스 오른쪽 버튼을 클릭하여 복사/붙여넣기를 활성화합니다.",
"shareIdeas": "SSH 도구의 향후 기능에 대한 아이디어가 있으신가요? 공유해 주세요!", "shareIdeas": "SSH 도구의 향후 기능에 대한 아이디어가 있으신가요? 공유해 주세요!",
@@ -230,7 +230,7 @@
"createDescription": "빠른 실행을 위해 새로운 명령 스니펫을 만드세요.", "createDescription": "빠른 실행을 위해 새로운 명령 스니펫을 만드세요.",
"editDescription": "이 명령 조각을 편집하세요", "editDescription": "이 명령 조각을 편집하세요",
"deleteConfirmTitle": "코드 조각 삭제", "deleteConfirmTitle": "코드 조각 삭제",
"deleteConfirmDescription": "\"{{name}}\"를 정말로 삭제하시겠습니까?", "deleteConfirmDescription": "\"{{name}}\" 삭제하시겠습니까?",
"createSuccess": "코드 조각이 성공적으로 생성되었습니다.", "createSuccess": "코드 조각이 성공적으로 생성되었습니다.",
"updateSuccess": "코드 조각이 성공적으로 업데이트되었습니다.", "updateSuccess": "코드 조각이 성공적으로 업데이트되었습니다.",
"deleteSuccess": "스니펫이 성공적으로 삭제되었습니다.", "deleteSuccess": "스니펫이 성공적으로 삭제되었습니다.",
@@ -239,7 +239,7 @@
"deleteFailed": "코드 조각을 삭제하는 데 실패했습니다.", "deleteFailed": "코드 조각을 삭제하는 데 실패했습니다.",
"failedToFetch": "코드 조각을 가져오는 데 실패했습니다.", "failedToFetch": "코드 조각을 가져오는 데 실패했습니다.",
"executeSuccess": "실행 중: {{name}}", "executeSuccess": "실행 중: {{name}}",
"copySuccess": "\"{{name}}\" 클립보드에 복사했습니다.", "copySuccess": "\"{{name}}\" 클립보드에 복사했습니다.",
"runTooltip": "터미널에서 다음 코드 조각을 실행하세요.", "runTooltip": "터미널에서 다음 코드 조각을 실행하세요.",
"copyTooltip": "코드 조각을 클립보드에 복사합니다", "copyTooltip": "코드 조각을 클립보드에 복사합니다",
"editTooltip": "이 코드 조각을 수정하세요", "editTooltip": "이 코드 조각을 수정하세요",
@@ -248,7 +248,7 @@
"reorderSameFolder": "같은 폴더 내에서만 스니펫 순서를 변경할 수 있습니다.", "reorderSameFolder": "같은 폴더 내에서만 스니펫 순서를 변경할 수 있습니다.",
"reorderSuccess": "스니펫 순서가 성공적으로 재정렬되었습니다.", "reorderSuccess": "스니펫 순서가 성공적으로 재정렬되었습니다.",
"reorderFailed": "스니펫 순서 변경에 실패했습니다.", "reorderFailed": "스니펫 순서 변경에 실패했습니다.",
"deleteFolderConfirm": "폴더 \"{{name}}\"를 삭제하세요. 모든 스니펫은 미분류로 이동니다.", "deleteFolderConfirm": "\"{{name}}\" 폴더를 삭제하시겠습니까? 모든 스니펫은 미분류로 이동니다.",
"deleteFolderSuccess": "폴더가 성공적으로 삭제되었습니다.", "deleteFolderSuccess": "폴더가 성공적으로 삭제되었습니다.",
"deleteFolderFailed": "폴더 삭제에 실패했습니다", "deleteFolderFailed": "폴더 삭제에 실패했습니다",
"updateFolderSuccess": "폴더가 성공적으로 업데이트되었습니다.", "updateFolderSuccess": "폴더가 성공적으로 업데이트되었습니다.",
@@ -256,7 +256,7 @@
"updateFolderFailed": "폴더 업데이트에 실패했습니다", "updateFolderFailed": "폴더 업데이트에 실패했습니다",
"createFolderFailed": "폴더 생성에 실패했습니다", "createFolderFailed": "폴더 생성에 실패했습니다",
"selectTerminals": "터미널 선택 (선택 사항)", "selectTerminals": "터미널 선택 (선택 사항)",
"executeOnSelected": "선택한 터미널 {{count}}에서 실행합니다.", "executeOnSelected": "{{count}} 선택된 터미널에서 실행",
"executeOnCurrent": "현재 터미널에서 실행 (여러 개를 선택하려면 클릭하세요)", "executeOnCurrent": "현재 터미널에서 실행 (여러 개를 선택하려면 클릭하세요)",
"folder": "접는 사람", "folder": "접는 사람",
"selectFolder": "폴더를 선택하거나 비워 두세요.", "selectFolder": "폴더를 선택하거나 비워 두세요.",
@@ -274,13 +274,13 @@
}, },
"commandHistory": { "commandHistory": {
"title": "역사", "title": "역사",
"searchPlaceholder": "검색 명령...", "searchPlaceholder": "검색 명령...",
"noTerminal": "활성화된 단말기 없음", "noTerminal": "활성화된 단말기 없음",
"noTerminalHint": "터미널을 열어 명령 기록을 확인하세요.", "noTerminalHint": "터미널을 열어 명령 기록을 확인하세요.",
"empty": "아직 명령 기록이 없습니다.", "empty": "아직 명령 기록이 없습니다.",
"emptyHint": "현재 실행 중인 터미널에서 명령어를 실행하여 터미널의 히스토리를 구축합니다.", "emptyHint": "현재 실행 중인 터미널에서 명령어를 실행하여 터미널의 히스토리를 구축합니다.",
"noResults": "명령어를 찾을 수 없습니다.", "noResults": "명령어를 찾을 수 없습니다.",
"noResultsHint": "\"{{query}}\"와 일치하는 명령이 없습니다.", "noResultsHint": "\"{{query}}\" 와 일치하는 명령이 없습니다.",
"deleteSuccess": "명령이 기록에서 삭제되었습니다.", "deleteSuccess": "명령이 기록에서 삭제되었습니다.",
"deleteFailed": "삭제 명령에 실패했습니다.", "deleteFailed": "삭제 명령에 실패했습니다.",
"deleteTooltip": "삭제 명령", "deleteTooltip": "삭제 명령",
@@ -308,7 +308,7 @@
"cleared": "분할 화면이 지워졌습니다", "cleared": "분할 화면이 지워졌습니다",
"error": { "error": {
"noAssignments": "레이아웃에 최소 하나 이상의 탭을 지정해 주세요.", "noAssignments": "레이아웃에 최소 하나 이상의 탭을 지정해 주세요.",
"fillAllSlots": "지원하시려면 {{count}}개의 슬롯을 모두 채우신 후 지원해 주세요." "fillAllSlots": "지원하시려면 {{count}}을 모두 채우신 후 지원해 주세요."
} }
}, },
"homepage": { "homepage": {
@@ -343,9 +343,9 @@
"error": "버전 확인 오류", "error": "버전 확인 오류",
"checkFailed": "업데이트 확인에 실패했습니다.", "checkFailed": "업데이트 확인에 실패했습니다.",
"upToDate": "앱이 최신 버전입니다.", "upToDate": "앱이 최신 버전입니다.",
"currentVersion": "현재 버전 {{version}}을 실행 중입니다.", "currentVersion": "현재 {{version}}버전을 실행 중입니다.",
"updateAvailable": "업데이트 가능", "updateAvailable": "업데이트 가능",
"newVersionAvailable": "새 버전이 출시되었습니다! 현재 {{current}} 버전을 사용 중이지만 {{latest}} 버전을 사용할 수 있습니다.", "newVersionAvailable": "새 버전이 나왔습니다! 현재 {{current}}을 실행 중이지만 {{latest}} 을 사용할 수 있습니다.",
"releasedOn": "{{date}}에 출시됨", "releasedOn": "{{date}}에 출시됨",
"downloadUpdate": "업데이트 다운로드", "downloadUpdate": "업데이트 다운로드",
"dismiss": "해고하다", "dismiss": "해고하다",
@@ -382,7 +382,7 @@
"home": "집", "home": "집",
"expired": "만료됨", "expired": "만료됨",
"expiresToday": "오늘 만료됩니다", "expiresToday": "오늘 만료됩니다",
"expiresTomorrow": "{{days}}일 후에 만료됩니다", "expiresTomorrow": "{{days}} 일 후에 만료됩니다",
"updateAvailable": "업데이트 가능", "updateAvailable": "업데이트 가능",
"sshPath": "SSH 경로", "sshPath": "SSH 경로",
"localPath": "로컬 경로", "localPath": "로컬 경로",
@@ -508,8 +508,8 @@
"tokenUrl": "토큰 URL", "tokenUrl": "토큰 URL",
"updateSettings": "업데이트 설정", "updateSettings": "업데이트 설정",
"confirmDelete": "이 사용자를 삭제하시겠습니까?", "confirmDelete": "이 사용자를 삭제하시겠습니까?",
"confirmMakeAdmin": "{{username}}을 관리자로 지정하시겠습니까?", "confirmMakeAdmin": "{{username}}을 관리자로 지정하시겠습니까?",
"confirmRemoveAdmin": "{{username}}에서 관리자 상태를 제거하시겠습니까?", "confirmRemoveAdmin": "{{username}}에서 관리자 권한을 제거하시겠습니까?",
"externalAuthentication": "외부 인증(OIDC)", "externalAuthentication": "외부 인증(OIDC)",
"configureExternalProvider": "OIDC/OAuth2 인증을 위해 외부 ID 공급자를 구성합니다.", "configureExternalProvider": "OIDC/OAuth2 인증을 위해 외부 ID 공급자를 구성합니다.",
"userIdentifierPath": "사용자 식별자 경로", "userIdentifierPath": "사용자 식별자 경로",
@@ -547,12 +547,12 @@
"failedToUpdateOidcConfig": "OIDC 구성 업데이트에 실패했습니다.", "failedToUpdateOidcConfig": "OIDC 구성 업데이트에 실패했습니다.",
"failedToDisableOidcConfig": "OIDC 구성을 비활성화하는 데 실패했습니다.", "failedToDisableOidcConfig": "OIDC 구성을 비활성화하는 데 실패했습니다.",
"enterUsernameToMakeAdmin": "관리자 권한을 얻으려면 사용자 이름을 입력하세요.", "enterUsernameToMakeAdmin": "관리자 권한을 얻으려면 사용자 이름을 입력하세요.",
"userIsNowAdmin": "사용자 {{username}}님이 이제 관리자입니다.", "userIsNowAdmin": "사용자 {{username}} 님이 이제 관리자입니다.",
"failedToMakeUserAdmin": "사용자를 관리자로 만드는 데 실패했습니다.", "failedToMakeUserAdmin": "사용자를 관리자로 만드는 데 실패했습니다.",
"removeAdminStatus": "{{username}}에서 관리자 상태를 제거하시겠습니까?", "removeAdminStatus": "{{username}}에서 관리자 상태를 제거하시겠습니까?",
"adminStatusRemoved": "{{username}}에서 관리자 상태가 제거되었습니다.", "adminStatusRemoved": "{{username}}에서 관리자 상태가 제거되었습니다.",
"failedToRemoveAdminStatus": "관리자 권한 제거에 실패했습니다.", "failedToRemoveAdminStatus": "관리자 권한 제거에 실패했습니다.",
"userDeletedSuccessfully": "사용자 {{username}}님이 성공적으로 삭제했습니다.", "userDeletedSuccessfully": "사용자 {{username}} 님이 성공적으로 삭제했습니다.",
"failedToDeleteUser": "사용자 삭제에 실패했습니다", "failedToDeleteUser": "사용자 삭제에 실패했습니다",
"overrideUserInfoUrl": "사용자 정보 URL 재정의 (필수 아님)", "overrideUserInfoUrl": "사용자 정보 URL 재정의 (필수 아님)",
"failedToFetchSessions": "세션을 가져오는 데 실패했습니다.", "failedToFetchSessions": "세션을 가져오는 데 실패했습니다.",
@@ -564,12 +564,12 @@
"sessionsRevokedSuccessfully": "세션이 성공적으로 취소되었습니다.", "sessionsRevokedSuccessfully": "세션이 성공적으로 취소되었습니다.",
"linkToPasswordAccount": "비밀번호 계정 링크", "linkToPasswordAccount": "비밀번호 계정 링크",
"linkOIDCDialogTitle": "OIDC 계정을 비밀번호 계정에 연결", "linkOIDCDialogTitle": "OIDC 계정을 비밀번호 계정에 연결",
"linkOIDCDialogDescription": "{{username}}(OIDC 사용자) 기존 암호 계정에 연결합니다. 이렇게 하면 암호 계정에 대한 이중 인증이 활성화됩니다.", "linkOIDCDialogDescription": "{{username}} (OIDC 사용자) 기존 암호 계정에 연결합니다. 이렇게 하면 암호 계정에 이중 인증이 활성화됩니다.",
"createUser": "사용자 생성", "createUser": "사용자 생성",
"createUserDescription": "사용자 이름과 비밀번호를 사용하여 새 로컬 사용자를 생성합니다.", "createUserDescription": "사용자 이름과 비밀번호를 사용하여 새 로컬 사용자를 생성합니다.",
"enterUsername": "사용자 이름을 입력하세요", "enterUsername": "사용자 이름을 입력하세요",
"enterPassword": "비밀번호를 입력하세요", "enterPassword": "비밀번호를 입력하세요",
"userCreatedSuccessfully": "사용자 {{username}}님이 성공적으로 생성되었습니다.", "userCreatedSuccessfully": "사용자 {{username}} 님이 성공적으로 생성습니다.",
"failedToCreateUser": "사용자 생성에 실패했습니다", "failedToCreateUser": "사용자 생성에 실패했습니다",
"manageUser": "사용자 관리", "manageUser": "사용자 관리",
"manageUserDescription": "사용자 설정, 역할 및 권한을 관리합니다.", "manageUserDescription": "사용자 설정, 역할 및 권한을 관리합니다.",
@@ -581,7 +581,7 @@
"administratorRole": "관리자 역할", "administratorRole": "관리자 역할",
"administratorRoleDescription": "전체 시스템 접근 권한 및 관리 권한을 부여하십시오.", "administratorRoleDescription": "전체 시스템 접근 권한 및 관리 권한을 부여하십시오.",
"passwordManagement": "비밀번호 관리", "passwordManagement": "비밀번호 관리",
"passwordResetWarning": "사용자 호를 재설정하면 해당 사용자의 모든 데이터(SSH 호스트, 자격 증명, 설정)가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", "passwordResetWarning": "사용자 비밀번호를 재설정하면 해당 사용자의 모든 데이터(SSH 호스트, 자격 증명, 설정)가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.",
"resetUserPassword": "사용자 비밀번호 재설정", "resetUserPassword": "사용자 비밀번호 재설정",
"resettingPassword": "재설정 중...", "resettingPassword": "재설정 중...",
"passwordResetInitiated": "{{username}}에 대한 비밀번호 재설정이 시작되었습니다. 재설정 코드가 전송되었습니다.", "passwordResetInitiated": "{{username}}에 대한 비밀번호 재설정이 시작되었습니다. 재설정 코드가 전송되었습니다.",
@@ -611,12 +611,12 @@
"linkTargetUsernamePlaceholder": "사용자 이름과 비밀번호를 입력하세요.", "linkTargetUsernamePlaceholder": "사용자 이름과 비밀번호를 입력하세요.",
"linkAccountsButton": "계정 연동", "linkAccountsButton": "계정 연동",
"linkingAccounts": "연결 중...", "linkingAccounts": "연결 중...",
"accountsLinkedSuccessfully": "OIDC 사용자 {{oidcUsername}} {{targetUsername}}에 연결되었습니다.", "accountsLinkedSuccessfully": "OIDC 사용자 {{oidcUsername}} {{targetUsername}}에 연결되었습니다.",
"failedToLinkAccounts": "계정 연결에 실패했습니다", "failedToLinkAccounts": "계정 연결에 실패했습니다",
"linkTargetUsernameRequired": "대상 사용자 이름은 필수입니다.", "linkTargetUsernameRequired": "대상 사용자 이름은 필수입니다.",
"unlinkOIDCTitle": "OIDC 인증 연결 해제", "unlinkOIDCTitle": "OIDC 인증 연결 해제",
"unlinkOIDCDescription": "{{username}}에서 OIDC 인증을 제거하시겠습니까? 이렇게 하면 사용자는 사용자 이름/비밀번호로만 로그인할 수 있습니다.", "unlinkOIDCDescription": "{{username}}에서 OIDC 인증을 제거하시겠습니까? 이렇게 하면 사용자는 사용자 이름/비밀번호로만 로그인할 수 있습니다.",
"unlinkOIDCSuccess": "OIDC {{username}}에서 연결 해제되었습니다.", "unlinkOIDCSuccess": "OIDC {{username}}에서 연결 해제되었습니다.",
"failedToUnlinkOIDC": "OIDC 연결 해제에 실패했습니다.", "failedToUnlinkOIDC": "OIDC 연결 해제에 실패했습니다.",
"databaseSecurity": "데이터베이스 보안", "databaseSecurity": "데이터베이스 보안",
"encryptionStatus": "암호화 상태", "encryptionStatus": "암호화 상태",
@@ -756,9 +756,9 @@
"revokeAllUserSessionsTitle": "이 사용자에 대한 모든 세션을 취소합니다.", "revokeAllUserSessionsTitle": "이 사용자에 대한 모든 세션을 취소합니다.",
"revokeAll": "모두 취소", "revokeAll": "모두 취소",
"linkOidcToPasswordAccount": "OIDC 계정을 비밀번호 계정에 연결", "linkOidcToPasswordAccount": "OIDC 계정을 비밀번호 계정에 연결",
"linkOidcToPasswordAccountDescription": "{{username}}(OIDC 사용자)를 기존 암호 계정에 연결합니다. 이렇게 하면 암호 계정에 대한 이중 인증이 활성화됩니다.", "linkOidcToPasswordAccountDescription": "{{username}} (OIDC 사용자)를 기존 암호 계정에 연결합니다. 이렇게 하면 암호 계정에 이중 인증이 활성화됩니다.",
"linkOidcWarningTitle": "경고: OIDC 사용자 데이터가 삭제됩니다.", "linkOidcWarningTitle": "경고: OIDC 사용자 데이터가 삭제됩니다.",
"linkOidcWarningDescription": "이 조치는 다음과 같은 결과를 가져올 것입니다:", "linkOidcWarningDescription": "이 작업은 다음과 같은 결과를 가져올 것입니다:",
"linkOidcActionDeleteUser": "OIDC 사용자 계정과 해당 계정의 모든 데이터를 삭제하세요.", "linkOidcActionDeleteUser": "OIDC 사용자 계정과 해당 계정의 모든 데이터를 삭제하세요.",
"linkOidcActionAddCapability": "대상 암호 계정에 OIDC 로그인 기능을 추가합니다.", "linkOidcActionAddCapability": "대상 암호 계정에 OIDC 로그인 기능을 추가합니다.",
"linkOidcActionDualAuth": "비밀번호 계정이 비밀번호와 OIDC 모두를 사용하여 로그인할 수 있도록 허용합니다.", "linkOidcActionDualAuth": "비밀번호 계정이 비밀번호와 OIDC 모두를 사용하여 로그인할 수 있도록 허용합니다.",
@@ -787,7 +787,7 @@
"exportCredentialWarning": "경고: 호스트 \"{{name}}\"는 자격 증명 인증을 사용합니다. 내보낸 파일에는 자격 증명 데이터가 포함되지 않으므로 가져온 후 수동으로 다시 구성해야 합니다. 계속하시겠습니까?", "exportCredentialWarning": "경고: 호스트 \"{{name}}\"는 자격 증명 인증을 사용합니다. 내보낸 파일에는 자격 증명 데이터가 포함되지 않으므로 가져온 후 수동으로 다시 구성해야 합니다. 계속하시겠습니까?",
"exportSensitiveDataWarning": "경고: 호스트 \"{{name}}\"에 민감한 인증 데이터(암호/SSH 키)가 포함되어 있습니다. 내보낸 파일에는 이 데이터가 평문으로 포함됩니다. 파일을 안전하게 보관하고 사용 후 삭제하십시오. 계속하시겠습니까?", "exportSensitiveDataWarning": "경고: 호스트 \"{{name}}\"에 민감한 인증 데이터(암호/SSH 키)가 포함되어 있습니다. 내보낸 파일에는 이 데이터가 평문으로 포함됩니다. 파일을 안전하게 보관하고 사용 후 삭제하십시오. 계속하시겠습니까?",
"uncategorized": "분류되지 않음", "uncategorized": "분류되지 않음",
"confirmDelete": "\"{{name}}\" 정말로 삭제하시겠습니까?", "confirmDelete": "\"{{name}}\" 정말로 삭제하시겠습니까?",
"failedToDeleteHost": "호스트 삭제에 실패했습니다", "failedToDeleteHost": "호스트 삭제에 실패했습니다",
"failedToExportHost": "호스트 내보내기에 실패했습니다. 로그인되어 있고 호스트 데이터에 접근 권한이 있는지 확인하십시오.", "failedToExportHost": "호스트 내보내기에 실패했습니다. 로그인되어 있고 호스트 데이터에 접근 권한이 있는지 확인하십시오.",
"jsonMustContainHosts": "JSON에는 \"hosts\" 배열이 포함되어 있거나 호스트 배열이어야 합니다.", "jsonMustContainHosts": "JSON에는 \"hosts\" 배열이 포함되어 있거나 호스트 배열이어야 합니다.",
@@ -837,10 +837,10 @@
"connection": "연결", "connection": "연결",
"remove": "제거하다", "remove": "제거하다",
"sourcePort": "소스 포트", "sourcePort": "소스 포트",
"sourcePortDesc": "(출처는 일반 탭의 현재 연결 세부 정보입니다.)", "sourcePortDesc": " (출처는 일반 탭의 현재 연결 세부 정보입니다.)",
"endpointPort": "엔드포인트 포트", "endpointPort": "엔드포인트 포트",
"endpointSshConfig": "엔드포인트 SSH 구성", "endpointSshConfig": "엔드포인트 SSH 구성",
"tunnelForwardDescription": "이 터널은 소스 머신(일반 탭의 현재 연결 세부 정보)의 포트 {{sourcePort}}에서 엔드포인트 머신의 포트 {{endpointPort}}로 트래픽을 전달합니다.", "tunnelForwardDescription": "이 터널은 소스 머신(일반 탭의 현재 연결 세부 정보 참조)의 포트 {{sourcePort}} 에서 엔드포인트 머신의 포트 {{endpointPort}} 로 트래픽을 전달합니다.",
"maxRetries": "최대 재시도 횟수", "maxRetries": "최대 재시도 횟수",
"maxRetriesDescription": "터널 연결에 대한 최대 재시도 횟수입니다.", "maxRetriesDescription": "터널 연결에 대한 최대 재시도 횟수입니다.",
"retryInterval": "재시도 간격(초)", "retryInterval": "재시도 간격(초)",
@@ -916,7 +916,7 @@
"customCommandsDesc": "이 서버에 대한 사용자 지정 종료 및 재부팅 명령을 정의하십시오.", "customCommandsDesc": "이 서버에 대한 사용자 지정 종료 및 재부팅 명령을 정의하십시오.",
"shutdownCommand": "종료 명령", "shutdownCommand": "종료 명령",
"rebootCommand": "재부팅 명령", "rebootCommand": "재부팅 명령",
"confirmRemoveFromFolder": "\"{{name}}\"를 \"{{folder}}\" 폴더에서 제하시겠습니까? 호스트가 \"폴더 없음\"으로 이동됩니다.", "confirmRemoveFromFolder": "\"{{folder}}\" 폴더에서 \"{{name}}\"를 삭제하시겠습니까? 호스트가 \"폴더 없음\"으로 이동됩니다.",
"removedFromFolder": "호스트 \"{{name}}\"가 폴더에서 성공적으로 제거되었습니다.", "removedFromFolder": "호스트 \"{{name}}\"가 폴더에서 성공적으로 제거되었습니다.",
"failedToRemoveFromFolder": "호스트를 폴더에서 제거하는 데 실패했습니다.", "failedToRemoveFromFolder": "호스트를 폴더에서 제거하는 데 실패했습니다.",
"folderRenamed": "폴더 \"{{oldName}}\"의 이름이 \"{{newName}}\"로 성공적으로 변경되었습니다.", "folderRenamed": "폴더 \"{{oldName}}\"의 이름이 \"{{newName}}\"로 성공적으로 변경되었습니다.",
@@ -929,10 +929,10 @@
"folderAppearanceUpdated": "폴더 모양이 성공적으로 업데이트되었습니다.", "folderAppearanceUpdated": "폴더 모양이 성공적으로 업데이트되었습니다.",
"failedToUpdateFolderAppearance": "폴더 모양 업데이트에 실패했습니다.", "failedToUpdateFolderAppearance": "폴더 모양 업데이트에 실패했습니다.",
"deleteAllHostsInFolder": "폴더 안의 모든 호스트를 삭제합니다", "deleteAllHostsInFolder": "폴더 안의 모든 호스트를 삭제합니다",
"confirmDeleteAllHostsInFolder": "폴더 \"{{count}}\"에 있는 모든 {{folder}} 호스트를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", "confirmDeleteAllHostsInFolder": "\"{{folder}}\" 폴더에 있는 모든 {{count}} 호스트를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"allHostsInFolderDeleted": "폴더 \"{{count}}\"에서 호스트 {{folder}}개를 성공적으로 삭제했습니다.", "allHostsInFolderDeleted": "폴더 \"{{folder}}\"에서 {{count}} 호스트를 성공적으로 삭제했습니다.",
"failedToDeleteHostsInFolder": "폴더에서 호스트를 삭제하는 데 실패했습니다.", "failedToDeleteHostsInFolder": "폴더에서 호스트를 삭제하는 데 실패했습니다.",
"movedToFolder": "호스트 \"{{name}}\" \"{{folder}}\"로 성공적으로 이동했습니다.", "movedToFolder": "호스트 \"{{name}}\" \"{{folder}}\"로 성공적으로 이동했습니다.",
"failedToMoveToFolder": "호스트를 폴더로 이동하는 데 실패했습니다.", "failedToMoveToFolder": "호스트를 폴더로 이동하는 데 실패했습니다.",
"clickToRenameFolder": "폴더 이름을 바꾸려면 클릭하세요", "clickToRenameFolder": "폴더 이름을 바꾸려면 클릭하세요",
"renameFolder": "폴더 이름 변경", "renameFolder": "폴더 이름 변경",
@@ -982,13 +982,13 @@
"selectFont": "글꼴을 선택하세요", "selectFont": "글꼴을 선택하세요",
"selectFontDesc": "터미널에서 사용할 글꼴을 선택하세요.", "selectFontDesc": "터미널에서 사용할 글꼴을 선택하세요.",
"fontSize": "글꼴 크기", "fontSize": "글꼴 크기",
"fontSizeValue": "글꼴 크기: {{value}}px", "fontSizeValue": "글꼴 크기: {{value}}픽셀",
"adjustFontSize": "터미널 글꼴 크기를 조정하세요", "adjustFontSize": "터미널 글꼴 크기를 조정하세요",
"letterSpacing": "글자 간격", "letterSpacing": "글자 간격",
"letterSpacingValue": "글자 간격: {{value}}px", "letterSpacingValue": "글자 간격: {{value}}픽셀",
"adjustLetterSpacing": "문자 간 간격을 조정하세요", "adjustLetterSpacing": "문자 간 간격을 조정하세요",
"lineHeight": "선 높이", "lineHeight": "선 높이",
"lineHeightValue": " 높이: {{value}}", "lineHeightValue": " 높이: {{value}}",
"adjustLineHeight": "줄 간격을 조정하세요", "adjustLineHeight": "줄 간격을 조정하세요",
"cursorStyle": "커서 스타일", "cursorStyle": "커서 스타일",
"selectCursorStyle": "커서 스타일을 선택하세요", "selectCursorStyle": "커서 스타일을 선택하세요",
@@ -999,7 +999,7 @@
"cursorBlink": "커서 깜빡임", "cursorBlink": "커서 깜빡임",
"enableCursorBlink": "커서 깜빡임 애니메이션 활성화", "enableCursorBlink": "커서 깜빡임 애니메이션 활성화",
"scrollbackBuffer": "스크롤백 버퍼", "scrollbackBuffer": "스크롤백 버퍼",
"scrollbackBufferValue": "스크롤백 버퍼: {{value}}줄", "scrollbackBufferValue": "스크롤백 버퍼: {{value}} 줄",
"scrollbackBufferDesc": "스크롤백 기록에 유지할 줄 수", "scrollbackBufferDesc": "스크롤백 기록에 유지할 줄 수",
"bellStyle": "벨 스타일", "bellStyle": "벨 스타일",
"selectBellStyle": "벨 스타일을 선택하세요", "selectBellStyle": "벨 스타일을 선택하세요",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "소리", "bellStyleSound": "소리",
"bellStyleVisual": "시각", "bellStyleVisual": "시각",
"bellStyleBoth": "둘 다", "bellStyleBoth": "둘 다",
"bellStyleDesc": "터미널 알림음(BEL 문자, \\x07)을 처리하는 방법입니다. 프로그램은 작업 완료, 오류 발생 또는 알림 시 이 알림음을 발생시킵니다. \"소리\"는 알림음을 재생하고, \"시각\"은 화면을 잠 깜빡이게 하며, \"둘 다\"는 소리와 깜빡임 모두 표시하고, \"없음\"은 알림음을 비활성화합니다.", "bellStyleDesc": "터미널 알림음(BEL 문자, \\x07)을 처리하는 방법입니다. 프로그램은 작업 완료, 오류 발생 또는 알림 시 이 알림음을 발생시킵니다. \"소리\"는 경고음을 재생하고, \"시각\"은 화면을 잠 깜빡이게 하며, \"둘 다\"는 경고음과 화면 깜빡임 모두 표시하고, \"없음\"은 알림음을 비활성화합니다.",
"rightClickSelectsWord": "마우스 오른쪽 버튼을 클릭하고 단어를 선택하세요.", "rightClickSelectsWord": "마우스 오른쪽 버튼을 클릭하고 단어를 선택하세요.",
"rightClickSelectsWordDesc": "마우스 오른쪽 버튼을 클릭하면 커서 아래에 있는 단어가 선택됩니다.", "rightClickSelectsWordDesc": "마우스 오른쪽 버튼을 클릭하면 커서 아래에 있는 단어가 선택됩니다.",
"fastScrollModifier": "빠른 스크롤 수정자", "fastScrollModifier": "빠른 스크롤 수정자",
@@ -1030,7 +1030,7 @@
"backspaceModeControlH": "컨트롤-H (^H)", "backspaceModeControlH": "컨트롤-H (^H)",
"backspaceModeDesc": "호환성을 위한 백스페이스 키 동작", "backspaceModeDesc": "호환성을 위한 백스페이스 키 동작",
"startupSnippet": "스타트업 스니펫", "startupSnippet": "스타트업 스니펫",
"selectSnippet": "코드 조각을 선택하세요", "selectSnippet": "스니펫을 선택하세요",
"searchSnippets": "검색 스니펫...", "searchSnippets": "검색 스니펫...",
"snippetNone": "없음", "snippetNone": "없음",
"noneAuthTitle": "키보드 인터랙티브 인증", "noneAuthTitle": "키보드 인터랙티브 인증",
@@ -1086,7 +1086,7 @@
"socks5HostDescription": "SOCKS 프록시 서버의 호스트 이름 또는 IP 주소", "socks5HostDescription": "SOCKS 프록시 서버의 호스트 이름 또는 IP 주소",
"socks5PortDescription": "SOCKS 프록시 서버의 포트 번호(기본값: 1080)", "socks5PortDescription": "SOCKS 프록시 서버의 포트 번호(기본값: 1080)",
"addProxyNode": "프록시 노드 추가", "addProxyNode": "프록시 노드 추가",
"noProxyNodes": "구성된 프록시 노드가 없습니다. 프록시 노드를 추가하려면 '프록시 노드 추가'를 클릭하십시오.", "noProxyNodes": "구성된 프록시 노드가 없습니다. '프록시 노드 추가'를 클릭하여 추가하세요.",
"proxyNode": "프록시 노드", "proxyNode": "프록시 노드",
"proxyType": "프록시 유형", "proxyType": "프록시 유형",
"quickActions": "빠른 조치", "quickActions": "빠른 조치",
@@ -1100,7 +1100,7 @@
"sudoPasswordAutoFill": "Sudo 비밀번호 자동 완성", "sudoPasswordAutoFill": "Sudo 비밀번호 자동 완성",
"sudoPasswordAutoFillDesc": "sudo 명령어가 암호를 입력하라는 메시지를 표시할 때 SSH 암호를 자동으로 입력하도록 제안합니다.", "sudoPasswordAutoFillDesc": "sudo 명령어가 암호를 입력하라는 메시지를 표시할 때 SSH 암호를 자동으로 입력하도록 제안합니다.",
"sudoPassword": "Sudo 비밀번호", "sudoPassword": "Sudo 비밀번호",
"sudoPasswordDesc": "sudo 명령어에 사용할 수 있는 선택적 암호 (키 인증 시 유용)", "sudoPasswordDesc": "sudo 명령어에 사용할 선택적 암호 (키 인증 시 유용)",
"socks4": "양말4개", "socks4": "양말4개",
"socks5": "양말5", "socks5": "양말5",
"executeSnippetOnConnect": "터미널이 연결될 때 코드 조각을 실행합니다.", "executeSnippetOnConnect": "터미널이 연결될 때 코드 조각을 실행합니다.",
@@ -1140,7 +1140,7 @@
"failedToConnect": "콘솔에 연결하지 못했습니다.", "failedToConnect": "콘솔에 연결하지 못했습니다.",
"disconnectedFromContainer": "컨테이너 콘솔 연결이 끊어졌습니다.", "disconnectedFromContainer": "컨테이너 콘솔 연결이 끊어졌습니다.",
"containerNotRunning": "컨테이너가 실행 중이 아닙니다.", "containerNotRunning": "컨테이너가 실행 중이 아닙니다.",
"startContainerToAccess": "콘솔에 접하려면 컨테이너를 시작하세요.", "startContainerToAccess": "콘솔에 접하려면 컨테이너를 시작하세요.",
"selectShell": "쉘을 선택하세요", "selectShell": "쉘을 선택하세요",
"bash": "세게 때리다", "bash": "세게 때리다",
"sh": "쉿", "sh": "쉿",
@@ -1160,17 +1160,17 @@
"allContainersCount": "모두 ({{count}})", "allContainersCount": "모두 ({{count}})",
"statusCount": "{{status}} ({{count}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "필터 조건에 맞는 컨테이너가 없습니다.", "noContainersMatchFilters": "필터 조건에 맞는 컨테이너가 없습니다.",
"noContainersMatchFiltersHint": "검색 또는 필터 조건을 조정해 보세요.", "noContainersMatchFiltersHint": "검색 또는 필터 설정을 조정해 보세요.",
"containerStarted": "컨테이너 {{name}} 시작됨", "containerStarted": "컨테이너 {{name}} 시작됨",
"failedToStartContainer": "컨테이너 시작 실패: {{error}}", "failedToStartContainer": "컨테이너 시작 실패: {{error}}",
"containerStopped": "컨테이너 {{name}}가 중지되었습니다.", "containerStopped": "컨테이너 {{name}} 가 중지되었습니다.",
"failedToStopContainer": "컨테이너를 중지하는 데 실패했습니다: {{error}}", "failedToStopContainer": "컨테이너 {{error}}를 중지하는 데 실패했습니다.",
"containerRestarted": "컨테이너 {{name}}가 재시작되었습니다.", "containerRestarted": "컨테이너 {{name}} 가 재시작되었습니다.",
"failedToRestartContainer": "컨테이너 재시작 실패: {{error}}", "failedToRestartContainer": "컨테이너 재시작 실패: {{error}}",
"containerUnpaused": "컨테이너 {{name}} 일시 중지 해제됨", "containerUnpaused": "컨테이너 {{name}} 일시 중지 해제됨",
"containerPaused": "컨테이너 {{name}} 일시 중지됨", "containerPaused": "컨테이너 {{name}} 일시 중지됨",
"failedToTogglePauseContainer": "컨테이너 {{action}}에 실패했습니다: {{error}}", "failedToTogglePauseContainer": "{{action}} 컨테이너에 실패했습니다: {{error}}",
"containerRemoved": "컨테이너 {{name}} 제거되었습니다.", "containerRemoved": "컨테이너 {{name}} 제거되었습니다.",
"failedToRemoveContainer": "컨테이너 {{error}}를 제거하는 데 실패했습니다.", "failedToRemoveContainer": "컨테이너 {{error}}를 제거하는 데 실패했습니다.",
"image": "영상:", "image": "영상:",
"idLabel": "ID:", "idLabel": "ID:",
@@ -1183,7 +1183,7 @@
"pause": "정지시키다", "pause": "정지시키다",
"restart": "재시작", "restart": "재시작",
"removeContainer": "컨테이너를 제거하세요", "removeContainer": "컨테이너를 제거하세요",
"confirmRemoveContainer": "컨테이너 \"{{name}}\" 정말로 제거하시겠습니까?", "confirmRemoveContainer": "컨테이너 \"{{name}}\" 정말로 제거하시겠습니까?",
"runningContainerWarning": "경고: 이 컨테이너는 현재 실행 중이며 강제로 제거될 예정입니다.", "runningContainerWarning": "경고: 이 컨테이너는 현재 실행 중이며 강제로 제거될 예정입니다.",
"removing": "풀이:", "removing": "풀이:",
"containerNotFound": "컨테이너를 찾을 수 없습니다", "containerNotFound": "컨테이너를 찾을 수 없습니다",
@@ -1236,7 +1236,7 @@
"connectionTimeout": "연결 시간 초과", "connectionTimeout": "연결 시간 초과",
"terminalTitle": "터미널 - {{host}}", "terminalTitle": "터미널 - {{host}}",
"terminalWithPath": "터미널 - {{host}}:{{path}}", "terminalWithPath": "터미널 - {{host}}:{{path}}",
"runTitle": "{{command}} - {{host}} 실행 중", "runTitle": "{{command}} - {{host}}실행 중",
"totpRequired": "2단계 인증이 필요합니다", "totpRequired": "2단계 인증이 필요합니다",
"totpCodeLabel": "인증 코드", "totpCodeLabel": "인증 코드",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
@@ -1254,26 +1254,26 @@
"uploadFile": "파일 업로드", "uploadFile": "파일 업로드",
"downloadFile": "다운로드", "downloadFile": "다운로드",
"extractArchive": "압축 해제", "extractArchive": "압축 해제",
"extractingArchive": "{{name}} 추출 중...", "extractingArchive": "{{name}}추출 중...",
"archiveExtractedSuccessfully": "{{name}}이 성공적으로 추출되었습니다.", "archiveExtractedSuccessfully": "{{name}} 추출 성공",
"extractFailed": "추출 실패", "extractFailed": "추출 실패",
"compressFile": "파일 압축", "compressFile": "파일 압축",
"compressFiles": "파일 압축", "compressFiles": "파일 압축",
"compressFilesDesc": "{{count}}개의 항목을 아카이브로 압축합니다.", "compressFilesDesc": "{{count}} 항목을 아카이브로 압축합니다.",
"archiveName": "아카이브 이름", "archiveName": "아카이브 이름",
"enterArchiveName": "아카이브 이름을 입력하세요...", "enterArchiveName": "아카이브 이름을 입력하세요...",
"compressionFormat": "압축 형식", "compressionFormat": "압축 형식",
"selectedFiles": "선택된 파일", "selectedFiles": "선택된 파일",
"andMoreFiles": "그리고 {{count}} 더...", "andMoreFiles": "그리고 {{count}} 더 보기...",
"compress": "압박 붕대", "compress": "압박 붕대",
"compressingFiles": "{{count}}개의 항목을 {{name}}로 압축 중...", "compressingFiles": "{{count}} 항목을 {{name}}로 압축 중...",
"filesCompressedSuccessfully": "{{name}} 성공적으로 생성되었습니다.", "filesCompressedSuccessfully": "{{name}} 성공적으로 생성되었습니다",
"compressFailed": "압축 실패", "compressFailed": "압축 실패",
"edit": "편집하다", "edit": "편집하다",
"preview": "시사", "preview": "시사",
"previous": "이전의", "previous": "이전의",
"next": "다음", "next": "다음",
"pageXOfY": "{{current}} 페이지 {{total}}", "pageXOfY": "{{total}} 페이지 {{current}}",
"zoomOut": "축소하기", "zoomOut": "축소하기",
"zoomIn": "확대", "zoomIn": "확대",
"newFile": "새 파일", "newFile": "새 파일",
@@ -1289,13 +1289,13 @@
"chooseFile": "파일을 선택하세요", "chooseFile": "파일을 선택하세요",
"uploading": "업로드 중...", "uploading": "업로드 중...",
"downloading": "다운로드 중...", "downloading": "다운로드 중...",
"uploadingFile": "{{name}} 업로드 중...", "uploadingFile": "{{name}}업로드 중...",
"uploadingLargeFile": "대용량 파일 {{name}} ({{size}}) 업로드 중...", "uploadingLargeFile": "대용량 파일 {{name}} ({{size}} ) 업로드 중...",
"downloadingFile": "{{name}} 다운로드 중...", "downloadingFile": "{{name}}다운로드 중...",
"creatingFile": "{{name}}를 생성하는 중...", "creatingFile": "{{name}}생성 중...",
"creatingFolder": "{{name}}을 생성하는 중...", "creatingFolder": "{{name}}생성 중...",
"deletingItem": "{{type}} {{name}} 삭제 중...", "deletingItem": "{{type}} {{name}}삭제 중...",
"renamingItem": "{{type}} {{oldName}}를 {{newName}}로 이름 변경 중...", "renamingItem": "{{type}} {{oldName}} 를 {{newName}}로 이름 변경 중...",
"createNewFile": "새 파일 만들기", "createNewFile": "새 파일 만들기",
"fileName": "파일 이름", "fileName": "파일 이름",
"creating": "생성 중...", "creating": "생성 중...",
@@ -1314,23 +1314,23 @@
"fileUploadedSuccessfully": "파일 \"{{name}}\"이 성공적으로 업로드되었습니다.", "fileUploadedSuccessfully": "파일 \"{{name}}\"이 성공적으로 업로드되었습니다.",
"failedToUploadFile": "파일 업로드에 실패했습니다", "failedToUploadFile": "파일 업로드에 실패했습니다",
"fileDownloadedSuccessfully": "파일 \"{{name}}\"이 성공적으로 다운로드되었습니다.", "fileDownloadedSuccessfully": "파일 \"{{name}}\"이 성공적으로 다운로드되었습니다.",
"failedToDownloadFile": "파일 다운로드에 실패했습니다.", "failedToDownloadFile": "파일 다운로드에 실패했습니다",
"noFileContent": "파일 내용이 수신되지 않았습니다.", "noFileContent": "파일 내용이 수신되지 않았습니다.",
"filePath": "파일 경로", "filePath": "파일 경로",
"fileCreatedSuccessfully": "파일 \"{{name}}\"이 성공적으로 생성되었습니다.", "fileCreatedSuccessfully": "파일 \"{{name}}\"이 성공적으로 생성되었습니다.",
"failedToCreateFile": "파일 생성에 실패했습니다.", "failedToCreateFile": "파일 생성에 실패했습니다.",
"folderCreatedSuccessfully": "폴더 \"{{name}}\" 성공적으로 생성되었습니다.", "folderCreatedSuccessfully": "폴더 \"{{name}}\" 성공적으로 생성되었습니다.",
"failedToCreateFolder": "폴더 생성에 실패했습니다", "failedToCreateFolder": "폴더 생성에 실패했습니다",
"failedToCreateItem": "아이템 생성에 실패했습니다", "failedToCreateItem": "아이템 생성에 실패했습니다",
"operationFailed": "{{operation}} 작업이 {{name}}에 대해 실패했습니다: {{error}}", "operationFailed": "{{operation}} 작업이 {{name}}에 대해 실패했습니다 : {{error}}",
"failedToResolveSymlink": "심볼릭 링크를 해결할 수 없습니다.", "failedToResolveSymlink": "심볼릭 링크를 해결할 수 없습니다.",
"itemDeletedSuccessfully": "{{type}} 성공적으로 삭제되었습니다.", "itemDeletedSuccessfully": "{{type}} 성공적으로 삭제되었습니다",
"itemsDeletedSuccessfully": "{{count}}개의 항목이 성공적으로 삭제되었습니다.", "itemsDeletedSuccessfully": "{{count}} 항목이 성공적으로 삭제되었습니다",
"failedToDeleteItems": "항목 삭제에 실패했습니다", "failedToDeleteItems": "항목 삭제에 실패했습니다",
"dragFilesToUpload": "파일을 여기에 드롭하여 업로드하세요", "dragFilesToUpload": "파일을 여기에 드롭하여 업로드하세요",
"emptyFolder": "이 폴더는 비어 있습니다", "emptyFolder": "이 폴더는 비어 있습니다",
"itemCount": "{{count}} 항목", "itemCount": "{{count}} 항목",
"selectedCount": "{{count}}명이 선택했습니다", "selectedCount": "{{count}} 선택",
"searchFiles": "파일을 검색하세요...", "searchFiles": "파일을 검색하세요...",
"upload": "업로드", "upload": "업로드",
"selectHostToStart": "파일 관리를 시작할 호스트를 선택하십시오.", "selectHostToStart": "파일 관리를 시작할 호스트를 선택하십시오.",
@@ -1347,28 +1347,28 @@
"delete": "삭제", "delete": "삭제",
"properties": "속성", "properties": "속성",
"refresh": "새로 고치다", "refresh": "새로 고치다",
"downloadFiles": "브라우저 {{count}}개의 파일을 다운로드하세요", "downloadFiles": "브라우저 {{count}} 파일을 다운로드하세요",
"copyFiles": "{{count}} 항목을 복사합니다.", "copyFiles": "{{count}} 항목을 복사하세요",
"cutFiles": "{{count}} 항목을 잘라냅니다.", "cutFiles": "{{count}} 항목을 잘라내세요",
"deleteFiles": "{{count}} 항목을 삭제합니다.", "deleteFiles": "{{count}} 항목을 삭제합니다.",
"filesCopiedToClipboard": "{{count}}개의 항목이 클립보드에 복사되었습니다.", "filesCopiedToClipboard": "{{count}} 항목이 클립보드에 복사되었습니다",
"filesCutToClipboard": "{{count}}개의 항목 클립보드에 잘렸습니다.", "filesCutToClipboard": "{{count}} 항목 클립보드에 복사합니다",
"pathCopiedToClipboard": "경로가 클립보드에 복사되었습니다", "pathCopiedToClipboard": "경로가 클립보드에 복사되었습니다",
"pathsCopiedToClipboard": "{{count}}개의 경로가 클립보드에 복사되었습니다.", "pathsCopiedToClipboard": "{{count}} 경로가 클립보드에 복사되었습니다",
"failedToCopyPath": "클립보드에 경로를 복사하는 데 실패했습니다.", "failedToCopyPath": "클립보드에 경로를 복사하는 데 실패했습니다.",
"movedItems": "{{count}}개의 항목을 이동했습니다.", "movedItems": "{{count}} 항목을 이동했습니다.",
"failedToDeleteItem": "항목 삭제에 실패했습니다", "failedToDeleteItem": "항목 삭제에 실패했습니다",
"itemRenamedSuccessfully": "{{type}} 이름이 성공적으로 변경되었습니다.", "itemRenamedSuccessfully": "{{type}} 이름이 성공적으로 변경되었습니다",
"failedToRenameItem": "항목 이름 변경에 실패했습니다", "failedToRenameItem": "항목 이름 변경에 실패했습니다",
"download": "다운로드", "download": "다운로드",
"permissions": "권한", "permissions": "권한",
"size": "크기", "size": "크기",
"modified": "수정됨", "modified": "수정됨",
"path": "길", "path": "길",
"confirmDelete": "{{name}} 삭제하시겠습니까?", "confirmDelete": "{{name}}를 정말로 삭제하시겠습니까?",
"uploadSuccess": "파일 업로드 완료", "uploadSuccess": "파일 업로드 완료",
"uploadFailed": "파일 업로드 실패", "uploadFailed": "파일 업로드 실패",
"downloadSuccess": "파일 다운로드 완료되었습니다.", "downloadSuccess": "파일 다운로드 완료",
"downloadFailed": "파일 다운로드 실패", "downloadFailed": "파일 다운로드 실패",
"permissionDenied": "권한이 거부되었습니다", "permissionDenied": "권한이 거부되었습니다",
"checkDockerLogs": "자세한 오류 정보는 Docker 로그를 확인하세요.", "checkDockerLogs": "자세한 오류 정보는 Docker 로그를 확인하세요.",
@@ -1388,11 +1388,11 @@
"connectToServer": "서버에 연결", "connectToServer": "서버에 연결",
"selectServerToEdit": "사이드바에서 서버를 선택하여 파일 편집을 시작하세요.", "selectServerToEdit": "사이드바에서 서버를 선택하여 파일 편집을 시작하세요.",
"fileOperations": "파일 작업", "fileOperations": "파일 작업",
"confirmDeleteMessage": "{{name}} 정말로 삭제하시겠습니까?", "confirmDeleteMessage": "{{name}} 정말로 삭제하시겠습니까?",
"confirmDeleteSingleItem": "\"{{name}}\"을 영구적으로 삭제하시겠습니까?", "confirmDeleteSingleItem": "\"{{name}}\"을 영구적으로 삭제하시겠습니까?",
"confirmDeleteMultipleItems": "{{count}}개의 항목을 영구적으로 삭제하시겠습니까?", "confirmDeleteMultipleItems": "{{count}} 항목을 영구적으로 삭제하시겠습니까?",
"confirmDeleteMultipleItemsWithFolders": "{{count}}개의 항목을 영구적으로 삭제하시겠습니까? 여기에는 폴더와 그 내용물이 포함됩니다.", "confirmDeleteMultipleItemsWithFolders": "{{count}} 항목을 영구적으로 삭제하시겠습니까? 폴더와 그 내용물이 모두 포함됩니다.",
"confirmDeleteFolder": "폴더 \"{{name}}\"와 그 안에 있는 모든 내용을 영구적으로 삭제하시겠습니까?", "confirmDeleteFolder": "폴더 \"{{name}}\"와 그 안 모든 내용을 영구적으로 삭제하시겠습니까?",
"deleteDirectoryWarning": "이렇게 하면 폴더와 그 안에 있는 모든 내용이 삭제됩니다.", "deleteDirectoryWarning": "이렇게 하면 폴더와 그 안에 있는 모든 내용이 삭제됩니다.",
"actionCannotBeUndone": "이 작업은 되돌릴 수 없습니다.", "actionCannotBeUndone": "이 작업은 되돌릴 수 없습니다.",
"permanentDeleteWarning": "이 작업은 되돌릴 수 없습니다. 해당 항목은 서버에서 영구적으로 삭제됩니다.", "permanentDeleteWarning": "이 작업은 되돌릴 수 없습니다. 해당 항목은 서버에서 영구적으로 삭제됩니다.",
@@ -1430,9 +1430,9 @@
"directories": "디렉토리", "directories": "디렉토리",
"removedFromRecentFiles": "최근 파일에서 \"{{name}}\"를 제거했습니다.", "removedFromRecentFiles": "최근 파일에서 \"{{name}}\"를 제거했습니다.",
"removeFailed": "제거 실패", "removeFailed": "제거 실패",
"unpinnedSuccessfully": "고정 해제됨 \"{{name}}\" 성공적으로", "unpinnedSuccessfully": "\"{{name}}\" 고정 해제 성공",
"unpinFailed": "핀 해제 실패", "unpinFailed": "핀 해제 실패",
"removedShortcut": "바로가기 \"{{name}}\" 제거했습니다.", "removedShortcut": "바로가기 \"{{name}}\" 제거했습니다.",
"removeShortcutFailed": "바로가기 제거 실패", "removeShortcutFailed": "바로가기 제거 실패",
"clearedAllRecentFiles": "최근 파일을 모두 삭제했습니다.", "clearedAllRecentFiles": "최근 파일을 모두 삭제했습니다.",
"clearFailed": "지우기 실패", "clearFailed": "지우기 실패",
@@ -1440,16 +1440,16 @@
"clearAllRecentFiles": "최근 파일을 모두 삭제합니다.", "clearAllRecentFiles": "최근 파일을 모두 삭제합니다.",
"unpinFile": "파일 고정 해제", "unpinFile": "파일 고정 해제",
"removeShortcut": "바로가기 제거", "removeShortcut": "바로가기 제거",
"saveFilesToSystem": "{{count}}개의 파일을 다음과 같이 저장하세요...", "saveFilesToSystem": "{{count}} 파일을 다음과 같이 저장하세요...",
"pinFile": "핀 파일", "pinFile": "핀 파일",
"addToShortcuts": "바로가기에 추가", "addToShortcuts": "바로가기에 추가",
"downloadToDefaultLocation": "기본 위치로 다운로드", "downloadToDefaultLocation": "기본 위치로 다운로드",
"pasteFailed": "붙여넣기 실패", "pasteFailed": "붙여넣기 실패",
"noUndoableActions": "되돌릴 수 없는 작업", "noUndoableActions": "되돌릴 수 없는 작업",
"undoCopySuccess": "실행 취소된 복사 작업: 복사된 파일 {{count}}개가 삭제되었습니다.", "undoCopySuccess": "실행 취소된 복사 작업: {{count}} 개의 복사된 파일이 삭제되었습니다.",
"undoCopyFailedDelete": "실행 취소 실패: 복사된 파일을 삭제할 수 없습니다.", "undoCopyFailedDelete": "실행 취소 실패: 복사된 파일을 삭제할 수 없습니다.",
"undoCopyFailedNoInfo": "실행 취소 실패: 복사된 파일 정보를 찾을 수 없습니다.", "undoCopyFailedNoInfo": "실행 취소 실패: 복사된 파일 정보를 찾을 수 없습니다.",
"undoMoveSuccess": "이동 취소 작업: {{count}}개의 파일을 원래 위치로 되돌렸습니다.", "undoMoveSuccess": "이동 취소 작업: {{count}} 파일을 원래 위치로 되돌렸습니다.",
"undoMoveFailedMove": "실행 취소 실패: 파일을 되돌릴 수 없습니다.", "undoMoveFailedMove": "실행 취소 실패: 파일을 되돌릴 수 없습니다.",
"undoMoveFailedNoInfo": "실행 취소 실패: 이동된 파일 정보를 찾을 수 없습니다.", "undoMoveFailedNoInfo": "실행 취소 실패: 이동된 파일 정보를 찾을 수 없습니다.",
"undoDeleteNotSupported": "삭제 작업은 되돌릴 수 없습니다. 파일이 서버에서 영구적으로 삭제되었습니다.", "undoDeleteNotSupported": "삭제 작업은 되돌릴 수 없습니다. 파일이 서버에서 영구적으로 삭제되었습니다.",
@@ -1491,8 +1491,8 @@
"unknownSize": "크기 미상", "unknownSize": "크기 미상",
"fileIsEmpty": "파일이 비어 있습니다", "fileIsEmpty": "파일이 비어 있습니다",
"largeFileWarning": "대용량 파일 경고", "largeFileWarning": "대용량 파일 경고",
"largeFileWarningDesc": "이 파일의 크기는 {{size}}이므로 텍스트로 열면 성능 문제가 발생할 수 있습니다.", "largeFileWarningDesc": "이 파일의 크기는 {{size}} 이므로 텍스트 모드로 열면 성능 문제가 발생할 수 있습니다.",
"fileNotFoundAndRemoved": "파일 \"{{name}}\"을 찾을 수 없어 최근/고정된 파일 목록에서 제거되었습니다.", "fileNotFoundAndRemoved": "파일 \"{{name}}\"을(를) 찾을 수 없어 최근/고정된 파일 목록에서 제거되었습니다.",
"failedToLoadFile": "파일 로드 실패: {{error}}", "failedToLoadFile": "파일 로드 실패: {{error}}",
"serverErrorOccurred": "서버 오류가 발생했습니다. 나중에 다시 시도해 주세요.", "serverErrorOccurred": "서버 오류가 발생했습니다. 나중에 다시 시도해 주세요.",
"autoSaveFailed": "자동 저장 실패", "autoSaveFailed": "자동 저장 실패",
@@ -1504,22 +1504,22 @@
"dragFailed": "드래그 작업이 실패했습니다.", "dragFailed": "드래그 작업이 실패했습니다.",
"filePinnedSuccessfully": "파일 \"{{name}}\"이 성공적으로 고정되었습니다.", "filePinnedSuccessfully": "파일 \"{{name}}\"이 성공적으로 고정되었습니다.",
"pinFileFailed": "파일 고정 실패", "pinFileFailed": "파일 고정 실패",
"fileUnpinnedSuccessfully": "파일 \"{{name}}\"의 고정 해제가 성공적으로 완료되었습니다.", "fileUnpinnedSuccessfully": "파일 \"{{name}}\" 성공적으로 고정 해제되었습니다.",
"unpinFileFailed": "파일 고정 해제에 실패했습니다.", "unpinFileFailed": "파일 고정 해제에 실패했습니다.",
"shortcutAddedSuccessfully": "폴더 바로가기 \"{{name}}\"가 성공적으로 추가되었습니다.", "shortcutAddedSuccessfully": "폴더 바로가기 \"{{name}}\"가 성공적으로 추가되었습니다.",
"addShortcutFailed": "바로가기 추가에 실패했습니다", "addShortcutFailed": "바로가기 추가에 실패했습니다",
"operationCompletedSuccessfully": "{{operation}} {{count}} 항목이 성공적으로 완료되었습니다.", "operationCompletedSuccessfully": "{{operation}} {{count}} 항목이 성공적으로 완료되었습니다",
"operationCompleted": "{{operation}} {{count}}", "operationCompleted": "{{operation}} {{count}} 항목",
"downloadFileSuccess": "파일 {{name}}이 성공적으로 다운로드되었습니다.", "downloadFileSuccess": "파일 {{name}} 이 성공적으로 다운로드되었습니다.",
"downloadFileFailed": "다운로드 실패", "downloadFileFailed": "다운로드 실패",
"moveTo": "{{name}}로 이동", "moveTo": "{{name}}로 이동",
"diffCompareWith": "{{name}}과 비교", "diffCompareWith": "{{name}}와 차이점을 비교합니다.",
"dragOutsideToDownload": "다운로드하려면 창 으로 드래그하세요({{count}} 파일)", "dragOutsideToDownload": "다운로드하려면 창 바깥쪽으로 드래그하세요({{count}} 파일).",
"newFolderDefault": "새 폴더", "newFolderDefault": "새 폴더",
"newFileDefault": "NewFile.txt", "newFileDefault": "NewFile.txt",
"successfullyMovedItems": "{{count}}개의 항목을 {{target}}로 성공적으로 이동했습니다.", "successfullyMovedItems": "{{count}} 항목을 {{target}}로 성공적으로 이동했습니다.",
"move": "이동하다", "move": "이동하다",
"searchInFile": "파일 검색(Ctrl+F)", "searchInFile": "파일에서 검색(Ctrl+F)",
"showKeyboardShortcuts": "키보드 단축키 표시", "showKeyboardShortcuts": "키보드 단축키 표시",
"startWritingMarkdown": "마크다운 콘텐츠 작성을 시작하세요...", "startWritingMarkdown": "마크다운 콘텐츠 작성을 시작하세요...",
"loadingFileComparison": "파일 비교 로딩 중...", "loadingFileComparison": "파일 비교 로딩 중...",
@@ -1529,7 +1529,7 @@
"inline": "인라인", "inline": "인라인",
"fileComparison": "파일 비교: {{file1}} vs {{file2}}", "fileComparison": "파일 비교: {{file1}} vs {{file2}}",
"fileTooLarge": "파일 크기가 너무 큽니다: {{error}}", "fileTooLarge": "파일 크기가 너무 큽니다: {{error}}",
"sshConnectionFailed": "SSH 연결에 실패했습니다. {{name}}({{ip}}:{{port}})에 대한 연결을 확인하십시오.", "sshConnectionFailed": "SSH 연결에 실패했습니다. {{name}} ({{ip}}:{{port}})에 대한 연결을 확인하십시오.",
"loadFileFailed": "파일 로드 실패: {{error}}", "loadFileFailed": "파일 로드 실패: {{error}}",
"connectedSuccessfully": "성공적으로 연결되었습니다", "connectedSuccessfully": "성공적으로 연결되었습니다",
"totpVerificationFailed": "TOTP 인증 실패", "totpVerificationFailed": "TOTP 인증 실패",
@@ -1573,10 +1573,10 @@
"disconnect": "연결을 끊으세요", "disconnect": "연결을 끊으세요",
"cancel": "취소", "cancel": "취소",
"port": "포트", "port": "포트",
"attempt": "{{current}} 시도 {{max}}", "attempt": "{{max}}의 {{current}} 시도",
"nextRetryIn": "다음 재시도까지 {{seconds}}초 소요", "nextRetryIn": "다음 재시도 {{seconds}} 초",
"checkDockerLogs": "오류 원인을 확인하려면 Docker 로그를 확인하고, 참여하세요.", "checkDockerLogs": "오류 원인을 확인하려면 Docker 로그를 확인하고, 참여하세요.",
"orCreate": "또는 생성하다", "orCreate": "또는 생성 ",
"noTunnelConnections": "구성된 터널 연결이 없습니다.", "noTunnelConnections": "구성된 터널 연결이 없습니다.",
"tunnelConnections": "터널 연결", "tunnelConnections": "터널 연결",
"addTunnel": "터널 추가", "addTunnel": "터널 추가",
@@ -1586,7 +1586,7 @@
"localPort": "현지 항구", "localPort": "현지 항구",
"remoteHost": "원격 호스트", "remoteHost": "원격 호스트",
"remotePort": "원격 포트", "remotePort": "원격 포트",
"autoStart": "자동 시", "autoStart": "자동 시",
"status": "상태", "status": "상태",
"active": "활동적인", "active": "활동적인",
"inactive": "비활성화됨", "inactive": "비활성화됨",
@@ -1650,7 +1650,7 @@
"totpInvalidCode": "잘못된 인증 코드입니다.", "totpInvalidCode": "잘못된 인증 코드입니다.",
"totpCancelled": "데이터 수집이 취소되었습니다", "totpCancelled": "데이터 수집이 취소되었습니다",
"authenticationFailed": "인증 실패", "authenticationFailed": "인증 실패",
"noneAuthNotSupported": "서버 통계는 'none' 인증 유형을 지원하지 않습니다.", "noneAuthNotSupported": "서버 통계는 '없음' 인증 유형을 지원하지 않습니다.",
"load": "짐", "load": "짐",
"editLayout": "레이아웃 편집", "editLayout": "레이아웃 편집",
"cancelEdit": "취소", "cancelEdit": "취소",
@@ -1678,11 +1678,11 @@
"noRecentLoginData": "최근 로그인 데이터가 없습니다.", "noRecentLoginData": "최근 로그인 데이터가 없습니다.",
"from": "~에서", "from": "~에서",
"quickActions": "빠른 조치", "quickActions": "빠른 조치",
"executeQuickAction": "{{name}} 실행하세요", "executeQuickAction": "{{name}} 실행하세요",
"executingQuickAction": "{{name}} 실행 중...", "executingQuickAction": "{{name}}실행 중...",
"quickActionSuccess": "{{name}} 성공적으로 완료되었습니다.", "quickActionSuccess": "{{name}} 성공적으로 완료되었습니다",
"quickActionFailed": "{{name}} 실패", "quickActionFailed": "{{name}} 실패",
"quickActionError": "{{name}} 실행에 실패했습니다." "quickActionError": "{{name}}실행에 실패했습니다."
}, },
"auth": { "auth": {
"tagline": "SSH 서버 관리자", "tagline": "SSH 서버 관리자",
@@ -1835,7 +1835,7 @@
"updateError": "업데이트에 실패했습니다", "updateError": "업데이트에 실패했습니다",
"copySuccess": "클립보드에 복사됨", "copySuccess": "클립보드에 복사됨",
"copyError": "복사에 실패했습니다", "copyError": "복사에 실패했습니다",
"copiedToClipboard": "{{item}} 클립보드에 복사되었습니다.", "copiedToClipboard": "{{item}} 클립보드에 복사",
"connectionEstablished": "연결이 설정되었습니다.", "connectionEstablished": "연결이 설정되었습니다.",
"connectionClosed": "연결이 종료되었습니다", "connectionClosed": "연결이 종료되었습니다",
"reconnecting": "다시 연결 중...", "reconnecting": "다시 연결 중...",
@@ -1880,7 +1880,7 @@
"languageLocalization": "언어 및 현지화", "languageLocalization": "언어 및 현지화",
"fileManagerSettings": "파일 관리자", "fileManagerSettings": "파일 관리자",
"terminalSettings": "단말기", "terminalSettings": "단말기",
"hostSidebarSettings": "호스트 & 사이드바", "hostSidebarSettings": "호스트 사이드바",
"snippetsSettings": "짧은 발췌", "snippetsSettings": "짧은 발췌",
"currentPassword": "현재 비밀번호", "currentPassword": "현재 비밀번호",
"passwordChangedSuccess": "비밀번호가 변경되었습니다! 다시 로그인해 주세요.", "passwordChangedSuccess": "비밀번호가 변경되었습니다! 다시 로그인해 주세요.",
@@ -1942,7 +1942,7 @@
"socks5Username": "프록시 사용자 이름", "socks5Username": "프록시 사용자 이름",
"socks5Password": "프록시 비밀번호", "socks5Password": "프록시 비밀번호",
"socks5PresetName": "예: 업무용 VPN 체인", "socks5PresetName": "예: 업무용 VPN 체인",
"socks5PresetDescription": "예: 업 서버 접속 프록시 체인", "socks5PresetDescription": "예: 업 서버 접속을 위한 프록시 체인",
"moshCommand": "mosh 사용자@서버", "moshCommand": "mosh 사용자@서버",
"defaultPort": "22", "defaultPort": "22",
"defaultEndpointPort": "224", "defaultEndpointPort": "224",
@@ -1955,9 +1955,9 @@
"passwordRequired": "비밀번호가 필요합니다", "passwordRequired": "비밀번호가 필요합니다",
"failedToDeleteAccount": "계정 삭제에 실패했습니다", "failedToDeleteAccount": "계정 삭제에 실패했습니다",
"failedToMakeUserAdmin": "사용자를 관리자로 만드는 데 실패했습니다.", "failedToMakeUserAdmin": "사용자를 관리자로 만드는 데 실패했습니다.",
"userIsNowAdmin": "사용자 {{username}}님이 이제 관리자입니다.", "userIsNowAdmin": "사용자 {{username}} 님이 이제 관리자입니다.",
"removeAdminConfirm": "{{username}}에서 관리자 상태를 제거하시겠습니까?", "removeAdminConfirm": "{{username}}에서 관리자 권한을 제거하시겠습니까?",
"deleteUserConfirm": "사용자 {{username}} 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", "deleteUserConfirm": "사용자 {{username}} 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"deleteAccount": "계정 삭제", "deleteAccount": "계정 삭제",
"closeDeleteAccount": "닫기 계정 삭제", "closeDeleteAccount": "닫기 계정 삭제",
"deleteAccountWarning": "이 작업은 되돌릴 수 없습니다. 계정과 관련된 모든 데이터가 영구적으로 삭제됩니다.", "deleteAccountWarning": "이 작업은 되돌릴 수 없습니다. 계정과 관련된 모든 데이터가 영구적으로 삭제됩니다.",
@@ -2142,15 +2142,15 @@
"createTempUser": "임시 사용자 생성", "createTempUser": "임시 사용자 생성",
"createTempUserDesc": "자격 증명을 공유하는 대신 서버에 제한된 사용자 계정을 생성합니다. sudo 권한이 필요하며, 가장 안전한 옵션입니다.", "createTempUserDesc": "자격 증명을 공유하는 대신 서버에 제한된 사용자 계정을 생성합니다. sudo 권한이 필요하며, 가장 안전한 옵션입니다.",
"expiresAt": "만료일", "expiresAt": "만료일",
"expiresIn": "{{hours}}시간 후에 만료됩니다", "expiresIn": "{{hours}} 시간 후에 만료됩니다",
"expired": "만료됨", "expired": "만료됨",
"grantedBy": "승인자:", "grantedBy": "승인자:",
"accessLevel": "접근 수준", "accessLevel": "접근 수준",
"lastAccessed": "최근 접속일", "lastAccessed": "최근 접속일",
"accessCount": "접근 횟수", "accessCount": "접근 횟수",
"revokeAccess": "접근 권한 취소", "revokeAccess": "접근 권한 취소",
"confirmRevokeAccess": "{{username}}에 대한 액세스 권한을 취소하시겠습니까?", "confirmRevokeAccess": "{{username}}에 대한 접근 권한을 취소하시겠습니까?",
"hostSharedSuccessfully": "호스트가 {{username}} 성공적으로 공유되었습니다.", "hostSharedSuccessfully": "호스트가 {{username}} 성공적으로 공유되었습니다.",
"hostAccessUpdated": "호스트 액세스가 업데이트되었습니다.", "hostAccessUpdated": "호스트 액세스가 업데이트되었습니다.",
"failedToShareHost": "호스트 공유에 실패했습니다", "failedToShareHost": "호스트 공유에 실패했습니다",
"accessRevokedSuccessfully": "접근 권한이 성공적으로 취소되었습니다.", "accessRevokedSuccessfully": "접근 권한이 성공적으로 취소되었습니다.",
@@ -2165,11 +2165,11 @@
"noAccessGranted": "이 호스트에 대한 액세스 권한이 부여되지 않았습니다.", "noAccessGranted": "이 호스트에 대한 액세스 권한이 부여되지 않았습니다.",
"noAccessGrantedMessage": "아직 이 호스트에 대한 접근 권한이 부여된 사용자는 없습니다.", "noAccessGrantedMessage": "아직 이 호스트에 대한 접근 권한이 부여된 사용자는 없습니다.",
"manageAccessFor": "액세스 관리", "manageAccessFor": "액세스 관리",
"totalAccessRecords": "{{count}} 액세스 레코드", "totalAccessRecords": "{{count}} 액세스 레코드(들)",
"neverAccessed": "절대", "neverAccessed": "절대",
"timesAccessed": "{{count}}", "timesAccessed": "{{count}} 시간(초)",
"daysRemaining": "{{days}}일", "daysRemaining": "{{days}} 일",
"hoursRemaining": "{{hours}}시간", "hoursRemaining": "{{hours}} 시간(초)",
"failedToFetchAccessList": "접근 권한 목록을 가져오는 데 실패했습니다.", "failedToFetchAccessList": "접근 권한 목록을 가져오는 데 실패했습니다.",
"currentAccess": "현재 액세스", "currentAccess": "현재 액세스",
"securityWarning": "보안 경고", "securityWarning": "보안 경고",
@@ -2184,9 +2184,9 @@
"permissions": "권한", "permissions": "권한",
"systemRole": "시스템 역할", "systemRole": "시스템 역할",
"customRole": "사용자 지정 역할", "customRole": "사용자 지정 역할",
"roleAssignedSuccessfully": "{{username}}에 역할이 성공적으로 할당되었습니다.", "roleAssignedSuccessfully": "{{username}} 에 역할이 성공적으로 할당되었습니다.",
"failedToAssignRole": "역할 할당에 실패했습니다", "failedToAssignRole": "역할 할당에 실패했습니다",
"roleRemovedSuccessfully": "{{username}}에서 역할이 성공적으로 제거되었습니다.", "roleRemovedSuccessfully": "{{username}} 에서 역할이 성공적으로 제거되었습니다.",
"failedToRemoveRole": "역할 제거에 실패했습니다", "failedToRemoveRole": "역할 제거에 실패했습니다",
"cannotRemoveSystemRole": "시스템 역할을 제거할 수 없습니다", "cannotRemoveSystemRole": "시스템 역할을 제거할 수 없습니다",
"cannotShareWithSelf": "본인과 호스트를 공유할 수 없습니다.", "cannotShareWithSelf": "본인과 호스트를 공유할 수 없습니다.",
@@ -2214,7 +2214,7 @@
"terminateSession": "세션 종료", "terminateSession": "세션 종료",
"sessionTerminated": "호스트 소유자에 의해 세션이 종료되었습니다.", "sessionTerminated": "호스트 소유자에 의해 세션이 종료되었습니다.",
"sharedAccessExpired": "이 호스트에 대한 공유 액세스 권한이 만료되었습니다.", "sharedAccessExpired": "이 호스트에 대한 공유 액세스 권한이 만료되었습니다.",
"sharedAccessExpiresIn": "공유 액세스는 {{hours}}시간 후에 만료됩니다.", "sharedAccessExpiresIn": "공유 액세스는 {{hours}} 시간 후에 만료됩니다.",
"roles": { "roles": {
"label": "역할", "label": "역할",
"admin": "관리자", "admin": "관리자",
@@ -2249,7 +2249,7 @@
"displayNamePlaceholder": "개발자", "displayNamePlaceholder": "개발자",
"descriptionPlaceholder": "소프트웨어 개발자 및 엔지니어", "descriptionPlaceholder": "소프트웨어 개발자 및 엔지니어",
"confirmDeleteRole": "역할 삭제", "confirmDeleteRole": "역할 삭제",
"confirmDeleteRoleDescription": "역할 '{{name}}'을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", "confirmDeleteRoleDescription": "'{{name}}' 역할을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"confirmRemoveRole": "역할 제거", "confirmRemoveRole": "역할 제거",
"confirmRemoveRoleDescription": "이 사용자에게서 해당 역할을 제거하시겠습니까?", "confirmRemoveRoleDescription": "이 사용자에게서 해당 역할을 제거하시겠습니까?",
"editRoleDescription": "역할 정보 업데이트", "editRoleDescription": "역할 정보 업데이트",
@@ -2310,16 +2310,16 @@
"errorCode": "오류 코드: {{code}}", "errorCode": "오류 코드: {{code}}",
"version": "도커 {{version}}", "version": "도커 {{version}}",
"containerStarted": "컨테이너 {{name}} 시작됨", "containerStarted": "컨테이너 {{name}} 시작됨",
"failedToStartContainer": "컨테이너 {{name}} 시작에 실패했습니다.", "failedToStartContainer": "컨테이너 {{name}}시작에 실패했습니다.",
"containerStopped": "컨테이너 {{name}}가 중지되었습니다.", "containerStopped": "컨테이너 {{name}} 가 중지되었습니다.",
"failedToStopContainer": "컨테이너 {{name}}를 중지하는 데 실패했습니다.", "failedToStopContainer": "컨테이너 {{name}}를 중지하는 데 실패했습니다.",
"containerRestarted": "컨테이너 {{name}}가 재시작되었습니다.", "containerRestarted": "컨테이너 {{name}} 가 재시작되었습니다.",
"failedToRestartContainer": "컨테이너 {{name}} 재시작에 실패했습니다.", "failedToRestartContainer": "컨테이너 {{name}}재시작에 실패했습니다.",
"containerPaused": "컨테이너 {{name}} 일시 중지됨", "containerPaused": "컨테이너 {{name}} 일시 중지됨",
"containerUnpaused": "컨테이너 {{name}} 일시 중지 해제됨", "containerUnpaused": "컨테이너 {{name}} 일시 중지 해제됨",
"failedToTogglePauseContainer": "컨테이너 {{name}}의 일시 정지 상태를 전환하는 데 실패했습니다.", "failedToTogglePauseContainer": "컨테이너 {{name}}의 일시 정지 상태를 전환하는 데 실패했습니다.",
"containerRemoved": "컨테이너 {{name}}가 제거되었습니다.", "containerRemoved": "컨테이너 {{name}} 가 제거되었습니다.",
"failedToRemoveContainer": "컨테이너 {{name}} 제거하는 데 실패했습니다.", "failedToRemoveContainer": "컨테이너 {{name}} 제거하는 데 실패했습니다.",
"image": "영상", "image": "영상",
"idLabel": "ID", "idLabel": "ID",
"ports": "항구", "ports": "항구",
@@ -2399,4 +2399,4 @@
"switchToLight": "조명으로 전환", "switchToLight": "조명으로 전환",
"switchToDark": "어둡게 전환" "switchToDark": "어둡게 전환"
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -39,11 +39,11 @@
"noCredentials": "ไม่มีข้อมูลประจำตัว", "noCredentials": "ไม่มีข้อมูลประจำตัว",
"noCredentialsMessage": "คุณยังไม่ได้เพิ่มข้อมูลประจำตัวใดๆ คลิก \"เพิ่มข้อมูลประจำตัว\" เพื่อเริ่มต้น", "noCredentialsMessage": "คุณยังไม่ได้เพิ่มข้อมูลประจำตัวใดๆ คลิก \"เพิ่มข้อมูลประจำตัว\" เพื่อเริ่มต้น",
"sshCredentials": "ข้อมูลรับรอง SSH", "sshCredentials": "ข้อมูลรับรอง SSH",
"credentialsCount": "ข้อมูลประจำตัว {{count}}", "credentialsCount": "{{count}} ข้อมูลประจำตัว",
"refresh": "รีเฟรช", "refresh": "รีเฟรช",
"passwordRequired": "ต้องใส่รหัสผ่าน", "passwordRequired": "ต้องใส่รหัสผ่าน",
"sshKeyRequired": "จำเป็นต้องใช้คีย์ SSH", "sshKeyRequired": "จำเป็นต้องใช้คีย์ SSH",
"credentialAddedSuccessfully": "ข้อมูลประจำตัว \"{{name}}\" ถูกเพิ่มสำเร็จแล้ว", "credentialAddedSuccessfully": "เพิ่มข้อมูลประจำตัว \"{{name}}\" สำเร็จแล้ว",
"general": "ทั่วไป", "general": "ทั่วไป",
"description": "คำอธิบาย", "description": "คำอธิบาย",
"folder": "โฟลเดอร์", "folder": "โฟลเดอร์",
@@ -114,7 +114,7 @@
"usage": "การใช้งาน", "usage": "การใช้งาน",
"securityDetails": "รายละเอียดด้านความปลอดภัย", "securityDetails": "รายละเอียดด้านความปลอดภัย",
"securityDetailsDescription": "ดูข้อมูลประจำตัวที่เข้ารหัส", "securityDetailsDescription": "ดูข้อมูลประจำตัวที่เข้ารหัส",
"credentialSecured": "ข้อมูลประจำตัวได้รับการรักษาความปลอดภัยแล้ว", "credentialSecured": "ยืนยันตัวตนเรียบร้อยแล้ว",
"credentialSecuredDescription": "ข้อมูลสำคัญทั้งหมดจะถูกเข้ารหัสด้วย AES-256", "credentialSecuredDescription": "ข้อมูลสำคัญทั้งหมดจะถูกเข้ารหัสด้วย AES-256",
"passwordAuthentication": "การตรวจสอบรหัสผ่าน", "passwordAuthentication": "การตรวจสอบรหัสผ่าน",
"keyAuthentication": "การตรวจสอบสิทธิ์ด้วยคีย์", "keyAuthentication": "การตรวจสอบสิทธิ์ด้วยคีย์",
@@ -128,7 +128,7 @@
"created": "สร้าง", "created": "สร้าง",
"lastModified": "แก้ไขล่าสุด", "lastModified": "แก้ไขล่าสุด",
"usageStatistics": "สถิติการใช้งาน", "usageStatistics": "สถิติการใช้งาน",
"copiedToClipboard": "{{field}} คัดลอกไปยังคลิปบอร์ด", "copiedToClipboard": "{{field}} คัดลอกไปยังคลิปบอร์ดแล้ว",
"failedToCopy": "ไม่สามารถคัดลอกไปยังคลิปบอร์ดได้", "failedToCopy": "ไม่สามารถคัดลอกไปยังคลิปบอร์ดได้",
"sshKey": "คีย์ SSH", "sshKey": "คีย์ SSH",
"createCredentialDescription": "สร้างข้อมูลรับรอง SSH ใหม่สำหรับการเข้าถึงที่ปลอดภัย", "createCredentialDescription": "สร้างข้อมูลรับรอง SSH ใหม่สำหรับการเข้าถึงที่ปลอดภัย",
@@ -136,7 +136,7 @@
"listView": "รายการ", "listView": "รายการ",
"folderView": "โฟลเดอร์", "folderView": "โฟลเดอร์",
"unknownCredential": "ไม่ทราบ", "unknownCredential": "ไม่ทราบ",
"confirmRemoveFromFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\" ออกจากโฟลเดอร์ \"{{folder}}\" ข้อมูลประจำตัวจะถูกย้ายไปยัง \"ไม่มีหมวดหมู่\"", "confirmRemoveFromFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\" ออกจากโฟลเดอร์ \"{{folder}}\"? ข้อมูลรับรองจะถูกย้ายไปยัง \"ไม่มีหมวดหมู่\"",
"removedFromFolder": "ข้อมูลประจำตัว \"{{name}}\" ถูกลบออกจากโฟลเดอร์เรียบร้อยแล้ว", "removedFromFolder": "ข้อมูลประจำตัว \"{{name}}\" ถูกลบออกจากโฟลเดอร์เรียบร้อยแล้ว",
"failedToRemoveFromFolder": "ไม่สามารถลบข้อมูลประจำตัวออกจากโฟลเดอร์ได้", "failedToRemoveFromFolder": "ไม่สามารถลบข้อมูลประจำตัวออกจากโฟลเดอร์ได้",
"folderRenamed": "เปลี่ยนชื่อโฟลเดอร์ \"{{oldName}}\" เป็น \"{{newName}}\" สำเร็จแล้ว", "folderRenamed": "เปลี่ยนชื่อโฟลเดอร์ \"{{oldName}}\" เป็น \"{{newName}}\" สำเร็จแล้ว",
@@ -166,7 +166,7 @@
"keyTypeDsa": "ดีเอสเอ (เอสเอช)", "keyTypeDsa": "ดีเอสเอ (เอสเอช)",
"keyTypeRsaSha256": "อาร์เอสเอ-เอสเอชเอ2-256", "keyTypeRsaSha256": "อาร์เอสเอ-เอสเอชเอ2-256",
"keyTypeRsaSha512": "อาร์เอสเอ-เอสเอชเอ2-512", "keyTypeRsaSha512": "อาร์เอสเอ-เอสเอชเอ2-512",
"keyPairGeneratedSuccessfully": "สร้างคู่คีย์ {{keyType}} สำเร็จแล้ว", "keyPairGeneratedSuccessfully": "{{keyType}} สร้างคู่คีย์สำเร็จแล้ว",
"failedToGenerateKeyPair": "ไม่สามารถสร้างคู่คีย์ได้", "failedToGenerateKeyPair": "ไม่สามารถสร้างคู่คีย์ได้",
"generateKeyPairNote": "สร้างคู่คีย์ SSH ใหม่โดยตรง ซึ่งจะแทนที่คีย์ที่มีอยู่เดิมในรูปแบบเดิม", "generateKeyPairNote": "สร้างคู่คีย์ SSH ใหม่โดยตรง ซึ่งจะแทนที่คีย์ที่มีอยู่เดิมในรูปแบบเดิม",
"invalidKey": "คีย์ไม่ถูกต้อง", "invalidKey": "คีย์ไม่ถูกต้อง",
@@ -187,10 +187,10 @@
"dragIndicator": { "dragIndicator": {
"error": "ข้อผิดพลาด: {{error}}", "error": "ข้อผิดพลาด: {{error}}",
"dragging": "การลาก {{fileName}}", "dragging": "การลาก {{fileName}}",
"preparing": "การเตรียม {{fileName}}", "preparing": "กำลังเตรียม {{fileName}}",
"readySingle": "พร้อมดาวน์โหลด {{fileName}}", "readySingle": "พร้อมดาวน์โหลด {{fileName}}",
"readyMultiple": "พร้อมดาวน์โหลดไฟล์ {{count}} ไฟล์", "readyMultiple": "พร้อมดาวน์โหลดไฟล์ {{count}} แล้ว",
"batchDrag": "ลากไฟล์ {{count}} ไฟล์ไปยังเดสก์ท็อป", "batchDrag": "ลากไฟล์ {{count}} ไปยังเดสก์ท็อป",
"dragToDesktop": "ลากไปที่เดสก์ท็อป", "dragToDesktop": "ลากไปที่เดสก์ท็อป",
"canDragAnywhere": "คุณสามารถลากไฟล์ไปที่ใดก็ได้บนเดสก์ท็อปของคุณ" "canDragAnywhere": "คุณสามารถลากไฟล์ไปที่ใดก็ได้บนเดสก์ท็อปของคุณ"
}, },
@@ -202,7 +202,7 @@
"stopKeyRecording": "หยุดการบันทึกคีย์", "stopKeyRecording": "หยุดการบันทึกคีย์",
"selectTerminals": "เลือกเทอร์มินัล:", "selectTerminals": "เลือกเทอร์มินัล:",
"typeCommands": "พิมพ์คำสั่ง (รองรับทุกปุ่ม):", "typeCommands": "พิมพ์คำสั่ง (รองรับทุกปุ่ม):",
"commandsWillBeSent": "คำสั่งจะถูกส่งไปยังเทอร์มินัลที่เลือกไว้ {{count}} เครื่อง", "commandsWillBeSent": "คำสั่งจะถูกส่งไปยังเทอร์มินัลที่เลือก {{count}} เครื่อง",
"settings": "การตั้งค่า", "settings": "การตั้งค่า",
"enableRightClickCopyPaste": "เปิดใช้งานการคัดลอก/วางโดยคลิกขวา", "enableRightClickCopyPaste": "เปิดใช้งานการคัดลอก/วางโดยคลิกขวา",
"shareIdeas": "มีไอเดียเกี่ยวกับสิ่งที่จะเกิดขึ้นต่อไปสำหรับเครื่องมือ SSH บ้างไหม? แชร์ไอเดียของคุณได้ที่นี่", "shareIdeas": "มีไอเดียเกี่ยวกับสิ่งที่จะเกิดขึ้นต่อไปสำหรับเครื่องมือ SSH บ้างไหม? แชร์ไอเดียของคุณได้ที่นี่",
@@ -248,7 +248,7 @@
"reorderSameFolder": "สามารถจัดเรียงลำดับข้อความใหม่ได้เฉพาะภายในโฟลเดอร์เดียวกันเท่านั้น", "reorderSameFolder": "สามารถจัดเรียงลำดับข้อความใหม่ได้เฉพาะภายในโฟลเดอร์เดียวกันเท่านั้น",
"reorderSuccess": "เรียงลำดับส่วนย่อยใหม่สำเร็จแล้ว", "reorderSuccess": "เรียงลำดับส่วนย่อยใหม่สำเร็จแล้ว",
"reorderFailed": "ไม่สามารถเรียงลำดับส่วนย่อยใหม่ได้", "reorderFailed": "ไม่สามารถเรียงลำดับส่วนย่อยใหม่ได้",
"deleteFolderConfirm": "ลบโฟลเดอร์ \"{{name}}\" หรือไม่? โค้ดทั้งหมดจะถูกย้ายไปยังหมวดหมู่ที่ไม่มีการจัดหมวดหมู่", "deleteFolderConfirm": "ลบโฟลเดอร์ \"{{name}}\"? ข้อความย่อทั้งหมดจะถูกย้ายไปยังหมวดหมู่ที่ไม่มีการจัดหมวดหมู่",
"deleteFolderSuccess": "ลบโฟลเดอร์สำเร็จแล้ว", "deleteFolderSuccess": "ลบโฟลเดอร์สำเร็จแล้ว",
"deleteFolderFailed": "ไม่สามารถลบโฟลเดอร์ได้", "deleteFolderFailed": "ไม่สามารถลบโฟลเดอร์ได้",
"updateFolderSuccess": "อัปเดตโฟลเดอร์สำเร็จแล้ว", "updateFolderSuccess": "อัปเดตโฟลเดอร์สำเร็จแล้ว",
@@ -308,7 +308,7 @@
"cleared": "หน้าจอแบ่งครึ่งถูกเคลียร์แล้ว", "cleared": "หน้าจอแบ่งครึ่งถูกเคลียร์แล้ว",
"error": { "error": {
"noAssignments": "โปรดกำหนดแท็บอย่างน้อยหนึ่งแท็บให้กับเค้าโครง", "noAssignments": "โปรดกำหนดแท็บอย่างน้อยหนึ่งแท็บให้กับเค้าโครง",
"fillAllSlots": "โปรดกรอกข้อมูลในช่องทั้งหมด {{count}} ช่องก่อนสมัคร" "fillAllSlots": "กรุณากรอกข้อมูลในช่อง {{count}} ทั้งหมดก่อนสมัคร"
} }
}, },
"homepage": { "homepage": {
@@ -345,8 +345,8 @@
"upToDate": "แอปได้รับการอัปเดตแล้ว", "upToDate": "แอปได้รับการอัปเดตแล้ว",
"currentVersion": "คุณกำลังใช้งานเวอร์ชัน {{version}}", "currentVersion": "คุณกำลังใช้งานเวอร์ชัน {{version}}",
"updateAvailable": "มีการอัปเดตแล้ว", "updateAvailable": "มีการอัปเดตแล้ว",
"newVersionAvailable": "มีเวอร์ชันใหม่ให้ใช้งานแล้ว! คุณกำลังใช้งาน {{current}} อยู่ แต่มี {{latest}} ให้ใช้งานแล้ว", "newVersionAvailable": "มีเวอร์ชันใหม่ให้ใช้งานแล้ว! คุณกำลังใช้งาน {{current}}อยู่ แต่มี {{latest}} ให้ใช้งานแล้ว",
"releasedOn": "วางจำหน่ายเมื่อ {{date}}", "releasedOn": "เผยแพร่เมื่อ {{date}}",
"downloadUpdate": "ดาวน์โหลดการอัปเดต", "downloadUpdate": "ดาวน์โหลดการอัปเดต",
"dismiss": "อนุญาตให้ออกไป", "dismiss": "อนุญาตให้ออกไป",
"checking": "กำลังตรวจสอบการอัปเดต...", "checking": "กำลังตรวจสอบการอัปเดต...",
@@ -459,7 +459,7 @@
"passwordResetSuccess": "รีเซ็ตรหัสผ่านสำเร็จแล้ว! คุณสามารถเข้าสู่ระบบด้วยรหัสผ่านใหม่ของคุณได้แล้ว", "passwordResetSuccess": "รีเซ็ตรหัสผ่านสำเร็จแล้ว! คุณสามารถเข้าสู่ระบบด้วยรหัสผ่านใหม่ของคุณได้แล้ว",
"failedToInitiatePasswordReset": "ไม่สามารถเริ่มการรีเซ็ตรหัสผ่านได้", "failedToInitiatePasswordReset": "ไม่สามารถเริ่มการรีเซ็ตรหัสผ่านได้",
"failedToVerifyResetCode": "ไม่สามารถตรวจสอบรหัสรีเซ็ตได้", "failedToVerifyResetCode": "ไม่สามารถตรวจสอบรหัสรีเซ็ตได้",
"failedToCompletePasswordReset": "ไม่สามารถทำการรีเซ็ตรหัสผ่านให้เสร็จสมบูรณ์ได้", "failedToCompletePasswordReset": "การรีเซ็ตรหัสผ่านล้มเหลว",
"documentation": "เอกสารประกอบ", "documentation": "เอกสารประกอบ",
"retry": "ลองใหม่อีกครั้ง", "retry": "ลองใหม่อีกครั้ง",
"checking": "กำลังตรวจสอบ...", "checking": "กำลังตรวจสอบ...",
@@ -498,7 +498,7 @@
"userManagement": "การจัดการผู้ใช้", "userManagement": "การจัดการผู้ใช้",
"makeAdmin": "ตั้งค่าผู้ดูแลระบบ", "makeAdmin": "ตั้งค่าผู้ดูแลระบบ",
"removeAdmin": "ลบผู้ดูแลระบบ", "removeAdmin": "ลบผู้ดูแลระบบ",
"deleteUser": "ลบผู้ใช้ {{username}} แล้ว แต่ไม่สามารถยกเลิกได้", "deleteUser": "ลบผู้ใช้ {{username}}? ไม่สามารถยกเลิกได้",
"allowRegistration": "อนุญาตการลงทะเบียน", "allowRegistration": "อนุญาตการลงทะเบียน",
"oidcSettings": "การตั้งค่า OIDC", "oidcSettings": "การตั้งค่า OIDC",
"clientId": "รหัสลูกค้า", "clientId": "รหัสลูกค้า",
@@ -537,7 +537,7 @@
"userRegistration": "การลงทะเบียนผู้ใช้", "userRegistration": "การลงทะเบียนผู้ใช้",
"allowNewAccountRegistration": "อนุญาตให้ลงทะเบียนบัญชีใหม่", "allowNewAccountRegistration": "อนุญาตให้ลงทะเบียนบัญชีใหม่",
"allowPasswordLogin": "อนุญาตให้เข้าสู่ระบบด้วยชื่อผู้ใช้/รหัสผ่าน", "allowPasswordLogin": "อนุญาตให้เข้าสู่ระบบด้วยชื่อผู้ใช้/รหัสผ่าน",
"missingRequiredFields": "ช่องข้อมูลที่จำเป็นไม่ครบถ้วน: {{fields}}", "missingRequiredFields": "กรอกข้อมูลในช่องที่จำเป็นไม่ครบถ้วน: {{fields}}",
"oidcConfigurationUpdated": "การกำหนดค่า OIDC ได้รับการอัปเดตเรียบร้อยแล้ว!", "oidcConfigurationUpdated": "การกำหนดค่า OIDC ได้รับการอัปเดตเรียบร้อยแล้ว!",
"failedToFetchOidcConfig": "ไม่สามารถดึงข้อมูลการกำหนดค่า OIDC ได้", "failedToFetchOidcConfig": "ไม่สามารถดึงข้อมูลการกำหนดค่า OIDC ได้",
"failedToFetchRegistrationStatus": "ไม่สามารถดึงสถานะการลงทะเบียนได้", "failedToFetchRegistrationStatus": "ไม่สามารถดึงสถานะการลงทะเบียนได้",
@@ -549,7 +549,7 @@
"enterUsernameToMakeAdmin": "ป้อนชื่อผู้ใช้เพื่อเข้าเป็นผู้ดูแลระบบ", "enterUsernameToMakeAdmin": "ป้อนชื่อผู้ใช้เพื่อเข้าเป็นผู้ดูแลระบบ",
"userIsNowAdmin": "ผู้ใช้ {{username}} ตอนนี้เป็นผู้ดูแลระบบแล้ว", "userIsNowAdmin": "ผู้ใช้ {{username}} ตอนนี้เป็นผู้ดูแลระบบแล้ว",
"failedToMakeUserAdmin": "ไม่สามารถทำให้ผู้ใช้เป็นผู้ดูแลระบบได้", "failedToMakeUserAdmin": "ไม่สามารถทำให้ผู้ใช้เป็นผู้ดูแลระบบได้",
"removeAdminStatus": "ลบสถานะผู้ดูแลระบบออกจาก {{username}} หรือไม่?", "removeAdminStatus": "ลบสถานะผู้ดูแลระบบออกจาก {{username}}?",
"adminStatusRemoved": "สถานะผู้ดูแลระบบถูกลบออกจาก {{username}}", "adminStatusRemoved": "สถานะผู้ดูแลระบบถูกลบออกจาก {{username}}",
"failedToRemoveAdminStatus": "ไม่สามารถลบสถานะผู้ดูแลระบบได้", "failedToRemoveAdminStatus": "ไม่สามารถลบสถานะผู้ดูแลระบบได้",
"userDeletedSuccessfully": "ผู้ใช้ {{username}} ถูกลบสำเร็จแล้ว", "userDeletedSuccessfully": "ผู้ใช้ {{username}} ถูกลบสำเร็จแล้ว",
@@ -559,12 +559,12 @@
"sessionRevokedSuccessfully": "การยกเลิกเซสชันสำเร็จแล้ว", "sessionRevokedSuccessfully": "การยกเลิกเซสชันสำเร็จแล้ว",
"failedToRevokeSession": "ไม่สามารถยกเลิกเซสชันได้", "failedToRevokeSession": "ไม่สามารถยกเลิกเซสชันได้",
"confirmRevokeSession": "คุณแน่ใจหรือไม่ว่าต้องการยกเลิกเซสชั่นนี้?", "confirmRevokeSession": "คุณแน่ใจหรือไม่ว่าต้องการยกเลิกเซสชั่นนี้?",
"confirmRevokeAllSessions": "คุณแน่ใจหรือไม่ว่าต้องการยกเลิกการใช้งานทั้งหมดสำหรับผู้ใช้รายนี้?", "confirmRevokeAllSessions": "คุณแน่ใจหรือไม่ว่าต้องการยกเลิกเซสชันทั้งหมดสำหรับผู้ใช้รายนี้?",
"failedToRevokeSessions": "ไม่สามารถยกเลิกเซสชันได้", "failedToRevokeSessions": "ไม่สามารถยกเลิกเซสชันได้",
"sessionsRevokedSuccessfully": "การยกเลิกเซสชันสำเร็จแล้ว", "sessionsRevokedSuccessfully": "การยกเลิกเซสชันสำเร็จแล้ว",
"linkToPasswordAccount": "เชื่อมโยงไปยังบัญชีรหัสผ่าน", "linkToPasswordAccount": "เชื่อมโยงไปยังบัญชีรหัสผ่าน",
"linkOIDCDialogTitle": "เชื่อมโยงบัญชี OIDC กับบัญชีรหัสผ่าน", "linkOIDCDialogTitle": "เชื่อมโยงบัญชี OIDC กับบัญชีรหัสผ่าน",
"linkOIDCDialogDescription": "เชื่อมโยง {{username}} (ผู้ใช้ OIDC) กับบัญชีรหัสผ่านที่มีอยู่แล้ว ซึ่งจะทำให้สามารตรวจสอบสิทธิ์แบบสองทางสำหรับบัญชีรหัสผ่านได้", "linkOIDCDialogDescription": "เชื่อมโยง {{username}} (ผู้ใช้ OIDC) กับบัญชีรหัสผ่านที่มีอยู่แล้ว การทำเช่นนี้จะเปิดใช้งานการตรวจสอบสิทธิ์แบบสองขั้นตอนสำหรับบัญชีรหัสผ่าน",
"createUser": "สร้างผู้ใช้", "createUser": "สร้างผู้ใช้",
"createUserDescription": "สร้างผู้ใช้ภายในเครื่องใหม่ โดยระบุชื่อผู้ใช้และรหัสผ่าน", "createUserDescription": "สร้างผู้ใช้ภายในเครื่องใหม่ โดยระบุชื่อผู้ใช้และรหัสผ่าน",
"enterUsername": "ป้อนชื่อผู้ใช้", "enterUsername": "ป้อนชื่อผู้ใช้",
@@ -584,7 +584,7 @@
"passwordResetWarning": "การรีเซ็ตรหัสผ่านของผู้ใช้จะลบข้อมูลทั้งหมดของผู้ใช้ (โฮสต์ SSH ข้อมูลประจำตัว การตั้งค่า) การกระทำนี้ไม่สามารถย้อนกลับได้", "passwordResetWarning": "การรีเซ็ตรหัสผ่านของผู้ใช้จะลบข้อมูลทั้งหมดของผู้ใช้ (โฮสต์ SSH ข้อมูลประจำตัว การตั้งค่า) การกระทำนี้ไม่สามารถย้อนกลับได้",
"resetUserPassword": "รีเซ็ตรหัสผ่านผู้ใช้", "resetUserPassword": "รีเซ็ตรหัสผ่านผู้ใช้",
"resettingPassword": "กำลังรีเซ็ต...", "resettingPassword": "กำลังรีเซ็ต...",
"passwordResetInitiated": "เริ่มการรีเซ็ตรหัสผ่านสำหรับ {{username}} ส่งรหัสรีเซ็ตแล้ว", "passwordResetInitiated": "เริ่มการรีเซ็ต mật khẩu สำหรับ {{username}}ส่งรหัสรีเซ็ตแล้ว",
"failedToResetPassword": "ไม่สามารถเริ่มการรีเซ็ตรหัสผ่านได้", "failedToResetPassword": "ไม่สามารถเริ่มการรีเซ็ตรหัสผ่านได้",
"sessionManagement": "การจัดการเซสชัน", "sessionManagement": "การจัดการเซสชัน",
"revokeAllSessions": "ยกเลิกเซสชันทั้งหมด", "revokeAllSessions": "ยกเลิกเซสชันทั้งหมด",
@@ -611,11 +611,11 @@
"linkTargetUsernamePlaceholder": "ป้อนชื่อผู้ใช้หรือรหัสผ่านของบัญชี", "linkTargetUsernamePlaceholder": "ป้อนชื่อผู้ใช้หรือรหัสผ่านของบัญชี",
"linkAccountsButton": "เชื่อมโยงบัญชี", "linkAccountsButton": "เชื่อมโยงบัญชี",
"linkingAccounts": "กำลังเชื่อมโยง...", "linkingAccounts": "กำลังเชื่อมโยง...",
"accountsLinkedSuccessfully": "ผู้ใช้ OIDC {{oidcUsername}} ได้รับการเชื่อมโยงกับ {{targetUsername}}", "accountsLinkedSuccessfully": "ผู้ใช้ OIDC {{oidcUsername}} ได้ถูกเชื่อมโยงกับ {{targetUsername}}แล้ว",
"failedToLinkAccounts": "ไม่สามารถเชื่อมโยงบัญชีได้", "failedToLinkAccounts": "ไม่สามารถเชื่อมโยงบัญชีได้",
"linkTargetUsernameRequired": "จำเป็นต้องระบุชื่อผู้ใช้เป้าหมาย", "linkTargetUsernameRequired": "จำเป็นต้องระบุชื่อผู้ใช้เป้าหมาย",
"unlinkOIDCTitle": "ยกเลิกการเชื่อมโยงการตรวจสอบสิทธิ์ OIDC", "unlinkOIDCTitle": "ยกเลิกการเชื่อมโยงการตรวจสอบสิทธิ์ OIDC",
"unlinkOIDCDescription": "ลบการตรวจสอบสิทธิ์ OIDC ออกจาก {{username}} หรือไม่? ผู้ใช้จะสามารถเข้าสู่ระบบได้เฉพาะด้วยชื่อผู้ใช้/รหัสผ่านหลังจากนี้เท่านั้น", "unlinkOIDCDescription": "ลบการตรวจสอบสิทธิ์ OIDC ออกจาก {{username}}หรือไม่? หลังจากนี้ผู้ใช้จะสามารถเข้าสู่ระบบได้เฉพาะด้วยชื่อผู้ใช้/รหัสผ่านเท่านั้น",
"unlinkOIDCSuccess": "OIDC ถูกตัดการเชื่อมต่อจาก {{username}}", "unlinkOIDCSuccess": "OIDC ถูกตัดการเชื่อมต่อจาก {{username}}",
"failedToUnlinkOIDC": "ไม่สามารถยกเลิกการเชื่อมโยง OIDC ได้", "failedToUnlinkOIDC": "ไม่สามารถยกเลิกการเชื่อมโยง OIDC ได้",
"databaseSecurity": "ความปลอดภัยของฐานข้อมูล", "databaseSecurity": "ความปลอดภัยของฐานข้อมูล",
@@ -737,13 +737,13 @@
"exportDescription": "ส่งออกข้อมูลโฮสต์และข้อมูลรับรอง SSH ไปยังไฟล์ SQLite", "exportDescription": "ส่งออกข้อมูลโฮสต์และข้อมูลรับรอง SSH ไปยังไฟล์ SQLite",
"importDescription": "นำเข้าไฟล์ SQLite ด้วยการผสานแบบเพิ่มทีละส่วน (ข้ามข้อมูลที่ซ้ำกัน)", "importDescription": "นำเข้าไฟล์ SQLite ด้วยการผสานแบบเพิ่มทีละส่วน (ข้ามข้อมูลที่ซ้ำกัน)",
"criticalWarning": "คำเตือนที่สำคัญ", "criticalWarning": "คำเตือนที่สำคัญ",
"cannotDisablePasswordLoginWithoutOIDC": "ไม่สามารถปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่านได้หากไม่ได้กำหนดค่า OIDC! คุณต้องกำหนดค่าการตรวจสอบสิทธิ์ OIDC ก่อนจึงจะสามารถปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่านได้ มิเช่นนั้นคุณจะไม่สามารถเข้าถึง Termix ได้", "cannotDisablePasswordLoginWithoutOIDC": "ไม่สามารถปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่านได้หากไม่ได้กำหนดค่า OIDC! คุณต้องกำหนดค่าการตรวจสอบสิทธิ์ OIDC ก่อนจึงจะปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่านได้ มิเช่นนั้นคุณจะไม่สามารถเข้าถึง Termix ได้",
"confirmDisablePasswordLogin": "คุณแน่ใจหรือไม่ว่าต้องการปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่าน? โปรดตรวจสอบให้แน่ใจว่า OIDC ได้รับการกำหนดค่าอย่างถูกต้องและทำงานได้อย่างถูกต้องก่อนดำเนินการต่อ มิเช่นนั้นคุณจะไม่สามารถเข้าถึงอินสแตนซ์ Termix ของคุณได้", "confirmDisablePasswordLogin": "คุณแน่ใจหรือไม่ว่าต้องการปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่าน? โปรดตรวจสอบให้แน่ใจว่า OIDC ได้รับการกำหนดค่าอย่างถูกต้องและทำงานได้อย่างถูกต้องก่อนดำเนินการต่อ มิเช่นนั้นคุณจะไม่สามารถเข้าถึงอินสแตนซ์ Termix ของคุณได้",
"passwordLoginDisabled": "การเข้าสู่ระบบด้วยรหัสผ่านถูกปิดใช้งานสำเร็จแล้ว", "passwordLoginDisabled": "การเข้าสู่ระบบด้วยรหัสผ่านถูกปิดใช้งานสำเร็จแล้ว",
"passwordLoginAndRegistrationDisabled": "การเข้าสู่ระบบด้วยรหัสผ่านและการลงทะเบียนบัญชีใหม่ถูกปิดใช้งานเรียบร้อยแล้ว", "passwordLoginAndRegistrationDisabled": "การเข้าสู่ระบบด้วยรหัสผ่านและการลงทะเบียนบัญชีใหม่ถูกปิดใช้งานเรียบร้อยแล้ว",
"requiresPasswordLogin": "ต้องเปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่าน", "requiresPasswordLogin": "ต้องเปิดใช้งานการเข้าสู่ระบบด้วยรหัสผ่าน",
"passwordLoginDisabledWarning": "การเข้าสู่ระบบด้วยรหัสผ่านถูกปิดใช้งาน โปรดตรวจสอบให้แน่ใจว่าได้กำหนดค่า OIDC อย่างถูกต้อง มิเช่นนั้นคุณจะไม่สามารถเข้าสู่ระบบ Termix ได้", "passwordLoginDisabledWarning": "การเข้าสู่ระบบด้วยรหัสผ่านถูกปิดใช้งาน โปรดตรวจสอบให้แน่ใจว่าได้กำหนดค่า OIDC อย่างถูกต้อง มิเช่นนั้นคุณจะไม่สามารถเข้าสู่ระบบ Termix ได้",
"oidcRequiredWarning": "คำเตือนสำคัญ: การเข้าสู่ระบบด้วยรหัสผ่านถูกปิดใช้งาน หากคุณรีเซ็ตหรือกำหนดค่า OIDC ผิดพลาด คุณจะสูญเสียการเข้าถึง Termix ทั้งหมดและทำให้ระบบของคุณใช้งานไม่ได้ โปรดดำเนินการต่อเฉพาะเมื่อคุณแน่ใจอย่างยิ่งเท่านั้น", "oidcRequiredWarning": "คำเตือนสำคัญ: การเข้าสู่ระบบด้วยรหัสผ่านถูกปิดใช้งาน หากคุณรีเซ็ตหรือกำหนดค่า OIDC ผิดพลาด คุณจะสูญเสียการเข้าถึง Termix ทั้งหมดและทำให้ระบบของคุณใช้งานไม่ได้ โปรดดำเนินการต่อเมื่อคุณแน่ใจอย่างยิ่งเท่านั้น",
"confirmDisableOIDCWarning": "คำเตือน: คุณกำลังจะปิดใช้งาน OIDC ในขณะที่การเข้าสู่ระบบด้วยรหัสผ่านก็ถูกปิดใช้งานอยู่เช่นกัน การกระทำนี้จะทำให้ระบบ Termix ของคุณใช้งานไม่ได้ และคุณจะสูญเสียการเข้าถึงทั้งหมด คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?", "confirmDisableOIDCWarning": "คำเตือน: คุณกำลังจะปิดใช้งาน OIDC ในขณะที่การเข้าสู่ระบบด้วยรหัสผ่านก็ถูกปิดใช้งานอยู่เช่นกัน การกระทำนี้จะทำให้ระบบ Termix ของคุณใช้งานไม่ได้ และคุณจะสูญเสียการเข้าถึงทั้งหมด คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?",
"failedToUpdatePasswordLoginStatus": "ไม่สามารถอัปเดตสถานะการเข้าสู่ระบบด้วยรหัสผ่านได้", "failedToUpdatePasswordLoginStatus": "ไม่สามารถอัปเดตสถานะการเข้าสู่ระบบด้วยรหัสผ่านได้",
"loadingSessions": "กำลังโหลดเซสชัน...", "loadingSessions": "กำลังโหลดเซสชัน...",
@@ -756,7 +756,7 @@
"revokeAllUserSessionsTitle": "ยกเลิกเซสชันทั้งหมดสำหรับผู้ใช้รายนี้", "revokeAllUserSessionsTitle": "ยกเลิกเซสชันทั้งหมดสำหรับผู้ใช้รายนี้",
"revokeAll": "เพิกถอนทั้งหมด", "revokeAll": "เพิกถอนทั้งหมด",
"linkOidcToPasswordAccount": "เชื่อมโยงบัญชี OIDC กับบัญชีรหัสผ่าน", "linkOidcToPasswordAccount": "เชื่อมโยงบัญชี OIDC กับบัญชีรหัสผ่าน",
"linkOidcToPasswordAccountDescription": "เชื่อมโยง {{username}} (ผู้ใช้ OIDC) กับบัญชีรหัสผ่านที่มีอยู่แล้ว การทำเช่นนี้จะเปิดใช้งานการตรวจสอบสิทธิ์แบบสองทางสำหรับบัญชีรหัสผ่าน", "linkOidcToPasswordAccountDescription": "เชื่อมโยง {{username}} (ผู้ใช้ OIDC) กับบัญชีรหัสผ่านที่มีอยู่แล้ว การทำเช่นนี้จะเปิดใช้งานการตรวจสอบสิทธิ์แบบสองขั้นตอนสำหรับบัญชีรหัสผ่าน",
"linkOidcWarningTitle": "คำเตือน: ข้อมูลผู้ใช้ OIDC จะถูกลบ", "linkOidcWarningTitle": "คำเตือน: ข้อมูลผู้ใช้ OIDC จะถูกลบ",
"linkOidcWarningDescription": "การกระทำนี้จะส่งผลให้:", "linkOidcWarningDescription": "การกระทำนี้จะส่งผลให้:",
"linkOidcActionDeleteUser": "ลบบัญชีผู้ใช้ OIDC และข้อมูลทั้งหมดของผู้ใช้รายนั้น", "linkOidcActionDeleteUser": "ลบบัญชีผู้ใช้ OIDC และข้อมูลทั้งหมดของผู้ใช้รายนั้น",
@@ -785,9 +785,9 @@
"downloadSample": "ดาวน์โหลดตัวอย่าง", "downloadSample": "ดาวน์โหลดตัวอย่าง",
"formatGuide": "คู่มือรูปแบบ", "formatGuide": "คู่มือรูปแบบ",
"exportCredentialWarning": "คำเตือน: โฮสต์ \"{{name}}\" ใช้การตรวจสอบสิทธิ์ด้วยข้อมูลประจำตัว ไฟล์ที่ส่งออกจะไม่รวมข้อมูลประจำตัว และจะต้องกำหนดค่าใหม่ด้วยตนเองหลังจากนำเข้า คุณต้องการดำเนินการต่อหรือไม่", "exportCredentialWarning": "คำเตือน: โฮสต์ \"{{name}}\" ใช้การตรวจสอบสิทธิ์ด้วยข้อมูลประจำตัว ไฟล์ที่ส่งออกจะไม่รวมข้อมูลประจำตัว และจะต้องกำหนดค่าใหม่ด้วยตนเองหลังจากนำเข้า คุณต้องการดำเนินการต่อหรือไม่",
"exportSensitiveDataWarning": "คำเตือน: โฮสต์ \"{{name}}\" มีข้อมูลการตรวจสอบสิทธิ์ที่ละเอียดอ่อน (รหัสผ่าน/คีย์ SSH) ไฟล์ที่ส่งออกจะรวมข้อมูลนี้ในรูปแบบข้อความธรรมดา โปรดเก็บไฟล์ให้ปลอดภัยและลบออกหลังจากใช้งาน คุณต้องการดำเนินการต่อหรือไม่", "exportSensitiveDataWarning": "คำเตือน: โฮสต์ \"{{name}}\" มีข้อมูลการตรวจสอบสิทธิ์ที่ละเอียดอ่อน (รหัสผ่าน/คีย์ SSH) ไฟล์ที่ส่งออกจะรวมข้อมูลนี้ในรูปแบบข้อความธรรมดา โปรดเก็บไฟล์ให้ปลอดภัยและลบหลังจากใช้งาน คุณต้องการดำเนินการต่อหรือไม่",
"uncategorized": "ไม่มีหมวดหมู่", "uncategorized": "ไม่มีหมวดหมู่",
"confirmDelete": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\"?", "confirmDelete": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\" ?",
"failedToDeleteHost": "ไม่สามารถลบโฮสต์ได้", "failedToDeleteHost": "ไม่สามารถลบโฮสต์ได้",
"failedToExportHost": "ไม่สามารถส่งออกข้อมูลโฮสต์ได้ โปรดตรวจสอบให้แน่ใจว่าคุณได้เข้าสู่ระบบและมีสิทธิ์เข้าถึงข้อมูลโฮสต์แล้ว", "failedToExportHost": "ไม่สามารถส่งออกข้อมูลโฮสต์ได้ โปรดตรวจสอบให้แน่ใจว่าคุณได้เข้าสู่ระบบและมีสิทธิ์เข้าถึงข้อมูลโฮสต์แล้ว",
"jsonMustContainHosts": "ไฟล์ JSON ต้องมีอาร์เรย์ \"hosts\" หรือเป็นอาร์เรย์ของ hosts", "jsonMustContainHosts": "ไฟล์ JSON ต้องมีอาร์เรย์ \"hosts\" หรือเป็นอาร์เรย์ของ hosts",
@@ -816,7 +816,7 @@
"editHost": "แก้ไขโฮสต์", "editHost": "แก้ไขโฮสต์",
"cloneHost": "โคลนโฮสต์", "cloneHost": "โคลนโฮสต์",
"updateHost": "อัปเดตโฮสต์", "updateHost": "อัปเดตโฮสต์",
"hostUpdatedSuccessfully": "โฮสต์ \"{{name}}\" ได้รับการอัปเดตสำเร็จแล้ว!", "hostUpdatedSuccessfully": "โฮสต์ \"{{name}}\" อัปเดตสำเร็จแล้ว!",
"hostAddedSuccessfully": "เพิ่มโฮสต์ \"{{name}}\" สำเร็จแล้ว!", "hostAddedSuccessfully": "เพิ่มโฮสต์ \"{{name}}\" สำเร็จแล้ว!",
"hostDeletedSuccessfully": "โฮสต์ \"{{name}}\" ถูกลบสำเร็จแล้ว!", "hostDeletedSuccessfully": "โฮสต์ \"{{name}}\" ถูกลบสำเร็จแล้ว!",
"failedToSaveHost": "ไม่สามารถบันทึกโฮสต์ได้ โปรดลองอีกครั้ง", "failedToSaveHost": "ไม่สามารถบันทึกโฮสต์ได้ โปรดลองอีกครั้ง",
@@ -837,7 +837,7 @@
"connection": "การเชื่อมต่อ", "connection": "การเชื่อมต่อ",
"remove": "ลบ", "remove": "ลบ",
"sourcePort": "พอร์ตต้นทาง", "sourcePort": "พอร์ตต้นทาง",
"sourcePortDesc": "(แหล่งที่มาหมายถึงรายละเอียดการเชื่อมต่อปัจจุบันในแท็บทั่วไป)", "sourcePortDesc": " (แหล่งที่มาหมายถึงรายละเอียดการเชื่อมต่อปัจจุบันในแท็บทั่วไป)",
"endpointPort": "พอร์ตปลายทาง", "endpointPort": "พอร์ตปลายทาง",
"endpointSshConfig": "การกำหนดค่า SSH ปลายทาง", "endpointSshConfig": "การกำหนดค่า SSH ปลายทาง",
"tunnelForwardDescription": "อุโมงค์นี้จะส่งต่อทราฟฟิกจากพอร์ต {{sourcePort}} บนเครื่องต้นทาง (รายละเอียดการเชื่อมต่อปัจจุบันในแท็บทั่วไป) ไปยังพอร์ต {{endpointPort}} บนเครื่องปลายทาง", "tunnelForwardDescription": "อุโมงค์นี้จะส่งต่อทราฟฟิกจากพอร์ต {{sourcePort}} บนเครื่องต้นทาง (รายละเอียดการเชื่อมต่อปัจจุบันในแท็บทั่วไป) ไปยังพอร์ต {{endpointPort}} บนเครื่องปลายทาง",
@@ -929,10 +929,10 @@
"folderAppearanceUpdated": "การแสดงผลโฟลเดอร์ได้รับการอัปเดตเรียบร้อยแล้ว", "folderAppearanceUpdated": "การแสดงผลโฟลเดอร์ได้รับการอัปเดตเรียบร้อยแล้ว",
"failedToUpdateFolderAppearance": "ไม่สามารถอัปเดตลักษณะการแสดงผลของโฟลเดอร์ได้", "failedToUpdateFolderAppearance": "ไม่สามารถอัปเดตลักษณะการแสดงผลของโฟลเดอร์ได้",
"deleteAllHostsInFolder": "ลบโฮสต์ทั้งหมดในโฟลเดอร์", "deleteAllHostsInFolder": "ลบโฮสต์ทั้งหมดในโฟลเดอร์",
"confirmDeleteAllHostsInFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบโฮสต์ทั้งหมด {{count}} ในโฟลเดอร์ \"{{folder}}\"? การกระทำนี้ไม่สามารถย้อนกลับได้", "confirmDeleteAllHostsInFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบโฮสต์ {{count}} ทั้งหมดในโฟลเดอร์ \"{{folder}}\"? การกระทำนี้ไม่สามารถย้อนกลับได้",
"allHostsInFolderDeleted": "ลบโฮสต์ {{count}} รายการจากโฟลเดอร์ \"{{folder}}\" สำเร็จแล้ว", "allHostsInFolderDeleted": "ลบโฮสต์ {{count}} จากโฟลเดอร์ \"{{folder}}\" สำเร็จแล้ว",
"failedToDeleteHostsInFolder": "ไม่สามารถลบโฮสต์ในโฟลเดอร์ได้", "failedToDeleteHostsInFolder": "ไม่สามารถลบโฮสต์ในโฟลเดอร์ได้",
"movedToFolder": "โฮสต์ \"{{name}}\" ย้ายไปที่ \"{{folder}}\" สำเร็จแล้ว", "movedToFolder": "โฮสต์ \"{{name}}\" ย้ายไปยัง \"{{folder}}\" สำเร็จแล้ว",
"failedToMoveToFolder": "ไม่สามารถย้ายโฮสต์ไปยังโฟลเดอร์ได้", "failedToMoveToFolder": "ไม่สามารถย้ายโฮสต์ไปยังโฟลเดอร์ได้",
"clickToRenameFolder": "คลิกเพื่อเปลี่ยนชื่อโฟลเดอร์", "clickToRenameFolder": "คลิกเพื่อเปลี่ยนชื่อโฟลเดอร์",
"renameFolder": "เปลี่ยนชื่อโฟลเดอร์", "renameFolder": "เปลี่ยนชื่อโฟลเดอร์",
@@ -950,7 +950,7 @@
"openServerDetails": "ดูรายละเอียดเซิร์ฟเวอร์", "openServerDetails": "ดูรายละเอียดเซิร์ฟเวอร์",
"statistics": "สถิติ", "statistics": "สถิติ",
"enabledWidgets": "วิดเจ็ตที่เปิดใช้งาน", "enabledWidgets": "วิดเจ็ตที่เปิดใช้งาน",
"openServerStats": "สถิติเซิร์ฟเวอร์แบบเปิด", "openServerStats": "เปิดสถิติเซิร์ฟเวอร์",
"enabledWidgetsDesc": "เลือกวิดเจ็ตแสดงสถิติที่จะแสดงสำหรับโฮสต์นี้", "enabledWidgetsDesc": "เลือกวิดเจ็ตแสดงสถิติที่จะแสดงสำหรับโฮสต์นี้",
"monitoringConfiguration": "การกำหนดค่าการตรวจสอบ", "monitoringConfiguration": "การกำหนดค่าการตรวจสอบ",
"monitoringConfigurationDesc": "ตั้งค่าความถี่ในการตรวจสอบสถิติและสถานะของเซิร์ฟเวอร์", "monitoringConfigurationDesc": "ตั้งค่าความถี่ในการตรวจสอบสถิติและสถานะของเซิร์ฟเวอร์",
@@ -982,13 +982,13 @@
"selectFont": "เลือกแบบอักษร", "selectFont": "เลือกแบบอักษร",
"selectFontDesc": "เลือกแบบอักษรที่จะใช้ในเทอร์มินัล", "selectFontDesc": "เลือกแบบอักษรที่จะใช้ในเทอร์มินัล",
"fontSize": "ขนาดตัวอักษร", "fontSize": "ขนาดตัวอักษร",
"fontSizeValue": "ขนาดตัวอักษร: {{value}}px", "fontSizeValue": "ขนาดตัวอักษร: {{value}}พิกเซล",
"adjustFontSize": "ปรับขนาดตัวอักษรของเทอร์มินัล", "adjustFontSize": "ปรับขนาดตัวอักษรของเทอร์มินัล",
"letterSpacing": "ระยะห่างระหว่างตัวอักษร", "letterSpacing": "ระยะห่างระหว่างตัวอักษร",
"letterSpacingValue": "ระยะห่างระหว่างตัวอักษร: {{value}}px", "letterSpacingValue": "ระยะห่างระหว่างตัวอักษร: {{value}}px",
"adjustLetterSpacing": "ปรับระยะห่างระหว่างตัวอักษร", "adjustLetterSpacing": "ปรับระยะห่างระหว่างตัวอักษร",
"lineHeight": "ความสูงของเส้น", "lineHeight": "ความสูงของเส้น",
"lineHeightValue": "ความสูงของบรรทัด: {{value}}", "lineHeightValue": "ความสูงของเส้น: {{value}}",
"adjustLineHeight": "ปรับระยะห่างระหว่างบรรทัด", "adjustLineHeight": "ปรับระยะห่างระหว่างบรรทัด",
"cursorStyle": "รูปแบบเคอร์เซอร์", "cursorStyle": "รูปแบบเคอร์เซอร์",
"selectCursorStyle": "เลือกรูปแบบเคอร์เซอร์", "selectCursorStyle": "เลือกรูปแบบเคอร์เซอร์",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "เสียง", "bellStyleSound": "เสียง",
"bellStyleVisual": "ภาพ", "bellStyleVisual": "ภาพ",
"bellStyleBoth": "ทั้งคู่", "bellStyleBoth": "ทั้งคู่",
"bellStyleDesc": "วิธีจัดการกับเสียงเตือนเมื่อสิ้นสุดโปรแกรม (อักขระ BEL, \\x07) โปรแกรมจะเรียกใช้เสียงเตือนนี้เมื่อทำงานเสร็จสิ้น พบข้อผิดพลาด หรือเพื่อแจ้งเตือน \"เสียง\" จะเล่นเสียงบี๊บ \"ภาพ\" จะแสดงภาพบนหน้าจอชั่วครู่ \"ทั้งสองอย่าง\" จะแสดงทั้งเสียงและภาพ \"ไม่มี\" จะปิดเสียงเตือนทั้งหมด", "bellStyleDesc": "วิธีจัดการกับเสียงเตือนเมื่อโปรแกรมทำงานเสร็จสิ้น (อักขระ BEL, \\x07) โปรแกรมจะเรียกใช้เสียงเตือนนี้เมื่อทำงานเสร็จสิ้น พบข้อผิดพลาด หรือเพื่อแจ้งเตือน \"เสียง\" จะเล่นเสียงบี๊บ \"ภาพ\" จะแสดงภาพบนหน้าจอชั่วครู่ \"ทั้งสองอย่าง\" จะแสดงทั้งเสียงและภาพ และ \"ไม่มี\" จะปิดการแจ้งเตือนด้วยเสียงเตือน",
"rightClickSelectsWord": "คลิกขวาแล้วเลือก Word", "rightClickSelectsWord": "คลิกขวาแล้วเลือก Word",
"rightClickSelectsWordDesc": "การคลิกขวาจะเลือกคำที่อยู่ใต้เคอร์เซอร์", "rightClickSelectsWordDesc": "การคลิกขวาจะเลือกคำที่อยู่ใต้เคอร์เซอร์",
"fastScrollModifier": "ตัวแก้ไขการเลื่อนเร็ว", "fastScrollModifier": "ตัวแก้ไขการเลื่อนเร็ว",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "สร้างค่าที่ตั้งไว้ล่วงหน้าของห่วงโซ่พร็อกซีแล้ว", "socks5PresetCreated": "สร้างค่าที่ตั้งไว้ล่วงหน้าของห่วงโซ่พร็อกซีแล้ว",
"socks5PresetUpdated": "อัปเดตค่าที่ตั้งไว้ล่วงหน้าของห่วงโซ่พร็อกซีแล้ว", "socks5PresetUpdated": "อัปเดตค่าที่ตั้งไว้ล่วงหน้าของห่วงโซ่พร็อกซีแล้ว",
"socks5PresetDeleted": "ลบการตั้งค่าล่วงหน้าของห่วงโซ่พร็อกซีแล้ว", "socks5PresetDeleted": "ลบการตั้งค่าล่วงหน้าของห่วงโซ่พร็อกซีแล้ว",
"socks5PresetSaved": "ค่าที่ตั้งไว้ล่วงหน้า \"{{name}}\" ถูกบันทึกสำเร็จแล้ว", "socks5PresetSaved": "บันทึกค่าที่ตั้งไว้ล่วงหน้า \"{{name}}\" สำเร็จแล้ว",
"socks5PresetSaveError": "ไม่สามารถบันทึกค่าที่ตั้งไว้ล่วงหน้าได้", "socks5PresetSaveError": "ไม่สามารถบันทึกค่าที่ตั้งไว้ล่วงหน้าได้",
"socks5PresetNameRequired": "ต้องระบุชื่อที่กำหนดไว้ล่วงหน้า", "socks5PresetNameRequired": "ต้องระบุชื่อที่กำหนดไว้ล่วงหน้า",
"socks5EmptyChainError": "ไม่สามารถบันทึกเชนพร็อกซีที่ว่างเปล่าได้", "socks5EmptyChainError": "ไม่สามารถบันทึกเชนพร็อกซีที่ว่างเปล่าได้",
@@ -1086,7 +1086,7 @@
"socks5HostDescription": "ชื่อโฮสต์หรือที่อยู่ IP ของเซิร์ฟเวอร์พร็อกซี SOCKS", "socks5HostDescription": "ชื่อโฮสต์หรือที่อยู่ IP ของเซิร์ฟเวอร์พร็อกซี SOCKS",
"socks5PortDescription": "หมายเลขพอร์ตของเซิร์ฟเวอร์พร็อกซี SOCKS (ค่าเริ่มต้น: 1080)", "socks5PortDescription": "หมายเลขพอร์ตของเซิร์ฟเวอร์พร็อกซี SOCKS (ค่าเริ่มต้น: 1080)",
"addProxyNode": "เพิ่มโหนดพร็อกซี", "addProxyNode": "เพิ่มโหนดพร็อกซี",
"noProxyNodes": "ยังไม่ได้กำหนดค่าโหนดพร็อกซี คลิก \"เพิ่มโหนดพร็อกซี\" เพื่อเพิ่มโหนดพร็อกซี", "noProxyNodes": "ไม่ได้กำหนดค่าโหนดพร็อกซี คลิก 'เพิ่มโหนดพร็อกซี' เพื่อเพิ่มโหนดพร็อกซี",
"proxyNode": "โหนดพร็อกซี", "proxyNode": "โหนดพร็อกซี",
"proxyType": "ประเภทพร็อกซี", "proxyType": "ประเภทพร็อกซี",
"quickActions": "การดำเนินการด่วน", "quickActions": "การดำเนินการด่วน",
@@ -1119,7 +1119,7 @@
"validating": "กำลังตรวจสอบความถูกต้องของ Docker...", "validating": "กำลังตรวจสอบความถูกต้องของ Docker...",
"error": "ข้อผิดพลาด", "error": "ข้อผิดพลาด",
"errorCode": "รหัสข้อผิดพลาด: {{code}}", "errorCode": "รหัสข้อผิดพลาด: {{code}}",
"version": "ด็อกเกอร์ v{{version}}", "version": "Docker v{{version}}",
"current": "ปัจจุบัน", "current": "ปัจจุบัน",
"used_limit": "ใช้งานแล้ว / ขีดจำกัด", "used_limit": "ใช้งานแล้ว / ขีดจำกัด",
"percentage": "เปอร์เซ็นต์", "percentage": "เปอร์เซ็นต์",
@@ -1131,7 +1131,7 @@
"id": "รหัสประจำตัว", "id": "รหัสประจำตัว",
"state": "สถานะ", "state": "สถานะ",
"console": "คอนโซล", "console": "คอนโซล",
"containerMustBeRunning": "คอนเทนเนอร์ต้องทำงานอยู่จึงจะสามารถเชื่อมต่อกับคอนโซลได้", "containerMustBeRunning": "ต้องเปิดใช้งานคอนเทนเนอร์ก่อนจึงจะสามารถเชื่อมต่อกับคอนโซลได้",
"authenticationRequired": "จำเป็นต้องยืนยันตัวตน", "authenticationRequired": "จำเป็นต้องยืนยันตัวตน",
"connectedTo": "เชื่อมต่อกับ {{containerName}}", "connectedTo": "เชื่อมต่อกับ {{containerName}}",
"disconnected": "ตัดการเชื่อมต่อ", "disconnected": "ตัดการเชื่อมต่อ",
@@ -1139,7 +1139,7 @@
"errorMessage": "ข้อผิดพลาด: {{message}}", "errorMessage": "ข้อผิดพลาด: {{message}}",
"failedToConnect": "ไม่สามารถเชื่อมต่อกับคอนโซลได้", "failedToConnect": "ไม่สามารถเชื่อมต่อกับคอนโซลได้",
"disconnectedFromContainer": "ตัดการเชื่อมต่อจากคอนโซลคอนเทนเนอร์แล้ว", "disconnectedFromContainer": "ตัดการเชื่อมต่อจากคอนโซลคอนเทนเนอร์แล้ว",
"containerNotRunning": "คอนเทนเนอร์ไม่ได้ทำงาน", "containerNotRunning": "คอนเทนเนอร์ไม่ได้ทำงานอยู่",
"startContainerToAccess": "เริ่มคอนเทนเนอร์เพื่อเข้าถึงคอนโซล", "startContainerToAccess": "เริ่มคอนเทนเนอร์เพื่อเข้าถึงคอนโซล",
"selectShell": "เลือกเปลือกหอย", "selectShell": "เลือกเปลือกหอย",
"bash": "ทุบตี", "bash": "ทุบตี",
@@ -1163,13 +1163,13 @@
"noContainersMatchFiltersHint": "ลองปรับการค้นหาหรือตัวกรองของคุณดู", "noContainersMatchFiltersHint": "ลองปรับการค้นหาหรือตัวกรองของคุณดู",
"containerStarted": "คอนเทนเนอร์ {{name}} เริ่มทำงานแล้ว", "containerStarted": "คอนเทนเนอร์ {{name}} เริ่มทำงานแล้ว",
"failedToStartContainer": "ไม่สามารถเริ่มต้นคอนเทนเนอร์ได้: {{error}}", "failedToStartContainer": "ไม่สามารถเริ่มต้นคอนเทนเนอร์ได้: {{error}}",
"containerStopped": "คอนเทนเนอร์ {{name}} หยุดแล้ว", "containerStopped": "คอนเทนเนอร์ {{name}} หยุดทำงานแล้ว",
"failedToStopContainer": "ไม่สามารถหยุดคอนเทนเนอร์ได้: {{error}}", "failedToStopContainer": "ไม่สามารถหยุดคอนเทนเนอร์ได้: {{error}}",
"containerRestarted": "คอนเทนเนอร์ {{name}} รีสตาร์ทแล้ว", "containerRestarted": "คอนเทนเนอร์ {{name}} รีสตาร์ทแล้ว",
"failedToRestartContainer": "ไม่สามารถรีสตาร์ทคอนเทนเนอร์ได้: {{error}}", "failedToRestartContainer": "ไม่สามารถรีสตาร์ทคอนเทนเนอร์ได้: {{error}}",
"containerUnpaused": "คอนเทนเนอร์ {{name}} ยกเลิกการหยุดชั่วคราว", "containerUnpaused": "คอนเทนเนอร์ {{name}} ยกเลิกการหยุดชั่วคราว",
"containerPaused": "คอนเทนเนอร์ {{name}} หยุดชั่วคราว", "containerPaused": "คอนเทนเนอร์ {{name}} หยุดชั่วคราว",
"failedToTogglePauseContainer": "ไม่สามารถสร้างคอนเทนเนอร์ {{action}} ได้: {{error}}", "failedToTogglePauseContainer": "ไม่สามารถ {{action}} คอนเทนเนอร์ได้: {{error}}",
"containerRemoved": "คอนเทนเนอร์ {{name}} ถูกลบออกแล้ว", "containerRemoved": "คอนเทนเนอร์ {{name}} ถูกลบออกแล้ว",
"failedToRemoveContainer": "ไม่สามารถลบคอนเทนเนอร์ได้: {{error}}", "failedToRemoveContainer": "ไม่สามารถลบคอนเทนเนอร์ได้: {{error}}",
"image": "ภาพ:", "image": "ภาพ:",
@@ -1191,7 +1191,7 @@
"logs": "บันทึก", "logs": "บันทึก",
"stats": "สถิติ", "stats": "สถิติ",
"consoleTab": "คอนโซล", "consoleTab": "คอนโซล",
"failedToFetchLogs": "ไม่สามารถดึงบันทึกได้: {{error}}", "failedToFetchLogs": "ไม่สามารถดึงข้อมูลบันทึกได้: {{error}}",
"failedToDownloadLogs": "ไม่สามารถดาวน์โหลดบันทึกได้: {{error}}", "failedToDownloadLogs": "ไม่สามารถดาวน์โหลดบันทึกได้: {{error}}",
"linesToShow": "เส้นเพื่อแสดง", "linesToShow": "เส้นเพื่อแสดง",
"last50Lines": "50 บรรทัดสุดท้าย", "last50Lines": "50 บรรทัดสุดท้าย",
@@ -1221,7 +1221,7 @@
"connectionLost": "การเชื่อมต่อขาดหาย", "connectionLost": "การเชื่อมต่อขาดหาย",
"error": "ข้อผิดพลาด: {{message}}", "error": "ข้อผิดพลาด: {{message}}",
"disconnected": "ตัดการเชื่อมต่อ", "disconnected": "ตัดการเชื่อมต่อ",
"connectionClosed": "การเชื่อมต่อถูกตัด", "connectionClosed": "การเชื่อมต่อถูกปิด",
"connectionError": "ข้อผิดพลาดในการเชื่อมต่อ: {{message}}", "connectionError": "ข้อผิดพลาดในการเชื่อมต่อ: {{message}}",
"connected": "เชื่อมต่อแล้ว", "connected": "เชื่อมต่อแล้ว",
"sshConnected": "การเชื่อมต่อ SSH สำเร็จแล้ว", "sshConnected": "การเชื่อมต่อ SSH สำเร็จแล้ว",
@@ -1236,7 +1236,7 @@
"connectionTimeout": "หมดเวลาการเชื่อมต่อ", "connectionTimeout": "หมดเวลาการเชื่อมต่อ",
"terminalTitle": "เทอร์มินัล - {{host}}", "terminalTitle": "เทอร์มินัล - {{host}}",
"terminalWithPath": "เทอร์มินัล - {{host}}:{{path}}", "terminalWithPath": "เทอร์มินัล - {{host}}:{{path}}",
"runTitle": "วิ่ง {{command}} - {{host}}", "runTitle": "กำลังวิ่ง {{command}} - {{host}}",
"totpRequired": "ต้องใช้การยืนยันตัวตนสองขั้นตอน", "totpRequired": "ต้องใช้การยืนยันตัวตนสองขั้นตอน",
"totpCodeLabel": "รหัสยืนยัน", "totpCodeLabel": "รหัสยืนยัน",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
@@ -1255,7 +1255,7 @@
"downloadFile": "ดาวน์โหลด", "downloadFile": "ดาวน์โหลด",
"extractArchive": "แตกไฟล์เก็บถาวร", "extractArchive": "แตกไฟล์เก็บถาวร",
"extractingArchive": "กำลังดึงข้อมูล {{name}}...", "extractingArchive": "กำลังดึงข้อมูล {{name}}...",
"archiveExtractedSuccessfully": "{{name}} สกัดสำเร็จแล้ว", "archiveExtractedSuccessfully": "{{name}} ดึงข้อมูลสำเร็จแล้ว",
"extractFailed": "การดึงข้อมูลล้มเหลว", "extractFailed": "การดึงข้อมูลล้มเหลว",
"compressFile": "บีบอัดไฟล์", "compressFile": "บีบอัดไฟล์",
"compressFiles": "บีบอัดไฟล์", "compressFiles": "บีบอัดไฟล์",
@@ -1264,9 +1264,9 @@
"enterArchiveName": "ป้อนชื่อไฟล์เก็บถาวร...", "enterArchiveName": "ป้อนชื่อไฟล์เก็บถาวร...",
"compressionFormat": "รูปแบบการบีบอัด", "compressionFormat": "รูปแบบการบีบอัด",
"selectedFiles": "ไฟล์ที่เลือก", "selectedFiles": "ไฟล์ที่เลือก",
"andMoreFiles": "และอีก {{count}} รายการ...", "andMoreFiles": "และ {{count}} เพิ่มเติม...",
"compress": "บีบอัด", "compress": "บีบอัด",
"compressingFiles": "บีบอัดรายการ {{count}} รายการให้เหลือ {{name}} รายการ...", "compressingFiles": "บีบอัดรายการ {{count}} รายการเป็น {{name}}รายการ ...",
"filesCompressedSuccessfully": "{{name}} สร้างสำเร็จแล้ว", "filesCompressedSuccessfully": "{{name}} สร้างสำเร็จแล้ว",
"compressFailed": "การบีบอัดล้มเหลว", "compressFailed": "การบีบอัดล้มเหลว",
"edit": "แก้ไข", "edit": "แก้ไข",
@@ -1324,8 +1324,8 @@
"failedToCreateItem": "ไม่สามารถสร้างรายการได้", "failedToCreateItem": "ไม่สามารถสร้างรายการได้",
"operationFailed": "การดำเนินการ {{operation}} ล้มเหลวสำหรับ {{name}}: {{error}}", "operationFailed": "การดำเนินการ {{operation}} ล้มเหลวสำหรับ {{name}}: {{error}}",
"failedToResolveSymlink": "ไม่สามารถแก้ไขลิงก์สัญลักษณ์ได้", "failedToResolveSymlink": "ไม่สามารถแก้ไขลิงก์สัญลักษณ์ได้",
"itemDeletedSuccessfully": "{{type}} ถูกลบสำเร็จแล้ว", "itemDeletedSuccessfully": "{{type}} ลบสำเร็จแล้ว",
"itemsDeletedSuccessfully": "ลบรายการสำเร็จแล้ว {{count}} รายการ", "itemsDeletedSuccessfully": "รายการ {{count}} ถูกลบสำเร็จแล้ว",
"failedToDeleteItems": "ไม่สามารถลบรายการได้", "failedToDeleteItems": "ไม่สามารถลบรายการได้",
"dragFilesToUpload": "ลากไฟล์มาวางที่นี่เพื่ออัปโหลด", "dragFilesToUpload": "ลากไฟล์มาวางที่นี่เพื่ออัปโหลด",
"emptyFolder": "โฟลเดอร์นี้ว่างเปล่า", "emptyFolder": "โฟลเดอร์นี้ว่างเปล่า",
@@ -1347,14 +1347,14 @@
"delete": "ลบ", "delete": "ลบ",
"properties": "คุณสมบัติ", "properties": "คุณสมบัติ",
"refresh": "รีเฟรช", "refresh": "รีเฟรช",
"downloadFiles": "ดาวน์โหลดไฟล์ {{count}} ไฟล์ไปยังเบราว์เซอร์", "downloadFiles": "ดาวน์โหลดไฟล์ {{count}} ไปยังเบราว์เซอร์",
"copyFiles": "คัดลอก {{count}} รายการ", "copyFiles": "คัดลอกรายการ {{count}} รายการ",
"cutFiles": "ตัด {{count}} รายการ", "cutFiles": "ตัดรายการ {{count}} รายการ",
"deleteFiles": "ลบรายการ {{count}} รายการ", "deleteFiles": "ลบรายการ {{count}} รายการ",
"filesCopiedToClipboard": "คัดลอกรายการไปยังคลิปบอร์ดแล้ว {{count}} รายการ", "filesCopiedToClipboard": "{{count}} รายการถูกคัดลอกไปยังคลิปบอร์ด",
"filesCutToClipboard": "{{count}} รายการถูกตัดไปยังคลิปบอร์ด", "filesCutToClipboard": "{{count}} รายการที่ถูกตัดไปยังคลิปบอร์ด",
"pathCopiedToClipboard": "คัดลอกเส้นทางไปยังคลิปบอร์ดแล้ว", "pathCopiedToClipboard": "คัดลอกเส้นทางไปยังคลิปบอร์ดแล้ว",
"pathsCopiedToClipboard": "คัดลอกเส้นทางไปยังคลิปบอร์ดแล้ว {{count}} เส้นทาง", "pathsCopiedToClipboard": "{{count}} คัดลอกเส้นทางไปยังคลิปบอร์ดแล้ว",
"failedToCopyPath": "ไม่สามารถคัดลอกเส้นทางไปยังคลิปบอร์ดได้", "failedToCopyPath": "ไม่สามารถคัดลอกเส้นทางไปยังคลิปบอร์ดได้",
"movedItems": "ย้ายรายการ {{count}} รายการ", "movedItems": "ย้ายรายการ {{count}} รายการ",
"failedToDeleteItem": "ไม่สามารถลบรายการได้", "failedToDeleteItem": "ไม่สามารถลบรายการได้",
@@ -1390,7 +1390,7 @@
"fileOperations": "การดำเนินการไฟล์", "fileOperations": "การดำเนินการไฟล์",
"confirmDeleteMessage": "คุณแน่ใจหรือไม่ว่าต้องการลบ {{name}}?", "confirmDeleteMessage": "คุณแน่ใจหรือไม่ว่าต้องการลบ {{name}}?",
"confirmDeleteSingleItem": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\" อย่างถาวร?", "confirmDeleteSingleItem": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\" อย่างถาวร?",
"confirmDeleteMultipleItems": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการจำนวน {{count}} รายการอย่างถาวร?", "confirmDeleteMultipleItems": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการ {{count}} อย่างถาวร?",
"confirmDeleteMultipleItemsWithFolders": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการ {{count}} รายการอย่างถาวร ซึ่งรวมถึงโฟลเดอร์และเนื้อหาภายในโฟลเดอร์ด้วย", "confirmDeleteMultipleItemsWithFolders": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการ {{count}} รายการอย่างถาวร ซึ่งรวมถึงโฟลเดอร์และเนื้อหาภายในโฟลเดอร์ด้วย",
"confirmDeleteFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบโฟลเดอร์ \"{{name}}\" และเนื้อหาทั้งหมดในนั้นอย่างถาวร?", "confirmDeleteFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบโฟลเดอร์ \"{{name}}\" และเนื้อหาทั้งหมดในนั้นอย่างถาวร?",
"deleteDirectoryWarning": "การดำเนินการนี้จะลบโฟลเดอร์และเนื้อหาทั้งหมดภายในโฟลเดอร์นั้น", "deleteDirectoryWarning": "การดำเนินการนี้จะลบโฟลเดอร์และเนื้อหาทั้งหมดภายในโฟลเดอร์นั้น",
@@ -1428,25 +1428,25 @@
"starred": "ดาว", "starred": "ดาว",
"shortcuts": "ทางลัด", "shortcuts": "ทางลัด",
"directories": "รายชื่อ", "directories": "รายชื่อ",
"removedFromRecentFiles": "ลบ \"{{name}}\" ออกจากไฟล์ล่าสุด", "removedFromRecentFiles": "ลบ \"{{name}}\" ออกจากไฟล์ล่าสุดแล้ว",
"removeFailed": "ลบสิ่งที่ล้มเหลว", "removeFailed": "ลบสิ่งที่ล้มเหลว",
"unpinnedSuccessfully": "ยกเลิกการตรึง \"{{name}}\" สำเร็จ", "unpinnedSuccessfully": "ยกเลิกการตรึง \"{{name}}\" สำเร็จแล้ว",
"unpinFailed": "ยกเลิกการตรึงไม่สำเร็จ", "unpinFailed": "ยกเลิกการตรึงไม่สำเร็จ",
"removedShortcut": "ลบทางลัด \"{{name}}\"", "removedShortcut": "ลบทางลัด \"{{name}}\" ออกแล้ว",
"removeShortcutFailed": "ลบทางลัดไม่สำเร็จ", "removeShortcutFailed": "การลบทางลัดล้มเหลว",
"clearedAllRecentFiles": "ลบไฟล์ล่าสุดทั้งหมดแล้ว", "clearedAllRecentFiles": "ลบไฟล์ล่าสุดทั้งหมดแล้ว",
"clearFailed": "เคลียร์ล้มเหลว", "clearFailed": "เคลียร์ล้มเหลว",
"removeFromRecentFiles": "ลบออกจากไฟล์ล่าสุด", "removeFromRecentFiles": "ลบออกจากไฟล์ล่าสุด",
"clearAllRecentFiles": "ลบไฟล์ล่าสุดทั้งหมด", "clearAllRecentFiles": "ลบไฟล์ล่าสุดทั้งหมด",
"unpinFile": "ยกเลิกการตรึงไฟล์", "unpinFile": "ยกเลิกการตรึงไฟล์",
"removeShortcut": "ลบทางลัด", "removeShortcut": "ลบทางลัด",
"saveFilesToSystem": "บันทึกไฟล์ {{count}} ไฟล์เป็น...", "saveFilesToSystem": "บันทึกไฟล์ {{count}} เป็น...",
"pinFile": "ไฟล์พิน", "pinFile": "ไฟล์พิน",
"addToShortcuts": "เพิ่มไปยังทางลัด", "addToShortcuts": "เพิ่มไปยังทางลัด",
"downloadToDefaultLocation": "ดาวน์โหลดไปยังตำแหน่งเริ่มต้น", "downloadToDefaultLocation": "ดาวน์โหลดไปยังตำแหน่งเริ่มต้น",
"pasteFailed": "การวางล้มเหลว", "pasteFailed": "การวางล้มเหลว",
"noUndoableActions": "ไม่มีการกระทำใดที่ย้อนกลับไม่ได้", "noUndoableActions": "ไม่มีการกระทำใดที่ย้อนกลับไม่ได้",
"undoCopySuccess": "ยกเลิกการคัดลอก: ลบไฟล์ที่คัดลอกไว้ {{count}} ไฟล์", "undoCopySuccess": "ยกเลิกการคัดลอก: ลบไฟล์ที่คัดลอก {{count}} ไฟล์",
"undoCopyFailedDelete": "การยกเลิกการกระทำล้มเหลว: ไม่สามารถลบไฟล์ที่คัดลอกไว้ได้", "undoCopyFailedDelete": "การยกเลิกการกระทำล้มเหลว: ไม่สามารถลบไฟล์ที่คัดลอกไว้ได้",
"undoCopyFailedNoInfo": "การยกเลิกการกระทำล้มเหลว: ไม่พบข้อมูลไฟล์ที่คัดลอกไว้", "undoCopyFailedNoInfo": "การยกเลิกการกระทำล้มเหลว: ไม่พบข้อมูลไฟล์ที่คัดลอกไว้",
"undoMoveSuccess": "ยกเลิกการย้าย: ย้ายไฟล์ {{count}} ไฟล์กลับไปยังตำแหน่งเดิม", "undoMoveSuccess": "ยกเลิกการย้าย: ย้ายไฟล์ {{count}} ไฟล์กลับไปยังตำแหน่งเดิม",
@@ -1490,25 +1490,25 @@
"startTyping": "เริ่มพิมพ์...", "startTyping": "เริ่มพิมพ์...",
"unknownSize": "ขนาดไม่ทราบแน่ชัด", "unknownSize": "ขนาดไม่ทราบแน่ชัด",
"fileIsEmpty": "ไฟล์ว่างเปล่า", "fileIsEmpty": "ไฟล์ว่างเปล่า",
"largeFileWarning": "คำเตือนไฟล์ขนาดใหญ่", "largeFileWarning": "คำเตือนเกี่ยวกับไฟล์ขนาดใหญ่",
"largeFileWarningDesc": "ไฟล์นี้มีขนาด {{size}} ซึ่งอาจทำให้เกิดปัญหาด้านประสิทธิภาพเมื่อเปิดเป็นข้อความ", "largeFileWarningDesc": "ไฟล์นี้มีขนาด {{size}} ซึ่งอาจทำให้เกิดปัญหาด้านประสิทธิภาพเมื่อเปิดเป็นข้อความ",
"fileNotFoundAndRemoved": "ไม่พบไฟล์ \"{{name}}\" และไฟล์ดังกล่าวถูกลบออกจากไฟล์ล่าสุด/ไฟล์ปักหมุดแล้ว", "fileNotFoundAndRemoved": "ไม่พบไฟล์ \"{{name}}\" และไฟล์ดังกล่าวถูกลบออกจากไฟล์ล่าสุด/ไฟล์ปักหมุดแล้ว",
"failedToLoadFile": "ไม่สามารถโหลดไฟล์ได้: {{error}}", "failedToLoadFile": "ไม่สามารถโหลดไฟล์ได้: {{error}}",
"serverErrorOccurred": "เกิดข้อผิดพลาดของเซิร์ฟเวอร์ โปรดลองใหม่อีกครั้งในภายหลัง", "serverErrorOccurred": "เกิดข้อผิดพลาดของเซิร์ฟเวอร์ โปรดลองใหม่อีกครั้งในภายหลัง",
"autoSaveFailed": "การบันทึกอัตโนมัติล้มเหลว", "autoSaveFailed": "การบันทึกอัตโนมัติล้มเหลว",
"fileAutoSaved": "ไฟล์ถูกบันทึกอัตโนมัติ", "fileAutoSaved": "ไฟล์ถูกบันทึกอัตโนมัติ",
"moveFileFailed": "ไม่สามารย้าย {{name}} ได้", "moveFileFailed": "ารย้ายล้มเหลว {{name}}",
"moveOperationFailed": "การดำเนินการย้ายล้มเหลว", "moveOperationFailed": "การดำเนินการย้ายล้มเหลว",
"canOnlyCompareFiles": "สามารถเปรียบเทียบไฟล์ได้เพียงสองไฟล์เท่านั้น", "canOnlyCompareFiles": "สามารถเปรียบเทียบไฟล์ได้เพียงสองไฟล์เท่านั้น",
"comparingFiles": "การเปรียบเทียบไฟล์: {{file1}} และ {{file2}}", "comparingFiles": "เปรียบเทียบไฟล์: {{file1}} และ {{file2}}",
"dragFailed": "การดำเนินการลากล้มเหลว", "dragFailed": "การดำเนินการลากล้มเหลว",
"filePinnedSuccessfully": "ไฟล์ \"{{name}}\" ถูกตรึงสำเร็จแล้ว", "filePinnedSuccessfully": "ไฟล์ \"{{name}}\" ถูกปักหมุดสำเร็จแล้ว",
"pinFileFailed": "ไม่สามารถตรึงไฟล์ได้", "pinFileFailed": "ไม่สามารถตรึงไฟล์ได้",
"fileUnpinnedSuccessfully": "ไฟล์ \"{{name}}\" ปลดตรึงสำเร็จแล้ว", "fileUnpinnedSuccessfully": "ไฟล์ \"{{name}}\" ถูกยกเลิกการตรึงเรียบร้อยแล้ว",
"unpinFileFailed": "ไม่สามารถยกเลิกการตรึงไฟล์ได้", "unpinFileFailed": "ไม่สามารถยกเลิกการตรึงไฟล์ได้",
"shortcutAddedSuccessfully": "เพิ่มทางลัดโฟลเดอร์ \"{{name}}\" สำเร็จแล้ว", "shortcutAddedSuccessfully": "เพิ่มทางลัดโฟลเดอร์ \"{{name}}\" สำเร็จแล้ว",
"addShortcutFailed": "ไม่สามารถเพิ่มทางลัดได้", "addShortcutFailed": "ไม่สามารถเพิ่มทางลัดได้",
"operationCompletedSuccessfully": "สำเร็จ {{operation}} {{count}} รายการ", "operationCompletedSuccessfully": "{{operation}} {{count}} รายการสำเร็จ",
"operationCompleted": "{{operation}} {{count}} รายการ", "operationCompleted": "{{operation}} {{count}} รายการ",
"downloadFileSuccess": "ดาวน์โหลดไฟล์ {{name}} สำเร็จแล้ว", "downloadFileSuccess": "ดาวน์โหลดไฟล์ {{name}} สำเร็จแล้ว",
"downloadFileFailed": "การดาวน์โหลดล้มเหลว", "downloadFileFailed": "การดาวน์โหลดล้มเหลว",
@@ -1517,7 +1517,7 @@
"dragOutsideToDownload": "ลากออกนอกหน้าต่างเพื่อดาวน์โหลดไฟล์ ({{count}} ไฟล์)", "dragOutsideToDownload": "ลากออกนอกหน้าต่างเพื่อดาวน์โหลดไฟล์ ({{count}} ไฟล์)",
"newFolderDefault": "โฟลเดอร์ใหม่", "newFolderDefault": "โฟลเดอร์ใหม่",
"newFileDefault": "ไฟล์ใหม่.txt", "newFileDefault": "ไฟล์ใหม่.txt",
"successfullyMovedItems": "ย้ายรายการ {{count}} รายการไปยัง {{target}} สำเร็จแล้ว", "successfullyMovedItems": "ย้ายรายการ {{count}} รายการไปยัง {{target}}สำเร็จแล้ว",
"move": "เคลื่อนไหว", "move": "เคลื่อนไหว",
"searchInFile": "ค้นหาในไฟล์ (Ctrl+F)", "searchInFile": "ค้นหาในไฟล์ (Ctrl+F)",
"showKeyboardShortcuts": "แสดงทางลัดแป้นพิมพ์", "showKeyboardShortcuts": "แสดงทางลัดแป้นพิมพ์",
@@ -1554,7 +1554,7 @@
"tunnels": { "tunnels": {
"title": "อุโมงค์ SSH", "title": "อุโมงค์ SSH",
"noSshTunnels": "ไม่มีอุโมงค์ SSH", "noSshTunnels": "ไม่มีอุโมงค์ SSH",
"createFirstTunnelMessage": "คุณยังไม่ได้สร้างอุโมงค์ SSH ใดๆ เลย ตั้งค่าการเชื่อมต่ออุโมงค์ใน Host Manager เพื่อเริ่มต้นใช้งาน", "createFirstTunnelMessage": "คุณยังไม่ได้สร้างอุโมงค์ SSH ใดๆ เลย กำหนดค่าการเชื่อมต่ออุโมงค์ใน Host Manager เพื่อเริ่มต้นใช้งาน",
"connected": "เชื่อมต่อแล้ว", "connected": "เชื่อมต่อแล้ว",
"disconnected": "ตัดการเชื่อมต่อ", "disconnected": "ตัดการเชื่อมต่อ",
"connecting": "กำลังเชื่อมต่อ...", "connecting": "กำลังเชื่อมต่อ...",
@@ -1573,10 +1573,10 @@
"disconnect": "ตัดการเชื่อมต่อ", "disconnect": "ตัดการเชื่อมต่อ",
"cancel": "ยกเลิก", "cancel": "ยกเลิก",
"port": "ท่าเรือ", "port": "ท่าเรือ",
"attempt": "ความพยายาม {{current}} จาก {{max}}", "attempt": "ความพยายาม {{current}} ของ {{max}}",
"nextRetryIn": "ลองใหม่อีกครั้งใน {{seconds}} วินาที", "nextRetryIn": "ลองใหม่อีกครั้งใน {{seconds}} วินาที",
"checkDockerLogs": "ตรวจสอบบันทึก Docker ของคุณเพื่อดูสาเหตุของข้อผิดพลาด เข้าร่วมกลุ่มสนทนา", "checkDockerLogs": "ตรวจสอบบันทึก Docker ของคุณเพื่อดูสาเหตุของข้อผิดพลาด เข้าร่วมกลุ่มสนทนา",
"orCreate": "หรือสร้าง", "orCreate": "หรือสร้าง ",
"noTunnelConnections": "ไม่มีการกำหนดค่าการเชื่อมต่ออุโมงค์", "noTunnelConnections": "ไม่มีการกำหนดค่าการเชื่อมต่ออุโมงค์",
"tunnelConnections": "การเชื่อมต่ออุโมงค์", "tunnelConnections": "การเชื่อมต่ออุโมงค์",
"addTunnel": "เพิ่มอุโมงค์", "addTunnel": "เพิ่มอุโมงค์",
@@ -1624,8 +1624,8 @@
"refreshStatus": "รีเฟรชสถานะ", "refreshStatus": "รีเฟรชสถานะ",
"fileManagerAlreadyOpen": "โปรแกรมจัดการไฟล์เปิดใช้งานอยู่แล้วสำหรับโฮสต์นี้", "fileManagerAlreadyOpen": "โปรแกรมจัดการไฟล์เปิดใช้งานอยู่แล้วสำหรับโฮสต์นี้",
"openFileManager": "เปิดตัวจัดการไฟล์", "openFileManager": "เปิดตัวจัดการไฟล์",
"cpuCores_one": "ซีพียู {{count}}", "cpuCores_one": "{{count}} ซีพียู",
"cpuCores_other": "ซีพียู {{count}}", "cpuCores_other": "{{count}} ซีพียู",
"naCpus": "ไม่มีข้อมูล CPU", "naCpus": "ไม่มีข้อมูล CPU",
"loadAverageNA": "ค่าเฉลี่ย: ไม่มีข้อมูล", "loadAverageNA": "ค่าเฉลี่ย: ไม่มีข้อมูล",
"cpuUsage": "การใช้งาน CPU", "cpuUsage": "การใช้งาน CPU",
@@ -1682,7 +1682,7 @@
"executingQuickAction": "กำลังดำเนินการ {{name}}...", "executingQuickAction": "กำลังดำเนินการ {{name}}...",
"quickActionSuccess": "{{name}} เสร็จสมบูรณ์เรียบร้อยแล้ว", "quickActionSuccess": "{{name}} เสร็จสมบูรณ์เรียบร้อยแล้ว",
"quickActionFailed": "{{name}} ล้มเหลว", "quickActionFailed": "{{name}} ล้มเหลว",
"quickActionError": "ไม่สามารถดำเนินการ {{name}} ได้" "quickActionError": "ไม่สามารถดำเนินการ {{name}}ได้"
}, },
"auth": { "auth": {
"tagline": "ตัวจัดการเซิร์ฟเวอร์ SSH", "tagline": "ตัวจัดการเซิร์ฟเวอร์ SSH",
@@ -1733,7 +1733,7 @@
"disableTwoFactorWarning": "การปิดใช้งานการยืนยันตัวตนสองขั้นตอนจะทำให้บัญชีของคุณมีความปลอดภัยน้อยลง", "disableTwoFactorWarning": "การปิดใช้งานการยืนยันตัวตนสองขั้นตอนจะทำให้บัญชีของคุณมีความปลอดภัยน้อยลง",
"passwordOrTotpCode": "รหัสผ่านหรือรหัส TOTP", "passwordOrTotpCode": "รหัสผ่านหรือรหัส TOTP",
"or": "หรือ", "or": "หรือ",
"generateNewBackupCodesText": "สร้างรหัสสำรองใหม่หากคุณทำรหัสสำรองเดิมหาย", "generateNewBackupCodesText": "หากคุณทำรหัสสำรองเดิมหาย ให้สร้างรหัสสำรองใหม่",
"generateNewBackupCodes": "สร้างรหัสสำรองข้อมูลใหม่", "generateNewBackupCodes": "สร้างรหัสสำรองข้อมูลใหม่",
"yourBackupCodes": "รหัสสำรองข้อมูลของคุณ", "yourBackupCodes": "รหัสสำรองข้อมูลของคุณ",
"download": "ดาวน์โหลด", "download": "ดาวน์โหลด",
@@ -1830,14 +1830,14 @@
"saveSuccess": "บันทึกสำเร็จแล้ว", "saveSuccess": "บันทึกสำเร็จแล้ว",
"saveError": "บันทึกไม่สำเร็จ", "saveError": "บันทึกไม่สำเร็จ",
"deleteSuccess": "ลบสำเร็จแล้ว", "deleteSuccess": "ลบสำเร็จแล้ว",
"deleteError": "ไม่สามารถลบได้", "deleteError": "ลบไม่สำเร็จ",
"updateSuccess": "อัปเดตสำเร็จแล้ว", "updateSuccess": "อัปเดตสำเร็จแล้ว",
"updateError": "การอัปเดตล้มเหลว", "updateError": "การอัปเดตล้มเหลว",
"copySuccess": "คัดลอกไปยังคลิปบอร์ดแล้ว", "copySuccess": "คัดลอกไปยังคลิปบอร์ดแล้ว",
"copyError": "การคัดลอกล้มเหลว", "copyError": "การคัดลอกล้มเหลว",
"copiedToClipboard": "{{item}} คัดลอกไปยังคลิปบอร์ด", "copiedToClipboard": "{{item}} คัดลอกไปยังคลิปบอร์ดแล้ว",
"connectionEstablished": "การเชื่อมต่อสำเร็จแล้ว", "connectionEstablished": "การเชื่อมต่อสำเร็จแล้ว",
"connectionClosed": "การเชื่อมต่อถูกตัด", "connectionClosed": "การเชื่อมต่อถูกปิด",
"reconnecting": "กำลังเชื่อมต่อใหม่...", "reconnecting": "กำลังเชื่อมต่อใหม่...",
"processing": "กำลังประมวลผล...", "processing": "กำลังประมวลผล...",
"pleaseWait": "โปรดรอ...", "pleaseWait": "โปรดรอ...",
@@ -1957,7 +1957,7 @@
"failedToMakeUserAdmin": "ไม่สามารถทำให้ผู้ใช้เป็นผู้ดูแลระบบได้", "failedToMakeUserAdmin": "ไม่สามารถทำให้ผู้ใช้เป็นผู้ดูแลระบบได้",
"userIsNowAdmin": "ผู้ใช้ {{username}} ตอนนี้เป็นผู้ดูแลระบบแล้ว", "userIsNowAdmin": "ผู้ใช้ {{username}} ตอนนี้เป็นผู้ดูแลระบบแล้ว",
"removeAdminConfirm": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะผู้ดูแลระบบออกจาก {{username}}?", "removeAdminConfirm": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะผู้ดูแลระบบออกจาก {{username}}?",
"deleteUserConfirm": "คุณแน่ใจหรือไม่ว่าต้องการลบผู้ใช้ {{username}}? การกระทำนี้ไม่สามารถยกเลิกได้", "deleteUserConfirm": "คุณแน่ใจหรือไม่ว่าต้องการลบผู้ใช้ {{username}}การกระทำนี้ไม่สามารถยกเลิกได้",
"deleteAccount": "ลบบัญชีผู้ใช้", "deleteAccount": "ลบบัญชีผู้ใช้",
"closeDeleteAccount": "ปิด ลบ บัญชี", "closeDeleteAccount": "ปิด ลบ บัญชี",
"deleteAccountWarning": "การกระทำนี้ไม่สามารถย้อนกลับได้ การดำเนินการนี้จะลบบัญชีของคุณและข้อมูลที่เกี่ยวข้องทั้งหมดอย่างถาวร", "deleteAccountWarning": "การกระทำนี้ไม่สามารถย้อนกลับได้ การดำเนินการนี้จะลบบัญชีของคุณและข้อมูลที่เกี่ยวข้องทั้งหมดอย่างถาวร",
@@ -2150,7 +2150,7 @@
"accessCount": "จำนวนการเข้าชม", "accessCount": "จำนวนการเข้าชม",
"revokeAccess": "เพิกถอนสิทธิ์การเข้าถึง", "revokeAccess": "เพิกถอนสิทธิ์การเข้าถึง",
"confirmRevokeAccess": "คุณแน่ใจหรือไม่ว่าต้องการเพิกถอนสิทธิ์การเข้าถึงสำหรับ {{username}}?", "confirmRevokeAccess": "คุณแน่ใจหรือไม่ว่าต้องการเพิกถอนสิทธิ์การเข้าถึงสำหรับ {{username}}?",
"hostSharedSuccessfully": "แชร์โฮสต์สำเร็จแล้วกับ {{username}}", "hostSharedSuccessfully": "แชร์โฮสต์สำเร็จแล้วด้วย {{username}}",
"hostAccessUpdated": "การเข้าถึงโฮสต์ได้รับการอัปเดตแล้ว", "hostAccessUpdated": "การเข้าถึงโฮสต์ได้รับการอัปเดตแล้ว",
"failedToShareHost": "ไม่สามารถแชร์โฮสต์ได้", "failedToShareHost": "ไม่สามารถแชร์โฮสต์ได้",
"accessRevokedSuccessfully": "สิทธิ์การเข้าถึงถูกยกเลิกเรียบร้อยแล้ว", "accessRevokedSuccessfully": "สิทธิ์การเข้าถึงถูกยกเลิกเรียบร้อยแล้ว",
@@ -2170,7 +2170,7 @@
"timesAccessed": "{{count}} ครั้ง", "timesAccessed": "{{count}} ครั้ง",
"daysRemaining": "{{days}} วัน", "daysRemaining": "{{days}} วัน",
"hoursRemaining": "{{hours}} ชั่วโมง", "hoursRemaining": "{{hours}} ชั่วโมง",
"failedToFetchAccessList": "ไม่สามารถดึงรายการการเข้าถึงได้", "failedToFetchAccessList": "ไม่สามารถดึงรายการสิทธิ์การเข้าถึงได้",
"currentAccess": "การเข้าถึงปัจจุบัน", "currentAccess": "การเข้าถึงปัจจุบัน",
"securityWarning": "คำเตือนด้านความปลอดภัย", "securityWarning": "คำเตือนด้านความปลอดภัย",
"securityWarningMessage": "การแชร์ข้อมูลประจำตัวจะทำให้ผู้ใช้มีสิทธิ์เข้าถึงและดำเนินการใดๆ บนเซิร์ฟเวอร์ได้อย่างเต็มที่ รวมถึงการเปลี่ยนรหัสผ่านและการลบไฟล์ ควรแชร์เฉพาะกับผู้ใช้ที่ไว้ใจได้เท่านั้น", "securityWarningMessage": "การแชร์ข้อมูลประจำตัวจะทำให้ผู้ใช้มีสิทธิ์เข้าถึงและดำเนินการใดๆ บนเซิร์ฟเวอร์ได้อย่างเต็มที่ รวมถึงการเปลี่ยนรหัสผ่านและการลบไฟล์ ควรแชร์เฉพาะกับผู้ใช้ที่ไว้ใจได้เท่านั้น",
@@ -2184,15 +2184,15 @@
"permissions": "สิทธิ์การเข้าถึง", "permissions": "สิทธิ์การเข้าถึง",
"systemRole": "บทบาทของระบบ", "systemRole": "บทบาทของระบบ",
"customRole": "บทบาทที่กำหนดเอง", "customRole": "บทบาทที่กำหนดเอง",
"roleAssignedSuccessfully": "บทบาทได้รับการมอบหมายให้กับ {{username}} เรียบร้อยแล้ว", "roleAssignedSuccessfully": "บทบาทได้รับการมอบหมายให้กับ {{username}} สำเร็จแล้ว",
"failedToAssignRole": "ไม่สามารถกำหนดบทบาทได้", "failedToAssignRole": "ไม่สามารถกำหนดบทบาทได้",
"roleRemovedSuccessfully": "บทบาทถูกลบออกจาก {{username}} สำเร็จแล้ว", "roleRemovedSuccessfully": "ลบบทบาทออกจาก {{username}} สำเร็จแล้ว",
"failedToRemoveRole": "ไม่สามารถลบบทบาทได้", "failedToRemoveRole": "ไม่สามารถลบบทบาทได้",
"cannotRemoveSystemRole": "ไม่สามารถลบบทบาทระบบได้", "cannotRemoveSystemRole": "ไม่สามารถลบบทบาทระบบได้",
"cannotShareWithSelf": "ไม่สามารถแชร์โฮสต์กับตัวเองได้", "cannotShareWithSelf": "ไม่สามารถแชร์โฮสต์กับตัวเองได้",
"noCustomRolesToAssign": "ไม่มีบทบาทที่กำหนดเองได้ บทบาทของระบบจะถูกกำหนดโดยอัตโนมัติ", "noCustomRolesToAssign": "ไม่มีบทบาทที่กำหนดเองได้ บทบาทของระบบจะถูกกำหนดโดยอัตโนมัติ",
"credentialSharingWarning": "ไม่รองรับการตรวจสอบสิทธิ์ด้วยข้อมูลประจำตัวสำหรับการแชร์", "credentialSharingWarning": "ไม่รองรับการตรวจสอบสิทธิ์ด้วยข้อมูลประจำตัวสำหรับการแชร์",
"credentialRequired": "จำเป็นต้องระบุข้อมูลประจำตัวเมื่อแชร์โฮสต์", "credentialRequired": "จำเป็นต้องระบุข้อมูลรับรองเมื่อแชร์โฮสต์",
"credentialRequiredDescription": "โฮสต์นี้ไม่ได้ใช้การตรวจสอบสิทธิ์แบบใช้ข้อมูลประจำตัว เพื่อให้สามารถแชร์โฮสต์ได้ เนื่องจากมีการเข้ารหัสแบบต่อผู้ใช้ โฮสต์จึงต้องใช้การตรวจสอบสิทธิ์แบบใช้ข้อมูลประจำตัว", "credentialRequiredDescription": "โฮสต์นี้ไม่ได้ใช้การตรวจสอบสิทธิ์แบบใช้ข้อมูลประจำตัว เพื่อให้สามารถแชร์โฮสต์ได้ เนื่องจากมีการเข้ารหัสแบบต่อผู้ใช้ โฮสต์จึงต้องใช้การตรวจสอบสิทธิ์แบบใช้ข้อมูลประจำตัว",
"auditLogs": "บันทึกการตรวจสอบ", "auditLogs": "บันทึกการตรวจสอบ",
"viewAuditLogs": "ดูบันทึกการตรวจสอบ", "viewAuditLogs": "ดูบันทึกการตรวจสอบ",
@@ -2214,7 +2214,7 @@
"terminateSession": "ยุติเซสชัน", "terminateSession": "ยุติเซสชัน",
"sessionTerminated": "เซสชันถูกยุติโดยเจ้าของโฮสต์", "sessionTerminated": "เซสชันถูกยุติโดยเจ้าของโฮสต์",
"sharedAccessExpired": "สิทธิ์การเข้าถึงแบบแชร์ของคุณไปยังโฮสต์นี้หมดอายุแล้ว", "sharedAccessExpired": "สิทธิ์การเข้าถึงแบบแชร์ของคุณไปยังโฮสต์นี้หมดอายุแล้ว",
"sharedAccessExpiresIn": "สิทธิ์การเข้าถึงแบบใช้ร่วมกันจะหมดอายุในอีก {{hours}} ชั่วโมง", "sharedAccessExpiresIn": "สิทธิ์การเข้าถึงแบบแชร์จะหมดอายุในอีก {{hours}} ชั่วโมง",
"roles": { "roles": {
"label": "บทบาท", "label": "บทบาท",
"admin": "ผู้ดูแลระบบ", "admin": "ผู้ดูแลระบบ",
@@ -2249,7 +2249,7 @@
"displayNamePlaceholder": "นักพัฒนา", "displayNamePlaceholder": "นักพัฒนา",
"descriptionPlaceholder": "นักพัฒนาซอฟต์แวร์และวิศวกร", "descriptionPlaceholder": "นักพัฒนาซอฟต์แวร์และวิศวกร",
"confirmDeleteRole": "ลบบทบาท", "confirmDeleteRole": "ลบบทบาท",
"confirmDeleteRoleDescription": "คุณแน่ใจหรือไม่ว่าต้องการลบบทบาท &{{name}}&apos? การกระทำนี้ไม่สามารถยกเลิกได้", "confirmDeleteRoleDescription": "คุณแน่ใจหรือไม่ว่าต้องการลบบทบาท '{{name}}'? การกระทำนี้ไม่สามารถยกเลิกได้",
"confirmRemoveRole": "ลบบทบาท", "confirmRemoveRole": "ลบบทบาท",
"confirmRemoveRoleDescription": "คุณแน่ใจหรือไม่ว่าต้องการลบสิทธิ์นี้ออกจากผู้ใช้?", "confirmRemoveRoleDescription": "คุณแน่ใจหรือไม่ว่าต้องการลบสิทธิ์นี้ออกจากผู้ใช้?",
"editRoleDescription": "อัปเดตข้อมูลบทบาท", "editRoleDescription": "อัปเดตข้อมูลบทบาท",
@@ -2310,16 +2310,16 @@
"errorCode": "รหัสข้อผิดพลาด: {{code}}", "errorCode": "รหัสข้อผิดพลาด: {{code}}",
"version": "ด็อกเกอร์ {{version}}", "version": "ด็อกเกอร์ {{version}}",
"containerStarted": "คอนเทนเนอร์ {{name}} เริ่มทำงานแล้ว", "containerStarted": "คอนเทนเนอร์ {{name}} เริ่มทำงานแล้ว",
"failedToStartContainer": "ไม่สามารถเริ่มต้นคอนเทนเนอร์ {{name}} ได้", "failedToStartContainer": "ไม่สามารถเริ่มต้นคอนเทนเนอร์ได้ {{name}}",
"containerStopped": "คอนเทนเนอร์ {{name}} หยุดทำงานแล้ว", "containerStopped": "คอนเทนเนอร์ {{name}} หยุดทำงานแล้ว",
"failedToStopContainer": "ไม่สามารถหยุดคอนเทนเนอร์ {{name}} ได้", "failedToStopContainer": "ไม่สามารถหยุดคอนเทนเนอร์ได้ {{name}}",
"containerRestarted": "คอนเทนเนอร์ {{name}} รีสตาร์ทแล้ว", "containerRestarted": "คอนเทนเนอร์ {{name}} รีสตาร์ทแล้ว",
"failedToRestartContainer": "ไม่สามารถรีสตาร์ทคอนเทนเนอร์ {{name}}", "failedToRestartContainer": "ไม่สามารถรีสตาร์ทคอนเทนเนอร์ได้ {{name}}",
"containerPaused": "คอนเทนเนอร์ {{name}} หยุดชั่วคราว", "containerPaused": "คอนเทนเนอร์ {{name}} หยุดชั่วคราว",
"containerUnpaused": "คอนเทนเนอร์ {{name}} ยกเลิกการหยุดชั่วคราว", "containerUnpaused": "คอนเทนเนอร์ {{name}} ยกเลิกการหยุดชั่วคราว",
"failedToTogglePauseContainer": "ไม่สามารถสลับสถานะหยุดชั่วคราวสำหรับคอนเทนเนอร์ {{name}} ได้", "failedToTogglePauseContainer": "ไม่สามารถสลับสถานะหยุดชั่วคราวสำหรับคอนเทนเนอร์ {{name}}ได้",
"containerRemoved": "คอนเทนเนอร์ {{name}} ถูกลบออกแล้ว", "containerRemoved": "คอนเทนเนอร์ {{name}} ถูกลบออกแล้ว",
"failedToRemoveContainer": "ไม่สามารถลบคอนเทนเนอร์ {{name}} ได้", "failedToRemoveContainer": "ไม่สามารถลบคอนเทนเนอร์ {{name}}ได้",
"image": "ภาพ", "image": "ภาพ",
"idLabel": "รหัสประจำตัว", "idLabel": "รหัสประจำตัว",
"ports": "ท่าเรือ", "ports": "ท่าเรือ",
@@ -2332,7 +2332,7 @@
"restart": "เริ่มใหม่", "restart": "เริ่มใหม่",
"remove": "ลบ", "remove": "ลบ",
"removeContainer": "นำภาชนะออก", "removeContainer": "นำภาชนะออก",
"confirmRemoveContainer": "คุณแน่ใจหรือไม่ว่าต้องการลบคอนเทนเนอร์ &{{name}}'? การกระทำนี้ไม่สามารถย้อนกลับได้", "confirmRemoveContainer": "คุณแน่ใจหรือไม่ว่าต้องการลบคอนเทนเนอร์ '{{name}}'? การกระทำนี้ไม่สามารถย้อนกลับได้",
"runningContainerWarning": "คำเตือน: ขณะนี้คอนเทนเนอร์นี้กำลังทำงานอยู่ การลบคอนเทนเนอร์นี้จะหยุดการทำงานของคอนเทนเนอร์ก่อน", "runningContainerWarning": "คำเตือน: ขณะนี้คอนเทนเนอร์นี้กำลังทำงานอยู่ การลบคอนเทนเนอร์นี้จะหยุดการทำงานของคอนเทนเนอร์ก่อน",
"removing": "กำลังลบ...", "removing": "กำลังลบ...",
"loadingContainers": "กำลังขนถ่ายตู้คอนเทนเนอร์...", "loadingContainers": "กำลังขนถ่ายตู้คอนเทนเนอร์...",
@@ -2368,7 +2368,7 @@
"id": "รหัสประจำตัว", "id": "รหัสประจำตัว",
"state": "สถานะ", "state": "สถานะ",
"disconnectedFromContainer": "ตัดการเชื่อมต่อจากคอนเทนเนอร์", "disconnectedFromContainer": "ตัดการเชื่อมต่อจากคอนเทนเนอร์",
"containerMustBeRunning": "ต้องเปิดใช้งานคอนเทนเนอร์ก่อนจึงจะสามารถเข้าถึงคอนโซลได้", "containerMustBeRunning": "ต้องรอให้คอนเทนเนอร์ทำงานอยู่จึงจะสามารถเข้าถึงคอนโซลได้",
"authenticationRequired": "จำเป็นต้องยืนยันตัวตน", "authenticationRequired": "จำเป็นต้องยืนยันตัวตน",
"verificationCodePrompt": "ป้อนรหัสยืนยัน", "verificationCodePrompt": "ป้อนรหัสยืนยัน",
"totpVerificationFailed": "การตรวจสอบ TOTP ล้มเหลว โปรดลองอีกครั้ง", "totpVerificationFailed": "การตรวจสอบ TOTP ล้มเหลว โปรดลองอีกครั้ง",
@@ -2399,4 +2399,4 @@
"switchToLight": "เปลี่ยนเป็นโหมดสว่าง", "switchToLight": "เปลี่ยนเป็นโหมดสว่าง",
"switchToDark": "เปลี่ยนเป็นโหมดมืด" "switchToDark": "เปลี่ยนเป็นโหมดมืด"
} }
} }

View File

@@ -28,7 +28,7 @@
"failedToFetchCredentials": "Kimlik bilgilerini alma işlemi başarısız oldu.", "failedToFetchCredentials": "Kimlik bilgilerini alma işlemi başarısız oldu.",
"credentialDeletedSuccessfully": "Kimlik bilgileri başarıyla silindi.", "credentialDeletedSuccessfully": "Kimlik bilgileri başarıyla silindi.",
"failedToDeleteCredential": "Kimlik bilgilerini silme işlemi başarısız oldu.", "failedToDeleteCredential": "Kimlik bilgilerini silme işlemi başarısız oldu.",
"confirmDeleteCredential": "\"{{name}}\" kimlik bilgisini silmek istediğinizden emin misiniz?", "confirmDeleteCredential": "\"{{name}}\" kimlik bilgilerini silmek istediğinizden emin misiniz?",
"credentialCreatedSuccessfully": "Kimlik doğrulama başarıyla oluşturuldu.", "credentialCreatedSuccessfully": "Kimlik doğrulama başarıyla oluşturuldu.",
"credentialUpdatedSuccessfully": "Kimlik bilgileri başarıyla güncellendi.", "credentialUpdatedSuccessfully": "Kimlik bilgileri başarıyla güncellendi.",
"failedToSaveCredential": "Kimlik bilgilerini kaydetme başarısız oldu.", "failedToSaveCredential": "Kimlik bilgilerini kaydetme başarısız oldu.",
@@ -36,14 +36,14 @@
"failedToFetchHostsUsing": "Bu kimlik bilgileri kullanılarak sunucular alınamadı.", "failedToFetchHostsUsing": "Bu kimlik bilgileri kullanılarak sunucular alınamadı.",
"loadingCredentials": "Kimlik bilgileri yükleniyor...", "loadingCredentials": "Kimlik bilgileri yükleniyor...",
"retry": "Tekrar dene", "retry": "Tekrar dene",
"noCredentials": "Kimlik Bilgisi Yok", "noCredentials": "Kimlik bilgileri yok",
"noCredentialsMessage": "Henüz herhangi bir kimlik bilgisi eklemediniz. Başlamak için \"Kimlik Bilgisi Ekle\"ye tıklayın.", "noCredentialsMessage": "Henüz herhangi bir kimlik bilgisi eklemediniz. Başlamak için \"Kimlik Bilgisi Ekle\"ye tıklayın.",
"sshCredentials": "SSH Kimlik Bilgileri", "sshCredentials": "SSH Kimlik Bilgileri",
"credentialsCount": "{{count}} kimlik bilgileri", "credentialsCount": "{{count}} kimlik bilgileri",
"refresh": "Yenile", "refresh": "Yenile",
"passwordRequired": "Şifre gereklidir.", "passwordRequired": "Şifre gereklidir.",
"sshKeyRequired": "SSH anahtarı gereklidir.", "sshKeyRequired": "SSH anahtarı gereklidir.",
"credentialAddedSuccessfully": "Kimlik bilgisi \"{{name}}\" başarıyla eklendi.", "credentialAddedSuccessfully": "Kimlik bilgisi \"{{name}}\" başarıyla eklendi",
"general": "Genel", "general": "Genel",
"description": "Tanım", "description": "Tanım",
"folder": "Dosya", "folder": "Dosya",
@@ -137,11 +137,11 @@
"folderView": "Klasörler", "folderView": "Klasörler",
"unknownCredential": "Bilinmiyor", "unknownCredential": "Bilinmiyor",
"confirmRemoveFromFolder": "\"{{name}}\" öğesini \"{{folder}}\" klasöründen kaldırmak istediğinizden emin misiniz? Kimlik bilgisi \"Kategorilenmemiş\" bölümüne taşınacaktır.", "confirmRemoveFromFolder": "\"{{name}}\" öğesini \"{{folder}}\" klasöründen kaldırmak istediğinizden emin misiniz? Kimlik bilgisi \"Kategorilenmemiş\" bölümüne taşınacaktır.",
"removedFromFolder": "Kimlik bilgisi \"{{name}}\" klasörden başarıyla kaldırıldı.", "removedFromFolder": "\"{{name}}\" kimlik bilgisi klasörden başarıyla kaldırıldı.",
"failedToRemoveFromFolder": "Klasörden kimlik bilgilerini kaldırma işlemi başarısız oldu.", "failedToRemoveFromFolder": "Klasörden kimlik bilgilerini kaldırma işlemi başarısız oldu.",
"folderRenamed": "\"{{oldName}}\" klasörü başarıyla \"{{newName}}\" olarak yeniden adlandırıldı.", "folderRenamed": "\"{{oldName}}\" klasörü başarıyla \"{{newName}}\" olarak yeniden adlandırıldı.",
"failedToRenameFolder": "Klasörü yeniden adlandırma başarısız oldu.", "failedToRenameFolder": "Klasörü yeniden adlandırma başarısız oldu.",
"movedToFolder": "Kimlik bilgisi \"{{name}}\" başarıyla \"{{folder}}\"'a taşındı.", "movedToFolder": "Kimlik bilgisi \"{{name}}\" başarıyla \"{{folder}}\" konumuna taşındı",
"failedToMoveToFolder": "Kimlik bilgilerini klasöre taşıma işlemi başarısız oldu.", "failedToMoveToFolder": "Kimlik bilgilerini klasöre taşıma işlemi başarısız oldu.",
"sshPublicKey": "SSH Genel Anahtarı", "sshPublicKey": "SSH Genel Anahtarı",
"publicKeyNote": "Herkese açık anahtar isteğe bağlıdır ancak anahtar doğrulaması için önerilir.", "publicKeyNote": "Herkese açık anahtar isteğe bağlıdır ancak anahtar doğrulaması için önerilir.",
@@ -186,11 +186,11 @@
}, },
"dragIndicator": { "dragIndicator": {
"error": "Hata: {{error}}", "error": "Hata: {{error}}",
"dragging": "{{fileName}} Sürükleme", "dragging": "Sürükleme {{fileName}}",
"preparing": "{{fileName}}hazırlamak", "preparing": "{{fileName}}hazırlanıyor",
"readySingle": "İndirmeye hazır {{fileName}}", "readySingle": "İndirmeye hazır {{fileName}}",
"readyMultiple": "{{count}} dosyayı indirmeye hazır", "readyMultiple": "{{count}} dosyaları indirmeye hazır",
"batchDrag": "{{count}} dosyayı masaüstüne sürükleyin", "batchDrag": "{{count}} dosyaları masaüstüne sürükleyin",
"dragToDesktop": "Masaüstüne sürükleyin", "dragToDesktop": "Masaüstüne sürükleyin",
"canDragAnywhere": "Dosyaları masaüstünüzde istediğiniz yere sürükleyebilirsiniz." "canDragAnywhere": "Dosyaları masaüstünüzde istediğiniz yere sürükleyebilirsiniz."
}, },
@@ -202,12 +202,12 @@
"stopKeyRecording": "Tuş Kaydını Durdur", "stopKeyRecording": "Tuş Kaydını Durdur",
"selectTerminals": "Terminalleri seçin:", "selectTerminals": "Terminalleri seçin:",
"typeCommands": "Komutları yazın (tüm tuşlar desteklenir):", "typeCommands": "Komutları yazın (tüm tuşlar desteklenir):",
"commandsWillBeSent": "Komutlar seçilen {{count}} terminale gönderilecektir.", "commandsWillBeSent": "Komutlar {{count}} seçili terminale gönderilecektir.",
"settings": "Ayarlar", "settings": "Ayarlar",
"enableRightClickCopyPaste": "Sağ tıklama ile kopyala/yapıştır özelliğini etkinleştirin.", "enableRightClickCopyPaste": "Sağ tıklama ile kopyala/yapıştır özelliğini etkinleştirin.",
"shareIdeas": "SSH araçları için sırada ne olması gerektiğine dair fikirleriniz var mı? Bunları paylaşın.", "shareIdeas": "SSH araçları için sırada ne olması gerektiğine dair fikirleriniz var mı? Bunları paylaşın.",
"scripts": { "scripts": {
"inputPlaceholder": "Örneğin, Sistem Komutları, Docker Komut Dosyaları" "inputPlaceholder": "Örneğin, Sistem Komutları, Docker Betikleri"
} }
}, },
"snippets": { "snippets": {
@@ -230,7 +230,7 @@
"createDescription": "Hızlı çalıştırma için yeni bir komut parçacığı oluşturun.", "createDescription": "Hızlı çalıştırma için yeni bir komut parçacığı oluşturun.",
"editDescription": "Bu komut parçasını düzenleyin", "editDescription": "Bu komut parçasını düzenleyin",
"deleteConfirmTitle": "Kod parçasını sil", "deleteConfirmTitle": "Kod parçasını sil",
"deleteConfirmDescription": "\"{{name}}\"u silmek istediğinizden emin misiniz?", "deleteConfirmDescription": "\"{{name}}\" ifadesini silmek istediğinizden emin misiniz?",
"createSuccess": "Kod parçası başarıyla oluşturuldu.", "createSuccess": "Kod parçası başarıyla oluşturuldu.",
"updateSuccess": "Kod parçası başarıyla güncellendi.", "updateSuccess": "Kod parçası başarıyla güncellendi.",
"deleteSuccess": "Kod parçası başarıyla silindi.", "deleteSuccess": "Kod parçası başarıyla silindi.",
@@ -248,7 +248,7 @@
"reorderSameFolder": "Yalnızca aynı klasör içindeki kod parçacıklarının sırasını değiştirebilirsiniz.", "reorderSameFolder": "Yalnızca aynı klasör içindeki kod parçacıklarının sırasını değiştirebilirsiniz.",
"reorderSuccess": "Parçacıkların sıralaması başarıyla değiştirildi.", "reorderSuccess": "Parçacıkların sıralaması başarıyla değiştirildi.",
"reorderFailed": "Kod parçacıklarının yeniden sıralanması başarısız oldu.", "reorderFailed": "Kod parçacıklarının yeniden sıralanması başarısız oldu.",
"deleteFolderConfirm": "\"{{name}}\" klasörünü silmek mi istiyorsunuz? Tüm parçalar Kategorilenmemiş'e taşınacak.", "deleteFolderConfirm": "\"{{name}}\" klasörünü silmek mi istiyorsunuz? Tüm parçalar Kategorilenmemiş klasörüne taşınacak.",
"deleteFolderSuccess": "Klasör başarıyla silindi.", "deleteFolderSuccess": "Klasör başarıyla silindi.",
"deleteFolderFailed": "Klasör silme işlemi başarısız oldu.", "deleteFolderFailed": "Klasör silme işlemi başarısız oldu.",
"updateFolderSuccess": "Klasör başarıyla güncellendi.", "updateFolderSuccess": "Klasör başarıyla güncellendi.",
@@ -256,7 +256,7 @@
"updateFolderFailed": "Klasör güncellemesi başarısız oldu.", "updateFolderFailed": "Klasör güncellemesi başarısız oldu.",
"createFolderFailed": "Klasör oluşturulamadı.", "createFolderFailed": "Klasör oluşturulamadı.",
"selectTerminals": "Terminalleri Seçin (isteğe bağlı)", "selectTerminals": "Terminalleri Seçin (isteğe bağlı)",
"executeOnSelected": "Seçilen {{count}} terminalde yürütülecektir.", "executeOnSelected": "{{count}} seçili terminalde yürütülecek",
"executeOnCurrent": "Geçerli terminalde çalıştır (birden fazlasını seçmek için tıklayın)", "executeOnCurrent": "Geçerli terminalde çalıştır (birden fazlasını seçmek için tıklayın)",
"folder": "Dosya", "folder": "Dosya",
"selectFolder": "Bir klasör seçin veya boş bırakın.", "selectFolder": "Bir klasör seçin veya boş bırakın.",
@@ -300,7 +300,7 @@
"dragTabsHint": "Sekmeleri aşağıdaki düzen hücrelerine sürükleyerek atayın.", "dragTabsHint": "Sekmeleri aşağıdaki düzen hücrelerine sürükleyerek atayın.",
"layout": "Bölünmüş Ekran Düzeni", "layout": "Bölünmüş Ekran Düzeni",
"dropHere": "Sekmeyi buraya bırakın.", "dropHere": "Sekmeyi buraya bırakın.",
"apply": "Bölünmüş Uygula", "apply": "Split uygulayın",
"clear": "Clear Split", "clear": "Clear Split",
"selectMode": "Bölünmüş ekran modunu seçin", "selectMode": "Bölünmüş ekran modunu seçin",
"helpText": "Aynı anda kaç sekme görüntülemek istediğinizi seçin.", "helpText": "Aynı anda kaç sekme görüntülemek istediğinizi seçin.",
@@ -308,7 +308,7 @@
"cleared": "Bölünmüş ekran temizlendi", "cleared": "Bölünmüş ekran temizlendi",
"error": { "error": {
"noAssignments": "Lütfen düzene en az bir sekme atayın.", "noAssignments": "Lütfen düzene en az bir sekme atayın.",
"fillAllSlots": "Başvurmadan önce lütfen tüm {{count}} boşluğu doldurun." "fillAllSlots": "Başvurmadan önce lütfen tüm {{count}} boşlukları doldurun."
} }
}, },
"homepage": { "homepage": {
@@ -343,10 +343,10 @@
"error": "Sürüm Kontrol Hatası", "error": "Sürüm Kontrol Hatası",
"checkFailed": "Güncellemeleri kontrol etme başarısız oldu.", "checkFailed": "Güncellemeleri kontrol etme başarısız oldu.",
"upToDate": "Uygulama güncel.", "upToDate": "Uygulama güncel.",
"currentVersion": "Şu anda {{version}} sürümünü kullanıyorsunuz.", "currentVersion": "Şu anda {{version}}sürümünü çalıştırıyorsunuz.",
"updateAvailable": "Güncelleme Mevcut", "updateAvailable": "Güncelleme Mevcut",
"newVersionAvailable": "Yeni bir sürüm mevcut! Şu anda {{current}} sürümünü kullanıyorsunuz, ancak {{latest}} sürümü de mevcut.", "newVersionAvailable": "Yeni bir sürüm mevcut! Şu anda {{current}}çalıştırıyorsunuz, ancak {{latest}} kullanılabilir durumda.",
"releasedOn": "{{date}} tarihinde yayınlandı", "releasedOn": "{{date}}tarihinde yayınlandı",
"downloadUpdate": "Güncellemeyi İndir", "downloadUpdate": "Güncellemeyi İndir",
"dismiss": "Azletmek", "dismiss": "Azletmek",
"checking": "Güncellemeler kontrol ediliyor...", "checking": "Güncellemeler kontrol ediliyor...",
@@ -391,12 +391,12 @@
"dragToResizeSidebar": "Kenar çubuğunu yeniden boyutlandırmak için sürükleyin.", "dragToResizeSidebar": "Kenar çubuğunu yeniden boyutlandırmak için sürükleyin.",
"noAuthCredentials": "Bu SSH sunucusu için kullanılabilir kimlik doğrulama bilgisi bulunmamaktadır.", "noAuthCredentials": "Bu SSH sunucusu için kullanılabilir kimlik doğrulama bilgisi bulunmamaktadır.",
"noReleases": "Yayın Yok", "noReleases": "Yayın Yok",
"updatesAndReleases": "Güncellemeler ve Sürümler", "updatesAndReleases": "Güncellemeler ve Yayınlar",
"newVersionAvailable": "Yeni bir sürüm ({{version}}) mevcuttur.", "newVersionAvailable": "Yeni bir sürüm ({{version}}) mevcuttur.",
"failedToFetchUpdateInfo": "Güncelleme bilgilerini alma işlemi başarısız oldu.", "failedToFetchUpdateInfo": "Güncelleme bilgilerini alma işlemi başarısız oldu.",
"preRelease": "Ön yayın", "preRelease": "Ön yayın",
"loginFailed": "giriş başarısız oldu", "loginFailed": "giriş başarısız oldu",
"noReleasesFound": "Yayınlanmış hiçbir içerik bulunamadı.", "noReleasesFound": "Yayınlanmış hiçbir dosya bulunamadı.",
"yourBackupCodes": "Yedekleme Kodlarınız", "yourBackupCodes": "Yedekleme Kodlarınız",
"sendResetCode": "Sıfırlama kodunu gönder", "sendResetCode": "Sıfırlama kodunu gönder",
"verifyCode": "Kodu Doğrula", "verifyCode": "Kodu Doğrula",
@@ -498,18 +498,18 @@
"userManagement": "Kullanıcı Yönetimi", "userManagement": "Kullanıcı Yönetimi",
"makeAdmin": "Yönetici Yap", "makeAdmin": "Yönetici Yap",
"removeAdmin": "Yöneticiyi Kaldır", "removeAdmin": "Yöneticiyi Kaldır",
"deleteUser": "Kullanıcı {{username}} silinsin mi? Bu işlem geri alınamaz.", "deleteUser": "Kullanıcı {{username}}silinsin mi? Bu işlem geri alınamaz.",
"allowRegistration": "Kayıt işlemine izin ver", "allowRegistration": "Kayıt işlemine izin ver",
"oidcSettings": "OIDC Ayarları", "oidcSettings": "OIDC Ayarları",
"clientId": "Müşteri Kimliği", "clientId": "Müşteri Kimliği",
"clientSecret": "Müşteri Sırrı", "clientSecret": "Müşteri Gizli Bilgileri",
"issuerUrl": "Yayıncı URL'si", "issuerUrl": "Yayıncı URL'si",
"authorizationUrl": "Yetkilendirme URL'si", "authorizationUrl": "Yetkilendirme URL'si",
"tokenUrl": "Token URL", "tokenUrl": "Token URL",
"updateSettings": "Ayarları Güncelle", "updateSettings": "Ayarları Güncelle",
"confirmDelete": "Bu kullanıcıyı silmek istediğinizden emin misiniz?", "confirmDelete": "Bu kullanıcıyı silmek istediğinizden emin misiniz?",
"confirmMakeAdmin": "{{username}}'yı yönetici yapmak istediğinizden emin misiniz?", "confirmMakeAdmin": "{{username}} 'ı yönetici yapmak istediğinizden emin misiniz?",
"confirmRemoveAdmin": "{{username}}'den yönetici statüsünü kaldırmak istediğinizden emin misiniz?", "confirmRemoveAdmin": "{{username}}'dan yönetici statüsünü kaldırmak istediğinizden emin misiniz?",
"externalAuthentication": "Harici Kimlik Doğrulama (OIDC)", "externalAuthentication": "Harici Kimlik Doğrulama (OIDC)",
"configureExternalProvider": "OIDC/OAuth2 kimlik doğrulaması için harici kimlik sağlayıcısını yapılandırın.", "configureExternalProvider": "OIDC/OAuth2 kimlik doğrulaması için harici kimlik sağlayıcısını yapılandırın.",
"userIdentifierPath": "Kullanıcı Tanımlayıcı Yolu", "userIdentifierPath": "Kullanıcı Tanımlayıcı Yolu",
@@ -549,10 +549,10 @@
"enterUsernameToMakeAdmin": "Yönetici yapmak için kullanıcı adınızı girin.", "enterUsernameToMakeAdmin": "Yönetici yapmak için kullanıcı adınızı girin.",
"userIsNowAdmin": "Kullanıcı {{username}} artık yöneticidir.", "userIsNowAdmin": "Kullanıcı {{username}} artık yöneticidir.",
"failedToMakeUserAdmin": "Kullanıcıyı yönetici yapma işlemi başarısız oldu.", "failedToMakeUserAdmin": "Kullanıcıyı yönetici yapma işlemi başarısız oldu.",
"removeAdminStatus": "{{username}}'tan yönetici statüsünü kaldır?", "removeAdminStatus": "{{username}}'dan yönetici statüsünü kaldır?",
"adminStatusRemoved": "Yönetici statüsü {{username}}'den kaldırıldı.", "adminStatusRemoved": "Yönetici statüsü {{username}}adresinden kaldırıldı.",
"failedToRemoveAdminStatus": "Yönetici statüsünü kaldırma işlemi başarısız oldu.", "failedToRemoveAdminStatus": "Yönetici statüsünü kaldırma işlemi başarısız oldu.",
"userDeletedSuccessfully": "Kullanıcı {{username}} başarıyla silindi.", "userDeletedSuccessfully": "Kullanıcı {{username}} başarıyla silindi",
"failedToDeleteUser": "Kullanıcı silme işlemi başarısız oldu.", "failedToDeleteUser": "Kullanıcı silme işlemi başarısız oldu.",
"overrideUserInfoUrl": "Kullanıcı Bilgisi URL'sini Geçersiz Kıl (gerekli değil)", "overrideUserInfoUrl": "Kullanıcı Bilgisi URL'sini Geçersiz Kıl (gerekli değil)",
"failedToFetchSessions": "Oturumları alma işlemi başarısız oldu.", "failedToFetchSessions": "Oturumları alma işlemi başarısız oldu.",
@@ -564,12 +564,12 @@
"sessionsRevokedSuccessfully": "Oturumlar başarıyla iptal edildi.", "sessionsRevokedSuccessfully": "Oturumlar başarıyla iptal edildi.",
"linkToPasswordAccount": "Parola Hesabına Bağlantı", "linkToPasswordAccount": "Parola Hesabına Bağlantı",
"linkOIDCDialogTitle": "OIDC Hesabını Parola Hesabına Bağla", "linkOIDCDialogTitle": "OIDC Hesabını Parola Hesabına Bağla",
"linkOIDCDialogDescription": "{{username}} (OIDC kullanıcısı)'nı mevcut bir parola hesabına bağlayın. Bu, parola hesabı için çift kimlik doğrulamayı etkinleştirecektir.", "linkOIDCDialogDescription": "{{username}} (OIDC kullanıcısı) öğesini mevcut bir parola hesabına bağlayın. Bu, parola hesabı için çift kimlik doğrulamayı etkinleştirecektir.",
"createUser": "Kullanıcı Oluştur", "createUser": "Kullanıcı Oluştur",
"createUserDescription": "Kullanıcı adı ve şifre ile yeni bir yerel kullanıcı oluşturun.", "createUserDescription": "Kullanıcı adı ve şifre ile yeni bir yerel kullanıcı oluşturun.",
"enterUsername": "Kullanıcı adınızı girin", "enterUsername": "Kullanıcı adınızı girin",
"enterPassword": "Şifrenizi girin", "enterPassword": "Şifrenizi girin",
"userCreatedSuccessfully": "Kullanıcı {{username}} başarıyla oluşturuldu.", "userCreatedSuccessfully": "Kullanıcı {{username}} başarıyla oluşturuldu",
"failedToCreateUser": "Kullanıcı oluşturulamadı.", "failedToCreateUser": "Kullanıcı oluşturulamadı.",
"manageUser": "Kullanıcıyı Yönet", "manageUser": "Kullanıcıyı Yönet",
"manageUserDescription": "Kullanıcı ayarlarını, rollerini ve izinlerini yönetin.", "manageUserDescription": "Kullanıcı ayarlarını, rollerini ve izinlerini yönetin.",
@@ -584,7 +584,7 @@
"passwordResetWarning": "Bir kullanıcının parolasını sıfırlamak, tüm verilerini (SSH sunucuları, kimlik bilgileri, ayarlar) silecektir. Bu işlem geri alınamaz.", "passwordResetWarning": "Bir kullanıcının parolasını sıfırlamak, tüm verilerini (SSH sunucuları, kimlik bilgileri, ayarlar) silecektir. Bu işlem geri alınamaz.",
"resetUserPassword": "Kullanıcı Parolasını Sıfırla", "resetUserPassword": "Kullanıcı Parolasını Sıfırla",
"resettingPassword": "Sıfırlanıyor...", "resettingPassword": "Sıfırlanıyor...",
"passwordResetInitiated": "{{username}} için parola sıfırlama işlemi başlatıldı. Sıfırlama kodu gönderildi.", "passwordResetInitiated": "{{username}}için parola sıfırlama işlemi başlatıldı. Sıfırlama kodu gönderildi.",
"failedToResetPassword": "Parola sıfırlama işlemi başlatılamadı.", "failedToResetPassword": "Parola sıfırlama işlemi başlatılamadı.",
"sessionManagement": "Oturum Yönetimi", "sessionManagement": "Oturum Yönetimi",
"revokeAllSessions": "Tüm Oturumları İptal Et", "revokeAllSessions": "Tüm Oturumları İptal Et",
@@ -611,12 +611,12 @@
"linkTargetUsernamePlaceholder": "Kullanıcı adınızı ve şifrenizi girin.", "linkTargetUsernamePlaceholder": "Kullanıcı adınızı ve şifrenizi girin.",
"linkAccountsButton": "Hesapları Bağla", "linkAccountsButton": "Hesapları Bağla",
"linkingAccounts": "Bağlantı kuruluyor...", "linkingAccounts": "Bağlantı kuruluyor...",
"accountsLinkedSuccessfully": "OIDC kullanıcısı {{oidcUsername}}, {{targetUsername}} ile ilişkilendirilmiştir.", "accountsLinkedSuccessfully": "OIDC kullanıcısı {{oidcUsername}} , {{targetUsername}}ile ilişkilendirildi.",
"failedToLinkAccounts": "Hesapları bağlama başarısız oldu.", "failedToLinkAccounts": "Hesapları bağlama başarısız oldu.",
"linkTargetUsernameRequired": "Hedef kullanıcı adı gereklidir.", "linkTargetUsernameRequired": "Hedef kullanıcı adı gereklidir.",
"unlinkOIDCTitle": "OIDC Kimlik Doğrulamasını Kaldır", "unlinkOIDCTitle": "OIDC Kimlik Doğrulamasını Kaldır",
"unlinkOIDCDescription": "{{username}}'den OIDC kimlik doğrulamasını kaldır? Kullanıcı bundan sonra yalnızca kullanıcı adı/şifre ile giriş yapabilecektir.", "unlinkOIDCDescription": "{{username}}'dan OIDC kimlik doğrulamasını kaldır? Bundan sonra kullanıcı yalnızca kullanıcı adı/şifre ile giriş yapabilecektir.",
"unlinkOIDCSuccess": "OIDC, {{username}}'dan bağlantısı kesildi.", "unlinkOIDCSuccess": "OIDC bağlantısı {{username}}adresinden kaldırıldı.",
"failedToUnlinkOIDC": "OIDC bağlantısını kaldırma işlemi başarısız oldu.", "failedToUnlinkOIDC": "OIDC bağlantısını kaldırma işlemi başarısız oldu.",
"databaseSecurity": "Veritabanı Güvenliği", "databaseSecurity": "Veritabanı Güvenliği",
"encryptionStatus": "Şifreleme Durumu", "encryptionStatus": "Şifreleme Durumu",
@@ -710,7 +710,7 @@
"databaseImportedSuccessfully": "SQLite veritabanı başarıyla içe aktarıldı", "databaseImportedSuccessfully": "SQLite veritabanı başarıyla içe aktarıldı",
"databaseImportFailed": "SQLite veritabanı içe aktarma işlemi başarısız oldu.", "databaseImportFailed": "SQLite veritabanı içe aktarma işlemi başarısız oldu.",
"manageEncryptionAndBackups": "Şifreleme anahtarlarını, veritabanı güvenliğini ve yedekleme işlemlerini yönetin.", "manageEncryptionAndBackups": "Şifreleme anahtarlarını, veritabanı güvenliğini ve yedekleme işlemlerini yönetin.",
"activeSecurityFeatures": "Şu anda aktif olan güvenlik önlemleri ve korumalar", "activeSecurityFeatures": "Şu anda aktif olan güvenlik önlemleri ve koruma yöntemleri",
"deviceBindingTechnology": "Gelişmiş donanım tabanlı anahtar koruma teknolojisi", "deviceBindingTechnology": "Gelişmiş donanım tabanlı anahtar koruma teknolojisi",
"backupAndRecovery": "Güvenli yedekleme oluşturma ve veritabanı kurtarma seçenekleri", "backupAndRecovery": "Güvenli yedekleme oluşturma ve veritabanı kurtarma seçenekleri",
"crossSystemDataTransfer": "Farklı sistemler arasında veritabanlarını dışa ve içe aktarma", "crossSystemDataTransfer": "Farklı sistemler arasında veritabanlarını dışa ve içe aktarma",
@@ -756,7 +756,7 @@
"revokeAllUserSessionsTitle": "Bu kullanıcıya ait tüm oturumları iptal et.", "revokeAllUserSessionsTitle": "Bu kullanıcıya ait tüm oturumları iptal et.",
"revokeAll": "Tümünü İptal Et", "revokeAll": "Tümünü İptal Et",
"linkOidcToPasswordAccount": "OIDC Hesabını Parola Hesabına Bağla", "linkOidcToPasswordAccount": "OIDC Hesabını Parola Hesabına Bağla",
"linkOidcToPasswordAccountDescription": "{{username}} (OIDC kullanıcısı)'nı mevcut bir parola hesabına bağlayın. Bu, parola hesabı için çift kimlik doğrulamayı etkinleştirecektir.", "linkOidcToPasswordAccountDescription": "{{username}} (OIDC kullanıcısı) öğesini mevcut bir parola hesabına bağlayın. Bu, parola hesabı için çift kimlik doğrulamayı etkinleştirecektir.",
"linkOidcWarningTitle": "Uyarı: OIDC Kullanıcı Verileri Silinecektir", "linkOidcWarningTitle": "Uyarı: OIDC Kullanıcı Verileri Silinecektir",
"linkOidcWarningDescription": "Bu işlem şunları sağlayacaktır:", "linkOidcWarningDescription": "Bu işlem şunları sağlayacaktır:",
"linkOidcActionDeleteUser": "OIDC kullanıcı hesabını ve tüm verilerini silin.", "linkOidcActionDeleteUser": "OIDC kullanıcı hesabını ve tüm verilerini silin.",
@@ -777,7 +777,7 @@
"retry": "Tekrar dene", "retry": "Tekrar dene",
"refresh": "Yenile", "refresh": "Yenile",
"optional": "İsteğe bağlı", "optional": "İsteğe bağlı",
"hostsCount": "{{count}} ev sahibi", "hostsCount": "{{count}} sunucular",
"importJson": "JSON'u içe aktar", "importJson": "JSON'u içe aktar",
"importing": "İçe aktarılıyor...", "importing": "İçe aktarılıyor...",
"importJsonTitle": "JSON dosyasından SSH sunucularını içe aktarın", "importJsonTitle": "JSON dosyasından SSH sunucularını içe aktarın",
@@ -790,7 +790,7 @@
"confirmDelete": "\"{{name}}\" öğesini silmek istediğinizden emin misiniz?", "confirmDelete": "\"{{name}}\" öğesini silmek istediğinizden emin misiniz?",
"failedToDeleteHost": "Sunucuyu silme işlemi başarısız oldu.", "failedToDeleteHost": "Sunucuyu silme işlemi başarısız oldu.",
"failedToExportHost": "Sunucu dışa aktarma işlemi başarısız oldu. Lütfen oturum açtığınızdan ve sunucu verilerine erişiminizin olduğundan emin olun.", "failedToExportHost": "Sunucu dışa aktarma işlemi başarısız oldu. Lütfen oturum açtığınızdan ve sunucu verilerine erişiminizin olduğundan emin olun.",
"jsonMustContainHosts": "JSON verisi bir \"hosts\" dizisi içermeli veya hosts dizisi olmalıdır.", "jsonMustContainHosts": "JSON dosyası bir \"hosts\" dizisi içermeli veya hosts dizisi olmalıdır.",
"noHostsInJson": "JSON dosyasında hiçbir sunucu bulunamadı.", "noHostsInJson": "JSON dosyasında hiçbir sunucu bulunamadı.",
"maxHostsAllowed": "İçe aktarma başına en fazla 100 sunucuya izin verilir.", "maxHostsAllowed": "İçe aktarma başına en fazla 100 sunucuya izin verilir.",
"importCompleted": "İçe aktarma tamamlandı: {{success}} başarılı, {{failed}} başarısız", "importCompleted": "İçe aktarma tamamlandı: {{success}} başarılı, {{failed}} başarısız",
@@ -811,14 +811,14 @@
"passwordRequired": "Parola tabanlı kimlik doğrulama kullanılırken parola gereklidir.", "passwordRequired": "Parola tabanlı kimlik doğrulama kullanılırken parola gereklidir.",
"sshKeyRequired": "Anahtar tabanlı kimlik doğrulama kullanılırken SSH özel anahtarı gereklidir.", "sshKeyRequired": "Anahtar tabanlı kimlik doğrulama kullanılırken SSH özel anahtarı gereklidir.",
"keyTypeRequired": "Anahtar tabanlı kimlik doğrulama kullanılırken Anahtar Türü gereklidir.", "keyTypeRequired": "Anahtar tabanlı kimlik doğrulama kullanılırken Anahtar Türü gereklidir.",
"mustSelectValidSshConfig": "Listeden geçerli bir SSH yapılandırması seçmelisiniz.", "mustSelectValidSshConfig": "Listeden geçerli bir SSH yapılandırması seçilmelidir.",
"addHost": "Sunucu Ekle", "addHost": "Sunucu Ekle",
"editHost": "Sunucuyu Düzenle", "editHost": "Sunucuyu Düzenle",
"cloneHost": "Klon Ana Bilgisayar", "cloneHost": "Klon Ana Bilgisayar",
"updateHost": "Sunucuyu Güncelle", "updateHost": "Sunucuyu Güncelle",
"hostUpdatedSuccessfully": "Sunucu \"{{name}}\" başarıyla güncellendi!", "hostUpdatedSuccessfully": "Sunucu \"{{name}}\" başarıyla güncellendi!",
"hostAddedSuccessfully": "Sunucu \"{{name}}\" başarıyla eklendi!", "hostAddedSuccessfully": "\"{{name}}\" sunucusu başarıyla eklendi!",
"hostDeletedSuccessfully": "Sunucu \"{{name}}\" başarıyla silindi!", "hostDeletedSuccessfully": "\"{{name}}\" sunucusu başarıyla silindi!",
"failedToSaveHost": "Sunucu kaydedilemedi. Lütfen tekrar deneyin.", "failedToSaveHost": "Sunucu kaydedilemedi. Lütfen tekrar deneyin.",
"savingHost": "Sunucuyu kaydediyorum...", "savingHost": "Sunucuyu kaydediyorum...",
"updatingHost": "Sunucu güncelleniyor...", "updatingHost": "Sunucu güncelleniyor...",
@@ -837,10 +837,10 @@
"connection": "Bağlantı", "connection": "Bağlantı",
"remove": "Kaldırmak", "remove": "Kaldırmak",
"sourcePort": "Kaynak Bağlantı Noktası", "sourcePort": "Kaynak Bağlantı Noktası",
"sourcePortDesc": "(Kaynak, Genel sekmesindeki Geçerli Bağlantı Ayrıntıları'na atıfta bulunmaktadır.)", "sourcePortDesc": " (Kaynak, Genel sekmesindeki Geçerli Bağlantı Ayrıntıları'na atıfta bulunmaktadır.)",
"endpointPort": "Uç Nokta Bağlantı Noktası", "endpointPort": "Uç Nokta Bağlantı Noktası",
"endpointSshConfig": "Uç Nokta SSH Yapılandırması", "endpointSshConfig": "Uç Nokta SSH Yapılandırması",
"tunnelForwardDescription": "Bu tünel, kaynak makinedeki {{sourcePort}} numaralı porttan (genel sekmesindeki mevcut bağlantı ayrıntıları) gelen trafiği uç nokta makinedeki {{endpointPort}} numaralı porta yönlendirecektir.", "tunnelForwardDescription": "Bu tünel, kaynak makinedeki {{sourcePort}} portundan (genel sekmesindeki mevcut bağlantı ayrıntıları) gelen trafiği uç nokta makinedeki {{endpointPort}} portuna yönlendirecektir.",
"maxRetries": "Maksimum Yeniden Deneme Sayısı", "maxRetries": "Maksimum Yeniden Deneme Sayısı",
"maxRetriesDescription": "Tünel bağlantısı için maksimum yeniden deneme sayısı.", "maxRetriesDescription": "Tünel bağlantısı için maksimum yeniden deneme sayısı.",
"retryInterval": "Tekrar Deneme Aralığı (saniye)", "retryInterval": "Tekrar Deneme Aralığı (saniye)",
@@ -916,8 +916,8 @@
"customCommandsDesc": "Bu sunucu için özel kapatma ve yeniden başlatma komutları tanımlayın.", "customCommandsDesc": "Bu sunucu için özel kapatma ve yeniden başlatma komutları tanımlayın.",
"shutdownCommand": "Kapatma Komutu", "shutdownCommand": "Kapatma Komutu",
"rebootCommand": "Yeniden Başlatma Komutu", "rebootCommand": "Yeniden Başlatma Komutu",
"confirmRemoveFromFolder": "\"{{name}}\" klasöründen \"{{folder}}\" öğesini kaldırmak istediğinizden emin misiniz? Sunucu \"Klasör Yok\" konumuna taşınacaktır.", "confirmRemoveFromFolder": "\"{{folder}}\" klasöründen \"{{name}}\" öğesini kaldırmak istediğinizden emin misiniz? Sunucu \"Klasör Yok\" konumuna taşınacaktır.",
"removedFromFolder": "Host \"{{name}}\" klasörden başarıyla kaldırıldı", "removedFromFolder": "\"{{name}}\" sunucusu klasörden başarıyla kaldırıldı",
"failedToRemoveFromFolder": "Ana bilgisayarı klasörden kaldırma işlemi başarısız oldu.", "failedToRemoveFromFolder": "Ana bilgisayarı klasörden kaldırma işlemi başarısız oldu.",
"folderRenamed": "\"{{oldName}}\" klasörü başarıyla \"{{newName}}\" olarak yeniden adlandırıldı.", "folderRenamed": "\"{{oldName}}\" klasörü başarıyla \"{{newName}}\" olarak yeniden adlandırıldı.",
"failedToRenameFolder": "Klasörü yeniden adlandırma başarısız oldu.", "failedToRenameFolder": "Klasörü yeniden adlandırma başarısız oldu.",
@@ -929,11 +929,11 @@
"folderAppearanceUpdated": "Klasör görünümü başarıyla güncellendi.", "folderAppearanceUpdated": "Klasör görünümü başarıyla güncellendi.",
"failedToUpdateFolderAppearance": "Klasör görünümünü güncelleme başarısız oldu.", "failedToUpdateFolderAppearance": "Klasör görünümünü güncelleme başarısız oldu.",
"deleteAllHostsInFolder": "Klasördeki Tüm Sunucuları Sil", "deleteAllHostsInFolder": "Klasördeki Tüm Sunucuları Sil",
"confirmDeleteAllHostsInFolder": "\"{{count}}\" klasöründeki tüm {{folder}} ana bilgisayarları silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.", "confirmDeleteAllHostsInFolder": "\"{{folder}}\" klasöründeki tüm {{count}} ana bilgisayarı silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.",
"allHostsInFolderDeleted": "\"{{count}}\" klasöründen {{folder}} ana bilgisayar başarıyla silindi.", "allHostsInFolderDeleted": "\"{{folder}}\" klasöründen \" {{count}} \" ana bilgisayar başarıyla silindi.",
"failedToDeleteHostsInFolder": "Klasördeki sunucuları silme işlemi başarısız oldu.", "failedToDeleteHostsInFolder": "Klasördeki sunucuları silme işlemi başarısız oldu.",
"movedToFolder": "Sunucu \"{{name}}\" başarıyla \"{{folder}}\" adresine taşındı.", "movedToFolder": "Sunucu \"{{name}}\" başarıyla \"{{folder}}\" adresine taşındı",
"failedToMoveToFolder": "Sunucuyu klasöre taşıma başarısız oldu.", "failedToMoveToFolder": "Sunucu klasöre taşınamadı.",
"clickToRenameFolder": "Klasörün adını değiştirmek için tıklayın.", "clickToRenameFolder": "Klasörün adını değiştirmek için tıklayın.",
"renameFolder": "Klasörü yeniden adlandır", "renameFolder": "Klasörü yeniden adlandır",
"removeFromFolder": "\"{{folder}}\" klasöründen kaldır", "removeFromFolder": "\"{{folder}}\" klasöründen kaldır",
@@ -943,7 +943,7 @@
"cloneHostTooltip": "Klon konak", "cloneHostTooltip": "Klon konak",
"clickToEditHost": "Sunucuyu düzenlemek için tıklayın", "clickToEditHost": "Sunucuyu düzenlemek için tıklayın",
"dragToMoveBetweenFolders": "Klasörler arasında geçiş yapmak için sürükleyin.", "dragToMoveBetweenFolders": "Klasörler arasında geçiş yapmak için sürükleyin.",
"exportedHostConfig": "{{name}} için dışa aktarılan ana bilgisayar yapılandırması", "exportedHostConfig": "{{name}}için dışa aktarılan ana bilgisayar yapılandırması",
"openTerminal": "Terminali açın", "openTerminal": "Terminali açın",
"openFileManager": "Dosya Yöneticisini Açın", "openFileManager": "Dosya Yöneticisini Açın",
"openTunnels": "Açık Tüneller", "openTunnels": "Açık Tüneller",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "Ses", "bellStyleSound": "Ses",
"bellStyleVisual": "Görsel", "bellStyleVisual": "Görsel",
"bellStyleBoth": "İkisi birden", "bellStyleBoth": "İkisi birden",
"bellStyleDesc": "Terminal zilini (BEL karakteri, \\x07) nasıl ele alacağınız aşağıda açıklanmıştır. Programlar, görevleri tamamladıklarında, hatalarla karşılaştıklarında veya bildirimler için bu zili tetikler. \"Sesli\" sesli bir bip sesi çalar, \"Görsel\" ekranı kısa süreliğine yanıp söndürür, \"Her ikisi\" hem sesli hem de görsel uyarı verir, \"Hiçbiri\" zil uyarılarını devre dışı bırakır.", "bellStyleDesc": "Terminal zilini (BEL karakteri, \\x07) nasıl ele alacağınız aşağıda açıklanmıştır. Programlar, görevleri tamamladıklarında, hatalarla karşılaştıklarında veya bildirimler için bu zili tetikler. \"Ses\" sesli bir bip sesi çıkarır, \"Görsel\" ekranı kısa süreliğine yanıp söndürür, \"Her ikisi\" hem sesli hem de görsel uyarı verir, \"Hiçbiri\" ise zil uyarılarını devre dışı bırakır.",
"rightClickSelectsWord": "Sağ Tıklama Word Seçer", "rightClickSelectsWord": "Sağ Tıklama Word Seçer",
"rightClickSelectsWordDesc": "Sağ tıklama, imlecin altındaki kelimeyi seçer.", "rightClickSelectsWordDesc": "Sağ tıklama, imlecin altındaki kelimeyi seçer.",
"fastScrollModifier": "Hızlı Kaydırma Değiştirici", "fastScrollModifier": "Hızlı Kaydırma Değiştirici",
@@ -1066,7 +1066,7 @@
"socks5UsePreset": "Kaydedilmiş Ön Ayarı Kullan", "socks5UsePreset": "Kaydedilmiş Ön Ayarı Kullan",
"socks5SelectPreset": "Ön ayarı seçin", "socks5SelectPreset": "Ön ayarı seçin",
"socks5ManagePresets": "Ön Ayarları Yönet", "socks5ManagePresets": "Ön Ayarları Yönet",
"socks5ProxyNode": "Vekil {{number}}", "socks5ProxyNode": "Proxy {{number}}",
"socks5AddProxy": "Zincire Proxy Ekle", "socks5AddProxy": "Zincire Proxy Ekle",
"socks5RemoveProxy": "Proxy'yi Kaldır", "socks5RemoveProxy": "Proxy'yi Kaldır",
"socks5ProxyType": "Vekil Türü", "socks5ProxyType": "Vekil Türü",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "Proxy zinciri ön ayarı oluşturuldu", "socks5PresetCreated": "Proxy zinciri ön ayarı oluşturuldu",
"socks5PresetUpdated": "Proxy zinciri ön ayarı güncellendi", "socks5PresetUpdated": "Proxy zinciri ön ayarı güncellendi",
"socks5PresetDeleted": "Proxy zinciri ön ayarı silindi", "socks5PresetDeleted": "Proxy zinciri ön ayarı silindi",
"socks5PresetSaved": "Ön ayar \"{{name}}\" başarıyla kaydedildi.", "socks5PresetSaved": "\"{{name}}\" ön ayarı başarıyla kaydedildi",
"socks5PresetSaveError": "Ön ayar kaydedilemedi.", "socks5PresetSaveError": "Ön ayar kaydedilemedi.",
"socks5PresetNameRequired": "Ön ayar adı gereklidir.", "socks5PresetNameRequired": "Ön ayar adı gereklidir.",
"socks5EmptyChainError": "Boş bir proxy zinciri kaydedilemiyor.", "socks5EmptyChainError": "Boş bir proxy zinciri kaydedilemiyor.",
@@ -1086,7 +1086,7 @@
"socks5HostDescription": "SOCKS proxy sunucusunun ana bilgisayar adı veya IP adresi", "socks5HostDescription": "SOCKS proxy sunucusunun ana bilgisayar adı veya IP adresi",
"socks5PortDescription": "SOCKS proxy sunucusunun port numarası (varsayılan: 1080)", "socks5PortDescription": "SOCKS proxy sunucusunun port numarası (varsayılan: 1080)",
"addProxyNode": "Proxy Düğümü Ekle", "addProxyNode": "Proxy Düğümü Ekle",
"noProxyNodes": "Hiçbir proxy düğümü yapılandırılmadı. Bir tane eklemek için 'Proxy Düğümü Ekle'ye tıklayın.", "noProxyNodes": "Hiçbir proxy düğümü yapılandırılmamış. Bir tane eklemek için 'Proxy Düğümü Ekle'ye tıklayın.",
"proxyNode": "Proxy Düğümü", "proxyNode": "Proxy Düğümü",
"proxyType": "Vekil Türü", "proxyType": "Vekil Türü",
"quickActions": "Hızlı İşlemler", "quickActions": "Hızlı İşlemler",
@@ -1133,7 +1133,7 @@
"console": "Konsol", "console": "Konsol",
"containerMustBeRunning": "Konsola bağlanabilmek için konteynerin çalışır durumda olması gerekir.", "containerMustBeRunning": "Konsola bağlanabilmek için konteynerin çalışır durumda olması gerekir.",
"authenticationRequired": "Kimlik doğrulama gereklidir.", "authenticationRequired": "Kimlik doğrulama gereklidir.",
"connectedTo": "{{containerName}} ile bağlantılı", "connectedTo": "{{containerName}}ile bağlantılı",
"disconnected": "Bağlantı kesildi", "disconnected": "Bağlantı kesildi",
"consoleError": "Konsol hatası", "consoleError": "Konsol hatası",
"errorMessage": "Hata: {{message}}", "errorMessage": "Hata: {{message}}",
@@ -1150,7 +1150,7 @@
"disconnect": "Bağlantıyı kes", "disconnect": "Bağlantıyı kes",
"notConnected": "Bağlı değil", "notConnected": "Bağlı değil",
"clickToConnect": "Etkileşimli bir kabuk başlatmak için Bağlan'a tıklayın.", "clickToConnect": "Etkileşimli bir kabuk başlatmak için Bağlan'a tıklayın.",
"connectingTo": "{{containerName}} ile bağlantı kuruluyor...", "connectingTo": "{{containerName}}ile bağlantı kuruluyor...",
"containerMustBeRunningToViewStats": "İstatistikleri görüntülemek için konteynerin çalışır durumda olması gerekir.", "containerMustBeRunningToViewStats": "İstatistikleri görüntülemek için konteynerin çalışır durumda olması gerekir.",
"failedToFetchStats": "İstatistikler alınamadı.", "failedToFetchStats": "İstatistikler alınamadı.",
"noContainersFound": "Hiçbir konteyner bulunamadı.", "noContainersFound": "Hiçbir konteyner bulunamadı.",
@@ -1163,13 +1163,13 @@
"noContainersMatchFiltersHint": "Arama veya filtre ayarlarınızı değiştirmeyi deneyin.", "noContainersMatchFiltersHint": "Arama veya filtre ayarlarınızı değiştirmeyi deneyin.",
"containerStarted": "Konteyner {{name}} başlatıldı", "containerStarted": "Konteyner {{name}} başlatıldı",
"failedToStartContainer": "Konteyner başlatılamadı: {{error}}", "failedToStartContainer": "Konteyner başlatılamadı: {{error}}",
"containerStopped": "Konteyner {{name}} durdu", "containerStopped": "Konteyner {{name}} durduruldu",
"failedToStopContainer": "Konteyner durdurulamadı: {{error}}", "failedToStopContainer": "Konteyner durdurulamadı: {{error}}",
"containerRestarted": "Konteyner {{name}} yeniden başlatıldı", "containerRestarted": "Konteyner {{name}} yeniden başlatıldı",
"failedToRestartContainer": "Konteyner yeniden başlatılamadı: {{error}}", "failedToRestartContainer": "Konteyner yeniden başlatılamadı: {{error}}",
"containerUnpaused": "Konteyner {{name}} duraklatılmadı", "containerUnpaused": "Konteyner {{name}} duraklatılmamış",
"containerPaused": "Konteyner {{name}} duraklatıldı", "containerPaused": "Konteyner {{name}} duraklatıldı",
"failedToTogglePauseContainer": "{{action}} konteynerine erişilemedi: {{error}}", "failedToTogglePauseContainer": "{{action}} konteynerine erişim başarısız oldu: {{error}}",
"containerRemoved": "Konteyner {{name}} kaldırıldı", "containerRemoved": "Konteyner {{name}} kaldırıldı",
"failedToRemoveContainer": "Konteyner kaldırılamadı: {{error}}", "failedToRemoveContainer": "Konteyner kaldırılamadı: {{error}}",
"image": "Resim:", "image": "Resim:",
@@ -1183,7 +1183,7 @@
"pause": "Duraklat", "pause": "Duraklat",
"restart": "Tekrar başlat", "restart": "Tekrar başlat",
"removeContainer": "Kabı çıkarın", "removeContainer": "Kabı çıkarın",
"confirmRemoveContainer": "\"{{name}}\" numaralı konteyneri kaldırmak istediğinizden emin misiniz?", "confirmRemoveContainer": "\"{{name}}\" kapsayıcısını kaldırmak istediğinizden emin misiniz?",
"runningContainerWarning": "Uyarı: Bu konteyner şu anda çalışıyor ve zorla kaldırılacaktır.", "runningContainerWarning": "Uyarı: Bu konteyner şu anda çalışıyor ve zorla kaldırılacaktır.",
"removing": "Kaldırılıyor:", "removing": "Kaldırılıyor:",
"containerNotFound": "Konteyner bulunamadı.", "containerNotFound": "Konteyner bulunamadı.",
@@ -1230,13 +1230,13 @@
"messageParseError": "Sunucu mesajı ayrıştırma işlemi başarısız oldu.", "messageParseError": "Sunucu mesajı ayrıştırma işlemi başarısız oldu.",
"websocketError": "WebSocket bağlantı hatası", "websocketError": "WebSocket bağlantı hatası",
"connecting": "Bağlanıyor...", "connecting": "Bağlanıyor...",
"reconnecting": "Yeniden bağlanıyor... ({{attempt}}/{{max}})", "reconnecting": "Yeniden bağlanılıyor... ({{attempt}}/{{max}})",
"reconnected": "Bağlantı başarıyla yeniden kuruldu.", "reconnected": "Bağlantı başarıyla yeniden kuruldu.",
"maxReconnectAttemptsReached": "Maksimum yeniden bağlantı deneme sayısına ulaşıldı.", "maxReconnectAttemptsReached": "Maksimum yeniden bağlantı deneme sayısına ulaşıldı.",
"connectionTimeout": "Bağlantı zaman aşımı", "connectionTimeout": "Bağlantı zaman aşımı",
"terminalTitle": "Terminal - {{host}}", "terminalTitle": "Terminal - {{host}}",
"terminalWithPath": "Terminal - {{host}}:{{path}}", "terminalWithPath": "Terminal - {{host}}:{{path}}",
"runTitle": "Koşu {{command}} - {{host}}", "runTitle": "Çalıştırılıyor {{command}} - {{host}}",
"totpRequired": "İki Faktörlü Kimlik Doğrulama Gerekli", "totpRequired": "İki Faktörlü Kimlik Doğrulama Gerekli",
"totpCodeLabel": "Doğrulama Kodu", "totpCodeLabel": "Doğrulama Kodu",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
@@ -1254,7 +1254,7 @@
"uploadFile": "Dosya Yükle", "uploadFile": "Dosya Yükle",
"downloadFile": "İndirmek", "downloadFile": "İndirmek",
"extractArchive": "Arşivden Çıkarma", "extractArchive": "Arşivden Çıkarma",
"extractingArchive": "{{name}} çıkarılıyor...", "extractingArchive": "{{name}}çıkarılıyor...",
"archiveExtractedSuccessfully": "{{name}} başarıyla çıkarıldı", "archiveExtractedSuccessfully": "{{name}} başarıyla çıkarıldı",
"extractFailed": ıkarma işlemi başarısız oldu.", "extractFailed": ıkarma işlemi başarısız oldu.",
"compressFile": "Dosyayı Sıkıştır", "compressFile": "Dosyayı Sıkıştır",
@@ -1266,7 +1266,7 @@
"selectedFiles": "Seçilen dosyalar", "selectedFiles": "Seçilen dosyalar",
"andMoreFiles": "ve {{count}} daha fazlası...", "andMoreFiles": "ve {{count}} daha fazlası...",
"compress": "Kompres", "compress": "Kompres",
"compressingFiles": "{{count}} öğeyi {{name}} öğeye sıkıştırılıyor...", "compressingFiles": "{{count}} öğeyi {{name}}öğeye sıkıştırılıyor...",
"filesCompressedSuccessfully": "{{name}} başarıyla oluşturuldu", "filesCompressedSuccessfully": "{{name}} başarıyla oluşturuldu",
"compressFailed": "Sıkıştırma başarısız oldu", "compressFailed": "Sıkıştırma başarısız oldu",
"edit": "Düzenlemek", "edit": "Düzenlemek",
@@ -1289,13 +1289,13 @@
"chooseFile": "Dosya Seç", "chooseFile": "Dosya Seç",
"uploading": "Yükleniyor...", "uploading": "Yükleniyor...",
"downloading": "İndiriliyor...", "downloading": "İndiriliyor...",
"uploadingFile": "{{name}} yükleniyor...", "uploadingFile": "{{name}}yükleniyor...",
"uploadingLargeFile": "Büyük dosya yükleniyor {{name}} ({{size}})...", "uploadingLargeFile": "Büyük dosya yükleniyor {{name}} ({{size}})...",
"downloadingFile": "{{name}} indiriliyor...", "downloadingFile": "{{name}}indiriliyor...",
"creatingFile": "{{name}} oluşturuluyor...", "creatingFile": "{{name}}oluşturuluyor...",
"creatingFolder": "{{name}} oluşturuluyor...", "creatingFolder": "{{name}}oluşturuluyor...",
"deletingItem": "{{type}} {{name}} siliniyor...", "deletingItem": "{{type}} {{name}}siliniyor...",
"renamingItem": "{{type}} {{oldName}} adını {{newName}} olarak yeniden adlandırma...", "renamingItem": "{{type}} {{oldName}} adını {{newName}}olarak yeniden adlandırma...",
"createNewFile": "Yeni Dosya Oluştur", "createNewFile": "Yeni Dosya Oluştur",
"fileName": "Dosya adı", "fileName": "Dosya adı",
"creating": "Oluşturuluyor...", "creating": "Oluşturuluyor...",
@@ -1311,18 +1311,18 @@
"newName": "Yeni İsim", "newName": "Yeni İsim",
"thisIsDirectoryRename": "Bu bir dizindir.", "thisIsDirectoryRename": "Bu bir dizindir.",
"renaming": "Yeniden adlandırılıyor...", "renaming": "Yeniden adlandırılıyor...",
"fileUploadedSuccessfully": "\"{{name}}\" dosyası başarıyla yüklendi.", "fileUploadedSuccessfully": "\"{{name}}\" dosyası başarıyla yüklendi",
"failedToUploadFile": "Dosya yükleme başarısız oldu.", "failedToUploadFile": "Dosya yükleme başarısız oldu.",
"fileDownloadedSuccessfully": "\"{{name}}\" dosyası başarıyla indirildi.", "fileDownloadedSuccessfully": "\"{{name}}\" dosyası başarıyla indirildi",
"failedToDownloadFile": "Dosya indirme başarısız oldu.", "failedToDownloadFile": "Dosya indirme başarısız oldu.",
"noFileContent": "Dosya içeriği alınamadı.", "noFileContent": "Dosya içeriği alınamadı.",
"filePath": "Dosya Yolu", "filePath": "Dosya Yolu",
"fileCreatedSuccessfully": "\"{{name}}\" dosyası başarıyla oluşturuldu.", "fileCreatedSuccessfully": "\"{{name}}\" dosyası başarıyla oluşturuldu",
"failedToCreateFile": "Dosya oluşturulamadı.", "failedToCreateFile": "Dosya oluşturulamadı.",
"folderCreatedSuccessfully": "\"{{name}}\" klasörü başarıyla oluşturuldu.", "folderCreatedSuccessfully": "\"{{name}}\" klasörü başarıyla oluşturuldu",
"failedToCreateFolder": "Klasör oluşturulamadı.", "failedToCreateFolder": "Klasör oluşturulamadı.",
"failedToCreateItem": "Öğe oluşturulamadı.", "failedToCreateItem": "Öğe oluşturulamadı.",
"operationFailed": "{{operation}} işlemi {{name}} için başarısız oldu: {{error}}", "operationFailed": "{{operation}} işlemi {{name}}için başarısız oldu: {{error}}",
"failedToResolveSymlink": "Sembolik bağlantı çözümlenemedi.", "failedToResolveSymlink": "Sembolik bağlantı çözümlenemedi.",
"itemDeletedSuccessfully": "{{type}} başarıyla silindi", "itemDeletedSuccessfully": "{{type}} başarıyla silindi",
"itemsDeletedSuccessfully": "{{count}} öğe başarıyla silindi", "itemsDeletedSuccessfully": "{{count}} öğe başarıyla silindi",
@@ -1354,7 +1354,7 @@
"filesCopiedToClipboard": "{{count}} öğe panoya kopyalandı", "filesCopiedToClipboard": "{{count}} öğe panoya kopyalandı",
"filesCutToClipboard": "{{count}} öğe panoya kopyalandı", "filesCutToClipboard": "{{count}} öğe panoya kopyalandı",
"pathCopiedToClipboard": "Yol panoya kopyalandı", "pathCopiedToClipboard": "Yol panoya kopyalandı",
"pathsCopiedToClipboard": "{{count}} yol panoya kopyalandı", "pathsCopiedToClipboard": "{{count}} yollar panoya kopyalandı",
"failedToCopyPath": "Yol kopyalanıp panoya aktarılamadı.", "failedToCopyPath": "Yol kopyalanıp panoya aktarılamadı.",
"movedItems": "{{count}} öğe taşındı", "movedItems": "{{count}} öğe taşındı",
"failedToDeleteItem": "Öğeyi silme işlemi başarısız oldu.", "failedToDeleteItem": "Öğeyi silme işlemi başarısız oldu.",
@@ -1365,7 +1365,7 @@
"size": "Boyut", "size": "Boyut",
"modified": "Değiştirildi", "modified": "Değiştirildi",
"path": "Yol", "path": "Yol",
"confirmDelete": "{{name}}'yı silmek istediğinizden emin misiniz?", "confirmDelete": "{{name}}'ı silmek istediğinizden emin misiniz?",
"uploadSuccess": "Dosya başarıyla yüklendi.", "uploadSuccess": "Dosya başarıyla yüklendi.",
"uploadFailed": "Dosya yükleme başarısız oldu", "uploadFailed": "Dosya yükleme başarısız oldu",
"downloadSuccess": "Dosya başarıyla indirildi.", "downloadSuccess": "Dosya başarıyla indirildi.",
@@ -1388,7 +1388,7 @@
"connectToServer": "Bir sunucuya bağlanın", "connectToServer": "Bir sunucuya bağlanın",
"selectServerToEdit": "Dosyaları düzenlemeye başlamak için kenar çubuğundan bir sunucu seçin.", "selectServerToEdit": "Dosyaları düzenlemeye başlamak için kenar çubuğundan bir sunucu seçin.",
"fileOperations": "Dosya İşlemleri", "fileOperations": "Dosya İşlemleri",
"confirmDeleteMessage": "{{name}}'yi silmek istediğinizden emin misiniz?", "confirmDeleteMessage": "{{name}}'ı silmek istediğinizden emin misiniz?",
"confirmDeleteSingleItem": "\"{{name}}\" öğesini kalıcı olarak silmek istediğinizden emin misiniz?", "confirmDeleteSingleItem": "\"{{name}}\" öğesini kalıcı olarak silmek istediğinizden emin misiniz?",
"confirmDeleteMultipleItems": "{{count}} öğeyi kalıcı olarak silmek istediğinizden emin misiniz?", "confirmDeleteMultipleItems": "{{count}} öğeyi kalıcı olarak silmek istediğinizden emin misiniz?",
"confirmDeleteMultipleItemsWithFolders": "{{count}} öğeyi kalıcı olarak silmek istediğinizden emin misiniz? Bu, klasörleri ve içeriklerini de içerir.", "confirmDeleteMultipleItemsWithFolders": "{{count}} öğeyi kalıcı olarak silmek istediğinizden emin misiniz? Bu, klasörleri ve içeriklerini de içerir.",
@@ -1422,7 +1422,7 @@
"openTerminalInFolder": "Bu klasörde terminali açın.", "openTerminalInFolder": "Bu klasörde terminali açın.",
"openTerminalInFileLocation": "Dosya konumunda terminali açın.", "openTerminalInFileLocation": "Dosya konumunda terminali açın.",
"terminalWithPath": "Terminal - {{host}}:{{path}}", "terminalWithPath": "Terminal - {{host}}:{{path}}",
"runningFile": "Koşu - {{file}}", "runningFile": "Koşuyor - {{file}}",
"onlyRunExecutableFiles": "Yalnızca çalıştırılabilir dosyaları çalıştırabilir.", "onlyRunExecutableFiles": "Yalnızca çalıştırılabilir dosyaları çalıştırabilir.",
"noHostSelected": "Sunucu seçilmedi.", "noHostSelected": "Sunucu seçilmedi.",
"starred": "Yıldızlı", "starred": "Yıldızlı",
@@ -1430,9 +1430,9 @@
"directories": "Dizinler", "directories": "Dizinler",
"removedFromRecentFiles": "Son dosyalardan \"{{name}}\" kaldırıldı.", "removedFromRecentFiles": "Son dosyalardan \"{{name}}\" kaldırıldı.",
"removeFailed": "Kaldırma işlemi başarısız oldu.", "removeFailed": "Kaldırma işlemi başarısız oldu.",
"unpinnedSuccessfully": "\"{{name}}\" başarıyla sabitlenmemiş", "unpinnedSuccessfully": "\"{{name}}\" başarıyla sabitlenmiş öğe kaldırıldı",
"unpinFailed": "Sabitlemeyi kaldırma başarısız oldu", "unpinFailed": "Sabitlemeyi kaldırma başarısız oldu",
"removedShortcut": "Kısayol kaldırıldı \"{{name}}\"", "removedShortcut": "\"{{name}}\" kısayolu kaldırıldı",
"removeShortcutFailed": "Kısayol kaldırma işlemi başarısız oldu.", "removeShortcutFailed": "Kısayol kaldırma işlemi başarısız oldu.",
"clearedAllRecentFiles": "Son kullanılan tüm dosyalar silindi.", "clearedAllRecentFiles": "Son kullanılan tüm dosyalar silindi.",
"clearFailed": "Temizleme başarısız oldu", "clearFailed": "Temizleme başarısız oldu",
@@ -1440,7 +1440,7 @@
"clearAllRecentFiles": "Son kullanılan tüm dosyaları temizle", "clearAllRecentFiles": "Son kullanılan tüm dosyaları temizle",
"unpinFile": "Dosyanın sabitlemesini kaldır", "unpinFile": "Dosyanın sabitlemesini kaldır",
"removeShortcut": "Kısayolu kaldır", "removeShortcut": "Kısayolu kaldır",
"saveFilesToSystem": "{{count}} dosyayı şu şekilde kaydet...", "saveFilesToSystem": "{{count}} dosyaları farklı kaydet...",
"pinFile": "Pin dosyası", "pinFile": "Pin dosyası",
"addToShortcuts": "Kısayollara ekle", "addToShortcuts": "Kısayollara ekle",
"downloadToDefaultLocation": "Varsayılan konuma indir", "downloadToDefaultLocation": "Varsayılan konuma indir",
@@ -1482,7 +1482,7 @@
"moveLineDown": "Satırı Aşağı Taşı", "moveLineDown": "Satırı Aşağı Taşı",
"toggleComment": "Yorumu Aç/Kapat", "toggleComment": "Yorumu Aç/Kapat",
"indent": "Girinti", "indent": "Girinti",
"outdent": "Girinti", "outdent": "Çıkıntı",
"autoComplete": "Otomatik Tamamlama", "autoComplete": "Otomatik Tamamlama",
"imageLoadError": "Görüntü yüklenemedi.", "imageLoadError": "Görüntü yüklenemedi.",
"rotate": "Döndür", "rotate": "Döndür",
@@ -1497,27 +1497,27 @@
"serverErrorOccurred": "Sunucu hatası oluştu. Lütfen daha sonra tekrar deneyin.", "serverErrorOccurred": "Sunucu hatası oluştu. Lütfen daha sonra tekrar deneyin.",
"autoSaveFailed": "Otomatik kaydetme başarısız oldu.", "autoSaveFailed": "Otomatik kaydetme başarısız oldu.",
"fileAutoSaved": "Dosya otomatik olarak kaydedildi", "fileAutoSaved": "Dosya otomatik olarak kaydedildi",
"moveFileFailed": "{{name}} taşınamadı", "moveFileFailed": "{{name}}taşınamadı",
"moveOperationFailed": "Taşıma işlemi başarısız oldu", "moveOperationFailed": "Taşıma işlemi başarısız oldu",
"canOnlyCompareFiles": "Yalnızca iki dosya karşılaştırılabilir.", "canOnlyCompareFiles": "Yalnızca iki dosya karşılaştırılabilir.",
"comparingFiles": "Dosyalar karşılaştırılıyor: {{file1}} ve {{file2}}", "comparingFiles": "Dosyaları karşılaştırma: {{file1}} ve {{file2}}",
"dragFailed": "Sürükleme işlemi başarısız oldu", "dragFailed": "Sürükleme işlemi başarısız oldu",
"filePinnedSuccessfully": "\"{{name}}\" dosyası başarıyla sabitlendi.", "filePinnedSuccessfully": "\"{{name}}\" dosyası başarıyla sabitlendi",
"pinFileFailed": "Dosyayı sabitleme başarısız oldu.", "pinFileFailed": "Dosyayı sabitleme başarısız oldu.",
"fileUnpinnedSuccessfully": "\"{{name}}\" dosyası başarıyla sabitlenmeden kaldırıldı.", "fileUnpinnedSuccessfully": "\"{{name}}\" dosyasının sabitlemesi başarıyla kaldırıldı.",
"unpinFileFailed": "Dosyanın sabitlemesi kaldırılamadı.", "unpinFileFailed": "Dosyanın sabitlemesi kaldırılamadı.",
"shortcutAddedSuccessfully": "Klasör kısayolu \"{{name}}\" başarıyla eklendi.", "shortcutAddedSuccessfully": "Klasör kısayolu \"{{name}}\" başarıyla eklendi",
"addShortcutFailed": "Kısayol ekleme başarısız oldu.", "addShortcutFailed": "Kısayol ekleme başarısız oldu.",
"operationCompletedSuccessfully": "{{operation}} {{count}} öğe başarıyla", "operationCompletedSuccessfully": "{{operation}} {{count}} öğe başarıyla",
"operationCompleted": "{{operation}} {{count}} öğe", "operationCompleted": "{{operation}} {{count}} öğeler",
"downloadFileSuccess": "{{name}} numaralı dosya başarıyla indirildi.", "downloadFileSuccess": "{{name}} dosyası başarıyla indirildi.",
"downloadFileFailed": "İndirme başarısız oldu", "downloadFileFailed": "İndirme başarısız oldu",
"moveTo": "{{name}}'e geçin", "moveTo": "{{name}}adresine geçin",
"diffCompareWith": "{{name}} ile karşılaştırın", "diffCompareWith": "{{name}}ile karşılaştırın",
"dragOutsideToDownload": "İndirmek için pencerenin dışına sürükleyin ({{count}} dosya)", "dragOutsideToDownload": "İndirmek için pencerenin dışına sürükleyin ({{count}} dosya)",
"newFolderDefault": "YeniKlasör", "newFolderDefault": "YeniKlasör",
"newFileDefault": "YeniDosya.txt", "newFileDefault": "YeniDosya.txt",
"successfullyMovedItems": "{{count}} öğe başarıyla {{target}} konumuna taşındı.", "successfullyMovedItems": "{{count}} öğe başarıyla {{target}}konumuna taşındı.",
"move": "Taşınmak", "move": "Taşınmak",
"searchInFile": "Dosyada arama yap (Ctrl+F)", "searchInFile": "Dosyada arama yap (Ctrl+F)",
"showKeyboardShortcuts": "Klavye kısayollarını göster", "showKeyboardShortcuts": "Klavye kısayollarını göster",
@@ -1527,7 +1527,7 @@
"compare": "Karşılaştırmak", "compare": "Karşılaştırmak",
"sideBySide": "Yan yana", "sideBySide": "Yan yana",
"inline": "Çizgide", "inline": "Çizgide",
"fileComparison": "Dosya Karşılaştırması: {{file1}} ile {{file2}}", "fileComparison": "Dosya Karşılaştırması: {{file1}} ve {{file2}}",
"fileTooLarge": "Dosya çok büyük: {{error}}", "fileTooLarge": "Dosya çok büyük: {{error}}",
"sshConnectionFailed": "SSH bağlantısı başarısız oldu. Lütfen {{name}} ({{ip}}:{{port}}) adresine olan bağlantınızı kontrol edin.", "sshConnectionFailed": "SSH bağlantısı başarısız oldu. Lütfen {{name}} ({{ip}}:{{port}}) adresine olan bağlantınızı kontrol edin.",
"loadFileFailed": "Dosya yüklenemedi: {{error}}", "loadFileFailed": "Dosya yüklenemedi: {{error}}",
@@ -1573,10 +1573,10 @@
"disconnect": "Bağlantıyı kes", "disconnect": "Bağlantıyı kes",
"cancel": "İptal etmek", "cancel": "İptal etmek",
"port": "Liman", "port": "Liman",
"attempt": "{{current}}'in {{max}} numaralı denemesi", "attempt": "{{max}}'in {{current}} denemesi",
"nextRetryIn": "Sonraki deneme {{seconds}} saniye sonra", "nextRetryIn": "Sonraki deneme {{seconds}} saniye sonra",
"checkDockerLogs": "Hata nedenini öğrenmek için Docker günlüklerinizi kontrol edin, katılın.", "checkDockerLogs": "Hata nedenini öğrenmek için Docker günlüklerinizi kontrol edin, katılın.",
"orCreate": "veya bir oluşturun", "orCreate": "veya bir oluşturun ",
"noTunnelConnections": "Tünel bağlantısı yapılandırılmamış.", "noTunnelConnections": "Tünel bağlantısı yapılandırılmamış.",
"tunnelConnections": "Tünel Bağlantıları", "tunnelConnections": "Tünel Bağlantıları",
"addTunnel": "Tünel Ekle", "addTunnel": "Tünel Ekle",
@@ -1589,7 +1589,7 @@
"autoStart": "Otomatik Başlatma", "autoStart": "Otomatik Başlatma",
"status": "Durum", "status": "Durum",
"active": "Aktif", "active": "Aktif",
"inactive": "Etkin değil", "inactive": "Aktif değil",
"start": "Başlangıç", "start": "Başlangıç",
"stop": "Durmak", "stop": "Durmak",
"restart": "Tekrar başlat", "restart": "Tekrar başlat",
@@ -1598,7 +1598,7 @@
"remote": "Uzak", "remote": "Uzak",
"dynamic": "Dinamik", "dynamic": "Dinamik",
"unknownConnectionStatus": "Bilinmiyor", "unknownConnectionStatus": "Bilinmiyor",
"portMapping": "Liman {{sourcePort}} → {{endpointHost}}:{{endpointPort}}", "portMapping": "Port {{sourcePort}} → {{endpointHost}}:{{endpointPort}}",
"endpointHostNotFound": "Uç nokta ana bilgisayarı bulunamadı.", "endpointHostNotFound": "Uç nokta ana bilgisayarı bulunamadı.",
"discord": "Discord", "discord": "Discord",
"githubIssue": "GitHub sorunu", "githubIssue": "GitHub sorunu",
@@ -1650,7 +1650,7 @@
"totpInvalidCode": "Geçersiz doğrulama kodu", "totpInvalidCode": "Geçersiz doğrulama kodu",
"totpCancelled": "Ölçüm toplama işlemi iptal edildi", "totpCancelled": "Ölçüm toplama işlemi iptal edildi",
"authenticationFailed": "Kimlik doğrulama başarısız oldu", "authenticationFailed": "Kimlik doğrulama başarısız oldu",
"noneAuthNotSupported": "Sunucu İstatistikleri, 'none' kimlik doğrulama türünü desteklemiyor.", "noneAuthNotSupported": "Sunucu İstatistikleri 'none' kimlik doğrulama türünü desteklemiyor.",
"load": "Yük", "load": "Yük",
"editLayout": "Düzeni Düzenle", "editLayout": "Düzeni Düzenle",
"cancelEdit": "İptal etmek", "cancelEdit": "İptal etmek",
@@ -1678,11 +1678,11 @@
"noRecentLoginData": "Son oturum açma verisi yok.", "noRecentLoginData": "Son oturum açma verisi yok.",
"from": "itibaren", "from": "itibaren",
"quickActions": "Hızlı İşlemler", "quickActions": "Hızlı İşlemler",
"executeQuickAction": "{{name}}'i yürüt", "executeQuickAction": "{{name}}komutunu yürüt",
"executingQuickAction": "{{name}} yürütülüyor...", "executingQuickAction": "{{name}}yürütülüyor...",
"quickActionSuccess": "{{name}} başarıyla tamamlandı", "quickActionSuccess": "{{name}} başarıyla tamamlandı",
"quickActionFailed": "{{name}} başarısız oldu", "quickActionFailed": "{{name}} başarısız oldu",
"quickActionError": "{{name}} yürütülemedi" "quickActionError": "{{name}}yürütülemedi"
}, },
"auth": { "auth": {
"tagline": "SSH SUNUCU YÖNETİCİSİ", "tagline": "SSH SUNUCU YÖNETİCİSİ",
@@ -1814,8 +1814,8 @@
"invalidAuthUrl": "Arka uçtan geçersiz yetkilendirme URL'si alındı.", "invalidAuthUrl": "Arka uçtan geçersiz yetkilendirme URL'si alındı.",
"invalidInput": "Geçersiz giriş", "invalidInput": "Geçersiz giriş",
"requiredField": "Bu alan zorunludur.", "requiredField": "Bu alan zorunludur.",
"minLength": "Minimum uzunluk {{min}}'tür.", "minLength": "Minimum uzunluk {{min}}",
"maxLength": "Maksimum uzunluk {{max}}'tür.", "maxLength": "Maksimum uzunluk {{max}}",
"invalidEmail": "Geçersiz e-posta adresi", "invalidEmail": "Geçersiz e-posta adresi",
"passwordMismatch": "Şifreler eşleşmiyor.", "passwordMismatch": "Şifreler eşleşmiyor.",
"passwordLoginDisabled": "Kullanıcı adı/şifre ile giriş şu anda devre dışı bırakılmıştır.", "passwordLoginDisabled": "Kullanıcı adı/şifre ile giriş şu anda devre dışı bırakılmıştır.",
@@ -1845,7 +1845,7 @@
"databaseConnected": "Veritabanı bağlantısı başarıyla kuruldu.", "databaseConnected": "Veritabanı bağlantısı başarıyla kuruldu.",
"databaseConnectionFailed": "Veritabanı sunucusuna bağlanılamadı.", "databaseConnectionFailed": "Veritabanı sunucusuna bağlanılamadı.",
"checkServerConnection": "Lütfen sunucu bağlantınızı kontrol edin ve tekrar deneyin.", "checkServerConnection": "Lütfen sunucu bağlantınızı kontrol edin ve tekrar deneyin.",
"resetCodeSent": "Docker günlüklerine gönderilen sıfırlama kodu", "resetCodeSent": "Docker günlüklerine sıfırlama kodu gönderildi.",
"codeVerified": "Kod başarıyla doğrulandı.", "codeVerified": "Kod başarıyla doğrulandı.",
"passwordResetSuccess": "Parola sıfırlama işlemi başarıyla tamamlandı.", "passwordResetSuccess": "Parola sıfırlama işlemi başarıyla tamamlandı.",
"loginSuccess": "Giriş başarılı", "loginSuccess": "Giriş başarılı",
@@ -1880,7 +1880,7 @@
"languageLocalization": "Dil ve Yerelleştirme", "languageLocalization": "Dil ve Yerelleştirme",
"fileManagerSettings": "Dosya Yöneticisi", "fileManagerSettings": "Dosya Yöneticisi",
"terminalSettings": "terminal", "terminalSettings": "terminal",
"hostSidebarSettings": "Sunucu ve Kenar Çubuğu", "hostSidebarSettings": "Sunucu ve Yan Menü",
"snippetsSettings": "Kısa bölümler", "snippetsSettings": "Kısa bölümler",
"currentPassword": "Mevcut Şifre", "currentPassword": "Mevcut Şifre",
"passwordChangedSuccess": "Şifre başarıyla değiştirildi! Lütfen tekrar giriş yapın.", "passwordChangedSuccess": "Şifre başarıyla değiştirildi! Lütfen tekrar giriş yapın.",
@@ -1933,7 +1933,7 @@
"searchHostsAny": "Sunucuları ara (deneyin: tag:prod, user:root, ip:192.168)...", "searchHostsAny": "Sunucuları ara (deneyin: tag:prod, user:root, ip:192.168)...",
"confirmPassword": "Onaylamak için şifrenizi girin.", "confirmPassword": "Onaylamak için şifrenizi girin.",
"typeHere": "Buraya yazın", "typeHere": "Buraya yazın",
"fileName": "Dosya adını girin (örneğin, example.txt)", "fileName": "Dosya adını girin (örneğin, example.txt).",
"folderName": "Klasör adını girin", "folderName": "Klasör adını girin",
"fullPath": "Öğeye giden tam yolu girin.", "fullPath": "Öğeye giden tam yolu girin.",
"currentPath": "Öğeye giden mevcut yolu girin.", "currentPath": "Öğeye giden mevcut yolu girin.",
@@ -1956,8 +1956,8 @@
"failedToDeleteAccount": "Hesap silme işlemi başarısız oldu.", "failedToDeleteAccount": "Hesap silme işlemi başarısız oldu.",
"failedToMakeUserAdmin": "Kullanıcıyı yönetici yapma işlemi başarısız oldu.", "failedToMakeUserAdmin": "Kullanıcıyı yönetici yapma işlemi başarısız oldu.",
"userIsNowAdmin": "Kullanıcı {{username}} artık yöneticidir.", "userIsNowAdmin": "Kullanıcı {{username}} artık yöneticidir.",
"removeAdminConfirm": "{{username}}'den yönetici statüsünü kaldırmak istediğinizden emin misiniz?", "removeAdminConfirm": "{{username}}'dan yönetici statüsünü kaldırmak istediğinizden emin misiniz?",
"deleteUserConfirm": "{{username}} kullanıcısını silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.", "deleteUserConfirm": "{{username}}kullanıcısını silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.",
"deleteAccount": "Hesabı Sil", "deleteAccount": "Hesabı Sil",
"closeDeleteAccount": "Hesabı Kapat Sil", "closeDeleteAccount": "Hesabı Kapat Sil",
"deleteAccountWarning": "Bu işlem geri alınamaz. Bu, hesabınızı ve ilgili tüm verileri kalıcı olarak silecektir.", "deleteAccountWarning": "Bu işlem geri alınamaz. Bu, hesabınızı ve ilgili tüm verileri kalıcı olarak silecektir.",
@@ -2149,8 +2149,8 @@
"lastAccessed": "Son Erişim Tarihi", "lastAccessed": "Son Erişim Tarihi",
"accessCount": "Erişim Sayısı", "accessCount": "Erişim Sayısı",
"revokeAccess": "Erişimi İptal Et", "revokeAccess": "Erişimi İptal Et",
"confirmRevokeAccess": "{{username}} kullanıcısının erişimini iptal etmek istediğinizden emin misiniz?", "confirmRevokeAccess": "{{username}}için erişimi iptal etmek istediğinizden emin misiniz?",
"hostSharedSuccessfully": "Sunucu, {{username}} ile başarıyla paylaşıldı.", "hostSharedSuccessfully": "Sunucu başarıyla {{username}}ile paylaşıldı.",
"hostAccessUpdated": "Sunucu erişimi güncellendi", "hostAccessUpdated": "Sunucu erişimi güncellendi",
"failedToShareHost": "Sunucuyu paylaşma başarısız oldu.", "failedToShareHost": "Sunucuyu paylaşma başarısız oldu.",
"accessRevokedSuccessfully": "Erişim başarıyla iptal edildi.", "accessRevokedSuccessfully": "Erişim başarıyla iptal edildi.",
@@ -2177,16 +2177,16 @@
"tempUserRecommended": "Daha iyi güvenlik için 'Geçici Kullanıcı Oluştur' seçeneğini etkinleştirmenizi öneririz.", "tempUserRecommended": "Daha iyi güvenlik için 'Geçici Kullanıcı Oluştur' seçeneğini etkinleştirmenizi öneririz.",
"roleManagement": "Rol Yönetimi", "roleManagement": "Rol Yönetimi",
"manageRoles": "Rolleri Yönet", "manageRoles": "Rolleri Yönet",
"manageRolesFor": "{{username}} için rolleri yönetin", "manageRolesFor": "{{username}}için rolleri yönetin",
"assignRole": "Rol Ata", "assignRole": "Rol Ata",
"removeRole": "Rolü Kaldır", "removeRole": "Rolü Kaldır",
"userRoles": "Kullanıcı Rolleri", "userRoles": "Kullanıcı Rolleri",
"permissions": "İzinler", "permissions": "İzinler",
"systemRole": "Sistem Rolü", "systemRole": "Sistem Rolü",
"customRole": "Özel Rol", "customRole": "Özel Rol",
"roleAssignedSuccessfully": "{{username}}'ye rol başarıyla atandı.", "roleAssignedSuccessfully": "{{username}} 'a rol başarıyla atandı.",
"failedToAssignRole": "Rol atama işlemi başarısız oldu.", "failedToAssignRole": "Rol atama işlemi başarısız oldu.",
"roleRemovedSuccessfully": "Rol, {{username}}'den başarıyla kaldırıldı.", "roleRemovedSuccessfully": "{{username}} 'dan rol başarıyla kaldırıldı.",
"failedToRemoveRole": "Rolü kaldırma işlemi başarısız oldu.", "failedToRemoveRole": "Rolü kaldırma işlemi başarısız oldu.",
"cannotRemoveSystemRole": "Sistem rolü kaldırılamıyor.", "cannotRemoveSystemRole": "Sistem rolü kaldırılamıyor.",
"cannotShareWithSelf": "Aynı sunucuyu kendinizle paylaşamazsınız.", "cannotShareWithSelf": "Aynı sunucuyu kendinizle paylaşamazsınız.",
@@ -2214,7 +2214,7 @@
"terminateSession": "Oturumu Sonlandır", "terminateSession": "Oturumu Sonlandır",
"sessionTerminated": "Oturum sunucu sahibi tarafından sonlandırıldı.", "sessionTerminated": "Oturum sunucu sahibi tarafından sonlandırıldı.",
"sharedAccessExpired": "Bu sunucuya olan paylaşımlı erişiminizin süresi doldu.", "sharedAccessExpired": "Bu sunucuya olan paylaşımlı erişiminizin süresi doldu.",
"sharedAccessExpiresIn": "Paylaşımlı erişim {{hours}} saat sonra sona eriyor", "sharedAccessExpiresIn": "Paylaşımlı erişim {{hours}} saat sonra sona eriyor.",
"roles": { "roles": {
"label": "Roller", "label": "Roller",
"admin": "Yönetici", "admin": "Yönetici",
@@ -2310,16 +2310,16 @@
"errorCode": "Hata kodu: {{code}}", "errorCode": "Hata kodu: {{code}}",
"version": "Docker {{version}}", "version": "Docker {{version}}",
"containerStarted": "Konteyner {{name}} başlatıldı", "containerStarted": "Konteyner {{name}} başlatıldı",
"failedToStartContainer": "{{name}} konteynerini başlatma başarısız oldu.", "failedToStartContainer": "{{name}}kapsayıcısı başlatılamadı.",
"containerStopped": "Konteyner {{name}} durdu", "containerStopped": "Konteyner {{name}} durduruldu",
"failedToStopContainer": "{{name}} numaralı konteyneri durdurma işlemi başarısız oldu.", "failedToStopContainer": "{{name}}kapsayıcısını durdurma başarısız oldu.",
"containerRestarted": "Konteyner {{name}} yeniden başlatıldı", "containerRestarted": "Konteyner {{name}} yeniden başlatıldı",
"failedToRestartContainer": "{{name}} numaralı konteyneri yeniden başlatma başarısız oldu.", "failedToRestartContainer": "{{name}}kapsayıcısını yeniden başlatma başarısız oldu.",
"containerPaused": "Konteyner {{name}} duraklatıldı", "containerPaused": "Konteyner {{name}} duraklatıldı",
"containerUnpaused": "Konteyner {{name}} duraklatılmadı", "containerUnpaused": "Konteyner {{name}} duraklatılmamış",
"failedToTogglePauseContainer": "{{name}} numaralı kapsayıcı için duraklatma durumunu değiştirme işlemi başarısız oldu.", "failedToTogglePauseContainer": "{{name}}kapsayıcısı için duraklatma durumunu değiştirme başarısız oldu.",
"containerRemoved": "Konteyner {{name}} kaldırıldı", "containerRemoved": "Konteyner {{name}} kaldırıldı",
"failedToRemoveContainer": "{{name}} numaralı konteyneri kaldırma işlemi başarısız oldu.", "failedToRemoveContainer": "{{name}}kapsayıcısını kaldırma işlemi başarısız oldu.",
"image": "Görüntü", "image": "Görüntü",
"idLabel": "İD", "idLabel": "İD",
"ports": "Limanlar", "ports": "Limanlar",
@@ -2332,7 +2332,7 @@
"restart": "Tekrar başlat", "restart": "Tekrar başlat",
"remove": "Kaldırmak", "remove": "Kaldırmak",
"removeContainer": "Kabı çıkarın", "removeContainer": "Kabı çıkarın",
"confirmRemoveContainer": "\"{{name}}\" konteynerini kaldırmak istediğinizden emin misiniz? Bu işlem geri alınamaz.", "confirmRemoveContainer": "'{{name}}' kapsayıcısını kaldırmak istediğinizden emin misiniz? Bu işlem geri alınamaz.",
"runningContainerWarning": "Uyarı: Bu konteyner şu anda çalışıyor. Kaldırılması durumunda konteyner önce durdurulacaktır.", "runningContainerWarning": "Uyarı: Bu konteyner şu anda çalışıyor. Kaldırılması durumunda konteyner önce durdurulacaktır.",
"removing": "Kaldırılıyor...", "removing": "Kaldırılıyor...",
"loadingContainers": "Konteynerler yükleniyor...", "loadingContainers": "Konteynerler yükleniyor...",
@@ -2372,7 +2372,7 @@
"authenticationRequired": "Kimlik doğrulama gereklidir.", "authenticationRequired": "Kimlik doğrulama gereklidir.",
"verificationCodePrompt": "Doğrulama kodunu girin", "verificationCodePrompt": "Doğrulama kodunu girin",
"totpVerificationFailed": "TOTP doğrulaması başarısız oldu. Lütfen tekrar deneyin.", "totpVerificationFailed": "TOTP doğrulaması başarısız oldu. Lütfen tekrar deneyin.",
"connectedTo": "{{containerName}} ile bağlantılı", "connectedTo": "{{containerName}}ile bağlantılı",
"disconnected": "Bağlantı kesildi", "disconnected": "Bağlantı kesildi",
"consoleError": "Konsol hatası", "consoleError": "Konsol hatası",
"errorMessage": "Hata: {{message}}", "errorMessage": "Hata: {{message}}",
@@ -2387,7 +2387,7 @@
"disconnect": "Bağlantıyı kes", "disconnect": "Bağlantıyı kes",
"notConnected": "Bağlı değil", "notConnected": "Bağlı değil",
"clickToConnect": "Kabuk oturumu başlatmak için bağlan'a tıklayın.", "clickToConnect": "Kabuk oturumu başlatmak için bağlan'a tıklayın.",
"connectingTo": "{{containerName}}'ye bağlanılıyor...", "connectingTo": "{{containerName}}ile bağlantı kuruluyor...",
"containerNotFound": "Konteyner bulunamadı.", "containerNotFound": "Konteyner bulunamadı.",
"backToList": "Listeye geri dön", "backToList": "Listeye geri dön",
"logs": "Günlükler", "logs": "Günlükler",
@@ -2399,4 +2399,4 @@
"switchToLight": "Işığa geç", "switchToLight": "Işığa geç",
"switchToDark": "Koyu moda geç" "switchToDark": "Koyu moda geç"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@
"failedToFetchCredentials": "Không thể tải thông tin đăng nhập", "failedToFetchCredentials": "Không thể tải thông tin đăng nhập",
"credentialDeletedSuccessfully": "Thông tin đăng nhập đã được xóa thành công.", "credentialDeletedSuccessfully": "Thông tin đăng nhập đã được xóa thành công.",
"failedToDeleteCredential": "Không thể xóa thông tin đăng nhập", "failedToDeleteCredential": "Không thể xóa thông tin đăng nhập",
"confirmDeleteCredential": "Bạn có chắc chắn muốn xóa thông tin xác thực \"{{name}}\" không?", "confirmDeleteCredential": "Bạn có chắc chắn muốn xóa thông tin đăng nhập \"{{name}}\" không?",
"credentialCreatedSuccessfully": "Thông tin xác thực đã được tạo thành công", "credentialCreatedSuccessfully": "Thông tin xác thực đã được tạo thành công",
"credentialUpdatedSuccessfully": "Thông tin đăng nhập đã được cập nhật thành công.", "credentialUpdatedSuccessfully": "Thông tin đăng nhập đã được cập nhật thành công.",
"failedToSaveCredential": "Không thể lưu thông tin đăng nhập", "failedToSaveCredential": "Không thể lưu thông tin đăng nhập",
@@ -43,7 +43,7 @@
"refresh": "Làm cho khỏe lại", "refresh": "Làm cho khỏe lại",
"passwordRequired": "Cần có mật khẩu.", "passwordRequired": "Cần có mật khẩu.",
"sshKeyRequired": "Cần có khóa SSH.", "sshKeyRequired": "Cần có khóa SSH.",
"credentialAddedSuccessfully": "Thông tin xác thực \"{{name}}\" đã được thêm thành công.", "credentialAddedSuccessfully": "Thông tin xác thực \"{{name}}\" đã được thêm thành công",
"general": "Tổng quan", "general": "Tổng quan",
"description": "Sự miêu tả", "description": "Sự miêu tả",
"folder": "Thư mục", "folder": "Thư mục",
@@ -128,7 +128,7 @@
"created": "Tạo", "created": "Tạo",
"lastModified": "Lần sửa đổi cuối cùng", "lastModified": "Lần sửa đổi cuối cùng",
"usageStatistics": "Thống kê sử dụng", "usageStatistics": "Thống kê sử dụng",
"copiedToClipboard": "{{field}} đã được sao chép vào clipboard", "copiedToClipboard": "{{field}} đã sao chép vào clipboard",
"failedToCopy": "Không thể sao chép vào clipboard", "failedToCopy": "Không thể sao chép vào clipboard",
"sshKey": "Khóa SSH", "sshKey": "Khóa SSH",
"createCredentialDescription": "Tạo thông tin đăng nhập SSH mới để truy cập an toàn.", "createCredentialDescription": "Tạo thông tin đăng nhập SSH mới để truy cập an toàn.",
@@ -137,11 +137,11 @@
"folderView": "Thư mục", "folderView": "Thư mục",
"unknownCredential": "Không rõ", "unknownCredential": "Không rõ",
"confirmRemoveFromFolder": "Bạn có chắc chắn muốn xóa \"{{name}}\" khỏi thư mục \"{{folder}}\" không? Thông tin đăng nhập sẽ được chuyển đến thư mục \"Chưa được phân loại\".", "confirmRemoveFromFolder": "Bạn có chắc chắn muốn xóa \"{{name}}\" khỏi thư mục \"{{folder}}\" không? Thông tin đăng nhập sẽ được chuyển đến thư mục \"Chưa được phân loại\".",
"removedFromFolder": "Thông tin xác thực \"{{name}}\" đã được xóa khỏi thư mục thành công.", "removedFromFolder": "Thông tin xác thực \"{{name}}\" đã được xóa khỏi thư mục thành công",
"failedToRemoveFromFolder": "Không thể xóa thông tin đăng nhập khỏi thư mục.", "failedToRemoveFromFolder": "Không thể xóa thông tin đăng nhập khỏi thư mục.",
"folderRenamed": "Thư mục \"{{oldName}}\" đã được đổi tên thành \"{{newName}}\" thành công.", "folderRenamed": "Thư mục \"{{oldName}}\" đã được đổi tên thành \"{{newName}}\" thành công",
"failedToRenameFolder": "Không thể đổi tên thư mục.", "failedToRenameFolder": "Không thể đổi tên thư mục.",
"movedToFolder": "Thông tin xác thực \"{{name}}\" đã được chuyển sang \"{{folder}}\" thành công.", "movedToFolder": "Thông tin xác thực \"{{name}}\" đã được chuyển thành công sang \"{{folder}}\"",
"failedToMoveToFolder": "Không thể chuyển thông tin đăng nhập vào thư mục.", "failedToMoveToFolder": "Không thể chuyển thông tin đăng nhập vào thư mục.",
"sshPublicKey": "Khóa công khai SSH", "sshPublicKey": "Khóa công khai SSH",
"publicKeyNote": "Khóa công khai là tùy chọn nhưng được khuyến nghị để xác thực khóa.", "publicKeyNote": "Khóa công khai là tùy chọn nhưng được khuyến nghị để xác thực khóa.",
@@ -166,7 +166,7 @@
"keyTypeDsa": "DSA (SSH)", "keyTypeDsa": "DSA (SSH)",
"keyTypeRsaSha256": "RSA-SHA2-256", "keyTypeRsaSha256": "RSA-SHA2-256",
"keyTypeRsaSha512": "RSA-SHA2-512", "keyTypeRsaSha512": "RSA-SHA2-512",
"keyPairGeneratedSuccessfully": "Cặp khóa {{keyType}} được tạo thành công", "keyPairGeneratedSuccessfully": "Cặp khóa {{keyType}} đã được tạo thành công",
"failedToGenerateKeyPair": "Không thể tạo cặp khóa", "failedToGenerateKeyPair": "Không thể tạo cặp khóa",
"generateKeyPairNote": "Tạo cặp khóa SSH mới trực tiếp. Thao tác này sẽ thay thế mọi khóa hiện có.", "generateKeyPairNote": "Tạo cặp khóa SSH mới trực tiếp. Thao tác này sẽ thay thế mọi khóa hiện có.",
"invalidKey": "Khóa không hợp lệ", "invalidKey": "Khóa không hợp lệ",
@@ -187,9 +187,9 @@
"dragIndicator": { "dragIndicator": {
"error": "Lỗi: {{error}}", "error": "Lỗi: {{error}}",
"dragging": "Kéo {{fileName}}", "dragging": "Kéo {{fileName}}",
"preparing": "Chuẩn bị {{fileName}}", "preparing": "Đang chuẩn bị {{fileName}}",
"readySingle": "Sẵn sàng tải xuống {{fileName}}", "readySingle": "Sẵn sàng tải xuống {{fileName}}",
"readyMultiple": "Sẵn sàng tải xuống {{count}} tệp", "readyMultiple": "Sẵn sàng tải xuống các tệp {{count}}",
"batchDrag": "Kéo {{count}} tập tin ra màn hình nền", "batchDrag": "Kéo {{count}} tập tin ra màn hình nền",
"dragToDesktop": "Kéo vào màn hình nền", "dragToDesktop": "Kéo vào màn hình nền",
"canDragAnywhere": "Bạn có thể kéo thả các tập tin đến bất kỳ vị trí nào trên màn hình máy tính." "canDragAnywhere": "Bạn có thể kéo thả các tập tin đến bất kỳ vị trí nào trên màn hình máy tính."
@@ -205,9 +205,9 @@
"commandsWillBeSent": "Các lệnh sẽ được gửi đến {{count}} thiết bị đầu cuối đã chọn.", "commandsWillBeSent": "Các lệnh sẽ được gửi đến {{count}} thiết bị đầu cuối đã chọn.",
"settings": "Cài đặt", "settings": "Cài đặt",
"enableRightClickCopyPaste": "Cho phép sao chép/dán bằng chuột phải.", "enableRightClickCopyPaste": "Cho phép sao chép/dán bằng chuột phải.",
"shareIdeas": "Bạn có ý tưởng nào về những tính năng tiếp theo cho các công cụ SSH không? Hãy chia sẻ chúng trên", "shareIdeas": "Bạn có ý tưởng nào về những tính năng tiếp theo cho các công cụ SSH không? Hãy chia sẻ chúng trên đây!",
"scripts": { "scripts": {
"inputPlaceholder": "Ví dụ: Lệnh hệ thống, Tập lệnh Docker" "inputPlaceholder": "Ví dụ: Lệnh hệ thống, tập lệnh Docker"
} }
}, },
"snippets": { "snippets": {
@@ -248,7 +248,7 @@
"reorderSameFolder": "Chỉ có thể sắp xếp lại các đoạn mã trong cùng một thư mục.", "reorderSameFolder": "Chỉ có thể sắp xếp lại các đoạn mã trong cùng một thư mục.",
"reorderSuccess": "Các đoạn trích đã được sắp xếp lại thành công", "reorderSuccess": "Các đoạn trích đã được sắp xếp lại thành công",
"reorderFailed": "Không thể sắp xếp lại các đoạn mã.", "reorderFailed": "Không thể sắp xếp lại các đoạn mã.",
"deleteFolderConfirm": "Xóa thư mục \"{{name}}\"? Tất cả các đoạn trích sẽ được chuyển đến thư mục Chưa được phân loại.", "deleteFolderConfirm": "Xóa thư mục \"{{name}}\"? Tất cả các đoạn sẽ được chuyển đến thư mục Chưa được phân loại.",
"deleteFolderSuccess": "Thư mục đã được xóa thành công", "deleteFolderSuccess": "Thư mục đã được xóa thành công",
"deleteFolderFailed": "Không thể xóa thư mục", "deleteFolderFailed": "Không thể xóa thư mục",
"updateFolderSuccess": "Thư mục đã được cập nhật thành công.", "updateFolderSuccess": "Thư mục đã được cập nhật thành công.",
@@ -308,7 +308,7 @@
"cleared": "Màn hình chia đôi đã được xóa", "cleared": "Màn hình chia đôi đã được xóa",
"error": { "error": {
"noAssignments": "Vui lòng chỉ định ít nhất một tab cho bố cục.", "noAssignments": "Vui lòng chỉ định ít nhất một tab cho bố cục.",
"fillAllSlots": "Vui lòng điền đầy đủ {{count}} ô trước khi nộp đơn." "fillAllSlots": "Vui lòng điền đầy đủ tất cả {{count}} ô trước khi ứng tuyển."
} }
}, },
"homepage": { "homepage": {
@@ -346,7 +346,7 @@
"currentVersion": "Bạn đang sử dụng phiên bản {{version}}", "currentVersion": "Bạn đang sử dụng phiên bản {{version}}",
"updateAvailable": "Đã có bản cập nhật", "updateAvailable": "Đã có bản cập nhật",
"newVersionAvailable": "Phiên bản mới đã có sẵn! Bạn đang sử dụng {{current}}, nhưng {{latest}} đã có sẵn.", "newVersionAvailable": "Phiên bản mới đã có sẵn! Bạn đang sử dụng {{current}}, nhưng {{latest}} đã có sẵn.",
"releasedOn": "Phát hành vào ngày {{date}}", "releasedOn": "Phát hành vào {{date}}",
"downloadUpdate": "Tải xuống bản cập nhật", "downloadUpdate": "Tải xuống bản cập nhật",
"dismiss": "Miễn nhiệm", "dismiss": "Miễn nhiệm",
"checking": "Đang kiểm tra cập nhật...", "checking": "Đang kiểm tra cập nhật...",
@@ -508,8 +508,8 @@
"tokenUrl": "URL mã thông báo", "tokenUrl": "URL mã thông báo",
"updateSettings": "Cập nhật cài đặt", "updateSettings": "Cập nhật cài đặt",
"confirmDelete": "Bạn có chắc chắn muốn xóa người dùng này không?", "confirmDelete": "Bạn có chắc chắn muốn xóa người dùng này không?",
"confirmMakeAdmin": "Bạn có chắc chắn muốn đặt {{username}} làm quản trị viên không?", "confirmMakeAdmin": "Bạn có chắc chắn muốn phong {{username}} làm quản trị viên không?",
"confirmRemoveAdmin": "Bạn có chắc chắn muốn xóa quyền quản trị khỏi {{username}} không?", "confirmRemoveAdmin": "Bạn có chắc chắn muốn xóa quyền quản trị khỏi {{username}}không?",
"externalAuthentication": "Xác thực bên ngoài (OIDC)", "externalAuthentication": "Xác thực bên ngoài (OIDC)",
"configureExternalProvider": "Cấu hình nhà cung cấp định danh bên ngoài cho xác thực OIDC/OAuth2.", "configureExternalProvider": "Cấu hình nhà cung cấp định danh bên ngoài cho xác thực OIDC/OAuth2.",
"userIdentifierPath": "Đường dẫn định danh người dùng", "userIdentifierPath": "Đường dẫn định danh người dùng",
@@ -546,10 +546,10 @@
"oidcConfigurationDisabled": "Cấu hình OIDC đã bị vô hiệu hóa thành công!", "oidcConfigurationDisabled": "Cấu hình OIDC đã bị vô hiệu hóa thành công!",
"failedToUpdateOidcConfig": "Không thể cập nhật cấu hình OIDC.", "failedToUpdateOidcConfig": "Không thể cập nhật cấu hình OIDC.",
"failedToDisableOidcConfig": "Không thể vô hiệu hóa cấu hình OIDC.", "failedToDisableOidcConfig": "Không thể vô hiệu hóa cấu hình OIDC.",
"enterUsernameToMakeAdmin": "Nhập tên người dùng để trở thành quản trị viên", "enterUsernameToMakeAdmin": "Nhập tên người dùng để trở thành quản trị viên.",
"userIsNowAdmin": "Người dùng {{username}} hiện là quản trị viên", "userIsNowAdmin": "Người dùng {{username}} hiện là quản trị viên",
"failedToMakeUserAdmin": "Không thể cấp quyền quản trị cho người dùng.", "failedToMakeUserAdmin": "Không thể cấp quyền quản trị cho người dùng.",
"removeAdminStatus": "Xóa trạng thái quản trị viên khỏi {{username}}?", "removeAdminStatus": "Xóa quyền quản trị khỏi {{username}}?",
"adminStatusRemoved": "Trạng thái quản trị viên đã bị xóa khỏi {{username}}", "adminStatusRemoved": "Trạng thái quản trị viên đã bị xóa khỏi {{username}}",
"failedToRemoveAdminStatus": "Không thể xóa trạng thái quản trị viên.", "failedToRemoveAdminStatus": "Không thể xóa trạng thái quản trị viên.",
"userDeletedSuccessfully": "Người dùng {{username}} đã bị xóa thành công", "userDeletedSuccessfully": "Người dùng {{username}} đã bị xóa thành công",
@@ -615,7 +615,7 @@
"failedToLinkAccounts": "Không thể liên kết tài khoản", "failedToLinkAccounts": "Không thể liên kết tài khoản",
"linkTargetUsernameRequired": "Tên người dùng mục tiêu là bắt buộc", "linkTargetUsernameRequired": "Tên người dùng mục tiêu là bắt buộc",
"unlinkOIDCTitle": "Hủy liên kết xác thực OIDC", "unlinkOIDCTitle": "Hủy liên kết xác thực OIDC",
"unlinkOIDCDescription": "Xóa xác thực OIDC khỏi {{username}}? Sau đó, người dùng chỉ có thể đăng nhập bằng tên người dùng/mật khẩu.", "unlinkOIDCDescription": "Xóa xác thực OIDC khỏi {{username}}? Sau thao tác này, người dùng chỉ có thể đăng nhập bằng tên người dùng/mật khẩu.",
"unlinkOIDCSuccess": "OIDC đã bị ngắt kết nối khỏi {{username}}", "unlinkOIDCSuccess": "OIDC đã bị ngắt kết nối khỏi {{username}}",
"failedToUnlinkOIDC": "Không thể hủy liên kết OIDC", "failedToUnlinkOIDC": "Không thể hủy liên kết OIDC",
"databaseSecurity": "Bảo mật cơ sở dữ liệu", "databaseSecurity": "Bảo mật cơ sở dữ liệu",
@@ -661,7 +661,7 @@
"loadingEncryptionStatus": "Đang tải trạng thái mã hóa...", "loadingEncryptionStatus": "Đang tải trạng thái mã hóa...",
"testMigrationDescription": "Xác minh rằng dữ liệu hiện có có thể được chuyển đổi an toàn sang định dạng mã hóa mà không cần sửa đổi bất kỳ dữ liệu nào.", "testMigrationDescription": "Xác minh rằng dữ liệu hiện có có thể được chuyển đổi an toàn sang định dạng mã hóa mà không cần sửa đổi bất kỳ dữ liệu nào.",
"serverMigrationGuide": "Hướng dẫn di chuyển máy chủ", "serverMigrationGuide": "Hướng dẫn di chuyển máy chủ",
"migrationInstructions": "Để di chuyển dữ liệu được mã hóa sang máy chủ mới: 1) Sao lưu các tệp cơ sở dữ liệu, 2) Đặt biến môi trường DB_ENCRYPTION_KEY=\"your-key\" trên máy chủ mới, 3) Khôi phục các tệp cơ sở dữ liệu.", "migrationInstructions": "Để di chuyển dữ liệu được mã hóa sang máy chủ mới: 1) Sao lưu các tệp cơ sở dữ liệu, 2) Đặt biến môi trường DB_ENCRYPTION_KEY=\"khóa của bạn\" trên máy chủ mới, 3) Khôi phục các tệp cơ sở dữ liệu.",
"environmentProtection": "Bảo vệ môi trường", "environmentProtection": "Bảo vệ môi trường",
"environmentProtectionDesc": "Bảo vệ các khóa mã hóa dựa trên thông tin môi trường máy chủ (tên máy chủ, đường dẫn, v.v.), có thể di chuyển thông qua các biến môi trường.", "environmentProtectionDesc": "Bảo vệ các khóa mã hóa dựa trên thông tin môi trường máy chủ (tên máy chủ, đường dẫn, v.v.), có thể di chuyển thông qua các biến môi trường.",
"verificationCompleted": "Quá trình xác minh tính tương thích đã hoàn tất - không có dữ liệu nào bị thay đổi.", "verificationCompleted": "Quá trình xác minh tính tương thích đã hoàn tất - không có dữ liệu nào bị thay đổi.",
@@ -684,7 +684,7 @@
"bothFieldAndFileEncryptionActive": "Cả mã hóa cấp trường và cấp tệp hiện đều được kích hoạt để đảm bảo an ninh tối đa.", "bothFieldAndFileEncryptionActive": "Cả mã hóa cấp trường và cấp tệp hiện đều được kích hoạt để đảm bảo an ninh tối đa.",
"fieldLevelAes256Encryption": "Mã hóa AES-256 cấp trường cho dữ liệu nhạy cảm", "fieldLevelAes256Encryption": "Mã hóa AES-256 cấp trường cho dữ liệu nhạy cảm",
"fileLevelDatabaseEncryption": "Mã hóa cơ sở dữ liệu cấp độ tệp với liên kết phần cứng", "fileLevelDatabaseEncryption": "Mã hóa cơ sở dữ liệu cấp độ tệp với liên kết phần cứng",
"hardwareBoundFileKeys": "Khóa mã hóa tp tin gắn liền với phần cứng", "hardwareBoundFileKeys": "Khóa mã hóa tp tin gắn liền với phần cứng",
"automaticEncryptedBackups": "Tạo bản sao lưu được mã hóa tự động", "automaticEncryptedBackups": "Tạo bản sao lưu được mã hóa tự động",
"createEncryptedBackup": "Tạo bản sao lưu được mã hóa", "createEncryptedBackup": "Tạo bản sao lưu được mã hóa",
"creatingBackup": "Đang tạo bản sao lưu...", "creatingBackup": "Đang tạo bản sao lưu...",
@@ -741,7 +741,7 @@
"confirmDisablePasswordLogin": "Bạn có chắc chắn muốn vô hiệu hóa đăng nhập bằng mật khẩu không? Hãy đảm bảo rằng OIDC đã được cấu hình đúng cách và hoạt động bình thường trước khi tiếp tục, nếu không bạn sẽ mất quyền truy cập vào phiên bản Termix của mình.", "confirmDisablePasswordLogin": "Bạn có chắc chắn muốn vô hiệu hóa đăng nhập bằng mật khẩu không? Hãy đảm bảo rằng OIDC đã được cấu hình đúng cách và hoạt động bình thường trước khi tiếp tục, nếu không bạn sẽ mất quyền truy cập vào phiên bản Termix của mình.",
"passwordLoginDisabled": "Đăng nhập bằng mật khẩu đã bị vô hiệu hóa thành công.", "passwordLoginDisabled": "Đăng nhập bằng mật khẩu đã bị vô hiệu hóa thành công.",
"passwordLoginAndRegistrationDisabled": "Đăng nhập bằng mật khẩu và đăng ký tài khoản mới đã bị vô hiệu hóa thành công.", "passwordLoginAndRegistrationDisabled": "Đăng nhập bằng mật khẩu và đăng ký tài khoản mới đã bị vô hiệu hóa thành công.",
"requiresPasswordLogin": "Yêu cầu đăng nhập bằng mật khẩu.", "requiresPasswordLogin": "Yêu cầu bật đăng nhập bằng mật khẩu.",
"passwordLoginDisabledWarning": "Chức năng đăng nhập bằng mật khẩu đã bị vô hiệu hóa. Hãy đảm bảo OIDC được cấu hình đúng cách, nếu không bạn sẽ không thể đăng nhập vào Termix.", "passwordLoginDisabledWarning": "Chức năng đăng nhập bằng mật khẩu đã bị vô hiệu hóa. Hãy đảm bảo OIDC được cấu hình đúng cách, nếu không bạn sẽ không thể đăng nhập vào Termix.",
"oidcRequiredWarning": "QUAN TRỌNG: Chức năng đăng nhập bằng mật khẩu đã bị vô hiệu hóa. Nếu bạn đặt lại hoặc cấu hình sai OIDC, bạn sẽ mất toàn bộ quyền truy cập vào Termix và làm hỏng phiên bản của mình. Chỉ tiếp tục nếu bạn hoàn toàn chắc chắn.", "oidcRequiredWarning": "QUAN TRỌNG: Chức năng đăng nhập bằng mật khẩu đã bị vô hiệu hóa. Nếu bạn đặt lại hoặc cấu hình sai OIDC, bạn sẽ mất toàn bộ quyền truy cập vào Termix và làm hỏng phiên bản của mình. Chỉ tiếp tục nếu bạn hoàn toàn chắc chắn.",
"confirmDisableOIDCWarning": "CẢNH BÁO: Bạn sắp vô hiệu hóa OIDC trong khi đăng nhập bằng mật khẩu cũng bị vô hiệu hóa. Điều này sẽ làm hỏng hệ thống Termix của bạn và bạn sẽ mất toàn bộ quyền truy cập. Bạn có hoàn toàn chắc chắn muốn tiếp tục không?", "confirmDisableOIDCWarning": "CẢNH BÁO: Bạn sắp vô hiệu hóa OIDC trong khi đăng nhập bằng mật khẩu cũng bị vô hiệu hóa. Điều này sẽ làm hỏng hệ thống Termix của bạn và bạn sẽ mất toàn bộ quyền truy cập. Bạn có hoàn toàn chắc chắn muốn tiếp tục không?",
@@ -837,7 +837,7 @@
"connection": "Sự liên quan", "connection": "Sự liên quan",
"remove": "Di dời", "remove": "Di dời",
"sourcePort": "Cổng nguồn", "sourcePort": "Cổng nguồn",
"sourcePortDesc": "(Nguồn tham khảo là Chi tiết kết nối hiện tại trong tab Chung)", "sourcePortDesc": " (Nguồn tham khảo là Chi tiết kết nối hiện tại trong tab Chung)",
"endpointPort": "Cổng điểm cuối", "endpointPort": "Cổng điểm cuối",
"endpointSshConfig": "Cấu hình SSH điểm cuối", "endpointSshConfig": "Cấu hình SSH điểm cuối",
"tunnelForwardDescription": "Đường hầm này sẽ chuyển tiếp lưu lượng truy cập từ cổng {{sourcePort}} trên máy nguồn (chi tiết kết nối hiện tại trong tab chung) đến cổng {{endpointPort}} trên máy đích.", "tunnelForwardDescription": "Đường hầm này sẽ chuyển tiếp lưu lượng truy cập từ cổng {{sourcePort}} trên máy nguồn (chi tiết kết nối hiện tại trong tab chung) đến cổng {{endpointPort}} trên máy đích.",
@@ -917,9 +917,9 @@
"shutdownCommand": "Lệnh tắt máy", "shutdownCommand": "Lệnh tắt máy",
"rebootCommand": "Lệnh khởi động lại", "rebootCommand": "Lệnh khởi động lại",
"confirmRemoveFromFolder": "Bạn có chắc chắn muốn xóa \"{{name}}\" khỏi thư mục \"{{folder}}\" không? Máy chủ sẽ được chuyển đến \"Không có thư mục\".", "confirmRemoveFromFolder": "Bạn có chắc chắn muốn xóa \"{{name}}\" khỏi thư mục \"{{folder}}\" không? Máy chủ sẽ được chuyển đến \"Không có thư mục\".",
"removedFromFolder": "Máy chủ \"{{name}}\" đã được xóa khỏi thư mục thành công.", "removedFromFolder": "Máy chủ \"{{name}}\" đã được xóa khỏi thư mục thành công",
"failedToRemoveFromFolder": "Không thể xóa máy chủ khỏi thư mục.", "failedToRemoveFromFolder": "Không thể xóa máy chủ khỏi thư mục.",
"folderRenamed": "Thư mục \"{{oldName}}\" đã được đổi tên thành \"{{newName}}\" thành công.", "folderRenamed": "Thư mục \"{{oldName}}\" đã được đổi tên thành \"{{newName}}\" thành công",
"failedToRenameFolder": "Không thể đổi tên thư mục.", "failedToRenameFolder": "Không thể đổi tên thư mục.",
"editFolderAppearance": "Chỉnh sửa giao diện thư mục", "editFolderAppearance": "Chỉnh sửa giao diện thư mục",
"editFolderAppearanceDesc": "Tùy chỉnh màu sắc và biểu tượng cho thư mục", "editFolderAppearanceDesc": "Tùy chỉnh màu sắc và biểu tượng cho thư mục",
@@ -929,23 +929,23 @@
"folderAppearanceUpdated": "Giao diện thư mục đã được cập nhật thành công.", "folderAppearanceUpdated": "Giao diện thư mục đã được cập nhật thành công.",
"failedToUpdateFolderAppearance": "Không thể cập nhật giao diện thư mục.", "failedToUpdateFolderAppearance": "Không thể cập nhật giao diện thư mục.",
"deleteAllHostsInFolder": "Xóa tất cả máy chủ trong thư mục", "deleteAllHostsInFolder": "Xóa tất cả máy chủ trong thư mục",
"confirmDeleteAllHostsInFolder": "Bạn có chắc chắn muốn xóa tất cả {{count}} máy chủ trong thư mục \"{{folder}}\" không? Hành động này không thể hoàn tác.", "confirmDeleteAllHostsInFolder": "Bạn có chắc chắn muốn xóa tất cả các máy chủ {{count}} trong thư mục \"{{folder}}\" không? Hành động này không thể hoàn tác.",
"allHostsInFolderDeleted": "Đã xóa thành công {{count}} máy chủ khỏi thư mục \"{{folder}}\".", "allHostsInFolderDeleted": "Đã xóa {{count}} máy chủ khỏi thư mục \"{{folder}}\" thành công",
"failedToDeleteHostsInFolder": "Không thể xóa các máy chủ trong thư mục.", "failedToDeleteHostsInFolder": "Không thể xóa các máy chủ trong thư mục.",
"movedToFolder": "Máy chủ \"{{name}}\" đã được chuyển sang \"{{folder}}\" thành công.", "movedToFolder": "Máy chủ \"{{name}}\" đã được chuyển đến \"{{folder}}\" thành công",
"failedToMoveToFolder": "Không thể di chuyển máy chủ vào thư mục.", "failedToMoveToFolder": "Không thể di chuyển máy chủ vào thư mục.",
"clickToRenameFolder": "Nhấp chuột để đổi tên thư mục", "clickToRenameFolder": "Nhấp chuột để đổi tên thư mục",
"renameFolder": "Đổi tên thư mục", "renameFolder": "Đổi tên thư mục",
"removeFromFolder": "Xóa khỏi thư mục \"{{folder}}\"", "removeFromFolder": "Xóa khỏi thư mục \"{{folder}}\"",
"editHostTooltip": "Chỉnh sửa máy chủ", "editHostTooltip": "Chỉnh sửa máy chủ",
"deleteHostTooltip": "Xóa máy chủ", "deleteHostTooltip": "Xóa máy chủ",
"exportHostTooltip": "Máy chủ xuất", "exportHostTooltip": "Máy chủ xuất khẩu",
"cloneHostTooltip": "Máy chủ nhân bản", "cloneHostTooltip": "Máy chủ nhân bản",
"clickToEditHost": "Nhấp chuột để chỉnh sửa máy chủ", "clickToEditHost": "Nhấp chuột để chỉnh sửa máy chủ",
"dragToMoveBetweenFolders": "Kéo để di chuyển giữa các thư mục", "dragToMoveBetweenFolders": "Kéo để di chuyển giữa các thư mục",
"exportedHostConfig": "Đã xuất cấu hình máy chủ cho {{name}}", "exportedHostConfig": "Đã xuất cấu hình máy chủ cho {{name}}",
"openTerminal": "Mở thiết bị đầu cuối", "openTerminal": "Mở thiết bị đầu cuối",
"openFileManager": "Mở Trình quản lý tệp", "openFileManager": "Mở trình quản lý tệp",
"openTunnels": "Đường hầm mở", "openTunnels": "Đường hầm mở",
"openServerDetails": "Chi tiết máy chủ mở", "openServerDetails": "Chi tiết máy chủ mở",
"statistics": "Thống kê", "statistics": "Thống kê",
@@ -985,7 +985,7 @@
"fontSizeValue": "Kích thước phông chữ: {{value}}px", "fontSizeValue": "Kích thước phông chữ: {{value}}px",
"adjustFontSize": "Điều chỉnh kích thước phông chữ của cửa sổ terminal", "adjustFontSize": "Điều chỉnh kích thước phông chữ của cửa sổ terminal",
"letterSpacing": "Khoảng cách giữa các chữ", "letterSpacing": "Khoảng cách giữa các chữ",
"letterSpacingValue": "Khoảng cách giữa các chữ: {{value}}px", "letterSpacingValue": "Khoảng cách giữa các chữ cái: {{value}}px",
"adjustLetterSpacing": "Điều chỉnh khoảng cách giữa các ký tự", "adjustLetterSpacing": "Điều chỉnh khoảng cách giữa các ký tự",
"lineHeight": "Chiều cao dòng", "lineHeight": "Chiều cao dòng",
"lineHeightValue": "Chiều cao dòng: {{value}}", "lineHeightValue": "Chiều cao dòng: {{value}}",
@@ -1007,7 +1007,7 @@
"bellStyleSound": "Âm thanh", "bellStyleSound": "Âm thanh",
"bellStyleVisual": "Thị giác", "bellStyleVisual": "Thị giác",
"bellStyleBoth": "Cả hai", "bellStyleBoth": "Cả hai",
"bellStyleDesc": "Cách xử lý tín hiệu chuông của thiết bị đầu cuối (ký tự BEL, \\x07). Các chương trình kích hoạt tín hiệu này khi hoàn thành tác vụ, gặp lỗi hoặc để thông báo. \"Âm thanh\" phát ra tiếng bíp, \"Hình ảnh\" nhấp nháy màn hình trong giây lát, \"Cả hai\" thực hiện cả hai, \"Không\" tắt cảnh báo chuông.", "bellStyleDesc": "Cách xử lý tín hiệu chuông của thiết bị đầu cuối (ký tự BEL, \\x07). Các chương trình kích hoạt tín hiệu này khi hoàn thành tác vụ, gặp lỗi hoặc để nhận thông báo. \"Âm thanh\" phát ra tiếng bíp, \"Hình ảnh\" nhấp nháy màn hình trong giây lát, \"Cả hai\" thực hiện cả hai, \"Không\" tắt cảnh báo chuông.",
"rightClickSelectsWord": "Nhấp chuột phải chọn Word", "rightClickSelectsWord": "Nhấp chuột phải chọn Word",
"rightClickSelectsWordDesc": "Nhấp chuột phải sẽ chọn từ nằm dưới con trỏ.", "rightClickSelectsWordDesc": "Nhấp chuột phải sẽ chọn từ nằm dưới con trỏ.",
"fastScrollModifier": "Bộ điều chỉnh cuộn nhanh", "fastScrollModifier": "Bộ điều chỉnh cuộn nhanh",
@@ -1041,7 +1041,7 @@
"overrideCredentialUsername": "Ghi đè tên người dùng xác thực", "overrideCredentialUsername": "Ghi đè tên người dùng xác thực",
"overrideCredentialUsernameDesc": "Hãy sử dụng tên người dùng khác với tên người dùng đã lưu trong thông tin đăng nhập. Điều này cho phép bạn sử dụng cùng một thông tin đăng nhập với các tên người dùng khác nhau.", "overrideCredentialUsernameDesc": "Hãy sử dụng tên người dùng khác với tên người dùng đã lưu trong thông tin đăng nhập. Điều này cho phép bạn sử dụng cùng một thông tin đăng nhập với các tên người dùng khác nhau.",
"jumpHosts": "Người dẫn chương trình nhảy", "jumpHosts": "Người dẫn chương trình nhảy",
"jumpHostsDescription": "Máy chủ trung gian (còn được gọi là máy chủ bảo vệ) cho phép bạn kết nối đến máy chủ đích thông qua một hoặc nhiều máy chủ trung gian. Điều này rất hữu ích khi truy cập các máy chủ nằm sau tường lửa hoặc trong mạng riêng.", "jumpHostsDescription": "Máy chủ trung gian (còn được gọi là máy chủ bảo vệ) cho phép bạn kết nối đến máy chủ mục tiêu thông qua một hoặc nhiều máy chủ trung gian. Điều này hữu ích khi truy cập các máy chủ nằm sau tường lửa hoặc trong mạng riêng.",
"jumpHostChain": "Chuỗi máy chủ nhảy", "jumpHostChain": "Chuỗi máy chủ nhảy",
"addJumpHost": "Thêm Jump Host", "addJumpHost": "Thêm Jump Host",
"selectServer": "Chọn máy chủ", "selectServer": "Chọn máy chủ",
@@ -1078,7 +1078,7 @@
"socks5PresetCreated": "Chuỗi proxy được thiết lập sẵn", "socks5PresetCreated": "Chuỗi proxy được thiết lập sẵn",
"socks5PresetUpdated": "Cài đặt sẵn chuỗi proxy đã được cập nhật", "socks5PresetUpdated": "Cài đặt sẵn chuỗi proxy đã được cập nhật",
"socks5PresetDeleted": "Chuỗi proxy đã bị xóa cài đặt sẵn", "socks5PresetDeleted": "Chuỗi proxy đã bị xóa cài đặt sẵn",
"socks5PresetSaved": "Cài đặt sẵn \"{{name}}\" đã được lưu thành công.", "socks5PresetSaved": "Cài đặt sẵn \"{{name}}\" đã được lưu thành công",
"socks5PresetSaveError": "Không thể lưu cài đặt trước", "socks5PresetSaveError": "Không thể lưu cài đặt trước",
"socks5PresetNameRequired": "Tên cài đặt sẵn là bắt buộc", "socks5PresetNameRequired": "Tên cài đặt sẵn là bắt buộc",
"socks5EmptyChainError": "Không thể lưu chuỗi proxy trống.", "socks5EmptyChainError": "Không thể lưu chuỗi proxy trống.",
@@ -1086,7 +1086,7 @@
"socks5HostDescription": "Tên máy chủ hoặc địa chỉ IP của máy chủ proxy SOCKS", "socks5HostDescription": "Tên máy chủ hoặc địa chỉ IP của máy chủ proxy SOCKS",
"socks5PortDescription": "Số cổng của máy chủ proxy SOCKS (mặc định: 1080)", "socks5PortDescription": "Số cổng của máy chủ proxy SOCKS (mặc định: 1080)",
"addProxyNode": "Thêm nút Proxy", "addProxyNode": "Thêm nút Proxy",
"noProxyNodes": "Chưa có nút proxy nào được cấu hình. Nhấp vào \"Thêm nút Proxy\" để thêm một nút.", "noProxyNodes": "Chưa có nút proxy nào được cấu hình. Nhấp vào 'Thêm nút Proxy' để thêm một nút.",
"proxyNode": "Nút ủy quyền", "proxyNode": "Nút ủy quyền",
"proxyType": "Loại Proxy", "proxyType": "Loại Proxy",
"quickActions": "Thao tác nhanh", "quickActions": "Thao tác nhanh",
@@ -1103,7 +1103,7 @@
"sudoPasswordDesc": "Mật khẩu tùy chọn cho các lệnh sudo (hữu ích khi xác thực bằng khóa)", "sudoPasswordDesc": "Mật khẩu tùy chọn cho các lệnh sudo (hữu ích khi xác thực bằng khóa)",
"socks4": "TẤT 4", "socks4": "TẤT 4",
"socks5": "TẤT 5", "socks5": "TẤT 5",
"executeSnippetOnConnect": "Thực thi đoạn mã khi thiết bị đầu cuối kết nối.", "executeSnippetOnConnect": "Thực thi đoạn mã khi thiết bị đầu cuối được kết nối.",
"autoMosh": "Auto-MOSH", "autoMosh": "Auto-MOSH",
"autoMoshDesc": "Tự động chạy lệnh MOSH khi kết nối", "autoMoshDesc": "Tự động chạy lệnh MOSH khi kết nối",
"moshCommand": "Bộ chỉ huy MOSH", "moshCommand": "Bộ chỉ huy MOSH",
@@ -1167,11 +1167,11 @@
"failedToStopContainer": "Không thể dừng container: {{error}}", "failedToStopContainer": "Không thể dừng container: {{error}}",
"containerRestarted": "Container {{name}} đã khởi động lại", "containerRestarted": "Container {{name}} đã khởi động lại",
"failedToRestartContainer": "Không thể khởi động lại container: {{error}}", "failedToRestartContainer": "Không thể khởi động lại container: {{error}}",
"containerUnpaused": "Container {{name}} đã được bỏ tạm dừng", "containerUnpaused": "Container {{name}} unpaused",
"containerPaused": "Container {{name}} tạm dừng", "containerPaused": "Container {{name}} tạm dừng",
"failedToTogglePauseContainer": "Không thể tải xuống container {{action}}: {{error}}", "failedToTogglePauseContainer": "Không thể tải xuống container {{action}} : {{error}}",
"containerRemoved": "Container {{name}} đã bị xóa", "containerRemoved": "Container {{name}} đã bị xóa",
"failedToRemoveContainer": "Không thể xóa container: {{error}}", "failedToRemoveContainer": "Không thể xóa vùng chứa: {{error}}",
"image": "Hình ảnh:", "image": "Hình ảnh:",
"idLabel": "NHẬN DẠNG:", "idLabel": "NHẬN DẠNG:",
"ports": "Cảng:", "ports": "Cảng:",
@@ -1183,7 +1183,7 @@
"pause": "Tạm dừng", "pause": "Tạm dừng",
"restart": "Khởi động lại", "restart": "Khởi động lại",
"removeContainer": "Tháo thùng chứa", "removeContainer": "Tháo thùng chứa",
"confirmRemoveContainer": "Bạn có chắc chắn muốn xóa container \"{{name}}\" không?", "confirmRemoveContainer": "Bạn có chắc chắn muốn xóa vùng chứa \"{{name}}\" không?",
"runningContainerWarning": "Cảnh báo: Container này hiện đang chạy và sẽ bị buộc phải gỡ bỏ.", "runningContainerWarning": "Cảnh báo: Container này hiện đang chạy và sẽ bị buộc phải gỡ bỏ.",
"removing": "Đang xóa:", "removing": "Đang xóa:",
"containerNotFound": "Không tìm thấy container", "containerNotFound": "Không tìm thấy container",
@@ -1195,7 +1195,7 @@
"failedToDownloadLogs": "Không thể tải xuống nhật ký: {{error}}", "failedToDownloadLogs": "Không thể tải xuống nhật ký: {{error}}",
"linesToShow": "Các dòng để hiển thị", "linesToShow": "Các dòng để hiển thị",
"last50Lines": "50 dòng cuối", "last50Lines": "50 dòng cuối",
"last100Lines": "100 dòng cuối", "last100Lines": "100 dòng cuối cùng",
"last500Lines": "500 dòng cuối", "last500Lines": "500 dòng cuối",
"last1000Lines": "1000 dòng cuối cùng", "last1000Lines": "1000 dòng cuối cùng",
"allLogs": "Tất cả nhật ký", "allLogs": "Tất cả nhật ký",
@@ -1234,9 +1234,9 @@
"reconnected": "Đã kết nối lại thành công", "reconnected": "Đã kết nối lại thành công",
"maxReconnectAttemptsReached": "Đã đạt số lần thử kết nối lại tối đa.", "maxReconnectAttemptsReached": "Đã đạt số lần thử kết nối lại tối đa.",
"connectionTimeout": "Hết thời gian chờ kết nối", "connectionTimeout": "Hết thời gian chờ kết nối",
"terminalTitle": "Nhà ga - {{host}}", "terminalTitle": "Thiết bị đầu cuối - {{host}}",
"terminalWithPath": "Nhà ga - {{host}}:{{path}}", "terminalWithPath": "Thiết bị đầu cuối - {{host}}:{{path}}",
"runTitle": "Chạy {{command}} - {{host}}", "runTitle": "Đang chạy {{command}} - {{host}}",
"totpRequired": "Yêu cầu xác thực hai yếu tố", "totpRequired": "Yêu cầu xác thực hai yếu tố",
"totpCodeLabel": "Mã xác minh", "totpCodeLabel": "Mã xác minh",
"totpPlaceholder": "000000", "totpPlaceholder": "000000",
@@ -1255,16 +1255,16 @@
"downloadFile": "Tải xuống", "downloadFile": "Tải xuống",
"extractArchive": "Trích xuất tệp lưu trữ", "extractArchive": "Trích xuất tệp lưu trữ",
"extractingArchive": "Đang trích xuất {{name}}...", "extractingArchive": "Đang trích xuất {{name}}...",
"archiveExtractedSuccessfully": "{{name}} đã được trích xuất thành công", "archiveExtractedSuccessfully": "{{name}} đã trích xuất thành công",
"extractFailed": "Trích xuất thất bại", "extractFailed": "Trích xuất thất bại",
"compressFile": "Nén tệp", "compressFile": "Nén tệp",
"compressFiles": "Nén tệp", "compressFiles": "Nén tệp",
"compressFilesDesc": "Nén {{count}} mục thành một tệp lưu trữ", "compressFilesDesc": "Nén {{count}} mục vào kho lưu trữ",
"archiveName": "Tên kho lưu trữ", "archiveName": "Tên kho lưu trữ",
"enterArchiveName": "Nhập tên kho lưu trữ...", "enterArchiveName": "Nhập tên kho lưu trữ...",
"compressionFormat": "Định dạng nén", "compressionFormat": "Định dạng nén",
"selectedFiles": "Các tệp đã chọn", "selectedFiles": "Các tệp đã chọn",
"andMoreFiles": "và {{count}} nữa...", "andMoreFiles": "và {{count}} nhiều hơn nữa...",
"compress": "Nén", "compress": "Nén",
"compressingFiles": "Nén {{count}} mục thành {{name}}...", "compressingFiles": "Nén {{count}} mục thành {{name}}...",
"filesCompressedSuccessfully": "{{name}} đã được tạo thành công", "filesCompressedSuccessfully": "{{name}} đã được tạo thành công",
@@ -1311,9 +1311,9 @@
"newName": "Tên mới", "newName": "Tên mới",
"thisIsDirectoryRename": "Đây là một thư mục", "thisIsDirectoryRename": "Đây là một thư mục",
"renaming": "Đổi tên...", "renaming": "Đổi tên...",
"fileUploadedSuccessfully": "Tệp \"{{name}}\" đã được tải lên thành công.", "fileUploadedSuccessfully": "Tệp \"{{name}}\" đã được tải lên thành công",
"failedToUploadFile": "Không thể tải tệp lên.", "failedToUploadFile": "Không thể tải tệp lên.",
"fileDownloadedSuccessfully": "Tệp \"{{name}}\" đã được tải xuống thành công.", "fileDownloadedSuccessfully": "Tệp \"{{name}}\" đã được tải xuống thành công",
"failedToDownloadFile": "Không thể tải xuống tệp.", "failedToDownloadFile": "Không thể tải xuống tệp.",
"noFileContent": "Không nhận được nội dung tệp nào.", "noFileContent": "Không nhận được nội dung tệp nào.",
"filePath": "Đường dẫn tệp", "filePath": "Đường dẫn tệp",
@@ -1322,10 +1322,10 @@
"folderCreatedSuccessfully": "Thư mục \"{{name}}\" đã được tạo thành công", "folderCreatedSuccessfully": "Thư mục \"{{name}}\" đã được tạo thành công",
"failedToCreateFolder": "Không thể tạo thư mục", "failedToCreateFolder": "Không thể tạo thư mục",
"failedToCreateItem": "Không thể tạo mục", "failedToCreateItem": "Không thể tạo mục",
"operationFailed": "Thao tác {{operation}} đã thất bại đối với {{name}}: {{error}}", "operationFailed": "Thao tác {{operation}} thất bại đối với {{name}}: {{error}}",
"failedToResolveSymlink": "Không thể giải quyết liên kết tượng trưng", "failedToResolveSymlink": "Không thể giải quyết liên kết tượng trưng",
"itemDeletedSuccessfully": "{{type}} đã được xóa thành công", "itemDeletedSuccessfully": "{{type}} đã xóa thành công",
"itemsDeletedSuccessfully": "Đã xóa thành công 144 mục", "itemsDeletedSuccessfully": "{{count}} mục đã được xóa thành công",
"failedToDeleteItems": "Không thể xóa các mục", "failedToDeleteItems": "Không thể xóa các mục",
"dragFilesToUpload": "Kéo thả tệp vào đây để tải lên", "dragFilesToUpload": "Kéo thả tệp vào đây để tải lên",
"emptyFolder": "Thư mục này trống", "emptyFolder": "Thư mục này trống",
@@ -1347,25 +1347,25 @@
"delete": "Xóa bỏ", "delete": "Xóa bỏ",
"properties": "Của cải", "properties": "Của cải",
"refresh": "Làm cho khỏe lại", "refresh": "Làm cho khỏe lại",
"downloadFiles": "Tải xuống {{count}} tập tin vào Trình duyệt", "downloadFiles": "Tải xuống các tệp {{count}} vào Trình duyệt",
"copyFiles": "Sao chép {{count}} mục", "copyFiles": "Sao chép các mục {{count}}",
"cutFiles": "Cắt {{count}} mục", "cutFiles": "Cắt các mục {{count}}",
"deleteFiles": "Xóa {{count}} mục", "deleteFiles": "Xóa {{count}} mục",
"filesCopiedToClipboard": "{{count}} mục đã được sao chép vào clipboard", "filesCopiedToClipboard": "{{count}} mục đã được sao chép vào clipboard",
"filesCutToClipboard": "{{count}} mục đã được cắt vào clipboard", "filesCutToClipboard": "{{count}} các mục đã được cắt vào clipboard",
"pathCopiedToClipboard": "Đường dẫn đã được sao chép vào clipboard", "pathCopiedToClipboard": "Đường dẫn đã được sao chép vào clipboard",
"pathsCopiedToClipboard": "{{count}} đường dẫn đã được sao chép vào clipboard", "pathsCopiedToClipboard": "{{count}} Đường dẫn đã được sao chép vào clipboard",
"failedToCopyPath": "Không thể sao chép đường dẫn vào clipboard", "failedToCopyPath": "Không thể sao chép đường dẫn vào clipboard",
"movedItems": "Đã di chuyển {{count}} mục", "movedItems": "Đã di chuyển {{count}} mục",
"failedToDeleteItem": "Không thể xóa mục", "failedToDeleteItem": "Không thể xóa mục",
"itemRenamedSuccessfully": "{{count}} đã được đổi tên thành công", "itemRenamedSuccessfully": "{{type}} đã đổi tên thành công",
"failedToRenameItem": "Không thể đổi tên mục", "failedToRenameItem": "Không thể đổi tên mục",
"download": "Tải xuống", "download": "Tải xuống",
"permissions": "Quyền hạn", "permissions": "Quyền hạn",
"size": "Kích cỡ", "size": "Kích cỡ",
"modified": "Đã sửa đổi", "modified": "Đã sửa đổi",
"path": "Con đường", "path": "Con đường",
"confirmDelete": "Bạn có chắc chắn muốn xóa {{type}} không?", "confirmDelete": "Bạn có chắc chắn muốn xóa {{name}}không?",
"uploadSuccess": "Tệp đã được tải lên thành công.", "uploadSuccess": "Tệp đã được tải lên thành công.",
"uploadFailed": "Tải lên tệp không thành công", "uploadFailed": "Tải lên tệp không thành công",
"downloadSuccess": "Tệp đã được tải xuống thành công.", "downloadSuccess": "Tệp đã được tải xuống thành công.",
@@ -1388,11 +1388,11 @@
"connectToServer": "Kết nối với máy chủ", "connectToServer": "Kết nối với máy chủ",
"selectServerToEdit": "Chọn máy chủ từ thanh bên để bắt đầu chỉnh sửa tệp.", "selectServerToEdit": "Chọn máy chủ từ thanh bên để bắt đầu chỉnh sửa tệp.",
"fileOperations": "Thao tác tệp", "fileOperations": "Thao tác tệp",
"confirmDeleteMessage": "Bạn có chắc chắn muốn xóa {{name}} không?", "confirmDeleteMessage": "Bạn có chắc chắn muốn xóa {{name}}không?",
"confirmDeleteSingleItem": "Bạn có chắc chắn muốn xóa vĩnh viễn \"{{name}}\" không?", "confirmDeleteSingleItem": "Bạn có chắc chắn muốn xóa vĩnh viễn \"{{name}}\" không?",
"confirmDeleteMultipleItems": "Bạn có chắc chắn muốn xóa vĩnh viễn {{name}} mục không?", "confirmDeleteMultipleItems": "Bạn có chắc chắn muốn xóa vĩnh viễn {{count}} mục không?",
"confirmDeleteMultipleItemsWithFolders": "Bạn có chắc chắn muốn xóa vĩnh viễn {{count}} mục không? Việc này bao gồm cả thư mục và nội dung bên trong chúng.", "confirmDeleteMultipleItemsWithFolders": "Bạn có chắc chắn muốn xóa vĩnh viễn {{count}} mục không? Việc này bao gồm cả thư mục và nội dung bên trong chúng.",
"confirmDeleteFolder": "Bạn có chắc chắn muốn xóa vĩnh viễn thư mục \"{{count}}\" và tất cả nội dung bên trong không?", "confirmDeleteFolder": "Bạn có chắc chắn muốn xóa vĩnh viễn thư mục \"{{name}}\" và tất cả nội dung bên trong không?",
"deleteDirectoryWarning": "Thao tác này sẽ xóa thư mục và toàn bộ nội dung bên trong.", "deleteDirectoryWarning": "Thao tác này sẽ xóa thư mục và toàn bộ nội dung bên trong.",
"actionCannotBeUndone": "Hành động này không thể đảo ngược.", "actionCannotBeUndone": "Hành động này không thể đảo ngược.",
"permanentDeleteWarning": "Thao tác này không thể hoàn tác. Mục (các mục) sẽ bị xóa vĩnh viễn khỏi máy chủ.", "permanentDeleteWarning": "Thao tác này không thể hoàn tác. Mục (các mục) sẽ bị xóa vĩnh viễn khỏi máy chủ.",
@@ -1421,16 +1421,16 @@
"selectLocationToSave": "Chọn vị trí lưu", "selectLocationToSave": "Chọn vị trí lưu",
"openTerminalInFolder": "Mở cửa sổ dòng lệnh trong thư mục này", "openTerminalInFolder": "Mở cửa sổ dòng lệnh trong thư mục này",
"openTerminalInFileLocation": "Mở cửa sổ dòng lệnh tại vị trí tệp", "openTerminalInFileLocation": "Mở cửa sổ dòng lệnh tại vị trí tệp",
"terminalWithPath": "Nhà ga - {{name}}:{{host}}", "terminalWithPath": "Thiết bị đầu cuối - {{host}}:{{path}}",
"runningFile": "Đang chạy - {{path}}", "runningFile": "Đang chạy - {{file}}",
"onlyRunExecutableFiles": "Chỉ có thể chạy các tệp thực thi.", "onlyRunExecutableFiles": "Chỉ có thể chạy các tệp thực thi.",
"noHostSelected": "Chưa chọn máy chủ nào", "noHostSelected": "Chưa chọn máy chủ nào",
"starred": "Đã đóng dấu sao", "starred": "Đã đóng dấu sao",
"shortcuts": "Phím tắt", "shortcuts": "Phím tắt",
"directories": "Danh mục", "directories": "Danh mục",
"removedFromRecentFiles": "Đã xóa \"{{file}}\" khỏi các tệp gần đây", "removedFromRecentFiles": "Đã xóa \"{{name}}\" khỏi các tệp gần đây",
"removeFailed": "Xóa không thành công", "removeFailed": "Xóa không thành công",
"unpinnedSuccessfully": "Đã gỡ ghim thành công \"{{name}}\"", "unpinnedSuccessfully": "Đã gỡ ghim \"{{name}}\" thành công",
"unpinFailed": "Gỡ ghim không thành công", "unpinFailed": "Gỡ ghim không thành công",
"removedShortcut": "Đã xóa lối tắt \"{{name}}\"", "removedShortcut": "Đã xóa lối tắt \"{{name}}\"",
"removeShortcutFailed": "Xóa lối tắt không thành công", "removeShortcutFailed": "Xóa lối tắt không thành công",
@@ -1440,7 +1440,7 @@
"clearAllRecentFiles": "Xóa tất cả các tệp gần đây", "clearAllRecentFiles": "Xóa tất cả các tệp gần đây",
"unpinFile": "Gỡ ghim tệp", "unpinFile": "Gỡ ghim tệp",
"removeShortcut": "Xóa lối tắt", "removeShortcut": "Xóa lối tắt",
"saveFilesToSystem": "Lưu {{name}} tập tin dưới dạng...", "saveFilesToSystem": "Lưu các tập tin {{count}} dưới dạng...",
"pinFile": "Tệp ghim", "pinFile": "Tệp ghim",
"addToShortcuts": "Thêm vào lối tắt", "addToShortcuts": "Thêm vào lối tắt",
"downloadToDefaultLocation": "Tải xuống vị trí mặc định", "downloadToDefaultLocation": "Tải xuống vị trí mặc định",
@@ -1466,7 +1466,7 @@
"replaceAll": "Thay thế tất cả", "replaceAll": "Thay thế tất cả",
"downloadInstead": "Tải xuống thay vì", "downloadInstead": "Tải xuống thay vì",
"keyboardShortcuts": "Phím tắt", "keyboardShortcuts": "Phím tắt",
"searchAndReplace": "Tìm kiếm & Thay thế", "searchAndReplace": "Tìm kiếm và thay thế",
"editing": "Chỉnh sửa", "editing": "Chỉnh sửa",
"navigation": "Điều hướng", "navigation": "Điều hướng",
"code": "Mã số", "code": "Mã số",
@@ -1491,33 +1491,33 @@
"unknownSize": "Kích thước không xác định", "unknownSize": "Kích thước không xác định",
"fileIsEmpty": "Tệp tin trống", "fileIsEmpty": "Tệp tin trống",
"largeFileWarning": "Cảnh báo về tệp tin lớn", "largeFileWarning": "Cảnh báo về tệp tin lớn",
"largeFileWarningDesc": "Tệp này có kích thước {{count}}, có thể gây ra sự cố về hiệu năng khi mở dưới dạng văn bản.", "largeFileWarningDesc": "Tệp này có kích thước {{size}} , có thể gây ra sự cố về hiệu năng khi mở dưới dạng văn bản.",
"fileNotFoundAndRemoved": "Tệp \"{{size}}\" không được tìm thấy và đã bị xóa khỏi các tệp gần đây/được ghim.", "fileNotFoundAndRemoved": "Tệp \"{{name}}\" không được tìm thấy và đã bị xóa khỏi các tệp gần đây/được ghim.",
"failedToLoadFile": "Không thể tải tệp: {{name}}", "failedToLoadFile": "Không thể tải tệp: {{error}}",
"serverErrorOccurred": "Đã xảy ra lỗi máy chủ. Vui lòng thử lại sau.", "serverErrorOccurred": "Đã xảy ra lỗi máy chủ. Vui lòng thử lại sau.",
"autoSaveFailed": "Lưu tự động thất bại", "autoSaveFailed": "Lưu tự động thất bại",
"fileAutoSaved": "Tệp đã được tự động lưu", "fileAutoSaved": "Tệp đã được tự động lưu",
"moveFileFailed": "Không thể di chuyển {{error}}", "moveFileFailed": "Không thể di chuyển {{name}}",
"moveOperationFailed": "Thao tác di chuyển thất bại", "moveOperationFailed": "Thao tác di chuyển thất bại",
"canOnlyCompareFiles": "Chỉ có thể so sánh hai tệp", "canOnlyCompareFiles": "Chỉ có thể so sánh hai tệp",
"comparingFiles": "So sánh các tập tin: {{name}} và {{file1}}", "comparingFiles": "So sánh các tập tin: {{file1}} và {{file2}}",
"dragFailed": "Thao tác kéo thả thất bại", "dragFailed": "Thao tác kéo thả thất bại",
"filePinnedSuccessfully": "Tệp \"{{file2}}\" đã được ghim thành công", "filePinnedSuccessfully": "Tệp \"{{name}}\" đã được ghim thành công",
"pinFileFailed": "Không thể ghim tệp", "pinFileFailed": "Không thể ghim tệp",
"fileUnpinnedSuccessfully": "Tệp \"{{name}}\" đã được gỡ ghim thành công", "fileUnpinnedSuccessfully": "Tệp \"{{name}}\" đã được gỡ ghim thành công",
"unpinFileFailed": "Không thể bỏ ghim tệp.", "unpinFileFailed": "Không thể bỏ ghim tệp.",
"shortcutAddedSuccessfully": "Thêm lối tắt thư mục \"{{name}}\" thành công", "shortcutAddedSuccessfully": "Thêm lối tắt thư mục \"{{name}}\" thành công",
"addShortcutFailed": "Không thể thêm lối tắt", "addShortcutFailed": "Không thể thêm lối tắt",
"operationCompletedSuccessfully": "{{name}} {{operation}} mục thành công", "operationCompletedSuccessfully": "{{operation}} {{count}} mục thành công",
"operationCompleted": "{{count}} {{operation}} mục", "operationCompleted": "{{operation}} {{count}} mục",
"downloadFileSuccess": "Tệp {{count}} đã được tải xuống thành công", "downloadFileSuccess": "Tệp {{name}} đã được tải xuống thành công",
"downloadFileFailed": "Tải xuống thất bại", "downloadFileFailed": "Tải xuống thất bại",
"moveTo": "Di chuyển tới {{name}}", "moveTo": "Di chuyển đến {{name}}",
"diffCompareWith": "So sánh khác biệt với {{name}}", "diffCompareWith": "So sánh khác biệt với {{name}}",
"dragOutsideToDownload": "Kéo chuột ra ngoài cửa sổ để tải xuống (187 tập tin)", "dragOutsideToDownload": "Kéo chuột ra ngoài cửa sổ để tải xuống ({{count}} tập tin)",
"newFolderDefault": "Thư mục mới", "newFolderDefault": "Thư mục mới",
"newFileDefault": "NewFile.txt", "newFileDefault": "NewFile.txt",
"successfullyMovedItems": "Đã chuyển thành công {{name}} mục đến {{count}}", "successfullyMovedItems": "Đã chuyển thành công {{count}} mục đến {{target}}",
"move": "Di chuyển", "move": "Di chuyển",
"searchInFile": "Tìm kiếm trong tệp (Ctrl+F)", "searchInFile": "Tìm kiếm trong tệp (Ctrl+F)",
"showKeyboardShortcuts": "Hiển thị các phím tắt", "showKeyboardShortcuts": "Hiển thị các phím tắt",
@@ -1527,10 +1527,10 @@
"compare": "So sánh", "compare": "So sánh",
"sideBySide": "Cạnh nhau", "sideBySide": "Cạnh nhau",
"inline": "Nội tuyến", "inline": "Nội tuyến",
"fileComparison": "So sánh tập tin: {{count}} so với {{target}}", "fileComparison": "So sánh tập tin: {{file1}} so với {{file2}}",
"fileTooLarge": "Tệp quá lớn: {{file1}}", "fileTooLarge": "Tệp quá lớn: {{error}}",
"sshConnectionFailed": "Kết nối SSH thất bại. Vui lòng kiểm tra kết nối của bạn tới {{file2}} ({{error}}:{{name}})", "sshConnectionFailed": "Kết nối SSH thất bại. Vui lòng kiểm tra kết nối của bạn tới {{name}} ({{ip}}:{{port}})",
"loadFileFailed": "Không thể tải tệp: {{ip}}", "loadFileFailed": "Không thể tải tệp: {{error}}",
"connectedSuccessfully": "Kết nối thành công", "connectedSuccessfully": "Kết nối thành công",
"totpVerificationFailed": "Xác thực TOTP thất bại", "totpVerificationFailed": "Xác thực TOTP thất bại",
"verificationCodePrompt": "Mã xác minh:", "verificationCodePrompt": "Mã xác minh:",
@@ -1573,10 +1573,10 @@
"disconnect": "Ngắt kết nối", "disconnect": "Ngắt kết nối",
"cancel": "Hủy bỏ", "cancel": "Hủy bỏ",
"port": "Cảng", "port": "Cảng",
"attempt": "Lần thử {{port}} trong số {{error}}", "attempt": "Lần thử {{current}} của {{max}}",
"nextRetryIn": "Lần thử lại tiếp theo sau {{current}} giây", "nextRetryIn": "Lần thử lại tiếp theo sau {{seconds}} giây",
"checkDockerLogs": "Kiểm tra nhật ký Docker để tìm nguyên nhân lỗi, tham gia nhóm.", "checkDockerLogs": "Kiểm tra nhật ký Docker để tìm nguyên nhân lỗi, tham gia nhóm.",
"orCreate": "hoặc tạo một", "orCreate": "hoặc tạo một ",
"noTunnelConnections": "Không có kết nối đường hầm nào được cấu hình.", "noTunnelConnections": "Không có kết nối đường hầm nào được cấu hình.",
"tunnelConnections": "Kết nối đường hầm", "tunnelConnections": "Kết nối đường hầm",
"addTunnel": "Thêm đường hầm", "addTunnel": "Thêm đường hầm",
@@ -1598,7 +1598,7 @@
"remote": "Xa", "remote": "Xa",
"dynamic": "Năng động", "dynamic": "Năng động",
"unknownConnectionStatus": "Không rõ", "unknownConnectionStatus": "Không rõ",
"portMapping": "Cổng {{max}} → {{seconds}}:{{sourcePort}}", "portMapping": "Cổng {{sourcePort}} → {{endpointHost}}:{{endpointPort}}",
"endpointHostNotFound": "Không tìm thấy máy chủ điểm cuối", "endpointHostNotFound": "Không tìm thấy máy chủ điểm cuối",
"discord": "Discord", "discord": "Discord",
"githubIssue": "Sự cố trên GitHub", "githubIssue": "Sự cố trên GitHub",
@@ -1611,7 +1611,7 @@
"disk": "Đĩa", "disk": "Đĩa",
"network": "Mạng", "network": "Mạng",
"uptime": "Thời gian hoạt động", "uptime": "Thời gian hoạt động",
"loadAverage": "Trung bình: {{endpointHost}}, {{endpointPort}}, {{avg1}}", "loadAverage": "Trung bình: {{avg1}}, {{avg5}}, {{avg15}}",
"processes": "Quy trình", "processes": "Quy trình",
"connections": "Kết nối", "connections": "Kết nối",
"usage": "Cách sử dụng", "usage": "Cách sử dụng",
@@ -1623,9 +1623,9 @@
"refreshStatusAndMetrics": "Cập nhật trạng thái và số liệu", "refreshStatusAndMetrics": "Cập nhật trạng thái và số liệu",
"refreshStatus": "Làm mới trạng thái", "refreshStatus": "Làm mới trạng thái",
"fileManagerAlreadyOpen": "Trình quản lý tập tin đã được mở cho máy chủ này.", "fileManagerAlreadyOpen": "Trình quản lý tập tin đã được mở cho máy chủ này.",
"openFileManager": "Mở Trình quản lý tệp", "openFileManager": "Mở trình quản lý tệp",
"cpuCores_one": "CPU {{avg5}}", "cpuCores_one": "{{count}} CPU",
"cpuCores_other": "CPU {{avg15}}", "cpuCores_other": "{{count}} CPU",
"naCpus": "Không áp dụng CPU", "naCpus": "Không áp dụng CPU",
"loadAverageNA": "Trung bình: Không xác định", "loadAverageNA": "Trung bình: Không xác định",
"cpuUsage": "Mức sử dụng CPU", "cpuUsage": "Mức sử dụng CPU",
@@ -1650,7 +1650,7 @@
"totpInvalidCode": "Mã xác minh không hợp lệ", "totpInvalidCode": "Mã xác minh không hợp lệ",
"totpCancelled": "Việc thu thập số liệu đã bị hủy bỏ.", "totpCancelled": "Việc thu thập số liệu đã bị hủy bỏ.",
"authenticationFailed": "Xác thực thất bại", "authenticationFailed": "Xác thực thất bại",
"noneAuthNotSupported": "Server Stats không hỗ trợ loại xác thực 'none'.", "noneAuthNotSupported": "Server Stats không hỗ trợ loại xác thực 'non'.",
"load": "Trọng tải", "load": "Trọng tải",
"editLayout": "Chỉnh sửa bố cục", "editLayout": "Chỉnh sửa bố cục",
"cancelEdit": "Hủy bỏ", "cancelEdit": "Hủy bỏ",
@@ -1678,8 +1678,8 @@
"noRecentLoginData": "Không có dữ liệu đăng nhập gần đây", "noRecentLoginData": "Không có dữ liệu đăng nhập gần đây",
"from": "từ", "from": "từ",
"quickActions": "Thao tác nhanh", "quickActions": "Thao tác nhanh",
"executeQuickAction": "Thực thi {{count}}", "executeQuickAction": "Thực thi {{name}}",
"executingQuickAction": "Đang thực thi {{count}}...", "executingQuickAction": "Đang thực thi {{name}}...",
"quickActionSuccess": "{{name}} đã hoàn thành thành công", "quickActionSuccess": "{{name}} đã hoàn thành thành công",
"quickActionFailed": "{{name}} thất bại", "quickActionFailed": "{{name}} thất bại",
"quickActionError": "Không thể thực thi {{name}}" "quickActionError": "Không thể thực thi {{name}}"
@@ -1733,7 +1733,7 @@
"disableTwoFactorWarning": "Việc vô hiệu hóa xác thực hai yếu tố sẽ khiến tài khoản của bạn kém an toàn hơn.", "disableTwoFactorWarning": "Việc vô hiệu hóa xác thực hai yếu tố sẽ khiến tài khoản của bạn kém an toàn hơn.",
"passwordOrTotpCode": "Mật khẩu hoặc mã TOTP", "passwordOrTotpCode": "Mật khẩu hoặc mã TOTP",
"or": "Hoặc", "or": "Hoặc",
"generateNewBackupCodesText": "Tạo mã sao lưu mới nếu bạn đã làm mất mã hiện có.", "generateNewBackupCodesText": "Hãy tạo mã sao lưu mới nếu bạn đã mất mã hiện có.",
"generateNewBackupCodes": "Tạo mã sao lưu mới", "generateNewBackupCodes": "Tạo mã sao lưu mới",
"yourBackupCodes": "Mã sao lưu của bạn", "yourBackupCodes": "Mã sao lưu của bạn",
"download": "Tải xuống", "download": "Tải xuống",
@@ -1814,8 +1814,8 @@
"invalidAuthUrl": "URL xác thực không hợp lệ được nhận từ máy chủ phụ trợ.", "invalidAuthUrl": "URL xác thực không hợp lệ được nhận từ máy chủ phụ trợ.",
"invalidInput": "Đầu vào không hợp lệ", "invalidInput": "Đầu vào không hợp lệ",
"requiredField": "Trường này là bắt buộc", "requiredField": "Trường này là bắt buộc",
"minLength": "Độ dài tối thiểu là {{name}}", "minLength": "Độ dài tối thiểu là {{min}}",
"maxLength": "Độ dài tối đa là {{name}}", "maxLength": "Độ dài tối đa là {{max}}",
"invalidEmail": "Địa chỉ email không hợp lệ", "invalidEmail": "Địa chỉ email không hợp lệ",
"passwordMismatch": "Mật khẩu không khớp", "passwordMismatch": "Mật khẩu không khớp",
"passwordLoginDisabled": "Chức năng đăng nhập bằng tên người dùng/mật khẩu hiện đang bị vô hiệu hóa.", "passwordLoginDisabled": "Chức năng đăng nhập bằng tên người dùng/mật khẩu hiện đang bị vô hiệu hóa.",
@@ -1835,7 +1835,7 @@
"updateError": "Cập nhật không thành công", "updateError": "Cập nhật không thành công",
"copySuccess": "Đã sao chép vào clipboard", "copySuccess": "Đã sao chép vào clipboard",
"copyError": "Không thể sao chép", "copyError": "Không thể sao chép",
"copiedToClipboard": "{{min}} đã được sao chép vào clipboard", "copiedToClipboard": "{{item}} đã sao chép vào clipboard",
"connectionEstablished": "Kết nối đã được thiết lập", "connectionEstablished": "Kết nối đã được thiết lập",
"connectionClosed": "Kết nối đã bị đóng", "connectionClosed": "Kết nối đã bị đóng",
"reconnecting": "Đang kết nối lại...", "reconnecting": "Đang kết nối lại...",
@@ -1926,7 +1926,7 @@
"usernameField": "tên", "usernameField": "tên",
"scopes": "hồ sơ email openid", "scopes": "hồ sơ email openid",
"userinfoUrl": "https://your-provider.com/application/o/userinfo/", "userinfoUrl": "https://your-provider.com/application/o/userinfo/",
"enterUsername": "Nhập tên người dùng để trở thành quản trị viên", "enterUsername": "Nhập tên người dùng để trở thành quản trị viên.",
"searchHosts": "Tìm kiếm máy chủ theo tên, tên người dùng, địa chỉ IP, thư mục, thẻ...", "searchHosts": "Tìm kiếm máy chủ theo tên, tên người dùng, địa chỉ IP, thư mục, thẻ...",
"enterPassword": "Nhập mật khẩu của bạn", "enterPassword": "Nhập mật khẩu của bạn",
"totpCode": "Mã TOTP 6 chữ số", "totpCode": "Mã TOTP 6 chữ số",
@@ -1942,7 +1942,7 @@
"socks5Username": "tên người dùng ủy quyền", "socks5Username": "tên người dùng ủy quyền",
"socks5Password": "mật khẩu proxy", "socks5Password": "mật khẩu proxy",
"socks5PresetName": "Ví dụ: Chuỗi VPN công việc", "socks5PresetName": "Ví dụ: Chuỗi VPN công việc",
"socks5PresetDescription": "Ví dụ: Chuỗi proxy để truy cập máy chủ làm việc", "socks5PresetDescription": "Ví dụ: Chuỗi proxy để truy cập máy chủ công việc",
"moshCommand": "người dùng mosh@máy chủ", "moshCommand": "người dùng mosh@máy chủ",
"defaultPort": "22", "defaultPort": "22",
"defaultEndpointPort": "224", "defaultEndpointPort": "224",
@@ -1955,9 +1955,9 @@
"passwordRequired": "Cần có mật khẩu.", "passwordRequired": "Cần có mật khẩu.",
"failedToDeleteAccount": "Không thể xóa tài khoản", "failedToDeleteAccount": "Không thể xóa tài khoản",
"failedToMakeUserAdmin": "Không thể cấp quyền quản trị cho người dùng.", "failedToMakeUserAdmin": "Không thể cấp quyền quản trị cho người dùng.",
"userIsNowAdmin": "Người dùng {{max}} hiện là quản trị viên", "userIsNowAdmin": "Người dùng {{username}} hiện là quản trị viên",
"removeAdminConfirm": "Bạn có chắc chắn muốn xóa quyền quản trị khỏi {{item}} không?", "removeAdminConfirm": "Bạn có chắc chắn muốn xóa quyền quản trị khỏi {{username}}không?",
"deleteUserConfirm": "Bạn có chắc chắn muốn xóa người dùng {{username}} không? Hành động này không thể hoàn tác.", "deleteUserConfirm": "Bạn có chắc chắn muốn xóa người dùng {{username}}không? Hành động này không thể hoàn tác.",
"deleteAccount": "Xóa tài khoản", "deleteAccount": "Xóa tài khoản",
"closeDeleteAccount": "Đóng Xóa tài khoản", "closeDeleteAccount": "Đóng Xóa tài khoản",
"deleteAccountWarning": "Thao tác này không thể hoàn tác. Thao tác này sẽ xóa vĩnh viễn tài khoản của bạn và tất cả dữ liệu liên quan.", "deleteAccountWarning": "Thao tác này không thể hoàn tác. Thao tác này sẽ xóa vĩnh viễn tài khoản của bạn và tất cả dữ liệu liên quan.",
@@ -2142,15 +2142,15 @@
"createTempUser": "Tạo người dùng tạm thời", "createTempUser": "Tạo người dùng tạm thời",
"createTempUserDesc": "Tạo một người dùng bị hạn chế quyền truy cập trên máy chủ thay vì chia sẻ thông tin đăng nhập của bạn. Yêu cầu quyền sudo. Đây là tùy chọn an toàn nhất.", "createTempUserDesc": "Tạo một người dùng bị hạn chế quyền truy cập trên máy chủ thay vì chia sẻ thông tin đăng nhập của bạn. Yêu cầu quyền sudo. Đây là tùy chọn an toàn nhất.",
"expiresAt": "Hết hạn vào lúc", "expiresAt": "Hết hạn vào lúc",
"expiresIn": "Hết hạn sau {{username}} giờ", "expiresIn": "Hết hạn sau {{hours}} giờ",
"expired": "Hết hạn", "expired": "Hết hạn",
"grantedBy": "Được cấp bởi", "grantedBy": "Được cấp bởi",
"accessLevel": "Cấp độ truy cập", "accessLevel": "Cấp độ truy cập",
"lastAccessed": "Lần truy cập cuối cùng", "lastAccessed": "Lần truy cập cuối cùng",
"accessCount": "Số lượt truy cập", "accessCount": "Số lượt truy cập",
"revokeAccess": "Thu hồi quyền truy cập", "revokeAccess": "Thu hồi quyền truy cập",
"confirmRevokeAccess": "Bạn có chắc chắn muốn thu hồi quyền truy cập cho {{username}} không?", "confirmRevokeAccess": "Bạn có chắc chắn muốn thu hồi quyền truy cập cho {{username}}không?",
"hostSharedSuccessfully": "Máy chủ đã chia sẻ thành công với {{hours}}", "hostSharedSuccessfully": "Máy chủ đã chia sẻ thành công với {{username}}",
"hostAccessUpdated": "Cập nhật quyền truy cập máy chủ", "hostAccessUpdated": "Cập nhật quyền truy cập máy chủ",
"failedToShareHost": "Không thể chia sẻ máy chủ", "failedToShareHost": "Không thể chia sẻ máy chủ",
"accessRevokedSuccessfully": "Quyền truy cập đã bị thu hồi thành công.", "accessRevokedSuccessfully": "Quyền truy cập đã bị thu hồi thành công.",
@@ -2165,26 +2165,26 @@
"noAccessGranted": "Không có quyền truy cập nào được cấp cho máy chủ này.", "noAccessGranted": "Không có quyền truy cập nào được cấp cho máy chủ này.",
"noAccessGrantedMessage": "Chưa có người dùng nào được cấp quyền truy cập vào máy chủ này.", "noAccessGrantedMessage": "Chưa có người dùng nào được cấp quyền truy cập vào máy chủ này.",
"manageAccessFor": "Quản lý quyền truy cập cho", "manageAccessFor": "Quản lý quyền truy cập cho",
"totalAccessRecords": "{{username}} bản ghi truy cập", "totalAccessRecords": "{{count}} truy cập bản ghi(các)",
"neverAccessed": "Không bao giờ", "neverAccessed": "Không bao giờ",
"timesAccessed": "{{username}} lần", "timesAccessed": "{{count}} thời gian",
"daysRemaining": "{{count}} ngày", "daysRemaining": "{{days}} ngày",
"hoursRemaining": "{{count}} giờ", "hoursRemaining": "{{hours}} giờ",
"failedToFetchAccessList": "Không thể tải danh sách truy cập", "failedToFetchAccessList": "Không thể tải danh sách truy cập",
"currentAccess": "Truy cập hiện tại", "currentAccess": "Truy cập hiện tại",
"securityWarning": "Cảnh báo an ninh", "securityWarning": "Cảnh báo an ninh",
"securityWarningMessage": "Chia sẻ thông tin đăng nhập cho phép người dùng có toàn quyền thực hiện mọi thao tác trên máy chủ, bao gồm thay đổi mật khẩu và xóa tập tin. Chỉ chia sẻ với những người dùng đáng tin cậy.", "securityWarningMessage": "Chia sẻ thông tin đăng nhập cho phép người dùng có toàn quyền thực hiện mọi thao tác trên máy chủ, bao gồm thay đổi mật khẩu và xóa tập tin. Chỉ chia sẻ với những người dùng đáng tin cậy.",
"tempUserRecommended": "Chúng tôi khuyến nghị bạn nên bật tùy chọn \"Tạo người dùng tạm thời\" để tăng cường bảo mật.", "tempUserRecommended": "Chúng tôi khuyên bạn nên bật tùy chọn 'Tạo người dùng tạm thời' để tăng cường bảo mật.",
"roleManagement": "Quản lý vai trò", "roleManagement": "Quản lý vai trò",
"manageRoles": "Quản lý vai trò", "manageRoles": "Quản lý vai trò",
"manageRolesFor": "Quản lý vai trò cho {{days}}", "manageRolesFor": "Quản lý vai trò cho {{username}}",
"assignRole": "Phân công vai trò", "assignRole": "Phân công vai trò",
"removeRole": "Xóa vai trò", "removeRole": "Xóa vai trò",
"userRoles": "Vai trò người dùng", "userRoles": "Vai trò người dùng",
"permissions": "Quyền hạn", "permissions": "Quyền hạn",
"systemRole": "Vai trò hệ thống", "systemRole": "Vai trò hệ thống",
"customRole": "Vai trò tùy chỉnh", "customRole": "Vai trò tùy chỉnh",
"roleAssignedSuccessfully": "Vai trò được giao cho {{hours}} thành công", "roleAssignedSuccessfully": "Vai trò được giao cho {{username}} thành công",
"failedToAssignRole": "Không thể gán vai trò", "failedToAssignRole": "Không thể gán vai trò",
"roleRemovedSuccessfully": "Vai trò đã được xóa khỏi {{username}} thành công", "roleRemovedSuccessfully": "Vai trò đã được xóa khỏi {{username}} thành công",
"failedToRemoveRole": "Không thể xóa vai trò", "failedToRemoveRole": "Không thể xóa vai trò",
@@ -2214,7 +2214,7 @@
"terminateSession": "Kết thúc phiên", "terminateSession": "Kết thúc phiên",
"sessionTerminated": "Phiên làm việc bị chấm dứt bởi chủ sở hữu máy chủ.", "sessionTerminated": "Phiên làm việc bị chấm dứt bởi chủ sở hữu máy chủ.",
"sharedAccessExpired": "Quyền truy cập dùng chung của bạn vào máy chủ này đã hết hạn.", "sharedAccessExpired": "Quyền truy cập dùng chung của bạn vào máy chủ này đã hết hạn.",
"sharedAccessExpiresIn": "Quyền truy cập dùng chung sẽ hết hạn sau {{username}} giờ", "sharedAccessExpiresIn": "Quyền truy cập dùng chung sẽ hết hạn sau {{hours}} giờ",
"roles": { "roles": {
"label": "Vai trò", "label": "Vai trò",
"admin": "Quản trị viên", "admin": "Quản trị viên",
@@ -2249,7 +2249,7 @@
"displayNamePlaceholder": "Nhà phát triển", "displayNamePlaceholder": "Nhà phát triển",
"descriptionPlaceholder": "Các nhà phát triển và kỹ sư phần mềm", "descriptionPlaceholder": "Các nhà phát triển và kỹ sư phần mềm",
"confirmDeleteRole": "Xóa vai trò", "confirmDeleteRole": "Xóa vai trò",
"confirmDeleteRoleDescription": "Bạn có chắc chắn muốn xóa vai trò '{{username}}' không? Hành động này không thể hoàn tác.", "confirmDeleteRoleDescription": "Bạn có chắc chắn muốn xóa vai trò '{{name}}' không? Hành động này không thể hoàn tác.",
"confirmRemoveRole": "Xóa vai trò", "confirmRemoveRole": "Xóa vai trò",
"confirmRemoveRoleDescription": "Bạn có chắc chắn muốn xóa vai trò này khỏi người dùng không?", "confirmRemoveRoleDescription": "Bạn có chắc chắn muốn xóa vai trò này khỏi người dùng không?",
"editRoleDescription": "Cập nhật thông tin vai trò", "editRoleDescription": "Cập nhật thông tin vai trò",
@@ -2289,7 +2289,7 @@
"updateLog": "Nhật ký cập nhật", "updateLog": "Nhật ký cập nhật",
"hosts": "Người dẫn chương trình", "hosts": "Người dẫn chương trình",
"openServerDetails": "Chi tiết máy chủ mở", "openServerDetails": "Chi tiết máy chủ mở",
"openFileManager": "Mở Trình quản lý tệp", "openFileManager": "Mở trình quản lý tệp",
"edit": "Biên tập", "edit": "Biên tập",
"links": "Liên kết", "links": "Liên kết",
"github": "GitHub", "github": "GitHub",
@@ -2307,16 +2307,16 @@
"validating": "Đang xác thực Docker...", "validating": "Đang xác thực Docker...",
"connectingToHost": "Đang kết nối với máy chủ...", "connectingToHost": "Đang kết nối với máy chủ...",
"error": "Lỗi", "error": "Lỗi",
"errorCode": "Mã lỗi: {{hours}}", "errorCode": "Mã lỗi: {{code}}",
"version": "Docker {{name}}", "version": "Docker {{version}}",
"containerStarted": "Container {{code}} đã khởi động", "containerStarted": "Container {{name}} đã khởi động",
"failedToStartContainer": "Không thể khởi động container {{version}}", "failedToStartContainer": "Không thể khởi động container {{name}}",
"containerStopped": "Container {{name}} đã dừng", "containerStopped": "Container {{name}} đã dừng",
"failedToStopContainer": "Không thể dừng container {{name}}", "failedToStopContainer": "Không thể dừng container {{name}}",
"containerRestarted": "Container {{name}} đã khởi động lại", "containerRestarted": "Container {{name}} đã khởi động lại",
"failedToRestartContainer": "Không thể khởi động lại container {{name}}", "failedToRestartContainer": "Không thể khởi động lại container {{name}}",
"containerPaused": "Container {{name}} tạm dừng", "containerPaused": "Container {{name}} tạm dừng",
"containerUnpaused": "Container {{name}} chưa tạm dừng", "containerUnpaused": "Container {{name}} unpaused",
"failedToTogglePauseContainer": "Không thể chuyển đổi trạng thái tạm dừng cho vùng chứa {{name}}", "failedToTogglePauseContainer": "Không thể chuyển đổi trạng thái tạm dừng cho vùng chứa {{name}}",
"containerRemoved": "Container {{name}} đã bị xóa", "containerRemoved": "Container {{name}} đã bị xóa",
"failedToRemoveContainer": "Không thể xóa container {{name}}", "failedToRemoveContainer": "Không thể xóa container {{name}}",
@@ -2340,8 +2340,8 @@
"noContainersFoundHint": "Hiện không có container Docker nào khả dụng trên máy chủ này.", "noContainersFoundHint": "Hiện không có container Docker nào khả dụng trên máy chủ này.",
"searchPlaceholder": "Tìm kiếm container...", "searchPlaceholder": "Tìm kiếm container...",
"filterByStatusPlaceholder": "Lọc theo trạng thái", "filterByStatusPlaceholder": "Lọc theo trạng thái",
"allContainersCount": "Tất cả ({{name}})", "allContainersCount": "Tất cả ({{count}})",
"statusCount": "{{name}} ({{count}})", "statusCount": "{{status}} ({{count}})",
"noContainersMatchFilters": "Không có hộp đựng nào phù hợp với bộ lọc của bạn.", "noContainersMatchFilters": "Không có hộp đựng nào phù hợp với bộ lọc của bạn.",
"noContainersMatchFiltersHint": "Hãy thử điều chỉnh tiêu chí tìm kiếm hoặc lọc của bạn.", "noContainersMatchFiltersHint": "Hãy thử điều chỉnh tiêu chí tìm kiếm hoặc lọc của bạn.",
"containerMustBeRunningToViewStats": "Container phải đang chạy để xem số liệu thống kê.", "containerMustBeRunningToViewStats": "Container phải đang chạy để xem số liệu thống kê.",
@@ -2372,10 +2372,10 @@
"authenticationRequired": "Cần xác thực", "authenticationRequired": "Cần xác thực",
"verificationCodePrompt": "Nhập mã xác minh", "verificationCodePrompt": "Nhập mã xác minh",
"totpVerificationFailed": "Xác thực TOTP không thành công. Vui lòng thử lại.", "totpVerificationFailed": "Xác thực TOTP không thành công. Vui lòng thử lại.",
"connectedTo": "Đã kết nối với {{status}}", "connectedTo": "Đã kết nối với {{containerName}}",
"disconnected": "Đã ngắt kết nối", "disconnected": "Đã ngắt kết nối",
"consoleError": "Lỗi bảng điều khiển", "consoleError": "Lỗi bảng điều khiển",
"errorMessage": "Lỗi: {{count}}", "errorMessage": "Lỗi: {{message}}",
"failedToConnect": "Không thể kết nối với container", "failedToConnect": "Không thể kết nối với container",
"console": "Bảng điều khiển", "console": "Bảng điều khiển",
"selectShell": "Chọn vỏ", "selectShell": "Chọn vỏ",
@@ -2399,4 +2399,4 @@
"switchToLight": "Chuyển sang chế độ sáng", "switchToLight": "Chuyển sang chế độ sáng",
"switchToDark": "Chuyển sang chế độ Tối" "switchToDark": "Chuyển sang chế độ Tối"
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,23 @@ import { ThemeProvider } from "@/components/theme-provider";
import { ElectronVersionCheck } from "@/ui/desktop/user/ElectronVersionCheck.tsx"; import { ElectronVersionCheck } from "@/ui/desktop/user/ElectronVersionCheck.tsx";
import "./i18n/i18n"; import "./i18n/i18n";
import { isElectron } from "./ui/main-axios.ts"; import { isElectron } from "./ui/main-axios.ts";
import HostManagerApp from "./ui/desktop/apps/HostManagerApp.tsx";
import NetworkGraphApp from "./ui/desktop/apps/NetworkGraphApp.tsx";
const FullscreenApp: React.FC = () => {
const searchParams = new URLSearchParams(window.location.search);
const view = searchParams.get('view');
switch (view) {
case 'host-manager':
return <HostManagerApp />;
case 'network-graph':
return <NetworkGraphApp />;
default:
return <DesktopApp />;
}
};
import { useServiceWorker } from "@/hooks/use-service-worker";
function useWindowWidth() { function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth); const [width, setWidth] = useState(window.innerWidth);
@@ -58,11 +75,21 @@ function RootApp() {
const isMobile = width < 768; const isMobile = width < 768;
const [showVersionCheck, setShowVersionCheck] = useState(true); const [showVersionCheck, setShowVersionCheck] = useState(true);
// PWA Service Worker registration (production web only)
useServiceWorker();
const userAgent = const userAgent =
navigator.userAgent || navigator.vendor || (window as any).opera || ""; navigator.userAgent || navigator.vendor || (window as any).opera || "";
const isTermixMobile = /Termix-Mobile/.test(userAgent); const isTermixMobile = /Termix-Mobile/.test(userAgent);
const searchParams = new URLSearchParams(window.location.search);
const isFullscreen = searchParams.has('view');
const renderApp = () => { const renderApp = () => {
if (isFullscreen) {
return <FullscreenApp />;
}
if (isElectron()) { if (isElectron()) {
return <DesktopApp />; return <DesktopApp />;
} }
@@ -94,7 +121,7 @@ function RootApp() {
}} }}
/> />
<div className="relative min-h-screen" style={{ zIndex: 1 }}> <div className="relative min-h-screen" style={{ zIndex: 1 }}>
{isElectron() && showVersionCheck ? ( {isElectron() && showVersionCheck && !isFullscreen ? (
<ElectronVersionCheck <ElectronVersionCheck
onContinue={() => setShowVersionCheck(false)} onContinue={() => setShowVersionCheck(false)}
isAuthenticated={false} isAuthenticated={false}
@@ -114,3 +141,4 @@ createRoot(document.getElementById("root")!).render(
</ThemeProvider> </ThemeProvider>
</StrictMode>, </StrictMode>,
); );

View File

@@ -42,6 +42,11 @@ export interface SSHHost {
enableTunnel: boolean; enableTunnel: boolean;
enableFileManager: boolean; enableFileManager: boolean;
enableDocker: boolean; enableDocker: boolean;
showTerminalInSidebar: boolean;
showFileManagerInSidebar: boolean;
showTunnelInSidebar: boolean;
showDockerInSidebar: boolean;
showServerStatsInSidebar: boolean;
defaultPath: string; defaultPath: string;
tunnelConnections: TunnelConnection[]; tunnelConnections: TunnelConnection[];
jumpHosts?: JumpHost[]; jumpHosts?: JumpHost[];
@@ -102,6 +107,11 @@ export interface SSHHostData {
enableTunnel?: boolean; enableTunnel?: boolean;
enableFileManager?: boolean; enableFileManager?: boolean;
enableDocker?: boolean; enableDocker?: boolean;
showTerminalInSidebar?: boolean;
showFileManagerInSidebar?: boolean;
showTunnelInSidebar?: boolean;
showDockerInSidebar?: boolean;
showServerStatsInSidebar?: boolean;
defaultPath?: string; defaultPath?: string;
forceKeyboardInteractive?: boolean; forceKeyboardInteractive?: boolean;
tunnelConnections?: TunnelConnection[]; tunnelConnections?: TunnelConnection[];
@@ -193,6 +203,7 @@ export interface CredentialData {
// ============================================================================ // ============================================================================
export interface TunnelConnection { export interface TunnelConnection {
tunnelType?: "local" | "remote";
sourcePort: number; sourcePort: number;
endpointPort: number; endpointPort: number;
endpointHost: string; endpointHost: string;
@@ -210,6 +221,7 @@ export interface TunnelConnection {
export interface TunnelConfig { export interface TunnelConfig {
name: string; name: string;
tunnelType?: "local" | "remote";
sourceHostId: number; sourceHostId: number;
tunnelIndex: number; tunnelIndex: number;

View File

@@ -6,7 +6,48 @@ export type WidgetType =
| "uptime" | "uptime"
| "processes" | "processes"
| "system" | "system"
| "login_stats"; | "login_stats"
| "ports"
| "firewall";
export interface ListeningPort {
protocol: "tcp" | "udp";
localAddress: string;
localPort: number;
state?: string;
pid?: number;
process?: string;
}
export interface PortsMetrics {
source: "ss" | "netstat" | "none";
ports: ListeningPort[];
}
export interface FirewallRule {
chain: string;
target: string;
protocol: string;
source: string;
destination: string;
dport?: string;
sport?: string;
state?: string;
interface?: string;
extra?: string;
}
export interface FirewallChain {
name: string;
policy: string;
rules: FirewallRule[];
}
export interface FirewallMetrics {
type: "iptables" | "nftables" | "none";
status: "active" | "inactive" | "unknown";
chains: FirewallChain[];
}
export interface StatsConfig { export interface StatsConfig {
enabledWidgets: WidgetType[]; enabledWidgets: WidgetType[];

View File

@@ -11,12 +11,17 @@ import { TopNavbar } from "@/ui/desktop/navigation/TopNavbar.tsx";
import { CommandHistoryProvider } from "@/ui/desktop/apps/features/terminal/command-history/CommandHistoryContext.tsx"; import { CommandHistoryProvider } from "@/ui/desktop/apps/features/terminal/command-history/CommandHistoryContext.tsx";
import { AdminSettings } from "@/ui/desktop/apps/admin/AdminSettings.tsx"; import { AdminSettings } from "@/ui/desktop/apps/admin/AdminSettings.tsx";
import { UserProfile } from "@/ui/desktop/user/UserProfile.tsx"; import { UserProfile } from "@/ui/desktop/user/UserProfile.tsx";
import { NetworkGraphCard } from "@/ui/desktop/apps/dashboard/cards/NetworkGraphCard";
import { Toaster } from "@/components/ui/sonner.tsx"; import { Toaster } from "@/components/ui/sonner.tsx";
import { toast } from "sonner";
import { CommandPalette } from "@/ui/desktop/apps/command-palette/CommandPalette.tsx"; import { CommandPalette } from "@/ui/desktop/apps/command-palette/CommandPalette.tsx";
import { getUserInfo } from "@/ui/main-axios.ts"; import { getUserInfo, logoutUser, isElectron } from "@/ui/main-axios.ts";
import { useTheme } from "@/components/theme-provider"; import { useTheme } from "@/components/theme-provider";
import { dbHealthMonitor } from "@/lib/db-health-monitor.ts";
import { useTranslation } from "react-i18next";
function AppContent() { function AppContent() {
const { t } = useTranslation();
const [isAuthenticated, setIsAuthenticated] = useState(false); const [isAuthenticated, setIsAuthenticated] = useState(false);
const [username, setUsername] = useState<string | null>(null); const [username, setUsername] = useState<string | null>(null);
const [isAdmin, setIsAdmin] = useState(false); const [isAdmin, setIsAdmin] = useState(false);
@@ -29,11 +34,12 @@ function AppContent() {
const [transitionPhase, setTransitionPhase] = useState< const [transitionPhase, setTransitionPhase] = useState<
"idle" | "fadeOut" | "fadeIn" "idle" | "fadeOut" | "fadeIn"
>("idle"); >("idle");
const { currentTab, tabs, updateTab } = useTabs(); const { currentTab, tabs, updateTab, addTab } = useTabs();
const [isCommandPaletteOpen, setIsCommandPaletteOpen] = useState(false); const [isCommandPaletteOpen, setIsCommandPaletteOpen] = useState(false);
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
const [rightSidebarOpen, setRightSidebarOpen] = useState(false); const [rightSidebarOpen, setRightSidebarOpen] = useState(false);
const [rightSidebarWidth, setRightSidebarWidth] = useState(400); const [rightSidebarWidth, setRightSidebarWidth] = useState(400);
const [dbConnectionFailed, setDbConnectionFailed] = useState(false);
const isDarkMode = const isDarkMode =
theme === "dark" || theme === "dark" ||
@@ -45,12 +51,49 @@ function AppContent() {
const lastAltPressTime = useRef(0); const lastAltPressTime = useRef(0);
useEffect(() => {
const handleDatabaseConnectionLost = () => {
setDbConnectionFailed(true);
setIsAuthenticated(false);
};
const handleDatabaseConnectionRestored = () => {
setDbConnectionFailed(false);
window.location.reload();
};
dbHealthMonitor.on(
"database-connection-lost",
handleDatabaseConnectionLost,
);
dbHealthMonitor.on(
"database-connection-restored",
handleDatabaseConnectionRestored,
);
return () => {
dbHealthMonitor.off(
"database-connection-lost",
handleDatabaseConnectionLost,
);
dbHealthMonitor.off(
"database-connection-restored",
handleDatabaseConnectionRestored,
);
};
}, []);
useEffect(() => { useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if (event.code === "ShiftLeft") { if (event.code === "ShiftLeft") {
if (event.repeat) { if (event.repeat) {
return; return;
} }
const shortcutEnabled =
localStorage.getItem("commandPaletteShortcutEnabled") !== "false";
if (!shortcutEnabled) {
return;
}
const now = Date.now(); const now = Date.now();
if (now - lastShiftPressTime.current < 300) { if (now - lastShiftPressTime.current < 300) {
setIsCommandPaletteOpen((isOpen) => !isOpen); setIsCommandPaletteOpen((isOpen) => !isOpen);
@@ -86,6 +129,52 @@ function AppContent() {
}; };
}, [theme, setTheme]); }, [theme, setTheme]);
useEffect(() => {
const path = window.location.pathname;
// New format: /terminal/{hostNameOrId}
const terminalMatch = path.match(/^\/terminal\/([a-zA-Z0-9_-]+)$/);
// Legacy format: /hosts/{id}/terminal (backward compatible)
const legacyMatch = path.match(/^\/hosts\/([a-zA-Z0-9_-]+)\/terminal$/);
const hostIdentifier = terminalMatch?.[1] || legacyMatch?.[1];
if (hostIdentifier) {
const openTerminal = async () => {
try {
const { getSSHHostById, getSSHHosts } =
await import("@/ui/main-axios.ts");
let host = null;
// Pure numeric → lookup by ID
if (/^\d+$/.test(hostIdentifier)) {
host = await getSSHHostById(parseInt(hostIdentifier, 10));
} else {
// Non-numeric → lookup by name (first match)
const hosts = await getSSHHosts();
host =
hosts.find((h: { name?: string }) => h.name === hostIdentifier) ||
null;
}
if (host) {
addTab({
type: "terminal",
title: host.name || host.ip,
data: { host, initialCommand: "" },
});
// Clean URL to prevent re-opening on refresh
window.history.replaceState({}, "", "/");
} else {
toast.error(`Host "${hostIdentifier}" not found`);
}
} catch (error) {
console.error("Failed to open terminal:", error);
toast.error("Failed to open terminal for host");
}
};
openTerminal();
}
}, [addTab]);
useEffect(() => { useEffect(() => {
const checkAuth = () => { const checkAuth = () => {
setAuthLoading(true); setAuthLoading(true);
@@ -131,8 +220,6 @@ function AppContent() {
localStorage.setItem("topNavbarOpen", JSON.stringify(isTopbarOpen)); localStorage.setItem("topNavbarOpen", JSON.stringify(isTopbarOpen));
}, [isTopbarOpen]); }, [isTopbarOpen]);
const handleSelectView = () => {};
const handleAuthSuccess = useCallback( const handleAuthSuccess = useCallback(
(authData: { (authData: {
isAdmin: boolean; isAdmin: boolean;
@@ -163,7 +250,6 @@ function AppContent() {
setTimeout(async () => { setTimeout(async () => {
try { try {
const { logoutUser, isElectron } = await import("@/ui/main-axios.ts");
await logoutUser(); await logoutUser();
if (isElectron()) { if (isElectron()) {
@@ -188,11 +274,12 @@ function AppContent() {
const showSshManager = currentTabData?.type === "ssh_manager"; const showSshManager = currentTabData?.type === "ssh_manager";
const showAdmin = currentTabData?.type === "admin"; const showAdmin = currentTabData?.type === "admin";
const showProfile = currentTabData?.type === "user_profile"; const showProfile = currentTabData?.type === "user_profile";
const showNetworkGraph = currentTabData?.type === "network_graph";
if (authLoading) { if (authLoading && !dbConnectionFailed) {
return ( return (
<div <div
className="h-screen w-screen flex items-center justify-center" className="fixed inset-0 flex items-center justify-center"
style={{ style={{
background: "var(--bg-elevated)", background: "var(--bg-elevated)",
backgroundImage: `repeating-linear-gradient( backgroundImage: `repeating-linear-gradient(
@@ -204,13 +291,44 @@ function AppContent() {
)`, )`,
}} }}
> >
<div className="text-center"> <div className="w-[420px] max-w-full p-8 flex flex-col backdrop-blur-sm bg-card/50 rounded-2xl shadow-xl border-2 border-edge overflow-y-auto thin-scrollbar my-2 animate-in fade-in zoom-in-95 duration-300">
<div className="w-16 h-16 border-4 border-primary/30 border-t-primary rounded-full animate-spin mx-auto" /> <div className="flex items-center justify-center h-32">
<div className="text-center">
<div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin mx-auto mb-4" />
<p className="text-muted-foreground">
{t("common.checkingAuthentication")}
</p>
</div>
</div>
</div> </div>
</div> </div>
); );
} }
if (dbConnectionFailed) {
return (
<div className="h-screen w-screen overflow-hidden bg-background">
<div className="fixed inset-0 flex items-center justify-center z-[10000] bg-background">
<Dashboard
isAuthenticated={false}
authLoading={false}
onAuthSuccess={handleAuthSuccess}
isTopbarOpen={isTopbarOpen}
onSelectView={() => {}}
initialDbError="Database connection failed"
/>
</div>
<Toaster
position="bottom-right"
richColors={false}
closeButton
duration={5000}
offset={20}
/>
</div>
);
}
return ( return (
<div className="h-screen w-screen overflow-hidden bg-background"> <div className="h-screen w-screen overflow-hidden bg-background">
<CommandPalette <CommandPalette
@@ -220,7 +338,6 @@ function AppContent() {
{!isAuthenticated && ( {!isAuthenticated && (
<div className="fixed inset-0 flex items-center justify-center z-[10000] bg-background"> <div className="fixed inset-0 flex items-center justify-center z-[10000] bg-background">
<Dashboard <Dashboard
onSelectView={handleSelectView}
isAuthenticated={isAuthenticated} isAuthenticated={isAuthenticated}
authLoading={authLoading} authLoading={authLoading}
onAuthSuccess={handleAuthSuccess} onAuthSuccess={handleAuthSuccess}
@@ -231,7 +348,6 @@ function AppContent() {
{isAuthenticated && ( {isAuthenticated && (
<LeftSidebar <LeftSidebar
onSelectView={handleSelectView}
disabled={!isAuthenticated || authLoading} disabled={!isAuthenticated || authLoading}
isAdmin={isAdmin} isAdmin={isAdmin}
username={username} username={username}
@@ -251,7 +367,6 @@ function AppContent() {
{showHome && ( {showHome && (
<div className="h-screen w-full visible pointer-events-auto static overflow-hidden"> <div className="h-screen w-full visible pointer-events-auto static overflow-hidden">
<Dashboard <Dashboard
onSelectView={handleSelectView}
isAuthenticated={isAuthenticated} isAuthenticated={isAuthenticated}
authLoading={authLoading} authLoading={authLoading}
onAuthSuccess={handleAuthSuccess} onAuthSuccess={handleAuthSuccess}
@@ -265,7 +380,6 @@ function AppContent() {
{showSshManager && ( {showSshManager && (
<div className="h-screen w-full visible pointer-events-auto static overflow-hidden"> <div className="h-screen w-full visible pointer-events-auto static overflow-hidden">
<HostManager <HostManager
onSelectView={handleSelectView}
isTopbarOpen={isTopbarOpen} isTopbarOpen={isTopbarOpen}
initialTab={currentTabData?.initialTab} initialTab={currentTabData?.initialTab}
hostConfig={currentTabData?.hostConfig} hostConfig={currentTabData?.hostConfig}
@@ -298,6 +412,16 @@ function AppContent() {
</div> </div>
)} )}
{showNetworkGraph && (
<div className="h-screen w-full visible pointer-events-auto static overflow-hidden">
<NetworkGraphCard
isTopbarOpen={isTopbarOpen}
rightSidebarOpen={rightSidebarOpen}
rightSidebarWidth={rightSidebarWidth}
/>
</div>
)}
<TopNavbar <TopNavbar
isTopbarOpen={isTopbarOpen} isTopbarOpen={isTopbarOpen}
setIsTopbarOpen={setIsTopbarOpen} setIsTopbarOpen={setIsTopbarOpen}

View File

@@ -0,0 +1,12 @@
import { HostManager } from "@/ui/desktop/apps/host-manager/hosts/HostManager";
import React from "react";
const HostManagerApp: React.FC = () => {
return (
<div className="w-full h-screen">
<HostManager isTopbarOpen={false} onSelectView={() => {}} />
</div>
);
};
export default HostManagerApp;

Some files were not shown because too many files have changed in this diff Show More