diff --git a/app/locales/cn.ts b/app/locales/cn.ts new file mode 100644 index 000000000..3675ee208 --- /dev/null +++ b/app/locales/cn.ts @@ -0,0 +1,346 @@ +import { SubmitKey } from "../store/config"; + +const cn = { + WIP: "该功能仍在开发中……", + Error: { + Unauthorized: + "访问密码不正确或为空,请前往[登录](/#/auth)页输入正确的访问密码,或者在[设置](/#/settings)页填入你自己的 API Key。", + }, + Auth: { + Title: "需要密码", + Tips: "管理员开启了密码验证,请在下方填入访问码", + Input: "在此处填写访问码", + Confirm: "确认", + Later: "稍后再说", + }, + ChatItem: { + ChatItemCount: (count: number) => `${count} 条对话`, + }, + Chat: { + SubTitle: (count: number) => `共 ${count} 条对话`, + Actions: { + ChatList: "查看消息列表", + CompressedHistory: "查看压缩后的历史 Prompt", + Export: "导出聊天记录", + Copy: "复制", + Stop: "停止", + Retry: "重试", + Pin: "固定", + PinToastContent: "已将 1 条对话固定至预设提示词", + PinToastAction: "查看", + Delete: "删除", + Edit: "编辑", + }, + Commands: { + new: "新建聊天", + newm: "从面具新建聊天", + next: "下一个聊天", + prev: "上一个聊天", + clear: "清除上下文", + del: "删除聊天", + }, + InputActions: { + Stop: "停止响应", + ToBottom: "滚到最新", + Theme: { + auto: "自动主题", + light: "亮色模式", + dark: "深色模式", + }, + Prompt: "快捷指令", + Masks: "所有面具", + Clear: "清除聊天", + Settings: "对话设置", + }, + Rename: "重命名对话", + Typing: "正在输入…", + Input: (submitKey: string) => { + var inputHints = `${submitKey} 发送`; + if (submitKey === String(SubmitKey.Enter)) { + inputHints += ",Shift + Enter 换行"; + } + return inputHints + ",/ 触发补全,: 触发命令"; + }, + Send: "发送", + Config: { + Reset: "清除记忆", + SaveAs: "存为面具", + }, + IsContext: "预设提示词", + }, + Export: { + Title: "分享聊天记录", + Copy: "全部复制", + Download: "下载文件", + Share: "分享到 ShareGPT", + MessageFromYou: "来自你的消息", + MessageFromChatGPT: "来自 ChatGPT 的消息", + Format: { + Title: "导出格式", + SubTitle: "可以导出 Markdown 文本或者 PNG 图片", + }, + IncludeContext: { + Title: "包含面具上下文", + SubTitle: "是否在消息中展示面具上下文", + }, + Steps: { + Select: "选取", + Preview: "预览", + }, + Image: { + Toast: "正在生成截图", + Modal: "长按或右键保存图片", + }, + }, + Select: { + Search: "搜索消息", + All: "选取全部", + Latest: "最近几条", + Clear: "清除选中", + }, + Memory: { + Title: "历史摘要", + EmptyContent: "对话内容过短,无需总结", + Send: "自动压缩聊天记录并作为上下文发送", + Copy: "复制摘要", + Reset: "[unused]", + ResetConfirm: "确认清空历史摘要?", + }, + Home: { + NewChat: "新的聊天", + DeleteChat: "确认删除选中的对话?", + DeleteToast: "已删除会话", + Revert: "撤销", + }, + Settings: { + Title: "设置", + SubTitle: "所有设置选项", + + Danger: { + Reset: { + Title: "重置所有设置", + SubTitle: "重置所有设置项回默认值", + Action: "立即重置", + Confirm: "确认重置所有设置?", + }, + Clear: { + Title: "清除所有数据", + SubTitle: "清除所有聊天、设置数据", + Action: "立即清除", + Confirm: "确认清除所有聊天、设置数据?", + }, + }, + Lang: { + Name: "Language", // ATTENTION: if you wanna add a new translation, please do not translate this value, leave it as `Language` + All: "所有语言", + }, + Avatar: "头像", + FontSize: { + Title: "字体大小", + SubTitle: "聊天内容的字体大小", + }, + + InputTemplate: { + Title: "用户输入预处理", + SubTitle: "用户最新的一条消息会填充到此模板", + }, + + Update: { + Version: (x: string) => `当前版本:${x}`, + IsLatest: "已是最新版本", + CheckUpdate: "检查更新", + IsChecking: "正在检查更新...", + FoundUpdate: (x: string) => `发现新版本:${x}`, + GoToUpdate: "前往更新", + }, + SendKey: "发送键", + Theme: "主题", + TightBorder: "无边框模式", + SendPreviewBubble: { + Title: "预览气泡", + SubTitle: "在预览气泡中预览 Markdown 内容", + }, + Mask: { + Splash: { + Title: "面具启动页", + SubTitle: "新建聊天时,展示面具启动页", + }, + Builtin: { + Title: "隐藏内置面具", + SubTitle: "在所有面具列表中隐藏内置面具", + }, + }, + Prompt: { + Disable: { + Title: "禁用提示词自动补全", + SubTitle: "在输入框开头输入 / 即可触发自动补全", + }, + List: "自定义提示词列表", + ListCount: (builtin: number, custom: number) => + `内置 ${builtin} 条,用户定义 ${custom} 条`, + Edit: "编辑", + Modal: { + Title: "提示词列表", + Add: "新建", + Search: "搜索提示词", + }, + EditModal: { + Title: "编辑提示词", + }, + }, + HistoryCount: { + Title: "附带历史消息数", + SubTitle: "每次请求携带的历史消息数", + }, + CompressThreshold: { + Title: "历史消息长度压缩阈值", + SubTitle: "当未压缩的历史消息超过该值时,将进行压缩", + }, + Token: { + Title: "API Key", + SubTitle: "使用自己的 Key 可绕过密码访问限制", + Placeholder: "OpenAI API Key", + }, + + Usage: { + Title: "余额查询", + SubTitle(used: any, total: any) { + return `本月已使用 $${used},订阅总额 $${total}`; + }, + IsChecking: "正在检查…", + Check: "重新检查", + NoAccess: "输入 API Key 或访问密码查看余额", + }, + AccessCode: { + Title: "访问密码", + SubTitle: "管理员已开启加密访问", + Placeholder: "请输入访问密码", + }, + CustomModel: { + Title: "自定义模型名", + SubTitle: "增加自定义模型可选项,使用英文逗号隔开", + }, + Model: "模型 (model)", + Temperature: { + Title: "随机性 (temperature)", + SubTitle: "值越大,回复越随机", + }, + TopP: { + Title: "核采样 (top_p)", + SubTitle: "与随机性类似,但不要和随机性一起更改", + }, + MaxTokens: { + Title: "单次回复限制 (max_tokens)", + SubTitle: "单次交互所用的最大 Token 数", + }, + PresencePenalty: { + Title: "话题新鲜度 (presence_penalty)", + SubTitle: "值越大,越有可能扩展到新话题", + }, + FrequencyPenalty: { + Title: "频率惩罚度 (frequency_penalty)", + SubTitle: "值越大,越有可能降低重复字词", + }, + }, + Store: { + DefaultTopic: "新的聊天", + BotHello: "有什么可以帮你的吗", + Error: "出错了,稍后重试吧", + Prompt: { + History: (content: string) => "这是历史聊天总结作为前情提要:" + content, + Topic: + "使用四到五个字直接返回这句话的简要主题,不要解释、不要标点、不要语气词、不要多余文本,如果没有主题,请直接返回“闲聊”", + Summarize: + "简要总结一下对话内容,用作后续的上下文提示 prompt,控制在 200 字以内", + }, + }, + Copy: { + Success: "已写入剪切板", + Failed: "复制失败,请赋予剪切板权限", + }, + Context: { + Toast: (x: any) => `包含 ${x} 条预设提示词`, + Edit: "当前对话设置", + Add: "新增预设对话", + Clear: "上下文已清除", + Revert: "恢复上下文", + }, + Plugin: { + Name: "插件", + }, + Mask: { + Name: "面具", + Page: { + Title: "预设角色面具", + SubTitle: (count: number) => `${count} 个预设角色定义`, + Search: "搜索角色面具", + Create: "新建", + }, + Item: { + Info: (count: number) => `包含 ${count} 条预设对话`, + Chat: "对话", + View: "查看", + Edit: "编辑", + Delete: "删除", + DeleteConfirm: "确认删除?", + }, + EditModal: { + Title: (readonly: boolean) => + `编辑预设面具 ${readonly ? "(只读)" : ""}`, + Download: "下载预设", + Clone: "克隆预设", + }, + Config: { + Avatar: "角色头像", + Name: "角色名称", + Sync: { + Title: "使用全局设置", + SubTitle: "当前对话是否使用全局模型设置", + Confirm: "当前对话的自定义设置将会被自动覆盖,确认启用全局设置?", + }, + HideContext: { + Title: "隐藏预设对话", + SubTitle: "隐藏后预设对话不会出现在聊天界面", + }, + Share: { + Title: "分享此面具", + SubTitle: "生成此面具的直达链接", + Action: "复制链接", + }, + }, + }, + NewChat: { + Return: "返回", + Skip: "直接开始", + NotShow: "不再展示", + ConfirmNoShow: "确认禁用?禁用后可以随时在设置中重新启用。", + Title: "挑选一个面具", + SubTitle: "现在开始,与面具背后的灵魂思维碰撞", + More: "查看全部", + }, + + UI: { + Confirm: "确认", + Cancel: "取消", + Close: "关闭", + Create: "新建", + Edit: "编辑", + }, + Exporter: { + Model: "模型", + Messages: "消息", + Topic: "主题", + Time: "时间", + }, +}; + +type DeepPartial = T extends object + ? { + [P in keyof T]?: DeepPartial; + } + : T; + +export type LocaleType = typeof cn; +export type PartialLocaleType = DeepPartial; + +export default cn; diff --git a/app/locales/en.ts b/app/locales/en.ts new file mode 100644 index 000000000..e8ec6d677 --- /dev/null +++ b/app/locales/en.ts @@ -0,0 +1,343 @@ +import { SubmitKey } from "../store/config"; +import { LocaleType } from "./index"; + +// if you are adding a new translation, please use PartialLocaleType instead of LocaleType +const en: LocaleType = { + WIP: "Coming Soon...", + Error: { + Unauthorized: + "Unauthorized access, please enter access code in [auth](/#/auth) page.", + }, + Auth: { + Title: "Need Access Code", + Tips: "Please enter access code below", + Input: "access code", + Confirm: "Confirm", + Later: "Later", + }, + ChatItem: { + ChatItemCount: (count: number) => `${count} messages`, + }, + Chat: { + SubTitle: (count: number) => `${count} messages`, + Actions: { + ChatList: "Go To Chat List", + CompressedHistory: "Compressed History Memory Prompt", + Export: "Export All Messages as Markdown", + Copy: "Copy", + Stop: "Stop", + Retry: "Retry", + Pin: "Pin", + PinToastContent: "Pinned 1 messages to contextual prompts", + PinToastAction: "View", + Delete: "Delete", + Edit: "Edit", + }, + Commands: { + new: "Start a new chat", + newm: "Start a new chat with mask", + next: "Next Chat", + prev: "Previous Chat", + clear: "Clear Context", + del: "Delete Chat", + }, + InputActions: { + Stop: "Stop", + ToBottom: "To Latest", + Theme: { + auto: "Auto", + light: "Light Theme", + dark: "Dark Theme", + }, + Prompt: "Prompts", + Masks: "Masks", + Clear: "Clear Context", + Settings: "Settings", + }, + Rename: "Rename Chat", + Typing: "Typing…", + Input: (submitKey: string) => { + var inputHints = `${submitKey} to send`; + if (submitKey === String(SubmitKey.Enter)) { + inputHints += ", Shift + Enter to wrap"; + } + return inputHints + ", / to search prompts, : to use commands"; + }, + Send: "Send", + Config: { + Reset: "Reset to Default", + SaveAs: "Save as Mask", + }, + IsContext: "Contextual Prompt", + }, + Export: { + Title: "Export Messages", + Copy: "Copy All", + Download: "Download", + MessageFromYou: "Message From You", + MessageFromChatGPT: "Message From ChatGPT", + Share: "Share to ShareGPT", + Format: { + Title: "Export Format", + SubTitle: "Markdown or PNG Image", + }, + IncludeContext: { + Title: "Including Context", + SubTitle: "Export context prompts in mask or not", + }, + Steps: { + Select: "Select", + Preview: "Preview", + }, + Image: { + Toast: "Capturing Image...", + Modal: "Long press or right click to save image", + }, + }, + Select: { + Search: "Search", + All: "Select All", + Latest: "Select Latest", + Clear: "Clear", + }, + Memory: { + Title: "Memory Prompt", + EmptyContent: "Nothing yet.", + Send: "Send Memory", + Copy: "Copy Memory", + Reset: "Reset Session", + ResetConfirm: + "Resetting will clear the current conversation history and historical memory. Are you sure you want to reset?", + }, + Home: { + NewChat: "New Chat", + DeleteChat: "Confirm to delete the selected conversation?", + DeleteToast: "Chat Deleted", + Revert: "Revert", + }, + Settings: { + Title: "Settings", + SubTitle: "All Settings", + Danger: { + Reset: { + Title: "Reset All Settings", + SubTitle: "Reset all setting items to default", + Action: "Reset", + Confirm: "Confirm to reset all settings to default?", + }, + Clear: { + Title: "Clear All Data", + SubTitle: "Clear all messages and settings", + Action: "Clear", + Confirm: "Confirm to clear all messages and settings?", + }, + }, + Lang: { + Name: "Language", // ATTENTION: if you wanna add a new translation, please do not translate this value, leave it as `Language` + All: "All Languages", + }, + Avatar: "Avatar", + FontSize: { + Title: "Font Size", + SubTitle: "Adjust font size of chat content", + }, + + InputTemplate: { + Title: "Input Template", + SubTitle: "Newest message will be filled to this template", + }, + + Update: { + Version: (x: string) => `Version: ${x}`, + IsLatest: "Latest version", + CheckUpdate: "Check Update", + IsChecking: "Checking update...", + FoundUpdate: (x: string) => `Found new version: ${x}`, + GoToUpdate: "Update", + }, + SendKey: "Send Key", + Theme: "Theme", + TightBorder: "Tight Border", + SendPreviewBubble: { + Title: "Send Preview Bubble", + SubTitle: "Preview markdown in bubble", + }, + Mask: { + Splash: { + Title: "Mask Splash Screen", + SubTitle: "Show a mask splash screen before starting new chat", + }, + Builtin: { + Title: "Hide Builtin Masks", + SubTitle: "Hide builtin masks in mask list", + }, + }, + Prompt: { + Disable: { + Title: "Disable auto-completion", + SubTitle: "Input / to trigger auto-completion", + }, + List: "Prompt List", + ListCount: (builtin: number, custom: number) => + `${builtin} built-in, ${custom} user-defined`, + Edit: "Edit", + Modal: { + Title: "Prompt List", + Add: "Add One", + Search: "Search Prompts", + }, + EditModal: { + Title: "Edit Prompt", + }, + }, + HistoryCount: { + Title: "Attached Messages Count", + SubTitle: "Number of sent messages attached per request", + }, + CompressThreshold: { + Title: "History Compression Threshold", + SubTitle: + "Will compress if uncompressed messages length exceeds the value", + }, + Token: { + Title: "API Key", + SubTitle: "Use your key to ignore access code limit", + Placeholder: "OpenAI API Key", + }, + Usage: { + Title: "Account Balance", + SubTitle(used: any, total: any) { + return `Used this month $${used}, subscription $${total}`; + }, + IsChecking: "Checking...", + Check: "Check", + NoAccess: "Enter API Key to check balance", + }, + AccessCode: { + Title: "Access Code", + SubTitle: "Access control enabled", + Placeholder: "Need Access Code", + }, + + CustomModel: { + Title: "Custom Models", + SubTitle: "Add extra model options, separate by comma", + }, + Model: "Model", + Temperature: { + Title: "Temperature", + SubTitle: "A larger value makes the more random output", + }, + TopP: { + Title: "Top P", + SubTitle: "Do not alter this value together with temperature", + }, + MaxTokens: { + Title: "Max Tokens", + SubTitle: "Maximum length of input tokens and generated tokens", + }, + PresencePenalty: { + Title: "Presence Penalty", + SubTitle: + "A larger value increases the likelihood to talk about new topics", + }, + FrequencyPenalty: { + Title: "Frequency Penalty", + SubTitle: + "A larger value decreasing the likelihood to repeat the same line", + }, + }, + Store: { + DefaultTopic: "New Conversation", + BotHello: "Hello! How can I assist you today?", + Error: "Something went wrong, please try again later.", + Prompt: { + History: (content: string) => + "This is a summary of the chat history as a recap: " + content, + Topic: + "Please generate a four to five word title summarizing our conversation without any lead-in, punctuation, quotation marks, periods, symbols, or additional text. Remove enclosing quotation marks.", + Summarize: + "Summarize the discussion briefly in 200 words or less to use as a prompt for future context.", + }, + }, + Copy: { + Success: "Copied to clipboard", + Failed: "Copy failed, please grant permission to access clipboard", + }, + Context: { + Toast: (x: any) => `With ${x} contextual prompts`, + Edit: "Current Chat Settings", + Add: "Add a Prompt", + Clear: "Context Cleared", + Revert: "Revert", + }, + Plugin: { + Name: "Plugin", + }, + Mask: { + Name: "Mask", + Page: { + Title: "Prompt Template", + SubTitle: (count: number) => `${count} prompt templates`, + Search: "Search Templates", + Create: "Create", + }, + Item: { + Info: (count: number) => `${count} prompts`, + Chat: "Chat", + View: "View", + Edit: "Edit", + Delete: "Delete", + DeleteConfirm: "Confirm to delete?", + }, + EditModal: { + Title: (readonly: boolean) => + `Edit Prompt Template ${readonly ? "(readonly)" : ""}`, + Download: "Download", + Clone: "Clone", + }, + Config: { + Avatar: "Bot Avatar", + Name: "Bot Name", + Sync: { + Title: "Use Global Config", + SubTitle: "Use global config in this chat", + Confirm: "Confirm to override custom config with global config?", + }, + HideContext: { + Title: "Hide Context Prompts", + SubTitle: "Do not show in-context prompts in chat", + }, + Share: { + Title: "Share This Mask", + SubTitle: "Generate a link to this mask", + Action: "Copy Link", + }, + }, + }, + NewChat: { + Return: "Return", + Skip: "Just Start", + Title: "Pick a Mask", + SubTitle: "Chat with the Soul behind the Mask", + More: "Find More", + NotShow: "Never Show Again", + ConfirmNoShow: "Confirm to disable?You can enable it in settings later.", + }, + + UI: { + Confirm: "Confirm", + Cancel: "Cancel", + Close: "Close", + Create: "Create", + Edit: "Edit", + }, + Exporter: { + Model: "Model", + Messages: "Messages", + Topic: "Topic", + Time: "Time", + }, +}; + +export default en;