Files
3x-ui/internal/web/translation/fa-IR.json
T
Sanaei 5e1cb7693b Repo-wide self-correcting audit: 54 verified bug fixes (#5970)
* fix(email): resolve a name-addr smtpFrom into bare envelope address and display name

The save-time validator accepts any RFC 5322 address form, so a value
like '3x-ui Panel <panel(at)example.com>' passes validation, but Send and
TestConnection fed that raw string to MAIL FROM, which strict servers
reject with 501, and buildMessage mangled it into a quoted local part.
Parse the configured sender at the point of use: the envelope gets the
bare address and, when no explicit sender name is set, the display name
embedded in the setting is used for the From header.

* fix(email): report a missing sender address from the SMTP connection test

TestConnection skipped the empty-from guard that Send enforces, so with
no sender and no username configured the test issued the null reverse-path
and could report success against a lenient relay while every real
notification send kept failing with the missing-sender error. Guard the
test path the same way and surface a dedicated translated message.

* fix(sub): fall back to the raw subscription when an auto-detected format has no content

With format auto-detection enabled, a client whose User-Agent matched the
Clash or JSON regex was routed straight to that format handler. For a
subscription whose entries convert to neither format (an MTProto-only
subscription, for example) the handler returns an empty document and the
request ended as 404, breaking a URL that served the raw list before the
toggle. The auto-detect branches now serve the detected format only when
it produces content and otherwise continue to the raw response; the
explicit format endpoints keep answering 404 for empty documents.

* fix(node): match prefixed central tags when filtering a selected-mode node snapshot

FilterNodeSnapshot compared a node snapshot's inbound tags against the
raw selected-tag list with an exact match, while its two siblings
(SnapshotHasUnadoptedInbounds and the reconcile tagToCentral map) expand
each selected tag to both its bare node-side form and its n<id>- prefixed
central form. A panel-created node inbound is recorded in the selected
list under the central prefixed tag but reported by the node under the
bare tag, so the exact match dropped it from every snapshot and the
orphan sweep then deleted its central row one tick after creation. Expand
the allowed set with the same prefix flip the siblings use.

* fix(client): refuse a bulk quota reduction that would fall to or below zero

BulkAdjust clamped a client's new traffic limit with max(total+addBytes, 0).
Because 0 is the unlimited sentinel, reducing a client's quota by more than
it had left silently granted that client unlimited traffic. The sibling
expiry branch already refuses an over-reduction; mirror it for quota so the
adjustment is skipped with a clear reason instead of crossing the sentinel.

* fix(client): persist a bulk adjustment's applied field even when the sibling field is skipped

In a mixed BulkAdjust (both a days delta and a bytes delta), a per-field
planning skip such as "unlimited expiry" or "unlimited traffic" was recorded
in the same map that gated the client_traffics write. The applied field was
already written to the inbound JSON and the clients table, but the enforcement
row was left untouched, so the depletion job cut the client on the old limit
while the panel showed the new one. Gate the traffic-row write on an actual
inbound-processing failure rather than on any planning-phase skip note.

* fix(inbound): always create in AddInbound instead of overwriting a row whose id was posted

The add controller binds the inbound model's id form field and never clears
it, and AddInbound persisted with GORM Save, which updates in place when the
primary key is non-zero. A client that reused an existing id (for instance by
duplicating an inbound fetched from /get and changing the port) silently
overwrote that stored row instead of creating a new inbound. Zero the id at
the top of AddInbound, matching how it already zeroes the client-stat ids.

* fix(inbound): accept WireGuard clients when creating an inbound

AddInbound's per-client validation switch had cases for every protocol
except WireGuard, so a WireGuard client fell through to the default branch
that requires a non-empty id. WireGuard clients are keyed by their public
key and carry no id, so importing a WireGuard inbound or re-adding one to a
reconciling node was rejected with "empty client ID". Add a wireguard case
that validates the client key, mirroring addInboundClient.

* fix(client): stop holding the inbound-lock registry mutex while waiting on one inbound

lockInbound acquired the global registry mutex and then blocked on the
per-inbound mutex without releasing the registry first. A slow client
operation holding one inbound's mutex (for example a bulk delete pushing to
an unreachable node) made the next waiter park on that inbound while still
holding the registry mutex, which in turn blocked lockInbound for every
other inbound — freezing client mutations panel-wide. Release the registry
mutex before taking the per-inbound lock.

* fix(client): honor keepTraffic when deleting a client that is attached to inbounds

Delete, DeleteByEmail and BulkDelete all pass keepTraffic to their final
cleanup transaction, but each called the per-inbound delete helper with a
hardcoded false. That helper purges the client's traffic, IP and stat rows
before the gated cleanup runs, so keepTraffic=true still destroyed all
traffic history for any client actually attached to an inbound (the pinned
test only covered a record with no inbound mappings). Thread the caller's
keepTraffic through to the per-inbound helper at all three call sites.

* fix(inbound): defer a local MTProto inbound edit's sidecar push until after commit

UpdateInbound applied a local MTProto inbound change by calling the runtime
UpdateInbound (which stops/starts the mtg sidecar or talks to it) from inside
runSerializedTx. That runs process and network I/O on the single traffic-writer
goroutine while a DB transaction is open, so a slow sidecar stalls traffic
accounting and every concurrent client mutation, and a later step failing the
transaction leaves the sidecar ahead of the rolled-back row. Move the push into
the post-commit hook, matching the xray branch. Adds a SetLocalRuntimeOverride
test seam mirroring the existing node override so the deferral is regression
tested.

* fix(client): delete external-link rows when bulk-deleting clients

The single-client Delete path removes a client's client_external_links rows,
but BulkDelete (and the DelDepleted reaper that routes through it) deleted the
record, mappings and traffic while leaving the external-link rows keyed by the
now-dead client id, so they accumulated as orphans. Delete them in the same
cleanup transaction, keyed by client id like the single path.

* fix(inbound): request an xray restart when toggling a routed MTProto inbound

AddInbound, DelInbound and UpdateInbound all flag needRestart when an inbound
routes MTProto through xray, so the egress SOCKS bridge is regenerated. Only
SetInboundEnable's local path omitted it, so toggling a routed MTProto inbound
off then on left the bridge out of the running config while the sidecar dialed
its loopback port, blackholing that inbound until an unrelated restart. Flag the
restart on the local enable path too.

* fix(client): apply enable-by-email to every inbound a client is attached to

ToggleClientEnableByEmail (Telegram bot) and SetClientEnableByEmail (LDAP sync)
resolved a single inbound via the legacy client_traffics pointer and flipped
enable only there. A client attached to several inbounds kept connecting through
the siblings' running Xray after being disabled, and the next edit could
re-enable it everywhere from a stale sibling. Route both through the
applyClientFieldByEmail fan-out (the #5039 fix path) so the whole multi-inbound
identity is toggled at once, dropping the circular Set/Toggle dependency.

* fix(traffic): commit a traffic tick even when a best-effort maintenance helper fails

addTrafficLocked stages the inbound and client deltas, then runs three helpers
(auto-renew, disable depleted clients, disable depleted inbounds) that are meant
to log and continue. All three reused the function-scope err that the deferred
commit/rollback inspects, so the last helper's error decided the whole tick: a
failure in disableInvalidInbounds rolled back the already-staged traffic while
AddTraffic reported success, and because xray had already advanced its counter
baseline that traffic was lost for good. Give each best-effort helper its own
error variable so only a genuine staging failure rolls the tick back.

* fix(traffic): re-enable clients and serialize the write in Reset All Client Traffic

ClientService.ResetAllTraffics zeroed up/down but, unlike every sibling reset
path, never restored enable=true, so clients that had been auto-disabled for
exceeding their quota stayed cut with zero usage after a reset. It also wrote
client_traffics directly on the shared DB handle instead of through the serial
traffic writer, reintroducing the cross-transaction lock-order deadlock the
writer exists to prevent. Restore enable and run the reset inside
submitTrafficWrite within one transaction.

* fix(traffic): keep node reset propagation out of the serial traffic writer

ResetAllTraffics and ResetInboundTraffic performed their remote-node reset HTTP
calls inside submitTrafficWrite. Each call can block up to the remote timeout,
and Reset All Traffics loops every node serially, so the single traffic-writer
goroutine was held for seconds — long enough that the concurrent 5s traffic poll
timed out submitting its own write and dropped the deltas it had already drained
from xray. Do the DB reset inside the writer, then propagate to the nodes after
it returns, matching how the mtproto quota reset is already sequenced.

* fix(sub): stop the subscription from 500ing on valid-but-unusual stream settings

The raw share-link generators used unchecked type assertions and unguarded
array indexing: an empty Reality shortIds/serverNames array (random.Num(0)
panics), a tcp-http header with no request block or an empty request.path, a
grpc block missing its keys, empty stream settings, and a non-string Host
header all panicked mid-generation. Because getSubs loops every client's link
with no recover, one such client 500s the entire subscription for everyone. The
sibling JSON, Clash and frontend generators already guard these; make the raw
generators match with comma-ok assertions and length checks.

* fix(sub): tolerate a hysteria inbound without hysteriaSettings in the JSON subscription

genHy asserted stream["hysteriaSettings"].(map[string]any) without the comma-ok
form, so a hysteria inbound whose StreamSettings omit the hysteriaSettings key
(a valid, representable shape the raw generator renders fine) panicked and 500ed
the entire JSON subscription. Use comma-ok; the downstream reads already guard
each key, so a nil map degrades gracefully.

* fix(sub): emit the pinned peer cert sha256 in Clash subscriptions

The Clash stream builder computed tlsSettings["pin-sha256"] from the inbound's
pinnedPeerCertSha256, but applySecurity's tls case never copied it onto the
proxy, so it was written with no reader and silently dropped. Clash subscribers
lost certificate pinning while JSON subscribers kept it. Surface pin-sha256 on
the proxy in the tls case, matching the JSON emitter.

* fix(link): parse the snake_case and extra-blob xhttp fields when importing a share link

The panel's share-link emitters (Go and TS) carry advanced xhttp knobs as a
snake_case x_padding_bytes plus an extra=<json> payload, but the Go parser's
xhttp branch read only top-level camelCase params, so importing an xhttp link
via the outbound-subscription feature dropped xPaddingBytes, scMaxEachPostBytes
and the rest, silently reverting them to the stream defaults and producing a
non-working outbound. Mirror the TS parser: read the snake_case alias, merge the
extra JSON blob, then let explicit camelCase params win.

* fix(frontend): decode URL-safe base64 when parsing an imported share link

Base64.decode called window.atob directly, which rejects the base64url
alphabet (- and _) and unpadded input. But the panel's own share-link emitter
uses Base64.encode(x, true) (URL-safe, unpadded), and real SIP002 links do too,
so importing a Shadowsocks link whose method:password encodes with a - or _ threw,
fell back to the raw undecoded string, and produced a wrong method and garbage
password (the vmess parser shared the same limitation). Normalize base64url and
re-pad before atob so decode round-trips every emitted link.

* fix(link): honor the vmess ws path and hysteria2 vcn params on import

Two Go/TS parser parity gaps in the outbound share-link import path: parseVmess
only applied a ws link's path when the inner JSON also carried a host key, so a
generator that omits host dropped the path back to the default; and parseHysteria2
hardcoded verifyPeerCertByName to empty, ignoring the vcn param the panel emits,
so a hysteria2 outbound with a decoy SNI and a distinct cert name failed TLS
verification after import. The TS parser handles both; make the Go parser match.

* fix(ui): stop the sniffing form island from clobbering unrendered fields

antd's Form.useWatch only reports registered fields, so while the
sniffing toggle was off the island emitted { enabled: false } upward and
replaced the full Sniffing object in form state. Saving a VLESS reverse
outbound then crashed in sniffingToWire on the missing ipsExcluded
array; the loopback outbound and the inbound sniffing tab shared the
same hole. Watch the store with preserve: true so unrendered fields
keep their values, and seed a missing value from the schema defaults
instead of an empty cast.

* fix(sub): drop empty remark segments instead of leaving a stray separator

expandSegment dropped a "|" segment only when its tokens rendered the unlimited
mark, so a segment whose only token resolved to the empty string (a client with
no comment, an unlimited client's expiry date) was kept as bare decoration,
leaving a trailing "|" or a dangling emoji on every share link's remark. Drop a
token-bearing segment whenever none of its tokens produce a real value, while
still keeping pure-literal segments.

* fix(xray): keep source- and domains-scoped routing rules when an inbound is deleted

removeInboundTagFromRules drops a routing rule whose inboundTag list becomes
empty only if the rule has no other matcher, but routingMatcherKeys omitted
xray-core's canonical source and domains keys. A rule scoped by source or domains
(common in hand-authored or imported configs) therefore lost its whole body —
including a security-relevant block — when its single listed inbound was deleted,
instead of just having the tag trimmed. Recognize source and domains as live
matchers.

* fix(xray): guard RemoveUser against an uninitialized handler client

Every XrayAPI handler method returns an error when HandlerServiceClient is nil,
except RemoveUser, which dereferenced it directly. A depletion sweep runs Init
with the port ignored and, during a restart window where the fresh process's
api port is still 0, Init fails and leaves the client nil — so RemoveUser
panicked (recovered by the traffic writer, but re-thrown every poll) instead of
returning an error. Add the same nil guard the siblings have.

* fix(xray): do not revive a manually stopped Xray on a background restart

RestartXray cleared isManuallyStopped unconditionally at its top, so the @30s
pending-config cron (and warp/ldap/outbound reconcile jobs) that call
RestartXray(false) resurrected an Xray the admin had deliberately stopped —
unlike the crash-detector, which honors the manual-stop flag. Skip a non-forced
restart while the stop flag is set; only an explicit forced restart clears it.

* fix(xray): retry a failed pending-restart instead of dropping the config change

The 30s cron consumed the need-restart flag with IsNeedRestartAndSetFalse before
calling RestartXray and only logged a failure. If RestartXray failed early (a
transient GetXrayConfig DB error) the old process kept running the old config,
the crash detector saw a running process and never retried, and the flag stayed
cleared — so an admin's saved change silently never reached the core. Move the
consume/restart/retry into ApplyPendingRestart, which re-arms the flag on
failure so the next tick retries.

* fix(xray): synchronize the process version and apiPort fields

Start writes p.version and p.apiPort (via refreshVersion/refreshAPIPort) after
flipping the process to running, while GetXrayVersion and GetAPIPort read them
lock-free from the status and traffic poll goroutines. The struct mutex
deliberately excluded these fields, so a restart racing a poll was a real data
race — a torn read of the version string header can crash. Extend the mutex to
cover version and apiPort, doing the blocking version probe before taking the
lock.

* fix(settings): detect a wildcard listen collision between the web and sub ports

The web/sub same-port check compared the two listen addresses as raw strings, so
binding both on all interfaces with different spellings (webListen 0.0.0.0 vs an
empty subListen) slipped past validation and only failed at startup with an
opaque bind error. Treat any wildcard listen ('', 0.0.0.0, ::) as overlapping so
the clash is reported up front, while still allowing two distinct specific
addresses to share a port.

* fix(db): mark the IP-limit cleanup seeder done on a fresh install

ResetIpLimitNoFail2ban is a one-time migration that, on a host without fail2ban,
zeroes every existing client's limitIp because the limit can't be enforced. It
was missing from the fresh-install fast-path seeder list, so on a brand-new DB it
did not run on the first boot but fired on the second — wiping any IP limits the
admin had set in between. Add it to the fast-path so a truly fresh install marks
it done up front (there is nothing to clean), leaving later admin-set limits
intact.

* fix(security): dial outbound subscriptions through the SSRF guard

The outbound-subscription fetch validated the URL host once (resolving DNS and
rejecting private targets) but then fetched with a plain HTTP client that
re-resolves the host at dial time, so a subscription domain the attacker controls
could pass validation as a public IP and rebind to 127.0.0.1 / a cloud metadata
endpoint / an internal host for the actual dial — a blind SSRF into the panel's
network. Route the direct fetch (and its redirects) through
netsafe.SSRFGuardedDialContext, which resolves, checks and dials the same IP
atomically, carrying the subscription's AllowPrivate flag on the request context;
a configured egress proxy still dials its loopback bridge unguarded.

* fix(security): bound the login-limiter attempts map

The login rate limiter keys its records on the caller-supplied username and only
evicted a record when that exact key was revisited or the login succeeded. An
unauthenticated attacker replaying one CSRF token while rotating a fresh username
per request seeded a record that was never revisited, growing the map without
bound until the panel OOMs. Cap the map: before inserting a new record, reclaim
records whose block has lapsed and whose failures aged out, and if the map is
still at the ceiling under a broad flood, drop one so memory can never grow past
the cap.

* fix(tgbot): require admin for privileged callbacks, not just the first switch

answerCallback wraps only its first callback switch in an isAdmin guard; the
second switch (server usage, inbound/online enumeration, database backup export,
ban logs, mass traffic reset, client creation) ran for every caller. Telegram
delivers a callback with the tapping user's id, so a non-admin who can see an
admin's inline keyboard — as when the bot runs in a group — could tap Backup and
receive the full database and config, or reset all traffic. Default-deny before
the second switch: a non-admin may only run the per-user client_* callbacks that
resolve their own data from their Telegram id.

* fix(eventbus): dispatch each subscriber in its own goroutine

The fan-out loop called every subscriber's handler sequentially on the
single dispatch goroutine. The email and Telegram notifiers block on
network I/O for tens of seconds (or minutes when the remote is slow), so
one slow subscriber stalled the whole loop: the 256-slot channel then
filled and Publish silently dropped later events — including high-value
xray.crash and node.down notifications unrelated to the slow handler.

Hand each delivered event to every handler in its own goroutine so a
blocking subscriber can no longer stall delivery to the others. safeCall
already recovers panics, so a detached handler cannot take down the bus.

* fix(integration): cap WARP API response body size

doWarpRequest read the response with an unbounded io.ReadAll, unlike the
sibling NordVPN client which already caps every read at maxResponseSize.
A hostile panel egress proxy or a MITM on the Cloudflare WARP endpoint
could stream an arbitrarily large body and force the panel into an
unbounded allocation. Wrap the body in an io.LimitReader(maxResponseSize)
to match the NordVPN client.

* fix(email): bound every SMTP step with a connection deadline

The "starttls"/"none" transport delivered through net/smtp.SendMail, which
dials with an untimed net.Dial and never sets a socket deadline. When an
SMTP server accepted the TCP connection but then stalled (or was a
blackhole), the caller was released by Send's 30s select, but the sender
goroutine and its socket stayed blocked until the OS TCP timeout — minutes
per notification, leaking a goroutine and a connection each time.
sendWithTLS dialed with a timeout but likewise armed no deadline on the
protocol phase, and TestConnection (called synchronously from the settings
handler, with no select guard) could hang the request indefinitely.

Replace SendMail with sendPlain, which dials with smtpConnectTimeout and
arms conn.SetDeadline(smtpDeadline) before the greeting read, preserving
SendMail's opportunistic STARTTLS upgrade. Arm the same deadline in
sendWithTLS and TestConnection so every SMTP step is bounded.

* fix(server): guard access-log parser against malformed lines

GetXrayLogs split each Xray access-log line on whitespace and then read
fixed offsets — parts[1] for the timestamp and parts[i+1] after the "from",
"accepted" and "email:" markers — without checking the line had that many
fields. A truncated or malformed line (the logged destination is
attacker-influenced) indexed past the slice and panicked; the panel handler
returned a 500 via Gin's recovery.

Extract the per-line field parsing into parseAccessLogFields and length
guard every positional lookup so a short line yields a partial entry
instead of panicking.

* fix(server): guard xray key-generator output parsing

GetNewX25519Cert, GetNewmldsa65 and GetNewmlkem768 parsed xray's stdout by
reading lines[0], lines[1] and each line's second colon-separated field
without any length check — unlike GetNewEchCert, which already guards its
line count. If the xray binary printed fewer than two lines or reformatted
its labels (a version change, or a silent failure that emitted nothing),
the fixed slice index panicked and the handler 500'd.

Extract the shared parsing into parseXrayKeyPairOutput, which length guards
the line count and each label split and returns an error instead of
panicking, then route all three generators through it.

* fix(tgbot): stop auto-deleted messages from resetting wizard state

SendMsgToTgbotDeleteAfter spawns a goroutine that, after the display delay,
deleted the transient message and then unconditionally cleared the chat's
conversation state. Every caller that ends a wizard step already clears the
state synchronously, so that call was redundant — and harmful: if within
the delay the user advanced to the next step (a callback sets a fresh
awaiting_* state), the late goroutine wiped it, and the user's next message
fell through unrecognized, silently dropping their input.

Move the delayed deletion into deleteMessageAfterDelay, which only removes
the message and no longer touches the conversation state. Guard
deleteMessageTgBot against a nil bot so the deletion path is unit-testable.

* fix(frontend): refetch a fresh CSRF token on 403 instead of reusing the stale meta tag

On a 403 to an unsafe method the client cleared its cached CSRF token and
called ensureCsrfToken to retry. But ensureCsrfToken prefers the
<meta name="csrf-token"> tag baked into the page, which the production
panel always injects, so the "refresh" re-read the same stale token and the
/csrf-token refetch was never reached — the retry re-sent the token that had
just been rejected and the save failed with an error toast.

The token lives in the session and rotates when the session is regenerated
(for example re-login in another tab), leaving the tab's baked-in meta token
stale. Fetch the current token straight from /csrf-token in the 403 branch so
the retry uses the authoritative server value. The existing tests only passed
because they strip the meta tag; the new test keeps a stale tag present.

* fix(frontend): surface backend error text from failed requests

HttpUtil.get/post read the thrown HttpError body as response.data.message,
but the backend error envelope (entity.Msg) serializes its text as msg. On
any non-2xx JSON response the real reason was therefore dropped and the
operator saw only the generic "Request failed with status N" toast.

Read response.data.msg first (keeping message and the native error text as
fallbacks). The sibling test had pinned the wrong body shape ({ message });
correct it to the real backend shape ({ success:false, msg }) so it exercises
the actual envelope.

* fix(frontend): share one WebSocket connection across bridge and hooks

websocketBridge.ts and useWebSocket.ts each declared their own
module-scoped sharedClient plus an identical getSharedClient, so the
"shared" client was not shared between them: whenever a page using
useWebSocket (Clients/Inbounds) mounted alongside the always-mounted
bridge, the panel opened two sockets to /ws. The server then pushed every
traffic/stats/nodes/inbounds snapshot to both, doubling WebSocket bandwidth
and running two independent reconnect loops, and the hook's socket was never
disconnected on unmount.

Hoist a single getSharedWebSocketClient into api/websocket.ts and route both
the bridge and the hook through it, so exactly one connection is opened.

* fix(frontend): guard the outbounds WebSocket handler against non-array payloads

onOutbounds wrote the raw WebSocket payload straight into the
outboundsTraffic cache, unlike the sibling onNodes/onInbounds handlers which
first check Array.isArray. A malformed non-array push (for example an object)
would land in the cache with staleTime Infinity; consumers that call
.find()/.map() on the outbounds list would then throw and crash the Outbounds
tab. Add the same Array.isArray guard so a bad push is ignored.

* fix(frontend): key the node table by the computed row key, not id

The desktop node table used rowKey="id", but transitive sub-nodes (the
read-only rows surfaced from downstream nodes) all carry id 0, so a topology
with two or more transitive rows gave React duplicate keys. antd's rowKey
prop overrides the row object's own computed `key` (`t-${guid}` for
transitive rows, the numeric id otherwise), so the unique key the code
already builds was ignored — causing row-state/DOM mis-association on any
re-render (heartbeat refetch, address-eye toggle). The mobile card path
already keyed by record.key.

Key the table by "key" so transitive rows get their distinct t-${guid}
identity; direct nodes keep key === id, so row selection (filtered to numeric
keys) is unchanged.

* fix(frontend): map routing row actions through the rule's real index

The routing table hides balancer-loopback rules (`_bl_*`) but keeps each
visible row's original index in `key`, then handed antd's positional row
index straight to edit/delete/toggle/move/drag — all of which mutate the
full, unfiltered routing.rules array. Once a hidden loopback rule precedes a
visible one (e.g. a balancer whose fallback is another balancer, plus any
rule added afterwards), the positional index no longer matches the array
index, so deleting or editing a rule silently hit the wrong one — including
destroying the loopback rule that keeps the balancer alive.

Add originalRuleIndex to translate a positional row index back through the
row's `key`, and route every mutating handler (openEdit, confirmDelete,
toggleRule, moveUp/moveDown, drag) through it. When no loopback rows are
hidden the mapping is the identity, so ordinary configs are unaffected.

