@object-ui/i18n 17.3.0 → 17.5.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +1295 -1
  2. package/README.md +0 -13
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +11 -1
  5. package/dist/locales/ar.d.ts +466 -107
  6. package/dist/locales/ar.js +559 -153
  7. package/dist/locales/de.d.ts +466 -107
  8. package/dist/locales/de.js +574 -175
  9. package/dist/locales/en.d.ts +502 -143
  10. package/dist/locales/en.js +678 -145
  11. package/dist/locales/es.d.ts +466 -107
  12. package/dist/locales/es.js +553 -155
  13. package/dist/locales/fr.d.ts +466 -107
  14. package/dist/locales/fr.js +553 -152
  15. package/dist/locales/index.d.ts +4734 -1144
  16. package/dist/locales/ja.d.ts +466 -107
  17. package/dist/locales/ja.js +545 -146
  18. package/dist/locales/ko.d.ts +466 -107
  19. package/dist/locales/ko.js +551 -153
  20. package/dist/locales/pt.d.ts +466 -107
  21. package/dist/locales/pt.js +552 -154
  22. package/dist/locales/ru.d.ts +466 -107
  23. package/dist/locales/ru.js +563 -153
  24. package/dist/locales/zh.d.ts +501 -142
  25. package/dist/locales/zh.js +542 -142
  26. package/dist/pickLocalized.d.ts +21 -0
  27. package/dist/pickLocalized.js +40 -7
  28. package/dist/provider.d.ts +83 -1
  29. package/dist/provider.js +303 -29
  30. package/dist/useDisplayLocale.d.ts +49 -0
  31. package/dist/useDisplayLocale.js +55 -0
  32. package/dist/useObjectLabel.d.ts +8 -2
  33. package/dist/useObjectLabel.js +28 -8
  34. package/dist/useSafeTranslation.js +50 -2
  35. package/dist/utils/index.d.ts +1 -0
  36. package/dist/utils/index.js +1 -0
  37. package/dist/utils/number-display.d.ts +32 -0
  38. package/dist/utils/number-display.js +32 -0
  39. package/dist/utils/spec-formatters.d.ts +39 -13
  40. package/dist/utils/spec-formatters.js +3 -3
  41. package/package.json +4 -3
