3x-ui/web/translation/uk-UA.json
Sanaei edf0f36940
Frontend rewrite: React + TypeScript with AntD v6 (#4498)
* chore(frontend): add react+typescript toolchain alongside vue

Step 0 of the planned vue->react migration. React 19, antd 5, i18next
+ react-i18next, typescript 5, and @vitejs/plugin-react 6 are added as
dev/runtime deps alongside the existing vue stack. Both frameworks
coexist in the build until the last entry flips.

* vite.config.js: react() plugin runs next to vue(); new manualChunks
  for vendor-react / vendor-antd-react / vendor-icons-react /
  vendor-i18next. Existing vue chunks unchanged.
* eslint.config.js: typescript-eslint + eslint-plugin-react-hooks
  rules scoped to *.{ts,tsx}; vue config untouched for *.{js,vue}.
* tsconfig.json: strict, jsx: react-jsx, moduleResolution: bundler,
  allowJs: true (lets .tsx files import the remaining .js modules
  during incremental migration), @/* path alias.
* env.d.ts: Vite client types + window.X_UI_BASE_PATH typing +
  SubPageData shape consumed by the subscription page.

Vite stays pinned at 8.0.13 per the existing project policy. No
existing .vue/.js source files touched in this step.

eslint-plugin-react (not -hooks) is not included because its latest
release does not yet support ESLint 10. react-hooks/purity covers
the safety-critical case; revisit when the plugin updates.

* refactor(frontend): port subpage to react+ts

Step 1 of the planned vue->react migration. The standalone
subscription page (sub/sub.go renders the HTML host; React mounts
into #app) is the first entry off vue.

Introduces two shared pieces both entries (and future ones) will
use:

* src/hooks/useTheme.tsx — React Context + useTheme hook + the
  same buildAntdThemeConfig (dark/ultra-dark token overrides) and
  pauseAnimationsUntilLeave helper the vue version exposes. Same
  localStorage keys (dark-mode, isUltraDarkThemeEnabled) and DOM
  side effects (body.className, html[data-theme]) so the two stay
  in sync across the coexistence period.
* src/i18n/react.ts — i18next + react-i18next loader that reads
  the same web/translation/*.json files via import.meta.glob. The
  vue-i18n setup in src/i18n/index.js is untouched and still serves
  the remaining vue entries.

SubPage.tsx mirrors the vue version's behavior: reads
window.__SUB_PAGE_DATA__ injected by the Go sub server, renders QR
codes / descriptions / Android+iOS deep-link dropdowns, supports
theme cycle and language switch. Uses AntD v5 idioms: Descriptions
items prop, Dropdown menu prop, Layout.Content.

* refactor(frontend): port login to react+ts

Step 2 of the planned vue->react migration. The login entry is the
first to exercise AntD React's Form API (Form + Form.Item with
name/rules + onFinish) and the existing axios/CSRF interceptors
under React.

* LoginPage.tsx: same form fields, conditional 2FA input,
  rotating headline ("Hello" / "Welcome to..."), drifting blob
  background, theme cycle + language popover. Headline transition
  switches from vue's <Transition mode=out-in> to a CSS keyframe
  animation keyed off the visible word.
* entries/login.tsx: setupAxios() + applyDocumentTitle() unchanged
  from the vue entry — both are framework-agnostic in src/utils
  and src/api/axios-init.js.

useTheme hook, ThemeProvider, and i18n/react.ts loader introduced
in step 1 are now shared across two entries; Vite extracts them as
a small chunk in the build output.

* refactor(frontend): port api-docs to react+ts

Step 3 of the planned vue->react migration. The five api-docs files
(ApiDocsPage, CodeBlock, EndpointRow, EndpointSection, plus the
data-only endpoints.js) all move to react+ts.

Also introduces components/AppSidebar.tsx — api-docs is the first
authenticated page to need it. AppSidebar.vue stays in place for the
six remaining vue entries (settings, inbounds, clients, xray, nodes,
index); each gets switched to AppSidebar.tsx as its entry migrates.
After the last entry flips, AppSidebar.vue is deleted.

Notable transformations:

* The scroll observer that highlights the active TOC link is a
  useEffect keyed on sections — re-registers whenever the visible
  set changes (search filter narrows it). Same behaviour as the vue
  watchEffect.
* v-html="safeInlineHtml(...)" becomes
  dangerouslySetInnerHTML={{ __html: safeInlineHtml(...) }}. The
  helper still escapes everything except <code> tags.
* JSON syntax highlighter in CodeBlock is unchanged — pure regex on
  the escaped string, then rendered via dangerouslySetInnerHTML.
* endpoints.js stays as JS (allowJs in tsconfig); only the consumer
  signatures (Endpoint, Section) are typed at the React boundary.
* AppSidebar reuses pauseAnimationsUntilLeave + useTheme from
  step 1. Drawer + Sider keyed off the same localStorage flag
  (isSidebarCollapsed) and DOM theme attributes the vue version
  uses, so the two stay in sync during coexistence.

* refactor(frontend): port nodes to react+ts

Step 4 of the planned vue->react migration. The nodes entry brings in
the largest shared-infrastructure batch so far — every authenticated
react page from here on can lean on these.

New shared pieces (live alongside their .vue counterparts during
coexistence):

* hooks/useMediaQuery.ts — useState + resize listener
* hooks/useWebSocket.ts — wraps WebSocketClient, subscribes on mount
  and unsubscribes on unmount. The underlying client is a single
  module-level instance so multiple components on the same page
  share one socket.
* hooks/useNodes.ts — node list state + CRUD + probe/test, including
  the totals memo (online/offline/avgLatency) used by the summary card.
  applyNodesEvent is the entry point for the heartbeat-pushed list.
* components/CustomStatistic.tsx — thin Statistic wrapper, prefix +
  suffix slots become props.
* components/Sparkline.tsx — the SVG line chart with measured-width
  axis scaling, gradient fill, tooltip overlay, and per-instance
  gradient id from React.useId. ResizeObserver lifecycle is in
  useEffect; the math is unchanged.

Pages:

* NodesPage — wires hooks + WebSocket together, renders summary card
  + NodeList, hosts the form modal. Uses Modal.useModal() for the
  delete confirm so the dialog inherits ConfigProvider theming.
* NodeList — desktop renders a Table with expandable history rows;
  mobile flips to a vertical card list whose actions live in a
  bottom-right Dropdown. The IP-blur eye toggle persists across both.
* NodeFormModal — controlled form (useState object, single setForm
  per change). The reset-on-open effect computes the next state
  once and applies it with eslint-disable to satisfy the new
  react-hooks/set-state-in-effect rule on a legitimate pattern.
* NodeHistoryPanel — polls /panel/api/nodes/history/{id}/{metric}/
  {bucket} every 15s, renders cpu+mem sparklines side-by-side.

* refactor(frontend): port settings to react+ts

Step 5 of the planned vue->react migration. Settings is the first
entry whose state model didn't translate to the Vue-style "parent
passes a reactive object, children mutate it in place" pattern, so
the React port flips it to lifted state + a typed updateSetting
patch function.

* models/setting.ts — typed AllSetting class with the same field
  defaults and equals() behavior the vue version had. The .js
  twin is deleted; nothing else imported it.
* hooks/useAllSetting.ts — owns allSetting + oldAllSetting state,
  exposes updateSetting(patch), saveDisabled is derived via useMemo
  off equals() (no more 1Hz dirty-check timer).
* components/SettingListItem.tsx — children-based wrapper instead
  of named slots. The vue twin stays alive because xray (BasicsTab,
  DnsTab) still imports it; deleted when xray migrates.

The five tab components and the TwoFactorModal each accept
{ allSetting, updateSetting } and render with AntD v5's Collapse
items[] API. Every v-model:value="x" became
value={...} onChange={(e) => updateSetting({ key: e.target.value })}
or onChange={(v) => updateSetting({ key: v })} for non-input
controls.

SubscriptionFormatsTab is the trickiest — fragment / noises[] /
mux / direct routing rules are stored as JSON-encoded strings on
the wire. Parsing them once via useMemo per field, mutating the
parsed object on edit, and stringifying back into the patch keeps
the round-trip identical to the vue version.

SettingsPage hosts the tab navigation (with hash sync), the
save / restart action bar, the security-warnings alert banner,
and the restart flow that rebuilds the panel URL after the new
host/port/cert settings take effect.

* refactor(frontend): port clients to react+ts

Step 6 of the planned vue->react migration. Clients is the biggest
data-CRUD page in the panel (1.1k-line ClientsPage, 4 modals, full
table + mobile card list, WebSocket-driven realtime traffic + online
updates).

New shared infra (lives alongside vue twins until inbounds migrates):

* hooks/useClients.ts — clients + inbounds list, CRUD + bulk delete +
  attach/detach + traffic reset, with WebSocket event handlers
  (traffic, client_stats, invalidate) and a small debounced refresh
  on the invalidate event. State managed via setState; the live
  client_stats event merges traffic snapshots row-by-row through a
  ref to avoid stale closure issues.
* hooks/useDatepicker.ts — singleton "gregorian"/"jalalian" cache
  with subscribe/notify so multiple components can read the panel's
  Calendar Type without re-fetching. Mirrors useDatepicker.js.
* components/DateTimePicker.tsx — AntD DatePicker wrapper.
  vue3-persian-datetime-picker has no React port; the Jalali UI
  calendar is deferred (read-only Jalali display via IntlUtil
  formatDate still works). The vue twin stays for inbounds.
* pages/inbounds/QrPanel.tsx — copy/download/copy-as-png QR helper
  shared between clients (qr modal) and inbounds (still on vue).
  Vue twin stays alive at QrPanel.vue.
* models/inbound.ts — slim port: only the TLS_FLOW_CONTROL constant
  the clients form needs. The full inbound model stays as
  inbound.js for now; inbounds will pull it in as inbound.ts.

The clients page itself uses Modal.useModal() for all confirm
dialogs (delete, bulk-delete, reset-traffic, delDepleted, reset-all)
so the dialogs render themed. Filter state persists to
localStorage under clientsFilterState. Sort + pagination state is
local; pageSize seeds from /panel/setting/defaultSettings.

The four modals share a controlled "open/onOpenChange" pattern
that replaces vue's v-model:open. ClientFormModal computes
attach/detach diffs from the inbound multi-select on submit; the
parent's onSave callback routes them through useClients's attach()/
detach() after the main update succeeds.

ESLint config: turned off four react-hooks v7 rules
(react-compiler, preserve-manual-memoization, set-state-in-effect,
purity). They're all React-Compiler-driven informational rules; we
don't run the compiler and the patterns they flag (initial-fetch
useEffect, derived computations using Date.now, inline arrow event
handlers) are all idiomatic React. Disabling globally instead of
per-line keeps the diff readable.

* refactor(frontend): port index dashboard to react+ts

Step 7 of the Vue→React migration. Ports the overview/index entry: dashboard
page, status + xray cards, panel-update / log / backup / system-history /
xray-metrics / xray-log / version modals, and the custom-geo subsection. Adds
the shared JsonEditor (CodeMirror 6) and useStatus hook used by the config
modal. Removes the unused react-hooks/set-state-in-effect disables now that
the rule is off globally.

* refactor(frontend): port xray to react+ts

Step 8 of the Vue→React migration. Ports the xray config entry: page shell,
basics/routing/outbounds/balancers/dns tabs, the rule + balancer + dns server
+ dns presets + warp + nord modals, the protocol-aware outbound form, and the
shared FinalMaskForm (TCP/UDP masks + QUIC params). Adds useXraySetting that
mirrors the legacy two-way sync between the JSON template string and the
parsed templateSettings tree. The outbound model itself stays in JS so the
class-driven form keeps its existing mutation API; instance access is typed
loosely inside the form to match.

The shared FinalMaskForm.vue and JsonEditor.vue stay alongside the new .tsx
versions until step 9 — InboundFormModal.vue still imports them.

Adds react-hooks/immutability and react-hooks/refs to the already-disabled
react-compiler rule set; both flag the outbound form's instance-mutation
pattern that doesn't run through useState.

* Upgrade frontend deps (antd v6, i18n, TS)

Bump frontend dependencies in package.json and regenerate package-lock.json. Notable updates: upgrade antd to v6, update i18next/react-i18next, axios, qs, vue-i18n, TypeScript and ESLint, plus related @rc-component packages and replacements (e.g. classnames/rc-util -> clsx/@rc-component/util). Lockfile changes reflect the new dependency tree required for Ant Design v6 and other package upgrades.

* refactor(frontend): port inbounds to react+ts and drop vue toolchain

Step 9 — the last entry. Ports the inbounds entry: page shell, list with
desktop table + mobile cards, info modal, qr-code modal, share-link
helpers, and the protocol-aware form modal (basics / protocol /
stream / security / sniffing / advanced JSON). useInbounds replaces
the Vue composable with WebSocket-driven traffic + client-stats merge.

Inbound and DBInbound models stay in JS so the class-driven form keeps
its mutation API; instance access is typed loosely inside the form to
match. FinalMaskForm/JsonEditor/TextModal/PromptModal/InfinityIcon are
the last shared bits to flip; their .vue counterparts go too.

Toolchain cleanup now that no entry needs Vue: drop plugin-vue from
vite.config, remove the .vue lint block + parser, prune vue / vue-i18n
/ ant-design-vue / @ant-design/icons-vue / vue3-persian-datetime-picker
/ moment-jalaali override from package.json, and switch utils/index.js
to import { message } from 'antd' instead of ant-design-vue.

* chore(frontend): adopt antd v6 api updates

Sweep deprecated props across the React tree:
- Modal: destroyOnClose -> destroyOnHidden, maskClosable -> mask.closable
- Space: direction -> orientation (or removed when redundant)
- Input.Group compact -> Space.Compact block
- Drawer: width -> size
- Spin: tip -> description
- Progress: trailColor -> railColor
- Alert: message -> title
- Popover: overlayClassName -> rootClassName
- BackTop -> FloatButton.BackTop

Also refresh dashboard theming for v6: rename dark/ultra Layout and Menu
tokens (siderBg, darkItemBg, darkSubMenuItemBg, darkPopupBg), tweak gauge
size/stroke, add font-size overrides for Statistic and Progress so the
overview numbers stay legible under v6 defaults.

* chore(frontend): antd v6 polish, theme + modal fixes

- adopt message.useMessage hook + messageBus bridge so HttpUtil messages
  inherit ConfigProvider theme tokens
- replace deprecated antd APIs (List, Input addonBefore/After, Empty
  imageStyle); introduce InputAddon helper + SettingListItem custom rows
- fix dark/ultra selectors in portaled modals (body.dark,
  html[data-theme='ultra-dark']) instead of nonexistent .is-dark/.is-ultra
- add horizontal scroll to clients table; reorder node columns so
  actions+enable sit at the left
- swap raw button for antd Button in NodeFormModal test connection
- fix FinalMaskForm nested-form by hoisting it outside OutboundFormModal's
  parent Form
- fix advanced "all" JSON tab in InboundFormModal — useMemo on a mutated
  ref was stale; compute on every render
- fix chart-on-open for SystemHistory + XrayMetrics modals by adding open
  to effect deps (useRef.current doesn't trigger re-runs)
- switch i18next interpolation to single-brace {var} to match locale files
- drop residual Vue mentions in CI workflows and Go comments

* fix(frontend): qr code collapse — open only first panel, allow toggle

ClientQrModal and QrCodeModal both used activeKey without onChange,
forcing every panel open and blocking user toggle. Switch to controlled
state initialized to the first item's key on open, with onChange so
clicks update state.

Also remove unused AppBridge.tsx (superseded by per-page message.useMessage
hook).

* fix(frontend): hover cards, balancer load, routing dnd, modal a11y, outbound crash

- ClientsPage/SettingsPage/XrayPage: add hoverable to bottom card/tabs so
  hover affordance matches the top card
- BalancerFormModal: lazy-init useState from props + destroyOnHidden so
  the form mounts with saved values instead of relying on a useEffect
  sync that could miss the first open
- RoutingTab: rewrite pointer drag — handlers are now defined inside the
  pointerdown closure so addEventListener/removeEventListener match;
  drag state lives on a ref (from/to/moved) so onUp reads the real
  indices, not stale closure values. Adds setPointerCapture so Windows
  and touch keep delivering events when the cursor leaves the handle.
- OutboundFormModal/InboundFormModal: blur the focused input before
  switching tabs to silence the aria-hidden-on-focused-element warning
- utils.isArrEmpty: return true for undefined/null arrays — the old form
  treated undefined as "not empty" which crashed VLESSSettings.fromJson
  when json.vnext was missing

* fix(frontend): clipboard reliability + restyle login page

- ClipboardManager.copyText: prefer navigator.clipboard on secure
  contexts, fall back to a focused on-screen textarea + execCommand.
  Old path used left:-9999px which failed selection in some browsers
  and swallowed execCommand's return value, so the "copied" toast
  appeared even when nothing made it to the clipboard.
- LoginPage: richer gradient backdrop — five animated colour blobs,
  glassmorphic card (backdrop-filter blur + saturate), gradient brand
  text/accent, masked grid texture for depth, and a thin gradient
  border on the card. Light/dark/ultra each get their own palette.

* Memoize compactAdvancedJson and update deps

Wrap compactAdvancedJson in useCallback (dependent on messageApi) and add it to the dependency array of applyAdvancedJsonToBasic. This ensures a stable function reference for correct dependency tracking and avoids stale closures/unnecessary re-renders in InboundFormModal.tsx.

* style(frontend): prettier charts, drop redundant frame, format net rates

- Sparkline: multi-stop gradient fill, soft drop-shadow under the line,
  dashed grid, glowing pulse on the latest-point marker, pill-shaped
  tooltip with dashed crosshair
- XrayMetricsModal: glow + pulse on the observatory alive dot,
  monospace stamps/listen text
- SystemHistoryModal: keep just the modal's frame around the chart (the
  inner wrapper I'd added stacked a second border on top); strip the
  decimal from Net Up/Down (25.63 KB/s → 25 KB/s) only on this chart's
  formatter

* style(frontend): refined dark/ultra palette + shared pro card frame

- Dark tokens shifted to a cooler, Linear-style palette: page #1a1b1f,
  sidebar/header #15161a (recessed nav, darker than cards), card
  #23252b, elevated #2d2f37
- Ultra dark: page pure #000 for OLED, sidebar #050507 disappears into
  the frame, card #101013 with a clear step, elevated #1a1a1e
- New styles/page-cards.css holds the card border/shadow/hover rules so
  all seven content pages (index, clients, inbounds, xray, settings,
  nodes, api-docs) share one definition instead of duplicating in each
  page CSS
- Dashboard typography: uppercase card titles with letter-spacing,
  larger 17px stat values, subtle gradient divider between stat columns,
  ellipsis on action labels so "Backup & Restore" doesn't break the
  card height at mid widths
- Light --bg-page stays at #e6e8ec for the contrast against white cards

* fix(frontend): wireguard info alignment, blue login dark, embed gitkeep

- align WireGuard info-modal fields with Protocol/Address/Port by wrapping
  values in Tag (matches the rest of the dl.info-list rows)
- swap login dark palette from purple to pure blue blobs/accent/brand
- pin web/dist/.gitkeep through gitignore so //go:embed all:dist never
  fails on a fresh clone with an empty dist directory

* docs: refresh frontend docs for the React + TS + AntD 6 stack

Update CONTRIBUTING.md and frontend/README.md to describe the migrated
frontend accurately:

- replace Vue 3 / Ant Design Vue 4 references with React 19 / AntD 6 / TS
- swap composables -> hooks, vue-i18n -> react-i18next, createApp -> createRoot
- mention the typecheck step (tsc --noEmit) in the PR checklist
- document the Vite 8.0.13 pin and TypeScript strict mode in conventions
- list the nodes and api-docs entries that were missing from the layout

* style(frontend): improve readability and mobile polish

- bump statistic title/value contrast in dark and ultra-dark so totals
  on the inbounds summary card stay legible
- give index card actions explicit colors per theme so links like Stop,
  Logs, System History no longer fade into the card background
- show the panel version as a tag next to "3X-UI" on mobile, mirroring
  the Xray version tag pattern, and turn it orange when an update is
  available
- make the login settings button a proper circle by adding size="large"
  + an explicit border-radius fallback on .toolbar-btn

* feat: jalali calendar support and date formatting fixes

- Wire useDatepicker into IntlUtil and switch jalalian display locale
  to fa-IR for clean "1405/07/03 12:00:00" output (drops the awkward
  "AP" era suffix that "<lang>-u-ca-persian" produced)
- Drop in persian-calendar-suite for the jalali date picker, with a
  light/dark/ultra theme map and CSS overrides so the inline-styled
  input stays readable and bg matches the surrounding container
- Force LTR on the picker input so "1405/03/07 00:00" reads naturally
- Pass calendar setting through ClientInfoModal, ClientsPage Duration
  tooltip, and ClientFormModal's expiry picker
- Heuristic toMs() in ClientInfoModal so GORM's autoUpdateTime seconds
  render as a real date instead of "1348/11/01"
- Persist UpdatedAt on the ClientRecord row in client_service.Update;
  previously only the inbound settings JSON was bumped, so the panel
  never saw a fresh updated_at after editing a client

* feat(frontend): donate link, panel version label, login lang menu

- Sidebar: add heart donate link to https://donate.sanaei.dev and small panel version under 3X-UI brand
- Login: swap settings-cog for translation icon, drop title, render languages as a direct list
- Vite dev: inject window.X_UI_CUR_VER from config/version so dev mode matches prod
- Translations: add menu.donate across all locales

* fix(xray-update): respect XUI_BIN_FOLDER on Windows

The Windows update path hardcoded "bin/xray-windows-amd64.exe", ignoring
the configured XUI_BIN_FOLDER. In dev mode (folder set to x-ui) this
created a stray bin/ folder while the running binary stayed un-updated.

* Bump Xray to v26.5.9 and minor cleanup

Update Xray release URLs to v26.5.9 in the GitHub Actions workflow and DockerInit.sh. Remove the hardcoded skip for tagVersion "26.5.3" so it will be considered when collecting Xray versions. Apply small formatting fixes: remove an extra blank line in database/db.go, normalize spacing/alignment of Protocol constants in database/model/model.go, and trim a trailing blank line in web/controller/inbound.go.

* fix(frontend): route remaining copy buttons through ClipboardManager

Direct navigator.clipboard calls fail in non-secure contexts (HTTP on a
LAN IP), making the API-docs code copy and security-tab token copy
silently broken. Both now go through ClipboardManager which falls back
to document.execCommand('copy') when navigator.clipboard is unavailable.

* fix(db): store CreatedAt/UpdatedAt in milliseconds

GORM's autoCreateTime/autoUpdateTime tags default to Unix seconds on
int64 fields and overwrite the service-supplied UnixMilli value on
save. The frontend interprets these timestamps as JS Date inputs
(milliseconds), so created/updated columns rendered ~1970 dates. Adding
the :milli qualifier makes GORM match what the service code and UI
expect.

* Improve legacy clipboard copy handling

Refactor ClipboardManager._legacyCopy to better handle focus and selection when copying. The textarea is now appended to the active element's parent (or body) and placed off-screen with aria-hidden and readonly attributes. The code preserves and restores the previous document selection and active element, uses focus({preventScroll: true}) to avoid scrolling, and returns the execCommand('copy') result. This makes legacy copy behavior more robust and less disruptive to the page state.

* fix(lint): drop redundant ok=false in clipboard fallback catch

* chore(deps): bump golang.org/x/net to v0.55.0 for GO-2026-5026
2026-05-23 15:21:45 +02:00

1093 lines
No EOL
77 KiB
JSON
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"username": "Ім'я користувача",
"password": "Пароль",
"login": "Увійти",
"confirm": "Підтвердити",
"cancel": "Скасувати",
"close": "Закрити",
"save": "Зберегти",
"logout": "Вийти",
"create": "Створити",
"update": "Оновити",
"copy": "Копіювати",
"copied": "Скопійовано",
"download": "Завантажити",
"remark": "Примітка",
"enable": "Увімкнути",
"protocol": "Протокол",
"search": "Пошук",
"filter": "Фільтр",
"loading": "Завантаження...",
"refresh": "Оновити",
"clear": "Очистити",
"second": "Секунда",
"minute": "Хвилина",
"hour": "Година",
"day": "День",
"check": "Перевірка",
"indefinite": "Безстроково",
"unlimited": "Безлімітний",
"none": "Немає",
"qrCode": "QR-Код",
"info": "Більше інформації",
"edit": "Редагувати",
"delete": "Видалити",
"reset": "Скидання",
"noData": "Немає даних.",
"copySuccess": "Скопійовано успішно",
"sure": "Звичайно",
"encryption": "Шифрування",
"useIPv4ForHost": "Використовувати IPv4 для хоста",
"transmission": "Протокол передачи",
"host": "Хост",
"path": "Шлях",
"camouflage": "Маскування",
"status": "Статус",
"enabled": "Увімкнено",
"disabled": "Вимкнено",
"depleted": "Вичерпано",
"depletingSoon": "Вичерпується",
"offline": "Офлайн",
"online": "Онлайн",
"domainName": "Доменне ім`я",
"monitor": "Слухати IP",
"certificate": "Цифровий сертифікат",
"fail": "Помилка",
"comment": "Коментар",
"success": "Успішно",
"lastOnline": "Був(ла) онлайн",
"getVersion": "Отримати версію",
"install": "Встановити",
"clients": "Клієнти",
"usage": "Використання",
"twoFactorCode": "Код",
"remained": "Залишилося",
"security": "Беспека",
"secAlertTitle": "Попередження системи безпеки",
"secAlertSsl": "Це з'єднання не є безпечним. Будь ласка, уникайте введення конфіденційної інформації, поки TLS не буде активовано для захисту даних.",
"secAlertConf": "Деякі налаштування вразливі до атак. Рекомендується посилити протоколи безпеки, щоб запобігти можливим порушенням.",
"secAlertSSL": "Панель не має безпечного з'єднання. Будь ласка, встановіть сертифікат TLS для захисту даних.",
"secAlertPanelPort": "Стандартний порт панелі вразливий. Будь ласка, сконфігуруйте випадковий або конкретний порт.",
"secAlertPanelURI": "Стандартний URI-шлях панелі небезпечний. Будь ласка, сконфігуруйте складний URI-шлях.",
"secAlertSubURI": "Стандартний URI-шлях підписки небезпечний. Будь ласка, сконфігуруйте складний URI-шлях.",
"secAlertSubJsonURI": "Стандартний URI-шлях JSON підписки небезпечний. Будь ласка, сконфігуруйте складний URI-шлях.",
"emptyDnsDesc": "Немає доданих DNS-серверів.",
"emptyFakeDnsDesc": "Немає доданих Fake DNS-серверів.",
"emptyBalancersDesc": "Немає доданих балансувальників.",
"emptyReverseDesc": "Немає доданих зворотних проксі.",
"somethingWentWrong": "Щось пішло не так",
"subscription": {
"title": "Інформація про підписку",
"subId": "ID підписки",
"status": "Статус",
"downloaded": "Завантажено",
"uploaded": "Відвантажено",
"expiry": "Термін дії",
"totalQuota": "Загальна квота",
"individualLinks": "Окремі посилання",
"active": "Активна",
"inactive": "Неактивна",
"unlimited": "Безліміт",
"noExpiry": "Без строку"
},
"menu": {
"theme": "Тема",
"dark": "Темна",
"ultraDark": "Ультра темна",
"dashboard": "Огляд",
"inbounds": "Вхідні",
"clients": "Клієнти",
"nodes": "Вузли",
"settings": "Параметри панелі",
"xray": "Конфігурації Xray",
"apiDocs": "Документація API",
"logout": "Вийти",
"link": "Керувати",
"donate": "Підтримати"
},
"pages": {
"login": {
"hello": "Привіт",
"title": "Привітання!",
"loginAgain": "Ваш сеанс закінчився, увійдіть знову",
"toasts": {
"invalidFormData": "Формат вхідних даних недійсний.",
"emptyUsername": "Потрібне ім'я користувача",
"emptyPassword": "Потрібен пароль",
"wrongUsernameOrPassword": "Невірне ім’я користувача, пароль або код двофакторної аутентифікації.",
"successLogin": "Ви успішно увійшли до свого облікового запису."
}
},
"index": {
"title": "Огляд",
"cpu": "ЦП",
"logicalProcessors": "Логічні процесори",
"frequency": "Частота",
"swap": "Своп",
"storage": "Сховище",
"memory": "ОЗП",
"threads": "Потоки",
"xrayStatus": "Xray",
"stopXray": "Зупинити",
"restartXray": "Перезапустити",
"xraySwitch": "Версія",
"xrayUpdates": "Оновлення Xray",
"xraySwitchClick": "Виберіть версію, на яку ви хочете перейти.",
"xraySwitchClickDesk": "Вибирайте уважно, оскільки старіші версії можуть бути несумісними з поточними конфігураціями.",
"updatePanel": "Оновити панель",
"panelUpdateDesc": "Це оновить 3X-UI до останнього релізу та перезапустить сервіс панелі.",
"currentPanelVersion": "Поточна версія панелі",
"latestPanelVersion": "Остання версія панелі",
"panelUpToDate": "Панель оновлено",
"upToDate": "Оновлено",
"xrayStatusUnknown": "Невідомо",
"xrayStatusRunning": "Запущено",
"xrayStatusStop": "Зупинено",
"xrayStatusError": "Помилка",
"xrayErrorPopoverTitle": "Під час роботи Xray сталася помилка",
"operationHours": "Час роботи",
"systemHistoryTitle": "Історія системи",
"charts": "Графіки",
"xrayMetricsTitle": "Метрики Xray",
"xrayMetricsDisabled": "Кінцева точка метрик Xray не налаштована",
"xrayMetricsHint": "Додайте блок metrics верхнього рівня до конфігурації xray з tag metrics_out і listen 127.0.0.1:11111, потім перезапустіть xray.",
"xrayObservatoryEmpty": "Даних Observatory ще немає",
"xrayObservatoryHint": "Додайте блок observatory до конфігурації xray зі списком outbound тегів для перевірки, потім перезапустіть xray.",
"xrayObservatoryTagPlaceholder": "Виберіть outbound",
"xrayObservatoryAlive": "Активний",
"xrayObservatoryDead": "Недоступний",
"xrayObservatoryLastSeen": "Остання активність",
"xrayObservatoryLastTry": "Остання спроба",
"trendLast2Min": "Останні 2 хвилини",
"systemLoad": "Завантаження системи",
"systemLoadDesc": "Середнє завантаження системи за останні 1, 5 і 15 хвилин",
"connectionCount": "Статистика з'єднання",
"ipAddresses": "IP-адреси",
"toggleIpVisibility": "Перемкнути видимість IP",
"overallSpeed": "Загальна швидкість",
"upload": "Відправка",
"download": "Завантаження",
"totalData": "Загальний обсяг даних",
"sent": "Відправлено",
"received": "Отримано",
"documentation": "Документація",
"xraySwitchVersionDialog": "Ви дійсно хочете змінити версію Xray?",
"xraySwitchVersionDialogDesc": "Це змінить версію Xray на #version#.",
"xraySwitchVersionPopover": "Xray успішно оновлено",
"panelUpdateDialog": "Ви дійсно хочете оновити панель?",
"panelUpdateDialogDesc": "Це оновить 3X-UI до #version# та перезапустить сервіс панелі.",
"panelUpdateCheckPopover": "Перевірка оновлення панелі не вдалася",
"panelUpdateStartedPopover": "Розпочато оновлення панелі",
"geofileUpdateDialog": "Ви дійсно хочете оновити геофайл?",
"geofileUpdateDialogDesc": "Це оновить файл #filename#.",
"geofilesUpdateDialogDesc": "Це оновить усі геофайли.",
"geofilesUpdateAll": "Оновити все",
"geofileUpdatePopover": "Геофайл успішно оновлено",
"customGeoTitle": "Користувацькі GeoSite / GeoIP",
"customGeoAdd": "Додати",
"customGeoType": "Тип",
"customGeoAlias": "Псевдонім",
"customGeoUrl": "URL",
"customGeoEnabled": "Увімкнено",
"customGeoLastUpdated": "Оновлено",
"customGeoExtColumn": "Маршрутизація (ext:…)",
"customGeoToastUpdateAll": "Усі користувацькі джерела оновлено",
"customGeoActions": "Дії",
"customGeoEdit": "Змінити",
"customGeoDelete": "Видалити",
"customGeoDownload": "Оновити зараз",
"customGeoModalAdd": "Додати користувацький geo",
"customGeoModalEdit": "Змінити користувацький geo",
"customGeoModalSave": "Зберегти",
"customGeoDeleteConfirm": "Видалити це джерело geo?",
"customGeoRoutingHint": "У правилах маршрутизації використовуйте значення як ext:файл.dat:тег (замініть тег).",
"customGeoInvalidId": "Некоректний ідентифікатор ресурсу",
"customGeoAliasesError": "Не вдалося завантажити псевдоніми geo",
"customGeoValidationAlias": "Псевдонім: лише a-z, цифри, - і _",
"customGeoValidationUrl": "URL має починатися з http:// або https://",
"customGeoAliasPlaceholder": "a-z 0-9 _ -",
"customGeoAliasLabelSuffix": " (власний)",
"customGeoToastList": "Список користувацьких geo",
"customGeoToastAdd": "Додати користувацький geo",
"customGeoToastUpdate": "Оновити користувацький geo",
"customGeoToastDelete": "Користувацький geofile «{{ .fileName }}» видалено",
"customGeoToastDownload": "Geofile «{{ .fileName }}» оновлено",
"customGeoErrInvalidType": "Тип має бути geosite або geoip",
"customGeoErrAliasRequired": "Потрібен псевдонім",
"customGeoErrAliasPattern": "Псевдонім містить недопустимі символи",
"customGeoErrAliasReserved": "Цей псевдонім зарезервовано",
"customGeoErrUrlRequired": "Потрібен URL",
"customGeoErrInvalidUrl": "Некоректний URL",
"customGeoErrUrlScheme": "URL має використовувати http або https",
"customGeoErrUrlHost": "Некоректний хост URL",
"customGeoErrDuplicateAlias": "Цей псевдонім уже використовується для цього типу",
"customGeoErrNotFound": "Джерело geo не знайдено",
"customGeoErrDownload": "Помилка завантаження",
"customGeoErrUpdateAllIncomplete": "Не вдалося оновити один або кілька користувацьких джерел",
"customGeoEmpty": "Користувацьких джерел geo поки немає — натисніть «Додати», щоб створити",
"dontRefresh": "Інсталяція триває, будь ласка, не оновлюйте цю сторінку",
"logs": "Журнали",
"config": "Конфігурація",
"backup": "Резервна копія",
"backupTitle": "Резервне копіювання та відновлення",
"exportDatabase": "Резервна копія",
"exportDatabaseDesc": "Натисніть, щоб завантажити файл .db, що містить резервну копію вашої поточної бази даних на ваш пристрій.",
"importDatabase": "Відновити",
"importDatabaseDesc": "Натисніть, щоб вибрати та завантажити файл .db з вашого пристрою для відновлення бази даних з резервної копії.",
"importDatabaseSuccess": "Базу даних успішно імпортовано",
"importDatabaseError": "Виникла помилка під час імпорту бази даних",
"readDatabaseError": "Виникла помилка під час читання бази даних",
"getDatabaseError": "Виникла помилка під час отримання бази даних",
"getConfigError": "Виникла помилка під час отримання файлу конфігурації"
},
"inbounds": {
"title": "Вхідні",
"totalDownUp": "Всього надісланих/отриманих",
"totalUsage": "Всього використанно",
"inboundCount": "Загальна кількість вхідних",
"operate": "Меню",
"enable": "Увімкнено",
"remark": "Примітка",
"node": "Вузол",
"deployTo": "Розгорнути на",
"localPanel": "Локальна панель",
"fallbacks": {
"title": "Фолбеки",
"help": "Коли з'єднання на цьому інбаунді не збігається з жодним клієнтом, воно перенаправляється на інший інбаунд. Оберіть дочірній інбаунд нижче — поля маршрутизації (SNI / ALPN / Path / xver) заповняться автоматично з його транспорту; для більшості налаштувань більше нічого змінювати не треба. Кожен дочірній має слухати на 127.0.0.1 з security=none.",
"empty": "Фолбеків поки немає",
"add": "Додати фолбек",
"pickInbound": "Оберіть інбаунд",
"matchAny": "будь-який",
"rederive": "Заповнити з дочірнього",
"rederived": "Заповнено з дочірнього",
"editAdvanced": "Редагувати поля маршрутизації",
"hideAdvanced": "Сховати розширені",
"quickAddAll": "Швидко додати всі придатні",
"quickAdded": "Додано {n} фолбек(ів)",
"quickAddedNone": "Немає нових придатних інбаундів",
"routesWhen": "Маршрутизує, коли",
"defaultCatchAll": "За замовчуванням — ловить усе інше"
},
"protocol": "Протокол",
"port": "Порт",
"portMap": "Порт-перехід",
"traffic": "Трафік",
"details": "Деталі",
"transportConfig": "Транспорт",
"expireDate": "Тривалість",
"createdAt": "Створено",
"updatedAt": "Оновлено",
"resetTraffic": "Скинути трафік",
"addInbound": "Додати вхідний",
"generalActions": "Загальні дії",
"modifyInbound": "Змінити вхідний",
"deleteInbound": "Видалити вхідні",
"deleteInboundContent": "Ви впевнені, що хочете видалити вхідні?",
"deleteClient": "Видалити клієнта",
"deleteClientContent": "Ви впевнені, що хочете видалити клієнт?",
"resetTrafficContent": "Ви впевнені, що хочете скинути трафік?",
"copyLink": "Копіювати URL",
"address": "Адреса",
"network": "Мережа",
"destinationPort": "Порт призначення",
"targetAddress": "Цільова адреса",
"monitorDesc": "Залиште порожнім, щоб слухати всі IP-адреси",
"meansNoLimit": "= Необмежено. (одиниця: ГБ)",
"totalFlow": "Загальна витрата",
"leaveBlankToNeverExpire": "Залиште порожнім, щоб ніколи не закінчувався",
"noRecommendKeepDefault": "Рекомендується зберегти значення за замовчуванням",
"certificatePath": "Шлях до файлу",
"certificateContent": "Вміст файлу",
"publicKey": "Публічний ключ",
"privatekey": "Закритий ключ",
"clickOnQRcode": "Натисніть QR-код, щоб скопіювати",
"client": "Клієнт",
"export": "Експортувати всі URL-адреси",
"clone": "Клон",
"cloneInbound": "Клонувати",
"cloneInboundContent": "Усі налаштування цього вхідного потоку, крім порту, IP-адреси прослуховування та клієнтів, будуть застосовані до клону.",
"cloneInboundOk": "Клонувати",
"resetAllTraffic": "Скинути весь вхідний трафік",
"resetAllTrafficTitle": "Скинути весь вхідний трафік",
"resetAllTrafficContent": "Ви впевнені, що бажаєте скинути трафік усіх вхідних?",
"resetInboundClientTraffics": "Скинути трафік клієнтів",
"resetInboundClientTrafficTitle": "Скинути трафік клієнтів",
"resetInboundClientTrafficContent": "Ви впевнені, що бажаєте скинути трафік клієнтів цього вхідного потоку?",
"resetAllClientTraffics": "Скинути весь трафік клієнтів",
"resetAllClientTrafficTitle": "Скинути весь трафік клієнтів",
"resetAllClientTrafficContent": "Ви впевнені, що бажаєте скинути трафік усіх клієнтів?",
"delDepletedClients": "Видалити вичерпані клієнти",
"delDepletedClientsTitle": "Видалити вичерпані клієнти",
"delDepletedClientsContent": "Ви впевнені, що хочете видалити всі вичерпані клієнти?",
"email": "Електронна пошта",
"emailDesc": "Будь ласка, надайте унікальну адресу електронної пошти.",
"IPLimit": "Обмеження IP",
"IPLimitDesc": "Вимикає вхідний, якщо кількість перевищує встановлене значення. (0 = вимкнено)",
"IPLimitlog": "Журнал IP",
"IPLimitlogDesc": "Журнал історії IP-адрес. (щоб увімкнути вхідну після вимкнення, очистіть журнал)",
"IPLimitlogclear": "Очистити журнал",
"setDefaultCert": "Установити сертифікат з панелі",
"streamTab": "Потік",
"securityTab": "Безпека",
"sniffingTab": "Сніфінг",
"sniffingMetadataOnly": "Лише метадані",
"sniffingRouteOnly": "Лише маршрутизація",
"sniffingIpsExcluded": "Виключені IP",
"sniffingDomainsExcluded": "Виключені домени",
"decryption": "Розшифрування",
"encryption": "Шифрування",
"vlessAuthX25519": "Автентифікація X25519",
"vlessAuthMlkem768": "Автентифікація ML-KEM-768",
"vlessAuthCustom": "Користувацький",
"vlessAuthSelected": "Вибрано: {auth}",
"advanced": {
"title": "Розділи JSON вхідного",
"subtitle": "Повний JSON вхідного та окремі редактори для settings, sniffing і streamSettings.",
"all": "Усе",
"allHelp": "Повний об'єкт вхідного з усіма полями в одному редакторі.",
"settings": "Налаштування",
"settingsHelp": "Обгортка блоку settings Xray:",
"sniffing": "Сніфінг",
"sniffingHelp": "Обгортка блоку sniffing Xray:",
"stream": "Потік",
"streamHelp": "Обгортка блоку stream Xray:",
"jsonErrorPrefix": "Розширений JSON"
},
"telegramDesc": "Будь ласка, вкажіть ID чату Telegram. (використовуйте команду '/id' у боті) або ({'@'}userinfobot)",
"subscriptionDesc": "Щоб знайти URL-адресу вашої підписки, перейдіть до «Деталі». Крім того, ви можете використовувати одне ім'я для кількох клієнтів.",
"info": "Інформація",
"same": "Те саме",
"inboundData": "Вхідні дані",
"exportInbound": "Експортувати вхідні",
"import": "Імпорт",
"importInbound": "Імпортувати вхідний",
"periodicTrafficResetTitle": "Скидання трафіку",
"periodicTrafficResetDesc": "Автоматично скидати лічильник трафіку через певні проміжки часу",
"lastReset": "Останнє скидання",
"periodicTrafficReset": {
"never": "Ніколи",
"daily": "Щодня",
"weekly": "Щотижня",
"monthly": "Щомісяця",
"hourly": "Щогодини"
},
"toasts": {
"obtain": "Отримати",
"updateSuccess": "Оновлення пройшло успішно",
"logCleanSuccess": "Журнал очищено",
"inboundsUpdateSuccess": "Вхідні підключення успішно оновлено",
"inboundUpdateSuccess": "Вхідне підключення успішно оновлено",
"inboundCreateSuccess": "Вхідне підключення успішно створено",
"inboundDeleteSuccess": "Вхідне підключення успішно видалено",
"inboundClientAddSuccess": "Клієнт(и) вхідного підключення додано",
"inboundClientDeleteSuccess": "Клієнта вхідного підключення видалено",
"inboundClientUpdateSuccess": "Клієнта вхідного підключення оновлено",
"delDepletedClientsSuccess": "Усі вичерпані клієнти видалені",
"resetAllClientTrafficSuccess": "Весь трафік клієнта скинуто",
"resetAllTrafficSuccess": "Весь трафік скинуто",
"resetInboundClientTrafficSuccess": "Трафік скинуто",
"resetInboundTrafficSuccess": "Трафік вхідного потоку скинуто",
"trafficGetError": "Помилка отримання даних про трафік",
"getNewX25519CertError": "Помилка при отриманні сертифіката X25519.",
"getNewmldsa65Error": "Помилка при отриманні сертифіката mldsa65.",
"getNewVlessEncError": "Помилка при отриманні сертифіката VlessEnc."
},
"stream": {
"general": {
"request": "Запит",
"response": "Відповідь",
"name": "Ім'я",
"value": "Значення"
},
"tcp": {
"version": "Версія",
"method": "Метод",
"path": "Шлях",
"status": "Статус",
"statusDescription": "Опис стану",
"requestHeader": "Заголовок запиту",
"responseHeader": "Заголовок відповіді"
}
}
},
"clients": {
"add": "Додати клієнта",
"edit": "Редагувати клієнта",
"submitAdd": "Додати клієнта",
"submitEdit": "Зберегти зміни",
"clientCount": "Кількість клієнтів",
"bulk": "Масове додавання",
"copyFromInbound": "Скопіювати клієнтів із вхідного",
"copyToInbound": "Скопіювати клієнтів у",
"copySelected": "Скопіювати вибране",
"copySource": "Джерело",
"copyEmailPreview": "Перегляд email, що буде створено",
"copySelectSourceFirst": "Спочатку виберіть вхідний-джерело.",
"copyResult": "Результат копіювання",
"copyResultSuccess": "Скопійовано успішно",
"copyResultNone": "Нічого копіювати: не вибрано клієнтів або джерело порожнє",
"copyResultErrors": "Помилки копіювання",
"copyFlowLabel": "Flow для нових клієнтів (VLESS)",
"copyFlowHint": "Застосовується до всіх скопійованих клієнтів. Залишіть порожнім, щоб пропустити.",
"selectAll": "Вибрати все",
"clearAll": "Очистити все",
"method": "Метод",
"first": "Перший",
"last": "Останній",
"ipLog": "Журнал IP",
"prefix": "Префікс",
"postfix": "Постфікс",
"delayedStart": "Запуск після першого використання",
"expireDays": "Тривалість",
"days": "Дні",
"renew": "Авто-продовження",
"renewDesc": "Автоматичне продовження після закінчення. (0 = вимкнено) (одиниця: день)",
"title": "Клієнти",
"actions": "Дії",
"totalGB": "Усього надіслано/отримано (ГБ)",
"expiryTime": "Термін дії",
"addClients": "Додати клієнтів",
"limitIp": "Ліміт IP",
"password": "Пароль",
"subId": "ID підписки",
"online": "У мережі",
"email": "Email",
"comment": "Коментар",
"traffic": "Трафік",
"offline": "Не в мережі",
"addTitle": "Додати клієнта",
"qrCode": "QR-код",
"moreInformation": "Докладніше",
"delete": "Видалити",
"reset": "Скинути трафік",
"editTitle": "Редагувати клієнта",
"client": "Клієнт",
"enabled": "Увімкнено",
"remaining": "Залишок",
"duration": "Тривалість",
"attachedInbounds": "Прив'язані вхідні",
"selectInbound": "Виберіть один або кілька вхідних",
"noSubId": "У цього клієнта немає subId, посилання для спільного доступу відсутнє.",
"noLinks": "Немає посилань для спільного доступу — спочатку прив'яжіть цього клієнта до вхідного з підтримкою протоколу.",
"link": "Посилання",
"resetNotPossible": "Спочатку прив'яжіть цього клієнта до вхідного.",
"general": "Загальне",
"resetAllTraffics": "Скинути трафік усіх клієнтів",
"resetAllTrafficsTitle": "Скинути трафік усіх клієнтів?",
"resetAllTrafficsContent": "Лічильники відправлення/отримання кожного клієнта обнулюються. Квоти й термін дії не змінюються. Цю дію неможливо скасувати.",
"empty": "Клієнтів ще немає — додайте першого, щоб почати.",
"deleteConfirmTitle": "Видалити клієнта {email}?",
"deleteConfirmContent": "Клієнт буде вилучений з усіх прив'язаних вхідних, його запис трафіку буде знищено. Цю дію неможливо скасувати.",
"deleteSelected": "Видалити ({count})",
"bulkDeleteConfirmTitle": "Видалити {count} клієнтів?",
"bulkDeleteConfirmContent": "Кожен вибраний клієнт вилучається з усіх прив'язаних вхідних, його запис трафіку знищується. Цю дію неможливо скасувати.",
"delDepleted": "Видалити вичерпаних",
"delDepletedConfirmTitle": "Видалити вичерпаних клієнтів?",
"delDepletedConfirmContent": "Видаляються всі клієнти, у яких вичерпана квота трафіку або сплив термін. Цю дію неможливо скасувати.",
"auth": "Auth",
"hysteriaAuth": "Auth для Hysteria",
"uuid": "UUID",
"flow": "Flow",
"reverseTag": "Reverse tag",
"reverseTagPlaceholder": "Необов'язковий Reverse tag",
"telegramId": "ID користувача Telegram",
"telegramIdPlaceholder": "Числовий ID користувача Telegram (0 = немає)",
"created": "Створено",
"updated": "Оновлено",
"ipLimit": "Ліміт IP",
"toasts": {
"deleted": "Клієнта видалено",
"trafficReset": "Трафік скинуто",
"allTrafficsReset": "Трафік усіх клієнтів скинуто",
"bulkDeleted": "Видалено клієнтів: {count}",
"bulkDeletedMixed": "Видалено: {ok}, не вдалось: {failed}",
"bulkCreated": "Створено клієнтів: {count}",
"bulkCreatedMixed": "Створено: {ok}, не вдалось: {failed}",
"delDepleted": "Видалено вичерпаних клієнтів: {count}"
}
},
"nodes": {
"title": "Вузли",
"addNode": "Додати вузол",
"editNode": "Редагувати вузол",
"totalNodes": "Усього вузлів",
"onlineNodes": "Онлайн",
"offlineNodes": "Офлайн",
"avgLatency": "Середня затримка",
"name": "Назва",
"namePlaceholder": "напр. de-frankfurt-1",
"addressPlaceholder": "panel.example.com або 1.2.3.4",
"remark": "Примітка",
"scheme": "Схема",
"address": "Адреса",
"port": "Порт",
"basePath": "Базовий шлях",
"apiToken": "Токен API",
"apiTokenPlaceholder": "Токен зі сторінки Налаштувань віддаленої панелі",
"apiTokenHint": "Віддалена панель показує свій токен API в Налаштуваннях → Токен API.",
"regenerate": "Перегенерувати токен",
"regenerateConfirm": "Перегенерація скасовує поточний токен. Будь-яка центральна панель, що його використовує, втратить доступ до оновлення. Продовжити?",
"allowPrivateAddress": "Дозволити приватну адресу",
"allowPrivateAddressHint": "Увімкнути лише для вузлів у приватній мережі або VPN.",
"enable": "Увімкнено",
"status": "Статус",
"cpu": "CPU",
"mem": "Пам'ять",
"uptime": "Час роботи",
"latency": "Затримка",
"lastHeartbeat": "Останній пінг",
"xrayVersion": "Версія Xray",
"panelVersion": "Версія панелі",
"actions": "Дії",
"probe": "Перевірити зараз",
"testConnection": "Перевірити з'єднання",
"connectionOk": "З'єднання в порядку ({ms} мс)",
"connectionFailed": "Помилка з'єднання",
"never": "ніколи",
"justNow": "щойно",
"deleteConfirmTitle": "Видалити вузол \"{name}\"?",
"deleteConfirmContent": "Це зупинить моніторинг вузла. Сама віддалена панель не зазнає змін.",
"statusValues": {
"online": "Онлайн",
"offline": "Офлайн",
"unknown": "Невідомо"
},
"toasts": {
"list": "Не вдалося завантажити вузли",
"obtain": "Не вдалося завантажити вузол",
"add": "Додати вузол",
"update": "Оновити вузол",
"delete": "Видалити вузол",
"deleted": "Вузол видалено",
"test": "Перевірити з'єднання",
"fillRequired": "Назва, адреса, порт та токен API є обов'язковими",
"probeFailed": "Помилка перевірки"
}
},
"settings": {
"title": "Параметри панелі",
"save": "Зберегти",
"infoDesc": "Кожна внесена тут зміна повинна бути збережена. Перезапустіть панель, щоб застосувати зміни.",
"restartPanel": "Перезапустити панель",
"restartPanelDesc": "Ви впевнені, що бажаєте перезапустити панель? Якщо ви не можете отримати доступ до панелі після перезапуску, будь ласка, перегляньте інформацію журналу панелі на сервері.",
"restartPanelSuccess": "Панель успішно перезапущено",
"actions": "Дії",
"resetDefaultConfig": "Відновити значення за замовчуванням",
"panelSettings": "Загальні",
"securitySettings": "Автентифікація",
"TGBotSettings": "Telegram Бот",
"panelListeningIP": "Слухати IP",
"panelListeningIPDesc": "IP-адреса для веб-панелі. (залиште порожнім, щоб слухати всі IP-адреси)",
"panelListeningDomain": "Домен прослуховування",
"panelListeningDomainDesc": "Доменне ім'я для веб-панелі. (залиште порожнім, щоб слухати всі домени та IP-адреси)",
"panelPort": "Порт прослуховування",
"panelPortDesc": "Номер порту для веб-панелі. (має бути невикористаний порт)",
"publicKeyPath": "Шлях відкритого ключа",
"publicKeyPathDesc": "Шлях до файлу відкритого ключа для веб-панелі. (починається з /)",
"privateKeyPath": "Шлях приватного ключа",
"privateKeyPathDesc": "Шлях до файлу приватного ключа для веб-панелі. (починається з /)",
"panelUrlPath": "Шлях URL",
"panelUrlPathDesc": "Шлях URL для веб-панелі. (починається з / і закінчується /)",
"pageSize": "Розмір сторінки",
"pageSizeDesc": "Визначити розмір сторінки для вхідної таблиці. (0 = вимкнено)",
"remarkModel": "Модель зауваження та роздільний символ",
"datepicker": "Тип календаря",
"datepickerPlaceholder": "Виберіть дату",
"datepickerDescription": "Заплановані завдання виконуватимуться на основі цього календаря.",
"sampleRemark": "Зразок зауваження",
"oldUsername": "Поточне ім'я користувача",
"currentPassword": "Поточний пароль",
"newUsername": "Нове ім'я користувача",
"newPassword": "Новий пароль",
"telegramBotEnable": "Увімкнути Telegram Bot",
"telegramBotEnableDesc": "Вмикає бота Telegram.",
"telegramToken": "Telegram Токен",
"telegramTokenDesc": "Токен бота Telegram, отриманий від '{'@'}BotFather'.",
"telegramProxy": "SOCKS Проксі",
"telegramProxyDesc": "Вмикає проксі-сервер SOCKS5 для підключення до Telegram. (відкоригуйте параметри відповідно до посібника)",
"telegramAPIServer": "Сервер Telegram API",
"telegramAPIServerDesc": "Сервер Telegram API для використання. Залиште поле порожнім, щоб використовувати сервер за умовчанням.",
"telegramChatId": "Ідентифікатор чату адміністратора",
"telegramChatIdDesc": "Ідентифікатори чату адміністратора Telegram. (розділені комами) (отримайте тут {'@'}userinfobot) або (використовуйте команду '/id' у боті)",
"telegramNotifyTime": "Час сповіщення",
"telegramNotifyTimeDesc": "Час повідомлення бота Telegram, встановлений для періодичних звітів. (використовуйте формат часу crontab)",
"tgNotifyBackup": "Резервне копіювання бази даних",
"tgNotifyBackupDesc": "Надіслати файл резервної копії бази даних зі звітом.",
"tgNotifyLogin": "Сповіщення про вхід",
"tgNotifyLoginDesc": "Отримувати сповіщення про ім'я користувача, IP-адресу та час щоразу, коли хтось намагається увійти у вашу веб-панель.",
"sessionMaxAge": "Тривалість сеансу",
"sessionMaxAgeDesc": "Тривалість, протягом якої ви можете залишатися в системі. (одиниця: хвилина)",
"expireTimeDiff": "Повідомлення про дату закінчення",
"expireTimeDiffDesc": "Отримувати сповіщення про термін дії при досягненні цього порогу. (одиниця: день)",
"trafficDiff": "Повідомлення про обмеження трафіку",
"trafficDiffDesc": "Отримувати сповіщення про обмеження трафіку при досягненні цього порогу. (одиниця: ГБ)",
"tgNotifyCpu": "Сповіщення про завантаження ЦП",
"tgNotifyCpuDesc": "Отримувати сповіщення, якщо навантаження ЦП перевищує це порогове значення. (одиниця: %)",
"timeZone": "Часовий пояс",
"timeZoneDesc": "Заплановані завдання виконуватимуться на основі цього часового поясу.",
"subSettings": "Підписка",
"subEnable": "Увімкнути службу підписки",
"subEnableDesc": "Вмикає службу підписки.",
"subJsonEnable": "Увімкнути/вимкнути JSON-кінець підписки незалежно.",
"subTitle": "Назва Підписки",
"subTitleDesc": "Назва, яка відображається у VPN-клієнті",
"subSupportUrl": "URL підтримки",
"subSupportUrlDesc": "Посилання на технічну підтримку, що відображається у VPN-клієнті",
"subProfileUrl": "URL профілю",
"subProfileUrlDesc": "Посилання на ваш вебсайт, що відображається у VPN-клієнті",
"subAnnounce": "Оголошення",
"subAnnounceDesc": "Текст оголошення, що відображається у VPN-клієнті",
"subEnableRouting": "Увімкнути маршрутизацію",
"subEnableRoutingDesc": "Глобальне налаштування для увімкнення маршрутизації у VPN-клієнті. (Тільки для Happ)",
"subRoutingRules": "Правила маршрутизації",
"subRoutingRulesDesc": "Глобальні правила маршрутизації для VPN-клієнта. (Тільки для Happ)",
"subListen": "Слухати IP",
"subListenDesc": "IP-адреса для служби підписки. (залиште порожнім, щоб слухати всі IP-адреси)",
"subPort": "Слухати порт",
"subPortDesc": "Номер порту для служби підписки. (має бути невикористаний порт)",
"subCertPath": "Шлях відкритого ключа",
"subCertPathDesc": "Шлях до файлу відкритого ключа для служби підписки. (починається з /)",
"subKeyPath": "Шлях приватного ключа",
"subKeyPathDesc": "Шлях до файлу приватного ключа для служби підписки. (починається з /)",
"subPath": "Шлях URI",
"subPathDesc": "Шлях URI для служби підписки. (починається з / і закінчується /)",
"subDomain": "Домен прослуховування",
"subDomainDesc": "Ім'я домену для служби підписки. (залиште порожнім, щоб слухати всі домени та IP-адреси)",
"subUpdates": "Інтервали оновлення",
"subUpdatesDesc": "Інтервали оновлення URL-адреси підписки в клієнтських програмах. (одиниця: година)",
"subEncrypt": "Закодувати",
"subEncryptDesc": "Повернений вміст послуги підписки матиме кодування Base64.",
"subShowInfo": "Показати інформацію про використання",
"subShowInfoDesc": "Залишок трафіку та дата відображатимуться в клієнтських програмах.",
"subEmailInRemark": "Включати Email до назви",
"subEmailInRemarkDesc": "Включати email клієнта до назви профілю підписки.",
"subURI": "URI зворотного проксі",
"subURIDesc": "URI до URL-адреси підписки для використання за проксі.",
"externalTrafficInformEnable": "Інформація про зовнішній трафік",
"externalTrafficInformEnableDesc": "Інформувати зовнішній API про кожне оновлення трафіку.",
"externalTrafficInformURI": "Інформаційний URI зовнішнього трафіку",
"externalTrafficInformURIDesc": "Оновлення трафіку надсилаються на цей URI.",
"restartXrayOnClientDisable": "Перезапускати Xray після авто-вимкнення",
"restartXrayOnClientDisableDesc": "Коли клієнт автоматично вимикається через закінчення терміну дії або ліміт трафіку, перезапускати Xray.",
"fragment": "Фрагментація",
"fragmentDesc": "Увімкнути фрагментацію для пакету привітання TLS",
"fragmentSett": "Параметри фрагментації",
"noisesDesc": "Увімкнути Noises.",
"noisesSett": "Налаштування Noises",
"mux": "Mux",
"muxDesc": "Передавати кілька незалежних потоків даних у межах встановленого потоку даних.",
"muxSett": "Налаштування Mux",
"direct": "Пряме підключення",
"directDesc": "Безпосередньо встановлює з’єднання з доменами або діапазонами IP певної країни.",
"notifications": "Сповіщення",
"certs": "Сертифікати",
"externalTraffic": "Зовнішній трафік",
"dateAndTime": "Дата та час",
"proxyAndServer": "Проксі та сервер",
"intervals": "Інтервали",
"information": "Інформація",
"language": "Мова",
"telegramBotLanguage": "Мова Telegram-бота",
"security": {
"admin": "Облікові дані адміністратора",
"twoFactor": "Двофакторна аутентифікація",
"twoFactorEnable": "Увімкнути 2FA",
"twoFactorEnableDesc": "Додає додатковий рівень аутентифікації для підвищення безпеки.",
"twoFactorModalSetTitle": "Увімкнути двофакторну аутентифікацію",
"twoFactorModalDeleteTitle": "Вимкнути двофакторну аутентифікацію",
"twoFactorModalSteps": "Щоб налаштувати двофакторну аутентифікацію, виконайте кілька кроків:",
"twoFactorModalFirstStep": "1. Відскануйте цей QR-код у програмі для аутентифікації або скопіюйте токен біля QR-коду та вставте його в програму",
"twoFactorModalSecondStep": "2. Введіть код з програми",
"twoFactorModalRemoveStep": "Введіть код з програми, щоб вимкнути двофакторну аутентифікацію.",
"twoFactorModalChangeCredentialsTitle": "Змінити облікові дані",
"twoFactorModalChangeCredentialsStep": "Введіть код з додатку, щоб змінити облікові дані адміністратора.",
"twoFactorModalSetSuccess": "Двофакторна аутентифікація була успішно встановлена",
"twoFactorModalDeleteSuccess": "Двофакторна аутентифікація була успішно видалена",
"twoFactorModalError": "Невірний код",
"show": "Показати",
"hide": "Сховати",
"apiTokenNew": "Новий токен",
"apiTokenName": "Назва",
"apiTokenNamePlaceholder": "наприклад, central-panel-a",
"apiTokenNameRequired": "Назва обов'язкова",
"apiTokenEmpty": "Поки немає токенів — створіть один для автентифікації ботів або віддалених панелей.",
"apiTokenDeleteWarning": "Будь-який клієнт, що використовує цей токен, негайно втратить автентифікацію."
},
"toasts": {
"modifySettings": "Параметри було змінено.",
"getSettings": "Виникла помилка під час отримання параметрів.",
"modifyUserError": "Виникла помилка під час зміни облікових даних адміністратора.",
"modifyUser": "Ви успішно змінили облікові дані адміністратора.",
"originalUserPassIncorrect": "Поточне ім'я користувача або пароль недійсні",
"userPassMustBeNotEmpty": "Нове ім'я користувача та пароль порожні",
"getOutboundTrafficError": "Помилка отримання вихідного трафіку",
"resetOutboundTrafficError": "Помилка скидання вихідного трафіку"
}
},
"xray": {
"title": "Xray конфігурації",
"save": "Зберегти",
"restart": "Перезапустити Xray",
"restartSuccess": "Xray успішно перезапущено",
"stopSuccess": "Xray успішно зупинено",
"restartError": "Виникла помилка під час перезапуску Xray.",
"stopError": "Виникла помилка під час зупинки Xray.",
"basicTemplate": "Базовий шаблон",
"advancedTemplate": "Додатково",
"generalConfigs": "Загальні конфігурації",
"generalConfigsDesc": "Ці параметри визначатимуть загальні налаштування.",
"logConfigs": "Журнал",
"logConfigsDesc": "Журнали можуть вплинути на ефективність вашого сервера. Рекомендується вмикати його з розумом лише у випадку ваших потреб",
"blockConfigsDesc": "Ці параметри блокуватимуть трафік на основі конкретних запитуваних протоколів і веб-сайтів.",
"basicRouting": "Основна Маршрутизація",
"blockConnectionsConfigsDesc": "Ці параметри блокуватимуть трафік на основі запитаних країн.",
"directConnectionsConfigsDesc": "Пряме з'єднання гарантує, що певний трафік не буде маршрутизовано через інший сервер.",
"blockips": "Блокувати IP",
"blockdomains": "Блокувати домени",
"directips": "Прямі IP",
"directdomains": "Прямі домени",
"ipv4Routing": "Маршрутизація IPv4",
"ipv4RoutingDesc": "Ці параметри спрямовуватимуть трафік на основі певного призначення через IPv4.",
"warpRouting": "WARP Маршрутизація",
"warpRoutingDesc": "Ці параметри маршрутизуватимуть трафік на основі певного пункту призначення через WARP.",
"nordRouting": "Маршрутизація NordVPN",
"nordRoutingDesc": "Ці параметри маршрутизуватимуть трафік на основі певного пункту призначення через NordVPN.",
"Template": "Шаблон розширеної конфігурації Xray",
"TemplateDesc": "Остаточний конфігураційний файл Xray буде створено на основі цього шаблону.",
"FreedomStrategy": "Стратегія протоколу свободи",
"FreedomStrategyDesc": "Установити стратегію виведення для мережі в протоколі свободи.",
"RoutingStrategy": "Загальна стратегія маршрутизації",
"RoutingStrategyDesc": "Установити загальну стратегію маршрутизації трафіку для вирішення всіх запитів.",
"outboundTestUrl": "URL тесту outbound",
"outboundTestUrlDesc": "URL для перевірки з'єднання outbound",
"Torrent": "Блокувати протокол BitTorrent",
"Inbounds": "Вхідні",
"InboundsDesc": "Прийняття певних клієнтів.",
"Outbounds": "Вихід",
"Balancers": "Балансери",
"OutboundsDesc": "Встановити шлях вихідного трафіку.",
"Routings": "Правила маршрутизації",
"RoutingsDesc": "Пріоритет кожного правила важливий!",
"completeTemplate": "Усі",
"logLevel": "Рівень журналу",
"logLevelDesc": "Рівень журналу для журналів помилок із зазначенням інформації, яку потрібно записати.",
"accessLog": "Журнал доступу",
"accessLogDesc": "Шлях до файлу журналу доступу. Спеціальне значення 'none' вимикає журнали доступу",
"errorLog": "Журнал помилок",
"errorLogDesc": "Шлях до файлу журналу помилок. Спеціальне значення 'none' вимикає журнали помилок",
"dnsLog": "Журнал DNS",
"dnsLogDesc": "Чи включити журнали запитів DNS",
"maskAddress": "Маскувати Адресу",
"maskAddressDesc": "Маска IP-адреси, при активації автоматично замінює IP-адресу, яка з'являється у журналі.",
"statistics": "Статистика",
"statsInboundUplink": "Статистика вхідного аплінку",
"statsInboundUplinkDesc": "Увімкнення збору статистики для вхідного трафіку всіх вхідних проксі.",
"statsInboundDownlink": "Статистика вхідного даунлінку",
"statsInboundDownlinkDesc": "Увімкнення збору статистики для вихідного трафіку всіх вхідних проксі.",
"statsOutboundUplink": "Статистика вихідного аплінку",
"statsOutboundUplinkDesc": "Увімкнення збору статистики для вхідного трафіку всіх вихідних проксі.",
"statsOutboundDownlink": "Статистика вихідного даунлінку",
"statsOutboundDownlinkDesc": "Увімкнення збору статистики для вихідного трафіку всіх вихідних проксі.",
"rules": {
"first": "Перший",
"last": "Останній",
"up": "Вгору",
"down": "Вниз",
"source": "Джерело",
"dest": "Пункт призначення",
"inbound": "Вхідний",
"outbound": "Вихідний",
"balancer": "Балансувальник",
"info": "Інформація",
"add": "Додати правило",
"edit": "Редагувати правило",
"useComma": "Елементи, розділені комами"
},
"outbound": {
"addOutbound": "Додати вихідний",
"addReverse": "Додати реверс",
"editOutbound": "Редагувати вихідні",
"editReverse": "Редагувати реверс",
"reverseTag": "Тег реверс-проксі",
"reverseTagDesc": "Тег вихідного з'єднання для простого реверс-проксі VLESS. Залиште порожнім для вимкнення.",
"reverseTagPlaceholder": "тег вихідного (порожнє = вимкнено)",
"tag": "Тег",
"tagDesc": "Унікальний тег",
"address": "Адреса",
"reverse": "Зворотний",
"domain": "Домен",
"type": "Тип",
"bridge": "Міст",
"portal": "Портал",
"link": "Посилання",
"intercon": "Взаємозв'язок",
"settings": "Налаштування",
"accountInfo": "Інформація про обліковий запис",
"outboundStatus": "Статус виходу",
"sendThrough": "Надіслати через",
"test": "Тест",
"testResult": "Результат тесту",
"testing": "Тестування з'єднання...",
"testSuccess": "Тест успішний",
"testFailed": "Тест не пройдено",
"testError": "Не вдалося протестувати вихідне з'єднання",
"nordvpn": "NordVPN",
"accessToken": "Токен доступу",
"country": "Країна",
"server": "Сервер",
"city": "Місто",
"allCities": "Усі міста",
"privateKey": "Приватний ключ",
"load": "Навантаження"
},
"balancer": {
"addBalancer": "Додати балансир",
"editBalancer": "Редагувати балансир",
"balancerStrategy": "Стратегія",
"balancerSelectors": "Селектори",
"tag": "Тег",
"tagDesc": "Унікальний тег",
"balancerDesc": "Неможливо використовувати balancerTag і outboundTag одночасно. Якщо використовувати одночасно, працюватиме лише outboundTag."
},
"wireguard": {
"secretKey": "Приватний ключ",
"publicKey": "Публічний ключ",
"allowedIPs": "Дозволені IP-адреси",
"endpoint": "Кінцева точка",
"psk": "Спільний ключ",
"domainStrategy": "Стратегія домену"
},
"tun": {
"nameDesc": "Назва інтерфейсу TUN. Значення за замовчуванням - 'xray0'",
"mtuDesc": "Максимальна одиниця передачі. Максимальний розмір пакетів даних. Значення за замовчуванням - 1500",
"userLevel": "Рівень користувача",
"userLevelDesc": "Всі з'єднання, встановлені через цей вхід, використовуватимуть цей рівень користувача. Значення за замовчуванням - 0"
},
"dns": {
"enable": "Увімкнути DNS",
"enableDesc": "Увімкнути вбудований DNS-сервер",
"tag": "Мітка вхідного DNS",
"tagDesc": "Ця мітка буде доступна як вхідна мітка в правилах маршрутизації.",
"clientIp": "IP клієнта",
"clientIpDesc": "Використовується для повідомлення серверу про вказане місцезнаходження IP під час DNS-запитів",
"disableCache": "Вимкнути кеш",
"disableCacheDesc": "Вимкнути кешування DNS",
"disableFallback": "Вимкнути резервний DNS",
"disableFallbackDesc": "Вимкнути резервні DNS-запити",
"disableFallbackIfMatch": "Вимкнути резервний DNS при збігу",
"disableFallbackIfMatchDesc": "Вимкнути резервні DNS-запити при збігу списку доменів DNS-сервера",
"enableParallelQuery": "Увімкнути паралельні запити",
"enableParallelQueryDesc": "Увімкнути паралельні DNS-запити до кількох серверів для швидшого вирішення",
"strategy": "Стратегія запиту",
"strategyDesc": "Загальна стратегія вирішення доменних імен",
"add": "Додати сервер",
"edit": "Редагувати сервер",
"domains": "Домени",
"expectIPs": "Очікувані IP",
"unexpectIPs": "Неочікувані IP",
"useSystemHosts": "Використовувати системні Hosts",
"useSystemHostsDesc": "Використовувати файл hosts з встановленої системи",
"serveStale": "Видавати застарілі",
"serveStaleDesc": "Повертати застарілі результати з кешу під час фонового оновлення",
"serveExpiredTTL": "TTL застарілих",
"serveExpiredTTLDesc": "Термін дії (секунди) застарілих записів кешу; 0 = ніколи",
"timeoutMs": "Тайм-аут (мс)",
"skipFallback": "Пропустити Fallback",
"finalQuery": "Фінальний запит",
"hosts": "Hosts",
"hostsAdd": "Додати Host",
"hostsEmpty": "Host не визначено",
"hostsDomain": "Домен (напр. domain:example.com)",
"hostsValues": "IP або домен — введіть і натисніть Enter",
"usePreset": "Використати шаблон",
"dnsPresetTitle": "Шаблони DNS",
"dnsPresetFamily": "Сімейний",
"clearAll": "Видалити всі",
"clearAllTitle": "Видалити всі DNS-сервери?",
"clearAllConfirm": "Усі DNS-сервери буде видалено зі списку. Дію не можна скасувати."
},
"fakedns": {
"add": "Додати підроблений DNS",
"edit": "Редагувати підроблений DNS",
"ipPool": "Підмережа IP-пулу",
"poolSize": "Розмір пулу"
}
}
},
"tgbot": {
"keyboardClosed": "❌ Клавіатуру закрито!",
"noResult": "❗ Немає результату!",
"noQuery": "❌ Запит не знайдено! Будь ласка, використовуйте команду ще раз!",
"wentWrong": "❌ Щось пішло не так!",
"noIpRecord": "❗ Немає запису IP!",
"noInbounds": "❗ Вхідні не знайдені!",
"unlimited": "♾ Необмежено (Скинути)",
"add": "Додати",
"month": "Місяць",
"months": "Місяці",
"day": "День",
"days": "Дні",
"hours": "Години",
"minutes": "Хвилини",
"unknown": "Невідомо",
"inbounds": "Вхідні",
"clients": "Клієнти",
"offline": "🔴 Офлайн",
"online": "🟢 Онлайн",
"commands": {
"unknown": "❗ Невідома команда.",
"pleaseChoose": "👇 Будь ласка, виберіть:\r\n",
"help": "🤖 Ласкаво просимо до цього бота! Він розроблений, щоб надавати певні дані з веб-панелі та дозволяє вносити зміни за потреби.\r\n\r\n",
"start": "👋 Привіт <i>{{ .Firstname }}</i>.\r\n",
"welcome": "🤖 Ласкаво просимо до <b>{{ .Hostname }}</b> бота керування.\r\n",
"status": "✅ Бот в порядку!",
"usage": "❗ Введіть текст для пошуку!",
"getID": "🆔 Ваш ідентифікатор: <code>{{ .ID }}</code>",
"helpAdminCommands": "Для перезапуску Xray Core:\r\n<code>/restart</code>\r\n\r\nДля пошуку електронної пошти клієнта:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nДля пошуку вхідних (зі статистикою клієнта):\r\n<code>/inbound [Примітка]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>",
"helpClientCommands": "Для пошуку статистики використовуйте наступну команду:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>",
"restartUsage": "\r\n\r\n<code>/restart</code>",
"restartSuccess": "✅ Операція успішна!",
"restartFailed": "❗ Помилка в операції.\r\n\r\n<code>Помилка: {{ .Error }}</code>.",
"xrayNotRunning": "❗ Xray Core не запущений.",
"startDesc": "Показати головне меню",
"helpDesc": "Довідка по боту",
"statusDesc": "Перевірити статус бота",
"idDesc": "Показати ваш Telegram ID"
},
"messages": {
"cpuThreshold": "🔴 Навантаження ЦП {{ .Percent }}% перевищує порогове значення {{ .Threshold }}%",
"selectUserFailed": "❌ Помилка під час вибору користувача!",
"userSaved": "✅ Користувача Telegram збережено.",
"loginSuccess": "✅ Успішно ввійшли в панель\r\n",
"loginFailed": "❗️ Помилка входу в панель.\r\n",
"2faFailed": "Помилка 2FA",
"report": "🕰 Заплановані звіти: {{ .RunTime }}\r\n",
"datetime": "⏰ Дата й час: {{ .DateTime }}\r\n",
"hostname": "💻 Хост: {{ .Hostname }}\r\n",
"version": "🚀 3X-UI Версія: {{ .Version }}\r\n",
"xrayVersion": "📡 Xray Версія: {{ .XrayVersion }}\r\n",
"ipv6": "🌐 IPv6: {{ .IPv6 }}\r\n",
"ipv4": "🌐 IPv4: {{ .IPv4 }}\r\n",
"ip": "🌐 IP: {{ .IP }}\r\n",
"ips": "🔢 IP-адреси:\r\n{{ .IPs }}\r\n",
"serverUpTime": "⏳ Час роботи: {{ .UpTime }} {{ .Unit }}\r\n",
"serverLoad": "📈 Завантаження системи: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n",
"serverMemory": "📋 RAM: {{ .Current }}/{{ .Total }}\r\n",
"tcpCount": "🔹 TCP: {{ .Count }}\r\n",
"udpCount": "🔸 UDP: {{ .Count }}\r\n",
"traffic": "🚦 Трафік: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n",
"xrayStatus": " Статус: {{ .State }}\r\n",
"username": "👤 Ім'я користувача: {{ .Username }}\r\n",
"reason": "❗️ Причина: {{ .Reason }}\r\n",
"time": "⏰ Час: {{ .Time }}\r\n",
"inbound": "📍 Inbound: {{ .Remark }}\r\n",
"port": "🔌 Порт: {{ .Port }}\r\n",
"expire": "📅 Дата закінчення: {{ .Time }}\r\n",
"expireIn": "📅 Термін дії: {{ .Time }}\r\n",
"active": "💡 Активний: {{ .Enable }}\r\n",
"enabled": "🚨 Увімкнено: {{ .Enable }}\r\n",
"online": "🌐 Стан підключення: {{ .Status }}\r\n",
"lastOnline": "🔙 Був(ла) онлайн: {{ .Time }}\r\n",
"email": "📧 Електронна пошта: {{ .Email }}\r\n",
"upload": "🔼 Upload: ↑{{ .Upload }}\r\n",
"download": "🔽 Download: ↓{{ .Download }}\r\n",
"total": "📊 Всього: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
"TGUser": "👤 Користувач Telegram: {{ .TelegramID }}\r\n",
"exhaustedMsg": "🚨 Вичерпано {{ .Type }}:\r\n",
"exhaustedCount": "🚨 Вичерпано кількість {{ .Type }} count:\r\n",
"onlinesCount": "🌐 Онлайн-клієнти: {{ .Count }}\r\n",
"disabled": "🛑 Вимкнено: {{ .Disabled }}\r\n",
"depleteSoon": "🔜 Скоро вичерпається: {{ .Deplete }}\r\n\r\n",
"backupTime": "🗄 Час резервного копіювання: {{ .Time }}\r\n",
"refreshedOn": "\r\n📋🔄 Оновлено: {{ .Time }}\r\n\r\n",
"yes": "✅ Так",
"no": "❌ Ні",
"received_id": "🔑📥 ID оновлено.",
"received_password": "🔑📥 Пароль оновлено.",
"received_email": "📧📥 Електронна пошта оновлена.",
"received_comment": "💬📥 Коментар оновлено.",
"id_prompt": "🔑 Стандартний ID: {{ .ClientId }}\n\nВведіть ваш ID.",
"pass_prompt": "🔑 Стандартний пароль: {{ .ClientPassword }}\n\nВведіть ваш пароль.",
"email_prompt": "📧 Стандартний email: {{ .ClientEmail }}\n\nВведіть ваш email.",
"comment_prompt": "💬 Стандартний коментар: {{ .ClientComment }}\n\nВведіть ваш коментар.",
"inbound_client_data_id": "🔄 Вхід: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Електронна пошта: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Дата завершення: {{ .ClientExp }}\n🌐 Обмеження IP: {{ .IpLimit }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідного з'єднання!",
"inbound_client_data_pass": "🔄 Вхід: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Електронна пошта: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Дата завершення: {{ .ClientExp }}\n🌐 Обмеження IP: {{ .IpLimit }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідного з'єднання!",
"cancel": "❌ Процес скасовано! \n\nВи можете знову розпочати, використовуючи /start у будь-який час. 🔄",
"error_add_client": "⚠️ Помилка:\n\n {{ .error }}",
"using_default_value": "Гаразд, залишу значення за замовчуванням. 😊",
"incorrect_input": "Ваш ввід невірний.\nФрази повинні бути без пробілів.\nПравильний приклад: aaaaaa\nНеправильний приклад: aaa aaa 🚫",
"AreYouSure": "Ви впевнені? 🤔",
"SuccessResetTraffic": "📧 Електронна пошта: {{ .ClientEmail }}\n🏁 Результат: ✅ Успішно",
"FailedResetTraffic": "📧 Електронна пошта: {{ .ClientEmail }}\n🏁 Результат: ❌ Невдача \n\n🛠 Помилка: [ {{ .ErrorMessage }} ]",
"FinishProcess": "🔚 Процес скидання трафіку завершено для всіх клієнтів."
},
"buttons": {
"closeKeyboard": "❌ Закрити клавіатуру",
"cancel": "❌ Скасувати",
"cancelReset": "❌ Скасувати скидання",
"cancelIpLimit": "❌ Скасувати обмеження IP",
"confirmResetTraffic": "✅ Підтвердити скидання трафіку?",
"confirmClearIps": "✅ Підтвердити очищення IP-адрес?",
"confirmRemoveTGUser": "✅ Підтвердити видалення користувача Telegram?",
"confirmToggle": "✅ Підтвердити ввімкнути/вимкнути користувача?",
"dbBackup": "Отримати резервну копію БД",
"serverUsage": "Використання сервера",
"getInbounds": "Отримати вхідні",
"depleteSoon": "Скоро вичерпати",
"clientUsage": "Отримати використання",
"onlines": "Онлайн-клієнти",
"commands": "Команди",
"refresh": "🔄 Оновити",
"clearIPs": "❌ Очистити IP-адреси",
"removeTGUser": "❌ Видалити користувача Telegram",
"selectTGUser": "👤 Виберіть користувача Telegram",
"selectOneTGUser": "👤 Виберіть користувача Telegram:",
"resetTraffic": "📈 Скинути трафік",
"resetExpire": "📅 Змінити термін дії",
"ipLog": "🔢 IP журнал",
"ipLimit": "🔢 IP Ліміт",
"setTGUser": "👤 Встановити користувача Telegram",
"toggle": "🔘 Увімкнути / Вимкнути",
"custom": "🔢 Custom",
"confirmNumber": "✅ Підтвердити: {{ .Num }}",
"confirmNumberAdd": "✅ Підтвердити додавання: {{ .Num }}",
"limitTraffic": "🚧 Ліміт трафіку",
"getBanLogs": "Отримати журнали заборон",
"allClients": "Всі Клієнти",
"addClient": "Додати клієнта",
"submitDisable": "Надіслати як вимкнено ☑️",
"submitEnable": "Надіслати як увімкнено ✅",
"use_default": "🏷️ Використати типове",
"change_id": "⚙️🔑 ID",
"change_password": "⚙️🔑 Пароль",
"change_email": "⚙️📧 Електронна пошта",
"change_comment": "⚙️💬 Коментар",
"change_flow": "⚙️🚦 Потік",
"ResetAllTraffics": "Скинути весь трафік",
"SortedTrafficUsageReport": "Відсортований звіт про використання трафіку"
},
"answers": {
"successfulOperation": "✅ Операція успішна!",
"errorOperation": "❗ Помилка в роботі.",
"getInboundsFailed": "❌ Не вдалося отримати вхідні повідомлення.",
"getClientsFailed": "❌ Не вдалося отримати клієнтів.",
"canceled": "❌ {{ .Email }}: Операцію скасовано.",
"clientRefreshSuccess": "✅ {{ .Email }}: Клієнт успішно оновлено.",
"IpRefreshSuccess": "✅ {{ .Email }}: IP-адреси успішно оновлено.",
"TGIdRefreshSuccess": "✅ {{ .Email }}: Користувач Telegram клієнта успішно оновлено.",
"resetTrafficSuccess": "✅ {{ .Email }}: Трафік скинуто успішно.",
"setTrafficLimitSuccess": "✅ {{ .Email }}: Ліміт трафіку успішно збережено.",
"expireResetSuccess": "✅ {{ .Email }}: Успішно скинуто дні закінчення терміну дії.",
"resetIpSuccess": "✅ {{ .Email }}: IP обмеження {{ .Count }} успішно збережено.",
"clearIpSuccess": "✅ {{ .Email }}: IP успішно очищено.",
"getIpLog": "✅ {{ .Email }}: Отримати IP-журнал.",
"getUserInfo": "✅ {{ .Email }}: Отримати інформацію про користувача Telegram.",
"removedTGUserSuccess": "✅ {{ .Email }}: Користувача Telegram видалено успішно.",
"enableSuccess": "✅ {{ .Email }}: Увімкнути успішно.",
"disableSuccess": "✅ {{ .Email }}: Успішно вимкнено.",
"askToAddUserId": "Вашу конфігурацію не знайдено!\r\nБудь ласка, попросіть свого адміністратора використовувати ваш ідентифікатор Telegram у вашій конфігурації.\r\n\r\nВаш ідентифікатор користувача: <code>{{ .TgUserID }}</code>",
"chooseClient": "Виберіть клієнта для Вхідного {{ .Inbound }}",
"chooseInbound": "Виберіть Вхідний"
}
}
}