export type Locale = "en" | "zh" | "ja" | "ko" | "de";

export const DEFAULT_LOCALE: Locale = "en";

interface TranslationTree {
  [key: string]: string | TranslationTree;
}

export const localeOptions: Array<{ value: Locale; label: string }> = [
  { value: "en", label: "English" },
  { value: "zh", label: "中文" },
  { value: "ja", label: "日本語" },
  { value: "ko", label: "한국어" },
  { value: "de", label: "Deutsch" },
];

const adminLayoutTranslations: Record<Locale, TranslationTree> = {
  en: { admin: "Admin", navigation: "Navigation" },
  zh: { admin: "管理后台", navigation: "导航" },
  ja: { admin: "管理", navigation: "ナビゲーション" },
  ko: { admin: "관리", navigation: "탐색" },
  de: { admin: "Admin", navigation: "Navigation" },
};

const securityCenterTranslations: Record<Locale, TranslationTree> = {
  en: {
    title: "Security Center",
    nav: {
      dashboard: "Dashboard",
      reports: "Reports",
      scanner: "Scanner Config",
    },
    navDashboardDesc: "Overview, alerts, and assets currently in use.",
    navReportsDesc: "Review historical scan reports and per-item results.",
    navScannerDesc: "Manage scan modes, rules, and live tasks.",
    common: { noneYet: "None yet" },
    errors: {
      loadCenter: "Failed to load Security Center.",
      loadReports: "Failed to load scan report.",
      saveConfig: "Failed to save scan configuration.",
      startIncrementalScan: "Failed to start incremental scan.",
      startFullScan: "Failed to start full scan.",
    },
    assetTypes: { skill: "Skill" },
    sources: { uploaded: "User Uploaded", discovered: "Instance Discovered" },
    risks: {
      safe: "SAFE",
      low: "Low Risk",
      medium: "Medium Risk",
      high: "High Risk",
      completed: "Completed",
      running: "Running",
      failed: "Failed",
      pending: "Pending",
      queued: "Queued",
      unknown: "Unknown",
    },
    status: {
      queued: "Queued",
      pending: "Pending",
      running: "Running",
      completed: "Completed",
      failed: "Failed",
      unknown: "Unknown",
    },
    scanStatus: {
      queued: "Queued",
      pending: "Pending",
      running: "Running",
      completed: "Completed",
      failed: "Failed",
      unknown: "Unknown",
    },
    scanModes: { quick: "Quick", deep: "Deep" },
    scanScopes: { incremental: "Incremental Scan", full: "Full Scan" },
    pagination: {
      summary: "{pageSize} per page, showing {from}-{to}",
      prev: "Previous",
      next: "Next",
    },
    dashboard: {
      title: "Runtime Overview",
      subtitle:
        "This dashboard summarizes the current security posture. Incremental scans only process new or changed assets, while full scans ignore cache and rescan everything.",
      activeMode: "Active mode: {mode}",
      starting: "Starting...",
      totalAssets: "Total Assets",
      completedScans: "Completed Scans",
      coverage: "Scan Coverage",
      coverageDesc:
        "The number of assets that have completed a real scan, as a share of all platform assets.",
      safeSubtitle: "Passed scan",
      highRiskSubtitle: "Requires immediate action",
      pendingSubtitle: "Waiting for evidence or queue",
      failedSubtitle: "Needs rerun",
      riskDistribution: "Risk Distribution",
      riskDistributionTitle: "Platform asset risk posture",
      groupedByRisk: "Grouped by risk level",
      hotAssets: "Hot Assets",
      hotAssetsTitle: "Most frequently used skills",
      noAssetUsage: "No asset usage records yet.",
      instances: "Instances",
      assetListTitle: "Platform Asset List",
      assetListDesc:
        "Aggregates managed skills across the platform, including assets used by instances and uploaded by users.",
      searchPlaceholder:
        "Search by name, key, user, source, risk, or scan status",
      loadingAssets: "Loading assets...",
      noMatchingAssets: "No matching assets found.",
      columns: {
        asset: "Asset",
        user: "User",
        source: "Source",
        scanStatus: "Scan Status",
        risk: "Risk",
        lastScan: "Last Scan",
        instances: "Instances",
      },
      notScanned: "Not scanned",
      scannerStatus: "Scanner Status",
      scannerAvailability: "skill-scanner Availability",
      notEnabled: "Not Enabled",
      connected: "Connected",
      disconnected: "Disconnected",
      scannerLlmEnabled:
        "skill-scanner is configured with LLM support and can run both static scans and LLM semantic scans.",
      scannerLlmDisabled:
        "skill-scanner is not configured with an LLM and currently supports static scanning only.",
      alertZone: "Alert Zone",
      alertTitle: "Risk Alerts and Remediation",
      noWarnings:
        "There are currently no high-risk or medium-risk assets. The platform security posture is stable.",
      warningFallback:
        "This asset matched a risk rule. Open report history to review the full evidence.",
      recentScans: "Recent Scans",
      recentScansTitle: "Latest Scan Jobs",
      noScanJobs: "No scan jobs yet.",
      jobTitle: "{scope} · {mode} #{id}",
    },
    reports: {
      title: "Report History",
      subtitle:
        "Review the progress, execution time, and final status of each scan job.",
      noJobs: "No scan jobs yet.",
      jobTitle: "{scope} · {mode} #{id}",
      jobMeta:
        "{assetType} · Scope {scope} · Mode {mode} · Completed {completed}/{total}",
      selectJob: "Select a job on the left to view the report.",
      completedProgress: "Completed {completed}/{total}",
      currentItem: "Current {name}",
      scopeMode: "Scope {scope} · Mode {mode}",
      startedAt: "Started at {value}",
      waitingToStart: "Waiting to start",
      finishedAt: "Finished at {value}",
      analyzerView: "Analyzer View",
      analyzerViewDesc:
        "This view distinguishes configured analyzers, currently available scanner capabilities, and analyzers that actually produced findings.",
      configuredAnalyzers: "Configured",
      availableAnalyzers: "Available Now",
      triggeredAnalyzers: "Triggered",
      noAnalyzerFindings: "No analyzer produced findings in this run.",
      itemResults: "Per-Item Results",
      cachedResult: "Cached result reused",
      liveScan: "Live scan",
      evidence: "Evidence: {value}",
      remediation: "Remediation: {value}",
      reportGenerating: "The report is still being generated.",
    },
    scanner: {
      title: "Scanner Configuration",
      subtitle:
        "Background scans are forced through skill-scanner. Manage the LLM settings and quick/deep scan policies here.",
      saving: "Saving and applying...",
      saveAndApply: "Save and Apply",
      serviceStatus: "skill-scanner Service Status",
      namespaceDeployment:
        "Namespace `{namespace}` · Deployment `{deployment}`",
      llmConfig: "LLM Configuration",
      llmConfigDesc:
        "View and edit the active skill-scanner LLM environment variables. Saving triggers a Deployment rollout and waits for the new configuration to take effect.",
      primaryLlmIntegration: "Primary LLM Integration",
      primaryLlmIntegrationHelp:
        "Import the primary LLM settings directly from an AI Gateway model.",
      llmApiKeyHelp:
        "Maps to SKILL_SCANNER_LLM_API_KEY for authenticating the primary LLM analyzer.",
      llmModelHelp: "Maps to SKILL_SCANNER_LLM_MODEL, for example kimi-k2.5.",
      llmBaseUrlHelp:
        "Maps to SKILL_SCANNER_LLM_BASE_URL for the primary LLM service endpoint.",
      metaLlmIntegration: "Meta LLM Integration",
      metaLlmIntegrationHelp:
        "Import the meta analyzer settings directly from an AI Gateway model.",
      metaLlmApiKeyHelp:
        "Maps to SKILL_SCANNER_META_LLM_API_KEY for the meta analyzer.",
      metaLlmModelHelp: "Maps to SKILL_SCANNER_META_LLM_MODEL.",
      metaLlmBaseUrlHelp:
        "Maps to SKILL_SCANNER_META_LLM_BASE_URL for the meta analyzer service endpoint.",
      currentMode: "Current Scan Mode",
      currentModeDesc:
        "The Dashboard uses the selected scan strength here for both incremental and full scans. The difference between those buttons is the scan scope, not analyzer depth.",
      quickMode: "Quick Mode",
      quickModeDesc: "Run scans with quick analyzers.",
      deepMode: "Deep Mode",
      deepModeDesc: "Run scans with deep analyzers.",
      applySummary:
        "Saving also updates ClawManager quick/deep policies, updates the skill-scanner Deployment environment variables, and waits for rollout completion so the new configuration is live immediately.",
      loadingConfig: "Loading configuration...",
      timeoutSeconds: "Timeout (seconds)",
      invocationMethod: "Invocation Method",
      hide: "Hide",
      reveal: "Reveal",
      selectAiGatewayModel: "Select an AI Gateway model",
      analyzers: {
        static: "YAML + YARA static rules scanning",
        bytecode: "Python bytecode integrity checks",
        pipeline: "Command pipeline and taint analysis",
        behavioral: "AST-based behavior and dataflow analysis",
        llm: "Semantic analysis powered by an external LLM",
        meta: "Secondary aggregation over findings",
      },
    },
  },
  zh: {
    title: "安全中心",
    nav: { dashboard: "运行总览", reports: "报告历史", scanner: "扫描器配置" },
    navDashboardDesc: "总览、安全告警与使用中的资产。",
    navReportsDesc: "查看每次扫描的历史报告与逐项结果。",
    navScannerDesc: "管理扫描模式、规则和实时任务。",
    common: { noneYet: "暂无" },
    errors: {
      loadCenter: "加载安全中心失败。",
      loadReports: "加载扫描报告失败。",
      saveConfig: "保存扫描配置失败。",
      startIncrementalScan: "启动快速扫描失败。",
      startFullScan: "启动全量扫描失败。",
    },
    assetTypes: { skill: "技能" },
    sources: { uploaded: "用户上传", discovered: "实例发现" },
    risks: {
      safe: "SAFE",
      low: "低风险",
      medium: "中风险",
      high: "高风险",
      completed: "已完成",
      running: "扫描中",
      failed: "失败",
      pending: "等待中",
      queued: "排队中",
      unknown: "未知",
    },
    status: {
      queued: "排队中",
      pending: "等待中",
      running: "扫描中",
      completed: "已完成",
      failed: "失败",
      unknown: "未知",
    },
    scanStatus: {
      queued: "排队中",
      pending: "待扫描",
      running: "扫描中",
      completed: "已完成",
      failed: "扫描失败",
      unknown: "未知",
    },
    scanModes: { quick: "快速", deep: "深度" },
    scanScopes: { incremental: "快速扫描", full: "全量扫描" },
    pagination: {
      summary: "每页 {pageSize} 条，本页显示 {from}-{to}",
      prev: "上一页",
      next: "下一页",
    },
    dashboard: {
      title: "运行总览",
      subtitle:
        "Dashboard 负责总览当前安全态势。快速扫描只处理新增或变更资产；全量扫描会忽略缓存重扫全部资产。",
      activeMode: "当前生效模式：{mode}",
      starting: "启动中...",
      totalAssets: "资产总数",
      completedScans: "已完成扫描",
      coverage: "扫描覆盖率",
      coverageDesc: "已完成真实扫描的资产数，占平台总资产的当前比例。",
      safeSubtitle: "通过扫描",
      highRiskSubtitle: "需立即处置",
      pendingSubtitle: "等待取证或排队",
      failedSubtitle: "需重新执行",
      riskDistribution: "风险分布",
      riskDistributionTitle: "平台资产风险态势",
      groupedByRisk: "按风险等级聚合",
      hotAssets: "热点资产",
      hotAssetsTitle: "使用最频繁的技能",
      noAssetUsage: "当前没有资产使用记录。",
      instances: "实例数",
      assetListTitle: "平台资产列表",
      assetListDesc:
        "聚合展示平台已管理的 skill，包括实例中正在使用和用户上传的资产。",
      searchPlaceholder: "按名称、key、用户、来源、风险、扫描状态搜索",
      loadingAssets: "正在加载资产...",
      noMatchingAssets: "没有找到匹配的资产。",
      columns: {
        asset: "资产",
        user: "用户",
        source: "来源",
        scanStatus: "扫描状态",
        risk: "风险",
        lastScan: "最近扫描",
        instances: "实例数",
      },
      notScanned: "未扫描",
      scannerStatus: "扫描器状态",
      scannerAvailability: "skill-scanner 可用性",
      notEnabled: "未启用",
      connected: "已连接",
      disconnected: "未连接",
      scannerLlmEnabled:
        "当前 skill-scanner 已配置 LLM，支持静态扫描与 LLM 语义扫描。",
      scannerLlmDisabled: "当前 skill-scanner 未配置 LLM，仅支持静态扫描。",
      alertZone: "告警区域",
      alertTitle: "风险提醒与处置建议",
      noWarnings: "当前没有高风险或中风险资产，安全面处于稳定状态。",
      warningFallback: "已命中风险规则，可进入报告历史查看完整依据。",
      recentScans: "最近扫描",
      recentScansTitle: "最近的扫描任务",
      noScanJobs: "还没有扫描任务记录。",
      jobTitle: "{scope} · {mode} #{id}",
    },
    reports: {
      title: "报告历史",
      subtitle: "查看每次扫描任务的进度、执行时间和最终状态。",
      noJobs: "还没有扫描任务。",
      jobTitle: "{scope} · {mode} #{id}",
      jobMeta:
        "{assetType} · 范围 {scope} · 模式 {mode} · 已完成 {completed}/{total}",
      selectJob: "选择左侧任务查看扫描报告。",
      completedProgress: "已完成 {completed}/{total}",
      currentItem: "当前 {name}",
      scopeMode: "范围 {scope} · 模式 {mode}",
      startedAt: "开始于 {value}",
      waitingToStart: "等待开始",
      finishedAt: "完成于 {value}",
      analyzerView: "Analyzer 视图",
      analyzerViewDesc:
        "这里区分了本次请求配置、scanner 当前可用能力以及最终产出 findings 的 analyzer。",
      configuredAnalyzers: "本次配置",
      availableAnalyzers: "当前可用",
      triggeredAnalyzers: "实际命中",
      noAnalyzerFindings: "本次没有 analyzer 产出 findings",
      itemResults: "逐项结果",
      cachedResult: "复用缓存结果",
      liveScan: "实时扫描",
      evidence: "依据：{value}",
      remediation: "建议：{value}",
      reportGenerating: "报告还在生成中。",
    },
    scanner: {
      title: "扫描器配置",
      subtitle:
        "后台扫描强制走 skill-scanner。这里维护 LLM 配置和 quick/deep 两套扫描策略。",
      saving: "保存并应用中...",
      saveAndApply: "保存并应用",
      serviceStatus: "skill-scanner 服务状态",
      namespaceDeployment: "命名空间 `{namespace}` · Deployment `{deployment}`",
      llmConfig: "LLM 配置",
      llmConfigDesc:
        "这里展示并编辑当前运行中的 skill-scanner LLM 相关环境变量。保存后会触发 Deployment rollout，并等待新配置生效。",
      primaryLlmIntegration: "主 LLM 集成",
      primaryLlmIntegrationHelp:
        "从 AI Gateway 已配置好的模型中直接导入主 LLM 配置。",
      llmApiKeyHelp:
        "对应 SKILL_SCANNER_LLM_API_KEY，用于主 LLM analyzer 的鉴权。",
      llmModelHelp: "对应 SKILL_SCANNER_LLM_MODEL，例如 kimi-k2.5。",
      llmBaseUrlHelp: "对应 SKILL_SCANNER_LLM_BASE_URL，主 LLM 服务地址。",
      metaLlmIntegration: "Meta LLM 集成",
      metaLlmIntegrationHelp:
        "从 AI Gateway 已配置好的模型中直接导入 meta analyzer 配置。",
      metaLlmApiKeyHelp:
        "对应 SKILL_SCANNER_META_LLM_API_KEY，用于 meta analyzer。",
      metaLlmModelHelp: "对应 SKILL_SCANNER_META_LLM_MODEL。",
      metaLlmBaseUrlHelp:
        "对应 SKILL_SCANNER_META_LLM_BASE_URL，meta analyzer 使用的服务地址。",
      currentMode: "当前扫描模式",
      currentModeDesc:
        "Dashboard 上的“快速扫描”和“全量扫描”都会使用这里选中的扫描强度；区别只在扫描范围，不在 analyzer 深度。",
      quickMode: "Quick 模式",
      quickModeDesc: "使用 quick analyzers 执行扫描。",
      deepMode: "Deep 模式",
      deepModeDesc: "使用 deep analyzers 执行扫描。",
      applySummary:
        "保存后会同时更新 ClawManager 的 quick/deep 扫描策略、更新 skill-scanner Deployment 的环境变量，并等待 rollout 完成让新配置实时生效。",
      loadingConfig: "正在加载配置...",
      timeoutSeconds: "超时（秒）",
      invocationMethod: "调用方法",
      hide: "隐藏",
      reveal: "查看",
      selectAiGatewayModel: "选择一个 AI Gateway 模型",
      analyzers: {
        static: "YAML + YARA 静态规则扫描",
        bytecode: "Python bytecode 完整性校验",
        pipeline: "命令链路与 taint 分析",
        behavioral: "基于 AST 的行为与数据流分析",
        llm: "依赖外部 LLM 的语义分析",
        meta: "对 findings 进行二次汇总分析",
      },
    },
  },
  ja: {
    title: "セキュリティセンター",
    nav: {
      dashboard: "ダッシュボード",
      reports: "レポート履歴",
      scanner: "スキャナー設定",
    },
    navDashboardDesc: "概要、警告、使用中アセットを確認します。",
    navReportsDesc: "過去のスキャンレポートと項目ごとの結果を確認します。",
    navScannerDesc: "スキャンモード、ルール、実行中タスクを管理します。",
    common: { noneYet: "まだありません" },
    errors: {
      loadCenter: "セキュリティセンターの読み込みに失敗しました。",
      loadReports: "スキャンレポートの読み込みに失敗しました。",
      saveConfig: "スキャン設定の保存に失敗しました。",
      startIncrementalScan: "増分スキャンの開始に失敗しました。",
      startFullScan: "フルスキャンの開始に失敗しました。",
    },
    assetTypes: { skill: "スキル" },
    sources: {
      uploaded: "ユーザーアップロード",
      discovered: "インスタンス検出",
    },
    risks: {
      safe: "SAFE",
      low: "低リスク",
      medium: "中リスク",
      high: "高リスク",
      completed: "完了",
      running: "実行中",
      failed: "失敗",
      pending: "保留",
      queued: "待機中",
      unknown: "不明",
    },
    status: {
      queued: "待機中",
      pending: "保留",
      running: "実行中",
      completed: "完了",
      failed: "失敗",
      unknown: "不明",
    },
    scanStatus: {
      queued: "待機中",
      pending: "未スキャン",
      running: "スキャン中",
      completed: "完了",
      failed: "スキャン失敗",
      unknown: "不明",
    },
    scanModes: { quick: "クイック", deep: "ディープ" },
    scanScopes: { incremental: "増分スキャン", full: "フルスキャン" },
    pagination: {
      summary: "1ページ {pageSize} 件、{from}-{to} を表示",
      prev: "前へ",
      next: "次へ",
    },
    dashboard: {
      title: "ランタイム概要",
      subtitle:
        "現在のセキュリティ状況を要約します。増分スキャンは新規または変更されたアセットのみを処理し、フルスキャンはキャッシュを無視して全件を再スキャンします。",
      activeMode: "現在のモード: {mode}",
      starting: "開始中...",
      totalAssets: "総アセット数",
      completedScans: "完了スキャン",
      coverage: "スキャンカバレッジ",
      coverageDesc:
        "実際のスキャンが完了したアセット数と全体に対する割合です。",
      safeSubtitle: "スキャン通過",
      highRiskSubtitle: "即時対応が必要",
      pendingSubtitle: "証跡待ちまたは待機中",
      failedSubtitle: "再実行が必要",
      riskDistribution: "リスク分布",
      riskDistributionTitle: "プラットフォームのリスク状況",
      groupedByRisk: "リスクレベル別集計",
      hotAssets: "ホットアセット",
      hotAssetsTitle: "最も使用されているスキル",
      noAssetUsage: "アセット利用記録はありません。",
      instances: "インスタンス",
      assetListTitle: "プラットフォームアセット一覧",
      assetListDesc:
        "インスタンスで利用中のアセットとユーザーアップロードのアセットを含む、管理対象スキルを集約表示します。",
      searchPlaceholder:
        "名前、キー、ユーザー、ソース、リスク、スキャン状態で検索",
      loadingAssets: "アセットを読み込み中...",
      noMatchingAssets: "一致するアセットがありません。",
      columns: {
        asset: "アセット",
        user: "ユーザー",
        source: "ソース",
        scanStatus: "スキャン状態",
        risk: "リスク",
        lastScan: "最終スキャン",
        instances: "インスタンス数",
      },
      notScanned: "未スキャン",
      scannerStatus: "スキャナー状態",
      scannerAvailability: "skill-scanner の可用性",
      notEnabled: "未有効",
      connected: "接続済み",
      disconnected: "未接続",
      scannerLlmEnabled:
        "skill-scanner は LLM 付きで構成されており、静的スキャンと LLM セマンティックスキャンの両方を実行できます。",
      scannerLlmDisabled:
        "skill-scanner には LLM が設定されておらず、現在は静的スキャンのみ利用できます。",
      alertZone: "アラート領域",
      alertTitle: "リスク通知と対処提案",
      noWarnings:
        "現在、高リスクまたは中リスクのアセットはありません。プラットフォームは安定しています。",
      warningFallback:
        "このアセットはリスクルールに一致しました。完全な証跡はレポート履歴で確認できます。",
      recentScans: "最近のスキャン",
      recentScansTitle: "最新のスキャンジョブ",
      noScanJobs: "スキャンジョブはまだありません。",
      jobTitle: "{scope} · {mode} #{id}",
    },
    reports: {
      title: "レポート履歴",
      subtitle: "各スキャンジョブの進行状況、実行時間、最終状態を確認します。",
      noJobs: "スキャンジョブはまだありません。",
      jobTitle: "{scope} · {mode} #{id}",
      jobMeta:
        "{assetType} · 範囲 {scope} · モード {mode} · 完了 {completed}/{total}",
      selectJob: "左側のジョブを選択してレポートを表示します。",
      completedProgress: "完了 {completed}/{total}",
      currentItem: "現在 {name}",
      scopeMode: "範囲 {scope} · モード {mode}",
      startedAt: "{value} に開始",
      waitingToStart: "開始待ち",
      finishedAt: "{value} に完了",
      analyzerView: "Analyzer ビュー",
      analyzerViewDesc:
        "設定済み analyzer、現在利用可能な scanner 機能、実際に findings を生成した analyzer を区別して表示します。",
      configuredAnalyzers: "今回の設定",
      availableAnalyzers: "現在利用可能",
      triggeredAnalyzers: "実際にヒット",
      noAnalyzerFindings:
        "この実行で findings を生成した analyzer はありません。",
      itemResults: "項目別結果",
      cachedResult: "キャッシュ結果を再利用",
      liveScan: "リアルタイムスキャン",
      evidence: "根拠: {value}",
      remediation: "対処: {value}",
      reportGenerating: "レポートを生成中です。",
    },
    scanner: {
      title: "スキャナー設定",
      subtitle:
        "バックグラウンドスキャンはすべて skill-scanner 経由で実行されます。ここで LLM 設定と quick/deep ポリシーを管理します。",
      saving: "保存して適用中...",
      saveAndApply: "保存して適用",
      serviceStatus: "skill-scanner サービス状態",
      namespaceDeployment:
        "Namespace `{namespace}` · Deployment `{deployment}`",
      llmConfig: "LLM 設定",
      llmConfigDesc:
        "稼働中の skill-scanner の LLM 環境変数を表示・編集します。保存すると Deployment のロールアウトが開始され、新しい設定が有効になるまで待機します。",
      primaryLlmIntegration: "メイン LLM 連携",
      primaryLlmIntegrationHelp:
        "AI Gateway に設定済みのモデルからメイン LLM 設定を直接取り込みます。",
      llmApiKeyHelp:
        "メイン LLM analyzer 用の SKILL_SCANNER_LLM_API_KEY に対応します。",
      llmModelHelp: "SKILL_SCANNER_LLM_MODEL に対応します。例: kimi-k2.5。",
      llmBaseUrlHelp:
        "メイン LLM サービスの SKILL_SCANNER_LLM_BASE_URL に対応します。",
      metaLlmIntegration: "Meta LLM 連携",
      metaLlmIntegrationHelp:
        "AI Gateway に設定済みのモデルから meta analyzer 設定を直接取り込みます。",
      metaLlmApiKeyHelp:
        "meta analyzer 用の SKILL_SCANNER_META_LLM_API_KEY に対応します。",
      metaLlmModelHelp: "SKILL_SCANNER_META_LLM_MODEL に対応します。",
      metaLlmBaseUrlHelp:
        "meta analyzer サービスの SKILL_SCANNER_META_LLM_BASE_URL に対応します。",
      currentMode: "現在のスキャンモード",
      currentModeDesc:
        "ダッシュボードの増分スキャンとフルスキャンは、ここで選択したスキャン強度を使用します。違いは analyzer の深さではなく対象範囲です。",
      quickMode: "Quick モード",
      quickModeDesc: "quick analyzers でスキャンします。",
      deepMode: "Deep モード",
      deepModeDesc: "deep analyzers でスキャンします。",
      applySummary:
        "保存すると ClawManager の quick/deep ポリシー更新、skill-scanner Deployment の環境変数更新、rollout 完了待機がまとめて実行されます。",
      loadingConfig: "設定を読み込み中...",
      timeoutSeconds: "タイムアウト（秒）",
      invocationMethod: "呼び出し方式",
      hide: "非表示",
      reveal: "表示",
      selectAiGatewayModel: "AI Gateway モデルを選択",
      analyzers: {
        static: "YAML + YARA の静的ルールスキャン",
        bytecode: "Python bytecode の整合性検証",
        pipeline: "コマンドパイプラインと taint 解析",
        behavioral: "AST ベースの挙動・データフロー解析",
        llm: "外部 LLM を使った意味解析",
        meta: "findings の二次集約解析",
      },
    },
  },
  ko: {
    title: "보안 센터",
    nav: {
      dashboard: "대시보드",
      reports: "보고서 기록",
      scanner: "스캐너 설정",
    },
    navDashboardDesc: "개요, 경고, 현재 사용 중인 자산을 확인합니다.",
    navReportsDesc: "과거 스캔 보고서와 항목별 결과를 확인합니다.",
    navScannerDesc: "스캔 모드, 규칙, 실시간 작업을 관리합니다.",
    common: { noneYet: "없음" },
    errors: {
      loadCenter: "보안 센터를 불러오지 못했습니다.",
      loadReports: "스캔 보고서를 불러오지 못했습니다.",
      saveConfig: "스캔 구성을 저장하지 못했습니다.",
      startIncrementalScan: "증분 스캔 시작에 실패했습니다.",
      startFullScan: "전체 스캔 시작에 실패했습니다.",
    },
    assetTypes: { skill: "스킬" },
    sources: { uploaded: "사용자 업로드", discovered: "인스턴스 감지" },
    risks: {
      safe: "SAFE",
      low: "낮음",
      medium: "중간",
      high: "높음",
      completed: "완료",
      running: "실행 중",
      failed: "실패",
      pending: "대기 중",
      queued: "큐 대기",
      unknown: "알 수 없음",
    },
    status: {
      queued: "큐 대기",
      pending: "대기 중",
      running: "실행 중",
      completed: "완료",
      failed: "실패",
      unknown: "알 수 없음",
    },
    scanStatus: {
      queued: "큐 대기",
      pending: "미스캔",
      running: "스캔 중",
      completed: "완료",
      failed: "스캔 실패",
      unknown: "알 수 없음",
    },
    scanModes: { quick: "빠른", deep: "심층" },
    scanScopes: { incremental: "빠른 스캔", full: "전체 스캔" },
    pagination: {
      summary: "페이지당 {pageSize}개, {from}-{to} 표시",
      prev: "이전 페이지",
      next: "다음 페이지",
    },
    dashboard: {
      title: "런타임 개요",
      subtitle:
        "현재 보안 상태를 요약합니다. 빠른 스캔은 신규 또는 변경 자산만 처리하고, 전체 스캔은 캐시를 무시하고 모든 자산을 다시 검사합니다.",
      activeMode: "현재 모드: {mode}",
      starting: "시작 중...",
      totalAssets: "총 자산",
      completedScans: "완료된 스캔",
      coverage: "스캔 커버리지",
      coverageDesc: "실제 스캔이 완료된 자산 수와 전체 대비 비율입니다.",
      safeSubtitle: "스캔 통과",
      highRiskSubtitle: "즉시 조치 필요",
      pendingSubtitle: "증거 또는 대기열 대기",
      failedSubtitle: "재실행 필요",
      riskDistribution: "위험 분포",
      riskDistributionTitle: "플랫폼 자산 위험 현황",
      groupedByRisk: "위험 수준별 집계",
      hotAssets: "핫 자산",
      hotAssetsTitle: "가장 자주 사용되는 스킬",
      noAssetUsage: "자산 사용 기록이 없습니다.",
      instances: "인스턴스",
      assetListTitle: "플랫폼 자산 목록",
      assetListDesc:
        "인스턴스 사용 자산과 사용자 업로드 자산을 포함한 관리 대상 스킬을 집계해 보여줍니다.",
      searchPlaceholder: "이름, 키, 사용자, 소스, 위험, 스캔 상태로 검색",
      loadingAssets: "자산을 불러오는 중...",
      noMatchingAssets: "일치하는 자산이 없습니다.",
      columns: {
        asset: "자산",
        user: "사용자",
        source: "소스",
        scanStatus: "스캔 상태",
        risk: "위험",
        lastScan: "최근 스캔",
        instances: "인스턴스 수",
      },
      notScanned: "스캔 안 함",
      scannerStatus: "스캐너 상태",
      scannerAvailability: "skill-scanner 가용성",
      notEnabled: "비활성",
      connected: "연결됨",
      disconnected: "연결 안 됨",
      scannerLlmEnabled:
        "skill-scanner 에 LLM 이 설정되어 정적 스캔과 LLM 의미 분석 스캔을 모두 실행할 수 있습니다.",
      scannerLlmDisabled:
        "skill-scanner 에 LLM 이 설정되지 않아 현재 정적 스캔만 지원합니다.",
      alertZone: "알림 영역",
      alertTitle: "위험 알림 및 대응 제안",
      noWarnings:
        "현재 높음 또는 중간 위험 자산이 없습니다. 플랫폼 보안 상태는 안정적입니다.",
      warningFallback:
        "이 자산이 위험 규칙에 일치했습니다. 전체 근거는 보고서 기록에서 확인할 수 있습니다.",
      recentScans: "최근 스캔",
      recentScansTitle: "최근 스캔 작업",
      noScanJobs: "스캔 작업 기록이 없습니다.",
      jobTitle: "{scope} · {mode} #{id}",
    },
    reports: {
      title: "보고서 기록",
      subtitle: "각 스캔 작업의 진행률, 실행 시간, 최종 상태를 확인합니다.",
      noJobs: "스캔 작업이 없습니다.",
      jobTitle: "{scope} · {mode} #{id}",
      jobMeta:
        "{assetType} · 범위 {scope} · 모드 {mode} · 완료 {completed}/{total}",
      selectJob: "왼쪽에서 작업을 선택해 보고서를 확인하세요.",
      completedProgress: "완료 {completed}/{total}",
      currentItem: "현재 {name}",
      scopeMode: "범위 {scope} · 모드 {mode}",
      startedAt: "{value} 시작",
      waitingToStart: "시작 대기",
      finishedAt: "{value} 완료",
      analyzerView: "Analyzer 보기",
      analyzerViewDesc:
        "이번 요청의 analyzer 설정, 현재 scanner 가 제공하는 기능, 실제 findings 를 만든 analyzer 를 구분해서 보여줍니다.",
      configuredAnalyzers: "이번 설정",
      availableAnalyzers: "현재 사용 가능",
      triggeredAnalyzers: "실제 적중",
      noAnalyzerFindings:
        "이번 실행에서 findings 를 생성한 analyzer 가 없습니다.",
      itemResults: "항목별 결과",
      cachedResult: "캐시 결과 재사용",
      liveScan: "실시간 스캔",
      evidence: "근거: {value}",
      remediation: "조치: {value}",
      reportGenerating: "보고서를 생성하는 중입니다.",
    },
    scanner: {
      title: "스캐너 설정",
      subtitle:
        "백그라운드 스캔은 모두 skill-scanner 를 통해 실행됩니다. 여기에서 LLM 설정과 quick/deep 정책을 관리합니다.",
      saving: "저장 및 적용 중...",
      saveAndApply: "저장 및 적용",
      serviceStatus: "skill-scanner 서비스 상태",
      namespaceDeployment:
        "Namespace `{namespace}` · Deployment `{deployment}`",
      llmConfig: "LLM 설정",
      llmConfigDesc:
        "실행 중인 skill-scanner 의 LLM 환경 변수를 확인하고 수정합니다. 저장하면 Deployment rollout 이 실행되고 새 구성이 적용될 때까지 기다립니다.",
      primaryLlmIntegration: "기본 LLM 연동",
      primaryLlmIntegrationHelp:
        "AI Gateway 모델에서 기본 LLM 구성을 직접 가져옵니다.",
      llmApiKeyHelp:
        "기본 LLM analyzer 인증용 SKILL_SCANNER_LLM_API_KEY 에 대응합니다.",
      llmModelHelp: "SKILL_SCANNER_LLM_MODEL 에 대응합니다. 예: kimi-k2.5.",
      llmBaseUrlHelp:
        "기본 LLM 서비스 엔드포인트인 SKILL_SCANNER_LLM_BASE_URL 에 대응합니다.",
      metaLlmIntegration: "Meta LLM 연동",
      metaLlmIntegrationHelp:
        "AI Gateway 모델에서 meta analyzer 구성을 직접 가져옵니다.",
      metaLlmApiKeyHelp:
        "meta analyzer 용 SKILL_SCANNER_META_LLM_API_KEY 에 대응합니다.",
      metaLlmModelHelp: "SKILL_SCANNER_META_LLM_MODEL 에 대응합니다.",
      metaLlmBaseUrlHelp:
        "meta analyzer 서비스 엔드포인트인 SKILL_SCANNER_META_LLM_BASE_URL 에 대응합니다.",
      currentMode: "현재 스캔 모드",
      currentModeDesc:
        "대시보드의 빠른 스캔과 전체 스캔은 여기서 선택한 스캔 강도를 사용합니다. 차이는 analyzer 깊이가 아니라 스캔 범위입니다.",
      quickMode: "Quick 모드",
      quickModeDesc: "quick analyzers 로 스캔합니다.",
      deepMode: "Deep 모드",
      deepModeDesc: "deep analyzers 로 스캔합니다.",
      applySummary:
        "저장하면 ClawManager quick/deep 정책 업데이트, skill-scanner Deployment 환경 변수 업데이트, rollout 완료 대기가 함께 실행됩니다.",
      loadingConfig: "구성을 불러오는 중...",
      timeoutSeconds: "시간 제한(초)",
      invocationMethod: "호출 방식",
      hide: "숨기기",
      reveal: "보기",
      selectAiGatewayModel: "AI Gateway 모델 선택",
      analyzers: {
        static: "YAML + YARA 정적 규칙 스캔",
        bytecode: "Python bytecode 무결성 검사",
        pipeline: "명령 파이프라인 및 taint 분석",
        behavioral: "AST 기반 동작 및 데이터 흐름 분석",
        llm: "외부 LLM 기반 의미 분석",
        meta: "findings 에 대한 2차 집계 분석",
      },
    },
  },
  de: {
    title: "Sicherheitszentrum",
    nav: {
      dashboard: "Dashboard",
      reports: "Berichtshistorie",
      scanner: "Scanner-Konfiguration",
    },
    navDashboardDesc: "Überblick, Warnungen und aktuell genutzte Assets.",
    navReportsDesc:
      "Historische Scanberichte und Ergebnisse pro Element prüfen.",
    navScannerDesc: "Scanmodi, Regeln und Live-Aufgaben verwalten.",
    common: { noneYet: "Noch nichts vorhanden" },
    errors: {
      loadCenter: "Sicherheitszentrum konnte nicht geladen werden.",
      loadReports: "Scanbericht konnte nicht geladen werden.",
      saveConfig: "Scankonfiguration konnte nicht gespeichert werden.",
      startIncrementalScan:
        "Inkrementeller Scan konnte nicht gestartet werden.",
      startFullScan: "Vollständiger Scan konnte nicht gestartet werden.",
    },
    assetTypes: { skill: "Skill" },
    sources: {
      uploaded: "Vom Benutzer hochgeladen",
      discovered: "In Instanz gefunden",
    },
    risks: {
      safe: "SAFE",
      low: "Niedriges Risiko",
      medium: "Mittleres Risiko",
      high: "Hohes Risiko",
      completed: "Abgeschlossen",
      running: "Läuft",
      failed: "Fehlgeschlagen",
      pending: "Ausstehend",
      queued: "In Warteschlange",
      unknown: "Unbekannt",
    },
    status: {
      queued: "In Warteschlange",
      pending: "Ausstehend",
      running: "Läuft",
      completed: "Abgeschlossen",
      failed: "Fehlgeschlagen",
      unknown: "Unbekannt",
    },
    scanStatus: {
      queued: "In Warteschlange",
      pending: "Nicht gescannt",
      running: "Scan läuft",
      completed: "Abgeschlossen",
      failed: "Scan fehlgeschlagen",
      unknown: "Unbekannt",
    },
    scanModes: { quick: "Schnell", deep: "Tief" },
    scanScopes: { incremental: "Inkrementeller Scan", full: "Vollscan" },
    pagination: {
      summary: "{pageSize} pro Seite, zeige {from}-{to}",
      prev: "Zurück",
      next: "Weiter",
    },
    dashboard: {
      title: "Laufzeitüberblick",
      subtitle:
        "Dieses Dashboard fasst die aktuelle Sicherheitslage zusammen. Inkrementelle Scans verarbeiten nur neue oder geänderte Assets, während Vollscans den Cache ignorieren und alles neu prüfen.",
      activeMode: "Aktiver Modus: {mode}",
      starting: "Wird gestartet...",
      totalAssets: "Gesamtanzahl Assets",
      completedScans: "Abgeschlossene Scans",
      coverage: "Scan-Abdeckung",
      coverageDesc:
        "Anzahl der Assets mit abgeschlossenem echten Scan als Anteil aller Plattform-Assets.",
      safeSubtitle: "Scan bestanden",
      highRiskSubtitle: "Sofortige Maßnahme nötig",
      pendingSubtitle: "Wartet auf Beweise oder Queue",
      failedSubtitle: "Erneut ausführen",
      riskDistribution: "Risikoverteilung",
      riskDistributionTitle: "Risikolage der Plattform-Assets",
      groupedByRisk: "Nach Risikostufe gruppiert",
      hotAssets: "Hot Assets",
      hotAssetsTitle: "Am häufigsten genutzte Skills",
      noAssetUsage: "Keine Nutzungsdaten für Assets vorhanden.",
      instances: "Instanzen",
      assetListTitle: "Plattform-Asset-Liste",
      assetListDesc:
        "Zeigt verwaltete Skills der Plattform zusammengefasst, inklusive in Instanzen genutzter und von Benutzern hochgeladener Assets.",
      searchPlaceholder:
        "Nach Name, Schlüssel, Benutzer, Quelle, Risiko oder Scanstatus suchen",
      loadingAssets: "Assets werden geladen...",
      noMatchingAssets: "Keine passenden Assets gefunden.",
      columns: {
        asset: "Asset",
        user: "Benutzer",
        source: "Quelle",
        scanStatus: "Scanstatus",
        risk: "Risiko",
        lastScan: "Letzter Scan",
        instances: "Instanzen",
      },
      notScanned: "Nicht gescannt",
      scannerStatus: "Scannerstatus",
      scannerAvailability: "skill-scanner Verfügbarkeit",
      notEnabled: "Nicht aktiviert",
      connected: "Verbunden",
      disconnected: "Nicht verbunden",
      scannerLlmEnabled:
        "skill-scanner ist mit LLM-Unterstützung konfiguriert und kann statische Scans sowie semantische LLM-Scans ausführen.",
      scannerLlmDisabled:
        "skill-scanner ist nicht mit einem LLM konfiguriert und unterstützt derzeit nur statisches Scannen.",
      alertZone: "Alarmbereich",
      alertTitle: "Risikoalarme und Maßnahmen",
      noWarnings:
        "Derzeit gibt es keine Assets mit hohem oder mittlerem Risiko. Die Sicherheitslage ist stabil.",
      warningFallback:
        "Dieses Asset hat eine Risikoregel ausgelöst. Öffnen Sie die Berichtshistorie für die vollständigen Belege.",
      recentScans: "Letzte Scans",
      recentScansTitle: "Neueste Scan-Jobs",
      noScanJobs: "Noch keine Scan-Jobs vorhanden.",
      jobTitle: "{scope} · {mode} #{id}",
    },
    reports: {
      title: "Berichtshistorie",
      subtitle: "Fortschritt, Laufzeit und Endstatus jedes Scan-Jobs prüfen.",
      noJobs: "Noch keine Scan-Jobs vorhanden.",
      jobTitle: "{scope} · {mode} #{id}",
      jobMeta:
        "{assetType} · Bereich {scope} · Modus {mode} · Abgeschlossen {completed}/{total}",
      selectJob: "Wählen Sie links einen Job aus, um den Bericht zu sehen.",
      completedProgress: "Abgeschlossen {completed}/{total}",
      currentItem: "Aktuell {name}",
      scopeMode: "Bereich {scope} · Modus {mode}",
      startedAt: "Gestartet um {value}",
      waitingToStart: "Wartet auf Start",
      finishedAt: "Beendet um {value}",
      analyzerView: "Analyzer-Ansicht",
      analyzerViewDesc:
        "Diese Ansicht trennt konfigurierte Analyzer, aktuell verfügbare Scanner-Fähigkeiten und Analyzer, die tatsächlich Findings erzeugt haben.",
      configuredAnalyzers: "Konfiguriert",
      availableAnalyzers: "Aktuell verfügbar",
      triggeredAnalyzers: "Ausgelöst",
      noAnalyzerFindings: "In diesem Lauf hat kein Analyzer Findings erzeugt.",
      itemResults: "Ergebnisse pro Element",
      cachedResult: "Cache-Ergebnis wiederverwendet",
      liveScan: "Live-Scan",
      evidence: "Beleg: {value}",
      remediation: "Empfehlung: {value}",
      reportGenerating: "Der Bericht wird noch erstellt.",
    },
    scanner: {
      title: "Scanner-Konfiguration",
      subtitle:
        "Hintergrundscans laufen erzwungen über skill-scanner. Verwalten Sie hier LLM-Einstellungen sowie Quick/Deep-Richtlinien.",
      saving: "Wird gespeichert und angewendet...",
      saveAndApply: "Speichern und Anwenden",
      serviceStatus: "skill-scanner Dienststatus",
      namespaceDeployment:
        "Namespace `{namespace}` · Deployment `{deployment}`",
      llmConfig: "LLM-Konfiguration",
      llmConfigDesc:
        "Aktive skill-scanner LLM-Umgebungsvariablen anzeigen und bearbeiten. Speichern startet ein Deployment-Rollout und wartet, bis die neue Konfiguration aktiv ist.",
      primaryLlmIntegration: "Primäre LLM-Integration",
      primaryLlmIntegrationHelp:
        "Primäre LLM-Konfiguration direkt aus einem AI-Gateway-Modell importieren.",
      llmApiKeyHelp:
        "Entspricht SKILL_SCANNER_LLM_API_KEY für den primären LLM-Analyzer.",
      llmModelHelp: "Entspricht SKILL_SCANNER_LLM_MODEL, z. B. kimi-k2.5.",
      llmBaseUrlHelp:
        "Entspricht SKILL_SCANNER_LLM_BASE_URL für den primären LLM-Endpunkt.",
      metaLlmIntegration: "Meta-LLM-Integration",
      metaLlmIntegrationHelp:
        "Meta-Analyzer-Konfiguration direkt aus einem AI-Gateway-Modell importieren.",
      metaLlmApiKeyHelp:
        "Entspricht SKILL_SCANNER_META_LLM_API_KEY für den Meta-Analyzer.",
      metaLlmModelHelp: "Entspricht SKILL_SCANNER_META_LLM_MODEL.",
      metaLlmBaseUrlHelp:
        "Entspricht SKILL_SCANNER_META_LLM_BASE_URL für den Meta-Analyzer-Endpunkt.",
      currentMode: "Aktueller Scanmodus",
      currentModeDesc:
        "Die Buttons im Dashboard für inkrementelle und vollständige Scans verwenden beide die hier ausgewählte Scanstärke. Der Unterschied liegt im Umfang, nicht in der Analyzer-Tiefe.",
      quickMode: "Quick-Modus",
      quickModeDesc: "Scans mit Quick-Analyzern ausführen.",
      deepMode: "Deep-Modus",
      deepModeDesc: "Scans mit Deep-Analyzern ausführen.",
      applySummary:
        "Beim Speichern werden außerdem die Quick/Deep-Richtlinien von ClawManager aktualisiert, die Umgebungsvariablen des skill-scanner Deployments angepasst und der Rollout bis zur sofort wirksamen Aktivierung abgewartet.",
      loadingConfig: "Konfiguration wird geladen...",
      timeoutSeconds: "Timeout (Sekunden)",
      invocationMethod: "Aufrufmethode",
      hide: "Ausblenden",
      reveal: "Anzeigen",
      selectAiGatewayModel: "AI-Gateway-Modell auswählen",
      analyzers: {
        static: "YAML + YARA statische Regelscans",
        bytecode: "Integritätsprüfung für Python-Bytecode",
        pipeline: "Befehls-Pipeline- und Taint-Analyse",
        behavioral: "AST-basierte Verhaltens- und Datenflussanalyse",
        llm: "Semantische Analyse mit externem LLM",
        meta: "Sekundäre Aggregation über Findings",
      },
    },
  },
};

export const translations: Record<Locale, TranslationTree> = {
  en: {
    app: {
      name: "ClawManager",
    },
    common: {
      loading: "Loading...",
      logout: "Logout",
      admin: "Admin",
      user: "User",
      comingSoon: "Coming Soon",
      language: "Language",
      refresh: "Refresh",
      retry: "Retry",
      create: "Create",
      save: "Save",
      cancel: "Cancel",
      close: "Close",
      overview: "Overview",
      logs: "Logs",
      description: "Description",
      type: "Type",
      status: "Status",
      createdAt: "Created At",
      lastUpdated: "Last Updated",
      open: "Open",
      stop: "Stop",
      start: "Start",
      restart: "Restart",
      delete: "Delete",
      cpu: "CPU",
      memory: "Memory",
      disk: "Disk",
      search: "Search",
      all: "All",
    },
    status: {
      all: "All",
      running: "Running",
      stopped: "Stopped",
      creating: "Creating",
      error: "Error",
      deleting: "Deleting",
    },
    nav: {
      dashboard: "Dashboard",
      adminDashboard: "Console",
      userDashboard: "Workspace",
      users: "Users",
      instances: "Instances",
      aiGateway: "AI Gateway",
      aiAudit: "AI Audit",
      costs: "Costs",
      riskRules: "Risk Rules",
      models: "Models",
      settings: "Settings",
      myInstances: "My Instances",
      openClawConfigs: "Resources",
      backToDashboard: "Back to Dashboard",
      backToUserDashboard: "Workspace",
      securityCenter: "Security Center",
      adminPanel: "Admin Panel",
    },
    adminLayout: adminLayoutTranslations.en,
    securityCenter: securityCenterTranslations.en,
    auth: {
      signInTitle: "Sign in to ClawManager",
      subtitle: "Virtual Desktop Management Platform",
      username: "Username",
      password: "Password",
      email: "Email",
      usernamePlaceholder: "Enter your username",
      passwordPlaceholder: "Enter your password",
      signIn: "Sign in",
      signingIn: "Signing in...",
      noAccount: "Don't have an account?",
      signUp: "Sign up",
      createAccount: "Create your account",
      joinToday: "Join ClawManager today",
      chooseUsername: "Choose a username",
      enterEmail: "Enter your email",
      createPassword: "Create a password (min 8 chars)",
      confirmPassword: "Confirm Password",
      confirmPasswordPlaceholder: "Confirm your password",
      createAccountAction: "Create account",
      creatingAccount: "Creating account...",
      alreadyHaveAccount: "Already have an account?",
      passwordsMismatch: "Passwords do not match",
      passwordTooShort: "Password must be at least 8 characters",
      changePassword: "Change Password",
      currentPassword: "Current Password",
      newPassword: "New Password",
      confirmNewPassword: "Confirm New Password",
      changePasswordAction: "Update Password",
      changePasswordDesc: "Update your account password from Settings.",
      changingPassword: "Updating...",
      passwordChanged: "Password changed successfully",
      changePasswordFailed: "Failed to change password",
      loginFailed: "Login failed",
    },
    admin: {
      dashboardTitle: "Console",
      userManagement: "User Management",
      userManagementDesc: "Manage users, roles, and quotas",
      instanceManagement: "Instance Management",
      instanceManagementDesc: "Manage virtual desktop instances",
      globalInstances: "Global Instances",
      globalInstancesDesc:
        "Search, filter, and operate all user instances from one place.",
      instanceSearchPlaceholder:
        "Search by instance, user, type, pod, or namespace...",
      allStatuses: "All Statuses",
      allTypes: "All Types",
      showingInstances: "Showing {filtered} of {total} instances",
      loadingInstances: "Loading instances...",
      noFilteredInstances: "No instances match the current filters.",
      instanceColumn: "Instance",
      userColumn: "User",
      typeOsColumn: "Type / OS",
      resourcesColumn: "Resources",
      k8sColumn: "K8s",
      actionsColumn: "Actions",
      updatedAtLabel: "Updated",
      userIdLabel: "user_id",
      gpuLabel: "GPU",
      failedToLoadInstances: "Failed to load instances",
      failedToStartInstance: "Failed to start instance",
      failedToStopInstance: "Failed to stop instance",
      failedToRestartInstance: "Failed to restart instance",
      failedToSyncInstance: "Failed to sync instance",
      failedToDeleteInstance: "Failed to delete instance",
      confirmDeleteInstance: "Delete instance {name}?",
      systemSettings: "System Settings",
      systemSettingsDesc: "Configure system settings",
      systemOverview: "System Overview",
      totalUsers: "Total Users",
      totalInstances: "Total Instances",
      runningInstances: "Running Instances",
      totalStorage: "Total Storage",
      instanceManagementStub:
        "This feature is under development. Check back soon!",
      systemSettingsStub: "This feature is under development. Check back soon!",
      addUser: "Add User",
      dashboardLoadFailed: "Failed to load dashboard statistics",
      clusterCommand: "Cluster Command",
      clusterHeroTitle: "Cluster infrastructure overview",
      clusterHeroDesc:
        "This dashboard should read like an operations cockpit, not a settings page. The key signals are surfaced first, and node pressure is one click away.",
      accountsWithAccess: "Accounts with access",
      provisionedDesktops: "Provisioned desktops",
      currentlyOnline: "Currently online",
      allocatedToInstances: "Allocated to instances",
      readiness: "Readiness",
      clusterStatusPending: "Cluster status pending",
      nodesHealthySchedulable:
        "{percent}% of nodes are healthy and schedulable.",
      hotNode: "Hot node",
      cpuRequested: "CPU requested",
      memoryRequested: "Memory requested",
      diskAllocated: "Disk allocated",
      pressureFocus: "Pressure focus",
      pressureFocusMem: "{percent}% mem",
      clusterResources: "Cluster Resources",
      capacityBoard: "Capacity board",
      waitingForClusterData: "Waiting for cluster data",
      nodesReadySummary: "{ready}/{total} nodes ready",
      nodeFleet: "Node fleet",
      nodes: "Nodes",
      healthyNodesScheduling: "Healthy nodes available for scheduling",
      computePressure: "Compute pressure",
      memoryPressure: "Memory pressure",
      persistentAllocation: "Persistent allocation",
      requestedVsAllocatable: "Requested vs allocatable",
      allocatedVsAllocatable: "Allocated vs allocatable",
      capacityCores: "Capacity {value} cores",
      capacityGiB: "Capacity {value} GiB",
      usage: "Usage",
      nodeMatrix: "Node Matrix",
      infrastructureTable: "Infrastructure table",
      infrastructureTableDesc:
        "Scan the fleet in one pass. Expand any node to inspect CPU, memory, disk, and kubelet details without leaving the dashboard.",
      node: "Node",
      health: "Health",
      ready: "Ready",
      role: "Role",
      internalIp: "Internal IP",
      pods: "Pods",
      cpuLoad: "CPU load",
      memoryLoad: "Memory load",
      inspect: "Inspect",
      nodeDossier: "Node dossier",
      kubeletVersion: "Kubelet Version",
      roles: "Roles",
      podCount: "Pod Count",
      diskSummary: "Disk Summary",
      resourceProfile: "Resource profile",
      noNodeData: "No node data returned from the cluster.",
      showingNodes: "Showing {from}-{to} of {total} nodes",
      prev: "Prev",
      nextPage: "Next",
      pageSummary: "Page {page} / {total}",
      collapse: "Collapse",
      viewDetails: "Details",
      notReady: "Not Ready",
      openSection: "Open section",
    },
    aiGatewayPage: {
      badge: "Governance Hub",
      title: "AI Gateway control center",
      subtitle:
        "All AI governance features live here: model catalog, audit traces, spend reporting, and configurable sensitive-content rules.",
      modelsDescription:
        "Manage normal and secure models, provider endpoints, prices, and activation state.",
      auditDescription:
        "Inspect trace IDs, request and response payloads, risk hits, routing decisions, and invocation details.",
      costsDescription:
        "Review token usage, estimated spend, internal secure-model cost, and trace-linked billing details.",
      riskRulesDescription:
        "Tune regex-based sensitive detection rules, severities, actions, and execution order.",
    },
    aiAuditPage: {
      title: "Recent AI Traces",
      subtitle:
        "Review governed model calls, trace IDs, token usage, status, and provider routing outcomes.",
      loadFailed: "Failed to load AI audit records",
      detailLoadFailed: "Failed to load trace detail",
      copyFailed: "Failed to copy trace ID",
      completed: "Completed",
      blocked: "Blocked",
      failed: "Failed",
      pending: "Pending",
      tokensOnPage: "Tokens On Page",
      traceTable: "Trace Table",
      traceTableSubtitle:
        "Search, filter, and inspect the most recent governed traces from one place.",
      searchPlaceholder: "Search trace, request, user, model...",
      allStatuses: "All statuses",
      modelPlaceholder: "Filter by model...",
      loading: "Loading audit records...",
      empty: "No AI audit records found.",
      trace: "Trace",
      user: "User",
      requested: "Requested",
      providerResult: "Provider Result",
      failureReason: "Failure Reason",
      usage: "Usage",
      action: "Action",
      copy: "Copy",
      copied: "Copied",
      noLatency: "No latency data",
      detailTitle: "Trace Detail",
      detailSubtitle:
        "Select a trace to inspect invocation payloads, audit events, and recorded costs.",
      detailLoading: "Loading trace detail...",
      noTraceSelected: "No trace selected yet.",
      executionFlow: "Execution Flow",
      executionFlowSubtitle:
        "View the full OpenClaw question flow, including model calls, tool calls, tool outputs, and the final response.",
      flowMinimap: "Minimap",
      flowMinimapSubtitle:
        "Shows the orchestration path and lets you jump straight to each step.",
      noFlowNodes:
        "No execution flow nodes were synthesized for this trace yet.",
      flowNode: "Flow Node",
      flowUserMessage: "User Message",
      flowLlmCall: "LLM Call",
      flowToolCall: "Tool Call",
      flowToolOutput: "Tool Output",
      flowAssistantResponse: "Assistant Response",
      flowAssistantMessage: "Assistant Message",
      nodeInput: "Input",
      nodeOutput: "Output",
      requestIdLabel: "Request ID",
      modelLabel: "Model",
      userLabel: "User: {user}",
      sessionLabel: "Session: {session}",
      copyTraceId: "Copy Trace ID",
      clear: "Clear",
      invocations: "Invocations",
      noInvocation: "No persisted invocation row was found for this trace.",
      payloads: "Payloads",
      auditEvents: "Audit Events",
      costRecords: "Cost Records",
      noCostRecords:
        "No cost records were generated for this trace. This usually means the request was blocked or failed before reaching a billable model call.",
      riskHits: "Risk Hits",
      noRiskHits: "No sensitive-content hits were recorded for this trace.",
      messages: "Messages",
      noMessages: "No persisted messages were recorded for this trace.",
    },
    costsPage: {
      badge: "Cost Overview",
      title: "AI spend in one frame",
      subtitle:
        "Review token volume, estimated spend, internal cost, and the traces behind unusual spikes.",
      loadFailed: "Failed to load AI cost overview",
      loading: "Loading AI cost overview...",
      promptTokens: "Prompt Tokens",
      promptTokensNote: "Inbound prompt volume",
      completionTokens: "Completion Tokens",
      completionTokensNote: "Generated output volume",
      estimatedSpend: "Estimated Spend",
      estimatedSpendNote: "Provider-style spend estimate",
      internalCost: "Internal Cost",
      internalCostNote: "Internal secure-model accounting",
      userTotals: "User Totals",
      userTotalsSubtitle: "Usage and spend aggregated by user",
      instanceTotals: "Instance Totals",
      instanceTotalsSubtitle: "Usage and spend aggregated by instance",
      recentRecords: "Recent Cost Records",
      recentRecordsSubtitle:
        "Search and page through trace-linked cost records, then jump straight into the audit trail.",
      searchPlaceholder: "Search trace, user, model...",
      pageSize10: "10 / page",
      pageSize20: "20 / page",
      pageSize50: "50 / page",
      apply: "Apply",
      trace: "Trace",
      user: "User",
      instance: "Instance",
      model: "Model",
      tokens: "Tokens",
      spend: "Spend",
      recorded: "Recorded",
      instanceId: "ID {id}",
      internalValue: "Internal {value} {currency}",
      openInAudit: "Open in Audit",
      showing: "Showing {from}-{to} of {total}",
      name: "Name",
      estimated: "Estimated",
      internal: "Internal",
      dailyTrend: "Daily Spend Trend",
      lastSevenDays: "Last 7 days",
      dailyTrendSubtitle:
        "Estimated spend and token movement across the current window.",
      sevenDayView: "7-day view",
      noTrendData: "No trend data yet.",
    },
    modelManagementPage: {
      title: "Managed Models",
      subtitle:
        "Configure secure and normal AI models at model granularity. Choose a vendor template with a fixed base URL, then load or type the provider model name.",
      addModel: "Add Model",
      finishEditing:
        "Finish or cancel the current edit before adding or editing another model.",
      loading: "Loading models...",
      loadFailed: "Failed to load models",
      noProviderModels: "No provider models were returned.",
      discoverFailed: "Failed to discover provider models",
      requiredFields:
        "Display name, vendor template, and provider model are required.",
      saveFailed: "Failed to save model",
      deleteFailed: "Failed to delete model",
      secure: "Secure",
      secureModel: "Secure model",
      active: "Active",
      inactive: "Inactive",
      providerModel: "Provider Model",
      currency: "Currency",
      baseUrl: "Base URL",
      inputPriceShort: "Input Price / 1M",
      outputPriceShort: "Output Price / 1M",
      edit: "Edit",
      displayName: "Display Name",
      displayNamePlaceholder: "Internal Secure GPT",
      vendorTemplate: "Vendor Template",
      vendorTemplatePlaceholder: "Select a vendor template",
      vendorTemplateSearchPlaceholder:
        "Search vendor name, alias, or base URL...",
      vendorTemplateEmpty: "No vendor templates match your search.",
      currentVendorTemplate: "Current Custom Endpoint",
      providerType: "Provider Type",
      protocol: "Protocol",
      baseUrlPlaceholder: "https://api.example.com/v1",
      fixedBaseUrlPlaceholder: "Select a vendor template to lock the base URL",
      fixedBaseUrlHelp:
        "Base URL is fixed by the selected vendor template and does not need manual editing.",
      editableBaseUrlHelp:
        "Local / Internal templates allow overriding the base URL for your own runtime or gateway.",
      localProtocolHelp:
        "Local / Internal models can switch between OpenAI-compatible and Anthropic APIs while keeping a custom Base URL.",
      apiKey: "API Key",
      optionalPlaceholder: "Optional",
      secretRef: "Secret Ref",
      secretRefPlaceholder: "namespace/secret-name:key",
      loadingProviderModels: "Loading provider models...",
      selectProviderModel: "Select a provider model",
      waitingDiscovery: "Waiting for automatic discovery",
      manualProviderModelPlaceholder: "Type a provider model name manually",
      discoveryHelp:
        "Model suggestions refresh automatically after vendor or credential changes, and you can still type a provider model manually.",
      discoveryCredentialsHelp:
        "Add an API key or secret ref to load provider model suggestions.",
      manualFallbackHelp:
        "Automatic discovery is unavailable right now. You can continue by typing the provider model manually.",
      manualEntryHelp: "This provider currently uses manual model entry.",
      currencyPlaceholder: "USD",
      inputPrice: "Input Price / 1M tokens",
      outputPrice: "Output Price / 1M tokens",
      descriptionPlaceholder: "Explain when this model should be used.",
      saving: "Saving...",
      empty:
        "No models configured yet. Add one to start governing secure and normal LLM access.",
      howItWorks: "How It Works",
      howItWorksSecure:
        "Secure models are reserved for sensitive prompts that cannot be sent to normal external models.",
      howItWorksActive:
        "Only active models can be exposed to future user-facing model pickers and routing policies.",
      howItWorksDiscovery:
        "Built-in vendor templates cover common OpenAI-compatible providers and local endpoints, and provider models can still be entered manually when discovery is unavailable.",
    },
    riskRulesPage: {
      title: "Configurable Sensitive Detection Rules",
      subtitle:
        "Adjust regex-based risk policies and choose whether each rule should allow or reroute to a secure model.",
      addRule: "Add Rule",
      totalRules: "Total Rules",
      enabled: "Enabled",
      disabled: "Disabled",
      allowActions: "Allow Actions",
      secureRouteActions: "Secure Route Actions",
      allCategories: "All categories",
      searchPlaceholder: "Search rule id, name, description, or pattern...",
      allSeverities: "All severities",
      allActions: "All actions",
      allStatuses: "All statuses",
      finishEditing:
        "Finish or cancel the current edit before creating or editing another rule.",
      loading: "Loading risk rules...",
      loadFailed: "Failed to load risk rules",
      requiredFields: "Rule ID, display name, and pattern are required.",
      duplicateRuleId: "Rule ID already exists.",
      saveFailed: "Failed to save risk rule",
      disableFailed: "Failed to disable risk rule",
      statusUpdateFailed: "Failed to update risk rule status",
      action: "Action",
      pattern: "Pattern",
      disable: "Disable",
      enable: "Enable",
      ruleId: "Rule ID",
      ruleIdPlaceholder: "email_address",
      ruleIdLocked:
        "Existing rule IDs are locked to avoid accidental remapping of live policies.",
      severity: "Severity",
      sortOrder: "Sort Order",
      regexPattern: "Regex Pattern",
      patternPlaceholder:
        "(?i)\\\\b[A-Z0-9._%+\\\\-]+@[A-Z0-9.\\\\-]+\\\\.[A-Z]{2,}\\\\b",
      descriptionPlaceholder: "Describe what this rule detects.",
      noRules: "No rules match the current filters.",
      testLab: "Rule Test Lab",
      testLabSubtitle:
        "Paste sample text to preview which enabled rules would match, or test the rule you are currently editing before saving it.",
      testEnabled: "Test Enabled Rules",
      testDraft: "Test Draft Rule",
      testing: "Testing...",
      sampleText: "Sample Text",
      samplePlaceholder:
        "Paste sample request content here to preview rule matches...",
      sampleRequired: "Please provide sample text to test.",
      noDraftRule: "No rule is currently being edited.",
      testFailed: "Failed to test risk rules",
      sensitive: "Sensitive",
      noMatch: "No Match",
      highestSeverity: "Highest severity: {value}",
      highestAction: "Highest action: {value}",
      noMatchesForSample: "No rules matched the provided sample text.",
      bulkNoSelection: "Select at least one rule first.",
      bulkStatusUpdateFailed: "Failed to update rule statuses in bulk",
      selectVisible: "Select visible",
      bulkEnable: "Bulk Enable",
      bulkDisable: "Bulk Disable",
      selectRule: "Select",
      categoryPersonal: "Personal",
      categoryCompany: "Company",
      categoryCustomer: "Customer",
      categorySecurity: "Security",
      categoryFinanceLegal: "Finance / Legal",
      categoryPolitical: "Political",
      categoryCustom: "Custom",
    },
    systemSettingsPage: {
      loadFailed: "Failed to load image settings",
      requiredFields: "Instance type and image are required.",
      duplicateType: "This instance type already has a card.",
      duplicateImage:
        "This runtime image already exists under the selected instance type.",
      saveFailed: "Failed to save image setting",
      deleteFailed: "Failed to delete image setting",
      runtimeImageCards: "Runtime Image Cards",
      runtimeImageCardsSubtitle:
        "Configure the image address used by each supported desktop runtime. Saved cards override the built-in defaults.",
      addCard: "Add Card",
      instanceType: "Instance Type",
      cardTitle: "Card Title",
      imageAddress: "Image Address",
      defaultImage: "Default image",
      empty:
        "No runtime image cards yet. Add one to override the default image for a desktop type.",
    },
    userManagementPage: {
      loading: "Loading users...",
      loadFailed: "Failed to load users",
      deleteFailed: "Failed to delete user",
      loadQuotaFailed: "Failed to load quota",
      updateQuotaFailed: "Failed to update quota",
      updateRoleFailed: "Failed to update role",
      createFailed: "Failed to create user",
      selectCsv: "Please select a CSV file to import",
      importFailed: "Failed to import users",
      importUsers: "Import Users",
      showingUsers: "Showing {from}-{to} of {total} users",
      noUsers: "No users found",
      importCompleted: "Import completed: {created} created, {failed} failed",
      expectedColumns: "Expected columns:",
      lineError: "Line {line}{username}",
      createdAccounts: "Created Accounts",
      quota: "Quota",
      initialPassword: "Initial password",
      supportedFormat: "Supported format",
      csvHeaders: "CSV file with headers:",
      csvHelp:
        "Username, Role, Max Instances, Max CPU Cores, Max Memory (GB) and Max Storage (GB) are required. Email, Password and Max GPU Count are optional. If Password is empty, the system default password will be used.",
      downloadTemplate: "Download CSV Template",
      importFile: "Import File",
      chooseFile: "Choose File",
      noFileSelected: "No file selected",
      importing: "Importing...",
      startImport: "Start Import",
      addNewUser: "Add New User",
      editQuotaFor: "Edit Quota for {username}",
      maxInstances: "Max Instances",
      maxCpuCores: "Max CPU Cores",
      maxMemoryGb: "Max Memory (GB)",
      maxStorageGb: "Max Storage (GB)",
      maxGpuCount: "Max GPU Count",
      changeRoleFor: "Change Role for {username}",
      confirmDeleteTitle: "Confirm Delete",
      confirmDeleteMessage:
        "Are you sure you want to delete user {username}? This action cannot be undone.",
    },
    errorBoundary: {
      title: "Something went wrong",
    },
    userDashboard: {
      subtitle:
        "Manage your virtual desktop instances and resources from your dashboard.",
      myInstances: "My Instances",
      running: "Running",
      storageUsed: "Storage Used",
      myResourceQuota: "My Resource Quota",
      loadingQuota: "Loading quota...",
      quotaUnavailable: "No quota information available",
      instances: "Instances",
      maxCpuCores: "Max CPU Cores",
      maxMemory: "Max Memory",
      maxStorage: "Max Storage",
      maxGpus: "Max GPUs",
      recentInstances: "Recent Instances",
      viewAll: "View All",
      quickActions: "Quick Actions",
      createNewInstance: "Create New Instance",
      viewAllInstances: "View All Instances",
      noInstancesYet: "No instances yet",
      noInstancesSubtitle:
        "Get started by creating your first virtual desktop instance",
      createInstance: "Create Instance",
    },
    instances: {
      listTitle: "My Instances",
      realTimeUpdates: "Real-time updates",
      connected: "Connected",
      disconnected: "Disconnected",
      createInstance: "Create Instance",
      searchPlaceholder: "Search by name, type, or OS...",
      noInstances: "No instances",
      noInstancesSubtitle:
        "Create your first virtual desktop instance to get started.",
      noMatchingInstances: "No matching instances",
      noMatchingInstancesSubtitle:
        "Try adjusting your filters or search query.",
      clearFilters: "Clear Filters",
      showingResults: "Showing {filtered} of {total} instances",
      failedToLoad: "Failed to load instances",
      failedToDelete: "Failed to delete instance",
      failedToStart: "Failed to start instance",
      failedToStop: "Failed to stop instance",
      confirmDelete:
        "Are you sure you want to delete this instance? This action cannot be undone.",
      details: "Details",
      instanceImage: "Instance Image",
      runtimeImageSelectionHint:
        "Choose which runtime image version should be used for this instance type.",
      runtimeImageUnavailable:
        "No enabled runtime image is currently available for this instance type.",
      operatingSystem: "Operating System",
      access: "Access",
      portalView: "Portal View",
      portalTitle: "Desktop Portal",
      portalWorkspace: "Instances",
      portalSelectInstance: "Select an instance",
      portalSelectInstanceSubtitle: "Choose a desktop from the list to begin.",
      portalUnavailable: "Desktop unavailable",
      portalUnavailableSubtitle: "Start a desktop instance to access it here.",
      timeline: "Timeline",
      storage: "Storage",
      resourceConfiguration: "Resource Configuration",
      kubernetesStatus: "Kubernetes Status",
      accessInfo: "Your instance is running and ready to access.",
      openDesktop: "Open Desktop",
      accessUrlUnavailable: "Access URL not available yet",
      startToAccess: "Start the instance to access the desktop",
      created: "Created",
      lastStarted: "Last Started",
      lastStopped: "Last Stopped",
      storageClass: "Storage Class",
      mountPath: "Mount Path",
      podName: "Pod Name",
      namespace: "Namespace",
      podIp: "Pod IP",
      podStatus: "Pod Status",
      loadingInstance: "Loading instance...",
      instanceNotFound: "Instance not found",
      backToInstances: "Back to Instances",
      basicInformation: "Basic Information",
      desktopAccess: "Desktop Access",
      logsPlaceholder: "Instance logs will be displayed here...",
      logsComingSoon: "Coming soon in Phase 6",
      startTheInstance: "Instance Stopped",
      startToAccessDesktop: "Start the instance to access the desktop.",
      generatingToken: "Generating access token...",
      accessError: "Access Error",
      readyToAccess: "Ready to Access",
      generateAccessPrompt: "Generate an access token to connect to {name}.",
      generateAccess: "Generate Access",
      expiresIn: "Expires in",
      refreshToken: "Refresh Token",
      accessTokenExpired: "Access token expired",
      regenerateToken: "Regenerate Token",
      instanceMustBeRunning: "Instance must be running to access",
      failedToGenerateAccessToken: "Failed to generate access token",
      expired: "Expired",
      createTitle: "Create Instance",
      stepOf: "Step {step} of 3: {label}",
      stepBasic: "Basic Information",
      stepType: "Select Type",
      stepConfig: "Configuration",
      instanceName: "Instance Name *",
      instanceNamePlaceholder: "e.g., my-desktop",
      minimumThreeChars: "Minimum 3 characters",
      descriptionOptional: "Description (optional)",
      descriptionPlaceholder: "Brief description of this instance...",
      selectInstanceType: "Select Instance Type",
      quickConfiguration: "Quick Configuration",
      customConfiguration: "Custom Configuration",
      cpuCores: "CPU Cores",
      memoryGb: "Memory (GB)",
      diskGb: "Disk (GB)",
      storageClassOptional: "Storage Class (optional)",
      enableGpu: "Enable GPU",
      gpuCount: "GPU Count",
      summary: "Summary",
      createFailed: "Failed to create instance",
      nameAlreadyExists: "An instance with this name already exists.",
      next: "Next",
      back: "Back",
      createNow: "Create Instance",
      creatingNow: "Creating...",
      defaultStorageClass: "Default",
      instanceIdLabel: "Instance ID",
      heroFallbackDescription:
        "A dedicated desktop workspace with direct cluster-backed resources, isolated storage, and one-click secure access.",
      allocatedCompute: "Allocated compute",
      reservedRam: "Reserved RAM",
      persistentDisk: "Persistent disk",
      launchLiveSession: "Launch the live desktop session",
      desktopAvailableAfterStart:
        "Desktop becomes available after the instance starts",
      instanceDossier: "Instance dossier",
      allocatedProfile: "Allocated profile",
      kubernetesSection: "Kubernetes",
      volumeMapping: "Volume mapping",
      workspaceSection: "Workspace",
      openClawWorkspace: "OpenClaw Workspace",
      openClawWorkspaceDesc:
        "Import or export the `.openclaw` folder as a `.tar.gz` archive up to 50 MiB.",
      runtimeWorkspace: "{runtime} Workspace",
      runtimeWorkspaceDesc:
        "Import or export the `{directory}` folder as a `.tar.gz` archive up to 50 MiB.",
      workspaceReady: "Ready",
      workspacePaused: "Paused",
      exportingOpenClaw: "Exporting...",
      exportOpenClaw: "Export .openclaw",
      importingOpenClaw: "Importing...",
      importOpenClaw: "Import .openclaw",
      importOpenClawSuccess: "OpenClaw workspace imported successfully.",
      exportingRuntimeWorkspace: "Exporting...",
      exportRuntimeWorkspace: "Export {directory}",
      importingRuntimeWorkspace: "Importing...",
      importRuntimeWorkspace: "Import {directory}",
      importRuntimeWorkspaceSuccess:
        "{runtime} workspace imported successfully.",
      openClawArchiveTooLarge: "Archive too large. Maximum size is 50 MiB.",
      importOpenClawFailed: "Failed to import .openclaw: {message}",
      exportOpenClawFailed: "Failed to export .openclaw: {message}",
      importRuntimeWorkspaceFailed:
        "Failed to import {directory}: {message}",
      exportRuntimeWorkspaceFailed:
        "Failed to export {directory}: {message}",
      memoryReserved: "Memory reserved",
      persistentStorage: "Persistent storage",
      gpuAttached: "GPU attached",
      waitingForRunningState:
        "Waiting for instance to become running before importing .openclaw.",
      timedOutWaitingForRunning:
        "Timed out waiting for the instance to become running for .openclaw import.",
      openClawImportTitle: "OpenClaw Import",
      openClawImportDesc:
        "Optional. Choose an exported `.openclaw` archive and it will be imported automatically after the instance starts.",
      optional: "Optional",
      changeOpenClawArchive: "Change .openclaw Archive",
      chooseOpenClawArchive: "Choose .openclaw Archive",
      changeRuntimeArchive: "Change {directory} Archive",
      chooseRuntimeArchive: "Choose {directory} Archive",
      remove: "Remove",
      selectedArchive: "Selected archive: {name}",
      noArchiveSelected:
        "No archive selected. The instance will be created with an empty .openclaw workspace.",
      noRuntimeArchiveSelected:
        "No archive selected. The instance will be created with an empty {directory} workspace.",
      quotaValidation: "Quota Validation",
      unableToLoadQuota:
        "Unable to load your quota. Create Instance stays disabled until quota is available.",
      requestedResourcesExceeded:
        "Requested resources exceed your assigned quota. Reduce the configuration before creating the instance.",
      quotaInstances: "Instances",
      checkingQuota: "Checking quota...",
      creatingAndImporting: "Creating and importing...",
      typeOptions: {
        ubuntu: {
          label: "Ubuntu Desktop",
          description: "Popular Linux distribution with GNOME desktop",
        },
        debian: {
          label: "Debian Desktop",
          description: "Stable and secure Linux distribution",
        },
        centos: {
          label: "CentOS Desktop",
          description: "Enterprise-class Linux distribution",
        },
        openclaw: {
          label: "OpenClaw Desktop",
          description: "Optimized desktop environment for OpenClaw",
        },
        webtop: {
          label: "Webtop Desktop",
          description:
            "Browser-based Linux desktop proxied through ClawManager",
        },
        hermes: {
          label: "Hermes Runtime",
          description: "Hermes runtime built on the webtop desktop base",
        },
        custom: {
          label: "Custom Image",
          description: "Use your own custom image",
        },
      },
      presetOptions: {
        small: {
          label: "Small",
          description: "Suitable for light tasks",
        },
        medium: {
          label: "Medium",
          description: "Good for development",
        },
        large: {
          label: "Large",
          description: "For heavy workloads",
        },
      },
      customPresetTitle: "Custom",
      customPresetDescription:
        "Manual sizing with Medium as the starting point.",
      customPresetEditing: "Editing",
      resourcePresetSummary: "{cpu} CPU • {memory} GB RAM • {disk} GB Disk",
      mediumDefaultPreset:
        "Medium default: {cpu} CPU • {memory} GB RAM • {disk} GB Disk",
      presetCpuShort: "CPU",
      presetRamShort: "RAM",
      presetDiskShort: "Disk",
      environmentVariables: "Environment Variables",
      clawManagerBuiltIns: "ClawManager Built-ins",
      hideBuiltIns: "Hide Built-ins",
      editBuiltIns: "Edit Built-ins",
      editBuiltInsCount: "Edit Built-ins ({count})",
      builtinOverridesConfigured:
        "{count} built-in override(s) configured. Expand to review or edit them.",
      usingBuiltInDefaults:
        "Using ClawManager defaults for {count} built-in variables.",
      builtinOverrideHelp:
        "Add only the built-ins you want to override. Unlisted variables will keep their default injected values.",
      addBuiltinVariable: "Add Built-in Variable",
      noBuiltinOverrides: "No built-in overrides added yet.",
      defaultValue: "Default: {value}",
      variable: "Variable",
      overrideValue: "Override Value",
      overrideValuePlaceholder: "Override value",
      actionLabel: "Action",
      customVariables: "Custom Variables",
      addVariable: "Add Variable",
      noCustomEnvironmentVariables: "No custom environment variables yet.",
      variableNamePlaceholder: "VARIABLE_NAME",
      variableValuePlaceholder: "value",
      customEnvNameRequired: "Custom environment variable name is required.",
      invalidEnvName: "Invalid environment variable name: {name}",
      reservedBuiltinEnvName:
        "{name} is a ClawManager built-in variable. Edit it in the built-in section instead.",
      duplicateEnvName: "Duplicate environment variable name: {name}",
      openClawInjection: "OpenClaw Injection",
      runtimeInjection: "{runtime} Injection",
      selectedCount: "{count} selected",
      noReusableSkillsSelected: "No reusable skills selected.",
      noAvailableSkillsForInjection:
        "No available skills. Import skills from the resource center first.",
      skillRiskVersionLabel: "{key} · risk {risk} · v{version}",
      skillPageSummary: "Page {page} of {totalPages} · {totalSkills} skills",
      archiveImport: "Archive Import",
      archiveModeRequiresFile: "Required for archive mode",
      envInjection: "Env Injection",
      noEnvOverridesConfigured:
        "No container environment overrides configured.",
      channelInjection: "Channel Injection",
      archiveSkipsChannelInjection:
        "Archive mode skips resource-based channel injection.",
      compilingOpenClawPreview: "Compiling OpenClaw resource preview...",
      compilingRuntimePreview: "Compiling runtime resource preview...",
      noChannelsSelectedForInjection: "No channels selected for injection.",
      skillInjection: "Skill Injection",
      envManagedProxyPath: "ClawManager managed proxy path",
      envGeneratedAtRuntime: "ClawManager generated at runtime",
      envAssignedAfterCreation: "Assigned after creation",
      envManagedAtRuntime: "ClawManager managed at runtime",
      envDescDesktopTitleWebtop:
        "Desktop window title injected for the LinuxServer Webtop container.",
      envDescDesktopTitleOpenClaw:
        "Desktop title shown by the OpenClaw browser desktop image.",
      envDescProxySubfolder:
        "Path prefix used by the ClawManager reverse proxy for browser access.",
      envDescLlmBaseUrl:
        "OpenClaw gateway base URL generated by ClawManager at runtime.",
      envDescLlmApiKey:
        "Per-instance API key minted by ClawManager for the gateway.",
      envDescLlmModel:
        "Gateway model catalog JSON injected into the OpenClaw workspace, with auto kept as the default entry.",
      envDescLlmProvider: "Provider hint for the OpenClaw workspace.",
      envDescInstanceToken:
        "Per-instance token generated by ClawManager for workspace access.",
      envDescOpenAiBaseUrl:
        "Compatibility alias for the OpenAI-compatible gateway base URL.",
      envDescOpenAiApiBase:
        "Compatibility alias for the OpenAI-compatible gateway base URL.",
      envDescOpenAiApiKey: "Compatibility alias for the gateway API key.",
      envDescOpenAiModel: "Compatibility alias for the default model name.",
      envDescAgentEnabled:
        "Toggles the ClawManager instance agent inside OpenClaw.",
      envDescAgentBaseUrl:
        "Base URL used by the in-instance agent control plane client.",
      envDescAgentBootstrapToken:
        "Bootstrap token generated by ClawManager for the in-instance agent.",
      envDescAgentDiskLimitBytes: "Disk quota injected for the instance agent.",
      envDescAgentInstanceId:
        "Runtime instance identifier provided to the in-instance agent.",
      envDescAgentPersistentDir:
        "Persistent workspace path mounted into the OpenClaw container.",
      envDescAgentProtocolVersion:
        "Protocol version expected by ClawManager agent control.",
      gpuLabel: "GPU",
      cpuCoresValue: "{value} cores",
      gpuCountValue: "{count} GPU(s)",
      memoryLabel: "Memory",
      storageLabel: "Storage",
      gpuDisabled: "Disabled",
      noOpenClawArchiveSelected: "No .openclaw archive selected",
      live: "Live",
      notAvailable: "N/A",
      runtimeCommandFailed: "Failed to run {command}",
      failedToAttachSkill: "Failed to attach skill",
      failedToRemoveSkill: "Failed to remove skill",
      kubernetesStatusTitle: "Pod and infrastructure status",
      infrastructureReady: "Infra ready",
      skillsSection: "Skills",
      skillManagement: "Skill Management",
      selectSkill: "Select a skill",
      installingSkill: "Installing...",
      installSkill: "Install Skill",
      noSkillsReported: "No skills have been reported for this instance yet.",
      skillFallback: "Skill #{id}",
      lastSeenAt: "last seen {value}",
      removingSkill: "Removing...",
      removeSkill: "Remove",
      skillPagination: "Showing {from}-{to} of {total} skills",
      previous: "Previous",
      nextPage: "Next",
      timelineSubtitle: "Instance operations and runtime history",
      timelineEvents: "{count} events",
      noRuntimeActivity: "No runtime activity yet.",
      minimap: "Minimap",
      runtimeSummary: "Runtime Summary",
      agentReportedStatus: "Agent reported status",
      fresh: "Fresh",
      operatingSystemShort: "OS",
      openClawShort: "OpenClaw",
      agents: "Agents",
      channels: "Channels",
      agentStatusLabel: "Agent {status}",
      gatewayStatusLabel: "Gateway {status}",
      agentId: "Agent ID",
      agentVersion: "Agent Version",
      protocol: "Protocol",
      lastHeartbeat: "Last heartbeat",
      lastReport: "Last report",
      skillSourceUploaded: "Uploaded",
      skillSourceDiscovered: "Discovered",
      skillRiskNone: "Safe",
      skillRiskLow: "Low",
      skillRiskMedium: "Medium",
      skillRiskHigh: "High",
      skillRiskUnknown: "Unknown",
      timelineInstanceCreated: "Instance created",
      timelineInstanceCreatedDetail: "{name} was provisioned as {type}.",
      timelineInstanceStarted: "Instance started",
      timelineInstanceStartedDetail:
        "Infrastructure start was recorded for this instance.",
      timelineInstanceStopped: "Instance stopped",
      timelineInstanceStoppedDetail:
        "Infrastructure stop was recorded for this instance.",
      timelineAgentRegistered: "Agent registered",
      timelineAgentRegisteredDetail:
        "{agentId} connected to ClawManager using protocol {protocol}.",
      timelineRuntimeReported: "Runtime status reported",
      timelineRuntimeReportedDetail:
        "Agent reported gateway status {gatewayStatus} and infra status {infraStatus}.",
      timelinePodStatusObserved: "Pod status observed",
      timelinePodStatusObservedDetail:
        "Kubernetes currently reports pod status {status}.",
      timelineCommandWithError: "{status}: {error}",
      timelineCommandWithIdempotency: "{status} · idempotency {key}",
      timelineSectionInstance: "instance",
      timelineSectionInfra: "infra",
      timelineSectionAgent: "agent",
      timelineSectionRuntime: "runtime",
      timelineSectionKubernetes: "k8s",
      timelineSectionCommand: "command",
      metricCpu: "CPU",
      metricCpuDetail:
        "{cores} cores · load 1m {load1} · 5m {load5} · 15m {load15}",
      metricMemory: "Memory",
      metricMemoryDetail: "{used} used / {total}",
      metricDisk: "Disk",
      metricDiskDetail: "{free} free / {total}",
      metricNetwork: "Network",
      metricNetworkDetail:
        "{addresses} addresses across {interfaces} interfaces",
      metricLegendDown: "Down",
      metricLegendUp: "Up",
      metricTrafficDetail: "Inbound {inbound} · Outbound {outbound}",
    },
    openClawResourcesPage: {
      title: "OpenClaw Resource Management",
      tabs: {
        resources: "Resources",
        bundles: "Bundles",
        injections: "Injection Records",
      },
      resourceTypesTitle: "Resource Types",
      searchPlaceholder: "Search resources...",
      resourceListHint:
        "Click a resource card to edit it in a popup instead of editing inline.",
      loadingResources: "Loading resources...",
      noResources: 'No resources in this type yet. Click "New" to create one.',
      enabled: "Enabled",
      disabled: "Disabled",
      thisResourceType: "This resource type",
      notConfigurableYet: "{type} is not configurable yet.",
      onlyChannelConfigurable:
        "Channel resources are supported today. Skill, Agent, and Scheduled Task editors will be added in a later update.",
      bundlesSubtitle:
        "Compose reusable OpenClaw bootstrap packages in a dedicated popup editor.",
      loadingBundles: "Loading bundles...",
      noBundles: 'No bundles yet. Click "New Bundle" to create one.',
      bundleResourceCount: "{count} resource(s)",
      injectionsSubtitle:
        "Snapshots are saved at instance creation time and reused on restart.",
      snapshot: "Snapshot",
      mode: "Mode",
      resources: "Resources",
      envCount: "Env Count",
      created: "Created",
      loadingSnapshots: "Loading snapshots...",
      noInjectionRecords: "No OpenClaw injection records yet.",
      paginationSummary: "{pageSize} per page, showing {from}-{to}",
      paginationPrev: "Previous",
      paginationNext: "Next",
      skillUploadHint:
        "Upload `.zip` only. Each top-level directory is imported as one skill.",
      loadingSkills: "Loading skills...",
      noSkills: "No skills uploaded yet.",
      skillMeta: "{key} · risk {risk} · used by {count} instance(s)",
      recordModes: {
        none: "None",
        manual: "Manual",
        bundle: "Bundle",
        archive: "Archive",
      },
      recordStatuses: {
        compiled: "Compiled",
        active: "Active",
        failed: "Failed",
      },
      editResourceTitle: "Edit Resource",
      newResourceTitle: "New Resource",
      editResourceSubtitle:
        "Adjust metadata and JSON in a focused popup editor.",
      newResourceSubtitle:
        "Create a new OpenClaw resource without exposing the full editor on the page.",
      resourceKey: "Resource Key",
      name: "Name",
      tags: "Tags",
      tagsPlaceholder: "comma,separated,tags",
      channelTemplate: "Channel Template",
      chooseStarterTemplate: "Choose a starter template",
      channelTemplateHint:
        "Only Slack, Telegram, DingTalk, and Feishu are supported here. Start in form mode, then switch to JSON when you need the full config surface.",
      templateKey: "key: {key}",
      invalidChannelJson:
        "This channel JSON is currently invalid. Switch to JSON mode to fix it, then come back to the form.",
      contentJson: "Content JSON",
      editBundleTitle: "Edit Bundle",
      newBundleTitle: "New Bundle",
      editBundleSubtitle:
        "Refine a reusable bootstrap package in a focused popup editor.",
      newBundleSubtitle:
        "Compose a new reusable bundle without leaving the resources list behind.",
      bundleName: "Bundle Name",
      bundleResources: "Bundle Resources",
      noResourcesForGroup: "No {type} resources yet.",
      actions: {
        new: "New",
        newBundle: "New Bundle",
        loadTemplate: "Load Template",
        saveResource: "Save Resource",
        createResource: "Create Resource",
        validateJson: "Validate JSON",
        clone: "Clone",
        saveBundle: "Save Bundle",
        createBundle: "Create Bundle",
      },
      resourceTypes: {
        channel: "Channel",
        skill: "Skill",
        session_template: "Session Template",
        log_policy: "Log Policy",
        agent: "Agent",
        scheduled_task: "Scheduled Task",
      },
      templateCategories: {
        builtin: "Built-in",
        plugin: "Plugin",
      },
      templates: {
        telegram: {
          label: "Telegram",
          description:
            "Telegram Bot API channel with DM and group policy controls.",
        },
        dingtalkConnector: {
          label: "DingTalk",
          description:
            "DingTalk channel with client credentials and sender allowlist controls.",
        },
        slack: {
          label: "Slack",
          description: "Slack workspace app powered by Bolt.",
        },
        feishu: {
          label: "Feishu / Lark",
          description:
            "Feishu or Lark plugin channel with account-aware defaults.",
        },
      },
      editorModes: {
        form: "Form",
        json: "JSON",
      },
      channelEditors: {
        dingtalkConnector: {
          title: "DingTalk Channel Editor",
          description:
            "Start with the client credential form, or switch to JSON when you need the full config surface.",
          fields: {
            clientId: {
              label: "Client ID",
              placeholder: "ding-xxxxxxxxxxxxxx",
            },
            clientSecret: {
              label: "Client Secret",
              placeholder: "client secret",
            },
          },
        },
        feishu: {
          title: "Feishu Channel Editor",
          description:
            "Start with the main account form, or switch to JSON when you need the full config surface.",
          fields: {
            appId: {
              label: "App ID",
              placeholder: "cli_xxx",
            },
            appSecret: {
              label: "App Secret",
              placeholder: "app secret",
            },
          },
        },
        slack: {
          title: "Slack Channel Editor",
          description:
            "Start with the token form, or switch to JSON when you need the full config surface.",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "xoxb-...",
            },
            appToken: {
              label: "App Token",
              placeholder: "xapp-...",
            },
          },
        },
        telegram: {
          title: "Telegram Channel Editor",
          description:
            "Start with the bot token form, or switch to JSON when you need the full config surface.",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "123456:ABCDEF",
            },
          },
        },
      },
      notices: {
        resourceUpdated: "Resource updated.",
        resourceCreated: "Resource created.",
        resourceDeleted: "Resource deleted.",
        resourceCloned: "Resource cloned.",
        resourceJsonValid: "Resource JSON is valid.",
        templateLoaded: "Loaded {name} template.",
        bundleUpdated: "Bundle updated.",
        bundleCreated: "Bundle created.",
        bundleDeleted: "Bundle deleted.",
        bundleCloned: "Bundle cloned.",
        skillArchiveImported: "Skill archive imported successfully.",
        skillDeleted: "Skill deleted successfully.",
      },
      errors: {
        loadFailed: "Failed to load OpenClaw resources.",
        saveResource: "Failed to save resource.",
        validationFailed: "Failed to validate resource JSON.",
        deleteResource: "Failed to delete resource.",
        cloneResource: "Failed to clone resource.",
        saveBundle: "Failed to save bundle.",
        deleteBundle: "Failed to delete bundle.",
        cloneBundle: "Failed to clone bundle.",
        importSkillArchive: "Failed to import skill archive.",
        deleteSkill: "Failed to delete skill.",
        downloadSkill: "Failed to download skill.",
      },
      skillActions: {
        chooseFile: "Choose File",
        uploadArchive: "Upload Skill Archive",
        download: "Download",
      },
      risks: {
        none: "safe",
        low: "low",
        medium: "medium",
        high: "high",
        unknown: "unknown",
      },
      confirms: {
        deleteResource: 'Delete resource "{name}"?',
        deleteBundle: 'Delete bundle "{name}"?',
      },
    },
    openClawInjectionSection: {
      title: "OpenClaw Resource Injection",
      subtitle:
        "Choose how this instance bootstraps OpenClaw. Click an active option again if you want to cancel the selection.",
      optional: "Optional",
      modes: {
        manual: "Manual resources",
        bundle: "Bundle",
        archive: "Archive import",
      },
      loading: "Loading resource management assets...",
      chooseBundle: "Choose Bundle",
      selectBundle: "Select a bundle",
      bundleOptionCount: "{count} resources",
      channel: "Channel",
      noChannelResources: "No channel resources available.",
      errors: {
        chooseBundle: "Choose a bundle before continuing.",
        chooseResource: "Choose at least one resource before continuing.",
        compileFailed: "Failed to compile OpenClaw bootstrap preview.",
      },
    },
  },
  zh: {
    app: { name: "ClawManager" },
    common: {
      loading: "加载中...",
      logout: "退出登录",
      admin: "管理员",
      user: "用户",
      comingSoon: "即将上线",
      language: "语言",
      refresh: "刷新",
      retry: "重试",
      create: "创建",
      save: "保存",
      cancel: "取消",
      close: "关闭",
      overview: "概览",
      logs: "日志",
      description: "描述",
      type: "类型",
      status: "状态",
      createdAt: "创建时间",
      lastUpdated: "最后更新时间",
      open: "打开",
      stop: "停止",
      start: "启动",
      restart: "重启",
      delete: "删除",
      cpu: "CPU",
      memory: "内存",
      disk: "磁盘",
      search: "搜索",
      all: "全部",
    },
    status: {
      all: "全部",
      running: "运行中",
      stopped: "已停止",
      creating: "创建中",
      error: "错误",
      deleting: "删除中",
    },
    nav: {
      dashboard: "仪表盘",
      adminDashboard: "控制台",
      userDashboard: "工作台",
      users: "用户",
      instances: "实例",
      aiGateway: "AI 网关",
      aiAudit: "AI 审计",
      costs: "成本",
      riskRules: "风控规则",
      models: "模型",
      settings: "设置",
      myInstances: "我的实例",
      openClawConfigs: "资源管理",
      backToDashboard: "返回仪表盘",
      backToUserDashboard: "工作台",
      securityCenter: "安全中心",
      adminPanel: "管理后台",
    },
    adminLayout: adminLayoutTranslations.zh,
    securityCenter: securityCenterTranslations.zh,
    auth: {
      signInTitle: "登录 ClawManager",
      subtitle: "虚拟桌面管理平台",
      username: "用户名",
      password: "密码",
      email: "邮箱",
      usernamePlaceholder: "请输入用户名",
      passwordPlaceholder: "请输入密码",
      signIn: "登录",
      signingIn: "登录中...",
      noAccount: "还没有账号？",
      signUp: "注册",
      createAccount: "创建你的账号",
      joinToday: "立即加入 ClawManager",
      chooseUsername: "设置用户名",
      enterEmail: "请输入邮箱",
      createPassword: "创建密码（至少 8 位）",
      confirmPassword: "确认密码",
      confirmPasswordPlaceholder: "再次输入密码",
      createAccountAction: "创建账号",
      creatingAccount: "创建中...",
      alreadyHaveAccount: "已有账号？",
      passwordsMismatch: "两次输入的密码不一致",
      passwordTooShort: "密码至少需要 8 位",
      changePassword: "修改密码",
      currentPassword: "当前密码",
      newPassword: "新密码",
      confirmNewPassword: "确认新密码",
      changePasswordAction: "更新密码",
      changePasswordDesc: "在设置中更新你的账户密码。",
      changingPassword: "更新中...",
      passwordChanged: "密码修改成功",
      changePasswordFailed: "修改密码失败",
      loginFailed: "登录失败",
    },
    admin: {
      dashboardTitle: "控制台",
      userManagement: "用户管理",
      userManagementDesc: "管理用户、角色和配额",
      instanceManagement: "实例管理",
      instanceManagementDesc: "管理虚拟桌面实例",
      globalInstances: "全局实例",
      globalInstancesDesc: "在一个页面中搜索、筛选并操作所有用户实例。",
      instanceSearchPlaceholder: "按实例、用户、类型、Pod 或命名空间搜索...",
      allStatuses: "全部状态",
      allTypes: "全部类型",
      showingInstances: "显示 {filtered} / {total} 个实例",
      loadingInstances: "正在加载实例...",
      noFilteredInstances: "没有符合当前筛选条件的实例。",
      instanceColumn: "实例",
      userColumn: "用户",
      typeOsColumn: "类型 / 系统",
      resourcesColumn: "资源",
      k8sColumn: "K8s",
      actionsColumn: "操作",
      updatedAtLabel: "更新时间",
      userIdLabel: "用户 ID",
      gpuLabel: "GPU",
      failedToLoadInstances: "加载实例失败",
      failedToStartInstance: "启动实例失败",
      failedToStopInstance: "停止实例失败",
      failedToRestartInstance: "重启实例失败",
      failedToSyncInstance: "同步实例失败",
      failedToDeleteInstance: "删除实例失败",
      confirmDeleteInstance: "确认删除实例 {name} 吗？",
      systemSettings: "系统设置",
      systemSettingsDesc: "配置系统设置",
      systemOverview: "系统概览",
      totalUsers: "用户总数",
      totalInstances: "实例总数",
      runningInstances: "运行中实例",
      totalStorage: "总存储",
      instanceManagementStub: "该功能仍在开发中，请稍后查看。",
      systemSettingsStub: "该功能仍在开发中，请稍后查看。",
      addUser: "添加用户",
      dashboardLoadFailed: "加载仪表盘统计失败",
      clusterCommand: "集群指挥台",
      clusterHeroTitle: "集群基础信息概览",
      clusterHeroDesc:
        "这个仪表盘应该像运维驾驶舱，而不是设置页。关键指标需要优先呈现，节点压力应一键可见。",
      accountsWithAccess: "可访问账户",
      provisionedDesktops: "已创建桌面",
      currentlyOnline: "当前在线",
      allocatedToInstances: "已分配给实例",
      readiness: "就绪度",
      clusterStatusPending: "集群状态获取中",
      nodesHealthySchedulable: "{percent}% 的节点健康且可调度。",
      hotNode: "高压节点",
      cpuRequested: "CPU 已申请",
      memoryRequested: "内存已申请",
      diskAllocated: "磁盘已分配",
      pressureFocus: "压力焦点",
      pressureFocusMem: "内存 {percent}%",
      clusterResources: "集群资源",
      capacityBoard: "容量看板",
      waitingForClusterData: "等待集群数据",
      nodesReadySummary: "{ready}/{total} 个节点就绪",
      nodeFleet: "节点舰队",
      nodes: "节点",
      healthyNodesScheduling: "可用于调度的健康节点",
      computePressure: "算力压力",
      memoryPressure: "内存压力",
      persistentAllocation: "持久化分配",
      requestedVsAllocatable: "申请量 / 可分配量",
      allocatedVsAllocatable: "分配量 / 可分配量",
      capacityCores: "总容量 {value} 核",
      capacityGiB: "总容量 {value} GiB",
      usage: "使用率",
      nodeMatrix: "节点矩阵",
      infrastructureTable: "基础设施表",
      infrastructureTableDesc:
        "一屏扫描整个集群。展开任意节点即可查看 CPU、内存、磁盘和 kubelet 详情，无需离开当前页面。",
      node: "节点",
      health: "健康",
      ready: "就绪",
      role: "角色",
      internalIp: "内网 IP",
      pods: "Pod 数",
      cpuLoad: "CPU 负载",
      memoryLoad: "内存负载",
      inspect: "查看",
      nodeDossier: "节点档案",
      kubeletVersion: "Kubelet 版本",
      roles: "角色",
      podCount: "Pod 数量",
      diskSummary: "磁盘摘要",
      resourceProfile: "资源画像",
      noNodeData: "集群没有返回节点数据。",
      showingNodes: "显示第 {from}-{to} 项，共 {total} 个节点",
      prev: "上一页",
      nextPage: "下一页",
      pageSummary: "第 {page} / {total} 页",
      collapse: "收起",
      viewDetails: "详情",
      notReady: "未就绪",
      openSection: "进入模块",
    },
    aiGatewayPage: {
      badge: "治理中心",
      title: "AI 网关控制中心",
      subtitle: "模型目录、审计追踪、成本报表和敏感内容规则都统一收口在这里。",
      modelsDescription:
        "管理普通模型和安全模型、Provider 地址、价格以及启停状态。",
      auditDescription:
        "查看 trace、请求与响应负载、风险命中、路由决策和调用明细。",
      costsDescription:
        "查看 token 用量、预估费用、内部安全模型成本以及关联账单明细。",
      riskRulesDescription: "调整正则敏感规则、严重级别、动作和执行顺序。",
    },
    aiAuditPage: {
      title: "最近 AI Trace",
      subtitle: "查看受管模型调用、Trace、Token 用量、状态和实际路由结果。",
      loadFailed: "加载 AI 审计记录失败",
      detailLoadFailed: "加载 Trace 详情失败",
      copyFailed: "复制 Trace ID 失败",
      completed: "已完成",
      blocked: "已拦截",
      failed: "失败",
      pending: "处理中",
      tokensOnPage: "本页 Token",
      traceTable: "Trace 列表",
      traceTableSubtitle: "在一个表里完成搜索、筛选和检查最近的受管 Trace。",
      searchPlaceholder: "搜索 trace、request、user、model...",
      allStatuses: "全部状态",
      modelPlaceholder: "按模型筛选...",
      loading: "正在加载审计记录...",
      empty: "暂无 AI 审计记录。",
      trace: "Trace",
      user: "用户",
      requested: "请求模型",
      providerResult: "实际结果",
      failureReason: "失败原因",
      usage: "用量",
      action: "操作",
      copy: "复制",
      copied: "已复制",
      noLatency: "暂无延迟数据",
      detailTitle: "Trace 详情",
      detailSubtitle: "选择一条 Trace 查看调用负载、审计事件和成本记录。",
      detailLoading: "正在加载 Trace 详情...",
      noTraceSelected: "尚未选择 Trace。",
      executionFlow: "执行流程",
      executionFlowSubtitle:
        "把一次 OpenClaw 问答中的模型调用、工具调用、工具输出和最终回答串起来查看。",
      flowMinimap: "流程缩略图",
      flowMinimapSubtitle:
        "显示调度流程，点击任一步骤都可以快速跳转到对应位置。",
      noFlowNodes: "这条 Trace 还没有可视化流程节点。",
      flowNode: "流程节点",
      flowUserMessage: "用户消息",
      flowLlmCall: "模型调用",
      flowToolCall: "工具调用",
      flowToolOutput: "工具输出",
      flowAssistantResponse: "助手回答",
      flowAssistantMessage: "助手消息",
      nodeInput: "输入",
      nodeOutput: "输出",
      requestIdLabel: "请求 ID",
      modelLabel: "模型",
      userLabel: "用户：{user}",
      sessionLabel: "会话：{session}",
      copyTraceId: "复制 Trace ID",
      clear: "清除",
      invocations: "调用记录",
      noInvocation: "这条 Trace 没有持久化的 invocation 记录。",
      payloads: "负载内容",
      auditEvents: "审计事件",
      costRecords: "成本记录",
      noCostRecords:
        "这条 Trace 没有生成成本记录，通常表示请求在进入计费模型调用前就被拦截或失败。",
      riskHits: "风险命中",
      noRiskHits: "这条 Trace 没有记录到敏感命中。",
      messages: "消息记录",
      noMessages: "这条 Trace 没有持久化消息。",
    },
    costsPage: {
      badge: "成本概览",
      title: "一屏查看 AI 成本",
      subtitle:
        "查看 token 规模、预估花费、内部成本，以及异常峰值对应的 trace。",
      loadFailed: "加载 AI 成本概览失败",
      loading: "正在加载 AI 成本概览...",
      promptTokens: "输入 Token",
      promptTokensNote: "输入提示词总量",
      completionTokens: "输出 Token",
      completionTokensNote: "模型生成内容总量",
      estimatedSpend: "预估费用",
      estimatedSpendNote: "按 Provider 单价估算",
      internalCost: "内部成本",
      internalCostNote: "安全模型内部核算",
      userTotals: "用户汇总",
      userTotalsSubtitle: "按用户聚合用量和费用",
      instanceTotals: "实例汇总",
      instanceTotalsSubtitle: "按实例聚合用量和费用",
      recentRecords: "最近成本记录",
      recentRecordsSubtitle:
        "搜索并分页查看带 trace 的成本记录，然后直接跳转审计详情。",
      searchPlaceholder: "搜索 trace、用户、模型...",
      pageSize10: "10 / 页",
      pageSize20: "20 / 页",
      pageSize50: "50 / 页",
      apply: "应用",
      trace: "Trace",
      user: "用户",
      instance: "实例",
      model: "模型",
      tokens: "Token",
      spend: "费用",
      recorded: "记录时间",
      instanceId: "ID {id}",
      internalValue: "内部 {value} {currency}",
      openInAudit: "打开审计",
      showing: "显示 {from}-{to} / 共 {total}",
      name: "名称",
      estimated: "预估",
      internal: "内部",
      dailyTrend: "每日费用趋势",
      lastSevenDays: "最近 7 天",
      dailyTrendSubtitle: "当前窗口内的预估费用和 Token 变化。",
      sevenDayView: "7 天视图",
      noTrendData: "暂无趋势数据。",
    },
    modelManagementPage: {
      title: "模型管理",
      subtitle:
        "按模型粒度配置安全模型和普通模型。通过厂家模板选择固定 Base URL，再自动发现或手动填写 Provider Model。",
      addModel: "添加模型",
      finishEditing: "请先完成或取消当前编辑，再添加或编辑其他模型。",
      loading: "正在加载模型...",
      loadFailed: "加载模型失败",
      noProviderModels: "Provider 没有返回模型列表。",
      discoverFailed: "自动发现 Provider 模型失败",
      requiredFields: "显示名称、厂家模板和 Provider Model 都是必填项。",
      saveFailed: "保存模型失败",
      deleteFailed: "删除模型失败",
      secure: "安全",
      secureModel: "安全模型",
      active: "启用",
      inactive: "停用",
      providerModel: "Provider Model",
      currency: "币种",
      baseUrl: "Base URL",
      inputPriceShort: "输入价格 / 1M",
      outputPriceShort: "输出价格 / 1M",
      edit: "编辑",
      displayName: "显示名称",
      displayNamePlaceholder: "内部安全模型",
      vendorTemplate: "厂家模板",
      vendorTemplatePlaceholder: "选择一个厂家模板",
      vendorTemplateSearchPlaceholder: "搜索厂家名、别名或 Base URL...",
      vendorTemplateEmpty: "没有匹配的厂家模板。",
      currentVendorTemplate: "当前自定义地址",
      providerType: "Provider 类型",
      protocol: "协议",
      baseUrlPlaceholder: "https://api.example.com/v1",
      fixedBaseUrlPlaceholder: "选择厂家模板后会自动固定 Base URL",
      fixedBaseUrlHelp: "Base URL 由厂家模板固定，无需手动填写。",
      editableBaseUrlHelp:
        "Local / Internal 模板允许你按自己的运行时或网关地址修改 Base URL。",
      localProtocolHelp:
        "Local / Internal 类型现在可以在 OpenAI-compatible 和 Anthropic 协议之间切换，同时继续使用自定义 Base URL。",
      apiKey: "API Key",
      optionalPlaceholder: "可选",
      secretRef: "Secret Ref",
      secretRefPlaceholder: "namespace/secret-name:key",
      loadingProviderModels: "正在加载 Provider 模型...",
      selectProviderModel: "选择一个 Provider Model",
      waitingDiscovery: "等待自动发现",
      manualProviderModelPlaceholder: "手动填写 Provider Model",
      discoveryHelp:
        "切换厂家模板或修改凭据后会自动刷新模型建议；如果列表里没有，也可以直接手填 Provider Model。",
      discoveryCredentialsHelp:
        "填写 API Key 或 Secret Ref 后即可加载 Provider 模型建议。",
      manualFallbackHelp:
        "当前无法自动发现模型，你仍然可以手动填写 Provider Model。",
      manualEntryHelp: "当前 Provider 使用手动填写模型名。",
      currencyPlaceholder: "USD",
      inputPrice: "输入价格 / 1M tokens",
      outputPrice: "输出价格 / 1M tokens",
      descriptionPlaceholder: "说明这个模型适合什么场景。",
      saving: "保存中...",
      empty: "当前还没有配置模型，添加后即可开始治理安全模型和普通模型访问。",
      howItWorks: "工作方式",
      howItWorksSecure: "安全模型用于处理不能发送到普通外部模型的敏感请求。",
      howItWorksActive: "只有启用状态的模型才会暴露给用户侧选择器和路由策略。",
      howItWorksDiscovery:
        "内置厂家模板覆盖常见 OpenAI-compatible 厂家和本地端点；即使自动发现不可用，也仍可手动填写 Provider Model。",
    },
    riskRulesPage: {
      title: "可配置敏感检测规则",
      subtitle: "调整正则敏感策略，并决定规则是放行还是路由到安全模型。",
      addRule: "添加规则",
      totalRules: "规则总数",
      enabled: "启用",
      disabled: "停用",
      allowActions: "放行动作",
      secureRouteActions: "安全路由动作",
      allCategories: "全部类型",
      searchPlaceholder: "搜索规则 ID、名称、描述或 pattern...",
      allSeverities: "全部级别",
      allActions: "全部动作",
      allStatuses: "全部状态",
      finishEditing: "请先完成或取消当前编辑，再创建或编辑其他规则。",
      loading: "正在加载规则...",
      loadFailed: "加载规则失败",
      requiredFields: "规则 ID、显示名称和 pattern 都是必填项。",
      duplicateRuleId: "规则 ID 已存在。",
      saveFailed: "保存规则失败",
      disableFailed: "停用规则失败",
      statusUpdateFailed: "更新规则状态失败",
      action: "动作",
      pattern: "规则表达式",
      disable: "停用",
      enable: "启用",
      ruleId: "规则 ID",
      ruleIdPlaceholder: "email_address",
      ruleIdLocked: "已有规则的 ID 会锁定，避免误改导致线上策略映射错乱。",
      severity: "严重级别",
      sortOrder: "排序",
      regexPattern: "正则 Pattern",
      patternPlaceholder:
        "(?i)\\\\b[A-Z0-9._%+\\\\-]+@[A-Z0-9.\\\\-]+\\\\.[A-Z]{2,}\\\\b",
      descriptionPlaceholder: "说明这个规则检测什么。",
      noRules: "当前筛选条件下没有匹配的规则。",
      testLab: "规则测试台",
      testLabSubtitle:
        "粘贴样本文本，预览启用规则会命中什么，或者先测试你正在编辑的草稿规则。",
      testEnabled: "测试启用规则",
      testDraft: "测试草稿规则",
      testing: "测试中...",
      sampleText: "样本文本",
      samplePlaceholder: "粘贴样本文本，预览规则命中结果...",
      sampleRequired: "请先输入待测试的样本文本。",
      noDraftRule: "当前没有正在编辑的规则。",
      testFailed: "规则测试失败",
      sensitive: "命中敏感",
      noMatch: "未命中",
      highestSeverity: "最高级别：{value}",
      highestAction: "最高动作：{value}",
      noMatchesForSample: "当前样本文本没有命中任何规则。",
      bulkNoSelection: "请先选择至少一条规则。",
      bulkStatusUpdateFailed: "批量更新规则状态失败",
      selectVisible: "选择当前可见",
      bulkEnable: "批量启用",
      bulkDisable: "批量停用",
      selectRule: "选择",
      categoryPersonal: "个人信息",
      categoryCompany: "公司信息",
      categoryCustomer: "客户业务",
      categorySecurity: "安全凭据",
      categoryFinanceLegal: "财务法务",
      categoryPolitical: "政治敏感",
      categoryCustom: "自定义",
    },
    systemSettingsPage: {
      loadFailed: "加载镜像设置失败",
      requiredFields: "实例类型和镜像地址为必填项。",
      duplicateType: "这个实例类型已经有一张卡片。",
      duplicateImage: "该实例类型下已经存在相同的运行时镜像。",
      saveFailed: "保存镜像设置失败",
      deleteFailed: "删除镜像设置失败",
      runtimeImageCards: "运行时镜像卡片",
      runtimeImageCardsSubtitle:
        "为每种桌面运行时配置镜像地址。保存后的卡片会覆盖内置默认值。",
      addCard: "添加卡片",
      instanceType: "实例类型",
      cardTitle: "卡片标题",
      imageAddress: "镜像地址",
      defaultImage: "默认镜像",
      empty:
        "当前还没有运行时镜像卡片。添加一张卡片即可覆盖某种桌面类型的默认镜像。",
    },
    userManagementPage: {
      loading: "正在加载用户...",
      loadFailed: "加载用户失败",
      deleteFailed: "删除用户失败",
      loadQuotaFailed: "加载配额失败",
      updateQuotaFailed: "更新配额失败",
      updateRoleFailed: "更新角色失败",
      createFailed: "创建用户失败",
      selectCsv: "请先选择要导入的 CSV 文件",
      importFailed: "导入用户失败",
      importUsers: "导入用户",
      showingUsers: "显示第 {from}-{to} 个用户，共 {total} 个",
      noUsers: "暂无用户",
      importCompleted: "导入完成：成功创建 {created} 个，失败 {failed} 个",
      expectedColumns: "期望列：",
      lineError: "第 {line} 行{username}",
      createdAccounts: "已创建账号",
      quota: "配额",
      initialPassword: "初始密码",
      supportedFormat: "支持格式",
      csvHeaders: "CSV 文件头应为：",
      csvHelp:
        "Username、Role、Max Instances、Max CPU Cores、Max Memory (GB) 和 Max Storage (GB) 为必填项。Email、Password 和 Max GPU Count 为可选项。若 Password 为空，会使用系统默认密码。",
      downloadTemplate: "下载 CSV 模板",
      importFile: "导入文件",
      chooseFile: "选择文件",
      noFileSelected: "未选择文件",
      importing: "导入中...",
      startImport: "开始导入",
      addNewUser: "添加新用户",
      editQuotaFor: "编辑 {username} 的配额",
      maxInstances: "最大实例数",
      maxCpuCores: "最大 CPU 核数",
      maxMemoryGb: "最大内存 (GB)",
      maxStorageGb: "最大存储 (GB)",
      maxGpuCount: "最大 GPU 数",
      changeRoleFor: "修改 {username} 的角色",
      confirmDeleteTitle: "确认删除",
      confirmDeleteMessage: "确定要删除用户 {username} 吗？此操作不可撤销。",
    },
    errorBoundary: {
      title: "页面发生错误",
    },
    userDashboard: {
      subtitle: "在仪表盘中管理你的虚拟桌面实例和资源。",
      myInstances: "我的实例",
      running: "运行中",
      storageUsed: "已用存储",
      myResourceQuota: "我的资源配额",
      loadingQuota: "正在加载配额...",
      quotaUnavailable: "暂无配额信息",
      instances: "实例",
      maxCpuCores: "最大 CPU 核数",
      maxMemory: "最大内存",
      maxStorage: "最大存储",
      maxGpus: "最大 GPU 数",
      recentInstances: "最近实例",
      viewAll: "查看全部",
      quickActions: "快捷操作",
      createNewInstance: "创建新实例",
      viewAllInstances: "查看全部实例",
      noInstancesYet: "还没有实例",
      noInstancesSubtitle: "从创建你的第一个虚拟桌面实例开始",
      createInstance: "创建实例",
    },
    instances: {
      listTitle: "我的实例",
      realTimeUpdates: "实时更新",
      connected: "已连接",
      disconnected: "未连接",
      createInstance: "创建实例",
      searchPlaceholder: "按名称、类型或系统搜索...",
      noInstances: "暂无实例",
      noInstancesSubtitle: "先创建你的第一个虚拟桌面实例。",
      noMatchingInstances: "没有匹配的实例",
      noMatchingInstancesSubtitle: "请尝试调整筛选条件或搜索词。",
      clearFilters: "清除筛选",
      showingResults: "显示 {filtered} / {total} 个实例",
      failedToLoad: "加载实例失败",
      failedToDelete: "删除实例失败",
      failedToStart: "启动实例失败",
      failedToStop: "停止实例失败",
      confirmDelete: "确定要删除这个实例吗？此操作不可撤销。",
      details: "详情",
      instanceImage: "实例镜像",
      runtimeImageSelectionHint: "选择该实例类型实际要使用的运行时镜像版本。",
      runtimeImageUnavailable: "当前这个实例类型没有可用的运行时镜像。",
      operatingSystem: "操作系统",
      access: "访问",
      portalView: "门户视图",
      portalTitle: "桌面门户",
      portalWorkspace: "实例",
      portalSelectInstance: "选择实例",
      portalSelectInstanceSubtitle: "从列表中选择一个桌面开始使用。",
      portalUnavailable: "桌面不可用",
      portalUnavailableSubtitle: "请先启动一个桌面实例再从这里访问。",
      timeline: "时间线",
      storage: "存储",
      resourceConfiguration: "资源配置",
      kubernetesStatus: "Kubernetes 状态",
      accessInfo: "你的实例正在运行，可以访问。",
      openDesktop: "打开桌面",
      accessUrlUnavailable: "访问地址暂不可用",
      startToAccess: "启动实例后即可访问桌面",
      created: "已创建",
      lastStarted: "上次启动",
      lastStopped: "上次停止",
      storageClass: "存储类",
      mountPath: "挂载路径",
      podName: "Pod 名称",
      namespace: "命名空间",
      podIp: "Pod IP",
      podStatus: "Pod 状态",
      loadingInstance: "正在加载实例...",
      instanceNotFound: "实例不存在",
      backToInstances: "返回实例列表",
      basicInformation: "基础信息",
      desktopAccess: "桌面访问",
      logsPlaceholder: "实例日志将显示在这里...",
      logsComingSoon: "将在第 6 阶段提供",
      startTheInstance: "实例已停止",
      startToAccessDesktop: "启动实例后即可访问桌面。",
      generatingToken: "正在生成访问令牌...",
      accessError: "访问错误",
      readyToAccess: "准备访问",
      generateAccessPrompt: "生成访问令牌以连接到 {name}。",
      generateAccess: "生成访问令牌",
      expiresIn: "剩余时间",
      refreshToken: "刷新令牌",
      accessTokenExpired: "访问令牌已过期",
      regenerateToken: "重新生成令牌",
      instanceMustBeRunning: "实例必须处于运行中才能访问",
      failedToGenerateAccessToken: "生成访问令牌失败",
      expired: "已过期",
      createTitle: "创建实例",
      stepOf: "第 {step} 步，共 3 步：{label}",
      stepBasic: "基础信息",
      stepType: "选择类型",
      stepConfig: "配置",
      instanceName: "实例名称 *",
      instanceNamePlaceholder: "例如：my-desktop",
      minimumThreeChars: "至少 3 个字符",
      descriptionOptional: "描述（可选）",
      descriptionPlaceholder: "简要描述这个实例...",
      selectInstanceType: "选择实例类型",
      quickConfiguration: "快速配置",
      customConfiguration: "自定义配置",
      cpuCores: "CPU 核数",
      memoryGb: "内存（GB）",
      diskGb: "磁盘（GB）",
      storageClassOptional: "存储类（可选）",
      enableGpu: "启用 GPU",
      gpuCount: "GPU 数量",
      summary: "摘要",
      createFailed: "创建实例失败",
      nameAlreadyExists: "该实例名称已存在。",
      next: "下一步",
      back: "上一步",
      createNow: "创建实例",
      creatingNow: "创建中...",
      defaultStorageClass: "默认",
      instanceIdLabel: "实例 ID",
      heroFallbackDescription:
        "专属桌面工作区，具备集群资源隔离、独立存储和一键安全访问能力。",
      allocatedCompute: "已分配算力",
      reservedRam: "已预留内存",
      persistentDisk: "持久磁盘",
      launchLiveSession: "打开实时桌面会话",
      desktopAvailableAfterStart: "实例启动后即可使用桌面访问",
      instanceDossier: "实例档案",
      allocatedProfile: "资源分配",
      kubernetesSection: "Kubernetes",
      volumeMapping: "卷映射",
      workspaceSection: "工作区",
      openClawWorkspace: "OpenClaw 工作区",
      openClawWorkspaceDesc:
        "可将 `.openclaw` 文件夹导入或导出为不超过 50 MiB 的 `.tar.gz` 压缩包。",
      runtimeWorkspace: "{runtime} 工作区",
      runtimeWorkspaceDesc:
        "可将 `{directory}` 文件夹导入或导出为不超过 50 MiB 的 `.tar.gz` 压缩包。",
      workspaceReady: "可操作",
      workspacePaused: "未就绪",
      exportingOpenClaw: "正在导出...",
      exportOpenClaw: "导出 .openclaw",
      importingOpenClaw: "正在导入...",
      importOpenClaw: "导入 .openclaw",
      exportingRuntimeWorkspace: "正在导出...",
      exportRuntimeWorkspace: "导出 {directory}",
      importingRuntimeWorkspace: "正在导入...",
      importRuntimeWorkspace: "导入 {directory}",
      importRuntimeWorkspaceSuccess: "{runtime} 工作区导入成功。",
      openClawArchiveTooLarge: "归档过大。最大大小为 50 MiB。",
      importRuntimeWorkspaceFailed: "导入 {directory} 失败：{message}",
      exportRuntimeWorkspaceFailed: "导出 {directory} 失败：{message}",
      memoryReserved: "预留内存",
      persistentStorage: "持久存储",
      gpuAttached: "GPU 数量",
      waitingForRunningState: "正在等待实例进入运行状态后导入 .openclaw。",
      timedOutWaitingForRunning: "等待实例进入运行状态以导入 .openclaw 超时。",
      openClawImportTitle: "OpenClaw 导入",
      openClawImportDesc:
        "可选。选择一个已导出的 `.openclaw` 归档，实例启动后会自动导入。",
      optional: "可选",
      changeOpenClawArchive: "更换 .openclaw 归档",
      chooseOpenClawArchive: "选择 .openclaw 归档",
      changeRuntimeArchive: "更换 {directory} 归档",
      chooseRuntimeArchive: "选择 {directory} 归档",
      remove: "移除",
      selectedArchive: "已选择归档：{name}",
      noArchiveSelected: "尚未选择归档。实例将以空的 .openclaw 工作区创建。",
      noRuntimeArchiveSelected:
        "尚未选择归档。实例将以空的 {directory} 工作区创建。",
      quotaValidation: "配额校验",
      unableToLoadQuota:
        "无法加载你的配额。在配额可用前，创建实例按钮会保持禁用。",
      requestedResourcesExceeded:
        "请求资源已超出管理员分配的配额，请先降低配置。",
      quotaInstances: "实例数",
      checkingQuota: "正在检查配额...",
      creatingAndImporting: "正在创建并导入...",
      typeOptions: {
        ubuntu: {
          label: "Ubuntu 桌面",
          description: "带有 GNOME 桌面的流行 Linux 发行版",
        },
        debian: {
          label: "Debian 桌面",
          description: "稳定且安全的 Linux 发行版",
        },
        centos: {
          label: "CentOS 桌面",
          description: "面向企业的 Linux 发行版",
        },
        openclaw: {
          label: "OpenClaw 桌面",
          description: "为 OpenClaw 优化的桌面环境",
        },
        webtop: {
          label: "Webtop 桌面",
          description: "通过 ClawManager 代理的浏览器 Linux 桌面",
        },
        hermes: {
          label: "Hermes Runtime",
          description: "基于 Webtop 桌面基础镜像构建的 Hermes 运行时",
        },
        custom: {
          label: "自定义镜像",
          description: "使用你自己的自定义镜像",
        },
      },
      presetOptions: {
        small: {
          label: "小型",
          description: "适合轻量任务",
        },
        medium: {
          label: "中型",
          description: "适合开发工作",
        },
        large: {
          label: "大型",
          description: "适合高负载场景",
        },
      },
      customPresetTitle: "自定义",
      customPresetDescription: "以 Medium 为起点手动调整资源大小。",
      customPresetEditing: "编辑中",
      resourcePresetSummary: "{cpu} CPU • {memory} GB 内存 • {disk} GB 磁盘",
      mediumDefaultPreset:
        "中等默认值：{cpu} CPU • {memory} GB 内存 • {disk} GB 磁盘",
      presetCpuShort: "CPU",
      presetRamShort: "RAM",
      presetDiskShort: "磁盘",
      environmentVariables: "环境变量",
      clawManagerBuiltIns: "ClawManager 内置变量",
      hideBuiltIns: "收起内置变量",
      editBuiltIns: "编辑内置变量",
      editBuiltInsCount: "编辑内置变量（{count}）",
      builtinOverridesConfigured:
        "已配置 {count} 个内置变量覆盖。展开即可查看或编辑。",
      usingBuiltInDefaults:
        "当前对 {count} 个内置变量使用 ClawManager 默认值。",
      builtinOverrideHelp:
        "只添加你想覆盖的内置变量。未列出的变量会继续使用默认注入值。",
      addBuiltinVariable: "添加内置变量",
      noBuiltinOverrides: "还没有添加任何内置变量覆盖。",
      defaultValue: "默认值：{value}",
      variable: "变量名",
      overrideValue: "覆盖值",
      overrideValuePlaceholder: "覆盖值",
      actionLabel: "操作",
      customVariables: "自定义变量",
      addVariable: "添加变量",
      noCustomEnvironmentVariables: "还没有自定义环境变量。",
      variableNamePlaceholder: "VARIABLE_NAME",
      variableValuePlaceholder: "value",
      customEnvNameRequired: "自定义环境变量名称不能为空。",
      invalidEnvName: "环境变量名称无效：{name}",
      reservedBuiltinEnvName:
        "{name} 是 ClawManager 内置变量，请到内置变量区域中编辑。",
      duplicateEnvName: "环境变量名称重复：{name}",
      openClawInjection: "OpenClaw 注入",
      runtimeInjection: "{runtime} 注入",
      selectedCount: "已选择 {count} 个",
      noReusableSkillsSelected: "还没有选择可复用技能。",
      noAvailableSkillsForInjection:
        "当前没有可用技能。请先到资源中心导入技能。",
      skillRiskVersionLabel: "{key} · 风险 {risk} · v{version}",
      skillPageSummary: "第 {page}/{totalPages} 页 · 共 {totalSkills} 个技能",
      archiveImport: "归档导入",
      archiveModeRequiresFile: "归档模式必须提供文件",
      envInjection: "环境变量注入",
      noEnvOverridesConfigured: "当前没有配置容器环境变量覆盖。",
      channelInjection: "Channel 注入",
      archiveSkipsChannelInjection: "归档模式会跳过基于资源的 Channel 注入。",
      compilingOpenClawPreview: "正在生成 OpenClaw 资源预览...",
      compilingRuntimePreview: "正在生成运行时资源预览...",
      noChannelsSelectedForInjection: "还没有选择用于注入的 Channel。",
      skillInjection: "技能注入",
      envManagedProxyPath: "ClawManager 管理的代理路径",
      envGeneratedAtRuntime: "由 ClawManager 在运行时生成",
      envAssignedAfterCreation: "创建后分配",
      envManagedAtRuntime: "由 ClawManager 在运行时管理",
      envDescDesktopTitleWebtop:
        "注入到 LinuxServer Webtop 容器中的桌面窗口标题。",
      envDescDesktopTitleOpenClaw:
        "显示在 OpenClaw 浏览器桌面镜像中的桌面标题。",
      envDescProxySubfolder: "ClawManager 反向代理用于浏览器访问的路径前缀。",
      envDescLlmBaseUrl:
        "由 ClawManager 在运行时生成的 OpenClaw 网关基础 URL。",
      envDescLlmApiKey: "ClawManager 为该实例生成的网关 API Key。",
      envDescLlmModel:
        "注入到 OpenClaw 工作区中的 Gateway 模型目录 JSON，首项保留为 auto。",
      envDescLlmProvider: "提供给 OpenClaw 工作区的 Provider 提示。",
      envDescInstanceToken: "ClawManager 为工作区访问生成的实例令牌。",
      envDescOpenAiBaseUrl: "OpenAI 兼容网关基础 URL 的兼容别名。",
      envDescOpenAiApiBase: "OpenAI 兼容网关基础 URL 的兼容别名。",
      envDescOpenAiApiKey: "网关 API Key 的兼容别名。",
      envDescOpenAiModel: "默认模型名的兼容别名。",
      envDescAgentEnabled:
        "控制是否在 OpenClaw 内启用 ClawManager 实例 Agent。",
      envDescAgentBaseUrl: "实例内 Agent 控制平面客户端使用的基础 URL。",
      envDescAgentBootstrapToken: "ClawManager 为实例内 Agent 生成的引导令牌。",
      envDescAgentDiskLimitBytes: "注入给实例 Agent 的磁盘配额。",
      envDescAgentInstanceId: "提供给实例内 Agent 的运行时实例标识。",
      envDescAgentPersistentDir: "挂载到 OpenClaw 容器中的持久工作区路径。",
      envDescAgentProtocolVersion: "ClawManager Agent 控制面期望的协议版本。",
      gpuLabel: "GPU",
      cpuCoresValue: "{value} 核",
      gpuCountValue: "{count} 个 GPU",
      memoryLabel: "内存",
      storageLabel: "存储",
      gpuDisabled: "未启用",
      noOpenClawArchiveSelected: "未选择 .openclaw 归档",
      live: "实时",
      notAvailable: "暂无",
      runtimeCommandFailed: "执行 {command} 失败",
      failedToAttachSkill: "安装技能失败",
      failedToRemoveSkill: "移除技能失败",
      kubernetesStatusTitle: "Pod 与基础设施状态",
      infrastructureReady: "基础设施就绪",
      skillsSection: "技能",
      skillManagement: "技能管理",
      selectSkill: "选择技能",
      installingSkill: "安装中...",
      installSkill: "安装技能",
      noSkillsReported: "这个实例还没有上报任何技能。",
      skillFallback: "技能 #{id}",
      lastSeenAt: "最近出现于 {value}",
      removingSkill: "移除中...",
      removeSkill: "移除",
      skillPagination: "显示第 {from}-{to} 项，共 {total} 个技能",
      previous: "上一页",
      nextPage: "下一页",
      timelineSubtitle: "实例操作与运行时历史",
      timelineEvents: "{count} 条事件",
      noRuntimeActivity: "暂时没有运行时活动。",
      minimap: "缩略图",
      runtimeSummary: "运行时摘要",
      agentReportedStatus: "Agent 上报状态",
      fresh: "最新",
      operatingSystemShort: "系统",
      openClawShort: "OpenClaw",
      agents: "代理",
      channels: "通道",
      agentStatusLabel: "Agent {status}",
      gatewayStatusLabel: "网关 {status}",
      agentId: "Agent ID",
      agentVersion: "Agent 版本",
      protocol: "协议",
      lastHeartbeat: "最近心跳",
      lastReport: "最近上报",
      skillSourceUploaded: "上传",
      skillSourceDiscovered: "发现",
      skillRiskNone: "安全",
      skillRiskLow: "低",
      skillRiskMedium: "中",
      skillRiskHigh: "高",
      skillRiskUnknown: "未知",
      timelineInstanceCreated: "实例已创建",
      timelineInstanceCreatedDetail: "{name} 已按 {type} 类型完成创建。",
      timelineInstanceStarted: "实例已启动",
      timelineInstanceStartedDetail: "该实例已记录基础设施启动事件。",
      timelineInstanceStopped: "实例已停止",
      timelineInstanceStoppedDetail: "该实例已记录基础设施停止事件。",
      timelineAgentRegistered: "Agent 已注册",
      timelineAgentRegisteredDetail:
        "{agentId} 已通过协议 {protocol} 连接到 ClawManager。",
      timelineRuntimeReported: "运行时状态已上报",
      timelineRuntimeReportedDetail:
        "Agent 上报的网关状态为 {gatewayStatus}，基础设施状态为 {infraStatus}。",
      timelinePodStatusObserved: "Pod 状态已采集",
      timelinePodStatusObservedDetail:
        "Kubernetes 当前上报的 Pod 状态为 {status}。",
      timelineCommandWithError: "{status}: {error}",
      timelineCommandWithIdempotency: "{status} · 幂等键 {key}",
      timelineSectionInstance: "实例",
      timelineSectionInfra: "基础设施",
      timelineSectionAgent: "Agent",
      timelineSectionRuntime: "运行时",
      timelineSectionKubernetes: "K8s",
      timelineSectionCommand: "命令",
      metricCpu: "CPU",
      metricCpuDetail:
        "{cores} 核 · 1 分钟负载 {load1} · 5 分钟负载 {load5} · 15 分钟负载 {load15}",
      metricMemory: "内存",
      metricMemoryDetail: "已用 {used} / 总计 {total}",
      metricDisk: "磁盘",
      metricDiskDetail: "剩余 {free} / 总计 {total}",
      metricNetwork: "网络",
      metricNetworkDetail: "{interfaces} 个网卡，共 {addresses} 个地址",
      metricLegendDown: "下行",
      metricLegendUp: "上行",
      metricTrafficDetail: "入站 {inbound} · 出站 {outbound}",
    },
    openClawResourcesPage: {
      title: "OpenClaw 资源管理",
      tabs: {
        resources: "资源",
        bundles: "资源包",
        injections: "注入记录",
      },
      resourceTypesTitle: "资源类型",
      searchPlaceholder: "搜索资源...",
      resourceListHint:
        "点击资源卡片后会以弹窗方式编辑，不再在页面右侧直接展开。",
      loadingResources: "正在加载资源...",
      noResources: "当前类型下还没有资源，点击“新建”开始创建。",
      enabled: "已启用",
      disabled: "已禁用",
      thisResourceType: "该资源类型",
      notConfigurableYet: "{type} 暂不支持配置。",
      onlyChannelConfigurable:
        "当前仅支持配置 Channel。Skill、Agent 和 Scheduled Task 的编辑器会在后续版本提供。",
      bundlesSubtitle:
        "把可复用的 OpenClaw 启动资源组合成资源包，并在弹窗中集中编辑。",
      loadingBundles: "正在加载资源包...",
      noBundles: "还没有资源包，点击“新建资源包”开始创建。",
      bundleResourceCount: "{count} 个资源",
      injectionsSubtitle: "快照会在实例创建时保存，并在重启时复用。",
      snapshot: "快照",
      mode: "模式",
      resources: "资源数",
      envCount: "环境变量数",
      created: "创建时间",
      loadingSnapshots: "正在加载快照...",
      noInjectionRecords: "还没有 OpenClaw 注入记录。",
      paginationSummary: "每页 {pageSize} 条，本页显示 {from}-{to}",
      paginationPrev: "上一页",
      paginationNext: "下一页",
      skillUploadHint: "仅支持上传 `.zip`。每个一级目录会被导入为一个技能。",
      loadingSkills: "正在加载技能...",
      noSkills: "暂时还没有上传任何技能。",
      skillMeta: "{key} · 风险 {risk} · 已被 {count} 个实例使用",
      recordModes: {
        none: "无",
        manual: "手动",
        bundle: "资源包",
        archive: "归档",
      },
      recordStatuses: {
        compiled: "已编译",
        active: "已生效",
        failed: "失败",
      },
      editResourceTitle: "编辑资源",
      newResourceTitle: "新建资源",
      editResourceSubtitle: "在聚焦弹窗中统一调整元数据和 JSON。",
      newResourceSubtitle:
        "无需在页面常驻编辑器中操作，直接创建新的 OpenClaw 资源。",
      resourceKey: "资源 Key",
      name: "名称",
      tags: "标签",
      tagsPlaceholder: "tag1,tag2",
      channelTemplate: "Channel 模板",
      chooseStarterTemplate: "选择起始模板",
      channelTemplateHint:
        "这里只支持 Slack、Telegram、DingTalk 和飞书。先用表单模式快速填写，再在需要时切换到 JSON 查看完整配置。",
      templateKey: "键：{key}",
      invalidChannelJson:
        "当前 Channel JSON 无法解析。请先切到 JSON 模式修复，再回到表单。",
      contentJson: "内容 JSON",
      editBundleTitle: "编辑资源包",
      newBundleTitle: "新建资源包",
      editBundleSubtitle: "在聚焦弹窗中调整可复用的启动资源包。",
      newBundleSubtitle: "无需离开资源列表，就能创建新的可复用资源包。",
      bundleName: "资源包名称",
      bundleResources: "资源包内容",
      noResourcesForGroup: "当前还没有 {type} 资源。",
      actions: {
        new: "新建",
        newBundle: "新建资源包",
        loadTemplate: "加载模板",
        saveResource: "保存资源",
        createResource: "创建资源",
        validateJson: "校验 JSON",
        clone: "克隆",
        saveBundle: "保存资源包",
        createBundle: "创建资源包",
      },
      resourceTypes: {
        channel: "通道",
        skill: "技能",
        session_template: "会话模板",
        log_policy: "日志策略",
        agent: "智能体",
        scheduled_task: "定时任务",
      },
      templateCategories: {
        builtin: "内置",
        plugin: "插件",
      },
      templates: {
        telegram: {
          label: "Telegram",
          description: "支持私聊和群组策略控制的 Telegram Bot API 通道。",
        },
        dingtalkConnector: {
          label: "DingTalk",
          description: "支持客户端凭证和发送方白名单控制的 DingTalk 通道。",
        },
        slack: {
          label: "Slack",
          description: "基于 Bolt 的 Slack 工作区应用通道。",
        },
        feishu: {
          label: "飞书 / Lark",
          description: "带账号默认值的飞书 / Lark 通道。",
        },
      },
      editorModes: {
        form: "表单",
        json: "JSON",
      },
      channelEditors: {
        dingtalkConnector: {
          title: "DingTalk Channel 编辑器",
          description:
            "先填写客户端凭证表单，只有在需要完整配置时再切到 JSON。",
          fields: {
            clientId: {
              label: "Client ID",
              placeholder: "ding-xxxxxxxxxxxxxx",
            },
            clientSecret: {
              label: "Client Secret",
              placeholder: "客户端密钥",
            },
          },
        },
        feishu: {
          title: "飞书 Channel 编辑器",
          description: "先填写主账号表单，只有在需要完整配置时再切到 JSON。",
          fields: {
            appId: {
              label: "App ID",
              placeholder: "cli_xxx",
            },
            appSecret: {
              label: "App Secret",
              placeholder: "应用密钥",
            },
          },
        },
        slack: {
          title: "Slack Channel 编辑器",
          description: "先填写 Token 表单，只有在需要完整配置时再切到 JSON。",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "xoxb-...",
            },
            appToken: {
              label: "App Token",
              placeholder: "xapp-...",
            },
          },
        },
        telegram: {
          title: "Telegram Channel 编辑器",
          description:
            "先填写 Bot Token 表单，只有在需要完整配置时再切到 JSON。",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "123456:ABCDEF",
            },
          },
        },
      },
      notices: {
        resourceUpdated: "资源已更新。",
        resourceCreated: "资源已创建。",
        resourceDeleted: "资源已删除。",
        resourceCloned: "资源已克隆。",
        resourceJsonValid: "资源 JSON 校验通过。",
        templateLoaded: "已加载 {name} 模板。",
        bundleUpdated: "资源包已更新。",
        bundleCreated: "资源包已创建。",
        bundleDeleted: "资源包已删除。",
        bundleCloned: "资源包已克隆。",
        skillArchiveImported: "技能归档导入成功。",
        skillDeleted: "技能已删除。",
      },
      errors: {
        loadFailed: "加载 OpenClaw 资源失败。",
        saveResource: "保存资源失败。",
        validationFailed: "资源 JSON 校验失败。",
        deleteResource: "删除资源失败。",
        cloneResource: "克隆资源失败。",
        saveBundle: "保存资源包失败。",
        deleteBundle: "删除资源包失败。",
        cloneBundle: "克隆资源包失败。",
        importSkillArchive: "导入技能归档失败。",
        deleteSkill: "删除技能失败。",
        downloadSkill: "下载技能失败。",
      },
      skillActions: {
        chooseFile: "选择文件",
        uploadArchive: "上传技能归档",
        download: "下载",
      },
      risks: {
        none: "安全",
        low: "低",
        medium: "中",
        high: "高",
        unknown: "未知",
      },
      confirms: {
        deleteResource: "确认删除资源“{name}”吗？",
        deleteBundle: "确认删除资源包“{name}”吗？",
      },
    },
    openClawInjectionSection: {
      title: "OpenClaw 资源注入",
      subtitle:
        "选择这个实例如何启动 OpenClaw。再次点击当前已选项即可取消选择。",
      optional: "可选",
      modes: {
        manual: "手动资源",
        bundle: "资源包",
        archive: "归档导入",
      },
      loading: "正在加载资源管理内容...",
      chooseBundle: "选择资源包",
      selectBundle: "请选择资源包",
      bundleOptionCount: "{count} 个资源",
      channel: "通道",
      noChannelResources: "当前没有可用的通道资源。",
      errors: {
        chooseBundle: "请先选择一个资源包。",
        chooseResource: "请至少选择一个资源。",
        compileFailed: "生成 OpenClaw 启动预览失败。",
      },
    },
  },
  ja: {
    app: { name: "ClawManager" },
    common: {
      loading: "読み込み中...",
      logout: "ログアウト",
      admin: "管理者",
      user: "ユーザー",
      comingSoon: "近日公開",
      language: "言語",
      refresh: "更新",
      retry: "再試行",
      create: "作成",
      save: "保存",
      cancel: "キャンセル",
      close: "閉じる",
      overview: "概要",
      logs: "ログ",
      description: "説明",
      type: "タイプ",
      status: "状態",
      createdAt: "作成日時",
      lastUpdated: "最終更新",
      open: "開く",
      stop: "停止",
      start: "開始",
      restart: "再起動",
      delete: "削除",
      cpu: "CPU",
      memory: "メモリ",
      disk: "ディスク",
      search: "検索",
      all: "すべて",
    },
    status: {
      all: "すべて",
      running: "稼働中",
      stopped: "停止",
      creating: "作成中",
      error: "エラー",
      deleting: "削除中",
    },
    nav: {
      dashboard: "ダッシュボード",
      adminDashboard: "コンソール",
      userDashboard: "ワークスペース",
      users: "ユーザー",
      instances: "インスタンス",
      aiGateway: "AI Gateway",
      aiAudit: "AI 監査",
      costs: "コスト",
      riskRules: "リスクルール",
      models: "モデル",
      settings: "設定",
      myInstances: "マイインスタンス",
      openClawConfigs: "リソース管理",
      backToDashboard: "ダッシュボードに戻る",
      backToUserDashboard: "ワークスペース",
      securityCenter: "セキュリティセンター",
      adminPanel: "管理パネル",
    },
    adminLayout: adminLayoutTranslations.ja,
    securityCenter: securityCenterTranslations.ja,
    auth: {
      signInTitle: "ClawManager にサインイン",
      subtitle: "仮想デスクトップ管理プラットフォーム",
      username: "ユーザー名",
      password: "パスワード",
      email: "メール",
      usernamePlaceholder: "ユーザー名を入力",
      passwordPlaceholder: "パスワードを入力",
      signIn: "サインイン",
      signingIn: "サインイン中...",
      noAccount: "アカウントをお持ちでないですか？",
      signUp: "新規登録",
      createAccount: "アカウントを作成",
      joinToday: "今すぐ ClawManager に参加",
      chooseUsername: "ユーザー名を選択",
      enterEmail: "メールを入力",
      createPassword: "パスワードを作成（8文字以上）",
      confirmPassword: "パスワード確認",
      confirmPasswordPlaceholder: "パスワードを再入力",
      createAccountAction: "アカウント作成",
      creatingAccount: "作成中...",
      alreadyHaveAccount: "すでにアカウントをお持ちですか？",
      passwordsMismatch: "パスワードが一致しません",
      passwordTooShort: "パスワードは8文字以上必要です",
      changePassword: "パスワード変更",
      currentPassword: "現在のパスワード",
      newPassword: "新しいパスワード",
      confirmNewPassword: "新しいパスワードの確認",
      changePasswordAction: "パスワードを更新",
      changePasswordDesc: "設定ページからアカウントのパスワードを更新します。",
      changingPassword: "更新中...",
      passwordChanged: "パスワードが変更されました",
      changePasswordFailed: "パスワードの変更に失敗しました",
      loginFailed: "ログインに失敗しました",
    },
    admin: {
      dashboardTitle: "コンソール",
      userManagement: "ユーザー管理",
      userManagementDesc: "ユーザー、権限、クォータを管理",
      instanceManagement: "インスタンス管理",
      instanceManagementDesc: "仮想デスクトップインスタンスを管理",
      globalInstances: "全インスタンス",
      globalInstancesDesc:
        "すべてのユーザーインスタンスを一か所で検索、絞り込み、操作します。",
      instanceSearchPlaceholder:
        "インスタンス、ユーザー、タイプ、Pod、名前空間で検索...",
      allStatuses: "すべての状態",
      allTypes: "すべてのタイプ",
      showingInstances: "{total} 件中 {filtered} 件を表示",
      loadingInstances: "インスタンスを読み込み中...",
      noFilteredInstances:
        "現在のフィルターに一致するインスタンスはありません。",
      instanceColumn: "インスタンス",
      userColumn: "ユーザー",
      typeOsColumn: "タイプ / OS",
      resourcesColumn: "リソース",
      k8sColumn: "K8s",
      actionsColumn: "操作",
      updatedAtLabel: "更新日時",
      userIdLabel: "ユーザー ID",
      gpuLabel: "GPU",
      failedToLoadInstances: "インスタンスの読み込みに失敗しました",
      failedToStartInstance: "インスタンスの起動に失敗しました",
      failedToStopInstance: "インスタンスの停止に失敗しました",
      failedToRestartInstance: "インスタンスの再起動に失敗しました",
      failedToSyncInstance: "インスタンスの同期に失敗しました",
      failedToDeleteInstance: "インスタンスの削除に失敗しました",
      confirmDeleteInstance: "インスタンス {name} を削除しますか？",
      systemSettings: "システム設定",
      systemSettingsDesc: "システム設定を構成",
      systemOverview: "システム概要",
      totalUsers: "総ユーザー数",
      totalInstances: "総インスタンス数",
      runningInstances: "稼働中のインスタンス",
      totalStorage: "総ストレージ",
      instanceManagementStub:
        "この機能は現在開発中です。しばらくお待ちください。",
      systemSettingsStub: "この機能は現在開発中です。しばらくお待ちください。",
      addUser: "ユーザー追加",
      dashboardLoadFailed: "ダッシュボード統計の読み込みに失敗しました",
      clusterCommand: "クラスター指揮",
      clusterHeroTitle: "クラスター基盤情報の概要",
      clusterHeroDesc:
        "このダッシュボードは設定画面ではなく、運用コックピットとして機能するべきです。重要な指標を先に見せ、ノード負荷を一目で把握できます。",
      accountsWithAccess: "アクセス可能アカウント",
      provisionedDesktops: "作成済みデスクトップ",
      currentlyOnline: "現在オンライン",
      allocatedToInstances: "インスタンスに割り当て済み",
      readiness: "準備状況",
      clusterStatusPending: "クラスター状態を取得中",
      nodesHealthySchedulable:
        "ノードの {percent}% が健全でスケジュール可能です。",
      hotNode: "高負荷ノード",
      cpuRequested: "CPU 要求量",
      memoryRequested: "メモリ要求量",
      diskAllocated: "ディスク割り当て量",
      pressureFocus: "圧力焦点",
      pressureFocusMem: "メモリ {percent}%",
      clusterResources: "クラスター資源",
      capacityBoard: "容量ボード",
      waitingForClusterData: "クラスター情報を待機中",
      nodesReadySummary: "{ready}/{total} ノードが準備完了",
      nodeFleet: "ノード群",
      nodes: "ノード",
      healthyNodesScheduling: "スケジュール可能な健全ノード",
      computePressure: "計算資源の圧力",
      memoryPressure: "メモリ圧力",
      persistentAllocation: "永続割り当て",
      requestedVsAllocatable: "要求量 / 割り当て可能量",
      allocatedVsAllocatable: "割り当て量 / 割り当て可能量",
      capacityCores: "総容量 {value} コア",
      capacityGiB: "総容量 {value} GiB",
      usage: "使用率",
      nodeMatrix: "ノードマトリクス",
      infrastructureTable: "インフラ一覧",
      infrastructureTableDesc:
        "クラスター全体を一画面で確認できます。任意のノードを展開すると CPU、メモリ、ディスク、kubelet の詳細を確認できます。",
      node: "ノード",
      health: "健全性",
      ready: "準備完了",
      role: "役割",
      internalIp: "内部 IP",
      pods: "Pod 数",
      cpuLoad: "CPU 負荷",
      memoryLoad: "メモリ負荷",
      inspect: "確認",
      nodeDossier: "ノード概要",
      kubeletVersion: "Kubelet バージョン",
      roles: "役割",
      podCount: "Pod 数",
      diskSummary: "ディスク概要",
      resourceProfile: "リソースプロファイル",
      noNodeData: "クラスターからノード情報が返されませんでした。",
      showingNodes: "{total} ノード中 {from}-{to} を表示",
      prev: "前へ",
      nextPage: "次へ",
      pageSummary: "{page} / {total} ページ",
      collapse: "閉じる",
      viewDetails: "詳細",
      notReady: "未準備",
      openSection: "開く",
    },
    aiGatewayPage: {
      badge: "ガバナンスハブ",
      title: "AI ゲートウェイ管理センター",
      subtitle:
        "モデルカタログ、監査トレース、コストレポート、機密検知ルールをここに集約します。",
      modelsDescription:
        "通常モデルと安全モデル、Provider エンドポイント、価格、アクティブ状態を管理します。",
      auditDescription:
        "Trace ID、リクエスト/レスポンス、リスクヒット、ルーティング判断、呼び出し詳細を確認します。",
      costsDescription:
        "Token 使用量、推定コスト、内部安全モデルコスト、関連する課金明細を確認します。",
      riskRulesDescription:
        "正規表現ベースの機密検知ルール、重大度、動作、実行順序を調整します。",
    },
    aiAuditPage: {
      title: "最近の AI トレース",
      subtitle:
        "ガバナンス対象のモデル呼び出し、Trace、Token 使用量、状態、実際のルーティング結果を確認します。",
      loadFailed: "AI 監査レコードの読み込みに失敗しました",
      detailLoadFailed: "Trace 詳細の読み込みに失敗しました",
      copyFailed: "Trace ID のコピーに失敗しました",
      completed: "完了",
      blocked: "ブロック済み",
      failed: "失敗",
      pending: "処理中",
      tokensOnPage: "このページの Token",
      traceTable: "Trace テーブル",
      traceTableSubtitle: "検索、絞り込み、確認を 1 つのテーブルから行えます。",
      searchPlaceholder: "trace、request、user、model を検索...",
      allStatuses: "すべての状態",
      modelPlaceholder: "モデルで絞り込み...",
      loading: "監査レコードを読み込み中...",
      empty: "AI 監査レコードはありません。",
      trace: "Trace",
      user: "ユーザー",
      requested: "要求モデル",
      providerResult: "実際の結果",
      failureReason: "失敗原因",
      usage: "使用量",
      action: "操作",
      copy: "コピー",
      copied: "コピー済み",
      noLatency: "遅延データなし",
      detailTitle: "Trace 詳細",
      detailSubtitle:
        "Trace を選択して、呼び出しペイロード、監査イベント、コスト記録を確認します。",
      detailLoading: "Trace 詳細を読み込み中...",
      noTraceSelected: "まだ Trace が選択されていません。",
      executionFlow: "実行フロー",
      executionFlowSubtitle:
        "OpenClaw の 1 回の質問を、モデル呼び出し、ツール呼び出し、ツール出力、最終応答までまとめて確認します。",
      flowMinimap: "ミニマップ",
      flowMinimapSubtitle:
        "実行ステップを一覧表示し、クリックするとその位置へすぐ移動できます。",
      noFlowNodes: "この Trace ではまだ実行フローノードが生成されていません。",
      flowNode: "フローノード",
      flowUserMessage: "ユーザーメッセージ",
      flowLlmCall: "LLM 呼び出し",
      flowToolCall: "ツール呼び出し",
      flowToolOutput: "ツール出力",
      flowAssistantResponse: "アシスタント応答",
      flowAssistantMessage: "アシスタントメッセージ",
      nodeInput: "入力",
      nodeOutput: "出力",
      requestIdLabel: "Request ID",
      modelLabel: "Model",
      userLabel: "ユーザー: {user}",
      sessionLabel: "セッション: {session}",
      copyTraceId: "Trace ID をコピー",
      clear: "クリア",
      invocations: "呼び出し記録",
      noInvocation: "この Trace には保存済み invocation レコードがありません。",
      payloads: "ペイロード",
      auditEvents: "監査イベント",
      costRecords: "コスト記録",
      noCostRecords:
        "この Trace にはコスト記録がありません。通常は、課金対象のモデル呼び出しに到達する前にブロックまたは失敗したことを意味します。",
      riskHits: "リスクヒット",
      noRiskHits: "この Trace では機密ヒットは記録されていません。",
      messages: "メッセージ",
      noMessages: "この Trace には保存済みメッセージがありません。",
    },
    costsPage: {
      badge: "コスト概要",
      title: "AI コストを 1 画面で確認",
      subtitle:
        "Token 量、推定費用、内部コスト、および異常なスパイクに紐づく Trace を確認します。",
      loadFailed: "AI コスト概要の読み込みに失敗しました",
      loading: "AI コスト概要を読み込み中...",
      promptTokens: "入力 Token",
      promptTokensNote: "入力プロンプト量",
      completionTokens: "出力 Token",
      completionTokensNote: "生成出力量",
      estimatedSpend: "推定費用",
      estimatedSpendNote: "Provider 単価ベースの推定",
      internalCost: "内部コスト",
      internalCostNote: "安全モデルの内部計上",
      userTotals: "ユーザー集計",
      userTotalsSubtitle: "ユーザー単位の使用量と費用",
      instanceTotals: "インスタンス集計",
      instanceTotalsSubtitle: "インスタンス単位の使用量と費用",
      recentRecords: "最近のコスト記録",
      recentRecordsSubtitle:
        "Trace に紐づくコスト記録を検索・ページングし、そのまま監査へ移動できます。",
      searchPlaceholder: "trace、user、model を検索...",
      pageSize10: "10 / ページ",
      pageSize20: "20 / ページ",
      pageSize50: "50 / ページ",
      apply: "適用",
      trace: "Trace",
      user: "ユーザー",
      instance: "インスタンス",
      model: "モデル",
      tokens: "Token",
      spend: "費用",
      recorded: "記録時刻",
      instanceId: "ID {id}",
      internalValue: "内部 {value} {currency}",
      openInAudit: "監査を開く",
      showing: "{from}-{to} / 全 {total} 件を表示",
      name: "名称",
      estimated: "推定",
      internal: "内部",
      dailyTrend: "日次費用推移",
      lastSevenDays: "直近 7 日間",
      dailyTrendSubtitle: "現在の期間内での推定費用と Token 変動です。",
      sevenDayView: "7 日表示",
      noTrendData: "まだ推移データがありません。",
    },
    modelManagementPage: {
      title: "モデル管理",
      subtitle:
        "モデル単位で安全モデルと通常モデルを設定します。固定 Base URL を持つベンダーテンプレートを選び、Provider Model を自動取得または手入力できます。",
      addModel: "モデル追加",
      finishEditing:
        "現在の編集を完了またはキャンセルしてから、別のモデルを追加・編集してください。",
      loading: "モデルを読み込み中...",
      loadFailed: "モデルの読み込みに失敗しました",
      noProviderModels: "Provider からモデル一覧が返されませんでした。",
      discoverFailed: "Provider モデルの自動取得に失敗しました",
      requiredFields:
        "表示名、ベンダーテンプレート、Provider Model は必須です。",
      saveFailed: "モデルの保存に失敗しました",
      deleteFailed: "モデルの削除に失敗しました",
      secure: "安全",
      secureModel: "安全モデル",
      active: "有効",
      inactive: "無効",
      providerModel: "Provider Model",
      currency: "通貨",
      baseUrl: "Base URL",
      inputPriceShort: "入力価格 / 1M",
      outputPriceShort: "出力価格 / 1M",
      edit: "編集",
      displayName: "表示名",
      displayNamePlaceholder: "内部安全モデル",
      vendorTemplate: "ベンダーテンプレート",
      vendorTemplatePlaceholder: "ベンダーテンプレートを選択",
      vendorTemplateSearchPlaceholder: "ベンダー名、別名、Base URL を検索...",
      vendorTemplateEmpty: "一致するベンダーテンプレートがありません。",
      currentVendorTemplate: "現在のカスタムエンドポイント",
      providerType: "Provider 種別",
      protocol: "プロトコル",
      baseUrlPlaceholder: "https://api.example.com/v1",
      fixedBaseUrlPlaceholder:
        "ベンダーテンプレートを選択すると Base URL が固定されます",
      fixedBaseUrlHelp:
        "Base URL は選択したベンダーテンプレートで固定されるため、手入力は不要です。",
      editableBaseUrlHelp:
        "Local / Internal テンプレートでは、独自のランタイムやゲートウェイに合わせて Base URL を上書きできます。",
      localProtocolHelp:
        "Local / Internal モデルでは、カスタム Base URL を維持したまま OpenAI-compatible と Anthropic の API を切り替えられます。",
      apiKey: "API Key",
      optionalPlaceholder: "任意",
      secretRef: "Secret Ref",
      secretRefPlaceholder: "namespace/secret-name:key",
      loadingProviderModels: "Provider モデルを読み込み中...",
      selectProviderModel: "Provider Model を選択",
      waitingDiscovery: "自動取得待ち",
      manualProviderModelPlaceholder: "Provider Model を手入力",
      discoveryHelp:
        "ベンダーテンプレートまたは資格情報が変わると候補が自動更新され、必要なら Provider Model を手入力することもできます。",
      discoveryCredentialsHelp:
        "API Key または Secret Ref を入力すると Provider Model 候補を読み込めます。",
      manualFallbackHelp:
        "現在は自動取得できませんが、Provider Model を手入力して続行できます。",
      manualEntryHelp: "この Provider は現在手動入力を使用します。",
      currencyPlaceholder: "USD",
      inputPrice: "入力価格 / 1M tokens",
      outputPrice: "出力価格 / 1M tokens",
      descriptionPlaceholder: "このモデルを使う場面を説明してください。",
      saving: "保存中...",
      empty:
        "まだモデルは設定されていません。追加すると安全/通常 LLM アクセスの統制を始められます。",
      howItWorks: "仕組み",
      howItWorksSecure:
        "安全モデルは、通常の外部モデルに送れない機密プロンプト専用です。",
      howItWorksActive:
        "有効化されたモデルだけが将来のユーザー向け選択肢やルーティングに公開されます。",
      howItWorksDiscovery:
        "組み込みのベンダーテンプレートは主要な OpenAI-compatible Provider とローカル endpoint をカバーし、自動取得できない場合でも Provider Model を手入力できます。",
    },
    riskRulesPage: {
      title: "設定可能な機密検知ルール",
      subtitle:
        "正規表現ベースの機密ポリシーを調整し、各ルールを許可または安全モデルへルーティングするよう設定します。",
      addRule: "ルール追加",
      totalRules: "ルール総数",
      enabled: "有効",
      disabled: "無効",
      allowActions: "許可アクション",
      secureRouteActions: "安全ルートアクション",
      allCategories: "すべての種類",
      searchPlaceholder: "rule id、name、description、pattern を検索...",
      allSeverities: "すべての重大度",
      allActions: "すべてのアクション",
      allStatuses: "すべての状態",
      finishEditing:
        "現在の編集を完了またはキャンセルしてから、別のルールを作成・編集してください。",
      loading: "ルールを読み込み中...",
      loadFailed: "ルールの読み込みに失敗しました",
      requiredFields: "Rule ID、表示名、pattern は必須です。",
      duplicateRuleId: "Rule ID は既に存在します。",
      saveFailed: "ルールの保存に失敗しました",
      disableFailed: "ルールの無効化に失敗しました",
      statusUpdateFailed: "ルール状態の更新に失敗しました",
      action: "アクション",
      pattern: "パターン",
      disable: "無効化",
      enable: "有効化",
      ruleId: "Rule ID",
      ruleIdPlaceholder: "email_address",
      ruleIdLocked:
        "既存ルールの ID はライブポリシーの誤マッピング防止のため固定されています。",
      severity: "重大度",
      sortOrder: "並び順",
      regexPattern: "正規表現パターン",
      patternPlaceholder:
        "(?i)\\\\b[A-Z0-9._%+\\\\-]+@[A-Z0-9.\\\\-]+\\\\.[A-Z]{2,}\\\\b",
      descriptionPlaceholder: "このルールが何を検知するか説明してください。",
      noRules: "現在のフィルタに一致するルールはありません。",
      testLab: "ルールテストラボ",
      testLabSubtitle:
        "サンプルテキストを貼り付けて有効なルールの一致結果を確認するか、保存前に編集中の草稿ルールをテストできます。",
      testEnabled: "有効ルールをテスト",
      testDraft: "草稿ルールをテスト",
      testing: "テスト中...",
      sampleText: "サンプルテキスト",
      samplePlaceholder:
        "サンプルのリクエスト内容を貼り付けて一致結果を確認...",
      sampleRequired: "テストするサンプルテキストを入力してください。",
      noDraftRule: "現在編集中のルールはありません。",
      testFailed: "ルールテストに失敗しました",
      sensitive: "機密あり",
      noMatch: "一致なし",
      highestSeverity: "最高重大度: {value}",
      highestAction: "最高アクション: {value}",
      noMatchesForSample:
        "入力されたサンプルテキストに一致するルールはありませんでした。",
      bulkNoSelection: "少なくとも 1 つのルールを選択してください。",
      bulkStatusUpdateFailed: "ルール状態の一括更新に失敗しました",
      selectVisible: "表示中を選択",
      bulkEnable: "一括有効化",
      bulkDisable: "一括無効化",
      selectRule: "選択",
      categoryPersonal: "個人情報",
      categoryCompany: "企業情報",
      categoryCustomer: "顧客業務",
      categorySecurity: "セキュリティ",
      categoryFinanceLegal: "財務・法務",
      categoryPolitical: "政治敏感",
      categoryCustom: "カスタム",
    },
    systemSettingsPage: {
      loadFailed: "イメージ設定の読み込みに失敗しました",
      requiredFields: "インスタンスタイプとイメージは必須です。",
      duplicateType: "このインスタンスタイプには既にカードがあります。",
      duplicateImage:
        "選択したインスタンスタイプには同じランタイムイメージが既に存在します。",
      saveFailed: "イメージ設定の保存に失敗しました",
      deleteFailed: "イメージ設定の削除に失敗しました",
      runtimeImageCards: "ランタイムイメージカード",
      runtimeImageCardsSubtitle:
        "サポートされている各デスクトップランタイムで使用するイメージアドレスを設定します。保存したカードは組み込み既定値を上書きします。",
      addCard: "カードを追加",
      instanceType: "インスタンスタイプ",
      cardTitle: "カードタイトル",
      imageAddress: "イメージアドレス",
      defaultImage: "既定イメージ",
      empty:
        "ランタイムイメージカードはまだありません。追加するとデスクトップタイプの既定イメージを上書きできます。",
    },
    userManagementPage: {
      loading: "ユーザーを読み込み中...",
      loadFailed: "ユーザーの読み込みに失敗しました",
      deleteFailed: "ユーザーの削除に失敗しました",
      loadQuotaFailed: "クォータの読み込みに失敗しました",
      updateQuotaFailed: "クォータの更新に失敗しました",
      updateRoleFailed: "ロールの更新に失敗しました",
      createFailed: "ユーザーの作成に失敗しました",
      selectCsv: "インポートする CSV ファイルを選択してください",
      importFailed: "ユーザーのインポートに失敗しました",
      importUsers: "ユーザーをインポート",
      showingUsers: "{total} 人中 {from}-{to} 人のユーザーを表示",
      noUsers: "ユーザーが見つかりません",
      importCompleted: "インポート完了: 作成 {created} 件、失敗 {failed} 件",
      expectedColumns: "想定列:",
      lineError: "行 {line}{username}",
      createdAccounts: "作成されたアカウント",
      quota: "クォータ",
      initialPassword: "初期パスワード",
      supportedFormat: "対応形式",
      csvHeaders: "ヘッダー付き CSV ファイル:",
      csvHelp:
        "Username、Role、Max Instances、Max CPU Cores、Max Memory (GB)、Max Storage (GB) は必須です。Email、Password、Max GPU Count は任意です。Password が空の場合はシステム既定のパスワードが使用されます。",
      downloadTemplate: "CSV テンプレートをダウンロード",
      importFile: "ファイルをインポート",
      chooseFile: "ファイルを選択",
      noFileSelected: "ファイルが選択されていません",
      importing: "インポート中...",
      startImport: "インポート開始",
      addNewUser: "新しいユーザーを追加",
      editQuotaFor: "{username} のクォータを編集",
      maxInstances: "最大インスタンス数",
      maxCpuCores: "最大 CPU コア",
      maxMemoryGb: "最大メモリ (GB)",
      maxStorageGb: "最大ストレージ (GB)",
      maxGpuCount: "最大 GPU 数",
      changeRoleFor: "{username} のロールを変更",
      confirmDeleteTitle: "削除の確認",
      confirmDeleteMessage:
        "ユーザー {username} を削除してもよろしいですか？この操作は元に戻せません。",
    },
    errorBoundary: {
      title: "問題が発生しました",
    },
    userDashboard: {
      subtitle:
        "ダッシュボードから仮想デスクトップのインスタンスとリソースを管理します。",
      myInstances: "マイインスタンス",
      running: "稼働中",
      storageUsed: "使用済みストレージ",
      myResourceQuota: "マイリソースクォータ",
      loadingQuota: "クォータを読み込み中...",
      quotaUnavailable: "利用可能なクォータ情報がありません",
      instances: "インスタンス",
      maxCpuCores: "最大 CPU コア",
      maxMemory: "最大メモリ",
      maxStorage: "最大ストレージ",
      maxGpus: "最大 GPU 数",
      recentInstances: "最近のインスタンス",
      viewAll: "すべて表示",
      quickActions: "クイックアクション",
      createNewInstance: "新しいインスタンスを作成",
      viewAllInstances: "すべてのインスタンスを見る",
      noInstancesYet: "まだインスタンスがありません",
      noInstancesSubtitle:
        "最初の仮想デスクトップインスタンスを作成して始めましょう",
      createInstance: "インスタンスを作成",
    },
    instances: {
      listTitle: "マイインスタンス",
      realTimeUpdates: "リアルタイム更新",
      connected: "接続済み",
      disconnected: "未接続",
      createInstance: "インスタンス作成",
      searchPlaceholder: "名前、タイプ、OS で検索...",
      noInstances: "インスタンスがありません",
      noInstancesSubtitle:
        "最初の仮想デスクトップインスタンスを作成してください。",
      noMatchingInstances: "一致するインスタンスがありません",
      noMatchingInstancesSubtitle:
        "フィルターまたは検索条件を調整してください。",
      clearFilters: "フィルターをクリア",
      showingResults: "{total} 件中 {filtered} 件を表示",
      failedToLoad: "インスタンスの読み込みに失敗しました",
      failedToDelete: "インスタンスの削除に失敗しました",
      failedToStart: "インスタンスの開始に失敗しました",
      failedToStop: "インスタンスの停止に失敗しました",
      confirmDelete:
        "このインスタンスを削除してもよろしいですか？この操作は元に戻せません。",
      details: "詳細",
      instanceImage: "インスタンスイメージ",
      runtimeImageSelectionHint:
        "このインスタンスタイプで使用するランタイムイメージのバージョンを選択してください。",
      runtimeImageUnavailable:
        "このインスタンスタイプで利用可能なランタイムイメージは現在ありません。",
      operatingSystem: "オペレーティングシステム",
      access: "アクセス",
      portalView: "ポータル表示",
      portalTitle: "デスクトップポータル",
      portalWorkspace: "インスタンス一覧",
      portalSelectInstance: "インスタンスを選択",
      portalSelectInstanceSubtitle:
        "左側の一覧からデスクトップを選択してください。",
      portalUnavailable: "デスクトップを利用できません",
      portalUnavailableSubtitle:
        "ここからアクセスするには、先にデスクトップインスタンスを起動してください。",
      timeline: "タイムライン",
      storage: "ストレージ",
      resourceConfiguration: "リソース構成",
      kubernetesStatus: "Kubernetes 状態",
      accessInfo: "インスタンスは稼働中で、アクセス可能です。",
      openDesktop: "デスクトップを開く",
      accessUrlUnavailable: "アクセス URL はまだ利用できません",
      startToAccess:
        "デスクトップにアクセスするにはインスタンスを開始してください",
      created: "作成",
      lastStarted: "最終開始",
      lastStopped: "最終停止",
      storageClass: "ストレージクラス",
      mountPath: "マウントパス",
      podName: "Pod 名",
      namespace: "Namespace",
      podIp: "Pod IP",
      podStatus: "Pod 状態",
      loadingInstance: "インスタンスを読み込み中...",
      instanceNotFound: "インスタンスが見つかりません",
      backToInstances: "インスタンス一覧へ戻る",
      basicInformation: "基本情報",
      desktopAccess: "デスクトップアクセス",
      logsPlaceholder: "インスタンスログがここに表示されます...",
      logsComingSoon: "フェーズ 6 で対応予定",
      startTheInstance: "インスタンス停止中",
      startToAccessDesktop:
        "デスクトップにアクセスするにはインスタンスを開始してください。",
      generatingToken: "アクセストークンを生成中...",
      accessError: "アクセスエラー",
      readyToAccess: "アクセス可能です",
      generateAccessPrompt:
        "{name} に接続するためのアクセストークンを生成します。",
      generateAccess: "アクセストークンを生成",
      expiresIn: "有効期限まで",
      refreshToken: "トークンを更新",
      accessTokenExpired: "アクセストークンの期限が切れました",
      regenerateToken: "トークンを再生成",
      instanceMustBeRunning:
        "アクセスするにはインスタンスが稼働中である必要があります",
      failedToGenerateAccessToken: "アクセストークンの生成に失敗しました",
      expired: "期限切れ",
      createTitle: "インスタンス作成",
      stepOf: "ステップ {step}/3: {label}",
      stepBasic: "基本情報",
      stepType: "タイプを選択",
      stepConfig: "構成",
      instanceName: "インスタンス名 *",
      instanceNamePlaceholder: "例: my-desktop",
      minimumThreeChars: "3文字以上",
      descriptionOptional: "説明（任意）",
      descriptionPlaceholder: "このインスタンスの簡単な説明...",
      selectInstanceType: "インスタンスタイプを選択",
      quickConfiguration: "クイック構成",
      customConfiguration: "カスタム構成",
      cpuCores: "CPU コア数",
      memoryGb: "メモリ (GB)",
      diskGb: "ディスク (GB)",
      storageClassOptional: "ストレージクラス（任意）",
      enableGpu: "GPU を有効化",
      gpuCount: "GPU 数",
      summary: "概要",
      createFailed: "インスタンスの作成に失敗しました",
      nameAlreadyExists: "このインスタンス名は既に存在します。",
      next: "次へ",
      back: "戻る",
      createNow: "インスタンスを作成",
      creatingNow: "作成中...",
      defaultStorageClass: "デフォルト",
      instanceIdLabel: "インスタンス ID",
      heroFallbackDescription:
        "クラスタ資源を分離し、専用ストレージとワンクリックの安全な接続を備えたデスクトップ環境です。",
      allocatedCompute: "割り当て済み CPU",
      reservedRam: "予約済みメモリ",
      persistentDisk: "永続ディスク",
      launchLiveSession: "ライブデスクトップを開く",
      desktopAvailableAfterStart:
        "インスタンスの起動後にデスクトップへアクセスできます",
      instanceDossier: "インスタンス概要",
      allocatedProfile: "割り当てプロファイル",
      kubernetesSection: "Kubernetes",
      volumeMapping: "ボリュームマッピング",
      workspaceSection: "ワークスペース",
      openClawWorkspace: "OpenClaw ワークスペース",
      openClawWorkspaceDesc:
        "`.openclaw` フォルダーを 50 MiB までの `.tar.gz` アーカイブとしてインポートまたはエクスポートできます。",
      runtimeWorkspace: "{runtime} ワークスペース",
      runtimeWorkspaceDesc:
        "`{directory}` フォルダーを 50 MiB までの `.tar.gz` アーカイブとしてインポートまたはエクスポートできます。",
      workspaceReady: "利用可能",
      workspacePaused: "停止中",
      exportingOpenClaw: "エクスポート中...",
      exportOpenClaw: ".openclaw をエクスポート",
      importingOpenClaw: "インポート中...",
      importOpenClaw: ".openclaw をインポート",
      importOpenClawSuccess: "OpenClaw ワークスペースをインポートしました。",
      exportingRuntimeWorkspace: "エクスポート中...",
      exportRuntimeWorkspace: "{directory} をエクスポート",
      importingRuntimeWorkspace: "インポート中...",
      importRuntimeWorkspace: "{directory} をインポート",
      importRuntimeWorkspaceSuccess:
        "{runtime} ワークスペースをインポートしました。",
      openClawArchiveTooLarge: "アーカイブが大きすぎます。最大サイズは 50 MiB です。",
      importOpenClawFailed: ".openclaw のインポートに失敗しました: {message}",
      exportOpenClawFailed: ".openclaw のエクスポートに失敗しました: {message}",
      importRuntimeWorkspaceFailed:
        "{directory} のインポートに失敗しました: {message}",
      exportRuntimeWorkspaceFailed:
        "{directory} のエクスポートに失敗しました: {message}",
      memoryReserved: "予約済みメモリ",
      persistentStorage: "永続ストレージ",
      gpuAttached: "GPU 接続数",
      waitingForRunningState:
        ".openclaw をインポートするため、インスタンスが稼働状態になるのを待っています。",
      timedOutWaitingForRunning:
        ".openclaw のインポート前に、インスタンスが稼働状態になるまでの待機がタイムアウトしました。",
      openClawImportTitle: "OpenClaw インポート",
      openClawImportDesc:
        "任意です。エクスポート済みの `.openclaw` アーカイブを選ぶと、インスタンス起動後に自動でインポートします。",
      optional: "任意",
      changeOpenClawArchive: ".openclaw アーカイブを変更",
      chooseOpenClawArchive: ".openclaw アーカイブを選択",
      changeRuntimeArchive: "{directory} アーカイブを変更",
      chooseRuntimeArchive: "{directory} アーカイブを選択",
      remove: "削除",
      selectedArchive: "選択済みアーカイブ: {name}",
      noArchiveSelected:
        "アーカイブが選択されていません。空の .openclaw ワークスペースでインスタンスが作成されます。",
      noRuntimeArchiveSelected:
        "アーカイブが選択されていません。空の {directory} ワークスペースでインスタンスが作成されます。",
      quotaValidation: "クォータ検証",
      unableToLoadQuota:
        "クォータを読み込めませんでした。クォータが取得できるまでインスタンス作成は無効のままです。",
      requestedResourcesExceeded:
        "要求したリソースが割り当てられたクォータを超えています。設定を下げてください。",
      quotaInstances: "インスタンス数",
      checkingQuota: "クォータを確認中...",
      creatingAndImporting: "作成とインポートを実行中...",
      typeOptions: {
        ubuntu: {
          label: "Ubuntu デスクトップ",
          description:
            "GNOME デスクトップを備えた人気の Linux ディストリビューション",
        },
        debian: {
          label: "Debian デスクトップ",
          description: "安定性と安全性に優れた Linux ディストリビューション",
        },
        centos: {
          label: "CentOS デスクトップ",
          description: "エンタープライズ向けの Linux ディストリビューション",
        },
        openclaw: {
          label: "OpenClaw デスクトップ",
          description: "OpenClaw 向けに最適化されたデスクトップ環境",
        },
        webtop: {
          label: "Webtop デスクトップ",
          description:
            "ClawManager 経由でプロキシされるブラウザベースの Linux デスクトップ",
        },
        hermes: {
          label: "Hermes Runtime",
          description:
            "Webtop デスクトップベースで構築された Hermes ランタイム",
        },
        custom: {
          label: "カスタムイメージ",
          description: "独自のカスタムイメージを使用",
        },
      },
      presetOptions: {
        small: {
          label: "Small",
          description: "軽い作業向け",
        },
        medium: {
          label: "Medium",
          description: "開発作業に適したバランス",
        },
        large: {
          label: "Large",
          description: "高負荷ワークロード向け",
        },
      },
      customPresetTitle: "カスタム",
      customPresetDescription: "Medium を起点に手動でサイズを調整します。",
      customPresetEditing: "編集中",
      resourcePresetSummary:
        "{cpu} CPU • {memory} GB メモリ • {disk} GB ディスク",
      mediumDefaultPreset:
        "Medium の既定値: {cpu} CPU • {memory} GB メモリ • {disk} GB ディスク",
      presetCpuShort: "CPU",
      presetRamShort: "RAM",
      presetDiskShort: "ディスク",
      environmentVariables: "環境変数",
      clawManagerBuiltIns: "ClawManager 組み込み変数",
      hideBuiltIns: "組み込み変数を隠す",
      editBuiltIns: "組み込み変数を編集",
      editBuiltInsCount: "組み込み変数を編集 ({count})",
      builtinOverridesConfigured:
        "{count} 件の組み込み変数上書きが設定されています。展開して確認または編集できます。",
      usingBuiltInDefaults:
        "{count} 件の組み込み変数で ClawManager の既定値を使用しています。",
      builtinOverrideHelp:
        "上書きしたい組み込み変数だけを追加してください。未指定の変数は既定の注入値のままです。",
      addBuiltinVariable: "組み込み変数を追加",
      noBuiltinOverrides: "まだ組み込み変数の上書きはありません。",
      defaultValue: "既定値: {value}",
      variable: "変数",
      overrideValue: "上書き値",
      overrideValuePlaceholder: "上書き値",
      actionLabel: "操作",
      customVariables: "カスタム変数",
      addVariable: "変数を追加",
      noCustomEnvironmentVariables: "カスタム環境変数はまだありません。",
      variableNamePlaceholder: "VARIABLE_NAME",
      variableValuePlaceholder: "value",
      customEnvNameRequired: "カスタム環境変数名は必須です。",
      invalidEnvName: "無効な環境変数名: {name}",
      reservedBuiltinEnvName:
        "{name} は ClawManager の組み込み変数です。組み込みセクションで編集してください。",
      duplicateEnvName: "重複した環境変数名: {name}",
      openClawInjection: "OpenClaw 注入",
      runtimeInjection: "{runtime} 注入",
      selectedCount: "{count} 件を選択",
      noReusableSkillsSelected: "再利用可能なスキルが選択されていません。",
      noAvailableSkillsForInjection:
        "利用可能なスキルがありません。先にリソースセンターからスキルをインポートしてください。",
      skillRiskVersionLabel: "{key} · リスク {risk} · v{version}",
      skillPageSummary: "{page}/{totalPages} ページ · スキル {totalSkills} 件",
      archiveImport: "アーカイブのインポート",
      archiveModeRequiresFile: "アーカイブモードではファイルが必須です",
      envInjection: "環境変数注入",
      noEnvOverridesConfigured: "コンテナ環境変数の上書きはまだありません。",
      channelInjection: "Channel 注入",
      archiveSkipsChannelInjection:
        "アーカイブモードではリソースベースの Channel 注入をスキップします。",
      compilingOpenClawPreview: "OpenClaw リソースのプレビューを生成中...",
      compilingRuntimePreview: "Runtime リソースのプレビューを生成中...",
      noChannelsSelectedForInjection: "注入する Channel が選択されていません。",
      skillInjection: "スキル注入",
      envManagedProxyPath: "ClawManager が管理するプロキシパス",
      envGeneratedAtRuntime: "ClawManager が実行時に生成",
      envAssignedAfterCreation: "作成後に割り当て",
      envManagedAtRuntime: "ClawManager が実行時に管理",
      envDescDesktopTitleWebtop:
        "LinuxServer Webtop コンテナに注入されるデスクトップウィンドウのタイトルです。",
      envDescDesktopTitleOpenClaw:
        "OpenClaw ブラウザデスクトップイメージに表示されるデスクトップタイトルです。",
      envDescProxySubfolder:
        "ブラウザアクセスで ClawManager リバースプロキシが使用するパスプレフィックスです。",
      envDescLlmBaseUrl:
        "ClawManager が実行時に生成する OpenClaw ゲートウェイのベース URL です。",
      envDescLlmApiKey:
        "ClawManager がそのインスタンス用に発行するゲートウェイ API キーです。",
      envDescLlmModel:
        "OpenClaw ワークスペースに注入される Gateway モデルカタログ JSON で、先頭は auto のままです。",
      envDescLlmProvider:
        "OpenClaw ワークスペースに渡されるプロバイダーヒントです。",
      envDescInstanceToken:
        "ClawManager がワークスペースアクセス用に生成するインスタンストークンです。",
      envDescOpenAiBaseUrl:
        "OpenAI 互換ゲートウェイのベース URL 用の互換エイリアスです。",
      envDescOpenAiApiBase:
        "OpenAI 互換ゲートウェイのベース URL 用の互換エイリアスです。",
      envDescOpenAiApiKey: "ゲートウェイ API キー用の互換エイリアスです。",
      envDescOpenAiModel: "既定モデル名用の互換エイリアスです。",
      envDescAgentEnabled:
        "OpenClaw 内で ClawManager インスタンス Agent を有効にするかを切り替えます。",
      envDescAgentBaseUrl:
        "インスタンス内 Agent 制御プレーンクライアントが使用するベース URL です。",
      envDescAgentBootstrapToken:
        "ClawManager がインスタンス内 Agent 用に生成するブートストラップトークンです。",
      envDescAgentDiskLimitBytes:
        "インスタンス Agent に注入されるディスククォータです。",
      envDescAgentInstanceId:
        "インスタンス内 Agent に渡されるランタイムインスタンス識別子です。",
      envDescAgentPersistentDir:
        "OpenClaw コンテナにマウントされる永続ワークスペースのパスです。",
      envDescAgentProtocolVersion:
        "ClawManager Agent 制御面が期待するプロトコルバージョンです。",
      gpuLabel: "GPU",
      cpuCoresValue: "{value} コア",
      gpuCountValue: "GPU {count} 基",
      memoryLabel: "メモリ",
      storageLabel: "ストレージ",
      gpuDisabled: "無効",
      noOpenClawArchiveSelected: ".openclaw アーカイブ未選択",
      live: "ライブ",
      notAvailable: "該当なし",
      runtimeCommandFailed: "{command} の実行に失敗しました",
      failedToAttachSkill: "スキルの適用に失敗しました",
      failedToRemoveSkill: "スキルの削除に失敗しました",
      kubernetesStatusTitle: "Pod とインフラの状態",
      infrastructureReady: "インフラ準備完了",
      skillsSection: "スキル",
      skillManagement: "スキル管理",
      selectSkill: "スキルを選択",
      installingSkill: "適用中...",
      installSkill: "スキルを適用",
      noSkillsReported: "このインスタンスではまだスキルが報告されていません。",
      skillFallback: "スキル #{id}",
      lastSeenAt: "最終確認 {value}",
      removingSkill: "削除中...",
      removeSkill: "削除",
      skillPagination: "{total} 件中 {from}-{to} 件のスキルを表示",
      previous: "前へ",
      nextPage: "次へ",
      timelineSubtitle: "インスタンス操作とランタイム履歴",
      timelineEvents: "{count} 件のイベント",
      noRuntimeActivity: "ランタイム活動はまだありません。",
      minimap: "ミニマップ",
      runtimeSummary: "ランタイム概要",
      agentReportedStatus: "Agent 報告ステータス",
      fresh: "最新",
      operatingSystemShort: "OS",
      openClawShort: "OpenClaw",
      agents: "Agent",
      channels: "チャネル",
      agentStatusLabel: "Agent {status}",
      gatewayStatusLabel: "Gateway {status}",
      agentId: "Agent ID",
      agentVersion: "Agent バージョン",
      protocol: "プロトコル",
      lastHeartbeat: "最終ハートビート",
      lastReport: "最終レポート",
      skillSourceUploaded: "アップロード",
      skillSourceDiscovered: "検出",
      skillRiskNone: "安全",
      skillRiskLow: "低",
      skillRiskMedium: "中",
      skillRiskHigh: "高",
      skillRiskUnknown: "不明",
      timelineInstanceCreated: "インスタンス作成",
      timelineInstanceCreatedDetail: "{name} が {type} として作成されました。",
      timelineInstanceStarted: "インスタンス起動",
      timelineInstanceStartedDetail:
        "このインスタンスでインフラ起動が記録されました。",
      timelineInstanceStopped: "インスタンス停止",
      timelineInstanceStoppedDetail:
        "このインスタンスでインフラ停止が記録されました。",
      timelineAgentRegistered: "Agent 登録",
      timelineAgentRegisteredDetail:
        "{agentId} がプロトコル {protocol} で ClawManager に接続しました。",
      timelineRuntimeReported: "ランタイム状態報告",
      timelineRuntimeReportedDetail:
        "Agent が gateway 状態 {gatewayStatus} と infra 状態 {infraStatus} を報告しました。",
      timelinePodStatusObserved: "Pod 状態確認",
      timelinePodStatusObservedDetail:
        "Kubernetes は現在 Pod 状態を {status} と報告しています。",
      timelineCommandWithError: "{status}: {error}",
      timelineCommandWithIdempotency: "{status} · 冪等キー {key}",
      timelineSectionInstance: "instance",
      timelineSectionInfra: "infra",
      timelineSectionAgent: "agent",
      timelineSectionRuntime: "runtime",
      timelineSectionKubernetes: "k8s",
      timelineSectionCommand: "command",
      metricCpu: "CPU",
      metricCpuDetail:
        "{cores} コア · 負荷 1m {load1} · 5m {load5} · 15m {load15}",
      metricMemory: "メモリ",
      metricMemoryDetail: "{used} 使用 / {total}",
      metricDisk: "ディスク",
      metricDiskDetail: "{free} 空き / {total}",
      metricNetwork: "ネットワーク",
      metricNetworkDetail:
        "{interfaces} インターフェースに {addresses} 個のアドレス",
      metricLegendDown: "Down",
      metricLegendUp: "Up",
      metricTrafficDetail: "Inbound {inbound} · Outbound {outbound}",
    },
    openClawResourcesPage: {
      title: "OpenClaw リソース管理",
      tabs: {
        resources: "リソース",
        bundles: "バンドル",
        injections: "注入記録",
      },
      resourceTypesTitle: "リソースタイプ",
      searchPlaceholder: "リソースを検索...",
      resourceListHint:
        "リソースカードをクリックすると、右側ではなくポップアップで編集できます。",
      loadingResources: "リソースを読み込み中...",
      noResources:
        "このタイプのリソースはまだありません。「新規作成」をクリックしてください。",
      enabled: "有効",
      disabled: "無効",
      thisResourceType: "このリソースタイプ",
      notConfigurableYet: "{type} はまだ設定できません。",
      onlyChannelConfigurable:
        "現在設定できるのは Channel のみです。Skill、Agent、Scheduled Task のエディタは後続の更新で追加されます。",
      bundlesSubtitle:
        "再利用可能な OpenClaw 起動パッケージを束ねて、専用ポップアップで編集します。",
      loadingBundles: "バンドルを読み込み中...",
      noBundles:
        "バンドルはまだありません。「新規バンドル」をクリックしてください。",
      bundleResourceCount: "{count} 件のリソース",
      injectionsSubtitle:
        "スナップショットはインスタンス作成時に保存され、再起動時に再利用されます。",
      snapshot: "スナップショット",
      mode: "モード",
      resources: "リソース数",
      envCount: "環境変数数",
      created: "作成日時",
      loadingSnapshots: "スナップショットを読み込み中...",
      noInjectionRecords: "OpenClaw の注入記録はまだありません。",
      paginationSummary: "1ページ {pageSize} 件、{from}-{to} を表示",
      paginationPrev: "前へ",
      paginationNext: "次へ",
      skillUploadHint:
        "`.zip` のみアップロードできます。トップレベルの各ディレクトリが 1 つのスキルとして取り込まれます。",
      loadingSkills: "スキルを読み込み中...",
      noSkills: "まだアップロードされたスキルはありません。",
      skillMeta: "{key} · リスク {risk} · {count} インスタンスで使用中",
      recordModes: {
        none: "なし",
        manual: "手動",
        bundle: "バンドル",
        archive: "アーカイブ",
      },
      recordStatuses: {
        compiled: "コンパイル済み",
        active: "有効",
        failed: "失敗",
      },
      editResourceTitle: "リソースを編集",
      newResourceTitle: "リソースを新規作成",
      editResourceSubtitle:
        "メタデータと JSON をポップアップで集中して編集します。",
      newResourceSubtitle:
        "ページ全体を広げずに、新しい OpenClaw リソースを作成します。",
      resourceKey: "リソースキー",
      name: "名前",
      tags: "タグ",
      tagsPlaceholder: "tag1,tag2",
      channelTemplate: "Channel テンプレート",
      chooseStarterTemplate: "スターターテンプレートを選択",
      channelTemplateHint:
        "ここでは Slack、Telegram、DingTalk、Feishu に対応しています。まずフォームで入力し、必要になったら JSON に切り替えて完全な設定を編集してください。",
      templateKey: "キー: {key}",
      invalidChannelJson:
        "この Channel JSON は現在無効です。先に JSON モードで修正してからフォームに戻ってください。",
      contentJson: "内容 JSON",
      editBundleTitle: "バンドルを編集",
      newBundleTitle: "新規バンドル",
      editBundleSubtitle:
        "再利用可能な起動パッケージをポップアップで編集します。",
      newBundleSubtitle:
        "リソース一覧を離れずに新しい再利用可能バンドルを作成します。",
      bundleName: "バンドル名",
      bundleResources: "バンドルのリソース",
      noResourcesForGroup: "{type} のリソースはまだありません。",
      actions: {
        new: "新規作成",
        newBundle: "新規バンドル",
        loadTemplate: "テンプレートを読み込む",
        saveResource: "リソースを保存",
        createResource: "リソースを作成",
        validateJson: "JSON を検証",
        clone: "複製",
        saveBundle: "バンドルを保存",
        createBundle: "バンドルを作成",
      },
      resourceTypes: {
        channel: "チャネル",
        skill: "スキル",
        session_template: "セッションテンプレート",
        log_policy: "ログポリシー",
        agent: "エージェント",
        scheduled_task: "定期タスク",
      },
      templateCategories: {
        builtin: "内蔵",
        plugin: "プラグイン",
      },
      templates: {
        telegram: {
          label: "Telegram",
          description:
            "DM とグループポリシーを制御できる Telegram Bot API チャネル。",
        },
        dingtalkConnector: {
          label: "DingTalk",
          description:
            "クライアント認証情報と送信元許可リストを設定できる DingTalk チャネル。",
        },
        slack: {
          label: "Slack",
          description: "Bolt ベースの Slack ワークスペースアプリ。",
        },
        feishu: {
          label: "Feishu / Lark",
          description: "アカウント初期値を備えた Feishu / Lark チャネル。",
        },
      },
      editorModes: {
        form: "フォーム",
        json: "JSON",
      },
      channelEditors: {
        dingtalkConnector: {
          title: "DingTalk Channel エディタ",
          description:
            "まずクライアント認証情報フォームから始め、完全な設定が必要なときだけ JSON に切り替えます。",
          fields: {
            clientId: {
              label: "Client ID",
              placeholder: "ding-xxxxxxxxxxxxxx",
            },
            clientSecret: {
              label: "Client Secret",
              placeholder: "client secret",
            },
          },
        },
        feishu: {
          title: "Feishu Channel エディタ",
          description:
            "まずメインアカウントのフォームから始め、完全な設定が必要なときだけ JSON に切り替えます。",
          fields: {
            appId: {
              label: "App ID",
              placeholder: "cli_xxx",
            },
            appSecret: {
              label: "App Secret",
              placeholder: "app secret",
            },
          },
        },
        slack: {
          title: "Slack Channel エディタ",
          description:
            "まず Token フォームから始め、完全な設定が必要なときだけ JSON に切り替えます。",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "xoxb-...",
            },
            appToken: {
              label: "App Token",
              placeholder: "xapp-...",
            },
          },
        },
        telegram: {
          title: "Telegram Channel エディタ",
          description:
            "まず Bot Token フォームから始め、完全な設定が必要なときだけ JSON に切り替えます。",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "123456:ABCDEF",
            },
          },
        },
      },
      notices: {
        resourceUpdated: "リソースを更新しました。",
        resourceCreated: "リソースを作成しました。",
        resourceDeleted: "リソースを削除しました。",
        resourceCloned: "リソースを複製しました。",
        resourceJsonValid: "リソース JSON は有効です。",
        templateLoaded: "{name} テンプレートを読み込みました。",
        bundleUpdated: "バンドルを更新しました。",
        bundleCreated: "バンドルを作成しました。",
        bundleDeleted: "バンドルを削除しました。",
        bundleCloned: "バンドルを複製しました。",
        skillArchiveImported: "スキルアーカイブを取り込みました。",
        skillDeleted: "スキルを削除しました。",
      },
      errors: {
        loadFailed: "OpenClaw リソースの読み込みに失敗しました。",
        saveResource: "リソースの保存に失敗しました。",
        validationFailed: "リソース JSON の検証に失敗しました。",
        deleteResource: "リソースの削除に失敗しました。",
        cloneResource: "リソースの複製に失敗しました。",
        saveBundle: "バンドルの保存に失敗しました。",
        deleteBundle: "バンドルの削除に失敗しました。",
        cloneBundle: "バンドルの複製に失敗しました。",
        importSkillArchive: "スキルアーカイブの取り込みに失敗しました。",
        deleteSkill: "スキルの削除に失敗しました。",
        downloadSkill: "スキルのダウンロードに失敗しました。",
      },
      skillActions: {
        chooseFile: "ファイルを選択",
        uploadArchive: "スキルアーカイブをアップロード",
        download: "ダウンロード",
      },
      risks: {
        none: "安全",
        low: "低",
        medium: "中",
        high: "高",
        unknown: "不明",
      },
      confirms: {
        deleteResource: "リソース「{name}」を削除しますか？",
        deleteBundle: "バンドル「{name}」を削除しますか？",
      },
    },
    openClawInjectionSection: {
      title: "OpenClaw リソース注入",
      subtitle:
        "このインスタンスが OpenClaw をどのように起動するかを選択します。選択中の項目をもう一度クリックすると解除できます。",
      optional: "任意",
      modes: {
        manual: "手動リソース",
        bundle: "バンドル",
        archive: "アーカイブ取り込み",
      },
      loading: "リソース管理データを読み込み中...",
      chooseBundle: "バンドルを選択",
      selectBundle: "バンドルを選んでください",
      bundleOptionCount: "{count} 件のリソース",
      channel: "チャネル",
      noChannelResources: "利用可能なチャネルリソースがありません。",
      errors: {
        chooseBundle: "先にバンドルを選択してください。",
        chooseResource: "少なくとも 1 つのリソースを選択してください。",
        compileFailed: "OpenClaw 起動プレビューの生成に失敗しました。",
      },
    },
  },
  ko: {
    app: { name: "ClawManager" },
    common: {
      loading: "불러오는 중...",
      logout: "로그아웃",
      admin: "관리자",
      user: "사용자",
      comingSoon: "곧 제공 예정",
      language: "언어",
      refresh: "새로고침",
      retry: "다시 시도",
      create: "생성",
      save: "저장",
      cancel: "취소",
      close: "닫기",
      overview: "개요",
      logs: "로그",
      description: "설명",
      type: "유형",
      status: "상태",
      createdAt: "생성 시간",
      lastUpdated: "마지막 업데이트",
      open: "열기",
      stop: "중지",
      start: "시작",
      restart: "재시작",
      delete: "삭제",
      cpu: "CPU",
      memory: "메모리",
      disk: "디스크",
      search: "검색",
      all: "전체",
    },
    status: {
      all: "전체",
      running: "실행 중",
      stopped: "중지됨",
      creating: "생성 중",
      error: "오류",
      deleting: "삭제 중",
    },
    nav: {
      dashboard: "대시보드",
      adminDashboard: "콘솔",
      userDashboard: "워크스페이스",
      users: "사용자",
      instances: "인스턴스",
      aiGateway: "AI Gateway",
      aiAudit: "AI 감사",
      costs: "비용",
      riskRules: "리스크 규칙",
      models: "모델",
      settings: "설정",
      myInstances: "내 인스턴스",
      openClawConfigs: "리소스 관리",
      backToDashboard: "대시보드로 돌아가기",
      backToUserDashboard: "워크스페이스",
      securityCenter: "보안 센터",
      adminPanel: "관리 패널",
    },
    adminLayout: adminLayoutTranslations.ko,
    securityCenter: securityCenterTranslations.ko,
    auth: {
      signInTitle: "ClawManager 로그인",
      subtitle: "가상 데스크톱 관리 플랫폼",
      username: "사용자 이름",
      password: "비밀번호",
      email: "이메일",
      usernamePlaceholder: "사용자 이름을 입력하세요",
      passwordPlaceholder: "비밀번호를 입력하세요",
      signIn: "로그인",
      signingIn: "로그인 중...",
      noAccount: "계정이 없으신가요?",
      signUp: "회원가입",
      createAccount: "계정 만들기",
      joinToday: "지금 ClawManager에 가입하세요",
      chooseUsername: "사용자 이름 선택",
      enterEmail: "이메일을 입력하세요",
      createPassword: "비밀번호 만들기 (최소 8자)",
      confirmPassword: "비밀번호 확인",
      confirmPasswordPlaceholder: "비밀번호를 다시 입력하세요",
      createAccountAction: "계정 만들기",
      creatingAccount: "생성 중...",
      alreadyHaveAccount: "이미 계정이 있으신가요?",
      passwordsMismatch: "비밀번호가 일치하지 않습니다",
      passwordTooShort: "비밀번호는 최소 8자 이상이어야 합니다",
      changePassword: "비밀번호 변경",
      currentPassword: "현재 비밀번호",
      newPassword: "새 비밀번호",
      confirmNewPassword: "새 비밀번호 확인",
      changePasswordAction: "비밀번호 업데이트",
      changePasswordDesc: "설정에서 계정 비밀번호를 업데이트하세요.",
      changingPassword: "업데이트 중...",
      passwordChanged: "비밀번호가 성공적으로 변경되었습니다",
      changePasswordFailed: "비밀번호 변경에 실패했습니다",
      loginFailed: "로그인 실패",
    },
    admin: {
      dashboardTitle: "콘솔",
      userManagement: "사용자 관리",
      userManagementDesc: "사용자, 역할, 할당량 관리",
      instanceManagement: "인스턴스 관리",
      instanceManagementDesc: "가상 데스크톱 인스턴스 관리",
      globalInstances: "전체 인스턴스",
      globalInstancesDesc:
        "모든 사용자 인스턴스를 한 곳에서 검색, 필터링, 조작합니다.",
      instanceSearchPlaceholder:
        "인스턴스, 사용자, 유형, Pod 또는 네임스페이스로 검색...",
      allStatuses: "모든 상태",
      allTypes: "모든 유형",
      showingInstances: "{total}개 중 {filtered}개 표시",
      loadingInstances: "인스턴스를 불러오는 중...",
      noFilteredInstances: "현재 필터에 맞는 인스턴스가 없습니다.",
      instanceColumn: "인스턴스",
      userColumn: "사용자",
      typeOsColumn: "유형 / OS",
      resourcesColumn: "리소스",
      k8sColumn: "K8s",
      actionsColumn: "작업",
      updatedAtLabel: "업데이트 시간",
      userIdLabel: "사용자 ID",
      gpuLabel: "GPU",
      failedToLoadInstances: "인스턴스를 불러오지 못했습니다",
      failedToStartInstance: "인스턴스 시작에 실패했습니다",
      failedToStopInstance: "인스턴스 중지에 실패했습니다",
      failedToRestartInstance: "인스턴스 재시작에 실패했습니다",
      failedToSyncInstance: "인스턴스 동기화에 실패했습니다",
      failedToDeleteInstance: "인스턴스 삭제에 실패했습니다",
      confirmDeleteInstance: "인스턴스 {name}을 삭제하시겠습니까?",
      systemSettings: "시스템 설정",
      systemSettingsDesc: "시스템 설정 구성",
      systemOverview: "시스템 개요",
      totalUsers: "총 사용자 수",
      totalInstances: "총 인스턴스 수",
      runningInstances: "실행 중 인스턴스",
      totalStorage: "총 스토리지",
      instanceManagementStub:
        "이 기능은 현재 개발 중입니다. 잠시 후 다시 확인하세요.",
      systemSettingsStub:
        "이 기능은 현재 개발 중입니다. 잠시 후 다시 확인하세요.",
      addUser: "사용자 추가",
      dashboardLoadFailed: "대시보드 통계를 불러오지 못했습니다",
      clusterCommand: "클러스터 커맨드",
      clusterHeroTitle: "클러스터 기본 정보 개요",
      clusterHeroDesc:
        "이 대시보드는 설정 화면이 아니라 운영 조종석처럼 보여야 합니다. 핵심 지표를 먼저 보여주고 노드 압력을 한눈에 파악할 수 있어야 합니다.",
      accountsWithAccess: "접근 가능한 계정",
      provisionedDesktops: "생성된 데스크톱",
      currentlyOnline: "현재 온라인",
      allocatedToInstances: "인스턴스에 할당됨",
      readiness: "준비 상태",
      clusterStatusPending: "클러스터 상태를 확인하는 중",
      nodesHealthySchedulable:
        "노드의 {percent}% 가 정상이며 스케줄 가능합니다.",
      hotNode: "고부하 노드",
      cpuRequested: "요청된 CPU",
      memoryRequested: "요청된 메모리",
      diskAllocated: "할당된 디스크",
      pressureFocus: "집중 확인 지점",
      pressureFocusMem: "메모리 {percent}%",
      clusterResources: "클러스터 리소스",
      capacityBoard: "용량 보드",
      waitingForClusterData: "클러스터 데이터를 기다리는 중",
      nodesReadySummary: "{ready}/{total} 노드 준비 완료",
      nodeFleet: "노드 플릿",
      nodes: "노드",
      healthyNodesScheduling: "스케줄 가능한 정상 노드",
      computePressure: "연산 압력",
      memoryPressure: "메모리 압력",
      persistentAllocation: "영구 할당량",
      requestedVsAllocatable: "요청량 / 할당 가능량",
      allocatedVsAllocatable: "할당량 / 할당 가능량",
      capacityCores: "총 용량 {value} 코어",
      capacityGiB: "총 용량 {value} GiB",
      usage: "사용률",
      nodeMatrix: "노드 매트릭스",
      infrastructureTable: "인프라 표",
      infrastructureTableDesc:
        "한 번에 전체 클러스터를 훑어볼 수 있습니다. 아무 노드나 펼치면 CPU, 메모리, 디스크, kubelet 세부 정보를 볼 수 있습니다.",
      node: "노드",
      health: "상태",
      ready: "준비됨",
      role: "역할",
      internalIp: "내부 IP",
      pods: "Pod 수",
      cpuLoad: "CPU 부하",
      memoryLoad: "메모리 부하",
      inspect: "확인",
      nodeDossier: "노드 개요",
      kubeletVersion: "Kubelet 버전",
      roles: "역할",
      podCount: "Pod 수",
      diskSummary: "디스크 요약",
      resourceProfile: "리소스 프로필",
      noNodeData: "클러스터에서 노드 데이터를 반환하지 않았습니다.",
      showingNodes: "{total}개 노드 중 {from}-{to} 표시",
      prev: "이전",
      nextPage: "다음",
      pageSummary: "{page} / {total} 페이지",
      collapse: "접기",
      viewDetails: "상세",
      notReady: "준비 안 됨",
      openSection: "열기",
    },
    aiGatewayPage: {
      badge: "거버넌스 허브",
      title: "AI 게이트웨이 관리 센터",
      subtitle:
        "모델 카탈로그, 감사 추적, 비용 보고, 민감 콘텐츠 규칙을 이곳에서 통합 관리합니다.",
      modelsDescription:
        "일반 모델과 보안 모델, Provider 엔드포인트, 가격, 활성 상태를 관리합니다.",
      auditDescription:
        "Trace ID, 요청/응답 payload, 리스크 히트, 라우팅 결정, 호출 상세를 확인합니다.",
      costsDescription:
        "Token 사용량, 예상 비용, 내부 보안 모델 비용, 연계된 청구 세부를 확인합니다.",
      riskRulesDescription:
        "정규식 기반 민감 규칙, 심각도, 동작, 실행 순서를 조정합니다.",
    },
    aiAuditPage: {
      title: "최근 AI Trace",
      subtitle:
        "통제된 모델 호출, Trace, Token 사용량, 상태, 실제 라우팅 결과를 확인합니다.",
      loadFailed: "AI 감사 기록을 불러오지 못했습니다",
      detailLoadFailed: "Trace 상세를 불러오지 못했습니다",
      copyFailed: "Trace ID 복사에 실패했습니다",
      completed: "완료",
      blocked: "차단됨",
      failed: "실패",
      pending: "처리 중",
      tokensOnPage: "현재 페이지 Token",
      traceTable: "Trace 테이블",
      traceTableSubtitle: "검색, 필터, 점검을 한 테이블에서 처리합니다.",
      searchPlaceholder: "trace, request, user, model 검색...",
      allStatuses: "모든 상태",
      modelPlaceholder: "모델로 필터...",
      loading: "감사 기록을 불러오는 중...",
      empty: "AI 감사 기록이 없습니다.",
      trace: "Trace",
      user: "사용자",
      requested: "요청 모델",
      providerResult: "실제 결과",
      failureReason: "실패 원인",
      usage: "사용량",
      action: "작업",
      copy: "복사",
      copied: "복사됨",
      noLatency: "지연 데이터 없음",
      detailTitle: "Trace 상세",
      detailSubtitle:
        "Trace를 선택해 invocation payload, 감사 이벤트, 비용 기록을 확인하세요.",
      detailLoading: "Trace 상세를 불러오는 중...",
      noTraceSelected: "아직 Trace가 선택되지 않았습니다.",
      executionFlow: "실행 흐름",
      executionFlowSubtitle:
        "한 번의 OpenClaw 질의를 모델 호출, 도구 호출, 도구 출력, 최종 응답까지 한 흐름으로 확인합니다.",
      flowMinimap: "미니맵",
      flowMinimapSubtitle:
        "실행 단계를 한눈에 보고, 클릭해서 원하는 위치로 바로 이동할 수 있습니다.",
      noFlowNodes: "이 Trace에는 아직 시각화할 실행 흐름 노드가 없습니다.",
      flowNode: "흐름 노드",
      flowUserMessage: "사용자 메시지",
      flowLlmCall: "LLM 호출",
      flowToolCall: "도구 호출",
      flowToolOutput: "도구 출력",
      flowAssistantResponse: "어시스턴트 응답",
      flowAssistantMessage: "어시스턴트 메시지",
      nodeInput: "입력",
      nodeOutput: "출력",
      requestIdLabel: "Request ID",
      modelLabel: "Model",
      userLabel: "사용자: {user}",
      sessionLabel: "세션: {session}",
      copyTraceId: "Trace ID 복사",
      clear: "지우기",
      invocations: "호출 기록",
      noInvocation: "이 Trace에는 저장된 invocation 레코드가 없습니다.",
      payloads: "Payload",
      auditEvents: "감사 이벤트",
      costRecords: "비용 기록",
      noCostRecords:
        "이 Trace에는 비용 기록이 없습니다. 보통 과금 가능한 모델 호출에 도달하기 전에 요청이 차단되거나 실패했음을 의미합니다.",
      riskHits: "리스크 히트",
      noRiskHits: "이 Trace에는 민감 콘텐츠 히트가 기록되지 않았습니다.",
      messages: "메시지",
      noMessages: "이 Trace에는 저장된 메시지가 없습니다.",
    },
    costsPage: {
      badge: "비용 개요",
      title: "한 화면에서 보는 AI 비용",
      subtitle:
        "Token 규모, 예상 비용, 내부 비용, 그리고 이상 급증에 연결된 Trace를 확인합니다.",
      loadFailed: "AI 비용 개요를 불러오지 못했습니다",
      loading: "AI 비용 개요를 불러오는 중...",
      promptTokens: "입력 Token",
      promptTokensNote: "입력 프롬프트 규모",
      completionTokens: "출력 Token",
      completionTokensNote: "생성 출력 규모",
      estimatedSpend: "예상 비용",
      estimatedSpendNote: "Provider 단가 기준 추정",
      internalCost: "내부 비용",
      internalCostNote: "보안 모델 내부 정산",
      userTotals: "사용자 집계",
      userTotalsSubtitle: "사용자별 사용량과 비용 집계",
      instanceTotals: "인스턴스 집계",
      instanceTotalsSubtitle: "인스턴스별 사용량과 비용 집계",
      recentRecords: "최근 비용 기록",
      recentRecordsSubtitle:
        "Trace와 연결된 비용 기록을 검색·페이지 처리하고 바로 감사 화면으로 이동합니다.",
      searchPlaceholder: "trace, user, model 검색...",
      pageSize10: "10 / 페이지",
      pageSize20: "20 / 페이지",
      pageSize50: "50 / 페이지",
      apply: "적용",
      trace: "Trace",
      user: "사용자",
      instance: "인스턴스",
      model: "모델",
      tokens: "Token",
      spend: "비용",
      recorded: "기록 시간",
      instanceId: "ID {id}",
      internalValue: "내부 {value} {currency}",
      openInAudit: "감사 열기",
      showing: "{from}-{to} / 총 {total}개 표시",
      name: "이름",
      estimated: "예상",
      internal: "내부",
      dailyTrend: "일별 비용 추이",
      lastSevenDays: "최근 7일",
      dailyTrendSubtitle: "현재 구간의 예상 비용과 Token 변동입니다.",
      sevenDayView: "7일 보기",
      noTrendData: "추이 데이터가 아직 없습니다.",
    },
    modelManagementPage: {
      title: "모델 관리",
      subtitle:
        "모델 단위로 보안 모델과 일반 모델을 구성합니다. 고정 Base URL이 포함된 벤더 템플릿을 선택하고 Provider Model을 자동으로 불러오거나 직접 입력할 수 있습니다.",
      addModel: "모델 추가",
      finishEditing:
        "현재 편집을 완료하거나 취소한 뒤 다른 모델을 추가하거나 편집하세요.",
      loading: "모델을 불러오는 중...",
      loadFailed: "모델을 불러오지 못했습니다",
      noProviderModels: "Provider가 모델 목록을 반환하지 않았습니다.",
      discoverFailed: "Provider 모델 자동 검색에 실패했습니다",
      requiredFields: "표시 이름, 벤더 템플릿, Provider Model은 필수입니다.",
      saveFailed: "모델 저장에 실패했습니다",
      deleteFailed: "모델 삭제에 실패했습니다",
      secure: "보안",
      secureModel: "보안 모델",
      active: "활성",
      inactive: "비활성",
      providerModel: "Provider Model",
      currency: "통화",
      baseUrl: "Base URL",
      inputPriceShort: "입력 가격 / 1M",
      outputPriceShort: "출력 가격 / 1M",
      edit: "편집",
      displayName: "표시 이름",
      displayNamePlaceholder: "내부 보안 모델",
      vendorTemplate: "벤더 템플릿",
      vendorTemplatePlaceholder: "벤더 템플릿 선택",
      vendorTemplateSearchPlaceholder: "벤더 이름, 별칭 또는 Base URL 검색...",
      vendorTemplateEmpty: "검색과 일치하는 벤더 템플릿이 없습니다.",
      currentVendorTemplate: "현재 사용자 정의 엔드포인트",
      providerType: "Provider 유형",
      protocol: "프로토콜",
      baseUrlPlaceholder: "https://api.example.com/v1",
      fixedBaseUrlPlaceholder: "벤더 템플릿을 선택하면 Base URL이 고정됩니다",
      fixedBaseUrlHelp:
        "Base URL은 선택한 벤더 템플릿으로 고정되며 직접 입력할 필요가 없습니다.",
      editableBaseUrlHelp:
        "Local / Internal 템플릿은 자체 런타임이나 게이트웨이에 맞게 Base URL을 수정할 수 있습니다.",
      localProtocolHelp:
        "Local / Internal 모델은 사용자 지정 Base URL을 유지한 채 OpenAI-compatible API와 Anthropic API 사이를 전환할 수 있습니다.",
      apiKey: "API Key",
      optionalPlaceholder: "선택 사항",
      secretRef: "Secret Ref",
      secretRefPlaceholder: "namespace/secret-name:key",
      loadingProviderModels: "Provider 모델을 불러오는 중...",
      selectProviderModel: "Provider Model 선택",
      waitingDiscovery: "자동 검색 대기 중",
      manualProviderModelPlaceholder: "Provider Model 직접 입력",
      discoveryHelp:
        "벤더 템플릿이나 인증 정보가 바뀌면 후보가 자동으로 갱신되며, 필요하면 Provider Model을 직접 입력할 수도 있습니다.",
      discoveryCredentialsHelp:
        "Provider Model 후보를 불러오려면 API Key 또는 Secret Ref를 입력하세요.",
      manualFallbackHelp:
        "지금은 자동 검색을 사용할 수 없지만 Provider Model을 직접 입력해 계속 진행할 수 있습니다.",
      manualEntryHelp: "이 Provider는 현재 수동 모델 입력을 사용합니다.",
      currencyPlaceholder: "USD",
      inputPrice: "입력 가격 / 1M tokens",
      outputPrice: "출력 가격 / 1M tokens",
      descriptionPlaceholder: "이 모델을 언제 사용하는지 설명하세요.",
      saving: "저장 중...",
      empty:
        "아직 설정된 모델이 없습니다. 추가하면 보안/일반 LLM 접근 제어를 시작할 수 있습니다.",
      howItWorks: "작동 방식",
      howItWorksSecure:
        "보안 모델은 일반 외부 모델로 보낼 수 없는 민감 프롬프트 전용입니다.",
      howItWorksActive:
        "활성화된 모델만 향후 사용자 선택기와 라우팅 정책에 노출됩니다.",
      howItWorksDiscovery:
        "기본 제공 벤더 템플릿은 주요 OpenAI-compatible Provider와 로컬 endpoint를 포함하며, 자동 검색이 안 되더라도 Provider Model을 수동으로 입력할 수 있습니다.",
    },
    riskRulesPage: {
      title: "구성 가능한 민감 감지 규칙",
      subtitle:
        "정규식 기반 민감 정책을 조정하고 각 규칙을 허용 또는 보안 모델 라우팅으로 설정합니다.",
      addRule: "규칙 추가",
      totalRules: "규칙 수",
      enabled: "활성",
      disabled: "비활성",
      allowActions: "허용 액션",
      secureRouteActions: "보안 라우팅 액션",
      allCategories: "모든 유형",
      searchPlaceholder: "rule id, name, description, pattern 검색...",
      allSeverities: "모든 심각도",
      allActions: "모든 액션",
      allStatuses: "모든 상태",
      finishEditing:
        "현재 편집을 완료하거나 취소한 뒤 다른 규칙을 생성하거나 편집하세요.",
      loading: "규칙을 불러오는 중...",
      loadFailed: "규칙을 불러오지 못했습니다",
      requiredFields: "Rule ID, 표시 이름, pattern은 필수입니다.",
      duplicateRuleId: "Rule ID가 이미 존재합니다.",
      saveFailed: "규칙 저장에 실패했습니다",
      disableFailed: "규칙 비활성화에 실패했습니다",
      statusUpdateFailed: "규칙 상태 업데이트에 실패했습니다",
      action: "액션",
      pattern: "패턴",
      disable: "비활성화",
      enable: "활성화",
      ruleId: "Rule ID",
      ruleIdPlaceholder: "email_address",
      ruleIdLocked:
        "기존 Rule ID는 운영 정책 매핑 혼선을 막기 위해 잠금 처리됩니다.",
      severity: "심각도",
      sortOrder: "정렬 순서",
      regexPattern: "정규식 패턴",
      patternPlaceholder:
        "(?i)\\\\b[A-Z0-9._%+\\\\-]+@[A-Z0-9.\\\\-]+\\\\.[A-Z]{2,}\\\\b",
      descriptionPlaceholder: "이 규칙이 무엇을 감지하는지 설명하세요.",
      noRules: "현재 필터에 맞는 규칙이 없습니다.",
      testLab: "규칙 테스트 랩",
      testLabSubtitle:
        "샘플 텍스트를 붙여 넣어 활성 규칙의 매칭 결과를 미리 보거나, 저장 전에 현재 편집 중인 초안 규칙을 테스트할 수 있습니다.",
      testEnabled: "활성 규칙 테스트",
      testDraft: "초안 규칙 테스트",
      testing: "테스트 중...",
      sampleText: "샘플 텍스트",
      samplePlaceholder: "샘플 요청 내용을 붙여 넣어 규칙 매칭을 확인하세요...",
      sampleRequired: "테스트할 샘플 텍스트를 입력하세요.",
      noDraftRule: "현재 편집 중인 규칙이 없습니다.",
      testFailed: "규칙 테스트에 실패했습니다",
      sensitive: "민감 감지",
      noMatch: "매치 없음",
      highestSeverity: "최고 심각도: {value}",
      highestAction: "최고 액션: {value}",
      noMatchesForSample: "입력한 샘플 텍스트와 일치하는 규칙이 없습니다.",
      bulkNoSelection: "먼저 하나 이상의 규칙을 선택하세요.",
      bulkStatusUpdateFailed: "규칙 상태 일괄 업데이트에 실패했습니다",
      selectVisible: "표시 항목 선택",
      bulkEnable: "일괄 활성화",
      bulkDisable: "일괄 비활성화",
      selectRule: "선택",
      categoryPersonal: "개인정보",
      categoryCompany: "회사정보",
      categoryCustomer: "고객업무",
      categorySecurity: "보안",
      categoryFinanceLegal: "재무·법무",
      categoryPolitical: "정치민감",
      categoryCustom: "사용자 정의",
    },
    systemSettingsPage: {
      loadFailed: "이미지 설정을 불러오지 못했습니다",
      requiredFields: "인스턴스 유형과 이미지는 필수입니다.",
      duplicateType: "이 인스턴스 유형에는 이미 카드가 있습니다.",
      duplicateImage:
        "선택한 인스턴스 유형에 동일한 런타임 이미지가 이미 있습니다.",
      saveFailed: "이미지 설정을 저장하지 못했습니다",
      deleteFailed: "이미지 설정을 삭제하지 못했습니다",
      runtimeImageCards: "런타임 이미지 카드",
      runtimeImageCardsSubtitle:
        "지원되는 각 데스크톱 런타임에서 사용할 이미지 주소를 설정합니다. 저장된 카드는 기본 내장값을 덮어씁니다.",
      addCard: "카드 추가",
      instanceType: "인스턴스 유형",
      cardTitle: "카드 제목",
      imageAddress: "이미지 주소",
      defaultImage: "기본 이미지",
      empty:
        "아직 런타임 이미지 카드가 없습니다. 카드를 추가하면 데스크톱 유형의 기본 이미지를 덮어쓸 수 있습니다.",
    },
    userManagementPage: {
      loading: "사용자를 불러오는 중...",
      loadFailed: "사용자를 불러오지 못했습니다",
      deleteFailed: "사용자를 삭제하지 못했습니다",
      loadQuotaFailed: "할당량을 불러오지 못했습니다",
      updateQuotaFailed: "할당량을 업데이트하지 못했습니다",
      updateRoleFailed: "역할을 업데이트하지 못했습니다",
      createFailed: "사용자를 생성하지 못했습니다",
      selectCsv: "가져올 CSV 파일을 선택하세요",
      importFailed: "사용자 가져오기에 실패했습니다",
      importUsers: "사용자 가져오기",
      showingUsers: "총 {total}명 중 {from}-{to}명 사용자 표시",
      noUsers: "사용자를 찾을 수 없습니다",
      importCompleted: "가져오기 완료: 생성 {created}명, 실패 {failed}명",
      expectedColumns: "필수 열:",
      lineError: "{line}행{username}",
      createdAccounts: "생성된 계정",
      quota: "할당량",
      initialPassword: "초기 비밀번호",
      supportedFormat: "지원 형식",
      csvHeaders: "헤더가 포함된 CSV 파일:",
      csvHelp:
        "Username, Role, Max Instances, Max CPU Cores, Max Memory (GB), Max Storage (GB)는 필수입니다. Email, Password, Max GPU Count는 선택 사항입니다. Password가 비어 있으면 시스템 기본 비밀번호가 사용됩니다.",
      downloadTemplate: "CSV 템플릿 다운로드",
      importFile: "파일 가져오기",
      chooseFile: "파일 선택",
      noFileSelected: "선택된 파일이 없습니다",
      importing: "가져오는 중...",
      startImport: "가져오기 시작",
      addNewUser: "새 사용자 추가",
      editQuotaFor: "{username}의 할당량 편집",
      maxInstances: "최대 인스턴스 수",
      maxCpuCores: "최대 CPU 코어",
      maxMemoryGb: "최대 메모리 (GB)",
      maxStorageGb: "최대 스토리지 (GB)",
      maxGpuCount: "최대 GPU 수",
      changeRoleFor: "{username}의 역할 변경",
      confirmDeleteTitle: "삭제 확인",
      confirmDeleteMessage:
        "사용자 {username}을(를) 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
    },
    errorBoundary: {
      title: "문제가 발생했습니다",
    },
    userDashboard: {
      subtitle: "대시보드에서 가상 데스크톱 인스턴스와 리소스를 관리하세요.",
      myInstances: "내 인스턴스",
      running: "실행 중",
      storageUsed: "사용 중인 스토리지",
      myResourceQuota: "내 리소스 할당량",
      loadingQuota: "할당량 불러오는 중...",
      quotaUnavailable: "사용 가능한 할당량 정보가 없습니다",
      instances: "인스턴스",
      maxCpuCores: "최대 CPU 코어",
      maxMemory: "최대 메모리",
      maxStorage: "최대 스토리지",
      maxGpus: "최대 GPU 수",
      recentInstances: "최근 인스턴스",
      viewAll: "전체 보기",
      quickActions: "빠른 작업",
      createNewInstance: "새 인스턴스 생성",
      viewAllInstances: "모든 인스턴스 보기",
      noInstancesYet: "아직 인스턴스가 없습니다",
      noInstancesSubtitle: "첫 번째 가상 데스크톱 인스턴스를 만들어 시작하세요",
      createInstance: "인스턴스 생성",
    },
    instances: {
      listTitle: "내 인스턴스",
      realTimeUpdates: "실시간 업데이트",
      connected: "연결됨",
      disconnected: "연결 끊김",
      createInstance: "인스턴스 생성",
      searchPlaceholder: "이름, 유형 또는 OS로 검색...",
      noInstances: "인스턴스가 없습니다",
      noInstancesSubtitle:
        "첫 번째 가상 데스크톱 인스턴스를 생성해 시작하세요.",
      noMatchingInstances: "일치하는 인스턴스가 없습니다",
      noMatchingInstancesSubtitle: "필터나 검색어를 조정해 보세요.",
      clearFilters: "필터 초기화",
      showingResults: "{total}개 중 {filtered}개 표시",
      failedToLoad: "인스턴스를 불러오지 못했습니다",
      failedToDelete: "인스턴스 삭제에 실패했습니다",
      failedToStart: "인스턴스 시작에 실패했습니다",
      failedToStop: "인스턴스 중지에 실패했습니다",
      confirmDelete:
        "이 인스턴스를 정말 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
      details: "세부정보",
      instanceImage: "인스턴스 이미지",
      runtimeImageSelectionHint:
        "이 인스턴스 유형에 사용할 런타임 이미지 버전을 선택하세요.",
      runtimeImageUnavailable:
        "이 인스턴스 유형에 현재 사용할 수 있는 런타임 이미지가 없습니다.",
      operatingSystem: "운영체제",
      access: "접속",
      portalView: "포털 보기",
      portalTitle: "데스크톱 포털",
      portalWorkspace: "인스턴스",
      portalSelectInstance: "인스턴스 선택",
      portalSelectInstanceSubtitle: "목록에서 데스크톱을 선택해 시작하세요.",
      portalUnavailable: "데스크톱을 사용할 수 없습니다",
      portalUnavailableSubtitle:
        "여기에서 접근하려면 먼저 데스크톱 인스턴스를 시작하세요.",
      timeline: "타임라인",
      storage: "스토리지",
      resourceConfiguration: "리소스 구성",
      kubernetesStatus: "Kubernetes 상태",
      accessInfo: "인스턴스가 실행 중이며 접근할 수 있습니다.",
      openDesktop: "데스크톱 열기",
      accessUrlUnavailable: "접속 URL을 아직 사용할 수 없습니다",
      startToAccess: "데스크톱에 접속하려면 인스턴스를 시작하세요",
      created: "생성됨",
      lastStarted: "마지막 시작",
      lastStopped: "마지막 중지",
      storageClass: "스토리지 클래스",
      mountPath: "마운트 경로",
      podName: "Pod 이름",
      namespace: "네임스페이스",
      podIp: "Pod IP",
      podStatus: "Pod 상태",
      loadingInstance: "인스턴스를 불러오는 중...",
      instanceNotFound: "인스턴스를 찾을 수 없습니다",
      backToInstances: "인스턴스 목록으로 돌아가기",
      basicInformation: "기본 정보",
      desktopAccess: "데스크톱 접속",
      logsPlaceholder: "인스턴스 로그가 여기에 표시됩니다...",
      logsComingSoon: "6단계에서 지원 예정",
      startTheInstance: "인스턴스 중지됨",
      startToAccessDesktop: "데스크톱에 접속하려면 인스턴스를 시작하세요.",
      generatingToken: "접속 토큰 생성 중...",
      accessError: "접속 오류",
      readyToAccess: "접속 준비 완료",
      generateAccessPrompt: "{name}에 연결할 접속 토큰을 생성합니다.",
      generateAccess: "접속 토큰 생성",
      expiresIn: "만료까지",
      refreshToken: "토큰 새로고침",
      accessTokenExpired: "접속 토큰이 만료되었습니다",
      regenerateToken: "토큰 재생성",
      instanceMustBeRunning: "접속하려면 인스턴스가 실행 중이어야 합니다",
      failedToGenerateAccessToken: "접속 토큰 생성에 실패했습니다",
      expired: "만료됨",
      createTitle: "인스턴스 생성",
      stepOf: "3단계 중 {step}단계: {label}",
      stepBasic: "기본 정보",
      stepType: "유형 선택",
      stepConfig: "구성",
      instanceName: "인스턴스 이름 *",
      instanceNamePlaceholder: "예: my-desktop",
      minimumThreeChars: "최소 3자",
      descriptionOptional: "설명 (선택)",
      descriptionPlaceholder: "이 인스턴스에 대한 간단한 설명...",
      selectInstanceType: "인스턴스 유형 선택",
      quickConfiguration: "빠른 구성",
      customConfiguration: "사용자 지정 구성",
      cpuCores: "CPU 코어",
      memoryGb: "메모리 (GB)",
      diskGb: "디스크 (GB)",
      storageClassOptional: "스토리지 클래스 (선택)",
      enableGpu: "GPU 활성화",
      gpuCount: "GPU 수",
      summary: "요약",
      createFailed: "인스턴스 생성 실패",
      nameAlreadyExists: "같은 이름의 인스턴스가 이미 존재합니다.",
      next: "다음",
      back: "이전",
      createNow: "인스턴스 생성",
      creatingNow: "생성 중...",
      defaultStorageClass: "기본값",
      instanceIdLabel: "인스턴스 ID",
      heroFallbackDescription:
        "클러스터 자원을 분리하고 전용 스토리지와 원클릭 보안 접속을 제공하는 전용 데스크톱 작업 공간입니다.",
      allocatedCompute: "할당된 연산 자원",
      reservedRam: "예약된 메모리",
      persistentDisk: "영구 디스크",
      launchLiveSession: "실행 중인 데스크톱 열기",
      desktopAvailableAfterStart:
        "인스턴스가 시작되면 데스크톱에 접근할 수 있습니다",
      instanceDossier: "인스턴스 개요",
      allocatedProfile: "할당 프로필",
      kubernetesSection: "Kubernetes",
      volumeMapping: "볼륨 매핑",
      workspaceSection: "워크스페이스",
      openClawWorkspace: "OpenClaw 워크스페이스",
      openClawWorkspaceDesc:
        "`.openclaw` 폴더를 최대 50 MiB 크기의 `.tar.gz` 아카이브로 가져오거나 내보낼 수 있습니다.",
      runtimeWorkspace: "{runtime} 워크스페이스",
      runtimeWorkspaceDesc:
        "`{directory}` 폴더를 최대 50 MiB 크기의 `.tar.gz` 아카이브로 가져오거나 내보낼 수 있습니다.",
      workspaceReady: "준비됨",
      workspacePaused: "대기 중",
      exportingOpenClaw: "내보내는 중...",
      exportOpenClaw: ".openclaw 내보내기",
      importingOpenClaw: "가져오는 중...",
      importOpenClaw: ".openclaw 가져오기",
      importOpenClawSuccess: "OpenClaw 워크스페이스를 가져왔습니다.",
      exportingRuntimeWorkspace: "내보내는 중...",
      exportRuntimeWorkspace: "{directory} 내보내기",
      importingRuntimeWorkspace: "가져오는 중...",
      importRuntimeWorkspace: "{directory} 가져오기",
      importRuntimeWorkspaceSuccess:
        "{runtime} 워크스페이스를 가져왔습니다.",
      openClawArchiveTooLarge: "아카이브가 너무 큽니다. 최대 크기는 50 MiB입니다.",
      importOpenClawFailed: ".openclaw 가져오기 실패: {message}",
      exportOpenClawFailed: ".openclaw 내보내기 실패: {message}",
      importRuntimeWorkspaceFailed: "{directory} 가져오기 실패: {message}",
      exportRuntimeWorkspaceFailed: "{directory} 내보내기 실패: {message}",
      memoryReserved: "예약 메모리",
      persistentStorage: "영구 스토리지",
      gpuAttached: "연결된 GPU",
      waitingForRunningState:
        ".openclaw 가져오기를 위해 인스턴스가 실행 상태가 될 때까지 기다리는 중입니다.",
      timedOutWaitingForRunning:
        ".openclaw 가져오기 전에 인스턴스가 실행 상태가 되기를 기다리다 시간 초과되었습니다.",
      openClawImportTitle: "OpenClaw 가져오기",
      openClawImportDesc:
        "선택 사항입니다. 내보낸 `.openclaw` 아카이브를 선택하면 인스턴스 시작 후 자동으로 가져옵니다.",
      optional: "선택",
      changeOpenClawArchive: ".openclaw 아카이브 변경",
      chooseOpenClawArchive: ".openclaw 아카이브 선택",
      changeRuntimeArchive: "{directory} 아카이브 변경",
      chooseRuntimeArchive: "{directory} 아카이브 선택",
      remove: "제거",
      selectedArchive: "선택된 아카이브: {name}",
      noArchiveSelected:
        "선택된 아카이브가 없습니다. 빈 .openclaw 워크스페이스로 인스턴스가 생성됩니다.",
      noRuntimeArchiveSelected:
        "선택된 아카이브가 없습니다. 빈 {directory} 워크스페이스로 인스턴스가 생성됩니다.",
      quotaValidation: "할당량 검증",
      unableToLoadQuota:
        "할당량을 불러올 수 없습니다. 할당량 정보를 받을 때까지 인스턴스 생성은 비활성화됩니다.",
      requestedResourcesExceeded:
        "요청한 리소스가 할당된 한도를 초과했습니다. 구성을 줄여 주세요.",
      quotaInstances: "인스턴스 수",
      checkingQuota: "할당량 확인 중...",
      creatingAndImporting: "생성 및 가져오는 중...",
      typeOptions: {
        ubuntu: {
          label: "Ubuntu 데스크톱",
          description: "GNOME 데스크톱이 포함된 인기 Linux 배포판",
        },
        debian: {
          label: "Debian 데스크톱",
          description: "안정성과 보안성이 뛰어난 Linux 배포판",
        },
        centos: {
          label: "CentOS 데스크톱",
          description: "엔터프라이즈급 Linux 배포판",
        },
        openclaw: {
          label: "OpenClaw 데스크톱",
          description: "OpenClaw에 최적화된 데스크톱 환경",
        },
        webtop: {
          label: "Webtop 데스크톱",
          description:
            "ClawManager를 통해 프록시되는 브라우저 기반 Linux 데스크톱",
        },
        hermes: {
          label: "Hermes Runtime",
          description: "Webtop 데스크톱 기반으로 빌드된 Hermes 런타임",
        },
        custom: {
          label: "사용자 지정 이미지",
          description: "직접 준비한 사용자 지정 이미지를 사용합니다",
        },
      },
      presetOptions: {
        small: {
          label: "Small",
          description: "가벼운 작업에 적합",
        },
        medium: {
          label: "Medium",
          description: "개발 작업에 적절한 균형",
        },
        large: {
          label: "Large",
          description: "고부하 워크로드용",
        },
      },
      customPresetTitle: "사용자 지정",
      customPresetDescription: "Medium을 시작점으로 수동 크기 조정을 합니다.",
      customPresetEditing: "편집 중",
      resourcePresetSummary: "{cpu} CPU • {memory} GB RAM • {disk} GB 디스크",
      mediumDefaultPreset:
        "Medium 기본값: {cpu} CPU • {memory} GB RAM • {disk} GB 디스크",
      presetCpuShort: "CPU",
      presetRamShort: "RAM",
      presetDiskShort: "디스크",
      environmentVariables: "환경 변수",
      clawManagerBuiltIns: "ClawManager 내장 변수",
      hideBuiltIns: "내장 변수 숨기기",
      editBuiltIns: "내장 변수 편집",
      editBuiltInsCount: "내장 변수 편집 ({count})",
      builtinOverridesConfigured:
        "{count}개의 내장 변수 덮어쓰기가 설정되었습니다. 펼쳐서 검토하거나 수정할 수 있습니다.",
      usingBuiltInDefaults:
        "{count}개의 내장 변수에 ClawManager 기본값을 사용 중입니다.",
      builtinOverrideHelp:
        "덮어쓰고 싶은 내장 변수만 추가하세요. 목록에 없는 변수는 기본 주입값을 유지합니다.",
      addBuiltinVariable: "내장 변수 추가",
      noBuiltinOverrides: "아직 추가된 내장 변수 덮어쓰기가 없습니다.",
      defaultValue: "기본값: {value}",
      variable: "변수",
      overrideValue: "덮어쓰기 값",
      overrideValuePlaceholder: "덮어쓰기 값",
      actionLabel: "동작",
      customVariables: "사용자 지정 변수",
      addVariable: "변수 추가",
      noCustomEnvironmentVariables: "아직 사용자 지정 환경 변수가 없습니다.",
      variableNamePlaceholder: "VARIABLE_NAME",
      variableValuePlaceholder: "value",
      customEnvNameRequired: "사용자 지정 환경 변수 이름은 필수입니다.",
      invalidEnvName: "유효하지 않은 환경 변수 이름: {name}",
      reservedBuiltinEnvName:
        "{name}은(는) ClawManager 내장 변수입니다. 내장 변수 섹션에서 편집하세요.",
      duplicateEnvName: "중복된 환경 변수 이름: {name}",
      openClawInjection: "OpenClaw 주입",
      runtimeInjection: "{runtime} 주입",
      selectedCount: "{count}개 선택됨",
      noReusableSkillsSelected: "선택된 재사용 가능 스킬이 없습니다.",
      noAvailableSkillsForInjection:
        "사용 가능한 스킬이 없습니다. 먼저 리소스 센터에서 스킬을 가져오세요.",
      skillRiskVersionLabel: "{key} · 위험도 {risk} · v{version}",
      skillPageSummary: "{page}/{totalPages} 페이지 · 스킬 {totalSkills}개",
      archiveImport: "아카이브 가져오기",
      archiveModeRequiresFile: "아카이브 모드에는 파일이 필요합니다",
      envInjection: "환경 변수 주입",
      noEnvOverridesConfigured:
        "구성된 컨테이너 환경 변수 덮어쓰기가 없습니다.",
      channelInjection: "Channel 주입",
      archiveSkipsChannelInjection:
        "아카이브 모드는 리소스 기반 Channel 주입을 건너뜁니다.",
      compilingOpenClawPreview: "OpenClaw 리소스 미리보기를 생성하는 중...",
      compilingRuntimePreview: "Runtime 리소스 미리보기를 생성하는 중...",
      noChannelsSelectedForInjection: "주입할 Channel 이 선택되지 않았습니다.",
      skillInjection: "스킬 주입",
      envManagedProxyPath: "ClawManager가 관리하는 프록시 경로",
      envGeneratedAtRuntime: "ClawManager가 런타임에 생성",
      envAssignedAfterCreation: "생성 후 할당",
      envManagedAtRuntime: "ClawManager가 런타임에 관리",
      envDescDesktopTitleWebtop:
        "LinuxServer Webtop 컨테이너에 주입되는 데스크톱 창 제목입니다.",
      envDescDesktopTitleOpenClaw:
        "OpenClaw 브라우저 데스크톱 이미지에 표시되는 데스크톱 제목입니다.",
      envDescProxySubfolder:
        "브라우저 접근 시 ClawManager 리버스 프록시가 사용하는 경로 접두사입니다.",
      envDescLlmBaseUrl:
        "ClawManager가 런타임에 생성하는 OpenClaw 게이트웨이 기본 URL입니다.",
      envDescLlmApiKey:
        "ClawManager가 인스턴스별로 발급하는 게이트웨이 API 키입니다.",
      envDescLlmModel:
        "OpenClaw 워크스페이스에 주입되는 Gateway 모델 카탈로그 JSON이며, 첫 항목은 auto로 유지됩니다.",
      envDescLlmProvider: "OpenClaw 워크스페이스에 전달되는 제공자 힌트입니다.",
      envDescInstanceToken:
        "ClawManager가 워크스페이스 접근용으로 생성하는 인스턴스 토큰입니다.",
      envDescOpenAiBaseUrl:
        "OpenAI 호환 게이트웨이 기본 URL용 호환 별칭입니다.",
      envDescOpenAiApiBase:
        "OpenAI 호환 게이트웨이 기본 URL용 호환 별칭입니다.",
      envDescOpenAiApiKey: "게이트웨이 API 키용 호환 별칭입니다.",
      envDescOpenAiModel: "기본 모델 이름용 호환 별칭입니다.",
      envDescAgentEnabled:
        "OpenClaw 내부에서 ClawManager 인스턴스 Agent 활성화를 전환합니다.",
      envDescAgentBaseUrl:
        "인스턴스 내부 Agent 제어 클라이언트가 사용하는 기본 URL입니다.",
      envDescAgentBootstrapToken:
        "ClawManager가 인스턴스 내부 Agent용으로 생성하는 부트스트랩 토큰입니다.",
      envDescAgentDiskLimitBytes:
        "인스턴스 Agent에 주입되는 디스크 할당량입니다.",
      envDescAgentInstanceId:
        "인스턴스 내부 Agent에 제공되는 런타임 인스턴스 식별자입니다.",
      envDescAgentPersistentDir:
        "OpenClaw 컨테이너에 마운트되는 영구 워크스페이스 경로입니다.",
      envDescAgentProtocolVersion:
        "ClawManager Agent 제어면이 기대하는 프로토콜 버전입니다.",
      gpuLabel: "GPU",
      cpuCoresValue: "{value}코어",
      gpuCountValue: "GPU {count}개",
      memoryLabel: "메모리",
      storageLabel: "스토리지",
      gpuDisabled: "비활성화",
      noOpenClawArchiveSelected: ".openclaw 아카이브 미선택",
      live: "실시간",
      notAvailable: "없음",
      runtimeCommandFailed: "{command} 실행에 실패했습니다",
      failedToAttachSkill: "스킬 연결에 실패했습니다",
      failedToRemoveSkill: "스킬 제거에 실패했습니다",
      kubernetesStatusTitle: "Pod 및 인프라 상태",
      infrastructureReady: "인프라 준비 완료",
      skillsSection: "스킬",
      skillManagement: "스킬 관리",
      selectSkill: "스킬 선택",
      installingSkill: "설치 중...",
      installSkill: "스킬 설치",
      noSkillsReported: "이 인스턴스에는 아직 보고된 스킬이 없습니다.",
      skillFallback: "스킬 #{id}",
      lastSeenAt: "마지막 확인 {value}",
      removingSkill: "제거 중...",
      removeSkill: "제거",
      skillPagination: "총 {total}개 중 {from}-{to}개 스킬 표시",
      previous: "이전",
      nextPage: "다음",
      timelineSubtitle: "인스턴스 작업 및 런타임 기록",
      timelineEvents: "{count}개 이벤트",
      noRuntimeActivity: "아직 런타임 활동이 없습니다.",
      minimap: "미니맵",
      runtimeSummary: "런타임 요약",
      agentReportedStatus: "Agent 보고 상태",
      fresh: "최신",
      operatingSystemShort: "OS",
      openClawShort: "OpenClaw",
      agents: "에이전트",
      channels: "채널",
      agentStatusLabel: "Agent {status}",
      gatewayStatusLabel: "게이트웨이 {status}",
      agentId: "Agent ID",
      agentVersion: "Agent 버전",
      protocol: "프로토콜",
      lastHeartbeat: "마지막 하트비트",
      lastReport: "마지막 보고",
      skillSourceUploaded: "업로드",
      skillSourceDiscovered: "발견",
      skillRiskNone: "안전",
      skillRiskLow: "낮음",
      skillRiskMedium: "중간",
      skillRiskHigh: "높음",
      skillRiskUnknown: "알 수 없음",
      timelineInstanceCreated: "인스턴스 생성됨",
      timelineInstanceCreatedDetail:
        "{name} 인스턴스가 {type} 유형으로 프로비저닝되었습니다.",
      timelineInstanceStarted: "인스턴스 시작됨",
      timelineInstanceStartedDetail:
        "이 인스턴스의 인프라 시작 기록이 남았습니다.",
      timelineInstanceStopped: "인스턴스 중지됨",
      timelineInstanceStoppedDetail:
        "이 인스턴스의 인프라 중지 기록이 남았습니다.",
      timelineAgentRegistered: "Agent 등록됨",
      timelineAgentRegisteredDetail:
        "{agentId}가 프로토콜 {protocol}로 ClawManager에 연결했습니다.",
      timelineRuntimeReported: "런타임 상태 보고됨",
      timelineRuntimeReportedDetail:
        "Agent가 게이트웨이 상태 {gatewayStatus} 및 인프라 상태 {infraStatus}를 보고했습니다.",
      timelinePodStatusObserved: "Pod 상태 수집됨",
      timelinePodStatusObservedDetail:
        "Kubernetes가 현재 Pod 상태를 {status}(으)로 보고합니다.",
      timelineCommandWithError: "{status}: {error}",
      timelineCommandWithIdempotency: "{status} · 멱등 키 {key}",
      timelineSectionInstance: "instance",
      timelineSectionInfra: "infra",
      timelineSectionAgent: "agent",
      timelineSectionRuntime: "runtime",
      timelineSectionKubernetes: "k8s",
      timelineSectionCommand: "command",
      metricCpu: "CPU",
      metricCpuDetail:
        "{cores}코어 · 1분 부하 {load1} · 5분 부하 {load5} · 15분 부하 {load15}",
      metricMemory: "메모리",
      metricMemoryDetail: "{used} 사용 / {total}",
      metricDisk: "디스크",
      metricDiskDetail: "{free} 남음 / {total}",
      metricNetwork: "네트워크",
      metricNetworkDetail: "{interfaces}개 인터페이스, 주소 {addresses}개",
      metricLegendDown: "다운",
      metricLegendUp: "업",
      metricTrafficDetail: "수신 {inbound} · 송신 {outbound}",
    },
    openClawResourcesPage: {
      title: "OpenClaw 리소스 관리",
      tabs: {
        resources: "리소스",
        bundles: "번들",
        injections: "주입 기록",
      },
      resourceTypesTitle: "리소스 유형",
      searchPlaceholder: "리소스를 검색하세요...",
      resourceListHint:
        "리소스 카드를 클릭하면 오른쪽 고정 편집기 대신 팝업에서 편집합니다.",
      loadingResources: "리소스를 불러오는 중...",
      noResources:
        '이 유형에는 아직 리소스가 없습니다. "새로 만들기"를 클릭하세요.',
      enabled: "활성화됨",
      disabled: "비활성화됨",
      thisResourceType: "이 리소스 유형은",
      notConfigurableYet: "{type} 아직 설정할 수 없습니다.",
      onlyChannelConfigurable:
        "현재는 Channel만 설정할 수 있습니다. Skill, Agent, Scheduled Task 편집기는 이후 업데이트에서 추가됩니다.",
      bundlesSubtitle:
        "재사용 가능한 OpenClaw 부트스트랩 패키지를 번들로 구성하고 전용 팝업에서 편집합니다.",
      loadingBundles: "번들을 불러오는 중...",
      noBundles: '아직 번들이 없습니다. "새 번들"을 클릭해 생성하세요.',
      bundleResourceCount: "{count}개 리소스",
      injectionsSubtitle:
        "스냅샷은 인스턴스 생성 시 저장되고 재시작 시 다시 사용됩니다.",
      snapshot: "스냅샷",
      mode: "모드",
      resources: "리소스 수",
      envCount: "환경 변수 수",
      created: "생성 시각",
      loadingSnapshots: "스냅샷을 불러오는 중...",
      noInjectionRecords: "아직 OpenClaw 주입 기록이 없습니다.",
      paginationSummary: "페이지당 {pageSize}개, {from}-{to} 표시",
      paginationPrev: "이전 페이지",
      paginationNext: "다음 페이지",
      skillUploadHint:
        "`.zip`만 업로드할 수 있습니다. 최상위 디렉터리 하나가 스킬 하나로 가져와집니다.",
      loadingSkills: "스킬을 불러오는 중...",
      noSkills: "업로드된 스킬이 아직 없습니다.",
      skillMeta: "{key} · 위험도 {risk} · {count}개 인스턴스에서 사용 중",
      recordModes: {
        none: "없음",
        manual: "수동",
        bundle: "번들",
        archive: "아카이브",
      },
      recordStatuses: {
        compiled: "컴파일됨",
        active: "활성",
        failed: "실패",
      },
      editResourceTitle: "리소스 편집",
      newResourceTitle: "새 리소스",
      editResourceSubtitle:
        "집중된 팝업 편집기에서 메타데이터와 JSON을 함께 수정합니다.",
      newResourceSubtitle:
        "페이지에 전체 편집기를 노출하지 않고 새 OpenClaw 리소스를 만듭니다.",
      resourceKey: "리소스 키",
      name: "이름",
      tags: "태그",
      tagsPlaceholder: "tag1,tag2",
      channelTemplate: "Channel 템플릿",
      chooseStarterTemplate: "시작 템플릿 선택",
      channelTemplateHint:
        "여기서는 Slack, Telegram, DingTalk, Feishu만 지원합니다. 먼저 폼 모드로 입력한 뒤, 전체 설정이 필요할 때 JSON으로 전환하세요.",
      templateKey: "키: {key}",
      invalidChannelJson:
        "현재 Channel JSON 이 유효하지 않습니다. 먼저 JSON 모드에서 수정한 뒤 폼으로 돌아오세요.",
      contentJson: "내용 JSON",
      editBundleTitle: "번들 편집",
      newBundleTitle: "새 번들",
      editBundleSubtitle:
        "집중된 팝업 편집기에서 재사용 가능한 부트스트랩 패키지를 다듬습니다.",
      newBundleSubtitle:
        "리소스 목록을 벗어나지 않고 새 재사용 번들을 만듭니다.",
      bundleName: "번들 이름",
      bundleResources: "번들 리소스",
      noResourcesForGroup: "{type} 리소스가 아직 없습니다.",
      actions: {
        new: "새로 만들기",
        newBundle: "새 번들",
        loadTemplate: "템플릿 불러오기",
        saveResource: "리소스 저장",
        createResource: "리소스 생성",
        validateJson: "JSON 검증",
        clone: "복제",
        saveBundle: "번들 저장",
        createBundle: "번들 생성",
      },
      resourceTypes: {
        channel: "채널",
        skill: "스킬",
        session_template: "세션 템플릿",
        log_policy: "로그 정책",
        agent: "에이전트",
        scheduled_task: "예약 작업",
      },
      templateCategories: {
        builtin: "기본 제공",
        plugin: "플러그인",
      },
      templates: {
        telegram: {
          label: "Telegram",
          description:
            "DM 및 그룹 정책 제어를 지원하는 Telegram Bot API 채널입니다.",
        },
        dingtalkConnector: {
          label: "DingTalk",
          description:
            "클라이언트 자격 증명과 발신자 허용 목록을 지원하는 DingTalk 채널입니다.",
        },
        slack: {
          label: "Slack",
          description: "Bolt 기반의 Slack 워크스페이스 앱입니다.",
        },
        feishu: {
          label: "Feishu / Lark",
          description: "계정 기본값을 포함한 Feishu / Lark 채널입니다.",
        },
      },
      editorModes: {
        form: "폼",
        json: "JSON",
      },
      channelEditors: {
        dingtalkConnector: {
          title: "DingTalk Channel 편집기",
          description:
            "먼저 클라이언트 자격 증명 폼으로 시작하고, 전체 설정이 필요할 때만 JSON 으로 전환하세요.",
          fields: {
            clientId: {
              label: "Client ID",
              placeholder: "ding-xxxxxxxxxxxxxx",
            },
            clientSecret: {
              label: "Client Secret",
              placeholder: "client secret",
            },
          },
        },
        feishu: {
          title: "Feishu Channel 편집기",
          description:
            "먼저 메인 계정 폼으로 시작하고, 전체 설정이 필요할 때만 JSON 으로 전환하세요.",
          fields: {
            appId: {
              label: "App ID",
              placeholder: "cli_xxx",
            },
            appSecret: {
              label: "App Secret",
              placeholder: "app secret",
            },
          },
        },
        slack: {
          title: "Slack Channel 편집기",
          description:
            "먼저 토큰 폼으로 시작하고, 전체 설정이 필요할 때만 JSON 으로 전환하세요.",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "xoxb-...",
            },
            appToken: {
              label: "App Token",
              placeholder: "xapp-...",
            },
          },
        },
        telegram: {
          title: "Telegram Channel 편집기",
          description:
            "먼저 Bot Token 폼으로 시작하고, 전체 설정이 필요할 때만 JSON 으로 전환하세요.",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "123456:ABCDEF",
            },
          },
        },
      },
      notices: {
        resourceUpdated: "리소스를 업데이트했습니다.",
        resourceCreated: "리소스를 생성했습니다.",
        resourceDeleted: "리소스를 삭제했습니다.",
        resourceCloned: "리소스를 복제했습니다.",
        resourceJsonValid: "리소스 JSON 이 유효합니다.",
        templateLoaded: "{name} 템플릿을 불러왔습니다.",
        bundleUpdated: "번들을 업데이트했습니다.",
        bundleCreated: "번들을 생성했습니다.",
        bundleDeleted: "번들을 삭제했습니다.",
        bundleCloned: "번들을 복제했습니다.",
        skillArchiveImported: "스킬 아카이브를 가져왔습니다.",
        skillDeleted: "스킬을 삭제했습니다.",
      },
      errors: {
        loadFailed: "OpenClaw 리소스를 불러오지 못했습니다.",
        saveResource: "리소스를 저장하지 못했습니다.",
        validationFailed: "리소스 JSON 검증에 실패했습니다.",
        deleteResource: "리소스를 삭제하지 못했습니다.",
        cloneResource: "리소스를 복제하지 못했습니다.",
        saveBundle: "번들을 저장하지 못했습니다.",
        deleteBundle: "번들을 삭제하지 못했습니다.",
        cloneBundle: "번들을 복제하지 못했습니다.",
        importSkillArchive: "스킬 아카이브 가져오기에 실패했습니다.",
        deleteSkill: "스킬 삭제에 실패했습니다.",
        downloadSkill: "스킬 다운로드에 실패했습니다.",
      },
      skillActions: {
        chooseFile: "파일 선택",
        uploadArchive: "스킬 아카이브 업로드",
        download: "다운로드",
      },
      risks: {
        none: "안전",
        low: "낮음",
        medium: "중간",
        high: "높음",
        unknown: "알 수 없음",
      },
      confirms: {
        deleteResource: '리소스 "{name}"을(를) 삭제할까요?',
        deleteBundle: '번들 "{name}"을(를) 삭제할까요?',
      },
    },
    openClawInjectionSection: {
      title: "OpenClaw 리소스 주입",
      subtitle:
        "이 인스턴스가 OpenClaw 를 어떻게 부트스트랩할지 선택하세요. 현재 선택된 옵션을 다시 클릭하면 선택이 해제됩니다.",
      optional: "선택 사항",
      modes: {
        manual: "수동 리소스",
        bundle: "번들",
        archive: "아카이브 가져오기",
      },
      loading: "리소스 관리 데이터를 불러오는 중...",
      chooseBundle: "번들 선택",
      selectBundle: "번들을 선택하세요",
      bundleOptionCount: "{count}개 리소스",
      channel: "채널",
      noChannelResources: "사용 가능한 채널 리소스가 없습니다.",
      errors: {
        chooseBundle: "계속하려면 먼저 번들을 선택하세요.",
        chooseResource: "계속하려면 최소 한 개의 리소스를 선택하세요.",
        compileFailed: "OpenClaw 부트스트랩 미리보기를 생성하지 못했습니다.",
      },
    },
  },
  de: {
    app: { name: "ClawManager" },
    common: {
      loading: "Lädt...",
      logout: "Abmelden",
      admin: "Admin",
      user: "Benutzer",
      comingSoon: "Demnächst verfügbar",
      language: "Sprache",
      refresh: "Aktualisieren",
      retry: "Erneut versuchen",
      create: "Erstellen",
      save: "Speichern",
      cancel: "Abbrechen",
      close: "Schließen",
      overview: "Übersicht",
      logs: "Logs",
      description: "Beschreibung",
      type: "Typ",
      status: "Status",
      createdAt: "Erstellt am",
      lastUpdated: "Zuletzt aktualisiert",
      open: "Öffnen",
      stop: "Stoppen",
      start: "Starten",
      restart: "Neustarten",
      delete: "Löschen",
      cpu: "CPU",
      memory: "Speicher",
      disk: "Festplatte",
      search: "Suchen",
      all: "Alle",
    },
    status: {
      all: "Alle",
      running: "Laufend",
      stopped: "Gestoppt",
      creating: "Wird erstellt",
      error: "Fehler",
      deleting: "Wird gelöscht",
    },
    nav: {
      dashboard: "Dashboard",
      adminDashboard: "Konsole",
      userDashboard: "Arbeitsbereich",
      users: "Benutzer",
      instances: "Instanzen",
      aiGateway: "AI Gateway",
      aiAudit: "AI-Audit",
      costs: "Kosten",
      riskRules: "Risiko-Regeln",
      models: "Modelle",
      settings: "Einstellungen",
      myInstances: "Meine Instanzen",
      openClawConfigs: "Ressourcen",
      backToDashboard: "Zurück zum Dashboard",
      backToUserDashboard: "Arbeitsbereich",
      securityCenter: "Sicherheitszentrum",
      adminPanel: "Admin-Bereich",
    },
    adminLayout: adminLayoutTranslations.de,
    securityCenter: securityCenterTranslations.de,
    auth: {
      signInTitle: "Bei ClawManager anmelden",
      subtitle: "Plattform zur Verwaltung virtueller Desktops",
      username: "Benutzername",
      password: "Passwort",
      email: "E-Mail",
      usernamePlaceholder: "Benutzernamen eingeben",
      passwordPlaceholder: "Passwort eingeben",
      signIn: "Anmelden",
      signingIn: "Anmeldung läuft...",
      noAccount: "Noch kein Konto?",
      signUp: "Registrieren",
      createAccount: "Konto erstellen",
      joinToday: "Noch heute ClawManager beitreten",
      chooseUsername: "Benutzernamen wählen",
      enterEmail: "E-Mail eingeben",
      createPassword: "Passwort erstellen (mind. 8 Zeichen)",
      confirmPassword: "Passwort bestätigen",
      confirmPasswordPlaceholder: "Passwort bestätigen",
      createAccountAction: "Konto erstellen",
      creatingAccount: "Konto wird erstellt...",
      alreadyHaveAccount: "Sie haben bereits ein Konto?",
      passwordsMismatch: "Passwörter stimmen nicht überein",
      passwordTooShort: "Das Passwort muss mindestens 8 Zeichen lang sein",
      changePassword: "Passwort ändern",
      currentPassword: "Aktuelles Passwort",
      newPassword: "Neues Passwort",
      confirmNewPassword: "Neues Passwort bestätigen",
      changePasswordAction: "Passwort aktualisieren",
      changePasswordDesc:
        "Aktualisieren Sie Ihr Kontopasswort in den Einstellungen.",
      changingPassword: "Wird aktualisiert...",
      passwordChanged: "Passwort erfolgreich geändert",
      changePasswordFailed: "Passwort konnte nicht geändert werden",
      loginFailed: "Anmeldung fehlgeschlagen",
    },
    admin: {
      dashboardTitle: "Konsole",
      userManagement: "Benutzerverwaltung",
      userManagementDesc: "Benutzer, Rollen und Kontingente verwalten",
      instanceManagement: "Instanzverwaltung",
      instanceManagementDesc: "Virtuelle Desktop-Instanzen verwalten",
      globalInstances: "Alle Instanzen",
      globalInstancesDesc:
        "Alle Benutzerinstanzen an einem Ort suchen, filtern und steuern.",
      instanceSearchPlaceholder:
        "Nach Instanz, Benutzer, Typ, Pod oder Namespace suchen...",
      allStatuses: "Alle Status",
      allTypes: "Alle Typen",
      showingInstances: "{filtered} von {total} Instanzen angezeigt",
      loadingInstances: "Instanzen werden geladen...",
      noFilteredInstances: "Keine Instanzen entsprechen den aktuellen Filtern.",
      instanceColumn: "Instanz",
      userColumn: "Benutzer",
      typeOsColumn: "Typ / OS",
      resourcesColumn: "Ressourcen",
      k8sColumn: "K8s",
      actionsColumn: "Aktionen",
      updatedAtLabel: "Aktualisiert",
      userIdLabel: "Benutzer-ID",
      gpuLabel: "GPU",
      failedToLoadInstances: "Instanzen konnten nicht geladen werden",
      failedToStartInstance: "Instanz konnte nicht gestartet werden",
      failedToStopInstance: "Instanz konnte nicht gestoppt werden",
      failedToRestartInstance: "Instanz konnte nicht neu gestartet werden",
      failedToSyncInstance: "Instanz konnte nicht synchronisiert werden",
      failedToDeleteInstance: "Instanz konnte nicht gelöscht werden",
      confirmDeleteInstance: "Instanz {name} löschen?",
      systemSettings: "Systemeinstellungen",
      systemSettingsDesc: "Systemeinstellungen konfigurieren",
      systemOverview: "Systemübersicht",
      totalUsers: "Benutzer gesamt",
      totalInstances: "Instanzen gesamt",
      runningInstances: "Laufende Instanzen",
      totalStorage: "Gesamtspeicher",
      instanceManagementStub:
        "Diese Funktion befindet sich noch in Entwicklung. Bitte später erneut prüfen.",
      systemSettingsStub:
        "Diese Funktion befindet sich noch in Entwicklung. Bitte später erneut prüfen.",
      addUser: "Benutzer hinzufügen",
      dashboardLoadFailed: "Dashboard-Statistiken konnten nicht geladen werden",
      clusterCommand: "Cluster-Kommando",
      clusterHeroTitle: "Überblick über die grundlegenden Clusterinformationen",
      clusterHeroDesc:
        "Dieses Dashboard sollte wie ein Betriebs-Cockpit wirken, nicht wie eine Einstellungsseite. Wichtige Signale stehen vorne, Knotendruck ist mit einem Blick sichtbar.",
      accountsWithAccess: "Konten mit Zugriff",
      provisionedDesktops: "Bereitgestellte Desktops",
      currentlyOnline: "Aktuell online",
      allocatedToInstances: "Instanzen zugewiesen",
      readiness: "Bereitschaft",
      clusterStatusPending: "Cluster-Status wird ermittelt",
      nodesHealthySchedulable: "{percent}% der Knoten sind gesund und planbar.",
      hotNode: "Hot Node",
      cpuRequested: "Angeforderte CPU",
      memoryRequested: "Angeforderter Speicher",
      diskAllocated: "Zugeteilter Speicher",
      pressureFocus: "Druckfokus",
      pressureFocusMem: "{percent}% Speicher",
      clusterResources: "Cluster-Ressourcen",
      capacityBoard: "Kapazitätsübersicht",
      waitingForClusterData: "Warte auf Cluster-Daten",
      nodesReadySummary: "{ready}/{total} Knoten bereit",
      nodeFleet: "Knotenflotte",
      nodes: "Knoten",
      healthyNodesScheduling: "Gesunde Knoten für das Scheduling",
      computePressure: "Compute-Druck",
      memoryPressure: "Speicherdruck",
      persistentAllocation: "Persistente Zuordnung",
      requestedVsAllocatable: "Anforderung / zuteilbar",
      allocatedVsAllocatable: "Zuteilung / zuteilbar",
      capacityCores: "Kapazität {value} Kerne",
      capacityGiB: "Kapazität {value} GiB",
      usage: "Auslastung",
      nodeMatrix: "Knotenmatrix",
      infrastructureTable: "Infrastrukturtabelle",
      infrastructureTableDesc:
        "Überblicken Sie die gesamte Flotte in einem Schritt. Erweitern Sie jeden Knoten, um CPU-, Speicher-, Datenträger- und Kubelet-Details anzuzeigen.",
      node: "Knoten",
      health: "Gesundheit",
      ready: "Bereit",
      role: "Rolle",
      internalIp: "Interne IP",
      pods: "Pods",
      cpuLoad: "CPU-Last",
      memoryLoad: "Speicherlast",
      inspect: "Anzeigen",
      nodeDossier: "Knotenprofil",
      kubeletVersion: "Kubelet-Version",
      roles: "Rollen",
      podCount: "Pod-Anzahl",
      diskSummary: "Datenträgerübersicht",
      resourceProfile: "Ressourcenprofil",
      noNodeData: "Der Cluster hat keine Knotendaten zurückgegeben.",
      showingNodes: "Zeige {from}-{to} von {total} Knoten",
      prev: "Zurück",
      nextPage: "Weiter",
      pageSummary: "Seite {page} / {total}",
      collapse: "Einklappen",
      viewDetails: "Details",
      notReady: "Nicht bereit",
      openSection: "Bereich öffnen",
    },
    aiGatewayPage: {
      badge: "Governance-Hub",
      title: "AI-Gateway-Kontrollzentrum",
      subtitle:
        "Modellkatalog, Audit-Traces, Kostenberichte und Regeln für sensible Inhalte werden hier gebündelt.",
      modelsDescription:
        "Verwalten Sie normale und sichere Modelle, Provider-Endpunkte, Preise und Aktivierungsstatus.",
      auditDescription:
        "Prüfen Sie Trace-IDs, Request-/Response-Payloads, Risikotreffer, Routing-Entscheidungen und Aufrufdetails.",
      costsDescription:
        "Prüfen Sie Token-Nutzung, geschätzte Kosten, interne Secure-Model-Kosten und zugehörige Abrechnungsdetails.",
      riskRulesDescription:
        "Passen Sie regex-basierte Erkennungsregeln, Schweregrade, Aktionen und Ausführungsreihenfolge an.",
    },
    aiAuditPage: {
      title: "Letzte AI-Traces",
      subtitle:
        "Prüfen Sie überwachte Modellaufrufe, Traces, Token-Nutzung, Status und tatsächliche Routing-Ergebnisse.",
      loadFailed: "AI-Audit-Daten konnten nicht geladen werden",
      detailLoadFailed: "Trace-Details konnten nicht geladen werden",
      copyFailed: "Trace-ID konnte nicht kopiert werden",
      completed: "Abgeschlossen",
      blocked: "Blockiert",
      failed: "Fehlgeschlagen",
      pending: "Ausstehend",
      tokensOnPage: "Token auf dieser Seite",
      traceTable: "Trace-Tabelle",
      traceTableSubtitle:
        "Suchen, filtern und prüfen Sie die neuesten überwachten Traces an einer Stelle.",
      searchPlaceholder: "Trace, Request, Benutzer, Modell suchen...",
      allStatuses: "Alle Status",
      modelPlaceholder: "Nach Modell filtern...",
      loading: "Audit-Daten werden geladen...",
      empty: "Keine AI-Audit-Daten gefunden.",
      trace: "Trace",
      user: "Benutzer",
      requested: "Angefordert",
      providerResult: "Provider-Ergebnis",
      failureReason: "Fehlerursache",
      usage: "Nutzung",
      action: "Aktion",
      copy: "Kopieren",
      copied: "Kopiert",
      noLatency: "Keine Latenzdaten",
      detailTitle: "Trace-Details",
      detailSubtitle:
        "Wählen Sie einen Trace aus, um Payloads, Audit-Ereignisse und Kostenaufzeichnungen zu prüfen.",
      detailLoading: "Trace-Details werden geladen...",
      noTraceSelected: "Noch kein Trace ausgewählt.",
      executionFlow: "Ablauf",
      executionFlowSubtitle:
        "Zeigt einen vollständigen OpenClaw-Frageablauf mit Modellaufrufen, Tool-Aufrufen, Tool-Ausgaben und der finalen Antwort.",
      flowMinimap: "Minikarte",
      flowMinimapSubtitle:
        "Zeigt den Ablauf kompakt an und springt per Klick direkt zum gewünschten Schritt.",
      noFlowNodes: "Für diesen Trace wurden noch keine Ablaufknoten erzeugt.",
      flowNode: "Ablaufknoten",
      flowUserMessage: "Benutzernachricht",
      flowLlmCall: "LLM-Aufruf",
      flowToolCall: "Tool-Aufruf",
      flowToolOutput: "Tool-Ausgabe",
      flowAssistantResponse: "Assistentenantwort",
      flowAssistantMessage: "Assistentennachricht",
      nodeInput: "Eingabe",
      nodeOutput: "Ausgabe",
      requestIdLabel: "Request ID",
      modelLabel: "Model",
      userLabel: "Benutzer: {user}",
      sessionLabel: "Sitzung: {session}",
      copyTraceId: "Trace-ID kopieren",
      clear: "Zurücksetzen",
      invocations: "Aufrufe",
      noInvocation:
        "Für diesen Trace wurde keine persistierte Invocation-Zeile gefunden.",
      payloads: "Payloads",
      auditEvents: "Audit-Ereignisse",
      costRecords: "Kostenaufzeichnungen",
      noCostRecords:
        "Für diesen Trace wurden keine Kostenaufzeichnungen erzeugt. Das bedeutet meist, dass die Anfrage blockiert wurde oder scheiterte, bevor ein abrechenbarer Modellaufruf erreicht wurde.",
      riskHits: "Risikotreffer",
      noRiskHits:
        "Für diesen Trace wurden keine Sensitivitäts-Treffer aufgezeichnet.",
      messages: "Nachrichten",
      noMessages: "Für diesen Trace wurden keine Nachrichten persistiert.",
    },
    costsPage: {
      badge: "Kostenübersicht",
      title: "AI-Kosten auf einen Blick",
      subtitle:
        "Prüfen Sie Token-Volumen, geschätzte Kosten, interne Kosten und die Traces hinter ungewöhnlichen Spitzen.",
      loadFailed: "AI-Kostenübersicht konnte nicht geladen werden",
      loading: "AI-Kostenübersicht wird geladen...",
      promptTokens: "Prompt-Token",
      promptTokensNote: "Eingehendes Prompt-Volumen",
      completionTokens: "Completion-Token",
      completionTokensNote: "Generiertes Ausgabevolumen",
      estimatedSpend: "Geschätzte Kosten",
      estimatedSpendNote: "Provider-basierte Kostenschätzung",
      internalCost: "Interne Kosten",
      internalCostNote: "Interne Secure-Model-Abrechnung",
      userTotals: "Benutzer-Summen",
      userTotalsSubtitle: "Nutzung und Kosten pro Benutzer aggregiert",
      instanceTotals: "Instanz-Summen",
      instanceTotalsSubtitle: "Nutzung und Kosten pro Instanz aggregiert",
      recentRecords: "Letzte Kostenaufzeichnungen",
      recentRecordsSubtitle:
        "Suchen und blättern Sie durch Trace-verknüpfte Kostenaufzeichnungen und springen Sie direkt in den Audit-Pfad.",
      searchPlaceholder: "Trace, Benutzer, Modell suchen...",
      pageSize10: "10 / Seite",
      pageSize20: "20 / Seite",
      pageSize50: "50 / Seite",
      apply: "Anwenden",
      trace: "Trace",
      user: "Benutzer",
      instance: "Instanz",
      model: "Modell",
      tokens: "Token",
      spend: "Kosten",
      recorded: "Erfasst",
      instanceId: "ID {id}",
      internalValue: "Intern {value} {currency}",
      openInAudit: "Im Audit öffnen",
      showing: "Zeige {from}-{to} von {total}",
      name: "Name",
      estimated: "Geschätzt",
      internal: "Intern",
      dailyTrend: "Täglicher Kostentrend",
      lastSevenDays: "Letzte 7 Tage",
      dailyTrendSubtitle:
        "Geschätzte Kosten und Token-Bewegung im aktuellen Zeitraum.",
      sevenDayView: "7-Tage-Ansicht",
      noTrendData: "Noch keine Trenddaten.",
    },
    modelManagementPage: {
      title: "Modellverwaltung",
      subtitle:
        "Konfigurieren Sie sichere und normale AI-Modelle auf Modellebene. Wählen Sie eine Vendor-Vorlage mit fester Base URL und laden oder tippen Sie anschließend den Provider-Modellnamen.",
      addModel: "Modell hinzufügen",
      finishEditing:
        "Schließen oder verwerfen Sie zuerst die aktuelle Bearbeitung, bevor Sie ein anderes Modell hinzufügen oder ändern.",
      loading: "Modelle werden geladen...",
      loadFailed: "Modelle konnten nicht geladen werden",
      noProviderModels: "Der Provider hat keine Modelle zurückgegeben.",
      discoverFailed:
        "Provider-Modelle konnten nicht automatisch erkannt werden",
      requiredFields:
        "Anzeigename, Vendor-Vorlage und Provider-Modell sind erforderlich.",
      saveFailed: "Modell konnte nicht gespeichert werden",
      deleteFailed: "Modell konnte nicht gelöscht werden",
      secure: "Sicher",
      secureModel: "Sicheres Modell",
      active: "Aktiv",
      inactive: "Inaktiv",
      providerModel: "Provider-Modell",
      currency: "Währung",
      baseUrl: "Base URL",
      inputPriceShort: "Eingabepreis / 1M",
      outputPriceShort: "Ausgabepreis / 1M",
      edit: "Bearbeiten",
      displayName: "Anzeigename",
      displayNamePlaceholder: "Internes sicheres Modell",
      vendorTemplate: "Vendor-Vorlage",
      vendorTemplatePlaceholder: "Vendor-Vorlage auswählen",
      vendorTemplateSearchPlaceholder:
        "Vendor-Name, Alias oder Base URL suchen...",
      vendorTemplateEmpty: "Keine Vendor-Vorlagen passen zur Suche.",
      currentVendorTemplate: "Aktueller benutzerdefinierter Endpoint",
      providerType: "Provider-Typ",
      protocol: "Protokoll",
      baseUrlPlaceholder: "https://api.example.com/v1",
      fixedBaseUrlPlaceholder:
        "Wählen Sie eine Vendor-Vorlage, um die Base URL festzulegen",
      fixedBaseUrlHelp:
        "Die Base URL wird durch die gewählte Vendor-Vorlage fest vorgegeben und muss nicht manuell eingetragen werden.",
      editableBaseUrlHelp:
        "Bei Local-/Internal-Vorlagen kann die Base URL für den eigenen Runtime- oder Gateway-Endpunkt überschrieben werden.",
      localProtocolHelp:
        "Local-/Internal-Modelle können bei eigener Base URL zwischen OpenAI-kompatibler und Anthropic-API umschalten.",
      apiKey: "API Key",
      optionalPlaceholder: "Optional",
      secretRef: "Secret Ref",
      secretRefPlaceholder: "namespace/secret-name:key",
      loadingProviderModels: "Provider-Modelle werden geladen...",
      selectProviderModel: "Provider-Modell auswählen",
      waitingDiscovery: "Warte auf automatische Erkennung",
      manualProviderModelPlaceholder: "Provider-Modell manuell eingeben",
      discoveryHelp:
        "Modellvorschläge werden nach Änderungen an Vendor-Vorlage oder Zugangsdaten automatisch aktualisiert, und Sie können den Provider-Modellnamen weiterhin manuell eingeben.",
      discoveryCredentialsHelp:
        "Fügen Sie einen API Key oder Secret Ref hinzu, um Provider-Modellvorschläge zu laden.",
      manualFallbackHelp:
        "Die automatische Erkennung ist momentan nicht verfügbar. Sie können mit einer manuellen Provider-Modellangabe fortfahren.",
      manualEntryHelp:
        "Dieser Provider verwendet derzeit die manuelle Modelleingabe.",
      currencyPlaceholder: "USD",
      inputPrice: "Eingabepreis / 1M tokens",
      outputPrice: "Ausgabepreis / 1M tokens",
      descriptionPlaceholder:
        "Erläutern Sie, wann dieses Modell verwendet werden sollte.",
      saving: "Speichern...",
      empty:
        "Noch keine Modelle konfiguriert. Fügen Sie eines hinzu, um den sicheren und normalen LLM-Zugriff zu steuern.",
      howItWorks: "So funktioniert es",
      howItWorksSecure:
        "Sichere Modelle sind für sensible Prompts reserviert, die nicht an normale externe Modelle gesendet werden dürfen.",
      howItWorksActive:
        "Nur aktive Modelle können später in Benutzerauswahl und Routing-Regeln auftauchen.",
      howItWorksDiscovery:
        "Integrierte Vendor-Vorlagen decken gängige OpenAI-compatible Provider und lokale Endpunkte ab. Wenn die automatische Erkennung nicht verfügbar ist, kann das Provider-Modell weiterhin manuell eingetragen werden.",
    },
    riskRulesPage: {
      title: "Konfigurierbare Regeln zur Sensitivitätserkennung",
      subtitle:
        "Passen Sie regex-basierte Sensitivitätsrichtlinien an und legen Sie fest, ob jede Regel erlaubt oder an ein sicheres Modell umgeleitet werden soll.",
      addRule: "Regel hinzufügen",
      totalRules: "Gesamtregeln",
      enabled: "Aktiviert",
      disabled: "Deaktiviert",
      allowActions: "Erlauben-Aktionen",
      secureRouteActions: "Sicheres Routing",
      allCategories: "Alle Kategorien",
      searchPlaceholder: "Regel-ID, Name, Beschreibung oder Pattern suchen...",
      allSeverities: "Alle Schweregrade",
      allActions: "Alle Aktionen",
      allStatuses: "Alle Status",
      finishEditing:
        "Beenden oder verwerfen Sie zuerst die aktuelle Bearbeitung, bevor Sie eine andere Regel erstellen oder bearbeiten.",
      loading: "Regeln werden geladen...",
      loadFailed: "Regeln konnten nicht geladen werden",
      requiredFields: "Regel-ID, Anzeigename und Pattern sind erforderlich.",
      duplicateRuleId: "Die Regel-ID existiert bereits.",
      saveFailed: "Regel konnte nicht gespeichert werden",
      disableFailed: "Regel konnte nicht deaktiviert werden",
      statusUpdateFailed: "Regelstatus konnte nicht aktualisiert werden",
      action: "Aktion",
      pattern: "Pattern",
      disable: "Deaktivieren",
      enable: "Aktivieren",
      ruleId: "Regel-ID",
      ruleIdPlaceholder: "email_address",
      ruleIdLocked:
        "Bestehende Regel-IDs sind gesperrt, um versehentliche Fehlzuordnungen in Live-Policies zu vermeiden.",
      severity: "Schweregrad",
      sortOrder: "Sortierung",
      regexPattern: "Regex-Pattern",
      patternPlaceholder:
        "(?i)\\\\b[A-Z0-9._%+\\\\-]+@[A-Z0-9.\\\\-]+\\\\.[A-Z]{2,}\\\\b",
      descriptionPlaceholder: "Beschreiben Sie, was diese Regel erkennt.",
      noRules: "Keine Regeln entsprechen den aktuellen Filtern.",
      testLab: "Regel-Testlabor",
      testLabSubtitle:
        "Fügen Sie Beispieltext ein, um zu sehen, welche aktiven Regeln treffen, oder testen Sie die aktuell bearbeitete Entwurfsregel vor dem Speichern.",
      testEnabled: "Aktive Regeln testen",
      testDraft: "Entwurfsregel testen",
      testing: "Wird getestet...",
      sampleText: "Beispieltext",
      samplePlaceholder:
        "Beispielinhalt einfügen, um Regeltreffer zu prüfen...",
      sampleRequired: "Bitte geben Sie Beispieltext zum Testen ein.",
      noDraftRule: "Derzeit wird keine Regel bearbeitet.",
      testFailed: "Regeltest fehlgeschlagen",
      sensitive: "Sensitiv",
      noMatch: "Kein Treffer",
      highestSeverity: "Höchster Schweregrad: {value}",
      highestAction: "Höchste Aktion: {value}",
      noMatchesForSample:
        "Der angegebene Beispieltext hat keine Regeln getroffen.",
      bulkNoSelection: "Wählen Sie zuerst mindestens eine Regel aus.",
      bulkStatusUpdateFailed:
        "Regelstatus konnte nicht gesammelt aktualisiert werden",
      selectVisible: "Sichtbare auswählen",
      bulkEnable: "Sammel-Aktivieren",
      bulkDisable: "Sammel-Deaktivieren",
      selectRule: "Auswählen",
      categoryPersonal: "Personenbezogen",
      categoryCompany: "Unternehmen",
      categoryCustomer: "Kunde",
      categorySecurity: "Sicherheit",
      categoryFinanceLegal: "Finanzen / Recht",
      categoryPolitical: "Politisch",
      categoryCustom: "Benutzerdefiniert",
    },
    systemSettingsPage: {
      loadFailed: "Bildeinstellungen konnten nicht geladen werden",
      requiredFields: "Instanztyp und Image sind erforderlich.",
      duplicateType: "Für diesen Instanztyp existiert bereits eine Karte.",
      duplicateImage:
        "Dieses Runtime-Image existiert für den gewählten Instanztyp bereits.",
      saveFailed: "Bildeinstellung konnte nicht gespeichert werden",
      deleteFailed: "Bildeinstellung konnte nicht gelöscht werden",
      runtimeImageCards: "Runtime-Image-Karten",
      runtimeImageCardsSubtitle:
        "Konfigurieren Sie die Image-Adresse für jede unterstützte Desktop-Laufzeit. Gespeicherte Karten überschreiben die eingebauten Standardwerte.",
      addCard: "Karte hinzufügen",
      instanceType: "Instanztyp",
      cardTitle: "Kartentitel",
      imageAddress: "Image-Adresse",
      defaultImage: "Standard-Image",
      empty:
        "Es gibt noch keine Runtime-Image-Karten. Fügen Sie eine hinzu, um das Standard-Image für einen Desktop-Typ zu überschreiben.",
    },
    userManagementPage: {
      loading: "Benutzer werden geladen...",
      loadFailed: "Benutzer konnten nicht geladen werden",
      deleteFailed: "Benutzer konnte nicht gelöscht werden",
      loadQuotaFailed: "Kontingent konnte nicht geladen werden",
      updateQuotaFailed: "Kontingent konnte nicht aktualisiert werden",
      updateRoleFailed: "Rolle konnte nicht aktualisiert werden",
      createFailed: "Benutzer konnte nicht erstellt werden",
      selectCsv: "Bitte wählen Sie eine CSV-Datei zum Importieren aus",
      importFailed: "Benutzer konnten nicht importiert werden",
      importUsers: "Benutzer importieren",
      showingUsers: "Zeige Benutzer {from}-{to} von {total}",
      noUsers: "Keine Benutzer gefunden",
      importCompleted:
        "Import abgeschlossen: {created} erstellt, {failed} fehlgeschlagen",
      expectedColumns: "Erwartete Spalten:",
      lineError: "Zeile {line}{username}",
      createdAccounts: "Erstellte Konten",
      quota: "Kontingent",
      initialPassword: "Initiales Passwort",
      supportedFormat: "Unterstütztes Format",
      csvHeaders: "CSV-Datei mit Headern:",
      csvHelp:
        "Username, Role, Max Instances, Max CPU Cores, Max Memory (GB) und Max Storage (GB) sind erforderlich. Email, Password und Max GPU Count sind optional. Wenn Password leer ist, wird das System-Standardpasswort verwendet.",
      downloadTemplate: "CSV-Vorlage herunterladen",
      importFile: "Datei importieren",
      chooseFile: "Datei auswählen",
      noFileSelected: "Keine Datei ausgewählt",
      importing: "Import läuft...",
      startImport: "Import starten",
      addNewUser: "Neuen Benutzer hinzufügen",
      editQuotaFor: "Kontingent für {username} bearbeiten",
      maxInstances: "Maximale Instanzen",
      maxCpuCores: "Maximale CPU-Kerne",
      maxMemoryGb: "Maximaler Speicher (GB)",
      maxStorageGb: "Maximaler Speicherplatz (GB)",
      maxGpuCount: "Maximale GPU-Anzahl",
      changeRoleFor: "Rolle für {username} ändern",
      confirmDeleteTitle: "Löschen bestätigen",
      confirmDeleteMessage:
        "Möchten Sie den Benutzer {username} wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
    },
    errorBoundary: {
      title: "Etwas ist schiefgelaufen",
    },
    userDashboard: {
      subtitle:
        "Verwalten Sie Ihre virtuellen Desktop-Instanzen und Ressourcen im Dashboard.",
      myInstances: "Meine Instanzen",
      running: "Laufend",
      storageUsed: "Genutzter Speicher",
      myResourceQuota: "Mein Ressourcenkontingent",
      loadingQuota: "Kontingent wird geladen...",
      quotaUnavailable: "Keine Kontingentinformationen verfügbar",
      instances: "Instanzen",
      maxCpuCores: "Max. CPU-Kerne",
      maxMemory: "Max. Speicher",
      maxStorage: "Max. Speicherplatz",
      maxGpus: "Max. GPUs",
      recentInstances: "Letzte Instanzen",
      viewAll: "Alle anzeigen",
      quickActions: "Schnellaktionen",
      createNewInstance: "Neue Instanz erstellen",
      viewAllInstances: "Alle Instanzen anzeigen",
      noInstancesYet: "Noch keine Instanzen",
      noInstancesSubtitle:
        "Erstellen Sie zuerst Ihre erste virtuelle Desktop-Instanz",
      createInstance: "Instanz erstellen",
    },
    instances: {
      listTitle: "Meine Instanzen",
      realTimeUpdates: "Echtzeit-Updates",
      connected: "Verbunden",
      disconnected: "Getrennt",
      createInstance: "Instanz erstellen",
      searchPlaceholder: "Nach Name, Typ oder OS suchen...",
      noInstances: "Keine Instanzen",
      noInstancesSubtitle:
        "Erstellen Sie Ihre erste virtuelle Desktop-Instanz, um zu beginnen.",
      noMatchingInstances: "Keine passenden Instanzen",
      noMatchingInstancesSubtitle:
        "Passen Sie Ihre Filter oder Suchanfrage an.",
      clearFilters: "Filter zurücksetzen",
      showingResults: "{filtered} von {total} Instanzen werden angezeigt",
      failedToLoad: "Instanzen konnten nicht geladen werden",
      failedToDelete: "Instanz konnte nicht gelöscht werden",
      failedToStart: "Instanz konnte nicht gestartet werden",
      failedToStop: "Instanz konnte nicht gestoppt werden",
      confirmDelete:
        "Möchten Sie diese Instanz wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
      details: "Details",
      instanceImage: "Instanz-Image",
      runtimeImageSelectionHint:
        "Wählen Sie aus, welche Runtime-Image-Version für diesen Instanztyp verwendet werden soll.",
      runtimeImageUnavailable:
        "Für diesen Instanztyp ist derzeit kein aktiviertes Runtime-Image verfügbar.",
      operatingSystem: "Betriebssystem",
      access: "Zugriff",
      portalView: "Portalansicht",
      portalTitle: "Desktop-Portal",
      portalWorkspace: "Instanzen",
      portalSelectInstance: "Instanz auswählen",
      portalSelectInstanceSubtitle:
        "Wählen Sie links einen Desktop aus, um zu beginnen.",
      portalUnavailable: "Desktop nicht verfügbar",
      portalUnavailableSubtitle:
        "Starten Sie zuerst eine Desktop-Instanz, um hier darauf zuzugreifen.",
      timeline: "Zeitverlauf",
      storage: "Speicher",
      resourceConfiguration: "Ressourcenkonfiguration",
      kubernetesStatus: "Kubernetes-Status",
      accessInfo: "Ihre Instanz läuft und ist bereit für den Zugriff.",
      openDesktop: "Desktop öffnen",
      accessUrlUnavailable: "Zugriffs-URL noch nicht verfügbar",
      startToAccess: "Starten Sie die Instanz, um auf den Desktop zuzugreifen",
      created: "Erstellt",
      lastStarted: "Zuletzt gestartet",
      lastStopped: "Zuletzt gestoppt",
      storageClass: "Storage Class",
      mountPath: "Mount-Pfad",
      podName: "Pod-Name",
      namespace: "Namespace",
      podIp: "Pod-IP",
      podStatus: "Pod-Status",
      loadingInstance: "Instanz wird geladen...",
      instanceNotFound: "Instanz nicht gefunden",
      backToInstances: "Zurück zu den Instanzen",
      basicInformation: "Grundinformationen",
      desktopAccess: "Desktop-Zugriff",
      logsPlaceholder: "Instanz-Logs werden hier angezeigt...",
      logsComingSoon: "Kommt in Phase 6",
      startTheInstance: "Instanz gestoppt",
      startToAccessDesktop:
        "Starten Sie die Instanz, um auf den Desktop zuzugreifen.",
      generatingToken: "Zugriffstoken wird erstellt...",
      accessError: "Zugriffsfehler",
      readyToAccess: "Bereit für den Zugriff",
      generateAccessPrompt:
        "Generieren Sie ein Zugriffstoken, um sich mit {name} zu verbinden.",
      generateAccess: "Zugriff generieren",
      expiresIn: "Läuft ab in",
      refreshToken: "Token aktualisieren",
      accessTokenExpired: "Zugriffstoken abgelaufen",
      regenerateToken: "Token neu erzeugen",
      instanceMustBeRunning: "Die Instanz muss laufen, um darauf zuzugreifen",
      failedToGenerateAccessToken: "Zugriffstoken konnte nicht erstellt werden",
      expired: "Abgelaufen",
      createTitle: "Instanz erstellen",
      stepOf: "Schritt {step} von 3: {label}",
      stepBasic: "Grundinformationen",
      stepType: "Typ wählen",
      stepConfig: "Konfiguration",
      instanceName: "Instanzname *",
      instanceNamePlaceholder: "z. B. my-desktop",
      minimumThreeChars: "Mindestens 3 Zeichen",
      descriptionOptional: "Beschreibung (optional)",
      descriptionPlaceholder: "Kurze Beschreibung dieser Instanz...",
      selectInstanceType: "Instanztyp auswählen",
      quickConfiguration: "Schnellkonfiguration",
      customConfiguration: "Benutzerdefinierte Konfiguration",
      cpuCores: "CPU-Kerne",
      memoryGb: "Speicher (GB)",
      diskGb: "Festplatte (GB)",
      storageClassOptional: "Storage Class (optional)",
      enableGpu: "GPU aktivieren",
      gpuCount: "GPU-Anzahl",
      summary: "Zusammenfassung",
      createFailed: "Instanz konnte nicht erstellt werden",
      nameAlreadyExists: "Eine Instanz mit diesem Namen existiert bereits.",
      next: "Weiter",
      back: "Zurück",
      createNow: "Instanz erstellen",
      creatingNow: "Wird erstellt...",
      defaultStorageClass: "Standard",
      instanceIdLabel: "Instanz-ID",
      heroFallbackDescription:
        "Ein dedizierter Desktop-Arbeitsbereich mit isolierten Cluster-Ressourcen, eigenem Speicher und sicherem Zugriff per Klick.",
      allocatedCompute: "Zugewiesene Rechenleistung",
      reservedRam: "Reservierter RAM",
      persistentDisk: "Persistente Festplatte",
      launchLiveSession: "Live-Desktop öffnen",
      desktopAvailableAfterStart:
        "Der Desktop ist verfügbar, sobald die Instanz gestartet wurde",
      instanceDossier: "Instanzprofil",
      allocatedProfile: "Zugewiesenes Profil",
      kubernetesSection: "Kubernetes",
      volumeMapping: "Volume-Zuordnung",
      workspaceSection: "Arbeitsbereich",
      openClawWorkspace: "OpenClaw-Arbeitsbereich",
      openClawWorkspaceDesc:
        "Importieren oder exportieren Sie den Ordner `.openclaw` als `.tar.gz`-Archiv bis 50 MiB.",
      runtimeWorkspace: "{runtime}-Arbeitsbereich",
      runtimeWorkspaceDesc:
        "Importieren oder exportieren Sie den Ordner `{directory}` als `.tar.gz`-Archiv bis 50 MiB.",
      workspaceReady: "Bereit",
      workspacePaused: "Pausiert",
      exportingOpenClaw: "Export wird erstellt...",
      exportOpenClaw: ".openclaw exportieren",
      importingOpenClaw: "Import läuft...",
      importOpenClaw: ".openclaw importieren",
      importOpenClawSuccess: "OpenClaw-Arbeitsbereich erfolgreich importiert.",
      exportingRuntimeWorkspace: "Export wird erstellt...",
      exportRuntimeWorkspace: "{directory} exportieren",
      importingRuntimeWorkspace: "Import läuft...",
      importRuntimeWorkspace: "{directory} importieren",
      importRuntimeWorkspaceSuccess:
        "{runtime}-Arbeitsbereich erfolgreich importiert.",
      openClawArchiveTooLarge: "Archiv zu groß. Die maximale Größe beträgt 50 MiB.",
      importOpenClawFailed: ".openclaw-Import fehlgeschlagen: {message}",
      exportOpenClawFailed: ".openclaw-Export fehlgeschlagen: {message}",
      importRuntimeWorkspaceFailed:
        "{directory}-Import fehlgeschlagen: {message}",
      exportRuntimeWorkspaceFailed:
        "{directory}-Export fehlgeschlagen: {message}",
      memoryReserved: "Reservierter Speicher",
      persistentStorage: "Persistenter Speicher",
      gpuAttached: "Zugewiesene GPU",
      waitingForRunningState:
        "Es wird gewartet, bis die Instanz läuft, bevor .openclaw importiert wird.",
      timedOutWaitingForRunning:
        "Zeitüberschreitung beim Warten auf den laufenden Zustand der Instanz vor dem .openclaw-Import.",
      openClawImportTitle: "OpenClaw-Import",
      openClawImportDesc:
        "Optional. Wählen Sie ein exportiertes `.openclaw`-Archiv aus; es wird nach dem Start der Instanz automatisch importiert.",
      optional: "Optional",
      changeOpenClawArchive: ".openclaw-Archiv ändern",
      chooseOpenClawArchive: ".openclaw-Archiv auswählen",
      changeRuntimeArchive: "{directory}-Archiv ändern",
      chooseRuntimeArchive: "{directory}-Archiv auswählen",
      remove: "Entfernen",
      selectedArchive: "Ausgewähltes Archiv: {name}",
      noArchiveSelected:
        "Kein Archiv ausgewählt. Die Instanz wird mit einem leeren .openclaw-Arbeitsbereich erstellt.",
      noRuntimeArchiveSelected:
        "Kein Archiv ausgewählt. Die Instanz wird mit einem leeren {directory}-Arbeitsbereich erstellt.",
      quotaValidation: "Kontingentprüfung",
      unableToLoadQuota:
        "Ihr Kontingent konnte nicht geladen werden. Instanz erstellen bleibt deaktiviert, bis das Kontingent verfügbar ist.",
      requestedResourcesExceeded:
        "Die angeforderten Ressourcen überschreiten Ihr zugewiesenes Kontingent. Reduzieren Sie die Konfiguration vor dem Erstellen.",
      quotaInstances: "Instanzen",
      checkingQuota: "Kontingent wird geprüft...",
      creatingAndImporting: "Erstellen und importieren...",
      typeOptions: {
        ubuntu: {
          label: "Ubuntu-Desktop",
          description: "Beliebte Linux-Distribution mit GNOME-Desktop",
        },
        debian: {
          label: "Debian-Desktop",
          description: "Stabile und sichere Linux-Distribution",
        },
        centos: {
          label: "CentOS-Desktop",
          description: "Linux-Distribution der Enterprise-Klasse",
        },
        openclaw: {
          label: "OpenClaw-Desktop",
          description: "Für OpenClaw optimierte Desktop-Umgebung",
        },
        webtop: {
          label: "Webtop-Desktop",
          description:
            "Browserbasierter Linux-Desktop, der über ClawManager bereitgestellt wird",
        },
        hermes: {
          label: "Hermes Runtime",
          description:
            "Hermes-Runtime auf Basis des Webtop-Desktop-Images",
        },
        custom: {
          label: "Benutzerdefiniertes Image",
          description: "Eigenes benutzerdefiniertes Image verwenden",
        },
      },
      presetOptions: {
        small: {
          label: "Small",
          description: "Geeignet für leichte Aufgaben",
        },
        medium: {
          label: "Medium",
          description: "Gut für Entwicklungsarbeit",
        },
        large: {
          label: "Large",
          description: "Für hohe Lasten",
        },
      },
      customPresetTitle: "Benutzerdefiniert",
      customPresetDescription:
        "Manuelle Größenanpassung mit Medium als Ausgangspunkt.",
      customPresetEditing: "Wird bearbeitet",
      resourcePresetSummary:
        "{cpu} CPU • {memory} GB RAM • {disk} GB Festplatte",
      mediumDefaultPreset:
        "Medium-Standard: {cpu} CPU • {memory} GB RAM • {disk} GB Festplatte",
      presetCpuShort: "CPU",
      presetRamShort: "RAM",
      presetDiskShort: "Disk",
      environmentVariables: "Umgebungsvariablen",
      clawManagerBuiltIns: "ClawManager Built-ins",
      hideBuiltIns: "Built-ins ausblenden",
      editBuiltIns: "Built-ins bearbeiten",
      editBuiltInsCount: "Built-ins bearbeiten ({count})",
      builtinOverridesConfigured:
        "{count} Built-in-Überschreibung(en) konfiguriert. Zum Prüfen oder Bearbeiten ausklappen.",
      usingBuiltInDefaults:
        "Für {count} Built-in-Variablen werden die ClawManager-Standardwerte verwendet.",
      builtinOverrideHelp:
        "Fügen Sie nur die Built-ins hinzu, die Sie überschreiben möchten. Nicht aufgeführte Variablen behalten ihre Standardwerte.",
      addBuiltinVariable: "Built-in-Variable hinzufügen",
      noBuiltinOverrides: "Noch keine Built-in-Überschreibungen hinzugefügt.",
      defaultValue: "Standard: {value}",
      variable: "Variable",
      overrideValue: "Überschreibungswert",
      overrideValuePlaceholder: "Wert überschreiben",
      actionLabel: "Aktion",
      customVariables: "Benutzerdefinierte Variablen",
      addVariable: "Variable hinzufügen",
      noCustomEnvironmentVariables:
        "Noch keine benutzerdefinierten Umgebungsvariablen.",
      variableNamePlaceholder: "VARIABLE_NAME",
      variableValuePlaceholder: "value",
      customEnvNameRequired:
        "Name der benutzerdefinierten Umgebungsvariable ist erforderlich.",
      invalidEnvName: "Ungültiger Umgebungsvariablenname: {name}",
      reservedBuiltinEnvName:
        "{name} ist eine ClawManager-Built-in-Variable. Bearbeiten Sie sie stattdessen im Built-in-Bereich.",
      duplicateEnvName: "Doppelter Umgebungsvariablenname: {name}",
      openClawInjection: "OpenClaw-Injektion",
      runtimeInjection: "{runtime}-Injektion",
      selectedCount: "{count} ausgewählt",
      noReusableSkillsSelected: "Keine wiederverwendbaren Skills ausgewählt.",
      noAvailableSkillsForInjection:
        "Keine verfügbaren Skills. Importieren Sie zuerst Skills aus dem Ressourcencenter.",
      skillRiskVersionLabel: "{key} · Risiko {risk} · v{version}",
      skillPageSummary: "Seite {page} von {totalPages} · {totalSkills} Skills",
      archiveImport: "Archivimport",
      archiveModeRequiresFile: "Für den Archivmodus erforderlich",
      envInjection: "Env-Injektion",
      noEnvOverridesConfigured:
        "Keine Container-Umgebungsvariablenüberschreibungen konfiguriert.",
      channelInjection: "Channel-Injektion",
      archiveSkipsChannelInjection:
        "Der Archivmodus überspringt die ressourcenbasierte Channel-Injektion.",
      compilingOpenClawPreview: "OpenClaw-Ressourcenvorschau wird erstellt...",
      compilingRuntimePreview: "Runtime-Ressourcenvorschau wird erstellt...",
      noChannelsSelectedForInjection:
        "Keine Channels für die Injektion ausgewählt.",
      skillInjection: "Skill-Injektion",
      envManagedProxyPath: "Von ClawManager verwalteter Proxy-Pfad",
      envGeneratedAtRuntime: "Von ClawManager zur Laufzeit generiert",
      envAssignedAfterCreation: "Nach der Erstellung zugewiesen",
      envManagedAtRuntime: "Von ClawManager zur Laufzeit verwaltet",
      envDescDesktopTitleWebtop:
        "Fenstertitel des Desktops, der in den LinuxServer-Webtop-Container injiziert wird.",
      envDescDesktopTitleOpenClaw:
        "Desktop-Titel, der im OpenClaw-Browser-Desktop-Image angezeigt wird.",
      envDescProxySubfolder:
        "Pfadpräfix, das vom ClawManager-Reverse-Proxy für den Browserzugriff verwendet wird.",
      envDescLlmBaseUrl:
        "Von ClawManager zur Laufzeit erzeugte OpenClaw-Gateway-Basis-URL.",
      envDescLlmApiKey:
        "Von ClawManager pro Instanz ausgegebener Gateway-API-Schlüssel.",
      envDescLlmModel:
        "Als JSON injizierter Gateway-Modellkatalog fuer den OpenClaw-Arbeitsbereich, wobei auto der erste Eintrag bleibt.",
      envDescLlmProvider: "Provider-Hinweis für den OpenClaw-Arbeitsbereich.",
      envDescInstanceToken:
        "Von ClawManager erzeugtes Instanztoken für den Arbeitsbereichszugriff.",
      envDescOpenAiBaseUrl:
        "Kompatibilitätsalias für die Basis-URL des OpenAI-kompatiblen Gateways.",
      envDescOpenAiApiBase:
        "Kompatibilitätsalias für die Basis-URL des OpenAI-kompatiblen Gateways.",
      envDescOpenAiApiKey:
        "Kompatibilitätsalias für den Gateway-API-Schlüssel.",
      envDescOpenAiModel: "Kompatibilitätsalias für den Standardmodellnamen.",
      envDescAgentEnabled:
        "Schaltet den ClawManager-Instanz-Agenten innerhalb von OpenClaw ein oder aus.",
      envDescAgentBaseUrl:
        "Basis-URL, die der In-Instance-Agent-Control-Plane-Client verwendet.",
      envDescAgentBootstrapToken:
        "Von ClawManager für den In-Instance-Agent erzeugtes Bootstrap-Token.",
      envDescAgentDiskLimitBytes:
        "Dem Instanz-Agenten injiziertes Festplattenkontingent.",
      envDescAgentInstanceId:
        "Laufzeit-Instanzkennung, die dem In-Instance-Agenten bereitgestellt wird.",
      envDescAgentPersistentDir:
        "Persistenter Arbeitsbereichspfad, der in den OpenClaw-Container eingehängt wird.",
      envDescAgentProtocolVersion:
        "Von der ClawManager-Agent-Control-Plane erwartete Protokollversion.",
      gpuLabel: "GPU",
      cpuCoresValue: "{value} Kerne",
      gpuCountValue: "{count} GPU(s)",
      memoryLabel: "Speicher",
      storageLabel: "Speicherplatz",
      gpuDisabled: "Deaktiviert",
      noOpenClawArchiveSelected: "Kein .openclaw-Archiv ausgewählt",
      live: "Live",
      notAvailable: "k. A.",
      runtimeCommandFailed: "{command} konnte nicht ausgeführt werden",
      failedToAttachSkill: "Skill konnte nicht zugewiesen werden",
      failedToRemoveSkill: "Skill konnte nicht entfernt werden",
      kubernetesStatusTitle: "Pod- und Infrastrukturstatus",
      infrastructureReady: "Infrastruktur bereit",
      skillsSection: "Skills",
      skillManagement: "Skill-Verwaltung",
      selectSkill: "Skill auswählen",
      installingSkill: "Wird installiert...",
      installSkill: "Skill installieren",
      noSkillsReported: "Für diese Instanz wurden noch keine Skills gemeldet.",
      skillFallback: "Skill #{id}",
      lastSeenAt: "zuletzt gesehen {value}",
      removingSkill: "Wird entfernt...",
      removeSkill: "Entfernen",
      skillPagination: "Zeige Skill {from}-{to} von {total}",
      previous: "Zurück",
      nextPage: "Weiter",
      timelineSubtitle: "Instanzaktionen und Laufzeithistorie",
      timelineEvents: "{count} Ereignisse",
      noRuntimeActivity: "Noch keine Laufzeitaktivität.",
      minimap: "Minimap",
      runtimeSummary: "Laufzeitübersicht",
      agentReportedStatus: "Vom Agent gemeldeter Status",
      fresh: "Aktuell",
      operatingSystemShort: "OS",
      openClawShort: "OpenClaw",
      agents: "Agenten",
      channels: "Kanäle",
      agentStatusLabel: "Agent {status}",
      gatewayStatusLabel: "Gateway {status}",
      agentId: "Agent-ID",
      agentVersion: "Agent-Version",
      protocol: "Protokoll",
      lastHeartbeat: "Letzter Heartbeat",
      lastReport: "Letzter Bericht",
      skillSourceUploaded: "Hochgeladen",
      skillSourceDiscovered: "Erkannt",
      skillRiskNone: "Sicher",
      skillRiskLow: "Niedrig",
      skillRiskMedium: "Mittel",
      skillRiskHigh: "Hoch",
      skillRiskUnknown: "Unbekannt",
      timelineInstanceCreated: "Instanz erstellt",
      timelineInstanceCreatedDetail: "{name} wurde als {type} bereitgestellt.",
      timelineInstanceStarted: "Instanz gestartet",
      timelineInstanceStartedDetail:
        "Der Infrastrukturstart wurde für diese Instanz erfasst.",
      timelineInstanceStopped: "Instanz gestoppt",
      timelineInstanceStoppedDetail:
        "Der Infrastrukturstopp wurde für diese Instanz erfasst.",
      timelineAgentRegistered: "Agent registriert",
      timelineAgentRegisteredDetail:
        "{agentId} hat sich über Protokoll {protocol} mit ClawManager verbunden.",
      timelineRuntimeReported: "Laufzeitstatus gemeldet",
      timelineRuntimeReportedDetail:
        "Der Agent meldete Gateway-Status {gatewayStatus} und Infra-Status {infraStatus}.",
      timelinePodStatusObserved: "Pod-Status erkannt",
      timelinePodStatusObservedDetail:
        "Kubernetes meldet derzeit den Pod-Status {status}.",
      timelineCommandWithError: "{status}: {error}",
      timelineCommandWithIdempotency: "{status} · Idempotenzschlüssel {key}",
      timelineSectionInstance: "Instanz",
      timelineSectionInfra: "Infra",
      timelineSectionAgent: "Agent",
      timelineSectionRuntime: "Laufzeit",
      timelineSectionKubernetes: "K8s",
      timelineSectionCommand: "Befehl",
      metricCpu: "CPU",
      metricCpuDetail:
        "{cores} Kerne · Last 1m {load1} · 5m {load5} · 15m {load15}",
      metricMemory: "Speicher",
      metricMemoryDetail: "{used} genutzt / {total}",
      metricDisk: "Festplatte",
      metricDiskDetail: "{free} frei / {total}",
      metricNetwork: "Netzwerk",
      metricNetworkDetail:
        "{addresses} Adressen über {interfaces} Schnittstellen",
      metricLegendDown: "Down",
      metricLegendUp: "Up",
      metricTrafficDetail: "Eingehend {inbound} · Ausgehend {outbound}",
    },
    openClawResourcesPage: {
      title: "OpenClaw Ressourcenverwaltung",
      tabs: {
        resources: "Ressourcen",
        bundles: "Bundles",
        injections: "Injektionsprotokolle",
      },
      resourceTypesTitle: "Ressourcentypen",
      searchPlaceholder: "Ressourcen suchen...",
      resourceListHint:
        "Klicken Sie auf eine Ressourcenkarte, um sie in einem Popup statt direkt auf der Seite zu bearbeiten.",
      loadingResources: "Ressourcen werden geladen...",
      noResources:
        "Für diesen Typ gibt es noch keine Ressourcen. Klicken Sie auf „Neu“, um eine anzulegen.",
      enabled: "Aktiviert",
      disabled: "Deaktiviert",
      thisResourceType: "Dieser Ressourcentyp",
      notConfigurableYet: "{type} ist noch nicht konfigurierbar.",
      onlyChannelConfigurable:
        "Derzeit werden nur Channel-Ressourcen unterstützt. Editoren für Skill, Agent und Scheduled Task folgen in einem späteren Update.",
      bundlesSubtitle:
        "Stellen Sie wiederverwendbare OpenClaw-Startpakete in einem separaten Popup-Editor zusammen.",
      loadingBundles: "Bundles werden geladen...",
      noBundles:
        "Es gibt noch keine Bundles. Klicken Sie auf „Neues Bundle“, um eines anzulegen.",
      bundleResourceCount: "{count} Ressource(n)",
      injectionsSubtitle:
        "Snapshots werden beim Erstellen einer Instanz gespeichert und beim Neustart wiederverwendet.",
      snapshot: "Snapshot",
      mode: "Modus",
      resources: "Ressourcen",
      envCount: "Env-Anzahl",
      created: "Erstellt",
      loadingSnapshots: "Snapshots werden geladen...",
      noInjectionRecords: "Es gibt noch keine OpenClaw-Injektionsprotokolle.",
      paginationSummary: "{pageSize} pro Seite, zeige {from}-{to}",
      paginationPrev: "Zurück",
      paginationNext: "Weiter",
      skillUploadHint:
        "Nur `.zip` hochladen. Jedes Verzeichnis auf oberster Ebene wird als ein Skill importiert.",
      loadingSkills: "Skills werden geladen...",
      noSkills: "Noch keine Skills hochgeladen.",
      skillMeta: "{key} · Risiko {risk} · in {count} Instanz(en) verwendet",
      recordModes: {
        none: "Keine",
        manual: "Manuell",
        bundle: "Bundle",
        archive: "Archiv",
      },
      recordStatuses: {
        compiled: "Kompiliert",
        active: "Aktiv",
        failed: "Fehlgeschlagen",
      },
      editResourceTitle: "Ressource bearbeiten",
      newResourceTitle: "Neue Ressource",
      editResourceSubtitle:
        "Passen Sie Metadaten und JSON in einem fokussierten Popup-Editor an.",
      newResourceSubtitle:
        "Erstellen Sie eine neue OpenClaw-Ressource, ohne den kompletten Editor auf der Seite anzuzeigen.",
      resourceKey: "Ressourcenschlüssel",
      name: "Name",
      tags: "Tags",
      tagsPlaceholder: "tag1,tag2",
      channelTemplate: "Channel-Template",
      chooseStarterTemplate: "Starter-Template auswählen",
      channelTemplateHint:
        "Hier werden nur Slack, Telegram, DingTalk und Feishu unterstützt. Starten Sie im Formularmodus und wechseln Sie erst zu JSON, wenn Sie die komplette Konfigurationsoberfläche brauchen.",
      templateKey: "Schlüssel: {key}",
      invalidChannelJson:
        "Dieses Channel-JSON ist derzeit ungültig. Wechseln Sie zuerst in den JSON-Modus, beheben Sie den Fehler und kehren Sie dann zum Formular zurück.",
      contentJson: "Inhalts-JSON",
      editBundleTitle: "Bundle bearbeiten",
      newBundleTitle: "Neues Bundle",
      editBundleSubtitle:
        "Überarbeiten Sie ein wiederverwendbares Startpaket in einem fokussierten Popup-Editor.",
      newBundleSubtitle:
        "Erstellen Sie ein neues wiederverwendbares Bundle, ohne die Ressourcenliste zu verlassen.",
      bundleName: "Bundle-Name",
      bundleResources: "Bundle-Ressourcen",
      noResourcesForGroup: "Es gibt noch keine {type}-Ressourcen.",
      actions: {
        new: "Neu",
        newBundle: "Neues Bundle",
        loadTemplate: "Template laden",
        saveResource: "Ressource speichern",
        createResource: "Ressource erstellen",
        validateJson: "JSON prüfen",
        clone: "Klonen",
        saveBundle: "Bundle speichern",
        createBundle: "Bundle erstellen",
      },
      resourceTypes: {
        channel: "Kanal",
        skill: "Fähigkeit",
        session_template: "Sitzungsvorlage",
        log_policy: "Log-Richtlinie",
        agent: "Agent",
        scheduled_task: "Geplanter Task",
      },
      templateCategories: {
        builtin: "Integriert",
        plugin: "Plugin",
      },
      templates: {
        telegram: {
          label: "Telegram",
          description:
            "Telegram-Bot-API-Channel mit Steuerung für Direktnachrichten und Gruppenrichtlinien.",
        },
        dingtalkConnector: {
          label: "DingTalk",
          description:
            "DingTalk-Channel mit Client-Zugangsdaten und Absender-Allowlist-Steuerung.",
        },
        slack: {
          label: "Slack",
          description: "Slack-Workspace-App auf Basis von Bolt.",
        },
        feishu: {
          label: "Feishu / Lark",
          description:
            "Feishu- oder Lark-Channel mit kontobezogenen Standardwerten.",
        },
      },
      editorModes: {
        form: "Formular",
        json: "JSON",
      },
      channelEditors: {
        dingtalkConnector: {
          title: "DingTalk-Channel-Editor",
          description:
            "Beginnen Sie mit dem Formular für die Client-Zugangsdaten und wechseln Sie nur bei Bedarf zur vollständigen JSON-Konfiguration.",
          fields: {
            clientId: {
              label: "Client ID",
              placeholder: "ding-xxxxxxxxxxxxxx",
            },
            clientSecret: {
              label: "Client Secret",
              placeholder: "client secret",
            },
          },
        },
        feishu: {
          title: "Feishu-Channel-Editor",
          description:
            "Beginnen Sie mit dem Formular für das Hauptkonto und wechseln Sie nur bei Bedarf zur vollständigen JSON-Konfiguration.",
          fields: {
            appId: {
              label: "App ID",
              placeholder: "cli_xxx",
            },
            appSecret: {
              label: "App Secret",
              placeholder: "app secret",
            },
          },
        },
        slack: {
          title: "Slack-Channel-Editor",
          description:
            "Beginnen Sie mit dem Token-Formular und wechseln Sie nur bei Bedarf zur vollständigen JSON-Konfiguration.",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "xoxb-...",
            },
            appToken: {
              label: "App Token",
              placeholder: "xapp-...",
            },
          },
        },
        telegram: {
          title: "Telegram-Channel-Editor",
          description:
            "Beginnen Sie mit dem Bot-Token-Formular und wechseln Sie nur bei Bedarf zur vollständigen JSON-Konfiguration.",
          fields: {
            botToken: {
              label: "Bot Token",
              placeholder: "123456:ABCDEF",
            },
          },
        },
      },
      notices: {
        resourceUpdated: "Ressource wurde aktualisiert.",
        resourceCreated: "Ressource wurde erstellt.",
        resourceDeleted: "Ressource wurde gelöscht.",
        resourceCloned: "Ressource wurde geklont.",
        resourceJsonValid: "Ressourcen-JSON ist gültig.",
        templateLoaded: "Template {name} wurde geladen.",
        bundleUpdated: "Bundle wurde aktualisiert.",
        bundleCreated: "Bundle wurde erstellt.",
        bundleDeleted: "Bundle wurde gelöscht.",
        bundleCloned: "Bundle wurde geklont.",
        skillArchiveImported: "Skill-Archiv wurde importiert.",
        skillDeleted: "Skill wurde gelöscht.",
      },
      errors: {
        loadFailed: "OpenClaw-Ressourcen konnten nicht geladen werden.",
        saveResource: "Ressource konnte nicht gespeichert werden.",
        validationFailed: "Ressourcen-JSON konnte nicht geprüft werden.",
        deleteResource: "Ressource konnte nicht gelöscht werden.",
        cloneResource: "Ressource konnte nicht geklont werden.",
        saveBundle: "Bundle konnte nicht gespeichert werden.",
        deleteBundle: "Bundle konnte nicht gelöscht werden.",
        cloneBundle: "Bundle konnte nicht geklont werden.",
        importSkillArchive: "Skill-Archiv konnte nicht importiert werden.",
        deleteSkill: "Skill konnte nicht gelöscht werden.",
        downloadSkill: "Skill konnte nicht heruntergeladen werden.",
      },
      skillActions: {
        chooseFile: "Datei wählen",
        uploadArchive: "Skill-Archiv hochladen",
        download: "Herunterladen",
      },
      risks: {
        none: "sicher",
        low: "niedrig",
        medium: "mittel",
        high: "hoch",
        unknown: "unbekannt",
      },
      confirms: {
        deleteResource: "Ressource „{name}“ löschen?",
        deleteBundle: "Bundle „{name}“ löschen?",
      },
    },
    openClawInjectionSection: {
      title: "OpenClaw-Ressourceninjektion",
      subtitle:
        "Wählen Sie, wie diese Instanz OpenClaw startet. Klicken Sie erneut auf eine aktive Option, um die Auswahl aufzuheben.",
      optional: "Optional",
      modes: {
        manual: "Manuelle Ressourcen",
        bundle: "Bundle",
        archive: "Archivimport",
      },
      loading: "Daten der Ressourcenverwaltung werden geladen...",
      chooseBundle: "Bundle auswählen",
      selectBundle: "Bundle auswählen",
      bundleOptionCount: "{count} Ressourcen",
      channel: "Kanal",
      noChannelResources: "Keine Kanal-Ressourcen verfügbar.",
      errors: {
        chooseBundle: "Wählen Sie zuerst ein Bundle aus.",
        chooseResource: "Wählen Sie mindestens eine Ressource aus.",
        compileFailed:
          "Die OpenClaw-Bootstrap-Vorschau konnte nicht erstellt werden.",
      },
    },
  },
};

export function translate(locale: Locale, key: string): string | undefined {
  const segments = key.split(".");
  let current: string | TranslationTree | undefined = translations[locale];

  for (const segment of segments) {
    if (!current || typeof current === "string") {
      return undefined;
    }
    current = current[segment];
  }

  return typeof current === "string" ? current : undefined;
}

export function interpolate(
  template: string,
  variables?: Record<string, string | number>,
): string {
  if (!variables) {
    return template;
  }

  return template.replace(/\{(\w+)\}/g, (_, key: string) => {
    const value = variables[key];
    return value === undefined ? `{${key}}` : String(value);
  });
}
