export default { // 로그인 login: { title: 'Hermes Web UI', description: '계속하려면 액세스 토큰을 입력하세요. 서버 시작 로그에서 확인할 수 있습니다.', placeholder: '액세스 토큰', submit: '로그인', tokenRequired: '액세스 토큰을 입력해 주세요', invalidToken: '유효하지 않은 토큰입니다', connectionFailed: '서버에 연결할 수 없습니다', passwordLogin: '비밀번호', tokenLogin: '토큰', usernamePlaceholder: '사용자 이름', passwordPlaceholder: '비밀번호', credentialsRequired: '사용자 이름과 비밀번호를 입력해 주세요', invalidCredentials: '사용자 이름 또는 비밀번호가 올바르지 않습니다', tooManyAttempts: '로그인 시도 횟수가 너무 많습니다. 잠시 후 다시 시도해 주세요', passwordMismatch: '비밀번호가 일치하지 않습니다', passwordTooShort: '비밀번호는 6자 이상이어야 합니다', setupSuccess: '비밀번호 로그인이 설정되었습니다', passwordChanged: '비밀번호가 변경되었습니다', passwordRemoved: '비밀번호 로그인이 제거되었습니다', setupPassword: '비밀번호 로그인 설정', changePassword: '비밀번호 변경', changeUsername: '사용자 이름 변경', removePasswordLogin: '제거', username: '사용자 이름', currentPassword: '현재 비밀번호', newPassword: '새 비밀번호', confirmPassword: '비밀번호 확인', newUsername: '새 사용자 이름', usernameChanged: '사용자 이름이 변경되었습니다', usernameTooShort: '사용자 이름은 2자 이상이어야 합니다', setupDescription: '사용자 이름과 비밀번호를 설정하여 편리하게 로그인하세요. 액세스 토큰은 백업으로 계속 사용할 수 있습니다.', removeConfirm: '비밀번호 로그인을 제거하시겠습니까? 액세스 토큰을 사용하여 로그인해야 합니다.', passwordLoginNotConfigured: '비밀번호 로그인 미설정', passwordLoginConfigured: '비밀번호 로그인 활성화됨 ({username})', }, // 공통 common: { loading: '로딩 중...', cancel: '취소', retry: '재시도', delete: '삭제', edit: '편집', save: '저장', saved: '저장됨', update: '업데이트', create: '생성', saveFailed: '저장 실패', deleteFailed: '삭제 실패', ok: '확인', copied: '복사됨', copy: '복사', noData: '데이터 없음', fetch: '가져오기', add: '추가', enable: '활성화', disable: '비활성화', configured: '구성됨', notConfigured: '미구성', confirm: '확인', expand: '펼치기', collapse: '접기', }, // 사이드바 sidebar: { chat: '채팅', search: '검색', apiRelay: 'API 릴레이', history: '기록', jobs: '예약 작업', models: '모델', profiles: '프로필', plugins: '플러그인', skills: '스킬', memory: '메모리', logs: '로그', usage: '사용량', skillsUsage: '스킬 사용량', channels: '채널', terminal: '터미널', files: '파일', groupChat: '그룹 채팅', groupConversation: '대화', settings: '설정', connected: '연결됨', disconnected: '연결 끊김', updateTip: '터미널에서 "hermes-web-ui update"를 실행하여 업데이트하세요', updateVersion: 'v{version}(으)로 업그레이드', reloadClientVersion: 'v{version}(으)로 새로고침', updating: '업데이트 중...', updateSuccess: '업데이트가 완료되었습니다. 잠시 후 페이지를 새로고침하세요. 오랫동안 시작되지 않으면 수동으로 시작하세요.', updateFailed: '업데이트 실패', logout: '로그아웃', nodeVersionWarning: 'Node.js v{version}이 감지되었습니다. 버전 23 이상으로 업그레이드하세요.', changelog: '변경 이력', noChangelog: '변경 이력이 없습니다', }, // 서랍 drawer: { terminal: '터미널', files: '작업 공간', }, // 채팅 chat: { contextRemaining: '남음', contextClickToEdit: '클릭하여 컨텍스트 길이 편집', contextEditTitle: '컨텍스트 길이 편집', contextEditDesc: '현재 모델의 컨텍스트 길이 제한 설정 (토큰 수)', contextEditPlaceholder: '컨텍스트 길이 입력', contextEditHint: '일반적인 값: 200k (Claude), 128k (GPT-4), 32k (GPT-3.5)', contextEditSave: '저장', contextEditCancel: '취소', contextEditInvalid: '유효한 컨텍스트 길이를 입력하세요', contextEditSuccess: '컨텍스트 길이가 업데이트되었습니다', contextEditFailed: '업데이트 실패', emptyState: 'Hermes Agent와 대화를 시작하세요', inputPlaceholder: '메시지를 입력하세요... (Enter로 전송, Shift+Enter로 줄바꿈)', slashCommandArgs: { message: '<메시지>', title: '<제목>', text: '<텍스트>', }, slashCommands: { usage: '현재 세션 사용량 계산', status: '세션 상태와 대기열 표시', abort: '활성 Bridge 실행 중지', queue: '활성 실행 뒤에 메시지 대기열 추가', clear: '현재 표시 내용 지우기', clearHistory: '이 세션의 저장된 메시지 기록 삭제', title: '이 세션 이름 변경', compress: '유휴 상태에서 컨텍스트 압축 실행', steer: '활성 Bridge 실행에 지시 텍스트 보내기', destroy: '이 세션의 Bridge Agent 해제', }, attachFiles: '파일 첨부', messageQueue: '메시지 대기열', removeQueuedMessage: '대기열 메시지 제거', stop: '중지', send: '전송', contextUsed: '사용된 컨텍스트:', sessions: '세션', webUiSessions: '세션', sessionScopeHint: '채팅에는 Web UI/API Server 세션만 표시됩니다. CLI, Telegram, Discord, Cron 등 채널 세션은 기록에서 읽기 전용으로 볼 수 있습니다.', openHistory: '기록 열기', hermesHistory: 'Hermes 기록', historyScopeHint: '소스별로 그룹화된 Hermes 기록 세션을 읽기 전용으로 봅니다.', noSessions: '세션 없음', newChat: '새 채팅', approvalKicker: '터미널 권한', approvalTitle: '실행 전에 명령 확인', approvalAllowOnce: '한 번만 허용', approvalAllowSession: '이 세션에서 허용', approvalAlways: '항상 허용', approvalDeny: '거부', deleteSession: '이 세션을 삭제하시겠습니까?', toggleBatchMode: '일괄 선택', selectAll: '모두 선택', confirmBatchDelete: '선택한 {count}개의 세션을 삭제하시겠습니까?', batchDeleteSuccess: '{count}개의 세션을 삭제했습니다', batchDeletePartial: '{failed}개의 세션 삭제 실패', batchDeleteFailed: '일괄 삭제 실패', sessionDeleted: '세션이 삭제되었습니다', rename: '이름 변경', pin: '고정', unpin: '고정 해제', pinned: '고정됨', chatMode: '채팅', liveMode: '라이브', liveSessions: '라이브 세션', recentBadge: '최근', linkedSessions: '{count}개 연결됨', noVisibleMessages: '사람이 볼 수 있는 메시지가 없습니다.', monitorRoleUser: '사용자', monitorRoleAssistant: '어시스턴트', copySessionId: '세션 ID 복사', export: '내보내기', exportFull: '전체 내보내기 (JSON)', exportCompressed: '압축 내보내기 (TXT)', exportCompressing: '컨텍스트 압축 중, 잠시 기다려주세요...', exportSuccess: '세션을 내보냈습니다', exportFailed: '내보내기 실패', renamed: '이름이 변경되었습니다', renameFailed: '이름 변경 실패', renameSession: '세션 이름 변경', sessionNotFound: '세션을 찾을 수 없습니다', enterNewTitle: '새 제목을 입력하세요', other: '기타', runFailed: '실행 실패', error: '오류', tool: '도구', arguments: '인수', result: '결과', truncated: '... (잘림)', executionDuration: 'Execution time', thinkingLabel: '사고 과정', thinkingInProgress: '사고 중…', thinkingShow: '사고 과정 펼치기', thinkingHide: '사고 과정 접기', thinkingDuration: '관측 {duration}', thinkingChars: '{count}자', copyBubble: '메시지 복사', copiedBubble: '복사됨', copyFailed: '복사 실패', playSpeech: '음성 재생', pauseSpeech: '일시정지', resumeSpeech: '재개', stopSpeech: '중지', speechNotSupported: '이 브라우저는 음성 재생을 지원하지 않습니다', }, // 예약 작업 jobs: { title: '예약 작업', createJob: '작업 생성', editJob: '작업 편집', noJobs: '예약된 작업이 없습니다. 새로 만들어 시작하세요.', name: '이름', namePlaceholder: '작업 이름', schedule: '스케줄 (Cron 표현식)', schedulePlaceholder: '예: 0 9 * * *', quickPresets: '빠른 프리셋', selectPreset: '프리셋 선택...', presetEveryMinute: '매 분', presetEvery5Min: '매 5분', presetEveryHour: '매 시간', presetEveryDay: '매일 00:00', presetEveryDay9: '매일 09:00', presetEveryMonday: '매주 월요일 09:00', presetEveryMonth: '매월 1일 09:00', prompt: '프롬프트', promptPlaceholder: '실행할 프롬프트', deliverTarget: '전송 대상', origin: '출처', local: '로컬', repeatCount: '반복 횟수 (선택)', modelPlaceholder: 'Default model', repeatPlaceholder: '비워두면 무한 반복', jobCreated: '작업이 생성되었습니다', jobUpdated: '작업이 업데이트되었습니다', nameRequired: '이름을 입력해 주세요', scheduleRequired: '스케줄을 입력해 주세요', loadFailed: '작업을 불러오지 못했습니다', jobPaused: '작업이 일시 정지되었습니다', jobResumed: '작업이 재개되었습니다', jobTriggered: '작업이 실행되었습니다', modelUpdated: 'Model updated', jobDeleted: '작업이 삭제되었습니다', status: { running: '실행 중', paused: '일시 정지', disabled: '비활성화', scheduled: '예약됨', }, info: { model: 'Model', schedule: 'Schedule', lastRun: '마지막 실행', nextRun: '다음 실행', deliver: '전송', repeat: '반복', }, action: { pause: '일시 정지', pauseJob: '작업 일시 정지', resume: '재개', resumeJob: '작업 재개', runNow: '즉시 실행', triggerImmediately: '즉시 실행', }, runHistory: { title: '실행 기록', runs: '회 실행', noRuns: '실행 기록이 없습니다.', }, }, // 스킬 skills: { title: '스킬', searchPlaceholder: '스킬 검색...', noMatch: '검색과 일치하는 스킬이 없습니다', noSkills: '스킬을 찾을 수 없습니다', backTo: '돌아가기', attachedFiles: '첨부 파일', loadFailed: '스킬을 불러오지 못했습니다', fileLoadFailed: '파일을 불러오지 못했습니다', modified: '사용자 수정됨', archived: '보관됨', pinned: '고정됨', pin: '스킬 고정', unpin: '고정 해제', pinFailed: '고정 상태 변경 실패', toggleFailed: '스킬 상태를 전환하지 못했습니다', source: { builtin: '내장', hub: 'Hub', local: '로컬', }, }, // 플러그인 plugins: { title: '플러그인', refresh: '새로고침', notice: '탐색 가능한 Hermes 플러그인 manifest의 읽기 전용 인벤토리입니다. 탐색 메타데이터는 플러그인 코드를 로드하지 않고 읽습니다. v1의 관리 작업은 CLI에 유지되며, 변경 사항은 새 Hermes 세션에서 적용됩니다.', loadFailed: '플러그인을 불러오지 못했습니다', commandCopied: '명령을 복사했습니다', searchPlaceholder: 'key, 이름, 설명, 경로 검색...', source: '소스', kind: '종류', statusTitle: '상태', configStatus: 'config: {status}', notAvailable: 'n/a', copyCommand: '명령 복사', managedElsewhere: '다른 곳에서 관리됨', noMatch: '현재 필터와 일치하는 플러그인이 없습니다', enabled: '활성화됨', disabled: '비활성화됨', summary: { total: '전체', active: '활성 / 자동', inactive: '비활성', disabled: '비활성화됨', providerManaged: 'Provider 관리', }, status: { enabled: '활성화됨', 'auto-active': '자동 활성', inactive: '비활성', disabled: '비활성화됨', 'provider-managed': 'Provider 관리', }, statusLabel: { enabled: '설정으로 활성화됨', 'auto-active': '자동 활성', inactive: '비활성', disabled: '비활성화됨', 'provider-managed': 'Provider 관리', }, configStatuses: { enabled: '활성화됨', disabled: '비활성화됨', 'not-enabled': '활성화되지 않음', auto: '자동', 'provider-managed': 'Provider 관리', }, table: { plugin: '플러그인', status: '상태', source: '소스', kind: '종류', capabilities: '기능', path: '경로 / entrypoint', cli: 'CLI', }, capabilities: { tools: '{count} tools', hooks: '{count} hooks', env: '{count} env', }, metadata: { agentRoot: 'Agent root', python: 'Python', scanCwd: 'Scan cwd', projectPlugins: '프로젝트 플러그인', }, }, // 메모리 memory: { title: '메모리', refresh: '새로고침', loadFailed: '메모리를 불러오지 못했습니다', myNotes: '내 메모', noNotes: '메모가 없습니다.', notesPlaceholder: '메모를 작성하세요...', userProfile: '사용자 프로필', noProfile: '프로필이 없습니다.', profilePlaceholder: '프로필을 작성하세요...', soul: '소울', noSoul: '소울 설정이 없습니다.', soulPlaceholder: '소울 설정을 작성하세요...', }, // 모델 models: { title: '모델', addProvider: 'Provider 추가', providerType: 'Provider 유형', preset: '프리셋', custom: '사용자 지정', selectProvider: 'Provider 선택', chooseProvider: 'Provider를 선택하세요...', name: '이름', autoGeneratedName: 'Base URL에서 자동 생성', baseUrl: 'Base URL', region: '지역', regionIntl: '국제판', regionCn: '중국 본토', baseUrlPlaceholder: '예: https://api.example.com/v1', apiKey: 'API Key', apiKeyPlaceholder: 'sk-...', defaultModel: '기본 모델', selectOrInput: '모델 선택 또는 직접 입력...', selectModel: '모델 선택...', providerAdded: 'Provider가 추가되었습니다', providerDeleted: 'Provider가 삭제되었습니다', deleteProvider: 'Provider 삭제', deleteConfirm: '"{name}"을(를) 삭제하시겠습니까?', codexLoginTitle: 'OpenAI Codex 로그인', codexWaiting: '인증 페이지에서 아래 코드를 입력하여 로그인하세요:', codexCopyCode: '코드가 복사되었습니다', codexOpenLink: '인증 페이지 열기', codexApproved: '로그인 성공', codexExpired: '인증이 만료되었습니다. 다시 시도해주세요.', nousLoginTitle: 'Nous Portal 로그인', nousWaiting: '인증 페이지에서 이 코드를 입력하세요:', nousCopyCode: '코드 복사됨', nousOpenLink: '인증 페이지 열기', nousApproved: '로그인 성공', nousDenied: '인증이 거부되었습니다', nousExpired: '인증이 만료되었습니다', copilotLoginTitle: 'GitHub Copilot 로그인', copilotWaiting: 'GitHub을 열고 아래의 디바이스 코드를 입력하여 인증하세요. 승인 후 창이 자동으로 닫힙니다.', copilotCopyCode: '코드가 복사되었습니다', copilotOpenLink: 'GitHub 인증 페이지 열기', copilotApproved: '로그인 성공!', copilotDenied: '인증이 거부되었습니다.', copilotExpired: '인증 링크가 만료되었습니다. 다시 시도하세요.', copilotAddDetectedTitle: 'GitHub Copilot 감지됨', copilotAddDetected: '이 컴퓨터에서 GitHub Copilot OAuth 토큰이 감지되었습니다. 추가를 클릭하여 Hermes에서 Copilot을 활성화하세요.', copilotAddSourceEnv: '출처: ~/.hermes/.env (COPILOT_GITHUB_TOKEN)', copilotAddSourceGhCli: '출처: gh CLI (gh auth token)', copilotAddSourceAppsJson: '출처: VS Code Copilot 확장 (apps.json)', copilotDeleteHintEnv: '이 작업은 ~/.hermes/.env의 COPILOT_GITHUB_TOKEN을 지웁니다. 다른 도구에는 영향이 없습니다.', copilotDeleteHintGhCli: 'Copilot이 Hermes에서 숨겨집니다. gh CLI 로그인에는 영향이 없으며 `gh auth status`는 여전히 로그인 상태를 표시합니다.', copilotDeleteHintAppsJson: 'Copilot이 Hermes에서 숨겨집니다. VS Code Copilot 확장 로그인에는 영향이 없습니다.', customBadge: '커스텀', previewBadge: '프리뷰', disabledBadge: '사용 불가', disabledTooltip: "이 모델은 현재 계정에서 사용할 수 없습니다.", customModelPlaceholder: '목록에 없는 모델 ID', customModelHint: '제공자는 지원하지만 API가 반환하지 않는 모델용입니다. 표시 이름 변경이 아닙니다. Enter로 불러옵니다.', noProviders: 'Provider가 없습니다. 사용자 지정 Provider를 추가하여 시작하세요.', clearVisibleModels: '선택 지우기', builtIn: '내장', customType: '사용자 지정', provider: 'Provider', contextLength: '컨텍스트 길이', contextLengthPlaceholder: '예: 200000 (선택사항)', local: '로컬 ({host})', selectProviderRequired: 'Provider를 선택해 주세요', baseUrlRequired: 'Base URL을 입력해 주세요', apiKeyRequired: 'API Key를 입력해 주세요', modelRequired: '기본 모델을 선택해 주세요', enterBaseUrl: '먼저 Base URL을 입력해 주세요', unexpectedFormat: '예상치 못한 응답 형식입니다', foundModels: '{count}개의 모델을 찾았습니다', fetchFailed: '모델을 가져오지 못했습니다', }, // 프로필 profiles: { title: '프로필', create: '프로필 생성', import: '가져오기', export: '내보내기', rename: '이름 변경', delete: '삭제', switchTo: '전환', switchConfirm: '프로필 "{name}"(으)로 전환하면 게이트웨이가 재시작됩니다. 계속하시겠습니까?', switchSuccess: '프로필 "{name}"(으)로 전환되었습니다', switchFailed: '프로필 전환 실패. 게이트웨이를 수동으로 재시작해야 할 수 있습니다.', createSuccess: '프로필 "{name}"이(가) 생성되었습니다', createFailed: '프로필 생성 실패', renameSuccess: '프로필 이름이 변경되었습니다', renameFailed: '프로필 이름 변경 실패', deleteConfirm: '프로필 "{name}"을(를) 삭제하시겠습니까?', deleteSuccess: '프로필이 삭제되었습니다', deleteFailed: '프로필 삭제 실패', exportSuccess: '프로필이 내보내기되었습니다', exportFailed: '프로필 내보내기 실패', importSuccess: '프로필이 가져오기되었습니다', importFailed: '프로필 가져오기 실패', importSelectFile: '아카이브 파일 선택', importInvalidFile: '유효한 아카이브 파일을 선택해 주세요 (.tar.gz, .tgz, .gz, .zip)', name: '프로필 이름', namePlaceholder: '영문, 숫자, 하이픈만 사용 가능', nameValidation: '프로필 이름에는 소문자, 숫자, 밑줄, 하이픈만 사용할 수 있습니다', newName: '새 이름', newNamePlaceholder: '새 이름을 입력하세요', cloneFromCurrent: '현재 프로필에서 복제', cloneCleanupNotice: '복제 시 독점형 플랫폼 자격 증명(Weixin / Telegram / Slack 등)은 자동으로 건너뛰어 원본 프로필과의 충돌을 방지합니다', cloneStrippedCredentials: '독점 자격 증명 {count}개 제거됨: {list}', cloneDisabledPlatforms: '플랫폼 {count}개 비활성화됨: {list}', cloneStrippedConfigCredentials: 'config.yaml에서 임베디드 자격 증명 {count}개 제거됨: {list}', archivePath: '아카이브 경로', archivePathPlaceholder: '아카이브 파일의 서버 경로', importName: '프로필 이름 (선택)', importNamePlaceholder: '비워두면 아카이브 이름을 사용합니다', active: '활성', model: '모델', gateway: '게이트웨이', alias: '별칭', provider: 'Provider', path: '경로', skills: '스킬', hasEnv: '.env 있음', hasSoulMd: 'soul.md 있음', noProfiles: '프로필이 없습니다. 새로 만들어 시작하세요.', }, // 로그 logs: { title: '로그', all: '전체', searchPlaceholder: '검색...', refresh: '새로고침', noEntries: '로그 항목 없음', }, // 설정 settings: { title: '설정', saved: '저장됨', saveFailed: '저장 실패', tabs: { display: '표시', account: '계정', agent: '에이전트', memory: '메모리', session: '세션', privacy: '개인정보', apiServer: 'API 서버', models: '모델', voice: '음성', }, display: { streaming: '스트리밍 응답', streamingHint: 'AI 응답을 실시간으로 표시', compact: '컴팩트 모드', compactHint: '메시지 간격 줄이기', showReasoning: '추론 과정 표시', showReasoningHint: '모델의 생각 과정 표시', showCost: '비용 표시', showCostHint: '응답에 토큰 사용량 표시', inlineDiffs: '인라인 변경사항', inlineDiffsHint: '코드 변경사항을 인라인으로 표시', bellOnComplete: '완료 알림음', bellOnCompleteHint: 'AI 응답 완료 시 알림음 재생', busyInputMode: '바쁨 입력 모드', busyInputModeHint: 'AI 처리 중에도 입력 허용', theme: '테마', themeHint: '라이트, 다크 또는 시스템 설정 따르기', themeLight: '라이트', themeDark: '다크', themeSystem: '시스템', }, agent: { maxTurns: '최대 턴 수', maxTurnsHint: '대화당 최대 상호작용 라운드 수', gatewayTimeout: '게이트웨이 시간초과', gatewayTimeoutHint: '요청 시간초과 (초)', restartDrainTimeout: '재시작 드레인 시간초과', restartDrainTimeoutHint: '재시작 전 드레인 시간초과 (초)', toolEnforcement: '도구 실행 정책', toolEnforcementHint: '도구 호출 실행 모드 제어', auto: '자동', always: '항상', never: '사용 안 함', }, memory: { enabled: '메모리 활성화', enabledHint: 'AI가 대화 컨텍스트를 기억하도록 허용', userProfile: '사용자 프로필', userProfileHint: 'AI가 사용자 선호를 기억하도록 허용', charLimit: '메모리 문자 제한', charLimitHint: 'MEMORY.md 최대 문자 수', userCharLimit: '사용자 프로필 문자 제한', userCharLimitHint: 'USER.md 최대 문자 수', }, session: { mode: '초기화 모드', modeHint: '세션 초기화 트리거 조건', modeBoth: '유휴 + 예약', modeIdle: '유휴만', modeDaily: '예약만', modeNone: '안함 (수동만)', idleMinutes: '유휴 시간초과', idleMinutesHint: '자동 초기화 대기 시간 (분)', atHour: '예약 초기화 시간', humanOnly: '사람 세션만 표시', humanOnlyHint: '하위 에이전트 및 세션 모니터 노이즈를 기본으로 숨깁니다', liveMonitorHumanOnly: '라이브 모니터: 사람 세션만 표시', liveMonitorHumanOnlyHint: '라이브 모니터에서 하위 에이전트 및 세션 모니터 노이즈를 기본으로 숨깁니다', atHourHint: '매일 지정한 시간에 세션 초기화', requireAuth: '세션 인증', requireAuthHint: '세션 작업에 인증 필요', }, privacy: { redactPii: '개인정보 마스킹', redactPiiHint: '민감 정보 자동 감지 및 숨김 (비밀번호, 키 등)', }, apiServer: { enable: '활성화', enableHint: 'API 서버 활성화', host: '호스트', hostHint: '수신 주소', port: '포트', portHint: '수신 포트', key: '키', keyHint: 'API 접근 키', cors: 'CORS 출처', corsHint: '허용된 교차 출처', }, voice: { ttsProvider: 'TTS 제공자', ttsProviderHint: '메시지 재생에 사용할 텍스트 음성 변환 엔진 선택', providerWebSpeech: 'WebSpeech API (브라우저)', providerOpenai: 'OpenAI TTS', providerCustom: '사용자 정의 엔드포인트 (OpenAI 호환)', providerEdge: 'Edge TTS (무료, API Key 불필요)', // WebSpeech webspeechVoice: '음성', webspeechVoiceHint: '브라우저 또는 OS에서 음성 선택', webspeechVoicePlaceholder: '자동 (기본 음성)', // OpenAI openaiKey: 'API 키', openaiKeyHint: 'TTS 접근 권한이 있는 OpenAI API 키', openaiUrl: 'API 기본 URL', openaiUrlHint: '예: https://api.openai.com/v1/audio/speech', openaiModel: '모델', openaiModelHint: 'tts-1 (빠름) / tts-1-hd (고음질)', openaiVoice: '음색', openaiVoiceHint: '합성에 사용할 음색', // Custom endpoint customHint: '모든 OpenAI 호환 TTS API 사용 가능 — GPT-SoVITS, CosyVoice 등 지원', customUrl: 'API URL', customUrlHint: 'TTS 서비스의 기본 URL', customUrlPlaceholder: '로컬 어댑터에 설정된 주소 (예: http://127.0.0.1:9880)', customApiKey: 'API 키 (선택사항)', customApiKeyHint: '일부 사용자 정의 엔드포인트는 인증 필요', customApiKeyPlaceholder: '필요하지 않으면 비워둠', // Edge TTS edgeHint: 'Microsoft Edge TTS 기반 (node-edge-tts).', edgeUrl: '어댑터 URL', edgeUrlHint: 'Edge TTS 어댑터 주소 (예: http://127.0.0.1:9882)', edgeUrlPlaceholder: 'http://127.0.0.1:9882', edgeVoice: '음색', edgeVoiceHint: '음성 합성에 사용할 음색 선택', edgeRate: '속도', edgeRateHint: '음성 속도 조절 (0.5~2.0배)', edgePitch: '음높이', edgePitchHint: '음성 음높이 조절 (-20~+20 Hz)', // Test testTitle: '음성 테스트', testText: '테스트 텍스트', testTextPlaceholder: '테스트할 텍스트 입력...', testTextDefault: '안녕하세요, 음성 테스트입니다.', testButton: '테스트', testButtonPlaying: '재생 중...', testFailed: '테스트 실패: {error}', // MiMo TTS providerMimo: 'MiMo TTS', mimoHint: '샤오미 MiMo TTS — 프리셋 음성, 음성 디자인, 음성 클론 세 가지 모드 지원', mimoApiKey: 'API Key', mimoApiKeyHint: 'platform.xiaomimimo.com에서 발급', mimoApiKeyPlaceholder: 'MiMo API Key', mimoBaseUrl: 'Base URL', mimoBaseUrlHint: 'MiMo API 엔드포인트 URL', mimoModel: '모델', mimoModelHint: '음성 합성 모델 선택', mimoModelPreset: '프리셋 음성', mimoModelVoiceDesign: '음성 디자인', mimoModelVoiceClone: '음성 클론', mimoVoice: '음성', mimoVoiceHint: '프리셋 음성 선택', mimoVoiceDesignPrompt: '음성 설명', mimoVoiceDesignPromptHint: '원하는 음성 특징을 설명하세요', mimoVoiceDesignPromptPlaceholder: '예: 따뜻한 젊은 여성 목소리, 약간 느린 속도, 마그네틱한 톤', mimoCloneAudio: '오디오 업로드', mimoCloneAudioHint: '음성 클론용 오디오 샘플 업로드 (mp3/wav, 최대 10MB)', mimoCloneAudioUpload: '파일 선택', mimoCloneAudioClear: '지우기', mimoStylePrompt: '스타일 프롬프트', mimoStylePromptHint: '선택사항 — 자연어로 말하기 스타일 설명', mimoStylePromptPlaceholder: '예: 밝고 경쾌한 톤, 빠른 속도', }, lockedIps: { title: '잠긴 IP 관리', count: '{count}개 잠김', empty: '잠긴 IP 없음', unlock: '잠금 해제', unlockAll: '전체 해제', unlockAllConfirm: '모든 잠긴 IP를 해제하시겠습니까?', unlocked: 'IP 잠금 해제됨', allUnlocked: '{count}개 IP 잠금 해제됨', }, }, // 플랫폼 채널 설정 platform: { requireMention: "{'@'}멘션 필요", requireMentionGroup: "그룹에서 {'@'}멘션 시에만 응답", requireMentionChannel: "채널에서 {'@'}멘션 시에만 응답", requireMentionRoom: "방에서 {'@'}멘션 시에만 응답", reactions: '반응', reactionsHint: '메시지에 이모지 반응', freeResponseChats: '자유 응답 채팅', freeResponseChatsHint: "{'@'}멘션 없이 응답할 채팅 ID (쉼표로 구분)", freeResponseChannels: '자유 응답 채널', freeResponseChannelsHint: "{'@'}멘션 없이 응답할 채널 ID (쉼표로 구분)", freeResponseRooms: '자유 응답 방', freeResponseRoomsHint: "{'@'}멘션 없이 응답할 방 ID (쉼표로 구분)", mentionPatterns: '사용자 지정 멘션 패턴', mentionPatternsHint: '추가 트리거 패턴', autoThread: '자동 스레드', autoThreadHint: "{'@'}멘션 후 자동으로 스레드 생성", autoThreadHintRoom: '방에서 자동으로 스레드 생성', dmMentionThreads: 'DM 멘션 스레드', dmMentionThreadsHint: 'DM에서 멘션 시 스레드로 응답', allowBots: '봇 메시지 허용', allowBotsHint: '다른 봇의 메시지에 응답', allowedChannels: '허용된 채널', allowedChannelsHint: '채널 ID 허용 목록 (쉼표로 구분)', ignoredChannels: '무시할 채널', ignoredChannelsHint: '봇이 응답하지 않는 채널 ID (쉼표로 구분)', noThreadChannels: '스레드 없는 채널', noThreadChannelsHint: '스레드 없이 응답할 채널 ID (쉼표로 구분)', exclusiveTokenWarning: '이 플랫폼은 독점 토큰 잠금을 사용합니다. 각 프로필은 다른 프로필과 충돌하지 않도록 서로 다른 ID 토큰을 사용해야 합니다.', botToken: 'Bot Token', botTokenHint: '개발자 포털에서 발급받은 Bot Token', accessToken: 'Access Token', accessTokenHint: 'Matrix Access Token', homeserver: 'Homeserver URL', homeserverHint: 'Matrix 홈서버 URL', appId: 'App ID', appIdHint: 'Feishu App ID', appSecret: 'App Secret', appSecretHint: 'Feishu App Secret', clientId: 'Client ID', clientIdHint: 'DingTalk Client ID', clientSecret: 'Client Secret', clientSecretHint: 'DingTalk Client Secret', botId: 'Bot ID', botIdHint: 'WeCom Bot ID', wecomSecretHint: 'WeCom Bot Secret', waEnabled: 'WhatsApp 활성화', waEnabledHint: 'QR 코드 페어링으로 WhatsApp 활성화', weixinToken: 'Weixin Token', weixinTokenHint: 'weixin CLI QR 로그인에서 가져오기 (hermes weixin)', accountId: 'Account ID', accountIdHint: 'Weixin Account ID', qrLogin: 'QR 로그인', qrRelogin: '다시 로그인', qrFetching: 'QR 코드를 가져오는 중...', qrScanHint: 'WeChat으로 QR 코드를 스캔하여 로그인', qrScanedHint: '스캔됨, 휴대폰에서 확인해 주세요...', }, // 언어 language: { label: '언어', zh: '中文', en: 'English', ko: '한국어', }, // 터미널 terminal: { sessions: '세션', newTab: '새 터미널', closeSession: '이 세션을 닫으시겠습니까?', sessionExited: '종료됨', processExited: '프로세스가 종료되었습니다 (코드 {code})', }, // 사용량 usage: { title: '사용량 통계', refresh: '새로고침', totalTokens: '총 토큰 수', inputTokens: '입력', outputTokens: '출력', totalSessions: '총 세션 수', avgPerDay: '일평균 ~{n}', estimatedCost: '예상 비용', cacheHitRate: '캐시 적중률', modelBreakdown: '모델별 분포', dailyTrend: '일별 사용량', date: '날짜', tokens: '토큰', cache: '캐시', cacheRead: '캐시 읽기', cacheWrite: '캐시 쓰기', sessions: '세션', cost: '비용', noData: '사용량 데이터 없음', }, skillsUsage: { title: '스킬 사용량', subtitle: 'Hermes 세션의 스킬 로드와 편집을 추적합니다', refresh: '새로고침', periodSelector: '스킬 사용량 기간', periodLabel: '{days}일', summary: '요약', totalActions: '작업 수', loads: '로드', edits: '편집', distinctSkills: '스킬 수', topSkills: '상위', dailyTrend: '일별', periodSummary: '최근 {days}일', skill: '스킬', share: '비중', lastUsed: '마지막', noData: '스킬 사용량 데이터가 없습니다', loadFailed: '스킬 사용량을 불러오지 못했습니다', otherSkills: '기타', }, // 변경 이력 changelog: { new_0_5_6_1: '음성 재생 기능: Web Speech API, 수동 재생 버튼, 자동 재생 스위치, 무지개 테두리 애니메이션, 모바일 최적화', new_0_5_6_2: '강력한 LLM JSON 파서: Python 형식 허용, 스트리밍 이벤트에서 텍스트 추출', new_0_5_6_3: 'Skils 기능 향상: 사용 통계, 소스 필터링, 보관된 스킬, 출처, 고정 토글', new_0_5_6_4: '확장된 일일 사용 통계: 캐시 읽기/쓰기 분리를 포함한 상세한 토큰 분석', new_0_5_6_5: '세션 기록 범위 명확화: 채팅 및 기록 보기의 설명 개선', new_0_5_6_6: 'Anthropic 스타일의 ContentBlock 배열 형식(텍스트, 이미지, 파일)을 사용하여 첨부파일 처리를 재설계', new_0_5_6_7: '인증이 포함된 ContentBlock 및 Markdown 형식을 지원하는 프론트엔드 파일 다운로드 기능 추가', new_0_5_6_8: '중복된 nodemon 인스턴스를 제거하여 SQLite 데이터베이스 재설정을 일으키는 다중 프로세스 충돌 수정', new_0_5_14_1: 'Add session export with full and compressed modes (JSON or plain text)', new_0_5_14_2: 'Fix terminal PTY resource exhaustion, switch to lazy connect', new_0_5_14_3: 'Fix WSL2 health check failure caused by IPv6 dual-stack binding', new_0_5_14_4: 'Fix SQLite connection not released on shutdown causing database lock', new_0_5_14_5: 'Update FUN provider models, add builtin badge and API relay link', new_0_5_15_1: '칸반 보드로 작업 및 세션 시각적 관리', new_0_5_15_2: '공식 랜딩 페이지 및 문서 사이트 추가', new_0_5_15_3: '그룹 채팅 에이전트 클라이언트가 하드코딩 8648 대신 동적 포트 사용', new_0_5_15_4: 'node-edge-tts 음성 모듈 추가', new_0_5_15_5: 'WSL 기본 리슨 호스트 바인딩 수정', new_0_5_15_6: '웹사이트 홈페이지 SEO 메타데이터 추가', new_0_5_15_7: 'IP 기반 로그인 무차별 대입 공격 보호 추가', new_0_5_15_8: 'MarkdownRenderer 다운로드 URL 이중 래핑 수정', new_0_5_15_9: 'Hermes Markdown 미디어 렌더링 및 동기화 재시도 수정', new_0_5_15_10: '업스트림 환경 변수 종속성 제거', new_0_5_15_11: '칸반 기능을 사용할 수 없는 경우 hermes-agent를 업그레이드하세요', new_0_5_16_1: '채팅 스트리밍을 /v1/runs에서 /v1/responses API로 마이그레이션하여 지연 시간 단축', new_0_5_16_2: '실제 API 사용량(토큰, 캐시, 추론)을 사용량 통계 테이블에 저장', new_0_5_16_3: '웹사이트 내비게이션 바에 QQ 그룹 QR 코드 추가', new_0_5_16_4: '메시지 스키마에서 사용하지 않는 codex_reasoning_items 필드 제거', new_0_5_17_1: 'Windows 완전 호환: 경로 처리, 프로세스 관리, 터미널, 로그 파싱', new_0_5_17_2: 'Gateway 프로세스 관리 리팩토링, 크로스 플랫폼 시작/중지/헬스체크 지원', new_0_5_17_3: 'Termux에서 hermes shebang을 파싱하여 Python을 찾아 플러그인 발견 수정', new_0_5_17_4: '설정 파싱 시 중복 YAML 키 허용', new_0_5_17_5: '인증 잠금 창 및 개발 환경 종료 흐름 개선', new_0_5_17_6: 'Comic 테마에 중국어(ZCOOL KuaiLe), 일본어(Zen Maru Gothic), 한국어(Gaegu) 필기 폰트 추가', new_0_5_17_7: 'Comic/낙서 테마 스타일 추가', new_0_5_17_8: '라이선스를 BSL-1.1로 변경', new_0_5_17_9: '읽기 전용 Hermes 플러그인 페이지 추가', new_0_5_17_10: '이미지 업로드를 base64 멀티모달 형식으로 변환', new_0_5_17_11: '칸반 보드 선택 및 격리 수정', new_0_5_17_12: '4개 제공자 TTS 지원 음성 재생 설정 추가', new_0_5_17_13: '컨텍스트 압축 메시지 임계값을 200에서 150으로 낮춤', new_0_5_17_14: 'Web UI 자동 업데이트 재시작 로직 수정', new_0_5_17_15: 'opencode-zen과 opencode-go 공유 환경 변수로 인한 설정 결합 문제 수정', new_0_5_17_16: '번체 중국어(zh-TW) 언어 지원 추가', new_0_5_17_17: 'Web UI에서 보이는 모델 관리 지원', new_0_5_17_18: '칸반: 작업의 전체 액션 체인(댓글, 로그, 할당, 발송)과 기능 경계 구현', new_0_5_17_19: '프로바이더 삭제 시 인증 항목이 지워지지 않는 문제 수정', new_0_5_17_20: 'Codex credential-pool 인증 인식 수정', new_0_5_17_21: '음성 설정에 Edge TTS 속도/피치 슬라이더 추가', new_0_5_17_22: '설정 YAML 중복 키가 더 이상 파싱 충돌을 일으키지 않음', new_0_5_17_23: '게이트웨이 포트 소유권이 PID 파일 기반으로 변경되어 프로필 간 포트 탈취 방지', new_0_5_17_24: '기록 페이지에 Cron 세션 기록 표시', new_0_5_17_25: '접힌 사이드바에서 언어 전환 및 테마 아이콘이 눌리는 문제 수정', new_0_5_18_1: 'Add Skills Usage monitoring page with daily trend chart and top skills statistics', new_0_5_18_2: 'Add CLI chat session bridge with Python agent bridge for WebSocket-based sessions', new_0_5_18_3: 'Add Ollama Cloud provider preset with dynamic model catalog', new_0_5_18_4: 'Support model display name renaming (aliases)', new_0_5_18_5: 'Support model visibility management in Web UI', new_0_5_18_6: 'Enhance usage analytics dashboard', new_0_5_18_7: 'Docker single-container deployment with docker-compose and gateway startup fixes', new_0_5_18_8: 'Fix plugins page HERMES_HOME fallback warning for non-default profiles', new_0_5_18_9: 'Fix gateway stability across dev restarts and improve Windows compatibility', new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database', new_0_5_23_1: 'Add bridge-only chat slash commands with localized command suggestions', new_0_5_23_2: 'Persist command history for session replay without polluting model context, usage, or compression', new_0_5_23_3: 'Isolate gateway profile environment variables to prevent credentials leaking across profiles', new_0_5_23_4: 'Reserve the Web UI port during gateway allocation to avoid startup conflicts', new_0_5_23_5: 'Fix self-update restart handling so successful helper exits are not reported as failures', new_0_5_24_1: 'Align Bridge chat with API Server handling for multimodal input, system prompt, and workspace context', new_0_5_25_1: 'Add group chat room reset and clone actions', new_0_5_25_2: 'Make the Web UI state directory configurable for custom deployment layouts', new_0_5_25_3: 'Add MiMo as a TTS provider in voice settings', new_0_5_25_4: 'Fetch custom provider model lists through the backend to avoid browser CORS failures', new_0_5_25_5: 'Fix tool approval flow for bridge sessions', new_0_5_25_6: 'Remove the forced CLI platform hint from bridge prompts so custom media/file instructions are preserved', new_0_5_25_7: 'Show base64 image content correctly in user message history', new_0_5_25_8: 'Add Playwright browser tests, chat streaming contract coverage, provider model coverage, and coverage baseline', new_0_5_5_1: '🎉 노동절 감사합니다! 오늘은 쉬니까 양해 부탁드립니다', new_0_5_5_2: 'Hermes 세션 기록 페이지 추가', new_0_5_5_3: '기록 페이지는 독립적으로 세션 관리', new_0_5_5_4: '기록 페이지는 첫 번째 CLI 세션 자동 선택', new_0_5_5_5: 'HistoryMessageList 컴포넌트 추가', new_0_5_5_6: '빈 메시지와 toolName 없는 tool 메시지 필터링', new_0_5_5_7: 'localStorage 세션 캐시 제거, 백엔드에서 직접 가져오기', new_0_5_5_8: '프로필 전환 최적화', new_0_5_4_2: 'Fix concurrent chat sessions event cross-talk with WebSocket event routing refactoring', new_0_5_4_3: 'Fix cron job edit payloads with partial PATCH to support long prompt name-only edits', new_0_5_4_4: 'Fix web terminal Hermes CLI availability after Docker deployment', new_0_5_4_5: 'Add workspace dialog i18n translations for title and improve session persistence', new_0_5_4_6: 'Support code block copy feedback with user notifications', new_0_5_4_7: 'Align usage analytics with Hermes state DB schema', new_0_4_8_2: 'Fix nested markdown fence rendering truncation', new_0_4_8_3: 'Fix compressed session lineage projection and search', new_0_4_8_4: 'Optimize session list N+1 queries and fix search 500 on non-CJK input', new_0_4_8_5: 'Fix forced scroll to bottom when switching back from other tabs', new_0_4_8_6: 'Smooth session switch with loading transition overlay', new_0_4_8_7: 'Fix login token validation using Hermes session endpoint', new_0_4_8_8: 'Fix image attachments broken after page refresh (blob URL persistence)', new_0_4_8_9: 'Click image attachments to preview in fullscreen overlay', new_0_4_8_10: 'Move upload directory from temp to ~/.hermes-web-ui/upload', new_0_4_7_1: '생각/추론 블록의 실시간 스트리밍 표시', new_0_4_7_2: 'Docker 빌드 중 prepare 스크립트 건너뛰기', new_0_4_7_3: '그룹 채팅 모바일 UX 개선 및 UI 다듬기', new_0_4_7_4: '컨텍스트 남은 토큰을 음수 대신 0으로 제한', new_0_4_7_5: '.env base_url 재정의를 지원하는 Alibaba Coding Plan 내장 프로바이더 추가', new_0_4_7_6: '시작 시 원격 프로필 건너뛰어 중지 방지', new_0_4_7_7: '조용히 삼켜진 실행 오류 감지 및 표시', new_0_4_7_8: '프로바이더 인식 컨텍스트 길이 조회', new_0_4_7_9: '전환 시 config.model 재설정 및 CLI 커스텀 프로바이더 해결', new_0_4_7_10: '내장 프로바이더 삭제 시 .env에서 base_url_env 정리', new_0_4_7_11: '그룹 채팅 방 사이드바 배경을 세션 목록과 맞추기', new_0_4_5_1: 'Add group chat with multi-agent rooms, mention routing, and typing status recovery', new_0_4_5_2: 'Rewrite model-context config to use YAML with context_length setting', new_0_4_5_3: 'Add gpt-5.5 to OpenAI Codex model list', new_0_4_5_4: 'Replace jobs proxy with local controller and optimize model loading', new_0_4_5_5: 'Add i18n support for custom model feature in ModelSelector', new_0_4_5_6: 'Fix sidebar i18n missing key warnings', new_0_4_5_7: 'Clear all localStorage on logout', new_0_4_5_8: 'Add periodic log rotation to prevent unbounded log growth', new_0_4_2_1: '토큰 사용량 추적 및 동적 컨텍스트 길이 추가', new_0_4_2_2: '세션 검색 모달 추가', new_0_4_2_3: 'Socket.IO 및 SQLite로 그룹 채팅 시스템 복원', new_0_4_2_4: '채팅 페이지에 고정 세션 및 라이브 모니터 추가', new_0_4_2_5: '내장 프로바이더 감지 및 모델 매칭 수정', }, // 파일 files: { title: '파일', tree: '디렉터리 트리', list: '파일 목록', breadcrumbRoot: '홈', newFile: '새 파일', newFolder: '새 폴더', upload: '업로드', refresh: '새로고침', open: '열기', edit: '편집', preview: '미리보기', download: '다운로드', copyPath: '경로 복사', rename: '이름 변경', delete: '삭제', name: '이름', size: '크기', modified: '수정일', actions: '작업', emptyDir: '빈 디렉터리', loading: '불러오는 중...', confirmDelete: '"{name}"을(를) 삭제하시겠습니까?', confirmDeleteDir: '디렉터리 "{name}"과 그 내부 항목을 모두 삭제하시겠습니까?', deleteFailed: '삭제 실패', deleted: '삭제됨', renameTo: '새 이름', newFileName: '파일 이름', newFolderName: '폴더 이름', created: '생성됨', createFailed: '생성 실패', renamed: '이름이 변경됨', renameFailed: '이름 변경 실패', uploadSuccess: '{count}개 파일이 업로드되었습니다', uploadFailed: '업로드 실패', saveFailed: '저장 실패', saved: '저장됨', unsavedChanges: '저장하지 않은 변경 사항이 있습니다. 취소하시겠습니까?', pathCopied: '경로가 복사되었습니다', fileTooLarge: '파일이 너무 큽니다 (최대 10MB)', permissionDenied: '보호된 파일은 수정할 수 없습니다', notFound: '파일 또는 디렉터리를 찾을 수 없습니다', backendError: '파일 작업 실패', dragDropHint: '여기로 파일을 드래그하여 업로드', closeEditor: '편집기 닫기', closePreview: '닫기', saveFile: '저장', }, // 그룹 채팅 groupChat: { title: '그룹 채팅', createRoom: '방 만들기', joinByCode: '코드로 참여', roomName: '방 이름', roomNamePlaceholder: '방 이름을 입력하세요', inviteCode: '초대 코드', autoGenerate: '자동 생성', noRooms: '아직 방이 없습니다', selectOrCreate: '방을 선택하거나 만들어 채팅을 시작하세요', agents: '에이전트', addAgent: '에이전트 추가', selectProfile: '프로필 선택', agentAdded: '에이전트가 추가되었습니다', agentAlreadyInRoom: '해당 에이전트가 이미 방에 있습니다', noAgents: '이 방에 에이전트가 없습니다', members: '멤버', roomCreated: '방이 생성되었습니다', roomDeleted: '방이 삭제되었습니다', roomCloned: '방이 복제되었습니다', cloneRoom: '방 복제', deleteRoomConfirm: '이 방을 삭제하시겠습니까?', clearContext: '컨텍스트 지우기', clearContextConfirm: '이 방의 컨텍스트를 지우시겠습니까? 메시지와 압축 스냅샷은 삭제되고 에이전트와 멤버는 유지됩니다.', contextCleared: '컨텍스트가 지워졌습니다', you: '나', joined: '방에 참여했습니다', joinFailed: '방 참여에 실패했습니다', inputPlaceholder: '메시지를 입력하세요... (Enter로 전송)', enterCode: '초대 코드를 입력하세요', yourName: '이름', yourNamePlaceholder: '표시 이름을 입력하세요', yourDescription: '설명 (선택)', yourDescriptionPlaceholder: '자신을 소개해 주세요...', agentName: '에이전트 이름', agentNamePlaceholder: '사용자 지정 이름 (빈칸=프로필 이름)', agentDesc: '에이전트 설명', agentDescPlaceholder: '이 에이전트가 하는 일을 설명...', agentReplying: '이(가) 응답 중...', agentCompressing: '이(가) 컨텍스트 압축 중...', compressionSettings: '압축 설정', triggerTokens: '압축 트리거 토큰', triggerTokensDesc: '이 토큰 수를 초과하면 컨텍스트 압축이 시작됩니다', maxHistoryTokens: '최대 기록 토큰', maxHistoryTokensDesc: '압축된 컨텍스트의 최대 토큰 수', tailMessageCount: '최근 메시지 수', tailMessageCountDesc: '압축 후 그대로 유지할 최근 메시지 수', compressionConfig: '압축 설정', compressNow: '지금 압축', compressingInProgress: '압축 진행 중', compressionSaved: '압축 설정이 저장되었습니다', }, // 다운로드 download: { downloading: '다운로드 중...', downloadFailed: '다운로드 실패', fileNotFound: '파일을 찾을 수 없거나 삭제되었습니다', fileTooLarge: '파일이 너무 큽니다 (제한 초과)', backendError: '파일 읽기에 실패했습니다. 원격 환경이 사용 불가능할 수 있습니다', backendTimeout: '파일 읽기 시간 초과', unsupportedBackend: '현재 터미널 백엔드는 파일 다운로드를 지원하지 않습니다', invalidPath: '잘못된 파일 경로', download: '다운로드', downloadFile: '파일 다운로드', }, }