export const LANGUAGE_STORAGE_KEY = "codexRemote.language";
export const SUPPORTED_LANGUAGES = new Set(["en", "ko"]);

const messages = {
  en: {
    "settings.title": "Settings", "settings.accounts": "Accounts", "settings.chats": "Chats", "settings.archivedChats": "Archived chats", "settings.appearance": "Appearance", "settings.language": "Language", "settings.systemLanguage": "System language", "settings.english": "English", "settings.korean": "Korean", "settings.theme": "Theme", "settings.systemTheme": "System theme", "settings.dark": "Dark mode", "settings.light": "Light mode", "settings.back": "Back",
    "account.removeConfirm": "Remove {name} from this app? Login and chat files stay on this PC.", "account.remove": "Remove", "account.removing": "Removing...", "account.add": "Add account", "account.starting": "Starting...", "account.empty": "No Codex account is connected yet. Sign in to connect this PC to your Codex account.", "account.note": "Login and chat files stay on this PC when an account is removed.", "account.error": "Account update failed.", "account.configWriteFailed": "Could not save account settings.", "account.rateLimited": "Sign-in temporarily rate limited. Try again shortly.", "account.loginStartFailed": "Could not start sign-in. Try again.",
    "context.accounts": "Accounts", "context.settings": "Settings", "context.switchLocked": "Work must finish before switching accounts", "context.connect": "Connect account", "context.close": "Close", "context.getLoginCode": "Get login code", "context.requestingCode": "Getting code...", "context.deviceCode": "Open ChatGPT and enter this one-time code:", "context.openChatGpt": "Open ChatGPT", "context.manageAccount": "Manage account", "context.signIn": "Sign in to a Codex account", "context.resetCredits": "Reset credits {count}", "context.unavailable": "Unavailable", "context.using": "Using...", "context.use": "Use", "context.resetConfirm": "Use one reset credit for {name}?", "context.noUsageReset": "No current usage window can be reset.", "context.noResetCredit": "No reset credits are available.", "context.resetFailed": "Reset credit could not be used.", "context.checking": "Checking...", "context.checkConnection": "Check connection", "context.openLastChat": "Open last chat",
  },
  ko: {
    "settings.title": "설정", "settings.accounts": "계정", "settings.chats": "채팅", "settings.archivedChats": "보관된 채팅", "settings.appearance": "화면", "settings.language": "언어", "settings.systemLanguage": "시스템 언어", "settings.english": "영어", "settings.korean": "한국어", "settings.theme": "테마", "settings.systemTheme": "시스템 테마", "settings.dark": "어둡게", "settings.light": "밝게", "settings.back": "뒤로",
    "account.removeConfirm": "이 앱에서 {name} 계정을 삭제할까요? 로그인과 채팅 파일은 이 PC에 남습니다.", "account.remove": "삭제", "account.removing": "삭제 중...", "account.add": "계정 추가", "account.starting": "시작 중...", "account.empty": "연결된 Codex 계정이 없습니다. 이 PC를 Codex 계정에 연결하려면 로그인하세요.", "account.note": "계정을 삭제해도 로그인과 채팅 파일은 이 PC에 남습니다.", "account.error": "계정 업데이트에 실패했습니다.", "account.configWriteFailed": "계정 설정을 저장하지 못했습니다.", "account.rateLimited": "로그인 요청이 일시적으로 제한되었습니다. 잠시 후 다시 시도하세요.", "account.loginStartFailed": "로그인을 시작하지 못했습니다. 다시 시도하세요.",
    "context.accounts": "계정", "context.settings": "설정", "context.switchLocked": "작업이 끝난 뒤 계정을 전환할 수 있습니다", "context.connect": "계정 연결", "context.close": "닫기", "context.getLoginCode": "로그인 코드 받기", "context.requestingCode": "코드 받는 중...", "context.deviceCode": "ChatGPT를 열고 일회용 코드를 입력하세요:", "context.openChatGpt": "ChatGPT 열기", "context.manageAccount": "계정 관리", "context.signIn": "Codex 계정 로그인", "context.resetCredits": "재설정 크레딧 {count}", "context.unavailable": "사용할 수 없음", "context.using": "사용 중...", "context.use": "사용", "context.resetConfirm": "{name} 계정에 재설정 크레딧 1개를 사용할까요?", "context.noUsageReset": "재설정할 현재 사용량 기간이 없습니다.", "context.noResetCredit": "사용 가능한 재설정 크레딧이 없습니다.", "context.resetFailed": "재설정 크레딧을 사용하지 못했습니다.", "context.checking": "확인 중...", "context.checkConnection": "연결 확인", "context.openLastChat": "최근 채팅 열기",
  }
};

Object.assign(messages.en, {
  "usage.daily": "Daily", "usage.weekly": "Weekly", "usage.cumulative": "Cumulative", "usage.tokenPeriod": "Token usage period"
});
Object.assign(messages.ko, {
  "usage.daily": "\uC77C\uBCC4", "usage.weekly": "\uC8FC\uAC04", "usage.cumulative": "\uB204\uC801", "usage.tokenPeriod": "\uD1A0\uD070 \uC0AC\uC6A9 \uAE30\uAC04"
});
Object.assign(messages.en, {
  "settings.pcData": "PC app data", "settings.resetPcData": "Reset PC app data", "settings.resetPcDataTitle": "Reset Code Remote Manager data on the PC?", "settings.resetPcDataDescription": "The installed Backend restarts after removing its local runtime data.", "settings.resetPcDataConfirm": "Reset PC data", "settings.resettingPcData": "Preparing reset…", "settings.resetPcDeletesTitle": "Deleted from the PC", "settings.resetPcDeletesSessions": "Local session cache, attachments, and generated previews", "settings.resetPcDeletesPreferences": "Thread, project, and local usage preferences", "settings.resetPcDeletesPairings": "Every paired-device record", "settings.resetPcDeletesLogs": "Existing production operation logs", "settings.resetPcKeepsTitle": "Kept on the PC", "settings.resetPcKeepsCodex": "Codex chats, login, settings, and account files", "settings.resetPcKeepsConfiguration": "Code Remote Manager configuration and its backups", "settings.resetPcKeepsReceipts": "Seven-day duplicate-execution protection records", "settings.resetPcKeepsAccounts": "OpenAI and Tailscale accounts are not deleted", "settings.resetPcInUse": "Finish running work, approvals, and queued messages before resetting.", "settings.resetPcUnmanaged": "PC data can be reset only from the installed Windows host.", "settings.resetPcFailed": "PC data could not be reset safely. The Backend will recover and restart; try again.", "settings.resetPcScheduledTitle": "PC reset prepared", "settings.resetPcScheduled": "The Backend is restarting. You will need to pair this device again.", "settings.reconnectPc": "Reconnect"
});
Object.assign(messages.ko, {
  "settings.pcData": "PC 앱 데이터", "settings.resetPcData": "PC 앱 데이터 초기화", "settings.resetPcDataTitle": "PC의 Code Remote Manager 데이터를 초기화할까요?", "settings.resetPcDataDescription": "PC에 저장된 앱 실행 데이터를 삭제한 뒤 Backend만 다시 시작합니다.", "settings.resetPcDataConfirm": "PC 데이터 초기화", "settings.resettingPcData": "초기화 준비 중…", "settings.resetPcDeletesTitle": "PC에서 삭제", "settings.resetPcDeletesSessions": "앱의 임시 채팅정보·첨부파일·생성된 미리보기", "settings.resetPcDeletesPreferences": "채팅·프로젝트·로컬 사용량 설정", "settings.resetPcDeletesPairings": "연결된 모든 기기의 인증 기록", "settings.resetPcDeletesLogs": "기존 운영 로그", "settings.resetPcKeepsTitle": "PC에 그대로 유지", "settings.resetPcKeepsCodex": "Codex 채팅·로그인·설정·계정 파일", "settings.resetPcKeepsConfiguration": "Code Remote Manager 설정 파일과 백업", "settings.resetPcKeepsReceipts": "중복 실행을 막는 7일 안전 기록", "settings.resetPcKeepsAccounts": "OpenAI와 Tailscale 계정은 삭제하지 않음", "settings.resetPcInUse": "실행 중인 작업·승인·대기 메시지를 모두 끝낸 뒤 초기화하세요.", "settings.resetPcUnmanaged": "설치된 Windows 호스트에서만 PC 데이터를 초기화할 수 있습니다.", "settings.resetPcFailed": "PC 데이터를 안전하게 초기화하지 못했습니다. Backend가 복구 후 다시 시작되면 재시도하세요.", "settings.resetPcScheduledTitle": "PC 초기화 준비 완료", "settings.resetPcScheduled": "Backend를 다시 시작하고 있습니다. 이 기기를 다시 연결해야 합니다.", "settings.reconnectPc": "다시 연결"
});
Object.assign(messages.en, { "settings.dataReset": "Data reset" });
Object.assign(messages.ko, { "settings.dataReset": "\uB370\uC774\uD130 \uCD08\uAE30\uD654" });
Object.assign(messages.en, {
  "usage.resetAvailableCount": "Can reset {count} times", "usage.tokenTooltip": "{period} · {count} tokens", "usage.weekOf": "Week of {date}", "usage.cumulativeThroughWeek": "Cumulative through week of {date}"
});
Object.assign(messages.ko, {
  "usage.resetAvailableCount": "\uCD08\uAE30\uD654 {count}\uD68C \uAC00\uB2A5", "usage.tokenTooltip": "{period} \uD1A0\uD070 {count}", "usage.weekOf": "{date}\uC8FC", "usage.cumulativeThroughWeek": "{date}\uC8FC\uAE4C\uC9C0 \uB204\uC801"
});