* fix(frontend): map outbound row actions through the outbound's real index

The outbounds table hides balancer-loopback outbounds (`_bl_*`) but keeps
each visible row's original index in `key`, then passed antd's positional
row index to edit/delete/move and to the per-row probe (onTest) and its
result lookup — all of which address the full, unfiltered outbounds array.
Once a hidden loopback outbound precedes a visible one, the positional index
diverges from the array index, so deleting or editing an outbound hit the
wrong one (its deletion-impact plan and removal targeting the wrong entry),
and the test button probed / showed results against the wrong outbound.

Add originalOutboundIndex and route the mutating handlers through it; key
the probe trigger and test-result columns by record.key. With no loopback
rows hidden the mapping is the identity, so ordinary configs are unaffected.

* fix(frontend): tolerate a malformed happyEyeballs value in the Xray Basics tab

BasicsTab derived directHappyEyeballs by calling HappyEyeballsSchema.parse
during render, guarding only against null/non-object. A wrong-typed field
(e.g. happyEyeballs.tryDelayMs as a string) or any other shape mismatch —
reachable via the Complete Template JSON editor or an imported config — threw
straight out of render, white-screening the default Xray landing tab.

Use safeParse and fall back to null so a bad value degrades to "no override"
instead of crashing the page.

* fix(frontend): preserve routing-rule fields the form does not surface

The rule form rebuilt the rule from a fixed literal of only the fields it
edits, and RoutingTab replaces the rule wholesale on confirm. Fields the
form never exposes — localPort, localIP, process, ruleTag, webhook — are in
the rule schema and can arrive via the advanced JSON editor or Import Rules;
opening such a rule in the form and saving silently dropped them.

Carry over every key of the original rule the form does not manage before
applying the form-derived fields, so an edit only touches what it surfaces.

* fix(frontend): re-sync the sniffing island when its value changes externally

The sniffing config editor froze its seed value at mount and only watched
its own inner AntD form, never reflecting a later change to the shared RHF
`sniffing` path. Because the inbound form mounts every tab with
forceRender, the friendly Sniffing tab and the Advanced JSON editor are live
at once: editing sniffing in the JSON editor updated the RHF value but not
the frozen island, so the next interaction with the friendly tab emitted the
stale value and silently discarded the JSON edit.

Add an effect that pushes an external value change into the inner form,
guarded by the same lastEmitted marker the emit path uses so the island
never re-seeds from its own echo and no update loop forms.

* fix(frontend): don't drift a client's byte quota on a no-op save

The quota field shows the total in GB rounded to two decimals; editing a
client and saving converted that display value straight back to bytes. A
byte total not aligned to 0.01 GB — one set via the API or an import — was
therefore rewritten to the rounded value on any save that never touched the
field, losing a few MB each time.

Add resolveTotalBytes: keep the original byte total when the displayed GB
still matches it, and only re-derive from GB when the user actually changed
the field.

* fix(eventbus): deliver events on a bounded per-subscriber worker

The previous fix dispatched each event to every subscriber with a bare
`go safeCall`. That unblocked the dispatch loop, but removed the bus's
backpressure: under a login-attempt flood (which both notifier subscribers
process without rate-limiting) with email/Telegram enabled, every attempt
spawned handler goroutines that each block on network I/O for up to ~30s,
with no bound — a goroutine and outbound-connection storm. It also let a
subscriber's handler run concurrently with itself, racing the Telegram
notifier's lazily-cached hostname.

Give each subscriber its own bounded queue drained by a single worker
goroutine. Dispatch does a non-blocking send per subscriber (dropping only
that subscriber's event when its queue is full), so a slow subscriber still
can't stall the others, concurrency is bounded to one in-flight handler per
subscriber, per-subscriber event order is preserved, and Stop again waits
for in-flight handlers to finish.

* fix(frontend): map outbound mobile-card actions through the real index too

The desktop outbounds table was keyed by the outbound's real index, but the
mobile card list was left keying the probe trigger and every test-state
lookup by the positional row index. With a hidden balancer-loopback outbound
present, tapping Check on a mobile card probed the wrong outbound and the
Test-All results landed on the wrong card. Key onTest and the
testResult/isTesting reads by record.key, matching the desktop columns.

* fix(frontend): meet WCAG AA contrast on the config-block link text

The Storybook accessibility test flagged the share-link <code> block: with no
explicit color it inherited a muted grey that renders as #888888 on the
#f8f8f8 tertiary-fill background in CI's Chromium — a 3.33:1 contrast, below
the 4.5:1 AA threshold. Set the text to the theme's primary text token so the
colour is explicit and high-contrast in both light and dark themes instead of
depending on an inherited value that varies by browser.

* style(sub): simplify a negated conjunction to satisfy staticcheck QF1001

golangci-lint (staticcheck QF1001) flagged the `!(a && b)` guard in
expandSegment. Rewrite it via De Morgan's law to the equivalent
`!a || !b` form so the linter passes; behavior is unchanged.

* fix: close panics and races the audit's own fixes left nearby

Second-pass review of the 54-commit self-correcting audit. Each item below
was confirmed by reading the surrounding source (and, where practical, the
pre-fix code) before being changed; regression tests are included for every
behavioral fix.

Concurrency:
- eventbus: Bus.Subscribe called wg.Add with no synchronization against a
  concurrent Bus.Stop's wg.Wait, a real "WaitGroup misuse" panic risk (e.g. a
  Telegram-bot settings save racing panel shutdown/restart). Stop now flips a
  mu-guarded `stopped` flag before waiting, and Subscribe checks it under the
  same lock, so Add and Wait can no longer race.

