oh-my-customcode 0.68.0 → 0.68.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1248,6 +1248,61 @@ async function generateAndWriteLockfileForDir(targetDir) {
1248
1248
  }
1249
1249
  }
1250
1250
 
1251
+ // src/core/rtk-installer.ts
1252
+ import { execSync } from "node:child_process";
1253
+ import { platform } from "node:os";
1254
+ function isRtkInstalled() {
1255
+ try {
1256
+ execSync("which rtk", { stdio: "pipe", timeout: 3000 });
1257
+ return true;
1258
+ } catch {
1259
+ return false;
1260
+ }
1261
+ }
1262
+ function installRtk() {
1263
+ if (process.env.CI || false || false) {
1264
+ return false;
1265
+ }
1266
+ if (isRtkInstalled()) {
1267
+ info("rtk.already_installed");
1268
+ return true;
1269
+ }
1270
+ const os = platform();
1271
+ try {
1272
+ if (os === "darwin") {
1273
+ try {
1274
+ info("rtk.installing_brew");
1275
+ execSync("brew install rtk-ai/tap/rtk", {
1276
+ stdio: "inherit",
1277
+ timeout: 120000
1278
+ });
1279
+ return true;
1280
+ } catch {
1281
+ info("rtk.installing_curl");
1282
+ execSync("curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh", {
1283
+ stdio: "inherit",
1284
+ timeout: 120000
1285
+ });
1286
+ return isRtkInstalled();
1287
+ }
1288
+ } else if (os === "linux") {
1289
+ info("rtk.installing_curl");
1290
+ execSync("curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh", {
1291
+ stdio: "inherit",
1292
+ timeout: 120000
1293
+ });
1294
+ return isRtkInstalled();
1295
+ } else {
1296
+ warn("rtk.unsupported_os", { os });
1297
+ return false;
1298
+ }
1299
+ } catch (err) {
1300
+ const message = err instanceof Error ? err.message : String(err);
1301
+ warn("rtk.install_failed", { error: message });
1302
+ return false;
1303
+ }
1304
+ }
1305
+
1251
1306
  // src/core/scope-filter.ts
