mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-17 08:40:59 +00:00
709b332d17
* test(sub): characterize current link output (externalProxy + single-link baselines)
Phase 0 of the Hosts feature. Locks current subscription-link output for the
externalProxy paths (vless/vmess/trojan/ss exact, reality/hysteria by Contains)
so the upcoming ShareEndpoint refactor can be proven behavior-preserving. These
must stay green and unedited through every later phase.
* refactor(sub): unify external-proxy link building behind ShareEndpoint (TDD, snapshot-locked)
Phase 1 of the Hosts feature. Collapse the duplicated externalProxy link
builders (param-form for vless/trojan/ss, object-form for vmess) onto a single
ShareEndpoint abstraction so Phase 4 can add Host-driven links with ~zero new
branching.
Design: an externalProxy-derived endpoint carries the original entry map and
applies it through the UNCHANGED applyExternalProxyTLS{Params,Obj} helpers, so
output is provably byte-identical. buildExternalProxyURLLinks /
buildVmessExternalProxyLinks become thin adapters; the genVless/Trojan/SS/Vmess
call sites are untouched. genHysteriaLink is deliberately left on its own path
(hex pinSHA256, not pcs). The no-externalProxy default tails are unchanged.
TDD: N1-N4 (externalProxyToEndpoint, inboundDefaultEndpoint, buildEndpointLinks,
buildEndpointVmessLinks) written failing-first against stubs, then implemented.
Mutation sanity (performed + reverted): dropping the ep-carry in
externalProxyToEndpoint makes the Phase-0 C1/C2 characterization snapshots go
red (TLS overrides vanish), proving the snapshots guard the emitted output.
Gate: go test ./internal/sub/... and go test ./... green with ZERO edits to the
Phase-0 snapshots; go build ./... green on linux and windows; go vet clean.
* feat(model): Host entity + automigrate + openapi codegen (TDD)
Phase 2 of the Hosts feature. Adds the Host GORM model: an override endpoint
attached to an inbound (address/port + TLS/transport/clash overrides + sub
scoping), superseding the legacy externalProxy array functionally while leaving
it intact.
- model.Host with snake_case column tags, json serializer for slices, text for
free-JSON (mux/sockopt/xhttp), validate tags (remark 1-40, port 0-65535,
security + mihomoIpVersion enums); TableName "hosts". NodeGuids column is added
now but unused (host->node scoping deferred to v2).
- Registered in BOTH initModels() (db.go) and migrationModels() (migrate_data.go);
the latter is required for cross-DB migration and is easy to miss. PG sequence
resync iterates the initModels slice, so it is covered automatically.
- pruneOrphanedHosts() deletes hosts whose inbound_id has no inbound, called
alongside pruneOrphanedClientInbounds().
- openapigen manifest: Host added to StructAllow with MuxParams/SockoptParams/
XhttpExtraParams -> KindAny; regenerated frontend/src/generated/* + openapi.json.
TDD: TestHostTableName, TestHostValidation, TestHostAutoMigrateCreatesColumns
(+ _Postgres), TestPruneOrphanedHosts written failing-first against a wrong-name,
untagged, unregistered stub, then implemented.
Gate: go test ./... green on SQLite AND a real Postgres DSN (local container);
go build/vet/gofmt clean; npm run gen succeeds with the new Host type/schema/
example/zod; npm run typecheck + npm run test (542) green.
* feat(api): Host CRUD service + controller + routes (TDD)
Phase 3 of the Hosts feature.
- service/host.go (HostService, empty struct + database.GetDB() like
ClientService): GetHosts, GetHostsByInbound, GetHost, AddHost (verifies the
inbound exists — no hard FK), UpdateHost (inbound + sort order immutable here),
DeleteHost, SetHostEnable, SetHostsEnable, DeleteHosts, ReorderHosts (single
driver-safe transaction), GetAllTags.
- controller/host.go mirrors NodeController: routes under /panel/api/hosts
(list/get/byInbound/tags + add/update/del/setEnable/reorder + bulk/setEnable,
bulk/del), binds via middleware.BindAndValidate so the model validate tags are
enforced, {success,msg,obj} envelopes.
- Wired the hosts group into api.go after nodes (inherits checkAPIAuth + CSRF).
- DelInbound now cascades: deleting an inbound deletes its hosts.
- Documented all 11 routes in api-docs endpoints.ts (referencing the generated
Host schema) and regenerated openapi.json; extended TestAPIRoutesDocumented's
controller->basePath switch for host.go. Backend en toast keys added.
TDD: service tests (Add/GetByInbound, RejectsUnknownInbound, Reorder, Set/Bulk
enable, DeleteHosts, DeleteInboundCascadesHosts, GetAllTags) written failing-
first against a nil-returning stub; controller test (AddListGetDelete envelope
round-trip + AuthInherited 401) added.
Gate: go test ./internal/web/... + go test ./... green; npm run gen + typecheck
+ lint + test (542) + build green.
* feat(sub): render subscription links from hosts; legacy fallback when none (TDD, mutation-checked)
Phase 4 of the Hosts feature. Inserts host resolution between inbound and link
across all three subscription formats.
Mechanism: hostEndpoints(inbound, format) loads the inbound's enabled hosts
(filtered by ExcludeFromSubTypes, ordered by sort_order then id) and projects
each onto the externalProxy entry shape the raw/json/clash renderers already
consume. So a host fans out one link/proxy reusing the exact existing rendering
(address/port/security/sni/fp/alpn/pins/ech) with zero new TLS code. Host header
and path overrides are applied additively in the raw builders (no-op for legacy
externalProxy, which never carries those keys — characterization snapshots stay
green). Clash ip-version (MihomoIpVersion) is set last on the proxy.
Integration points:
- getSubs (raw): per inbound, hostEndpoints AFTER projectThroughFallbackMaster;
len>0 -> linkFromHosts (renders only the hosts), else legacy GetLink.
- GetJson/GetClash: inject the host endpoints into the inbound's externalProxy
before the existing getConfig/getProxies loop.
- Precedence: hosts win over any legacy externalProxy (injection replaces it).
Backward compat: a zero-host inbound takes the legacy path -> byte-identical
output (all Phase-0 characterization snapshots unchanged).
TDD: 9 cycles (zero-hosts identical, N-links-ordered with host/path override,
disabled skipped, host-vs-externalProxy precedence, no-dedup, sort composes with
SubSortIndex, host-over-fallback, resolve-via-client-inbounds, ExcludeFromSubTypes
per format) written failing-first against unwired helpers, then wired green.
Mutation sanity (performed + reverted, documented here):
- zero-hosts fallback: flipping the len(hostEps)>0 guard to >=0 makes
TestSub_ZeroHosts_IdenticalOutput go red (host path yields "" for no hosts).
- no-dedup: adding a remark-dedup in hostEndpoints makes TestSub_NHosts_NoDedup
go red (two distinct hosts collapse to one link).
Gate: go test ./internal/sub/... + go test ./... green with ZERO edits to the
Phase-0 snapshots; go build green on linux and windows; go vet + gofmt clean.
* feat(migration): seed hosts from inbound externalProxy (TDD, idempotent, dual-driver)
Phase 5 of the Hosts feature. One-time migration so existing installs surface
their legacy externalProxy entries as first-class Host rows.
- seedHostsFromExternalProxy() is self-gated on a HistoryOfSeeders
"HostsFromExternalProxy" row (run-once) and wired into runSeeders. For each
inbound it parses StreamSettings, reads externalProxy[], and creates one Host
per entry: forceTls->Security (unknown->same), dest->Address, port->Port,
remark->Remark (generated when blank, capped at 40), sni/fingerprint/alpn/
pinnedPeerCertSha256/echConfigList copied; SortOrder=index; InboundId set.
- Additive: externalProxy is left intact in StreamSettings (rollback-safe; the
sub layer prefers hosts when present, §Phase 4).
- Postgres: GORM db.Create advances hosts_id_seq via the sequence, so no extra
resync is needed beyond the existing startup resync.
TDD: field-mapping, idempotency (second run no-op), no-externalProxy->no-hosts,
externalProxy-kept-intact written failing-first against a stub; plus a
Postgres counterpart that skips without XUI_DB_DSN.
Gate: go test ./internal/web/service/... ./internal/database/... green on SQLite;
the *_Postgres tests green against a real Postgres container; go build green on
linux and windows; go vet + gofmt clean. (Running the whole database package
under XUI_DB_TYPE=postgres is not supported — the SQLite-path tests share the one
DSN — so only the t.Skip-gated *_Postgres tests run with the env set.)
* feat(ui): Hosts page + schema + query hooks + link preview helper (TDD on schema/helpers)
Phase 6 of the Hosts feature — the admin UI.
- schemas/api/host.ts: HostFormSchema (validation: remark 1-40, tags ^[A-Z0-9_:]+$
≤10×≤36, port 0-65535, security/mihomoIpVersion enums, alpn/fingerprint reused
from the shared primitives) + a loose HostRecordSchema/HostListSchema for reads.
- lib/hosts/host-link.ts: hostToExternalProxyEntry — the frontend mirror of the
backend hostToExternalProxyMap (security->forceTls, sni override rules, port
inherit), for share-link previews.
- api/queries/useHostsQuery.ts + useHostMutations.ts (mirror the node hooks):
list/get + add/update/del/setEnable/reorder/bulk; queryKeys.hosts.* added;
mutations invalidate keys.hosts.root().
- pages/hosts/{HostsPage,HostList,HostFormModal}.tsx (+CSS) mirroring pages/nodes:
list with remark · address:port · inbound · security · tags · enable Switch ·
per-inbound move up/down (reorder) · bulk enable/disable/delete; form grouped
into Basic / Advanced / Clash / Subscription-scope sections.
- Route '/hosts' + sidebar item (Global icon); menu.hosts + pages.hosts.* added to
the en-US bundle (other locales fall back to English until translated).
TDD: HostFormSchema (10 cases) and hostToExternalProxyEntry (6 cases) written
failing-first, then implemented. UI verified by lint/typecheck/test/build.
Deferred (documented enhancement): the live in-form share-link preview (needs
inbound+client context) and a per-host host/path override in JSON/Clash output
(raw already overrides; JSON/Clash inherit the inbound's host/path).
Gate: cd frontend && npm run lint && npm run typecheck && npm run test (557) &&
npm run build all green; go build ./... + go test ./... still green.
* refactor(ui): remove the External Proxy form from the inbound stream settings
Hosts supersede the legacy externalProxy: the subscription renders from hosts
(hosts win when both exist) and the migration converts existing externalProxy
entries to hosts. externalProxy's only real consumers were the subscription
(now covered) and this form's preview — the backend per-client copy-link never
used it — so removing the editor has no functional regression.
- Drop ExternalProxyForm + toggleExternalProxy from InboundFormModal and delete
the orphaned form component + its export; remove its block test + snapshot.
- KEEP the externalProxy schema field and backend parsing/link-generation: an
existing inbound's externalProxy still round-trips through the form (not
silently destroyed on edit) and still renders if a host was removed.
Gate: cd frontend && npm run typecheck + lint + test (556) + build green.
* fix(ui): use Alert `title` instead of deprecated `message` (antd 6)
Ant Design 6 deprecated <Alert message=> in favor of <Alert title=>; the panel
was mid-migration (21 Alerts already on title). Renamed the 7 remaining stragglers
across 5 files (SubLinksModal, InboundFormModal, sockopt, EmailTab, TelegramTab),
silencing the runtime deprecation warning. description= is unchanged.
Pre-existing warning, surfaced while testing Hosts — not introduced by it.
Gate: npm run typecheck + lint + test (556) + build green.
* style(ui): align Hosts page with Clients/Inbounds cards + reorder columns
- page-shell.css never listed .hosts-page, so the Hosts page got no content
padding / transparent-layout / summary-card spacing. Add a .hosts-page shell
block (background, dark/ultra vars, content-area + summary-card padding). This
is the actual "card spacing" bug.
- HostList: match the Clients/Inbounds list card — hoverable + the toolbar moved
into the card title as a .card-toolbar (Add when nothing selected; selected
count + bulk enable/disable/delete on selection). Re-declare .card-toolbar in
HostList.css since the shared rule lives in a lazily-loaded page stylesheet.
- Reorder table columns as requested: Actions, Enable, then Remark, Endpoint,
Inbound, Security, Tags. Added scroll x for narrow screens.
- HostsPage: add a summary card (Total / Enabled / Disabled) like the other
pages. New i18n keys: pages.hosts.selectedCount + pages.hosts.summary.*.
Gate: npm run typecheck + lint + test (556) + build green.
* style(ui): use Tabs instead of Collapse in the Add/Edit Host form
The Basic / Advanced / Clash / Subscription-scope sections are now tabs. Each
pane sets forceRender so all fields stay mounted — required because the form
uses preserve=false, so an unmounted tab's values would otherwise be dropped on
submit (and a required field on a hidden tab still blocks submit).
Gate: npm run typecheck + lint + test (556) + build green.
* style(ui): split Host form into Security + Advanced tabs; drop unused JSON fields
- Remove the Mux/Sockopt/XHTTP raw-JSON fields from the Host form: they were not
wired into link generation and the inbound's structured editors are inbound-
specific (not reusable). The DB columns + read schema + generated type stay, so
they can get proper editors later. (HostFormSchema drops them; HostRecordSchema
keeps them.)
- Reorganize tabs to Basic / Security / Advanced / Clash / Subscription scope:
Security holds the TLS/cert fields (security, sni, sni-overrides, alpn,
fingerprint, pins, verify-by-name, ech); Advanced now holds the transport
overrides (host header, path).
- i18n: add pages.hosts.sections.security; drop the 3 unused field labels.
Gate: npm run typecheck + lint + test (556) + build green.
* style(ui): restore Mux/Sockopt/XHTTP fields in the Host Advanced tab
Put the three free-JSON override fields back, in the Advanced tab next to host
header / path (as JSON inputs — the inbound's structured editors aren't reusable
here). Re-added to HostFormSchema + defaults + the i18n labels.
Gate: npm run typecheck + lint + test (556) + build green.
* feat(hosts): add allowInsecure (rendered) + serverDescription/mihomoX25519/vlessRouteId fields
Closes most of the Remnawave-host gap analysis.
- model.Host: + allowInsecure, serverDescription (≤64), vlessRouteId (0-65535),
mihomoX25519. Auto-migrated (SQLite + Postgres verified); openapi regenerated.
- allowInsecure is fully RENDERED into subscription output (TDD):
- raw link: allowInsecure=1 (TLS/Reality, skipped for none) via the endpoint
builder;
- JSON/Clash: applyExternalProxyTLSToStream writes tlsSettings.settings.
allowInsecure, and clash applySecurity now emits skip-cert-verify for the tls
case (it previously only did so for Hysteria — a pre-existing gap, so inbound
allowInsecure now renders for vless/trojan/ss clash too).
- Frontend: the four fields added to the Host form (allowInsecure → Security,
serverDescription → Basic, vlessRouteId → Advanced, mihomoX25519 → Clash);
serverDescription shown under the remark in the list. Schema + i18n updated.
serverDescription / vlessRouteId / mihomoX25519 are stored + editable; their
deeper rendering (and per-host mux/sockopt/xhttp into JSON/Clash, plus a per-host
xray JSON template) are tracked as follow-ups.
Gate: go test ./... green (SQLite + Postgres for the host schema/migration);
go build linux+windows; go vet + gofmt clean; npm run gen + typecheck + lint +
test (556) + build green; generated files in sync.
* feat(sub): render host sockopt + xhttp-extra params into JSON/Clash output (TDD)
A host's sockoptParams and xhttpExtraParams (free-JSON) now take effect:
applyHostStreamOverrides injects sockopt into the per-host stream (re-added since
the base stream strips it) and merges xhttpExtraParams into xhttpSettings, called
in both getConfig (JSON) and getProxies (Clash) right after the per-host TLS
apply. No-op for legacy externalProxy entries (keys absent) — characterization
snapshots unchanged.
mux rendering is outbound-level (overrides outbound.Mux) and needs a genVless/
genVnext/genServer signature change — deferred, along with the per-host xray
JSON template.
Gate: go test ./internal/sub/... + go test ./... green (snapshots unchanged);
go build + vet + gofmt clean.
* feat(sub): render host muxParams as a per-host JSON outbound mux override (TDD)
genVnext/genVless/genServer take a muxOverride: a host's muxParams (when valid
JSON) overrides the global mux on its JSON outbound; empty falls back to the
panel mux (behavior unchanged for non-host configs). Completes the host
mux/sockopt/xhttp trio. Test call sites updated for the new signature.
Gate: go test ./internal/sub/... + go test ./... green (snapshots unchanged);
go build + gofmt clean.
* style(ui): show Host security fields conditionally per security (like externalProxy)
* feat(sub): apply host SNI + fingerprint override for reality (TDD)
A reality host now overrides SNI and fingerprint while inheriting publicKey/
shortId from the inbound (reality keys can't be host-supplied). Previously the
reality link kept the inbound's serverName because the TLS appliers are gated to
security=="tls".
- raw: applyEndpointRealityParams sets sni/fp on the params for reality;
- JSON/Clash: applyHostStreamOverrides sets realitySettings.serverName +
serverNames from the host SNI.
Gated to host endpoints via an isHost marker on the synthesized ep, so the legacy
externalProxy path stays byte-identical (characterization snapshots unchanged).
The marker is internal and never emitted.
Gate: go test ./internal/sub/... + go test ./... green; go build + vet + gofmt clean.
* fix(ui): start the Host inbound select unselected instead of showing 0
A new host left inboundId defaulting to 0, so the Select rendered "0". inboundId
is now optional in the form (undefined until chosen), so it shows its
placeholder ("Select an inbound"); the required rule still enforces a choice on
save. Port keeps 0 (means "inherit the inbound's port").
Gate: npm run typecheck + lint + build green.
* fix(ui): drop redundant :port suffix from the Host inbound select label
The inbound tag (e.g. in-59303-tcp) already carries the port, so the appended
":59303" was duplicated. Show just the remark/tag.
Gate: npm run typecheck + lint + build green.
* style(ui): apply the shared card hover shadows to the Hosts page
page-cards.css scoped its card styling + hover shadows to each page class but
not .hosts-page, so Hosts fell back to antd's default hoverable (a larger/blurry
shadow + pointer cursor). Add a .hosts-page block matching the other pages.
Gate: npm run build green.
* feat(hosts): move Tags to Basic tab, add Nodes field, accept VLESS route ranges
- Move the Tags field into the Host form's Basic tab and add a Nodes
multi-select (visual-only assignment, backed by the existing node_guids
column) so the Basic tab matches the reference layout.
- Replace the single-port vlessRouteId integer with a free-form vlessRoute
string that accepts comma-separated ports/ranges (e.g. 53,443,1000-2000);
format-validated on the frontend, stored verbatim on the backend.
- Regenerated frontend types/openapi from the changed model.
* feat(hosts): structured editors for Mux/Sockopt/XHTTP + new Final Mask
Replace the raw JSON textareas in the Host form's Advanced tab with the same
structured editors used elsewhere, under a nested tabbed layout (General / Mux /
Sockopt / XHTTP / Final Mask), mirroring the Sub-JSON settings tab:
- Mux: the Sub-JSON mux editor (enable + concurrency/xudpConcurrency/xudp443).
- Sockopt + XHTTP: reuse the outbound SockoptForm / XhttpForm, wrapped in an
isolated form that serializes the edited subtree back to the host's JSON
string (pruned so the override stays sparse).
- Final Mask: new host field (model + column + JSON-render wiring that merges
the masks into the host's JSON-subscription stream), edited via the shared
FinalMaskForm like the Sub-JSON Final Mask editor.
Each editor stays a controlled value/onChange component bound to its existing
host JSON string field; backend rendering of mux/sockopt/xhttp is unchanged.
* feat(hosts): drop XHTTP + Xray-JSON-template overrides; fix mobile form layout
Remove the host's XHTTP extra-params and Xray-JSON-template overrides entirely
(model fields + columns, JSON-subscription render paths incl. hostTemplateOutbound,
schema, form tab/field, i18n, openapi codegen, and their tests) — they did not
fit the host model. Mux, Sockopt and Final Mask stay as structured editors.
Mobile fixes for the Edit Host modal:
- responsive width (95vw on mobile, was a fixed 760px that overflowed the
viewport and clipped the tabs/labels) + a scrollable body so the footer stays
on screen;
- Mux fields use responsive Row/Col (stack on mobile) instead of a fixed-width
label grid.
* fix(hosts): hide the spurious horizontal scrollbar in the Edit Host modal
Setting overflowY:auto on the modal body forced overflow-x to auto too (CSS
rule), so antd Row's negative gutter margins triggered a horizontal scrollbar.
Pin overflowX:hidden.
* feat(hosts): inbound-style responsive field layout + icon empty state
- Host form (main form + Mux/Sockopt/Final Mask editors) now use the inbound
form's label layout: label beside the input on desktop (labelCol sm span 8 /
wrapperCol sm span 14, right-aligned), stacked label-above-input on mobile.
Rewrote HostMuxForm onto an internal antd Form so it follows the same layout
instead of a manual grid.
- Empty hosts table now shows the host icon + the shared 'Nothing here yet'
(noData) text, matching Nodes/Inbounds/Clients, replacing the bespoke
'No hosts yet…' string.
* fix(hosts): avoid nested <form> in the Edit Host modal
The Mux/Sockopt/Final Mask editors each render their own antd Form inside the
host's main Form, producing an invalid nested <form> DOM node (hydration
warning). Render those inner forms with component={false} so they keep the form
instance/context but emit no <form> element.
* fix(hosts): make the Mux enable toggle work
The Switch's checked state came from Form.useWatch('mux'), but the mux object
field had no registered Form.Item while disabled, so setFieldValue never
notified the watcher and the toggle stayed off. Bind the Switch to a real
name='enabled' field (antd drives its checked state directly) and keep the
sub-fields registered via hidden={!enabled}, serialized to the flat mux JSON.
* refactor(hosts): reuse the outbound MuxForm instead of a bespoke Mux editor
The Mux fields duplicated the outbound MuxForm. Reuse it through the same
wrapper as Sockopt: generalize OutboundSubtreeJsonForm with defaultSubtree
(pre-fill on enable) and a serialize hook, and have HostMuxForm render MuxForm
at the ['mux'] path. The host keeps its inherit-when-off semantics by storing ''
unless mux.enabled. Also drops the now-unused enableSwitch path from the
wrapper (only the removed XHTTP editor used it).
* style(hosts): use default-width Port input like the inbound form
The host Port used width:100% (full width); the inbound's numeric inputs use
antd's default width. Drop the override so Port matches. The Mux number inputs
already use the default width via the reused MuxForm.
* refactor(sockopt): readable customSockopt editor as a shared component
The customSockopt rows were a single cramped Space.Compact line and duplicated
verbatim in the inbound and outbound sockopt forms. Extract a shared
CustomSockoptList that renders each entry as a titled group of labeled fields
(System / Level / Opt / Type / Value), matching the rest of the form, and use it
in both (and thus the host Sockopt editor).
* fix(finalmask): drop the empty Custom Tables tag on a new sudoku mask
The sudoku TCP-mask default seeded customTables: [''] (one empty string), which
rendered as a blank removable tag. Seed [] instead.
* fix(sockopt): make the outbound (and host) Sockopt client-only
Per the XTLS sockopt docs, tproxy / acceptProxyProtocol / V6Only /
trustedXForwardedFor only apply to an inbound (listening socket); they are
meaningless on an outbound/dialer. Drop them from the outbound SockoptForm
(which the host reuses). The Sockopt default object still seeds those keys, so
the host also strips them on serialize, keeping its override honest to the
server/client split. The inbound SockoptForm is left unchanged.
* fix(sockopt): make the inbound Sockopt server-only
Complete the server/client split: drop the outbound/dialer-only fields from the
inbound SockoptForm — dialerProxy, domainStrategy, interface, addressPortStrategy,
happyEyeballs, tcpMptcp (client-only since Go 1.24 auto-enables MPTCP on listen).
mark stays (xray applies SO_MARK on inbound sockets too). Update the form-blocks
snapshot to the server-side field set (intentional spec change).
* feat(hosts): populate Sockopt dialerProxy with the panel's outbound tags
The host Sockopt editor reused the outbound SockoptForm with outboundTags=[],
so the dialerProxy dropdown was empty. Feed it the panel's outbound tags via
the existing useOutboundTags hook (shares the cached xray-config query;
blackhole excluded), so a host can chain through a subscription outbound by tag.
* fix(hosts): empty-state styling on direct load + exclude balancers from dialerProxy
- .card-empty was only defined in lazily-loaded Clients/Inbounds/Nodes
stylesheets, so a direct /hosts refresh rendered the empty table state
unstyled (faint + uncentered) until another page was visited. Re-declare it
in HostList.css so it's correct on first load.
- The Sockopt dialerProxy dropdown listed balancer tags (useOutboundTags merges
them in for mtproto egress). dialerProxy chains a single outbound, so balancers
aren't valid — switch to useOutboundTagGroups and use only the outbound group.
* fix(outbounds): icon + 'Nothing here yet' empty state; stop fading other pages
The Outbounds empty state was a faint '—', and OutboundsTab.css set the global
.card-empty to opacity:0.4 — which leaked onto whichever page's empty state was
shown after the Outbounds CSS had loaded (e.g. Hosts went faint after visiting
Outbounds). Render the icon + noData ('Nothing here yet') like the other lists,
and align .card-empty to the shared centered/secondary style (no opacity).
* fix(outbounds): custom empty state on the desktop table too
The desktop Outbounds Table had no locale.emptyText, so it showed antd's
default 'No data' box. Add the same ExportOutlined + noData empty state as the
card (mobile) view.
* style(sidebar): use ExportOutlined for the Outbounds nav item
The Outbounds sidebar item used UploadOutlined (an upload tray). Switch to
ExportOutlined, matching the outbound icon now used in the routing target and
the outbounds empty states.
* feat(hosts): icons on the form tabs (icon-only on mobile)
Wrap every Host form tab label (Basic/Security/Advanced/Clash/Subscription
scope and the nested General/Mux/Sockopt/Final Mask) with catTabLabel, so the
tabs show icon + text on desktop and just the icon (with a tooltip) on mobile,
matching the Settings/Xray tab bars.
* refactor(hosts): fold Exclude-from-formats into Advanced, drop the one-field tab
The Subscription scope tab held only excludeFromSubTypes after Tags moved to
Basic — a niche per-format scoping knob. Move it into the Advanced > General
sub-tab and remove the standalone tab (and its now-unused subScope label/icon).
* feat(sub): per-client remark template variables; drop the remark model & Show Usage Info
* fix(migration): cap seeded host remark at the model's 256-char limit, not 40
1904 lines
142 KiB
JSON
1904 lines
142 KiB
JSON
{
|
||
"username": "Ім'я користувача",
|
||
"password": "Пароль",
|
||
"login": "Увійти",
|
||
"confirm": "Підтвердити",
|
||
"cancel": "Скасувати",
|
||
"close": "Закрити",
|
||
"save": "Зберегти",
|
||
"logout": "Вийти",
|
||
"create": "Створити",
|
||
"add": "Додати",
|
||
"remove": "Видалити",
|
||
"update": "Оновити",
|
||
"copy": "Копіювати",
|
||
"copied": "Скопійовано",
|
||
"more": "більше",
|
||
"download": "Завантажити",
|
||
"remark": "Примітка",
|
||
"enable": "Увімкнути",
|
||
"protocol": "Протокол",
|
||
"search": "Пошук",
|
||
"filter": "Фільтр",
|
||
"all": "Усі",
|
||
"from": "Від",
|
||
"to": "До",
|
||
"done": "Готово",
|
||
"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": "Без строку",
|
||
"copyAllConfigs": "Копіювати всі конфігурації",
|
||
"copyAllConfigsCopied": "Всі конфігурації скопійовано"
|
||
},
|
||
"menu": {
|
||
"theme": "Тема",
|
||
"dark": "Темна",
|
||
"ultraDark": "Ультра темна",
|
||
"dashboard": "Огляд",
|
||
"inbounds": "Вхідні",
|
||
"clients": "Клієнти",
|
||
"groups": "Групи",
|
||
"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": "Історія системи",
|
||
"historyTitleCpu": "Завантаження ЦП",
|
||
"historyTitleMem": "Використання пам’яті",
|
||
"historyTitleNetwork": "Пропускна здатність мережі",
|
||
"historyTitlePackets": "Мережеві пакети",
|
||
"historyTitleDisk": "Дисковий ввід-вивід",
|
||
"historyTitleOnline": "Клієнти онлайн",
|
||
"historyTitleLoad": "Середнє навантаження системи (1 / 5 / 15 хв)",
|
||
"historyTitleConnections": "Активні з’єднання (TCP / UDP)",
|
||
"historyTitleDiskUsage": "Використання дискового простору",
|
||
"historyTabBandwidth": "Пропускна здатність",
|
||
"historyTabPackets": "Пакети",
|
||
"historyTabDisk": "Диск I/O",
|
||
"historyTabOnline": "Онлайн",
|
||
"historyTabLoad": "Навантаження",
|
||
"historyTabConnections": "З’єднання",
|
||
"historyTabDiskUsage": "Використання диска",
|
||
"charts": "Графіки",
|
||
"xrayMetricsTitle": "Метрики Xray",
|
||
"xrayTitleHeap": "Виділена пам’ять купи",
|
||
"xrayTitleSys": "Пам’ять, зарезервована в ОС",
|
||
"xrayTitleObjects": "Активні об’єкти купи",
|
||
"xrayTitleGcCount": "Завершені цикли GC",
|
||
"xrayTitleGcPause": "Тривалість паузи GC",
|
||
"xrayTitleObservatory": "Стан вихідних з’єднань",
|
||
"xrayTabHeap": "Купа",
|
||
"xrayTabSys": "Sys",
|
||
"xrayTabObjects": "Об’єкти",
|
||
"xrayTabGcCount": "Лічильник GC",
|
||
"xrayTabGcPause": "Пауза GC",
|
||
"xrayTabObservatory": "Обсерваторія",
|
||
"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": "Геофайл успішно оновлено",
|
||
"geodataTitle": "Автооновлення Geodata",
|
||
"geodataHint": "Xray завантажує ці файли за розкладом і перезавантажує їх без перезапуску. URL мають бути HTTPS. Файл має вже існувати в теці bin, щоб Xray міг його оновлювати.",
|
||
"geodataCron": "Розклад (cron)",
|
||
"geodataOutbound": "Завантажувати через outbound (необов’язково)",
|
||
"geodataFile": "Ім’я файлу",
|
||
"geodataAddFile": "Додати файл",
|
||
"geodataSaveRestart": "Зберегти та перезапустити Xray",
|
||
"geodataConfirmTitle": "Зберегти налаштування geodata?",
|
||
"geodataConfirmContent": "Шаблон конфігурації Xray буде оновлено, а Xray перезапущено.",
|
||
"geodataInvalidUrl": "Для кожного файлу потрібен HTTPS URL.",
|
||
"geodataInvalidFile": "Ім’я файлу має бути простим, напр. geosite_custom.dat (без шляхів).",
|
||
"geodataInvalidCron": "Cron має містити 5 полів, напр. 0 4 * * *",
|
||
"geodataEmpty": "Файли не налаштовано. У правилах маршрутизації файли вказуються як ext:geosite_custom.dat:category.",
|
||
"dontRefresh": "Інсталяція триває, будь ласка, не оновлюйте цю сторінку",
|
||
"logs": "Логи",
|
||
"config": "Конфігурація",
|
||
"backup": "Резервна копія",
|
||
"backupTitle": "Резервне копіювання та відновлення",
|
||
"exportDatabase": "Резервна копія",
|
||
"exportDatabaseDesc": "Натисніть, щоб завантажити файл .db, що містить резервну копію вашої поточної бази даних на ваш пристрій.",
|
||
"importDatabase": "Відновити",
|
||
"importDatabaseDesc": "Натисніть, щоб вибрати та завантажити файл .db з вашого пристрою для відновлення бази даних з резервної копії.",
|
||
"importDatabaseSuccess": "Базу даних успішно імпортовано",
|
||
"importDatabaseError": "Виникла помилка під час імпорту бази даних",
|
||
"readDatabaseError": "Виникла помилка під час читання бази даних",
|
||
"getDatabaseError": "Виникла помилка під час отримання бази даних",
|
||
"getConfigError": "Виникла помилка під час отримання файлу конфігурації",
|
||
"backupPostgresNote": "Ця панель працює на PostgreSQL. «Резервна копія» завантажує архів pg_dump (.dump), а «Відновлення» завантажує його назад через pg_restore. На сервері мають бути встановлені клієнтські інструменти PostgreSQL (pg_dump і pg_restore).",
|
||
"exportDatabasePgDesc": "Натисніть, щоб завантажити дамп PostgreSQL (.dump) вашої поточної бази даних на ваш пристрій.",
|
||
"importDatabasePgDesc": "Натисніть, щоб вибрати та завантажити файл .dump для відновлення бази даних PostgreSQL. Це замінить усі поточні дані.",
|
||
"migrationDownload": "Завантажити файл міграції",
|
||
"migrationDownloadDesc": "Натисніть, щоб завантажити переносний експорт .dump (текст SQL) вашої бази даних SQLite.",
|
||
"migrationDownloadPgDesc": "Натисніть, щоб завантажити базу даних SQLite (.db), створену з ваших даних PostgreSQL і готову для запуску панелі на SQLite."
|
||
},
|
||
"inbounds": {
|
||
"title": "Вхідні",
|
||
"totalDownUp": "Всього надісланих/отриманих",
|
||
"totalUsage": "Всього використанно",
|
||
"inboundCount": "Загальна кількість вхідних",
|
||
"operate": "Меню",
|
||
"enable": "Увімкнено",
|
||
"remark": "Примітка",
|
||
"node": "Вузол",
|
||
"deployTo": "Розгорнути на",
|
||
"localPanel": "Локальна панель",
|
||
"fallbacks": {
|
||
"title": "Fallback'и",
|
||
"help": "Коли з'єднання на цьому інбаунді не збігається з жодним клієнтом, воно перенаправляється в інше місце. Оберіть дочірній інбаунд нижче, щоб поля маршрутизації (SNI / ALPN / Path / xver) заповнилися автоматично з його транспорту, або залиште вибір порожнім і задайте Dest напряму (наприклад, 8080 або 127.0.0.1:8080), щоб перенаправити на зовнішній сервер, такий як Nginx. Кожен дочірній інбаунд має слухати на 127.0.0.1 з security=none.",
|
||
"empty": "Фолбеків поки немає",
|
||
"add": "Додати фолбек",
|
||
"pickInbound": "Оберіть інбаунд",
|
||
"matchAny": "будь-який",
|
||
"destPlaceholder": "авто (listen:порт дочірнього)",
|
||
"rederive": "Заповнити з дочірнього",
|
||
"rederived": "Заповнено з дочірнього",
|
||
"editAdvanced": "Редагувати поля маршрутизації",
|
||
"hideAdvanced": "Сховати розширені",
|
||
"quickAddAll": "Швидко додати всі придатні",
|
||
"quickAdded": "Додано {n} фолбек(ів)",
|
||
"quickAddedNone": "Немає нових придатних інбаундів",
|
||
"routesWhen": "Маршрутизує, коли",
|
||
"defaultCatchAll": "За замовчуванням — ловить усе інше",
|
||
"needsTls": "Fallbacks стануть доступні після вибору TLS або Reality на вкладці «Безпека» (лише VLESS/Trojan поверх RAW)."
|
||
},
|
||
"protocol": "Протокол",
|
||
"port": "Порт",
|
||
"portMap": "Відображення портів",
|
||
"traffic": "Трафік",
|
||
"speed": "Швидкість",
|
||
"details": "Деталі",
|
||
"transportConfig": "Транспорт",
|
||
"expireDate": "Тривалість",
|
||
"createdAt": "Створено",
|
||
"updatedAt": "Оновлено",
|
||
"resetTraffic": "Скинути трафік",
|
||
"addInbound": "Додати вхідний",
|
||
"generalActions": "Загальні дії",
|
||
"modifyInbound": "Змінити вхідний",
|
||
"deleteInbound": "Видалити вхідні",
|
||
"deleteInboundContent": "Ви впевнені, що хочете видалити вхідні?",
|
||
"deleteConfirmTitle": "Видалити вхідні \"{remark}\"?",
|
||
"deleteConfirmContent": "Це видалить вхідні та всіх його клієнтів. Цю дію неможливо скасувати.",
|
||
"resetConfirmTitle": "Скинути трафік \"{remark}\"?",
|
||
"resetConfirmContent": "Скидає лічильники відправки/отримання цього вхідного до 0.",
|
||
"selectedCount": "Обрано {count}",
|
||
"selectAll": "Вибрати все",
|
||
"bulkDeleteConfirmTitle": "Видалити {count} вхідних підключень?",
|
||
"bulkDeleteConfirmContent": "Будуть видалені вибрані вхідні підключення та всі їхні клієнти. Цю дію неможливо скасувати.",
|
||
"cloneConfirmTitle": "Клонувати вхідні \"{remark}\"?",
|
||
"cloneConfirmContent": "Створює копію з новим портом і порожнім списком клієнтів.",
|
||
"delAllClients": "Видалити всіх клієнтів",
|
||
"delAllClientsConfirmTitle": "Видалити всіх {count} клієнтів із \"{remark}\"?",
|
||
"delAllClientsConfirmContent": "Видаляє всіх клієнтів цього вхідного й скидає їхні записи трафіку. Сам вхідний зберігається. Цю дію не можна скасувати.",
|
||
"attachClients": "Прив'язати клієнтів до…",
|
||
"addClientsToGroup": "Додати клієнтів до групи…",
|
||
"attachClientsTitle": "Прив'язати клієнтів з «{remark}»",
|
||
"attachClientsDesc": "Прив'язує тих самих {count} клієнт(ів) (з тим самим UUID/паролем і спільним трафіком) до обраних вхідних. Вони залишаються і на цьому вхідному.",
|
||
"attachClientsTargets": "Цільові вхідні",
|
||
"attachClientsNoTargets": "Немає інших сумісних вхідних для прив'язки.",
|
||
"attachClientsResult": "Прив'язано {attached}, пропущено {skipped}.",
|
||
"attachClientsResultMixed": "Прив'язано {attached}, пропущено {skipped}, помилок {errors}.",
|
||
"attachClientsSelectLabel": "Клієнти для прив'язки",
|
||
"attachClientsSearchPlaceholder": "Пошук email або коментаря",
|
||
"attachClientsStatusDisabled": "Вимкнено",
|
||
"attachClientsSelectedCount": "Обрано {selected} з {total}",
|
||
"attachExistingClients": "Прив'язати наявних клієнтів…",
|
||
"attachExistingTitle": "Прив'язати наявних клієнтів до «{remark}»",
|
||
"attachExistingDesc": "Прив'язує наявних клієнтів (доступно {count}) до цього вхідного — той самий UUID/пароль і спільний трафік. Клієнти, уже прив'язані до нього, пропускаються.",
|
||
"attachExistingNoClients": "Клієнтів поки немає. Спершу створіть клієнтів, потім прив'яжіть їх тут.",
|
||
"attachExistingStatusAttached": "Вже прив'язано",
|
||
"detachClients": "Від'єднати клієнтів",
|
||
"detachClientsTitle": "Від'єднати клієнтів з «{remark}»",
|
||
"detachClientsDesc": "Видаляє обраних клієнт(ів) лише з цього вхідного. Записи клієнтів зберігаються (використовуйте Delete для повного видалення). У джерела всього {count} клієнт(ів).",
|
||
"detachClientsResult": "Від'єднано {detached}, пропущено {skipped}.",
|
||
"detachClientsResultMixed": "Від'єднано {detached}, пропущено {skipped}, помилок {errors}.",
|
||
"detachClientsSelectLabel": "Клієнти для від'єднання",
|
||
"exportLinksTitle": "Експортувати посилання вхідних",
|
||
"exportSubsTitle": "Експортувати посилання підписок",
|
||
"exportAllLinksTitle": "Експортувати всі посилання вхідних",
|
||
"exportAllSubsTitle": "Експортувати всі посилання підписок",
|
||
"exportAllLinksFileName": "Усі-вхідні",
|
||
"exportAllSubsFileName": "Усі-вхідні-Subs",
|
||
"inboundJsonTitle": "JSON вхідного",
|
||
"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": "Email",
|
||
"emailDesc": "Будь ласка, надайте унікальну адресу електронної пошти.",
|
||
"IPLimit": "Обмеження IP",
|
||
"IPLimitDesc": "Вимикає вхідний, якщо кількість перевищує встановлене значення. (0 = вимкнено)",
|
||
"IPLimitlog": "Журнал IP",
|
||
"IPLimitlogDesc": "Журнал історії IP-адрес. (щоб увімкнути вхідну після вимкнення, очистіть журнал)",
|
||
"IPLimitlogclear": "Очистити журнал",
|
||
"setDefaultCert": "Установити сертифікат з панелі",
|
||
"setDefaultCertEmpty": "Для панелі не налаштовано сертифікат. Спочатку встановіть його в Налаштуваннях.",
|
||
"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": "Sniffing",
|
||
"sniffingHelp": "Обгортка блоку sniffing Xray:",
|
||
"stream": "Stream",
|
||
"streamHelp": "Обгортка блоку stream Xray:",
|
||
"jsonErrorPrefix": "Розширений JSON"
|
||
},
|
||
"telegramDesc": "Будь ласка, вкажіть ID чату Telegram. (використовуйте команду '/id' у боті) або ({'@'}userinfobot)",
|
||
"subscriptionDesc": "Щоб знайти URL-адресу вашої підписки, перейдіть до «Деталі». Крім того, ви можете використовувати одне ім'я для кількох клієнтів.",
|
||
"subSortIndex": "Порядок",
|
||
"same": "Те саме",
|
||
"inboundInfo": "Інформація про підключення",
|
||
"exportInbound": "Експортувати вхідні",
|
||
"import": "Імпорт",
|
||
"importInbound": "Імпортувати вхідний",
|
||
"periodicTrafficResetTitle": "Скидання трафіку",
|
||
"periodicTrafficResetDesc": "Автоматично скидати лічильник трафіку через певні проміжки часу",
|
||
"lastReset": "Останнє скидання",
|
||
"periodicTrafficReset": {
|
||
"never": "Ніколи",
|
||
"daily": "Щодня",
|
||
"weekly": "Щотижня",
|
||
"monthly": "Щомісяця",
|
||
"hourly": "Щогодини"
|
||
},
|
||
"toasts": {
|
||
"obtain": "Отримати",
|
||
"updateSuccess": "Оновлення пройшло успішно",
|
||
"logCleanSuccess": "Журнал очищено",
|
||
"inboundsUpdateSuccess": "Вхідні підключення успішно оновлено",
|
||
"inboundUpdateSuccess": "Вхідне підключення успішно оновлено",
|
||
"inboundCreateSuccess": "Вхідне підключення успішно створено",
|
||
"bulkDeleted": "Видалено підключень: {count}",
|
||
"bulkDeletedMixed": "Видалено: {ok}, не вдалось: {failed}",
|
||
"inboundDeleteSuccess": "Вхідне підключення успішно видалено",
|
||
"inboundClientAddSuccess": "Клієнт(и) вхідного підключення додано",
|
||
"inboundClientDeleteSuccess": "Клієнта вхідного підключення видалено",
|
||
"inboundClientUpdateSuccess": "Клієнта вхідного підключення оновлено",
|
||
"savedNodeOfflineWillSync": "Збережено локально. Опорний вузол вимкнено або недоступний — зміни синхронізуються після повторного підключення.",
|
||
"delDepletedClientsSuccess": "Усі вичерпані клієнти видалені",
|
||
"resetAllClientTrafficSuccess": "Весь трафік клієнта скинуто",
|
||
"resetAllTrafficSuccess": "Весь трафік скинуто",
|
||
"resetInboundClientTrafficSuccess": "Трафік скинуто",
|
||
"resetInboundTrafficSuccess": "Трафік вхідного потоку скинуто",
|
||
"trafficGetError": "Помилка отримання даних про трафік",
|
||
"getNewX25519CertError": "Помилка при отриманні сертифіката X25519.",
|
||
"getNewmldsa65Error": "Помилка при отриманні сертифіката mldsa65.",
|
||
"getNewVlessEncError": "Помилка при отриманні сертифіката VlessEnc.",
|
||
"invalidClientField": "Клієнт {client}: поле {field} — {reason}",
|
||
"invalidField": "{field} — {reason}",
|
||
"moreIssues": "{message} (+{count} ще)"
|
||
},
|
||
"form": {
|
||
"moveUp": "Вгору",
|
||
"moveDown": "Вниз",
|
||
"addAll": "Додати всі",
|
||
"addAllFallbackTooltip": "Додає рядок fallback для кожного придатного вхідного, ще не приєднаного",
|
||
"peers": "Peers",
|
||
"addPeer": "Додати peer",
|
||
"keepAlive": "Keep-alive",
|
||
"autoSystemRoutesTooltip": "Лише для Windows. CIDR'и автоматично додаються до системної таблиці маршрутизації, щоб відповідний трафік проходив через TUN.",
|
||
"autoOutboundsInterface": "Авто-інтерфейс вихідних",
|
||
"autoOutboundsInterfaceTooltip": "Фізичний інтерфейс для вихідного трафіку. Використовуйте 'auto' для виявлення; вмикається автоматично, коли налаштовано Auto system routes.",
|
||
"rewriteAddress": "Переписати адресу",
|
||
"rewritePort": "Переписати порт",
|
||
"allowedNetwork": "Дозволена мережа",
|
||
"followRedirect": "Слідувати redirect",
|
||
"accounts": "Акаунти",
|
||
"allowTransparent": "Дозволити прозорий",
|
||
"encryptionMethod": "Метод шифрування",
|
||
"fakeTlsDomain": "Домен FakeTLS (SNI)",
|
||
"mtprotoSecret": "Секрет",
|
||
"mtgDomainFrontingIp": "IP домен-фронтингу",
|
||
"mtgDomainFrontingPort": "Порт домен-фронтингу",
|
||
"mtgDomainFrontingProxyProtocol": "PROXY-протокол домен-фронтингу",
|
||
"mtgDomainFrontingHint": "Куди mtg надсилає не-Telegram трафік — наприклад, на ваш фейковий сайт NGINX. Залиште IP порожнім, щоб використовувати домен FakeTLS через DNS; типовий порт — 443.",
|
||
"mtgProxyProtocolListener": "Приймати PROXY-протокол (слухач)",
|
||
"mtgPreferIp": "Перевага IP",
|
||
"mtgDebug": "Журнал налагодження",
|
||
"mtgRouteThroughXray": "Маршрутизація через Xray",
|
||
"mtgRouteThroughXrayHint": "Спрямуйте трафік Telegram цього проксі через Xray, щоб він підкорявся вашим правилам маршрутизації. Сайдкар mtg виходить через локальний SOCKS-міст із тегом цього вхідного підключення; використовуйте цей тег на вкладці «Маршрутизація» для розширених правил.",
|
||
"mtgRouteOutbound": "Вихідне",
|
||
"mtgRouteOutboundHint": "Необов'язково. Примусово спрямувати трафік Telegram через це вихідне з'єднання (або балансувальник). Залиште порожнім, щоб вирішували ваші правила маршрутизації.",
|
||
"mtgRouteOutboundPlaceholder": "Використовувати правила маршрутизації",
|
||
"visionTestseed": "Vision testseed",
|
||
"version": "Версія",
|
||
"udpIdleTimeout": "UDP idle timeout (с)",
|
||
"masquerade": "Masquerade",
|
||
"type": "Тип",
|
||
"upstreamUrl": "Upstream URL",
|
||
"rewriteHost": "Переписати Host",
|
||
"skipTlsVerify": "Пропустити TLS verify",
|
||
"directory": "Каталог",
|
||
"statusCode": "Код статусу",
|
||
"body": "Body",
|
||
"headers": "Заголовки",
|
||
"proxyProtocol": "Proxy Protocol",
|
||
"requestVersion": "Версія запиту",
|
||
"requestMethod": "Метод запиту",
|
||
"requestPath": "Шлях запиту",
|
||
"requestHeaders": "Заголовки запиту",
|
||
"responseVersion": "Версія відповіді",
|
||
"responseStatus": "Статус відповіді",
|
||
"responseReason": "Причина відповіді",
|
||
"responseHeaders": "Заголовки відповіді",
|
||
"heartbeatPeriod": "Період heartbeat",
|
||
"serviceName": "Назва сервісу",
|
||
"authority": "Authority",
|
||
"multiMode": "Multi Mode",
|
||
"maxBufferedUpload": "Макс. буферизоване завантаження",
|
||
"maxUploadSize": "Макс. розмір завантаження (байт)",
|
||
"streamUpServer": "Stream-Up Server",
|
||
"serverMaxHeaderBytes": "Server Max Header Bytes",
|
||
"paddingBytes": "Padding Bytes",
|
||
"uplinkHttpMethod": "HTTP-метод Uplink",
|
||
"paddingObfsMode": "Padding Obfs Mode",
|
||
"paddingKey": "Padding Key",
|
||
"paddingHeader": "Padding Header",
|
||
"paddingPlacement": "Padding Placement",
|
||
"paddingMethod": "Padding Method",
|
||
"sessionPlacement": "Session Placement",
|
||
"sessionKey": "Session Key",
|
||
"sequencePlacement": "Sequence Placement",
|
||
"sequenceKey": "Sequence Key",
|
||
"uplinkDataPlacement": "Uplink Data Placement",
|
||
"uplinkDataKey": "Uplink Data Key",
|
||
"noSseHeader": "Без заголовка SSE",
|
||
"ttiMs": "TTI (мс)",
|
||
"uplinkMbps": "Uplink (МБ/с)",
|
||
"downlinkMbps": "Downlink (МБ/с)",
|
||
"cwndMultiplier": "Множник CWND",
|
||
"maxSendingWindow": "Макс. вікно відправки",
|
||
"externalProxy": "External Proxy",
|
||
"forceTls": "Примусовий TLS",
|
||
"fingerprint": "Fingerprint",
|
||
"defaultOption": "За замовчуванням",
|
||
"routeMark": "Route Mark",
|
||
"tcpKeepAliveInterval": "TCP Keep Alive Interval",
|
||
"tcpKeepAliveIdle": "TCP Keep Alive Idle",
|
||
"tcpMaxSeg": "TCP Max Seg",
|
||
"tcpUserTimeout": "TCP User Timeout",
|
||
"tcpWindowClamp": "TCP Window Clamp",
|
||
"tcpWindowClampHint": "Залиште 0, щоб використовувати значення за умовчанням ОС. Ненульові значення обмежують оголошуване вікно приймання TCP; значення на кшталт 600 (з прикладу в документації Xray) можуть обвалити пропускну здатність на каналах із високою затримкою.",
|
||
"tcpFastOpen": "TCP Fast Open",
|
||
"multipathTcp": "Multipath TCP",
|
||
"penetrate": "Penetrate",
|
||
"v6Only": "Лише V6",
|
||
"tcpCongestion": "TCP Congestion",
|
||
"dialerProxy": "Dialer Proxy",
|
||
"trustedXForwardedFor": "Довірений X-Forwarded-For",
|
||
"trustedXForwardedForHint": "Довіряти цьому заголовку запиту для визначення справжнього IP клієнта (наприклад, CF-Connecting-IP за CDN Cloudflare). Працює лише на транспортах WebSocket, HTTPUpgrade та XHTTP. Залиште порожнім, щоб ігнорувати заголовки пересилання.",
|
||
"proxyProtocolHint": "Приймати заголовок PROXY protocol, щоб отримати справжній IP клієнта від висхідного L4-тунелю чи релея (HAProxy, gost, nginx-stream, Xray dokodemo-door) або Cloudflare Spectrum. Висхідний вузол МУСИТЬ надсилати PROXY protocol. Працює на TCP, WebSocket, HTTPUpgrade та gRPC; не працює на mKCP.",
|
||
"realClientIp": "Справжній IP клієнта",
|
||
"realClientIpHint": "Отримувати справжній IP відвідувача, коли трафік надходить на цей вхідний через CDN або релей, замість адреси проміжного вузла. Виберіть пресет, щоб заповнити відповідні поля sockopt нижче. Ці поля ніколи не надсилаються клієнтам у підписках.",
|
||
"realClientIpPresetOff": "Вимк. / напряму",
|
||
"realClientIpPresetCloudflare": "Cloudflare CDN",
|
||
"realClientIpPresetProxyProtocol": "L4-релей / Spectrum (PROXY)",
|
||
"realClientIpTrustedHeaderTransportWarn": "Trusted X-Forwarded-For працює лише на WebSocket, HTTPUpgrade та XHTTP. На поточному транспорті цей заголовок ігнорується.",
|
||
"realClientIpProxyProtocolTransportWarn": "PROXY protocol не підтримується на цьому транспорті (mKCP). Використовуйте TCP/RAW, WebSocket, HTTPUpgrade, gRPC або XHTTP.",
|
||
"addressPortStrategy": "Стратегія адрес+порт",
|
||
"tryDelayMs": "Затримка спроби (мс)",
|
||
"prioritizeIPv6": "Пріоритет IPv6",
|
||
"interleave": "Interleave",
|
||
"maxConcurrentTry": "Макс. одночасних спроб",
|
||
"customSockopt": "Користувацький sockopt",
|
||
"addCustomOption": "Додати опцію",
|
||
"serverNameIndication": "SNI",
|
||
"cipherSuites": "Cipher Suites",
|
||
"autoOption": "Авто",
|
||
"minMaxVersion": "Мін/Макс версія",
|
||
"rejectUnknownSni": "Відхиляти невідомий SNI",
|
||
"disableSystemRoot": "Вимкнути System Root",
|
||
"sessionResumption": "Відновлення сесії",
|
||
"oneTimeLoading": "Одноразове завантаження",
|
||
"usageOption": "Опція використання",
|
||
"buildChain": "Build Chain",
|
||
"echKey": "ECH key",
|
||
"echConfig": "ECH config",
|
||
"pinnedPeerCertSha256": "Закріплений SHA-256 сертифіката пира",
|
||
"pinnedPeerCertSha256Tip": "SHA-256-хеші сертифіката пира у вигляді шістнадцяткового рядка (напр. e8e2d3…), через кому. Лише панель — не записується в конфіг xray сервера, але додається до посилань спільного доступу, щоб клієнти могли закріпити сертифікат.",
|
||
"pinnedPeerCertSha256Placeholder": "шістнадцятковий хеш(і), через кому",
|
||
"generateRandomPin": "Згенерувати випадковий хеш",
|
||
"getNewEchCert": "Отримати новий ECH-сертифікат",
|
||
"show": "Показати",
|
||
"xver": "Xver",
|
||
"target": "Ціль",
|
||
"maxTimeDiff": "Макс. різниця в часі (мс)",
|
||
"minClientVer": "Мін. версія клієнта",
|
||
"maxClientVer": "Макс. версія клієнта",
|
||
"shortIds": "Short IDs",
|
||
"realityTargetHint": "Обов'язково. Має містити порт (напр., example.com:443). Без порту Xray-core не запускається.",
|
||
"realityTargetRequired": "Ціль REALITY обов'язкова",
|
||
"realityTargetNeedsPort": "Ціль REALITY має містити порт (напр., example.com:443)",
|
||
"realityTargetInvalidPort": "Ціль REALITY має недійсний порт",
|
||
"spiderX": "SpiderX",
|
||
"getNewCert": "Отримати новий сертифікат",
|
||
"mldsa65Seed": "mldsa65 Seed",
|
||
"mldsa65Verify": "mldsa65 Verify",
|
||
"getNewSeed": "Отримати новий Seed",
|
||
"listenHelp": "Можна також указати шлях Unix-сокета (наприклад, /run/xray/in.sock) або ім'я абстрактного сокета з префіксом @ (наприклад, @xray/in.sock), щоб слухати сокет замість TCP-порту — у цьому разі встановіть порт 0.",
|
||
"shareAddrStrategy": "Стратегія адреси поширення",
|
||
"shareAddrStrategyHelp": "Визначає, яку адресу записувати в експортовані посилання поширення, QR-коди та вивід підписки.",
|
||
"shareAddr": "Користувацька адреса поширення",
|
||
"shareAddrHelp": "Використовується лише коли стратегія адреси поширення — користувацька. Введіть хост або IP без схеми та порту.",
|
||
"subSortIndex": "Порядок у підписці",
|
||
"subSortIndexHelp": "Позиція посилань цього вхідного у виводі підписки (сторінка підписки та клієнтські застосунки). Менші значення йдуть першими; за однакових значень зберігається порядок створення. Не впливає на список вхідних у панелі.",
|
||
"shareAddrStrategyOptions": {
|
||
"node": "Адреса вузла",
|
||
"listen": "Адреса прослуховування inbound",
|
||
"custom": "Користувацька"
|
||
}
|
||
},
|
||
"info": {
|
||
"mode": "Режим",
|
||
"grpcServiceName": "grpc serviceName",
|
||
"grpcMultiMode": "grpc multiMode",
|
||
"interfaceName": "Назва інтерфейсу",
|
||
"mtu": "MTU",
|
||
"gateway": "Gateway",
|
||
"dns": "DNS",
|
||
"outboundsInterface": "Інтерфейс вихідних",
|
||
"autoSystemRoutes": "Авто-маршрути системи",
|
||
"followRedirect": "FollowRedirect",
|
||
"auth": "Auth",
|
||
"noKernelTun": "TUN без kernel",
|
||
"keepAlive": "Keep alive",
|
||
"peerNumber": "Peer {n}",
|
||
"peerNumberConfig": "Конфіг Peer {n}"
|
||
},
|
||
"stream": {
|
||
"general": {
|
||
"request": "Запит",
|
||
"response": "Відповідь",
|
||
"name": "Ім'я",
|
||
"value": "Значення"
|
||
},
|
||
"tcp": {
|
||
"version": "Версія",
|
||
"method": "Метод",
|
||
"path": "Шлях",
|
||
"status": "Статус",
|
||
"statusDescription": "Опис стану",
|
||
"requestHeader": "Заголовок запиту",
|
||
"responseHeader": "Заголовок відповіді"
|
||
}
|
||
}
|
||
},
|
||
"clients": {
|
||
"tabBasics": "Основні",
|
||
"tabCredentials": "Облікові дані",
|
||
"tabLinks": "Посилання",
|
||
"linksHint": "Додайте сторонні посилання та URL віддалених підписок, щоб включити їх до підписки цього клієнта.",
|
||
"addExternalLink": "Додати зовнішнє посилання",
|
||
"addExternalSubscription": "Додати зовнішню підписку",
|
||
"noExternalLinks": "Зовнішніх посилань ще немає.",
|
||
"noExternalSubscriptions": "Зовнішніх підписок ще немає.",
|
||
"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 = вимкнено) (одиниця: день)",
|
||
"renewDays": "Авто-продовження (днів)",
|
||
"searchPlaceholder": "Пошук email, коментаря, sub ID, UUID, паролю, auth…",
|
||
"filterTitle": "Фільтр клієнтів",
|
||
"clearAllFilters": "Очистити все",
|
||
"filters": {
|
||
"nodes": "Вузли",
|
||
"localPanel": "Локально (ця панель)"
|
||
},
|
||
"showingCount": "Показано {shown} з {total}",
|
||
"sortOldest": "Спочатку старі",
|
||
"sortNewest": "Спочатку нові",
|
||
"sortRecentlyUpdated": "Нещодавно оновлені",
|
||
"sortRecentlyOnline": "Нещодавно у мережі",
|
||
"sortEmailAZ": "Email А→Я",
|
||
"sortEmailZA": "Email Я→А",
|
||
"sortMostTraffic": "Більше трафіку",
|
||
"sortHighestRemaining": "Більше залишку",
|
||
"sortExpiringSoonest": "Швидше закінчуються",
|
||
"has": "Має",
|
||
"hasNot": "Не має",
|
||
"title": "Клієнти",
|
||
"actions": "Дії",
|
||
"totalGB": "Ліміт трафіку (ГБ)",
|
||
"totalGBDesc": "Квота трафіку для цього клієнта. 0 = без обмежень.",
|
||
"expiryTime": "Термін дії",
|
||
"addClients": "Додати клієнтів",
|
||
"limitIp": "Ліміт IP",
|
||
"limitIpDesc": "Максимум одночасних IP-адрес. 0 = без обмежень.",
|
||
"password": "Пароль",
|
||
"subId": "ID підписки",
|
||
"online": "У мережі",
|
||
"email": "Email",
|
||
"emailInvalidChars": "Email не може містити пробіли, '/', '\\' або керуючі символи",
|
||
"subIdInvalidChars": "ID підписки не може містити пробіли, '/', '\\' або керуючі символи",
|
||
"group": "Група",
|
||
"groupDesc": "Логічна мітка для групування пов'язаних клієнтів (напр. команда, клієнт, регіон). Фільтрується з панелі інструментів.",
|
||
"groupPlaceholder": "напр. customer-a",
|
||
"comment": "Коментар",
|
||
"traffic": "Трафік",
|
||
"offline": "Не в мережі",
|
||
"addClient": "Додати клієнта",
|
||
"qrCode": "QR-код",
|
||
"clientInfo": "Інформація про клієнта",
|
||
"delete": "Видалити",
|
||
"reset": "Скинути трафік",
|
||
"editClient": "Редагувати клієнта",
|
||
"client": "Клієнт",
|
||
"enabled": "Увімкнено",
|
||
"remaining": "Залишок",
|
||
"duration": "Тривалість",
|
||
"attachedInbounds": "Прив'язані вхідні",
|
||
"selectInbound": "Виберіть один або кілька вхідних",
|
||
"selectAllInbounds": "Вибрати все",
|
||
"clearAllInbounds": "Очистити все",
|
||
"noSubId": "У цього клієнта немає subId, посилання для спільного доступу відсутнє.",
|
||
"noLinks": "Немає посилань для спільного доступу — спочатку прив'яжіть цього клієнта до вхідного з підтримкою протоколу.",
|
||
"link": "Посилання",
|
||
"resetNotPossible": "Спочатку прив'яжіть цього клієнта до вхідного.",
|
||
"general": "Загальне",
|
||
"resetAllTraffics": "Скинути трафік усіх клієнтів",
|
||
"resetAllTrafficsTitle": "Скинути трафік усіх клієнтів?",
|
||
"resetAllTrafficsContent": "Лічильники відправлення/отримання кожного клієнта обнулюються. Квоти й термін дії не змінюються. Цю дію неможливо скасувати.",
|
||
"deleteConfirmTitle": "Видалити клієнта {email}?",
|
||
"deleteConfirmContent": "Клієнт буде вилучений з усіх прив'язаних вхідних, його запис трафіку буде знищено. Цю дію неможливо скасувати.",
|
||
"deleteSelected": "Видалити ({count})",
|
||
"adjustSelected": "Змінити ({count})",
|
||
"subLinksSelected": "Sub-посилання ({count})",
|
||
"addToGroupTitle": "Додати {count} клієнт(ів) до групи",
|
||
"addToGroupTooltip": "Виберіть існуючу групу або введіть нову назву. Використовуйте Ungroup, щоб вилучити клієнтів із поточної групи.",
|
||
"groupName": "Назва групи",
|
||
"addToGroupSuccessToast": "{count} клієнт(ів) додано до {group}",
|
||
"ungroupSuccessToast": "Групу очищено у {count} клієнт(ів)",
|
||
"ungroup": "Розгрупувати",
|
||
"ungroupConfirmTitle": "Видалити {count} клієнт(ів) з їхньої групи?",
|
||
"ungroupConfirmContent": "Очищує мітку групи у кожного обраного клієнта. Самі клієнти зберігаються (використовуйте Delete для повного видалення).",
|
||
"addToGroup": "Додати до групи",
|
||
"attach": "Прив'язати",
|
||
"adjust": "Коригування",
|
||
"subLinks": "Sub-посилання",
|
||
"selectedCount": "Обрано {count}",
|
||
"attachSelected": "Прив'язати ({count})",
|
||
"attachToInboundsTitle": "Прив'язати {count} клієнт(ів) до вхідних",
|
||
"attachToInboundsDesc": "Прив'язує обрані {count} клієнт(ів) (той самий UUID/пароль і спільний трафік) до обраних вхідних. Існуючі прив'язки зберігаються.",
|
||
"attachToInboundsTargets": "Цільові вхідні",
|
||
"attachToInboundsNoTargets": "Немає доступних багатокористувацьких вхідних для прив'язки.",
|
||
"detachSelected": "Від'єднати ({count})",
|
||
"detach": "Від'єднати",
|
||
"detachFromInboundsTitle": "Від'єднати {count} клієнт(ів) від вхідних",
|
||
"detachFromInboundsDesc": "Видаляє обраних {count} клієнт(ів) з обраних вхідних. Пари, де клієнт не був прив'язаний, тихо пропускаються. Записи клієнтів зберігаються (використовуйте Delete для повного видалення).",
|
||
"detachFromInboundsTargets": "Вхідні для від'єднання",
|
||
"detachFromInboundsNoTargets": "Немає доступних багатокористувацьких вхідних.",
|
||
"detachFromInboundsResult": "Від'єднано {detached}, пропущено {skipped}.",
|
||
"detachFromInboundsResultMixed": "Від'єднано {detached}, пропущено {skipped}, помилок {errors}.",
|
||
"subLinksTitle": "Sub-посилання ({count})",
|
||
"subLinkColumn": "URL підписки",
|
||
"subJsonLinkColumn": "URL JSON-підписки",
|
||
"subLinksCopyAll": "Копіювати все",
|
||
"subLinksCopiedAll": "Скопійовано {count} посилань",
|
||
"subLinksEmpty": "Жоден з обраних клієнтів не має ID підписки.",
|
||
"subLinksDisabled": "Сервіс підписки вимкнено.",
|
||
"subLinksDisabledHint": "Увімкніть підписку в Налаштування панелі → Підписка для генерації посилань.",
|
||
"bulkDeleteConfirmTitle": "Видалити {count} клієнтів?",
|
||
"bulkDeleteConfirmContent": "Кожен вибраний клієнт вилучається з усіх прив'язаних вхідних, його запис трафіку знищується. Цю дію неможливо скасувати.",
|
||
"bulkAdjustTitle": "Змінити {count} клієнтів",
|
||
"bulkAdjustHint": "Додатні значення подовжують, від'ємні зменшують. Клієнти з необмеженим терміном або трафіком пропускаються для відповідного поля.",
|
||
"bulkAdjustNothing": "Вкажіть дні або трафік перед застосуванням.",
|
||
"addDays": "Додати дні",
|
||
"addTrafficGB": "Додати трафік (ГБ)",
|
||
"delDepleted": "Видалити вичерпаних",
|
||
"delDepletedConfirmTitle": "Видалити вичерпаних клієнтів?",
|
||
"delDepletedConfirmContent": "Видаляються всі клієнти, у яких вичерпана квота трафіку або сплив термін. Цю дію неможливо скасувати.",
|
||
"auth": "Авторизація",
|
||
"hysteriaAuth": "Hysteria Auth",
|
||
"uuid": "UUID",
|
||
"flow": "Flow",
|
||
"vmessSecurity": "Безпека VMess",
|
||
"reverseTag": "Зворотний тег",
|
||
"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}",
|
||
"bulkAdjusted": "Змінено клієнтів: {count}",
|
||
"bulkAdjustedMixed": "Змінено: {ok}, пропущено: {skipped}",
|
||
"delDepleted": "Видалено вичерпаних клієнтів: {count}"
|
||
}
|
||
},
|
||
"groups": {
|
||
"title": "Групи",
|
||
"name": "Назва",
|
||
"clientCount": "Клієнти",
|
||
"totalGroups": "Всього груп",
|
||
"totalGroupedClients": "Клієнти з групою",
|
||
"trafficUsed": "Використаний трафік",
|
||
"upload": "Вивантаження",
|
||
"download": "Завантаження",
|
||
"totalTraffic": "Загальний трафік",
|
||
"totalUpDown": "Всього вивантажено / завантажено",
|
||
"addGroup": "Додати групу",
|
||
"createSuccess": "Групу «{name}» створено.",
|
||
"rename": "Перейменувати",
|
||
"renameTitle": "Перейменувати {name}",
|
||
"renameCollision": "Група з назвою «{name}» вже існує.",
|
||
"renameSuccess": "Групу перейменовано на {count} клієнт(ах).",
|
||
"deleteConfirmTitle": "Видалити групу {name}?",
|
||
"deleteConfirmContent": "Це видаляє групу й очищує її мітку у {count} клієнт(ів). Самі клієнти не видаляються.",
|
||
"deleteSuccess": "Групу очищено у {count} клієнт(ів).",
|
||
"resetTraffic": "Скинути трафік",
|
||
"resetConfirmTitle": "Скинути трафік групи {name}?",
|
||
"resetConfirmContent": "Це обнулить up/down для всіх {count} клієнт(ів) у цій групі.",
|
||
"resetSuccess": "Скинуто трафік у {count} клієнт(ів).",
|
||
"adjustSuccess": "Скориговано {count} клієнт(ів) у {name}.",
|
||
"emptyForAction": "У цій групі ще немає клієнтів.",
|
||
"deleteGroupOnly": "Видалити групу (зберегти клієнтів)",
|
||
"deleteClients": "Видалити клієнтів групи",
|
||
"deleteClientsConfirmTitle": "Видалити всіх клієнтів у {name}?",
|
||
"deleteClientsConfirmContent": "Це безповоротно видалить {count} клієнт(ів) разом з їхніми записами трафіку. Мітка групи також очищується. Дію не можна скасувати.",
|
||
"deleteClientsSuccess": "Видалено {count} клієнт(ів).",
|
||
"deleteClientsMixed": "{ok} видалено, {failed} пропущено",
|
||
"addToGroup": "Додати клієнтів…",
|
||
"addToGroupTitle": "Додати клієнтів до групи «{name}»",
|
||
"addToGroupDesc": "Виберіть клієнтів для додавання в цю групу. Існуючі прив'язки до вхідних зберігаються; змінюється лише мітка групи. Клієнти, які вже в цій групі, не відображаються.",
|
||
"addToGroupEmpty": "Немає інших клієнтів для додавання.",
|
||
"addToGroupResult": "Додано {count} клієнт(ів) до {name}.",
|
||
"removeFromGroup": "Видалити клієнтів…",
|
||
"removeFromGroupTitle": "Видалити клієнтів з групи «{name}»",
|
||
"removeFromGroupDesc": "Виберіть учасників для видалення з цієї групи. Самі клієнти зберігаються (використовуйте «Видалити клієнтів групи» для повного видалення).",
|
||
"removeFromGroupResult": "Видалено {count} клієнт(ів) з {name}."
|
||
},
|
||
"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.",
|
||
"outboundTag": "Вихідне з'єднання",
|
||
"outboundTagHint": "Маршрутизуйте трафік API панелі цього вузла через вибраний вихідний Xray. Вхідний міст зворотної петлі автоматично додається до поточної конфігурації та застосовується в реальному часі. Залиште порожнім для прямого підключення.",
|
||
"outboundTagPlaceholder": "Пряме підключення",
|
||
"inboundSyncMode": "Імпорт інбаундів",
|
||
"inboundSyncModeHint": "Виберіть інбаунди для імпорту з цього вузла. Для наявних вузлів типово імпортуються всі.",
|
||
"allInbounds": "Усі інбаунди",
|
||
"selectedInbounds": "Вибрані інбаунди",
|
||
"inboundTags": "Інбаунди",
|
||
"inboundTagsHint": "Вибір зіставляється за тегом інбаунду. Порожній список нічого не імпортує.",
|
||
"inboundTagsPlaceholder": "Завантажте та виберіть інбаунди",
|
||
"loadInbounds": "Завантажити інбаунди з вузла",
|
||
"inboundsLoaded": "Завантажено інбаундів: {{count}}",
|
||
"inboundsLoadFailed": "Не вдалося завантажити інбаунди",
|
||
"enable": "Увімкнено",
|
||
"status": "Статус",
|
||
"cpu": "CPU",
|
||
"mem": "Пам'ять",
|
||
"netUp": "Вихідний (KB/s)",
|
||
"netDown": "Вхідний (KB/s)",
|
||
"uptime": "Час роботи",
|
||
"latency": "Затримка",
|
||
"lastHeartbeat": "Останній пінг",
|
||
"xrayVersion": "Версія Xray",
|
||
"panelVersion": "Версія панелі",
|
||
"actions": "Дії",
|
||
"probe": "Перевірити зараз",
|
||
"updatePanel": "Оновити панель",
|
||
"updateSelected": "Оновити вибрані ({count})",
|
||
"updateAvailable": "Доступне оновлення",
|
||
"upToDate": "Актуально",
|
||
"updateConfirmTitle": "Оновити {count} вузлів до останньої версії?",
|
||
"updateConfirmContent": "Кожен вибраний вузол завантажить останній реліз і перезапуститься. Оновлюються лише увімкнені вузли в мережі.",
|
||
"testConnection": "Перевірити з'єднання",
|
||
"connectionOk": "З'єднання в порядку ({ms} мс)",
|
||
"connectionFailed": "Помилка з'єднання",
|
||
"never": "ніколи",
|
||
"justNow": "щойно",
|
||
"subNode": "Підвузол",
|
||
"subNodeTip": "Лише для читання: підлеглий вузол, доступний через {parent}. Керуйте ним із власної панелі {parent}.",
|
||
"deleteConfirmTitle": "Видалити вузол \"{name}\"?",
|
||
"deleteConfirmContent": "Це зупинить моніторинг вузла. Сама віддалена панель не зазнає змін.",
|
||
"statusValues": {
|
||
"online": "У мережі",
|
||
"offline": "Не в мережі",
|
||
"unknown": "Невідомо",
|
||
"xrayError": "Помилка Xray",
|
||
"xrayStopped": "Зупинено"
|
||
},
|
||
"toasts": {
|
||
"list": "Не вдалося завантажити вузли",
|
||
"obtain": "Не вдалося завантажити вузол",
|
||
"add": "Додати вузол",
|
||
"update": "Оновити вузол",
|
||
"delete": "Видалити вузол",
|
||
"deleted": "Вузол видалено",
|
||
"test": "Перевірити з'єднання",
|
||
"fillRequired": "Назва, адреса, порт та токен API є обов'язковими",
|
||
"probeFailed": "Помилка перевірки",
|
||
"updateStarted": "Оновлення панелі розпочато",
|
||
"updateResult": "Оновлення запущено на {ok} вузлах, {failed} не вдалося",
|
||
"updateNoneEligible": "Виберіть принаймні один увімкнений вузол у мережі",
|
||
"saveMtls": "Зберегти mTLS вузла"
|
||
},
|
||
"tlsVerifyMode": "Перевірка TLS",
|
||
"tlsVerifyModeHint": "Як панель перевіряє HTTPS-сертифікат вузла. Закріплення або Пропуск — для самопідписаних сертифікатів (лише https-вузли).",
|
||
"tlsVerify": "Перевіряти (стандартний CA)",
|
||
"tlsPin": "Закріпити сертифікат (SHA-256)",
|
||
"tlsSkip": "Пропустити перевірку",
|
||
"tlsMtls": "Взаємний TLS (клієнтський сертифікат)",
|
||
"mtlsFormHint": "Цей вузол автентифікує панель за допомогою клієнтського сертифіката. Скопіюйте CA цієї панелі з розділу «mTLS вузла» на вузол, задайте його довірений CA та перезапустіть вузол.",
|
||
"mtls": {
|
||
"title": "mTLS вузла",
|
||
"intro": "Взаємний TLS додає фактор клієнтського сертифіката поверх API-токена для викликів між вузлами. Це необов’язково: залиште порожнім, щоб використовувати лише автентифікацію за токеном.",
|
||
"copyCa": "Скопіювати CA цієї панелі",
|
||
"copyCaHint": "Передайте цей CA вузлам, якими керує ця панель, потім встановіть їхній режим перевірки TLS на «Взаємний TLS».",
|
||
"caCopied": "Сертифікат CA скопійовано в буфер обміну",
|
||
"caFailed": "Не вдалося отримати сертифікат CA",
|
||
"trustLabel": "Довірений CA (батьківська панель)",
|
||
"trustHint": "Якщо ця панель сама є вузлом, вставте сюди CA керуючої панелі, щоб вимагати її клієнтський сертифікат. Перезапустіть панель для застосування.",
|
||
"trustPlaceholder": "-----BEGIN CERTIFICATE-----",
|
||
"save": "Зберегти довірений CA",
|
||
"saved": "Довірений CA збережено — перезапустіть панель для застосування"
|
||
},
|
||
"tlsSkipWarning": "Пропуск перевірки прибирає захист від атак «людина посередині» — токен API можуть перехопити. Краще закріпити сертифікат.",
|
||
"pinnedCert": "SHA-256 закріпленого сертифіката",
|
||
"pinnedCertHint": "SHA-256 сертифіката вузла у base64 або hex. Натисніть «Отримати», щоб зчитати його з вузла зараз.",
|
||
"pinnedCertPlaceholder": "SHA-256 у base64 або hex",
|
||
"fetchPin": "Отримати",
|
||
"pinFetched": "Поточний сертифікат вузла отримано",
|
||
"pinFetchFailed": "Не вдалося отримати сертифікат"
|
||
},
|
||
"settings": {
|
||
"title": "Параметри панелі",
|
||
"save": "Зберегти",
|
||
"infoDesc": "Кожна внесена тут зміна повинна бути збережена. Перезапустіть панель, щоб застосувати зміни.",
|
||
"restartPanel": "Перезапустити панель",
|
||
"restartPanelDesc": "Ви впевнені, що бажаєте перезапустити панель? Якщо ви не можете отримати доступ до панелі після перезапуску, будь ласка, перегляньте інформацію журналу панелі на сервері.",
|
||
"restartPanelSuccess": "Панель успішно перезапущено",
|
||
"actions": "Дії",
|
||
"resetDefaultConfig": "Відновити значення за замовчуванням",
|
||
"panelSettings": "Загальні",
|
||
"securitySettings": "Автентифікація",
|
||
"securityWarnings": "Попередження безпеки",
|
||
"panelExposed": "Ваша панель може бути відкрита:",
|
||
"warnHttp": "Панель працює через звичайний HTTP — налаштуйте TLS для продакшну.",
|
||
"warnDefaultPort": "Стандартний порт 2053 широко відомий — змініть його на випадковий.",
|
||
"warnDefaultBasePath": "Базовий шлях за замовчуванням \"/\" широко відомий — змініть його на випадковий.",
|
||
"warnDefaultSubPath": "Шлях підписки за замовчуванням \"/sub/\" широко відомий — змініть його.",
|
||
"warnDefaultJsonPath": "JSON-шлях підписки за замовчуванням \"/json/\" широко відомий — змініть його.",
|
||
"TGBotSettings": "Telegram-бот",
|
||
"panelListeningIP": "Слухати IP",
|
||
"panelListeningIPDesc": "IP-адреса для веб-панелі. (залиште порожнім, щоб слухати всі IP-адреси)",
|
||
"panelListeningDomain": "Домен прослуховування",
|
||
"panelListeningDomainDesc": "Доменне ім'я для веб-панелі. (залиште порожнім, щоб слухати всі домени та IP-адреси)",
|
||
"panelPort": "Порт прослуховування",
|
||
"panelPortDesc": "Номер порту для веб-панелі. (має бути невикористаний порт)",
|
||
"publicKeyPath": "Шлях відкритого ключа",
|
||
"publicKeyPathDesc": "Шлях до файлу відкритого ключа для веб-панелі. (починається з ‘/‘)",
|
||
"privateKeyPath": "Шлях приватного ключа",
|
||
"privateKeyPathDesc": "Шлях до файлу приватного ключа для веб-панелі. (починається з ‘/‘)",
|
||
"panelUrlPath": "URI-шлях",
|
||
"panelUrlPathDesc": "Шлях URL для веб-панелі. (починається з ‘/‘ і закінчується ‘/‘)",
|
||
"pageSize": "Розмір сторінки",
|
||
"pageSizeDesc": "Визначити розмір сторінки для вхідної таблиці. (0 = вимкнено)",
|
||
"panelOutbound": "Вихідний для трафіку панелі",
|
||
"panelOutboundDesc": "Маршрутизує власні запити панелі — перевірки версій і завантаження панелі/Xray, Telegram та звичайне оновлення geo-файлів — через цей вихідний Xray для обходу фільтрації GitHub/Telegram на стороні сервера. Локальний міст-вхідний додається до робочої конфігурації автоматично і застосовується наживо. Вбудоване в Xray автооновлення Geodata не зачіпається; воно має власний вихідний для завантаження. Залиште порожнім для прямого підключення.",
|
||
"panelOutboundPh": "Пряме підключення",
|
||
"datepicker": "Тип календаря",
|
||
"datepickerPlaceholder": "Виберіть дату",
|
||
"datepickerDescription": "Заплановані завдання виконуватимуться на основі цього календаря.",
|
||
"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.",
|
||
"notifyTime": {
|
||
"every": "@every — повторювати з інтервалом",
|
||
"hourly": "@hourly — щогодини",
|
||
"daily": "@daily — щодня о 00:00",
|
||
"weekly": "@weekly — щотижня",
|
||
"monthly": "@monthly — щомісяця",
|
||
"custom": "Власний (crontab)",
|
||
"seconds": "Секунди",
|
||
"minutes": "Хвилини",
|
||
"hours": "Години"
|
||
},
|
||
"tgNotifyBackup": "Резервне копіювання бази даних",
|
||
"tgNotifyBackupDesc": "Надіслати файл резервної копії бази даних зі звітом.",
|
||
"tgNotifyLogin": "Сповіщення про вхід",
|
||
"tgNotifyLoginDesc": "Отримувати сповіщення про ім'я користувача, IP-адресу та час щоразу, коли хтось намагається увійти у вашу веб-панель.",
|
||
"sessionMaxAge": "Тривалість сеансу",
|
||
"sessionMaxAgeDesc": "Тривалість, протягом якої ви можете залишатися в системі. (одиниця: хвилина)",
|
||
"expireTimeDiff": "Повідомлення про дату закінчення",
|
||
"expireTimeDiffDesc": "Отримувати сповіщення про термін дії при досягненні цього порогу. (одиниця: день)",
|
||
"trafficDiff": "Повідомлення про обмеження трафіку",
|
||
"trafficDiffDesc": "Отримувати сповіщення про обмеження трафіку при досягненні цього порогу. (одиниця: ГБ)",
|
||
"tgNotifyCpu": "Сповіщення про завантаження ЦП",
|
||
"tgNotifyCpuDesc": "Отримувати сповіщення, якщо навантаження ЦП перевищує це порогове значення. (одиниця: %)",
|
||
"timeZone": "Часовий пояс",
|
||
"timeZoneDesc": "Заплановані завдання виконуватимуться на основі цього часового поясу.",
|
||
"subSettings": "Підписка",
|
||
"subEnable": "Увімкнути службу підписки",
|
||
"subEnableDesc": "Вмикає службу підписки.",
|
||
"subJsonEnable": "Увімкнути/вимкнути JSON-кінець підписки незалежно.",
|
||
"subJsonEnableTitle": "JSON-підписка",
|
||
"subClashEnableTitle": "Підписка Clash / Mihomo",
|
||
"subTitle": "Назва Підписки",
|
||
"subTitleDesc": "Назва, яка відображається у VPN-клієнті",
|
||
"subSupportUrl": "URL підтримки",
|
||
"subSupportUrlDesc": "Посилання на технічну підтримку, що відображається у VPN-клієнті",
|
||
"subProfileUrl": "URL профілю",
|
||
"subProfileUrlDesc": "Посилання на ваш вебсайт, що відображається у VPN-клієнті",
|
||
"subAnnounce": "Оголошення",
|
||
"subAnnounceDesc": "Текст оголошення, що відображається у VPN-клієнті",
|
||
"subThemeDir": "Каталог теми підписки",
|
||
"subThemeDirDesc": "Абсолютний шлях до теки з користувацьким шаблоном (index.html/sub.html) для сторінки підписки (наприклад, /etc/3x-ui/sub_templates/my-theme/). Залиште порожнім, щоб використовувати сторінку за замовчуванням.",
|
||
"subThemeDirDocs": "Посібник із шаблонів ↗",
|
||
"subEnableRouting": "Увімкнути маршрутизацію",
|
||
"subEnableRoutingDesc": "Глобальне налаштування для увімкнення маршрутизації у VPN-клієнті. (Тільки для Happ)",
|
||
"subRoutingRules": "Правила маршрутизації",
|
||
"subRoutingRulesDesc": "Глобальні правила маршрутизації для VPN-клієнта. (Тільки для Happ)",
|
||
"subClashEnableRouting": "Увімкнути маршрутизацію",
|
||
"subClashEnableRoutingDesc": "Додавати глобальні правила маршрутизації Clash/Mihomo до згенерованих YAML-підписок.",
|
||
"subClashRoutingRules": "Глобальні правила маршрутизації",
|
||
"subClashRoutingRulesDesc": "Правила Clash/Mihomo, що додаються на початок кожної YAML-підписки перед MATCH,PROXY.",
|
||
"subListen": "Слухати IP",
|
||
"subListenDesc": "IP-адреса для служби підписки. (залиште порожнім, щоб слухати всі IP-адреси)",
|
||
"subPort": "Слухати порт",
|
||
"subPortDesc": "Номер порту для служби підписки. (має бути невикористаний порт)",
|
||
"subCertPath": "Шлях відкритого ключа",
|
||
"subCertPathDesc": "Шлях до файлу відкритого ключа для служби підписки. (починається з ‘/‘)",
|
||
"subKeyPath": "Шлях приватного ключа",
|
||
"subKeyPathDesc": "Шлях до файлу приватного ключа для служби підписки. (починається з ‘/‘)",
|
||
"subPath": "URI-шлях",
|
||
"subPathDesc": "Шлях URI для служби підписки. (починається з ‘/‘ і закінчується ‘/‘)",
|
||
"subDomain": "Домен прослуховування",
|
||
"subDomainDesc": "Ім'я домену для служби підписки. (залиште порожнім, щоб слухати всі домени та IP-адреси)",
|
||
"subUpdates": "Інтервали оновлення",
|
||
"subUpdatesDesc": "Інтервали оновлення URL-адреси підписки в клієнтських програмах. (одиниця: година)",
|
||
"subEncrypt": "Кодувати",
|
||
"subEncryptDesc": "Повернений вміст послуги підписки матиме кодування Base64.",
|
||
"subURI": "URI зворотного проксі",
|
||
"subURIDesc": "URI до URL-адреси підписки для використання за проксі.",
|
||
"externalTrafficInformEnable": "Інформація про зовнішній трафік",
|
||
"externalTrafficInformEnableDesc": "Повідомляти зовнішній API про кожне оновлення трафіку.",
|
||
"externalTrafficInformURI": "Інформаційний URI зовнішнього трафіку",
|
||
"externalTrafficInformURIDesc": "Оновлення трафіку надсилаються на цей URI.",
|
||
"restartXrayOnClientDisable": "Перезапускати Xray після авто-вимкнення",
|
||
"restartXrayOnClientDisableDesc": "Коли клієнт автоматично вимикається через закінчення терміну дії або ліміт трафіку, перезапускати Xray.",
|
||
"fragment": "Фрагментація",
|
||
"fragmentDesc": "Увімкнути фрагментацію для пакету привітання TLS",
|
||
"fragmentSett": "Параметри фрагментації",
|
||
"noisesDesc": "Увімкнути Noises.",
|
||
"noisesSett": "Налаштування Noises",
|
||
"trustedProxyCidrs": "Довірені CIDR проксі",
|
||
"trustedProxyCidrsDesc": "IP/CIDR через кому, яким дозволено встановлювати заголовки forwarded host, proto та client IP.",
|
||
"ldap": {
|
||
"enable": "Увімкнути LDAP-синхронізацію",
|
||
"host": "LDAP-хост",
|
||
"port": "Порт LDAP",
|
||
"useTls": "Використовувати TLS (LDAPS)",
|
||
"bindDn": "Bind DN",
|
||
"passwordConfigured": "Налаштовано; залиште порожнім для збереження поточного паролю.",
|
||
"passwordUnconfigured": "Не налаштовано.",
|
||
"passwordPlaceholder": "Налаштовано — введіть нове значення для заміни",
|
||
"baseDn": "Base DN",
|
||
"userFilter": "Фільтр користувача",
|
||
"userAttr": "Атрибут користувача (username/email)",
|
||
"vlessField": "Атрибут VLESS-flag",
|
||
"flagField": "Загальний атрибут flag (опц.)",
|
||
"flagFieldDesc": "Якщо задано, перевизначає VLESS flag — напр. shadowInactive.",
|
||
"truthyValues": "Truthy-значення",
|
||
"truthyValuesDesc": "Через кому; за замовч.: true,1,yes,on",
|
||
"invertFlag": "Інвертувати flag",
|
||
"invertFlagDesc": "Увімкніть, коли атрибут означає «вимкнено» (напр. shadowInactive).",
|
||
"syncSchedule": "Розклад синхронізації",
|
||
"syncScheduleDesc": "Рядок типу cron, напр. @every 1m",
|
||
"inboundTags": "Теги вхідних",
|
||
"inboundTagsDesc": "Вхідні, на яких LDAP-синхронізація може авто-створювати або авто-видаляти клієнтів.",
|
||
"noInbounds": "Вхідних не знайдено. Спочатку створіть один у Вхідних.",
|
||
"autoCreate": "Авто-створення клієнтів",
|
||
"autoDelete": "Авто-видалення клієнтів",
|
||
"defaultTotalGb": "Обсяг за замовч. (ГБ)",
|
||
"defaultExpiryDays": "Термін за замовч. (дні)",
|
||
"defaultIpLimit": "Ліміт IP за замовч."
|
||
},
|
||
"subFormats": {
|
||
"finalMask": "Final Mask",
|
||
"finalMaskDesc": "Маски finalmask xray (TCP/UDP) і налаштування QUIC, що додаються до кожного потоку JSON-підписки. Потрібна свіжа версія xray на клієнті.",
|
||
"packets": "Пакети",
|
||
"length": "Довжина",
|
||
"interval": "Інтервал",
|
||
"maxSplit": "Макс. розбиття",
|
||
"noises": "Шуми",
|
||
"noiseItem": "Шум №{n}",
|
||
"type": "Тип",
|
||
"packet": "Пакет",
|
||
"delayMs": "Затримка (мс)",
|
||
"applyTo": "Застосувати до",
|
||
"addNoise": "+ Шум",
|
||
"concurrency": "Паралельність",
|
||
"xudpConcurrency": "Паралельність xudp",
|
||
"xudpUdp443": "xudp UDP 443"
|
||
},
|
||
"mux": "Mux",
|
||
"muxDesc": "Передавати кілька незалежних потоків даних у межах встановленого потоку даних.",
|
||
"muxSett": "Налаштування Mux",
|
||
"direct": "Пряме підключення",
|
||
"directDesc": "Безпосередньо встановлює з’єднання з доменами або діапазонами IP певної країни.",
|
||
"notifications": "Сповіщення",
|
||
"certs": "Сертифікати",
|
||
"externalTraffic": "Зовнішній трафік",
|
||
"dateAndTime": "Дата та час",
|
||
"proxyAndServer": "Проксі та сервер",
|
||
"intervals": "Інтервали",
|
||
"information": "Інформація",
|
||
"profile": "Профіль",
|
||
"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": "Будь-який клієнт, що використовує цей токен, негайно втратить автентифікацію.",
|
||
"apiTokenCreatedTitle": "Токен створено",
|
||
"apiTokenCreatedNotice": "Скопіюйте цей токен зараз. З міркувань безпеки він не зберігається у читабельному вигляді й більше не відображатиметься."
|
||
},
|
||
"toasts": {
|
||
"modifySettings": "Параметри було змінено.",
|
||
"getSettings": "Виникла помилка під час отримання параметрів.",
|
||
"modifyUserError": "Виникла помилка під час зміни облікових даних адміністратора.",
|
||
"modifyUser": "Ви успішно змінили облікові дані адміністратора.",
|
||
"originalUserPassIncorrect": "Поточне ім'я користувача або пароль недійсні",
|
||
"userPassMustBeNotEmpty": "Нове ім'я користувача та пароль порожні",
|
||
"getOutboundTrafficError": "Помилка отримання вихідного трафіку",
|
||
"resetOutboundTrafficError": "Помилка скидання вихідного трафіку"
|
||
},
|
||
"smtpSettings": "Налаштування SMTP",
|
||
"smtpEnable": "Увімкнути сповіщення електронною поштою",
|
||
"smtpEnableDesc": "Увімкнути сповіщення електронною поштою через SMTP",
|
||
"smtpHost": "Хост SMTP",
|
||
"smtpHostDesc": "Ім'я хоста сервера SMTP (наприклад, smtp.gmail.com)",
|
||
"smtpPort": "Порт SMTP",
|
||
"smtpPortDesc": "Порт сервера SMTP (типово: 587)",
|
||
"smtpUsername": "Ім'я користувача SMTP",
|
||
"smtpUsernameDesc": "Ім'я користувача для автентифікації SMTP",
|
||
"smtpPassword": "Пароль SMTP",
|
||
"smtpPasswordDesc": "Пароль для автентифікації SMTP",
|
||
"smtpTo": "Отримувачі",
|
||
"smtpToDesc": "Адреси електронної пошти отримувачів, розділені комами",
|
||
"emailSettings": "Електронна пошта",
|
||
"emailNotifications": "Сповіщення",
|
||
"smtpEventBusNotify": "Сповіщення про події електронною поштою",
|
||
"smtpEventBusNotifyDesc": "Виберіть, які події спричиняють сповіщення електронною поштою",
|
||
"tgEventBusNotify": "Сповіщення про події в Telegram",
|
||
"tgEventBusNotifyDesc": "Виберіть, які події спричиняють сповіщення в Telegram",
|
||
"testSmtp": "Надіслати тестовий лист",
|
||
"testTgBot": "Надіслати тестове повідомлення",
|
||
"eventGroupOutbound": "Вихідні з'єднання",
|
||
"eventGroupXray": "Ядро Xray",
|
||
"eventGroupSystem": "Система",
|
||
"eventGroupSecurity": "Безпека",
|
||
"eventGroupNode": "Вузли",
|
||
"eventOutboundDown": "Недоступне",
|
||
"eventOutboundUp": "Доступне",
|
||
"eventXrayCrash": "Збій",
|
||
"eventNodeDown": "Недоступний",
|
||
"eventNodeUp": "Доступний",
|
||
"eventCPUHigh": "Високе навантаження на CPU (%)",
|
||
"requestFailed": "Запит не вдалося виконати",
|
||
"smtpEncryption": "Шифрування",
|
||
"smtpEncryptionDesc": "Метод шифрування з'єднання SMTP",
|
||
"smtpEncryptionNone": "Немає (відкритий текст)",
|
||
"smtpEncryptionStartTLS": "STARTTLS",
|
||
"smtpEncryptionTLS": "TLS (неявне)",
|
||
"smtpStageConnect": "З'єднання",
|
||
"smtpStageAuth": "Автентифікація",
|
||
"smtpStageSend": "Надсилання",
|
||
"smtpTestSuccess": "Тестовий лист успішно надіслано",
|
||
"smtpHostNotConfigured": "Хост SMTP не налаштовано",
|
||
"smtpNoRecipients": "Отримувачів не налаштовано",
|
||
"eventLoginAttempt": "Спроба входу",
|
||
"telegramTokenConfigured": "Налаштовано; залиште порожнім, щоб зберегти поточний токен.",
|
||
"telegramTokenPlaceholder": "Налаштовано — введіть новий токен для заміни",
|
||
"smtpPasswordConfigured": "Налаштовано; залиште порожнім, щоб зберегти поточний пароль.",
|
||
"smtpPasswordPlaceholder": "Налаштовано — введіть новий пароль для заміни",
|
||
"smtpNotInitialized": "SMTP не ініціалізовано",
|
||
"tgBotNotEnabled": "Бот Telegram не увімкнено",
|
||
"tgTestFailed": "Тест Telegram не вдався",
|
||
"tgTestSuccess": "Тестове повідомлення надіслано в Telegram",
|
||
"tgBotNotRunning": "Бот Telegram не запущено",
|
||
"smtpErrorAuth": "Помилка автентифікації — перевірте ім'я користувача та пароль",
|
||
"smtpErrorStarttls": "Сервер вимагає STARTTLS — змініть тип шифрування",
|
||
"smtpErrorTls": "Сервер вимагає TLS — змініть тип шифрування",
|
||
"smtpErrorRefused": "У з'єднанні відмовлено — перевірте хост і порт",
|
||
"smtpErrorTimeout": "Час очікування з'єднання вичерпано — хост недоступний",
|
||
"smtpErrorRelay": "Сервер відхиляє надсилання з цієї адреси",
|
||
"smtpErrorEof": "З'єднання закрито сервером",
|
||
"smtpErrorUnknown": "Помилка SMTP: {{ .Error }}"
|
||
},
|
||
"xray": {
|
||
"title": "Xray конфігурації",
|
||
"save": "Зберегти",
|
||
"restart": "Перезапуск Xray",
|
||
"restartSuccess": "Xray успішно перезапущено",
|
||
"restartOutputTitle": "Вивід перезапуску Xray",
|
||
"restartConfirmTitle": "Перезапустити xray?",
|
||
"restartConfirmContent": "Перезавантажує сервіс 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": "Установити стратегію виведення для мережі в протоколі свободи.",
|
||
"FreedomHappyEyeballs": "Freedom Happy Eyeballs (IPv4/IPv6)",
|
||
"FreedomHappyEyeballsDesc": "Двостековий набір для прямого (freedom) вихідного — корисно на вихідних серверах із IPv4 та IPv6.",
|
||
"FreedomHappyEyeballsTryDelayDesc": "Мілісекунди перед спробою іншої родини адрес. 150–250 мс — добра початкова точка.",
|
||
"RoutingStrategy": "Загальна стратегія маршрутизації",
|
||
"RoutingStrategyDesc": "Установити загальну стратегію маршрутизації трафіку для вирішення всіх запитів.",
|
||
"outboundTestUrl": "URL тесту outbound",
|
||
"outboundTestUrlDesc": "URL для перевірки з'єднання outbound",
|
||
"Torrent": "Блокувати протокол BitTorrent",
|
||
"Inbounds": "Вхідні",
|
||
"InboundsDesc": "Прийняття певних клієнтів.",
|
||
"Outbounds": "Вихідні",
|
||
"OutboundSubscriptions": "Підписки вихідних",
|
||
"OutboundSubscriptionsDesc": "Імпортуйте вихідні з віддалених URL підписок (vmess/vless/trojan/ss/...). Теги залишаються стабільними для використання в балансувальниках і правилах маршрутизації. Оновлення відбувається автоматично.",
|
||
"Balancers": "Балансери",
|
||
"balancerTagRequired": "Тег обов'язковий",
|
||
"balancerSelectorRequired": "Виберіть принаймні один вихідний",
|
||
"balancerLive": "Поточна ціль",
|
||
"balancerOverride": "Примусова ціль",
|
||
"balancerOverridePh": "Авто (стратегія)",
|
||
"balancerLiveRefresh": "Оновити стан балансувальника",
|
||
"balancerNotRunning": "Цей балансувальник неактивний у запущеному Xray — збережіть зміни або спочатку запустіть Xray",
|
||
"routeTester": "Тест маршруту",
|
||
"routeTesterDesc": "Запитайте запущений Xray, через який вихідний буде оброблено з'єднання. Реальний трафік не надсилається — рішення надходить безпосередньо від живого рушія маршрутизації.",
|
||
"routeTesterDest": "Домен або IP",
|
||
"routeTesterPort": "Порт",
|
||
"routeTesterInbound": "Вхідний",
|
||
"routeTesterProtocol": "Виявлений протокол",
|
||
"routeTesterTest": "Тест маршруту",
|
||
"routeTesterMatchedOutbound": "Відповідний вихідний",
|
||
"routeTesterViaBalancer": "через балансувальник",
|
||
"routeTesterDefaultOutbound": "Жодне правило маршрутизації не збіглося — трафік надходить до вихідного за замовчуванням (першого).",
|
||
"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": "Увімкнення збору статистики для вихідного трафіку всіх вихідних проксі.",
|
||
"connectionLimits": "Обмеження з'єднання",
|
||
"connectionLimitsDesc": "Політики рівня з'єднання для користувачів рівня 0. Залиште поле порожнім, щоб використовувати значення Xray за замовчуванням.",
|
||
"connIdle": "Тайм-аут простою",
|
||
"connIdleDesc": "Закриває з'єднання після простою протягом вказаної кількості секунд. Зменшення значення швидше звільняє пам'ять і файлові дескриптори на завантажених серверах (за замовчуванням у Xray: 300).",
|
||
"bufferSize": "Розмір буфера",
|
||
"bufferSizeDesc": "Розмір внутрішнього буфера на з'єднання в КБ. Встановіть 0, щоб мінімізувати використання пам'яті на серверах з малим обсягом ОЗП (значення Xray за замовчуванням залежить від платформи).",
|
||
"bufferSizePlaceholder": "авто",
|
||
"seconds": "секунд",
|
||
"rules": {
|
||
"first": "Перший",
|
||
"last": "Останній",
|
||
"up": "Вгору",
|
||
"down": "Вниз",
|
||
"source": "Джерело",
|
||
"dest": "Пункт призначення",
|
||
"inbound": "Вхідний",
|
||
"outbound": "Вихідний",
|
||
"balancer": "Балансувальник",
|
||
"info": "Інфо",
|
||
"add": "Додати правило",
|
||
"edit": "Редагувати правило",
|
||
"useComma": "Елементи, розділені комами"
|
||
},
|
||
"routing": {
|
||
"dragToReorder": "Перетягніть для зміни порядку"
|
||
},
|
||
"ruleForm": {
|
||
"sourceIps": "IP джерела",
|
||
"sourcePort": "Порт джерела",
|
||
"vlessRoute": "VLESS route",
|
||
"attributes": "Атрибути",
|
||
"value": "Значення",
|
||
"user": "Користувач",
|
||
"inboundTags": "Теги вхідних",
|
||
"outboundTag": "Тег вихідного",
|
||
"balancerTag": "Тег балансувальника",
|
||
"balancerTagTooltip": "Спрямовує трафік через один з налаштованих балансувальників навантаження"
|
||
},
|
||
"outboundForm": {
|
||
"tagDuplicate": "Тег уже використовується іншим вихідним",
|
||
"tagRequired": "Тег обов'язковий",
|
||
"tagPlaceholder": "унікальний-тег",
|
||
"localIpPlaceholder": "локальний IP",
|
||
"dialerProxyPlaceholder": "Виберіть вихідний для ланцюжка",
|
||
"dialerProxyHint": "Підключайте цей вихідний через інший вихідний (за тегом), щоб побудувати ланцюжок проксі. Залиште порожнім для прямого підключення.",
|
||
"addressRequired": "Адреса обов'язкова",
|
||
"portRequired": "Порт обов'язковий",
|
||
"optional": "опційно",
|
||
"udpOverTcp": "UDP over TCP",
|
||
"uotVersion": "Версія UoT",
|
||
"inboundTag": "Тег вхідного",
|
||
"inboundTagPlaceholder": "тег вхідного у правилах маршрутизації",
|
||
"responseType": "Тип відповіді",
|
||
"rewriteNetwork": "Переписати мережу",
|
||
"unchanged": "(без змін)",
|
||
"unchangedAddress": "(без змін) напр. 1.1.1.1",
|
||
"rules": "Правила",
|
||
"ruleN": "Правило {n}",
|
||
"action": "Дія",
|
||
"redirect": "Redirect",
|
||
"fragment": "Fragment",
|
||
"finalRules": "Фінальні правила",
|
||
"overrideXrayPrivateIp": "Перевизначити дефолтний блок приватних IP у Xray",
|
||
"blockDelay": "Затримка блоку (мс)",
|
||
"reverseSniffing": "Зворотний sniffing",
|
||
"workers": "Воркери",
|
||
"reserved": "Зарезервовано",
|
||
"minUploadInterval": "Мін. інтервал завантаження (мс)",
|
||
"maxUploadSizeBytes": "Макс. розмір завантаження (байт)",
|
||
"uplinkChunkSize": "Розмір chunk Uplink",
|
||
"noGrpcHeader": "Без gRPC-заголовка",
|
||
"maxConcurrency": "Макс. паралельність",
|
||
"maxConnections": "Макс. з'єднань",
|
||
"maxReuseTimes": "Макс. повторних використань",
|
||
"maxRequestTimes": "Макс. запитів",
|
||
"maxReusableSecs": "Макс. секунд повторного використання",
|
||
"keepAlivePeriod": "Період keep alive",
|
||
"authPassword": "Пароль авторизації",
|
||
"visionTestpre": "Vision testpre",
|
||
"serverNamePlaceholder": "ім'я сервера",
|
||
"verifyPeerName": "Перевіряти ім'я peer",
|
||
"pinnedSha256": "Pinned SHA256",
|
||
"shortId": "Short ID",
|
||
"sockopts": "Sockopts",
|
||
"keepAliveInterval": "Інтервал keep alive",
|
||
"markFwmark": "Mark (fwmark)",
|
||
"interface": "Інтерфейс",
|
||
"ipv6Only": "Лише IPv6",
|
||
"acceptProxyProtocol": "Приймати proxy protocol",
|
||
"proxyProtocol": "Proxy protocol",
|
||
"tcpUserTimeoutMs": "TCP user timeout (мс)",
|
||
"tcpKeepAliveIdleS": "TCP keep-alive idle (с)"
|
||
},
|
||
"outbound": {
|
||
"addOutbound": "Додати вихідний",
|
||
"addReverse": "Додати реверс",
|
||
"editOutbound": "Редагувати вихідні",
|
||
"editReverse": "Редагувати реверс",
|
||
"reverseTag": "Тег реверс-проксі",
|
||
"reverseTagDesc": "Тег вихідного з'єднання для простого реверс-проксі VLESS. Залиште порожнім для вимкнення.",
|
||
"reverseTagPlaceholder": "тег вихідного (порожнє = вимкнено)",
|
||
"tag": "Тег",
|
||
"tagDesc": "Унікальний тег",
|
||
"address": "Адреса",
|
||
"reverse": "Зворотний",
|
||
"domain": "Домен",
|
||
"type": "Тип",
|
||
"bridge": "Bridge",
|
||
"portal": "Portal",
|
||
"link": "Посилання",
|
||
"intercon": "Взаємозв'язок",
|
||
"settings": "Налаштування",
|
||
"accountInfo": "Інформація про обліковий запис",
|
||
"outboundStatus": "Статус виходу",
|
||
"sendThrough": "Надіслати через",
|
||
"test": "Тест",
|
||
"testResult": "Результат тесту",
|
||
"testing": "Тестування з'єднання...",
|
||
"testSuccess": "Тест успішний",
|
||
"testFailed": "Тест не пройдено",
|
||
"testError": "Не вдалося протестувати вихідне з'єднання",
|
||
"testModeTooltip": "TCP: швидкий dial-only probe. HTTP: повний запит через xray.",
|
||
"testAll": "Тестувати всі",
|
||
"httpStatus": "HTTP-статус",
|
||
"breakdownConnect": "Підключення до проксі",
|
||
"breakdownTls": "TLS через вихідний",
|
||
"breakdownTtfb": "Перший байт",
|
||
"nordvpn": "NordVPN",
|
||
"accessToken": "Токен доступу",
|
||
"country": "Країна",
|
||
"server": "Сервер",
|
||
"city": "Місто",
|
||
"allCities": "Усі міста",
|
||
"privateKey": "Приватний ключ",
|
||
"load": "Навантаження"
|
||
},
|
||
"outboundSub": {
|
||
"manage": "Підписки",
|
||
"title": "Підписки вихідних",
|
||
"remark": "Примітка (необов'язково)",
|
||
"remarkPlaceholder": "напр. вузли HK",
|
||
"url": "URL підписки",
|
||
"urlPlaceholder": "https://... (список посилань у base64)",
|
||
"tagPrefix": "Префікс тегу",
|
||
"tagPrefixPlaceholder": "hk-",
|
||
"interval": "Інтервал оновлення",
|
||
"hours": "год",
|
||
"minutes": "хв",
|
||
"intervalHint": "За замовчуванням 10 хвилин. Фонове завдання перевіряє часто; кожна підписка повторно завантажується лише після того, як мине її власний інтервал.",
|
||
"enabled": "Увімкнено",
|
||
"allowPrivate": "Дозволити приватні адреси",
|
||
"allowPrivateHint": "Дозволити localhost / LAN / приватні IP-адреси для URL цієї підписки. З міркувань безпеки вимкнено за замовчуванням — вмикайте лише для довіреного локального джерела.",
|
||
"prepend": "Перед ручними вихідними",
|
||
"prependHint": "Розмістити вихідні цієї підписки перед вашими ручними, щоб один із них міг стати типовим.",
|
||
"preview": "Попередній перегляд",
|
||
"previewEmpty": "За цим URL вихідних не знайдено.",
|
||
"refreshAll": "Оновити всі",
|
||
"statusOk": "OK",
|
||
"toastUpdated": "Підписку оновлено",
|
||
"addButton": "Додати",
|
||
"active": "Активні підписки",
|
||
"empty": "Підписок поки немає. Додайте одну вище.",
|
||
"colRemark": "Примітка",
|
||
"colPrefix": "Префікс",
|
||
"colInterval": "Інтервал",
|
||
"colLastFetch": "Останнє завантаження",
|
||
"colEnabled": "Увімкнено",
|
||
"auto": "авто",
|
||
"never": "ніколи",
|
||
"yes": "Так",
|
||
"no": "Ні",
|
||
"refreshNow": "Оновити зараз",
|
||
"lastError": "Остання помилка",
|
||
"deleteConfirm": "Видалити цю підписку?",
|
||
"restartHint": "Після додавання або оновлення перезапустіть Xray (або зачекайте наступного автоматичного перезавантаження), щоб вихідні стали активними.",
|
||
"fromSubsTitle": "З підписок вихідних (лише для читання)",
|
||
"fromSubsDesc": "Імпортовано з ваших активних підписок. Керуйте ними на панелі «Підписки» вище.",
|
||
"toastLoadFailed": "Не вдалося завантажити підписки",
|
||
"toastUrlRequired": "Потрібен URL підписки",
|
||
"toastAdded": "Підписку додано",
|
||
"toastAddFailed": "Не вдалося додати підписку",
|
||
"toastRefreshed": "Оновлено",
|
||
"toastRefreshFailed": "Не вдалося оновити",
|
||
"toastDeleted": "Видалено",
|
||
"toastDeleteFailed": "Не вдалося видалити"
|
||
},
|
||
"balancer": {
|
||
"addBalancer": "Додати балансир",
|
||
"editBalancer": "Редагувати балансир",
|
||
"balancerStrategy": "Стратегія",
|
||
"balancerSelectors": "Селектори",
|
||
"tag": "Тег",
|
||
"tagDesc": "Унікальний тег",
|
||
"tagDuplicate": "Тег уже використовується іншим балансувальником",
|
||
"tagPlaceholder": "унікальний тег балансувальника",
|
||
"selector": "Селектор",
|
||
"fallback": "Fallback",
|
||
"expected": "Очікуване",
|
||
"expectedPlaceholder": "оптимальна кількість вузлів",
|
||
"maxRtt": "Макс. RTT",
|
||
"tolerance": "Допуск",
|
||
"baselines": "Baselines",
|
||
"costs": "Costs",
|
||
"balancerDesc": "Неможливо використовувати balancerTag і outboundTag одночасно. Якщо використовувати одночасно, працюватиме лише outboundTag."
|
||
},
|
||
"wireguard": {
|
||
"secretKey": "Приватний ключ",
|
||
"publicKey": "Публічний ключ",
|
||
"allowedIPs": "Дозволені IP-адреси",
|
||
"endpoint": "Кінцева точка",
|
||
"psk": "Спільний ключ",
|
||
"domainStrategy": "Стратегія домену"
|
||
},
|
||
"tun": {
|
||
"nameDesc": "Назва інтерфейсу TUN. Значення за замовчуванням - 'xray0'",
|
||
"mtuDesc": "Максимальна одиниця передачі. Максимальний розмір пакетів даних. Значення за замовчуванням - 1500",
|
||
"userLevel": "Рівень користувача",
|
||
"userLevelDesc": "Всі з'єднання, встановлені через цей вхід, використовуватимуть цей рівень користувача. Значення за замовчуванням - 0"
|
||
},
|
||
"nord": {
|
||
"accessToken": "Access token",
|
||
"privateKey": "Приватний ключ",
|
||
"noServers": "Серверів для обраної країни не знайдено",
|
||
"noPublicKey": "Обраний сервер не повідомляє публічного ключа NordLynx.",
|
||
"outboundAdded": "Вихідний NordVPN додано",
|
||
"outboundUpdated": "Вихідний NordVPN оновлено"
|
||
},
|
||
"warp": {
|
||
"changeIp": "Змінити IP",
|
||
"changeIpSuccess": "IP-адресу WARP успішно змінено!",
|
||
"autoUpdateIp": "Автоматичне оновлення IP-адреси",
|
||
"intervalDays": "Інтервал (дні)",
|
||
"intervalDesc": "0 — вимкнути. Автоматично змінює IP-адресу.",
|
||
"licenseError": "Не вдалося встановити ліцензію WARP.",
|
||
"fetchFirst": "Спочатку отримайте WARP-конфіг.",
|
||
"createAccount": "Створити акаунт WARP",
|
||
"accessToken": "Access token",
|
||
"deviceId": "ID пристрою",
|
||
"licenseKey": "Ключ ліцензії",
|
||
"privateKey": "Приватний ключ",
|
||
"deleteAccount": "Видалити акаунт",
|
||
"settings": "Налаштування",
|
||
"licenseKeyLabel": "Ключ ліцензії WARP / WARP+",
|
||
"key": "Ключ",
|
||
"keyPlaceholder": "26-символьний ключ WARP+",
|
||
"accountInfo": "Інформація про акаунт",
|
||
"deviceName": "Назва пристрою",
|
||
"deviceModel": "Модель пристрою",
|
||
"deviceEnabled": "Пристрій увімкнено",
|
||
"accountType": "Тип акаунта",
|
||
"role": "Роль",
|
||
"warpPlusData": "WARP+ data",
|
||
"quota": "Квота",
|
||
"usage": "Використання",
|
||
"addOutbound": "Додати вихідний"
|
||
},
|
||
"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": "📍 Вхідний: {{ .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: {{ .Email }}\r\n",
|
||
"upload": "🔼 Завантаження: ↑{{ .Upload }}\r\n",
|
||
"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": "🔚 Процес скидання трафіку завершено для всіх клієнтів.",
|
||
"eventOutboundDown": "Вихідне з'єднання {{ .Tag }} НЕДОСТУПНЕ",
|
||
"eventOutboundUp": "Вихідне з'єднання {{ .Tag }} ДОСТУПНЕ",
|
||
"eventErrorDetail": "Помилка: {{ .Error }}",
|
||
"eventDelayDetail": "Затримка: {{ .Delay }} мс",
|
||
"eventXrayCrash": "Стався збій Xray",
|
||
"eventXrayCrashError": "Помилка: {{ .Error }}",
|
||
"eventNodeDown": "Вузол {{ .Name }} НЕДОСТУПНИЙ",
|
||
"eventNodeUp": "Вузол {{ .Name }} ДОСТУПНИЙ",
|
||
"eventCPUHigh": "Високе навантаження на CPU",
|
||
"eventCPUHighDetail": "CPU: {{ .Detail }}",
|
||
"eventLoginFallback": "Невдала спроба входу з {{ .Source }}"
|
||
},
|
||
"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": "🔢 Своє",
|
||
"confirmNumber": "✅ Підтвердити: {{ .Num }}",
|
||
"confirmNumberAdd": "✅ Підтвердити додавання: {{ .Num }}",
|
||
"limitTraffic": "🚧 Ліміт трафіку",
|
||
"getBanLogs": "Отримати журнали заборон",
|
||
"allClients": "Всі Клієнти",
|
||
"addClient": "Додати клієнта",
|
||
"submitDisable": "Надіслати як вимкнено ☑️",
|
||
"submitEnable": "Надіслати як увімкнено ✅",
|
||
"use_default": "🏷️ Використати типове",
|
||
"change_id": "⚙️🔑 ID",
|
||
"change_password": "⚙️🔑 Пароль",
|
||
"change_email": "⚙️📧 Email",
|
||
"change_comment": "⚙️💬 Коментар",
|
||
"change_flow": "⚙️🚦 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": "Виберіть Вхідний"
|
||
}
|
||
},
|
||
"email": {
|
||
"subjectOutboundDown": "Вихідне з'єднання {{ .Tag }} НЕДОСТУПНЕ",
|
||
"subjectOutboundUp": "Вихідне з'єднання {{ .Tag }} ДОСТУПНЕ",
|
||
"subjectXrayCrash": "Стався збій Xray",
|
||
"subjectCPUHigh": "Високе навантаження на CPU",
|
||
"subjectLoginSuccess": "Успішний вхід",
|
||
"subjectLoginFailed": "Невдалий вхід",
|
||
"titleOutboundDown": "Вихідне з'єднання НЕДОСТУПНЕ",
|
||
"titleOutboundUp": "Вихідне з'єднання ДОСТУПНЕ",
|
||
"titleXrayCrash": "Стався збій Xray",
|
||
"titleCPUHigh": "Високе навантаження на CPU",
|
||
"titleLoginSuccess": "Успішний вхід",
|
||
"titleLoginFailed": "Невдалий вхід",
|
||
"labelStatus": "Статус",
|
||
"labelOutbound": "Вихідне з'єднання",
|
||
"labelNode": "Вузол",
|
||
"labelError": "Помилка",
|
||
"labelDelay": "Затримка",
|
||
"labelDetail": "Деталі",
|
||
"labelUsername": "Ім'я користувача",
|
||
"labelIP": "IP",
|
||
"labelReason": "Причина",
|
||
"labelSource": "Джерело",
|
||
"labelTime": "Час",
|
||
"statusCrashed": "ЗБІЙ",
|
||
"statusRunning": "Працює",
|
||
"statusHigh": "ВИСОКЕ",
|
||
"statusSuccess": "УСПІШНО",
|
||
"statusFailed": "НЕВДАЛО",
|
||
"statusDown": "НЕДОСТУПНО",
|
||
"statusUp": "ДОСТУПНО"
|
||
}
|
||
} |