"""Lightweight internationalization (i18n) for LMM messages.

Supports: ja (default), en, zh, ko, es, hi, fr, bn, ta, te, mr, ur, gu, kn, ml, pa.

Usage:
    from lmm.i18n import t, set_locale

    set_locale("en")
    print(t("solver.no_quantum"))  # "No quantum computer required"
"""

from __future__ import annotations

import os

_LOCALE = os.environ.get("LMM_LANG", "ja")

_MESSAGES: dict[str, dict[str, str]] = {
    # -- Core solver messages --
    "solver.no_quantum": {
        "ja": "量子コンピュータ不要",
        "en": "No quantum computer required",
        "zh": "无需量子计算机",
        "ko": "양자 컴퓨터 불필요",
        "es": "No se requiere computadora cuántica",
        "hi": "क्वांटम कंप्यूटर की आवश्यकता नहीं",
        "fr": "Aucun ordinateur quantique requis",
        "bn": "কোয়ান্টাম কম্পিউটারের প্রয়োজন নেই",
        "ta": "குவாண்டம் கணினி தேவையில்லை",
        "te": "క్వాంటం కంప్యూటర్ అవసరం లేదు",
        "mr": "क्वांटम संगणकाची आवश्यकता नाही",
        "ur": "کوانٹم کمپیوٹر کی ضرورت نہیں",
        "gu": "ક્વોન્ટમ કમ્પ્યુટરની જરૂર નથી",
        "kn": "ಕ್ವಾಂಟಮ್ ಕಂಪ್ಯೂಟರ್ ಅಗತ್ಯವಿಲ್ಲ",
        "ml": "ക്വാണ്ടം കമ്പ്യൂട്ടർ ആവശ്യമില്ല",
        "pa": "ਕੁਆਂਟਮ ਕੰਪਿਊਟਰ ਦੀ ਲੋੜ ਨਹੀਂ",
    },
    "solver.unknown_method": {
        "ja": "不明なソルバー手法: {method}",
        "en": "Unknown solver method: {method}",
        "zh": "未知的求解器方法: {method}",
        "ko": "알 수 없는 솔버 방법: {method}",
        "es": "Método de resolución desconocido: {method}",
        "hi": "अज्ञात सॉल्वर विधि: {method}",
        "fr": "Méthode de résolution inconnue : {method}",
        "bn": "অজানা সলভার পদ্ধতি: {method}",
        "ta": "அறியப்படாத தீர்வு முறை: {method}",
        "te": "తెలియని సాల్వర్ పద్ధతి: {method}",
        "mr": "अज्ञात सोल्व्हर पद्धत: {method}",
        "ur": "نامعلوم سالور طریقہ: {method}",
        "gu": "અજાણી સોલ્વર પદ્ધતિ: {method}",
        "kn": "ಅಜ್ಞಾತ ಸಾಲ್ವರ್ ವಿಧಾನ: {method}",
        "ml": "അജ്ഞാത സോൾവർ രീതി: {method}",
        "pa": "ਅਣਜਾਣ ਸੌਲਵਰ ਵਿਧੀ: {method}",
    },
    "surprise.fit_first": {
        "ja": "先に fit() を呼んでください",
        "en": "Call fit() first",
        "zh": "请先调用 fit()",
        "ko": "먼저 fit()을 호출하세요",
        "es": "Llame a fit() primero",
        "hi": "पहले fit() कॉल करें",
        "fr": "Appelez fit() d'abord",
        "bn": "প্রথমে fit() কল করুন",
        "ta": "முதலில் fit() அழைக்கவும்",
        "te": "ముందుగా fit() కాల్ చేయండి",
        "mr": "आधी fit() कॉल करा",
        "ur": "پہلے fit() کال کریں",
        "gu": "પહેલાં fit() કૉલ કરો",
        "kn": "ಮೊದಲು fit() ಕರೆ ಮಾಡಿ",
        "ml": "ആദ്യം fit() വിളിക്കുക",
        "pa": "ਪਹਿਲਾਂ fit() ਕਾਲ ਕਰੋ",
    },
    "surprise.unknown_method": {
        "ja": "不明なサプライズ手法: {method}",
        "en": "Unknown surprise method: {method}",
        "zh": "未知的惊喜方法: {method}",
        "ko": "알 수 없는 서프라이즈 방법: {method}",
        "es": "Método de sorpresa desconocido: {method}",
        "hi": "अज्ञात सरप्राइज़ विधि: {method}",
        "fr": "Méthode de surprise inconnue : {method}",
        "bn": "অজানা সারপ্রাইজ পদ্ধতি: {method}",
        "ta": "அறியப்படாத சர்ப்ரைஸ் முறை: {method}",
        "te": "తెలియని సర్‌ప్రైజ్ పద్ధతి: {method}",
        "mr": "अज्ञात सरप्राइझ पद्धत: {method}",
        "ur": "نامعلوم سرپرائز طریقہ: {method}",
        "gu": "અજાણી સરપ્રાઇઝ પદ્ધતિ: {method}",
        "kn": "ಅಜ್ಞಾತ ಸರ್‌ಪ್ರೈಸ್ ವಿಧಾನ: {method}",
        "ml": "അജ്ഞാത സർപ്രൈസ് രീതി: {method}",
        "pa": "ਅਣਜਾਣ ਸਰਪ੍ਰਾਈਜ਼ ਵਿਧੀ: {method}",
    },
    # -- Dharma engine messages --
    "dharma.supermodular": {
        "ja": "慈悲 (Karuna) = 超モジュラ関数 — 相乗効果",
        "en": "Karuna (Compassion) = supermodular function — synergy effect",
        "zh": "慈悲 (Karuna) = 超模函数 — 协同效应",
        "ko": "자비 (Karuna) = 초모듈러 함수 — 상승 효과",
        "es": "Karuna (Compasión) = función supermodular — efecto sinérgico",
        "hi": "करुणा (Karuna) = सुपरमॉड्यूलर फ़ंक्शन — सहक्रिया प्रभाव",
        "fr": "Karuna (Compassion) = fonction supermodulaire — effet de synergie",
        "bn": "করুণা (Karuna) = সুপারমডুলার ফাংশন — সমন্বয় প্রভাব",
        "ta": "கருணை (Karuna) = சூப்பர்மாடுலர் செயல்பாடு — ஒருங்கிணைப்பு விளைவு",
        "te": "కరుణ (Karuna) = సూపర్‌మాడ్యులర్ ఫంక్షన్ — సినర్జీ ప్రభావం",
        "mr": "करुणा (Karuna) = सुपरमॉड्युलर फंक्शन — समन्वय प्रभाव",
        "ur": "کرونا (Karuna) = سپرماڈیولر فنکشن — ہم آہنگی اثر",
        "gu": "કરુણા (Karuna) = સુપરમોડ્યુલર ફંક્શન — સિનર્જી અસર",
        "kn": "ಕರುಣಾ (Karuna) = ಸೂಪರ್‌ಮಾಡ್ಯುಲರ್ ಫಂಕ್ಷನ್ — ಸಿನರ್ಜಿ ಪರಿಣಾಮ",
        "ml": "കരുണ (Karuna) = സൂപ്പർമോഡുലാർ ഫങ്ഷൻ — സിനർജി പ്രഭാവം",
        "pa": "ਕਰੁਣਾ (Karuna) = ਸੁਪਰਮੌਡਿਊਲਰ ਫੰਕਸ਼ਨ — ਸਿਨਰਜੀ ਪ੍ਰਭਾਵ",
    },
    "dharma.submodular": {
        "ja": "持戒 (Sila) = 劣モジュラ関数 — 限界効用逓減",
        "en": "Sila (Conduct) = submodular function — diminishing returns",
        "zh": "持戒 (Sila) = 子模函数 — 边际效用递减",
        "ko": "지계 (Sila) = 서브모듈러 함수 — 한계 효용 체감",
        "es": "Sila (Conducta) = función submodular — rendimientos decrecientes",
        "hi": "शील (Sila) = सबमॉड्यूलर फ़ंक्शन — ह्रासमान प्रतिफल",
        "fr": "Sila (Conduite) = fonction sous-modulaire — rendements décroissants",
        "bn": "শীল (Sila) = সাবমডুলার ফাংশন — ক্রমহ্রাসমান প্রতিদান",
        "ta": "சீலம் (Sila) = சப்மாடுலர் செயல்பாடு — குறைந்துவரும் வருவாய்",
        "te": "శీలం (Sila) = సబ్‌మాడ్యులర్ ఫంక్షన్ — తగ్గుతున్న రాబడి",
        "mr": "शील (Sila) = सबमॉड्युलर फंक्शन — ह्रासमान परतावा",
        "ur": "سیلا (Sila) = سب ماڈیولر فنکشن — کم ہوتا منافع",
        "gu": "શીલ (Sila) = સબમોડ્યુલર ફંક્શન — ઘટતું વળતર",
        "kn": "ಶೀಲ (Sila) = ಸಬ್‌ಮಾಡ್ಯುಲರ್ ಫಂಕ್ಷನ್ — ಕ್ಷೀಣಿಸುವ ಲಾಭ",
        "ml": "ശീലം (Sila) = സബ്‌മോഡുലാർ ഫങ്ഷൻ — കുറയുന്ന വരുമാനം",
        "pa": "ਸ਼ੀਲ (Sila) = ਸਬਮੌਡਿਊਲਰ ਫੰਕਸ਼ਨ — ਘਟਦਾ ਮੁਨਾਫ਼ਾ",
    },
    "dharma.middle_way": {
        "ja": "中道 (Madhyamaka) = カオスの縁 (CV = 0.5)",
        "en": "Madhyamaka (Middle Way) = edge of chaos (CV = 0.5)",
        "zh": "中道 (Madhyamaka) = 混沌边缘 (CV = 0.5)",
        "ko": "중도 (Madhyamaka) = 혼돈의 가장자리 (CV = 0.5)",
        "es": "Madhyamaka (Camino Medio) = borde del caos (CV = 0.5)",
        "hi": "मध्यमक (मध्य मार्ग) = अराजकता का किनारा (CV = 0.5)",
        "fr": "Madhyamaka (Voie du Milieu) = bord du chaos (CV = 0.5)",
        "bn": "মধ্যমক (মধ্যপথ) = বিশৃঙ্খলার প্রান্ত (CV = 0.5)",
        "ta": "மத்யமகா (நடுவழி) = குழப்பத்தின் விளிம்பு (CV = 0.5)",
        "te": "మధ్యమక (మధ్యమార్గం) = అస్తవ్యస్తత అంచు (CV = 0.5)",
        "mr": "मध्यमक (मध्य मार्ग) = अराजकतेची धार (CV = 0.5)",
        "ur": "مدھیمکا (درمیانی راستہ) = افراتفری کا کنارہ (CV = 0.5)",
        "gu": "મધ્યમક (મધ્ય માર્ગ) = અરાજકતાની ધાર (CV = 0.5)",
        "kn": "ಮಧ್ಯಮಕ (ಮಧ್ಯಮ ಮಾರ್ಗ) = ಅವ್ಯವಸ್ಥೆಯ ಅಂಚು (CV = 0.5)",
        "ml": "മധ്യമക (മധ്യമാർഗം) = അരാജകത്വത്തിന്റെ വക്ക് (CV = 0.5)",
        "pa": "ਮੱਧਮਕ (ਮੱਧ ਮਾਰਗ) = ਅਰਾਜਕਤਾ ਦਾ ਕਿਨਾਰਾ (CV = 0.5)",
    },
    # -- Reasoning mode names --
    "mode.adaptive": {
        "ja": "応病与薬 — 器に合わせて変化する",
        "en": "Adaptive — medicine fit to illness",
        "zh": "应病与药 — 对症下药",
        "ko": "응병여약 — 병에 맞는 처방",
        "es": "Adaptivo — medicina ajustada a la enfermedad",
        "hi": "अनुकूली — रोग के अनुसार औषधि",
        "fr": "Adaptatif — remède adapté à la maladie",
        "bn": "অভিযোজিত — রোগ অনুসারে ওষুধ",
        "ta": "தகவமைப்பு — நோய்க்கேற்ற மருந்து",
        "te": "అనుకూల — వ్యాధికి తగిన ఔషధం",
        "mr": "अनुकूली — रोगानुसार औषध",
        "ur": "موافق — بیماری کے مطابق دوا",
        "gu": "અનુકૂલનશીલ — રોગ અનુસાર ઔષધ",
        "kn": "ಹೊಂದಾಣಿಕೆ — ರೋಗಕ್ಕೆ ತಕ್ಕ ಔಷಧ",
        "ml": "അനുയോജ്യ — രോഗത്തിനനുസരിച്ച ഔഷധം",
        "pa": "ਅਨੁਕੂਲ — ਰੋਗ ਅਨੁਸਾਰ ਦਵਾਈ",
    },
    "mode.theoretical": {
        "ja": "因明 — 仏教論理学",
        "en": "Theoretical — Buddhist formal logic (Hetuvidyā)",
        "zh": "因明 — 佛教逻辑学",
        "ko": "인명 — 불교 논리학",
        "es": "Teórico — lógica formal budista (Hetuvidyā)",
        "hi": "हेतुविद्या — बौद्ध तर्कशास्त्र",
        "fr": "Théorique — logique formelle bouddhiste (Hetuvidyā)",
        "bn": "হেতুবিদ্যা — বৌদ্ধ আনুষ্ঠানিক তর্কশাস্ত্র",
        "ta": "ஹேதுவித்யா — பௌத்த முறையான தருக்கவியல்",
        "te": "హేతువిద్య — బౌద్ధ తార్కిక శాస్త్రం",
        "mr": "हेतुविद्या — बौद्ध तर्कशास्त्र",
        "ur": "ہیتوودیا — بدھ مت کی رسمی منطق",
        "gu": "હેતુવિદ્યા — બૌદ્ધ ઔપચારિક તર્કશાસ્ત્ર",
        "kn": "ಹೇತುವಿದ್ಯಾ — ಬೌದ್ಧ ಔಪಚಾರಿಕ ತರ್ಕಶಾಸ್ತ್ರ",
        "ml": "ഹേതുവിദ്യ — ബുദ്ധമത ഔപചാരിക തർക്കശാസ്ത്രം",
        "pa": "ਹੇਤੁਵਿਦਿਆ — ਬੋਧੀ ਰਸਮੀ ਤਰਕ ਸ਼ਾਸਤਰ",
    },
    "mode.hyper": {
        "ja": "般若の飛躍 — 直感的仮説生成",
        "en": "Abductive — Prajna's intuitive leap",
        "zh": "般若飞跃 — 直觉假设生成",
        "ko": "반야의 비약 — 직관적 가설 생성",
        "es": "Abductivo — salto intuitivo de Prajna",
        "hi": "प्रज्ञा की छलांग — अंतर्ज्ञानी परिकल्पना",
        "fr": "Abductif — saut intuitif de Prajna",
        "bn": "প্রজ্ঞার লাফ — স্বজ্ঞাত অনুমান",
        "ta": "பிரஜ்ஞாவின் பாய்ச்சல் — உள்ளுணர்வு கருதுகோள்",
        "te": "ప్రజ్ఞ యొక్క దూకుడు — అంతర్ దృష్టి పరికల్పన",
        "mr": "प्रज्ञेची उडी — अंतर्ज्ञानी परिकल्पना",
        "ur": "پرجنا کی چھلانگ — وجدانی مفروضہ",
        "gu": "પ્રજ્ઞાની છલાંગ — અંતર્જ્ઞાની પરિકલ્પના",
        "kn": "ಪ್ರಜ್ಞಾ ಜಿಗಿತ — ಅಂತಃಪ್ರಜ್ಞೆಯ ಊಹೆ",
        "ml": "പ്രജ്ഞയുടെ കുതിച്ചുചാട്ടം — അന്തർജ്ഞാന സിദ്ധാന്തം",
        "pa": "ਪ੍ਰਜਨਾ ਦੀ ਛਾਲ — ਅੰਤਰਗਿਆਨੀ ਪਰਿਕਲਪਨਾ",
    },
    "mode.active": {
        "ja": "托鉢 — 外の真理を求める",
        "en": "Active Inference — seeking external truth",
        "zh": "托钵 — 寻求外在真理",
        "ko": "탁발 — 외부 진리 탐구",
        "es": "Inferencia activa — buscando la verdad externa",
        "hi": "पिण्डपात — बाह्य सत्य की खोज",
        "fr": "Inférence active — recherche de la vérité extérieure",
        "bn": "পিণ্ডপাত — বাহ্যিক সত্য অন্বেষণ",
        "ta": "பிண்டபாதம் — வெளிப்புற உண்மை தேடல்",
        "te": "పిండపాతం — బాహ్య సత్యం అన్వేషణ",
        "mr": "पिंडपात — बाह्य सत्याचा शोध",
        "ur": "پنڈپات — بیرونی سچائی کی تلاش",
        "gu": "પિંડપાત — બાહ્ય સત્યની શોધ",
        "kn": "ಪಿಂಡಪಾತ — ಬಾಹ್ಯ ಸತ್ಯದ ಹುಡುಕಾಟ",
        "ml": "പിണ്ഡപാതം — ബാഹ്യ സത്യാന്വേഷണം",
        "pa": "ਪਿੰਡਪਾਤ — ਬਾਹਰੀ ਸੱਚ ਦੀ ਖੋਜ",
    },
    "mode.alaya": {
        "ja": "阿頼耶識 — 蔵識の記憶",
        "en": "Alaya Memory — storehouse consciousness",
        "zh": "阿赖耶识 — 藏识记忆",
        "ko": "아뢰야식 — 장식의 기억",
        "es": "Memoria Alaya — consciencia almacén",
        "hi": "आलय-विज्ञान — भंडार चेतना",
        "fr": "Mémoire Alaya — conscience entrepôt",
        "bn": "আলয়-বিজ্ঞান — ভাণ্ডার চেতনা",
        "ta": "ஆலய-விஞ்ஞானம் — களஞ்சிய உணர்வு",
        "te": "ఆలయ-విజ్ఞానం — భాండాగార చైతన్యం",
        "mr": "आलय-विज्ञान — भांडार चेतना",
        "ur": "آلیہ وجنان — گودام شعور",
        "gu": "આલય-વિજ્ઞાન — ભંડાર ચેતના",
        "kn": "ಆಲಯ-ವಿಜ್ಞಾನ — ಉಗ್ರಾಣ ಪ್ರಜ್ಞೆ",
        "ml": "ആലയ-വിജ്ഞാനം — ഭണ്ഡാര ബോധം",
        "pa": "ਆਲਯ-ਵਿਗਿਆਨ — ਭੰਡਾਰ ਚੇਤਨਾ",
    },
    "mode.sleep": {
        "ja": "禅定 — 記憶の統合・圧縮",
        "en": "Sleep — NREM/REM memory consolidation",
        "zh": "禅定 — 记忆整合与压缩",
        "ko": "선정 — 기억 통합 및 압축",
        "es": "Sueño — consolidación de memoria NREM/REM",
        "hi": "ध्यान — NREM/REM स्मृति समेकन",
        "fr": "Sommeil — consolidation de mémoire NREM/REM",
        "bn": "ধ্যান — NREM/REM স্মৃতি সুসংহতকরণ",
        "ta": "தியானம் — NREM/REM நினைவக ஒருங்கிணைப்பு",
        "te": "ధ్యానం — NREM/REM జ్ఞాపక సుసంఘటనం",
        "mr": "ध्यान — NREM/REM स्मृती एकत्रीकरण",
        "ur": "دھیان — NREM/REM یادداشت کا استحکام",
        "gu": "ધ્યાન — NREM/REM સ્મૃતિ એકીકરણ",
        "kn": "ಧ್ಯಾನ — NREM/REM ಸ್ಮೃತಿ ಕ್ರೋಡೀಕರಣ",
        "ml": "ധ്യാനം — NREM/REM സ്മൃതി ഏകീകരണം",
        "pa": "ਧਿਆਨ — NREM/REM ਯਾਦ ਏਕੀਕਰਨ",
    },
    "mode.embodied": {
        "ja": "六根 — 六つの感覚統合",
        "en": "Embodied — six sense modalities",
        "zh": "六根 — 六感统合",
        "ko": "육근 — 여섯 감각의 통합",
        "es": "Encarnado — seis modalidades sensoriales",
        "hi": "षड्-इन्द्रिय — छह इन्द्रिय विधाएँ",
        "fr": "Incarné — six modalités sensorielles",
        "bn": "ষড়-ইন্দ্রিয় — ছয়টি ইন্দ্রিয় রূপ",
        "ta": "ஆறு-இந்திரியங்கள் — ஆறு புலன் முறைகள்",
        "te": "షడ్-ఇంద్రియాలు — ఆరు ఇంద్రియ విధానాలు",
        "mr": "षड्-इंद्रिय — सहा इंद्रिय पद्धती",
        "ur": "شش-حواس — چھ حسی طریقے",
        "gu": "ષડ્-ઇન્દ્રિય — છ ઇન્દ્રિય પદ્ધતિઓ",
        "kn": "ಷಡ್-ಇಂದ್ರಿಯ — ಆರು ಇಂದ್ರಿಯ ವಿಧಾನಗಳು",
        "ml": "ഷഡ്-ഇന്ദ്രിയം — ആറ് ഇന്ദ്രിയ രീതികൾ",
        "pa": "ਛੇ-ਇੰਦਰੀਆਂ — ਛੇ ਇੰਦਰੀ ਵਿਧੀਆਂ",
    },
    "mode.pineal": {
        "ja": "松果体 — 量子意識",
        "en": "Pineal — quantum consciousness (hardware TRNG)",
        "zh": "松果体 — 量子意识",
        "ko": "송과체 — 양자 의식",
        "es": "Pineal — consciencia cuántica (TRNG por hardware)",
        "hi": "पीनियल — क्वांटम चेतना (हार्डवेयर TRNG)",
        "fr": "Pinéale — conscience quantique (TRNG matériel)",
        "bn": "পিনিয়াল — কোয়ান্টাম চেতনা (হার্ডওয়্যার TRNG)",
        "ta": "பீனியல் — குவாண்டம் உணர்வு (வன்பொருள் TRNG)",
        "te": "పీనియల్ — క్వాంటం చైతన్యం (హార్డ్‌వేర్ TRNG)",
        "mr": "पिनियल — क्वांटम चेतना (हार्डवेअर TRNG)",
        "ur": "پائنل — کوانٹم شعور (ہارڈویئر TRNG)",
        "gu": "પિનિયલ — ક્વોન્ટમ ચેતના (હાર્ડવેર TRNG)",
        "kn": "ಪೀನಿಯಲ್ — ಕ್ವಾಂಟಮ್ ಪ್ರಜ್ಞೆ (ಹಾರ್ಡ್‌ವೇರ್ TRNG)",
        "ml": "പീനിയൽ — ക്വാണ്ടം ബോധം (ഹാർഡ്‌വെയർ TRNG)",
        "pa": "ਪੀਨੀਅਲ — ਕੁਆਂਟਮ ਚੇਤਨਾ (ਹਾਰਡਵੇਅਰ TRNG)",
    },
    # -- CLI messages --
    "cli.demo_running": {
        "ja": "デモ実行中...",
        "en": "Running demo...",
        "zh": "运行演示中...",
        "ko": "데모 실행 중...",
        "es": "Ejecutando demo...",
        "hi": "डेमो चल रहा है...",
        "fr": "Exécution de la démo...",
        "bn": "ডেমো চলছে...",
        "ta": "டெமோ இயங்குகிறது...",
        "te": "డెమో నడుస్తోంది...",
        "mr": "डेमो चालू आहे...",
        "ur": "ڈیمو چل رہا ہے...",
        "gu": "ડેમો ચાલી રહ્યો છે...",
        "kn": "ಡೆಮೋ ಚಾಲನೆಯಲ್ಲಿದೆ...",
        "ml": "ഡെമോ പ്രവർത്തിക്കുന്നു...",
        "pa": "ਡੈਮੋ ਚੱਲ ਰਿਹਾ ਹੈ...",
    },
    "cli.selected": {
        "ja": "選択されたインデックス: {indices}",
        "en": "Selected indices: {indices}",
        "zh": "选定的索引: {indices}",
        "ko": "선택된 인덱스: {indices}",
        "es": "Índices seleccionados: {indices}",
        "hi": "चयनित सूचकांक: {indices}",
        "fr": "Indices sélectionnés : {indices}",
        "bn": "নির্বাচিত সূচক: {indices}",
        "ta": "தேர்ந்தெடுக்கப்பட்ட குறியீடுகள்: {indices}",
        "te": "ఎంపిక చేసిన సూచికలు: {indices}",
        "mr": "निवडलेले अनुक्रमांक: {indices}",
        "ur": "منتخب اشاریے: {indices}",
        "gu": "પસંદ કરેલા અનુક્રમણિકાઓ: {indices}",
        "kn": "ಆಯ್ಕೆಮಾಡಿದ ಸೂಚ್ಯಂಕಗಳು: {indices}",
        "ml": "തിരഞ്ഞെടുത്ത സൂചികകൾ: {indices}",
        "pa": "ਚੁਣੇ ਹੋਏ ਸੂਚਕਾਂਕ: {indices}",
    },
    # -- Server messages --
    "server.starting": {
        "ja": "自動降臨サーバー起動中",
        "en": "Starting auto-descent server",
        "zh": "自动降临服务器启动中",
        "ko": "자동 강림 서버 시작 중",
        "es": "Iniciando servidor de descenso automático",
        "hi": "स्वचालित अवतरण सर्वर शुरू हो रहा है",
        "fr": "Démarrage du serveur de descente automatique",
        "bn": "স্বয়ংক্রিয় অবতরণ সার্ভার শুরু হচ্ছে",
        "ta": "தானியங்கி அவதரண சேவையகம் தொடங்குகிறது",
        "te": "ఆటో-డిసెంట్ సర్వర్ ప్రారంభమవుతోంది",
        "mr": "स्वयंचलित अवतरण सर्व्हर सुरू होत आहे",
        "ur": "خودکار نزول سرور شروع ہو رہا ہے",
        "gu": "ઑટો-ડિસેન્ટ સર્વર શરૂ થઈ રહ્યું છે",
        "kn": "ಆಟೋ-ಡಿಸೆಂಟ್ ಸರ್ವರ್ ಪ್ರಾರಂಭವಾಗುತ್ತಿದೆ",
        "ml": "ഓട്ടോ-ഡിസെന്റ് സെർവർ ആരംഭിക്കുന്നു",
        "pa": "ਆਟੋ-ਡਿਸੈਂਟ ਸਰਵਰ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ",
    },
    "server.api_key_required": {
        "ja": "Claude または Gemini の API キーが必要です",
        "en": "At least one API key (Claude or Gemini) is required",
        "zh": "至少需要一个 API 密钥（Claude 或 Gemini）",
        "ko": "최소 하나의 API 키(Claude 또는 Gemini)가 필요합니다",
        "es": "Se requiere al menos una clave API (Claude o Gemini)",
        "hi": "कम से कम एक API कुंजी (Claude या Gemini) आवश्यक है",
        "fr": "Au moins une clé API (Claude ou Gemini) est requise",
        "bn": "কমপক্ষে একটি API কী (Claude বা Gemini) প্রয়োজন",
        "ta": "குறைந்தது ஒரு API விசை (Claude அல்லது Gemini) தேவை",
        "te": "కనీసం ఒక API కీ (Claude లేదా Gemini) అవసరం",
        "mr": "किमान एक API की (Claude किंवा Gemini) आवश्यक आहे",
        "ur": "کم از کم ایک API کلید (Claude یا Gemini) ضروری ہے",
        "gu": "ઓછામાં ઓછી એક API કી (Claude અથવા Gemini) જરૂરી છે",
        "kn": "ಕನಿಷ್ಠ ಒಂದು API ಕೀ (Claude ಅಥವಾ Gemini) ಅಗತ್ಯ",
        "ml": "കുറഞ്ഞത് ഒരു API കീ (Claude അല്ലെങ്കിൽ Gemini) ആവശ്യമാണ്",
        "pa": "ਘੱਟੋ-ਘੱਟ ਇੱਕ API ਕੁੰਜੀ (Claude ਜਾਂ Gemini) ਲੋੜੀਂਦੀ ਹੈ",
    },
    # -- Warnings --
    "warn.brute_force_knn": {
        "ja": "n={n:,} でブルートフォース k-NN は O(n²) です。hnswlib をインストールしてください: pip install hnswlib",
        "en": "Brute-force k-NN with n={n:,} is O(n²). Install hnswlib for O(n*log(n)): pip install hnswlib",
        "zh": "n={n:,} 的暴力 k-NN 是 O(n²)。安装 hnswlib 以获得 O(n*log(n)): pip install hnswlib",
        "ko": "n={n:,}에서 브루트포스 k-NN은 O(n²)입니다. O(n*log(n))을 위해 hnswlib를 설치하세요: pip install hnswlib",
        "es": "k-NN por fuerza bruta con n={n:,} es O(n²). Instale hnswlib: pip install hnswlib",
        "hi": "n={n:,} के साथ ब्रूट-फ़ोर्स k-NN O(n²) है। hnswlib इंस्टॉल करें: pip install hnswlib",
        "fr": "k-NN par force brute avec n={n:,} est O(n²). Installez hnswlib : pip install hnswlib",
        "bn": "n={n:,} সহ ব্রুট-ফোর্স k-NN হল O(n²)। hnswlib ইনস্টল করুন: pip install hnswlib",
        "ta": "n={n:,} உடன் ப்ரூட்-ஃபோர்ஸ் k-NN O(n²) ஆகும். hnswlib நிறுவுக: pip install hnswlib",
        "te": "n={n:,} తో బ్రూట్-ఫోర్స్ k-NN O(n²). hnswlib ఇన్‌స్టాల్ చేయండి: pip install hnswlib",
        "mr": "n={n:,} सह ब्रूट-फोर्स k-NN O(n²) आहे. hnswlib इंस्टॉल करा: pip install hnswlib",
        "ur": "n={n:,} کے ساتھ بروٹ-فورس k-NN O(n²) ہے۔ hnswlib انسٹال کریں: pip install hnswlib",
        "gu": "n={n:,} સાથે બ્રુટ-ફોર્સ k-NN O(n²) છે. hnswlib ઇન્સ્ટોલ કરો: pip install hnswlib",
        "kn": "n={n:,} ನೊಂದಿಗೆ ಬ್ರೂಟ್-ಫೋರ್ಸ್ k-NN O(n²). hnswlib ಅನುಸ್ಥಾಪಿಸಿ: pip install hnswlib",
        "ml": "n={n:,} ഉള്ള ബ്രൂട്ട്-ഫോഴ്‌സ് k-NN O(n²) ആണ്. hnswlib ഇൻസ്റ്റാൾ ചെയ്യുക: pip install hnswlib",
        "pa": "n={n:,} ਨਾਲ ਬਰੂਟ-ਫੋਰਸ k-NN O(n²) ਹੈ। hnswlib ਇੰਸਟਾਲ ਕਰੋ: pip install hnswlib",
    },
    # -- Ising SA --
    "warn.hnswlib_missing": {
        "ja": "hnswlib が見つかりません。ランダム射影近似 k-NN にフォールバックします",
        "en": "hnswlib not found. Falling back to random-projection approximate k-NN",
        "zh": "未找到 hnswlib。回退到随机投影近似 k-NN",
        "ko": "hnswlib을 찾을 수 없습니다. 랜덤 프로젝션 근사 k-NN으로 대체합니다",
        "es": "hnswlib no encontrado. Usando k-NN aproximado por proyección aleatoria",
        "hi": "hnswlib नहीं मिला। रैंडम प्रोजेक्शन अनुमानित k-NN पर वापस जा रहा है",
        "fr": "hnswlib introuvable. Repli sur k-NN approximatif par projection aléatoire",
        "bn": "hnswlib পাওয়া যায়নি। র‍্যান্ডম প্রজেকশন আনুমানিক k-NN-এ ফলব্যাক করা হচ্ছে",
        "ta": "hnswlib கிடைக்கவில்லை. ரேண்டம் ப்ரொஜெக்ஷன் தோராய k-NN க்கு மாறுகிறது",
        "te": "hnswlib కనుగొనబడలేదు. రాండమ్ ప్రొజెక్షన్ అంచనా k-NN కి ఫాల్‌బ్యాక్",
        "mr": "hnswlib सापडले नाही. रँडम प्रोजेक्शन अंदाजे k-NN वर फॉलबॅक",
        "ur": "hnswlib نہیں ملا۔ رینڈم پروجیکشن تخمینی k-NN پر واپسی",
        "gu": "hnswlib મળ્યું નથી. રેન્ડમ પ્રોજેક્શન અંદાજિત k-NN પર ફૉલબેક",
        "kn": "hnswlib ಕಂಡುಬಂದಿಲ್ಲ. ಯಾದೃಚ್ಛಿಕ ಪ್ರೊಜೆಕ್ಷನ್ ಅಂದಾಜು k-NN ಗೆ ಫಾಲ್‌ಬ್ಯಾಕ್",
        "ml": "hnswlib കണ്ടെത്തിയില്ല. റാൻഡം പ്രൊജക്ഷൻ ഏകദേശ k-NN ലേക്ക് ഫോൾബാക്ക്",
        "pa": "hnswlib ਨਹੀਂ ਮਿਲਿਆ। ਰੈਂਡਮ ਪ੍ਰੋਜੈਕਸ਼ਨ ਅਨੁਮਾਨਿਤ k-NN ਤੇ ਫਾਲਬੈਕ",
    },
}


def set_locale(locale: str) -> None:
    """Set the global locale for LMM messages."""
    global _LOCALE
    _LOCALE = locale


def get_locale() -> str:
    """Get the current locale."""
    return _LOCALE


def t(key: str, **kwargs) -> str:
    """Translate a message key to the current locale.

    Falls back to English, then to the key itself if no translation found.
    """
    msg_dict = _MESSAGES.get(key)
    if msg_dict is None:
        return key
    msg = msg_dict.get(_LOCALE) or msg_dict.get("en", key)
    if kwargs:
        try:
            return msg.format(**kwargs)
        except (KeyError, IndexError):
            return msg
    return msg


def available_locales() -> list[str]:
    """Return all supported locale codes."""
    return ["ja", "en", "zh", "ko", "es", "hi", "fr", "bn", "ta", "te", "mr", "ur", "gu", "kn", "ml", "pa"]
