UNPKG

@ogs-gmbh/ngx-translate

Version:

A lightweight, REST-based Angular i18n library designed for seamless internationalization with minimal setup. It supports dynamic language switching & flexible translation management via RESTful APIs.

207 lines 38.1 kB
import { BehaviorSubject, distinctUntilChanged } from "rxjs"; import { Injectable, inject } from "@angular/core"; import { CollectingStrategies } from "../enums/collecting-strategies.enum"; import { LocaleNotDefinedError } from "../errors/locale-not-defined.error"; import { SourceLocaleNotDefinedError } from "../errors/source-locale-not-defined.error"; import { TRANSLATION_CONFIG_TOKEN } from "../tokens/config.token"; import * as i0 from "@angular/core"; export class TranslationStoreService { _loadedScopes; _notifierScopes = null; _translationConfig = inject(TRANSLATION_CONFIG_TOKEN); _locale; _locale$; _storageAttributes = { collectingStrategy: this._translationConfig.storageConfig?.collectingStrategy ?? CollectingStrategies.CURRENT, locale: { type: this._translationConfig.storageConfig?.locale?.type ?? window.localStorage, key: this._translationConfig.storageConfig?.locale?.key ?? "locale" }, translations: { type: this._translationConfig.storageConfig?.translations?.type ?? window.sessionStorage, key: this._translationConfig.storageConfig?.translations?.key ?? "translations" } }; constructor() { const sourceLocale = this.getSourceLocale(); if (sourceLocale === undefined) throw new SourceLocaleNotDefinedError(); if (this._translationConfig.storageConfig?.locale?.store) { const localeStorageValue = this._getStorageValue("locale"); const localeExists = localeStorageValue ? this._checkIfLocaleExists(localeStorageValue) : false; const isSourceLocale = localeStorageValue ? this._checkIfLocaleIsSourceLocale(localeStorageValue) : false; if (!localeExists || isSourceLocale) this._setStorageValue("locale", null); this._locale = new BehaviorSubject(localeStorageValue ?? sourceLocale); } else this._locale = new BehaviorSubject(sourceLocale); if (this._translationConfig.storageConfig?.translations?.store) { const translationsStorageValue = this._getStorageValue("translations"); this._loadedScopes = translationsStorageValue ?? null; } else this._loadedScopes = null; this._locale$ = this._locale.asObservable(); } getCurrentLocale() { return this._locale.value; } getLocale$() { return this._locale$.pipe(distinctUntilChanged()); } setLocale(locale) { if (!this._checkIfLocaleExists(locale)) throw new LocaleNotDefinedError(locale); if (this._translationConfig.storageConfig?.locale?.store) { this._checkIfLocaleIsSourceLocale(locale) ? this._setStorageValue("locale", null) : this._setStorageValue("locale", locale); } if (this._translationConfig.storageConfig?.translations?.store && this._translationConfig.storageConfig.collectingStrategy === CollectingStrategies.CURRENT) this._setStorageValue("translations", null); this._locale.next(locale); } getLocales() { return this._translationConfig.locales; } setScopedFile(scopeName, file) { const existingScope = scopeName ? this._getScopeByScopeName(scopeName) : undefined; if (existingScope === undefined) this._appendScope(scopeName, file); else existingScope.file = file; if (this._translationConfig.storageConfig?.translations?.store) this._setStorageValue("translations", this._loadedScopes); } getScopedFile(scopeName) { const existingScope = this._getScopeByScopeName(scopeName); return existingScope ? existingScope.file : undefined; } hasScopedFile(scopeName) { const existingScope = this._getScopeByScopeName(scopeName); return Boolean(existingScope); } hasScopedFiles(scopeNames) { const existingScopes = this._getScopeByScopeNames(scopeNames); return Boolean(existingScopes); } isScopeExisting(scopeName) { const existingScope = this._getScopeByScopeName(scopeName); return existingScope !== undefined; } getExistingScopes(scopeNames) { return scopeNames.filter((scopeName) => this.isScopeExisting(scopeName)); } isScopeNameInNotifierScopes(scopeName) { return Boolean(this._notifierScopes?.find((notifierScope) => notifierScope.scope === scopeName)); } areScopeNamesInNotifierScopes(scopeNames) { return scopeNames.map((scopeName) => this.isScopeNameInNotifierScopes(scopeName)) .reduce((previous, current) => previous && current); } getExistingNotifierScopes(scopeNames) { return scopeNames.filter((scopeName) => this.isScopeNameInNotifierScopes(scopeName)); } getNotiferScope(scopeName) { return this._notifierScopes?.find((notiferScope) => notiferScope.scope === scopeName); } getNotifierScopes(scopeNames) { const filteredScopes = scopeNames.map((scopeName) => this.getNotiferScope(scopeName)) .filter((notifierScope) => notifierScope !== undefined); return filteredScopes.length === 0 ? filteredScopes : undefined; } addNotifierScope(notifierScope) { this._notifierScopes === null ? this._notifierScopes = [notifierScope] : this._notifierScopes.push(notifierScope); } addNotifierScopes(notifierScopes) { this._notifierScopes === null ? this._notifierScopes = notifierScopes : this._notifierScopes.push(...notifierScopes); } addNotifierToNotifierScope(scopeName, notifier) { this._notifierScopes = this._notifierScopes?.map((notifierScope) => { if (notifierScope.scope !== scopeName) return notifierScope; notifierScope.notifiers === null ? notifierScope.notifiers = [notifier] : notifierScope.notifiers.push(notifier); return notifierScope; }) ?? null; } removeNotifierScope(scopeName) { if (this._notifierScopes === null) return; this._notifierScopes = this._notifierScopes.filter((notifierScope) => notifierScope.scope !== scopeName); } getSourceLocale() { return this._translationConfig.locales.find((localeConfig) => localeConfig.isSource); } _checkIfLocaleExists(locale) { return this._translationConfig.locales.some((configLocale) => configLocale.value === locale.value); } _checkIfLocaleIsSourceLocale(locale) { return this._translationConfig.locales.some((localeConfig) => localeConfig.value === locale.value && localeConfig.isSource); } _setStorageValue(dataType, storageValue) { storageValue === null ? this._storageAttributes[dataType].type.removeItem(this._storageAttributes[dataType].key) : this._storageAttributes[dataType].type.setItem(this._storageAttributes[dataType].key, JSON.stringify(storageValue)); } _getStorageValue(dataType) { const serializedStorageValue = this._storageAttributes[dataType].type.getItem(this._storageAttributes[dataType].key); return serializedStorageValue ? JSON.parse(serializedStorageValue) : null; } _getScopeByScopeName(scopeName) { if (this._storageAttributes.collectingStrategy === CollectingStrategies.ALL) { const localeLoadedScopes = this._loadedScopes; if (this._loadedScopes === null) return undefined; const _loadedScopes = localeLoadedScopes[this._locale.value.value]; return _loadedScopes?.find((loadedScope) => loadedScope.scope === scopeName); } const loadedScopes = this._loadedScopes; return loadedScopes?.find((loadedScope) => loadedScope.scope === scopeName); } _getScopeByScopeNames(scopeNames) { if (this._storageAttributes.collectingStrategy === CollectingStrategies.ALL) { const localeLoadedScopes = this._loadedScopes; if (this._loadedScopes === null) return undefined; const _loadedScopes = localeLoadedScopes[this._locale.value.value]; return _loadedScopes?.filter((loadedScope) => scopeNames.includes(loadedScope.scope)); } const loadedScopes = this._loadedScopes; return loadedScopes.filter((loadedScope) => scopeNames.includes(loadedScope.scope)); } _appendScope(scopeName, file) { if (this._storageAttributes.collectingStrategy === CollectingStrategies.ALL) { const localeLoadedScopes = this._loadedScopes; if (localeLoadedScopes === null) { this._loadedScopes = { [this._locale.value.value]: [{ scope: scopeName, file }] }; return; } const loadedScope = localeLoadedScopes[this._locale.value.value]; if (loadedScope === undefined) { localeLoadedScopes[this._locale.value.value] = [{ scope: scopeName, file }]; return; } loadedScope.push({ scope: scopeName, file }); return; } this._loadedScopes === null ? this._loadedScopes = [{ scope: scopeName, file }] : this._loadedScopes.push({ scope: scopeName, file }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, providedIn: "root" }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }], ctorParameters: () => [] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24tc3RvcmUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZXJ2aWNlcy90cmFuc2xhdGlvbi1zdG9yZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQXVCLG9CQUFvQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR25ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ3hGLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDOztBQXNCbEUsTUFBTSxPQUFPLHVCQUF1QjtJQUMxQixhQUFhLENBQTJDO0lBRXhELGVBQWUsR0FBMEIsSUFBSSxDQUFDO0lBRXJDLGtCQUFrQixHQUE0QixNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUUvRSxPQUFPLENBQWdDO0lBRXZDLFFBQVEsQ0FBMkI7SUFFbkMsa0JBQWtCLEdBQXNCO1FBQ3ZELGtCQUFrQixFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsa0JBQWtCLElBQUksb0JBQW9CLENBQUMsT0FBTztRQUM3RyxNQUFNLEVBQUU7WUFDTixJQUFJLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsSUFBSSxJQUFJLE1BQU0sQ0FBQyxZQUFZO1lBQ2hGLEdBQUcsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksUUFBUTtTQUNwRTtRQUNELFlBQVksRUFBRTtZQUNaLElBQUksRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLFlBQVksRUFBRSxJQUFJLElBQUksTUFBTSxDQUFDLGNBQWM7WUFDeEYsR0FBRyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsWUFBWSxFQUFFLEdBQUcsSUFBSSxjQUFjO1NBQ2hGO0tBQ0YsQ0FBQztJQUVGO1FBQ0UsTUFBTSxZQUFZLEdBQTZCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV0RSxJQUFJLFlBQVksS0FBSyxTQUFTO1lBQzVCLE1BQU0sSUFBSSwyQkFBMkIsRUFBRSxDQUFDO1FBRTFDLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDekQsTUFBTSxrQkFBa0IsR0FBd0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBd0IsQ0FBQztZQUN2RyxNQUFNLFlBQVksR0FBWSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUN6RyxNQUFNLGNBQWMsR0FBWSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUVuSCxJQUFJLENBQUMsWUFBWSxJQUFJLGNBQWM7Z0JBQ2pDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFeEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGVBQWUsQ0FBZSxrQkFBa0IsSUFBSSxZQUFZLENBQUMsQ0FBQztRQUN2RixDQUFDOztZQUNDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxlQUFlLENBQWUsWUFBWSxDQUFDLENBQUM7UUFFakUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUMvRCxNQUFNLHdCQUF3QixHQUE2QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxDQUE2QixDQUFDO1lBRTdILElBQUksQ0FBQyxhQUFhLEdBQUcsd0JBQXdCLElBQUksSUFBSSxDQUFDO1FBQ3hELENBQUM7O1lBQ0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFFNUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzlDLENBQUM7SUFFTSxnQkFBZ0I7UUFDckIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUM1QixDQUFDO0lBRU0sVUFBVTtRQUNmLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFTSxTQUFTLENBQUUsTUFBb0I7UUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7WUFDcEMsTUFBTSxJQUFJLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTFDLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDekQsSUFBSSxDQUFDLDRCQUE0QixDQUFDLE1BQU0sQ0FBQztnQkFDdkMsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDO2dCQUN2QyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLFlBQVksRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsS0FBSyxvQkFBb0IsQ0FBQyxPQUFPO1lBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV6TSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRU0sVUFBVTtRQUNmLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQztJQUN6QyxDQUFDO0lBRU0sYUFBYSxDQUFFLFNBQXdCLEVBQUUsSUFBZ0I7UUFDOUQsTUFBTSxhQUFhLEdBQTRCLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFNUcsSUFBSSxhQUFhLEtBQUssU0FBUztZQUM3QixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQzs7WUFFbkMsYUFBYSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFHNUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLFlBQVksRUFBRSxLQUFLO1lBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDNUgsQ0FBQztJQUVNLGFBQWEsQ0FBRSxTQUF3QjtRQUM1QyxNQUFNLGFBQWEsR0FBNEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXBGLE9BQU8sYUFBYSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDeEQsQ0FBQztJQUVNLGFBQWEsQ0FBRSxTQUF3QjtRQUM1QyxNQUFNLGFBQWEsR0FBNEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXBGLE9BQU8sT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFTSxjQUFjLENBQUUsVUFBd0M7UUFDN0QsTUFBTSxjQUFjLEdBQTZCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV4RixPQUFPLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRU0sZUFBZSxDQUFFLFNBQXdCO1FBQzlDLE1BQU0sYUFBYSxHQUE0QixJQUFJLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEYsT0FBTyxhQUFhLEtBQUssU0FBUyxDQUFDO0lBQ3JDLENBQUM7SUFFTSxpQkFBaUIsQ0FBRSxVQUF3QztRQUNoRSxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUF3QixFQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUVNLDJCQUEyQixDQUFFLFNBQXdCO1FBQzFELE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUMsYUFBc0MsRUFBVyxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3JJLENBQUM7SUFFTSw2QkFBNkIsQ0FBRSxVQUF3QztRQUM1RSxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUF3QixFQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsU0FBUyxDQUFDLENBQUM7YUFDdEcsTUFBTSxDQUFDLENBQUMsUUFBaUIsRUFBRSxPQUFnQixFQUFXLEVBQUUsQ0FBQyxRQUFRLElBQUksT0FBTyxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVNLHlCQUF5QixDQUFFLFVBQXdDO1FBQ3hFLE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQXdCLEVBQVcsRUFBRSxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFFTSxlQUFlLENBQUUsU0FBd0I7UUFDOUMsT0FBTyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFDLFlBQTJCLEVBQVcsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUM7SUFDaEgsQ0FBQztJQUVNLGlCQUFpQixDQUFFLFVBQXdDO1FBQ2hFLE1BQU0sY0FBYyxHQUF3QixVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBd0IsRUFBNkIsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7YUFDakosTUFBTSxDQUFDLENBQUMsYUFBa0QsRUFBVyxFQUFFLENBQUMsYUFBYSxLQUFLLFNBQVMsQ0FBd0IsQ0FBQztRQUUvSCxPQUFPLGNBQWMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNsRSxDQUFDO0lBRU0sZ0JBQWdCLENBQUUsYUFBc0M7UUFDN0QsSUFBSSxDQUFDLGVBQWUsS0FBSyxJQUFJO1lBQzNCLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxHQUFHLENBQUUsYUFBYSxDQUFFO1lBQzFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU0saUJBQWlCLENBQUUsY0FBOEI7UUFDdEQsSUFBSSxDQUFDLGVBQWUsS0FBSyxJQUFJO1lBQzNCLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxHQUFHLGNBQWM7WUFDdkMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVNLDBCQUEwQixDQUFFLFNBQXdCLEVBQUUsUUFBNkI7UUFDeEYsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxDQUFDLGFBQTRCLEVBQWlCLEVBQUU7WUFDL0YsSUFBSSxhQUFhLENBQUMsS0FBSyxLQUFLLFNBQVM7Z0JBQUUsT0FBTyxhQUFhLENBQUM7WUFFNUQsYUFBYSxDQUFDLFNBQVMsS0FBSyxJQUFJO2dCQUM5QixDQUFDLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxDQUFFLFFBQVEsQ0FBRTtnQkFDeEMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRTNDLE9BQU8sYUFBYSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQztJQUNiLENBQUM7SUFFTSxtQkFBbUIsQ0FBRSxTQUF3QjtRQUNsRCxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSTtZQUMvQixPQUFPO1FBRVQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGFBQXNDLEVBQVcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUM7SUFDN0ksQ0FBQztJQUVNLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQTBCLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyRyxDQUFDO0lBRU8sb0JBQW9CLENBQUUsTUFBb0I7UUFDaEQsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQTBCLEVBQVcsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVILENBQUM7SUFFTyw0QkFBNEIsQ0FBRSxNQUFvQjtRQUN4RCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsWUFBMEIsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssS0FBSyxNQUFNLENBQUMsS0FBSyxJQUFJLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1SSxDQUFDO0lBRU8sZ0JBQWdCLENBQUUsUUFBbUMsRUFBRSxZQUFxQjtRQUNsRixZQUFZLEtBQUssSUFBSTtZQUNuQixDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFFLFFBQVEsQ0FBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFFLFFBQVEsQ0FBRSxDQUFDLEdBQUcsQ0FBQztZQUM5RixDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFFLFFBQVEsQ0FBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFFLFFBQVEsQ0FBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDOUgsQ0FBQztJQUVPLGdCQUFnQixDQUFFLFFBQW1DO1FBQzNELE1BQU0sc0JBQXNCLEdBQWtCLElBQUksQ0FBQyxrQkFBa0IsQ0FBRSxRQUFRLENBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBRSxRQUFRLENBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV4SSxPQUFPLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM1RSxDQUFDO0lBRU8sb0JBQW9CLENBQUUsU0FBd0I7UUFDcEQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsa0JBQWtCLEtBQUssb0JBQW9CLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDNUUsTUFBTSxrQkFBa0IsR0FBOEIsSUFBSSxDQUFDLGFBQW1DLENBQUM7WUFFL0YsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLElBQUk7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFFbEQsTUFBTSxhQUFhLEdBQTZCLGtCQUFrQixDQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBRSxDQUFDO1lBRS9GLE9BQU8sYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDLFdBQXdCLEVBQVcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDckcsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUF3QixJQUFJLENBQUMsYUFBb0MsQ0FBQztRQUVwRixPQUFPLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQyxXQUF3QixFQUFXLEVBQUUsQ0FBQyxXQUFXLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDO0lBQ3BHLENBQUM7SUFFTyxxQkFBcUIsQ0FBRSxVQUF3QztRQUNyRSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxrQkFBa0IsS0FBSyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM1RSxNQUFNLGtCQUFrQixHQUE4QixJQUFJLENBQUMsYUFBbUMsQ0FBQztZQUUvRixJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSTtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUVsRCxNQUFNLGFBQWEsR0FBNkIsa0JBQWtCLENBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFFLENBQUM7WUFFL0YsT0FBTyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUMsV0FBd0IsRUFBVyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM5RyxDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQWlCLElBQUksQ0FBQyxhQUE2QixDQUFDO1FBRXRFLE9BQU8sWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFdBQXdCLEVBQVcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDNUcsQ0FBQztJQUVPLFlBQVksQ0FBRSxTQUF3QixFQUFFLElBQWdCO1FBQzlELElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGtCQUFrQixLQUFLLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQzVFLE1BQU0sa0JBQWtCLEdBQThCLElBQUksQ0FBQyxhQUEwQyxDQUFDO1lBRXRHLElBQUksa0JBQWtCLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBRSxFQUFFLENBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFFLEVBQUUsQ0FBQztnQkFFdEYsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLFdBQVcsR0FBNkIsa0JBQWtCLENBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFFLENBQUM7WUFFN0YsSUFBSSxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzlCLGtCQUFrQixDQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBRSxHQUFHLENBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFFLENBQUM7Z0JBRWhGLE9BQU87WUFDVCxDQUFDO1lBRUQsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUU3QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSTtZQUN6QixDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBRTtZQUNyRCxDQUFDLENBQUUsSUFBSSxDQUFDLGFBQThCLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7d0dBL1BVLHVCQUF1Qjs0R0FBdkIsdUJBQXVCLGNBRnRCLE1BQU07OzRGQUVQLHVCQUF1QjtrQkFIbkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YmplY3QsIGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBMb2FkZWRTY29wZSwgTG9hZGVkU2NvcGVzLCBMb2NhbGVMb2FkZWRTY29wZXMsIE5vdGlmaWVyU2NvcGUsIE5vdGlmaWVyU2NvcGVzLCBTY29wZWRGaWxlIH0gZnJvbSBcIi4uL3R5cGVzL3N0b3JlLnR5cGVcIjtcbmltcG9ydCB7IExvY2FsZUNvbmZpZywgU3BlY2lmaWNUcmFuc2xhdGVDb25maWcgfSBmcm9tIFwiLi4vdHlwZXMvY29uZmlnLnR5cGVcIjtcbmltcG9ydCB7IENvbGxlY3RpbmdTdHJhdGVnaWVzIH0gZnJvbSBcIi4uL2VudW1zL2NvbGxlY3Rpbmctc3RyYXRlZ2llcy5lbnVtXCI7XG5pbXBvcnQgeyBMb2NhbGVOb3REZWZpbmVkRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzL2xvY2FsZS1ub3QtZGVmaW5lZC5lcnJvclwiO1xuaW1wb3J0IHsgU291cmNlTG9jYWxlTm90RGVmaW5lZEVycm9yIH0gZnJvbSBcIi4uL2Vycm9ycy9zb3VyY2UtbG9jYWxlLW5vdC1kZWZpbmVkLmVycm9yXCI7XG5pbXBvcnQgeyBUUkFOU0xBVElPTl9DT05GSUdfVE9LRU4gfSBmcm9tIFwiLi4vdG9rZW5zL2NvbmZpZy50b2tlblwiO1xuXG50eXBlIFN0b3JhZ2VBdHRyaWJ1dGVzID0ge1xuICBjb2xsZWN0aW5nU3RyYXRlZ3k6IENvbGxlY3RpbmdTdHJhdGVnaWVzO1xuICBsb2NhbGU6IHtcbiAgICB0eXBlOiBTdG9yYWdlO1xuICAgIGtleTogc3RyaW5nO1xuICB9O1xuICB0cmFuc2xhdGlvbnM6IHtcbiAgICB0eXBlOiBTdG9yYWdlO1xuICAgIGtleTogc3RyaW5nO1xuICB9O1xufTtcblxudHlwZSBTdG9yZVRyYW5zbGF0aW9ucyA9IExvYWRlZFNjb3BlcyB8IExvY2FsZUxvYWRlZFNjb3BlcztcblxuLypcbiAqIEEgc2NvcGUgbmFtZSBvZiBudWxsIGlzIHRoZSBkZWZhdWx0IHNjb3BlLCBvdGhlcndpc2UsIGl0IGlzIHRoZSBpZGVudGlmaWVyIGZvciBhIHRyYW5zbGF0aW9uIGZpbGUuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogXCJyb290XCJcbn0pXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRpb25TdG9yZVNlcnZpY2Uge1xuICBwcml2YXRlIF9sb2FkZWRTY29wZXM6IExvYWRlZFNjb3BlcyB8IExvY2FsZUxvYWRlZFNjb3BlcyB8IG51bGw7XG5cbiAgcHJpdmF0ZSBfbm90aWZpZXJTY29wZXM6IE5vdGlmaWVyU2NvcGVzIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfdHJhbnNsYXRpb25Db25maWc6IFNwZWNpZmljVHJhbnNsYXRlQ29uZmlnID0gaW5qZWN0KFRSQU5TTEFUSU9OX0NPTkZJR19UT0tFTik7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbG9jYWxlOiBCZWhhdmlvclN1YmplY3Q8TG9jYWxlQ29uZmlnPjtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9sb2NhbGUkOiBPYnNlcnZhYmxlPExvY2FsZUNvbmZpZz47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfc3RvcmFnZUF0dHJpYnV0ZXM6IFN0b3JhZ2VBdHRyaWJ1dGVzID0ge1xuICAgIGNvbGxlY3RpbmdTdHJhdGVneTogdGhpcy5fdHJhbnNsYXRpb25Db25maWcuc3RvcmFnZUNvbmZpZz8uY29sbGVjdGluZ1N0cmF0ZWd5ID8/IENvbGxlY3RpbmdTdHJhdGVnaWVzLkNVUlJFTlQsXG4gICAgbG9jYWxlOiB7XG4gICAgICB0eXBlOiB0aGlzLl90cmFuc2xhdGlvbkNvbmZpZy5zdG9yYWdlQ29uZmlnPy5sb2NhbGU/LnR5cGUgPz8gd2luZG93LmxvY2FsU3RvcmFnZSxcbiAgICAgIGtleTogdGhpcy5fdHJhbnNsYXRpb25Db25maWcuc3RvcmFnZUNvbmZpZz8ubG9jYWxlPy5rZXkgPz8gXCJsb2NhbGVcIlxuICAgIH0sXG4gICAgdHJhbnNsYXRpb25zOiB7XG4gICAgICB0eXBlOiB0aGlzLl90cmFuc2xhdGlvbkNvbmZpZy5zdG9yYWdlQ29uZmlnPy50cmFuc2xhdGlvbnM/LnR5cGUgPz8gd2luZG93LnNlc3Npb25TdG9yYWdlLFxuICAgICAga2V5OiB0aGlzLl90cmFuc2xhdGlvbkNvbmZpZy5zdG9yYWdlQ29uZmlnPy50cmFuc2xhdGlvbnM/LmtleSA/PyBcInRyYW5zbGF0aW9uc1wiXG4gICAgfVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICBjb25zdCBzb3VyY2VMb2NhbGU6IExvY2FsZUNvbmZpZyB8IHVuZGVmaW5lZCA9IHRoaXMuZ2V0U291cmNlTG9jYWxlKCk7XG5cbiAgICBpZiAoc291cmNlTG9jYWxlID09PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgU291cmNlTG9jYWxlTm90RGVmaW5lZEVycm9yKCk7XG5cbiAgICBpZiAodGhpcy5fdHJhbnNsYXRpb25Db25maWcuc3RvcmFnZUNvbmZpZz8ubG9jYWxlPy5zdG9yZSkge1xuICAgICAgY29uc3QgbG9jYWxlU3RvcmFnZVZhbHVlOiBMb2NhbGVDb25maWcgfCBudWxsID0gdGhpcy5fZ2V0U3RvcmFnZVZhbHVlKFwibG9jYWxlXCIpIGFzIExvY2FsZUNvbmZpZyB8IG51bGw7XG4gICAgICBjb25zdCBsb2NhbGVFeGlzdHM6IGJvb2xlYW4gPSBsb2NhbGVTdG9yYWdlVmFsdWUgPyB0aGlzLl9jaGVja0lmTG9jYWxlRXhpc3RzKGxvY2FsZVN0b3JhZ2VWYWx1ZSkgOiBmYWxzZTtcbiAgICAgIGNvbnN0IGlzU291cmNlTG9jYWxlOiBib29sZWFuID0gbG9jYWxlU3RvcmFnZVZhbHVlID8gdGhpcy5fY2hlY2tJZkxvY2FsZUlzU291cmNlTG9jYWxlKGxvY2FsZVN0b3JhZ2VWYWx1ZSkgOiBmYWxzZTtcblxuICAgICAgaWYgKCFsb2NhbGVFeGlzdHMgfHwgaXNTb3VyY2VMb2NhbGUpXG4gICAgICAgIHRoaXMuX3NldFN0b3JhZ2VWYWx1ZShcImxvY2FsZVwiLCBudWxsKTtcblxuICAgICAgdGhpcy5fbG9jYWxlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxMb2NhbGVDb25maWc+KGxvY2FsZVN0b3JhZ2VWYWx1ZSA/PyBzb3VyY2VMb2NhbGUpO1xuICAgIH0gZWxzZVxuICAgICAgdGhpcy5fbG9jYWxlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxMb2NhbGVDb25maWc+KHNvdXJjZUxvY2FsZSk7XG5cbiAgICBpZiAodGhpcy5fdHJhbnNsYXRpb25Db25maWcuc3RvcmFnZUNvbmZpZz8udHJhbnNsYXRpb25zPy5zdG9yZSkge1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25zU3RvcmFnZVZhbHVlOiBTdG9yZVRyYW5zbGF0aW9ucyB8IG51bGwgPSB0aGlzLl9nZXRTdG9yYWdlVmFsdWUoXCJ0cmFuc2xhdGlvbnNcIikgYXMgU3RvcmVUcmFuc2xhdGlvbnMgfCBudWxsO1xuXG4gICAgICB0aGlzLl9sb2FkZWRTY29wZXMgPSB0cmFuc2xhdGlvbnNTdG9yYWdlVmFsdWUgPz8gbnVsbDtcbiAgICB9IGVsc2VcbiAgICAgIHRoaXMuX2xvYWRlZFNjb3BlcyA9IG51bGw7XG5cbiAgICB0aGlzLl9sb2NhbGUkID0gdGhpcy5fbG9jYWxlLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHVibGljIGdldEN1cnJlbnRMb2NhbGUgKCk6IExvY2FsZUNvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuX2xvY2FsZS52YWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRMb2NhbGUkICgpOiBPYnNlcnZhYmxlPExvY2FsZUNvbmZpZz4ge1xuICAgIHJldHVybiB0aGlzLl9sb2NhbGUkLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gIH1cblxuICBwdWJsaWMgc2V0TG9jYWxlIChsb2NhbGU6IExvY2FsZUNvbmZpZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fY2hlY2tJZkxvY2FsZUV4aXN0cyhsb2NhbGUpKVxuICAgICAgdGhyb3cgbmV3IExvY2FsZU5vdERlZmluZWRFcnJvcihsb2NhbGUpO1xuXG4gICAgaWYgKHRoaXMuX3RyYW5zbGF0aW9uQ29uZmlnLnN0b3JhZ2VDb25maWc/LmxvY2FsZT8uc3RvcmUpIHtcbiAgICAgIHRoaXMuX2NoZWNrSWZMb2NhbGVJc1NvdXJjZUxvY2FsZShsb2NhbGUpXG4gICAgICAgID8gdGhpcy5fc2V0U3RvcmFnZVZhbHVlKFwibG9jYWxlXCIsIG51bGwpXG4gICAgICAgIDogdGhpcy5fc2V0U3RvcmFnZVZhbHVlKFwibG9jYWxlXCIsIGxvY2FsZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3RyYW5zbGF0aW9uQ29uZmlnLnN0b3JhZ2VDb25maWc/LnRyYW5zbGF0aW9ucz8uc3RvcmUgJiYgdGhpcy5fdHJhbnNsYXRpb25Db25maWcuc3RvcmFnZUNvbmZpZy5jb2xsZWN0aW5nU3RyYXRlZ3kgPT09IENvbGxlY3RpbmdTdHJhdGVnaWVzLkNVUlJFTlQpIHRoaXMuX3NldFN0b3JhZ2VWYWx1ZShcInRyYW5zbGF0aW9uc1wiLCBudWxsKTtcblxuICAgIHRoaXMuX2xvY2FsZS5uZXh0KGxvY2FsZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0TG9jYWxlcyAoKTogTG9jYWxlQ29uZmlnW10ge1xuICAgIHJldHVybiB0aGlzLl90cmFuc2xhdGlvbkNvbmZpZy5sb2NhbGVzO1xuICB9XG5cbiAgcHVibGljIHNldFNjb3BlZEZpbGUgKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCwgZmlsZTogU2NvcGVkRmlsZSk6IHZvaWQge1xuICAgIGNvbnN0IGV4aXN0aW5nU2NvcGU6IExvYWRlZFNjb3BlIHwgdW5kZWZpbmVkID0gc2NvcGVOYW1lID8gdGhpcy5fZ2V0U2NvcGVCeVNjb3BlTmFtZShzY29wZU5hbWUpIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKGV4aXN0aW5nU2NvcGUgPT09IHVuZGVmaW5lZClcbiAgICAgIHRoaXMuX2FwcGVuZFNjb3BlKHNjb3BlTmFtZSwgZmlsZSk7XG4gICAgZWxzZVxuICAgICAgZXhpc3RpbmdTY29wZS5maWxlID0gZmlsZTtcblxuXG4gICAgaWYgKHRoaXMuX3RyYW5zbGF0aW9uQ29uZmlnLnN0b3JhZ2VDb25maWc/LnRyYW5zbGF0aW9ucz8uc3RvcmUpIHRoaXMuX3NldFN0b3JhZ2VWYWx1ZShcInRyYW5zbGF0aW9uc1wiLCB0aGlzLl9sb2FkZWRTY29wZXMpO1xuICB9XG5cbiAgcHVibGljIGdldFNjb3BlZEZpbGUgKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCk6IFNjb3BlZEZpbGUgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGV4aXN0aW5nU2NvcGU6IExvYWRlZFNjb3BlIHwgdW5kZWZpbmVkID0gdGhpcy5fZ2V0U2NvcGVCeVNjb3BlTmFtZShzY29wZU5hbWUpO1xuXG4gICAgcmV0dXJuIGV4aXN0aW5nU2NvcGUgPyBleGlzdGluZ1Njb3BlLmZpbGUgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgaGFzU2NvcGVkRmlsZSAoc2NvcGVOYW1lOiBzdHJpbmcgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZXhpc3RpbmdTY29wZTogTG9hZGVkU2NvcGUgfCB1bmRlZmluZWQgPSB0aGlzLl9nZXRTY29wZUJ5U2NvcGVOYW1lKHNjb3BlTmFtZSk7XG5cbiAgICByZXR1cm4gQm9vbGVhbihleGlzdGluZ1Njb3BlKTtcbiAgfVxuXG4gIHB1YmxpYyBoYXNTY29wZWRGaWxlcyAoc2NvcGVOYW1lczogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGV4aXN0aW5nU2NvcGVzOiBMb2FkZWRTY29wZXMgfCB1bmRlZmluZWQgPSB0aGlzLl9nZXRTY29wZUJ5U2NvcGVOYW1lcyhzY29wZU5hbWVzKTtcblxuICAgIHJldHVybiBCb29sZWFuKGV4aXN0aW5nU2NvcGVzKTtcbiAgfVxuXG4gIHB1YmxpYyBpc1Njb3BlRXhpc3RpbmcgKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGV4aXN0aW5nU2NvcGU6IExvYWRlZFNjb3BlIHwgdW5kZWZpbmVkID0gdGhpcy5fZ2V0U2NvcGVCeVNjb3BlTmFtZShzY29wZU5hbWUpO1xuXG4gICAgcmV0dXJuIGV4aXN0aW5nU2NvcGUgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRFeGlzdGluZ1Njb3BlcyAoc2NvcGVOYW1lczogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPik6IEFycmF5PHN0cmluZyB8IG51bGw+IHtcbiAgICByZXR1cm4gc2NvcGVOYW1lcy5maWx0ZXIoKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4gPT4gdGhpcy5pc1Njb3BlRXhpc3Rpbmcoc2NvcGVOYW1lKSk7XG4gIH1cblxuICBwdWJsaWMgaXNTY29wZU5hbWVJbk5vdGlmaWVyU2NvcGVzIChzY29wZU5hbWU6IHN0cmluZyB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLl9ub3RpZmllclNjb3Blcz8uZmluZCgobm90aWZpZXJTY29wZTogUmVhZG9ubHk8Tm90aWZpZXJTY29wZT4pOiBib29sZWFuID0+IG5vdGlmaWVyU2NvcGUuc2NvcGUgPT09IHNjb3BlTmFtZSkpO1xuICB9XG5cbiAgcHVibGljIGFyZVNjb3BlTmFtZXNJbk5vdGlmaWVyU2NvcGVzIChzY29wZU5hbWVzOiBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHNjb3BlTmFtZXMubWFwKChzY29wZU5hbWU6IHN0cmluZyB8IG51bGwpOiBib29sZWFuID0+IHRoaXMuaXNTY29wZU5hbWVJbk5vdGlmaWVyU2NvcGVzKHNjb3BlTmFtZSkpXG4gICAgICAucmVkdWNlKChwcmV2aW91czogYm9vbGVhbiwgY3VycmVudDogYm9vbGVhbik6IGJvb2xlYW4gPT4gcHJldmlvdXMgJiYgY3VycmVudCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RXhpc3RpbmdOb3RpZmllclNjb3BlcyAoc2NvcGVOYW1lczogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPik6IEFycmF5PHN0cmluZyB8IG51bGw+IHtcbiAgICByZXR1cm4gc2NvcGVOYW1lcy5maWx0ZXIoKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4gPT4gdGhpcy5pc1Njb3BlTmFtZUluTm90aWZpZXJTY29wZXMoc2NvcGVOYW1lKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Tm90aWZlclNjb3BlIChzY29wZU5hbWU6IHN0cmluZyB8IG51bGwpOiBOb3RpZmllclNjb3BlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fbm90aWZpZXJTY29wZXM/LmZpbmQoKG5vdGlmZXJTY29wZTogTm90aWZpZXJTY29wZSk6IGJvb2xlYW4gPT4gbm90aWZlclNjb3BlLnNjb3BlID09PSBzY29wZU5hbWUpO1xuICB9XG5cbiAgcHVibGljIGdldE5vdGlmaWVyU2NvcGVzIChzY29wZU5hbWVzOiBSZWFkb25seUFycmF5PHN0cmluZyB8IG51bGw+KTogTm90aWZpZXJTY29wZXMgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGZpbHRlcmVkU2NvcGVzOiBOb3RpZmllclNjb3BlcyB8IFtdID0gc2NvcGVOYW1lcy5tYXAoKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCk6IE5vdGlmaWVyU2NvcGUgfCB1bmRlZmluZWQgPT4gdGhpcy5nZXROb3RpZmVyU2NvcGUoc2NvcGVOYW1lKSlcbiAgICAgIC5maWx0ZXIoKG5vdGlmaWVyU2NvcGU6IFJlYWRvbmx5PE5vdGlmaWVyU2NvcGU+IHwgdW5kZWZpbmVkKTogYm9vbGVhbiA9PiBub3RpZmllclNjb3BlICE9PSB1bmRlZmluZWQpIGFzIE5vdGlmaWVyU2NvcGVzIHwgW107XG5cbiAgICByZXR1cm4gZmlsdGVyZWRTY29wZXMubGVuZ3RoID09PSAwID8gZmlsdGVyZWRTY29wZXMgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgYWRkTm90aWZpZXJTY29wZSAobm90aWZpZXJTY29wZTogUmVhZG9ubHk8Tm90aWZpZXJTY29wZT4pOiB2b2lkIHtcbiAgICB0aGlzLl9ub3RpZmllclNjb3BlcyA9PT0gbnVsbFxuICAgICAgPyB0aGlzLl9ub3RpZmllclNjb3BlcyA9IFsgbm90aWZpZXJTY29wZSBdXG4gICAgICA6IHRoaXMuX25vdGlmaWVyU2NvcGVzLnB1c2gobm90aWZpZXJTY29wZSk7XG4gIH1cblxuICBwdWJsaWMgYWRkTm90aWZpZXJTY29wZXMgKG5vdGlmaWVyU2NvcGVzOiBOb3RpZmllclNjb3Blcyk6IHZvaWQge1xuICAgIHRoaXMuX25vdGlmaWVyU2NvcGVzID09PSBudWxsXG4gICAgICA/IHRoaXMuX25vdGlmaWVyU2NvcGVzID0gbm90aWZpZXJTY29wZXNcbiAgICAgIDogdGhpcy5fbm90aWZpZXJTY29wZXMucHVzaCguLi5ub3RpZmllclNjb3Blcyk7XG4gIH1cblxuICBwdWJsaWMgYWRkTm90aWZpZXJUb05vdGlmaWVyU2NvcGUgKHNjb3BlTmFtZTogc3RyaW5nIHwgbnVsbCwgbm90aWZpZXI6IFN1YmplY3Q8U2NvcGVkRmlsZT4pOiB2b2lkIHtcbiAgICB0aGlzLl9ub3RpZmllclNjb3BlcyA9IHRoaXMuX25vdGlmaWVyU2NvcGVzPy5tYXAoKG5vdGlmaWVyU2NvcGU6IE5vdGlmaWVyU2NvcGUpOiBOb3RpZmllclNjb3BlID0+IHtcbiAgICAgIGlmIChub3RpZmllclNjb3BlLnNjb3BlICE9PSBzY29wZU5hbWUpIHJldHVybiBub3RpZmllclNjb3BlO1xuXG4gICAgICBub3RpZmllclNjb3BlLm5vdGlmaWVycyA9PT0gbnVsbFxuICAgICAgICA/IG5vdGlmaWVyU2NvcGUubm90aWZpZXJzID0gWyBub3RpZmllciBdXG4gICAgICAgIDogbm90aWZpZXJTY29wZS5ub3RpZmllcnMucHVzaChub3RpZmllcik7XG5cbiAgICAgIHJldHVybiBub3RpZmllclNjb3BlO1xuICAgIH0pID8/IG51bGw7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlTm90aWZpZXJTY29wZSAoc2NvcGVOYW1lOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX25vdGlmaWVyU2NvcGVzID09PSBudWxsKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdGhpcy5fbm90aWZpZXJTY29wZXMgPSB0aGlzLl9ub3RpZmllclNjb3Blcy5maWx0ZXIoKG5vdGlmaWVyU2NvcGU6IFJlYWRvbmx5PE5vdGlmaWVyU2NvcGU+KTogYm9vbGVhbiA9PiBub3RpZmllclNjb3BlLnNjb3BlICE9PSBzY29wZU5hbWUpO1xuICB9XG5cbiAgcHVibGljIGdldFNvdXJjZUxvY2FsZSAoKTogTG9jYWxlQ29uZmlnIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNsYXRpb25Db25maWcubG9jYWxlcy5maW5kKChsb2NhbGVDb25maWc6IExvY2FsZUNvbmZpZykgPT4gbG9jYWxlQ29uZmlnLmlzU291cmNlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NoZWNrSWZMb2NhbGVFeGlzdHMgKGxvY2FsZTogTG9jYWxlQ29uZmlnKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zbGF0aW9uQ29uZmlnLmxvY2FsZXMuc29tZSgoY29uZmlnTG9jYWxlOiBMb2NhbGVDb25maWcpOiBib29sZWFuID0+IGNvbmZpZ0xvY2FsZS52YWx1ZSA9PT0gbG9jYWxlLnZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NoZWNrSWZMb2NhbGVJc1NvdXJjZUxvY2FsZSAobG9jYWxlOiBMb2NhbGVDb25maWcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNsYXRpb25Db25maWcubG9jYWxlcy5zb21lKChsb2NhbGVDb25maWc6IExvY2FsZUNvbmZpZykgPT4gbG9jYWxlQ29uZmlnLnZhbHVlID09PSBsb2NhbGUudmFsdWUgJiYgbG9jYWxlQ29uZmlnLmlzU291cmNlKTtcbiAgfVxuXG4gIHByaXZhdGUgX3NldFN0b3JhZ2VWYWx1ZSAoZGF0YVR5cGU6IFwibG9jYWxlXCIgfCBcInRyYW5zbGF0aW9uc1wiLCBzdG9yYWdlVmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICBzdG9yYWdlVmFsdWUgPT09IG51bGxcbiAgICAgID8gdGhpcy5fc3RvcmFnZUF0dHJpYnV0ZXNbIGRhdGFUeXBlIF0udHlwZS5yZW1vdmVJdGVtKHRoaXMuX3N0b3JhZ2VBdHRyaWJ1dGVzWyBkYXRhVHlwZSBdLmtleSlcbiAgICAgIDogdGhpcy5fc3RvcmFnZUF0dHJpYnV0ZXNbIGRhdGFUeXBlIF0udHlwZS5zZXRJdGVtKHRoaXMuX3N0b3JhZ2VBdHRyaWJ1dGVzWyBkYXRhVHlwZSBdLmtleSwgSlNPTi5zdHJpbmdpZnkoc3RvcmFnZVZhbHVlKSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRTdG9yYWdlVmFsdWUgKGRhdGFUeXBlOiBcImxvY2FsZVwiIHwgXCJ0cmFuc2xhdGlvbnNcIik6IHVua25vd24ge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRTdG9yYWdlVmFsdWU6IHN0cmluZyB8IG51bGwgPSB0aGlzLl9zdG9yYWdlQXR0cmlidXRlc1sgZGF0YVR5cGUgXS50eXBlLmdldEl0ZW0odGhpcy5fc3RvcmFnZUF0dHJpYnV0ZXNbIGRhdGFUeXBlIF0ua2V5KTtcblxuICAgIHJldHVybiBzZXJpYWxpemVkU3RvcmFnZVZhbHVlID8gSlNPTi5wYXJzZShzZXJpYWxpemVkU3RvcmFnZVZhbHVlKSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9nZXRTY29wZUJ5U2NvcGVOYW1lIChzY29wZU5hbWU6IHN0cmluZyB8IG51bGwpOiBMb2FkZWRTY29wZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuX3N0b3JhZ2VBdHRyaWJ1dGVzLmNvbGxlY3RpbmdTdHJhdGVneSA9PT0gQ29sbGVjdGluZ1N0cmF0ZWdpZXMuQUxMKSB7XG4gICAgICBjb25zdCBsb2NhbGVMb2FkZWRTY29wZXM6IExvY2FsZUxvYWRlZFNjb3BlcyB8IG51bGwgPSB0aGlzLl9sb2FkZWRTY29wZXMgYXMgTG9jYWxlTG9hZGVkU2NvcGVzO1xuXG4gICAgICBpZiAodGhpcy5fbG9hZGVkU2NvcGVzID09PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICBjb25zdCBfbG9hZGVkU2NvcGVzOiBMb2FkZWRTY29wZXMgfCB1bmRlZmluZWQgPSBsb2NhbGVMb2FkZWRTY29wZXNbIHRoaXMuX2xvY2FsZS52YWx1ZS52YWx1ZSBdO1xuXG4gICAgICByZXR1cm4gX2xvYWRlZFNjb3Blcz8uZmluZCgobG9hZGVkU2NvcGU6IExvYWRlZFNjb3BlKTogYm9vbGVhbiA9PiBsb2FkZWRTY29wZS5zY29wZSA9PT0gc2NvcGVOYW1lKTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2FkZWRTY29wZXM6IExvYWRlZFNjb3BlcyB8IG51bGwgPSB0aGlzLl9sb2FkZWRTY29wZXMgYXMgTG9hZGVkU2NvcGVzIHwgbnVsbDtcblxuICAgIHJldHVybiBsb2FkZWRTY29wZXM/LmZpbmQoKGxvYWRlZFNjb3BlOiBMb2FkZWRTY29wZSk6IGJvb2xlYW4gPT4gbG9hZGVkU2NvcGUuc2NvcGUgPT09IHNjb3BlTmFtZSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRTY29wZUJ5U2NvcGVOYW1lcyAoc2NvcGVOYW1lczogUmVhZG9ubHlBcnJheTxzdHJpbmcgfCBudWxsPik6IExvYWRlZFNjb3BlcyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuX3N0b3JhZ2VBdHRyaWJ1dGVzLmNvbGxlY3RpbmdTdHJhdGVneSA9PT0gQ29sbGVjdGluZ1N0cmF0ZWdpZXMuQUxMKSB7XG4gICAgICBjb25zdCBsb2NhbGVMb2FkZWRTY29wZXM6IExvY2FsZUxvYWRlZFNjb3BlcyB8IG51bGwgPSB0aGlzLl9sb2FkZWRTY29wZXMgYXMgTG9jYWxlTG9hZGVkU2NvcGVzO1xuXG4gICAgICBpZiAodGhpcy5fbG9hZGVkU2NvcGVzID09PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICBjb25zdCBfbG9hZGVkU2NvcGVzOiBMb2FkZWRTY29wZXMgfCB1bmRlZmluZWQgPSBsb2NhbGVMb2FkZWRTY29wZXNbIHRoaXMuX2xvY2FsZS52YWx1ZS52YWx1ZSBdO1xuXG4gICAgICByZXR1cm4gX2xvYWRlZFNjb3Blcz8uZmlsdGVyKChsb2FkZWRTY29wZTogTG9hZGVkU2NvcGUpOiBib29sZWFuID0+IHNjb3BlTmFtZXMuaW5jbHVkZXMobG9hZGVkU2NvcGUuc2NvcGUpKTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2FkZWRTY29wZXM6IExvYWRlZFNjb3BlcyA9IHRoaXMuX2xvYWRlZFNjb3BlcyBhcyBMb2FkZWRTY29wZXM7XG5cbiAgICByZXR1cm4gbG9hZGVkU2NvcGVzLmZpbHRlcigobG9hZGVkU2NvcGU6IExvYWRlZFNjb3BlKTogYm9vbGVhbiA9PiBzY29wZU5hbWVzLmluY2x1ZGVzKGxvYWRlZFNjb3BlLnNjb3BlKSk7XG4gIH1cblxuICBwcml2YXRlIF9hcHBlbmRTY29wZSAoc2NvcGVOYW1lOiBzdHJpbmcgfCBudWxsLCBmaWxlOiBTY29wZWRGaWxlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3N0b3JhZ2VBdHRyaWJ1dGVzLmNvbGxlY3RpbmdTdHJhdGVneSA9PT0gQ29sbGVjdGluZ1N0cmF0ZWdpZXMuQUxMKSB7XG4gICAgICBjb25zdCBsb2NhbGVMb2FkZWRTY29wZXM6IExvY2FsZUxvYWRlZFNjb3BlcyB8IG51bGwgPSB0aGlzLl9sb2FkZWRTY29wZXMgYXMgTG9jYWxlTG9hZGVkU2NvcGVzIHwgbnVsbDtcblxuICAgICAgaWYgKGxvY2FsZUxvYWRlZFNjb3BlcyA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9sb2FkZWRTY29wZXMgPSB7IFsgdGhpcy5fbG9jYWxlLnZhbHVlLnZhbHVlIF06IFsgeyBzY29wZTogc2NvcGVOYW1lLCBmaWxlIH0gXSB9O1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbG9hZGVkU2NvcGU6IExvYWRlZFNjb3BlcyB8IHVuZGVmaW5lZCA9IGxvY2FsZUxvYWRlZFNjb3Blc1sgdGhpcy5fbG9jYWxlLnZhbHVlLnZhbHVlIF07XG5cbiAgICAgIGlmIChsb2FkZWRTY29wZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxvY2FsZUxvYWRlZFNjb3Blc1sgdGhpcy5fbG9jYWxlLnZhbHVlLnZhbHVlIF0gPSBbIHsgc2NvcGU6IHNjb3BlTmFtZSwgZmlsZSB9IF07XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsb2FkZWRTY29wZS5wdXNoKHsgc2NvcGU6IHNjb3BlTmFtZSwgZmlsZSB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2xvYWRlZFNjb3BlcyA9PT0gbnVsbFxuICAgICAgPyB0aGlzLl9sb2FkZWRTY29wZXMgPSBbIHsgc2NvcGU6IHNjb3BlTmFtZSwgZmlsZSB9IF1cbiAgICAgIDogKHRoaXMuX2xvYWRlZFNjb3BlcyBhcyBMb2FkZWRTY29wZXMpLnB1c2goeyBzY29wZTogc2NvcGVOYW1lLCBmaWxlIH0pO1xuICB9XG59XG4iXX0=