Files
Cli-Proxy-API-Management-Ce…/i18n.js

1442 lines
89 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 国际化语言包
const i18n = {
// 语言配置
currentLanguage: 'zh-CN',
fallbackLanguage: 'zh-CN',
// 语言包
translations: {
'zh-CN': {
// 通用
'common.login': '登录',
'common.logout': '登出',
'common.cancel': '取消',
'common.confirm': '确认',
'common.save': '保存',
'common.delete': '删除',
'common.edit': '编辑',
'common.add': '添加',
'common.update': '更新',
'common.refresh': '刷新',
'common.close': '关闭',
'common.success': '成功',
'common.error': '错误',
'common.info': '信息',
'common.warning': '警告',
'common.loading': '加载中...',
'common.connecting': '连接中...',
'common.connected': '已连接',
'common.disconnected': '未连接',
'common.connecting_status': '连接中',
'common.connected_status': '已连接',
'common.disconnected_status': '未连接',
'common.yes': '是',
'common.no': '否',
'common.optional': '可选',
'common.required': '必填',
'common.api_key': '密钥',
'common.base_url': '地址',
'common.proxy_url': '代理',
'common.alias': '别名',
'common.failure': '失败',
'common.unknown_error': '未知错误',
'common.copy': '复制',
'common.custom_headers_label': '自定义请求头',
'common.custom_headers_hint': '可选,设置需要附带到请求中的 HTTP 头,名称和值均不能为空。',
'common.custom_headers_add': '添加请求头',
'common.custom_headers_key_placeholder': 'Header 名称,例如 X-Custom-Header',
'common.custom_headers_value_placeholder': 'Header 值',
'common.model_name_placeholder': '模型名称,例如 claude-3-5-sonnet-20241022',
'common.model_alias_placeholder': '模型别名 (可选)',
// 页面标题
'title.main': 'CLI Proxy API Management Center',
'title.login': 'CLI Proxy API Management Center',
'title.abbr': 'CPAMC',
// 自动登录
'auto_login.title': '正在自动登录...',
'auto_login.message': '正在使用本地保存的连接信息尝试连接服务器',
// 登录页面
'login.subtitle': '请输入连接信息以访问管理界面',
'login.connection_title': '连接地址',
'login.connection_current': '当前地址',
'login.connection_auto_hint': '系统将自动使用当前访问地址进行连接',
'login.custom_connection_label': '自定义连接地址:',
'login.custom_connection_placeholder': '例如: https://example.com:8317',
'login.custom_connection_hint': '默认使用当前访问地址,若需要可手动输入其他地址。',
'login.use_current_address': '使用当前地址',
'login.management_key_label': '管理密钥:',
'login.management_key_placeholder': '请输入管理密钥',
'login.connect_button': '连接',
'login.submit_button': '登录',
'login.submitting': '连接中...',
'login.error_title': '登录失败',
'login.error_required': '请填写完整的连接信息',
'login.error_invalid': '连接失败,请检查地址和密钥',
// 头部导航
'header.check_connection': '检查连接',
'header.refresh_all': '刷新全部',
'header.logout': '登出',
// 连接信息
'connection.title': '连接信息',
'connection.server_address': '服务器地址:',
'connection.management_key': '管理密钥:',
'connection.status': '连接状态:',
// 侧边栏导航
'nav.basic_settings': '基础设置',
'nav.api_keys': 'API 密钥',
'nav.ai_providers': 'AI 提供商',
'nav.auth_files': '认证文件',
'nav.usage_stats': '使用统计',
'nav.config_management': '配置管理',
'nav.logs': '日志查看',
'nav.system_info': '中心信息',
// 基础设置
'basic_settings.title': '基础设置',
'basic_settings.debug_title': '调试模式',
'basic_settings.debug_enable': '启用调试模式',
'basic_settings.proxy_title': '代理设置',
'basic_settings.proxy_url_label': '代理 URL:',
'basic_settings.proxy_url_placeholder': '例如: socks5://user:pass@127.0.0.1:1080/',
'basic_settings.proxy_update': '更新',
'basic_settings.proxy_clear': '清空',
'basic_settings.retry_title': '请求重试',
'basic_settings.retry_count_label': '重试次数:',
'basic_settings.retry_update': '更新',
'basic_settings.quota_title': '配额超出行为',
'basic_settings.quota_switch_project': '自动切换项目',
'basic_settings.quota_switch_preview': '切换到预览模型',
'basic_settings.usage_statistics_title': '使用统计',
'basic_settings.usage_statistics_enable': '启用使用统计',
'basic_settings.logging_title': '日志记录',
'basic_settings.logging_to_file_enable': '启用日志记录到文件',
'basic_settings.request_log_enable': '启用请求日志',
'basic_settings.ws_auth_title': 'WebSocket 鉴权',
'basic_settings.ws_auth_enable': '启用 /ws/* 鉴权',
// API 密钥管理
'api_keys.title': 'API 密钥管理',
'api_keys.proxy_auth_title': '代理服务认证密钥',
'api_keys.add_button': '添加密钥',
'api_keys.empty_title': '暂无API密钥',
'api_keys.empty_desc': '点击上方按钮添加第一个密钥',
'api_keys.item_title': 'API密钥',
'api_keys.add_modal_title': '添加API密钥',
'api_keys.add_modal_key_label': 'API密钥:',
'api_keys.add_modal_key_placeholder': '请输入API密钥',
'api_keys.edit_modal_title': '编辑API密钥',
'api_keys.edit_modal_key_label': 'API密钥:',
'api_keys.delete_confirm': '确定要删除这个API密钥吗',
// AI 提供商
'ai_providers.title': 'AI 提供商配置',
'ai_providers.gemini_title': 'Gemini API 密钥',
'ai_providers.gemini_add_button': '添加密钥',
'ai_providers.gemini_empty_title': '暂无Gemini密钥',
'ai_providers.gemini_empty_desc': '点击上方按钮添加第一个密钥',
'ai_providers.gemini_item_title': 'Gemini密钥',
'ai_providers.gemini_add_modal_title': '添加Gemini API密钥',
'ai_providers.gemini_add_modal_key_label': 'API密钥',
'ai_providers.gemini_add_modal_key_placeholder': '输入 Gemini API 密钥',
'ai_providers.gemini_add_modal_key_hint': '逐条输入密钥,可同时指定可选 Base URL。',
'ai_providers.gemini_keys_add_btn': '添加密钥',
'ai_providers.gemini_base_url_placeholder': '可选 Base URL如 https://generativelanguage.googleapis.com',
'ai_providers.gemini_edit_modal_title': '编辑Gemini API密钥',
'ai_providers.gemini_edit_modal_key_label': 'API密钥:',
'ai_providers.gemini_delete_confirm': '确定要删除这个Gemini密钥吗',
'ai_providers.excluded_models_label': '排除的模型 (可选):',
'ai_providers.excluded_models_placeholder': '用逗号或换行分隔,例如: gemini-1.5-pro, gemini-1.5-flash',
'ai_providers.excluded_models_hint': '留空表示不过滤;保存时会自动去重并忽略空白。',
'ai_providers.excluded_models_count': '排除 {count} 个模型',
'ai_providers.codex_title': 'Codex API 配置',
'ai_providers.codex_add_button': '添加配置',
'ai_providers.codex_empty_title': '暂无Codex配置',
'ai_providers.codex_empty_desc': '点击上方按钮添加第一个配置',
'ai_providers.codex_item_title': 'Codex配置',
'ai_providers.codex_add_modal_title': '添加Codex API配置',
'ai_providers.codex_add_modal_key_label': 'API密钥:',
'ai_providers.codex_add_modal_key_placeholder': '请输入Codex API密钥',
'ai_providers.codex_add_modal_url_label': 'Base URL (必填):',
'ai_providers.codex_add_modal_url_placeholder': '例如: https://api.example.com',
'ai_providers.codex_add_modal_proxy_label': '代理 URL (可选):',
'ai_providers.codex_add_modal_proxy_placeholder': '例如: socks5://proxy.example.com:1080',
'ai_providers.codex_edit_modal_title': '编辑Codex API配置',
'ai_providers.codex_edit_modal_key_label': 'API密钥:',
'ai_providers.codex_edit_modal_url_label': 'Base URL (必填):',
'ai_providers.codex_edit_modal_proxy_label': '代理 URL (可选):',
'ai_providers.codex_delete_confirm': '确定要删除这个Codex配置吗',
'ai_providers.claude_title': 'Claude API 配置',
'ai_providers.claude_add_button': '添加配置',
'ai_providers.claude_empty_title': '暂无Claude配置',
'ai_providers.claude_empty_desc': '点击上方按钮添加第一个配置',
'ai_providers.claude_item_title': 'Claude配置',
'ai_providers.claude_add_modal_title': '添加Claude API配置',
'ai_providers.claude_add_modal_key_label': 'API密钥:',
'ai_providers.claude_add_modal_key_placeholder': '请输入Claude API密钥',
'ai_providers.claude_add_modal_url_label': 'Base URL (可选):',
'ai_providers.claude_add_modal_url_placeholder': '例如: https://api.anthropic.com',
'ai_providers.claude_add_modal_proxy_label': '代理 URL (可选):',
'ai_providers.claude_add_modal_proxy_placeholder': '例如: socks5://proxy.example.com:1080',
'ai_providers.claude_edit_modal_title': '编辑Claude API配置',
'ai_providers.claude_edit_modal_key_label': 'API密钥:',
'ai_providers.claude_edit_modal_url_label': 'Base URL (可选):',
'ai_providers.claude_edit_modal_proxy_label': '代理 URL (可选):',
'ai_providers.claude_delete_confirm': '确定要删除这个Claude配置吗',
'ai_providers.claude_models_label': '自定义模型 (可选):',
'ai_providers.claude_models_hint': '为空表示使用全部模型;可填写 name[, alias] 以限制或重命名模型。',
'ai_providers.claude_models_add_btn': '添加模型',
'ai_providers.claude_models_count': '模型数量',
'ai_providers.openai_title': 'OpenAI 兼容提供商',
'ai_providers.openai_add_button': '添加提供商',
'ai_providers.openai_empty_title': '暂无OpenAI兼容提供商',
'ai_providers.openai_empty_desc': '点击上方按钮添加第一个提供商',
'ai_providers.openai_add_modal_title': '添加OpenAI兼容提供商',
'ai_providers.openai_add_modal_name_label': '提供商名称:',
'ai_providers.openai_add_modal_name_placeholder': '例如: openrouter',
'ai_providers.openai_add_modal_url_label': 'Base URL:',
'ai_providers.openai_add_modal_url_placeholder': '例如: https://openrouter.ai/api/v1',
'ai_providers.openai_add_modal_keys_label': 'API密钥',
'ai_providers.openai_edit_modal_keys_label': 'API密钥',
'ai_providers.openai_keys_hint': '每个密钥可搭配一个可选代理地址,更便于管理。',
'ai_providers.openai_keys_add_btn': '添加密钥',
'ai_providers.openai_key_placeholder': '输入 sk- 开头的密钥',
'ai_providers.openai_proxy_placeholder': '可选代理 URL (如 socks5://...)',
'ai_providers.openai_add_modal_models_label': '模型列表 (name[, alias] 每行一个):',
'ai_providers.openai_models_hint': '示例gpt-4o-mini 或 moonshotai/kimi-k2:free, kimi-k2',
'ai_providers.openai_model_name_placeholder': '模型名称,如 moonshotai/kimi-k2:free',
'ai_providers.openai_model_alias_placeholder': '模型别名 (可选)',
'ai_providers.openai_models_add_btn': '添加模型',
'ai_providers.openai_models_fetch_button': '从 /v1/models 获取',
'ai_providers.openai_models_fetch_title': '从 /v1/models 选择模型',
'ai_providers.openai_models_fetch_hint': '使用上方 Base URL 调用 /v1/models 端点,附带首个 API KeyBearer与自定义请求头。',
'ai_providers.openai_models_fetch_url_label': '请求地址',
'ai_providers.openai_models_fetch_refresh': '重新获取',
'ai_providers.openai_models_fetch_loading': '正在从 /v1/models 获取模型列表...',
'ai_providers.openai_models_fetch_empty': '未获取到模型,请检查端点或鉴权信息。',
'ai_providers.openai_models_fetch_error': '获取模型失败',
'ai_providers.openai_models_fetch_back': '返回编辑',
'ai_providers.openai_models_fetch_apply': '添加所选模型',
'ai_providers.openai_models_search_label': '搜索模型',
'ai_providers.openai_models_search_placeholder': '按名称、别名或描述筛选',
'ai_providers.openai_models_search_empty': '没有匹配的模型,请更换关键字试试。',
'ai_providers.openai_models_fetch_invalid_url': '请先填写有效的 Base URL',
'ai_providers.openai_models_fetch_added': '已添加 {count} 个新模型',
'ai_providers.openai_edit_modal_title': '编辑OpenAI兼容提供商',
'ai_providers.openai_edit_modal_name_label': '提供商名称:',
'ai_providers.openai_edit_modal_url_label': 'Base URL:',
'ai_providers.openai_edit_modal_keys_label': 'API密钥',
'ai_providers.openai_edit_modal_models_label': '模型列表 (name[, alias] 每行一个):',
'ai_providers.openai_delete_confirm': '确定要删除这个OpenAI提供商吗',
'ai_providers.openai_keys_count': '密钥数量',
'ai_providers.openai_models_count': '模型数量',
'ai_providers.openai_test_title': '连通性测试',
'ai_providers.openai_test_hint': '使用当前配置向 /v1/chat/completions 请求,验证是否可用。',
'ai_providers.openai_test_model_placeholder': '选择或输入要测试的模型',
'ai_providers.openai_test_action': '发送测试',
'ai_providers.openai_test_running': '正在发送测试请求...',
'ai_providers.openai_test_success': '测试成功,模型可用。',
'ai_providers.openai_test_failed': '测试失败',
'ai_providers.openai_test_select_placeholder': '从当前模型列表选择',
'ai_providers.openai_test_select_empty': '当前未配置模型,可直接输入',
// 认证文件管理
'auth_files.title': '认证文件管理',
'auth_files.title_section': '认证文件',
'auth_files.description': '这里集中管理 CLI Proxy 支持的所有 JSON 认证文件(如 Qwen、Gemini、Vertex 等),上传后即可在运行时启用相应的 AI 服务。',
'auth_files.upload_button': '上传文件',
'auth_files.delete_all_button': '删除全部',
'auth_files.empty_title': '暂无认证文件',
'auth_files.empty_desc': '点击上方按钮上传第一个文件',
'auth_files.search_empty_title': '没有匹配的配置文件',
'auth_files.search_empty_desc': '请调整筛选条件或清空搜索关键字再试一次。',
'auth_files.file_size': '大小',
'auth_files.file_modified': '修改时间',
'auth_files.download_button': '下载',
'auth_files.delete_button': '删除',
'auth_files.delete_confirm': '确定要删除文件',
'auth_files.delete_all_confirm': '确定要删除所有认证文件吗?此操作不可恢复!',
'auth_files.delete_filtered_confirm': '确定要删除筛选出的 {type} 认证文件吗?此操作不可恢复!',
'auth_files.upload_error_json': '只能上传JSON文件',
'auth_files.upload_success': '文件上传成功',
'auth_files.download_success': '文件下载成功',
'auth_files.delete_success': '文件删除成功',
'auth_files.delete_all_success': '成功删除',
'auth_files.delete_filtered_success': '成功删除 {count} 个 {type} 认证文件',
'auth_files.delete_filtered_partial': '{type} 认证文件删除完成,成功 {success} 个,失败 {failed} 个',
'auth_files.delete_filtered_none': '当前筛选类型 ({type}) 下没有可删除的认证文件',
'auth_files.files_count': '个文件',
'auth_files.pagination_prev': '上一页',
'auth_files.pagination_next': '下一页',
'auth_files.pagination_info': '第 {current} / {total} 页 · 共 {count} 个文件',
'auth_files.search_label': '搜索配置文件',
'auth_files.search_placeholder': '输入名称、类型或提供方关键字',
'auth_files.page_size_label': '单页数量',
'auth_files.page_size_unit': '个/页',
'auth_files.filter_all': '全部',
'auth_files.filter_qwen': 'Qwen',
'auth_files.filter_gemini': 'Gemini',
'auth_files.filter_gemini-cli': 'GeminiCLI',
'auth_files.filter_aistudio': 'AIStudio',
'auth_files.filter_claude': 'Claude',
'auth_files.filter_codex': 'Codex',
'auth_files.filter_antigravity': 'Antigravity',
'auth_files.filter_iflow': 'iFlow',
'auth_files.filter_vertex': 'Vertex',
'auth_files.filter_empty': '空文件',
'auth_files.filter_unknown': '其他',
'auth_files.type_qwen': 'Qwen',
'auth_files.type_gemini': 'Gemini',
'auth_files.type_gemini-cli': 'GeminiCLI',
'auth_files.type_aistudio': 'AIStudio',
'auth_files.type_claude': 'Claude',
'auth_files.type_codex': 'Codex',
'auth_files.type_antigravity': 'Antigravity',
'auth_files.type_iflow': 'iFlow',
'auth_files.type_vertex': 'Vertex',
'auth_files.type_empty': '空文件',
'auth_files.type_unknown': '其他',
'vertex_import.title': 'Vertex AI 凭证导入',
'vertex_import.description': '上传 Google 服务账号 JSON使用 CLI vertex-import 同步规则写入 auth-dir/vertex-<project>.json。',
'vertex_import.location_label': '目标区域 (可选)',
'vertex_import.location_placeholder': 'us-central1',
'vertex_import.location_hint': '留空表示使用默认区域 us-central1。',
'vertex_import.file_label': '服务账号密钥 JSON',
'vertex_import.file_hint': '仅支持 Google Cloud service account key JSON 文件,私钥会自动规范化。',
'vertex_import.file_placeholder': '尚未选择文件',
'vertex_import.choose_file': '选择文件',
'vertex_import.import_button': '导入 Vertex 凭证',
'vertex_import.file_required': '请先选择 .json 凭证文件',
'vertex_import.success': 'Vertex 凭证导入成功',
'vertex_import.result_title': '凭证已保存',
'vertex_import.result_project': '项目 ID',
'vertex_import.result_email': '服务账号',
'vertex_import.result_location': '区域',
'vertex_import.result_file': '存储文件',
// OAuth 排除模型
'oauth_excluded.title': 'OAuth 排除列表',
'oauth_excluded.description': '按提供商分列展示,点击卡片编辑或删除;支持 * 通配符,范围跟随上方的配置文件过滤标签。',
'oauth_excluded.add': '新增排除',
'oauth_excluded.add_title': '新增提供商排除列表',
'oauth_excluded.edit_title': '编辑 {provider} 的排除列表',
'oauth_excluded.refresh': '刷新',
'oauth_excluded.refreshing': '刷新中...',
'oauth_excluded.provider_label': '提供商',
'oauth_excluded.provider_auto': '跟随当前过滤',
'oauth_excluded.provider_placeholder': '例如 gemini-cli / openai',
'oauth_excluded.provider_hint': '默认选中当前筛选的提供商,也可直接输入或选择其他名称。',
'oauth_excluded.models_label': '排除的模型',
'oauth_excluded.models_placeholder': 'gpt-4.1-mini\n*-preview',
'oauth_excluded.models_hint': '逗号或换行分隔;留空保存将删除该提供商记录;支持 * 通配符。',
'oauth_excluded.save': '保存/更新',
'oauth_excluded.saving': '正在保存...',
'oauth_excluded.save_success': '排除列表已更新',
'oauth_excluded.save_failed': '更新排除列表失败',
'oauth_excluded.delete': '删除提供商',
'oauth_excluded.delete_confirm': '确定要删除 {provider} 的排除列表吗?',
'oauth_excluded.delete_success': '已删除该提供商的排除列表',
'oauth_excluded.delete_failed': '删除排除列表失败',
'oauth_excluded.deleting': '正在删除...',
'oauth_excluded.no_models': '未配置排除模型',
'oauth_excluded.model_count': '排除 {count} 个模型',
'oauth_excluded.list_empty_all': '暂无任何提供商的排除列表,点击“新增排除”创建。',
'oauth_excluded.list_empty_filtered': '当前筛选下没有排除项,点击“新增排除”添加。',
'oauth_excluded.disconnected': '请先连接服务器以查看排除列表',
'oauth_excluded.load_failed': '加载排除列表失败',
'oauth_excluded.provider_required': '请先填写提供商名称',
'oauth_excluded.scope_all': '当前范围:全局(显示所有提供商)',
'oauth_excluded.scope_provider': '当前范围:{provider}',
// Codex OAuth
'auth_login.codex_oauth_title': 'Codex OAuth',
'auth_login.codex_oauth_button': '开始 Codex 登录',
'auth_login.codex_oauth_hint': '通过 OAuth 流程登录 Codex 服务,自动获取并保存认证文件。',
'auth_login.codex_oauth_url_label': '授权链接:',
'auth_login.codex_open_link': '打开链接',
'auth_login.codex_copy_link': '复制链接',
'auth_login.codex_oauth_status_waiting': '等待认证中...',
'auth_login.codex_oauth_status_success': '认证成功!',
'auth_login.codex_oauth_status_error': '认证失败:',
'auth_login.codex_oauth_start_error': '启动 Codex OAuth 失败:',
'auth_login.codex_oauth_polling_error': '检查认证状态失败:',
// Anthropic OAuth
'auth_login.anthropic_oauth_title': 'Anthropic OAuth',
'auth_login.anthropic_oauth_button': '开始 Anthropic 登录',
'auth_login.anthropic_oauth_hint': '通过 OAuth 流程登录 Anthropic (Claude) 服务,自动获取并保存认证文件。',
'auth_login.anthropic_oauth_url_label': '授权链接:',
'auth_login.anthropic_open_link': '打开链接',
'auth_login.anthropic_copy_link': '复制链接',
'auth_login.anthropic_oauth_status_waiting': '等待认证中...',
'auth_login.anthropic_oauth_status_success': '认证成功!',
'auth_login.anthropic_oauth_status_error': '认证失败:',
'auth_login.anthropic_oauth_start_error': '启动 Anthropic OAuth 失败:',
'auth_login.anthropic_oauth_polling_error': '检查认证状态失败:',
// Antigravity OAuth
'auth_login.antigravity_oauth_title': 'Antigravity OAuth',
'auth_login.antigravity_oauth_button': '开始 Antigravity 登录',
'auth_login.antigravity_oauth_hint': '通过 OAuth 流程登录 AntigravityGoogle 账号)服务,自动获取并保存认证文件。',
'auth_login.antigravity_oauth_url_label': '授权链接:',
'auth_login.antigravity_open_link': '打开链接',
'auth_login.antigravity_copy_link': '复制链接',
'auth_login.antigravity_oauth_status_waiting': '等待认证中...',
'auth_login.antigravity_oauth_status_success': '认证成功!',
'auth_login.antigravity_oauth_status_error': '认证失败:',
'auth_login.antigravity_oauth_start_error': '启动 Antigravity OAuth 失败:',
'auth_login.antigravity_oauth_polling_error': '检查认证状态失败:',
// Gemini CLI OAuth
'auth_login.gemini_cli_oauth_title': 'Gemini CLI OAuth',
'auth_login.gemini_cli_oauth_button': '开始 Gemini CLI 登录',
'auth_login.gemini_cli_oauth_hint': '通过 OAuth 流程登录 Google Gemini CLI 服务,自动获取并保存认证文件。',
'auth_login.gemini_cli_project_id_label': 'Google Cloud 项目 ID (可选):',
'auth_login.gemini_cli_project_id_placeholder': '输入 Google Cloud 项目 ID (可选)',
'auth_login.gemini_cli_project_id_hint': '如果指定了项目 ID将使用该项目的认证信息。',
'auth_login.gemini_cli_oauth_url_label': '授权链接:',
'auth_login.gemini_cli_open_link': '打开链接',
'auth_login.gemini_cli_copy_link': '复制链接',
'auth_login.gemini_cli_oauth_status_waiting': '等待认证中...',
'auth_login.gemini_cli_oauth_status_success': '认证成功!',
'auth_login.gemini_cli_oauth_status_error': '认证失败:',
'auth_login.gemini_cli_oauth_start_error': '启动 Gemini CLI OAuth 失败:',
'auth_login.gemini_cli_oauth_polling_error': '检查认证状态失败:',
// Qwen OAuth
'auth_login.qwen_oauth_title': 'Qwen OAuth',
'auth_login.qwen_oauth_button': '开始 Qwen 登录',
'auth_login.qwen_oauth_hint': '通过设备授权流程登录 Qwen 服务,自动获取并保存认证文件。',
'auth_login.qwen_oauth_url_label': '授权链接:',
'auth_login.qwen_open_link': '打开链接',
'auth_login.qwen_copy_link': '复制链接',
'auth_login.qwen_oauth_status_waiting': '等待认证中...',
'auth_login.qwen_oauth_status_success': '认证成功!',
'auth_login.qwen_oauth_status_error': '认证失败:',
'auth_login.qwen_oauth_start_error': '启动 Qwen OAuth 失败:',
'auth_login.qwen_oauth_polling_error': '检查认证状态失败:',
'auth_login.missing_state': '无法获取认证状态参数',
// iFlow OAuth
'auth_login.iflow_oauth_title': 'iFlow OAuth',
'auth_login.iflow_oauth_button': '开始 iFlow 登录',
'auth_login.iflow_oauth_hint': '通过 OAuth 流程登录 iFlow 服务,自动获取并保存认证文件。',
'auth_login.iflow_oauth_url_label': '授权链接:',
'auth_login.iflow_open_link': '打开链接',
'auth_login.iflow_copy_link': '复制链接',
'auth_login.iflow_oauth_status_waiting': '等待认证中...',
'auth_login.iflow_oauth_status_success': '认证成功!',
'auth_login.iflow_oauth_status_error': '认证失败:',
'auth_login.iflow_oauth_start_error': '启动 iFlow OAuth 失败:',
'auth_login.iflow_oauth_polling_error': '检查认证状态失败:',
'auth_login.iflow_cookie_title': 'iFlow Cookie 登录',
'auth_login.iflow_cookie_label': 'Cookie 内容:',
'auth_login.iflow_cookie_placeholder': '粘贴浏览器中的 Cookie例如 sessionid=...;',
'auth_login.iflow_cookie_hint': '直接提交 Cookie 以完成登录(无需打开授权链接),服务端将自动保存凭据。',
'auth_login.iflow_cookie_button': '提交 Cookie 登录',
'auth_login.iflow_cookie_status_success': 'Cookie 登录成功,凭据已保存。',
'auth_login.iflow_cookie_status_error': 'Cookie 登录失败:',
'auth_login.iflow_cookie_start_error': '提交 Cookie 登录失败:',
'auth_login.iflow_cookie_required': '请先填写 Cookie 内容',
'auth_login.iflow_cookie_result_title': 'Cookie 登录结果',
'auth_login.iflow_cookie_result_email': '账号',
'auth_login.iflow_cookie_result_expired': '过期时间',
'auth_login.iflow_cookie_result_path': '保存路径',
'auth_login.iflow_cookie_result_type': '类型',
// 使用统计
'usage_stats.title': '使用统计',
'usage_stats.total_requests': '总请求数',
'usage_stats.success_requests': '成功请求',
'usage_stats.failed_requests': '失败请求',
'usage_stats.total_tokens': '总Token数',
'usage_stats.cached_tokens': '缓存 Token 数',
'usage_stats.reasoning_tokens': '思考 Token 数',
'usage_stats.rpm_30m': 'RPM近30分钟',
'usage_stats.tpm_30m': 'TPM近30分钟',
'usage_stats.requests_trend': '请求趋势',
'usage_stats.tokens_trend': 'Token 使用趋势',
'usage_stats.api_details': 'API 详细统计',
'usage_stats.by_hour': '按小时',
'usage_stats.by_day': '按天',
'usage_stats.refresh': '刷新',
'usage_stats.chart_line_label_1': '曲线 1',
'usage_stats.chart_line_label_2': '曲线 2',
'usage_stats.chart_line_label_3': '曲线 3',
'usage_stats.chart_line_label_4': '曲线 4',
'usage_stats.chart_line_label_5': '曲线 5',
'usage_stats.chart_line_label_6': '曲线 6',
'usage_stats.chart_line_label_7': '曲线 7',
'usage_stats.chart_line_label_8': '曲线 8',
'usage_stats.chart_line_label_9': '曲线 9',
'usage_stats.chart_line_hidden': '不显示',
'usage_stats.chart_line_actions_label': '曲线数量',
'usage_stats.chart_line_add': '增加曲线',
'usage_stats.chart_line_all': '全部',
'usage_stats.chart_line_delete': '删除曲线',
'usage_stats.chart_line_hint': '最多同时显示 9 条模型曲线',
'usage_stats.no_data': '暂无数据',
'usage_stats.loading_error': '加载失败',
'usage_stats.api_endpoint': 'API端点',
'usage_stats.requests_count': '请求次数',
'usage_stats.tokens_count': 'Token数量',
'usage_stats.models': '模型统计',
'usage_stats.success_rate': '成功率',
'usage_stats.total_cost': '总花费',
'usage_stats.total_cost_hint': '基于已设置的模型单价',
'usage_stats.model_price_title': '模型价格',
'usage_stats.model_price_reset': '清除价格',
'usage_stats.model_price_model_label': '选择模型',
'usage_stats.model_price_select_placeholder': '选择模型',
'usage_stats.model_price_select_hint': '模型列表来自使用统计明细',
'usage_stats.model_price_prompt': '提示价格 ($/1M tokens)',
'usage_stats.model_price_completion': '补全价格 ($/1M tokens)',
'usage_stats.model_price_save': '保存价格',
'usage_stats.model_price_empty': '暂未设置任何模型价格',
'usage_stats.model_price_model': '模型',
'usage_stats.model_price_saved': '模型价格已保存',
'usage_stats.model_price_model_required': '请选择要设置价格的模型',
'usage_stats.cost_trend': '花费统计',
'usage_stats.cost_axis_label': '花费 ($)',
'usage_stats.cost_need_price': '请先设置模型价格',
'usage_stats.cost_need_usage': '暂无使用数据,无法计算花费',
'usage_stats.cost_no_data': '没有可计算的花费数据',
'stats.success': '成功',
'stats.failure': '失败',
// 日志查看
'logs.title': '日志查看',
'logs.refresh_button': '刷新日志',
'logs.clear_button': '清空日志',
'logs.download_button': '下载日志',
'logs.error_log_button': '选择错误日志',
'logs.error_logs_modal_title': '错误请求日志',
'logs.error_logs_description': '请选择要下载的错误请求日志文件(仅在关闭请求日志时生成)。',
'logs.error_logs_empty': '暂无错误请求日志文件',
'logs.error_logs_load_error': '加载错误日志列表失败',
'logs.error_logs_size': '大小',
'logs.error_logs_modified': '最后修改',
'logs.error_logs_download': '下载',
'logs.error_log_download_success': '错误日志下载成功',
'logs.empty_title': '暂无日志记录',
'logs.empty_desc': '当启用"日志记录到文件"功能后,日志将显示在这里',
'logs.log_content': '日志内容',
'logs.loading': '正在加载日志...',
'logs.load_error': '加载日志失败',
'logs.clear_confirm': '确定要清空所有日志吗?此操作不可恢复!',
'logs.clear_success': '日志已清空',
'logs.download_success': '日志下载成功',
'logs.auto_refresh': '自动刷新',
'logs.auto_refresh_enabled': '自动刷新已开启',
'logs.auto_refresh_disabled': '自动刷新已关闭',
'logs.search_placeholder': '搜索日志内容或关键字',
'logs.search_empty_title': '未找到匹配的日志',
'logs.search_empty_desc': '尝试更换关键字或清空搜索条件。',
'logs.lines': '行',
'logs.removed': '已删除',
'logs.upgrade_required_title': '需要升级 CLI Proxy API',
'logs.upgrade_required_desc': '当前服务器版本不支持日志查看功能,请升级到最新版本的 CLI Proxy API 以使用此功能。',
// 配置管理
'config_management.title': '配置管理',
'config_management.editor_title': '配置文件',
'config_management.reload': '重新加载',
'config_management.save': '保存',
'config_management.description': '查看并编辑服务器上的 config.yaml 配置文件。保存前请确认语法正确。',
'config_management.status_idle': '等待操作',
'config_management.status_loading': '加载配置中...',
'config_management.status_loaded': '配置已加载',
'config_management.status_dirty': '有未保存的更改',
'config_management.status_disconnected': '请先连接服务器以加载配置',
'config_management.status_load_failed': '加载失败',
'config_management.status_saving': '正在保存配置...',
'config_management.status_saved': '配置保存完成',
'config_management.status_save_failed': '保存失败',
'config_management.save_success': '配置已保存',
'config_management.error_yaml_not_supported': '服务器未返回 YAML 格式,请确认 /config.yaml 接口可用',
'config_management.editor_placeholder': 'key: value',
// 系统信息
'system_info.title': '管理中心信息',
'system_info.connection_status_title': '连接状态',
'system_info.api_status_label': 'API 状态:',
'system_info.config_status_label': '配置状态:',
'system_info.last_update_label': '最后更新:',
'system_info.cache_data': '缓存数据',
'system_info.real_time_data': '实时数据',
'system_info.not_loaded': '未加载',
'system_info.seconds_ago': '秒前',
'system_info.models_title': '可用模型列表',
'system_info.models_desc': '展示 /v1/models 返回的模型,并自动使用服务器保存的 API Key 进行鉴权。',
'system_info.models_loading': '正在加载可用模型...',
'system_info.models_empty': '未从 /v1/models 获取到模型数据',
'system_info.models_error': '获取模型列表失败',
'system_info.models_count': '可用模型 {count} 个',
'system_info.version_check_title': '版本检查',
'system_info.version_check_desc': '调用 /latest-version 接口比对服务器版本,提示是否有可用更新。',
'system_info.version_current_label': '当前版本',
'system_info.version_latest_label': '最新版本',
'system_info.version_check_button': '检查更新',
'system_info.version_check_idle': '点击检查更新',
'system_info.version_checking': '正在检查最新版本...',
'system_info.version_update_available': '有新版本可用:{version}',
'system_info.version_is_latest': '当前已是最新版本',
'system_info.version_check_error': '检查更新失败',
'system_info.version_current_missing': '未获取到服务器版本号,暂无法比对',
'system_info.version_unknown': '未知',
// 通知消息
'notification.debug_updated': '调试设置已更新',
'notification.proxy_updated': '代理设置已更新',
'notification.proxy_cleared': '代理设置已清空',
'notification.retry_updated': '重试设置已更新',
'notification.quota_switch_project_updated': '项目切换设置已更新',
'notification.quota_switch_preview_updated': '预览模型切换设置已更新',
'notification.usage_statistics_updated': '使用统计设置已更新',
'notification.logging_to_file_updated': '日志记录设置已更新',
'notification.request_log_updated': '请求日志设置已更新',
'notification.ws_auth_updated': 'WebSocket 鉴权设置已更新',
'notification.api_key_added': 'API密钥添加成功',
'notification.api_key_updated': 'API密钥更新成功',
'notification.api_key_deleted': 'API密钥删除成功',
'notification.gemini_key_added': 'Gemini密钥添加成功',
'notification.gemini_key_updated': 'Gemini密钥更新成功',
'notification.gemini_key_deleted': 'Gemini密钥删除成功',
'notification.gemini_multi_input_required': '请先输入至少一个Gemini密钥',
'notification.gemini_multi_failed': 'Gemini密钥批量添加失败',
'notification.gemini_multi_summary': 'Gemini批量添加完成成功 {success},跳过 {skipped},失败 {failed}',
'notification.codex_config_added': 'Codex配置添加成功',
'notification.codex_config_updated': 'Codex配置更新成功',
'notification.codex_config_deleted': 'Codex配置删除成功',
'notification.codex_base_url_required': '请填写Codex Base URL',
'notification.claude_config_added': 'Claude配置添加成功',
'notification.claude_config_updated': 'Claude配置更新成功',
'notification.claude_config_deleted': 'Claude配置删除成功',
'notification.field_required': '必填字段不能为空',
'notification.openai_provider_required': '请填写提供商名称和Base URL',
'notification.openai_provider_added': 'OpenAI提供商添加成功',
'notification.openai_provider_updated': 'OpenAI提供商更新成功',
'notification.openai_provider_deleted': 'OpenAI提供商删除成功',
'notification.openai_model_name_required': '请填写模型名称',
'notification.openai_test_url_required': '请先填写有效的 Base URL 以进行测试',
'notification.openai_test_key_required': '请至少填写一个 API 密钥以进行测试',
'notification.openai_test_model_required': '请选择或输入要测试的模型',
'notification.data_refreshed': '数据刷新成功',
'notification.connection_required': '请先建立连接',
'notification.refresh_failed': '刷新失败',
'notification.update_failed': '更新失败',
'notification.add_failed': '添加失败',
'notification.delete_failed': '删除失败',
'notification.upload_failed': '上传失败',
'notification.download_failed': '下载失败',
'notification.login_failed': '登录失败',
'notification.please_enter': '请输入',
'notification.please_fill': '请填写',
'notification.provider_name_url': '提供商名称和Base URL',
'notification.api_key': 'API密钥',
'notification.gemini_api_key': 'Gemini API密钥',
'notification.codex_api_key': 'Codex API密钥',
'notification.claude_api_key': 'Claude API密钥',
'notification.link_copied': '链接已复制到剪贴板',
// 语言切换
'language.switch': '语言',
'language.chinese': '中文',
'language.english': 'English',
// 主题切换
'theme.switch': '主题',
'theme.light': '亮色',
'theme.dark': '暗色',
'theme.switch_to_light': '切换到亮色模式',
'theme.switch_to_dark': '切换到暗色模式',
'theme.auto': '跟随系统',
// 侧边栏
'sidebar.toggle_expand': '展开侧边栏',
'sidebar.toggle_collapse': '收起侧边栏',
// 页脚
'footer.api_version': 'CLI Proxy API 版本',
'footer.build_date': '构建时间',
'footer.version': '管理中心版本',
'footer.author': '作者'
},
'en-US': {
// Common
'common.login': 'Login',
'common.logout': 'Logout',
'common.cancel': 'Cancel',
'common.confirm': 'Confirm',
'common.save': 'Save',
'common.delete': 'Delete',
'common.edit': 'Edit',
'common.add': 'Add',
'common.update': 'Update',
'common.refresh': 'Refresh',
'common.close': 'Close',
'common.success': 'Success',
'common.error': 'Error',
'common.info': 'Info',
'common.warning': 'Warning',
'common.loading': 'Loading...',
'common.connecting': 'Connecting...',
'common.connected': 'Connected',
'common.disconnected': 'Disconnected',
'common.connecting_status': 'Connecting',
'common.connected_status': 'Connected',
'common.disconnected_status': 'Disconnected',
'common.yes': 'Yes',
'common.no': 'No',
'common.optional': 'Optional',
'common.required': 'Required',
'common.api_key': 'Key',
'common.base_url': 'Address',
'common.proxy_url': 'Proxy',
'common.alias': 'Alias',
'common.failure': 'Failure',
'common.unknown_error': 'Unknown error',
'common.copy': 'Copy',
'common.custom_headers_label': 'Custom Headers',
'common.custom_headers_hint': 'Optional HTTP headers to send with the request. Leave blank to remove.',
'common.custom_headers_add': 'Add Header',
'common.custom_headers_key_placeholder': 'Header name, e.g. X-Custom-Header',
'common.custom_headers_value_placeholder': 'Header value',
'common.model_name_placeholder': 'Model name, e.g. claude-3-5-sonnet-20241022',
'common.model_alias_placeholder': 'Model alias (optional)',
// Page titles
'title.main': 'CLI Proxy API Management Center',
'title.login': 'CLI Proxy API Management Center',
'title.abbr': 'CPAMC',
// Auto login
'auto_login.title': 'Auto Login in Progress...',
'auto_login.message': 'Attempting to connect to server using locally saved connection information',
// Login page
'login.subtitle': 'Please enter connection information to access the management interface',
'login.connection_title': 'Connection Address',
'login.connection_current': 'Current URL',
'login.connection_auto_hint': 'The system will automatically use the current URL for connection',
'login.custom_connection_label': 'Custom Connection URL:',
'login.custom_connection_placeholder': 'Eg: https://example.com:8317',
'login.custom_connection_hint': 'By default the current URL is used. Override it here if needed.',
'login.use_current_address': 'Use Current URL',
'login.management_key_label': 'Management Key:',
'login.management_key_placeholder': 'Enter the management key',
'login.connect_button': 'Connect',
'login.submit_button': 'Login',
'login.submitting': 'Connecting...',
'login.error_title': 'Login Failed',
'login.error_required': 'Please fill in complete connection information',
'login.error_invalid': 'Connection failed, please check address and key',
// Header navigation
'header.check_connection': 'Check Connection',
'header.refresh_all': 'Refresh All',
'header.logout': 'Logout',
// Connection info
'connection.title': 'Connection Information',
'connection.server_address': 'Server Address:',
'connection.management_key': 'Management Key:',
'connection.status': 'Connection Status:',
// Sidebar navigation
'nav.basic_settings': 'Basic Settings',
'nav.api_keys': 'API Keys',
'nav.ai_providers': 'AI Providers',
'nav.auth_files': 'Auth Files',
'nav.usage_stats': 'Usage Statistics',
'nav.config_management': 'Config Management',
'nav.logs': 'Logs Viewer',
'nav.system_info': 'Management Center Info',
// Basic settings
'basic_settings.title': 'Basic Settings',
'basic_settings.debug_title': 'Debug Mode',
'basic_settings.debug_enable': 'Enable Debug Mode',
'basic_settings.proxy_title': 'Proxy Settings',
'basic_settings.proxy_url_label': 'Proxy URL:',
'basic_settings.proxy_url_placeholder': 'e.g.: socks5://user:pass@127.0.0.1:1080/',
'basic_settings.proxy_update': 'Update',
'basic_settings.proxy_clear': 'Clear',
'basic_settings.retry_title': 'Request Retry',
'basic_settings.retry_count_label': 'Retry Count:',
'basic_settings.retry_update': 'Update',
'basic_settings.quota_title': 'Quota Exceeded Behavior',
'basic_settings.quota_switch_project': 'Auto Switch Project',
'basic_settings.quota_switch_preview': 'Switch to Preview Model',
'basic_settings.usage_statistics_title': 'Usage Statistics',
'basic_settings.usage_statistics_enable': 'Enable usage statistics',
'basic_settings.logging_title': 'Logging',
'basic_settings.logging_to_file_enable': 'Enable logging to file',
'basic_settings.request_log_enable': 'Enable request logging',
'basic_settings.ws_auth_title': 'WebSocket Authentication',
'basic_settings.ws_auth_enable': 'Require auth for /ws/*',
// API Keys management
'api_keys.title': 'API Keys Management',
'api_keys.proxy_auth_title': 'Proxy Service Authentication Keys',
'api_keys.add_button': 'Add Key',
'api_keys.empty_title': 'No API Keys',
'api_keys.empty_desc': 'Click the button above to add the first key',
'api_keys.item_title': 'API Key',
'api_keys.add_modal_title': 'Add API Key',
'api_keys.add_modal_key_label': 'API Key:',
'api_keys.add_modal_key_placeholder': 'Please enter API key',
'api_keys.edit_modal_title': 'Edit API Key',
'api_keys.edit_modal_key_label': 'API Key:',
'api_keys.delete_confirm': 'Are you sure you want to delete this API key?',
// AI Providers
'ai_providers.title': 'AI Providers Configuration',
'ai_providers.gemini_title': 'Gemini API Keys',
'ai_providers.gemini_add_button': 'Add Key',
'ai_providers.gemini_empty_title': 'No Gemini Keys',
'ai_providers.gemini_empty_desc': 'Click the button above to add the first key',
'ai_providers.gemini_item_title': 'Gemini Key',
'ai_providers.gemini_add_modal_title': 'Add Gemini API Key',
'ai_providers.gemini_add_modal_key_label': 'API Keys:',
'ai_providers.gemini_add_modal_key_placeholder': 'Enter Gemini API key',
'ai_providers.gemini_add_modal_key_hint': 'Add keys one by one and optionally specify a Base URL.',
'ai_providers.gemini_keys_add_btn': 'Add Key',
'ai_providers.gemini_base_url_placeholder': 'Optional Base URL, e.g. https://generativelanguage.googleapis.com',
'ai_providers.gemini_edit_modal_title': 'Edit Gemini API Key',
'ai_providers.gemini_edit_modal_key_label': 'API Key:',
'ai_providers.gemini_delete_confirm': 'Are you sure you want to delete this Gemini key?',
'ai_providers.excluded_models_label': 'Excluded models (optional):',
'ai_providers.excluded_models_placeholder': 'Comma or newline separated, e.g. gemini-1.5-pro, gemini-1.5-flash',
'ai_providers.excluded_models_hint': 'Leave empty to allow all models; values are trimmed and deduplicated automatically.',
'ai_providers.excluded_models_count': 'Excluding {count} models',
'ai_providers.codex_title': 'Codex API Configuration',
'ai_providers.codex_add_button': 'Add Configuration',
'ai_providers.codex_empty_title': 'No Codex Configuration',
'ai_providers.codex_empty_desc': 'Click the button above to add the first configuration',
'ai_providers.codex_item_title': 'Codex Configuration',
'ai_providers.codex_add_modal_title': 'Add Codex API Configuration',
'ai_providers.codex_add_modal_key_label': 'API Key:',
'ai_providers.codex_add_modal_key_placeholder': 'Please enter Codex API key',
'ai_providers.codex_add_modal_url_label': 'Base URL (Required):',
'ai_providers.codex_add_modal_url_placeholder': 'e.g.: https://api.example.com',
'ai_providers.codex_add_modal_proxy_label': 'Proxy URL (Optional):',
'ai_providers.codex_add_modal_proxy_placeholder': 'e.g.: socks5://proxy.example.com:1080',
'ai_providers.codex_edit_modal_title': 'Edit Codex API Configuration',
'ai_providers.codex_edit_modal_key_label': 'API Key:',
'ai_providers.codex_edit_modal_url_label': 'Base URL (Required):',
'ai_providers.codex_edit_modal_proxy_label': 'Proxy URL (Optional):',
'ai_providers.codex_delete_confirm': 'Are you sure you want to delete this Codex configuration?',
'ai_providers.claude_title': 'Claude API Configuration',
'ai_providers.claude_add_button': 'Add Configuration',
'ai_providers.claude_empty_title': 'No Claude Configuration',
'ai_providers.claude_empty_desc': 'Click the button above to add the first configuration',
'ai_providers.claude_item_title': 'Claude Configuration',
'ai_providers.claude_add_modal_title': 'Add Claude API Configuration',
'ai_providers.claude_add_modal_key_label': 'API Key:',
'ai_providers.claude_add_modal_key_placeholder': 'Please enter Claude API key',
'ai_providers.claude_add_modal_url_label': 'Base URL (Optional):',
'ai_providers.claude_add_modal_url_placeholder': 'e.g.: https://api.anthropic.com',
'ai_providers.claude_add_modal_proxy_label': 'Proxy URL (Optional):',
'ai_providers.claude_add_modal_proxy_placeholder': 'e.g.: socks5://proxy.example.com:1080',
'ai_providers.claude_edit_modal_title': 'Edit Claude API Configuration',
'ai_providers.claude_edit_modal_key_label': 'API Key:',
'ai_providers.claude_edit_modal_url_label': 'Base URL (Optional):',
'ai_providers.claude_edit_modal_proxy_label': 'Proxy URL (Optional):',
'ai_providers.claude_delete_confirm': 'Are you sure you want to delete this Claude configuration?',
'ai_providers.claude_models_label': 'Custom Models (Optional):',
'ai_providers.claude_models_hint': 'Leave empty to allow all models, or add name[, alias] entries to limit/alias them.',
'ai_providers.claude_models_add_btn': 'Add Model',
'ai_providers.claude_models_count': 'Models Count',
'ai_providers.openai_title': 'OpenAI Compatible Providers',
'ai_providers.openai_add_button': 'Add Provider',
'ai_providers.openai_empty_title': 'No OpenAI Compatible Providers',
'ai_providers.openai_empty_desc': 'Click the button above to add the first provider',
'ai_providers.openai_add_modal_title': 'Add OpenAI Compatible Provider',
'ai_providers.openai_add_modal_name_label': 'Provider Name:',
'ai_providers.openai_add_modal_name_placeholder': 'e.g.: openrouter',
'ai_providers.openai_add_modal_url_label': 'Base URL:',
'ai_providers.openai_add_modal_url_placeholder': 'e.g.: https://openrouter.ai/api/v1',
'ai_providers.openai_add_modal_keys_label': 'API Keys',
'ai_providers.openai_edit_modal_keys_label': 'API Keys',
'ai_providers.openai_keys_hint': 'Add each key separately with an optional proxy URL to keep things organized.',
'ai_providers.openai_keys_add_btn': 'Add Key',
'ai_providers.openai_key_placeholder': 'sk-... key',
'ai_providers.openai_proxy_placeholder': 'Optional proxy URL (e.g. socks5://...)',
'ai_providers.openai_add_modal_models_label': 'Model List (name[, alias] one per line):',
'ai_providers.openai_models_hint': 'Example: gpt-4o-mini or moonshotai/kimi-k2:free, kimi-k2',
'ai_providers.openai_model_name_placeholder': 'Model name, e.g. moonshotai/kimi-k2:free',
'ai_providers.openai_model_alias_placeholder': 'Model alias (optional)',
'ai_providers.openai_models_add_btn': 'Add Model',
'ai_providers.openai_models_fetch_button': 'Fetch via /v1/models',
'ai_providers.openai_models_fetch_title': 'Pick Models from /v1/models',
'ai_providers.openai_models_fetch_hint': 'Call the /v1/models endpoint using the Base URL above, sending the first API key as Bearer plus custom headers.',
'ai_providers.openai_models_fetch_url_label': 'Request URL',
'ai_providers.openai_models_fetch_refresh': 'Refresh',
'ai_providers.openai_models_fetch_loading': 'Fetching models from /v1/models...',
'ai_providers.openai_models_fetch_empty': 'No models returned. Please check the endpoint or auth.',
'ai_providers.openai_models_fetch_error': 'Failed to fetch models',
'ai_providers.openai_models_fetch_back': 'Back to edit',
'ai_providers.openai_models_fetch_apply': 'Add selected models',
'ai_providers.openai_models_search_label': 'Search models',
'ai_providers.openai_models_search_placeholder': 'Filter by name, alias, or description',
'ai_providers.openai_models_search_empty': 'No models match your search. Try a different keyword.',
'ai_providers.openai_models_fetch_invalid_url': 'Please enter a valid Base URL first',
'ai_providers.openai_models_fetch_added': '{count} new models added',
'ai_providers.openai_edit_modal_title': 'Edit OpenAI Compatible Provider',
'ai_providers.openai_edit_modal_name_label': 'Provider Name:',
'ai_providers.openai_edit_modal_url_label': 'Base URL:',
'ai_providers.openai_edit_modal_keys_label': 'API Keys',
'ai_providers.openai_edit_modal_models_label': 'Model List (name[, alias] one per line):',
'ai_providers.openai_delete_confirm': 'Are you sure you want to delete this OpenAI provider?',
'ai_providers.openai_keys_count': 'Keys Count',
'ai_providers.openai_models_count': 'Models Count',
'ai_providers.openai_test_title': 'Connection Test',
'ai_providers.openai_test_hint': 'Send a /v1/chat/completions request with the current settings to verify availability.',
'ai_providers.openai_test_model_placeholder': 'Model to test',
'ai_providers.openai_test_action': 'Run Test',
'ai_providers.openai_test_running': 'Sending test request...',
'ai_providers.openai_test_success': 'Test succeeded. The model responded.',
'ai_providers.openai_test_failed': 'Test failed',
'ai_providers.openai_test_select_placeholder': 'Choose from current models',
'ai_providers.openai_test_select_empty': 'No models configured, enter manually',
// Auth files management
'auth_files.title': 'Auth Files Management',
'auth_files.title_section': 'Auth Files',
'auth_files.description': 'Manage all CLI Proxy JSON auth files here (e.g. Qwen, Gemini, Vertex). Uploading a credential immediately enables the corresponding AI integration.',
'auth_files.upload_button': 'Upload File',
'auth_files.delete_all_button': 'Delete All',
'auth_files.empty_title': 'No Auth Files',
'auth_files.empty_desc': 'Click the button above to upload the first file',
'auth_files.search_empty_title': 'No matching files',
'auth_files.search_empty_desc': 'Try changing the filters or clearing the search box.',
'auth_files.file_size': 'Size',
'auth_files.file_modified': 'Modified',
'auth_files.download_button': 'Download',
'auth_files.delete_button': 'Delete',
'auth_files.delete_confirm': 'Are you sure you want to delete file',
'auth_files.delete_all_confirm': 'Are you sure you want to delete all auth files? This operation cannot be undone!',
'auth_files.delete_filtered_confirm': 'Are you sure you want to delete all {type} auth files? This operation cannot be undone!',
'auth_files.upload_error_json': 'Only JSON files are allowed',
'auth_files.upload_success': 'File uploaded successfully',
'auth_files.download_success': 'File downloaded successfully',
'auth_files.delete_success': 'File deleted successfully',
'auth_files.delete_all_success': 'Successfully deleted',
'auth_files.delete_filtered_success': 'Deleted {count} {type} auth files successfully',
'auth_files.delete_filtered_partial': '{type} auth files deletion finished: {success} succeeded, {failed} failed',
'auth_files.delete_filtered_none': 'No deletable auth files under the current filter ({type})',
'auth_files.files_count': 'files',
'auth_files.pagination_prev': 'Previous',
'auth_files.pagination_next': 'Next',
'auth_files.pagination_info': 'Page {current} / {total} · {count} files',
'auth_files.search_label': 'Search configs',
'auth_files.search_placeholder': 'Filter by name, type, or provider',
'auth_files.page_size_label': 'Per page',
'auth_files.page_size_unit': 'items',
'auth_files.filter_all': 'All',
'auth_files.filter_qwen': 'Qwen',
'auth_files.filter_gemini': 'Gemini',
'auth_files.filter_gemini-cli': 'GeminiCLI',
'auth_files.filter_aistudio': 'AIStudio',
'auth_files.filter_claude': 'Claude',
'auth_files.filter_codex': 'Codex',
'auth_files.filter_antigravity': 'Antigravity',
'auth_files.filter_iflow': 'iFlow',
'auth_files.filter_vertex': 'Vertex',
'auth_files.filter_empty': 'Empty',
'auth_files.filter_unknown': 'Other',
'auth_files.type_qwen': 'Qwen',
'auth_files.type_gemini': 'Gemini',
'auth_files.type_gemini-cli': 'GeminiCLI',
'auth_files.type_aistudio': 'AIStudio',
'auth_files.type_claude': 'Claude',
'auth_files.type_codex': 'Codex',
'auth_files.type_antigravity': 'Antigravity',
'auth_files.type_iflow': 'iFlow',
'auth_files.type_vertex': 'Vertex',
'auth_files.type_empty': 'Empty',
'auth_files.type_unknown': 'Other',
'vertex_import.title': 'Vertex AI Credential Import',
'vertex_import.description': 'Upload a Google service account JSON to store it as auth-dir/vertex-<project>.json using the same rules as the CLI vertex-import helper.',
'vertex_import.location_label': 'Region (optional)',
'vertex_import.location_placeholder': 'us-central1',
'vertex_import.location_hint': 'Leave empty to use the default region us-central1.',
'vertex_import.file_label': 'Service account key JSON',
'vertex_import.file_hint': 'Only Google Cloud service account key JSON files are accepted.',
'vertex_import.file_placeholder': 'No file selected',
'vertex_import.choose_file': 'Choose File',
'vertex_import.import_button': 'Import Vertex Credential',
'vertex_import.file_required': 'Select a .json credential file first',
'vertex_import.success': 'Vertex credential imported successfully',
'vertex_import.result_title': 'Credential saved',
'vertex_import.result_project': 'Project ID',
'vertex_import.result_email': 'Service account',
'vertex_import.result_location': 'Region',
'vertex_import.result_file': 'Persisted file',
// OAuth excluded models
'oauth_excluded.title': 'OAuth Excluded Models',
'oauth_excluded.description': 'Per-provider exclusions are shown as cards; click edit to adjust. Wildcards * are supported and the scope follows the auth file filter.',
'oauth_excluded.add': 'Add Exclusion',
'oauth_excluded.add_title': 'Add provider exclusion',
'oauth_excluded.edit_title': 'Edit exclusions for {provider}',
'oauth_excluded.refresh': 'Refresh',
'oauth_excluded.refreshing': 'Refreshing...',
'oauth_excluded.provider_label': 'Provider',
'oauth_excluded.provider_auto': 'Follow current filter',
'oauth_excluded.provider_placeholder': 'e.g. gemini-cli',
'oauth_excluded.provider_hint': 'Defaults to the current filter; pick an existing provider or type a new name.',
'oauth_excluded.models_label': 'Models to exclude',
'oauth_excluded.models_placeholder': 'gpt-4.1-mini\n*-preview',
'oauth_excluded.models_hint': 'Separate by commas or new lines; saving an empty list removes that provider. * wildcards are supported.',
'oauth_excluded.save': 'Save/Update',
'oauth_excluded.saving': 'Saving...',
'oauth_excluded.save_success': 'Excluded models updated',
'oauth_excluded.save_failed': 'Failed to update excluded models',
'oauth_excluded.delete': 'Delete Provider',
'oauth_excluded.delete_confirm': 'Delete the exclusion list for {provider}?',
'oauth_excluded.delete_success': 'Exclusion list removed',
'oauth_excluded.delete_failed': 'Failed to delete exclusion list',
'oauth_excluded.deleting': 'Deleting...',
'oauth_excluded.no_models': 'No excluded models',
'oauth_excluded.model_count': '{count} models excluded',
'oauth_excluded.list_empty_all': 'No exclusions yet—use “Add Exclusion” to create one.',
'oauth_excluded.list_empty_filtered': 'No exclusions in this scope; click “Add Exclusion” to add.',
'oauth_excluded.disconnected': 'Connect to the server to view exclusions',
'oauth_excluded.load_failed': 'Failed to load exclusion list',
'oauth_excluded.provider_required': 'Please enter a provider first',
'oauth_excluded.scope_all': 'Scope: All providers',
'oauth_excluded.scope_provider': 'Scope: {provider}',
// Codex OAuth
'auth_login.codex_oauth_title': 'Codex OAuth',
'auth_login.codex_oauth_button': 'Start Codex Login',
'auth_login.codex_oauth_hint': 'Login to Codex service through OAuth flow, automatically obtain and save authentication files.',
'auth_login.codex_oauth_url_label': 'Authorization URL:',
'auth_login.codex_open_link': 'Open Link',
'auth_login.codex_copy_link': 'Copy Link',
'auth_login.codex_oauth_status_waiting': 'Waiting for authentication...',
'auth_login.codex_oauth_status_success': 'Authentication successful!',
'auth_login.codex_oauth_status_error': 'Authentication failed:',
'auth_login.codex_oauth_start_error': 'Failed to start Codex OAuth:',
'auth_login.codex_oauth_polling_error': 'Failed to check authentication status:',
// Anthropic OAuth
'auth_login.anthropic_oauth_title': 'Anthropic OAuth',
'auth_login.anthropic_oauth_button': 'Start Anthropic Login',
'auth_login.anthropic_oauth_hint': 'Login to Anthropic (Claude) service through OAuth flow, automatically obtain and save authentication files.',
'auth_login.anthropic_oauth_url_label': 'Authorization URL:',
'auth_login.anthropic_open_link': 'Open Link',
'auth_login.anthropic_copy_link': 'Copy Link',
'auth_login.anthropic_oauth_status_waiting': 'Waiting for authentication...',
'auth_login.anthropic_oauth_status_success': 'Authentication successful!',
'auth_login.anthropic_oauth_status_error': 'Authentication failed:',
'auth_login.anthropic_oauth_start_error': 'Failed to start Anthropic OAuth:',
'auth_login.anthropic_oauth_polling_error': 'Failed to check authentication status:',
// Antigravity OAuth
'auth_login.antigravity_oauth_title': 'Antigravity OAuth',
'auth_login.antigravity_oauth_button': 'Start Antigravity Login',
'auth_login.antigravity_oauth_hint': 'Login to Antigravity service (Google account) through OAuth flow, automatically obtain and save authentication files.',
'auth_login.antigravity_oauth_url_label': 'Authorization URL:',
'auth_login.antigravity_open_link': 'Open Link',
'auth_login.antigravity_copy_link': 'Copy Link',
'auth_login.antigravity_oauth_status_waiting': 'Waiting for authentication...',
'auth_login.antigravity_oauth_status_success': 'Authentication successful!',
'auth_login.antigravity_oauth_status_error': 'Authentication failed:',
'auth_login.antigravity_oauth_start_error': 'Failed to start Antigravity OAuth:',
'auth_login.antigravity_oauth_polling_error': 'Failed to check authentication status:',
// Gemini CLI OAuth
'auth_login.gemini_cli_oauth_title': 'Gemini CLI OAuth',
'auth_login.gemini_cli_oauth_button': 'Start Gemini CLI Login',
'auth_login.gemini_cli_oauth_hint': 'Login to Google Gemini CLI service through OAuth flow, automatically obtain and save authentication files.',
'auth_login.gemini_cli_project_id_label': 'Google Cloud Project ID (Optional):',
'auth_login.gemini_cli_project_id_placeholder': 'Enter Google Cloud Project ID (optional)',
'auth_login.gemini_cli_project_id_hint': 'If a project ID is specified, authentication information for that project will be used.',
'auth_login.gemini_cli_oauth_url_label': 'Authorization URL:',
'auth_login.gemini_cli_open_link': 'Open Link',
'auth_login.gemini_cli_copy_link': 'Copy Link',
'auth_login.gemini_cli_oauth_status_waiting': 'Waiting for authentication...',
'auth_login.gemini_cli_oauth_status_success': 'Authentication successful!',
'auth_login.gemini_cli_oauth_status_error': 'Authentication failed:',
'auth_login.gemini_cli_oauth_start_error': 'Failed to start Gemini CLI OAuth:',
'auth_login.gemini_cli_oauth_polling_error': 'Failed to check authentication status:',
// Qwen OAuth
'auth_login.qwen_oauth_title': 'Qwen OAuth',
'auth_login.qwen_oauth_button': 'Start Qwen Login',
'auth_login.qwen_oauth_hint': 'Login to Qwen service through device authorization flow, automatically obtain and save authentication files.',
'auth_login.qwen_oauth_url_label': 'Authorization URL:',
'auth_login.qwen_open_link': 'Open Link',
'auth_login.qwen_copy_link': 'Copy Link',
'auth_login.qwen_oauth_status_waiting': 'Waiting for authentication...',
'auth_login.qwen_oauth_status_success': 'Authentication successful!',
'auth_login.qwen_oauth_status_error': 'Authentication failed:',
'auth_login.qwen_oauth_start_error': 'Failed to start Qwen OAuth:',
'auth_login.qwen_oauth_polling_error': 'Failed to check authentication status:',
'auth_login.missing_state': 'Unable to retrieve authentication state parameter',
// iFlow OAuth
'auth_login.iflow_oauth_title': 'iFlow OAuth',
'auth_login.iflow_oauth_button': 'Start iFlow Login',
'auth_login.iflow_oauth_hint': 'Login to iFlow service through OAuth flow, automatically obtain and save authentication files.',
'auth_login.iflow_oauth_url_label': 'Authorization URL:',
'auth_login.iflow_open_link': 'Open Link',
'auth_login.iflow_copy_link': 'Copy Link',
'auth_login.iflow_oauth_status_waiting': 'Waiting for authentication...',
'auth_login.iflow_oauth_status_success': 'Authentication successful!',
'auth_login.iflow_oauth_status_error': 'Authentication failed:',
'auth_login.iflow_oauth_start_error': 'Failed to start iFlow OAuth:',
'auth_login.iflow_oauth_polling_error': 'Failed to check authentication status:',
'auth_login.iflow_cookie_title': 'iFlow Cookie Login',
'auth_login.iflow_cookie_label': 'Cookie Value:',
'auth_login.iflow_cookie_placeholder': 'Paste browser cookie, e.g. sessionid=...;',
'auth_login.iflow_cookie_hint': 'Submit an existing cookie to finish login without opening the authorization link; the credential file will be saved automatically.',
'auth_login.iflow_cookie_button': 'Submit Cookie Login',
'auth_login.iflow_cookie_status_success': 'Cookie login succeeded and credentials are saved.',
'auth_login.iflow_cookie_status_error': 'Cookie login failed:',
'auth_login.iflow_cookie_start_error': 'Failed to submit cookie login:',
'auth_login.iflow_cookie_required': 'Please provide the Cookie value first.',
'auth_login.iflow_cookie_result_title': 'Cookie Login Result',
'auth_login.iflow_cookie_result_email': 'Account',
'auth_login.iflow_cookie_result_expired': 'Expires At',
'auth_login.iflow_cookie_result_path': 'Saved Path',
'auth_login.iflow_cookie_result_type': 'Type',
// Usage Statistics
'usage_stats.title': 'Usage Statistics',
'usage_stats.total_requests': 'Total Requests',
'usage_stats.success_requests': 'Success Requests',
'usage_stats.failed_requests': 'Failed Requests',
'usage_stats.total_tokens': 'Total Tokens',
'usage_stats.cached_tokens': 'Cached Tokens',
'usage_stats.reasoning_tokens': 'Reasoning Tokens',
'usage_stats.rpm_30m': 'RPM (last 30 min)',
'usage_stats.tpm_30m': 'TPM (last 30 min)',
'usage_stats.requests_trend': 'Request Trends',
'usage_stats.tokens_trend': 'Token Usage Trends',
'usage_stats.api_details': 'API Details',
'usage_stats.by_hour': 'By Hour',
'usage_stats.by_day': 'By Day',
'usage_stats.refresh': 'Refresh',
'usage_stats.chart_line_label_1': 'Line 1',
'usage_stats.chart_line_label_2': 'Line 2',
'usage_stats.chart_line_label_3': 'Line 3',
'usage_stats.chart_line_label_4': 'Line 4',
'usage_stats.chart_line_label_5': 'Line 5',
'usage_stats.chart_line_label_6': 'Line 6',
'usage_stats.chart_line_label_7': 'Line 7',
'usage_stats.chart_line_label_8': 'Line 8',
'usage_stats.chart_line_label_9': 'Line 9',
'usage_stats.chart_line_hidden': 'Hide',
'usage_stats.chart_line_actions_label': 'Lines to display',
'usage_stats.chart_line_add': 'Add line',
'usage_stats.chart_line_all': 'All',
'usage_stats.chart_line_delete': 'Delete line',
'usage_stats.chart_line_hint': 'Show up to 9 model lines at once',
'usage_stats.no_data': 'No Data Available',
'usage_stats.loading_error': 'Loading Failed',
'usage_stats.api_endpoint': 'API Endpoint',
'usage_stats.requests_count': 'Request Count',
'usage_stats.tokens_count': 'Token Count',
'usage_stats.models': 'Model Statistics',
'usage_stats.success_rate': 'Success Rate',
'usage_stats.total_cost': 'Total Cost',
'usage_stats.total_cost_hint': 'Based on configured model pricing',
'usage_stats.model_price_title': 'Model Pricing',
'usage_stats.model_price_reset': 'Clear Prices',
'usage_stats.model_price_model_label': 'Model',
'usage_stats.model_price_select_placeholder': 'Choose a model',
'usage_stats.model_price_select_hint': 'Models come from usage details',
'usage_stats.model_price_prompt': 'Prompt price ($/1M tokens)',
'usage_stats.model_price_completion': 'Completion price ($/1M tokens)',
'usage_stats.model_price_save': 'Save Price',
'usage_stats.model_price_empty': 'No model prices set',
'usage_stats.model_price_model': 'Model',
'usage_stats.model_price_saved': 'Model price saved',
'usage_stats.model_price_model_required': 'Please choose a model to set pricing',
'usage_stats.cost_trend': 'Cost Overview',
'usage_stats.cost_axis_label': 'Cost ($)',
'usage_stats.cost_need_price': 'Set a model price to view cost stats',
'usage_stats.cost_need_usage': 'No usage data available to calculate cost',
'usage_stats.cost_no_data': 'No cost data yet',
'stats.success': 'Success',
'stats.failure': 'Failure',
// Logs viewer
'logs.title': 'Logs Viewer',
'logs.refresh_button': 'Refresh Logs',
'logs.clear_button': 'Clear Logs',
'logs.download_button': 'Download Logs',
'logs.error_log_button': 'Select Error Log',
'logs.error_logs_modal_title': 'Error Request Logs',
'logs.error_logs_description': 'Pick an error request log file to download (only generated when request logging is off).',
'logs.error_logs_empty': 'No error request log files found',
'logs.error_logs_load_error': 'Failed to load error log list',
'logs.error_logs_size': 'Size',
'logs.error_logs_modified': 'Last modified',
'logs.error_logs_download': 'Download',
'logs.error_log_download_success': 'Error log downloaded successfully',
'logs.empty_title': 'No Logs Available',
'logs.empty_desc': 'When "Enable logging to file" is enabled, logs will be displayed here',
'logs.log_content': 'Log Content',
'logs.loading': 'Loading logs...',
'logs.load_error': 'Failed to load logs',
'logs.clear_confirm': 'Are you sure you want to clear all logs? This action cannot be undone!',
'logs.clear_success': 'Logs cleared successfully',
'logs.download_success': 'Logs downloaded successfully',
'logs.auto_refresh': 'Auto Refresh',
'logs.auto_refresh_enabled': 'Auto refresh enabled',
'logs.auto_refresh_disabled': 'Auto refresh disabled',
'logs.search_placeholder': 'Search logs by content or keyword',
'logs.search_empty_title': 'No matching logs found',
'logs.search_empty_desc': 'Try a different keyword or clear the search filter.',
'logs.lines': 'lines',
'logs.removed': 'Removed',
'logs.upgrade_required_title': 'Please Upgrade CLI Proxy API',
'logs.upgrade_required_desc': 'The current server version does not support the logs viewing feature. Please upgrade to the latest version of CLI Proxy API to use this feature.',
// Config management
'config_management.title': 'Config Management',
'config_management.editor_title': 'Configuration File',
'config_management.reload': 'Reload',
'config_management.save': 'Save',
'config_management.description': 'View and edit the server-side config.yaml file. Validate the syntax before saving.',
'config_management.status_idle': 'Waiting for action',
'config_management.status_loading': 'Loading configuration...',
'config_management.status_loaded': 'Configuration loaded',
'config_management.status_dirty': 'Unsaved changes',
'config_management.status_disconnected': 'Connect to the server to load the configuration',
'config_management.status_load_failed': 'Load failed',
'config_management.status_saving': 'Saving configuration...',
'config_management.status_saved': 'Configuration saved',
'config_management.status_save_failed': 'Save failed',
'config_management.save_success': 'Configuration saved successfully',
'config_management.error_yaml_not_supported': 'Server did not return YAML. Verify the /config.yaml endpoint is available.',
'config_management.editor_placeholder': 'key: value',
// System info
'system_info.title': 'Management Center Info',
'system_info.connection_status_title': 'Connection Status',
'system_info.api_status_label': 'API Status:',
'system_info.config_status_label': 'Config Status:',
'system_info.last_update_label': 'Last Update:',
'system_info.cache_data': 'Cache Data',
'system_info.real_time_data': 'Real-time Data',
'system_info.not_loaded': 'Not Loaded',
'system_info.seconds_ago': 'seconds ago',
'system_info.models_title': 'Available Models',
'system_info.models_desc': 'Shows the /v1/models response and uses saved API keys for auth automatically.',
'system_info.models_loading': 'Loading available models...',
'system_info.models_empty': 'No models returned by /v1/models',
'system_info.models_error': 'Failed to load model list',
'system_info.models_count': '{count} available models',
'system_info.version_check_title': 'Update Check',
'system_info.version_check_desc': 'Call the /latest-version endpoint to compare with the server version and see if an update is available.',
'system_info.version_current_label': 'Current version',
'system_info.version_latest_label': 'Latest version',
'system_info.version_check_button': 'Check for updates',
'system_info.version_check_idle': 'Click to check for updates',
'system_info.version_checking': 'Checking for the latest version...',
'system_info.version_update_available': 'An update is available: {version}',
'system_info.version_is_latest': 'You are on the latest version',
'system_info.version_check_error': 'Update check failed',
'system_info.version_current_missing': 'Server version is unavailable; cannot compare',
'system_info.version_unknown': 'Unknown',
// Notification messages
'notification.debug_updated': 'Debug settings updated',
'notification.proxy_updated': 'Proxy settings updated',
'notification.proxy_cleared': 'Proxy settings cleared',
'notification.retry_updated': 'Retry settings updated',
'notification.quota_switch_project_updated': 'Project switch settings updated',
'notification.quota_switch_preview_updated': 'Preview model switch settings updated',
'notification.usage_statistics_updated': 'Usage statistics settings updated',
'notification.logging_to_file_updated': 'Logging settings updated',
'notification.request_log_updated': 'Request logging setting updated',
'notification.ws_auth_updated': 'WebSocket authentication setting updated',
'notification.api_key_added': 'API key added successfully',
'notification.api_key_updated': 'API key updated successfully',
'notification.api_key_deleted': 'API key deleted successfully',
'notification.gemini_key_added': 'Gemini key added successfully',
'notification.gemini_key_updated': 'Gemini key updated successfully',
'notification.gemini_key_deleted': 'Gemini key deleted successfully',
'notification.gemini_multi_input_required': 'Please enter at least one Gemini key',
'notification.gemini_multi_failed': 'Gemini bulk add failed',
'notification.gemini_multi_summary': 'Gemini bulk add finished: {success} added, {skipped} skipped, {failed} failed',
'notification.codex_config_added': 'Codex configuration added successfully',
'notification.codex_config_updated': 'Codex configuration updated successfully',
'notification.codex_config_deleted': 'Codex configuration deleted successfully',
'notification.codex_base_url_required': 'Please enter the Codex Base URL',
'notification.claude_config_added': 'Claude configuration added successfully',
'notification.claude_config_updated': 'Claude configuration updated successfully',
'notification.claude_config_deleted': 'Claude configuration deleted successfully',
'notification.field_required': 'Required fields cannot be empty',
'notification.openai_provider_required': 'Please fill in provider name and Base URL',
'notification.openai_provider_added': 'OpenAI provider added successfully',
'notification.openai_provider_updated': 'OpenAI provider updated successfully',
'notification.openai_provider_deleted': 'OpenAI provider deleted successfully',
'notification.openai_model_name_required': 'Model name is required',
'notification.openai_test_url_required': 'Please provide a valid Base URL before testing',
'notification.openai_test_key_required': 'Please add at least one API key before testing',
'notification.openai_test_model_required': 'Please select or enter a model to test',
'notification.data_refreshed': 'Data refreshed successfully',
'notification.connection_required': 'Please establish connection first',
'notification.refresh_failed': 'Refresh failed',
'notification.update_failed': 'Update failed',
'notification.add_failed': 'Add failed',
'notification.delete_failed': 'Delete failed',
'notification.upload_failed': 'Upload failed',
'notification.download_failed': 'Download failed',
'notification.login_failed': 'Login failed',
'notification.please_enter': 'Please enter',
'notification.please_fill': 'Please fill',
'notification.provider_name_url': 'provider name and Base URL',
'notification.api_key': 'API key',
'notification.gemini_api_key': 'Gemini API key',
'notification.codex_api_key': 'Codex API key',
'notification.claude_api_key': 'Claude API key',
'notification.link_copied': 'Link copied to clipboard',
// Language switch
'language.switch': 'Language',
'language.chinese': '中文',
'language.english': 'English',
// Theme switch
'theme.switch': 'Theme',
'theme.light': 'Light',
'theme.dark': 'Dark',
'theme.switch_to_light': 'Switch to light mode',
'theme.switch_to_dark': 'Switch to dark mode',
'theme.auto': 'Follow system',
// Sidebar
'sidebar.toggle_expand': 'Expand sidebar',
'sidebar.toggle_collapse': 'Collapse sidebar',
// Footer
'footer.api_version': 'CLI Proxy API Version',
'footer.build_date': 'Build Time',
'footer.version': 'Management UI Version',
'footer.author': 'Author'
}
},
// 获取翻译文本
t(key, params = {}) {
const translation = this.translations[this.currentLanguage]?.[key] ||
this.translations[this.fallbackLanguage]?.[key] ||
key;
// 简单的参数替换
return translation.replace(/\{(\w+)\}/g, (match, param) => {
return params[param] || match;
});
},
// 设置语言
setLanguage(lang) {
if (this.translations[lang]) {
this.currentLanguage = lang;
localStorage.setItem('preferredLanguage', lang);
this.updatePageLanguage();
this.updateAllTexts();
}
},
// 更新页面语言属性
updatePageLanguage() {
document.documentElement.lang = this.currentLanguage;
},
// 更新所有文本
updateAllTexts() {
// 更新所有带有 data-i18n 属性的元素
document.querySelectorAll('[data-i18n]').forEach(element => {
const key = element.getAttribute('data-i18n');
const text = this.t(key);
if (element.tagName === 'INPUT' && (element.type === 'text' || element.type === 'password')) {
element.placeholder = text;
} else if (element.tagName === 'TITLE') {
element.textContent = text;
} else {
element.textContent = text;
}
});
// 更新所有包含 data-i18n-placeholder 的输入框占位符
document.querySelectorAll('[data-i18n-placeholder]').forEach(element => {
const key = element.getAttribute('data-i18n-placeholder');
element.placeholder = this.t(key);
});
// 更新 data-i18n-title
document.querySelectorAll('[data-i18n-title]').forEach(element => {
const key = element.getAttribute('data-i18n-title');
element.title = this.t(key);
});
// 更新 data-i18n-tooltip
document.querySelectorAll('[data-i18n-tooltip]').forEach(element => {
const key = element.getAttribute('data-i18n-tooltip');
element.setAttribute('data-tooltip', this.t(key));
});
// 更新 data-i18n-text常用于按钮或标签
document.querySelectorAll('[data-i18n-text]').forEach(element => {
const key = element.getAttribute('data-i18n-text');
element.textContent = this.t(key);
});
// 更新所有带有 data-i18n-html 属性的元素支持HTML
document.querySelectorAll('[data-i18n-html]').forEach(element => {
const key = element.getAttribute('data-i18n-html');
const html = this.t(key);
element.innerHTML = html;
});
},
// 初始化
init() {
// 从本地存储获取用户偏好语言
const savedLanguage = localStorage.getItem('preferredLanguage');
if (savedLanguage && this.translations[savedLanguage]) {
this.currentLanguage = savedLanguage;
} else {
// 根据浏览器语言自动选择
const browserLang = navigator.language || navigator.userLanguage;
if (browserLang.startsWith('zh')) {
this.currentLanguage = 'zh-CN';
} else {
this.currentLanguage = 'en-US';
}
}
this.updatePageLanguage();
this.updateAllTexts();
}
};
// 全局函数供HTML调用
window.t = (key, params) => i18n.t(key, params);
window.setLanguage = (lang) => i18n.setLanguage(lang);