PageSourceSearch

https://www.bullfighter.se/node_modules/i18next/dist/esm/i18next.js

js bullfighter.se collected 2026-10-07 09:36:53 UTC 89,491 bytes, 2,382 lines download raw bytes

vendor: 88,712 bytes, lines 1-2366
1const isString = obj => typeof obj === 'string';
2const defer = () => {
3  let res;
4  let rej;
5  const promise = new Promise((resolve, reject) => {
6    res = resolve;
7    rej = reject;
8  });
9  promise.resolve = res;
10  promise.reject = rej;
11  return promise;
12};
13const makeString = object => {
14  if (object == null) return '';
15  return '' + object;
16};
17const copy = (a, s, t) => {
18  a.forEach(m => {
19    if (s[m]) t[m] = s[m];
20  });
21};
22const lastOfPathSeparatorRegExp = /###/g;
23const cleanKey = key => key && key.indexOf('###') > -1 ? key.replace(lastOfPathSeparatorRegExp, '.') : key;
24const canNotTraverseDeeper = object => !object || isString(object);
25const getLastOfPath = (object, path, Empty) => {
26  const stack = !isString(path) ? path : path.split('.');
27  let stackIndex = 0;
28  while (stackIndex < stack.length - 1) {
29    if (canNotTraverseDeeper(object)) return {};
30    const key = cleanKey(stack[stackIndex]);
31    if (!object[key] && Empty) object[key] = new Empty();
32    if (Object.prototype.hasOwnProperty.call(object, key)) {
33      object = object[key];
34    } else {
35      object = {};
36    }
37    ++stackIndex;
38  }
39  if (canNotTraverseDeeper(object)) return {};
40  return {
41    obj: object,
42    k: cleanKey(stack[stackIndex])
43  };
44};
45const setPath = (object, path, newValue) => {
46  const {
47    obj,
48    k
49  } = getLastOfPath(object, path, Object);
50  if (obj !== undefined || path.length === 1) {
51    obj[k] = newValue;
52    return;
53  }
54  let e = path[path.length - 1];
55  let p = path.slice(0, path.length - 1);
56  let last = getLastOfPath(object, p, Object);
57  while (last.obj === undefined && p.length) {
58    e = `${p[p.length - 1]}.${e}`;
59    p = p.slice(0, p.length - 1);
60    last = getLastOfPath(object, p, Object);
61    if (last && last.obj && typeof last.obj[`${last.k}.${e}`] !== 'undefined') {
62      last.obj = undefined;
63    }
64  }
65  last.obj[`${last.k}.${e}`] = newValue;
66};
67const pushPath = (object, path, newValue, concat) => {
68  const {
69    obj,
70    k
71  } = getLastOfPath(object, path, Object);
72  obj[k] = obj[k] || [];
73  obj[k].push(newValue);
74};
75const getPath = (object, path) => {
76  const {
77    obj,
78    k
79  } = getLastOfPath(object, path);
80  if (!obj) return undefined;
81  return obj[k];
82};
83const getPathWithDefaults = (data, defaultData, key) => {
84  const value = getPath(data, key);
85  if (value !== undefined) {
86    return value;
87  }
88  return getPath(defaultData, key);
89};
90const deepExtend = (target, source, overwrite) => {
91  for (const prop in source) {
92    if (prop !== '__proto__' && prop !== 'constructor') {
93      if (prop in target) {
94        if (isString(target[prop]) || target[prop] instanceof String || isString(source[prop]) || source[prop] instanceof String) {
95          if (overwrite) target[prop] = source[prop];
96        } else {
97          deepExtend(target[prop], source[prop], overwrite);
98        }
99      } else {
100        target[prop] = source[prop];
101      }
102    }
103  }
104  return target;
105};
106const regexEscape = str => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
107var _entityMap = {
108  '&': '&amp;',
109  '<': '&lt;',
110  '>': '&gt;',
111  '"': '&quot;',
112  "'": '&#39;',
113  '/': '&#x2F;'
114};
115const escape = data => {
116  if (isString(data)) {
117    return data.replace(/[&<>"'\/]/g, s => _entityMap[s]);
118  }
119  return data;
120};
121class RegExpCache {
122  constructor(capacity) {
123    this.capacity = capacity;
124    this.regExpMap = new Map();
125    this.regExpQueue = [];
126  }
127  getRegExp(pattern) {
128    const regExpFromCache = this.regExpMap.get(pattern);
129    if (regExpFromCache !== undefined) {
130      return regExpFromCache;
131    }
132    const regExpNew = new RegExp(pattern);
133    if (this.regExpQueue.length === this.capacity) {
134      this.regExpMap.delete(this.regExpQueue.shift());
135    }
136    this.regExpMap.set(pattern, regExpNew);
137    this.regExpQueue.push(pattern);
138    return regExpNew;
139  }
140}
141const chars = [' ', ',', '?', '!', ';'];
142const looksLikeObjectPathRegExpCache = new RegExpCache(20);
143const looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
144  nsSeparator = nsSeparator || '';
145  keySeparator = keySeparator || '';
146  const possibleChars = chars.filter(c => nsSeparator.indexOf(c) < 0 && keySeparator.indexOf(c) < 0);
147  if (possibleChars.length === 0) return true;
148  const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map(c => c === '?' ? '\\?' : c).join('|')})`);
149  let matched = !r.test(key);
150  if (!matched) {
151    const ki = key.indexOf(keySeparator);
152    if (ki > 0 && !r.test(key.substring(0, ki))) {
153      matched = true;
154    }
155  }
156  return matched;
157};
158const deepFind = function (obj, path) {
159  let keySeparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '.';
160  if (!obj) return undefined;
161  if (obj[path]) return obj[path];
162  const tokens = path.split(keySeparator);
163  let current = obj;
164  for (let i = 0; i < tokens.length;) {
165    if (!current || typeof current !== 'object') {
166      return undefined;
167    }
168    let next;
169    let nextPath = '';
170    for (let j = i; j < tokens.length; ++j) {
171      if (j !== i) {
172        nextPath += keySeparator;
173      }
174      nextPath += tokens[j];
175      next = current[nextPath];
176      if (next !== undefined) {
177        if (['string', 'number', 'boolean'].indexOf(typeof next) > -1 && j < tokens.length - 1) {
178          continue;
179        }
180        i += j - i + 1;
181        break;
182      }
183    }
184    current = next;
185  }
186  return current;
187};
188const getCleanedCode = code => code && code.replace('_', '-');
189
190const consoleLogger = {
191  type: 'logger',
192  log(args) {
193    this.output('log', args);
194  },
195  warn(args) {
196    this.output('warn', args);
197  },
198  error(args) {
199    this.output('error', args);
200  },
201  output(type, args) {
202    if (console && console[type]) console[type].apply(console, args);
203  }
204};
205class Logger {
206  constructor(concreteLogger) {
207    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
208    this.init(concreteLogger, options);
209  }
210  init(concreteLogger) {
211    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
212    this.prefix = options.prefix || 'i18next:';
213    this.logger = concreteLogger || consoleLogger;
214    this.options = options;
215    this.debug = options.debug;
216  }
217  log() {
218    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
219      args[_key] = arguments[_key];
220    }
221    return this.forward(args, 'log', '', true);
222  }
223  warn() {
224    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
225      args[_key2] = arguments[_key2];
226    }
227    return this.forward(args, 'warn', '', true);
228  }
229  error() {
230    for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
231      args[_key3] = arguments[_key3];
232    }
233    return this.forward(args, 'error', '');
234  }
235  deprecate() {
236    for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
237      args[_key4] = arguments[_key4];
238    }
239    return this.forward(args, 'warn', 'WARNING DEPRECATED: ', true);
240  }
241  forward(args, lvl, prefix, debugOnly) {
242    if (debugOnly && !this.debug) return null;
243    if (isString(args[0])) args[0] = `${prefix}${this.prefix} ${args[0]}`;
244    return this.logger[lvl](args);
245  }
246  create(moduleName) {
247    return new Logger(this.logger, {
248      ...{
249        prefix: `${this.prefix}:${moduleName}:`
250      },
251      ...this.options
252    });
253  }
254  clone(options) {
255    options = options || this.options;
256    options.prefix = options.prefix || this.prefix;
257    return new Logger(this.logger, options);
258  }
259}
260var baseLogger = new Logger();
261
262class EventEmitter {
263  constructor() {
264    this.observers = {};
265  }
266  on(events, listener) {
267    events.split(' ').forEach(event => {
268      if (!this.observers[event]) this.observers[event] = new Map();
269      const numListeners = this.observers[event].get(listener) || 0;
270      this.observers[event].set(listener, numListeners + 1);
271    });
272    return this;
273  }
274  off(event, listener) {
275    if (!this.observers[event]) return;
276    if (!listener) {
277      delete this.observers[event];
278      return;
279    }
280    this.observers[event].delete(listener);
281  }
282  emit(event) {
283    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
284      args[_key - 1] = arguments[_key];
285    }
286    if (this.observers[event]) {
287      const cloned = Array.from(this.observers[event].entries());
288      cloned.forEach(_ref => {
289        let [observer, numTimesAdded] = _ref;
290        for (let i = 0; i < numTimesAdded; i++) {
291          observer(...args);
292        }
293      });
294    }
295    if (this.observers['*']) {
296      const cloned = Array.from(this.observers['*'].entries());
297      cloned.forEach(_ref2 => {
298        let [observer, numTimesAdded] = _ref2;
299        for (let i = 0; i < numTimesAdded; i++) {
300          observer.apply(observer, [event, ...args]);
301        }
302      });
303    }
304  }
305}
306
307class ResourceStore extends EventEmitter {
308  constructor(data) {
309    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
310      ns: ['translation'],
311      defaultNS: 'translation'
312    };
313    super();
314    this.data = data || {};
315    this.options = options;
316    if (this.options.keySeparator === undefined) {
317      this.options.keySeparator = '.';
318    }
319    if (this.options.ignoreJSONStructure === undefined) {
320      this.options.ignoreJSONStructure = true;
321    }
322  }
323  addNamespaces(ns) {
324    if (this.options.ns.indexOf(ns) < 0) {
325      this.options.ns.push(ns);
326    }
327  }
328  removeNamespaces(ns) {
329    const index = this.options.ns.indexOf(ns);
330    if (index > -1) {
331      this.options.ns.splice(index, 1);
332    }
333  }
334  getResource(lng, ns, key) {
335    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
336    const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
337    const ignoreJSONStructure = options.ignoreJSONStructure !== undefined ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
338    let path;
339    if (lng.indexOf('.') > -1) {
340      path = lng.split('.');
341    } else {
342      path = [lng, ns];
343      if (key) {
344        if (Array.isArray(key)) {
345          path.push(...key);
346        } else if (isString(key) && keySeparator) {
347          path.push(...key.split(keySeparator));
348        } else {
349          path.push(key);
350        }
351      }
352    }
353    const result = getPath(this.data, path);
354    if (!result && !ns && !key && lng.indexOf('.') > -1) {
355      lng = path[0];
356      ns = path[1];
357      key = path.slice(2).join('.');
358    }
359    if (result || !ignoreJSONStructure || !isString(key)) return result;
360    return deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator);
361  }
362  addResource(lng, ns, key, value) {
363    let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
364      silent: false
365    };
366    const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
367    let path = [lng, ns];
368    if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
369    if (lng.indexOf('.') > -1) {
370      path = lng.split('.');
371      value = ns;
372      ns = path[1];
373    }
374    this.addNamespaces(ns);
375    setPath(this.data, path, value);
376    if (!options.silent) this.emit('added', lng, ns, key, value);
377  }
378  addResources(lng, ns, resources) {
379    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
380      silent: false
381    };
382    for (const m in resources) {
383      if (isString(resources[m]) || Array.isArray(resources[m])) this.addResource(lng, ns, m, resources[m], {
384        silent: true
385      });
386    }
387    if (!options.silent) this.emit('added', lng, ns, resources);
388  }
389  addResourceBundle(lng, ns, resources, deep, overwrite) {
390    let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
391      silent: false,
392      skipCopy: false
393    };
394    let path = [lng, ns];
395    if (lng.indexOf('.') > -1) {
396      path = lng.split('.');
397      deep = resources;
398      resources = ns;
399      ns = path[1];
400    }
401    this.addNamespaces(ns);
402    let pack = getPath(this.data, path) || {};
403    if (!options.skipCopy) resources = JSON.parse(JSON.stringify(resources));
404    if (deep) {
405      deepExtend(pack, resources, overwrite);
406    } else {
407      pack = {
408        ...pack,
409        ...resources
410      };
411    }
412    setPath(this.data, path, pack);
413    if (!options.silent) this.emit('added', lng, ns, resources);
414  }
415  removeResourceBundle(lng, ns) {
416    if (this.hasResourceBundle(lng, ns)) {
417      delete this.data[lng][ns];
418    }
419    this.removeNamespaces(ns);
420    this.emit('removed', lng, ns);
421  }
422  hasResourceBundle(lng, ns) {
423    return this.getResource(lng, ns) !== undefined;
424  }
425  getResourceBundle(lng, ns) {
426    if (!ns) ns = this.options.defaultNS;
427    if (this.options.compatibilityAPI === 'v1') return {
428      ...{},
429      ...this.getResource(lng, ns)
430    };
431    return this.getResource(lng, ns);
432  }
433  getDataByLanguage(lng) {
434    return this.data[lng];
435  }
436  hasLanguageSomeTranslations(lng) {
437    const data = this.getDataByLanguage(lng);
438    const n = data && Object.keys(data) || [];
439    return !!n.find(v => data[v] && Object.keys(data[v]).length > 0);
440  }
441  toJSON() {
442    return this.data;
443  }
444}
445
446var postProcessor = {
447  processors: {},
448  addPostProcessor(module) {
449    this.processors[module.name] = module;
450  },
451  handle(processors, value, key, options, translator) {
452    processors.forEach(processor => {
453      if (this.processors[processor]) value = this.processors[processor].process(value, key, options, translator);
454    });
455    return value;
456  }
457};
458
459const checkedLoadedFor = {};
460class Translator extends EventEmitter {
461  constructor(services) {
462    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
463    super();
464    copy(['resourceStore', 'languageUtils', 'pluralResolver', 'interpolator', 'backendConnector', 'i18nFormat', 'utils'], services, this);
465    this.options = options;
466    if (this.options.keySeparator === undefined) {
467      this.options.keySeparator = '.';
468    }
469    this.logger = baseLogger.create('translator');
470  }
471  changeLanguage(lng) {
472    if (lng) this.language = lng;
473  }
474  exists(key) {
475    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
476      interpolation: {}
477    };
478    if (key === undefined || key === null) {
479      return false;
480    }
481    const resolved = this.resolve(key, options);
482    return resolved && resolved.res !== undefined;
483  }
484  extractFromKey(key, options) {
485    let nsSeparator = options.nsSeparator !== undefined ? options.nsSeparator : this.options.nsSeparator;
486    if (nsSeparator === undefined) nsSeparator = ':';
487    const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
488    let namespaces = options.ns || this.options.defaultNS || [];
489    const wouldCheckForNsInKey = nsSeparator && key.indexOf(nsSeparator) > -1;
490    const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !options.keySeparator && !this.options.userDefinedNsSeparator && !options.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
491    if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
492      const m = key.match(this.interpolator.nestingRegexp);
493      if (m && m.length > 0) {
494        return {
495          key,
496          namespaces: isString(namespaces) ? [namespaces] : namespaces
497        };
498      }
499      const parts = key.split(nsSeparator);
500      if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
501      key = parts.join(keySeparator);
502    }
503    return {
504      key,
505      namespaces: isString(namespaces) ? [namespaces] : namespaces
506    };
507  }
508  translate(keys, options, lastKey) {
509    if (typeof options !== 'object' && this.options.overloadTranslationOptionHandler) {
510      options = this.options.overloadTranslationOptionHandler(arguments);
511    }
512    if (typeof options === 'object') options = {
513      ...options
514    };
515    if (!options) options = {};
516    if (keys === undefined || keys === null) return '';
517    if (!Array.isArray(keys)) keys = [String(keys)];
518    const returnDetails = options.returnDetails !== undefined ? options.returnDetails : this.options.returnDetails;
519    const keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator;
520    const {
521      key,
522      namespaces
523    } = this.extractFromKey(keys[keys.length - 1], options);
524    const namespace = namespaces[namespaces.length - 1];
525    const lng = options.lng || this.language;
526    const appendNamespaceToCIMode = options.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
527    if (lng && lng.toLowerCase() === 'cimode') {
528      if (appendNamespaceToCIMode) {
529        const nsSeparator = options.nsSeparator || this.options.nsSeparator;
530        if (returnDetails) {
531          return {
532            res: `${namespace}${nsSeparator}${key}`,
533            usedKey: key,
534            exactUsedKey: key,
535            usedLng: lng,
536            usedNS: namespace,
537            usedParams: this.getUsedParamsDetails(options)
538          };
539        }
540        return `${namespace}${nsSeparator}${key}`;
541      }
542      if (returnDetails) {
543        return {
544          res: key,
545          usedKey: key,
546          exactUsedKey: key,
547          usedLng: lng,
548          usedNS: namespace,
549          usedParams: this.getUsedParamsDetails(options)
550        };
551      }
552      return key;
553    }
554    const resolved = this.resolve(keys, options);
555    let res = resolved && resolved.res;
556    const resUsedKey = resolved && resolved.usedKey || key;
557    const resExactUsedKey = resolved && resolved.exactUsedKey || key;
558    const resType = Object.prototype.toString.apply(res);
559    const noObject = ['[object Number]', '[object Function]', '[object RegExp]'];
560    const joinArrays = options.joinArrays !== undefined ? options.joinArrays : this.options.joinArrays;
561    const handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject;
562    const handleAsObject = !isString(res) && typeof res !== 'boolean' && typeof res !== 'number';
563    if (handleAsObjectInI18nFormat && res && handleAsObject && noObject.indexOf(resType) < 0 && !(isString(joinArrays) && Array.isArray(res))) {
564      if (!options.returnObjects && !this.options.returnObjects) {
565        if (!this.options.returnedObjectHandler) {
566          this.logger.warn('accessing an object - but returnObjects options is not enabled!');
567        }
568        const r = this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, res, {
569          ...options,
570          ns: namespaces
571        }) : `key '${key} (${this.language})' returned an object instead of string.`;
572        if (returnDetails) {
573          resolved.res = r;
574          resolved.usedParams = this.getUsedParamsDetails(options);
575          return resolved;
576        }
577        return r;
578      }
579      if (keySeparator) {
580        const resTypeIsArray = Array.isArray(res);
581        const copy = resTypeIsArray ? [] : {};
582        const newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey;
583        for (const m in res) {
584          if (Object.prototype.hasOwnProperty.call(res, m)) {
585            const deepKey = `${newKeyToUse}${keySeparator}${m}`;
586            copy[m] = this.translate(deepKey, {
587              ...options,
588              ...{
589                joinArrays: false,
590                ns: namespaces
591              }
592            });
593            if (copy[m] === deepKey) copy[m] = res[m];
594          }
595        }
596        res = copy;
597      }
598    } else if (handleAsObjectInI18nFormat && isString(joinArrays) && Array.isArray(res)) {
599      res = res.join(joinArrays);
600      if (res) res = this.extendTranslation(res, keys, options, lastKey);
601    } else {
602      let usedDefault = false;
603      let usedKey = false;
604      const needsPluralHandling = options.count !== undefined && !isString(options.count);
605      const hasDefaultValue = Translator.hasDefaultValue(options);
606      const defaultValueSuffix = needsPluralHandling ? this.pluralResolver.getSuffix(lng, options.count, options) : '';
607      const defaultValueSuffixOrdinalFallback = options.ordinal && needsPluralHandling ? this.pluralResolver.getSuffix(lng, options.count, {
608        ordinal: false
609      }) : '';
610      const needsZeroSuffixLookup = needsPluralHandling && !options.ordinal && options.count === 0 && this.pluralResolver.shouldUseIntlApi();
611      const defaultValue = needsZeroSuffixLookup && options[`defaultValue${this.options.pluralSeparator}zero`] || options[`defaultValue${defaultValueSuffix}`] || options[`defaultValue${defaultValueSuffixOrdinalFallback}`] || options.defaultValue;
612      if (!this.isValidLookup(res) && hasDefaultValue) {
613        usedDefault = true;
614        res = defaultValue;
615      }
616      if (!this.isValidLookup(res)) {
617        usedKey = true;
618        res = key;
619      }
620      const missingKeyNoValueFallbackToKey = options.missingKeyNoValueFallbackToKey || this.options.missingKeyNoValueFallbackToKey;
621      const resForMissing = missingKeyNoValueFallbackToKey && usedKey ? undefined : res;
622      const updateMissing = hasDefaultValue && defaultValue !== res && this.options.updateMissing;
623      if (usedKey || usedDefault || updateMissing) {
624        this.logger.log(updateMissing ? 'updateKey' : 'missingKey', lng, namespace, key, updateMissing ? defaultValue : res);
625        if (keySeparator) {
626          const fk = this.resolve(key, {
627            ...options,
628            keySeparator: false
629          });
630          if (fk && fk.res) 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.');
631        }
632        let lngs = [];
633        const fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, options.lng || this.language);
634        if (this.options.saveMissingTo === 'fallback' && fallbackLngs && fallbackLngs[0]) {
635          for (let i = 0; i < fallbackLngs.length; i++) {
636            lngs.push(fallbackLngs[i]);
637          }
638        } else if (this.options.saveMissingTo === 'all') {
639          lngs = this.languageUtils.toResolveHierarchy(options.lng || this.language);
640        } else {
641          lngs.push(options.lng || this.language);
642        }
643        const send = (l, k, specificDefaultValue) => {
644          const defaultForMissing = hasDefaultValue && specificDefaultValue !== res ? specificDefaultValue : resForMissing;
645          if (this.options.missingKeyHandler) {
646            this.options.missingKeyHandler(l, namespace, k, defaultForMissing, updateMissing, options);
647          } else if (this.backendConnector && this.backendConnector.saveMissing) {
648            this.backendConnector.saveMissing(l, namespace, k, defaultForMissing, updateMissing, options);
649          }
650          this.emit('missingKey', l, namespace, k, res);
651        };
652        if (this.options.saveMissing) {
653          if (this.options.saveMissingPlurals && needsPluralHandling) {
654            lngs.forEach(language => {
655              const suffixes = this.pluralResolver.getSuffixes(language, options);
656              if (needsZeroSuffixLookup && options[`defaultValue${this.options.pluralSeparator}zero`] && suffixes.indexOf(`${this.options.pluralSeparator}zero`) < 0) {
657                suffixes.push(`${this.options.pluralSeparator}zero`);
658              }
659              suffixes.forEach(suffix => {
660                send([language], key + suffix, options[`defaultValue${suffix}`] || defaultValue);
661              });
662            });
663          } else {
664            send(lngs, key, defaultValue);
665          }
666        }
667      }
668      res = this.extendTranslation(res, keys, options, resolved, lastKey);
669      if (usedKey && res === key && this.options.appendNamespaceToMissingKey) res = `${namespace}:${key}`;
670      if ((usedKey || usedDefault) && this.options.parseMissingKeyHandler) {
671        if (this.options.compatibilityAPI !== 'v1') {
672          res = this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey ? `${namespace}:${key}` : key, usedDefault ? res : undefined);
673        } else {
674          res = this.options.parseMissingKeyHandler(res);
675        }
676      }
677    }
678    if (returnDetails) {
679      resolved.res = res;
680      resolved.usedParams = this.getUsedParamsDetails(options);
681      return resolved;
682    }
683    return res;
684  }
685  extendTranslation(res, key, options, resolved, lastKey) {
686    var _this = this;
687    if (this.i18nFormat && this.i18nFormat.parse) {
688      res = this.i18nFormat.parse(res, {
689        ...this.options.interpolation.defaultVariables,
690        ...options
691      }, options.lng || this.language || resolved.usedLng, resolved.usedNS, resolved.usedKey, {
692        resolved
693      });
694    } else if (!options.skipInterpolation) {
695      if (options.interpolation) this.interpolator.init({
696        ...options,
697        ...{
698          interpolation: {
699            ...this.options.interpolation,
700            ...options.interpolation
701          }
702        }
703      });
704      const skipOnVariables = isString(res) && (options && options.interpolation && options.interpolation.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables);
705      let nestBef;
706      if (skipOnVariables) {
707        const nb = res.match(this.interpolator.nestingRegexp);
708        nestBef = nb && nb.length;
709      }
710      let data = options.replace && !isString(options.replace) ? options.replace : options;
711      if (this.options.interpolation.defaultVariables) data = {
712        ...this.options.interpolation.defaultVariables,
713        ...data
714      };
715      res = this.interpolator.interpolate(res, data, options.lng || this.language || resolved.usedLng, options);
716      if (skipOnVariables) {
717        const na = res.match(this.interpolator.nestingRegexp);
718        const nestAft = na && na.length;
719        if (nestBef < nestAft) options.nest = false;
720      }
721      if (!options.lng && this.options.compatibilityAPI !== 'v1' && resolved && resolved.res) options.lng = this.language || resolved.usedLng;
722      if (options.nest !== false) res = this.interpolator.nest(res, function () {
723        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
724          args[_key] = arguments[_key];
725        }
726        if (lastKey && lastKey[0] === args[0] && !options.context) {
727          _this.logger.warn(`It seems you are nesting recursively key: ${args[0]} in key: ${key[0]}`);
728          return null;
729        }
730        return _this.translate(...args, key);
731      }, options);
732      if (options.interpolation) this.interpolator.reset();
733    }
734    const postProcess = options.postProcess || this.options.postProcess;
735    const postProcessorNames = isString(postProcess) ? [postProcess] : postProcess;
736    if (res !== undefined && res !== null && postProcessorNames && postProcessorNames.length && options.applyPostProcessor !== false) {
737      res = postProcessor.handle(postProcessorNames, res, key, this.options && this.options.postProcessPassResolved ? {
738        i18nResolved: {
739          ...resolved,
740          usedParams: this.getUsedParamsDetails(options)
741        },
742        ...options
743      } : options, this);
744    }
745    return res;
746  }
747  resolve(keys) {
748    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
749    let found;
750    let usedKey;
751    let exactUsedKey;
752    let usedLng;
753    let usedNS;
754    if (isString(keys)) keys = [keys];
755    keys.forEach(k => {
756      if (this.isValidLookup(found)) return;
757      const extracted = this.extractFromKey(k, options);
758      const key = extracted.key;
759      usedKey = key;
760      let namespaces = extracted.namespaces;
761      if (this.options.fallbackNS) namespaces = namespaces.concat(this.options.fallbackNS);
762      const needsPluralHandling = options.count !== undefined && !isString(options.count);
763      const needsZeroSuffixLookup = needsPluralHandling && !options.ordinal && options.count === 0 && this.pluralResolver.shouldUseIntlApi();
764      const needsContextHandling = options.context !== undefined && (isString(options.context) || typeof options.context === 'number') && options.context !== '';
765      const codes = options.lngs ? options.lngs : this.languageUtils.toResolveHierarchy(options.lng || this.language, options.fallbackLng);
766      namespaces.forEach(ns => {
767        if (this.isValidLookup(found)) return;
768        usedNS = ns;
769        if (!checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils && this.utils.hasLoadedNamespace && !this.utils.hasLoadedNamespace(usedNS)) {
770          checkedLoadedFor[`${codes[0]}-${ns}`] = true;
771          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!!!');
772        }
773        codes.forEach(code => {
774          if (this.isValidLookup(found)) return;
775          usedLng = code;
776          const finalKeys = [key];
777          if (this.i18nFormat && this.i18nFormat.addLookupKeys) {
778            this.i18nFormat.addLookupKeys(finalKeys, key, code, ns, options);
779          } else {
780            let pluralSuffix;
781            if (needsPluralHandling) pluralSuffix = this.pluralResolver.getSuffix(code, options.count, options);
782            const zeroSuffix = `${this.options.pluralSeparator}zero`;
783            const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
784            if (needsPluralHandling) {
785              finalKeys.push(key + pluralSuffix);
786              if (options.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
787                finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
788              }
789              if (needsZeroSuffixLookup) {
790                finalKeys.push(key + zeroSuffix);
791              }
792            }
793            if (needsContextHandling) {
794              const contextKey = `${key}${this.options.contextSeparator}${options.context}`;
795              finalKeys.push(contextKey);
796              if (needsPluralHandling) {
797                finalKeys.push(contextKey + pluralSuffix);
798                if (options.ordinal && pluralSuffix.indexOf(ordinalPrefix) === 0) {
799                  finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
800                }
801                if (needsZeroSuffixLookup) {
802                  finalKeys.push(contextKey + zeroSuffix);
803                }
804              }
805            }
806          }
807          let possibleKey;
808          while (possibleKey = finalKeys.pop()) {
809            if (!this.isValidLookup(found)) {
810              exactUsedKey = possibleKey;
811              found = this.getResource(code, ns, possibleKey, options);
812            }
813          }
814        });
815      });
816    });
817    return {
818      res: found,
819      usedKey,
820      exactUsedKey,
821      usedLng,
822      usedNS
823    };
824  }
825  isValidLookup(res) {
826    return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === '');
827  }
828  getResource(code, ns, key) {
829    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
830    if (this.i18nFormat && this.i18nFormat.getResource) return this.i18nFormat.getResource(code, ns, key, options);
831    return this.resourceStore.getResource(code, ns, key, options);
832  }
833  getUsedParamsDetails() {
834    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
835    const optionsKeys = ['defaultValue', 'ordinal', 'context', 'replace', 'lng', 'lngs', 'fallbackLng', 'ns', 'keySeparator', 'nsSeparator', 'returnObjects', 'returnDetails', 'joinArrays', 'postProcess', 'interpolation'];
836    const useOptionsReplaceForData = options.replace && !isString(options.replace);
837    let data = useOptionsReplaceForData ? options.replace : options;
838    if (useOptionsReplaceForData && typeof options.count !== 'undefined') {
839      data.count = options.count;
840    }
841    if (this.options.interpolation.defaultVariables) {
842      data = {
843        ...this.options.interpolation.defaultVariables,
844        ...data
845      };
846    }
847    if (!useOptionsReplaceForData) {
848      data = {
849        ...data
850      };
851      for (const key of optionsKeys) {
852        delete data[key];
853      }
854    }
855    return data;
856  }
857  static hasDefaultValue(options) {
858    const prefix = 'defaultValue';
859    for (const option in options) {
860      if (Object.prototype.hasOwnProperty.call(options, option) && prefix === option.substring(0, prefix.length) && undefined !== options[option]) {
861        return true;
862      }
863    }
864    return false;
865  }
866}
867
868const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1);
869class LanguageUtil {
870  constructor(options) {
871    this.options = options;
872    this.supportedLngs = this.options.supportedLngs || false;
873    this.logger = baseLogger.create('languageUtils');
874  }
875  getScriptPartFromCode(code) {
876    code = getCleanedCode(code);
877    if (!code || code.indexOf('-') < 0) return null;
878    const p = code.split('-');
879    if (p.length === 2) return null;
880    p.pop();
881    if (p[p.length - 1].toLowerCase() === 'x') return null;
882    return this.formatLanguageCode(p.join('-'));
883  }
884  getLanguagePartFromCode(code) {
885    code = getCleanedCode(code);
886    if (!code || code.indexOf('-') < 0) return code;
887    const p = code.split('-');
888    return this.formatLanguageCode(p[0]);
889  }
890  formatLanguageCode(code) {
891    if (isString(code) && code.indexOf('-') > -1) {
892      if (typeof Intl !== 'undefined' && typeof Intl.getCanonicalLocales !== 'undefined') {
893        try {
894          let formattedCode = Intl.getCanonicalLocales(code)[0];
895          if (formattedCode && this.options.lowerCaseLng) {
896            formattedCode = formattedCode.toLowerCase();
897          }
898          if (formattedCode) return formattedCode;
899        } catch (e) {}
900      }
901      const specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab'];
902      let p = code.split('-');
903      if (this.options.lowerCaseLng) {
904        p = p.map(part => part.toLowerCase());
905      } else if (p.length === 2) {
906        p[0] = p[0].toLowerCase();
907        p[1] = p[1].toUpperCase();
908        if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
909      } else if (p.length === 3) {
910        p[0] = p[0].toLowerCase();
911        if (p[1].length === 2) p[1] = p[1].toUpperCase();
912        if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase();
913        if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
914        if (specialCases.indexOf(p[2].toLowerCase()) > -1) p[2] = capitalize(p[2].toLowerCase());
915      }
916      return p.join('-');
917    }
918    return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code;
919  }
920  isSupportedCode(code) {
921    if (this.options.load === 'languageOnly' || this.options.nonExplicitSupportedLngs) {
922      code = this.getLanguagePartFromCode(code);
923    }
924    return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.indexOf(code) > -1;
925  }
926  getBestMatchFromCodes(codes) {
927    if (!codes) return null;
928    let found;
929    codes.forEach(code => {
930      if (found) return;
931      const cleanedLng = this.formatLanguageCode(code);
932      if (!this.options.supportedLngs || this.isSupportedCode(cleanedLng)) found = cleanedLng;
933    });
934    if (!found && this.options.supportedLngs) {
935      codes.forEach(code => {
936        if (found) return;
937        const lngOnly = this.getLanguagePartFromCode(code);
938        if (this.isSupportedCode(lngOnly)) return found = lngOnly;
939        found = this.options.supportedLngs.find(supportedLng => {
940          if (supportedLng === lngOnly) return supportedLng;
941          if (supportedLng.indexOf('-') < 0 && lngOnly.indexOf('-') < 0) return;
942          if (supportedLng.indexOf('-') > 0 && lngOnly.indexOf('-') < 0 && supportedLng.substring(0, supportedLng.indexOf('-')) === lngOnly) return supportedLng;
943          if (supportedLng.indexOf(lngOnly) === 0 && lngOnly.length > 1) return supportedLng;
944        });
945      });
946    }
947    if (!found) found = this.getFallbackCodes(this.options.fallbackLng)[0];
948    return found;
949  }
950  getFallbackCodes(fallbacks, code) {
951    if (!fallbacks) return [];
952    if (typeof fallbacks === 'function') fallbacks = fallbacks(code);
953    if (isString(fallbacks)) fallbacks = [fallbacks];
954    if (Array.isArray(fallbacks)) return fallbacks;
955    if (!code) return fallbacks.default || [];
956    let found = fallbacks[code];
957    if (!found) found = fallbacks[this.getScriptPartFromCode(code)];
958    if (!found) found = fallbacks[this.formatLanguageCode(code)];
959    if (!found) found = fallbacks[this.getLanguagePartFromCode(code)];
960    if (!found) found = fallbacks.default;
961    return found || [];
962  }
963  toResolveHierarchy(code, fallbackCode) {
964    const fallbackCodes = this.getFallbackCodes(fallbackCode || this.options.fallbackLng || [], code);
965    const codes = [];
966    const addCode = c => {
967      if (!c) return;
968      if (this.isSupportedCode(c)) {
969        codes.push(c);
970      } else {
971        this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
972      }
973    };
974    if (isString(code) && (code.indexOf('-') > -1 || code.indexOf('_') > -1)) {
975      if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code));
976      if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code));
977      if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code));
978    } else if (isString(code)) {
979      addCode(this.formatLanguageCode(code));
980    }
981    fallbackCodes.forEach(fc => {
982      if (codes.indexOf(fc) < 0) addCode(this.formatLanguageCode(fc));
983    });
984    return codes;
985  }
986}
987
988let sets = [{
989  lngs: ['ach', 'ak', 'am', 'arn', 'br', 'fil', 'gun', 'ln', 'mfe', 'mg', 'mi', 'oc', 'pt', 'pt-BR', 'tg', 'tl', 'ti', 'tr', 'uz', 'wa'],
990  nr: [1, 2],
991  fc: 1
992}, {
993  lngs: ['af', 'an', 'ast', 'az', 'bg', 'bn', 'ca', 'da', 'de', 'dev', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fi', 'fo', 'fur', 'fy', 'gl', 'gu', 'ha', 'hi', 'hu', 'hy', 'ia', 'it', 'kk', 'kn', 'ku', 'lb', 'mai', 'ml', 'mn', 'mr', 'nah', 'nap', 'nb', 'ne', 'nl', 'nn', 'no', 'nso', 'pa', 'pap', 'pms', 'ps', 'pt-PT', 'rm', 'sco', 'se', 'si', 'so', 'son', 'sq', 'sv', 'sw', 'ta', 'te', 'tk', 'ur', 'yo'],
994  nr: [1, 2],
995  fc: 2
996}, {
997  lngs: ['ay', 'bo', 'cgg', 'fa', 'ht', 'id', 'ja', 'jbo', 'ka', 'km', 'ko', 'ky', 'lo', 'ms', 'sah', 'su', 'th', 'tt', 'ug', 'vi', 'wo', 'zh'],
998  nr: [1],
999  fc: 3
1000}, {
1001  lngs: ['be', 'bs', 'cnr', 'dz', 'hr', 'ru', 'sr', 'uk'],
1002  nr: [1, 2, 5],
1003  fc: 4
1004}, {
1005  lngs: ['ar'],
1006  nr: [0, 1, 2, 3, 11, 100],
1007  fc: 5
1008}, {
1009  lngs: ['cs', 'sk'],
1010  nr: [1, 2, 5],
1011  fc: 6
1012}, {
1013  lngs: ['csb', 'pl'],
1014  nr: [1, 2, 5],
1015  fc: 7
1016}, {
1017  lngs: ['cy'],
1018  nr: [1, 2, 3, 8],
1019  fc: 8
1020}, {
1021  lngs: ['fr'],
1022  nr: [1, 2],
1023  fc: 9
1024}, {
1025  lngs: ['ga'],
1026  nr: [1, 2, 3, 7, 11],
1027  fc: 10
1028}, {
1029  lngs: ['gd'],
1030  nr: [1, 2, 3, 20],
1031  fc: 11
1032}, {
1033  lngs: ['is'],
1034  nr: [1, 2],
1035  fc: 12
1036}, {
1037  lngs: ['jv'],
1038  nr: [0, 1],
1039  fc: 13
1040}, {
1041  lngs: ['kw'],
1042  nr: [1, 2, 3, 4],
1043  fc: 14
1044}, {
1045  lngs: ['lt'],
1046  nr: [1, 2, 10],
1047  fc: 15
1048}, {
1049  lngs: ['lv'],
1050  nr: [1, 2, 0],
1051  fc: 16
1052}, {
1053  lngs: ['mk'],
1054  nr: [1, 2],
1055  fc: 17
1056}, {
1057  lngs: ['mnk'],
1058  nr: [0, 1, 2],
1059  fc: 18
1060}, {
1061  lngs: ['mt'],
1062  nr: [1, 2, 11, 20],
1063  fc: 19
1064}, {
1065  lngs: ['or'],
1066  nr: [2, 1],
1067  fc: 2
1068}, {
1069  lngs: ['ro'],
1070  nr: [1, 2, 20],
1071  fc: 20
1072}, {
1073  lngs: ['sl'],
1074  nr: [5, 1, 2, 3],
1075  fc: 21
1076}, {
1077  lngs: ['he', 'iw'],
1078  nr: [1, 2, 20, 21],
1079  fc: 22
1080}];
1081let _rulesPluralsTypes = {
1082  1: n => Number(n > 1),
1083  2: n => Number(n != 1),
1084  3: n => 0,
1085  4: n => Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2),
1086  5: n => Number(n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5),
1087  6: n => Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2),
1088  7: n => Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2),
1089  8: n => Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3),
1090  9: n => Number(n >= 2),
1091  10: n => Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4),
1092  11: n => Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3),
1093  12: n => Number(n % 10 != 1 || n % 100 == 11),
1094  13: n => Number(n !== 0),
1095  14: n => Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3),
1096  15: n => Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2),
1097  16: n => Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2),
1098  17: n => Number(n == 1 || n % 10 == 1 && n % 100 != 11 ? 0 : 1),
1099  18: n => Number(n == 0 ? 0 : n == 1 ? 1 : 2),
1100  19: n => Number(n == 1 ? 0 : n == 0 || n % 100 > 1 && n % 100 < 11 ? 1 : n % 100 > 10 && n % 100 < 20 ? 2 : 3),
1101  20: n => Number(n == 1 ? 0 : n == 0 || n % 100 > 0 && n % 100 < 20 ? 1 : 2),
1102  21: n => Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0),
1103  22: n => Number(n == 1 ? 0 : n == 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3)
1104};
1105const nonIntlVersions = ['v1', 'v2', 'v3'];
1106const intlVersions = ['v4'];
1107const suffixesOrder = {
1108  zero: 0,
1109  one: 1,
1110  two: 2,
1111  few: 3,
1112  many: 4,
1113  other: 5
1114};
1115const createRules = () => {
1116  const rules = {};
1117  sets.forEach(set => {
1118    set.lngs.forEach(l => {
1119      rules[l] = {
1120        numbers: set.nr,
1121        plurals: _rulesPluralsTypes[set.fc]
1122      };
1123    });
1124  });
1125  return rules;
1126};
1127class PluralResolver {
1128  constructor(languageUtils) {
1129    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1130    this.languageUtils = languageUtils;
1131    this.options = options;
1132    this.logger = baseLogger.create('pluralResolver');
1133    if ((!this.options.compatibilityJSON || intlVersions.includes(this.options.compatibilityJSON)) && (typeof Intl === 'undefined' || !Intl.PluralRules)) {
1134      this.options.compatibilityJSON = 'v3';
1135      this.logger.error('Your environment seems not to be Intl API compatible, use an Intl.PluralRules polyfill. Will fallback to the compatibilityJSON v3 format handling.');
1136    }
1137    this.rules = createRules();
1138    this.pluralRulesCache = {};
1139  }
1140  addRule(lng, obj) {
1141    this.rules[lng] = obj;
1142  }
1143  clearCache() {
1144    this.pluralRulesCache = {};
1145  }
1146  getRule(code) {
1147    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1148    if (this.shouldUseIntlApi()) {
1149      const cleanedCode = getCleanedCode(code === 'dev' ? 'en' : code);
1150      const type = options.ordinal ? 'ordinal' : 'cardinal';
1151      const cacheKey = JSON.stringify({
1152        cleanedCode,
1153        type
1154      });
1155      if (cacheKey in this.pluralRulesCache) {
1156        return this.pluralRulesCache[cacheKey];
1157      }
1158      let rule;
1159      try {
1160        rule = new Intl.PluralRules(cleanedCode, {
1161          type
1162        });
1163      } catch (err) {
1164        if (!code.match(/-|_/)) return;
1165        const lngPart = this.languageUtils.getLanguagePartFromCode(code);
1166        rule = this.getRule(lngPart, options);
1167      }
1168      this.pluralRulesCache[cacheKey] = rule;
1169      return rule;
1170    }
1171    return this.rules[code] || this.rules[this.languageUtils.getLanguagePartFromCode(code)];
1172  }
1173  needsPlural(code) {
1174    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1175    const rule = this.getRule(code, options);
1176    if (this.shouldUseIntlApi()) {
1177      return rule && rule.resolvedOptions().pluralCategories.length > 1;
1178    }
1179    return rule && rule.numbers.length > 1;
1180  }
1181  getPluralFormsOfKey(code, key) {
1182    let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1183    return this.getSuffixes(code, options).map(suffix => `${key}${suffix}`);
1184  }
1185  getSuffixes(code) {
1186    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1187    const rule = this.getRule(code, options);
1188    if (!rule) {
1189      return [];
1190    }
1191    if (this.shouldUseIntlApi()) {
1192      return rule.resolvedOptions().pluralCategories.sort((pluralCategory1, pluralCategory2) => suffixesOrder[pluralCategory1] - suffixesOrder[pluralCategory2]).map(pluralCategory => `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ''}${pluralCategory}`);
1193    }
1194    return rule.numbers.map(number => this.getSuffix(code, number, options));
1195  }
1196  getSuffix(code, count) {
1197    let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1198    const rule = this.getRule(code, options);
1199    if (rule) {
1200      if (this.shouldUseIntlApi()) {
1201        return `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ''}${rule.select(count)}`;
1202      }
1203      return this.getSuffixRetroCompatible(rule, count);
1204    }
1205    this.logger.warn(`no plural rule found for: ${code}`);
1206    return '';
1207  }
1208  getSuffixRetroCompatible(rule, count) {
1209    const idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count));
1210    let suffix = rule.numbers[idx];
1211    if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
1212      if (suffix === 2) {
1213        suffix = 'plural';
1214      } else if (suffix === 1) {
1215        suffix = '';
1216      }
1217    }
1218    const returnSuffix = () => this.options.prepend && suffix.toString() ? this.options.prepend + suffix.toString() : suffix.toString();
1219    if (this.options.compatibilityJSON === 'v1') {
1220      if (suffix === 1) return '';
1221      if (typeof suffix === 'number') return `_plural_${suffix.toString()}`;
1222      return returnSuffix();
1223    } else if (this.options.compatibilityJSON === 'v2') {
1224      return returnSuffix();
1225    } else if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
1226      return returnSuffix();
1227    }
1228    return this.options.prepend && idx.toString() ? this.options.prepend + idx.toString() : idx.toString();
1229  }
1230  shouldUseIntlApi() {
1231    return !nonIntlVersions.includes(this.options.compatibilityJSON);
1232  }
1233}
1234
1235const deepFindWithDefaults = function (data, defaultData, key) {
1236  let keySeparator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '.';
1237  let ignoreJSONStructure = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
1238  let path = getPathWithDefaults(data, defaultData, key);
1239  if (!path && ignoreJSONStructure && isString(key)) {
1240    path = deepFind(data, key, keySeparator);
1241    if (path === undefined) path = deepFind(defaultData, key, keySeparator);
1242  }
1243  return path;
1244};
1245const regexSafe = val => val.replace(/\$/g, '$$$$');
1246class Interpolator {
1247  constructor() {
1248    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1249    this.logger = baseLogger.create('interpolator');
1250    this.options = options;
1251    this.format = options.interpolation && options.interpolation.format || (value => value);
1252    this.init(options);
1253  }
1254  init() {
1255    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1256    if (!options.interpolation) options.interpolation = {
1257      escapeValue: true
1258    };
1259    const {
1260      escape: escape$1,
1261      escapeValue,
1262      useRawValueToEscape,
1263      prefix,
1264      prefixEscaped,
1265      suffix,
1266      suffixEscaped,
1267      formatSeparator,
1268      unescapeSuffix,
1269      unescapePrefix,
1270      nestingPrefix,
1271      nestingPrefixEscaped,
1272      nestingSuffix,
1273      nestingSuffixEscaped,
1274      nestingOptionsSeparator,
1275      maxReplaces,
1276      alwaysFormat
1277    } = options.interpolation;
1278    this.escape = escape$1 !== undefined ? escape$1 : escape;
1279    this.escapeValue = escapeValue !== undefined ? escapeValue : true;
1280    this.useRawValueToEscape = useRawValueToEscape !== undefined ? useRawValueToEscape : false;
1281    this.prefix = prefix ? regexEscape(prefix) : prefixEscaped || '{{';
1282    this.suffix = suffix ? regexEscape(suffix) : suffixEscaped || '}}';
1283    this.formatSeparator = formatSeparator || ',';
1284    this.unescapePrefix = unescapeSuffix ? '' : unescapePrefix || '-';
1285    this.unescapeSuffix = this.unescapePrefix ? '' : unescapeSuffix || '';
1286    this.nestingPrefix = nestingPrefix ? regexEscape(nestingPrefix) : nestingPrefixEscaped || regexEscape('$t(');
1287    this.nestingSuffix = nestingSuffix ? regexEscape(nestingSuffix) : nestingSuffixEscaped || regexEscape(')');
1288    this.nestingOptionsSeparator = nestingOptionsSeparator || ',';
1289    this.maxReplaces = maxReplaces || 1000;
1290    this.alwaysFormat = alwaysFormat !== undefined ? alwaysFormat : false;
1291    this.resetRegExp();
1292  }
1293  reset() {
1294    if (this.options) this.init(this.options);
1295  }
1296  resetRegExp() {
1297    const getOrResetRegExp = (existingRegExp, pattern) => {
1298      if (existingRegExp && existingRegExp.source === pattern) {
1299        existingRegExp.lastIndex = 0;
1300        return existingRegExp;
1301      }
1302      return new RegExp(pattern, 'g');
1303    };
1304    this.regexp = getOrResetRegExp(this.regexp, `${this.prefix}(.+?)${this.suffix}`);
1305    this.regexpUnescape = getOrResetRegExp(this.regexpUnescape, `${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`);
1306    this.nestingRegexp = getOrResetRegExp(this.nestingRegexp, `${this.nestingPrefix}(.+?)${this.nestingSuffix}`);
1307  }
1308  interpolate(str, data, lng, options) {
1309    let match;
1310    let value;
1311    let replaces;
1312    const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
1313    const handleFormat = key => {
1314      if (key.indexOf(this.formatSeparator) < 0) {
1315        const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
1316        return this.alwaysFormat ? this.format(path, undefined, lng, {
1317          ...options,
1318          ...data,
1319          interpolationkey: key
1320        }) : path;
1321      }
1322      const p = key.split(this.formatSeparator);
1323      const k = p.shift().trim();
1324      const f = p.join(this.formatSeparator).trim();
1325      return this.format(deepFindWithDefaults(data, defaultData, k, this.options.keySeparator, this.options.ignoreJSONStructure), f, lng, {
1326        ...options,
1327        ...data,
1328        interpolationkey: k
1329      });
1330    };
1331    this.resetRegExp();
1332    const missingInterpolationHandler = options && options.missingInterpolationHandler || this.options.missingInterpolationHandler;
1333    const skipOnVariables = options && options.interpolation && options.interpolation.skipOnVariables !== undefined ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
1334    const todos = [{
1335      regex: this.regexpUnescape,
1336      safeValue: val => regexSafe(val)
1337    }, {
1338      regex: this.regexp,
1339      safeValue: val => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
1340    }];
1341    todos.forEach(todo => {
1342      replaces = 0;
1343      while (match = todo.regex.exec(str)) {
1344        const matchedVar = match[1].trim();
1345        value = handleFormat(matchedVar);
1346        if (value === undefined) {
1347          if (typeof missingInterpolationHandler === 'function') {
1348            const temp = missingInterpolationHandler(str, match, options);
1349            value = isString(temp) ? temp : '';
1350          } else if (options && Object.prototype.hasOwnProperty.call(options, matchedVar)) {
1351            value = '';
1352          } else if (skipOnVariables) {
1353            value = match[0];
1354            continue;
1355          } else {
1356            this.logger.warn(`missed to pass in variable ${matchedVar} for interpolating ${str}`);
1357            value = '';
1358          }
1359        } else if (!isString(value) && !this.useRawValueToEscape) {
1360          value = makeString(value);
1361        }
1362        const safeValue = todo.safeValue(value);
1363        str = str.replace(match[0], safeValue);
1364        if (skipOnVariables) {
1365          todo.regex.lastIndex += value.length;
1366          todo.regex.lastIndex -= match[0].length;
1367        } else {
1368          todo.regex.lastIndex = 0;
1369        }
1370        replaces++;
1371        if (replaces >= this.maxReplaces) {
1372          break;
1373        }
1374      }
1375    });
1376    return str;
1377  }
1378  nest(str, fc) {
1379    let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1380    let match;
1381    let value;
1382    let clonedOptions;
1383    const handleHasOptions = (key, inheritedOptions) => {
1384      const sep = this.nestingOptionsSeparator;
1385      if (key.indexOf(sep) < 0) return key;
1386      const c = key.split(new RegExp(`${sep}[ ]*{`));
1387      let optionsString = `{${c[1]}`;
1388      key = c[0];
1389      optionsString = this.interpolate(optionsString, clonedOptions);
1390      const matchedSingleQuotes = optionsString.match(/'/g);
1391      const matchedDoubleQuotes = optionsString.match(/"/g);
1392      if (matchedSingleQuotes && matchedSingleQuotes.length % 2 === 0 && !matchedDoubleQuotes || matchedDoubleQuotes.length % 2 !== 0) {
1393        optionsString = optionsString.replace(/'/g, '"');
1394      }
1395      try {
1396        clonedOptions = JSON.parse(optionsString);
1397        if (inheritedOptions) clonedOptions = {
1398          ...inheritedOptions,
1399          ...clonedOptions
1400        };
1401      } catch (e) {
1402        this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
1403        return `${key}${sep}${optionsString}`;
1404      }
1405      if (clonedOptions.defaultValue && clonedOptions.defaultValue.indexOf(this.prefix) > -1) delete clonedOptions.defaultValue;
1406      return key;
1407    };
1408    while (match = this.nestingRegexp.exec(str)) {
1409      let formatters = [];
1410      clonedOptions = {
1411        ...options
1412      };
1413      clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
1414      clonedOptions.applyPostProcessor = false;
1415      delete clonedOptions.defaultValue;
1416      let doReduce = false;
1417      if (match[0].indexOf(this.formatSeparator) !== -1 && !/{.*}/.test(match[1])) {
1418        const r = match[1].split(this.formatSeparator).map(elem => elem.trim());
1419        match[1] = r.shift();
1420        formatters = r;
1421        doReduce = true;
1422      }
1423      value = fc(handleHasOptions.call(this, match[1].trim(), clonedOptions), clonedOptions);
1424      if (value && match[0] === str && !isString(value)) return value;
1425      if (!isString(value)) value = makeString(value);
1426      if (!value) {
1427        this.logger.warn(`missed to resolve ${match[1]} for nesting ${str}`);
1428        value = '';
1429      }
1430      if (doReduce) {
1431        value = formatters.reduce((v, f) => this.format(v, f, options.lng, {
1432          ...options,
1433          interpolationkey: match[1].trim()
1434        }), value.trim());
1435      }
1436      str = str.replace(match[0], value);
1437      this.regexp.lastIndex = 0;
1438    }
1439    return str;
1440  }
1441}
1442
1443const parseFormatStr = formatStr => {
1444  let formatName = formatStr.toLowerCase().trim();
1445  const formatOptions = {};
1446  if (formatStr.indexOf('(') > -1) {
1447    const p = formatStr.split('(');
1448    formatName = p[0].toLowerCase().trim();
1449    const optStr = p[1].substring(0, p[1].length - 1);
1450    if (formatName === 'currency' && optStr.indexOf(':') < 0) {
1451      if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1452    } else if (formatName === 'relativetime' && optStr.indexOf(':') < 0) {
1453      if (!formatOptions.range) formatOptions.range = optStr.trim();
1454    } else {
1455      const opts = optStr.split(';');
1456      opts.forEach(opt => {
1457        if (opt) {
1458          const [key, ...rest] = opt.split(':');
1459          const val = rest.join(':').trim().replace(/^'+|'+$/g, '');
1460          const trimmedKey = key.trim();
1461          if (!formatOptions[trimmedKey]) formatOptions[trimmedKey] = val;
1462          if (val === 'false') formatOptions[trimmedKey] = false;
1463          if (val === 'true') formatOptions[trimmedKey] = true;
1464          if (!isNaN(val)) formatOptions[trimmedKey] = parseInt(val, 10);
1465        }
1466      });
1467    }
1468  }
1469  return {
1470    formatName,
1471    formatOptions
1472  };
1473};
1474const createCachedFormatter = fn => {
1475  const cache = {};
1476  return (val, lng, options) => {
1477    let optForCache = options;
1478    if (options && options.interpolationkey && options.formatParams && options.formatParams[options.interpolationkey] && options[options.interpolationkey]) {
1479      optForCache = {
1480        ...optForCache,
1481        [options.interpolationkey]: undefined
1482      };
1483    }
1484    const key = lng + JSON.stringify(optForCache);
1485    let formatter = cache[key];
1486    if (!formatter) {
1487      formatter = fn(getCleanedCode(lng), options);
1488      cache[key] = formatter;
1489    }
1490    return formatter(val);
1491  };
1492};
1493class Formatter {
1494  constructor() {
1495    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1496    this.logger = baseLogger.create('formatter');
1497    this.options = options;
1498    this.formats = {
1499      number: createCachedFormatter((lng, opt) => {
1500        const formatter = new Intl.NumberFormat(lng, {
1501          ...opt
1502        });
1503        return val => formatter.format(val);
1504      }),
1505      currency: createCachedFormatter((lng, opt) => {
1506        const formatter = new Intl.NumberFormat(lng, {
1507          ...opt,
1508          style: 'currency'
1509        });
1510        return val => formatter.format(val);
1511      }),
1512      datetime: createCachedFormatter((lng, opt) => {
1513        const formatter = new Intl.DateTimeFormat(lng, {
1514          ...opt
1515        });
1516        return val => formatter.format(val);
1517      }),
1518      relativetime: createCachedFormatter((lng, opt) => {
1519        const formatter = new Intl.RelativeTimeFormat(lng, {
1520          ...opt
1521        });
1522        return val => formatter.format(val, opt.range || 'day');
1523      }),
1524      list: createCachedFormatter((lng, opt) => {
1525        const formatter = new Intl.ListFormat(lng, {
1526          ...opt
1527        });
1528        return val => formatter.format(val);
1529      })
1530    };
1531    this.init(options);
1532  }
1533  init(services) {
1534    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
1535      interpolation: {}
1536    };
1537    this.formatSeparator = options.interpolation.formatSeparator || ',';
1538  }
1539  add(name, fc) {
1540    this.formats[name.toLowerCase().trim()] = fc;
1541  }
1542  addCached(name, fc) {
1543    this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
1544  }
1545  format(value, format, lng) {
1546    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1547    const formats = format.split(this.formatSeparator);
1548    if (formats.length > 1 && formats[0].indexOf('(') > 1 && formats[0].indexOf(')') < 0 && formats.find(f => f.indexOf(')') > -1)) {
1549      const lastIndex = formats.findIndex(f => f.indexOf(')') > -1);
1550      formats[0] = [formats[0], ...formats.splice(1, lastIndex)].join(this.formatSeparator);
1551    }
1552    const result = formats.reduce((mem, f) => {
1553      const {
1554        formatName,
1555        formatOptions
1556      } = parseFormatStr(f);
1557      if (this.formats[formatName]) {
1558        let formatted = mem;
1559        try {
1560          const valOptions = options && options.formatParams && options.formatParams[options.interpolationkey] || {};
1561          const l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
1562          formatted = this.formats[formatName](mem, l, {
1563            ...formatOptions,
1564            ...options,
1565            ...valOptions
1566          });
1567        } catch (error) {
1568          this.logger.warn(error);
1569        }
1570        return formatted;
1571      } else {
1572        this.logger.warn(`there was no format function for ${formatName}`);
1573      }
1574      return mem;
1575    }, value);
1576    return result;
1577  }
1578}
1579
1580const removePending = (q, name) => {
1581  if (q.pending[name] !== undefined) {
1582    delete q.pending[name];
1583    q.pendingCount--;
1584  }
1585};
1586class Connector extends EventEmitter {
1587  constructor(backend, store, services) {
1588    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1589    super();
1590    this.backend = backend;
1591    this.store = store;
1592    this.services = services;
1593    this.languageUtils = services.languageUtils;
1594    this.options = options;
1595    this.logger = baseLogger.create('backendConnector');
1596    this.waitingReads = [];
1597    this.maxParallelReads = options.maxParallelReads || 10;
1598    this.readingCalls = 0;
1599    this.maxRetries = options.maxRetries >= 0 ? options.maxRetries : 5;
1600    this.retryTimeout = options.retryTimeout >= 1 ? options.retryTimeout : 350;
1601    this.state = {};
1602    this.queue = [];
1603    if (this.backend && this.backend.init) {
1604      this.backend.init(services, options.backend, options);
1605    }
1606  }
1607  queueLoad(languages, namespaces, options, callback) {
1608    const toLoad = {};
1609    const pending = {};
1610    const toLoadLanguages = {};
1611    const toLoadNamespaces = {};
1612    languages.forEach(lng => {
1613      let hasAllNamespaces = true;
1614      namespaces.forEach(ns => {
1615        const name = `${lng}|${ns}`;
1616        if (!options.reload && this.store.hasResourceBundle(lng, ns)) {
1617          this.state[name] = 2;
1618        } else if (this.state[name] < 0) ; else if (this.state[name] === 1) {
1619          if (pending[name] === undefined) pending[name] = true;
1620        } else {
1621          this.state[name] = 1;
1622          hasAllNamespaces = false;
1623          if (pending[name] === undefined) pending[name] = true;
1624          if (toLoad[name] === undefined) toLoad[name] = true;
1625          if (toLoadNamespaces[ns] === undefined) toLoadNamespaces[ns] = true;
1626        }
1627      });
1628      if (!hasAllNamespaces) toLoadLanguages[lng] = true;
1629    });
1630    if (Object.keys(toLoad).length || Object.keys(pending).length) {
1631      this.queue.push({
1632        pending,
1633        pendingCount: Object.keys(pending).length,
1634        loaded: {},
1635        errors: [],
1636        callback
1637      });
1638    }
1639    return {
1640      toLoad: Object.keys(toLoad),
1641      pending: Object.keys(pending),
1642      toLoadLanguages: Object.keys(toLoadLanguages),
1643      toLoadNamespaces: Object.keys(toLoadNamespaces)
1644    };
1645  }
1646  loaded(name, err, data) {
1647    const s = name.split('|');
1648    const lng = s[0];
1649    const ns = s[1];
1650    if (err) this.emit('failedLoading', lng, ns, err);
1651    if (!err && data) {
1652      this.store.addResourceBundle(lng, ns, data, undefined, undefined, {
1653        skipCopy: true
1654      });
1655    }
1656    this.state[name] = err ? -1 : 2;
1657    if (err && data) this.state[name] = 0;
1658    const loaded = {};
1659    this.queue.forEach(q => {
1660      pushPath(q.loaded, [lng], ns);
1661      removePending(q, name);
1662      if (err) q.errors.push(err);
1663      if (q.pendingCount === 0 && !q.done) {
1664        Object.keys(q.loaded).forEach(l => {
1665          if (!loaded[l]) loaded[l] = {};
1666          const loadedKeys = q.loaded[l];
1667          if (loadedKeys.length) {
1668            loadedKeys.forEach(n => {
1669              if (loaded[l][n] === undefined) loaded[l][n] = true;
1670            });
1671          }
1672        });
1673        q.done = true;
1674        if (q.errors.length) {
1675          q.callback(q.errors);
1676        } else {
1677          q.callback();
1678        }
1679      }
1680    });
1681    this.emit('loaded', loaded);
1682    this.queue = this.queue.filter(q => !q.done);
1683  }
1684  read(lng, ns, fcName) {
1685    let tried = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
1686    let wait = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.retryTimeout;
1687    let callback = arguments.length > 5 ? arguments[5] : undefined;
1688    if (!lng.length) return callback(null, {});
1689    if (this.readingCalls >= this.maxParallelReads) {
1690      this.waitingReads.push({
1691        lng,
1692        ns,
1693        fcName,
1694        tried,
1695        wait,
1696        callback
1697      });
1698      return;
1699    }
1700    this.readingCalls++;
1701    const resolver = (err, data) => {
1702      this.readingCalls--;
1703      if (this.waitingReads.length > 0) {
1704        const next = this.waitingReads.shift();
1705        this.read(next.lng, next.ns, next.fcName, next.tried, next.wait, next.callback);
1706      }
1707      if (err && data && tried < this.maxRetries) {
1708        setTimeout(() => {
1709          this.read.call(this, lng, ns, fcName, tried + 1, wait * 2, callback);
1710        }, wait);
1711        return;
1712      }
1713      callback(err, data);
1714    };
1715    const fc = this.backend[fcName].bind(this.backend);
1716    if (fc.length === 2) {
1717      try {
1718        const r = fc(lng, ns);
1719        if (r && typeof r.then === 'function') {
1720          r.then(data => resolver(null, data)).catch(resolver);
1721        } else {
1722          resolver(null, r);
1723        }
1724      } catch (err) {
1725        resolver(err);
1726      }
1727      return;
1728    }
1729    return fc(lng, ns, resolver);
1730  }
1731  prepareLoading(languages, namespaces) {
1732    let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1733    let callback = arguments.length > 3 ? arguments[3] : undefined;
1734    if (!this.backend) {
1735      this.logger.warn('No backend was added via i18next.use. Will not load resources.');
1736      return callback && callback();
1737    }
1738    if (isString(languages)) languages = this.languageUtils.toResolveHierarchy(languages);
1739    if (isString(namespaces)) namespaces = [namespaces];
1740    const toLoad = this.queueLoad(languages, namespaces, options, callback);
1741    if (!toLoad.toLoad.length) {
1742      if (!toLoad.pending.length) callback();
1743      return null;
1744    }
1745    toLoad.toLoad.forEach(name => {
1746      this.loadOne(name);
1747    });
1748  }
1749  load(languages, namespaces, callback) {
1750    this.prepareLoading(languages, namespaces, {}, callback);
1751  }
1752  reload(languages, namespaces, callback) {
1753    this.prepareLoading(languages, namespaces, {
1754      reload: true
1755    }, callback);
1756  }
1757  loadOne(name) {
1758    let prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
1759    const s = name.split('|');
1760    const lng = s[0];
1761    const ns = s[1];
1762    this.read(lng, ns, 'read', undefined, undefined, (err, data) => {
1763      if (err) this.logger.warn(`${prefix}loading namespace ${ns} for language ${lng} failed`, err);
1764      if (!err && data) this.logger.log(`${prefix}loaded namespace ${ns} for language ${lng}`, data);
1765      this.loaded(name, err, data);
1766    });
1767  }
1768  saveMissing(languages, namespace, key, fallbackValue, isUpdate) {
1769    let options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
1770    let clb = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : () => {};
1771    if (this.services.utils && this.services.utils.hasLoadedNamespace && !this.services.utils.hasLoadedNamespace(namespace)) {
1772      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!!!');
1773      return;
1774    }
1775    if (key === undefined || key === null || key === '') return;
1776    if (this.backend && this.backend.create) {
1777      const opts = {
1778        ...options,
1779        isUpdate
1780      };
1781      const fc = this.backend.create.bind(this.backend);
1782      if (fc.length < 6) {
1783        try {
1784          let r;
1785          if (fc.length === 5) {
1786            r = fc(languages, namespace, key, fallbackValue, opts);
1787          } else {
1788            r = fc(languages, namespace, key, fallbackValue);
1789          }
1790          if (r && typeof r.then === 'function') {
1791            r.then(data => clb(null, data)).catch(clb);
1792          } else {
1793            clb(null, r);
1794          }
1795        } catch (err) {
1796          clb(err);
1797        }
1798      } else {
1799        fc(languages, namespace, key, fallbackValue, clb, opts);
1800      }
1801    }
1802    if (!languages || !languages[0]) return;
1803    this.store.addResource(languages[0], namespace, key, fallbackValue);
1804  }
1805}
1806
1807const get = () => ({
1808  debug: false,
1809  initImmediate: true,
1810  ns: ['translation'],
1811  defaultNS: ['translation'],
1812  fallbackLng: ['dev'],
1813  fallbackNS: false,
1814  supportedLngs: false,
1815  nonExplicitSupportedLngs: false,
1816  load: 'all',
1817  preload: false,
1818  simplifyPluralSuffix: true,
1819  keySeparator: '.',
1820  nsSeparator: ':',
1821  pluralSeparator: '_',
1822  contextSeparator: '_',
1823  partialBundledLanguages: false,
1824  saveMissing: false,
1825  updateMissing: false,
1826  saveMissingTo: 'fallback',
1827  saveMissingPlurals: true,
1828  missingKeyHandler: false,
1829  missingInterpolationHandler: false,
1830  postProcess: false,
1831  postProcessPassResolved: false,
1832  returnNull: false,
1833  returnEmptyString: true,
1834  returnObjects: false,
1835  joinArrays: false,
1836  returnedObjectHandler: false,
1837  parseMissingKeyHandler: false,
1838  appendNamespaceToMissingKey: false,
1839  appendNamespaceToCIMode: false,
1840  overloadTranslationOptionHandler: args => {
1841    let ret = {};
1842    if (typeof args[1] === 'object') ret = args[1];
1843    if (isString(args[1])) ret.defaultValue = args[1];
1844    if (isString(args[2])) ret.tDescription = args[2];
1845    if (typeof args[2] === 'object' || typeof args[3] === 'object') {
1846      const options = args[3] || args[2];
1847      Object.keys(options).forEach(key => {
1848        ret[key] = options[key];
1849      });
1850    }
1851    return ret;
1852  },
1853  interpolation: {
1854    escapeValue: true,
1855    format: value => value,
1856    prefix: '{{',
1857    suffix: '}}',
1858    formatSeparator: ',',
1859    unescapePrefix: '-',
1860    nestingPrefix: '$t(',
1861    nestingSuffix: ')',
1862    nestingOptionsSeparator: ',',
1863    maxReplaces: 1000,
1864    skipOnVariables: true
1865  }
1866});
1867const transformOptions = options => {
1868  if (isString(options.ns)) options.ns = [options.ns];
1869  if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
1870  if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
1871  if (options.supportedLngs && options.supportedLngs.indexOf('cimode') < 0) {
1872    options.supportedLngs = options.supportedLngs.concat(['cimode']);
1873  }
1874  return options;
1875};
1876
1877const noop = () => {};
1878const bindMemberFunctions = inst => {
1879  const mems = Object.getOwnPropertyNames(Object.getPrototypeOf(inst));
1880  mems.forEach(mem => {
1881    if (typeof inst[mem] === 'function') {
1882      inst[mem] = inst[mem].bind(inst);
1883    }
1884  });
1885};
1886class I18n extends EventEmitter {
1887  constructor() {
1888    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1889    let callback = arguments.length > 1 ? arguments[1] : undefined;
1890    super();
1891    this.options = transformOptions(options);
1892    this.services = {};
1893    this.logger = baseLogger;
1894    this.modules = {
1895      external: []
1896    };
1897    bindMemberFunctions(this);
1898    if (callback && !this.isInitialized && !options.isClone) {
1899      if (!this.options.initImmediate) {
1900        this.init(options, callback);
1901        return this;
1902      }
1903      setTimeout(() => {
1904        this.init(options, callback);
1905      }, 0);
1906    }
1907  }
1908  init() {
1909    var _this = this;
1910    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1911    let callback = arguments.length > 1 ? arguments[1] : undefined;
1912    this.isInitializing = true;
1913    if (typeof options === 'function') {
1914      callback = options;
1915      options = {};
1916    }
1917    if (!options.defaultNS && options.defaultNS !== false && options.ns) {
1918      if (isString(options.ns)) {
1919        options.defaultNS = options.ns;
1920      } else if (options.ns.indexOf('translation') < 0) {
1921        options.defaultNS = options.ns[0];
1922      }
1923    }
1924    const defOpts = get();
1925    this.options = {
1926      ...defOpts,
1927      ...this.options,
1928      ...transformOptions(options)
1929    };
1930    if (this.options.compatibilityAPI !== 'v1') {
1931      this.options.interpolation = {
1932        ...defOpts.interpolation,
1933        ...this.options.interpolation
1934      };
1935    }
1936    if (options.keySeparator !== undefined) {
1937      this.options.userDefinedKeySeparator = options.keySeparator;
1938    }
1939    if (options.nsSeparator !== undefined) {
1940      this.options.userDefinedNsSeparator = options.nsSeparator;
1941    }
1942    const createClassOnDemand = ClassOrObject => {
1943      if (!ClassOrObject) return null;
1944      if (typeof ClassOrObject === 'function') return new ClassOrObject();
1945      return ClassOrObject;
1946    };
1947    if (!this.options.isClone) {
1948      if (this.modules.logger) {
1949        baseLogger.init(createClassOnDemand(this.modules.logger), this.options);
1950      } else {
1951        baseLogger.init(null, this.options);
1952      }
1953      let formatter;
1954      if (this.modules.formatter) {
1955        formatter = this.modules.formatter;
1956      } else if (typeof Intl !== 'undefined') {
1957        formatter = Formatter;
1958      }
1959      const lu = new LanguageUtil(this.options);
1960      this.store = new ResourceStore(this.options.resources, this.options);
1961      const s = this.services;
1962      s.logger = baseLogger;
1963      s.resourceStore = this.store;
1964      s.languageUtils = lu;
1965      s.pluralResolver = new PluralResolver(lu, {
1966        prepend: this.options.pluralSeparator,
1967        compatibilityJSON: this.options.compatibilityJSON,
1968        simplifyPluralSuffix: this.options.simplifyPluralSuffix
1969      });
1970      if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
1971        s.formatter = createClassOnDemand(formatter);
1972        s.formatter.init(s, this.options);
1973        this.options.interpolation.format = s.formatter.format.bind(s.formatter);
1974      }
1975      s.interpolator = new Interpolator(this.options);
1976      s.utils = {
1977        hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
1978      };
1979      s.backendConnector = new Connector(createClassOnDemand(this.modules.backend), s.resourceStore, s, this.options);
1980      s.backendConnector.on('*', function (event) {
1981        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1982          args[_key - 1] = arguments[_key];
1983        }
1984        _this.emit(event, ...args);
1985      });
1986      if (this.modules.languageDetector) {
1987        s.languageDetector = createClassOnDemand(this.modules.languageDetector);
1988        if (s.languageDetector.init) s.languageDetector.init(s, this.options.detection, this.options);
1989      }
1990      if (this.modules.i18nFormat) {
1991        s.i18nFormat = createClassOnDemand(this.modules.i18nFormat);
1992        if (s.i18nFormat.init) s.i18nFormat.init(this);
1993      }
1994      this.translator = new Translator(this.services, this.options);
1995      this.translator.on('*', function (event) {
1996        for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1997          args[_key2 - 1] = arguments[_key2];
1998        }
1999        _this.emit(event, ...args);
2000      });
2001      this.modules.external.forEach(m => {
2002        if (m.init) m.init(this);
2003      });
2004    }
2005    this.format = this.options.interpolation.format;
2006    if (!callback) callback = noop;
2007    if (this.options.fallbackLng && !this.services.languageDetector && !this.options.lng) {
2008      const codes = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
2009      if (codes.length > 0 && codes[0] !== 'dev') this.options.lng = codes[0];
2010    }
2011    if (!this.services.languageDetector && !this.options.lng) {
2012      this.logger.warn('init: no languageDetector is used and no lng is defined');
2013    }
2014    const storeApi = ['getResource', 'hasResourceBundle', 'getResourceBundle', 'getDataByLanguage'];
2015    storeApi.forEach(fcName => {
2016      this[fcName] = function () {
2017        return _this.store[fcName](...arguments);
2018      };
2019    });
2020    const storeApiChained = ['addResource', 'addResources', 'addResourceBundle', 'removeResourceBundle'];
2021    storeApiChained.forEach(fcName => {
2022      this[fcName] = function () {
2023        _this.store[fcName](...arguments);
2024        return _this;
2025      };
2026    });
2027    const deferred = defer();
2028    const load = () => {
2029      const finish = (err, t) => {
2030        this.isInitializing = false;
2031        if (this.isInitialized && !this.initializedStoreOnce) this.logger.warn('init: i18next is already initialized. You should call init just once!');
2032        this.isInitialized = true;
2033        if (!this.options.isClone) this.logger.log('initialized', this.options);
2034        this.emit('initialized', this.options);
2035        deferred.resolve(t);
2036        callback(err, t);
2037      };
2038      if (this.languages && this.options.compatibilityAPI !== 'v1' && !this.isInitialized) return finish(null, this.t.bind(this));
2039      this.changeLanguage(this.options.lng, finish);
2040    };
2041    if (this.options.resources || !this.options.initImmediate) {
2042      load();
2043    } else {
2044      setTimeout(load, 0);
2045    }
2046    return deferred;
2047  }
2048  loadResources(language) {
2049    let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
2050    let usedCallback = callback;
2051    const usedLng = isString(language) ? language : this.language;
2052    if (typeof language === 'function') usedCallback = language;
2053    if (!this.options.resources || this.options.partialBundledLanguages) {
2054      if (usedLng && usedLng.toLowerCase() === 'cimode' && (!this.options.preload || this.options.preload.length === 0)) return usedCallback();
2055      const toLoad = [];
2056      const append = lng => {
2057        if (!lng) return;
2058        if (lng === 'cimode') return;
2059        const lngs = this.services.languageUtils.toResolveHierarchy(lng);
2060        lngs.forEach(l => {
2061          if (l === 'cimode') return;
2062          if (toLoad.indexOf(l) < 0) toLoad.push(l);
2063        });
2064      };
2065      if (!usedLng) {
2066        const fallbacks = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
2067        fallbacks.forEach(l => append(l));
2068      } else {
2069        append(usedLng);
2070      }
2071      if (this.options.preload) {
2072        this.options.preload.forEach(l => append(l));
2073      }
2074      this.services.backendConnector.load(toLoad, this.options.ns, e => {
2075        if (!e && !this.resolvedLanguage && this.language) this.setResolvedLanguage(this.language);
2076        usedCallback(e);
2077      });
2078    } else {
2079      usedCallback(null);
2080    }
2081  }
2082  reloadResources(lngs, ns, callback) {
2083    const deferred = defer();
2084    if (typeof lngs === 'function') {
2085      callback = lngs;
2086      lngs = undefined;
2087    }
2088    if (typeof ns === 'function') {
2089      callback = ns;
2090      ns = undefined;
2091    }
2092    if (!lngs) lngs = this.languages;
2093    if (!ns) ns = this.options.ns;
2094    if (!callback) callback = noop;
2095    this.services.backendConnector.reload(lngs, ns, err => {
2096      deferred.resolve();
2097      callback(err);
2098    });
2099    return deferred;
2100  }
2101  use(module) {
2102    if (!module) throw new Error('You are passing an undefined module! Please check the object you are passing to i18next.use()');
2103    if (!module.type) throw new Error('You are passing a wrong module! Please check the object you are passing to i18next.use()');
2104    if (module.type === 'backend') {
2105      this.modules.backend = module;
2106    }
2107    if (module.type === 'logger' || module.log && module.warn && module.error) {
2108      this.modules.logger = module;
2109    }
2110    if (module.type === 'languageDetector') {
2111      this.modules.languageDetector = module;
2112    }
2113    if (module.type === 'i18nFormat') {
2114      this.modules.i18nFormat = module;
2115    }
2116    if (module.type === 'postProcessor') {
2117      postProcessor.addPostProcessor(module);
2118    }
2119    if (module.type === 'formatter') {
2120      this.modules.formatter = module;
2121    }
2122    if (module.type === '3rdParty') {
2123      this.modules.external.push(module);
2124    }
2125    return this;
2126  }
2127  setResolvedLanguage(l) {
2128    if (!l || !this.languages) return;
2129    if (['cimode', 'dev'].indexOf(l) > -1) return;
2130    for (let li = 0; li < this.languages.length; li++) {
2131      const lngInLngs = this.languages[li];
2132      if (['cimode', 'dev'].indexOf(lngInLngs) > -1) continue;
2133      if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
2134        this.resolvedLanguage = lngInLngs;
2135        break;
2136      }
2137    }
2138  }
2139  changeLanguage(lng, callback) {
2140    var _this2 = this;
2141    this.isLanguageChangingTo = lng;
2142    const deferred = defer();
2143    this.emit('languageChanging', lng);
2144    const setLngProps = l => {
2145      this.language = l;
2146      this.languages = this.services.languageUtils.toResolveHierarchy(l);
2147      this.resolvedLanguage = undefined;
2148      this.setResolvedLanguage(l);
2149    };
2150    const done = (err, l) => {
2151      if (l) {
2152        setLngProps(l);
2153        this.translator.changeLanguage(l);
2154        this.isLanguageChangingTo = undefined;
2155        this.emit('languageChanged', l);
2156        this.logger.log('languageChanged', l);
2157      } else {
2158        this.isLanguageChangingTo = undefined;
2159      }
2160      deferred.resolve(function () {
2161        return _this2.t(...arguments);
2162      });
2163      if (callback) callback(err, function () {
2164        return _this2.t(...arguments);
2165      });
2166    };
2167    const setLng = lngs => {
2168      if (!lng && !lngs && this.services.languageDetector) lngs = [];
2169      const l = isString(lngs) ? lngs : this.services.languageUtils.getBestMatchFromCodes(lngs);
2170      if (l) {
2171        if (!this.language) {
2172          setLngProps(l);
2173        }
2174        if (!this.translator.language) this.translator.changeLanguage(l);
2175        if (this.services.languageDetector && this.services.languageDetector.cacheUserLanguage) this.services.languageDetector.cacheUserLanguage(l);
2176      }
2177      this.loadResources(l, err => {
2178        done(err, l);
2179      });
2180    };
2181    if (!lng && this.services.languageDetector && !this.services.languageDetector.async) {
2182      setLng(this.services.languageDetector.detect());
2183    } else if (!lng && this.services.languageDetector && this.services.languageDetector.async) {
2184      if (this.services.languageDetector.detect.length === 0) {
2185        this.services.languageDetector.detect().then(setLng);
2186      } else {
2187        this.services.languageDetector.detect(setLng);
2188      }
2189    } else {
2190      setLng(lng);
2191    }
2192    return deferred;
2193  }
2194  getFixedT(lng, ns, keyPrefix) {
2195    var _this3 = this;
2196    const fixedT = function (key, opts) {
2197      let options;
2198      if (typeof opts !== 'object') {
2199        for (var _len3 = arguments.length, rest = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
2200          rest[_key3 - 2] = arguments[_key3];
2201        }
2202        options = _this3.options.overloadTranslationOptionHandler([key, opts].concat(rest));
2203      } else {
2204        options = {
2205          ...opts
2206        };
2207      }
2208      options.lng = options.lng || fixedT.lng;
2209      options.lngs = options.lngs || fixedT.lngs;
2210      options.ns = options.ns || fixedT.ns;
2211      if (options.keyPrefix !== '') options.keyPrefix = options.keyPrefix || keyPrefix || fixedT.keyPrefix;
2212      const keySeparator = _this3.options.keySeparator || '.';
2213      let resultKey;
2214      if (options.keyPrefix && Array.isArray(key)) {
2215        resultKey = key.map(k => `${options.keyPrefix}${keySeparator}${k}`);
2216      } else {
2217        resultKey = options.keyPrefix ? `${options.keyPrefix}${keySeparator}${key}` : key;
2218      }
2219      return _this3.t(resultKey, options);
2220    };
2221    if (isString(lng)) {
2222      fixedT.lng = lng;
2223    } else {
2224      fixedT.lngs = lng;
2225    }
2226    fixedT.ns = ns;
2227    fixedT.keyPrefix = keyPrefix;
2228    return fixedT;
2229  }
2230  t() {
2231    return this.translator && this.translator.translate(...arguments);
2232  }
2233  exists() {
2234    return this.translator && this.translator.exists(...arguments);
2235  }
2236  setDefaultNamespace(ns) {
2237    this.options.defaultNS = ns;
2238  }
2239  hasLoadedNamespace(ns) {
2240    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2241    if (!this.isInitialized) {
2242      this.logger.warn('hasLoadedNamespace: i18next was not initialized', this.languages);
2243      return false;
2244    }
2245    if (!this.languages || !this.languages.length) {
2246      this.logger.warn('hasLoadedNamespace: i18n.languages were undefined or empty', this.languages);
2247      return false;
2248    }
2249    const lng = options.lng || this.resolvedLanguage || this.languages[0];
2250    const fallbackLng = this.options ? this.options.fallbackLng : false;
2251    const lastLng = this.languages[this.languages.length - 1];
2252    if (lng.toLowerCase() === 'cimode') return true;
2253    const loadNotPending = (l, n) => {
2254      const loadState = this.services.backendConnector.state[`${l}|${n}`];
2255      return loadState === -1 || loadState === 0 || loadState === 2;
2256    };
2257    if (options.precheck) {
2258      const preResult = options.precheck(this, loadNotPending);
2259      if (preResult !== undefined) return preResult;
2260    }
2261    if (this.hasResourceBundle(lng, ns)) return true;
2262    if (!this.services.backendConnector.backend || this.options.resources && !this.options.partialBundledLanguages) return true;
2263    if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
2264    return false;
2265  }
2266  loadNamespaces(ns, callback) {
2267    const deferred = defer();
2268    if (!this.options.ns) {
2269      if (callback) callback();
2270      return Promise.resolve();
2271    }
2272    if (isString(ns)) ns = [ns];
2273    ns.forEach(n => {
2274      if (this.options.ns.indexOf(n) < 0) this.options.ns.push(n);
2275    });
2276    this.loadResources(err => {
2277      deferred.resolve();
2278      if (callback) callback(err);
2279    });
2280    return deferred;
2281  }
2282  loadLanguages(lngs, callback) {
2283    const deferred = defer();
2284    if (isString(lngs)) lngs = [lngs];
2285    const preloaded = this.options.preload || [];
2286    const newLngs = lngs.filter(lng => preloaded.indexOf(lng) < 0 && this.services.languageUtils.isSupportedCode(lng));
2287    if (!newLngs.length) {
2288      if (callback) callback();
2289      return Promise.resolve();
2290    }
2291    this.options.preload = preloaded.concat(newLngs);
2292    this.loadResources(err => {
2293      deferred.resolve();
2294      if (callback) callback(err);
2295    });
2296    return deferred;
2297  }
2298  dir(lng) {
2299    if (!lng) lng = this.resolvedLanguage || (this.languages && this.languages.length > 0 ? this.languages[0] : this.language);
2300    if (!lng) return 'rtl';
2301    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'];
2302    const languageUtils = this.services && this.services.languageUtils || new LanguageUtil(get());
2303    return rtlLngs.indexOf(languageUtils.getLanguagePartFromCode(lng)) > -1 || lng.toLowerCase().indexOf('-arab') > 1 ? 'rtl' : 'ltr';
2304  }
2305  static createInstance() {
2306    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2307    let callback = arguments.length > 1 ? arguments[1] : undefined;
2308    return new I18n(options, callback);
2309  }
2310  cloneInstance() {
2311    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2312    let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
2313    const forkResourceStore = options.forkResourceStore;
2314    if (forkResourceStore) delete options.forkResourceStore;
2315    const mergedOptions = {
2316      ...this.options,
2317      ...options,
2318      ...{
2319        isClone: true
2320      }
2321    };
2322    const clone = new I18n(mergedOptions);
2323    if (options.debug !== undefined || options.prefix !== undefined) {
2324      clone.logger = clone.logger.clone(options);
2325    }
2326    const membersToCopy = ['store', 'services', 'language'];
2327    membersToCopy.forEach(m => {
2328      clone[m] = this[m];
2329    });
2330    clone.services = {
2331      ...this.services
2332    };
2333    clone.services.utils = {
2334      hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
2335    };
2336    if (forkResourceStore) {
2337      clone.store = new ResourceStore(this.store.data, mergedOptions);
2338      clone.services.resourceStore = clone.store;
2339    }
2340    clone.translator = new Translator(clone.services, mergedOptions);
2341    clone.translator.on('*', function (event) {
2342      for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
2343        args[_key4 - 1] = arguments[_key4];
2344      }
2345      clone.emit(event, ...args);
2346    });
2347    clone.init(mergedOptions, callback);
2348    clone.translator.options = mergedOptions;
2349    clone.translator.backendConnector.services.utils = {
2350      hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
2351    };
2352    return clone;
2353  }
2354  toJSON() {
2355    return {
2356      options: this.options,
2357      store: this.store,
2358      language: this.language,
2359      languages: this.languages,
2360      resolvedLanguage: this.resolvedLanguage
2361    };
2362  }
2363}
2364const instance = I18n.createInstance();
2365instance.createInstance = I18n.createInstance;
2366
2367const createInstance = instance.createInstance;
2368const dir = instance.dir;
2369const init = instance.init;
2370const loadResources = instance.loadResources;
2371const reloadResources = instance.reloadResources;
2372const use = instance.use;
2373const changeLanguage = instance.changeLanguage;
2374const getFixedT = instance.getFixedT;
2375const t = instance.t;
2376const exists = instance.exists;
2377const setDefaultNamespace = instance.setDefaultNamespace;
2378const hasLoadedNamespace = instance.hasLoadedNamespace;
2379const loadNamespaces = instance.loadNamespaces;
2380const loadLanguages = instance.loadLanguages;
2381
2382export { changeLanguage, createInstance, instance as default, dir, exists, getFixedT, hasLoadedNamespace, init, loadLanguages, loadNamespaces, loadResources, reloadResources, setDefaultNamespace, t, use };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.