export const zhCN = { translation: { app: { name: "CrossRelay", tagline: "Claude Code 与 Codex 的本地协议网关", }, nav: { dashboard: "仪表盘", providers: "Claude", settings: "设置", codex: "Codex", }, common: { save: "保存", cancel: "取消", delete: "删除", edit: "编辑", add: "新增", activate: "激活", restoring: "还原中", restore: "还原官方配置", loading: "加载中", error: "出错了", retry: "重试", none: "无", optional: "选填", language: "语言", actions: "操作", saved: "已保存", copyFailed: "操作失败", yes: "是", no: "否", }, dashboard: { title: "仪表盘", gateway: "网关", running: "运行中", stopped: "已停止", port: "端口", uptime: "运行时长", version: "版本", activeProvider: "当前供应商", noActiveProvider: "尚未激活任何供应商", requests: "请求总数", failed: "失败请求", tokensIn: "输入 Token", tokensOut: "输出 Token", recentRequests: "最近请求", tabLogs: "请求日志", tabProviders: "供应商", tabModels: "模型", tabSettings: "设置", usageTabs: "用量页面标签", usageWindowHint: "汇总范围:内存中最近 100 条模型请求,不是历史总量", summaryRequests: "请求数", summaryInput: "输入 Token", summaryOutput: "输出 Token", summaryTokens: "Token", summaryFailed: "失败", summarySuccessRate: "成功率", summaryCost: "成本", displaySettings: "显示设置", logColumns: "请求日志列", resetColumns: "恢复默认列", dataLimits: "数据范围", dataLimitsDescription: "CrossRelay 当前只保留最近 100 条模型请求于内存,重启后清空;成本、缓存命中和首字延迟暂未采集。", configSettings: "网关设置", openConfigSettings: "打开网关设置", quickApply: "写入 Claude 配置", restoreDone: "已还原为官方配置", tableTime: "时间", tableApp: "应用", tableProvider: "供应商", tableModel: "模型", tableInput: "新增输入", tableOutput: "输出", tableCacheHit: "缓存命中", tableCost: "成本", tableUnpriced: "未定价", tableSpeed: "速度", tableFirstToken: "首字", emptyLogs: "暂无请求记录", statsTitle: "统计", }, providers: { title: "Claude", add: "新增供应商", edit: "编辑供应商", name: "名称", baseUrl: "Base URL", apiKey: "API Key", preset: "预设", presetCustom: "自定义", protocol: "协议选择", protocolHintClaude: "供应商原生支持的协议:Anthropic Messages 原生无需转换;其他协议经由网关转换。", protocolHintCodex: "供应商原生支持的协议:Responses 原生无转换;Chat 与 Anthropic 经网关转换为 Responses。", protocolAnthropicClaude: "Anthropic Messages (原生)", protocolOpenAIChatClaude: "OpenAI Chat Completions (需转换)", protocolOpenAIResponsesClaude: "OpenAI Responses API (需转换)", protocolGeminiNativeClaude: "Gemini Native generateContent (需转换)", protocolOpenAIResponsesCodex: "OpenAI Responses API (原生)", protocolOpenAIChatCodex: "OpenAI Chat Completions (需转换)", protocolAnthropicCodex: "Anthropic Messages (需转换)", models: "模型映射", defaultModel: "默认模型", sonnetModel: "Sonnet 模型", haikuModel: "Haiku 模型", opusModel: "Opus 模型", extraMappings: "精确映射", extraKey: "请求的模型名", extraValue: "上游模型名", addMapping: "添加一行", fetchModels: "获取模型列表", fetchingModels: "获取中", modelsFetched: "已获取 {{count}} 个模型", modelsFetchHint: "点「获取模型列表」从供应商拉取可用模型,下方输入可从列表选择;不支持列表的供应商可手动输入。", fetchModelsNeedKey: "请先填写 Base URL 和 API Key", extraHint: "Codex 等客户端会把模型名原样发给网关,在此把入站模型名映射到上游模型名。", activated: "已激活", activate: "激活并写入", empty: "还没有供应商,先添加一个", validationName: "请填写名称", validationBaseUrl: "请填写 http(s) Base URL", validationApiKey: "请填写 API Key", appliedEnv: "已写入 ~/.claude/settings.json 的环境变量", created: "供应商已创建", updated: "供应商已更新", deleted: "供应商已删除", deleteConfirm: "确定删除这个供应商吗?", keyHint: "留空表示保持原有 Key 不变", enabledClaude: "对 Claude Code 启用", }, codex: { title: "Codex", status: "注入状态", injected: "已注入", notInjected: "未注入", configPath: "配置文件", portHint: "auto 端口模式下网关重启后端口会变,需重新激活", preview: "已写入 config.toml 的托管配置", activate: "激活并写入", activated: "已激活", restore: "还原官方配置", restoreDone: "已还原 Codex 官方配置", empty: "还没有供应商,请先到供应商页添加", }, settings: { title: "设置", gateway: "网关", portMode: "端口模式", portAuto: "自动(随机端口)", portFixed: "固定端口", fixedPort: "固定端口号", portRestartHint: "端口模式在网关重启后生效", language: "界面语言", backups: "配置备份", backupsEmpty: "暂无备份", restoreBackup: "还原", restored: "已还原", backupTarget: "备份目标", targetClaude: "Claude Code", targetCodex: "Codex", rollback: "回滚", rolledBack: "已回滚", saveFailed: "保存失败", }, }, }; export const enUS = { translation: { app: { name: "CrossRelay", tagline: "Local protocol gateway for Claude Code and Codex", }, nav: { dashboard: "Dashboard", providers: "Claude", settings: "Settings", codex: "Codex", }, common: { save: "Save", cancel: "Cancel", delete: "Delete", edit: "Edit", add: "Add", activate: "Activate", restoring: "Restoring", restore: "Restore official config", loading: "Loading", error: "Something went wrong", retry: "Retry", none: "None", optional: "optional", language: "Language", actions: "Actions", saved: "Saved", copyFailed: "Action failed", yes: "Yes", no: "No", }, dashboard: { title: "Dashboard", gateway: "Gateway", running: "Running", stopped: "Stopped", port: "Port", uptime: "Uptime", version: "Version", activeProvider: "Active provider", noActiveProvider: "No provider activated yet", requests: "Requests", failed: "Failed", tokensIn: "Input tokens", tokensOut: "Output tokens", recentRequests: "Recent requests", tabLogs: "Request logs", tabProviders: "Providers", tabModels: "Models", tabSettings: "Settings", usageTabs: "Usage page tabs", usageWindowHint: "Scope: the latest 100 model requests held in memory, not all-time history", summaryRequests: "Requests", summaryInput: "Input tokens", summaryOutput: "Output tokens", summaryTokens: "Tokens", summaryFailed: "Failed", summarySuccessRate: "Success rate", summaryCost: "Cost", displaySettings: "Display settings", logColumns: "Request log columns", resetColumns: "Restore default columns", dataLimits: "Data scope", dataLimitsDescription: "CrossRelay currently keeps only the latest 100 model requests in memory; they are cleared on restart. Cost, cache hits, and first-token latency are not collected yet.", configSettings: "Gateway settings", openConfigSettings: "Open gateway settings", quickApply: "Write to Claude config", restoreDone: "Official config restored", tableTime: "Time", tableApp: "App", tableProvider: "Provider", tableModel: "Model", tableInput: "Fresh Input", tableOutput: "Output", tableCacheHit: "Cache Hit", tableCost: "Cost", tableUnpriced: "Unpriced", tableSpeed: "Speed", tableFirstToken: "First token", emptyLogs: "No requests yet", statsTitle: "Stats", }, providers: { title: "Claude", add: "Add provider", edit: "Edit provider", name: "Name", baseUrl: "Base URL", apiKey: "API key", preset: "Preset", presetCustom: "Custom", protocol: "Protocol", protocolHintClaude: "Native protocol supported by provider: Anthropic Messages is native without conversion; other protocols are converted by the gateway.", protocolHintCodex: "Native protocol supported by provider: Responses is native without conversion; Chat and Anthropic are converted to Responses by the gateway.", protocolAnthropicClaude: "Anthropic Messages (Native)", protocolOpenAIChatClaude: "OpenAI Chat Completions (Routing required)", protocolOpenAIResponsesClaude: "OpenAI Responses API (Routing required)", protocolGeminiNativeClaude: "Gemini Native generateContent (Routing required)", protocolOpenAIResponsesCodex: "OpenAI Responses API (Native)", protocolOpenAIChatCodex: "OpenAI Chat Completions (Routing required)", protocolAnthropicCodex: "Anthropic Messages (Routing required)", models: "Model mapping", defaultModel: "Default model", sonnetModel: "Sonnet model", haikuModel: "Haiku model", opusModel: "Opus model", extraMappings: "Exact mappings", extraKey: "Requested model", extraValue: "Upstream model", addMapping: "Add row", fetchModels: "Fetch models", fetchingModels: "Fetching", modelsFetched: "Fetched {{count}} models", modelsFetchHint: "Fetch the provider's model list to pick from the inputs below; providers without a list can be filled in manually.", fetchModelsNeedKey: "Base URL and API key are required first", extraHint: "Clients like Codex send their model names as-is; map inbound names onto upstream models here.", activated: "Active", activate: "Activate & apply", empty: "No providers yet", validationName: "Name is required", validationBaseUrl: "An http(s) base URL is required", validationApiKey: "API key is required", appliedEnv: "Environment written to ~/.claude/settings.json", created: "Provider created", updated: "Provider updated", deleted: "Provider deleted", deleteConfirm: "Delete this provider?", keyHint: "Leave empty to keep the current key", enabledClaude: "Enabled for Claude Code", }, codex: { title: "Codex", status: "Injection status", injected: "Injected", notInjected: "Not injected", configPath: "Config file", portHint: "With an automatic port the gateway picks a new port on restart; activate again afterwards.", preview: "Managed keys written to config.toml", activate: "Activate & apply", activated: "Active", restore: "Restore official config", restoreDone: "Codex official config restored", empty: "No providers yet, add one on the Providers page", }, settings: { title: "Settings", gateway: "Gateway", portMode: "Port mode", portAuto: "Automatic (random port)", portFixed: "Fixed port", fixedPort: "Fixed port number", portRestartHint: "Port mode applies after the gateway restarts", language: "Language", backups: "Config backups", backupsEmpty: "No backups yet", restoreBackup: "Restore", restored: "Restored", backupTarget: "Backup target", targetClaude: "Claude Code", targetCodex: "Codex", rollback: "Roll back", rolledBack: "Rolled back", saveFailed: "Save failed", }, }, };