@object-ui/i18n 16.1.0 → 17.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,15 @@
1
1
  const ko = {
2
2
  // objectui#2600 B5 — capability picker scope group headers (labels come from the sys_capability registry).
3
3
  capability: {
4
+ label: {
5
+ manage_users: "사용자 관리",
6
+ manage_org_users: "조직 사용자 관리",
7
+ manage_metadata: "메타데이터 관리",
8
+ manage_platform_settings: "플랫폼 설정 관리",
9
+ setup_access: "설정 접근",
10
+ setup_write: "설정 쓰기",
11
+ studio_access: "Studio 접근",
12
+ },
4
13
  group: {
5
14
  platform: '플랫폼',
6
15
  org: '조직',
@@ -74,6 +83,10 @@ const ko = {
74
83
  package: "패키지",
75
84
  },
76
85
  actions: {
86
+ decisionOutput: {
87
+ help: '결정 출력으로 플로우에 전달됩니다.',
88
+ helpMultiValue: '결정 출력으로 플로우에 전달됩니다. 여러 값은 쉼표로 구분하세요.',
89
+ },
77
90
  resultDialog: {
78
91
  defaultTitle: '이 값을 지금 저장하세요',
79
92
  acknowledge: '저장했습니다',
@@ -94,6 +107,16 @@ const ko = {
94
107
  type: "{{field}}은(는) 유효한 {{type}}이어야 합니다",
95
108
  },
96
109
  form: {
110
+ noPermissionToSave: "이 레코드를 저장할 권한이 없습니다.",
111
+ submitFailed: "저장하지 못했습니다. 다시 시도해 주세요.",
112
+ discardTitle: "변경 내용을 버릴까요?",
113
+ discardMessage: "저장하지 않은 변경 내용이 있습니다. 지금 이 양식을 닫으면 편집 내용이 사라집니다.",
114
+ keepEditing: "계속 편집",
115
+ discard: "버리기",
116
+ conflictTitle: "저장 충돌",
117
+ conflictMessage: "편집하는 동안 다른 사용자가 이 레코드를 변경했습니다. 덮어쓰면 상대방의 변경 내용이 내 내용으로 대체됩니다.",
118
+ conflictLatestVersion: "상대방 저장 시각: {{time}}",
119
+ conflictOverwrite: "덮어쓰기",
97
120
  addItem: "항목 추가",
98
121
  removeItem: "항목 제거",
99
122
  fieldRequired: "이 필드는 필수입니다",
@@ -104,8 +127,6 @@ const ko = {
104
127
  stepOf: "{{total}}단계 중 {{current}}단계",
105
128
  createTitle: "{{object}} 생성",
106
129
  editTitle: "{{object}} 편집",
107
- createDescription: "새 {{object}}을(를) 데이터베이스에 추가합니다.",
108
- editDescription: "{{object}} 세부 정보 업데이트",
109
130
  saveRecord: "레코드 저장",
110
131
  create: "생성",
111
132
  update: "업데이트",
@@ -114,14 +135,70 @@ const ko = {
114
135
  deleteSuccess: "{{object}} 삭제됨",
115
136
  },
116
137
  fields: {
138
+ image: {
139
+ upload: "이미지 업로드",
140
+ addMore: "이미지 더 추가",
141
+ uploading: "업로드 중…",
142
+ imageAlt: "이미지 {{index}}",
143
+ crop: "이미지 {{index}} 자르기",
144
+ remove: "이미지 {{index}} 삭제",
145
+ enlarge: "{{name}} 확대",
146
+ preview: "이미지 미리보기",
147
+ previous: "이전 이미지",
148
+ next: "다음 이미지",
149
+ counter: "{{current}} / {{total}}",
150
+ },
117
151
  relativeDate: {
118
152
  overdue: "기한 초과 {{count}}일",
119
153
  },
154
+ file: {
155
+ dragDropHere: '파일을 여기로 끌어다 놓기',
156
+ dropFilesHere: '여기에 놓기',
157
+ browseHint: '또는 클릭하여 찾아보기',
158
+ browseHintCamera: '또는 클릭하여 찾아보기 • 아래 카메라 버튼 사용',
159
+ takePhoto: '사진 촬영',
160
+ takeSelfie: '셀피 촬영',
161
+ cameraCapture: '카메라 촬영',
162
+ uploading: '업로드 중…',
163
+ uploadingPct: '업로드 중…({{pct}}%)',
164
+ fileFallback: '파일',
165
+ upload: '업로드',
166
+ remove: '{{name}} 제거',
167
+ exceedsMaxSize: '"{{name}}"이(가) 최대 크기({{max}} MB)를 초과합니다',
168
+ uploadFailed: '"{{name}}" 업로드 실패: {{error}}',
169
+ },
120
170
  richText: {
121
171
  format: "형식: {{format}}",
122
172
  basicEditorHint: "서식 있는 텍스트 편집기 (기본)",
123
173
  placeholder: "내용을 입력하세요...",
124
174
  },
175
+ objectRef: {
176
+ loading: "객체를 불러오는 중…",
177
+ placeholder: "객체 선택",
178
+ search: "객체 검색…",
179
+ empty: "객체를 찾을 수 없습니다",
180
+ },
181
+ recipient: {
182
+ selectTypeFirst: "먼저 수신자 유형을 선택하세요.",
183
+ loading: "불러오는 중…",
184
+ search: "검색…",
185
+ empty: "일치하는 항목 없음",
186
+ select: "수신자 선택",
187
+ selectUser: "사용자 선택",
188
+ selectTeam: "팀 선택",
189
+ selectBusinessUnit: "사업 단위 선택",
190
+ selectPosition: "직위 선택",
191
+ selectUnitAndSubordinates: "사업 단위 선택",
192
+ },
193
+ filterCondition: {
194
+ selectObjectFirst: "먼저 객체를 선택하세요.",
195
+ noCriteria: "조건 없음 — 이 규칙은 아무것도 공유하지 않습니다",
196
+ criteriaRequired: "조건을 하나 이상 추가하세요. 조건이 없는 규칙은 모든 레코드를 공유하게 되므로 저장할 수 없습니다.",
197
+ invalidJson: "잘못된 JSON — 수정하기 전까지 이 규칙은 어떤 레코드와도 일치하지 않습니다.",
198
+ jsonOnly: "이 조건은 JSON으로만 편집할 수 있습니다",
199
+ editAsJson: "JSON으로 편집",
200
+ useVisualBuilder: "비주얼 빌더 사용",
201
+ },
125
202
  },
126
203
  table: {
127
204
  rowsPerPage: "페이지당 행 수",
@@ -156,6 +233,37 @@ const ko = {
156
233
  delete: "삭제",
157
234
  },
158
235
  grid: {
236
+ bulkSelected: "{{count}}건 선택됨",
237
+ bulkSelectedAllMatches: "{{count}}건 선택됨(일치 항목 전체)",
238
+ bulkClear: "선택 해제",
239
+ bulkAllOnPage: "이 페이지의 {{count}}건이 모두 선택되었습니다.",
240
+ bulkSelectAllMatching: "일치하는 {{count}}건 모두 선택",
241
+ bulkAllMatchingSelected: "일치하는 레코드 {{count}}건이 모두 선택되었습니다.",
242
+ bulk: {
243
+ confirmDefault: "레코드 {{count}}건에 적용됩니다.",
244
+ overLimit: "선택 건수({{count}})가 작업 한도({{limit}})를 초과합니다. 선택을 줄여 주세요.",
245
+ affectedRecords: "영향을 받는 레코드({{count}}):",
246
+ skippedIneligible: "선택한 레코드 중 {{count}}건은 이 작업의 대상이 아니므로 건너뜁니다.",
247
+ rowFallback: "{{index}}행",
248
+ andMore: "… 외 {{count}}건",
249
+ processed: "{{count}} / {{total}} 처리됨",
250
+ processedFailed: " · 실패 {{count}}건",
251
+ undonePrefix: "되돌림 — ",
252
+ succeeded: "성공 {{count}} / {{total}}",
253
+ resultFailed: " · 실패 {{count}}",
254
+ retry: "다시 시도",
255
+ downloadErrorCsv: "오류 CSV 다운로드",
256
+ cancel: "취소",
257
+ back: "뒤로",
258
+ next: "다음",
259
+ run: "실행",
260
+ running: "실행 중…",
261
+ undo: "되돌리기",
262
+ undoing: "되돌리는 중…",
263
+ done: "완료",
264
+ selectPlaceholder: "선택…",
265
+ loading: "불러오는 중…",
266
+ },
159
267
  actions: "작업",
160
268
  edit: "편집",
161
269
  delete: "삭제",
@@ -181,7 +289,88 @@ const ko = {
181
289
  densityCycleShortHint: "클릭하여 변경",
182
290
  },
183
291
  import: {
292
+ downloadTemplate: "템플릿 다운로드",
293
+ downloadTemplateHint: "올바른 열이 포함된 CSV를 받습니다(필수 필드에는 * 표시).",
294
+ templateFileName: "{{object}}-import-template",
295
+ autoMatched: "자동 매핑됨",
296
+ autoMatchedSummary: "{{count}}개 열을 자동 매핑했습니다 — 아래에서 확인하고 조정하세요.",
297
+ confidence: {
298
+ high: "신뢰도 높음",
299
+ medium: "신뢰도 보통",
300
+ low: "신뢰도 낮음",
301
+ },
302
+ asyncQueued: "대기 중 — 가져오기를 준비하고 있습니다…",
303
+ asyncProcessing: "{{total}}행 중 {{processed}}행 가져오는 중… {{progress}}%",
304
+ asyncLargeHint: "파일이 커서 백그라운드에서 가져옵니다.",
305
+ largeSampleNotice: "{{total}}행 중 처음 {{shown}}행을 미리 보고 있습니다.",
306
+ cancelImport: "가져오기 취소",
307
+ importCancelled: "가져오기를 취소했습니다",
308
+ resultsTruncated: "{{total}}행 중 처음 {{count}}행의 결과를 표시합니다.",
309
+ createdCount: "{{count}}건 생성",
310
+ updatedCount: "{{count}}건 업데이트",
311
+ downloadFailed: "실패한 행 다운로드",
312
+ options: "가져오기 옵션",
313
+ writeMode: "기존 레코드와 일치하는 행의 처리",
314
+ writeModeOpt: {
315
+ insert: "항상 새로 생성",
316
+ update: "기존 항목 업데이트(일치하지 않으면 건너뜀)",
317
+ upsert: "일치하면 업데이트, 없으면 생성",
318
+ },
319
+ matchFields: "일치 기준",
320
+ matchFieldsPlaceholder: "일치 기준 필드 선택…",
321
+ matchFieldsHint: "이 필드를 기준으로 기존 레코드와 대조합니다.",
322
+ needMatchFields: "일치 기준 필드를 하나 이상 선택하세요.",
323
+ matchOnlyField: "(일치 전용)",
324
+ optCreateOptions: "알 수 없는 선택 값 유지",
325
+ optRunAutomations: "자동화 및 트리거 실행",
326
+ optTreatHistorical: "과거 데이터로 가져오기",
327
+ optTreatHistoricalHint: "(완료된 레코드를 그대로 가져옵니다 — 상태 머신 검사를 건너뛰고 현재 시각을 찍는 대신 원래 타임스탬프와 작성자를 유지합니다)",
328
+ optSkipBlankKey: "일치 값이 비어 있는 행 건너뛰기",
329
+ optBackground: "백그라운드에서 가져오기",
330
+ optBackgroundHint: "(되돌릴 수 있는 작업으로 실행됩니다)",
331
+ validate: "데이터 검증",
332
+ validating: "검증 중…",
333
+ validateHint: "가져오기 전에 모든 행을 서버에서 검사합니다.",
334
+ validatePassed: "{{ok}}행 모두 유효합니다.",
335
+ validateFailed: "유효 {{ok}}행, 오류 {{errors}}행.",
336
+ errorRowPrefix: "{{row}}행: ",
337
+ referenceNotFound: "\"{{value}}\"과(와) 일치하는 레코드가 없습니다",
338
+ referenceAmbiguous: "\"{{value}}\"이(가) 여러 레코드와 일치합니다 — 고유한 값이나 레코드 ID를 사용하세요",
339
+ invalidBoolean: "\"{{value}}\"은(는) 유효한 true/false 값이 아닙니다",
340
+ invalidNumber: "\"{{value}}\"은(는) 유효한 숫자가 아닙니다",
341
+ invalidDate: "\"{{value}}\"은(는) 유효한 날짜가 아닙니다",
342
+ invalidOption: "\"{{value}}\"은(는) 허용된 선택지에 없습니다",
343
+ requiredValue: "필수 필드입니다",
344
+ matchAmbiguous: "기존 레코드 여러 건과 일치합니다 — 고유한 값이나 레코드 ID를 사용하세요",
345
+ history: "기록",
346
+ historyBack: "가져오기로 돌아가기",
347
+ historyDescription: "이 객체의 최근 가져오기입니다.",
348
+ historyHint: "백그라운드 가져오기 작업, 최신순.",
349
+ historyRefresh: "새로고침",
350
+ historyLoading: "불러오는 중…",
351
+ historyEmpty: "아직 가져오기가 없습니다.",
352
+ historyUnsupported: "이 데이터 소스는 가져오기 기록을 지원하지 않습니다.",
353
+ historyColStatus: "상태",
354
+ historyColRows: "행 수",
355
+ historyColResult: "결과",
356
+ historyColTime: "시각",
357
+ errorCount: "오류 {{count}}건",
358
+ undoImport: "가져오기 되돌리기",
359
+ undoing: "되돌리는 중…",
360
+ undoConfirm: "이 가져오기를 되돌릴까요? 생성된 레코드는 삭제되고 업데이트된 레코드는 이전 값으로 복원됩니다.",
361
+ reverted: "되돌림",
362
+ jobStatus: {
363
+ pending: "대기 중",
364
+ running: "실행 중",
365
+ succeeded: "성공",
366
+ failed: "실패",
367
+ cancelled: "취소됨",
368
+ },
369
+ legacyReferenceBlocked: "가져오기가 차단되었습니다: {{fields}}은(는) 이름을 레코드 ID로 변환하기 위해 서버 가져오기 경로가 필요한 관계 필드인데, 이 연결은 이를 지원하지 않습니다. 일반 텍스트로 가져오면 데이터가 손상됩니다. 백엔드/클라이언트를 업그레이드하거나, 이 열들의 매핑을 해제하고 별도로 가져오세요.",
370
+ missingRequiredHint: "계속할 수 없습니다 — 매핑되지 않은 필수 필드: {{fields}}. 파일에 해당 열을 추가하거나, 뒤로 돌아가 그 열이 포함된 파일을 업로드하세요.",
371
+ legacyFallbackNotice: "호환 폴백으로 가져왔습니다: 이 연결은 서버 가져오기 경로를 지원하지 않아 값이 서버 측 형 변환 없이 텍스트로 저장되었습니다. 완전한 가져오기 기능(형 변환 및 관계 조회)을 사용하려면 백엔드/클라이언트를 업그레이드하세요.",
184
372
  title: "{{object}} 가져오기",
373
+ notAllowed: "이 객체는 가져오기가 허용되지 않습니다.",
185
374
  stepUpload: "업로드",
186
375
  stepMapping: "매핑",
187
376
  stepPreview: "미리보기",
@@ -257,6 +446,42 @@ const ko = {
257
446
  moreEvents: "+{{count}} 더보기",
258
447
  },
259
448
  list: {
449
+ firstRunTitle: "아직 아무것도 없습니다",
450
+ firstRunMessage: "첫 레코드를 만들어 시작하세요.",
451
+ noMatches: "일치하는 레코드가 없습니다",
452
+ noMatchesMessage: "현재 필터나 검색어와 일치하는 레코드가 없습니다. 조건을 조정하거나 지워 보세요.",
453
+ loadErrorTitle: "레코드를 불러오지 못했습니다",
454
+ loadErrorMessage: "이 데이터를 불러오는 중 문제가 발생했습니다. 연결을 확인하고 다시 시도하세요.",
455
+ loadErrorForbiddenTitle: "접근 권한이 없습니다",
456
+ loadErrorForbiddenMessage: "이 레코드를 볼 권한이 없습니다. 접근이 필요하면 관리자에게 문의하세요.",
457
+ loadErrorUnauthorizedTitle: "로그인이 필요합니다",
458
+ loadErrorUnauthorizedMessage: "세션이 만료되었거나 로그아웃되었습니다. 다시 로그인한 후 확인하세요.",
459
+ loadErrorRejectedTitle: "이 뷰의 쿼리가 거부되었습니다",
460
+ loadErrorRejectedMessage: "서버가 이 뷰의 필터 또는 쿼리 옵션을 처리하지 못했습니다. 필터를 지우면 대부분 해결됩니다. 뷰가 이 상태로 저장되어 있다면 관리자가 수정해야 합니다.",
461
+ retry: "다시 시도",
462
+ managedBy: {
463
+ system: {
464
+ title: "아직 아무것도 없습니다",
465
+ message: "원본 작업(승인 요청, 공유, 초대 등)이 실행되면 항목이 자동으로 나타납니다. 원본 레코드에서 그중 하나를 실행하면 행이 생성됩니다.",
466
+ },
467
+ appendOnly: {
468
+ title: "기록된 이벤트가 없습니다",
469
+ message: "변경할 수 없는 감사 로그입니다. 행은 이벤트 발생 시 플랫폼이 기록합니다 — 기록을 내보낼 수는 있지만 여기서 항목을 만들 수는 없습니다.",
470
+ },
471
+ betterAuth: {
472
+ title: "ID 레코드가 없습니다",
473
+ message: "이 레코드들은 인증 공급자가 로그인·프로비저닝·보안 절차를 통해 생성하며, 여기서 직접 추가하는 것이 아닙니다.",
474
+ },
475
+ betterAuthUser: {
476
+ title: "아직 사용자가 없습니다",
477
+ message: "사용자 계정은 인증 공급자가 프로비저닝하며 여기서 생성하지 않습니다. 조직에 동료를 초대하면 첫 로그인 시 자동으로 표시됩니다(SSO 적시 프로비저닝). 앱 사용자는 앱을 통해 가입할 때 추가됩니다.",
478
+ },
479
+ betterAuthTeam: {
480
+ title: "아직 팀이 없습니다",
481
+ message: "팀은 조직 내 구성원을 묶습니다. \"팀 만들기\"로 생성하거나, 인증 공급자의 조직 및 SSO 프로비저닝 절차를 통해 추가됩니다.",
482
+ },
483
+ },
484
+ refresh: "새로고침",
260
485
  loading: 'Loading records...',
261
486
  recordCount: "{{count}}개 레코드",
262
487
  recordCountOne: "{{count}}개 레코드",
@@ -268,6 +493,8 @@ const ko = {
268
493
  filterRecords: "레코드 필터",
269
494
  sort: "정렬",
270
495
  sortRecords: "레코드 정렬",
496
+ sortByIdSuffix: "(ID 기준)",
497
+ sortRelationalHint: "다른 레코드를 참조하는 열은 목록에 없습니다. 저장된 ID로만 정렬할 수 있고 셀에 표시되는 이름으로는 정렬할 수 없습니다. 그 이름으로 정렬하려면 이름을 담는 수식 필드를 추가하세요.",
271
498
  group: "그룹",
272
499
  groupBy: "그룹 기준",
273
500
  export: "내보내기",
@@ -297,6 +524,11 @@ const ko = {
297
524
  recordEditingTitle: "레코드 편집",
298
525
  },
299
526
  managedByBadge: {
527
+ systemWritable: {
528
+ short: "플랫폼 스키마",
529
+ title: "플랫폼 정의, 관리자 쓰기 가능",
530
+ body: "이 객체의 스키마는 플랫폼이 정의하지만, 행은 여기서 직접 만들고 편집할 수 있습니다. 누가 쓸 수 있는지는 이 배지가 아니라 위임 관리와 레코드 수준 보안이 결정합니다.",
531
+ },
300
532
  config: {
301
533
  short: "관리 구성",
302
534
  title: "관리자 구성",
@@ -319,6 +551,7 @@ const ko = {
319
551
  },
320
552
  },
321
553
  kanban: {
554
+ uncategorized: "미분류",
322
555
  addCard: "카드 추가",
323
556
  addColumn: "열 추가",
324
557
  moveCard: "카드 이동",
@@ -340,12 +573,92 @@ const ko = {
340
573
  },
341
574
  },
342
575
  gantt: {
576
+ viewMode: {
577
+ day: "일",
578
+ week: "주",
579
+ month: "월",
580
+ quarter: "분기",
581
+ year: "년",
582
+ },
583
+ row: {
584
+ expand: "펼치기",
585
+ collapse: "접기",
586
+ open: "세부 정보 열기",
587
+ },
588
+ aria: {
589
+ taskList: "작업 목록",
590
+ },
591
+ tooltip: {
592
+ days: "일",
593
+ },
594
+ menu: {
595
+ view: "세부 정보 보기",
596
+ edit: "인라인 편집",
597
+ delete: "삭제",
598
+ addPredecessor: "선행 작업 추가…",
599
+ addSuccessor: "후행 작업 추가…",
600
+ removeDependency: "종속성 제거",
601
+ noCandidates: "사용할 수 있는 작업이 없습니다",
602
+ searchTasks: "작업 검색…",
603
+ },
604
+ delete: {
605
+ title: "이 작업을 삭제할까요?",
606
+ body: "\"{{title}}\"이(가) 영구히 삭제됩니다. 이 작업은 되돌릴 수 없습니다.",
607
+ cancel: "취소",
608
+ confirm: "삭제",
609
+ deleting: "삭제 중…",
610
+ },
611
+ drawer: {
612
+ fallbackTitle: "작업 세부 정보",
613
+ },
614
+ linkType: {
615
+ fs: "종료 → 시작",
616
+ ss: "시작 → 시작",
617
+ ff: "종료 → 종료",
618
+ sf: "시작 → 종료",
619
+ },
620
+ conflict: {
621
+ title: "일정 충돌",
622
+ body: "이 이동은 종속성 제약과 충돌합니다. 영향을 받는 작업 {{count}}건의 일정을 자동으로 조정할까요?",
623
+ confirm: "자동 일정 조정",
624
+ cancel: "그대로 두기",
625
+ },
626
+ autoScheduleDlg: {
627
+ title: "자동 일정 조정",
628
+ body: "종속성 연결을 충족하도록 작업 {count}건을 뒤로 미룰까요?",
629
+ skipped: "잠긴 작업 {count}건도 연결을 위반하지만 건너뛰었습니다.",
630
+ confirm: "적용",
631
+ cancel: "취소",
632
+ none: "모든 종속성이 충족되었습니다 — 조정할 일정이 없습니다.",
633
+ },
634
+ resource: {
635
+ header: "리소스",
636
+ peak: "최대",
637
+ over: "과부하",
638
+ empty: "배정할 작업이 없습니다.",
639
+ },
640
+ readOnly: "읽기 전용",
641
+ readOnlyHint: "이 보기에서는 편집할 수 없습니다.",
642
+ lockedHint: "편집 권한 없음",
643
+ writeFailed: "저장 실패 — 변경이 취소되었습니다",
343
644
  column: {
344
645
  taskName: "작업 이름",
345
646
  start: "시작",
346
647
  end: "종료",
347
648
  },
348
649
  toolbar: {
650
+ thisWeek: "이번 주",
651
+ thisMonth: "이번 달",
652
+ viewMode: "타임라인 단위",
653
+ enterFullscreen: "전체 화면",
654
+ exitFullscreen: "전체 화면 종료",
655
+ criticalPath: "주 공정 경로 강조",
656
+ autoSchedule: "종속성 자동 일정 조정",
657
+ exportPng: "PNG로 내보내기",
658
+ exportPdf: "PDF로 내보내기",
659
+ saveLayout: "레이아웃 저장",
660
+ undo: "실행 취소",
661
+ redo: "다시 실행",
349
662
  prevPeriod: "이전 기간",
350
663
  nextPeriod: "다음 기간",
351
664
  zoomIn: "확대",
@@ -391,6 +704,9 @@ const ko = {
391
704
  redo: 'Redo',
392
705
  },
393
706
  detail: {
707
+ editInlineHint: "더블클릭하여 편집",
708
+ systemActor: "시스템",
709
+ unknownUser: "알 수 없음",
394
710
  back: "뒤로",
395
711
  edit: "편집",
396
712
  editInline: "편집",
@@ -440,6 +756,18 @@ const ko = {
440
756
  attachmentCount: "첨부파일 {{count}}개",
441
757
  attachmentCountPlural: "첨부파일 {{count}}개",
442
758
  removeAttachment: "첨부파일 제거",
759
+ // Record Attachments panel (enable.files, objectstack#4358)
760
+ attachments: "첨부파일",
761
+ uploadAttachment: "업로드",
762
+ loadingAttachments: "첨부파일 불러오는 중…",
763
+ noAttachments: "아직 첨부파일이 없습니다. 파일을 업로드해 시작하세요.",
764
+ downloadAttachment: "다운로드",
765
+ deleteAttachment: "첨부파일 삭제",
766
+ attachmentDeleteDenied: "업로드한 사용자 또는 이 레코드를 편집할 수 있는 사용자만 이 첨부파일을 삭제할 수 있습니다.",
767
+ attachmentParentAccessDenied: "이 레코드에 파일을 첨부할 권한이 없습니다.",
768
+ attachmentDownloadDenied: "이 첨부파일을 다운로드할 권한이 없습니다.",
769
+ attachmentAuthRequired: "이 첨부파일을 다운로드하려면 로그인하세요.",
770
+ attachmentPermissionDenied: "이 작업을 수행할 권한이 없습니다.",
443
771
  unifiedDiff: "통합 보기",
444
772
  sideBySideDiff: "나란히 보기",
445
773
  noChanges: "변경 없음",
@@ -487,9 +815,15 @@ const ko = {
487
815
  saving: "저장 중…",
488
816
  lockedByApproval: "승인을 위해 잠김",
489
817
  lockedTooltip: "이 레코드에 대기 중인 승인 요청이 있습니다. 편집이 잠겨 있습니다",
818
+ writeStrippedTitle: "일부 필드가 저장되지 않았습니다",
819
+ writeStrippedReadonly: "다음 필드는 읽기 전용이므로 저장되지 않았습니다: {{fields}}",
820
+ writeStrippedByState: "다음 필드는 이 레코드의 현재 상태에서 편집할 수 없으므로 저장되지 않았습니다: {{fields}}",
821
+ approvalPendingEditable: "승인 진행 중 · 편집 가능",
822
+ approvalPendingTooltip: "이 레코드에 대기 중인 승인 요청이 있지만 이 단계에서는 편집할 수 있습니다",
490
823
  cancelApproval: "승인 취소",
491
824
  cancelApprovalInFlight: "취소 중…",
492
825
  cancelApprovalTooltip: "대기 중인 승인 요청을 취소하여 레코드 잠금 해제",
826
+ cancelApprovalTooltipUnlocked: "대기 중인 승인 요청 취소",
493
827
  cancelApprovalFailed: "승인 취소 실패",
494
828
  cancelApprovalUnavailable: "이 데이터 소스에서는 승인 취소가 지원되지 않습니다",
495
829
  linkCopied: "링크가 클립보드에 복사됨",
@@ -605,6 +939,35 @@ const ko = {
605
939
  resetZoom: "확대/축소 초기화",
606
940
  },
607
941
  dashboard: {
942
+ noRows: "행 없음",
943
+ pickMeasures: "이 데이터셋 위젯의 측정값(값)을 선택하세요.",
944
+ datasetUnsupported: "이 데이터 소스는 데이터셋 쿼리를 지원하지 않습니다.",
945
+ details: "세부 정보",
946
+ exportCsv: "CSV 내보내기",
947
+ openInList: "목록에서 열기",
948
+ filters: {
949
+ label: "대시보드 필터",
950
+ dateRange: "기간",
951
+ allTime: "전체 기간",
952
+ custom: "사용자 지정…",
953
+ all: "전체",
954
+ reset: "초기화",
955
+ range: {
956
+ today: "오늘",
957
+ yesterday: "어제",
958
+ this_week: "이번 주",
959
+ last_week: "지난주",
960
+ this_month: "이번 달",
961
+ last_month: "지난달",
962
+ this_quarter: "이번 분기",
963
+ last_quarter: "지난 분기",
964
+ this_year: "올해",
965
+ last_year: "작년",
966
+ last_7_days: "최근 7일",
967
+ last_30_days: "최근 30일",
968
+ last_90_days: "최근 90일",
969
+ },
970
+ },
608
971
  addWidget: "위젯 추가",
609
972
  removeWidget: "위젯 제거",
610
973
  editLayout: "레이아웃 편집",
@@ -732,6 +1095,7 @@ const ko = {
732
1095
  navTypeGroup: "그룹",
733
1096
  navTypeSeparator: "구분선",
734
1097
  navTypeAction: "작업",
1098
+ navTypeComponent: "컴포넌트",
735
1099
  navEditIcon: "아이콘 편집",
736
1100
  navToggleVisible: "가시성 토글",
737
1101
  navHidden: "숨김",
@@ -833,8 +1197,199 @@ const ko = {
833
1197
  },
834
1198
  },
835
1199
  console: {
1200
+ settingsHub: {
1201
+ title: "설정",
1202
+ subtitle: "워크스페이스, 연동, 기능 플래그를 구성합니다.",
1203
+ loadError: "설정을 불러오지 못했습니다",
1204
+ empty: "등록된 설정이 없습니다. 플러그인은 SettingsService를 통해 설정 매니페스트를 등록할 수 있습니다.",
1205
+ settingsCount: "설정 {{n}}개",
1206
+ beta: "베타",
1207
+ categories: {
1208
+ Workspace: "워크스페이스",
1209
+ Communication: "커뮤니케이션",
1210
+ Security: "보안",
1211
+ Infrastructure: "인프라",
1212
+ Beta: "베타",
1213
+ Other: "기타",
1214
+ },
1215
+ },
1216
+ objectData: {
1217
+ badge: "데이터",
1218
+ description: "URL로 정의된 데이터 구간 — 저장된 뷰에 연결되어 있지 않습니다.",
1219
+ filteredBy: "필터 조건",
1220
+ removeFilter: "필터 {{field}} 제거",
1221
+ saveAsView: "뷰로 저장",
1222
+ noAccessTitle: "접근이 거부되었습니다",
1223
+ noAccess: "이 데이터를 볼 권한이 없습니다.",
1224
+ },
1225
+ identityImport: {
1226
+ policyTitle: "가져온 사용자의 로그인 설정",
1227
+ policy: {
1228
+ auto: "자동(권장)",
1229
+ invite: "초대 보내기",
1230
+ temporary: "임시 비밀번호",
1231
+ none: "비밀번호 없음(ID만)",
1232
+ },
1233
+ policyHint: {
1234
+ auto: "연락 가능한 사용자에게는 초대(이메일 또는 SMS)를 보내고, 연락할 수 없는 사용자에게는 일회용 비밀번호를 발급해 결과 화면에 한 번만 표시합니다. 이메일/SMS 서비스 유무와 관계없이 동작합니다.",
1235
+ invite: "생성된 모든 사용자에게 비밀번호 설정 이메일(전화번호만 있는 행에는 초대 SMS)을 보냅니다. 이메일/SMS 서비스 구성이 필요하며, 연락할 수 없는 행은 실패합니다.",
1236
+ temporary: "이메일/SMS가 없는 환경용: 생성된 모든 사용자에게 일회용 비밀번호를 발급해 결과 화면에 한 번만 표시합니다. 첫 로그인 시 변경해야 합니다.",
1237
+ none: "사용자는 먼저 전화 OTP, 매직 링크 또는 비밀번호 재설정 링크로 로그인한 뒤 직접 비밀번호를 설정합니다.",
1238
+ },
1239
+ passwordsNote: "임시 비밀번호 — 한 번만 표시되며 저장되지 않습니다. 지금 저장하세요. 각 사용자는 첫 로그인 시 변경해야 합니다.",
1240
+ passwordsMore: "이후 항목은 생략되었습니다 — 다운로드를 이용하세요.",
1241
+ passwordsDownload: "CSV 다운로드",
1242
+ },
1243
+ ai: {
1244
+ usage: {
1245
+ title: "AI 사용량",
1246
+ meterBuild: "빌드",
1247
+ meterAsk: "질문",
1248
+ statusOk: "여유가 충분합니다",
1249
+ statusLow: "얼마 남지 않았습니다",
1250
+ statusFull: "한도에 도달했습니다",
1251
+ resetsDaily: "오늘 밤 초기화됩니다",
1252
+ resetsMonthly: "다음 주기에 초기화됩니다",
1253
+ ctaUpgrade: "업그레이드하고 계속하기",
1254
+ ctaTopUp: "크레딧을 추가하고 계속하기",
1255
+ ariaLabel: "AI 사용량: {{status}}",
1256
+ },
1257
+ workspaceTitle: "AI 워크스페이스",
1258
+ workspaceSubtitle: "질문하고, 살펴보고, 대화를 이어가세요",
1259
+ openChats: "채팅 열기",
1260
+ chats: "채팅",
1261
+ chatsDescription: "AI 대화를 살펴보고 관리합니다.",
1262
+ share: "공유",
1263
+ shareTitle: "이 대화 공유",
1264
+ shareDisabledTitle: "공유하려면 먼저 대화를 시작하세요",
1265
+ newChat: "새로 만들기",
1266
+ searchChats: "채팅 검색...",
1267
+ noChatsYet: "아직 채팅이 없습니다",
1268
+ noChatsDescription: "새 대화를 시작하면 여기에 표시됩니다.",
1269
+ noMatchingChats: "일치하는 채팅이 없습니다.",
1270
+ newConversation: "새 대화",
1271
+ renameConversation: "대화 이름 변경",
1272
+ deleteConversation: "대화 삭제",
1273
+ saveRename: "이름 저장",
1274
+ cancelRename: "이름 변경 취소",
1275
+ loadingHistory: "대화 기록을 불러오는 중...",
1276
+ conversationReady: "대화 준비 완료",
1277
+ preparingConversation: "새 대화를 준비하는 중",
1278
+ offlineDemoMode: "오프라인 데모 모드 — 에이전트 목록을 사용할 수 없습니다",
1279
+ sendFailedRateLimited: "메시지를 너무 빠르게 보내고 있습니다. 메시지는 아래에 보관되어 있습니다 — 잠시 후 다시 시도하세요.",
1280
+ sendFailedGeneric: "메시지를 보내지 못했습니다. 아래에 보관되어 있습니다 — 다시 시도해 주세요.",
1281
+ askAgent: "{{agent}}에게 질문...",
1282
+ assistant: "어시스턴트",
1283
+ liveCanvas: "실시간 미리보기 — {{app}}(초안)",
1284
+ liveCanvasUnlisted: "실시간 앱 — {{app}}(게시 전까지 비공개)",
1285
+ loadingAgents: "에이전트를 불러오는 중...",
1286
+ askAnything: "무엇이든 물어보세요...",
1287
+ emptyTitle: "대화 시작하기",
1288
+ emptyDescription: "무엇이든 물어보세요 — 어시스턴트는 현재 앱 컨텍스트에 접근할 수 있습니다.",
1289
+ switchAssistant: "어시스턴트 전환",
1290
+ chooseAgent: "어시스턴트 선택…",
1291
+ empty: {
1292
+ build: {
1293
+ title: "AI로 빌드",
1294
+ description: "앱이나 워크플로를 일상 언어로 설명해 주세요 — 객체, 화면, 자동화를 초안으로 만들어 드리면 검토 후 게시하시면 됩니다.",
1295
+ },
1296
+ ask: {
1297
+ title: "데이터에 질문하기",
1298
+ description: "레코드에 대해 질문하세요 — 접근 가능한 데이터의 개수, 목록, 요약을 알려 드립니다.",
1299
+ },
1300
+ editApp: {
1301
+ title: "“{{app}}” 편집 중",
1302
+ titleGeneric: "이 앱 편집",
1303
+ description: "무엇을 바꿀까요? 이 앱을 그 자리에서 수정합니다 — 필드, 객체, 뷰, 자동화를 추가하거나 기존 내용을 조정할 수 있습니다.",
1304
+ },
1305
+ },
1306
+ clearConversation: "지우기",
1307
+ sendHint: "눌러 전송",
1308
+ agentActivity: "에이전트 활동",
1309
+ toolCompleted: "완료됨",
1310
+ toolRunning: "실행 중",
1311
+ toolAwaitingApproval: "승인 대기 중",
1312
+ toolFailed: "실패",
1313
+ toolDetailsHidden: "이 보기에서는 도구 입력과 원본 결과가 숨겨집니다.",
1314
+ copy: "복사",
1315
+ copied: "복사됨",
1316
+ regenerate: "다시 생성",
1317
+ model: "모델",
1318
+ submit: "보내기",
1319
+ uploadFiles: "파일 업로드",
1320
+ stopResponse: "응답 중지",
1321
+ trace: "추적",
1322
+ viewTrace: "추적 보기",
1323
+ nextSteps: "다음 단계",
1324
+ publishDrafts: "게시",
1325
+ publishOk: "게시했습니다 — 객체가 이제 활성화되었습니다.",
1326
+ seedWarn: "게시했지만 일부 샘플 데이터를 불러오지 못했습니다.",
1327
+ openBuiltApp: "앱 열기",
1328
+ designBuiltApp: "Studio에서 디자인",
1329
+ previewDraft: "미리보기",
1330
+ previewApp: "앱 미리보기",
1331
+ resizeSplit: "채팅과 미리보기 크기 조정",
1332
+ hideChats: "채팅 숨기기",
1333
+ showChats: "채팅 표시",
1334
+ planTitle: "제안된 계획",
1335
+ planQuestions: "빌드 전에 확인",
1336
+ planAssumptions: "가정",
1337
+ planApproveHint: "회신하여 이 계획을 승인하거나 조정하세요.",
1338
+ planApprove: "빌드하기",
1339
+ planAdjust: "조정",
1340
+ justNow: "방금",
1341
+ minutesAgo: "{{count}}분 전",
1342
+ hoursAgo: "{{count}}시간 전",
1343
+ daysAgo: "{{count}}일 전",
1344
+ agentLabels: {
1345
+ ask: "질문",
1346
+ build: "빌드",
1347
+ dataChat: "어시스턴트",
1348
+ metadataAssistant: "메타데이터 어시스턴트",
1349
+ },
1350
+ suggestions: {
1351
+ dataChat: {
1352
+ userCount: "시스템에 사용자가 몇 명인가요? 이메일도 나열해 주세요.",
1353
+ recentRecords: "가장 최근에 생성된 레코드 5건을 보여 주세요.",
1354
+ recordCounts: "객체별 레코드 수를 세어 주세요.",
1355
+ },
1356
+ metadataAssistant: {
1357
+ buildCrm: "영업 CRM을 만들어 줘 — 고객, 담당자, 단계별로 합계를 낼 수 있는 거래 파이프라인.",
1358
+ buildApp: "프로젝트 트래커를 만들어 줘 — 프로젝트, 담당자와 마감일이 있는 작업, 상태별 보드.",
1359
+ buildFlow: "고객 지원 데스크를 설계해 줘 — 우선순위가 있는 티켓, 상태 워크플로, 고객 연결.",
1360
+ buildInventory: "재고 앱을 만들어 줘 — 제품, 재고 수량, 공급업체, 재고 부족 표시.",
1361
+ buildRecruiting: "채용 트래커를 만들어 줘 — 지원자, 채용 중인 직무, 면접 단계, 메모.",
1362
+ },
1363
+ generic: {
1364
+ help: "무엇을 도와줄 수 있나요?",
1365
+ availableObjects: "사용 가능한 데이터 객체를 나열해 주세요.",
1366
+ recentActivity: "내 최근 활동을 요약해 주세요.",
1367
+ },
1368
+ editApp: {
1369
+ addField: "객체 중 하나에 필드를 추가해 주세요.",
1370
+ addObject: "새 객체를 추가하고 기존 객체와 연결해 주세요.",
1371
+ addDashboard: "핵심 지표를 위한 대시보드를 추가해 주세요.",
1372
+ addAutomation: "자동화를 추가해 주세요 — 승인, 상태 흐름 또는 알림.",
1373
+ },
1374
+ },
1375
+ changesTitle: "변경 확인",
1376
+ changesConfirmed: "확인됨",
1377
+ changesConfirm: "변경 확정",
1378
+ changesConfirmHint: "회신하여 이 변경을 확정하거나 조정하세요.",
1379
+ changeVerb: {
1380
+ createObject: "객체 생성",
1381
+ addField: "필드 추가",
1382
+ modifyField: "필드 수정",
1383
+ deleteField: "필드 삭제",
1384
+ createMetadata: "생성",
1385
+ updateMetadata: "수정",
1386
+ createSeed: "샘플 데이터 생성",
1387
+ createPackage: "앱 패키지 생성",
1388
+ },
1389
+ },
836
1390
  title: "ObjectStack 콘솔",
837
1391
  initializing: "애플리케이션 초기화 중...",
1392
+ loadingHint: "새 환경을 설정하는 데 시간이 조금 걸릴 수 있습니다.",
838
1393
  breadcrumb: {
839
1394
  dashboards: "대시보드",
840
1395
  pages: "페이지",
@@ -876,6 +1431,7 @@ const ko = {
876
1431
  toggleDarkMode: "다크 모드 전환",
877
1432
  },
878
1433
  commandPalette: {
1434
+ title: "명령 팔레트",
879
1435
  placeholder: "명령어를 입력하거나 검색...",
880
1436
  noResults: "결과를 찾을 수 없습니다.",
881
1437
  objects: "객체",
@@ -909,6 +1465,14 @@ const ko = {
909
1465
  system: "시스템",
910
1466
  },
911
1467
  objectView: {
1468
+ viewTypeTree: "트리",
1469
+ viewTypeTreeDesc: "상위 필드를 기준으로 자기 참조 레코드를 계층 구조로 중첩합니다.",
1470
+ parentField: "상위 필드",
1471
+ parentFieldHelp: "계층 구조를 정의하는 상위 레코드(같은 객체)를 가리키는 필드입니다. 자기 참조 필드만 사용할 수 있습니다.",
1472
+ viewName: "이름",
1473
+ viewNameHelp: "머신 키(snake_case)입니다. 제목에서 자동으로 채워집니다 — 원하면 수정하세요.",
1474
+ viewNameRequired: "키를 입력하세요(소문자, 숫자, 밑줄). 비라틴 문자 제목에서는 자동으로 채워지지 않습니다.",
1475
+ viewNameInvalid: "소문자, 숫자, 밑줄을 사용하고 문자 또는 밑줄로 시작하세요.",
912
1476
  systemViewReadonly: 'System view defined in code - duplicate to customize.',
913
1477
  expandToPage: 'Open as full page',
914
1478
  objectNotFound: "객체를 찾을 수 없음",
@@ -1122,7 +1686,28 @@ const ko = {
1122
1686
  },
1123
1687
  },
1124
1688
  auth: {
1689
+ setPassword: {
1690
+ title: "복구 비밀번호 설정",
1691
+ description: "싱글 사인온으로 로그인했습니다. SSO를 사용할 수 없게 되더라도 이 환경에 직접 로그인할 수 있도록 로컬 비밀번호를 설정하세요.",
1692
+ email: "이메일",
1693
+ newPassword: "새 비밀번호",
1694
+ confirmPassword: "비밀번호 확인",
1695
+ submit: "비밀번호 설정",
1696
+ submitting: "저장 중…",
1697
+ success: "로컬 비밀번호가 설정되었습니다",
1698
+ failed: "비밀번호를 설정하지 못했습니다",
1699
+ passwordsMismatch: "비밀번호가 일치하지 않습니다",
1700
+ noSession: "세션이 만료되었습니다.",
1701
+ backToSignIn: "다시 로그인",
1702
+ },
1125
1703
  login: {
1704
+ signingIn: "로그인하는 중…",
1705
+ ssoHandoff: "{{target}}(으)로 계속",
1706
+ devAdminHint: {
1707
+ title: "개발 인스턴스",
1708
+ body: "시드된 개발용 관리자 계정으로 로그인하세요:",
1709
+ dismiss: "닫기",
1710
+ },
1126
1711
  title: "계정에 로그인",
1127
1712
  description: "이메일과 비밀번호를 입력하세요",
1128
1713
  emailLabel: "이메일",
@@ -1135,6 +1720,7 @@ const ko = {
1135
1720
  noAccountText: "계정이 없으신가요?",
1136
1721
  signUpText: "회원가입",
1137
1722
  errors: {
1723
+ oauthCallbackFailed: "싱글 사인온을 완료하지 못했습니다 — 로그인 링크가 만료되었거나 이미 사용되었습니다. 다시 시도해 주세요.",
1138
1724
  invalidCredentials: "잘못된 이메일 또는 비밀번호입니다. 다시 시도하세요.",
1139
1725
  emailNotVerified: "로그인하기 전에 이메일을 확인하세요.",
1140
1726
  },
@@ -1260,6 +1846,40 @@ const ko = {
1260
1846
  shell: {
1261
1847
  tenantHostHint: "이 작업 공간에 로그인하는 중입니다",
1262
1848
  },
1849
+ layout: {
1850
+ headline: "강력한 비즈니스 애플리케이션을 더 빠르게.",
1851
+ subhead: "엔터프라이즈 데이터 관리, 워크플로, 분석을 위한 통합 플랫폼.",
1852
+ },
1853
+ remediation: {
1854
+ signOut: "대신 로그아웃",
1855
+ password: {
1856
+ title: "비밀번호가 만료되었습니다",
1857
+ fallbackMessage: "계속하려면 새 비밀번호를 설정하세요.",
1858
+ current: "현재 비밀번호",
1859
+ next: "새 비밀번호",
1860
+ confirm: "새 비밀번호 확인",
1861
+ submit: "비밀번호 변경 후 계속",
1862
+ submitting: "업데이트 중…",
1863
+ mismatch: "새 비밀번호가 일치하지 않습니다.",
1864
+ failed: "비밀번호를 변경할 수 없습니다.",
1865
+ },
1866
+ mfa: {
1867
+ title: "2단계 인증 설정",
1868
+ fallbackMessage: "계속하려면 조직 정책에 따라 인증 앱이 필요합니다.",
1869
+ confirmPassword: "비밀번호 확인",
1870
+ continue: "계속",
1871
+ preparing: "준비 중…",
1872
+ enrollFailed: "등록을 시작할 수 없습니다.",
1873
+ scanTitle: "인증 앱으로 스캔",
1874
+ scanBody: "Google Authenticator, 1Password, Authy 등으로 이 QR 코드를 스캔한 다음 6자리 코드를 입력하세요.",
1875
+ backupTitle: "백업 코드 저장",
1876
+ backupBody: "안전한 곳에 보관하세요. 기기를 분실한 경우 각 코드는 한 번씩 사용할 수 있습니다.",
1877
+ codeLabel: "6자리 코드",
1878
+ verify: "확인 후 계속",
1879
+ verifying: "확인 중…",
1880
+ invalidCode: "코드가 올바르지 않습니다. 다시 시도하세요.",
1881
+ },
1882
+ },
1263
1883
  },
1264
1884
  profile: {
1265
1885
  title: "프로필",
@@ -1324,11 +1944,15 @@ const ko = {
1324
1944
  settings: "워크스페이스 설정",
1325
1945
  },
1326
1946
  help: {
1947
+ onThisPage: "이 페이지에서",
1948
+ keyboardShortcuts: "키보드 단축키",
1327
1949
  appDocs: '이 앱의 문서',
1328
1950
  allDocs: '전체 문서',
1329
1951
  onlineDocs: '온라인 문서',
1330
1952
  },
1331
1953
  sidebar: {
1954
+ packageManagement: "패키지 관리",
1955
+ searchNavigation: "내비게이션 검색...",
1332
1956
  settings: "설정",
1333
1957
  help: "도움말",
1334
1958
  helpTooltip: "도움말 및 문서",
@@ -1345,14 +1969,66 @@ const ko = {
1345
1969
  removeFromFavorites: "즐겨찾기에서 {{name}} 제거",
1346
1970
  },
1347
1971
  topbar: {
1972
+ openAssistant: "{{name}} 어시스턴트 열기",
1973
+ offline: "오프라인",
1974
+ usersOnline: "현재 접속 중인 사용자",
1975
+ switchView: "뷰 전환",
1976
+ switchObject: "객체 전환",
1977
+ connection: {
1978
+ connected: "연결됨",
1979
+ connecting: "연결 중...",
1980
+ reconnecting: "다시 연결 중...",
1981
+ disconnected: "연결 끊김",
1982
+ error: "연결 오류",
1983
+ },
1984
+ stage: {
1985
+ preview: "미리보기",
1986
+ beta: "베타",
1987
+ tooltip: "이 플랫폼은 미리보기 단계입니다 — 기능이 변경될 수 있습니다.",
1988
+ },
1348
1989
  aiAssistant: "AI 어시스턴트",
1349
1990
  designInStudio: "Studio에서 디자인",
1350
1991
  },
1351
1992
  home: {
1993
+ build: {
1994
+ title: "앱 만들기",
1995
+ subtitle: "처음부터 시작 — 객체, 폼, 자동화, 인터페이스를 설계합니다.",
1996
+ },
1997
+ template: {
1998
+ title: "템플릿으로 시작",
1999
+ subtitle: "마켓플레이스에서 템플릿 앱을 설치하고 원하는 대로 바꾸세요.",
2000
+ },
2001
+ welcomeAdminDescription: "비즈니스를 한 문장으로 설명해 주세요 — AI가 객체, 화면, API, 에이전트 도구를 생성합니다. 왼쪽 메뉴에서 직접 설정할 수도 있습니다.",
2002
+ welcomeAdminDescriptionNoBuild: "왼쪽 관리 메뉴에서 첫 애플리케이션을 설정하세요. 데이터가 쌓이면 AI 어시스턴트가 살펴보는 것을 도와줍니다.",
2003
+ welcomeAdminDescriptionNoAi: "왼쪽 관리 메뉴에서 첫 애플리케이션을 설정하세요.",
2004
+ noAppsTitle: "아직 애플리케이션이 없습니다",
2005
+ noAppsDescription: "워크스페이스를 준비하고 있습니다 — 관리자가 공유한 앱이 여기에 표시됩니다.",
2006
+ buildWithAI: "AI로 빌드",
2007
+ askAI: "AI에게 질문",
2008
+ recoveryReminder: {
2009
+ message: "싱글 사인온을 사용할 수 없을 때도 로그인할 수 있도록 복구 비밀번호를 설정하세요.",
2010
+ cta: "비밀번호 설정",
2011
+ dismiss: "닫기",
2012
+ },
2013
+ pendingDrafts: {
2014
+ message: "게시되지 않은 변경이 {{count}}건 있습니다 — 게시하면 반영됩니다.",
2015
+ cta: "게시",
2016
+ publishing: "게시하는 중…",
2017
+ published: "게시했습니다! 변경 사항이 반영되었습니다.",
2018
+ publishFailed: "게시에 실패했습니다",
2019
+ },
1352
2020
  title: "홈",
1353
2021
  subtitle: "워크스페이스 대시보드",
1354
2022
  nav: "홈",
1355
2023
  allApps: "모든 애플리케이션",
2024
+ yourApps: "내 앱",
2025
+ showMoreApps: "더 보기",
2026
+ showLess: "간략히",
2027
+ continueEmpty: "열어본 항목이 여기에 표시됩니다.",
2028
+ actionCenter: {
2029
+ title: "확인이 필요한 항목",
2030
+ empty: "모두 처리했습니다",
2031
+ },
1356
2032
  loading: "워크스페이스 로드 중...",
1357
2033
  recent: "최근",
1358
2034
  starred: "즐겨찾기",
@@ -1404,7 +2080,21 @@ const ko = {
1404
2080
  },
1405
2081
  },
1406
2082
  layout: {
2083
+ systemNav: {
2084
+ systemSettings: "시스템 설정",
2085
+ applications: "애플리케이션",
2086
+ appMarketplace: "앱 마켓플레이스",
2087
+ objectManager: "객체 관리자",
2088
+ users: "사용자",
2089
+ organizations: "조직",
2090
+ roles: "역할",
2091
+ configuration: "구성",
2092
+ createApp: "앱 만들기",
2093
+ },
1407
2094
  appSwitcher: {
2095
+ switchApplication: "애플리케이션 전환",
2096
+ appsAvailable: "사용 가능한 앱 {{count}}개",
2097
+ editNavigation: "내비게이션 편집",
1408
2098
  home: "홈",
1409
2099
  addApp: "앱 추가",
1410
2100
  editApp: "앱 편집",
@@ -1497,8 +2187,8 @@ const ko = {
1497
2187
  uploading: "업로드 중…",
1498
2188
  defaultActionTitle: "작업",
1499
2189
  ok: "확인",
1500
- lookupPlaceholder: "{{label}}의 레코드 ID(UUID) 붙여넣기",
1501
- lookupHelpText: "참조된 개체의 레코드 ID를 입력하세요. 선택기가 곧 추가됩니다.",
2190
+ lookupPlaceholder: "{{label}}의 레코드 ID",
2191
+ lookupHelpText: "이 매개변수에 참조 개체가 설정되어 있지 않아 레코드 선택기를 사용할 수 없습니다. 레코드 ID를 직접 입력하거나 관리자에게 작업 매개변수 수정을 요청하세요.",
1502
2192
  },
1503
2193
  actionConfirm: {
1504
2194
  title: "작업 확인",
@@ -1523,6 +2213,8 @@ const ko = {
1523
2213
  updateFailed: "탐색을 업데이트할 수 없습니다",
1524
2214
  },
1525
2215
  objectActions: {
2216
+ resetPackageSetConfirm: "이 권한 세트는 설치된 패키지에 포함되어 있어 제거할 수 없습니다. 삭제하면 패키지 기본 상태로 초기화되며 이 환경의 커스터마이징은 폐기됩니다. 계속할까요?",
2217
+ resetPackageSetSuccess: "권한 세트를 패키지 기본 상태로 초기화했습니다",
1526
2218
  deleteSuccess: "{{label}} 삭제 성공",
1527
2219
  deleteFailed: "{{label}} 삭제 실패",
1528
2220
  noRecordId: "레코드 ID가 없습니다",
@@ -1687,6 +2379,7 @@ const ko = {
1687
2379
  },
1688
2380
  },
1689
2381
  organizations: {
2382
+ create: "워크스페이스 만들기",
1690
2383
  mine: "내 조직",
1691
2384
  title: "조직",
1692
2385
  heading: "내 조직",
@@ -1700,6 +2393,11 @@ const ko = {
1700
2393
  noMatches: "검색과 일치하는 조직이 없습니다.",
1701
2394
  },
1702
2395
  notifications: {
2396
+ regionLabel: "알림",
2397
+ groupCount: "알림 {{count}}건",
2398
+ groupUnread: "읽지 않음 {{count}}건",
2399
+ groupMarkRead: "읽음 표시",
2400
+ groupMarkReadTitle: "이 유형 전체를 읽음으로 표시",
1703
2401
  empty: "알림 없음",
1704
2402
  markAllRead: "모두 읽음으로 표시",
1705
2403
  viewAll: "모든 알림 보기",
@@ -1818,7 +2516,103 @@ const ko = {
1818
2516
  done: '완료 — 숨기기',
1819
2517
  },
1820
2518
  },
2519
+ excelImport: {
2520
+ noImportableFields: "해당 오브젝트에는 가져올 수 있는 필드가 없습니다.",
2521
+ schemaReadFailed: "오브젝트 스키마를 읽을 수 없습니다.",
2522
+ imported: "{{count}}개 행을 {{object}}(으)로 가져왔습니다.",
2523
+ importFrom: "실제 데이터 가져오기 원본",
2524
+ into: "→",
2525
+ opening: "여는 중…",
2526
+ importAction: "가져오기",
2527
+ dismiss: "닫기",
2528
+ },
2529
+ cloudOnboarding: {
2530
+ hintCreate: "첫 환경을 만들어 보세요. 고유한 URL과 데이터베이스, 요금제를 갖춘 전용 작업 공간이며 앱 구축은 그 안에서 이루어집니다.",
2531
+ hintReady: "프로덕션 환경이 준비되었습니다. 열어서 앱을 만들고 실행하세요. 모두 환경 안에서 이루어집니다.",
2532
+ createEnvironment: "환경 만들기",
2533
+ openProduction: "프로덕션 열기",
2534
+ manageEnvironments: "환경 관리",
2535
+ },
2536
+ aiModelStatus: {
2537
+ summary: "빌드 / 질문은 {{conversational}}({{conversationalSource}}), 구조화 출력은 {{structured}}({{structuredSource}})을(를) 사용합니다.",
2538
+ summaryRouting: "라우팅 정책: 무료 요금제 → {{free}}, 유료 요금제 → {{paid}}.",
2539
+ modelUnknown: "알 수 없음",
2540
+ sourceUnknown: "어댑터가 보고하지 않음",
2541
+ rowConversational: "Build / Ask 모델",
2542
+ rowStructured: "구조화(블루프린트 / 시드)",
2543
+ rowReasoning: "추론 강도",
2544
+ readFailed: "유효한 AI 모델을 읽을 수 없습니다. 이 환경에서 AI 서비스가 실행되지 않거나 ai:read 권한이 없을 수 있습니다.",
2545
+ readFailedWithStatus: "유효한 AI 모델을 읽을 수 없습니다(HTTP {{status}}). 이 환경에서 AI 서비스가 실행되지 않거나 ai:read 권한이 없을 수 있습니다.",
2546
+ overridesInEffect: "적용 중인 재정의: ",
2547
+ noOverrides: "없음 — 배포된 코드의 기본값으로 실행 중입니다.",
2548
+ adapter: "어댑터: ",
2549
+ sourceCodeDefault: "코드 기본값(env 재정의 없음)",
2550
+ sourceInherits: "build/ask와 동일",
2551
+ sourcePinned: "{{source}}에 의해 고정됨",
2552
+ },
2553
+ chatbotError: {
2554
+ title: "응답 실패",
2555
+ fallbackDetail: "문제가 발생했습니다. 다시 시도해 주세요.",
2556
+ details: "세부 정보",
2557
+ hide: "숨기기",
2558
+ retry: "다시 시도",
2559
+ },
2560
+ chatbotQuota: {
2561
+ title: "업그레이드 필요",
2562
+ fallbackMessage: "AI 사용 한도에 도달했습니다.",
2563
+ buyCredits: "크레딧 팩 구매",
2564
+ upgradePlan: "요금제 업그레이드",
2565
+ },
2566
+ environment: {
2567
+ addEnvironment: "환경 추가",
2568
+ setUpProduction: "프로덕션 환경 설정",
2569
+ addDevelopment: "개발 환경 추가",
2570
+ },
2571
+ cloudConnection: {
2572
+ checking: "연결을 확인하는 중…",
2573
+ retry: "다시 시도",
2574
+ errors: {
2575
+ expired: "승인되기 전에 요청이 만료되었습니다. 다시 시작하세요.",
2576
+ bindFailed: "바인딩에 실패했습니다.",
2577
+ deviceCodeFailed: "장치 코드 요청에 실패했습니다.",
2578
+ },
2579
+ waiting: {
2580
+ popupOpened: "방금 열린 창에서 연결을 승인하세요. 이 페이지는 자동으로 업데이트됩니다.",
2581
+ polling: "클라우드 콘솔에서의 승인을 기다리는 중…",
2582
+ openApproval: "승인 페이지 열기",
2583
+ copy: "복사",
2584
+ copied: "복사됨",
2585
+ codePrefilled: "승인 페이지에 코드가 미리 입력되어 있습니다.",
2586
+ openItHere: "창이 나타나지 않았나요? 여기에서 열기",
2587
+ cancel: "취소",
2588
+ },
2589
+ bound: {
2590
+ title: "ObjectStack Cloud에 연결됨",
2591
+ runtime: "런타임",
2592
+ organization: "조직",
2593
+ approvedBy: "승인자",
2594
+ runtimeId: "런타임 ID",
2595
+ environment: "환경",
2596
+ since: "연결 시각",
2597
+ privatePackages: "조직의 비공개 패키지가 이제 마켓플레이스의 '내 조직'에 표시됩니다.",
2598
+ disconnect: "연결 해제",
2599
+ },
2600
+ unbound: {
2601
+ title: "연결되지 않음",
2602
+ body: "이 런타임을 ObjectStack 컨트롤 플레인에 연결하면 조직의 비공개 패키지를 탐색하고 여기에 설치할 수 있습니다. 승인은 클라우드 계정에서 한 번만 클릭하면 되며, 이 페이지에 ID나 자격 증명을 입력할 필요가 없습니다.",
2603
+ connect: "연결",
2604
+ },
2605
+ },
1821
2606
  marketplace: {
2607
+ suggestedBindings: {
2608
+ promptEveryone: "이 앱은 로그인한 모든 사용자(Everyone 위치)에게 \"{{set}}\"을(를) 부여할 것을 제안합니다.",
2609
+ promptGuest: "이 앱은 인증되지 않은 방문자(Guest 위치)에게 \"{{set}}\"을(를) 부여할 것을 제안합니다.",
2610
+ confirm: "부여",
2611
+ confirming: "부여하는 중…",
2612
+ dismiss: "닫기",
2613
+ confirmedToast: "\"{{set}}\"이(가) 이제 {{anchor}}에 부여되었습니다.",
2614
+ dismissedToast: "\"{{set}}\" 제안을 닫았습니다.",
2615
+ },
1822
2616
  title: "앱 마켓플레이스",
1823
2617
  subtitle: "ObjectStack 카탈로그에 게시된 승인된 앱을 탐색하세요. 앱을 클릭하여 세부 정보를 보고 환경 중 하나에 설치하세요.",
1824
2618
  searchPlaceholder: "이름 또는 매니페스트 ID로 앱 검색…",
@@ -1870,6 +2664,7 @@ const ko = {
1870
2664
  updateAvailable: '업데이트 가능',
1871
2665
  },
1872
2666
  action: {
2667
+ installed: "설치됨",
1873
2668
  install: "설치",
1874
2669
  reinstall: "재설치",
1875
2670
  working: "처리 중…",
@@ -1940,6 +2735,14 @@ const ko = {
1940
2735
  yearsAgo: "{{count}}년 전",
1941
2736
  },
1942
2737
  },
2738
+ approvals: {
2739
+ approve: '승인',
2740
+ reject: '반려',
2741
+ comment: '의견(선택 사항)',
2742
+ approveSuccess: '승인됨',
2743
+ rejectSuccess: '반려됨',
2744
+ rejectConfirm: '이 승인 요청을 반려하시겠습니까?',
2745
+ },
1943
2746
  approvalsInbox: {
1944
2747
  loadMore: '더 보기',
1945
2748
  loadingMore: '불러오는 중…',
@@ -1964,13 +2767,28 @@ const ko = {
1964
2767
  slaRemaining: 'SLA {{dur}} 남음',
1965
2768
  slaOverdue: 'SLA {{dur}} 초과',
1966
2769
  actReassign: '재할당',
2770
+ reassignFromTo: '{{from}} 님에서 {{to}} 님으로',
1967
2771
  actRemind: '독촉',
1968
2772
  actRequestInfo: '보완 요청',
1969
2773
  actComment: '댓글',
1970
2774
  stepProgress: '승인 단계',
1971
2775
  prevRequest: '이전',
1972
2776
  nextRequest: '다음',
1973
- positionOf: '{{total}}개 중 {{index}}번째',
2777
+ positionOf: '요청 {{total}}개 중 {{index}}번째',
2778
+ progressApprovals: '승인 — {{got}} / {{need}}',
2779
+ progressGroups: '그룹 승인 — {{got}} / {{need}} 그룹',
2780
+ progressEligible: '승인 가능자 {{count}}명',
2781
+ progressBar: '결정 진행 상황',
2782
+ declaredActions: '작업',
2783
+ attachmentChip: '첨부 파일',
2784
+ attachmentOpenFailed: '첨부 파일을 열 수 없습니다. 다시 시도해 주세요',
2785
+ approveOneTitle: '"{{title}}"을(를) 승인할까요?',
2786
+ approveOneBody: '내 이름으로 이 요청을 승인합니다. 의견이나 첨부 파일을 추가하려면 요청을 열어 처리하세요.',
2787
+ flowOrigin: '플로우 시작',
2788
+ sortBy: '정렬',
2789
+ sortRecent: '최신순',
2790
+ sortOldest: '오래된순',
2791
+ sortAmount: '금액(높은순)',
1974
2792
  quickPhrase1: '승인합니다. 요건을 충족합니다.',
1975
2793
  quickPhrase2: '조건부 승인합니다. 실행 상황을 확인해 주세요.',
1976
2794
  quickPhrase3: '자료를 보완하여 다시 제출해 주세요.',
@@ -2099,6 +2917,10 @@ const ko = {
2099
2917
  retry: '다시 시도',
2100
2918
  },
2101
2919
  draftBar: {
2920
+ messageClean: "초안 미리보기 — 게시되지 않은 변경이 없습니다. 여기 있는 내용은 모두 이미 반영되어 있습니다.",
2921
+ sampleDataTitle: "샘플 데이터는 게시 후에 표시됩니다",
2922
+ sampleDataBody: "앱의 구조를 미리 보고 있습니다. 게시하면 예시 레코드가 로드되고 앱이 활성화됩니다.",
2923
+ publishCta: "게시하고 확인하기",
2102
2924
  message: '드래프트 미리보기 — 게시되지 않은 변경 사항을 보고 있습니다. 게시 전에는 실제로 반영되지 않습니다.',
2103
2925
  publish: '게시',
2104
2926
  publishing: '게시 중…',