@object-ui/i18n 16.0.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,9 +83,14 @@ const ko = {
74
83
  package: "패키지",
75
84
  },
76
85
  actions: {
86
+ decisionOutput: {
87
+ help: '결정 출력으로 플로우에 전달됩니다.',
88
+ helpMultiValue: '결정 출력으로 플로우에 전달됩니다. 여러 값은 쉼표로 구분하세요.',
89
+ },
77
90
  resultDialog: {
78
- defaultTitle: 'Save this value now',
79
- acknowledge: 'I have saved this',
91
+ defaultTitle: '이 값을 지금 저장하세요',
92
+ acknowledge: '저장했습니다',
93
+ copyAll: '모두 복사',
80
94
  },
81
95
  },
82
96
  validation: {
@@ -93,6 +107,16 @@ const ko = {
93
107
  type: "{{field}}은(는) 유효한 {{type}}이어야 합니다",
94
108
  },
95
109
  form: {
110
+ noPermissionToSave: "이 레코드를 저장할 권한이 없습니다.",
111
+ submitFailed: "저장하지 못했습니다. 다시 시도해 주세요.",
112
+ discardTitle: "변경 내용을 버릴까요?",
113
+ discardMessage: "저장하지 않은 변경 내용이 있습니다. 지금 이 양식을 닫으면 편집 내용이 사라집니다.",
114
+ keepEditing: "계속 편집",
115
+ discard: "버리기",
116
+ conflictTitle: "저장 충돌",
117
+ conflictMessage: "편집하는 동안 다른 사용자가 이 레코드를 변경했습니다. 덮어쓰면 상대방의 변경 내용이 내 내용으로 대체됩니다.",
118
+ conflictLatestVersion: "상대방 저장 시각: {{time}}",
119
+ conflictOverwrite: "덮어쓰기",
96
120
  addItem: "항목 추가",
97
121
  removeItem: "항목 제거",
98
122
  fieldRequired: "이 필드는 필수입니다",
@@ -103,8 +127,6 @@ const ko = {
103
127
  stepOf: "{{total}}단계 중 {{current}}단계",
104
128
  createTitle: "{{object}} 생성",
105
129
  editTitle: "{{object}} 편집",
106
- createDescription: "새 {{object}}을(를) 데이터베이스에 추가합니다.",
107
- editDescription: "{{object}} 세부 정보 업데이트",
108
130
  saveRecord: "레코드 저장",
109
131
  create: "생성",
110
132
  update: "업데이트",
@@ -113,14 +135,70 @@ const ko = {
113
135
  deleteSuccess: "{{object}} 삭제됨",
114
136
  },
115
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
+ },
116
151
  relativeDate: {
117
152
  overdue: "기한 초과 {{count}}일",
118
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
+ },
119
170
  richText: {
120
171
  format: "형식: {{format}}",
121
172
  basicEditorHint: "서식 있는 텍스트 편집기 (기본)",
122
173
  placeholder: "내용을 입력하세요...",
123
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
+ },
124
202
  },
125
203
  table: {
126
204
  rowsPerPage: "페이지당 행 수",
@@ -155,6 +233,37 @@ const ko = {
155
233
  delete: "삭제",
156
234
  },
157
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
+ },
158
267
  actions: "작업",
159
268
  edit: "편집",
160
269
  delete: "삭제",
@@ -180,7 +289,88 @@ const ko = {
180
289
  densityCycleShortHint: "클릭하여 변경",
181
290
  },
182
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: "호환 폴백으로 가져왔습니다: 이 연결은 서버 가져오기 경로를 지원하지 않아 값이 서버 측 형 변환 없이 텍스트로 저장되었습니다. 완전한 가져오기 기능(형 변환 및 관계 조회)을 사용하려면 백엔드/클라이언트를 업그레이드하세요.",
183
372
  title: "{{object}} 가져오기",
373
+ notAllowed: "이 객체는 가져오기가 허용되지 않습니다.",
184
374
  stepUpload: "업로드",
185
375
  stepMapping: "매핑",
186
376
  stepPreview: "미리보기",
@@ -256,6 +446,42 @@ const ko = {
256
446
  moreEvents: "+{{count}} 더보기",
257
447
  },
258
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: "새로고침",
259
485
  loading: 'Loading records...',
260
486
  recordCount: "{{count}}개 레코드",
261
487
  recordCountOne: "{{count}}개 레코드",
@@ -267,6 +493,8 @@ const ko = {
267
493
  filterRecords: "레코드 필터",
268
494
  sort: "정렬",
269
495
  sortRecords: "레코드 정렬",
496
+ sortByIdSuffix: "(ID 기준)",
497
+ sortRelationalHint: "다른 레코드를 참조하는 열은 목록에 없습니다. 저장된 ID로만 정렬할 수 있고 셀에 표시되는 이름으로는 정렬할 수 없습니다. 그 이름으로 정렬하려면 이름을 담는 수식 필드를 추가하세요.",
270
498
  group: "그룹",
271
499
  groupBy: "그룹 기준",
272
500
  export: "내보내기",
@@ -296,6 +524,11 @@ const ko = {
296
524
  recordEditingTitle: "레코드 편집",
297
525
  },
298
526
  managedByBadge: {
527
+ systemWritable: {
528
+ short: "플랫폼 스키마",
529
+ title: "플랫폼 정의, 관리자 쓰기 가능",
530
+ body: "이 객체의 스키마는 플랫폼이 정의하지만, 행은 여기서 직접 만들고 편집할 수 있습니다. 누가 쓸 수 있는지는 이 배지가 아니라 위임 관리와 레코드 수준 보안이 결정합니다.",
531
+ },
299
532
  config: {
300
533
  short: "관리 구성",
301
534
  title: "관리자 구성",
@@ -318,6 +551,7 @@ const ko = {
318
551
  },
319
552
  },
320
553
  kanban: {
554
+ uncategorized: "미분류",
321
555
  addCard: "카드 추가",
322
556
  addColumn: "열 추가",
323
557
  moveCard: "카드 이동",
@@ -339,12 +573,92 @@ const ko = {
339
573
  },
340
574
  },
341
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: "저장 실패 — 변경이 취소되었습니다",
342
644
  column: {
343
645
  taskName: "작업 이름",
344
646
  start: "시작",
345
647
  end: "종료",
346
648
  },
347
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: "다시 실행",
348
662
  prevPeriod: "이전 기간",
349
663
  nextPeriod: "다음 기간",
350
664
  zoomIn: "확대",
@@ -390,6 +704,9 @@ const ko = {
390
704
  redo: 'Redo',
391
705
  },
392
706
  detail: {
707
+ editInlineHint: "더블클릭하여 편집",
708
+ systemActor: "시스템",
709
+ unknownUser: "알 수 없음",
393
710
  back: "뒤로",
394
711
  edit: "편집",
395
712
  editInline: "편집",
@@ -439,6 +756,18 @@ const ko = {
439
756
  attachmentCount: "첨부파일 {{count}}개",
440
757
  attachmentCountPlural: "첨부파일 {{count}}개",
441
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: "이 작업을 수행할 권한이 없습니다.",
442
771
  unifiedDiff: "통합 보기",
443
772
  sideBySideDiff: "나란히 보기",
444
773
  noChanges: "변경 없음",
@@ -486,9 +815,15 @@ const ko = {
486
815
  saving: "저장 중…",
487
816
  lockedByApproval: "승인을 위해 잠김",
488
817
  lockedTooltip: "이 레코드에 대기 중인 승인 요청이 있습니다. 편집이 잠겨 있습니다",
818
+ writeStrippedTitle: "일부 필드가 저장되지 않았습니다",
819
+ writeStrippedReadonly: "다음 필드는 읽기 전용이므로 저장되지 않았습니다: {{fields}}",
820
+ writeStrippedByState: "다음 필드는 이 레코드의 현재 상태에서 편집할 수 없으므로 저장되지 않았습니다: {{fields}}",
821
+ approvalPendingEditable: "승인 진행 중 · 편집 가능",
822
+ approvalPendingTooltip: "이 레코드에 대기 중인 승인 요청이 있지만 이 단계에서는 편집할 수 있습니다",
489
823
  cancelApproval: "승인 취소",
490
824
  cancelApprovalInFlight: "취소 중…",
491
825
  cancelApprovalTooltip: "대기 중인 승인 요청을 취소하여 레코드 잠금 해제",
826
+ cancelApprovalTooltipUnlocked: "대기 중인 승인 요청 취소",
492
827
  cancelApprovalFailed: "승인 취소 실패",
493
828
  cancelApprovalUnavailable: "이 데이터 소스에서는 승인 취소가 지원되지 않습니다",
494
829
  linkCopied: "링크가 클립보드에 복사됨",
@@ -604,6 +939,35 @@ const ko = {
604
939
  resetZoom: "확대/축소 초기화",
605
940
  },
606
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
+ },
607
971
  addWidget: "위젯 추가",
608
972
  removeWidget: "위젯 제거",
609
973
  editLayout: "레이아웃 편집",
@@ -731,6 +1095,7 @@ const ko = {
731
1095
  navTypeGroup: "그룹",
732
1096
  navTypeSeparator: "구분선",
733
1097
  navTypeAction: "작업",
1098
+ navTypeComponent: "컴포넌트",
734
1099
  navEditIcon: "아이콘 편집",
735
1100
  navToggleVisible: "가시성 토글",
736
1101
  navHidden: "숨김",
@@ -832,8 +1197,199 @@ const ko = {
832
1197
  },
833
1198
  },
834
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
+ },
835
1390
  title: "ObjectStack 콘솔",
836
1391
  initializing: "애플리케이션 초기화 중...",
1392
+ loadingHint: "새 환경을 설정하는 데 시간이 조금 걸릴 수 있습니다.",
837
1393
  breadcrumb: {
838
1394
  dashboards: "대시보드",
839
1395
  pages: "페이지",
@@ -875,6 +1431,7 @@ const ko = {
875
1431
  toggleDarkMode: "다크 모드 전환",
876
1432
  },
877
1433
  commandPalette: {
1434
+ title: "명령 팔레트",
878
1435
  placeholder: "명령어를 입력하거나 검색...",
879
1436
  noResults: "결과를 찾을 수 없습니다.",
880
1437
  objects: "객체",
@@ -908,6 +1465,14 @@ const ko = {
908
1465
  system: "시스템",
909
1466
  },
910
1467
  objectView: {
1468
+ viewTypeTree: "트리",
1469
+ viewTypeTreeDesc: "상위 필드를 기준으로 자기 참조 레코드를 계층 구조로 중첩합니다.",
1470
+ parentField: "상위 필드",
1471
+ parentFieldHelp: "계층 구조를 정의하는 상위 레코드(같은 객체)를 가리키는 필드입니다. 자기 참조 필드만 사용할 수 있습니다.",
1472
+ viewName: "이름",
1473
+ viewNameHelp: "머신 키(snake_case)입니다. 제목에서 자동으로 채워집니다 — 원하면 수정하세요.",
1474
+ viewNameRequired: "키를 입력하세요(소문자, 숫자, 밑줄). 비라틴 문자 제목에서는 자동으로 채워지지 않습니다.",
1475
+ viewNameInvalid: "소문자, 숫자, 밑줄을 사용하고 문자 또는 밑줄로 시작하세요.",
911
1476
  systemViewReadonly: 'System view defined in code - duplicate to customize.',
912
1477
  expandToPage: 'Open as full page',
913
1478
  objectNotFound: "객체를 찾을 수 없음",
@@ -1121,7 +1686,28 @@ const ko = {
1121
1686
  },
1122
1687
  },
1123
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
+ },
1124
1703
  login: {
1704
+ signingIn: "로그인하는 중…",
1705
+ ssoHandoff: "{{target}}(으)로 계속",
1706
+ devAdminHint: {
1707
+ title: "개발 인스턴스",
1708
+ body: "시드된 개발용 관리자 계정으로 로그인하세요:",
1709
+ dismiss: "닫기",
1710
+ },
1125
1711
  title: "계정에 로그인",
1126
1712
  description: "이메일과 비밀번호를 입력하세요",
1127
1713
  emailLabel: "이메일",
@@ -1134,6 +1720,7 @@ const ko = {
1134
1720
  noAccountText: "계정이 없으신가요?",
1135
1721
  signUpText: "회원가입",
1136
1722
  errors: {
1723
+ oauthCallbackFailed: "싱글 사인온을 완료하지 못했습니다 — 로그인 링크가 만료되었거나 이미 사용되었습니다. 다시 시도해 주세요.",
1137
1724
  invalidCredentials: "잘못된 이메일 또는 비밀번호입니다. 다시 시도하세요.",
1138
1725
  emailNotVerified: "로그인하기 전에 이메일을 확인하세요.",
1139
1726
  },
@@ -1259,6 +1846,40 @@ const ko = {
1259
1846
  shell: {
1260
1847
  tenantHostHint: "이 작업 공간에 로그인하는 중입니다",
1261
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
+ },
1262
1883
  },
1263
1884
  profile: {
1264
1885
  title: "프로필",
@@ -1323,11 +1944,15 @@ const ko = {
1323
1944
  settings: "워크스페이스 설정",
1324
1945
  },
1325
1946
  help: {
1947
+ onThisPage: "이 페이지에서",
1948
+ keyboardShortcuts: "키보드 단축키",
1326
1949
  appDocs: '이 앱의 문서',
1327
1950
  allDocs: '전체 문서',
1328
1951
  onlineDocs: '온라인 문서',
1329
1952
  },
1330
1953
  sidebar: {
1954
+ packageManagement: "패키지 관리",
1955
+ searchNavigation: "내비게이션 검색...",
1331
1956
  settings: "설정",
1332
1957
  help: "도움말",
1333
1958
  helpTooltip: "도움말 및 문서",
@@ -1344,14 +1969,66 @@ const ko = {
1344
1969
  removeFromFavorites: "즐겨찾기에서 {{name}} 제거",
1345
1970
  },
1346
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
+ },
1347
1989
  aiAssistant: "AI 어시스턴트",
1348
1990
  designInStudio: "Studio에서 디자인",
1349
1991
  },
1350
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
+ },
1351
2020
  title: "홈",
1352
2021
  subtitle: "워크스페이스 대시보드",
1353
2022
  nav: "홈",
1354
2023
  allApps: "모든 애플리케이션",
2024
+ yourApps: "내 앱",
2025
+ showMoreApps: "더 보기",
2026
+ showLess: "간략히",
2027
+ continueEmpty: "열어본 항목이 여기에 표시됩니다.",
2028
+ actionCenter: {
2029
+ title: "확인이 필요한 항목",
2030
+ empty: "모두 처리했습니다",
2031
+ },
1355
2032
  loading: "워크스페이스 로드 중...",
1356
2033
  recent: "최근",
1357
2034
  starred: "즐겨찾기",
@@ -1403,7 +2080,21 @@ const ko = {
1403
2080
  },
1404
2081
  },
1405
2082
  layout: {
2083
+ systemNav: {
2084
+ systemSettings: "시스템 설정",
2085
+ applications: "애플리케이션",
2086
+ appMarketplace: "앱 마켓플레이스",
2087
+ objectManager: "객체 관리자",
2088
+ users: "사용자",
2089
+ organizations: "조직",
2090
+ roles: "역할",
2091
+ configuration: "구성",
2092
+ createApp: "앱 만들기",
2093
+ },
1406
2094
  appSwitcher: {
2095
+ switchApplication: "애플리케이션 전환",
2096
+ appsAvailable: "사용 가능한 앱 {{count}}개",
2097
+ editNavigation: "내비게이션 편집",
1407
2098
  home: "홈",
1408
2099
  addApp: "앱 추가",
1409
2100
  editApp: "앱 편집",
@@ -1493,10 +2184,11 @@ const ko = {
1493
2184
  requiredError: "{{label}}은(는) 필수입니다",
1494
2185
  cancel: "취소",
1495
2186
  confirm: "확인",
2187
+ uploading: "업로드 중…",
1496
2188
  defaultActionTitle: "작업",
1497
2189
  ok: "확인",
1498
- lookupPlaceholder: "{{label}}의 레코드 ID(UUID) 붙여넣기",
1499
- lookupHelpText: "참조된 개체의 레코드 ID를 입력하세요. 선택기가 곧 추가됩니다.",
2190
+ lookupPlaceholder: "{{label}}의 레코드 ID",
2191
+ lookupHelpText: "이 매개변수에 참조 개체가 설정되어 있지 않아 레코드 선택기를 사용할 수 없습니다. 레코드 ID를 직접 입력하거나 관리자에게 작업 매개변수 수정을 요청하세요.",
1500
2192
  },
1501
2193
  actionConfirm: {
1502
2194
  title: "작업 확인",
@@ -1521,6 +2213,8 @@ const ko = {
1521
2213
  updateFailed: "탐색을 업데이트할 수 없습니다",
1522
2214
  },
1523
2215
  objectActions: {
2216
+ resetPackageSetConfirm: "이 권한 세트는 설치된 패키지에 포함되어 있어 제거할 수 없습니다. 삭제하면 패키지 기본 상태로 초기화되며 이 환경의 커스터마이징은 폐기됩니다. 계속할까요?",
2217
+ resetPackageSetSuccess: "권한 세트를 패키지 기본 상태로 초기화했습니다",
1524
2218
  deleteSuccess: "{{label}} 삭제 성공",
1525
2219
  deleteFailed: "{{label}} 삭제 실패",
1526
2220
  noRecordId: "레코드 ID가 없습니다",
@@ -1685,6 +2379,7 @@ const ko = {
1685
2379
  },
1686
2380
  },
1687
2381
  organizations: {
2382
+ create: "워크스페이스 만들기",
1688
2383
  mine: "내 조직",
1689
2384
  title: "조직",
1690
2385
  heading: "내 조직",
@@ -1698,6 +2393,11 @@ const ko = {
1698
2393
  noMatches: "검색과 일치하는 조직이 없습니다.",
1699
2394
  },
1700
2395
  notifications: {
2396
+ regionLabel: "알림",
2397
+ groupCount: "알림 {{count}}건",
2398
+ groupUnread: "읽지 않음 {{count}}건",
2399
+ groupMarkRead: "읽음 표시",
2400
+ groupMarkReadTitle: "이 유형 전체를 읽음으로 표시",
1701
2401
  empty: "알림 없음",
1702
2402
  markAllRead: "모두 읽음으로 표시",
1703
2403
  viewAll: "모든 알림 보기",
@@ -1816,7 +2516,103 @@ const ko = {
1816
2516
  done: '완료 — 숨기기',
1817
2517
  },
1818
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
+ },
1819
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
+ },
1820
2616
  title: "앱 마켓플레이스",
1821
2617
  subtitle: "ObjectStack 카탈로그에 게시된 승인된 앱을 탐색하세요. 앱을 클릭하여 세부 정보를 보고 환경 중 하나에 설치하세요.",
1822
2618
  searchPlaceholder: "이름 또는 매니페스트 ID로 앱 검색…",
@@ -1868,6 +2664,7 @@ const ko = {
1868
2664
  updateAvailable: '업데이트 가능',
1869
2665
  },
1870
2666
  action: {
2667
+ installed: "설치됨",
1871
2668
  install: "설치",
1872
2669
  reinstall: "재설치",
1873
2670
  working: "처리 중…",
@@ -1938,6 +2735,14 @@ const ko = {
1938
2735
  yearsAgo: "{{count}}년 전",
1939
2736
  },
1940
2737
  },
2738
+ approvals: {
2739
+ approve: '승인',
2740
+ reject: '반려',
2741
+ comment: '의견(선택 사항)',
2742
+ approveSuccess: '승인됨',
2743
+ rejectSuccess: '반려됨',
2744
+ rejectConfirm: '이 승인 요청을 반려하시겠습니까?',
2745
+ },
1941
2746
  approvalsInbox: {
1942
2747
  loadMore: '더 보기',
1943
2748
  loadingMore: '불러오는 중…',
@@ -1962,13 +2767,28 @@ const ko = {
1962
2767
  slaRemaining: 'SLA {{dur}} 남음',
1963
2768
  slaOverdue: 'SLA {{dur}} 초과',
1964
2769
  actReassign: '재할당',
2770
+ reassignFromTo: '{{from}} 님에서 {{to}} 님으로',
1965
2771
  actRemind: '독촉',
1966
2772
  actRequestInfo: '보완 요청',
1967
2773
  actComment: '댓글',
1968
2774
  stepProgress: '승인 단계',
1969
2775
  prevRequest: '이전',
1970
2776
  nextRequest: '다음',
1971
- 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: '금액(높은순)',
1972
2792
  quickPhrase1: '승인합니다. 요건을 충족합니다.',
1973
2793
  quickPhrase2: '조건부 승인합니다. 실행 상황을 확인해 주세요.',
1974
2794
  quickPhrase3: '자료를 보완하여 다시 제출해 주세요.',
@@ -2097,6 +2917,10 @@ const ko = {
2097
2917
  retry: '다시 시도',
2098
2918
  },
2099
2919
  draftBar: {
2920
+ messageClean: "초안 미리보기 — 게시되지 않은 변경이 없습니다. 여기 있는 내용은 모두 이미 반영되어 있습니다.",
2921
+ sampleDataTitle: "샘플 데이터는 게시 후에 표시됩니다",
2922
+ sampleDataBody: "앱의 구조를 미리 보고 있습니다. 게시하면 예시 레코드가 로드되고 앱이 활성화됩니다.",
2923
+ publishCta: "게시하고 확인하기",
2100
2924
  message: '드래프트 미리보기 — 게시되지 않은 변경 사항을 보고 있습니다. 게시 전에는 실제로 반영되지 않습니다.',
2101
2925
  publish: '게시',
2102
2926
  publishing: '게시 중…',