Object.assign(messages.en, {
  "chats.backToChats": "Back to chats", "chats.backToProjects": "Back to projects", "chats.projects": "Projects", "chats.noProjectChats": "No chats in this project.", "chats.pinned": "Pinned", "chats.archived": "Archived chats", "chats.recent": "Recent chats", "chats.searchResults": "Search results", "chats.loading": "Loading chats...", "chats.retry": "Retry", "chats.noMatches": "No matching chats.", "chats.noArchived": "No archived chats.", "chats.empty": "No chats yet.", "chats.loadMore": "Load more", "chats.expandProject": "Expand project", "chats.collapseProject": "Collapse project", "chats.unpin": "Unpin", "chats.pin": "Pin to top", "chats.rename": "Rename", "chats.archive": "Archive", "chats.delete": "Delete", "chats.renamePrompt": "Chat name", "chats.deleteConfirm": "Delete this archived chat from Code Remote Manager? Uploaded images for this chat will be removed.", "chats.messageProject": "Message this project", "chats.newChatMessage": "New chat message", "chats.sendCreate": "Send and create chat", "chats.search": "Search chats", "chats.new": "New chat",
  "newChat.back": "Back to chats", "newChat.title": "Choose a project folder", "newChat.description": "Create or select a folder on this PC for Codex to work in.", "newChat.note": "Projects root lists only direct child folders; workspaces are the folders already allowed for Codex runs.", "newChat.search": "Search projects", "newChat.starting": "Starting...", "newChat.newProject": "New project", "newChat.withoutProject": "Chat without a project", "newChat.folderName": "Project folder name", "newChat.create": "Create", "newChat.none": "No direct child project folders found.", "newChat.prompt": "What will you build?", "newChat.promptBefore": "What will you build?", "newChat.promptAfter": "", "newChat.chooseProject": "Choose a project", "newChat.message": "Message Codex",
  "conversation.back": "Back to chats", "conversation.empty": "Send a message to start this chat.", "conversation.workspaceRequired": "Choose an allowlisted project before sending.", "conversation.attachProject": "Project to attach", "conversation.selectProject": "Select project", "conversation.attach": "Attach workspace", "conversation.plan": "Plan", "conversation.attachedImage": "Attached image", "conversation.attachmentDeleted": "Local image deleted", "conversation.image": "Image", "conversation.uploading": "Uploading attachment", "conversation.uploadPartial": "{count} image(s) could not be uploaded. The successful images were kept.", "conversation.removeImage": "Remove {name}", "conversation.stopVoice": "Stop voice input", "conversation.message": "Message Codex", "conversation.startVoice": "Start voice input", "conversation.voicePermissionDenied": "Allow microphone access to use voice input.", "conversation.voiceUnavailable": "The microphone is unavailable.", "conversation.voiceFailed": "Voice input could not start. Try again.", "conversation.stop": "Stop", "conversation.send": "Send",
  "notification.open": "Open", "notification.confirm": "Confirm", "notification.openNotifications": "Open notifications", "notification.title": "Notifications", "notification.clear": "Clear all", "notification.empty": "No notifications", "notification.activeTitle": "In progress", "notification.alertsTitle": "Alerts", "notification.untitledChat": "New chat", "notification.openFailed": "Could not open notification. Try again.", "notification.sessionsRefreshFailed": "Chat status could not refresh.", "notification.usageRefreshFailed": "{account} usage could not refresh.", "notification.type.approval": "Approval needed", "notification.type.completed": "Response complete", "notification.type.failed": "Work failed", "notification.type.interrupted": "Work stopped", "notification.type.usage-critical": "Usage critical", "notification.type.usage-exhausted": "Usage exhausted", "notification.type.usage-low": "Usage low", "notification.type.weekly-reset": "Weekly usage reset", "notification.unknownProject": "Unknown project", "notification.remaining": "{percent}% remaining", "notification.available": "{percent}% available", "notification.limitRemaining": "{window} limit {percent}% remaining",
  "transition.opening": "Opening chat", "transition.failed": "Could not open chat", "transition.requestFailed": "Request failed.",
  "approval.resolving": "Resolving", "approval.reject": "Reject", "approval.approve": "Approve",
  "changes.title": "Changed files", "changes.refresh": "Refresh", "changes.notRepository": "Selected workspace is not a Git repository.", "changes.empty": "No changes yet.", "changes.diffFor": "Diff for {path}",
  "status.usage": "Usage status", "status.weekly": "Weekly", "status.context": "Context", "status.loading": "Loading...", "status.lastAccount": "Last chat account", "connection.unavailable": "Could not connect to the PC. Check Tailscale and the Windows host."
});

Object.assign(messages.ko, {
  "chats.backToChats": "채팅으로 돌아가기", "chats.backToProjects": "프로젝트로 돌아가기", "chats.projects": "프로젝트", "chats.noProjectChats": "이 프로젝트에 채팅이 없습니다.", "chats.pinned": "고정됨", "chats.archived": "보관된 채팅", "chats.recent": "최근 채팅", "chats.searchResults": "검색 결과", "chats.loading": "채팅 불러오는 중...", "chats.retry": "다시 시도", "chats.noMatches": "일치하는 채팅이 없습니다.", "chats.noArchived": "보관된 채팅이 없습니다.", "chats.empty": "아직 채팅이 없습니다.", "chats.loadMore": "더 보기", "chats.expandProject": "프로젝트 펼치기", "chats.collapseProject": "프로젝트 접기", "chats.unpin": "고정 해제", "chats.pin": "맨 위에 고정", "chats.rename": "이름 바꾸기", "chats.archive": "보관", "chats.delete": "삭제", "chats.renamePrompt": "채팅 이름", "chats.deleteConfirm": "Code Remote Manager에서 이 보관 채팅을 삭제할까요? 이 채팅에 업로드한 이미지는 제거됩니다.", "chats.messageProject": "이 프로젝트에 메시지 보내기", "chats.newChatMessage": "새 채팅 메시지", "chats.sendCreate": "전송하고 채팅 만들기", "chats.search": "채팅 검색", "chats.new": "새 채팅",
  "newChat.back": "채팅으로 돌아가기", "newChat.title": "프로젝트 폴더 선택", "newChat.description": "Codex가 작업할 이 PC의 폴더를 만들거나 선택하세요.", "newChat.note": "프로젝트 루트에는 바로 아래 폴더만 표시됩니다. 작업공간은 이미 Codex 실행이 허용된 폴더입니다.", "newChat.search": "프로젝트 검색", "newChat.starting": "시작 중...", "newChat.newProject": "새 프로젝트", "newChat.withoutProject": "프로젝트 없이 채팅하기", "newChat.folderName": "프로젝트 폴더 이름", "newChat.create": "만들기", "newChat.none": "바로 아래 프로젝트 폴더를 찾지 못했습니다.", "newChat.prompt": "무엇을 만들까요?", "newChat.promptBefore": "무엇을 빌드할까요?", "newChat.promptAfter": "", "newChat.chooseProject": "프로젝트 선택", "newChat.message": "Codex에 메시지 보내기",
  "conversation.back": "채팅으로 돌아가기", "conversation.empty": "메시지를 보내 채팅을 시작하세요.", "conversation.workspaceRequired": "전송하기 전에 허용된 프로젝트를 선택하세요.", "conversation.attachProject": "연결할 프로젝트", "conversation.selectProject": "프로젝트 선택", "conversation.attach": "작업공간 연결", "conversation.plan": "계획", "conversation.attachedImage": "첨부한 이미지", "conversation.attachmentDeleted": "로컬 이미지 삭제됨", "conversation.image": "이미지", "conversation.uploading": "첨부 파일 업로드 중", "conversation.uploadPartial": "이미지 {count}개를 업로드하지 못했습니다. 성공한 이미지는 유지했습니다.", "conversation.removeImage": "{name} 제거", "conversation.stopVoice": "음성 입력 중지", "conversation.message": "Codex에 메시지 보내기", "conversation.startVoice": "음성 입력 시작", "conversation.voicePermissionDenied": "음성 입력을 사용하려면 마이크 권한을 허용하세요.", "conversation.voiceUnavailable": "마이크를 사용할 수 없습니다.", "conversation.voiceFailed": "음성 입력을 시작하지 못했습니다. 다시 시도하세요.", "conversation.stop": "중지", "conversation.send": "전송",
  "notification.open": "열기", "notification.confirm": "확인", "notification.openNotifications": "알림 열기", "notification.title": "알림", "notification.clear": "모두 확인", "notification.empty": "알림 없음", "notification.activeTitle": "진행 중", "notification.alertsTitle": "알림", "notification.untitledChat": "새 채팅", "notification.openFailed": "알림을 열지 못했습니다. 다시 시도하세요.", "notification.sessionsRefreshFailed": "채팅 상태를 새로 고치지 못했습니다.", "notification.usageRefreshFailed": "{account} 계정의 사용량을 새로 고치지 못했습니다.", "notification.type.approval": "승인 필요", "notification.type.completed": "응답 완료", "notification.type.failed": "작업 실패", "notification.type.interrupted": "작업 중지됨", "notification.type.usage-critical": "한도 위험", "notification.type.usage-exhausted": "한도 소진", "notification.type.usage-low": "한도 낮음", "notification.type.weekly-reset": "주간 한도 갱신", "notification.unknownProject": "알 수 없는 프로젝트", "notification.remaining": "{percent}% 남음", "notification.available": "{percent}% 사용 가능", "notification.limitRemaining": "{window} 한도 {percent}% 남음",
  "transition.opening": "채팅 여는 중", "transition.failed": "채팅을 열지 못했습니다", "transition.requestFailed": "요청에 실패했습니다.",
  "approval.resolving": "처리 중", "approval.reject": "거절", "approval.approve": "승인",
  "changes.title": "변경된 파일", "changes.refresh": "새로 고침", "changes.notRepository": "선택한 작업공간은 Git 저장소가 아닙니다.", "changes.empty": "아직 변경 사항이 없습니다.", "changes.diffFor": "{path} 변경 내용",
  "status.usage": "사용량 상태", "status.weekly": "주간", "status.context": "컨텍스트", "status.loading": "불러오는 중...", "status.lastAccount": "마지막 채팅 계정", "connection.unavailable": "PC에 연결할 수 없습니다. Tailscale과 Windows 호스트를 확인하세요."
});

