#!/usr/bin/env python3
"""Generate translated XLIFF files for nb, sv, da, de."""

import re, os

# Base path
BASE = "/Users/rune/Code/Swift/oAI/Locales/oAI Localizations"

# Translations: key -> {lang: translation}
# None means "keep source as-is"
T = {
    # --- keep as-is (None = copy source) ---
    "%@": None,
    "%@ min": None,
    "%@ pt": None,
    "%@s": None,
    "Branch: %@": None,
    "Remote: %@": None,
    "Bash Execution": None,
    "Model Context Protocol": None,
    "SSH Key": None,
    "OpenAI (text-embedding-3-large)": None,
    "OpenAI (text-embedding-3-small)": None,
    "OpenRouter (OpenAI large)": None,
    "OpenRouter (OpenAI small)": None,
    "OpenRouter (Qwen 8B)": None,
    "OpenRouter Credits": None,
    "OpenAI Balance": None,
    "Anthropic Balance": None,
    "Ollama (Local)": None,
    "Google (Gemini embedding)": None,
    "oAI": None,
    "tokens": None,
    "v%@": None,
    "Version %@ (%@)": None,
    "↑↓ navigate  ↩ open": None,
    "⌘N New • ⌘M Model • ⌘S Save": None,
    "Built with SwiftUI": None,
    "Example: oai-bot-x7k2m9p3@gmail.com": None,
    "© 2026 [Rune Olsen](https://blog.rune.pm)": None,
    "[GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl-3.0.html)": None,
    "Username + Password": None,
    "•": None,
    "🌐": None,
    "🎨": None,
    "👁️": None,
    "🔧": None,
    # The skill example template — keep as English (it's instructional content)
    "# When reviewing code, always:\n- Check for security vulnerabilities\n- Verify error handling\n- Suggest tests for edge cases": None,
    "Access Token": None,

    # --- translated strings ---
    "%@ active — injected into every conversation": {
        "nb": "%@ aktiv — injisert i alle samtaler",
        "sv": "%@ aktiv — injiceras i alla konversationer",
        "da": "%@ aktiv — injiceres i alle samtaler",
        "de": "%@ aktiv — in jedes Gespräch eingefügt",
    },
    "%@ chars": {
        "nb": "%@ tegn",
        "sv": "%@ tecken",
        "da": "%@ tegn",
        "de": "%@ Zeichen",
    },
    "(always used)": {
        "nb": "(alltid brukt)",
        "sv": "(används alltid)",
        "da": "(altid brugt)",
        "de": "(immer verwendet)",
    },
    "(optional)": {
        "nb": "(valgfri)",
        "sv": "(valfri)",
        "da": "(valgfri)",
        "de": "(optional)",
    },
    "1. Open Paperless-NGX → Settings → API Tokens": {
        "nb": "1. Åpne Paperless-NGX → Innstillinger → API-tokens",
        "sv": "1. Öppna Paperless-NGX → Inställningar → API-tokens",
        "da": "1. Åbn Paperless-NGX → Indstillinger → API-tokens",
        "de": "1. Paperless-NGX öffnen → Einstellungen → API-Tokens",
    },
    "2. Create or copy your token": {
        "nb": "2. Opprett eller kopier tokenet ditt",
        "sv": "2. Skapa eller kopiera din token",
        "da": "2. Opret eller kopier dit token",
        "de": "2. Token erstellen oder kopieren",
    },
    "3. Paste it above": {
        "nb": "3. Lim det inn ovenfor",
        "sv": "3. Klistra in det ovan",
        "da": "3. Indsæt det ovenfor",
        "de": "3. Oben einfügen",
    },
    "A shortcut with command %@ already exists.": {
        "nb": "En snarvei med kommandoen %@ finnes allerede.",
        "sv": "En genväg med kommandot %@ finns redan.",
        "da": "En genvej med kommandoen %@ findes allerede.",
        "de": "Eine Verknüpfung mit dem Befehl %@ existiert bereits.",
    },
    "API keys and credentials are **not** included in the backup. You will need to re-enter them after restoring on a new machine.": {
        "nb": "API-nøkler og legitimasjon er **ikke** inkludert i sikkerhetskopien. Du må taste dem inn på nytt etter gjenoppretting på en ny maskin.",
        "sv": "API-nycklar och inloggningsuppgifter ingår **inte** i säkerhetskopian. Du måste ange dem igen efter återställning på en ny dator.",
        "da": "API-nøgler og legitimationsoplysninger er **ikke** inkluderet i sikkerhedskopien. Du skal indtaste dem igen efter gendannelse på en ny maskine.",
        "de": "API-Schlüssel und Zugangsdaten sind **nicht** in der Sicherung enthalten. Du musst sie nach der Wiederherstellung auf einem neuen Gerät erneut eingeben.",
    },
    "Active": {
        "nb": "Aktiv",
        "sv": "Aktiv",
        "da": "Aktiv",
        "de": "Aktiv",
    },
    "Active skills are appended to the system prompt. Toggle them per-skill to control what the AI knows.": {
        "nb": "Aktive ferdigheter legges til systemprompten. Slå dem av og på per ferdighet for å kontrollere hva KI-en vet.",
        "sv": "Aktiva färdigheter läggs till i systemprompten. Aktivera/inaktivera dem per färdighet för att kontrollera vad AI:n känner till.",
        "da": "Aktive færdigheder tilføjes til systemprompten. Slå dem til og fra per færdighed for at styre, hvad AI'en ved.",
        "de": "Aktive Skills werden an den System-Prompt angehängt. Schalte sie einzeln ein oder aus, um zu steuern, was die KI weiß.",
    },
    "Agent Skills": {
        "nb": "Agent-ferdigheter",
        "sv": "Agent-färdigheter",
        "da": "Agent-færdigheder",
        "de": "Agent-Skills",
    },
    "Allow Shell Command?": {
        "nb": "Tillat skalkommando?",
        "sv": "Tillåt skalkommando?",
        "da": "Tillad skalkommando?",
        "de": "Shell-Befehl erlauben?",
    },
    "Allow the AI to run shell commands on your machine. Commands are executed via /bin/zsh. Enable approval mode to review each command before it runs.": {
        "nb": "Gi KI-en tilgang til å kjøre skalkommandoer på maskinen din. Kommandoer kjøres via /bin/zsh. Aktiver godkjenningsmodus for å se gjennom hver kommando før den kjøres.",
        "sv": "Låt AI:n köra skalkommandon på din dator. Kommandon körs via /bin/zsh. Aktivera godkännandeläge för att granska varje kommando innan det körs.",
        "da": "Giv AI'en adgang til at køre skalkommandoer på din maskine. Kommandoer udføres via /bin/zsh. Aktiver godkendelsestilstand for at gennemgå hver kommando, inden den køres.",
        "de": "Erlaube der KI, Shell-Befehle auf deinem Rechner auszuführen. Befehle werden über /bin/zsh ausgeführt. Aktiviere den Genehmigungsmodus, um jeden Befehl vor der Ausführung zu prüfen.",
    },
    "Auto-execute mode: commands run without approval. Use with caution.": {
        "nb": "Auto-kjøremodus: kommandoer kjøres uten godkjenning. Bruk med forsiktighet.",
        "sv": "Automatisk körning: kommandon körs utan godkännande. Använd med försiktighet.",
        "da": "Automatisk kørselstilstand: kommandoer køres uden godkendelse. Brug med forsigtighed.",
        "de": "Automatischer Ausführungsmodus: Befehle werden ohne Genehmigung ausgeführt. Mit Vorsicht verwenden.",
    },
    "Auto-sync can cause conflicts if running on multiple machines simultaneously.": {
        "nb": "Auto-synkronisering kan forårsake konflikter hvis den kjøres på flere maskiner samtidig.",
        "sv": "Automatisk synkronisering kan orsaka konflikter om den körs på flera datorer samtidigt.",
        "da": "Auto-synkronisering kan forårsage konflikter, hvis den kører på flere maskiner samtidigt.",
        "de": "Die automatische Synchronisierung kann zu Konflikten führen, wenn sie auf mehreren Geräten gleichzeitig läuft.",
    },
    "Automatically select relevant messages instead of sending all history. Reduces token usage for long conversations.": {
        "nb": "Velg automatisk relevante meldinger i stedet for å sende all historikk. Reduserer tokenforbruk for lange samtaler.",
        "sv": "Välj automatiskt relevanta meddelanden istället för att skicka all historik. Minskar tokenanvändningen för långa konversationer.",
        "da": "Vælg automatisk relevante beskeder i stedet for at sende al historik. Reducerer tokenforbrug for lange samtaler.",
        "de": "Relevante Nachrichten automatisch auswählen statt die gesamte Historie zu senden. Reduziert den Token-Verbrauch bei langen Gesprächen.",
    },
    "Automatically summarize old portions of long conversations to save tokens and improve context efficiency.": {
        "nb": "Sammenfatt automatisk eldre deler av lange samtaler for å spare tokens og forbedre konteksteffektiviteten.",
        "sv": "Sammanfatta automatiskt äldre delar av långa konversationer för att spara tokens och förbättra kontexteffektiviteten.",
        "da": "Opsummer automatisk ældre dele af lange samtaler for at spare tokens og forbedre konteksteffektiviteten.",
        "de": "Ältere Teile langer Gespräche automatisch zusammenfassen, um Tokens zu sparen und die Kontexteffizienz zu verbessern.",
    },
    "Back Up Now": {
        "nb": "Sikkerhetskopier nå",
        "sv": "Säkerhetskopiera nu",
        "da": "Sikkerhedskopier nu",
        "de": "Jetzt sichern",
    },
    "Backup location:": {
        "nb": "Sikkerhetskopiplassering:",
        "sv": "Säkerhetskopieringsplats:",
        "da": "Sikkerhedskopieringsplacering:",
        "de": "Sicherungsort:",
    },
    "COMMAND": {
        "nb": "KOMMANDO",
        "sv": "KOMMANDO",
        "da": "KOMMANDO",
        "de": "BEFEHL",
    },
    "Capabilities": {
        "nb": "Egenskaper",
        "sv": "Funktioner",
        "da": "Egenskaber",
        "de": "Fähigkeiten",
    },
    "Changing these values affects how the AI generates responses. The defaults work well for most use cases.": {
        "nb": "Å endre disse verdiene påvirker hvordan KI-en genererer svar. Standardverdiene fungerer bra for de fleste brukstilfeller.",
        "sv": "Att ändra dessa värden påverkar hur AI:n genererar svar. Standardvärdena fungerar bra för de flesta användningsfall.",
        "da": "Ændring af disse værdier påvirker, hvordan AI'en genererer svar. Standardværdierne fungerer godt til de fleste anvendelser.",
        "de": "Das Ändern dieser Werte beeinflusst, wie die KI Antworten generiert. Die Standardwerte funktionieren für die meisten Anwendungsfälle gut.",
    },
    "Check your balance at:": {
        "nb": "Sjekk saldoen din på:",
        "sv": "Kontrollera ditt saldo på:",
        "da": "Tjek din saldo på:",
        "de": "Guthaben prüfen unter:",
    },
    "Check your usage at:": {
        "nb": "Sjekk forbruket ditt på:",
        "sv": "Kontrollera din användning på:",
        "da": "Tjek dit forbrug på:",
        "de": "Nutzung prüfen unter:",
    },
    "Clear All": {
        "nb": "Slett alle",
        "sv": "Rensa alla",
        "da": "Ryd alle",
        "de": "Alle löschen",
    },
    "Click 'Add Folder' below or drag folders here from Finder": {
        "nb": "Klikk «Legg til mappe» nedenfor eller dra mapper hit fra Finder",
        "sv": "Klicka på \"Lägg till mapp\" nedan eller dra mappar hit från Finder",
        "da": "Klik på 'Tilføj mappe' nedenfor eller træk mapper hertil fra Finder",
        "de": 'Klicke unten auf \u201eOrdner hinzuf\u00fcgen\u201c oder ziehe Ordner aus dem Finder hierher',
    },
    "Command": {
        "nb": "Kommando",
        "sv": "Kommando",
        "da": "Kommando",
        "de": "Befehl",
    },
    "Command History": {
        "nb": "Kommandohistorikk",
        "sv": "Kommandohistorik",
        "da": "Kommandohistorik",
        "de": "Befehlshistorie",
    },
    "Content (Markdown)": {
        "nb": "Innhold (Markdown)",
        "sv": "Innehåll (Markdown)",
        "da": "Indhold (Markdown)",
        "de": "Inhalt (Markdown)",
    },
    "Controls which messages are written to ~/Library/Logs/oAI.log": {
        "nb": "Styrer hvilke meldinger som skrives til ~/Library/Logs/oAI.log",
        "sv": "Styr vilka meddelanden som skrivs till ~/Library/Logs/oAI.log",
        "da": "Styrer hvilke beskeder der skrives til ~/Library/Logs/oAI.log",
        "de": "Steuert, welche Nachrichten in ~/Library/Logs/oAI.log geschrieben werden",
    },
    "Conversations": {
        "nb": "Samtaler",
        "sv": "Konversationer",
        "da": "Samtaler",
        "de": "Gespräche",
    },
    "Copied!": {
        "nb": "Kopiert!",
        "sv": "Kopierat!",
        "da": "Kopieret!",
        "de": "Kopiert!",
    },
    "Cost Examples": {
        "nb": "Kostnadseksempler",
        "sv": "Kostnadsexempel",
        "da": "Omkostningseksempler",
        "de": "Kostenbeispiele",
    },
    "Create a dedicated email account specifically for AI handling. Do NOT use your personal email address.": {
        "nb": "Opprett en dedikert e-postkonto spesielt for KI-håndtering. IKKE bruk din personlige e-postadresse.",
        "sv": "Skapa ett dedikerat e-postkonto specifikt för AI-hantering. Använd INTE din personliga e-postadress.",
        "da": "Opret en dedikeret e-mailkonto specifikt til AI-håndtering. Brug IKKE din personlige e-mailadresse.",
        "de": "Erstelle ein dediziertes E-Mail-Konto speziell für die KI-Bearbeitung. Verwende NICHT deine persönliche E-Mail-Adresse.",
    },
    "Create a shortcut to save a reusable prompt template accessible from the / command dropdown.": {
        "nb": "Opprett en snarvei for å lagre en gjenbrukbar promptmal som er tilgjengelig fra /kommando-rullegardinmenyen.",
        "sv": "Skapa en genväg för att spara en återanvändbar promptmall tillgänglig från /-kommandomenyn.",
        "da": "Opret en genvej til at gemme en genanvendelig promptskabelon, der er tilgængelig fra /kommando-rullemenuen.",
        "de": "Erstelle eine Verknüpfung, um eine wiederverwendbare Prompt-Vorlage zu speichern, die über das /-Befehlsmenü zugänglich ist.",
    },
    "Default Prompt": {
        "nb": "Standardprompt",
        "sv": "Standardprompt",
        "da": "Standardprompt",
        "de": "Standard-Prompt",
    },
    "Delete (%@)": {
        "nb": "Slett (%@)",
        "sv": "Radera (%@)",
        "da": "Slet (%@)",
        "de": "Löschen (%@)",
    },
    "Description": {
        "nb": "Beskrivelse",
        "sv": "Beskrivning",
        "da": "Beskrivelse",
        "de": "Beschreibung",
    },
    "Each command will require your approval before running.": {
        "nb": "Hver kommando krever din godkjenning før den kjøres.",
        "sv": "Varje kommando kräver ditt godkännande innan det körs.",
        "da": "Hver kommando kræver din godkendelse, inden den køres.",
        "de": "Jeder Befehl erfordert deine Genehmigung, bevor er ausgeführt wird.",
    },
    "Edit": {
        "nb": "Rediger",
        "sv": "Redigera",
        "da": "Rediger",
        "de": "Bearbeiten",
    },
    "Email Activity Log": {
        "nb": "E-postaktivitetslogg",
        "sv": "E-postaktivitetslogg",
        "da": "E-mailaktivitetslog",
        "de": "E-Mail-Aktivitätsprotokoll",
    },
    "Email Handler System Prompt": {
        "nb": "Systemprompt for e-postbehandler",
        "sv": "Systemprompt för e-posthanterare",
        "da": "Systemprompt til e-mailbehandler",
        "de": "System-Prompt für E-Mail-Handler",
    },
    "Email handler uses ONLY its own system prompt, completely isolated from your main chat settings. A custom prompt below will override the defaults.": {
        "nb": "E-postbehandleren bruker KUN sin egen systemprompt, fullstendig isolert fra de viktigste chatinnstillingene dine. En egendefinert prompt nedenfor vil overstyre standardinnstillingene.",
        "sv": "E-posthanteraren använder BARA sin egen systemprompt, helt isolerad från dina viktigaste chattinställningar. En anpassad prompt nedan åsidosätter standardinställningarna.",
        "da": "E-mailbehandleren bruger KUN sin egen systemprompt, fuldstændig isoleret fra dine vigtigste chatindstillinger. En brugerdefineret prompt nedenfor tilsidesætter standardindstillingerne.",
        "de": "Der E-Mail-Handler verwendet NUR seinen eigenen System-Prompt, vollständig isoliert von deinen Chat-Einstellungen. Ein benutzerdefinierter Prompt unten überschreibt die Standardeinstellungen.",
    },
    "Email tasks have READ-ONLY access to MCP folders. The AI cannot write, delete, or modify files when processing emails.": {
        "nb": "E-postoppgaver har SKRIVEBESKYTTET tilgang til MCP-mapper. KI-en kan ikke skrive, slette eller endre filer ved behandling av e-post.",
        "sv": "E-postuppgifter har LÄSBEHÖRIGHET till MCP-mappar. AI:n kan inte skriva, radera eller ändra filer vid e-postbehandling.",
        "da": "E-mailopgaver har KUN LÆSEADGANG til MCP-mapper. AI'en kan ikke skrive, slette eller ændre filer under behandling af e-mails.",
        "de": "E-Mail-Aufgaben haben NUR LESEZUGRIFF auf MCP-Ordner. Die KI kann beim Verarbeiten von E-Mails keine Dateien schreiben, löschen oder ändern.",
    },
    "Enable AI-powered semantic search using %@ embeddings. Cost: ~$0.02–0.15/1M tokens.": {
        "nb": "Aktiver KI-drevet semantisk søk med %@-innbygginger. Kostnad: ~$0,02–0,15/1M tokens.",
        "sv": "Aktivera AI-driven semantisk sökning med %@-embeddings. Kostnad: ~$0,02–0,15/1M tokens.",
        "da": "Aktiver AI-drevet semantisk søgning med %@-indlejringer. Omkostning: ~$0,02–0,15/1M tokens.",
        "de": "KI-gestützte semantische Suche mit %@-Embeddings aktivieren. Kosten: ~$0,02–0,15/1M Tokens.",
    },
    "Enable email handler in Settings to start monitoring emails": {
        "nb": "Aktiver e-postbehandler i Innstillinger for å starte overvåking av e-post",
        "sv": "Aktivera e-posthanteraren i Inställningar för att börja övervaka e-post",
        "da": "Aktiver e-mailbehandler i Indstillinger for at begynde at overvåge e-mails",
        "de": "E-Mail-Handler in den Einstellungen aktivieren, um E-Mails zu überwachen",
    },
    "Error: %@": {
        "nb": "Feil: %@",
        "sv": "Fel: %@",
        "da": "Fejl: %@",
        "de": "Fehler: %@",
    },
    "Example structure:": {
        "nb": "Eksempelstruktur:",
        "sv": "Exempelstruktur:",
        "da": "Eksempelstruktur:",
        "de": "Beispielstruktur:",
    },
    "File Access Permissions": {
        "nb": "Filtillatelser",
        "sv": "Filbehörigheter",
        "da": "Filtilladelser",
        "de": "Dateizugriffsberechtigungen",
    },
    "Files": {
        "nb": "Filer",
        "sv": "Filer",
        "da": "Filer",
        "de": "Dateien",
    },
    "Help": {
        "nb": "Hjelp",
        "sv": "Hjälp",
        "da": "Hjælp",
        "de": "Hilfe",
    },
    "How to get your API token:": {
        "nb": "Slik får du API-tokenet ditt:",
        "sv": "Så här hämtar du din API-token:",
        "da": "Sådan får du dit API-token:",
        "de": "So erhältst du deinen API-Token:",
    },
    "Initialize Repository": {
        "nb": "Initialiser repositorium",
        "sv": "Initiera förvar",
        "da": "Initialiser repository",
        "de": "Repository initialisieren",
    },
    "Inject into system prompt for every conversation": {
        "nb": "Injiser i systemprompten for hver samtale",
        "sv": "Injicera i systemprompten för varje konversation",
        "da": "Injicér i systemprompten for hver samtale",
        "de": "In den System-Prompt jedes Gesprächs einfügen",
    },
    "Large files inflate the system prompt and may hit token limits.": {
        "nb": "Store filer blåser opp systemprompten og kan nå token-grenser.",
        "sv": "Stora filer blåser upp systemprompten och kan nå token-gränser.",
        "da": "Store filer oppblæser systemprompten og kan ramme token-grænser.",
        "de": "Große Dateien blähen den System-Prompt auf und können Token-Limits erreichen.",
    },
    "Last sync: %@": {
        "nb": "Siste synkronisering: %@",
        "sv": "Senaste synkronisering: %@",
        "da": "Seneste synkronisering: %@",
        "de": "Letzte Synchronisierung: %@",
    },
    "Leave empty to use the default email handler system prompt.": {
        "nb": "La stå tomt for å bruke standard systemprompt for e-postbehandler.",
        "sv": "Lämna tomt för att använda e-posthanterarens standardsystemprompt.",
        "da": "Lad stå tomt for at bruge standard systemprompt til e-mailbehandler.",
        "de": "Leer lassen, um den Standard-System-Prompt des E-Mail-Handlers zu verwenden.",
    },
    "Lowercase letters, numbers, and hyphens only. No spaces.": {
        "nb": "Kun små bokstaver, tall og bindestreker. Ingen mellomrom.",
        "sv": "Endast gemener, siffror och bindestreck. Inga blanksteg.",
        "da": "Kun små bogstaver, tal og bindestreger. Ingen mellemrum.",
        "de": "Nur Kleinbuchstaben, Zahlen und Bindestriche. Keine Leerzeichen.",
    },
    "MCP gives the AI controlled access to read and optionally write files on your computer. The AI can search, read, and analyze files in allowed folders to help with coding, analysis, and other tasks.": {
        "nb": "MCP gir KI-en kontrollert tilgang til å lese og eventuelt skrive filer på datamaskinen din. KI-en kan søke, lese og analysere filer i tillatte mapper for å hjelpe med koding, analyse og andre oppgaver.",
        "sv": "MCP ger AI:n kontrollerad åtkomst att läsa och eventuellt skriva filer på din dator. AI:n kan söka, läsa och analysera filer i tillåtna mappar för att hjälpa till med kodning, analys och andra uppgifter.",
        "da": "MCP giver AI'en kontrolleret adgang til at læse og eventuelt skrive filer på din computer. AI'en kan søge, læse og analysere filer i tilladte mapper for at hjælpe med kodning, analyse og andre opgaver.",
        "de": "MCP gibt der KI kontrollierten Zugriff, um Dateien auf deinem Computer zu lesen und optional zu schreiben. Die KI kann Dateien in erlaubten Ordnern suchen, lesen und analysieren, um bei Programmierung, Analyse und anderen Aufgaben zu helfen.",
    },
    "Markdown instruction files injected into the system prompt. Compatible with SKILL.md format.": {
        "nb": "Markdown-instruksjonsfiler som injiseres i systemprompten. Kompatibel med SKILL.md-format.",
        "sv": "Markdown-instruktionsfiler som injiceras i systemprompten. Kompatibel med SKILL.md-format.",
        "da": "Markdown-instruktionsfiler injiceret i systemprompten. Kompatibel med SKILL.md-format.",
        "de": "Markdown-Anweisungsdateien, die in den System-Prompt eingefügt werden. Kompatibel mit SKILL.md-Format.",
    },
    "Max Tokens: set to 0 to use model default. Higher values allow longer responses.": {
        "nb": "Maks tokens: sett til 0 for å bruke modellstandard. Høyere verdier gir lengre svar.",
        "sv": "Max tokens: sätt till 0 för att använda modellens standard. Högre värden tillåter längre svar.",
        "da": "Maks tokens: sæt til 0 for at bruge modelstandard. Højere værdier tillader længere svar.",
        "de": "Maximale Tokens: auf 0 setzen, um den Modell-Standard zu verwenden. Höhere Werte erlauben längere Antworten.",
    },
    "Model Info": {
        "nb": "Modellinformasjon",
        "sv": "Modellinformation",
        "da": "Modelinformation",
        "de": "Modell-Info",
    },
    "Multi-provider AI chat client": {
        "nb": "AI-chatklient med støtte for flere tilbydere",
        "sv": "AI-chattklient med stöd för flera leverantörer",
        "da": "AI-chatklient med understøttelse af flere udbydere",
        "de": "KI-Chat-Client mit mehreren Anbietern",
    },
    "Name": {
        "nb": "Navn",
        "sv": "Namn",
        "da": "Navn",
        "de": "Name",
    },
    "Never": {
        "nb": "Aldri",
        "sv": "Aldrig",
        "da": "Aldrig",
        "de": "Nie",
    },
    "No credit data available": {
        "nb": "Ingen kredittdata tilgjengelig",
        "sv": "Ingen kreditdata tillgänglig",
        "da": "Ingen kreditdata tilgængelig",
        "de": "Keine Guthabendaten verfügbar",
    },
    "No email activity yet": {
        "nb": "Ingen e-postaktivitet ennå",
        "sv": "Ingen e-postaktivitet ännu",
        "da": "Ingen e-mailaktivitet endnu",
        "de": "Noch keine E-Mail-Aktivität",
    },
    "No files attached. Add JSON, YAML, CSV or TXT files to inject data into the system prompt alongside this skill.": {
        "nb": "Ingen filer vedlagt. Legg til JSON, YAML, CSV eller TXT-filer for å injisere data i systemprompten sammen med denne ferdigheten.",
        "sv": "Inga filer bifogade. Lägg till JSON, YAML, CSV eller TXT-filer för att injicera data i systemprompten bredvid denna färdighet.",
        "da": "Ingen filer vedhæftet. Tilføj JSON, YAML, CSV eller TXT-filer for at injicere data i systemprompten ved siden af denne færdighed.",
        "de": "Keine Dateien angehängt. Füge JSON, YAML, CSV oder TXT-Dateien hinzu, um Daten zusammen mit diesem Skill in den System-Prompt einzufügen.",
    },
    "No model selected": {
        "nb": "Ingen modell valgt",
        "sv": "Ingen modell vald",
        "da": "Ingen model valgt",
        "de": "Kein Modell ausgewählt",
    },
    "No models available": {
        "nb": "Ingen modeller tilgjengelig",
        "sv": "Inga modeller tillgängliga",
        "da": "Ingen modeller tilgængelige",
        "de": "Keine Modelle verfügbar",
    },
    'No results for "%@"': {
        "nb": "Ingen resultater for «%@»",
        "sv": "Inga resultat för \"%@\"",
        "da": "Ingen resultater for \"%@\"",
        "de": "Keine Ergebnisse f\u00fcr \u201e%@\u201c",
    },
    "No shortcuts yet": {
        "nb": "Ingen snarveier ennå",
        "sv": "Inga genvägar ännu",
        "da": "Ingen genveje endnu",
        "de": "Noch keine Verknüpfungen",
    },
    "No shortcuts yet — click New Shortcut to create one.": {
        "nb": "Ingen snarveier ennå — klikk på Ny snarvei for å opprette en.",
        "sv": "Inga genvägar ännu — klicka på Ny genväg för att skapa en.",
        "da": "Ingen genveje endnu — klik på Ny genvej for at oprette en.",
        "de": "Noch keine Verkn\u00fcpfungen \u2014 klicke auf \u201eNeue Verkn\u00fcpfung\u201c, um eine zu erstellen.",
    },
    "No skills yet": {
        "nb": "Ingen ferdigheter ennå",
        "sv": "Inga färdigheter ännu",
        "da": "Ingen færdigheder endnu",
        "de": "Noch keine Skills",
    },
    "No skills yet — click New Skill or Import to get started.": {
        "nb": "Ingen ferdigheter ennå — klikk på Ny ferdighet eller Importer for å komme i gang.",
        "sv": "Inga färdigheter ännu — klicka på Ny färdighet eller Importera för att komma igång.",
        "da": "Ingen færdigheder endnu — klik på Ny færdighed eller Importer for at komme i gang.",
        "de": "Noch keine Skills \u2014 klicke auf \u201eNeuer Skill\u201c oder \u201eImportieren\u201c, um loszulegen.",
    },
    "Only emails with this text in the subject line will be processed. Example: \"[OAIBOT] What's the weather?\"": {
        "nb": "Bare e-poster med denne teksten i emnefeltet behandles. Eksempel: «[OAIBOT] Hva er været?»",
        "sv": "Bara e-post med denna text i ämnesraden bearbetas. Exempel: \"[OAIBOT] Vad är vädret?\"",
        "da": "Kun e-mails med denne tekst i emnelinjen behandles. Eksempel: \"[OAIBOT] Hvad er vejret?\"",
        "de": "Nur E-Mails mit diesem Text in der Betreffzeile werden verarbeitet. Beispiel: \u201e[OAIBOT] Wie ist das Wetter?\u201c",
    },
    "Read access (always enabled)": {
        "nb": "Lesetilgang (alltid aktivert)",
        "sv": "Läsbehörighet (alltid aktiverad)",
        "da": "Læseadgang (altid aktiveret)",
        "de": "Lesezugriff (immer aktiviert)",
    },
    "Restore from File…": {
        "nb": "Gjenopprett fra fil…",
        "sv": "Återställ från fil…",
        "da": "Gendan fra fil…",
        "de": "Aus Datei wiederherstellen…",
    },
    "Running locally — no credits needed!": {
        "nb": "Kjører lokalt — ingen kreditter nødvendig!",
        "sv": "Körs lokalt — inga krediter behövs!",
        "da": "Kører lokalt — ingen kreditter nødvendige!",
        "de": "Läuft lokal — kein Guthaben benötigt!",
    },
    "SKILL.md format — write instructions in plain Markdown.": {
        "nb": "SKILL.md-format — skriv instruksjoner i vanlig Markdown.",
        "sv": "SKILL.md-format — skriv instruktioner i vanlig Markdown.",
        "da": "SKILL.md-format — skriv instruktioner i almindelig Markdown.",
        "de": "SKILL.md-Format — Anweisungen in einfachem Markdown schreiben.",
    },
    "Security Recommendation": {
        "nb": "Sikkerhetsanbefaling",
        "sv": "Säkerhetsrekommendation",
        "da": "Sikkerhedsanbefaling",
        "de": "Sicherheitsempfehlung",
    },
    "Shell commands have full access to your system. Only approve commands you understand and trust.": {
        "nb": "Skalkommandoer har full tilgang til systemet ditt. Godkjenn bare kommandoer du forstår og stoler på.",
        "sv": "Skalkommandon har full åtkomst till ditt system. Godkänn bara kommandon du förstår och litar på.",
        "da": "Skalkommandoer har fuld adgang til dit system. Godkend kun kommandoer, du forstår og har tillid til.",
        "de": "Shell-Befehle haben vollen Zugriff auf dein System. Genehmige nur Befehle, die du verstehst und denen du vertraust.",
    },
    "Show text labels below toolbar icons (helpful for new users)": {
        "nb": "Vis tekstetiketter under verktøylinjeikonene (nyttig for nye brukere)",
        "sv": "Visa textetiketter under verktygsfältets ikoner (hjälpsamt för nya användare)",
        "da": "Vis tekstetikvetter under værktøjslinjeikoner (nyttigt for nye brugere)",
        "de": "Textbeschriftungen unter Symbolleistensymbolen anzeigen (hilfreich für neue Benutzer)",
    },
    "Skills are markdown instruction files that teach the AI how to behave. Active skills are automatically injected into the system prompt.": {
        "nb": "Ferdigheter er Markdown-instruksjonsfiler som lærer KI-en hvordan den skal oppføre seg. Aktive ferdigheter injiseres automatisk i systemprompten.",
        "sv": "Färdigheter är Markdown-instruktionsfiler som lär AI:n hur den ska bete sig. Aktiva färdigheter injiceras automatiskt i systemprompten.",
        "da": "Færdigheder er Markdown-instruktionsfiler, der lærer AI'en, hvordan den skal opføre sig. Aktive færdigheder injiceres automatisk i systemprompten.",
        "de": "Skills sind Markdown-Anweisungsdateien, die der KI beibringen, wie sie sich verhalten soll. Aktive Skills werden automatisch in den System-Prompt eingefügt.",
    },
    "Stream responses as they're generated. Disable for single, complete responses.": {
        "nb": "Strøm svar etter hvert som de genereres. Deaktiver for enkle, fullstendige svar.",
        "sv": "Strömma svar medan de genereras. Inaktivera för fullständiga, enkla svar.",
        "da": "Stream svar, efterhånden som de genereres. Deaktiver for enkle, komplette svar.",
        "de": "Antworten während der Generierung streamen. Deaktivieren für vollständige Einzelantworten.",
    },
    "Sync Now": {
        "nb": "Synkroniser nå",
        "sv": "Synkronisera nu",
        "da": "Synkroniser nu",
        "de": "Jetzt synchronisieren",
    },
    "Sync conversations and settings across multiple machines using Git.": {
        "nb": "Synkroniser samtaler og innstillinger på tvers av flere maskiner ved hjelp av Git.",
        "sv": "Synkronisera konversationer och inställningar på flera datorer med Git.",
        "da": "Synkroniser samtaler og indstillinger på tværs af flere maskiner ved hjælp af Git.",
        "de": "Gespräche und Einstellungen über mehrere Geräte hinweg mit Git synchronisieren.",
    },
    "Temperature: 0 = model default · 0.0–0.7 = focused · 0.8–2.0 = creative": {
        "nb": "Temperatur: 0 = modellstandard · 0,0–0,7 = fokusert · 0,8–2,0 = kreativ",
        "sv": "Temperatur: 0 = modellens standard · 0,0–0,7 = fokuserat · 0,8–2,0 = kreativt",
        "da": "Temperatur: 0 = modelstandard · 0,0–0,7 = fokuseret · 0,8–2,0 = kreativt",
        "de": "Temperatur: 0 = Modell-Standard · 0,0–0,7 = fokussiert · 0,8–2,0 = kreativ",
    },
    "Template": {
        "nb": "Mal",
        "sv": "Mall",
        "da": "Skabelon",
        "de": "Vorlage",
    },
    "Test Connection": {
        "nb": "Test tilkobling",
        "sv": "Testa anslutning",
        "da": "Test forbindelse",
        "de": "Verbindung testen",
    },
    "Text files are injected into the system prompt alongside the skill.": {
        "nb": "Tekstfiler injiseres i systemprompten ved siden av ferdigheten.",
        "sv": "Textfiler injiceras i systemprompten bredvid färdigheten.",
        "da": "Tekstfiler injiceres i systemprompten ved siden af færdigheden.",
        "de": "Textdateien werden zusammen mit dem Skill in den System-Prompt eingefügt.",
    },
    "The AI can read and search files in allowed folders": {
        "nb": "KI-en kan lese og søke filer i tillatte mapper",
        "sv": "AI:n kan läsa och söka i filer i tillåtna mappar",
        "da": "AI'en kan læse og søge i filer i tilladte mapper",
        "de": "Die KI kann Dateien in erlaubten Ordnern lesen und durchsuchen",
    },
    "The AI reads this content and decides when to apply it. Describe **what** the AI should do and **how** — be specific and concise.": {
        "nb": "KI-en leser dette innholdet og bestemmer når det skal brukes. Beskriv **hva** KI-en skal gjøre og **hvordan** — vær spesifikk og konsis.",
        "sv": "AI:n läser detta innehåll och bestämmer när det ska tillämpas. Beskriv **vad** AI:n ska göra och **hur** — var specifik och koncis.",
        "da": "AI'en læser dette indhold og beslutter, hvornår det skal bruges. Beskriv **hvad** AI'en skal gøre og **hvordan** — vær specifik og præcis.",
        "de": "Die KI liest diesen Inhalt und entscheidet, wann sie ihn anwendet. Beschreibe **was** die KI tun soll und **wie** — sei spezifisch und prägnant.",
    },
    "The AI wants to run the following command": {
        "nb": "KI-en ønsker å kjøre følgende kommando",
        "sv": "AI:n vill köra följande kommando",
        "da": "AI'en ønsker at køre følgende kommando",
        "de": "Die KI möchte den folgenden Befehl ausführen",
    },
    "This default prompt is always included to ensure accurate, helpful responses.": {
        "nb": "Denne standardprompten er alltid inkludert for å sikre nøyaktige, nyttige svar.",
        "sv": "Denna standardprompt ingår alltid för att säkerställa korrekta, användbara svar.",
        "da": "Denne standardprompt er altid inkluderet for at sikre præcise, nyttige svar.",
        "de": "Dieser Standard-Prompt ist immer enthalten, um genaue und hilfreiche Antworten sicherzustellen.",
    },
    "This will permanently delete all email activity logs. This action cannot be undone.": {
        "nb": "Dette vil slette alle e-postaktivitetslogger permanent. Denne handlingen kan ikke angres.",
        "sv": "Detta raderar alla e-postaktivitetsloggar permanent. Åtgärden kan inte ångras.",
        "da": "Dette vil permanent slette alle e-mailaktivitetslogge. Denne handling kan ikke fortrydes.",
        "de": "Dadurch werden alle E-Mail-Aktivitätsprotokolle dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.",
    },
    "Token Distribution": {
        "nb": "Token-fordeling",
        "sv": "Token-fördelning",
        "da": "Token-fordeling",
        "de": "Token-Verteilung",
    },
    "Try adjusting your search or filters": {
        "nb": "Prøv å justere søket eller filtrene",
        "sv": "Försök att justera din sökning eller dina filter",
        "da": "Prøv at justere din søgning eller dine filtre",
        "de": "Suche oder Filter anpassen",
    },
    "Type / in the input to see command suggestions": {
        "nb": "Skriv / i inndata for å se kommandoforslag",
        "sv": "Skriv / i inmatningsfältet för att se kommandoförslag",
        "da": "Skriv / i inputfeltet for at se kommandoforslag",
        "de": "/ im Eingabefeld eingeben, um Befehlsvorschläge zu sehen",
    },
    "Type a message or / for commands...": {
        "nb": "Skriv en melding eller / for kommandoer...",
        "sv": "Skriv ett meddelande eller / för kommandon...",
        "da": "Skriv en besked eller / for kommandoer...",
        "de": "Nachricht eingeben oder / für Befehle...",
    },
    "Uncommitted changes: %@": {
        "nb": "Ulagrede endringer: %@",
        "sv": "Ej sparade ändringar: %@",
        "da": "Ikke-committede ændringer: %@",
        "de": "Nicht übernommene Änderungen: %@",
    },
    "Update Available%@": {
        "nb": "Oppdatering tilgjengelig%@",
        "sv": "Uppdatering tillgänglig%@",
        "da": "Opdatering tilgængelig%@",
        "de": "Update verfügbar%@",
    },
    "Use **{{input}}** in the template to insert whatever you type after the command.": {
        "nb": "Bruk **{{input}}** i malen for å sette inn det du skriver etter kommandoen.",
        "sv": "Använd **{{input}}** i mallen för att infoga det du skriver efter kommandot.",
        "da": "Brug **{{input}}** i skabelonen til at indsætte det, du skriver efter kommandoen.",
        "de": "Verwende **{{input}}** in der Vorlage, um einzufügen, was du nach dem Befehl tippst.",
    },
    "Use **{{input}}** to insert whatever you type after the command.": {
        "nb": "Bruk **{{input}}** for å sette inn det du skriver etter kommandoen.",
        "sv": "Använd **{{input}}** för att infoga det du skriver efter kommandot.",
        "da": "Brug **{{input}}** til at indsætte det, du skriver efter kommandoen.",
        "de": "Verwende **{{input}}**, um einzufügen, was du nach dem Befehl tippst.",
    },
    "Use @filename to attach files to your message": {
        "nb": "Bruk @filnavn for å legge ved filer i meldingen",
        "sv": "Använd @filnamn för att bifoga filer till ditt meddelande",
        "da": "Brug @filnavn for at vedhæfte filer til din besked",
        "de": "@dateiname verwenden, um Dateien an die Nachricht anzuhängen",
    },
    "View Email Log": {
        "nb": "Vis e-postlogg",
        "sv": "Visa e-postlogg",
        "da": "Vis e-maillog",
        "de": "E-Mail-Protokoll anzeigen",
    },
    "When enabled, listing and searching skip gitignored files. Write operations always ignore .gitignore.": {
        "nb": "Når aktivert, hoppes gitignorerte filer over ved listing og søk. Skriveoperasjoner ignorerer alltid .gitignore.",
        "sv": "När aktiverat hoppar listning och sökning över gitignorerade filer. Skrivoperationer ignorerar alltid .gitignore.",
        "da": "Når aktiveret, springes gitignorerede filer over ved listning og søgning. Skriveoperationer ignorerer altid .gitignore.",
        "de": "Wenn aktiviert, werden gitignorierte Dateien beim Auflisten und Suchen übersprungen. Schreiboperationen ignorieren immer .gitignore.",
    },
    "Working directory:": {
        "nb": "Arbeidsmappe:",
        "sv": "Arbetskatalog:",
        "da": "Arbejdsmappe:",
        "de": "Arbeitsverzeichnis:",
    },
    "You can import any SKILL.md file from skill0.io or write your own.": {
        "nb": "Du kan importere en hvilken som helst SKILL.md-fil fra skill0.io eller skrive din egen.",
        "sv": "Du kan importera vilken SKILL.md-fil som helst från skill0.io eller skriva din egen.",
        "da": "Du kan importere en hvilken som helst SKILL.md-fil fra skill0.io eller skrive din egen.",
        "de": "Du kannst jede SKILL.md-Datei von skill0.io importieren oder deine eigene schreiben.",
    },
    "^[%@ entry](inflect: true)": {
        "nb": "^[%@ oppføring](inflect: true)",
        "sv": "^[%@ post](inflect: true)",
        "da": "^[%@ post](inflect: true)",
        "de": "^[%@ Eintrag](inflect: true)",
    },
    "active": {
        "nb": "aktiv",
        "sv": "aktiv",
        "da": "aktiv",
        "de": "aktiv",
    },
    "messages": {
        "nb": "meldinger",
        "sv": "meddelanden",
        "da": "beskeder",
        "de": "Nachrichten",
    },
    "~750 tokens ≈ 500 words. Online mode allows web search in responses.": {
        "nb": "~750 tokens ≈ 500 ord. Nettmodus tillater nettsøk i svar.",
        "sv": "~750 tokens ≈ 500 ord. Onlineläge tillåter webbsökning i svar.",
        "da": "~750 tokens ≈ 500 ord. Onlinetilstand tillader websøgning i svar.",
        "de": "~750 Tokens ≈ 500 Wörter. Online-Modus ermöglicht Websuche in Antworten.",
    },
    "• Add public key to your git provider": {
        "nb": "• Legg til den offentlige nøkkelen hos git-leverandøren din",
        "sv": "• Lägg till den offentliga nyckeln hos din git-leverantör",
        "da": "• Tilføj den offentlige nøgle til din git-udbyder",
        "de": "• Öffentlichen Schlüssel beim Git-Anbieter hinzufügen",
    },
    "• No credentials needed in oAI": {
        "nb": "• Ingen legitimasjon nødvendig i oAI",
        "sv": "• Inga inloggningsuppgifter behövs i oAI",
        "da": "• Ingen legitimationsoplysninger nødvendige i oAI",
        "de": "• Keine Zugangsdaten in oAI erforderlich",
    },
    "• Uses your system SSH keys (~/.ssh/id_ed25519)": {
        "nb": "• Bruker systemets SSH-nøkler (~/.ssh/id_ed25519)",
        "sv": "• Använder dina system-SSH-nycklar (~/.ssh/id_ed25519)",
        "da": "• Bruger dine system-SSH-nøgler (~/.ssh/id_ed25519)",
        "de": "• Verwendet deine System-SSH-Schlüssel (~/.ssh/id_ed25519)",
    },
    "ℹ️ SSH Key Authentication": {
        "nb": "ℹ️ SSH-nøkkelautentisering",
        "sv": "ℹ️ SSH-nyckelautentisering",
        "da": "ℹ️ SSH-nøglegodkendelse",
        "de": "ℹ️ SSH-Schlüssel-Authentifizierung",
    },
    "⚠️ Custom prompt active — only this prompt will be sent to the model.": {
        "nb": "⚠️ Egendefinert prompt aktiv — bare denne prompten sendes til modellen.",
        "sv": "⚠️ Anpassad prompt aktiv — bara denna prompt skickas till modellen.",
        "da": "⚠️ Brugerdefineret prompt aktiv — kun denne prompt sendes til modellen.",
        "de": "⚠️ Benutzerdefinierter Prompt aktiv — nur dieser Prompt wird an das Modell gesendet.",
    },
    "⚠️ Many providers (GitHub) no longer support password authentication. Use Access Token instead.": {
        "nb": "⚠️ Mange tilbydere (GitHub) støtter ikke lenger passordautentisering. Bruk Access Token i stedet.",
        "sv": "⚠️ Många leverantörer (GitHub) stöder inte längre lösenordsautentisering. Använd Access Token istället.",
        "da": "⚠️ Mange udbydere (GitHub) understøtter ikke længere adgangskodegodkendelse. Brug Access Token i stedet.",
        "de": "⚠️ Viele Anbieter (GitHub) unterstützen keine Passwort-Authentifizierung mehr. Stattdessen Access Token verwenden.",
    },
    "⚠️ No embedding providers available. Configure an API key for OpenAI, OpenRouter, or Google in the General tab.": {
        "nb": "⚠️ Ingen innbyggingsleverandører tilgjengelig. Konfigurer en API-nøkkel for OpenAI, OpenRouter eller Google i fanen Generelt.",
        "sv": "⚠️ Inga embedding-leverantörer tillgängliga. Konfigurera en API-nyckel för OpenAI, OpenRouter eller Google på fliken Allmänt.",
        "da": "⚠️ Ingen indlejringsudbydere tilgængelige. Konfigurer en API-nøgle til OpenAI, OpenRouter eller Google på fanen Generelt.",
        "de": "⚠️ Keine Embedding-Anbieter verf\u00fcgbar. Konfiguriere einen API-Schl\u00fcssel f\u00fcr OpenAI, OpenRouter oder Google auf der Registerkarte \u201eAllgemein\u201c.",
    },
    "⚠️ One-time operation — generates embeddings for all messages. Estimated cost: ~$0.04 for 10,000 messages.": {
        "nb": "⚠️ Engangsoperasjon — genererer innbygginger for alle meldinger. Estimert kostnad: ~$0,04 for 10 000 meldinger.",
        "sv": "⚠️ Engångsoperation — genererar embeddings för alla meddelanden. Uppskattad kostnad: ~$0,04 för 10 000 meddelanden.",
        "da": "⚠️ Engangshandling — genererer indlejringer for alle beskeder. Estimeret omkostning: ~$0,04 for 10.000 beskeder.",
        "de": "⚠️ Einmaliger Vorgang — generiert Embeddings für alle Nachrichten. Geschätzte Kosten: ~$0,04 für 10.000 Nachrichten.",
    },
    "⚠️ These are advanced settings": {
        "nb": "⚠️ Dette er avanserte innstillinger",
        "sv": "⚠️ Det här är avancerade inställningar",
        "da": "⚠️ Dette er avancerede indstillinger",
        "de": "⚠️ Das sind erweiterte Einstellungen",
    },
    "⚠️ interrupted": {
        "nb": "⚠️ avbrutt",
        "sv": "⚠️ avbruten",
        "da": "⚠️ afbrudt",
        "de": "⚠️ unterbrochen",
    },
    "💡 For Gmail, use an App Password. Google Account > Security > 2-Step Verification > App passwords.": {
        "nb": "💡 For Gmail, bruk et apppassord. Google-konto > Sikkerhet > 2-trinns bekreftelse > Apppassord.",
        "sv": "💡 För Gmail, använd ett applösenord. Google-konto > Säkerhet > 2-stegsverifiering > Applösenord.",
        "da": "💡 Til Gmail, brug et app-adgangskode. Google-konto > Sikkerhed > 2-trinsbekræftelse > App-adgangskoder.",
        "de": "💡 Für Gmail ein App-Passwort verwenden. Google-Konto > Sicherheit > 2-Schritt-Verifizierung > App-Passwörter.",
    },
    "💡 Use HTTPS URL (e.g., https://gitlab.pm/user/repo.git) — works with all auth methods.": {
        "nb": "💡 Bruk HTTPS URL (f.eks. https://gitlab.pm/user/repo.git) — fungerer med alle autentiseringsmetoder.",
        "sv": "💡 Använd HTTPS URL (t.ex. https://gitlab.pm/user/repo.git) — fungerar med alla autentiseringsmetoder.",
        "da": "💡 Brug HTTPS URL (f.eks. https://gitlab.pm/user/repo.git) — fungerer med alle godkendelsesmetoder.",
        "de": "💡 HTTPS-URL verwenden (z.B. https://gitlab.pm/user/repo.git) — funktioniert mit allen Authentifizierungsmethoden.",
    },
}


