@ngx-translate/core
Version:
The internationalization (i18n) library for Angular
877 lines • 69.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { EventEmitter, Inject, Injectable, InjectionToken } from "@angular/core";
import { concat, merge, Observable, of } from "rxjs";
import { map, share, switchMap, take, toArray } from "rxjs/operators";
import { MissingTranslationHandler } from "./missing-translation-handler";
import { TranslateCompiler } from "./translate.compiler";
import { TranslateLoader } from "./translate.loader";
import { TranslateParser } from "./translate.parser";
import { TranslateStore } from "./translate.store";
import { isDefined, mergeDeep } from "./util";
/** @type {?} */
export var USE_STORE = new InjectionToken('USE_STORE');
/** @type {?} */
export var USE_DEFAULT_LANG = new InjectionToken('USE_DEFAULT_LANG');
/**
* @record
*/
export function TranslationChangeEvent() { }
if (false) {
/** @type {?} */
TranslationChangeEvent.prototype.translations;
/** @type {?} */
TranslationChangeEvent.prototype.lang;
}
/**
* @record
*/
export function LangChangeEvent() { }
if (false) {
/** @type {?} */
LangChangeEvent.prototype.lang;
/** @type {?} */
LangChangeEvent.prototype.translations;
}
/**
* @record
*/
export function DefaultLangChangeEvent() { }
if (false) {
/** @type {?} */
DefaultLangChangeEvent.prototype.lang;
/** @type {?} */
DefaultLangChangeEvent.prototype.translations;
}
var TranslateService = /** @class */ (function () {
/**
*
* @param store an instance of the store (that is supposed to be unique)
* @param currentLoader An instance of the loader currently used
* @param compiler An instance of the compiler currently used
* @param parser An instance of the parser currently used
* @param missingTranslationHandler A handler for missing translations.
* @param isolate whether this service should use the store or not
* @param useDefaultLang whether we should use default language translation when current language translation is missing.
*/
function TranslateService(store, currentLoader, compiler, parser, missingTranslationHandler, useDefaultLang, isolate) {
if (useDefaultLang === void 0) { useDefaultLang = true; }
if (isolate === void 0) { isolate = false; }
this.store = store;
this.currentLoader = currentLoader;
this.compiler = compiler;
this.parser = parser;
this.missingTranslationHandler = missingTranslationHandler;
this.useDefaultLang = useDefaultLang;
this.isolate = isolate;
this.pending = false;
this._onTranslationChange = new EventEmitter();
this._onLangChange = new EventEmitter();
this._onDefaultLangChange = new EventEmitter();
this._langs = [];
this._translations = {};
this._translationRequests = {};
}
Object.defineProperty(TranslateService.prototype, "onTranslationChange", {
/**
* An EventEmitter to listen to translation change events
* onTranslationChange.subscribe((params: TranslationChangeEvent) => {
* // do something
* });
*/
get: /**
* An EventEmitter to listen to translation change events
* onTranslationChange.subscribe((params: TranslationChangeEvent) => {
* // do something
* });
* @return {?}
*/
function () {
return this.isolate ? this._onTranslationChange : this.store.onTranslationChange;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TranslateService.prototype, "onLangChange", {
/**
* An EventEmitter to listen to lang change events
* onLangChange.subscribe((params: LangChangeEvent) => {
* // do something
* });
*/
get: /**
* An EventEmitter to listen to lang change events
* onLangChange.subscribe((params: LangChangeEvent) => {
* // do something
* });
* @return {?}
*/
function () {
return this.isolate ? this._onLangChange : this.store.onLangChange;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TranslateService.prototype, "onDefaultLangChange", {
/**
* An EventEmitter to listen to default lang change events
* onDefaultLangChange.subscribe((params: DefaultLangChangeEvent) => {
* // do something
* });
*/
get: /**
* An EventEmitter to listen to default lang change events
* onDefaultLangChange.subscribe((params: DefaultLangChangeEvent) => {
* // do something
* });
* @return {?}
*/
function () {
return this.isolate ? this._onDefaultLangChange : this.store.onDefaultLangChange;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TranslateService.prototype, "defaultLang", {
/**
* The default lang to fallback when translations are missing on the current lang
*/
get: /**
* The default lang to fallback when translations are missing on the current lang
* @return {?}
*/
function () {
return this.isolate ? this._defaultLang : this.store.defaultLang;
},
set: /**
* @param {?} defaultLang
* @return {?}
*/
function (defaultLang) {
if (this.isolate) {
this._defaultLang = defaultLang;
}
else {
this.store.defaultLang = defaultLang;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(TranslateService.prototype, "currentLang", {
/**
* The lang currently used
*/
get: /**
* The lang currently used
* @return {?}
*/
function () {
return this.isolate ? this._currentLang : this.store.currentLang;
},
set: /**
* @param {?} currentLang
* @return {?}
*/
function (currentLang) {
if (this.isolate) {
this._currentLang = currentLang;
}
else {
this.store.currentLang = currentLang;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(TranslateService.prototype, "langs", {
/**
* an array of langs
*/
get: /**
* an array of langs
* @return {?}
*/
function () {
return this.isolate ? this._langs : this.store.langs;
},
set: /**
* @param {?} langs
* @return {?}
*/
function (langs) {
if (this.isolate) {
this._langs = langs;
}
else {
this.store.langs = langs;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(TranslateService.prototype, "translations", {
/**
* a list of translations per lang
*/
get: /**
* a list of translations per lang
* @return {?}
*/
function () {
return this.isolate ? this._translations : this.store.translations;
},
set: /**
* @param {?} translations
* @return {?}
*/
function (translations) {
if (this.isolate) {
this._translations = translations;
}
else {
this.store.translations = translations;
}
},
enumerable: true,
configurable: true
});
/**
* Sets the default language to use as a fallback
*/
/**
* Sets the default language to use as a fallback
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.setDefaultLang = /**
* Sets the default language to use as a fallback
* @param {?} lang
* @return {?}
*/
function (lang) {
var _this = this;
if (lang === this.defaultLang) {
return;
}
/** @type {?} */
var pending = this.retrieveTranslations(lang);
if (typeof pending !== "undefined") {
// on init set the defaultLang immediately
if (!this.defaultLang) {
this.defaultLang = lang;
}
pending.pipe(take(1))
.subscribe(function (res) {
_this.changeDefaultLang(lang);
});
}
else { // we already have this language
this.changeDefaultLang(lang);
}
};
/**
* Gets the default language used
*/
/**
* Gets the default language used
* @return {?}
*/
TranslateService.prototype.getDefaultLang = /**
* Gets the default language used
* @return {?}
*/
function () {
return this.defaultLang;
};
/**
* Changes the lang currently used
*/
/**
* Changes the lang currently used
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.use = /**
* Changes the lang currently used
* @param {?} lang
* @return {?}
*/
function (lang) {
var _this = this;
// don't change the language if the language given is already selected
if (lang === this.currentLang) {
return of(this.translations[lang]);
}
/** @type {?} */
var pending = this.retrieveTranslations(lang);
if (typeof pending !== "undefined") {
// on init set the currentLang immediately
if (!this.currentLang) {
this.currentLang = lang;
}
pending.pipe(take(1))
.subscribe(function (res) {
_this.changeLang(lang);
});
return pending;
}
else { // we have this language, return an Observable
this.changeLang(lang);
return of(this.translations[lang]);
}
};
/**
* Retrieves the given translations
*/
/**
* Retrieves the given translations
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.retrieveTranslations = /**
* Retrieves the given translations
* @param {?} lang
* @return {?}
*/
function (lang) {
/** @type {?} */
var pending;
// if this language is unavailable, ask for it
if (typeof this.translations[lang] === "undefined") {
this._translationRequests[lang] = this._translationRequests[lang] || this.getTranslation(lang);
pending = this._translationRequests[lang];
}
return pending;
};
/**
* Gets an object of translations for a given language with the current loader
* and passes it through the compiler
*/
/**
* Gets an object of translations for a given language with the current loader
* and passes it through the compiler
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.getTranslation = /**
* Gets an object of translations for a given language with the current loader
* and passes it through the compiler
* @param {?} lang
* @return {?}
*/
function (lang) {
var _this = this;
this.pending = true;
/** @type {?} */
var loadingTranslations = this.currentLoader.getTranslation(lang).pipe(share());
this.loadingTranslations = loadingTranslations.pipe(take(1), map(function (res) { return _this.compiler.compileTranslations(res, lang); }), share());
this.loadingTranslations
.subscribe(function (res) {
_this.translations[lang] = res;
_this.updateLangs();
_this.pending = false;
}, function (err) {
_this.pending = false;
});
return loadingTranslations;
};
/**
* Manually sets an object of translations for a given language
* after passing it through the compiler
*/
/**
* Manually sets an object of translations for a given language
* after passing it through the compiler
* @param {?} lang
* @param {?} translations
* @param {?=} shouldMerge
* @return {?}
*/
TranslateService.prototype.setTranslation = /**
* Manually sets an object of translations for a given language
* after passing it through the compiler
* @param {?} lang
* @param {?} translations
* @param {?=} shouldMerge
* @return {?}
*/
function (lang, translations, shouldMerge) {
if (shouldMerge === void 0) { shouldMerge = false; }
translations = this.compiler.compileTranslations(translations, lang);
if (shouldMerge && this.translations[lang]) {
this.translations[lang] = mergeDeep(this.translations[lang], translations);
}
else {
this.translations[lang] = translations;
}
this.updateLangs();
this.onTranslationChange.emit({ lang: lang, translations: this.translations[lang] });
};
/**
* Returns an array of currently available langs
*/
/**
* Returns an array of currently available langs
* @return {?}
*/
TranslateService.prototype.getLangs = /**
* Returns an array of currently available langs
* @return {?}
*/
function () {
return this.langs;
};
/**
* Add available langs
*/
/**
* Add available langs
* @param {?} langs
* @return {?}
*/
TranslateService.prototype.addLangs = /**
* Add available langs
* @param {?} langs
* @return {?}
*/
function (langs) {
var _this = this;
langs.forEach(function (lang) {
if (_this.langs.indexOf(lang) === -1) {
_this.langs.push(lang);
}
});
};
/**
* Update the list of available langs
*/
/**
* Update the list of available langs
* @return {?}
*/
TranslateService.prototype.updateLangs = /**
* Update the list of available langs
* @return {?}
*/
function () {
this.addLangs(Object.keys(this.translations));
};
/**
* Returns the parsed result of the translations
*/
/**
* Returns the parsed result of the translations
* @param {?} translations
* @param {?} key
* @param {?=} interpolateParams
* @return {?}
*/
TranslateService.prototype.getParsedResult = /**
* Returns the parsed result of the translations
* @param {?} translations
* @param {?} key
* @param {?=} interpolateParams
* @return {?}
*/
function (translations, key, interpolateParams) {
var e_1, _a, e_2, _b;
/** @type {?} */
var res;
if (key instanceof Array) {
/** @type {?} */
var result = {};
/** @type {?} */
var observables = false;
try {
for (var key_1 = tslib_1.__values(key), key_1_1 = key_1.next(); !key_1_1.done; key_1_1 = key_1.next()) {
var k = key_1_1.value;
result[k] = this.getParsedResult(translations, k, interpolateParams);
if (typeof result[k].subscribe === "function") {
observables = true;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (key_1_1 && !key_1_1.done && (_a = key_1.return)) _a.call(key_1);
}
finally { if (e_1) throw e_1.error; }
}
if (observables) {
/** @type {?} */
var mergedObs = void 0;
try {
for (var key_2 = tslib_1.__values(key), key_2_1 = key_2.next(); !key_2_1.done; key_2_1 = key_2.next()) {
var k = key_2_1.value;
/** @type {?} */
var obs = typeof result[k].subscribe === "function" ? result[k] : of((/** @type {?} */ (result[k])));
if (typeof mergedObs === "undefined") {
mergedObs = obs;
}
else {
mergedObs = merge(mergedObs, obs);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (key_2_1 && !key_2_1.done && (_b = key_2.return)) _b.call(key_2);
}
finally { if (e_2) throw e_2.error; }
}
return mergedObs.pipe(toArray(), map(function (arr) {
/** @type {?} */
var obj = {};
arr.forEach(function (value, index) {
obj[key[index]] = value;
});
return obj;
}));
}
return result;
}
if (translations) {
res = this.parser.interpolate(this.parser.getValue(translations, key), interpolateParams);
}
if (typeof res === "undefined" && this.defaultLang && this.defaultLang !== this.currentLang && this.useDefaultLang) {
res = this.parser.interpolate(this.parser.getValue(this.translations[this.defaultLang], key), interpolateParams);
}
if (typeof res === "undefined") {
/** @type {?} */
var params = { key: key, translateService: this };
if (typeof interpolateParams !== 'undefined') {
params.interpolateParams = interpolateParams;
}
res = this.missingTranslationHandler.handle(params);
}
return typeof res !== "undefined" ? res : key;
};
/**
* Gets the translated value of a key (or an array of keys)
* @returns the translated key, or an object of translated keys
*/
/**
* Gets the translated value of a key (or an array of keys)
* @param {?} key
* @param {?=} interpolateParams
* @return {?} the translated key, or an object of translated keys
*/
TranslateService.prototype.get = /**
* Gets the translated value of a key (or an array of keys)
* @param {?} key
* @param {?=} interpolateParams
* @return {?} the translated key, or an object of translated keys
*/
function (key, interpolateParams) {
var _this = this;
if (!isDefined(key) || !key.length) {
throw new Error("Parameter \"key\" required");
}
// check if we are loading a new translation to use
if (this.pending) {
return Observable.create(function (observer) {
/** @type {?} */
var onComplete = function (res) {
observer.next(res);
observer.complete();
};
/** @type {?} */
var onError = function (err) {
observer.error(err);
};
_this.loadingTranslations.subscribe(function (res) {
res = _this.getParsedResult(res, key, interpolateParams);
if (typeof res.subscribe === "function") {
res.subscribe(onComplete, onError);
}
else {
onComplete(res);
}
}, onError);
});
}
else {
/** @type {?} */
var res = this.getParsedResult(this.translations[this.currentLang], key, interpolateParams);
if (typeof res.subscribe === "function") {
return res;
}
else {
return of(res);
}
}
};
/**
* Returns a stream of translated values of a key (or an array of keys) which updates
* whenever the language changes.
* @returns A stream of the translated key, or an object of translated keys
*/
/**
* Returns a stream of translated values of a key (or an array of keys) which updates
* whenever the language changes.
* @param {?} key
* @param {?=} interpolateParams
* @return {?} A stream of the translated key, or an object of translated keys
*/
TranslateService.prototype.stream = /**
* Returns a stream of translated values of a key (or an array of keys) which updates
* whenever the language changes.
* @param {?} key
* @param {?=} interpolateParams
* @return {?} A stream of the translated key, or an object of translated keys
*/
function (key, interpolateParams) {
var _this = this;
if (!isDefined(key) || !key.length) {
throw new Error("Parameter \"key\" required");
}
return concat(this.get(key, interpolateParams), this.onLangChange.pipe(switchMap(function (event) {
/** @type {?} */
var res = _this.getParsedResult(event.translations, key, interpolateParams);
if (typeof res.subscribe === "function") {
return res;
}
else {
return of(res);
}
})));
};
/**
* Returns a translation instantly from the internal state of loaded translation.
* All rules regarding the current language, the preferred language of even fallback languages will be used except any promise handling.
*/
/**
* Returns a translation instantly from the internal state of loaded translation.
* All rules regarding the current language, the preferred language of even fallback languages will be used except any promise handling.
* @param {?} key
* @param {?=} interpolateParams
* @return {?}
*/
TranslateService.prototype.instant = /**
* Returns a translation instantly from the internal state of loaded translation.
* All rules regarding the current language, the preferred language of even fallback languages will be used except any promise handling.
* @param {?} key
* @param {?=} interpolateParams
* @return {?}
*/
function (key, interpolateParams) {
if (!isDefined(key) || !key.length) {
throw new Error("Parameter \"key\" required");
}
/** @type {?} */
var res = this.getParsedResult(this.translations[this.currentLang], key, interpolateParams);
if (typeof res.subscribe !== "undefined") {
if (key instanceof Array) {
/** @type {?} */
var obj_1 = {};
key.forEach(function (value, index) {
obj_1[key[index]] = key[index];
});
return obj_1;
}
return key;
}
else {
return res;
}
};
/**
* Sets the translated value of a key, after compiling it
*/
/**
* Sets the translated value of a key, after compiling it
* @param {?} key
* @param {?} value
* @param {?=} lang
* @return {?}
*/
TranslateService.prototype.set = /**
* Sets the translated value of a key, after compiling it
* @param {?} key
* @param {?} value
* @param {?=} lang
* @return {?}
*/
function (key, value, lang) {
if (lang === void 0) { lang = this.currentLang; }
this.translations[lang][key] = this.compiler.compile(value, lang);
this.updateLangs();
this.onTranslationChange.emit({ lang: lang, translations: this.translations[lang] });
};
/**
* Changes the current lang
*/
/**
* Changes the current lang
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.changeLang = /**
* Changes the current lang
* @param {?} lang
* @return {?}
*/
function (lang) {
this.currentLang = lang;
this.onLangChange.emit({ lang: lang, translations: this.translations[lang] });
// if there is no default lang, use the one that we just set
if (!this.defaultLang) {
this.changeDefaultLang(lang);
}
};
/**
* Changes the default lang
*/
/**
* Changes the default lang
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.changeDefaultLang = /**
* Changes the default lang
* @param {?} lang
* @return {?}
*/
function (lang) {
this.defaultLang = lang;
this.onDefaultLangChange.emit({ lang: lang, translations: this.translations[lang] });
};
/**
* Allows to reload the lang file from the file
*/
/**
* Allows to reload the lang file from the file
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.reloadLang = /**
* Allows to reload the lang file from the file
* @param {?} lang
* @return {?}
*/
function (lang) {
this.resetLang(lang);
return this.getTranslation(lang);
};
/**
* Deletes inner translation
*/
/**
* Deletes inner translation
* @param {?} lang
* @return {?}
*/
TranslateService.prototype.resetLang = /**
* Deletes inner translation
* @param {?} lang
* @return {?}
*/
function (lang) {
this._translationRequests[lang] = undefined;
this.translations[lang] = undefined;
};
/**
* Returns the language code name from the browser, e.g. "de"
*/
/**
* Returns the language code name from the browser, e.g. "de"
* @return {?}
*/
TranslateService.prototype.getBrowserLang = /**
* Returns the language code name from the browser, e.g. "de"
* @return {?}
*/
function () {
if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {
return undefined;
}
/** @type {?} */
var browserLang = window.navigator.languages ? window.navigator.languages[0] : null;
browserLang = browserLang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;
if (browserLang.indexOf('-') !== -1) {
browserLang = browserLang.split('-')[0];
}
if (browserLang.indexOf('_') !== -1) {
browserLang = browserLang.split('_')[0];
}
return browserLang;
};
/**
* Returns the culture language code name from the browser, e.g. "de-DE"
*/
/**
* Returns the culture language code name from the browser, e.g. "de-DE"
* @return {?}
*/
TranslateService.prototype.getBrowserCultureLang = /**
* Returns the culture language code name from the browser, e.g. "de-DE"
* @return {?}
*/
function () {
if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {
return undefined;
}
/** @type {?} */
var browserCultureLang = window.navigator.languages ? window.navigator.languages[0] : null;
browserCultureLang = browserCultureLang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;
return browserCultureLang;
};
TranslateService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
TranslateService.ctorParameters = function () { return [
{ type: TranslateStore },
{ type: TranslateLoader },
{ type: TranslateCompiler },
{ type: TranslateParser },
{ type: MissingTranslationHandler },
{ type: Boolean, decorators: [{ type: Inject, args: [USE_DEFAULT_LANG,] }] },
{ type: Boolean, decorators: [{ type: Inject, args: [USE_STORE,] }] }
]; };
return TranslateService;
}());
export { TranslateService };
if (false) {
/** @type {?} */
TranslateService.prototype.loadingTranslations;
/** @type {?} */
TranslateService.prototype.pending;
/** @type {?} */
TranslateService.prototype._onTranslationChange;
/** @type {?} */
TranslateService.prototype._onLangChange;
/** @type {?} */
TranslateService.prototype._onDefaultLangChange;
/** @type {?} */
TranslateService.prototype._defaultLang;
/** @type {?} */
TranslateService.prototype._currentLang;
/** @type {?} */
TranslateService.prototype._langs;
/** @type {?} */
TranslateService.prototype._translations;
/** @type {?} */
TranslateService.prototype._translationRequests;
/** @type {?} */
TranslateService.prototype.store;
/** @type {?} */
TranslateService.prototype.currentLoader;
/** @type {?} */
TranslateService.prototype.compiler;
/** @type {?} */
TranslateService.prototype.parser;
/** @type {?} */
TranslateService.prototype.missingTranslationHandler;
/** @type {?} */
TranslateService.prototype.useDefaultLang;
/** @type {?} */
TranslateService.prototype.isolate;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LXRyYW5zbGF0ZS9jb3JlLyIsInNvdXJjZXMiOlsibGliL3RyYW5zbGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQVksRUFBRSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdELE9BQU8sRUFBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEUsT0FBTyxFQUFDLHlCQUF5QixFQUFrQyxNQUFNLCtCQUErQixDQUFDO0FBQ3pHLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZELE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFFbkQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sUUFBUSxDQUFDOztBQUU1QyxNQUFNLEtBQU8sU0FBUyxHQUFHLElBQUksY0FBYyxDQUFTLFdBQVcsQ0FBQzs7QUFDaEUsTUFBTSxLQUFPLGdCQUFnQixHQUFHLElBQUksY0FBYyxDQUFTLGtCQUFrQixDQUFDOzs7O0FBRTlFLDRDQUdDOzs7SUFGQyw4Q0FBa0I7O0lBQ2xCLHNDQUFhOzs7OztBQUdmLHFDQUdDOzs7SUFGQywrQkFBYTs7SUFDYix1Q0FBa0I7Ozs7O0FBR3BCLDRDQUdDOzs7SUFGQyxzQ0FBYTs7SUFDYiw4Q0FBa0I7O0FBU3BCO0lBdUdFOzs7Ozs7Ozs7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VyxFQUFFO1lBQzVFLE9BQU8sU0FBUyxDQUFDO1NBQ2xCOztZQUVHLGtCQUFrQixHQUFRLE1BQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSTtRQUMvRixrQkFBa0IsR0FBRyxrQkFBa0IsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGVBQWUsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQztRQUUxSSxPQUFPLGtCQUFrQixDQUFDO0lBQzVCLENBQUM7O2dCQXZlRixVQUFVOzs7O2dCQTNCSCxjQUFjO2dCQUhkLGVBQWU7Z0JBRGYsaUJBQWlCO2dCQUVqQixlQUFlO2dCQUhmLHlCQUF5Qjs4Q0FzSmxCLE1BQU0sU0FBQyxnQkFBZ0I7OENBQ3ZCLE1BQU0sU0FBQyxTQUFTOztJQWlYL0IsdUJBQUM7Q0FBQSxBQXhlRCxJQXdlQztTQXZlWSxnQkFBZ0I7OztJQUMzQiwrQ0FBNkM7O0lBQzdDLG1DQUFpQzs7SUFDakMsZ0RBQWdIOztJQUNoSCx5Q0FBMkY7O0lBQzNGLGdEQUFnSDs7SUFDaEgsd0NBQTZCOztJQUM3Qix3Q0FBNkI7O0lBQzdCLGtDQUFtQzs7SUFDbkMseUNBQWdDOztJQUNoQyxnREFBdUM7O0lBc0czQixpQ0FBNEI7O0lBQzVCLHlDQUFxQzs7SUFDckMsb0NBQWtDOztJQUNsQyxrQ0FBOEI7O0lBQzlCLHFEQUEyRDs7SUFDM0QsMENBQWdFOztJQUNoRSxtQ0FBbUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0V2ZW50RW1pdHRlciwgSW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7Y29uY2F0LCBtZXJnZSwgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIG9mfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHttYXAsIHNoYXJlLCBzd2l0Y2hNYXAsIHRha2UsIHRvQXJyYXl9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuaW1wb3J0IHtNaXNzaW5nVHJhbnNsYXRpb25IYW5kbGVyLCBNaXNzaW5nVHJhbnNsYXRpb25IYW5kbGVyUGFyYW1zfSBmcm9tIFwiLi9taXNzaW5nLXRyYW5zbGF0aW9uLWhhbmRsZXJcIjtcbmltcG9ydCB7VHJhbnNsYXRlQ29tcGlsZXJ9IGZyb20gXCIuL3RyYW5zbGF0ZS5jb21waWxlclwiO1xuaW1wb3J0IHtUcmFuc2xhdGVMb2FkZXJ9IGZyb20gXCIuL3RyYW5zbGF0ZS5sb2FkZXJcIjtcbmltcG9ydCB7VHJhbnNsYXRlUGFyc2VyfSBmcm9tIFwiLi90cmFuc2xhdGUucGFyc2VyXCI7XG5cbmltcG9ydCB7VHJhbnNsYXRlU3RvcmV9IGZyb20gXCIuL3RyYW5zbGF0ZS5zdG9yZVwiO1xuaW1wb3J0IHtpc0RlZmluZWQsIG1lcmdlRGVlcH0gZnJvbSBcIi4vdXRpbFwiO1xuXG5leHBvcnQgY29uc3QgVVNFX1NUT1JFID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oJ1VTRV9TVE9SRScpO1xuZXhwb3J0IGNvbnN0IFVTRV9ERUZBVUxUX0xBTkcgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPignVVNFX0RFRkFVTFRfTEFORycpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbGF0aW9uQ2hhbmdlRXZlbnQge1xuICB0cmFuc2xhdGlvbnM6IGFueTtcbiAgbGFuZzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExhbmdDaGFuZ2VFdmVudCB7XG4gIGxhbmc6IHN0cmluZztcbiAgdHJhbnNsYXRpb25zOiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVmYXVsdExhbmdDaGFuZ2VFdmVudCB7XG4gIGxhbmc6IHN0cmluZztcbiAgdHJhbnNsYXRpb25zOiBhbnk7XG59XG5cbmRlY2xhcmUgaW50ZXJmYWNlIFdpbmRvdyB7XG4gIG5hdmlnYXRvcjogYW55O1xufVxuXG5kZWNsYXJlIGNvbnN0IHdpbmRvdzogV2luZG93O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRlU2VydmljZSB7XG4gIHByaXZhdGUgbG9hZGluZ1RyYW5zbGF0aW9uczogT2JzZXJ2YWJsZTxhbnk+O1xuICBwcml2YXRlIHBlbmRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBfb25UcmFuc2xhdGlvbkNoYW5nZTogRXZlbnRFbWl0dGVyPFRyYW5zbGF0aW9uQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxUcmFuc2xhdGlvbkNoYW5nZUV2ZW50PigpO1xuICBwcml2YXRlIF9vbkxhbmdDaGFuZ2U6IEV2ZW50RW1pdHRlcjxMYW5nQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxMYW5nQ2hhbmdlRXZlbnQ+KCk7XG4gIHByaXZhdGUgX29uRGVmYXVsdExhbmdDaGFuZ2U6IEV2ZW50RW1pdHRlcjxEZWZhdWx0TGFuZ0NoYW5nZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8RGVmYXVsdExhbmdDaGFuZ2VFdmVudD4oKTtcbiAgcHJpdmF0ZSBfZGVmYXVsdExhbmc6IHN0cmluZztcbiAgcHJpdmF0ZSBfY3VycmVudExhbmc6IHN0cmluZztcbiAgcHJpdmF0ZSBfbGFuZ3M6IEFycmF5PHN0cmluZz4gPSBbXTtcbiAgcHJpdmF0ZSBfdHJhbnNsYXRpb25zOiBhbnkgPSB7fTtcbiAgcHJpdmF0ZSBfdHJhbnNsYXRpb25SZXF1ZXN0czogYW55ID0ge307XG5cbiAgLyoqXG4gICAqIEFuIEV2ZW50RW1pdHRlciB0byBsaXN0ZW4gdG8gdHJhbnNsYXRpb24gY2hhbmdlIGV2ZW50c1xuICAgKiBvblRyYW5zbGF0aW9uQ2hhbmdlLnN1YnNjcmliZSgocGFyYW1zOiBUcmFuc2xhdGlvbkNoYW5nZUV2ZW50KSA9PiB7XG4gICAgICogICAgIC8vIGRvIHNvbWV0aGluZ1xuICAgICAqIH0pO1xuICAgKi9cbiAgZ2V0IG9uVHJhbnNsYXRpb25DaGFuZ2UoKTogRXZlbnRFbWl0dGVyPFRyYW5zbGF0aW9uQ2hhbmdlRXZlbnQ+IHtcbiAgICByZXR1cm4gdGhpcy5pc29sYXRlID8gdGhpcy5fb25UcmFuc2xhdGlvbkNoYW5nZSA6IHRoaXMuc3RvcmUub25U