angular-l10n
Version:
Angular library to translate texts, dates and numbers
200 lines • 26.8 kB
JavaScript
import { Injectable, Inject } from '@angular/core';
import { BehaviorSubject, merge, concat } from 'rxjs';
import { L10N_CONFIG, L10N_LOCALE } from '../models/l10n-config';
import { formatLanguage, getSchema, getValue, mergeDeep } from '../models/utils';
import * as i0 from "@angular/core";
import * as i1 from "./l10n-cache";
import * as i2 from "./l10n-storage";
import * as i3 from "./l10n-locale-resolver";
import * as i4 from "./l10n-translation-fallback";
import * as i5 from "./l10n-translation-loader";
import * as i6 from "./l10n-translation-handler";
import * as i7 from "./l10n-missing-translation-handler";
export class L10nTranslationService {
constructor(config, locale, cache, storage, resolveLocale, translationFallback, translationLoader, translationHandler, missingTranslationHandler) {
this.config = config;
this.locale = locale;
this.cache = cache;
this.storage = storage;
this.resolveLocale = resolveLocale;
this.translationFallback = translationFallback;
this.translationLoader = translationLoader;
this.translationHandler = translationHandler;
this.missingTranslationHandler = missingTranslationHandler;
/**
* The translation data: {language: {key: value}}
*/
this.data = {};
this.translation = new BehaviorSubject(this.locale);
this.error = new BehaviorSubject(null);
}
/**
* Gets the current locale.
*/
getLocale() {
return this.locale;
}
/**
* Changes the current locale and load the translation data.
* @param locale The new locale
*/
async setLocale(locale) {
await this.loadTranslations(this.config.providers, locale);
}
/**
* Fired every time the translation data has been loaded. Returns the locale.
*/
onChange() {
return this.translation.asObservable();
}
/**
* Fired when the translation data could not been loaded. Returns the error.
*/
onError() {
return this.error.asObservable();
}
/**
* Translates a key or an array of keys.
* @param keys The key or an array of keys to be translated
* @param params Optional parameters contained in the key
* @param language The current language
* @return The translated value or an object: {key: value}
*/
translate(keys, params, language = this.locale.language) {
language = formatLanguage(language, this.config.format);
if (Array.isArray(keys)) {
const data = {};
for (const key of keys) {
data[key] = this.translate(key, params, language);
}
return data;
}
const value = getValue(keys, this.data[language], this.config.keySeparator);
return value ? this.translationHandler.parseValue(keys, params, value) : this.missingTranslationHandler.handle(keys, value, params);
}
/**
* Checks if a translation exists.
* @param key The key to be tested
* @param language The current language
*/
has(key, language = this.locale.language) {
language = formatLanguage(language, this.config.format);
return getValue(key, this.data[language], this.config.keySeparator) !== null;
}
/**
* Gets the language direction.
*/
getLanguageDirection(language = this.locale.language) {
const schema = getSchema(this.config.schema, language, this.config.format);
return schema ? schema.dir : undefined;
}
/**
* Gets available languages.
*/
getAvailableLanguages() {
const languages = this.config.schema.map(item => formatLanguage(item.locale.language, this.config.format));
return languages;
}
/**
* Initializes the service
* @param providers An array of L10nProvider
*/
async init(providers = this.config.providers) {
let locale = null;
// Tries to get locale from storage.
if (locale == null) {
locale = await this.storage.read();
}
// Tries resolved locale.
if (locale == null) {
locale = await this.resolveLocale.get();
}
// Uses default locale.
if (locale == null) {
locale = this.config.defaultLocale;
}
// Loads translation data.
await this.loadTranslations(providers, locale);
}
/**
* Can be called at every translation change.
* @param providers An array of L10nProvider
* @param locale The current locale
*/
async loadTranslations(providers = this.config.providers, locale = this.locale) {
const language = formatLanguage(locale.language, this.config.format);
return new Promise((resolve) => {
concat(...this.getTranslation(providers, language)).subscribe({
next: (data) => this.addData(data, language),
error: (error) => {
this.handleError(error);
resolve();
},
complete: () => {
this.releaseTranslation(locale);
resolve();
}
});
});
}
/**
* Can be called to add translation data.
* @param data The translation data {key: value}
* @param language The language to add data
*/
addData(data, language) {
this.data[language] = this.data[language] !== undefined
? mergeDeep(this.data[language], data)
: data;
}
/**
* Adds providers to configuration
* @param providers The providers of the translations data
*/
addProviders(providers) {
providers.forEach(provider => {
if (!this.config.providers.find(p => p.name === provider.name)) {
this.config.providers.push(provider);
}
});
}
getTranslation(providers, language) {
const lazyLoaders = [];
let loaders = [];
for (const provider of providers) {
if (this.config.fallback) {
loaders = loaders.concat(this.translationFallback.get(language, provider));
}
else {
if (this.config.cache) {
lazyLoaders.push(this.cache.read(`${provider.name}-${language}`, this.translationLoader.get(language, provider)));
}
else {
lazyLoaders.push(this.translationLoader.get(language, provider));
}
}
}
loaders.push(merge(...lazyLoaders));
return loaders;
}
handleError(error) {
this.error.next(error);
}
releaseTranslation(locale) {
Object.assign(this.locale, locale);
this.translation.next(this.locale);
this.storage.write(this.locale);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: L10nTranslationService, deps: [{ token: L10N_CONFIG }, { token: L10N_LOCALE }, { token: i1.L10nCache }, { token: i2.L10nStorage }, { token: i3.L10nLocaleResolver }, { token: i4.L10nTranslationFallback }, { token: i5.L10nTranslationLoader }, { token: i6.L10nTranslationHandler }, { token: i7.L10nMissingTranslationHandler }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: L10nTranslationService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: L10nTranslationService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [L10N_CONFIG]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [L10N_LOCALE]
}] }, { type: i1.L10nCache }, { type: i2.L10nStorage }, { type: i3.L10nLocaleResolver }, { type: i4.L10nTranslationFallback }, { type: i5.L10nTranslationLoader }, { type: i6.L10nTranslationHandler }, { type: i7.L10nMissingTranslationHandler }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDEwbi10cmFuc2xhdGlvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1sMTBuL3NyYy9saWIvc2VydmljZXMvbDEwbi10cmFuc2xhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBYyxlQUFlLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUdsRSxPQUFPLEVBQUUsV0FBVyxFQUFjLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7Ozs7O0FBU25FLE1BQU0sT0FBTyxzQkFBc0I7SUFXN0MsWUFDaUMsTUFBa0IsRUFDbEIsTUFBa0IsRUFDdkMsS0FBZ0IsRUFDaEIsT0FBb0IsRUFDcEIsYUFBaUMsRUFDakMsbUJBQTRDLEVBQzVDLGlCQUF3QyxFQUN4QyxrQkFBMEMsRUFDMUMseUJBQXdEO1FBUm5DLFdBQU0sR0FBTixNQUFNLENBQVk7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBWTtRQUN2QyxVQUFLLEdBQUwsS0FBSyxDQUFXO1FBQ2hCLFlBQU8sR0FBUCxPQUFPLENBQWE7UUFDcEIsa0JBQWEsR0FBYixhQUFhLENBQW9CO1FBQ2pDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBeUI7UUFDNUMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUF1QjtRQUN4Qyx1QkFBa0IsR0FBbEIsa0JBQWtCLENBQXdCO1FBQzFDLDhCQUF5QixHQUF6Qix5QkFBeUIsQ0FBK0I7UUFsQnBFOztXQUVHO1FBQ0ksU0FBSSxHQUEyQixFQUFFLENBQUM7UUFFakMsZ0JBQVcsR0FBRyxJQUFJLGVBQWUsQ0FB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Q0FBQztJQUNwQyxDQUFDOzhHQTlNc0Isc0JBQXNCLGtCQVlqQyxXQUFXLGFBQ1gsV0FBVztrSEFiQSxzQkFBc0I7OzJGQUF0QixzQkFBc0I7a0JBQWhELFVBQVU7OzBCQVlGLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0LCBtZXJnZSwgY29uY2F0IH0gZnJvbSAncnhqcyc7XHJcblxyXG5pbXBvcnQgeyBMMTBuTG9jYWxlLCBMMTBuUHJvdmlkZXIgfSBmcm9tICcuLi9tb2RlbHMvdHlwZXMnO1xyXG5pbXBvcnQgeyBMMTBOX0NPTkZJRywgTDEwbkNvbmZpZywgTDEwTl9MT0NBTEUgfSBmcm9tICcuLi9tb2RlbHMvbDEwbi1jb25maWcnO1xyXG5pbXBvcnQgeyBmb3JtYXRMYW5ndWFnZSwgZ2V0U2NoZW1hLCBnZXRWYWx1ZSwgbWVyZ2VEZWVwIH0gZnJvbSAnLi4vbW9kZWxzL3V0aWxzJztcclxuaW1wb3J0IHsgTDEwbkNhY2hlIH0gZnJvbSAnLi9sMTBuLWNhY2hlJztcclxuaW1wb3J0IHsgTDEwblN0b3JhZ2UgfSBmcm9tICcuL2wxMG4tc3RvcmFnZSc7XHJcbmltcG9ydCB7IEwxMG5Mb2NhbGVSZXNvbHZlciB9IGZyb20gJy4vbDEwbi1sb2NhbGUtcmVzb2x2ZXInO1xyXG5pbXBvcnQgeyBMMTBuVHJhbnNsYXRpb25GYWxsYmFjayB9IGZyb20gJy4vbDEwbi10cmFuc2xhdGlvbi1mYWxsYmFjayc7XHJcbmltcG9ydCB7IEwxMG5UcmFuc2xhdGlvbkxvYWRlciB9IGZyb20gJy4vbDEwbi10cmFuc2xhdGlvbi1sb2FkZXInO1xyXG5pbXBvcnQgeyBMMTBuVHJhbnNsYXRpb25IYW5kbGVyIH0gZnJvbSAnLi9sMTBuLXRyYW5zbGF0aW9uLWhhbmRsZXInO1xyXG5pbXBvcnQgeyBMMTBuTWlzc2luZ1RyYW5zbGF0aW9uSGFuZGxlciB9IGZyb20gJy4vbDEwbi1taXNzaW5nLXRyYW5zbGF0aW9uLWhhbmRsZXInO1xyXG5cclxuQEluamVjdGFibGUoKSBleHBvcnQgY2xhc3MgTDEwblRyYW5zbGF0aW9uU2VydmljZSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdHJhbnNsYXRpb24gZGF0YToge2xhbmd1YWdlOiB7a2V5OiB2YWx1ZX19XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkYXRhOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcblxyXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGlvbiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8TDEwbkxvY2FsZT4odGhpcy5sb2NhbGUpO1xyXG5cclxuICAgIHByaXZhdGUgZXJyb3IgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgQEluamVjdChMMTBOX0NPTkZJRykgcHJpdmF0ZSBjb25maWc6IEwxMG5Db25maWcsXHJcbiAgICAgICAgQEluamVjdChMMTBOX0xPQ0FMRSkgcHJpdmF0ZSBsb2NhbGU6IEwxMG5Mb2NhbGUsXHJcbiAgICAgICAgcHJpdmF0ZSBjYWNoZTogTDEwbkNhY2hlLFxyXG4gICAgICAgIHByaXZhdGUgc3RvcmFnZTogTDEwblN0b3JhZ2UsXHJcbiAgICAgICAgcHJpdmF0ZSByZXNvbHZlTG9jYWxlOiBMMTBuTG9jYWxlUmVzb2x2ZXIsXHJcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGlvbkZhbGxiYWNrOiBMMTBuVHJhbnNsYXRpb25GYWxsYmFjayxcclxuICAgICAgICBwcml2YXRlIHRyYW5zbGF0aW9uTG9hZGVyOiBMMTBuVHJhbnNsYXRpb25Mb2FkZXIsXHJcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGlvbkhhbmRsZXI6IEwxMG5UcmFuc2xhdGlvbkhhbmRsZXIsXHJcbiAgICAgICAgcHJpdmF0ZSBtaXNzaW5nVHJhbnNsYXRpb25IYW5kbGVyOiBMMTBuTWlzc2luZ1RyYW5zbGF0aW9uSGFuZGxlclxyXG4gICAgKSB7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGN1cnJlbnQgbG9jYWxlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0TG9jYWxlKCk6IEwxMG5Mb2NhbGUge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoYW5nZXMgdGhlIGN1cnJlbnQgbG9jYWxlIGFuZCBsb2FkIHRoZSB0cmFuc2xhdGlvbiBkYXRhLlxyXG4gICAgICogQHBhcmFtIGxvY2FsZSBUaGUgbmV3IGxvY2FsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXN5bmMgc2V0TG9jYWxlKGxvY2FsZTogTDEwbkxvY2FsZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGF3YWl0IHRoaXMubG9hZFRyYW5zbGF0aW9ucyh0aGlzLmNvbmZpZy5wcm92aWRlcnMsIGxvY2FsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCBldmVyeSB0aW1lIHRoZSB0cmFuc2xhdGlvbiBkYXRhIGhhcyBiZWVuIGxvYWRlZC4gUmV0dXJucyB0aGUgbG9jYWxlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25DaGFuZ2UoKTogT2JzZXJ2YWJsZTxMMTBuTG9jYWxlPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRpb24uYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuIHRoZSB0cmFuc2xhdGlvbiBkYXRhIGNvdWxkIG5vdCBiZWVuIGxvYWRlZC4gUmV0dXJucyB0aGUgZXJyb3IuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkVycm9yKCk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3IuYXNPYnNlcnZhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUcmFuc2xhdGVzIGEga2V5IG9yIGFuIGFycmF5IG9mIGtleXMuXHJcbiAgICAgKiBAcGFyYW0ga2V5cyBUaGUga2V5IG9yIGFuIGFycmF5IG9mIGtleXMgdG8gYmUgdHJhbnNsYXRlZFxyXG4gICAgICogQHBhcmFtIHBhcmFtcyBPcHRpb25hbCBwYXJhbWV0ZXJzIGNvbnRhaW5lZCBpbiB0aGUga2V5XHJcbiAgICAgKiBAcGFyYW0gbGFuZ3VhZ2UgVGhlIGN1cnJlbnQgbGFuZ3VhZ2VcclxuICAgICAqIEByZXR1cm4gVGhlIHRyYW5zbGF0ZWQgdmFsdWUgb3IgYW4gb2JqZWN0OiB7a2V5OiB2YWx1ZX1cclxuICAgICAqL1xyXG4gICAgcHVibGljIHRyYW5zbGF0ZShcclxuICAgICAgICBrZXlzOiBzdHJpbmcgfCBzdHJpbmdbXSxcclxuICAgICAgICBwYXJhbXM/OiBhbnksXHJcbiAgICAgICAgbGFuZ3VhZ2UgPSB0aGlzLmxvY2FsZS5sYW5ndWFnZVxyXG4gICAgKTogc3RyaW5nIHwgYW55IHtcclxuICAgICAgICBsYW5ndWFnZSA9IGZvcm1hdExhbmd1YWdlKGxhbmd1YWdlLCB0aGlzLmNvbmZpZy5mb3JtYXQpO1xyXG5cclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShrZXlzKSkge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcclxuICAgICAgICAgICAgICAgIGRhdGFba2V5XSA9IHRoaXMudHJhbnNsYXRlKGtleSwgcGFyYW1zLCBsYW5ndWFnZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB2YWx1ZSA9IGdldFZhbHVlKGtleXMsIHRoaXMuZGF0YVtsYW5ndWFnZV0sIHRoaXMuY29uZmlnLmtleVNlcGFyYXRvcik7XHJcblxyXG4gICAgICAgIHJldHVybiB2YWx1ZSA/IHRoaXMudHJhbnNsYXRpb25IYW5kbGVyLnBhcnNlVmFsdWUoa2V5cywgcGFyYW1zLCB2YWx1ZSkgOiB0aGlzLm1pc3NpbmdUcmFuc2xhdGlvbkhhbmRsZXIuaGFuZGxlKGtleXMsIHZhbHVlLCBwYXJhbXMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGlmIGEgdHJhbnNsYXRpb24gZXhpc3RzLlxyXG4gICAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIGJlIHRlc3RlZFxyXG4gICAgICogQHBhcmFtIGxhbmd1YWdlIFRoZSBjdXJyZW50IGxhbmd1YWdlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoYXMoa2V5OiBzdHJpbmcsIGxhbmd1YWdlID0gdGhpcy5sb2NhbGUubGFuZ3VhZ2UpOiBib29sZWFuIHtcclxuICAgICAgICBsYW5ndWFnZSA9IGZvcm1hdExhbmd1YWdlKGxhbmd1YWdlLCB0aGlzLmNvbmZpZy5mb3JtYXQpO1xyXG5cclxuICAgICAgICByZXR1cm4gZ2V0VmFsdWUoa2V5LCB0aGlzLmRhdGFbbGFuZ3VhZ2VdLCB0aGlzLmNvbmZpZy5rZXlTZXBhcmF0b3IpICE9PSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbGFuZ3VhZ2UgZGlyZWN0aW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0TGFuZ3VhZ2VEaXJlY3Rpb24obGFuZ3VhZ2UgPSB0aGlzLmxvY2FsZS5sYW5ndWFnZSk6ICdsdHInIHwgJ3J0bCcgfCB1bmRlZmluZWQge1xyXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGdldFNjaGVtYSh0aGlzLmNvbmZpZy5zY2hlbWEsIGxhbmd1YWdlLCB0aGlzLmNvbmZpZy5mb3JtYXQpO1xyXG4gICAgICAgIHJldHVybiBzY2hlbWEgPyBzY2hlbWEuZGlyIDogdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhdmFpbGFibGUgbGFuZ3VhZ2VzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0QXZhaWxhYmxlTGFuZ3VhZ2VzKCk6IHN0cmluZ1tdIHtcclxuICAgICAgICBjb25zdCBsYW5ndWFnZXMgPSB0aGlzLmNvbmZpZy5zY2hlbWEubWFwKGl0ZW0gPT4gZm9ybWF0TGFuZ3VhZ2UoaXRlbS5sb2NhbGUubGFuZ3VhZ2UsIHRoaXMuY29uZmlnLmZvcm1hdCkpO1xyXG4gICAgICAgIHJldHVybiBsYW5ndWFnZXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgc2VydmljZVxyXG4gICAgICogQHBhcmFtIHByb3ZpZGVycyBBbiBhcnJheSBvZiBMMTBuUHJvdmlkZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFzeW5jIGluaXQocHJvdmlkZXJzOiBMMTBuUHJvdmlkZXJbXSA9IHRoaXMuY29uZmlnLnByb3ZpZGVycyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGxldCBsb2NhbGU6IEwxMG5Mb2NhbGUgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgICAgICAgLy8gVHJpZXMgdG8gZ2V0IGxvY2FsZSBmcm9tIHN0b3JhZ2UuXHJcbiAgICAgICAgaWYgKGxvY2FsZSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIGxvY2FsZSA9IGF3YWl0IHRoaXMuc3RvcmFnZS5yZWFkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFRyaWVzIHJlc29sdmVkIGxvY2FsZS5cclxuICAgICAgICBpZiAobG9jYWxlID09IG51bGwpIHtcclxuICAgICAgICAgICAgbG9jYWxlID0gYXdhaXQgdGhpcy5yZXNvbHZlTG9jYWxlLmdldCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBVc2VzIGRlZmF1bHQgbG9jYWxlLlxyXG4gICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBsb2NhbGUgPSB0aGlzLmNvbmZpZy5kZWZhdWx0TG9jYWxlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTG9hZHMgdHJhbnNsYXRpb24gZGF0YS5cclxuICAgICAgICBhd2FpdCB0aGlzLmxvYWRUcmFuc2xhdGlvbnMocHJvdmlkZXJzLCBsb2NhbGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FuIGJlIGNhbGxlZCBhdCBldmVyeSB0cmFuc2xhdGlvbiBjaGFuZ2UuXHJcbiAgICAgKiBAcGFyYW0gcHJvdmlkZXJzIEFuIGFycmF5IG9mIEwxMG5Qcm92aWRlclxyXG4gICAgICogQHBhcmFtIGxvY2FsZSBUaGUgY3VycmVudCBsb2NhbGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFzeW5jIGxvYWRUcmFuc2xhdGlvbnMocHJvdmlkZXJzOiBMMTBuUHJvdmlkZXJbXSA9IHRoaXMuY29uZmlnLnByb3ZpZGVycywgbG9jYWxlID0gdGhpcy5sb2NhbGUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBsYW5ndWFnZSA9IGZvcm1hdExhbmd1YWdlKGxvY2FsZS5sYW5ndWFnZSwgdGhpcy5jb25maWcuZm9ybWF0KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbmNhdCguLi50aGlzLmdldFRyYW5zbGF0aW9uKHByb3ZpZGVycywgbGFuZ3VhZ2UpKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAgICAgbmV4dDogKGRhdGEpID0+IHRoaXMuYWRkRGF0YShkYXRhLCBsYW5ndWFnZSksXHJcbiAgICAgICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVFcnJvcihlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWxlYXNlVHJhbnNsYXRpb24obG9jYWxlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FuIGJlIGNhbGxlZCB0byBhZGQgdHJhbnNsYXRpb24gZGF0YS5cclxuICAgICAqIEBwYXJhbSBkYXRhIFRoZSB0cmFuc2xhdGlvbiBkYXRhIHtrZXk6IHZhbHVlfVxyXG4gICAgICogQHBhcmFtIGxhbmd1YWdlIFRoZSBsYW5ndWFnZSB0byBhZGQgZGF0YVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRkRGF0YShkYXRhOiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBsYW5ndWFnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5kYXRhW2xhbmd1YWdlXSA9IHRoaXMuZGF0YVtsYW5ndWFnZV0gIT09IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICA/IG1lcmdlRGVlcCh0aGlzLmRhdGFbbGFuZ3VhZ2VdLCBkYXRhKVxyXG4gICAgICAgICAgICA6IGRhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIHByb3ZpZGVycyB0byBjb25maWd1cmF0aW9uXHJcbiAgICAgKiBAcGFyYW0gcHJvdmlkZXJzIFRoZSBwcm92aWRlcnMgb2YgdGhlIHRyYW5zbGF0aW9ucyBkYXRhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGRQcm92aWRlcnMocHJvdmlkZXJzOiBMMTBuUHJvdmlkZXJbXSk6IHZvaWQge1xyXG4gICAgICAgIHByb3ZpZGVycy5mb3JFYWNoKHByb3ZpZGVyID0+IHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5wcm92aWRlcnMuZmluZChwID0+IHAubmFtZSA9PT0gcHJvdmlkZXIubmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLnByb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0VHJhbnNsYXRpb24ocHJvdmlkZXJzOiBMMTBuUHJvdmlkZXJbXSwgbGFuZ3VhZ2U6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PltdIHtcclxuICAgICAgICBjb25zdCBsYXp5TG9hZGVyczogT2JzZXJ2YWJsZTxhbnk+W10gPSBbXTtcclxuICAgICAgICBsZXQgbG9hZGVyczogT2JzZXJ2YWJsZTxhbnk+W10gPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBwcm92aWRlciBvZiBwcm92aWRlcnMpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLmZhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICBsb2FkZXJzID0gbG9hZGVycy5jb25jYXQodGhpcy50cmFuc2xhdGlvbkZhbGxiYWNrLmdldChsYW5ndWFnZSwgcHJvdmlkZXIpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5jYWNoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhenlMb2FkZXJzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUucmVhZChgJHtwcm92aWRlci5uYW1lfS0ke2xhbmd1YWdlfWAsIHRoaXMudHJhbnNsYXRpb25Mb2FkZXIuZ2V0KGxhbmd1YWdlLCBwcm92aWRlcikpXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGF6eUxvYWRlcnMucHVzaCh0aGlzLnRyYW5zbGF0aW9uTG9hZGVyLmdldChsYW5ndWFnZSwgcHJvdmlkZXIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBsb2FkZXJzLnB1c2gobWVyZ2UoLi4ubGF6eUxvYWRlcnMpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGxvYWRlcnM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVFcnJvcihlcnJvcjogYW55KTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5lcnJvci5uZXh0KGVycm9yKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlbGVhc2VUcmFuc2xhdGlvbihsb2NhbGU6IEwxMG5Mb2NhbGUpOiB2b2lkIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMubG9jYWxlLCBsb2NhbGUpO1xyXG4gICAgICAgIHRoaXMudHJhbnNsYXRpb24ubmV4dCh0aGlzLmxvY2FsZSk7XHJcbiAgICAgICAgdGhpcy5zdG9yYWdlLndyaXRlKHRoaXMubG9jYWxlKTtcclxuICAgIH1cclxuXHJcbn1cclxuIl19