@singleton-i18n/angular-client
Version:
Singleton client code for Angular 10.
256 lines • 33.7 kB
JavaScript
import { __awaiter } from "tslib";
/*
* Copyright 2019-2021 VMware, Inc.
* SPDX-License-Identifier: EPL-2.0
*/
import { Injectable } from '@angular/core';
import { EventEmitter } from '@angular/core';
import { LocaleService } from './locale.service';
import { I18nLoader } from '../loader';
import { mergeObject, assign, deprecatedWarn } from '../util';
import { concat, Observable, forkJoin, of } from 'rxjs';
import { share, switchMap, take, catchError } from 'rxjs/operators';
import { getNameSpace, VIPConfigFactory } from '../config';
import { I18nContext } from './i18n.context';
export class VIPService {
constructor(localeService, i18nContext, currentLoader) {
this.localeService = localeService;
this.i18nContext = i18nContext;
this.currentLoader = currentLoader;
this.pending = false;
this.configs = [];
this.availableLocales = [];
this._onLocaleChange = new EventEmitter();
this._i18nScope = [];
this._localeData = {};
}
get onLocaleChange() {
return this._onLocaleChange;
}
get localeData() {
return this._localeData;
}
get i18nScope() {
return this._i18nScope;
}
/**
* Loading the i18n data at app module or root of lazy module.
* @param config For root module or lazy load mdule.
*/
initData(config) {
return __awaiter(this, void 0, void 0, function* () {
this.subscribeLocaleSubject();
this.registerComponent(config, true);
this.initLocale(config);
yield this.loadLocaleData();
});
}
/**
* Init locale by config passed from root module for compatibility.
* Will be removed in v9.
* @param config
*/
initLocale(config) {
if (config.locale || config.language || config.region) {
console.warn('Set language and region by configuration is deprecated, will be removed in v9. ' +
'Please use LocaleService.init instead.');
if (config.language && config.region) {
this.localeService.init(config.language, config.region);
}
else if (config.locale) {
this.localeService.init(config.locale);
}
}
}
/**
* Subscrible the locale changed event from view layer.
* For live UI translation update.
*/
subscribeLocaleSubject() {
if (!this.localeSubscription) {
this.localeSubscription = this.localeService.userLocaleChanged
.subscribe(() => { this.loadLocaleData(); });
}
}
/**
* Specifically, for the feature module which will be imported
* to root module or lazy load module. This method should be invoked
* in the constructor of feature module.
* @param config
* @param isMain
*/
registerComponent(config, isMain = false) {
this.subscribeLocaleSubject();
config = VIPConfigFactory(config, this.i18nContext);
this.mainConfig = isMain ? config : this.mainConfig;
this.configs.push(config);
this.updateI18nScope(config);
if (config.sourceBundles || config.sourceBundle) {
if (config.sourceBundle) {
deprecatedWarn('The sourceBundle option in i18n config', 'v10', 'sourceBundles');
}
const bundle = config.sourceBundles ? this.resetBundle(config.sourceBundles) : config.sourceBundle;
this.processBundle(bundle, this.localeService.defaultLocale.languageCode, config);
}
}
/**
* Tentative solution, if translation bundle is mounted.
* no longer to consider i18n scope which defined in
* feature module configuration.
* @param config
*/
updateI18nScope(config) {
if (config.i18nScope && !config.translationBundles) {
this._i18nScope = this._i18nScope.concat(config.i18nScope)
.filter((elem, index, self) => {
return index === self.indexOf(elem);
});
}
}
/**
* If the locale is processed or source locale, skip.
*/
loadLocaleData() {
return __awaiter(this, void 0, void 0, function* () {
const language = this.localeService.getCurrentLanguage();
const region = this.localeService.getCurrentRegion();
const locale = this.localeService.getCurrentLocale();
if (!this.localeService.isSourceLocale &&
this.availableLocales.indexOf(locale) === -1
&& this.i18nContext.i18nEnabled !== false) {
yield this.getLocaleData(language, region, locale)
.toPromise();
}
this.releaseLocale(locale);
});
}
getLocaleData(language, region, locale) {
const sequencesOfRequest = [];
let loadingLocaleData;
for (const config of this.configs) {
// Bypass sending HTTP call to get translation.
// Using local bundle instead.
// Using language to map local bundle.
// Using locale to store the translation.
if (config.translationBundles) {
const standardLanguageTag = this.localeService.normalizeLanguageCode(language);
const bundle = config.translationBundles[language] || config.translationBundles[standardLanguageTag];
if (bundle) {
this.processBundle(bundle, locale, config);
}
}
else {
sequencesOfRequest.push(this.currentLoader
.getLocaleData(config, language, region)
.pipe(share(), catchError((err) => {
console.error(`Can't fetch locale data.`, config, err);
return of(undefined);
})));
}
}
// No HTTP call required.
// Resource of current locale is available.
if (sequencesOfRequest.length < 1) {
this.availableLocales.push(locale);
return of([]);
}
loadingLocaleData = forkJoin(sequencesOfRequest);
this.loadingLocaleData = {
data: loadingLocaleData.pipe(take(1), share()), locale: locale
};
// FIFO
this.pending = true;
this.loadingLocaleData.data.subscribe((res) => {
this.storeResource(res, this._localeData, locale);
this.availableLocales.push(locale);
this.pending = false;
}, (err) => {
this.pending = false;
});
return loadingLocaleData;
}
resetBundle(sourceBundles) {
if (Array.isArray(sourceBundles)) {
return assign({}, sourceBundles);
}
return undefined;
}
processBundle(bundle, locale, config) {
const formattedBundle = { 'messages': {} };
const namespace = getNameSpace(config);
formattedBundle.messages[namespace] = bundle;
this.storeResource([formattedBundle], this._localeData, locale);
}
storeResource(res, localedata, locale) {
if (res) {
const supplemental = {};
localedata[locale] = localedata[locale] || {};
res.forEach((element) => {
if (element) {
if (element.messages) {
localedata[locale].messages =
mergeObject(localedata[locale].messages, element.messages);
}
if (element.categories) {
localedata[locale].categories =
mergeObject(localedata[locale].categories, element.categories);
if (element.categories.supplemental) {
Object.assign(supplemental, element.categories.supplemental);
}
}
}
});
if (localedata[locale].categories) {
localedata[locale].categories.supplemental = supplemental;
}
}
}
/**
* current represents current available locale to cover the initial status.
* since in some situation, the 'onLocaleChange' haven't be register always,
* or there is no event at time.
*/
get current() {
if (this.pending) {
const locale = this.loadingLocaleData.locale;
return Observable.create((observer) => {
const onComplete = () => {
observer.next(locale);
observer.complete();
};
this.loadingLocaleData.data.subscribe((res) => {
onComplete();
}, onComplete);
});
}
else {
return of(this.localeService.getCurrentLocale());
}
}
/**
* stream of 'available' locale.
*/
get stream() {
return concat(this.current, this.onLocaleChange.pipe(switchMap((locale) => {
return of(locale);
})));
}
releaseLocale(locale) {
this.onLocaleChange.emit(locale);
}
registerSourceBundles(sourceBundles, config) {
if (sourceBundles) {
const bundle = this.resetBundle(sourceBundles);
this.processBundle(bundle, this.localeService.defaultLocale.languageCode, config);
}
}
}
VIPService.decorators = [
{ type: Injectable }
];
VIPService.ctorParameters = () => [
{ type: LocaleService },
{ type: I18nContext },
{ type: I18nLoader }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlwLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiL2hvbWUvcmxpZ2VuZy9Qcm9qZWN0cy9EZXZvcHMvQ2xpZW50X0FuZ3VsYXJfR2l0SHViX05wbWpzL3ZpcC9jaS9wdWIyb3JnL0NsaWVudF9Bbmd1bGFyX0dpdEh1Yl9OcG1qcy9zaW5nbGV0b24vcHJvamVjdHMvYW5ndWxhci1jbGllbnQvIiwic291cmNlcyI6WyJzcmMvc2VydmljZXMvdmlwLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRztBQUNILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN2QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDOUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFZLEVBQUUsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDaEYsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BFLE9BQU8sRUFBYSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFdEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBYTdDLE1BQU0sT0FBTyxVQUFVO0lBV25CLFlBQ2MsYUFBNEIsRUFDNUIsV0FBd0IsRUFDM0IsYUFBeUI7UUFGdEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDM0Isa0JBQWEsR0FBYixhQUFhLENBQVk7UUFaNUIsWUFBTyxHQUFHLEtBQUssQ0FB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QUksYUFBYSxFQUFFO1lBQ2YsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQzlEO0lBQ0wsQ0FBQzs7O1lBcFFKLFVBQVU7OztZQW5CRixhQUFhO1lBT2IsV0FBVztZQU5YLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMTktMjAyMSBWTXdhcmUsIEluYy5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wXG4gKi9cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTG9jYWxlU2VydmljZSB9IGZyb20gJy4vbG9jYWxlLnNlcnZpY2UnO1xuaW1wb3J0IHsgSTE4bkxvYWRlciB9IGZyb20gJy4uL2xvYWRlcic7XG5pbXBvcnQgeyBtZXJnZU9iamVjdCwgYXNzaWduLCBkZXByZWNhdGVkV2FybiB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHsgY29uY2F0LCBPYnNlcnZhYmxlLCBmb3JrSm9pbiwgT2JzZXJ2ZXIsIG9mLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHNoYXJlLCBzd2l0Y2hNYXAsIHRha2UsIGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBWSVBDb25maWcsIGdldE5hbWVTcGFjZSwgVklQQ29uZmlnRmFjdG9yeSB9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBzb3VyY2VCdW5kbGVPYmplY3QgfSBmcm9tICcuL2wxMG4uc2VydmljZSc7XG5pbXBvcnQgeyBJMThuQ29udGV4dCB9IGZyb20gJy4vaTE4bi5jb250ZXh0JztcblxuZXhwb3J0IGludGVyZmFjZSBMb2NhbGVEYXRhIHtcbiAgICBjYXRlZ29yaWVzOiBPYmplY3Q7XG4gICAgbWVzc2FnZXM6IHsgW2tleTogc3RyaW5nXTogYW55IH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZGluZ0xvY2FsZURhdGEge1xuICAgIGxvY2FsZTogc3RyaW5nO1xuICAgIGRhdGE6IE9ic2VydmFibGU8YW55Pjtcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFZJUFNlcnZpY2Uge1xuICAgIHB1YmxpYyBtYWluQ29uZmlnOiBWSVBDb25maWc7XG4gICAgcHJpdmF0ZSBwZW5kaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBsb2FkaW5nTG9jYWxlRGF0YTogTG9hZGluZ0xvY2FsZURhdGE7XG4gICAgcHJpdmF0ZSBjb25maWdzOiBWSVBDb25maWdbXSA9IFtdO1xuICAgIHByaXZhdGUgYXZhaWxhYmxlTG9jYWxlczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuICAgIHByaXZhdGUgbG9jYWxlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBfb25Mb2NhbGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gICAgcHJpdmF0ZSBfaTE4blNjb3BlOiBBcnJheTxzdHJpbmc+ID0gW107XG4gICAgcHJpdmF0ZSBfbG9jYWxlRGF0YTogYW55ID0ge307XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIGxvY2FsZVNlcnZpY2U6IExvY2FsZVNlcnZpY2UsXG4gICAgICAgIHByb3RlY3RlZCBpMThuQ29udGV4dDogSTE4bkNvbnRleHQsXG4gICAgICAgIHB1YmxpYyBjdXJyZW50TG9hZGVyOiBJMThuTG9hZGVyXG4gICAgKSB7IH1cblxuICAgIGdldCBvbkxvY2FsZUNoYW5nZSgpOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vbkxvY2FsZUNoYW5nZTtcbiAgICB9XG5cbiAgICBnZXQgbG9jYWxlRGF0YSgpOiBhbnkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlRGF0YTtcbiAgICB9XG5cbiAgICBnZXQgaTE4blNjb3BlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faTE4blNjb3BlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvYWRpbmcgdGhlIGkxOG4gZGF0YSBhdCBhcHAgbW9kdWxlIG9yIHJvb3Qgb2YgbGF6eSBtb2R1bGUuXG4gICAgICogQHBhcmFtIGNvbmZpZyBGb3Igcm9vdCBtb2R1bGUgb3IgbGF6eSBsb2FkIG1kdWxlLlxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBpbml0RGF0YShjb25maWc6IFZJUENvbmZpZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlTG9jYWxlU3ViamVjdCgpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyQ29tcG9uZW50KGNvbmZpZywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuaW5pdExvY2FsZShjb25maWcpO1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRMb2NhbGVEYXRhKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdCBsb2NhbGUgYnkgY29uZmlnIHBhc3NlZCBmcm9tIHJvb3QgbW9kdWxlIGZvciBjb21wYXRpYmlsaXR5LlxuICAgICAqIFdpbGwgYmUgcmVtb3ZlZCBpbiB2OS5cbiAgICAgKiBAcGFyYW0gY29uZmlnXG4gICAgICovXG4gICAgcHJpdmF0ZSBpbml0TG9jYWxlKGNvbmZpZzogVklQQ29uZmlnKSB7XG4gICAgICAgIGlmICggY29uZmlnLmxvY2FsZSB8fCBjb25maWcubGFuZ3VhZ2UgfHwgY29uZmlnLnJlZ2lvbiApIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAnU2V0IGxhbmd1YWdlIGFuZCByZWdpb24gYnkgY29uZmlndXJhdGlvbiBpcyBkZXByZWNhdGVkLCB3aWxsIGJlIHJlbW92ZWQgaW4gdjkuICcgK1xuICAgICAgICAgICAgICAgICdQbGVhc2UgdXNlIExvY2FsZVNlcnZpY2UuaW5pdCBpbnN0ZWFkLicpO1xuICAgICAgICAgICAgaWYgKCBjb25maWcubGFuZ3VhZ2UgJiYgY29uZmlnLnJlZ2lvbiApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZVNlcnZpY2UuaW5pdChjb25maWcubGFuZ3VhZ2UsIGNvbmZpZy5yZWdpb24pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb25maWcubG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2NhbGVTZXJ2aWNlLmluaXQoY29uZmlnLmxvY2FsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJsZSB0aGUgbG9jYWxlIGNoYW5nZWQgZXZlbnQgZnJvbSB2aWV3IGxheWVyLlxuICAgICAqIEZvciBsaXZlIFVJIHRyYW5zbGF0aW9uIHVwZGF0ZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3Vic2NyaWJlTG9jYWxlU3ViamVjdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmxvY2FsZVN1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhpcy5sb2NhbGVTdWJzY3JpcHRpb24gPSB0aGlzLmxvY2FsZVNlcnZpY2UudXNlckxvY2FsZUNoYW5nZWRcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHsgdGhpcy5sb2FkTG9jYWxlRGF0YSgpOyB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNwZWNpZmljYWxseSwgZm9yIHRoZSBmZWF0dXJlIG1vZHVsZSB3aGljaCB3aWxsIGJlIGltcG9ydGVkXG4gICAgICogdG8gcm9vdCBtb2R1bGUgb3IgbGF6eSBsb2FkIG1vZHVsZS4gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGludm9rZWRcbiAgICAgKiBpbiB0aGUgY29uc3RydWN0b3Igb2YgZmVhdHVyZSBtb2R1bGUuXG4gICAgICogQHBhcmFtIGNvbmZpZ1xuICAgICAqIEBwYXJhbSBpc01haW5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVnaXN0ZXJDb21wb25lbnQoY29uZmlnOiBWSVBDb25maWcsIGlzTWFpbjogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlTG9jYWxlU3ViamVjdCgpO1xuICAgICAgICBjb25maWcgPSBWSVBDb25maWdGYWN0b3J5KGNvbmZpZywgdGhpcy5pMThuQ29udGV4dCk7XG4gICAgICAgIHRoaXMubWFpbkNvbmZpZyA9IGlzTWFpbiA/IGNvbmZpZyA6IHRoaXMubWFpbkNvbmZpZztcbiAgICAgICAgdGhpcy5jb25maWdzLnB1c2goY29uZmlnKTtcbiAgICAgICAgdGhpcy51cGRhdGVJMThuU2NvcGUoY29uZmlnKTtcbiAgICAgICAgaWYgKGNvbmZpZy5zb3VyY2VCdW5kbGVzIHx8IGNvbmZpZy5zb3VyY2VCdW5kbGUpIHtcbiAgICAgICAgICAgIGlmIChjb25maWcuc291cmNlQnVuZGxlKSB7XG4gICAgICAgICAgICAgICAgZGVwcmVjYXRlZFdhcm4oJ1RoZSBzb3VyY2VCdW5kbGUgb3B0aW9uIGluIGkxOG4gY29uZmlnJywgJ3YxMCcsICdzb3VyY2VCdW5kbGVzJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGJ1bmRsZSA9IGNvbmZpZy5zb3VyY2VCdW5kbGVzID8gdGhpcy5yZXNldEJ1bmRsZShjb25maWcuc291cmNlQnVuZGxlcykgOiBjb25maWcuc291cmNlQnVuZGxlO1xuICAgICAgICAgICAgdGhpcy5wcm9jZXNzQnVuZGxlKGJ1bmRsZSxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZVNlcnZpY2UuZGVmYXVsdExvY2FsZS5sYW5ndWFnZUNvZGUsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUZW50YXRpdmUgc29sdXRpb24sIGlmIHRyYW5zbGF0aW9uIGJ1bmRsZSBpcyBtb3VudGVkLlxuICAgICAqIG5vIGxvbmdlciB0byBjb25zaWRlciBpMThuIHNjb3BlIHdoaWNoIGRlZmluZWQgaW5cbiAgICAgKiBmZWF0dXJlIG1vZHVsZSBjb25maWd1cmF0aW9uLlxuICAgICAqIEBwYXJhbSBjb25maWdcbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZUkxOG5TY29wZShjb25maWc6IFZJUENvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLmkxOG5TY29wZSAmJiAhY29uZmlnLnRyYW5zbGF0aW9uQnVuZGxlcykge1xuICAgICAgICAgICAgdGhpcy5faTE4blNjb3BlID0gdGhpcy5faTE4blNjb3BlLmNvbmNhdChjb25maWcuaTE4blNjb3BlKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoIChlbGVtLCBpbmRleCwgc2VsZikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXggPT09IHNlbGYuaW5kZXhPZihlbGVtKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElmIHRoZSBsb2NhbGUgaXMgcHJvY2Vzc2VkIG9yIHNvdXJjZSBsb2NhbGUsIHNraXAuXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIGxvYWRMb2NhbGVEYXRhKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIGNvbnN0IGxhbmd1YWdlID0gdGhpcy5sb2NhbGVTZXJ2aWNlLmdldEN1cnJlbnRMYW5ndWFnZSgpO1xuICAgICAgICBjb25zdCByZWdpb24gPSB0aGlzLmxvY2FsZVNlcnZpY2UuZ2V0Q3VycmVudFJlZ2lvbigpO1xuICAgICAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmxvY2FsZVNlcnZpY2UuZ2V0Q3VycmVudExvY2FsZSgpO1xuICAgICAgICBpZiAoIXRoaXMubG9jYWxlU2VydmljZS5pc1NvdXJjZUxvY2FsZSAmJlxuICAgICAgICAgICAgdGhpcy5hdmFpbGFibGVMb2NhbGVzLmluZGV4T2YobG9jYWxlKSA9PT0gLTFcbiAgICAgICAgICAgICYmIHRoaXMuaTE4bkNvbnRleHQuaTE4bkVuYWJsZWQgIT09IGZhbHNlXG4gICAgICAgICkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRMb2NhbGVEYXRhKGxhbmd1YWdlLCByZWdpb24sIGxvY2FsZSlcbiAgICAgICAgICAgICAgICAudG9Qcm9taXNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWxlYXNlTG9jYWxlKGxvY2FsZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRMb2NhbGVEYXRhKGxhbmd1YWdlOiBzdHJpbmcsIHJlZ2lvbjogc3RyaW5nLCBsb2NhbGU6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIGNvbnN0IHNlcXVlbmNlc09mUmVxdWVzdDogQXJyYXk8T2JzZXJ2YWJsZTxhbnk+PiA9IFtdO1xuICAgICAgICBsZXQgbG9hZGluZ0xvY2FsZURhdGE6IE9ic2VydmFibGU8YW55PjtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICAvLyBCeXBhc3Mgc2VuZGluZyBIVFRQIGNhbGwgdG8gZ2V0IHRyYW5zbGF0aW9uLlxuICAgICAgICAgICAgLy8gVXNpbmcgbG9jYWwgYnVuZGxlIGluc3RlYWQuXG4gICAgICAgICAgICAvLyBVc2luZyBsYW5ndWFnZSB0byBtYXAgbG9jYWwgYnVuZGxlLlxuICAgICAgICAgICAgLy8gVXNpbmcgbG9jYWxlIHRvIHN0b3JlIHRoZSB0cmFuc2xhdGlvbi5cbiAgICAgICAgICAgIGlmIChjb25maWcudHJhbnNsYXRpb25CdW5kbGVzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhbmRhcmRMYW5ndWFnZVRhZyA9IHRoaXMubG9jYWxlU2VydmljZS5ub3JtYWxpemVMYW5ndWFnZUNvZGUobGFuZ3VhZ2UpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1bmRsZSA9IGNvbmZpZy50cmFuc2xhdGlvbkJ1bmRsZXNbbGFuZ3VhZ2VdIHx8IGNvbmZpZy50cmFuc2xhdGlvbkJ1bmRsZXNbc3RhbmRhcmRMYW5ndWFnZVRhZ107XG4gICAgICAgICAgICAgICAgaWYgKGJ1bmRsZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NCdW5kbGUoYnVuZGxlLCBsb2NhbGUsIGNvbmZpZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXF1ZW5jZXNPZlJlcXVlc3QucHVzaCh0aGlzLmN1cnJlbnRMb2FkZXJcbiAgICAgICAgICAgICAgICAgICAgLmdldExvY2FsZURhdGEoY29uZmlnLCBsYW5ndWFnZSwgcmVnaW9uKVxuICAgICAgICAgICAgICAgICAgICAucGlwZShzaGFyZSgpLCBjYXRjaEVycm9yKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENhbid0IGZldGNoIGxvY2FsZSBkYXRhLmAsIGNvbmZpZywgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICB9KSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm8gSFRUUCBjYWxsIHJlcXVpcmVkLlxuICAgICAgICAvLyBSZXNvdXJjZSBvZiBjdXJyZW50IGxvY2FsZSBpcyBhdmFpbGFibGUuXG4gICAgICAgIGlmIChzZXF1ZW5jZXNPZlJlcXVlc3QubGVuZ3RoIDwgMSkge1xuICAgICAgICAgICAgdGhpcy5hdmFpbGFibGVMb2NhbGVzLnB1c2gobG9jYWxlKTtcbiAgICAgICAgICAgIHJldHVybiBvZihbXSk7XG4gICAgICAgIH1cblxuICAgICAgICBsb2FkaW5nTG9jYWxlRGF0YSA9IGZvcmtKb2luKHNlcXVlbmNlc09mUmVxdWVzdCk7XG4gICAgICAgIHRoaXMubG9hZGluZ0xvY2FsZURhdGEgPSB7XG4gICAgICAgICAgICBkYXRhOiBsb2FkaW5nTG9jYWxlRGF0YS5waXBlKFxuICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgc2hhcmUoKVxuICAgICAgICAgICAgKSwgbG9jYWxlOiBsb2NhbGVcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBGSUZPXG4gICAgICAgIHRoaXMucGVuZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubG9hZGluZ0xvY2FsZURhdGEuZGF0YS5zdWJzY3JpYmUoKHJlczogTG9jYWxlRGF0YSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdG9yZVJlc291cmNlKHJlcywgdGhpcy5fbG9jYWxlRGF0YSwgbG9jYWxlKTtcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmxlTG9jYWxlcy5wdXNoKGxvY2FsZSk7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgfSwgKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBsb2FkaW5nTG9jYWxlRGF0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlc2V0QnVuZGxlKHNvdXJjZUJ1bmRsZXM6IGFueSkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2VCdW5kbGVzKSkge1xuICAgICAgICAgICAgcmV0dXJuIGFzc2lnbih7fSwgc291cmNlQnVuZGxlcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NCdW5kbGUoYnVuZGxlOiBhbnksIGxvY2FsZTogc3RyaW5nLCBjb25maWc6IFZJUENvbmZpZykge1xuICAgICAgICBjb25zdCBmb3JtYXR0ZWRCdW5kbGUgPSB7ICdtZXNzYWdlcyc6IHt9IH07XG4gICAgICAgIGNvbnN0IG5hbWVzcGFjZSA9IGdldE5hbWVTcGFjZShjb25maWcpO1xuICAgICAgICAoZm9ybWF0dGVkQnVuZGxlLm1lc3NhZ2VzIGFzIGFueSlbbmFtZXNwYWNlXSA9IGJ1bmRsZTtcbiAgICAgICAgdGhpcy5zdG9yZVJlc291cmNlKFtmb3JtYXR0ZWRCdW5kbGVdLFxuICAgICAgICAgICAgdGhpcy5fbG9jYWxlRGF0YSwgbG9jYWxlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3JlUmVzb3VyY2UocmVzOiBhbnksIGxvY2FsZWRhdGE6IGFueSwgbG9jYWxlOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgY29uc3Qgc3VwcGxlbWVudGFsOiBPYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGxvY2FsZWRhdGFbbG9jYWxlXSA9IGxvY2FsZWRhdGFbbG9jYWxlXSB8fCB7fTtcbiAgICAgICAgICAgIHJlcy5mb3JFYWNoKChlbGVtZW50OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5tZXNzYWdlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlZGF0YVtsb2NhbGVdLm1lc3NhZ2VzID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZU9iamVjdChsb2NhbGVkYXRhW2xvY2FsZV0ubWVzc2FnZXMsIGVsZW1lbnQubWVzc2FnZXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmNhdGVnb3JpZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZWRhdGFbbG9jYWxlXS5jYXRlZ29yaWVzID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZU9iamVjdChsb2NhbGVkYXRhW2xvY2FsZV0uY2F0ZWdvcmllcywgZWxlbWVudC5jYXRlZ29yaWVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmNhdGVnb3JpZXMuc3VwcGxlbWVudGFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzdXBwbGVtZW50YWwsIGVsZW1lbnQuY2F0ZWdvcmllcy5zdXBwbGVtZW50YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAobG9jYWxlZGF0YVtsb2NhbGVdLmNhdGVnb3JpZXMpIHtcbiAgICAgICAgICAgICAgICBsb2NhbGVkYXRhW2xvY2FsZV0uY2F0ZWdvcmllcy5zdXBwbGVtZW50YWwgPSBzdXBwbGVtZW50YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBjdXJyZW50IHJlcHJlc2VudHMgY3VycmVudCBhdmFpbGFibGUgbG9jYWxlIHRvIGNvdmVyIHRoZSBpbml0aWFsIHN0YXR1cy5cbiAgICAgKiBzaW5jZSBpbiBzb21lIHNpdHVhdGlvbiwgdGhlICdvbkxvY2FsZUNoYW5nZScgaGF2ZW4ndCBiZSByZWdpc3RlciBhbHdheXMsXG4gICAgICogb3IgdGhlcmUgaXMgbm8gZXZlbnQgYXQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgY3VycmVudCgpOiBPYnNlcnZhYmxlPHN0cmluZyB8IGFueT4ge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nKSB7XG4gICAgICAgICAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmxvYWRpbmdMb2NhbGVEYXRhLmxvY2FsZTtcbiAgICAgICAgICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZSgob2JzZXJ2ZXI6IE9ic2VydmVyPHN0cmluZz4pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbkNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGxvY2FsZSk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmdMb2NhbGVEYXRhLmRhdGEuc3Vic2NyaWJlKChyZXM6IExvY2FsZURhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgIH0sIG9uQ29tcGxldGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy5sb2NhbGVTZXJ2aWNlLmdldEN1cnJlbnRMb2NhbGUoKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBzdHJlYW0gb2YgJ2F2YWlsYWJsZScgbG9jYWxlLlxuICAgICAqL1xuICAgIGdldCBzdHJlYW0oKTogT2JzZXJ2YWJsZTxzdHJpbmcgfCBhbnk+IHtcbiAgICAgICAgcmV0dXJuIGNvbmNhdChcbiAgICAgICAgICAgIHRoaXMuY3VycmVudCxcbiAgICAgICAgICAgIHRoaXMub25Mb2NhbGVDaGFuZ2UucGlwZShcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKGxvY2FsZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihsb2NhbGUpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbGVhc2VMb2NhbGUobG9jYWxlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5vbkxvY2FsZUNoYW5nZS5lbWl0KGxvY2FsZSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZ2lzdGVyU291cmNlQnVuZGxlcyhzb3VyY2VCdW5kbGVzOiBzb3VyY2VCdW5kbGVPYmplY3RbXSwgY29uZmlnOiBWSVBDb25maWcpIHtcbiAgICAgICAgaWYgKHNvdXJjZUJ1bmRsZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1bmRsZSA9IHRoaXMucmVzZXRCdW5kbGUoc291cmNlQnVuZGxlcyk7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NCdW5kbGUoYnVuZGxlLFxuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlU2VydmljZS5kZWZhdWx0TG9jYWxlLmxhbmd1YWdlQ29kZSwgY29uZmlnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==