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