From 8f7e992b841e90e97e9615fe6b9ff8f5361533c8 Mon Sep 17 00:00:00 2001 From: potaser Date: Sun, 9 Aug 2026 04:07:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E8=AF=AD=E8=A8=80=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E4=B8=8E=E9=A6=96=E9=A1=B5=E5=BC=95=E7=94=A8=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- apps/web/vue3/agent_status_component_ml.html | 416 + apps/web/vue3/index-with-sidebar_ml.html | 391 + apps/web/vue3/index.html | 129 +- apps/web/vue3/index_ml.html | 23874 ++++++++++++++++ apps/web/vue3/kg_ml.html | 712 + apps/web/vue3/lightWeightExtensionTest.js | 304 + apps/web/vue3/main.py | 210 +- apps/web/vue3/static/cdn/en.js | 165 + apps/web/vue3/static/cdn/en.mjs | 165 + apps/web/vue3/static/cdn/zh-cn.js | 130 + apps/web/vue3/static/cdn/zh-cn.mjs | 130 + apps/web/vue3/static/conversation-sidebar.js | 728 +- apps/web/vue3/static/i18n.js | 1911 ++ apps/web/vue3/static/i18n_en.js | 380 + gfa_core/extension_stage_lightweight/api.py | 4 + .../extension_stage_lightweight/service.py | 20 +- 17 files changed, 29290 insertions(+), 382 deletions(-) create mode 100755 apps/web/vue3/agent_status_component_ml.html create mode 100755 apps/web/vue3/index-with-sidebar_ml.html create mode 100644 apps/web/vue3/index_ml.html create mode 100755 apps/web/vue3/kg_ml.html create mode 100644 apps/web/vue3/lightWeightExtensionTest.js create mode 100644 apps/web/vue3/static/cdn/en.js create mode 100644 apps/web/vue3/static/cdn/en.mjs create mode 100644 apps/web/vue3/static/cdn/zh-cn.js create mode 100644 apps/web/vue3/static/cdn/zh-cn.mjs create mode 100644 apps/web/vue3/static/i18n.js create mode 100644 apps/web/vue3/static/i18n_en.js diff --git a/.gitignore b/.gitignore index d5e2ea7f0..eedcfcbf5 100755 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ outputs/ input/ workspace/ paper/ -memory/ +#memory/ memory_storage/ backup/ backups/ @@ -29,3 +29,4 @@ nohup.out Rplots.pdf *.pyc *.log +.gitignore diff --git a/apps/web/vue3/agent_status_component_ml.html b/apps/web/vue3/agent_status_component_ml.html new file mode 100755 index 000000000..dead607b1 --- /dev/null +++ b/apps/web/vue3/agent_status_component_ml.html @@ -0,0 +1,416 @@ + + + + +// Agent状态组件 +const AgentStatusComponent = { + template: '#agent-status-component', + + data() { + return { + messages: [], + userInput: '', + isProcessing: false, + currentMode: '', + sessionId: '', + tasks: [], + currentTask: null, + pollingInterval: null + }; + }, + + mounted() { + this.sessionId = 'session_' + Date.now(); + this.currentMode = t('standby'); + this.loadTasks(); + this.startPolling(); + }, + + beforeUnmount() { + this.stopPolling(); + }, + + methods: { + async sendMessage() { + if (!this.userInput.trim() || this.isProcessing) return; + + const message = this.userInput.trim(); + this.userInput = ''; + this.isProcessing = true; + + // 添加用户消息 + this.addMessage('user', message); + + try { + // 调用Agent执行API + const response = await fetch('/api/agent/execute', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + message: message, + session_id: this.sessionId, + model: 'kimi' + }) + }); + + const data = await response.json(); + + if (data.success) { + this.currentTask = data.task_id; + this.addMessage('system', t('msg-task-submitted') + data.task_id); + this.loadTasks(); + } else { + this.addMessage('error', data.message || t('msg-submit-failed')); + } + } catch (error) { + this.addMessage('error', t('msg-request-failed') + error.message); + } + + this.isProcessing = false; + }, + + async loadTasks() { + try { + const response = await fetch('/api/agent/tasks'); + const data = await response.json(); + + if (data.success) { + this.tasks = data.tasks; + } + } catch (error) { + console.error(t('msg-load-task-failed'), error); + } + }, + + async checkTaskStatus(taskId) { + try { + const response = await fetch(`/api/agent/status/${taskId}`); + const data = await response.json(); + + if (data.success && data.task) { + const task = data.task; + + // 更新任务状态 + const taskIndex = this.tasks.findIndex(t => t.task_id === taskId); + if (taskIndex >= 0) { + this.tasks[taskIndex] = { ...this.tasks[taskIndex], ...task }; + } + + // 如果任务完成,显示结果 + if (task.status === 'completed' && task.result) { + this.addMessage('assistant', task.result.response || t('msg-task-completed')); + + // 显示执行结果摘要 + if (task.result.execution_result) { + const execResult = task.result.execution_result; + if (execResult.status === 'success') { + const manifest = execResult.manifest || {}; + const metrics = manifest.metrics || {}; + this.addMessage('system', + t('msg-analysis-complete') + (metrics.final_members || 0) + t('msg-gene-members')); + } + } + } else if (task.status === 'failed') { + this.addMessage('error', task.result?.response || t('msg-task-failed')); + } + } + } catch (error) { + console.error(t('msg-check-task-status-failed'), error); + } + }, + + selectTask(task) { + this.currentTask = task.task_id; + this.checkTaskStatus(task.task_id); + }, + + startPolling() { + this.pollingInterval = setInterval(() => { + if (this.currentTask) { + this.checkTaskStatus(this.currentTask); + } + this.loadTasks(); + }, 3000); // 每3秒轮询一次 + }, + + stopPolling() { + if (this.pollingInterval) { + clearInterval(this.pollingInterval); + } + }, + + addMessage(role, content) { + this.messages.push({ + role: role, + content: content, + timestamp: new Date().toISOString() + }); + + // 滚动到底部 + setTimeout(() => { + const container = this.$refs.messageContainer; + if (container) { + container.scrollTop = container.scrollHeight; + } + }, 100); + }, + + getRoleLabel(role) { + const keys = { + 'user': 'user-role', + 'assistant': 'agent-role', + 'system': 'system-role', + 'error': 'error-role', + 'execution': 'execution-role', + 'planning': 'planning-role', + 'diagnosis': 'diagnosis-role' + }; + return keys[role] ? t(keys[role]) : role; + }, + + getStatusIcon(status) { + const icons = { + 'pending': '⏳', + 'running': '🔄', + 'completed': '✅', + 'failed': '❌', + 'cancelled': '🚫' + }; + return icons[status] || '❓'; + }, + + formatMessage(content) { + // 简单的Markdown格式化 + return content + .replace(/\*\*(.+?)\*\*/g, '$1') + .replace(/\n/g, '
'); + }, + + formatTime(timestamp) { + if (!timestamp) return ''; + const date = new Date(timestamp); + return date.toLocaleTimeString('zh-CN', { + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + }, + + t(key) { + return window.t ? window.t(key) : key; + } + } +}; + + + \ No newline at end of file diff --git a/apps/web/vue3/index-with-sidebar_ml.html b/apps/web/vue3/index-with-sidebar_ml.html new file mode 100755 index 000000000..05f6b5d3b --- /dev/null +++ b/apps/web/vue3/index-with-sidebar_ml.html @@ -0,0 +1,391 @@ + + + + + + + BotanicalBaseAgent + + + + + + + + +
+ +
+

{{ t('gf-analysis-system') }}

+
+ +
+ +
+ +
+ + + + +
+
+
{{ t('conv-list') }}
+
+
+ +
+
+
{{ conv.title }}
+
+ {{ conv.gene_family }} + {{ conv.message_count }}{{ t('msg-count') }} +
+
+
+
+
+
+ + +
+
{{ t('analysis-stage') }}
+ + + + + + + + + {{ t('execute-analysis') }} + +
+ + +
+
{{ t('param-settings') }}
+ + + + + + + + +
+
+ + +
+
+
+
+ {{ msg.role === 'user' ? t('user') : t('ai-assistant') }} · {{ msg.time }} +
+
{{ msg.content }}
+
+
+ +

{{ t('start-new-chat') }}

+

{{ t('or-continue') }}

+
+
+ +
+ + + + {{ t('send') }} + +
+
+ + +
+
📊 Analysis Results
+ +
+
+ {{ stage.label }} + {{ stage.statusText }} +
+ +
+ + + +
+ +

{{ t('results-here') }}

+
+
+
+
+ + + + diff --git a/apps/web/vue3/index.html b/apps/web/vue3/index.html index 8f97daaae..7b228b2cc 100644 --- a/apps/web/vue3/index.html +++ b/apps/web/vue3/index.html @@ -1389,10 +1389,13 @@ 名称 原始命令 环境 - - - - + + + 原始代码 @@ -1419,6 +1422,10 @@
+
+ 拖入拓展包到此自动填充 +
+ +
+
拖入固定结构拓展包
+
要求包含 raw_code/run.sh 与 raw_test_data/,系统会自动创建 Job、解析环境并开始 lightweight upload。
+ +
+ {{ lightweightExtensionTestStatus }} + 选择文件夹 +
+
+ @@ -7774,6 +7795,7 @@ RNA-seq KEGG/fgsea 会优先使用物种级 KEGG gene set;没有物种级缓 working_dir: '', output_dir: '' }); + const lightweightExtensionTestStatus = ref('拖入固定结构文件夹,系统将自动创建 Job、解析环境并开始 upload。'); const activeRnaseqScopeId = ref(''); const activeGenotypeScopeId = ref(''); @@ -9128,6 +9150,7 @@ RNA-seq KEGG/fgsea 会优先使用物种级 KEGG gene set;没有物种级缓 statusDialogVisible: false, statusEvents: [] }); + const extensionEnvOptions = ref(['test4py311', 'rnaseq', 'rnaR']); const lightweightExtensions = ref([]); const lightweightExtensionConversation = reactive({ cards: [], @@ -19489,6 +19512,10 @@ compare: [[flesh, peel]]`; }; const extensionFileKey = (file) => `${file?.name || ''}::${file?.size || 0}::${file?.lastModified || 0}`; + const extensionUploadPath = (file) => { + const relative = String(file?.lightweightRelativePath || '').trim().replace(/^\/+/, ''); + return relative || String(file?.name || '').trim(); + }; const appendExtensionFiles = (target, files) => { const current = Array.isArray(target) ? target : []; const merged = [...current]; @@ -19514,6 +19541,53 @@ compare: [[flesh, peel]]`; if (selected.length) ElMessage.success(`已选择 ${selected.length} 个测试数据文件`); event.target.value = ''; }; + const handleLightweightExtensionFolderDrop = (event) => { + const droppedFiles = Array.from(event?.dataTransfer?.files || []); + if (!droppedFiles.length) { + ElMessage.warning('未检测到可用文件'); + return; + } + + const codeExtPattern = /\.(py|r|sh|bash|pl|js|ts|java|c|cc|cpp|go|rs|jl|rb|m|smk|nf|ipynb)$/i; + const dataExtPattern = /\.(fastq|fq|gz|fa|fasta|fna|faa|pep|cds|gff|gff3|gtf|csv|tsv|txt|xlsx|xls|vcf|sam|bam)$/i; + + const normalized = droppedFiles.map((file) => { + const relativePath = file.webkitRelativePath || file.name; + if (!file.lightweightRelativePath) { + Object.defineProperty(file, 'lightweightRelativePath', { + value: relativePath, + configurable: true + }); + } + return file; + }); + + const codeFiles = []; + const dataFiles = []; + normalized.forEach((file) => { + const filePath = extensionUploadPath(file).toLowerCase(); + if (codeExtPattern.test(filePath)) { + codeFiles.push(file); + } else if (dataExtPattern.test(filePath)) { + dataFiles.push(file); + } else { + codeFiles.push(file); + } + }); + + extensionBuild.codeFiles = appendExtensionFiles(extensionBuild.codeFiles, codeFiles); + extensionBuild.dataFiles = appendExtensionFiles(extensionBuild.dataFiles, dataFiles); + + if (!extensionBuild.displayName) { + const firstPath = normalized[0]?.webkitRelativePath || normalized[0]?.name || ''; + const folder = firstPath.includes('/') ? firstPath.split('/')[0] : ''; + if (folder) { + extensionBuild.displayName = folder.replace(/[^a-zA-Z0-9_-]+/g, '_'); + } + } + + ElMessage.success(`已拖入 ${normalized.length} 个文件,已自动填充拓展包`); + }; const removeExtensionFile = (kind, file) => { const key = extensionFileKey(file); if (kind === 'code') { @@ -19546,9 +19620,10 @@ compare: [[flesh, peel]]`; }; const extensionApiUrl = (path) => { const value = String(path || ''); - if (!value.startsWith('/api/extension-stages') && !value.startsWith('/api/extension-stage-runs')) return value; + if (!value.startsWith('/api/extension-stages') && !value.startsWith('/api/extension-stage-runs') && !value.startsWith('/api/lightweight-extension-stages')) return value; const host = window.location.hostname || '127.0.0.1'; - return `${window.location.protocol}//${host}:7880${value}`; + const port = window.location.port; + return port ? `${window.location.protocol}//${host}:${port}${value}` : `${window.location.protocol}//${host}${value}`; }; const extensionApiFetch = async (path, options = {}) => fetch(extensionApiUrl(path), options); const pushExtensionStatus = (message, type = 'info', showDialog = false) => { @@ -19909,9 +19984,10 @@ compare: [[flesh, peel]]`; form.append('extension_id', extensionId); if (hasCommand) form.append('original_command', extensionBuild.command); form.append('operation_token', token); - extensionBuild.codeFiles.forEach(file => form.append('raw_code_files', file)); - extensionBuild.dataFiles.forEach(file => form.append('raw_data_files', file)); + extensionBuild.codeFiles.forEach(file => form.append('raw_code_files', file, extensionUploadPath(file))); + extensionBuild.dataFiles.forEach(file => form.append('raw_data_files', file, extensionUploadPath(file))); if (hasDataPaths) form.append('raw_data_paths', extensionBuild.dataPaths); + form.append('runtime_env', extensionBuild.runtimeEnv); const response = await extensionApiFetch('/api/lightweight-extension-stages/upload', { method: 'POST', body: form }); if (!response.ok) throw new Error(await extensionApiError(response, '原始包可复现检查提交失败')); ElMessage.success('文件上传成功,已开始生成并验收'); @@ -20156,6 +20232,18 @@ compare: [[flesh, peel]]`; console.warn('[lightweight extension] list failed', err); } }; + const loadExtensionEnvOptions = async () => { + try { + const response = await extensionApiFetch('/api/extension-stages/envs'); + if (!response.ok) return; + const data = await response.json(); + if (data.success && Array.isArray(data.envs) && data.envs.length) { + extensionEnvOptions.value = data.envs; + } + } catch (err) { + console.warn('[extension env options] load failed', err); + } + }; const answerLightweightExtensionHelp = async (message) => { const query = String(message || ''); const matched = (lightweightExtensions.value || []).find(item => query.includes(item.extension_id)); @@ -23388,6 +23476,7 @@ compare: [[flesh, peel]]`; startRuntimeMonitor(); loadExtensionStages(); loadLightweightExtensionStages(); + loadExtensionEnvOptions(); resumeLightweightOperation(); loadExtensionRuns(); loadMethodologyJobs(); @@ -23718,6 +23807,7 @@ compare: [[flesh, peel]]`; intentHistory, uploadedFiles, extensionBuild, + extensionEnvOptions, extensionStages, extensionCompletedStages, lightweightExtensionConversation, @@ -23736,6 +23826,7 @@ compare: [[flesh, peel]]`; extensionFileKey, onExtensionCodeFilesChange, onExtensionDataFilesChange, + handleLightweightExtensionFolderDrop, removeExtensionFile, buildExtensionStage, confirmLightweightCandidate, @@ -23755,6 +23846,7 @@ compare: [[flesh, peel]]`; validateExtensionStage, publishExtensionStage, loadExtensionStages, + loadExtensionEnvOptions, loadExtensionRuns, runExtensionStage, runExtensionStageFromIntent, @@ -23874,6 +23966,24 @@ compare: [[flesh, peel]]`; openPreview, redrawImage, createNewJob, + lightweightExtensionTestStatus, + handleLightweightExtensionFolderDrop: (event) => window.LightWeightExtensionTest && window.LightWeightExtensionTest.handleDrop({ + jobInfo, + extensionBuild, + createNewJob, + appendExtensionFiles, + buildLightweightExtensionStage, + lightweightExtensionTestStatus, + }, event), + handleLightweightExtensionFolderPick: (event) => window.LightWeightExtensionTest && window.LightWeightExtensionTest.handlePick({ + jobInfo, + extensionBuild, + createNewJob, + appendExtensionFiles, + buildLightweightExtensionStage, + lightweightExtensionTestStatus, + }, event), + openLightweightExtensionFolderPicker: () => window.LightWeightExtensionTest && window.LightWeightExtensionTest.openPicker(), // Working DirectorySelect existingJobs, jobSelectorVisible, @@ -23990,6 +24100,9 @@ compare: [[flesh, peel]]`; document.getElementById('app').style.display = 'block'; console.log('App mounted successfully'); + + + + + + +
+ Loading… +
+ + + + + + + + + + + diff --git a/apps/web/vue3/kg_ml.html b/apps/web/vue3/kg_ml.html new file mode 100755 index 000000000..be6f9fc76 --- /dev/null +++ b/apps/web/vue3/kg_ml.html @@ -0,0 +1,712 @@ + + + + + + Knowledge Graph + + + + + + + + + +
+
+
+

{{ t('kg-visualization') }}

+
{{ t('kg-subtitle') }}
+
+ + {{ t('back-to-main') }} + +
+ +
+ +
+
+

{{ t('kg-stats') }}

+
+ {{ t('node-count') }} + {{ stats.nodes }} +
+
+ {{ t('edge-count') }} + {{ stats.edges }} +
+
+ {{ t('node-types') }} + {{ stats.nodeTypes }} +
+
+ {{ t('edge-types') }} + {{ stats.edgeTypes }} +
+
+ +
+

{{ t('node-search') }}

+ + + +
+ +
+

{{ t('relation-filter-pc') }}

+
+
+
+ {{ category === 'activation' ? t('activation-induction') : + category === 'repression' ? t('repression-inhibition') : + category === 'regulation' ? t('regulation-control') : + category === 'expression' ? t('expression-detection') : + category === 'association' ? t('association-interaction') : + category === 'localization' ? t('localization') : + category === 'containment' ? t('containment-composition') : + category === 'participation' ? t('participation-function') : t('other-rel') }} +
+ + {{ type }} ({{ relationCounts[type] }}) + +
+
+
+ +
+

{{ t('node-legend-pc') }}

+
Gene/Protein
+
+
+
+ {{ nodeTypeLabels[type] }} +
+
+
Phenotype
+
+
+
+ {{ nodeTypeLabels[type] }} +
+
+
Cell/Organ/Organism
+
+
+
+ {{ nodeTypeLabels[type] }} +
+
+
Biological Process
+
+
+
+ {{ nodeTypeLabels[type] }} +
+
+
Genomic
+
+
+
+ {{ nodeTypeLabels[type] }} +
+
+

🔗 {{ t('edge-legend-pc') }}

+
+
+
+ {{ cat === 'activation' ? 'Activation/Induction' : + cat === 'repression' ? 'Repression/Inhibition' : + cat === 'regulation' ? 'Regulation/Control' : + cat === 'expression' ? 'Expression/Detection' : + cat === 'association' ? 'Association/Interaction' : + cat === 'localization' ? 'Localization' : + cat === 'containment' ? 'Containment/Composition' : + cat === 'participation' ? 'Participation/Function' : 'Other' }} +
+
+
+
+ + +
+
+ + + {{ t('fit-view') }} + + + {{ t('reset-filters') }} + + + + + {{ t('click-drag-hint') }} + +
+
+
+ + +
+

{{ t('node-detail') }}

+
+
+
{{ t('node-name') }}
+
{{ selectedNode.name }}
+
+
+
{{ t('node-type-pc') }}
+
+ + {{ nodeTypeLabels[selectedNode.category] || selectedNode.category }} + +
+
+
+
{{ t('connection-count') }}
+
{{ selectedNode.degree }}{{ t('num-connections') }}
+
+
+
+ {{ t('click-node-detail') }} +
+ + +
+
+
+ + + + diff --git a/apps/web/vue3/lightWeightExtensionTest.js b/apps/web/vue3/lightWeightExtensionTest.js new file mode 100644 index 000000000..f93af52ca --- /dev/null +++ b/apps/web/vue3/lightWeightExtensionTest.js @@ -0,0 +1,304 @@ +(function () { + const PY_EXTENSIONS = new Set(['.py']); + const R_EXTENSIONS = new Set(['.r']); + + function normalizedRelativePath(file) { + const relative = String(file.webkitRelativePath || file.relativePath || file.name || '').replace(/^\/+/, ''); + return relative.split('\\').join('/'); + } + + function parsePythonImports(content) { + const imports = new Set(); + const lines = String(content || '').split(/\r?\n/); + for (const line of lines) { + let match = line.match(/^\s*import\s+([A-Za-z0-9_.,\s]+)/); + if (match) { + match[1].split(',').forEach((item) => { + const token = item.trim().split(/\s+as\s+/i)[0].split('.')[0].trim(); + if (token) imports.add(token); + }); + } + match = line.match(/^\s*from\s+([A-Za-z0-9_.]+)\s+import\s+/); + if (match) { + const token = match[1].split('.')[0].trim(); + if (token) imports.add(token); + } + } + return Array.from(imports); + } + + function parseRPackages(content) { + const packages = new Set(); + const pattern = /(?:library|require)\(\s*["']?([A-Za-z0-9_.-]+)["']?\s*\)/g; + let match; + const text = String(content || ''); + while ((match = pattern.exec(text)) !== null) { + if (match[1]) packages.add(match[1]); + } + return Array.from(packages); + } + + function commonPathPrefix(files) { + const paths = files.map((f) => normalizedRelativePath(f).split('/')).filter((parts) => parts.length > 0); + if (!paths.length) return ''; + const first = paths[0]; + let prefixLen = 0; + for (let i = 0; i < first.length; i++) { + if (!paths.every((parts) => parts[i] === first[i])) break; + prefixLen = i + 1; + } + return first.slice(0, prefixLen).join('/'); + } + + function sanitizeDisplayName(raw) { + return String(raw || '').replace(/[^A-Za-z0-9_-]+/g, '_').replace(/^_+|_+$/g, '') || 'lightweight_extension'; + } + + function extractRootName(files) { + const prefix = commonPathPrefix(files); + const base = (prefix && prefix !== 'raw_code' && prefix !== 'raw_test_data') + ? sanitizeDisplayName(prefix.split('/')[0]) + : 'lightweight_extension_drop'; + const ts = Date.now(); + return base + '_' + ts; + } + + function splitFixedStructure(files) { + const codeFiles = []; + const dataFiles = []; + let hasRunScript = false; + let prefix = commonPathPrefix(files); + if (prefix && !prefix.endsWith('/')) prefix += '/'; + + const sampled = []; + for (const file of files) { + let relativePath = normalizedRelativePath(file); + if (prefix && relativePath.startsWith(prefix)) { + relativePath = relativePath.slice(prefix.length); + } + if (sampled.length < 10) sampled.push(relativePath); + if (relativePath.startsWith('raw_code/')) { + file.lightweightRelativePath = relativePath.slice('raw_code/'.length) || file.name; + codeFiles.push(file); + if (relativePath === 'raw_code/run.sh') { + hasRunScript = true; + } + } else if (relativePath.startsWith('raw_test_data/')) { + file.lightweightRelativePath = relativePath.slice('raw_test_data/'.length) || file.name; + dataFiles.push(file); + } + } + if (!codeFiles.length) { + const preview = sampled.length ? sampled.slice(0, 10).join(', ') : '(无)'; + throw new Error('缺少 raw_code/ 目录(检测到的路径样例: ' + preview + ')'); + } + if (!dataFiles.length) { + throw new Error('缺少 raw_test_data/ 目录'); + } + if (!hasRunScript) { + throw new Error('缺少 raw_code/run.sh'); + } + return { codeFiles, dataFiles }; + } + + async function extractDependencies(files) { + const pythonImports = new Set(); + const rPackages = new Set(); + for (const file of files) { + const path = normalizedRelativePath(file); + const lower = path.toLowerCase(); + const extension = lower.includes('.') ? lower.slice(lower.lastIndexOf('.')) : ''; + if (!PY_EXTENSIONS.has(extension) && !R_EXTENSIONS.has(extension)) { + continue; + } + const content = await file.text(); + if (PY_EXTENSIONS.has(extension)) { + parsePythonImports(content).forEach((name) => pythonImports.add(name)); + } else { + parseRPackages(content).forEach((name) => rPackages.add(name)); + } + } + return { + python_imports: Array.from(pythonImports), + r_packages: Array.from(rPackages), + }; + } + + async function encodeBase64(file) { + const buffer = await file.arrayBuffer(); + const bytes = new Uint8Array(buffer); + let binary = ''; + const chunkSize = 0x8000; + for (let index = 0; index < bytes.length; index += chunkSize) { + binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize)); + } + return btoa(binary); + } + + async function importFolderToJob(hooks, rootName, files) { + const payload = { + job_id: String(hooks.jobInfo.job_id || '').trim(), + root_name: rootName, + files: [], + relative_paths: [], + }; + for (const file of files) { + payload.files.push(await encodeBase64(file)); + payload.relative_paths.push(normalizedRelativePath(file)); + } + const response = await fetch('/api/job/import-folder', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }); + const data = await response.json(); + if (!response.ok || !data.success) { + throw new Error(data.detail || data.error || data.message || 'Job 导入失败'); + } + return data; + } + + async function resolveRuntimeEnv(files) { + const dependencies = await extractDependencies(files); + console.log('[lightWeightExtensionTest] 提取的依赖:', JSON.stringify(dependencies), '| 扫描文件数:', files.length); + try { + const response = await fetch('/api/extension-stages/envs/resolve', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(dependencies), + }); + const data = await response.json(); + console.log('[lightWeightExtensionTest] 后端 env/resolve 原始响应:', response.status, JSON.stringify(data).slice(0, 500)); + if (!response.ok || !data.success) { + throw new Error(data.detail || data.error || data.message || '运行环境解析失败'); + } + return data; + } catch (e) { + console.error('[lightWeightExtensionTest] env/resolve 调用失败:', e); + throw e; + } + } + + function notifyError(message) { + if (window.ElementPlus && window.ElementPlus.ElMessage) { + window.ElementPlus.ElMessage.error(message); + } + } + + async function ensureJob(hooks) { + if (String(hooks.jobInfo.job_id || '').trim() && String(hooks.jobInfo.job_id) !== 'default_job') { + return; + } + await hooks.createNewJob(); + if (!String(hooks.jobInfo.job_id || '').trim() || String(hooks.jobInfo.job_id) === 'default_job') { + throw new Error('自动创建 Job 失败'); + } + } + + async function processFolderFiles(hooks, inputFiles) { + const files = Array.from(inputFiles || []).filter((file) => normalizedRelativePath(file)); + if (!files.length) { + throw new Error('未读取到任何文件'); + } + hooks.lightweightExtensionTestStatus.value = '正在校验目录结构...'; + const rootName = extractRootName(files); + const fixed = splitFixedStructure(files); + hooks.lightweightExtensionTestStatus.value = '正在确保 Job 可用...'; + await ensureJob(hooks); + hooks.lightweightExtensionTestStatus.value = '正在解析运行环境...'; + const envResult = await resolveRuntimeEnv(files); + hooks.extensionBuild.runtimeEnv = envResult.runtime_env || 'test4py311'; + console.log( + '[lightWeightExtensionTest] ✓ 选定环境: ' + hooks.extensionBuild.runtimeEnv, + '| 原因: ' + (envResult.reason || 'unknown'), + '| 兜底: ' + (envResult.fallback ? '是' : '否'), + envResult.matches ? '| 候选: ' + JSON.stringify(envResult.matches.map(m => m.env + '(py:' + (m.python_hits || []).join(',') + ' r:' + (m.r_hits || []).join(',') + ')')) : '', + ); + hooks.lightweightExtensionTestStatus.value = '正在镜像导入当前 Job...'; + await importFolderToJob(hooks, rootName, files); + hooks.extensionBuild.displayName = rootName; + hooks.extensionBuild.command = 'bash run.sh'; + hooks.extensionBuild.codeFiles = hooks.appendExtensionFiles([], fixed.codeFiles); + hooks.extensionBuild.dataFiles = hooks.appendExtensionFiles([], fixed.dataFiles); + hooks.extensionBuild.dataPaths = ''; + hooks.lightweightExtensionTestStatus.value = `运行环境 ${hooks.extensionBuild.runtimeEnv} 已确定,正在触发 upload...`; + await hooks.buildLightweightExtensionStage(); + hooks.lightweightExtensionTestStatus.value = '已开始 upload,系统正在自动轮询并等待候选卡。'; + } + + async function readEntry(entry, basePath) { + if (entry.isFile) { + return new Promise((resolve) => { + entry.file((file) => { + Object.defineProperty(file, 'webkitRelativePath', { + value: basePath ? basePath + '/' + entry.name : entry.name, + writable: false, + }); + resolve([file]); + }); + }); + } + if (entry.isDirectory) { + const reader = entry.createReader(); + const entries = await new Promise((resolve) => { + reader.readEntries(resolve); + }); + const subPath = basePath ? basePath + '/' + entry.name : entry.name; + const nested = await Promise.all(entries.map((e) => readEntry(e, subPath))); + return nested.flat(); + } + return []; + } + + async function readDroppedFiles(dataTransfer) { + if (!dataTransfer || !dataTransfer.items) { + return Array.from(dataTransfer?.files || []); + } + const items = Array.from(dataTransfer.items); + const entries = items + .map((item) => item.webkitGetAsEntry && item.webkitGetAsEntry()) + .filter(Boolean); + if (!entries.length) { + return Array.from(dataTransfer.files || []); + } + const results = await Promise.all(entries.map((entry) => readEntry(entry, ''))); + return results.flat(); + } + + function mountApi() { + window.LightWeightExtensionTest = { + async handleDrop(hooks, event) { + try { + const files = await readDroppedFiles(event?.dataTransfer); + await processFolderFiles(hooks, files); + } catch (error) { + const message = `失败:${error.message || '目录处理失败'}`; + hooks.lightweightExtensionTestStatus.value = message; + notifyError(message); + } + }, + async handlePick(hooks, event) { + const files = event?.target?.files || []; + try { + await processFolderFiles(hooks, files); + } catch (error) { + const message = `失败:${error.message || '目录处理失败'}`; + hooks.lightweightExtensionTestStatus.value = message; + notifyError(message); + } finally { + if (event?.target) { + event.target.value = ''; + } + } + }, + openPicker() { + const input = document.getElementById('lightweight-extension-test-folder-input'); + if (input) { + input.click(); + } + }, + }; + } + + mountApi(); +})(); diff --git a/apps/web/vue3/main.py b/apps/web/vue3/main.py index 0da4410c9..f1f63a684 100644 --- a/apps/web/vue3/main.py +++ b/apps/web/vue3/main.py @@ -6,6 +6,7 @@ BotanicalBaseAgent - FastAPI Backend import os import sys import json +import base64 import csv import asyncio import hashlib @@ -41,6 +42,7 @@ _builtins.print = _safe_print # 添加项目路径 PROJECT_ROOT = Path(__file__).parent.parent.parent.parent +DEFAULT_RUNTIME_ENV = os.environ.get("BBAV5_DEFAULT_RUNTIME_ENV", "test4py311") sys.path.insert(0, str(PROJECT_ROOT)) from gfa_core.project_paths import get_conda_env_bin, get_conda_env_rscript, get_configured_path, get_wgs_bcftools, get_wgs_java, get_wgs_samtools @@ -8573,6 +8575,19 @@ async def root(): ) +@app.get("/ml") +async def root_ml(): + """返回Vue3前端多语言页面""" + return FileResponse( + Path(__file__).parent / "index_ml.html", + headers={ + "Cache-Control": "no-cache, no-store, must-revalidate", + "Pragma": "no-cache", + "Expires": "0" + } + ) + + @app.post("/api/new_job") async def create_new_job(): """创建新工作目录""" @@ -8780,6 +8795,56 @@ async def upload_file(files: List[UploadFile] = File(...), job_id: str = Form("" } +class JobImportFolderRequest(BaseModel): + job_id: str + root_name: str = "" + files: List[str] = Field(default_factory=list) + relative_paths: List[str] = Field(default_factory=list) + + +@app.post("/api/job/import-folder") +async def import_job_folder(req: JobImportFolderRequest): + job_id = str(req.job_id or "").strip() + if not job_id: + raise HTTPException(status_code=400, detail="job_id is required") + if len(req.files) != len(req.relative_paths): + raise HTTPException(status_code=400, detail="files and relative_paths length mismatch") + + root_name = _safe_upload_name(req.root_name or "lightweight_extension_drop") + import_root = INPUT_ROOT / job_id / root_name + import_root.mkdir(parents=True, exist_ok=True) + saved_files: List[str] = [] + + for encoded, raw_relative in zip(req.files, req.relative_paths): + relative = Path(str(raw_relative or "").strip()) + if not raw_relative or relative.is_absolute() or any(part in {"", ".", ".."} for part in relative.parts): + raise HTTPException(status_code=400, detail=f"invalid relative path: {raw_relative}") + try: + content = base64.b64decode(str(encoded or "").encode("utf-8"), validate=True) + except Exception as exc: + raise HTTPException(status_code=400, detail=f"invalid base64 payload for {raw_relative}: {exc}") from exc + destination = import_root / relative + destination.parent.mkdir(parents=True, exist_ok=True) + destination.write_bytes(content) + saved_files.append(relative.as_posix()) + + return { + "success": True, + "job_id": job_id, + "root_name": root_name, + "import_root": str(import_root), + "saved_files": saved_files, + } + + +@app.get("/lightWeightExtensionTest.js") +async def get_lightweight_extension_test_script(): + script_path = WEB_DIR / "lightWeightExtensionTest.js" + if not script_path.exists(): + raise HTTPException(status_code=404, detail="lightWeightExtensionTest.js not found") + return FileResponse(str(script_path), media_type="application/javascript") + + class ExtensionStageRunRequest(BaseModel): extension_id: str job_id: str = "" @@ -8850,6 +8915,137 @@ class ExtensionStageResolveIntentRequest(BaseModel): job_id: str = "" +class ExtensionStageEnvResolveRequest(BaseModel): + python_imports: List[str] = Field(default_factory=list) + r_packages: List[str] = Field(default_factory=list) + + + +@app.get("/api/extension-stages/envs") +async def list_extension_stage_envs(): + """Return available conda environment names for the extension stage runtime dropdown.""" + import json as _json + try: + proc = await asyncio.create_subprocess_exec( + "conda", "env", "list", "--json", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await proc.communicate() + if proc.returncode != 0: + # fallback: try parsing plain-text output + proc2 = await asyncio.create_subprocess_exec( + "conda", "env", "list", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout2, _ = await proc2.communicate() + envs = [] + for line in stdout2.decode("utf-8", errors="replace").splitlines(): + stripped = line.strip() + if not stripped or stripped.startswith("#"): + continue + # format: "env_name /path/to/env" + parts = stripped.split() + if parts: + envs.append(parts[0]) + return {"success": True, "envs": envs} + data = _json.loads(stdout.decode("utf-8")) + envs = [entry.split("/")[-1] if "/" in str(entry) else str(entry) for entry in data.get("envs", [])] + return {"success": True, "envs": envs} + except Exception as exc: + return {"success": False, "envs": ["test4py311", "rnaseq", "rnaR"], "error": str(exc)} + + +def _normalized_dependency_names(values: List[str]) -> List[str]: + normalized: List[str] = [] + seen: set[str] = set() + stdlib_names = set(getattr(sys, "stdlib_module_names", set())) + for raw in values or []: + token = re.split(r"[<>=\[\]()\s]", str(raw or "").strip(), maxsplit=1)[0].strip() + if not token: + continue + top_level = token.split(".")[0].strip() + key = top_level.lower().replace("_", "-") + if top_level in stdlib_names or key in seen: + continue + seen.add(key) + normalized.append(top_level) + return normalized + + +async def _available_extension_env_names() -> List[str]: + result = await list_extension_stage_envs() + envs = result.get("envs") if isinstance(result, dict) else [] + if isinstance(envs, list) and envs: + return [str(item) for item in envs if str(item).strip()] + return ["test4py311", "rnaseq", "rnaR"] + + +async def _python_packages_for_env(env_name: str) -> set[str]: + proc = await asyncio.create_subprocess_exec( + "conda", "run", "-n", env_name, "python", "-c", + "import json, importlib.metadata as m; print(json.dumps(sorted({dist.metadata.get('Name', '') for dist in m.distributions() if dist.metadata.get('Name', '')})))", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, _stderr = await proc.communicate() + if proc.returncode != 0: + return set() + try: + values = json.loads(stdout.decode("utf-8", errors="replace")) + except Exception: + return set() + return {str(item).strip().lower().replace("_", "-") for item in values if str(item).strip()} + + +async def _r_packages_for_env(env_name: str) -> set[str]: + proc = await asyncio.create_subprocess_exec( + "conda", "run", "-n", env_name, "Rscript", "-e", + "cat(paste(sort(rownames(installed.packages())), collapse='\n'))", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, _stderr = await proc.communicate() + if proc.returncode != 0: + return set() + return {line.strip().lower() for line in stdout.decode("utf-8", errors="replace").splitlines() if line.strip()} + + +@app.post("/api/extension-stages/envs/resolve") +async def resolve_extension_stage_env(req: ExtensionStageEnvResolveRequest): + python_imports = _normalized_dependency_names(req.python_imports) + r_packages = _normalized_dependency_names(req.r_packages) + if not python_imports and not r_packages: + return { + "success": True, + "runtime_env": "test4py311", + "reason": "no_dependencies_detected", + "fallback": True, + } + + for dep in list(dict.fromkeys(d.lower() for d in python_imports + r_packages)): + proc = await asyncio.create_subprocess_exec( + "conda", "run", "-n", dep, "python", "--version", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + await proc.communicate() + if proc.returncode == 0: + return { + "success": True, + "runtime_env": dep, + "reason": "env_name_matches_dependency", + "dependency": dep, + "fallback": False, + } + + return { + "success": True, + "runtime_env": "test4py311", + "reason": "no_conda_env_matches_dependency", + "fallback": True, + } @app.post("/api/extension-stages/build") async def build_extension_stage( display_name: str = Form(...), @@ -9750,7 +9946,7 @@ async def get_config_autofill_template(): async def draft_config_autofill(req: AutofillDraftRequest): job_id, input_dir, workspace_dir = _autofill_job_dirs(req.job_id) cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_config_autofill.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), @@ -9779,7 +9975,7 @@ async def draft_config_autofill(req: AutofillDraftRequest): async def draft_samples_autofill(req: AutofillDraftRequest): job_id, input_dir, workspace_dir = _autofill_job_dirs(req.job_id) cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_samples_autofill.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), @@ -9910,7 +10106,7 @@ async def confirm_config_autofill(req: AutofillDraftRequest): _write_config_draft_rows(draft_path, req.rows, family, primary_reference_species, identify_blast_reference_species) draft_to_use = str(draft_path) cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_config_autofill.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), @@ -9958,7 +10154,7 @@ async def confirm_samples_autofill(req: AutofillDraftRequest): req, ) cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_samples_autofill.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), @@ -10284,7 +10480,7 @@ async def confirm_identify_domain_review(req: IdentifyDomainReviewConfirmRequest curated_file.parent.mkdir(parents=True, exist_ok=True) curated_file.write_text("\n".join(selected) + "\n", encoding="utf-8") cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_identify_refine.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), @@ -10767,7 +10963,7 @@ def _split_joint_subfamily_confirmation(job_id: str, prefix: str, rows: list[dic f"{row.get('confidence','')}\t{row.get('note','')}\n" ) cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_subfamily_confirm.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), @@ -11104,7 +11300,7 @@ async def confirm_subfamily_review(req: SubfamilyReviewConfirmRequest): member_set_changed = bool(current_ids and confirmed_ids and not current_ids.issubset(confirmed_ids)) cmd = [ - "/home/xzq/miniconda3/envs/test4py311/bin/python", + f"/home/xzq/miniconda3/envs/{DEFAULT_RUNTIME_ENV}/bin/python", "apps/cli/run_subfamily_confirm.py", "--input-dir", str(input_dir), "--workspace", str(workspace_dir), diff --git a/apps/web/vue3/static/cdn/en.js b/apps/web/vue3/static/cdn/en.js new file mode 100644 index 000000000..1894bbb3f --- /dev/null +++ b/apps/web/vue3/static/cdn/en.js @@ -0,0 +1,165 @@ +// global wrapper +/*! Element Plus v2.3.14 */ + +window.en = { + name: "en", + el: { + colorpicker: { + confirm: "OK", + clear: "Clear", + defaultLabel: "color picker", + description: "current color is {color}. press enter to select a new color." + }, + datepicker: { + now: "Now", + today: "Today", + cancel: "Cancel", + clear: "Clear", + confirm: "OK", + dateTablePrompt: "Use the arrow keys and enter to select the day of the month", + monthTablePrompt: "Use the arrow keys and enter to select the month", + yearTablePrompt: "Use the arrow keys and enter to select the year", + selectedDate: "Selected date", + selectDate: "Select date", + selectTime: "Select time", + startDate: "Start Date", + startTime: "Start Time", + endDate: "End Date", + endTime: "End Time", + prevYear: "Previous Year", + nextYear: "Next Year", + prevMonth: "Previous Month", + nextMonth: "Next Month", + year: "", + month1: "January", + month2: "February", + month3: "March", + month4: "April", + month5: "May", + month6: "June", + month7: "July", + month8: "August", + month9: "September", + month10: "October", + month11: "November", + month12: "December", + week: "week", + weeks: { + sun: "Sun", + mon: "Mon", + tue: "Tue", + wed: "Wed", + thu: "Thu", + fri: "Fri", + sat: "Sat" + }, + weeksFull: { + sun: "Sunday", + mon: "Monday", + tue: "Tuesday", + wed: "Wednesday", + thu: "Thursday", + fri: "Friday", + sat: "Saturday" + }, + months: { + jan: "Jan", + feb: "Feb", + mar: "Mar", + apr: "Apr", + may: "May", + jun: "Jun", + jul: "Jul", + aug: "Aug", + sep: "Sep", + oct: "Oct", + nov: "Nov", + dec: "Dec" + } + }, + inputNumber: { + decrease: "decrease number", + increase: "increase number" + }, + select: { + loading: "Loading", + noMatch: "No matching data", + noData: "No data", + placeholder: "Select" + }, + dropdown: { + toggleDropdown: "Toggle Dropdown" + }, + cascader: { + noMatch: "No matching data", + loading: "Loading", + placeholder: "Select", + noData: "No data" + }, + pagination: { + goto: "Go to", + pagesize: "/page", + total: "Total {total}", + pageClassifier: "", + page: "Page", + prev: "Go to previous page", + next: "Go to next page", + currentPage: "page {pager}", + prevPages: "Previous {pager} pages", + nextPages: "Next {pager} pages", + deprecationWarning: "Deprecated usages detected, please refer to the el-pagination documentation for more details" + }, + dialog: { + close: "Close this dialog" + }, + drawer: { + close: "Close this dialog" + }, + messagebox: { + title: "Message", + confirm: "OK", + cancel: "Cancel", + error: "Illegal input", + close: "Close this dialog" + }, + upload: { + deleteTip: "press delete to remove", + delete: "Delete", + preview: "Preview", + continue: "Continue" + }, + slider: { + defaultLabel: "slider between {min} and {max}", + defaultRangeStartLabel: "pick start value", + defaultRangeEndLabel: "pick end value" + }, + table: { + emptyText: "No Data", + confirmFilter: "Confirm", + resetFilter: "Reset", + clearFilter: "All", + sumText: "Sum" + }, + tree: { + emptyText: "No Data" + }, + transfer: { + noMatch: "No matching data", + noData: "No data", + titles: ["List 1", "List 2"], + filterPlaceholder: "Enter keyword", + noCheckedFormat: "{total} items", + hasCheckedFormat: "{checked}/{total} checked" + }, + image: { + error: "FAILED" + }, + pageHeader: { + title: "Back" + }, + popconfirm: { + confirmButtonText: "Yes", + cancelButtonText: "No" + } + } +}; diff --git a/apps/web/vue3/static/cdn/en.mjs b/apps/web/vue3/static/cdn/en.mjs new file mode 100644 index 000000000..71aff82d0 --- /dev/null +++ b/apps/web/vue3/static/cdn/en.mjs @@ -0,0 +1,165 @@ +/*! Element Plus v2.3.14 */ + +var en = { + name: "en", + el: { + colorpicker: { + confirm: "OK", + clear: "Clear", + defaultLabel: "color picker", + description: "current color is {color}. press enter to select a new color." + }, + datepicker: { + now: "Now", + today: "Today", + cancel: "Cancel", + clear: "Clear", + confirm: "OK", + dateTablePrompt: "Use the arrow keys and enter to select the day of the month", + monthTablePrompt: "Use the arrow keys and enter to select the month", + yearTablePrompt: "Use the arrow keys and enter to select the year", + selectedDate: "Selected date", + selectDate: "Select date", + selectTime: "Select time", + startDate: "Start Date", + startTime: "Start Time", + endDate: "End Date", + endTime: "End Time", + prevYear: "Previous Year", + nextYear: "Next Year", + prevMonth: "Previous Month", + nextMonth: "Next Month", + year: "", + month1: "January", + month2: "February", + month3: "March", + month4: "April", + month5: "May", + month6: "June", + month7: "July", + month8: "August", + month9: "September", + month10: "October", + month11: "November", + month12: "December", + week: "week", + weeks: { + sun: "Sun", + mon: "Mon", + tue: "Tue", + wed: "Wed", + thu: "Thu", + fri: "Fri", + sat: "Sat" + }, + weeksFull: { + sun: "Sunday", + mon: "Monday", + tue: "Tuesday", + wed: "Wednesday", + thu: "Thursday", + fri: "Friday", + sat: "Saturday" + }, + months: { + jan: "Jan", + feb: "Feb", + mar: "Mar", + apr: "Apr", + may: "May", + jun: "Jun", + jul: "Jul", + aug: "Aug", + sep: "Sep", + oct: "Oct", + nov: "Nov", + dec: "Dec" + } + }, + inputNumber: { + decrease: "decrease number", + increase: "increase number" + }, + select: { + loading: "Loading", + noMatch: "No matching data", + noData: "No data", + placeholder: "Select" + }, + dropdown: { + toggleDropdown: "Toggle Dropdown" + }, + cascader: { + noMatch: "No matching data", + loading: "Loading", + placeholder: "Select", + noData: "No data" + }, + pagination: { + goto: "Go to", + pagesize: "/page", + total: "Total {total}", + pageClassifier: "", + page: "Page", + prev: "Go to previous page", + next: "Go to next page", + currentPage: "page {pager}", + prevPages: "Previous {pager} pages", + nextPages: "Next {pager} pages", + deprecationWarning: "Deprecated usages detected, please refer to the el-pagination documentation for more details" + }, + dialog: { + close: "Close this dialog" + }, + drawer: { + close: "Close this dialog" + }, + messagebox: { + title: "Message", + confirm: "OK", + cancel: "Cancel", + error: "Illegal input", + close: "Close this dialog" + }, + upload: { + deleteTip: "press delete to remove", + delete: "Delete", + preview: "Preview", + continue: "Continue" + }, + slider: { + defaultLabel: "slider between {min} and {max}", + defaultRangeStartLabel: "pick start value", + defaultRangeEndLabel: "pick end value" + }, + table: { + emptyText: "No Data", + confirmFilter: "Confirm", + resetFilter: "Reset", + clearFilter: "All", + sumText: "Sum" + }, + tree: { + emptyText: "No Data" + }, + transfer: { + noMatch: "No matching data", + noData: "No data", + titles: ["List 1", "List 2"], + filterPlaceholder: "Enter keyword", + noCheckedFormat: "{total} items", + hasCheckedFormat: "{checked}/{total} checked" + }, + image: { + error: "FAILED" + }, + pageHeader: { + title: "Back" + }, + popconfirm: { + confirmButtonText: "Yes", + cancelButtonText: "No" + } + } +}; + diff --git a/apps/web/vue3/static/cdn/zh-cn.js b/apps/web/vue3/static/cdn/zh-cn.js new file mode 100644 index 000000000..b86238535 --- /dev/null +++ b/apps/web/vue3/static/cdn/zh-cn.js @@ -0,0 +1,130 @@ +// global wrapper +/*! Element Plus v2.3.14 */ + +window.zhCn = { + name: "zh-cn", + el: { + colorpicker: { + confirm: "\u786E\u5B9A", + clear: "\u6E05\u7A7A" + }, + datepicker: { + now: "\u6B64\u523B", + today: "\u4ECA\u5929", + cancel: "\u53D6\u6D88", + clear: "\u6E05\u7A7A", + confirm: "\u786E\u5B9A", + selectDate: "\u9009\u62E9\u65E5\u671F", + selectTime: "\u9009\u62E9\u65F6\u95F4", + startDate: "\u5F00\u59CB\u65E5\u671F", + startTime: "\u5F00\u59CB\u65F6\u95F4", + endDate: "\u7ED3\u675F\u65E5\u671F", + endTime: "\u7ED3\u675F\u65F6\u95F4", + prevYear: "\u524D\u4E00\u5E74", + nextYear: "\u540E\u4E00\u5E74", + prevMonth: "\u4E0A\u4E2A\u6708", + nextMonth: "\u4E0B\u4E2A\u6708", + year: "\u5E74", + month1: "1 \u6708", + month2: "2 \u6708", + month3: "3 \u6708", + month4: "4 \u6708", + month5: "5 \u6708", + month6: "6 \u6708", + month7: "7 \u6708", + month8: "8 \u6708", + month9: "9 \u6708", + month10: "10 \u6708", + month11: "11 \u6708", + month12: "12 \u6708", + weeks: { + sun: "\u65E5", + mon: "\u4E00", + tue: "\u4E8C", + wed: "\u4E09", + thu: "\u56DB", + fri: "\u4E94", + sat: "\u516D" + }, + months: { + jan: "\u4E00\u6708", + feb: "\u4E8C\u6708", + mar: "\u4E09\u6708", + apr: "\u56DB\u6708", + may: "\u4E94\u6708", + jun: "\u516D\u6708", + jul: "\u4E03\u6708", + aug: "\u516B\u6708", + sep: "\u4E5D\u6708", + oct: "\u5341\u6708", + nov: "\u5341\u4E00\u6708", + dec: "\u5341\u4E8C\u6708" + } + }, + select: { + loading: "\u52A0\u8F7D\u4E2D", + noMatch: "\u65E0\u5339\u914D\u6570\u636E", + noData: "\u65E0\u6570\u636E", + placeholder: "\u8BF7\u9009\u62E9" + }, + cascader: { + noMatch: "\u65E0\u5339\u914D\u6570\u636E", + loading: "\u52A0\u8F7D\u4E2D", + placeholder: "\u8BF7\u9009\u62E9", + noData: "\u6682\u65E0\u6570\u636E" + }, + pagination: { + goto: "\u524D\u5F80", + pagesize: "\u6761/\u9875", + total: "\u5171 {total} \u6761", + pageClassifier: "\u9875", + page: "\u9875", + prev: "\u4E0A\u4E00\u9875", + next: "\u4E0B\u4E00\u9875", + currentPage: "\u7B2C {pager} \u9875", + prevPages: "\u5411\u524D {pager} \u9875", + nextPages: "\u5411\u540E {pager} \u9875", + deprecationWarning: "\u4F60\u4F7F\u7528\u4E86\u4E00\u4E9B\u5DF2\u88AB\u5E9F\u5F03\u7684\u7528\u6CD5\uFF0C\u8BF7\u53C2\u8003 el-pagination \u7684\u5B98\u65B9\u6587\u6863" + }, + messagebox: { + title: "\u63D0\u793A", + confirm: "\u786E\u5B9A", + cancel: "\u53D6\u6D88", + error: "\u8F93\u5165\u7684\u6570\u636E\u4E0D\u5408\u6CD5!" + }, + upload: { + deleteTip: "\u6309 delete \u952E\u53EF\u5220\u9664", + delete: "\u5220\u9664", + preview: "\u67E5\u770B\u56FE\u7247", + continue: "\u7EE7\u7EED\u4E0A\u4F20" + }, + table: { + emptyText: "\u6682\u65E0\u6570\u636E", + confirmFilter: "\u7B5B\u9009", + resetFilter: "\u91CD\u7F6E", + clearFilter: "\u5168\u90E8", + sumText: "\u5408\u8BA1" + }, + tree: { + emptyText: "\u6682\u65E0\u6570\u636E" + }, + transfer: { + noMatch: "\u65E0\u5339\u914D\u6570\u636E", + noData: "\u65E0\u6570\u636E", + titles: ["\u5217\u8868 1", "\u5217\u8868 2"], + filterPlaceholder: "\u8BF7\u8F93\u5165\u641C\u7D22\u5185\u5BB9", + noCheckedFormat: "\u5171 {total} \u9879", + hasCheckedFormat: "\u5DF2\u9009 {checked}/{total} \u9879" + }, + image: { + error: "\u52A0\u8F7D\u5931\u8D25" + }, + pageHeader: { + title: "\u8FD4\u56DE" + }, + popconfirm: { + confirmButtonText: "\u786E\u5B9A", + cancelButtonText: "\u53D6\u6D88" + } + } +}; diff --git a/apps/web/vue3/static/cdn/zh-cn.mjs b/apps/web/vue3/static/cdn/zh-cn.mjs new file mode 100644 index 000000000..ed050d71c --- /dev/null +++ b/apps/web/vue3/static/cdn/zh-cn.mjs @@ -0,0 +1,130 @@ +/*! Element Plus v2.3.14 */ + +var zhCn = { + name: "zh-cn", + el: { + colorpicker: { + confirm: "\u786E\u5B9A", + clear: "\u6E05\u7A7A" + }, + datepicker: { + now: "\u6B64\u523B", + today: "\u4ECA\u5929", + cancel: "\u53D6\u6D88", + clear: "\u6E05\u7A7A", + confirm: "\u786E\u5B9A", + selectDate: "\u9009\u62E9\u65E5\u671F", + selectTime: "\u9009\u62E9\u65F6\u95F4", + startDate: "\u5F00\u59CB\u65E5\u671F", + startTime: "\u5F00\u59CB\u65F6\u95F4", + endDate: "\u7ED3\u675F\u65E5\u671F", + endTime: "\u7ED3\u675F\u65F6\u95F4", + prevYear: "\u524D\u4E00\u5E74", + nextYear: "\u540E\u4E00\u5E74", + prevMonth: "\u4E0A\u4E2A\u6708", + nextMonth: "\u4E0B\u4E2A\u6708", + year: "\u5E74", + month1: "1 \u6708", + month2: "2 \u6708", + month3: "3 \u6708", + month4: "4 \u6708", + month5: "5 \u6708", + month6: "6 \u6708", + month7: "7 \u6708", + month8: "8 \u6708", + month9: "9 \u6708", + month10: "10 \u6708", + month11: "11 \u6708", + month12: "12 \u6708", + weeks: { + sun: "\u65E5", + mon: "\u4E00", + tue: "\u4E8C", + wed: "\u4E09", + thu: "\u56DB", + fri: "\u4E94", + sat: "\u516D" + }, + months: { + jan: "\u4E00\u6708", + feb: "\u4E8C\u6708", + mar: "\u4E09\u6708", + apr: "\u56DB\u6708", + may: "\u4E94\u6708", + jun: "\u516D\u6708", + jul: "\u4E03\u6708", + aug: "\u516B\u6708", + sep: "\u4E5D\u6708", + oct: "\u5341\u6708", + nov: "\u5341\u4E00\u6708", + dec: "\u5341\u4E8C\u6708" + } + }, + select: { + loading: "\u52A0\u8F7D\u4E2D", + noMatch: "\u65E0\u5339\u914D\u6570\u636E", + noData: "\u65E0\u6570\u636E", + placeholder: "\u8BF7\u9009\u62E9" + }, + cascader: { + noMatch: "\u65E0\u5339\u914D\u6570\u636E", + loading: "\u52A0\u8F7D\u4E2D", + placeholder: "\u8BF7\u9009\u62E9", + noData: "\u6682\u65E0\u6570\u636E" + }, + pagination: { + goto: "\u524D\u5F80", + pagesize: "\u6761/\u9875", + total: "\u5171 {total} \u6761", + pageClassifier: "\u9875", + page: "\u9875", + prev: "\u4E0A\u4E00\u9875", + next: "\u4E0B\u4E00\u9875", + currentPage: "\u7B2C {pager} \u9875", + prevPages: "\u5411\u524D {pager} \u9875", + nextPages: "\u5411\u540E {pager} \u9875", + deprecationWarning: "\u4F60\u4F7F\u7528\u4E86\u4E00\u4E9B\u5DF2\u88AB\u5E9F\u5F03\u7684\u7528\u6CD5\uFF0C\u8BF7\u53C2\u8003 el-pagination \u7684\u5B98\u65B9\u6587\u6863" + }, + messagebox: { + title: "\u63D0\u793A", + confirm: "\u786E\u5B9A", + cancel: "\u53D6\u6D88", + error: "\u8F93\u5165\u7684\u6570\u636E\u4E0D\u5408\u6CD5!" + }, + upload: { + deleteTip: "\u6309 delete \u952E\u53EF\u5220\u9664", + delete: "\u5220\u9664", + preview: "\u67E5\u770B\u56FE\u7247", + continue: "\u7EE7\u7EED\u4E0A\u4F20" + }, + table: { + emptyText: "\u6682\u65E0\u6570\u636E", + confirmFilter: "\u7B5B\u9009", + resetFilter: "\u91CD\u7F6E", + clearFilter: "\u5168\u90E8", + sumText: "\u5408\u8BA1" + }, + tree: { + emptyText: "\u6682\u65E0\u6570\u636E" + }, + transfer: { + noMatch: "\u65E0\u5339\u914D\u6570\u636E", + noData: "\u65E0\u6570\u636E", + titles: ["\u5217\u8868 1", "\u5217\u8868 2"], + filterPlaceholder: "\u8BF7\u8F93\u5165\u641C\u7D22\u5185\u5BB9", + noCheckedFormat: "\u5171 {total} \u9879", + hasCheckedFormat: "\u5DF2\u9009 {checked}/{total} \u9879" + }, + image: { + error: "\u52A0\u8F7D\u5931\u8D25" + }, + pageHeader: { + title: "\u8FD4\u56DE" + }, + popconfirm: { + confirmButtonText: "\u786E\u5B9A", + cancelButtonText: "\u53D6\u6D88" + } + } +}; + diff --git a/apps/web/vue3/static/conversation-sidebar.js b/apps/web/vue3/static/conversation-sidebar.js index 87a3f8aba..8c020d3db 100755 --- a/apps/web/vue3/static/conversation-sidebar.js +++ b/apps/web/vue3/static/conversation-sidebar.js @@ -1,373 +1,373 @@ /** * Conversation Sidebar Component - * 类似ChatGPT的会话侧边栏组件 + * Conversation Sidebar component */ const ConversationSidebar = { - template: ` -
- - - - - - - -
- -
-
今天
-
-
- -
-
-
{{ conv.title }}
-
- {{ conv.gene_family }} - {{ conv.message_count }}条消息 -
-
{{ conv.last_message }}
-
-
- - - - -
-
-
- - -
-
昨天
-
-
- -
-
-
{{ conv.title }}
-
- {{ conv.gene_family }} - {{ conv.message_count }}条 -
-
-
-
- - -
-
过去7天
-
-
- -
-
-
{{ conv.title }}
-
- {{ conv.gene_family }} -
-
-
-
- - -
- -

暂无会话

-

点击上方"New Chat"开始新的基因家族分析

-
-
- - - -
- `, - - props: { - userId: { - type: String, - default: 'xia-lab' - }, - apiBaseUrl: { - type: String, - default: 'http://localhost:8000/api' - } - }, - - data() { - return { - isCollapsed: false, - searchQuery: '', - conversations: [], - currentConversationId: null, - loading: false, - // 图标 - Plus: ElementPlusIconsVue.Plus, - ArrowLeft: ElementPlusIconsVue.ArrowLeft, - ArrowRight: ElementPlusIconsVue.ArrowRight, - ChatDotRound: ElementPlusIconsVue.ChatDotRound, - ChatLineRound: ElementPlusIconsVue.ChatLineRound, - More: ElementPlusIconsVue.More, - Edit: ElementPlusIconsVue.Edit, - Folder: ElementPlusIconsVue.Folder, - Delete: ElementPlusIconsVue.Delete, - UserFilled: ElementPlusIconsVue.UserFilled, - } - }, - - computed: { - filteredConversations() { - if (!this.searchQuery) return this.conversations; - const query = this.searchQuery.toLowerCase(); - return this.conversations.filter(conv => - conv.title.toLowerCase().includes(query) || - (conv.gene_family && conv.gene_family.toLowerCase().includes(query)) || - conv.last_message.toLowerCase().includes(query) - ); - }, - - todayConversations() { - const today = new Date().toDateString(); - return this.filteredConversations.filter(conv => { - const convDate = new Date(conv.updated_at).toDateString(); - return convDate === today; - }); - }, - - yesterdayConversations() { - const yesterday = new Date(Date.now() - 86400000).toDateString(); - return this.filteredConversations.filter(conv => { - const convDate = new Date(conv.updated_at).toDateString(); - return convDate === yesterday; - }); - }, - - olderConversations() { - const yesterday = new Date(Date.now() - 86400000).toDateString(); - return this.filteredConversations.filter(conv => { - const convDate = new Date(conv.updated_at).toDateString(); - return convDate < yesterday; - }); - } - }, - - mounted() { - this.loadConversations(); - // 定时刷新 - this.refreshInterval = setInterval(() => { - this.loadConversations(); - }, 30000); // 30秒刷新一次 - }, - - beforeUnmount() { - if (this.refreshInterval) { - clearInterval(this.refreshInterval); - } - }, - - methods: { - async loadConversations() { - try { - this.loading = true; - const response = await fetch(`${this.apiBaseUrl}/conversations/list/${this.userId}`); - if (response.ok) { - const data = await response.json(); - this.conversations = data.conversations || []; - } - } catch (error) { - console.error('Failed to load conversations:', error); - // 使用模拟数据 - this.conversations = this.getMockConversations(); - } finally { - this.loading = false; - } - }, - - getMockConversations() { - // 模拟数据,用于测试 - return [ - { - conversation_id: 'conv_001', - title: 'At.WRKY基因家族分析', - gene_family: 'WRKY', - species: 'At', - message_count: 12, - last_message: '系统发育树已生成完成', - updated_at: new Date().toISOString() - }, - { - conversation_id: 'conv_002', - title: 'Os.TCP进化分析', - gene_family: 'TCP', - species: 'Os', - message_count: 5, - last_message: '正在构建进化树...', - updated_at: new Date(Date.now() - 3600000).toISOString() - }, - { - conversation_id: 'conv_003', - title: 'HMMER参数配置咨询', - message_count: 8, - last_message: 'E-value建议设置为1e-5', - updated_at: new Date(Date.now() - 86400000).toISOString() - } - ]; - }, - - toggleSidebar() { - this.isCollapsed = !this.isCollapsed; - this.$emit('toggle', this.isCollapsed); - }, - - async createNewConversation() { - try { - const response = await fetch(`${this.apiBaseUrl}/conversations/create`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - user_id: this.userId, - title: '新会话 ' + new Date().toLocaleTimeString() - }) - }); - - if (response.ok) { - const data = await response.json(); - this.currentConversationId = data.conversation_id; - this.$emit('new-conversation', data); - await this.loadConversations(); - } - } catch (error) { - console.error('Failed to create conversation:', error); - // 创建本地会话 - const newConv = { - conversation_id: 'conv_' + Date.now(), - title: '新会话', - message_count: 0, - last_message: '', - updated_at: new Date().toISOString() - }; - this.conversations.unshift(newConv); - this.currentConversationId = newConv.conversation_id; - this.$emit('new-conversation', newConv); - } - }, - - selectConversation(conv) { - this.currentConversationId = conv.conversation_id; - this.$emit('select-conversation', conv); - }, - - async renameConversation(conv) { - const newTitle = prompt('请输入新标题:', conv.title); - if (newTitle && newTitle !== conv.title) { - try { - await fetch(`${this.apiBaseUrl}/conversations/update-title`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - conversation_id: conv.conversation_id, - title: newTitle - }) - }); - conv.title = newTitle; - } catch (error) { - console.error('Failed to rename:', error); - conv.title = newTitle; // 本地更新 - } - } - }, - - async archiveConversation(conv) { - try { - await fetch(`${this.apiBaseUrl}/conversations/archive`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - conversation_id: conv.conversation_id - }) - }); - await this.loadConversations(); - } catch (error) { - console.error('Failed to archive:', error); - } - }, - - async deleteConversation(conv) { - if (confirm(`确定要删除会话 "${conv.title}" 吗?`)) { - try { - await fetch(`${this.apiBaseUrl}/conversations/delete`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - conversation_id: conv.conversation_id - }) - }); - await this.loadConversations(); - if (this.currentConversationId === conv.conversation_id) { - this.currentConversationId = null; - this.$emit('select-conversation', null); - } - } catch (error) { - console.error('Failed to delete:', error); - } - } - } - } + template: ` +
+ + + + + + + +
+ +
+
Today
+
+
+ +
+
+
{{ conv.title }}
+
+ {{ conv.gene_family }} + {{ conv.message_count }} messages +
+
{{ conv.last_message }}
+
+
+ + + + +
+
+
+ + +
+
Yesterday
+
+
+ +
+
+
{{ conv.title }}
+
+ {{ conv.gene_family }} + {{ conv.message_count }} +
+
+
+
+ + +
+
Past 7 days
+
+
+ +
+
+
{{ conv.title }}
+
+ {{ conv.gene_family }} +
+
+
+
+ + +
+ +

No conversations yet

+

Click "New Chat" to start gene family analysis

+
+
+ + + +
+ `, + + props: { + userId: { + type: String, + default: 'xia-lab' + }, + apiBaseUrl: { + type: String, + default: 'http://localhost:8000/api' + } + }, + + data() { + return { + isCollapsed: false, + searchQuery: '', + conversations: [], + currentConversationId: null, + loading: false, + // Icons + Plus: ElementPlusIconsVue.Plus, + ArrowLeft: ElementPlusIconsVue.ArrowLeft, + ArrowRight: ElementPlusIconsVue.ArrowRight, + ChatDotRound: ElementPlusIconsVue.ChatDotRound, + ChatLineRound: ElementPlusIconsVue.ChatLineRound, + More: ElementPlusIconsVue.More, + Edit: ElementPlusIconsVue.Edit, + Folder: ElementPlusIconsVue.Folder, + Delete: ElementPlusIconsVue.Delete, + UserFilled: ElementPlusIconsVue.UserFilled, + } + }, + + computed: { + filteredConversations() { + if (!this.searchQuery) return this.conversations; + const query = this.searchQuery.toLowerCase(); + return this.conversations.filter(conv => + conv.title.toLowerCase().includes(query) || + (conv.gene_family && conv.gene_family.toLowerCase().includes(query)) || + conv.last_message.toLowerCase().includes(query) + ); + }, + + todayConversations() { + const today = new Date().toDateString(); + return this.filteredConversations.filter(conv => { + const convDate = new Date(conv.updated_at).toDateString(); + return convDate === today; + }); + }, + + yesterdayConversations() { + const yesterday = new Date(Date.now() - 86400000).toDateString(); + return this.filteredConversations.filter(conv => { + const convDate = new Date(conv.updated_at).toDateString(); + return convDate === yesterday; + }); + }, + + olderConversations() { + const yesterday = new Date(Date.now() - 86400000).toDateString(); + return this.filteredConversations.filter(conv => { + const convDate = new Date(conv.updated_at).toDateString(); + return convDate < yesterday; + }); + } + }, + + mounted() { + this.loadConversations(); + // Auto-refresh + this.refreshInterval = setInterval(() => { + this.loadConversations(); + }, 30000); // 30 seconds refresh interval + }, + + beforeUnmount() { + if (this.refreshInterval) { + clearInterval(this.refreshInterval); + } + }, + + methods: { + async loadConversations() { + try { + this.loading = true; + const response = await fetch(`${this.apiBaseUrl}/conversations/list/${this.userId}`); + if (response.ok) { + const data = await response.json(); + this.conversations = data.conversations || []; + } + } catch (error) { + console.error('Failed to load conversations:', error); + // Use mock data + this.conversations = this.getMockConversations(); + } finally { + this.loading = false; + } + }, + + getMockConversations() { + // Mock data for testing + return [ + { + conversation_id: 'conv_001', + title: 'At.WRKY gene family analysis', + gene_family: 'WRKY', + species: 'At', + message_count: 12, + last_message: 'Phylogenetic tree done', + updated_at: new Date().toISOString() + }, + { + conversation_id: 'conv_002', + title: 'Os.TCP evolution analysis', + gene_family: 'TCP', + species: 'Os', + message_count: 5, + last_message: 'Building tree...', + updated_at: new Date(Date.now() - 3600000).toISOString() + }, + { + conversation_id: 'conv_003', + title: 'HMMER config consultation', + message_count: 8, + last_message: 'E-value 1e-5 recommended', + updated_at: new Date(Date.now() - 86400000).toISOString() + } + ]; + }, + + toggleSidebar() { + this.isCollapsed = !this.isCollapsed; + this.$emit('toggle', this.isCollapsed); + }, + + async createNewConversation() { + try { + const response = await fetch(`${this.apiBaseUrl}/conversations/create`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + user_id: this.userId, + title: 'New Chat ' + new Date().toLocaleTimeString() + }) + }); + + if (response.ok) { + const data = await response.json(); + this.currentConversationId = data.conversation_id; + this.$emit('new-conversation', data); + await this.loadConversations(); + } + } catch (error) { + console.error('Failed to create conversation:', error); + // Create local conversation + const newConv = { + conversation_id: 'conv_' + Date.now(), + title: 'New Chat', + message_count: 0, + last_message: '', + updated_at: new Date().toISOString() + }; + this.conversations.unshift(newConv); + this.currentConversationId = newConv.conversation_id; + this.$emit('new-conversation', newConv); + } + }, + + selectConversation(conv) { + this.currentConversationId = conv.conversation_id; + this.$emit('select-conversation', conv); + }, + + async renameConversation(conv) { + const newTitle = prompt('Enter new title:', conv.title); + if (newTitle && newTitle !== conv.title) { + try { + await fetch(`${this.apiBaseUrl}/conversations/update-title`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + conversation_id: conv.conversation_id, + title: newTitle + }) + }); + conv.title = newTitle; + } catch (error) { + console.error('Failed to rename:', error); + conv.title = newTitle; // local update + } + } + }, + + async archiveConversation(conv) { + try { + await fetch(`${this.apiBaseUrl}/conversations/archive`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + conversation_id: conv.conversation_id + }) + }); + await this.loadConversations(); + } catch (error) { + console.error('Failed to archive:', error); + } + }, + + async deleteConversation(conv) { + if (confirm(`Delete conversation "${conv.title}"?`)) { + try { + await fetch(`${this.apiBaseUrl}/conversations/delete`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + conversation_id: conv.conversation_id + }) + }); + await this.loadConversations(); + if (this.currentConversationId === conv.conversation_id) { + this.currentConversationId = null; + this.$emit('select-conversation', null); + } + } catch (error) { + console.error('Failed to delete:', error); + } + } + } + } }; -// 导出组件 +// Export component if (typeof module !== 'undefined' && module.exports) { - module.exports = { ConversationSidebar }; + module.exports = { ConversationSidebar }; } diff --git a/apps/web/vue3/static/i18n.js b/apps/web/vue3/static/i18n.js new file mode 100644 index 000000000..770d574fe --- /dev/null +++ b/apps/web/vue3/static/i18n.js @@ -0,0 +1,1911 @@ +// /static/i18n.js — CropAI 中英文翻译对照表 +// 默认中文,由 Vue setup() 中 reactive t() 接管切换 +window.__CROPAI_LANG__ = 'zh'; + +// 全局 t/tp 可能被 Vue reactive 版本覆盖;保留为兼容回退 +function t(key) { + var entry = I18N_MAP[key]; + if (!entry) return '⚠' + key; + var lang = window.__CROPAI_LANG__ || 'zh'; + return entry[lang] || entry['zh'] || key; +} + +// 带参数替换: t('found-node', { name: 'xxx' }) +function tp(key, params) { + var s = t(key); + if (params) { + Object.keys(params).forEach(function(k) { + s = s.replace('{' + k + '}', params[k]); + }); + } + return s; +} + +var I18N_MAP = { + // ========== 通用 ========== + 'send': { zh: '发送', en: 'Send' }, + 'cancel': { zh: '取消', en: 'Cancel' }, + 'confirm': { zh: '确认', en: 'Confirm' }, + 'close': { zh: '关闭', en: 'Close' }, + 'loading': { zh: '加载中...', en: 'Loading...' }, + 'processing': { zh: '处理中...', en: 'Processing...' }, + 'refresh': { zh: '刷新', en: 'Refresh' }, + 'delete': { zh: '删除', en: 'Delete' }, + 'search': { zh: '搜索', en: 'Search' }, + 'download': { zh: '下载', en: 'Download' }, + 'upload': { zh: '上传', en: 'Upload' }, + 'save': { zh: '保存', en: 'Save' }, + 'reset': { zh: '重置', en: 'Reset' }, + 'prefix': { zh: '前缀', en: 'Prefix' }, + 'status': { zh: '状态', en: 'Status' }, + 'copy': { zh: '复制', en: 'Copy' }, + 'new-chat': { zh: 'New Chat', en: 'New Chat' }, + + // ========== agent_status_component ========== + 'agent-assistant': { zh: '🤖 Agent 智能助手', en: '🤖 Agent Assistant' }, + 'standby': { zh: '待机', en: 'Standby' }, + 'enter-question': { zh: '输入您的问题,例如:分析SPL基因家族', en: 'Enter your question, e.g.: Analyze SPL gene family' }, + 'task-list': { zh: '📋 任务列表', en: '📋 Task List' }, + 'user-role': { zh: '👤 用户', en: '👤 User' }, + 'agent-role': { zh: '🤖 Agent', en: '🤖 Agent' }, + 'system-role': { zh: '💬 系统', en: '💬 System' }, + 'error-role': { zh: '❌ 错误', en: '❌ Error' }, + 'execution-role': { zh: '⚙️ 执行', en: '⚙️ Execution' }, + 'planning-role': { zh: '📋 规划', en: '📋 Planning' }, + 'diagnosis-role': { zh: '🔍 诊断', en: '🔍 Diagnosis' }, + 'msg-task-submitted': { zh: '任务已提交: ', en: 'Task submitted: ' }, + 'msg-submit-failed': { zh: '提交失败', en: 'Submission failed' }, + 'msg-request-failed': { zh: '请求失败: ', en: 'Request failed: ' }, + 'msg-task-completed': { zh: '任务完成', en: 'Task completed' }, + 'msg-task-failed': { zh: '任务失败', en: 'Task failed' }, + 'msg-analysis-complete': { zh: '✅ 分析完成! 找到 ', en: '✅ Analysis complete! Found ' }, + 'msg-gene-members': { zh: ' 个基因成员', en: ' gene members' }, + + // ========== index-with-sidebar ========== + 'prefix-placeholder': { zh: '如: Ft.SPL', en: 'e.g. Ft.SPL' }, + 'gf-analysis': { zh: '基因家族分析', en: 'Gene Family Analysis' }, + 'gf-analysis-system': { zh: '🌱 BotanicalBaseAgent - 基因家族分析系统', en: '🌱 BotanicalBaseAgent - Gene Family Analysis System' }, + 'search-conv': { zh: '搜索会话...', en: 'Search conversations...' }, + 'conv-list': { zh: '会话列表', en: 'Conversations' }, + 'msg-count': { zh: '条消息', en: ' messages' }, + 'select-stage': { zh: '选择分析阶段', en: 'Select Stage' }, + 'identify-label': { zh: 'Identify - 基因家族鉴定', en: 'Identify - Gene Family Identification' }, + 'phylogeny-label': { zh: 'Phylogeny - 系统发育分析', en: 'Phylogeny - Phylogenetic Analysis' }, + 'motif-label': { zh: 'Motif - Motif分析', en: 'Motif - Motif Analysis' }, + 'domain-label': { zh: 'Domain - 结构域分析', en: 'Domain - Domain Analysis' }, + 'expression-label': { zh: 'Expression - 表达分析', en: 'Expression - Expression Analysis' }, + 'execute-analysis': { zh: '🚀 执行分析', en: '🚀 Execute Analysis' }, + 'analysis-stage': { zh: '▶ Analysis Stage', en: '▶ Analysis Stage' }, + 'param-settings': { zh: '⚙️ 参数设置', en: '⚙️ Parameters' }, + 'user': { zh: '用户', en: 'User' }, + 'ai-assistant': { zh: 'AI助手', en: 'AI Assistant' }, + 'initial-welcome': { zh: '欢迎来到 "{title}"!我是BotanicalBaseAgent,专注于基因家族分析。请告诉我您想分析哪个基因家族?', en: 'Welcome to "{title}"! I am BotanicalBaseAgent, specialized in gene family analysis. Tell me which gene family you want to analyze?' }, + 'describe-need': { zh: '描述您的需求,如:帮我分析拟南芥SPL基因家族', en: 'Describe your needs, e.g.: Help me analyze the Arabidopsis SPL gene family' }, + 'results-here': { zh: '分析结果将在此显示', en: 'Analysis results will appear here' }, + 'start-new-chat': { zh: '开始一个新的对话', en: 'Start a new conversation' }, + 'or-continue': { zh: '或点击左侧会话继续之前的对话', en: 'Or click a conversation on the left to continue' }, + 'completed': { zh: '已完成', en: 'Completed' }, + 'running': { zh: '运行中', en: 'Running' }, + 'pending': { zh: '等待中', en: 'Pending' }, + 'msg-select-stage-first': { zh: '请先选择分析阶段', en: 'Please select an analysis stage first' }, + 'msg-executing': { zh: '开始执行 ', en: 'Starting execution: ' }, + 'msg-analysis-text': { zh: ' 分析', en: ' analysis' }, + + // ========== kg.html ========== + 'kg-title': { zh: '知识图谱 - V13.1 基因家族分析', en: 'Knowledge Graph - V13.1 Gene Family Analysis' }, + 'kg-visualization': { zh: '🧬 知识图谱可视化', en: '🧬 Knowledge Graph Visualization' }, + 'kg-subtitle': { zh: 'V13.1 基因家族分析系统 - Pecan SPL', en: 'V13.1 Gene Family Analysis System - Pecan SPL' }, + 'back-to-main': { zh: '返回主界面', en: 'Back to Main' }, + 'kg-stats': { zh: '📊 图谱统计', en: '📊 Graph Statistics' }, + 'node-count': { zh: '节点总数', en: 'Total Nodes' }, + 'edge-count': { zh: '关系总数', en: 'Total Edges' }, + 'node-types': { zh: '节点类型', en: 'Node Types' }, + 'edge-types': { zh: '关系类型', en: 'Edge Types' }, + 'node-search': { zh: '🔍 节点搜索', en: '🔍 Node Search' }, + 'enter-gene-name': { zh: '输入基因名或实体...', en: 'Enter gene name or entity...' }, + 'relation-filter-pc': { zh: '🏷️ 关系过滤 (PC语义)', en: '🏷️ Relation Filter (PC Semantic)' }, + 'activation-induction': { zh: '激活/诱导', en: 'Activation/Induction' }, + 'repression-inhibition': { zh: '抑制/下调', en: 'Repression/Inhibition' }, + 'regulation-control': { zh: '调控', en: 'Regulation/Control' }, + 'expression-detection': { zh: '表达', en: 'Expression/Detection' }, + 'association-interaction': { zh: '关联', en: 'Association/Interaction' }, + 'localization': { zh: '定位', en: 'Localization' }, + 'containment-composition': { zh: '包含', en: 'Containment/Composition' }, + 'participation-function': { zh: '参与', en: 'Participation/Function' }, + 'other-rel': { zh: '其他', en: 'Other' }, + 'node-legend-pc': { zh: '🎨 节点图例 (PC语义)', en: '🎨 Node Legend (PC Semantic)' }, + 'edge-legend-pc': { zh: '🔗 关系图例 (PC语义)', en: '🔗 Edge Legend (PC Semantic)' }, + 'fit-view': { zh: '适应视图', en: 'Fit View' }, + 'reset-filters': { zh: '重置过滤', en: 'Reset Filters' }, + 'click-drag-hint': { zh: '💡 点击节点查看详情,拖拽调整布局', en: '💡 Click nodes for details, drag to adjust layout' }, + 'node-detail': { zh: '📋 节点详情', en: '📋 Node Details' }, + 'node-name': { zh: '节点名称', en: 'Node Name' }, + 'node-type-pc': { zh: '节点类型 (PC)', en: 'Node Type (PC)' }, + 'connection-count': { zh: '连接关系数', en: 'Connections' }, + 'click-node-detail': { zh: '点击图谱中的节点查看详情', en: 'Click a node in the graph to view details' }, + 'related-relations': { zh: '🔗 相关关系', en: '🔗 Related Relations' }, + 'more-relations': { zh: '还有 {count} 个关系...', en: '{count} more relations...' }, + 'msg-kg-loaded': { zh: '知识图谱加载完成 (PC语义规范)', en: 'Knowledge graph loaded (PC Semantic)' }, + 'msg-load-data-failed': { zh: '加载数据失败: ', en: 'Data load failed: ' }, + 'msg-node-found': { zh: '找到节点: ', en: 'Node found: ' }, + 'msg-node-not-found': { zh: '未找到匹配的节点', en: 'No matching node found' }, + + // ========== NEW ENTRIES ========== + '1basedinclusivealignmentcolumnendsite': { zh: '1-based inclusive alignment column / 位点终点', en: '1-based inclusive alignment column / End Site' }, + '1basedinclusivealignmentcolumnstartsite': { zh: '1-based inclusive alignment column / 位点起点', en: '1-based inclusive alignment column / Start Site' }, + '11samplesforpipelinesmoketestingonlynotf': { zh: '11 个样本仅用于流程烟雾测试,不用于稳定群体结构推断。', en: '11 samples for pipeline smoke testing only; not for stable population structure inference.' }, + '11samplevcfrequired': { zh: '11 样本 VCF(必填)', en: '11-sample VCF (Required)' }, + '22msareplotregionreplot': { zh: '2.2 MSA Replot / 区间重绘', en: '2.2 MSA Replot / Region Replot' }, + '23treereplotphylogenetictreereplot': { zh: '2.3 Tree Replot / 进化树重绘', en: '2.3 Tree Replot / Phylogenetic Tree Replot' }, + '25subfamilyconfirmation': { zh: '2.5 亚家族确认', en: '2.5 Subfamily Confirmation' }, + 'autoexecutewithcurrentparamsifidle40spau': { zh: '40秒内不操作将使用当前参数自动执行,可随时暂停倒计时后手动确认。', en: 'Auto-execute with current params if idle 40s; pause countdown for manual.' }, + '61promotercustomplot': { zh: '6.1 启动子自定义绘图', en: '6.1 Promoter Custom Plot' }, + '71intraspeciessyntenycircosreplot': { zh: '7.1 种内共线性 Circos 重绘', en: '7.1 Intraspecies Synteny Circos Replot' }, + 'intraspeciessynteny': { zh: '7️⃣ 种内Synteny', en: 'Intraspecies Synteny' }, + 'interspeciessynteny': { zh: '9️⃣ 种间Synteny', en: 'Interspecies Synteny' }, + 'rnaseqanalysis': { zh: '===== RNA-Seq 分析 =====', en: '----- RNA-Seq Analysis -----' }, + 'datapreparation': { zh: '===== 数据准备 =====', en: '----- Data Preparation -----' }, + 'coreanalysis': { zh: '===== 核心分析 =====', en: '----- Core Analysis -----' }, + 'kmaximum': { zh: '>K 最大值K 最小值指定 GWAS K(0=仅报告最佳 K)预览💡 可通过上方', en: 'Tip: via above' }, + 'alignstagedidnotfindupstreamrnaseqqcgene': { zh: 'Align 阶段没有找到上游 RNA-seq QC 生成的 *.clean.fastq.gz。', en: 'Align stage did not find upstream RNA-seq QC generated *.clean.fastq.gz.' }, + 'annotationbackgroundannotationgeneratege': { zh: 'Annotation - 背景注释(生成gene2go/gene2ko', en: 'Annotation - Background Annotation (generate gene2go/gene2ko)' }, + 'applyconfirmfill': { zh: 'Apply 确认填入', en: 'Apply Confirm Fill' }, + 'blastpercentidentitylowerboundfill50when': { zh: 'BLAST percent identity 下限;文献写 identity 50% 时填 50', en: 'BLAST percent identity lower bound; fill 50 when literature reports 50%' }, + 'blastengine': { zh: 'BLAST 引擎', en: 'BLAST Engine' }, + 'blastsignificancethresholdforcandidatesc': { zh: 'BLAST 显著性阈值,用于初步筛选候选基因', en: 'BLAST significance threshold for candidate screening' }, + 'blastreference': { zh: 'BLAST参考', en: 'BLAST Reference' }, + 'bootstrapsize': { zh: 'Bootstrap大小', en: 'Bootstrap Size' }, + 'celeryrestartedqueuecheckcomplete': { zh: 'Celery 已重启并完成队列检查', en: 'Celery Restarted & Queue Check Complete' }, + 'celeryrestartincomplete': { zh: 'Celery 重启未完成', en: 'Celery Restart Incomplete' }, + 'comborevisionparameters': { zh: 'Combo 修订参数', en: 'Combo Revision Parameters' }, + 'comborevisionrequiresatleasttwotypessele': { zh: 'Combo 修订至少选择两个类型。', en: 'Combo revision requires at least two types selected.' }, + 'comboplotrevisionfailed': { zh: 'Combo 图修订失败:', en: 'Combo Plot Revision Failed:' }, + 'comboplotrevisioncompleteswitchedtonewfi': { zh: 'Combo 图修订完成,已切换到新图', en: 'Combo plot revision complete; switched to new figure' }, + 'comboplotrevisionsubmittedtaskid': { zh: 'Combo 图修订已提交:task_id=', en: 'Combo plot revision submitted: task_id=' }, + 'comparativerolespecieseligibleasanalysis': { zh: 'Comparative 角色物种(可作为本次待分析物种)', en: 'Comparative Role Species (eligible as analysis species)' }, + 'demoduleautodetect': { zh: 'DE模块:自动识别', en: 'DE Module: Auto-detect' }, + 'domainparameters': { zh: 'Domain 参数', en: 'Domain Parameters' }, + 'domaincoveragefilterthresholdinpercenteg': { zh: 'Domain 绘图覆盖度过滤阈值,按百分比填写;例如 30 表示 30%', en: 'Domain coverage filter threshold in percent; e.g. 30 means 30%' }, + 'domainuseshmmerhmmscanthisvaluepassedtoe': { zh: 'Domain 阶段使用 HMMER hmmscan 扫描 Pfam;该值传给 --evalue 并用于 i-Evalue 过滤,越小越严格', en: 'Domain uses HMMER hmmscan; this value passed to --evalue for i-Evalue filter (smaller = stricter)' }, + 'ensemblformat': { zh: 'Ensembl 格式', en: 'Ensembl Format' }, + 'expressionusingfpkmdifferentialexpressio': { zh: 'Expression (使用FPKM) - Differential Expression', en: 'Expression (using FPKM) - Differential Expression' }, + 'expressionparametersfpkmtpmmatrix': { zh: 'Expression 参数 (FPKM/TPM矩阵', en: 'Expression Parameters (FPKM/TPM matrix)' }, + 'fastafileleaveemptyforautodiscoverycomma': { zh: 'FASTA文件;可留空自动查找,多个用逗号分隔', en: 'FASTA file; leave empty for auto-discovery; comma-separated for multiples' }, + 'fastqfiles': { zh: 'FASTQ文件', en: 'FASTQ Files' }, + 'fimopvaluethresholddefault1e4': { zh: 'FIMO p-value 阈值,默认 1e-4', en: 'FIMO p-value threshold, default 1e-4' }, + 'fimoqvaluefilterthresholddefault005': { zh: 'FIMO q-value 过滤阈值,默认 0.05', en: 'FIMO q-value filter threshold, default 0.05' }, + 'filescopeunchanged': { zh: 'File_Scope不改', en: 'File_Scope (Unchanged)' }, + 'filetypeunchanged': { zh: 'File_Type不改', en: 'File_Type (Unchanged)' }, + 'gatkexecutionfailed': { zh: 'GATK 执行失败', en: 'GATK Execution Failed' }, + 'geonumber': { zh: 'GEO编号', en: 'GEO Number' }, + 'geonumberinputgeonumbereggse111937autodo': { zh: 'GEO编号 - InputGEO编号(如 GSE111937)自动Download', en: 'GEO Number - Input GEO Number (e.g. GSE111937) Auto-download' }, + 'goenrichment': { zh: 'GO 富集', en: 'GO Enrichment' }, + 'goenrichmentbackgroundmissing': { zh: 'GO 富集背景缺失', en: 'GO Enrichment Background Missing' }, + 'gokeggenrichmentbackgroundmissing': { zh: 'GO/KEGG 富集背景缺失', en: 'GO/KEGG Enrichment Background Missing' }, + 'gokeggenrichmentrequiresgene2goorgene2ko': { zh: 'GO/KEGG 富集需要 gene2go 或 gene2ko 背景映射文件,但当前任务没有找到可用文件。', en: 'GO/KEGG enrichment requires gene2go or gene2ko background mapping files; none found.' }, + 'gwasemmaxplotting': { zh: 'GWAS EMMAX绘图', en: 'GWAS EMMAX Plotting' }, + 'gwasmlmcmlmplotting': { zh: 'GWAS MLM/CMLM绘图', en: 'GWAS MLM/CMLM Plotting' }, + 'gwastasselkinshipmatrix': { zh: 'GWAS TASSEL亲缘关系矩阵', en: 'GWAS TASSEL Kinship Matrix' }, + 'gwasvcfsorthapmapconversion': { zh: 'GWAS VCF排序与HapMap转换', en: 'GWAS VCF Sort & HapMap Conversion' }, + 'gwasspeciesoutput': { zh: 'GWAS 物种与输出', en: 'GWAS Species & Output' }, + 'gwasinputvcf': { zh: 'GWAS 输入 VCF', en: 'GWAS Input VCF' }, + 'gwascovariatepreparation': { zh: 'GWAS协变量准备', en: 'GWAS Covariate Preparation' }, + 'gwasphenotypepreparation': { zh: 'GWAS表型准备', en: 'GWAS Phenotype Preparation' }, + 'genefamilyunchanged': { zh: 'Gene_Family不改', en: 'Gene_Family (Unchanged)' }, + 'genomepreparegenomedatapreprocessing': { zh: 'Genome Prepare - Genome数据预处理', en: 'Genome Prepare - Genome Data Preprocessing' }, + 'genomeprepareparameters': { zh: 'Genome Prepare 参数', en: 'Genome Prepare Parameters' }, + 'hisat2needsgenomefastaorgenomehisat2inde': { zh: 'HISAT2 比对应使用基因组 FASTA 或基因组 HISAT2 index,不能使用 CDS/PEP index。', en: 'HISAT2 needs genome FASTA or genome HISAT2 index, not CDS/PEP index.' }, + 'hmmpfamaudit': { zh: 'HMM/Pfam 审计', en: 'HMM/Pfam Audit' }, + 'hmmerparameterconsultation': { zh: 'HMMER参数配置咨询', en: 'HMMER Parameter Consultation' }, + 'idlistfileegpathtogeneids': { zh: 'ID列表文件,如 /path/to/gene.ids', en: 'ID list file, e.g. /path/to/gene.ids' }, + 'idlistfileegathdzipidsautolookupbyoutput': { zh: 'ID列表文件,如 At.HD-ZIP.ids;留空时按输出前缀自动查找', en: 'ID list file, e.g. At.HD-ZIP.ids; auto-lookup by output prefix' }, + 'iqtreeparamsegmmfpbb1000': { zh: 'IQ-TREE 建树参数,如 -m MFP -bb 1000', en: 'IQ-TREE params, e.g. -m MFP -bb 1000' }, + 'identifyblastreference': { zh: 'Identify BLAST参考', en: 'Identify BLAST Reference' }, + 'identifyblastreferencespeciesegatos': { zh: 'Identify BLAST参考物种,如 At / Os', en: 'Identify BLAST reference species, e.g. At / Os' }, + 'identifyblastreferenceegatos': { zh: 'Identify BLAST参考,例如 At / Os', en: 'Identify BLAST reference, e.g. At / Os' }, + 'identifydomainmemberconfirmation': { zh: 'Identify Domain 成员确认', en: 'Identify Domain Member Confirmation' }, + 'identifyrefinerevisememberidsrebuildprot': { zh: 'Identify Refine - 修订成员ID并重建蛋白', en: 'Identify Refine - Revise Member IDs & Rebuild Proteins' }, + 'identifyparameters': { zh: 'Identify 参数', en: 'Identify Parameters' }, + 'hmmmodelcoveragethresholdforidentify01cl': { zh: 'Identify 阶段 HMM 模型覆盖度阈值,按 0-1 比例填写;对应 CLI --hmm-cov-min', en: 'HMM model coverage threshold for Identify (0-1); CLI --hmm-cov-min' }, + 'hmmerhmmsearchievaluefilterforidentifycl': { zh: 'Identify 阶段使用 HMMER hmmsearch,过滤 domtblout 的 independent domain E-value;对应 CLI --dom-i-evalue-max,越小越严格', en: 'HMMER hmmsearch i-Evalue filter for Identify; CLI --dom-i-evalue-max' }, + 'inputspecieslatinnameegarabidopsisthalia': { zh: 'Input物种拉丁名 (如 Arabidopsis thaliana', en: 'Input Species Latin Name (e.g. Arabidopsis thaliana)' }, + 'inputspecieslatinnameegarabidopsisthalia-2': { zh: 'Input物种拉丁名,如 Arabidopsis thaliana', en: 'Input species Latin name, e.g. Arabidopsis thaliana' }, + 'interspeciessyntenycrossspeciessynteny': { zh: 'Interspecies Synteny - 物种间共线性分析 (跨物种', en: 'Interspecies Synteny - Cross-Species Synteny' }, + 'jgiformat': { zh: 'JGI 格式', en: 'JGI Format' }, + 'jsondataloadedtoconsole': { zh: 'JSON数据已加载到控制台', en: 'JSON data loaded to console' }, + 'kmaximum-2': { zh: 'K 最大值', en: 'K Maximum' }, + 'kminimum-2': { zh: 'K 最小值', en: 'K Minimum' }, + 'keggenrichment': { zh: 'KEGG 富集', en: 'KEGG Enrichment' }, + 'keggenrichmentbackgroundmissing': { zh: 'KEGG 富集背景缺失', en: 'KEGG Enrichment Background Missing' }, + 'kaksanalysis': { zh: 'Ka/Ks分析', en: 'Ka/Ks Analysis' }, + 'kaksparameters': { zh: 'KaKs 参数', en: 'KaKs Parameters' }, + 'knownsplicesitesource': { zh: 'Known splice site 来源', en: 'Known Splice Site Source' }, + 'm1standardgroupcomparison': { zh: 'M1 - 标准组间比较', en: 'M1 - Standard Group Comparison' }, + 'm3multigroupstratifiedcomparison': { zh: 'M3 - 多组合分层比较', en: 'M3 - Multi-group Stratified Comparison' }, + 'm4twowayinteractionanalysis': { zh: 'M4 - 双因素交互分析', en: 'M4 - Two-way Interaction Analysis' }, + 'mafftparamsegautothread1': { zh: 'MAFFT 多序列Alignment参数,如 --auto --thread -1', en: 'MAFFT params, e.g. --auto --thread -1' }, + 'numberofconservedmotifsminedbymeme': { zh: 'MEME 挖掘的保守 Motif 数量', en: 'Number of conserved motifs mined by MEME' }, + 'msaregionplot': { zh: 'MSA Region Plot - MSA区间绘图', en: 'MSA Region Plot' }, + 'msaregionplot-2': { zh: 'MSA区间图 (', en: 'MSA Region Plot (' }, + 'msaregionplotparameters': { zh: 'MSA区间绘图参数', en: 'MSA Region Plot Parameters' }, + 'msaregionreplotcomplete': { zh: 'MSA区间重绘完成', en: 'MSA Region Replot Complete' }, + 'msaregionreplotsubmittedtaskid': { zh: 'MSA区间重绘已提交:task_id=', en: 'MSA region replot submitted: task_id=' }, + 'msasourceautoresolvedfromcurrentimageman': { zh: 'MSA来源:将根据当前图片/manifest自动解析', en: 'MSA source: auto-resolved from current image/manifest' }, + 'minerudocumentparsing': { zh: 'MinerU 文档解析', en: 'MinerU Document Parsing' }, + 'motifparameters': { zh: 'Motif 参数', en: 'Motif Parameters' }, + 'motifmaximumaminoacidlength': { zh: 'Motif 最大氨基酸长度', en: 'Motif Maximum Amino Acid Length' }, + 'motifminimumaminoacidlength': { zh: 'Motif 最小氨基酸长度', en: 'Motif Minimum Amino Acid Length' }, + 'motifanalysis': { zh: 'Motif分析', en: 'Motif Analysis' }, + 'motifcount': { zh: 'Motif数量', en: 'Motif Count' }, + 'ncbitaxideg3702': { zh: 'NCBI TaxID,如 3702', en: 'NCBI TaxID, e.g. 3702' }, + 'ncbiformat': { zh: 'NCBI 格式', en: 'NCBI Format' }, + 'ncbisequencedownload': { zh: 'NCBI序列下载', en: 'NCBI Sequence Download' }, + 'nlruntimegatefailed': { zh: 'NL Runtime Gate 失败', en: 'NL Runtime Gate Failed' }, + 'nlruntimegatepassedstartinguidisplaygate': { zh: 'NL Runtime Gate 已通过,开始 UI Display Gate...', en: 'NL Runtime Gate Passed; Starting UI Display Gate...' }, + 'orgdbspecies': { zh: 'OrgDb物种', en: 'OrgDb Species' }, + 'orthologmapping': { zh: 'Ortholog 映射', en: 'Ortholog Mapping' }, + 'orthologppikakspausedawaitingpepcdsother': { zh: 'Ortholog/PPI/KaKs 已暂停等待 PEP/CDS 和映射;其它可执行阶段将继续提交。', en: 'Ortholog/PPI/KaKs paused awaiting PEP/CDS; other stages continue.' }, + 'ostcpevolutionaryanalysis': { zh: 'Os.TCP进化分析', en: 'Os.TCP Evolutionary Analysis' }, + 'pcacorrelationdistanceheatmapsandvstmatr': { zh: 'PCA、样本相关性热图、样本距离热图和 VST 矩阵通常已经生成;可先查看这些 QC 结果。若要让阶段标记成功,应在代码里对样本数少于 3 的情况跳过聚类树或改成距离热图。', en: 'PCA, correlation/distance heatmaps and VST matrix typically generated; for stage success skip clustering when N<3.' }, + 'ppiresetfailed': { zh: 'PPI Reset 失败', en: 'PPI Reset Failed' }, + 'ppiresetresult': { zh: 'PPI Reset 结果 (', en: 'PPI Reset Result (' }, + 'ppiresetinputgenelist': { zh: 'PPI Reset 输入基因列表', en: 'PPI Reset Input Gene List' }, + 'ppiparameters': { zh: 'PPI 参数', en: 'PPI Parameters' }, + 'ppiparametersproteininteraction': { zh: 'PPI 参数 (Protein Interaction', en: 'PPI Parameters (Protein Interaction)' }, + 'ppireferencespeciesnotconfirmed': { zh: 'PPI 参考物种未确认', en: 'PPI Reference Species Not Confirmed' }, + 'ppitechnicalrefmustcomefromconfirmedstri': { zh: 'PPI 的技术参考必须来自已确认的 STRING 候选;项目参考物种不会写入 PPI owner。', en: 'PPI technical ref must come from confirmed STRING candidates; project species not written to PPI owner.' }, + 'ppinearsourcestringrefnotconfirmedorthol': { zh: 'PPI 近源 STRING 参考物种尚未确认;本次不提交 Ortholog 或 PPI。', en: 'PPI near-source STRING ref not confirmed; Ortholog/PPI not submitted.' }, + 'ppikaksdownloadfailurefallbackconfirmati': { zh: 'PPI/KaKs 下载失败兜底确认', en: 'PPI/KaKs Download Failure Fallback Confirmation' }, + 'ppikaksfallbackconfirmation': { zh: 'PPI/KaKs 兜底确认', en: 'PPI/KaKs Fallback Confirmation' }, + 'ppikaksreferencedata': { zh: 'PPI/KaKs 参考数据', en: 'PPI/KaKs Reference Data' }, + 'ppikaksreferencedataorthologprecheckfail': { zh: 'PPI/KaKs 参考数据/同源映射预检未通过。', en: 'PPI/KaKs reference data/ortholog pre-check failed.' }, + 'ppikaksreferencedataprocessing': { zh: 'PPI/KaKs 参考数据处理', en: 'PPI/KaKs Reference Data Processing' }, + 'ppikakscannotexecuterefspeciesdatanotrea': { zh: 'PPI/KaKs 暂时不能直接执行:参考物种数据还没准备好。', en: 'PPI/KaKs cannot execute: ref species data not ready.' }, + 'ppikaksneedsrefspeciesorthologprocessing': { zh: 'PPI/KaKs 需要先处理参考物种/Ortholog', en: 'PPI/KaKs needs ref species/Ortholog processing first' }, + 'ppikaksrequiresrefspeciespepcdsandorthol': { zh: 'PPI/KaKs 需要参考物种 PEP/CDS 和 Ortholog 映射,已先暂停相关阶段。', en: 'PPI/KaKs requires ref species PEP/CDS and Ortholog mapping; related stages paused.' }, + 'ppikaksprecheckfailed': { zh: 'PPI/KaKs 预检失败', en: 'PPI/KaKs Pre-check Failed' }, + 'ppianalysis': { zh: 'PPI分析', en: 'PPI Analysis' }, + 'phylogenyparameters': { zh: 'Phylogeny 参数', en: 'Phylogeny Parameters' }, + 'qctools': { zh: 'QC 工具', en: 'QC Tools' }, + 'rreturnedanerrorprecedingwarningsmaynotb': { zh: 'R 已返回错误。前面的 warning 不一定是失败原因,真正原因通常在日志最后的“错误于/停止执行”附近。', en: 'R returned an error. Preceding warnings may not be the cause; check near "Error in/Execution halted" at log end.' }, + 'rscriptexecutionfailed': { zh: 'R 脚本执行失败', en: 'R Script Execution Failed' }, + 'ragmethodologyextractionlaunchfailed': { zh: 'RAG 方法学提取启动失败', en: 'RAG Methodology Extraction Launch Failed' }, + 'ragsource': { zh: 'RAG来源', en: 'RAG Source' }, + 'ragstreamresponsereturnednofinalanswer': { zh: 'RAG流式响应未返回最终回答', en: 'RAG Stream Response Returned No Final Answer' }, + 'ragstreamresponseparsefailed': { zh: 'RAG流式响应解析失败', en: 'RAG Stream Response Parse Failed' }, + 'ragstreamrequestfailed': { zh: 'RAG流式请求失败', en: 'RAG Stream Request Failed' }, + 'raginterpretationrefreshfailed': { zh: 'RAG解读刷新失败', en: 'RAG Interpretation Refresh Failed' }, + 'raginterpretationenhanced': { zh: 'RAG解读增强', en: 'RAG Interpretation Enhanced' }, + 'raginterpretationrefreshed': { zh: 'RAG解读已刷新', en: 'RAG Interpretation Refreshed' }, + 'ragrequestfailed': { zh: 'RAG请求失败', en: 'RAG Request Failed' }, + 'rnaseqcandidatefamilycandidatefamilyscre': { zh: 'RNA-Seq Candidate Family - 候选家族筛选', en: 'RNA-Seq Candidate Family - Candidate Family Screening' }, + 'rnaseqdedifferentialexpression': { zh: 'RNA-Seq DE - 差异表达', en: 'RNA-Seq DE - Differential Expression' }, + 'rnaseqgoenrichgoenrichmentanalysis': { zh: 'RNA-Seq GO Enrich - GO富集分析', en: 'RNA-Seq GO Enrich - GO Enrichment Analysis' }, + 'rnaseqkeggenrichkeggenrichmentanalysis': { zh: 'RNA-Seq KEGG Enrich - KEGG富集分析', en: 'RNA-Seq KEGG Enrich - KEGG Enrichment Analysis' }, + 'rnaseqsampleqcsamplequalityassessment': { zh: 'RNA-Seq Sample QC - 样本质量评估', en: 'RNA-Seq Sample QC - Sample Quality Assessment' }, + 'rnaseqwgcnaweightedcoexpressionanalysis': { zh: 'RNA-Seq WGCNA - 加权共表达分析', en: 'RNA-Seq WGCNA - Weighted Co-expression Analysis' }, + 'rnaseqfgsearankedenrichmentanalysis': { zh: 'RNA-Seq fgsea - 排序富集分析', en: 'RNA-Seq fgsea - Ranked Enrichment Analysis' }, + 'rnaseqalignparameters': { zh: 'RNA-seq Align 参数', en: 'RNA-seq Align Parameters' }, + 'rnaseqalignparametersalignmentstep2': { zh: 'RNA-seq Align 参数 (Alignment - Step 2', en: 'RNA-seq Align Parameters (Alignment - Step 2)' }, + 'rnaseqcandidateparameters': { zh: 'RNA-seq Candidate 参数', en: 'RNA-seq Candidate Parameters' }, + 'rnaseqdeparametersstep4': { zh: 'RNA-seq DE 参数 (差异表达 - Step 4', en: 'RNA-seq DE Parameters (Step 4)' }, + 'rnaseqenrichparametersstep5': { zh: 'RNA-seq Enrich 参数 (Enrichment Analysis - Step 5', en: 'RNA-seq Enrich Parameters (Step 5)' }, + 'rnaseqfgseaparameters': { zh: 'RNA-seq FGSEA 参数', en: 'RNA-seq FGSEA Parameters' }, + 'rnaseqqcparametersstep1': { zh: 'RNA-seq QC 参数 (Quality Control - Step 1', en: 'RNA-seq QC Parameters (Step 1)' }, + 'rnaseqqctoolparameters': { zh: 'RNA-seq QC 工具参数', en: 'RNA-seq QC Tool Parameters' }, + 'rnaseqquantparametersstep3': { zh: 'RNA-seq Quant 参数 (Quantification - Step 3', en: 'RNA-seq Quant Parameters (Step 3)' }, + 'rnaseqwgcnaparameters': { zh: 'RNA-seq WGCNA 参数', en: 'RNA-seq WGCNA Parameters' }, + 'rnaseqanalysischainconfirmation': { zh: 'RNA-seq 分析链路确认', en: 'RNA-seq Analysis Chain Confirmation' }, + 'rnaseqparameters': { zh: 'RNA-seq 参数', en: 'RNA-seq Parameters' }, + 'rnaseqquantificationparameters': { zh: 'RNA-seq 定量参数', en: 'RNA-seq Quantification Parameters' }, + 'rnaseqenrichmentbackgroundmissing': { zh: 'RNA-seq 富集背景缺失', en: 'RNA-seq Enrichment Background Missing' }, + 'rnaseqenrichmentadvancedparameters': { zh: 'RNA-seq 富集高级参数', en: 'RNA-seq Enrichment Advanced Parameters' }, + 'rnaseqdifferentialexpressionparameters': { zh: 'RNA-seq 差异分析参数', en: 'RNA-seq Differential Expression Parameters' }, + 'rnaseqalignmentreferencefileincorrect': { zh: 'RNA-seq 比对参考文件不对', en: 'RNA-seq Alignment Reference File Incorrect' }, + 'rnaseqspeciesinfoforkeggfgseaenrichment': { zh: 'RNA-seq 物种信息(KEGG/fgsea/富集用)', en: 'RNA-seq Species Info (for KEGG/fgsea/Enrichment)' }, + 'refunchanged': { zh: 'Ref不改', en: 'Ref (Unchanged)' }, + 'snpdensityanalysis': { zh: 'SNP密度分析', en: 'SNP Density Analysis' }, + 'stringscorethresholddefault200': { zh: 'STRING score阈值,默认200', en: 'STRING score threshold, default 200' }, + 'stringlinkfilecontent': { zh: 'STRING 链接文件内容:', en: 'STRING Link File Content:' }, + 'salmontximporttpmentersexpressionplotsaf': { zh: 'Salmon/tximport TPM 只在 bridge QC 通过后进入 expression plots;tximport counts_from_abundance 不作为默认 DESeq2 输入。', en: 'Salmon/tximport TPM enters expression plots after bridge QC; tximport counts_from_abundance not default DESeq2 input.' }, + 'scorethreshold': { zh: 'Score阈值', en: 'Score Threshold' }, + 'selectgenomedatasourceformatautowillauto': { zh: 'SelectGenome数据来源格式,auto会自动检测', en: 'SelectGenome data source format; auto will auto-detect' }, + 'selectidconversionmethod': { zh: 'SelectID转换方式', en: 'SelectID Conversion Method' }, + 'selectinputmode': { zh: 'SelectInput模式', en: 'SelectInput Mode' }, + 'selectinputmodeuploadmanualrefgenomegtfd': { zh: 'SelectInput模式:上传模式需要手动上传参考Genome和GTF,Download模式可自动检索物种数据', en: 'SelectInput Mode: Upload=manual ref Genome+GTF; Download=auto-retrieve' }, + 'selectsession': { zh: 'Select会话', en: 'Select Session' }, + 'selectexistingworkingdirectory': { zh: 'Select已有Working Directory', en: 'Select Existing Working Directory' }, + 'selectdatabasetype': { zh: 'Select数据库类型', en: 'Select Database Type' }, + 'selectdatasource': { zh: 'Select数据来源', en: 'Select Data Source' }, + 'selectdatasourceuploadfilesorspecifyexis': { zh: 'Select数据来源方式:Upload Files或指定已有数据路径', en: 'Select Data Source: Upload Files or specify existing data path' }, + 'selectstage': { zh: 'Select阶段', en: 'Select Stage' }, + 'subfamilyconfirmconfirmsubfamilylabels': { zh: 'Subfamily Confirm - 确认亚家族标签', en: 'Subfamily Confirm - Confirm Subfamily Labels' }, + 'syntenyintraspeciessyntenymcscanxcircos': { zh: 'Synteny - 种内共线性分析 (MCScanX / Circos', en: 'Synteny - Intraspecies Synteny (MCScanX / Circos)' }, + 'tfbsparameters': { zh: 'TFBS 参数', en: 'TFBS Parameters' }, + 'tfbindingsiteprediction': { zh: 'TF结合位点预测', en: 'TF Binding Site Prediction' }, + 'targetrolespecieseligibleasanalysisspeci': { zh: 'Target 角色物种(可作为本次待分析物种)', en: 'Target Role Species (eligible as analysis species)' }, + 'tipmarkshape': { zh: 'Tip标记形状', en: 'Tip Mark Shape' }, + 'uidisplaygatefailed': { zh: 'UI Display Gate 失败', en: 'UI Display Gate Failed' }, + 'vcfallcontigs': { zh: 'VCF 全部 contig', en: 'VCF All Contigs' }, + 'wgs2gwasgeneticvariationpopulationanalys': { zh: 'WGS2GWAS(遗传变异与群体分析)', en: 'WGS2GWAS (Genetic Variation & Population Analysis)' }, + 'yesconfirmed': { zh: 'Yes,确认无误', en: 'Yes, Confirmed' }, + 'sessioncreatefailed': { zh: '[会话] 创建失败', en: '[Session] Create Failed' }, + 'sessiondeletefailed': { zh: '[会话] 删除失败', en: '[Session] Delete Failed' }, + 'sessionloaded': { zh: '[会话] 加载了', en: '[Session] Loaded' }, + 'sessionloadhistoryfailed': { zh: '[会话] 加载历史消息失败', en: '[Session] Load History Failed' }, + 'sessionloadfailed': { zh: '[会话] 加载失败', en: '[Session] Load Failed' }, + 'sessionstagescleared': { zh: '[会话] 已清空 stages 状态', en: '[Session] Stages Cleared' }, + 'sessionjobbound': { zh: '[会话] 已绑定 job', en: '[Session] Job Bound' }, + 'sessionjobrestored': { zh: '[会话] 恢复 job', en: '[Session] Job Restored' }, + 'sessionmessagepersistfailed': { zh: '[会话] 消息持久化失败', en: '[Session] Message Persist Failed' }, + 'sessionjobinfocleared': { zh: '[会话] 清空 jobInfo', en: '[Session] JobInfo Cleared' }, + 'sessionstagescleared-2': { zh: '[会话] 清空 stages', en: '[Session] Stages Cleared' }, + 'sessionmessagesclearednewsession': { zh: '[会话] 清空消息,新建会话', en: '[Session] Messages Cleared, New Session' }, + 'sessionbindjobfailed': { zh: '[会话] 绑定 job 失败', en: '[Session] Bind Job Failed' }, + 'sessionautocreatedsession': { zh: '[会话] 自动创建会话', en: '[Session] Auto-Created Session' }, + 'sessionautocreatefailedmessagesinpagemem': { zh: '[会话] 自动创建失败,消息仅保存在当前页面内存', en: '[Session] Auto-Create Failed; messages in page memory' }, + 'sessionautorestorerecentmessages': { zh: '[会话] 自动恢复最近会话消息', en: '[Session] Auto-Restore Recent Messages' }, + 'deepinterpretationrequestfailed': { zh: '[深度解读] 请求失败', en: '[Deep Interpretation] Request Failed' }, + 'alignmentcolumn': { zh: 'alignment列', en: 'Alignment Column' }, + 'configautodetectionsampleautodetection': { zh: 'autofillState.type === \'config\' ? \'配置表自动识别\' : \'样本表自动识别', en: 'Config Auto-detection / Sample Auto-detection' }, + 'filtermatchedrowsbytype': { zh: 'autofillState.type === \'samples\' ? \'筛选匹配行:SRR / Con-1 / CK / T0 / rep1 / fastq 前缀\' : \'筛选匹配行:At.SPL / Cpapaya_113_ / Lc / gff / pep', en: 'Filter matched rows by type' }, + 'bbav5parameters': { zh: 'bbav5 参数', en: 'bbav5 Parameters' }, + 'bbav5alignmentaudit': { zh: 'bbav5 对齐与审计', en: 'bbav5 Alignment & Audit' }, + 'bbav5tools': { zh: 'bbav5 工具', en: 'bbav5 Tools' }, + 'comparativespecies': { zh: 'comparative 比较物种', en: 'Comparative Species' }, + 'comparativespeciesforcomparisonnotchange': { zh: 'comparative 比较物种(参与比较/分类,不改为 target)', en: 'Comparative Species (for comparison; not changed to target)' }, + 'conditionunchanged': { zh: 'condition不改', en: 'Condition (Unchanged)' }, + 'confidencehighconfirmablemediumreviewlow': { zh: 'confidence: high 可确认,medium 建议检查,low 必须人工补全;正式写入前会自动备份旧文件。', en: 'Confidence: high=confirmable, medium=review, low=manual completion; auto-backup before write.' }, + 'countmatrixcontainsnonnumericcolumns': { zh: 'count matrix 含非数字列', en: 'Count matrix contains non-numeric columns' }, + 'samplenamesincountmatrixnotfoundinsample': { zh: 'count matrix 里的样本名没有在 sample_table.tsv/samples.yaml 中找到,或样本表缺少 sample/condition 列。', en: 'Sample names in count matrix not found in sample table, or missing sample/condition column.' }, + 'withoutmanualfilteringonlymembershitting': { zh: 'domainReviewSource === \'member_evidence_fallback\' ? \'未找到 InterProScan domain_review.tsv,当前显示 final_members 与 HMM/BLAST 证据;默认保留全部 final_members,确认后才继续方法学下游分析。\' : \'如果不手动筛选,系统默认只保留命中本基因家族目标结构域的成员;你也可以按 domain、e-value/score 和 coverage 调整后重新生成最终成员蛋白。', en: 'Without manual filtering, only members hitting target domain kept; adjust by domain, e-value/score and coverage.' }, + 'failabortondiscoverystrict': { zh: 'fail:发现即终止(严格)', en: 'fail: abort on discovery (strict)' }, + 'fastpexecutable': { zh: 'fastp 可执行文件', en: 'fastp Executable' }, + 'gene2godoesnotmatchdegeneids': { zh: 'gene2go 与 DE 基因 ID 不匹配', en: 'gene2go does not match DE gene IDs' }, + 'gene2gogobackground': { zh: 'gene2go(GO 背景)', en: 'gene2go (GO Background)' }, + 'gene2kokeggbackground': { zh: 'gene2ko(KEGG 背景)', en: 'gene2ko (KEGG Background)' }, + 'identifydonemethodologyneedsgenefamilyme': { zh: 'identify 已完成,但方法学链路需要先确认基因家族成员表', en: 'Identify done; methodology needs gene family member table confirmation' }, + 'includeunchanged': { zh: 'include不改', en: 'Include (Unchanged)' }, + 'gwasstagecheck': { zh: 'isGwasStage(confirmParams.stage) ? \'At / Os / Zm\' : \'留空则自动推断', en: 'GWAS stage check' }, + 'describerevisioncontenthere': { zh: 'lightweightExtensionConversation.pendingRevisionCardId ? \'请在这里说明需要修订的内容,然后发送。\' : (preferenceMode ? \'Ask a question about methods or biology...\' : \'Describe what you want to run (default prefix At).', en: 'Describe revision content here.' }, + 'log2fcthreshold': { zh: 'log2FC| 阈值', en: '|log2FC| Threshold' }, + 'maskexcludesmarkerstasselhapmapcannotrep': { zh: 'mask 会排除 TASSEL/HapMap 无法无损表示的标记;输出仅保留可严格复现的标记子集。', en: 'mask excludes markers TASSEL/HapMap cannot represent losslessly; only reproducible markers retained.' }, + 'maskandcontinuelossy': { zh: 'mask:屏蔽后继续(有损)', en: 'Mask and continue (lossy)' }, + 'planningstagefailedtogenerateexecutablew': { zh: 'n\\n规划阶段未能生成可执行流程,请查看后端日志中的具体原因。', en: 'Planning stage failed to generate executable workflow; check backend logs.' }, + 'padjthreshold': { zh: 'padj 阈值', en: 'padj Threshold' }, + 'pfamid': { zh: 'pfam号', en: 'Pfam ID' }, + 'plantairestartscriptorrestartplantai9000': { zh: 'projectRestartAvailable ? \'提交配置好的项目重启脚本\' : \'未配置 PLANTAI_RESTART_SCRIPT 或 restart_plantai_9000.sh', en: 'PLANTAI_RESTART_SCRIPT or restart_plantai_9000.sh not configured' }, + 'qrtpcrvalidation': { zh: 'qRT-PCR 验证', en: 'qRT-PCR Validation' }, + 'referencespecies': { zh: 'reference 参考物种', en: 'Reference Species' }, + 'referencespeciespreliminarytechnicalrefd': { zh: 'reference 参考物种(仅作为初步推荐,执行前将确定技术参考物种)', en: 'Reference Species (preliminary; technical ref determined before execution)' }, + 'referencespeciesforlabelmigrationonly': { zh: 'reference 参考物种(仅用于标签迁移)', en: 'Reference Species (for label migration only)' }, + 'replicateid': { zh: 'replicate(重复编号', en: 'Replicate (ID)' }, + 'replicateunchanged': { zh: 'replicate不改', en: 'Replicate (Unchanged)' }, + 'rununchanged': { zh: 'run不改', en: 'Run (Unchanged)' }, + 'sampleidunchanged': { zh: 'sample_id不改', en: 'Sample ID (Unchanged)' }, + 'samplesyamlbulkeditarea': { zh: 'samples.yaml 批量修订区', en: 'samples.yaml Bulk Edit Area' }, + 'splicesiteannotationpath': { zh: 'splice site / 注释路径', en: 'Splice Site / Annotation Path' }, + 'targetspecies': { zh: 'target 目标物种', en: 'Target Species' }, + 'targetcomparativerefinsametreecomboplota': { zh: 'target、comparative 与 reference 放入同一棵树、同一张组合证据图和一张联合亚家族确认表;确认表只包含待分类物种。', en: 'Target, comparative & ref in same tree, combo plot and joint confirmation table.' }, + 'timestagetimeseriesonly': { zh: 'time/stage(仅时间序列', en: 'Time/Stage (time series only)' }, + 'timestageunchanged': { zh: 'time/stage不改', en: 'Time/Stage (Unchanged)' }, + 'wholegenomeorknownfamily': { zh: 'whole_genome 或 known_family', en: 'whole_genome or known_family' }, + 'skip': { zh: '⏭️ 跳过', en: 'Skip' }, + 'recommendedrefdatadownloadmovedtobackgro': { zh: '⏳ 推荐参考数据下载已转入后台:', en: 'Recommended Ref Data Download Moved to Background:' }, + 'downloadfailurefallbackrequiresmanualcon': { zh: '⏸ 下载失败兜底需要手动确认', en: 'Download Failure Fallback Requires Manual Confirmation' }, + 'countdownpaused': { zh: '⏸ 倒计时已暂停', en: 'Countdown Paused' }, + 'countdownpausedpleaseconfirmparametersth': { zh: '⏸ 倒计时已暂停,请确认参数后手动执行', en: 'Countdown Paused; Please Confirm Parameters then Execute Manually' }, + 'fixskippedthisblocksdownstreamsubsequent': { zh: '⏸ 已跳过修复;该问题会阻断下游,后续阶段已暂停。', en: 'Fix Skipped; This Blocks Downstream; Subsequent Stages Paused.' }, + 'waitingforvalidvcfselection': { zh: '⏸ 等待选择有效 VCF', en: 'Waiting for Valid VCF Selection' }, + 'ppikaksprecheckfailedbatchpausedcomplete': { zh: '⏸️ PPI/KaKs 前置数据检查未通过,已暂停批量执行;请补齐参考注释包或确认参考物种后重新执行。', en: 'PPI/KaKs Pre-check Failed; Batch Paused. Complete Ref Packages then Re-execute.' }, + 'identifydoneconfirmgenefamilymembersfirs': { zh: '⏸️ identify 已完成,但方法学链路需要先确认基因家族成员表;保存成员确认后再继续 phylogeny。', en: 'Identify done; confirm gene family members first, then continue phylogeny.' }, + 'openedidentifymemberscreeningtablesaveto': { zh: '⏸️ 已打开 identify 成员初筛确认表;保存后会生成 curated_members,再继续亚家族证据阶段。', en: 'Opened identify member screening table; save to generate curated_members.' }, + 'foregroundbatchrunningwgsplanpreservedre': { zh: '⏸️ 当前已有前台批次执行中;WGS 规划已保留,请在当前批次结束后重新执行。', en: 'Foreground batch running; WGS plan preserved. Re-execute after batch completes.' }, + 'stopall': { zh: '⏹️ 停止全部', en: 'Stop All' }, + 'backendprecheckfailedbatchstoppedrepullp': { zh: '⏹️ 后端预检失败,当前批次已停止;请重新拉取规划后继续。', en: 'Backend Pre-check Failed; Batch Stopped. Re-pull Plan to Continue.' }, + 'analysisstage': { zh: '▶ 分析阶段 Analysis Stage', en: 'Analysis Stage' }, + 'parameterconfirmationadjustment': { zh: '⚙️ 参数确认与调整', en: 'Parameter Confirmation & Adjustment' }, + 'configuredpermethodologyplan': { zh: '⚙️ 已按方法学规划', en: 'Configured per Methodology Plan' }, + 'backgroundbatchstagesskippedduetodepende': { zh: '⚠️ 后台批次中以下阶段因依赖失败被跳过:', en: 'Background batch: stages skipped due to dependency failure:' }, + 'backgroundbatchcannotcontinue': { zh: '⚠️ 后台批次无法继续:', en: 'Background batch cannot continue:' }, + 'issuedetected': { zh: '⚠️ 检测到问题', en: 'Issue Detected' }, + 'autoannotationnote': { zh: '⚠️ 自动注释说明:', en: 'Auto-Annotation Note:' }, + 'interpretationrisk': { zh: '⚠️ 解释风险', en: 'Interpretation Risk' }, + 'ppikaksprecheckpassed': { zh: '✅ PPI/KaKs 前置数据检查通过:', en: 'PPI/KaKs Pre-check Passed:' }, + 'ppikaksprecheckpassedorthologexistsgener': { zh: '✅ PPI/KaKs 前置数据检查通过:当前批次已有 Ortholog,将先生成同源映射再继续下游分析。', en: 'PPI/KaKs pre-check passed: Ortholog exists; generating mapping then continuing downstream.' }, + 'fixappliedcontinuing': { zh: '✅ 已应用修复方案,继续执行...', en: 'Fix Applied; Continuing...' }, + 'confirmedarabidopsisfallbackforppikakson': { zh: '✅ 已确认使用拟南芥作为 PPI/KaKs 的显式兜底参考;该选择只写入 Ortholog/PPI/KaKs 专用参数,其它常规阶段不受影响。', en: 'Confirmed Arabidopsis fallback for PPI/KaKs; only Ortholog/PPI/KaKs params affected.' }, + 'selectedprojectreferencespecies': { zh: '✅ 已选择项目参考物种', en: 'Selected project reference species:' }, + 'executioncomplete': { zh: '✅ 执行完成', en: 'Execution Complete' }, + 'recommendedrefdatadownloadcomplete': { zh: '✅ 推荐参考数据下载完成:', en: 'Recommended Ref Data Download Complete:' }, + 'confirmexecution': { zh: '✅ 确认执行', en: 'Confirm Execution' }, + 'confirmselection': { zh: '✅ 确认选择', en: 'Confirm Selection' }, + 'autousingpreviousstepoutput': { zh: '✅ 自动使用上一步Output:', en: 'Auto-using Previous Step Output:' }, + 'stage': { zh: '✅ 阶段', en: 'Stage' }, + 'restoredpublished': { zh: '✓ 已恢复并发布。', en: 'Restored & Published.' }, + 'restoredcompleted': { zh: '✓ 已恢复并完成。', en: 'Restored & Completed.' }, + 'restoredcompletedcandidatereviewcardgene': { zh: '✓ 已恢复并完成;候选核对卡已生成。', en: 'Restored & Completed; candidate review card generated.' }, + 'restoredverificationcanbegin': { zh: '✓ 已恢复确认;可以开始验证。', en: 'Restored; verification can begin.' }, + 'resultsreviewrestoredauthorizedtopublish': { zh: '✓ 已恢复结果核对;可以授权发布。', en: 'Results review restored; authorized to publish.' }, + 'executionrestoredresultcardgenerated': { zh: '✓ 已恢复运行;本次结果卡已生成。', en: 'Execution restored; result card generated.' }, + 'verificationrestoredresultreviewcardgene': { zh: '✓ 已恢复验证;结果核对卡已生成。', en: 'Verification restored; result review card generated.' }, + 'explicitlyauthorizedpublished': { zh: '✓ 已显式授权并发布。', en: 'Explicitly authorized & published.' }, + 'runresultsreviewed': { zh: '✓ 已核对运行结果。', en: 'Run results reviewed.' }, + 'candidateconfirmednorevisions': { zh: '✓ 已确认候选|未作修订', en: 'Candidate confirmed; no revisions.' }, + 'inputparamsconfirmedruncompleted': { zh: '✓ 已确认输入与参数;本次运行已完成。', en: 'Input & params confirmed; run completed.' }, + 'executionentryreproducedcandidateinfogen': { zh: '✓ 执行入口已成功复现;候选信息已生成。', en: 'Execution entry reproduced; candidate info generated.' }, + 'semanticdescriptionregeneratedcommandnot': { zh: '✓ 语义说明已重新生成;执行命令未重新运行。', en: 'Semantic description regenerated; command not re-run.' }, + 'verificationcompletedresultreviewcardgen': { zh: '✓ 验证已完成;结果核对卡已生成。', en: 'Verification completed; result review card generated.' }, + 'cancel-2': { zh: '❌ 取消', en: 'Cancel' }, + 'fixapplicationfailed': { zh: '❌ 应用修复失败', en: 'Fix Application Failed' }, + 'batchexecutioncancelled': { zh: '❌ 批量执行已取消', en: 'Batch Execution Cancelled' }, + 'methodologyexecutionplanfailed': { zh: '❌ 方法学执行规划失败:', en: 'Methodology Execution Plan Failed:' }, + 'servicetemporarilyunavailable': { zh: '❌ 服务暂时不可用:', en: 'Service Temporarily Unavailable:' }, + 'networkerrorpleaseretry': { zh: '❌ 网络错误,请重试', en: 'Network Error; Please Retry' }, + 'resetview': { zh: '⟲ 重置视图', en: 'Reset View' }, + 'submittingrecommendedrefannotationdownlo': { zh: '⬇️ 正在提交推荐近源参考物种注释包后台下载;Ortholog/PPI/KaKs 将等待参考数据,其它阶段继续执行。', en: 'Submitting recommended ref annotation download; Ortholog/PPI/KaKs will wait.' }, + '1analysismodulequickcommands': { zh: '一、分析模块快速指令', en: '1. Analysis Module Quick Commands' }, + '3ragquickcommands': { zh: '三、RAG快速指令', en: '3. RAG Quick Commands' }, + 'threeagentcontributionaudit': { zh: '三个 agent 贡献审计', en: 'Three-agent Contribution Audit' }, + 'triangle': { zh: '三角形', en: 'Triangle' }, + 'uploadexecutablecodetestdataandoriginalc': { zh: '上传可执行代码、测试数据和原始命令,核对候选后验证并授权发布;发布后可指定输入和原命令已有参数运行。', en: 'Upload executable code, test data and original commands; verify candidates then publish.' }, + 'uploadfailed': { zh: '上传失败', en: 'Upload Failed' }, + 'uploadbackgroundfileorselectautoannotati': { zh: '上传对应背景文件,或选择自动注释模式先生成背景注释后再继续富集。', en: 'Upload background file or select auto-annotation mode to generate backgrounds then enrich.' }, + 'uploadverifiedcodeandtestdataexecutiontr': { zh: '上传已跑通过的代码和测试数据;执行通过自然语言触发。', en: 'Upload verified code and test data; execution triggered via natural language.' }, + 'uploadoriginalfilenamesautoscannedfromdi': { zh: '上传文件原名,自动从目录扫描,不需要手动逐个输入', en: 'Upload original filenames; auto-scanned from directory, no manual entry' }, + 'uploadmodeuploadreferencegenome': { zh: '上传模式 (upload) - 上传参考Genome', en: 'Upload Mode - Upload Reference Genome' }, + 'uploadmode': { zh: '上传模式:', en: 'Upload Mode:' }, + 'upstreammanifest': { zh: '上游 Manifest', en: 'Upstream Manifest' }, + 'nextstep': { zh: '下一步', en: 'Next Step' }, + 'downloadcompleterecommendedrefdatathenco': { zh: '下载/补齐推荐参考数据后继续', en: 'Download/Complete Recommended Ref Data Then Continue' }, + 'arabidopsisfallbackafterdlfailurerequire': { zh: '下载失败后的拟南芥兜底必须手动确认,不会自动执行。', en: 'Arabidopsis fallback after DL failure requires manual confirmation.' }, + 'downloadreportfailed': { zh: '下载报告失败', en: 'Download Report Failed' }, + 'downloadincompletecannotbeusedforppikaks': { zh: '下载未完成,不能直接用于本次 PPI/KaKs。', en: 'Download incomplete; cannot be used for PPI/KaKs.' }, + 'wontoverwriteoriginalppioutputstofinalpp': { zh: '不会覆盖原始 PPI;提交后输出到 final/ppi_reset/reset_###', en: 'Won\'t overwrite original PPI; outputs to final/ppi_reset/reset_###/' }, + 'unsupportedmarkerhandlingpolicy': { zh: '不受支持标记处理策略', en: 'Unsupported Marker Handling Policy' }, + 'noconversionnone': { zh: '不转换 (none', en: 'No Conversion (none)' }, + 'twocolumnssampleandgroup': { zh: '两列:sample 与 group', en: 'Two columns: sample and group' }, + 'sessions': { zh: '个会话', en: ' sessions' }, + 'stagespleaseconfirmparameters': { zh: '个阶段,请确认参数', en: ' stages; please confirm parameters' }, + 'mediumpriority': { zh: '中优先级', en: 'Medium Priority' }, + 'neutralsubstitutionrate': { zh: '中性替换率', en: 'Neutral Substitution Rate' }, + 'neutralevolutionratedefault708e9': { zh: '中性进化速率,默认7.08e-9', en: 'Neutral evolution rate, default 7.08e-9' }, + 'neutralrate': { zh: '中性速率', en: 'Neutral Rate' }, + 'abundanceengine': { zh: '丰度引擎', en: 'Abundance Engine' }, + 'serial': { zh: '串行', en: 'Serial' }, + 'mainagentstillprocessing': { zh: '主 Agent 仍在处理……', en: 'Main Agent Still Processing...' }, + 'mainagentstreamresponsereturnednofinalre': { zh: '主 Agent 流式响应未返回最终结果', en: 'Main Agent Stream Response Returned No Final Result' }, + 'mainagentstreamrequestfailed': { zh: '主 Agent 流式请求失败', en: 'Main Agent Stream Request Failed' }, + 'primaryreference': { zh: '主参考', en: 'Primary Reference' }, + 'primaryreferencespecies': { zh: '主参考物种', en: 'Primary Reference Species' }, + 'mainresults': { zh: '主要结果', en: 'Main Results' }, + '2articlereproductionsteps': { zh: '二、文章复现步骤', en: '2. Article Reproduction Steps' }, + 'twogroup': { zh: '二分类 two_group', en: 'Two-group' }, + 'subfamily': { zh: '亚家族', en: 'Subfamily' }, + 'subfamilyclassificationconfirmation': { zh: '亚家族分类确认', en: 'Subfamily Classification Confirmation' }, + 'subfamilyclassificationevidencechaincomb': { zh: '亚家族分类证据链: combo', en: 'Subfamily Classification Evidence Chain: combo' }, + 'subfamilyclassificationevidencechaindoma': { zh: '亚家族分类证据链: domain', en: 'Subfamily Classification Evidence Chain: domain' }, + 'subfamilyclassificationpredictionrealtim': { zh: '亚家族分类预测实时解读', en: 'Subfamily Classification Prediction - Real-time Interpretation' }, + 'subfamilyclassificationpredictioninterpr': { zh: '亚家族分类预测解读', en: 'Subfamily Classification Prediction Interpretation' }, + 'subfamilyrefnotinjobconfiglocalplangener': { zh: '亚家族参考物种未写入当前 job 配置,已生成方法学本地计划,请在批量确认页核对参考物种', en: 'Subfamily ref not in job config; local plan generated. Verify ref on batch page.' }, + 'subfamilynamesize0auto': { zh: '亚家族名称大小(0=自动)', en: 'Subfamily Name Size (0=auto)' }, + 'subfamilynamedistance': { zh: '亚家族名称距离', en: 'Subfamily Name Distance' }, + 'subfamilyouterarc': { zh: '亚家族外圈弧线', en: 'Subfamily Outer Arc' }, + 'subfamilylabelsnotconfirmed': { zh: '亚家族标签尚未确认', en: 'Subfamily Labels Not Confirmed' }, + 'subfamilylabelsnotconfirmeddownstreampau': { zh: '亚家族标签尚未确认,已暂停后续执行。', en: 'Subfamily labels not confirmed; downstream paused.' }, + 'subfamilylabelsconfirmed': { zh: '亚家族标签已确认', en: 'Subfamily Labels Confirmed' }, + 'subfamilylabelconfirmation': { zh: '亚家族标签确认', en: 'Subfamily Label Confirmation' }, + 'subfamilyconfirmationskippedstagesdepend': { zh: '亚家族标签确认被跳过,已停止依赖 confirmed_subfamily.tsv 的后续阶段;如需普通无亚家族标签分析,请重新发起并明确说明“不需要亚家族”。', en: 'Subfamily confirmation skipped; stages depending on confirmed_subfamily.tsv stopped.' }, + 'subfamilyconfirmationreferenceclassifica': { zh: '亚家族确认 - Reference Classification', en: 'Subfamily Confirmation - Reference Classification' }, + 'subfamilyconfirmationparameters': { zh: '亚家族确认参数', en: 'Subfamily Confirmation Parameters' }, + 'autocontinueplanningaftersubfamilyconfir': { zh: '亚家族确认后自动续跑规划失败', en: 'Auto-continue planning after subfamily confirmation failed' }, + 'subfamilyconfirmationoutput': { zh: '亚家族确认输出:', en: 'Subfamily Confirmation Output:' }, + 'subfamilyconfirmationoutputspecies': { zh: '亚家族确认输出:Species.', en: 'Subfamily confirmation output: Species.' }, + 'subfamilyoutputjointconfirmationtablesav': { zh: '亚家族确认输出:一张联合确认表;保存后同步生成各物种 Species.', en: 'Subfamily output: joint confirmation table; saves and syncs per-species.' }, + 'subfamilyevidenceneedsidentifymemberscre': { zh: '亚家族证据阶段需要先保存 identify 成员初筛确认表', en: 'Subfamily evidence needs identify member screening table saved first' }, + 'subfamilypredictionoutputtarget': { zh: '亚家族预测输出:Target.', en: 'Subfamily prediction output: Target.' }, + 'intersection': { zh: '交集', en: 'Intersection' }, + 'humanhsa': { zh: '人 Human (hsa', en: 'Human (hsa)' }, + 'circleplotonly': { zh: '仅圈图', en: 'Circle Plot Only' }, + 'diagnosisonlymanualhandlingrequired': { zh: '仅展示诊断,需人工处理', en: 'Diagnosis Only; Manual Handling Required' }, + 'reportonly': { zh: '仅报告', en: 'Report Only' }, + 'comparativespeciesonly': { zh: '仅比较物种', en: 'Comparative Species Only' }, + 'targetonly': { zh: '仅目标', en: 'Target Only' }, + 'targetspeciesonly': { zh: '仅目标物种', en: 'Target Species Only' }, + 'rectangularonly': { zh: '仅矩形图', en: 'Rectangular Only' }, + 'recordonlyawaitingmanualconfirmation': { zh: '仅记录,待人工确认', en: 'Record Only; Awaiting Manual Confirmation' }, + 'downloadexpressiondatafromncbigeoleaveem': { zh: '从NCBI GEODownload表达量数据,留空则使用已Upload Files', en: 'Download expression data from NCBI GEO; leave empty to use uploaded files' }, + 'removethisgenefromcurrentresults': { zh: '从本次确认结果中删除该基因?', en: 'Remove this gene from current results?' }, + 'promoterlengthupstreamfromeachtargetgene': { zh: '从每个目标基因上游提取的启动子长度,默认 2000 bp', en: 'Promoter length upstream from each target gene; default 2000 bp' }, + 'coderevision': { zh: '代码修订', en: 'Code Revision' }, + 'coderevisionsuggestion': { zh: '代码修订建议', en: 'Code Revision Suggestion' }, + 'tasksubmittedrunninginbackground': { zh: '任务已提交,正在后台执行...', en: 'Task submitted, running in background...' }, + 'taskpaused': { zh: '任务已暂停', en: 'Task Paused' }, + 'prioritizereusingexpressionmatrix': { zh: '优先复用表达矩阵', en: 'Prioritize Reusing Expression Matrix' }, + 'sessiondeleted': { zh: '会话已删除', en: 'Session Deleted' }, + 'traditionalanalysisoutput': { zh: '传统分析输出:', en: 'Traditional Analysis Output:' }, + 'traditionalanalysisoutputgeneratedperspe': { zh: '传统分析输出:按物种分别生成 Species.', en: 'Traditional Analysis Output: Generated Per Species.' }, + 'locatedat': { zh: '位于', en: 'Located at' }, + 'positiondistributionmap': { zh: '位置分布图', en: 'Position Distribution Map' }, + 'youselectedgene2gobackgroundfile': { zh: '你选择了 gene2go 背景文件', en: 'You selected gene2go background file' }, + 'retrywithbcftools': { zh: '使用 bcftools 重试', en: 'Retry with bcftools' }, + 'usebuiltinmodelspeciesorgdb': { zh: '使用内置模式物种 OrgDb', en: 'Use Built-in Model Species OrgDb' }, + 'usebuiltinmodelspeciesorgdbgoonly': { zh: '使用内置模式物种 OrgDb(仅 GO)', en: 'Use Built-in Model Species OrgDb (GO only)' }, + 'useuploadedgene2gofile': { zh: '使用已上传 gene2go 文件', en: 'Use Uploaded gene2go File' }, + 'useuploadedgene2gogene2kobackgroundfiles': { zh: '使用已上传 gene2go/gene2ko 背景文件', en: 'Use Uploaded gene2go/gene2ko Background Files' }, + 'usearabidopsisasexplicitfallback': { zh: '使用拟南芥作为显式兜底', en: 'Use Arabidopsis as Explicit Fallback' }, + 'userecommendedrange': { zh: '使用推荐区间', en: 'Use Recommended Range' }, + 'usequeryid': { zh: '使用查询ID', en: 'Use Query ID' }, + 'usedefaultdomainfilter': { zh: '使用默认结构域筛选', en: 'Use Default Domain Filter' }, + 'eg03': { zh: '例如 0.3', en: 'e.g. 0.3' }, + 'eg1e5': { zh: '例如 1e-5', en: 'e.g. 1e-5' }, + 'eghmmerhmmsearch': { zh: '例如 HMMER hmmsearch', en: 'e.g. HMMER hmmsearch' }, + 'egbashrunshinputfa': { zh: '例如 bash run.sh input.fa', en: 'e.g. bash run.sh input.fa' }, + 'sidebarstatus': { zh: '侧边栏状态', en: 'Sidebar Status' }, + 'savemethodologyplan': { zh: '保存方法学方案', en: 'Save Methodology Plan' }, + 'retain': { zh: '保留', en: 'Retain' }, + 'retainoriginalheader': { zh: '保留原header', en: 'Retain Original Header' }, + 'modify': { zh: '修改', en: 'Modify' }, + 'revise': { zh: '修订', en: 'Revise' }, + 'reviseredraw': { zh: '修订 / 重绘', en: 'Revise / Redraw' }, + 'countdownpaused-2': { zh: '倒计时已暂停', en: 'Countdown Paused' }, + 'candidatestage': { zh: '候选阶段', en: 'Candidate Stage' }, + 'failedtostopextensionanalysis': { zh: '停止拓展分析失败', en: 'Failed to Stop Extension Analysis' }, + 'tryfindingmatrixfirstfallbacktorawrnaseq': { zh: '先找矩阵,失败后 raw RNA-seq fallback', en: 'Try finding matrix first; fall back to raw RNA-seq' }, + 'runrnaseqqcfirstverifycleanfastqfilesinf': { zh: '先运行 RNA-seq QC,并确认 final/ 中有每个样本的 clean FASTQ 文件。', en: 'Run RNA-seq QC first; verify clean FASTQ files in final/.' }, + 'firstrunsubfamilyclassificationconfirmat': { zh: '先进行亚家族分类确认(reference_classification/subfamily_confirm', en: 'First run subfamily classification confirmation' }, + 'genomewideforegrounduseglobaldegenes': { zh: '全基因组 foreground:使用全局 DE_genes', en: 'Genome-wide foreground: use global DE_genes' }, + 'genomewideforegroundusealldifferentialex': { zh: '全基因组 foreground:使用所有差异表达基因', en: 'Genome-wide foreground: use all differential expression genes' }, + 'genomewidedifferentialexpressionoutputgl': { zh: '全基因组差异表达:输出全局 DE_genes', en: 'Genome-wide differential expression: output global DE_genes' }, + 'globaldegenes': { zh: '全局 DE_genes', en: 'Global DE_genes' }, + 'fullscreen': { zh: '全屏', en: 'Full Screen' }, + 'fullscreendisplay': { zh: '全屏展示', en: 'Full Screen Display' }, + 'all': { zh: '全部', en: 'All' }, + 'allrows': { zh: '全部行', en: 'All Rows' }, + 'closenofurtheradjustments': { zh: '关闭,不再调整', en: 'Close; No Further Adjustments' }, + 'closeconfirmlater': { zh: '关闭,稍后确认', en: 'Close; Confirm Later' }, + 'compatibilitymode': { zh: '兼容模式', en: 'Compatibility Mode' }, + 'content': { zh: '内容', en: 'Content' }, + 'builtinspeciescode': { zh: '内置物种代码', en: 'Built-in Species Code' }, + 'writecheckpoint': { zh: '写入检查点', en: 'Write Checkpoint' }, + 'analyzing': { zh: '分析中', en: 'Analyzing' }, + 'analysisfamily': { zh: '分析家族', en: 'Analysis Family' }, + 'analysisdata': { zh: '分析数据', en: 'Analysis Data' }, + 'analyzesyntenybetweentargetandreferencec': { zh: '分析目标物种与参考/比较物种之间的共线性', en: 'Analyze synteny between target and reference/comparative species' }, + 'classificationtable': { zh: '分类表', en: 'Classification Table' }, + 'grouprole': { zh: '分组角色', en: 'Group Role' }, + 'grouproleunchanged': { zh: '分组角色不改', en: 'Group Role (Unchanged)' }, + 'switchto': { zh: '切换到', en: 'Switch to' }, + 'switchfailed': { zh: '切换失败', en: 'Switch Failed' }, + 'createsessionfailed': { zh: '创建会话失败', en: 'Create Session Failed' }, + 'createfailed': { zh: '创建失败', en: 'Create Failed' }, + 'deletesession': { zh: '删除会话', en: 'Delete Session' }, + 'deletesessionfailed': { zh: '删除会话失败', en: 'Delete Session Failed' }, + 'refreshresults': { zh: '刷新结果', en: 'Refresh Results' }, + 'foregrounddependencymissing': { zh: '前景依赖缺失', en: 'Foreground Dependency Missing' }, + 'foregroundgenes': { zh: '前景基因', en: 'Foreground Genes' }, + 'function': { zh: '功能', en: 'Function' }, + 'featurecategory': { zh: '功能类别', en: 'Feature Category' }, + 'addtoformallist': { zh: '加入正式列表', en: 'Add to Formal List' }, + 'failedtoloadppiinput': { zh: '加载 PPI 输入失败', en: 'Failed to Load PPI Input' }, + 'failedtoloadrnaseqsamples': { zh: '加载RNA-seq样本失败', en: 'Failed to Load RNA-seq Samples' }, + 'failedtoloadtasks': { zh: '加载任务失败', en: 'Failed to Load Tasks' }, + 'failedtoloadsessionmessages': { zh: '加载会话消息失败', en: 'Failed to Load Session Messages' }, + 'failedtoloadgraph': { zh: '加载图谱失败', en: 'Failed to Load Graph' }, + 'loadfailed': { zh: '加载失败', en: 'Load Failed' }, + 'failedtoloadmethodologyconfig': { zh: '加载方法学配置失败', en: 'Failed to Load Methodology Config' }, + 'failedtoloadknowledgegraph': { zh: '加载知识图谱失败', en: 'Failed to Load Knowledge Graph' }, + 'twornaseqpathsreusematrixorfallbacktoraw': { zh: '包含RNA-seq两条路: 可直接复用矩阵则复用,无法复用时执行raw RNA-seq fallback的质控/比对/定量/样本评估/差异表达', en: 'Two RNA-seq paths: reuse matrix or fallback to raw (QC/Align/Quant/Sample/DE)' }, + 'containskeyword': { zh: '包含关键词', en: 'Contains Keyword' }, + 'includeskaryotypechromosomedistributiona': { zh: '包含核型/染色体分布分析(karyotype', en: 'Includes karyotype/chromosome distribution analysis' }, + 'matchmode': { zh: '匹配方式', en: 'Match Mode' }, + 'matchedrows': { zh: '匹配行', en: 'Matched Rows' }, + 'singlegeneidgenenamelocusleaveemptywhenu': { zh: '单个GeneID/基因名/locus;使用ID文件时可留空', en: 'Single GeneID/gene name/locus; leave empty when using ID file' }, + 'singleormultipleidsegat1g01010at1g01720': { zh: '单个或多个ID,如 At1g01010,At1g01720', en: 'Single or multiple IDs, e.g. At1g01010,At1g01720' }, + 'reason': { zh: '原因', en: 'Reason' }, + 'originalcode': { zh: '原始代码', en: 'Original Code' }, + 'originalpackagereproducibilitycheckinpro': { zh: '原始包可复现检查中…', en: 'Original Package Reproducibility Check In Progress...' }, + 'originalpackagereproducibilitychecksubmi': { zh: '原始包可复现检查提交失败', en: 'Original Package Reproducibility Check Submit Failed' }, + 'originalcommand': { zh: '原始命令', en: 'Original Command' }, + 'originalcommandtestdataandexecutionfacts': { zh: '原始命令、测试数据和执行事实已经保留;这里只重新生成说明,不会重新运行原始命令。', en: 'Original command, test data and execution facts retained; only description regenerated.' }, + 'originalfilename': { zh: '原始文件名', en: 'Original Filename' }, + 'originalsequencingid': { zh: '原始测序编号', en: 'Original Sequencing ID' }, + 'originalevidence': { zh: '原始证据', en: 'Original Evidence' }, + 'originalrecommendedreference': { zh: '原推荐参考', en: 'Original Recommended Reference' }, + 'removet01suffixremovet01': { zh: '去除.T01后缀 (remove_T01', en: 'Remove .T01 Suffix (remove_T01)' }, + 'parameters': { zh: '参数', en: 'Parameters' }, + 'parameterpreviewfailed': { zh: '参数预览失败', en: 'Parameter Preview Failed' }, + 'referencegenome': { zh: '参考Genome', en: 'Reference Genome' }, + 'referencesubfamilyclassification': { zh: '参考亚家族分类', en: 'Reference Subfamily Classification' }, + 'referenceclassification': { zh: '参考分类', en: 'Reference Classification' }, + 'referenceprefix': { zh: '参考前缀', en: 'Reference Prefix' }, + 'referencegene': { zh: '参考基因', en: 'Reference Gene' }, + 'referencegeneid': { zh: '参考基因编号', en: 'Reference Gene ID' }, + 'refdatadownloadfailed': { zh: '参考数据下载失败', en: 'Ref Data Download Failed' }, + 'referencedataready': { zh: '参考数据已就绪', en: 'Reference Data Ready' }, + 'referencesource': { zh: '参考来源', en: 'Reference Source' }, + 'referencespecies-2': { zh: '参考物种', en: 'Reference Species' }, + 'refspeciessubfamilytwocolumntableautofin': { zh: '参考物种亚家族两列表。留空时自动从 input/final 查找 *.subfamily 或 *subfamily*.tsv', en: 'Ref species subfamily two-column table; auto-find from input/final when empty.' }, + 'refspeciesprefixinjointtreetipsegatat1g': { zh: '参考物种在联合树 tip 中的前缀,例如 At|AT1G...', en: 'Ref species prefix in joint tree tips, e.g. At|AT1G...' }, + 'referencespeciesshaperoletree': { zh: '参考物种形状(角色树)', en: 'Reference Species Shape (Role Tree)' }, + 'referencespeciesreferenceonlynotfortarge': { zh: '参考物种(仅参考,不参与目标鉴定)', en: 'Reference species (reference only; not for target identification)' }, + 'referencespeciesuseathforarabidopsis': { zh: '参考物种,拟南芥用ath', en: 'Reference species; use ath for Arabidopsis' }, + 'referenceuseadvanced': { zh: '参考用途(高级', en: 'Reference Use (Advanced)' }, + 'refgroupoptionalcontrolrequiredfortimetw': { zh: '参考组可选;time/two_group 必须在表中标 control,多组组织比较可留空', en: 'Ref group optional; control required for time/two_group; leave empty for multi-group tissue' }, + 'reflecting': { zh: '反思中', en: 'Reflecting...' }, + 'publishing': { zh: '发布中...', en: 'Publishing...' }, + 'prepublishverificationfailed': { zh: '发布前验收失败', en: 'Pre-publish Verification Failed' }, + 'prepublishverificationallpassedreadytopu': { zh: '发布前验收已全部通过,可以发布。', en: 'Pre-publish verification all passed; ready to publish.' }, + 'prepublishverificationpassed': { zh: '发布前验收已通过', en: 'Pre-publish Verification Passed' }, + 'publishfailed': { zh: '发布失败', en: 'Publish Failed' }, + 'agentfound': { zh: '发现 agent', en: 'Agent Found' }, + 'cancelppi': { zh: '取消 PPI', en: 'Cancel PPI' }, + 'cancelpreview': { zh: '取消预览', en: 'Cancel Preview' }, + 'onlycheckedandexecutablestageswillrun': { zh: '只会执行已勾选且可执行的阶段', en: 'Only checked and executable stages will run' }, + 'analyzeonlytargetspeciesinternalduplicat': { zh: '只分析目标物种内部复制关系', en: 'Analyze only target species internal duplication events' }, + 'onlyforidentifyblastreferencefamilyprote': { zh: '只用于 identify BLAST 的参考家族蛋白物种,在上方“Identify BLAST参考”填写,如 At,Os', en: 'Only for identify BLAST reference family protein species; fill under Identify BLAST Ref.' }, + 'onlyforidentifystageblastrefproteinsearc': { zh: '只用于 identify 阶段 BLAST/reference-protein search 的参考家族蛋白来源;可以多选,如 At 和 Os', en: 'Only for identify stage BLAST/ref-protein search; multi-select supported.' }, + 'onlyredrawtreenomafftiqtreererunbothoutp': { zh: '只重绘树图,不重跑 MAFFT/IQ-TREE。both 会同时输出矩形树和圈图。', en: 'Only redraw tree; no MAFFT/IQ-TREE rerun. Both outputs rectangular and circle plots.' }, + 'retrydirectlyorcancelandcheckerrorcause': { zh: '可以直接重试,或取消后检查错误原因。', en: 'Retry directly or cancel and check error cause.' }, + 'manuallyspecifykeggorganismcodeosariceat': { zh: '可手动指定 KEGG organism code;水稻 osa,拟南芥 ath。留空时系统尝试从拉丁名推断,失败则回退 KO 全库植物过滤。', en: 'Manually specify KEGG organism code; osa=rice, ath=Arabidopsis; auto-infer from Latin name otherwise.' }, + 'editable': { zh: '可改', en: 'Editable' }, + 'optionaleglcdlat': { zh: '可选,如 Lc / Dl / At', en: 'Optional, e.g. Lc / Dl / At' }, + 'numberofsamplesprocessedsimultaneously': { zh: '同时处理的样本数', en: 'Number of Samples Processed Simultaneously' }, + 'alsorunfullannotationgenepromoterbackgro': { zh: '同时跑全注释基因 promoter 背景', en: 'Also run full annotation gene promoter background' }, + 'name': { zh: '名称', en: 'Name' }, + 'modelstagedescription': { zh: '描述模型的阶段', en: 'Describe the model stage' }, + 'downstreamprimaryreferencespecies': { zh: '后续主参考物种', en: 'Downstream Primary Reference Species' }, + 'downstreamprimaryreferencespeciesegat': { zh: '后续主参考物种,例如 At', en: 'Downstream primary reference species, e.g. At' }, + 'downstreamprimaryreferencespeciesegat-2': { zh: '后续主参考物种,如 At', en: 'Downstream primary reference species, e.g. At' }, + 'defaultprimaryreffordownstreamusuallyone': { zh: '后续阶段默认主参考物种;通常一个,例如 At。不会自动加入 identify BLAST,除非也在 Identify BLAST参考 中选择', en: 'Default primary ref for downstream; usually one, e.g. At.' }, + 'promoterelements': { zh: '启动子元件', en: 'Promoter Elements' }, + 'promoterelementprediction': { zh: '启动子元件预测', en: 'Promoter Element Prediction' }, + 'promotercustomplot': { zh: '启动子自定义绘图', en: 'Promoter Custom Plot' }, + 'promotercustomplotfailed': { zh: '启动子自定义绘图失败:', en: 'Promoter Custom Plot Failed:' }, + 'promotercustomplotcomplete': { zh: '启动子自定义绘图完成', en: 'Promoter Custom Plot Complete' }, + 'promotercustomplotsubmittedtaskid': { zh: '启动子自定义绘图已提交:task_id=', en: 'Promoter custom plot submitted: task_id=' }, + 'commandtemplatereturnednopreviewablecomm': { zh: '命令模板未返回可预览命令;请先检查 entrypoint.command_template。', en: 'Command template returned no previewable command; check entrypoint.command_template.' }, + 'legendcolor': { zh: '图例颜色', en: 'Legend Color' }, + 'plottype': { zh: '图类型', en: 'Plot Type' }, + 'charttitlelist': { zh: '图表标题清单', en: 'Chart Title List' }, + 'charttitleevidence': { zh: '图表标题证据', en: 'Chart Title Evidence' }, + 'charttitledrivenreproductionplanpreview': { zh: '图表标题驱动复现规划预览', en: 'Chart Title-Driven Reproduction Plan Preview' }, + 'circle': { zh: '圆形', en: 'Circle' }, + 'geneid': { zh: '基因ID', en: 'Gene ID' }, + 'geneidsize': { zh: '基因ID大小', en: 'Gene ID Size' }, + 'geneiddistance': { zh: '基因ID距离', en: 'Gene ID Distance' }, + 'geneidtochromosomeblockdistance': { zh: '基因ID距离染色体色块', en: 'Gene ID to Chromosome Block Distance' }, + 'geneidtrackouterboundary': { zh: '基因ID轨道外边界', en: 'Gene ID Track Outer Boundary' }, + 'geneidconversionremovet01oraddt01suffix': { zh: '基因ID转换方式:去除.T01后缀或添加.T01后缀', en: 'Gene ID conversion: remove .T01 or add .T01 suffix' }, + 'geneid-2': { zh: '基因id', en: 'Gene ID' }, + 'genelist': { zh: '基因list', en: 'Gene List' }, + 'genelist-2': { zh: '基因列表', en: 'Gene List' }, + 'genotype': { zh: '基因型 genotype', en: 'Genotype' }, + 'genefamilyforegroundonlyanalyzemembersin': { zh: '基因家族 foreground:仅分析 final_members.id 中的家族成员', en: 'Gene family foreground: only analyze members in final_members.id' }, + 'genefamilyforegroundusefamilydegenes': { zh: '基因家族 foreground:使用 family_DE_genes', en: 'Gene family foreground: use family_DE_genes' }, + 'genefamilypromoterscanning': { zh: '基因家族 promoter 扫描', en: 'Gene family promoter scanning' }, + 'genefamilyrequiredforknownfamily': { zh: '基因家族(known_family必填', en: 'Gene Family (required for known_family)' }, + 'genefamilydifferentialexpressionoutputfa': { zh: '基因家族差异表达:只输出 family_DE_genes', en: 'Gene family differential expression: output family_DE_genes only' }, + 'genefamilymembers': { zh: '基因家族成员', en: 'Gene Family Members' }, + 'genefamilyidentification': { zh: '基因家族鉴定', en: 'Gene Family Identification' }, + 'geneannotation': { zh: '基因注释', en: 'Gene Annotation' }, + 'genestructureanalysis': { zh: '基因结构分析', en: 'Gene Structure Analysis' }, + 'fill': { zh: '填写', en: 'Fill' }, + 'absolutepathtorawdatadircommaseparatedfo': { zh: '填写Raw Data所在目录的绝对路径,多个路径用逗号分隔,如 /data/SRR1,/data/SRR2', en: 'Absolute path to Raw Data dir; comma-separated for multiples' }, + 'fillgenefamilyegsplwrky': { zh: '填写基因家族,如 SPL / WRKY', en: 'Fill gene family, e.g. SPL / WRKY' }, + 'fillabsolutedatadirpathcommaseparatedfor': { zh: '填写数据目录绝对路径,多个路径用逗号分隔', en: 'Fill absolute data dir path; comma-separated for multiples' }, + 'condition': { zh: '处理/条件 condition', en: 'Condition' }, + 'processing-2': { zh: '处理中', en: 'Processing' }, + 'processingmethod': { zh: '处理方式', en: 'Processing Method' }, + 'copyfailed': { zh: '复制失败', en: 'Copy Failed' }, + 'reuseplantcarefilteredtablefromcompleted': { zh: '复用已完成 promoter 阶段的 PlantCARE filtered 表,不重新提交 PlantCARE。', en: 'Reuse PlantCARE filtered table from completed promoter; do not re-submit.' }, + 'multigroup': { zh: '多分类 multi_group', en: 'Multi-group' }, + 'multiagentplanning': { zh: '多智能体规划', en: 'Multi-agent Planning' }, + 'multiagentmethodologyexecutionsequencepl': { zh: '多智能体规划方法学执行顺序失败', en: 'Multi-agent Methodology Execution Sequence Planning Failed' }, + 'multiagentplanningshowsstagescompletedno': { zh: '多智能体规划结果显示相关阶段已完成,无需重复执行', en: 'Multi-agent planning shows stages completed; no re-execution needed' }, + 'multispeciesprocessing': { zh: '多物种处理方式', en: 'Multi-species Processing' }, + 'multispeciesjointanalysisconfirmationdef': { zh: '多物种联合分析与确认(默认)', en: 'Multi-species Joint Analysis & Confirmation (default)' }, + 'size': { zh: '大小', en: 'Size' }, + 'largefilescanbereferencedoneabsolutepath': { zh: '大文件可直接引用;每行填写一个绝对路径', en: 'Large files can be referenced; one absolute path per line' }, + 'soybeangma': { zh: '大豆 (gma', en: 'Soybean (gma)' }, + 'ratrno': { zh: '大鼠 Rat (rno', en: 'Rat (rno)' }, + 'failed': { zh: '失败', en: 'Failed' }, + 'howtouse': { zh: '如何使用', en: 'How to Use' }, + 'withoutmanualfilteringonlymembershitting-2': { zh: '如果不手动筛选,系统默认只保留命中本基因家族目标结构域的成员;你也可以按 domain、e-value/score 和 coverage 调整后重新生成最终成员蛋白。', en: 'Without manual filtering, only members hitting target domain kept; adjust by domain, e-value/score and coverage.' }, + 'fielddescription': { zh: '字段说明:', en: 'Field Description:' }, + 'complete': { zh: '完成', en: 'Complete' }, + 'quantification': { zh: '定量', en: 'Quantification' }, + 'quantificationmode': { zh: '定量模式', en: 'Quantification Mode' }, + 'realtimecumulativeinterpretation': { zh: '实时累计解读', en: 'Real-time Cumulative Interpretation' }, + 'actualcommand': { zh: '实际命令', en: 'Actual Command' }, + 'experimentaldesign': { zh: '实验设计', en: 'Experimental Design' }, + 'experimentaldesignmodule': { zh: '实验设计模块', en: 'Experimental Design Module' }, + 'reviewnotes': { zh: '审核备注', en: 'Review Notes' }, + 'familymembers': { zh: '家族成员', en: 'Family Members' }, + 'enrichmentanalysismissingbackgroundannot': { zh: '富集分析缺少背景注释', en: 'Enrichment Analysis Missing Background Annotation' }, + 'enrichmenttype': { zh: '富集类型', en: 'Enrichment Type' }, + 'chathistorycleared': { zh: '对话历史已清空', en: 'Chat History Cleared' }, + 'comparisonstobegenerated': { zh: '将生成的比较:', en: 'Comparisons to be Generated:' }, + 'speciestobeidentified': { zh: '将鉴定物种', en: 'Species to be identified' }, + 'mousemmu': { zh: '小鼠 Mouse (mmu', en: 'Mouse (mmu)' }, + 'expand': { zh: '展开', en: 'Expand' }, + 'displaychain': { zh: '展示链:', en: 'Display Chain:' }, + 'deorsampleqcneedspurelynumericrawcountsb': { zh: '差异分析或样本 QC 需要纯数字 raw counts,但矩阵里混入了注释列或文本列。', en: 'DE or sample QC needs purely numeric raw counts, but matrix has annotation/text columns.' }, + 'differentialexpression': { zh: '差异表达', en: 'Differential Expression' }, + 'differentialexpressiondownstreamanalysis': { zh: '差异表达下游分析', en: 'Differential Expression Downstream Analysis' }, + 'differentialexpressionscope': { zh: '差异表达范围', en: 'Differential Expression Scope' }, + 'currentsessioncleared': { zh: '已Clear当前会话', en: 'Current Session Cleared' }, + 'methodologyplansavedbutnotexecuting': { zh: '已保存方法学方案,但暂不执行:', en: 'Methodology plan saved but not executing:' }, + 'writtentoofficialconfigxlsx': { zh: '已写入正式 config.xlsx', en: 'Written to Official config.xlsx' }, + 'writtentoofficialsamplesyaml': { zh: '已写入正式 samples.yaml', en: 'Written to Official samples.yaml' }, + 'registeredstages': { zh: '已写阶段', en: 'Registered Stages' }, + 'switchedtoworkingdirectory': { zh: '已切换到Working Directory', en: 'Switched to Working Directory' }, + 'creatednewworkingdirectory': { zh: '已创建新Working Directory', en: 'Created New Working Directory' }, + 'addedtoformalstagelistincludedinthisexec': { zh: '已加入正式阶段列表,并默认纳入本次执行', en: 'Added to formal stage list; included in this execution' }, + 'publishedreadytoexecute': { zh: '已发布,可执行', en: 'Published; Ready to Execute' }, + 'cancelled': { zh: '已取消', en: 'Cancelled' }, + 'applied': { zh: '已应用', en: 'Applied' }, + 'openedconfigxlsxautodetectiontableeditro': { zh: '已打开 config.xlsx 自动识别表。你可以直接修订单行,或用批量修订区筛选、预览、Apply。', en: 'Opened config.xlsx auto-detection table. Edit rows or use bulk edit.' }, + 'openedsamplesyamlautodetectiontableedits': { zh: '已打开 samples.yaml 自动识别表。你可以直接修订样本、分组、重复和对照组。', en: 'Opened samples.yaml auto-detection table. Edit sample, group, replicate and control.' }, + 'openedcurrentjobconfigxlsxreviewtable': { zh: '已打开当前 job 的 config.xlsx 核对表。', en: 'Opened current job config.xlsx review table.' }, + 'existingorthologmappinginconsistentwithp': { zh: '已有 Ortholog 映射与当前 PPI/KaKs 参考物种不一致', en: 'Existing Ortholog mapping inconsistent with PPI/KaKs ref' }, + 'downstreamstagesmarkedforrerunbasedonfil': { zh: '已标记下游 phylogeny/motif/domain/structure/combo 需要基于筛选后成员重跑。', en: 'Downstream stages marked for re-run based on filtered members.' }, + 'paramsoutputconfirmedpleasecontinueverif': { zh: '已确认参数和输出,请继续验证', en: 'Params & output confirmed; please continue verification' }, + 'boundtoserversidevcf': { zh: '已绑定服务器端 VCF', en: 'Bound to Server-side VCF' }, + 'paramsoutputautoconfirmedstartingverific': { zh: '已自动确认参数和输出,开始验证...', en: 'Params & output auto-confirmed; starting verification...' }, + 'autobound': { zh: '已自动绑定:', en: 'Auto-bound:' }, + 'broughtup': { zh: '已调出', en: 'Brought Up' }, + 'help': { zh: '帮助', en: 'Help' }, + 'parallel': { zh: '并行', en: 'Parallel' }, + 'suggestedfixplan': { zh: '建议修复方案', en: 'Suggested Fix Plan' }, + 'suggestedparameters': { zh: '建议参数', en: 'Suggested Parameters' }, + 'suggestedhandlingplan': { zh: '建议处理方案', en: 'Suggested Handling Plan' }, + 'startingprepublishnlruntimegate': { zh: '开始发布前 NL Runtime Gate...', en: 'Starting Pre-publish NL Runtime Gate...' }, + 'startverification': { zh: '开始验证', en: 'Start Verification' }, + 'arcavoidancedistance': { zh: '弧线避让距离', en: 'Arc Avoidance Distance' }, + 'popout': { zh: '弹出', en: 'Pop Out' }, + 'goenrichmentlacksgene2gosystemwillrunloc': { zh: '当前 GO 富集缺少可用 gene2go 背景。系统将先运行本地 GO 注释生成 gene2go,再继续 GO 富集分析。', en: 'GO enrichment lacks gene2go; system will run local GO annotation first.' }, + 'goandkegglackbackgroundssystemwillrunloc': { zh: '当前 GO 缺少可用 gene2go 背景,KEGG 缺少 gene2ko 背景。系统将先运行本地自动注释生成背景文件,再继续富集分析。', en: 'GO and KEGG lack backgrounds; system will run local auto-annotation first.' }, + 'gobackgrounddoesnotmatchdegeneidssystemw': { zh: '当前 GO 背景与 DE 基因 ID 不匹配。系统将先运行本地 GO 注释生成匹配的 gene2go,再继续 GO 富集分析。', en: 'GO background does not match DE gene IDs; system will run local GO annotation first.' }, + 'keggenrichmentlacksgene2kosystemwillrunl': { zh: '当前 KEGG 富集缺少 gene2ko 背景。系统将先运行本地 KEGG 注释生成 gene2ko,再继续 KEGG 富集分析。', en: 'KEGG enrichment lacks gene2ko; system will run local KEGG annotation first.' }, + 'currentgene2go': { zh: '当前 gene2go', en: 'Current gene2go' }, + 'currentjob': { zh: '当前 job', en: 'Current Job' }, + 'currentjobfinal': { zh: '当前 job final', en: 'Current Job Final' }, + 'noconfigxlsxdraftorofficialconfigfoundin': { zh: '当前 job 中没有找到可打开的 config.xlsx 草稿或正式配置。', en: 'No config.xlsx draft or official config found in current job.' }, + 'filesincurrentjobinputorworkspaceegkey': { zh: '当前 job 的 input/ 或 workspace/ 中的文件,例如', en: 'Files in current job input/ or workspace/, e.g.: {key}' }, + 'currentjobidisemptycannotsavemethodology': { zh: '当前 job_id 为空,不能保存方法学方案', en: 'Current job_id is empty; cannot save methodology plan' }, + 'currentjobidisemptycannotrunprepublishve': { zh: '当前 job_id 为空,不能运行发布前验收。', en: 'Current job_id is empty; cannot run pre-publish verification.' }, + 'currentparameters': { zh: '当前参数', en: 'Current Parameters' }, + 'currentreferencespecies': { zh: '当前参考物种', en: 'Current Reference Species' }, + 'currentdisplaymode': { zh: '当前显示模式', en: 'Current Display Mode' }, + 'nodirectlyusableexpressionmatrixdetected': { zh: '当前未检测到可直接执行的表达矩阵。', en: 'No directly usable expression matrix detected.' }, + 'currentsampleinfoinsufficienttogenerated': { zh: '当前样品信息不足以生成 DE 设计', en: 'Current sample info insufficient to generate DE design' }, + 'currentsamplecounttoolow': { zh: '当前样本数过少', en: 'Current sample count too low' }, + 'nousablejobidavailable': { zh: '当前没有可用 job_id', en: 'No Usable Job ID Available' }, + 'currentbrowserdoesnotsupportstreamingres': { zh: '当前浏览器不支持流式响应', en: 'Current browser does not support streaming response' }, + 'messagenotsavedtosessionhistorymaybelost': { zh: '当前消息未成功写入会话历史,刷新后可能丢失', en: 'Message not saved to session history; may be lost on refresh' }, + 'nomembersafterfilterfinalmembersnotrebui': { zh: '当前筛选没有成员,未重建 final_members。', en: 'No members after filter; final_members not rebuilt.' }, + 'currentlymissing': { zh: '当前缺失:', en: 'Currently Missing:' }, + 'currentselection': { zh: '当前选择', en: 'Current Selection' }, + 'currentstage': { zh: '当前阶段', en: 'Current Stage' }, + 'pending-2': { zh: '待执行', en: 'Pending' }, + 'pendingauthorization': { zh: '待授权', en: 'Pending Authorization' }, + 'pendingreview': { zh: '待核对', en: 'Pending Review' }, + 'pendingconfirmation': { zh: '待确认', en: 'Pending Confirmation' }, + 'awaitingdata': { zh: '待补数据', en: 'Awaiting Data' }, + 'required': { zh: '必填', en: 'Required' }, + 'requiredpfamidsorcommondomainaliasesrequ': { zh: '必需 Pfam 号(PFxxxxx)或常见结构域别名,多个用逗号分隔;Identify 无上传 HMM 时必填', en: 'Required Pfam IDs or common domain aliases; required when no HMM uploaded for Identify' }, + 'requiredpfamproteinfamilyidscommaseparat': { zh: '必需包含的 Pfam 蛋白家族ID,多个用逗号分隔', en: 'Required Pfam protein family IDs, comma-separated' }, + 'mustmatchfilenameininput': { zh: '必须匹配 input 中的文件名', en: 'Must match filename in input' }, + 'howtouse-2': { zh: '怎么用', en: 'How to Use' }, + 'helloiambotanicalbaseagentspecializeding': { zh: '您好!我是BotanicalBaseAgent,专注于基因家族分析。请告诉我您想分析哪个基因家族?', en: 'Hello! I am BotanicalBaseAgent, specialized in gene family analysis.' }, + 'memberscreeningconfirmation': { zh: '成员初筛确认', en: 'Member Screening Confirmation' }, + 'memberconfirmation': { zh: '成员确认', en: 'Member Confirmation' }, + 'memberfilter': { zh: '成员筛选', en: 'Member Filter' }, + 'memberidentificationoutput': { zh: '成员鉴定输出:', en: 'Member Identification Output:' }, + 'memberidentificationoutputperspeciesgene': { zh: '成员鉴定输出:每个鉴定物种分别生成 Species.', en: 'Member identification output: per species generates Species.' }, + 'membersetchangedphylogenyneedsrerun': { zh: '成员集合有变化,需要重跑 phylogeny。', en: 'Member set changed; phylogeny needs re-run.' }, + 'membersetunchangeddownstreamwillreusecon': { zh: '成员集合未变,后续绘图将直接复用确认标签。', en: 'Member set unchanged; downstream will reuse confirmed labels.' }, + 'gotit': { zh: '我知道了', en: 'Got It' }, + 'nousablefilesforconfigxlsxsamplesyamlatp': { zh: '我识别到你是在提供数据路径,但该路径下没有发现可用于 config.xlsx / samples.yaml 的文件。请确认目录是否包含 genome/pep/cds/gff/hmm 或 FASTQ 文件。', en: 'No usable files for config.xlsx/samples.yaml at path; check for genome/pep/cds/gff/hmm or FASTQ.' }, + 'allstagescompleted': { zh: '所有阶段已完成', en: 'All Stages Completed' }, + 'manualrange': { zh: '手动区间', en: 'Manual Range' }, + 'manuallyprovidessfile': { zh: '手动提供 .ss 文件', en: 'Manually Provide .ss File' }, + 'open': { zh: '打开', en: 'Open' }, + 'openselectedextractionresult': { zh: '打开所选提取结果', en: 'Open Selected Extraction Result' }, + 'failedtoopenmethodologyextractionresults': { zh: '打开方法学提取结果失败', en: 'Failed to Open Methodology Extraction Results' }, + 'openlatestextractionresult': { zh: '打开最新提取结果', en: 'Open Latest Extraction Result' }, + 'execute': { zh: '执行', en: 'Execute' }, + 'executing': { zh: '执行中...', en: 'Executing...' }, + 'executionentryraninisolatedenvironmentve': { zh: '执行入口已在隔离环境运行。请核对系统记录的事实与说明;确认后才会验证。', en: 'Execution entry ran in isolated environment. Verify recorded facts before confirming.' }, + 'executegenefamilyanalysis': { zh: '执行基因家族分析', en: 'Execute Gene Family Analysis' }, + 'executionfailed': { zh: '执行失败', en: 'Execution Failed' }, + 'erroroccurredduringexecution': { zh: '执行过程中发生错误', en: 'Error occurred during execution' }, + 'executionissue': { zh: '执行问题', en: 'Execution Issue' }, + 'executestage': { zh: '执行阶段', en: 'Execute Stage' }, + 'extendedanalysis': { zh: '扩展分析', en: 'Extended Analysis' }, + 'scanbothstrands': { zh: '扫描双链', en: 'Scan Both Strands' }, + 'batchexecutionconfirmation': { zh: '批量执行确认', en: 'Batch Execution Confirmation' }, + 'collapse': { zh: '折叠', en: 'Collapse' }, + 'reportdata': { zh: '报告数据', en: 'Report Data' }, + 'sorryididnotunderstandpleasetrytodescrib': { zh: '抱歉,我没有理解你的意思。请尝试更详细地描述。', en: 'Sorry, I did not understand. Please try to describe in more detail.' }, + 'sorryliteraturesearchserviceistemporaril': { zh: '抱歉,文献检索服务暂时不可用。', en: 'Sorry, literature search service is temporarily unavailable.' }, + 'sorryliteraturesearchserviceisunavailabl': { zh: '抱歉,文献检索服务暂时不可用,请稍后重试。', en: 'Sorry, literature search service is unavailable; please try again later.' }, + 'sorryserviceistemporarilyunavailableplea': { zh: '抱歉,服务暂时不可用,请稍后重试。', en: 'Sorry, service is temporarily unavailable; please try again later.' }, + 'latinname': { zh: '拉丁名', en: 'Latin Name' }, + 'latinnamealiasunchanged': { zh: '拉丁名/别名不改', en: 'Latin Name/Alias (Unchanged)' }, + 'extensionanalysis': { zh: '拓展分析', en: 'Extension Analysis' }, + 'extensionanalysiscandidatereview': { zh: '拓展分析候选核对', en: 'Extension Analysis Candidate Review' }, + 'extensionanalysisdescriptiongenerationfa': { zh: '拓展分析说明生成失败', en: 'Extension Analysis Description Generation Failed' }, + 'extensionanalysisrunparameterconfirmatio': { zh: '拓展分析运行参数确认', en: 'Extension Analysis Run Parameter Confirmation' }, + 'extensionanalysisstage': { zh: '拓展分析阶段', en: 'Extension Analysis Stage' }, + 'extensionanalysisstagepublished': { zh: '拓展分析阶段已发布', en: 'Extension Analysis Stage Published' }, + 'extensionanalysisstagegeneratedpublished': { zh: '拓展分析阶段已生成并发布', en: 'Extension Analysis Stage Generated & Published' }, + 'extensionanalysisstageexecutioncomplete': { zh: '拓展分析阶段执行完成', en: 'Extension Analysis Stage Execution Complete' }, + 'extensionanalysisstagefailedcheckstderrl': { zh: '拓展分析阶段执行未成功,请查看 stderr.log', en: 'Extension Analysis Stage Failed; check stderr.log' }, + 'extensionanalysisstagefailedcheckresultl': { zh: '拓展分析阶段执行未成功,请查看结果日志', en: 'Extension Analysis Stage Failed; check result log' }, + 'extensionanalysisstagestatus': { zh: '拓展分析阶段状态', en: 'Extension Analysis Stage Status' }, + 'extensionanalysisstagegenerationfailed': { zh: '拓展分析阶段生成失败', en: 'Extension Analysis Stage Generation Failed' }, + 'extensionanalysisstageconfirmation': { zh: '拓展分析阶段确认', en: 'Extension Analysis Stage Confirmation' }, + 'extensionanalysisstagerunresult': { zh: '拓展分析阶段运行结果', en: 'Extension Analysis Stage Run Result' }, + 'extensionstage': { zh: '拓展阶段', en: 'Extension Stage' }, + 'arabidopsisath': { zh: '拟南芥 (ath', en: 'Arabidopsis (ath)' }, + 'arabidopsisthalianaath': { zh: '拟南芥 Arabidopsis (ath', en: 'Arabidopsis thaliana (ath)' }, + 'arabidopsisfallbackreferenceconfirmed': { zh: '拟南芥兜底参考已确认', en: 'Arabidopsis Fallback Reference Confirmed' }, + 'arabidopsisonlyinorthologppikaksparamsot': { zh: '拟南芥只会写入 Ortholog/PPI/KaKs 专用参考参数,不会把全流程其它分析阶段改成 At。', en: 'Arabidopsis only in Ortholog/PPI/KaKs params; other stages unchanged.' }, + 'specifygtfgffannotation': { zh: '指定 GTF/GFF 注释', en: 'Specify GTF/GFF Annotation' }, + 'specifygwask0reportbestkonly-2': { zh: '指定 GWAS K(0=仅报告最佳 K)', en: 'Specify GWAS K (0=report best K only)' }, + 'splitperspecies': { zh: '按 per_species 拆分', en: 'Split per-species:' }, + 'byelement': { zh: '按元件', en: 'By Element' }, + 'perspeciesseparateanalysisconfirmation': { zh: '按单个物种分别分析与确认', en: 'Per-species Separate Analysis & Confirmation' }, + 'markbyspeciesandgeneratespecieslegend': { zh: '按物种标记并生成Species图例', en: 'Mark by species and generate Species legend' }, + 'markbytargetreferenceroleroletree': { zh: '按目标/参考角色标记(角色树)', en: 'Mark by target/reference role (Role Tree)' }, + 'bycategory': { zh: '按类别', en: 'By Category' }, + 'authorizepublish': { zh: '授权发布', en: 'Authorize Publish' }, + 'queued': { zh: '排队中', en: 'Queued' }, + 'waitinginqueue': { zh: '排队等待', en: 'Waiting in Queue' }, + 'recommendedrefdatadownloadfailed': { zh: '推荐参考数据下载失败', en: 'Recommended Ref Data Download Failed' }, + 'recommendedrefdatadownloadcomplete-2': { zh: '推荐参考数据已下载完成', en: 'Recommended Ref Data Download Complete' }, + 'recommendedrefdatadownloadinginbackgroun': { zh: '推荐参考数据正在后台下载', en: 'Recommended Ref Data Downloading in Background' }, + 'recommendednearsourcestringreferencespec': { zh: '推荐近源 STRING 参考物种:', en: 'Recommended Near-source STRING Reference Species:' }, + 'recommendednearsourceorthologousrefspeci': { zh: '推荐近源/同源参考物种', en: 'Recommended Near-source / Orthologous Ref Species' }, + 'submitrerunppi': { zh: '提交并重新运行 PPI', en: 'Submit & Re-run PPI' }, + 'submitconfiguredprojectrestartscript': { zh: '提交配置好的项目重启脚本', en: 'Submit Configured Project Restart Script' }, + 'submitrevisionsuggestions': { zh: '提出修订意见', en: 'Submit Revision Suggestions' }, + 'extracting': { zh: '提取中', en: 'Extracting...' }, + 'extractioncompletebutconfigreadfailed': { zh: '提取完成但配置读取失败', en: 'Extraction Complete but Config Read Failed' }, + 'tip': { zh: '提示:', en: 'Tip:' }, + 'searchgeneorentity': { zh: '搜索基因或实体...', en: 'Search gene or entity...' }, + 'operation': { zh: '操作', en: 'Operation' }, + 'operationfailed': { zh: '操作失败', en: 'Operation Failed' }, + 'placeat': { zh: '放在', en: 'Place at' }, + 'datapreparation-2': { zh: '数据准备', en: 'Data Preparation' }, + 'nonewexecutablemethodologystagesafterdat': { zh: '数据准备完成后没有新的可执行方法学阶段', en: 'No new executable methodology stages after data preparation' }, + 'dataat': { zh: '数据在', en: 'Data at' }, + 'databasearticleexpressionmatrix': { zh: '数据库/文章表达矩阵', en: 'Database / Article Expression Matrix' }, + 'dataformaterrornodesundefinedornotanarra': { zh: '数据格式错误: nodes 未定义或不是数组', en: 'Data Format Error: nodes undefined or not an array' }, + 'datadirectory': { zh: '数据目录', en: 'Data Directory' }, + 'datarolefromconfigxlsx': { zh: '数据角色(来自 config.xlsx)', en: 'Data Role (from config.xlsx)' }, + 'datawarningedgesundefinedusingemptyarray': { zh: '数据警告: edges 未定义,使用空数组', en: 'Data Warning: edges undefined, using empty array' }, + 'datapath': { zh: '数据路径', en: 'Data Path' }, + 'datagate': { zh: '数据门控', en: 'Data Gate' }, + 'dataneeds': { zh: '数据需求', en: 'Data Needs' }, + 'file': { zh: '文件', en: 'File' }, + 'fileuploadsuccessfulgenerationverificati': { zh: '文件上传成功,已开始生成并验收', en: 'File upload successful; generation & verification started' }, + 'fileat': { zh: '文件在', en: 'File at' }, + 'folder': { zh: '文件夹', en: 'Folder' }, + 'filedirectory': { zh: '文件目录', en: 'File Directory' }, + 'filedirectoryleaveemptytousecurrentjobin': { zh: '文件目录;留空则使用当前 job input 目录', en: 'File directory; leave empty to use current job input directory' }, + 'filetype': { zh: '文件类型', en: 'File Type' }, + 'filescope': { zh: '文件范围', en: 'File Scope' }, + 'documentsearch': { zh: '文档检索', en: 'Document Search' }, + 'literatureparameters': { zh: '文献参数', en: 'Literature Parameters' }, + 'literaturetools': { zh: '文献工具', en: 'Literature Tools' }, + 'literaturesupport': { zh: '文献支撑', en: 'Literature Support' }, + 'literaturesupportclaim': { zh: '文献支撑claim', en: 'Literature Support Claim' }, + 'literaturemethodvsbbav5stageaudit': { zh: '文献方法与 bbav5 阶段核对', en: 'Literature Method vs bbav5 Stage Audit' }, + 'literaturesnippet': { zh: '文献片段', en: 'Literature Snippet' }, + 'literaturerecord': { zh: '文献记录', en: 'Literature Record' }, + 'requiredforarticlereproductionegarabidop': { zh: '文章复现时必填,如 Arabidopsis thaliana', en: 'Required for article reproduction, e.g. Arabidopsis thaliana' }, + 'articlespeciesdownloadentry': { zh: '文章涉及物种与下载入口', en: 'Article Species & Download Entry' }, + 'newsession': { zh: '新会话', en: 'New Session' }, + 'newsessioncreatedpleaseselectorcreateawo': { zh: '新会话已创建,请选择或创建 Working Directory', en: 'New session created; please select or create a Working Directory' }, + 'add': { zh: '新增', en: 'Add' }, + 'newid': { zh: '新增 ID', en: 'New ID' }, + 'method1': { zh: '方式1:', en: 'Method 1:' }, + 'method2': { zh: '方式2:', en: 'Method 2:' }, + 'square': { zh: '方形', en: 'Square' }, + 'methodreference': { zh: '方法参考', en: 'Method Reference' }, + 'methodologysandboxbuilt': { zh: '方法学 sandbox 已构建', en: 'Methodology Sandbox Built' }, + 'methodologysandboxbuildfailed': { zh: '方法学 sandbox 构建失败', en: 'Methodology Sandbox Build Failed' }, + 'methodologysandboxqueryfailed': { zh: '方法学 sandbox 查询失败', en: 'Methodology Sandbox Query Failed' }, + 'methodologysandboxexamplereadfailed': { zh: '方法学 sandbox 示例读取失败', en: 'Methodology Sandbox Example Read Failed' }, + 'methodologyreference': { zh: '方法学参考', en: 'Methodology Reference' }, + 'methodologyexecutionplanningfailed': { zh: '方法学执行规划失败', en: 'Methodology Execution Planning Failed' }, + 'methodologyextraction': { zh: '方法学抽取', en: 'Methodology Extraction' }, + 'methodologyextractionbbav5executionaudit': { zh: '方法学提取与 bbav5 执行核对', en: 'Methodology Extraction & bbav5 Execution Audit' }, + 'methodologyextracting': { zh: '方法学提取中', en: 'Methodology Extracting...' }, + 'methodologyextractionlaunchfailed': { zh: '方法学提取启动失败', en: 'Methodology Extraction Launch Failed' }, + 'methodologyextractionfailed': { zh: '方法学提取失败', en: 'Methodology Extraction Failed' }, + 'methodologyextractionstatusreadfailed': { zh: '方法学提取状态读取失败', en: 'Methodology Extraction Status Read Failed' }, + 'methodologyextractionrecordreadfailed': { zh: '方法学提取记录读取失败', en: 'Methodology Extraction Record Read Failed' }, + 'methodologydatareadinesscheckfailed': { zh: '方法学数据就绪检查失败', en: 'Methodology Data Readiness Check Failed' }, + 'methodologypapers': { zh: '方法学文献', en: 'Methodology Papers' }, + 'methodologyplansavefailed': { zh: '方法学方案保存失败', en: 'Methodology Plan Save Failed' }, + 'methodologyplansavedpreparedatathenexecu': { zh: '方法学方案已保存,可先准备数据,稍后再按该方案执行', en: 'Methodology plan saved; prepare data then execute later.' }, + 'methodologyplanbindingfailed': { zh: '方法学方案绑定失败', en: 'Methodology Plan Binding Failed' }, + 'datapreparationrequiredbymethodologyplan': { zh: '方法学方案要求的数据准备', en: 'Data Preparation Required by Methodology Plan' }, + 'methodologypipeline': { zh: '方法学流水线', en: 'Methodology Pipeline' }, + 'methodologycontinueplanningfailed': { zh: '方法学续跑规划失败', en: 'Methodology Continue Planning Failed' }, + 'methodologyconfigreadfailed': { zh: '方法学配置读取失败', en: 'Methodology Config Read Failed' }, + 'noavailablenearsourcerecommendation': { zh: '无可用近源推荐', en: 'No Available Near-source Recommendation' }, + 'noexternalreference': { zh: '无外部参考', en: 'No External Reference' }, + 'cannotdeterminecombooutputlabelselectaco': { zh: '无法确定 combo 输出标签,请先选择 combo 图。', en: 'Cannot determine combo output label; select a combo plot first.' }, + 'cannotdeterminemsaoutputlabelselectimage': { zh: '无法确定MSA输出标签,请先选择对应图片或填写输出标签。', en: 'Cannot determine MSA output label; select image or fill output label.' }, + 'cannotdeterminepromoteroutputprefix': { zh: '无法确定启动子输出前缀。', en: 'Cannot determine promoter output prefix.' }, + 'cannotdetermineintraspeciessyntenyoutput': { zh: '无法确定种内共线性输出标签,请先选择 Circos 图。', en: 'Cannot determine intraspecies synteny output label; select Circos plot.' }, + 'cannotdeterminetreeoutputlabelselecttree': { zh: '无法确定进化树输出标签,请先选择树图或填写输出标签。', en: 'Cannot determine tree output label; select tree plot or fill output label.' }, + 'cannotreadoperationstatus': { zh: '无法读取操作状态', en: 'Cannot Read Operation Status' }, + 'noneedtouploadfilesagain': { zh: '无需再次Upload Files', en: 'No Need to Upload Files Again' }, + 'log': { zh: '日志', en: 'Log' }, + 'legacyfieldusuallyfalseseedreferencemayb': { zh: '旧兼容字段,通常 FALSE;seed_reference 可为 TRUE', en: 'Legacy field, usually FALSE; seed_reference may be TRUE' }, + 'timeseries': { zh: '时间序列 time_series', en: 'Time Series' }, + 'explicitlyspecify': { zh: '明确指定', en: 'Explicitly Specify' }, + 'show': { zh: '显示', en: 'Show' }, + 'pausecountdown': { zh: '暂停倒计时', en: 'Pause Countdown' }, + 'norecommendationsavailable': { zh: '暂无可用推荐', en: 'No Recommendations Available' }, + 'nouploadedfilesyet': { zh: '暂无已上传文件', en: 'No Uploaded Files Yet' }, + 'noextensionanalysisstageresultsyet': { zh: '暂无拓展分析阶段结果', en: 'No Extension Analysis Stage Results Yet' }, + 'nostatusrecordyet': { zh: '暂无状态记录', en: 'No Status Record Yet' }, + 'maxwidth': { zh: '最大宽度', en: 'Max Width' }, + 'minwidth': { zh: '最小宽度', en: 'Min Width' }, + 'minnongapratio': { zh: '最小非缺口比例', en: 'Min Non-gap Ratio' }, + 'finalcomprehensiveinterpretation': { zh: '最终综合解读', en: 'Final Comprehensive Interpretation' }, + 'closesttogenus': { zh: '最近到属', en: 'Closest to Genus' }, + 'closesttoorder': { zh: '最近到目', en: 'Closest to Order' }, + 'closesttofamily': { zh: '最近到科', en: 'Closest to Family' }, + 'closesttoclass': { zh: '最近到纲', en: 'Closest to Class' }, + 'lossyconversionwarning': { zh: '有损转换警告', en: 'Lossy Conversion Warning' }, + 'stagespausedawaitinguserconfirmation': { zh: '有阶段暂停,等待用户确认', en: 'Stages paused, awaiting user confirmation' }, + 'servertestdatapath': { zh: '服务器测试数据路径', en: 'Server Test Data Path' }, + 'serversidevcforvcfgzpath': { zh: '服务器端 .vcf 或 .vcf.gz 路径', en: 'Server-side .vcf or .vcf.gz Path' }, + 'noadditionalstagesinferredfromcharttitle': { zh: '未从图表标题推断出额外阶段', en: 'No Additional Stages Inferred from Chart Titles' }, + 'nomethodologyplanmatched': { zh: '未匹配到方法学计划', en: 'No Methodology Plan Matched' }, + 'unnamedsample': { zh: '未命名样本', en: 'Unnamed Sample' }, + 'nooutputfilesscanned': { zh: '未扫描到输出文件', en: 'No output files scanned' }, + 'nointerproscandomainreviewtsvfoundshowin': { zh: '未找到 InterProScan domain_review.tsv,当前显示 final_members 与 HMM/BLAST 证据;默认保留全部 final_members,确认后才继续方法学下游分析。', en: 'No InterProScan domain_review.tsv found; showing final_members with HMM/BLAST evidence; keeping all for downstream.' }, + 'referencespeciesnotfound': { zh: '未找到 reference 物种', en: 'Reference Species Not Found' }, + 'targetspeciesnotfound': { zh: '未找到 target 物种', en: 'Target Species Not Found' }, + 'nodirectlydownloadablestringnearsourcere': { zh: '未找到可直接下载的 STRING 近源参考物种。', en: 'No directly downloadable STRING near-source ref species found.' }, + 'noexistingtablefound': { zh: '未找到已有表格', en: 'No Existing Table Found' }, + 'novalidvcffound': { zh: '未找到有效 VCF', en: 'No Valid VCF Found' }, + 'norelatedinformationfound': { zh: '未找到相关信息', en: 'No Related Information Found' }, + 'nooutputfilesfound': { zh: '未找到输出文件', en: 'No Output Files Found' }, + 'nocharttitleextracted': { zh: '未提取到图表标题', en: 'No Chart Title Extracted' }, + 'notsupported': { zh: '未支持', en: 'Not Supported' }, + 'nopairablefastqfilesdetectedcannotgenera': { zh: '未检测到可配对的 FASTQ 样本文件,不能生成 samples.yaml 草稿。', en: 'No pairable FASTQ files detected; cannot generate samples.yaml draft.' }, + 'nopairablefastqfilesuseconfigxlsxautofil': { zh: '未检测到可配对的 FASTQ 样本文件;如果这是基因组/注释/蛋白/CDS目录,请使用 config.xlsx 自动填充。', en: 'No pairable FASTQ files; use config.xlsx auto-fill for genome/annotation/protein/CDS dirs.' }, + 'notgenerated': { zh: '未生成', en: 'Not Generated' }, + 'noexecutablestagesgeneratedcheckstagenam': { zh: '未生成可执行阶段。未检测到当前 scope 的完成结果时,不再把空计划解释为已完成;请检查阶段名称或前置依赖。', en: 'No executable stages generated; check stage names or upstream dependencies.' }, + 'noadvanceddesigngenerated': { zh: '未生成高级设计', en: 'No Advanced Design Generated' }, + 'unknown': { zh: '未知', en: 'Unknown' }, + 'unknownspecies': { zh: '未知物种', en: 'Unknown Species' }, + 'notbound': { zh: '未绑定', en: 'Not Bound' }, + 'notrecorded': { zh: '未记录', en: 'Not Recorded' }, + 'notset': { zh: '未设置', en: 'Not Set' }, + 'notrecognized': { zh: '未识别', en: 'Not Recognized' }, + 'nobuiltindllinkidentified': { zh: '未识别到内置下载链接', en: 'No Built-in DL Link Identified' }, + 'noparametersidentified': { zh: '未识别到参数', en: 'No Parameters Identified' }, + 'noliteraturetoolidentified': { zh: '未识别到文献工具', en: 'No Literature Tool Identified' }, + 'nospeciesinfodetected': { zh: '未识别到物种信息', en: 'No Species Info Detected' }, + 'notselected': { zh: '未选择', en: 'Not Selected' }, + 'plantairestartscriptorrestartplantai9000-2': { zh: '未配置 PLANTAI_RESTART_SCRIPT 或 restart_plantai_9000.sh', en: 'PLANTAI_RESTART_SCRIPT or restart_plantai_9000.sh not configured' }, + 'noprojectrestartscriptconfigured': { zh: '未配置项目重启脚本', en: 'No Project Restart Script Configured' }, + 'thisupload': { zh: '本次上传', en: 'This Upload' }, + 'currentsubfamilyclassificationtargetstar': { zh: '本次亚家族分类对象(target', en: 'Current Subfamily Classification Targets (target)' }, + 'skipppikaksthistime': { zh: '本次先跳过 PPI/KaKs', en: 'Skip PPI/KaKs This Time' }, + 'allstagesofthiscompletegwasusethisprefix': { zh: '本次完整 GWAS 的所有阶段统一使用该前缀。', en: 'All stages of this complete GWAS use this prefix uniformly.' }, + 'currentmemberidentificationspecies': { zh: '本次成员鉴定物种', en: 'Current Member Identification Species' }, + 'executionscopeforthisstage': { zh: '本阶段执行范围', en: 'Execution Scope for This Stage' }, + 'historicalmessages': { zh: '条历史消息', en: ' historical messages' }, + 'hints': { zh: '条提示', en: ' hints' }, + 'source': { zh: '来源:', en: 'Source:' }, + 'nearsourcerefrecommendationfromstringspe': { zh: '来自 STRING 物种列表的近源参考推荐', en: 'Near-source ref recommendation from STRING species list' }, + 'buildfailed': { zh: '构建失败', en: 'Build Failed' }, + 'buildapididnotreturnextensionidcannotpro': { zh: '构建接口未返回 extension_id,不能继续试运行。', en: 'Build API did not return extension_id; cannot proceed with trial.' }, + 'fruitflydme': { zh: '果蝇 Fly (dme', en: 'Fruit Fly (dme)' }, + 'chromosomeannotationposition': { zh: '染色体标注位置', en: 'Chromosome Annotation Position' }, + 'chromosomeannotationsize': { zh: '染色体标注大小', en: 'Chromosome Annotation Size' }, + 'chromosomestrategy': { zh: '染色体策略', en: 'Chromosome Strategy' }, + 'chromosomeblockwidth': { zh: '染色体色块粗细', en: 'Chromosome Block Width' }, + 'chromosomescommaseparated': { zh: '染色体(逗号分隔)', en: 'Chromosomes (comma-separated)' }, + 'viewselectedextractionstatus': { zh: '查看所选提取状态', en: 'View Selected Extraction Status' }, + 'viewlatestextractionstatus': { zh: '查看最新提取状态', en: 'View Latest Extraction Status' }, + 'queryanalysis': { zh: '查询分析', en: 'Query Analysis' }, + 'standardoutput': { zh: '标准输出', en: 'Standard Output' }, + 'standardoutputdirectdisplay': { zh: '标准输出(直接展示)', en: 'Standard Output (Direct Display)' }, + 'labeltable': { zh: '标签表', en: 'Label Table' }, + 'marksize': { zh: '标记大小', en: 'Mark Size' }, + 'markmode': { zh: '标记模式', en: 'Mark Mode' }, + 'candidatestagesinferredfromtitles': { zh: '标题推断的候选阶段', en: 'Candidate Stages Inferred from Titles' }, + 'charttitleruleinference': { zh: '标题规则推断', en: 'Chart Title Rule Inference' }, + 'treefileautoresolvedfromcurrentimagetotr': { zh: '树文件:将根据当前图片自动解析对应 .tree.nwk', en: 'Tree file: auto-resolved from current image to .tree.nwk' }, + 'branchwidth': { zh: '树枝粗细', en: 'Branch Width' }, + 'branchcolor': { zh: '树枝颜色', en: 'Branch Color' }, + 'sample': { zh: '样本', en: 'Sample' }, + 'sampleqcrequiresatleast2samplesforpcacor': { zh: '样本 QC 至少需要 2 个样本才能计算 PCA、相关性或距离。', en: 'Sample QC requires at least 2 samples for PCA, correlation or distance.' }, + 'sampleinfotablesampleid': { zh: '样本信息表 sample_id', en: 'Sample Info Table sample_id' }, + 'sampleinfotablepathoptionalsamplesinfoxl': { zh: '样本信息表路径,可选:samples_info.xlsx/csv/tsv', en: 'Sample info table path, optional: samples_info.xlsx/csv/tsv' }, + 'samplegrouptableoptionalforpcald': { zh: '样本分组表(PCA/LD 可选)', en: 'Sample Group Table (optional for PCA/LD)' }, + 'sampleparallelcount': { zh: '样本并行数量', en: 'Sample Parallel Count' }, + 'insufficientsamplecount': { zh: '样本数量不足', en: 'Insufficient sample count' }, + 'samplefiles': { zh: '样本文件', en: 'Sample Files' }, + 'sampleclusteringtreeplotfailed': { zh: '样本聚类树绘图失败', en: 'Sample Clustering Tree Plot Failed' }, + 'sampletable': { zh: '样本表', en: 'Sample Table' }, + 'sampletableandexpressionmatrixmismatch': { zh: '样本表和表达矩阵不匹配', en: 'Sample table and expression matrix mismatch' }, + 'sampletableautodetection': { zh: '样本表自动识别', en: 'Sample Table Auto-detection' }, + 'sampleevaluation': { zh: '样本评估', en: 'Sample Evaluation' }, + 'sampleconfiguration': { zh: '样本配置', en: 'Sample Configuration' }, + 'sampleconfiguration-2': { zh: '样本配置:', en: 'Sample Configuration:' }, + 'karyotypechromosomedistributionanalysis': { zh: '核型/染色体分布分析', en: 'Karyotype / Chromosome Distribution Analysis' }, + 'checksamplenamesrunidsinsamplesyamlagain': { zh: '核对 samples.yaml 的样本名、run ID 和 count matrix 表头,确保名称一致。', en: 'Check sample names, run IDs in samples.yaml against count matrix headers.' }, + 'check': { zh: '检查', en: 'Check' }, + 'checkcountmatrixkeeponlygeneidsamplecoun': { zh: '检查 count matrix,只保留 gene_id', en: 'Check count matrix; keep only gene_id + sample count columns; remove Chr/Start/End/Strand/Length.' }, + 'checkifsamplesyamlhasonlyonesampleorqcqu': { zh: '检查 samples.yaml 是否只保留了一个样本,或上游 QC/quant 是否只产出一个样本的 count。', en: 'Check if samples.yaml has only one sample, or QC/quant produced single-sample count.' }, + 'checktaskstatusfailed': { zh: '检查任务状态失败', en: 'Check Task Status Failed' }, + 'multipletaxadetectedforclassification': { zh: '检测到多个待分类物种:', en: 'Multiple taxa detected for classification:' }, + 'multiplevalidvcfsdetectedpleaseselect': { zh: '检测到多个有效 VCF,请选择', en: 'Multiple valid VCFs detected; please select' }, + 'downloadmodeautoretrievespeciesdata': { zh: '检索Download模式 (download) - 自动检索物种数据', en: 'Download Mode - Auto-retrieve Species Data' }, + 'downloadmode': { zh: '检索Download模式:', en: 'Download Mode:' }, + 'searching': { zh: '检索中', en: 'Searching...' }, + 'searchresultssufficient': { zh: '检索结果充分', en: 'Search Results Sufficient' }, + 'searchtablecontent': { zh: '检索表格内容', en: 'Search Table Content' }, + 'regexmatch': { zh: '正则匹配', en: 'Regex Match' }, + 'loadinginterspeciesspecieslist': { zh: '正在加载种间物种列表...', en: 'Loading Interspecies Species List...' }, + 'processingrequest': { zh: '正在处理请求...', en: 'Processing request...' }, + 'searchingknowledgebaseandgeneratinganswe': { zh: '正在检索知识库并生成回答...', en: 'Searching knowledge base and generating answer...' }, + 'understandingyourquestionandidentifyings': { zh: '正在理解你的问题并识别检索目标……', en: 'Understanding your question and identifying search targets...' }, + 'generatingexecutionplanandcheckinginputf': { zh: '正在生成执行计划并检查输入文件...', en: 'Generating execution plan and checking input files...' }, + 'searchingknowledgebaseforrelevantcontent': { zh: '正在知识库中查找相关内容……', en: 'Searching knowledge base for relevant content...' }, + 'recognizingyouranalysisintent': { zh: '正在识别你的分析意图...', en: 'Recognizing your analysis intent...' }, + 'recognizingintentandanalysistype': { zh: '正在识别意图和分析类型...', en: 'Recognizing intent and analysis type...' }, + 'invokingmultiagentmethodologyexecutionse': { zh: '正在调用多智能体规划方法学执行顺序...', en: 'Invoking multi-agent methodology execution sequence planning...' }, + 'thisextensionstagehasnoconfigurableparam': { zh: '此拓展阶段没有可配置参数', en: 'This extension stage has no configurable parameters' }, + 'eachtaxongeneratesindependenttreecombopl': { zh: '每个待分类物种分别与 reference 生成独立树、组合图、亚家族分类结果和确认表。', en: 'Each taxon generates independent tree, combo plot, subfamily results with reference.' }, + 'alignment': { zh: '比对', en: 'Alignment' }, + 'comparisonaxis': { zh: '比较主轴:', en: 'Comparison Axis:' }, + 'comparisonaxisautodetect': { zh: '比较主轴:自动判断', en: 'Comparison Axis: Auto-detect' }, + 'comparativespeciescheckasneeded': { zh: '比较物种(按需勾选)', en: 'Comparative Species (check as needed)' }, + 'riceosa': { zh: '水稻 (osa', en: 'Rice (osa)' }, + 'ricechromosomes112': { zh: '水稻 1–12 号染色体', en: 'Rice Chromosomes 1-12' }, + 'aggregatebatchoutput': { zh: '汇总批次输出', en: 'Aggregate Batch Output' }, + 'nomatchingdraftrows': { zh: '没有匹配的草稿行', en: 'No matching draft rows' }, + 'nodownloadablerecommendednearsourcerefsp': { zh: '没有可下载的推荐近源参考物种', en: 'No downloadable recommended near-source ref species' }, + 'noresultsfoundtodisplay': { zh: '没有找到可展示的结果。', en: 'No results found to display.' }, + 'noextensionanalysisstagedetectedforexecu': { zh: '没有识别到要执行的拓展分析阶段', en: 'No extension analysis stage detected for execution' }, + 'uselegacypipelinecompatibilitydesign': { zh: '沿用原流程兼容设计', en: 'Use legacy pipeline compatibility design' }, + 'testdata': { zh: '测试数据', en: 'Test Data' }, + 'browse': { zh: '浏览', en: 'Browse' }, + 'addt01suffixaddt01': { zh: '添加.T01后缀 (add_T01', en: 'Add .T01 Suffix (add_T01)' }, + 'addrow': { zh: '添加行', en: 'Add Row' }, + 'gray': { zh: '灰色', en: 'Gray' }, + 'species': { zh: '物种', en: 'Species' }, + 'species1cdsegatcdsfasta': { zh: '物种1 CDS序列 (如 At.cds.fasta', en: '- Species 1 CDS (e.g. At.cds.fasta)' }, + 'species2cdsegoscdsfasta': { zh: '物种2 CDS序列 (如 Os.cds.fasta', en: '- Species 2 CDS (e.g. Os.cds.fasta)' }, + 'speciescode': { zh: '物种代码', en: 'Species Code' }, + 'speciescodeunchanged': { zh: '物种代码不改', en: 'Species Code (Unchanged)' }, + 'speciesname': { zh: '物种名', en: 'Species Name' }, + 'specieslatinnameegarabidopsisthaliana': { zh: '物种拉丁名,如 Arabidopsis thaliana', en: 'Species Latin name, e.g. Arabidopsis thaliana' }, + 'speciesabbreviationegosatzm': { zh: '物种简称,如 Os / At / Zm', en: 'Species abbreviation, e.g. Os / At / Zm' }, + 'speciesrole': { zh: '物种角色', en: 'Species Role' }, + 'speciesroleunchanged': { zh: '物种角色不改', en: 'Species Role (Unchanged)' }, + 'maizezma': { zh: '玉米 (zma', en: 'Maize (zma)' }, + 'environment': { zh: '环境', en: 'Environment' }, + 'generate': { zh: '生成', en: 'Generate' }, + 'generating': { zh: '生成中', en: 'Generating...' }, + 'generateanswer': { zh: '生成回答', en: 'Generate Answer' }, + 'generatedraft': { zh: '生成草稿', en: 'Generate Draft' }, + 'draftgenerationfailed': { zh: '生成草稿失败', en: 'Draft Generation Failed' }, + 'generateinterpretationfailed': { zh: '生成解读失败', en: 'Generate Interpretation Failed' }, + 'biologicalcontext': { zh: '生物学背景', en: 'Biological Context' }, + 'usedtoinferkeggorganismcodeegoryzasativa': { zh: '用于推断 KEGG organism code;例如 Oryza sativa 会优先检索 osa 物种级 pathway gene set', en: 'Used to infer KEGG organism code; e.g. Oryza sativa retrieves osa species-level pathway gene set' }, + 'usermanuallyadded': { zh: '用户手动添加', en: 'User Manually Added' }, + 'leaveemptytousegtfgffannotationfrominput': { zh: '留空则使用 input 中的 GTF/GFF 注释', en: 'Leave empty to use GTF/GFF annotation from input' }, + 'leaveemptytouseoutput': { zh: '留空则使用 output', en: 'Leave empty to use output' }, + 'leaveemptyforautouseoffeaturecountscount': { zh: '留空则自动使用 featureCounts count matrix', en: 'Leave empty for auto-use of featureCounts count matrix' }, + 'leaveemptyforautouseofnormalizedvsttpmma': { zh: '留空则自动使用 normalized/vst/TPM 表达矩阵', en: 'Leave empty for auto-use of normalized/vst/TPM matrix' }, + 'leaveemptyforautouseofsamplesyamlsamplet': { zh: '留空则自动使用 samples.yaml / sample table', en: 'Leave empty for auto-use of samples.yaml / sample table' }, + 'leaveemptyforautodiscovery': { zh: '留空则自动发现', en: 'Leave empty for auto-discovery' }, + 'leaveemptyforautoinference': { zh: '留空则自动推断', en: 'Leave empty for auto-inference' }, + 'leaveemptyforautogenerationdiscovery': { zh: '留空则自动生成/发现', en: 'Leave empty for auto-generation/discovery' }, + 'leaveemptyforautoselectionofdecomparison': { zh: '留空则自动选择 DE comparison', en: 'Leave empty for auto-selection of DE comparison' }, + 'leaveemptytousefastpbinorpath': { zh: '留空时使用 FASTP_BIN 或 PATH', en: 'Leave empty to use FASTP_BIN or PATH' }, + 'tomatosly': { zh: '番茄 (sly', en: 'Tomato (sly)' }, + 'directory': { zh: '目录', en: 'Directory' }, + 'target': { zh: '目标', en: 'Target' }, + 'targetprefix': { zh: '目标前缀', en: 'Target Prefix' }, + 'targetspecies-2': { zh: '目标物种', en: 'Target Species' }, + 'targetspeciesnotinstringsnapshotconfirmu': { zh: '目标物种不在 STRING 固定快照中。请确认是否采用排序第一的近源物种:', en: 'Target species not in STRING snapshot. Confirm using top-ranked near-source species:' }, + 'targetspeciesnotusableforstringppikaks': { zh: '目标物种当前不能直接用于 STRING PPI/KaKs', en: 'Target species not usable for STRING PPI/KaKs.' }, + 'targetspeciesnotusableforstringppikaks-2': { zh: '目标物种当前不能直接用于 STRING PPI/KaKs。', en: 'Target species not usable for STRING PPI/KaKs.' }, + 'directuploadexpressionmatrixfpkmtxttpmtx': { zh: '直接上传 - 上传表达量矩阵(*.fpkm.txt/*.tpm.txt)', en: 'Direct Upload: expression matrix (*.fpkm.txt/*.tpm.txt)+geneID+sample.txt' }, + 'knowledgegraph': { zh: '知识图谱', en: 'Knowledge Graph' }, + 'knowledgegraphloaded': { zh: '知识图谱加载完成', en: 'Knowledge Graph Loaded' }, + 'knowledgebasesearch': { zh: '知识库检索', en: 'Knowledge Base Search' }, + 'knowledgebasesearchtimedout300s': { zh: '知识库检索超时(300秒未返回)。', en: 'Knowledge base search timed out (300s).' }, + 'gotit-2': { zh: '知道了', en: 'Got It' }, + 'rectangularplot': { zh: '矩形图', en: 'Rectangular Plot' }, + 'rectangulartree': { zh: '矩形树', en: 'Rectangular Tree' }, + 'confirm-2': { zh: '确定', en: 'Confirm' }, + 'confirmdeanalysisdesign': { zh: '确认 DE 分析设计', en: 'Confirm DE Analysis Design' }, + 'confirmppistringnearsourcereferencespeci': { zh: '确认 PPI 的 STRING 近源参考物种', en: 'Confirm PPI STRING Near-source Reference Species' }, + 'verifygenomefilesindexininputdonotusecds': { zh: '确认 input 目录中有类似 Os.genome.fasta/fa/fna,或 Os.genome.1.ht2 等基因组索引;不要把 Os.cds 或 Os.pep 当作比对参考。', en: 'Verify genome files/index in input; do not use CDS/PEP as alignment reference.' }, + 'confirmsubfamilylabels': { zh: '确认亚家族标签', en: 'Confirm Subfamily Labels' }, + 'confirmsave': { zh: '确认保存', en: 'Confirm Save' }, + 'confirmkeepallmembers': { zh: '确认保留全部成员', en: 'Confirm Keep All Members' }, + 'nonewexecutablestagesafterconfirmation': { zh: '确认后常规分析没有新的可执行阶段', en: 'No new executable stages after confirmation' }, + 'nonewexecutablestagesafterconfirmation-2': { zh: '确认后常规分析没有新的可执行阶段。', en: 'No new executable stages after confirmation.' }, + 'refpepdownloadorthologgenerationppiexecu': { zh: '确认后才会下载参考 PEP、生成 Ortholog,并执行 PPI。', en: 'Ref PEP download, Ortholog generation, PPI execution only after confirmation.' }, + 'onlypublishafterconfirmationwillnotautop': { zh: '确认后才会发布;不会自动发布。', en: 'Only publish after confirmation; will not auto-publish.' }, + 'confirmfailed': { zh: '确认失败', en: 'Confirm Failed' }, + 'confirmedsaved': { zh: '确认已保存', en: 'Confirmed & Saved' }, + 'confirmwritetoofficialconfig': { zh: '确认并写入正式配置', en: 'Confirm & Write to Official Config' }, + 'confirmexecute': { zh: '确认并执行', en: 'Confirm & Execute' }, + 'confirmexecution-2': { zh: '确认执行', en: 'Confirm Execution' }, + 'confirmfirstcandidate': { zh: '确认第一候选', en: 'Confirm First Candidate' }, + 'confirmautoannotation': { zh: '确认自动注释', en: 'Confirm Auto-Annotation' }, + 'confirmationtable': { zh: '确认表', en: 'Confirmation Table' }, + 'confirmdesignwrite': { zh: '确认设计并写入', en: 'Confirm Design & Write' }, + 'confirmrestart': { zh: '确认重启', en: 'Confirm Restart' }, + 'exampledownloadfunctioncurrentlyunavaila': { zh: '示例下载功能当前不可用', en: 'Example Download Function Currently Unavailable' }, + 'disablekeggnetwork': { zh: '禁用 KEGG 网络', en: 'Disable KEGG Network' }, + 'intraspeciessyntenycircosrevisionparamet': { zh: '种内共线性 Circos 修订参数', en: 'Intraspecies Synteny Circos Revision Parameters' }, + 'intraspeciessyntenycircosreplotfailed': { zh: '种内共线性 Circos 重绘失败:', en: 'Intraspecies Synteny Circos Replot Failed:' }, + 'intraspeciessyntenycircosreplotcompletes': { zh: '种内共线性 Circos 重绘完成,已切换到新图', en: 'Intraspecies synteny Circos replot complete; switched to new figure' }, + 'intraspeciessyntenycircosreplotsubmitted': { zh: '种内共线性 Circos 重绘已提交:task_id=', en: 'Intraspecies synteny Circos replot submitted: task_id=' }, + 'intraspeciessyntenyanalysis': { zh: '种内共线性分析', en: 'Intraspecies Synteny Analysis' }, + 'interspeciessyntenyanalysis': { zh: '种间共线性分析', en: 'Interspecies Synteny Analysis' }, + 'interspeciessyntenycomparativespecies': { zh: '种间共线性比较物种', en: 'Interspecies Synteny Comparative Species' }, + 'interspeciessyntenyplotsettings': { zh: '种间共线性绘图设置', en: 'Interspecies Synteny Plot Settings' }, + 'remove': { zh: '移除', en: 'Remove' }, + 'windowlength': { zh: '窗口长度', en: 'Window Length' }, + 'filter': { zh: '筛选', en: 'Filter' }, + 'simplifytooriginalrecordid': { zh: '简化为原record ID', en: 'Simplify to Original Record ID' }, + 'type': { zh: '类型', en: 'Type' }, + 'exactmatch': { zh: '精确匹配', en: 'Exact Match' }, + 'system': { zh: '系统', en: 'System' }, + 'systemwillpreparerefpepcdsgenerateorthol': { zh: '系统会先准备参考 PEP/CDS,再由 Ortholog 生成映射,之后执行 PPI/KaKs。', en: 'System will prepare ref PEP/CDS, generate Ortholog mapping, then execute PPI/KaKs.' }, + 'systemwillautosearchfilesattheselocation': { zh: '系统会自动搜索以下位置的文件:', en: 'System Will Auto-Search Files at These Locations:' }, + 'phylogenetics': { zh: '系统发育', en: 'Phylogenetics' }, + 'phylogeneticanalysis': { zh: '系统发育分析', en: 'Phylogenetic Analysis' }, + 'systemdeterminingexecutionentryrunningup': { zh: '系统正在确定执行入口,并运行上传的代码和测试数据,提取不可修改的执行事实。', en: 'System determining execution entry; running uploaded code and test data.' }, + 'red': { zh: '红色', en: 'Red' }, + 'comboplot': { zh: '组合图', en: 'Combo Plot' }, + 'tissue': { zh: '组织 tissue', en: 'Tissue' }, + 'endalignmentcolumn': { zh: '终止 alignment 列', en: 'End Alignment Column' }, + 'endsite': { zh: '终止位点', en: 'End Site' }, + 'endresidue': { zh: '终止残基', en: 'End Residue' }, + 'domainanalysis': { zh: '结构域分析', en: 'Domain Analysis' }, + 'numberoftopmotifsinresultplot': { zh: '结果图展示的 Top motif 数量', en: 'Number of Top Motifs in result plot' }, + 'resultcorrectcontinue': { zh: '结果无误,继续', en: 'Result Correct; Continue' }, + 'resultfailedmanifestvalidation': { zh: '结果未通过 manifest 校验', en: 'Result failed manifest validation' }, + 'resultchecklistvalidationfailed': { zh: '结果清单校验未通过', en: 'Result checklist validation failed' }, + 'resulttable': { zh: '结果表', en: 'Result Table' }, + 'resultassessment': { zh: '结果评估', en: 'Result Assessment' }, + 'plotdatareusegffmcscanxcollinearityfamil': { zh: '绘图数据:复用 synteny 阶段的 GFF、MCScanX collinearity、family gene ID 和 genome。', en: 'Plot data: reuse GFF, MCScanX collinearity, family gene ID and genome from synteny stage.' }, + 'plotmode': { zh: '绘图模式', en: 'Plot Mode' }, + 'unifiedtipmark': { zh: '统一Tip标记', en: 'Unified Tip Mark' }, + 'statisticschain': { zh: '统计链:', en: 'Statistics Chain:' }, + 'green': { zh: '绿色', en: 'Green' }, + 'edit': { zh: '编辑', en: 'Edit' }, + 'missingcleanreadsafterqc': { zh: '缺少 QC 后的 clean reads', en: 'Missing clean reads after QC' }, + 'missinggene2kobackground': { zh: '缺少 gene2ko 背景', en: 'Missing gene2ko Background' }, + 'missinggene2kobackgroundfile': { zh: '缺少 gene2ko 背景文件', en: 'Missing gene2ko Background File' }, + 'missingusablegene2gobackground': { zh: '缺少可用 gene2go 背景', en: 'Missing Usable gene2go Background' }, + 'missingusableorthologmapping': { zh: '缺少可用同源映射', en: 'Missing Usable Ortholog Mapping' }, + 'missingbackgroundannotationfile': { zh: '缺少背景注释文件', en: 'Missing Background Annotation File' }, + 'missinginputdata': { zh: '缺少输入数据', en: 'Missing Input Data' }, + 'confidence': { zh: '置信度', en: 'Confidence' }, + 'confidencethreshold': { zh: '置信度阈值', en: 'Confidence Threshold' }, + 'populationlddecayanalysis': { zh: '群体LD衰减分析', en: 'Population LD Decay Analysis' }, + 'populationpcaanalysis': { zh: '群体PCA分析', en: 'Population PCA Analysis' }, + 'populationphylogenetictreeanalysis': { zh: '群体系统树分析', en: 'Population Phylogenetic Tree Analysis' }, + 'populationstructureanalysis': { zh: '群体结构分析', en: 'Population Structure Analysis' }, + 'populationgeneticinput': { zh: '群体遗传输入', en: 'Population Genetic Input' }, + 'backgroundidexample': { zh: '背景ID示例', en: 'Background ID Example' }, + 'backgroundreferenceonlynotindataprep': { zh: '背景提及,不进入数据准备', en: 'Background reference only; not in data prep' }, + 'backgroundsource': { zh: '背景来源', en: 'Background Source' }, + 'backgroundannotation': { zh: '背景注释', en: 'Background Annotation' }, + 'auto': { zh: '自动', en: 'Auto' }, + 'autoinferfromconfigxlsxscope': { zh: '自动从 config.xlsx / scope 推断', en: 'Auto-infer from config.xlsx / scope' }, + 'autoextractfromannotation': { zh: '自动从注释提取', en: 'Auto-extract from Annotation' }, + 'autousesamplesyamlfrominputfinal': { zh: '自动使用 input/final 中的 samples.yaml', en: 'Auto-use samples.yaml from input/final' }, + 'autoconservedwindow': { zh: '自动保守窗口', en: 'Auto Conserved Window' }, + 'autofix': { zh: '自动修复', en: 'Auto Fix' }, + 'autofixresults': { zh: '自动修复结果', en: 'Auto Fix Results' }, + 'autorecommendedprioritizefamilydegenesfa': { zh: '自动判定(推荐):优先 family_DE_genes,缺失时回退 DE_genes', en: 'Auto (recommended): prioritize family_DE_genes, fallback to global DE_genes' }, + 'autoprioritizefamilydegenesfallbacktoglo': { zh: '自动判定:优先 family_DE_genes,缺失时回退全局 DE_genes', en: 'Auto: prioritize family_DE_genes, fallback to global DE_genes' }, + 'autogenefamilywhenfinalmembersidexistsot': { zh: '自动判定:有 final_members.id 时做基因家族,否则做全基因组', en: 'Auto: gene family when final_members.id exists, otherwise genome-wide' }, + 'autodetect': { zh: '自动判断', en: 'Auto-detect' }, + 'autodetectrecommended': { zh: '自动判断(推荐)', en: 'Auto-detect (Recommended)' }, + 'autoreview': { zh: '自动审核', en: 'Auto Review' }, + 'autodetectpeadapter': { zh: '自动检测 PE adapter', en: 'Auto-detect PE Adapter' }, + 'autoannotatecontinue': { zh: '自动注释并继续', en: 'Auto-annotate & Continue' }, + 'autoannotationislongtaskautoconfirmin40s': { zh: '自动注释是长任务。40秒内不操作将自动确认;可暂停倒计时后手动决定。', en: 'Auto-annotation is long task. Auto-confirm in 40s if no action; pause countdown to decide.' }, + 'autodetectrecommended-2': { zh: '自动识别(推荐)', en: 'Auto-detect (Recommended)' }, + 'autoselectplanttfdbjaspar': { zh: '自动选择 PlantTFDB/JASPAR', en: 'Auto-select PlantTFDB/JASPAR' }, + 'autoselectgene2gofirstthenbuiltinorgdbbi': { zh: '自动选择:优先 gene2go,其次内置OrgDb/可用Bioconductor', en: 'Auto-select: gene2go first, then built-in OrgDb/Bioconductor' }, + 'autoselectuploadedbackgroundfirstthenbui': { zh: '自动选择:优先已上传背景,其次内置模式物种/可用Bioconductor', en: 'Auto-select: uploaded background first, then built-in model species/Bioconductor' }, + 'autoperspeciesformultiunifiedtipforsingl': { zh: '自动:多物种按物种,单物种统一Tip', en: 'Auto: per-species for multi; unified Tip for single' }, + 'nltriggerwordscommaseparatedegblastpsequ': { zh: '自然语言触发词,逗号分隔,例如 blastp, 序列比对, SPL blast', en: 'NL trigger words, comma-separated, e.g. blastp, sequence alignment' }, + 'nldescriptiontargetspeciesfamilyreferenc': { zh: '自然语言说明:目标物种、家族、参考物种、比较物种等', en: 'NL description: target species, family, reference, comparative, etc.' }, + 'naturallanguageschedulinginprogress': { zh: '自然语言调度执行中...', en: 'Natural language scheduling in progress...' }, + 'atleasttwosamples': { zh: '至少两个样本', en: 'At least two samples' }, + 'keepatleastonegeneid': { zh: '至少保留一个 gene ID', en: 'Keep at least one gene ID' }, + 'diamond': { zh: '菱形', en: 'Diamond' }, + 'blue': { zh: '蓝色', en: 'Blue' }, + 'protein': { zh: '蛋白', en: 'Protein' }, + 'proteinpep': { zh: '蛋白/PEP', en: 'Protein/PEP' }, + 'proteinfiles': { zh: '蛋白文件', en: 'Protein Files' }, + 'proteinphysicochemicalpropertiessubcellu': { zh: '蛋白理化性质与亚细胞定位', en: 'Protein Physicochemical Properties & Subcellular Localization' }, + 'tablepreview': { zh: '表格预览', en: 'Table Preview' }, + 'expressionmatrix': { zh: '表达矩阵', en: 'Expression Matrix' }, + 'expressionmatrixanalysis': { zh: '表达矩阵分析', en: 'Expression Matrix Analysis' }, + 'seeexecutionlog': { zh: '见执行日志', en: 'See Execution Log' }, + 'plan': { zh: '规划', en: 'Plan' }, + 'planning': { zh: '规划中', en: 'Planning...' }, + 'planningrevisionsuggestions': { zh: '规划修订建议', en: 'Planning Revision Suggestions' }, + 'planningfailed': { zh: '规划失败', en: 'Planning Failed' }, + 'planningrequestfailed': { zh: '规划请求失败', en: 'Planning Request Failed' }, + 'normalizeobservation': { zh: '规范化 observation', en: 'Normalize Observation' }, + 'viewreset': { zh: '视图已重置', en: 'View Reset' }, + 'interpretationcontentcopied': { zh: '解读内容已复制', en: 'Interpretation Content Copied' }, + 'designreviewfailed': { zh: '设计审查失败', en: 'Design Review Failed' }, + 'designreviewneedsadditionalinformation': { zh: '设计审查需要补充信息', en: 'Design Review Needs Additional Information' }, + 'designreview': { zh: '设计审查:', en: 'Design Review:' }, + 'diagnosis': { zh: '诊断', en: 'Diagnosis' }, + 'trialrunning': { zh: '试运行中...', en: 'Trial Running...' }, + 'trialrunfailed': { zh: '试运行失败', en: 'Trial Run Failed' }, + 'trialrunfailedpleasechecklog': { zh: '试运行失败,请查看日志', en: 'Trial run failed; please check log' }, + 'trialrunsuccessful': { zh: '试运行成功', en: 'Trial Run Successful' }, + 'trialrunnotpassed': { zh: '试运行未通过', en: 'Trial Run Not Passed' }, + 'thisidalreadyexists': { zh: '该 ID 已存在', en: 'This ID Already Exists' }, + 'stagealreadyinformallist': { zh: '该阶段已在正式列表中', en: 'Stage Already in Formal List' }, + 'description': { zh: '说明', en: 'Description' }, + 'noteppineedsorthologmappingoftargetstost': { zh: '说明:PPI 需要先把目标基因通过 Ortholog 映射到 STRING 支持物种;Ka/Ks 还需要参考 CDS。你可以先准备/下载参考数据,也可以本次先跳过 PPI/KaKs,继续其它不依赖该数据的分析。', en: 'Note: PPI needs Ortholog mapping of targets to STRING species; Ka/Ks needs ref CDS. Prepare/download ref data or skip PPI/KaKs this time.' }, + 'pleaseuploadvcffirstorfixauthoritativema': { zh: '请先上传 VCF,或修复当前 job 的权威 Manifest。', en: 'Please upload VCF first, or fix authoritative Manifest of current job.' }, + 'pleasebuildtemporarydbfirst': { zh: '请先构建临时库', en: 'Please Build Temporary DB First' }, + 'pleasereviewconfigxlsxdraftfirst': { zh: '请先核对 config.xlsx 草稿。', en: 'Please review config.xlsx draft first.' }, + 'pleasegenerateorloadadraftfirst': { zh: '请先生成或加载草稿', en: 'Please generate or load a draft first' }, + 'pleasegenerateextensionanalysisstagefirs': { zh: '请先生成拓展分析阶段。', en: 'Please generate extension analysis stage first.' }, + 'pleasetrialrunfirsttorecordactualoutput': { zh: '请先试运行以记录真实输出', en: 'Please trial-run first to record actual output' }, + 'pleaseselectpdforminerucontentlistjsonli': { zh: '请先选择 PDF 或 MinerU content_list JSON 文献文件', en: 'Please select PDF or MinerU content_list JSON literature file' }, + 'pleaseselectanimagefirst': { zh: '请先选择一张图片', en: 'Please select an image first' }, + 'pleaseselectanactualrunjobfirst': { zh: '请先选择实际运行 Job。', en: 'Please select an actual run Job first.' }, + 'pleaseselectorcreateaworkingdirectory': { zh: '请先选择或创建 Working Directory', en: 'Please select or create a Working Directory' }, + 'pleaseselectorentermethodologydirfirst': { zh: '请先选择或输入 methodology_dir', en: 'Please select or enter methodology_dir first' }, + 'pleaseselectavalidvcffirst': { zh: '请先选择有效 VCF', en: 'Please Select a Valid VCF First' }, + 'pleasepreviewchangestoapplyfirst': { zh: '请先预览要应用的修改', en: 'Please preview changes to apply first' }, + 'pleasewriterevisionsuggestions': { zh: '请写明修订意见。', en: 'Please write revision suggestions.' }, + 'pleasedescriberevisioncontentherethensen': { zh: '请在这里说明需要修订的内容,然后发送。', en: 'Please describe revision content here, then send.' }, + 'describerevisioninmainconversationinputb': { zh: '请在页面下方的主对话输入框说明需要修订的内容,然后发送。命令和真实执行事实不会被修改。', en: 'Describe revision in main conversation input below; commands and facts won\'t be modified.' }, + 'pleasefillgwasspeciesabbreviationforresu': { zh: '请填写 GWAS 物种简称(用于结果前缀)', en: 'Please fill GWAS species abbreviation (for result prefix)' }, + 'pleasefillmsaalignmentstartendcolumnsors': { zh: '请填写MSA alignment 起始列和终止列,或选择其他模式。', en: 'Please fill MSA alignment start/end columns or select another mode.' }, + 'pleasefillreferencegeneanditsstartendres': { zh: '请填写参考基因及其起止残基编号。', en: 'Please fill reference gene and its start/end residue numbers.' }, + 'fillnameandprovidetestdataorserverpathat': { zh: '请填写名称并提供测试数据文件或服务器路径;原始命令和原始代码至少提供一项。', en: 'Fill name and provide test data or server path; at least original command or code.' }, + 'fillnameanduploadoriginalcode': { zh: '请填写名称,并上传原始代码。', en: 'Fill name and upload original code.' }, + 'pleasecheckverificationlog': { zh: '请查看验证日志', en: 'Please Check Verification Log' }, + 'pleasechecktestdataandcommandtemplate': { zh: '请检查测试数据和命令模板', en: 'Please check test data and command template' }, + 'request': { zh: '请求', en: 'Request' }, + 'requestfailed': { zh: '请求失败', en: 'Request Failed' }, + 'requestfailedpleasetryagainlater': { zh: '请求失败,请稍后重试。', en: 'Request failed; please try again later.' }, + 'interpretationservicerequestfailed': { zh: '请求解读服务失败', en: 'Interpretation Service Request Failed' }, + 'requesttimedoutnoanswerwithintimelimitpl': { zh: '请求超时,未能在规定时间内获得回答,请稍后重试。', en: 'Request timed out; no answer within time limit; please try again later.' }, + 'pleasefillatleastonefieldtopreviewchange': { zh: '请至少填写一个要预览修改的字段', en: 'Please fill at least one field to preview changes' }, + 'pleaseselectatleastoneexecutablebbav5sta': { zh: '请至少选择一个可执行的 bbav5 阶段', en: 'Please select at least one executable bbav5 stage' }, + 'pleaseselectatleastonepromoterelementorc': { zh: '请至少选择一个启动子元件或类别。', en: 'Please select at least one promoter element or category.' }, + 'pleaseselectatleastoneplottype': { zh: '请至少选择一种图类型。', en: 'Please select at least one plot type.' }, + 'pleasedetailyourrequirements': { zh: '请补充你的需求。', en: 'Please detail your requirements.' }, + 'pleaseenterfilepath': { zh: '请输入文件路径', en: 'Please Enter File Path' }, + 'pleaseentermethodologyquestion': { zh: '请输入方法学问题', en: 'Please Enter Methodology Question' }, + 'pleaseselectsyntenyanalysistype': { zh: '请选择共线性分析类型', en: 'Please select synteny analysis type' }, + 'pleaseselectthisgwasinput': { zh: '请选择本次 GWAS 输入', en: 'Please select this GWAS input' }, + 'failedtoreadpromoterelements': { zh: '读取启动子元件失败:', en: 'Failed to Read Promoter Elements:' }, + 'failedtoreadextensionanalysisstatus': { zh: '读取拓展分析状态失败', en: 'Failed to Read Extension Analysis Status' }, + 'failedtoreadextensionanalysisdescription': { zh: '读取拓展分析说明失败', en: 'Failed to Read Extension Analysis Description' }, + 'readconfirmationinfofailed': { zh: '读取确认信息失败', en: 'Read Confirmation Info Failed' }, + 'failedtoreadlightweightextensionanalysis': { zh: '读取轻量拓展分析列表失败', en: 'Failed to Read Lightweight Extension Analysis List' }, + 'failedtoreadrunparameters': { zh: '读取运行参数失败', en: 'Failed to Read Run Parameters' }, + 'failedtoreadrundescription': { zh: '读取运行说明失败', en: 'Failed to Read Run Description' }, + 'failedtoreadverificationresults': { zh: '读取验证结果失败', en: 'Failed to Read Verification Results' }, + 'bringup': { zh: '调出', en: 'Bring Up' }, + 'pedigreeinputinvalid': { zh: '谱系图输入无效', en: 'Pedigree Input Invalid' }, + 'qc': { zh: '质控', en: 'QC' }, + 'startalignmentcolumn': { zh: '起始 alignment 列', en: 'Start Alignment Column' }, + 'startsite': { zh: '起始位点', en: 'Start Site' }, + 'startresidue': { zh: '起始残基', en: 'Start Residue' }, + 'path': { zh: '路径', en: 'Path' }, + 'pathcopied': { zh: '路径已复制', en: 'Path Copied' }, + 'skippathview': { zh: '跳过 pathview', en: 'Skip pathview' }, + 'transcriptome': { zh: '转录组', en: 'Transcriptome' }, + 'polltaskstatusfailed': { zh: '轮询任务状态失败', en: 'Poll Task Status Failed' }, + 'loadparseddocument': { zh: '载入解析文档', en: 'Load Parsed Document' }, + 'input': { zh: '输入', en: 'Input' }, + 'entergeneidtosearchandlocate': { zh: '输入 Gene ID 搜索定位', en: 'Enter Gene ID to Search and Locate' }, + 'inputfiles': { zh: '输入文件', en: 'Input Files' }, + 'inputfilesparameters': { zh: '输入文件和参数', en: 'Input Files & Parameters' }, + 'output': { zh: '输出', en: 'Output' }, + 'outputprefix': { zh: '输出前缀', en: 'Output Prefix' }, + 'outputnaming': { zh: '输出命名:', en: 'Output Naming:' }, + 'outputnamingautofromconfigxlsxfilespecie': { zh: '输出命名:按 config.xlsx / 文件物种代码自动生成,不需要填写输出标签', en: 'Output naming: auto from config.xlsx / file species codes' }, + 'outputnamingautoinferredwhenempty': { zh: '输出命名:留空时自动推断', en: 'Output naming: auto-inferred when empty' }, + 'outputfiles': { zh: '输出文件', en: 'Output Files' }, + 'outputlabel': { zh: '输出标签', en: 'Output Label' }, + 'outputtagprefix': { zh: '输出标签 / Prefix', en: 'Output Tag / Prefix' }, + 'runvalue': { zh: '运行值', en: 'Run Value' }, + 'runresults': { zh: '运行结果', en: 'Run Results' }, + 'runresultreview': { zh: '运行结果核对', en: 'Run Result Review' }, + 'returntomodify': { zh: '返回修改', en: 'Return to Modify' }, + 'whatisthemethodologyworkflowofthispaper': { zh: '这个文献的方法学流程是什么?', en: 'What is the methodology workflow of this paper?' }, + 'thiswillstopandrestartceleryworkerbacken': { zh: '这会停止当前 profile 的 Celery worker 并重新启动。若有任务正在运行,后端会默认拒绝执行。', en: 'This will stop and restart Celery worker; backend rejects if tasks running.' }, + 'thiswillsubmitprojectrestartscriptpagema': { zh: '这会提交项目重启脚本,当前页面可能短暂断开。', en: 'This will submit project restart script; page may briefly disconnect.' }, + 'sampleqcfinalplotboundaryissueupstreamal': { zh: '这是 sample QC 最后的绘图边界问题,不代表前面的比对、定量或 VST 计算全部失败。', en: 'Sample QC final plot boundary issue; upstream alignment/quantification/VST not all failed.' }, + 'phylogenetictreerevisionparameters': { zh: '进化树图修订参数', en: 'Phylogenetic Tree Revision Parameters' }, + 'phylogenetictreereplotfailed': { zh: '进化树图重绘失败:', en: 'Phylogenetic Tree Replot Failed:' }, + 'phylogenetictreereplotcompleteswitchedto': { zh: '进化树图重绘完成,已切换到新图', en: 'Phylogenetic tree replot complete; switched to new figure' }, + 'phylogenetictreereplotsubmittedtaskid': { zh: '进化树图重绘已提交:task_id=', en: 'Phylogenetic tree replot submitted: task_id=' }, + 'treeoutputlayoutbothoutputsrectangularan': { zh: '进化树输出布局。both 会同时输出矩形树和圈图。', en: 'Tree output layout; both outputs rectangular and circle plots.' }, + 'selectabredreltrmbsetc': { zh: '选择 ABRE / DRE / LTR / MBS 等', en: 'Select ABRE / DRE / LTR / MBS etc.' }, + 'afterselectingdlrecommendedrefdatasystem': { zh: '选择“下载推荐参考数据”后,系统会先下载参考 PEP/CDS,再重新检查并由 Ortholog 生成映射。', en: 'After selecting DL recommended ref data, system downloads ref PEP/CDS, re-checks, generates Ortholog mapping.' }, + 'whenselectingskipthistimeppikaksmarkedpa': { zh: '选择“本次先跳过”时,PPI/KaKs 会标记为暂停,其它阶段继续执行。', en: 'When selecting skip this time, PPI/KaKs marked paused; other stages continue.' }, + 'selectotherextractionresult': { zh: '选择其他提取结果', en: 'Select Other Extraction Result' }, + 'selectanalysisstageselectstage': { zh: '选择分析阶段 / Select stage', en: 'Select Analysis Stage / Select stage' }, + 'selecttool': { zh: '选择工具', en: 'Select Tool' }, + 'selectcompletedextensionstage': { zh: '选择已完成撰写的拓展阶段', en: 'Select Completed Extension Stage' }, + 'selectorentergeneid': { zh: '选择或输入基因ID', en: 'Select or Enter Gene ID' }, + 'selectclassificationidentificationtarget': { zh: '选择本次分类/鉴定对象', en: 'Select classification/identification targets for this run' }, + 'selectanalysistypestoshowincomboplotuses': { zh: '选择要在 combo 图中展示的分析类型;单类型图请使用对应阶段已有结果。', en: 'Select analysis types to show in combo plot; use stage results for single-type plots.' }, + 'perrowfieldleaveemptyforgenomewidefillfo': { zh: '逐行字段;全基因组资源留空,已知家族 seed 文件才填写,如 NAC/WRKY', en: 'Per-row field; leave empty for genome-wide; fill for known family seed files' }, + 'usuallyleaveempty': { zh: '通常留空', en: 'Usually Leave Empty' }, + 'configbulkeditarea': { zh: '配置批量修订区', en: 'Config Bulk Edit Area' }, + 'configfile': { zh: '配置文件', en: 'Config File' }, + 'configtable': { zh: '配置表', en: 'Config Table' }, + 'configtableautodetection': { zh: '配置表自动识别', en: 'Config Table Auto-detection' }, + 'yeastsce': { zh: '酵母 Yeast (sce', en: 'Yeast (sce)' }, + 'restartcelery': { zh: '重启 Celery', en: 'Restart Celery' }, + 'restartproject': { zh: '重启项目', en: 'Restart Project' }, + 'redrawingfeatureunderdevelopment': { zh: '重新绘图功能开发中...', en: 'Re-drawing feature under development...' }, + 'redetect': { zh: '重新识别', en: 'Re-detect' }, + 'resetview-2': { zh: '重置视图', en: 'Reset View' }, + 'link': { zh: '链接', en: 'Link' }, + 'librarystrandedness': { zh: '链特异性', en: 'Library Strandedness' }, + 'librarystrandednessunchangededitable': { zh: '链特异性不改/可输入', en: 'Library Strandedness (Unchanged/Editable)' }, + 'error': { zh: '错误', en: 'Error' }, + 'stage-2': { zh: '阶段', en: 'Stage' }, + 'stagepausedawaitinguserconfirmation': { zh: '阶段暂停,等待用户确认', en: 'Stage paused, awaiting user confirmation' }, + 'hide': { zh: '隐藏', en: 'Hide' }, + 'needsconfirmation': { zh: '需确认', en: 'Needs Confirmation' }, + 'preparenearsourcehomologousrefdatafirstt': { zh: '需要先准备近源/同源参考物种数据,再由 Ortholog 生成目标到参考物种映射。', en: 'Prepare near-source/homologous ref data first, then generate target-to-ref mapping via Ortholog.' }, + 'needtorunidentifystagefirst': { zh: '需要先运行 Identify 阶段', en: 'Need to run Identify stage first' }, + 'refdataandorthologmappingneeded': { zh: '需要准备参考数据和 Ortholog 映射', en: 'Ref data and Ortholog mapping needed' }, + 'autoannotationneededtogenerateenrichment': { zh: '需要自动注释生成富集背景', en: 'Auto-annotation needed to generate enrichment background' }, + 'needtosupplement': { zh: '需要补充', en: 'Need to Supplement' }, + 'needs': { zh: '需要:', en: 'Needs:' }, + 'leaveemptyfornontimeexperiments': { zh: '非时间实验留空', en: 'Leave empty for non-time experiments' }, + 'project': { zh: '项目', en: 'Project' }, + 'projectrestartnotsubmitted': { zh: '项目重启未提交', en: 'Project Restart Not Submitted' }, + 'projectrestartscriptsubmitted': { zh: '项目重启脚本已提交', en: 'Project Restart Script Submitted' }, + 'preview-2': { zh: '预览', en: 'Preview' }, + 'previewtotable': { zh: '预览到表格', en: 'Preview to Table' }, + 'previewcommands': { zh: '预览命令', en: 'Preview Commands' }, + 'verifying': { zh: '验证中...', en: 'Verifying...' }, + 'verificationfailed': { zh: '验证失败', en: 'Verification Failed' }, + 'verificationfailedpleasecheckbackendlog': { zh: '验证失败,请查看后端日志', en: 'Verification failed; please check backend log' }, + 'verificationsuccessful': { zh: '验证成功', en: 'Verification Successful' }, + 'verificationsuccessfulreadytopublish': { zh: '验证成功,可发布', en: 'Verification Successful; Ready to Publish' }, + 'verificationsuccessfulstartingpublish': { zh: '验证成功,开始发布...', en: 'Verification successful; starting publish...' }, + 'verificationnotpassed': { zh: '验证未通过', en: 'Verification Not Passed' }, + 'highpriority': { zh: '高优先级', en: 'High Priority' }, + 'black': { zh: '黑色', en: 'Black' }, + 'defaultvalue': { zh: '默认值', en: 'Default Value' }, + 'bydefaultgeneratesallspeciesoverviewandp': { zh: '默认生成所有物种总图和两两共线性图。', en: 'By default generates all-species overview and pairwise synteny plots.' }, + 'tabdelimited': { zh: '(制表符分隔)', en: '(Tab-delimited)' }, + 'nofileoutput': { zh: '(无文件输出)', en: '(No File Output)' }, + 'noproteinfastadetected': { zh: '(未检测到蛋白FASTA)', en: '(No Protein FASTA Detected)' }, + 'prerequisitegate': { zh: ';前置/门控', en: '; Pre-requisite / Gate' }, + 'parallelizable': { zh: ';可并行', en: '; Parallelizable' }, + 'hasresultsorhandledbydependency': { zh: ';已有结果或由依赖链处理', en: '; Has Results or Handled by Dependency' }, + 'searchresults': { zh: '📄 检索结果', en: 'Search Results' }, + 'filterallresults': { zh: '📄 过滤全库页', en: 'Filter All Results' }, + 'cumulativeprogress': { zh: '📈 当前累计进展', en: 'Cumulative Progress' }, + 'expressiondatasourceselectone': { zh: '📊 表达量数据来源(Select一种):', en: 'Expression Data Source (Select One):' }, + 'nextstepsuggestions': { zh: '📋 下一步建议', en: 'Next Step Suggestions' }, + 'requiredfiles': { zh: '📋 所需文件:', en: 'Required Files:' }, + 'uploadfilestoinputdirectory': { zh: '📤 Upload Files到input目录', en: 'Upload Files to Input Directory' }, + 'needtouploadfiles': { zh: '📤 需要Upload Files:', en: 'Need to Upload Files:' }, + 'inputfilerequirementsgzcompressionsuppor': { zh: '📦 Input文件要求(支持.gz压缩):', en: 'Input File Requirements (.gz Compression Supported):' }, + 'subfamilylabelsconfirmedpullingpostconfi': { zh: '🔁 亚家族标签已确认,正在拉取确认后常规分析规划...', en: 'Subfamily labels confirmed; pulling post-confirmation analysis plan...' }, + 'subfamilylabelsconfirmedreplanningpostco': { zh: '🔁 亚家族标签已确认,正在重新规划确认后常规基因家族分析...', en: 'Subfamily labels confirmed; re-planning post-confirmation gene family analysis...' }, + 'reload': { zh: '🔄 重新加载', en: 'Reload' }, + 'scientificdiscoverycandidatehypothesis': { zh: '🔎 科学发现 / 候选假设', en: 'Scientific Discovery / Candidate Hypothesis' }, + 'useexistingdatapathautocreatesymlink': { zh: '🔗 使用已有数据路径(自动创建软链接', en: 'Use Existing Data Path (Auto-create Symlink)' }, + 'rnaseqdatasource': { zh: '🔬 RNA-seq 数据来源:', en: 'RNA-seq Data Source:' }, + 'biologicalstory': { zh: '🧬 生物学故事', en: 'Biological Story' }, + 'evidencecard': { zh: '🧷 证据卡', en: 'Evidence Card' }, + 'err-data-format': { zh: '数据格式错误: nodes 未定义或不是数组', en: 'Data format error: nodes is undefined or not an array' }, + 'warn-edges-undefined': { zh: '数据警告: edges 未定义,使用空数组', en: 'Data warning: edges undefined, using empty array' }, + + // ========== agent_status_component additions ========== + 'msg-load-task-failed': { zh: '加载任务失败:', en: 'Failed to load tasks:' }, + 'msg-check-task-status-failed': { zh: '检查任务状态失败:', en: 'Failed to check task status:' }, + + // ========== Auto-generated from scan ========== + 'label-gobioconductorinterproscankegg': { zh: '按需补背景 + 富集(GO 优先Bioconductor,回退InterProScan;KEGG 用KofamScan)', en: 'Add background + enrichment (GO via Bioconductor, fallback InterProScan; KEGG via KofamScan)' }, + 'label-gobioconductorkeggkofamscan': { zh: '按需补背景 + 继续富集(GO优先Bioconductor,KEGG用KofamScan)', en: 'Add background + continue enrichment (GO via Bioconductor, KEGG via KofamScan)' }, + 'ph-athhsaosa': { zh: '如 ath / hsa / osa', en: 'e.g. ath / hsa / osa' }, + 'ph-atos': { zh: '如 At / Os', en: 'e.g. At / Os' }, + 'ph-ftosprefix': { zh: '如 Ft / Os,留空取 prefix 第一段', en: 'e.g. Ft / Os, leave empty for first segment of prefix' }, + 'ph-geneid': { zh: '检索 gene ID', en: 'Search gene ID' }, + 'ph-oryzasativa': { zh: '如 Oryza sativa', en: 'e.g. Oryza sativa' }, + 'ph-osaathzma': { zh: '如 osa / ath / zma', en: 'e.g. osa / ath / zma' }, + 'txt-': { zh: '📚 参考文献', en: '📚 References' }, + 'txt--': { zh: '- 同源基因对', en: '- Orthologous gene pairs' }, + 'txt-0claim': { zh: '0">🧬 Claim级结果解读', en: '🧬 Claim-Level Result Interpretation' }, + 'txt-agent': { zh: '结果 agent', en: 'Result agent' }, + 'txt-id': { zh: '按ID提取序列', en: 'Extract sequence by ID' }, + 'txt-rag': { zh: '🧪 证据质量 / RAG解读审计', en: '🧪 Evidence Quality / RAG Audit' }, + 'txt-self-rag': { zh: '📝 Self-RAG反思', en: '📝 Self-RAG Reflection' }, + 'txt-tip': { zh: '💡 使用小Tip', en: '💡 Quick Tips' }, + + + + // === Fix empty t() === + 'extract-methodology': { zh: '提取方法学', en: 'Extract' }, + 'run-published': { zh: '运行已发布', en: 'Run Published' }, + 'more-conversations': { zh: '更多会话', en: 'More Conversations' }, + 'new-session': { zh: '新建会话', en: 'New Session' }, + 'new-session-title': { zh: '新会话', en: 'New Session' }, + 'generate-and-publish': { zh: '生成并发布', en: 'Generate & Publish' }, + 'stop-waiting': { zh: '停止等待', en: 'Stop Waiting' }, + + 'current-display-mode-analysis-or-rag': { zh: '当前显示模式: analysis or rag', en: 'Current display mode: analysis or rag' }, + + // === Bulk additions === + 'refresh-records': { zh: '刷新记录', en: 'Refresh Records' }, + 'more-sessions': { zh: '更多会话', en: 'More Sessions' }, + 'new': { zh: '新建', en: 'New' }, + 'restart-celery': { zh: '重启 Celery', en: 'Restart Celery' }, + 'restart-project': { zh: '重启项目', en: 'Restart Project' }, + 'current-session': { zh: '当前会话', en: 'Current Session' }, + 'no-parameters-identified': { zh: '未识别到参数', en: 'No parameters identified' }, + 'please-trial-run-to-record-output': { zh: '请先试运行以记录真实输出', en: 'Please run a trial first to record actual output' }, + 'no-configurable-parameters': { zh: '此拓展阶段没有可配置参数', en: 'No configurable parameters for this extension stage' }, + 'current-job': { zh: '当前 job', en: 'Current job' }, + 'latin-name-alias': { zh: '拉丁名/别名(文章复现必填)', en: 'Latin name/alias (required for reproduction)' }, + 'revision': { zh: '修订', en: 'Revision' }, + 'search-failed': { zh: '检索失败', en: 'Search failed' }, + 'matched': { zh: '匹配', en: 'Matched' }, + 'above': { zh: '上方', en: 'Above' }, + 'primary-reference-species': { zh: '主参考物种', en: 'Primary reference species' }, + 'reference-config-main-entry': { zh: '参考配置主入口', en: 'Reference config main entry' }, + 'will-be-written-to': { zh: '会分别写入', en: 'Will be written to' }, + 'row-level-override-only': { zh: '仅作为行级高级覆盖或旧配置兼容', en: 'Row-level override / legacy config only' }, + 'usually-leave-empty': { zh: '通常留空', en: 'Usually leave empty' }, + 'species-code-short': { zh: '物种简称', en: 'Species code (short)' }, + 'required-for-article-reproduction': { zh: '文章复现时为必填项', en: 'Required for article reproduction' }, + 'required-only-for-known-family-ref': { zh: '只在已知家族参考序列行必填', en: 'Required only for known family reference rows' }, + 'sequencing-run-srr': { zh: '测序运行号/SRR号', en: 'Sequencing run / SRR ID' }, + 'used-to-match': { zh: '用于匹配', en: 'Used to match' }, + 'sample-name-in-info-table': { zh: '样本信息表中的样本名', en: 'Sample name in info table' }, + 'sample-key': { zh: '样本键', en: 'Sample key' }, + 'paired-end-sequencing-file': { zh: '双端测序文件', en: 'Paired-end sequencing file' }, + 'indicates-treatment-tissue-group': { zh: '表示处理/组织/分组', en: 'Indicates treatment / tissue / group' }, + 'biological-replicate-number': { zh: '生物学重复编号', en: 'Biological replicate number' }, + 'only-for-time-series': { zh: '只在时间序列或明确发育时期实验中填写', en: 'Only for time series or developmental stage experiments' }, + 'leave-empty-for-tissue-comparison': { zh: '普通组织比较请留空', en: 'Leave empty for tissue comparison' }, + 'must-fill-per-library-instructions': { zh: '必须按建库说明填写', en: 'Must fill per library instructions' }, + 'group-role-for-marking': { zh: '分组角色用于标记', en: 'Group role for marking' }, + 'de-generates-comparisons': { zh: 'DE 会按设计生成对照比较或多组两两比较', en: 'DE generates control comparisons or pairwise group comparisons' }, + 'view-knowledge-retrieval-process': { zh: '查看本次知识检索过程', en: 'View knowledge retrieval process' }, + 'searching-knowledge-base': { zh: '正在知识库中查找相关内容', en: 'Searching knowledge base for related content' }, + 'default-thread-description': { zh: 'Default 是新提交任务使用的线程数', en: 'Default — thread count for new tasks' }, + 'max-stage-limit': { zh: 'Max 是该阶段上限', en: 'Max — upper limit for this stage' }, + 'increase-default-syncs-max': { zh: '直接提高 Default 时会同步提高 Max', en: 'Increasing Default will also raise Max' }, + 'sample-parallelism-affects-qc-align': { zh: '样本并行数只影响 QC/Align 的样本级并发', en: 'Sample parallelism only affects QC/Align sample concurrency' }, + 'original-filename-must-match': { zh: '原文件名必须匹配上传文件名', en: 'Original filename must match uploaded filename' }, + + // === R2 === + + 'stopped-waiting-no-answer': { zh: '已停止等待,本次未继续获取回答', en: 'Stopped waiting, no response received.' }, + + + 'text': { zh: '文本', en: 'Text' }, + 'background-knowledge': { zh: '背景知识', en: 'Background knowledge' }, + 'none': { zh: '无', en: 'None' }, + 'current-cumulative-findings': { zh: '当前累计发现', en: 'Current cumulative findings' }, + 'num-connections': { zh: ' 个', en: ' ' }, + 'or': { zh: '或', en: 'or' }, + + // === index_ml.html 模板文本(第5批) === + 'building-extension-stage': { zh: '生成并发布', en: 'Build & Publish' }, + 'running-published': { zh: '运行已发布', en: 'Run Published' }, + 'no-results-yet': { zh: '暂无结果', en: 'No Results' }, + 'unidentified-params': { zh: '未识别到参数', en: 'No Parameters Identified' }, + 'trial-first-for-output': { zh: '请先试运行以记录真实输出', en: 'Please Run a Trial First to Record Actual Output' }, + 'no-config-params': { zh: '此拓展阶段没有可配置参数', en: 'No Configurable Parameters' }, + 'searching-knowledge-base': { zh: '正在知识库中查找相关内容……', en: 'Searching Knowledge Base...' }, + 'processing-request': { zh: '正在处理请求...', en: 'Processing Request...' }, + 'uploaded-files': { zh: '已上传文件', en: 'Uploaded Files' }, + 'not-selected': { zh: '未选择', en: 'Not Selected' }, + 'not-loaded-gene-id': { zh: '未加载到 gene ID;请确认 PPI 已生成输入基因列表', en: 'Gene ID not loaded; please confirm PPI has generated input gene list' }, + 'searching-knowledge-base-full': { zh: '正在知识库中查找相关内容……', en: 'Searching Knowledge Base for Related Content...' }, + 'selectfile': { zh: '选择文件', en: 'Select File' }, + 'upload-files': { zh: '上传文件', en: 'Upload Files' }, + + // === tip popup steps === + 'tip-analysis-step1': { zh: '1.选择输入框上方"Analysis"', en: '1. Select "Analysis" above the input box' }, + 'tip-analysis-step2': { zh: '2.粘贴数据位置', en: '2. Paste data location' }, + 'tip-analysis-step3': { zh: '3.核对配置文件', en: '3. Verify configuration file' }, + 'tip-analysis-step4': { zh: '4.执行数据准备', en: '4. Execute data preparation' }, + 'tip-analysis-step5': { zh: '5.执行XX物种的亚家族分类', en: '5. Execute subfamily classification for XX species' }, + 'tip-analysis-step6': { zh: '6.执行XX物种的基因家族分析', en: '6. Execute gene family analysis for XX species' }, + 'tip-analysis-step7': { zh: '7.执行rnaseq分析', en: '7. Execute RNA-seq analysis' }, + 'tip-repro-step1': { zh: '1.点击"浏览"上传文献', en: '1. Click "Browse" to upload literature' }, + 'tip-repro-step2': { zh: '2.点击提取方法学', en: '2. Click "Extract Methodology"' }, + 'tip-repro-step3': { zh: '3.核对分析步骤', en: '3. Verify analysis steps' }, + 'tip-repro-step4': { zh: '4.点击保存方案', en: '4. Click "Save Plan"' }, + 'tip-repro-step5': { zh: '5.上传数据', en: '5. Upload data' }, + 'tip-repro-step6': { zh: '6.发送"按已保存的方法学方案继续执行"', en: '6. Send "Continue with saved methodology plan"' }, + 'tip-rag-step1': { zh: '1.选择输入框上方"RAG"', en: '1. Select "RAG" above the input box' }, + 'tip-rag-step2': { zh: '2.输入问题', en: '2. Enter your question' }, + 'tip-rag-step3': { zh: '3.点击"知识图谱"查看关系', en: '3. Click "Knowledge Graph" to view relationships' }, + + // === Additional ElMessage keys === + 'msg-create-failed': { zh: '创建失败', en: 'Creation failed' }, + 'msg-create-wd-success': { zh: '已创建新Working Directory', en: 'New Working Directory created' }, + 'msg-found-node': { zh: '找到节点', en: 'Found node' }, + 'msg-members-rebuilt': { zh: '已按 {count} 个成员重建 final_members。{rerun}', en: 'Rebuilt final_members with {count} members. {rerun}' }, + 'msg-ppi-reset-done': { zh: 'PPI Reset 已完成', en: 'PPI Reset completed' }, + 'msg-selected-code-files': { zh: '已选择 {count} 个原始代码文件', en: 'Selected {count} original code files' }, + 'msg-selected-data-files': { zh: '已选择 {count} 个测试数据文件', en: 'Selected {count} test data files' }, + 'msg-subfamily-confirmed': { zh: '已确认 {count} 个亚家族标签。{msg}', en: 'Confirmed {count} subfamily labels. {msg}' }, + 'msg-switch-failed': { zh: '切换失败', en: 'Switch failed' }, + 'msg-switch-wd-success': { zh: '已切换到Working Directory', en: 'Switched to Working Directory' }, + 'msg-switched-to': { zh: '切换到', en: 'Switched to' }, + 'msg-task-info': { zh: '任务', en: 'Task' }, + 'msgbox-ppi-tech-ref': { zh: 'PPI 的技术参考必须来自已确认的 STRING 候选;项目参考物种不会写入 PPI owner。', en: 'PPI technical reference must come from confirmed STRING candidates; project reference species will not be written to PPI owner.' }, + 'msgbox-restart-celery': { zh: '这会停止当前 profile 的 Celery worker 并重新启动。若有任务正在运行,后端会默认拒绝执行。', en: 'This will stop the Celery worker for the current profile and restart it. If tasks are running, the backend will refuse by default.' }, + 'msgbox-restart-project': { zh: '这会提交项目重启脚本,当前页面可能短暂断开。', en: 'This will submit the project restart script. The current page may briefly disconnect.' }, + + // === ElMessage toast messages === + 'msg-batch-already-running': { zh: '当前已有批量任务在执行,请等待完成后再提交方法学流程', en: 'A batch task is already running; wait for it to finish before submitting methodology pipeline' }, + 'msg-build-extension-first': { zh: '请先生成拓展分析阶段。', en: 'Please build the extension stage first.' }, + 'msg-build-temp-library-first': { zh: '请先构建临时库', en: 'Please build temporary library first' }, + 'msg-celery-restarted': { zh: 'Celery 已重启并完成队列检查', en: 'Celery restarted and queue check completed' }, + 'msg-clear-current-session': { zh: '已Clear当前会话', en: 'Current session cleared' }, + 'msg-combo-min-two-types': { zh: 'Combo 修订至少选择两个类型。', en: 'Combo revision requires at least two types selected.' }, + 'msg-combo-output-label-error': { zh: '无法确定 combo 输出标签,请先选择 combo 图。', en: 'Cannot determine combo output label; select a combo plot first.' }, + 'msg-combo-replot-done': { zh: 'Combo 图修订完成,已切换到新图', en: 'Combo revision completed, switched to new image' }, + 'msg-combo-replot-error': { zh: 'Combo 图修订失败', en: 'Combo revision failed' }, + 'msg-confirm-saved': { zh: '确认已保存', en: 'Confirmation saved' }, + 'msg-content-copied': { zh: '解读内容已复制', en: 'Content copied' }, + 'msg-copy-failed': { zh: '复制失败', en: 'Copy failed' }, + 'msg-create-session-failed': { zh: '创建会话失败', en: 'Failed to create session' }, + 'msg-create-wd-error': { zh: '获取Working Directory列表失败', en: 'Failed to get Working Directory list' }, + 'msg-delete-session-failed': { zh: '删除会话失败', en: 'Failed to delete session' }, + 'msg-design-hint': { zh: '设计提示', en: 'Design hint' }, + 'msg-diagnosis-closed': { zh: '已关闭诊断提示。', en: 'Diagnosis hint closed.' }, + 'msg-domain-confirm-error': { zh: 'Domain确认失败', en: 'Domain confirmation failed' }, + 'msg-download-demo-unavailable': { zh: '示例下载功能当前不可用', en: 'Download demo feature is currently unavailable' }, + 'msg-enter-file-path': { zh: '请输入文件路径', en: 'Please enter a file path' }, + 'msg-enter-methodology-question': { zh: '请输入方法学问题', en: 'Please enter methodology question' }, + 'msg-error-log-cleared': { zh: '错误日志已清空', en: 'Error log cleared' }, + 'msg-evidence-supplement-error': { zh: '补充证据失败', en: 'Evidence supplement failed' }, + 'msg-extension-built': { zh: '拓展分析阶段已生成并发布', en: 'Extension analysis stage built and published' }, + 'msg-extension-executed': { zh: '拓展分析阶段执行完成', en: 'Extension analysis stage execution completed' }, + 'msg-extension-execution-warn': { zh: '拓展分析阶段执行未成功,请查看结果日志', en: 'Extension analysis execution unsuccessful; check result logs' }, + 'msg-extension-published': { zh: '拓展分析阶段已发布', en: 'Extension stage published' }, + 'msg-fill-at-least-one-field': { zh: '请至少填写一个要预览修改的字段', en: 'Please fill at least one field to preview the change' }, + 'msg-fill-each-input-file': { zh: '请填写每个输入文件。', en: 'Please fill in each input file.' }, + 'msg-fill-gwas-species': { zh: '请填写 GWAS 物种简称(用于结果前缀)', en: 'Please fill in GWAS species code (used for result prefix)' }, + 'msg-fill-name-and-code': { zh: '请填写名称,并上传原始代码。', en: 'Please fill name and upload original code.' }, + 'msg-fill-name-and-code-or-data': { zh: '请填写名称并提供测试数据文件或服务器路径;原始命令和原始代码至少提供一项。', en: 'Please fill name and provide test data file or server path; original command and code — at least one required.' }, + 'msg-fill-revision-comments': { zh: '请写明修订意见。', en: 'Please specify revision comments.' }, + 'msg-fix-applied': { zh: '✅ 已应用修复方案,继续执行...', en: '✅ Fix applied, continuing...' }, + 'msg-fix-apply-failed': { zh: '❌ 应用修复失败', en: '❌ Failed to apply fix' }, + 'msg-fix-skipped': { zh: '⏸ 已跳过修复;该问题会阻断下游,后续阶段已暂停。', en: '⏸ Fix skipped; downstream blocked, later stages paused.' }, + 'msg-generate-or-load-draft-first': { zh: '请先生成或加载草稿', en: 'Please generate or load a draft first' }, + 'msg-history-cleared': { zh: '对话历史已清空', en: 'Chat history cleared' }, + 'msg-id-already-exists': { zh: '该 ID 已存在', en: 'This ID already exists' }, + 'msg-json-loaded-to-console': { zh: 'JSON数据已加载到控制台', en: 'JSON data loaded to console' }, + 'msg-keep-at-least-one-gene': { zh: '至少保留一个 gene ID', en: 'Keep at least one gene ID' }, + 'msg-kg-load-error': { zh: '加载图谱失败', en: 'Failed to load graph' }, + 'msg-kg-loaded': { zh: '知识图谱加载完成', en: 'Knowledge graph loaded' }, + 'msg-load-subgraph-first': { zh: '请先通过问答加载子图,或点击「重新加载」', en: 'Please load a subgraph via Q&A first, or click "Reload"' }, + 'msg-member-table-load-error': { zh: '成员确认表加载失败', en: 'Member confirmation table load failed' }, + 'msg-methodology-plan-saved': { zh: '方法学方案已保存,可先准备数据,稍后再按该方案执行', en: 'Methodology plan saved; prepare data and execute per the plan later' }, + 'msg-msa-fill-alignment': { zh: '请填写MSA alignment 起始列和终止列,或选择其他模式。', en: 'Please fill MSA alignment start/end columns, or select another mode.' }, + 'msg-msa-fill-ref-gene': { zh: '请填写参考基因及其起止残基编号。', en: 'Please fill reference gene and residue start/end numbers.' }, + 'msg-msa-output-label-error': { zh: '无法确定MSA输出标签,请先选择对应图片或填写输出标签。', en: 'Cannot determine MSA output label; select a corresponding image or fill output label first.' }, + 'msg-msa-replot-done': { zh: 'MSA区间重绘完成', en: 'MSA region replot completed' }, + 'msg-msa-replot-error': { zh: 'MSA区间重绘失败', en: 'MSA region replot failed' }, + 'msg-msg-not-saved': { zh: '当前消息未成功写入会话历史,刷新后可能丢失', en: 'Message not saved to session history, may be lost on refresh' }, + 'msg-network-error-retry': { zh: '❌ 网络错误,请重试', en: '❌ Network error, please retry' }, + 'msg-new-session-created': { zh: '新会话已创建,请选择或创建 Working Directory', en: 'New session created, please select or create a Working Directory' }, + 'msg-no-job-id': { zh: '当前没有可用 job_id', en: 'No available job_id' }, + 'msg-no-matching-draft-rows': { zh: '没有匹配的草稿行', en: 'No matching draft rows' }, + 'msg-no-members-filtered': { zh: '当前筛选没有成员,未重建 final_members。', en: 'No members match current filter; final_members not rebuilt.' }, + 'msg-no-subfamily-labels': { zh: '没有可确认的亚家族标签。', en: 'No subfamily labels to confirm.' }, + 'msg-node-not-found': { zh: '未找到匹配的节点', en: 'No matching node found' }, + 'msg-not-advanced-design': { zh: '未生成高级设计', en: 'No advanced design generated' }, + 'msg-path-copied': { zh: '路径已复制', en: 'Path copied' }, + 'msg-plan-request-error': { zh: '规划请求失败', en: 'Planning request failed' }, + 'msg-please-input-content': { zh: '请Input内容', en: 'Please input content' }, + 'msg-pre-publish-validation-passed': { zh: '发布前验收已通过', en: 'Pre-publish validation passed' }, + 'msg-preview-first': { zh: '请先预览要应用的修改', en: 'Please preview the changes first' }, + 'msg-project-restart-not-configured': { zh: '未配置项目重启脚本', en: 'Project restart script not configured' }, + 'msg-project-restart-submitted': { zh: '项目重启脚本已提交', en: 'Project restart script submitted' }, + 'msg-promoter-plot-done': { zh: '启动子自定义绘图完成', en: 'Custom promoter plot completed' }, + 'msg-promoter-plot-error': { zh: '启动子自定义绘图失败', en: 'Custom promoter plot failed' }, + 'msg-promoter-prefix-error': { zh: '无法确定启动子输出前缀。', en: 'Cannot determine promoter output prefix.' }, + 'msg-promoter-read-error': { zh: '读取启动子元件失败', en: 'Failed to read promoter elements' }, + 'msg-promoter-select-element': { zh: '请至少选择一个启动子元件或类别。', en: 'Please select at least one promoter element or category.' }, + 'msg-rag-interpretation-refreshed': { zh: 'RAG解读已刷新', en: 'RAG interpretation refreshed' }, + 'msg-rag-request-error': { zh: 'RAG请求失败', en: 'RAG request failed' }, + 'msg-read-file-error': { zh: '读取文件失败', en: 'Failed to read file' }, + 'msg-replot-in-development': { zh: '重新绘图功能开发中...', en: 'Replot feature in development...' }, + 'msg-request-failed': { zh: '请求失败', en: 'Request failed' }, + 'msg-sandbox-built': { zh: '方法学 sandbox 已构建', en: 'Methodology sandbox built' }, + 'msg-select-actual-job': { zh: '请先选择实际运行 Job。', en: 'Please select an actual running job first.' }, + 'msg-select-executable-stage': { zh: '请至少选择一个可执行的 bbav5 阶段', en: 'Please select at least one executable bbav5 stage' }, + 'msg-select-image-first': { zh: '请先选择一张图片', en: 'Please select an image first' }, + 'msg-select-methodology-dir': { zh: '请先选择或输入 methodology_dir', en: 'Please select or enter methodology_dir' }, + 'msg-select-or-create-wd': { zh: '请先选择或创建 Working Directory', en: 'Please select or create a Working Directory' }, + 'msg-select-pdf-or-mineru': { zh: '请先选择 PDF 或 MinerU content_list JSON 文献文件', en: 'Please select a PDF or MinerU content_list JSON file first' }, + 'msg-select-plot-type': { zh: '请至少选择一种图类型。', en: 'Please select at least one plot type.' }, + 'msg-select-stage-first': { zh: '请先SelectAnalysis Stage', en: 'Please select an analysis stage first' }, + 'msg-select-valid-vcf': { zh: '请先选择有效 VCF', en: 'Please select a valid VCF first' }, + 'msg-session-deleted': { zh: '会话已删除', en: 'Session deleted' }, + 'msg-split-species-no-results': { zh: '当前选择为按物种分别分析,但后端没有返回完整的分物种亚家族结果;将尝试打开可用的联合结果。', en: 'Split-species mode selected but backend returned no per-species subfamily results; trying available combined results.' }, + 'msg-stage-added-to-list': { zh: '已加入正式阶段列表,并默认纳入本次执行', en: 'Added to formal stage list and included in this execution by default' }, + 'msg-stage-already-in-list': { zh: '该阶段已在正式列表中', en: 'This stage is already in the formal list' }, + 'msg-stop-extension-error': { zh: '停止拓展分析失败', en: 'Failed to stop extension analysis' }, + 'msg-stop-extension-requested': { zh: '已请求停止当前拓展分析;状态仍会继续轮询直到进程退出。', en: 'Stop requested for current extension; status will keep polling until process exits.' }, + 'msg-string-link-content': { zh: 'STRING 链接文件内容', en: 'STRING link file content' }, + 'msg-subfamily-confirm-data-error': { zh: '亚家族确认数据加载失败', en: 'Subfamily confirmation data load failed' }, + 'msg-subfamily-confirm-error': { zh: '亚家族确认失败', en: 'Subfamily confirmation failed' }, + 'msg-subfamily-not-auto-open': { zh: '亚家族预测已完成,但未能自动打开确认表;请发送"调出亚家族确认表"手动打开。', en: 'Subfamily prediction completed but confirmation table could not auto-open; send "调出亚家族确认表" to open manually.' }, + 'msg-subfamily-ref-not-written': { zh: '亚家族参考物种未写入当前 job 配置,已生成方法学本地计划,请在批量确认页核对参考物种', en: 'Subfamily reference species not written to current job config; methodology local plan generated; verify reference species on batch confirmation page' }, + 'msg-synteny-output-label-error': { zh: '无法确定种内共线性输出标签,请先选择 Circos 图。', en: 'Cannot determine synteny output label; select a Circos plot first.' }, + 'msg-synteny-replot-done': { zh: '种内共线性 Circos 重绘完成,已切换到新图', en: 'Intraspecific synteny Circos replot completed, switched to new image' }, + 'msg-synteny-replot-error': { zh: '种内共线性 Circos 重绘失败', en: 'Intraspecific synteny Circos replot failed' }, + 'msg-table-read-error': { zh: '读取表格失败', en: 'Failed to read table' }, + 'msg-tree-output-label-error': { zh: '无法确定进化树输出标签,请先选择树图或填写输出标签。', en: 'Cannot determine tree output label; select a tree plot or fill output label first.' }, + 'msg-tree-replot-done': { zh: '进化树图重绘完成,已切换到新图', en: 'Tree replot completed, switched to new image' }, + 'msg-tree-replot-error': { zh: '进化树图重绘失败', en: 'Tree replot failed' }, + 'msg-trial-failed': { zh: '试运行未通过', en: 'Trial run failed' }, + 'msg-trial-succeeded': { zh: '试运行成功', en: 'Trial run succeeded' }, + 'msg-upload-error': { zh: '上传失败', en: 'Upload failed' }, + 'msg-uploaded-build-and-validate': { zh: '文件上传成功,已开始生成并验收', en: 'File uploaded, starting build and validation' }, + 'msg-validation-failed': { zh: '验证未通过', en: 'Validation failed' }, + 'msg-validation-succeeded': { zh: '验证成功', en: 'Validation succeeded' }, + 'msg-view-reset': { zh: '视图已重置', en: 'View reset' }, + 'msg-will-keep-compatible': { zh: '将保留原流程的兼容处理', en: 'Will keep original pipeline compatibility handling' }, + + // === Template string fragments === + 'msg-labels-count': { zh: '个亚家族标签', en: 'subfamily labels' }, + 'msg-loaded-files': { zh: '已加载', en: 'Loaded' }, + 'msg-members-count': { zh: '个成员', en: 'members' }, + 'msg-progress': { zh: '进度', en: 'Progress' }, + 'msg-samples-not-filled': { zh: '个样本未填写', en: 'samples not filled' }, + 'msg-status': { zh: '状态', en: 'Status' }, + 'msg-strand-specificity-required': { zh: '链特异性为必填', en: 'Strand specificity is required' }, + + // === Dialog button text === + 'btn-auto-annotate-continue': { zh: '自动注释并继续', en: 'Auto-annotate & Continue' }, + 'btn-back-to-edit': { zh: '返回修改', en: 'Back to Edit' }, + 'btn-cancel': { zh: '取消', en: 'Cancel' }, + 'btn-cancel-ppi': { zh: '取消 PPI', en: 'Cancel PPI' }, + 'btn-confirm-design-write': { zh: '确认设计并写入', en: 'Confirm Design & Write' }, + 'btn-confirm-first-candidate': { zh: '确认第一候选', en: 'Confirm First Candidate' }, + 'btn-confirm-restart': { zh: '确认重启', en: 'Confirm Restart' }, + 'btn-delete': { zh: '删除', en: 'Delete' }, + 'btn-got-it': { zh: '知道了', en: 'Got it' }, + 'btn-retry-bcftools': { zh: '使用 bcftools 重试', en: 'Retry with bcftools' }, + 'btn-upload-bg-first': { zh: '我先去上传背景文件', en: 'Upload Background Files First' }, + + // === Template labels === + 'label-added': { zh: '新增', en: 'Added' }, + 'label-conserved-msa': { zh: '自动保守区 MSA 图', en: 'Auto Conserved MSA Plot' }, + + // === Category & node labels === + 'category-gene-family': { zh: '基因家族', en: 'Gene Family' }, + 'category-wgs-population-gwas': { zh: 'WGS2GWAS(遗传变异与群体分析)', en: 'WGS2GWAS (Genetic Variation & Population)' }, + 'label-current-identification': { zh: '当前鉴定', en: 'Current Identification' }, + 'label-current-image': { zh: '当前图片', en: 'Current Image' }, + 'label-degree': { zh: '连接数', en: 'Degree' }, + 'label-deleted': { zh: '删除', en: 'Deleted' }, + 'label-edges': { zh: '关系', en: 'Edges' }, + 'label-input': { zh: '输入', en: 'Input' }, + 'label-msa-region': { zh: 'MSA区间图', en: 'MSA Region Plot' }, + 'label-msa-source': { zh: 'MSA来源', en: 'MSA Source' }, + 'label-nodes': { zh: '节点', en: 'Nodes' }, + 'label-ppi-reset': { zh: 'PPI Reset 结果', en: 'PPI Reset Results' }, + 'label-recommended-conserved': { zh: '推荐保守区', en: 'Recommended Conserved Region' }, + 'label-types': { zh: '类型', en: 'Types' }, + + // === Stage labels === + 'stage-combo': { zh: '组合图', en: 'Combined Plot' }, + 'stage-domain': { zh: '结构域分析', en: 'Domain Analysis' }, + 'stage-expression': { zh: '表达矩阵分析', en: 'Expression Matrix Analysis' }, + 'stage-gwas-cov': { zh: 'GWAS协变量准备', en: 'GWAS Covariate Preparation' }, + 'stage-gwas-emmax': { zh: 'GWAS EMMAX', en: 'GWAS EMMAX' }, + 'stage-gwas-emplot': { zh: 'GWAS EMMAX绘图', en: 'GWAS EMMAX Plotting' }, + 'stage-gwas-fmt': { zh: 'GWAS VCF排序与HapMap转换', en: 'GWAS VCF Sort & HapMap Conversion' }, + 'stage-gwas-glm': { zh: 'GWAS TASSEL GLM', en: 'GWAS TASSEL GLM' }, + 'stage-gwas-kinship': { zh: 'GWAS TASSEL亲缘关系矩阵', en: 'GWAS TASSEL Kinship Matrix' }, + 'stage-gwas-mlm': { zh: 'GWAS TASSEL MLM/CMLM', en: 'GWAS TASSEL MLM/CMLM' }, + 'stage-gwas-plot': { zh: 'GWAS MLM/CMLM绘图', en: 'GWAS MLM/CMLM Plotting' }, + 'stage-gwas-trait': { zh: 'GWAS表型准备', en: 'GWAS Trait Preparation' }, + 'stage-identify': { zh: '基因家族鉴定', en: 'Gene Family Identification' }, + 'stage-interspecies-synteny': { zh: '种间共线性分析', en: 'Interspecies Synteny Analysis' }, + 'stage-kaks': { zh: 'Ka/Ks分析', en: 'Ka/Ks Analysis' }, + 'stage-karyotype': { zh: '核型/染色体分布分析', en: 'Karyotype Analysis' }, + 'stage-motif': { zh: 'Motif分析', en: 'Motif Analysis' }, + 'stage-pep': { zh: '蛋白理化性质与亚细胞定位', en: 'Protein Properties & Subcellular Localization' }, + 'stage-phylogeny': { zh: '系统发育分析', en: 'Phylogenetic Analysis' }, + 'stage-pop-ld-decay': { zh: '群体LD衰减分析', en: 'Population LD Decay Analysis' }, + 'stage-pop-pca': { zh: '群体PCA分析', en: 'Population PCA Analysis' }, + 'stage-pop-phylogeny': { zh: '群体系统树分析', en: 'Population Phylogenetic Tree' }, + 'stage-pop-snp-density': { zh: 'SNP密度分析', en: 'SNP Density Analysis' }, + 'stage-pop-structure': { zh: '群体结构分析', en: 'Population Structure Analysis' }, + 'stage-ppi': { zh: 'PPI分析', en: 'PPI Analysis' }, + 'stage-ppi-kaks-download-fallback': { zh: 'PPI/KaKs 兜底确认', en: 'PPI/KaKs Fallback Confirmation' }, + 'stage-ppi-kaks-reference-data': { zh: 'PPI/KaKs 参考数据', en: 'PPI/KaKs Reference Data' }, + 'stage-promoter': { zh: '启动子元件预测', en: 'Promoter Element Prediction' }, + 'stage-reference-classification': { zh: '参考亚家族分类', en: 'Reference Subfamily Classification' }, + 'stage-structure': { zh: '基因结构分析', en: 'Gene Structure Analysis' }, + 'stage-subfamily-confirm': { zh: '亚家族标签确认', en: 'Subfamily Label Confirmation' }, + 'stage-synteny': { zh: '种内共线性分析', en: 'Intraspecific Synteny Analysis' }, + 'stage-tfbs': { zh: 'TF结合位点预测', en: 'TFBS Prediction' }, + + // === Short stage labels === + 'stage-interspecies-synteny-short': { zh: '9️⃣ 种间Synteny', en: '9️⃣ Interspecies Synteny' }, + 'stage-msa-region-plot': { zh: '2.2 MSA Replot / 区间重绘', en: '2.2 MSA Replot / Region Plot' }, + 'stage-promoter-plot-revise': { zh: '6.1 启动子自定义绘图', en: '6.1 Custom Promoter Plot' }, + 'stage-reference-classification-short': { zh: '2.5 亚家族确认', en: '2.5 Subfamily Confirmation' }, + 'stage-synteny-plot-revise': { zh: '7.1 种内共线性 Circos 重绘', en: '7.1 Intraspecies Synteny Circos Replot' }, + 'stage-synteny-short': { zh: '7️⃣ 种内Synteny', en: '7️⃣ Intraspecies Synteny' }, + 'stage-tree-plot-revise': { zh: '2.3 Tree Replot / 进化树重绘', en: '2.3 Tree Replot' }, + + // === Synteny choice labels === + 'choice-synteny': { zh: '种内共线性分析', en: 'Intraspecific Synteny Analysis' }, + 'choice-synteny-desc': { zh: '只分析目标物种内部复制关系', en: 'Analyze duplication within target species only' }, + 'choice-interspecies-synteny': { zh: '种间共线性分析', en: 'Interspecies Synteny Analysis' }, + 'choice-interspecies-synteny-desc': { zh: '分析目标物种与参考/比较物种之间的共线性', en: 'Analyze synteny between target and reference/comparative species' }, + + // === Sidebar status labels === + 'status-pending-confirm': { zh: '待确认', en: 'Pending Confirm' }, + 'status-running': { zh: '运行中', en: 'Running' }, + 'status-pending-exec': { zh: '待执行', en: 'Pending' }, + 'status-pending-review': { zh: '待核对', en: 'Pending Review' }, + 'status-pending-auth': { zh: '待授权', en: 'Pending Auth' }, + 'status-completed': { zh: '已完成', en: 'Completed' }, + + // === Lightweight card titles === + 'card-title-extension-candidate': { zh: '拓展分析候选核对', en: 'Extension Candidate Review' }, + 'card-title-generating-extension': { zh: '正在生成拓展分析', en: 'Generating Extension' }, + 'card-title-start-validation': { zh: '开始验证', en: 'Start Validation' }, + 'card-title-result-review': { zh: '运行结果核对', en: 'Result Review' }, + 'card-title-auth-publish': { zh: '授权发布', en: 'Authorize Publish' }, + 'card-title-input-files': { zh: '输入文件和参数', en: 'Input Files & Parameters' }, + 'card-title-run-result': { zh: '运行结果', en: 'Run Result' }, + 'card-title-restoring-extension': { zh: '正在恢复拓展分析状态', en: 'Restoring Extension State' }, + + // === More status labels === + 'card-title-extension-gen-failed': { zh: '拓展分析说明生成失败', en: 'Extension Description Generation Failed' }, + 'status-cancelled': { zh: '已取消', en: 'Cancelled' }, + 'status-failed': { zh: '失败', en: 'Failed' }, + + // === Species label === + 'label-multi-species-analysis': { zh: '多物种联合分析与确认(默认)', en: 'Multi-Species Joint Analysis (default)' }, + 'label-per-species-analysis': { zh: '按单个物种分别分析与确认', en: 'Per-Species Analysis & Confirmation' }, + 'label-target-only': { zh: '仅目标物种', en: 'Target Species Only' }, + + // === More visible labels === + 'desc-smart-extract': { zh: '如果没有蛋白文件,但有 genome.fa + GFF,系统会自动用 gffread 提取蛋白序列', en: 'If no protein file is available but genome.fa + GFF exist, the system will automatically extract protein sequences using gffread' }, + 'label-batch': { zh: '批次', en: 'Batch' }, + 'label-smart-extract': { zh: '智能提取', en: 'Smart Extract' }, + 'label-view-phase-report': { zh: '查看阶段性综合报告', en: 'View Phase Summary Report' }, + + + // === Target species === + 'label-target-species': { zh: '目标物种', en: 'Target Species' }, + 'msg-target-cannot-string': { zh: '目标物种当前不能直接用于 STRING PPI/KaKs。', en: 'Target species cannot be used directly for STRING PPI/KaKs.' }, + 'msg-target-not-in-string': { zh: '目标物种不在 STRING 固定快照中。请确认是否采用排序第一的近源物种:', en: 'Target species not in STRING fixed snapshot. Confirm using the closest related species:' }, + 'msg-methodology-plan-saved-detail': { zh: '已保存方法学方案到当前 job。下一步请上传/填写目标物种和参考物种数据,并确认 config.xlsx 后再执行方法学流程。', en: 'Methodology plan saved to current job. Next: upload/fill target and reference species data, verify config.xlsx, then execute the methodology pipeline.' }, + + // === json list tables === + 'json-list-tables': { zh: 'json list tables', en: 'JSON List Tables' }, + + // === Methodology labels === + 'label-auto-review': { zh: '自动审核', en: 'Auto Review' }, + 'label-missing': { zh: '缺少', en: 'Missing' }, + 'label-missing-fig': { zh: '缺失 Fig', en: 'Missing Fig' }, + 'label-missing-table': { zh: '缺失 Table', en: 'Missing Table' }, + 'label-stage-count': { zh: '阶段', en: 'Stages' }, + 'label-title-count': { zh: '标题', en: 'Titles' }, + 'unit-figure-titles': { zh: '条图表标题', en: 'figure titles' }, + 'unit-preview-stages': { zh: '个预览阶段', en: 'preview stages' }, + 'unit-species': { zh: '个物种', en: 'species' }, + 'unit-stages': { zh: '个方法阶段', en: 'methodology stages' }, + + // === getStageI18nKey mappings === + '0-genome-prepare': { zh: '0️⃣ Genome Prepare', en: '0️⃣ Genome Prepare' }, + '1-identify': { zh: '1️⃣ Identify', en: '1️⃣ Identify' }, + '1.1-identify-refine': { zh: '1.1 Identify Refine', en: '1.1 Identify Refine' }, + '10-ppi': { zh: '🔟 PPI', en: '🔟 PPI' }, + '11-kaks': { zh: '1️⃣1️⃣ KaKs', en: '1️⃣1️⃣ KaKs' }, + '12-pep': { zh: '1️⃣2️⃣ PEP', en: '1️⃣2️⃣ PEP' }, + '13-expression': { zh: '1️⃣3️⃣ Expression (FPKM)', en: '1️⃣3️⃣ Expression (FPKM)' }, + '2-phylogeny-tree': { zh: '2️⃣ Phylogeny Tree', en: '2️⃣ Phylogeny Tree' }, + '2.1-msa-alignment': { zh: '2.1 MSA Alignment Pages', en: '2.1 MSA Alignment Pages' }, + '20-Annotation': { zh: '2️⃣0️⃣ Annotation', en: '2️⃣0️⃣ Annotation' }, + '3-motif': { zh: '3️⃣ Motif', en: '3️⃣ Motif' }, + '4-domain': { zh: '4️⃣ Domain', en: '4️⃣ Domain' }, + '5-structure': { zh: '5️⃣ Structure', en: '5️⃣ Structure' }, + '6-combo': { zh: '6️⃣ Combo', en: '6️⃣ Combo' }, + '6-promoter': { zh: '6️⃣ Promoter', en: '6️⃣ Promoter' }, + '6.2-tfbs': { zh: '6.2 TFBS', en: '6.2 TFBS' }, + '8-karyotype': { zh: '8️⃣ Karyotype', en: '8️⃣ Karyotype' }, + 'GWAS-Cov': { zh: 'GWAS Covariate Preparation', en: 'GWAS Covariate Preparation' }, + 'GWAS-EMMAX': { zh: 'GWAS EMMAX', en: 'GWAS EMMAX' }, + 'GWAS-EMPlot': { zh: 'GWAS EMMAX Plot', en: 'GWAS EMMAX Plot' }, + 'GWAS-Format': { zh: 'GWAS Format (TASSEL)', en: 'GWAS Format (TASSEL)' }, + 'GWAS-GLM': { zh: 'GWAS TASSEL GLM', en: 'GWAS TASSEL GLM' }, + 'GWAS-Kinship': { zh: 'GWAS Kinship (TASSEL)', en: 'GWAS Kinship (TASSEL)' }, + 'GWAS-MLM': { zh: 'GWAS TASSEL MLM/CMLM', en: 'GWAS TASSEL MLM/CMLM' }, + 'GWAS-Plot': { zh: 'GWAS MLM/CMLM Plot', en: 'GWAS MLM/CMLM Plot' }, + 'GWAS-Trait': { zh: 'GWAS Trait Preparation', en: 'GWAS Trait Preparation' }, + 'PPI-KaKs-Fallback': { zh: 'PPI/KaKs 兜底确认', en: 'PPI/KaKs Fallback Confirmation' }, + 'PPI-KaKs-Ref': { zh: 'PPI/KaKs 参考数据', en: 'PPI/KaKs Reference Data' }, + 'RNA-seq-Align': { zh: '1️⃣6️⃣ RNA-seq Align', en: '1️⃣6️⃣ RNA-seq Align' }, + 'RNA-seq-Candidate': { zh: '2️⃣5️⃣ RNA-seq Candidate Family', en: '2️⃣5️⃣ RNA-seq Candidate Family' }, + 'RNA-seq-DE': { zh: '1️⃣9️⃣ RNA-seq DE + Expression', en: '1️⃣9️⃣ RNA-seq DE + Expression' }, + 'RNA-seq-GO': { zh: '2️⃣1️⃣ RNA-seq GO Enrich', en: '2️⃣1️⃣ RNA-seq GO Enrich' }, + 'RNA-seq-KEGG': { zh: '2️⃣2️⃣ RNA-seq KEGG Enrich', en: '2️⃣2️⃣ RNA-seq KEGG Enrich' }, + 'RNA-seq-QC': { zh: '1️⃣5️⃣ RNA-seq QC', en: '1️⃣5️⃣ RNA-seq QC' }, + 'RNA-seq-Quant': { zh: '1️⃣7️⃣ RNA-seq Quant', en: '1️⃣7️⃣ RNA-seq Quant' }, + 'RNA-seq-Sample-QC': { zh: '1️⃣8️⃣ RNA-seq Sample QC', en: '1️⃣8️⃣ RNA-seq Sample QC' }, + 'RNA-seq-WGCNA': { zh: '2️⃣4️⃣ RNA-seq WGCNA', en: '2️⃣4️⃣ RNA-seq WGCNA' }, + 'RNA-seq-fgsea': { zh: '2️⃣3️⃣ RNA-seq fgsea', en: '2️⃣3️⃣ RNA-seq fgsea' }, + 'WGS-Align': { zh: 'WGS Alignment', en: 'WGS Alignment' }, + 'WGS-BAM-QC': { zh: 'WGS BAM QC', en: 'WGS BAM QC' }, + 'WGS-GVCF': { zh: 'WGS GVCF Combine', en: 'WGS GVCF Combine' }, + 'WGS-Haplotype': { zh: 'WGS Haplotype Calling', en: 'WGS Haplotype Calling' }, + 'WGS-Impute': { zh: 'WGS Imputation', en: 'WGS Imputation' }, + 'WGS-Index': { zh: 'WGS Reference Index', en: 'WGS Reference Index' }, + 'WGS-Joint-Geno': { zh: 'WGS Joint Genotyping', en: 'WGS Joint Genotyping' }, + 'WGS-MAF': { zh: 'WGS MAF / Missing Filter', en: 'WGS MAF / Missing Filter' }, + 'WGS-MarkDup': { zh: 'WGS Mark Duplicates', en: 'WGS Mark Duplicates' }, + 'WGS-QC': { zh: 'WGS QC', en: 'WGS QC' }, + 'WGS-Var-Filter': { zh: 'WGS Variant Filter', en: 'WGS Variant Filter' }, + 'WGS-Var-Select': { zh: 'WGS Variant Select', en: 'WGS Variant Select' }, + 'pop-ld-decay': { zh: 'Population LD Decay', en: 'Population LD Decay' }, + 'pop-pca': { zh: 'Population PCA', en: 'Population PCA' }, + 'pop-phylogeny': { zh: 'Population Phylogeny', en: 'Population Phylogeny' }, + 'pop-snp-density': { zh: 'SNP Density', en: 'SNP Density' }, + 'pop-structure': { zh: 'Population Structure', en: 'Population Structure' }, + + // === Countdown labels === + 'countdown-paused': { zh: '倒计时已暂停', en: 'Countdown paused' }, + 'seconds-auto-annotate': { zh: '秒后自动注释', en: 's to auto-annotate' }, + 'seconds-auto-domain-review': { zh: '秒后自动使用默认结构域筛选', en: 's to auto-use default domain filter' }, + 'seconds-auto-execute': { zh: '秒后自动执行', en: 's to auto-execute' }, + 'seconds-auto-stage-confirm': { zh: '秒后自动执行', en: 's to auto-execute' }, + 'seconds-auto-subfamily-review': { zh: '秒后自动确认当前亚家族标签', en: 's to auto-confirm subfamily labels' }, +}; diff --git a/apps/web/vue3/static/i18n_en.js b/apps/web/vue3/static/i18n_en.js new file mode 100644 index 000000000..416f57655 --- /dev/null +++ b/apps/web/vue3/static/i18n_en.js @@ -0,0 +1,380 @@ +window.__I18N_EN__ = { + "Agent状态": "AgentStatus", + "Self-RAG反思": "Self-RAG Reflection", + "三角形": "Triangle", + "下一步": "Next Step", + "下载": "Download", + "不受支持标记处理策略": "Unsupported Marker Handling Policy", + "中性替换率": "Neutral Substitution Rate", + "中性速率": "Neutral Rate", + "中文": "Chinese", + "丰度引擎": "Abundance Engine", + "主参考": "Primary Reference", + "主参考物种": "Primary reference species", + "主要结果": "Main Results", + "亚家族分类确认": "Subfamily Classification Confirmation", + "亚家族名称距离": "Subfamily Name Distance", + "亚家族外圈弧线": "Subfamily Outer Arc", + "亚家族确认参数": "Subfamily Confirmation Parameters", + "交集": "Intersection", + "仅圈图": "Circle Plot Only", + "仅比较物种": "Comparative Species Only", + "仅目标": "Target Only", + "仅目标物种": "Target Species Only", + "仅矩形图": "Rectangular Only", + "任务列表": "Task List", + "位置分布图": "Position Distribution Map", + "使用拟南芥作为显式兜底": "Use Arabidopsis as Explicit Fallback", + "使用推荐区间": "Use Recommended Range", + "保存方法学方案": "Save Methodology Plan", + "保留": "Retain", + "修订": "Revision", + "倒计时已暂停": "Countdown paused", + "全屏": "Full Screen", + "全屏展示": "Full Screen Display", + "全部": "All", + "全部行": "All Rows", + "关系总数": "Total Edges", + "关闭": "Close", + "内容": "Content", + "内置物种代码": "Built-in Species Code", + "分析家族": "Analysis Family", + "分组角色": "Group Role", + "分组角色不改": "Group Role (Unchanged)", + "删除": "Deleted", + "删除会话": "Delete Session", + "刷新": "Refresh", + "刷新结果": "Refresh Results", + "前景基因": "Foreground Genes", + "功能类别": "Feature Category", + "加入正式列表": "Add to Formal List", + "包含关键词": "Contains Keyword", + "匹配方式": "Match Mode", + "匹配行": "Matched Rows", + "原因": "Reason", + "原始代码": "Original Code", + "原始命令": "Original Command", + "原始文件名": "Original Filename", + "原始证据": "Original Evidence", + "原推荐参考": "Original Recommended Reference", + "参数": "Parameters", + "参考分类": "Reference Classification", + "参考前缀": "Reference Prefix", + "参考基因": "Reference Gene", + "参考基因编号": "Reference Gene ID", + "参考文献": "References", + "参考物种": "Reference Species", + "发送": "Send", + "取消": "Cancel", + "取消预览": "Cancel Preview", + "只会执行已勾选且可执行的阶段": "Only checked and executable stages will run", + "可改": "Editable", + "同时处理的样本数": "Number of Samples Processed Simultaneously", + "名称": "Name", + "后续主参考物种": "Downstream Primary Reference Species", + "启动子元件": "Promoter Elements", + "启动子自定义绘图": "Promoter Custom Plot", + "图例颜色": "Legend Color", + "图类型": "Plot Type", + "图表标题清单": "Chart Title List", + "图表标题驱动复现规划预览": "Chart Title-Driven Reproduction Plan Preview", + "圆形": "Circle", + "基因注释": "Gene Annotation", + "基本参数": "Basic Parameters", + "基础参数": "Basic Parameters", + "处理中...": "Processing...", + "处理方式": "Processing Method", + "多物种处理方式": "Multi-species Processing", + "大小": "Size", + "定量模式": "Quantification Mode", + "实验设计": "Experimental Design", + "实验设计模块": "Experimental Design Module", + "审核备注": "Review Notes", + "富集类型": "Enrichment Type", + "差异表达范围": "Differential Expression Scope", + "已写阶段": "Registered Stages", + "已完成": "Completed", + "已完成阶段": "Completed Stages", + "已应用": "Applied", + "建议参数": "Suggested Parameters", + "开始验证": "Start Validation", + "弧线避让距离": "Arc Avoidance Distance", + "当前参数": "Current Parameters", + "当前参考物种": "Current Reference Species", + "当前选择": "Current Selection", + "待补数据": "Awaiting Data", + "必填": "Required", + "我知道了": "Got It", + "手动区间": "Manual Range", + "执行": "Execute", + "扫描双链": "Scan Both Strands", + "批量执行确认": "Batch Execution Confirmation", + "拉丁名": "Latin Name", + "拓展分析运行参数确认": "Extension Analysis Run Parameter Confirmation", + "拓展分析阶段": "Extension Analysis Stage", + "拓展分析阶段状态": "Extension Analysis Stage Status", + "拓展分析阶段确认": "Extension Analysis Stage Confirmation", + "拓展分析阶段运行结果": "Extension Analysis Stage Run Result", + "按元件": "By Element", + "按单个物种分别分析与确认": "Per-Species Analysis & Confirmation", + "按当前筛选重建成员蛋白": "Rebuild Member Proteins by Current Filter", + "按类别": "By Category", + "授权发布": "Authorize Publish", + "推荐参考数据下载失败": "Recommended Ref Data Download Failed", + "提出修订意见": "Submit Revision Suggestions", + "操作": "Operation", + "数据准备": "Data Preparation", + "数据路径": "Data Path", + "数据需求": "Data Needs", + "文件": "File", + "文件类型": "File Type", + "文件范围": "File Scope", + "文献参数": "Literature Parameters", + "文献工具": "Literature Tools", + "文章涉及物种与下载入口": "Article Species & Download Entry", + "新增": "Added", + "方形": "Square", + "方法参考": "Method Reference", + "方法学文献": "Methodology Papers", + "无": "None", + "明确指定": "Explicitly Specify", + "显示": "Show", + "暂停倒计时": "Pause Countdown", + "暂无已上传文件": "No Uploaded Files Yet", + "暂无拓展分析阶段结果": "No Extension Analysis Stage Results Yet", + "暂无状态记录": "No Status Record Yet", + "最大宽度": "Max Width", + "最小宽度": "Min Width", + "最小非缺口比例": "Min Non-gap Ratio", + "最近到属": "Closest to Genus", + "最近到目": "Closest to Order", + "最近到科": "Closest to Family", + "最近到纲": "Closest to Class", + "有损转换警告": "Lossy Conversion Warning", + "服务器测试数据路径": "Server Test Data Path", + "未从图表标题推断出额外阶段": "No Additional Stages Inferred from Chart Titles", + "未提取到图表标题": "No Chart Title Extracted", + "未识别到内置下载链接": "No Built-in DL Link Identified", + "未识别到参数": "No Parameters Identified", + "未识别到文献工具": "No Literature Tool Identified", + "本次成员鉴定物种": "Current Member Identification Species", + "来源": "Sources", + "染色体标注位置": "Chromosome Annotation Position", + "染色体标注大小": "Chromosome Annotation Size", + "染色体策略": "Chromosome Strategy", + "染色体色块粗细": "Chromosome Block Width", + "查看本次知识检索过程": "View knowledge retrieval process", + "标记大小": "Mark Size", + "标记模式": "Mark Mode", + "标题推断的候选阶段": "Candidate Stages Inferred from Titles", + "树枝粗细": "Branch Width", + "树枝颜色": "Branch Color", + "样本并行数量": "Sample Parallel Count", + "检索结果": "Retrieval Results", + "检索表格内容": "Search Table Content", + "正则匹配": "Regex Match", + "此拓展阶段没有可配置参数": "No Configurable Parameters", + "测试数据": "Test Data", + "涉及阶段": "Involved Stages", + "添加行": "Add Row", + "灰色": "Gray", + "物种": "Species", + "物种代码": "Species Code", + "物种代码不改": "Species Code (Unchanged)", + "物种名": "Species Name", + "物种角色": "Species Role", + "物种角色不改": "Species Role (Unchanged)", + "环境": "Environment", + "留空则自动发现": "Leave empty for auto-discovery", + "目标前缀": "Target Prefix", + "目标物种": "Target Species", + "知识图谱": "Knowledge Graph", + "确定": "Confirm", + "确认亚家族标签": "Confirm Subfamily Labels", + "确认保存": "Confirm Save", + "确认并写入正式配置": "Confirm & Write to Official Config", + "确认并执行": "Confirm & Execute", + "确认执行": "Confirm Execution", + "确认自动注释": "Confirm Auto-Annotation", + "确认重绘": "Confirm Replot", + "种间共线性比较物种": "Interspecies Synteny Comparative Species", + "种间共线性绘图设置": "Interspecies Synteny Plot Settings", + "移除": "Remove", + "窗口长度": "Window Length", + "类型": "Types", + "精确匹配": "Exact Match", + "红色": "Red", + "终止位点": "End Site", + "终止残基": "End Residue", + "绘图模式": "Plot Mode", + "绿色": "Green", + "置信度": "Confidence", + "置信度阈值": "Confidence Threshold", + "群体遗传输入": "Population Genetic Input", + "背景来源": "Background Source", + "背景知识": "Background knowledge", + "自动": "Auto", + "自动从注释提取": "Auto-extract from Annotation", + "自动保守窗口": "Auto Conserved Window", + "自动判断": "Auto-detect", + "节点名称": "Node Name", + "节点总数": "Total Nodes", + "节点类型": "Node Types", + "菱形": "Diamond", + "蓝色": "Blue", + "蛋白": "Protein", + "蛋白文件": "Protein Files", + "表达矩阵": "Expression Matrix", + "诊断动作": "Diagnostic Actions", + "说明": "Description", + "请先试运行以记录真实输出": "Please Run a Trial First to Record Actual Output", + "请选择共线性分析类型": "Please select synteny analysis type", + "请选择模式物种": "Select Model Species", + "起始位点": "Start Site", + "起始残基": "Start Residue", + "跳数": "Hops", + "输出": "Output", + "输出前缀": "Output Prefix", + "输出标签": "Output Label", + "运行值": "Run Value", + "运行结果": "Run Result", + "进化树图修订参数": "Phylogenetic Tree Revision Parameters", + "连接关系数": "Connections", + "迭代": "Iteration", + "选择其他提取结果": "Select Other Extraction Result", + "选择工具": "Select Tool", + "选择已完成撰写的拓展阶段": "Select Completed Extension Stage", + "通常留空": "Usually leave empty", + "重写查询": "Rewrite Query", + "重新生成说明": "Regenerate Description", + "重置": "Reset", + "重置视图": "Reset View", + "链接": "Link", + "链特异性": "Library Strandedness", + "隐藏": "Hide", + "需检查": "Needs Review", + "需要补充": "Need to Supplement", + "非时间实验留空": "Leave empty for non-time experiments", + "项目": "Project", + "预览": "Preview", + "预览到表格": "Preview to Table", + "预览命令": "Preview Commands", + "黑色": "Black", + "默认值": "Default Value", + "提取方法学": "Extract", + "刷新记录": "Refresh", + "打开最新提取结果": "Open Latest Extraction", + "查看最新提取状态": "View Latest Status", + "打开所选提取结果": "Open Selected Extraction", + "查看所选提取状态": "View Selected Status", + "生成并发布": "Generate & Publish", + "运行已发布": "Run Published", + "当前会话": "Current Session", + "更多会话": "More Sessions", + "新建": "New", + "新建会话": "New Session", + "使用小Tip": "Tips", + "一、分析模块快速指令": "1. Analysis Module Quick Commands", + "选择输入框上方\"Analysis\"": "Select \"Analysis\" above input box", + "粘贴数据位置": "Paste data location", + "核对配置文件": "Review config files", + "执行数据准备": "Run data preparation", + "执行XX物种的亚家族分类": "Run subfamily classification for XX species", + "执行XX物种的基因家族分析": "Run gene family analysis for XX species", + "执行rnaseq分析": "Run RNA-seq analysis", + "二、文章复现步骤": "2. Article Reproduction Steps", + "点击\"浏览\"上传文献": "Click \"Browse\" to upload paper", + "点击提取方法学": "Click Extract Methodology", + "核对分析步骤": "Review analysis steps", + "点击保存方案": "Click Save Plan", + "上传数据": "Upload data", + "发送\"按已保存的方法学方案继续执行\"": "Send \"Continue with saved methodology plan\"", + "三、RAG快速指令": "3. RAG Quick Commands", + "选择输入框上方\"RAG\"": "Select \"RAG\" above input box", + "输入问题": "Enter question", + "点击\"知识图谱\"查看关系": "Click \"Knowledge Graph\" to view relations", + "知识图谱": "Knowledge Graph", + "重新加载": "Reload", + "重置视图": "Reset View", + "2.2 MSA Replot / 区间重绘": "2.2 MSA Replot", + "2.3 Tree Replot / 进化树重绘": "2.3 Tree Replot", + "2.5 亚家族确认": "2.5 Subfamily Confirmation", + "6.1 启动子自定义绘图": "6.1 Promoter Custom Plot", + "7️⃣ 种内Synteny": "7️⃣ Intraspecies Synteny", + "7.1 种内共线性 Circos 重绘": "7.1 Intraspecies Synteny Circos Replot", + "8️⃣ Karyotype": "8️⃣ Karyotype", + "9️⃣ 种间Synteny": "9️⃣ Interspecies Synteny", + "基因家族": "Gene Family", + "WGS2GWAS(遗传变异与群体分析)": "WGS2GWAS", + "基因家族 promoter 扫描": "Gene family promoter scanning", + "新会话": "New Session", + "新会话已创建,请选择或创建 Working Directory": "New session created. Please select or create a Working Directory", + "创建会话失败": "Failed to create session", + "会话已删除": "Session deleted", + "删除会话失败": "Failed to delete session", + "对话历史已清空": "Chat history cleared", + "错误日志已清空": "Error logs cleared", + "重启 Celery": "Restart Celery", + "重启项目": "Restart Project", + "提交配置好的项目重启脚本": "Submit configured project restart script", + "未配置 PLANTAI_RESTART_SCRIPT 或 restart_plantai_9000.sh": "PLANTAI_RESTART_SCRIPT or restart_plantai_9000.sh not configured", + "未配置项目重启脚本": "Project restart script not configured", + "这会提交项目重启脚本,当前页面可能短暂断开。": "This will submit the project restart script. The page may briefly disconnect.", + "确认重启": "Confirm Restart", + "项目重启脚本已提交": "Project restart script submitted", + "项目重启未提交": "Project restart not submitted", + "基因家族鉴定": "Gene Family Identification", + "系统发育分析": "Phylogenetic Analysis", + "Motif分析": "Motif Analysis", + "结构域分析": "Domain Analysis", + "基因结构分析": "Gene Structure Analysis", + "启动子元件预测": "Promoter Element Prediction", + "TF结合位点预测": "TF Binding Site Prediction", + "种内共线性分析": "Intraspecies Synteny Analysis", + "种间共线性分析": "Interspecies Synteny Analysis", + "核型/染色体分布分析": "Karyotype/Chromosome Distribution", + "PPI分析": "PPI Analysis", + "Ka/Ks分析": "Ka/Ks Analysis", + "蛋白理化性质与亚细胞定位": "Protein Properties & Subcellular Localization", + "表达矩阵分析": "Expression Matrix Analysis", + "RNA-seq QC": "RNA-seq QC", + "RNA-seq Align": "RNA-seq Align", + "RNA-seq Quant": "RNA-seq Quant", + "RNA-seq Sample QC": "RNA-seq Sample QC", + "GWAS VCF排序与HapMap转换": "GWAS VCF Sort & HapMap Conversion", + "GWAS TASSEL亲缘关系矩阵": "GWAS TASSEL Kinship Matrix", + "GWAS表型准备": "GWAS Phenotype Preparation", + "GWAS协变量准备": "GWAS Covariate Preparation", + "GWAS TASSEL MLM/CMLM": "GWAS TASSEL MLM/CMLM", + "GWAS MLM/CMLM绘图": "GWAS MLM/CMLM Plotting", + "GWAS EMMAX": "GWAS EMMAX", + "GWAS EMMAX绘图": "GWAS EMMAX Plotting", + "GWAS TASSEL GLM": "GWAS TASSEL GLM", + "群体PCA分析": "Population PCA Analysis", + "群体系统树分析": "Population Phylogenetic Tree", + "群体结构分析": "Population Structure Analysis", + "群体LD衰减分析": "Population LD Decay Analysis", + "SNP密度分析": "SNP Density Analysis", + "RNA-seq DE": "RNA-seq DE", + "组合图": "Combo Plot", + "参考亚家族分类": "Reference Subfamily Classification", + "亚家族标签确认": "Subfamily Label Confirmation", + "PPI/KaKs 参考数据": "PPI/KaKs Reference Data", + "PPI/KaKs 兜底确认": "PPI/KaKs Fallback Confirmation", + "亚家族确认输出": "Subfamily Confirmation Output", + "MSA区间重绘": "MSA Region Replot", + "MSA区间重绘已提交": "MSA Replot submitted", + "MSA区间重绘完成": "MSA Replot completed", + "MSA区间重绘失败": "MSA Replot failed", + "启动子自定义绘图已提交": "Promoter custom plot submitted", + "启动子自定义绘图完成": "Promoter custom plot completed", + "启动子自定义绘图失败": "Promoter custom plot failed", + "种内共线性 Circos 重绘已提交": "Intraspecies Circos replot submitted", + "种内共线性 Circos 重绘完成,已切换到新图": "Intraspecies Circos replot completed, switched to new figure", + "种内共线性 Circos 重绘失败": "Intraspecies Circos replot failed", + "亚家族确认 - Reference Classification": "Subfamily Confirmation - Reference Classification", + "这会停止当前 profile 的 Celery worker 并重新启动。若有任务正在运行,后端会默认拒绝执行。": "This will stop and restart the Celery worker for the current profile. Running tasks will be rejected by default.", + "Celery 已重启并完成队列检查": "Celery restarted and queue check complete", + "Celery 重启未完成": "Celery restart incomplete" +}; + diff --git a/gfa_core/extension_stage_lightweight/api.py b/gfa_core/extension_stage_lightweight/api.py index 09e5927c4..54927cdce 100644 --- a/gfa_core/extension_stage_lightweight/api.py +++ b/gfa_core/extension_stage_lightweight/api.py @@ -361,6 +361,7 @@ def execute_queued_operation(payload: dict[str, Any]) -> dict[str, Any]: settings = LightweightApiSettings.from_environment() action = str(payload["action"]) + runtime_env = str(payload.get("runtime_env", "test4py311")) extension_id = _safe_component(str(payload["extension_id"]), name="extension_id") token = _safe_component(str(payload["operation_token"]), name="operation_token") _set_receipt(settings, token, state="running", status="running") @@ -373,6 +374,7 @@ def execute_queued_operation(payload: dict[str, Any]) -> dict[str, Any]: raw_code=stage / "raw_code", raw_data=stage / "raw_test_data", original_command=str(payload["original_command"]), + runtime_env=runtime_env, operation_token=token, ) elif action == "rebuild": @@ -479,6 +481,7 @@ def create_lightweight_extension_router( raw_code_files: list[UploadFile] | None = File(None), raw_data_files: list[UploadFile] | None = File(None), raw_data_paths: str | None = Form(None), + runtime_env: str = Form("test4py311"), ) -> dict[str, Any]: temporary_stage: Path | None = None try: @@ -555,6 +558,7 @@ def create_lightweight_extension_router( "action": "upload", "operation_token": token, "original_command": normalized_command, + "runtime_env": runtime_env, } ) except BaseException as exc: diff --git a/gfa_core/extension_stage_lightweight/service.py b/gfa_core/extension_stage_lightweight/service.py index 8c457dae5..903a4eef4 100644 --- a/gfa_core/extension_stage_lightweight/service.py +++ b/gfa_core/extension_stage_lightweight/service.py @@ -109,6 +109,18 @@ class LightweightExtensionService: def get(self, extension_id: str) -> dict[str, Any]: return self._read_record(extension_id) + def _make_env(self, runtime_env: str) -> dict[str, str]: + """Build a process env that activates the selected conda environment.""" + + conda_prefix = f"/home/xzq/miniconda3/envs/{runtime_env}" + conda_bin = f"{conda_prefix}/bin" + env = dict(self.environment or {}) + existing_path = env.get("PATH", os.environ.get("PATH", "")) + env["PATH"] = f"{conda_bin}:{existing_path}" if existing_path else conda_bin + env["CONDA_PREFIX"] = conda_prefix + env["CONDA_DEFAULT_ENV"] = runtime_env + return env + def _deepseek_candidate(self, facts: dict[str, Any], raw_code: Path) -> tuple[dict[str, Any], dict[str, Any]]: return generate_semantic_candidate( execution_facts=facts, raw_code=raw_code, environ=self.environment @@ -324,12 +336,13 @@ class LightweightExtensionService: build: dict[str, Any] | None = None failure: tuple[str, BaseException | str] | None = None try: + runtime_env = str(record.get("runtime_env") or "test4py311") evidence = run_raw_baseline( command=record["original_command"], raw_code=root / "raw_code", raw_data=root / "raw_test_data", run_dir=root / "baseline" / run_id, - env=self.environment, + env=self._make_env(runtime_env), on_process_start=lambda identity: self._mark_process( extension_id, token=token, phase="baseline", identity=identity ), @@ -365,6 +378,7 @@ class LightweightExtensionService: raw_code: Path, raw_data: Path, original_command: str, + runtime_env: str = "test4py311", operation_token: str, ) -> dict[str, Any]: raw_code, raw_data = Path(raw_code), Path(raw_data) @@ -394,6 +408,7 @@ class LightweightExtensionService: "schema_version": "lightweight-extension-service/v1", "extension_id": extension_id, "original_command": original_command, + "runtime_env": runtime_env, "status": "baseline_running", "operations": { operation_token: { @@ -605,9 +620,10 @@ class LightweightExtensionService: rendered = render_runtime_package( record["runtime_binding_contract"], root / "raw_code", resolved, run_dir ) + runtime_env = str(record.get("runtime_env") or "test4py311") result = replay_runtime_binding( rendered, - env=self.environment, + env=self._make_env(runtime_env), on_process_start=lambda identity: self._mark_process( record["extension_id"], token=operation_token, phase=phase, identity=identity ),