1252
1307
  function getSkillScope(content) {
1253
1308
  const cleaned = content.replace(/^\uFEFF/, "");
@@ -1424,6 +1479,19 @@ async function updateInstallConfig(targetDir, options, installedComponents) {
1424
1479
  config.installedComponents = installedComponents;
1425
1480
  await saveConfig(targetDir, config);
1426
1481
  }
1482
+ function installRtkIfNeeded(result) {
1483
+ if (!isRtkInstalled()) {
1484
+ info("install.rtk_installing");
1485
+ const rtkInstalled = installRtk();
1486
+ if (rtkInstalled) {
1487
+ info("install.rtk_success");
1488
+ } else {
1489
+ result.warnings.push("RTK installation failed — install manually: brew install rtk-ai/tap/rtk");
1490
+ }
1491
+ } else {
1492
+ info("install.rtk_already");
1493
+ }
1494
+ }
1427
1495
  async function install(options) {
1428
1496
  const result = createInstallResult(options.targetDir);
1429
1497
  try {
@@ -1461,6 +1529,7 @@ async function install(options) {
1461
1529
  } else {
1462
1530
  info("install.lockfile_generated", { files: String(lockfileResult.fileCount) });
1463
1531
  }
1532
+ installRtkIfNeeded(result);
1464
1533
  result.success = true;
1465
1534
  success("install.success");
1466
1535
  } catch (err) {
@@ -1674,7 +1743,7 @@ var package_default = {
1674
1743
  workspaces: [
1675
1744
  "packages/*"
1676
1745
  ],
1677
- version: "0.68.0",
1746
+ version: "0.68.2",
1678
1747
  description: "Batteries-included agent harness for Claude Code",
1679
1748
  type: "module",
1680
1749
  bin: {
@@ -1759,6 +1828,2432 @@ var package_default = {
1759
1828
  }
1760
1829
  };
1761
1830
 
1831
+ // node_modules/.bun/i18next@26.0.2+8e24a2f921b8d7be/node_modules/i18next/dist/esm/i18next.js
1832
+ var isString = (obj) => typeof obj === "string";
1833
+ var defer = () => {
1834
+ let res;
1835
+ let rej;
1836
+ const promise = new Promise((resolve2, reject) => {
1837
+ res = resolve2;
1838
+ rej = reject;
1839
+ });
1840
+ promise.resolve = res;
1841
+ promise.reject = rej;
1842
+ return promise;
1843
+ };
1844
+ var makeString = (object) => {
1845
+ if (object == null)
1846
+ return "";
1847
+ return String(object);
1848
+ };
1849
+ var copy = (a, s, t) => {
1850
+ a.forEach((m) => {
1851
+ if (s[m])
1852
+ t[m] = s[m];
1853
+ });
1854
+ };
1855
+ var lastOfPathSeparatorRegExp = /###/g;
1856
+ var cleanKey = (key) => key && key.includes("###") ? key.replace(lastOfPathSeparatorRegExp, ".") : key;
1857
+ var canNotTraverseDeeper = (object) => !object || isString(object);
1858
+ var getLastOfPath = (object, path, Empty) => {
1859
+ const stack = !isString(path) ? path : path.split(".");
1860
+ let stackIndex = 0;
1861
+ while (stackIndex < stack.length - 1) {
1862
+ if (canNotTraverseDeeper(object))
1863
+ return {};
1864
+ const key = cleanKey(stack[stackIndex]);
1865
+ if (!object[key] && Empty)
1866
+ object[key] = new Empty;
1867
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
1868
+ object = object[key];
1869
+ } else {
1870
+ object = {};
1871
+ }
1872
+ ++stackIndex;
1873
+ }
1874
+ if (canNotTraverseDeeper(object))
1875
+ return {};
1876
+ return {
1877
+ obj: object,
1878
+ k: cleanKey(stack[stackIndex])
1879
+ };
1880
+ };
1881
+ var setPath = (object, path, newValue) => {
1882
+ const {
1883
+ obj,
1884
+ k
1885
+ } = getLastOfPath(object, path, Object);
1886
+ if (obj !== undefined || path.length === 1) {
1887
+ obj[k] = newValue;
1888
+ return;
1889
+ }
1890
+ let e = path[path.length - 1];
1891
+ let p = path.slice(0, path.length - 1);
1892
+ let last = getLastOfPath(object, p, Object);
1893
+ while (last.obj === undefined && p.length) {
1894
+ e = `${p[p.length - 1]}.${e}`;
1895
+ p = p.slice(0, p.length - 1);
1896
+ last = getLastOfPath(object, p, Object);
1897
+ if (last?.obj && typeof last.obj[`${last.k}.${e}`] !== "undefined") {
1898
+ last.obj = undefined;
1899
+ }
1900
+ }
1901
+ last.obj[`${last.k}.${e}`] = newValue;
1902
+ };
1903
+ var pushPath = (object, path, newValue, concat) => {
1904
+ const {
1905
+ obj,
1906
+ k
1907
+ } = getLastOfPath(object, path, Object);
1908
+ obj[k] = obj[k] || [];
1909
+ obj[k].push(newValue);
1910
+ };
1911
+ var getPath = (object, path) => {
1912
+ const {
1913
+ obj,
1914
+ k
1915
+ } = getLastOfPath(object, path);
1916
+ if (!obj)
1917
+ return;
1918
+ if (!Object.prototype.hasOwnProperty.call(obj, k))
1919
+ return;
1920
+ return obj[k];
1921
+ };
1922
+ var getPathWithDefaults = (data, defaultData, key) => {
1923
+ const value = getPath(data, key);
1924
+ if (value !== undefined) {
1925
+ return value;
1926
+ }
1927
+ return getPath(defaultData, key);
1928
+ };
1929
+ var deepExtend = (target, source, overwrite) => {
1930
+ for (const prop in source) {
1931
+ if (prop !== "__proto__" && prop !== "constructor") {
1932
+ if (prop in target) {
1933
+ if (isString(target[prop]) || target[prop] instanceof String || isString(source[prop]) || source[prop] instanceof String) {
1934
+ if (overwrite)
1935
+ target[prop] = source[prop];
1936
+ } else {
1937
+ deepExtend(target[prop], source[prop], overwrite);
1938
+ }
1939
+ } else {
1940
+ target[prop] = source[prop];
1941
+ }
1942
+ }
1943
+ }
1944
+ return target;
1945
+ };
1946
+ var regexEscape = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
1947
+ var _entityMap = {
1948
+ "&": "&amp;",
1949
+ "<": "&lt;",
1950
+ ">": "&gt;",
1951
+ '"': "&quot;",
1952
+ "'": "&#39;",
1953
+ "/": "&#x2F;"
1954
+ };
1955
+ var escape = (data) => {
1956
+ if (isString(data)) {
1957
+ return data.replace(/[&<>"'\/]/g, (s) => _entityMap[s]);
1958
+ }
1959
+ return data;
1960
+ };
1961
+
1962
+ class RegExpCache {
1963
+ constructor(capacity) {
1964
+ this.capacity = capacity;
1965
+ this.regExpMap = new Map;
1966
+ this.regExpQueue = [];
1967
+ }
1968
+ getRegExp(pattern) {
1969
+ const regExpFromCache = this.regExpMap.get(pattern);
1970
+ if (regExpFromCache !== undefined) {
1971
+ return regExpFromCache;
1972
+ }
1973
+ const regExpNew = new RegExp(pattern);
1974
+ if (this.regExpQueue.length === this.capacity) {
1975
+ this.regExpMap.delete(this.regExpQueue.shift());
1976
+ }
1977
+ this.regExpMap.set(pattern, regExpNew);
1978
+ this.regExpQueue.push(pattern);
1979
+ return regExpNew;
1980
+ }
1981
+ }
1982
+ var chars = [" ", ",", "?", "!", ";"];
1983
+ var looksLikeObjectPathRegExpCache = new RegExpCache(20);
1984
+ var looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
1985
+ nsSeparator = nsSeparator || "";
1986
+ keySeparator = keySeparator || "";
1987
+ const possibleChars = chars.filter((c) => !nsSeparator.includes(c) && !keySeparator.includes(c));
1988
+ if (possibleChars.length === 0)
1989
+ return true;
1990
+ const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map((c) => c === "?" ? "\\?" : c).join("|")})`);
1991
+ let matched = !r.test(key);
1992
+ if (!matched) {
1993
+ const ki = key.indexOf(keySeparator);
1994
+ if (ki > 0 && !r.test(key.substring(0, ki))) {
1995
+ matched = true;
1996
+ }
1997
+ }
1998
+ return matched;
1999
+ };
2000
+ var deepFind = (obj, path, keySeparator = ".") => {
2001
+ if (!obj)
2002
+ return;
2003
+ if (obj[path]) {
2004
+ if (!Object.prototype.hasOwnProperty.call(obj, path))
2005
+ return;
2006
+ return obj[path];
2007
+ }
2008
+ const tokens = path.split(keySeparator);
2009
+ let current = obj;
2010
+ for (let i = 0;i < tokens.length; ) {
2011
+ if (!current || typeof current !== "object") {
2012
+ return;
2013
+ }
2014
+ let next;
2015
+ let nextPath = "";
2016
+ for (let j = i;j < tokens.length; ++j) {
2017
+ if (j !== i) {
2018
+ nextPath += keySeparator;
2019
+ }
2020
+ nextPath += tokens[j];
2021
+ next = current[nextPath];
2022
+ if (next !== undefined) {
2023
+ if (["string", "number", "boolean"].includes(typeof next) && j < tokens.length - 1) {
2024
+ continue;
2025
+ }
2026
+ i += j - i + 1;
2027
+ break;
2028
+ }
2029
+ }
2030
+ current = next;
2031
+ }
2032
+ return current;
2033
+ };
2034
+ var getCleanedCode = (code) => code?.replace(/_/g, "-");
2035
+ var consoleLogger = {
2036
+ type: "logger",
2037
+ log(args) {
2038
+ this.output("log", args);
2039
+ },
2040
+ warn(args) {
2041
+ this.output("warn", args);
2042
+ },
2043
+ error(args) {
2044
+ this.output("error", args);
2045
+ },
2046
+ output(type, args) {
2047
+ console?.[type]?.apply?.(console, args);
2048
+ }
2049
+ };
2050
+
2051
+ class Logger {
2052
+ constructor(concreteLogger, options = {}) {
2053
+ this.init(concreteLogger, options);
2054
+ }
2055
+ init(concreteLogger, options = {}) {
2056
+ this.prefix = options.prefix || "i18next:";
2057
+ this.logger = concreteLogger || consoleLogger;
2058
+ this.options = options;
2059
+ this.debug = options.debug;
2060
+ }
2061
+ log(...args) {
2062
+ return this.forward(args, "log", "", true);
2063
+ }
2064
+ warn(...args) {
2065
+ return this.forward(args, "warn", "", true);
2066
+ }
2067
+ error(...args) {
2068
+ return this.forward(args, "error", "");
2069
+ }
2070
+ deprecate(...args) {
2071
+ return this.forward(args, "warn", "WARNING DEPRECATED: ", true);
2072
+ }
2073
+ forward(args, lvl, prefix, debugOnly) {
2074
+ if (debugOnly && !this.debug)
2075
+ return null;
2076
+ if (isString(args[0]))
2077
+ args[0] = `${prefix}${this.prefix} ${args[0]}`;
2078
+ return this.logger[lvl](args);
2079
+ }
2080
+ create(moduleName) {
2081
+ return new Logger(this.logger, {
2082
+ ...{
2083
+ prefix: `${this.prefix}:${moduleName}:`
2084
+ },
2085
+ ...this.options
2086
+ });
2087
+ }
2088
+ clone(options) {
2089
+ options = options || this.options;
2090
+ options.prefix = options.prefix || this.prefix;
2091
+ return new Logger(this.logger, options);
2092
+ }
2093
+ }
2094
+ var baseLogger = new Logger;
2095
+
2096
+ class EventEmitter {
2097
+ constructor() {
2098
+ this.observers = {};
2099
+ }
2100
+ on(events, listener) {
2101
+ events.split(" ").forEach((event) => {
2102
+ if (!this.observers[event])
2103
+ this.observers[event] = new Map;
2104
+ const numListeners = this.observers[event].get(listener) || 0;
2105
+ this.observers[event].set(listener, numListeners + 1);
2106
+ });
2107
+ return this;
2108
+ }
2109
+ off(event, listener) {
2110
+ if (!this.observers[event])
2111
+ return;
2112
+ if (!listener) {
2113
+ delete this.observers[event];
2114
+ return;
2115
+ }
2116
+ this.observers[event].delete(listener);
2117
+ }
2118
+ once(event, listener) {
2119
+ const wrapper = (...args) => {
2120
+ listener(...args);
2121
+ this.off(event, wrapper);
2122
+ };
2123
+ this.on(event, wrapper);
2124
+ return this;
2125
+ }
2126
+ emit(event, ...args) {
2127
+ if (this.observers[event]) {
2128
+ const cloned = Array.from(this.observers[event].entries());
2129
+ cloned.forEach(([observer, numTimesAdded]) => {
2130
+ for (let i = 0;i < numTimesAdded; i++) {
2131
+ observer(...args);
2132
+ }
2133
+ });
2134
+ }
2135
+ if (this.observers["*"]) {
2136
+ const cloned = Array.from(this.observers["*"].entries());
2137
+ cloned.forEach(([observer, numTimesAdded]) => {
2138
+ for (let i = 0;i < numTimesAdded; i++) {
2139
+ observer(event, ...args);
2140
+ }
2141
+ });
2142
+ }
2143
+ }
2144
+ }
2145
+
2146
+ class ResourceStore extends EventEmitter {
2147
+ constructor(data, options = {
2148
+ ns: ["translation"],
2149
+ defaultNS: "translation"
2150
+ }) {
2151
+ super();
2152
+ this.data = data || {};
2153
+ this.options = options;
2154
+ if (this.options.keySeparator === undefined) {
2155
+ this.options.keySeparator = ".";
2156
+ }
2157
+ if (this.options.ignoreJSONStructure === undefined) {
2158
+ this.options.ignoreJSONStructure = true;
2159
+ }
2160
+ }
2161
+ addNamespaces(ns) {
2162
+ if (!this.options.ns.includes(ns)) {
2163
+ this.options.ns.push(ns);
2164
+ }
2165
+ }
2166
+ removeNamespaces(ns) {
2167
+ const index = this.options.ns.indexOf(ns);
2168
+ if (index > -1) {
2169
+ this.options.ns.splice(index, 1);
2170
+ }
2171
+ }
2172
+ getResource(lng, ns, key, options = {}) {
2173
+ const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
2174
+ const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
2175
+ let path;
2176
+ if (lng.includes(".")) {
2177
+ path = lng.split(".");
2178
+ } else {
2179
+ path = [lng, ns];
2180
+ if (key) {
2181
+ if (Array.isArray(key)) {
2182
+ path.push(...key);
2183
+ } else if (isString(key) && keySeparator) {
2184
+ path.push(...key.split(keySeparator));
2185
+ } else {
2186
+ path.push(key);
2187
+ }
2188
+ }
2189
+ }
2190
+ const result = getPath(this.data, path);
2191
+ if (!result && !ns && !key && lng.includes(".")) {
2192
+ lng = path[0];
2193
+ ns = path[1];
2194
+ key = path.slice(2).join(".");
2195
+ }
2196
+ if (result || !ignoreJSONStructure || !isString(key))
2197
+ return result;
2198
+ return deepFind(this.data?.[lng]?.[ns], key, keySeparator);
2199
+ }
2200
+ addResource(lng, ns, key, value, options = {
2201
+ silent: false
2202
+ }) {
2203
+ const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
2204
+ let path = [lng, ns];
2205
+ if (key)
2206
+ path = path.concat(keySeparator ? key.split(keySeparator) : key);
2207
+ if (lng.includes(".")) {
2208
+ path = lng.split(".");
2209
+ value = ns;
2210
+ ns = path[1];
2211
+ }
2212
+ this.addNamespaces(ns);
2213
+ setPath(this.data, path, value);
2214
+ if (!options.silent)
2215
+ this.emit("added", lng, ns, key, value);
2216
+ }
2217
+ addResources(lng, ns, resources, options = {
2218
+ silent: false
2219
+ }) {
2220
+ for (const m in resources) {
2221
+ if (isString(resources[m]) || Array.isArray(resources[m]))
2222
+ this.addResource(lng, ns, m, resources[m], {
2223
+ silent: true
2224
+ });
2225
+ }
2226
+ if (!options.silent)
2227
+ this.emit("added", lng, ns, resources);
2228
+ }
2229
+ addResourceBundle(lng, ns, resources, deep, overwrite, options = {
2230
+ silent: false,
2231
+ skipCopy: false
2232
+ }) {
2233
+ let path = [lng, ns];
2234
+ if (lng.includes(".")) {
2235
+ path = lng.split(".");
2236
+ deep = resources;
2237
+ resources = ns;
2238
+ ns = path[1];
2239
+ }
2240
+ this.addNamespaces(ns);
2241
+ let pack = getPath(this.data, path) || {};
2242
+ if (!options.skipCopy)
2243
+ resources = JSON.parse(JSON.stringify(resources));
2244
+ if (deep) {
2245
+ deepExtend(pack, resources, overwrite);
2246
+ } else {
2247
+ pack = {
2248
+ ...pack,
2249
+ ...resources
2250
+ };
2251
+ }
2252
+ setPath(this.data, path, pack);
2253
+ if (!options.silent)
2254
+ this.emit("added", lng, ns, resources);
2255
+ }
2256
+ removeResourceBundle(lng, ns) {
2257
+ if (this.hasResourceBundle(lng, ns)) {
2258
+ delete this.data[lng][ns];
2259
+ }
2260
+ this.removeNamespaces(ns);
2261
+ this.emit("removed", lng, ns);
2262
+ }
2263
+ hasResourceBundle(lng, ns) {
2264
+ return this.getResource(lng, ns) !== undefined;
2265
+ }
2266
+ getResourceBundle(lng, ns) {
2267
+ if (!ns)
2268
+ ns = this.options.defaultNS;
2269
+ return this.getResource(lng, ns);
2270
+ }
2271
+ getDataByLanguage(lng) {
2272
+ return this.data[lng];
2273
+ }
2274
+ hasLanguageSomeTranslations(lng) {
2275
+ const data = this.getDataByLanguage(lng);
2276
+ const n = data && Object.keys(data) || [];
2277
+ return !!n.find((v) => data[v] && Object.keys(data[v]).length > 0);
2278
+ }
2279
+ toJSON() {
2280
+ return this.data;
2281
+ }
2282
+ }
2283
+ var postProcessor = {
2284
+ processors: {},
2285
+ addPostProcessor(module) {
2286
+ this.processors[module.name] = module;
2287
+ },
2288
+ handle(processors, value, key, options, translator) {
2289
+ processors.forEach((processor) => {
2290
+ value = this.processors[processor]?.process(value, key, options, translator) ?? value;
2291
+ });
2292
+ return value;
2293
+ }
2294
+ };
2295
+ var PATH_KEY = Symbol("i18next/PATH_KEY");
2296
+ function createProxy() {
2297
+ const state = [];
2298
+ const handler = Object.create(null);
2299
+ let proxy;
2300
+ handler.get = (target, key) => {
2301
+ proxy?.revoke?.();
2302
+ if (key === PATH_KEY)
2303
+ return state;
2304
+ state.push(key);
2305
+ proxy = Proxy.revocable(target, handler);
2306
+ return proxy.proxy;
2307
+ };
2308
+ return Proxy.revocable(Object.create(null), handler).proxy;
2309
+ }
2310
+ function keysFromSelector(selector, opts) {
2311
+ const {
2312
+ [PATH_KEY]: path
2313
+ } = selector(createProxy());
2314
+ const keySeparator = opts?.keySeparator ?? ".";
2315
+ const nsSeparator = opts?.nsSeparator ?? ":";
2316
+ if (path.length > 1 && nsSeparator) {
2317
+ const ns = opts?.ns;
2318
+ const nsArray = Array.isArray(ns) ? ns : null;
2319
+ if (nsArray && nsArray.length > 1 && nsArray.slice(1).includes(path[0])) {
2320
+ return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
2321
+ }
2322
+ }
2323
+ return path.join(keySeparator);
2324
+ }
2325
+ var shouldHandleAsObject = (res) => !isString(res) && typeof res !== "boolean" && typeof res !== "number";
2326
+
2327
+ class Translator extends EventEmitter {
2328
+ constructor(services, options = {}) {
2329
+ super();
2330
+ copy(["resourceStore", "languageUtils", "pluralResolver", "interpolator", "backendConnector", "i18nFormat", "utils"], services, this);
2331
+ this.options = options;
2332
+ if (this.options.keySeparator === undefined) {
2333
+ this.options.keySeparator = ".";
2334
+ }
2335
+ this.logger = baseLogger.create("translator");
2336
+ this.checkedLoadedFor = {};
2337
+ }
2338
+ changeLanguage(lng) {
2339
+ if (lng)
2340
+ this.language = lng;
2341
+ }
2342
+ exists(key, o = {
2343
+ interpolation: {}
2344
+ }) {
2345
+ const opt = {
2346
+ ...o
2347
+ };
2348
+ if (key == null)
2349
+ return false;
2350
+ const resolved = this.resolve(key, opt);
2351
+ if (resolved?.res === undefined)
2352
+ return false;
2353
+ const isObject = shouldHandleAsObject(resolved.res);
2354
+ if (opt.returnObjects === false && isObject) {
2355
+ return false;
2356
+ }
2357
+ return true;
2358
+ }
2359
+ extractFromKey(key, opt) {
2360
+ let nsSeparator = opt.nsSeparator !== undefined ? opt.nsSeparator : this.options.nsSeparator;
2361
+ if (nsSeparator === undefined)
2362
+ nsSeparator = ":";
2363
+ const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
2364
+ let namespaces = opt.ns || this.options.defaultNS || [];
2365
+ const wouldCheckForNsInKey = nsSeparator && key.includes(nsSeparator);
2366
+ const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !opt.keySeparator && !this.options.userDefinedNsSeparator && !opt.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
2367
+ if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
2368
+ const m = key.match(this.interpolator.nestingRegexp);
2369
+ if (m && m.length > 0) {
2370
+ return {
2371
+ key,
2372
+ namespaces: isString(namespaces) ? [namespaces] : namespaces
2373
+ };
2374
+ }
2375
+ const parts = key.split(nsSeparator);
2376
+ if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.includes(parts[0]))
2377
+ namespaces = parts.shift();
2378
+ key = parts.join(keySeparator);
2379
+ }
2380
+ return {
2381
+ key,
2382
+ namespaces: isString(namespaces) ? [namespaces] : namespaces
2383
+ };
2384
+ }
2385
+ translate(keys, o, lastKey) {
2386
+ let opt = typeof o === "object" ? {
2387
+ ...o
2388
+ } : o;
2389
+ if (typeof opt !== "object" && this.options.overloadTranslationOptionHandler) {
2390
+ opt = this.options.overloadTranslationOptionHandler(arguments);
2391
+ }
2392
+ if (typeof opt === "object")
2393
+ opt = {
2394
+ ...opt
2395
+ };
2396
+ if (!opt)
2397
+ opt = {};
2398
+ if (keys == null)
2399
+ return "";
2400
+ if (typeof keys === "function")
2401
+ keys = keysFromSelector(keys, {
2402
+ ...this.options,
2403
+ ...opt
2404
+ });
2405
+ if (!Array.isArray(keys))
2406
+ keys = [String(keys)];
2407
+ keys = keys.map((k) => typeof k === "function" ? keysFromSelector(k, {
2408
+ ...this.options,
2409
+ ...opt
2410
+ }) : String(k));
2411
+ const returnDetails = opt.returnDetails !== undefined ? opt.returnDetails : this.options.returnDetails;
2412
+ const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
2413
+ const {
2414
+ key,
2415
+ namespaces
2416
+ } = this.extractFromKey(keys[keys.length - 1], opt);
2417
+ const namespace = namespaces[namespaces.length - 1];
2418
+ let nsSeparator = opt.nsSeparator !== undefined ? opt.nsSeparator : this.options.nsSeparator;
2419
+ if (nsSeparator === undefined)
2420
+ nsSeparator = ":";
2421
+ const lng = opt.lng || this.language;
2422
+ const appendNamespaceToCIMode = opt.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
2423
+ if (lng?.toLowerCase() === "cimode") {
2424
+ if (appendNamespaceToCIMode) {
2425
+ if (returnDetails) {
2426
+ return {
2427
+ res: `${namespace}${nsSeparator}${key}`,
2428
+ usedKey: key,
2429
+ exactUsedKey: key,
2430
+ usedLng: lng,
2431
+ usedNS: namespace,
2432
+ usedParams: this.getUsedParamsDetails(opt)
2433
+ };
2434
+ }
2435
+ return `${namespace}${nsSeparator}${key}`;
2436
+ }
2437
+ if (returnDetails) {
2438
+ return {
2439
+ res: key,
2440
+ usedKey: key,
2441
+ exactUsedKey: key,
2442
+ usedLng: lng,
2443
+ usedNS: namespace,
2444
+ usedParams: this.getUsedParamsDetails(opt)
2445
+ };
2446
+ }
2447
+ return key;
2448
+ }
2449
+ const resolved = this.resolve(keys, opt);
2450
+ let res = resolved?.res;
2451
+ const resUsedKey = resolved?.usedKey || key;
2452
+ const resExactUsedKey = resolved?.exactUsedKey || key;
2453
+ const noObject = ["[object Number]", "[object Function]", "[object RegExp]"];
2454
+ const joinArrays = opt.joinArrays !== undefined ? opt.joinArrays : this.options.joinArrays;
2455
+ const handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject;
2456
+ const needsPluralHandling = opt.count !== undefined && !isString(opt.count);
2457
+ const hasDefaultValue = Translator.hasDefaultValue(opt);
2458
+ const defaultValueSuffix = needsPluralHandling ? this.pluralResolver.getSuffix(lng, opt.count, opt) : "";
2459
+ const defaultValueSuffixOrdinalFallback = opt.ordinal && needsPluralHandling ? this.pluralResolver.getSuffix(lng, opt.count, {
2460
+ ordinal: false
2461
+ }) : "";
2462
+ const needsZeroSuffixLookup = needsPluralHandling && !opt.ordinal && opt.count === 0;
2463
+ const defaultValue = needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] || opt[`defaultValue${defaultValueSuffix}`] || opt[`defaultValue${defaultValueSuffixOrdinalFallback}`] || opt.defaultValue;
2464
+ let resForObjHndl = res;
2465
+ if (handleAsObjectInI18nFormat && !res && hasDefaultValue) {
2466
+ resForObjHndl = defaultValue;
2467
+ }
2468
+ const handleAsObject = shouldHandleAsObject(resForObjHndl);
2469
+ const resType = Object.prototype.toString.apply(resForObjHndl);
2470
+ if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && !noObject.includes(resType) && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
2471
+ if (!opt.returnObjects && !this.options.returnObjects) {
2472
+ if (!this.options.returnedObjectHandler) {
2473
+ this.logger.warn("accessing an object - but returnObjects options is not enabled!");
2474
+ }
2475
+ const r = this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, resForObjHndl, {
2476
+ ...opt,
2477
+ ns: namespaces
2478
+ }) : `key '${key} (${this.language})' returned an object instead of string.`;
2479
+ if (returnDetails) {
2480
+ resolved.res = r;
2481
+ resolved.usedParams = this.getUsedParamsDetails(opt);
2482
+ return resolved;
2483
+ }
2484
+ return r;
2485
+ }
2486
+ if (keySeparator) {
2487
+ const resTypeIsArray = Array.isArray(resForObjHndl);
2488
+ const copy2 = resTypeIsArray ? [] : {};
2489
+ const newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey;
2490
+ for (const m in resForObjHndl) {
2491
+ if (Object.prototype.hasOwnProperty.call(resForObjHndl, m)) {
2492
+ const deepKey = `${newKeyToUse}${keySeparator}${m}`;
2493
+ if (hasDefaultValue && !res) {
2494
+ copy2[m] = this.translate(deepKey, {
2495
+ ...opt,
2496
+ defaultValue: shouldHandleAsObject(defaultValue) ? defaultValue[m] : undefined,
2497
+ ...{
2498
+ joinArrays: false,
2499
+ ns: namespaces
2500
+ }
2501
+ });
2502
+ } else {
2503
+ copy2[m] = this.translate(deepKey, {
2504
+ ...opt,
2505
+ ...{
2506
+ joinArrays: false,
2507
+ ns: namespaces
2508
+ }
2509
+ });
2510
+ }
2511
+ if (copy2[m] === deepKey)
2512
+ copy2[m] = resForObjHndl[m];
2513
+ }
2514
+ }
2515
+ res = copy2;
2516
+ }
2517
+ } else if (handleAsObjectInI18nFormat && isString(joinArrays) && Array.isArray(res)) {
2518
+ res = res.join(joinArrays);
2519
+ if (res)
2520
+ res = this.extendTranslation(res, keys, opt, lastKey);
2521
+ } else {
2522
+ let usedDefault = false;
2523
+ let usedKey = false;
2524
+ if (!this.isValidLookup(res) && hasDefaultValue) {
2525
+ usedDefault = true;
2526
+ res = defaultValue;
2527
+ }
2528
+ if (!this.isValidLookup(res)) {
2529
+ usedKey = true;
2530
+ res = key;
2531
+ }
2532
+ const missingKeyNoValueFallbackToKey = opt.missingKeyNoValueFallbackToKey || this.options.missingKeyNoValueFallbackToKey;
2533
+ const resForMissing = missingKeyNoValueFallbackToKey && usedKey ? undefined : res;
2534
+ const updateMissing = hasDefaultValue && defaultValue !== res && this.options.updateMissing;
2535
+ if (usedKey || usedDefault || updateMissing) {
2536
+ this.logger.log(updateMissing ? "updateKey" : "missingKey", lng, namespace, key, updateMissing ? defaultValue : res);
2537
+ if (keySeparator) {
2538
+ const fk = this.resolve(key, {
2539
+ ...opt,
2540
+ keySeparator: false
2541
+ });
2542
+ if (fk && fk.res)
2543
+ this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.");
2544
+ }
2545
+ let lngs = [];
2546
+ const fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, opt.lng || this.language);
2547
+ if (this.options.saveMissingTo === "fallback" && fallbackLngs && fallbackLngs[0]) {
2548
+ for (let i = 0;i < fallbackLngs.length; i++) {
2549
+ lngs.push(fallbackLngs[i]);
2550
+ }
2551
+ } else if (this.options.saveMissingTo === "all") {
2552
+ lngs = this.languageUtils.toResolveHierarchy(opt.lng || this.language);
2553
+ } else {
2554
+ lngs.push(opt.lng || this.language);
2555
+ }
2556
+ const send = (l, k, specificDefaultValue) => {
2557
+ const defaultForMissing = hasDefaultValue && specificDefaultValue !== res ? specificDefaultValue : resForMissing;
2558
+ if (this.options.missingKeyHandler) {
2559
+ this.options.missingKeyHandler(l, namespace, k, defaultForMissing, updateMissing, opt);
2560
+ } else if (this.backendConnector?.saveMissing) {
2561
+ this.backendConnector.saveMissing(l, namespace, k, defaultForMissing, updateMissing, opt);
2562
+ }
2563
+ this.emit("missingKey", l, namespace, k, res);
2564
+ };
2565
+ if (this.options.saveMissing) {
2566
+ if (this.options.saveMissingPlurals && needsPluralHandling) {
2567
+ lngs.forEach((language) => {
2568
+ const suffixes = this.pluralResolver.getSuffixes(language, opt);
2569
+ if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && !suffixes.includes(`${this.options.pluralSeparator}zero`)) {
2570
+ suffixes.push(`${this.options.pluralSeparator}zero`);
2571
+ }
2572
+ suffixes.forEach((suffix) => {
2573
+ send([language], key + suffix, opt[`defaultValue${suffix}`] || defaultValue);
2574
+ });
2575
+ });
2576
+ } else {
2577
+ send(lngs, key, defaultValue);
2578
+ }
2579
+ }
2580
+ }
2581
+ res = this.extendTranslation(res, keys, opt, resolved, lastKey);
2582
+ if (usedKey && res === key && this.options.appendNamespaceToMissingKey) {
2583
+ res = `${namespace}${nsSeparator}${key}`;
2584
+ }
2585
+ if ((usedKey || usedDefault) && this.options.parseMissingKeyHandler) {
2586
+ res = this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey ? `${namespace}${nsSeparator}${key}` : key, usedDefault ? res : undefined, opt);
2587
+ }
2588
+ }
2589
+ if (returnDetails) {
2590
+ resolved.res = res;
2591
+ resolved.usedParams = this.getUsedParamsDetails(opt);
2592
+ return resolved;
2593
+ }
2594
+ return res;
2595
+ }
2596
+ extendTranslation(res, key, opt, resolved, lastKey) {
2597
+ if (this.i18nFormat?.parse) {
2598
+ res = this.i18nFormat.parse(res, {
2599
+ ...this.options.interpolation.defaultVariables,
2600
+ ...opt
2601
+ }, opt.lng || this.language || resolved.usedLng, resolved.usedNS, resolved.usedKey, {
2602
+ resolved
2603
+ });
2604
+ } else if (!opt.skipInterpolation) {
2605
+ if (opt.interpolation)
2606
+ this.interpolator.init({
2607
+ ...opt,
2608
+ ...{
2609
+ interpolation: {
2610
+ ...this.options.interpolation,
2611
+ ...opt.interpolation
2612
+ }
2613
+ }
2614
+ });
2615
+ const skipOnVariables = isString(res) && (opt?.interpolation?.skipOnVariables !== undefined ? opt.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables);
2616
+ let nestBef;
2617
+ if (skipOnVariables) {
2618
+ const nb = res.match(this.interpolator.nestingRegexp);
2619
+ nestBef = nb && nb.length;
2620
+ }
2621
+ let data = opt.replace && !isString(opt.replace) ? opt.replace : opt;
2622
+ if (this.options.interpolation.defaultVariables)
2623
+ data = {
2624
+ ...this.options.interpolation.defaultVariables,
2625
+ ...data
2626
+ };
2627
+ res = this.interpolator.interpolate(res, data, opt.lng || this.language || resolved.usedLng, opt);
2628
+ if (skipOnVariables) {
2629
+ const na = res.match(this.interpolator.nestingRegexp);
2630
+ const nestAft = na && na.length;
2631
+ if (nestBef < nestAft)
2632
+ opt.nest = false;
2633
+ }
2634
+ if (!opt.lng && resolved && resolved.res)
2635
+ opt.lng = this.language || resolved.usedLng;
2636
+ if (opt.nest !== false)
2637
+ res = this.interpolator.nest(res, (...args) => {
2638
+ if (lastKey?.[0] === args[0] && !opt.context) {
2639
+ this.logger.warn(`It seems you are nesting recursively key: ${args[0]} in key: ${key[0]}`);
2640
+ return null;
2641
+ }
2642
+ return this.translate(...args, key);
2643
+ }, opt);
2644
+ if (opt.interpolation)
2645
+ this.interpolator.reset();
2646
+ }
2647
+ const postProcess = opt.postProcess || this.options.postProcess;
2648
+ const postProcessorNames = isString(postProcess) ? [postProcess] : postProcess;
2649
+ if (res != null && postProcessorNames?.length && opt.applyPostProcessor !== false) {
2650
+ res = postProcessor.handle(postProcessorNames, res, key, this.options && this.options.postProcessPassResolved ? {
2651
+ i18nResolved: {
2652
+ ...resolved,
2653
+ usedParams: this.getUsedParamsDetails(opt)
2654
+ },
2655
+ ...opt
2656
+ } : opt, this);
2657
+ }
2658
+ return res;
2659
+ }
2660
+ resolve(keys, opt = {}) {
2661
+ let found;
2662
+ let usedKey;
2663
+ let exactUsedKey;
2664
+ let usedLng;
2665
+ let usedNS;
2666
+ if (isString(keys))
2667
+ keys = [keys];
2668
+ if (Array.isArray(keys))
2669
+ keys = keys.map((k) => typeof k === "function" ? keysFromSelector(k, {
2670
+ ...this.options,
2671
+ ...opt
2672
+ }) : k);
2673
+ keys.forEach((k) => {
2674
+ if (this.isValidLookup(found))
2675
+ return;
2676
+ const extracted = this.extractFromKey(k, opt);
2677
+ const key = extracted.key;
2678
+ usedKey = key;
2679
+ let namespaces = extracted.namespaces;
2680
+ if (this.options.fallbackNS)
2681
+ namespaces = namespaces.concat(this.options.fallbackNS);
2682
+ const needsPluralHandling = opt.count !== undefined && !isString(opt.count);
2683
+ const needsZeroSuffixLookup = needsPluralHandling && !opt.ordinal && opt.count === 0;
2684
+ const needsContextHandling = opt.context !== undefined && (isString(opt.context) || typeof opt.context === "number") && opt.context !== "";
2685
+ const codes = opt.lngs ? opt.lngs : this.languageUtils.toResolveHierarchy(opt.lng || this.language, opt.fallbackLng);
2686
+ namespaces.forEach((ns) => {
2687
+ if (this.isValidLookup(found))
2688
+ return;
2689
+ usedNS = ns;
2690
+ if (!this.checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
2691
+ this.checkedLoadedFor[`${codes[0]}-${ns}`] = true;
2692
+ this.logger.warn(`key "${usedKey}" for languages "${codes.join(", ")}" won't get resolved as namespace "${usedNS}" was not yet loaded`, "This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");
2693
+ }
2694
+ codes.forEach((code) => {
2695
+ if (this.isValidLookup(found))
2696
+ return;
2697
+ usedLng = code;
2698
+ const finalKeys = [key];
2699
+ if (this.i18nFormat?.addLookupKeys) {
2700
+ this.i18nFormat.addLookupKeys(finalKeys, key, code, ns, opt);
2701
+ } else {
2702
+ let pluralSuffix;
2703
+ if (needsPluralHandling)
2704
+ pluralSuffix = this.pluralResolver.getSuffix(code, opt.count, opt);
2705
+ const zeroSuffix = `${this.options.pluralSeparator}zero`;
2706
+ const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
2707
+ if (needsPluralHandling) {
2708
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
2709
+ finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
2710
+ }
2711
+ finalKeys.push(key + pluralSuffix);
2712
+ if (needsZeroSuffixLookup) {
2713
+ finalKeys.push(key + zeroSuffix);
2714
+ }
2715
+ }
2716
+ if (needsContextHandling) {
2717
+ const contextKey = `${key}${this.options.contextSeparator || "_"}${opt.context}`;
2718
+ finalKeys.push(contextKey);
2719
+ if (needsPluralHandling) {
2720
+ if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
2721
+ finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
2722
+ }
2723
+ finalKeys.push(contextKey + pluralSuffix);
2724
+ if (needsZeroSuffixLookup) {
2725
+ finalKeys.push(contextKey + zeroSuffix);
2726
+ }
2727
+ }
2728
+ }
2729
+ }
2730
+ let possibleKey;
2731
+ while (possibleKey = finalKeys.pop()) {
2732
+ if (!this.isValidLookup(found)) {
2733
+ exactUsedKey = possibleKey;
2734
+ found = this.getResource(code, ns, possibleKey, opt);
2735
+ }
2736
+ }
2737
+ });
2738
+ });
2739
+ });
2740
+ return {
2741
+ res: found,
2742
+ usedKey,
2743
+ exactUsedKey,
2744
+ usedLng,
2745
+ usedNS
2746
+ };
2747
+ }
2748
+ isValidLookup(res) {
2749
+ return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === "");
2750
+ }
2751
+ getResource(code, ns, key, options = {}) {
2752
+ if (this.i18nFormat?.getResource)
2753
+ return this.i18nFormat.getResource(code, ns, key, options);
2754
+ return this.resourceStore.getResource(code, ns, key, options);
2755
+ }
2756
+ getUsedParamsDetails(options = {}) {
2757
+ const optionsKeys = ["defaultValue", "ordinal", "context", "replace", "lng", "lngs", "fallbackLng", "ns", "keySeparator", "nsSeparator", "returnObjects", "returnDetails", "joinArrays", "postProcess", "interpolation"];
2758
+ const useOptionsReplaceForData = options.replace && !isString(options.replace);
2759
+ let data = useOptionsReplaceForData ? options.replace : options;
2760
+ if (useOptionsReplaceForData && typeof options.count !== "undefined") {
2761
+ data.count = options.count;
2762
+ }
2763
+ if (this.options.interpolation.defaultVariables) {
2764
+ data = {
2765
+ ...this.options.interpolation.defaultVariables,
2766
+ ...data
2767
+ };
2768
+ }
2769
+ if (!useOptionsReplaceForData) {
2770
+ data = {
2771
+ ...data
2772
+ };
2773
+ for (const key of optionsKeys) {
2774
+ delete data[key];
2775
+ }
2776
+ }
2777
+ return data;
2778
+ }
2779
+ static hasDefaultValue(options) {
2780
+ const prefix = "defaultValue";
2781
+ for (const option in options) {
2782
+ if (Object.prototype.hasOwnProperty.call(options, option) && option.startsWith(prefix) && options[option] !== undefined) {
2783
+ return true;
2784
+ }
2785
+ }
2786
+ return false;
2787
+ }
2788
+ }
2789
+
2790
+ class LanguageUtil {
2791
+ constructor(options) {
2792
+ this.options = options;
2793
+ this.supportedLngs = this.options.supportedLngs || false;
2794
+ this.logger = baseLogger.create("languageUtils");
2795
+ }
2796
+ getScriptPartFromCode(code) {
2797
+ code = getCleanedCode(code);
2798
+ if (!code || !code.includes("-"))
2799
+ return null;
2800
+ const p = code.split("-");
2801
+ if (p.length === 2)
2802
+ return null;
2803
+ p.pop();
2804
+ if (p[p.length - 1].toLowerCase() === "x")
2805
+ return null;
2806
+ return this.formatLanguageCode(p.join("-"));
2807
+ }
2808
+ getLanguagePartFromCode(code) {
2809
+ code = getCleanedCode(code);
2810
+ if (!code || !code.includes("-"))
2811
+ return code;
2812
+ const p = code.split("-");
2813
+ return this.formatLanguageCode(p[0]);
2814
+ }
2815
+ formatLanguageCode(code) {
2816
+ if (isString(code) && code.includes("-")) {
2817
+ let formattedCode;
2818
+ try {
2819
+ formattedCode = Intl.getCanonicalLocales(code)[0];
2820
+ } catch (e) {}
2821
+ if (formattedCode && this.options.lowerCaseLng) {
2822
+ formattedCode = formattedCode.toLowerCase();
2823
+ }
2824
+ if (formattedCode)
2825
+ return formattedCode;
2826
+ if (this.options.lowerCaseLng) {
2827
+ return code.toLowerCase();
2828
+ }
2829
+ return code;
2830
+ }
2831
+ return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code;
2832
+ }
2833
+ isSupportedCode(code) {
2834
+ if (this.options.load === "languageOnly" || this.options.nonExplicitSupportedLngs) {
2835
+ code = this.getLanguagePartFromCode(code);
2836
+ }
2837
+ return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.includes(code);
2838
+ }
2839
+ getBestMatchFromCodes(codes) {
2840
+ if (!codes)
2841
+ return null;
2842
+ let found;
2843
+ codes.forEach((code) => {
2844
+ if (found)
2845
+ return;
2846
+ const cleanedLng = this.formatLanguageCode(code);
2847
+ if (!this.options.supportedLngs || this.isSupportedCode(cleanedLng))
2848
+ found = cleanedLng;
2849
+ });
2850
+ if (!found && this.options.supportedLngs) {
2851
+ codes.forEach((code) => {
2852
+ if (found)
2853
+ return;
2854
+ const lngScOnly = this.getScriptPartFromCode(code);
2855
+ if (this.isSupportedCode(lngScOnly))
2856
+ return found = lngScOnly;
2857
+ const lngOnly = this.getLanguagePartFromCode(code);
2858
+ if (this.isSupportedCode(lngOnly))
2859
+ return found = lngOnly;
2860
+ found = this.options.supportedLngs.find((supportedLng) => {
2861
+ if (supportedLng === lngOnly)
2862
+ return true;
2863
+ if (!supportedLng.includes("-") && !lngOnly.includes("-"))
2864
+ return false;
2865
+ if (supportedLng.includes("-") && !lngOnly.includes("-") && supportedLng.slice(0, supportedLng.indexOf("-")) === lngOnly)
2866
+ return true;
2867
+ if (supportedLng.startsWith(lngOnly) && lngOnly.length > 1)
2868
+ return true;
2869
+ return false;
2870
+ });
2871
+ });
2872
+ }
2873
+ if (!found)
2874
+ found = this.getFallbackCodes(this.options.fallbackLng)[0];
2875
+ return found;
2876
+ }
2877
+ getFallbackCodes(fallbacks, code) {
2878
+ if (!fallbacks)
2879
+ return [];
2880
+ if (typeof fallbacks === "function")
2881
+ fallbacks = fallbacks(code);
2882
+ if (isString(fallbacks))
2883
+ fallbacks = [fallbacks];
2884
+ if (Array.isArray(fallbacks))
2885
+ return fallbacks;
2886
+ if (!code)
2887
+ return fallbacks.default || [];
2888
+ let found = fallbacks[code];
2889
+ if (!found)
2890
+ found = fallbacks[this.getScriptPartFromCode(code)];
2891
+ if (!found)
2892
+ found = fallbacks[this.formatLanguageCode(code)];
2893
+ if (!found)
2894
+ found = fallbacks[this.getLanguagePartFromCode(code)];
2895
+ if (!found)
2896
+ found = fallbacks.default;
2897
+ return found || [];
2898
+ }
2899
+ toResolveHierarchy(code, fallbackCode) {
2900
+ const fallbackCodes = this.getFallbackCodes((fallbackCode === false ? [] : fallbackCode) || this.options.fallbackLng || [], code);
2901
+ const codes = [];
2902
+ const addCode = (c) => {
2903
+ if (!c)
2904
+ return;
2905
+ if (this.isSupportedCode(c)) {
2906
+ codes.push(c);
2907
+ } else {
2908
+ this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
2909
+ }
2910
+ };
2911
+ if (isString(code) && (code.includes("-") || code.includes("_"))) {
2912
+ if (this.options.load !== "languageOnly")
2913
+ addCode(this.formatLanguageCode(code));
2914
+ if (this.options.load !== "languageOnly" && this.options.load !== "currentOnly")
2915
+ addCode(this.getScriptPartFromCode(code));
2916
+ if (this.options.load !== "currentOnly")
2917
+ addCode(this.getLanguagePartFromCode(code));
2918
+ } else if (isString(code)) {
2919
+ addCode(this.formatLanguageCode(code));
2920
+ }
2921
+ fallbackCodes.forEach((fc) => {
2922
+ if (!codes.includes(fc))
2923
+ addCode(this.formatLanguageCode(fc));
2924
+ });
2925
+ return codes;
2926
+ }
2927
+ }
2928
+ var suffixesOrder = {
2929
+ zero: 0,
2930
+ one: 1,
2931
+ two: 2,
2932
+ few: 3,
2933
+ many: 4,
2934
+ other: 5
2935
+ };
2936
+ var dummyRule = {
2937
+ select: (count) => count === 1 ? "one" : "other",
2938
+ resolvedOptions: () => ({
2939
+ pluralCategories: ["one", "other"]
2940
+ })
2941
+ };
2942
+
2943
+ class PluralResolver {
2944
+ constructor(languageUtils, options = {}) {
2945
+ this.languageUtils = languageUtils;
2946
+ this.options = options;
2947
+ this.logger = baseLogger.create("pluralResolver");
2948
+ this.pluralRulesCache = {};
2949
+ }
2950
+ clearCache() {
2951
+ this.pluralRulesCache = {};
2952
+ }
2953
+ getRule(code, options = {}) {
2954
+ const cleanedCode = getCleanedCode(code === "dev" ? "en" : code);
2955
+ const type = options.ordinal ? "ordinal" : "cardinal";
2956
+ const cacheKey = JSON.stringify({
2957
+ cleanedCode,
2958
+ type
2959
+ });
2960
+ if (cacheKey in this.pluralRulesCache) {
2961
+ return this.pluralRulesCache[cacheKey];
2962
+ }
2963
+ let rule;
2964
+ try {
2965
+ rule = new Intl.PluralRules(cleanedCode, {
2966
+ type
2967
+ });
2968
+ } catch (err) {
2969
+ if (typeof Intl === "undefined") {
2970
+ this.logger.error("No Intl support, please use an Intl polyfill!");
2971
+ return dummyRule;
2972
+ }
2973
+ if (!code.match(/-|_/))
2974
+ return dummyRule;
2975
+ const lngPart = this.languageUtils.getLanguagePartFromCode(code);
2976
+ rule = this.getRule(lngPart, options);
2977
+ }
2978
+ this.pluralRulesCache[cacheKey] = rule;
2979
+ return rule;
2980
+ }
2981
+ needsPlural(code, options = {}) {
2982
+ let rule = this.getRule(code, options);
2983
+ if (!rule)
2984
+ rule = this.getRule("dev", options);
2985
+ return rule?.resolvedOptions().pluralCategories.length > 1;
2986
+ }
2987
+ getPluralFormsOfKey(code, key, options = {}) {
2988
+ return this.getSuffixes(code, options).map((suffix) => `${key}${suffix}`);
2989
+ }
2990
+ getSuffixes(code, options = {}) {
2991
+ let rule = this.getRule(code, options);
2992
+ if (!rule)
2993
+ rule = this.getRule("dev", options);
2994
+ if (!rule)
2995
+ return [];
2996
+ return rule.resolvedOptions().pluralCategories.sort((pluralCategory1, pluralCategory2) => suffixesOrder[pluralCategory1] - suffixesOrder[pluralCategory2]).map((pluralCategory) => `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ""}${pluralCategory}`);
2997
+ }
2998
+ getSuffix(code, count, options = {}) {
2999
+ const rule = this.getRule(code, options);
3000
+ if (rule) {
3001
+ return `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ""}${rule.select(count)}`;
3002
+ }
3003
+ this.logger.warn(`no plural rule found for: ${code}`);
3004
+ return this.getSuffix("dev", count, options);
3005
+ }
3006
+ }
3007
+ var deepFindWithDefaults = (data, defaultData, key, keySeparator = ".", ignoreJSONStructure = true) => {
3008
+ let path = getPathWithDefaults(data, defaultData, key);
3009
+ if (!path && ignoreJSONStructure && isString(key)) {
3010
+ path = deepFind(data, key, keySeparator);
3011
+ if (path === undefined)
3012
+ path = deepFind(defaultData, key, keySeparator);
3013
+ }
3014
+ return path;
3015
+ };
3016
+ var regexSafe = (val) => val.replace(/\$/g, "$$$$");
3017
+
3018
+ class Interpolator {
3019
+ constructor(options = {}) {
3020
+ this.logger = baseLogger.create("interpolator");
3021
+ this.options = options;
3022
+ this.format = options?.interpolation?.format || ((value) => value);
3023
+ this.init(options);
3024
+ }
3025
+ init(options = {}) {
3026
+ if (!options.interpolation)
3027
+ options.interpolation = {
3028
+ escapeValue: true
3029
+ };
3030
+ const {
3031
+ escape: escape$1,
3032
+ escapeValue,
3033
+ useRawValueToEscape,
3034
+ prefix,
3035
+ prefixEscaped,
3036
+ suffix,
3037
+ suffixEscaped,
3038
+ formatSeparator,
3039
+ unescapeSuffix,
3040
+ unescapePrefix,
3041
+ nestingPrefix,
3042
+ nestingPrefixEscaped,
3043
+ nestingSuffix,
3044
+ nestingSuffixEscaped,
3045
+ nestingOptionsSeparator,
3046
+ maxReplaces,
3047
+ alwaysFormat
3048
+ } = options.interpolation;
3049
+ this.escape = escape$1 !== undefined ? escape$1 : escape;
3050
+ this.escapeValue = escapeValue !== undefined ? escapeValue : true;
3051
+ this.useRawValueToEscape = useRawValueToEscape !== undefined ? useRawValueToEscape : false;
3052
+ this.prefix = prefix ? regexEscape(prefix) : prefixEscaped || "{{";
3053
+ this.suffix = suffix ? regexEscape(suffix) : suffixEscaped || "}}";
3054
+ this.formatSeparator = formatSeparator || ",";
3055
+ this.unescapePrefix = unescapeSuffix ? "" : unescapePrefix || "-";
3056
+ this.unescapeSuffix = this.unescapePrefix ? "" : unescapeSuffix || "";
3057
+ this.nestingPrefix = nestingPrefix ? regexEscape(nestingPrefix) : nestingPrefixEscaped || regexEscape("$t(");
3058
+ this.nestingSuffix = nestingSuffix ? regexEscape(nestingSuffix) : nestingSuffixEscaped || regexEscape(")");
3059
+ this.nestingOptionsSeparator = nestingOptionsSeparator || ",";
3060
+ this.maxReplaces = maxReplaces || 1000;
3061
+ this.alwaysFormat = alwaysFormat !== undefined ? alwaysFormat : false;
3062
+ this.resetRegExp();
3063
+ }
3064
+ reset() {
3065
+ if (this.options)
3066
+ this.init(this.options);
3067
+ }
3068
+ resetRegExp() {
3069
+ const getOrResetRegExp = (existingRegExp, pattern) => {
3070
+ if (existingRegExp?.source === pattern) {
3071
+ existingRegExp.lastIndex = 0;
3072
+ return existingRegExp;
3073
+ }
3074
+ return new RegExp(pattern, "g");
3075
+ };
3076
+ this.regexp = getOrResetRegExp(this.regexp, `${this.prefix}(.+?)${this.suffix}`);
3077
+ this.regexpUnescape = getOrResetRegExp(this.regexpUnescape, `${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`);
3078
+ this.nestingRegexp = getOrResetRegExp(this.nestingRegexp, `${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`);
3079
+ }
3080
+ interpolate(str, data, lng, options) {
3081
+ let match;
3082
+ let value;
3083
+ let replaces;
3084
+ const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
3085
+ const handleFormat = (key) => {
3086
+ if (!key.includes(this.formatSeparator)) {
3087
+ const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
3088
+ return this.alwaysFormat ? this.format(path, undefined, lng, {
3089
+ ...options,
3090
+ ...data,
3091
+ interpolationkey: key
3092
+ }) : path;
3093
+ }
3094
+ const p = key.split(this.formatSeparator);
3095
+ const k = p.shift().trim();
3096
+ const f = p.join(this.formatSeparator).trim();
3097
+ return this.format(deepFindWithDefaults(data, defaultData, k, this.options.keySeparator, this.options.ignoreJSONStructure), f, lng, {
3098
+ ...options,
3099
+ ...data,
3100
+ interpolationkey: k
3101
+ });
3102
+ };
3103
+ this.resetRegExp();
3104
+ const missingInterpolationHandler = options?.missingInterpolationHandler || this.options.missingInterpolationHandler;
3105
+ const skipOnVariables = options?.interpolation?.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
3106
+ const todos = [{
3107
+ regex: this.regexpUnescape,
3108
+ safeValue: (val) => regexSafe(val)
3109
+ }, {
3110
+ regex: this.regexp,
3111
+ safeValue: (val) => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
3112
+ }];
3113
+ todos.forEach((todo) => {
3114
+ replaces = 0;
3115
+ while (match = todo.regex.exec(str)) {
3116
+ const matchedVar = match[1].trim();
3117
+ value = handleFormat(matchedVar);
3118
+ if (value === undefined) {
3119
+ if (typeof missingInterpolationHandler === "function") {
3120
+ const temp = missingInterpolationHandler(str, match, options);
3121
+ value = isString(temp) ? temp : "";
3122
+ } else if (options && Object.prototype.hasOwnProperty.call(options, matchedVar)) {
3123
+ value = "";
3124
+ } else if (skipOnVariables) {
3125
+ value = match[0];
3126
+ continue;
3127
+ } else {
3128
+ this.logger.warn(`missed to pass in variable ${matchedVar} for interpolating ${str}`);
3129
+ value = "";
3130
+ }
3131
+ } else if (!isString(value) && !this.useRawValueToEscape) {
3132
+ value = makeString(value);
3133
+ }
3134
+ const safeValue = todo.safeValue(value);
3135
+ str = str.replace(match[0], safeValue);
3136
+ if (skipOnVariables) {
3137
+ todo.regex.lastIndex += value.length;
3138
+ todo.regex.lastIndex -= match[0].length;
3139
+ } else {
3140
+ todo.regex.lastIndex = 0;
3141
+ }
3142
+ replaces++;
3143
+ if (replaces >= this.maxReplaces) {
3144
+ break;
3145
+ }
3146
+ }
3147
+ });
3148
+ return str;
3149
+ }
3150
+ nest(str, fc, options = {}) {
3151
+ let match;
3152
+ let value;
3153
+ let clonedOptions;
3154
+ const handleHasOptions = (key, inheritedOptions) => {
3155
+ const sep2 = this.nestingOptionsSeparator;
3156
+ if (!key.includes(sep2))
3157
+ return key;
3158
+ const c = key.split(new RegExp(`${regexEscape(sep2)}[ ]*{`));
3159
+ let optionsString = `{${c[1]}`;
3160
+ key = c[0];
3161
+ optionsString = this.interpolate(optionsString, clonedOptions);
3162
+ const matchedSingleQuotes = optionsString.match(/'/g);
3163
+ const matchedDoubleQuotes = optionsString.match(/"/g);
3164
+ if ((matchedSingleQuotes?.length ?? 0) % 2 === 0 && !matchedDoubleQuotes || (matchedDoubleQuotes?.length ?? 0) % 2 !== 0) {
3165
+ optionsString = optionsString.replace(/'/g, '"');
3166
+ }
3167
+ try {
3168
+ clonedOptions = JSON.parse(optionsString);
3169
+ if (inheritedOptions)
3170
+ clonedOptions = {
3171
+ ...inheritedOptions,
3172
+ ...clonedOptions
3173
+ };
3174
+ } catch (e) {
3175
+ this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
3176
+ return `${key}${sep2}${optionsString}`;
3177
+ }
3178
+ if (clonedOptions.defaultValue && clonedOptions.defaultValue.includes(this.prefix))
3179
+ delete clonedOptions.defaultValue;
3180
+ return key;
3181
+ };
3182
+ while (match = this.nestingRegexp.exec(str)) {
3183
+ let formatters = [];
3184
+ clonedOptions = {
3185
+ ...options
3186
+ };
3187
+ clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
3188
+ clonedOptions.applyPostProcessor = false;
3189
+ delete clonedOptions.defaultValue;
3190
+ const keyEndIndex = /{.*}/.test(match[1]) ? match[1].lastIndexOf("}") + 1 : match[1].indexOf(this.formatSeparator);
3191
+ if (keyEndIndex !== -1) {
3192
+ formatters = match[1].slice(keyEndIndex).split(this.formatSeparator).map((elem) => elem.trim()).filter(Boolean);
3193
+ match[1] = match[1].slice(0, keyEndIndex);
3194
+ }
3195
+ value = fc(handleHasOptions.call(this, match[1].trim(), clonedOptions), clonedOptions);
3196
+ if (value && match[0] === str && !isString(value))
3197
+ return value;
3198
+ if (!isString(value))
3199
+ value = makeString(value);
3200
+ if (!value) {
3201
+ this.logger.warn(`missed to resolve ${match[1]} for nesting ${str}`);
3202
+ value = "";
3203
+ }
3204
+ if (formatters.length) {
3205
+ value = formatters.reduce((v, f) => this.format(v, f, options.lng, {
3206
+ ...options,
3207
+ interpolationkey: match[1].trim()
3208
+ }), value.trim());
3209
+ }
3210
+ str = str.replace(match[0], value);
3211
+ this.regexp.lastIndex = 0;
3212
+ }
3213
+ return str;
3214
+ }
3215
+ }
3216
+ var parseFormatStr = (formatStr) => {
3217
+ let formatName = formatStr.toLowerCase().trim();
3218
+ const formatOptions = {};
3219
+ if (formatStr.includes("(")) {
3220
+ const p = formatStr.split("(");
3221
+ formatName = p[0].toLowerCase().trim();
3222
+ const optStr = p[1].slice(0, -1);
3223
+ if (formatName === "currency" && !optStr.includes(":")) {
3224
+ if (!formatOptions.currency)
3225
+ formatOptions.currency = optStr.trim();
3226
+ } else if (formatName === "relativetime" && !optStr.includes(":")) {
3227
+ if (!formatOptions.range)
3228
+ formatOptions.range = optStr.trim();
3229
+ } else {
3230
+ const opts = optStr.split(";");
3231
+ opts.forEach((opt) => {
3232
+ if (opt) {
3233
+ const [key, ...rest] = opt.split(":");
3234
+ const val = rest.join(":").trim().replace(/^'+|'+$/g, "");
3235
+ const trimmedKey = key.trim();
3236
+ if (!formatOptions[trimmedKey])
3237
+ formatOptions[trimmedKey] = val;
3238
+ if (val === "false")
3239
+ formatOptions[trimmedKey] = false;
3240
+ if (val === "true")
3241
+ formatOptions[trimmedKey] = true;
3242
+ if (!isNaN(val))
3243
+ formatOptions[trimmedKey] = parseInt(val, 10);
3244
+ }
3245
+ });
3246
+ }
3247
+ }
3248
+ return {
3249
+ formatName,
3250
+ formatOptions
3251
+ };
3252
+ };
3253
+ var createCachedFormatter = (fn) => {
3254
+ const cache = {};
3255
+ return (v, l, o) => {
3256
+ let optForCache = o;
3257
+ if (o && o.interpolationkey && o.formatParams && o.formatParams[o.interpolationkey] && o[o.interpolationkey]) {
3258
+ optForCache = {
3259
+ ...optForCache,
3260
+ [o.interpolationkey]: undefined
3261
+ };
3262
+ }
3263
+ const key = l + JSON.stringify(optForCache);
3264
+ let frm = cache[key];
3265
+ if (!frm) {
3266
+ frm = fn(getCleanedCode(l), o);
3267
+ cache[key] = frm;
3268
+ }
3269
+ return frm(v);
3270
+ };
3271
+ };
3272
+ var createNonCachedFormatter = (fn) => (v, l, o) => fn(getCleanedCode(l), o)(v);
3273
+
3274
+ class Formatter {
3275
+ constructor(options = {}) {
3276
+ this.logger = baseLogger.create("formatter");
3277
+ this.options = options;
3278
+ this.init(options);
3279
+ }
3280
+ init(services, options = {
3281
+ interpolation: {}
3282
+ }) {
3283
+ this.formatSeparator = options.interpolation.formatSeparator || ",";
3284
+ const cf = options.cacheInBuiltFormats ? createCachedFormatter : createNonCachedFormatter;
3285
+ this.formats = {
3286
+ number: cf((lng, opt) => {
3287
+ const formatter = new Intl.NumberFormat(lng, {
3288
+ ...opt
3289
+ });
3290
+ return (val) => formatter.format(val);
3291
+ }),
3292
+ currency: cf((lng, opt) => {
3293
+ const formatter = new Intl.NumberFormat(lng, {
3294
+ ...opt,
3295
+ style: "currency"
3296
+ });
3297
+ return (val) => formatter.format(val);
3298
+ }),
3299
+ datetime: cf((lng, opt) => {
3300
+ const formatter = new Intl.DateTimeFormat(lng, {
3301
+ ...opt
3302
+ });
3303
+ return (val) => formatter.format(val);
3304
+ }),
3305
+ relativetime: cf((lng, opt) => {
3306
+ const formatter = new Intl.RelativeTimeFormat(lng, {
3307
+ ...opt
3308
+ });
3309
+ return (val) => formatter.format(val, opt.range || "day");
3310
+ }),
3311
+ list: cf((lng, opt) => {
3312
+ const formatter = new Intl.ListFormat(lng, {
3313
+ ...opt
3314
+ });
3315
+ return (val) => formatter.format(val);
3316
+ })
3317
+ };
3318
+ }
3319
+ add(name, fc) {
3320
+ this.formats[name.toLowerCase().trim()] = fc;
3321
+ }
3322
+ addCached(name, fc) {
3323
+ this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
3324
+ }
3325
+ format(value, format, lng, options = {}) {
3326
+ if (!format)
3327
+ return value;
3328
+ if (value == null)
3329
+ return value;
3330
+ const formats = format.split(this.formatSeparator);
3331
+ if (formats.length > 1 && formats[0].indexOf("(") > 1 && !formats[0].includes(")") && formats.find((f) => f.includes(")"))) {
3332
+ const lastIndex = formats.findIndex((f) => f.includes(")"));
3333
+ formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
3334
+ }
3335
+ const result = formats.reduce((mem, f) => {
3336
+ const {
3337
+ formatName,
3338
+ formatOptions
3339
+ } = parseFormatStr(f);
3340
+ if (this.formats[formatName]) {
3341
+ let formatted = mem;
3342
+ try {
3343
+ const valOptions = options?.formatParams?.[options.interpolationkey] || {};
3344
+ const l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
3345
+ formatted = this.formats[formatName](mem, l, {
3346
+ ...formatOptions,
3347
+ ...options,
3348
+ ...valOptions
3349
+ });
3350
+ } catch (error2) {
3351
+ this.logger.warn(error2);
3352
+ }
3353
+ return formatted;
3354
+ } else {
3355
+ this.logger.warn(`there was no format function for ${formatName}`);
3356
+ }
3357
+ return mem;
3358
+ }, value);
3359
+ return result;
3360
+ }
3361
+ }
3362
+ var removePending = (q, name) => {
3363
+ if (q.pending[name] !== undefined) {
3364
+ delete q.pending[name];
3365
+ q.pendingCount--;
3366
+ }
3367
+ };
3368
+
3369
+ class Connector extends EventEmitter {
3370
+ constructor(backend, store, services, options = {}) {
3371
+ super();
3372
+ this.backend = backend;
3373
+ this.store = store;
3374
+ this.services = services;
3375
+ this.languageUtils = services.languageUtils;
3376
+ this.options = options;
3377
+ this.logger = baseLogger.create("backendConnector");
3378
+ this.waitingReads = [];
3379
+ this.maxParallelReads = options.maxParallelReads || 10;
3380
+ this.readingCalls = 0;
3381
+ this.maxRetries = options.maxRetries >= 0 ? options.maxRetries : 5;
3382
+ this.retryTimeout = options.retryTimeout >= 1 ? options.retryTimeout : 350;
3383
+ this.state = {};
3384
+ this.queue = [];
3385
+ this.backend?.init?.(services, options.backend, options);
3386
+ }
3387
+ queueLoad(languages, namespaces, options, callback) {
3388
+ const toLoad = {};
3389
+ const pending = {};
3390
+ const toLoadLanguages = {};
3391
+ const toLoadNamespaces = {};
3392
+ languages.forEach((lng) => {
3393
+ let hasAllNamespaces = true;
3394
+ namespaces.forEach((ns) => {
3395
+ const name = `${lng}|${ns}`;
3396
+ if (!options.reload && this.store.hasResourceBundle(lng, ns)) {
3397
+ this.state[name] = 2;
3398
+ } else if (this.state[name] < 0)
3399
+ ;
3400
+ else if (this.state[name] === 1) {
3401
+ if (pending[name] === undefined)
3402
+ pending[name] = true;
3403
+ } else {
3404
+ this.state[name] = 1;
3405
+ hasAllNamespaces = false;
3406
+ if (pending[name] === undefined)
3407
+ pending[name] = true;
3408
+ if (toLoad[name] === undefined)
3409
+ toLoad[name] = true;
3410
+ if (toLoadNamespaces[ns] === undefined)
3411
+ toLoadNamespaces[ns] = true;
3412
+ }
3413
+ });
3414
+ if (!hasAllNamespaces)
3415
+ toLoadLanguages[lng] = true;
3416
+ });
3417
+ if (Object.keys(toLoad).length || Object.keys(pending).length) {
3418
+ this.queue.push({
3419
+ pending,
3420
+ pendingCount: Object.keys(pending).length,
3421
+ loaded: {},
3422
+ errors: [],
3423
+ callback
3424
+ });
3425
+ }
3426
+ return {
3427
+ toLoad: Object.keys(toLoad),
3428
+ pending: Object.keys(pending),
3429
+ toLoadLanguages: Object.keys(toLoadLanguages),
3430
+ toLoadNamespaces: Object.keys(toLoadNamespaces)
3431
+ };
3432
+ }
3433
+ loaded(name, err, data) {
3434
+ const s = name.split("|");
3435
+ const lng = s[0];
3436
+ const ns = s[1];
3437
+ if (err)
3438
+ this.emit("failedLoading", lng, ns, err);
3439
+ if (!err && data) {
3440
+ this.store.addResourceBundle(lng, ns, data, undefined, undefined, {
3441
+ skipCopy: true
3442
+ });
3443
+ }
3444
+ this.state[name] = err ? -1 : 2;
3445
+ if (err && data)
3446
+ this.state[name] = 0;
3447
+ const loaded = {};
3448
+ this.queue.forEach((q) => {
3449
+ pushPath(q.loaded, [lng], ns);
3450
+ removePending(q, name);
3451
+ if (err)
3452
+ q.errors.push(err);
3453
+ if (q.pendingCount === 0 && !q.done) {
3454
+ Object.keys(q.loaded).forEach((l) => {
3455
+ if (!loaded[l])
3456
+ loaded[l] = {};
3457
+ const loadedKeys = q.loaded[l];
3458
+ if (loadedKeys.length) {
3459
+ loadedKeys.forEach((n) => {
3460
+ if (loaded[l][n] === undefined)
3461
+ loaded[l][n] = true;
3462
+ });
3463
+ }
3464
+ });
3465
+ q.done = true;
3466
+ if (q.errors.length) {
3467
+ q.callback(q.errors);
3468
+ } else {
3469
+ q.callback();
3470
+ }
3471
+ }
3472
+ });
3473
+ this.emit("loaded", loaded);
3474
+ this.queue = this.queue.filter((q) => !q.done);
3475
+ }
3476
+ read(lng, ns, fcName, tried = 0, wait = this.retryTimeout, callback) {
3477
+ if (!lng.length)
3478
+ return callback(null, {});
3479
+ if (this.readingCalls >= this.maxParallelReads) {
3480
+ this.waitingReads.push({
3481
+ lng,
3482
+ ns,
3483
+ fcName,
3484
+ tried,
3485
+ wait,
3486
+ callback
3487
+ });
3488
+ return;
3489
+ }
3490
+ this.readingCalls++;
3491
+ const resolver = (err, data) => {
3492
+ this.readingCalls--;
3493
+ if (this.waitingReads.length > 0) {
3494
+ const next = this.waitingReads.shift();
3495
+ this.read(next.lng, next.ns, next.fcName, next.tried, next.wait, next.callback);
3496
+ }
3497
+ if (err && data && tried < this.maxRetries) {
3498
+ setTimeout(() => {
3499
+ this.read(lng, ns, fcName, tried + 1, wait * 2, callback);
3500
+ }, wait);
3501
+ return;
3502
+ }
3503
+ callback(err, data);
3504
+ };
3505
+ const fc = this.backend[fcName].bind(this.backend);
3506
+ if (fc.length === 2) {
3507
+ try {
3508
+ const r = fc(lng, ns);
3509
+ if (r && typeof r.then === "function") {
3510
+ r.then((data) => resolver(null, data)).catch(resolver);
3511
+ } else {
3512
+ resolver(null, r);
3513
+ }
3514
+ } catch (err) {
3515
+ resolver(err);
3516
+ }
3517
+ return;
3518
+ }
3519
+ return fc(lng, ns, resolver);
3520
+ }
3521
+ prepareLoading(languages, namespaces, options = {}, callback) {
3522
+ if (!this.backend) {
3523
+ this.logger.warn("No backend was added via i18next.use. Will not load resources.");
3524
+ return callback && callback();
3525
+ }
3526
+ if (isString(languages))
3527
+ languages = this.languageUtils.toResolveHierarchy(languages);
3528
+ if (isString(namespaces))
3529
+ namespaces = [namespaces];
3530
+ const toLoad = this.queueLoad(languages, namespaces, options, callback);
3531
+ if (!toLoad.toLoad.length) {
3532
+ if (!toLoad.pending.length)
3533
+ callback();
3534
+ return null;
3535
+ }
3536
+ toLoad.toLoad.forEach((name) => {
3537
+ this.loadOne(name);
3538
+ });
3539
+ }
3540
+ load(languages, namespaces, callback) {
3541
+ this.prepareLoading(languages, namespaces, {}, callback);
3542
+ }
3543
+ reload(languages, namespaces, callback) {
3544
+ this.prepareLoading(languages, namespaces, {
3545
+ reload: true
3546
+ }, callback);
3547
+ }
3548
+ loadOne(name, prefix = "") {
3549
+ const s = name.split("|");
3550
+ const lng = s[0];
3551
+ const ns = s[1];
3552
+ this.read(lng, ns, "read", undefined, undefined, (err, data) => {
3553
+ if (err)
3554
+ this.logger.warn(`${prefix}loading namespace ${ns} for language ${lng} failed`, err);
3555
+ if (!err && data)
3556
+ this.logger.log(`${prefix}loaded namespace ${ns} for language ${lng}`, data);
3557
+ this.loaded(name, err, data);
3558
+ });
3559
+ }
3560
+ saveMissing(languages, namespace, key, fallbackValue, isUpdate, options = {}, clb = () => {}) {
3561
+ if (this.services?.utils?.hasLoadedNamespace && !this.services?.utils?.hasLoadedNamespace(namespace)) {
3562
+ this.logger.warn(`did not save key "${key}" as the namespace "${namespace}" was not yet loaded`, "This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");
3563
+ return;
3564
+ }
3565
+ if (key === undefined || key === null || key === "")
3566
+ return;
3567
+ if (this.backend?.create) {
3568
+ const opts = {
3569
+ ...options,
3570
+ isUpdate
3571
+ };
3572
+ const fc = this.backend.create.bind(this.backend);
3573
+ if (fc.length < 6) {
3574
+ try {
3575
+ let r;
3576
+ if (fc.length === 5) {
3577
+ r = fc(languages, namespace, key, fallbackValue, opts);
3578
+ } else {
3579
+ r = fc(languages, namespace, key, fallbackValue);
3580
+ }
3581
+ if (r && typeof r.then === "function") {
3582
+ r.then((data) => clb(null, data)).catch(clb);
3583
+ } else {
3584
+ clb(null, r);
3585
+ }
3586
+ } catch (err) {
3587
+ clb(err);
3588
+ }
3589
+ } else {
3590
+ fc(languages, namespace, key, fallbackValue, clb, opts);
3591
+ }
3592
+ }
3593
+ if (!languages || !languages[0])
3594
+ return;
3595
+ this.store.addResource(languages[0], namespace, key, fallbackValue);
3596
+ }
3597
+ }
3598
+ var get = () => ({
3599
+ debug: false,
3600
+ initAsync: true,
3601
+ ns: ["translation"],
3602
+ defaultNS: ["translation"],
3603
+ fallbackLng: ["dev"],
3604
+ fallbackNS: false,
3605
+ supportedLngs: false,
3606
+ nonExplicitSupportedLngs: false,
3607
+ load: "all",
3608
+ preload: false,
3609
+ keySeparator: ".",
3610
+ nsSeparator: ":",
3611
+ pluralSeparator: "_",
3612
+ contextSeparator: "_",
3613
+ partialBundledLanguages: false,
3614
+ saveMissing: false,
3615
+ updateMissing: false,
3616
+ saveMissingTo: "fallback",
3617
+ saveMissingPlurals: true,
3618
+ missingKeyHandler: false,
3619
+ missingInterpolationHandler: false,
3620
+ postProcess: false,
3621
+ postProcessPassResolved: false,
3622
+ returnNull: false,
3623
+ returnEmptyString: true,
3624
+ returnObjects: false,
3625
+ joinArrays: false,
3626
+ returnedObjectHandler: false,
3627
+ parseMissingKeyHandler: false,
3628
+ appendNamespaceToMissingKey: false,
3629
+ appendNamespaceToCIMode: false,
3630
+ overloadTranslationOptionHandler: (args) => {
3631
+ let ret = {};
3632
+ if (typeof args[1] === "object")
3633
+ ret = args[1];
3634
+ if (isString(args[1]))
3635
+ ret.defaultValue = args[1];
3636
+ if (isString(args[2]))
3637
+ ret.tDescription = args[2];
3638
+ if (typeof args[2] === "object" || typeof args[3] === "object") {
3639
+ const options = args[3] || args[2];
3640
+ Object.keys(options).forEach((key) => {
3641
+ ret[key] = options[key];
3642
+ });
3643
+ }
3644
+ return ret;
3645
+ },
3646
+ interpolation: {
3647
+ escapeValue: true,
3648
+ prefix: "{{",
3649
+ suffix: "}}",
3650
+ formatSeparator: ",",
3651
+ unescapePrefix: "-",
3652
+ nestingPrefix: "$t(",
3653
+ nestingSuffix: ")",
3654
+ nestingOptionsSeparator: ",",
3655
+ maxReplaces: 1000,
3656
+ skipOnVariables: true
3657
+ },
3658
+ cacheInBuiltFormats: true
3659
+ });
3660
+ var transformOptions = (options) => {
3661
+ if (isString(options.ns))
3662
+ options.ns = [options.ns];
3663
+ if (isString(options.fallbackLng))
3664
+ options.fallbackLng = [options.fallbackLng];
3665
+ if (isString(options.fallbackNS))
3666
+ options.fallbackNS = [options.fallbackNS];
3667
+ if (options.supportedLngs && !options.supportedLngs.includes("cimode")) {
3668
+ options.supportedLngs = options.supportedLngs.concat(["cimode"]);
3669
+ }
3670
+ return options;
3671
+ };
3672
+ var noop = () => {};
3673
+ var bindMemberFunctions = (inst) => {
3674
+ const mems = Object.getOwnPropertyNames(Object.getPrototypeOf(inst));
3675
+ mems.forEach((mem) => {
3676
+ if (typeof inst[mem] === "function") {
3677
+ inst[mem] = inst[mem].bind(inst);
3678
+ }
3679
+ });
3680
+ };
3681
+
3682
+ class I18n extends EventEmitter {
3683
+ constructor(options = {}, callback) {
3684
+ super();
3685
+ this.options = transformOptions(options);
3686
+ this.services = {};
3687
+ this.logger = baseLogger;
3688
+ this.modules = {
3689
+ external: []
3690
+ };
3691
+ bindMemberFunctions(this);
3692
+ if (callback && !this.isInitialized && !options.isClone) {
3693
+ if (!this.options.initAsync) {
3694
+ this.init(options, callback);
3695
+ return this;
3696
+ }
3697
+ setTimeout(() => {
3698
+ this.init(options, callback);
3699
+ }, 0);
3700
+ }
3701
+ }
3702
+ init(options = {}, callback) {
3703
+ this.isInitializing = true;
3704
+ if (typeof options === "function") {
3705
+ callback = options;
3706
+ options = {};
3707
+ }
3708
+ if (options.defaultNS == null && options.ns) {
3709
+ if (isString(options.ns)) {
3710
+ options.defaultNS = options.ns;
3711
+ } else if (!options.ns.includes("translation")) {
3712
+ options.defaultNS = options.ns[0];
3713
+ }
3714
+ }
3715
+ const defOpts = get();
3716
+ this.options = {
3717
+ ...defOpts,
3718
+ ...this.options,
3719
+ ...transformOptions(options)
3720
+ };
3721
+ this.options.interpolation = {
3722
+ ...defOpts.interpolation,
3723
+ ...this.options.interpolation
3724
+ };
3725
+ if (options.keySeparator !== undefined) {
3726
+ this.options.userDefinedKeySeparator = options.keySeparator;
3727
+ }
3728
+ if (options.nsSeparator !== undefined) {
3729
+ this.options.userDefinedNsSeparator = options.nsSeparator;
3730
+ }
3731
+ if (typeof this.options.overloadTranslationOptionHandler !== "function") {
3732
+ this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
3733
+ }
3734
+ const createClassOnDemand = (ClassOrObject) => {
3735
+ if (!ClassOrObject)
3736
+ return null;
3737
+ if (typeof ClassOrObject === "function")
3738
+ return new ClassOrObject;
3739
+ return ClassOrObject;
3740
+ };
3741
+ if (!this.options.isClone) {
3742
+ if (this.modules.logger) {
3743
+ baseLogger.init(createClassOnDemand(this.modules.logger), this.options);
3744
+ } else {
3745
+ baseLogger.init(null, this.options);
3746
+ }
3747
+ let formatter;
3748
+ if (this.modules.formatter) {
3749
+ formatter = this.modules.formatter;
3750
+ } else {
3751
+ formatter = Formatter;
3752
+ }
3753
+ const lu = new LanguageUtil(this.options);
3754
+ this.store = new ResourceStore(this.options.resources, this.options);
3755
+ const s = this.services;
3756
+ s.logger = baseLogger;
3757
+ s.resourceStore = this.store;
3758
+ s.languageUtils = lu;
3759
+ s.pluralResolver = new PluralResolver(lu, {
3760
+ prepend: this.options.pluralSeparator
3761
+ });
3762
+ if (formatter) {
3763
+ s.formatter = createClassOnDemand(formatter);
3764
+ if (s.formatter.init)
3765
+ s.formatter.init(s, this.options);
3766
+ this.options.interpolation.format = s.formatter.format.bind(s.formatter);
3767
+ }
3768
+ s.interpolator = new Interpolator(this.options);
3769
+ s.utils = {
3770
+ hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
3771
+ };
3772
+ s.backendConnector = new Connector(createClassOnDemand(this.modules.backend), s.resourceStore, s, this.options);
3773
+ s.backendConnector.on("*", (event, ...args) => {
3774
+ this.emit(event, ...args);
3775
+ });
3776
+ if (this.modules.languageDetector) {
3777
+ s.languageDetector = createClassOnDemand(this.modules.languageDetector);
3778
+ if (s.languageDetector.init)
3779
+ s.languageDetector.init(s, this.options.detection, this.options);
3780
+ }
3781
+ if (this.modules.i18nFormat) {
3782
+ s.i18nFormat = createClassOnDemand(this.modules.i18nFormat);
3783
+ if (s.i18nFormat.init)
3784
+ s.i18nFormat.init(this);
3785
+ }
3786
+ this.translator = new Translator(this.services, this.options);
3787
+ this.translator.on("*", (event, ...args) => {
3788
+ this.emit(event, ...args);
3789
+ });
3790
+ this.modules.external.forEach((m) => {
3791
+ if (m.init)
3792
+ m.init(this);
3793
+ });
3794
+ }
3795
+ this.format = this.options.interpolation.format;
3796
+ if (!callback)
3797
+ callback = noop;
3798
+ if (this.options.fallbackLng && !this.services.languageDetector && !this.options.lng) {
3799
+ const codes = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
3800
+ if (codes.length > 0 && codes[0] !== "dev")
3801
+ this.options.lng = codes[0];
3802
+ }
3803
+ if (!this.services.languageDetector && !this.options.lng) {
3804
+ this.logger.warn("init: no languageDetector is used and no lng is defined");
3805
+ }
3806
+ const storeApi = ["getResource", "hasResourceBundle", "getResourceBundle", "getDataByLanguage"];
3807
+ storeApi.forEach((fcName) => {
3808
+ this[fcName] = (...args) => this.store[fcName](...args);
3809
+ });
3810
+ const storeApiChained = ["addResource", "addResources", "addResourceBundle", "removeResourceBundle"];
3811
+ storeApiChained.forEach((fcName) => {
3812
+ this[fcName] = (...args) => {
3813
+ this.store[fcName](...args);
3814
+ return this;
3815
+ };
3816
+ });
3817
+ const deferred = defer();
3818
+ const load = () => {
3819
+ const finish = (err, t) => {
3820
+ this.isInitializing = false;
3821
+ if (this.isInitialized && !this.initializedStoreOnce)
3822
+ this.logger.warn("init: i18next is already initialized. You should call init just once!");
3823
+ this.isInitialized = true;
3824
+ if (!this.options.isClone)
3825
+ this.logger.log("initialized", this.options);
3826
+ this.emit("initialized", this.options);
3827
+ deferred.resolve(t);
3828
+ callback(err, t);
3829
+ };
3830
+ if (this.languages && !this.isInitialized)
3831
+ return finish(null, this.t.bind(this));
3832
+ this.changeLanguage(this.options.lng, finish);
3833
+ };
3834
+ if (this.options.resources || !this.options.initAsync) {
3835
+ load();
3836
+ } else {
3837
+ setTimeout(load, 0);
3838
+ }
3839
+ return deferred;
3840
+ }
3841
+ loadResources(language, callback = noop) {
3842
+ let usedCallback = callback;
3843
+ const usedLng = isString(language) ? language : this.language;
3844
+ if (typeof language === "function")
3845
+ usedCallback = language;
3846
+ if (!this.options.resources || this.options.partialBundledLanguages) {
3847
+ if (usedLng?.toLowerCase() === "cimode" && (!this.options.preload || this.options.preload.length === 0))
3848
+ return usedCallback();
3849
+ const toLoad = [];
3850
+ const append = (lng) => {
3851
+ if (!lng)
3852
+ return;
3853
+ if (lng === "cimode")
3854
+ return;
3855
+ const lngs = this.services.languageUtils.toResolveHierarchy(lng);
3856
+ lngs.forEach((l) => {
3857
+ if (l === "cimode")
3858
+ return;
3859
+ if (!toLoad.includes(l))
3860
+ toLoad.push(l);
3861
+ });
3862
+ };
3863
+ if (!usedLng) {
3864
+ const fallbacks = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
3865
+ fallbacks.forEach((l) => append(l));
3866
+ } else {
3867
+ append(usedLng);
3868
+ }
3869
+ this.options.preload?.forEach?.((l) => append(l));
3870
+ this.services.backendConnector.load(toLoad, this.options.ns, (e) => {
3871
+ if (!e && !this.resolvedLanguage && this.language)
3872
+ this.setResolvedLanguage(this.language);
3873
+ usedCallback(e);
3874
+ });
3875
+ } else {
3876
+ usedCallback(null);
3877
+ }
3878
+ }
3879
+ reloadResources(lngs, ns, callback) {
3880
+ const deferred = defer();
3881
+ if (typeof lngs === "function") {
3882
+ callback = lngs;
3883
+ lngs = undefined;
3884
+ }
3885
+ if (typeof ns === "function") {
3886
+ callback = ns;
3887
+ ns = undefined;
3888
+ }
3889
+ if (!lngs)
3890
+ lngs = this.languages;
3891
+ if (!ns)
3892
+ ns = this.options.ns;
3893
+ if (!callback)
3894
+ callback = noop;
3895
+ this.services.backendConnector.reload(lngs, ns, (err) => {
3896
+ deferred.resolve();
3897
+ callback(err);
3898
+ });
3899
+ return deferred;
3900
+ }
3901
+ use(module) {
3902
+ if (!module)
3903
+ throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");
3904
+ if (!module.type)
3905
+ throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");
3906
+ if (module.type === "backend") {
3907
+ this.modules.backend = module;
3908
+ }
3909
+ if (module.type === "logger" || module.log && module.warn && module.error) {
3910
+ this.modules.logger = module;
3911
+ }
3912
+ if (module.type === "languageDetector") {
3913
+ this.modules.languageDetector = module;
3914
+ }
3915
+ if (module.type === "i18nFormat") {
3916
+ this.modules.i18nFormat = module;
3917
+ }
3918
+ if (module.type === "postProcessor") {
3919
+ postProcessor.addPostProcessor(module);
3920
+ }
3921
+ if (module.type === "formatter") {
3922
+ this.modules.formatter = module;
3923
+ }
3924
+ if (module.type === "3rdParty") {
3925
+ this.modules.external.push(module);
3926
+ }
3927
+ return this;
3928
+ }
3929
+ setResolvedLanguage(l) {
3930
+ if (!l || !this.languages)
3931
+ return;
3932
+ if (["cimode", "dev"].includes(l))
3933
+ return;
3934
+ for (let li = 0;li < this.languages.length; li++) {
3935
+ const lngInLngs = this.languages[li];
3936
+ if (["cimode", "dev"].includes(lngInLngs))
3937
+ continue;
3938
+ if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
3939
+ this.resolvedLanguage = lngInLngs;
3940
+ break;
3941
+ }
3942
+ }
3943
+ if (!this.resolvedLanguage && !this.languages.includes(l) && this.store.hasLanguageSomeTranslations(l)) {
3944
+ this.resolvedLanguage = l;
3945
+ this.languages.unshift(l);
3946
+ }
3947
+ }
3948
+ changeLanguage(lng, callback) {
3949
+ this.isLanguageChangingTo = lng;
3950
+ const deferred = defer();
3951
+ this.emit("languageChanging", lng);
3952
+ const setLngProps = (l) => {
3953
+ this.language = l;
3954
+ this.languages = this.services.languageUtils.toResolveHierarchy(l);
3955
+ this.resolvedLanguage = undefined;
3956
+ this.setResolvedLanguage(l);
3957
+ };
3958
+ const done = (err, l) => {
3959
+ if (l) {
3960
+ if (this.isLanguageChangingTo === lng) {
3961
+ setLngProps(l);
3962
+ this.translator.changeLanguage(l);
3963
+ this.isLanguageChangingTo = undefined;
3964
+ this.emit("languageChanged", l);
3965
+ this.logger.log("languageChanged", l);
3966
+ }
3967
+ } else {
3968
+ this.isLanguageChangingTo = undefined;
3969
+ }
3970
+ deferred.resolve((...args) => this.t(...args));
3971
+ if (callback)
3972
+ callback(err, (...args) => this.t(...args));
3973
+ };
3974
+ const setLng = (lngs) => {
3975
+ if (!lng && !lngs && this.services.languageDetector)
3976
+ lngs = [];
3977
+ const fl = isString(lngs) ? lngs : lngs && lngs[0];
3978
+ const l = this.store.hasLanguageSomeTranslations(fl) ? fl : this.services.languageUtils.getBestMatchFromCodes(isString(lngs) ? [lngs] : lngs);
3979
+ if (l) {
3980
+ if (!this.language) {
3981
+ setLngProps(l);
3982
+ }
3983
+ if (!this.translator.language)
3984
+ this.translator.changeLanguage(l);
3985
+ this.services.languageDetector?.cacheUserLanguage?.(l);
3986
+ }
3987
+ this.loadResources(l, (err) => {
3988
+ done(err, l);
3989
+ });
3990
+ };
3991
+ if (!lng && this.services.languageDetector && !this.services.languageDetector.async) {
3992
+ setLng(this.services.languageDetector.detect());
3993
+ } else if (!lng && this.services.languageDetector && this.services.languageDetector.async) {
3994
+ if (this.services.languageDetector.detect.length === 0) {
3995
+ this.services.languageDetector.detect().then(setLng);
3996
+ } else {
3997
+ this.services.languageDetector.detect(setLng);
3998
+ }
3999
+ } else {
4000
+ setLng(lng);
4001
+ }
4002
+ return deferred;
4003
+ }
4004
+ getFixedT(lng, ns, keyPrefix) {
4005
+ const fixedT = (key, opts, ...rest) => {
4006
+ let o;
4007
+ if (typeof opts !== "object") {
4008
+ o = this.options.overloadTranslationOptionHandler([key, opts].concat(rest));
4009
+ } else {
4010
+ o = {
4011
+ ...opts
4012
+ };
4013
+ }
4014
+ o.lng = o.lng || fixedT.lng;
4015
+ o.lngs = o.lngs || fixedT.lngs;
4016
+ o.ns = o.ns || fixedT.ns;
4017
+ if (o.keyPrefix !== "")
4018
+ o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
4019
+ const selectorOpts = {
4020
+ ...this.options,
4021
+ ...o
4022
+ };
4023
+ if (typeof o.keyPrefix === "function")
4024
+ o.keyPrefix = keysFromSelector(o.keyPrefix, selectorOpts);
4025
+ const keySeparator = this.options.keySeparator || ".";
4026
+ let resultKey;
4027
+ if (o.keyPrefix && Array.isArray(key)) {
4028
+ resultKey = key.map((k) => {
4029
+ if (typeof k === "function")
4030
+ k = keysFromSelector(k, selectorOpts);
4031
+ return `${o.keyPrefix}${keySeparator}${k}`;
4032
+ });
4033
+ } else {
4034
+ if (typeof key === "function")
4035
+ key = keysFromSelector(key, selectorOpts);
4036
+ resultKey = o.keyPrefix ? `${o.keyPrefix}${keySeparator}${key}` : key;
4037
+ }
4038
+ return this.t(resultKey, o);
4039
+ };
4040
+ if (isString(lng)) {
4041
+ fixedT.lng = lng;
4042
+ } else {
4043
+ fixedT.lngs = lng;
4044
+ }
4045
+ fixedT.ns = ns;
4046
+ fixedT.keyPrefix = keyPrefix;
4047
+ return fixedT;
4048
+ }
4049
+ t(...args) {
4050
+ return this.translator?.translate(...args);
4051
+ }
4052
+ exists(...args) {
4053
+ return this.translator?.exists(...args);
4054
+ }
4055
+ setDefaultNamespace(ns) {
4056
+ this.options.defaultNS = ns;
4057
+ }
4058
+ hasLoadedNamespace(ns, options = {}) {
4059
+ if (!this.isInitialized) {
4060
+ this.logger.warn("hasLoadedNamespace: i18next was not initialized", this.languages);
4061
+ return false;
4062
+ }
4063
+ if (!this.languages || !this.languages.length) {
4064
+ this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty", this.languages);
4065
+ return false;
4066
+ }
4067
+ const lng = options.lng || this.resolvedLanguage || this.languages[0];
4068
+ const fallbackLng = this.options ? this.options.fallbackLng : false;
4069
+ const lastLng = this.languages[this.languages.length - 1];
4070
+ if (lng.toLowerCase() === "cimode")
4071
+ return true;
4072
+ const loadNotPending = (l, n) => {
4073
+ const loadState = this.services.backendConnector.state[`${l}|${n}`];
4074
+ return loadState === -1 || loadState === 0 || loadState === 2;
4075
+ };
4076
+ if (options.precheck) {
4077
+ const preResult = options.precheck(this, loadNotPending);
4078
+ if (preResult !== undefined)
4079
+ return preResult;
4080
+ }
4081
+ if (this.hasResourceBundle(lng, ns))
4082
+ return true;
4083
+ if (!this.services.backendConnector.backend || this.options.resources && !this.options.partialBundledLanguages)
4084
+ return true;
4085
+ if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns)))
4086
+ return true;
4087
+ return false;
4088
+ }
4089
+ loadNamespaces(ns, callback) {
4090
+ const deferred = defer();
4091
+ if (!this.options.ns) {
4092
+ if (callback)
4093
+ callback();
4094
+ return Promise.resolve();
4095
+ }
4096
+ if (isString(ns))
4097
+ ns = [ns];
4098
+ ns.forEach((n) => {
4099
+ if (!this.options.ns.includes(n))
4100
+ this.options.ns.push(n);
4101
+ });
4102
+ this.loadResources((err) => {
4103
+ deferred.resolve();
4104
+ if (callback)
4105
+ callback(err);
4106
+ });
4107
+ return deferred;
4108
+ }
4109
+ loadLanguages(lngs, callback) {
4110
+ const deferred = defer();
4111
+ if (isString(lngs))
4112
+ lngs = [lngs];
4113
+ const preloaded = this.options.preload || [];
4114
+ const newLngs = lngs.filter((lng) => !preloaded.includes(lng) && this.services.languageUtils.isSupportedCode(lng));
4115
+ if (!newLngs.length) {
4116
+ if (callback)
4117
+ callback();
4118
+ return Promise.resolve();
4119
+ }
4120
+ this.options.preload = preloaded.concat(newLngs);
4121
+ this.loadResources((err) => {
4122
+ deferred.resolve();
4123
+ if (callback)
4124
+ callback(err);
4125
+ });
4126
+ return deferred;
4127
+ }
4128
+ dir(lng) {
4129
+ if (!lng)
4130
+ lng = this.resolvedLanguage || (this.languages?.length > 0 ? this.languages[0] : this.language);
4131
+ if (!lng)
4132
+ return "rtl";
4133
+ try {
4134
+ const l = new Intl.Locale(lng);
4135
+ if (l && l.getTextInfo) {
4136
+ const ti = l.getTextInfo();
4137
+ if (ti && ti.direction)
4138
+ return ti.direction;
4139
+ }
4140
+ } catch (e) {}
4141
+ const rtlLngs = ["ar", "shu", "sqr", "ssh", "xaa", "yhd", "yud", "aao", "abh", "abv", "acm", "acq", "acw", "acx", "acy", "adf", "ads", "aeb", "aec", "afb", "ajp", "apc", "apd", "arb", "arq", "ars", "ary", "arz", "auz", "avl", "ayh", "ayl", "ayn", "ayp", "bbz", "pga", "he", "iw", "ps", "pbt", "pbu", "pst", "prp", "prd", "ug", "ur", "ydd", "yds", "yih", "ji", "yi", "hbo", "men", "xmn", "fa", "jpr", "peo", "pes", "prs", "dv", "sam", "ckb"];
4142
+ const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
4143
+ if (lng.toLowerCase().indexOf("-latn") > 1)
4144
+ return "ltr";
4145
+ return rtlLngs.includes(languageUtils.getLanguagePartFromCode(lng)) || lng.toLowerCase().indexOf("-arab") > 1 ? "rtl" : "ltr";
4146
+ }
4147
+ static createInstance(options = {}, callback) {
4148
+ const instance = new I18n(options, callback);
4149
+ instance.createInstance = I18n.createInstance;
4150
+ return instance;
4151
+ }
4152
+ cloneInstance(options = {}, callback = noop) {
4153
+ const forkResourceStore = options.forkResourceStore;
4154
+ if (forkResourceStore)
4155
+ delete options.forkResourceStore;
4156
+ const mergedOptions = {
4157
+ ...this.options,
4158
+ ...options,
4159
+ ...{
4160
+ isClone: true
4161
+ }
4162
+ };
4163
+ const clone = new I18n(mergedOptions);
4164
+ if (options.debug !== undefined || options.prefix !== undefined) {
4165
+ clone.logger = clone.logger.clone(options);
4166
+ }
4167
+ const membersToCopy = ["store", "services", "language"];
4168
+ membersToCopy.forEach((m) => {
4169
+ clone[m] = this[m];
4170
+ });
4171
+ clone.services = {
4172
+ ...this.services
4173
+ };
4174
+ clone.services.utils = {
4175
+ hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
4176
+ };
4177
+ if (forkResourceStore) {
4178
+ const clonedData = Object.keys(this.store.data).reduce((prev, l) => {
4179
+ prev[l] = {
4180
+ ...this.store.data[l]
4181
+ };
4182
+ prev[l] = Object.keys(prev[l]).reduce((acc, n) => {
4183
+ acc[n] = {
4184
+ ...prev[l][n]
4185
+ };
4186
+ return acc;
4187
+ }, prev[l]);
4188
+ return prev;
4189
+ }, {});
4190
+ clone.store = new ResourceStore(clonedData, mergedOptions);
4191
+ clone.services.resourceStore = clone.store;
4192
+ }
4193
+ if (options.interpolation) {
4194
+ const defOpts = get();
4195
+ const mergedInterpolation = {
4196
+ ...defOpts.interpolation,
4197
+ ...this.options.interpolation,
4198
+ ...options.interpolation
4199
+ };
4200
+ const mergedForInterpolator = {
4201
+ ...mergedOptions,
4202
+ interpolation: mergedInterpolation
4203
+ };
4204
+ clone.services.interpolator = new Interpolator(mergedForInterpolator);
4205
+ }
4206
+ clone.translator = new Translator(clone.services, mergedOptions);
4207
+ clone.translator.on("*", (event, ...args) => {
4208
+ clone.emit(event, ...args);
4209
+ });
4210
+ clone.init(mergedOptions, callback);
4211
+ clone.translator.options = mergedOptions;
4212
+ clone.translator.backendConnector.services.utils = {
4213
+ hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
4214
+ };
4215
+ return clone;
4216
+ }
4217
+ toJSON() {
4218
+ return {
4219
+ options: this.options,
4220
+ store: this.store,
4221
+ language: this.language,
4222
+ languages: this.languages,
4223
+ resolvedLanguage: this.resolvedLanguage
4224
+ };
4225
+ }
4226
+ }
4227
+ var instance = I18n.createInstance();
4228
+ var createInstance = instance.createInstance;
4229
+ var dir = instance.dir;
4230
+ var init = instance.init;
4231
+ var loadResources = instance.loadResources;
4232
+ var reloadResources = instance.reloadResources;
4233
+ var use = instance.use;
4234
+ var changeLanguage = instance.changeLanguage;
4235
+ var getFixedT = instance.getFixedT;
4236
+ var t = instance.t;
4237
+ var exists = instance.exists;
4238
+ var setDefaultNamespace = instance.setDefaultNamespace;
4239
+ var hasLoadedNamespace = instance.hasLoadedNamespace;
4240
+ var loadNamespaces = instance.loadNamespaces;
4241
+ var loadLanguages = instance.loadLanguages;
4242
+ // src/i18n/types.ts
4243
+ var DEFAULT_LANGUAGE2 = "en";
4244
+ // src/i18n/index.ts
4245
+ var i18n = {
4246
+ t(key, options) {
4247
+ return instance.t(key, options);
4248
+ },
4249
+ async changeLanguage(language) {
4250
+ await instance.changeLanguage(language);
4251
+ },
4252
+ get language() {
4253
+ return instance.language || DEFAULT_LANGUAGE2;
4254
+ }
4255
+ };
4256
+
1762
4257
  // src/core/updater.ts