Object.assign(messages.en, {
  "composer.modelAndEffort": "Model and reasoning effort", "composer.model": "Model", "composer.reasoningEffort": "Reasoning effort", "composer.defaultModel": "Default model", "composer.permissions": "Permissions", "composer.customPermissions": "Custom permissions", "composer.approvalMode": "Approval mode", "composer.fileAccess": "File access", "composer.askWhenNeeded": "Ask when needed", "composer.askOnFailure": "Ask after failure", "composer.alwaysAsk": "Always ask", "composer.neverAsk": "Never ask", "composer.workspaceWrite": "Project write", "composer.readOnly": "Read only", "composer.fullAccess": "Full access", "composer.tools": "Composer tools", "composer.uploadImage": "Upload image", "composer.planMode": "Plan mode", "composer.plugins": "Plugins",
  "activity.completed": "Completed", "activity.failed": "Failed", "activity.interrupted": "Stopped", "activity.waitingApproval": "Waiting for approval", "activity.waitingResponse": "Waiting for response", "activity.running": "Working", "activity.thinking": "Thinking", "activity.log": "Work log ({count})", "activity.started": "Starting work", "activity.reasoning": "Thinking", "activity.command": "Command", "activity.fileChange": "File changes", "activity.tool": "Tool", "activity.filesChanged": "{count} files changed", "activity.commandsRun": "{count} commands run", "activity.toolsRun": "{count} tools run", "activity.toolCall": "Tool call", "activity.call": "Call", "activity.function": "Function", "activity.server": "Server", "activity.status": "Status", "activity.duration": "Duration", "activity.arguments": "Arguments", "activity.closeToolCall": "Close tool call", "activity.retry": "Retry", "conversation.sending": "Sending", "conversation.attachedImage": "Attached image"
});

Object.assign(messages.ko, {
  "composer.modelAndEffort": "모델 및 사고 수준", "composer.model": "모델", "composer.reasoningEffort": "사고 수준", "composer.defaultModel": "기본 모델", "composer.permissions": "권한", "composer.customPermissions": "사용자 지정", "composer.approvalMode": "검토 방식", "composer.fileAccess": "파일 접근", "composer.askWhenNeeded": "필요할 때 묻기", "composer.askOnFailure": "실패 후 묻기", "composer.alwaysAsk": "항상 묻기", "composer.neverAsk": "묻지 않기", "composer.workspaceWrite": "프로젝트 쓰기", "composer.readOnly": "읽기 전용", "composer.fullAccess": "전체 액세스", "composer.tools": "작성 도구", "composer.uploadImage": "사진 업로드", "composer.planMode": "계획 모드", "composer.plugins": "플러그인",
  "activity.completed": "완료", "activity.failed": "실패", "activity.interrupted": "중단", "activity.waitingApproval": "승인 대기", "activity.waitingResponse": "응답 대기", "activity.running": "작업 중", "activity.thinking": "생각 중", "activity.log": "작업 로그 ({count})", "activity.started": "작업 시작 중", "activity.reasoning": "생각 중", "activity.command": "명령 실행", "activity.fileChange": "파일 변경", "activity.tool": "도구", "activity.filesChanged": "파일 {count}개 변경됨", "activity.commandsRun": "명령 {count}개 실행", "activity.toolsRun": "도구 {count}개 실행", "activity.toolCall": "도구 호출", "activity.call": "호출", "activity.function": "함수", "activity.server": "서버", "activity.status": "상태", "activity.duration": "소요 시간", "activity.arguments": "인수", "activity.closeToolCall": "도구 호출 닫기", "activity.retry": "다시 시도", "conversation.sending": "전송 중", "conversation.attachedImage": "Attached image"
});

Object.assign(messages.en, {
  "composer.modelAndEffort": "Model and reasoning effort", "composer.model": "Model", "composer.reasoningEffort": "Reasoning effort", "composer.defaultModel": "Default model", "composer.effort.low": "Low", "composer.effort.medium": "Medium", "composer.effort.high": "High", "composer.effort.xhigh": "Extra high", "composer.effort.max": "Maximum", "composer.effort.ultra": "Ultra", "composer.permissions": "Permissions", "composer.customPermissions": "Custom permissions", "composer.approvalMode": "Approval mode", "composer.fileAccess": "File access", "composer.askWhenNeeded": "Ask when needed", "composer.askOnFailure": "Ask after failure", "composer.alwaysAsk": "Always ask", "composer.neverAsk": "Never ask", "composer.workspaceWrite": "Project write", "composer.readOnly": "Read only", "composer.fullAccess": "Full access", "composer.tools": "Composer tools", "composer.uploadImage": "Upload image", "composer.planMode": "Plan mode", "composer.plugins": "Plugins", "conversation.sending": "Sending", "conversation.attachedImage": "Attached image"
});
Object.assign(messages.ko, {
  "composer.modelAndEffort": "모델 및 사고 수준", "composer.model": "모델", "composer.reasoningEffort": "사고 수준", "composer.defaultModel": "기본 모델", "composer.effort.low": "Light", "composer.effort.medium": "Medium", "composer.effort.high": "High", "composer.effort.xhigh": "Extra high", "composer.effort.max": "Max", "composer.effort.ultra": "Ultra", "composer.permissions": "권한", "composer.customPermissions": "사용자 지정", "composer.approvalMode": "검토 방식", "composer.fileAccess": "파일 접근", "composer.askWhenNeeded": "필요할 때 묻기", "composer.askOnFailure": "실패 후 묻기", "composer.alwaysAsk": "항상 묻기", "composer.neverAsk": "묻지 않기", "composer.workspaceWrite": "프로젝트 쓰기", "composer.readOnly": "읽기 전용", "composer.fullAccess": "전체 액세스", "composer.tools": "작성 도구", "composer.uploadImage": "사진 업로드", "composer.planMode": "계획 모드", "composer.plugins": "플러그인", "conversation.sending": "전송 중", "conversation.attachedImage": "첨부된 이미지"
});

