import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

const resources = {
  en: {
    translation: {
      dashboard: 'Dashboard',
      chat: 'Chat',
      config: 'Config',
      whatsappBridge: 'WhatsApp',
      channelsGroup: 'Channels',
      whatsappBridgeHint: 'Show WhatsApp bridge status, QR login, and the current linked companion session.',
      telegramChannelHint: 'Configure Telegram token, allowed senders and group behavior for the built-in Telegram channel.',
      discordChannelHint: 'Configure Discord bot token and allowed senders for the Discord channel.',
      feishuChannelHint: 'Configure Feishu app credentials and group policy for the Feishu channel.',
      qqChannelHint: 'Configure QQ bot credentials for the QQ channel.',
      dingtalkChannelHint: 'Configure DingTalk app credentials for the DingTalk channel.',
      maixcamChannelHint: 'Configure host, port, and allowed senders for the MaixCam channel.',
      whatsappBridgeRunning: 'Bridge Running',
      whatsappBridgeStopped: 'Bridge Stopped',
      whatsappBridgeURL: 'Bridge URL',
      whatsappBridgeAccount: 'Linked Account',
      whatsappBridgeLastEvent: 'Last Event',
      whatsappBridgeQRCode: 'QR Login',
      whatsappQRCodeReady: 'Scan with WhatsApp',
      whatsappQRCodeUnavailable: 'QR not available',
      whatsappQRCodeHint: 'If you are already linked, no QR is shown.\nIf the bridge is not running, start `clawgo channel whatsapp bridge run` first.',
      whatsappStateAwaitingScan: 'Awaiting Scan',
      whatsappStateDisconnected: 'Disconnected',
      whatsappBridgeDevHintTitle: 'How to use',
      whatsappBridgeDevHint: '1. Start the bridge with `clawgo channel whatsapp bridge run`.\n2. Scan the QR code here with WhatsApp.\n3. Keep `make dev` running to receive WhatsApp messages in ClawGo.',
      whatsappFieldEnabledHint: 'Master switch for receiving WhatsApp messages through the bridge.',
      whatsappFieldBridgeURLHint: 'WebSocket address of the local WhatsApp companion bridge service.',
      whatsappFieldAllowFromHint: 'One sender JID per line. Only these senders can trigger ClawGo.',
      whatsappFieldEnableGroupsHint: 'Allow messages from WhatsApp groups to enter the channel.',
      whatsappFieldRequireMentionHint: 'When enabled, group messages must mention the bot before being handled.',
      whatsappFieldAllowFromFootnote: 'Supports one JID per line, and also accepts comma-separated values.',
      whatsappLogoutTitle: 'Logout WhatsApp Session',
      whatsappLogoutMessage: 'Unlink the current WhatsApp companion session and request a new QR code?',
      mcpServices: 'MCP',
      mcpServicesHint: 'Manage MCP servers and install service packages.',
      cronJobs: 'Cron Jobs',
      nodes: 'Nodes',
      nodeArtifacts: 'Node Artifacts',
      nodeArtifactsHint: 'Browse, download, and delete files or media returned from node dispatches.',
      nodeArtifactsEmpty: 'No node artifacts found.',
      nodeArtifactsPrune: 'Prune',
      nodeArtifactsKeepLatest: 'Keep latest N',
      nodeArtifactsRetention: 'Artifact Retention',
      nodeArtifactsRetentionHint: 'Latest auto-prune result from node artifact retention.',
      nodeArtifactsRetentionKeepLatest: 'Keep latest',
      nodeArtifactsRetentionRetainDays: 'Retain days',
      nodeArtifactsRetentionPruned: 'Pruned this run',
      nodeArtifactsRetentionRemaining: 'Remaining',
      nodeArtifactDetail: 'Artifact Detail',
      nodeArtifactPreviewUnavailable: 'Preview unavailable for this artifact.',
      allNodes: 'All Nodes',
      allKinds: 'All Kinds',
      size: 'Size',
      nodesDetailHint: 'Inspect node capabilities, mirrored remote agents, recent dispatches, and returned artifacts.',
      nodesFilterPlaceholder: 'Filter by node id, name, or tag',
      agentTree: 'Agent Tree',
      noAgentTree: 'No agent tree available.',
      readonlyMirror: 'Read-only mirror',
      localControl: 'Local control',
      logs: 'Real-time Logs',
      logCodes: 'Log Codes',
      skills: 'Skills',
      memory: 'Memory',
      taskAudit: 'Task Audit',
      tasks: 'Tasks',
      subagentProfiles: 'Subagent Profiles',
      subagentsRuntime: 'Agents',
      nodeP2P: 'Node P2P',
      nodeAlerts: 'Node Alerts',
      nodeAlertsEmpty: 'No active node alerts.',
      nodeTags: 'Node Tags',
      nodeDispatchDetail: 'Dispatch Detail',
      replayDispatch: 'Replay Dispatch',
      replaying: 'Replaying...',
      resetReplayDraft: 'Reset Draft',
      nodeReplayRequest: 'Replay Request',
      nodeReplayResult: 'Replay Result',
      nodeReplayInvalidArgs: 'Replay args must be valid JSON.',
      agentTopology: 'Agent Topology',
      agentTopologyHint: 'Unified graph for local agents, registered nodes, and mirrored remote agent branches.',
      runningTasks: 'running',
      clearFocus: 'Clear Focus',
      zoomIn: 'Zoom In',
      zoomOut: 'Zoom Out',
      fitView: 'Fit View',
      childrenCount: 'children',
      'topologyFilter.all': 'All',
      'topologyFilter.running': 'Running',
      'topologyFilter.failed': 'Failed',
      'topologyFilter.local': 'Local',
      'topologyFilter.remote': 'Remote',
      noLiveTasks: 'No live tasks',
      remoteTasksUnavailable: 'Remote task details are not mirrored yet.',
      subagentDetail: 'Subagent Detail',
      spawnSubagent: 'Spawn Subagent',
      dispatchAndWait: 'Dispatch And Wait',
      dispatchReply: 'Dispatch Reply',
      mergedResult: 'Merged Result',
      configSubagentDraft: 'Config Subagent',
      agentRegistry: 'Agent Registry',
      loadDraft: 'Load Draft',
      enableAgent: 'Enable Agent',
      disableAgent: 'Disable Agent',
      deleteAgent: 'Delete Agent',
      deleteAgentConfirm: 'Delete agent "{{id}}" from config.json permanently?',
      noRegistryAgents: 'No configured agents.',
      saveToConfig: 'Save To Config',
      configSubagentSaved: 'Subagent config saved and runtime updated.',
      promptFileEditor: 'Prompt File Editor',
      promptFileEditorPlaceholder: 'Edit the AGENT.md content for this subagent.',
      bootstrapPromptFile: 'Bootstrap AGENT.md',
      savePromptFile: 'Save AGENT.md',
      promptFileSaved: 'Prompt file saved.',
      promptFileBootstrapped: 'Prompt file template created.',
      promptFileReady: 'AGENT.md ready',
      promptFileMissing: 'AGENT.md missing',
      threadTrace: 'Thread Trace',
      threadMessages: 'Thread Messages',
      inbox: 'Inbox',
      reply: 'Reply',
      ack: 'Ack',
      steerMessage: 'Steering message',
      newProfile: 'New Profile',
      spawn: 'Spawn',
      kill: 'Kill',
      send: 'Send',
      dispatch: 'Dispatch',
      toolAllowlist: 'Tool Allowlist',
      memoryNamespace: 'Memory Namespace',
      subagentDeleteConfirmTitle: 'Delete Subagent Profile',
      subagentDeleteConfirmMessage: 'Delete subagent profile "{{id}}" permanently?',
      sidebarCore: 'Core',
      sidebarMain: 'Main',
      sidebarAgents: 'Agents',
      sidebarRuntime: 'Runtime',
      sidebarConfig: 'Configuration',
      sidebarKnowledge: 'Knowledge',
      sidebarSystem: 'System',
      sidebarOps: 'Operations',
      sidebarInsights: 'Insights',
      ekg: 'EKG',
      ekgEscalations: 'Escalations',
      ekgSourceStats: 'Source Stats',
      ekgChannelStats: 'Channel Stats',
      ekgTopProvidersWorkload: 'Top Providers (workload)',
      ekgTopProvidersAll: 'Top Providers (all)',
      ekgTopErrsigWorkload: 'Top Error Signatures (workload)',
      ekgTopErrsigHeartbeat: 'Top Error Signatures (heartbeat)',
      ekgTopErrsigAll: 'Top Error Signatures (all)',
      taskList: 'Task List',
      taskDetail: 'Task Detail',
      taskQueue: 'Task Queue',
      taskLogs: 'Task Logs',
      mediaSources: 'Media Sources',
      lastPauseReason: 'Last Pause Reason',
      lastPauseAt: 'Last Pause Time',
      allSources: 'All Sources',
      allStatus: 'All Status',
      export: 'Export',
      error: 'Error',
      noTaskAudit: 'No task audit records',
      selectTask: 'Select a task from the left list',
      loading: 'Loading...',
      gatewayStatus: 'Gateway Status',
      githubRepo: 'GitHub Repository',
      checkVersion: 'Check Latest Version',
      versionCheckUpToDateTitle: 'Already Up To Date',
      versionCheckUpToDateMessage: 'Current gateway and WebUI already match {{version}}.',
      versionCheckUpdateTitle: 'Update Available',
      versionCheckUpdateMessage: 'Latest: {{latest}}\nGateway: {{gateway}}\nWebUI: {{webui}}',
      versionCheckFailedTitle: 'Version Check Failed',
      versionCheckFailedMessage: 'Unable to check latest release: {{error}}',
      online: 'Online',
      offline: 'Offline',
      activeSessions: 'Active Sessions',
      nodeDetails: 'Node Details',
      nodeCapabilities: 'Node Capabilities',
      nodeActions: 'Node Actions',
      nodeModels: 'Node Models',
      nodeAgents: 'Node Agents',
      nodesOnline: 'Nodes Online',
      recentCron: 'Recent Cron Jobs',
      nodesSnapshot: 'Nodes Snapshot',
      refreshAll: 'Refresh All',
      refresh: 'Refresh',
      dashboardNodeP2PDetail: '{{transport}} · {{sessions}} active · {{retries}} retries',
      dashboardNodeP2PTransport: 'Transport',
      dashboardNodeP2PIce: 'ICE Config',
      dashboardNodeP2PHealth: 'Health',
      dashboardNodeP2PSessions: 'Node P2P Sessions',
      dashboardNodeP2PSessionsEmpty: 'No node P2P sessions yet.',
      dashboardNodeP2PSessionCreated: 'Created',
      dashboardNodeP2PSessionRetries: 'Retries',
      dashboardNodeP2PSessionReady: 'Last Ready',
      dashboardNodeP2PSessionAttempt: 'Last Attempt',
      dashboardNodeP2PSessionError: 'Last Error',
      dashboardNodeDispatches: 'Recent Node Dispatches',
      dashboardNodeDispatchesHint: 'Actual dispatch path and fallback audit from recent node actions.',
      dashboardNodeDispatchesEmpty: 'No node dispatch records yet.',
      dashboardNodeDispatchTransport: 'Used Transport',
      dashboardNodeDispatchFallback: 'Fallback From',
      dashboardNodeDispatchDuration: 'Duration',
      dashboardNodeDispatchArtifacts: 'Artifacts',
      dashboardNodeDispatchArtifactPreview: 'Artifact Preview',
      dashboardNodeDispatchError: 'Error',
      configNodeP2P: 'Node P2P',
      configNodeP2PHint: 'Configure websocket tunnel or WebRTC transport for remote nodes.',
      configNodeDispatch: 'Node Dispatch Policy',
      configNodeDispatchHint: 'Bias node selection and bind actions or agents to tagged nodes.',
      configNodeDispatchPreferLocal: 'Prefer local node',
      configNodeDispatchPreferP2P: 'Prefer P2P transport',
      configNodeDispatchAllowRelay: 'Allow relay fallback',
      configNodeDispatchActionTags: 'Action tag rules',
      configNodeDispatchAgentTags: 'Agent tag rules',
      configNodeDispatchAllowActions: 'Node allow actions',
      configNodeDispatchDenyActions: 'Node deny actions',
      configNodeDispatchAllowAgents: 'Node allow agents',
      configNodeDispatchDenyAgents: 'Node deny agents',
      configNodeDispatchActionTagsPlaceholder: 'screen_snapshot=vision\ncamera_snap=vision,gpu',
      configNodeDispatchAgentTagsPlaceholder: 'coder=build\nvision=vision,gpu',
      configNodeDispatchAllowActionsPlaceholder: 'edge-a=camera_snap,screen_snapshot',
      configNodeDispatchDenyActionsPlaceholder: 'edge-b=screen_record',
      configNodeDispatchAllowAgentsPlaceholder: 'edge-a=main,coder',
      configNodeDispatchDenyAgentsPlaceholder: 'edge-b=vision',
      configNodeArtifacts: 'Node Artifact Retention',
      configNodeArtifactsHint: 'Auto-prune old node artifacts so audit and media storage stay bounded.',
      configNodeArtifactsKeepLatest: 'Keep latest artifacts',
      configNodeArtifactsRetainDays: 'Retain days (0 to disable)',
      configNodeArtifactsPruneOnRead: 'Apply retention on list/export',
      configNodeP2PStunPlaceholder: 'Comma-separated STUN URLs',
      configNodeP2PIceServers: 'ICE Servers',
      configNodeP2PIceServersEmpty: 'No structured ICE servers configured.',
      configNodeP2PIceUrlsPlaceholder: 'Comma-separated ICE URLs',
      configNodeP2PIceUsername: 'ICE Username',
      configNodeP2PIceCredential: 'ICE Credential',
      active: 'Active',
      paused: 'Paused',
      noCronJobs: 'No cron jobs found',
      noNodes: 'No nodes available',
      allActions: 'All Actions',
      allTransports: 'All Transports',
      sessions: 'Sessions',
      mainChat: 'Main Chat',
      internalStream: 'Internal Stream',
      enable: 'Enable',
      disable: 'Disable',
      action: 'Action',
      maxRetries: 'Max Retries',
      retryBackoffMs: 'Retry Backoff (ms)',
      agentPromptContentPlaceholder: 'AGENT.md content...',
      ekgOverviewHint: 'Runtime health, provider pressure, and error signature distribution.',
      ekgActiveSources: 'active sources',
      ekgActiveChannels: 'active channels',
      ekgErrorsCount: 'errors',
      dashboardTopErrorSignature: 'Top error signature',
      dashboardWorkloadSnapshot: '24h workload pressure snapshot',
      dashboardRecentFailedTasks: 'recent failed tasks',
      subagentGroup: 'Subagent Group',
      allAgents: 'All Agents',
      agents: 'Agents',
      subagentDispatch: 'Subagent Dispatch',
      subagentDispatchHint: 'Operator-only panel. Dispatch a task directly to a subagent without going through the main chat loop.',
      dispatchToSubagent: 'Dispatch Task',
      subagentTaskPlaceholder: 'Describe the task to run on the selected subagent...',
      subagentLabelPlaceholder: 'Optional task label...',
      subagentTaskDispatched: 'Subagent task dispatched.',
      replyTo: 'Reply To',
      toAgent: 'To',
      selfRefresh: 'Self Refresh',
      internalEvent: 'Internal Event',
      noSubagentStream: 'No subagent internal stream yet.',
      subagentGroupReadonly: 'Subagent group is read-only.',
      startConversation: 'Start a conversation',
      typeMessage: 'Type a message...',
      configuration: 'Configuration',
      form: 'Form',
      rawJson: 'Raw JSON',
      reload: 'Reload',
      saveChanges: 'Save Changes',
      gatewaySettings: 'Gateway Settings',
      host: 'Host',
      port: 'Port',
      token: 'Token',
      agentDefaults: 'Agent Defaults',
      maxToolIterations: 'Max Tool Iterations',
      maxTokens: 'Max Tokens',
      providers: 'Providers',
      proxyTimeout: 'Proxy Timeout (sec)',
      system: 'System',
      enableShellTools: 'Enable Shell Tools',
      enableLogging: 'Enable Logging',
      pauseJob: 'Pause Job',
      startJob: 'Start Job',
      deleteJob: 'Delete Job',
      gatewayToken: 'Gateway Token',
      enterToken: 'Enter token...',
      addJob: 'Add Job',
      editJob: 'Edit Job',
      jobName: 'Job Name',
      kind: 'Kind',
      everyMs: 'Interval (ms)',
      cronExpression: 'Cron Expression',
      runAt: 'Run At',
      message: 'Message',
      deliver: 'Deliver',
      channel: 'Channel',
      to: 'To (Recipient)',
      cancel: 'Cancel',
      save: 'Save',
      create: 'Create',
      update: 'Update',
      delete: 'Delete',
      add: 'Add',
      install: 'Install',
      installed: 'Installed',
      notInstalled: 'Not Installed',
      status: 'Status',
      source: 'Source',
      duration: 'Duration',
      provider: 'Provider',
      model: 'Model',
      time: 'Time',
      level: 'Level',
      code: 'Code',
      template: 'Template',
      content: 'Content',
      id: 'ID',
      files: 'Files',
      close: 'Close',
      path: 'Path',
      before: 'Before',
      after: 'After',
      hide: 'Hide',
      show: 'Show',
      clear: 'Clear',
      pause: 'Pause',
      resume: 'Resume',
      live: 'Live',
      raw: 'Raw',
      pretty: 'Pretty',
      entries: 'entries',
      appName: 'ClawGo',
      webui: 'WebUI',
      node: 'Node',
      unknownIp: 'Unknown IP',
      memoryFiles: 'Memory Files',
      memoryFileNamePrompt: 'Memory file name',
      noFileSelected: 'No file selected',
      noDescription: 'No description provided.',
      empty: '(empty)',
      modal: 'Modal',
      dialogPleaseConfirm: 'Please confirm',
      dialogNotice: 'Notice',
      dialogInputTitle: 'Input Required',
      dialogInputPlaceholder: 'Enter a value...',
      dialogOk: 'OK',
      requestFailed: 'Request Failed',
      saved: 'Saved',
      saving: 'Saving...',
      creating: 'Creating...',
      deleting: 'Deleting...',
      memoryCreateTitle: 'Create Memory File',
      memoryFileSaved: 'Memory file saved.',
      cronSaved: 'Cron job saved.',
      reloadHistory: 'Reload History',
      user: 'User',
      exec: 'Exec',
      agent: 'Agent',
      toolOutput: 'tool output',
      chatServerError: 'Error: Failed to get response from server.',
      waitingForLogs: 'Waiting for logs...',
      systemLog: 'system.log',
      codeCaller: 'Code/Caller',
      recursiveAddValuePlaceholder: 'Type new value and add',
      recursiveSelectOption: 'Select option',
      logCodesSearchPlaceholder: 'Search code/text',
      logCodesNoCodes: 'No codes',
      skillsDeleteTitle: 'Delete Skill',
      skillsDeleteMessage: 'Are you sure you want to delete this skill?',
      skillsClawhubMissingTitle: 'clawhub not detected',
      skillsClawhubMissingMessage: 'clawhub is not installed. Install dependencies and clawhub automatically?',
      skillsInstallPanelHint: 'Click "Install now" to bootstrap the skill environment. If Node.js/npm is missing, ClawGo will install it first, then install clawhub.',
      skillsInstallNow: 'Install now',
      skillsInstallingDeps: 'Installing node/npm and clawhub...',
      skillsInstallFailedTitle: 'Install failed',
      skillsInstallFailedMessage: 'Failed to install clawhub',
      skillsInstallDoneTitle: 'Install complete',
      skillsInstallDoneMessage: 'clawhub is installed. You can continue installing skills.',
      skillsInstallingSkill: 'Installing skill...',
      skillsInstallSkillDoneTitle: 'Skill installed',
      skillsInstallSkillDoneMessage: 'Skill "{{name}}" installed successfully.',
      skillsAddTitle: 'Add Skill',
      skillsAddMessage: 'Upload skill archive (.zip / .tar.gz / .tgz / .tar). It will be extracted into skills folder and archive will be removed.',
      skillsSelectArchive: 'Select archive',
      skillsImporting: 'Uploading and importing skill...',
      skillsImportFailedTitle: 'Import failed',
      skillsImportFailedMessage: 'Failed to import skill archive',
      skillsImportDoneTitle: 'Import complete',
      skillsImportedPrefix: 'Imported',
      skillsImportDoneMessage: 'Skill imported successfully.',
      skillsFileSaved: 'Skill file saved successfully.',
      skillsNamePlaceholder: 'skill name',
      skillsIgnoreSuspicious: 'Ignore suspicious warning (use --force)',
      skillsClawhubNotFound: 'clawhub not found',
      skillsClawhubStatus: 'clawhub',
      skillsAdd: 'Add Skill',
      skillsNoTools: 'No tools defined',
      skillsFileEdit: 'File Edit',
      configDiffPreview: 'Diff Preview',
      configBasicMode: 'Basic Mode',
      configAdvancedMode: 'Advanced Mode',
      configSaved: 'Config saved successfully.',
      configRiskyChangeConfirmTitle: 'Confirm Risky Config Change',
      configRiskyChangeConfirmMessage: 'These sensitive fields changed: {{fields}}. Save anyway?',
      configHotOnly: 'Hot-reload fields only',
      configSearchPlaceholder: 'Search group...',
      configHotFieldsFull: 'Hot-reload fields (full)',
      configTopLevel: 'Top Level',
      configProxies: 'Proxies',
      configNewProviderName: 'new provider name',
      configNoCustomProviders: 'No custom providers yet.',
      configMCPServers: 'MCP Servers',
      configNewMCPServerName: 'new MCP server name',
      configNoMCPServers: 'No MCP servers configured yet.',
      configMCPInstallTitle: 'Install MCP Server Package',
      configMCPInstallMessage: 'Install an npm package for MCP server "{{name}}"?',
      configMCPInstallPlaceholder: '@scope/package',
      configMCPInstalling: 'Installing MCP package...',
      configMCPInstallFailedTitle: 'MCP install failed',
      configMCPInstallFailedMessage: 'Failed to install MCP package',
      configMCPInstallDoneTitle: 'MCP package installed',
      configMCPInstallDoneMessage: 'Installed {{package}} and resolved binary {{bin}}.',
      configMCPInstallDoneFallback: 'MCP package installed.',
      configMCPArgsEnterHint: 'Type one argument and press Enter',
      configMCPCommandMissing: 'MCP command is unavailable.',
      configMCPInstallSuggested: 'Suggested package: {{pkg}}',
      configDeleteMCPServerConfirmTitle: 'Delete MCP Server',
      configDeleteMCPServerConfirmMessage: 'Delete MCP server "{{name}}" from current config?',
      configNoGroups: 'No config groups found.',
      configDiffPreviewCount: 'Diff Preview ({{count}} items)',
      saveConfigFailed: 'Failed to save config',
      sourceDirect: 'direct',
      sourceMemoryTodo: 'memory_todo',
      statusRunning: 'running',
      statusWaiting: 'waiting',
      idle: 'idle',
      statusBlocked: 'blocked',
      statusSuccess: 'success',
      statusError: 'error',
      statusSuppressed: 'suppressed',
      taskId: 'Task ID',
      inputPreview: 'Input Preview',
      blockReason: 'Block Reason',
      actionFailed: 'Action failed',
      cronDeleteConfirmTitle: 'Delete Cron Job',
      cronDeleteConfirmMessage: 'This will permanently delete the cron job. Continue?',
      cronDisableConfirmTitle: 'Pause Cron Job',
      cronDisableConfirmMessage: 'Pause this cron job now?',
      memoryDeleteConfirmTitle: 'Delete Memory File',
      memoryDeleteConfirmMessage: 'Delete memory file "{{path}}" permanently?',
      taskDeleteConfirmTitle: 'Delete Task',
      taskDeleteConfirmMessage: 'Delete task "{{id}}" permanently?',
      logsClearConfirmTitle: 'Clear Logs',
      logsClearConfirmMessage: 'Clear current log list from this page?',
      configDeleteProviderConfirmTitle: 'Delete Provider',
      configDeleteProviderConfirmMessage: 'Delete provider "{{name}}" from current config?',
      cronExpressionPlaceholder: '*/5 * * * *',
      recipientId: 'recipient id',
      languageZh: '中文',
      languageEn: 'English',
      themeLight: 'Day',
      themeDark: 'Night',
      expand: 'Expand',
      collapse: 'Collapse',
      configRoot: '(root)',
      configCommaSeparatedHint: ', a, b',
      configLabels: {
        gateway: 'Gateway',
        host: 'Host',
        port: 'Port',
        token: 'Token',
        agents: 'Agents',
        defaults: 'Defaults',
        max_tool_iterations: 'Max Tool Iterations',
        max_tokens: 'Max Tokens',
        providers: 'Providers',
        proxy: 'Proxy',
        timeout_sec: 'Timeout (Seconds)',
        shell: 'Shell',
        enabled: 'Enabled',
        logging: 'Logging',
        level: 'Log Level',
        format: 'Log Format',
        storage: 'Storage',
        path: 'Path',
        database: 'Database',
        type: 'Type',
        connection: 'Connection',
        security: 'Security',
        cors: 'CORS',
        allowed_origins: 'Allowed Origins',
        rate_limit: 'Rate Limit',
        requests_per_minute: 'Requests Per Minute',
        enabled_true: 'Enabled',
        enabled_false: 'Disabled',
        openai: 'OpenAI',
        gemini: 'Gemini',
        anthropic: 'Anthropic',
        api_key: 'API Key',
        model: 'Model',
        temperature: 'Temperature',
        top_p: 'Top P',
        top_k: 'Top K',
        presence_penalty: 'Presence Penalty',
        frequency_penalty: 'Frequency Penalty',
        stream: 'Stream',
        user: 'User',
        system_instruction: 'System Instruction',
        max_output_tokens: 'Max Output Tokens',
        response_mime_type: 'Response MIME Type',
        thinking_config: 'Thinking Config',
        thinking_level: 'Thinking Level',
        google_search: 'Google Search',
        google_maps: 'Google Maps',
        url_context: 'URL Context',
        api_base: 'API Base',
        protocol: 'Protocol',
        models: 'Models',
        command: 'Command',
        responses: 'Responses',
        streaming: 'Streaming',
        web_search_enabled: 'Web Search Enabled',
        web_search_context_size: 'Web Search Context Size',
        file_search_vector_store_ids: 'File Search Vector Store IDs',
        file_search_max_num_results: 'File Search Max Results',
        include: 'Include',
        stream_include_usage: 'Stream Include Usage',
        organization: 'Organization',
        project: 'Project',
        region: 'Region',
        deployment_name: 'Deployment Name',
        version: 'Version',
        name: 'Name',
        description: 'Description',
        package: 'Package',
        system_prompt: 'System Prompt',
        tools: 'Tools',
        auth: 'Authentication',
        jwt: 'JWT',
        secret: 'Secret',
        issuer: 'Issuer',
        audience: 'Audience',
        expires_in: 'Expires In',
        refresh_token: 'Refresh Token',
        access_token: 'Access Token',
        client_id: 'Client ID',
        client_secret: 'Client Secret',
        redirect_uri: 'Redirect URI',
        scope: 'Scope',
        state: 'State',
        retry: 'Retry',
        backoff: 'Backoff',
        factor: 'Factor',
        min_delay: 'Min Delay',
        max_delay: 'Max Delay',
        jitter: 'Jitter',
        channels: 'Channels',
        cron: 'Cron',
        workspace: 'Workspace',
        proxy_fallbacks: 'Proxy Fallbacks',
        heartbeat: 'Heartbeat',
        every_sec: 'Interval (Seconds)',
        ack_max_chars: 'Ack Max Chars',
        prompt_template: 'Prompt Template',
        context_compaction: 'Context Compaction',
        mode: 'Mode',
        trigger_messages: 'Trigger Messages',
        keep_recent_messages: 'Keep Recent Messages',
        max_summary_chars: 'Max Summary Chars',
        max_transcript_chars: 'Max Transcript Chars',
        execution: 'Execution',
        summary_policy: 'Summary Policy',
        policy: 'Policy',
        intent_max_input_chars: 'Intent Max Input Chars',
        max_rounds_without_user: 'Max Rounds Without User',
        run_state_ttl_seconds: 'Run State TTL (Seconds)',
        run_state_max: 'Run State Max',
        tool_parallel_safe_names: 'Tool Parallel Safe Names',
        tool_max_parallel_calls: 'Tool Max Parallel Calls',
        marker: 'Summary Marker',
        completed_prefix: 'Completed Prefix',
        changes_prefix: 'Changes Prefix',
        outcome_prefix: 'Outcome Prefix',
        completed_title: 'Completed Title',
        changes_title: 'Changes Title',
        outcomes_title: 'Outcomes Title',
        inbound_message_id_dedupe_ttl_seconds: 'Inbound Message Dedupe TTL (Seconds)',
        inbound_content_dedupe_window_seconds: 'Inbound Content Dedupe Window (Seconds)',
        outbound_dedupe_window_seconds: 'Outbound Dedupe Window (Seconds)',
        telegram: 'Telegram',
        allow_from: 'Allowed Senders',
        allow_chats: 'Allowed Chats',
        enable_groups: 'Enable Groups',
        require_mention_in_groups: 'Require Mention In Groups',
        discord: 'Discord',
        maixcam: 'MaixCam',
        whatsapp: 'WhatsApp',
        qq: 'QQ',
        bridge_url: 'Bridge URL',
        feishu: 'Feishu',
        app_id: 'App ID',
        app_secret: 'App Secret',
        encrypt_key: 'Encrypt Key',
        verification_token: 'Verification Token',
        dingtalk: 'DingTalk',
        filesystem: 'Filesystem',
        working_dir: 'Working Directory',
        url: 'URL',
        timeout: 'Timeout',
        auto_install_missing: 'Auto-install Missing',
        sandbox: 'Sandbox',
        image: 'Image',
        web: 'Web',
        mcp: 'MCP',
        search: 'Search',
        max_results: 'Max Results',
        request_timeout_sec: 'Request Timeout (Seconds)',
        servers: 'Servers',
        transport: 'Transport',
        args: 'Arguments',
        env: 'Environment',
        proxies: 'Proxies',
        cross_session_call_id: 'Cross-session Call ID',
        supports_responses_compact: 'Supports Responses Compact',
        dispatch: 'Dispatch',
        prefer_local: 'Prefer Local',
        prefer_p2p: 'Prefer P2P',
        allow_relay_fallback: 'Allow Relay Fallback',
        action_tags: 'Action Tags',
        agent_tags: 'Agent Tags',
        min_sleep_sec: 'Min Sleep (Seconds)',
        max_sleep_sec: 'Max Sleep (Seconds)',
        retry_backoff_base_sec: 'Retry Backoff Base (Seconds)',
        retry_backoff_max_sec: 'Retry Backoff Max (Seconds)',
        max_consecutive_failure_retries: 'Max Consecutive Failure Retries',
        max_workers: 'Max Workers',
        dir: 'Directory',
        filename: 'Filename',
        max_size_mb: 'Max Size (MB)',
        retention_days: 'Retention Days'
      }
    }
  },
  zh: {
    translation: {
      dashboard: '仪表盘',
      chat: '对话',
      config: '配置',
      whatsappBridge: 'WhatsApp',
      channelsGroup: '通道',
      whatsappBridgeHint: '查看 WhatsApp bridge 状态、二维码登录，以及当前已关联的 companion 会话。',
      telegramChannelHint: '配置 Telegram 内置通道的 token、允许发送者和群组行为。',
      discordChannelHint: '配置 Discord 通道的 bot token 和允许发送者。',
      feishuChannelHint: '配置飞书通道的应用凭证和群组策略。',
      qqChannelHint: '配置 QQ 通道的机器人凭证。',
      dingtalkChannelHint: '配置钉钉通道的应用凭证。',
      maixcamChannelHint: '配置 MaixCam 通道的 host、port 和允许发送者。',
      whatsappBridgeRunning: 'Bridge 运行中',
      whatsappBridgeStopped: 'Bridge 未运行',
      whatsappBridgeURL: 'Bridge 地址',
      whatsappBridgeAccount: '关联账号',
      whatsappBridgeLastEvent: '最近事件',
      whatsappBridgeQRCode: '二维码登录',
      whatsappQRCodeReady: '请用 WhatsApp 扫码',
      whatsappQRCodeUnavailable: '当前没有二维码',
      whatsappQRCodeHint: '如果已经关联成功，就不会显示二维码。\n如果 bridge 还没启动，请先执行 `clawgo channel whatsapp bridge run`。',
      whatsappStateAwaitingScan: '等待扫码',
      whatsappStateDisconnected: '已断开',
      whatsappBridgeDevHintTitle: '使用方式',
      whatsappBridgeDevHint: '1. 先执行 `clawgo channel whatsapp bridge run` 启动 bridge。\n2. 在这里用 WhatsApp 扫描二维码。\n3. 再保持 `make dev` 运行，让 ClawGo 接收 WhatsApp 消息。',
      whatsappFieldEnabledHint: '总开关，控制是否通过 bridge 接收 WhatsApp 消息。',
      whatsappFieldBridgeURLHint: '本地 WhatsApp companion bridge 服务的 WebSocket 地址。',
      whatsappFieldAllowFromHint: '每行一个发送者 JID，只有这些发送者可以触发 ClawGo。',
      whatsappFieldEnableGroupsHint: '允许来自 WhatsApp 群组的消息进入该通道。',
      whatsappFieldRequireMentionHint: '开启后，群消息必须显式 @ 提及机器人才会被处理。',
      whatsappFieldAllowFromFootnote: '支持每行一个 JID，也支持逗号分隔后自动拆分。',
      whatsappLogoutTitle: '退出 WhatsApp 会话',
      whatsappLogoutMessage: '是否解除当前 WhatsApp companion 会话，并重新申请新的二维码？',
      mcpServices: 'MCP',
      mcpServicesHint: '管理 MCP 服务并安装服务包。',
      cronJobs: '定时任务',
      nodes: '节点',
      nodeArtifacts: '节点工件',
      nodeArtifactsHint: '查看、下载和删除节点调度返回的文件或媒体工件。',
      nodeArtifactsEmpty: '当前没有节点工件。',
      nodeArtifactsPrune: '清理',
      nodeArtifactsKeepLatest: '保留最近 N 条',
      nodeArtifactsRetention: '工件保留统计',
      nodeArtifactsRetentionHint: '显示最近一次节点工件自动清理的结果。',
      nodeArtifactsRetentionKeepLatest: '保留最近数量',
      nodeArtifactsRetentionRetainDays: '保留天数',
      nodeArtifactsRetentionPruned: '本次清理数量',
      nodeArtifactsRetentionRemaining: '剩余数量',
      nodeArtifactDetail: '工件详情',
      nodeArtifactPreviewUnavailable: '该工件暂不支持预览。',
      allNodes: '全部节点',
      allKinds: '全部类型',
      size: '大小',
      nodesDetailHint: '查看节点能力、远端镜像 agent、最近调度记录以及返回的工件。',
      nodesFilterPlaceholder: '按节点 ID、名称或标签筛选',
      agentTree: '代理树',
      noAgentTree: '当前没有可用的代理树。',
      readonlyMirror: '只读镜像',
      localControl: '本地控制',
      logs: '实时日志',
      logCodes: '日志编号',
      skills: '技能管理',
      memory: '记忆文件',
      taskAudit: '任务审计',
      tasks: '任务管理',
      subagentProfiles: '子代理档案',
      subagentsRuntime: 'Agents',
      nodeP2P: '节点 P2P',
      nodeAlerts: '节点告警',
      nodeAlertsEmpty: '当前没有活跃节点告警。',
      nodeTags: '节点标签',
      nodeDispatchDetail: '调度详情',
      replayDispatch: '重放调度',
      replaying: '重放中...',
      resetReplayDraft: '重置草稿',
      nodeReplayRequest: '重放请求',
      nodeReplayResult: '重放结果',
      nodeReplayInvalidArgs: '重放参数必须是合法 JSON。',
      agentTopology: 'Agent 拓扑',
      agentTopologyHint: '统一展示本地 agent、注册 node 以及远端镜像 agent 分支的关系图。',
      runningTasks: '运行中',
      clearFocus: '清除聚焦',
      zoomIn: '放大',
      zoomOut: '缩小',
      fitView: '适应视图',
      childrenCount: '子节点',
      'topologyFilter.all': '全部',
      'topologyFilter.running': '运行中',
      'topologyFilter.failed': '失败',
      'topologyFilter.local': '本地',
      'topologyFilter.remote': '远端',
      noLiveTasks: '当前没有活动任务',
      remoteTasksUnavailable: '远端任务细节暂未镜像回来。',
      subagentDetail: '子代理详情',
      spawnSubagent: '创建子代理任务',
      dispatchAndWait: '派发并等待',
      dispatchReply: '派发回复',
      mergedResult: '汇总结果',
      configSubagentDraft: '配置子代理',
      agentRegistry: '代理注册表',
      loadDraft: '载入配置',
      enableAgent: '启用代理',
      disableAgent: '停用代理',
      deleteAgent: '删除代理',
      deleteAgentConfirm: '确认从 config.json 中永久删除代理 "{{id}}" 吗？',
      noRegistryAgents: '当前没有已配置代理。',
      saveToConfig: '写入配置',
      configSubagentSaved: '子代理配置已写入并刷新运行态。',
      promptFileEditor: '提示词文件编辑器',
      promptFileEditorPlaceholder: '编辑该子代理对应的 AGENT.md 内容。',
      bootstrapPromptFile: '生成 AGENT.md 模板',
      savePromptFile: '保存 AGENT.md',
      promptFileSaved: '提示词文件已保存。',
      promptFileBootstrapped: '提示词模板已创建。',
      promptFileReady: 'AGENT.md 已就绪',
      promptFileMissing: 'AGENT.md 缺失',
      threadTrace: '线程追踪',
      threadMessages: '线程消息',
      inbox: '收件箱',
      reply: '回复',
      ack: '确认',
      steerMessage: '引导消息',
      newProfile: '新建档案',
      spawn: '创建',
      kill: '终止',
      send: '发送',
      dispatch: '派发',
      toolAllowlist: '工具白名单',
      memoryNamespace: '记忆命名空间',
      subagentDeleteConfirmTitle: '删除子代理档案',
      subagentDeleteConfirmMessage: '确认永久删除子代理档案 "{{id}}"？',
      sidebarCore: '核心',
      sidebarMain: '主入口',
      sidebarAgents: 'Agents',
      sidebarRuntime: '运行态',
      sidebarConfig: '配置',
      sidebarKnowledge: '知识与调试',
      sidebarSystem: '系统',
      sidebarOps: '运维',
      sidebarInsights: '洞察',
      ekg: 'EKG',
      ekgEscalations: '升级拦截次数',
      ekgSourceStats: '来源统计',
      ekgChannelStats: '通道统计',
      ekgTopProvidersWorkload: 'Top Providers（业务负载）',
      ekgTopProvidersAll: 'Top Providers（全量）',
      ekgTopErrsigWorkload: 'Top 错误签名（业务负载）',
      ekgTopErrsigHeartbeat: 'Top 错误签名（心跳）',
      ekgTopErrsigAll: 'Top 错误签名（全量）',
      taskList: '任务列表',
      taskDetail: '任务详情',
      taskQueue: '任务队列',
      taskLogs: '任务日志',
      mediaSources: '媒体来源',
      lastPauseReason: '最近暂停原因',
      lastPauseAt: '最近暂停时间',
      allSources: '全部来源',
      allStatus: '全部状态',
      export: '导出',
      error: '错误',
      noTaskAudit: '暂无任务审计记录',
      selectTask: '请从左侧选择任务',
      loading: '加载中...',
      gatewayStatus: '网关状态',
      githubRepo: 'GitHub 仓库',
      checkVersion: '检查最新版本',
      versionCheckUpToDateTitle: '已经是最新版本',
      versionCheckUpToDateMessage: '当前 gateway 和 WebUI 已经是 {{version}}。',
      versionCheckUpdateTitle: '发现新版本',
      versionCheckUpdateMessage: '最新版本：{{latest}}\nGateway：{{gateway}}\nWebUI：{{webui}}',
      versionCheckFailedTitle: '版本检查失败',
      versionCheckFailedMessage: '无法检查最新版本：{{error}}',
      online: '在线',
      offline: '离线',
      activeSessions: '活跃会话',
      nodeDetails: '节点详情',
      nodeCapabilities: '节点能力',
      nodeActions: '节点动作',
      nodeModels: '节点模型',
      nodeAgents: '节点 Agents',
      nodesOnline: '在线节点',
      recentCron: '最近定时任务',
      nodesSnapshot: '节点快照',
      refreshAll: '刷新全部',
      refresh: '刷新',
      dashboardNodeP2PDetail: '{{transport}} · {{sessions}} 个活跃会话 · {{retries}} 次重试',
      dashboardNodeP2PTransport: '传输方式',
      dashboardNodeP2PIce: 'ICE 配置',
      dashboardNodeP2PHealth: '健康状态',
      dashboardNodeP2PSessions: '节点 P2P 会话',
      dashboardNodeP2PSessionsEmpty: '当前还没有节点 P2P 会话。',
      dashboardNodeP2PSessionCreated: '创建时间',
      dashboardNodeP2PSessionRetries: '重试次数',
      dashboardNodeP2PSessionReady: '最近就绪',
      dashboardNodeP2PSessionAttempt: '最近尝试',
      dashboardNodeP2PSessionError: '最近错误',
      dashboardNodeDispatches: '最近节点调度',
      dashboardNodeDispatchesHint: '展示最近节点动作实际走过的传输路径和回退记录。',
      dashboardNodeDispatchesEmpty: '当前还没有节点调度记录。',
      dashboardNodeDispatchTransport: '实际传输',
      dashboardNodeDispatchFallback: '回退来源',
      dashboardNodeDispatchDuration: '耗时',
      dashboardNodeDispatchArtifacts: '工件',
      dashboardNodeDispatchArtifactPreview: '工件预览',
      dashboardNodeDispatchError: '错误',
      configNodeP2P: '节点 P2P',
      configNodeP2PHint: '为远端节点配置 websocket tunnel 或 WebRTC 传输。',
      configNodeDispatch: '节点调度策略',
      configNodeDispatchHint: '控制节点选择偏好，并把动作或 agent 绑定到带标签的节点。',
      configNodeDispatchPreferLocal: '优先本地节点',
      configNodeDispatchPreferP2P: '优先 P2P 传输',
      configNodeDispatchAllowRelay: '允许 relay 回退',
      configNodeDispatchActionTags: '动作标签规则',
      configNodeDispatchAgentTags: 'Agent 标签规则',
      configNodeDispatchAllowActions: '节点允许动作',
      configNodeDispatchDenyActions: '节点禁止动作',
      configNodeDispatchAllowAgents: '节点允许 Agents',
      configNodeDispatchDenyAgents: '节点禁止 Agents',
      configNodeDispatchActionTagsPlaceholder: 'screen_snapshot=vision\ncamera_snap=vision,gpu',
      configNodeDispatchAgentTagsPlaceholder: 'coder=build\nvision=vision,gpu',
      configNodeDispatchAllowActionsPlaceholder: 'edge-a=camera_snap,screen_snapshot',
      configNodeDispatchDenyActionsPlaceholder: 'edge-b=screen_record',
      configNodeDispatchAllowAgentsPlaceholder: 'edge-a=main,coder',
      configNodeDispatchDenyAgentsPlaceholder: 'edge-b=vision',
      configNodeArtifacts: '节点工件保留策略',
      configNodeArtifactsHint: '自动清理旧节点工件，避免审计和媒体存储无限增长。',
      configNodeArtifactsKeepLatest: '保留最近工件数',
      configNodeArtifactsRetainDays: '保留天数（0 表示关闭）',
      configNodeArtifactsPruneOnRead: '在列表/导出时执行保留策略',
      configNodeP2PStunPlaceholder: '逗号分隔的 STUN URL',
      configNodeP2PIceServers: 'ICE 服务器',
      configNodeP2PIceServersEmpty: '当前没有结构化 ICE 服务器配置。',
      configNodeP2PIceUrlsPlaceholder: '逗号分隔的 ICE URL',
      configNodeP2PIceUsername: 'ICE 用户名',
      configNodeP2PIceCredential: 'ICE 凭证',
      active: '活跃',
      paused: '已暂停',
      noCronJobs: '未找到定时任务',
      noNodes: '无可用节点',
      allActions: '全部动作',
      allTransports: '全部传输',
      sessions: '会话',
      mainChat: '主对话',
      internalStream: '内部流',
      enable: '启用',
      disable: '停用',
      action: '动作',
      maxRetries: '最大重试次数',
      retryBackoffMs: '重试退避（毫秒）',
      agentPromptContentPlaceholder: 'AGENT.md 内容...',
      ekgOverviewHint: '运行时健康、Provider 压力与错误签名分布。',
      ekgActiveSources: '活跃来源',
      ekgActiveChannels: '活跃通道',
      ekgErrorsCount: '错误数',
      dashboardTopErrorSignature: 'Top 错误签名',
      dashboardWorkloadSnapshot: '24 小时业务负载快照',
      dashboardRecentFailedTasks: '最近失败任务',
      subagentGroup: '子代理群组',
      allAgents: '全部代理',
      agents: '代理',
      subagentDispatch: '子代理派发',
      subagentDispatchHint: '仅用于运维/调试。可直接向子代理发任务，不经过主对话链路。',
      dispatchToSubagent: '发起任务',
      subagentTaskPlaceholder: '描述要发给当前子代理的任务...',
      subagentLabelPlaceholder: '可选任务标签...',
      subagentTaskDispatched: '子代理任务已发起。',
      replyTo: '回复给',
      toAgent: '发送给',
      selfRefresh: '自我刷新',
      internalEvent: '内部事件',
      noSubagentStream: '当前还没有子代理内部流。',
      subagentGroupReadonly: '子代理群组为只读视图。',
      startConversation: '开始对话',
      typeMessage: '输入消息...',
      configuration: '配置',
      form: '表单',
      rawJson: '原始 JSON',
      reload: '重新加载',
      saveChanges: '保存更改',
      gatewaySettings: '网关设置',
      host: '主机',
      port: '端口',
      token: '令牌',
      agentDefaults: '代理默认值',
      maxToolIterations: '最大工具迭代次数',
      maxTokens: '最大 Token 数',
      providers: '提供商',
      proxyTimeout: '代理超时 (秒)',
      system: '系统',
      enableShellTools: '启用 Shell 工具',
      enableLogging: '启用日志',
      pauseJob: '暂停任务',
      startJob: '启动任务',
      deleteJob: '删除任务',
      gatewayToken: '网关令牌',
      enterToken: '输入令牌...',
      addJob: '新增任务',
      editJob: '编辑任务',
      jobName: '任务名称',
      kind: '类型',
      everyMs: '间隔 (毫秒)',
      cronExpression: 'Cron 表达式',
      runAt: '执行时间',
      message: '消息',
      deliver: '投递',
      channel: '频道',
      to: '接收者',
      cancel: '取消',
      save: '保存',
      create: '创建',
      update: '更新',
      delete: '删除',
      add: '添加',
      install: '安装',
      installed: '已安装',
      notInstalled: '未安装',
      status: '状态',
      source: '来源',
      duration: '耗时',
      provider: '提供商',
      model: '模型',
      time: '时间',
      level: '级别',
      code: '代码',
      template: '模板',
      content: '内容',
      id: 'ID',
      files: '文件',
      close: '关闭',
      path: '路径',
      before: '变更前',
      after: '变更后',
      hide: '隐藏',
      show: '显示',
      clear: '清空',
      pause: '暂停',
      resume: '继续',
      live: '实时',
      raw: '原始',
      pretty: '格式化',
      entries: '条',
      appName: 'ClawGo',
      webui: 'WebUI',
      node: '节点',
      unknownIp: '未知 IP',
      memoryFiles: '记忆文件',
      memoryFileNamePrompt: '记忆文件名',
      noFileSelected: '未选择文件',
      noDescription: '暂无描述。',
      empty: '(空)',
      modal: '弹窗',
      dialogPleaseConfirm: '请确认',
      dialogNotice: '提示',
      dialogInputTitle: '请输入',
      dialogInputPlaceholder: '请输入内容...',
      dialogOk: '确定',
      requestFailed: '请求失败',
      saved: '已保存',
      saving: '保存中...',
      creating: '创建中...',
      deleting: '删除中...',
      memoryCreateTitle: '创建记忆文件',
      memoryFileSaved: '记忆文件已保存。',
      cronSaved: '定时任务已保存。',
      reloadHistory: '重新加载历史',
      user: '用户',
      exec: '执行',
      agent: '助手',
      toolOutput: '工具输出',
      chatServerError: '错误：获取服务端响应失败。',
      waitingForLogs: '等待日志中...',
      systemLog: '系统日志',
      codeCaller: '代码/来源',
      recursiveAddValuePlaceholder: '输入新值后添加',
      recursiveSelectOption: '下拉选择',
      logCodesSearchPlaceholder: '搜索代码/文本',
      logCodesNoCodes: '暂无代码',
      skillsDeleteTitle: '删除技能',
      skillsDeleteMessage: '确认删除这个技能吗？',
      skillsClawhubMissingTitle: '未检测到 clawhub',
      skillsClawhubMissingMessage: '检测到系统中未安装 clawhub。是否自动安装依赖环境并安装 clawhub？',
      skillsInstallPanelHint: '点击“立即安装”即可初始化技能环境。如果系统缺少 Node.js/npm，ClawGo 会先安装它们，再安装 clawhub。',
      skillsInstallNow: '立即安装',
      skillsInstallingDeps: '正在安装 node/npm 与 clawhub...',
      skillsInstallFailedTitle: '安装失败',
      skillsInstallFailedMessage: '安装 clawhub 失败',
      skillsInstallDoneTitle: '安装完成',
      skillsInstallDoneMessage: 'clawhub 已安装，可继续安装技能。',
      skillsInstallingSkill: '正在安装技能...',
      skillsInstallSkillDoneTitle: '技能安装完成',
      skillsInstallSkillDoneMessage: '技能 "{{name}}" 安装成功。',
      skillsAddTitle: '添加技能',
      skillsAddMessage: '请上传技能压缩包（.zip / .tar.gz / .tgz / .tar）。上传后将自动解压到 skills 目录，并删除上传压缩包。',
      skillsSelectArchive: '选择压缩包',
      skillsImporting: '正在上传并导入技能...',
      skillsImportFailedTitle: '导入失败',
      skillsImportFailedMessage: '技能压缩包导入失败',
      skillsImportDoneTitle: '导入完成',
      skillsImportedPrefix: '已导入',
      skillsImportDoneMessage: '技能导入成功。',
      skillsFileSaved: '技能文件保存成功。',
      skillsNamePlaceholder: '技能名',
      skillsIgnoreSuspicious: '忽略可疑告警（使用 --force）',
      skillsClawhubNotFound: '未找到 clawhub',
      skillsClawhubStatus: 'clawhub',
      skillsAdd: '添加技能',
      skillsNoTools: '未定义工具',
      skillsFileEdit: '文件编辑',
      configDiffPreview: '差异预览',
      configBasicMode: '基础模式',
      configAdvancedMode: '高级模式',
      configSaved: '配置已保存。',
      configRiskyChangeConfirmTitle: '确认高风险配置变更',
      configRiskyChangeConfirmMessage: '以下敏感字段已变更：{{fields}}。仍要保存吗？',
      configHotOnly: '仅热更新字段',
      configSearchPlaceholder: '搜索分类...',
      configHotFieldsFull: '热更新字段（完整）',
      configTopLevel: '顶层分类',
      configProxies: '代理配置',
      configNewProviderName: '新 provider 名称',
      configNoCustomProviders: '暂无自定义 provider。',
      configMCPServers: 'MCP 服务',
      configNewMCPServerName: '新的 MCP 服务名',
      configNoMCPServers: '暂无 MCP 服务配置。',
      configMCPInstallTitle: '安装 MCP 服务包',
      configMCPInstallMessage: '是否为 MCP 服务 “{{name}}” 安装 npm 包？',
      configMCPInstallPlaceholder: '@scope/package',
      configMCPInstalling: '正在安装 MCP 包...',
      configMCPInstallFailedTitle: 'MCP 安装失败',
      configMCPInstallFailedMessage: '安装 MCP 包失败',
      configMCPInstallDoneTitle: 'MCP 包安装完成',
      configMCPInstallDoneMessage: '已安装 {{package}}，并解析到可执行文件 {{bin}}。',
      configMCPInstallDoneFallback: 'MCP 包已安装。',
      configMCPArgsEnterHint: '输入一个参数后按回车添加',
      configMCPCommandMissing: 'MCP 命令不可用。',
      configMCPInstallSuggested: '建议安装包：{{pkg}}',
      configDeleteMCPServerConfirmTitle: '删除 MCP 服务',
      configDeleteMCPServerConfirmMessage: '确认从当前配置中删除 MCP 服务 “{{name}}”吗？',
      configNoGroups: '未找到配置分组。',
      configDiffPreviewCount: '配置差异预览（{{count}}项）',
      saveConfigFailed: '保存配置失败',
      sourceDirect: 'direct',
      sourceMemoryTodo: 'memory_todo',
      statusRunning: 'running',
      statusWaiting: 'waiting',
      idle: '空闲',
      statusBlocked: 'blocked',
      statusSuccess: 'success',
      statusError: 'error',
      statusSuppressed: 'suppressed',
      taskId: '任务 ID',
      inputPreview: '输入预览',
      blockReason: '阻断原因',
      actionFailed: '操作失败',
      cronDeleteConfirmTitle: '删除定时任务',
      cronDeleteConfirmMessage: '此操作会永久删除该定时任务，是否继续？',
      cronDisableConfirmTitle: '暂停定时任务',
      cronDisableConfirmMessage: '确认暂停该定时任务吗？',
      memoryDeleteConfirmTitle: '删除记忆文件',
      memoryDeleteConfirmMessage: '确认永久删除记忆文件“{{path}}”吗？',
      taskDeleteConfirmTitle: '删除任务',
      taskDeleteConfirmMessage: '确认永久删除任务“{{id}}”吗？',
      logsClearConfirmTitle: '清空日志',
      logsClearConfirmMessage: '确认清空当前页面中的日志列表吗？',
      configDeleteProviderConfirmTitle: '删除 Provider',
      configDeleteProviderConfirmMessage: '确认从当前配置中删除 provider “{{name}}”吗？',
      cronExpressionPlaceholder: '*/5 * * * *',
      recipientId: '接收者 ID',
      languageZh: '中文',
      languageEn: 'English',
      themeLight: '白天',
      themeDark: '黑夜',
      expand: '展开',
      collapse: '收起',
      configRoot: '（根）',
      configCommaSeparatedHint: '，例如 a,b',
      configLabels: {
        gateway: '网关',
        host: '主机',
        port: '端口',
        token: '令牌',
        agents: '代理',
        defaults: '默认值',
        max_tool_iterations: '最大工具迭代次数',
        max_tokens: '最大 Token 数',
        providers: '提供商',
        proxy: '代理',
        timeout_sec: '超时时间 (秒)',
        shell: 'Shell',
        enabled: '已启用',
        logging: '日志',
        level: '日志级别',
        format: '日志格式',
        storage: '存储',
        path: '路径',
        database: '数据库',
        type: '类型',
        connection: '连接',
        security: '安全',
        cors: '跨域资源共享 (CORS)',
        allowed_origins: '允许的来源',
        rate_limit: '速率限制',
        requests_per_minute: '每分钟请求数',
        enabled_true: '已启用',
        enabled_false: '已禁用',
        openai: 'OpenAI',
        gemini: 'Gemini',
        anthropic: 'Anthropic',
        api_key: 'API 密钥',
        model: '模型',
        temperature: '温度',
        top_p: 'Top P',
        top_k: 'Top K',
        presence_penalty: '存在惩罚',
        frequency_penalty: '频率惩罚',
        stream: '流式传输',
        user: '用户',
        system_instruction: '系统指令',
        max_output_tokens: '最大输出 Token',
        response_mime_type: '响应 MIME 类型',
        thinking_config: '思考配置',
        thinking_level: '思考级别',
        google_search: '谷歌搜索',
        google_maps: '谷歌地图',
        url_context: 'URL 上下文',
        api_base: 'API 基础地址',
        protocol: '协议',
        models: '模型列表',
        command: '命令',
        responses: 'Responses 配置',
        streaming: '流式输出',
        web_search_enabled: '启用网页搜索',
        web_search_context_size: '网页搜索上下文大小',
        file_search_vector_store_ids: '文件搜索向量库 ID 列表',
        file_search_max_num_results: '文件搜索最大结果数',
        include: '包含字段',
        stream_include_usage: '流式包含用量',
        organization: '组织',
        project: '项目',
        region: '区域',
        deployment_name: '部署名称',
        version: '版本',
        name: '名称',
        description: '描述',
        package: '包名',
        system_prompt: '系统提示词',
        tools: '工具',
        auth: '身份验证',
        jwt: 'JWT',
        secret: '密钥',
        issuer: '发行者',
        audience: '受众',
        expires_in: '过期时间',
        refresh_token: '刷新令牌',
        access_token: '访问令牌',
        client_id: '客户端 ID',
        client_secret: '客户端密钥',
        redirect_uri: '重定向 URI',
        scope: '范围',
        state: '状态',
        retry: '重试',
        backoff: '退避',
        factor: '因子',
        min_delay: '最小延迟',
        max_delay: '最大延迟',
        jitter: '抖动',
        channels: '通道',
        cron: '定时任务',
        workspace: '工作目录',
        proxy_fallbacks: '代理回退链',
        heartbeat: '心跳',
        every_sec: '间隔（秒）',
        ack_max_chars: '确认最大字符数',
        prompt_template: '提示模板',
        context_compaction: '上下文压缩',
        mode: '模式',
        trigger_messages: '触发消息数',
        keep_recent_messages: '保留最近消息数',
        max_summary_chars: '摘要最大字符数',
        max_transcript_chars: '转录最大字符数',
        execution: '执行控制',
        summary_policy: '摘要策略',
        policy: '策略',
        intent_max_input_chars: '意图输入最大字符数',
        max_rounds_without_user: '无用户最大轮数',
        run_state_ttl_seconds: '运行状态 TTL（秒）',
        run_state_max: '运行状态上限',
        tool_parallel_safe_names: '工具并行安全名单',
        tool_max_parallel_calls: '工具最大并行调用数',
        marker: '摘要标记',
        completed_prefix: '完成前缀',
        changes_prefix: '变更前缀',
        outcome_prefix: '结果前缀',
        completed_title: '完成标题',
        changes_title: '变更标题',
        outcomes_title: '结果标题',
        inbound_message_id_dedupe_ttl_seconds: '入站消息去重 TTL（秒）',
        inbound_content_dedupe_window_seconds: '入站内容去重窗口（秒）',
        outbound_dedupe_window_seconds: '出站去重窗口（秒）',
        telegram: 'Telegram',
        allow_from: '允许发送者',
        allow_chats: '允许会话',
        enable_groups: '启用群组',
        require_mention_in_groups: '群组需 @ 提及',
        discord: 'Discord',
        maixcam: 'MaixCam',
        whatsapp: 'WhatsApp',
        qq: 'QQ',
        bridge_url: '桥接地址',
        feishu: '飞书',
        app_id: '应用 ID',
        app_secret: '应用密钥',
        encrypt_key: '加密 Key',
        verification_token: '校验 Token',
        dingtalk: '钉钉',
        filesystem: '文件系统',
        working_dir: '工作目录',
        url: '地址',
        timeout: '超时',
        auto_install_missing: '自动安装缺失依赖',
        sandbox: '沙箱',
        image: '镜像',
        web: 'Web',
        mcp: 'MCP',
        search: '搜索',
        max_results: '最大结果数',
        request_timeout_sec: '请求超时（秒）',
        servers: '服务列表',
        transport: '传输方式',
        args: '参数',
        env: '环境变量',
        proxies: '代理集合',
        cross_session_call_id: '跨会话调用 ID',
        supports_responses_compact: '支持紧凑 responses',
        dispatch: '调度',
        prefer_local: '优先本地',
        prefer_p2p: '优先 P2P',
        allow_relay_fallback: '允许 Relay 回退',
        action_tags: '动作标签',
        agent_tags: 'Agent 标签',
        min_sleep_sec: '最小休眠（秒）',
        max_sleep_sec: '最大休眠（秒）',
        retry_backoff_base_sec: '重试退避基准（秒）',
        retry_backoff_max_sec: '重试退避上限（秒）',
        max_consecutive_failure_retries: '最大连续失败重试次数',
        max_workers: '最大 worker 数',
        dir: '目录',
        filename: '文件名',
        max_size_mb: '最大大小（MB）',
        retention_days: '保留天数'
      }
    }
  }
};

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources,
    fallbackLng: 'zh',
    interpolation: {
      escapeValue: false,
    },
  });

export default i18n;
