diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 9da45107..8be00f84 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -8,6 +8,7 @@ import zhCN from './locales/zh-CN.json'; import zhTW from './locales/zh-TW.json'; import en from './locales/en.json'; import ru from './locales/ru.json'; +import vi from './locales/vi.json'; import { getInitialLanguage } from '@/utils/language'; i18n.use(initReactI18next).init({ @@ -16,6 +17,7 @@ i18n.use(initReactI18next).init({ 'zh-TW': { translation: zhTW }, en: { translation: en }, ru: { translation: ru }, + vi: { translation: vi }, }, lng: getInitialLanguage(), fallbackLng: 'zh-CN', diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 820a0690..5aecec38 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1805,7 +1805,8 @@ "chinese": "中文", "chinese_tw": "Traditional Chinese (Taiwan)", "english": "English", - "russian": "Русский" + "russian": "Русский", + "vietnamese": "Tiếng Việt" }, "theme": { "switch": "Theme", diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index e0b6d8ba..ff34aa8d 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -1799,7 +1799,8 @@ "chinese": "中文", "chinese_tw": "繁體中文(台灣)", "english": "English", - "russian": "Русский" + "russian": "Русский", + "vietnamese": "Tiếng Việt" }, "theme": { "switch": "Тема", diff --git a/src/i18n/locales/vi.json b/src/i18n/locales/vi.json new file mode 100644 index 00000000..dc9a3cf9 --- /dev/null +++ b/src/i18n/locales/vi.json @@ -0,0 +1,1725 @@ +{ + "common": { + "login": "Đăng nhập", + "logout": "Đăng xuất", + "back": "Quay lại", + "cancel": "Hủy", + "confirm": "Xác nhận", + "leave": "Rời đi", + "stay": "Ở lại", + "save": "Lưu", + "delete": "Xóa", + "edit": "Chỉnh sửa", + "add": "Thêm", + "update": "Cập nhật", + "refresh": "Làm mới", + "close": "Đóng", + "success": "Thành công", + "error": "Lỗi", + "info": "Thông tin", + "warning": "Cảnh báo", + "loading": "Đang tải...", + "connecting": "Đang kết nối...", + "connected": "Đã kết nối", + "disconnected": "Mất kết nối", + "connecting_status": "Đang kết nối", + "connected_status": "Đã kết nối", + "disconnected_status": "Mất kết nối", + "yes": "Có", + "no": "Không", + "not_set": "Chưa đặt", + "optional": "Tùy chọn", + "required": "Bắt buộc", + "api_key": "Key", + "base_url": "Địa chỉ", + "prefix": "Tiền tố", + "proxy_url": "Proxy", + "priority": "Ưu tiên", + "alias": "Bí danh", + "failure": "Thất bại", + "unknown_error": "Lỗi không xác định", + "quota_update_required": "Vui lòng cập nhật phiên bản CPA hoặc kiểm tra bản cập nhật", + "quota_check_credential": "Vui lòng kiểm tra trạng thái credential", + "copy": "Sao chép", + "expand": "Mở rộng", + "collapse": "Thu gọn", + "status": "Trạng thái", + "action": "Hành động", + "custom_headers_label": "Header tùy chỉnh", + "custom_headers_hint": "Header HTTP tùy chọn gửi kèm yêu cầu. Để trống để xóa.", + "custom_headers_add": "Thêm Header", + "custom_headers_key_placeholder": "Tên header, ví dụ X-Custom-Header", + "custom_headers_value_placeholder": "Giá trị header", + "model_name_placeholder": "Tên model, ví dụ claude-3-5-sonnet-20241022", + "model_alias_placeholder": "Bí danh model (tùy chọn)", + "invalid_provider_index": "Chỉ mục provider không hợp lệ.", + "unsaved_changes_title": "Thay đổi chưa lưu", + "unsaved_changes_message": "Bạn có thay đổi chưa lưu. Rời đi bây giờ sẽ mất các thay đổi đó. Bạn có muốn rời đi không?" + }, + "title": { + "login": "Trung tâm Quản lý CLI Proxy API", + "abbr": "CPAMC" + }, + "splash": { + "title": "CLI Proxy API", + "subtitle": "Trung tâm Quản lý" + }, + "login": { + "subtitle": "Vui lòng nhập thông tin kết nối để truy cập giao diện quản lý", + "connection_current": "URL hiện tại", + "connection_auto_hint": "Hệ thống sẽ tự động dùng URL hiện tại để kết nối", + "custom_connection_label": "URL kết nối tùy chỉnh:", + "custom_connection_placeholder": "Ví dụ: https://example.com:8317", + "custom_connection_hint": "Mặc định dùng URL hiện tại. Ghi đè tại đây nếu cần.", + "remember_password_label": "Ghi nhớ mật khẩu", + "management_key_label": "Key quản lý:", + "management_key_placeholder": "Nhập key quản lý", + "submit_button": "Đăng nhập", + "submitting": "Đang kết nối...", + "error_backend_detail": "Phản hồi từ backend", + "error_required": "Vui lòng điền đầy đủ thông tin kết nối", + "error_invalid": "Kết nối thất bại, vui lòng kiểm tra địa chỉ máy chủ, Management API và key quản lý", + "error_network": "Kết nối mạng thất bại, vui lòng kiểm tra mạng hoặc địa chỉ máy chủ", + "error_timeout": "Kết nối hết thời gian chờ, máy chủ không phản hồi", + "error_unauthorized": "Xác thực thất bại, key quản lý bị thiếu hoặc không hợp lệ", + "error_forbidden": "Truy cập bị từ chối, quản lý từ xa bị tắt, key quản lý chưa được cấu hình, hoặc IP này bị cấm tạm thời", + "error_not_found": "Không tìm thấy Management API, hãy xác nhận địa chỉ máy chủ trỏ đến backend CLIProxyAPI", + "error_server": "Backend gặp lỗi khi xử lý yêu cầu quản lý, hãy kiểm tra log máy chủ", + "error_cors": "Yêu cầu cross-origin bị chặn, vui lòng kiểm tra cấu hình máy chủ", + "error_ssl": "Xác minh chứng chỉ SSL/TLS thất bại" + }, + "header": { + "refresh_all": "Làm mới tất cả", + "logout": "Đăng xuất" + }, + "connection": { + "status": "Trạng thái kết nối:" + }, + "nav": { + "dashboard": "Bảng điều khiển", + "quick_start": "Bắt đầu nhanh", + "ai_providers": "AI Provider", + "auth_files": "File xác thực", + "oauth": "Đăng nhập OAuth", + "quota_management": "Quản lý Quota", + "plugins": "Plugin", + "plugin_store": "Cửa hàng Plugin", + "config_management": "Bảng cấu hình", + "logs": "Trình xem Log", + "system_info": "Thông tin Trung tâm Quản lý" + }, + "nav_groups": { + "operate": "Vận hành", + "gateway": "Gateway", + "observe": "Giám sát", + "plugin_pages": "Plugin", + "control": "Điều khiển" + }, + "nav_meta": { + "dashboard": "Tổng quan vận hành", + "quick_start": "Thiết lập APIKEY.FUN", + "ai_providers": "Định tuyến model upstream", + "auth_files": "File xác thực & credential", + "oauth": "Ủy quyền OAuth", + "quota_management": "API key & giới hạn", + "plugins": "Bật/tắt & cấu hình plugin", + "plugin_store": "Khám phá & cài đặt plugin", + "logs": "Truy vết yêu cầu", + "config_management": "Cấu hình gateway", + "system_info": "Runtime & chẩn đoán" + }, + "dashboard": { + "hero_verdict_good": "Mọi hệ thống ổn định", + "hero_verdict_warning": "Có chút trục trặc nhỏ", + "hero_verdict_critical": "Cần chú ý", + "hero_verdict_idle": "Tạm thời yên tĩnh", + "hero_verdict_offline": "Đang chờ kết nối", + "hero_verdict_connecting": "Đang kết nối", + "hero_period": ".", + "hero_requests_label": "Yêu cầu đã xử lý", + "hero_live": "Trực tiếp", + "hero_window_meta": "Cửa sổ trượt {{window}} · bucket 10 phút", + "hero_spark_label": "Lưu lượng yêu cầu trong {{window}} vừa qua", + "cta_manage_providers": "Quản lý provider", + "cta_inspect_logs": "Kiểm tra log", + "stats_aria": "Chỉ số chính", + "success_rate": "Tỷ lệ thành công", + "stat_success_hint": "Trên {{total}} yêu cầu trong cửa sổ", + "stat_credentials": "Credential", + "stat_credentials_hint": "{{active}} đang hoạt động · {{disabled}} không phục vụ", + "stat_credentials_empty": "Chưa tìm thấy file credential nào", + "stat_provider_keys": "Key provider", + "stat_provider_keys_hint": "API key được cấu hình trên tất cả các thương hiệu", + "stat_models": "Model", + "stat_models_hint": "Được phục vụ qua proxy endpoint", + "traffic_eyebrow": "Lưu lượng trực tiếp", + "traffic_title": "Thông lượng, từng khoảng mười phút", + "traffic_description": "Số lần thành công và thất bại mỗi bucket 10 phút trong {{window}} vừa qua. Di chuột vào cột để xem phân tách chính xác.", + "traffic_table": "Bảng dữ liệu", + "traffic_table_window": "Cửa sổ", + "traffic_chart_summary": "{{total}} yêu cầu trong {{minutes}} phút vừa qua: {{success}} thành công, {{failed}} thất bại.", + "traffic_unavailable": "Chưa có lưu lượng nào được ghi nhận", + "traffic_unavailable_hint": "Bộ đếm sẽ xuất hiện khi proxy phục vụ yêu cầu đầu tiên.", + "fleet_eyebrow": "Toàn cảnh", + "fleet_title": "Mọi provider, đặt cạnh nhau", + "fleet_description": "Lưu lượng và tỷ lệ thành công của từng provider trong cùng cửa sổ.", + "fleet_empty": "Chưa có lưu lượng provider nào được ghi nhận.", + "fleet_credentials": "Credential: {{value}}", + "fleet_spark_label": "Lưu lượng yêu cầu của {{provider}}", + "fleet_requests": "yêu cầu", + "provider_unknown": "Chưa xác định", + "health_eyebrow": "Sức khỏe", + "health_title": "Trạng thái credential", + "health_active": "Đang hoạt động", + "health_unavailable": "Không khả dụng", + "health_disabled": "Đã tắt", + "health_by_type": "Theo provider", + "health_empty": "Chưa tìm thấy file credential nào.", + "health_link": "Mở file xác thực", + "runtime_eyebrow": "Runtime", + "runtime_title": "Tổng quan cấu hình", + "runtime_routing": "Chiến lược định tuyến", + "runtime_retry": "Thử lại yêu cầu", + "runtime_management_keys": "Key quản lý", + "runtime_version": "Phiên bản máy chủ", + "runtime_build": "Ngày build", + "runtime_proxy": "Proxy upstream", + "runtime_debug": "Debug", + "runtime_file_logging": "Ghi log ra file", + "runtime_request_log": "Log yêu cầu", + "runtime_ws_auth": "Xác thực WebSocket", + "runtime_model_prefix": "Tiền tố model", + "runtime_link": "Chỉnh sửa cấu hình", + "cta_eyebrow": "Tiếp theo", + "cta_title": "Nên đi đâu từ đây", + "cta_providers_desc": "Thêm API key, đặt ưu tiên và kiểm thử các thương hiệu.", + "cta_auth_files_desc": "Tải lên, làm mới và vô hiệu hóa credential OAuth.", + "cta_config_desc": "Tinh chỉnh định tuyến, thử lại, ghi log và truy cập.", + "cta_quota_desc": "Kiểm tra quota còn lại của từng credential.", + "cta_logs_desc": "Theo dõi yêu cầu và tải báo cáo lỗi.", + "cta_system_desc": "Chi tiết phiên bản và thông tin trung tâm quản lý.", + "window_m": "{{minutes}}p", + "window_h": "{{hours}}g", + "window_hm": "{{hours}}g {{minutes}}p" + }, + "basic_settings": { + "debug_enable": "Bật chế độ Debug", + "proxy_url_label": "URL Proxy:", + "retry_count_label": "Số lần thử lại:", + "logging_to_file_enable": "Bật ghi log ra file", + "request_log_title": "Ghi log yêu cầu", + "request_log_enable": "Bật ghi log yêu cầu", + "request_log_warning": "Hãy tắt tính năng này trừ khi bạn cần gỡ lỗi chi tiết.", + "ws_auth_enable": "Yêu cầu xác thực cho /ws/*", + "routing_strategy_round_robin": "round-robin (luân phiên)", + "routing_strategy_weighted_round_robin": "weighted-round-robin (luân phiên có trọng số)", + "routing_strategy_fill_first": "fill-first (ưu tiên lấp đầy)" + }, + "auth_files": { + "title": "Quản lý File xác thực", + "meta_total": "{{count}} credential", + "meta_active": "{{count}} đang hoạt động", + "meta_problem": "{{count}} có vấn đề", + "empty_title": "Chưa có credential nào", + "empty_desc": "Tải lên file xác thực hoặc kết nối provider qua OAuth để bắt đầu.", + "empty_oauth_link": "Kết nối qua OAuth", + "no_results_clear": "Xóa bộ lọc", + "title_section": "File xác thực", + "upload_button": "Tải file lên", + "delete_all_button": "Xóa tất cả", + "search_empty_title": "Không có file phù hợp", + "search_empty_desc": "Hãy thử đổi bộ lọc hoặc xóa ô tìm kiếm.", + "file_size": "Kích thước", + "file_modified": "Đã sửa", + "health_status_label": "Sức khỏe", + "health_status_healthy": "Khỏe mạnh", + "health_status_warning": "Cảnh báo", + "health_status_disabled": "Đã tắt", + "download_button": "Tải xuống", + "manual_refresh_button": "Làm mới credential OAuth", + "manual_refresh_requested": "Đã yêu cầu làm mới credential cho \"{{name}}\"", + "manual_refresh_failed": "Không thể yêu cầu làm mới credential cho \"{{name}}\": {{message}}", + "delete_button": "Xóa", + "delete_confirm": "Bạn có chắc muốn xóa file", + "delete_all_confirm": "Bạn có chắc muốn xóa tất cả file xác thực? Thao tác này không thể hoàn tác!", + "delete_filtered_confirm": "Bạn có chắc muốn xóa tất cả file xác thực {{type}}? Thao tác này không thể hoàn tác!", + "delete_problem_button": "Xóa file có vấn đề", + "delete_problem_button_with_type": "Xóa file {{type}} có vấn đề", + "delete_problem_confirm": "Bạn có chắc muốn xóa tất cả file xác thực có vấn đề? Thao tác này không thể hoàn tác!", + "delete_problem_filtered_confirm": "Bạn có chắc muốn xóa tất cả file xác thực {{type}} có vấn đề? Thao tác này không thể hoàn tác!", + "delete_filtered_result_button": "Xóa kết quả đã lọc", + "delete_filtered_result_confirm": "Bạn có chắc muốn xóa các file xác thực trong kết quả lọc hiện tại? Thao tác này không thể hoàn tác!", + "upload_error_json": "Chỉ chấp nhận file JSON", + "upload_error_size": "Kích thước file không được vượt quá {{maxSize}}", + "upload_success": "Tải file lên thành công", + "download_success": "Tải file xuống thành công", + "delete_success": "Xóa file thành công", + "delete_all_success": "Đã xóa thành công", + "delete_filtered_success": "Đã xóa thành công {{count}} file xác thực {{type}}", + "delete_filtered_partial": "Hoàn tất xóa file xác thực {{type}}: {{success}} thành công, {{failed}} thất bại", + "delete_filtered_none": "Không có file xác thực nào xóa được trong bộ lọc hiện tại ({{type}})", + "delete_problem_success": "Đã xóa thành công {{count}} file xác thực có vấn đề", + "delete_problem_filtered_success": "Đã xóa thành công {{count}} file xác thực {{type}} có vấn đề", + "delete_problem_partial": "Hoàn tất xóa file xác thực có vấn đề: {{success}} thành công, {{failed}} thất bại", + "delete_problem_filtered_partial": "Hoàn tất xóa file xác thực {{type}} có vấn đề: {{success}} thành công, {{failed}} thất bại", + "delete_problem_none": "Không có file xác thực có vấn đề nào xóa được trong bộ lọc hiện tại", + "delete_problem_filtered_none": "Không có file xác thực {{type}} có vấn đề nào xóa được trong bộ lọc hiện tại", + "delete_filtered_result_success": "Đã xóa thành công {{count}} file xác thực từ kết quả lọc", + "delete_filtered_result_partial": "Hoàn tất xóa kết quả lọc: {{success}} thành công, {{failed}} thất bại", + "delete_filtered_result_none": "Không có file xác thực nào xóa được trong kết quả lọc hiện tại", + "pagination_prev": "Trước", + "pagination_next": "Sau", + "pagination_info": "Trang {{current}} / {{total}} · {{count}} file", + "search_label": "Tìm kiếm cấu hình", + "search_placeholder": "Lọc theo tên, tài khoản, loại hoặc provider. Dùng * làm ký tự đại diện", + "problem_filter_label": "Lọc trạng thái", + "problem_filter_all": "Tất cả", + "problem_filter_enabled": "Đang bật", + "problem_filter_problem": "Có vấn đề", + "problem_filter_disabled": "Đã tắt", + "display_options_label": "Tùy chọn hiển thị", + "compact_mode_label": "Chế độ thu gọn", + "sort_label": "Sắp xếp", + "sort_default": "Mặc định", + "sort_az": "Tên A-Z", + "sort_priority": "Ưu tiên", + "priority_display": "Ưu tiên", + "weight_display": "Trọng số WRR", + "page_size_label": "Mỗi trang", + "filter_all": "Tất cả", + "filter_qwen": "Qwen", + "filter_gemini": "Gemini", + "filter_kimi": "Kimi", + "filter_aistudio": "AIStudio", + "filter_claude": "Claude", + "filter_codex": "Codex", + "filter_antigravity": "Antigravity", + "filter_xai": "xAI", + "filter_iflow": "iFlow", + "filter_vertex": "Vertex", + "filter_empty": "Trống", + "filter_unknown": "Khác", + "type_virtual": "File xác thực ảo", + "models_button": "Model", + "models_title": "Model được hỗ trợ", + "models_loading": "Đang tải danh sách model...", + "models_empty": "Không có model khả dụng cho credential này", + "models_empty_desc": "Credential này có thể chưa được máy chủ nạp, hoặc chưa có model nào gắn với nó.", + "models_unsupported": "Phiên bản hiện tại không hỗ trợ tính năng này", + "models_unsupported_desc": "Vui lòng cập nhật CLI Proxy API lên phiên bản mới nhất và thử lại", + "models_excluded_badge": "Đã tắt", + "models_excluded_hint": "Model OAuth này đã bị tắt", + "status_toggle_label": "Đang bật", + "status_enabled_success": "\"{{name}}\" đã được bật", + "status_disabled_success": "\"{{name}}\" đã được tắt", + "batch_status_success": "Đã cập nhật thành công {{count}} file", + "batch_status_partial": "{{success}} đã cập nhật, {{failed}} thất bại", + "batch_delete_title": "Xóa các file đã chọn", + "batch_delete_confirm": "Bạn có chắc muốn xóa {{count}} file?", + "batch_selected": "Đã chọn {{count}}", + "batch_toolbar_label": "Hành động hàng loạt", + "batch_select_all": "Chọn tất cả", + "batch_select_page": "Chọn trang này", + "batch_select_filtered": "Chọn đã lọc", + "batch_invert_page": "Đảo lựa chọn trang", + "batch_deselect": "Bỏ chọn", + "batch_download": "Tải xuống đã chọn", + "batch_download_success": "Đã bắt đầu tải xuống {{count}} file", + "batch_download_partial": "Hoàn tất tải xuống: {{success}} thành công, {{failed}} thất bại", + "batch_enable": "Bật", + "batch_disable": "Tắt", + "prefix_proxy_button": "Chi tiết / Chỉnh sửa File xác thực", + "prefix_proxy_loading": "Đang tải file xác thực...", + "prefix_proxy_info_label": "Thông tin file xác thực (info)", + "prefix_proxy_source_label": "JSON file xác thực (xem trước)", + "prefix_proxy_invalid_content_label": "Nội dung đã tải (bị cắt)", + "prefix_label": "Tiền tố (prefix)", + "proxy_url_label": "URL Proxy (proxy_url)", + "proxy_url_placeholder": "socks5://username:password@proxy_ip:port/", + "priority_label": "Ưu tiên (priority)", + "priority_placeholder": "ví dụ 10 hoặc -1", + "priority_hint": "Chỉ nhận số nguyên. Giá trị không hợp lệ sẽ bị bỏ qua. Giá trị lớn hơn nghĩa là ưu tiên cao hơn.", + "weight_label": "Trọng số điều phối (weight)", + "weight_hint": "Mặc định là 1. Giá trị ≤ 0 sẽ loại credential này khỏi điều phối có trọng số; tối đa 1.000.000.", + "weight_invalid_integer": "Trọng số phải là số nguyên.", + "weight_invalid_max": "Trọng số không được vượt quá 1.000.000.", + "disable_cooling_label": "Tắt cooldown lũy thừa (disable_cooling)", + "disable_cooling_hint": "Bỏ qua cooldown thất bại và backoff lũy thừa chỉ cho credential này; các credential khác không bị ảnh hưởng.", + "websockets_label": "WebSocket (websockets)", + "websockets_hint": "Bật truyền tải websocket của Responses API cho credential này.", + "using_api_label": "Dùng API chính thức (using_api)", + "using_api_hint": "Dùng API xAI chính thức khi bật; dùng chat-proxy Grok CLI khi tắt.", + "note_label": "Ghi chú", + "note_placeholder": "Nhập ghi chú, ví dụ: Tài khoản của John", + "note_hint": "Tùy chọn. Dùng để mô tả mục đích hoặc chủ sở hữu của credential này; để trống nếu không cần.", + "excluded_models_label": "Model bị loại trừ (excluded_models)", + "headers_label": "Header tùy chỉnh (headers)", + "headers_placeholder": "{\n \"Header-Name\": \"value\"\n}", + "headers_hint": "Nhập header HTTP tùy chỉnh dưới dạng đối tượng JSON, ví dụ {\"X-My-Header\": \"value\"}", + "headers_invalid_json": "Header tùy chỉnh phải là JSON hợp lệ.", + "headers_invalid_object": "Header tùy chỉnh phải là một đối tượng JSON.", + "headers_invalid_value": "Mỗi giá trị header tùy chỉnh phải là chuỗi.", + "prefix_proxy_invalid_json": "File xác thực này không phải đối tượng JSON nên không thể chỉnh sửa các trường.", + "prefix_proxy_html_challenge": "Nội dung tải xuống là trang HTML challenge, không phải đối tượng JSON xác thực. Hãy xác thực lại hoặc thay file xác thực này trước khi chỉnh sửa.", + "prefix_proxy_saved_success": "Đã cập nhật file xác thực \"{{name}}\" thành công", + "quota_refresh_single": "Làm mới quota", + "quota_refresh_hint": "Chỉ làm mới quota cho credential này", + "quota_refresh_success": "Đã làm mới quota cho \"{{name}}\"", + "quota_refresh_failed": "Không thể làm mới quota cho \"{{name}}\": {{message}}" + }, + "antigravity_subscription": { + "plan_unknown": "Không rõ", + "plan_free": "Miễn phí", + "plan_pro": "Pro", + "plan_ultra": "Ultra", + "plan_ultra_lite": "Ultra Lite" + }, + "antigravity_quota": { + "title": "Quota Antigravity", + "empty_title": "Không có File xác thực Antigravity", + "empty_desc": "Tải lên credential Antigravity để xem quota còn lại.", + "idle": "Nhấn vào đây để làm mới quota", + "loading": "Đang tải quota...", + "load_failed": "Không thể tải quota: {{message}}", + "missing_auth_index": "File xác thực thiếu auth_index", + "missing_project_id": "Credential Antigravity thiếu project_id. Đăng nhập lại hoặc làm mới credential để xác định project.", + "empty_models": "Chưa có dữ liệu quota", + "plan_label": "Gói", + "group_gemini_models": "Model Gemini", + "group_claude_gpt_models": "Model Claude và GPT", + "group_models_description": "Các model trong nhóm này: {{models}}", + "weekly_limit": "Giới hạn tuần", + "daily_limit": "Giới hạn ngày", + "five_hour_limit": "Giới hạn 5 giờ", + "monthly_limit": "Giới hạn tháng", + "quota_available": "Quota khả dụng", + "remaining_percent": "Còn lại {{percent}}%", + "refreshes_in": "Làm mới sau {{duration}}", + "refresh_available": "Có thể làm mới", + "duration_day_hour": "{{days}}n {{hours}}g", + "duration_hour_minute": "{{hours}}g {{minutes}}p", + "duration_minute": "{{minutes}}p", + "duration_less_than_minute": "<1p", + "refresh_button": "Làm mới Quota", + "fetch_all": "Lấy tất cả" + }, + "claude_quota": { + "title": "Quota Claude", + "empty_title": "Không có File OAuth Claude", + "empty_desc": "Đăng nhập bằng Claude OAuth để xem quota.", + "idle": "Nhấn vào đây để làm mới quota", + "loading": "Đang tải quota...", + "load_failed": "Không thể tải quota: {{message}}", + "missing_auth_index": "File xác thực thiếu auth_index", + "empty_windows": "Chưa có dữ liệu quota", + "refresh_button": "Làm mới Quota", + "fetch_all": "Lấy tất cả", + "five_hour": "Giới hạn 5 giờ", + "seven_day": "Giới hạn 7 ngày", + "seven_day_oauth_apps": "OAuth apps 7 ngày", + "seven_day_opus": "Opus 7 ngày", + "seven_day_sonnet": "Sonnet 7 ngày", + "seven_day_cowork": "Cowork 7 ngày", + "iguana_necktie": "Iguana Necktie", + "seven_day_fable": "Fable 5 · 7 ngày", + "extra_usage_label": "Sử dụng thêm", + "plan_label": "Gói", + "plan_unknown": "Không rõ", + "plan_free": "Miễn phí", + "plan_pro": "Pro", + "plan_max": "Max", + "plan_max5": "Max 5x", + "plan_max20": "Max 20x", + "plan_team": "Team" + }, + "codex_quota": { + "title": "Quota Codex", + "empty_title": "Không có File xác thực Codex", + "empty_desc": "Tải lên credential Codex để xem quota.", + "idle": "Nhấn vào đây để làm mới quota", + "loading": "Đang tải quota...", + "load_failed": "Không thể tải quota: {{message}}", + "missing_auth_index": "File xác thực thiếu auth_index", + "missing_account_id": "Credential Codex thiếu ID tài khoản ChatGPT", + "empty_windows": "Chưa có dữ liệu quota", + "no_access": "Credential này không có quyền truy cập Codex (gói: free).", + "refresh_button": "Làm mới Quota", + "fetch_all": "Lấy tất cả", + "primary_window": "Giới hạn 5 giờ", + "secondary_window": "Giới hạn tuần", + "team_secondary_window": "Giới hạn tháng", + "code_review_primary_window": "Giới hạn 5 giờ cho code review", + "code_review_secondary_window": "Giới hạn tuần cho code review", + "code_review_team_secondary_window": "Giới hạn tháng cho code review", + "additional_primary_window": "Giới hạn 5 giờ của {{name}}", + "additional_secondary_window": "Giới hạn tuần của {{name}}", + "additional_team_secondary_window": "Giới hạn tháng của {{name}}", + "plan_label": "Gói", + "expires_label": "Thời gian gia hạn", + "reset_credits_label": "Lượt đặt lại thủ công", + "reset_credits_expiry_label": "Hết hạn đặt lại thủ công ({{timezone}})", + "reset_credit_number": "Lượt đặt lại {{index}}", + "reset_credits_expiry_failed": "Không thể tải thời hạn đặt lại thủ công: {{message}}", + "reset_credits_invalid_payload": "Phản hồi thời hạn đặt lại thủ công không hợp lệ", + "reset_button": "Đặt lại quota", + "reset_confirm_title": "Đặt lại quota Codex", + "reset_confirm_message": "Thao tác này sẽ dùng 1 lượt đặt lại thủ công để đặt lại quota Codex cho \"{{name}}\". Tiếp tục?", + "reset_confirm_button": "Đặt lại quota", + "reset_success": "Đã đặt lại quota Codex cho \"{{name}}\"", + "reset_failed": "Không thể đặt lại quota Codex cho \"{{name}}\": {{message}}", + "plan_plus": "Plus", + "plan_team": "Team", + "plan_free": "Miễn phí", + "plan_pro": "Pro 20x", + "plan_prolite": "Pro 5x" + }, + "kimi_quota": { + "title": "Quota Kimi", + "empty_title": "Không có File xác thực Kimi", + "empty_desc": "Tải lên credential Kimi để xem quota còn lại.", + "idle": "Nhấn vào đây để làm mới quota", + "loading": "Đang tải quota...", + "load_failed": "Không thể tải quota: {{message}}", + "missing_auth_index": "File xác thực thiếu auth_index", + "empty_data": "Chưa có dữ liệu quota", + "refresh_button": "Làm mới Quota", + "fetch_all": "Lấy tất cả", + "weekly_limit": "Giới hạn tuần", + "limit_window": "Giới hạn {{duration}}", + "limit_index": "Giới hạn #{{index}}", + "reset_hint": "đặt lại sau {{hint}}" + }, + "xai_quota": { + "title": "Quota Grok", + "empty_title": "Không có File xác thực xAI/Grok", + "empty_desc": "Đăng nhập bằng xAI OAuth để xem quota Grok.", + "idle": "Nhấn vào đây để làm mới quota", + "loading": "Đang tải quota...", + "load_failed": "Không thể tải quota: {{message}}", + "missing_auth_index": "File xác thực thiếu auth_index", + "empty_data": "Chưa có dữ liệu quota", + "refresh_button": "Làm mới Quota", + "fetch_all": "Lấy tất cả", + "weekly_limit": "Giới hạn tuần", + "monthly_credits": "Credit tháng", + "used_percent": "Đã dùng {{percent}}", + "reset_at": "Đặt lại lúc {{time}}", + "product_usage": "Mức sử dụng {{product}}", + "plan_label": "Gói", + "plan_supergrok": "SuperGrok", + "plan_supergrok_heavy": "SuperGrok Heavy", + "plan_paid": "Trả phí", + "paid_health": "API chat trả phí khả dụng. xAI không công bố tổng quota cho credential OAuth này.", + "pay_as_you_go_label": "Trả theo mức sử dụng", + "pay_as_you_go_enabled": "Đang bật, giới hạn {{cap}}", + "pay_as_you_go_disabled": "Đã tắt" + }, + "vertex_import": { + "title": "Đăng nhập Vertex bằng JSON", + "description": "Tải lên file JSON service account của Google để lưu thành auth-dir/vertex-.json theo cùng quy tắc với công cụ vertex-import của CLI.", + "location_label": "Khu vực (tùy chọn)", + "location_placeholder": "us-central1", + "location_hint": "Để trống để dùng khu vực mặc định us-central1.", + "file_label": "JSON key của service account", + "file_hint": "Chỉ chấp nhận file JSON key của service account Google Cloud.", + "file_placeholder": "Chưa chọn file", + "choose_file": "Chọn File", + "import_button": "Nhập Credential Vertex", + "file_required": "Hãy chọn file credential .json trước", + "success": "Đã nhập credential Vertex thành công", + "result_title": "Đã lưu credential", + "result_project": "Project ID", + "result_email": "Service account", + "result_location": "Khu vực", + "result_file": "File đã lưu" + }, + "oauth_excluded": { + "title": "Vô hiệu hóa Model OAuth", + "description": "Việc vô hiệu hóa model theo từng provider được hiển thị dưới dạng thẻ; nhấn vào thẻ để chỉnh sửa hoặc xóa. Hỗ trợ ký tự đại diện * và phạm vi áp dụng theo bộ lọc file xác thực.", + "add": "Thêm vô hiệu hóa", + "add_title": "Thêm vô hiệu hóa model của provider", + "edit_title": "Chỉnh sửa vô hiệu hóa model cho {{provider}}", + "provider_label": "Provider", + "provider_placeholder": "ví dụ codex / openai", + "provider_hint": "Mặc định theo bộ lọc hiện tại; chọn provider có sẵn hoặc nhập tên mới.", + "models_label": "Model cần vô hiệu hóa", + "save": "Lưu/Cập nhật", + "save_success": "Đã cập nhật vô hiệu hóa model", + "save_failed": "Không thể cập nhật vô hiệu hóa model", + "delete": "Xóa Provider", + "delete_confirm": "Xóa vô hiệu hóa model của {{provider}}?", + "delete_success": "Đã xóa vô hiệu hóa model của provider", + "delete_failed": "Không thể xóa vô hiệu hóa model", + "no_models": "Chưa cấu hình model bị vô hiệu hóa nào", + "model_count": "{{count}} model bị vô hiệu hóa", + "list_empty_all": "Chưa có vô hiệu hóa model provider nào; nhấn “Thêm vô hiệu hóa” để tạo.", + "provider_required": "Vui lòng nhập provider trước", + "upgrade_required": "Phiên bản CPA hiện tại không hỗ trợ vô hiệu hóa model OAuth. Vui lòng nâng cấp.", + "upgrade_required_title": "Vui lòng nâng cấp CLI Proxy API", + "upgrade_required_desc": "Phiên bản máy chủ hiện tại không hỗ trợ lấy danh sách vô hiệu hóa model OAuth. Vui lòng nâng cấp lên phiên bản CPA (CLI Proxy API) mới nhất và thử lại." + }, + "excluded_models": { + "trigger_summary": "{{excluded}} bị loại trừ · {{available}} khả dụng", + "trigger_summary_rules": "{{n}} quy tắc", + "trigger_empty": "Không có model nào bị loại trừ", + "meter_aria": "{{excluded}} trong {{total}} model bị loại trừ", + "search_placeholder": "Tìm model…", + "search_aria": "Tìm model để loại trừ", + "list_aria": "Model", + "no_results": "Không có model nào khớp “{{query}}”", + "catalog_loading": "Đang tải model…", + "catalog_unavailable": "Không lấy được danh sách model — các quy tắc vẫn được áp dụng.", + "catalog_error": "Không thể tải danh sách model.", + "catalog_retry": "Thử lại", + "catalog_empty": "Không có model nào để liệt kê.", + "footer_count": "{{excluded}} / {{total}} bị loại trừ", + "select_all": "Loại trừ tất cả", + "clear": "Xóa", + "clear_aria": "Bỏ chọn các model (giữ lại quy tắc ký tự đại diện)", + "badge_wildcard": "Theo quy tắc", + "badge_unknown": "Không có trong danh sách", + "wildcard_reason": "Khớp quy tắc {{rule}}", + "wildcard_locked": "Bị loại trừ bởi quy tắc {{rule}} — hãy sửa quy tắc bên dưới", + "also_wildcard": "Cũng khớp {{rule}}", + "chips_more": "+{{n}} khác", + "chip_remove": "Ngừng loại trừ {{rule}}", + "rules_label": "Quy tắc ký tự đại diện", + "rules_placeholder": "Mỗi dòng một quy tắc, ví dụ gpt-5-*", + "rules_hint": "* khớp mọi ký tự. Không phân biệt hoa thường.", + "rules_match_count": "khớp {{n}} model", + "rules_match_none": "không khớp model nào trong danh sách", + "rules_reserved": "“*” vô hiệu hóa toàn bộ provider — hãy dùng công tắc Đã tắt thay thế" + }, + "oauth_model_alias": { + "title": "Bí danh Model OAuth", + "add": "Thêm bí danh", + "add_title": "Thêm bí danh model của provider", + "provider_label": "Provider", + "provider_placeholder": "ví dụ codex / vertex", + "provider_hint": "Mặc định theo bộ lọc hiện tại; chọn provider có sẵn hoặc nhập tên mới.", + "model_source_loading": "Đang tải model...", + "model_source_unsupported": "Phiên bản CPA hiện tại không hỗ trợ lấy danh sách model (vẫn có thể nhập thủ công).", + "model_source_loaded": "Đã tải {{count}} model. Dùng menu thả trong 'Tên model gốc', hoặc nhập giá trị tùy chỉnh. Lưu danh sách trống sẽ xóa provider đó. Bật 'Giữ tên gốc' để giữ tên gốc trong khi thêm bí danh.", + "alias_label": "Bí danh model", + "alias_name_placeholder": "Tên model gốc", + "alias_placeholder": "Bí danh (bắt buộc)", + "duplicate_alias": "Mỗi bí danh phải là duy nhất cho provider này.", + "alias_fork_label": "Giữ tên gốc", + "add_alias": "Thêm bí danh", + "save": "Lưu/Cập nhật", + "save_success": "Đã cập nhật bí danh model", + "save_failed": "Không thể cập nhật bí danh model", + "delete": "Xóa Provider", + "delete_confirm": "Xóa bí danh model của {{provider}}?", + "delete_link_title": "Bỏ liên kết ánh xạ", + "delete_link_confirm": "Bỏ liên kết ánh xạ từ {{sourceModel}} ({{provider}}) sang bí danh {{alias}}?", + "delete_alias_title": "Xóa bí danh", + "delete_alias_confirm": "Xóa bí danh {{alias}} và bỏ ánh xạ tất cả model liên quan?", + "delete_success": "Đã xóa bí danh model", + "delete_failed": "Không thể xóa bí danh model", + "no_models": "Không có bí danh model", + "model_count": "{{count}} bí danh", + "list_empty_all": "Chưa có bí danh model nào—dùng “Thêm bí danh” để tạo.", + "chart_title": "Tổng quan mọi ánh xạ", + "diagram_providers": "Provider", + "diagram_source_models": "Model gốc", + "diagram_aliases": "Bí danh", + "diagram_expand": "Mở rộng", + "diagram_collapse": "Thu gọn", + "diagram_add_alias": "Thêm bí danh", + "diagram_rename": "Đổi tên", + "diagram_rename_alias_title": "Đổi tên bí danh", + "diagram_rename_alias_label": "Tên bí danh mới", + "diagram_rename_placeholder": "Nhập tên bí danh...", + "diagram_delete_link": "Bỏ liên kết khỏi {{provider}} / {{name}}", + "diagram_delete_alias": "Xóa bí danh", + "diagram_please_enter_alias": "Vui lòng nhập tên bí danh.", + "diagram_alias_exists": "Bí danh này đã tồn tại.", + "diagram_add_alias_title": "Thêm bí danh", + "diagram_add_alias_label": "Tên bí danh", + "diagram_add_placeholder": "Nhập tên bí danh mới...", + "diagram_rename_btn": "Đổi tên", + "diagram_add_btn": "Thêm", + "diagram_settings": "Cài đặt", + "diagram_settings_title": "Cài đặt bí danh — {{alias}}", + "diagram_settings_source_title": "Cài đặt model gốc", + "diagram_settings_empty": "Chưa có ánh xạ nào cho bí danh này.", + "diagram_tap_hint": "Trên thiết bị cảm ứng: chạm vào model gốc, sau đó chạm vào bí danh để liên kết.", + "view_mode_diagram": "Sơ đồ", + "view_mode_list": "Danh sách", + "provider_required": "Vui lòng nhập provider trước", + "upgrade_required": "Tính năng này yêu cầu phiên bản CLI Proxy API (CPA) mới hơn. Vui lòng nâng cấp.", + "upgrade_required_title": "Vui lòng nâng cấp CLI Proxy API", + "upgrade_required_desc": "Máy chủ hiện tại không hỗ trợ API bí danh model OAuth. Vui lòng nâng cấp lên phiên bản CLI Proxy API (CPA) mới nhất." + }, + "auth_login": { + "recommended_provider_section": "Provider đề xuất", + "recommended_provider_badge": "Provider đề xuất", + "other_oauth_providers": "Provider OAuth khác", + "other_login_methods": "Phương thức đăng nhập khác", + "codex_oauth_title": "Codex OAuth", + "codex_oauth_button": "Bắt đầu đăng nhập Codex", + "codex_oauth_hint": "Đăng nhập dịch vụ Codex qua luồng OAuth, tự động lấy và lưu file xác thực.", + "codex_oauth_url_label": "URL ủy quyền:", + "codex_open_link": "Mở liên kết", + "codex_copy_link": "Sao chép liên kết", + "codex_oauth_status_waiting": "Đang chờ xác thực...", + "codex_oauth_status_success": "Xác thực thành công!", + "codex_oauth_status_error": "Xác thực thất bại:", + "codex_oauth_start_error": "Không thể bắt đầu Codex OAuth:", + "codex_oauth_polling_error": "Không thể kiểm tra trạng thái xác thực:", + "anthropic_oauth_title": "Anthropic OAuth", + "anthropic_oauth_button": "Bắt đầu đăng nhập Anthropic", + "anthropic_oauth_hint": "Đăng nhập dịch vụ Anthropic (Claude) qua luồng OAuth, tự động lấy và lưu file xác thực.", + "anthropic_oauth_url_label": "URL ủy quyền:", + "anthropic_open_link": "Mở liên kết", + "anthropic_copy_link": "Sao chép liên kết", + "anthropic_oauth_status_waiting": "Đang chờ xác thực...", + "anthropic_oauth_status_success": "Xác thực thành công!", + "anthropic_oauth_status_error": "Xác thực thất bại:", + "anthropic_oauth_start_error": "Không thể bắt đầu Anthropic OAuth:", + "anthropic_oauth_polling_error": "Không thể kiểm tra trạng thái xác thực:", + "antigravity_oauth_title": "Antigravity OAuth", + "antigravity_oauth_button": "Bắt đầu đăng nhập Antigravity", + "antigravity_oauth_hint": "Đăng nhập dịch vụ Antigravity (tài khoản Google) qua luồng OAuth, tự động lấy và lưu file xác thực.", + "antigravity_oauth_url_label": "URL ủy quyền:", + "antigravity_open_link": "Mở liên kết", + "antigravity_copy_link": "Sao chép liên kết", + "antigravity_oauth_status_waiting": "Đang chờ xác thực...", + "antigravity_oauth_status_success": "Xác thực thành công!", + "antigravity_oauth_status_error": "Xác thực thất bại:", + "antigravity_oauth_start_error": "Không thể bắt đầu Antigravity OAuth:", + "antigravity_oauth_polling_error": "Không thể kiểm tra trạng thái xác thực:", + "kimi_oauth_title": "Kimi OAuth", + "kimi_oauth_button": "Đăng nhập bằng Kimi", + "kimi_sign_up_button": "Đăng ký ngay", + "kimi_oauth_hint": "Đăng nhập nhanh vào Kimi qua ủy quyền thiết bị. File xác thực được lấy và lưu tự động.", + "kimi_oauth_url_label": "URL ủy quyền:", + "kimi_open_link": "Mở liên kết", + "kimi_copy_link": "Sao chép liên kết", + "kimi_oauth_status_waiting": "Đang chờ xác thực...", + "kimi_oauth_status_success": "Xác thực thành công!", + "kimi_oauth_status_error": "Xác thực thất bại:", + "kimi_oauth_start_error": "Không thể bắt đầu Kimi OAuth:", + "kimi_oauth_polling_error": "Không thể kiểm tra trạng thái xác thực:", + "xai_oauth_title": "xAI OAuth", + "xai_oauth_button": "Bắt đầu đăng nhập xAI", + "xai_oauth_hint": "Đăng nhập xAI Grok qua luồng OAuth, tự động lấy và lưu file xác thực.", + "xai_oauth_url_label": "URL ủy quyền:", + "xai_open_link": "Mở liên kết", + "xai_copy_link": "Sao chép liên kết", + "xai_oauth_status_waiting": "Đang chờ xác thực...", + "xai_oauth_status_success": "Xác thực thành công!", + "xai_oauth_status_error": "Xác thực thất bại:", + "xai_oauth_start_error": "Không thể bắt đầu xAI OAuth:", + "xai_oauth_polling_error": "Không thể kiểm tra trạng thái xác thực:", + "plugin_oauth_title": "{{name}} OAuth", + "plugin_oauth_button": "Bắt đầu đăng nhập {{name}}", + "plugin_oauth_hint": "Đăng nhập {{name}} qua luồng OAuth của plugin, tự động lấy và lưu file xác thực.", + "plugin_oauth_url_label": "URL ủy quyền:", + "plugin_open_link": "Mở liên kết", + "plugin_copy_link": "Sao chép liên kết", + "plugin_oauth_status_waiting": "Đang chờ xác thực...", + "plugin_oauth_status_success": "Xác thực thành công!", + "plugin_oauth_status_error": "Xác thực thất bại:", + "plugin_oauth_start_error": "Không thể bắt đầu plugin OAuth:", + "xai_callback_label": "URL callback hoặc mã", + "xai_callback_placeholder": "Dán mã mà Grok hiển thị, hoặc URL callback đầy đủ", + "xai_callback_hint": "Grok có thể chỉ hiển thị mã trên trang. Dán trực tiếp mã đó và ứng dụng sẽ tự động gửi dưới dạng http://127.0.0.1:56121/callback?...", + "xai_callback_required": "Vui lòng dán mã Grok hiển thị hoặc URL callback đầy đủ trước.", + "xai_callback_state_missing": "Thiếu state cho lần đăng nhập xAI này. Hãy bắt đầu đăng nhập xAI lại, sau đó gửi mã.", + "oauth_callback_label": "URL callback", + "oauth_callback_placeholder": "http://localhost:1455/auth/callback?code=...&state=...", + "oauth_callback_hint": "Chế độ trình duyệt từ xa: sau khi provider chuyển hướng đến http://localhost:..., hãy sao chép URL đầy đủ và gửi tại đây.", + "oauth_callback_button": "Gửi URL callback", + "oauth_callback_required": "Vui lòng dán URL chuyển hướng đầy đủ trước.", + "oauth_callback_success": "Đã gửi URL callback. Tiếp tục chờ xác thực.", + "oauth_callback_error": "Không thể gửi URL callback:", + "oauth_callback_upgrade_hint": "Vui lòng cập nhật CLI Proxy API hoặc kiểm tra kết nối.", + "oauth_callback_status_success": "Đã gửi URL callback, đang chờ xác thực...", + "oauth_callback_status_error": "Gửi URL callback thất bại:", + "missing_state": "Không thể lấy tham số trạng thái xác thực", + "login_another_account": "Đăng nhập tài khoản khác", + "view_auth_files": "Xem file xác thực", + "iflow_oauth_title": "iFlow OAuth", + "iflow_oauth_button": "Bắt đầu đăng nhập iFlow", + "iflow_oauth_hint": "Đăng nhập dịch vụ iFlow qua luồng OAuth, tự động lấy và lưu file xác thực.", + "iflow_oauth_url_label": "URL ủy quyền:", + "iflow_open_link": "Mở liên kết", + "iflow_copy_link": "Sao chép liên kết", + "iflow_oauth_status_waiting": "Đang chờ xác thực...", + "iflow_oauth_status_success": "Xác thực thành công!", + "iflow_oauth_status_error": "Xác thực thất bại:", + "iflow_oauth_start_error": "Không thể bắt đầu iFlow OAuth:", + "iflow_oauth_polling_error": "Không thể kiểm tra trạng thái xác thực:", + "remote_access_disabled": "Phương thức đăng nhập này không khả dụng cho truy cập từ xa. Vui lòng truy cập từ localhost." + }, + "stats": { + "success": "Thành công", + "failure": "Thất bại" + }, + "status_bar": { + "success_short": "✓", + "failure_short": "✗", + "no_requests": "Không có yêu cầu" + }, + "logs": { + "title": "Trình xem Log", + "refresh_button": "Làm mới Log", + "clear_button": "Xóa Log", + "fullscreen_button": "Toàn màn hình", + "exit_fullscreen_button": "Thoát toàn màn hình", + "download_button": "Tải Log xuống", + "error_logs_modal_title": "Log yêu cầu lỗi", + "error_logs_description": "Chọn file log yêu cầu lỗi để mở hoặc tải xuống (chỉ được tạo khi tính năng ghi log yêu cầu đang tắt).", + "error_logs_request_log_enabled": "Ghi log yêu cầu đang bật nên danh sách này sẽ luôn trống. Hãy tắt ghi log yêu cầu và làm mới để xem log lỗi.", + "error_logs_empty": "Không tìm thấy file log yêu cầu lỗi nào", + "error_logs_load_error": "Không thể tải danh sách log lỗi", + "error_logs_size": "Kích thước", + "error_logs_modified": "Sửa lần cuối", + "error_logs_open": "Mở", + "error_logs_download": "Tải xuống", + "error_log_view_title": "Chi tiết Log yêu cầu lỗi", + "error_log_open_failed": "Không thể mở log lỗi", + "error_log_empty_content": "Log lỗi này trống", + "error_log_copy_success": "Đã sao chép nội dung log lỗi", + "error_log_download_success": "Đã tải log lỗi xuống thành công", + "request_log_download_title": "Tải xuống Log yêu cầu", + "request_log_download_confirm": "Tải xuống log yêu cầu của ID {{id}}?", + "request_log_download_success": "Đã tải log yêu cầu xuống thành công", + "empty_title": "Chưa có Log", + "empty_desc": "Khi bật \"Ghi log ra file\", log sẽ hiển thị tại đây", + "cpa_file_logging_required": "Runtime đang kết nối là CPA. Xem log yêu cầu bật ghi log ra file trước.", + "cpa_file_logging_required_title": "Cần bật ghi log ra file", + "cpa_file_logging_required_desc": "CPA đọc khung xem log này từ file log cục bộ. Hãy bật logging-to-file trong cấu hình rồi làm mới.", + "file_logging_required": "Endpoint log này cần bật ghi log ra file trước khi đọc được file log.", + "file_logging_required_title": "Cần bật ghi log ra file", + "file_logging_required_desc": "Endpoint log này đọc file log cục bộ. Hãy bật logging-to-file trong cấu hình rồi làm mới.", + "log_content": "Nội dung Log", + "loading": "Đang tải log...", + "load_error": "Không thể tải log", + "clear_confirm": "Bạn có chắc muốn xóa toàn bộ log? Thao tác này không thể hoàn tác!", + "clear_success": "Đã xóa log thành công", + "download_success": "Đã tải log xuống thành công", + "auto_refresh": "Tự động làm mới", + "load_more_hint": "Cuộn lên để tải thêm", + "hidden_lines": "Bị ẩn: {{count}} dòng", + "loaded_lines": "Đã tải: {{count}} dòng", + "filtered_lines": "Đã lọc: {{count}} dòng", + "hide_management_logs": "Ẩn log {{prefix}}", + "show_raw_logs": "Hiện Log thô", + "show_raw_logs_hint": "Hiện văn bản log gốc để dễ sao chép nhiều dòng", + "search_placeholder": "Tìm log theo nội dung hoặc từ khóa", + "filter_panel_title": "Bộ lọc cấu trúc", + "filter_panel_expand": "Mở bộ lọc cấu trúc", + "filter_panel_collapse": "Thu gọn bộ lọc cấu trúc", + "filter_panel_active_count": "{{count}} đang hoạt động", + "filter_method": "Phương thức", + "filter_status": "Trạng thái", + "filter_path": "Đường dẫn", + "filter_path_empty": "Không có ứng viên đường dẫn", + "filter_status_2xx": "2xx", + "filter_status_3xx": "3xx", + "filter_status_4xx": "4xx", + "filter_status_5xx": "5xx", + "clear_filters": "Xóa bộ lọc", + "search_empty_title": "Không tìm thấy log phù hợp", + "search_empty_desc": "Hãy thử từ khóa khác hoặc xóa bộ lọc.", + "double_click_copy_hint": "Nhấp đúp để sao chép dòng log thô", + "copy_success": "Đã sao chép log vào clipboard", + "copy_failed": "Sao chép thất bại" + }, + "config_management": { + "title": "Bảng cấu hình", + "meta_fields": "{{count}} cài đặt", + "meta_dirty": "{{count}} chưa lưu", + "meta_dirty_source": "Chỉnh sửa nguồn chưa lưu", + "meta_errors": "{{count}} lỗi xác thực", + "meta_synced": "Đã đồng bộ", + "actions": { + "discard": "Hủy thay đổi", + "save": "Lưu thay đổi" + }, + "discard_confirm_message": "Hủy mọi thay đổi chưa lưu và khôi phục phiên bản máy chủ gần nhất?", + "mode": { + "label": "Chế độ trình chỉnh sửa", + "visual": "Trực quan", + "source": "Mã nguồn" + }, + "reload": "Tải lại", + "reload_confirm_message": "Tải lại sẽ hủy các thay đổi chưa lưu của bạn. Bạn có muốn tiếp tục không?", + "save": "Lưu", + "status_loading": "Đang tải cấu hình...", + "status_loading_short": "Đang tải", + "status_loaded": "Đã tải cấu hình", + "status_loaded_short": "Đã tải", + "status_dirty": "Thay đổi chưa lưu", + "status_dirty_short": "Chưa lưu", + "status_disconnected": "Kết nối máy chủ để tải cấu hình", + "status_disconnected_short": "Mất kết nối", + "status_load_failed": "Tải thất bại", + "status_load_failed_short": "Thất bại", + "status_saving": "Đang lưu cấu hình...", + "status_saving_short": "Đang lưu", + "save_success": "Đã lưu cấu hình thành công", + "visual_mode_unavailable": "Trình chỉnh sửa trực quan không khả dụng cho đến khi sửa cú pháp YAML", + "visual_mode_unavailable_short": "Lỗi YAML", + "validation_blocked_short": "Sửa lỗi", + "visual_mode_unavailable_detail": "Trình chỉnh sửa trực quan không khả dụng vì cấu hình chứa YAML không hợp lệ: {{message}}", + "visual_mode_save_blocked": "Không thể lưu từ chế độ trực quan cho đến khi sửa cú pháp YAML", + "visual_mode_latest_yaml_invalid": "Cấu hình máy chủ mới nhất chứa YAML không hợp lệ. Hãy xem lại ở chế độ mã nguồn trước khi lưu thay đổi trực quan: {{message}}", + "editor_placeholder": "key: value", + "search_placeholder": "Tìm cấu hình...", + "search_button": "Tìm", + "search_no_results": "Không có kết quả", + "search_prev": "Trước", + "search_next": "Sau", + "diff": { + "title": "Xem lại thay đổi", + "confirm": "Xác nhận lưu", + "no_changes": "Không phát hiện thay đổi" + }, + "visual": { + "search": { + "placeholder": "Tìm cài đặt (nhãn hoặc key YAML)", + "no_results": "Không có cài đặt phù hợp" + }, + "sections": { + "common": { + "title": "Chung", + "description": "Các cài đặt dùng nhiều nhất, dùng chung dữ liệu với các mục đầy đủ" + }, + "connectivity": { + "title": "Truy cập & Xác thực", + "description": "Địa chỉ máy chủ, cổng, thư mục xác thực và API key" + }, + "logging": { + "title": "Ghi log & Chẩn đoán", + "description": "Debug, xuất log và thống kê sử dụng" + }, + "advanced": { + "title": "Nâng cao & Thử nghiệm", + "description": "Giả mạo header, cache chữ ký, nguồn plugin và các cài đặt ít thay đổi khác", + "plugins_title": "Plugin", + "signature_title": "Chữ ký Antigravity" + }, + "server": { + "host": "Địa chỉ Host", + "port": "Cổng" + }, + "tls": { + "title": "Cấu hình TLS/SSL", + "description": "Cài đặt kết nối HTTPS bảo mật", + "enable": "Bật TLS", + "enable_desc": "Bật kết nối HTTPS bảo mật", + "cert": "Đường dẫn file chứng chỉ", + "key": "Đường dẫn file khóa riêng" + }, + "remote": { + "title": "Quản lý từ xa", + "description": "Truy cập từ xa và cài đặt bảng điều khiển", + "allow_remote": "Cho phép truy cập từ xa", + "allow_remote_desc": "Cho phép truy cập quản lý từ máy chủ khác", + "disable_panel": "Tắt bảng điều khiển", + "disable_panel_desc": "Tắt bảng điều khiển web tích hợp", + "disable_auto_update_panel": "Tắt tự động cập nhật bảng điều khiển", + "disable_auto_update_panel_desc": "Tải bảng điều khiển khi thiếu lần đầu, nhưng không bao giờ tự cập nhật từ GitHub", + "secret_key": "Key quản lý", + "secret_key_placeholder": "Đặt key quản lý", + "panel_repo": "Repository bảng điều khiển" + }, + "auth": { + "auth_dir": "Thư mục xác thực (auth-dir)", + "auth_dir_hint": "Đường dẫn thư mục chứa file xác thực (hỗ trợ ~)" + }, + "system": { + "debug": "Chế độ Debug", + "debug_desc": "Bật ghi log debug chi tiết", + "commercial_mode": "Chế độ thương mại", + "commercial_mode_desc": "Tắt middleware tốn tài nguyên để hỗ trợ đồng thời cao", + "logging_to_file": "Ghi log ra file", + "logging_to_file_desc": "Lưu log vào file", + "plugins_enabled": "Bật hệ thống Plugin", + "plugins_enabled_desc": "Bật nạp plugin thư viện động chuẩn; từng phiên bản plugin vẫn được quản lý ở trang Plugin", + "plugin_store_sources": "Nguồn Plugin bên thứ ba", + "plugin_store_sources_desc": "Thêm nguồn registry plugin store; nguồn chính thức tích hợp luôn được giữ", + "plugin_store_sources_label": "URL registry nguồn plugin (plugins.store-sources)", + "plugin_store_sources_placeholder": "https://example.com/cliproxy-plugins/registry.json", + "plugin_store_sources_hint": "Mỗi dòng một URL registry.json. Dòng trống sẽ bị lọc khi lưu", + "plugin_store_auth": "Quy tắc xác thực Plugin Store", + "plugin_store_auth_desc": "Cấu hình header xác thực cho registry riêng tư, metadata GitHub Release hoặc tải artifact", + "plugin_store_auth_hint": "Chỉ nhập tên biến môi trường, không nhập token thật. Backend đọc giá trị từ môi trường runtime của nó.", + "store_auth_empty": "Chưa cấu hình quy tắc xác thực nào. Nguồn plugin công khai không cần.", + "store_auth_rule": "Quy tắc xác thực", + "store_auth_add": "Thêm quy tắc xác thực", + "store_auth_match": "Tiền tố URL khớp", + "store_auth_type": "Loại xác thực", + "store_auth_apply_to": "Áp dụng cho", + "store_auth_apply_to_hint": "Khi không chọn gì, quy tắc áp dụng cho mọi loại yêu cầu.", + "store_auth_apply_registry": "Registry", + "store_auth_apply_metadata": "Metadata", + "store_auth_apply_artifact": "Artifact", + "store_auth_type_none": "Không", + "store_auth_type_bearer": "Bearer", + "store_auth_type_basic": "Basic", + "store_auth_type_header": "Header tùy chỉnh", + "store_auth_type_github_token": "GitHub token", + "store_auth_token_env": "Biến môi trường token", + "store_auth_username_env": "Biến môi trường tên đăng nhập", + "store_auth_password_env": "Biến môi trường mật khẩu", + "store_auth_header_name": "Tên header", + "store_auth_header_value_env": "Biến môi trường giá trị header", + "store_auth_allow_insecure": "Cho phép URL HTTP không bảo mật", + "logs_max_size": "Giới hạn kích thước file log (MB)", + "error_logs_max_files": "Số file log lỗi giữ lại", + "usage_statistics_enabled": "Bật thống kê sử dụng trong bộ nhớ", + "usage_statistics_enabled_desc": "Tổng hợp thống kê sử dụng yêu cầu trong bộ nhớ", + "redis_usage_retention": "Thời gian giữ hàng đợi sử dụng Redis (giây)", + "redis_usage_retention_hint": "Thời gian giữ trong bộ nhớ cho đầu ra sử dụng RESP LPOP/RPOP, tối đa 3600 giây", + "antigravity_signature_cache": "Bật cache chữ ký Antigravity", + "antigravity_signature_cache_desc": "Ưu tiên và xác thực chữ ký thinking-block đã cache", + "antigravity_signature_strict": "Bỏ qua xác thực chữ ký nghiêm ngặt", + "antigravity_signature_strict_desc": "Chỉ áp dụng khi cache chữ ký bị tắt; xác thực toàn bộ cây protobuf Claude" + }, + "headers": { + "title": "Header mặc định", + "description": "Header mặc định cho yêu cầu OAuth Claude và Codex khi client không gửi", + "claude_title": "Header mặc định Claude", + "codex_title": "Header mặc định Codex", + "user_agent": "User-Agent", + "package_version": "Phiên bản gói", + "runtime_version": "Phiên bản runtime", + "os": "Hệ điều hành", + "arch": "Kiến trúc", + "timeout": "Timeout", + "stabilize_device": "Ổn định hồ sơ thiết bị", + "stabilize_device_desc": "Cố định OS/Kiến trúc và ổn định vân tay phần mềm theo từng credential/API key", + "beta_features": "Tính năng Beta" + }, + "network": { + "title": "Cấu hình mạng", + "description": "Cài đặt proxy, thử lại và định tuyến", + "proxy_url": "URL Proxy", + "request_retry": "Số lần thử lại yêu cầu", + "max_retry_credentials": "Số credential thử lại tối đa", + "max_retry_credentials_hint": "Để trống nếu không muốn đặt. Đặt 0 để giữ hành vi cũ và thử mọi credential khả dụng.", + "max_retry_interval": "Khoảng thử lại tối đa (giây)", + "auth_auto_refresh_workers": "Số worker tự làm mới xác thực", + "auth_auto_refresh_workers_hint": "Khi lớn hơn 0, ghi đè số worker mặc định (16)", + "disable_image_generation": "Tắt tạo ảnh", + "disable_image_generation_hint": "false để bật; true tắt toàn bộ tạo ảnh; chat tắt inject endpoint phi ảnh; passthrough giữ danh sách tool của client mà không inject", + "disable_image_generation_false": "false (đang bật)", + "disable_image_generation_true": "true (tắt ở mọi nơi)", + "disable_image_generation_chat": "chat (chỉ tắt inject trong chat)", + "disable_image_generation_passthrough": "passthrough (giữ danh sách tool của client)", + "gpt_image_2_base_model": "Model gốc GPT Image 2", + "gpt_image_2_base_model_hint": "Model chính dùng khi proxy yêu cầu ảnh gpt-image-2; backend dùng mặc định nếu trống hoặc không hợp lệ", + "routing_strategy": "Chiến lược định tuyến", + "routing_strategy_hint": "Chọn chiến lược lựa chọn credential", + "strategy_round_robin": "Round Robin", + "strategy_weighted_round_robin": "Weighted Round Robin", + "strategy_fill_first": "Fill First", + "session_affinity_ttl": "TTL Session Affinity", + "force_model_prefix": "Bắt buộc tiền tố model", + "force_model_prefix_desc": "Yêu cầu model không có tiền tố chỉ dùng credential không có tiền tố", + "passthrough_headers": "Chuyển tiếp Header upstream", + "passthrough_headers_desc": "Chuyển tiếp header phản hồi upstream đã lọc đến client downstream", + "disable_cooling": "Tắt Cooling", + "disable_cooling_desc": "Tắt toàn cục cửa sổ cooldown auth/model sau thất bại", + "session_affinity": "Định tuyến Session Affinity", + "ws_auth": "Xác thực WebSocket", + "ws_auth_desc": "Bật xác thực WebSocket (/v1/ws)" + }, + "quota": { + "title": "Quota dự phòng", + "description": "Chiến lược dự phòng khi vượt quota", + "switch_project": "Chuyển Project", + "switch_project_desc": "Tự động chuyển sang project khác khi vượt quota", + "switch_preview_model": "Chuyển sang model Preview", + "switch_preview_model_desc": "Chuyển sang phiên bản model preview khi vượt quota", + "antigravity_credits": "Dùng credit Antigravity" + }, + "streaming": { + "title": "Cấu hình Streaming", + "description": "Cài đặt keepalive và thử lại bootstrap", + "keepalive_seconds": "Số giây Keepalive", + "keepalive_hint": "Đặt 0 hoặc để trống để tắt keepalive", + "bootstrap_retries": "Số lần thử Bootstrap", + "bootstrap_hint": "Số lần thử lại khi khởi động stream (trước byte đầu tiên)", + "nonstream_keepalive": "Khoảng keepalive phi stream (giây)", + "nonstream_keepalive_hint": "Gửi dòng trống mỗi N giây cho phản hồi phi stream để tránh timeout nhàn rỗi, đặt 0 hoặc để trống để tắt", + "disabled": "Đã tắt" + }, + "payload": { + "title": "Cấu hình Payload", + "description": "Giá trị mặc định, quy tắc JSON thô, quy tắc ghi đè và quy tắc lọc", + "default_rules": "Quy tắc mặc định", + "default_rules_desc": "Dùng các giá trị mặc định này khi tham số không được chỉ định trong yêu cầu", + "default_raw_rules": "Quy tắc thô mặc định", + "default_raw_rules_desc": "Khi thiếu tham số, ghi các giá trị này dưới dạng đoạn JSON thô như true, 123, \"high\" hoặc {\"type\":\"object\"}", + "override_rules": "Quy tắc ghi đè", + "override_rules_desc": "Bắt buộc ghi đè giá trị tham số trong yêu cầu", + "override_raw_rules": "Quy tắc thô ghi đè", + "override_raw_rules_desc": "Luôn ghi đè giá trị tham số dưới dạng đoạn JSON thô, hữu ích cho response_format, schema và các trường phức tạp khác", + "filter_rules": "Quy tắc lọc", + "filter_rules_desc": "Lọc trước body yêu cầu upstream qua JSON Path, tự động loại bỏ tham số không tuân thủ/dư thừa (Làm sạch yêu cầu)" + } + }, + "api_keys": { + "label": "Danh sách API Key (api-keys)", + "add": "Thêm API Key", + "generate": "Tạo", + "empty": "Chưa có API key", + "hint": "Mỗi mục là một API key (nhất quán với phong cách trang 'Quản lý API Key')", + "edit_title": "Chỉnh sửa API Key", + "add_title": "Thêm API Key", + "input_label": "API Key", + "input_placeholder": "Dán API key của bạn", + "input_hint": "Chỉ sửa nội dung file cấu hình cục bộ, không đồng bộ sang giao diện Quản lý API Key", + "error_empty": "Vui lòng nhập API key", + "error_invalid": "API key chứa ký tự không hợp lệ", + "strength": { + "label": "Độ mạnh API key", + "empty": "Chưa nhập", + "weak": "Yếu", + "fair": "Khá", + "good": "Tốt", + "strong": "Mạnh" + } + }, + "payload_rules": { + "rule": "Quy tắc", + "models": "Model áp dụng", + "model_name": "Tên model", + "provider_type": "Loại Provider", + "add_model": "Thêm model", + "params": "Cài đặt tham số", + "remove_params": "Xóa tham số", + "json_path": "JSON Path (ví dụ temperature)", + "json_path_filter": "JSON Path (gjson/sjson), ví dụ generationConfig.thinkingConfig.thinkingBudget", + "param_type": "Loại tham số", + "param_value": "Giá trị tham số", + "add_param": "Thêm tham số", + "no_rules": "Chưa có quy tắc", + "add_rule": "Thêm quy tắc", + "provider_default": "Mặc định", + "provider_openai": "OpenAI", + "provider_openai_response": "OpenAI Response", + "provider_responses": "Responses", + "provider_gemini": "Gemini", + "provider_claude": "Claude", + "provider_codex": "Codex", + "provider_antigravity": "Antigravity", + "advanced": "Nâng cao", + "hide_advanced": "Ẩn nâng cao", + "from_protocol": "Giao thức nguồn (from-protocol)", + "headers": "Khớp Header yêu cầu", + "header_name": "Tên Header", + "header_value": "Giá trị Header", + "add_header": "Thêm Header", + "match": "Khớp bắt buộc (match)", + "notMatch": "Khớp cấm (not-match)", + "exist": "Đường dẫn bắt buộc (exist)", + "notExist": "Đường dẫn cấm (not-exist)", + "condition_path": "Đường dẫn khớp", + "condition_value": "Giá trị khớp", + "add_condition": "Thêm điều kiện", + "value_type_string": "Chuỗi", + "value_type_number": "Số", + "value_type_boolean": "Boolean", + "value_type_json": "JSON", + "value_string": "Giá trị chuỗi", + "value_number": "Giá trị số (ví dụ 0.7)", + "value_boolean": "true hoặc false", + "value_json": "Giá trị JSON", + "value_raw_json": "Đoạn JSON thô, ví dụ true, 123, \"high\" hoặc {\"type\":\"object\"}", + "value_default": "Giá trị", + "boolean_true": "true", + "boolean_false": "false" + }, + "validation": { + "validation_blocked": "Hãy sửa lỗi xác thực trước khi lưu", + "port_range": "Nhập cổng hợp lệ từ 1 đến 65535", + "non_negative_integer": "Nhập số nguyên không âm", + "integer_range_1_3600": "Nhập số nguyên từ 1 đến 3600", + "payload_invalid_number": "Nhập số hợp lệ", + "payload_invalid_boolean": "Chọn true hoặc false", + "payload_invalid_json": "Nhập JSON hợp lệ" + }, + "common": { + "edit": "Chỉnh sửa", + "delete": "Xóa", + "cancel": "Hủy", + "update": "Cập nhật", + "add": "Thêm" + } + } + }, + "quota_management": { + "title": "Quản lý Quota", + "description": "Theo dõi trạng thái quota OAuth của credential Antigravity, Codex, Claude, Kimi và xAI.", + "refresh_all_credentials": "Làm mới mọi credential", + "sort_label": "Sắp xếp", + "sort_default": "Mặc định", + "sort_soonest": "Sớm khôi phục nhất", + "meta_credentials": "{{count}} credential", + "meta_loaded": "{{count}} đã tải", + "meta_attention": "{{count}} cần chú ý", + "empty_title": "Không có credential hỗ trợ quota", + "empty_desc": "Kết nối credential Antigravity, Claude, Codex, xAI hoặc Kimi để theo dõi quota tại đây.", + "windows_title": "Cửa sổ quota", + "windows_span_weekly": "hai tuần", + "windows_span_session": "ba ngày", + "windows_current": "hiện tại", + "windows_today": "Hôm nay", + "windows_prev": "Trước", + "windows_next": "Sau", + "windows_mode_weekly": "Tuần", + "windows_mode_session": "5 giờ", + "windows_credential": "Credential", + "windows_idle": "không có cửa sổ nào đang đếm ngược", + "windows_empty_session": "Không có credential nào trên trang này báo cáo cửa sổ quota 5 giờ.", + "windows_legend_current": "cửa sổ hiện tại", + "windows_legend_upcoming": "sắp tới", + "windows_legend_elapsed": "đã trôi qua", + "windows_legend_reset_credit": "hết hạn đặt lại thủ công", + "soonest_row_hint": "Khôi phục sớm nhất trên credential này", + "windows_reset_credit": "Đặt lại thủ công", + "windows_credit_granted": "Được cấp", + "windows_credit_expires": "Hết hạn", + "windows_note_weekly": "Mỗi thanh là một cửa sổ quota đầy đủ, vẽ từ lúc mở đến lúc đặt lại. Các làn kết thúc cùng lúc sẽ cạnh tranh cùng ngày.", + "windows_note_session": "Mỗi thanh là một cửa sổ 5 giờ. Chỉ credential có cửa sổ đang đếm ngược mới được dự báo; các credential khác để trống thay vì bịa đặt.", + "weekday_sun": "CN", + "weekday_mon": "T2", + "weekday_tue": "T3", + "weekday_wed": "T4", + "weekday_thu": "T5", + "weekday_fri": "T6", + "weekday_sat": "T7" + }, + "plugin_management": { + "title": "Quản lý Plugin", + "description": "Xem plugin đã phát hiện và đăng ký, sau đó quản lý bật/tắt phiên bản, trường cấu hình và liên kết tài nguyên.", + "refresh": "Làm mới", + "load_failed": "Không thể tải plugin", + "config_load_failed": "Không thể đọc cấu hình plugin", + "config_not_found": "Không thể đọc cấu hình plugin vì backend không tìm thấy plugin này.", + "unsupported_backend": "Backend hiện tại không cung cấp API quản lý plugin. Hãy dùng bản backend mới hơn có endpoint quản lý plugin, sau đó khởi động lại dịch vụ.", + "global_status": "Trạng thái toàn cục", + "global_enabled": "Đang bật", + "global_disabled": "Đã tắt", + "global_disabled_hint": "plugins.enabled đang là false nên phiên bản plugin đã bật sẽ không có hiệu lực.", + "plugins_dir": "Thư mục plugin", + "discovered": "Đã phát hiện", + "effective": "Có hiệu lực", + "search_placeholder": "Tìm ID, tên, tác giả hoặc tài nguyên plugin...", + "search_label": "Tìm plugin", + "no_plugins": "Không có plugin", + "no_plugins_desc": "Không tìm thấy plugin nào trong thư mục plugin hoặc registry runtime.", + "configured": "Đã cấu hình", + "not_configured": "Chưa cấu hình", + "registered": "Đã đăng ký", + "not_registered": "Chưa đăng ký", + "oauth": "OAuth", + "status_effective": "Có hiệu lực", + "status_inactive": "Không hoạt động", + "edit_config": "Chỉnh sửa cấu hình", + "open_repository": "Mở repository", + "config_title": "Cấu hình {{name}}", + "base_settings": "Cài đặt cơ bản", + "enabled": "Đang bật", + "enabled_hint": "Điều khiển trường enabled của phiên bản plugin này trong plugins.configs.", + "priority": "Ưu tiên", + "config_fields": "Trường cấu hình", + "no_config_fields": "Plugin này không khai báo trường cấu hình trực quan.", + "select_placeholder": "Chọn", + "array_item_placeholder": "Nhập phần tử mảng", + "add_array_item": "Thêm phần tử mảng", + "remove_array_item": "Xóa phần tử mảng", + "delete_plugin": "Xóa", + "delete_confirm_title": "Xóa plugin", + "delete_confirm_message": "Xóa {{name}} ({{id}})? Thao tác này sẽ xóa file plugin cục bộ và cấu hình đã lưu.", + "delete_success": "Đã xóa plugin", + "delete_failed": "Không thể xóa plugin", + "delete_restart_required": "Plugin đã nạp không thể bị xóa cho đến khi backend khởi động lại.", + "toggle_success": "Đã cập nhật trạng thái plugin", + "toggle_failed": "Không thể cập nhật trạng thái plugin", + "runtime_pending": "Thay đổi plugin đã lưu nhưng trạng thái runtime vẫn đang chờ. Hãy làm mới sau hoặc kiểm tra log backend.", + "save_success": "Đã lưu cấu hình plugin", + "save_failed": "Không thể lưu cấu hình plugin", + "validation_failed": "Hãy sửa lỗi form cấu hình plugin trước", + "invalid_priority": "Nhập mức ưu tiên là số nguyên", + "invalid_number": "Nhập số hợp lệ", + "invalid_integer": "Nhập số nguyên hợp lệ", + "invalid_json": "Nhập JSON hợp lệ", + "expected_array": "Nhập mảng JSON", + "expected_object": "Nhập đối tượng JSON", + "invalid_enum": "Chọn một trong các giá trị enum đã khai báo" + }, + "plugin_store": { + "title": "Cửa hàng Plugin", + "description": "Duyệt registry plugin, sau đó cài đặt hoặc cập nhật plugin cho backend hiện tại.", + "description_show_more": "Hiện thêm", + "description_show_less": "Ẩn bớt", + "source_name": "Nguồn: {{source}}", + "cli_proxy_api_source": "Nguồn CLIProxyAPI", + "refresh": "Làm mới", + "retry": "Thử lại", + "load_failed": "Không thể tải cửa hàng plugin", + "unsupported_backend": "Backend hiện tại không cung cấp API plugin store. Hãy dùng bản backend mới hơn có endpoint plugin store, sau đó khởi động lại dịch vụ.", + "registry_failed": "Không thể kết nối registry plugin", + "global_status": "Trạng thái toàn cục", + "global_enabled": "Đang bật", + "global_disabled": "Đã tắt", + "global_disabled_hint": "plugins.enabled đang là false nên plugin đã cài sẽ không có hiệu lực.", + "plugins_dir": "Thư mục plugin", + "stat_available": "Khả dụng", + "search_placeholder": "Tìm ID, tên, tác giả hoặc tag plugin...", + "search_label": "Tìm cửa hàng plugin", + "filter_label": "Lọc theo trạng thái cài đặt", + "filter_all": "Tất cả", + "filter_installed": "Đã cài", + "filter_not_installed": "Chưa cài", + "filter_updates": "Có bản cập nhật", + "badge_installed": "Đã cài", + "badge_update": "Có bản cập nhật", + "badge_effective": "Có hiệu lực", + "version_arrow": "v{{from}} → v{{to}}", + "install_type": "Cài đặt: {{type}}", + "platforms": "Nền tảng: {{platforms}}", + "auth_required": "Cần xác thực", + "auth_configured": "Đã cấu hình xác thực", + "auth_required_hint": "Hãy cấu hình plugins.store-auth trước khi cài từ nguồn hoặc URL artifact này", + "source_errors_title": "Một số nguồn plugin không tải được", + "install": "Cài đặt", + "update": "Cập nhật", + "manage": "Quản lý", + "install_confirm_title": "Cài đặt plugin", + "install_confirm_message": "Tải {{target}} từ registry plugin và cài vào thư mục plugin cục bộ?", + "update_confirm_title": "Cập nhật plugin", + "update_confirm_message": "Tải và cài đặt {{target}}?", + "install_version_label": "Phiên bản", + "install_version_latest": "mới nhất", + "install_version_latest_mode": "Bản ổn định mới nhất", + "install_version_latest_hint": "Backend sẽ phân giải khi cài đặt. Phiên bản đang niêm yết: {{version}}.", + "install_version_release_mode": "Chọn bản phát hành", + "install_version_release_hint": "Đọc các tag cài được từ GitHub Releases.", + "install_version_manual_mode": "Tag phát hành thủ công", + "install_version_manual_hint": "Chỉ dùng khi không thể tự động tải danh sách bản phát hành.", + "install_versions_loading": "Đang tải GitHub Releases...", + "install_versions_load_failed": "Không thể tải danh sách phiên bản phát hành", + "install_version_non_github": "Repository plugin này không phải repository GitHub", + "install_versions_empty": "Không tìm thấy bản phát hành nào chọn được.", + "install_versions_only_prerelease": "Chỉ có phiên bản prerelease. Hãy hiện prerelease để chọn.", + "install_version_release_select": "Chọn phiên bản phát hành", + "install_version_release_placeholder": "Chọn phiên bản phát hành", + "install_version_prerelease_badge": "prerelease", + "install_version_assets_count": "{{count}} asset", + "install_version_show_prerelease": "Hiện phiên bản prerelease", + "install_version_manual_placeholder": "Ví dụ v0.1.4", + "install_version_manual_error": "Tag phát hành chỉ được chứa chữ cái, chữ số, dấu chấm, gạch dưới, dấu cộng và dấu gạch nối; không cho phép khoảng trắng và dấu gạch chéo.", + "install_version_current_selected": "{{version}} đã được cài. Hãy chọn phiên bản khác.", + "install_version_releases_link": "Xem GitHub Releases", + "install_success": "Đã cài đặt plugin", + "update_success": "Đã cập nhật plugin", + "install_failed": "Không thể cài đặt plugin", + "update_failed": "Không thể cập nhật plugin", + "status_pending": "File plugin đã cập nhật nhưng trạng thái cục bộ chưa làm mới. Hãy làm mới sau hoặc kiểm tra log backend.", + "registration_pending": "File plugin đã cập nhật nhưng việc đăng ký vẫn đang chờ. Hãy làm mới sau hoặc kiểm tra log backend.", + "restart_required_notice": "Khởi động lại dịch vụ để nạp phiên bản plugin mới", + "restart_required_banner": "Khởi động lại dịch vụ để áp dụng phiên bản mới của: {{plugins}}", + "open_repository": "Mở repository", + "open_homepage": "Mở trang chủ", + "no_plugins": "Registry trống", + "no_plugins_desc": "Registry plugin không trả về plugin nào.", + "no_matches": "Không có plugin phù hợp", + "no_matches_desc": "Không có plugin nào khớp tìm kiếm hoặc bộ lọc hiện tại.", + "clear_filters": "Xóa bộ lọc", + "security_banner_title": "Plugin bên thứ ba chạy với toàn quyền truy cập backend", + "security_banner_text": "Plugin thực thi mã bên trong dịch vụ proxy và có thể đọc credential cũng như lưu lượng của bạn. Chỉ cài plugin bạn tin tưởng — đặc biệt cẩn thận với plugin không do tổ chức chính thức router-for-me phát hành.", + "badge_untrusted": "Bên thứ ba", + "gate_title": "Cài đặt {{name}}", + "gate_title_update": "Cập nhật {{name}}", + "gate_warning": "Những điều bất ngờ và gây hại có thể xảy ra nếu bạn không đọc phần này.", + "gate_effect_runs_code": "Plugin này sẽ chạy mã bên thứ ba chưa được kiểm định trong backend proxy của bạn. Hệ thống không thể cô lập hay kiểm toán hành vi của nó, và nó có thể truy cập credential nhạy cảm, yêu cầu mạng và dữ liệu phản hồi của bạn.", + "gate_effect_no_review": "Plugin này không được tổ chức chính thức router-for-me phát hành hay đánh giá. Tổ chức chính thức không bảo hành rõ ràng hay ngụ ý về tính ổn định, bảo mật, tuân thủ hay bất kỳ thay đổi hành vi nào trong các phiên bản tương lai của plugin này.", + "gate_effect_restart": "Cài đặt sẽ thay đổi thư mục plugin cục bộ và có thể cần khởi động lại dịch vụ để có hiệu lực.", + "gate_untrusted_alert": "Plugin này không thuộc tổ chức chính thức router-for-me. Chỉ tiếp tục nếu bạn hoàn toàn tin tưởng tác giả và nguồn của nó.", + "gate_repository_label": "Repository", + "gate_source_label": "Nguồn", + "gate_step1_action": "Tôi muốn cài plugin này", + "gate_step2_action": "Tôi đã đọc và hiểu các rủi ro này", + "gate_step3_prompt": "Để xác nhận, nhập \"{{token}}\" vào ô bên dưới", + "gate_step3_action": "Cài đặt plugin này", + "gate_step3_hint": "Nhập chính xác mã định danh hiển thị ở trên để cho phép cài đặt." + }, + "plugin_resource": { + "page_count": "{{count}} trang", + "load_failed": "Không thể tải trang plugin", + "unavailable": "Trang plugin không khả dụng", + "not_found": "Không tìm thấy trang plugin", + "not_found_desc": "Trang plugin này không được khai báo trong danh sách plugin backend hiện tại.", + "empty_src": "URL trang plugin trống", + "empty_src_desc": "Menu plugin này không cung cấp URL trang nhúng được." + }, + "system_info": { + "title": "Thông tin Trung tâm Quản lý", + "about_title": "Trung tâm Quản lý CLI Proxy API", + "models_title": "Model khả dụng", + "models_desc": "Hiển thị phản hồi /models và tự động dùng API key đã lưu để xác thực.", + "models_loading": "Đang tải model khả dụng...", + "models_empty": "/models không trả về model nào", + "models_error": "Không thể tải danh sách model", + "models_count": "{{count}} model khả dụng", + "version_check_button": "Kiểm tra cập nhật", + "version_update_available": "Có bản cập nhật: {{version}}", + "version_is_latest": "Bạn đang dùng phiên bản mới nhất", + "version_check_error": "Kiểm tra cập nhật thất bại", + "version_current_missing": "Không có phiên bản máy chủ; không thể so sánh", + "version_unknown": "Không rõ", + "quick_links_title": "Liên kết nhanh", + "quick_links_desc": "Truy cập repository dự án và tài liệu để được trợ giúp và cập nhật.", + "link_main_repo": "Repository chính", + "link_main_repo_desc": "Mã nguồn chương trình lõi CLI Proxy API", + "link_webui_repo": "Repository WebUI", + "link_webui_repo_desc": "Mã nguồn frontend Trung tâm Quản lý", + "link_docs": "Tài liệu", + "link_docs_desc": "Hướng dẫn và tutorial cấu hình", + "clear_login_title": "Dữ liệu đăng nhập cục bộ", + "clear_login_desc": "Xóa dữ liệu đăng nhập đã lưu cục bộ và đăng xuất.", + "clear_login_button": "Xóa dữ liệu đăng nhập", + "clear_login_confirm": "Xóa dữ liệu đăng nhập cục bộ và đăng xuất ngay?" + }, + "notification": { + "request_log_updated": "Đã cập nhật cài đặt ghi log yêu cầu", + "login_storage_cleared": "Đã xóa dữ liệu đăng nhập cục bộ", + "data_refreshed": "Đã làm mới dữ liệu thành công", + "connection_required": "Vui lòng thiết lập kết nối trước", + "refresh_failed": "Làm mới thất bại", + "update_failed": "Cập nhật thất bại", + "add_failed": "Thêm thất bại", + "delete_failed": "Xóa thất bại", + "upload_failed": "Tải lên thất bại", + "download_failed": "Tải xuống thất bại", + "login_failed": "Đăng nhập thất bại", + "commercial_mode_restart_required": "Đã đổi cài đặt chế độ thương mại. Vui lòng khởi động lại dịch vụ để có hiệu lực", + "copy_failed": "Sao chép thất bại", + "link_copied": "Đã sao chép liên kết vào clipboard" + }, + "language": { + "switch": "Ngôn ngữ", + "chinese": "中文", + "chinese_tw": "繁體中文(台灣)", + "english": "English", + "russian": "Русский", + "vietnamese": "Tiếng Việt" + }, + "theme": { + "switch": "Giao diện", + "light": "Giấy len", + "white": "Trắng tinh", + "dark": "Tối", + "auto": "Theo hệ thống" + }, + "sidebar": { + "toggle_expand": "Mở rộng thanh bên", + "toggle_collapse": "Thu gọn thanh bên", + "expand": "Mở rộng", + "collapse": "Thu gọn", + "subtitle": "Bảng điều khiển CLI Proxy API", + "auth_files_count": "File xác thực: {{count}}" + }, + "footer": { + "api_version": "Phiên bản CLI Proxy API", + "build_date": "Thời gian build", + "version": "Phiên bản giao diện quản lý" + }, + "providersPage": { + "header": { + "title": "AI Provider", + "activeResources": "{{active}}/{{total}} tài nguyên đang hoạt động", + "providerFamilies": "{{count}} nhóm provider", + "updatedAt": "Cập nhật {{time}}" + }, + "actions": { + "refresh": "Làm mới", + "syncing": "Đang đồng bộ", + "new": "Mới", + "edit": "Chỉnh sửa", + "view": "Xem", + "delete": "Xóa", + "cancel": "Hủy", + "save": "Lưu", + "create": "Tạo", + "enable": "Bật", + "disable": "Tắt" + }, + "categories": { + "title": "Provider", + "quickFill": "Điền nhanh", + "activeCount": "{{active}}/{{total}} đang hoạt động" + }, + "providerNames": { + "gemini": "Gemini", + "interactions": "Interactions API", + "codex": "Codex", + "xai": "xAI", + "claude": "Claude", + "claudeApi": "ClaudeAPI", + "vertex": "Vertex", + "openaiCompatibility": "Tương thích OpenAI", + "apikeyFun": "APIKEY.FUN", + "code0": "Code0", + "fennoAI": "FennoAI", + "qiniuCloud": "Qiniu Cloud", + "lmuAI": "LMU AI (Linhmou AI)", + "infistar": "Infistar", + "kimi": "Kimi" + }, + "table": { + "key": "Key", + "baseUrl": "Base URL", + "prefix": "Tiền tố", + "models": "Model/Header", + "status": "Trạng thái", + "actions": "Hành động", + "metrics": { + "models": "Model", + "keys": "Key", + "headers": "Header" + }, + "websocketsTag": "WebSocket", + "cloakTag": "Cloak", + "empty": "Chưa có tài nguyên nào, nhấn \"Mới\" để thêm.", + "filterPlaceholder": "Tìm key, URL, tiền tố…", + "description": "Quản lý tài nguyên trong {{route}}" + }, + "sponsor": { + "protocolSummary": "Anthropic / OpenAI / Gemini / Codex API (Responses)", + "detailHint": "{{provider}} được lưu vào cấu hình API key tương ứng theo giao thức; khung xem này quản lý chúng cùng nhau.", + "registerLink": "Đăng ký tại đây", + "registerNow": "Đăng ký ngay", + "dashboardLink": "Bảng điều khiển", + "emptyRegisterHint": "Chưa có cấu hình nào.", + "apiKeyHint": "Key này chỉ được ghi vào cấu hình nhóm/giao thức đã chọn.", + "usageCheck": "Kiểm tra mức sử dụng", + "usageChecking": "Đang kiểm tra", + "usageRemaining": "Còn lại: {{amount}} {{unit}}", + "usageBreakdown": "Đã dùng {{used}} / Giới hạn {{limit}}", + "usageStatus": "Trạng thái: {{status}}", + "usageInvalid": "Key không hợp lệ", + "usageEmpty": "Endpoint không trả về dữ liệu sử dụng nào.", + "usageApiKeyRequired": "Cần có API key", + "aggregationConflict": "Provider được nhóm này chứa nhiều cấu hình backend hoặc key OpenAI. Hãy chỉnh trong cấu hình nguồn để tránh mất dữ liệu.", + "partialMutationWarning": "Thao tác thất bại sau khi một hoặc nhiều giao thức có thể đã được cập nhật. Cấu hình mới nhất đã được tải lại; hãy xem lại trước khi thử lại.", + "groupedKeysTitle": "Key được nhóm", + "groupedKeysHint": "Key nền tảng có thể được gắn vào nhóm khi tạo. Mỗi key được nhóm tại đây quản lý một giao thức, và khám phá model chỉ dùng giao thức đó.", + "groupedKey": "Key được nhóm #{{index}}", + "addGroupedKey": "Thêm key được nhóm", + "removeGroupedKey": "Xóa key được nhóm", + "protocol": "Nhóm/giao thức", + "protocolHint": "Chọn nhóm/giao thức cho key này.", + "protocolEndpoint": "Endpoint giao thức hiện tại", + "urlMode": "URL {{provider}}", + "urlHint": "Mọi URL dùng cùng quy ước API. Lưu chỉ ghi endpoint của giao thức được nhóm hiện tại.", + "urlOptions": { + "standard": "URL chuẩn", + "direct": "URL trực tiếp", + "domestic": "Tuyến Trung Quốc đại lục", + "overseas": "Tuyến nước ngoài", + "mainlandChina": "Trung Quốc đại lục (khuyến nghị)", + "global": "Toàn cầu" + }, + "urlOptionDescriptions": { + "domestic": "Dành cho người dùng và khối lượng công việc tại Trung Quốc đại lục; thường có độ trễ thấp hơn trên mạng đại lục.", + "overseas": "Dành cho triển khai nước ngoài, truy cập xuyên biên giới hoặc khối lượng công việc cần model nước ngoài.", + "mainlandChinaRecommended": "Khuyến nghị cho người dùng và khối lượng công việc trên mạng Trung Quốc đại lục.", + "global": "Dành cho người dùng và khối lượng công việc ở mọi khu vực khác." + }, + "modelsTitle": "Cài đặt model giao thức", + "modelsHint": "Cấu hình danh sách cho phép hoặc bí danh model riêng cho các tuyến Codex API, Anthropic, Gemini và tương thích OpenAI.", + "protocolModels": { + "codex": "Model Codex API", + "anthropic": "Model Anthropic", + "gemini": "Model Gemini", + "openai": "Model tương thích OpenAI" + }, + "protocolModelHints": { + "codex": "Ghi vào cấu hình model Codex API. Lấy từ /v1/models và đặt bí danh nếu cần.", + "anthropic": "Ghi vào cấu hình model Anthropic. Lấy từ /v1/models và đặt bí danh nếu cần.", + "gemini": "Ghi vào cấu hình model Gemini. Lấy từ /v1beta/models và đặt bí danh nếu cần.", + "openai": "Ghi vào cấu hình model tương thích OpenAI. Lấy từ /models và đặt bí danh nếu cần." + }, + "validation": { + "keyRequired": "Nhập API key cho mọi key được nhóm.", + "protocolDuplicate": "Mỗi giao thức chỉ có một key được nhóm." + }, + "openaiEntries": "Key tương thích OpenAI", + "codexEntries": "Key Codex API", + "anthropicEntries": "Key Anthropic", + "geminiEntries": "Key Gemini", + "protocols": { + "anthropic": "Anthropic", + "openai": "Tương thích OpenAI", + "gemini": "Gemini", + "codexResponses": "Codex API (Responses)" + } + }, + "status": { + "active": "Đang hoạt động", + "disabled": "Đã tắt", + "notSet": "Chưa đặt", + "none": "Không", + "notConfigured": "Chưa cấu hình", + "defaultSuffix": "(mặc định)" + }, + "detail": { + "title": "Chi tiết", + "metadataTitle": "Metadata", + "fields": { + "identifier": "Định danh", + "baseUrl": "Base URL", + "proxyUrl": "URL Proxy", + "prefix": "Tiền tố", + "models": "Model", + "headers": "Header", + "authIndex": "Chỉ mục xác thực", + "excludedModels": "Model bị loại trừ", + "apiKeyEntries": "Mục API key" + } + }, + "form": { + "createEyebrow": "Mới", + "editEyebrow": "Chỉnh sửa", + "name": "Tên", + "apiKey": "API key", + "apiKeyCreatePlaceholder": "Nhập API key", + "apiKeyEditPlaceholder": "Để trống nếu không đổi", + "baseUrl": "Base URL", + "baseUrlRequiredHint": "Bắt buộc với provider này", + "proxyUrl": "URL Proxy", + "prefix": "Tiền tố", + "priority": "Ưu tiên", + "weight": "Trọng số điều phối", + "weightHint": "Mặc định 1 · ≤ 0 bị loại trừ · tối đa 1.000.000", + "disabled": "Tắt mục này", + "disabledHint": "Gateway sẽ không dùng mục đã tắt", + "websockets": "Bật WebSocket", + "testModel": "Model kiểm thử", + "testModelClaudeHint": "Chỉ dùng để kiểm thử kết nối; không được lưu", + "testModelAutoWith": "Tự động · {{name}}", + "testModelAutoEmpty": "Tự động (chưa thêm model nào)", + "testModelCustom": "{{name}} (tùy chỉnh)", + "modelsSection": "Model tùy chỉnh", + "addModel": "Thêm model", + "headersSection": "Header yêu cầu", + "addHeader": "Thêm header", + "excludedSection": "Model bị loại trừ", + "excludedDisabledNote": "“*” nghĩa là toàn bộ provider bị tắt — hãy dùng công tắc Đã tắt ở trên thay thế.", + "cloakSection": "Cài đặt Cloak", + "cloakMode": "Chế độ", + "cloakStrict": "Chế độ nghiêm ngặt", + "cloakSensitiveWords": "Từ nhạy cảm (mỗi dòng một từ)", + "apiKeyEntriesSection": "Mục API key", + "apiKeyEntry": "Key #{{index}}", + "addApiKeyEntry": "Thêm mục key", + "showApiKey": "Hiện API key", + "hideApiKey": "Ẩn API key", + "disableCooling": "Tắt cooling", + "disableCoolingHint": "Chỉ tắt cửa sổ cooldown thất bại cho credential hoặc provider này", + "modelImage": "Cho phép endpoint ảnh", + "modelImageHint": "Cho phép model này trên /v1/images/generations và /v1/images/edits", + "showAllEntries": "Hiện tất cả ({{count}})", + "showFewerEntries": "Ẩn bớt", + "proxyBadge": "Proxy", + "modelBadgeImage": "Ảnh", + "modelBadgeThinking": "Suy luận", + "thinkingConfig": "Mức suy luận được phép", + "thinkingExistingHint": "Cấu hình backend hiện tại không đổi cho đến khi bạn đổi lựa chọn; sau đó sẽ được thay bằng các mức chuẩn đã chọn.", + "thinkingLevels": { + "none": "Tắt suy luận", + "minimal": "Tối thiểu", + "low": "Thấp", + "medium": "Trung bình", + "high": "Cao", + "xhigh": "Rất cao", + "max": "Tối đa", + "auto": "Tự động" + }, + "cloakCacheUserId": "Cache user_id", + "cloakCacheUserIdHint": "Dùng lại user_id Claude cloak theo từng API key", + "experimentalCchSigning": "Ký CCH thử nghiệm", + "experimentalCchSigningHint": "Ký body /v1/messages Claude đã cloak cuối cùng bằng CCH", + "validation": { + "nameRequired": "Tên là bắt buộc", + "apiKeyRequired": "Cần ít nhất một API key", + "baseUrlRequired": "Base URL là bắt buộc", + "weightInteger": "Trọng số điều phối phải là số nguyên", + "weightMax": "Trọng số điều phối không được vượt quá {{max}}" + } + }, + "delete": { + "title": "Xóa tài nguyên", + "confirm": "Xóa {{name}}? Thao tác này không thể hoàn tác." + }, + "toast": { + "created": "Đã tạo", + "updated": "Đã cập nhật", + "deleted": "Đã xóa", + "enabled": "Đã bật", + "disabled": "Đã tắt", + "toggleFailed": "Không thể cập nhật trạng thái" + }, + "unsavedChanges": { + "title": "Hủy thay đổi chưa lưu?", + "message": "Bạn có chỉnh sửa chưa lưu trong form này. Đóng sẽ hủy chúng.", + "discard": "Hủy thay đổi", + "keepEditing": "Tiếp tục chỉnh sửa" + }, + "connectivity": { + "test": "Kiểm thử", + "testAll": "Kiểm thử tất cả", + "success": "Kết nối được", + "baseUrlRequired": "Cần có Base URL", + "endpointInvalid": "URL endpoint không hợp lệ", + "apiKeyRequired": "Cần có API key", + "modelRequired": "Cần có model kiểm thử", + "timeout": "Hết thời gian sau {{seconds}} giây", + "requestFailed": "Yêu cầu thất bại" + }, + "discovery": { + "openButton": "Lấy từ endpoint", + "searchPlaceholder": "Tìm model", + "reload": "Tải lại", + "loading": "Đang tải model…", + "empty": "Endpoint không trả về model nào", + "notLoaded": "Nhấn Tải lại để lấy model", + "selectAll": "Chọn tất cả", + "clearAll": "Bỏ chọn", + "selectedCount": "{{selected}} / {{total}}", + "alreadyAdded": "Đã thêm", + "close": "Đóng", + "apply": "Áp dụng ({{count}})" + }, + "toolbar": { + "sortBy": "Sắp xếp theo", + "sort": { + "name": "Tên", + "priority": "Ưu tiên", + "recentSuccess": "Thành công gần đây", + "directionAsc": "Tăng dần", + "directionDesc": "Giảm dần" + }, + "filter": { + "allModels": "Mọi model", + "selectedModels": "{{selected}}/{{total}} model", + "selectAll": "Chọn tất cả", + "clear": "Xóa", + "empty": "Chưa cấu hình model nào" + } + }, + "modelCatalog": { + "notLoaded": "Chưa tải" + } + } +} diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 854fc70c..9da5051d 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -1803,7 +1803,8 @@ "chinese": "中文", "chinese_tw": "繁體中文(台灣)", "english": "English", - "russian": "Русский" + "russian": "Русский", + "vietnamese": "Tiếng Việt" }, "theme": { "switch": "主题", diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index 09c8713d..1f95bda1 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -1829,7 +1829,8 @@ "chinese": "簡體中文", "chinese_tw": "繁體中文(台灣)", "english": "英文", - "russian": "俄文" + "russian": "俄文", + "vietnamese": "Tiếng Việt" }, "theme": { "switch": "主題", diff --git a/src/types/common.ts b/src/types/common.ts index 83efd66b..38213a2c 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -4,7 +4,7 @@ export type Theme = 'light' | 'white' | 'dark' | 'auto'; -export type Language = 'zh-CN' | 'zh-TW' | 'en' | 'ru'; +export type Language = 'zh-CN' | 'zh-TW' | 'en' | 'ru' | 'vi'; export type NotificationType = 'info' | 'success' | 'warning' | 'error'; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index afec117e..3636ff9f 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -34,12 +34,13 @@ export const STORAGE_KEY_THEME = 'cli-proxy-theme'; export const STORAGE_KEY_LANGUAGE = 'cli-proxy-language'; // 语言配置 -export const LANGUAGE_ORDER = defineLanguageOrder(['zh-CN', 'zh-TW', 'en', 'ru'] as const); +export const LANGUAGE_ORDER = defineLanguageOrder(['zh-CN', 'zh-TW', 'en', 'ru', 'vi'] as const); export const LANGUAGE_LABEL_KEYS: Record = { 'zh-CN': 'language.chinese', 'zh-TW': 'language.chinese_tw', en: 'language.english', ru: 'language.russian', + vi: 'language.vietnamese', }; export const SUPPORTED_LANGUAGES = LANGUAGE_ORDER; diff --git a/src/utils/language.ts b/src/utils/language.ts index 67395ab2..7de8b52e 100644 --- a/src/utils/language.ts +++ b/src/utils/language.ts @@ -45,6 +45,7 @@ const getBrowserLanguage = (): Language => { if (TRADITIONAL_CHINESE_PREFIXES.some((prefix) => lower.startsWith(prefix))) return 'zh-TW'; if (lower.startsWith('zh')) return 'zh-CN'; if (lower.startsWith('ru')) return 'ru'; + if (lower.startsWith('vi')) return 'vi'; return 'en'; };