Security:
- login_limiter: evictForRoom's fallback eviction picked an arbitrary map
  key, including ones still under an active cooldown - an attacker flooding
  /login with fresh usernames could evict their own (or anyone's) blocked
  record and reset the lockout. The fallback now skips actively-blocked
  records, only falling back to an unconditional evict if the map is
  somehow entirely full of active blocks (preserves the hard memory cap).

Subscription-endpoint panics (reachable by any client hitting /sub):
- internal/sub/service.go: applyPathAndHostParams/Obj (ws/httpupgrade/xhttp
  with no path settings object) and the TLS alpn readers in three places
  used unchecked type assertions - exactly the bug class abab7cd0 patched
  elsewhere in the same switch statements, just not these call sites.
- internal/sub/json_service.go, clash_service.go: the externalProxy loops
  in the JSON and Clash generators used unchecked assertions on a
  legacy/admin-supplied field (missing "port", non-object entry, etc.).
- internal/sub/json_service.go: realityData's shortId/serverName selection
  could assert a non-string array element.

Other correctness:
- client_traffic.go: ResetAllTraffics (touched by 3eb214d0) still skipped
  clearing NodeClientTraffic node-sync baselines, unlike its sibling reset
  paths in the same file - a node's next sync would re-add pre-reset delta
  on top of the freshly-zeroed counter.
- inbound_traffic.go: the traffic-tick tx's Commit/Rollback errors were
  silently discarded; now logged so a backend-level commit failure (e.g. an
  aborted Postgres tx from a best-effort helper) doesn't masquerade as a
  successful tick.
- outbound_subscription.go: the new subscriptionFetchClient doc comment was
  wedged between fetchAndStore's existing comment and fetchAndStore itself,
  leaving fetchAndStore undocumented and the comment describing the wrong
  function.

Convention cleanup:
- Removed narrative // comments added by the audit that violate this repo's
  no-inline-comment rule (mostly narrating the specific bug/fix rather than
  a lasting contract, and mostly on new Test functions, which this repo's
  existing tests never comment) - calibrated against this exact codebase's
  own pre-existing comment style so legitimate godoc-style doc comments
  were left alone.

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-07-17 00:33:06 +02:00

2241 lines
165 KiB
JSON
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"username": "نام‌کاربری",
"password": "رمزعبور",
"login": "ورود",
"confirm": "تایید",
"cancel": "انصراف",
"close": "بستن",
"save": "ذخیره",
"logout": "خروج",
"create": "ایجاد",
"add": "افزودن",
"remove": "حذف",
"update": "به‌روزرسانی",
"copy": "کپی",
"copied": "کپی شد",
"more": "بیشتر",
"download": "دانلود",
"regenerate": "تولید مجدد",
"jsonEditor": "ویرایشگر JSON",
"downloadImage": "دانلود تصویر",
"sort": "مرتب‌سازی",
"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": "آی‌پی اتصال",
"certificate": "گواهی دیجیتال",
"fail": "ناموفق",
"comment": "توضیحات",
"success": "موفق",
"lastOnline": "آخرین فعالیت",
"getVersion": "دریافت نسخه",
"install": "نصب",
"clients": "کاربران",
"usage": "استفاده",
"twoFactorCode": "کد",
"remained": "باقی‌مانده",
"security": "امنیت",
"secAlertTitle": "هشدار‌امنیتی",
"secAlertSsl": "این‌اتصال‌امن نیست. لطفا‌ تازمانی‌که تی‌ال‌اس برای محافظت از‌ داده‌ها فعال نشده‌است، از وارد کردن اطلاعات حساس خودداری کنید",
"secAlertConf": "تنظیمات خاصی در برابر حملات آسیب پذیر هستند. توصیه می‌شود پروتکل‌های امنیتی را برای جلوگیری از نفوذ احتمالی تقویت کنید",
"secAlertSSL": "پنل فاقد ارتباط امن است. لطفاً یک گواهینامه تی‌ال‌اس برای محافظت از داده‌ها نصب کنید",
"secAlertPanelPort": "استفاده از پورت پیش‌فرض پنل ناامن است. لطفاً یک پورت تصادفی یا خاص تنظیم کنید",
"secAlertPanelURI": "مسیر پیش‌فرض لینک پنل ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
"secAlertSubURI": "مسیر پیش‌فرض لینک سابسکریپشن ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
"secAlertSubJsonURI": "مسیر پیش‌فرض لینک سابسکریپشن جیسون ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
"emptyDnsDesc": "هیچ سرور DNS اضافه نشده است.",
"emptyFakeDnsDesc": "هیچ سرور Fake DNS اضافه نشده است.",
"emptyBalancersDesc": "هیچ بالانسر اضافه نشده است.",
"emptyReverseDesc": "هیچ پروکسی معکوس اضافه نشده است.",
"somethingWentWrong": "مشکلی پیش آمد",
"subscription": {
"title": "اطلاعات سابسکریپشن",
"subId": "شناسه اشتراک",
"email": "ایمیل",
"status": "وضعیت",
"downloaded": "دانلود",
"uploaded": "آپلود",
"expiry": "تاریخ پایان",
"totalQuota": "حجم کلی",
"individualLinks": "لینک‌های تکی",
"active": "فعال",
"inactive": "غیرفعال",
"unlimited": "نامحدود",
"noExpiry": "بدون انقضا",
"copyAllConfigs": "کپی همه کانفیگ‌ها",
"copyAllConfigsCopied": "همه کانفیگ‌ها کپی شدند"
},
"menu": {
"theme": "تم",
"dark": "تیره",
"ultraDark": "فوق تیره",
"dashboard": "نمای کلی",
"inbounds": "ورودی‌ها",
"clients": "کلاینت‌ها",
"groups": "گروه‌ها",
"nodes": "نودها",
"settings": "تنظیمات پنل",
"xray": "پیکربندی Xray",
"routing": "مسیریابی",
"outbounds": "خروجی‌ها",
"apiDocs": "مستندات API",
"logout": "خروج",
"link": "مدیریت",
"donate": "حمایت مالی",
"hosts": "میزبان‌ها",
"docs": "مستندات",
"openMenu": "باز کردن منو"
},
"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": "پنل به‌روز است",
"devChannel": "کانال توسعه (Dev)",
"devChannelWarning": "بیلدهای توسعه هر کامیت روی main را دنبال می‌کنند و نسخهٔ پایدار نیستند — بازگشت خودکار به نسخهٔ قبلی وجود ندارد.",
"currentCommit": "کامیت فعلی",
"latestCommit": "آخرین کامیت",
"updateChannelChanged": "کانال به‌روزرسانی تغییر کرد",
"upToDate": "به‌روز",
"xrayStatusUnknown": "ناشناخته",
"xrayStatusRunning": "در حال اجرا",
"xrayStatusStop": "متوقف",
"xrayStatusError": "خطا",
"xrayErrorPopoverTitle": "خطا در هنگام اجرای Xray رخ داد",
"operationHours": "مدت‌کارکرد",
"systemHistoryTitle": "تاریخچه سیستم",
"historyTitleCpu": "مصرف پردازنده",
"historyTitleMem": "مصرف حافظه",
"historyTitleNetwork": "پهنای باند شبکه",
"historyTitlePackets": "بسته‌های شبکه",
"historyTitleDisk": "ورودی/خروجی دیسک",
"historyTitleOnline": "کاربران آنلاین",
"historyTitleLoad": "میانگین بار سیستم (۱ / ۵ / ۱۵ دقیقه)",
"historyTitleConnections": "اتصالات فعال (TCP / UDP)",
"historyTitleDiskUsage": "مصرف فضای دیسک",
"historyTabBandwidth": "پهنای باند",
"historyTabPackets": "بسته‌ها",
"historyTabDisk": "دیسک I/O",
"historyTabOnline": "آنلاین",
"historyTabLoad": "بار",
"historyTabConnections": "اتصالات",
"historyTabDiskUsage": "مصرف دیسک",
"charts": "نمودارها",
"xrayMetricsTitle": "متریک‌های Xray",
"xrayTitleHeap": "حافظه‌ی Heap تخصیص‌یافته",
"xrayTitleSys": "حافظه‌ی رزروشده از سیستم‌عامل",
"xrayTitleObjects": "اشیای زنده‌ی Heap",
"xrayTitleGcCount": "چرخه‌های کامل‌شده‌ی GC",
"xrayTitleGcPause": "مدت مکث GC",
"xrayTitleObservatory": "سلامت اتصال خروجی",
"xrayTabHeap": "Heap",
"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 tag‌هایی که می‌خواهید بررسی شوند را لیست کنید، سپس xray را راه‌اندازی مجدد کنید.",
"xrayObservatoryTagPlaceholder": "انتخاب outbound",
"xrayObservatoryAlive": "فعال",
"xrayObservatoryDead": "غیرفعال",
"xrayObservatoryLastSeen": "آخرین مشاهده",
"xrayObservatoryLastTry": "آخرین تلاش",
"trendLast2Min": "۲ دقیقه اخیر",
"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": "به‌روزرسانی پنل آغاز شد",
"panelUpdateFailedTitle": "به‌روزرسانی پنل ناموفق بود",
"panelUpdateFailedDesc": "به‌روزرسانی با موفقیت به پایان نرسید. گزارش‌های سرور را بررسی کنید یا دستور «x-ui update» را از خط فرمان اجرا کنید.",
"panelUpdateUnknownTitle": "تأیید نشد که به‌روزرسانی به پایان رسیده باشد",
"panelUpdateUnknownDesc": "پنل به‌موقع نتیجه‌ای گزارش نکرد. صفحه را بارگذاری مجدد کنید تا نسخه فعلی را بررسی کنید یا گزارش‌های سرور را بررسی کنید.",
"geofileUpdateDialog": "آیا واقعاً می‌خواهید فایل جغرافیایی را به‌روز کنید؟",
"geofileUpdateDialogDesc": "این عمل فایل #filename# را به‌روز می‌کند.",
"geofilesUpdateDialogDesc": "با این کار همه فایل‌ها به‌روزرسانی می‌شوند.",
"geofilesUpdateAll": "همه را به‌روزرسانی کنید",
"geofileUpdatePopover": "فایل جغرافیایی با موفقیت به‌روز شد",
"geodataTitle": "به‌روزرسانی خودکار Geodata",
"geodataHint": "Xray این فایل‌ها را طبق زمان‌بندی دانلود کرده و بدون ری‌استارت بارگذاری مجدد می‌کند. آدرس‌ها باید HTTPS باشند. هر فایل باید از قبل در پوشه bin موجود باشد تا Xray بتواند آن را به‌روزرسانی کند.",
"geodataCron": "زمان‌بندی (cron)",
"geodataOutbound": "دانلود از طریق خروجی (اختیاری)",
"geodataFile": "نام فایل",
"geodataAddFile": "افزودن فایل",
"geodataSaveRestart": "ذخیره و ری‌استارت Xray",
"geodataConfirmTitle": "تنظیمات geodata ذخیره شود؟",
"geodataConfirmContent": "قالب پیکربندی Xray به‌روزرسانی و Xray ری‌استارت می‌شود.",
"geodataInvalidUrl": "هر فایل به یک آدرس HTTPS نیاز دارد.",
"geodataInvalidFile": "نام فایل باید ساده باشد، مانند geosite_custom.dat (بدون مسیر).",
"geodataInvalidCron": "Cron باید ۵ بخش داشته باشد، مثل 0 4 * * *",
"geodataEmpty": "فایلی پیکربندی نشده است. در قوانین مسیریابی فایل‌ها به صورت ext:geosite_custom.dat:category استفاده می‌شوند.",
"dontRefresh": "در حال نصب، لطفا صفحه را رفرش نکنید",
"logs": "لاگ‌ها",
"accessLogs": "لاگ‌های دسترسی",
"autoUpdate": "به‌روزرسانی خودکار",
"config": "پیکربندی",
"backup": "پشتیبان‌گیری",
"backupTitle": "پشتیبان‌گیری و بازیابی",
"exportDatabase": "پشتیبان‌گیری",
"exportDatabaseDesc": "برای دانلود یک فایل .db حاوی پشتیبان از پایگاه داده فعلی خود به دستگاهتان کلیک کنید. همین فایل در پنلی که روی PostgreSQL اجرا می‌شود نیز قابل بازیابی است.",
"importDatabase": "بازیابی",
"importDatabaseDesc": "برای انتخاب و آپلود یک پشتیبان .db یا فایل مهاجرت ‎.dump از دستگاهتان جهت بازیابی پایگاه داده کلیک کنید.",
"importDatabaseSuccess": "پایگاه داده با موفقیت وارد شد",
"importDatabaseError": "خطا در وارد کردن پایگاه داده",
"readDatabaseError": "خطا در خواندن پایگاه داده",
"getDatabaseError": "خطا در دریافت پایگاه داده",
"getConfigError": "خطا در دریافت فایل پیکربندی",
"backupPostgresNote": "این پنل روی PostgreSQL اجرا می‌شود. «پشتیبان‌گیری» یک آرشیو pg_dump (.dump) دانلود می‌کند و «بازیابی» آن را با pg_restore بازمی‌گرداند. «بازیابی» همچنین پایگاه‌دادهٔ SQLite (.db) یا فایل مهاجرت SQLite را می‌پذیرد و داده‌های آن را به PostgreSQL وارد می‌کند. سرور باید ابزارهای کلاینت PostgreSQL (pg_dump و pg_restore) را نصب داشته باشد.",
"exportDatabasePgDesc": "برای دانلود یک دامپ PostgreSQL (.dump) از پایگاه داده فعلی روی دستگاهتان کلیک کنید.",
"importDatabasePgDesc": "برای انتخاب و بارگذاری یک پشتیبان PostgreSQL (.dump)، پایگاه‌دادهٔ SQLite (.db) یا فایل مهاجرت SQLite جهت بازیابی پایگاه داده کلیک کنید. این کار همه داده‌های فعلی را جایگزین می‌کند.",
"migrationDownload": "دانلود فایل مهاجرت",
"migrationDownloadPgDesc": "برای دانلود یک پایگاه‌دادهٔ SQLite با پسوند ‎.db که از داده‌های PostgreSQL شما ساخته می‌شود کلیک کنید؛ آمادهٔ اجرای این پنل روی SQLite."
},
"inbounds": {
"title": "ورودی‌ها",
"totalDownUp": "دریافت/ارسال کل",
"totalUsage": "‌مصرف کل",
"inboundCount": "کل ورودی‌ها",
"operate": "منو",
"enable": "فعال",
"remark": "نام",
"node": "نود",
"deployTo": "استقرار روی",
"localPanel": "پنل لوکال",
"fallbacks": {
"title": "Fallbackها",
"help": "وقتی اتصالی روی این اینباند با هیچ کلاینتی تطبیق پیدا نمی‌کند، به جای دیگری ارجاع داده می‌شود. یک اینباند فرزند از پایین انتخاب کنید تا فیلدهای مسیریابی (SNI / ALPN / Path / xver) خودکار از روی transport آن پر شود، یا انتخاب‌گر را خالی بگذارید و مقدار Dest را مستقیم تنظیم کنید (مثلاً 8080 یا 127.0.0.1:8080) تا به یک سرور بیرونی مانند Nginx ارجاع شود. هر اینباند فرزند باید روی 127.0.0.1 با security=none گوش بدهد.",
"empty": "هنوز فال‌بکی اضافه نشده",
"add": "افزودن فال‌بک",
"pickInbound": "یک اینباند انتخاب کنید",
"matchAny": "همه",
"destPlaceholder": "خودکار (listen:port فرزند)",
"rederive": "پر کردن مجدد از فرزند",
"rederived": "از فرزند پر شد",
"editAdvanced": "ویرایش فیلدهای مسیریابی",
"hideAdvanced": "بستن پیشرفته",
"quickAddAll": "افزودن سریع همه‌ی موارد واجد شرایط",
"quickAdded": "{n} فال‌بک افزوده شد",
"quickAddedNone": "اینباند جدیدی برای افزودن وجود ندارد",
"routesWhen": "هدایت می‌شود وقتی",
"defaultCatchAll": "پیش‌فرض — همه‌ی موارد دیگر را می‌گیرد",
"needsTls": "فال‌بک‌ها پس از انتخاب 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": "شمارنده‌های ارسال/دریافت این اینباند به صفر برمی‌گردد.",
"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": "جستجوی ایمیل یا توضیح",
"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": "کپی لینک",
"address": "آدرس",
"network": "شبکه",
"destinationPort": "پورت مقصد",
"targetAddress": "آدرس مقصد",
"monitorDesc": "به‌طور پیش‌فرض خالی‌بگذارید",
"meansNoLimit": "= نامحدود. (واحد: GB)",
"totalFlow": "ترافیک کل",
"leaveBlankToNeverExpire": "برای منقضی‌نشدن خالی‌بگذارید",
"noRecommendKeepDefault": "توصیه‌می‌شود به‌طور پیش‌فرض حفظ‌شود",
"certificatePath": "مسیر فایل",
"certificateContent": "محتوای فایل",
"publicKey": "کلید عمومی",
"privatekey": "کلید خصوصی",
"clickOnQRcode": "برای کپی بر روی کدتصویری کلیک کنید",
"client": "کاربر",
"export": "استخراج لینک‌ها",
"clone": "شبیه‌سازی",
"cloneInbound": "شبیه‌سازی ورودی",
"cloneInboundContent": "همه موارد این ورودی بجز پورت، آی‌پی و کاربر‌ها شبیه‌سازی خواهند شد",
"cloneInboundOk": "ساختن شبیه ساز",
"resetAllTraffic": "ریست ترافیک کل ورودی‌ها",
"resetAllTrafficTitle": "ریست ترافیک کل ورودی‌ها",
"resetAllTrafficContent": "آیا مطمئن به ریست ترافیک تمام ورودی‌ها هستید؟",
"resetInboundClientTraffics": "ریست ترافیک کاربران",
"resetInboundClientTrafficTitle": "ریست ترافیک کاربران",
"resetInboundClientTrafficContent": "آیا مطمئن به ریست ترافیک تمام کاربران این‌ ورودی هستید؟",
"resetAllClientTraffics": "ریست ترافیک کل کاربران",
"resetAllClientTrafficTitle": "ریست ترافیک کل کاربران",
"resetAllClientTrafficContent": "آیا مطمئن به ریست ترافیک تمام کاربران هستید؟",
"delDepletedClients": "حذف کاربران منقضی",
"delDepletedClientsTitle": "حذف کاربران منقضی",
"delDepletedClientsContent": "آیا مطمئن به حذف تمام کاربران منقضی‌شده ‌هستید؟",
"email": "ایمیل",
"emailDesc": "باید یک ایمیل یکتا باشد",
"IPLimit": "محدودیت آی‌پی",
"IPLimitDesc": "(اگر تعداد از مقدار تنظیم شده بیشتر شود، ورودی را غیرفعال می کند. (0 = غیرفعال",
"IPLimitlog": "گزارش‌ها",
"IPLimitlogDesc": "گزارش تاریخچه آی‌پی. برای فعال کردن ورودی پس از غیرفعال شدن، گزارش را پاک کنید",
"IPLimitlogclear": "پاک کردن گزارش‌ها",
"setDefaultCert": "استفاده از گواهی پنل",
"setDefaultCertEmpty": "هیچ گواهی‌ای برای پنل پیکربندی نشده. ابتدا از تنظیمات یکی تعیین کنید.",
"streamTab": "انتقال",
"securityTab": "امنیت",
"sniffingTab": "شنود",
"sniffingMetadataOnly": "فقط متادیتا",
"sniffingRouteOnly": "فقط مسیریابی",
"sniffingIpsExcluded": "IPهای مستثنا",
"sniffingDomainsExcluded": "دامنه‌های مستثنا",
"decryption": "رمزگشایی",
"encryption": "رمزنگاری",
"vlessAuthX25519": "X25519 (native)",
"vlessAuthMlkem768": "ML-KEM-768 (native)",
"vlessAuthX25519Xorpub": "X25519 (xorpub)",
"vlessAuthX25519Random": "X25519 (random)",
"vlessAuthMlkem768Xorpub": "ML-KEM-768 (xorpub)",
"vlessAuthMlkem768Random": "ML-KEM-768 (random)",
"vlessAuthCustom": "سفارشی",
"vlessAuthSelected": "انتخاب‌شده: {auth}",
"vlessAuthGenerate": "تولید کلیدها",
"vlessAuthGenerateButton": "تولید",
"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' در ربات استفاده کنید) یا ({'@'}userinfobot)",
"subscriptionDesc": "شما می‌توانید لینک سابسکربپشن خودرا در 'جزئیات' پیدا کنید، همچنین می‌توانید از همین نام برای چندین کاربر استفاده‌کنید",
"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.",
"scanRealityTargetError": "اسکن هدف REALITY ناموفق بود.",
"scanRealityTargetFeasible": "هدف مناسب است — هدف و SNI پر شد.",
"scanRealityTargetNotFeasible": "هدف در دسترس است اما برای REALITY مناسب نیست.",
"invalidClientField": "کلاینت {client}: فیلد {field} — {reason}",
"invalidField": "{field} — {reason}",
"moreIssues": "{message} (+{count} مورد دیگر)"
},
"form": {
"moveUp": "بالا",
"moveDown": "پایین",
"addAll": "افزودن همه",
"addAllFallbackTooltip": "برای هر ورودی واجد شرایط که هنوز متصل نشده یک ردیف fallback اضافه می‌کند",
"peers": "Peers",
"addPeer": "افزودن peer",
"keepAlive": "Keep-alive",
"autoSystemRoutesTooltip": "فقط ویندوز. CIDRها به‌صورت خودکار به جدول مسیریابی سیستم اضافه می‌شوند تا ترافیک مطابق از TUN عبور کند.",
"autoOutboundsInterface": "رابط خروجی خودکار",
"autoOutboundsInterfaceTooltip": "رابط فیزیکی برای ترافیک خروجی. از auto برای تشخیص استفاده کنید؛ زمانی که Auto system routes فعال باشد، به‌صورت خودکار فعال می‌شود.",
"rewriteAddress": "بازنویسی آدرس",
"rewritePort": "بازنویسی پورت",
"allowedNetwork": "شبکه مجاز",
"followRedirect": "دنبال‌کردن Redirect",
"accounts": "حساب‌ها",
"allowTransparent": "اجازه شفاف",
"encryptionMethod": "روش رمزنگاری",
"fakeTlsDomain": "دامنه FakeTLS (SNI)",
"mtprotoSecret": "کلید مخفی",
"mtgDomainFrontingIp": "آی‌پی Domain fronting",
"mtgDomainFrontingPort": "پورت Domain fronting",
"mtgDomainFrontingProxyProtocol": "پروتکل PROXY برای Domain fronting",
"mtgDomainFrontingHint": "جایی که mtg ترافیک غیرتلگرامی را به آن ارسال می‌کند — مثلاً سایت جعلی NGINX شما. برای استفاده از دامنهٔ FakeTLS از طریق DNS، فیلد IP را خالی بگذارید؛ پورت پیش‌فرض 443 است.",
"mtgProxyProtocolListener": "پذیرش پروتکل PROXY (شنونده)",
"mtgPreferIp": "ترجیح IP",
"mtgDebug": "گزارش اشکال‌زدایی",
"mtgRouteThroughXray": "مسیریابی از طریق Xray",
"mtgRouteThroughXrayHint": "ترافیک تلگرام این پراکسی را از طریق Xray بفرستید تا از قوانین مسیریابی شما پیروی کند. سرویس جانبی mtg از طریق یک پل SOCKS محلی که با تگ همین ورودی نشانه‌گذاری شده خارج می‌شود؛ برای قوانین پیشرفته در تب مسیریابی به همان تگ ارجاع دهید.",
"mtgRouteOutbound": "خروجی",
"mtgRouteOutboundHint": "اختیاری. ترافیک تلگرام را وادار کنید از این خروجی (یا متعادل‌کننده) خارج شود. برای اینکه قوانین مسیریابی تصمیم بگیرند، خالی بگذارید.",
"mtgRouteOutboundPlaceholder": "استفاده از قوانین مسیریابی",
"mtprotoFakeTlsDomainHint": "دامنه پیش‌فرض FakeTLS برای ساخت سکرت کلاینت جدید. هر کلاینت می‌تواند دامنه مخصوص خود را داشته باشد.",
"mtgThrottleMaxConnections": "حداکثر اتصالات",
"mtgThrottleMaxConnectionsHint": "محدود کردن اتصالات همزمان همه کاربران با تقسیم منصفانه. مقدار ۰ غیرفعال است.",
"mtgAdTagInvalid": "برچسب تبلیغاتی باید دقیقاً ۳۲ کاراکتر هگزادسیمال باشد.",
"mtgPublicIpv4": "IPv4 عمومی",
"mtgPublicIpv6": "IPv6 عمومی",
"mtgPublicIpHint": "نشانی عمومی و در‌دسترس این سرور که پروکسی میانی برچسب تبلیغاتی از آن استفاده می‌کند. برای تشخیص خودکار توسط mtg، خالی بگذارید.",
"visionTestseed": "Vision testseed",
"version": "نسخه",
"udpIdleTimeout": "UDP idle timeout (s)",
"masquerade": "استتار",
"type": "نوع",
"upstreamUrl": "آدرس Upstream",
"rewriteHost": "بازنویسی Host",
"skipTlsVerify": "رد تایید TLS",
"directory": "دایرکتوری",
"statusCode": "کد وضعیت",
"body": "Body",
"headers": "هدرها",
"proxyProtocol": "Proxy Protocol",
"requestVersion": "نسخه درخواست",
"requestMethod": "متد درخواست",
"requestPath": "مسیر درخواست",
"requestHeaders": "هدرهای درخواست",
"responseVersion": "نسخه پاسخ",
"responseStatus": "وضعیت پاسخ",
"responseReason": "دلیل پاسخ",
"responseHeaders": "هدرهای پاسخ",
"heartbeatPeriod": "دوره Heartbeat",
"serviceName": "نام سرویس",
"authority": "Authority",
"multiMode": "حالت چندگانه",
"maxBufferedUpload": "حداکثر آپلود بافرشده",
"maxUploadSize": "حداکثر اندازه آپلود (بایت)",
"streamUpServer": "سرور Stream-Up",
"serverMaxHeaderBytes": "حداکثر بایت هدر سرور",
"paddingBytes": "بایت‌های Padding",
"uplinkHttpMethod": "متد HTTP آپلینک",
"paddingObfsMode": "حالت ابهام Padding",
"paddingKey": "کلید Padding",
"paddingHeader": "هدر Padding",
"paddingPlacement": "محل Padding",
"paddingMethod": "روش Padding",
"sessionPlacement": "محل نشست",
"sessionKey": "کلید نشست",
"sessionIDTable": "جدول شناسه نشست",
"sessionIDTableHint": "مجموعه نویسه‌ها برای تولید شناسه نشست: یک نام از پیش‌تعریف‌شده (ALPHABET، Base62، hex، number، …) یا یک رشته ASCII. برای مقدار پیش‌فرض xray-core خالی بگذارید.",
"sessionIDLength": "طول شناسه نشست",
"sessionIDLengthHint": "طول یا بازه (مثلاً 8-16) شناسه نشست تولیدشده. فقط وقتی جدول شناسه نشست تنظیم شده باشد استفاده می‌شود؛ کمینه باید بزرگ‌تر از 0 باشد.",
"sequencePlacement": "محل Sequence",
"sequenceKey": "Sequence Key",
"uplinkDataPlacement": "محل داده Uplink",
"uplinkDataKey": "کلید داده Uplink",
"noSseHeader": "بدون هدر SSE",
"ttiMs": "TTI (ms)",
"uplinkMbps": "آپلود (MB/s)",
"downlinkMbps": "دانلود (MB/s)",
"cwndMultiplier": "ضریب CWND",
"maxSendingWindow": "حداکثر پنجره ارسال",
"externalProxy": "پراکسی خارجی",
"forceTls": "اجبار TLS",
"fingerprint": "اثرانگشت",
"defaultOption": "پیش‌فرض",
"routeMark": "علامت مسیر",
"tcpKeepAliveInterval": "بازه TCP Keep Alive",
"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": "فقط IPv6",
"tcpCongestion": "تراکم TCP",
"dialerProxy": "Dialer Proxy",
"trustedXForwardedFor": "X-Forwarded-For مورد اعتماد",
"trustedXForwardedForHint": "این هدر درخواست برای گرفتن IP واقعی کاربر مورد اعتماد قرار می‌گیرد (مثلاً CF-Connecting-IP پشت CDN کلودفلر). فقط روی ترنسپورت‌های WebSocket، HTTPUpgrade، XHTTP و gRPC اعمال می‌شود. برای نادیده‌گرفتن هدرها خالی بگذارید.",
"proxyProtocolHint": "پذیرش هدر PROXY protocol برای گرفتن IP واقعی کاربر از یک تونل/رله L4 بالادست (HAProxy، gost، nginx-stream، Xray dokodemo-door) یا Cloudflare Spectrum. بالادست باید PROXY protocol را ارسال کند. روی TCP، WebSocket، HTTPUpgrade و gRPC کار می‌کند؛ روی mKCP خیر.",
"realClientIp": "IP واقعی کاربر",
"realClientIpHint": "وقتی ترافیک از طریق CDN یا رله به این ورودی می‌رسد، به‌جای ثبت آدرس واسط، IP واقعی کاربر گرفته می‌شود. یک پریست انتخاب کنید تا فیلدهای 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": "تأخیر تلاش (ms)",
"prioritizeIPv6": "اولویت IPv6",
"interleave": "Interleave",
"maxConcurrentTry": "حداکثر تلاش هم‌زمان",
"customSockopt": "Sockopt دلخواه",
"addCustomOption": "افزودن گزینه دلخواه",
"serverNameIndication": "SNI",
"cipherSuites": "مجموعه‌های رمز",
"autoOption": "خودکار",
"minMaxVersion": "نسخه حداقل/حداکثر",
"rejectUnknownSni": "رد SNI ناشناخته",
"disableSystemRoot": "غیرفعال‌سازی System Root",
"sessionResumption": "ازسرگیری نشست",
"oneTimeLoading": "بارگذاری یک‌بار",
"usageOption": "گزینه استفاده",
"buildChain": "ساخت زنجیره",
"echKey": "کلید ECH",
"echConfig": "پیکربندی ECH",
"echSockopt": "Sockopt مربوط به ECH",
"echSockoptTip": "تنظیمات سوکت برای اتصالی که Xray برای دریافت لیست پیکربندی ECH استفاده می‌کند (مثلاً عبور این درخواست از یک dialerProxy). برای استفاده از پیش‌فرض غیرفعال بگذارید.",
"curvePreferences": "ترجیح منحنی‌ها",
"curvePreferencesTip": "منحنی‌های تبادل کلید TLS که سرور ارائه می‌دهد را به‌ترتیب اولویت محدود می‌کند (مثلاً X25519MLKEM768، X25519). خالی بگذارید تا پیش‌فرض Xray استفاده شود.",
"masterKeyLog": "لاگ کلید اصلی",
"masterKeyLogTip": "مسیر نوشتن کلیدهای اصلی TLS (قالب SSLKEYLOGFILE) برای دیباگ با Wireshark. در محیط عملیاتی خالی بگذارید — هرکس به این فایل دسترسی داشته باشد می‌تواند ترافیک را رمزگشایی کند.",
"pinFromCert": "پرکردن از گواهی همین ورودی",
"pinFromRemote": "گرفتن هش با پینگ‌کردن SNI (xray tls ping)",
"pinFromRemoteNoSni": "ابتدا SNI (serverName) را تنظیم کنید تا گواهی راه‌دور پینگ شود.",
"pinFromRemoteFailed": "گرفتن هشِ گواهی راه‌دور ممکن نشد.",
"verifyPeerCertByName": "تأیید گواهی همتا با نام",
"verifyPeerCertByNameTip": "به کلاینت‌ها می‌گوید گواهی سرور را به‌جای SNI با این نام تأیید کنند. نام‌ها با کاما جدا شوند. فقط در پنل — در لینک‌های اشتراک‌گذاری گنجانده می‌شود (vcn). جایگزین مدرن allowInsecure که xray بعد از ۲۰۲۶-۰۶-۰۱ حذفش کرد.",
"pinnedPeerCertSha256": "SHA-256 پین‌شدهٔ گواهی همتا",
"pinnedPeerCertSha256Tip": "هش‌های SHA-256 گواهی همتا به‌صورت رشتهٔ هگزادسیمال (مثل e8e2d3…)، با کاما جدا شوند. فقط در پنل — در پیکربندی xray سرور نوشته نمی‌شود، اما در لینک‌های اشتراک‌گذاری گنجانده می‌شود تا کلاینت‌ها بتوانند گواهی را پین کنند.",
"pinnedPeerCertSha256Placeholder": "هش(های) هگزادسیمال، با کاما جدا شوند",
"getNewEchCert": "دریافت گواهی ECH جدید",
"show": "نمایش",
"xver": "Xver",
"target": "هدف",
"maxTimeDiff": "حداکثر اختلاف زمان (ms)",
"minClientVer": "حداقل نسخه کلاینت",
"maxClientVer": "حداکثر نسخه کلاینت",
"shortIds": "Short IDها",
"realityTargetHint": "الزامی است. باید شامل پورت باشد (مثلاً example.com:443). بدون پورت، Xray-core اجرا نمی‌شود.",
"realityTargetRequired": "هدف REALITY الزامی است",
"realityTargetNeedsPort": "هدف REALITY باید شامل پورت باشد (مثلاً example.com:443)",
"realityTargetInvalidPort": "پورت هدف REALITY نامعتبر است",
"scan": "اسکن",
"findTargets": "یافتن هدف‌ها",
"scanModalTitle": "اسکنر هدف REALITY",
"scanModalDesc": "یک دامنه را اعتبارسنجی کنید، یا یک محدوده‌ی IP/CIDR را اسکن کنید تا هدف‌های جدید REALITY از روی گواهی‌هایشان کشف شوند. برای بررسی کاندیدهای پیش‌فرض، کادر را خالی بگذارید.",
"scanDiscoverPlaceholder": "آی‌پی، CIDR یا دامنه — برای کاندیدهای پیش‌فرض خالی بگذارید",
"scanStatus": "وضعیت",
"scanFeasible": "مناسب",
"scanNotFeasible": "نامناسب",
"scanCurve": "تبادل کلید",
"scanCert": "گواهی",
"scanCertInvalid": "نامعتبر",
"scanLatency": "تأخیر",
"scanUse": "استفاده",
"scanRescan": "اسکن مجدد",
"spiderX": "SpiderX",
"spiderXHint": "دانه‌ی هر کاربر — پنل از روی آن مسیر spx یکتا برای هر کاربر می‌سازد؛ برای چرخش مسیر همه، دوباره تولید کنید",
"getNewCert": "دریافت گواهی جدید",
"mldsa65Seed": "mldsa65 Seed",
"mldsa65Verify": "mldsa65 Verify",
"getNewSeed": "دریافت Seed جدید",
"limitFallback": "محدودیت فالبک",
"limitFallbackUpload": "محدودیت فالبک آپلود",
"limitFallbackDownload": "محدودیت فالبک دانلود",
"afterBytes": "پس از (بایت)",
"afterBytesTip": "اجازه بده فالبک برای این تعداد بایت با سرعت کامل اجرا شود، سپس محدودسازی شروع شود. مقدار ۰ یعنی از همان بایت اول محدود شود.",
"bytesPerSec": "بایت بر ثانیه",
"bytesPerSecTip": "سقف سرعت (بایت بر ثانیه) که بعد از آستانه روی ترافیک فالبک اعمال می‌شود تا پروب‌ها نتوانند سرورت را به‌عنوان پهنای‌باند رایگان به مقصد استفاده کنند. مقدار ۰ یعنی بدون محدودیت (این جهت غیرفعال می‌شود).",
"burstBytesPerSec": "بایت انفجاری بر ثانیه",
"burstBytesPerSecTip": "سهمیه برای انفجارهای کوتاه بالاتر از نرخ ثابت (اندازهٔ token-bucket). اگر کمتر از «بایت بر ثانیه» باشد، به همان مقدار افزایش می‌یابد.",
"listenHelp": "می‌توانید به‌جای پورت TCP یک مسیر سوکت یونیکس وارد کنید (مثلاً /run/xray/in.sock)، یا یک نام سوکت انتزاعی با پیشوند @ (مثلاً @xray/in.sock)، تا روی سوکت گوش داده شود — در این حالت پورت را روی ۰ بگذارید.",
"shareAddrStrategy": "راهبرد آدرس اشتراک‌گذاری",
"shareAddrStrategyHelp": "مشخص می‌کند کدام آدرس در لینک‌های اشتراک‌گذاری خروجی، کدهای QR و خروجی اشتراک نوشته شود.",
"shareAddr": "آدرس اشتراک‌گذاری سفارشی",
"shareAddrHelp": "فقط زمانی استفاده می‌شود که راهبرد آدرس اشتراک‌گذاری روی سفارشی باشد. میزبان یا IP را بدون طرح و پورت وارد کنید.",
"subSortIndex": "ترتیب در اشتراک",
"subSortIndexHelp": "جایگاه لینک‌های این ورودی در خروجی اشتراک (صفحه اشتراک و برنامه‌های کلاینت). مقدار کمتر اول می‌آید و مقدارهای برابر ترتیب ایجاد را حفظ می‌کنند. روی فهرست ورودی‌های پنل تأثیری ندارد.",
"shareAddrStrategyOptions": {
"node": "آدرس نود",
"listen": "آدرس شنود ورودی",
"custom": "سفارشی"
}
},
"info": {
"mode": "حالت",
"grpcServiceName": "grpc serviceName",
"grpcMultiMode": "grpc multiMode",
"interfaceName": "نام رابط",
"mtu": "MTU",
"gateway": "Gateway",
"dns": "DNS",
"outboundsInterface": "رابط خروجی",
"autoSystemRoutes": "مسیریابی خودکار سیستم",
"followRedirect": "FollowRedirect",
"auth": "احراز",
"noKernelTun": "TUN غیرکرنل",
"keepAlive": "Keep alive",
"peerNumber": "Peer {n}",
"peerNumberConfig": "پیکربندی Peer {n}"
},
"stream": {
"general": {
"request": "درخواست",
"response": "پاسخ",
"name": "نام",
"value": "مقدار"
},
"tcp": {
"version": "نسخه",
"method": "متد",
"path": "مسیر",
"status": "وضعیت",
"statusDescription": "توضیحات وضعیت",
"requestHeader": "سربرگ درخواست",
"responseHeader": "سربرگ پاسخ"
}
},
"sniffingDestOverride": "بازنویسی مقصد"
},
"clients": {
"tabBasics": "پایه",
"tabCredentials": "اطلاعات اتصال",
"tabLinks": "لینک‌ها",
"wireguardConfig": "پیکربندی WireGuard",
"config": "پیکربندی",
"linksHint": "لینک‌های اشتراک شخص‌ثالث و آدرس سابسکریپشن‌های خارجی را اضافه کنید تا در سابسکریپشن این کاربر قرار گیرند.",
"addExternalLink": "افزودن لینک خارجی",
"addExternalSubscription": "افزودن سابسکریپشن خارجی",
"noExternalLinks": "هنوز لینک خارجی‌ای اضافه نشده.",
"noExternalSubscriptions": "هنوز سابسکریپشن خارجی‌ای اضافه نشده.",
"add": "افزودن کلاینت",
"edit": "ویرایش کلاینت",
"submitAdd": "افزودن کلاینت",
"submitEdit": "ذخیره تغییرات",
"clientCount": "تعداد کلاینت‌ها",
"bulk": "افزودن گروهی",
"copyFromInbound": "کپی کلاینت‌ها از اینباند",
"copyToInbound": "کپی کلاینت‌ها به",
"copySelected": "کپی انتخاب‌شده‌ها",
"copySource": "منبع",
"copyEmailPreview": "پیش‌نمایش ایمیل خروجی",
"copySelectSourceFirst": "ابتدا یک اینباند مبدأ انتخاب کنید.",
"copyResult": "نتیجه کپی",
"copyResultSuccess": "با موفقیت کپی شد",
"copyResultNone": "چیزی برای کپی نیست: کلاینتی انتخاب نشده یا منبع خالی است",
"copyResultErrors": "خطاهای کپی",
"copyFlowLabel": "Flow برای کلاینت‌های جدید (VLESS)",
"copyFlowHint": "روی همه کلاینت‌های کپی‌شده اعمال می‌شود. خالی بگذارید تا رد شود.",
"selectAll": "انتخاب همه",
"clearAll": "پاک کردن همه",
"method": "روش",
"first": "اول",
"last": "آخر",
"ipLog": "گزارش IP",
"prefix": "پیشوند",
"postfix": "پسوند",
"delayedStart": "شروع پس از اولین استفاده",
"expireDays": "مدت اعتبار (روز)",
"days": "روز",
"renew": "تمدید خودکار",
"renewDesc": "تمدید خودکار پس از انقضا. (۰ = غیرفعال) (واحد: روز)",
"renewDays": "تمدید خودکار (روز)",
"searchPlaceholder": "جستجوی ایمیل، توضیح، Sub ID، UUID، رمز، احراز، Telegram ID...",
"filterTitle": "فیلتر کاربران",
"clearAllFilters": "پاک کردن همه",
"filters": {
"nodes": "نودها",
"localPanel": "محلی (همین پنل)"
},
"showingCount": "نمایش {shown} از {total}",
"sortOldest": "قدیمی‌ترین",
"sortNewest": "جدیدترین",
"sortRecentlyUpdated": "اخیراً به‌روزشده",
"sortRecentlyOnline": "اخیراً آنلاین",
"sortEmailAZ": "ایمیل ا→ی",
"sortEmailZA": "ایمیل ی→ا",
"sortMostTraffic": "بیشترین ترافیک",
"sortHighestRemaining": "بیشترین باقی‌مانده",
"sortExpiringSoonest": "نزدیک‌ترین انقضا",
"has": "دارد",
"hasNot": "ندارد",
"title": "کلاینت‌ها",
"actions": "عملیات",
"totalGB": "سقف حجم (گیگابایت)",
"totalGBDesc": "سهمیه‌ی حجم مصرفی کلاینت. ۰ = نامحدود",
"expiryTime": "انقضا",
"addClients": "افزودن کلاینت‌ها",
"limitIp": "محدودیت IP",
"limitIpDesc": "حداکثر تعداد IP همزمان. ۰ = نامحدود",
"limitIpFail2banMissing": "Fail2ban نصب نشده است، بنابراین محدودیت IP اعمال نمی‌شود. برای فعال‌سازی این گزینه، Fail2ban را از منوی بش x-ui نصب کنید.",
"limitIpFail2banWindows": "Fail2ban روی ویندوز در دسترس نیست، بنابراین محدودیت IP قابل اعمال نیست.",
"limitIpDisabled": "قابلیت محدودیت IP روی این سرور غیرفعال است.",
"password": "رمز عبور",
"passwordDesc": "فقط توسط کلاینت‌های Trojan و Shadowsocks استفاده می‌شود؛ برای VLESS، VMess، Hysteria و WireGuard نادیده گرفته می‌شود.",
"subId": "شناسه اشتراک",
"online": "آنلاین",
"email": "ایمیل",
"emailInvalidChars": "ایمیل نمی‌تواند شامل فاصله، '/'، '\\' یا کاراکترهای کنترلی باشد",
"subIdInvalidChars": "شناسه‌ی اشتراک نمی‌تواند شامل فاصله، '/'، '\\' یا کاراکترهای کنترلی باشد",
"group": "گروه",
"groupDesc": "برچسبی منطقی برای دسته‌بندی کاربران مرتبط (مثل تیم، مشتری، منطقه). از نوار ابزار قابل فیلتر است.",
"groupPlaceholder": "مثلاً customer-a",
"comment": "توضیحات",
"traffic": "ترافیک",
"speed": "سرعت",
"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": "لینک‌های اشتراک ({count})",
"addToGroupTitle": "افزودن {count} کاربر به یک گروه",
"addToGroupTooltip": "یک گروه موجود را انتخاب کنید یا نام جدیدی تایپ کنید. برای حذف کاربران از گروه فعلی، از Ungroup استفاده کنید.",
"groupName": "نام گروه",
"addToGroupSuccessToast": "{count} کاربر به {group} اضافه شد",
"ungroupSuccessToast": "گروه از {count} کاربر پاک شد",
"ungroup": "خارج از گروه",
"ungroupConfirmTitle": "حذف {count} کاربر از گروهشان؟",
"ungroupConfirmContent": "برچسب گروه را روی هر کاربر انتخابی پاک می‌کند. کاربران حفظ می‌شوند (برای حذف کامل از Delete استفاده کنید).",
"addToGroup": "افزودن به گروه",
"attach": "الصاق",
"adjust": "تنظیم",
"subLinks": "لینک‌های اشتراک",
"enable": "فعال‌سازی",
"disable": "غیرفعال‌سازی",
"bulkEnableConfirmTitle": "{count} کلاینت فعال شوند؟",
"bulkEnableConfirmContent": "هر کلاینت انتخاب‌شده روی تمام اینباندهای متصل فعال می‌شود. کلاینت‌هایی که سهمیه آن‌ها تمام شده یا تاریخ انقضایشان گذشته، به‌طور خودکار دوباره غیرفعال می‌شوند.",
"bulkDisableConfirmTitle": "{count} کلاینت غیرفعال شوند؟",
"bulkDisableConfirmContent": "هر کلاینت انتخاب‌شده روی تمام اینباندهای متصل غیرفعال می‌شود. دسترسی آن‌ها بلافاصله قطع می‌شود اما رکورد و ترافیکشان حفظ می‌گردد.",
"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": "لینک‌های اشتراک ({count})",
"subLinkColumn": "آدرس اشتراک",
"subJsonLinkColumn": "آدرس JSON اشتراک",
"subLinksCopyAll": "کپی همه",
"subLinksCopiedAll": "{count} لینک کپی شد",
"subLinksEmpty": "هیچ‌کدام از کاربران انتخابی شناسه اشتراک ندارند.",
"subLinksDisabled": "سرویس اشتراک غیرفعال است.",
"subLinksDisabledHint": "برای ساخت لینک، اشتراک را در تنظیمات پنل ← اشتراک فعال کنید.",
"bulkDeleteConfirmTitle": "حذف {count} کلاینت؟",
"bulkDeleteConfirmContent": "هر کلاینت انتخاب‌شده از تمام اینباندهای متصل حذف و سابقه ترافیک آن پاک می‌شود. این عمل غیرقابل بازگشت است.",
"bulkAdjustTitle": "تنظیم {count} کلاینت",
"bulkAdjustHint": "مقادیر مثبت اضافه و منفی کم می‌کنند. کلاینت‌هایی که زمان یا ترافیک نامحدود دارند برای همان فیلد رد می‌شوند.",
"bulkAdjustNothing": "قبل از اعمال، روز یا ترافیک را تنظیم کنید.",
"addDays": "افزودن روز",
"addTrafficGB": "افزودن ترافیک (گیگابایت)",
"bulkFlow": "تنظیم flow",
"bulkFlowNoChange": "بدون تغییر",
"bulkFlowDisable": "غیرفعال (پاک کردن flow)",
"delDepleted": "حذف اتمام‌یافته‌ها",
"delDepletedConfirmTitle": "حذف کلاینت‌های اتمام‌یافته؟",
"delDepletedConfirmContent": "هر کلاینتی که سهمیه ترافیک‌اش تمام شده یا تاریخ انقضایش گذشته است حذف می‌شود. این عمل غیرقابل بازگشت است.",
"exportClients": "خروجی گرفتن از کلاینت‌ها",
"importClients": "ورود کلاینت‌ها",
"import": "ورود",
"delOrphans": "حذف کلاینت‌های بدون اینباند",
"delOrphansConfirmTitle": "حذف کلاینت‌های بدون اینباند؟",
"delOrphansConfirmContent": "هر کلاینتی که به هیچ اینباندی متصل نیست، همراه با رکورد ترافیک‌اش حذف می‌شود. این عمل غیرقابل بازگشت است.",
"auth": "احراز",
"hysteriaAuth": "احراز Hysteria",
"hysteriaAuthDesc": "اعتباری که فقط کلاینت‌های Hysteria از آن استفاده می‌کنند. Trojan و Shadowsocks به‌جای آن از فیلد «رمز عبور» استفاده می‌کنند.",
"uuid": "UUID",
"flow": "Flow",
"vmessSecurity": "امنیت VMess",
"wireguardPrivateKey": "کلید خصوصی وایرگارد",
"wireguardPublicKey": "کلید عمومی وایرگارد",
"wireguardPreSharedKey": "کلید پیش‌اشتراکی وایرگارد",
"wireguardAllowedIPs": "آی‌پی‌های مجاز وایرگارد",
"wireguardAllowedIPsHint": "برای تخصیص خودکار خالی بگذارید؛ ورودی‌ها را با کاما جدا کنید",
"mtprotoSecret": "سکرت MTProto",
"mtprotoSecretHint": "سکرت FakeTLS این کلاینت. برای تعویض، دوباره تولید کنید.",
"mtprotoAdTag": "برچسب تبلیغاتی (کانال حامی)",
"mtprotoAdTagHint": "برچسب هگزادسیمال اختیاری ۳۲ کاراکتری که هنگام ثبت پروکسی در تلگرام دریافت می‌شود. با تنظیم آن، این کلاینت از طریق پروکسی‌های میانی تلگرام هدایت می‌شود و یک کانال حامی در بالای فهرست گفتگوهایش نمایش داده می‌شود.",
"reverseTag": "تگ معکوس",
"reverseTagPlaceholder": "Reverse tag اختیاری",
"telegramId": "شناسه کاربر تلگرام",
"telegramIdPlaceholder": "شناسه عددی کاربر تلگرام (۰ = هیچ)",
"created": "ساخته‌شده",
"updated": "به‌روزشده",
"ipLimit": "محدودیت IP",
"toasts": {
"deleted": "کلاینت حذف شد",
"trafficReset": "ترافیک بازنشانی شد",
"allTrafficsReset": "ترافیک همه کلاینت‌ها بازنشانی شد",
"bulkDeleted": "{count} کلاینت حذف شد",
"bulkDeletedMixed": "{ok} حذف، {failed} ناموفق",
"bulkEnabled": "{count} کلاینت فعال شد",
"bulkEnabledMixed": "{ok} فعال، {failed} ناموفق",
"bulkDisabled": "{count} کلاینت غیرفعال شد",
"bulkDisabledMixed": "{ok} غیرفعال، {failed} ناموفق",
"bulkCreated": "{count} کلاینت ساخته شد",
"bulkCreatedMixed": "{ok} ساخته شد، {failed} ناموفق",
"bulkAdjusted": "{count} کلاینت تنظیم شد",
"bulkAdjustedMixed": "{ok} تنظیم، {skipped} رد شد",
"delDepleted": "{count} کلاینت اتمام‌یافته حذف شد",
"delOrphans": "{count} کلاینت بدون اینباند حذف شد",
"imported": "{count} کلاینت وارد شد",
"importedMixed": "{ok} وارد شد، {failed} رد شد"
}
},
"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": "این فقط شمارنده‌ی ترافیک گروه را صفر می‌کند؛ شمارنده‌ی تک‌تک کاربران دست‌نخورده می‌ماند.",
"resetSuccess": "ترافیک گروه {name} صفر شد.",
"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 انتخاب‌شده مسیریابی کنید. یک inbound پل loopback به‌صورت خودکار به پیکربندی در حال اجرا اضافه شده و به‌صورت زنده اعمال می‌شود. برای اتصال مستقیم خالی بگذارید.",
"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": "هر نود انتخاب‌شده آخرین نسخه را دانلود و روی آن ری‌استارت می‌شود. فقط نودهای فعال و آنلاین به‌روزرسانی می‌شوند.",
"updateDevChannel": "به‌روزرسانی به کانال دِو (آخرین کامیت)",
"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 نود را چطور بررسی کند. Pin یا Skip برای گواهی‌های self-signed است (فقط نودهای https).",
"tlsVerify": "اعتبارسنجی (CA پیش‌فرض)",
"tlsPin": "Pin گواهی (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 ممکن است شنود شود. ترجیحاً به‌جای آن گواهی را Pin کنید.",
"pinnedCert": "SHA-256 گواهیِ Pin‌شده",
"pinnedCertHint": "SHA-256 گواهیِ نود به‌صورت base64 یا hex. برای خواندنِ همین حالا از نود، از دکمهٔ Fetch استفاده کنید.",
"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": "ربات تلگرام",
"panelListeningIP": "آدرس آی‌پی",
"panelListeningIPDesc": "آدرس آی‌پی برای وب پنل. برای گوش‌دادن به‌تمام آی‌پی‌ها خالی‌بگذارید",
"panelListeningDomain": "نام دامنه",
"panelListeningDomainDesc": "آدرس دامنه برای وب پنل. برای گوش دادن به‌تمام دامنه‌ها و آی‌پی‌ها خالی‌بگذارید",
"panelPort": "پورت",
"panelPortDesc": "شماره پورت برای وب پنل. باید پورت استفاده نشده‌باشد",
"publicKeyPath": "مسیر کلید عمومی",
"publicKeyPathDesc": "مسیر فایل کلیدعمومی برای وب پنل. با '/' شروع‌می‌شود",
"privateKeyPath": "مسیر کلید خصوصی",
"privateKeyPathDesc": "مسیر فایل کلیدخصوصی برای وب پنل. با '/' شروع‌می‌شود",
"panelUrlPath": "مسیر URI",
"panelUrlPathDesc": "برای وب پنل. با '/' شروع‌ و با '/' خاتمه‌ می‌یابد URI مسیر",
"pageSize": "اندازه صفحه بندی جدول",
"pageSizeDesc": "(اندازه صفحه برای جدول ورودی‌ها.(0 = غیرفعال",
"panelOutbound": "اوتباند ترافیک پنل",
"panelOutboundDesc": "درخواست‌های خود پنل — بررسی نسخه و دانلود پنل/Xray، تلگرام، و به‌روزرسانی معمولی فایل‌های geo — را از این اوتباند Xray عبور می‌دهد تا فیلترینگ GitHub/تلگرام در سمت سرور دور زده شود. یک ورودی پل لوکال به‌صورت خودکار به کانفیگ در حال اجرا اضافه و زنده اعمال می‌شود. روی Geodata Auto-Update نِیتیو Xray اثری ندارد؛ آن اوتباند دانلود مخصوص خودش را دارد. برای اتصال مستقیم خالی بگذارید.",
"panelOutboundPh": "اتصال مستقیم",
"remarkTemplate": "قالب ریمارک",
"remarkTemplateDesc": "اگر پر شود، جای مدلِ ریمارک را برای همه‌ی لینک‌های اشتراک می‌گیرد — فرمت دلخواهت را با توکن‌های متغیر بنویس (از دکمه برای درج استفاده کن). خالی = استفاده از مدلِ بالا.",
"datepicker": "نوع تقویم",
"datepickerPlaceholder": "انتخاب تاریخ",
"datepickerDescription": "وظایف برنامه ریزی شده بر اساس این تقویم اجرا می‌شود",
"oldUsername": "نام‌کاربری فعلی",
"currentPassword": "رمز‌عبور فعلی",
"newUsername": "نام‌کاربری جدید",
"newPassword": "رمزعبور جدید",
"telegramBotEnable": "فعال‌سازی ربات تلگرام",
"telegramBotEnableDesc": "ربات تلگرام را فعال می‌کند",
"telegramToken": "توکن تلگرام",
"telegramTokenDesc": "دریافت کنید {'@'}botfather توکن را می‌توانید از",
"telegramProxy": "پراکسی SOCKS",
"telegramProxyDesc": "را برای اتصال به تلگرام فعال می کند SOCKS5 پراکسی",
"telegramAPIServer": "سرور API تلگرام",
"telegramAPIServerDesc": "API سرور تلگرام برای اتصال را تغییر میدهد. برای استفاده از سرور پیش فرض خالی بگذارید",
"telegramChatId": "آی‌دی چت مدیر",
"telegramChatIdDesc": "دریافت ‌کنید ('/id'یا (دستور ({'@'}userinfobot) آی‌دی(های) چت تلگرام مدیر، از",
"telegramNotifyTime": "زمان نوتیفیکیشن",
"telegramNotifyTimeDesc": "هر چند وقت یک‌بار ربات تلگرام گزارش دوره‌ای بفرستد. یک بازهٔ آماده انتخاب کنید یا گزینهٔ سفارشی را بزنید تا عبارت crontab وارد کنید.",
"notifyTime": {
"every": "@every — تکرار در یک بازه",
"hourly": "@hourly — هر ساعت",
"daily": "@daily — هر روز ساعت ۰۰:۰۰",
"weekly": "@weekly — هر هفته",
"monthly": "@monthly — هر ماه",
"custom": "سفارشی (crontab)",
"seconds": "ثانیه",
"minutes": "دقیقه",
"hours": "ساعت",
"interval": "بازه زمانی",
"unit": "واحد"
},
"tgNotifyBackup": "پشتیبان‌گیری از دیتابیس",
"tgNotifyBackupDesc": "فایل پشتیبان‌دیتابیس را به‌همراه گزارش ارسال می‌کند",
"tgNotifyLogin": "اعلان ورود",
"tgNotifyLoginDesc": "نام‌کاربری، آدرس آی‌پی، و زمان ورود، فردی که سعی می‌کند وارد پنل شود را نمایش می‌دهد",
"sessionMaxAge": "بیشینه زمان جلسه وب",
"sessionMaxAgeDesc": "(بیشینه زمانی که می‌توانید لاگین بمانید. (واحد: دقیقه",
"expireTimeDiff": "آستانه زمان باقی مانده",
"expireTimeDiffDesc": "(فاصله زمانی هشدار تا رسیدن به زمان انقضا. (واحد: روز",
"trafficDiff": "آستانه ترافیک باقی مانده",
"trafficDiffDesc": "(فاصله زمانی هشدار تا رسیدن به اتمام ترافیک. (واحد: گیگابایت",
"tgNotifyCpu": "آستانه هشدار بار پردازنده",
"tgNotifyCpuDesc": "(اگر بار روی پردازنده ازاین آستانه فراتر رفت، برای شما پیام ارسال می‌شود. (واحد: درصد",
"timeZone": "منطقه زمانی",
"timeZoneDesc": "وظایف برنامه ریزی شده بر اساس این منطقه‌زمانی اجرا می‌شود",
"subSettings": "سابسکریپشن",
"subEnable": "فعال‌سازی سرویس سابسکریپشن",
"subEnableDesc": "سرویس سابسکریپشن‌ را فعال‌می‌کند",
"subJsonEnable": "فعال/غیرفعال‌سازی مستقل نقطه دسترسی سابسکریپشن JSON.",
"subJsonEnableTitle": "اشتراک JSON",
"subClashEnableTitle": "اشتراک Clash / Mihomo",
"subFormatsTipTitle": "تنظیمات اشتراک ویژه هر قالب",
"subFormatsTipDesc": "مسیرهای URL، آدرس‌های معکوس و تشخیص خودکار کلاینت را برای JSON و Clash / Mihomo جداگانه پیکربندی کنید.",
"subFormatsTipAction": "باز کردن قالب‌های اشتراک",
"subJsonAutoDetect": "تشخیص خودکار کلاینت‌های Xray JSON",
"subJsonAutoDetectDesc": "با فعال‌سازی، کلاینت‌های سازگار و شناخته‌شده که آدرس استاندارد اشتراک را درخواست می‌کنند، به‌طور خودکار آرایه تنظیمات Xray JSON دریافت می‌کنند. سایر کلاینت‌ها پاسخ خام/Base64 را دریافت می‌کنند. برای اعمال تغییر، اشتراک JSON باید فعال باشد و پنل راه‌اندازی مجدد شود.",
"subJsonAlwaysArray": "همیشه آرایه JSON برگردان",
"subJsonAlwaysArrayDesc": "مسیر صریح اشتراک JSON را حتی برای یک پروفایل، مطابق استاندارد XTLS به‌صورت آرایه برمی‌گرداند. پاسخ‌های JSON تشخیص‌داده‌شده همیشه آرایه هستند. برای حفظ پاسخ قدیمی تک‌شیء غیرفعال بگذارید.",
"subJsonUserAgentRegex": "عبارت User-Agent برای Xray JSON",
"subJsonUserAgentRegexDesc": "عبارت منظم Go RE2 که با عامل کاربر (User-Agent) کلاینت مطابقت داده می‌شود تا صیغه Xray JSON روی آدرس استاندارد اشتراک به‌طور خودکار انتخاب شود. به‌طور پیش‌فرض خالی است، بنابراین تشخیص خودکار غیرفعال می‌ماند تا زمانی که الگویی برای کلاینت‌های موردنظر خود تعیین کنید. سایر کلاینت‌ها پاسخ خام/Base64 را دریافت می‌کنند. پس از تغییر، پنل را راه‌اندازی مجدد کنید.",
"subClashAutoDetect": "تشخیص خودکار کلاینت‌های Clash/Mihomo",
"subClashAutoDetectDesc": "با فعال‌سازی، کلاینت‌های شناخته‌شده Clash/Mihomo که آدرس استاندارد اشتراک را درخواست می‌کنند، به‌طور خودکار پیکربندی Clash با فرمت YAML دریافت می‌کنند. مرورگرها همچنان صفحه اشتراک را نمایش می‌دهند، سایر کلاینت‌ها پاسخ خام/Base64 را دریافت می‌کنند و آدرس‌های صریح JSON و Clash در دسترس می‌مانند. برای اعمال تغییر، اشتراک Clash/Mihomo باید فعال باشد و پنل راه‌اندازی مجدد شود.",
"subClashUserAgentRegex": "عبارت User-Agent برای Clash/Mihomo",
"subClashUserAgentRegexDesc": "عبارت منظم Go RE2 که با عامل کاربر (User-Agent) کلاینت مطابقت داده می‌شود تا کلاینت‌های Clash/Mihomo در آدرس استاندارد اشتراک شناسایی شوند. برای استفاده از الگوی پیش‌فرض خالی بگذارید. پس از تغییر، پنل را راه‌اندازی مجدد کنید.",
"subTitle": "عنوان اشتراک",
"subTitleDesc": "عنوان نمایش داده شده در کلاینت VPN",
"subSupportUrl": "آدرس پشتیبانی",
"subSupportUrlDesc": "لینک پشتیبانی فنی که در کلاینت VPN نمایش داده می‌شود",
"subProfileUrl": "آدرس پروفایل",
"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)",
"subHideSettings": "پنهان کردن تنظیمات سرور",
"subHideSettingsDesc": "پنهان کردن توانایی مشاهده و ویرایش پیکربندی سرور در کلاینت VPN. (فقط برای Happ)",
"subIncyEnableRouting": "فعال‌سازی مسیریابی",
"subIncyEnableRoutingDesc": "تزریق پروفایل مسیریابی به بدنه اشتراک برای کلاینت Incy. (فقط برای Incy)",
"subIncyRoutingRules": "قوانین مسیریابی",
"subIncyRoutingRulesDesc": "لینک مسیریابی Incy که به بدنه اشتراک افزوده می‌شود، مثلاً incy://routing/onadd/<base64>. (فقط برای Incy)",
"subClashEnableRouting": "فعال‌سازی مسیریابی",
"subClashEnableRoutingDesc": "قوانین مسیریابی سراسری Clash/Mihomo را در اشتراک‌های YAML تولیدشده وارد کن.",
"subClashRoutingRules": "قوانین مسیریابی سراسری",
"subClashRoutingRulesDesc": "قوانین Clash/Mihomo که پیش از MATCH,PROXY به ابتدای هر اشتراک YAML افزوده می‌شوند.",
"subListen": "آدرس آی‌پی",
"subListenDesc": "آدرس آی‌پی برای سرویس سابسکریپشن. برای گوش دادن به‌تمام آی‌پی‌ها خالی‌بگذارید",
"subPort": "پورت",
"subPortDesc": "شماره پورت برای سرویس سابسکریپشن. باید پورت استفاده‌نشده‌باشد. همچنین وقتی «مسیر پراکسی معکوس» خالی باشد، برای ساخت لینک/QR سابسکریپشن نمایش‌داده‌شده در پنل استفاده می‌شود — اگر سابسکریپشن از پشت یک پراکسی معکوس روی پورت دیگری در دسترس است، به جای این، «مسیر پراکسی معکوس» را پر کنید.",
"subCertPath": "مسیر کلید عمومی",
"subCertPathDesc": "مسیر فایل کلیدعمومی برای سرویس سابیکریپشن. با '/' شروع‌می‌شود",
"subKeyPath": "مسیر کلید خصوصی",
"subKeyPathDesc": "مسیر فایل کلیدخصوصی برای سرویس سابسکریپشن. با '/' شروع‌می‌شود",
"subPath": "مسیر URI",
"subPathDesc": "برای سرویس سابسکریپشن. با '/' شروع‌ و با '/' خاتمه‌ می‌یابد URI مسیر",
"subDomain": "نام دامنه",
"subDomainDesc": "آدرس دامنه برای سرویس سابسکریپشن. برای گوش دادن به تمام دامنه‌ها و آی‌پی‌ها خالی‌بگذارید. همچنین وقتی «مسیر پراکسی معکوس» خالی باشد، به عنوان دامنه پیش‌فرض لینک سابسکریپشن نمایش‌داده‌شده استفاده می‌شود — اگر پنل و سابسکریپشن از دامنه‌های متفاوتی در دسترس هستند (مثلاً پشت یک پراکسی معکوس)، «مسیر پراکسی معکوس» را پر کنید.",
"subUpdates": "فاصله بروزرسانی‌ سابسکریپشن",
"subUpdatesDesc": "(فاصله مابین بروزرسانی در برنامه‌های کاربری. (واحد: ساعت",
"subEncrypt": "انکود",
"subEncryptDesc": "کدگذاری خواهدشد Base64 محتوای برگشتی سرویس سابسکریپشن برپایه",
"subURI": "پروکسی معکوس URI مسیر",
"subURIDesc": "آدرس پایه کامل (scheme://domain[:port]/path/) برای لینک سابسکریپشن و کد QR، به جای نام دامنه/پورت استفاده می‌شود. هر وقت سابسکریپشن از پشت یک پراکسی معکوس یا روی دامنه/پورت متفاوتی نسبت به موارد بالا در دسترس است، این را پر کنید.",
"externalTrafficInformEnable": "اطلاع رسانی خارجی مصرف ترافیک",
"externalTrafficInformEnableDesc": "به API خارجی در هر به‌روزرسانی ترافیک اطلاع بده.",
"externalTrafficInformURI": "لینک اطلاع رسانی خارجی مصرف ترافیک",
"externalTrafficInformURIDesc": "ترافیک های مصرفی به این لینک هم ارسال می شود",
"restartXrayOnClientDisable": "ری‌استارت Xray بعد از غیرفعال‌سازی خودکار",
"restartXrayOnClientDisableDesc": "وقتی کاربر به‌صورت خودکار به‌دلیل اتمام زمان یا ترافیک غیرفعال می‌شود، Xray ری‌استارت شود.",
"fragment": "فرگمنت",
"fragmentDesc": "فعال کردن فرگمنت برای بسته‌ی نخست تی‌ال‌اس",
"fragmentSett": "تنظیمات فرگمنت",
"noisesDesc": "فعال کردن Noises.",
"noisesSett": "تنظیمات Noises",
"trustedProxyCidrs": "CIDRهای پراکسی مورد اعتماد",
"trustedProxyCidrsDesc": "IPها/CIDRها (با کاما) که مجازند هدرهای host، proto و client IP فوروارد را تنظیم کنند.",
"ldap": {
"enable": "فعال‌سازی همگام‌سازی LDAP",
"host": "میزبان LDAP",
"port": "پورت LDAP",
"useTls": "استفاده از TLS (LDAPS)",
"skipTlsVerify": "رد کردن تأیید گواهی TLS",
"skipTlsVerifyDesc": "ناامن — اعتبارسنجی گواهی سرور را غیرفعال می‌کند. فقط برای CAهای داخلی/غیرمعتبر استفاده کنید.",
"bindDn": "Bind DN",
"passwordConfigured": "تنظیم‌شده؛ برای حفظ رمز فعلی خالی بگذارید.",
"passwordUnconfigured": "تنظیم نشده.",
"passwordPlaceholder": "تنظیم‌شده – برای جایگزینی مقدار جدید وارد کنید",
"baseDn": "Base DN",
"userFilter": "فیلتر کاربر",
"userAttr": "صفت کاربر (username/email)",
"vlessField": "صفت پرچم VLESS",
"flagField": "صفت پرچم عمومی (اختیاری)",
"flagFieldDesc": "اگر تعیین شود، پرچم VLESS را override می‌کند — مثل shadowInactive.",
"truthyValues": "مقادیر صحیح",
"truthyValuesDesc": "با کاما جدا شده؛ پیش‌فرض: true,1,yes,on",
"invertFlag": "وارونگی پرچم",
"invertFlagDesc": "وقتی صفت به معنی «غیرفعال» است فعال کنید (مثل shadowInactive).",
"syncSchedule": "زمان‌بندی همگام‌سازی",
"syncScheduleDesc": "رشته شبیه cron، مثل @every 1m",
"inboundTags": "تگ‌های ورودی",
"inboundTagsDesc": "ورودی‌هایی که همگام‌سازی LDAP اجازه دارد روی آن‌ها کاربر بسازد یا حذف کند.",
"noInbounds": "هیچ ورودی یافت نشد. ابتدا از بخش ورودی‌ها یکی بسازید.",
"autoCreate": "ساخت خودکار کاربران",
"autoDelete": "حذف خودکار کاربران",
"defaultTotalGb": "حجم پیش‌فرض (GB)",
"defaultExpiryDays": "انقضای پیش‌فرض (روز)",
"defaultIpLimit": "محدودیت IP پیش‌فرض"
},
"subFormats": {
"finalMask": "Final Mask",
"finalMaskDesc": "ماسک‌های TCP/UDP مربوط به Xray finalmask و پارامترهای QUIC را به هر پروفایل Xray JSON تولیدشده اضافه می‌کند. به برنامه‌ای با پشتیبانی از اشتراک Xray JSON و هسته جدید Xray نیاز دارد.",
"packets": "بسته‌ها",
"length": "طول",
"interval": "بازه",
"maxSplit": "حداکثر تقسیم",
"noises": "نویزها",
"noiseItem": "نویز №{n}",
"type": "نوع",
"packet": "بسته",
"delayMs": "تأخیر (ms)",
"applyTo": "اعمال بر",
"addNoise": "+ نویز",
"concurrency": "هم‌زمانی",
"xudpConcurrency": "هم‌زمانی xudp",
"xudpUdp443": "xudp UDP 443"
},
"mux": "Mux",
"muxDesc": "چندین جریان داده مستقل را در یک جریان داده ثابت منتقل می کند",
"muxSett": "تنظیمات ماکس",
"direct": "اتصال مستقیم",
"directDesc": "به طور مستقیم با دامنه ها یا محدوده آی‌پی یک کشور خاص ارتباط برقرار می کند",
"notifications": "اعلان‌ها",
"certs": "گواهی‌ها",
"externalTraffic": "ترافیک خارجی",
"dateAndTime": "تاریخ و زمان",
"proxyAndServer": "پراکسی و سرور",
"intervals": "فواصل",
"information": "اطلاعات",
"profile": "پروفایل",
"language": "زبان",
"telegramBotLanguage": "زبان ربات تلگرام",
"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 (پیش‌فرض: ۵۸۷)",
"smtpUsername": "نام‌کاربری SMTP",
"smtpUsernameDesc": "نام‌کاربری احراز هویت SMTP",
"smtpFrom": "آدرس فرستنده (From)",
"smtpFromDesc": "آدرس استفاده‌شده در سرآیند From ایمیل. برای استفاده از نام کاربری، خالی بگذارید.",
"smtpFromName": "نام فرستنده (From)",
"smtpFromNameDesc": "نام نمایشی اختیاری پیش از آدرس در سرآیند From.",
"smtpPassword": "رمز عبور SMTP",
"smtpPasswordDesc": "رمز عبور احراز هویت SMTP",
"smtpTo": "گیرندگان",
"smtpToDesc": "آدرس‌های ایمیل گیرندگان، جداشده با کاما",
"emailSettings": "ایمیل",
"emailNotifications": "اعلان‌ها",
"smtpEventBusNotify": "اعلان‌های رویداد ایمیلی",
"smtpEventBusNotifyDesc": "انتخاب کنید کدام رویدادها اعلان ایمیلی را فعال می‌کنند",
"tgEventBusNotify": "اعلان‌های رویداد تلگرام",
"tgEventBusNotifyDesc": "انتخاب کنید کدام رویدادها اعلان تلگرام را فعال می‌کنند",
"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": "هیچ گیرنده‌ای پیکربندی نشده است",
"smtpFromNotConfigured": "آدرس فرستنده SMTP پیکربندی نشده است",
"eventLoginAttempt": "تلاش برای ورود",
"telegramTokenConfigured": "پیکربندی شده؛ برای حفظ توکن فعلی خالی بگذارید.",
"telegramTokenPlaceholder": "پیکربندی شده - برای جایگزینی، توکن جدید وارد کنید",
"smtpPasswordConfigured": "پیکربندی شده؛ برای حفظ رمز عبور فعلی خالی بگذارید.",
"smtpPasswordPlaceholder": "پیکربندی شده - برای جایگزینی، رمز عبور جدید وارد کنید",
"smtpNotInitialized": "SMTP مقداردهی اولیه نشده است",
"tgBotNotEnabled": "ربات تلگرام فعال نیست",
"tgTestFailed": "آزمایش تلگرام ناموفق بود",
"tgTestSuccess": "پیام آزمایشی به تلگرام ارسال شد",
"tgBotNotRunning": "ربات تلگرام در حال اجرا نیست",
"smtpErrorAuth": "احراز هویت ناموفق بود — نام‌کاربری و رمز عبور را بررسی کنید",
"smtpErrorStarttls": "سرور به STARTTLS نیاز دارد — نوع رمزنگاری را تغییر دهید",
"smtpErrorTls": "سرور به TLS نیاز دارد — نوع رمزنگاری را تغییر دهید",
"smtpErrorRefused": "اتصال رد شد — میزبان و پورت را بررسی کنید",
"smtpErrorTimeout": "مهلت اتصال به پایان رسید — میزبان در دسترس نیست",
"smtpErrorRelay": "سرور ارسال از این آدرس را رد می‌کند",
"smtpErrorEof": "اتصال توسط سرور بسته شد",
"smtpErrorUnknown": "خطای SMTP: {{ .Error }}",
"eventMemoryHigh": "مصرف حافظه بالا (%)",
"validation": {
"pathLeadingSlash": "مسیر باید با / شروع شود"
},
"secretClear": "پاک کردن",
"secretClearUndo": "لغو پاک کردن"
},
"xray": {
"title": "پیکربندی ایکس‌ری",
"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": "مسدود کردن آی‌پی‌ها",
"blockdomains": "مسدود کردن دامنه‌ها",
"directips": "آی‌پی‌های مستقیم",
"directdomains": "دامنه‌های مستقیم",
"ipv4Routing": "IPv4 مسیریابی",
"ipv4RoutingDesc": "این گزینه‌ها ترافیک را از طریق آی‌پی نسخه4 سرور، به مقصد هدایت می‌کند",
"warpRouting": "WARP مسیریابی",
"warpRoutingDesc": "این گزینه‌ها ترافیک‌ را از طریق وارپ کلادفلر به مقصد هدایت می‌کند",
"nordRouting": "مسیریابی NordVPN",
"nordRoutingDesc": "این گزینه‌ها ترافیک را بر اساس مقصد خاص از طریق NordVPN مسیریابی می‌کنند.",
"Template": "‌پیکربندی پیشرفته الگو ایکس‌ری",
"TemplateDesc": "فایل پیکربندی نهایی ایکس‌ری بر اساس این الگو ایجاد می‌شود",
"FreedomStrategy": "Freedom استراتژی پروتکل",
"FreedomStrategyDesc": "تعیین می‌کند Freedom استراتژی خروجی شبکه را برای پروتکل",
"FreedomHappyEyeballs": "Freedom Happy Eyeballs (IPv4/IPv6)",
"FreedomHappyEyeballsDesc": "اتصال دو‌پشته‌ای برای خروجی مستقیم (freedom) — برای سرورهای خروج دارای هر دو IPv4 و IPv6 مفید است.",
"FreedomHappyEyeballsTryDelayDesc": "تعداد میلی‌ثانیه پیش از امتحان خانوادهٔ آدرس دیگر. مقدار 150 تا 250 میلی‌ثانیه نقطهٔ شروع خوبی است.",
"RoutingStrategy": "استراتژی کلی مسیریابی",
"RoutingStrategyDesc": "استراتژی کلی مسیریابی برای حل تمام درخواست‌ها را تعیین می‌کند",
"outboundTestUrl": "آدرس تست خروجی",
"outboundTestUrlDesc": "آدرسی که برای تست اتصال خروجی استفاده می‌شود.",
"Torrent": "مسدودسازی پروتکل بیت‌تورنت",
"Inbounds": "ورودی‌ها",
"InboundsDesc": "پذیرش کلاینت خاص",
"Outbounds": "خروجی‌ها",
"OutboundSubscriptions": "سابسکریپشن‌های خروجی",
"OutboundSubscriptionsDesc": "خروجی‌ها را از آدرس‌های سابسکریپشن راه‌دور (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": "اولویت هر قانون مهم است",
"importRules": "ورود قوانین",
"exportRules": "خروج قوانین",
"importOutbounds": "ورود خروجی‌ها",
"exportOutbounds": "خروج خروجی‌ها",
"importInvalidJson": "JSON نامعتبر — یک آرایه یا یک شیء با کلید متناظر انتظار می‌رود.",
"completeTemplate": "همه",
"logLevel": "سطح گزارش",
"logLevelDesc": "سطح گزارش برای گزارش های خطا، نشان دهنده اطلاعاتی است که باید ثبت شوند.",
"accessLog": "مسیر گزارش",
"accessLogDesc": "مسیر فایل برای گزارش دسترسی. مقدار ویژه «هیچ» گزارش‌های دسترسی را غیرفعال میکند.",
"errorLog": "گزارش خطا",
"errorLogDesc": "مسیر فایل برای ورود به سیستم خطا. مقدار ویژه «هیچ» گزارش های خطا را غیرفعال میکند",
"dnsLog": "گزارش DNS",
"dnsLogDesc": "آیا ثبت‌های درخواست DNS را فعال کنید",
"maskAddress": "پنهان کردن آدرس",
"maskAddressDesc": "پوشش آدرس IP، هنگامی که فعال می‌شود، به طور خودکار آدرس IP که در لاگ ظاهر می‌شود را جایگزین می‌کند.",
"statistics": "آمار",
"statsInboundUplink": "آمار آپلود ورودی",
"statsInboundUplinkDesc": "جمع‌آوری آمار برای ترافیک بالارو (آپلود) تمام پروکسی‌های ورودی را فعال می‌کند.",
"statsInboundDownlink": "آمار دانلود ورودی",
"statsInboundDownlinkDesc": "جمع‌آوری آمار برای ترافیک پایین‌رو (دانلود) تمام پروکسی‌های ورودی را فعال می‌کند.",
"statsOutboundUplink": "آمار آپلود خروجی",
"statsOutboundUplinkDesc": "جمع‌آوری آمار برای ترافیک بالارو (آپلود) تمام پروکسی‌های خروجی را فعال می‌کند.",
"statsOutboundDownlink": "آمار دانلود خروجی",
"statsOutboundDownlinkDesc": "جمع‌آوری آمار برای ترافیک پایین‌رو (دانلود) تمام پروکسی‌های خروجی را فعال می‌کند.",
"metricsListen": "نقطه پایانی متریک",
"metricsListenDesc": "متریک‌های Xray (سبک Prometheus) را روی این آدرس:پورت در دسترس قرار می‌دهد (مثلاً 127.0.0.1:11111). برای غیرفعال‌کردن خالی بگذارید. روی localhost ببندید و با ریورس‌پروکسی ارائه دهید — احراز هویت ندارد.",
"metricsTag": "تگ متریک",
"connectionLimits": "محدودیت اتصال",
"connectionLimitsDesc": "سیاست‌های سطح اتصال برای کاربرانِ سطح ۰. هر فیلد را خالی بگذارید تا مقدار پیش‌فرض Xray استفاده شود.",
"connIdle": "مهلت بی‌کاری",
"connIdleDesc": "اتصال را پس از این تعداد ثانیه بی‌کار ماندن می‌بندد. کم‌کردن آن، روی سرورهای شلوغ حافظه و file descriptor را زودتر آزاد می‌کند (پیش‌فرض Xray: ۳۰۰).",
"bufferSize": "اندازهٔ بافر",
"bufferSizeDesc": "اندازهٔ بافر داخلی هر اتصال بر حسب کیلوبایت. برای کم‌کردن مصرف حافظه روی سرورهای کم‌رم روی ۰ بگذارید (پیش‌فرض 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",
"attributes": "صفت‌ها",
"value": "مقدار",
"user": "کاربر",
"inboundTags": "تگ‌های ورودی",
"outboundTag": "تگ خروجی",
"balancerTag": "تگ بالانسر",
"balancerTagTooltip": "ترافیک را از یکی از بالانسرهای پیکربندی‌شده عبور می‌دهد"
},
"outboundForm": {
"tagDuplicate": "این تگ توسط خروجی دیگری استفاده شده است",
"tagRequired": "تگ الزامی است",
"tagPlaceholder": "تگ-منحصربه‌فرد",
"localIpPlaceholder": "IP محلی",
"dialerProxyPlaceholder": "یک خروجی برای زنجیره کردن انتخاب کنید",
"dialerProxyHint": "این خروجی را از طریق خروجی دیگری (با تگ) برقرار کن تا یک زنجیره پروکسی ساخته شود. برای اتصال مستقیم خالی بگذار.",
"targetStrategyHint": "نحوه تبدیل دامنه مقصد پیش از اتصال: AsIs (پیش‌فرض) آن را بدون تغییر می‌فرستد، UseIP… با امکان بازگشت تبدیل می‌کند، ForceIP… تبدیل موفق را الزامی می‌کند.",
"addressRequired": "آدرس الزامی است",
"portRequired": "پورت الزامی است",
"optional": "اختیاری",
"udpOverTcp": "UDP over TCP",
"uotVersion": "نسخه UoT",
"inboundTag": "تگ ورودی",
"inboundTagPlaceholder": "تگ ورودی استفاده‌شده در قوانین مسیریابی",
"responseType": "نوع پاسخ",
"rewriteNetwork": "بازنویسی شبکه",
"unchanged": "(بدون تغییر)",
"unchangedAddress": "(بدون تغییر) مثل 1.1.1.1",
"rules": "قوانین",
"ruleN": "قانون {n}",
"action": "عمل",
"redirect": "بازهدایت",
"fragment": "Fragment",
"finalRules": "قوانین نهایی",
"overrideXrayPrivateIp": "override بلاک پیش‌فرض IP خصوصی Xray",
"blockDelay": "تأخیر بلاک (ms)",
"reverseSniffing": "Sniffing معکوس",
"reserved": "رزرو شده",
"minUploadInterval": "حداقل بازه آپلود (ms)",
"maxUploadSizeBytes": "حداکثر اندازه آپلود (بایت)",
"uplinkChunkSize": "اندازه قطعه آپلینک",
"noGrpcHeader": "بدون هدر gRPC",
"maxConcurrency": "حداکثر هم‌زمانی",
"maxConnections": "حداکثر اتصال‌ها",
"maxReuseTimes": "حداکثر استفاده مجدد",
"maxRequestTimes": "حداکثر تعداد درخواست",
"maxReusableSecs": "حداکثر ثانیه قابل استفاده مجدد",
"keepAlivePeriod": "دوره Keep alive",
"authPassword": "رمز احراز",
"visionTestpre": "Vision testpre",
"serverNamePlaceholder": "نام سرور",
"verifyPeerName": "تایید نام Peer",
"pinnedSha256": "SHA256 پین‌شده",
"shortId": "Short ID",
"sockopts": "Sockopts",
"keepAliveInterval": "بازه Keep alive",
"markFwmark": "علامت (fwmark)",
"interface": "رابط",
"ipv6Only": "فقط IPv6",
"acceptProxyProtocol": "پذیرش Proxy Protocol",
"proxyProtocol": "Proxy Protocol",
"tcpUserTimeoutMs": "TCP user timeout (ms)",
"tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
},
"outbound": {
"addOutbound": "افزودن خروجی",
"addReverse": "افزودن معکوس",
"editOutbound": "ویرایش خروجی",
"editReverse": "ویرایش معکوس",
"reverseTag": "تگ معکوس",
"reverseTagDesc": "تگ خروجی پروکسی معکوس ساده VLESS. برای غیرفعال کردن خالی بگذارید. در صورت تنظیم، اتصالات این کلاینت می‌توانند به عنوان تونل پروکسی معکوس استفاده شوند.",
"reverseTagPlaceholder": "تگ خروجی (خالی = غیرفعال)",
"tag": "تگ",
"tagDesc": "برچسب یگانه",
"address": "آدرس",
"egress": "Egress",
"egressHint": "Run an HTTP test to show egress IP and country.",
"reverse": "معکوس",
"domain": "دامنه",
"type": "نوع",
"bridge": "پل",
"portal": "پورتال",
"link": "لینک",
"intercon": "اتصال میانی",
"settings": "تنظیمات",
"accountInfo": "اطلاعات حساب",
"outboundStatus": "وضعیت خروجی",
"sendThrough": "ارسال با",
"targetStrategy": "استراتژی مقصد",
"test": "تست",
"testResult": "نتیجه تست",
"testing": "در حال تست اتصال...",
"testSuccess": "تست موفقیت‌آمیز",
"testFailed": "تست ناموفق",
"testError": "خطا در تست خروجی",
"modeRealDelay": "تأخیر واقعی",
"testModeTooltip": "TCP: فقط dial سریع. HTTP: درخواست کامل از طریق xray. تأخیر واقعی: کل زمان همراه با برقراری اتصال.",
"testAll": "تست همه",
"httpStatus": "وضعیت HTTP",
"breakdownConnect": "اتصال پروکسی",
"breakdownTls": "TLS از طریق خروجی",
"breakdownTtfb": "اولین بایت",
"nordvpn": "NordVPN",
"accessToken": "توکن دسترسی",
"country": "کشور",
"server": "سرور",
"city": "شهر",
"allCities": "همه شهرها",
"privateKey": "کلید خصوصی",
"load": "فشار سرور",
"moveToTop": "انتقال به بالا"
},
"outboundSub": {
"manage": "سابسکریپشن‌ها",
"title": "سابسکریپشن‌های خروجی",
"remark": "نام (اختیاری)",
"remarkPlaceholder": "مثلاً نودهای هنگ‌کنگ",
"url": "آدرس سابسکریپشن",
"urlPlaceholder": "https://... (فهرست base64 از لینک‌ها)",
"tagPrefix": "پیشوند تگ",
"tagPrefixPlaceholder": "hk-",
"interval": "بازه به‌روزرسانی",
"hours": "ساعت",
"minutes": "دقیقه",
"intervalHint": "پیش‌فرض ۱۰ دقیقه. وظیفهٔ پس‌زمینه به‌طور مکرر بررسی می‌کند؛ هر سابسکریپشن فقط زمانی دوباره دریافت می‌شود که بازهٔ خودش سپری شده باشد.",
"enabled": "فعال",
"allowPrivate": "اجازهٔ آدرس خصوصی",
"allowPrivateHint": "اجازه به localhost / شبکهٔ محلی (LAN) / IPهای خصوصی برای آدرس این سابسکریپشن. به‌دلایل امنیتی به‌طور پیش‌فرض غیرفعال است؛ فقط برای یک منبع محلی مورد اعتماد فعال کنید.",
"prepend": "پیش از خروجی‌های دستی",
"prependHint": "خروجی‌های این سابسکریپشن را پیش از خروجی‌های دستی شما قرار می‌دهد تا یکی از آن‌ها بتواند پیش‌فرض شود.",
"preview": "پیش‌نمایش",
"previewEmpty": "هیچ خروجی‌ای در این آدرس یافت نشد.",
"refreshAll": "تازه‌سازی همه",
"statusOk": "موفق",
"toastUpdated": "سابسکریپشن به‌روزرسانی شد",
"addButton": "افزودن",
"active": "سابسکریپشن‌های فعال",
"empty": "هنوز سابسکریپشنی وجود ندارد. از بالا یکی اضافه کنید.",
"colRemark": "نام",
"colPrefix": "پیشوند",
"colInterval": "بازه",
"colLastFetch": "آخرین دریافت",
"colEnabled": "فعال",
"auto": "خودکار",
"never": "هرگز",
"yes": "بله",
"no": "خیر",
"refreshNow": "تازه‌سازی اکنون",
"lastError": "آخرین خطا",
"deleteConfirm": "این سابسکریپشن حذف شود؟",
"restartHint": "پس از افزودن یا تازه‌سازی، برای فعال‌شدن خروجی‌ها Xray را راه‌اندازی مجدد کنید (یا منتظر بارگذاری مجدد خودکار بعدی بمانید).",
"fromSubsTitle": "از سابسکریپشن‌های خروجی (فقط‌خواندنی)",
"fromSubsDesc": "از سابسکریپشن‌های فعال شما وارد شده‌اند. آن‌ها را از پنل سابسکریپشن‌ها در بالا مدیریت کنید.",
"toastLoadFailed": "بارگذاری سابسکریپشن‌ها ناموفق بود",
"toastUrlRequired": "آدرس سابسکریپشن الزامی است",
"toastAdded": "سابسکریپشن افزوده شد",
"toastAddFailed": "افزودن سابسکریپشن ناموفق بود",
"toastRefreshed": "تازه‌سازی شد",
"toastRefreshFailed": "تازه‌سازی ناموفق بود",
"toastDeleted": "حذف شد",
"toastDeleteFailed": "حذف ناموفق بود"
},
"tabBalancerSettings": "تنظیمات بالانسر",
"tabObservatory": "رصدخانه",
"observatory": {
"title": "رصدخانه",
"burstTitle": "رصدخانه Burst",
"autoManaged": "رصدگرها به‌صورت خودکار از روی بالانسرهای شما مدیریت می‌شوند. در ادامه می‌توانید نحوهٔ پروب‌زدن را تنظیم کنید؛ خروجی‌های تحت نظر از سلکتورهای بالانسر پیروی می‌کنند.",
"emptyHint": "هیچ رصدگر اتصالی فعال نیست. وقتی یک بالانسر Least Ping یا Least Load بسازید — یا یک بالانسر Random / Round-robin همراه با fallback — به‌صورت خودکار یکی اضافه می‌شود تا بالانسرهای متکی به رصدگر بتوانند پیش از انتخاب مقصد، سلامت خروجی‌ها را بررسی کنند.",
"mixedLegacy": "این پیکربندی هم Observatory و هم Burst Observatory دارد. Xray فقط از یک رصدگر سراسری استفاده می‌کند، بنابراین این حالت قدیمیِ ترکیبی پشتیبانی نمی‌شود؛ ذخیرهٔ بالانسرها آن را به یک رصدگر عادی‌سازی می‌کند.",
"subjectSelector": "خروجی‌های تحت نظر",
"subjectSelectorDesc": "تگ خروجی‌هایی که این رصدگر پروب می‌کند. به‌صورت خودکار از روی بالانسرهای شما مدیریت می‌شود.",
"probeURL": "آدرس پروب (URL)",
"probeURLDesc": "آدرسی که برای سنجش هر خروجی فراخوانی می‌شود. باید HTTP 204 برگرداند.",
"probeInterval": "بازهٔ پروب",
"probeIntervalDesc": "هر چند وقت یک‌بار هر خروجی پروب شود، مثلاً 30s یا 1m یا 2h45m.",
"enableConcurrency": "پروب هم‌زمان",
"enableConcurrencyDesc": "همهٔ خروجی‌های تحت نظر را به‌جای یکی‌یکی، هم‌زمان پروب کن. سریع‌تر است اما در شبکه نمایان‌تر.",
"destination": "مقصد پروب",
"destinationDesc": "آدرسی که برای سنجش هر خروجی فراخوانی می‌شود. باید HTTP 204 برگرداند.",
"connectivity": "بررسی اتصال",
"connectivityDesc": "آدرس اختیاری برای بررسی شبکهٔ محلی که فقط پس از شکست مقصد امتحان می‌شود. برای نادیده‌گرفتن خالی بگذارید.",
"interval": "بازهٔ پروب",
"intervalDesc": "میانگین فاصلهٔ زمانی بین پروب‌ها برای هر خروجی، مثلاً 1m. کمینه 10s.",
"timeout": "مهلت پروب",
"timeoutDesc": "چه مدت برای پاسخ یک پروب صبر شود تا ناموفق به‌حساب بیاید، مثلاً 5s.",
"sampling": "تعداد نمونه‌گیری",
"samplingDesc": "تعداد نتایج اخیر پروب که برای امتیازدهی به هر خروجی نگه داشته می‌شود.",
"httpMethod": "متد HTTP",
"httpMethodDesc": "متد HTTP که برای پروب‌ها استفاده می‌شود.",
"deleteAlsoObservatory": "این آخرین بالانسری است که از Observatory استفاده می‌کند، بنابراین آن هم حذف خواهد شد.",
"deleteAlsoBurst": "این آخرین بالانسری است که از Burst Observatory استفاده می‌کند، بنابراین آن هم حذف خواهد شد."
},
"refCleanup": {
"header": "حذف این مورد مسیریابی شما را هم به‌روز می‌کند:",
"ruleRemoved": "قاعده {label} — حذف شد (مقصدی باقی نماند)",
"ruleModified": "قاعده {label} — حفظ شد (اکنون از {keeps} استفاده می‌کند)",
"balancerRemoved": "بالانسر {tag} — حذف شد (هدفی باقی نماند)"
},
"balancer": {
"addBalancer": "افزودن بالانسر",
"editBalancer": "ویرایش بالانسر",
"balancerStrategy": "استراتژی",
"balancerSelectors": "انتخاب‌گرها",
"tag": "تگ",
"tagDesc": "برچسب یگانه",
"tagDuplicate": "این تگ توسط بالانسر دیگری استفاده شده است",
"tagPlaceholder": "تگ منحصربه‌فرد بالانسر",
"selector": "انتخابگر",
"fallback": "Fallback",
"cycleTooltip": "حلقه: {path} → (بازگشت به {start})",
"expected": "مورد انتظار",
"expectedPlaceholder": "تعداد نود بهینه",
"maxRtt": "حداکثر RTT",
"tolerance": "تحمل",
"baselines": "خطوط پایه",
"costs": "هزینه‌ها",
"balancerDesc": "امکان استفاده همزمان balancerTag و outboundTag باهم وجود ندارد. درصورت استفاده همزمان فقط outboundTag عمل خواهد کرد.",
"costMatch": "الگوی برچسب",
"costValue": "وزن",
"costRegexp": "تطبیق با عبارت باقاعده",
"balancerDeleteInUse": "امکان حذف این بالانسر وجود ندارد — به عنوان پشتیبان برای موارد زیر استفاده می‌شود: {names}",
"balancerFallbackCycle": "امکان تنظیم این بالانسر به عنوان پشتیبان وجود ندارد — وابستگی دایره‌ای ایجاد می‌کند.",
"balancerFallbackInfo": "ترافیک از مسیر زیر مسیریابی می‌شود: بالانسر → Loopback → سرور → بالانسر مقصد → اتصال خروجی. این یک پرش اضافی از طریق سرور اضافه می‌کند که ممکن است تأخیرهای جزئی ایجاد کند.",
"fallbackBalancerHint": "یک بالانسر دیگر به عنوان پشتیبان انتخاب کنید",
"reservedPrefix": "پیشوند _bl_ برای اشیاء loopback داخلی بالانسر رزرو شده است"
},
"wireguard": {
"secretKey": "کلید شخصی",
"publicKey": "کلید عمومی",
"allowedIPs": "آی‌پی‌های مجاز",
"endpoint": "نقطه پایانی",
"psk": "کلید مشترک",
"domainStrategy": "استراتژی حل دامنه"
},
"tun": {
"nameDesc": "نام رابط TUN. مقدار پیش‌فرض 'xray0' است",
"mtuDesc": "واحد انتقال حداکثر. بیشترین اندازه بسته‌های داده. مقدار پیش‌فرض 1500 است",
"userLevel": "سطح کاربر",
"userLevelDesc": "تمام اتصالات انجام‌شده از طریق این ورودی از این سطح کاربری استفاده خواهند کرد. مقدار پیش‌فرض 0 است"
},
"nord": {
"accessToken": "توکن دسترسی",
"privateKey": "کلید خصوصی",
"noServers": "سروری برای کشور انتخابی پیدا نشد",
"noPublicKey": "سرور انتخابی کلید عمومی NordLynx اعلام نمی‌کند.",
"outboundAdded": "خروجی NordVPN اضافه شد",
"outboundUpdated": "خروجی NordVPN به‌روزرسانی شد"
},
"warp": {
"changeIp": "تغییر IP",
"changeIpSuccess": "آدرس IP وارپ با موفقیت تغییر کرد!",
"autoUpdateIp": "به‌روزرسانی خودکار آدرس IP",
"intervalDays": "بازه (روز)",
"intervalDesc": "برای غیرفعال‌سازی ۰ بگذارید. آدرس IP را به‌صورت خودکار تغییر می‌دهد.",
"licenseError": "تنظیم لایسنس WARP ناموفق بود.",
"fetchFirst": "ابتدا پیکربندی WARP را دریافت کنید.",
"createAccount": "ایجاد حساب WARP",
"accessToken": "توکن دسترسی",
"deviceId": "شناسه دستگاه",
"licenseKey": "کلید لایسنس",
"privateKey": "کلید خصوصی",
"deleteAccount": "حذف حساب",
"settings": "تنظیمات",
"licenseKeyLabel": "کلید لایسنس WARP / WARP+",
"key": "کلید",
"keyPlaceholder": "کلید ۲۶ کاراکتری WARP+",
"accountInfo": "اطلاعات حساب",
"deviceName": "نام دستگاه",
"deviceModel": "مدل دستگاه",
"deviceEnabled": "دستگاه فعال",
"accountType": "نوع حساب",
"role": "نقش",
"warpPlusData": "داده WARP+",
"quota": "سهمیه",
"usage": "مصرف",
"addOutbound": "افزودن خروجی"
},
"dns": {
"enable": "فعال کردن حل دامنه",
"enableDesc": "سرور حل دامنه داخلی را فعال کنید",
"tag": "برچسب",
"tagDesc": "این برچسب در قوانین مسیریابی به عنوان یک برچسب ورودی قابل استفاده خواهد بود",
"clientIp": "آی‌پی کلاینت",
"clientIpDesc": "برای اطلاع‌رسانی به سرور درباره مکان IP مشخص‌شده در طول درخواست‌های DNS استفاده می‌شود",
"disableCache": "غیرفعال‌سازی کش",
"disableCacheDesc": "کش DNS را غیرفعال می‌کند",
"disableFallback": "غیرفعال‌سازی Fallback",
"disableFallbackDesc": "درخواست‌های DNS Fallback را غیرفعال می‌کند",
"disableFallbackIfMatch": "غیرفعال‌سازی Fallback در صورت تطابق",
"disableFallbackIfMatchDesc": "درخواست‌های DNS Fallback را زمانی که لیست دامنه‌های مطابقت‌یافته سرور DNS فعال است، غیرفعال می‌کند",
"enableParallelQuery": "فعال‌سازی پرس‌وجوی موازی",
"enableParallelQueryDesc": "فعال‌سازی پرس‌وجوهای DNS موازی به چندین سرور برای وضوح سریع‌تر",
"strategy": "استراتژی پرس‌وجو",
"strategyDesc": "استراتژی کلی برای حل نام دامنه",
"add": "افزودن سرور",
"edit": "ویرایش سرور",
"domains": "دامنه‌ها",
"expectIPs": "آی‌پی‌های مورد انتظار",
"unexpectIPs": "آی‌پی‌های غیرمنتظره",
"useSystemHosts": "استفاده از Hosts سیستم",
"useSystemHostsDesc": "استفاده از فایل hosts یک سیستم نصب‌شده",
"serveStale": "ارائه نتایج منقضی",
"serveStaleDesc": "بازگرداندن نتایج منقضی کش هنگام بروزرسانی در پس‌زمینه",
"serveExpiredTTL": "TTL نتایج منقضی",
"serveExpiredTTLDesc": "مدت اعتبار نتایج منقضی به ثانیه؛ ۰ یعنی هرگز منقضی نمی‌شود",
"timeoutMs": "زمان انتظار (میلی‌ثانیه)",
"skipFallback": "رد کردن Fallback",
"finalQuery": "پرس‌وجوی نهایی",
"hosts": "Hosts",
"hostsAdd": "افزودن Host",
"hostsEmpty": "هیچ Host تعریف نشده",
"hostsDomain": "دامنه (مثلاً domain:example.com)",
"hostsValues": "آی‌پی یا دامنه — تایپ کنید و Enter بزنید",
"usePreset": "استفاده از پیش‌تنظیم",
"dnsPresetTitle": "پیش‌تنظیم‌های DNS",
"dnsPresetFamily": "خانوادگی",
"clearAll": "حذف همه",
"clearAllTitle": "حذف همه سرورهای DNS؟",
"clearAllConfirm": "این کار همه سرورهای DNS را از لیست حذف می‌کند و قابل بازگشت نیست.",
"dnsLeakWarning": "DNS ممکن است از طریق localhost، UDP/TCP ساده، حالت محلی DoH/DoQ، درخواست‌های fallback یا EDNS client IP نشت کند. برای حریم خصوصی از DoH مسیریابی‌شده، مقدارهای hosts ثابت و غیرفعال‌سازی fallback استفاده کنید."
},
"fakedns": {
"add": "افزودن دی‌ان‌اس جعلی",
"edit": "ویرایش دی‌ان‌اس جعلی",
"ipPool": "زیرشبکه استخر آی‌پی",
"poolSize": "اندازه استخر"
},
"defaultOutbound": "خروجی پیش‌فرض",
"defaultOutboundDesc": "ترافیکی که با هیچ قانون مسیریابی جور نشود از این خروجی استفاده می‌کند (اولین خروجی در فهرست)."
},
"hosts": {
"addHost": "افزودن میزبان",
"editHost": "ویرایش میزبان",
"selectInbound": "یک اینباند انتخاب کنید",
"selectedCount": "{count} انتخاب‌شده",
"summary": {
"total": "کل",
"enabled": "فعال",
"disabled": "غیرفعال"
},
"moveUp": "انتقال به بالا",
"moveDown": "انتقال به پایین",
"bulkEnable": "فعال‌سازی",
"bulkDisable": "غیرفعال‌سازی",
"bulkDelete": "حذف",
"bulkDeleteConfirm": "{count} میزبان انتخاب‌شده حذف شود؟",
"deleteConfirmTitle": "میزبان «{name}» حذف شود؟",
"sections": {
"basic": "پایه",
"security": "امنیت",
"advanced": "پیشرفته",
"general": "عمومی",
"clash": "Clash (mihomo)"
},
"fields": {
"remark": "نام",
"serverDescription": "توضیحات",
"inbound": "اینباندها",
"address": "آدرس",
"port": "پورت",
"endpoint": "نقطه پایانی",
"enable": "فعال",
"actions": "عملیات",
"security": "امنیت",
"sni": "SNI",
"overrideSniFromAddress": "استفاده از آدرس به‌عنوان SNI",
"keepSniBlank": "SNI خالی بماند",
"hostHeader": "هدر Host",
"path": "مسیر",
"alpn": "ALPN",
"fingerprint": "اثرانگشت",
"pins": "SHA-256 پین‌شدهٔ گواهی",
"verifyPeerCertByName": "بررسی گواهی همتا بر اساس نام",
"allowInsecure": "اجازهٔ اتصال ناامن",
"echConfigList": "فهرست پیکربندی ECH",
"muxParams": "Mux",
"sockoptParams": "Sockopt",
"finalMask": "ماسک نهایی",
"vlessRoute": "مسیر VLESS",
"mihomoIpVersion": "نسخه IP",
"mihomoX25519": "Mihomo X25519",
"shuffleHost": "درهم‌سازی میزبان",
"tags": "برچسب‌ها",
"nodeGuids": "نودها",
"excludeFromSubTypes": "حذف از فرمت‌ها",
"inheritAddress": "ارث‌بری آدرس"
},
"hints": {
"address": "برای ارث‌بری آدرس خودِ اینباند خالی بگذارید.",
"port": "مقدار ۰ پورت اینباند را به ارث می‌برد.",
"tags": "برای کاربران نهایی قابل مشاهده نیست؛ فقط با اشتراک RAW ارسال می‌شود. تنها حروف بزرگ، ارقام، _ و : مجاز است.",
"nodeGuids": "نودهایی را که از این میزبان resolve می‌شوند انتخاب کنید. صرفاً انتساب نمایشی است.",
"serverDescription": "یادداشت اختیاری که زیر نام نمایش داده می‌شود.",
"allowInsecure": "رد کردن بررسی گواهی TLS (allowInsecure / skip-cert-verify).",
"vlessRoute": "یک مقدار مسیر VLESS (0 تا 65535) که در UUID جاسازی می‌شود، مثلاً 443. برای هیچ‌کدام خالی بگذارید.",
"remark": "یک برچسب ساده برای این میزبان. تنها زمانی به‌عنوان نام کانفیگ نمایش داده می‌شود که اینباند نام مخصوص خود را نداشته باشد."
},
"remarkVars": {
"title": "متغیرهای قالب",
"intro": "برای افزودن یک متغیر روی آن کلیک کنید. هنگام ساخت اشتراک، برای هر کاربر جایگزین می‌شود.",
"preview": "پیش‌نمایش",
"groups": {
"client": "کاربر",
"traffic": "ترافیک",
"time": "زمان و وضعیت",
"connection": "اتصال"
},
"descEMAIL": "ایمیل کاربر",
"descINBOUND": "نام خود اینباند (نام کانفیگ)",
"descHOST": "نام میزبان",
"descID": "UUID کاربر",
"descSHORT_ID": "۸ کاراکتر اول UUID",
"descTELEGRAM_ID": "شناسهٔ تلگرام کاربر (در صورت عدم تنظیم خالی)",
"descSUB_ID": "شناسهٔ اشتراک",
"descCOMMENT": "توضیحات کاربر",
"descTRAFFIC_USED": "ترافیک مصرف‌شده (قابل خواندن برای انسان)",
"descTRAFFIC_LEFT": "ترافیک باقی‌مانده (در صورت نامحدود بودن پنهان می‌شود)",
"descTRAFFIC_TOTAL": "ترافیک کل (در صورت نامحدود بودن پنهان می‌شود)",
"descTRAFFIC_USED_BYTES": "ترافیک مصرف‌شده به بایت",
"descTRAFFIC_LEFT_BYTES": "ترافیک باقی‌مانده به بایت",
"descTRAFFIC_TOTAL_BYTES": "ترافیک کل به بایت",
"descUP": "ترافیک آپلود",
"descDOWN": "ترافیک دانلود",
"descSTATUS": "فعال / منقضی‌شده / غیرفعال / مصرف‌شده",
"descSTATUS_EMOJI": "وضعیت به‌صورت ایموجی (✅ ⏳ 🚫)",
"descDAYS_LEFT": "روزهای باقی‌مانده تا انقضا (در صورت نامحدود بودن پنهان می‌شود)",
"descTIME_LEFT": "زمان باقی‌مانده (مثلاً 12d 4h 30m)",
"descUSAGE_PERCENTAGE": "ترافیک مصرف‌شده به درصد (در صورت نامحدود بودن پنهان می‌شود)",
"descEXPIRE_DATE": "تاریخ انقضا (YYYY-MM-DD)",
"descJALALI_EXPIRE_DATE": "تاریخ انقضا در تقویم جلالی (YYYY/MM/DD)",
"descEXPIRE_UNIX": "انقضا به‌صورت مهر زمانی Unix (ثانیه)",
"descCREATED_UNIX": "زمان ایجاد به‌صورت مهر زمانی Unix (ثانیه)",
"descRESET_DAYS": "دورهٔ بازنشانی ترافیک به روز",
"descPROTOCOL": "پروتکل اینباند (VLESS، VMess، Trojan، …)",
"descTRANSPORT": "شبکهٔ انتقال (tcp، ws، grpc، …)",
"descSECURITY": "امنیت انتقال (TLS، REALITY، NONE)"
},
"toasts": {
"list": "بارگذاری میزبان‌ها ناموفق",
"obtain": "بارگذاری میزبان ناموفق",
"add": "افزودن میزبان",
"update": "به‌روزرسانی میزبان",
"delete": "حذف میزبان",
"badTag": "برچسب نامعتبر",
"badVlessRoute": "یک عدد بین 0 تا 65535 وارد کنید"
}
}
},
"tgbot": {
"keyboardClosed": "❌ صفحه کلید بسته شد!",
"noResult": "❗ نتیجه ای یافت نشد!",
"noQuery": "❌ درخواست یافت نشد! لطفا دوباره تلاش کنید!",
"wentWrong": "❌ مشکلی پیش آمد!",
"noIpRecord": "❗ رکورد آی پی وجود ندارد!",
"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\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>",
"helpClientCommands": "برای جستجوی آمار، از دستور زیر استفاده کنید:\r\n<code>/usage [ایمیل]</code>\r\n\r\nشناسه گفتگوی تلگرام:\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": "نمایش شناسه تلگرام شما",
"usageDesc": "مشاهده مصرف کاربر: /usage ایمیل",
"inboundDesc": "جستجوی ورودی‌ها: /inbound نام (مدیر)",
"restartDesc": "راه‌اندازی مجدد هسته Xray (مدیر)",
"clearallDesc": "صفر کردن ترافیک همه کاربران (مدیر)"
},
"messages": {
"cpuThreshold": "بار ‌پردازنده {{ .Percent }}% بیشتر از آستانه است {{ .Threshold }}%",
"selectUserFailed": "❌ خطا در انتخاب کاربر!",
"userSaved": "✅ کاربر تلگرام ذخیره شد.",
"loginSuccess": "✅ با موفقیت به پنل وارد شدید.\r\n",
"loginFailed": "❗️ ورود به پنل ناموفق‌بود \r\n",
"2faFailed": "خطای 2FA",
"report": "🕰 گزارشات‌زمان‌بندی‌شده: {{ .RunTime }}\r\n",
"datetime": "⏰ تاریخ‌وزمان: {{ .DateTime }}\r\n",
"hostname": "💻 میزبان: {{ .Hostname }}\r\n",
"version": "🚀 نسخه‌پنل: {{ .Version }}\r\n",
"xrayVersion": "📡 نسخه‌هسته: {{ .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\r\n",
"expireIn": "📅 باقی‌ مانده‌ تا انقضا: {{ .Time }}\r\n\r\n",
"active": "💡 فعال: {{ .Enable }}\r\n",
"enabled": "🚨 وضعیت: {{ .Enable }}\r\n",
"online": "🌐 وضعیت اتصال: {{ .Status }}\r\n",
"lastOnline": "🔙 آخرین فعالیت: {{ .Time }}\r\n",
"email": "📧 ایمیل: {{ .Email }}\r\n",
"upload": "🔼 آپلود: ↑{{ .Upload }}\r\n",
"download": "🔽 دانلود: ↓{{ .Download }}\r\n",
"total": "📊 کل: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
"TGUser": "👤 کاربر تلگرام: {{ .TelegramID }}\r\n",
"exhaustedMsg": "🚨 {{ .Type }} به‌اتمام‌رسیده‌است:\r\n",
"exhaustedCount": "🚨 تعداد {{ .Type }} به‌اتمام‌رسیده‌است:\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": "🔑📥 شناسه به‌روزرسانی شد.",
"received_password": "🔑📥 رمز عبور به‌روزرسانی شد.",
"received_email": "📧📥 ایمیل به‌روزرسانی شد.",
"received_comment": "💬📥 نظر به‌روزرسانی شد.",
"id_prompt": "🔑 شناسه پیش‌فرض: {{ .ClientId }}\n\nشناسه خود را وارد کنید.",
"pass_prompt": "🔑 رمز عبور پیش‌فرض: {{ .ClientPassword }}\n\nرمز عبور خود را وارد کنید.",
"email_prompt": "📧 ایمیل پیش‌فرض: {{ .ClientEmail }}\n\nایمیل خود را وارد کنید.",
"comment_prompt": "💬 نظر پیش‌فرض: {{ .ClientComment }}\n\nنظر خود را وارد کنید.",
"inbound_client_data_id": "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 شناسه: {{ .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 }}",
"memoryThreshold": "مصرف حافظه {{ .Percent }}% از حد آستانه {{ .Threshold }}% فراتر رفته است"
},
"buttons": {
"closeKeyboard": "❌ بستن کیبورد",
"cancel": "❌ لغو",
"cancelReset": "❌ لغو تنظیم مجدد",
"cancelIpLimit": "❌ لغو محدودیت آی‌پی",
"confirmResetTraffic": "✅ تأیید تنظیم مجدد ترافیک؟",
"confirmClearIps": "✅ تأیید پاک‌سازی آدرس‌های آی‌پی؟",
"confirmRemoveTGUser": "✅ تأیید حذف کاربر تلگرام؟",
"confirmToggle": "✅ تایید فعال/غیرفعال کردن کاربر؟",
"dbBackup": "دریافت پشتیبان",
"serverUsage": "استفاده از سیستم",
"getInbounds": "دریافت ورودی‌ها",
"depleteSoon": "به‌زودی به پایان خواهد رسید",
"clientUsage": "دریافت آمار کاربر",
"onlines": "کاربران آنلاین",
"commands": "دستورات",
"refresh": "🔄 تازه‌سازی",
"clearIPs": "❌ پاک‌سازی آدرس‌ها",
"removeTGUser": "❌ حذف کاربر تلگرام",
"selectTGUser": "👤 انتخاب کاربر تلگرام",
"selectOneTGUser": "👤 یک کاربر تلگرام را انتخاب کنید:",
"resetTraffic": "📈 تنظیم مجدد ترافیک",
"resetExpire": "📅 تنظیم مجدد تاریخ انقضا",
"ipLog": "🔢 لاگ آدرس‌های IP",
"ipLimit": "🔢 محدودیت IP",
"setTGUser": "👤 تنظیم کاربر تلگرام",
"toggle": "🔘 فعال / غیرفعال",
"custom": "🔢 سفارشی",
"confirmNumber": "✅ تایید: {{ .Num }}",
"confirmNumberAdd": "✅ تایید اضافه کردن: {{ .Num }}",
"limitTraffic": "🚧 محدودیت ترافیک",
"getBanLogs": "گزارش های بلوک را دریافت کنید",
"allClients": "همه مشتریان",
"addClient": "افزودن مشتری",
"submitDisable": "ارسال به عنوان غیرفعال ☑️",
"submitEnable": "ارسال به عنوان فعال ✅",
"use_default": "🏷️ استفاده از پیش‌فرض",
"change_id": "⚙️🔑 ID",
"change_password": "⚙️🔑 گذرواژه",
"change_email": "⚙️📧 ایمیل",
"change_comment": "⚙️💬 نظر",
"change_flow": "⚙️🚦 Flow",
"ResetAllTraffics": "بازنشانی همه ترافیک‌ها",
"SortedTrafficUsageReport": "گزارش استفاده از ترافیک مرتب‌شده"
},
"answers": {
"successfulOperation": "✅ انجام شد!",
"errorOperation": "❗ خطا در عملیات.",
"getInboundsFailed": "❌ دریافت ورودی‌ها با خطا مواجه شد.",
"getClientsFailed": "❌ دریافت مشتریان با شکست مواجه شد.",
"canceled": "❌ {{ .Email }} : عملیات لغو شد.",
"clientRefreshSuccess": "✅ {{ .Email }} : کلاینت با موفقیت تازه‌سازی شد.",
"IpRefreshSuccess": "✅ {{ .Email }} : آدرس‌ها با موفقیت تازه‌سازی شدند.",
"TGIdRefreshSuccess": "✅ {{ .Email }} : کاربر تلگرام کلاینت با موفقیت تازه‌سازی شد.",
"resetTrafficSuccess": "✅ {{ .Email }} : ترافیک با موفقیت تنظیم مجدد شد.",
"setTrafficLimitSuccess": "✅ {{ .Email }} : محدودیت ترافیک با موفقیت ذخیره شد.",
"expireResetSuccess": "✅ {{ .Email }} : تاریخ انقضا با موفقیت تنظیم مجدد شد.",
"resetIpSuccess": "✅ {{ .Email }} : محدودیت آدرس IP {{ .Count }} با موفقیت ذخیره شد.",
"clearIpSuccess": "✅ {{ .Email }} : آدرس‌ها با موفقیت پاک‌سازی شدند.",
"getIpLog": "✅ {{ .Email }} : دریافت لاگ آدرس‌های IP.",
"getUserInfo": "✅ {{ .Email }} : دریافت اطلاعات کاربر تلگرام.",
"removedTGUserSuccess": "✅ {{ .Email }} : کاربر تلگرام با موفقیت حذف شد.",
"enableSuccess": "✅ {{ .Email }} : با موفقیت فعال شد.",
"disableSuccess": "✅ {{ .Email }} : با موفقیت غیرفعال شد.",
"askToAddUserId": "پیکربندی شما یافت نشد!\r\nلطفاً از مدیر خود بخواهید که شناسه کاربر تلگرام خود را در پیکربندی (های) خود استفاده کند.\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": "وصل"
}
}