@@ -1,4 +1,18 @@
1
1
  const ko = {
2
+ // objectui#4467 — the impersonation banner (app-shell ImpersonationBanner).
3
+ // Raised by `session.impersonatedBy`, so it survives SPA reboots; it names
4
+ // BOTH parties because the audit trail attributes the work to the impersonated
5
+ // user, and the exit states its own failure rather than appearing to succeed.
6
+ impersonation: {
7
+ banner: {
8
+ message: '{{user}} 계정을 대행하고 있습니다. 모든 작업이 해당 사용자로 기록됩니다.',
9
+ startedBy: '관리자 {{admin}}이(가) 시작했습니다.',
10
+ stop: '대행 종료',
11
+ stopping: '종료하는 중…',
12
+ stopFailed: '대행을 종료할 수 없습니다: {{reason}}',
13
+ notRestored: '서버가 요청을 받았지만 관리자 세션을 복원하지 않았습니다. 여전히 {{user}} 계정을 대행하고 있습니다. 로그아웃 후 다시 로그인하여 종료하세요.',
14
+ },
15
+ },
2
16
  // objectui#2600 B5 — capability picker scope group headers (labels come from the sys_capability registry).
3
17
  capability: {
4
18
  label: {
@@ -16,6 +30,26 @@ const ko = {
16
30
  other: '기타',
17
31
  },
18
32
  },
33
+ // objectui#3546 slice six — PermissionFacetLink 의 권한 파셋 요약.
34
+ // 수량 라벨은 appDesigner.objectManager.fieldCount 와 같은 "{{count}}개 + 단위" 형식.
35
+ // 한국어에는 단수/복수 구분이 없어 `_one` 은 기본 키와 같은 값(의도적).
36
+ perm: {
37
+ facet: {
38
+ none: "없음",
39
+ more: "+{{count}} 더보기",
40
+ objects: "{{count}}개 오브젝트",
41
+ objects_one: "{{count}}개 오브젝트",
42
+ fields: "{{count}}개 필드 규칙",
43
+ fields_one: "{{count}}개 필드 규칙",
44
+ rls: "{{count}}개 RLS 정책",
45
+ rls_one: "{{count}}개 RLS 정책",
46
+ tabs: "{{count}}개 탭 규칙",
47
+ tabs_one: "{{count}}개 탭 규칙",
48
+ adminScope: "위임 관리가 구성됨",
49
+ designInStudio: "Studio에서 디자인 →",
50
+ designInStudioHint: "Studio에서 디자인",
51
+ },
52
+ },
19
53
  lookup: {
20
54
  recentlyUsed: '최근 사용',
21
55
  allResults: '모든 결과',
@@ -46,13 +80,12 @@ const ko = {
46
80
  common: {
47
81
  addToFavorites: "즐겨찾기에 추가",
48
82
  removeFromFavorites: "즐겨찾기에서 제거",
49
- loading: "로딩 중...",
83
+ loading: "로딩 중…",
50
84
  save: "저장",
51
85
  cancel: "취소",
52
86
  delete: "삭제",
53
87
  edit: "편집",
54
88
  create: "생성",
55
- search: "검색",
56
89
  filter: "필터",
57
90
  reset: "초기화",
58
91
  confirm: "확인",
@@ -76,7 +109,7 @@ const ko = {
76
109
  required: "필수",
77
110
  optional: "선택",
78
111
  selectOption: "옵션을 선택하세요",
79
- select: "선택...",
112
+ select: "선택…",
80
113
  openChat: "채팅 열기",
81
114
  closeChat: "채팅 닫기",
82
115
  closePanel: "패널 닫기",
@@ -85,6 +118,11 @@ const ko = {
85
118
  itemCountOne: "{{count}}개 항목",
86
119
  toggleSidebar: "사이드바 전환",
87
120
  package: "패키지",
121
+ done: "완료",
122
+ editInStudio: "Studio에서 편집",
123
+ record: "레코드",
124
+ retry: "다시 시도",
125
+ printDialogHint: "브라우저의 인쇄 대화 상자를 엽니다(PDF 내보내기가 아닙니다)",
88
126
  },
89
127
  actions: {
90
128
  decisionOutput: {
@@ -116,6 +154,9 @@ const ko = {
116
154
  submitFailed: "저장하지 못했습니다. 다시 시도해 주세요.",
117
155
  discardTitle: "변경 내용을 버릴까요?",
118
156
  discardMessage: "저장하지 않은 변경 내용이 있습니다. 지금 이 양식을 닫으면 편집 내용이 사라집니다.",
157
+ // objectui#4024 — the create/edit dialog's `sr-only` accessible
158
+ // description, used when the form declares no `description` of its own.
159
+ dialogDescriptionFallback: "양식 필드를 작성한 다음 제출하거나 취소하세요.",
119
160
  keepEditing: "계속 편집",
120
161
  discard: "버리기",
121
162
  conflictTitle: "저장 충돌",
@@ -184,7 +225,7 @@ const ko = {
184
225
  richText: {
185
226
  format: "형식: {{format}}",
186
227
  basicEditorHint: "서식 있는 텍스트 편집기 (기본)",
187
- placeholder: "내용을 입력하세요...",
228
+ placeholder: "내용을 입력하세요…",
188
229
  },
189
230
  options: {
190
231
  empty: "선택할 수 있는 옵션이 없습니다",
@@ -250,7 +291,7 @@ const ko = {
250
291
  saveAll: "모두 저장 ({{count}})",
251
292
  addRecord: "레코드 추가",
252
293
  open: "열기",
253
- search: "검색...",
294
+ search: "검색…",
254
295
  modified: "{{count}}개 행 수정됨",
255
296
  saveFailed: '저장 실패',
256
297
  selected: "{{count}}개 선택됨",
@@ -294,7 +335,7 @@ const ko = {
294
335
  delete: "삭제",
295
336
  export: "내보내기",
296
337
  exportAs: "{{format}}으로 내보내기",
297
- loading: "그리드 로딩 중...",
338
+ loading: "그리드 로딩 중…",
298
339
  errorLoading: "그리드 로딩 오류",
299
340
  pullToRefresh: "당겨서 새로고침",
300
341
  refreshing: "새로고침 중…",
@@ -305,6 +346,22 @@ const ko = {
305
346
  yes: "예",
306
347
  no: "아니요",
307
348
  systemFields: "시스템",
349
+ // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
350
+ // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
351
+ // pack controls its own separator and word order.
352
+ summary: {
353
+ pattern: "{{label}}: {{value}}",
354
+ count: "개수",
355
+ countEmpty: "빈 값",
356
+ countFilled: "채워짐",
357
+ countUnique: "고유",
358
+ percentEmpty: "빈 값",
359
+ percentFilled: "채워짐",
360
+ sum: "합계",
361
+ avg: "평균",
362
+ min: "최소",
363
+ max: "최대",
364
+ },
308
365
  toolbar: {
309
366
  densityMode: "밀도",
310
367
  densityCompact: "컴팩트",
@@ -418,12 +475,12 @@ const ko = {
418
475
  templateName: "템플릿 이름",
419
476
  save: "저장",
420
477
  deleteTemplate: "템플릿 삭제",
421
- savedMapping: 'Saved mapping:',
422
- chooseSavedMapping: 'Choose a saved mapping…',
423
- manualMapping: '— Map columns manually —',
424
- transform: 'Transform',
425
- savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
426
- savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
478
+ savedMapping: '저장된 매핑:',
479
+ chooseSavedMapping: '저장된 매핑 선택…',
480
+ manualMapping: '— 열 수동 매핑 —',
481
+ transform: '변환',
482
+ savedMappingHint: '매핑 "{{name}}"은(는) 서버에서 이름 변경 + 변환 + 형 변환을 적용합니다. 열 매핑은 읽기 전용입니다.',
483
+ savedMappingPreviewNote: '미리보기에는 원본 열이 표시됩니다. 가져올 때 매핑 "{{name}}"이(가) 서버에서 이름 변경, 변환, 형 변환을 적용합니다.',
427
484
  csvColumn: "열",
428
485
  mapsTo: "매핑 대상",
429
486
  typeMismatch: "{{type}}인 것 같습니다",
@@ -483,6 +540,8 @@ const ko = {
483
540
  loadErrorUnauthorizedMessage: "세션이 만료되었거나 로그아웃되었습니다. 다시 로그인한 후 확인하세요.",
484
541
  loadErrorRejectedTitle: "이 뷰의 쿼리가 거부되었습니다",
485
542
  loadErrorRejectedMessage: "서버가 이 뷰의 필터 또는 쿼리 옵션을 처리하지 못했습니다. 필터를 지우면 대부분 해결됩니다. 뷰가 이 상태로 저장되어 있다면 관리자가 수정해야 합니다.",
543
+ loadErrorApiDisabledTitle: "이 객체는 API로 제공되지 않습니다",
544
+ loadErrorApiDisabledMessage: "객체가 API에 공개되어 있지 않아 이 페이지는 레코드를 불러올 수 없습니다. 이는 권한이 아니라 객체 자체의 설정입니다. 관리자가 API 액세스를 활성화해야 이 페이지가 동작합니다.",
486
545
  retry: "다시 시도",
487
546
  managedBy: {
488
547
  system: {
@@ -507,7 +566,7 @@ const ko = {
507
566
  },
508
567
  },
509
568
  refresh: "새로고침",
510
- loading: 'Loading records...',
569
+ loading: "레코드 로딩 중…",
511
570
  recordCount: "{{count}}개 레코드",
512
571
  recordCountOne: "{{count}}개 레코드",
513
572
  addRecord: "레코드 추가",
@@ -519,7 +578,8 @@ const ko = {
519
578
  sort: "정렬",
520
579
  sortRecords: "레코드 정렬",
521
580
  sortByIdSuffix: "(ID 기준)",
522
- sortRelationalHint: "다른 레코드를 참조하는 열은 목록에 없습니다. 저장된 ID로만 정렬할 수 있고 셀에 표시되는 이름으로는 정렬할 수 없습니다. 그 이름으로 정렬하려면 이름을 담는 수식 필드를 추가하세요.",
581
+ sortRelationalHint: "다른 레코드를 참조하는 열은 목록에 없습니다. 저장된 ID로만 정렬할 수 있고 셀에 표시되는 이름으로는 정렬할 수 없습니다. 그 이름으로 정렬하려면 이름을 이 오브젝트에 비정규화하여 원본이 변경될 때 기록되는 저장 필드로 만든 다음, 그 필드로 정렬하세요. 수식 필드는 안 됩니다. 수식은 가상이라 저장되는 열이 없어 서버가 정렬을 거부합니다.",
582
+ resetSortToDefault: "뷰 기본 정렬로 재설정",
523
583
  group: "그룹",
524
584
  groupBy: "그룹 기준",
525
585
  export: "내보내기",
@@ -577,13 +637,16 @@ const ko = {
577
637
  },
578
638
  kanban: {
579
639
  uncategorized: "미분류",
640
+ columns: "열",
580
641
  addCard: "카드 추가",
581
642
  addColumn: "열 추가",
582
643
  moveCard: "카드 이동",
583
644
  deleteCard: "카드 삭제",
584
645
  deleteColumn: "열 삭제",
585
646
  noCards: "카드 없음",
586
- cardTitlePlaceholder: "카드 제목 입력...",
647
+ cardTitlePlaceholder: "카드 제목 입력…",
648
+ requiredFieldsTitle: "필수 항목 입력",
649
+ requiredFieldsDescription: "이 이동으로 아래 항목이 필수가 됩니다. 입력한 후 계속하세요.",
587
650
  },
588
651
  timeline: {
589
652
  bucket: {
@@ -596,6 +659,13 @@ const ko = {
596
659
  noDate: "날짜 없음",
597
660
  unassigned: "미할당",
598
661
  },
662
+ scale: {
663
+ week: "{{n}}주차",
664
+ quarter: "{{year}}년 {{quarter}}분기",
665
+ },
666
+ gantt: {
667
+ rowLabel: "항목",
668
+ },
599
669
  },
600
670
  gantt: {
601
671
  viewMode: {
@@ -642,6 +712,18 @@ const ko = {
642
712
  ff: "종료 → 종료",
643
713
  sf: "시작 → 종료",
644
714
  },
715
+ linkEnd: {
716
+ start: "시작",
717
+ end: "종료",
718
+ },
719
+ link: {
720
+ rejected: {
721
+ self: "작업은 자기 자신에 종속될 수 없습니다.",
722
+ locked: "이 행은 잠겨 있어 새 종속성을 추가할 수 없습니다.",
723
+ group: "요약 행은 종속 대상이 될 수 없습니다. 하위 작업에 연결하세요.",
724
+ cycle: "이 연결은 순환 종속성을 만듭니다.",
725
+ },
726
+ },
645
727
  conflict: {
646
728
  title: "일정 충돌",
647
729
  body: "이 이동은 종속성 제약과 충돌합니다. 영향을 받는 작업 {{count}}건의 일정을 자동으로 조정할까요?",
@@ -650,8 +732,8 @@ const ko = {
650
732
  },
651
733
  autoScheduleDlg: {
652
734
  title: "자동 일정 조정",
653
- body: "종속성 연결을 충족하도록 작업 {count}건을 뒤로 미룰까요?",
654
- skipped: "잠긴 작업 {count}건도 연결을 위반하지만 건너뛰었습니다.",
735
+ body: "종속성 연결을 충족하도록 작업 {{count}}건을 뒤로 미룰까요?",
736
+ skipped: "잠긴 작업 {{count}}건도 연결을 위반하지만 건너뛰었습니다.",
655
737
  confirm: "적용",
656
738
  cancel: "취소",
657
739
  none: "모든 종속성이 충족되었습니다 — 조정할 일정이 없습니다.",
@@ -688,6 +770,7 @@ const ko = {
688
770
  exportPng: "PNG로 내보내기",
689
771
  exportPdf: "PDF로 내보내기",
690
772
  saveLayout: "레이아웃 저장",
773
+ refresh: "새로 고침",
691
774
  undo: "실행 취소",
692
775
  redo: "다시 실행",
693
776
  prevPeriod: "이전 기간",
@@ -728,11 +811,11 @@ const ko = {
728
811
  defaultBadge: "기본",
729
812
  tabActionsFor: "{{name}}의 보기 작업",
730
813
  readonlyAriaLabel: "읽기 전용 보기",
731
- readonlyTooltip: "시스템 보기 — 사용자 지정하려면 복제하세요.",
814
+ readonlyTooltip: "시스템 보기 — 코드에 정의되어 있으며 읽기 전용입니다.",
732
815
  },
733
816
  designer: {
734
- undo: 'Undo',
735
- redo: 'Redo',
817
+ undo: "실행 취소",
818
+ redo: "다시 실행",
736
819
  },
737
820
  detail: {
738
821
  editInlineHint: "더블클릭하여 편집",
@@ -772,13 +855,15 @@ const ko = {
772
855
  relatedRecords: "{{count}}개 레코드",
773
856
  relatedRecordOne: "{{count}}개 레코드",
774
857
  noRelatedRecords: "관련 레코드를 찾을 수 없습니다",
775
- loading: "로딩 중...",
858
+ loading: "로딩 중…",
776
859
  copyToClipboard: "클립보드에 복사",
777
860
  copied: "복사됨!",
778
861
  deleteConfirmation: "이 레코드를 삭제하시겠습니까?",
862
+ deleted: "레코드가 삭제됨",
779
863
  editRecord: "레코드 편집",
780
864
  viewAll: "모두 보기",
781
865
  new: "새로 만들기",
866
+ add: "추가",
782
867
  emptyValue: "—",
783
868
  comments: "댓글",
784
869
  searchComments: "댓글 검색…",
@@ -843,6 +928,7 @@ const ko = {
843
928
  loadMore: "더 보기",
844
929
  edited: "(수정됨)",
845
930
  via: "{{source}} 통해",
931
+ viewSource: "원본 보기",
846
932
  replyCount: "답글 {{count}}개",
847
933
  replyCountPlural: "답글 {{count}}개",
848
934
  replyPlaceholder: "답글…",
@@ -884,9 +970,11 @@ const ko = {
884
970
  concurrentUpdateReload: "현재 버전 로드",
885
971
  concurrentUpdateOverwrite: "그래도 덮어쓰기",
886
972
  concurrentUpdateCancel: "취소",
973
+ concurrentUpdateRecordLabel: "이 레코드",
887
974
  openInNewTab: "새 탭에서 열기",
888
975
  activity: "활동",
889
976
  history: "기록",
977
+ historyEmpty: "아직 기록이 없습니다",
890
978
  editRow: "편집",
891
979
  deleteRow: "삭제",
892
980
  deleteRowConfirmation: "이 레코드를 삭제하시겠습니까?",
@@ -896,12 +984,15 @@ const ko = {
896
984
  nextPage: "다음",
897
985
  pageOf: "{{total}}페이지 중 {{current}}페이지",
898
986
  sortBy: "정렬 기준",
899
- filterPlaceholder: "필터...",
987
+ filterPlaceholder: "필터…",
900
988
  highlightFields: "주요 필드",
901
989
  createdBy: "작성자",
902
990
  updatedBy: "업데이트한 사람",
903
991
  created: "작성됨",
904
992
  updated: "업데이트됨",
993
+ // objectui#3863 — base key. ko has a single plural category (`other`), so this
994
+ // slot is unreachable here and equals `_other` for key-set parity.
995
+ showEmptyRelated: "+ {{count}}개 비어 있음",
905
996
  showEmptyRelated_one: "+ {{count}}개 비어 있음",
906
997
  showEmptyRelated_other: "+ {{count}}개 비어 있음",
907
998
  copyEmail: "이메일 복사",
@@ -913,7 +1004,8 @@ const ko = {
913
1004
  },
914
1005
  chart: {
915
1006
  noData: "차트 데이터가 없습니다",
916
- loading: "차트 로딩 중...",
1007
+ loading: "차트 로딩 중…",
1008
+ nullCategory: "(미지정)",
917
1009
  },
918
1010
  map: {
919
1011
  searchLocations: "위치 검색…",
@@ -935,8 +1027,8 @@ const ko = {
935
1027
  properties: "속성",
936
1028
  connections: "연결",
937
1029
  quickConnect: "빠른 연결",
938
- fromPlaceholder: "시작...",
939
- toPlaceholder: "종료...",
1030
+ fromPlaceholder: "시작…",
1031
+ toPlaceholder: "종료…",
940
1032
  connect: "연결",
941
1033
  label: "라벨",
942
1034
  type: "유형",
@@ -984,6 +1076,7 @@ const ko = {
984
1076
  },
985
1077
  dashboard: {
986
1078
  noRows: "행 없음",
1079
+ loading: "로딩 중…",
987
1080
  pickMeasures: "이 데이터셋 위젯의 측정값(값)을 선택하세요.",
988
1081
  datasetUnsupported: "이 데이터 소스는 데이터셋 쿼리를 지원하지 않습니다.",
989
1082
  details: "세부 정보",
@@ -1077,7 +1170,7 @@ const ko = {
1077
1170
  faviconUrl: "Favicon URL",
1078
1171
  preview: "미리보기",
1079
1172
  complete: "완료",
1080
- snakeCaseHint: "Must be snake_case (e.g. my_app)",
1173
+ snakeCaseHint: "snake_case 형식이어야 합니다 (예: my_app)",
1081
1174
  modeEdit: "편집",
1082
1175
  modePreview: "미리보기",
1083
1176
  modeCode: "코드",
@@ -1241,6 +1334,7 @@ const ko = {
1241
1334
  },
1242
1335
  },
1243
1336
  console: {
1337
+ saveAdvisoryTitle: "저장되었습니다 — 작성 검사에서 {{count}}건의 권장 사항이 발견되었습니다",
1244
1338
  settingsHub: {
1245
1339
  title: "설정",
1246
1340
  subtitle: "워크스페이스, 연동, 기능 플래그를 구성합니다.",
@@ -1307,7 +1401,7 @@ const ko = {
1307
1401
  shareTitle: "이 대화 공유",
1308
1402
  shareDisabledTitle: "공유하려면 먼저 대화를 시작하세요",
1309
1403
  newChat: "새로 만들기",
1310
- searchChats: "채팅 검색...",
1404
+ searchChats: "채팅 검색…",
1311
1405
  noChatsYet: "아직 채팅이 없습니다",
1312
1406
  noChatsDescription: "새 대화를 시작하면 여기에 표시됩니다.",
1313
1407
  noMatchingChats: "일치하는 채팅이 없습니다.",
@@ -1316,18 +1410,18 @@ const ko = {
1316
1410
  deleteConversation: "대화 삭제",
1317
1411
  saveRename: "이름 저장",
1318
1412
  cancelRename: "이름 변경 취소",
1319
- loadingHistory: "대화 기록을 불러오는 중...",
1413
+ loadingHistory: "대화 기록을 불러오는 중…",
1320
1414
  conversationReady: "대화 준비 완료",
1321
1415
  preparingConversation: "새 대화를 준비하는 중",
1322
1416
  offlineDemoMode: "오프라인 데모 모드 — 에이전트 목록을 사용할 수 없습니다",
1323
1417
  sendFailedRateLimited: "메시지를 너무 빠르게 보내고 있습니다. 메시지는 아래에 보관되어 있습니다 — 잠시 후 다시 시도하세요.",
1324
1418
  sendFailedGeneric: "메시지를 보내지 못했습니다. 아래에 보관되어 있습니다 — 다시 시도해 주세요.",
1325
- askAgent: "{{agent}}에게 질문...",
1419
+ askAgent: "{{agent}}에게 질문…",
1326
1420
  assistant: "어시스턴트",
1327
1421
  liveCanvas: "실시간 미리보기 — {{app}}(초안)",
1328
1422
  liveCanvasUnlisted: "실시간 앱 — {{app}}(게시 전까지 비공개)",
1329
- loadingAgents: "에이전트를 불러오는 중...",
1330
- askAnything: "무엇이든 물어보세요...",
1423
+ loadingAgents: "에이전트를 불러오는 중…",
1424
+ askAnything: "무엇이든 물어보세요…",
1331
1425
  emptyTitle: "대화 시작하기",
1332
1426
  emptyDescription: "무엇이든 물어보세요 — 어시스턴트는 현재 앱 컨텍스트에 접근할 수 있습니다.",
1333
1427
  switchAssistant: "어시스턴트 전환",
@@ -1430,9 +1524,60 @@ const ko = {
1430
1524
  createSeed: "샘플 데이터 생성",
1431
1525
  createPackage: "앱 패키지 생성",
1432
1526
  },
1527
+ // objectui#3546 slice four — the AI console surfaces: the /ai chat page's app switcher,
1528
+ // connection banner and plan/publish cards, the ChatDock chrome, and the
1529
+ // conversation-list date buckets. `group.*` is the template-key family
1530
+ // `console.ai.group.${key}` (ConversationsSidebar), enumerated from the
1531
+ // ConversationGroupKey union — all five members, no wildcard.
1532
+ collapseToDock: "사이드 패널로 접기",
1533
+ switchApp: "앱 전환",
1534
+ switchAppLabel: "앱별 빌드 대화",
1535
+ newApp: "새 앱",
1536
+ connectionWaiting: "서버를 기다리는 중…",
1537
+ connectionStalled: "계속 처리하는 중…",
1538
+ connectionOffline: "연결이 끊어졌습니다 — 다시 연결하는 중…",
1539
+ designingPlan: "앱을 설계하는 중…",
1540
+ designingPlanHint: {
1541
+ data: "추적할 데이터를 정리하는 중…",
1542
+ objects: "객체와 필드를 구성하는 중…",
1543
+ relations: "관련 레코드를 연결하는 중…",
1544
+ lookups: "관계와 조회 필드를 설정하는 중…",
1545
+ views: "화면과 뷰를 계획하는 중…",
1546
+ forms: "양식과 목록을 배치하는 중…",
1547
+ defaults: "합리적인 기본값과 검증을 추가하는 중…",
1548
+ dashboard: "추적용 대시보드를 스케치하는 중…",
1549
+ review: "구조가 잘 맞물리는지 다시 확인하는 중…",
1550
+ finalize: "계획을 정리하는 중…",
1551
+ },
1552
+ planBuilding: "빌드 중…",
1553
+ planBuilt: "빌드 완료",
1554
+ planDeferred: "아직 빌드하지 않음",
1555
+ planReady: "계획이 준비되었습니다. 지금 빌드하거나 조정할 부분을 알려주세요.",
1556
+ published: "게시했습니다",
1557
+ publishFailed: "게시에 실패했습니다",
1558
+ unavailableTitle: "AI 어시스턴트를 사용할 수 없습니다",
1559
+ unavailableDescription: "이 배포에는 AI 어시스턴트가 활성화되어 있지 않습니다. 나머지 기능은 정상적으로 작동합니다.",
1560
+ unavailableError: "AI 서비스에 연결할 수 없습니다. 일시적으로 오프라인일 수 있습니다 — 다시 시도하거나 홈으로 돌아가세요.",
1561
+ unavailableRetry: "다시 시도",
1562
+ unavailableHome: "홈으로 돌아가기",
1563
+ dock: {
1564
+ title: "어시스턴트",
1565
+ description: "AI 어시스턴트 채팅",
1566
+ resize: "채팅 크기 조정",
1567
+ collapse: "채팅 접기",
1568
+ maximize: "전체 페이지로 열기",
1569
+ open: "어시스턴트 열기",
1570
+ },
1571
+ group: {
1572
+ today: "오늘",
1573
+ yesterday: "어제",
1574
+ previous7Days: "지난 7일",
1575
+ previous30Days: "지난 30일",
1576
+ older: "이전",
1577
+ },
1433
1578
  },
1434
1579
  title: "ObjectStack 콘솔",
1435
- initializing: "애플리케이션 초기화 중...",
1580
+ initializing: "애플리케이션 초기화 중…",
1436
1581
  loadingHint: "새 환경을 설정하는 데 시간이 조금 걸릴 수 있습니다.",
1437
1582
  breadcrumb: {
1438
1583
  dashboards: "대시보드",
@@ -1440,6 +1585,31 @@ const ko = {
1440
1585
  reports: "보고서",
1441
1586
  system: "시스템",
1442
1587
  },
1588
+ // objectui#4024 — the single-namespace settings screen. Its sibling
1589
+ // `settingsHub` above already resolved through this pack; the view was the
1590
+ // one file still carrying English literals.
1591
+ settingsView: {
1592
+ backToHub: "전체 설정",
1593
+ back: "뒤로",
1594
+ noNamespace: "선택된 네임스페이스가 없습니다.",
1595
+ loadError: "설정을 불러오지 못했습니다",
1596
+ saved: "설정이 저장되었습니다",
1597
+ saveFailed: "저장에 실패했습니다",
1598
+ lockedByEnv: "환경에 의해 잠김: {{key}}",
1599
+ lockedByEnvNoKey: "환경에 의해 잠김",
1600
+ actionSucceeded: "작업 성공",
1601
+ actionFailed: "작업 실패",
1602
+ discard: "버리기",
1603
+ saveChanges: "변경사항 저장",
1604
+ unsavedCount: "저장되지 않은 변경 {{count}}개",
1605
+ unsavedCount_one: "저장되지 않은 변경 {{count}}개",
1606
+ unsavedCount_other: "저장되지 않은 변경 {{count}}개",
1607
+ cryptoRefusalTitle: "이 배포는 시크릿을 암호화할 수 없습니다",
1608
+ cryptoRefusalSubjectSuffix: "은(는) 암호화 대상으로 선언되어 아무것도 기록되지 않았습니다.",
1609
+ cryptoRefusalNoSubject: "암호화 대상으로 선언된 값이 거부되어 아무것도 기록되지 않았습니다.",
1610
+ cryptoRefusalToast: "시크릿을 암호화할 수 없습니다: {{subject}}",
1611
+ cryptoRefusalToastNoSubject: "시크릿을 암호화할 수 없습니다",
1612
+ },
1443
1613
  loadingSteps: {
1444
1614
  connecting: "데이터 소스에 연결 중",
1445
1615
  loadingConfig: "설정 로드 중",
@@ -1469,6 +1639,7 @@ const ko = {
1469
1639
  general: "일반",
1470
1640
  navigation: "탐색",
1471
1641
  dataViews: "데이터 뷰",
1642
+ aiChat: "AI 어시스턴트",
1472
1643
  preferences: "환경설정",
1473
1644
  },
1474
1645
  openCommandPalette: "명령 팔레트 열기",
@@ -1479,11 +1650,13 @@ const ko = {
1479
1650
  createRecord: "새 레코드 생성",
1480
1651
  refreshData: "데이터 새로고침",
1481
1652
  editRecord: "선택한 레코드 편집",
1653
+ newChat: "새 채팅",
1654
+ toggleChatsList: "채팅 목록 전환",
1482
1655
  toggleDarkMode: "다크 모드 전환",
1483
1656
  },
1484
1657
  commandPalette: {
1485
1658
  title: "명령 팔레트",
1486
- placeholder: "명령어를 입력하거나 검색...",
1659
+ placeholder: "명령어를 입력하거나 검색…",
1487
1660
  noResults: "결과를 찾을 수 없습니다.",
1488
1661
  objects: "객체",
1489
1662
  dashboards: "대시보드",
@@ -1509,6 +1682,12 @@ const ko = {
1509
1682
  goHome: "홈으로 이동",
1510
1683
  errorDetails: "오류 상세정보 (개발 모드 전용)",
1511
1684
  },
1685
+ // objectui#3546 slice four — the console's catch-all route (AppContent `RouteNotFound`).
1686
+ notFound: {
1687
+ title: "페이지를 찾을 수 없습니다",
1688
+ description: "접속한 URL이 이 앱의 어떤 뷰와도 일치하지 않습니다.",
1689
+ back: "뒤로",
1690
+ },
1512
1691
  theme: {
1513
1692
  toggle: "테마 전환",
1514
1693
  light: "라이트",
@@ -1524,8 +1703,10 @@ const ko = {
1524
1703
  viewNameHelp: "머신 키(snake_case)입니다. 제목에서 자동으로 채워집니다 — 원하면 수정하세요.",
1525
1704
  viewNameRequired: "키를 입력하세요(소문자, 숫자, 밑줄). 비라틴 문자 제목에서는 자동으로 채워지지 않습니다.",
1526
1705
  viewNameInvalid: "소문자, 숫자, 밑줄을 사용하고 문자 또는 밑줄로 시작하세요.",
1527
- systemViewReadonly: 'System view defined in code - duplicate to customize.',
1528
- expandToPage: 'Open as full page',
1706
+ systemViewReadonly: "시스템 보기는 코드에 정의되어 있어 읽기 전용입니다.",
1707
+ cannotEditMetaView: "이 보기는 코드에 정의된 기본 제공 보기이므로 변경할 수 없습니다.",
1708
+ cannotDeleteMetaView: "이 보기는 코드에 정의된 기본 제공 보기이므로 삭제할 수 없습니다.",
1709
+ expandToPage: "전체 페이지로 열기",
1529
1710
  objectNotFound: "객체를 찾을 수 없음",
1530
1711
  objectNotFoundDescription: "객체 \"{{objectName}}\"이(가) 현재 구성에 존재하지 않습니다.",
1531
1712
  objectNotFoundHint: "앱 탐색 설정을 확인하거나 사이드바에서 다른 객체를 선택하세요.",
@@ -1557,7 +1738,7 @@ const ko = {
1557
1738
  exportPrintHint: "내보내기 형식, 인쇄 및 레코드 수 표시",
1558
1739
  showAllFields: "모두 표시",
1559
1740
  hideAllFields: "모두 숨기기",
1560
- searchFields: "필드 검색...",
1741
+ searchFields: "필드 검색…",
1561
1742
  title: "제목",
1562
1743
  description: "설명",
1563
1744
  data: "데이터",
@@ -1596,7 +1777,7 @@ const ko = {
1596
1777
  longitudeField: "경도 필드",
1597
1778
  imageField: "이미지 필드",
1598
1779
  dateField: "날짜 필드",
1599
- selectField: "필드 선택...",
1780
+ selectField: "필드 선택…",
1600
1781
  gridOptionsHint: "그리드 뷰는 위에서 구성된 열을 사용합니다.",
1601
1782
  groupBy: "그룹화 기준",
1602
1783
  prefixField: "접두사 필드",
@@ -1659,7 +1840,7 @@ const ko = {
1659
1840
  latitudeFieldHelp: "위도를 포함하는 필드 (지리 필드만 해당).",
1660
1841
  longitudeFieldHelp: "경도를 포함하는 필드 (지리 필드만 해당).",
1661
1842
  imageFieldHelp: "갤러리 표지는 이 이미지 또는 첨부 파일 필드에서 가져옵니다.",
1662
- selectOption: "선택...",
1843
+ selectOption: "선택…",
1663
1844
  noEligibleFieldForType: "해당 유형의 적합한 필드가 없습니다. 먼저 개체에 추가하세요.",
1664
1845
  viewTypeUnavailable: "이 개체에는 \"{{field}}\"로 사용할 수 있는 필드가 없습니다.",
1665
1846
  viewTypeUnavailableShort: "이 개체에서 지원되지 않습니다.",
@@ -1709,7 +1890,7 @@ const ko = {
1709
1890
  ufDropdown: "드롭다운",
1710
1891
  ufTabs: "탭",
1711
1892
  ufToggle: "토글",
1712
- ufAddField: "+ 필터 필드 추가...",
1893
+ ufAddField: "+ 필터 필드 추가…",
1713
1894
  ufNoFields: "사용 가능한 필드 없음",
1714
1895
  ufAddTab: "+ 탭 추가",
1715
1896
  ufTabLabel: "레이블",
@@ -1769,7 +1950,7 @@ const ko = {
1769
1950
  passwordPlaceholder: "비밀번호를 입력하세요",
1770
1951
  forgotPasswordText: "비밀번호를 잊으셨나요?",
1771
1952
  submitButton: "로그인",
1772
- submittingButton: "로그인 중...",
1953
+ submittingButton: "로그인 중…",
1773
1954
  noAccountText: "계정이 없으신가요?",
1774
1955
  signUpText: "회원가입",
1775
1956
  errors: {
@@ -1777,6 +1958,18 @@ const ko = {
1777
1958
  invalidCredentials: "잘못된 이메일 또는 비밀번호입니다. 다시 시도하세요.",
1778
1959
  emailNotVerified: "로그인하기 전에 이메일을 확인하세요.",
1779
1960
  },
1961
+ // objectui#3546 slice three — phone/OTP sign-in. `{seconds}` is LoginForm's own
1962
+ // literal `.replace()` hole, not i18next interpolation: keep the single braces.
1963
+ emailOrPhoneLabel: "이메일 또는 전화번호",
1964
+ emailOrPhonePlaceholder: "name@example.com 또는 +1 555 000 0000",
1965
+ phoneLabel: "전화번호",
1966
+ phonePlaceholder: "+1 555 000 0000",
1967
+ otpCodeLabel: "인증 코드",
1968
+ otpCodePlaceholder: "6자리 코드",
1969
+ sendOtpButton: "코드 받기",
1970
+ resendOtpCountdownText: "{seconds}초 후 재전송",
1971
+ usePhoneOtpText: "인증 코드로 로그인",
1972
+ usePasswordSignInText: "비밀번호로 로그인하기",
1780
1973
  },
1781
1974
  register: {
1782
1975
  title: "계정 만들기",
@@ -1792,7 +1985,7 @@ const ko = {
1792
1985
  passwordMismatchError: "비밀번호가 일치하지 않습니다",
1793
1986
  passwordTooShortError: "비밀번호는 최소 8자 이상이어야 합니다",
1794
1987
  submitButton: "계정 만들기",
1795
- submittingButton: "계정 생성 중...",
1988
+ submittingButton: "계정 생성 중…",
1796
1989
  hasAccountText: "이미 계정이 있으신가요?",
1797
1990
  signInText: "로그인",
1798
1991
  errors: {
@@ -1813,12 +2006,26 @@ const ko = {
1813
2006
  emailLabel: "이메일",
1814
2007
  emailPlaceholder: "name@example.com",
1815
2008
  submitButton: "재설정 링크 보내기",
1816
- submittingButton: "전송 중...",
2009
+ submittingButton: "전송 중…",
1817
2010
  successTitle: "이메일을 확인하세요",
1818
2011
  successDescription: "{{email}}(으)로 비밀번호 재설정 링크를 전송했습니다. 수신함을 확인해주세요.",
1819
2012
  backToSignInText: "로그인으로 돌아가기",
1820
2013
  rememberPasswordText: "비밀번호가 기억나시나요?",
1821
2014
  signInText: "로그인",
2015
+ // objectui#3546 slice three — the SMS reset branch of the same form.
2016
+ phoneLabel: "전화번호",
2017
+ phonePlaceholder: "+1 555 000 0000",
2018
+ otpCodeLabel: "인증 코드",
2019
+ otpCodePlaceholder: "6자리 코드",
2020
+ sendOtpButton: "코드 받기",
2021
+ resendOtpCountdownText: "{seconds}초 후 재전송",
2022
+ newPasswordLabel: "새 비밀번호",
2023
+ newPasswordPlaceholder: "새 비밀번호를 입력하세요",
2024
+ resetButton: "비밀번호 재설정",
2025
+ usePhoneResetText: "SMS 코드로 재설정",
2026
+ useEmailResetText: "이메일로 재설정하기",
2027
+ phoneSuccessTitle: "비밀번호가 재설정되었습니다",
2028
+ phoneSuccessDescription: "비밀번호가 재설정되었습니다. 이제 새 비밀번호로 로그인할 수 있습니다.",
1822
2029
  },
1823
2030
  resetPassword: {
1824
2031
  title: "새 비밀번호 설정",
@@ -1857,6 +2064,8 @@ const ko = {
1857
2064
  backToLogin: "로그인으로 돌아가기",
1858
2065
  checkSpam: "이메일을 받지 못하셨나요? 스팸 폴더를 확인하거나 지원팀에 문의하세요.",
1859
2066
  or: "또는",
2067
+ // objectui#3546 slice three.
2068
+ resendUnavailable: "이 환경에서는 이메일 발송이 구성되지 않았을 수 있습니다. 문제가 계속되면 지원팀에 문의하세요.",
1860
2069
  },
1861
2070
  setup: {
1862
2071
  welcomeTitle: "ObjectStack에 오신 것을 환영합니다",
@@ -1895,6 +2104,9 @@ const ko = {
1895
2104
  invalidDescription: "URL에 장치 코드가 제공되지 않았습니다.",
1896
2105
  loading: "로딩 중…",
1897
2106
  cancel: "취소",
2107
+ // objectui#3546 slice three — device-authorization plugin switched off.
2108
+ disabledTitle: "장치 승인이 활성화되지 않았습니다",
2109
+ disabledDescription: "이 배포에는 장치 승인이 활성화되어 있지 않으므로 여기에서 이 장치를 승인할 수 없습니다.",
1898
2110
  },
1899
2111
  shell: {
1900
2112
  tenantHostHint: "이 작업 공간에 로그인하는 중입니다",
@@ -1934,6 +2146,29 @@ const ko = {
1934
2146
  },
1935
2147
  },
1936
2148
  },
2149
+ // objectui#3546 slice three — the /oauth/consent screen.
2150
+ oauth: {
2151
+ consent: {
2152
+ title: "{{appName}}이(가) 계정에 액세스하려고 합니다",
2153
+ request: "{{appName}}이(가) 권한을 요청합니다{{suffix}}.",
2154
+ unknownApp: "어떤 애플리케이션",
2155
+ willAllow: "이 앱은 다음을 할 수 있습니다:",
2156
+ scope: {
2157
+ openid: "본인 확인",
2158
+ profile: "기본 프로필(이름, 사진) 읽기",
2159
+ email: "이메일 주소 읽기",
2160
+ offlineAccess: "로그인 상태 유지(액세스 갱신)",
2161
+ },
2162
+ deny: "거부",
2163
+ authorize: "허용",
2164
+ submitting: "허용 중…",
2165
+ granted: "액세스가 허용되었습니다",
2166
+ denied: "액세스 거부됨",
2167
+ noRedirect: "서버가 리디렉션 URL을 반환하지 않았습니다.",
2168
+ failed: "동의 실패",
2169
+ footer: "계정 설정에서 언제든지 액세스를 취소할 수 있습니다.",
2170
+ },
2171
+ },
1937
2172
  profile: {
1938
2173
  title: "프로필",
1939
2174
  subtitle: "계정 설정을 관리하세요",
@@ -1995,6 +2230,8 @@ const ko = {
1995
2230
  invite: "구성원 초대",
1996
2231
  members: "구성원",
1997
2232
  settings: "워크스페이스 설정",
2233
+ multiOrgDisabled: "이 인스턴스에서는 새 조직을 만들 수 없습니다.",
2234
+ createFailed: '워크스페이스를 만들지 못했습니다',
1998
2235
  },
1999
2236
  help: {
2000
2237
  onThisPage: "이 페이지에서",
@@ -2005,7 +2242,7 @@ const ko = {
2005
2242
  },
2006
2243
  sidebar: {
2007
2244
  packageManagement: "패키지 관리",
2008
- searchNavigation: "내비게이션 검색...",
2245
+ searchNavigation: "내비게이션 검색…",
2009
2246
  settings: "설정",
2010
2247
  help: "도움말",
2011
2248
  helpTooltip: "도움말 및 문서",
@@ -2029,8 +2266,8 @@ const ko = {
2029
2266
  switchObject: "객체 전환",
2030
2267
  connection: {
2031
2268
  connected: "연결됨",
2032
- connecting: "연결 중...",
2033
- reconnecting: "다시 연결 중...",
2269
+ connecting: "연결 중…",
2270
+ reconnecting: "다시 연결 중…",
2034
2271
  disconnected: "연결 끊김",
2035
2272
  error: "연결 오류",
2036
2273
  },
@@ -2069,6 +2306,13 @@ const ko = {
2069
2306
  publishing: "게시하는 중…",
2070
2307
  published: "게시했습니다! 변경 사항이 반영되었습니다.",
2071
2308
  publishFailed: "게시에 실패했습니다",
2309
+ // objectui#3546 slice six — seedWarn 은 console.ai.seedWarn 과 영문이 같아
2310
+ // 기존 번역을 그대로 재사용.
2311
+ nothing: "게시할 내용이 없습니다.",
2312
+ probeWarn: "게시했지만 검증에서 문제를 발견했습니다.",
2313
+ seedWarn: "게시했지만 일부 샘플 데이터를 불러오지 못했습니다.",
2314
+ publishedVerified: "게시 및 검증 완료 — 샘플 데이터 {{count}}개 행이 반영되었습니다.",
2315
+ capabilityWarn: "작성 검사: 기능 권한 참조 {{count}}개가 아무것도 가리키지 않습니다.",
2072
2316
  },
2073
2317
  title: "홈",
2074
2318
  subtitle: "워크스페이스 대시보드",
@@ -2082,7 +2326,7 @@ const ko = {
2082
2326
  title: "확인이 필요한 항목",
2083
2327
  empty: "모두 처리했습니다",
2084
2328
  },
2085
- loading: "워크스페이스 로드 중...",
2329
+ loading: "워크스페이스 로드 중…",
2086
2330
  recent: "최근",
2087
2331
  starred: "즐겨찾기",
2088
2332
  welcome: "ObjectUI에 오신 것을 환영합니다",
@@ -2143,6 +2387,9 @@ const ko = {
2143
2387
  roles: "역할",
2144
2388
  configuration: "구성",
2145
2389
  createApp: "앱 만들기",
2390
+ administration: "관리",
2391
+ datasources: "데이터 소스",
2392
+ documentation: "문서",
2146
2393
  },
2147
2394
  appSwitcher: {
2148
2395
  switchApplication: "애플리케이션 전환",
@@ -2182,7 +2429,7 @@ const ko = {
2182
2429
  search: {
2183
2430
  title: "검색",
2184
2431
  back: "뒤로",
2185
- placeholder: "오브젝트, 대시보드, 페이지, 보고서 검색...",
2432
+ placeholder: "오브젝트, 대시보드, 페이지, 보고서 검색…",
2186
2433
  inputAriaLabel: "오브젝트, 대시보드, 페이지, 보고서 검색",
2187
2434
  resultsCount: "\"{{query}}\"에 대한 {{count}}개 결과",
2188
2435
  resultsCountPlural: "\"{{query}}\"에 대한 {{count}}개 결과",
@@ -2201,6 +2448,7 @@ const ko = {
2201
2448
  empty: {
2202
2449
  objectNotFound: "오브젝트를 찾을 수 없습니다",
2203
2450
  objectNotFoundDescription: "\"{{name}}\" 오브젝트 정의가 없습니다. 구성을 확인하거나 뒤로 이동하세요.",
2451
+ interfacePageSourceMissing: "이 인터페이스 페이지는 \"{{name}}\"을(를) 참조하지만 사용할 수 없습니다.",
2204
2452
  pageNotFound: "페이지를 찾을 수 없습니다",
2205
2453
  pageNotFoundDescription: "\"{{name}}\" 페이지를 찾을 수 없습니다. 삭제되거나 이름이 변경되었을 수 있습니다.",
2206
2454
  dashboardNotFound: "대시보드를 찾을 수 없습니다",
@@ -2209,6 +2457,11 @@ const ko = {
2209
2457
  reportNotFoundDescription: "\"{{name}}\" 보고서를 찾을 수 없습니다. 삭제되거나 이름이 변경되었을 수 있습니다.",
2210
2458
  noAppsConfigured: "구성된 앱 없음",
2211
2459
  noAppsConfiguredDescription: "등록된 앱이 없습니다. 첫 번째 앱을 만들거나 시스템 설정을 방문하세요.",
2460
+ appNotAvailable: "앱을 사용할 수 없습니다",
2461
+ appNotAvailableDescription: "이 앱을 아직 사용할 수 없습니다 — 아직 게시 중일 수 있습니다. 잠시 후 다시 시도하세요.",
2462
+ appAccessDenied: "이 앱에 접근할 권한이 없습니다",
2463
+ appAccessDeniedDescription: "이 앱은 존재하지만 계정에 여는 권한이 없습니다. 관리자에게 접근 권한을 요청하세요.",
2464
+ appAccessDeniedHome: "홈으로 돌아가기",
2212
2465
  createFirstApp: "첫 번째 앱 만들기",
2213
2466
  systemSettings: "시스템 설정",
2214
2467
  back: "뒤로",
@@ -2280,7 +2533,7 @@ const ko = {
2280
2533
  deleteFailed: "보기 삭제 실패",
2281
2534
  },
2282
2535
  dashboardActions: {
2283
- pdfPreparing: "PDF 내보내기 준비 중…",
2536
+ printDialogOpening: "브라우저의 인쇄 대화 상자를 여는 중입니다(PDF 내보내기가 아닙니다)",
2284
2537
  exportFailed: "내보내기 실패: {{message}}",
2285
2538
  forecastSoon: "예측 보기가 곧 출시됩니다",
2286
2539
  },
@@ -2324,111 +2577,7 @@ const ko = {
2324
2577
  first: "첫 번째",
2325
2578
  },
2326
2579
  editor: {
2327
- breadcrumb: "구성",
2328
- basic: "기본",
2329
- title: "제목",
2330
- titlePlaceholder: "예: 분기별 파이프라인",
2331
- description: "설명",
2332
- descriptionPlaceholder: "이 보고서가 무엇을 보여주나요?",
2333
- type: "보고서 유형",
2334
- typeTabular: "표 — 평면 목록",
2335
- typeSummary: "요약 — 합계 포함 그룹화",
2336
- typeMatrix: "매트릭스 — 행 × 열 피벗",
2337
- typeJoined: "결합 — 여러 블록",
2338
- typeHelp: "보고 싶은 형태에 맞는 레이아웃을 선택하세요.",
2339
- data: "데이터",
2340
- objectName: "데이터 소스",
2341
- objectNamePlaceholder: "예: opportunity",
2342
- objectNameHelp: "이 보고서가 조회할 객체는 무엇인가요?",
2343
- limit: "행 수 제한",
2344
- limitPlaceholder: "예: 100",
2345
- columns: "열",
2346
- columnsHint: "열로 표시할 필드를 선택하세요. 요약 또는 매트릭스 보고서에서는 집계(합계, 개수…)를 추가할 수 있습니다.",
2347
- filters: "필터",
2348
- filtersHint: "이 보고서에 포함되는 행을 제한합니다.",
2349
- filtersComplex: "이 보고서는 여기서 편집할 수 없는 고급 필터를 사용합니다. 저장 시 그대로 유지됩니다.",
2350
- groupBy: "그룹화 기준",
2351
- groupByHint: "데이터를 그룹화하고 소계를 계산합니다.",
2352
- rows: "행",
2353
- rowsHint: "이 필드들로 행을 그룹화합니다.",
2354
- columnsAxis: "열",
2355
- columnsAxisHint: "이 필드들을 상단에 피벗합니다.",
2356
- values: "값",
2357
- valuesHint: "각 셀에 표시되는 숫자입니다. 하나 이상의 필드를 선택하고 집계(합계, 개수…)를 지정하세요.",
2358
- grouping: "그룹화",
2359
- addGrouping: "그룹화 추가",
2360
- dateGranularity: "날짜 단위",
2361
- dateGranularityNone: "(원래 값 사용)",
2362
- day: "일",
2363
- week: "주",
2364
- month: "월",
2365
- quarter: "분기",
2366
- year: "연도",
2367
- sortAsc: "오름차순",
2368
- sortDesc: "내림차순",
2369
- chart: "차트",
2370
- chartHint: "표 옆에 표시되는 선택 시각화입니다.",
2371
- chartType: "차트 유형",
2372
- chartTitle: "차트 제목",
2373
- chartTitlePlaceholder: "기본값은 보고서 제목",
2374
- chartXAxis: "X축 (범주)",
2375
- chartYAxis: "Y축 (값)",
2376
- chartShowLegend: "범례 표시",
2377
- chartShowDataLabels: "데이터 레이블 표시",
2378
- chartNone: "(차트 없음)",
2379
- chartBar: "막대",
2380
- chartLine: "선",
2381
- chartArea: "영역",
2382
- chartPie: "원형",
2383
- chartDonut: "도넛",
2384
- chartFunnel: "퍼널",
2385
- validationNeedsObject: "열을 추가하기 전에 데이터 소스를 선택하세요.",
2386
- validationMatrixNeedsRowsCols: "매트릭스 보고서에는 최소 한 개의 행과 한 개의 열이 필요합니다.",
2387
- validationSummaryNeedsRows: "요약 보고서에는 최소 한 개의 그룹화 필드가 필요합니다.",
2388
- blocks: "블록",
2389
- blocksHint: "각 블록은 독립적인 표 또는 차트입니다. 블록 필터는 보고서 필터와 AND로 결합됩니다.",
2390
- addBlock: "블록 추가",
2391
- removeBlock: "블록 삭제",
2392
- blockName: "블록 이름",
2393
- blockNamePlaceholder: "고유한_블록_이름",
2394
- blockLabel: "표시 레이블",
2395
- blockLabelPlaceholder: "블록 위에 표시됩니다",
2396
- blockDescription: "설명",
2397
- blockDescriptionPlaceholder: "이 블록의 선택적 설명",
2398
- validationJoinedNeedsBlocks: "결합 보고서에는 최소 한 개의 블록이 필요합니다.",
2399
- validationBlockNameRequired: "각 블록에는 비어 있지 않은 이름이 필요합니다.",
2400
- validationBlockNameDuplicate: "블록 이름은 보고서 내에서 고유해야 합니다.",
2401
- validationBlockNeedsColumns: "각 블록에는 최소 한 개의 열이 필요합니다.",
2402
- noneOption: "(없음)",
2403
- addCondition: "조건 추가",
2404
- combineLogic: "결합 방식",
2405
- opContains: "포함",
2406
- opIsEmpty: "비어 있음",
2407
- opIsNotEmpty: "비어 있지 않음",
2408
- formatAuto: "자동",
2409
- formatCurrency: "통화",
2410
- formatPercent: "백분율",
2411
- formatInteger: "정수",
2412
- formatDate: "날짜",
2413
- formatDatetime: "날짜 및 시간",
2414
- columnLabelPlaceholder: "레이블 재정의",
2415
- aggregateColumn: "집계",
2416
- formatColumn: "형식",
2417
- addColumns: "열 추가",
2418
- searchFields: "필드 검색…",
2419
- noMatchingFields: "검색과 일치하는 필드가 없습니다.",
2420
- noFieldsAvailable: "사용 가능한 필드가 없습니다.",
2421
- columnsCount: "{n}개 열 선택됨",
2422
- columnsEmpty: "아직 선택된 열이 없습니다.",
2423
- fieldPickerTitle: "필드 선택",
2424
- fieldPickerDescription: "추가할 필드를 하나 이상 선택하세요. 검색 필드를 사용하여 목록을 필터링하세요.",
2425
- fieldPickerChangeTitle: "필드 변경",
2426
- fieldPickerAddGroupingTitle: "그룹화 추가",
2427
- fieldPickerEmpty: "(필드 선택)",
2428
- fieldPickerSelected: "{n}개 선택됨",
2429
- fieldPickerClear: "선택 지우기",
2430
- fieldPickerAdd: "추가",
2431
- fieldPickerAddN: "{n}개 추가",
2580
+ panelTitle: "보고서 편집",
2432
2581
  },
2433
2582
  },
2434
2583
  organizations: {
@@ -2445,6 +2594,140 @@ const ko = {
2445
2594
  emptyDescription: "시작하려면 첫 번째 조직을 만드세요.",
2446
2595
  noMatches: "검색과 일치하는 조직이 없습니다.",
2447
2596
  },
2597
+ organization: {
2598
+ roles: {
2599
+ owner: '소유자',
2600
+ admin: '관리자',
2601
+ delegatedAdmin: '위임 관리자',
2602
+ member: '멤버',
2603
+ },
2604
+ errors: {
2605
+ notAllowedToInvite: '이 조직에 사용자를 초대할 권한이 없습니다.',
2606
+ notAllowedToInviteWithRole: '이 역할로 사용자를 초대할 권한이 없습니다.',
2607
+ alreadyInvited: '이 사용자는 이미 이 조직에 초대되었습니다.',
2608
+ organizationExists: '해당 조직이 이미 존재합니다.',
2609
+ slugTaken: '해당 슬러그는 이미 사용 중입니다.',
2610
+ notAllowedToCreate: '새 조직을 만들 권한이 없습니다.',
2611
+ notTheRecipient: '이 초대의 수신자가 아닙니다.',
2612
+ invitationNotFound: '이 초대는 더 이상 존재하지 않거나 만료되었습니다.',
2613
+ unknown: '문제가 발생했습니다. 다시 시도해 주세요.',
2614
+ },
2615
+ backToList: "조직 목록으로 돌아가기",
2616
+ notFound: "조직을 찾을 수 없음",
2617
+ notFoundDescription: "이 조직이 존재하지 않거나 접근 권한이 없습니다.",
2618
+ tabs: {
2619
+ members: "구성원",
2620
+ invitations: "초대",
2621
+ settings: "설정",
2622
+ },
2623
+ members: {
2624
+ title: "구성원",
2625
+ inviteMember: "구성원 초대",
2626
+ inviteRestrictedNote: "조직 관리자만 구성원을 초대할 수 있습니다.",
2627
+ removeMember: "구성원 제거",
2628
+ removeConfirmTitle: "구성원을 제거할까요?",
2629
+ removeConfirmDescription: "{{name}}을(를) 조직에서 제거합니다. 접근 권한이 즉시 사라집니다.",
2630
+ removeConfirmAction: "제거",
2631
+ memberRemoved: "구성원이 제거됨",
2632
+ removeFailed: "구성원 제거 실패",
2633
+ roleUpdated: "역할이 업데이트됨",
2634
+ roleUpdateFailed: "역할 업데이트 실패",
2635
+ memberActions: '멤버 작업',
2636
+ loadFailed: '멤버를 불러오지 못했습니다',
2637
+ },
2638
+ invitations: {
2639
+ title: "초대",
2640
+ empty: "초대가 없습니다.",
2641
+ expiresAt: "만료",
2642
+ linkCopied: "초대 링크가 복사됨",
2643
+ copyFailed: "링크 복사 실패",
2644
+ canceled: "초대가 취소됨",
2645
+ cancelFailed: "초대 취소 실패",
2646
+ cancelTitle: "초대를 취소할까요?",
2647
+ cancelDescription: "{{email}}에 대한 초대가 철회됩니다.",
2648
+ cancelAction: "초대 취소",
2649
+ inviteTitle: "구성원 초대",
2650
+ inviteDescription: "이 조직에 참여하라는 초대를 받게 됩니다.",
2651
+ emailLabel: "이메일",
2652
+ roleLabel: "역할",
2653
+ placementLabel: "배치(선택 사항)",
2654
+ placementDescription: "초대를 수락하면 적용됩니다. 위임할 수 있는 단위와 직위만 표시됩니다.",
2655
+ businessUnitLabel: "사업 단위",
2656
+ businessUnitPlaceholder: "배치 없음",
2657
+ positionsLabel: "직위",
2658
+ sendInvite: "초대 보내기",
2659
+ sentTitle: "초대가 생성됨",
2660
+ sentDescription: "아래 링크를 초대 대상자와 공유하세요. 수락하려면 로그인해야 합니다.",
2661
+ linkLabel: "수락 링크",
2662
+ invitedAs: "{{email}}을(를) {{role}}(으)로 초대함",
2663
+ copyLinkLabel: '초대 링크 복사',
2664
+ loadFailed: '초대를 불러오지 못했습니다',
2665
+ inviteFailed: '멤버를 초대하지 못했습니다',
2666
+ status: {
2667
+ all: "전체",
2668
+ pending: "대기 중",
2669
+ accepted: "수락됨",
2670
+ rejected: "거절됨",
2671
+ canceled: "취소됨",
2672
+ },
2673
+ },
2674
+ settings: {
2675
+ generalTitle: "일반",
2676
+ generalDescription: "조직 정보를 업데이트하세요.",
2677
+ readOnlyNote: "소유자만 설정을 변경할 수 있습니다.",
2678
+ nameLabel: "조직 이름",
2679
+ slugLabel: "슬러그",
2680
+ logoLabel: "로고",
2681
+ logoUpload: "업로드",
2682
+ logoReplace: "변경",
2683
+ logoClear: "제거",
2684
+ logoUploaded: "로고가 업로드됨 — 저장해야 적용됩니다",
2685
+ logoUploadFailed: "로고 업로드 실패",
2686
+ save: "변경사항 저장",
2687
+ saved: "설정이 저장됨",
2688
+ saveFailed: "설정 저장 실패",
2689
+ leaveTitle: "조직 나가기",
2690
+ leaveDescription: "이 조직에 대한 접근 권한을 잃게 됩니다.",
2691
+ leaveAction: "나가기",
2692
+ leaveConfirmTitle: "조직에서 나갈까요?",
2693
+ leaveConfirmDescription: "{{name}}에서 나가시겠습니까? 접근 권한이 즉시 사라집니다.",
2694
+ leaveConfirmAction: "나가기",
2695
+ leftOrg: "조직에서 나갔습니다",
2696
+ leaveFailed: "조직 나가기 실패",
2697
+ dangerZone: "위험 구역",
2698
+ deleteTitle: "조직 삭제",
2699
+ deleteDescription: "이 조직과 모든 데이터를 영구적으로 삭제합니다.",
2700
+ deleteAction: "삭제",
2701
+ deleteConfirmTitle: "조직을 삭제할까요?",
2702
+ deleteConfirmDescription: "이 작업은 되돌릴 수 없습니다. 모든 데이터가 영구적으로 삭제됩니다. 확인하려면 조직 슬러그를 입력하세요.",
2703
+ deleteConfirmSlugLabel: "확인하려면 “{{slug}}”을(를) 입력하세요",
2704
+ deleteConfirmAction: "조직 삭제",
2705
+ deleted: "조직이 삭제됨",
2706
+ deleteFailed: "조직 삭제 실패",
2707
+ },
2708
+ accept: {
2709
+ title: "초대를 받았습니다",
2710
+ description: "{{orgName}}에 {{role}}(으)로 초대되었습니다.",
2711
+ errorTitle: "초대를 사용할 수 없음",
2712
+ goToOrgs: "조직 목록으로 이동",
2713
+ loading: "초대를 불러오는 중…",
2714
+ organization: "조직",
2715
+ role: "역할",
2716
+ expiresAt: "만료",
2717
+ accept: "초대 수락",
2718
+ accepted: "초대를 수락함",
2719
+ acceptFailed: "초대 수락 실패",
2720
+ decline: "거절",
2721
+ declined: "초대를 거절함",
2722
+ declineFailed: "초대 거절 실패",
2723
+ },
2724
+ switcher: {
2725
+ label: "조직 전환",
2726
+ groupLabel: "작업 중인 조직",
2727
+ groupHint: "새 레코드는 여기에 생성됩니다. 보기에는 모든 조직의 데이터가 표시됩니다.",
2728
+ manageMembers: "구성원 관리",
2729
+ },
2730
+ },
2448
2731
  notifications: {
2449
2732
  regionLabel: "알림",
2450
2733
  groupCount: "알림 {{count}}건",
@@ -2458,6 +2741,9 @@ const ko = {
2458
2741
  viewApprovals: "승인 보기",
2459
2742
  noPendingApprovals: "대기 중인 승인 없음",
2460
2743
  openApprovalsInbox: "승인 보관함 열기",
2744
+ badgeTotal: "총 {{total}}건",
2745
+ badgeNotifications: "알림 {{unread}}건",
2746
+ badgeApprovals: "승인 대기 {{approvals}}건",
2461
2747
  emptyUnread: "모두 읽음",
2462
2748
  filterUnread: "읽지 않음",
2463
2749
  filterAll: "전체",
@@ -2744,6 +3030,7 @@ const ko = {
2744
3030
  dismiss: "닫기",
2745
3031
  openOnCloud: "클라우드에서 열기",
2746
3032
  backHome: "홈으로 돌아가기",
3033
+ updateTo: "업데이트",
2747
3034
  },
2748
3035
  install: {
2749
3036
  dialogTitle: "{{name}} 설치",
@@ -2760,6 +3047,37 @@ const ko = {
2760
3047
  localManifestConflict: "{{message}}\n참고: 로컬 앱이 이미 이 manifest_id를 가지고 있습니다. 먼저 objectstack.config.ts에서 제거하세요.",
2761
3048
  localUnauthorized: "먼저 이 런타임에 로그인하세요.",
2762
3049
  localMarketplaceUnavailable: "이 런타임에 OS_CLOUD_URL이 구성되지 않았습니다.",
3050
+ updateTo: "업데이트 → v{{version}}",
3051
+ installedVersion: "v{{version}} 설치됨",
3052
+ },
3053
+ // objectui#3546 — the MarketplacePage "Your organization" strip.
3054
+ org: {
3055
+ heading: "조직",
3056
+ install: "설치",
3057
+ installed: "{{name}} 설치됨",
3058
+ installedBadge: "설치됨",
3059
+ installing: "설치 중…",
3060
+ },
3061
+ // ADR-0025 PD4 §3.5/§3.11 — the pre-install consent panel
3062
+ // (PluginDisclosure.tsx). `runtime` is a CLOSED enum: spec
3063
+ // PluginRuntimeSchema = z.enum(['node', 'sandbox', 'worker']).
3064
+ disclosure: {
3065
+ containsCode: "이 패키지에는 코드가 포함되어 있습니다",
3066
+ reviewed: "검토 및 승인됨",
3067
+ unreviewed: "아직 검토되지 않음",
3068
+ signed: "서명됨",
3069
+ grantsIntro: "설치하면 이 패키지에 다음 권한이 부여됩니다:",
3070
+ services: "플랫폼 서비스",
3071
+ hooks: "라이프사이클 후크",
3072
+ network: "네트워크 액세스",
3073
+ fs: "파일 시스템 액세스",
3074
+ noPermissions: "특별한 권한을 요청하지 않습니다.",
3075
+ acknowledge: "이 패키지가 코드를 실행하고 위 권한을 부여받는다는 점을 이해합니다.",
3076
+ runtime: {
3077
+ node: "프로세스 내 · 완전 신뢰",
3078
+ sandbox: "샌드박스",
3079
+ worker: "프로세스 외부",
3080
+ },
2763
3081
  },
2764
3082
  uninstall: {
2765
3083
  confirm: "이 런타임에서 {{manifestId}} v{{version}}을(를) 제거하시겠습니까?\n\n캐시된 매니페스트가 삭제됩니다.",
@@ -3009,6 +3327,34 @@ const ko = {
3009
3327
  confirmNote: '게시하면 이 패키지의 대기 중인 초안 {{count}}개가 한 번에(원자적으로) 게시됩니다.',
3010
3328
  publishConfirm: '모두 게시',
3011
3329
  },
3330
+ // ADR-0045 — the materialized-but-unlisted app banner
3331
+ // (UnpublishedAppBar.tsx), sibling of draftBar above.
3332
+ unpublishedBar: {
3333
+ message: '게시되지 않은 앱 — 기능은 모두 작동하지만 빌더만 볼 수 있습니다. 게시하면 사용자에게 표시됩니다.',
3334
+ publish: '게시',
3335
+ publishing: '게시 중…',
3336
+ published: '게시했습니다! 이제 사용자에게 앱이 표시됩니다.',
3337
+ publishFailed: '게시에 실패했습니다',
3338
+ },
3339
+ // ADR-0067 — the append-only build/revert timeline (CommitTimeline.tsx);
3340
+ // `button` is the banner's entry point into it.
3341
+ history: {
3342
+ button: '기록',
3343
+ title: '빌드 기록',
3344
+ description: '이 앱의 모든 변경을 최신순으로 표시합니다. 어떤 단계든 되돌려 취소할 수 있습니다 — 게시 확인은 필요하지 않습니다.',
3345
+ loadFailed: '기록을 불러올 수 없습니다:',
3346
+ loadFailedUnavailable: '커밋 저장소에 일시적으로 연결할 수 없습니다 — 이번 읽기는 수행되지 않았으므로 기록이 표시되지 않습니다. 잠시 후 다시 시도하세요.',
3347
+ loading: '기록을 불러오는 중…',
3348
+ empty: '이 앱의 기록이 아직 없습니다.',
3349
+ revertLabel: '변경을 되돌렸습니다',
3350
+ applyLabel: '빌드 변경',
3351
+ revert: '되돌림',
3352
+ items: '항목',
3353
+ revertAction: '되돌리기',
3354
+ reverted: '되돌렸습니다 — 변경이 취소되었습니다.',
3355
+ revertFailed: '되돌리기 실패',
3356
+ revertUnavailable: '커밋 저장소에 일시적으로 연결할 수 없습니다 — 되돌리기가 적용되지 않았을 수 있습니다. 이 기록을 다시 열어 확인한 후 재시도하세요.',
3357
+ },
3012
3358
  },
3013
3359
  filterBuilder: {
3014
3360
  where: "조건",
@@ -3087,5 +3433,57 @@ const ko = {
3087
3433
  statusIdle: "유휴",
3088
3434
  statusAway: "자리 비움",
3089
3435
  },
3436
+ wizard: {
3437
+ missingRequired: "필수 항목을 입력하세요: {{fields}}",
3438
+ },
3439
+ appManagement: {
3440
+ title: "애플리케이션",
3441
+ subtitle: "구성된 모든 애플리케이션을 관리합니다",
3442
+ newApp: "새 앱",
3443
+ searchLabel: "앱 검색",
3444
+ searchPlaceholder: "앱 검색…",
3445
+ selectedCount: "{{n}}개 선택됨",
3446
+ bulkEnable: "활성화",
3447
+ bulkDisable: "비활성화",
3448
+ selectAll: "전체 선택({{n}})",
3449
+ empty: "앱을 찾을 수 없습니다.",
3450
+ defaultBadge: "기본값",
3451
+ active: "활성",
3452
+ inactive: "비활성",
3453
+ selectApp: "{{name}} 선택",
3454
+ openApp: "앱 열기",
3455
+ openAppNamed: "{{name}} 열기",
3456
+ editApp: "앱 편집",
3457
+ editAppNamed: "{{name}} 편집",
3458
+ editWithAi: "AI로 편집",
3459
+ editWithAiNamed: "AI로 {{name}} 편집",
3460
+ enableApp: "앱 활성화",
3461
+ disableApp: "앱 비활성화",
3462
+ enableAppNamed: "{{name}} 활성화",
3463
+ disableAppNamed: "{{name}} 비활성화",
3464
+ setDefault: "기본값으로 설정",
3465
+ setDefaultNamed: "{{name}}을(를) 기본값으로 설정",
3466
+ deleteApp: "앱 삭제",
3467
+ deleteAppNamed: "{{name}} 삭제",
3468
+ confirmDelete: "삭제하려면 다시 클릭하세요",
3469
+ confirmDeleteNamed: "{{name}} 삭제 확인",
3470
+ toast: {
3471
+ noClient: "메타데이터 서비스에 연결할 수 없습니다",
3472
+ unknownError: "알 수 없는 오류",
3473
+ appEnabled: "{{name}}을(를) 활성화했습니다",
3474
+ appDisabled: "{{name}}을(를) 비활성화했습니다",
3475
+ toggleFailed: "앱 상태 전환 실패: {{reason}}",
3476
+ setDefaultDone: "{{name}}을(를) 기본값으로 설정했습니다",
3477
+ setDefaultFailed: "기본 앱 설정 실패: {{reason}}",
3478
+ appDeleted: "{{name}}을(를) 삭제했습니다",
3479
+ deleteFailed: "앱 삭제 실패: {{reason}}",
3480
+ bulkEnabled: "앱 {{n}}개를 활성화했습니다",
3481
+ bulkDisabled: "앱 {{n}}개를 비활성화했습니다",
3482
+ bulkFailed: "{{n}}개 실패: {{details}}",
3483
+ bulkFailureEntry: "{{name}}({{reason}})",
3484
+ bulkFailureJoiner: "; ",
3485
+ bulkOperationFailed: "일괄 작업 실패: {{reason}}",
3486
+ },
3487
+ },
3090
3488
  };
3091
3489
  export default ko;