chore(i18n): delete 230 dead translation keys and guard against new ones (#6132)

* chore(i18n): delete 230 dead translation keys and guard against new ones

The 13 locale files carried 230 keys (11% of the set) that nothing in
the frontend or Go sources references — leftovers of renamed features
(the email notifier reuses tgbot.messages.* for subjects, the old
email.subject*/title* set was orphaned; likewise menu.*, the clients
bulk-copy strings, and the secAlert* family). Nothing detected this:
a missing key falls back to en-US and an unused key fails nothing.

A new test now fails the build when an en-US key has no reference in
frontend/src or internal Go sources (dynamic keys are covered by
harvesting concatenation and template-literal prefixes), and pins
that all 13 locales carry exactly the en-US key set, so parity drift
surfaces at test time instead of as a silent fallback.

Each locale shrinks by the same 230 keys; net -2,900 lines across
the translation set.

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

* fix(i18n): restore the 29 live remarkVars keys, match whole tokens, unmask 9 more

From review: the template-literal harvester required the prefix to end
on a dot, so pages.hosts.remarkVars.desc${token} harvested nothing
and all 29 desc* tooltip keys were wrongly deleted — and the guard
shared the flawed logic, so CI stayed green while the Hosts page
would have shown raw key names in 13 languages. Restored from the
parent commit; the harvester now requires at least one dot but not a
trailing one.

Also from review: references are matched as whole dotted tokens
instead of substrings (a dead key can no longer hide behind a longer
sibling — that unmasked 9 more genuinely dead keys, each verified by
hand before deletion), and the test excludes itself from the scan so
its own prose cannot whitelist a subtree.

Net: -210 keys per locale instead of the previous -230.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
PathGao
2026-07-29 13:59:25 +08:00
committed by GitHub
parent 17e6b5a460
commit ea35884390
14 changed files with 117 additions and 2834 deletions
+2 -218
View File
@@ -48,7 +48,6 @@
"copySuccess": "باموفقیت کپی‌شد",
"sure": "مطمئن",
"encryption": "رمزگذاری",
"useIPv4ForHost": "از IPv4 برای میزبان استفاده کنید",
"transmission": "راه‌اتصال",
"host": "میزبان",
"path": "مسیر",
@@ -74,18 +73,9 @@
"twoFactorCode": "کد",
"remained": "باقی‌مانده",
"security": "امنیت",
"secAlertTitle": "هشدار‌امنیتی",
"secAlertSsl": "این‌اتصال‌امن نیست. لطفا‌ تازمانی‌که تی‌ال‌اس برای محافظت از‌ داده‌ها فعال نشده‌است، از وارد کردن اطلاعات حساس خودداری کنید",
"secAlertConf": "تنظیمات خاصی در برابر حملات آسیب پذیر هستند. توصیه می‌شود پروتکل‌های امنیتی را برای جلوگیری از نفوذ احتمالی تقویت کنید",
"secAlertSSL": "پنل فاقد ارتباط امن است. لطفاً یک گواهینامه تی‌ال‌اس برای محافظت از داده‌ها نصب کنید",
"secAlertPanelPort": "استفاده از پورت پیش‌فرض پنل ناامن است. لطفاً یک پورت تصادفی یا خاص تنظیم کنید",
"secAlertPanelURI": "مسیر پیش‌فرض لینک پنل ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
"secAlertSubURI": "مسیر پیش‌فرض لینک سابسکریپشن ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
"secAlertSubJsonURI": "مسیر پیش‌فرض لینک سابسکریپشن جیسون ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
"emptyDnsDesc": "هیچ سرور DNS اضافه نشده است.",
"emptyFakeDnsDesc": "هیچ سرور Fake DNS اضافه نشده است.",
"emptyBalancersDesc": "هیچ بالانسر اضافه نشده است.",
"emptyReverseDesc": "هیچ پروکسی معکوس اضافه نشده است.",
"somethingWentWrong": "مشکلی پیش آمد",
"subscription": {
"title": "اطلاعات سابسکریپشن",
@@ -106,8 +96,6 @@
},
"menu": {
"theme": "تم",
"dark": "تیره",
"ultraDark": "فوق تیره",
"dashboard": "نمای کلی",
"inbounds": "ورودی‌ها",
"clients": "کلاینت‌ها",
@@ -118,7 +106,6 @@
"routing": "مسیریابی",
"outbounds": "خروجی‌ها",
"apiDocs": "مستندات API",
"logout": "خروج",
"link": "مدیریت",
"donate": "حمایت مالی",
"hosts": "میزبان‌ها",
@@ -139,7 +126,6 @@
}
},
"index": {
"title": "نمای کلی",
"cpu": "پردازنده",
"logicalProcessors": "پردازنده‌های منطقی",
"frequency": "فرکانس",
@@ -152,7 +138,6 @@
"restartXray": "راه‌اندازی مجدد",
"xraySwitch": "‌نسخه",
"xrayUpdates": "به‌روزرسانی‌های Xray",
"xraySwitchClick": "نسخه مورد نظر را انتخاب کنید",
"xraySwitchClickDesk": "لطفا بادقت انتخاب کنید. درصورت انتخاب نسخه قدیمی‌تر، امکان ناهماهنگی با پیکربندی فعلی وجود دارد",
"updatePanel": "به‌روزرسانی پنل",
"panelUpdateDesc": "این عملیات 3X-UI را به آخرین نسخه به‌روزرسانی می‌کند و سرویس پنل را مجدداً راه‌اندازی می‌کند.",
@@ -164,12 +149,10 @@
"currentCommit": "کامیت فعلی",
"latestCommit": "آخرین کامیت",
"updateChannelChanged": "کانال به‌روزرسانی تغییر کرد",
"upToDate": "به‌روز",
"xrayStatusUnknown": "ناشناخته",
"xrayStatusRunning": "در حال اجرا",
"xrayStatusStop": "متوقف",
"xrayStatusError": "خطا",
"xrayErrorPopoverTitle": "خطا در هنگام اجرای Xray رخ داد",
"operationHours": "مدت‌کارکرد",
"systemHistoryTitle": "تاریخچه سیستم",
"historyTitleCpu": "مصرف پردازنده",
@@ -211,9 +194,6 @@
"xrayObservatoryDead": "غیرفعال",
"xrayObservatoryLastSeen": "آخرین مشاهده",
"xrayObservatoryLastTry": "آخرین تلاش",
"trendLast2Min": "۲ دقیقه اخیر",
"systemLoad": "بارسیستم",
"systemLoadDesc": "میانگین بار سیستم برای 1، 5 و 15 دقیقه گذشته",
"connectionCount": "تعداد کانکشن ها",
"ipAddresses": "آدرس‌های IP",
"toggleIpVisibility": "تغییر وضعیت نمایش IP",
@@ -223,13 +203,11 @@
"totalData": "داده‌های کل",
"sent": "ارسال شده",
"received": "دریافت شده",
"documentation": "مستندات",
"xraySwitchVersionDialog": "آیا واقعاً می‌خواهید نسخه Xray را تغییر دهید؟",
"xraySwitchVersionDialogDesc": "این کار نسخه Xray را به #version# تغییر می‌دهد.",
"xraySwitchVersionPopover": "Xray با موفقیت به‌روز شد",
"panelUpdateDialog": "آیا مطمئن هستید که می‌خواهید پنل را به‌روزرسانی کنید؟",
"panelUpdateDialogDesc": "این 3X-UI را به نسخه #version# به‌روزرسانی کرده و سرویس پنل را مجدداً راه‌اندازی می‌کند.",
"panelUpdateCheckPopover": "خطا در بررسی به‌روزرسانی پنل",
"panelUpdateStartedPopover": "به‌روزرسانی پنل آغاز شد",
"panelUpdateFailedTitle": "به‌روزرسانی پنل ناموفق بود",
"panelUpdateFailedDesc": "به‌روزرسانی با موفقیت به پایان نرسید. گزارش‌های سرور را بررسی کنید یا دستور «x-ui update» را از خط فرمان اجرا کنید.",
@@ -258,7 +236,6 @@
"accessLogs": "لاگ‌های دسترسی",
"autoUpdate": "به‌روزرسانی خودکار",
"config": "پیکربندی",
"backup": "پشتیبان‌گیری",
"backupTitle": "پشتیبان‌گیری و بازیابی",
"exportDatabase": "پشتیبان‌گیری",
"exportDatabaseDesc": "برای دانلود یک فایل .db حاوی پشتیبان از پایگاه داده فعلی خود به دستگاهتان کلیک کنید. همین فایل در پنلی که روی PostgreSQL اجرا می‌شود نیز قابل بازیابی است.",
@@ -276,7 +253,6 @@
"migrationDownloadPgDesc": "برای دانلود یک پایگاه‌دادهٔ SQLite با پسوند ‎.db که از داده‌های PostgreSQL شما ساخته می‌شود کلیک کنید؛ آمادهٔ اجرای این پنل روی SQLite."
},
"inbounds": {
"title": "ورودی‌ها",
"totalDownUp": "دریافت/ارسال کل",
"totalUsage": "‌مصرف کل",
"inboundCount": "کل ورودی‌ها",
@@ -288,21 +264,11 @@
"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": "پروتکل",
@@ -310,8 +276,6 @@
"portMap": "نگاشت پورت",
"traffic": "ترافیک",
"speed": "سرعت",
"details": "توضیحات",
"transportConfig": "انتقال",
"expireDate": "مدت زمان",
"createdAt": "ایجاد",
"updatedAt": "به‌روزرسانی",
@@ -319,8 +283,6 @@
"addInbound": "افزودن ورودی",
"generalActions": "عملیات کلی",
"modifyInbound": "ویرایش ورودی",
"deleteInbound": "حذف ورودی",
"deleteInboundContent": "آیا مطمئن به حذف ورودی هستید؟",
"deleteConfirmTitle": "اینباند «{remark}» حذف شود؟",
"deleteConfirmContent": "این اینباند و تمام کلاینت‌های آن حذف می‌شود. این عمل غیرقابل بازگشت است.",
"resetConfirmTitle": "ترافیک اینباند «{remark}» صفر شود؟",
@@ -364,8 +326,6 @@
"exportAllLinksFileName": "همه-ورودی‌ها",
"exportAllSubsFileName": "همه-ورودی‌ها-Subs",
"inboundJsonTitle": "JSON ورودی",
"deleteClient": "حذف کاربر",
"deleteClientContent": "آیا مطمئن به حذف کاربر هستید؟",
"resetTrafficContent": "آیا مطمئن به ریست ترافیک هستید؟",
"copyLink": "کپی لینک",
"address": "آدرس",
@@ -376,36 +336,19 @@
"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": "هیچ گواهی‌ای برای پنل پیکربندی نشده. ابتدا از تنظیمات یکی تعیین کنید.",
@@ -438,21 +381,15 @@
"sniffing": "Sniffing",
"sniffingHelp": "ساختار بلوک sniffing در Xray:",
"stream": "Stream",
"streamHelp": "ساختار بلوک stream در Xray:",
"jsonErrorPrefix": "JSON پیشرفته"
"streamHelp": "ساختار بلوک stream در Xray:"
},
"telegramDesc": "لطفا شناسه گفتگوی تلگرام را وارد کنید. (از دستور '/id' در ربات استفاده کنید) یا ({'@'}userinfobot)",
"subscriptionDesc": "شما می‌توانید لینک سابسکربپشن خودرا در 'جزئیات' پیدا کنید، همچنین می‌توانید از همین نام برای چندین کاربر استفاده‌کنید",
"subSortIndex": "ترتیب اشتراک",
"same": "همسان",
"inboundInfo": "اطلاعات ورودی",
"exportInbound": "استخراج ورودی",
"import": "افزودن",
"importInbound": "افزودن یک ورودی",
"periodicTrafficResetTitle": "بازنشانی ترافیک",
"periodicTrafficResetDesc": "بازنشانی خودکار شمارنده ترافیک در فواصل زمانی مشخص",
"periodicTrafficResetDay": "روز بازنشانی ماهانه",
"lastReset": "آخرین بازنشانی",
"periodicTrafficReset": {
"never": "هرگز",
"daily": "روزانه",
@@ -464,7 +401,6 @@
"obtain": "فراهم‌سازی",
"updateSuccess": "بروزرسانی با موفقیت انجام شد",
"logCleanSuccess": "لاگ پاکسازی شد",
"inboundsUpdateSuccess": "ورودی‌ها با موفقیت به‌روزرسانی شدند",
"inboundUpdateSuccess": "ورودی با موفقیت به‌روزرسانی شد",
"inboundCreateSuccess": "ورودی با موفقیت ایجاد شد",
"bulkDeleted": "{count} اینباند حذف شد",
@@ -474,7 +410,6 @@
"inboundClientDeleteSuccess": "کلاینت ورودی حذف شد",
"inboundClientUpdateSuccess": "کلاینت ورودی به‌روزرسانی شد",
"savedNodeOfflineWillSync": "به‌صورت محلی ذخیره شد. یک نود پشتیبان آفلاین یا غیرفعال است — تغییر پس از اتصال مجدد همگام‌سازی می‌شود.",
"delDepletedClientsSuccess": "تمام کلاینت‌های مصرف شده حذف شدند",
"resetAllClientTrafficSuccess": "تمام ترافیک کلاینت بازنشانی شد",
"resetAllTrafficSuccess": "تمام ترافیک‌ها بازنشانی شدند",
"resetInboundClientTrafficSuccess": "ترافیک بازنشانی شد",
@@ -717,23 +652,6 @@
"peerNumber": "Peer {n}",
"peerNumberConfig": "پیکربندی Peer {n}"
},
"stream": {
"general": {
"request": "درخواست",
"response": "پاسخ",
"name": "نام",
"value": "مقدار"
},
"tcp": {
"version": "نسخه",
"method": "متد",
"path": "مسیر",
"status": "وضعیت",
"statusDescription": "توضیحات وضعیت",
"requestHeader": "سربرگ درخواست",
"responseHeader": "سربرگ پاسخ"
}
},
"sniffingDestOverride": "بازنویسی مقصد"
},
"clients": {
@@ -747,24 +665,9 @@
"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": "روش",
@@ -775,7 +678,6 @@
"postfix": "پسوند",
"delayedStart": "شروع پس از اولین استفاده",
"expireDays": "مدت اعتبار (روز)",
"days": "روز",
"renew": "تمدید خودکار",
"renewDesc": "تمدید خودکار پس از انقضا. (۰ = غیرفعال) (واحد: روز)",
"renewDays": "تمدید خودکار (روز)",
@@ -798,7 +700,6 @@
"sortExpiringSoonest": "نزدیک‌ترین انقضا",
"has": "دارد",
"hasNot": "ندارد",
"title": "کلاینت‌ها",
"actions": "عملیات",
"totalGB": "سقف حجم (گیگابایت)",
"totalGBDesc": "سهمیه‌ی حجم مصرفی کلاینت. ۰ = نامحدود",
@@ -826,8 +727,6 @@
"addClient": "افزودن کلاینت",
"qrCode": "کد QR",
"clientInfo": "اطلاعات کلاینت",
"delete": "حذف",
"reset": "بازنشانی ترافیک",
"editClient": "ویرایش کلاینت",
"client": "کلاینت",
"enabled": "فعال",
@@ -841,13 +740,11 @@
"noLinks": "لینکی برای اشتراک‌گذاری نیست — ابتدا این کلاینت را به یک اینباند با پروتکل سازگار متصل کنید.",
"link": "لینک",
"resetNotPossible": "ابتدا این کلاینت را به یک اینباند متصل کنید.",
"general": "عمومی",
"resetAllTraffics": "بازنشانی ترافیک همه کلاینت‌ها",
"resetAllTrafficsTitle": "بازنشانی ترافیک همه کلاینت‌ها؟",
"resetAllTrafficsContent": "شمارنده ارسال/دریافت همه کلاینت‌ها به صفر می‌رسد. سهمیه و تاریخ انقضا تغییری نمی‌کند. این عمل غیرقابل بازگشت است.",
"deleteConfirmTitle": "حذف کلاینت {email}؟",
"deleteConfirmContent": "این کلاینت از تمام اینباندهای متصل حذف و سابقه ترافیک آن پاک می‌شود. این عمل غیرقابل بازگشت است.",
"deleteSelected": "حذف ({count})",
"adjustSelected": "تنظیم ({count})",
"subLinksSelected": "لینک‌های اشتراک ({count})",
"addToGroupTitle": "افزودن {count} کاربر به یک گروه",
@@ -869,12 +766,10 @@
"bulkDisableConfirmTitle": "{count} کلاینت غیرفعال شوند؟",
"bulkDisableConfirmContent": "هر کلاینت انتخاب‌شده روی تمام اینباندهای متصل غیرفعال می‌شود. دسترسی آن‌ها بلافاصله قطع می‌شود اما رکورد و ترافیکشان حفظ می‌گردد.",
"selectedCount": "{count} انتخاب‌شده",
"attachSelected": "الصاق ({count})",
"attachToInboundsTitle": "الصاق {count} کاربر به ورودی‌(ها)",
"attachToInboundsDesc": "{count} کاربر انتخاب‌شده (همان UUID/رمز و ترافیک مشترک) را به ورودی‌های انتخابی الصاق می‌کند. الصاق‌های قبلی حفظ می‌شوند.",
"attachToInboundsTargets": "ورودی‌های مقصد",
"attachToInboundsNoTargets": "هیچ ورودی چندکاربره‌ای برای الصاق در دسترس نیست.",
"detachSelected": "جداسازی ({count})",
"detach": "جداسازی",
"detachFromInboundsTitle": "جداسازی {count} کاربر از ورودی‌(ها)",
"detachFromInboundsDesc": "{count} کاربر انتخاب‌شده را از ورودی‌های انتخابی حذف می‌کند. در مواردی که کاربر الصاق نبوده، نادیده گرفته می‌شود. رکورد کاربر حفظ می‌شود (برای حذف کامل از Delete استفاده کنید).",
@@ -928,8 +823,6 @@
"reverseTagPlaceholder": "Reverse tag اختیاری",
"telegramId": "شناسه کاربر تلگرام",
"telegramIdPlaceholder": "شناسه عددی کاربر تلگرام (۰ = هیچ)",
"created": "ساخته‌شده",
"updated": "به‌روزشده",
"ipLimit": "محدودیت IP",
"toasts": {
"deleted": "کلاینت حذف شد",
@@ -952,7 +845,6 @@
}
},
"groups": {
"title": "گروه‌ها",
"name": "نام",
"clientCount": "کاربران",
"totalGroups": "تعداد گروه‌ها",
@@ -994,7 +886,6 @@
"removeFromGroupResult": "{count} کاربر از {name} حذف شد."
},
"nodes": {
"title": "نودها",
"addNode": "افزودن نود",
"editNode": "ویرایش نود",
"totalNodes": "کل نودها",
@@ -1013,8 +904,6 @@
"apiTokenPlaceholder": "توکن از صفحه تنظیمات پنل ریموت",
"apiTokenHint": "پنل ریموت توکن API خودش را در بخش احرازهویت → توکن API نمایش می‌دهد.",
"apiTokenKeepHint": "برای حفظ توکن فعلی خالی بگذارید",
"regenerate": "تولید مجدد توکن",
"regenerateConfirm": "تولید مجدد، توکن فعلی را باطل می‌کند. هر پنل مرکزی‌ای که از این توکن استفاده می‌کند تا زمان به‌روزرسانی، دسترسی‌اش قطع می‌شود. ادامه می‌دهید؟",
"allowPrivateAddress": "اجازه آدرس خصوصی",
"allowPrivateAddressHint": "فقط برای نودهای روی شبکه خصوصی یا VPN فعال شود.",
"outboundTag": "خروجی اتصال",
@@ -1046,7 +935,6 @@
"updatePanel": "به‌روزرسانی پنل",
"updateSelected": "به‌روزرسانی انتخاب‌شده‌ها ({count})",
"updateAvailable": "به‌روزرسانی موجود",
"upToDate": "به‌روز",
"updateConfirmTitle": "{count} نود به آخرین نسخه به‌روزرسانی شوند؟",
"updateConfirmContent": "هر نود انتخاب‌شده آخرین نسخه را دانلود و روی آن ری‌استارت می‌شود. فقط نودهای فعال و آنلاین به‌روزرسانی می‌شوند.",
"updateDevChannel": "به‌روزرسانی به کانال دِو (آخرین کامیت)",
@@ -1447,13 +1335,8 @@
"secretClearUndo": "لغو پاک کردن"
},
"xray": {
"title": "پیکربندی ایکس‌ری",
"save": "ذخیره",
"restart": "راه‌اندازی مجدد Xray",
"restartSuccess": "Xray با موفقیت راه‌اندازی مجدد شد",
"restartOutputTitle": "خروجی راه‌اندازی مجدد Xray",
"restartConfirmTitle": "راه‌اندازی مجدد xray؟",
"restartConfirmContent": "سرویس xray با پیکربندی ذخیره‌شده دوباره بارگذاری می‌شود.",
"stopSuccess": "Xray با موفقیت متوقف شد",
"restartError": "خطا در راه‌اندازی مجدد Xray.",
"stopError": "خطا در توقف Xray.",
@@ -1463,7 +1346,6 @@
"generalConfigsDesc": "این گزینه‌ها استراتژی کلی ترافیک را تعیین می‌کنند",
"logConfigs": "لاگ",
"logConfigsDesc": "گزارش‌ها ممکن است بر کارایی سرور شما تأثیر بگذارد. توصیه می شود فقط در صورت نیاز آن را عاقلانه فعال کنید",
"blockConfigsDesc": "این گزینه‌ها ترافیک را بر اساس پروتکل‌های درخواستی خاص، و وب سایت‌ها مسدود می‌کند",
"basicRouting": "مسیریابی پایه",
"blockConnectionsConfigsDesc": "این گزینه‌ها ترافیک را بر اساس کشور درخواست‌شده خاص مسدود می‌کنند.",
"directConnectionsConfigsDesc": "یک اتصال مستقیم تضمین می‌کند که ترافیک خاص از طریق سرور دیگری مسیریابی نشود.",
@@ -1473,10 +1355,6 @@
"directdomains": "دامنه‌های مستقیم",
"ipv4Routing": "IPv4 مسیریابی",
"ipv4RoutingDesc": "این گزینه‌ها ترافیک را از طریق آی‌پی نسخه4 سرور، به مقصد هدایت می‌کند",
"warpRouting": "WARP مسیریابی",
"warpRoutingDesc": "این گزینه‌ها ترافیک‌ را از طریق وارپ کلادفلر به مقصد هدایت می‌کند",
"nordRouting": "مسیریابی NordVPN",
"nordRoutingDesc": "این گزینه‌ها ترافیک را بر اساس مقصد خاص از طریق NordVPN مسیریابی می‌کنند.",
"Template": "‌پیکربندی پیشرفته الگو ایکس‌ری",
"TemplateDesc": "فایل پیکربندی نهایی ایکس‌ری بر اساس این الگو ایجاد می‌شود",
"FreedomStrategy": "Freedom استراتژی پروتکل",
@@ -1490,10 +1368,7 @@
"outboundTestUrlDesc": "آدرسی که برای تست اتصال خروجی استفاده می‌شود.",
"Torrent": "مسدودسازی پروتکل بیت‌تورنت",
"Inbounds": "ورودی‌ها",
"InboundsDesc": "پذیرش کلاینت خاص",
"Outbounds": "خروجی‌ها",
"OutboundSubscriptions": "سابسکریپشن‌های خروجی",
"OutboundSubscriptionsDesc": "خروجی‌ها را از آدرس‌های سابسکریپشن راه‌دور (vmess/vless/trojan/ss/...) وارد کنید. تگ‌ها ثابت می‌مانند تا در بالانسرها و قوانین مسیریابی قابل استفاده باشند. به‌روزرسانی‌ها به‌صورت خودکار انجام می‌شوند.",
"Balancers": "بالانسرها",
"balancerTagRequired": "تگ الزامی است",
"balancerSelectorRequired": "حداقل یک خروجی انتخاب کنید",
@@ -1512,9 +1387,7 @@
"routeTesterMatchedOutbound": "خروجی منطبق",
"routeTesterViaBalancer": "از طریق بالانسر",
"routeTesterDefaultOutbound": "هیچ قانونی منطبق نشد — ترافیک به خروجی پیش‌فرض (اولین خروجی) می‌رود.",
"OutboundsDesc": "مسیر ترافیک خروجی را تنظیم کنید",
"Routings": "قوانین مسیریابی",
"RoutingsDesc": "اولویت هر قانون مهم است",
"importRules": "ورود قوانین",
"exportRules": "خروج قوانین",
"importOutbounds": "ورود خروجی‌ها",
@@ -1533,13 +1406,9 @@
"maskAddressDesc": "پوشش آدرس IP، هنگامی که فعال می‌شود، به طور خودکار آدرس IP که در لاگ ظاهر می‌شود را جایگزین می‌کند.",
"statistics": "آمار",
"statsInboundUplink": "آمار آپلود ورودی",
"statsInboundUplinkDesc": "جمع‌آوری آمار برای ترافیک بالارو (آپلود) تمام پروکسی‌های ورودی را فعال می‌کند.",
"statsInboundDownlink": "آمار دانلود ورودی",
"statsInboundDownlinkDesc": "جمع‌آوری آمار برای ترافیک پایین‌رو (دانلود) تمام پروکسی‌های ورودی را فعال می‌کند.",
"statsOutboundUplink": "آمار آپلود خروجی",
"statsOutboundUplinkDesc": "جمع‌آوری آمار برای ترافیک بالارو (آپلود) تمام پروکسی‌های خروجی را فعال می‌کند.",
"statsOutboundDownlink": "آمار دانلود خروجی",
"statsOutboundDownlinkDesc": "جمع‌آوری آمار برای ترافیک پایین‌رو (دانلود) تمام پروکسی‌های خروجی را فعال می‌کند.",
"metricsListen": "نقطه پایانی متریک",
"metricsListenDesc": "متریک‌های Xray (سبک Prometheus) را روی این آدرس:پورت در دسترس قرار می‌دهد (مثلاً 127.0.0.1:11111). برای غیرفعال‌کردن خالی بگذارید. روی localhost ببندید و با ریورس‌پروکسی ارائه دهید — احراز هویت ندارد.",
"metricsTag": "تگ متریک",
@@ -1552,18 +1421,10 @@
"bufferSizePlaceholder": "خودکار",
"seconds": "ثانیه",
"rules": {
"first": "اولین",
"last": "آخرین",
"up": "بالا",
"down": "پایین",
"source": "مبدا",
"dest": "مقصد",
"inbound": "ورودی",
"outbound": "خروجی",
"balancer": "بالانسر",
"info": "اطلاعات",
"add": "افزودن قانون",
"edit": "ویرایش قانون",
"useComma": "موارد جدا شده با کاما"
},
"routing": {
@@ -1604,7 +1465,6 @@
"ruleN": "قانون {n}",
"action": "عمل",
"redirect": "بازهدایت",
"fragment": "Fragment",
"finalRules": "قوانین نهایی",
"overrideXrayPrivateIp": "override بلاک پیش‌فرض IP خصوصی Xray",
"blockDelay": "تأخیر بلاک (ms)",
@@ -1630,43 +1490,17 @@
"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": "تست همه",
@@ -1674,14 +1508,10 @@
"breakdownConnect": "اتصال پروکسی",
"breakdownTls": "TLS از طریق خروجی",
"breakdownTtfb": "اولین بایت",
"nordvpn": "NordVPN",
"accessToken": "توکن دسترسی",
"country": "کشور",
"server": "سرور",
"city": "شهر",
"allCities": "همه شهرها",
"privateKey": "کلید خصوصی",
"load": "فشار سرور",
"moveToTop": "انتقال به بالا"
},
"outboundSub": {
@@ -1711,16 +1541,11 @@
"active": "سابسکریپشن‌های فعال",
"empty": "هنوز سابسکریپشنی وجود ندارد. از بالا یکی اضافه کنید.",
"colRemark": "نام",
"colPrefix": "پیشوند",
"colInterval": "بازه",
"colLastFetch": "آخرین دریافت",
"colEnabled": "فعال",
"auto": "خودکار",
"never": "هرگز",
"yes": "بله",
"no": "خیر",
"refreshNow": "تازه‌سازی اکنون",
"lastError": "آخرین خطا",
"deleteConfirm": "این سابسکریپشن حذف شود؟",
"restartHint": "پس از افزودن یا تازه‌سازی، برای فعال‌شدن خروجی‌ها Xray را راه‌اندازی مجدد کنید (یا منتظر بارگذاری مجدد خودکار بعدی بمانید).",
"fromSubsTitle": "از سابسکریپشن‌های خروجی (فقط‌خواندنی)",
@@ -1737,8 +1562,6 @@
"tabBalancerSettings": "تنظیمات بالانسر",
"tabObservatory": "رصدخانه",
"observatory": {
"title": "رصدخانه",
"burstTitle": "رصدخانه Burst",
"autoManaged": "رصدگرها به‌صورت خودکار از روی بالانسرهای شما مدیریت می‌شوند. در ادامه می‌توانید نحوهٔ پروب‌زدن را تنظیم کنید؛ خروجی‌های تحت نظر از سلکتورهای بالانسر پیروی می‌کنند.",
"emptyHint": "هیچ رصدگر اتصالی فعال نیست. وقتی یک بالانسر Least Ping یا Least Load بسازید — یا یک بالانسر Random / Round-robin همراه با fallback — به‌صورت خودکار یکی اضافه می‌شود تا بالانسرهای متکی به رصدگر بتوانند پیش از انتخاب مقصد، سلامت خروجی‌ها را بررسی کنند.",
"mixedLegacy": "این پیکربندی هم Observatory و هم Burst Observatory دارد. Xray فقط از یک رصدگر سراسری استفاده می‌کند، بنابراین این حالت قدیمیِ ترکیبی پشتیبانی نمی‌شود؛ ذخیرهٔ بالانسرها آن را به یک رصدگر عادی‌سازی می‌کند.",
@@ -1772,12 +1595,8 @@
"balancerRemoved": "بالانسر {tag} — حذف شد (هدفی باقی نماند)"
},
"balancer": {
"addBalancer": "افزودن بالانسر",
"editBalancer": "ویرایش بالانسر",
"balancerStrategy": "استراتژی",
"balancerSelectors": "انتخاب‌گرها",
"tag": "تگ",
"tagDesc": "برچسب یگانه",
"tagDuplicate": "این تگ توسط بالانسر دیگری استفاده شده است",
"tagPlaceholder": "تگ منحصربه‌فرد بالانسر",
"selector": "انتخابگر",
@@ -1789,7 +1608,6 @@
"tolerance": "تحمل",
"baselines": "خطوط پایه",
"costs": "هزینه‌ها",
"balancerDesc": "امکان استفاده همزمان balancerTag و outboundTag باهم وجود ندارد. درصورت استفاده همزمان فقط outboundTag عمل خواهد کرد.",
"costMatch": "الگوی برچسب",
"costValue": "وزن",
"costRegexp": "تطبیق با عبارت باقاعده",
@@ -1804,14 +1622,10 @@
"publicKey": "کلید عمومی",
"allowedIPs": "آی‌پی‌های مجاز",
"endpoint": "نقطه پایانی",
"psk": "کلید مشترک",
"domainStrategy": "استراتژی حل دامنه"
},
"tun": {
"nameDesc": "نام رابط TUN. مقدار پیش‌فرض 'xray0' است",
"mtuDesc": "واحد انتقال حداکثر. بیشترین اندازه بسته‌های داده. مقدار پیش‌فرض 1500 است",
"userLevel": "سطح کاربر",
"userLevelDesc": "تمام اتصالات انجام‌شده از طریق این ورودی از این سطح کاربری استفاده خواهند کرد. مقدار پیش‌فرض 0 است"
"userLevel": "سطح کاربر"
},
"nord": {
"accessToken": "توکن دسترسی",
@@ -1896,7 +1710,6 @@
},
"fakedns": {
"add": "افزودن دی‌ان‌اس جعلی",
"edit": "ویرایش دی‌ان‌اس جعلی",
"ipPool": "زیرشبکه استخر آی‌پی",
"poolSize": "اندازه استخر"
},
@@ -2032,7 +1845,6 @@
"add": "افزودن",
"month": "ماه",
"months": "ماه",
"day": "روز",
"days": "روز",
"hours": "ساعت",
"minutes": "دقیقه",
@@ -2071,7 +1883,6 @@
"userSaved": "✅ کاربر تلگرام ذخیره شد.",
"loginSuccess": "✅ با موفقیت به پنل وارد شدید.\r\n",
"loginFailed": "❗️ ورود به پنل ناموفق‌بود \r\n",
"2faFailed": "خطای 2FA",
"report": "🕰 گزارشات‌زمان‌بندی‌شده: {{ .RunTime }}\r\n",
"datetime": "⏰ تاریخ‌وزمان: {{ .DateTime }}\r\n",
"hostname": "💻 میزبان: {{ .Hostname }}\r\n",
@@ -2104,7 +1915,6 @@
"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",
@@ -2113,16 +1923,10 @@
"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": "باشه، از مقدار پیش‌فرض استفاده می‌کنم. 😊",
@@ -2139,8 +1943,6 @@
"eventXrayCrashError": "خطا: {{ .Error }}",
"eventNodeDown": "نود {{ .Name }} قطع است",
"eventNodeUp": "نود {{ .Name }} وصل است",
"eventCPUHigh": "بالا بودن CPU",
"eventCPUHighDetail": "CPU: {{ .Detail }}",
"eventLoginFallback": "ورود ناموفق از {{ .Source }}",
"memoryThreshold": "مصرف حافظه {{ .Percent }}% از حد آستانه {{ .Threshold }}% فراتر رفته است"
},
@@ -2181,11 +1983,8 @@
"submitDisable": "ارسال به عنوان غیرفعال ☑️",
"submitEnable": "ارسال به عنوان فعال ✅",
"use_default": "🏷️ استفاده از پیش‌فرض",
"change_id": "⚙️🔑 ID",
"change_password": "⚙️🔑 گذرواژه",
"change_email": "⚙️📧 ایمیل",
"change_comment": "⚙️💬 نظر",
"change_flow": "⚙️🚦 Flow",
"ResetAllTraffics": "بازنشانی همه ترافیک‌ها",
"SortedTrafficUsageReport": "گزارش استفاده از ترافیک مرتب‌شده"
},
@@ -2214,31 +2013,16 @@
}
},
"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": "ناموفق",