jspaint/src/app-localization.js

1114 lines
24 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// @TODO: DRY hotkey helpers
// & defines accelerators (hotkeys) in menus and buttons and things, which get underlined in the UI.
// & can be escaped by doubling it, e.g. "&Taskbar && Start Menu"
function index_of_hotkey(text) {
// Returns the index of the ampersand that defines a hotkey, or -1 if not present.
// return english_text.search(/(?<!&)&(?!&|\s)/); // not enough browser support for negative lookbehind assertions
// The space here handles beginning-of-string matching and counteracts the offset for the [^&] so it acts like a negative lookbehind
return ` ${text}`.search(/[^&]&[^&\s]/);
}
function has_hotkey(text) {
return index_of_hotkey(text) !== -1;
}
function remove_hotkey(text) {
return text.replace(/\s?\(&.\)/, "").replace(/([^&]|^)&([^&\s])/, "$1$2");
}
function display_hotkey(text) {
// misnomer: using .menu-hotkey out of laziness, instead of a more general term like .hotkey or .accelerator
return `<span style="white-space: pre">${text.replace(/([^&]|^)&([^&\s])/, "$1<span class='menu-hotkey'>$2</span>").replace(/&&/g, "&")}</span>`;
}
function get_hotkey(text) {
return text[index_of_hotkey(text) + 1].toUpperCase();
}
let localizations = {};
window.localize = (english_text, ...interpolations)=> {
function find_localization(english_text) {
const amp_index = index_of_hotkey(english_text);
if (amp_index > -1) {
const without_hotkey = remove_hotkey(english_text);
if (localizations[without_hotkey]) {
const hotkey_def = english_text.slice(amp_index, amp_index + 2);
if (localizations[without_hotkey].toUpperCase().indexOf(hotkey_def.toUpperCase()) > -1) {
return localizations[without_hotkey];
} else {
if (has_hotkey(localizations[without_hotkey])) {
// window.console && console.warn(`Localization has differing accelerator (hotkey) hint: '${localizations[without_hotkey]}' vs '${english_text}'`);
// @TODO: detect differing accelerator more generally
return `${remove_hotkey(localizations[without_hotkey])} (${hotkey_def})`;
}
return `${localizations[without_hotkey]} (${hotkey_def})`;
}
}
}
if (localizations[english_text]) {
return localizations[english_text];
}
return english_text;
}
function interpolate(text, interpolations) {
for (let i = 0; i < interpolations.length; i++) {
text = text.replace(`%${i+1}`, interpolations[i]);
}
return text;
}
return interpolate(find_localization(english_text), interpolations);
}
const language_storage_key = "jspaint language";
const accepted_languages = Array.from(navigator.languages || [navigator.language || navigator.userLanguage]);
try {
if (localStorage[language_storage_key]) {
accepted_languages.unshift(localStorage[language_storage_key]);
}
} catch (error) {
// if there's no localStorage access, you can still configure the language via system settings, theoretically
// TODO: also via URL?
}
var language_to_default_region = {
aa: 'ET',
ab: 'GE',
abr: 'GH',
ace: 'ID',
ach: 'UG',
ada: 'GH',
ady: 'RU',
ae: 'IR',
aeb: 'TN',
af: 'ZA',
agq: 'CM',
aho: 'IN',
ak: 'GH',
akk: 'IQ',
aln: 'XK',
alt: 'RU',
am: 'ET',
amo: 'NG',
aoz: 'ID',
apd: 'TG',
ar: 'EG',
arc: 'IR',
'arc-Nbat': 'JO',
'arc-Palm': 'SY',
arn: 'CL',
aro: 'BO',
arq: 'DZ',
ary: 'MA',
arz: 'EG',
as: 'IN',
asa: 'TZ',
ase: 'US',
ast: 'ES',
atj: 'CA',
av: 'RU',
awa: 'IN',
ay: 'BO',
az: 'AZ',
'az-Arab': 'IR',
ba: 'RU',
bal: 'PK',
ban: 'ID',
bap: 'NP',
bar: 'AT',
bas: 'CM',
bax: 'CM',
bbc: 'ID',
bbj: 'CM',
bci: 'CI',
be: 'BY',
bej: 'SD',
bem: 'ZM',
bew: 'ID',
bez: 'TZ',
bfd: 'CM',
bfq: 'IN',
bft: 'PK',
bfy: 'IN',
bg: 'BG',
bgc: 'IN',
bgn: 'PK',
bgx: 'TR',
bhb: 'IN',
bhi: 'IN',
bhk: 'PH',
bho: 'IN',
bi: 'VU',
bik: 'PH',
bin: 'NG',
bjj: 'IN',
bjn: 'ID',
bjt: 'SN',
bkm: 'CM',
bku: 'PH',
blt: 'VN',
bm: 'ML',
bmq: 'ML',
bn: 'BD',
bo: 'CN',
bpy: 'IN',
bqi: 'IR',
bqv: 'CI',
br: 'FR',
bra: 'IN',
brh: 'PK',
brx: 'IN',
bs: 'BA',
bsq: 'LR',
bss: 'CM',
bto: 'PH',
btv: 'PK',
bua: 'RU',
buc: 'YT',
bug: 'ID',
bum: 'CM',
bvb: 'GQ',
byn: 'ER',
byv: 'CM',
bze: 'ML',
ca: 'ES',
cch: 'NG',
ccp: 'BD',
ce: 'RU',
ceb: 'PH',
cgg: 'UG',
ch: 'GU',
chk: 'FM',
chm: 'RU',
cho: 'US',
chp: 'CA',
chr: 'US',
cja: 'KH',
cjm: 'VN',
ckb: 'IQ',
co: 'FR',
cop: 'EG',
cps: 'PH',
cr: 'CA',
crh: 'UA',
crj: 'CA',
crk: 'CA',
crl: 'CA',
crm: 'CA',
crs: 'SC',
cs: 'CZ',
csb: 'PL',
csw: 'CA',
ctd: 'MM',
cu: 'RU',
'cu-Glag': 'BG',
cv: 'RU',
cy: 'GB',
da: 'DK',
dak: 'US',
dar: 'RU',
dav: 'KE',
dcc: 'IN',
de: 'DE',
den: 'CA',
dgr: 'CA',
dje: 'NE',
dnj: 'CI',
doi: 'IN',
dsb: 'DE',
dtm: 'ML',
dtp: 'MY',
dty: 'NP',
dua: 'CM',
dv: 'MV',
dyo: 'SN',
dyu: 'BF',
dz: 'BT',
ebu: 'KE',
ee: 'GH',
efi: 'NG',
egl: 'IT',
egy: 'EG',
eky: 'MM',
el: 'GR',
en: 'US',
'en-Shaw': 'GB',
es: 'ES',
esu: 'US',
et: 'EE',
ett: 'IT',
eu: 'ES',
ewo: 'CM',
ext: 'ES',
fa: 'IR',
fan: 'GQ',
ff: 'SN',
'ff-Adlm': 'GN',
ffm: 'ML',
fi: 'FI',
fia: 'SD',
fil: 'PH',
fit: 'SE',
fj: 'FJ',
fo: 'FO',
fon: 'BJ',
fr: 'FR',
frc: 'US',
frp: 'FR',
frr: 'DE',
frs: 'DE',
fub: 'CM',
fud: 'WF',
fuf: 'GN',
fuq: 'NE',
fur: 'IT',
fuv: 'NG',
fvr: 'SD',
fy: 'NL',
ga: 'IE',
gaa: 'GH',
gag: 'MD',
gan: 'CN',
gay: 'ID',
gbm: 'IN',
gbz: 'IR',
gcr: 'GF',
gd: 'GB',
gez: 'ET',
ggn: 'NP',
gil: 'KI',
gjk: 'PK',
gju: 'PK',
gl: 'ES',
glk: 'IR',
gn: 'PY',
gom: 'IN',
gon: 'IN',
gor: 'ID',
gos: 'NL',
got: 'UA',
grc: 'CY',
'grc-Linb': 'GR',
grt: 'IN',
gsw: 'CH',
gu: 'IN',
gub: 'BR',
guc: 'CO',
gur: 'GH',
guz: 'KE',
gv: 'IM',
gvr: 'NP',
gwi: 'CA',
ha: 'NG',
hak: 'CN',
haw: 'US',
haz: 'AF',
he: 'IL',
hi: 'IN',
hif: 'FJ',
hil: 'PH',
hlu: 'TR',
hmd: 'CN',
hnd: 'PK',
hne: 'IN',
hnj: 'LA',
hnn: 'PH',
hno: 'PK',
ho: 'PG',
hoc: 'IN',
hoj: 'IN',
hr: 'HR',
hsb: 'DE',
hsn: 'CN',
ht: 'HT',
hu: 'HU',
hy: 'AM',
hz: 'NA',
ia: 'FR',
iba: 'MY',
ibb: 'NG',
id: 'ID',
ife: 'TG',
ig: 'NG',
ii: 'CN',
ik: 'US',
ikt: 'CA',
ilo: 'PH',
in: 'ID',
inh: 'RU',
is: 'IS',
it: 'IT',
iu: 'CA',
iw: 'IL',
izh: 'RU',
ja: 'JP',
jam: 'JM',
jgo: 'CM',
ji: 'UA',
jmc: 'TZ',
jml: 'NP',
jut: 'DK',
jv: 'ID',
jw: 'ID',
ka: 'GE',
kaa: 'UZ',
kab: 'DZ',
kac: 'MM',
kaj: 'NG',
kam: 'KE',
kao: 'ML',
kbd: 'RU',
kby: 'NE',
kcg: 'NG',
kck: 'ZW',
kde: 'TZ',
kdh: 'TG',
kdt: 'TH',
kea: 'CV',
ken: 'CM',
kfo: 'CI',
kfr: 'IN',
kfy: 'IN',
kg: 'CD',
kge: 'ID',
kgp: 'BR',
kha: 'IN',
khb: 'CN',
khn: 'IN',
khq: 'ML',
kht: 'IN',
khw: 'PK',
ki: 'KE',
kiu: 'TR',
kj: 'NA',
kjg: 'LA',
kk: 'KZ',
'kk-Arab': 'CN',
kkj: 'CM',
kl: 'GL',
kln: 'KE',
km: 'KH',
kmb: 'AO',
kn: 'IN',
knf: 'SN',
ko: 'KR',
koi: 'RU',
kok: 'IN',
kos: 'FM',
kpe: 'LR',
krc: 'RU',
kri: 'SL',
krj: 'PH',
krl: 'RU',
kru: 'IN',
ks: 'IN',
ksb: 'TZ',
ksf: 'CM',
ksh: 'DE',
ku: 'TR',
'ku-Arab': 'IQ',
kum: 'RU',
kv: 'RU',
kvr: 'ID',
kvx: 'PK',
kw: 'GB',
kxm: 'TH',
kxp: 'PK',
ky: 'KG',
'ky-Arab': 'CN',
'ky-Latn': 'TR',
la: 'VA',
lab: 'GR',
lad: 'IL',
lag: 'TZ',
lah: 'PK',
laj: 'UG',
lb: 'LU',
lbe: 'RU',
lbw: 'ID',
lcp: 'CN',
lep: 'IN',
lez: 'RU',
lg: 'UG',
li: 'NL',
lif: 'NP',
'lif-Limb': 'IN',
lij: 'IT',
lis: 'CN',
ljp: 'ID',
lki: 'IR',
lkt: 'US',
lmn: 'IN',
lmo: 'IT',
ln: 'CD',
lo: 'LA',
lol: 'CD',
loz: 'ZM',
lrc: 'IR',
lt: 'LT',
ltg: 'LV',
lu: 'CD',
lua: 'CD',
luo: 'KE',
luy: 'KE',
luz: 'IR',
lv: 'LV',
lwl: 'TH',
lzh: 'CN',
lzz: 'TR',
mad: 'ID',
maf: 'CM',
mag: 'IN',
mai: 'IN',
mak: 'ID',
man: 'GM',
'man-Nkoo': 'GN',
mas: 'KE',
maz: 'MX',
mdf: 'RU',
mdh: 'PH',
mdr: 'ID',
men: 'SL',
mer: 'KE',
mfa: 'TH',
mfe: 'MU',
mg: 'MG',
mgh: 'MZ',
mgo: 'CM',
mgp: 'NP',
mgy: 'TZ',
mh: 'MH',
mi: 'NZ',
min: 'ID',
mis: 'IQ',
mk: 'MK',
ml: 'IN',
mls: 'SD',
mn: 'MN',
'mn-Mong': 'CN',
mni: 'IN',
mnw: 'MM',
moe: 'CA',
moh: 'CA',
mos: 'BF',
mr: 'IN',
mrd: 'NP',
mrj: 'RU',
mro: 'BD',
ms: 'MY',
mt: 'MT',
mtr: 'IN',
mua: 'CM',
mus: 'US',
mvy: 'PK',
mwk: 'ML',
mwr: 'IN',
mwv: 'ID',
mxc: 'ZW',
my: 'MM',
myv: 'RU',
myx: 'UG',
myz: 'IR',
mzn: 'IR',
na: 'NR',
nan: 'CN',
nap: 'IT',
naq: 'NA',
nb: 'NO',
nch: 'MX',
nd: 'ZW',
ndc: 'MZ',
nds: 'DE',
ne: 'NP',
new: 'NP',
ng: 'NA',
ngl: 'MZ',
nhe: 'MX',
nhw: 'MX',
nij: 'ID',
niu: 'NU',
njo: 'IN',
nl: 'NL',
nmg: 'CM',
nn: 'NO',
nnh: 'CM',
no: 'NO',
nod: 'TH',
noe: 'IN',
non: 'SE',
nqo: 'GN',
nr: 'ZA',
nsk: 'CA',
nso: 'ZA',
nus: 'SS',
nv: 'US',
nxq: 'CN',
ny: 'MW',
nym: 'TZ',
nyn: 'UG',
nzi: 'GH',
oc: 'FR',
om: 'ET',
or: 'IN',
os: 'GE',
osa: 'US',
otk: 'MN',
pa: 'IN',
'pa-Arab': 'PK',
pag: 'PH',
pal: 'IR',
'pal-Phlp': 'CN',
pam: 'PH',
pap: 'AW',
pau: 'PW',
pcd: 'FR',
pcm: 'NG',
pdc: 'US',
pdt: 'CA',
peo: 'IR',
pfl: 'DE',
phn: 'LB',
pka: 'IN',
pko: 'KE',
pl: 'PL',
pms: 'IT',
pnt: 'GR',
pon: 'FM',
pra: 'PK',
prd: 'IR',
ps: 'AF',
pt: 'PT',//'BR',
puu: 'GA',
qu: 'PE',
quc: 'GT',
qug: 'EC',
raj: 'IN',
rcf: 'RE',
rej: 'ID',
rgn: 'IT',
ria: 'IN',
rif: 'MA',
rjs: 'NP',
rkt: 'BD',
rm: 'CH',
rmf: 'FI',
rmo: 'CH',
rmt: 'IR',
rmu: 'SE',
rn: 'BI',
rng: 'MZ',
ro: 'RO',
rob: 'ID',
rof: 'TZ',
rtm: 'FJ',
ru: 'RU',
rue: 'UA',
rug: 'SB',
rw: 'RW',
rwk: 'TZ',
ryu: 'JP',
sa: 'IN',
saf: 'GH',
sah: 'RU',
saq: 'KE',
sas: 'ID',
sat: 'IN',
sav: 'SN',
saz: 'IN',
sbp: 'TZ',
sc: 'IT',
sck: 'IN',
scn: 'IT',
sco: 'GB',
scs: 'CA',
sd: 'PK',
'sd-Deva': 'IN',
'sd-Khoj': 'IN',
'sd-Sind': 'IN',
sdc: 'IT',
sdh: 'IR',
se: 'NO',
sef: 'CI',
seh: 'MZ',
sei: 'MX',
ses: 'ML',
sg: 'CF',
sga: 'IE',
sgs: 'LT',
shi: 'MA',
shn: 'MM',
si: 'LK',
sid: 'ET',
sk: 'SK',
skr: 'PK',
sl: 'SI',
sli: 'PL',
sly: 'ID',
sm: 'WS',
sma: 'SE',
smj: 'SE',
smn: 'FI',
smp: 'IL',
sms: 'FI',
sn: 'ZW',
snk: 'ML',
so: 'SO',
sou: 'TH',
sq: 'AL',
sr: 'RS',
srb: 'IN',
srn: 'SR',
srr: 'SN',
srx: 'IN',
ss: 'ZA',
ssy: 'ER',
st: 'ZA',
stq: 'DE',
su: 'ID',
suk: 'TZ',
sus: 'GN',
sv: 'SE',
sw: 'TZ',
swb: 'YT',
swc: 'CD',
swg: 'DE',
swv: 'IN',
sxn: 'ID',
syl: 'BD',
syr: 'IQ',
szl: 'PL',
ta: 'IN',
taj: 'NP',
tbw: 'PH',
tcy: 'IN',
tdd: 'CN',
tdg: 'NP',
tdh: 'NP',
te: 'IN',
tem: 'SL',
teo: 'UG',
tet: 'TL',
tg: 'TJ',
'tg-Arab': 'PK',
th: 'TH',
thl: 'NP',
thq: 'NP',
thr: 'NP',
ti: 'ET',
tig: 'ER',
tiv: 'NG',
tk: 'TM',
tkl: 'TK',
tkr: 'AZ',
tkt: 'NP',
tl: 'PH',
tly: 'AZ',
tmh: 'NE',
tn: 'ZA',
to: 'TO',
tog: 'MW',
tpi: 'PG',
tr: 'TR',
tru: 'TR',
trv: 'TW',
ts: 'ZA',
tsd: 'GR',
tsf: 'NP',
tsg: 'PH',
tsj: 'BT',
tt: 'RU',
ttj: 'UG',
tts: 'TH',
ttt: 'AZ',
tum: 'MW',
tvl: 'TV',
twq: 'NE',
txg: 'CN',
ty: 'PF',
tyv: 'RU',
tzm: 'MA',
udm: 'RU',
ug: 'CN',
'ug-Cyrl': 'KZ',
uga: 'SY',
uk: 'UA',
uli: 'FM',
umb: 'AO',
und: 'US',
unr: 'IN',
'unr-Deva': 'NP',
unx: 'IN',
ur: 'PK',
uz: 'UZ',
'uz-Arab': 'AF',
vai: 'LR',
ve: 'ZA',
vec: 'IT',
vep: 'RU',
vi: 'VN',
vic: 'SX',
vls: 'BE',
vmf: 'DE',
vmw: 'MZ',
vot: 'RU',
vro: 'EE',
vun: 'TZ',
wa: 'BE',
wae: 'CH',
wal: 'ET',
war: 'PH',
wbp: 'AU',
wbq: 'IN',
wbr: 'IN',
wls: 'WF',
wni: 'KM',
wo: 'SN',
wtm: 'IN',
wuu: 'CN',
xav: 'BR',
xcr: 'TR',
xh: 'ZA',
xlc: 'TR',
xld: 'TR',
xmf: 'GE',
xmn: 'CN',
xmr: 'SD',
xna: 'SA',
xnr: 'IN',
xog: 'UG',
xpr: 'IR',
xsa: 'YE',
xsr: 'NP',
yao: 'MZ',
yap: 'FM',
yav: 'CM',
ybb: 'CM',
yo: 'NG',
yrl: 'BR',
yua: 'MX',
yue: 'HK',
'yue-Hans': 'CN',
za: 'CN',
zag: 'SD',
zdj: 'KM',
zea: 'NL',
zgh: 'MA',
zh: 'CN',
'zh-Bopo': 'TW',
'zh-Hanb': 'TW',
'zh-Hant': 'TW',
zlm: 'TG',
zmi: 'MY',
zu: 'ZA',
zza: 'TR',
};
function get_language_emoji(locale) {
var split = locale.toUpperCase().split(/-|_/);
var lang = split.shift();
var code = split.pop();
if (!/^[A-Z]{2}$/.test(code)) {
code = language_to_default_region[lang.toLowerCase()];
}
if (!code) {
return '';
}
const a = String.fromCodePoint(code.codePointAt(0) - 0x41 + 0x1F1E6);
const b = String.fromCodePoint(code.codePointAt(1) - 0x41 + 0x1F1E6);
return a + b;
}
const base_language = "en";
const available_languages = ["ar", "cs", "da", "de", "el", "en", "es", "fi", "fr", "he", "hu", "it", "ja", "ko", "nl", "no", "pl", "pt", "pt-br", "ru", "sk", "sl", "sv", "tr", "zh", "zh-simplified"];
const language_names = {
// "639-1": [["ISO language name"], ["Native name (endonym)"]],
ab: [["Abkhazian"], ["Аҧсуа Бызшәа", "Аҧсшәа"]],
aa: [["Afar"], ["Afaraf"]],
af: [["Afrikaans"], ["Afrikaans"]],
ak: [["Akan"], ["Akan"]],
sq: [["Albanian"], ["Shqip"]],
am: [["Amharic"], ["አማርኛ"]],
ar: [["Arabic"], ["العربية"]],
an: [["Aragonese"], ["Aragonés"]],
hy: [["Armenian"], ["Հայերեն"]],
as: [["Assamese"], ["অসমীয়া"]],
av: [["Avaric"], ["Авар МацӀ", "МагӀарул МацӀ"]],
ae: [["Avestan"], ["Avesta"]],
ay: [["Aymara"], ["Aymar Aru"]],
az: [["Azerbaijani"], ["Azərbaycan Dili"]],
bm: [["Bambara"], ["Bamanankan"]],
ba: [["Bashkir"], ["Башҡорт Теле"]],
eu: [["Basque"], ["Euskara", "Euskera"]],
be: [["Belarusian"], ["Беларуская Мова"]],
bn: [["Bengali"], ["বাংলা"]],
bh: [["Bihari Languages"], ["भोजपुरी"]],
bi: [["Bislama"], ["Bislama"]],
bs: [["Bosnian"], ["Bosanski Jezik"]],
br: [["Breton"], ["Brezhoneg"]],
bg: [["Bulgarian"], ["Български Език"]],
my: [["Burmese"], ["ဗမာစာ"]],
ca: [["Catalan", "Valencian"], ["Català", "Valencià"]],
ch: [["Chamorro"], ["Chamoru"]],
ce: [["Chechen"], ["Нохчийн Мотт"]],
ny: [["Chichewa", "Chewa", "Nyanja"], ["ChiCheŵa", "Chinyanja"]],
// zh: [["Chinese"], ["中文", "Zhōngwén", "汉语", "漢語"]],
// The ISO 639-1 code "zh" doesn't refer to Traditional Chinese specifically,
// but we want to show the distinction between Chinese varieties in the Language menu,
// so this is overly specific for now.
// @TODO: do this cleaner by establishing a mapping between ISO codes (such as "zh") and default language IDs (such as "zh-traditional")
zh: [["Traditional Chinese"], ["繁體中文", "傳統中文", "正體中文", "繁体中文"]],
"zh-traditional": [["Traditional Chinese"], ["繁體中文", "傳統中文", "正體中文", "繁体中文"]], // made-up ID, not real ISO 639-1
"zh-simplified": [["Simple Chinese"], ["简体中文"]], // made-up ID, not real ISO 639-1
cv: [["Chuvash"], ["Чӑваш Чӗлхи"]],
kw: [["Cornish"], ["Kernewek"]],
co: [["Corsican"], ["Corsu", "Lingua Corsa"]],
cr: [["Cree"], ["ᓀᐦᐃᔭᐍᐏᐣ"]],
hr: [["Croatian"], ["Hrvatski Jezik"]],
cs: [["Czech"], ["Čeština", "Český Jazyk"]],
da: [["Danish"], ["Dansk"]],
dv: [["Divehi", "Dhivehi", "Maldivian"], ["ދިވެހި"]],
nl: [["Dutch", "Flemish"], ["Nederlands", "Vlaams"]],
dz: [["Dzongkha"], ["རྫོང་ཁ"]],
en: [["English"], ["English"]],
eo: [["Esperanto"], ["Esperanto"]],
et: [["Estonian"], ["Eesti", "Eesti Keel"]],
ee: [["Ewe"], ["Eʋegbe"]],
fo: [["Faroese"], ["Føroyskt"]],
fj: [["Fijian"], ["Vosa Vakaviti"]],
fi: [["Finnish"], ["Suomi", "Suomen Kieli"]],
fr: [["French"], ["Français", "Langue Française"]],
ff: [["Fulah"], ["Fulfulde", "Pulaar", "Pular"]],
gl: [["Galician"], ["Galego"]],
ka: [["Georgian"], ["ქართული"]],
de: [["German"], ["Deutsch"]],
el: [["Greek"], ["Ελληνικά"]],
gn: [["Guarani"], ["Avañe'ẽ"]],
gu: [["Gujarati"], ["ગુજરાતી"]],
ht: [["Haitian", "Haitian Creole"], ["Kreyòl Ayisyen"]],
ha: [["Hausa"], ["هَوُسَ"]],
he: [["Hebrew"], ["עברית"]],
hz: [["Herero"], ["Otjiherero"]],
hi: [["Hindi"], ["हिन्दी", "हिंदी"]],
ho: [["Hiri Motu"], ["Hiri Motu"]],
hu: [["Hungarian"], ["Magyar"]],
ia: [["Interlingua"], ["Interlingua"]],
id: [["Indonesian"], ["Bahasa Indonesia"]],
ie: [["Interlingue", "Occidental"], ["Interlingue", "Occidental"]],
ga: [["Irish"], ["Gaeilge"]],
ig: [["Igbo"], ["Asụsụ Igbo"]],
ik: [["Inupiaq"], ["Iñupiaq", "Iñupiatun"]],
io: [["Ido"], ["Ido"]],
is: [["Icelandic"], ["Íslenska"]],
it: [["Italian"], ["Italiano"]],
iu: [["Inuktitut"], ["ᐃᓄᒃᑎᑐᑦ"]],
ja: [["Japanese"], ["日本語", "にほんご"]],
jv: [["Javanese"], ["ꦧꦱꦗꦮ", "Basa Jawa"]],
kl: [["Kalaallisut", "Greenlandic"], ["Kalaallisut", "Kalaallit Oqaasii"]],
kn: [["Kannada"], ["ಕನ್ನಡ"]],
kr: [["Kanuri"], ["Kanuri"]],
ks: [["Kashmiri"], ["कश्मीरी", "كشميري‎"]],
kk: [["Kazakh"], ["Қазақ Тілі"]],
km: [["Central Khmer"], ["ខ្មែរ", "ខេមរភាសា", "ភាសាខ្មែរ"]],
ki: [["Kikuyu", "Gikuyu"], ["Gĩkũyũ"]],
rw: [["Kinyarwanda"], ["Ikinyarwanda"]],
ky: [["Kirghiz", "Kyrgyz"], ["Кыргызча", "Кыргыз Тили"]],
kv: [["Komi"], ["Коми Кыв"]],
kg: [["Kongo"], ["Kikongo"]],
ko: [["Korean"], ["한국어"]],
ku: [["Kurdish"], ["Kurdî", "کوردی‎"]],
kj: [["Kuanyama", "Kwanyama"], ["Kuanyama"]],
la: [["Latin"], ["Latine", "Lingua Latina"]],
lb: [["Luxembourgish", "Letzeburgesch"], ["Lëtzebuergesch"]],
lg: [["Ganda"], ["Luganda"]],
li: [["Limburgan", "Limburger", "Limburgish"], ["Limburgs"]],
ln: [["Lingala"], ["Lingála"]],
lo: [["Lao"], ["ພາສາລາວ"]],
lt: [["Lithuanian"], ["Lietuvių Kalba"]],
lu: [["Luba-Katanga"], ["Kiluba"]],
lv: [["Latvian"], ["Latviešu Valoda"]],
gv: [["Manx"], ["Gaelg", "Gailck"]],
mk: [["Macedonian"], ["Македонски Јазик"]],
mg: [["Malagasy"], ["Fiteny Malagasy"]],
ms: [["Malay"], ["Bahasa Melayu", "بهاس ملايو‎"]],
ml: [["Malayalam"], ["മലയാളം"]],
mt: [["Maltese"], ["Malti"]],
mi: [["Maori"], ["Te Reo Māori"]],
mr: [["Marathi"], ["मराठी"]],
mh: [["Marshallese"], ["Kajin M̧ajeļ"]],
mn: [["Mongolian"], ["Монгол Хэл"]],
na: [["Nauru"], ["Dorerin Naoero"]],
nv: [["Navajo", "Navaho"], ["Diné Bizaad"]],
nd: [["North Ndebele"], ["IsiNdebele"]],
ne: [["Nepali"], ["नेपाली"]],
ng: [["Ndonga"], ["Owambo"]],
nb: [["Norwegian Bokmål"], ["Norsk Bokmål"]],
nn: [["Norwegian Nynorsk"], ["Norsk Nynorsk"]],
no: [["Norwegian"], ["Norsk"]],
ii: [["Sichuan Yi", "Nuosu"], ["ꆈꌠ꒿", "Nuosuhxop"]],
nr: [["South Ndebele"], ["IsiNdebele"]],
oc: [["Occitan"], ["Occitan", "Lenga d'Òc"]],
oj: [["Ojibwa"], ["ᐊᓂᔑᓈᐯᒧᐎᓐ"]],
cu: [["Church Slavic", "Old Slavonic", "Church Slavonic", "Old Bulgarian", "Old Church Slavonic"], ["Ѩзыкъ Словѣньскъ"]],
om: [["Oromo"], ["Afaan Oromoo"]],
or: [["Oriya"], ["ଓଡ଼ିଆ"]],
os: [["Ossetian", "Ossetic"], ["Ирон Æвзаг"]],
pa: [["Punjabi", "Panjabi"], ["ਪੰਜਾਬੀ", "پنجابی‎"]],
pi: [["Pali"], ["पालि", "पाळि"]],
fa: [["Persian"], ["فارسی"]],
pl: [["Polish"], ["Język Polski", "Polszczyzna"]],
ps: [["Pashto", "Pushto"], ["پښتو"]],
pt: [["Portuguese"], ["Português"]],
"pt-br": [["Brazilian Portuguese"], ["Português Brasileiro"]],
"pt-pt": [["Portuguese (Portugal)"], ["Português De Portugal"]],
qu: [["Quechua"], ["Runa Simi", "Kichwa"]],
rm: [["Romansh"], ["Rumantsch Grischun"]],
rn: [["Rundi"], ["Ikirundi"]],
ro: [["Romanian", "Moldavian", "Moldovan"], ["Română"]],
ru: [["Russian"], ["Русский"]],
sa: [["Sanskrit"], ["संस्कृतम्"]],
sc: [["Sardinian"], ["Sardu"]],
sd: [["Sindhi"], ["सिन्धी", "سنڌي، سندھی‎"]],
se: [["Northern Sami"], ["Davvisámegiella"]],
sm: [["Samoan"], ["Gagana Fa'a Samoa"]],
sg: [["Sango"], ["Yângâ Tî Sängö"]],
sr: [["Serbian"], ["Српски Језик"]],
gd: [["Gaelic", "Scottish Gaelic"], ["Gàidhlig"]],
sn: [["Shona"], ["ChiShona"]],
si: [["Sinhala", "Sinhalese"], ["සිංහල"]],
sk: [["Slovak"], ["Slovenčina", "Slovenský Jazyk"]],
sl: [["Slovenian"], ["Slovenski Jezik", "Slovenščina"]],
so: [["Somali"], ["Soomaaliga", "Af Soomaali"]],
st: [["Southern Sotho"], ["Sesotho"]],
es: [["Spanish", "Castilian"], ["Español"]],
su: [["Sundanese"], ["Basa Sunda"]],
sw: [["Swahili"], ["Kiswahili"]],
ss: [["Swati"], ["SiSwati"]],
sv: [["Swedish"], ["Svenska"]],
ta: [["Tamil"], ["தமிழ்"]],
te: [["Telugu"], ["తెలుగు"]],
tg: [["Tajik"], ["Тоҷикӣ", "Toçikī", "تاجیکی‎"]],
th: [["Thai"], ["ไทย"]],
ti: [["Tigrinya"], ["ትግርኛ"]],
bo: [["Tibetan"], ["བོད་ཡིག"]],
tk: [["Turkmen"], ["Türkmen", "Түркмен"]],
tl: [["Tagalog"], ["Wikang Tagalog"]],
tn: [["Tswana"], ["Setswana"]],
to: [["Tonga"], ["Faka Tonga"]],
tr: [["Turkish"], ["Türkçe"]],
ts: [["Tsonga"], ["Xitsonga"]],
tt: [["Tatar"], ["Татар Теле", "Tatar Tele"]],
tw: [["Twi"], ["Twi"]],
ty: [["Tahitian"], ["Reo Tahiti"]],
ug: [["Uighur", "Uyghur"], ["ئۇيغۇرچە‎", "Uyghurche"]],
uk: [["Ukrainian"], ["Українська"]],
ur: [["Urdu"], ["اردو"]],
uz: [["Uzbek"], ["Oʻzbek", "Ўзбек", "أۇزبېك‎"]],
ve: [["Venda"], ["Tshivenḓa"]],
vi: [["Vietnamese"], ["Tiếng Việt"]],
vo: [["Volapük"], ["Volapük"]],
wa: [["Walloon"], ["Walon"]],
cy: [["Welsh"], ["Cymraeg"]],
wo: [["Wolof"], ["Wollof"]],
fy: [["Western Frisian"], ["Frysk"]],
xh: [["Xhosa"], ["IsiXhosa"]],
yi: [["Yiddish"], ["ייִדיש"]],
yo: [["Yoruba"], ["Yorùbá"]],
za: [["Zhuang", "Chuang"], ["Saɯ Cueŋƅ", "Saw Cuengh"]],
zu: [["Zulu"], ["IsiZulu"]],
};
function get_iso_language_name(language) {
return language_names[language][0][0];
}
function get_language_endonym(language) {
return language_names[language][1][0];
}
let current_language = base_language;
for (const accepted_language of accepted_languages) {
if (available_languages.indexOf(accepted_language) !== -1) {
current_language = accepted_language;
break;
}
}
function get_language() {
return current_language;
}
function get_direction(language=current_language) {
return current_language.match(/^(ar|dv|fa|ha|he|ks|ku|ms|pa|ps|sd|ug|yi)\b/i) ? "rtl" : "ltr";
}
function load_language(language) {
const prev_language = current_language;
const stylesheets = [...document.querySelectorAll(".flippable-layout-stylesheet")];
for (const stylesheet of stylesheets) {
let href = stylesheet.getAttribute("href");
if (get_direction(language) === "rtl") {
if (href.indexOf(".rtl.css") === -1) {
href = href.replace(/\.css/i, ".rtl.css");
}
} else {
if (href.indexOf(".rtl.css") > -1) {
href = href.replace(/\.rtl\.css/i, ".css");
}
}
stylesheet.setAttribute("href", href);
// hack to wait for stylesheet to load
const img = document.createElement("img");
img.onerror = ()=> {
$(()=> {
$G.triggerHandler("theme-load"); // signal layout change
});
};
img.src = href;
}
if (language === base_language) {
localizations = {};
current_language = base_language;
return;
}
// fetch(`localization/${language}/localizations.json`)
// .then((response)=> response.json())
// .then((new_localizations)=> {
// localizations = new_localizations;
// current_language = language;
// }).catch((error)=> {
// show_error_message(`Failed to load localizations for ${language_names[language]}.`, error);
// current_language = prev_language;
// });
const src = `localization/${language}/localizations.js`;
document.write(`<script src="${src}"></${""/*(avoiding ending script tag if inlined in HTML)*/}script>`);
}
// JSONP callback
function loaded_localizations(language, mapping) {
localizations = mapping;
current_language = language;
}
function set_language(language) {
showMessageBox({
title: "Reload Required",
message: "The application needs to reload to change the language.",
buttons: [
{ label: localize("OK"), value: "reload", default: true },
{ label: localize("Cancel"), value: "cancel" },
],
windowOptions: {
innerWidth: 450,
},
}).then((result) => {
if (result === "reload") {
are_you_sure(() => {
try {
localStorage[language_storage_key] = language;
location.reload();
} catch (error) {
show_error_message("Failed to store language preference. Make sure cookies / local storage is enabled in your browser settings.", error);
}
});
}
});
}
load_language(current_language);