const isArray = Array.isArray; const isObject = (val) => val !== null && typeof val === "object"; const defaultDelimiters = ["{", "}"]; class BaseFormatter { constructor() { this._caches = /* @__PURE__ */ Object.create(null); } interpolate(message, values, delimiters = defaultDelimiters) { if (!values) { return [message]; } let tokens = this._caches[message]; if (!tokens) { tokens = parse(message, delimiters); this._caches[message] = tokens; } return compile(tokens, values); } } const RE_TOKEN_LIST_VALUE = /^(?:\d)+/; const RE_TOKEN_NAMED_VALUE = /^(?:\w)+/; function parse(format, [startDelimiter, endDelimiter]) { const tokens = []; let position = 0; let text = ""; while (position < format.length) { let char = format[position++]; if (char === startDelimiter) { if (text) { tokens.push({ type: "text", value: text }); } text = ""; let sub = ""; char = format[position++]; while (char !== void 0 && char !== endDelimiter) { sub += char; char = format[position++]; } const isClosed = char === endDelimiter; const type = RE_TOKEN_LIST_VALUE.test(sub) ? "list" : isClosed && RE_TOKEN_NAMED_VALUE.test(sub) ? "named" : "unknown"; tokens.push({ value: sub, type }); } else { text += char; } } text && tokens.push({ type: "text", value: text }); return tokens; } function compile(tokens, values) { const compiled = []; let index = 0; const mode = isArray(values) ? "list" : isObject(values) ? "named" : "unknown"; if (mode === "unknown") { return compiled; } while (index < tokens.length) { const token = tokens[index]; switch (token.type) { case "text": compiled.push(token.value); break; case "list": compiled.push(values[parseInt(token.value, 10)]); break; case "named": if (mode === "named") { compiled.push(values[token.value]); } else { { console.warn(`Type of token '${token.type}' and format of value '${mode}' don't match!`); } } break; case "unknown": { console.warn(`Detect 'unknown' type of token!`); } break; } index++; } return compiled; } const LOCALE_ZH_HANS = "zh-Hans"; const LOCALE_ZH_HANT = "zh-Hant"; const LOCALE_EN = "en"; const LOCALE_FR = "fr"; const LOCALE_ES = "es"; const hasOwnProperty = Object.prototype.hasOwnProperty; const hasOwn = (val, key) => hasOwnProperty.call(val, key); const defaultFormatter = new BaseFormatter(); function include(str, parts) { return !!parts.find((part) => str.indexOf(part) !== -1); } function startsWith(str, parts) { return parts.find((part) => str.indexOf(part) === 0); } function normalizeLocale(locale, messages) { if (!locale) { return; } locale = locale.trim().replace(/_/g, "-"); if (messages && messages[locale]) { return locale; } locale = locale.toLowerCase(); if (locale === "chinese") { return LOCALE_ZH_HANS; } if (locale.indexOf("zh") === 0) { if (locale.indexOf("-hans") > -1) { return LOCALE_ZH_HANS; } if (locale.indexOf("-hant") > -1) { return LOCALE_ZH_HANT; } if (include(locale, ["-tw", "-hk", "-mo", "-cht"])) { return LOCALE_ZH_HANT; } return LOCALE_ZH_HANS; } const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES]); if (lang) { return lang; } } class I18n { constructor({ locale, fallbackLocale, messages, watcher, formater }) { this.locale = LOCALE_EN; this.fallbackLocale = LOCALE_EN; this.message = {}; this.messages = {}; this.watchers = []; if (fallbackLocale) { this.fallbackLocale = fallbackLocale; } this.formater = formater || defaultFormatter; this.messages = messages || {}; this.setLocale(locale || LOCALE_EN); if (watcher) { this.watchLocale(watcher); } } setLocale(locale) { const oldLocale = this.locale; this.locale = normalizeLocale(locale, this.messages) || this.fallbackLocale; if (!this.messages[this.locale]) { this.messages[this.locale] = {}; } this.message = this.messages[this.locale]; if (oldLocale !== this.locale) { this.watchers.forEach((watcher) => { watcher(this.locale, oldLocale); }); } } getLocale() { return this.locale; } watchLocale(fn) { const index = this.watchers.push(fn) - 1; return () => { this.watchers.splice(index, 1); }; } add(locale, message, override = true) { const curMessages = this.messages[locale]; if (curMessages) { if (override) { Object.assign(curMessages, message); } else { Object.keys(message).forEach((key) => { if (!hasOwn(curMessages, key)) { curMessages[key] = message[key]; } }); } } else { this.messages[locale] = message; } } f(message, values, delimiters) { return this.formater.interpolate(message, values, delimiters).join(""); } t(key, locale, values) { let message = this.message; if (typeof locale === "string") { locale = normalizeLocale(locale, this.messages); locale && (message = this.messages[locale]); } else { values = locale; } if (!hasOwn(message, key)) { console.warn(`Cannot translate the value of keypath ${key}. Use the value of keypath as default.`); return key; } return this.formater.interpolate(message[key], values).join(""); } } function watchAppLocale(appVm, i18n) { if (appVm.$watchLocale) { appVm.$watchLocale((newLocale) => { i18n.setLocale(newLocale); }); } else { appVm.$watch(() => appVm.$locale, (newLocale) => { i18n.setLocale(newLocale); }); } } function getDefaultLocale() { if (typeof uni !== "undefined" && uni.getLocale) { return uni.getLocale(); } if (typeof global !== "undefined" && global.getLocale) { return global.getLocale(); } return LOCALE_EN; } function initVueI18n(locale, messages = {}, fallbackLocale, watcher) { if (typeof locale !== "string") { [locale, messages] = [ messages, locale ]; } if (typeof locale !== "string") { locale = getDefaultLocale(); } if (typeof fallbackLocale !== "string") { fallbackLocale = typeof __uniConfig !== "undefined" && __uniConfig.fallbackLocale || LOCALE_EN; } const i18n = new I18n({ locale, fallbackLocale, messages, watcher }); let t = (key, values) => { if (typeof getApp !== "function") { t = function(key2, values2) { return i18n.t(key2, values2); }; } else { let isWatchedAppLocale = false; t = function(key2, values2) { const appVm = getApp().$vm; if (appVm) { appVm.$locale; if (!isWatchedAppLocale) { isWatchedAppLocale = true; watchAppLocale(appVm, i18n); } } return i18n.t(key2, values2); }; } return t(key, values); }; return { i18n, f(message, values, delimiters) { return i18n.f(message, values, delimiters); }, t(key, values) { return t(key, values); }, add(locale2, message, override = true) { return i18n.add(locale2, message, override); }, watch(fn) { return i18n.watchLocale(fn); }, getLocale() { return i18n.getLocale(); }, setLocale(newLocale) { return i18n.setLocale(newLocale); } }; } export { initVueI18n as i };