Object.assign(messages.ko, { "settings.dark": "\uB2E4\uD06C \uBAA8\uB4DC", "settings.light": "\uB77C\uC774\uD2B8 \uBAA8\uB4DC" });
Object.assign(messages.en, { "chats.showClassicView": "Show default view", "chats.showGroupedView": "Show project-grouped view" });
Object.assign(messages.ko, { "chats.showClassicView": "\uAE30\uBCF8 \uBCF4\uAE30\uB85C \uC804\uD658", "chats.showGroupedView": "\uD504\uB85C\uC81D\uD2B8\uBCC4 \uBCF4\uAE30\uB85C \uC804\uD658" });
Object.assign(messages.en, { "newChat.browseFolders": "Browse PC folders", "newChat.createFolder": "Create new folder", "newChat.createFolderHere": "New folder here", "newChat.confirmCreateFolder": "Create", "newChat.folderUp": "Back", "newChat.selectThisFolder": "Select this folder" });
Object.assign(messages.ko, { "newChat.browseFolders": "PC \uD3F4\uB354 \uCC3E\uAE30", "newChat.createFolder": "\uC0C8 \uD3F4\uB354 \uB9CC\uB4E4\uAE30", "newChat.createFolderHere": "\uD604\uC7AC \uC704\uCE58\uC5D0 \uC0C8 \uD3F4\uB354", "newChat.confirmCreateFolder": "\uB9CC\uB4E4\uAE30", "newChat.folderUp": "\uB4A4\uB85C", "newChat.selectThisFolder": "\uC774 \uD3F4\uB354 \uC120\uD0DD" });
Object.assign(messages.en, { "newChat.recentProjects": "Recent projects", "newChat.noRecentProjects": "No recent projects." });
Object.assign(messages.ko, { "newChat.recentProjects": "\uCD5C\uADFC \uD504\uB85C\uC81D\uD2B8", "newChat.noRecentProjects": "\uCD5C\uADFC \uD504\uB85C\uC81D\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." });
Object.assign(messages.en, {
  "composer.effort.low": "Light", "composer.effort.max": "Max",
  "composer.permission.readOnly": "Read only", "composer.permission.readOnly.description": "Inspect files and commands without editing.",
  "composer.permission.workspace": "Workspace", "composer.permission.workspace.description": "Write inside active workspace.",
  "composer.permission.fullAccess": "Full access", "composer.permission.fullAccess.description": "Remove local sandbox restrictions."
});
Object.assign(messages.ko, {
  "composer.effort.low": "Light", "composer.effort.max": "Max",
  "composer.permission.readOnly": "\uC77D\uAE30 \uC804\uC6A9", "composer.permission.readOnly.description": "\uD30C\uC77C\uACFC \uBA85\uB839\uC744 \uC218\uC815\uD558\uC9C0 \uC54A\uACE0 \uD655\uC778\uD569\uB2C8\uB2E4.",
  "composer.permission.workspace": "\uC791\uC5C5 \uACF5\uAC04", "composer.permission.workspace.description": "\uD604\uC7AC \uC791\uC5C5 \uACF5\uAC04 \uC548\uC5D0\uC11C\uB9CC \uC4F8 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
  "composer.permission.fullAccess": "\uC804\uCCB4 \uC561\uC138\uC2A4", "composer.permission.fullAccess.description": "\uB85C\uCEEC \uC0CC\uB4DC\uBC15\uC2A4 \uC81C\uD55C\uC744 \uC81C\uAC70\uD569\uB2C8\uB2E4."
});
Object.assign(messages.en, { "conversation.showEarlier": "Show earlier messages" });
Object.assign(messages.ko, { "conversation.showEarlier": "\uC774\uC804 \uB300\uD654 \uBCF4\uAE30" });
Object.assign(messages.en, { "conversation.scrollToLatest": "Go to latest message" });
Object.assign(messages.ko, { "conversation.scrollToLatest": "최신 메시지로 이동" });
Object.assign(messages.en, { "notification.count": "{count} notifications" });
Object.assign(messages.ko, { "notification.count": "\uC0C8 \uC54C\uB9BC {count}\uAC1C" });
Object.assign(messages.en, { "notification.otherChatAlerts": "{count} alerts" });
Object.assign(messages.ko, { "notification.otherChatAlerts": "알림 {count}개" });
Object.assign(messages.en, { "startup.restoring": "Getting your workspace ready" });
Object.assign(messages.ko, { "startup.restoring": "\uC791\uC5C5 \uACF5\uAC04\uC744 \uC900\uBE44\uD558\uACE0 \uC788\uC5B4\uC694" });
Object.assign(messages.en, {
  "connection.title": "Connect to your PC", "connection.description": "Enter the private Tailscale address shown by Code Remote Manager on your PC.", "connection.address": "PC address", "connection.connect": "Connect", "connection.connecting": "Connecting...", "connection.unreachable": "Could not reach Code Remote Manager. Check the address, Tailscale, and the PC app.", "connection.httpsRequired": "Use the secure HTTPS Tailscale address.", "connection.note": "Only the server address is stored on this device."
});
Object.assign(messages.ko, {
  "connection.title": "PC\uC5D0 \uC5F0\uACB0", "connection.description": "PC\uC758 Code Remote Manager\uC5D0 \uD45C\uC2DC\uB41C \uBE44\uACF5\uAC1C Tailscale \uC8FC\uC18C\uB97C \uC785\uB825\uD558\uC138\uC694.", "connection.address": "PC \uC8FC\uC18C", "connection.connect": "\uC5F0\uACB0", "connection.connecting": "\uC5F0\uACB0 \uC911...", "connection.unreachable": "Code Remote Manager\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC8FC\uC18C, Tailscale, PC \uC571\uC744 \uD655\uC778\uD558\uC138\uC694.", "connection.httpsRequired": "\uBCF4\uC548 HTTPS Tailscale \uC8FC\uC18C\uB97C \uC0AC\uC6A9\uD558\uC138\uC694.", "connection.note": "\uC774 \uAE30\uAE30\uC5D0\uB294 \uC11C\uBC84 \uC8FC\uC18C\uB9CC \uC800\uC7A5\uB429\uB2C8\uB2E4."
});
Object.assign(messages.en, { "settings.pcConnection": "PC connection", "settings.changePc": "Change PC" });
Object.assign(messages.ko, { "settings.pcConnection": "PC \uC5F0\uACB0", "settings.changePc": "PC \uBCC0\uACBD" });
Object.assign(messages.en, { "settings.pcManagement": "PC management", "settings.removePc": "Remove current PC", "settings.removePcConfirm": "Remove the current PC from this app? You will need to connect again." });
Object.assign(messages.ko, { "settings.pcManagement": "PC 관리", "settings.removePc": "현재 PC 삭제", "settings.removePcConfirm": "이 앱에서 현재 PC 정보를 삭제할까요? 다시 연결해야 합니다." });
Object.assign(messages.en, { "settings.pcDefaultName": "Windows PC", "settings.pcChecking": "Checking connection…", "settings.pcOnline": "Connected", "settings.pcOffline": "Not connected", "settings.pcLastChecked": "Last checked: {time}" });
Object.assign(messages.ko, { "settings.pcDefaultName": "Windows PC", "settings.pcChecking": "연결 확인 중…", "settings.pcOnline": "연결됨", "settings.pcOffline": "연결 안 됨", "settings.pcLastChecked": "마지막 확인: {time}" });
Object.assign(messages.en, { "settings.legalSupport": "Legal and support", "settings.contactEmail": "Contact email", "settings.officialWebsite": "Official website", "settings.privacyPolicy": "Privacy policy", "settings.termsOfService": "Terms of service", "settings.supportPage": "Support", "settings.dataDeletion": "Data deletion", "settings.openSourceLicenses": "Open-source licenses", "settings.contactWarning": "Never email passwords, API keys, tokens, full logs, authentication files, or real project files." });
Object.assign(messages.ko, { "settings.legalSupport": "법률 및 지원", "settings.contactEmail": "문의 이메일", "settings.officialWebsite": "공식 웹사이트", "settings.privacyPolicy": "개인정보처리방침", "settings.termsOfService": "이용약관", "settings.supportPage": "지원 및 문의", "settings.dataDeletion": "데이터 삭제", "settings.openSourceLicenses": "오픈소스 라이선스", "settings.contactWarning": "비밀번호, API 키, 토큰, 전체 로그, 인증 파일 또는 실제 프로젝트 파일을 이메일로 보내지 마세요." });
Object.assign(messages.en, { "settings.policyEffectiveDate": "Policy effective date" });
Object.assign(messages.ko, { "settings.policyEffectiveDate": "정책 시행일" });
Object.assign(messages.en, { "settings.privacy": "Privacy", "settings.accountManagement": "Account management", "settings.accountDisplay": "Account display", "settings.accountMosaic": "Mosaic account address", "settings.conversationAccountVisible": "Show last chat account" });
Object.assign(messages.ko, { "settings.privacy": "\uAC1C\uC778\uC815\uBCF4", "settings.accountManagement": "\uACC4\uC815 \uAD00\uB9AC", "settings.accountDisplay": "\uACC4\uC815 \uD45C\uC2DC", "settings.accountMosaic": "\uACC4\uC815 \uC8FC\uC18C \uBAA8\uC790\uC774\uD06C", "settings.conversationAccountVisible": "\uB9C8\uC9C0\uB9C9 \uCC44\uD305 \uACC4\uC815 \uD45C\uC2DC" });
Object.assign(messages.en, {
  "dialog.cancel": "Cancel", "dialog.close": "Close",
  "context.resetDialogTitle": "Use a reset credit?", "context.useOneResetCredit": "Use 1 credit", "context.resetCompleteTitle": "Usage reset", "context.resetComplete": "One reset credit was used successfully.", "context.resetUnavailableTitle": "Could not reset usage",
  "settings.thisDevice": "This device", "settings.resetThisDevice": "Reset this device data", "settings.resetThisDeviceTitle": "Reset this device?", "settings.resetThisDeviceDescription": "This removes Code Remote Manager data saved on this device and disconnects it from the PC.", "settings.resetThisDeviceConfirm": "Reset this device", "settings.resettingThisDevice": "Resetting…", "settings.resetDeletesTitle": "Removed from this device", "settings.resetDeletesConnection": "PC address and this device's authentication", "settings.resetDeletesSelections": "Selected account, project, chat, and drafts", "settings.resetDeletesPreferences": "Theme, language, composer, and notification settings", "settings.resetDeletesTemporary": "Notifications, previews, and app caches", "settings.resetKeepsTitle": "Kept on the PC", "settings.resetKeepsPcData": "Codex chats, attachments, settings, login, and backups", "settings.resetKeepsAccounts": "OpenAI and Tailscale accounts are not deleted", "settings.resetThisDeviceFailed": "Could not disconnect this device from the PC. Nothing stored locally was deleted; try again.", "settings.resetThisDeviceIncomplete": "The PC connection was removed, but some local app data could not be cleared. Close and reopen the app."
});
Object.assign(messages.ko, {
  "dialog.cancel": "취소", "dialog.close": "닫기",
  "context.resetDialogTitle": "초기화권을 사용할까요?", "context.useOneResetCredit": "초기화권 1개 사용", "context.resetCompleteTitle": "사용량 초기화 완료", "context.resetComplete": "초기화권 1개를 사용했습니다.", "context.resetUnavailableTitle": "사용량을 초기화하지 못했습니다",
  "settings.thisDevice": "이 기기", "settings.resetThisDevice": "이 기기 데이터 초기화", "settings.resetThisDeviceTitle": "이 기기를 초기화할까요?", "settings.resetThisDeviceDescription": "이 기기에 저장된 Code Remote Manager 데이터와 PC 연결을 삭제합니다.", "settings.resetThisDeviceConfirm": "이 기기 초기화", "settings.resettingThisDevice": "초기화 중…", "settings.resetDeletesTitle": "이 기기에서 삭제", "settings.resetDeletesConnection": "PC 주소와 이 기기의 인증 정보", "settings.resetDeletesSelections": "선택한 계정·프로젝트·채팅과 작성 중인 내용", "settings.resetDeletesPreferences": "테마·언어·작성·알림 설정", "settings.resetDeletesTemporary": "알림·미리보기·앱 임시 캐시", "settings.resetKeepsTitle": "PC에는 그대로 유지", "settings.resetKeepsPcData": "Codex 채팅·첨부파일·설정·로그인·백업", "settings.resetKeepsAccounts": "OpenAI와 Tailscale 계정은 삭제하지 않음", "settings.resetThisDeviceFailed": "PC에서 이 기기 연결을 끊지 못했습니다. 휴대폰 데이터도 삭제하지 않았으니 다시 시도하세요.", "settings.resetThisDeviceIncomplete": "PC 연결은 삭제했지만 일부 휴대폰 데이터를 지우지 못했습니다. 앱을 완전히 닫았다가 다시 여세요."
});
Object.assign(messages.en, { "connection.deviceOffline": "This phone is offline. Reconnect to Wi-Fi or mobile data.", "connection.recovering": "Connection restored. Reconnecting to the PC…" });
Object.assign(messages.ko, { "connection.deviceOffline": "휴대폰이 오프라인입니다. Wi-Fi 또는 모바일 데이터에 다시 연결하세요.", "connection.recovering": "네트워크가 복구되어 PC에 다시 연결하는 중입니다…" });
Object.assign(messages.en, { "connection.pcUnreachable": "Could not reach the PC. Check Tailscale and Code Remote Manager on Windows.", "connection.codexLoginRequired": "Codex login expired. Reconnect the Codex account on the PC." });
Object.assign(messages.ko, { "connection.pcUnreachable": "PC에 연결할 수 없습니다. Tailscale과 Windows의 Code Remote Manager를 확인하세요.", "connection.codexLoginRequired": "Codex 로그인이 만료되었습니다. PC에서 Codex 계정을 다시 연결하세요." });
Object.assign(messages.en, { "composer.modelPickerTitle": "Select model", "composer.closeModelPicker": "Close model picker" });
Object.assign(messages.ko, { "composer.modelPickerTitle": "\uBAA8\uB378 \uC120\uD0DD", "composer.closeModelPicker": "\uBAA8\uB378 \uC120\uD0DD \uB2EB\uAE30" });

