umami/scripts/translate-4-nordic.cjs
Mike Cao e1ee5eba27
Some checks are pending
Node.js CI / build (push) Waiting to run
Translate all 51 locale files, reducing untranslated keys from 6,017 to 862.
12 batch translation scripts covering all language families: East Asian, Romance,
Germanic, Nordic, Slavic, Other European, South/Southeast Asian, Tamil, Sinhala,
Urdu, and Burmese. Remaining untranslated keys are intentional loanwords (URL, UTM,
SMS, etc.) and en-GB which is intentionally identical to en-US.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 13:04:45 -08:00

518 lines
17 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const dir = path.join(__dirname, '..', 'public', 'intl', 'messages');
const enUS = JSON.parse(fs.readFileSync(path.join(dir, 'en-US.json'), 'utf8'));
const translations = {
'da-DK': {
label: {
'account': 'Konto',
'action': 'Handling',
'add-link': 'Tilføj link',
'add-pixel': 'Tilføj pixel',
'analysis': 'Analyse',
'application': 'Applikation',
'audience': 'Målgruppe',
'browser': 'Browser',
'campaign': 'Kampagne',
'channel': 'Kanal',
'chart': 'Diagram',
'cohorts': 'Kohorter',
'contains': 'Indeholder',
'criteria': 'Kriterier',
'data': 'Data',
'destination-url': 'Destinations-URL',
'documentation': 'Dokumentation',
'download': 'Download',
'environment': 'Miljø',
'exclude-bounce': 'Ekskluder afvisning',
'filter': 'Filter',
'growth': 'Vækst',
'hour': 'Time',
'invalid-url': 'Ugyldig URL',
'laptop': 'Laptop',
'link': 'Link',
'links': 'Links',
'location': 'Placering',
'medium': 'Medie',
'min': 'Min',
'minute': 'Minut',
'model': 'Model',
'month': 'Måned',
'ok': 'OK',
'online': 'Online',
'os': 'OS',
'pixel': 'Pixel',
'pixels': 'Pixels',
'preferences': 'Præferencer',
'previous': 'Forrige',
'previous-period': 'Forrige periode',
'previous-year': 'Forrige år',
'profiles': 'Profiler',
'region': 'Region',
'save-cohort': 'Gem kohorte',
'save-segment': 'Gem segment',
'screen': 'Skærm',
'segment': 'Segment',
'segments': 'Segmenter',
'session': 'Session',
'sms': 'SMS',
'source': 'Kilde',
'sum': 'Sum',
'support': 'Support',
'switch-account': 'Skift konto',
'table': 'Tabel',
'tablet': 'Tablet',
'tag': 'Tag',
'tags': 'Tags',
'team': 'Hold',
'team-id': 'Hold-ID',
'teams': 'Hold',
'term': 'Søgeord',
'title': 'Titel',
'total': 'Total',
'total-records': 'Samlede poster',
'traffic': 'Trafik',
'transactions': 'Transaktioner',
'transfer': 'Overfør',
'transfer-website': 'Overfør website',
'true': 'Sand',
'type': 'Type',
'unique': 'Unik',
'unique-events': 'Unikke begivenheder',
'uniqueCustomers': 'Unikke kunder',
'untitled': 'Uden titel',
'update': 'Opdater',
'url': 'URL',
'user': 'Bruger',
'users': 'Brugere',
'utm': 'UTM',
'utm-campaign': 'UTM-kampagne',
'utm-content': 'UTM-indhold',
'utm-description': 'Spor dine kampagner via UTM-parametre.',
'utm-medium': 'UTM-medie',
'utm-source': 'UTM-kilde',
'utm-term': 'UTM-søgeord',
'value': 'Værdi',
'version': 'Version',
'view': 'Vis',
'view-only': 'Kun visning',
'views-per-visit': 'Visninger per besøg',
'visits': 'Besøg',
'website': 'Website',
'website-id': 'Website-ID',
'window': 'Vindue',
'yesterday': 'I går'
},
message: {
'action-confirmation': 'Skriv {confirmation} i feltet herunder for at bekræfte.',
'bad-request': 'Ugyldig forespørgsel',
'collected-data': 'Indsamlede data',
'confirm-leave': 'Er du sikker på, at du vil forlade <b>{target}</b>?',
'confirm-remove': 'Er du sikker på, at du vil fjerne <b>{target}</b>?',
'delete-team-warning': 'Sletning af et hold sletter også alle holdets websites.',
'event-log': '<b>{event}</b> på <a>{url}</a>',
'forbidden': 'Forbudt',
'min-password-length': 'Minimumlængde på {n} tegn',
'new-version-available': 'En ny version af Umami {version} er tilgængelig!',
'no-event-data': 'Ingen begivenhedsdata tilgængelig.',
'no-team-websites': 'Dette hold har ingen websites.',
'no-teams': 'Du har ikke oprettet nogen hold.',
'no-users': 'Der er ingen brugere.',
'not-found': 'Ikke fundet',
'nothing-selected': 'Intet valgt.',
'reset-website': 'For at nulstille denne website, skriv {confirmation} i feltet herunder for at bekræfte.',
'sever-error': 'Serverfejl',
'team-already-member': 'Du er allerede medlem af holdet.',
'team-not-found': 'Hold ikke fundet.',
'team-websites-info': 'Websites kan ses af alle på holdet.',
'transfer-team-website-to-user': 'Overfør denne website til din konto?',
'transfer-user-website-to-team': 'Vælg holdet, som denne website skal overføres til.',
'transfer-website': 'Overfør websiteejerskab til din konto eller et andet hold.',
'triggered-event': 'Udløst begivenhed',
'unauthorized': 'Ikke autoriseret',
'user-deleted': 'Bruger slettet.',
'viewed-page': 'Vist side'
}
},
'sv-SE': {
label: {
'account': 'Konto',
'action': 'Åtgärd',
'add-link': 'Lägg till länk',
'add-pixel': 'Lägg till pixel',
'analysis': 'Analys',
'application': 'Applikation',
'audience': 'Publik',
'campaign': 'Kampanj',
'channel': 'Kanal',
'chart': 'Diagram',
'cohorts': 'Kohorter',
'criteria': 'Kriterier',
'data': 'Data',
'destination-url': 'Mål-URL',
'documentation': 'Dokumentation',
'download': 'Ladda ner',
'email': 'E-post',
'environment': 'Miljö',
'exclude-bounce': 'Exkludera avvisning',
'filter': 'Filter',
'first-seen': 'Först sedd',
'funnel': 'Tratt',
'growth': 'Tillväxt',
'hour': 'Timme',
'invalid-url': 'Ogiltig URL',
'link': 'Länk',
'location': 'Plats',
'manage': 'Hantera',
'manager': 'Ansvarig',
'max': 'Max',
'medium': 'Medium',
'min': 'Min',
'minute': 'Minut',
'month': 'Månad',
'number-of-records': '{x} {x, plural, one {post} other {poster}}',
'ok': 'OK',
'online': 'Online',
'pixel': 'Pixel',
'preferences': 'Inställningar',
'profiles': 'Profiler',
'region': 'Region',
'remove-member': 'Ta bort medlem',
'retention': 'Retention',
'save-cohort': 'Spara kohort',
'save-segment': 'Spara segment',
'screen': 'Skärm',
'segment': 'Segment',
'segments': 'Segment',
'select': 'Välj',
'select-role': 'Välj roll',
'session': 'Session',
'sms': 'SMS',
'source': 'Källa',
'start-step': 'Startsteg',
'steps': 'Steg',
'support': 'Support',
'switch-account': 'Byt konto',
'table': 'Tabell',
'team': 'Team',
'team-id': 'Team-ID',
'team-view-only': 'Endast teamvisning',
'term': 'Sökord',
'traffic': 'Trafik',
'transactions': 'Transaktioner',
'transfer': 'Överför',
'transfer-website': 'Överför webbplats',
'unique-events': 'Unika händelser',
'uniqueCustomers': 'Unika kunder',
'update': 'Uppdatera',
'url': 'URL',
'utm': 'UTM',
'utm-campaign': 'UTM-kampanj',
'utm-content': 'UTM-innehåll',
'utm-description': 'Spåra dina kampanjer genom UTM-parametrar.',
'utm-medium': 'UTM-medium',
'utm-source': 'UTM-källa',
'utm-term': 'UTM-sökord',
'version': 'Version',
'views-per-visit': 'Visningar per besök',
'visits': 'Besök'
},
message: {
'action-confirmation': 'Skriv {confirmation} i rutan nedan för att bekräfta.',
'bad-request': 'Ogiltig förfrågan',
'collected-data': 'Insamlad data',
'confirm-remove': 'Är du säker på att du vill ta bort <b>{target}</b>?',
'delete-team-warning': 'Att radera ett team raderar även alla teamets webbplatser.',
'forbidden': 'Förbjudet',
'not-found': 'Hittades inte',
'nothing-selected': 'Inget valt.',
'sever-error': 'Serverfel',
'transfer-team-website-to-user': 'Överför denna webbplats till ditt konto?',
'transfer-user-website-to-team': 'Välj teamet att överföra denna webbplats till.',
'transfer-website': 'Överför webbplatsägande till ditt konto eller ett annat team.',
'triggered-event': 'Utlöst händelse',
'unauthorized': 'Inte auktoriserad',
'viewed-page': 'Visad sida'
}
},
'nb-NO': {
label: {
'account': 'Konto',
'action': 'Handling',
'add-link': 'Legg til lenke',
'add-pixel': 'Legg til piksel',
'analysis': 'Analyse',
'application': 'Applikasjon',
'audience': 'Målgruppe',
'campaign': 'Kampanje',
'channel': 'Kanal',
'chart': 'Diagram',
'cohorts': 'Kohorter',
'criteria': 'Kriterier',
'data': 'Data',
'destination-url': 'Mål-URL',
'documentation': 'Dokumentasjon',
'download': 'Last ned',
'dropoff': 'Frafall',
'email': 'E-post',
'environment': 'Miljø',
'exclude-bounce': 'Ekskluder avvisning',
'filter': 'Filter',
'growth': 'Vekst',
'hour': 'Time',
'invalid-url': 'Ugyldig URL',
'last-months': 'Siste {x} måneder',
'link': 'Lenke',
'location': 'Plassering',
'medium': 'Medium',
'min': 'Min',
'minute': 'Minutt',
'month': 'Måned',
'number-of-records': '{x} {x, plural, one {post} other {poster}}',
'ok': 'OK',
'online': 'Tilkoblet',
'os': 'OS',
'pixel': 'Piksel',
'preferences': 'Innstillinger',
'profiles': 'Profiler',
'referral': 'Henvisning',
'region': 'Region',
'save-cohort': 'Lagre kohort',
'save-segment': 'Lagre segment',
'screen': 'Skjerm',
'segment': 'Segment',
'segments': 'Segmenter',
'sms': 'SMS',
'source': 'Kilde',
'sum': 'Sum',
'support': 'Støtte',
'switch-account': 'Bytt konto',
'table': 'Tabell',
'team': 'Lag',
'term': 'Søkeord',
'traffic': 'Trafikk',
'type': 'Type',
'unique-events': 'Unike hendelser',
'url': 'URL',
'utm': 'UTM',
'utm-campaign': 'UTM-kampanje',
'utm-content': 'UTM-innhold',
'utm-medium': 'UTM-medium',
'utm-source': 'UTM-kilde',
'utm-term': 'UTM-søkeord',
'version': 'Versjon'
},
message: {
'bad-request': 'Ugyldig forespørsel',
'forbidden': 'Forbudt',
'not-found': 'Ikke funnet',
'nothing-selected': 'Ingenting valgt.',
'sever-error': 'Serverfeil',
'unauthorized': 'Ikke autorisert'
}
},
'fo-FO': {
label: {
'account': 'Konto',
'action': 'Handling',
'add-link': 'Legg afturat link',
'add-pixel': 'Legg afturat piksel',
'analysis': 'Greining',
'application': 'Forrit',
'audience': 'Áhoyrarar',
'campaign': 'Herferð',
'channel': 'Rás',
'chart': 'Graf',
'cohorts': 'Kohortar',
'criteria': 'Viðmið',
'destination-url': 'Mál-URL',
'documentation': 'Skjøl',
'download': 'Tak niður',
'dropoff': 'Fráfall',
'environment': 'Umhvørvi',
'exclude-bounce': 'Útiloka frástøyt',
'growth': 'Vøkstur',
'hour': 'Tími',
'invalid-url': 'Ógild URL',
'link': 'Leinkja',
'location': 'Støða',
'minute': 'Minuttur',
'model': 'Fyrimynd',
'month': 'Mánaður',
'number-of-records': '{x} {x, plural, one {skrá} other {skrár}}',
'ok': 'OK',
'online': 'Online',
'os': 'OS',
'pixel': 'Piksel',
'preferences': 'Stillingar',
'profiles': 'Profilir',
'save-cohort': 'Goym kohortu',
'save-segment': 'Goym segment',
'screen': 'Skíggi',
'segment': 'Segment',
'segments': 'Segment',
'sms': 'SMS',
'source': 'Kelda',
'support': 'Stuðul',
'switch-account': 'Skift konto',
'table': 'Tabell',
'term': 'Leitorð',
'title': 'Heiti',
'toggle-charts': 'Vísa/fjal grafir',
'total': 'Tilsamans',
'total-records': 'Skrár tilsamans',
'traffic': 'Umferð',
'transactions': 'Umsetningar',
'transfer': 'Flyt',
'transfer-website': 'Flyt heimasíðu',
'true': 'Satt',
'type': 'Slag',
'unique': 'Einstaklingar',
'unique-events': 'Einstakar hendingar',
'uniqueCustomers': 'Einstakar kundar',
'untitled': 'Einki heiti',
'update': 'Dagfør',
'url': 'URL',
'user': 'Brúkari',
'users': 'Brúkarar',
'utm': 'UTM',
'utm-campaign': 'UTM-herferð',
'utm-content': 'UTM-innihald',
'utm-description': 'Fylg herferðunum við UTM-stikum.',
'utm-medium': 'UTM-miðil',
'utm-source': 'UTM-kelda',
'utm-term': 'UTM-leitorð',
'value': 'Virði',
'version': 'Útgáva',
'view': 'Vís',
'view-only': 'Bert vísing',
'views-per-visit': 'Sýningar per vitjan',
'visits': 'Vitjanir',
'website': 'Heimasíða',
'website-id': 'Heimasíðu-ID',
'window': 'Gluggi',
'yesterday': 'Í gjár'
},
message: {
'action-confirmation': 'Skriva {confirmation} í teigin niðanfyri at vátta.',
'bad-request': 'Ógild umbøn',
'collected-data': 'Innsamlaði dáta',
'confirm-leave': 'Ert tú vís/ur í at fara frá <b>{target}</b>?',
'confirm-remove': 'Ert tú vís/ur í at strika <b>{target}</b>?',
'delete-team-warning': 'At strika eitt lið strikar eisini allar heimasíður hjá liðnum.',
'event-log': '<b>{event}</b> á <a>{url}</a>',
'forbidden': 'Forboðið',
'min-password-length': 'Minsta longd er {n} tekn',
'new-version-available': 'Nýggj útgáva av Umami {version} er tøk!',
'no-event-data': 'Eingin hendingardata tøk.',
'no-team-websites': 'Hetta liðið hevur eingi heimasíður.',
'no-teams': 'Tú hevur ikki stovnað nøkur lið.',
'no-users': 'Eingi brúkarar eru.',
'not-found': 'Ikki funnið',
'nothing-selected': 'Einki valt.',
'reset-website': 'Fyri at nullstilla hesa heimasíðu, skriva {confirmation} í teigin niðanfyri at vátta.',
'sever-error': 'Ambætaravilla',
'team-already-member': 'Tú ert longu limur í liðnum.',
'team-not-found': 'Lið ikki funnið.',
'team-websites-info': 'Heimasíður kunnu síggjas av øllum á liðnum.',
'transfer-team-website-to-user': 'Flyt hesa heimasíðu til tín konto?',
'transfer-user-website-to-team': 'Vel liðið at flyta hesa heimasíðu til.',
'transfer-website': 'Flyt ognarskapið av heimasíðuni til tín konto ella annað lið.',
'triggered-event': 'Avbjóðað hending',
'unauthorized': 'Ikki góðkent',
'user-deleted': 'Brúkari strikaður.',
'viewed-page': 'Síð vís'
}
},
'fi-FI': {
label: {
'account': 'Tili',
'action': 'Toiminto',
'add-link': 'Lisää linkki',
'add-pixel': 'Lisää pikseli',
'analysis': 'Analyysi',
'application': 'Sovellus',
'audience': 'Yleisö',
'campaign': 'Kampanja',
'channel': 'Kanava',
'chart': 'Kaavio',
'cohorts': 'Kohortit',
'criteria': 'Kriteerit',
'data': 'Data',
'destination-url': 'Kohde-URL',
'documentation': 'Dokumentaatio',
'download': 'Lataa',
'environment': 'Ympäristö',
'exclude-bounce': 'Sulje poishyppäys pois',
'growth': 'Kasvu',
'hour': 'Tunti',
'invalid-url': 'Virheellinen URL',
'link': 'Linkki',
'location': 'Sijainti',
'minute': 'Minuutti',
'month': 'Kuukausi',
'ok': 'OK',
'online': 'Verkossa',
'os': 'Käyttöjärjestelmä',
'pixel': 'Pikseli',
'preferences': 'Asetukset',
'profiles': 'Profiilit',
'retention': 'Säilyvyys',
'retention-description': 'Mittaa verkkosivustosi sitoutumista seuraamalla, kuinka usein käyttäjät palaavat.',
'save-cohort': 'Tallenna kohortti',
'save-segment': 'Tallenna segmentti',
'screen': 'Näyttö',
'segment': 'Segmentti',
'segments': 'Segmentit',
'sms': 'SMS',
'source': 'Lähde',
'support': 'Tuki',
'switch-account': 'Vaihda tiliä',
'table': 'Taulukko',
'team-view-only': 'Vain tiimin katselu',
'term': 'Hakusana',
'traffic': 'Liikenne',
'unique-events': 'Uniikit tapahtumat',
'url': 'URL',
'utm': 'UTM',
'utm-campaign': 'UTM-kampanja',
'utm-content': 'UTM-sisältö',
'utm-medium': 'UTM-media',
'utm-source': 'UTM-lähde',
'utm-term': 'UTM-hakusana',
'version': 'Versio'
},
message: {
'event-log': '<b>{event}</b> sivulla <a>{url}</a>'
}
}
};
for (const [locale, trans] of Object.entries(translations)) {
const filePath = path.join(dir, locale + '.json');
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
let count = 0;
for (const [section, keys] of Object.entries(trans)) {
for (const [key, value] of Object.entries(keys)) {
if (data[section] && key in data[section]) {
data[section][key] = value;
count++;
}
}
}
const sorted = {};
for (const section of Object.keys(enUS)) {
if (data[section]) {
sorted[section] = {};
for (const key of Object.keys(enUS[section])) {
if (key in data[section]) sorted[section][key] = data[section][key];
}
for (const key of Object.keys(data[section])) {
if (!(key in sorted[section])) sorted[section][key] = data[section][key];
}
}
}
fs.writeFileSync(filePath, JSON.stringify(sorted, null, 2) + '\n', 'utf8');
console.log('Updated ' + locale + ': ' + count + ' keys');
}