From 973b4192878f7e064aa3446b10e8d25fb112debc Mon Sep 17 00:00:00 2001 From: htlee Date: Sat, 4 Apr 2026 01:06:14 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=AA=A8=EC=84=A0=20=EA=B2=80=ED=86=A0?= =?UTF-8?q?=20=ED=8C=A8=EB=84=90=20i18n=20=EB=B2=88=EC=97=AD=20=ED=82=A4?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20(ko/en)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parentInference.* 키가 누락되어 UI에 번역 키가 그대로 노출되던 문제. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/i18n/locales/en/common.json | 196 +++++++++++++++++++++++ frontend/src/i18n/locales/ko/common.json | 196 +++++++++++++++++++++++ 2 files changed, 392 insertions(+) diff --git a/frontend/src/i18n/locales/en/common.json b/frontend/src/i18n/locales/en/common.json index 3daf053..04fd523 100644 --- a/frontend/src/i18n/locales/en/common.json +++ b/frontend/src/i18n/locales/en/common.json @@ -195,6 +195,202 @@ "operator": "Operator", "yearSuffix": "" }, + "fleetGear": { + "fleetSection": "Fleet Status ({{count}})", + "fleetFallback": "Fleet #{{id}}", + "inZoneSection": "Gear In Zone ({{count}})", + "outZoneSection": "Unauthorized Gear ({{count}})", + "toggleFleetSection": "Collapse or expand fleet status", + "emptyFleet": "No fleet data", + "vesselCountCompact": "({{count}} vessels)", + "zoom": "Zoom", + "moveToFleet": "Move map to this fleet", + "moveToGroup": "Move map to this gear group", + "moveToShip": "Move to ship", + "moveToShipItem": "Move to ship {{name}}", + "moveToGear": "Move to gear position", + "moveToGearItem": "Move to {{name}} position", + "shipList": "Ships", + "gearList": "Gear List", + "roleMain": "Main", + "roleSub": "Sub" + }, + "parentInference": { + "title": "Parent Review", + "actorLabel": "Review Actor", + "actorPlaceholder": "lab-ui", + "reviewQueue": "Review Queue ({{count}})", + "reviewQueueFiltered": "Review Queue ({{filtered}} / {{total}})", + "queueMeta": "sc#{{subClusterId}} · {{count}} candidates", + "emptyQueue": "No items waiting for review.", + "loading": "Loading...", + "emptyState": "No parent inference data yet.", + "filters": { + "minScore": "Minimum score", + "minScoreValue": "{{value}}%+", + "minScoreAll": "All", + "minMemberCount": "Minimum gear", + "search": "Search", + "searchPlaceholder": "Search name, zone, suggested parent", + "clearSearch": "Clear", + "resetFilters": "Reset filters", + "sort": "Sort", + "startSpatial": "Draw map range", + "finishSpatial": "Apply range", + "clearSpatial": "Clear range", + "spatialIdle": "No map range filter is applied.", + "spatialDrawing": "{{count}} points added on the map. Move the mouse for a live preview, and click near the start point after 3 or more points to close the polygon.", + "spatialApplied": "Only gear groups inside the drawn map range are shown.", + "queueFilterFallback": "Saved filters currently hide every item, so the full review queue is shown temporarily.", + "queueTopScore": "Top Score {{score}}", + "queueMemberCount": "{{count}} gear", + "sortOptions": { + "backend": "Default order", + "topScore": "Highest score", + "memberCount": "Most gear", + "candidateCount": "Most candidates", + "zoneDistance": "Closest to fishing zone", + "name": "Name" + } + }, + "summary": { + "label": "Inference", + "recommendedParent": "Suggested Parent", + "confidence": "Confidence", + "topMargin": "Top Score/Margin", + "stableCycles": "Stable Cycles", + "statusReason": "Reason", + "marginOnly": "Margin", + "activeLabel": "Active Label", + "activeUntil": "until {{value}}", + "groupExclusions": "Group Exclusions" + }, + "metrics": { + "corr": "Corr", + "name": "Name", + "track": "Track", + "visit": "Visit", + "prox": "Prox", + "activity": "Activity" + }, + "actions": { + "refresh": "Refresh", + "duration": "Duration", + "durationOption": "{{days}}d", + "label": "Label", + "jumpSubCluster": "Locate", + "cancelLabel": "Clear Label", + "groupExclude": "Group Excl.", + "releaseGroupExclude": "Group Clear", + "globalExclude": "Global Excl.", + "releaseGlobalExclude": "Global Clear", + "otherLabelActive": "Another candidate is already active as the labeled parent." + }, + "badges": { + "AUTO_PROMOTED": "AUTO", + "MANUAL_CONFIRMED": "MANUAL", + "DIRECT_PARENT_MATCH": "DIRECT", + "REVIEW_REQUIRED": "REVIEW", + "SKIPPED_SHORT_NAME": "SHORT", + "NO_CANDIDATE": "NO CAND", + "UNRESOLVED": "OPEN", + "NONE": "NONE" + }, + "status": { + "AUTO_PROMOTED": "Auto Promoted", + "MANUAL_CONFIRMED": "Manual Confirmed", + "DIRECT_PARENT_MATCH": "Direct Parent Match", + "REVIEW_REQUIRED": "Review Required", + "SKIPPED_SHORT_NAME": "Skipped: Short Name", + "NO_CANDIDATE": "No Candidate", + "UNRESOLVED": "Unresolved" + }, + "reasons": { + "shortName": "Normalized name is shorter than 4 characters", + "directParentMatch": "A direct parent vessel is already included in the group", + "noCandidate": "No candidate could be generated" + }, + "reference": { + "shipOnly": "Only ship candidates are used for confirm and 24-hour exclusion. Gear remains reference-only for replay comparison.", + "reviewDriven": "When parent review is active, this panel becomes reference-only. Actual overlay visibility follows the state of the right-side parent review panel.", + "referenceGear": "Reference Gear" + }, + "candidate": { + "hoverHint": "Hover a candidate card to compare that vessel's full track and current replay movement more clearly.", + "trackReady": "Track Ready", + "trackMissing": "No Track", + "totalScore": "Total", + "nationalityBonusApplied": "Nationality +{{value}}%", + "nationalityBonusNone": "No nationality bonus", + "evidenceConfidence": "Evidence {{value}}%", + "emptyThreshold": "No candidates at or above {{score}}%.", + "labelActive": "Label", + "groupExcludedUntil": "Group Excluded · {{value}}", + "globalExcluded": "Global Excl.", + "trackWindow": "Observed", + "overlapWindow": "Overlap", + "inZoneWindow": "In zone", + "scoreWindow": "Score win.", + "trackCoverage": "Track adj.", + "visitCoverage": "Visit adj.", + "activityCoverage": "Activity adj.", + "proxCoverage": "Prox adj." + }, + "help": { + "title": "Parent Review Guide", + "intro": "All scores are shown as 0-100%. The final candidate score is built from the components below, and reviewers should use both the candidate cards and replay comparison together.", + "close": "Close", + "scoreTitle": "Scoring", + "scoreScaleLabel": "Display scale", + "scoreScaleDesc": "Each candidate metric is stored as 0.0-1.0 internally and displayed as 0-100%.", + "formulaLabel": "Final score formula", + "formulaDesc": "Corr 40% + Name 15% + Track 15% + Visit 10% + Proximity 5% + Activity 5% + Stability 10% + Registry bonus 5%. After that, if the pre-bonus score is at least 30% and MMSI starts with 412/413, a +15% nationality bonus is added at the very end.", + "nameScoreLabel": "Name score", + "nameScoreDesc": "100% for raw uppercase exact match, 80% for normalized exact match after removing spaces/`_`/`-`/`%`, 50% for prefix or contains match, 30% when only the pure alphabetic portion matches after removing digits, and 0% otherwise. Normalized comparison uses the gear-group name against candidate AIS/registry names.", + "corrLabel": "Corr", + "corrDesc": "Uses the current_score from the default correlation model directly. This is the base linkage score between the group and the vessel candidate.", + "trackLabel": "Track", + "trackDesc": "Compares the last 6 hours of gear-polygon center movement and vessel track with DTW. Near 0m average distance approaches 100%; 10km or more approaches 0%. Short observations are reduced afterward by a coverage adjustment based on observed points and span.", + "coverageLabel": "Coverage adjustment", + "coverageDesc": "Track, visit, proximity, and activity are discounted when the observed track, overlap window, or in-zone stay is too short. The candidate card shows this as Observed/Overlap/In zone plus the adjustment rows.", + "visitLabel": "Visit", + "visitDesc": "Average visit_score from raw metrics over the last 6 hours. It rises when the vessel repeatedly visits the group area, but short in-zone coverage lowers the effective value.", + "proxLabel": "Proximity", + "proxDesc": "Average proximity_ratio from raw metrics over the last 6 hours. It rises when the vessel stays physically close over aligned observations, but very short tracks are reduced by the track coverage adjustment.", + "activityLabel": "Activity", + "activityDesc": "Average activity_sync from raw metrics over the last 6 hours. It reflects how similarly movement and working patterns evolve together, and is reduced when in-zone coverage is too short.", + "stabilityLabel": "Stability", + "stabilityDesc": "Computed as default correlation streak_count divided by 6, then clamped to 100%. It rises when the same top candidate persists across cycles.", + "bonusLabel": "Bonuses", + "bonusDesc": "A registry-matched vessel gets a fixed +5%. A 412/413 MMSI gets +15% only when the pre-bonus score is already at least 30%.", + "summaryLabel": "Top / Margin / Stable cycles", + "summaryDesc": "Top score is the final score of the #1 candidate for the group, margin is the gap between #1 and #2, and stable cycles counts how many consecutive cycles the same top MMSI remained on top.", + "filterTitle": "Filters", + "filterSortLabel": "Sort", + "filterSortDesc": "Reorders the queue by default order, score, gear count, candidate count, fishing-zone distance, or name.", + "filterMemberLabel": "Min gear count", + "filterMemberDesc": "Only groups with at least this many gear members remain in the review queue. Default is 2.", + "filterScoreLabel": "Min score", + "filterScoreDesc": "Only groups whose top score is at or above this threshold remain in the list and on the map. Candidate cards are also limited to 30%+ scores in the current UI.", + "filterSearchLabel": "Search", + "filterSearchDesc": "Matches input text while ignoring spaces and case. Groups remain visible when the query is contained in the group name, zone name, or suggested parent name.", + "filterSpatialLabel": "Map area", + "filterSpatialDesc": "Start drawing, click the map to create a polygon, and finish to keep only groups inside that area. It combines with score/gear-count filters using AND logic.", + "actionTitle": "Buttons and interactions", + "actionRefreshLabel": "Refresh", + "actionRefreshDesc": "Reloads the selected group's inference, active labels/exclusions, and the review queue.", + "actionLocateLabel": "Locate", + "actionLocateDesc": "Moves the map to the actual member bounds of that `sc#` subcluster, which helps when the same name is split into far-apart clusters.", + "actionLabelLabel": "Label", + "actionLabelDesc": "Stores the selected candidate as the answer label for this group. During the chosen duration (1/3/5 days), shadow tracking rows are accumulated for model evaluation.", + "actionGroupExcludeLabel": "Group Excl.", + "actionGroupExcludeDesc": "Excludes the selected candidate only from this gear group for the chosen duration. Other groups are unaffected.", + "actionGlobalExcludeLabel": "Global Excl.", + "actionGlobalExcludeDesc": "Excludes the selected MMSI from every gear group's candidate pool for the chosen duration. Use this for AIS targets that were misclassified as vessel candidates.", + "actionHoverLabel": "Hover compare", + "actionHoverDesc": "Hovering a candidate card strongly highlights that vessel's full track and current movement in replay so you can visually compare it against the gear polygon movement." + } + }, "auth": { "title": "KCG Monitoring Dashboard", "subtitle": "Maritime Situational Awareness", diff --git a/frontend/src/i18n/locales/ko/common.json b/frontend/src/i18n/locales/ko/common.json index 39a8287..9c7a996 100644 --- a/frontend/src/i18n/locales/ko/common.json +++ b/frontend/src/i18n/locales/ko/common.json @@ -195,6 +195,202 @@ "operator": "운영", "yearSuffix": "년" }, + "fleetGear": { + "fleetSection": "선단 현황 ({{count}}개)", + "fleetFallback": "선단 #{{id}}", + "inZoneSection": "조업구역내 어구 ({{count}}개)", + "outZoneSection": "비허가 어구 ({{count}}개)", + "toggleFleetSection": "선단 현황 접기/펴기", + "emptyFleet": "선단 데이터 없음", + "vesselCountCompact": "({{count}}척)", + "zoom": "이동", + "moveToFleet": "이 선단으로 지도 이동", + "moveToGroup": "이 어구 그룹으로 지도 이동", + "moveToShip": "선박으로 이동", + "moveToShipItem": "{{name}} 선박으로 이동", + "moveToGear": "어구 위치로 이동", + "moveToGearItem": "{{name}} 위치로 이동", + "shipList": "선박", + "gearList": "어구 목록", + "roleMain": "주선", + "roleSub": "구성" + }, + "parentInference": { + "title": "모선 검토", + "actorLabel": "검토자", + "actorPlaceholder": "lab-ui", + "reviewQueue": "검토 대기 ({{count}}건)", + "reviewQueueFiltered": "검토 대기 ({{filtered}} / {{total}}건)", + "queueMeta": "sc#{{subClusterId}} · 후보 {{count}}건", + "emptyQueue": "대기 중인 검토가 없습니다.", + "loading": "불러오는 중...", + "emptyState": "모선 추론 데이터가 아직 없습니다.", + "filters": { + "minScore": "최소 일치율", + "minScoreValue": "{{value}}%+", + "minScoreAll": "전체", + "minMemberCount": "최소 어구 수", + "search": "검색", + "searchPlaceholder": "이름, 수역, 추천 모선 검색", + "clearSearch": "초기화", + "resetFilters": "필터 초기화", + "sort": "정렬", + "startSpatial": "지도 범위 그리기", + "finishSpatial": "범위 확정", + "clearSpatial": "범위 해제", + "spatialIdle": "지도 범위 필터가 적용되지 않았습니다.", + "spatialDrawing": "지도에서 점 {{count}}개를 찍었습니다. 마우스를 움직이면 미리보기가 보이고, 3개 이상이면 시작점 근처 클릭으로 바로 닫을 수 있습니다.", + "spatialApplied": "사용자가 그린 지도 범위 안의 어구 그룹만 표시합니다.", + "queueFilterFallback": "저장된 필터로 0건이 되어 전체 검토 대기 목록을 임시 표시 중입니다.", + "queueTopScore": "Top 점수 {{score}}", + "queueMemberCount": "{{count}}개", + "sortOptions": { + "backend": "기본 순서", + "topScore": "일치율 높은순", + "memberCount": "어구 수 많은순", + "candidateCount": "후보 수 많은순", + "zoneDistance": "조업구역 가까운순", + "name": "이름순" + } + }, + "summary": { + "label": "추론", + "recommendedParent": "추천 모선", + "confidence": "신뢰도", + "topMargin": "Top/격차", + "stableCycles": "연속 안정 주기", + "statusReason": "사유", + "marginOnly": "격차", + "activeLabel": "활성 정답 라벨", + "activeUntil": "{{value}}까지", + "groupExclusions": "그룹 제외 후보" + }, + "metrics": { + "corr": "상관", + "name": "이름", + "track": "궤적", + "visit": "방문", + "prox": "근접", + "activity": "활동" + }, + "actions": { + "refresh": "새로고침", + "duration": "적용 기간", + "durationOption": "{{days}}일", + "label": "라벨", + "jumpSubCluster": "이동", + "cancelLabel": "라벨 해제", + "groupExclude": "그룹 제외", + "releaseGroupExclude": "그룹 해제", + "globalExclude": "전체 제외", + "releaseGlobalExclude": "전체 해제", + "otherLabelActive": "다른 후보가 이미 정답 라벨로 활성화되어 있습니다." + }, + "badges": { + "AUTO_PROMOTED": "자동", + "MANUAL_CONFIRMED": "수동", + "DIRECT_PARENT_MATCH": "직접일치", + "REVIEW_REQUIRED": "검토", + "SKIPPED_SHORT_NAME": "짧음", + "NO_CANDIDATE": "후보없음", + "UNRESOLVED": "미해결", + "NONE": "없음" + }, + "status": { + "AUTO_PROMOTED": "자동 승격", + "MANUAL_CONFIRMED": "수동 확정", + "DIRECT_PARENT_MATCH": "직접 모선 일치", + "REVIEW_REQUIRED": "검토 필요", + "SKIPPED_SHORT_NAME": "짧은 이름 제외", + "NO_CANDIDATE": "후보 없음", + "UNRESOLVED": "미해결" + }, + "reasons": { + "shortName": "정규화 이름 길이 4 미만", + "directParentMatch": "그룹 멤버에 직접 모선이 포함됨", + "noCandidate": "후보를 생성하지 못함" + }, + "reference": { + "shipOnly": "모선 확정과 24시간 제외 판단은 선박 후보만 사용합니다. 어구는 재생 비교용 참고 정보입니다.", + "reviewDriven": "모선 검토가 선택되면 이 패널은 참고 정보만 보여주고, 실제 오버레이 표시는 우측 모선 검토 패널 상태를 그대로 따릅니다.", + "referenceGear": "참고 어구" + }, + "candidate": { + "hoverHint": "후보 카드에 마우스를 올리면 리플레이에서 해당 선박 항적과 현재 움직임을 강하게 비교할 수 있습니다.", + "trackReady": "항적 비교 가능", + "trackMissing": "항적 없음", + "totalScore": "전체", + "nationalityBonusApplied": "국적 가산 +{{value}}%", + "nationalityBonusNone": "국적 가산 없음", + "evidenceConfidence": "증거 {{value}}%", + "emptyThreshold": "{{score}}% 이상 후보가 없습니다.", + "labelActive": "라벨 활성", + "groupExcludedUntil": "그룹 제외 · {{value}}", + "globalExcluded": "전체 제외", + "trackWindow": "관측", + "overlapWindow": "겹침", + "inZoneWindow": "영역내", + "scoreWindow": "점수창", + "trackCoverage": "궤적 보정", + "visitCoverage": "방문 보정", + "activityCoverage": "활동 보정", + "proxCoverage": "근접 보정" + }, + "help": { + "title": "모선 검토 가이드", + "intro": "각 점수는 0~100%로 표시됩니다. 최종 후보 점수는 아래 항목을 합산해 계산하고, 검토자는 우측 후보 카드와 리플레이 비교를 함께 사용합니다.", + "close": "닫기", + "scoreTitle": "점수 기준", + "scoreScaleLabel": "표시 단위", + "scoreScaleDesc": "후보 카드의 각 수치는 0.0~1.0 내부 점수를 0~100%로 변환해 보여줍니다.", + "formulaLabel": "전체 점수 산식", + "formulaDesc": "상관 40% + 이름 15% + 궤적 15% + 방문 10% + 근접 5% + 활동 5% + 안정성 10% + 등록보너스 5%를 합산합니다. 그 뒤 pre-bonus 점수가 30% 이상이고 MMSI가 412/413으로 시작하면 국적 가산 +15%를 마지막에 후가산합니다.", + "nameScoreLabel": "이름 점수", + "nameScoreDesc": "원문을 대문자로 본 완전일치면 100%, 공백/`_`/`-`/`%` 제거 후 정규화 일치면 80%, prefix 또는 contains 일치면 50%, 숫자를 제거한 순수 문자 기준으로만 같으면 30%, 그 외는 0%입니다. 정규화 비교는 어구 그룹 이름과 후보 AIS/registry 이름을 기준으로 합니다.", + "corrLabel": "상관", + "corrDesc": "기본 correlation model의 current_score를 그대로 사용합니다. 해당 어구 그룹과 후보 선박이 기존 상관 모델에서 얼마나 강하게 연결됐는지의 기본 점수입니다.", + "trackLabel": "궤적", + "trackDesc": "최근 6시간의 어구 폴리곤 중심 이동과 선박 항적을 DTW 기반으로 비교합니다. 평균 거리 0m에 가까울수록 100%, 평균 거리 10km 이상이면 0%에 수렴합니다. 다만 관측 포인트 수와 관측 시간폭이 짧으면 coverage 보정으로 실제 반영치는 더 낮아집니다.", + "coverageLabel": "Coverage 보정", + "coverageDesc": "짧은 항적, 짧은 겹침, 짧은 영역내 체류가 과대평가되지 않도록 궤적/방문/근접/활동에 별도 보정 계수를 곱합니다. 후보 카드의 `관측/겹침/영역내`와 `XX 보정` 항목이 이 근거입니다.", + "visitLabel": "방문", + "visitDesc": "최근 6시간 raw metrics의 visit_score 평균입니다. 선박이 해당 어구 그룹 주변을 반복 방문할수록 높아집니다. 단, 영역내 포인트 수와 체류 시간이 짧으면 coverage 보정으로 낮아집니다.", + "proxLabel": "근접", + "proxDesc": "최근 6시간 raw metrics의 proximity_ratio 평균입니다. 같은 시계열 기준으로 가까이 붙어 있던 비율이 높을수록 올라갑니다. 단, 짧은 관측은 궤적 coverage 보정으로 그대로 100%를 유지하지 못합니다.", + "activityLabel": "활동", + "activityDesc": "최근 6시간 raw metrics의 activity_sync 평균입니다. 이동/조업 패턴이 함께 움직인 정도를 반영합니다. 영역내 관측이 짧으면 activity coverage 보정으로 반영치를 낮춥니다.", + "stabilityLabel": "안정성", + "stabilityDesc": "기본 correlation model의 streak_count를 6으로 나눈 뒤 100%로 clamp 합니다. 같은 후보가 여러 cycle 연속 유지될수록 올라갑니다.", + "bonusLabel": "보너스", + "bonusDesc": "registry 선박으로 식별되면 +5% 고정 가산, MMSI 412/413 후보는 pre-bonus 점수 30% 이상일 때만 +15%를 마지막에 추가합니다.", + "summaryLabel": "Top/격차/안정 주기", + "summaryDesc": "Top 점수는 현재 그룹의 1위 후보 최종 점수, 격차는 1위와 2위의 차이, 연속 안정 주기는 같은 1위 MMSI가 연속 유지된 cycle 수입니다.", + "filterTitle": "필터 사용법", + "filterSortLabel": "정렬", + "filterSortDesc": "기본 순서, 일치율, 어구 수, 후보 수, 조업구역 거리, 이름 기준으로 검토 대기 목록을 재배열합니다.", + "filterMemberLabel": "최소 어구 수", + "filterMemberDesc": "해당 수 이상 멤버를 가진 어구 그룹만 검토 대기에 남깁니다. 기본값은 2입니다.", + "filterScoreLabel": "최소 일치율", + "filterScoreDesc": "Top 점수가 지정한 값 이상인 그룹만 목록과 지도에 남깁니다. 현재 UI 후보 카드도 30% 이상 후보만 보여줍니다.", + "filterSearchLabel": "검색", + "filterSearchDesc": "입력한 텍스트를 공백 무관, 대소문자 무관으로 비교합니다. 그룹 이름, 수역명, 추천 모선 이름에 포함되면 목록과 지도에 남깁니다.", + "filterSpatialLabel": "지도 범위", + "filterSpatialDesc": "범위 시작 후 지도를 클릭해 다각형을 그리고, 완료를 누르면 그 범위 안의 어구 그룹만 검토 대기에 남깁니다. 최소 일치율/어구 수와 AND 조건으로 함께 적용됩니다.", + "actionTitle": "버튼과 동작", + "actionRefreshLabel": "새로고침", + "actionRefreshDesc": "현재 선택 그룹의 추론 결과, 활성 라벨/제외 상태, 검토 대기 목록을 다시 불러옵니다.", + "actionLocateLabel": "이동", + "actionLocateDesc": "해당 `sc#` 서브클러스터의 실제 멤버 bounds로 지도를 이동시켜, 멀리 떨어진 클러스터를 바로 찾을 수 있게 합니다.", + "actionLabelLabel": "라벨", + "actionLabelDesc": "선택한 후보를 이 어구 그룹의 정답 라벨로 기록합니다. 기간(1/3/5일) 동안 별도 tracking row가 쌓여 모델 평가용 백데이터로 사용됩니다.", + "actionGroupExcludeLabel": "그룹 제외", + "actionGroupExcludeDesc": "선택한 후보를 현재 어구 그룹에서만 기간 동안 제외합니다. 다른 어구 그룹의 후보군에는 영향을 주지 않습니다.", + "actionGlobalExcludeLabel": "전체 제외", + "actionGlobalExcludeDesc": "선택한 MMSI를 모든 어구 그룹의 후보군에서 기간 동안 제외합니다. 패턴 기반 이름이 아니어서 선박으로 오분류된 AIS를 제거할 때 사용합니다.", + "actionHoverLabel": "호버 비교", + "actionHoverDesc": "후보 카드에 마우스를 올리면 리플레이에서 해당 후보 선박의 전체 항적과 현재 움직임이 강하게 강조되어, 어구 폴리곤 중심 이동과 시각적으로 비교할 수 있습니다." + } + }, "auth": { "title": "KCG 모니터링 대시보드", "subtitle": "해양 상황 인식 시스템",