Object.assign(messages.en, {
  "composer.preset.default": "Default permissions", "composer.preset.default.description": "Run commands in the sandbox.",
  "composer.preset.auto-review": "Auto review", "composer.preset.auto-review.description": "Review elevated permission requests automatically.",
  "composer.preset.read-only": "Read only", "composer.preset.read-only.description": "Approval is required to edit files or run commands.",
  "composer.preset.full-access": "Full access", "composer.preset.full-access.description": "Access the entire computer (higher risk).",
  "changes.close": "Close changes", "changes.loadingDiffs": "Loading changes…", "changes.diffLoadFailed": "Could not load this file's changes.",
  "changes.unavailable.diff_too_large": "This file is too large to show its diff on a phone. Check it on your PC.",
  "changes.unavailable.binary_file": "Binary files do not have a displayable diff.", "changes.unavailable.untracked_file": "Untracked files do not have a displayable diff.",
  "changes.unavailable.changed_file_not_found": "The saved change snapshot could not be found.", "status.none": "None"
});
Object.assign(messages.ko, {
  "composer.preset.default": "기본 권한", "composer.preset.default.description": "샌드박스에서 명령을 실행합니다.",
  "composer.preset.auto-review": "자동 검토", "composer.preset.auto-review.description": "권한 상승 요청을 자동으로 검토합니다.",
  "composer.preset.read-only": "읽기 전용", "composer.preset.read-only.description": "파일을 편집하거나 명령을 실행하려면 승인이 필요합니다.",
  "composer.preset.full-access": "전체 액세스", "composer.preset.full-access.description": "컴퓨터 전체에 접근합니다 (위험 높음).",
  "changes.close": "변경 내용 닫기", "changes.loadingDiffs": "변경 내용을 불러오는 중…", "changes.diffLoadFailed": "이 파일의 변경 내용을 불러오지 못했습니다.",
  "changes.unavailable.diff_too_large": "파일이 너무 커서 휴대폰에서 diff를 표시하지 않습니다. PC에서 확인해 주세요.",
  "changes.unavailable.binary_file": "바이너리 파일은 diff를 표시하지 않습니다.", "changes.unavailable.untracked_file": "추적되지 않은 파일은 diff를 표시할 수 없습니다.",
  "changes.unavailable.changed_file_not_found": "저장된 변경 스냅샷을 찾지 못했습니다.", "status.none": "없음"
});
Object.assign(messages.en, {
  "conversation.queuedMessages": "Queued messages", "conversation.queuedActions": "Queued message actions", "conversation.editMessage": "Edit message",
  "conversation.steering": "Steering…", "conversation.sendAsSteer": "Send as steer", "conversation.canceling": "Canceling…", "conversation.cancelMessage": "Cancel message",
  "conversation.copy": "Copy", "conversation.copyMessage": "Copy message", "conversation.copied": "Copied", "conversation.queueing": "Queueing", "conversation.stopping": "Stopping"
});
Object.assign(messages.ko, {
  "conversation.queuedMessages": "대기 중인 메시지", "conversation.queuedActions": "대기 중인 메시지 작업", "conversation.editMessage": "메시지 수정",
  "conversation.steering": "지시 전송 중…", "conversation.sendAsSteer": "지시로 전송", "conversation.canceling": "취소 중…", "conversation.cancelMessage": "메시지 취소",
  "conversation.copy": "복사", "conversation.copyMessage": "메시지 복사", "conversation.copied": "복사됨", "conversation.queueing": "대기열에 추가 중", "conversation.stopping": "중지 중"
});
Object.assign(messages.en, {
  "context.chat.noSelection": "No chat selected", "context.chat.starting": "Starting", "context.chat.answering": "Answering",
  "context.chat.waitingApproval": "Waiting for approval", "context.chat.waitingResponse": "Waiting for response",
  "context.chat.complete": "Answer complete", "context.chat.failed": "Answer failed", "context.chat.interrupted": "Interrupted",
  "context.chat.ready": "Ready", "context.project.unknown": "No project", "context.chat.none": "No recent chat"
});
Object.assign(messages.ko, {
  "context.chat.noSelection": "\uC120\uD0DD\uD55C \uCC44\uD305 \uC5C6\uC74C", "context.chat.starting": "\uC2DC\uC791 \uC911", "context.chat.answering": "\uB2F5\uBCC0 \uC911",
  "context.chat.waitingApproval": "\uC2B9\uC778 \uB300\uAE30 \uC911", "context.chat.waitingResponse": "\uC751\uB2F5 \uB300\uAE30 \uC911",
  "context.chat.complete": "\uB2F5\uBCC0 \uC644\uB8CC", "context.chat.failed": "\uB2F5\uBCC0 \uC2E4\uD328", "context.chat.interrupted": "\uC911\uB2E8\uB428",
  "context.chat.ready": "\uC900\uBE44\uB428", "context.project.unknown": "\uD504\uB85C\uC81D\uD2B8 \uC5C6\uC74C", "context.chat.none": "\uCD5C\uADFC \uCC44\uD305 \uC5C6\uC74C"
});
Object.assign(messages.en, {
  "connection.scanQr": "Scan QR code", "connection.scanInstructions": "Scan the QR code shown by Code Remote Manager on your PC",
  "connection.orEnterAddress": "or enter the address", "connection.invalidQr": "This is not a valid Code Remote Manager PC QR code.",
  "connection.scanFailed": "QR scanning was cancelled or camera access is unavailable."
});
Object.assign(messages.ko, {
  "connection.scanQr": "QR 코드 스캔", "connection.scanInstructions": "PC의 Code Remote Manager에 표시된 QR 코드를 스캔하세요",
  "connection.orEnterAddress": "또는 주소 직접 입력", "connection.invalidQr": "올바른 Code Remote Manager PC QR 코드가 아닙니다.",
  "connection.scanFailed": "QR 스캔이 취소되었거나 카메라를 사용할 수 없습니다."
});

Object.assign(messages.en, {
  "gallery.title": "Image gallery", "gallery.open": "Open {name}", "gallery.close": "Close image gallery",
  "gallery.previous": "Previous image", "gallery.next": "Next image", "gallery.loadFailed": "Could not load this image."
});
Object.assign(messages.ko, {
  "gallery.title": "이미지 갤러리", "gallery.open": "{name} 크게 보기", "gallery.close": "이미지 갤러리 닫기",
  "gallery.previous": "이전 이미지", "gallery.next": "다음 이미지", "gallery.loadFailed": "이미지를 불러올 수 없습니다."
});

Object.assign(messages.en, { "chats.deleteTitle": "Delete archived chat", "chats.cancel": "Cancel", "chats.deleting": "Deleting..." });
Object.assign(messages.ko, { "chats.deleteTitle": "\uBCF4\uAD00 \uCC44\uD305 \uC0AD\uC81C", "chats.cancel": "\uCDE8\uC18C", "chats.deleting": "\uC0AD\uC81C \uC911..." });
Object.assign(messages.en, { "chats.hideProject": "Remove from projects" });
Object.assign(messages.ko, { "chats.hideProject": "\uBA54\uC778\uC5D0\uC11C \uC81C\uAC70" });
Object.assign(messages.en, {
  "artifact.htmlPreview": "Interactive HTML preview", "artifact.expand": "Expand", "artifact.close": "Close preview",
  "artifact.previewTitle": "Preview {name}"
});
Object.assign(messages.ko, {
  "artifact.htmlPreview": "\uC778\uD130\uB799\uD2F0\uBE0C HTML \uBBF8\uB9AC\uBCF4\uAE30", "artifact.expand": "\uD06C\uAC8C \uBCF4\uAE30", "artifact.close": "\uBBF8\uB9AC\uBCF4\uAE30 \uB2EB\uAE30",
  "artifact.previewTitle": "{name} \uBBF8\uB9AC\uBCF4\uAE30"
});

