@spartacus/core
Version:
Spartacus - the core framework
152 lines • 17.3 kB
JavaScript
import { __awaiter } from "tslib";
import { Inject, Injectable, isDevMode, Optional } from '@angular/core';
import { BehaviorSubject, of } from 'rxjs';
import { filter, mapTo, take } from 'rxjs/operators';
import { RootConfig } from '../config-tokens';
import { deepMerge } from '../utils/deep-merge';
import { CONFIG_INITIALIZER_FORROOT_GUARD, } from './config-initializer';
import * as i0 from "@angular/core";
import * as i1 from "../config-tokens";
/**
* Provides support for CONFIG_INITIALIZERS
*/
export class ConfigInitializerService {
constructor(config, initializerGuard, rootConfig) {
this.config = config;
this.initializerGuard = initializerGuard;
this.rootConfig = rootConfig;
this.ongoingScopes$ = new BehaviorSubject(undefined);
}
/**
* Returns true if config is stable, i.e. all CONFIG_INITIALIZERS resolved correctly
*/
get isStable() {
var _a;
return !this.initializerGuard || ((_a = this.ongoingScopes$.value) === null || _a === void 0 ? void 0 : _a.length) === 0;
}
/**
* Recommended way to get config for code that can run before app will finish
* initialization (APP_INITIALIZERS, selected service constructors)
*
* Used without parameters waits for the whole config to become stable
*
* Parameters allow to describe which part of the config should be stable using
* string describing config part, e.g.:
* 'siteContext', 'siteContext.language', etc.
*
* @param scopes String describing parts of the config we want to be sure are stable
*/
getStable(...scopes) {
if (this.isStable) {
return of(this.config);
}
return this.ongoingScopes$.pipe(filter((ongoingScopes) => !!ongoingScopes && this.areReady(scopes, ongoingScopes)), take(1), mapTo(this.config));
}
/**
* Removes provided scopes from currently ongoingScopes
*
* @param scopes
*/
finishScopes(scopes) {
var _a;
const newScopes = [...((_a = this.ongoingScopes$.value) !== null && _a !== void 0 ? _a : [])];
for (const scope of scopes) {
newScopes.splice(newScopes.indexOf(scope), 1);
}
this.ongoingScopes$.next(newScopes);
}
/**
* Return true if provided scopes are not part of ongoingScopes
*
* @param scopes
* @param ongoingScopes
*/
areReady(scopes, ongoingScopes) {
if (!scopes.length) {
return !ongoingScopes.length;
}
for (const scope of scopes) {
for (const ongoingScope of ongoingScopes) {
if (this.scopesOverlap(scope, ongoingScope)) {
return false;
}
}
}
return true;
}
/**
* Check if two scopes overlap.
*
* Example of scopes that overlap:
* 'test' and 'test', 'test.a' and 'test', 'test' and 'test.a'
*
* Example of scopes that do not overlap:
* 'test' and 'testA', 'test.a' and 'test.b', 'test.nested' and 'test.nest'
*
* @param a ScopeA
* @param b ScopeB
*/
scopesOverlap(a, b) {
if (b.length > a.length) {
[a, b] = [b, a];
}
return a.startsWith(b) && (a[b.length] || '.') === '.';
}
/**
* @internal
*
* Not a part of a public API, used by APP_INITIALIZER to initialize all provided CONFIG_INITIALIZERS
*
*/
initialize(initializers) {
return __awaiter(this, void 0, void 0, function* () {
if (this.ongoingScopes$.value) {
// guard for double initialization
return;
}
const ongoingScopes = [];
const asyncConfigs = [];
for (const initializer of initializers || []) {
if (!initializer) {
continue;
}
if (!initializer.scopes || !initializer.scopes.length) {
throw new Error('CONFIG_INITIALIZER should provide scope!');
}
if (isDevMode() && !this.areReady(initializer.scopes, ongoingScopes)) {
console.warn('More than one CONFIG_INITIALIZER is initializing the same config scope.');
}
ongoingScopes.push(...initializer.scopes);
asyncConfigs.push((() => __awaiter(this, void 0, void 0, function* () {
const initializerConfig = yield initializer.configFactory();
// contribute configuration to rootConfig
deepMerge(this.rootConfig, initializerConfig);
// contribute configuration to global config
deepMerge(this.config, initializerConfig);
this.finishScopes(initializer.scopes);
}))());
}
this.ongoingScopes$.next(ongoingScopes);
if (asyncConfigs.length) {
yield Promise.all(asyncConfigs);
}
});
}
}
ConfigInitializerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ConfigInitializerService, deps: [{ token: i1.Config }, { token: CONFIG_INITIALIZER_FORROOT_GUARD, optional: true }, { token: RootConfig }], target: i0.ɵɵFactoryTarget.Injectable });
ConfigInitializerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ConfigInitializerService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ConfigInitializerService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.Config }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [CONFIG_INITIALIZER_FORROOT_GUARD]
}] }, { type: i1.Config, decorators: [{
type: Inject,
args: [RootConfig]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLWluaXRpYWxpemVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9jb25maWcvY29uZmlnLWluaXRpYWxpemVyL2NvbmZpZy1pbml0aWFsaXplci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxlQUFlLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JELE9BQU8sRUFBVSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUVMLGdDQUFnQyxHQUNqQyxNQUFNLHNCQUFzQixDQUFDOzs7QUFFOUI7O0dBRUc7QUFJSCxNQUFNLE9BQU8sd0JBQXdCO0lBQ25DLFlBQ1ksTUFBYyxFQUdkLGdCQUFxQixFQUNELFVBQWtCO1FBSnRDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFHZCxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQUs7UUFDRCxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBR3hDLG1CQUFjLEdBQUcsSUFBSSxlQUFlLENBQzVDLFNBQVMsQ0FDVixDQUFDO0lBSkMsQ0FBQztJQU1KOztPQUVHO0lBQ0gsSUFBSSxRQUFROztRQUNWLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQSxNQUFBLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSywwQ0FBRSxNQUFNLE1BQUssQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILFNBQVMsQ0FBQyxH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QU0sQ0FBQyxDQUFDO2dCQUUxQyxZQUFZLENBQUMsSUFBSSxDQUNmLENBQUMsR0FBUyxFQUFFO29CQUNWLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxXQUFXLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQzVELHlDQUF5QztvQkFDekMsU0FBUyxDQUNQLElBQUksQ0FBQyxVQUFxQyxFQUMxQyxpQkFBaUIsQ0FDbEIsQ0FBQztvQkFDRiw0Q0FBNEM7b0JBQzVDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBaUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO29CQUNyRSxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDeEMsQ0FBQyxDQUFBLENBQUMsRUFBRSxDQUNMLENBQUM7YUFDSDtZQUNELElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRXhDLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRTtnQkFDdkIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQ2pDO1FBQ0gsQ0FBQztLQUFBOztxSEFySlUsd0JBQXdCLHdDQUl6QixnQ0FBZ0MsNkJBRWhDLFVBQVU7eUhBTlQsd0JBQXdCLGNBRnZCLE1BQU07MkZBRVAsd0JBQXdCO2tCQUhwQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBSUksUUFBUTs7MEJBQ1IsTUFBTTsyQkFBQyxnQ0FBZ0M7OzBCQUV2QyxNQUFNOzJCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIGlzRGV2TW9kZSwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwVG8sIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDb25maWcsIFJvb3RDb25maWcgfSBmcm9tICcuLi9jb25maWctdG9rZW5zJztcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gJy4uL3V0aWxzL2RlZXAtbWVyZ2UnO1xuaW1wb3J0IHtcbiAgQ29uZmlnSW5pdGlhbGl6ZXIsXG4gIENPTkZJR19JTklUSUFMSVpFUl9GT1JST09UX0dVQVJELFxufSBmcm9tICcuL2NvbmZpZy1pbml0aWFsaXplcic7XG5cbi8qKlxuICogUHJvdmlkZXMgc3VwcG9ydCBmb3IgQ09ORklHX0lOSVRJQUxJWkVSU1xuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQ29uZmlnSW5pdGlhbGl6ZXJTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGNvbmZpZzogQ29uZmlnLFxuICAgIEBPcHRpb25hbCgpXG4gICAgQEluamVjdChDT05GSUdfSU5JVElBTElaRVJfRk9SUk9PVF9HVUFSRClcbiAgICBwcm90ZWN0ZWQgaW5pdGlhbGl6ZXJHdWFyZDogYW55LFxuICAgIEBJbmplY3QoUm9vdENvbmZpZykgcHJvdGVjdGVkIHJvb3RDb25maWc6IENvbmZpZ1xuICApIHt9XG5cbiAgcHJvdGVjdGVkIG9uZ29pbmdTY29wZXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmdbXSB8IHVuZGVmaW5lZD4oXG4gICAgdW5kZWZpbmVkXG4gICk7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBjb25maWcgaXMgc3RhYmxlLCBpLmUuIGFsbCBDT05GSUdfSU5JVElBTElaRVJTIHJlc29sdmVkIGNvcnJlY3RseVxuICAgKi9cbiAgZ2V0IGlzU3RhYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5pbml0aWFsaXplckd1YXJkIHx8IHRoaXMub25nb2luZ1Njb3BlcyQudmFsdWU/Lmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvbW1lbmRlZCB3YXkgdG8gZ2V0IGNvbmZpZyBmb3IgY29kZSB0aGF0IGNhbiBydW4gYmVmb3JlIGFwcCB3aWxsIGZpbmlzaFxuICAgKiBpbml0aWFsaXphdGlvbiAoQVBQX0lOSVRJQUxJWkVSUywgc2VsZWN0ZWQgc2VydmljZSBjb25zdHJ1Y3RvcnMpXG4gICAqXG4gICAqIFVzZWQgd2l0aG91dCBwYXJhbWV0ZXJzIHdhaXRzIGZvciB0aGUgd2hvbGUgY29uZmlnIHRvIGJlY29tZSBzdGFibGVcbiAgICpcbiAgICogUGFyYW1ldGVycyBhbGxvdyB0byBkZXNjcmliZSB3aGljaCBwYXJ0IG9mIHRoZSBjb25maWcgc2hvdWxkIGJlIHN0YWJsZSB1c2luZ1xuICAgKiBzdHJpbmcgZGVzY3JpYmluZyBjb25maWcgcGFydCwgZS5nLjpcbiAgICogJ3NpdGVDb250ZXh0JywgJ3NpdGVDb250ZXh0Lmxhbmd1YWdlJywgZXRjLlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGVzIFN0cmluZyBkZXNjcmliaW5nIHBhcnRzIG9mIHRoZSBjb25maWcgd2Ugd2FudCB0byBiZSBzdXJlIGFyZSBzdGFibGVcbiAgICovXG4gIGdldFN0YWJsZSguLi5zY29wZXM6IHN0cmluZ1tdKTogT2JzZXJ2YWJsZTxDb25maWc+IHtcbiAgICBpZiAodGhpcy5pc1N0YWJsZSkge1xuICAgICAgcmV0dXJuIG9mKHRoaXMuY29uZmlnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMub25nb2luZ1Njb3BlcyQucGlwZShcbiAgICAgIGZpbHRlcihcbiAgICAgICAgKG9uZ29pbmdTY29wZXMpID0+XG4gICAgICAgICAgISFvbmdvaW5nU2NvcGVzICYmIHRoaXMuYXJlUmVhZHkoc2NvcGVzLCBvbmdvaW5nU2NvcGVzKVxuICAgICAgKSxcbiAgICAgIHRha2UoMSksXG4gICAgICBtYXBUbyh0aGlzLmNvbmZpZylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgcHJvdmlkZWQgc2NvcGVzIGZyb20gY3VycmVudGx5IG9uZ29pbmdTY29wZXNcbiAgICpcbiAgICogQHBhcmFtIHNjb3Blc1xuICAgKi9cbiAgcHJvdGVjdGVkIGZpbmlzaFNjb3BlcyhzY29wZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgbmV3U2NvcGVzID0gWy4uLih0aGlzLm9uZ29pbmdTY29wZXMkLnZhbHVlID8/IFtdKV07XG4gICAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICAgIG5ld1Njb3Blcy5zcGxpY2UobmV3U2NvcGVzLmluZGV4T2Yoc2NvcGUpLCAxKTtcbiAgICB9XG4gICAgdGhpcy5vbmdvaW5nU2NvcGVzJC5uZXh0KG5ld1Njb3Blcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRydWUgaWYgcHJvdmlkZWQgc2NvcGVzIGFyZSBub3QgcGFydCBvZiBvbmdvaW5nU2NvcGVzXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZXNcbiAgICogQHBhcmFtIG9uZ29pbmdTY29wZXNcbiAgICovXG4gIHByb3RlY3RlZCBhcmVSZWFkeShzY29wZXM6IHN0cmluZ1tdLCBvbmdvaW5nU2NvcGVzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIGlmICghc2NvcGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuICFvbmdvaW5nU2NvcGVzLmxlbmd0aDtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICAgIGZvciAoY29uc3Qgb25nb2luZ1Njb3BlIG9mIG9uZ29pbmdTY29wZXMpIHtcbiAgICAgICAgaWYgKHRoaXMuc2NvcGVzT3ZlcmxhcChzY29wZSwgb25nb2luZ1Njb3BlKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0d28gc2NvcGVzIG92ZXJsYXAuXG4gICAqXG4gICAqIEV4YW1wbGUgb2Ygc2NvcGVzIHRoYXQgb3ZlcmxhcDpcbiAgICogJ3Rlc3QnIGFuZCAndGVzdCcsICd0ZXN0LmEnIGFuZCAndGVzdCcsICd0ZXN0JyBhbmQgJ3Rlc3QuYSdcbiAgICpcbiAgICogRXhhbXBsZSBvZiBzY29wZXMgdGhhdCBkbyBub3Qgb3ZlcmxhcDpcbiAgICogJ3Rlc3QnIGFuZCAndGVzdEEnLCAndGVzdC5hJyBhbmQgJ3Rlc3QuYicsICd0ZXN0Lm5lc3RlZCcgYW5kICd0ZXN0Lm5lc3QnXG4gICAqXG4gICAqIEBwYXJhbSBhIFNjb3BlQVxuICAgKiBAcGFyYW0gYiBTY29wZUJcbiAgICovXG4gIHByb3RlY3RlZCBzY29wZXNPdmVybGFwKGE6IHN0cmluZywgYjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGIubGVuZ3RoID4gYS5sZW5ndGgpIHtcbiAgICAgIFthLCBiXSA9IFtiLCBhXTtcbiAgICB9XG4gICAgcmV0dXJuIGEuc3RhcnRzV2l0aChiKSAmJiAoYVtiLmxlbmd0aF0gfHwgJy4nKSA9PT0gJy4nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKlxuICAgKiBOb3QgYSBwYXJ0IG9mIGEgcHVibGljIEFQSSwgdXNlZCBieSBBUFBfSU5JVElBTElaRVIgdG8gaW5pdGlhbGl6ZSBhbGwgcHJvdmlkZWQgQ09ORklHX0lOSVRJQUxJWkVSU1xuICAgKlxuICAgKi9cbiAgYXN5bmMgaW5pdGlhbGl6ZShpbml0aWFsaXplcnM/OiBDb25maWdJbml0aWFsaXplcltdKSB7XG4gICAgaWYgKHRoaXMub25nb2luZ1Njb3BlcyQudmFsdWUpIHtcbiAgICAgIC8vIGd1YXJkIGZvciBkb3VibGUgaW5pdGlhbGl6YXRpb25cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvbmdvaW5nU2NvcGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgY29uc3QgYXN5bmNDb25maWdzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgaW5pdGlhbGl6ZXIgb2YgaW5pdGlhbGl6ZXJzIHx8IFtdKSB7XG4gICAgICBpZiAoIWluaXRpYWxpemVyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFpbml0aWFsaXplci5zY29wZXMgfHwgIWluaXRpYWxpemVyLnNjb3Blcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDT05GSUdfSU5JVElBTElaRVIgc2hvdWxkIHByb3ZpZGUgc2NvcGUhJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0Rldk1vZGUoKSAmJiAhdGhpcy5hcmVSZWFkeShpbml0aWFsaXplci5zY29wZXMsIG9uZ29pbmdTY29wZXMpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAnTW9yZSB0aGFuIG9uZSBDT05GSUdfSU5JVElBTElaRVIgaXMgaW5pdGlhbGl6aW5nIHRoZSBzYW1lIGNvbmZpZyBzY29wZS4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIG9uZ29pbmdTY29wZXMucHVzaCguLi5pbml0aWFsaXplci5zY29wZXMpO1xuXG4gICAgICBhc3luY0NvbmZpZ3MucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBpbml0aWFsaXplckNvbmZpZyA9IGF3YWl0IGluaXRpYWxpemVyLmNvbmZpZ0ZhY3RvcnkoKTtcbiAgICAgICAgICAvLyBjb250cmlidXRlIGNvbmZpZ3VyYXRpb24gdG8gcm9vdENvbmZpZ1xuICAgICAgICAgIGRlZXBNZXJnZShcbiAgICAgICAgICAgIHRoaXMucm9vdENvbmZpZyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgICAgIGluaXRpYWxpemVyQ29uZmlnXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyBjb250cmlidXRlIGNvbmZpZ3VyYXRpb24gdG8gZ2xvYmFsIGNvbmZpZ1xuICAgICAgICAgIGRlZXBNZXJnZSh0aGlzLmNvbmZpZyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgaW5pdGlhbGl6ZXJDb25maWcpO1xuICAgICAgICAgIHRoaXMuZmluaXNoU2NvcGVzKGluaXRpYWxpemVyLnNjb3Blcyk7XG4gICAgICAgIH0pKClcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMub25nb2luZ1Njb3BlcyQubmV4dChvbmdvaW5nU2NvcGVzKTtcblxuICAgIGlmIChhc3luY0NvbmZpZ3MubGVuZ3RoKSB7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChhc3luY0NvbmZpZ3MpO1xuICAgIH1cbiAgfVxufVxuIl19