def xml_escape(s):
    """Escape XML special characters."""
    return (s
        .replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace('"', "&quot;"))


def get_translation(source_text, lang):
    """Return the translated text for a given source and language."""
    # Try exact match first
    if source_text in T:
        val = T[source_text]
        if val is None:
            return source_text  # keep as-is
        return val.get(lang, source_text)
    # Return source unchanged if not found
    return source_text


def process_xliff(lang):
    src_path = f"{BASE}/{lang}.xcloc/Localized Contents/{lang}.xliff"
    dst_path = src_path  # overwrite in place

    with open(src_path, "r", encoding="utf-8") as f:
        content = f.read()

    # We'll process trans-unit blocks and inject <target> after <source>
    def replace_unit(m):
        block = m.group(0)
        # Extract source text (may span multiple lines)
        src_match = re.search(r'<source>(.*?)</source>', block, re.DOTALL)
        if not src_match:
            return block
        # Check if target already exists
        if '<target>' in block:
            return block
        raw_source = src_match.group(1)
        # Unescape XML entities to get the actual key
        key = (raw_source
               .replace("&amp;", "&")
               .replace("&lt;", "<")
               .replace("&gt;", ">")
               .replace("&quot;", '"'))
        translation = get_translation(key, lang)
        escaped_translation = xml_escape(translation)
        # Insert <target> after </source>
        new_block = block.replace(
            f'</source>',
            f'</source>\n        <target>{escaped_translation}</target>',
            1
        )
        return new_block

    # Match each trans-unit block
    new_content = re.sub(
        r'<trans-unit\b[^>]*>.*?</trans-unit>',
        replace_unit,
        content,
        flags=re.DOTALL
    )

    with open(dst_path, "w", encoding="utf-8") as f:
        f.write(new_content)
    print(f"  ✓ {lang}.xliff written")


langs = ["nb", "sv", "da", "de"]
for lang in langs:
    print(f"Processing {lang}...")
    process_xliff(lang)

print("\nDone! All four XLIFF files updated.")
print("Next step: In Xcode → Product → Import Localizations → select each .xcloc package.")