Object.assign(messages.en, {
  "approval.title.command": "Command approval required", "approval.title.fileChange": "File change approval required",
  "approval.title.permissions": "Additional permission required", "approval.title.generic": "Approval required",
  "approval.status.pending": "Pending approval", "approval.status.approved": "Approved", "approval.status.rejected": "Rejected", "approval.status.expired": "Expired",
  "approval.reason.command": "Codex requests permission to run this command.",
  "approval.reason.fileChange": "Codex requests permission to write outside the workspace.",
  "approval.reason.permissions": "Codex requests additional filesystem or network access.",
  "approval.reason.generic": "This action may install software, use the network, delete data, or access outside the workspace.",
  "approval.preview.commandUnavailable": "Command details unavailable", "approval.preview.fileChange": "File change",
  "approval.preview.permissionsNetwork": "Network access", "approval.preview.permissionsFilesystem": "{count} filesystem permission(s)",
  "approval.preview.permissionsNetworkAndFilesystem": "Network access, {count} filesystem permission(s)",
  "approval.preview.permissionsAdditional": "Additional permissions"
});
Object.assign(messages.ko, {
  "approval.title.command": "\uBA85\uB839 \uC2E4\uD589 \uC2B9\uC778 \uD544\uC694", "approval.title.fileChange": "\uD30C\uC77C \uBCC0\uACBD \uC2B9\uC778 \uD544\uC694",
  "approval.title.permissions": "\uCD94\uAC00 \uAD8C\uD55C \uC2B9\uC778 \uD544\uC694", "approval.title.generic": "\uC2B9\uC778 \uD544\uC694",
  "approval.status.pending": "\uC2B9\uC778 \uB300\uAE30 \uC911", "approval.status.approved": "\uC2B9\uC778\uB428", "approval.status.rejected": "\uAC70\uC808\uB428", "approval.status.expired": "\uB9CC\uB8CC\uB428",
  "approval.reason.command": "Codex\uAC00 \uC774 \uBA85\uB839\uC744 \uC2E4\uD589\uD560 \uAD8C\uD55C\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4.",
  "approval.reason.fileChange": "Codex\uAC00 \uC791\uC5C5 \uACF5\uAC04 \uBC16\uC758 \uD30C\uC77C\uC744 \uBCC0\uACBD\uD560 \uAD8C\uD55C\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4.",
  "approval.reason.permissions": "Codex\uAC00 \uD30C\uC77C \uC2DC\uC2A4\uD15C \uB610\uB294 \uB124\uD2B8\uC6CC\uD06C\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAD8C\uD55C\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4.",
  "approval.reason.generic": "\uC774 \uC791\uC5C5\uC740 \uC18C\uD504\uD2B8\uC6E8\uC5B4 \uC124\uCE58, \uB124\uD2B8\uC6CC\uD06C \uC0AC\uC6A9, \uB370\uC774\uD130 \uC0AD\uC81C \uB610\uB294 \uC791\uC5C5 \uACF5\uAC04 \uBC16\uC758 \uC704\uCE58 \uC811\uADFC\uC744 \uD3EC\uD568\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
  "approval.preview.commandUnavailable": "\uBA85\uB839 \uC138\uBD80 \uC815\uBCF4\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", "approval.preview.fileChange": "\uD30C\uC77C \uBCC0\uACBD",
  "approval.preview.permissionsNetwork": "\uB124\uD2B8\uC6CC\uD06C \uC811\uADFC", "approval.preview.permissionsFilesystem": "\uD30C\uC77C \uC2DC\uC2A4\uD15C \uAD8C\uD55C {count}\uAC1C",
  "approval.preview.permissionsNetworkAndFilesystem": "\uB124\uD2B8\uC6CC\uD06C \uC811\uADFC, \uD30C\uC77C \uC2DC\uC2A4\uD15C \uAD8C\uD55C {count}\uAC1C",
  "approval.preview.permissionsAdditional": "\uCD94\uAC00 \uAD8C\uD55C"
});
Object.assign(messages.en, {
  "approval.approveOnce": "Approve once",
  "approval.approveSession": "Approve for session",
  "approval.approveAlways": "Always approve similar commands"
});
Object.assign(messages.ko, {
  "approval.approveOnce": "\uC774\uBC88\uB9CC \uC2B9\uC778",
  "approval.approveSession": "\uC774 \uC138\uC158 \uB3D9\uC548 \uC2B9\uC778",
  "approval.approveAlways": "\uBE44\uC2B7\uD55C \uBA85\uB839 \uD56D\uC0C1 \uC2B9\uC778"
});
Object.assign(messages.en, {
  "settings.usage": "Usage", "settings.viewUsage": "View usage", "usage.accountLimits": "Account limits",
    "usage.resetCredits": "Reset credits", "usage.resetCreditsCount": "Reset credits {count}", "usage.availableCredits": "Available", "usage.useResetCredit": "Use reset credit",
  "usage.refresh": "Refresh usage", "usage.unavailable": "Unavailable"
});
Object.assign(messages.ko, {
  "settings.usage": "사용량", "settings.viewUsage": "사용량 확인", "usage.accountLimits": "계정 사용 한도",
    "usage.resetCredits": "재설정 크레딧", "usage.resetCreditsCount": "재설정 크레딧 {count}", "usage.availableCredits": "사용 가능", "usage.useResetCredit": "재설정 크레딧 사용",
  "usage.refresh": "사용량 새로고침", "usage.unavailable": "사용할 수 없음"
});
Object.assign(messages.en, {
  "usage.fiveHour": "5h", "usage.limitTrend": "Limit usage trend", "usage.trendRange": "Trend range",
  "usage.threeHours": "3 hours", "usage.sixHours": "6 hours", "usage.twelveHours": "12 hours", "usage.oneDay": "1 day", "usage.threeDays": "3 days", "usage.sevenDays": "7 days", "usage.thirtyDays": "30 days", "usage.daysAgo": "{count} days ago", "usage.now": "Now",
  "usage.collectingHistory": "Collecting local history. The chart appears after usage changes are recorded.",
  "usage.historyUnavailable": "Usage history could not be loaded.", "usage.localHistoryNote": "Charts show locally recorded remaining-limit percentages, not token totals.", "usage.chartGestures": "Drag horizontally to move through time.", "usage.noDataInRange": "No recorded usage in this range",
  "usage.noAccounts": "No Codex account is connected."
  , "usage.dailyTokens": "Daily tokens", "usage.lastThirtyDays": "Last 30 days", "usage.selectDay": "Select a day to view token usage.", "usage.tokens": "tokens", "usage.weeklySummary": "Weekly summary", "usage.accountDetails": "Account details"
});
Object.assign(messages.ko, {
  "usage.fiveHour": "5시간", "usage.limitTrend": "한도 사용 추이", "usage.trendRange": "추이 기간",
  "usage.threeHours": "3시간", "usage.sixHours": "6시간", "usage.twelveHours": "12시간", "usage.oneDay": "1일", "usage.threeDays": "3일", "usage.sevenDays": "7일", "usage.thirtyDays": "30일", "usage.daysAgo": "{count}일 전", "usage.now": "현재",
  "usage.collectingHistory": "로컬 사용량 기록을 수집 중입니다. 사용량 변화가 기록되면 차트가 표시됩니다.",
  "usage.historyUnavailable": "사용량 기록을 불러오지 못했습니다.", "usage.localHistoryNote": "차트는 토큰 총량이 아니라 이 PC에 기록된 한도 잔여율을 보여줍니다.", "usage.chartGestures": "좌우로 드래그해 시간대를 이동할 수 있습니다.", "usage.noDataInRange": "이 구간에는 기록이 없습니다",
  "usage.noAccounts": "연결된 Codex 계정이 없습니다."
  , "usage.dailyTokens": "일별 토큰", "usage.lastThirtyDays": "최근 30일", "usage.selectDay": "날짜를 선택하면 토큰 사용량을 확인할 수 있습니다.", "usage.tokens": "토큰", "usage.weeklySummary": "주간 한도 요약", "usage.accountDetails": "계정별 상세"
});

Object.assign(messages.en, {
  "usage.trendsTitle": "Remaining-limit trends", "usage.trendExplainer": "Vertical axis: remaining limit (%). Higher means more usage is available.",
  "usage.fiveHourRemaining": "5h remaining", "usage.weeklyRemaining": "Weekly remaining",
  "usage.sort": "Sort", "usage.sortPrimary": "5h remaining",
  "usage.sortSecondary": "Weekly remaining", "usage.sortConfigured": "Registration", "usage.sortAscending": "Ascending", "usage.sortDescending": "Descending",
  "usage.earliestExpiry": "Earliest known expiry", "usage.expiryUnavailable": "Expiry details unavailable",
  "usage.daysLeft": "{count}d left", "usage.hoursLeft": "{count}h left", "usage.expired": "Expired"
});
Object.assign(messages.ko, {
  "usage.trendsTitle": "\uD55C\uB3C4 \uC794\uC5EC\uC728 \uCD94\uC774", "usage.trendExplainer": "\uC138\uB85C\uCD95: \uB0A8\uC740 \uD55C\uB3C4(%). \uB192\uC744\uC218\uB85D \uC0AC\uC6A9 \uC5EC\uC720\uAC00 \uD07D\uB2C8\uB2E4.",
  "usage.fiveHourRemaining": "5\uC2DC\uAC04 \uC794\uC5EC", "usage.weeklyRemaining": "\uC8FC\uAC04 \uC794\uC5EC",
  "usage.sort": "\uC815\uB82C", "usage.sortPrimary": "5\uC2DC\uAC04 \uC794\uC5EC",
  "usage.sortSecondary": "\uC8FC\uAC04 \uC794\uC5EC", "usage.sortConfigured": "\uB4F1\uB85D", "usage.sortAscending": "\uC624\uB984\uCC28\uC21C", "usage.sortDescending": "\uB0B4\uB9BC\uCC28\uC21C",
  "usage.earliestExpiry": "\uD655\uC778\uB41C \uAC00\uC7A5 \uBE60\uB978 \uB9CC\uB8CC", "usage.expiryUnavailable": "\uB9CC\uB8CC\uC77C \uC815\uBCF4 \uC5C6\uC74C",
  "usage.daysLeft": "{count}\uC77C \uB0A8\uC74C", "usage.hoursLeft": "{count}\uC2DC\uAC04 \uB0A8\uC74C", "usage.expired": "\uB9CC\uB8CC\uB428"
});

Object.assign(messages.en, {
  "conversation.accountHandoffTitle": "Switch account for this chat?",
  "conversation.accountHandoffDescription": "Your current conversation will continue after switching accounts.",
  "conversation.accountHandoffTokens": "The new account must reread the conversation from the beginning, so this request will use more input tokens than usual.",
  "conversation.accountHandoffCancel": "Cancel", "conversation.accountHandoffConfirm": "Switch and send", "conversation.accountFallback": "Unknown account"
});
Object.assign(messages.ko, {
  "conversation.accountHandoffTitle": "\uC774 \uCC44\uD305\uC758 \uACC4\uC815\uC744 \uBC14\uAFC0\uAE4C\uC694?",
  "conversation.accountHandoffDescription": "\uACC4\uC815\uC744 \uBC14\uAFD4\uB3C4 \uC9C0\uAE08 \uB300\uD654\uB294 \uADF8\uB300\uB85C \uC774\uC5B4\uC9D1\uB2C8\uB2E4.",
  "conversation.accountHandoffTokens": "\uC0C8 \uACC4\uC815\uC774 \uC774\uC804 \uB300\uD654 \uB0B4\uC6A9\uC744 \uCC98\uC74C\uBD80\uD130 \uB2E4\uC2DC \uC77D\uC5B4\uC57C \uD558\uBBC0\uB85C, \uC785\uB825 \uD1A0\uD070\uC744 \uD3C9\uC18C\uBCF4\uB2E4 \uB9CE\uC774 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.",
  "conversation.accountHandoffCancel": "\uCDE8\uC18C", "conversation.accountHandoffConfirm": "\uBC14\uAFB8\uACE0 \uBCF4\uB0B4\uAE30", "conversation.accountFallback": "\uC54C \uC218 \uC5C6\uB294 \uACC4\uC815"
});

