@spartacus/storefront
Version:
Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.
209 lines • 28.1 kB
JavaScript
import { isPlatformServer } from '@angular/common';
import { Inject, Injectable, isDevMode, PLATFORM_ID, } from '@angular/core';
import { deepMerge, } from '@spartacus/core';
import { defer, forkJoin, of } from 'rxjs';
import { mapTo, share, tap } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@spartacus/core";
import * as i2 from "./cms-features.service";
/**
* Service with logic related to resolving component from cms mapping
*/
export class CmsComponentsService {
constructor(config, platformId, featureModules, configInitializer) {
this.config = config;
this.platformId = platformId;
this.featureModules = featureModules;
this.configInitializer = configInitializer;
// Component mappings that were identified as missing
this.missingComponents = [];
// Already resolved mappings
this.mappings = {};
// Contains already initialized resolvers for specified component typez
this.mappingResolvers = new Map();
this.configInitializer
.getStable('cmsComponents')
.subscribe((cmsConfig) => {
// we want to grab cms configuration available at config initialization phase
// as lazy-loaded modules can affect global configuration resulting in
// non-deterministic state
this.staticCmsConfig = Object.assign({}, cmsConfig.cmsComponents);
});
}
/**
* Should be called to make sure all component mappings are determined,
* especially lazy loaded ones.
*
* It's recommended way to make sure all other methods of CmsComponentService
* will be able to work synchronously for asked component types and avoid risk
* of potential errors that could be thrown otherwise.
*/
determineMappings(componentTypes) {
return defer(() => {
var _a, _b;
// we use defer, to be sure the logic below used to compose final observable
// will be executed at subscription time (with up to date state at the time,
// when it will be needed)
const featureResolvers = [];
for (const componentType of componentTypes) {
if (!this.mappings[componentType]) {
const staticConfig = (_b = ((_a = this.staticCmsConfig) !== null && _a !== void 0 ? _a : this.config.cmsComponents)) === null || _b === void 0 ? void 0 : _b[componentType];
// check if this component type is managed by feature module
if (this.featureModules.hasFeatureFor(componentType)) {
featureResolvers.push(
// we delegate populating this.mappings to feature resolver
this.getFeatureMappingResolver(componentType, staticConfig));
}
else {
// simply use only static config
this.mappings[componentType] = staticConfig;
}
}
}
if (featureResolvers.length) {
return forkJoin(featureResolvers).pipe(mapTo(componentTypes));
}
else {
return of(componentTypes);
}
});
}
getFeatureMappingResolver(componentType, staticConfig) {
if (!this.mappingResolvers.has(componentType)) {
const mappingResolver$ = this.featureModules
.getCmsMapping(componentType)
.pipe(tap((featureComponentMapping) => {
// We treat cms mapping configuration from a feature as a default,
// that can be overridden by app/static configuration
this.mappings[componentType] = deepMerge({}, featureComponentMapping, staticConfig);
this.mappingResolvers.delete(componentType);
}), share());
this.mappingResolvers.set(componentType, mappingResolver$);
}
return this.mappingResolvers.get(componentType);
}
/**
* Returns the feature module for a cms component.
* It will only work for cms components provided by feature modules.
*
* @param componentType
*/
getModule(componentType) {
return (this.featureModules.hasFeatureFor(componentType) &&
this.featureModules.getModule(componentType));
}
/**
* Return collection of component mapping configuration for specified list of
* component types.
*
* If component mapping can't be determined synchronously, for example, lazy
* loaded one, it will throw an error.
*
* To make sure component mapping is available, determineMappings()
* should be called and completed first.
*/
getMapping(componentType) {
var _a, _b, _c;
const componentConfig = (_a = this.mappings[componentType]) !== null && _a !== void 0 ? _a : (_c = ((_b = this.staticCmsConfig) !== null && _b !== void 0 ? _b : this.config.cmsComponents)) === null || _c === void 0 ? void 0 : _c[componentType];
if (isDevMode() && !componentConfig) {
if (!this.missingComponents.includes(componentType)) {
this.missingComponents.push(componentType);
console.warn(`No component implementation found for the CMS component type '${componentType}'.\n`, `Make sure you implement a component and register it in the mapper.`);
}
}
return componentConfig;
}
/**
* Checks, if component should be rendered as some components
* could be disabled for server side renderings
*/
shouldRender(componentType) {
var _a;
const isSSR = isPlatformServer(this.platformId);
return !(isSSR && ((_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.disableSSR));
}
/**
* Return DeferLoadingStrategy for component type.
*/
getDeferLoadingStrategy(componentType) {
var _a, _b, _c;
return (_c = (_b = ((_a = this.staticCmsConfig) !== null && _a !== void 0 ? _a : this.config.cmsComponents)) === null || _b === void 0 ? void 0 : _b[componentType]) === null || _c === void 0 ? void 0 : _c.deferLoading;
}
/**
* Get cms driven child routes for components
*/
getChildRoutes(componentTypes) {
var _a, _b;
const configs = [];
for (const componentType of componentTypes) {
if (this.shouldRender(componentType)) {
configs.push((_b = (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.childRoutes) !== null && _b !== void 0 ? _b : []);
}
}
return this.standardizeChildRoutes(configs);
}
/**
* Returns the static data for the component type.
*/
getStaticData(componentType) {
var _a;
return (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.data;
}
/**
* Standardizes the format of `childRoutes` config.
*
* Some `childRoutes` configs are simple arrays of Routes (without the notion of the parent route).
* But some configs can be an object with children routes and their parent defined in separate property.
*/
standardizeChildRoutes(childRoutesConfigs) {
const result = { children: [] };
(childRoutesConfigs || []).forEach((config) => {
if (Array.isArray(config)) {
result.children.push(...config);
}
else {
result.children.push(...(config.children || []));
if (config.parent) {
result.parent = config.parent;
}
}
});
return result;
}
/**
* Get cms driven guards for components
*/
getGuards(componentTypes) {
var _a, _b;
const guards = new Set();
for (const componentType of componentTypes) {
(_b = (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.guards) === null || _b === void 0 ? void 0 : _b.forEach((guard) => guards.add(guard));
}
return Array.from(guards);
}
/**
* Get i18n keys associated with components
*/
getI18nKeys(componentTypes) {
var _a, _b;
const i18nKeys = new Set();
for (const componentType of componentTypes) {
if (this.shouldRender(componentType)) {
(_b = (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.i18nKeys) === null || _b === void 0 ? void 0 : _b.forEach((key) => i18nKeys.add(key));
}
}
return Array.from(i18nKeys);
}
}
CmsComponentsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CmsComponentsService, deps: [{ token: i1.CmsConfig }, { token: PLATFORM_ID }, { token: i2.CmsFeaturesService }, { token: i1.ConfigInitializerService }], target: i0.ɵɵFactoryTarget.Injectable });
CmsComponentsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CmsComponentsService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CmsComponentsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.CmsConfig }, { type: Object, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: i2.CmsFeaturesService }, { type: i1.ConfigInitializerService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY21zLWNvbXBvbmVudHMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLXN0cnVjdHVyZS9zZXJ2aWNlcy9jbXMtY29tcG9uZW50cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFDTCxNQUFNLEVBQ04sVUFBVSxFQUNWLFNBQVMsRUFFVCxXQUFXLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQU9MLFNBQVMsR0FFVixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2RCxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUduRDs7R0FFRztBQUlILE1BQU0sT0FBTyxvQkFBb0I7SUFjL0IsWUFDWSxNQUFpQixFQUNJLFVBQWtCLEVBQ3ZDLGNBQWtDLEVBQ2xDLGlCQUEyQztRQUgzQyxXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ0ksZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUN2QyxtQkFBYyxHQUFkLGNBQWMsQ0FBb0I7UUFDbEMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUEwQjtRQWpCdkQscURBQXFEO1FBQzNDLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztRQUUzQyw0QkFBNEI7UUFDbEIsYUFBUSxHQUFxRCxFQUFFLENBQUM7UUFLMUUsdUVBQXVFO1FBQzdELHFCQUFnQixHQUN4QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBUVYsSUFBSSxDQUFDLGlCQUFpQjthQUNuQixTQUFTLENBQUMsZUFBZSxDQUFDO2FBQzFCLFNBQVMsQ0FBQyxDQUFDLFNBQW9CLEVBQUUsRUFBRTtZQUNsQyw2RUFB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S0FBSyxDQUFDLENBQ2xCLENBQUM7U0FDSDtRQUNELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXLENBQUMsY0FBd0I7O1FBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDbkMsS0FBSyxNQUFNLGFBQWEsSUFBSSxjQUFjLEVBQUU7WUFDMUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNwQyxNQUFBLE1BQUEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsMENBQUUsUUFBUSwwQ0FBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUN4RCxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUNsQixDQUFDO2FBQ0g7U0FDRjtRQUNELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QixDQUFDOztpSEF0T1Usb0JBQW9CLDJDQWdCckIsV0FBVztxSEFoQlYsb0JBQW9CLGNBRm5CLE1BQU07MkZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjtrRkFpQjhDLE1BQU07MEJBQWhELE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgSW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBpc0Rldk1vZGUsXG4gIE5nTW9kdWxlUmVmLFxuICBQTEFURk9STV9JRCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICBDbXNDb21wb25lbnQsXG4gIENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnLFxuICBDTVNDb21wb25lbnRDb25maWcsXG4gIENtc0NvbXBvbmVudE1hcHBpbmcsXG4gIENtc0NvbmZpZyxcbiAgQ29uZmlnSW5pdGlhbGl6ZXJTZXJ2aWNlLFxuICBkZWVwTWVyZ2UsXG4gIERlZmVyTG9hZGluZ1N0cmF0ZWd5LFxufSBmcm9tICdAc3BhcnRhY3VzL2NvcmUnO1xuaW1wb3J0IHsgZGVmZXIsIGZvcmtKb2luLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwVG8sIHNoYXJlLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDbXNGZWF0dXJlc1NlcnZpY2UgfSBmcm9tICcuL2Ntcy1mZWF0dXJlcy5zZXJ2aWNlJztcblxuLyoqXG4gKiBTZXJ2aWNlIHdpdGggbG9naWMgcmVsYXRlZCB0byByZXNvbHZpbmcgY29tcG9uZW50IGZyb20gY21zIG1hcHBpbmdcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIENtc0NvbXBvbmVudHNTZXJ2aWNlIHtcbiAgLy8gQ29tcG9uZW50IG1hcHBpbmdzIHRoYXQgd2VyZSBpZGVudGlmaWVkIGFzIG1pc3NpbmdcbiAgcHJvdGVjdGVkIG1pc3NpbmdDb21wb25lbnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIEFscmVhZHkgcmVzb2x2ZWQgbWFwcGluZ3NcbiAgcHJvdGVjdGVkIG1hcHBpbmdzOiB7IFtjb21wb25lbnRUeXBlOiBzdHJpbmddOiBDbXNDb21wb25lbnRNYXBwaW5nIH0gPSB7fTtcblxuICAvLyBDb3B5IG9mIGluaXRpYWwvc3RhdGljIGNtcyBtYXBwaW5nIGNvbmZpZ3VyYXRpb24gdW5hZmZlY3RlZCBieSBsYXp5LWxvYWRlZCBtb2R1bGVzXG4gIHByb3RlY3RlZCBzdGF0aWNDbXNDb25maWc6IENNU0NvbXBvbmVudENvbmZpZyB8IHVuZGVmaW5lZDtcblxuICAvLyBDb250YWlucyBhbHJlYWR5IGluaXRpYWxpemVkIHJlc29sdmVycyBmb3Igc3BlY2lmaWVkIGNvbXBvbmVudCB0eXBlelxuICBwcm90ZWN0ZWQgbWFwcGluZ1Jlc29sdmVyczogTWFwPHN0cmluZywgT2JzZXJ2YWJsZTxDbXNDb21wb25lbnRNYXBwaW5nPj4gPVxuICAgIG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgY29uZmlnOiBDbXNDb25maWcsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJvdGVjdGVkIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBwcm90ZWN0ZWQgZmVhdHVyZU1vZHVsZXM6IENtc0ZlYXR1cmVzU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY29uZmlnSW5pdGlhbGl6ZXI6IENvbmZpZ0luaXRpYWxpemVyU2VydmljZVxuICApIHtcbiAgICB0aGlzLmNvbmZpZ0luaXRpYWxpemVyXG4gICAgICAuZ2V0U3RhYmxlKCdjbXNDb21wb25lbnRzJylcbiAgICAgIC5zdWJzY3JpYmUoKGNtc0NvbmZpZzogQ21zQ29uZmlnKSA9PiB7XG4gICAgICAgIC8vIHdlIHdhbnQgdG8gZ3JhYiBjbXMgY29uZmlndXJhdGlvbiBhdmFpbGFibGUgYXQgY29uZmlnIGluaXRpYWxpemF0aW9uIHBoYXNlXG4gICAgICAgIC8vIGFzIGxhenktbG9hZGVkIG1vZHVsZXMgY2FuIGFmZmVjdCBnbG9iYWwgY29uZmlndXJhdGlvbiByZXN1bHRpbmcgaW5cbiAgICAgICAgLy8gbm9uLWRldGVybWluaXN0aWMgc3RhdGVcbiAgICAgICAgdGhpcy5zdGF0aWNDbXNDb25maWcgPSB7IC4uLmNtc0NvbmZpZy5jbXNDb21wb25lbnRzIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaG91bGQgYmUgY2FsbGVkIHRvIG1ha2Ugc3VyZSBhbGwgY29tcG9uZW50IG1hcHBpbmdzIGFyZSBkZXRlcm1pbmVkLFxuICAgKiBlc3BlY2lhbGx5IGxhenkgbG9hZGVkIG9uZXMuXG4gICAqXG4gICAqIEl0J3MgcmVjb21tZW5kZWQgd2F5IHRvIG1ha2Ugc3VyZSBhbGwgb3RoZXIgbWV0aG9kcyBvZiBDbXNDb21wb25lbnRTZXJ2aWNlXG4gICAqIHdpbGwgYmUgYWJsZSB0byB3b3JrIHN5bmNocm9ub3VzbHkgZm9yIGFza2VkIGNvbXBvbmVudCB0eXBlcyBhbmQgYXZvaWQgcmlza1xuICAgKiBvZiBwb3RlbnRpYWwgZXJyb3JzIHRoYXQgY291bGQgYmUgdGhyb3duIG90aGVyd2lzZS5cbiAgICovXG4gIGRldGVybWluZU1hcHBpbmdzKGNvbXBvbmVudFR5cGVzOiBzdHJpbmdbXSk6IE9ic2VydmFibGU8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gZGVmZXIoKCkgPT4ge1xuICAgICAgLy8gd2UgdXNlIGRlZmVyLCB0byBiZSBzdXJlIHRoZSBsb2dpYyBiZWxvdyB1c2VkIHRvIGNvbXBvc2UgZmluYWwgb2JzZXJ2YWJsZVxuICAgICAgLy8gd2lsbCBiZSBleGVjdXRlZCBhdCBzdWJzY3JpcHRpb24gdGltZSAod2l0aCB1cCB0byBkYXRlIHN0YXRlIGF0IHRoZSB0aW1lLFxuICAgICAgLy8gd2hlbiBpdCB3aWxsIGJlIG5lZWRlZClcbiAgICAgIGNvbnN0IGZlYXR1cmVSZXNvbHZlcnMgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjb21wb25lbnRUeXBlIG9mIGNvbXBvbmVudFR5cGVzKSB7XG4gICAgICAgIGlmICghdGhpcy5tYXBwaW5nc1tjb21wb25lbnRUeXBlXSkge1xuICAgICAgICAgIGNvbnN0IHN0YXRpY0NvbmZpZyA9ICh0aGlzLnN0YXRpY0Ntc0NvbmZpZyA/P1xuICAgICAgICAgICAgdGhpcy5jb25maWcuY21zQ29tcG9uZW50cyk/Lltjb21wb25lbnRUeXBlXTtcblxuICAgICAgICAgIC8vIGNoZWNrIGlmIHRoaXMgY29tcG9uZW50IHR5cGUgaXMgbWFuYWdlZCBieSBmZWF0dXJlIG1vZHVsZVxuICAgICAgICAgIGlmICh0aGlzLmZlYXR1cmVNb2R1bGVzLmhhc0ZlYXR1cmVGb3IoY29tcG9uZW50VHlwZSkpIHtcbiAgICAgICAgICAgIGZlYXR1cmVSZXNvbHZlcnMucHVzaChcbiAgICAgICAgICAgICAgLy8gd2UgZGVsZWdhdGUgcG9wdWxhdGluZyB0aGlzLm1hcHBpbmdzIHRvIGZlYXR1cmUgcmVzb2x2ZXJcbiAgICAgICAgICAgICAgdGhpcy5nZXRGZWF0dXJlTWFwcGluZ1Jlc29sdmVyKGNvbXBvbmVudFR5cGUsIHN0YXRpY0NvbmZpZylcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNpbXBseSB1c2Ugb25seSBzdGF0aWMgY29uZmlnXG4gICAgICAgICAgICB0aGlzLm1hcHBpbmdzW2NvbXBvbmVudFR5cGVdID0gc3RhdGljQ29uZmlnO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmVhdHVyZVJlc29sdmVycy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKGZlYXR1cmVSZXNvbHZlcnMpLnBpcGUobWFwVG8oY29tcG9uZW50VHlwZXMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvZihjb21wb25lbnRUeXBlcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZlYXR1cmVNYXBwaW5nUmVzb2x2ZXIoXG4gICAgY29tcG9uZW50VHlwZTogc3RyaW5nLFxuICAgIHN0YXRpY0NvbmZpZz86IENtc0NvbXBvbmVudE1hcHBpbmdcbiAgKTogT2JzZXJ2YWJsZTxDbXNDb21wb25lbnRNYXBwaW5nPiB7XG4gICAgaWYgKCF0aGlzLm1hcHBpbmdSZXNvbHZlcnMuaGFzKGNvbXBvbmVudFR5cGUpKSB7XG4gICAgICBjb25zdCBtYXBwaW5nUmVzb2x2ZXIkID0gdGhpcy5mZWF0dXJlTW9kdWxlc1xuICAgICAgICAuZ2V0Q21zTWFwcGluZyhjb21wb25lbnRUeXBlKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoKGZlYXR1cmVDb21wb25lbnRNYXBwaW5nKSA9PiB7XG4gICAgICAgICAgICAvLyBXZSB0cmVhdCBjbXMgbWFwcGluZyBjb25maWd1cmF0aW9uIGZyb20gYSBmZWF0dXJlIGFzIGEgZGVmYXVsdCxcbiAgICAgICAgICAgIC8vIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gYnkgYXBwL3N0YXRpYyBjb25maWd1cmF0aW9uXG4gICAgICAgICAgICB0aGlzLm1hcHBpbmdzW2NvbXBvbmVudFR5cGVdID0gZGVlcE1lcmdlKFxuICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgZmVhdHVyZUNvbXBvbmVudE1hcHBpbmcsXG4gICAgICAgICAgICAgIHN0YXRpY0NvbmZpZ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubWFwcGluZ1Jlc29sdmVycy5kZWxldGUoY29tcG9uZW50VHlwZSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgc2hhcmUoKVxuICAgICAgICApO1xuICAgICAgdGhpcy5tYXBwaW5nUmVzb2x2ZXJzLnNldChjb21wb25lbnRUeXBlLCBtYXBwaW5nUmVzb2x2ZXIkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubWFwcGluZ1Jlc29sdmVycy5nZXQoY29tcG9uZW50VHlwZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZmVhdHVyZSBtb2R1bGUgZm9yIGEgY21zIGNvbXBvbmVudC5cbiAgICogSXQgd2lsbCBvbmx5IHdvcmsgZm9yIGNtcyBjb21wb25lbnRzIHByb3ZpZGVkIGJ5IGZlYXR1cmUgbW9kdWxlcy5cbiAgICpcbiAgICogQHBhcmFtIGNvbXBvbmVudFR5cGVcbiAgICovXG4gIGdldE1vZHVsZShjb21wb25lbnRUeXBlOiBzdHJpbmcpOiBOZ01vZHVsZVJlZjxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5mZWF0dXJlTW9kdWxlcy5oYXNGZWF0dXJlRm9yKGNvbXBvbmVudFR5cGUpICYmXG4gICAgICB0aGlzLmZlYXR1cmVNb2R1bGVzLmdldE1vZHVsZShjb21wb25lbnRUeXBlKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGNvbGxlY3Rpb24gb2YgY29tcG9uZW50IG1hcHBpbmcgY29uZmlndXJhdGlvbiBmb3Igc3BlY2lmaWVkIGxpc3Qgb2ZcbiAgICogY29tcG9uZW50IHR5cGVzLlxuICAgKlxuICAgKiBJZiBjb21wb25lbnQgbWFwcGluZyBjYW4ndCBiZSBkZXRlcm1pbmVkIHN5bmNocm9ub3VzbHksIGZvciBleGFtcGxlLCBsYXp5XG4gICAqIGxvYWRlZCBvbmUsIGl0IHdpbGwgdGhyb3cgYW4gZXJyb3IuXG4gICAqXG4gICAqIFRvIG1ha2Ugc3VyZSBjb21wb25lbnQgbWFwcGluZyBpcyBhdmFpbGFibGUsIGRldGVybWluZU1hcHBpbmdzKClcbiAgICogc2hvdWxkIGJlIGNhbGxlZCBhbmQgY29tcGxldGVkIGZpcnN0LlxuICAgKi9cbiAgZ2V0TWFwcGluZyhjb21wb25lbnRUeXBlOiBzdHJpbmcpOiBDbXNDb21wb25lbnRNYXBwaW5nIHtcbiAgICBjb25zdCBjb21wb25lbnRDb25maWcgPVxuICAgICAgdGhpcy5tYXBwaW5nc1tjb21wb25lbnRUeXBlXSA/P1xuICAgICAgKHRoaXMuc3RhdGljQ21zQ29uZmlnID8/IHRoaXMuY29uZmlnLmNtc0NvbXBvbmVudHMpPy5bY29tcG9uZW50VHlwZV07XG5cbiAgICBpZiAoaXNEZXZNb2RlKCkgJiYgIWNvbXBvbmVudENvbmZpZykge1xuICAgICAgaWYgKCF0aGlzLm1pc3NpbmdDb21wb25lbnRzLmluY2x1ZGVzKGNvbXBvbmVudFR5cGUpKSB7XG4gICAgICAgIHRoaXMubWlzc2luZ0NvbXBvbmVudHMucHVzaChjb21wb25lbnRUeXBlKTtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBObyBjb21wb25lbnQgaW1wbGVtZW50YXRpb24gZm91bmQgZm9yIHRoZSBDTVMgY29tcG9uZW50IHR5cGUgJyR7Y29tcG9uZW50VHlwZX0nLlxcbmAsXG4gICAgICAgICAgYE1ha2Ugc3VyZSB5b3UgaW1wbGVtZW50IGEgY29tcG9uZW50IGFuZCByZWdpc3RlciBpdCBpbiB0aGUgbWFwcGVyLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29tcG9uZW50Q29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcywgaWYgY29tcG9uZW50IHNob3VsZCBiZSByZW5kZXJlZCBhcyBzb21lIGNvbXBvbmVudHNcbiAgICogY291bGQgYmUgZGlzYWJsZWQgZm9yIHNlcnZlciBzaWRlIHJlbmRlcmluZ3NcbiAgICovXG4gIHNob3VsZFJlbmRlcihjb21wb25lbnRUeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBpc1NTUiA9IGlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5wbGF0Zm9ybUlkKTtcbiAgICByZXR1cm4gIShpc1NTUiAmJiB0aGlzLmdldE1hcHBpbmcoY29tcG9uZW50VHlwZSk/LmRpc2FibGVTU1IpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBEZWZlckxvYWRpbmdTdHJhdGVneSBmb3IgY29tcG9uZW50IHR5cGUuXG4gICAqL1xuICBnZXREZWZlckxvYWRpbmdTdHJhdGVneShcbiAgICBjb21wb25lbnRUeXBlOiBzdHJpbmdcbiAgKTogRGVmZXJMb2FkaW5nU3RyYXRlZ3kgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiAodGhpcy5zdGF0aWNDbXNDb25maWcgPz8gdGhpcy5jb25maWcuY21zQ29tcG9uZW50cyk/Lltjb21wb25lbnRUeXBlXVxuICAgICAgPy5kZWZlckxvYWRpbmc7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNtcyBkcml2ZW4gY2hpbGQgcm91dGVzIGZvciBjb21wb25lbnRzXG4gICAqL1xuICBnZXRDaGlsZFJvdXRlcyhjb21wb25lbnRUeXBlczogc3RyaW5nW10pOiBDbXNDb21wb25lbnRDaGlsZFJvdXRlc0NvbmZpZyB7XG4gICAgY29uc3QgY29uZmlncyA9IFtdO1xuICAgIGZvciAoY29uc3QgY29tcG9uZW50VHlwZSBvZiBjb21wb25lbnRUeXBlcykge1xuICAgICAgaWYgKHRoaXMuc2hvdWxkUmVuZGVyKGNvbXBvbmVudFR5cGUpKSB7XG4gICAgICAgIGNvbmZpZ3MucHVzaCh0aGlzLmdldE1hcHBpbmcoY29tcG9uZW50VHlwZSk/LmNoaWxkUm91dGVzID8/IFtdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdGFuZGFyZGl6ZUNoaWxkUm91dGVzKGNvbmZpZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHN0YXRpYyBkYXRhIGZvciB0aGUgY29tcG9uZW50IHR5cGUuXG4gICAqL1xuICBnZXRTdGF0aWNEYXRhPFQgZXh0ZW5kcyBDbXNDb21wb25lbnQgPSBDbXNDb21wb25lbnQ+KFxuICAgIGNvbXBvbmVudFR5cGU6IHN0cmluZ1xuICApOiBUIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNYXBwaW5nKGNvbXBvbmVudFR5cGUpPy5kYXRhIGFzIFQ7XG4gIH1cblxuICAvKipcbiAgICogU3RhbmRhcmRpemVzIHRoZSBmb3JtYXQgb2YgYGNoaWxkUm91dGVzYCBjb25maWcuXG4gICAqXG4gICAqIFNvbWUgYGNoaWxkUm91dGVzYCBjb25maWdzIGFyZSBzaW1wbGUgYXJyYXlzIG9mIFJvdXRlcyAod2l0aG91dCB0aGUgbm90aW9uIG9mIHRoZSBwYXJlbnQgcm91dGUpLlxuICAgKiBCdXQgc29tZSBjb25maWdzIGNhbiBiZSBhbiBvYmplY3Qgd2l0aCBjaGlsZHJlbiByb3V0ZXMgYW5kIHRoZWlyIHBhcmVudCBkZWZpbmVkIGluIHNlcGFyYXRlIHByb3BlcnR5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YW5kYXJkaXplQ2hpbGRSb3V0ZXMoXG4gICAgY2hpbGRSb3V0ZXNDb25maWdzOiAoUm91dGVbXSB8IENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnKVtdXG4gICk6IENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnIHtcbiAgICBjb25zdCByZXN1bHQ6IENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnID0geyBjaGlsZHJlbjogW10gfTtcblxuICAgIChjaGlsZFJvdXRlc0NvbmZpZ3MgfHwgW10pLmZvckVhY2goKGNvbmZpZykgPT4ge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29uZmlnKSkge1xuICAgICAgICByZXN1bHQuY2hpbGRyZW4ucHVzaCguLi5jb25maWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LmNoaWxkcmVuLnB1c2goLi4uKGNvbmZpZy5jaGlsZHJlbiB8fCBbXSkpO1xuICAgICAgICBpZiAoY29uZmlnLnBhcmVudCkge1xuICAgICAgICAgIHJlc3VsdC5wYXJlbnQgPSBjb25maWcucGFyZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjbXMgZHJpdmVuIGd1YXJkcyBmb3IgY29tcG9uZW50c1xuICAgKi9cbiAgZ2V0R3VhcmRzKGNvbXBvbmVudFR5cGVzOiBzdHJpbmdbXSk6IGFueVtdIHtcbiAgICBjb25zdCBndWFyZHMgPSBuZXcgU2V0PGFueT4oKTtcbiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudFR5cGUgb2YgY29tcG9uZW50VHlwZXMpIHtcbiAgICAgIHRoaXMuZ2V0TWFwcGluZyhjb21wb25lbnRUeXBlKT8uZ3VhcmRzPy5mb3JFYWNoKChndWFyZCkgPT5cbiAgICAgICAgZ3VhcmRzLmFkZChndWFyZClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKGd1YXJkcyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGkxOG4ga2V5cyBhc3NvY2lhdGVkIHdpdGggY29tcG9uZW50c1xuICAgKi9cbiAgZ2V0STE4bktleXMoY29tcG9uZW50VHlwZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGkxOG5LZXlzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCBjb21wb25lbnRUeXBlIG9mIGNvbXBvbmVudFR5cGVzKSB7XG4gICAgICBpZiAodGhpcy5zaG91bGRSZW5kZXIoY29tcG9uZW50VHlwZSkpIHtcbiAgICAgICAgdGhpcy5nZXRNYXBwaW5nKGNvbXBvbmVudFR5cGUpPy5pMThuS2V5cz8uZm9yRWFjaCgoa2V5KSA9PlxuICAgICAgICAgIGkxOG5LZXlzLmFkZChrZXkpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKGkxOG5LZXlzKTtcbiAgfVxufVxuIl19