chore: move i18n to shared package (#1066)

* chore: move i18n to shared package

* chore: move server translations to shared package and apply linter and prettier on entire shared package
This commit is contained in:
Julien G.
2026-05-26 20:27:29 +02:00
committed by GitHub
parent 324d930ca3
commit 126f2df21b
860 changed files with 56891 additions and 46377 deletions
+353
View File
@@ -0,0 +1,353 @@
import type { TranslationStrings } from '../types';
const admin: TranslationStrings = {
'admin.notifications.title': '알림',
'admin.notifications.hint':
'알림 채널을 하나 선택하세요. 한 번에 하나만 활성화할 수 있습니다.',
'admin.notifications.none': '비활성화',
'admin.notifications.email': '이메일 (SMTP)',
'admin.notifications.webhook': '웹훅',
'admin.notifications.ntfy': 'Ntfy',
'admin.ntfy.hint':
'사용자가 자신의 ntfy 토픽을 설정하여 푸시 알림을 받을 수 있습니다. 아래에 기본 서버를 설정하면 사용자 설정에 미리 채워집니다.',
'admin.notifications.save': '알림 설정 저장',
'admin.notifications.saved': '알림 설정이 저장되었습니다',
'admin.notifications.testWebhook': '테스트 웹훅 전송',
'admin.notifications.testWebhookSuccess':
'테스트 웹훅이 성공적으로 전송되었습니다',
'admin.notifications.testWebhookFailed': '테스트 웹훅 실패',
'admin.notifications.testNtfy': '테스트 ntfy 전송',
'admin.notifications.testNtfySuccess':
'테스트 ntfy가 성공적으로 전송되었습니다',
'admin.notifications.testNtfyFailed': '테스트 ntfy 실패',
'admin.notifications.emailPanel.title': '이메일 (SMTP)',
'admin.notifications.webhookPanel.title': '웹훅',
'admin.notifications.inappPanel.title': '앱 내',
'admin.notifications.inappPanel.hint':
'앱 내 알림은 항상 활성화되어 있으며 전역으로 비활성화할 수 없습니다.',
'admin.notifications.adminWebhookPanel.title': '관리자 웹훅',
'admin.notifications.adminWebhookPanel.hint':
'이 웹훅은 관리자 알림 전용입니다 (예: 버전 알림). 사용자별 웹훅과 별개이며 설정 시 항상 실행됩니다.',
'admin.notifications.adminWebhookPanel.saved':
'관리자 웹훅 URL이 저장되었습니다',
'admin.notifications.adminWebhookPanel.testSuccess':
'테스트 웹훅이 성공적으로 전송되었습니다',
'admin.notifications.adminWebhookPanel.testFailed': '테스트 웹훅 실패',
'admin.notifications.adminWebhookPanel.alwaysOnHint':
'URL이 설정되면 관리자 웹훅은 항상 실행됩니다',
'admin.notifications.adminNtfyPanel.title': '관리자 Ntfy',
'admin.notifications.adminNtfyPanel.hint':
'이 ntfy 토픽은 관리자 알림 전용입니다 (예: 버전 알림). 사용자별 토픽과 별개이며 설정 시 항상 실행됩니다.',
'admin.notifications.adminNtfyPanel.serverLabel': 'Ntfy 서버 URL',
'admin.notifications.adminNtfyPanel.serverHint':
'사용자 ntfy 알림의 기본 서버로도 사용됩니다. 비워두면 ntfy.sh가 기본값입니다. 사용자는 자신의 설정에서 변경할 수 있습니다.',
'admin.notifications.adminNtfyPanel.serverPlaceholder': 'https://ntfy.sh',
'admin.notifications.adminNtfyPanel.topicLabel': '관리자 토픽',
'admin.notifications.adminNtfyPanel.topicPlaceholder': 'trek-admin-alerts',
'admin.notifications.adminNtfyPanel.tokenLabel': '액세스 토큰 (선택)',
'admin.notifications.adminNtfyPanel.tokenCleared':
'관리자 액세스 토큰이 삭제되었습니다',
'admin.notifications.adminNtfyPanel.saved':
'관리자 ntfy 설정이 저장되었습니다',
'admin.notifications.adminNtfyPanel.test': '테스트 ntfy 전송',
'admin.notifications.adminNtfyPanel.testSuccess':
'테스트 ntfy가 성공적으로 전송되었습니다',
'admin.notifications.adminNtfyPanel.testFailed': '테스트 ntfy 실패',
'admin.notifications.adminNtfyPanel.alwaysOnHint':
'토픽이 설정되면 관리자 ntfy는 항상 실행됩니다',
'admin.notifications.adminNotificationsHint':
'관리자 전용 알림 (예: 버전 알림)을 전달할 채널을 설정하세요.',
'admin.notifications.tripReminders.title': '여행 리마인더',
'admin.notifications.tripReminders.hint':
'여행 시작 전에 리마인더 알림을 전송합니다 (여행에 리마인더 일수가 설정되어 있어야 합니다).',
'admin.notifications.tripReminders.enabled': '여행 리마인더 활성화됨',
'admin.notifications.tripReminders.disabled': '여행 리마인더 비활성화됨',
'admin.smtp.title': '이메일 및 알림',
'admin.smtp.hint': '이메일 알림 전송을 위한 SMTP 설정입니다.',
'admin.smtp.testButton': '테스트 이메일 전송',
'admin.webhook.hint':
'사용자가 알림용 웹훅 URL을 설정할 수 있습니다 (Discord, Slack 등).',
'admin.smtp.testSuccess': '테스트 이메일이 성공적으로 전송되었습니다',
'admin.smtp.testFailed': '테스트 이메일 실패',
'admin.title': '관리자',
'admin.subtitle': '사용자 관리 및 시스템 설정',
'admin.tabs.users': '사용자',
'admin.tabs.categories': '카테고리',
'admin.tabs.backup': '백업',
'admin.tabs.notifications': '알림',
'admin.tabs.audit': '감사',
'admin.stats.users': '사용자',
'admin.stats.trips': '여행',
'admin.stats.places': '장소',
'admin.stats.photos': '사진',
'admin.stats.files': '파일',
'admin.table.user': '사용자',
'admin.table.email': '이메일',
'admin.table.role': '역할',
'admin.table.created': '생성일',
'admin.table.lastLogin': '마지막 로그인',
'admin.table.actions': '작업',
'admin.you': '(나)',
'admin.editUser': '사용자 편집',
'admin.newPassword': '새 비밀번호',
'admin.newPasswordHint': '비워두면 현재 비밀번호 유지',
'admin.deleteUser':
'사용자 "{name}"을(를) 삭제할까요? 모든 여행이 영구 삭제됩니다.',
'admin.deleteUserTitle': '사용자 삭제',
'admin.newPasswordPlaceholder': '새 비밀번호 입력…',
'admin.toast.loadError': '관리자 데이터 불러오기 실패',
'admin.toast.userUpdated': '사용자가 업데이트되었습니다',
'admin.toast.updateError': '업데이트 실패',
'admin.toast.userDeleted': '사용자가 삭제되었습니다',
'admin.toast.deleteError': '삭제 실패',
'admin.toast.cannotDeleteSelf': '자신의 계정은 삭제할 수 없습니다',
'admin.toast.userCreated': '사용자가 생성되었습니다',
'admin.toast.createError': '사용자 생성 실패',
'admin.toast.fieldsRequired': '사용자 이름, 이메일, 비밀번호가 필요합니다',
'admin.createUser': '사용자 만들기',
'admin.invite.title': '초대 링크',
'admin.invite.subtitle': '일회용 회원가입 링크 만들기',
'admin.invite.create': '링크 만들기',
'admin.invite.createAndCopy': '만들기 및 복사',
'admin.invite.empty': '아직 초대 링크가 없습니다',
'admin.invite.maxUses': '최대 사용 횟수',
'admin.invite.expiry': '만료 기간',
'admin.invite.uses': '사용됨',
'admin.invite.expiresAt': '만료',
'admin.invite.createdBy': '작성자',
'admin.invite.active': '활성',
'admin.invite.expired': '만료됨',
'admin.invite.usedUp': '사용 완료',
'admin.invite.copied': '초대 링크가 클립보드에 복사되었습니다',
'admin.invite.copyLink': '링크 복사',
'admin.invite.deleted': '초대 링크가 삭제되었습니다',
'admin.invite.createError': '초대 링크 생성 실패',
'admin.invite.deleteError': '초대 링크 삭제 실패',
'admin.tabs.settings': '설정',
'admin.allowRegistration': '회원가입 허용',
'admin.allowRegistrationHint': '새 사용자가 직접 회원가입할 수 있습니다',
'admin.authMethods': '인증 방법',
'admin.passwordLogin': '비밀번호 로그인',
'admin.passwordLoginHint':
'사용자가 이메일과 비밀번호로 로그인할 수 있습니다',
'admin.passwordRegistration': '비밀번호 회원가입',
'admin.passwordRegistrationHint':
'새 사용자가 이메일과 비밀번호로 가입할 수 있습니다',
'admin.oidcLogin': 'SSO 로그인',
'admin.oidcLoginHint': '사용자가 SSO로 로그인할 수 있습니다',
'admin.oidcRegistration': 'SSO 자동 프로비저닝',
'admin.oidcRegistrationHint': '새 SSO 사용자의 계정을 자동으로 생성합니다',
'admin.envOverrideHint':
'비밀번호 로그인 설정은 OIDC_ONLY 환경 변수로 제어되며 여기서 변경할 수 없습니다.',
'admin.lockoutWarning': '최소 하나의 로그인 방법이 활성화되어 있어야 합니다',
'admin.requireMfa': '2단계 인증 (2FA) 요구',
'admin.requireMfaHint':
'2FA가 없는 사용자는 앱을 사용하기 전에 설정에서 설정을 완료해야 합니다.',
'admin.apiKeys': 'API 키',
'admin.apiKeysHint':
'선택 사항. 사진 및 날씨 등 확장된 장소 데이터를 활성화합니다.',
'admin.mapsKey': 'Google Maps API 키',
'admin.mapsKeyHint':
'장소 검색에 필요합니다. console.cloud.google.com에서 발급',
'admin.mapsKeyHintLong':
'API 키 없이는 장소 검색에 OpenStreetMap이 사용됩니다. Google API 키가 있으면 사진, 평점, 영업 시간도 불러올 수 있습니다. console.cloud.google.com에서 발급하세요.',
'admin.recommended': '권장',
'admin.weatherKey': 'OpenWeatherMap API 키',
'admin.weatherKeyHint': '날씨 데이터용. openweathermap.org에서 무료 발급',
'admin.validateKey': '테스트',
'admin.keyValid': '연결됨',
'admin.keyInvalid': '유효하지 않음',
'admin.keySaved': 'API 키가 저장되었습니다',
'admin.oidcTitle': 'Single Sign-On (OIDC)',
'admin.oidcSubtitle':
'Google, Apple, Authentik 또는 Keycloak 등 외부 공급자를 통한 로그인을 허용합니다.',
'admin.oidcDisplayName': '표시 이름',
'admin.oidcIssuer': '발급자 URL',
'admin.oidcIssuerHint':
'공급자의 OpenID Connect 발급자 URL. 예: https://accounts.google.com',
'admin.oidcSaved': 'OIDC 설정이 저장되었습니다',
'admin.oidcOnlyMode': '비밀번호 인증 비활성화',
'admin.oidcOnlyModeHint':
'활성화하면 SSO 로그인만 허용됩니다. 비밀번호 기반 로그인 및 회원가입이 차단됩니다.',
'admin.fileTypes': '허용된 파일 형식',
'admin.fileTypesHint': '사용자가 업로드할 수 있는 파일 형식을 설정합니다.',
'admin.fileTypesFormat':
'쉼표로 구분된 확장자 (예: jpg,png,pdf,doc). 모든 형식을 허용하려면 *를 사용하세요.',
'admin.fileTypesSaved': '파일 형식 설정이 저장되었습니다',
'admin.placesPhotos.title': '장소 사진',
'admin.placesPhotos.subtitle':
'Google Places API에서 사진을 가져옵니다. API 할당량 절약을 위해 비활성화할 수 있습니다. Wikimedia 사진은 영향을 받지 않습니다.',
'admin.placesAutocomplete.title': '장소 자동완성',
'admin.placesAutocomplete.subtitle':
'검색 제안에 Google Places API를 사용합니다. API 할당량 절약을 위해 비활성화할 수 있습니다.',
'admin.placesDetails.title': '장소 상세 정보',
'admin.placesDetails.subtitle':
'Google Places API에서 상세 장소 정보 (영업 시간, 평점, 웹사이트)를 가져옵니다. API 할당량 절약을 위해 비활성화할 수 있습니다.',
'admin.bagTracking.title': '가방 추적',
'admin.bagTracking.subtitle': '짐 항목에 무게 및 가방 배정을 활성화합니다',
'admin.collab.chat.title': '채팅',
'admin.collab.chat.subtitle': '여행 협업을 위한 실시간 메시지',
'admin.collab.notes.title': '메모',
'admin.collab.notes.subtitle': '공유 메모 및 문서',
'admin.collab.polls.title': '투표',
'admin.collab.polls.subtitle': '그룹 투표',
'admin.collab.whatsnext.title': '다음 할 일',
'admin.collab.whatsnext.subtitle': '활동 제안 및 다음 단계',
'admin.tabs.config': '개인 설정',
'admin.tabs.defaults': '기본값',
'admin.defaultSettings.title': '기본 사용자 설정',
'admin.defaultSettings.description':
'인스턴스 전체 기본값을 설정합니다. 설정을 변경하지 않은 사용자에게 이 값이 표시됩니다. 사용자의 변경 사항이 항상 우선합니다.',
'admin.defaultSettings.saved': '기본값이 저장되었습니다',
'admin.defaultSettings.reset': '기본 내장값으로 초기화',
'admin.defaultSettings.resetToBuiltIn': '초기화',
'admin.tabs.templates': '짐 목록 템플릿',
'admin.packingTemplates.title': '짐 목록 템플릿',
'admin.packingTemplates.subtitle':
'여행을 위한 재사용 가능한 짐 목록을 만드세요',
'admin.packingTemplates.create': '새 템플릿',
'admin.packingTemplates.namePlaceholder': '템플릿 이름 (예: 해변 휴가)',
'admin.packingTemplates.empty': '아직 템플릿이 없습니다',
'admin.packingTemplates.items': '항목',
'admin.packingTemplates.categories': '카테고리',
'admin.packingTemplates.itemName': '항목 이름',
'admin.packingTemplates.itemCategory': '카테고리',
'admin.packingTemplates.categoryName': '카테고리 이름 (예: 의류)',
'admin.packingTemplates.addCategory': '카테고리 추가',
'admin.packingTemplates.created': '템플릿이 생성되었습니다',
'admin.packingTemplates.deleted': '템플릿이 삭제되었습니다',
'admin.packingTemplates.loadError': '템플릿 불러오기 실패',
'admin.packingTemplates.createError': '템플릿 생성 실패',
'admin.packingTemplates.deleteError': '템플릿 삭제 실패',
'admin.packingTemplates.saveError': '저장 실패',
'admin.tabs.addons': '애드온',
'admin.addons.title': '애드온',
'admin.addons.subtitle':
'기능을 활성화 또는 비활성화하여 TREK 경험을 맞춤 설정하세요.',
'admin.addons.catalog.packing.name': '목록',
'admin.addons.catalog.packing.description':
'여행을 위한 짐 목록 및 할 일 작업',
'admin.addons.catalog.budget.name': '예산',
'admin.addons.catalog.budget.description': '지출 추적 및 여행 예산 계획',
'admin.addons.catalog.documents.name': '문서',
'admin.addons.catalog.documents.description': '여행 서류 저장 및 관리',
'admin.addons.catalog.vacay.name': 'Vacay',
'admin.addons.catalog.vacay.description':
'캘린더 보기가 있는 개인 휴가 플래너',
'admin.addons.catalog.atlas.name': 'Atlas',
'admin.addons.catalog.atlas.description':
'방문한 나라와 여행 통계가 있는 세계 지도',
'admin.addons.catalog.collab.name': 'Collab',
'admin.addons.catalog.collab.description':
'여행 계획을 위한 실시간 메모, 투표, 채팅',
'admin.addons.catalog.memories.name': '사진 (Immich)',
'admin.addons.catalog.memories.description':
'Immich 인스턴스를 통해 여행 사진 공유',
'admin.addons.catalog.mcp.name': 'MCP',
'admin.addons.catalog.mcp.description':
'AI 어시스턴트 통합을 위한 모델 컨텍스트 프로토콜',
'admin.addons.subtitleBefore': '기능을 활성화 또는 비활성화하여 ',
'admin.addons.subtitleAfter': ' 경험을 맞춤 설정하세요.',
'admin.addons.enabled': '활성화됨',
'admin.addons.disabled': '비활성화됨',
'admin.addons.type.trip': '여행',
'admin.addons.type.global': '전역',
'admin.addons.type.integration': '통합',
'admin.addons.tripHint': '각 여행 내 탭으로 사용 가능',
'admin.addons.globalHint': '메인 내비게이션의 독립 섹션으로 사용 가능',
'admin.addons.integrationHint':
'전용 페이지가 없는 백엔드 서비스 및 API 통합',
'admin.addons.toast.updated': '애드온이 업데이트되었습니다',
'admin.addons.toast.error': '애드온 업데이트 실패',
'admin.addons.noAddons': '사용 가능한 애드온이 없습니다',
'admin.weather.title': '날씨 데이터',
'admin.weather.badge': '2026년 3월 24일부터',
'admin.weather.description':
'TREK은 날씨 데이터 소스로 Open-Meteo를 사용합니다. Open-Meteo는 무료 오픈 소스 날씨 서비스로 API 키가 필요 없습니다.',
'admin.weather.forecast': '16일 예보',
'admin.weather.forecastDesc': '이전: 5일 (OpenWeatherMap)',
'admin.weather.climate': '과거 기후 데이터',
'admin.weather.climateDesc': '16일 예보 이후 날짜의 85년 평균값',
'admin.weather.requests': '하루 10,000 요청',
'admin.weather.requestsDesc': '무료, API 키 불필요',
'admin.weather.locationHint':
'날씨는 각 날의 좌표가 있는 첫 번째 장소를 기준으로 합니다. 날에 배정된 장소가 없으면 장소 목록의 임의 장소가 참조로 사용됩니다.',
'admin.tabs.mcpTokens': 'MCP 접근',
'admin.mcpTokens.title': 'MCP 접근',
'admin.mcpTokens.subtitle':
'모든 사용자의 OAuth 세션 및 API 토큰을 관리합니다',
'admin.mcpTokens.sectionTitle': 'API 토큰',
'admin.mcpTokens.owner': '소유자',
'admin.mcpTokens.tokenName': '토큰 이름',
'admin.mcpTokens.created': '생성일',
'admin.mcpTokens.lastUsed': '마지막 사용',
'admin.mcpTokens.never': '없음',
'admin.mcpTokens.empty': '생성된 MCP 토큰이 없습니다',
'admin.mcpTokens.deleteTitle': '토큰 삭제',
'admin.mcpTokens.deleteMessage':
'토큰이 즉시 취소됩니다. 사용자는 이 토큰을 통한 MCP 접근 권한을 잃게 됩니다.',
'admin.mcpTokens.deleteSuccess': '토큰이 삭제되었습니다',
'admin.mcpTokens.deleteError': '토큰 삭제 실패',
'admin.mcpTokens.loadError': '토큰 불러오기 실패',
'admin.oauthSessions.sectionTitle': 'OAuth 세션',
'admin.oauthSessions.clientName': '클라이언트',
'admin.oauthSessions.owner': '소유자',
'admin.oauthSessions.scopes': '권한 범위',
'admin.oauthSessions.created': '생성일',
'admin.oauthSessions.empty': '활성 OAuth 세션이 없습니다',
'admin.oauthSessions.revokeTitle': '세션 취소',
'admin.oauthSessions.revokeMessage':
'OAuth 세션이 즉시 취소됩니다. 클라이언트는 MCP 접근 권한을 잃게 됩니다.',
'admin.oauthSessions.revokeSuccess': '세션이 취소되었습니다',
'admin.oauthSessions.revokeError': '세션 취소 실패',
'admin.oauthSessions.loadError': 'OAuth 세션 불러오기 실패',
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': '보안 및 관리 이벤트 (백업, 사용자, MFA, 설정).',
'admin.audit.empty': '아직 감사 항목이 없습니다.',
'admin.audit.refresh': '새로 고침',
'admin.audit.loadMore': '더 불러오기',
'admin.audit.showing': '{count}개 불러옴 · 총 {total}개',
'admin.audit.col.time': '시간',
'admin.audit.col.user': '사용자',
'admin.audit.col.action': '작업',
'admin.audit.col.resource': '리소스',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': '상세',
'admin.github.title': '릴리스 히스토리',
'admin.github.subtitle': '{repo}의 최신 업데이트',
'admin.github.latest': '최신',
'admin.github.prerelease': '사전 릴리스',
'admin.github.showDetails': '상세 보기',
'admin.github.hideDetails': '상세 숨기기',
'admin.github.loadMore': '더 불러오기',
'admin.github.loading': '불러오는 중...',
'admin.github.error': '릴리스 불러오기 실패',
'admin.github.by': '작성자',
'admin.github.support': 'TREK 개발 지속에 도움이 됩니다',
'admin.update.available': '업데이트 사용 가능',
'admin.update.text':
'TREK {version}이(가) 사용 가능합니다. 현재 {current}을(를) 실행 중입니다.',
'admin.update.button': 'GitHub에서 보기',
'admin.update.install': '업데이트 설치',
'admin.update.confirmTitle': '업데이트를 설치할까요?',
'admin.update.confirmText':
'TREK이 {current}에서 {version}으로 업데이트됩니다. 서버가 이후 자동으로 재시작됩니다.',
'admin.update.dataInfo':
'모든 데이터 (여행, 사용자, API 키, 업로드, Vacay, Atlas, 예산)가 보존됩니다.',
'admin.update.warning': '재시작 중에 앱이 잠시 사용할 수 없게 됩니다.',
'admin.update.confirm': '지금 업데이트',
'admin.update.installing': '업데이트 중…',
'admin.update.success': '업데이트 완료! 서버가 재시작 중입니다…',
'admin.update.failed': '업데이트 실패',
'admin.update.backupHint': '업데이트 전에 백업을 생성하는 것을 권장합니다.',
'admin.update.backupLink': '백업으로 이동',
'admin.update.howTo': '업데이트 방법',
'admin.update.dockerText':
'TREK 인스턴스가 Docker에서 실행 중입니다. {version}으로 업데이트하려면 서버에서 다음 명령을 실행하세요:',
'admin.update.reloadHint': '잠시 후 페이지를 새로 고침하세요.',
'admin.tabs.permissions': '권한',
'admin.addons.catalog.journey.name': 'Journey',
'admin.addons.catalog.journey.description':
'체크인, 사진, 일별 이야기가 있는 여행 기록 및 여행 일지',
};
export default admin;
+6
View File
@@ -0,0 +1,6 @@
import type { TranslationStrings } from '../types';
const airport: TranslationStrings = {
'airport.searchPlaceholder': '공항 코드 또는 도시 (예: ICN)',
};
export default airport;
+58
View File
@@ -0,0 +1,58 @@
import type { TranslationStrings } from '../types';
const atlas: TranslationStrings = {
'atlas.subtitle': '전 세계의 나의 여행 발자취',
'atlas.countries': '국가',
'atlas.trips': '여행',
'atlas.places': '장소',
'atlas.unmark': '제거',
'atlas.confirmMark': '이 나라를 방문한 곳으로 표시할까요?',
'atlas.confirmUnmark': '방문 목록에서 이 나라를 제거할까요?',
'atlas.confirmUnmarkRegion': '방문 목록에서 이 지역을 제거할까요?',
'atlas.markVisited': '방문으로 표시',
'atlas.markVisitedHint': '방문 목록에 이 나라를 추가합니다',
'atlas.markRegionVisitedHint': '방문 목록에 이 지역을 추가합니다',
'atlas.addToBucket': '버킷 리스트에 추가',
'atlas.addPoi': '장소 추가',
'atlas.searchCountry': '국가 검색...',
'atlas.bucketNamePlaceholder': '이름 (국가, 도시, 장소...)',
'atlas.month': '월',
'atlas.year': '연도',
'atlas.addToBucketHint': '방문하고 싶은 장소로 저장',
'atlas.bucketWhen': '방문 예정 시기는 언제인가요?',
'atlas.statsTab': '통계',
'atlas.bucketTab': '버킷 리스트',
'atlas.addBucket': '버킷 리스트에 추가',
'atlas.bucketNotesPlaceholder': '메모 (선택)',
'atlas.bucketEmpty': '버킷 리스트가 비어 있습니다',
'atlas.bucketEmptyHint': '꿈꾸는 방문지를 추가하세요',
'atlas.days': '일',
'atlas.visitedCountries': '방문한 나라',
'atlas.cities': '도시',
'atlas.noData': '아직 여행 데이터가 없습니다',
'atlas.noDataHint': '여행을 만들고 장소를 추가하여 세계 지도를 확인하세요',
'atlas.lastTrip': '마지막 여행',
'atlas.nextTrip': '다음 여행',
'atlas.daysLeft': '일 남음',
'atlas.streak': '연속',
'atlas.years': '년',
'atlas.yearInRow': '연 연속',
'atlas.yearsInRow': '년 연속',
'atlas.tripIn': '에서 여행',
'atlas.tripsIn': '에서 여행',
'atlas.since': '부터',
'atlas.europe': '유럽',
'atlas.asia': '아시아',
'atlas.northAmerica': '북미',
'atlas.southAmerica': '남미',
'atlas.africa': '아프리카',
'atlas.oceania': '오세아니아',
'atlas.other': '기타',
'atlas.firstVisit': '첫 번째 여행',
'atlas.lastVisitLabel': '마지막 여행',
'atlas.tripSingular': '여행',
'atlas.tripPlural': '여행',
'atlas.placeVisited': '방문한 장소',
'atlas.placesVisited': '방문한 장소',
};
export default atlas;
+74
View File
@@ -0,0 +1,74 @@
import type { TranslationStrings } from '../types';
const backup: TranslationStrings = {
'backup.title': '데이터 백업',
'backup.subtitle': '데이터베이스 및 모든 업로드된 파일',
'backup.refresh': '새로 고침',
'backup.upload': '백업 업로드',
'backup.uploading': '업로드 중…',
'backup.create': '백업 만들기',
'backup.creating': '생성 중…',
'backup.empty': '아직 백업이 없습니다',
'backup.createFirst': '첫 번째 백업 만들기',
'backup.download': '다운로드',
'backup.restore': '복원',
'backup.confirm.restore':
'백업 "{name}"을(를) 복원할까요?\n\n현재 모든 데이터가 백업으로 교체됩니다.',
'backup.confirm.uploadRestore':
'백업 파일 "{name}"을(를) 업로드하고 복원할까요?\n\n현재 모든 데이터가 덮어쓰여집니다.',
'backup.confirm.delete': '백업 "{name}"을(를) 삭제할까요?',
'backup.toast.loadError': '백업 불러오기 실패',
'backup.toast.created': '백업이 성공적으로 생성되었습니다',
'backup.toast.createError': '백업 생성 실패',
'backup.toast.restored': '백업이 복원되었습니다. 페이지가 새로 고침됩니다…',
'backup.toast.restoreError': '복원 실패',
'backup.toast.uploadError': '업로드 실패',
'backup.toast.deleted': '백업이 삭제되었습니다',
'backup.toast.deleteError': '삭제 실패',
'backup.toast.downloadError': '다운로드 실패',
'backup.toast.settingsSaved': '자동 백업 설정이 저장되었습니다',
'backup.toast.settingsError': '설정 저장 실패',
'backup.auto.title': '자동 백업',
'backup.auto.subtitle': '일정에 따른 자동 백업',
'backup.auto.enable': '자동 백업 활성화',
'backup.auto.enableHint': '선택한 일정에 따라 자동으로 백업이 생성됩니다',
'backup.auto.interval': '간격',
'backup.auto.hour': '실행 시간',
'backup.auto.hourHint': '서버 현지 시간 ({format} 형식)',
'backup.auto.dayOfWeek': '요일',
'backup.auto.dayOfMonth': '매월 몇 일',
'backup.auto.dayOfMonthHint': '모든 달과의 호환성을 위해 1-28로 제한',
'backup.auto.scheduleSummary': '일정',
'backup.auto.summaryDaily': '매일 {hour}:00',
'backup.auto.summaryWeekly': '매주 {day} {hour}:00',
'backup.auto.summaryMonthly': '매월 {day}일 {hour}:00',
'backup.auto.envLocked': 'Docker',
'backup.auto.envLockedHint':
'자동 백업이 Docker 환경 변수로 설정되어 있습니다. 설정을 변경하려면 docker-compose.yml을 업데이트하고 컨테이너를 재시작하세요.',
'backup.auto.copyEnv': 'Docker 환경 변수 복사',
'backup.auto.envCopied': 'Docker 환경 변수가 클립보드에 복사되었습니다',
'backup.auto.keepLabel': '이후 오래된 백업 삭제',
'backup.dow.sunday': '일',
'backup.dow.monday': '월',
'backup.dow.tuesday': '화',
'backup.dow.wednesday': '수',
'backup.dow.thursday': '목',
'backup.dow.friday': '금',
'backup.dow.saturday': '토',
'backup.interval.hourly': '매시간',
'backup.interval.daily': '매일',
'backup.interval.weekly': '매주',
'backup.interval.monthly': '매월',
'backup.keep.1day': '1일',
'backup.keep.3days': '3일',
'backup.keep.7days': '7일',
'backup.keep.14days': '14일',
'backup.keep.30days': '30일',
'backup.keep.forever': '영구 보관',
'backup.restoreConfirmTitle': '백업을 복원할까요?',
'backup.restoreWarning':
'현재 모든 데이터 (여행, 장소, 사용자, 업로드)가 백업으로 영구 교체됩니다. 이 작업은 취소할 수 없습니다.',
'backup.restoreTip': '팁: 복원 전에 현재 상태의 백업을 만드세요.',
'backup.restoreConfirm': '예, 복원',
};
export default backup;
+42
View File
@@ -0,0 +1,42 @@
import type { TranslationStrings } from '../types';
const budget: TranslationStrings = {
'budget.title': '예산',
'budget.exportCsv': 'CSV 내보내기',
'budget.emptyTitle': '아직 예산이 없습니다',
'budget.emptyText': '카테고리와 항목을 만들어 여행 예산을 계획하세요',
'budget.emptyPlaceholder': '카테고리 이름을 입력하세요...',
'budget.createCategory': '카테고리 만들기',
'budget.category': '카테고리',
'budget.categoryName': '카테고리 이름',
'budget.table.name': '이름',
'budget.table.total': '합계',
'budget.table.persons': '인원',
'budget.table.days': '일수',
'budget.table.perPerson': '1인당',
'budget.table.perDay': '일당',
'budget.table.perPersonDay': '1인/일',
'budget.table.note': '메모',
'budget.table.date': '날짜',
'budget.newEntry': '새 항목',
'budget.defaultEntry': '새 항목',
'budget.defaultCategory': '새 카테고리',
'budget.total': '합계',
'budget.totalBudget': '총 예산',
'budget.byCategory': '카테고리별',
'budget.editTooltip': '클릭하여 편집',
'budget.linkedToReservation': '예약에 연결됨 — 이름은 예약에서 편집하세요',
'budget.confirm.deleteCategory':
'카테고리 "{name}"을(를) {count}개 항목과 함께 삭제할까요?',
'budget.deleteCategory': '카테고리 삭제',
'budget.perPerson': '1인당',
'budget.paid': '지불됨',
'budget.open': '미결',
'budget.noMembers': '배정된 멤버가 없습니다',
'budget.settlement': '정산',
'budget.settlementInfo':
'예산 항목의 멤버 아바타를 클릭하면 녹색으로 표시됩니다 — 해당 멤버가 지불했음을 의미합니다. 그러면 정산에서 누가 누구에게 얼마를 지불해야 하는지 보여줍니다.',
'budget.netBalances': '순 잔액',
'budget.categoriesLabel': '카테고리',
};
export default budget;
+26
View File
@@ -0,0 +1,26 @@
import type { TranslationStrings } from '../types';
const categories: TranslationStrings = {
'categories.title': '카테고리',
'categories.subtitle': '장소 카테고리 관리',
'categories.new': '새 카테고리',
'categories.empty': '아직 카테고리가 없습니다',
'categories.namePlaceholder': '카테고리 이름',
'categories.icon': '아이콘',
'categories.color': '색상',
'categories.customColor': '사용자 지정 색상 선택',
'categories.preview': '미리보기',
'categories.defaultName': '카테고리',
'categories.update': '업데이트',
'categories.create': '생성',
'categories.confirm.delete':
'카테고리를 삭제할까요? 이 카테고리의 장소는 삭제되지 않습니다.',
'categories.toast.loadError': '카테고리 불러오기 실패',
'categories.toast.nameRequired': '이름을 입력하세요',
'categories.toast.updated': '카테고리가 업데이트되었습니다',
'categories.toast.created': '카테고리가 생성되었습니다',
'categories.toast.saveError': '저장 실패',
'categories.toast.deleted': '카테고리가 삭제되었습니다',
'categories.toast.deleteError': '삭제 실패',
};
export default categories;
+73
View File
@@ -0,0 +1,73 @@
import type { TranslationStrings } from '../types';
const collab: TranslationStrings = {
'collab.tabs.chat': '채팅',
'collab.tabs.notes': '메모',
'collab.tabs.polls': '투표',
'collab.whatsNext.title': '다음 할 일',
'collab.whatsNext.today': '오늘',
'collab.whatsNext.tomorrow': '내일',
'collab.whatsNext.empty': '예정된 활동이 없습니다',
'collab.whatsNext.until': '까지',
'collab.whatsNext.emptyHint': '시간이 있는 활동이 여기에 표시됩니다',
'collab.chat.send': '전송',
'collab.chat.placeholder': '메시지 입력...',
'collab.chat.empty': '대화를 시작하세요',
'collab.chat.emptyHint': '메시지는 모든 여행 멤버와 공유됩니다',
'collab.chat.emptyDesc': '여행 그룹과 아이디어, 계획, 업데이트를 공유하세요',
'collab.chat.today': '오늘',
'collab.chat.yesterday': '어제',
'collab.chat.deletedMessage': '메시지를 삭제했습니다',
'collab.chat.reply': '답장',
'collab.chat.loadMore': '이전 메시지 불러오기',
'collab.chat.justNow': '방금 전',
'collab.chat.minutesAgo': '{n}분 전',
'collab.chat.hoursAgo': '{n}시간 전',
'collab.notes.title': '메모',
'collab.notes.new': '새 메모',
'collab.notes.empty': '아직 메모가 없습니다',
'collab.notes.emptyHint': '아이디어와 계획을 기록하세요',
'collab.notes.all': '전체',
'collab.notes.titlePlaceholder': '메모 제목',
'collab.notes.contentPlaceholder': '내용을 입력하세요...',
'collab.notes.categoryPlaceholder': '카테고리',
'collab.notes.newCategory': '새 카테고리...',
'collab.notes.category': '카테고리',
'collab.notes.noCategory': '카테고리 없음',
'collab.notes.color': '색상',
'collab.notes.save': '저장',
'collab.notes.cancel': '취소',
'collab.notes.edit': '편집',
'collab.notes.delete': '삭제',
'collab.notes.pin': '고정',
'collab.notes.unpin': '고정 해제',
'collab.notes.daysAgo': '{n}일 전',
'collab.notes.categorySettings': '카테고리 관리',
'collab.notes.create': '생성',
'collab.notes.website': '웹사이트',
'collab.notes.websitePlaceholder': 'https://...',
'collab.notes.attachFiles': '파일 첨부',
'collab.notes.noCategoriesYet': '아직 카테고리가 없습니다',
'collab.notes.emptyDesc': '메모를 만들어 시작하세요',
'collab.polls.title': '투표',
'collab.polls.new': '새 투표',
'collab.polls.empty': '아직 투표가 없습니다',
'collab.polls.emptyHint': '그룹에 질문하고 함께 투표하세요',
'collab.polls.question': '질문',
'collab.polls.questionPlaceholder': '무엇을 할까요?',
'collab.polls.addOption': '+ 옵션 추가',
'collab.polls.optionPlaceholder': '옵션 {n}',
'collab.polls.create': '투표 만들기',
'collab.polls.close': '닫기',
'collab.polls.closed': '종료됨',
'collab.polls.votes': '{n}표',
'collab.polls.vote': '{n}표',
'collab.polls.multipleChoice': '복수 선택',
'collab.polls.multiChoice': '복수 선택',
'collab.polls.deadline': '마감일',
'collab.polls.option': '옵션',
'collab.polls.options': '옵션',
'collab.polls.delete': '삭제',
'collab.polls.closedSection': '종료됨',
};
export default collab;
+55
View File
@@ -0,0 +1,55 @@
import type { TranslationStrings } from '../types';
const common: TranslationStrings = {
'common.save': '저장',
'common.showMore': '더 보기',
'common.showLess': '접기',
'common.cancel': '취소',
'common.clear': '지우기',
'common.delete': '삭제',
'common.edit': '편집',
'common.add': '추가',
'common.loading': '로딩 중...',
'common.import': '가져오기',
'common.select': '선택',
'common.selectAll': '전체 선택',
'common.deselectAll': '전체 해제',
'common.error': '오류',
'common.unknownError': '알 수 없는 오류',
'common.tooManyAttempts':
'시도 횟수가 너무 많습니다. 잠시 후 다시 시도해 주세요.',
'common.back': '뒤로',
'common.all': '전체',
'common.close': '닫기',
'common.open': '열기',
'common.upload': '업로드',
'common.search': '검색',
'common.confirm': '확인',
'common.ok': '확인',
'common.yes': '예',
'common.no': '아니오',
'common.or': '또는',
'common.none': '없음',
'common.date': '날짜',
'common.rename': '이름 변경',
'common.discardChanges': '변경 사항 취소',
'common.discard': '취소',
'common.name': '이름',
'common.email': '이메일',
'common.password': '비밀번호',
'common.saving': '저장 중...',
'common.justNow': '방금 전',
'common.hoursAgo': '{count}시간 전',
'common.daysAgo': '{count}일 전',
'common.saved': '저장됨',
'common.update': '업데이트',
'common.change': '변경',
'common.uploading': '업로드 중…',
'common.backToPlanning': '계획으로 돌아가기',
'common.reset': '초기화',
'common.expand': '펼치기',
'common.collapse': '접기',
'common.copy': '복사',
'common.copied': '복사됨',
};
export default common;
+120
View File
@@ -0,0 +1,120 @@
import type { TranslationStrings } from '../types';
const dashboard: TranslationStrings = {
'dashboard.title': '내 여행',
'dashboard.subtitle.loading': '여행 불러오는 중...',
'dashboard.subtitle.trips': '{count}개 여행 ({archived}개 보관됨)',
'dashboard.subtitle.empty': '첫 번째 여행을 시작하세요',
'dashboard.subtitle.activeOne': '활성 여행 {count}개',
'dashboard.subtitle.activeMany': '활성 여행 {count}개',
'dashboard.subtitle.archivedSuffix': ' · {count}개 보관됨',
'dashboard.newTrip': '새 여행',
'dashboard.gridView': '격자 보기',
'dashboard.listView': '목록 보기',
'dashboard.currency': '통화',
'dashboard.timezone': '시간대',
'dashboard.localTime': '현지',
'dashboard.timezoneCustomTitle': '사용자 지정 시간대',
'dashboard.timezoneCustomLabelPlaceholder': '레이블 (선택)',
'dashboard.timezoneCustomTzPlaceholder': '예: America/New_York',
'dashboard.timezoneCustomAdd': '추가',
'dashboard.timezoneCustomErrorEmpty': '시간대 식별자를 입력하세요',
'dashboard.timezoneCustomErrorInvalid':
'잘못된 시간대입니다. Europe/Berlin 같은 형식을 사용하세요',
'dashboard.timezoneCustomErrorDuplicate': '이미 추가됨',
'dashboard.emptyTitle': '아직 여행이 없습니다',
'dashboard.emptyText': '첫 번째 여행을 만들고 계획을 시작하세요!',
'dashboard.emptyButton': '첫 번째 여행 만들기',
'dashboard.nextTrip': '다음 여행',
'dashboard.shared': '공유됨',
'dashboard.sharedBy': '{name}이(가) 공유',
'dashboard.days': '일',
'dashboard.places': '장소',
'dashboard.members': '동행자',
'dashboard.archive': '보관',
'dashboard.copyTrip': '복사',
'dashboard.copySuffix': '사본',
'dashboard.restore': '복원',
'dashboard.archived': '보관됨',
'dashboard.status.ongoing': '진행 중',
'dashboard.status.today': '오늘',
'dashboard.status.tomorrow': '내일',
'dashboard.status.past': '지난 여행',
'dashboard.status.daysLeft': '{count}일 남음',
'dashboard.toast.loadError': '여행 불러오기 실패',
'dashboard.toast.created': '여행이 생성되었습니다!',
'dashboard.toast.createError': '여행 생성 실패',
'dashboard.toast.updated': '여행이 업데이트되었습니다!',
'dashboard.toast.updateError': '여행 업데이트 실패',
'dashboard.toast.deleted': '여행이 삭제되었습니다',
'dashboard.toast.deleteError': '여행 삭제 실패',
'dashboard.toast.archived': '여행이 보관되었습니다',
'dashboard.toast.archiveError': '여행 보관 실패',
'dashboard.toast.restored': '여행이 복원되었습니다',
'dashboard.toast.restoreError': '여행 복원 실패',
'dashboard.toast.copied': '여행이 복사되었습니다!',
'dashboard.toast.copyError': '여행 복사 실패',
'dashboard.confirm.delete':
'여행 "{title}"을(를) 삭제할까요? 모든 장소와 계획이 영구 삭제됩니다.',
'dashboard.confirm.copy.title': '이 여행을 복사할까요?',
'dashboard.confirm.copy.willCopy': '복사될 항목',
'dashboard.confirm.copy.will1': '일정, 장소 및 일별 배정',
'dashboard.confirm.copy.will2': '숙박 및 예약',
'dashboard.confirm.copy.will3': '예산 항목 및 카테고리 순서',
'dashboard.confirm.copy.will4': '짐 목록 (체크 해제 상태)',
'dashboard.confirm.copy.will5': '할 일 (미배정 및 미완료)',
'dashboard.confirm.copy.will6': '일별 메모',
'dashboard.confirm.copy.wontCopy': '복사되지 않는 항목',
'dashboard.confirm.copy.wont1': '공동 작업자 및 멤버 배정',
'dashboard.confirm.copy.wont2': '공동 작업 메모, 투표 및 메시지',
'dashboard.confirm.copy.wont3': '파일 및 사진',
'dashboard.confirm.copy.wont4': '공유 토큰',
'dashboard.confirm.copy.confirm': '여행 복사',
'dashboard.editTrip': '여행 편집',
'dashboard.createTrip': '새 여행 만들기',
'dashboard.tripTitle': '제목',
'dashboard.tripTitlePlaceholder': '예: 일본에서의 여름',
'dashboard.tripDescription': '설명',
'dashboard.tripDescriptionPlaceholder': '이 여행에 대해 설명해 주세요',
'dashboard.startDate': '시작일',
'dashboard.endDate': '종료일',
'dashboard.dayCount': '일수',
'dashboard.dayCountHint': '여행 날짜가 설정되지 않은 경우 계획할 일수입니다.',
'dashboard.noDateHint':
'날짜 미설정 — 기본 7일이 생성됩니다. 언제든지 변경할 수 있습니다.',
'dashboard.coverImage': '커버 이미지',
'dashboard.addCoverImage': '커버 이미지 추가 (또는 끌어다 놓기)',
'dashboard.addMembers': '동행자',
'dashboard.addMember': '멤버 추가',
'dashboard.coverSaved': '커버 이미지가 저장되었습니다',
'dashboard.coverUploadError': '업로드 실패',
'dashboard.coverRemoveError': '삭제 실패',
'dashboard.titleRequired': '제목을 입력하세요',
'dashboard.endDateError': '종료일은 시작일 이후여야 합니다',
'dashboard.greeting.morning': '좋은 아침이에요,',
'dashboard.greeting.afternoon': '안녕하세요,',
'dashboard.greeting.evening': '좋은 저녁이에요,',
'dashboard.mobile.liveNow': '지금 라이브',
'dashboard.mobile.tripProgress': '여행 진행도',
'dashboard.mobile.daysLeft': '{count}일 남음',
'dashboard.mobile.places': '장소',
'dashboard.mobile.buddies': '동행자',
'dashboard.mobile.newTrip': '새 여행',
'dashboard.mobile.currency': '통화',
'dashboard.mobile.timezone': '시간대',
'dashboard.mobile.upcomingTrips': '예정된 여행',
'dashboard.mobile.yourTrips': '내 여행',
'dashboard.mobile.trips': '개 여행',
'dashboard.mobile.starts': '시작',
'dashboard.mobile.duration': '기간',
'dashboard.mobile.day': '일',
'dashboard.mobile.days': '일',
'dashboard.mobile.ongoing': '진행 중',
'dashboard.mobile.startsToday': '오늘 시작',
'dashboard.mobile.tomorrow': '내일',
'dashboard.mobile.inDays': '{count}일 후',
'dashboard.mobile.inMonths': '{count}개월 후',
'dashboard.mobile.completed': '완료됨',
'dashboard.mobile.currencyConverter': '환율 계산기',
};
export default dashboard;
+26
View File
@@ -0,0 +1,26 @@
import type { TranslationStrings } from '../types';
const day: TranslationStrings = {
'day.precipProb': '강수 확률',
'day.precipitation': '강수량',
'day.wind': '바람',
'day.sunrise': '일출',
'day.sunset': '일몰',
'day.hourlyForecast': '시간별 예보',
'day.climateHint':
'역사적 평균값 — 이 날짜로부터 16일 이내의 실제 예보를 사용할 수 있습니다.',
'day.noWeather': '날씨 데이터가 없습니다. 좌표가 있는 장소를 추가하세요.',
'day.overview': '일별 개요',
'day.accommodation': '숙박',
'day.addAccommodation': '숙박 추가',
'day.hotelDayRange': '적용할 날',
'day.noPlacesForHotel': '먼저 여행에 장소를 추가하세요',
'day.allDays': '전체',
'day.checkIn': '체크인',
'day.checkInUntil': '까지',
'day.checkOut': '체크아웃',
'day.confirmation': '확인',
'day.editAccommodation': '숙박 편집',
'day.reservations': '예약',
};
export default day;
+46
View File
@@ -0,0 +1,46 @@
import type { TranslationStrings } from '../types';
const dayplan: TranslationStrings = {
'dayplan.icsTooltip': '캘린더 내보내기 (ICS)',
'dayplan.emptyDay': '이 날에 계획된 장소가 없습니다',
'dayplan.cannotReorderTransport':
'고정된 시간이 있는 예약은 순서를 변경할 수 없습니다',
'dayplan.confirmRemoveTimeTitle': '시간을 제거할까요?',
'dayplan.confirmRemoveTimeBody':
'이 장소에 고정된 시간 ({time})이 있습니다. 이동하면 시간이 제거되고 자유 정렬이 허용됩니다.',
'dayplan.confirmRemoveTimeAction': '시간 제거 및 이동',
'dayplan.cannotDropOnTimed': '시간이 고정된 항목 사이에 배치할 수 없습니다',
'dayplan.cannotBreakChronology':
'이 작업은 시간 고정 항목과 예약의 시간 순서를 깨뜨립니다',
'dayplan.addNote': '메모 추가',
'dayplan.expandAll': '모든 날 펼치기',
'dayplan.collapseAll': '모든 날 접기',
'dayplan.editNote': '메모 편집',
'dayplan.noteAdd': '메모 추가',
'dayplan.noteEdit': '메모 편집',
'dayplan.noteTitle': '메모',
'dayplan.noteSubtitle': '일별 메모',
'dayplan.totalCost': '총 비용',
'dayplan.days': '일',
'dayplan.dayN': '{n}일차',
'dayplan.calculating': '계산 중...',
'dayplan.route': '경로',
'dayplan.optimize': '최적화',
'dayplan.optimized': '경로가 최적화되었습니다',
'dayplan.routeError': '경로 계산 실패',
'dayplan.toast.needTwoPlaces':
'경로 최적화에는 최소 두 개의 장소가 필요합니다',
'dayplan.toast.routeOptimized': '경로가 최적화되었습니다',
'dayplan.toast.noGeoPlaces': '경로 계산을 위한 좌표가 있는 장소가 없습니다',
'dayplan.confirmed': '확정됨',
'dayplan.pendingRes': '대기 중',
'dayplan.pdf': 'PDF',
'dayplan.pdfTooltip': '일별 계획을 PDF로 내보내기',
'dayplan.pdfError': 'PDF 내보내기 실패',
'dayplan.mobile.addPlace': '장소 추가',
'dayplan.mobile.searchPlaces': '장소 검색...',
'dayplan.mobile.allAssigned': '모든 장소가 배정되었습니다',
'dayplan.mobile.noMatch': '일치 없음',
'dayplan.mobile.createNew': '새 장소 만들기',
};
export default dayplan;
@@ -0,0 +1,63 @@
import type { NotificationLocale } from '../externalNotifications/types';
const ko: NotificationLocale = {
email: {
footer: 'TREK에서 알림을 활성화했기 때문에 이 이메일을 받으셨습니다.',
manage: '설정에서 환경설정 관리',
madeWith: 'Made with',
openTrek: 'TREK 열기',
},
events: {
trip_invite: (p) => ({
title: `"${p.trip}" 여행 초대`,
body: `${p.actor}이(가) ${p.invitee || '멤버'}를 "${p.trip}" 여행에 초대했습니다.`,
}),
booking_change: (p) => ({
title: `새 예약: ${p.booking}`,
body: `${p.actor}이(가) "${p.trip}"에 "${p.booking}" (${p.type}) 예약을 추가했습니다.`,
}),
trip_reminder: (p) => ({
title: `여행 알림: ${p.trip}`,
body: `"${p.trip}" 여행이 곧 시작됩니다!`,
}),
todo_due: (p) => ({
title: `할 일 마감: ${p.todo}`,
body: `"${p.trip}"의 "${p.todo}"은(는) ${p.due}에 마감됩니다.`,
}),
vacay_invite: (p) => ({
title: 'Vacay Fusion 초대',
body: `${p.actor}이(가) 휴가 계획을 합치도록 초대했습니다. TREK을 열어 수락하거나 거절하세요.`,
}),
photos_shared: (p) => ({
title: `${p.count}장의 사진이 공유되었습니다`,
body: `${p.actor}이(가) "${p.trip}"에서 ${p.count}장의 사진을 공유했습니다.`,
}),
collab_message: (p) => ({
title: `"${p.trip}"의 새 메시지`,
body: `${p.actor}: ${p.preview}`,
}),
packing_tagged: (p) => ({
title: `짐 꾸리기: ${p.category}`,
body: `${p.actor}이(가) "${p.trip}"의 "${p.category}" 카테고리에 당신을 할당했습니다.`,
}),
version_available: (p) => ({
title: '새 TREK 버전 사용 가능',
body: `TREK ${p.version}을 사용할 수 있습니다. 관리자 패널에서 업데이트하세요.`,
}),
synology_session_cleared: () => ({
title: 'Synology 세션이 초기화되었습니다',
body: 'Synology 계정 또는 URL이 변경되었습니다. Synology Photos에서 로그아웃되었습니다.',
}),
},
passwordReset: {
subject: '비밀번호 재설정',
greeting: '안녕하세요',
body: 'TREK 계정 비밀번호 재설정 요청을 받았습니다. 아래 버튼을 클릭하여 새 비밀번호를 설정하세요.',
ctaIntro: '비밀번호 재설정',
expiry: '이 링크는 60분 후에 만료됩니다.',
ignore:
'본인이 요청하지 않으셨다면 이 이메일을 무시하셔도 됩니다 — 비밀번호는 변경되지 않습니다.',
},
};
export default ko;
+62
View File
@@ -0,0 +1,62 @@
import type { TranslationStrings } from '../types';
const files: TranslationStrings = {
'files.title': '파일',
'files.pageTitle': '파일 및 서류',
'files.subtitle': '{trip}의 파일 {count}개',
'files.download': '다운로드',
'files.openError': '파일을 열 수 없습니다',
'files.downloadPdf': 'PDF 다운로드',
'files.count': '파일 {count}개',
'files.countSingular': '파일 1개',
'files.uploaded': '{count}개 업로드됨',
'files.uploadError': '업로드 실패',
'files.dropzone': '여기에 파일을 놓으세요',
'files.dropzoneHint': '또는 클릭하여 탐색',
'files.allowedTypes':
'이미지, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · 최대 50 MB',
'files.uploading': '업로드 중...',
'files.filterAll': '전체',
'files.filterPdf': 'PDF',
'files.filterImages': '이미지',
'files.filterDocs': '문서',
'files.filterCollab': 'Collab 메모',
'files.sourceCollab': 'Collab 메모에서',
'files.empty': '아직 파일이 없습니다',
'files.emptyHint': '파일을 업로드하여 여행에 첨부하세요',
'files.openTab': '새 탭에서 열기',
'files.confirm.delete': '이 파일을 삭제할까요?',
'files.toast.deleted': '파일이 삭제되었습니다',
'files.toast.deleteError': '파일 삭제 실패',
'files.sourcePlan': '일별 계획',
'files.sourceBooking': '예약',
'files.sourceTransport': '교통',
'files.attach': '첨부',
'files.pasteHint': '클립보드에서 이미지를 붙여넣을 수도 있습니다 (Ctrl+V)',
'files.trash': '휴지통',
'files.trashEmpty': '휴지통이 비어 있습니다',
'files.emptyTrash': '휴지통 비우기',
'files.restore': '복원',
'files.star': '즐겨찾기',
'files.unstar': '즐겨찾기 해제',
'files.assign': '배정',
'files.assignTitle': '파일 배정',
'files.assignPlace': '장소',
'files.assignBooking': '예약',
'files.assignTransport': '교통',
'files.unassigned': '미배정',
'files.unlink': '연결 해제',
'files.toast.trashed': '휴지통으로 이동됨',
'files.toast.restored': '파일이 복원되었습니다',
'files.toast.trashEmptied': '휴지통이 비워졌습니다',
'files.toast.assigned': '파일이 배정되었습니다',
'files.toast.assignError': '배정 실패',
'files.toast.restoreError': '복원 실패',
'files.confirm.permanentDelete':
'이 파일을 영구 삭제할까요? 이 작업은 취소할 수 없습니다.',
'files.confirm.emptyTrash':
'휴지통의 모든 파일을 영구 삭제할까요? 이 작업은 취소할 수 없습니다.',
'files.noteLabel': '메모',
'files.notePlaceholder': '메모 추가...',
};
export default files;
+86
View File
@@ -0,0 +1,86 @@
import admin from './admin';
import airport from './airport';
import atlas from './atlas';
import backup from './backup';
import budget from './budget';
import categories from './categories';
import collab from './collab';
import common from './common';
import dashboard from './dashboard';
import day from './day';
import dayplan from './dayplan';
import files from './files';
import inspector from './inspector';
import journey from './journey';
import login from './login';
import map from './map';
import members from './members';
import memories from './memories';
import nav from './nav';
import notif from './notif';
import notifications from './notifications';
import oauth from './oauth';
import packing from './packing';
import pdf from './pdf';
import perm from './perm';
import photos from './photos';
import places from './places';
import planner from './planner';
import register from './register';
import reservations from './reservations';
import settings from './settings';
import share from './share';
import shared from './shared';
import stats from './stats';
import system_notice from './system_notice';
import todo from './todo';
import transport from './transport';
import trip from './trip';
import trips from './trips';
import undo from './undo';
import vacay from './vacay';
const locale = {
...common,
...trips,
...nav,
...dashboard,
...settings,
...admin,
...dayplan,
...share,
...shared,
...login,
...register,
...vacay,
...atlas,
...trip,
...places,
...inspector,
...reservations,
...airport,
...map,
...budget,
...files,
...packing,
...members,
...categories,
...backup,
...photos,
...pdf,
...planner,
...stats,
...day,
...memories,
...collab,
...perm,
...undo,
...notifications,
...todo,
...notif,
...journey,
...oauth,
...system_notice,
...transport,
};
export default locale;
+22
View File
@@ -0,0 +1,22 @@
import type { TranslationStrings } from '../types';
const inspector: TranslationStrings = {
'inspector.opened': '영업 중',
'inspector.closed': '영업 종료',
'inspector.openingHours': '영업 시간',
'inspector.showHours': '영업 시간 보기',
'inspector.files': '파일',
'inspector.filesCount': '{count}개 파일',
'inspector.remove': '제거',
'inspector.removeFromDay': '날에서 제거',
'inspector.addToDay': '날에 추가',
'inspector.confirmedRes': '확정된 예약',
'inspector.pendingRes': '대기 중인 예약',
'inspector.google': 'Google Maps에서 열기',
'inspector.website': '웹사이트 열기',
'inspector.addRes': '예약',
'inspector.editRes': '예약 편집',
'inspector.participants': '참가자',
'inspector.trackStats': '트랙 통계',
};
export default inspector;
+244
View File
@@ -0,0 +1,244 @@
import type { TranslationStrings } from '../types';
const journey: TranslationStrings = {
'journey.search.placeholder': 'Journey 검색…',
'journey.search.noResults': '"{query}"와(과) 일치하는 Journey가 없습니다',
'journey.title': 'Journey',
'journey.subtitle': '여행을 실시간으로 기록하세요',
'journey.new': '새 Journey',
'journey.create': '만들기',
'journey.titlePlaceholder': '어디로 가시나요?',
'journey.empty': '아직 Journey가 없습니다',
'journey.emptyHint': '다음 여행을 기록하기 시작하세요',
'journey.deleted': 'Journey가 삭제되었습니다',
'journey.createError': 'Journey를 만들 수 없습니다',
'journey.deleteError': 'Journey를 삭제할 수 없습니다',
'journey.deleteConfirmTitle': '삭제',
'journey.deleteConfirmMessage':
'"{title}"을(를) 삭제할까요? 이 작업은 취소할 수 없습니다.',
'journey.deleteConfirmGeneric': '정말로 삭제할까요?',
'journey.notFound': 'Journey를 찾을 수 없습니다',
'journey.photos': '사진',
'journey.timelineEmpty': '아직 정류장이 없습니다',
'journey.timelineEmptyHint': '체크인을 추가하거나 일기를 작성하여 시작하세요',
'journey.status.draft': '초안',
'journey.status.active': '활성',
'journey.status.completed': '완료됨',
'journey.status.upcoming': '예정됨',
'journey.status.archived': '보관됨',
'journey.checkin.add': '체크인',
'journey.checkin.namePlaceholder': '위치 이름',
'journey.checkin.notesPlaceholder': '메모 (선택)',
'journey.checkin.save': '저장',
'journey.checkin.error': '체크인을 저장할 수 없습니다',
'journey.entry.add': '일기',
'journey.entry.edit': '항목 편집',
'journey.entry.titlePlaceholder': '제목 (선택)',
'journey.entry.bodyPlaceholder': '오늘 무슨 일이 있었나요?',
'journey.entry.save': '저장',
'journey.entry.error': '항목을 저장할 수 없습니다',
'journey.photo.add': '사진',
'journey.photo.uploadError': '업로드 실패',
'journey.share.share': '공유',
'journey.share.public': '공개',
'journey.share.linkCopied': '공개 링크가 복사되었습니다',
'journey.share.disabled': '공개 공유 비활성화됨',
'journey.editor.titlePlaceholder': '이 순간에 이름을 붙여주세요...',
'journey.editor.bodyPlaceholder': '오늘의 이야기를 들려주세요...',
'journey.editor.placePlaceholder': '위치 (선택)',
'journey.editor.tagsPlaceholder':
'태그: 숨겨진 명소, 최고의 식사, 다시 방문...',
'journey.visibility.private': '비공개',
'journey.visibility.shared': '공유됨',
'journey.visibility.public': '공개',
'journey.emptyState.title': '여기서 이야기가 시작됩니다',
'journey.emptyState.subtitle':
'장소에 체크인하거나 첫 번째 일기 항목을 작성하세요',
'journey.frontpage.subtitle': '여행을 영원히 잊지 못할 이야기로 만드세요',
'journey.frontpage.createJourney': 'Journey 만들기',
'journey.frontpage.activeJourney': '활성 Journey',
'journey.frontpage.allJourneys': '모든 Journey',
'journey.frontpage.journeys': '개 Journey',
'journey.frontpage.createNew': '새 Journey 만들기',
'journey.frontpage.createNewSub':
'여행을 선택하고, 이야기를 쓰고, 모험을 공유하세요',
'journey.frontpage.live': '라이브',
'journey.frontpage.synced': '동기화됨',
'journey.frontpage.continueWriting': '계속 쓰기',
'journey.frontpage.updated': '{time}에 업데이트됨',
'journey.frontpage.suggestionLabel': '여행이 방금 종료됨',
'journey.frontpage.suggestionText':
'<strong>{title}</strong>을(를) Journey로 만들어보세요',
'journey.frontpage.dismiss': '닫기',
'journey.frontpage.journeyName': 'Journey 이름',
'journey.frontpage.namePlaceholder': '예: 동남아시아 2026',
'journey.frontpage.selectTrips': '여행 선택',
'journey.frontpage.tripsSelected': '개 여행 선택됨',
'journey.frontpage.trips': '개 여행',
'journey.frontpage.placesImported': '개 장소가 가져와집니다',
'journey.frontpage.places': '개 장소',
'journey.detail.backToJourney': 'Journey로 돌아가기',
'journey.detail.syncedWithTrips': '여행과 동기화됨',
'journey.detail.addEntry': '항목 추가',
'journey.detail.newEntry': '새 항목',
'journey.detail.editEntry': '항목 편집',
'journey.detail.noEntries': '아직 항목이 없습니다',
'journey.detail.noEntriesHint':
'여행을 추가하여 스켈레톤 항목으로 시작하세요',
'journey.detail.noPhotos': '아직 사진이 없습니다',
'journey.detail.noPhotosHint':
'항목에 사진을 업로드하거나 Immich/Synology 라이브러리를 탐색하세요',
'journey.detail.journeyTab': 'Journey',
'journey.detail.journeyStats': 'Journey 통계',
'journey.detail.syncedTrips': '동기화된 여행',
'journey.detail.noTripsLinked': '아직 연결된 여행이 없습니다',
'journey.detail.contributors': '기여자',
'journey.detail.readMore': '더 읽기',
'journey.detail.prosCons': '장단점',
'journey.detail.photos': '장',
'journey.detail.day': '{number}일차',
'journey.detail.places': '개 장소',
'journey.stats.days': '일',
'journey.stats.cities': '도시',
'journey.stats.entries': '항목',
'journey.stats.photos': '사진',
'journey.stats.places': '장소',
'journey.skeletons.show': '제안 보기',
'journey.skeletons.hide': '제안 숨기기',
'journey.verdict.lovedIt': '정말 좋았어요',
'journey.verdict.couldBeBetter': '더 좋을 수 있었어요',
'journey.synced.places': '개 장소',
'journey.synced.synced': '동기화됨',
'journey.editor.discardChangesConfirm':
'저장되지 않은 변경 사항이 있습니다. 취소할까요?',
'journey.editor.uploadPhotos': '사진 업로드',
'journey.editor.uploading': '업로드 중...',
'journey.editor.fromGallery': '갤러리에서',
'journey.editor.allPhotosAdded': '모든 사진이 이미 추가되었습니다',
'journey.editor.writeStory': '이야기를 써주세요...',
'journey.editor.prosCons': '장단점',
'journey.editor.pros': '장점',
'journey.editor.cons': '단점',
'journey.editor.proPlaceholder': '좋은 점...',
'journey.editor.conPlaceholder': '아쉬운 점...',
'journey.editor.addAnother': '하나 더 추가',
'journey.editor.date': '날짜',
'journey.editor.location': '위치',
'journey.editor.searchLocation': '위치 검색...',
'journey.editor.mood': '기분',
'journey.editor.weather': '날씨',
'journey.editor.photoFirst': '1번째',
'journey.editor.makeFirst': '1번째로 설정',
'journey.editor.searching': '검색 중...',
'journey.mood.amazing': '최고!',
'journey.mood.good': '좋음',
'journey.mood.neutral': '보통',
'journey.mood.rough': '힘들었음',
'journey.weather.sunny': '맑음',
'journey.weather.partly': '구름 조금',
'journey.weather.cloudy': '흐림',
'journey.weather.rainy': '비',
'journey.weather.stormy': '폭풍',
'journey.weather.cold': '눈',
'journey.trips.linkTrip': '여행 연결',
'journey.trips.searchTrip': '여행 검색',
'journey.trips.searchPlaceholder': '여행 이름 또는 목적지...',
'journey.trips.noTripsAvailable': '사용 가능한 여행이 없습니다',
'journey.trips.link': '연결',
'journey.trips.tripLinked': '여행이 연결되었습니다',
'journey.trips.linkFailed': '여행 연결 실패',
'journey.trips.addTrip': '여행 추가',
'journey.trips.unlinkTrip': '여행 연결 해제',
'journey.trips.unlinkMessage':
'"{title}"을(를) 연결 해제할까요? 이 여행의 동기화된 모든 항목과 사진이 영구 삭제됩니다. 이 작업은 취소할 수 없습니다.',
'journey.trips.unlink': '연결 해제',
'journey.trips.tripUnlinked': '여행 연결이 해제되었습니다',
'journey.trips.unlinkFailed': '여행 연결 해제 실패',
'journey.trips.noTripsLinkedSettings': '연결된 여행이 없습니다',
'journey.contributors.invite': '기여자 초대',
'journey.contributors.searchUser': '사용자 검색',
'journey.contributors.searchPlaceholder': '사용자 이름 또는 이메일...',
'journey.contributors.noUsers': '사용자를 찾을 수 없습니다',
'journey.contributors.role': '역할',
'journey.contributors.added': '기여자가 추가되었습니다',
'journey.contributors.addFailed': '기여자 추가 실패',
'journey.contributors.remove': '기여자 제거',
'journey.contributors.removeConfirm':
'{username}을(를) 이 Journey에서 제거할까요?',
'journey.contributors.removed': '기여자가 제거되었습니다',
'journey.contributors.removeFailed': '기여자 제거 실패',
'journey.share.publicShare': '공개 공유',
'journey.share.createLink': '공유 링크 만들기',
'journey.share.linkCreated': '공유 링크가 생성되었습니다',
'journey.share.createFailed': '링크 생성 실패',
'journey.share.copy': '복사',
'journey.share.copied': '복사됨!',
'journey.share.timeline': '타임라인',
'journey.share.gallery': '갤러리',
'journey.share.map': '지도',
'journey.share.removeLink': '공유 링크 제거',
'journey.share.linkDeleted': '공유 링크가 삭제되었습니다',
'journey.share.deleteFailed': '삭제 실패',
'journey.share.updateFailed': '업데이트 실패',
'journey.invite.role': '역할',
'journey.invite.viewer': '뷰어',
'journey.invite.editor': '편집자',
'journey.invite.invite': '초대',
'journey.invite.inviting': '초대 중...',
'journey.settings.title': 'Journey 설정',
'journey.settings.coverImage': '커버 이미지',
'journey.settings.changeCover': '커버 변경',
'journey.settings.addCover': '커버 이미지 추가',
'journey.settings.name': '이름',
'journey.settings.subtitle': '부제목',
'journey.settings.subtitlePlaceholder': '예: 태국, 베트남 & 캄보디아',
'journey.settings.endJourney': 'Journey 보관',
'journey.settings.reopenJourney': 'Journey 복원',
'journey.settings.archived': 'Journey가 보관되었습니다',
'journey.settings.reopened': 'Journey가 복원되었습니다',
'journey.settings.endDescription':
'라이브 배지를 숨깁니다. 언제든지 다시 열 수 있습니다.',
'journey.settings.delete': '삭제',
'journey.settings.deleteJourney': 'Journey 삭제',
'journey.settings.deleteMessage':
'"{title}"을(를) 삭제할까요? 모든 항목과 사진이 삭제됩니다.',
'journey.settings.saved': '설정이 저장되었습니다',
'journey.settings.saveFailed': '저장 실패',
'journey.settings.coverUpdated': '커버가 업데이트되었습니다',
'journey.settings.coverFailed': '업로드 실패',
'journey.settings.failedToDelete': '삭제 실패',
'journey.entries.deleteTitle': '항목 삭제',
'journey.photosUploaded': '{count}장 사진이 업로드되었습니다',
'journey.photosAdded': '{count}장 사진이 추가되었습니다',
'journey.public.notFound': '찾을 수 없습니다',
'journey.public.notFoundMessage':
'이 Journey가 존재하지 않거나 링크가 만료되었습니다.',
'journey.public.readOnly': '읽기 전용 · 공개 Journey',
'journey.public.tagline': '여행 기록 및 탐험 키트',
'journey.public.sharedVia': '공유 경로',
'journey.public.madeWith': '으로 만들어짐',
'journey.pdf.journeyBook': 'Journey 책',
'journey.pdf.madeWith': 'TREK으로 만들어짐',
'journey.pdf.day': '일차',
'journey.pdf.theEnd': '끝',
'journey.pdf.saveAsPdf': 'PDF로 저장',
'journey.pdf.pages': '페이지',
'journey.picker.tripPeriod': '여행 기간',
'journey.picker.dateRange': '날짜 범위',
'journey.picker.allPhotos': '모든 사진',
'journey.picker.albums': '앨범',
'journey.picker.selected': '선택됨',
'journey.picker.addTo': '추가',
'journey.picker.newGallery': '새 갤러리',
'journey.picker.selectAll': '전체 선택',
'journey.picker.deselectAll': '전체 해제',
'journey.picker.noAlbums': '앨범을 찾을 수 없습니다',
'journey.picker.selectDate': '날짜 선택',
'journey.picker.search': '검색',
'journey.editor.uploadingProgress': '업로드 중 {done}/{total}…',
'journey.editor.uploadFailed': '사진 업로드 실패',
'journey.editor.uploadPartialFailed':
'{total}개 중 {failed}개의 사진을 업로드하지 못했습니다 — 다시 저장하여 재시도하세요',
'journey.photosUploadFailed': '일부 사진을 업로드하지 못했습니다',
};
export default journey;
+93
View File
@@ -0,0 +1,93 @@
import type { TranslationStrings } from '../types';
const login: TranslationStrings = {
'login.error': '로그인 실패. 자격 증명을 확인하세요.',
'login.tagline': '나의 여행.\n나의 계획.',
'login.description':
'인터랙티브 지도, 예산, 실시간 동기화로 함께 여행을 계획하세요.',
'login.features.maps': '인터랙티브 지도',
'login.features.mapsDesc': 'Google Places, 경로 및 클러스터링',
'login.features.realtime': '실시간 동기화',
'login.features.realtimeDesc': 'WebSocket으로 함께 계획',
'login.features.budget': '예산 추적',
'login.features.budgetDesc': '카테고리, 차트 및 1인당 비용',
'login.features.collab': '협업',
'login.features.collabDesc': '공유 여행으로 다중 사용자 지원',
'login.features.packing': '짐 목록',
'login.features.packingDesc': '카테고리, 진행 상황 및 제안',
'login.features.bookings': '예약',
'login.features.bookingsDesc': '항공, 호텔, 레스토랑 등',
'login.features.files': '문서',
'login.features.filesDesc': '문서 업로드 및 관리',
'login.features.routes': '스마트 경로',
'login.features.routesDesc': '자동 최적화 및 Google Maps 내보내기',
'login.selfHosted': '자체 호스팅 · 오픈 소스 · 내 데이터는 내 것',
'login.title': '로그인',
'login.subtitle': '다시 오신 것을 환영합니다',
'login.signingIn': '로그인 중…',
'login.signIn': '로그인',
'login.createAdmin': '관리자 계정 만들기',
'login.createAdminHint': 'TREK의 첫 번째 관리자 계정을 설정하세요.',
'login.setNewPassword': '새 비밀번호 설정',
'login.setNewPasswordHint': '계속하기 전에 비밀번호를 변경해야 합니다.',
'login.createAccount': '계정 만들기',
'login.createAccountHint': '새 계정을 등록하세요.',
'login.creating': '생성 중…',
'login.noAccount': '계정이 없으신가요?',
'login.hasAccount': '이미 계정이 있으신가요?',
'login.register': '회원가입',
'login.emailPlaceholder': 'your@email.com',
'login.username': '사용자 이름',
'login.oidc.registrationDisabled':
'회원가입이 비활성화되어 있습니다. 관리자에게 문의하세요.',
'login.oidc.noEmail': '공급자로부터 이메일을 받지 못했습니다.',
'login.oidc.tokenFailed': '인증 실패.',
'login.oidc.invalidState': '유효하지 않은 세션입니다. 다시 시도하세요.',
'login.demoFailed': '데모 로그인 실패',
'login.oidcSignIn': '{name}으로 로그인',
'login.oidcOnly':
'비밀번호 인증이 비활성화되었습니다. SSO 공급자로 로그인하세요.',
'login.oidcLoggedOut': '로그아웃되었습니다. SSO 공급자로 다시 로그인하세요.',
'login.demoHint': '데모 체험 — 회원가입 불필요',
'login.mfaTitle': '2단계 인증',
'login.mfaSubtitle': '인증 앱의 6자리 코드를 입력하세요.',
'login.mfaCodeLabel': '인증 코드',
'login.mfaCodeRequired': '인증 앱의 코드를 입력하세요.',
'login.mfaHint':
'Google Authenticator, Authy 또는 다른 TOTP 앱을 열어주세요.',
'login.mfaBack': '← 로그인으로 돌아가기',
'login.mfaVerify': '인증',
'login.invalidInviteLink': '유효하지 않거나 만료된 초대 링크입니다',
'login.oidcFailed': 'OIDC 로그인 실패',
'login.usernameRequired': '사용자 이름을 입력하세요',
'login.passwordMinLength': '비밀번호는 최소 8자 이상이어야 합니다',
'login.forgotPassword': '비밀번호를 잊으셨나요?',
'login.forgotPasswordTitle': '비밀번호 재설정',
'login.forgotPasswordBody':
'가입 시 사용한 이메일 주소를 입력하세요. 계정이 존재하면 재설정 링크를 보내드립니다.',
'login.forgotPasswordSubmit': '재설정 링크 전송',
'login.forgotPasswordSentTitle': '이메일을 확인하세요',
'login.forgotPasswordSentBody':
'해당 이메일로 계정이 있다면 재설정 링크가 전송 중입니다. 링크는 60분 후 만료됩니다.',
'login.forgotPasswordSmtpHintOff':
'알림: 관리자가 SMTP를 설정하지 않아 재설정 링크가 이메일 대신 서버 콘솔에 기록됩니다.',
'login.backToLogin': '로그인으로 돌아가기',
'login.newPassword': '새 비밀번호',
'login.confirmPassword': '새 비밀번호 확인',
'login.passwordsDontMatch': '비밀번호가 일치하지 않습니다',
'login.mfaCode': '2FA 코드',
'login.resetPasswordTitle': '새 비밀번호 설정',
'login.resetPasswordBody':
'이전에 사용하지 않은 강력한 비밀번호를 선택하세요. 최소 8자.',
'login.resetPasswordMfaBody':
'재설정을 완료하려면 2FA 코드 또는 백업 코드를 입력하세요.',
'login.resetPasswordSubmit': '비밀번호 재설정',
'login.resetPasswordVerify': '인증 및 재설정',
'login.resetPasswordSuccessTitle': '비밀번호가 업데이트되었습니다',
'login.resetPasswordSuccessBody': '새 비밀번호로 로그인할 수 있습니다.',
'login.resetPasswordInvalidLink': '유효하지 않은 재설정 링크',
'login.resetPasswordInvalidLinkBody':
'이 링크가 없거나 손상되었습니다. 새 링크를 요청하세요.',
'login.resetPasswordFailed': '재설정 실패. 링크가 만료되었을 수 있습니다.',
};
export default login;
+8
View File
@@ -0,0 +1,8 @@
import type { TranslationStrings } from '../types';
const map: TranslationStrings = {
'map.connections': '연결',
'map.showConnections': '예약 경로 표시',
'map.hideConnections': '예약 경로 숨기기',
};
export default map;
+24
View File
@@ -0,0 +1,24 @@
import type { TranslationStrings } from '../types';
const members: TranslationStrings = {
'members.shareTrip': '여행 공유',
'members.inviteUser': '사용자 초대',
'members.selectUser': '사용자 선택…',
'members.invite': '초대',
'members.allHaveAccess': '모든 사용자가 이미 접근 권한을 가지고 있습니다.',
'members.access': '접근',
'members.person': '명',
'members.persons': '명',
'members.you': '나',
'members.owner': '소유자',
'members.leaveTrip': '여행 떠나기',
'members.removeAccess': '접근 권한 제거',
'members.confirmLeave': '여행을 떠날까요? 접근 권한을 잃게 됩니다.',
'members.confirmRemove': '이 사용자의 접근 권한을 제거할까요?',
'members.loadError': '멤버 불러오기 실패',
'members.added': '추가됨',
'members.addError': '추가 실패',
'members.removed': '멤버가 제거되었습니다',
'members.removeError': '제거 실패',
};
export default members;
+80
View File
@@ -0,0 +1,80 @@
import type { TranslationStrings } from '../types';
const memories: TranslationStrings = {
'memories.title': '사진',
'memories.notConnected': '{provider_name}이(가) 연결되지 않았습니다',
'memories.notConnectedHint':
'이 여행에 사진을 추가하려면 설정에서 {provider_name} 인스턴스를 연결하세요.',
'memories.notConnectedMultipleHint':
'이 여행에 사진을 추가하려면 설정에서 다음 사진 공급자 중 하나를 연결하세요: {provider_names}',
'memories.noDates': '사진을 불러오려면 여행에 날짜를 추가하세요.',
'memories.noPhotos': '사진을 찾을 수 없습니다',
'memories.noPhotosHint':
'{provider_name}에서 이 여행의 날짜 범위에 해당하는 사진을 찾을 수 없습니다.',
'memories.photosFound': '장',
'memories.fromOthers': '다른 사람으로부터',
'memories.sharePhotos': '사진 공유',
'memories.sharing': '공유',
'memories.reviewTitle': '사진 검토',
'memories.reviewHint': '사진을 클릭하여 공유에서 제외하세요.',
'memories.shareCount': '사진 {count}장 공유',
'memories.providerUrl': '서버 URL',
'memories.providerApiKey': 'API 키',
'memories.providerUsername': '사용자 이름',
'memories.providerPassword': '비밀번호',
'memories.providerOTP': 'MFA 코드 (활성화된 경우)',
'memories.skipSSLVerification': 'SSL 인증서 확인 건너뛰기',
'memories.immichAutoUpload': '업로드 시 Journey 사진을 Immich에 미러링',
'memories.providerUrlHintSynology':
'URL에 Photos 앱 경로를 포함하세요. 예: https://nas:5001/photo',
'memories.testConnection': '연결 테스트',
'memories.testShort': '테스트',
'memories.testFirst': '먼저 연결을 테스트하세요',
'memories.connected': '연결됨',
'memories.disconnected': '연결되지 않음',
'memories.connectionSuccess': '{provider_name}에 연결되었습니다',
'memories.connectionError': '{provider_name}에 연결할 수 없습니다',
'memories.saved': '{provider_name} 설정이 저장되었습니다',
'memories.providerDisconnectedBanner':
'{provider_name} 연결이 끊어졌습니다. 사진을 보려면 설정에서 다시 연결하세요.',
'memories.saveError': '{provider_name} 설정을 저장할 수 없습니다',
'memories.addPhotos': '사진 추가',
'memories.linkAlbum': '앨범 연결',
'memories.selectAlbum': '{provider_name} 앨범 선택',
'memories.selectAlbumMultiple': '앨범 선택',
'memories.noAlbums': '앨범을 찾을 수 없습니다',
'memories.syncAlbum': '앨범 동기화',
'memories.unlinkAlbum': '앨범 연결 해제',
'memories.photos': '장',
'memories.selectPhotos': '{provider_name}에서 사진 선택',
'memories.selectPhotosMultiple': '사진 선택',
'memories.selectHint': '사진을 탭하여 선택하세요.',
'memories.selected': '선택됨',
'memories.addSelected': '{count}장 추가',
'memories.alreadyAdded': '추가됨',
'memories.private': '비공개',
'memories.stopSharing': '공유 중지',
'memories.oldest': '오래된 것 먼저',
'memories.newest': '최신 것 먼저',
'memories.allLocations': '모든 위치',
'memories.tripDates': '여행 날짜',
'memories.allPhotos': '모든 사진',
'memories.confirmShareTitle': '여행 멤버와 공유할까요?',
'memories.confirmShareHint':
'{count}장의 사진이 이 여행의 모든 멤버에게 표시됩니다. 나중에 개별 사진을 비공개로 만들 수 있습니다.',
'memories.confirmShareButton': '사진 공유',
'memories.error.loadAlbums': '앨범 불러오기 실패',
'memories.error.linkAlbum': '앨범 연결 실패',
'memories.error.unlinkAlbum': '앨범 연결 해제 실패',
'memories.error.syncAlbum': '앨범 동기화 실패',
'memories.error.loadPhotos': '사진 불러오기 실패',
'memories.error.addPhotos': '사진 추가 실패',
'memories.error.removePhoto': '사진 제거 실패',
'memories.error.toggleSharing': '공유 업데이트 실패',
'memories.saveRouteNotConfigured':
'이 공급자에 대해 저장 경로가 설정되지 않았습니다',
'memories.testRouteNotConfigured':
'이 공급자에 대해 테스트 경로가 설정되지 않았습니다',
'memories.fillRequiredFields': '모든 필수 항목을 입력하세요',
};
export default memories;
+20
View File
@@ -0,0 +1,20 @@
import type { TranslationStrings } from '../types';
const nav: TranslationStrings = {
'nav.trip': '여행',
'nav.share': '공유',
'nav.settings': '설정',
'nav.admin': '관리자',
'nav.logout': '로그아웃',
'nav.lightMode': '라이트 모드',
'nav.darkMode': '다크 모드',
'nav.autoMode': '자동 모드',
'nav.administrator': '관리자',
'nav.myTrips': '내 여행',
'nav.profile': '프로필',
'nav.bottomSettings': '설정',
'nav.bottomAdmin': '관리자 설정',
'nav.bottomLogout': '로그아웃',
'nav.bottomAdminBadge': '관리자',
};
export default nav;
+43
View File
@@ -0,0 +1,43 @@
import type { TranslationStrings } from '../types';
const notif: TranslationStrings = {
'notif.test.title': '[테스트] 알림',
'notif.test.simple.text': '간단한 테스트 알림입니다.',
'notif.test.boolean.text': '이 테스트 알림을 수락하시겠습니까?',
'notif.test.navigate.text': '아래를 클릭하여 대시보드로 이동하세요.',
'notif.trip_invite.title': '여행 초대',
'notif.trip_invite.text': '{actor}이(가) {trip}에 초대했습니다',
'notif.booking_change.title': '예약 업데이트됨',
'notif.booking_change.text': '{actor}이(가) {trip}의 예약을 업데이트했습니다',
'notif.trip_reminder.title': '여행 리마인더',
'notif.trip_reminder.text': '여행 {trip}이(가) 곧 시작됩니다!',
'notif.todo_due.title': '할 일 마감',
'notif.todo_due.text': '{trip}의 {todo}이(가) {due}에 마감됩니다',
'notif.vacay_invite.title': 'Vacay 퓨전 초대',
'notif.vacay_invite.text': '{actor}이(가) 휴가 계획 공유에 초대했습니다',
'notif.photos_shared.title': '사진 공유됨',
'notif.photos_shared.text':
'{actor}이(가) {trip}에서 {count}장의 사진을 공유했습니다',
'notif.collab_message.title': '새 메시지',
'notif.collab_message.text': '{actor}이(가) {trip}에서 메시지를 보냈습니다',
'notif.packing_tagged.title': '짐 목록 배정',
'notif.packing_tagged.text':
'{actor}이(가) {trip}의 {category}에 배정했습니다',
'notif.version_available.title': '새 버전 사용 가능',
'notif.version_available.text': 'TREK {version}이(가) 사용 가능합니다',
'notif.action.view_trip': '여행 보기',
'notif.action.view_collab': '메시지 보기',
'notif.action.view_packing': '짐 목록 보기',
'notif.action.view_photos': '사진 보기',
'notif.action.view_vacay': 'Vacay 보기',
'notif.action.view_admin': '관리자로 이동',
'notif.action.view': '보기',
'notif.action.accept': '수락',
'notif.action.decline': '거절',
'notif.generic.title': '알림',
'notif.generic.text': '새 알림이 있습니다',
'notif.dev.unknown_event.title': '[DEV] 알 수 없는 이벤트',
'notif.dev.unknown_event.text':
'이벤트 유형 "{event}"이(가) EVENT_NOTIFICATION_CONFIG에 등록되지 않았습니다',
};
export default notif;
+39
View File
@@ -0,0 +1,39 @@
import type { TranslationStrings } from '../types';
const notifications: TranslationStrings = {
'notifications.title': '알림',
'notifications.markAllRead': '모두 읽음으로 표시',
'notifications.deleteAll': '모두 삭제',
'notifications.showAll': '모든 알림 보기',
'notifications.empty': '알림 없음',
'notifications.emptyDescription': '모두 확인했습니다!',
'notifications.all': '전체',
'notifications.unreadOnly': '읽지 않음',
'notifications.markRead': '읽음으로 표시',
'notifications.markUnread': '읽지 않음으로 표시',
'notifications.delete': '삭제',
'notifications.system': '시스템',
'notifications.synologySessionCleared.title': 'Synology Photos 연결 해제됨',
'notifications.synologySessionCleared.text':
'서버 또는 계정이 변경되었습니다 — 설정에서 연결을 다시 테스트하세요.',
'notifications.versionAvailable.title': '업데이트 사용 가능',
'notifications.versionAvailable.text':
'TREK {version}이(가) 사용 가능합니다.',
'notifications.versionAvailable.button': '상세 보기',
'notifications.test.title': '{actor}의 테스트 알림',
'notifications.test.text': '간단한 테스트 알림입니다.',
'notifications.test.booleanTitle': '{actor}이(가) 승인을 요청합니다',
'notifications.test.booleanText':
'테스트 boolean 알림입니다. 아래에서 작업을 선택하세요.',
'notifications.test.accept': '승인',
'notifications.test.decline': '거절',
'notifications.test.navigateTitle': '확인할 항목이 있습니다',
'notifications.test.navigateText': '테스트 navigate 알림입니다.',
'notifications.test.goThere': '이동',
'notifications.test.adminTitle': '관리자 방송',
'notifications.test.adminText':
'{actor}이(가) 모든 관리자에게 테스트 알림을 보냈습니다.',
'notifications.test.tripTitle': '{actor}이(가) 여행에 게시했습니다',
'notifications.test.tripText': '여행 "{trip}"의 테스트 알림입니다.',
};
export default notifications;
+87
View File
@@ -0,0 +1,87 @@
import type { TranslationStrings } from '../types';
const oauth: TranslationStrings = {
'oauth.scope.group.trips': '여행',
'oauth.scope.group.places': '장소',
'oauth.scope.group.atlas': 'Atlas',
'oauth.scope.group.packing': '짐 목록',
'oauth.scope.group.todos': '할 일',
'oauth.scope.group.budget': '예산',
'oauth.scope.group.reservations': '예약',
'oauth.scope.group.collab': '협업',
'oauth.scope.group.notifications': '알림',
'oauth.scope.group.vacay': '휴가',
'oauth.scope.group.geo': '지리',
'oauth.scope.group.weather': '날씨',
'oauth.scope.group.journey': 'Journey',
'oauth.scope.trips:read.label': '여행 및 일정 보기',
'oauth.scope.trips:read.description': '여행, 날, 일별 메모, 멤버 읽기',
'oauth.scope.trips:write.label': '여행 및 일정 편집',
'oauth.scope.trips:write.description':
'여행, 날, 메모 만들기 및 업데이트, 멤버 관리',
'oauth.scope.trips:delete.label': '여행 삭제',
'oauth.scope.trips:delete.description':
'전체 여행 영구 삭제 — 이 작업은 되돌릴 수 없습니다',
'oauth.scope.trips:share.label': '공유 링크 관리',
'oauth.scope.trips:share.description':
'여행의 공개 공유 링크 만들기, 업데이트, 취소',
'oauth.scope.places:read.label': '장소 및 지도 데이터 보기',
'oauth.scope.places:read.description': '장소, 날 배정, 태그, 카테고리 읽기',
'oauth.scope.places:write.label': '장소 관리',
'oauth.scope.places:write.description':
'장소, 배정, 태그 만들기, 업데이트, 삭제',
'oauth.scope.atlas:read.label': 'Atlas 보기',
'oauth.scope.atlas:read.description': '방문한 나라, 지역, 버킷 리스트 읽기',
'oauth.scope.atlas:write.label': 'Atlas 관리',
'oauth.scope.atlas:write.description':
'방문한 나라 및 지역 표시, 버킷 리스트 관리',
'oauth.scope.packing:read.label': '짐 목록 보기',
'oauth.scope.packing:read.description': '짐 항목, 가방, 카테고리 배정 읽기',
'oauth.scope.packing:write.label': '짐 목록 관리',
'oauth.scope.packing:write.description':
'짐 항목 및 가방 추가, 업데이트, 삭제, 체크, 순서 변경',
'oauth.scope.todos:read.label': '할 일 목록 보기',
'oauth.scope.todos:read.description': '여행 할 일 항목 및 카테고리 배정 읽기',
'oauth.scope.todos:write.label': '할 일 목록 관리',
'oauth.scope.todos:write.description':
'할 일 항목 만들기, 업데이트, 체크, 삭제, 순서 변경',
'oauth.scope.budget:read.label': '예산 보기',
'oauth.scope.budget:read.description': '예산 항목 및 지출 내역 읽기',
'oauth.scope.budget:write.label': '예산 관리',
'oauth.scope.budget:write.description': '예산 항목 만들기, 업데이트, 삭제',
'oauth.scope.reservations:read.label': '예약 보기',
'oauth.scope.reservations:read.description': '예약 및 숙박 상세 정보 읽기',
'oauth.scope.reservations:write.label': '예약 관리',
'oauth.scope.reservations:write.description':
'예약 만들기, 업데이트, 삭제, 순서 변경',
'oauth.scope.collab:read.label': '협업 보기',
'oauth.scope.collab:read.description': '협업 메모, 투표, 메시지 읽기',
'oauth.scope.collab:write.label': '협업 관리',
'oauth.scope.collab:write.description':
'협업 메모, 투표, 메시지 만들기, 업데이트, 삭제',
'oauth.scope.notifications:read.label': '알림 보기',
'oauth.scope.notifications:read.description':
'앱 내 알림 및 읽지 않은 수 읽기',
'oauth.scope.notifications:write.label': '알림 관리',
'oauth.scope.notifications:write.description': '알림 읽음 표시 및 응답',
'oauth.scope.vacay:read.label': '휴가 계획 보기',
'oauth.scope.vacay:read.description': '휴가 계획 데이터, 항목, 통계 읽기',
'oauth.scope.vacay:write.label': '휴가 계획 관리',
'oauth.scope.vacay:write.description':
'휴가 항목, 공휴일, 팀 계획 만들기 및 관리',
'oauth.scope.geo:read.label': '지도 및 지오코딩',
'oauth.scope.geo:read.description':
'위치 검색, 지도 URL 확인, 좌표 역지오코딩',
'oauth.scope.weather:read.label': '날씨 예보',
'oauth.scope.weather:read.description':
'여행 위치 및 날짜의 날씨 예보 가져오기',
'oauth.scope.journey:read.label': 'Journey 보기',
'oauth.scope.journey:read.description': 'Journey, 항목, 기여자 목록 읽기',
'oauth.scope.journey:write.label': 'Journey 관리',
'oauth.scope.journey:write.description':
'Journey 및 항목 만들기, 업데이트, 삭제',
'oauth.scope.journey:share.label': 'Journey 링크 관리',
'oauth.scope.journey:share.description':
'Journey의 공개 공유 링크 만들기, 업데이트, 취소',
};
export default oauth;
+185
View File
@@ -0,0 +1,185 @@
import type { TranslationStrings } from '../types';
const packing: TranslationStrings = {
'packing.title': '짐 목록',
'packing.empty': '짐 목록이 비어 있습니다',
'packing.import': '가져오기',
'packing.importTitle': '짐 목록 가져오기',
'packing.importHint':
'한 줄에 하나의 항목. 형식: 카테고리, 이름, 무게(g, 선택), 가방(선택), checked/unchecked(선택)',
'packing.importPlaceholder':
'위생, 칫솔\n의류, 티셔츠, 200\n서류, 여권, , 기내 수하물\n전자기기, 충전기, 50, 캐리어, checked',
'packing.importCsv': 'CSV/TXT 불러오기',
'packing.importAction': '{count}개 가져오기',
'packing.importSuccess': '{count}개 항목을 가져왔습니다',
'packing.importError': '가져오기 실패',
'packing.importEmpty': '가져올 항목이 없습니다',
'packing.progress': '{total}개 중 {packed}개 완료 ({percent}%)',
'packing.clearChecked': '체크된 {count}개 제거',
'packing.clearCheckedShort': '{count}개 제거',
'packing.suggestions': '제안',
'packing.suggestionsTitle': '제안 추가',
'packing.allSuggested': '모든 제안이 추가되었습니다',
'packing.allPacked': '모두 완료!',
'packing.addPlaceholder': '새 항목 추가...',
'packing.categoryPlaceholder': '카테고리...',
'packing.filterAll': '전체',
'packing.filterOpen': '미완료',
'packing.filterDone': '완료',
'packing.emptyTitle': '짐 목록이 비어 있습니다',
'packing.emptyHint': '항목을 추가하거나 제안을 사용하세요',
'packing.emptyFiltered': '이 필터와 일치하는 항목이 없습니다',
'packing.menuRename': '이름 변경',
'packing.menuCheckAll': '전체 체크',
'packing.menuUncheckAll': '전체 체크 해제',
'packing.menuDeleteCat': '카테고리 삭제',
'packing.noMembers': '여행 멤버가 없습니다',
'packing.addItem': '항목 추가',
'packing.addItemPlaceholder': '항목 이름...',
'packing.addCategory': '카테고리 추가',
'packing.newCategoryPlaceholder': '카테고리 이름 (예: 의류)',
'packing.applyTemplate': '템플릿 적용',
'packing.template': '템플릿',
'packing.templateApplied': '템플릿에서 {count}개 항목이 추가되었습니다',
'packing.templateError': '템플릿 적용 실패',
'packing.saveAsTemplate': '템플릿으로 저장',
'packing.templateName': '템플릿 이름',
'packing.templateSaved': '짐 목록이 템플릿으로 저장되었습니다',
'packing.bags': '가방',
'packing.noBag': '미배정',
'packing.totalWeight': '총 무게',
'packing.bagName': '가방 이름...',
'packing.addBag': '가방 추가',
'packing.changeCategory': '카테고리 변경',
'packing.confirm.clearChecked': '체크된 {count}개 항목을 제거할까요?',
'packing.confirm.deleteCat':
'카테고리 "{name}"을(를) {count}개 항목과 함께 삭제할까요?',
'packing.defaultCategory': '기타',
'packing.toast.saveError': '저장 실패',
'packing.toast.deleteError': '삭제 실패',
'packing.toast.renameError': '이름 변경 실패',
'packing.toast.addError': '추가 실패',
'packing.suggestions.items': [
{
name: '여권',
category: '서류',
},
{
name: '신분증',
category: '서류',
},
{
name: '여행자 보험',
category: '서류',
},
{
name: '항공권',
category: '서류',
},
{
name: '신용카드',
category: '금융',
},
{
name: '현금',
category: '금융',
},
{
name: '비자',
category: '서류',
},
{
name: '티셔츠',
category: '의류',
},
{
name: '바지',
category: '의류',
},
{
name: '속옷',
category: '의류',
},
{
name: '양말',
category: '의류',
},
{
name: '재킷',
category: '의류',
},
{
name: '잠옷',
category: '의류',
},
{
name: '수영복',
category: '의류',
},
{
name: '우비',
category: '의류',
},
{
name: '편한 신발',
category: '의류',
},
{
name: '칫솔',
category: '세면도구',
},
{
name: '치약',
category: '세면도구',
},
{
name: '샴푸',
category: '세면도구',
},
{
name: '데오도란트',
category: '세면도구',
},
{
name: '자외선 차단제',
category: '세면도구',
},
{
name: '면도기',
category: '세면도구',
},
{
name: '충전기',
category: '전자기기',
},
{
name: '보조 배터리',
category: '전자기기',
},
{
name: '헤드폰',
category: '전자기기',
},
{
name: '여행용 어댑터',
category: '전자기기',
},
{
name: '카메라',
category: '전자기기',
},
{
name: '진통제',
category: '건강',
},
{
name: '반창고',
category: '건강',
},
{
name: '소독제',
category: '건강',
},
],
};
export default packing;
+10
View File
@@ -0,0 +1,10 @@
import type { TranslationStrings } from '../types';
const pdf: TranslationStrings = {
'pdf.travelPlan': '여행 계획',
'pdf.planned': '계획됨',
'pdf.costLabel': '비용 (원)',
'pdf.preview': 'PDF 미리보기',
'pdf.saveAsPdf': 'PDF로 저장',
};
export default pdf;
+60
View File
@@ -0,0 +1,60 @@
import type { TranslationStrings } from '../types';
const perm: TranslationStrings = {
'perm.title': '권한 설정',
'perm.subtitle': '앱 전체에서 누가 작업을 수행할 수 있는지 제어합니다',
'perm.saved': '권한 설정이 저장되었습니다',
'perm.resetDefaults': '기본값으로 초기화',
'perm.customized': '맞춤 설정됨',
'perm.level.admin': '관리자만',
'perm.level.tripOwner': '여행 소유자',
'perm.level.tripMember': '여행 멤버',
'perm.level.everybody': '모든 사람',
'perm.cat.trip': '여행 관리',
'perm.cat.members': '멤버 관리',
'perm.cat.files': '파일',
'perm.cat.content': '콘텐츠 및 일정',
'perm.cat.extras': '예산, 짐 목록 및 협업',
'perm.action.trip_create': '여행 만들기',
'perm.action.trip_edit': '여행 상세 편집',
'perm.action.trip_delete': '여행 삭제',
'perm.action.trip_archive': '여행 보관/복원',
'perm.action.trip_cover_upload': '커버 이미지 업로드',
'perm.action.member_manage': '멤버 추가/제거',
'perm.action.file_upload': '파일 업로드',
'perm.action.file_edit': '파일 메타데이터 편집',
'perm.action.file_delete': '파일 삭제',
'perm.action.place_edit': '장소 추가/편집/삭제',
'perm.action.day_edit': '날, 메모 및 배정 편집',
'perm.action.reservation_edit': '예약 관리',
'perm.action.budget_edit': '예산 관리',
'perm.action.packing_edit': '짐 목록 관리',
'perm.action.collab_edit': '협업 (메모, 투표, 채팅)',
'perm.action.share_manage': '공유 링크 관리',
'perm.actionHint.trip_create': '누가 새 여행을 만들 수 있는지',
'perm.actionHint.trip_edit':
'누가 여행 이름, 날짜, 설명, 통화를 변경할 수 있는지',
'perm.actionHint.trip_delete': '누가 여행을 영구 삭제할 수 있는지',
'perm.actionHint.trip_archive': '누가 여행을 보관하거나 복원할 수 있는지',
'perm.actionHint.trip_cover_upload':
'누가 커버 이미지를 업로드하거나 변경할 수 있는지',
'perm.actionHint.member_manage':
'누가 여행 멤버를 초대하거나 제거할 수 있는지',
'perm.actionHint.file_upload': '누가 여행에 파일을 업로드할 수 있는지',
'perm.actionHint.file_edit': '누가 파일 설명 및 링크를 편집할 수 있는지',
'perm.actionHint.file_delete':
'누가 파일을 휴지통으로 이동하거나 영구 삭제할 수 있는지',
'perm.actionHint.place_edit': '누가 장소를 추가, 편집, 삭제할 수 있는지',
'perm.actionHint.day_edit':
'누가 날, 일별 메모, 장소 배정을 편집할 수 있는지',
'perm.actionHint.reservation_edit':
'누가 예약을 만들고, 편집하고, 삭제할 수 있는지',
'perm.actionHint.budget_edit':
'누가 예산 항목을 만들고, 편집하고, 삭제할 수 있는지',
'perm.actionHint.packing_edit': '누가 짐 항목과 가방을 관리할 수 있는지',
'perm.actionHint.collab_edit':
'누가 메모, 투표를 만들고 메시지를 보낼 수 있는지',
'perm.actionHint.share_manage':
'누가 공개 공유 링크를 만들거나 삭제할 수 있는지',
};
export default perm;
+25
View File
@@ -0,0 +1,25 @@
import type { TranslationStrings } from '../types';
const photos: TranslationStrings = {
'photos.title': '사진',
'photos.subtitle': '{trip}의 사진 {count}장',
'photos.dropHere': '여기에 사진을 놓으세요...',
'photos.dropHereActive': '여기에 사진을 놓으세요',
'photos.captionForAll': '캡션 (전체)',
'photos.captionPlaceholder': '선택적 캡션...',
'photos.addCaption': '캡션 추가...',
'photos.allDays': '모든 날',
'photos.noPhotos': '아직 사진이 없습니다',
'photos.uploadHint': '여행 사진을 업로드하세요',
'photos.clickToSelect': '또는 클릭하여 선택',
'photos.linkPlace': '장소 연결',
'photos.noPlace': '장소 없음',
'photos.uploadN': '{n}장 사진 업로드',
'photos.linkDay': '날 연결',
'photos.noDay': '날 없음',
'photos.dayLabel': '{number}일차',
'photos.photoSelected': '사진 선택됨',
'photos.photosSelected': '사진 선택됨',
'photos.fileTypeHint': 'JPG, PNG, WebP · 최대 10 MB · 최대 30장',
};
export default photos;
+90
View File
@@ -0,0 +1,90 @@
import type { TranslationStrings } from '../types';
const places: TranslationStrings = {
'places.addPlace': '장소/활동 추가',
'places.importFile': '파일 가져오기',
'places.sidebarDrop': '끌어다 가져오기',
'places.importFileHint':
'Google My Maps, Google Earth 또는 GPS 추적기 등의 .gpx, .kml, .kmz 파일을 가져옵니다.',
'places.importFileDropHere': '파일을 선택하거나 여기에 끌어다 놓으세요',
'places.importFileDropActive': '파일을 놓으세요',
'places.importFileUnsupported':
'지원하지 않는 파일 형식입니다. .gpx, .kml 또는 .kmz를 사용하세요.',
'places.importFileTooLarge':
'파일이 너무 큽니다. 최대 업로드 크기는 {maxMb} MB입니다.',
'places.importFileError': '가져오기 실패',
'places.importAllSkipped': '모든 장소가 이미 여행에 포함되어 있습니다.',
'places.gpxImported': 'GPX에서 {count}개 장소를 가져왔습니다',
'places.gpxImportTypes': '무엇을 가져올까요?',
'places.gpxImportWaypoints': '웨이포인트',
'places.gpxImportRoutes': '경로',
'places.gpxImportTracks': '트랙 (경로 형상 포함)',
'places.gpxImportNoneSelected': '가져올 유형을 하나 이상 선택하세요.',
'places.kmlImportTypes': '무엇을 가져올까요?',
'places.kmlImportPoints': '포인트 (Placemarks)',
'places.kmlImportPaths': '경로 (LineStrings)',
'places.kmlImportNoneSelected': '가져올 유형을 하나 이상 선택하세요.',
'places.selectionCount': '{count}개 선택됨',
'places.deleteSelected': '선택 항목 삭제',
'places.kmlKmzImported': 'KMZ/KML에서 {count}개 장소를 가져왔습니다',
'places.urlResolved': 'URL에서 장소를 가져왔습니다',
'places.importList': '목록 가져오기',
'places.kmlKmzSummaryValues':
'총 Placemarks: {total} · 가져옴: {created} · 건너뜀: {skipped}',
'places.importGoogleList': 'Google 목록',
'places.importNaverList': '네이버 목록',
'places.googleListHint':
'공유된 Google Maps 목록 링크를 붙여넣어 모든 장소를 가져옵니다.',
'places.googleListImported': '"{list}"에서 {count}개 장소를 가져왔습니다',
'places.googleListError': 'Google Maps 목록 가져오기 실패',
'places.naverListHint':
'공유된 네이버 지도 목록 링크를 붙여넣어 모든 장소를 가져옵니다.',
'places.naverListImported': '"{list}"에서 {count}개 장소를 가져왔습니다',
'places.naverListError': '네이버 지도 목록 가져오기 실패',
'places.viewDetails': '상세 보기',
'places.assignToDay': '어느 날에 추가할까요?',
'places.all': '전체',
'places.unplanned': '미계획',
'places.filterTracks': '트랙',
'places.search': '장소 검색...',
'places.allCategories': '모든 카테고리',
'places.categoriesSelected': '카테고리',
'places.clearFilter': '필터 지우기',
'places.count': '장소 {count}개',
'places.countSingular': '장소 1개',
'places.allPlanned': '모든 장소가 계획되었습니다',
'places.noneFound': '장소를 찾을 수 없습니다',
'places.editPlace': '장소 편집',
'places.formName': '이름',
'places.formNamePlaceholder': '예: 에펠탑',
'places.formDescription': '설명',
'places.formDescriptionPlaceholder': '간단한 설명...',
'places.formAddress': '주소',
'places.formAddressPlaceholder': '도로, 도시, 국가',
'places.formLat': '위도 (예: 48.8566)',
'places.formLng': '경도 (예: 2.3522)',
'places.formCategory': '카테고리',
'places.noCategory': '카테고리 없음',
'places.categoryNamePlaceholder': '카테고리 이름',
'places.formTime': '시간',
'places.startTime': '시작',
'places.endTime': '종료',
'places.endTimeBeforeStart': '종료 시간이 시작 시간보다 앞입니다',
'places.timeCollision': '시간 겹침:',
'places.formWebsite': '웹사이트',
'places.formNotes': '메모',
'places.formNotesPlaceholder': '개인 메모...',
'places.formReservation': '예약',
'places.reservationNotesPlaceholder': '예약 메모, 확인 번호...',
'places.mapsSearchPlaceholder': '장소 검색...',
'places.mapsSearchError': '장소 검색 실패.',
'places.loadingDetails': '장소 상세 정보 불러오는 중…',
'places.osmHint':
'OpenStreetMap 검색 사용 중 (사진, 영업 시간, 평점 없음). 전체 정보를 위해 설정에서 Google API 키를 추가하세요.',
'places.osmActive':
'OpenStreetMap으로 검색 중 (사진, 평점, 영업 시간 없음). 향상된 데이터를 위해 설정에서 Google API 키를 추가하세요.',
'places.categoryCreateError': '카테고리 생성 실패',
'places.nameRequired': '이름을 입력하세요',
'places.saveError': '저장 실패',
};
export default places;
+67
View File
@@ -0,0 +1,67 @@
import type { TranslationStrings } from '../types';
const planner: TranslationStrings = {
'planner.places': '장소',
'planner.bookings': '예약',
'planner.packingList': '짐 목록',
'planner.documents': '문서',
'planner.dayPlan': '일별 계획',
'planner.reservations': '예약',
'planner.minTwoPlaces': '경로 계산에 좌표가 있는 장소가 최소 2개 필요합니다',
'planner.noGeoPlaces': '좌표가 있는 장소가 없습니다',
'planner.routeCalculated': '경로가 계산되었습니다',
'planner.routeCalcFailed': '경로를 계산할 수 없습니다',
'planner.routeError': '경로 계산 중 오류',
'planner.icsExportFailed': 'ICS 내보내기 실패',
'planner.routeOptimized': '경로가 최적화되었습니다',
'planner.reservationUpdated': '예약이 업데이트되었습니다',
'planner.reservationAdded': '예약이 추가되었습니다',
'planner.confirmDeleteReservation': '예약을 삭제할까요?',
'planner.reservationDeleted': '예약이 삭제되었습니다',
'planner.days': '일',
'planner.allPlaces': '모든 장소',
'planner.totalPlaces': '총 {n}개 장소',
'planner.noDaysPlanned': '아직 계획된 날이 없습니다',
'planner.editTrip': '여행 편집 →',
'planner.placeOne': '장소 1개',
'planner.placeN': '장소 {n}개',
'planner.addNote': '메모 추가',
'planner.noEntries': '이 날에 항목이 없습니다',
'planner.addPlace': '장소/활동 추가',
'planner.addPlaceShort': '+ 장소/활동 추가',
'planner.resPending': '예약 대기 중 · ',
'planner.resConfirmed': '예약 확정 · ',
'planner.notePlaceholder': '메모…',
'planner.noteTimePlaceholder': '시간 (선택)',
'planner.noteExamplePlaceholder':
'예: 14:30 중앙역에서 S3, 7번 부두에서 페리, 점심 휴식…',
'planner.totalCost': '총 비용',
'planner.searchPlaces': '장소 검색…',
'planner.allCategories': '모든 카테고리',
'planner.noPlacesFound': '장소를 찾을 수 없습니다',
'planner.addFirstPlace': '첫 번째 장소 추가',
'planner.noReservations': '예약 없음',
'planner.addFirstReservation': '첫 번째 예약 추가',
'planner.new': '새로 만들기',
'planner.addToDay': '+ 날에 추가',
'planner.calculating': '계산 중…',
'planner.route': '경로',
'planner.optimize': '최적화',
'planner.openGoogleMaps': 'Google Maps에서 열기',
'planner.selectDayHint': '왼쪽 목록에서 날을 선택하여 일별 계획을 보세요',
'planner.noPlacesForDay': '이 날에 아직 장소가 없습니다',
'planner.addPlacesLink': '장소 추가 →',
'planner.minTotal': '분 합계',
'planner.noReservation': '예약 없음',
'planner.removeFromDay': '날에서 제거',
'planner.addToThisDay': '날에 추가',
'planner.overview': '개요',
'planner.noDays': '아직 날이 없습니다',
'planner.editTripToAddDays': '여행을 편집하여 날을 추가하세요',
'planner.dayCount': '{n}일',
'planner.clickToUnlock': '클릭하여 잠금 해제',
'planner.keepPosition': '경로 최적화 중 위치 유지',
'planner.dayDetails': '일별 상세',
'planner.dayN': '{n}일차',
};
export default planner;
+25
View File
@@ -0,0 +1,25 @@
import type { TranslationStrings } from '../types';
const register: TranslationStrings = {
'register.passwordMismatch': '비밀번호가 일치하지 않습니다',
'register.passwordTooShort': '비밀번호는 최소 8자 이상이어야 합니다',
'register.failed': '회원가입 실패',
'register.getStarted': '시작하기',
'register.subtitle': '계정을 만들고 꿈의 여행을 계획하세요.',
'register.feature1': '무제한 여행 계획',
'register.feature2': '인터랙티브 지도 보기',
'register.feature3': '장소 및 카테고리 관리',
'register.feature4': '예약 추적',
'register.feature5': '짐 목록 만들기',
'register.feature6': '사진 및 파일 저장',
'register.createAccount': '계정 만들기',
'register.startPlanning': '여행 계획 시작',
'register.minChars': '최소 6자',
'register.confirmPassword': '비밀번호 확인',
'register.repeatPassword': '비밀번호 재입력',
'register.registering': '가입 중...',
'register.register': '회원가입',
'register.hasAccount': '이미 계정이 있으신가요?',
'register.signIn': '로그인',
};
export default register;
+116
View File
@@ -0,0 +1,116 @@
import type { TranslationStrings } from '../types';
const reservations: TranslationStrings = {
'reservations.title': '예약',
'reservations.empty': '아직 예약이 없습니다',
'reservations.emptyHint': '항공, 호텔 등의 예약을 추가하세요',
'reservations.add': '예약 추가',
'reservations.addManual': '직접 예약',
'reservations.placeHint':
'팁: 예약은 일별 계획과 연결하기 위해 장소에서 직접 만드는 것이 가장 좋습니다.',
'reservations.confirmed': '확정됨',
'reservations.pending': '대기 중',
'reservations.summary': '{confirmed}개 확정, {pending}개 대기 중',
'reservations.fromPlan': '계획에서',
'reservations.showFiles': '파일 보기',
'reservations.editTitle': '예약 편집',
'reservations.status': '상태',
'reservations.datetime': '날짜 및 시간',
'reservations.startTime': '시작 시간',
'reservations.endTime': '종료 시간',
'reservations.date': '날짜',
'reservations.time': '시간',
'reservations.timeAlt': '시간 (대안, 예: 19:30)',
'reservations.notes': '메모',
'reservations.notesPlaceholder': '추가 메모...',
'reservations.meta.airline': '항공사',
'reservations.meta.flightNumber': '항공편 번호',
'reservations.meta.from': '출발',
'reservations.meta.to': '도착',
'reservations.needsReview': '검토 필요',
'reservations.needsReviewHint':
'공항이 자동으로 매칭되지 않았습니다 — 위치를 확인해 주세요.',
'reservations.searchLocation': '역, 항구, 주소 검색…',
'reservations.meta.trainNumber': '열차 번호',
'reservations.meta.platform': '플랫폼',
'reservations.meta.seat': '좌석',
'reservations.meta.checkIn': '체크인',
'reservations.meta.checkInUntil': '체크인 마감',
'reservations.meta.checkOut': '체크아웃',
'reservations.meta.linkAccommodation': '숙박',
'reservations.meta.pickAccommodation': '숙박 연결',
'reservations.meta.noAccommodation': '없음',
'reservations.meta.hotelPlace': '숙박',
'reservations.meta.pickHotel': '숙박 선택',
'reservations.meta.fromDay': '부터',
'reservations.meta.toDay': '까지',
'reservations.meta.selectDay': '날 선택',
'reservations.type.flight': '항공',
'reservations.type.hotel': '숙박',
'reservations.type.restaurant': '레스토랑',
'reservations.type.train': '기차',
'reservations.type.car': '차량',
'reservations.type.cruise': '크루즈',
'reservations.type.event': '이벤트',
'reservations.type.tour': '투어',
'reservations.type.other': '기타',
'reservations.confirm.delete': '예약 "{name}"을(를) 삭제할까요?',
'reservations.confirm.deleteTitle': '예약을 삭제할까요?',
'reservations.confirm.deleteBody': '"{name}"이(가) 영구 삭제됩니다.',
'reservations.toast.updated': '예약이 업데이트되었습니다',
'reservations.toast.removed': '예약이 삭제되었습니다',
'reservations.toast.fileUploaded': '파일이 업로드되었습니다',
'reservations.toast.uploadError': '업로드 실패',
'reservations.newTitle': '새 예약',
'reservations.bookingType': '예약 유형',
'reservations.titleLabel': '제목',
'reservations.titlePlaceholder': '예: 대한항공 KE123, 호텔 신라, ...',
'reservations.locationAddress': '위치 / 주소',
'reservations.locationPlaceholder': '주소, 공항, 호텔...',
'reservations.confirmationCode': '예약 코드',
'reservations.confirmationPlaceholder': '예: ABC12345',
'reservations.day': '날',
'reservations.noDay': '날 없음',
'reservations.place': '장소',
'reservations.noPlace': '장소 없음',
'reservations.pendingSave': '저장될 예정…',
'reservations.uploading': '업로드 중...',
'reservations.attachFile': '파일 첨부',
'reservations.linkExisting': '기존 파일 연결',
'reservations.toast.saveError': '저장 실패',
'reservations.toast.updateError': '업데이트 실패',
'reservations.toast.deleteError': '삭제 실패',
'reservations.confirm.remove': '"{name}"의 예약을 제거할까요?',
'reservations.linkAssignment': '날 배정에 연결',
'reservations.pickAssignment': '계획에서 배정을 선택하세요...',
'reservations.noAssignment': '연결 없음 (독립)',
'reservations.price': '가격',
'reservations.budgetCategory': '예산 카테고리',
'reservations.budgetCategoryPlaceholder': '예: 교통, 숙박',
'reservations.budgetCategoryAuto': '자동 (예약 유형에서)',
'reservations.budgetHint': '저장 시 예산 항목이 자동으로 생성됩니다.',
'reservations.departureDate': '출발',
'reservations.arrivalDate': '도착',
'reservations.departureTime': '출발 시간',
'reservations.arrivalTime': '도착 시간',
'reservations.pickupDate': '픽업',
'reservations.returnDate': '반납',
'reservations.pickupTime': '픽업 시간',
'reservations.returnTime': '반납 시간',
'reservations.endDate': '종료 날짜',
'reservations.meta.departureTimezone': '출발 시간대',
'reservations.meta.arrivalTimezone': '도착 시간대',
'reservations.span.departure': '출발',
'reservations.span.arrival': '도착',
'reservations.span.inTransit': '이동 중',
'reservations.span.pickup': '픽업',
'reservations.span.return': '반납',
'reservations.span.active': '활성',
'reservations.span.start': '시작',
'reservations.span.end': '종료',
'reservations.span.ongoing': '진행 중',
'reservations.validation.endBeforeStart':
'종료 날짜/시간은 시작 날짜/시간 이후여야 합니다',
'reservations.addBooking': '예약 추가',
};
export default reservations;
+295
View File
@@ -0,0 +1,295 @@
import type { TranslationStrings } from '../types';
const settings: TranslationStrings = {
'settings.title': '설정',
'settings.subtitle': '개인 설정을 구성하세요',
'settings.tabs.display': '화면',
'settings.tabs.map': '지도',
'settings.tabs.notifications': '알림',
'settings.tabs.integrations': '통합',
'settings.tabs.account': '계정',
'settings.tabs.offline': '오프라인',
'settings.tabs.about': '정보',
'settings.map': '지도',
'settings.mapTemplate': '지도 템플릿',
'settings.mapTemplatePlaceholder.select': '템플릿 선택...',
'settings.mapDefaultHint': '비워두면 OpenStreetMap (기본값) 사용',
'settings.mapTemplatePlaceholder':
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
'settings.mapHint': '지도 타일 URL 템플릿',
'settings.mapProvider': '지도 공급자',
'settings.mapProviderHint':
'여행 플래너 및 Journey 지도에 영향을 줍니다. Atlas는 항상 Leaflet을 사용합니다.',
'settings.mapLeafletSubtitle': '클래식 2D, 모든 래스터 타일',
'settings.mapMapboxSubtitle': '벡터 타일, 3D 건물 및 지형',
'settings.mapExperimental': '실험적',
'settings.mapMapboxToken': 'Mapbox 액세스 토큰',
'settings.mapMapboxTokenHint': '공개 토큰 (pk.*) 출처',
'settings.mapMapboxTokenLink': 'mapbox.com → 액세스 토큰',
'settings.mapStyle': '지도 스타일',
'settings.mapStylePlaceholder': 'Mapbox 스타일 선택',
'settings.mapStyleHint': '프리셋 또는 mapbox://styles/USER/ID URL 직접 입력',
'settings.map3dBuildings': '3D 건물 및 지형',
'settings.map3dHint':
'기울기 + 실제 3D 건물 돌출 — 위성 포함 모든 스타일에서 작동합니다.',
'settings.mapHighQuality': '고품질 모드',
'settings.mapHighQualityHint':
'안티앨리어싱 + 구형 투영으로 선명한 경계와 현실적인 지구 뷰를 제공합니다.',
'settings.mapHighQualityWarning':
'저사양 기기에서 성능에 영향을 줄 수 있습니다.',
'settings.mapTipLabel': '팁:',
'settings.mapTip':
'우클릭 후 드래그하여 지도를 회전/기울이세요. 가운데 클릭으로 장소를 추가할 수 있습니다 (우클릭은 회전 전용).',
'settings.latitude': '위도',
'settings.longitude': '경도',
'settings.saveMap': '지도 저장',
'settings.apiKeys': 'API 키',
'settings.mapsKey': 'Google Maps API 키',
'settings.mapsKeyHint':
'장소 검색용. Places API (New) 필요. console.cloud.google.com에서 발급',
'settings.weatherKey': 'OpenWeatherMap API 키',
'settings.weatherKeyHint':
'날씨 데이터용. openweathermap.org/api에서 무료 발급',
'settings.keyPlaceholder': '키 입력...',
'settings.configured': '설정됨',
'settings.saveKeys': '키 저장',
'settings.display': '화면',
'settings.colorMode': '색상 모드',
'settings.light': '라이트',
'settings.dark': '다크',
'settings.auto': '자동',
'settings.language': '언어',
'settings.temperature': '온도 단위',
'settings.timeFormat': '시간 형식',
'settings.bookingLabels': '예약 경로 레이블',
'settings.bookingLabelsHint':
'지도에 역 / 공항 이름을 표시합니다. 끄면 아이콘만 표시됩니다.',
'settings.blurBookingCodes': '예약 코드 흐리게',
'settings.notifications': '알림',
'settings.notifyTripInvite': '여행 초대',
'settings.notifyBookingChange': '예약 변경',
'settings.notifyTripReminder': '여행 리마인더',
'settings.notifyTodoDue': '할 일 마감 임박',
'settings.notifyVacayInvite': 'Vacay 퓨전 초대',
'settings.notifyPhotosShared': '공유된 사진 (Immich)',
'settings.notifyCollabMessage': '채팅 메시지 (Collab)',
'settings.notifyPackingTagged': '짐 목록: 배정',
'settings.notifyWebhook': '웹훅 알림',
'settings.notifyVersionAvailable': '새 버전 사용 가능',
'settings.notificationPreferences.email': '이메일',
'settings.notificationPreferences.webhook': '웹훅',
'settings.notificationPreferences.inapp': '앱 내',
'settings.notificationPreferences.ntfy': 'Ntfy',
'settings.notificationPreferences.noChannels':
'알림 채널이 설정되지 않았습니다. 관리자에게 이메일 또는 웹훅 알림 설정을 요청하세요.',
'settings.webhookUrl.label': '웹훅 URL',
'settings.webhookUrl.placeholder': 'https://discord.com/api/webhooks/...',
'settings.webhookUrl.hint':
'Discord, Slack 또는 사용자 지정 웹훅 URL을 입력하여 알림을 받으세요.',
'settings.webhookUrl.saved': '웹훅 URL이 저장되었습니다',
'settings.webhookUrl.test': '테스트',
'settings.webhookUrl.testSuccess': '테스트 웹훅이 성공적으로 전송되었습니다',
'settings.webhookUrl.testFailed': '테스트 웹훅 실패',
'settings.ntfyUrl.topicLabel': 'Ntfy 토픽',
'settings.ntfyUrl.topicPlaceholder': 'my-trek-alerts',
'settings.ntfyUrl.serverLabel': 'Ntfy 서버 URL (선택)',
'settings.ntfyUrl.serverPlaceholder': 'https://ntfy.sh',
'settings.ntfyUrl.hint':
'ntfy 토픽을 입력하여 푸시 알림을 받으세요. 서버를 비워두면 관리자가 설정한 기본값을 사용합니다.',
'settings.ntfyUrl.tokenLabel': '액세스 토큰 (선택)',
'settings.ntfyUrl.tokenHint': '비밀번호로 보호된 토픽에 필요합니다.',
'settings.ntfyUrl.saved': 'Ntfy 설정이 저장되었습니다',
'settings.ntfyUrl.test': '테스트',
'settings.ntfyUrl.testSuccess':
'테스트 ntfy 알림이 성공적으로 전송되었습니다',
'settings.ntfyUrl.testFailed': '테스트 ntfy 알림 실패',
'settings.ntfyUrl.tokenCleared': '액세스 토큰이 삭제되었습니다',
'settings.notificationsDisabled':
'알림이 설정되지 않았습니다. 관리자에게 이메일 또는 웹훅 알림 활성화를 요청하세요.',
'settings.notificationsActive': '활성 채널',
'settings.notificationsManagedByAdmin': '알림 이벤트는 관리자가 설정합니다.',
'settings.on': '켜기',
'settings.off': '끄기',
'settings.mcp.title': 'MCP 설정',
'settings.mcp.endpoint': 'MCP 엔드포인트',
'settings.mcp.clientConfig': '클라이언트 설정',
'settings.mcp.clientConfigHint':
'<your_token>을 아래 목록의 API 토큰으로 교체하세요. npx 경로는 시스템에 따라 조정해야 할 수 있습니다 (예: Windows의 경우 C:\\PROGRA~1\\nodejs\\npx.cmd).',
'settings.mcp.clientConfigHintOAuth':
'<your_client_id>와 <your_client_secret>을 위에서 생성한 OAuth 2.1 클라이언트 자격 증명으로 교체하세요. mcp-remote가 처음 연결 시 브라우저를 열어 인증을 완료합니다. npx 경로는 시스템에 따라 조정해야 할 수 있습니다 (예: Windows의 경우 C:\\PROGRA~1\\nodejs\\npx.cmd).',
'settings.mcp.copy': '복사',
'settings.mcp.copied': '복사됨!',
'settings.mcp.apiTokens': 'API 토큰',
'settings.mcp.createToken': '새 토큰 만들기',
'settings.mcp.noTokens':
'토큰이 없습니다. MCP 클라이언트 연결을 위해 토큰을 만드세요.',
'settings.mcp.tokenCreatedAt': '생성일',
'settings.mcp.tokenUsedAt': '사용일',
'settings.mcp.deleteTokenTitle': '토큰 삭제',
'settings.mcp.deleteTokenMessage':
'이 토큰은 즉시 무효화됩니다. 이 토큰을 사용하는 MCP 클라이언트는 접근 권한을 잃게 됩니다.',
'settings.mcp.modal.createTitle': 'API 토큰 만들기',
'settings.mcp.modal.tokenName': '토큰 이름',
'settings.mcp.modal.tokenNamePlaceholder':
'예: Claude Desktop, 업무용 노트북',
'settings.mcp.modal.creating': '생성 중…',
'settings.mcp.modal.create': '토큰 만들기',
'settings.mcp.modal.createdTitle': '토큰이 생성되었습니다',
'settings.mcp.modal.createdWarning':
'이 토큰은 한 번만 표시됩니다. 지금 복사하여 저장하세요 — 다시 복구할 수 없습니다.',
'settings.mcp.modal.done': '완료',
'settings.mcp.toast.created': '토큰이 생성되었습니다',
'settings.mcp.toast.createError': '토큰 생성 실패',
'settings.mcp.toast.deleted': '토큰이 삭제되었습니다',
'settings.mcp.toast.deleteError': '토큰 삭제 실패',
'settings.mcp.apiTokensDeprecated':
'API 토큰은 더 이상 사용되지 않으며 향후 버전에서 제거될 예정입니다. 대신 OAuth 2.1 클라이언트를 사용하세요.',
'settings.oauth.clients': 'OAuth 2.1 클라이언트',
'settings.oauth.clientsHint':
'OAuth 2.1 클라이언트를 등록하여 타사 MCP 앱 (Claude Web, Cursor 등)이 정적 토큰 없이 연결할 수 있도록 하세요.',
'settings.oauth.createClient': '새 클라이언트',
'settings.oauth.noClients': '등록된 OAuth 클라이언트가 없습니다.',
'settings.oauth.clientId': '클라이언트 ID',
'settings.oauth.clientSecret': '클라이언트 시크릿',
'settings.oauth.deleteClient': '클라이언트 삭제',
'settings.oauth.deleteClientMessage':
'이 클라이언트와 모든 활성 세션이 영구 삭제됩니다. 이 클라이언트를 사용하는 앱은 즉시 접근 권한을 잃게 됩니다.',
'settings.oauth.rotateSecret': '시크릿 교체',
'settings.oauth.rotateSecretMessage':
'새 클라이언트 시크릿이 생성되고 기존 세션은 즉시 무효화됩니다. 이 대화창을 닫기 전에 앱을 업데이트하세요.',
'settings.oauth.rotateSecretConfirm': '교체',
'settings.oauth.rotateSecretConfirming': '교체 중…',
'settings.oauth.rotateSecretDoneTitle': '새 시크릿이 생성되었습니다',
'settings.oauth.rotateSecretDoneWarning':
'이 시크릿은 한 번만 표시됩니다. 지금 복사하여 앱을 업데이트하세요 — 이전 세션은 모두 무효화되었습니다.',
'settings.oauth.activeSessions': '활성 OAuth 세션',
'settings.oauth.sessionScopes': '권한 범위',
'settings.oauth.sessionExpires': '만료',
'settings.oauth.revoke': '취소',
'settings.oauth.revokeSession': '세션 취소',
'settings.oauth.revokeSessionMessage':
'이 OAuth 세션의 접근 권한이 즉시 취소됩니다.',
'settings.oauth.modal.createTitle': 'OAuth 클라이언트 등록',
'settings.oauth.modal.presets': '빠른 프리셋',
'settings.oauth.modal.clientName': '앱 이름',
'settings.oauth.modal.clientNamePlaceholder': '예: Claude Web, My MCP App',
'settings.oauth.modal.redirectUris': '리디렉션 URI',
'settings.oauth.modal.redirectUrisPlaceholder':
'https://your-app.com/callback\nhttps://your-app.com/auth',
'settings.oauth.modal.redirectUrisHint':
'한 줄에 URI 하나. HTTPS 필수 (localhost 예외). 정확히 일치해야 합니다.',
'settings.oauth.modal.scopes': '허용 권한 범위',
'settings.oauth.modal.scopesHint':
'list_trips 및 get_trip_summary는 항상 사용 가능합니다 — 권한 범위 불필요. AI가 다른 도구를 사용하는 데 필요한 여행 ID를 찾을 수 있습니다.',
'settings.oauth.modal.selectAll': '전체 선택',
'settings.oauth.modal.deselectAll': '전체 해제',
'settings.oauth.modal.creating': '등록 중…',
'settings.oauth.modal.create': '클라이언트 등록',
'settings.oauth.modal.createdTitle': '클라이언트가 등록되었습니다',
'settings.oauth.modal.createdWarning':
'클라이언트 시크릿은 한 번만 표시됩니다. 지금 복사하세요 — 다시 복구할 수 없습니다.',
'settings.oauth.toast.createError': 'OAuth 클라이언트 등록 실패',
'settings.oauth.toast.deleted': 'OAuth 클라이언트가 삭제되었습니다',
'settings.oauth.toast.deleteError': 'OAuth 클라이언트 삭제 실패',
'settings.oauth.toast.revoked': '세션이 취소되었습니다',
'settings.oauth.toast.revokeError': '세션 취소 실패',
'settings.oauth.toast.rotateError': '클라이언트 시크릿 교체 실패',
'settings.account': '계정',
'settings.about': '정보',
'settings.about.reportBug': '버그 신고',
'settings.about.reportBugHint': '문제를 발견하셨나요? 알려주세요',
'settings.about.featureRequest': '기능 요청',
'settings.about.featureRequestHint': '새로운 기능을 제안하세요',
'settings.about.wikiHint': '문서 및 가이드',
'settings.about.supporters.badge': '월간 후원자',
'settings.about.supporters.title': 'TREK의 여행 동반자',
'settings.about.supporters.subtitle':
'다음 여정을 계획하는 동안, 이분들이 TREK의 미래를 함께 만들어가고 있습니다. 월간 후원금은 개발과 실제 작업 시간에 직접 사용되어 TREK이 오픈 소스로 유지될 수 있게 합니다.',
'settings.about.supporters.since': '{date}부터 후원자',
'settings.about.supporters.tierEmpty': '첫 번째 후원자가 되어보세요',
'settings.about.supporter.tier.noReturnTicket': '편도 티켓',
'settings.about.supporter.tier.lostLuggageVip': '분실 수하물 VIP',
'settings.about.supporter.tier.businessClassDreamer':
'비즈니스 클래스 꿈꾸기',
'settings.about.supporter.tier.budgetTraveller': '알뜰 여행자',
'settings.about.supporter.tier.hostelBunkmate': '호스텔 룸메이트',
'settings.about.description':
'TREK은 첫 아이디어부터 마지막 추억까지 여행을 체계적으로 관리하는 자체 호스팅 여행 플래너입니다. 일별 계획, 예산, 짐 목록, 사진 등 모든 것이 하나의 서버에 담겨 있습니다.',
'settings.about.madeWith': '으로 만들어졌습니다',
'settings.about.madeBy': 'Maurice와 성장하는 오픈 소스 커뮤니티가 함께',
'settings.username': '사용자 이름',
'settings.email': '이메일',
'settings.role': '역할',
'settings.roleAdmin': '관리자',
'settings.oidcLinked': '연결됨',
'settings.changePassword': '비밀번호 변경',
'settings.currentPassword': '현재 비밀번호',
'settings.currentPasswordRequired': '현재 비밀번호를 입력하세요',
'settings.newPassword': '새 비밀번호',
'settings.confirmPassword': '새 비밀번호 확인',
'settings.updatePassword': '비밀번호 업데이트',
'settings.passwordRequired': '현재 비밀번호와 새 비밀번호를 입력하세요',
'settings.passwordTooShort': '비밀번호는 최소 8자 이상이어야 합니다',
'settings.passwordMismatch': '비밀번호가 일치하지 않습니다',
'settings.passwordWeak':
'비밀번호는 대문자, 소문자, 숫자, 특수문자를 포함해야 합니다',
'settings.passwordChanged': '비밀번호가 성공적으로 변경되었습니다',
'settings.mustChangePassword':
'계속하기 전에 비밀번호를 변경해야 합니다. 아래에서 새 비밀번호를 설정하세요.',
'settings.deleteAccount': '계정 삭제',
'settings.deleteAccountTitle': '계정을 삭제할까요?',
'settings.deleteAccountWarning':
'계정과 모든 여행, 장소, 파일이 영구 삭제됩니다. 이 작업은 취소할 수 없습니다.',
'settings.deleteAccountConfirm': '영구 삭제',
'settings.deleteBlockedTitle': '삭제 불가',
'settings.deleteBlockedMessage':
'유일한 관리자입니다. 계정을 삭제하기 전에 다른 사용자를 관리자로 승격하세요.',
'settings.roleUser': '사용자',
'settings.saveProfile': '프로필 저장',
'settings.toast.mapSaved': '지도 설정이 저장되었습니다',
'settings.toast.keysSaved': 'API 키가 저장되었습니다',
'settings.toast.displaySaved': '화면 설정이 저장되었습니다',
'settings.toast.profileSaved': '프로필이 저장되었습니다',
'settings.uploadAvatar': '프로필 사진 업로드',
'settings.removeAvatar': '프로필 사진 삭제',
'settings.avatarUploaded': '프로필 사진이 업데이트되었습니다',
'settings.avatarRemoved': '프로필 사진이 삭제되었습니다',
'settings.avatarError': '업로드 실패',
'settings.mfa.title': '2단계 인증 (2FA)',
'settings.mfa.description':
'이메일 및 비밀번호로 로그인할 때 두 번째 단계를 추가합니다. 인증 앱 (Google Authenticator, Authy 등)을 사용하세요.',
'settings.mfa.requiredByPolicy':
'관리자가 2단계 인증을 요구합니다. 앱을 계속 사용하려면 아래에서 인증 앱을 설정하세요.',
'settings.mfa.backupTitle': '백업 코드',
'settings.mfa.backupDescription':
'인증 앱에 접근할 수 없을 때 이 일회용 백업 코드를 사용하세요.',
'settings.mfa.backupWarning':
'지금 이 코드를 저장하세요. 각 코드는 한 번만 사용할 수 있습니다.',
'settings.mfa.backupCopy': '코드 복사',
'settings.mfa.backupDownload': 'TXT 다운로드',
'settings.mfa.backupPrint': '인쇄 / PDF',
'settings.mfa.backupCopied': '백업 코드가 복사되었습니다',
'settings.mfa.enabled': '계정에 2FA가 활성화되어 있습니다.',
'settings.mfa.disabled': '2FA가 활성화되지 않았습니다.',
'settings.mfa.setup': '인증 앱 설정',
'settings.mfa.scanQr':
'앱으로 이 QR 코드를 스캔하거나 시크릿을 수동으로 입력하세요.',
'settings.mfa.secretLabel': '시크릿 키 (수동 입력)',
'settings.mfa.codePlaceholder': '6자리 코드',
'settings.mfa.enable': '2FA 활성화',
'settings.mfa.cancelSetup': '취소',
'settings.mfa.disableTitle': '2FA 비활성화',
'settings.mfa.disableHint':
'계정 비밀번호와 인증 앱의 현재 코드를 입력하세요.',
'settings.mfa.disable': '2FA 비활성화',
'settings.mfa.toastEnabled': '2단계 인증이 활성화되었습니다',
'settings.mfa.toastDisabled': '2단계 인증이 비활성화되었습니다',
'settings.mfa.demoBlocked': '데모 모드에서는 사용할 수 없습니다',
'settings.oauth.modal.machineClient': '머신 클라이언트(브라우저 로그인 없음)',
'settings.oauth.modal.machineClientHint':
'client_credentials 권한 부여를 사용합니다 — 리디렉션 URI가 필요하지 않습니다. 토큰은 client_id + client_secret을 통해 직접 발급되며 선택한 범위 내에서 사용자로 작동합니다.',
'settings.oauth.modal.machineClientUsage':
'토큰 받기: grant_type=client_credentials, client_id, client_secret으로 POST /oauth/token을 호출하세요. 브라우저도 새로 고침 토큰도 필요 없습니다.',
'settings.oauth.badge.machine': '머신',
};
export default settings;
+16
View File
@@ -0,0 +1,16 @@
import type { TranslationStrings } from '../types';
const share: TranslationStrings = {
'share.linkTitle': '공개 링크',
'share.linkHint':
'로그인 없이 이 여행을 볼 수 있는 링크를 만드세요. 읽기 전용 — 편집 불가.',
'share.createLink': '링크 만들기',
'share.deleteLink': '링크 삭제',
'share.createError': '링크 생성 실패',
'share.permMap': '지도 및 계획',
'share.permBookings': '예약',
'share.permPacking': '짐 목록',
'share.permBudget': '예산',
'share.permCollab': '채팅',
};
export default share;
+21
View File
@@ -0,0 +1,21 @@
import type { TranslationStrings } from '../types';
const shared: TranslationStrings = {
'shared.expired': '링크가 만료되었거나 유효하지 않습니다',
'shared.expiredHint': '이 공유 여행 링크는 더 이상 유효하지 않습니다.',
'shared.readOnly': '읽기 전용 공유 보기',
'shared.tabPlan': '계획',
'shared.tabBookings': '예약',
'shared.tabPacking': '짐 목록',
'shared.tabBudget': '예산',
'shared.tabChat': '채팅',
'shared.days': '일',
'shared.places': '장소',
'shared.other': '기타',
'shared.totalBudget': '총 예산',
'shared.messages': '메시지',
'shared.sharedVia': '공유 경로',
'shared.confirmed': '확정됨',
'shared.pending': '대기 중',
};
export default shared;
+13
View File
@@ -0,0 +1,13 @@
import type { TranslationStrings } from '../types';
const stats: TranslationStrings = {
'stats.countries': '국가',
'stats.cities': '도시',
'stats.trips': '여행',
'stats.places': '장소',
'stats.worldProgress': '세계 진행도',
'stats.visited': '방문함',
'stats.remaining': '남음',
'stats.visitedCountries': '방문한 나라',
};
export default stats;
+56
View File
@@ -0,0 +1,56 @@
import type { TranslationStrings } from '../types';
const system_notice: TranslationStrings = {
'system_notice.v3_photos.title': '3.0에서 사진이 이동했습니다',
'system_notice.v3_photos.body':
'여행 플래너의 **사진** 기능이 제거되었습니다. 사진은 안전합니다 — TREK은 Immich 또는 Synology 라이브러리를 수정하지 않았습니다.\n\n사진은 이제 **Journey** 애드온에 있습니다. Journey는 선택 사항입니다 — 아직 사용할 수 없다면 관리자에게 관리자 → 애드온에서 활성화를 요청하세요.',
'system_notice.v3_journey.title': 'Journey를 만나보세요 — 여행 일지',
'system_notice.v3_journey.body':
'타임라인, 사진 갤러리, 인터랙티브 지도가 있는 풍부한 여행 이야기로 여행을 기록하세요.',
'system_notice.v3_journey.cta_label': 'Journey 열기',
'system_notice.v3_journey.highlight_timeline': '일별 타임라인 및 갤러리',
'system_notice.v3_journey.highlight_photos':
'Immich 또는 Synology에서 가져오기',
'system_notice.v3_journey.highlight_share': '공개 공유 — 로그인 불필요',
'system_notice.v3_journey.highlight_export': 'PDF 사진 책으로 내보내기',
'system_notice.v3_features.title': '3.0의 더 많은 하이라이트',
'system_notice.v3_features.body': '이번 릴리스에서 알아두면 좋은 몇 가지 더.',
'system_notice.v3_features.highlight_dashboard':
'모바일 우선 대시보드 재설계',
'system_notice.v3_features.highlight_offline': 'PWA로 완전한 오프라인 모드',
'system_notice.v3_features.highlight_search': '실시간 장소 검색 자동완성',
'system_notice.v3_features.highlight_import':
'KMZ/KML 파일에서 장소 가져오기',
'system_notice.v3_mcp.title': 'MCP: OAuth 2.1 업그레이드',
'system_notice.v3_mcp.body':
'MCP 통합이 완전히 개선되었습니다. OAuth 2.1이 이제 권장 인증 방법입니다. 기존 정적 토큰 (trek_…)은 더 이상 사용되지 않으며 향후 릴리스에서 제거될 예정입니다.',
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 권장 (mcp-remote)',
'system_notice.v3_mcp.highlight_scopes': '24개 세분화된 권한 범위',
'system_notice.v3_mcp.highlight_deprecated':
'정적 trek_ 토큰 더 이상 사용 안 됨',
'system_notice.v3_mcp.highlight_tools': '확장된 도구 모음 및 프롬프트',
'system_notice.v3_thankyou.title': '개인적인 감사 인사',
'system_notice.v3_thankyou.body':
'떠나시기 전에 잠깐 시간을 내주세요.\n\nTREK은 제 자신의 여행을 위해 만든 사이드 프로젝트로 시작했습니다. 4,000명이 넘는 분들이 모험을 계획하는 데 신뢰해 주실 줄은 상상도 못 했습니다. 모든 별, 모든 이슈, 모든 기능 요청 — 저는 다 읽고, 그것들이 풀타임 직장과 대학 사이의 늦은 밤을 버티게 해줍니다.\n\n알아주셨으면 합니다: TREK은 항상 오픈 소스이고, 항상 자체 호스팅이며, 항상 여러분의 것입니다. 추적 없음, 구독 없음, 조건 없음. 그저 여러분만큼 여행을 사랑하는 누군가가 만든 도구입니다.\n\n[jubnl](https://github.com/jubnl)에게 특별한 감사를. 당신은 훌륭한 협력자가 되었습니다. 3.0을 훌륭하게 만든 많은 부분에 당신의 손길이 담겨 있습니다. 거칠던 초기에 이 프로젝트를 믿어줘서 고맙습니다.\n\n그리고 버그를 제출하고, 문자열을 번역하고, TREK을 친구에게 공유하거나, 단순히 여행 계획에 사용해 주신 모든 분들께 — **감사합니다**. 여러분이 바로 이것이 존재하는 이유입니다.\n\n함께하는 더 많은 모험을 위해.\n\n— Maurice\n\n---\n\n[Discord 커뮤니티에 참여하세요](https://discord.gg/7Q6M6jDwzf)\n\nTREK이 여행을 더 즐겁게 만들어 준다면, [커피 한 잔](https://ko-fi.com/mauriceboe)으로 불을 켜두는 데 도움이 됩니다.',
'system_notice.v3014_whitespace_collision.title':
'조치 필요: 사용자 계정 충돌',
'system_notice.v3014_whitespace_collision.body':
'3.0.14 업그레이드 중 저장된 계정의 앞뒤 공백으로 인한 사용자 이름 또는 이메일 충돌이 감지되었습니다. 영향받은 계정은 자동으로 이름이 변경되었습니다. 검토가 필요한 계정을 확인하려면 **[migration] WHITESPACE COLLISION**으로 시작하는 줄의 서버 로그를 확인하세요.',
'system_notice.welcome_v1.title': 'TREK에 오신 것을 환영합니다',
'system_notice.welcome_v1.body':
'올인원 여행 플래너. 일정을 만들고, 친구들과 여행을 공유하고, 온라인 또는 오프라인으로 체계적으로 유지하세요.',
'system_notice.welcome_v1.cta_label': '여행 계획',
'system_notice.welcome_v1.hero_alt':
'TREK 계획 UI 오버레이가 있는 아름다운 여행지',
'system_notice.welcome_v1.highlight_plan': '모든 여행을 위한 일별 일정',
'system_notice.welcome_v1.highlight_share': '여행 파트너와 협업',
'system_notice.welcome_v1.highlight_offline': '모바일에서 오프라인으로 작동',
'system_notice.dev_test_modal.title': '[Dev] 테스트 공지',
'system_notice.dev_test_modal.body': '개발 전용 테스트 공지입니다.',
'system_notice.pager.prev': '이전 공지',
'system_notice.pager.next': '다음 공지',
'system_notice.pager.counter': '{current} / {total}',
'system_notice.pager.goto': '{n}번 공지로 이동',
'system_notice.pager.position': '공지 {current}/{total}',
};
export default system_notice;
+40
View File
@@ -0,0 +1,40 @@
import type { TranslationStrings } from '../types';
const todo: TranslationStrings = {
'todo.subtab.packing': '짐 목록',
'todo.subtab.todo': '할 일',
'todo.completed': '완료됨',
'todo.filter.all': '전체',
'todo.filter.open': '미완료',
'todo.filter.done': '완료',
'todo.uncategorized': '미분류',
'todo.namePlaceholder': '작업 이름',
'todo.descriptionPlaceholder': '설명 (선택)',
'todo.unassigned': '미배정',
'todo.noCategory': '카테고리 없음',
'todo.hasDescription': '설명 있음',
'todo.addItem': '새 작업 추가',
'todo.sidebar.sortBy': '정렬 기준',
'todo.priority': '우선순위',
'todo.newCategoryLabel': '새로 만들기',
'todo.newCategory': '카테고리 이름',
'todo.addCategory': '카테고리 추가',
'todo.newItem': '새 작업',
'todo.empty': '아직 작업이 없습니다. 작업을 추가하여 시작하세요!',
'todo.filter.my': '내 작업',
'todo.filter.overdue': '기한 초과',
'todo.sidebar.tasks': '작업',
'todo.sidebar.categories': '카테고리',
'todo.detail.title': '작업',
'todo.detail.description': '설명',
'todo.detail.category': '카테고리',
'todo.detail.dueDate': '마감일',
'todo.detail.assignedTo': '배정 대상',
'todo.detail.delete': '삭제',
'todo.detail.save': '변경 사항 저장',
'todo.sortByPrio': '우선순위',
'todo.detail.priority': '우선순위',
'todo.detail.noPriority': '없음',
'todo.detail.create': '작업 만들기',
};
export default todo;
+10
View File
@@ -0,0 +1,10 @@
import type { TranslationStrings } from '../types';
const transport: TranslationStrings = {
'transport.addTransport': '교통 추가',
'transport.modalTitle.create': '교통 추가',
'transport.modalTitle.edit': '교통 편집',
'transport.title': '교통',
'transport.addManual': '직접 교통 입력',
};
export default transport;
+31
View File
@@ -0,0 +1,31 @@
import type { TranslationStrings } from '../types';
const trip: TranslationStrings = {
'trip.tabs.plan': '계획',
'trip.tabs.transports': '교통',
'trip.tabs.reservations': '예약',
'trip.tabs.reservationsShort': '예약',
'trip.tabs.packing': '짐 목록',
'trip.tabs.packingShort': '짐',
'trip.tabs.lists': '목록',
'trip.tabs.listsShort': '목록',
'trip.tabs.budget': '예산',
'trip.tabs.files': '파일',
'trip.loading': '여행 불러오는 중...',
'trip.loadingPhotos': '장소 사진 불러오는 중...',
'trip.mobilePlan': '계획',
'trip.mobilePlaces': '장소',
'trip.toast.placeUpdated': '장소가 업데이트되었습니다',
'trip.toast.placeAdded': '장소가 추가되었습니다',
'trip.toast.placeDeleted': '장소가 삭제되었습니다',
'trip.toast.selectDay': '먼저 날을 선택하세요',
'trip.toast.assignedToDay': '장소가 날에 배정되었습니다',
'trip.toast.reorderError': '순서 변경 실패',
'trip.toast.reservationUpdated': '예약이 업데이트되었습니다',
'trip.toast.reservationAdded': '예약이 추가되었습니다',
'trip.toast.deleted': '삭제됨',
'trip.confirm.deletePlace': '이 장소를 삭제할까요?',
'trip.confirm.deletePlaces': '{count}개 장소를 삭제할까요?',
'trip.toast.placesDeleted': '{count}개 장소가 삭제되었습니다',
};
export default trip;
+17
View File
@@ -0,0 +1,17 @@
import type { TranslationStrings } from '../types';
const trips: TranslationStrings = {
'trips.memberRemoved': '{username} 제거됨',
'trips.memberRemoveError': '제거 실패',
'trips.memberAdded': '{username} 추가됨',
'trips.memberAddError': '추가 실패',
'trips.reminder': '리마인더',
'trips.reminderNone': '없음',
'trips.reminderDay': '일',
'trips.reminderDays': '일',
'trips.reminderCustom': '직접 설정',
'trips.reminderDaysBefore': '일 전 출발',
'trips.reminderDisabledHint':
'여행 리마인더가 비활성화되어 있습니다. 관리자 > 설정 > 알림에서 활성화하세요.',
};
export default trips;
+21
View File
@@ -0,0 +1,21 @@
import type { TranslationStrings } from '../types';
const undo: TranslationStrings = {
'undo.button': '실행 취소',
'undo.tooltip': '실행 취소: {action}',
'undo.assignPlace': '장소가 날에 배정되었습니다',
'undo.removeAssignment': '장소가 날에서 제거되었습니다',
'undo.reorder': '장소 순서가 변경되었습니다',
'undo.optimize': '경로가 최적화되었습니다',
'undo.deletePlace': '장소가 삭제되었습니다',
'undo.deletePlaces': '장소들이 삭제되었습니다',
'undo.moveDay': '장소가 다른 날로 이동되었습니다',
'undo.lock': '장소 잠금이 변경되었습니다',
'undo.importGpx': 'GPX 가져오기',
'undo.importKeyholeMarkup': 'KMZ/KML 가져오기',
'undo.importGoogleList': 'Google Maps 가져오기',
'undo.importNaverList': '네이버 지도 가져오기',
'undo.addPlace': '장소가 추가되었습니다',
'undo.done': '실행 취소됨: {action}',
};
export default undo;
+99
View File
@@ -0,0 +1,99 @@
import type { TranslationStrings } from '../types';
const vacay: TranslationStrings = {
'vacay.subtitle': '휴가 일수를 계획하고 관리하세요',
'vacay.settings': '설정',
'vacay.year': '연도',
'vacay.addYear': '다음 연도 추가',
'vacay.addPrevYear': '이전 연도 추가',
'vacay.removeYear': '연도 제거',
'vacay.removeYearConfirm': '{year}을(를) 제거할까요?',
'vacay.removeYearHint':
'이 연도의 모든 휴가 항목 및 회사 공휴일이 영구 삭제됩니다.',
'vacay.remove': '제거',
'vacay.persons': '인원',
'vacay.noPersons': '추가된 인원이 없습니다',
'vacay.addPerson': '인원 추가',
'vacay.editPerson': '인원 편집',
'vacay.removePerson': '인원 제거',
'vacay.removePersonConfirm': '{name}을(를) 제거할까요?',
'vacay.removePersonHint': '이 인원의 모든 휴가 항목이 영구 삭제됩니다.',
'vacay.personName': '이름',
'vacay.personNamePlaceholder': '이름 입력',
'vacay.color': '색상',
'vacay.add': '추가',
'vacay.legend': '범례',
'vacay.publicHoliday': '공휴일',
'vacay.companyHoliday': '회사 휴일',
'vacay.weekend': '주말',
'vacay.modeVacation': '휴가',
'vacay.modeCompany': '회사 휴일',
'vacay.entitlement': '휴가 일수',
'vacay.entitlementDays': '일',
'vacay.used': '사용',
'vacay.remaining': '남음',
'vacay.carriedOver': '{year}에서 이월',
'vacay.blockWeekends': '주말 차단',
'vacay.blockWeekendsHint': '주말에 휴가 항목 추가를 방지합니다',
'vacay.weekendDays': '주말 요일',
'vacay.mon': '월',
'vacay.tue': '화',
'vacay.wed': '수',
'vacay.thu': '목',
'vacay.fri': '금',
'vacay.sat': '토',
'vacay.sun': '일',
'vacay.publicHolidays': '공휴일',
'vacay.publicHolidaysHint': '캘린더에 공휴일을 표시합니다',
'vacay.selectCountry': '국가 선택',
'vacay.selectRegion': '지역 선택 (선택)',
'vacay.addCalendar': '캘린더 추가',
'vacay.calendarLabel': '레이블 (선택)',
'vacay.calendarColor': '색상',
'vacay.noCalendars': '아직 공휴일 캘린더가 없습니다',
'vacay.companyHolidays': '회사 휴일',
'vacay.companyHolidaysHint': '회사 전체 휴일 표시를 허용합니다',
'vacay.companyHolidaysNoDeduct':
'회사 휴일은 휴가 일수에서 차감되지 않습니다.',
'vacay.weekStart': '주 시작 요일',
'vacay.weekStartHint': '캘린더 주가 월요일 또는 일요일에 시작할지 선택하세요',
'vacay.carryOver': '이월',
'vacay.carryOverHint': '남은 휴가 일수를 다음 연도로 자동 이월합니다',
'vacay.sharing': '공유',
'vacay.sharingHint': '다른 TREK 사용자와 휴가 계획을 공유합니다',
'vacay.owner': '소유자',
'vacay.shareEmailPlaceholder': 'TREK 사용자 이메일',
'vacay.shareSuccess': '계획이 성공적으로 공유되었습니다',
'vacay.shareError': '계획 공유 실패',
'vacay.dissolve': '퓨전 해제',
'vacay.dissolveHint': '캘린더를 다시 분리합니다. 항목은 유지됩니다.',
'vacay.dissolveAction': '해제',
'vacay.dissolved': '캘린더가 분리되었습니다',
'vacay.fusedWith': '퓨전됨',
'vacay.you': '나',
'vacay.noData': '데이터 없음',
'vacay.changeColor': '색상 변경',
'vacay.inviteUser': '사용자 초대',
'vacay.inviteHint':
'다른 TREK 사용자를 초대하여 통합 휴가 캘린더를 공유하세요.',
'vacay.selectUser': '사용자 선택',
'vacay.sendInvite': '초대 전송',
'vacay.inviteSent': '초대가 전송되었습니다',
'vacay.inviteError': '초대 전송 실패',
'vacay.pending': '대기 중',
'vacay.noUsersAvailable': '사용 가능한 사용자가 없습니다',
'vacay.accept': '수락',
'vacay.decline': '거절',
'vacay.acceptFusion': '수락 및 퓨전',
'vacay.inviteTitle': '퓨전 요청',
'vacay.inviteWantsToFuse': '귀하와 휴가 캘린더를 공유하고 싶어 합니다.',
'vacay.fuseInfo1':
'두 사람 모두 하나의 공유 캘린더에서 모든 휴가 항목을 볼 수 있습니다.',
'vacay.fuseInfo2': '양측 모두 서로의 항목을 만들고 편집할 수 있습니다.',
'vacay.fuseInfo3':
'양측 모두 항목을 삭제하고 휴가 일수를 변경할 수 있습니다.',
'vacay.fuseInfo4': '공휴일 및 회사 휴일 등의 설정이 공유됩니다.',
'vacay.fuseInfo5':
'어느 쪽이든 언제든지 퓨전을 해제할 수 있습니다. 항목은 보존됩니다.',
};
export default vacay;