Object.assign(messages.en, {
  "settings.notifications": "Notifications", "settings.manageNotifications": "Manage notifications",
  "notifications.permissionTitle": "Permission", "notifications.permissionDescription": "Allow this device to show alerts outside the app.",
  "notifications.permission.granted": "Notifications allowed", "notifications.permission.denied": "Notifications blocked in system settings", "notifications.permission.prompt": "Permission not granted", "notifications.permission.checking": "Checking permission…", "notifications.permission.unsupported": "System notifications are unavailable on this device",
  "notifications.allow": "Allow", "notifications.requesting": "Requesting…", "notifications.pushTitle": "Push notifications", "notifications.all": "All push notifications", "notifications.allDescription": "Pause or resume system alerts without changing the choices below.",
  "notifications.group.work": "Work", "notifications.group.usage": "Usage",
  "notifications.type.approval": "Approval needed", "notifications.type.approval.description": "A task is waiting for your approval.",
  "notifications.type.completed": "Response complete", "notifications.type.completed.description": "A response finishes in another chat.",
  "notifications.type.failed": "Work failed", "notifications.type.failed.description": "A task ends because of an error.",
  "notifications.type.interrupted": "Work stopped", "notifications.type.interrupted.description": "A running task is interrupted.",
  "notifications.type.usage-exhausted": "Usage exhausted", "notifications.type.usage-exhausted.description": "An account has no remaining usage.",
  "notifications.type.usage-critical": "Usage at 5%", "notifications.type.usage-critical.description": "A usage window falls to 5% remaining.",
  "notifications.type.usage-low": "Usage at 20%", "notifications.type.usage-low.description": "A usage window falls to 20% remaining.",
  "notifications.type.weekly-reset": "Weekly usage reset", "notifications.type.weekly-reset.description": "A weekly usage window resets.",
  "notifications.foregroundNote": "Alerts are detected while Code Remote Manager is connected to the PC. The in-app notification center continues to keep every alert."
});
Object.assign(messages.ko, {
  "settings.notifications": "\uC54C\uB9BC", "settings.manageNotifications": "\uC54C\uB9BC \uC124\uC815",
  "notifications.permissionTitle": "\uAD8C\uD55C", "notifications.permissionDescription": "\uC571 \uBC16\uC5D0\uC11C\uB3C4 \uC774 \uAE30\uAE30\uC5D0 \uC54C\uB9BC\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.",
  "notifications.permission.granted": "\uC54C\uB9BC \uD5C8\uC6A9\uB428", "notifications.permission.denied": "\uC2DC\uC2A4\uD15C \uC124\uC815\uC5D0\uC11C \uC54C\uB9BC\uC774 \uCC28\uB2E8\uB428", "notifications.permission.prompt": "\uC54C\uB9BC \uAD8C\uD55C\uC774 \uD544\uC694\uD568", "notifications.permission.checking": "\uAD8C\uD55C \uD655\uC778 \uC911\u2026", "notifications.permission.unsupported": "\uC774 \uAE30\uAE30\uC5D0\uC11C \uC2DC\uC2A4\uD15C \uC54C\uB9BC\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC74C",
  "notifications.allow": "\uD5C8\uC6A9", "notifications.requesting": "\uC694\uCCAD \uC911\u2026", "notifications.pushTitle": "\uD478\uC2DC \uC54C\uB9BC", "notifications.all": "\uC804\uCCB4 \uD478\uC2DC \uC54C\uB9BC", "notifications.allDescription": "\uC544\uB798 \uC120\uD0DD\uC740 \uC720\uC9C0\uD558\uACE0 \uC2DC\uC2A4\uD15C \uC54C\uB9BC\uB9CC \uC77C\uC2DC \uC911\uC9C0\uD569\uB2C8\uB2E4.",
  "notifications.group.work": "\uC791\uC5C5", "notifications.group.usage": "\uC0AC\uC6A9\uB7C9",
  "notifications.type.approval": "\uC2B9\uC778 \uD544\uC694", "notifications.type.approval.description": "\uC791\uC5C5\uC774 \uC2B9\uC778\uC744 \uAE30\uB2E4\uB9B4 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.completed": "\uC751\uB2F5 \uC644\uB8CC", "notifications.type.completed.description": "\uB2E4\uB978 \uCC44\uD305\uC758 \uC751\uB2F5\uC774 \uC644\uB8CC\uB420 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.failed": "\uC791\uC5C5 \uC2E4\uD328", "notifications.type.failed.description": "\uC624\uB958\uB85C \uC791\uC5C5\uC774 \uC885\uB8CC\uB420 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.interrupted": "\uC791\uC5C5 \uC911\uB2E8", "notifications.type.interrupted.description": "\uC9C4\uD589 \uC911\uC778 \uC791\uC5C5\uC774 \uC911\uB2E8\uB420 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.usage-exhausted": "\uC0AC\uC6A9\uB7C9 \uC18C\uC9C4", "notifications.type.usage-exhausted.description": "\uACC4\uC815\uC758 \uB0A8\uC740 \uC0AC\uC6A9\uB7C9\uC774 \uC5C6\uC744 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.usage-critical": "\uC0AC\uC6A9\uB7C9 5%", "notifications.type.usage-critical.description": "\uC0AC\uC6A9 \uD55C\uB3C4\uAC00 5% \uB0A8\uC558\uC744 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.usage-low": "\uC0AC\uC6A9\uB7C9 20%", "notifications.type.usage-low.description": "\uC0AC\uC6A9 \uD55C\uB3C4\uAC00 20% \uB0A8\uC558\uC744 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.type.weekly-reset": "\uC8FC\uAC04 \uC0AC\uC6A9\uB7C9 \uCD08\uAE30\uD654", "notifications.type.weekly-reset.description": "\uC8FC\uAC04 \uC0AC\uC6A9 \uD55C\uB3C4\uAC00 \uCD08\uAE30\uD654\uB420 \uB54C \uC54C\uB9BD\uB2C8\uB2E4.",
  "notifications.foregroundNote": "Code Remote Manager\uAC00 PC\uC640 \uC5F0\uACB0\uB41C \uB3D9\uC548 \uC54C\uB9BC \uC0C1\uD669\uC744 \uAC10\uC9C0\uD569\uB2C8\uB2E4. \uC571 \uB0B4 \uC54C\uB9BC\uCC3D\uC5D0\uB294 \uBAA8\uB4E0 \uC54C\uB9BC\uC774 \uACC4\uC18D \uBCF4\uAD00\uB429\uB2C8\uB2E4."
});

Object.assign(messages.en, {
  "composer.fullAccessConfirmTitle": "Allow full access?",
  "composer.fullAccessConfirmDescription": "Until you change this setting, tasks sent from this device can work beyond the current project. Individual actions may run without another prompt, depending on the review mode.",
  "composer.fullAccessScopeTitle": "This expands what Codex can do",
  "composer.fullAccessFiles": "Reach files elsewhere on this PC to read, change, upload, or delete them",
  "composer.fullAccessCommands": "Run terminal commands that can install software or change system settings",
  "composer.fullAccessConnections": "Connect to websites, send data, and use enabled plugins",
  "composer.fullAccessRisk": "A mistake or untrusted instruction could expose sensitive information or cause data loss.",
  "composer.fullAccessConfirm": "Allow full access"
});
Object.assign(messages.ko, {
  "composer.fullAccessConfirmTitle": "\uC804\uCCB4 \uC561\uC138\uC2A4\uB97C \uD5C8\uC6A9\uD560\uAE4C\uC694?",
  "composer.fullAccessConfirmDescription": "\uC774 \uC124\uC815\uC744 \uB2E4\uC2DC \uBC14\uAFC0 \uB54C\uAE4C\uC9C0, \uC774 \uAE30\uAE30\uC5D0\uC11C \uBCF4\uB0B4\uB294 \uC791\uC5C5\uC740 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC16\uAE4C\uC9C0 \uC791\uC5C5\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uAC80\uD1A0 \uBC29\uC2DD\uC5D0 \uB530\uB77C \uAC1C\uBCC4 \uC791\uC5C5\uC744 \uB2E4\uC2DC \uBB3B\uC9C0 \uC54A\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
  "composer.fullAccessScopeTitle": "Codex\uAC00 \uD560 \uC218 \uC788\uB294 \uC77C\uC774 \uB2E4\uC74C\uACFC \uAC19\uC774 \uB298\uC5B4\uB0A9\uB2C8\uB2E4",
  "composer.fullAccessFiles": "PC\uC758 \uB2E4\uB978 \uC704\uCE58\uC5D0 \uC788\uB294 \uD30C\uC77C\uC744 \uC77D\uACE0 \uC218\uC815\u00B7\uC5C5\uB85C\uB4DC\u00B7\uC0AD\uC81C",
  "composer.fullAccessCommands": "\uD504\uB85C\uADF8\uB7A8 \uC124\uCE58\uB098 \uC2DC\uC2A4\uD15C \uC124\uC815 \uBCC0\uACBD\uC774 \uAC00\uB2A5\uD55C \uD130\uBBF8\uB110 \uBA85\uB839 \uC2E4\uD589",
  "composer.fullAccessConnections": "\uC6F9\uC0AC\uC774\uD2B8 \uC811\uC18D, \uB370\uC774\uD130 \uC804\uC1A1, \uD65C\uC131\uD654\uB41C \uD50C\uB7EC\uADF8\uC778 \uC0AC\uC6A9",
  "composer.fullAccessRisk": "\uC2E4\uC218\uB098 \uC2E0\uB8B0\uD560 \uC218 \uC5C6\uB294 \uC9C0\uC2DC\uB85C \uBBFC\uAC10\uD55C \uC815\uBCF4\uAC00 \uB178\uCD9C\uB418\uAC70\uB098 \uB370\uC774\uD130\uAC00 \uC190\uC2E4\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
  "composer.fullAccessConfirm": "\uC804\uCCB4 \uC561\uC138\uC2A4 \uD5C8\uC6A9"
});

Object.assign(messages.en, { "notification.dismiss": "Dismiss notification" });
Object.assign(messages.ko, { "notification.dismiss": "\uC54C\uB9BC \uC9C0\uC6B0\uAE30" });

