(() => {
  'use strict';
  if (window.__APU_DESIGN_I18N_V60__) return;
  window.__APU_DESIGN_I18N_V60__ = true;
  const LANGUAGES = {
    id: { name: 'Indonesia', short: 'ID' },
    en: { name: 'English', short: 'EN' },
    ms: { name: 'Melayu', short: 'MS' },
    de: { name: 'Deutsch', short: 'DE' },
    vi: { name: 'Tiếng Việt', short: 'VI' },
    zh: { name: '中文', short: '中文' },
    ja: { name: '日本語', short: '日本' }
  };

  const UI = {
    id: { group: 'Tampilan dan bahasa', theme: 'Ganti mode warna', light: 'Terang', dark: 'Gelap', enabledLight: 'Mode terang aktif', enabledDark: 'Mode gelap aktif', language: 'Pilih bahasa', changed: 'Bahasa diubah ke Indonesia', brand: 'Kontrol tampilan', translating: 'Menerjemahkan', translated: 'Terjemahan selesai', modelDownload: 'Menyiapkan model bahasa', fallback: 'Menggunakan terjemahan bawaan' },
    en: { group: 'Appearance and language', theme: 'Change color mode', light: 'Light', dark: 'Dark', enabledLight: 'Light mode enabled', enabledDark: 'Dark mode enabled', language: 'Choose language', changed: 'Language changed to English', brand: 'Display controls', translating: 'Translating', translated: 'Translation complete', modelDownload: 'Preparing language model', fallback: 'Using built-in fallback translation' },
    ms: { group: 'Penampilan dan bahasa', theme: 'Tukar mod warna', light: 'Cerah', dark: 'Gelap', enabledLight: 'Mod cerah diaktifkan', enabledDark: 'Mod gelap diaktifkan', language: 'Pilih bahasa', changed: 'Bahasa ditukar kepada Melayu', brand: 'Kawalan paparan', translating: 'Menterjemah', translated: 'Terjemahan selesai', modelDownload: 'Menyediakan model bahasa', fallback: 'Menggunakan terjemahan sandaran' },
    de: { group: 'Darstellung und Sprache', theme: 'Farbmodus wechseln', light: 'Hell', dark: 'Dunkel', enabledLight: 'Heller Modus aktiviert', enabledDark: 'Dunkler Modus aktiviert', language: 'Sprache wählen', changed: 'Sprache auf Deutsch geändert', brand: 'Anzeigeoptionen', translating: 'Wird übersetzt', translated: 'Übersetzung abgeschlossen', modelDownload: 'Sprachmodell wird vorbereitet', fallback: 'Interne Ersatzübersetzung wird verwendet' },
    vi: { group: 'Giao diện và ngôn ngữ', theme: 'Đổi chế độ màu', light: 'Sáng', dark: 'Tối', enabledLight: 'Đã bật chế độ sáng', enabledDark: 'Đã bật chế độ tối', language: 'Chọn ngôn ngữ', changed: 'Đã đổi ngôn ngữ sang Tiếng Việt', brand: 'Điều khiển hiển thị', translating: 'Đang dịch', translated: 'Đã dịch xong', modelDownload: 'Đang chuẩn bị mô hình ngôn ngữ', fallback: 'Đang dùng bản dịch dự phòng' },
    zh: { group: '外观与语言', theme: '切换颜色模式', light: '浅色', dark: '深色', enabledLight: '已启用浅色模式', enabledDark: '已启用深色模式', language: '选择语言', changed: '语言已切换为中文', brand: '显示控制', translating: '正在翻译', translated: '翻译完成', modelDownload: '正在准备语言模型', fallback: '正在使用内置备用翻译' },
    ja: { group: '外観と言語', theme: 'カラーモードを変更', light: 'ライト', dark: 'ダーク', enabledLight: 'ライトモードを有効化', enabledDark: 'ダークモードを有効化', language: '言語を選択', changed: '言語を日本語に変更しました', brand: '表示コントロール', translating: '翻訳中', translated: '翻訳が完了しました', modelDownload: '言語モデルを準備中', fallback: '内蔵の代替翻訳を使用中' }
  };

  const PHRASES = {
    'Overview': ['Ikhtisar','Overview','Gambaran keseluruhan','Übersicht','Tổng quan','概览','概要'],
    'Dashboard': ['Dasbor','Dashboard','Papan pemuka','Dashboard','Bảng điều khiển','仪表板','ダッシュボード'],
    'Dataset': ['Kumpulan Data','Dataset','Set data','Datensatz','Tập dữ liệu','数据集','データセット'],
    'Model': ['Model','Model','Model','Modell','Mô hình','模型','モデル'],
    'Models': ['Model','Models','Model','Modelle','Mô hình','模型','モデル'],
    'Results': ['Hasil','Results','Keputusan','Ergebnisse','Kết quả','结果','結果'],
    'Analysis': ['Analisis','Analysis','Analisis','Analyse','Phân tích','分析','分析'],
    'Failure Analysis': ['Analisis Kegagalan','Failure Analysis','Analisis Kegagalan','Fehleranalyse','Phân tích lỗi','失败分析','失敗分析'],
    'Limitations': ['Keterbatasan','Limitations','Batasan','Einschränkungen','Hạn chế','局限性','制限事項'],
    'Source Code': ['Kode Sumber','Source Code','Kod Sumber','Quellcode','Mã nguồn','源代码','ソースコード'],
    'Technical Report': ['Laporan Teknis','Technical Report','Laporan Teknikal','Technischer Bericht','Báo cáo kỹ thuật','技术报告','技術レポート'],
    'Reports': ['Laporan','Reports','Laporan','Berichte','Báo cáo','报告','レポート'],
    'Report': ['Laporan','Report','Laporan','Bericht','Báo cáo','报告','レポート'],
    'Settings': ['Pengaturan','Settings','Tetapan','Einstellungen','Cài đặt','设置','設定'],
    'Search': ['Cari','Search','Cari','Suchen','Tìm kiếm','搜索','検索'],
    'Home': ['Beranda','Home','Laman Utama','Startseite','Trang chủ','首页','ホーム'],
    'Projects': ['Proyek','Projects','Projek','Projekte','Dự án','项目','プロジェクト'],
    'Project': ['Proyek','Project','Projek','Projekt','Dự án','项目','プロジェクト'],
    'Research': ['Riset','Research','Penyelidikan','Forschung','Nghiên cứu','研究','研究'],
    'Certificates': ['Sertifikat','Certificates','Sijil','Zertifikate','Chứng chỉ','证书','証明書'],
    'Admission': ['Penerimaan','Admission','Kemasukan','Zulassung','Tuyển sinh','招生','入学'],
    'Documents': ['Dokumen','Documents','Dokumen','Dokumente','Tài liệu','文档','ドキュメント'],
    'Contact': ['Kontak','Contact','Hubungi','Kontakt','Liên hệ','联系','お問い合わせ'],
    'Support': ['Dukungan','Support','Sokongan','Support','Hỗ trợ','支持','サポート'],
    'Resume': ['Resume','Resume','Resume','Lebenslauf','Hồ sơ','简历','履歴書'],
    'Security': ['Keamanan','Security','Keselamatan','Sicherheit','Bảo mật','安全','セキュリティ'],
    'Governance': ['Tata Kelola','Governance','Tadbir Urus','Governance','Quản trị','治理','ガバナンス'],
    'Cloud Compare': ['Perbandingan Cloud','Cloud Compare','Perbandingan Awan','Cloud-Vergleich','So sánh đám mây','云对比','クラウド比較'],
    'Blueprints': ['Cetak Biru','Blueprints','Pelan Tindakan','Blaupausen','Bản thiết kế','蓝图','ブループリント'],
    'Agents': ['Agen','Agents','Ejen','Agenten','Tác nhân','智能体','エージェント'],
    'Predict': ['Prediksi','Predict','Ramalan','Vorhersage','Dự đoán','预测','予測'],
    'Recommendations': ['Rekomendasi','Recommendations','Cadangan','Empfehlungen','Đề xuất','建议','推奨事項'],
    'Students': ['Siswa','Students','Pelajar','Studierende','Sinh viên','学生','学生'],
    'Fairness': ['Keadilan','Fairness','Keadilan','Fairness','Công bằng','公平性','公平性'],
    'Tickets': ['Tiket','Tickets','Tiket','Tickets','Phiếu hỗ trợ','工单','チケット'],
    'Incidents': ['Insiden','Incidents','Insiden','Vorfälle','Sự cố','事件','インシデント'],
    'Timeline': ['Linimasa','Timeline','Garis Masa','Zeitleiste','Dòng thời gian','时间线','タイムライン'],
    'Analytics': ['Analitik','Analytics','Analitik','Analytik','Phân tích','分析','分析'],
    'Campaigns': ['Kampanye','Campaigns','Kempen','Kampagnen','Chiến dịch','活动','キャンペーン'],
    'Create': ['Buat','Create','Cipta','Erstellen','Tạo','创建','作成'],
    'History': ['Riwayat','History','Sejarah','Verlauf','Lịch sử','历史','履歴'],
    'Calculator': ['Kalkulator','Calculator','Kalkulator','Rechner','Máy tính','计算器','計算機'],
    'Troubleshoot': ['Pemecahan Masalah','Troubleshoot','Penyelesaian Masalah','Fehlerbehebung','Khắc phục sự cố','故障排除','トラブルシューティング'],
    'Tutorial': ['Tutorial','Tutorial','Tutorial','Tutorial','Hướng dẫn','教程','チュートリアル'],
    'Segmentation': ['Segmentasi','Segmentation','Segmentasi','Segmentierung','Phân đoạn','分段','セグメンテーション'],
    'Feedback': ['Umpan Balik','Feedback','Maklum Balas','Feedback','Phản hồi','反馈','フィードバック'],
    'New Feedback': ['Umpan Balik Baru','New Feedback','Maklum Balas Baharu','Neues Feedback','Phản hồi mới','新反馈','新しいフィードバック'],
    'Keywords': ['Kata Kunci','Keywords','Kata Kunci','Schlüsselwörter','Từ khóa','关键词','キーワード'],
    'Topics': ['Topik','Topics','Topik','Themen','Chủ đề','主题','トピック'],
    'Categories': ['Kategori','Categories','Kategori','Kategorien','Danh mục','类别','カテゴリー'],
    'Costs': ['Biaya','Costs','Kos','Kosten','Chi phí','费用','費用'],
    'Housing': ['Perumahan','Housing','Perumahan','Wohnen','Nhà ở','住房','住宅'],
    'Simulator': ['Simulator','Simulator','Simulator','Simulator','Mô phỏng','模拟器','シミュレーター'],
    'Methodology': ['Metodologi','Methodology','Metodologi','Methodik','Phương pháp','方法论','方法論'],
    'Save': ['Simpan','Save','Simpan','Speichern','Lưu','保存','保存'],
    'Cancel': ['Batal','Cancel','Batal','Abbrechen','Hủy','取消','キャンセル'],
    'Delete': ['Hapus','Delete','Padam','Löschen','Xóa','删除','削除'],
    'Edit': ['Edit','Edit','Sunting','Bearbeiten','Chỉnh sửa','编辑','編集'],
    'Update': ['Perbarui','Update','Kemas Kini','Aktualisieren','Cập nhật','更新','更新'],
    'Add': ['Tambah','Add','Tambah','Hinzufügen','Thêm','添加','追加'],
    'Download': ['Unduh','Download','Muat Turun','Herunterladen','Tải xuống','下载','ダウンロード'],
    'Upload': ['Unggah','Upload','Muat Naik','Hochladen','Tải lên','上传','アップロード'],
    'Back': ['Kembali','Back','Kembali','Zurück','Quay lại','返回','戻る'],
    'Next': ['Berikutnya','Next','Seterusnya','Weiter','Tiếp theo','下一步','次へ'],
    'Previous': ['Sebelumnya','Previous','Sebelumnya','Zurück','Trước','上一步','前へ'],
    'View Details': ['Lihat Detail','View Details','Lihat Butiran','Details ansehen','Xem chi tiết','查看详情','詳細を見る'],
    'Loading...': ['Memuat...','Loading...','Memuatkan...','Wird geladen...','Đang tải...','加载中...','読み込み中...'],
    'No data available': ['Tidak ada data','No data available','Tiada data','Keine Daten verfügbar','Không có dữ liệu','暂无数据','データがありません'],
    'Language': ['Bahasa','Language','Bahasa','Sprache','Ngôn ngữ','语言','言語'],
    'Theme': ['Tema','Theme','Tema','Design','Giao diện','主题','テーマ']
  };

  Object.assign(PHRASES, {
    'Model Architecture': ['Arsitektur Model','Model Architecture','Seni Bina Model','Modellarchitektur','Kiến trúc mô hình','模型架构','モデルアーキテクチャ'],
    'Network Selection': ['Pemilihan Jaringan','Network Selection','Pemilihan Rangkaian','Netzwerkauswahl','Lựa chọn mạng','网络选择','ネットワーク選択'],
    'Training Configuration': ['Konfigurasi Pelatihan','Training Configuration','Konfigurasi Latihan','Trainingskonfiguration','Cấu hình huấn luyện','训练配置','トレーニング設定'],
    'Training Dynamics': ['Dinamika Pelatihan','Training Dynamics','Dinamik Latihan','Trainingsdynamik','Diễn biến huấn luyện','训练动态','トレーニング推移'],
    'Loss Curve': ['Kurva Loss','Loss Curve','Lengkung Kehilangan','Verlustkurve','Đường cong mất mát','损失曲线','損失曲線'],
    'Accuracy': ['Akurasi','Accuracy','Ketepatan','Genauigkeit','Độ chính xác','准确率','精度'],
    'Validation Accuracy': ['Akurasi Validasi','Validation Accuracy','Ketepatan Pengesahan','Validierungsgenauigkeit','Độ chính xác xác thực','验证准确率','検証精度'],
    'Training Loss': ['Loss Pelatihan','Training Loss','Kehilangan Latihan','Trainingsverlust','Mất mát huấn luyện','训练损失','トレーニング損失'],
    'Validation Loss': ['Loss Validasi','Validation Loss','Kehilangan Pengesahan','Validierungsverlust','Mất mát xác thực','验证损失','検証損失'],
    'Performance': ['Performa','Performance','Prestasi','Leistung','Hiệu suất','性能','パフォーマンス'],
    'Architecture': ['Arsitektur','Architecture','Seni Bina','Architektur','Kiến trúc','架构','アーキテクチャ'],
    'Data Explorer': ['Penjelajah Data','Data Explorer','Peneroka Data','Daten-Explorer','Trình khám phá dữ liệu','数据浏览器','データエクスプローラー'],
    'Model Comparison': ['Perbandingan Model','Model Comparison','Perbandingan Model','Modellvergleich','So sánh mô hình','模型对比','モデル比較'],
    'Feature Importance': ['Pentingnya Fitur','Feature Importance','Kepentingan Ciri','Merkmalsbedeutung','Tầm quan trọng của đặc trưng','特征重要性','特徴量重要度'],
    'System Status': ['Status Sistem','System Status','Status Sistem','Systemstatus','Trạng thái hệ thống','系统状态','システム状態'],
    'Recent Activity': ['Aktivitas Terbaru','Recent Activity','Aktiviti Terkini','Letzte Aktivität','Hoạt động gần đây','最近活动','最近のアクティビティ'],
    'Quick Actions': ['Tindakan Cepat','Quick Actions','Tindakan Pantas','Schnellaktionen','Thao tác nhanh','快捷操作','クイック操作'],
    'Open': ['Buka','Open','Buka','Öffnen','Mở','打开','開く'],
    'Close': ['Tutup','Close','Tutup','Schließen','Đóng','关闭','閉じる'],
    'Menu': ['Menu','Menu','Menu','Menü','Trình đơn','菜单','メニュー'],
    'Light': ['Terang','Light','Cerah','Hell','Sáng','浅色','ライト'],
    'Dark': ['Gelap','Dark','Gelap','Dunkel','Tối','深色','ダーク'],
    'Appearance': ['Tampilan','Appearance','Penampilan','Darstellung','Giao diện','外观','外観'],
    'Select language': ['Pilih bahasa','Select language','Pilih bahasa','Sprache auswählen','Chọn ngôn ngữ','选择语言','言語を選択'],
    'Change theme': ['Ganti tema','Change theme','Tukar tema','Design wechseln','Đổi giao diện','切换主题','テーマを変更'],
    'Refresh': ['Segarkan','Refresh','Muat Semula','Aktualisieren','Làm mới','刷新','更新'],
    'Apply': ['Terapkan','Apply','Gunakan','Anwenden','Áp dụng','应用','適用'],
    'Reset': ['Atur Ulang','Reset','Tetapkan Semula','Zurücksetzen','Đặt lại','重置','リセット'],
    'Submit': ['Kirim','Submit','Hantar','Senden','Gửi','提交','送信'],
    'Export': ['Ekspor','Export','Eksport','Exportieren','Xuất','导出','エクスポート'],
    'Import': ['Impor','Import','Import','Importieren','Nhập','导入','インポート'],
    'Filter': ['Filter','Filter','Tapis','Filter','Bộ lọc','筛选','フィルター'],
    'Sort': ['Urutkan','Sort','Isih','Sortieren','Sắp xếp','排序','並べ替え'],
    'Status': ['Status','Status','Status','Status','Trạng thái','状态','ステータス'],
    'Name': ['Nama','Name','Nama','Name','Tên','名称','名前'],
    'Description': ['Deskripsi','Description','Penerangan','Beschreibung','Mô tả','描述','説明'],
    'Date': ['Tanggal','Date','Tarikh','Datum','Ngày','日期','日付'],
    'Actions': ['Tindakan','Actions','Tindakan','Aktionen','Thao tác','操作','操作'],
    'Active': ['Aktif','Active','Aktif','Aktiv','Đang hoạt động','活跃','有効'],
    'Inactive': ['Tidak Aktif','Inactive','Tidak Aktif','Inaktiv','Không hoạt động','未启用','無効'],
    'Completed': ['Selesai','Completed','Selesai','Abgeschlossen','Hoàn thành','已完成','完了'],
    'Pending': ['Menunggu','Pending','Menunggu','Ausstehend','Đang chờ','待处理','保留中'],
    'Error': ['Kesalahan','Error','Ralat','Fehler','Lỗi','错误','エラー'],
    'Success': ['Berhasil','Success','Berjaya','Erfolgreich','Thành công','成功','成功'],
    'All': ['Semua','All','Semua','Alle','Tất cả','全部','すべて'],
    'Today': ['Hari Ini','Today','Hari Ini','Heute','Hôm nay','今天','今日'],
    'This Week': ['Minggu Ini','This Week','Minggu Ini','Diese Woche','Tuần này','本周','今週'],
    'This Month': ['Bulan Ini','This Month','Bulan Ini','Dieser Monat','Tháng này','本月','今月'],
    'Documentation': ['Dokumentasi','Documentation','Dokumentasi','Dokumentation','Tài liệu','文档','ドキュメント'],
    'Help': ['Bantuan','Help','Bantuan','Hilfe','Trợ giúp','帮助','ヘルプ'],
    'Log out': ['Keluar','Log out','Log keluar','Abmelden','Đăng xuất','退出登录','ログアウト'],
    'Sign in': ['Masuk','Sign in','Log masuk','Anmelden','Đăng nhập','登录','ログイン'],
    'Learn more': ['Pelajari Lebih Lanjut','Learn more','Ketahui lebih lanjut','Mehr erfahren','Tìm hiểu thêm','了解更多','詳しく見る'],
    'View all': ['Lihat Semua','View all','Lihat Semua','Alle anzeigen','Xem tất cả','查看全部','すべて表示'],
    'No results found': ['Tidak ada hasil','No results found','Tiada hasil ditemui','Keine Ergebnisse gefunden','Không tìm thấy kết quả','未找到结果','結果が見つかりません'],
    'Try again': ['Coba Lagi','Try again','Cuba Lagi','Erneut versuchen','Thử lại','重试','再試行'],
    'Loading': ['Memuat','Loading','Memuatkan','Wird geladen','Đang tải','加载中','読み込み中']
  });



  Object.assign(PHRASES, {
    'Feedback Explorer': ['Penjelajah Umpan Balik','Feedback Explorer','Peneroka Maklum Balas','Feedback-Explorer','Trình khám phá phản hồi','反馈浏览器','フィードバックエクスプローラー'],
    'Submit Feedback': ['Kirim Umpan Balik','Submit Feedback','Hantar Maklum Balas','Feedback senden','Gửi phản hồi','提交反馈','フィードバックを送信'],
    'Topic Analysis': ['Analisis Topik','Topic Analysis','Analisis Topik','Themenanalyse','Phân tích chủ đề','主题分析','トピック分析'],
    'Model Evaluation': ['Evaluasi Model','Model Evaluation','Penilaian Model','Modellbewertung','Đánh giá mô hình','模型评估','モデル評価'],
    'Enterprise RAG': ['RAG Perusahaan','Enterprise RAG','RAG Perusahaan','Enterprise-RAG','RAG doanh nghiệp','企业级 RAG','エンタープライズ RAG'],
    'AI Support': ['Dukungan AI','AI Support','Sokongan AI','KI-Support','Hỗ trợ AI','AI 支持','AI サポート'],
    'ML Predict API': ['API Prediksi ML','ML Predict API','API Ramalan ML','ML-Prognose-API','API dự đoán ML','ML 预测 API','ML 予測 API'],
    'Talent Match': ['Pencocokan Talenta','Talent Match','Padanan Bakat','Talentabgleich','Ghép nối nhân tài','人才匹配','人材マッチング'],
    'Doc Intel': ['Intelijen Dokumen','Doc Intel','Risikan Dokumen','Dokumentenintelligenz','Trí tuệ tài liệu','文档智能','文書インテリジェンス'],
    'ROI Estimator': ['Estimasi ROI','ROI Estimator','Penganggar ROI','ROI-Schätzer','Ước tính ROI','ROI 估算器','ROI 推定'],
    'Knowledge Base': ['Basis Pengetahuan','Knowledge Base','Pangkalan Pengetahuan','Wissensdatenbank','Cơ sở kiến thức','知识库','ナレッジベース'],
    'New Ticket': ['Tiket Baru','New Ticket','Tiket Baharu','Neues Ticket','Phiếu mới','新工单','新規チケット'],
    'Incident Monitoring': ['Pemantauan Insiden','Incident Monitoring','Pemantauan Insiden','Vorfallüberwachung','Giám sát sự cố','事件监控','インシデント監視'],
    'Academic Evidence': ['Bukti Akademik','Academic Evidence','Bukti Akademik','Akademische Nachweise','Minh chứng học thuật','学术证明','学術的証拠'],
    'Evidence Hub': ['Pusat Bukti','Evidence Hub','Hab Bukti','Nachweiszentrum','Trung tâm minh chứng','证据中心','証拠ハブ'],
    'Publications': ['Publikasi','Publications','Penerbitan','Publikationen','Ấn phẩm','出版物','出版物'],
    'Education': ['Pendidikan','Education','Pendidikan','Ausbildung','Giáo dục','教育','学歴'],
    'Awards': ['Penghargaan','Awards','Anugerah','Auszeichnungen','Giải thưởng','奖项','受賞歴'],
    'URL Shortener': ['Penyingkat URL','URL Shortener','Pemendek URL','URL-Kürzer','Trình rút gọn URL','URL 缩短器','URL 短縮'],
    'Cost Simulator': ['Simulator Biaya','Cost Simulator','Simulator Kos','Kostensimulator','Trình mô phỏng chi phí','费用模拟器','費用シミュレーター'],
    'Subnet Calculator': ['Kalkulator Subnet','Subnet Calculator','Kalkulator Subnet','Subnetzrechner','Máy tính mạng con','子网计算器','サブネット計算機'],
    'Student Performance': ['Performa Siswa','Student Performance','Prestasi Pelajar','Studierendenleistung','Kết quả học tập','学生表现','学生パフォーマンス'],
    'Data Studio': ['Studio Data','Data Studio','Studio Data','Datenstudio','Studio dữ liệu','数据工作室','データスタジオ'],
    'Run Prediction': ['Jalankan Prediksi','Run Prediction','Jalankan Ramalan','Prognose starten','Chạy dự đoán','运行预测','予測を実行'],
    'View Report': ['Lihat Laporan','View Report','Lihat Laporan','Bericht anzeigen','Xem báo cáo','查看报告','レポートを見る']
  });


  Object.assign(PHRASES, {
    'Privacy choice': ['Pilihan privasi','Privacy choice','Pilihan privasi','Datenschutzauswahl','Lựa chọn quyền riêng tư','隐私选择','プライバシー設定'],
    'Allow cookies to continue': ['Izinkan cookie untuk melanjutkan','Allow cookies to continue','Benarkan kuki untuk meneruskan','Cookies zum Fortfahren zulassen','Cho phép cookie để tiếp tục','允许 Cookie 以继续','続行するには Cookie を許可'],
    'Allow cookies & continue': ['Izinkan cookie dan lanjutkan','Allow cookies & continue','Benarkan kuki dan teruskan','Cookies zulassen und fortfahren','Cho phép cookie và tiếp tục','允许 Cookie 并继续','Cookie を許可して続行'],
    'Essential only': ['Hanya esensial','Essential only','Asas sahaja','Nur erforderliche','Chỉ thiết yếu','仅必要','必須のみ'],
    'Toggle theme': ['Ganti tema','Toggle theme','Tukar tema','Design wechseln','Đổi giao diện','切换主题','テーマ切替'],
    'Close navigation': ['Tutup navigasi','Close navigation','Tutup navigasi','Navigation schließen','Đóng điều hướng','关闭导航','ナビゲーションを閉じる'],
    'Open navigation': ['Buka navigasi','Open navigation','Buka navigasi','Navigation öffnen','Mở điều hướng','打开导航','ナビゲーションを開く'],
    'Menu': ['Menu','Menu','Menu','Menü','Menu','菜单','メニュー'],
    'Navigation': ['Navigasi','Navigation','Navigasi','Navigation','Điều hướng','导航','ナビゲーション'],
    'Research Navigation': ['Navigasi Riset','Research Navigation','Navigasi Penyelidikan','Forschungsnavigation','Điều hướng nghiên cứu','研究导航','研究ナビゲーション'],
    'Architecture Modules': ['Modul Arsitektur','Architecture Modules','Modul Seni Bina','Architekturmodule','Mô-đun kiến trúc','架构模块','アーキテクチャモジュール'],
    'interactive workspaces': ['ruang kerja interaktif','interactive workspaces','ruang kerja interaktif','interaktive Arbeitsbereiche','không gian làm việc tương tác','交互式工作区','インタラクティブワークスペース'],
    'Experiment Tracker': ['Pelacak Eksperimen','Experiment Tracker','Penjejak Eksperimen','Experiment-Tracker','Trình theo dõi thử nghiệm','实验跟踪器','実験トラッカー'],
    'Research Dashboard': ['Dasbor Riset','Research Dashboard','Papan Pemuka Penyelidikan','Forschungs-Dashboard','Bảng điều khiển nghiên cứu','研究仪表板','研究ダッシュボード'],
    'Image Classification': ['Klasifikasi Gambar','Image Classification','Pengelasan Imej','Bildklassifizierung','Phân loại hình ảnh','图像分类','画像分類'],
    'Student Feedback Sentiment Analysis': ['Analisis Sentimen Umpan Balik Siswa','Student Feedback Sentiment Analysis','Analisis Sentimen Maklum Balas Pelajar','Stimmungsanalyse von Studierendenfeedback','Phân tích cảm xúc phản hồi sinh viên','学生反馈情感分析','学生フィードバック感情分析'],
    'NLP Dashboard': ['Dasbor NLP','NLP Dashboard','Papan Pemuka NLP','NLP-Dashboard','Bảng điều khiển NLP','NLP 仪表板','NLP ダッシュボード'],
    'Positive': ['Positif','Positive','Positif','Positiv','Tích cực','正面','ポジティブ'],
    'Neutral': ['Netral','Neutral','Neutral','Neutral','Trung lập','中性','中立'],
    'Negative': ['Negatif','Negative','Negatif','Negativ','Tiêu cực','负面','ネガティブ'],
    'Open': ['Terbuka','Open','Terbuka','Offen','Mở','打开','未対応'],
    'Reviewed': ['Ditinjau','Reviewed','Disemak','Geprüft','Đã xem xét','已审核','確認済み'],
    'Archived': ['Diarsipkan','Archived','Diarkibkan','Archiviert','Đã lưu trữ','已归档','アーカイブ済み'],
    'Export JSON': ['Ekspor JSON','Export JSON','Eksport JSON','JSON exportieren','Xuất JSON','导出 JSON','JSON をエクスポート'],
    'Export CSV': ['Ekspor CSV','Export CSV','Eksport CSV','CSV exportieren','Xuất CSV','导出 CSV','CSV をエクスポート'],
    'Import JSON': ['Impor JSON','Import JSON','Import JSON','JSON importieren','Nhập JSON','导入 JSON','JSON をインポート'],
    'Clear form': ['Bersihkan formulir','Clear form','Kosongkan borang','Formular leeren','Xóa biểu mẫu','清空表单','フォームをクリア'],
    'Restore demo data': ['Pulihkan data demo','Restore demo data','Pulihkan data demo','Demodaten wiederherstellen','Khôi phục dữ liệu mẫu','恢复演示数据','デモデータを復元'],
    'Delete selected': ['Hapus yang dipilih','Delete selected','Padam yang dipilih','Auswahl löschen','Xóa mục đã chọn','删除所选项','選択項目を削除'],
    'Student Explorer': ['Penjelajah Siswa','Student Explorer','Peneroka Pelajar','Studierenden-Explorer','Trình khám phá sinh viên','学生浏览器','学生エクスプローラー'],
    'Prediction Model Lab': ['Lab Model Prediksi','Prediction Model Lab','Makmal Model Ramalan','Prognosemodell-Labor','Phòng thí nghiệm mô hình dự đoán','预测模型实验室','予測モデルラボ'],
    'Fairness Audit': ['Audit Keadilan','Fairness Audit','Audit Keadilan','Fairness-Audit','Kiểm tra công bằng','公平性审计','公平性監査'],
    'Student Recommendations': ['Rekomendasi Siswa','Student Recommendations','Cadangan Pelajar','Empfehlungen für Studierende','Đề xuất cho sinh viên','学生建议','学生向け推奨事項'],
    'Performance Report': ['Laporan Performa','Performance Report','Laporan Prestasi','Leistungsbericht','Báo cáo hiệu suất','表现报告','パフォーマンスレポート'],
    'Low risk': ['Risiko rendah','Low risk','Risiko rendah','Niedriges Risiko','Rủi ro thấp','低风险','低リスク'],
    'Medium risk': ['Risiko sedang','Medium risk','Risiko sederhana','Mittleres Risiko','Rủi ro trung bình','中风险','中リスク'],
    'High risk': ['Risiko tinggi','High risk','Risiko tinggi','Hohes Risiko','Rủi ro cao','高风险','高リスク'],
    'Active': ['Aktif','Active','Aktif','Aktiv','Hoạt động','活跃','アクティブ'],
    'Completed': ['Selesai','Completed','Selesai','Abgeschlossen','Hoàn thành','已完成','完了'],
    'Save & predict': ['Simpan dan prediksi','Save & predict','Simpan dan ramal','Speichern und prognostizieren','Lưu và dự đoán','保存并预测','保存して予測'],
    'Recalculate all': ['Hitung ulang semua','Recalculate all','Kira semula semua','Alle neu berechnen','Tính lại tất cả','全部重新计算','すべて再計算'],
    'Print report': ['Cetak laporan','Print report','Cetak laporan','Bericht drucken','In báo cáo','打印报告','レポートを印刷'],
    'Loading local metrics, governance data, solution blueprints, MLOps, RAG, and interactive architecture modules.': ['Memuat metrik lokal, data tata kelola, cetak biru solusi, MLOps, RAG, dan modul arsitektur interaktif.','Loading local metrics, governance data, solution blueprints, MLOps, RAG, and interactive architecture modules.','Memuatkan metrik tempatan, data tadbir urus, pelan tindakan penyelesaian, MLOps, RAG dan modul seni bina interaktif.','Lokale Metriken, Governance-Daten, Lösungsblaupausen, MLOps, RAG und interaktive Architekturmodule werden geladen.','Đang tải chỉ số cục bộ, dữ liệu quản trị, bản thiết kế giải pháp, MLOps, RAG và mô-đun kiến trúc tương tác.','正在加载本地指标、治理数据、解决方案蓝图、MLOps、RAG 和交互式架构模块。','ローカル指標、ガバナンスデータ、ソリューション設計、MLOps、RAG、インタラクティブなアーキテクチャモジュールを読み込んでいます。'],
    'Website tetap dapat dilihat. Pilih cookie analitik untuk membantu menghitung pengunjung unik, atau lanjutkan hanya dengan cookie esensial.': ['Website tetap dapat dilihat. Pilih cookie analitik untuk membantu menghitung pengunjung unik, atau lanjutkan hanya dengan cookie esensial.','The website remains available. Choose analytics cookies to help count unique visitors, or continue with essential cookies only.','Laman web kekal boleh dilihat. Pilih kuki analitik untuk membantu mengira pelawat unik, atau teruskan dengan kuki asas sahaja.','Die Website bleibt verfügbar. Wählen Sie Analyse-Cookies zur Zählung eindeutiger Besucher oder fahren Sie nur mit erforderlichen Cookies fort.','Trang web vẫn có thể xem được. Chọn cookie phân tích để hỗ trợ đếm khách truy cập duy nhất hoặc chỉ tiếp tục với cookie thiết yếu.','网站仍可正常查看。请选择分析 Cookie 以帮助统计独立访客，或仅使用必要 Cookie 继续。','ウェブサイトは引き続き閲覧できます。ユニーク訪問者の集計に役立つ分析 Cookie を選択するか、必須 Cookie のみで続行してください。']
  });

  const WORD_ROWS = {
    about:['tentang','about','tentang','über','giới thiệu','关于','概要'],
    add:['tambah','add','tambah','hinzufügen','thêm','添加','追加'],
    all:['semua','all','semua','alle','tất cả','全部','すべて'],
    analysis:['analisis','analysis','analisis','analyse','phân tích','分析','分析'],
    application:['aplikasi','application','aplikasi','anwendung','ứng dụng','应用','アプリケーション'],
    architecture:['arsitektur','architecture','seni bina','architektur','kiến trúc','架构','アーキテクチャ'],
    attendance:['kehadiran','attendance','kehadiran','anwesenheit','chuyên cần','出勤率','出席率'],
    average:['rata-rata','average','purata','durchschnitt','trung bình','平均','平均'],
    browser:['browser','browser','pelayar','browser','trình duyệt','浏览器','ブラウザー'],
    calculate:['hitung','calculate','kira','berechnen','tính toán','计算','計算'],
    category:['kategori','category','kategori','kategorie','danh mục','类别','カテゴリー'],
    change:['ubah','change','ubah','ändern','thay đổi','更改','変更'],
    choose:['pilih','choose','pilih','auswählen','chọn','选择','選択'],
    classification:['klasifikasi','classification','pengelasan','klassifizierung','phân loại','分类','分類'],
    close:['tutup','close','tutup','schließen','đóng','关闭','閉じる'],
    complete:['lengkap','complete','lengkap','vollständig','hoàn chỉnh','完整','完全'],
    confidence:['keyakinan','confidence','keyakinan','konfidenz','độ tin cậy','置信度','信頼度'],
    contact:['kontak','contact','hubungi','kontakt','liên hệ','联系','お問い合わせ'],
    cost:['biaya','cost','kos','kosten','chi phí','费用','費用'],
    create:['buat','create','cipta','erstellen','tạo','创建','作成'],
    current:['saat ini','current','semasa','aktuell','hiện tại','当前','現在'],
    dashboard:['dasbor','dashboard','papan pemuka','dashboard','bảng điều khiển','仪表板','ダッシュボード'],
    data:['data','data','data','daten','dữ liệu','数据','データ'],
    dataset:['kumpulan data','dataset','set data','datensatz','tập dữ liệu','数据集','データセット'],
    delete:['hapus','delete','padam','löschen','xóa','删除','削除'],
    description:['deskripsi','description','penerangan','beschreibung','mô tả','描述','説明'],
    details:['detail','details','butiran','details','chi tiết','详细信息','詳細'],
    document:['dokumen','document','dokumen','dokument','tài liệu','文档','ドキュメント'],
    download:['unduh','download','muat turun','herunterladen','tải xuống','下载','ダウンロード'],
    edit:['edit','edit','sunting','bearbeiten','chỉnh sửa','编辑','編集'],
    education:['pendidikan','education','pendidikan','bildung','giáo dục','教育','教育'],
    error:['kesalahan','error','ralat','fehler','lỗi','错误','エラー'],
    evaluation:['evaluasi','evaluation','penilaian','bewertung','đánh giá','评估','評価'],
    export:['ekspor','export','eksport','exportieren','xuất','导出','エクスポート'],
    feedback:['umpan balik','feedback','maklum balas','feedback','phản hồi','反馈','フィードバック'],
    filter:['filter','filter','tapis','filtern','lọc','筛选','フィルター'],
    form:['formulir','form','borang','formular','biểu mẫu','表单','フォーム'],
    group:['grup','group','kumpulan','gruppe','nhóm','组','グループ'],
    help:['bantuan','help','bantuan','hilfe','trợ giúp','帮助','ヘルプ'],
    history:['riwayat','history','sejarah','verlauf','lịch sử','历史','履歴'],
    information:['informasi','information','maklumat','informationen','thông tin','信息','情報'],
    input:['masukan','input','input','eingabe','đầu vào','输入','入力'],
    language:['bahasa','language','bahasa','sprache','ngôn ngữ','语言','言語'],
    light:['terang','light','cerah','hell','sáng','浅色','ライト'],
    loading:['memuat','loading','memuatkan','wird geladen','đang tải','加载中','読み込み中'],
    local:['lokal','local','tempatan','lokal','cục bộ','本地','ローカル'],
    model:['model','model','model','modell','mô hình','模型','モデル'],
    monthly:['bulanan','monthly','bulanan','monatlich','hàng tháng','每月','月間'],
    name:['nama','name','nama','name','tên','名称','名前'],
    navigation:['navigasi','navigation','navigasi','navigation','điều hướng','导航','ナビゲーション'],
    new:['baru','new','baharu','neu','mới','新建','新規'],
    open:['buka','open','buka','öffnen','mở','打开','開く'],
    operations:['operasi','operations','operasi','vorgänge','thao tác','操作','操作'],
    performance:['performa','performance','prestasi','leistung','hiệu suất','表现','パフォーマンス'],
    prediction:['prediksi','prediction','ramalan','prognose','dự đoán','预测','予測'],
    previous:['sebelumnya','previous','sebelumnya','vorherig','trước đó','之前','以前'],
    privacy:['privasi','privacy','privasi','datenschutz','quyền riêng tư','隐私','プライバシー'],
    project:['proyek','project','projek','projekt','dự án','项目','プロジェクト'],
    recommendation:['rekomendasi','recommendation','cadangan','empfehlung','đề xuất','建议','推奨事項'],
    report:['laporan','report','laporan','bericht','báo cáo','报告','レポート'],
    research:['riset','research','penyelidikan','forschung','nghiên cứu','研究','研究'],
    reset:['reset','reset','set semula','zurücksetzen','đặt lại','重置','リセット'],
    result:['hasil','result','keputusan','ergebnis','kết quả','结果','結果'],
    risk:['risiko','risk','risiko','risiko','rủi ro','风险','リスク'],
    save:['simpan','save','simpan','speichern','lưu','保存','保存'],
    score:['skor','score','skor','punktzahl','điểm','分数','スコア'],
    search:['cari','search','cari','suchen','tìm kiếm','搜索','検索'],
    security:['keamanan','security','keselamatan','sicherheit','bảo mật','安全','セキュリティ'],
    select:['pilih','select','pilih','auswählen','chọn','选择','選択'],
    settings:['pengaturan','settings','tetapan','einstellungen','cài đặt','设置','設定'],
    status:['status','status','status','status','trạng thái','状态','ステータス'],
    student:['siswa','student','pelajar','studierende','sinh viên','学生','学生'],
    students:['siswa','students','pelajar','studierende','sinh viên','学生','学生'],
    support:['dukungan','support','sokongan','support','hỗ trợ','支持','サポート'],
    system:['sistem','system','sistem','system','hệ thống','系统','システム'],
    technical:['teknis','technical','teknikal','technisch','kỹ thuật','技术','技術'],
    text:['teks','text','teks','text','văn bản','文本','テキスト'],
    theme:['tema','theme','tema','design','giao diện','主题','テーマ'],
    total:['total','total','jumlah','gesamt','tổng','总计','合計'],
    update:['perbarui','update','kemas kini','aktualisieren','cập nhật','更新','更新'],
    user:['pengguna','user','pengguna','benutzer','người dùng','用户','ユーザー'],
    value:['nilai','value','nilai','wert','giá trị','值','値'],
    view:['lihat','view','lihat','anzeigen','xem','查看','表示'],
    website:['situs web','website','laman web','website','trang web','网站','ウェブサイト'],
    yearly:['tahunan','yearly','tahunan','jährlich','hàng năm','每年','年間'],
    and:['dan','and','dan','und','và','和','と'],
    or:['atau','or','atau','oder','hoặc','或','または'],
    with:['dengan','with','dengan','mit','với','与','と'],
    without:['tanpa','without','tanpa','ohne','không có','不使用','なし'],
    for:['untuk','for','untuk','für','cho','用于','用'],
    from:['dari','from','daripada','von','từ','从','から'],
    to:['ke','to','ke','zu','đến','到','へ'],
    in:['di','in','dalam','in','trong','在','で'],
    of:['dari','of','daripada','von','của','的','の'],
    is:['adalah','is','ialah','ist','là','是','です'],
    are:['adalah','are','ialah','sind','là','是','です'],
    this:['ini','this','ini','dies','này','此','この'],
    every:['setiap','every','setiap','jede','mọi','每个','すべての'],
    complete:['lengkap','complete','lengkap','vollständig','hoàn chỉnh','完整','完全'],
    automatically:['secara otomatis','automatically','secara automatik','automatisch','tự động','自动','自動的に'],
    available:['tersedia','available','tersedia','verfügbar','có sẵn','可用','利用可能'],
    visible:['terlihat','visible','kelihatan','sichtbar','hiển thị','可见','表示可能'],
    selected:['dipilih','selected','dipilih','ausgewählt','đã chọn','已选择','選択済み']
  };

  Object.assign(PHRASES, {"Living Cost Planner":["Perencana Biaya Hidup","Living Cost Planner","Perancang Kos Sara Hidup","Lebenshaltungskostenplaner","Trình lập chi phí sinh hoạt","生活成本规划器","生活費プランナー"],"Cross-country budget planner":["Perencana anggaran lintas negara","Cross-country budget planner","Perancang bajet antara negara","Länderübergreifender Budgetplaner","Trình lập ngân sách đa quốc gia","跨国预算规划器","国別予算プランナー"],"Summary":["Ringkasan","Summary","Ringkasan","Zusammenfassung","Tóm tắt","摘要","概要"],"Comparison":["Perbandingan","Comparison","Perbandingan","Vergleich","So sánh","比较","比較"],"Education":["Pendidikan","Education","Pendidikan","Bildung","Giáo dục","教育","教育"],"Information":["Informasi","Information","Maklumat","Information","Thông tin","信息","情報"],"Frugal":["Hemat","Frugal","Jimat","Sparsam","Tiết kiệm","节俭","節約"],"Normal":["Normal","Normal","Normal","Normal","Bình thường","正常","標準"],"Premium":["Premium","Premium","Premium","Premium","Cao cấp","高级","プレミアム"],"Cost Breakdown":["Rincian Biaya","Cost Breakdown","Pecahan Kos","Kostenaufschlüsselung","Chi tiết chi phí","费用明细","費用内訳"],"Family & Health":["Keluarga & Kesehatan","Family & Health","Keluarga & Kesihatan","Familie & Gesundheit","Gia đình & Sức khỏe","家庭与健康","家族と健康"],"Currency & Savings":["Mata Uang & Tabungan","Currency & Savings","Mata Wang & Simpanan","Währung & Ersparnisse","Tiền tệ & Tiết kiệm","货币与储蓄","通貨と貯蓄"],"MY Cost Insights":["Wawasan Biaya Saya","MY Cost Insights","Wawasan Kos Saya","Meine Kostenübersicht","Thông tin chi phí của tôi","我的成本洞察","自分の費用分析"],"Compare major costs, organize monthly needs, and evaluate financial capacity in one concise workspace.":["Bandingkan biaya utama, susun kebutuhan bulanan, dan evaluasi kemampuan finansial dalam satu ruang kerja yang ringkas.","Compare major costs, organize monthly needs, and evaluate financial capacity in one concise workspace.","Bandingkan kos utama, susun keperluan bulanan dan nilai kemampuan kewangan dalam satu ruang kerja ringkas.","Vergleichen Sie Hauptkosten, planen Sie monatliche Bedürfnisse und bewerten Sie die finanzielle Leistungsfähigkeit in einem kompakten Arbeitsbereich.","So sánh chi phí chính, sắp xếp nhu cầu hàng tháng và đánh giá khả năng tài chính trong một không gian gọn gàng.","在一个简洁的工作区中比较主要成本、规划每月需求并评估财务能力。","主要費用を比較し、月々の必要額を整理し、財務能力を一つの簡潔なワークスペースで評価します。"],"249 countries & territories":["249 negara & wilayah","249 countries & territories","249 negara & wilayah","249 Länder & Gebiete","249 quốc gia & vùng lãnh thổ","249 个国家和地区","249の国と地域"],"Compare 4 locations":["Perbandingan 4 lokasi","Compare 4 locations","Bandingkan 4 lokasi","4 Standorte vergleichen","So sánh 4 địa điểm","比较 4 个地点","4地点を比較"],"Export-ready report":["Laporan siap ekspor","Export-ready report","Laporan sedia eksport","Exportfertiger Bericht","Báo cáo sẵn sàng xuất","可导出的报告","エクスポート対応レポート"],"Open calculator":["Buka kalkulator","Open calculator","Buka kalkulator","Rechner öffnen","Mở máy tính","打开计算器","計算機を開く"],"Export data":["Ekspor data","Export data","Eksport data","Daten exportieren","Xuất dữ liệu","导出数据","データを書き出す"],"Print report":["Cetak laporan","Print report","Cetak laporan","Bericht drucken","In báo cáo","打印报告","レポートを印刷"],"Country / territory":["Negara / wilayah","Country / territory","Negara / wilayah","Land / Gebiet","Quốc gia / vùng lãnh thổ","国家/地区","国・地域"],"Default currency":["Mata uang bawaan","Default currency","Mata wang lalai","Standardwährung","Tiền tệ mặc định","默认货币","既定通貨"],"Country preset available":["Preset negara tersedia","Country preset available","Pratetap negara tersedia","Ländervoreinstellung verfügbar","Có cài đặt sẵn cho quốc gia","国家预设可用","国別プリセットあり"],"City":["Kota","City","Bandar","Stadt","Thành phố","城市","都市"],"Currency":["Mata uang","Currency","Mata wang","Währung","Tiền tệ","货币","通貨"],"1 USD = local currency":["1 USD = mata uang lokal","1 USD = local currency","1 USD = mata wang tempatan","1 USD = lokale Währung","1 USD = tiền tệ địa phương","1 美元 = 当地货币","1米ドル = 現地通貨"],"World Bank 2025: official annual exchange rate":["World Bank 2025: kurs resmi tahunan","World Bank 2025: official annual exchange rate","World Bank 2025: kadar pertukaran rasmi tahunan","World Bank 2025: offizieller jährlicher Wechselkurs","World Bank 2025: tỷ giá chính thức hàng năm","世界银行 2025：官方年度汇率","世界銀行 2025：公式年間為替レート"],"Official annual exchange rate":["Kurs resmi tahunan","Official annual exchange rate","Kadar pertukaran rasmi tahunan","Offizieller jährlicher Wechselkurs","Tỷ giá chính thức hàng năm","官方年度汇率","公式年間為替レート"],"Household size":["Jumlah orang","Household size","Saiz isi rumah","Haushaltsgröße","Quy mô hộ gia đình","家庭人数","世帯人数"],"Lifestyle":["Gaya hidup","Lifestyle","Gaya hidup","Lebensstil","Lối sống","生活方式","ライフスタイル"],"Comfortable":["Nyaman","Comfortable","Selesa","Komfortabel","Thoải mái","舒适","快適"],"Monthly income":["Pendapatan bulanan","Monthly income","Pendapatan bulanan","Monatliches Einkommen","Thu nhập hàng tháng","月收入","月収"],"Load starting estimate":["Muat estimasi awal","Load starting estimate","Muat anggaran awal","Startschätzung laden","Tải ước tính ban đầu","加载初始估算","初期見積もりを読み込む"],"Sync World Bank data":["Sinkronkan data World Bank","Sync World Bank data","Segerakkan data World Bank","World-Bank-Daten synchronisieren","Đồng bộ dữ liệu World Bank","同步世界银行数据","世界銀行データを同期"],"Reset":["Atur ulang","Reset","Tetapkan semula","Zurücksetzen","Đặt lại","重置","リセット"],"Academic Evidence Pack":["Paket Bukti Akademik","Academic Evidence Pack","Pek Bukti Akademik","Paket akademischer Nachweise","Gói minh chứng học thuật","学术证据包","学術証拠パック"],"View All on GitHub":["Lihat Semua di GitHub","View All on GitHub","Lihat Semua di GitHub","Alle auf GitHub ansehen","Xem tất cả trên GitHub","在 GitHub 查看全部","GitHubですべて表示"],"Full Source":["Kode Sumber Lengkap","Full Source","Sumber Penuh","Vollständiger Quellcode","Mã nguồn đầy đủ","完整源代码","完全なソース"],"Personal Statement":["Pernyataan Pribadi","Personal Statement","Pernyataan Peribadi","Persönliche Erklärung","Bài luận cá nhân","个人陈述","自己紹介書"],"Study Plan":["Rencana Studi","Study Plan","Rancangan Pengajian","Studienplan","Kế hoạch học tập","学习计划","学習計画"],"Research Detail":["Detail Riset","Research Detail","Butiran Penyelidikan","Forschungsdetails","Chi tiết nghiên cứu","研究详情","研究詳細"],"Academic Evidence Hub":["Pusat Bukti Akademik","Academic Evidence Hub","Hab Bukti Akademik","Zentrum für akademische Nachweise","Trung tâm minh chứng học thuật","学术证据中心","学術証拠ハブ"],"Main navigation":["Navigasi utama","Main navigation","Navigasi utama","Hauptnavigation","Điều hướng chính","主导航","メインナビゲーション"],"Explore the Evidence Hub":["Jelajahi Pusat Bukti","Explore the Evidence Hub","Terokai Hab Bukti","Nachweiszentrum erkunden","Khám phá trung tâm minh chứng","探索证据中心","証拠ハブを探索"],"View Projects":["Lihat Proyek","View Projects","Lihat Projek","Projekte ansehen","Xem dự án","查看项目","プロジェクトを見る"],"Research Statement":["Pernyataan Riset","Research Statement","Pernyataan Penyelidikan","Forschungserklärung","Tuyên bố nghiên cứu","研究陈述","研究声明"],"Curriculum Vitae":["Daftar Riwayat Hidup","Curriculum Vitae","Riwayat Hidup","Lebenslauf","Sơ yếu lý lịch","个人简历","履歴書"],"Evidence Pack":["Paket Bukti","Evidence Pack","Pek Bukti","Nachweispaket","Gói minh chứng","证据包","証拠パック"],"Admission Docs":["Dokumen Penerimaan","Admission Docs","Dokumen Kemasukan","Zulassungsunterlagen","Tài liệu tuyển sinh","申请材料","出願書類"],"Graduate admissions reviewers":["Peninjau penerimaan pascasarjana","Graduate admissions reviewers","Penilai kemasukan siswazah","Prüfer für Graduiertenzulassungen","Người xét tuyển sau đại học","研究生招生审核人员","大学院入試審査担当者"],"Independent academic evidence":["Bukti akademik independen","Independent academic evidence","Bukti akademik bebas","Unabhängige akademische Nachweise","Minh chứng học thuật độc lập","独立学术证据","独立した学術証拠"],"Verified credentials and badges":["Kredensial dan lencana terverifikasi","Verified credentials and badges","Kelayakan dan lencana disahkan","Verifizierte Qualifikationen und Abzeichen","Chứng chỉ và huy hiệu đã xác minh","已验证的资历和徽章","検証済み資格とバッジ"],"Downloadable academic evidence":["Bukti akademik yang dapat diunduh","Downloadable academic evidence","Bukti akademik boleh dimuat turun","Herunterladbare akademische Nachweise","Minh chứng học thuật có thể tải xuống","可下载的学术证据","ダウンロード可能な学術証拠"],"Open source repositories":["Repositori sumber terbuka","Open source repositories","Repositori sumber terbuka","Open-Source-Repositories","Kho mã nguồn mở","开源代码仓库","オープンソースリポジトリ"],"Education, skills, and experience":["Pendidikan, keterampilan, dan pengalaman","Education, skills, and experience","Pendidikan, kemahiran dan pengalaman","Ausbildung, Fähigkeiten und Erfahrung","Học vấn, kỹ năng và kinh nghiệm","教育、技能与经验","学歴・スキル・経験"],"Statement of purpose and study plan":["Pernyataan tujuan dan rencana studi","Statement of purpose and study plan","Pernyataan tujuan dan rancangan pengajian","Motivationsschreiben und Studienplan","Tuyên bố mục đích và kế hoạch học tập","目的陈述与学习计划","志望理由書と学習計画"],"All content reflects independent, self-directed work.":["Seluruh konten mencerminkan pekerjaan mandiri yang diarahkan sendiri.","All content reflects independent, self-directed work.","Semua kandungan mencerminkan kerja bebas yang diarahkan sendiri.","Alle Inhalte spiegeln unabhängige, selbstgesteuerte Arbeit wider.","Tất cả nội dung phản ánh công việc độc lập, tự định hướng.","所有内容均反映独立、自主完成的工作。","すべての内容は独立した自己主導の作業を反映しています。"]});

  const languageOrder = ['id','en','ms','de','vi','zh','ja'];
  const indexByLanguage = Object.fromEntries(languageOrder.map((lang, index) => [lang, index]));
  const root = document.documentElement;
  const EMBEDDED = window.self !== window.top;
  const THEME_KEY = 'apu-ui-theme';
  const LANGUAGE_KEY = 'apu-ui-language';
  const LEGACY_THEME_KEYS = ['apu-ui-theme-v5.5','apu-ui-theme-v5.6'];
  const LEGACY_LANGUAGE_KEYS = ['apu-ui-language-v5.5','apu-ui-language-v5.6'];
  const originalText = new WeakMap();
  const originalAttrs = new WeakMap();
  const expectedText = new WeakMap();
  const expectedAttrs = new WeakMap();
  const darkOwners = new WeakSet();
  const translationCache = new Map();
  const translatorPromises = new Map();
  let detectorPromise = null;
  let currentLanguage = LANGUAGES[root.dataset.apuLanguage] ? root.dataset.apuLanguage : 'en';
  let observer = null;
  let applying = false;
  let toastTimer = 0;
  let generation = 0;
  let translationTimer = 0;

  const normalize = value => String(value || '').replace(/\s+/g, ' ').trim();
  const escapeRegExp = value => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  const sourceToCanonical = new Map();
  const sourceLanguage = new Map();
  const sourceEntries = [];
  for (const [canonical, translations] of Object.entries(PHRASES)) {
    [canonical, ...translations].forEach((source, idx) => {
      const clean = normalize(source);
      if (!clean) return;
      const key = clean.toLocaleLowerCase();
      sourceToCanonical.set(key, canonical);
      sourceLanguage.set(key, idx === 0 ? 'en' : languageOrder[idx - 1]);
      sourceEntries.push([clean, canonical]);
    });
  }
  sourceEntries.sort((a,b) => b[0].length - a[0].length);

  const wordSourceToCanonical = new Map();
  for (const [canonical, translations] of Object.entries(WORD_ROWS)) {
    [canonical, ...translations].forEach((source, idx) => {
      const clean = normalize(source).toLocaleLowerCase();
      if (clean && !clean.includes(' ')) wordSourceToCanonical.set(clean, canonical);
    });
  }

  function targetFor(canonical, language) {
    return PHRASES[canonical]?.[indexByLanguage[language] ?? 1] || canonical;
  }
  function wordTargetFor(canonical, language) {
    return WORD_ROWS[canonical]?.[indexByLanguage[language] ?? 1] || canonical;
  }
  function preserveCase(source, target) {
    if (!source || !target) return target;
    if (source === source.toUpperCase() && source.length > 1) return target.toLocaleUpperCase();
    if (source[0] === source[0].toUpperCase()) return target[0]?.toLocaleUpperCase() + target.slice(1);
    return target;
  }
  const APU_OFFLINE_WORDS={id:{"academic":"akademik","evidence":"bukti","hub":"pusat","graduate":"pascasarjana","graduates":"lulusan","admission":"penerimaan","admissions":"penerimaan","reviewer":"peninjau","reviewers":"peninjau","independent":"independen","self-directed":"mandiri","work":"pekerjaan","works":"karya","project":"proyek","projects":"proyek","research":"riset","statement":"pernyataan","study":"studi","plan":"rencana","education":"pendidikan","skill":"keterampilan","skills":"keterampilan","experience":"pengalaman","certificate":"sertifikat","certificates":"sertifikat","credential":"kredensial","credentials":"kredensial","badge":"lencana","badges":"lencana","verified":"terverifikasi","downloadable":"dapat diunduh","download":"unduh","source":"sumber","code":"kode","open":"buka","view":"lihat","profile":"profil","repository":"repositori","repositories":"repositori","software":"perangkat lunak","engineering":"rekayasa","computer":"komputer","science":"sains","artificial":"kecerdasan","intelligence":"buatan","machine":"mesin","learning":"pembelajaran","model":"model","models":"model","data":"data","system":"sistem","systems":"sistem","design":"desain","architecture":"arsitektur","methodology":"metodologi","result":"hasil","results":"hasil","limitation":"keterbatasan","limitations":"keterbatasan","current":"saat ini","completed":"selesai","status":"status","category":"kategori","description":"deskripsi","formal":"resmi","relationship":"hubungan","affiliation":"afiliasi","endorsement":"dukungan resmi","content":"konten","prepared":"disiapkan","program":"program","application":"aplikasi","applications":"aplikasi","motivation":"motivasi","goal":"tujuan","goals":"tujuan","semester":"semester","coursework":"mata kuliah","thesis":"tesis","timeline":"linimasa","proposed":"diusulkan","question":"pertanyaan","questions":"pertanyaan","method":"metode","methods":"metode","preliminary":"awal","document":"dokumen","documents":"dokumen","university":"universitas","universities":"universitas","professional":"profesional","technical":"teknis","complete":"lengkap","full":"lengkap","all":"semua","each":"setiap","with":"dengan","without":"tanpa","for":"untuk","from":"dari","into":"ke dalam","across":"di seluruh","relevant":"relevan","public":"publik","private":"privat","available":"tersedia","created":"dibuat","built":"dibangun","using":"menggunakan","includes":"mencakup","including":"termasuk","covering":"mencakup","demonstrates":"menunjukkan","documentation":"dokumentasi","review":"tinjauan","reviewing":"meninjau","contact":"kontak","overview":"ikhtisar","navigation":"navigasi","main":"utama","explore":"jelajahi","purpose":"tujuan","career":"karier","careers":"karier","country":"negara","countries":"negara","territory":"wilayah","territories":"wilayah","city":"kota","currency":"mata uang","exchange":"pertukaran","rate":"kurs","monthly":"bulanan","annual":"tahunan","yearly":"tahunan","household":"rumah tangga","lifestyle":"gaya hidup","comfortable":"nyaman","income":"pendapatan","estimate":"estimasi","initial":"awal","starting":"awal","sync":"sinkronkan","reset":"atur ulang","cost":"biaya","costs":"biaya","breakdown":"rincian","comparison":"perbandingan","housing":"perumahan","family":"keluarga","health":"kesehatan","savings":"tabungan","information":"informasi","report":"laporan","reports":"laporan","export":"ekspor","print":"cetak","calculator":"kalkulator","location":"lokasi","locations":"lokasi","financial":"finansial","capacity":"kemampuan","workspace":"ruang kerja","local":"lokal","default":"bawaan","preset":"preset","official":"resmi","people":"orang","normal":"normal","frugal":"hemat","premium":"premium","world":"dunia","bank":"bank","ready":"siap","major":"utama","organize":"susun","evaluate":"evaluasi","concise":"ringkas"},en:{"akademik":"academic","bukti":"evidence","pusat":"hub","pascasarjana":"graduate","lulusan":"graduates","penerimaan":"admissions","peninjau":"reviewers","independen":"independent","mandiri":"self-directed","pekerjaan":"work","karya":"works","proyek":"projects","riset":"research","pernyataan":"statement","studi":"study","rencana":"plan","pendidikan":"education","keterampilan":"skills","pengalaman":"experience","sertifikat":"certificates","kredensial":"credentials","lencana":"badges","terverifikasi":"verified","dapat diunduh":"downloadable","unduh":"download","sumber":"source","kode":"code","buka":"open","lihat":"view","profil":"profile","repositori":"repositories","perangkat lunak":"software","rekayasa":"engineering","komputer":"computer","sains":"science","kecerdasan":"artificial","buatan":"intelligence","mesin":"machine","pembelajaran":"learning","sistem":"systems","desain":"design","arsitektur":"architecture","metodologi":"methodology","hasil":"results","keterbatasan":"limitations","saat ini":"current","selesai":"completed","kategori":"category","deskripsi":"description","resmi":"official","hubungan":"relationship","afiliasi":"affiliation","dukungan resmi":"endorsement","konten":"content","disiapkan":"prepared","aplikasi":"applications","motivasi":"motivation","tujuan":"purpose","mata kuliah":"coursework","tesis":"thesis","linimasa":"timeline","diusulkan":"proposed","pertanyaan":"questions","metode":"methods","awal":"starting","dokumen":"documents","universitas":"universities","profesional":"professional","teknis":"technical","lengkap":"full","semua":"all","setiap":"each","dengan":"with","tanpa":"without","untuk":"for","dari":"from","ke dalam":"into","di seluruh":"across","relevan":"relevant","publik":"public","privat":"private","tersedia":"available","dibuat":"created","dibangun":"built","menggunakan":"using","mencakup":"covering","termasuk":"including","menunjukkan":"demonstrates","dokumentasi":"documentation","tinjauan":"review","meninjau":"reviewing","kontak":"contact","ikhtisar":"overview","navigasi":"navigation","utama":"major","jelajahi":"explore","karier":"careers","negara":"countries","wilayah":"territories","kota":"city","mata uang":"currency","pertukaran":"exchange","kurs":"rate","bulanan":"monthly","tahunan":"yearly","rumah tangga":"household","gaya hidup":"lifestyle","nyaman":"comfortable","pendapatan":"income","estimasi":"estimate","sinkronkan":"sync","atur ulang":"reset","biaya":"costs","rincian":"breakdown","perbandingan":"comparison","perumahan":"housing","keluarga":"family","kesehatan":"health","tabungan":"savings","informasi":"information","laporan":"reports","ekspor":"export","cetak":"print","kalkulator":"calculator","lokasi":"locations","finansial":"financial","kemampuan":"capacity","ruang kerja":"workspace","lokal":"local","bawaan":"default","orang":"people","hemat":"frugal","dunia":"world","siap":"ready","susun":"organize","evaluasi":"evaluate","ringkas":"concise"}};
  function applyOfflineWords(value,language){
    const table=APU_OFFLINE_WORDS[language];if(!table)return value;
    return String(value).replace(/[\p{L}][\p{L}-]*/gu,token=>{const hit=table[token.toLocaleLowerCase()];return hit?preserveCase(token,hit):token;});
  }

  function localTranslate(value, language) {
    const raw = String(value ?? '');
    const clean = normalize(raw);
    if (!clean) return raw;
    const exact = sourceToCanonical.get(clean.toLocaleLowerCase());
    if (exact) return raw.replace(clean, targetFor(exact, language));
    let result = raw;
    let replacements = 0;
    if (clean.length <= 700) {
      for (const [source, canonical] of sourceEntries) {
        if (source.length < 3 || replacements >= 18) continue;
        const target = targetFor(canonical, language);
        if (!target || normalize(target).toLocaleLowerCase() === source.toLocaleLowerCase()) continue;
        const wordLike = /^[\p{L}\p{N} .&'’()/%+\-]+$/u.test(source);
        const pattern = wordLike
          ? new RegExp(`(^|[^\\p{L}\\p{N}])(${escapeRegExp(source)})(?=$|[^\\p{L}\\p{N}])`, 'giu')
          : new RegExp(escapeRegExp(source), 'g');
        const next = result.replace(pattern, wordLike ? `$1${target}` : target);
        if (next !== result) { result = next; replacements += 1; }
      }
    }
    result = result.replace(/\p{L}+/gu, token => {
      const canonical = wordSourceToCanonical.get(token.toLocaleLowerCase());
      return canonical ? preserveCase(token, wordTargetFor(canonical, language)) : token;
    });
    result = applyOfflineWords(result, language);
    if (language === 'zh' || language === 'ja') {
      result = result.replace(/([\u3040-\u30ff\u3400-\u9fff])\s+(?=[\u3040-\u30ff\u3400-\u9fff])/g, '$1');
    }
    return result;
  }

  function looksHuman(text) {
    const clean = normalize(text);
    if (!clean || clean.length < 2 || clean.length > 1600) return false;
    if (/^(?:[\d\s.,:%+\-–—/()]+|[A-Z]{2,8}|[A-Z]{3}-\d+)$/.test(clean)) return false;
    if (/^(?:https?:\/\/|mailto:|\/|#)/i.test(clean)) return false;
    if (!/[\p{L}]/u.test(clean)) return false;
    return true;
  }

  function heuristicLanguage(text) {
    const clean = ` ${normalize(text).toLocaleLowerCase()} `;
    if (/[\u3040-\u30ff]/.test(clean)) return 'ja';
    if (/[\u3400-\u9fff]/.test(clean)) return 'zh';
    const groups = {
      id:[' yang ',' dan ',' untuk ',' dengan ',' dari ',' pada ',' ini ',' siswa ',' biaya ',' pilih ',' semua ',' dapat ',' data ',' risiko ',' laporan ',' tampilan '],
      ms:[' yang ',' dan ',' untuk ',' dengan ',' daripada ',' ini ',' pelajar ',' kos ',' pilih ',' semua ',' boleh ',' data ',' risiko ',' laporan ',' paparan '],
      en:[' the ',' and ',' for ',' with ',' from ',' this ',' student ',' cost ',' choose ',' all ',' can ',' data ',' risk ',' report ',' view ',' is ',' are '],
      de:[' der ',' die ',' das ',' und ',' für ',' mit ',' von ',' diese ',' daten ',' risiko ',' bericht ',' wird ',' sind '],
      vi:[' và ',' cho ',' với ',' từ ',' này ',' sinh viên ',' dữ liệu ',' rủi ro ',' báo cáo ',' đang ',' được ']
    };
    let best='en',score=0;
    for (const [lang, words] of Object.entries(groups)) {
      const s=words.reduce((n,w)=>n+(clean.includes(w)?1:0),0);
      if (s>score) {score=s;best=lang;}
    }
    return best;
  }

  const withTimeout = (promise, ms=8000) => Promise.race([promise, new Promise((_,reject)=>setTimeout(()=>reject(new Error('timeout')),ms))]);

  async function getDetector() {
    if (!self.isSecureContext || !('LanguageDetector' in self)) return null;
    if (!detectorPromise) {
      detectorPromise = (async () => {
        try {
          return await withTimeout(LanguageDetector.create({ monitor(monitor) {
            monitor.addEventListener?.('downloadprogress', event => updateTranslationState(true, Math.round((event.loaded || 0) * 100), (UI[currentLanguage]||UI.en).modelDownload));
          }}), 20000);
        } catch (_) { detectorPromise = null; return null; }
      })();
    }
    return detectorPromise;
  }

  async function detectLanguage(text) {
    const clean = normalize(text);
    const exactLang = sourceLanguage.get(clean.toLocaleLowerCase());
    if (exactLang) return exactLang;
    const heuristic = heuristicLanguage(clean);
    try {
      const detector = await getDetector();
      if (detector && clean.length >= 12) {
        const results = await withTimeout(detector.detect(clean.slice(0,600)), 5000);
        const code = results?.[0]?.detectedLanguage?.split('-')[0];
        if (LANGUAGES[code]) return code;
      }
    } catch (_) {}
    return heuristic;
  }

  async function getTranslator(source, target) {
    const normalizedSource = source === 'ms' ? 'id' : source;
    const normalizedTarget = target === 'ms' ? 'id' : target;
    if (!self.isSecureContext || !('Translator' in self) || normalizedSource === normalizedTarget) return null;
    const key = `${normalizedSource}>${normalizedTarget}`;
    if (!translatorPromises.has(key)) {
      const promise = (async () => {
        try {
          const options={sourceLanguage:normalizedSource,targetLanguage:normalizedTarget};
          return await withTimeout(Translator.create({...options, monitor(monitor) {
            monitor.addEventListener?.('downloadprogress', event => updateTranslationState(true, Math.round((event.loaded || 0) * 100), (UI[currentLanguage]||UI.en).modelDownload));
          }}), 25000);
        } catch (_) { translatorPromises.delete(key); return null; }
      })();
      translatorPromises.set(key,promise);
    }
    return translatorPromises.get(key);
  }

  async function smartTranslate(raw, target) {
    const clean = normalize(raw);
    if (!looksHuman(clean)) return raw;
    const cacheKey = `${target}\u0000${clean}`;
    if (translationCache.has(cacheKey)) return translationCache.get(cacheKey);
    const local = localTranslate(raw, target);
    const source = await detectLanguage(clean);
    if (source === target) { translationCache.set(cacheKey, raw); return raw; }
    try {
      const translator = await getTranslator(source, target);
      if (translator) {
        let translatedClean = await withTimeout(translator.translate(clean), 15000);
        if (target === 'ms' && translatedClean) translatedClean = localTranslate(translatedClean, 'ms');
        if (translatedClean && normalize(translatedClean).toLocaleLowerCase() !== clean.toLocaleLowerCase()) {
          const translated = raw.replace(clean, translatedClean);
          translationCache.set(cacheKey, translated);
          return translated;
        }
      }
    } catch (_) {}
    translationCache.set(cacheKey, local);
    return local;
  }

  function shouldSkip(element) {
    return !element || Boolean(element.closest('#apu-ui-dock-v60,#apu-ui-toast-v60,script,style,code,pre,textarea,[contenteditable="true"],[data-apu-no-translate],[translate="no"]'));
  }

  function rememberNode(node) {
    if (!originalText.has(node)) originalText.set(node, node.nodeValue || '');
    return originalText.get(node);
  }
  function rememberAttr(element, attr) {
    if (!originalAttrs.has(element)) originalAttrs.set(element, {});
    const stored=originalAttrs.get(element);
    if (!(attr in stored)) stored[attr]=element.getAttribute(attr);
    return stored[attr];
  }
  function setNodeText(node, value) {
    applying=true;
    try { expectedText.set(node,value); if(node.nodeValue!==value) node.nodeValue=value; }
    finally { applying=false; }
  }
  function setAttr(element, attr, value) {
    applying=true;
    try {
      if(!expectedAttrs.has(element)) expectedAttrs.set(element,{});
      expectedAttrs.get(element)[attr]=value;
      if(element.getAttribute(attr)!==value) element.setAttribute(attr,value);
    } finally { applying=false; }
  }

  function collectTranslatables(container=document.body) {
    const nodes=[], attrs=[];
    if (!container) return {nodes,attrs};
    const rootEl=container.nodeType===Node.ELEMENT_NODE?container:container.parentElement;
    if(!rootEl||shouldSkip(rootEl)) return {nodes,attrs};
    const walker=document.createTreeWalker(rootEl,NodeFilter.SHOW_TEXT,{acceptNode(node){
      const p=node.parentElement,t=normalize(node.nodeValue||'');
      return !shouldSkip(p)&&looksHuman(t)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT;
    }});
    while(walker.nextNode()) nodes.push(walker.currentNode);
    rootEl.querySelectorAll?.('[placeholder],[title],[aria-label],[aria-description],[alt],input[type="button"][value],input[type="submit"][value],input[type="reset"][value]').forEach(element=>{
      if(shouldSkip(element))return;
      ['placeholder','title','aria-label','aria-description','alt','value'].forEach(attr=>{
        if(element.hasAttribute(attr)&&looksHuman(element.getAttribute(attr)))attrs.push([element,attr]);
      });
    });
    return {nodes,attrs};
  }

  async function runPool(items, worker, limit=4) {
    let cursor=0;
    const workers=Array.from({length:Math.min(limit,items.length)},async()=>{
      while(cursor<items.length){const index=cursor++;await worker(items[index],index);}
    });
    await Promise.all(workers);
  }

  async function translateMetadata(target, runId) {
    const entries=[];
    if(!document.documentElement.dataset.apuOriginalTitle) document.documentElement.dataset.apuOriginalTitle=document.title;
    entries.push(['title',document.documentElement.dataset.apuOriginalTitle,null]);
    document.querySelectorAll('meta[name="description"],meta[property="og:title"],meta[property="og:description"],meta[name="twitter:title"],meta[name="twitter:description"]').forEach(meta=>{
      if(!meta.dataset.apuOriginalContent) meta.dataset.apuOriginalContent=meta.content||'';
      entries.push(['meta',meta.dataset.apuOriginalContent,meta]);
    });
    for(const [type,raw,meta] of entries){
      const value=await smartTranslate(raw,target);if(runId!==generation)return;
      if(type==='title')document.title=value;else meta.content=value;
    }
  }

  async function translateAll(container=document.body, runId=generation) {
    const {nodes,attrs}=collectTranslatables(container);
    const total=nodes.length+attrs.length;
    let done=0;
    updateTranslationState(true,0,(UI[currentLanguage]||UI.en).translating);
    await runPool(nodes,async node=>{
      const original=rememberNode(node);
      const immediate=localTranslate(original,currentLanguage);
      if(runId===generation&&node.isConnected)setNodeText(node,immediate);
      const result=await smartTranslate(original,currentLanguage);
      if(runId===generation&&node.isConnected)setNodeText(node,result);
      done++;if(done%8===0)updateTranslationState(true,Math.round(done/Math.max(total,1)*100),(UI[currentLanguage]||UI.en).translating);
    },4);
    await runPool(attrs,async pair=>{
      const [element,attr]=pair, original=rememberAttr(element,attr);
      const immediate=localTranslate(original,currentLanguage);
      if(runId===generation&&element.isConnected)setAttr(element,attr,immediate);
      const result=await smartTranslate(original,currentLanguage);
      if(runId===generation&&element.isConnected)setAttr(element,attr,result);
      done++;
    },4);
    await translateMetadata(currentLanguage,runId);
    if(runId===generation){updateTranslationState(false,100,(UI[currentLanguage]||UI.en).translated);refreshLayout();}
  }

  function persist(key,value,legacy=[]) {try{localStorage.setItem(key,value);legacy.forEach(k=>localStorage.setItem(k,value));}catch(_) {}}
  function updateThemeMeta(theme){let meta=document.querySelector('meta[name="theme-color"]');if(!meta){meta=document.createElement('meta');meta.name='theme-color';document.head.appendChild(meta);}meta.content=theme==='dark'?'#000000':'#ffffff';}
  function ensureThemeEnforcer(){
    if(document.getElementById('apu-theme-enforcer-v60'))return;
    const style=document.createElement('style');style.id='apu-theme-enforcer-v60';style.dataset.apuNoTranslate='true';
    style.textContent=`html[data-apu-theme="dark"],html[data-apu-theme="dark"] body{background-color:#050608!important;color:#f8fafc}html[data-apu-theme="light"],html[data-apu-theme="light"] body{background-color:#f7f8fb!important;color:#111827}`;
    document.head.appendChild(style);
  }
  function syncThemeToApp(theme) {
    const dark=theme==='dark';
    if(dark&&!root.classList.contains('dark'))root.classList.add('dark');
    if(!dark&&root.classList.contains('dark'))root.classList.remove('dark');
    const body=document.body;
    if(body){if(dark&&!body.classList.contains('dark'))body.classList.add('dark');if(!dark&&body.classList.contains('dark'))body.classList.remove('dark');}
    const appRoot=document.getElementById('root');
    if(appRoot){if(dark&&!appRoot.classList.contains('dark'))appRoot.classList.add('dark');if(!dark&&appRoot.classList.contains('dark'))appRoot.classList.remove('dark');}
    document.querySelectorAll('[data-theme],[data-color-mode],[data-mode]').forEach(el=>{
      if(el.hasAttribute('data-theme')&&el.getAttribute('data-theme')!==theme)el.setAttribute('data-theme',theme);
      if(el.hasAttribute('data-color-mode')&&el.getAttribute('data-color-mode')!==theme)el.setAttribute('data-color-mode',theme);
      if(el.hasAttribute('data-mode')&&el.getAttribute('data-mode')!==theme)el.setAttribute('data-mode',theme);
    });
    document.querySelectorAll('#root > *,#root > * > *').forEach(el=>{
      if(!dark&&el.classList.contains('dark')){darkOwners.add(el);el.classList.remove('dark');}
      if(dark&&darkOwners.has(el)&&!el.classList.contains('dark'))el.classList.add('dark');
    });
    root.style.colorScheme=theme;
  }
  function setTheme(theme,announce=false,persistChoice=true){
    const resolved=theme==='dark'?'dark':'light';root.dataset.apuTheme=resolved;root.dataset.apuPalette='native';
    syncThemeToApp(resolved);updateThemeMeta(resolved);if(persistChoice)persist(THEME_KEY,resolved,LEGACY_THEME_KEYS);updateDock();refreshLayout();
    if(announce)showToast((UI[currentLanguage]||UI.en)[resolved==='dark'?'enabledDark':'enabledLight']);
    window.dispatchEvent(new CustomEvent('apu:themechange',{detail:{theme:resolved}}));
  }
  function setLanguage(language,announce=false,persistChoice=true){
    if(!LANGUAGES[language])language='en';currentLanguage=language;root.dataset.apuLanguage=language;root.lang=language;root.dir='ltr';
    if(persistChoice)persist(LANGUAGE_KEY,language,LEGACY_LANGUAGE_KEYS);updateDock();
    if(announce&&self.isSecureContext){getDetector();getTranslator('en',language);getTranslator('id',language);}
    generation++;const runId=generation;
    clearTimeout(translationTimer);translationTimer=setTimeout(()=>translateAll(document.body,runId),10);[450,1400,3200].forEach(delay=>setTimeout(()=>{if(runId===generation)translateAll(document.body,runId);},delay));
    if(announce)showToast((UI[language]||UI.en).changed);
    window.dispatchEvent(new CustomEvent('apu:languagechange',{detail:{language}}));
  }
  function refreshLayout(){requestAnimationFrame(()=>{try{window.ScrollTrigger?.refresh?.(true);}catch(_){}window.dispatchEvent(new Event('resize'));});}
  function gridIcon(){return '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><g fill="currentColor"><circle cx="5" cy="5" r="1.55"/><circle cx="12" cy="5" r="1.55"/><circle cx="19" cy="5" r="1.55"/><circle cx="5" cy="12" r="1.55"/><circle cx="12" cy="12" r="1.55"/><circle cx="19" cy="12" r="1.55"/><circle cx="5" cy="19" r="1.55"/><circle cx="12" cy="19" r="1.55"/><circle cx="19" cy="19" r="1.55"/></g></svg>';}
  function themeIcon(theme){return theme==='dark'?'<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3v2m0 14v2M3 12h2m14 0h2M5.64 5.64l1.42 1.42m9.88 9.88 1.42 1.42m0-12.72-1.42 1.42M7.06 16.94l-1.42 1.42M16.5 12a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>':'<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M20.6 15.7A8.5 8.5 0 0 1 8.3 3.4 8.6 8.6 0 1 0 20.6 15.7Z" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/></svg>';}
  function buildOverlay(){if(document.querySelector('.apu-grid-overlay-v60'))return;const el=document.createElement('div');el.className='apu-grid-overlay-v60';el.setAttribute('aria-hidden','true');document.body.prepend(el);}
  function findMenuMount(){
    const selectors=[
      '[data-apu-controls-slot]',
      'aside nav',
      'aside',
      '[data-sidebar]',
      '.sidebar',
      '[role="navigation"]',
      'nav',
      'header'
    ];
    for(const selector of selectors){
      for(const el of document.querySelectorAll(selector)){
        if(el.closest('#apu-ui-dock-v60,#apu-ui-toast-v60'))continue;
        const style=getComputedStyle(el),rect=el.getBoundingClientRect();
        if(style.display==='none'||style.visibility==='hidden'||rect.width<120||rect.height<30)continue;
        return el;
      }
    }
    return null;
  }
  function mountDockInMenu(dock){
    const mount=findMenuMount();
    if(!mount)return false;
    dock.dataset.apuInline='true';
    dock.dataset.apuMenuMounted='true';
    mount.appendChild(dock);
    return true;
  }
  function buildDock(){
    document.getElementById('apu-ui-dock-v58')?.remove();document.getElementById('apu-ui-toast-v58')?.remove();
    document.getElementById('apu-ui-dock-v57')?.remove();document.getElementById('apu-ui-toast-v57')?.remove();
    document.getElementById('apu-ui-dock-v56')?.remove();document.getElementById('apu-ui-toast-v56')?.remove();
    if(document.getElementById('apu-ui-dock-v60'))return;
    const dock=document.createElement('div');dock.id='apu-ui-dock-v60';dock.role='group';dock.dataset.apuNoTranslate='true';
    const brand=document.createElement('div');brand.className='apu-ui-brand-v60';brand.innerHTML=`${gridIcon()}<span data-apu-brand-label>UI</span>`;
    const theme=document.createElement('button');theme.type='button';theme.className='apu-ui-theme-v60 apu-chunky-v60';theme.dataset.apuAction='theme';theme.onclick=()=>setTheme(root.dataset.apuTheme==='dark'?'light':'dark',true);
    const langWrap=document.createElement('label');langWrap.className='apu-ui-language-wrap-v60 apu-chunky-v60';langWrap.innerHTML='<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.7"/><path d="M3.5 12h17M12 3c2.3 2.5 3.5 5.5 3.5 9S14.3 18.5 12 21c-2.3-2.5-3.5-5.5-3.5-9S9.7 5.5 12 3Z" stroke="currentColor" stroke-width="1.7"/></svg>';
    const select=document.createElement('select');select.className='apu-ui-language-v60';select.dataset.apuAction='language';
    Object.entries(LANGUAGES).forEach(([code,info])=>{const o=document.createElement('option');o.value=code;o.textContent=info.name;select.appendChild(o);});
    select.onchange=e=>setLanguage(e.target.value,true);langWrap.appendChild(select);
    const progress=document.createElement('span');progress.className='apu-translation-progress-v60';progress.dataset.apuProgress='';progress.hidden=true;
    dock.append(brand,theme,langWrap,progress);
    if(!mountDockInMenu(dock))document.body.appendChild(dock);
    const toast=document.createElement('div');toast.id='apu-ui-toast-v60';toast.role='status';toast.setAttribute('aria-live','polite');toast.dataset.apuNoTranslate='true';document.body.appendChild(toast);updateDock();
    if(!dock.dataset.apuMenuMounted){
      let tries=0;
      const relocate=setInterval(()=>{
        tries+=1;
        if(mountDockInMenu(dock)||tries>24)clearInterval(relocate);
      },250);
    }
  }
  function updateDock(){const dock=document.getElementById('apu-ui-dock-v60');if(!dock)return;const ui=UI[currentLanguage]||UI.en,theme=root.dataset.apuTheme==='dark'?'dark':'light';const btn=dock.querySelector('[data-apu-action="theme"]'),sel=dock.querySelector('[data-apu-action="language"]'),label=dock.querySelector('[data-apu-brand-label]');dock.setAttribute('aria-label',ui.group);label.textContent=ui.brand;btn.innerHTML=`${themeIcon(theme)}<span>${ui[theme]}</span>`;btn.title=ui.theme;btn.setAttribute('aria-label',`${ui.theme} — ${ui[theme]}`);btn.setAttribute('aria-pressed',String(theme==='dark'));sel.value=currentLanguage;sel.title=ui.language;sel.setAttribute('aria-label',ui.language);}
  function updateTranslationState(active,percent=0,message=''){const dock=document.getElementById('apu-ui-dock-v60');if(!dock)return;dock.dataset.translating=String(active);dock.setAttribute('aria-busy',String(active));const p=dock.querySelector('[data-apu-progress]');if(p){p.hidden=!active;p.textContent=active?`${Math.max(0,Math.min(100,percent))}%`:'';}if(message&&active&&percent===0)showToast(message);}
  function showToast(message){const toast=document.getElementById('apu-ui-toast-v60');if(!toast)return;clearTimeout(toastTimer);toast.textContent=message;toast.dataset.show='true';toastTimer=setTimeout(()=>toast.dataset.show='false',2200);}
  function removeAiArchitectLocalTheme(){
    if(root.getAttribute('data-scroll-theme')!=='ai-architect')return;
    const selectors=['button[aria-label="Toggle theme"]','button[aria-label*="toggle theme" i]','button[title*="toggle theme" i]','[data-testid*="theme-toggle" i]'];
    selectors.forEach(selector=>document.querySelectorAll(selector).forEach(el=>{if(!el.closest('#apu-ui-dock-v60'))el.remove();}));
  }

  function observe(){observer=new MutationObserver(mutations=>{
    if(applying)return;let target=null,themeNeedsSync=false;
    for(const m of mutations){
      if(m.type==='childList'&&m.addedNodes.length){target=m.target.nodeType===1?m.target:m.target.parentElement;themeNeedsSync=true;}
      if(m.type==='characterData'&&m.target.nodeValue!==expectedText.get(m.target)){originalText.set(m.target,m.target.nodeValue||'');target=m.target.parentElement;}
      if(m.type==='attributes'){const expected=expectedAttrs.get(m.target)?.[m.attributeName];if(m.target.getAttribute(m.attributeName)!==expected){if(originalAttrs.has(m.target))delete originalAttrs.get(m.target)[m.attributeName];target=m.target;}}
    }
    if(themeNeedsSync)syncThemeToApp(root.dataset.apuTheme||'light');
    removeAiArchitectLocalTheme();
    if(target&&!shouldSkip(target)){const runId=++generation;clearTimeout(translationTimer);translationTimer=setTimeout(()=>translateAll(target,runId),80);}
  });observer.observe(document.body,{childList:true,subtree:true,characterData:true,attributes:true,attributeFilter:['placeholder','title','aria-label','aria-description','alt','value']});}
  function bindSync(){
    window.addEventListener('storage',e=>{
      if(e.key===THEME_KEY&&['light','dark'].includes(e.newValue))setTheme(e.newValue,false,false);
      if(e.key===LANGUAGE_KEY&&LANGUAGES[e.newValue])setLanguage(e.newValue,false,false);
    });
    window.addEventListener('message',event=>{
      if(event.origin!==location.origin)return;
      const data=event.data;
      if(!data||data.type!=='apu:viewer-settings')return;
      if(['light','dark'].includes(data.theme))setTheme(data.theme,false,false);
      if(LANGUAGES[data.language])setLanguage(data.language,false,false);
    });
  }
  function init(){
    ensureThemeEnforcer();
    buildOverlay();
    removeAiArchitectLocalTheme();
    [120,500,1400].forEach(delay=>setTimeout(removeAiArchitectLocalTheme,delay));
    if(!EMBEDDED)buildDock();
    setTheme(root.dataset.apuTheme||'light',false,false);
    observe();
    bindSync();
    setLanguage(root.dataset.apuLanguage||'en',false,false);
    root.classList.add('apu-ui-ready-v60');
    if(EMBEDDED){
      try{window.parent.postMessage({type:'apu:project-ready'},location.origin);}catch(_){}
    }
  }
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init,{once:true});else init();
})();
