Files
lms-fe/src/renderer/public/slam-viewer/locale.js
T

74 lines
3.4 KiB
JavaScript

const storageKey = 'autonomy-studio.lms.language';
let language = 'ko';
try { language = localStorage.getItem(storageKey) === 'en' ? 'en' : 'ko'; } catch {}
const english = {
'벽 배치': 'Place walls',
'맵 저장': 'Save map',
'로봇 경로 표시': 'Show robot path',
'센서 표시': 'Show sensors',
'카메라 영상 표시': 'Show camera preview',
'초기 위치 지정': 'Set initial pose',
'목표 위치 지정': 'Set goal',
'카메라 시점': 'Camera view',
'미니맵 접기/펼치기': 'Toggle minimap',
'미니맵 접기': 'Collapse minimap',
'미니맵 펼치기': 'Expand minimap',
'카메라 화면 접기/펼치기': 'Toggle camera preview',
'카메라 화면 접기': 'Collapse camera preview',
'카메라 화면 펼치기': 'Expand camera preview',
'실시간 카메라 화면': 'Live camera preview',
'i 전진 · , 후진 · j/l 회전 · k 정지': 'i Forward · , Reverse · j/l Turn · k Stop',
'i 전진 · , 후진 · j/l 주행 중 조향 · k 정지': 'i Forward · , Reverse · j/l Steer while moving · k Stop',
'ROS 상태 접기/펼치기': 'Toggle ROS status',
'ROS 상태 접기': 'Collapse ROS status',
'ROS 상태 펼치기': 'Expand ROS status',
'ROS 상태': 'ROS status',
'응답을 기다리는 중입니다.': 'Waiting for a response.',
'맵을 저장하고 있습니다.': 'Saving the map.',
'가제보 로봇 위치를 적용하지 못했습니다.': 'Failed to set the Gazebo robot pose.',
'주행 시뮬레이션에서는 초기 위치를 한 번만 설정할 수 있습니다.': 'The initial pose can only be set once during navigation simulation.',
'로봇 초기 위치 설정': 'Set initial robot pose',
'3D 포인트클라우드를 표시 중입니다.': 'Displaying the 3D point cloud.',
'모듈을 연결해주세요.': 'Connect your modules.',
'맵 저장에 실패했습니다.': 'Failed to save the map.',
'기존 목표를 취소하지 못했습니다.': 'Failed to cancel the previous goal.',
'가제보 로봇 위치 적용 시간이 초과되었습니다.': 'Setting the Gazebo robot pose timed out.'
};
export function t(key) { return language === 'en' ? (english[key] ?? key) : key; }
// Only explicitly marked viewer UI is translated. Topic names and telemetry stay intact.
export function setText(element, key) {
element.dataset.i18n = key;
element.textContent = t(key);
}
function refresh() {
document.documentElement.lang = language;
document.querySelectorAll('[data-i18n]').forEach(element => {
element.textContent = t(element.dataset.i18n);
});
for (const attribute of ['title', 'aria-label', 'alt']) {
document.querySelectorAll(`[data-i18n-${attribute}]`).forEach(element => {
element.setAttribute(attribute, t(element.getAttribute(`data-i18n-${attribute}`)));
});
}
}
window.addEventListener('storage', event => {
if (event.key !== storageKey) return;
language = event.newValue === 'en' ? 'en' : 'ko';
refresh();
});
refresh();
// Embedded viewers may not share storage with the app (for example file URLs).
window.addEventListener('message', event => {
if (window.parent === window || event.source !== window.parent) return;
if (event.data?.type !== 'lms:language' || !['ko', 'en'].includes(event.data.language)) return;
language = event.data.language;
refresh();
});
if (window.parent !== window) window.parent.postMessage({ type: 'lms:language:ready' }, '*');