Object.assign(messages.en, {
  "pairing.checking": "Checking this device", "pairing.checkingDescription": "Confirming whether this device is already connected.",
  "pairing.title": "Connect this device", "pairing.description": "Scan the QR code shown by Code Remote Manager on the PC, or enter its one-time code.",
  "pairing.startOnPc": "Open Code Remote Manager on the PC and choose Pair a device first.", "pairing.scanQr": "Scan QR code",
  "pairing.scanInstructions": "Scan the pairing QR code shown on your PC", "pairing.orEnterCode": "or enter the code",
  "pairing.code": "One-time code", "pairing.connecting": "Connecting...", "pairing.connect": "Connect", "pairing.refresh": "Check again",
  "pairing.unreachable": "Could not reach the PC. Check the connection and try again.",
  "pairing.failed": "The code or QR has expired or is not valid. Start pairing again on the PC.",
  "pairing.note": "After connecting once, this device stays connected until it expires or you remove it."
});
Object.assign(messages.ko, {
  "pairing.checking": "\uC774 \uAE30\uAE30 \uD655\uC778 \uC911", "pairing.checkingDescription": "\uC774\uBBF8 \uC5F0\uACB0\uB41C \uAE30\uAE30\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC788\uC2B5\uB2C8\uB2E4.",
  "pairing.title": "\uC774 \uAE30\uAE30 \uC5F0\uACB0", "pairing.description": "PC\uC758 Code Remote Manager\uC5D0 \uD45C\uC2DC\uB41C QR\uC744 \uC2A4\uCE94\uD558\uAC70\uB098 \uC77C\uD68C\uC6A9 \uCF54\uB4DC\uB97C \uC785\uB825\uD558\uC138\uC694.",
  "pairing.startOnPc": "\uBA3C\uC800 PC\uC5D0\uC11C Code Remote Manager\uB97C \uC5F4\uACE0 '\uAE30\uAE30 \uC5F0\uACB0'\uC744 \uB204\uB974\uC138\uC694.", "pairing.scanQr": "QR \uC2A4\uCE94",
  "pairing.scanInstructions": "PC\uC5D0 \uD45C\uC2DC\uB41C \uD398\uC5B4\uB9C1 QR\uC744 \uC2A4\uCE94\uD558\uC138\uC694", "pairing.orEnterCode": "\uB610\uB294 \uCF54\uB4DC \uC785\uB825",
  "pairing.code": "\uC77C\uD68C\uC6A9 \uCF54\uB4DC", "pairing.connecting": "\uC5F0\uACB0 \uC911...", "pairing.connect": "\uC5F0\uACB0", "pairing.refresh": "\uB2E4\uC2DC \uD655\uC778",
  "pairing.unreachable": "PC\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.",
  "pairing.failed": "\uCF54\uB4DC\uB098 QR\uC774 \uB9CC\uB8CC\uB418\uC5C8\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. PC\uC5D0\uC11C \uB2E4\uC2DC \uC2DC\uC791\uD558\uC138\uC694.",
  "pairing.note": "\uD55C \uBC88 \uC5F0\uACB0\uD558\uBA74 \uB9CC\uB8CC\uB418\uAC70\uB098 PC\uC5D0\uC11C \uC81C\uAC70\uD560 \uB54C\uAE4C\uC9C0 \uACC4\uC18D \uC5F0\uACB0\uB429\uB2C8\uB2E4."
});

Object.assign(messages.en, {
  "conversation.modelChangedTitle": "Model changed",
  "conversation.modelChangedFromTo": "Changed the model from {from} to {to}.",
  "conversation.modelChangedPerformance": "Changing models during a chat may reduce performance.",
  "conversation.modelChangedCompaction": "Context may be compacted automatically."
});
Object.assign(messages.ko, {
  "conversation.modelChangedTitle": "\uBAA8\uB378 \uBCC0\uACBD",
  "conversation.modelChangedFromTo": "{from}\uC5D0\uC11C {to}\uB85C \uBAA8\uB378\uC744 \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.",
  "conversation.modelChangedPerformance": "\uB300\uD654 \uC911 \uBAA8\uB378\uC744 \uBCC0\uACBD\uD558\uBA74 \uC131\uB2A5\uC774 \uC800\uD558\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
  "conversation.modelChangedCompaction": "\uCEE8\uD14D\uC2A4\uD2B8\uAC00 \uC790\uB3D9\uC73C\uB85C \uC555\uCD95\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
});

Object.assign(messages.en, { "runtime.development": "Development", "runtime.windows": "Windows install", "runtime.native": "Mobile app" });
Object.assign(messages.ko, { "runtime.development": "\uAC1C\uBC1C\uC6A9", "runtime.windows": "Windows \uC124\uCE58\uBCF8", "runtime.native": "\uBAA8\uBC14\uC77C \uC571" });

Object.assign(messages.en, {
  "reviewDemo.start": "Try review demo", "reviewDemo.title": "Review demo", "reviewDemo.syntheticNotice": "Synthetic data only — no PC, account, or command access",
  "reviewDemo.exit": "Exit", "reviewDemo.navigation": "Review demo navigation", "reviewDemo.chats": "Chats", "reviewDemo.chat": "Synthetic chat",
  "reviewDemo.chatsDescription": "Open a sample conversation to inspect messages, streaming, and approval controls.", "reviewDemo.you": "You", "reviewDemo.responding": "Responding",
  "reviewDemo.approval": "Approval required", "reviewDemo.deny": "Deny", "reviewDemo.approve": "Approve", "reviewDemo.denied": "Denied", "reviewDemo.approved": "Approved",
  "reviewDemo.messagePlaceholder": "Message the synthetic assistant", "reviewDemo.send": "Send", "reviewDemo.usage": "Usage", "reviewDemo.usageDescription": "Sample values demonstrate the usage-status interface.",
  "reviewDemo.changes": "Changes", "reviewDemo.changesDescription": "Only synthetic project-relative paths and diffs are shown.", "reviewDemo.settings": "Settings", "reviewDemo.demoData": "Review demo data", "reviewDemo.reset": "Reset demo data"
});
Object.assign(messages.ko, {
  "reviewDemo.start": "\uC2EC\uC0AC\uC6A9 \uCCB4\uD5D8\uD558\uAE30", "reviewDemo.title": "\uC2EC\uC0AC\uC6A9 \uB370\uBAA8", "reviewDemo.syntheticNotice": "\uAC00\uC0C1 \uB370\uC774\uD130\uB9CC \uC0AC\uC6A9 \u2014 PC\u00B7\uACC4\uC815\u00B7\uBA85\uB839 \uC811\uADFC \uC5C6\uC74C",
  "reviewDemo.exit": "\uC885\uB8CC", "reviewDemo.navigation": "\uC2EC\uC0AC\uC6A9 \uB370\uBAA8 \uD0D0\uC0C9", "reviewDemo.chats": "\uCC44\uD305", "reviewDemo.chat": "\uAC00\uC0C1 \uCC44\uD305",
  "reviewDemo.chatsDescription": "\uC608\uC2DC \uB300\uD654\uC5D0\uC11C \uBA54\uC2DC\uC9C0\u00B7\uC2A4\uD2B8\uB9AC\uBC0D\u00B7\uC2B9\uC778 \uD654\uBA74\uC744 \uD655\uC778\uD558\uC138\uC694.", "reviewDemo.you": "\uB098", "reviewDemo.responding": "\uC751\uB2F5 \uC911",
  "reviewDemo.approval": "\uC2B9\uC778 \uD544\uC694", "reviewDemo.deny": "\uAC70\uBD80", "reviewDemo.approve": "\uC2B9\uC778", "reviewDemo.denied": "\uAC70\uBD80\uB428", "reviewDemo.approved": "\uC2B9\uC778\uB428",
  "reviewDemo.messagePlaceholder": "\uAC00\uC0C1 AI\uC5D0\uAC8C \uBA54\uC2DC\uC9C0", "reviewDemo.send": "\uBCF4\uB0B4\uAE30", "reviewDemo.usage": "\uC0AC\uC6A9\uB7C9", "reviewDemo.usageDescription": "\uC608\uC2DC \uAC12\uC73C\uB85C \uC0AC\uC6A9\uB7C9 \uD654\uBA74\uC744 \uBCF4\uC5EC\uC90D\uB2C8\uB2E4.",
  "reviewDemo.changes": "\uBCC0\uACBD", "reviewDemo.changesDescription": "\uAC00\uC0C1 \uD504\uB85C\uC81D\uD2B8\uC758 \uC0C1\uB300 \uACBD\uB85C\uC640 diff\uB9CC \uD45C\uC2DC\uD569\uB2C8\uB2E4.", "reviewDemo.settings": "\uC124\uC815", "reviewDemo.demoData": "\uC2EC\uC0AC\uC6A9 \uB370\uBAA8 \uB370\uC774\uD130", "reviewDemo.reset": "\uB370\uBAA8 \uB370\uC774\uD130 \uCD08\uAE30\uD654"
});

export function detectLanguage(locale = globalThis.navigator?.language) { return String(locale ?? "").toLowerCase().startsWith("ko") ? "ko" : "en"; }
export function readSavedLanguage(storage = globalThis.localStorage) { try { const language = storage?.getItem(LANGUAGE_STORAGE_KEY); return SUPPORTED_LANGUAGES.has(language) ? language : null; } catch { return null; } }
export function defaultLanguage(storage = globalThis.localStorage) { return readSavedLanguage(storage) ?? "en"; }
export function currentLanguage() { return typeof document === "undefined" ? "en" : defaultLanguage(); }
export function writeSavedLanguage(storage = globalThis.localStorage, language) { if (!storage || !SUPPORTED_LANGUAGES.has(language)) return; try { storage.setItem(LANGUAGE_STORAGE_KEY, language); } catch {} }
export function translate(language, key, values = {}) { const text = messages[SUPPORTED_LANGUAGES.has(language) ? language : "en"][key] ?? messages.en[key] ?? key; return text.replace(/\{(\w+)\}/g, (_, name) => String(values[name] ?? "")); }
