/** * dsh-imagegen surface copy: zh is the key source, en mirrors every key. */ export const zh = { "ppt.activityPreparing": "正在准备输入图片", "ppt.activityTextHints": "正在处理页面文字提示", "ppt.activityAssets": "正在重建页面图片素材", "ppt.activityBuilding": "正在构建幻灯片", "ppt.activityValidating": "正在校验幻灯片", "ppt.activityFinalizing": "正在合并与校验最终 PPT", "ppt.progressTitle": "转换进度", "ppt.lastActivity": "最近活动:{seconds} 秒前", "ppt.idleNote": "暂未收到新的执行事件。模型请求或外部工具可能仍在运行,这不代表任务已停止;可打开任务诊断查看已记录的步骤。", "ppt.pageProgress": "已校验 {done} / {total} 页", "ppt.progressPage": "第 {page} 页", "ppt.pageState.pending": "待处理", "ppt.pageState.running": "重建中", "ppt.pageState.validated": "校验通过", "ppt.activityHistory": "查看执行记录", "ppt.waitingActivity": "等待执行事件;页数进度将在上游生成页面记录后显示。", "ppt.activityModel": "模型请求处理中", "ppt.activityUnknownTool": "工具", "ppt.activityTool": "正在执行工具:{name}", "ppt.activityToolDone": "工具执行完成:{name}", "ppt.activityToolFailed": "工具返回错误,等待执行器处理:{name}", "ppt.activityModelDone": "已收到模型响应", "ppt.activityPages": "页面记录更新:已校验 {done} / {total} 页", "ppt.activityPrepared": "上游已准备输入图片", "ppt.activityDispatched": "上游已分派页面重建任务", "ppt.activityRecorded": "上游已记录各页结果,等待合并", "ppt.activityBuilt": "已构建最终 PPT,等待校验", "ppt.activityValidated": "上游最终 PPT 校验通过", "ppt.activityUpstreamDone": "上游流程完成,等待收集最终 PPT", "ppt.activityAgent": "正在创建技能执行器", "ppt.activityFailed": "转换执行失败,请查看任务错误与诊断", "ppt.persistenceWarning": "任务记录保存失败,转换状态与结果仍以当前页面为准;重启后历史可能不完整。错误:{error}", "ppt.diagnostic": "任务诊断", "ppt.diagnosticHint": "这里保留任务、Agent 会话和运行目录,便于关联 DSH 运行日志。点击文本框可全选复制。", "ppt.legacyDiagnostic": "这是旧任务,未保存 Agent 会话和原始错误,无法从这个通用报错恢复根因。请提供任务时间附近的 DSH 运行日志;点击文本框可复制任务信息。", "ppt.pages": "共 {count} 页", "ppt.downloadDeck": "下载 PPTX", "ppt.expand": "放大预览", "ppt.pageNavigation": "幻灯片导航", "ppt.goToPage": "转到第 {page} 页", "ppt.previousPage": "上一页", "ppt.nextPage": "下一页", "ppt.contentPreview": "内容预览 · 复杂版式以 PowerPoint 为准", "ppt.fitWindow": "适应窗口", "ppt.previewDeck": "预览 PPT", "ppt.previewHint": "内容预览支持逐页查看文字与内嵌图片;复杂版式请下载后用 PowerPoint 确认。", "ppt.agentFailed": "转换执行失败:{error}", "ppt.noAgentReply": "执行器没有返回回复或产物。请检查 DSH 默认模型的连接、额度及 Agent 预设中的文件和命令工具。", "ppt.close": "关闭", "ppt.sources": "幻灯片图片", "ppt.previewSource": "预览原图", "ppt.addImages": "添加图片", "ppt.orderHint": "按顺序生成幻灯片,可点击缩略图预览。", "ppt.history": "转换记录", "ppt.retry": "重新转换", "ppt.checkSetup": "检查配置", "ppt.settingsTitle": "图片转 PPT 配置", "ppt.updateSkill": "更新官方 skill", "ppt.reuseImages": "使用这些图片再次转换", "ppt.nav": "图片转 PPT", "ppt.title": "图片转可编辑 PPT", "ppt.description": "还原已有图片中的文字、图形与版式,输出可编辑的 PowerPoint。", "ppt.action": "生成可编辑 PPT", "ppt.upload": "上传幻灯片图片", "ppt.uploading": "正在上传…", "ppt.uploadHint": "拖入或选择 PNG / JPG / WebP,最多12张,每张20MB", "ppt.inputLimit": "请选择1–12张图片,每张对应一页幻灯片。", "ppt.invalidImage": "图片无效,请使用不超过20MB的 PNG / JPG / WebP。", "ppt.moveUp": "向前移动一页", "ppt.moveDown": "向后移动一页", "ppt.ocrTitle": "文字识别方式", "ppt.ocrPaddle": "使用已配置的 PaddleOCR", "ppt.ocrOffline": "本次使用离线文字检测", "ppt.ocrHint": "PaddleOCR 可改善文字内容和字号还原;离线模式不识别文字内容,由模型重建。", "ppt.processingHint": "转换可能耗时数分钟,并使用宿主模型及已配置的图像 API / OCR 服务;复杂页面可能需要更久。", "ppt.setupRequired": "请先在生图配置中安装 skill、运行环境,并启用技能与长任务。", "ppt.convert": "生成可编辑 PPT", "ppt.submitting": "正在提交…", "ppt.openSettings": "PPT 配置", "ppt.results": "转换结果", "ppt.resultCount": "{count} 个任务", "ppt.empty": "把图片变成可以修改的幻灯片", "ppt.emptyHint": "上传图片,或从生图结果点击「生成可编辑 PPT」。图片顺序就是幻灯片顺序。", "ppt.cancel": "取消转换", "ppt.working": "正在按 skill 转换…", "ppt.interrupted": "宿主已重启,转换中断。原始图片仍保留,请重新提交。", "ppt.invalidDeck": "产物不是有效的 PPTX,或页数与输入图片不一致。", "ppt.noDeck": "skill 未输出最终 PPTX,转换未完成。请查看运行环境与配置。", "ppt.setupHint": "直接使用上游 skill 与 editppt,不额外设计转换流程。", "ppt.installSkill": "安装官方 skill", "ppt.installed": "Skill 已安装", "ppt.installRuntime": "安装 / 修复运行环境", "ppt.checkRuntime": "检查运行环境", "ppt.runtimeReady": "editppt 已就绪", "ppt.runtimeMissing": "editppt 需要检查", "ppt.runtimeHint": "需要 Python 3.10+。安装按钮会将上游 CLI 和依赖安装到插件独立环境;首次安装需要联网。", "ppt.configured": "已配置", "ppt.secretUnchanged": "已保存,留空保持不变", "ppt.paddleLink": "申请 PaddleOCR token", "ppt.saveConfig": "保存并应用 PPT 配置", "ppt.configSaved": "PPT 配置已保存并应用。", "ppt.setupWorking": "正在处理,请稍候。安装依赖可能需要几分钟…", "poster.title": "海报编辑:文字 / Logo", "poster.hint": "在原图上叠加可编辑图层,拖动调整位置,不消耗模型额度。", "poster.sampleText": "在这里输入标题", "poster.addText": "添加文字", "poster.addLogo": "上传 Logo", "poster.undo": "撤销", "poster.redo": "重做", "poster.logoLimit": "请上传不超过 10MB、4000 万像素的 PNG / JPG / WebP 图片。", "poster.logoFailed": "无法读取 Logo 图片", "poster.exportFailed": "导出失败,请重试", "poster.preview": "海报预览", "poster.logo": "Logo 图层", "poster.loading": "正在加载图片…", "poster.layers": "图层(上方图层在前)", "poster.backgroundFixed": "底图保持原样;透明 PNG Logo 可直接叠加。", "poster.text": "文字内容", "poster.font": "字体", "poster.sans": "黑体 / 无衬线", "poster.serif": "宋体 / 衬线", "poster.mono": "等宽", "poster.fontSize": "字号(像素)", "poster.color": "文字颜色", "poster.bold": "加粗", "poster.align": "对齐方式", "poster.left": "左对齐", "poster.center": "居中", "poster.right": "右对齐", "poster.width": "宽度(像素)", "poster.front": "移到最前", "poster.back": "移到最后", "poster.delete": "删除图层", "poster.selectHint": "添加文字或上传 Logo,然后选择图层进行编辑。", "poster.discardHint": "修改尚未保存。", "poster.discard": "放弃修改", "poster.keepEditing": "继续编辑", "poster.saveHint": "保存为新图片节点,可再次打开编辑;导出 PNG 不会保存工程。", "poster.export": "导出 PNG", "poster.save": "保存到画布", "poster.working": "处理中…", "poster.sourceChanged": "原画布或图片已变更,请重新打开编辑器。", "poster.resultTitle": "可编辑海报", "poster.saved": "海报已加入画布,可再次编辑;请等待画布保存完成。", 'entry.label': 'AI 生图', 'entry.tooltip': 'AI 生图面板(gpt-image-2 / glm-image / grok-imagine-image / nanobanana / seedream 系列)', 'entry.session': '会话', 'entry.sessionTooltip': '返回当前会话界面', 'entry.image': '生图', 'entry.settings': '生图配置', 'panel.title': 'VisioWork', 'panel.githubTip': '觉得好用或有建议?欢迎来 GitHub 提 issues、点个 star 支持一下!', 'conversation.add': '加入对话', 'conversation.adding': '加入中…', 'conversation.added': '图片已加入当前对话', 'conversation.addHint': '加入对话后可使用 /edit_image 修改;命令使用插件图片模型', 'conversation.noSession': '请先打开一个会话,再加入图片', 'conversation.unavailable': '当前会话暂不可用', 'conversation.busy': '当前对话正在发送,请稍后再试', 'conversation.chooseSession': '选择目标会话', 'conversation.chooseSessionHint': '无法读取当前会话,请明确选择要接收图片的会话。', 'conversation.targetSession': '目标会话', 'conversation.selectSession': '请选择会话', 'conversation.confirmAdd': '加入所选会话', 'conversation.cancel': '取消', // mode 'mode.text': '文生图', 'mode.edit': '图生图', 'workspace.label': '创作模式', 'workspace.normal': '普通生图', 'workspace.canvas': '无限画布', 'workspace.ecommerce': '电商模式', 'canvas.addImage': '添加图片', 'canvas.addText': '添加文本', 'canvas.generate': '生成图片', 'canvas.addToCanvas': '加入画布', 'canvas.untitled': '未命名画布', 'canvas.imageNode': '图片节点', 'canvas.textNode': '文本节点', 'canvas.fromGallery': '素材库图片', 'canvas.fromHistory': '历史图片', 'canvas.project': '画布项目', 'canvas.favoriteCanvas': '收藏画布', 'canvas.unfavoriteCanvas': '取消收藏', 'canvas.favoriteProjects': '收藏夹({count})', 'canvas.allProjects': '其他画布({count})', 'canvas.newCanvas': '新建画布', 'canvas.deleteCanvas': '删除画布', 'canvas.deleteCanvasConfirm': '再点一次确认删除', 'canvas.rename': '重命名画布', 'canvas.renameHint': '双击重命名', 'canvas.background': '画布背景', 'canvas.backgroundDots': '点阵', 'canvas.backgroundLines': '网格线', 'canvas.backgroundWaves': '波浪线', 'canvas.backgroundShapeGrid': '滚动方格', 'canvas.backgroundDotField': '点场', 'canvas.backgroundDotGrid': '互动点阵', 'canvas.backgroundFloatingLines': '浮动线条', 'canvas.backgroundFlow': '流体扰动', 'canvas.backgroundLiquid': '液态以太', 'canvas.backgroundFaultyTerminal': '故障终端', 'canvas.backgroundSilk': '丝绸', 'canvas.backgroundGalaxy': '星系', 'canvas.backgroundBlank': '关闭背景渲染(提升性能)', 'canvas.backgroundUpload': '上传自定义背景…', 'canvas.backgroundRemove': '移除自定义背景', 'canvas.templateLibrary': '模板库(选择提示词生成文本+配置节点)', 'canvas.undo': '撤销 (Ctrl+Z)', 'canvas.redo': '重做 (Ctrl+Shift+Z)', 'canvas.saving': '保存中…', 'canvas.saved': '已保存', 'canvas.saveFailed': '保存失败', 'canvas.loading': '加载中…', 'canvas.toolSelect': '选择 / 移动节点', 'canvas.toolPan': '拖动画布(空格 / Ctrl + 拖动)', 'canvas.delete': '删除', 'canvas.duplicate': '创建副本 (Ctrl+D)', 'canvas.download': '下载图片', 'canvas.fitView': '适应全部内容', 'canvas.minimapOpen': '打开缩略图', 'canvas.minimapClose': '关闭缩略图', 'canvas.minimap': '画布缩略图', 'canvas.zoom': '缩放', 'canvas.textPlaceholder': '输入文本内容…', 'canvas.generatingNode': '生成中…', 'canvas.generateFailed': '生成失败', 'canvas.retry': '重试', 'canvas.taskLost': '生成任务已丢失(服务重启),请重试', 'canvas.emptyImageNode': '点击上传图片', 'canvas.connectHint': '拖到其他节点建立连线', 'canvas.connectAddHint': '拖到其他节点建立连线;点击直接添加下一节点', 'canvas.resizeHint': '拖动调整大小(图片锁定比例)', 'canvas.count': '生成数量', 'canvas.configNode': '生成配置', 'canvas.addConfigNode': '添加配置节点', 'canvas.configHint': '把图片节点连线到左侧作为参考图,文本节点连线过来作为提示词;选中本节点后在下方输入或改写提示词并生成。', 'canvas.composerLinked': '已连接 {count} 个输入节点', 'canvas.composerPlaceholder': '描述要生成的图片;也可把文本节点连线过来作为提示词…', 'canvas.countUnit': '{count} 张', 'canvas.model': '生图模型', 'canvas.modelPlaceholder': '选择模型', 'canvas.size': '尺寸比例', 'canvas.sizeAuto': '自动比例', 'canvas.quality': '清晰度', 'canvas.qualityAuto': '自动清晰度', 'canvas.needApi': '请先配置生图 API', 'canvas.needPrompt': '请输入生成描述', 'canvas.needModel': '尚未配置可用生图模型', 'canvas.openSettings': '打开设置', 'canvas.deleteConnection': '删除连线', 'canvas.paste': '粘贴 (Ctrl+V)', 'canvas.addImageNode': '添加图片节点', 'canvas.addTextNode': '添加文本节点', 'canvas.addSketch': '添加画板(手绘草图生图)', 'canvas.sketchNode': '画板节点', 'canvas.addSketchNode': '添加画板节点', 'canvas.sketchPlaceholder': '在此自由绘制草图,连线到配置节点即可作为参考图生成', 'canvas.sketchBrush': '画笔', 'canvas.sketchEraser': '橡皮擦', 'canvas.sketchUndo': '撤销上一笔', 'canvas.sketchClear': '清空画板', 'canvas.sketchWidth': '笔触粗细', 'canvas.dismiss': '关闭提示', 'canvas.annotate': '标注:在图片上画框,自动挂上提示词卡片', 'canvas.annotationNode': '标注提示词', 'canvas.annotationTag': '标注', 'canvas.annotationPlaceholder': '描述这个框里要改成什么,例如:把这里换成一只橘猫', 'canvas.annotationDrawHint': '在图片上拖拽画框;松开后从框上拉出引导线并挂一张提示词卡片(跟随图片移动,无需连线)', 'canvas.removeBackground': '移除背景(本地抠图,输出透明 PNG)', 'canvas.removingBackground': '正在移除背景…', 'canvas.removeBgDone': '已移除背景(透明像素 {percent}%)', 'canvas.removeBgFailed': '背景太复杂,本地抠图没有找到可移除的背景;可以先用「标注」框选主体再让模型重绘', 'canvas.alreadyTransparent': '这张图片已经是透明背景了', 'canvas.noBackgroundNode': '去背景图片', 'canvas.splitLayers': '图层拆分(AI 拆成可编辑图层)', 'canvas.splittingLayers': '正在拆分图层…', 'canvas.layerSplitDone': '已拆分为 {count} 个图层节点', 'canvas.layerSplitEmpty': '模型没有识别出可拆分的图层', 'canvas.layerBackground': '背景层 · {label}', 'canvas.layerObject': '图层 · {label}', 'canvas.layerText': '文字层 · {label}', 'canvas.layerKindBackground': '背景', 'canvas.layerKindObject': '元素', 'canvas.layerKindText': '文字', 'canvas.nodeModel': '本节点使用的模型(重试与相连配置节点默认使用)', 'canvas.modelDefault': '默认模型', 'canvas.fontSmaller': '缩小字号', 'canvas.fontLarger': '放大字号', 'canvas.bold': '加粗', 'canvas.textColor': '文字颜色', 'canvas.colorDefault': '跟随主题', 'canvas.close': '关闭', 'canvas.tabUpload': '上传', 'canvas.tabHistory': '历史记录', 'canvas.tabGallery': '素材库', 'canvas.imageMenuUpload': '本地图片', 'canvas.imageMenuAssets': '素材库', 'canvas.imageMenuHistory': '历史记录', 'canvas.imageMenuGenerate': 'AI生成', 'canvas.tabGenerate': 'AI 生成', 'canvas.dropHint': '图片拖动到此处即可添加', 'canvas.dropSub': '支持多选,PNG / JPG / WebP / GIF', 'canvas.untitledWork': '未命名作品', 'canvas.picked': '已选 {count} 张', 'canvas.generateAndAdd': '生成并添加到画布', 'chat.expand': '展开右侧对话', 'chat.collapse': '收起右侧对话', 'chat.toggle': '对话', 'config.resizeHint': '拖拽调整参数栏宽度', 'ecommerce.generation': '生成设置', 'ecommerce.title': '电商模式', 'ecommerce.badge': '预览', 'ecommerce.short': '电商', 'ecommerce.anchorPending': '已生成主图,其余图片正在自动参考主图生成,保证整套同款…', 'ecommerce.anchorFailed': '主图生成失败,其余图片已暂停。请重试主图(或整组重新生成)后再继续。', 'ecommerce.anchorNote': '锚定生成:先出主图,其余图片自动参考主图,保证整套同款', 'ecommerce.noAssetWarn': '未上传商品图:主图将按文字描述生成并作为锚定基准,建议先上传商品主图获得更高一致性', 'ecommerce.product': '商品信息', 'ecommerce.productName': '商品名称(必填)', 'ecommerce.projectName': '项目名称(可选)', 'ecommerce.constraints': '卖点与约束', 'ecommerce.sellingPoints': '参考信息:品牌型号、规格(容量/尺寸/克重)、材质工艺、核心卖点、安全认证、配件清单等', 'ecommerce.protectedFeatures': '必须保留的特征,例如:颜色、Logo、包装文字、结构', 'ecommerce.styleHint': '风格补充,例如:高级感 / 写实 / 自然光', 'ecommerce.setStructure': '套图结构', 'ecommerce.preview': '生成套图预览', 'ecommerce.planTitle': '预计生成 {count} 张图片', 'ecommerce.planSlot': '{count} 张 · {description}', 'ecommerce.confirm': '确认生成整套图片', 'ecommerce.uploadRef': '上传商品图(必选,最多 4 张:主体 / 包装 / 细节)', 'ecommerce.uploadShort': '上传素材', 'ecommerce.sellingTitle': '商品卖点', 'ecommerce.advanced': '高级选项(平台 / 约束)', 'ecommerce.params': '参数选择', 'ecommerce.platformLabel': '平台', 'ecommerce.languageLabel': '文案语言', 'ecommerce.customLanguageOption': '自定义…', 'ecommerce.customLanguageLabel': '自定义语言', 'ecommerce.customLanguagePlaceholder': '输入语言名称,例如:Русский / 日本語 / Português', 'ecommerce.ratioLabel': '比例', 'ecommerce.categoryLabel': '类目', 'ecommerce.multiSelect': '可多选', 'ecommerce.countHint': '点击调整数量(1-4)', 'ecommerce.refSettings': '参考图设置(可选)', 'ecommerce.styleTitle': '风格 / 补充提示', 'ecommerce.protectedLabel': '必须保留的特征(可选)', 'ecommerce.assetsFull': '最多上传 4 张商品图', 'ecommerce.productRefTitle': '主图参考图', 'ecommerce.productRefHint': '必选 · 商品主体图,最多 4 张', 'ecommerce.styleRefTitle': '风格参考图', 'ecommerce.styleRefBadge': '可选,最多 1 张', 'ecommerce.styleRefHint': '只传风格、光影、构图、氛围,不能更换商品主体。', 'ecommerce.styleRefUpload': '上传风格参考图', 'ecommerce.refInfoTitle': '参数信息', 'ecommerce.aiWrite': 'AI 帮写', 'ecommerce.aiWriting': 'AI 整理中…', 'ecommerce.aiWriteHint': '根据商品名称与类目自动整理参数信息(提示词)', 'ecommerce.promptInfoPlaceholder': '选填:品牌型号、规格(容量/尺寸/克重)、材质工艺、核心卖点、安全认证、配件清单、画面要求等,也可以点右上角 AI 帮写', 'ecommerce.optional': '可选', 'ecommerce.previewBoardTitle': '生成前预览', 'ecommerce.previewBoardHint': '每张图的提示词都可以在生成前修改', 'ecommerce.promptReset': '恢复默认', 'ecommerce.promptAutoHint': '自动生成 · 可直接修改', 'ecommerce.promptPolish': 'AI 润色', 'ecommerce.promptPolishing': '润色中…', 'ecommerce.refSelect': '该用途使用的参考图', 'ecommerce.refNone': '不使用参考图', 'ecommerce.role.product': '商品主体', 'ecommerce.role.packaging': '包装', 'ecommerce.role.detail': '细节/角度', 'ecommerce.role.style': '风格参考', 'ecommerce.footerReady': '将生成 {count} 张套图', 'ecommerce.footerEmpty': '请选择套图结构', 'ecommerce.results.title': '套图结果', 'ecommerce.results.progress': '{done}/{total} 已完成', 'ecommerce.results.failed': '{count} 张失败', 'ecommerce.results.empty': '确认生成后,每张图片的任务状态和结果会按用途显示在这里', 'ecommerce.results.regenerate': '重新生成', 'ecommerce.results.export': '导出清单', 'ecommerce.results.newProduct': '新商品', // prompt 'prompt.placeholder': '描述你想要的画面,例如:一只戴着宇航员头盔的橘猫,在月球上举起望远镜,水彩风格,柔和光线…', 'prompt.required': '请输入提示词', 'prompt.count': '{count}', 'prompt.countLimit': '{count} / {limit}', 'prompt.overLimit': '超出该模型 {limit} 字符的提示词上限,请精简后再生成', 'prompt.enhance': '增强', 'prompt.enhancing': '增强中…', 'prompt.enhanceHint': '使用已配置的对话模型扩写提示词', 'prompt.configTitle': '请先配置提示词增强模型', 'prompt.configHint': '已打开「设置 → 生图配置」。填写或复用 API 地址和密钥,选择对话模型并保存。', 'tasks.title': '生成任务', 'tasks.queued': '排队中', 'tasks.running': '生成中', 'tasks.completed': '已完成', 'tasks.failed': '失败', 'tasks.cancelled': '已取消', 'tasks.cancel': '取消', 'tasks.retry': '重试', // diagnostics (#38): the retained record of upstream attempts 'diagnostics.title': '诊断日志', 'diagnostics.open': '诊断日志', 'diagnostics.count': '{count} 条记录', 'diagnostics.refresh': '刷新', 'diagnostics.loading': '读取中…', 'diagnostics.copy': '复制全部', 'diagnostics.copied': '已复制', 'diagnostics.clear': '清空', 'diagnostics.empty': '暂无记录。生成失败后,这里会记录请求地址、HTTP 状态、网络错误码与上游响应。', 'diagnostics.hint': '记录仅保存在本机内存中,密钥已脱敏,可直接复制粘贴到 issue。', 'diagnostics.response': '上游响应', 'diagnostics.requestLabel': '请求内容', 'diagnostics.exactUrl': '完整 URL', // parameters 'params.size': '尺寸', 'params.quality': '清晰度', 'params.count': '生成数量', 'params.detail': '细节', 'size.auto': '自动', 'size.square': '1:1 方图', 'size.portrait34': '3:4 标准竖图', 'size.landscape43': '4:3 标准横图', 'size.portrait916': '9:16 竖屏', 'size.portrait23': '2:3 竖图', 'size.landscape32': '3:2 横图', 'size.wide169': '16:9 宽屏', 'size.ultrawide21': '21:9 超宽屏', 'quality.auto': '自动', 'quality.1k': '1K', 'quality.2k': '2K', 'quality.4k': '4K', 'count.one': '1 张', 'count.two': '2 张', 'count.three': '3 张', 'count.four': '4 张', 'detail.auto': '自动', 'detail.standard': '标准', 'detail.high': '高清', 'detail.hint': '透传参数,部分 gpt-image-2 网关支持;官方接口请保持「自动」', // footer 'model.label': '模型', 'model.channel': '渠道', 'model.channelPlaceholder': '默认渠道', 'model.noEditModels': '当前模式暂无可用模型', 'compare.enable': '多模型对比', 'compare.models': '参与对比的模型', 'compare.title': '多模型结果对比', 'compare.fullscreen': '全屏对比', 'compare.selectRequired': '请至少选择一个对比模型', 'generate': '开始生成', 'generating': '生成中…', // edit reference image 'edit.upload': '点击或拖拽上传参考图片', 'edit.uploadHint': 'PNG / JPG / WEBP,不超过 10MB', 'edit.change': '更换图片', 'edit.remove': '移除', 'edit.required': '请先上传参考图片', 'edit.references': '参考图片', 'edit.addedCount': '已添加 {count} 张', 'edit.clearAll': '清空', 'edit.uploadMultiple': '点击或拖拽上传多张图片', 'edit.addMore': '继续添加参考图', 'edit.add': '添加', 'edit.previewReference': '预览图{index}:{name}', 'edit.removeReference': '删除图{index}:{name}', 'edit.multiHint': '支持多选、拖拽或粘贴图片', 'edit.limits': '最多 {count} 张 · 单张≤10MB · 合计≤16MB', 'edit.reading': '正在读取参考图片…', 'edit.referencePreview': '参考图片预览', 'edit.previousReference': '上一张参考图', 'edit.nextReference': '下一张参考图', 'edit.invalidFiles': '部分图片未添加:仅支持非空 PNG / JPG / WEBP / GIF,单张不超过10MB。', 'edit.limitReached': '最多添加 {count} 张参考图,多余图片未添加。', 'edit.totalTooLarge': '图片合计大小不能超过16MB,超出部分未添加。', 'edit.readFailed': '部分图片读取失败,请重新上传。', 'edit.modelLimit': '当前选中的模型适配最多支持 {count} 张参考图,请切换模型或移除多余图片。', // canvas 'canvas.emptyTitle': '开始你的创作', 'canvas.emptyHint': '双击空白处或用底部工具添加图片/文本节点;把图片和文本节点连线到目标节点,选中后即可在底部生成器中出图', 'canvas.new': '新建作图', 'canvas.newHint': '开始新的作图并清空预览', 'canvas.error': '生成失败:{error}', 'canvas.submitting': '正在加入生成队列…', 'canvas.queued': '已加入生成队列', 'canvas.queueHint': '当前有 {count} 个任务等待处理', 'canvas.generating': '正在生成图片…', 'canvas.elapsed': '已用时 {seconds}s', 'canvas.images': '本次生成 {count} 张', 'download': '下载', 'revisedPrompt': '优化提示词:{prompt}', // history 'history.title': '历史记录', 'history.empty': '暂无历史记录,生成图片后会保存在这里', 'history.clear': '清空', 'history.clearConfirm': '确定要清空全部历史记录吗?此操作不可撤销。', 'history.restore': '恢复', 'history.delete': '删除', 'history.images': '张', 'history.viewing': '历史 · {time}', 'history.search': '搜索提示词或模型…', 'history.model': '模型筛选', 'history.ratio': '比例筛选', 'history.allModels': '全部模型', 'history.allRatios': '全部比例', // gallery 'gallery.title': '素材库', 'gallery.categories': '分类', 'gallery.all': '全部素材', 'gallery.upload': '上传素材', 'gallery.uploadModel': '本地上传', 'gallery.uploaded': '素材已入库', 'gallery.uploadHint': '把本地图保存进素材库,画布随时可用', 'gallery.gpt': 'gpt-image-2', 'gallery.grok': 'grok-imagine-image', 'gallery.ratio': '画面比例', 'gallery.tags': '标签', 'gallery.filterHint': '按生成模式、模型和比例筛选素材', 'gallery.count': '· 共 {count} 幅', 'gallery.viewMode': '视图模式', 'gallery.masonry': '瀑布流', 'gallery.grid': '整齐网格', 'gallery.sort': '排序', 'gallery.newest': '最新发布', 'gallery.oldest': '最早发布', 'gallery.untitled': '未命名作品', 'gallery.search': '搜索作品或模型…', 'gallery.tagsPlaceholder': '标签,用逗号分隔', 'gallery.tagsApply': '添加标签', 'gallery.editTags': '编辑标签', 'gallery.tagsEditShort': '编辑', 'gallery.tagsSave': '保存', 'gallery.tagsCancel': '取消', 'gallery.selected': '已选 {count} 项', 'gallery.selectionDone': '完成选择', 'gallery.selectionClear': '取消选择', 'gallery.downloadSelected': '下载所选', 'gallery.exportJson': '导出 JSON', 'gallery.select': '选择作品', 'gallery.add': '加入素材库', 'gallery.added': '已加入素材库', 'gallery.already': '已在素材库中', 'gallery.delete': '移出素材库', 'gallery.openFolder': '打开文件夹', 'gallery.clear': '清空素材库', 'gallery.openFolderHint': '在系统的文件管理器中打开图片保存目录(~/.dsh/dsh-imagegen)', 'gallery.clearConfirm': '确定要清空整个素材库吗?此操作不可撤销。', 'gallery.empty': '素材库还是空的,把喜欢的图片加入进来吧', 'gallery.viewing': '素材库 · {time}', // preview 'preview.title': '图片预览', 'preview.open': '点击预览', 'preview.close': '关闭', 'preview.prev': '上一张', 'preview.next': '下一张', 'preview.index': '{index} / {total}', 'preview.zoomControls': '图片缩放控制', 'preview.zoomIn': '放大', 'preview.zoomOut': '缩小', 'preview.zoomReset': '重置缩放', 'preview.zoomLevel': '{percent}%', 'preview.copyPrompt': '复制提示词', 'preview.copied': '已复制', 'preview.addToEdit': '添加到图生图', // config banner 'config.missing': '尚未配置 API:请打开「设置 → 生图配置」,填写 API 地址与密钥。', 'config.generationTitle': '请先配置生图 API', 'config.generationHint': '已打开「设置 → 生图配置」。填写生图 API 地址与 API 密钥,保存后即可开始生成。', 'config.enhancementTitle': '请先配置提示词增强模型', 'config.enhancementHint': '已打开「设置 → 生图配置」。填写或复用对话 API 地址和密钥,选择对话模型并保存。', 'config.disabledTitle': 'AI 生图插件已停用', 'config.disabledHint': '已打开「设置 → 生图配置」。开启「启用插件」后即可生成图片。', 'config.configured': '已连接 {url}', 'config.disabled': '插件已停用,请在设置中重新启用。', 'connection.connected': '已连接', 'connection.disconnected': '未连接', 'panel.collapseConfig': '收起参数栏', 'panel.expandConfig': '展开参数栏', // plugin update 'update.available': '检测到新版本:{version}', 'update.button': '更新 v{version}', 'update.title': '发现新版本', 'update.close': '关闭', 'update.noNotes': '本次 Release 未提供更新说明。', 'update.installed': '已更新', 'update.install': '在线更新', 'update.installing': '更新中…', 'update.success': '已更新到 {version},请重启 DSH', 'update.failed': '更新失败', 'update.hostManaged': '宿主缺少安装接口', 'update.hostHint': '将通过 DSH 内置插件管理器安装更新,使用当前桌面端的运行环境。更新完成后请重启 DSH。', 'update.hostManagedHint': '当前 DSH 桌面宿主未提供插件安装接口。请先升级 DSH,或从 Release 下载插件安装包后按宿主支持的方式安装。', 'update.release': '查看 Release', // settings card 'settings.title': 'AI 生图(dsh-imagegen)', 'settings.description': '配置图像生成 API 地址与密钥', 'settings.summaryTitle': '配置概览', 'settings.summaryHint': '点击状态卡或分组标题查看详情;每次只展开一个区域。', 'settings.summaryReady': '核心配置已就绪', 'settings.summaryNeedsSetup': '还需配置渠道', 'settings.summaryNotConfigured': '未配置', 'settings.summaryChannels': '{ready}/{total} 可用', 'settings.summaryOptional': '可选', 'settings.summaryEnabled': '已启用', 'settings.summaryDisabled': '已关闭', 'settings.summaryChannelsLabel': '渠道与模型', 'settings.summaryPromptLabel': '提示词增强', 'settings.summaryStorageLabel': '存储同步', 'settings.summarySkillsLabel': '画布技能', 'settings.summaryGeneralLabel': '通用设置', 'settings.subscriptionLoggedIn': '已登录', 'settings.subscriptionLoggedOut': '未登录', 'settings.subscriptionExperimental': '实验功能:使用第三方客户端接口,可能随服务端更新失效,请遵守对应服务条款。', 'settings.subscriptionExperimentalTag': '实验', 'settings.subscriptionLogin': '登录账号', 'settings.subscriptionLoggingIn': '等待登录…', 'settings.subscriptionLoginOk': '登录成功', 'settings.subscriptionLogout': '退出登录', 'settings.subscriptionLoggingOut': '正在退出…', 'settings.subscriptionIsolationHint': '授权令牌仅保存在 DSH Credentials,与 API Key 完全隔离。', 'settings.subscriptionDeviceCode': '请在授权页输入验证码:{code}', 'settings.subscriptionManualHint': '如果浏览器没有自动回调,完成登录后把最终地址或授权码粘贴到这里。', 'settings.subscriptionManualPlaceholder': '粘贴回调地址或授权码', 'settings.subscriptionManualComplete': '完成登录', 'settings.headerNeedsChannel': '先添加一个生图渠道开始使用', 'settings.headerSummary': '{channels} 个渠道 · {models} 个模型', 'settings.skillsTitle': '无限画布技能', 'settings.generalTitle': '通用设置', 'settings.generalHint': '插件总开关、Agent 播报与生图权限', 'settings.currentVersion': '当前版本', 'settings.apiUrl': 'API 地址(api_url)', 'settings.apiUrlHint': 'OpenAI 兼容接口基址,如 https://api.openai.com/v1;将自动拼接 /images/generations 与 /images/edits', 'settings.apiKey': 'API 密钥(api_key)', 'settings.apiKeyHint': 'Bearer 密钥,明文存于本机设置文档;界面只显示是否已设置', 'settings.apiKeySet': '已保存密钥;输入新值可更换,点击「清除」可删除', 'settings.apiKeyClear': '清除', 'settings.imageModelsTitle': '生图模型', 'settings.imageModelsHint': '保存 API 地址和密钥后检测候选模型;请只选择实际支持生图的项。', 'settings.imageModels': '允许使用的生图模型', 'settings.imageModelsManualHint': '一行一个模型;API 未提供 /models 时可手动填写。面板和 Agent 只能使用此列表。', 'settings.imageModelsFetch': '检测可用模型', 'settings.imageModelsLoading': '检测中…', 'settings.imageModelsCandidates': '检测到的候选模型(勾选后保存)', 'settings.addModel': '+ 手动添加', 'settings.cancelAddModel': '收起添加', 'settings.addModelPlaceholder': '输入模型名称,例如 qwen-image', 'settings.addModelConfirm': '添加', 'settings.removeModel': '移除模型', 'settings.optional': '可选', 'settings.moreOptions': '更多设置', 'settings.localStoragePath': '本地图片存储目录', 'settings.localStoragePathHint': '生成历史、素材库和无限画布图片统一保存到此目录;留空使用默认的 ~/.dsh/dsh-imagegen。', 'settings.storageTitle': '对象存储同步', 'settings.storageEnabled': '启用对象存储同步', 'settings.storageHint': '图片保存到本地后,异步上传一份到 S3 兼容对象存储(腾讯云 COS / 阿里云 OSS / 七牛云 S3 / MinIO / R2 等)', 'settings.storageEndpoint': '接口地址(含存储桶)', 'settings.storageEndpointHint': 'S3 兼容地址,例如 https://bucket-appid.cos.ap-guangzhou.myqcloud.com 或 https://bucket.oss-cn-hangzhou.aliyuncs.com', 'settings.storageRegion': '区域', 'settings.storageRegionHint': '签名用区域 ID,例如 ap-guangzhou / oss-cn-hangzhou / cn-east-1', 'settings.storagePrefix': 'Key 前缀', 'settings.storagePrefixHint': '上传目录前缀,对象键为 前缀/gallery|images/文件名', 'settings.storageAccessKey': 'Access Key', 'settings.storageAccessKeyHint': 'S3 兼容密钥 ID(COS SecretId / OSS AccessKeyId / 七牛 AK)', 'settings.storageSecretKey': 'Secret Key', 'settings.storageSecretKeyHint': 'S3 兼容密钥,仅保存在本机设置文档', 'settings.storageSyncGallery': '同步素材库图片', 'settings.storageSyncGalleryHint': '加入素材库的图片自动上传', 'settings.storageSyncHistory': '同步历史记录图片', 'settings.storageSyncHistoryHint': '所有生成结果也一并上传(数量可能较大)', 'settings.storageTest': '测试连接', 'settings.storageTesting': '测试中…', 'settings.storageTestOk': '连接成功({ms} ms),已上传探测文件', 'settings.storageTestFailed': '连接失败:{error}', 'settings.storageKeyHint': '提示:同步为尽力而为,失败不影响本地保存;可在对象存储控制台按前缀查看已同步文件。', 'settings.promptEnhanceTitle': '提示词增强模型', 'settings.promptEnhanceHint': '用于将简短描述扩写为更完整的生图提示词;留空的地址和密钥会复用生图配置。', 'settings.promptApiUrl': '对话 API 地址(可选)', 'settings.promptApiUrlHint': 'OpenAI 兼容基址;留空则复用图像 API 地址。', 'settings.promptApiKey': '对话 API 密钥(可选)', 'settings.promptApiKeyHint': '留空则复用图像 API 密钥。', 'settings.promptModel': '对话模型', 'settings.promptModelHint': '选择或填写支持 /chat/completions 的模型。', 'settings.promptModelDetectionHint': '默认复用生图 API;检测后点选一个模型即可。', 'settings.promptModelsFetch': '获取可用模型', 'settings.promptModelsLoading': '正在获取…', 'settings.promptModelsSelect': '选择一个模型', 'settings.promptModelsCandidates': '检测到的候选对话模型', 'settings.addPromptModelPlaceholder': '输入对话模型名称,例如 gpt-4.1-mini', 'settings.promptApiAdvanced': '使用独立对话 API(可选)', 'settings.announceToAgent': '向 Agent 播报本插件', 'settings.announceToAgentHint': '开启后,本插件的存在与能力会写入每个 Agent 的系统提示词', 'settings.allowAgentImageGeneration': '允许 Agent 调用生图', 'settings.allowAgentImageGenerationHint': '默认开启。关闭后,Agent 无法提交、查询或取消生图任务;侧边栏工作台不受影响。', 'settings.enabled': '启用插件', 'settings.enabledHint': '关闭后生图面板不可用(设置卡片始终可用)', 'settings.save': '保存', 'settings.saving': '保存中…', 'settings.discard': '放弃修改', 'settings.unsaved': '有未保存的修改', 'settings.saveFailed': '保存失败,请重试', 'settings.readOnly': '当前设置文档为只读,无法保存。', 'settings.notExposed': '设置命名空间不可用:本部署未提供该插件的设置服务。', 'settings.expand': '展开', 'settings.collapse': '收起', 'settings.inherit': '继承', 'settings.on': '开', 'settings.off': '关', 'settings.overridden': '已覆盖', 'settings.reset': '重置', 'settings.invalidNumber': '请输入有效数字', // template library 'templates.open': '模板库', 'templates.shortLabel': '模板', 'templates.resize': '调整模板库宽度', 'templates.recentsCount': '最近使用 {count} 个', 'templates.recents': '最近使用', 'templates.views': '浏览方式', 'templates.browse': '全部模板', 'templates.restore': '恢复宽度', 'templates.fullscreen': '铺满工作区', 'templates.searchScope': '搜索范围', 'templates.currentSource': '当前模板库', 'templates.allSources': '全部模板库', 'templates.recentsEmpty': '使用模板后,会在这里显示最近记录', 'templates.applyStyle': '添加到风格要求', 'templates.replace': '替换当前提示词', 'templates.append': '追加到提示词', 'templates.ecommerceHint': '模板会追加到参数信息,保留商品名称、参考图和出图配置。', 'templates.title': '提示词模板库', 'templates.sources': '模板库来源', 'templates.meta': '共 {count} 个模板 · {origin}', 'templates.origin.bundled': '内置快照', 'templates.origin.refreshed': '在线刷新', 'templates.search': '搜索模板标题或提示词…', 'templates.all': '全部', 'templates.close': '关闭', 'templates.back': '返回列表', 'templates.use': '使用此提示词', 'templates.copy': '复制提示词', 'templates.copied': '已复制', 'templates.refresh': '刷新本库', 'templates.refreshing': '刷新中…', 'templates.refreshed': '已刷新,共 {count} 个模板', 'templates.refreshFailed': '刷新失败:{error}', 'templates.favorites': '收藏', 'templates.favoritesCount': '共 {count} 个收藏', 'templates.favoritesHint': '只看已收藏的模板', 'templates.favoritesEmpty': '还没有收藏,点击模板卡片右上角的星标即可收藏', 'templates.favoriteAdd': '收藏此模板', 'templates.favoriteRemove': '取消收藏', 'templates.favorite': '收藏', 'templates.unfavorite': '已收藏', 'templates.cacheAll': '缓存全部图片', 'templates.cacheAllHint': '通过本机代理把当前模板库的全部参考图缓存到本地磁盘,之后离线也能浏览', 'templates.caching': '缓存中 {done}/{total}…', 'templates.cached': '图片已全部缓存', 'templates.empty': '没有匹配的模板', 'templates.loading': '正在加载模板库…', 'templates.loadFailed': '模板库加载失败:{error}', 'templates.retry': '重试', 'templates.attribution': '模板与图片来自各来源站点,作者链接见模板详情', 'templates.source': '来源:{label}', 'templates.featured': '精选', // inspiration wall (studio empty state) 'inspiration.title': '灵感案例', 'inspiration.shuffle': '随机', 'inspiration.shuffling': '换一批…', 'inspiration.useHint': '点击使用该提示词', // channel management 'channels.title': '渠道', 'channels.hint': '填写各渠道的 API 地址与密钥即可使用对应模型', 'channels.empty': '尚无渠道,点击下方按钮添加', 'channels.addProvider': '添加提供方', 'channels.addCustom': '添加自定义渠道', 'channels.untitled': '未命名渠道', 'channels.keySet': '密钥已设置', 'channels.keyMissing': '未设置密钥', 'channels.modelCount': '{n} 个模型', 'channels.noModels': '未配置模型', 'channels.defaultLabel': '默认', 'channels.statusReady': '可用', 'channels.statusIncomplete': '配置未完成', 'channels.edit': '编辑', 'channels.done': '完成', 'channels.delete': '删除', 'channels.deleteConfirmTitle': '删除渠道「{name}」?该渠道的密钥将被移除;历史与素材库中的记录仍会保留。', 'channels.confirm': '确认删除', 'channels.cancel': '取消', 'channels.editorTitle': '渠道', 'channels.editorSaveNote': '改动将随卡片底部「保存」一起生效', 'channels.displayName': '显示名称', 'channels.apiUrl': 'API 地址', 'channels.protocol': '接口协议', 'channels.protocolAuto': '自动检测', 'channels.protocolImages': 'Images API', 'channels.protocolChat': 'Chat Completions', 'channels.protocolHint': '自动:完整 URL 以 /chat/completions 结尾时使用 Chat 协议;也可以手动指定。', 'channels.apiUrlFull': '完整 URL', 'channels.apiUrlFullHint': '开启后精确请求此地址,不再拼接 /images/generations 或 /images/edits;Chat Completions 地址仍可从其上级路径自动检测 /models。', 'channels.apiKey': 'API 密钥', 'channels.keyReplaceHint': '已配置 — 输入新值可替换', 'channels.keyMissingHint': '填写密钥', 'channels.keyClear': '清除密钥', 'channels.showKey': '显示密钥', 'channels.hideKey': '隐藏密钥', 'channels.modelCatalogTitle': '模型目录', 'channels.noModelsHint': '暂无模型:点击「检测」拉取候选,或手动添加;别名(显示名)默认等于上游模型 id,可自行修改。', 'channels.detectFirst': '检测模型', 'channels.detect': '重新检测', 'channels.detecting': '检测中…', 'channels.detectSuccess': '连通 ✓ · {n} 个候选', 'channels.detectFailed': '检测失败:{error}', 'channels.detectOk': '已连接该 API', 'channels.modelAliasLabel': '显示名(别名)', 'channels.modelIdLabel': '上游模型 id', 'channels.generated': '已生成 {n} 次', 'channels.unknownProtocol': '未知协议,按通用 OpenAI 协议尝试', 'channels.removeModel': '移除模型', 'channels.manualAddPlaceholder': '输入模型 id,例如 qwen-image', 'channels.addModelConfirm': '添加', 'channels.copyFrom': '从其他渠道复制…', 'channels.copyApply': '复制', 'channels.candidatesTitle': '图片模型候选(点击加入)', 'channels.deleteThisChannel': '删除此渠道', 'channels.setDefault': '设为默认渠道', 'channels.defaultModel': '默认生图模型', 'channels.defaultModelHint': '普通生图、无限画布、电商和 Agent 未指定模型时优先使用它;侧栏生图入口始终保留。', 'channels.presetPickerTitle': '添加提供方', 'channels.presetPickerHint': '选择一个内置提供方,仅需填写 API 密钥', 'channels.presetTabApiKey': 'API Key', 'channels.presetTabSubscription': '订阅账号', 'channels.presetPickerApiKeyHint': '选择常规 API Key 渠道,需要填写端点与密钥。', 'channels.presetPickerSubscriptionHint': '登录账号后直接使用固定模型,无需单独填写 API Key。', 'channels.presetClickToLogin': '点击登录', 'channels.authMode': '认证方式', 'channels.authModeApiKey': 'API Key', 'channels.authModeSubscription': '官方订阅 / 实验性账号', 'channels.subscriptionProvider': '订阅账号', 'channels.presetSearch': '搜索提供方或模型', 'channels.presetEmpty': '没有匹配的提供方', 'channels.presetCustomHint': '自行填写 API 地址、密钥与模型目录', 'channels.presetLoadFailed': '加载提供方失败:{error}', 'canvas.skills.fileNode': '文件节点', 'canvas.skills.addFileNode': '添加文件节点', 'canvas.skills.emptyFileNode': '点击上传文件', 'canvas.skills.fileMenuUpload': '上传文件', 'canvas.skills.fileDropHint': '文件拖到此处即可上传', 'canvas.skills.fileDropSub': '支持 PDF / Office / 文本 / 图片等,≤50MB', 'canvas.skills.fileSizeUnknown': '大小未知', 'canvas.skills.filePreviewUnavailable': '此格式无法内联预览,请下载或用技能处理', 'canvas.skills.filePreviewLoading': '正在读取预览…', 'canvas.skills.fileDownload': '下载文件', 'canvas.skills.fileOpen': '用系统程序打开', 'canvas.skills.fileKind.text': '文本', 'canvas.skills.fileKind.pdf': 'PDF', 'canvas.skills.fileKind.image': '图片', 'canvas.skills.fileKind.office': '文档', 'canvas.skills.fileKind.archive': '压缩包', 'canvas.skills.fileKind.audio': '音频', 'canvas.skills.fileKind.video': '视频', 'canvas.skills.fileKind.other': '文件', 'canvas.skills.fileTooLarge': '文件超过 {size}MB 上限', 'canvas.skills.fileTypeBlocked': '出于安全考虑,不支持上传 {ext} 文件', 'canvas.skills.fileUploadFailed': '文件上传失败:{message}', 'canvas.preview.expand': '放大预览', 'canvas.preview.close': '关闭预览', 'canvas.preview.copy': '复制内容', 'canvas.preview.copied': '已复制', 'canvas.preview.openTab': '新标签页打开', 'canvas.preview.retry': '重试', 'canvas.preview.failed': '读取预览失败:{message}', 'canvas.preview.empty': '文件是空的', 'canvas.preview.textTruncated': '文件较大,仅显示前 {chars} 个字符', 'canvas.preview.tableTruncated': '表格较大,仅显示前 {rows} 行', 'canvas.preview.archiveTruncated': '压缩包条目较多,仅列出前 {count} 项', 'canvas.preview.docTruncated': '文档较长,仅显示前 {blocks} 段', 'canvas.preview.slidesTruncated': '幻灯片较多,仅显示前 {count} 页', 'canvas.preview.slideOf': '第 {page} 页', 'canvas.preview.rendered': '渲染', 'canvas.preview.source': '源码', 'canvas.preview.pdfFallback': '当前环境无法内联显示 PDF,请下载后查看', 'canvas.preview.pdfHeuristic': 'PDF 文字为启发式提取,复杂排版可能丢失顺序', 'canvas.preview.reason.unsupported': '这种格式没有可读内容,请下载后查看,或先转成图片 / 文本节点再交给技能处理', 'canvas.preview.reason.unreadable': '没能从这个文件里读出文字,可能是扫描件或特殊编码;可以转成图片节点交给视觉模型', 'canvas.preview.doubleClick': '双击放大预览', 'canvas.skills.button': '技能', 'canvas.skills.menuTitle': '运行技能', 'canvas.skills.runOn': '在「{name}」上运行技能', 'canvas.skills.pickerTitle': '选择技能', 'canvas.skills.searchPlaceholder': '搜索技能…', 'canvas.skills.groupBuiltin': '内置动作', 'canvas.skills.groupExternal': '本机技能', 'canvas.skills.emptyExternal': '本机没有可用技能,可在 ~/.dsh/skills 安装后重试', 'canvas.skills.empty': '没有可用技能', 'canvas.skills.loading': '正在读取技能列表…', 'canvas.skills.tierLight': '轻量', 'canvas.skills.tierHeavy': '重任务', 'canvas.skills.accepts': '可用节点:{types}', 'canvas.skills.incompatible': '该技能不适用于此节点类型', 'canvas.skills.disabled': '画布技能已在设置中关闭', 'canvas.skills.noRegistry': '本宿主未挂载技能注册表(ctx.skills),只能使用内置动作', 'canvas.skills.registryFailed': '读取技能列表失败:{message}', 'canvas.skills.needAgent': '需要宿主 Agent 运行层(本机 DSH 未提供),重任务技能不可用', 'canvas.skills.unknown': '技能不存在或已被移除', 'canvas.skills.canvasMissing': '画布不存在,请刷新后重试', 'canvas.skills.noInput': '这个节点没有可处理的输入', 'canvas.skills.noChat': '轻量技能需要先在「设置 → 生图配置」的「提示词增强」中配置聊天模型', 'canvas.skills.noDescription': '(技能未提供描述)', 'canvas.skills.externalName': '{name}', 'canvas.skills.externalSystem': '你在执行名为「{name}」的技能。严格按技能说明处理用户提供的输入,只用用户语言回答,直接输出处理结果,不要复述技能说明。', 'canvas.skills.externalHeader': '请按技能「{name}」的说明处理下面的输入。', 'canvas.skills.externalHeavyCost': '该技能属于长任务,会启动无头 Agent 执行,可能长时间占用模型额度。', 'canvas.skills.extraInstruction': '额外要求:', 'canvas.skills.inputsHeader': '输入内容:', 'canvas.skills.inputsEmpty': '(没有可读取的文本内容,请依据附带的图片处理)', 'canvas.skills.needInstruction': '请填写自定义润色指令', 'canvas.skills.needImage': '该技能需要图片节点作为输入', 'canvas.skills.needText': '该技能需要带文字的文本节点作为输入', 'canvas.skills.fileMissing': '文件资产不存在或已被清理', 'canvas.skills.extractFailed': '无法抽取该文件的内容', 'canvas.skills.nothingToRead': '没有可读取的文本内容', 'canvas.skills.truncated': '内容较长,已截断到 {count} 字符', 'canvas.skills.tooManyImages': '图片数量超过 {count} 张,只处理了前面的图片', 'canvas.skills.extractNodeTitle': '「{name}」内容', 'canvas.skills.summaryHead': '已汇总 {count} 个来源节点:', 'canvas.skills.describeAsk': '请描述这 {count} 张图片。', 'canvas.skills.polishNodeTitle': '润色结果({style})', 'canvas.skills.skillMissing': '本机未安装「{name}」技能。请先安装该技能(例如让 DSH Agent 安装 https://github.com/ningzimu/image-to-editable-ppt-skill ),再重试。', 'canvas.skills.agentFailed': '无法创建无头 Agent(请检查模型与 Agent 预设配置)', 'canvas.skills.needModel': '宿主没有提供默认模型(agent-default-model),重任务技能无法启动 Agent。请先在「设置 → 通用」选择默认模型,再重试。', 'canvas.skills.noOutputFile': '技能没有产出文件,已把 Agent 的回复保存为文本节点', 'canvas.skills.heavyIntro': '你正在为一个可视化画布执行技能「{name}」。严格按技能说明完成整个流程,不要省略步骤。', 'canvas.skills.heavyBodyHeader': '技能说明:', 'canvas.skills.heavyInputsHeader': '本任务的输入文件(绝对路径):', 'canvas.skills.heavyOutputHeader': '把最终产物写入这个目录:{dir}', 'canvas.skills.heavyRules': '要求:\n1. 全部中间文件放在当前工作目录,最终产物只能放在上面的输出目录。\n2. 完成后用简短中文回复:产物文件名、是否成功、注意事项。', 'canvas.skills.heavyAsk': '请执行技能「{name}」。', 'canvas.skills.heavyAskInputs': '输入文件目录:{dir}', 'canvas.skills.heavyAskOutput': '输出目录:{dir}', 'canvas.skills.heavyAskLoadSkill': '(如果技能说明不在上下文里,请先用技能名「{name}」加载它)', 'canvas.skills.stageQueued': '排队中', 'canvas.skills.stagePreparing': '准备输入文件', 'canvas.skills.stageReading': '读取节点内容', 'canvas.skills.stageRunning': '技能执行中', 'canvas.skills.stageCollecting': '收集产物', 'canvas.skills.stageDone': '完成', 'canvas.skills.stageCancelled': '已取消', 'canvas.skills.stagePrepared': '已备好 {count} 个输入文件', 'canvas.skills.stageArtifacts': '技能执行中 · 已产出 {count} 个文件', 'canvas.skills.runElapsed': '已用时', 'canvas.skills.runRetry': '重试', 'canvas.skills.runStarted': '技能「{name}」已开始', 'canvas.skills.runDone': '技能完成,新增 {count} 个节点', 'canvas.skills.runFailed': '技能运行失败:{message}', 'canvas.skills.runCancelled': '技能运行已取消', 'canvas.skills.cancel': '取消运行', 'canvas.skills.cancelling': '正在取消…', 'canvas.skills.confirmTitle': '运行重任务技能', 'canvas.skills.confirmBody': '技能「{name}」会启动一个无头 Agent 在本机执行,可能持续数分钟到数十分钟,并消耗较多模型额度。', 'canvas.skills.confirmCost': '成本提示:{hint}', 'canvas.skills.confirmRequires': '前置条件:{list}', 'canvas.skills.confirmRun': '确认运行', 'canvas.skills.confirmCancel': '先不运行', 'canvas.skills.batchTitle': '批量运行', 'canvas.skills.batchNote': '将依次在 {count} 个节点上运行(串行执行)', 'canvas.skills.batchTooMany': '一次最多处理 {count} 个节点', 'canvas.skills.sourceBadge': '技能产出', 'canvas.skills.sourceTip': '由技能「{name}」产出,来自 {count} 个来源节点', 'canvas.skills.rerun': '用同一技能再跑一次', 'canvas.skills.history': '技能运行记录', 'canvas.skills.historyEmpty': '暂无运行记录', 'canvas.skills.needConfirm': '该技能需要确认后才能运行', 'canvas.skills.polish': '文本润色', 'canvas.skills.polishDesc': '按风格改写文本节点:更正式 / 更口语 / 更短 / 扩写,或自定义指令', 'canvas.skills.describe': '图片描述', 'canvas.skills.describeDesc': '用视觉模型读出图片内容,产出文本节点(可用作提示词)', 'canvas.skills.extract': '内容抽取', 'canvas.skills.extractDesc': '把文件或图片里的文字抽成文本节点(文本 / 代码 / OOXML 文档 / PDF)', 'canvas.skills.ppt': '图片转可编辑 PPT', 'canvas.skills.pptDesc': '调用本机 image-to-editable-ppt 技能,把图片重建为可编辑 .pptx 文件节点', 'canvas.skills.pptCost': '长任务:10 页 PPT 可能消耗较多额度,单页通常 10 分钟以上', 'canvas.skills.pptRequires': '需要本机已安装 image-to-editable-ppt 技能,并按其文档配置 OCR Token 与图片后端', 'canvas.polish.button': 'AI 润色', 'canvas.polish.title': 'AI 润色', 'canvas.polish.formal': '更正式', 'canvas.polish.casual': '更口语', 'canvas.polish.shorter': '更短', 'canvas.polish.expand': '扩写', 'canvas.polish.custom': '自定义', 'canvas.polish.customPlaceholder': '例如:改写成小红书文案,带 emoji 和话题标签', 'canvas.polish.run': '开始润色', 'canvas.polish.previewTitle': '原 / 新对比', 'canvas.polish.apply': '应用', 'canvas.polish.revert': '还原', 'canvas.polish.applied': '已应用润色结果', 'canvas.polish.directHint': '当前设置:润色后直接覆盖原文(可在设置中改为先预览)', 'settings.skillsEnabled': '画布技能', 'settings.skillsEnabledHint': '在无限画布节点的「技能」菜单里启用技能系统(内置动作 + 本机技能)', 'settings.allowHeavySkills': '允许重任务技能', 'settings.allowHeavySkillsHint': '重任务技能会启动无头 DSH Agent 在本机执行,耗时且消耗模型额度;关闭后只能使用轻量技能', 'settings.skillAllowlist': '技能白名单', 'settings.skillAllowlistHint': '逗号或换行分隔的技能名;留空表示允许本机所有技能', 'settings.skillOutputDir': '重任务工作目录', 'settings.skillOutputDirHint': '无头 Agent 的工作目录(留空使用数据目录下的 canvas/runs)', 'settings.skillHeavyTimeout': '重任务超时(分钟)', 'settings.skillHeavyTimeoutHint': '超过该时长会自动取消重任务技能;填 0 表示不超时', 'settings.skillAgentPreset': '重任务 Agent 预设', 'settings.skillAgentPresetHint': '运行重任务技能时使用的 Agent 预设名;留空使用宿主默认预设', 'settings.skillProbe': '检测技能环境', 'settings.skillProbing': '检测中…', 'settings.skillProbeOk': '可用技能 {count} 个 · 无头 Agent:{agent}', 'settings.skillProbeAgentOn': '可用', 'settings.skillProbeAgentOff': '不可用', 'settings.skillsHint': '提示:把 image-to-editable-ppt 之类的技能装到 ~/.dsh/skills 后,即可在画布上把图片变成可编辑 PPT。', 'canvas.skills.libraryButton': '技能库', 'canvas.skills.libraryTitle': '技能库管理', 'canvas.skills.libraryInstalled': '已安装技能({count})', 'canvas.skills.libraryEmpty': '本机还没有安装任何技能。可以从仓库链接安装,或上传技能压缩包。', 'canvas.skills.libraryRoot': '安装目录:{root}', 'canvas.skills.libraryInstall': '在线安装', 'canvas.skills.libraryInstallHint': '支持 GitHub 仓库 / 目录 / 单个 SKILL.md、任意 git 地址、zip 压缩包地址;多个地址用换行分隔。安装后宿主动态加载,无需重启。', 'canvas.skills.libraryUrlPlaceholder': 'https://github.com/owner/repo 或 …/blob/main/SKILL.md', 'canvas.skills.libraryUpload': '上传压缩包', 'canvas.skills.libraryUploadHint': '上传一个包含 SKILL.md 的 zip(单文件 ≤50MB),解压后安装到 ~/.dsh/skills。', 'canvas.skills.libraryDropzone': '点击选择或拖入 .zip 压缩包', 'canvas.skills.libraryForce': '覆盖已安装的同名技能', 'canvas.skills.libraryInstallAction': '安装', 'canvas.skills.libraryInstalling': '安装中…', 'canvas.skills.libraryRemove': '卸载', 'canvas.skills.libraryRemoving': '卸载中…', 'canvas.skills.libraryRemoveConfirm': '确定卸载技能「{name}」?该技能目录会被删除。', 'canvas.skills.libraryInstalledToast': '已安装技能:{names}', 'canvas.skills.libraryFailedToast': '安装失败:{message}', 'canvas.skills.libraryRemovedToast': '已卸载技能:{name}', 'canvas.skills.libraryUnavailable': '本宿主不支持管理技能库', 'canvas.skills.libraryReload': '刷新', 'canvas.skills.libraryOpenFolder': '打开技能目录', 'canvas.skills.installNow': '去安装', 'canvas.skills.needsInstall': '未安装', 'canvas.skills.missingHint': '技能「{name}」还没安装,点击安装即可使用', 'canvas.skills.installArchiveFailed': '压缩包安装失败:{message}', 'canvas.skills.libraryIssueFrontmatter': 'SKILL.md 缺少 YAML frontmatter(name / description 必填),本机技能注册表不会加载它,节点里也用不了', 'canvas.skills.libraryIssueName': 'frontmatter 的 name「{name}」不是 kebab-case(只能小写字母、数字和连字符),本机技能注册表会忽略它,节点里也用不了', 'canvas.skills.libraryIssueDescription': 'SKILL.md 的 frontmatter 缺少 description(必填),本机技能注册表不会加载它,节点里也用不了', 'canvas.skills.libraryIssueInvocation': 'disable-model-invocation / user-invocable 的写法无法解析,本机技能注册表会忽略它,节点里也用不了', 'canvas.skills.libraryIssueUserOnly': '该技能声明了 disable-model-invocation,只允许人工调用,画布节点无法运行它', // Skill configuration (declared in skill.config.json, see docs/skill-config.md) 'canvas.skills.configOpen': '配置', 'canvas.skills.configSave': '保存', 'canvas.skills.configSaveApply': '保存并应用', 'canvas.skills.configSaving': '保存中…', 'canvas.skills.configApplying': '应用中…', 'canvas.skills.configSaved': '已保存', 'canvas.skills.configSaveFailed': '保存失败', 'canvas.skills.configApplied': '已保存并应用', 'canvas.skills.configApplyFailed': '应用失败', 'canvas.skills.configClear': '清除', 'canvas.skills.configSecretSet': '已设置(留空表示不改动)', 'canvas.skills.configSecretUnset': '未设置', 'canvas.skills.configMissingHint': '需要配置:{fields}', 'canvas.skills.configGo': '去配置', 'canvas.skills.configSourceSkill': '配置项由该技能自己的 skill.config.json 声明', 'canvas.skills.configSourcePlugin': '配置项来自本插件内置的已知技能配方(技能自带声明会优先)', 'canvas.skills.configHeader': '已配置的值:', 'canvas.skills.configUnwritable': '本宿主无法写入设置,技能配置暂不可用', 'canvas.skills.configIssueVersion': 'skill.config.json 的 version 不是 1,已忽略这份声明', 'canvas.skills.configIssueUnreadable': 'skill.config.json 无法解析(JSON 语法错误),已忽略这份声明', 'canvas.skills.configIssueEmpty': 'skill.config.json 里没有可用的字段或步骤,已忽略这份声明', } as const export const en: Record = { "ppt.activityPreparing": "Preparing input images", "ppt.activityTextHints": "Processing page text hints", "ppt.activityAssets": "Rebuilding page image assets", "ppt.activityBuilding": "Building slides", "ppt.activityValidating": "Validating slides", "ppt.activityFinalizing": "Assembling and validating final PPT", "ppt.progressTitle": "Conversion progress", "ppt.lastActivity": "Last activity: {seconds}s ago", "ppt.idleNote": "No new execution events. A model request or external tool may still be running; this does not mean the task has stopped. Open diagnostics for recorded steps.", "ppt.pageProgress": "Validated {done} / {total} slides", "ppt.progressPage": "Slide {page}", "ppt.pageState.pending": "Pending", "ppt.pageState.running": "Rebuilding", "ppt.pageState.validated": "Validated", "ppt.activityHistory": "Execution history", "ppt.waitingActivity": "Waiting for execution events. Page progress appears after upstream creates page records.", "ppt.activityModel": "Model request in progress", "ppt.activityUnknownTool": "tool", "ppt.activityTool": "Running tool: {name}", "ppt.activityToolDone": "Tool completed: {name}", "ppt.activityToolFailed": "Tool returned an error; awaiting agent handling: {name}", "ppt.activityModelDone": "Model response received", "ppt.activityPages": "Page records updated: {done} / {total} validated", "ppt.activityPrepared": "Upstream input images prepared", "ppt.activityDispatched": "Upstream page jobs dispatched", "ppt.activityRecorded": "Upstream page results recorded; awaiting assembly", "ppt.activityBuilt": "Final PPT built; awaiting validation", "ppt.activityValidated": "Upstream final PPT validation passed", "ppt.activityUpstreamDone": "Upstream finished; collecting final PPT", "ppt.activityAgent": "Creating skill agent", "ppt.activityFailed": "Conversion failed; see task error and diagnostics", "ppt.persistenceWarning": "Task history could not be saved. The current conversion status and result remain valid; history may be incomplete after restarting. Error: {error}", "ppt.diagnostic": "Task diagnostics", "ppt.diagnosticHint": "Use the task, agent session and directory to locate the DSH execution logs. Click the text area to select all.", "ppt.legacyDiagnostic": "This older task did not retain its agent session or original error. Its root cause cannot be recovered from this generic message. Provide DSH logs around the task time. Click to copy the task details.", "ppt.pages": "{count} slides", "ppt.downloadDeck": "Download PPTX", "ppt.expand": "Expand preview", "ppt.pageNavigation": "Slide navigation", "ppt.goToPage": "Go to slide {page}", "ppt.previousPage": "Previous slide", "ppt.nextPage": "Next slide", "ppt.contentPreview": "Content preview · Check complex layouts in PowerPoint", "ppt.fitWindow": "Fit to window", "ppt.previewDeck": "Preview PPT", "ppt.previewHint": "Content preview shows slide text and embedded pictures. Check complex layouts in PowerPoint after downloading.", "ppt.agentFailed": "Conversion execution failed: {error}", "ppt.noAgentReply": "The agent returned no reply or artifact. Check the DSH default model connection/quota and the preset file and command tools.", "ppt.close": "Close", "ppt.sources": "Slide images", "ppt.previewSource": "Preview source", "ppt.addImages": "Add images", "ppt.orderHint": "Slide order follows the thumbnails. Click to preview.", "ppt.history": "Conversion history", "ppt.retry": "Retry conversion", "ppt.checkSetup": "Check settings", "ppt.settingsTitle": "Image to PPT settings", "ppt.updateSkill": "Update upstream skill", "ppt.reuseImages": "Use these images again", "ppt.nav": "Image to PPT", "ppt.title": "Image to editable PPT", "ppt.description": "Rebuild text, shapes and layout from existing images into editable PowerPoint.", "ppt.action": "Create editable PPT", "ppt.upload": "Upload slide images", "ppt.uploading": "Uploading…", "ppt.uploadHint": "Drop PNG / JPG / WebP, up to 12 images, 20 MB each", "ppt.inputLimit": "Choose 1–12 images, one image per slide.", "ppt.invalidImage": "Use a valid PNG / JPG / WebP image up to 20 MB.", "ppt.moveUp": "Move slide up", "ppt.moveDown": "Move slide down", "ppt.ocrTitle": "Text recognition", "ppt.ocrPaddle": "Use configured PaddleOCR", "ppt.ocrOffline": "Use offline text detection for this run", "ppt.ocrHint": "PaddleOCR improves text and font-size recovery. Offline hints measure geometry; the model reconstructs the text.", "ppt.processingHint": "Conversion may take several minutes and uses the host model and configured image / OCR services. Complex slides may take longer.", "ppt.setupRequired": "Install the skill and runtime in image settings, and enable skills and long-running tasks.", "ppt.convert": "Create editable PPT", "ppt.submitting": "Submitting…", "ppt.openSettings": "PPT settings", "ppt.results": "Conversions", "ppt.resultCount": "{count} tasks", "ppt.empty": "Turn images into slides you can edit", "ppt.emptyHint": "Upload images or choose “Create editable PPT” from an image result. Image order becomes slide order.", "ppt.cancel": "Cancel conversion", "ppt.working": "Running the skill…", "ppt.interrupted": "The host restarted and interrupted this conversion. Source images are retained; submit again.", "ppt.invalidDeck": "The output is not a valid PPTX, or its slide count does not match the input.", "ppt.noDeck": "The skill did not output a final PPTX. Check the runtime and configuration.", "ppt.setupHint": "Uses the upstream skill and editppt workflow directly.", "ppt.installSkill": "Install upstream skill", "ppt.installed": "Skill installed", "ppt.installRuntime": "Install / repair runtime", "ppt.checkRuntime": "Check runtime", "ppt.runtimeReady": "editppt is ready", "ppt.runtimeMissing": "editppt needs attention", "ppt.runtimeHint": "Requires Python 3.10+. Installation puts the upstream CLI and dependencies in an isolated plugin environment and needs network access.", "ppt.configured": "Configured", "ppt.secretUnchanged": "Saved; leave blank to keep", "ppt.paddleLink": "Get a PaddleOCR token", "ppt.saveConfig": "Save and apply PPT settings", "ppt.configSaved": "PPT settings saved and applied.", "ppt.setupWorking": "Working… dependency installation may take a few minutes.", "poster.title": "Poster editor: text / logo", "poster.hint": "Add editable overlays and drag to position. No model credits used.", "poster.sampleText": "Your headline here", "poster.addText": "Add text", "poster.addLogo": "Upload logo", "poster.undo": "Undo", "poster.redo": "Redo", "poster.logoLimit": "Use a PNG / JPG / WebP up to 10 MB and 40 megapixels.", "poster.logoFailed": "Could not read logo image", "poster.exportFailed": "Export failed. Please retry.", "poster.preview": "Poster preview", "poster.logo": "Logo layer", "poster.loading": "Loading images…", "poster.layers": "Layers (top is front)", "poster.backgroundFixed": "The background stays intact. Transparent PNG logos work best.", "poster.text": "Text", "poster.font": "Font", "poster.sans": "Sans serif", "poster.serif": "Serif", "poster.mono": "Monospace", "poster.fontSize": "Font size (px)", "poster.color": "Text color", "poster.bold": "Bold", "poster.align": "Alignment", "poster.left": "Left", "poster.center": "Center", "poster.right": "Right", "poster.width": "Width (px)", "poster.front": "Bring to front", "poster.back": "Send to back", "poster.delete": "Delete layer", "poster.selectHint": "Add text or upload a logo, then select a layer to edit.", "poster.discardHint": "Changes have not been saved.", "poster.discard": "Discard changes", "poster.keepEditing": "Keep editing", "poster.saveHint": "Save a new image node to keep editing later. PNG export does not save the recipe.", "poster.export": "Export PNG", "poster.save": "Save to canvas", "poster.working": "Working…", "poster.sourceChanged": "The source canvas or image changed. Reopen the editor.", "poster.resultTitle": "Editable poster", "poster.saved": "Poster added. Reopen to edit; wait for the canvas save to finish.", 'entry.label': 'AI Image', 'entry.tooltip': 'AI image generation studio (gpt-image-2 / glm-image / grok-imagine-image / nanobanana / seedream family)', 'entry.session': 'Session', 'entry.sessionTooltip': 'Back to the current conversation', 'entry.image': 'Image', 'entry.settings': 'Image settings', 'panel.title': 'VisioWork', 'panel.githubTip': 'Like it or have suggestions? Head to GitHub to open issues and star us!', 'conversation.add': 'Add to chat', 'conversation.adding': 'Adding…', 'conversation.added': 'Image added to the current chat', 'conversation.addHint': 'After adding to chat, use /edit_image to modify it; the command uses the plugin image model', 'conversation.noSession': 'Open a session before adding an image', 'conversation.unavailable': 'The current session is unavailable', 'conversation.busy': 'The chat is sending a message; try again shortly', 'conversation.chooseSession': 'Choose a conversation', 'conversation.chooseSessionHint': 'The current conversation is unavailable. Choose where to add the image.', 'conversation.targetSession': 'Target conversation', 'conversation.selectSession': 'Select a conversation', 'conversation.confirmAdd': 'Add to selected conversation', 'conversation.cancel': 'Cancel', 'mode.text': 'Text to Image', 'mode.edit': 'Image to Image', 'workspace.label': 'Workspace', 'workspace.normal': 'Standard', 'workspace.canvas': 'Infinite canvas', 'workspace.ecommerce': 'E-commerce', 'canvas.addImage': 'Add image', 'canvas.addText': 'Add text', 'canvas.generate': 'Generate image', 'canvas.addToCanvas': 'Add to canvas', 'canvas.untitled': 'Untitled canvas', 'canvas.imageNode': 'Image node', 'canvas.textNode': 'Text node', 'canvas.fromGallery': 'Gallery image', 'canvas.fromHistory': 'History image', 'canvas.project': 'Canvas project', 'canvas.favoriteCanvas': 'Favorite canvas', 'canvas.unfavoriteCanvas': 'Remove from favorites', 'canvas.favoriteProjects': 'Favorites ({count})', 'canvas.allProjects': 'Other canvases ({count})', 'canvas.newCanvas': 'New canvas', 'canvas.deleteCanvas': 'Delete canvas', 'canvas.deleteCanvasConfirm': 'Click again to confirm', 'canvas.rename': 'Rename canvas', 'canvas.renameHint': 'Double-click to rename', 'canvas.background': 'Canvas background', 'canvas.backgroundDots': 'Dots', 'canvas.backgroundLines': 'Grid lines', 'canvas.backgroundWaves': 'Waves', 'canvas.backgroundShapeGrid': 'Scrolling grid', 'canvas.backgroundDotField': 'Dot field', 'canvas.backgroundDotGrid': 'Interactive dots', 'canvas.backgroundFloatingLines': 'Floating lines', 'canvas.backgroundFlow': 'Fluid flow', 'canvas.backgroundLiquid': 'Liquid ether', 'canvas.backgroundFaultyTerminal': 'Faulty terminal', 'canvas.backgroundSilk': 'Silk', 'canvas.backgroundGalaxy': 'Galaxy', 'canvas.backgroundBlank': 'Disable background (performance)', 'canvas.backgroundUpload': 'Upload custom background…', 'canvas.backgroundRemove': 'Remove custom background', 'canvas.templateLibrary': 'Template library (pick a prompt to create text + config nodes)', 'canvas.undo': 'Undo (Ctrl+Z)', 'canvas.redo': 'Redo (Ctrl+Shift+Z)', 'canvas.saving': 'Saving…', 'canvas.saved': 'Saved', 'canvas.saveFailed': 'Save failed', 'canvas.loading': 'Loading…', 'canvas.toolSelect': 'Select / move nodes', 'canvas.toolPan': 'Pan canvas (Space / Ctrl + drag)', 'canvas.delete': 'Delete', 'canvas.duplicate': 'Duplicate (Ctrl+D)', 'canvas.download': 'Download image', 'canvas.fitView': 'Fit all content', 'canvas.minimapOpen': 'Open minimap', 'canvas.minimapClose': 'Close minimap', 'canvas.minimap': 'Canvas minimap', 'canvas.zoom': 'Zoom', 'canvas.textPlaceholder': 'Type text…', 'canvas.generatingNode': 'Generating…', 'canvas.generateFailed': 'Generation failed', 'canvas.retry': 'Retry', 'canvas.taskLost': 'Generation task lost (service restarted); please retry', 'canvas.emptyImageNode': 'Click to upload an image', 'canvas.connectHint': 'Drag onto another node to connect', 'canvas.connectAddHint': 'Drag onto another node to connect, or click to add the next node', 'canvas.resizeHint': 'Drag to resize (image ratio locked)', 'canvas.count': 'Image count', 'canvas.configNode': 'Generation config', 'canvas.addConfigNode': 'Add config node', 'canvas.configHint': 'Connect image nodes on the left as references and text nodes as prompts; select this node to write the prompt in the composer below and generate.', 'canvas.composerLinked': '{count} input node(s) connected', 'canvas.composerPlaceholder': 'Describe the image to generate; or connect text nodes as the prompt…', 'canvas.countUnit': '{count}', 'canvas.model': 'Image model', 'canvas.modelPlaceholder': 'Choose a model', 'canvas.size': 'Size ratio', 'canvas.sizeAuto': 'Auto ratio', 'canvas.quality': 'Quality', 'canvas.qualityAuto': 'Auto quality', 'canvas.needApi': 'Configure the image API first', 'canvas.needPrompt': 'Enter a generation prompt first', 'canvas.needModel': 'No image model available', 'canvas.openSettings': 'Open settings', 'canvas.deleteConnection': 'Delete connection', 'canvas.paste': 'Paste (Ctrl+V)', 'canvas.addImageNode': 'Add image node', 'canvas.addTextNode': 'Add text node', 'canvas.addSketch': 'Add sketch board (draw-to-generate)', 'canvas.sketchNode': 'Sketch board', 'canvas.addSketchNode': 'Add sketch board node', 'canvas.sketchPlaceholder': 'Draw a sketch freely, then connect it to a config node as the reference image', 'canvas.sketchBrush': 'Brush', 'canvas.sketchEraser': 'Eraser', 'canvas.sketchUndo': 'Undo last stroke', 'canvas.sketchClear': 'Clear board', 'canvas.sketchWidth': 'Stroke width', 'canvas.dismiss': 'Dismiss', 'canvas.annotate': 'Annotate: draw a box to attach a prompt card', 'canvas.annotationNode': 'Annotation prompt', 'canvas.annotationTag': 'Annotated', 'canvas.annotationPlaceholder': 'Describe what this box should become, e.g. replace it with an orange cat', 'canvas.annotationDrawHint': 'Drag on the image to draw a box; releasing attaches a prompt card that follows the image (no connection needed)', 'canvas.removeBackground': 'Remove background (local matting, transparent PNG)', 'canvas.removingBackground': 'Removing background…', 'canvas.removeBgDone': 'Background removed ({percent}% transparent)', 'canvas.removeBgFailed': 'The background is too complex for local matting; box the subject with 标注 and let the model redraw it', 'canvas.alreadyTransparent': 'This image already has a transparent background', 'canvas.noBackgroundNode': 'Cut-out image', 'canvas.splitLayers': 'Split layers (AI decomposition into editable layers)', 'canvas.splittingLayers': 'Splitting layers…', 'canvas.layerSplitDone': 'Split into {count} layer node(s)', 'canvas.layerSplitEmpty': 'The model found no layers to split', 'canvas.layerBackground': 'Background · {label}', 'canvas.layerObject': 'Layer · {label}', 'canvas.layerText': 'Text · {label}', 'canvas.layerKindBackground': 'Background', 'canvas.layerKindObject': 'Object', 'canvas.layerKindText': 'Text', 'canvas.nodeModel': 'Model used by this node (retry and connected config nodes)', 'canvas.modelDefault': 'Default model', 'canvas.fontSmaller': 'Smaller font', 'canvas.fontLarger': 'Larger font', 'canvas.bold': 'Bold', 'canvas.textColor': 'Text color', 'canvas.colorDefault': 'Theme default', 'canvas.close': 'Close', 'canvas.tabUpload': 'Upload', 'canvas.tabHistory': 'History', 'canvas.tabGallery': 'Assets', 'canvas.imageMenuUpload': 'Local image', 'canvas.imageMenuAssets': 'Assets', 'canvas.imageMenuHistory': 'History', 'canvas.imageMenuGenerate': 'AI generate', 'canvas.tabGenerate': 'AI generate', 'canvas.dropHint': 'Drop images here to add them', 'canvas.dropSub': 'Multiple files, PNG / JPG / WebP / GIF', 'canvas.untitledWork': 'Untitled work', 'canvas.picked': '{count} selected', 'canvas.generateAndAdd': 'Generate and add to canvas', 'chat.expand': 'Expand the conversation pane', 'chat.collapse': 'Collapse the conversation pane', 'chat.toggle': 'Chat', 'config.resizeHint': 'Drag to resize the parameter panel', 'ecommerce.generation': 'Generation settings', 'ecommerce.title': 'E-commerce Mode', 'ecommerce.badge': 'Beta', 'ecommerce.short': 'Store', 'ecommerce.anchorPending': 'Main image generated — remaining images are being generated with the main image as reference to keep the set consistent…', 'ecommerce.anchorFailed': 'Main image failed; remaining images are paused. Retry the main image or regenerate the set.', 'ecommerce.anchorNote': 'Anchored: main image first, remaining images reference it automatically for a consistent set', 'ecommerce.noAssetWarn': 'No product image uploaded: the main image will be generated from text as the anchor. Upload one for higher consistency.', 'ecommerce.product': 'Product details', 'ecommerce.productName': 'Product name (required)', 'ecommerce.projectName': 'Project name (optional)', 'ecommerce.constraints': 'Selling points & constraints', 'ecommerce.sellingPoints': 'Reference info: brand & model, specs (capacity/size/weight), materials, key selling points, certifications, accessories…', 'ecommerce.protectedFeatures': 'Features to preserve: color, logo, packaging text, structure', 'ecommerce.styleHint': 'Style hint, e.g. premium / realistic / natural light', 'ecommerce.setStructure': 'Image set structure', 'ecommerce.preview': 'Preview product set', 'ecommerce.planTitle': 'Plan to generate {count} images', 'ecommerce.planSlot': '{count} images · {description}', 'ecommerce.confirm': 'Confirm and generate set', 'ecommerce.uploadRef': 'Upload product images (required, up to 4: product / packaging / detail)', 'ecommerce.uploadShort': 'Upload', 'ecommerce.sellingTitle': 'Selling points', 'ecommerce.advanced': 'Advanced (platform / constraints)', 'ecommerce.params': 'Parameters', 'ecommerce.platformLabel': 'Platform', 'ecommerce.languageLabel': 'Copy language', 'ecommerce.customLanguageOption': 'Custom…', 'ecommerce.customLanguageLabel': 'Custom language', 'ecommerce.customLanguagePlaceholder': 'Enter a language, e.g. Русский / 日本語 / Português', 'ecommerce.ratioLabel': 'Aspect ratio', 'ecommerce.categoryLabel': 'Category', 'ecommerce.multiSelect': 'multi-select', 'ecommerce.countHint': 'Click to adjust count (1-4)', 'ecommerce.refSettings': 'Reference images (optional)', 'ecommerce.styleTitle': 'Style / extra hints', 'ecommerce.protectedLabel': 'Features to preserve (optional)', 'ecommerce.assetsFull': 'Up to 4 product images', 'ecommerce.productRefTitle': 'Product images', 'ecommerce.productRefHint': 'Required · product shots, up to 4', 'ecommerce.styleRefTitle': 'Style reference', 'ecommerce.styleRefBadge': 'optional, 1 max', 'ecommerce.styleRefHint': 'Style, lighting, composition and mood only — the product itself cannot change.', 'ecommerce.styleRefUpload': 'Upload style reference', 'ecommerce.refInfoTitle': 'Product info', 'ecommerce.aiWrite': 'AI write', 'ecommerce.aiWriting': 'AI drafting…', 'ecommerce.aiWriteHint': 'Draft the product info prompt from name and category', 'ecommerce.promptInfoPlaceholder': 'Optional: brand & model, specs, materials, selling points, certifications, accessories, framing… or use AI write', 'ecommerce.optional': 'optional', 'ecommerce.previewBoardTitle': 'Pre-generation review', 'ecommerce.previewBoardHint': "Tweak each image's prompt before submitting", 'ecommerce.promptReset': 'Reset', 'ecommerce.promptAutoHint': 'Auto-generated · edit freely', 'ecommerce.promptPolish': 'AI polish', 'ecommerce.promptPolishing': 'Polishing…', 'ecommerce.refSelect': 'Reference image for this slot', 'ecommerce.refNone': 'No reference', 'ecommerce.role.product': 'Product', 'ecommerce.role.packaging': 'Packaging', 'ecommerce.role.detail': 'Detail / angle', 'ecommerce.role.style': 'Style', 'ecommerce.footerReady': '{count} images in this set', 'ecommerce.footerEmpty': 'Select the image set structure', 'ecommerce.results.title': 'Product set results', 'ecommerce.results.progress': '{done}/{total} completed', 'ecommerce.results.failed': '{count} failed', 'ecommerce.results.empty': 'After confirming, each image task and result will show here grouped by purpose', 'ecommerce.results.regenerate': 'Regenerate', 'ecommerce.results.export': 'Export manifest', 'ecommerce.results.newProduct': 'New product', 'prompt.placeholder': 'Describe the picture you want, e.g. an orange cat in an astronaut helmet raising a telescope on the moon, watercolor style, soft light…', 'prompt.required': 'Enter a prompt first', 'prompt.count': '{count}', 'prompt.countLimit': '{count} / {limit}', 'prompt.overLimit': 'Over this model\u2019s {limit}-character prompt limit; please shorten it', 'prompt.enhance': 'Enhance', 'prompt.enhancing': 'Enhancing…', 'prompt.enhanceHint': 'Expand the prompt with the configured chat model', 'prompt.configTitle': 'Configure a prompt enhancement model first', 'prompt.configHint': 'Settings → Image settings has opened. Enter or reuse an API URL and key, choose a chat model, then save.', 'tasks.title': 'Generation tasks', 'tasks.queued': 'Queued', 'tasks.running': 'Generating', 'tasks.completed': 'Completed', 'tasks.failed': 'Failed', 'tasks.cancelled': 'Cancelled', 'tasks.cancel': 'Cancel', 'tasks.retry': 'Retry', // diagnostics (#38): the retained record of upstream attempts 'diagnostics.title': 'Diagnostics', 'diagnostics.open': 'Diagnostics', 'diagnostics.count': '{count} entr(y/ies)', 'diagnostics.refresh': 'Refresh', 'diagnostics.loading': 'Loading…', 'diagnostics.copy': 'Copy all', 'diagnostics.copied': 'Copied', 'diagnostics.clear': 'Clear', 'diagnostics.empty': 'No entries yet. After a failed generation this records the request URL, HTTP status, network error code and upstream response.', 'diagnostics.hint': 'Kept in host memory only. Secrets are redacted, so the copy is safe to paste into an issue.', 'diagnostics.response': 'Upstream response', 'diagnostics.requestLabel': 'Request', 'diagnostics.exactUrl': 'exact URL', 'params.size': 'Size', 'params.quality': 'Quality', 'params.count': 'Count', 'params.detail': 'Detail', 'size.auto': 'Auto', 'size.square': '1:1 Square', 'size.portrait34': '3:4 Portrait', 'size.landscape43': '4:3 Landscape', 'size.portrait916': '9:16 Vertical', 'size.portrait23': '2:3 Portrait', 'size.landscape32': '3:2 Landscape', 'size.wide169': '16:9 Widescreen', 'size.ultrawide21': '21:9 Ultrawide', 'quality.auto': 'Auto', 'quality.1k': '1K', 'quality.2k': '2K', 'quality.4k': '4K', 'count.one': '1', 'count.two': '2', 'count.three': '3', 'count.four': '4', 'detail.auto': 'Auto', 'detail.standard': 'Standard', 'detail.high': 'High', 'detail.hint': 'Passthrough parameter supported by some gpt-image-2 gateways; keep "Auto" for official endpoints', 'model.label': 'Model', 'model.channel': 'Channel', 'model.channelPlaceholder': 'Default channel', 'model.noEditModels': 'No model is available for this mode', 'compare.enable': 'Multi-model comparison', 'compare.models': 'Models to compare', 'compare.title': 'Multi-model comparison', 'compare.fullscreen': 'Fullscreen comparison', 'compare.selectRequired': 'Select at least one model', 'generate': 'Generate', 'generating': 'Generating…', 'edit.upload': 'Click or drag to upload a reference image', 'edit.uploadHint': 'PNG / JPG / WEBP, up to 10MB', 'edit.change': 'Change image', 'edit.remove': 'Remove', 'edit.required': 'Upload a reference image first', 'edit.references': 'Reference images', 'edit.addedCount': '{count} added', 'edit.clearAll': 'Clear', 'edit.uploadMultiple': 'Click or drop multiple images', 'edit.addMore': 'Add more references', 'edit.add': 'Add', 'edit.previewReference': 'Preview image {index}: {name}', 'edit.removeReference': 'Remove image {index}: {name}', 'edit.multiHint': 'Select multiple, drop or paste images', 'edit.limits': 'Up to {count} images · 10MB each · 16MB total', 'edit.reading': 'Reading reference images…', 'edit.referencePreview': 'Reference image preview', 'edit.previousReference': 'Previous reference', 'edit.nextReference': 'Next reference', 'edit.invalidFiles': 'Some files were skipped: use non-empty PNG / JPG / WEBP / GIF images up to 10MB each.', 'edit.limitReached': 'Up to {count} references; extra images were skipped.', 'edit.totalTooLarge': 'References cannot exceed 16MB in total; excess images were skipped.', 'edit.readFailed': 'Some images could not be read. Please upload them again.', 'edit.modelLimit': 'The selected model adapters support up to {count} reference image(s). Switch models or remove extra images.', 'canvas.emptyTitle': 'Start creating', 'canvas.emptyHint': "Double-click the canvas or use the bottom dock to add image/text nodes; wire image and text nodes into a target node, select it and generate from the composer below", 'canvas.new': 'New creation', 'canvas.newHint': 'Start a new creation and clear the preview', 'canvas.error': 'Generation failed: {error}', 'canvas.submitting': 'Adding to the generation queue…', 'canvas.queued': 'Added to the generation queue', 'canvas.queueHint': '{count} task(s) waiting or generating', 'canvas.generating': 'Generating images…', 'canvas.elapsed': 'Elapsed {seconds}s', 'canvas.images': '{count} image(s) generated', 'download': 'Download', 'revisedPrompt': 'Refined prompt: {prompt}', 'history.title': 'History', 'history.empty': 'No history yet — generations will be saved here', 'history.clear': 'Clear', 'history.clearConfirm': 'Clear all history? This action cannot be undone.', 'history.restore': 'Restore', 'history.delete': 'Delete', 'history.images': 'images', 'history.viewing': 'History · {time}', 'history.search': 'Search prompt or model…', 'history.model': 'Model filter', 'history.ratio': 'Ratio filter', 'history.allModels': 'All models', 'history.allRatios': 'All ratios', 'gallery.title': 'Assets', 'gallery.categories': 'Categories', 'gallery.all': 'All assets', 'gallery.upload': 'Upload', 'gallery.uploadModel': 'Local upload', 'gallery.uploaded': 'Asset saved', 'gallery.uploadHint': 'Save local images for reuse on the canvas', 'gallery.gpt': 'gpt-image-2', 'gallery.grok': 'grok-imagine-image', 'gallery.ratio': 'Aspect ratio', 'gallery.tags': 'Tags', 'gallery.filterHint': 'Filter by mode, model, and aspect ratio', 'gallery.count': '· {count} works', 'gallery.viewMode': 'View mode', 'gallery.masonry': 'Masonry', 'gallery.grid': 'Grid', 'gallery.sort': 'Sort', 'gallery.newest': 'Newest', 'gallery.oldest': 'Oldest', 'gallery.untitled': 'Untitled work', 'gallery.search': 'Search works or models…', 'gallery.tagsPlaceholder': 'Tags, comma separated', 'gallery.tagsApply': 'Add tags', 'gallery.editTags': 'Edit tags', 'gallery.tagsEditShort': 'Edit', 'gallery.tagsSave': 'Save', 'gallery.tagsCancel': 'Cancel', 'gallery.selected': '{count} selected', 'gallery.selectionDone': 'Done selecting', 'gallery.selectionClear': 'Clear selection', 'gallery.downloadSelected': 'Download selected', 'gallery.exportJson': 'Export JSON', 'gallery.select': 'Select work', 'gallery.add': 'Add to gallery', 'gallery.added': 'Added to gallery', 'gallery.already': 'Already in gallery', 'gallery.delete': 'Remove', 'gallery.openFolder': 'Open folder', 'gallery.clear': 'Clear gallery', 'gallery.openFolderHint': 'Open the image save directory (~/.dsh/dsh-imagegen) in the system file manager', 'gallery.clearConfirm': 'Clear the entire gallery? This action cannot be undone.', 'gallery.empty': 'The gallery is empty — add images you like here', 'gallery.viewing': 'Gallery · {time}', 'preview.title': 'Image preview', 'preview.open': 'Click to preview', 'preview.close': 'Close', 'preview.prev': 'Previous', 'preview.next': 'Next', 'preview.index': '{index} / {total}', 'preview.zoomControls': 'Image zoom controls', 'preview.zoomIn': 'Zoom in', 'preview.zoomOut': 'Zoom out', 'preview.zoomReset': 'Reset zoom', 'preview.zoomLevel': '{percent}%', 'preview.copyPrompt': 'Copy prompt', 'preview.copied': 'Copied', 'preview.addToEdit': 'Add to image to image', 'config.missing': 'API not configured: open Settings → Image settings and fill in the API URL and key.', 'config.generationTitle': 'Configure the image API first', 'config.generationHint': 'Settings → Image settings has opened. Enter the image API URL and API key, then save before generating.', 'config.enhancementTitle': 'Configure a prompt enhancement model first', 'config.enhancementHint': 'Settings → Image settings has opened. Configure or reuse a chat API URL and key, choose a chat model, then save.', 'config.disabledTitle': 'The AI Image plugin is disabled', 'config.disabledHint': 'Settings → Image settings has opened. Enable the plugin, then generate images.', 'config.configured': 'Connected to {url}', 'config.disabled': 'The plugin is disabled — re-enable it in Settings.', 'connection.connected': 'Connected', 'connection.disconnected': 'Disconnected', 'panel.collapseConfig': 'Collapse settings panel', 'panel.expandConfig': 'Expand settings panel', 'update.available': 'A new version is available: {version}', 'update.button': 'Update v{version}', 'update.title': 'New version available', 'update.close': 'Close', 'update.noNotes': 'This Release does not include release notes.', 'update.installed': 'Updated', 'update.install': 'Update online', 'update.installing': 'Updating…', 'update.success': 'Updated to {version}; restart DSH to load it', 'update.failed': 'Update failed', 'update.hostManaged': 'Host installer unavailable', 'update.hostHint': 'DSH’s built-in plugin manager will install the update using the current host runtime. Restart DSH when finished.', 'update.hostManagedHint': 'This DSH desktop host does not expose a plugin installer. Upgrade DSH, or download the plugin from Releases and use the host’s supported installation flow.', 'update.release': 'View Release', 'settings.title': 'AI Image (dsh-imagegen)', 'settings.description': 'Configure the image generation API endpoint and key', 'settings.summaryTitle': 'Configuration overview', 'settings.summaryHint': 'Open a status card or group title to view details; only one group expands at a time.', 'settings.summaryReady': 'Core setup ready', 'settings.summaryNeedsSetup': 'Channel setup required', 'settings.summaryNotConfigured': 'Not configured', 'settings.summaryChannels': '{ready}/{total} ready', 'settings.summaryOptional': 'Optional', 'settings.summaryEnabled': 'Enabled', 'settings.summaryDisabled': 'Off', 'settings.summaryChannelsLabel': 'Channels and models', 'settings.summaryPromptLabel': 'Prompt enhancement', 'settings.summaryStorageLabel': 'Storage sync', 'settings.summarySkillsLabel': 'Canvas skills', 'settings.summaryGeneralLabel': 'General', 'settings.subscriptionLoggedIn': 'Signed in', 'settings.subscriptionLoggedOut': 'Signed out', 'settings.subscriptionExperimental': 'Experimental: uses a third-party client interface that may break with service updates. Follow the provider terms.', 'settings.subscriptionExperimentalTag': 'Experimental', 'settings.subscriptionLogin': 'Sign in', 'settings.subscriptionLoggingIn': 'Waiting for sign-in…', 'settings.subscriptionLoginOk': 'Signed in', 'settings.subscriptionLogout': 'Sign out', 'settings.subscriptionLoggingOut': 'Signing out…', 'settings.subscriptionIsolationHint': 'Tokens live in DSH Credentials only and are isolated from API keys.', 'settings.subscriptionDeviceCode': 'Enter this code on the authorization page: {code}', 'settings.subscriptionManualHint': 'If the browser cannot return automatically, paste the final redirect URL or authorization code here.', 'settings.subscriptionManualPlaceholder': 'Paste redirect URL or authorization code', 'settings.subscriptionManualComplete': 'Complete sign-in', 'settings.headerNeedsChannel': 'Add an image channel to get started', 'settings.headerSummary': '{channels} channels · {models} models', 'settings.skillsTitle': 'Infinite-canvas skills', 'settings.generalTitle': 'General settings', 'settings.generalHint': 'Master switch, Agent announcement, and image-generation permission', 'settings.currentVersion': 'Current version', 'settings.apiUrl': 'API URL (api_url)', 'settings.apiUrlHint': 'OpenAI-compatible base URL, e.g. https://api.openai.com/v1; /images/generations and /images/edits are appended', 'settings.apiKey': 'API Key (api_key)', 'settings.apiKeyHint': 'Bearer key, stored in plaintext in the local settings document; the UI only shows whether it is set', 'settings.apiKeySet': 'A key is stored; type a new value to replace it, or click "Clear" to remove it', 'settings.apiKeyClear': 'Clear', 'settings.imageModelsTitle': 'Image generation models', 'settings.imageModelsHint': 'Save the API URL and key, then detect candidate models. Select only models that actually support image generation.', 'settings.imageModels': 'Allowed image models', 'settings.imageModelsManualHint': 'One model per line. Add models manually when the API does not provide /models. The panel and Agent can use only this list.', 'settings.imageModelsFetch': 'Detect available models', 'settings.imageModelsLoading': 'Detecting…', 'settings.imageModelsCandidates': 'Detected candidate models (select, then save)', 'settings.addModel': '+ Add manually', 'settings.cancelAddModel': 'Hide add', 'settings.addModelPlaceholder': 'Enter a model name, e.g. qwen-image', 'settings.addModelConfirm': 'Add', 'settings.removeModel': 'Remove model', 'settings.optional': 'Optional', 'settings.moreOptions': 'More settings', 'settings.localStoragePath': 'Local image storage directory', 'settings.localStoragePathHint': 'History, assets and canvas images share this directory; leave empty for the default ~/.dsh/dsh-imagegen.', 'settings.storageTitle': 'Object storage sync', 'settings.storageEnabled': 'Enable object storage sync', 'settings.storageHint': 'After images land locally, mirror them to an S3-compatible store (Tencent COS / Alibaba OSS / Qiniu S3 / MinIO / R2 …)', 'settings.storageEndpoint': 'Endpoint (with bucket)', 'settings.storageEndpointHint': 'S3-compatible URL, e.g. https://bucket-appid.cos.ap-guangzhou.myqcloud.com or https://bucket.oss-cn-hangzhou.aliyuncs.com', 'settings.storageRegion': 'Region', 'settings.storageRegionHint': 'Region id used for signing, e.g. ap-guangzhou / oss-cn-hangzhou / cn-east-1', 'settings.storagePrefix': 'Key prefix', 'settings.storagePrefixHint': 'Object keys look like prefix/gallery|images/', 'settings.storageAccessKey': 'Access Key', 'settings.storageAccessKeyHint': 'S3-compatible access key id (COS SecretId / OSS AccessKeyId / Qiniu AK)', 'settings.storageSecretKey': 'Secret Key', 'settings.storageSecretKeyHint': 'S3-compatible secret, stored only in the local settings document', 'settings.storageSyncGallery': 'Sync gallery images', 'settings.storageSyncGalleryHint': 'Upload images when they are added to the gallery', 'settings.storageSyncHistory': 'Sync history images', 'settings.storageSyncHistoryHint': 'Also upload every generation result (can be a lot)', 'settings.storageTest': 'Test connection', 'settings.storageTesting': 'Testing…', 'settings.storageTestOk': 'Connected ({ms} ms), probe file uploaded', 'settings.storageTestFailed': 'Connection failed: {error}', 'settings.storageKeyHint': 'Note: syncing is best-effort and never blocks local saving; browse synced files under this prefix in your provider console.', 'settings.promptEnhanceTitle': 'Prompt enhancement model', 'settings.promptEnhanceHint': 'Expands short requests into complete image prompts. Blank URL and key reuse the image API configuration.', 'settings.promptApiUrl': 'Chat API URL (optional)', 'settings.promptApiUrlHint': 'OpenAI-compatible base URL. Leave blank to reuse the image API URL.', 'settings.promptApiKey': 'Chat API key (optional)', 'settings.promptApiKeyHint': 'Leave blank to reuse the image API key.', 'settings.promptModel': 'Chat model', 'settings.promptModelHint': 'Select or enter a model supporting /chat/completions.', 'settings.promptModelDetectionHint': 'Uses the image API by default. Detect and select one model.', 'settings.promptModelsFetch': 'Fetch available models', 'settings.promptModelsLoading': 'Fetching…', 'settings.promptModelsSelect': 'Select a model', 'settings.promptModelsCandidates': 'Detected chat model candidates', 'settings.addPromptModelPlaceholder': 'Enter a chat model name, e.g. gpt-4.1-mini', 'settings.promptApiAdvanced': 'Use a separate chat API (optional)', 'settings.announceToAgent': 'Announce this plugin to agents', 'settings.announceToAgentHint': 'When on, the plugin presence and capabilities are written into every agent system prompt', 'settings.allowAgentImageGeneration': 'Allow agents to generate images', 'settings.allowAgentImageGenerationHint': 'On by default. When off, agents cannot submit, query, or cancel image tasks; the sidebar studio remains available.', 'settings.enabled': 'Enable plugin', 'settings.enabledHint': 'When off, the generation studio is unavailable (this card stays available)', 'settings.save': 'Save', 'settings.saving': 'Saving…', 'settings.discard': 'Discard', 'settings.unsaved': 'Unsaved changes', 'settings.saveFailed': 'Save failed, please retry', 'settings.readOnly': 'The settings document is read-only; saving is disabled.', 'settings.notExposed': 'Settings namespace unavailable: this deployment does not serve this plugin\'s settings.', 'settings.expand': 'Expand', 'settings.collapse': 'Collapse', 'settings.inherit': 'Inherit', 'settings.on': 'On', 'settings.off': 'Off', 'settings.overridden': 'Overridden', 'settings.reset': 'Reset', 'settings.invalidNumber': 'Enter a valid number', // template library 'templates.open': 'Templates', 'templates.shortLabel': 'Templates', 'templates.resize': 'Resize template drawer', 'templates.recentsCount': '{count} recently used', 'templates.recents': 'Recent', 'templates.views': 'Library views', 'templates.browse': 'Browse', 'templates.restore': 'Restore width', 'templates.fullscreen': 'Fill workspace', 'templates.searchScope': 'Search scope', 'templates.currentSource': 'Current library', 'templates.allSources': 'All libraries', 'templates.recentsEmpty': 'Your recently used templates will appear here', 'templates.applyStyle': 'Add to style requirements', 'templates.replace': 'Replace prompt', 'templates.append': 'Append to prompt', 'templates.ecommerceHint': 'The template is appended to product information. Product name, references and output settings are preserved.', 'templates.title': 'Prompt Template Library', 'templates.sources': 'Template sources', 'templates.meta': '{count} templates · {origin}', 'templates.origin.bundled': 'bundled snapshot', 'templates.origin.refreshed': 'refreshed online', 'templates.search': 'Search template titles or prompts…', 'templates.all': 'All', 'templates.close': 'Close', 'templates.back': 'Back to list', 'templates.use': 'Use this prompt', 'templates.copy': 'Copy prompt', 'templates.copied': 'Copied', 'templates.refresh': 'Refresh this library', 'templates.refreshing': 'Refreshing…', 'templates.refreshed': 'Refreshed — {count} templates', 'templates.refreshFailed': 'Refresh failed: {error}', 'templates.favorites': 'Favorites', 'templates.favoritesCount': '{count} favorites', 'templates.favoritesHint': 'Show favorited templates only', 'templates.favoritesEmpty': 'No favorites yet — tap the star in a card\'s top-right corner to save one', 'templates.favoriteAdd': 'Favorite this template', 'templates.favoriteRemove': 'Remove from favorites', 'templates.favorite': 'Favorite', 'templates.unfavorite': 'Favorited', 'templates.cacheAll': 'Cache all images', 'templates.cacheAllHint': 'Mirror every reference image of the current library to local disk through the host proxy, for offline browsing', 'templates.caching': 'Caching {done}/{total}…', 'templates.cached': 'All images cached', 'templates.empty': 'No matching templates', 'templates.loading': 'Loading the template library…', 'templates.loadFailed': 'Failed to load the library: {error}', 'templates.retry': 'Retry', 'templates.attribution': 'Templates and images come from each source site; author links are on each template', 'templates.source': 'Source: {label}', 'templates.featured': 'Featured', // inspiration wall (studio empty state) 'inspiration.title': 'Inspiration', 'inspiration.shuffle': 'Shuffle', 'inspiration.shuffling': 'Shuffling…', 'inspiration.useHint': 'Click to use this prompt', // channel management 'channels.title': 'Channels', 'channels.hint': 'Fill in each channel\'s API URL and key to use its models', 'channels.empty': 'No channels yet — add one below', 'channels.addProvider': 'Add provider', 'channels.addCustom': 'Add custom channel', 'channels.untitled': 'Untitled channel', 'channels.keySet': 'Key set', 'channels.keyMissing': 'Key missing', 'channels.modelCount': '{n} model(s)', 'channels.noModels': 'No models', 'channels.defaultLabel': 'Default', 'channels.statusReady': 'Ready', 'channels.statusIncomplete': 'Config incomplete', 'channels.edit': 'Edit', 'channels.done': 'Done', 'channels.delete': 'Delete', 'channels.deleteConfirmTitle': 'Delete channel "{name}"? Its key will be removed; history and gallery records are kept.', 'channels.confirm': 'Delete', 'channels.cancel': 'Cancel', 'channels.editorTitle': 'Channel', 'channels.editorSaveNote': 'Changes take effect with the card\'s "Save" button', 'channels.displayName': 'Display name', 'channels.apiUrl': 'API URL', 'channels.protocol': 'Protocol', 'channels.protocolAuto': 'Auto detect', 'channels.protocolImages': 'Images API', 'channels.protocolChat': 'Chat Completions', 'channels.protocolHint': 'Auto uses Chat when the exact URL ends in /chat/completions; manual selection is also supported.', 'channels.apiUrlFull': 'Exact URL', 'channels.apiUrlFullHint': 'Use this URL verbatim without appending /images/generations or /images/edits. Chat Completions URLs can still derive /models from their parent path.', 'channels.apiKey': 'API key', 'channels.keyReplaceHint': 'Configured — type a new value to replace it', 'channels.keyMissingHint': 'Enter a key', 'channels.keyClear': 'Clear key', 'channels.showKey': 'Show key', 'channels.hideKey': 'Hide key', 'channels.modelCatalogTitle': 'Model catalog', 'channels.noModelsHint': 'No models yet: run "Detect" to pull candidates, or add one manually; the alias (display name) defaults to the upstream model id and can be renamed.', 'channels.detectFirst': 'Detect models', 'channels.detect': 'Re-detect', 'channels.detecting': 'Detecting…', 'channels.detectSuccess': 'Connected ✓ · {n} candidates', 'channels.detectFailed': 'Detection failed: {error}', 'channels.detectOk': 'Connected to this API', 'channels.modelAliasLabel': 'Display name (alias)', 'channels.modelIdLabel': 'Upstream model id', 'channels.generated': 'Generated {n} time(s)', 'channels.unknownProtocol': 'Unknown protocol — best-effort OpenAI', 'channels.removeModel': 'Remove model', 'channels.manualAddPlaceholder': 'Enter a model id, e.g. qwen-image', 'channels.addModelConfirm': 'Add', 'channels.copyFrom': 'Copy from another channel…', 'channels.copyApply': 'Copy', 'channels.candidatesTitle': 'Image model candidates (click to add)', 'channels.deleteThisChannel': 'Delete this channel', 'channels.setDefault': 'Set as default channel', 'channels.defaultModel': 'Default image model', 'channels.defaultModelHint': 'Used first by the studio, canvas, ecommerce and Agent tools when no model is specified. The sidebar Image entry stays enabled.', 'channels.presetPickerTitle': 'Add provider', 'channels.presetPickerHint': 'Pick a built-in provider — only the API key is needed', 'channels.presetTabApiKey': 'API Key', 'channels.presetTabSubscription': 'Subscriptions', 'channels.presetPickerApiKeyHint': 'Choose a regular API-key provider. Endpoint and key are required.', 'channels.presetPickerSubscriptionHint': 'Sign in once and use the fixed image model without a separate API key.', 'channels.presetClickToLogin': 'Sign in', 'channels.authMode': 'Authentication', 'channels.authModeApiKey': 'API key', 'channels.authModeSubscription': 'Subscription / experimental account', 'channels.subscriptionProvider': 'Subscription account', 'channels.presetSearch': 'Search providers or models', 'channels.presetEmpty': 'No matching providers', 'channels.presetCustomHint': 'Configure the API URL, key, and model catalog yourself', 'channels.presetLoadFailed': 'Failed to load providers: {error}', 'canvas.skills.fileNode': 'File node', 'canvas.skills.addFileNode': 'Add file node', 'canvas.skills.emptyFileNode': 'Click to upload a file', 'canvas.skills.fileMenuUpload': 'Upload file', 'canvas.skills.fileDropHint': 'Drop a file here to upload', 'canvas.skills.fileDropSub': 'PDF / Office / text / images, up to 50MB', 'canvas.skills.fileSizeUnknown': 'Unknown size', 'canvas.skills.filePreviewUnavailable': 'No inline preview for this format — download it or run a skill', 'canvas.skills.filePreviewLoading': 'Loading preview…', 'canvas.skills.fileDownload': 'Download file', 'canvas.skills.fileOpen': 'Open with the system app', 'canvas.skills.fileKind.text': 'Text', 'canvas.skills.fileKind.pdf': 'PDF', 'canvas.skills.fileKind.image': 'Image', 'canvas.skills.fileKind.office': 'Document', 'canvas.skills.fileKind.archive': 'Archive', 'canvas.skills.fileKind.audio': 'Audio', 'canvas.skills.fileKind.video': 'Video', 'canvas.skills.fileKind.other': 'File', 'canvas.skills.fileTooLarge': 'The file exceeds the {size}MB limit', 'canvas.skills.fileTypeBlocked': '{ext} files cannot be uploaded for safety reasons', 'canvas.skills.fileUploadFailed': 'Upload failed: {message}', 'canvas.preview.expand': 'Open preview', 'canvas.preview.close': 'Close preview', 'canvas.preview.copy': 'Copy content', 'canvas.preview.copied': 'Copied', 'canvas.preview.openTab': 'Open in a new tab', 'canvas.preview.retry': 'Retry', 'canvas.preview.failed': 'Preview failed: {message}', 'canvas.preview.empty': 'The file is empty', 'canvas.preview.textTruncated': 'Large file — showing the first {chars} characters', 'canvas.preview.tableTruncated': 'Large table — showing the first {rows} rows', 'canvas.preview.archiveTruncated': 'Many entries — listing the first {count}', 'canvas.preview.docTruncated': 'Long document — showing the first {blocks} blocks', 'canvas.preview.slidesTruncated': 'Large deck — showing the first {count} slides', 'canvas.preview.slideOf': 'Slide {page}', 'canvas.preview.rendered': 'Rendered', 'canvas.preview.source': 'Source', 'canvas.preview.pdfFallback': 'This environment cannot display the PDF inline — download it instead', 'canvas.preview.pdfHeuristic': 'PDF text is extracted heuristically; complex layouts may lose their order', 'canvas.preview.reason.unsupported': 'No readable content for this format — download it, or turn it into an image or text node for a skill', 'canvas.preview.reason.unreadable': 'No text could be read from this file (a scan or an unusual encoding); convert it to an image node for a vision model', 'canvas.preview.doubleClick': 'Double-click to open the preview', 'canvas.skills.button': 'Skill', 'canvas.skills.menuTitle': 'Run a skill', 'canvas.skills.runOn': 'Run a skill on “{name}”', 'canvas.skills.pickerTitle': 'Pick a skill', 'canvas.skills.searchPlaceholder': 'Search skills…', 'canvas.skills.groupBuiltin': 'Built-in actions', 'canvas.skills.groupExternal': 'Local skills', 'canvas.skills.emptyExternal': 'No local skills found — install one under ~/.dsh/skills and reload', 'canvas.skills.empty': 'No skills available', 'canvas.skills.loading': 'Loading skills…', 'canvas.skills.tierLight': 'Quick', 'canvas.skills.tierHeavy': 'Long task', 'canvas.skills.accepts': 'Works on: {types}', 'canvas.skills.incompatible': 'This skill does not apply to this node type', 'canvas.skills.disabled': 'Canvas skills are disabled in the plugin settings', 'canvas.skills.noRegistry': 'This host mounted no skill registry (ctx.skills), so only built-in actions are available', 'canvas.skills.registryFailed': 'Could not read the skill list: {message}', 'canvas.skills.needAgent': 'Needs the host agent runtime, which this DSH build does not provide — long-task skills stay disabled', 'canvas.skills.unknown': 'That skill no longer exists', 'canvas.skills.canvasMissing': 'The canvas no longer exists — reload and try again', 'canvas.skills.noInput': 'This node has no processable input', 'canvas.skills.noChat': 'Quick skills need a chat model: open Settings → Image settings → Prompt enhancement', 'canvas.skills.noDescription': '(no description provided)', 'canvas.skills.externalName': '{name}', 'canvas.skills.externalSystem': 'You are running the skill “{name}”. Follow its instructions exactly on the input below, answer in the input language, and output only the result — never restate the instructions.', 'canvas.skills.externalHeader': 'Apply the skill “{name}” to the input below.', 'canvas.skills.externalHeavyCost': 'This is a long task: it runs a headless agent and may consume a large amount of model quota.', 'canvas.skills.extraInstruction': 'Additional requirement:', 'canvas.skills.inputsHeader': 'Input:', 'canvas.skills.inputsEmpty': '(no readable text — work from the attached images)', 'canvas.skills.needInstruction': 'Enter a custom polish instruction', 'canvas.skills.needImage': 'This skill needs an image node as input', 'canvas.skills.needText': 'This skill needs a text node with content as input', 'canvas.skills.fileMissing': 'The file asset is missing or was cleaned up', 'canvas.skills.extractFailed': 'Could not extract any content from this file', 'canvas.skills.nothingToRead': 'Nothing readable found', 'canvas.skills.truncated': 'Content was long and got truncated to {count} characters', 'canvas.skills.tooManyImages': 'More than {count} images were selected; only the first ones were processed', 'canvas.skills.extractNodeTitle': 'Content of “{name}”', 'canvas.skills.summaryHead': 'Collected {count} source nodes:', 'canvas.skills.describeAsk': 'Describe these {count} image(s).', 'canvas.skills.polishNodeTitle': 'Polished ({style})', 'canvas.skills.skillMissing': 'The skill “{name}” is not installed. Install it first (for example, ask your DSH agent to install https://github.com/ningzimu/image-to-editable-ppt-skill) and retry.', 'canvas.skills.agentFailed': 'Could not create a headless agent — check the model and agent preset configuration', 'canvas.skills.needModel': 'This host publishes no default model (agent-default-model), so a long-task skill cannot start its agent. Pick a default model in Settings → General and retry.', 'canvas.skills.noOutputFile': 'The skill produced no file; the agent’s answer was saved as a text node', 'canvas.skills.heavyIntro': 'You are running the skill “{name}” for a visual canvas. Complete the whole procedure exactly as documented; do not skip steps.', 'canvas.skills.heavyBodyHeader': 'Skill instructions:', 'canvas.skills.heavyInputsHeader': 'Input files for this task (absolute paths):', 'canvas.skills.heavyOutputHeader': 'Write the final artifact(s) into this directory: {dir}', 'canvas.skills.heavyRules': 'Requirements:\n1. Keep every intermediate file in the working directory; the final artifact may only go into the output directory above.\n2. When done, reply briefly with the artifact file names, whether it succeeded, and any caveats.', 'canvas.skills.heavyAsk': 'Run the skill “{name}”.', 'canvas.skills.heavyAskInputs': 'Input directory: {dir}', 'canvas.skills.heavyAskOutput': 'Output directory: {dir}', 'canvas.skills.heavyAskLoadSkill': '(If the skill instructions are not in context, load them by the skill name “{name}” first.)', 'canvas.skills.stageQueued': 'Queued', 'canvas.skills.stagePreparing': 'Preparing input files', 'canvas.skills.stageReading': 'Reading node content', 'canvas.skills.stageRunning': 'Running the skill', 'canvas.skills.stageCollecting': 'Collecting artifacts', 'canvas.skills.stageDone': 'Done', 'canvas.skills.stageCancelled': 'Cancelled', 'canvas.skills.stagePrepared': 'Prepared {count} input file(s)', 'canvas.skills.stageArtifacts': 'Running — {count} file(s) produced', 'canvas.skills.runElapsed': 'Elapsed', 'canvas.skills.runRetry': 'Retry', 'canvas.skills.runStarted': 'Skill “{name}” started', 'canvas.skills.runDone': 'Skill finished — {count} new node(s)', 'canvas.skills.runFailed': 'The skill failed: {message}', 'canvas.skills.runCancelled': 'The skill run was cancelled', 'canvas.skills.cancel': 'Cancel run', 'canvas.skills.cancelling': 'Cancelling…', 'canvas.skills.confirmTitle': 'Run a long-task skill', 'canvas.skills.confirmBody': '“{name}” starts a headless agent on this machine. It can run for minutes to tens of minutes and consume a large amount of model quota.', 'canvas.skills.confirmCost': 'Cost: {hint}', 'canvas.skills.confirmRequires': 'Requires: {list}', 'canvas.skills.confirmRun': 'Run it', 'canvas.skills.confirmCancel': 'Not now', 'canvas.skills.batchTitle': 'Batch run', 'canvas.skills.batchNote': 'Runs once per node, one after another ({count} nodes)', 'canvas.skills.batchTooMany': 'At most {count} nodes per run', 'canvas.skills.sourceBadge': 'Skill output', 'canvas.skills.sourceTip': 'Produced by the skill “{name}” from {count} source node(s)', 'canvas.skills.rerun': 'Run the same skill again', 'canvas.skills.history': 'Skill run history', 'canvas.skills.historyEmpty': 'No runs yet', 'canvas.skills.needConfirm': 'This skill needs confirmation before it runs', 'canvas.skills.polish': 'Polish text', 'canvas.skills.polishDesc': 'Rewrite a text node in a chosen style: more formal / casual / shorter / expanded, or a custom instruction', 'canvas.skills.describe': 'Describe image', 'canvas.skills.describeDesc': 'Read an image with a vision model and produce a text node (usable as a prompt)', 'canvas.skills.extract': 'Extract content', 'canvas.skills.extractDesc': 'Pull the text out of a file or image into a text node (text / code / OOXML / PDF)', 'canvas.skills.ppt': 'Image → editable PPT', 'canvas.skills.pptDesc': 'Drive the local image-to-editable-ppt skill to rebuild images into an editable .pptx file node', 'canvas.skills.pptCost': 'Long task: a 10-page deck can consume a large quota; a single page often takes 10+ minutes', 'canvas.skills.pptRequires': 'Needs the image-to-editable-ppt skill installed locally, with the OCR token and image backend configured as its docs describe', 'canvas.polish.button': 'AI polish', 'canvas.polish.title': 'AI polish', 'canvas.polish.formal': 'More formal', 'canvas.polish.casual': 'More casual', 'canvas.polish.shorter': 'Shorter', 'canvas.polish.expand': 'Expand', 'canvas.polish.custom': 'Custom', 'canvas.polish.customPlaceholder': 'e.g. rewrite as a social post with emoji and hashtags', 'canvas.polish.run': 'Polish', 'canvas.polish.previewTitle': 'Before / after', 'canvas.polish.apply': 'Apply', 'canvas.polish.revert': 'Revert', 'canvas.polish.applied': 'Polish applied', 'canvas.polish.directHint': 'Current setting: polish overwrites the node directly (switch to preview-first in the settings)', 'settings.skillsEnabled': 'Canvas skills', 'settings.skillsEnabledHint': 'Enable the skill system on infinite-canvas nodes (built-in actions plus local skills)', 'settings.allowHeavySkills': 'Allow long-task skills', 'settings.allowHeavySkillsHint': 'Long-task skills start a headless DSH agent on this machine — slow and quota-hungry. Turn off to keep only quick skills.', 'settings.skillAllowlist': 'Skill allowlist', 'settings.skillAllowlistHint': 'Comma or newline separated skill names; leave empty to allow every local skill', 'settings.skillOutputDir': 'Long-task working directory', 'settings.skillOutputDirHint': 'Working directory for headless agent runs (empty uses canvas/runs under the data directory)', 'settings.skillHeavyTimeout': 'Long-task timeout (minutes)', 'settings.skillHeavyTimeoutHint': 'Long-task skills are cancelled after this long; 0 disables the timeout', 'settings.skillAgentPreset': 'Long-task agent preset', 'settings.skillAgentPresetHint': 'Agent preset used for long-task skills; empty uses the host default', 'settings.skillProbe': 'Detect skill environment', 'settings.skillProbing': 'Detecting…', 'settings.skillProbeOk': '{count} skill(s) available · headless agent: {agent}', 'settings.skillProbeAgentOn': 'available', 'settings.skillProbeAgentOff': 'unavailable', 'settings.skillsHint': 'Tip: install skills such as image-to-editable-ppt under ~/.dsh/skills to turn images into editable decks right on the canvas.', 'canvas.skills.libraryButton': 'Skill library', 'canvas.skills.libraryTitle': 'Skill library', 'canvas.skills.libraryInstalled': 'Installed skills ({count})', 'canvas.skills.libraryEmpty': 'No skills installed yet. Install one from a repository URL, or upload a skill archive.', 'canvas.skills.libraryRoot': 'Install root: {root}', 'canvas.skills.libraryInstall': 'Install from URL', 'canvas.skills.libraryInstallHint': 'GitHub repo / folder / single SKILL.md, any git URL, or a zip URL; separate several with new lines. The host loads installs live — no restart.', 'canvas.skills.libraryUrlPlaceholder': 'https://github.com/owner/repo or …/blob/main/SKILL.md', 'canvas.skills.libraryUpload': 'Upload archive', 'canvas.skills.libraryUploadHint': 'Upload a zip that contains SKILL.md (≤50MB); it is unpacked into ~/.dsh/skills.', 'canvas.skills.libraryDropzone': 'Click or drop a .zip archive here', 'canvas.skills.libraryForce': 'Replace an installed skill of the same name', 'canvas.skills.libraryInstallAction': 'Install', 'canvas.skills.libraryInstalling': 'Installing…', 'canvas.skills.libraryRemove': 'Uninstall', 'canvas.skills.libraryRemoving': 'Uninstalling…', 'canvas.skills.libraryRemoveConfirm': 'Uninstall “{name}”? Its folder is deleted from the skill library.', 'canvas.skills.libraryInstalledToast': 'Installed: {names}', 'canvas.skills.libraryFailedToast': 'Install failed: {message}', 'canvas.skills.libraryRemovedToast': 'Uninstalled: {name}', 'canvas.skills.libraryUnavailable': 'This host cannot manage the skill library', 'canvas.skills.libraryReload': 'Refresh', 'canvas.skills.libraryOpenFolder': 'Open skill folder', 'canvas.skills.installNow': 'Install', 'canvas.skills.needsInstall': 'Not installed', 'canvas.skills.missingHint': '“{name}” is not installed yet — install it to use this action', 'canvas.skills.installArchiveFailed': 'Archive install failed: {message}', 'canvas.skills.libraryIssueFrontmatter': 'No YAML frontmatter (name / description are required), so the host skill registry never loads it and no node can run it', 'canvas.skills.libraryIssueName': 'The frontmatter name “{name}” is not kebab-case (lowercase letters, digits and hyphens), so the host skill registry ignores it and no node can run it', 'canvas.skills.libraryIssueDescription': 'The SKILL.md frontmatter has no description (required), so the host skill registry never loads it and no node can run it', 'canvas.skills.libraryIssueInvocation': 'The disable-model-invocation / user-invocable spelling cannot be parsed, so the host skill registry ignores it and no node can run it', 'canvas.skills.libraryIssueUserOnly': 'This skill declares disable-model-invocation: it is human-invocable only, so canvas nodes cannot run it', 'canvas.skills.configOpen': 'Configure', 'canvas.skills.configSave': 'Save', 'canvas.skills.configSaveApply': 'Save and apply', 'canvas.skills.configSaving': 'Saving…', 'canvas.skills.configApplying': 'Applying…', 'canvas.skills.configSaved': 'Saved', 'canvas.skills.configSaveFailed': 'Could not save', 'canvas.skills.configApplied': 'Saved and applied', 'canvas.skills.configApplyFailed': 'Could not apply', 'canvas.skills.configClear': 'Clear', 'canvas.skills.configSecretSet': 'Set (leave empty to keep it)', 'canvas.skills.configSecretUnset': 'Not set', 'canvas.skills.configMissingHint': 'Needs configuration: {fields}', 'canvas.skills.configGo': 'Configure', 'canvas.skills.configSourceSkill': 'These fields are declared by the skill’s own skill.config.json', 'canvas.skills.configSourcePlugin': 'These fields come from this plugin’s built-in recipe for a known skill (a skill’s own declaration wins)', 'canvas.skills.configHeader': 'Already configured:', 'canvas.skills.configUnwritable': 'This host cannot write settings, so skill configuration is unavailable', 'canvas.skills.configIssueVersion': 'skill.config.json declares a version other than 1, so the declaration was ignored', 'canvas.skills.configIssueUnreadable': 'skill.config.json could not be parsed (JSON syntax error), so the declaration was ignored', 'canvas.skills.configIssueEmpty': 'skill.config.json declares no usable field or step, so it was ignored', } /** Locale key union. */ export type ImageGenKey = keyof typeof zh /** Russian mirror of every key (полный словарь интерфейса). */ export const ru: Record = { "ppt.activityPreparing": "Подготовка исходных изображений", "ppt.activityTextHints": "Обработка текстовых подсказок", "ppt.activityAssets": "Воссоздание изображений", "ppt.activityBuilding": "Сборка слайдов", "ppt.activityValidating": "Проверка слайдов", "ppt.activityFinalizing": "Сборка и проверка итогового PPT", "ppt.progressTitle": "Ход преобразования", "ppt.lastActivity": "Последнее событие: {seconds} с назад", "ppt.idleNote": "Новых событий пока нет. Запрос модели или внешний инструмент может продолжать работу. Подробности — в диагностике.", "ppt.pageProgress": "Проверено {done} / {total} слайдов", "ppt.progressPage": "Слайд {page}", "ppt.pageState.pending": "Ожидание", "ppt.pageState.running": "Воссоздание", "ppt.pageState.validated": "Проверен", "ppt.activityHistory": "История выполнения", "ppt.waitingActivity": "Ожидание событий и записей о страницах.", "ppt.activityModel": "Выполняется запрос модели", "ppt.activityUnknownTool": "инструмент", "ppt.activityTool": "Запущен инструмент: {name}", "ppt.activityToolDone": "Инструмент завершён: {name}", "ppt.activityToolFailed": "Ошибка инструмента; ожидается обработка агентом: {name}", "ppt.activityModelDone": "Ответ модели получен", "ppt.activityPages": "Проверено страниц: {done} / {total}", "ppt.activityPrepared": "Исходные изображения подготовлены", "ppt.activityDispatched": "Задачи страниц распределены", "ppt.activityRecorded": "Результаты страниц записаны; ожидается сборка", "ppt.activityBuilt": "PPT собран; ожидается проверка", "ppt.activityValidated": "Итоговый PPT прошёл проверку", "ppt.activityUpstreamDone": "Исходный процесс завершён; сборка результата", "ppt.activityAgent": "Создание агента навыка", "ppt.activityFailed": "Преобразование не удалось; см. ошибку и диагностику", "ppt.persistenceWarning": "Не удалось сохранить историю задачи. Текущее состояние и результат действительны; после перезапуска история может быть неполной. Ошибка: {error}", "ppt.diagnostic": "Диагностика задания", "ppt.diagnosticHint": "Используйте задание, сеанс агента и каталог для поиска журналов DSH. Нажмите текст для выделения.", "ppt.legacyDiagnostic": "Старое задание не сохранило сеанс агента и исходную ошибку. Для определения причины нужны журналы DSH за время выполнения.", "ppt.pages": "Слайдов: {count}", "ppt.downloadDeck": "Скачать PPTX", "ppt.expand": "Развернуть просмотр", "ppt.pageNavigation": "Навигация по слайдам", "ppt.goToPage": "Перейти к слайду {page}", "ppt.previousPage": "Предыдущий слайд", "ppt.nextPage": "Следующий слайд", "ppt.contentPreview": "Просмотр содержимого · Сложная вёрстка — в PowerPoint", "ppt.fitWindow": "По размеру окна", "ppt.previewDeck": "Просмотр PPT", "ppt.previewHint": "Просмотр показывает текст и встроенные изображения слайдов. Сложную вёрстку проверяйте в PowerPoint.", "ppt.agentFailed": "Ошибка преобразования: {error}", "ppt.noAgentReply": "Агент не вернул ответ или файл. Проверьте подключение/квоту модели DSH и инструменты файлов и команд.", "ppt.close": "Закрыть", "ppt.sources": "Изображения слайдов", "ppt.previewSource": "Просмотр оригинала", "ppt.addImages": "Добавить изображения", "ppt.orderHint": "Порядок слайдов соответствует миниатюрам. Нажмите для просмотра.", "ppt.history": "История преобразований", "ppt.retry": "Повторить", "ppt.checkSetup": "Проверить настройки", "ppt.settingsTitle": "Настройки изображения в PPT", "ppt.updateSkill": "Обновить навык", "ppt.reuseImages": "Повторить с этими изображениями", "ppt.nav": "Изображение → PPT", "ppt.title": "Изображение в редактируемый PPT", "ppt.description": "Восстановление текста, фигур и макета в редактируемом PowerPoint.", "ppt.action": "Создать редактируемый PPT", "ppt.upload": "Загрузить изображения слайдов", "ppt.uploading": "Загрузка…", "ppt.uploadHint": "PNG / JPG / WebP: до 12 изображений, 20 МБ каждое", "ppt.inputLimit": "Выберите 1–12 изображений, по одному на слайд.", "ppt.invalidImage": "Используйте PNG / JPG / WebP размером до 20 МБ.", "ppt.moveUp": "Переместить слайд выше", "ppt.moveDown": "Переместить слайд ниже", "ppt.ocrTitle": "Распознавание текста", "ppt.ocrPaddle": "Использовать настроенный PaddleOCR", "ppt.ocrOffline": "Локальное определение текста для этого задания", "ppt.ocrHint": "PaddleOCR улучшает восстановление текста и размеров. Локальный режим измеряет геометрию; текст восстанавливает модель.", "ppt.processingHint": "Преобразование использует модель хоста и настроенные сервисы изображений / OCR и может занять несколько минут.", "ppt.setupRequired": "Установите навык и среду в настройках и включите длительные задания.", "ppt.convert": "Создать редактируемый PPT", "ppt.submitting": "Отправка…", "ppt.openSettings": "Открыть настройки", "ppt.results": "Результаты", "ppt.resultCount": "Заданий: {count}", "ppt.empty": "Превратите изображения в редактируемые слайды", "ppt.emptyHint": "Загрузите изображения или выберите создание PPT в результатах генерации. Порядок изображений задаёт порядок слайдов.", "ppt.cancel": "Отменить", "ppt.working": "Выполнение навыка…", "ppt.interrupted": "Хост перезапущен, преобразование прервано. Исходные изображения сохранены; повторите задание.", "ppt.invalidDeck": "Некорректный PPTX или число слайдов не совпадает с количеством изображений.", "ppt.noDeck": "Навык не создал итоговый PPTX. Проверьте среду и настройки.", "ppt.setupHint": "Используется оригинальный процесс навыка и editppt.", "ppt.installSkill": "Установить навык", "ppt.installed": "Навык установлен", "ppt.installRuntime": "Установить / восстановить среду", "ppt.checkRuntime": "Проверить среду", "ppt.runtimeReady": "editppt готов", "ppt.runtimeMissing": "Проверьте editppt", "ppt.runtimeHint": "Нужен Python 3.10+. CLI и зависимости устанавливаются в отдельную среду плагина; нужен интернет.", "ppt.configured": "Настроено", "ppt.secretUnchanged": "Сохранено; оставьте пустым для сохранения", "ppt.paddleLink": "Получить токен PaddleOCR", "ppt.saveConfig": "Сохранить и применить настройки PPT", "ppt.configSaved": "Настройки PPT сохранены и применены.", "ppt.setupWorking": "Обработка… установка зависимостей может занять несколько минут.", "poster.title": "Редактор постера: текст / логотип", "poster.hint": "Добавляйте и перемещайте слои без расхода лимита модели.", "poster.sampleText": "Ваш заголовок", "poster.addText": "Добавить текст", "poster.addLogo": "Загрузить логотип", "poster.undo": "Отменить", "poster.redo": "Повторить", "poster.logoLimit": "PNG / JPG / WebP: до 10 МБ и 40 мегапикселей.", "poster.logoFailed": "Не удалось прочитать логотип", "poster.exportFailed": "Не удалось экспортировать. Повторите попытку.", "poster.preview": "Предпросмотр постера", "poster.logo": "Слой логотипа", "poster.loading": "Загрузка изображений…", "poster.layers": "Слои (верхний на переднем плане)", "poster.backgroundFixed": "Фон сохраняется. Рекомендуется прозрачный PNG.", "poster.text": "Текст", "poster.font": "Шрифт", "poster.sans": "Без засечек", "poster.serif": "С засечками", "poster.mono": "Моноширинный", "poster.fontSize": "Размер шрифта (пикс.)", "poster.color": "Цвет текста", "poster.bold": "Жирный", "poster.align": "Выравнивание", "poster.left": "Слева", "poster.center": "По центру", "poster.right": "Справа", "poster.width": "Ширина (пикс.)", "poster.front": "На передний план", "poster.back": "На задний план", "poster.delete": "Удалить слой", "poster.selectHint": "Добавьте текст или логотип и выберите слой для редактирования.", "poster.discardHint": "Изменения не сохранены.", "poster.discard": "Отменить изменения", "poster.keepEditing": "Продолжить", "poster.saveHint": "Сохраните новый узел для дальнейшего редактирования. PNG не сохраняет слои.", "poster.export": "Экспорт PNG", "poster.save": "Сохранить на холст", "poster.working": "Обработка…", "poster.sourceChanged": "Исходный холст или изображение изменились. Откройте редактор заново.", "poster.resultTitle": "Редактируемый постер", "poster.saved": "Постер добавлен. Дождитесь сохранения холста.", 'entry.label': 'ИИ-генерация', 'entry.tooltip': 'Панель ИИ-генерации изображений (gpt-image-2 / glm-image / grok-imagine-image / nanobanana / seedream)', 'entry.session': 'Сессия', 'entry.sessionTooltip': 'Вернуться к текущей сессии', 'entry.image': 'Генерация', 'entry.settings': 'Настройки генерации', 'panel.title': 'VisioWork', 'panel.githubTip': 'Понравился плагин или есть идеи? Поставьте звезду или откройте issue на GitHub!', 'conversation.add': 'В диалог', 'conversation.adding': 'Добавляем…', 'conversation.added': 'Изображение добавлено в текущий диалог', 'conversation.addHint': 'После добавления можно править через /edit_image; команда использует модель плагина', 'conversation.noSession': 'Сначала откройте сессию, затем добавьте изображение', 'conversation.unavailable': 'Текущая сессия недоступна', 'conversation.busy': 'Диалог отправляет сообщение, попробуйте позже', 'conversation.chooseSession': 'Выберите диалог', 'conversation.chooseSessionHint': 'Текущий диалог недоступен. Выберите, куда добавить изображение.', 'conversation.targetSession': 'Целевой диалог', 'conversation.selectSession': 'Выберите диалог', 'conversation.confirmAdd': 'Добавить в выбранный диалог', 'conversation.cancel': 'Отмена', 'mode.text': 'Из текста', 'mode.edit': 'Из изображения', 'workspace.label': 'Режим работы', 'workspace.normal': 'Генерация', 'workspace.canvas': 'Бесконечный холст', 'workspace.ecommerce': 'E-commerce', 'canvas.addImage': 'Добавить изображение', 'canvas.addText': 'Добавить текст', 'canvas.generate': 'Создать изображение', 'canvas.addToCanvas': 'Добавить на холст', 'canvas.untitled': 'Безымянный холст', 'canvas.imageNode': 'Узел изображения', 'canvas.textNode': 'Текстовый узел', 'canvas.fromGallery': 'Из галереи', 'canvas.fromHistory': 'Из истории', 'canvas.project': 'Проект холста', 'canvas.favoriteCanvas': 'Добавить в избранное', 'canvas.unfavoriteCanvas': 'Убрать из избранного', 'canvas.favoriteProjects': 'Избранное ({count})', 'canvas.allProjects': 'Другие холсты ({count})', 'canvas.newCanvas': 'Новый холст', 'canvas.deleteCanvas': 'Удалить холст', 'canvas.deleteCanvasConfirm': 'Нажмите ещё раз для подтверждения', 'canvas.rename': 'Переименовать холст', 'canvas.renameHint': 'Двойной клик — переименовать', 'canvas.background': 'Фон холста', 'canvas.backgroundDots': 'Точки', 'canvas.backgroundLines': 'Сетка', 'canvas.backgroundWaves': 'Волны', 'canvas.backgroundShapeGrid': 'Бегущая сетка', 'canvas.backgroundDotField': 'Поле точек', 'canvas.backgroundDotGrid': 'Интерактивные точки', 'canvas.backgroundFloatingLines': 'Плавающие линии', 'canvas.backgroundFlow': 'Жидкостный поток', 'canvas.backgroundLiquid': 'Жидкий эфир', 'canvas.backgroundFaultyTerminal': 'Сбойный терминал', 'canvas.backgroundSilk': 'Шёлк', 'canvas.backgroundGalaxy': 'Галактика', 'canvas.backgroundBlank': 'Отключить фон (для производительности)', 'canvas.backgroundUpload': 'Загрузить свой фон…', 'canvas.backgroundRemove': 'Убрать свой фон', 'canvas.templateLibrary': 'Библиотека шаблонов (выберите промпт — создадутся текстовый узел и узел конфигурации)', 'canvas.undo': 'Отменить (Ctrl+Z)', 'canvas.redo': 'Повторить (Ctrl+Shift+Z)', 'canvas.saving': 'Сохранение…', 'canvas.saved': 'Сохранено', 'canvas.saveFailed': 'Ошибка сохранения', 'canvas.loading': 'Загрузка…', 'canvas.toolSelect': 'Выбор / перемещение узлов', 'canvas.toolPan': 'Перетаскивание холста (Space / Ctrl)', 'canvas.delete': 'Удалить', 'canvas.duplicate': 'Дублировать (Ctrl+D)', 'canvas.download': 'Скачать изображение', 'canvas.fitView': 'Показать всё содержимое', 'canvas.minimapOpen': 'Открыть мини-карту', 'canvas.minimapClose': 'Скрыть мини-карту', 'canvas.minimap': 'Мини-карта холста', 'canvas.zoom': 'Масштаб', 'canvas.textPlaceholder': 'Введите текст…', 'canvas.generatingNode': 'Генерация…', 'canvas.generateFailed': 'Не удалось создать изображение', 'canvas.retry': 'Повторить', 'canvas.taskLost': 'Задача генерации потеряна (сервис перезапущен); повторите', 'canvas.emptyImageNode': 'Нажмите, чтобы загрузить изображение', 'canvas.connectHint': 'Потяните к другому узлу, чтобы соединить', 'canvas.connectAddHint': 'Потяните к другому узлу, чтобы соединить; клик добавляет следующий узел', 'canvas.resizeHint': 'Потяните, чтобы изменить размер (пропорции зафиксированы)', 'canvas.count': 'Кол-во изображений', 'canvas.configNode': 'Конфигурация генерации', 'canvas.addConfigNode': 'Добавить узел конфигурации', 'canvas.configHint': 'Подключите узлы изображений слева как референсы и текстовые узлы как промпт; выберите этот узел и генерируйте через панель ниже.', 'canvas.composerLinked': 'Подключено узлов ввода: {count}', 'canvas.composerPlaceholder': 'Опишите изображение; либо подключите текстовые узлы как промпт…', 'canvas.countUnit': '{count} шт.', 'canvas.model': 'Модель изображений', 'canvas.modelPlaceholder': 'Выберите модель', 'canvas.size': 'Пропорции', 'canvas.sizeAuto': 'Авто', 'canvas.quality': 'Качество', 'canvas.qualityAuto': 'Авто', 'canvas.needApi': 'Сначала настройте API генерации', 'canvas.needPrompt': 'Введите описание генерации', 'canvas.needModel': 'Нет доступной модели изображений', 'canvas.openSettings': 'Открыть настройки', 'canvas.deleteConnection': 'Удалить связь', 'canvas.paste': 'Вставить (Ctrl+V)', 'canvas.addImageNode': 'Добавить узел изображения', 'canvas.addTextNode': 'Добавить текстовый узел', 'canvas.addSketch': 'Добавить скетчборд (эскиз → изображение)', 'canvas.sketchNode': 'Скетчборд', 'canvas.addSketchNode': 'Добавить узел скетчборда', 'canvas.sketchPlaceholder': 'Нарисуйте эскиз от руки и подключите к узлу конфигурации как референс', 'canvas.sketchBrush': 'Кисть', 'canvas.sketchEraser': 'Ластик', 'canvas.sketchUndo': 'Отменить последний штрих', 'canvas.sketchClear': 'Очистить доску', 'canvas.sketchWidth': 'Толщина линии', 'canvas.dismiss': 'Закрыть', 'canvas.annotate': 'Разметка: обведите область, чтобы прикрепить карточку промпта', 'canvas.annotationNode': 'Промпт разметки', 'canvas.annotationTag': 'Разметка', 'canvas.annotationPlaceholder': 'Опишите, что должно быть в рамке, например: заменить на рыжего кота', 'canvas.annotationDrawHint': 'Проведите по изображению, чтобы нарисовать рамку; после отпускания появится карточка промпта, которая следует за изображением (соединять не нужно)', 'canvas.removeBackground': 'Удалить фон (локальная обработка, прозрачный PNG)', 'canvas.removingBackground': 'Удаляем фон…', 'canvas.removeBgDone': 'Фон удалён (прозрачных пикселей {percent}%)', 'canvas.removeBgFailed': 'Фон слишком сложный для локальной обработки; обведите объект разметкой и попросите модель перерисовать', 'canvas.alreadyTransparent': 'У этого изображения уже прозрачный фон', 'canvas.noBackgroundNode': 'Изображение без фона', 'canvas.splitLayers': 'Разделить слои (ИИ-разбор на редактируемые слои)', 'canvas.splittingLayers': 'Разделяем слои…', 'canvas.layerSplitDone': 'Разделено на {count} слоёв', 'canvas.layerSplitEmpty': 'Модель не нашла слоёв для разделения', 'canvas.layerBackground': 'Фон · {label}', 'canvas.layerObject': 'Слой · {label}', 'canvas.layerText': 'Текст · {label}', 'canvas.layerKindBackground': 'Фон', 'canvas.layerKindObject': 'Элемент', 'canvas.layerKindText': 'Текст', 'canvas.nodeModel': 'Модель для этого узла (повтор и подключённые узлы конфигурации)', 'canvas.modelDefault': 'Модель по умолчанию', 'canvas.fontSmaller': 'Меньше шрифт', 'canvas.fontLarger': 'Больше шрифт', 'canvas.bold': 'Жирный', 'canvas.textColor': 'Цвет текста', 'canvas.colorDefault': 'Как в теме', 'canvas.close': 'Закрыть', 'canvas.tabUpload': 'Загрузка', 'canvas.tabHistory': 'История', 'canvas.tabGallery': 'Материалы', 'canvas.imageMenuUpload': 'Локальное изображение', 'canvas.imageMenuAssets': 'Материалы', 'canvas.imageMenuHistory': 'История', 'canvas.imageMenuGenerate': 'AI-генерация', 'canvas.tabGenerate': 'AI-генерация', 'canvas.dropHint': 'Перетащите изображения сюда', 'canvas.dropSub': 'Несколько файлов, PNG / JPG / WebP / GIF', 'canvas.untitledWork': 'Без названия', 'canvas.picked': 'Выбрано: {count}', 'canvas.generateAndAdd': 'Создать и добавить на холст', 'chat.expand': 'Показать диалог', 'chat.collapse': 'Скрыть диалог', 'chat.toggle': 'Диалог', 'config.resizeHint': 'Потяните, чтобы изменить ширину панели параметров', 'ecommerce.generation': 'Параметры генерации', 'ecommerce.title': 'Режим e-commerce', 'ecommerce.badge': 'Превью', 'ecommerce.short': 'E-com', 'ecommerce.anchorPending': 'Главное изображение готово, остальные генерируются по нему для единого стиля…', 'ecommerce.anchorFailed': 'Не удалось создать главное изображение, остальные приостановлены. Повторите главное (или всю группу) и продолжите.', 'ecommerce.anchorNote': 'Якорная генерация: сначала главное изображение, остальные создаются по нему для единого стиля', 'ecommerce.noAssetWarn': 'Товар не загружен: главное изображение будет создано по описанию и станет якорем; загрузите фото товара для большей точности', 'ecommerce.product': 'Товар', 'ecommerce.productName': 'Название товара (обязательно)', 'ecommerce.projectName': 'Название проекта (необязательно)', 'ecommerce.constraints': 'Преимущества и ограничения', 'ecommerce.sellingPoints': 'Доп. информация: бренд и модель, характеристики (объём/размер/вес), материалы, преимущества, сертификация, комплектация…', 'ecommerce.protectedFeatures': 'Что обязательно сохранить: цвет, логотип, текст упаковки, конструкцию', 'ecommerce.styleHint': 'Стиль, например: премиальный / реалистичный / естественный свет', 'ecommerce.setStructure': 'Структура комплекта', 'ecommerce.preview': 'Создать превью комплекта', 'ecommerce.planTitle': 'Будет сгенерировано изображений: {count}', 'ecommerce.planSlot': '{count} шт. · {description}', 'ecommerce.confirm': 'Сгенерировать весь комплект', 'ecommerce.uploadRef': 'Фото товара (обязательно, до 4 шт.: товар / упаковка / детали)', 'ecommerce.uploadShort': 'Загрузить материалы', 'ecommerce.sellingTitle': 'Преимущества товара', 'ecommerce.advanced': 'Дополнительно (площадка / ограничения)', 'ecommerce.params': 'Параметры', 'ecommerce.platformLabel': 'Площадка', 'ecommerce.languageLabel': 'Язык текста', 'ecommerce.customLanguageOption': 'Свой язык…', 'ecommerce.customLanguageLabel': 'Свой язык', 'ecommerce.customLanguagePlaceholder': 'Введите язык, например: Русский / 日本語 / Português', 'ecommerce.ratioLabel': 'Пропорции', 'ecommerce.categoryLabel': 'Категория', 'ecommerce.multiSelect': 'Можно выбрать несколько', 'ecommerce.countHint': 'Нажмите, чтобы изменить количество (1-4)', 'ecommerce.refSettings': 'Настройки референсов (необязательно)', 'ecommerce.styleTitle': 'Стиль / дополнения', 'ecommerce.protectedLabel': 'Обязательно сохранить (необязательно)', 'ecommerce.assetsFull': 'Не более 4 фото товара', 'ecommerce.productRefTitle': 'Референсы товара', 'ecommerce.productRefHint': 'Обязательно · фото товара, до 4 шт.', 'ecommerce.styleRefTitle': 'Референс стиля', 'ecommerce.styleRefBadge': 'опционально, 1 шт.', 'ecommerce.styleRefHint': 'Только стиль, свет, композиция и настроение — сам товар заменить нельзя.', 'ecommerce.styleRefUpload': 'Загрузить референс стиля', 'ecommerce.refInfoTitle': 'Параметры товара', 'ecommerce.aiWrite': 'ИИ-заполнить', 'ecommerce.aiWriting': 'ИИ составляет…', 'ecommerce.aiWriteHint': 'Составить параметры товара из названия и категории', 'ecommerce.promptInfoPlaceholder': 'Опционально: бренд и модель, характеристики, материалы, преимущества, сертификация, комплектация… или ИИ-заполнить', 'ecommerce.optional': 'опционально', 'ecommerce.previewBoardTitle': 'Предпросмотр перед генерацией', 'ecommerce.previewBoardHint': 'Промпт каждого изображения можно изменить до запуска', 'ecommerce.promptReset': 'Сбросить', 'ecommerce.promptAutoHint': 'Автоматически · можно изменить', 'ecommerce.promptPolish': 'ИИ-переписать', 'ecommerce.promptPolishing': 'Переписываем…', 'ecommerce.refSelect': 'Референс для этого назначения', 'ecommerce.refNone': 'Без референса', 'ecommerce.role.product': 'Товар', 'ecommerce.role.packaging': 'Упаковка', 'ecommerce.role.detail': 'Детали/ракурс', 'ecommerce.role.style': 'Стиль', 'ecommerce.footerReady': 'Будет сгенерировано {count} изображений', 'ecommerce.footerEmpty': 'Выберите структуру комплекта', 'ecommerce.results.title': 'Результаты комплекта', 'ecommerce.results.progress': '{done}/{total} готово', 'ecommerce.results.failed': '{count} с ошибкой', 'ecommerce.results.empty': 'После запуска генерации здесь появятся статус и результат каждого изображения', 'ecommerce.results.regenerate': 'Сгенерировать заново', 'ecommerce.results.export': 'Экспорт списка', 'ecommerce.results.newProduct': 'Новый товар', 'prompt.placeholder': 'Опишите желаемое изображение, например: рыжий кот в шлеме космонавта смотрит в телескоп на Луне, акварель, мягкий свет…', 'prompt.required': 'Введите промпт', 'prompt.count': '{count}', 'prompt.countLimit': '{count} / {limit}', 'prompt.overLimit': 'Превышен лимит промпта для этой модели ({limit} символов); сократите текст', 'prompt.enhance': 'Улучш.', 'prompt.enhancing': 'Улучшаем…', 'prompt.enhanceHint': 'Развернуть краткий промпт через настроенную диалоговую модель', 'prompt.configTitle': 'Сначала настройте модель улучшения промптов', 'prompt.configHint': 'Настройки генерации открыты. Укажите или переиспользуйте API-адрес и ключ, выберите диалоговую модель и сохраните.', 'tasks.title': 'Задачи генерации', 'tasks.queued': 'В очереди', 'tasks.running': 'Генерация', 'tasks.completed': 'Готово', 'tasks.failed': 'Ошибка', 'tasks.cancelled': 'Отменено', 'tasks.cancel': 'Отменить', 'tasks.retry': 'Повторить', // diagnostics (#38): the retained record of upstream attempts 'diagnostics.title': 'Диагностика', 'diagnostics.open': 'Диагностика', 'diagnostics.count': 'записей: {count}', 'diagnostics.refresh': 'Обновить', 'diagnostics.loading': 'Загрузка…', 'diagnostics.copy': 'Копировать всё', 'diagnostics.copied': 'Скопировано', 'diagnostics.clear': 'Очистить', 'diagnostics.empty': 'Записей пока нет. После сбоя генерации здесь появятся URL запроса, HTTP-статус, код сетевой ошибки и ответ провайдера.', 'diagnostics.hint': 'Хранится только в памяти хоста. Секреты скрыты, поэтому копию можно вставлять в issue.', 'diagnostics.response': 'Ответ провайдера', 'diagnostics.requestLabel': 'Запрос', 'diagnostics.exactUrl': 'точный URL', 'params.size': 'Размер', 'params.quality': 'Чёткость', 'params.count': 'Количество', 'params.detail': 'Детализация', 'size.auto': 'Авто', 'size.square': '1:1 квадрат', 'size.portrait34': '3:4 верт.', 'size.landscape43': '4:3 гориз.', 'size.portrait916': '9:16 верт.', 'size.portrait23': '2:3 верт.', 'size.landscape32': '3:2 гориз.', 'size.wide169': '16:9 шир.', 'size.ultrawide21': '21:9 ультрашир.', 'quality.auto': 'Авто', 'quality.1k': '1K', 'quality.2k': '2K', 'quality.4k': '4K', 'count.one': '1 шт.', 'count.two': '2 шт.', 'count.three': '3 шт.', 'count.four': '4 шт.', 'detail.auto': 'Авто', 'detail.standard': 'Стандарт', 'detail.high': 'Высокая', 'detail.hint': 'Сквозной параметр, поддерживают некоторые шлюзы gpt-image-2; для официального API оставьте «Авто»', 'model.label': 'Модель', 'model.channel': 'Канал', 'model.channelPlaceholder': 'Канал по умолчанию', 'model.noEditModels': 'В текущем режиме нет доступных моделей', 'compare.enable': 'Сравнение моделей', 'compare.models': 'Модели для сравнения', 'compare.title': 'Сравнение результатов моделей', 'compare.fullscreen': 'Полноэкранное сравнение', 'compare.selectRequired': 'Выберите хотя бы одну модель для сравнения', 'generate': 'Сгенерировать', 'generating': 'Генерация…', 'edit.upload': 'Нажмите или перетащите референс', 'edit.uploadHint': 'PNG / JPG / WEBP, до 10 МБ', 'edit.change': 'Заменить изображение', 'edit.remove': 'Убрать', 'edit.required': 'Сначала загрузите референс', 'edit.references': 'Референсы', 'edit.addedCount': 'Добавлено: {count}', 'edit.clearAll': 'Очистить', 'edit.uploadMultiple': 'Выберите или перетащите изображения', 'edit.addMore': 'Добавить референсы', 'edit.add': 'Добавить', 'edit.previewReference': 'Просмотр {index}: {name}', 'edit.removeReference': 'Удалить {index}: {name}', 'edit.multiHint': 'Можно выбрать несколько, перетащить или вставить', 'edit.limits': 'До {count} изображений · по 10 МБ · всего 16 МБ', 'edit.reading': 'Чтение изображений…', 'edit.referencePreview': 'Просмотр референса', 'edit.previousReference': 'Предыдущий референс', 'edit.nextReference': 'Следующий референс', 'edit.invalidFiles': 'Часть файлов пропущена: допустимы непустые PNG / JPG / WEBP / GIF до 10 МБ.', 'edit.limitReached': 'Не более {count} референсов; лишние пропущены.', 'edit.totalTooLarge': 'Суммарный размер не должен превышать 16 МБ; лишние файлы пропущены.', 'edit.readFailed': 'Не удалось прочитать часть изображений. Загрузите их снова.', 'edit.modelLimit': 'Адаптеры выбранных моделей поддерживают до {count} референсов. Смените модель или удалите лишние изображения.', 'canvas.emptyTitle': 'Начните творить', 'canvas.emptyHint': 'Двойной клик или нижняя панель добавляют узлы; соедините узлы изображений и текста с целевым узлом, выберите его и генерируйте внизу', 'canvas.new': 'Новая генерация', 'canvas.newHint': 'Начать новую генерацию и очистить просмотр', 'canvas.error': 'Ошибка генерации: {error}', 'canvas.submitting': 'Ставим в очередь…', 'canvas.queued': 'Задача в очереди', 'canvas.queueHint': 'Сейчас ожидают {count} задач', 'canvas.generating': 'Генерируем изображение…', 'canvas.elapsed': 'Прошло {seconds} с', 'canvas.images': 'Сгенерировано: {count}', 'download': 'Скачать', 'revisedPrompt': 'Улучшенный промпт: {prompt}', 'history.title': 'История', 'history.empty': 'Истории пока нет — созданные изображения появятся здесь', 'history.clear': 'Очистить', 'history.clearConfirm': 'Очистить всю историю? Действие необратимо.', 'history.restore': 'Восстановить', 'history.delete': 'Удалить', 'history.images': 'шт.', 'history.viewing': 'История · {time}', 'history.search': 'Поиск по промптам и моделям…', 'history.model': 'Фильтр по модели', 'history.ratio': 'Фильтр по пропорциям', 'history.allModels': 'Все модели', 'history.allRatios': 'Все пропорции', 'gallery.title': 'Материалы', 'gallery.categories': 'Категории', 'gallery.all': 'Все материалы', 'gallery.upload': 'Загрузить', 'gallery.uploadModel': 'Локальный файл', 'gallery.uploaded': 'Материал добавлен', 'gallery.uploadHint': 'Сохраните локальные изображения для холста', 'gallery.gpt': 'gpt-image-2', 'gallery.grok': 'grok-imagine-image', 'gallery.ratio': 'Пропорции', 'gallery.tags': 'Метки', 'gallery.filterHint': 'Фильтр галереи по режиму, модели и пропорциям', 'gallery.count': '· всего {count}', 'gallery.viewMode': 'Вид', 'gallery.masonry': 'Плитка', 'gallery.grid': 'Сетка', 'gallery.sort': 'Сортировка', 'gallery.newest': 'Сначала новые', 'gallery.oldest': 'Сначала старые', 'gallery.untitled': 'Без названия', 'gallery.search': 'Поиск по работам и моделям…', 'gallery.tagsPlaceholder': 'Метки через запятую', 'gallery.tagsApply': 'Добавить метки', 'gallery.editTags': 'Править метки', 'gallery.tagsEditShort': 'Правка', 'gallery.tagsSave': 'Сохранить', 'gallery.tagsCancel': 'Отмена', 'gallery.selected': 'Выбрано: {count}', 'gallery.selectionDone': 'Завершить выбор', 'gallery.selectionClear': 'Снять выбор', 'gallery.downloadSelected': 'Скачать выбранные', 'gallery.exportJson': 'Экспорт JSON', 'gallery.select': 'Выбрать работы', 'gallery.add': 'В галерею', 'gallery.added': 'Добавлено в галерею', 'gallery.already': 'Уже в галерее', 'gallery.delete': 'Убрать из галереи', 'gallery.openFolder': 'Открыть папку', 'gallery.clear': 'Очистить галерею', 'gallery.openFolderHint': 'Открыть каталог сохранения изображений (~/.dsh/dsh-imagegen) в проводнике', 'gallery.clearConfirm': 'Очистить всю галерею? Действие необратимо.', 'gallery.empty': 'Галерея пуста — добавьте понравившиеся изображения', 'gallery.viewing': 'Галерея · {time}', 'preview.title': 'Просмотр изображения', 'preview.open': 'Открыть просмотр', 'preview.close': 'Закрыть', 'preview.prev': 'Назад', 'preview.next': 'Вперёд', 'preview.index': '{index} / {total}', 'preview.zoomControls': 'Управление масштабом', 'preview.zoomIn': 'Увеличить', 'preview.zoomOut': 'Уменьшить', 'preview.zoomReset': 'Сбросить масштаб', 'preview.zoomLevel': '{percent}%', 'preview.copyPrompt': 'Копировать промпт', 'preview.copied': 'Скопировано', 'preview.addToEdit': 'В режим img2img', 'config.missing': 'API не настроен: откройте «Настройки → Настройки генерации» и заполните адрес и ключ API.', 'config.generationTitle': 'Сначала настройте API генерации', 'config.generationHint': '«Настройки → Настройки генерации» открыты. Укажите адрес и ключ API генерации и сохраните.', 'config.enhancementTitle': 'Сначала настройте модель улучшения промптов', 'config.enhancementHint': '«Настройки → Настройки генерации» открыты. Укажите или переиспользуйте адрес и ключ диалогового API, выберите модель и сохраните.', 'config.disabledTitle': 'Плагин ИИ-генерации отключён', 'config.disabledHint': '«Настройки → Настройки генерации» открыты. Включите плагин и запускайте генерацию.', 'config.configured': 'Подключено: {url}', 'config.disabled': 'Плагин отключён — включите его в настройках.', 'connection.connected': 'Подключено', 'connection.disconnected': 'Нет подключения', 'panel.collapseConfig': 'Свернуть параметры', 'panel.expandConfig': 'Развернуть параметры', 'update.available': 'Доступна новая версия: {version}', 'update.button': 'Обновить до v{version}', 'update.title': 'Доступна новая версия', 'update.close': 'Закрыть', 'update.noNotes': 'В этом релизе нет описания изменений.', 'update.installed': 'Обновлено', 'update.install': 'Обновить онлайн', 'update.installing': 'Обновляем…', 'update.success': 'Обновлено до {version}, перезапустите DSH', 'update.failed': 'Не удалось обновить', 'update.hostManaged': 'Нет интерфейса установки', 'update.hostHint': 'Встроенный менеджер DSH установит обновление в текущем окружении. После установки перезапустите DSH.', 'update.hostManagedHint': 'Текущий DSH не предоставляет интерфейс установки плагинов. Обновите DSH или скачайте пакет из Releases и установите способом, поддерживаемым приложением.', 'update.release': 'Открыть релиз', 'settings.title': 'ИИ-генерация (dsh-imagegen)', 'settings.description': 'Адрес и ключ API генерации изображений', 'settings.summaryTitle': 'Обзор настроек', 'settings.summaryHint': 'Нажмите карточку или заголовок группы, чтобы раскрыть детали; одновременно открыта только одна группа.', 'settings.summaryReady': 'Основные настройки готовы', 'settings.summaryNeedsSetup': 'Нужно настроить канал', 'settings.summaryNotConfigured': 'Не настроено', 'settings.summaryChannels': 'Готово {ready}/{total}', 'settings.summaryOptional': 'Необязательно', 'settings.summaryEnabled': 'Включено', 'settings.summaryDisabled': 'Выключено', 'settings.summaryChannelsLabel': 'Каналы и модели', 'settings.summaryPromptLabel': 'Улучшение промптов', 'settings.summaryStorageLabel': 'Синхронизация хранилища', 'settings.summarySkillsLabel': 'Навыки холста', 'settings.summaryGeneralLabel': 'Общие', 'settings.subscriptionLoggedIn': 'Вход выполнен', 'settings.subscriptionLoggedOut': 'Вход не выполнен', 'settings.subscriptionExperimental': 'Экспериментально: используется сторонний клиентский интерфейс, который может перестать работать после обновлений сервиса.', 'settings.subscriptionExperimentalTag': 'Эксперим.', 'settings.subscriptionLogin': 'Войти', 'settings.subscriptionLoggingIn': 'Ожидание входа…', 'settings.subscriptionLoginOk': 'Вход выполнен', 'settings.subscriptionLogout': 'Выйти', 'settings.subscriptionLoggingOut': 'Выходим…', 'settings.subscriptionIsolationHint': 'Токены хранятся только в DSH Credentials и изолированы от API-ключей.', 'settings.subscriptionDeviceCode': 'Введите этот код на странице авторизации: {code}', 'settings.subscriptionManualHint': 'Если браузер не может вернуться автоматически, вставьте итоговый URL или код авторизации.', 'settings.subscriptionManualPlaceholder': 'Вставьте URL перенаправления или код', 'settings.subscriptionManualComplete': 'Завершить вход', 'settings.headerNeedsChannel': 'Добавьте канал генерации изображений', 'settings.headerSummary': '{channels} каналов · {models} моделей', 'settings.skillsTitle': 'Навыки бесконечного холста', 'settings.generalTitle': 'Общие настройки', 'settings.generalHint': 'Общий переключатель, оповещение агентов и разрешение генерации', 'settings.currentVersion': 'Текущая версия', 'settings.apiUrl': 'Адрес API (api_url)', 'settings.apiUrlHint': 'База OpenAI-совместимого API, например https://api.openai.com/v1; /images/generations и /images/edits дописываются автоматически', 'settings.apiKey': 'Ключ API (api_key)', 'settings.apiKeyHint': 'Bearer-ключ хранится открыто в локальном документе настроек; интерфейс показывает лишь факт его наличия', 'settings.apiKeySet': 'Ключ сохранён; введите новый, чтобы заменить, или нажмите «Очистить»', 'settings.apiKeyClear': 'Очистить', 'settings.imageModelsTitle': 'Модели генерации', 'settings.imageModelsHint': 'После сохранения адреса и ключа будут найдены кандидаты; выбирайте только те, что реально умеют генерировать изображения.', 'settings.imageModels': 'Разрешённые модели генерации', 'settings.imageModelsManualHint': 'По одной модели в строке; можно заполнить вручную, если API не отдаёт /models. Панель и агент используют только этот список.', 'settings.imageModelsFetch': 'Найти модели', 'settings.imageModelsLoading': 'Ищем…', 'settings.imageModelsCandidates': 'Найденные кандидаты (отметьте и сохраните)', 'settings.addModel': '+ Добавить вручную', 'settings.cancelAddModel': 'Скрыть добавление', 'settings.addModelPlaceholder': 'Имя модели, например qwen-image', 'settings.addModelConfirm': 'Добавить', 'settings.removeModel': 'Удалить модель', 'settings.optional': 'необязательно', 'settings.moreOptions': 'Дополнительно', 'settings.localStoragePath': 'Локальная папка изображений', 'settings.localStoragePathHint': 'История, материалы и холст используют эту папку; пусто — ~/.dsh/dsh-imagegen.', 'settings.storageTitle': 'Синхронизация с объектным хранилищем', 'settings.storageEnabled': 'Включить синхронизацию', 'settings.storageHint': 'После сохранения локально изображения выгружаются в S3-совместимое хранилище (Tencent COS / Alibaba OSS / Qiniu S3 / MinIO / R2…)', 'settings.storageEndpoint': 'Адрес (с бакетом)', 'settings.storageEndpointHint': 'S3-совместимый URL, например https://bucket-appid.cos.ap-guangzhou.myqcloud.com', 'settings.storageRegion': 'Регион', 'settings.storageRegionHint': 'ID региона для подписи, например ap-guangzhou / oss-cn-hangzhou / cn-east-1', 'settings.storagePrefix': 'Префикс ключей', 'settings.storagePrefixHint': 'Ключи объекта: префикс/gallery|images/<файл>', 'settings.storageAccessKey': 'Access Key', 'settings.storageAccessKeyHint': 'S3-совместимый идентификатор ключа', 'settings.storageSecretKey': 'Secret Key', 'settings.storageSecretKeyHint': 'S3-совместимый секрет, хранится только в локальных настройках', 'settings.storageSyncGallery': 'Синхронизировать галерею', 'settings.storageSyncGalleryHint': 'Выгружать изображения при добавлении в галерею', 'settings.storageSyncHistory': 'Синхронизировать историю', 'settings.storageSyncHistoryHint': 'Также выгружать все результаты генерации (их может быть много)', 'settings.storageTest': 'Проверить соединение', 'settings.storageTesting': 'Проверяем…', 'settings.storageTestOk': 'Соединение в порядке ({ms} мс), тестовый файл загружен', 'settings.storageTestFailed': 'Ошибка соединения: {error}', 'settings.storageKeyHint': 'Синхронизация выполняется по возможности и никогда не блокирует локальное сохранение.', 'settings.promptEnhanceTitle': 'Модель улучшения промптов', 'settings.promptEnhanceHint': 'Разворачивает краткое описание в полноценный промпт; пустые адрес и ключ наследуют настройки генерации.', 'settings.promptApiUrl': 'Адрес диалогового API (необязательно)', 'settings.promptApiUrlHint': 'OpenAI-совместимая база; если пусто — используется адрес API генерации.', 'settings.promptApiKey': 'Ключ диалогового API (необязательно)', 'settings.promptApiKeyHint': 'Если пусто — используется ключ API генерации.', 'settings.promptModel': 'Диалоговая модель', 'settings.promptModelHint': 'Выберите или впишите модель с поддержкой /chat/completions.', 'settings.promptModelDetectionHint': 'По умолчанию используется API генерации; после поиска просто выберите модель.', 'settings.promptModelsFetch': 'Получить модели', 'settings.promptModelsLoading': 'Получаем…', 'settings.promptModelsSelect': 'Выберите модель', 'settings.promptModelsCandidates': 'Найденные диалоговые модели', 'settings.addPromptModelPlaceholder': 'Имя диалоговой модели, например gpt-4.1-mini', 'settings.promptApiAdvanced': 'Отдельный диалоговый API (необязательно)', 'settings.announceToAgent': 'Оповещать агентов о плагине', 'settings.announceToAgentHint': 'Включено — возможности плагина добавляются в системный промпт каждого агента', 'settings.allowAgentImageGeneration': 'Разрешить агентам генерацию', 'settings.allowAgentImageGenerationHint': 'Включено по умолчанию. Выключено — агенты не могут создавать, смотреть или отменять задачи; боковая панель работает.', 'settings.enabled': 'Включить плагин', 'settings.enabledHint': 'Выключено — панель генерации недоступна (карточка настроек работает всегда)', 'settings.save': 'Сохранить', 'settings.saving': 'Сохраняем…', 'settings.discard': 'Отменить правки', 'settings.unsaved': 'Есть несохранённые правки', 'settings.saveFailed': 'Не удалось сохранить, попробуйте ещё раз', 'settings.readOnly': 'Документ настроек сейчас только для чтения, сохранить нельзя.', 'settings.notExposed': 'Пространство настроек недоступно: этот деплой не предоставляет сервис настроек плагина.', 'settings.expand': 'Развернуть', 'settings.collapse': 'Свернуть', 'settings.inherit': 'Наследовать', 'settings.on': 'Вкл', 'settings.off': 'Выкл', 'settings.overridden': 'Переопределено', 'settings.reset': 'Сбросить', 'settings.invalidNumber': 'Введите корректное число', 'templates.open': 'Шаблоны', 'templates.shortLabel': 'Шаблоны', 'templates.resize': 'Изменить ширину', 'templates.recentsCount': 'Недавние: {count}', 'templates.recents': 'Недавние', 'templates.views': 'Виды библиотеки', 'templates.browse': 'Все шаблоны', 'templates.restore': 'Восстановить ширину', 'templates.fullscreen': 'На всю рабочую область', 'templates.searchScope': 'Область поиска', 'templates.currentSource': 'Текущая библиотека', 'templates.allSources': 'Все библиотеки', 'templates.recentsEmpty': 'Здесь появятся недавно использованные шаблоны', 'templates.applyStyle': 'Добавить к требованиям', 'templates.replace': 'Заменить промпт', 'templates.append': 'Дополнить промпт', 'templates.ecommerceHint': 'Шаблон добавляется к информации о товаре. Название, референсы и настройки сохраняются.', 'templates.title': 'Библиотека промпт-шаблонов', 'templates.sources': 'Источники шаблонов', 'templates.meta': 'Всего шаблонов: {count} · {origin}', 'templates.origin.bundled': 'встроенный снимок', 'templates.origin.refreshed': 'обновлено онлайн', 'templates.search': 'Поиск по названиям и промптам…', 'templates.all': 'Все', 'templates.close': 'Закрыть', 'templates.back': 'К списку', 'templates.use': 'Использовать промпт', 'templates.copy': 'Копировать промпт', 'templates.copied': 'Скопировано', 'templates.refresh': 'Обновить библиотеку', 'templates.refreshing': 'Обновляем…', 'templates.refreshed': 'Обновлено, шаблонов: {count}', 'templates.refreshFailed': 'Ошибка обновления: {error}', 'templates.favorites': 'Избранное', 'templates.favoritesCount': 'В избранном: {count}', 'templates.favoritesHint': 'Показать только избранные шаблоны', 'templates.favoritesEmpty': 'Пока пусто — нажмите звёздочку в углу карточки, чтобы сохранить шаблон', 'templates.favoriteAdd': 'Добавить в избранное', 'templates.favoriteRemove': 'Убрать из избранного', 'templates.favorite': 'В избранное', 'templates.unfavorite': 'В избранном', 'templates.cacheAll': 'Кэшировать все картинки', 'templates.cacheAllHint': 'Через локальный прокси сохранит все референсы этой библиотеки на диск — дальше доступно офлайн', 'templates.caching': 'Кэшируем {done}/{total}…', 'templates.cached': 'Все картинки закэшированы', 'templates.empty': 'Нет подходящих шаблонов', 'templates.loading': 'Загружаем библиотеку…', 'templates.loadFailed': 'Не удалось загрузить библиотеку: {error}', 'templates.retry': 'Повторить', 'templates.attribution': 'Шаблоны и изображения принадлежат сайтам-источникам; ссылки на авторов — в карточках', 'templates.source': 'Источник: {label}', 'templates.featured': 'Выбор редакции', 'inspiration.title': 'Вдохновение', 'inspiration.shuffle': 'Другие', 'inspiration.shuffling': 'Подбираем…', 'inspiration.useHint': 'Нажмите, чтобы использовать промпт', 'channels.title': 'Каналы', 'channels.hint': 'Укажите адрес и ключ API каждого канала — и модели станут доступны', 'channels.empty': 'Каналов пока нет — добавьте кнопкой ниже', 'channels.addProvider': 'Добавить провайдера', 'channels.addCustom': 'Добавить свой канал', 'channels.untitled': 'Канал без названия', 'channels.keySet': 'Ключ задан', 'channels.keyMissing': 'Ключ не задан', 'channels.modelCount': 'Моделей: {n}', 'channels.noModels': 'Модели не настроены', 'channels.defaultLabel': 'По умолчанию', 'channels.statusReady': 'Готов', 'channels.statusIncomplete': 'Настройка не завершена', 'channels.edit': 'Править', 'channels.done': 'Готово', 'channels.delete': 'Удалить', 'channels.deleteConfirmTitle': 'Удалить канал «{name}»? Ключ канала будет удалён; история и галерея сохранятся.', 'channels.confirm': 'Удалить', 'channels.cancel': 'Отмена', 'channels.editorTitle': 'Канал', 'channels.editorSaveNote': 'Изменения вступят в силу после «Сохранить» внизу карточки', 'channels.displayName': 'Название', 'channels.apiUrl': 'Адрес API', 'channels.protocol': 'Протокол', 'channels.protocolAuto': 'Автоопределение', 'channels.protocolImages': 'Images API', 'channels.protocolChat': 'Chat Completions', 'channels.protocolHint': 'Авто использует Chat, если полный URL заканчивается на /chat/completions; можно выбрать вручную.', 'channels.apiUrlFull': 'Полный URL', 'channels.apiUrlFullHint': 'Использовать URL как есть, без добавления /images/generations или /images/edits. Для Chat Completions /models всё ещё выводится из родительского пути.', 'channels.apiKey': 'Ключ API', 'channels.keyReplaceHint': 'Задан — введите новый, чтобы заменить', 'channels.keyMissingHint': 'Введите ключ', 'channels.keyClear': 'Очистить ключ', 'channels.showKey': 'Показать ключ', 'channels.hideKey': 'Скрыть ключ', 'channels.modelCatalogTitle': 'Каталог моделей', 'channels.noModelsHint': 'Моделей пока нет: нажмите «Найти» для списка кандидатов или добавьте вручную; псевдоним по умолчанию равен id модели и его можно менять.', 'channels.detectFirst': 'Найти модели', 'channels.detect': 'Найти снова', 'channels.detecting': 'Ищем…', 'channels.detectSuccess': 'Связь есть ✓ · кандидатов: {n}', 'channels.detectFailed': 'Ошибка поиска: {error}', 'channels.detectOk': 'API отвечает', 'channels.modelAliasLabel': 'Псевдоним (отображается)', 'channels.modelIdLabel': 'id модели у провайдера', 'channels.generated': 'Сгенерировано: {n}', 'channels.unknownProtocol': 'Протокол неизвестен — пробуем универсальный OpenAI', 'channels.removeModel': 'Удалить модель', 'channels.manualAddPlaceholder': 'id модели, например qwen-image', 'channels.addModelConfirm': 'Добавить', 'channels.copyFrom': 'Скопировать из канала…', 'channels.copyApply': 'Копировать', 'channels.candidatesTitle': 'Кандидаты (нажмите, чтобы добавить)', 'channels.deleteThisChannel': 'Удалить этот канал', 'channels.setDefault': 'Сделать каналом по умолчанию', 'channels.defaultModel': 'Модель изображений по умолчанию', 'channels.defaultModelHint': 'Используется первой в студии, на холсте, в ecommerce и инструментах Agent, если модель не указана. Вход «Изображение» в боковой панели всегда остаётся доступным.', 'channels.presetPickerTitle': 'Добавить провайдера', 'channels.presetPickerHint': 'Выберите встроенного провайдера — останется ввести только ключ API', 'channels.presetTabApiKey': 'API-ключ', 'channels.presetTabSubscription': 'Подписки', 'channels.presetPickerApiKeyHint': 'Обычные провайдеры с API-ключом; нужны адрес и ключ.', 'channels.presetPickerSubscriptionHint': 'Войдите один раз и используйте фиксированную модель без отдельного API-ключа.', 'channels.presetClickToLogin': 'Войти', 'channels.authMode': 'Аутентификация', 'channels.authModeApiKey': 'API-ключ', 'channels.authModeSubscription': 'Подписка / экспериментальный аккаунт', 'channels.subscriptionProvider': 'Аккаунт подписки', 'channels.presetSearch': 'Поиск провайдеров или моделей', 'channels.presetEmpty': 'Нет подходящих провайдеров', 'channels.presetCustomHint': 'Свой адрес, ключ и каталог моделей', 'channels.presetLoadFailed': 'Не удалось загрузить провайдеров: {error}', 'canvas.skills.fileNode': 'Узел файла', 'canvas.skills.addFileNode': 'Добавить узел файла', 'canvas.skills.emptyFileNode': 'Нажмите, чтобы загрузить файл', 'canvas.skills.fileMenuUpload': 'Загрузить файл', 'canvas.skills.fileDropHint': 'Перетащите файл сюда для загрузки', 'canvas.skills.fileDropSub': 'PDF / Office / текст / изображения, до 50 МБ', 'canvas.skills.fileSizeUnknown': 'Размер неизвестен', 'canvas.skills.filePreviewUnavailable': 'Для этого формата нет предпросмотра — скачайте файл или запустите навык', 'canvas.skills.filePreviewLoading': 'Загружаем предпросмотр…', 'canvas.skills.fileDownload': 'Скачать файл', 'canvas.skills.fileOpen': 'Открыть системным приложением', 'canvas.skills.fileKind.text': 'Текст', 'canvas.skills.fileKind.pdf': 'PDF', 'canvas.skills.fileKind.image': 'Изображение', 'canvas.skills.fileKind.office': 'Документ', 'canvas.skills.fileKind.archive': 'Архив', 'canvas.skills.fileKind.audio': 'Аудио', 'canvas.skills.fileKind.video': 'Видео', 'canvas.skills.fileKind.other': 'Файл', 'canvas.skills.fileTooLarge': 'Файл превышает лимит {size} МБ', 'canvas.skills.fileTypeBlocked': 'Файлы {ext} не загружаются из соображений безопасности', 'canvas.skills.fileUploadFailed': 'Не удалось загрузить: {message}', 'canvas.preview.expand': 'Открыть предпросмотр', 'canvas.preview.close': 'Закрыть предпросмотр', 'canvas.preview.copy': 'Скопировать содержимое', 'canvas.preview.copied': 'Скопировано', 'canvas.preview.openTab': 'Открыть в новой вкладке', 'canvas.preview.retry': 'Повторить', 'canvas.preview.failed': 'Не удалось прочитать предпросмотр: {message}', 'canvas.preview.empty': 'Файл пуст', 'canvas.preview.textTruncated': 'Большой файл — показаны первые {chars} символов', 'canvas.preview.tableTruncated': 'Большая таблица — показаны первые {rows} строк', 'canvas.preview.archiveTruncated': 'Много записей — показаны первые {count}', 'canvas.preview.docTruncated': 'Длинный документ — показаны первые {blocks} блоков', 'canvas.preview.slidesTruncated': 'Большая презентация — показаны первые {count} слайдов', 'canvas.preview.slideOf': 'Слайд {page}', 'canvas.preview.rendered': 'Рендер', 'canvas.preview.source': 'Исходник', 'canvas.preview.pdfFallback': 'В этой среде PDF не отображается встроенно — скачайте файл', 'canvas.preview.pdfHeuristic': 'Текст PDF извлекается эвристически; сложная вёрстка может потерять порядок', 'canvas.preview.reason.unsupported': 'В этом формате нет читаемого содержимого — скачайте файл или превратите его в узел изображения или текста для навыка', 'canvas.preview.reason.unreadable': 'Из файла не удалось извлечь текст (скан или необычная кодировка); преобразуйте его в узел изображения для визуальной модели', 'canvas.preview.doubleClick': 'Двойной щелчок открывает предпросмотр', 'canvas.skills.button': 'Навык', 'canvas.skills.menuTitle': 'Запустить навык', 'canvas.skills.runOn': 'Запустить навык на «{name}»', 'canvas.skills.pickerTitle': 'Выберите навык', 'canvas.skills.searchPlaceholder': 'Поиск навыков…', 'canvas.skills.groupBuiltin': 'Встроенные действия', 'canvas.skills.groupExternal': 'Локальные навыки', 'canvas.skills.emptyExternal': 'Локальных навыков нет — установите их в ~/.dsh/skills и обновите', 'canvas.skills.empty': 'Навыки недоступны', 'canvas.skills.loading': 'Загружаем список навыков…', 'canvas.skills.tierLight': 'Быстро', 'canvas.skills.tierHeavy': 'Долгая задача', 'canvas.skills.accepts': 'Работает с: {types}', 'canvas.skills.incompatible': 'Навык не применим к этому типу узла', 'canvas.skills.disabled': 'Навыки холста отключены в настройках плагина', 'canvas.skills.noRegistry': 'В этом хосте нет реестра навыков (ctx.skills) — доступны только встроенные действия', 'canvas.skills.registryFailed': 'Не удалось получить список навыков: {message}', 'canvas.skills.needAgent': 'Нужен агентный рантайм хоста, которого нет в этой сборке DSH — долгие задачи недоступны', 'canvas.skills.unknown': 'Такого навыка больше нет', 'canvas.skills.canvasMissing': 'Холст не найден — обновите страницу и повторите', 'canvas.skills.noInput': 'У этого узла нет данных для обработки', 'canvas.skills.noChat': 'Быстрым навыкам нужна чат-модель: откройте «Настройки → Настройки генерации» → «Улучшение промпта»', 'canvas.skills.noDescription': '(описание не указано)', 'canvas.skills.externalName': '{name}', 'canvas.skills.externalSystem': 'Вы выполняете навык «{name}». Строго следуйте его инструкциям для входа ниже, отвечайте на языке входа и выводите только результат — не пересказывайте инструкции.', 'canvas.skills.externalHeader': 'Примените навык «{name}» к данным ниже.', 'canvas.skills.externalHeavyCost': 'Это долгая задача: запускается безголовый агент и может израсходовать много квоты модели.', 'canvas.skills.extraInstruction': 'Дополнительное требование:', 'canvas.skills.inputsHeader': 'Входные данные:', 'canvas.skills.inputsEmpty': '(читаемого текста нет — работайте по приложенным изображениям)', 'canvas.skills.needInstruction': 'Введите своё указание для обработки', 'canvas.skills.needImage': 'Этому навыку нужен узел изображения', 'canvas.skills.needText': 'Этому навыку нужен текстовый узел с содержимым', 'canvas.skills.fileMissing': 'Файловый ресурс отсутствует или удалён', 'canvas.skills.extractFailed': 'Из этого файла не удалось извлечь содержимое', 'canvas.skills.nothingToRead': 'Читаемого содержимого не найдено', 'canvas.skills.truncated': 'Содержимое обрезано до {count} символов', 'canvas.skills.tooManyImages': 'Изображений больше {count} — обработаны только первые', 'canvas.skills.extractNodeTitle': 'Содержимое «{name}»', 'canvas.skills.summaryHead': 'Собрано узлов-источников: {count}', 'canvas.skills.describeAsk': 'Опишите эти изображения ({count}).', 'canvas.skills.polishNodeTitle': 'Результат обработки ({style})', 'canvas.skills.skillMissing': 'Навык «{name}» не установлен. Сначала установите его (например, попросите агента DSH установить https://github.com/ningzimu/image-to-editable-ppt-skill) и повторите.', 'canvas.skills.agentFailed': 'Не удалось создать безголового агента — проверьте модель и пресет агента', 'canvas.skills.needModel': 'Хост не публикует модель по умолчанию (agent-default-model), поэтому долгая задача не может запустить агента. Выберите модель по умолчанию в «Настройки → Общие» и повторите.', 'canvas.skills.noOutputFile': 'Навык не создал файл; ответ агента сохранён текстовым узлом', 'canvas.skills.heavyIntro': 'Вы выполняете навык «{name}» для визуального холста. Пройдите всю процедуру строго по документации, не пропуская шагов.', 'canvas.skills.heavyBodyHeader': 'Инструкции навыка:', 'canvas.skills.heavyInputsHeader': 'Входные файлы задачи (абсолютные пути):', 'canvas.skills.heavyOutputHeader': 'Запишите итоговый артефакт в этот каталог: {dir}', 'canvas.skills.heavyRules': 'Требования:\n1. Все промежуточные файлы держите в рабочем каталоге; итоговый артефакт — только в каталоге выше.\n2. По завершении коротко ответьте: имена файлов, успех, замечания.', 'canvas.skills.heavyAsk': 'Выполните навык «{name}».', 'canvas.skills.heavyAskInputs': 'Каталог входных файлов: {dir}', 'canvas.skills.heavyAskOutput': 'Каталог вывода: {dir}', 'canvas.skills.heavyAskLoadSkill': '(Если инструкций навыка нет в контексте, сначала загрузите их по имени «{name}».)', 'canvas.skills.stageQueued': 'В очереди', 'canvas.skills.stagePreparing': 'Готовим входные файлы', 'canvas.skills.stageReading': 'Читаем содержимое узлов', 'canvas.skills.stageRunning': 'Навык выполняется', 'canvas.skills.stageCollecting': 'Собираем артефакты', 'canvas.skills.stageDone': 'Готово', 'canvas.skills.stageCancelled': 'Отменено', 'canvas.skills.stagePrepared': 'Подготовлено входных файлов: {count}', 'canvas.skills.stageArtifacts': 'Выполняется — создано файлов: {count}', 'canvas.skills.runElapsed': 'Прошло', 'canvas.skills.runRetry': 'Повторить', 'canvas.skills.runStarted': 'Навык «{name}» запущен', 'canvas.skills.runDone': 'Навык завершён — новых узлов: {count}', 'canvas.skills.runFailed': 'Навык завершился ошибкой: {message}', 'canvas.skills.runCancelled': 'Запуск навыка отменён', 'canvas.skills.cancel': 'Отменить запуск', 'canvas.skills.cancelling': 'Отменяем…', 'canvas.skills.confirmTitle': 'Запустить долгую задачу', 'canvas.skills.confirmBody': '«{name}» запускает безголового агента на этой машине. Это может занять от нескольких до десятков минут и израсходовать много квоты модели.', 'canvas.skills.confirmCost': 'Стоимость: {hint}', 'canvas.skills.confirmRequires': 'Требуется: {list}', 'canvas.skills.confirmRun': 'Запустить', 'canvas.skills.confirmCancel': 'Не сейчас', 'canvas.skills.batchTitle': 'Пакетный запуск', 'canvas.skills.batchNote': 'Запуск по одному узлу подряд (узлов: {count})', 'canvas.skills.batchTooMany': 'Не более {count} узлов за запуск', 'canvas.skills.sourceBadge': 'Результат навыка', 'canvas.skills.sourceTip': 'Создано навыком «{name}» из узлов-источников: {count}', 'canvas.skills.rerun': 'Запустить тот же навык снова', 'canvas.skills.history': 'История запусков', 'canvas.skills.historyEmpty': 'Запусков пока нет', 'canvas.skills.needConfirm': 'Этот навык требует подтверждения', 'canvas.skills.polish': 'Обработка текста', 'canvas.skills.polishDesc': 'Переписать текстовый узел в выбранном стиле: формальнее / разговорнее / короче / подробнее или своё указание', 'canvas.skills.describe': 'Описание изображения', 'canvas.skills.describeDesc': 'Прочитать изображение визуальной моделью и создать текстовый узел (годится как промпт)', 'canvas.skills.extract': 'Извлечь содержимое', 'canvas.skills.extractDesc': 'Извлечь текст из файла или изображения в текстовый узел (текст / код / OOXML / PDF)', 'canvas.skills.ppt': 'Изображение → редактируемый PPT', 'canvas.skills.pptDesc': 'Запускает локальный навык image-to-editable-ppt и создаёт редактируемый .pptx как узел файла', 'canvas.skills.pptCost': 'Долгая задача: презентация на 10 страниц может израсходовать много квоты; одна страница часто занимает 10+ минут', 'canvas.skills.pptRequires': 'Нужен установленный навык image-to-editable-ppt, а также токен OCR и образный бэкенд по его документации', 'canvas.polish.button': 'ИИ-обработка', 'canvas.polish.title': 'ИИ-обработка текста', 'canvas.polish.formal': 'Формальнее', 'canvas.polish.casual': 'Разговорнее', 'canvas.polish.shorter': 'Короче', 'canvas.polish.expand': 'Подробнее', 'canvas.polish.custom': 'Своё', 'canvas.polish.customPlaceholder': 'напр. переписать как пост для соцсети с эмодзи и хэштегами', 'canvas.polish.run': 'Обработать', 'canvas.polish.previewTitle': 'Было / стало', 'canvas.polish.apply': 'Применить', 'canvas.polish.revert': 'Вернуть', 'canvas.polish.applied': 'Результат применён', 'canvas.polish.directHint': 'Текущая настройка: результат сразу заменяет текст (в настройках можно включить предпросмотр)', 'settings.skillsEnabled': 'Навыки холста', 'settings.skillsEnabledHint': 'Включить систему навыков на узлах бесконечного холста (встроенные действия и локальные навыки)', 'settings.allowHeavySkills': 'Разрешить долгие задачи', 'settings.allowHeavySkillsHint': 'Долгие задачи запускают безголового агента DSH на этой машине — это медленно и расходует квоту. Выключите, чтобы оставить только быстрые навыки.', 'settings.skillAllowlist': 'Белый список навыков', 'settings.skillAllowlistHint': 'Имена навыков через запятую или с новой строки; пусто — разрешены все локальные навыки', 'settings.skillOutputDir': 'Рабочий каталог долгих задач', 'settings.skillOutputDirHint': 'Рабочий каталог безголовых агентов (пусто — canvas/runs в каталоге данных)', 'settings.skillHeavyTimeout': 'Таймаут долгой задачи (минуты)', 'settings.skillHeavyTimeoutHint': 'Через это время долгая задача отменяется; 0 — без таймаута', 'settings.skillAgentPreset': 'Пресет агента для долгих задач', 'settings.skillAgentPresetHint': 'Пресет агента для долгих задач; пусто — пресет хоста по умолчанию', 'settings.skillProbe': 'Проверить окружение навыков', 'settings.skillProbing': 'Проверяем…', 'settings.skillProbeOk': 'Доступно навыков: {count} · безголовый агент: {agent}', 'settings.skillProbeAgentOn': 'доступен', 'settings.skillProbeAgentOff': 'недоступен', 'settings.skillsHint': 'Совет: установите навыки вроде image-to-editable-ppt в ~/.dsh/skills, чтобы превращать изображения в редактируемые презентации прямо на холсте.', 'canvas.skills.libraryButton': 'Библиотека навыков', 'canvas.skills.libraryTitle': 'Библиотека навыков', 'canvas.skills.libraryInstalled': 'Установленные навыки ({count})', 'canvas.skills.libraryEmpty': 'Навыков пока нет. Установите по ссылке на репозиторий или загрузите архив.', 'canvas.skills.libraryRoot': 'Каталог установки: {root}', 'canvas.skills.libraryInstall': 'Установка по ссылке', 'canvas.skills.libraryInstallHint': 'Репозиторий или папка GitHub, отдельный SKILL.md, любой git-адрес или ссылка на zip; несколько ссылок — с новой строки. Хост подхватывает установку без перезапуска.', 'canvas.skills.libraryUrlPlaceholder': 'https://github.com/owner/repo или …/blob/main/SKILL.md', 'canvas.skills.libraryUpload': 'Загрузить архив', 'canvas.skills.libraryUploadHint': 'Загрузите zip с файлом SKILL.md (≤50 МБ): он распакуется в ~/.dsh/skills.', 'canvas.skills.libraryDropzone': 'Нажмите или перетащите zip-архив сюда', 'canvas.skills.libraryForce': 'Заменить навык с тем же именем', 'canvas.skills.libraryInstallAction': 'Установить', 'canvas.skills.libraryInstalling': 'Установка…', 'canvas.skills.libraryRemove': 'Удалить', 'canvas.skills.libraryRemoving': 'Удаление…', 'canvas.skills.libraryRemoveConfirm': 'Удалить навык «{name}»? Его папка будет стёрта.', 'canvas.skills.libraryInstalledToast': 'Установлено: {names}', 'canvas.skills.libraryFailedToast': 'Ошибка установки: {message}', 'canvas.skills.libraryRemovedToast': 'Удалено: {name}', 'canvas.skills.libraryUnavailable': 'Этот хост не управляет библиотекой навыков', 'canvas.skills.libraryReload': 'Обновить', 'canvas.skills.libraryOpenFolder': 'Открыть каталог', 'canvas.skills.installNow': 'Установить', 'canvas.skills.needsInstall': 'Не установлен', 'canvas.skills.missingHint': 'Навык «{name}» ещё не установлен — установите его, чтобы использовать', 'canvas.skills.installArchiveFailed': 'Ошибка установки архива: {message}', 'canvas.skills.libraryIssueFrontmatter': 'Нет YAML frontmatter (нужны name и description), поэтому реестр навыков хоста его не загружает и узлы не могут его запустить', 'canvas.skills.libraryIssueName': 'Имя в frontmatter «{name}» не в kebab-case (строчные буквы, цифры и дефисы), поэтому реестр навыков хоста его игнорирует и узлы не могут его запустить', 'canvas.skills.libraryIssueDescription': 'В frontmatter файла SKILL.md нет description (обязательно), поэтому реестр навыков хоста его не загружает и узлы не могут его запустить', 'canvas.skills.libraryIssueInvocation': 'Запись disable-model-invocation / user-invocable не разбирается, поэтому реестр навыков хоста его игнорирует и узлы не могут его запустить', 'canvas.skills.libraryIssueUserOnly': 'Навык объявляет disable-model-invocation: он доступен только человеку, поэтому узлы холста не могут его запустить', 'canvas.skills.configOpen': 'Настроить', 'canvas.skills.configSave': 'Сохранить', 'canvas.skills.configSaveApply': 'Сохранить и применить', 'canvas.skills.configSaving': 'Сохранение…', 'canvas.skills.configApplying': 'Применение…', 'canvas.skills.configSaved': 'Сохранено', 'canvas.skills.configSaveFailed': 'Не удалось сохранить', 'canvas.skills.configApplied': 'Сохранено и применено', 'canvas.skills.configApplyFailed': 'Не удалось применить', 'canvas.skills.configClear': 'Очистить', 'canvas.skills.configSecretSet': 'Задан (пустое поле оставит как есть)', 'canvas.skills.configSecretUnset': 'Не задан', 'canvas.skills.configMissingHint': 'Требуется настройка: {fields}', 'canvas.skills.configGo': 'Настроить', 'canvas.skills.configSourceSkill': 'Поля объявлены собственным skill.config.json навыка', 'canvas.skills.configSourcePlugin': 'Поля взяты из встроенного рецепта плагина для известного навыка (собственное объявление навыка важнее)', 'canvas.skills.configHeader': 'Уже настроено:', 'canvas.skills.configUnwritable': 'Этот хост не может записывать настройки, поэтому настройка навыков недоступна', 'canvas.skills.configIssueVersion': 'В skill.config.json указана версия, отличная от 1, поэтому объявление проигнорировано', 'canvas.skills.configIssueUnreadable': 'skill.config.json не удалось разобрать (ошибка JSON), поэтому объявление проигнорировано', 'canvas.skills.configIssueEmpty': 'В skill.config.json нет пригодных полей или шагов, поэтому он проигнорирован', }