1763
4258
  init_fs();
1764
4259
 
@@ -2083,6 +4578,16 @@ function compareSemver(a, b) {
2083
4578
  }
2084
4579
  return 0;
2085
4580
  }
4581
+ function checkAndInstallRtkAfterUpdate() {
4582
+ if (!isRtkInstalled()) {
4583
+ warn("update.rtk_missing");
4584
+ console.log(i18n.t("cli.update.rtkMissing"));
4585
+ const rtkInstalled = installRtk();
4586
+ if (rtkInstalled) {
4587
+ console.log(i18n.t("cli.update.rtkInstalled"));
4588
+ }
4589
+ }
4590
+ }
2086
4591
  async function update(options) {
2087
4592
  const result = createUpdateResult();
2088
4593
  try {
@@ -2130,6 +4635,7 @@ async function update(options) {
2130
4635
  files: String(lockfileResult.fileCount)
2131
4636
  });
2132
4637
  }
4638
+ checkAndInstallRtkAfterUpdate();
2133
4639
  } catch (err) {
2134
4640
  const message = err instanceof Error ? err.message : String(err);
2135
4641
  result.error = message;
@@ -2249,9 +4755,9 @@ function isEntryProtected(relPath, componentRelativePrefix) {
2249
4755
  const componentPrefixed = componentRelativePrefix ? `${componentRelativePrefix}/${relPath}` : relPath;
2250
4756
  return isProtectedFile(componentPrefixed);
2251
4757
  }
2252
- async function safeReaddir(dir, fs) {
4758
+ async function safeReaddir(dir2, fs) {
2253
4759
  try {
2254
- return await fs.readdir(dir, { withFileTypes: true });
4760
+ return await fs.readdir(dir2, { withFileTypes: true });
2255
4761
  } catch {
2256
4762
  return [];
2257
4763
  }
@@ -2262,11 +4768,11 @@ async function findProtectedFilesInDir(dirPath, componentRelativePrefix) {
2262
4768
  const protected_ = [];
2263
4769
  const queue = [{ dir: dirPath, relDir: "" }];
2264
4770
  while (queue.length > 0) {
2265
- const { dir, relDir } = queue.shift();
2266
- const entries = await safeReaddir(dir, fs);
4771
+ const { dir: dir2, relDir } = queue.shift();
4772
+ const entries = await safeReaddir(dir2, fs);
2267
4773
  for (const entry of entries) {
2268
4774
  const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
2269
- const fullPath = path.join(dir, entry.name);
4775
+ const fullPath = path.join(dir2, entry.name);
2270
4776
  if (entry.isDirectory()) {
2271
4777
  queue.push({ dir: fullPath, relDir: relPath });
2272
4778
  } else if (entry.isFile() && isEntryProtected(relPath, componentRelativePrefix)) {
@@ -2445,16 +4951,16 @@ async function applyNamespaceSync(targetDir, component, lockfile) {
2445
4951
  const synced = [];
2446
4952
  const queue = [{ dir: srcPath, relDir: "" }];
2447
4953
  while (queue.length > 0) {
2448
- const { dir, relDir } = queue.shift();
4954
+ const { dir: dir2, relDir } = queue.shift();
2449
4955
  let entries;
2450
4956
  try {
2451
- entries = await fs.readdir(dir, { withFileTypes: true });
4957
+ entries = await fs.readdir(dir2, { withFileTypes: true });
2452
4958
  } catch {
2453
4959
  continue;
2454
4960
  }
2455
4961
  for (const entry of entries) {
2456
4962
  const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
2457
- const fullSrcPath = join6(dir, entry.name);
4963
+ const fullSrcPath = join6(dir2, entry.name);
2458
4964
  if (entry.isDirectory()) {
2459
4965
  queue.push({ dir: fullSrcPath, relDir: relPath });
2460
4966
  continue;
@@ -2482,10 +4988,10 @@ async function backupInstallation(targetDir) {
2482
4988
  await ensureDirectory(backupDir);
2483
4989
  const layout = getProviderLayout();
2484
4990
  const dirsToBackup = [layout.rootDir, "guides"];
2485
- for (const dir of dirsToBackup) {
2486
- const srcPath = join6(targetDir, dir);
4991
+ for (const dir2 of dirsToBackup) {
4992
+ const srcPath = join6(targetDir, dir2);
2487
4993
  if (await fileExists(srcPath)) {
2488
- const destPath = join6(backupDir, dir);
4994
+ const destPath = join6(backupDir, dir2);
2489
4995
  await copyDirectory(srcPath, destPath, { overwrite: true });
2490
4996
  }
2491
4997
  }