UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

247 lines • 36.9 kB
import { Injector } from '@angular/core'; import { NavigationEnd } from '@angular/router'; import { castArray, flatten, groupBy, sortBy, uniq } from 'lodash-es'; import { BehaviorSubject, combineLatest, defer, from, isObservable, merge, of, race, Subject } from 'rxjs'; import { filter, map, startWith, switchMap } from 'rxjs/operators'; import { StateService } from './state-service.abstract'; export function fromTrigger(router, refresh, factories) { return merge(router.events.pipe(filter(evt => evt instanceof NavigationEnd)), ...castArray(refresh)).pipe(startWith(1), switchMap(() => fromFactories(factories, router))); } export function fromTriggerOnce(router, refresh, factories) { return merge(...castArray(refresh)).pipe(startWith(1), switchMap(() => fromFactories(factories, router))); } export var InjectionType; (function (InjectionType) { InjectionType[InjectionType["COMPONENT"] = 0] = "COMPONENT"; InjectionType[InjectionType["ROUTE"] = 1] = "ROUTE"; })(InjectionType || (InjectionType = {})); export class StandalonePluginInjector extends Injector { /** * @deprecated Use `constructor` instead. */ static create(..._args) { throw Error('Not implemented'); } constructor(options) { super(); this.options = options; this.injector = Injector.create(options); } get name() { return this.options.name; } get(token, notFoundValue, options) { return this.injector.get(token, notFoundValue, options); } } export function getInjectedHooks(token, injectors, type = InjectionType.COMPONENT) { return () => flatten(injectors.map(injector => { const factoryOrFactories = injector.get(token, [], { self: true }); const factories = Array.isArray(factoryOrFactories) ? flatten(factoryOrFactories) : [factoryOrFactories]; if (injector.scopes?.has('root')) { return factories; } if (injector instanceof StandalonePluginInjector) { // No need to set injector for items retrieved from standalone plugins return factories; } factories.forEach((factory) => { if (!factory.get && factory.injector !== null) { if (type === InjectionType.ROUTE) { factory._injector = injector; } else { factory.injector = injector; } } }); return factories; })); } export function fromFactories(factories, router, withFirstEmpty = true) { return !Array.isArray(factories) || factories.length < 1 ? of([]) : defer(() => { const factoryObservables = resolveInjectedFactories(factories).map(f => { if (Array.isArray(f)) { return toObservableOfArrays(f, withFirstEmpty); } if (isExtensionFactory(f)) { return toObservableOfArrays(f.get(getActivatedRoute(router)), withFirstEmpty); } return toObservableOfArrays([f], withFirstEmpty); }); return combineLatest(factoryObservables); }).pipe(map(results => sortByPriority([].concat(...results))), map(value => uniq(value))); } export function resolveInjectedFactories(factories) { return flatten(factories.map(f => { if (typeof f === 'function') { const func = f; return func(); } return [f]; })); } export function stateToFactory(componentsState) { const components$ = componentsState.pipe(map((componentSet) => [...componentSet])); return { get: () => components$ }; } export function sortByPriority(items) { return sortBy(items, item => -(item?.priority || 0)); } export function removeDuplicatesIds(items) { const grouped = groupBy(items, 'id'); const itemsWithoutDuplicates = new Array(); for (const key of Object.keys(grouped)) { if (key && key !== 'undefined') { const sortedByPrio = sortByPriority(grouped[key]); itemsWithoutDuplicates.push(sortedByPrio[0]); } else { itemsWithoutDuplicates.push(...grouped[key]); } } return sortByPriority(itemsWithoutDuplicates); } export function toObservableOfArrays(factoryResult, withFirstEmpty) { let observable; if (!factoryResult) { return of([]); } else { observable = toObservable(factoryResult); if (withFirstEmpty) { const withEmptyFirst = observable.pipe(startWith([])); observable = race(observable, withEmptyFirst); } } return observable.pipe(map(result => (Array.isArray(result) ? result : [result]).filter(item => !!item))); } export function isPromise(obj) { return !!obj && typeof obj.then === 'function'; } export function isExtensionFactory(obj) { return !!obj && typeof obj.get === 'function'; } /** * Converts any value provided to an Observable that emits this value once and then completes. * A convenience method to represent all the data as Observables rather than * a mixture of Observables and other types. * * @param value The value the resulting Observable will emit. */ export function toObservable(value) { if (isObservable(value)) { return value; } if (isPromise(value)) { return from(value); } return of(value); } export class ExtensionPointWithoutStateForPlugins { constructor(rootInjector, pluginService) { this.factories = []; this.refreshTrigger = new Subject(); this.injectors = [rootInjector]; pluginService.injectors$.subscribe(injector => { this.injectors.push(injector); }); this.refresh$ = merge(this.refreshTrigger, pluginService.refresh$); } /** * Refresh the extension factories */ refresh() { this.refreshTrigger.next(); } } export class ExtensionPointForPlugins extends StateService { constructor(rootInjector, pluginService) { super(); this.factories = []; this.state$ = new BehaviorSubject(new Set()); this.refreshTrigger = new Subject(); this.injectors = [rootInjector]; pluginService.injectors$.subscribe(injector => { this.injectors.push(injector); }); this.refresh$ = merge(this.refreshTrigger, pluginService.refresh$); } /** * Refresh the extension factories */ refresh() { this.refreshTrigger.next(); } } /** * Helper function to get the activated route in * a service (as ActivatedRoute injection only * works in components). Works as long as we only use * a tree and no child is active at the same time. * * @param router The current router */ export function getActivatedRoute(router) { if (router && router.routerState && router.routerState.root) { let route = router.routerState.root; while (route.firstChild) { route = route.firstChild; } return route; } } /** * A generic function to be used by specific implementations of the HOOK concept. * @param items The items that should be provided under the `useValue` or `useClass` attribute. * Allows an extension factory to be passed as an argument, which can create instances of type T. * @param token The InjectionToken/HOOK to be provided. * @param options If this is a multi provider or not (defaults to true) and provider type definition (defaults to ClassProvider) - `HookOptions`. * @returns A `Provider` (either `ValueProvider` or `ClassProvider`) to be provided in a module. */ export function hookGeneric(items, token, options) { const finalOptions = Object.assign({ multi: true, providerType: HookProviderTypes.ClassProvider }, options); const { multi, providerType } = finalOptions; if (typeof items !== 'function') { return { provide: token, useValue: items, multi }; } if (providerType === HookProviderTypes.ExistingProvider) { return { provide: token, useExisting: items, multi }; } return { provide: token, useClass: items, multi }; } export var HookProviderTypes; (function (HookProviderTypes) { HookProviderTypes["ExistingProvider"] = "ExistingProvider"; HookProviderTypes["ClassProvider"] = "ClassProvider"; })(HookProviderTypes || (HookProviderTypes = {})); export function allEntriesAreEqual(previous, next) { if (previous === next) return true; if (previous == null || next == null) return false; if (previous.length !== next.length) return false; for (let i = 0; i < previous.length; ++i) { if (previous[i] !== next[i]) return false; } return true; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9uLWhvb2tzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9jb21tb24vZXh0ZW5zaW9uLWhvb2tzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFNTCxRQUFRLEVBS1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFrQixhQUFhLEVBQVUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN0RSxPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFDYixLQUFLLEVBQ0wsSUFBSSxFQUNKLFlBQVksRUFDWixLQUFLLEVBRUwsRUFBRSxFQUNGLElBQUksRUFDSixPQUFPLEVBQ1IsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXhELE1BQU0sVUFBVSxXQUFXLENBQ3pCLE1BQWMsRUFDZCxPQUE0QyxFQUM1QyxTQU1DO0lBRUQsT0FBTyxLQUFLLENBQ1YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLGFBQWEsQ0FBQyxDQUFDLEVBQy9ELEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUN0QixDQUFDLElBQUksQ0FDSixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQ1osU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBSSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FDckQsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsZUFBZSxDQUM3QixNQUFjLEVBQ2QsT0FBNEMsRUFD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LE9BQU8sRUFBRSxLQUFLO1lBQ2QsUUFBUSxFQUFFLEtBQUs7WUFDZixLQUFLO1NBQ1csQ0FBQztJQUNyQixDQUFDO0lBRUQsSUFBSSxZQUFZLEtBQUssaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4RCxPQUFPO1lBQ0wsT0FBTyxFQUFFLEtBQUs7WUFDZCxXQUFXLEVBQUUsS0FBSztZQUNsQixLQUFLO1NBQ2MsQ0FBQztJQUN4QixDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU8sRUFBRSxLQUFLO1FBQ2QsUUFBUSxFQUFFLEtBQUs7UUFDZixLQUFLO0tBQ1csQ0FBQztBQUNyQixDQUFDO0FBTUQsTUFBTSxDQUFOLElBQVksaUJBR1g7QUFIRCxXQUFZLGlCQUFpQjtJQUMzQiwwREFBcUMsQ0FBQTtJQUNyQyxvREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBSFcsaUJBQWlCLEtBQWpCLGlCQUFpQixRQUc1QjtBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxRQUF3QixFQUFFLElBQW9CO0lBQy9FLElBQUksUUFBUSxLQUFLLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNuQyxJQUFJLFFBQVEsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNuRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLEtBQUssQ0FBQztJQUVsRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ3pDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUM1QyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2xhc3NQcm92aWRlcixcbiAgRXhpc3RpbmdQcm92aWRlcixcbiAgSW5qZWN0T3B0aW9ucyxcbiAgSW5qZWN0RmxhZ3MsXG4gIEluamVjdGlvblRva2VuLFxuICBJbmplY3RvcixcbiAgUHJvdmlkZXIsXG4gIFN0YXRpY1Byb3ZpZGVyLFxuICBUeXBlLFxuICBWYWx1ZVByb3ZpZGVyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIE5hdmlnYXRpb25FbmQsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBjYXN0QXJyYXksIGZsYXR0ZW4sIGdyb3VwQnksIHNvcnRCeSwgdW5pcSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGRlZmVyLFxuICBmcm9tLFxuICBpc09ic2VydmFibGUsXG4gIG1lcmdlLFxuICBPYnNlcnZhYmxlLFxuICBvZixcbiAgcmFjZSxcbiAgU3ViamVjdFxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCBzdGFydFdpdGgsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFBsdWdpbnNSZXNvbHZlU2VydmljZSB9IGZyb20gJy4uL3BsdWdpbnMnO1xuaW1wb3J0IHsgU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi9zdGF0ZS1zZXJ2aWNlLmFic3RyYWN0JztcblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21UcmlnZ2VyPFQ+KFxuICByb3V0ZXI6IFJvdXRlcixcbiAgcmVmcmVzaDogT2JzZXJ2YWJsZTxhbnk+IHwgT2JzZXJ2YWJsZTxhbnk+W10sXG4gIGZhY3RvcmllczogQXJyYXk8XG4gICAgfCBUXG4gICAgfCBUW11cbiAgICB8IEV4dGVuc2lvbkZhY3Rvcnk8VD5cbiAgICB8IEV4dGVuc2lvbkZhY3Rvcnk8VD5bXVxuICAgIHwgKCgpID0+IFQgfCBFeHRlbnNpb25GYWN0b3J5PFQ+IHwgQXJyYXk8VCB8IEV4dGVuc2lvbkZhY3Rvcnk8VD4+KVxuICA+XG4pOiBPYnNlcnZhYmxlPFRbXT4ge1xuICByZXR1cm4gbWVyZ2UoXG4gICAgcm91dGVyLmV2ZW50cy5waXBlKGZpbHRlcihldnQgPT4gZXZ0IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkpLFxuICAgIC4uLmNhc3RBcnJheShyZWZyZXNoKVxuICApLnBpcGUoXG4gICAgc3RhcnRXaXRoKDEpLFxuICAgIHN3aXRjaE1hcCgoKSA9PiBmcm9tRmFjdG9yaWVzPFQ+KGZhY3Rvcmllcywgcm91dGVyKSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21UcmlnZ2VyT25jZTxUPihcbiAgcm91dGVyOiBSb3V0ZXIsXG4gIHJlZnJlc2g6IE9ic2VydmFibGU8YW55PiB8IE9ic2VydmFibGU8YW55PltdLFxuICBmYWN0b3JpZXM6IEFycmF5PFxuICAgIHwgVFxuICAgIHwgVFtdXG4gICAgfCBFeHRlbnNpb25GYWN0b3J5PFQ+XG4gICAgfCBFeHRlbnNpb25GYWN0b3J5PFQ+W11cbiAgICB8ICgoKSA9PiBUIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPiB8IEFycmF5PFQgfCBFeHRlbnNpb25GYWN0b3J5PFQ+PilcbiAgPlxuKTogT2JzZXJ2YWJsZTxUW10+IHtcbiAgcmV0dXJuIG1lcmdlKC4uLmNhc3RBcnJheShyZWZyZXNoKSkucGlwZShcbiAgICBzdGFydFdpdGgoMSksXG4gICAgc3dpdGNoTWFwKCgpID0+IGZyb21GYWN0b3JpZXM8VD4oZmFjdG9yaWVzLCByb3V0ZXIpKVxuICApO1xufVxuXG5leHBvcnQgZW51bSBJbmplY3Rpb25UeXBlIHtcbiAgQ09NUE9ORU5ULFxuICBST1VURVxufVxuXG5leHBvcnQgY2xhc3MgU3RhbmRhbG9uZVBsdWdpbkluamVjdG9yIGV4dGVuZHMgSW5qZWN0b3Ige1xuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBjb25zdHJ1Y3RvcmAgaW5zdGVhZC5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGUoLi4uX2FyZ3M6IGFueVtdKTogU3RhbmRhbG9uZVBsdWdpbkluamVjdG9yIHtcbiAgICB0aHJvdyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG9wdGlvbnM6IHtcbiAgICAgIHByb3ZpZGVyczogQXJyYXk8UHJvdmlkZXIgfCBTdGF0aWNQcm92aWRlcj47XG4gICAgICBwYXJlbnQ/OiBJbmplY3RvcjtcbiAgICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgfVxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuaW5qZWN0b3IgPSBJbmplY3Rvci5jcmVhdGUob3B0aW9ucyk7XG4gIH1cblxuICBnZXQgbmFtZSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMubmFtZTtcbiAgfVxuXG4gIGdldDxUPihcbiAgICB0b2tlbjogVHlwZTxUPiB8IEluamVjdGlvblRva2VuPFQ+LFxuICAgIG5vdEZvdW5kVmFsdWU/OiBULFxuICAgIG9wdGlvbnM/OiBJbmplY3RPcHRpb25zIHwgSW5qZWN0RmxhZ3NcbiAgKTogVCB7XG4gICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IuZ2V0KHRva2VuLCBub3RGb3VuZFZhbHVlLCBvcHRpb25zKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5qZWN0ZWRIb29rczxUPihcbiAgdG9rZW46IEluamVjdGlvblRva2VuPFRbXT4sXG4gIGluamVjdG9yczogSW5qZWN0b3JbXSxcbiAgdHlwZSA9IEluamVjdGlvblR5cGUuQ09NUE9ORU5UXG4pOiAoKSA9PiBUW10ge1xuICByZXR1cm4gKCkgPT5cbiAgICBmbGF0dGVuKFxuICAgICAgaW5qZWN0b3JzLm1hcChpbmplY3RvciA9PiB7XG4gICAgICAgIGNvbnN0IGZhY3RvcnlPckZhY3RvcmllcyA9IGluamVjdG9yLmdldDxUIHwgVFtdPih0b2tlbiwgW10sIHsgc2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZmFjdG9yaWVzOiBUW10gPSBBcnJheS5pc0FycmF5KGZhY3RvcnlPckZhY3RvcmllcylcbiAgICAgICAgICA/IGZsYXR0ZW4oZmFjdG9yeU9yRmFjdG9yaWVzKVxuICAgICAgICAgIDogW2ZhY3RvcnlPckZhY3Rvcmllc107XG4gICAgICAgIGlmICgoaW5qZWN0b3IgYXMgYW55KS5zY29wZXM/Lmhhcygncm9vdCcpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhY3RvcmllcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5qZWN0b3IgaW5zdGFuY2VvZiBTdGFuZGFsb25lUGx1Z2luSW5qZWN0b3IpIHtcbiAgICAgICAgICAvLyBObyBuZWVkIHRvIHNldCBpbmplY3RvciBmb3IgaXRlbXMgcmV0cmlldmVkIGZyb20gc3RhbmRhbG9uZSBwbHVnaW5zXG4gICAgICAgICAgcmV0dXJuIGZhY3RvcmllcztcbiAgICAgICAgfVxuICAgICAgICBmYWN0b3JpZXMuZm9yRWFjaCgoZmFjdG9yeTogVCB8IEV4dGVuc2lvbkZhY3Rvcnk8VD4pID0+IHtcbiAgICAgICAgICBpZiAoIShmYWN0b3J5IGFzIEV4dGVuc2lvbkZhY3Rvcnk8VD4pLmdldCAmJiAoZmFjdG9yeSBhcyBhbnkpLmluamVjdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gSW5qZWN0aW9uVHlwZS5ST1VURSkge1xuICAgICAgICAgICAgICAoZmFjdG9yeSBhcyBhbnkpLl9pbmplY3RvciA9IGluamVjdG9yO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgKGZhY3RvcnkgYXMgYW55KS5pbmplY3RvciA9IGluamVjdG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWN0b3JpZXM7XG4gICAgICB9KVxuICAgICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tRmFjdG9yaWVzPFQ+KFxuICBmYWN0b3JpZXM/OiBBcnJheTxcbiAgICB8IFRcbiAgICB8IFRbXVxuICAgIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPlxuICAgIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPltdXG4gICAgfCAoKCkgPT4gVCB8IEV4dGVuc2lvbkZhY3Rvcnk8VD4gfCBBcnJheTxUIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPj4pXG4gID4sXG4gIHJvdXRlcj86IFJvdXRlcixcbiAgd2l0aEZpcnN0RW1wdHkgPSB0cnVlXG4pOiBPYnNlcnZhYmxlPFRbXT4ge1xuICByZXR1cm4gIUFycmF5LmlzQXJyYXkoZmFjdG9yaWVzKSB8fCBmYWN0b3JpZXMubGVuZ3RoIDwgMVxuICAgID8gb2YoW10pXG4gICAgOiBkZWZlcigoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZhY3RvcnlPYnNlcnZhYmxlczogT2JzZXJ2YWJsZTxUW10+W10gPSByZXNvbHZlSW5qZWN0ZWRGYWN0b3JpZXMoZmFjdG9yaWVzKS5tYXAoZiA9PiB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZikpIHtcbiAgICAgICAgICAgIHJldHVybiB0b09ic2VydmFibGVPZkFycmF5cyhmLCB3aXRoRmlyc3RFbXB0eSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpc0V4dGVuc2lvbkZhY3RvcnkoZikpIHtcbiAgICAgICAgICAgIHJldHVybiB0b09ic2VydmFibGVPZkFycmF5cyhmLmdldChnZXRBY3RpdmF0ZWRSb3V0ZShyb3V0ZXIpKSwgd2l0aEZpcnN0RW1wdHkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0b09ic2VydmFibGVPZkFycmF5cyhbZl0sIHdpdGhGaXJzdEVtcHR5KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KGZhY3RvcnlPYnNlcnZhYmxlcyk7XG4gICAgICB9KS5waXBlKFxuICAgICAgICBtYXAocmVzdWx0cyA9PiBzb3J0QnlQcmlvcml0eShbXS5jb25jYXQoLi4ucmVzdWx0cykpKSxcbiAgICAgICAgbWFwKHZhbHVlID0+IHVuaXEodmFsdWUpKVxuICAgICAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVJbmplY3RlZEZhY3RvcmllczxUPihcbiAgZmFjdG9yaWVzOiBBcnJheTxcbiAgICB8IFRcbiAgICB8IFRbXVxuICAgIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPlxuICAgIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPltdXG4gICAgfCAoKCkgPT4gVCB8IEV4dGVuc2lvbkZhY3Rvcnk8VD4gfCBBcnJheTxUIHwgRXh0ZW5zaW9uRmFjdG9yeTxUPj4pXG4gID5cbik6IEFycmF5PFQgfCBUW10gfCBFeHRlbnNpb25GYWN0b3J5PFQ+PiB7XG4gIHJldHVybiBmbGF0dGVuKFxuICAgIGZhY3Rvcmllcy5tYXAoZiA9PiB7XG4gICAgICBpZiAodHlwZW9mIGYgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY29uc3QgZnVuYyA9IGYgYXMgKCkgPT4gVCB8IFRbXSB8IEV4dGVuc2lvbkZhY3Rvcnk8VD47XG4gICAgICAgIHJldHVybiBmdW5jKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW2ZdO1xuICAgIH0pXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGF0ZVRvRmFjdG9yeTxUPihjb21wb25lbnRzU3RhdGUpOiBFeHRlbnNpb25GYWN0b3J5PFQ+IHtcbiAgY29uc3QgY29tcG9uZW50cyQgPSBjb21wb25lbnRzU3RhdGUucGlwZShtYXAoKGNvbXBvbmVudFNldDogU2V0PFQ+KSA9PiBbLi4uY29tcG9uZW50U2V0XSkpO1xuICByZXR1cm4geyBnZXQ6ICgpID0+IGNvbXBvbmVudHMkIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb3J0QnlQcmlvcml0eTxUPihpdGVtczogVFtdKTogVFtdIHtcbiAgcmV0dXJuIHNvcnRCeShpdGVtcywgaXRlbSA9PiAtKGl0ZW0/LnByaW9yaXR5IHx8IDApKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUR1cGxpY2F0ZXNJZHM8VCBleHRlbmRzIHsgaWQ/OiBzdHJpbmc7IHByaW9yaXR5PzogbnVtYmVyIH0+KGl0ZW1zOiBUW10pOiBUW10ge1xuICBjb25zdCBncm91cGVkOiB7IFtrZXk6IHN0cmluZ106IFRbXSB9ID0gZ3JvdXBCeShpdGVtcywgJ2lkJyk7XG4gIGNvbnN0IGl0ZW1zV2l0aG91dER1cGxpY2F0ZXMgPSBuZXcgQXJyYXk8VD4oKTtcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoZ3JvdXBlZCkpIHtcbiAgICBpZiAoa2V5ICYmIGtleSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnN0IHNvcnRlZEJ5UHJpbyA9IHNvcnRCeVByaW9yaXR5KGdyb3VwZWRba2V5XSk7XG4gICAgICBpdGVtc1dpdGhvdXREdXBsaWNhdGVzLnB1c2goc29ydGVkQnlQcmlvWzBdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaXRlbXNXaXRob3V0RHVwbGljYXRlcy5wdXNoKC4uLmdyb3VwZWRba2V5XSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzb3J0QnlQcmlvcml0eShpdGVtc1dpdGhvdXREdXBsaWNhdGVzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRvT2JzZXJ2YWJsZU9mQXJyYXlzPFQ+KFxuICBmYWN0b3J5UmVzdWx0OiBUIHwgVFtdIHwgUHJvbWlzZTxUIHwgVFtdPiB8IE9ic2VydmFibGU8VCB8IFRbXT4sXG4gIHdpdGhGaXJzdEVtcHR5OiBib29sZWFuXG4pOiBPYnNlcnZhYmxlPFRbXT4ge1xuICBsZXQgb2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxUIHwgVFtdPjtcbiAgaWYgKCFmYWN0b3J5UmVzdWx0KSB7XG4gICAgcmV0dXJuIG9mKFtdKTtcbiAgfSBlbHNlIHtcbiAgICBvYnNlcnZhYmxlID0gdG9PYnNlcnZhYmxlKGZhY3RvcnlSZXN1bHQpO1xuICAgIGlmICh3aXRoRmlyc3RFbXB0eSkge1xuICAgICAgY29uc3Qgd2l0aEVtcHR5Rmlyc3QgPSBvYnNlcnZhYmxlLnBpcGUoc3RhcnRXaXRoKFtdKSk7XG4gICAgICBvYnNlcnZhYmxlID0gcmFjZShvYnNlcnZhYmxlLCB3aXRoRW1wdHlGaXJzdCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvYnNlcnZhYmxlLnBpcGUoXG4gICAgbWFwKHJlc3VsdCA9PiAoQXJyYXkuaXNBcnJheShyZXN1bHQpID8gcmVzdWx0IDogW3Jlc3VsdF0pLmZpbHRlcihpdGVtID0+ICEhaXRlbSkpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Byb21pc2U8VCA9IGFueT4ob2JqOiBhbnkpOiBvYmogaXMgUHJvbWlzZTxUPiB7XG4gIHJldHVybiAhIW9iaiAmJiB0eXBlb2Ygb2JqLnRoZW4gPT09ICdmdW5jdGlvbic7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0V4dGVuc2lvbkZhY3Rvcnk8VCA9IGFueT4ob2JqOiBhbnkpOiBvYmogaXMgRXh0ZW5zaW9uRmFjdG9yeTxUPiB7XG4gIHJldHVybiAhIW9iaiAmJiB0eXBlb2Ygb2JqLmdldCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhbnkgdmFsdWUgcHJvdmlkZWQgdG8gYW4gT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoaXMgdmFsdWUgb25jZSBhbmQgdGhlbiBjb21wbGV0ZXMuXG4gKiBBIGNvbnZlbmllbmNlIG1ldGhvZCB0byByZXByZXNlbnQgYWxsIHRoZSBkYXRhIGFzIE9ic2VydmFibGVzIHJhdGhlciB0aGFuXG4gKiBhIG1peHR1cmUgb2YgT2JzZXJ2YWJsZXMgYW5kIG90aGVyIHR5cGVzLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdGhlIHJlc3VsdGluZyBPYnNlcnZhYmxlIHdpbGwgZW1pdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvT2JzZXJ2YWJsZTxUPih2YWx1ZTogVCB8IFByb21pc2U8VD4gfCBPYnNlcnZhYmxlPFQ+KTogT2JzZXJ2YWJsZTxUPiB7XG4gIGlmIChpc09ic2VydmFibGUodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzUHJvbWlzZSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZnJvbSh2YWx1ZSBhcyBQcm9taXNlPFQ+KTtcbiAgfVxuXG4gIHJldHVybiBvZih2YWx1ZSBhcyBUKTtcbn1cblxuLyoqXG4gKiBBbGxvd3MgdG8gZXh0ZW5kIHRoZSBleGlzdGluZyBhcHBsaWNhdGlvbnMgZnJvbSBhIG1vZHVsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHRlbnNpb25GYWN0b3J5PFQ+IHtcbiAgLyoqXG4gICAqIEFsbG93cyB0byByZXNvbHZlIHRoZSBkYXRhIG9mIGFuIGV4dGVuc2lvbiBwb2ludC5cbiAgICogVGhlIHJldHVybiB2YWx1ZSBjYW4gYmUgYSBQcm9taXNlIG9yIE9ic2VydmFibGVcbiAgICogKGFsbG93aW5nIGZvciBhc3luY2hyb25vdXMgZGF0YSByZXNvbHV0aW9uKS5cbiAgICpcbiAgICogQHBhcmFtIGFjdGl2YXRlZFJvdXRlIFRoZSBjdXJyZW50IGFjdGl2YXRlZCByb3V0ZSAoaWYgcG9zc2libGUgdG8gcmVzb2x2ZSkuXG4gICAqL1xuICBnZXQoYWN0aXZhdGVkUm91dGU/OiBBY3RpdmF0ZWRSb3V0ZSk6IE9ic2VydmFibGU8VFtdIHwgVD4gfCBQcm9taXNlPFRbXSB8IFQ+IHwgVFtdIHwgVDtcbn1cblxuLyoqXG4gKiBFeHRlbnNpb24gcG9pbnRzIGFsbG93IHRvIGV4dGVuZCB0aGUgYXBwbGljYXRpb24gZnJvbVxuICogYW55IG1vZHVsZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuc2lvblBvaW50PFQ+IHtcbiAgLyoqXG4gICAqIE9ic2VydmFibGUgdGhhdCBlbWl0cyBvZiBhcnJheSBvZiBleHRlbnNpb25zIGFjdGl2ZSBhdCBhbnkgZ2l2ZSB0aW1lXG4gICAqL1xuICByZWFkb25seSBpdGVtcyQ6IE9ic2VydmFibGU8VFtdPjtcbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgZmFjdG9yaWVzIHRoYXQgY2FuIGJlIGFkZGVkIGR5bmFtaWNhbGx5LiAod2l0aG91dCBob29rKVxuICAgKi9cbiAgZmFjdG9yaWVzOiBFeHRlbnNpb25GYWN0b3J5PFQ+W107XG4gIC8qKlxuICAgKiBDYWxsIHRoZSBleHRlbnNpb24gZmFjdG9yaWVzIHRvIHJlZnJlc2ggdGhlbS5cbiAgICovXG4gIHJlZnJlc2goKTtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEV4dGVuc2lvblBvaW50V2l0aG91dFN0YXRlRm9yUGx1Z2luczxUPiBpbXBsZW1lbnRzIEV4dGVuc2lvblBvaW50PFQ+IHtcbiAgaXRlbXMkOiBPYnNlcnZhYmxlPFRbXT47XG4gIGZhY3RvcmllczogRXh0ZW5zaW9uRmFjdG9yeTxUPltdID0gW107XG4gIHJlYWRvbmx5IHJlZnJlc2gkOiBPYnNlcnZhYmxlPHZvaWQ+O1xuICAvKipcbiAgICogQWxsIGluamVjdG9ycyB0byBzZWFyY2ggZm9yIGFuIGV4dGVuc2lvbi5cbiAgICovXG4gIHByb3RlY3RlZCBpbmplY3RvcnM6IEluamVjdG9yW107XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaFRyaWdnZXIgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKHJvb3RJbmplY3RvcjogSW5qZWN0b3IsIHBsdWdpblNlcnZpY2U6IFBsdWdpbnNSZXNvbHZlU2VydmljZSkge1xuICAgIHRoaXMuaW5qZWN0b3JzID0gW3Jvb3RJbmplY3Rvcl07XG4gICAgcGx1Z2luU2VydmljZS5pbmplY3RvcnMkLnN1YnNjcmliZShpbmplY3RvciA9PiB7XG4gICAgICB0aGlzLmluamVjdG9ycy5wdXNoKGluamVjdG9yKTtcbiAgICB9KTtcbiAgICB0aGlzLnJlZnJlc2gkID0gbWVyZ2UodGhpcy5yZWZyZXNoVHJpZ2dlciwgcGx1Z2luU2VydmljZS5yZWZyZXNoJCk7XG4gIH1cblxuICAvKipcbiAgICogUmVmcmVzaCB0aGUgZXh0ZW5zaW9uIGZhY3Rvcmllc1xuICAgKi9cbiAgcmVmcmVzaCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlZnJlc2hUcmlnZ2VyLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaG91bGQgYmUgY2FsbGVkIHdpdGhpbiB0aGUgY29uc3RydWN0b3Igb2YgdGhlIGV4dGVuZGluZyBjbGFzcyBhbmQgc2V0IHRoZSBpdGVtcyQgYXR0cmlidXRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNldHVwSXRlbXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8VFtdPjtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEV4dGVuc2lvblBvaW50Rm9yUGx1Z2luczxUPlxuICBleHRlbmRzIFN0YXRlU2VydmljZVxuICBpbXBsZW1lbnRzIEV4dGVuc2lvblBvaW50PFQ+XG57XG4gIGl0ZW1zJDogT2JzZXJ2YWJsZTxUW10+O1xuICBmYWN0b3JpZXM6IEV4dGVuc2lvbkZhY3Rvcnk8VD5bXSA9IFtdO1xuICByZWFkb25seSByZWZyZXNoJDogT2JzZXJ2YWJsZTx2b2lkPjtcbiAgcmVhZG9ubHkgc3RhdGUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTZXQ8VD4+KG5ldyBTZXQ8VD4oKSk7XG4gIC8qKlxuICAgKiBBbGwgaW5qZWN0b3JzIHRvIHNlYXJjaCBmb3IgYW4gZXh0ZW5zaW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGluamVjdG9yczogSW5qZWN0b3JbXTtcbiAgcHJpdmF0ZSByZWFkb25seSByZWZyZXNoVHJpZ2dlciA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3Iocm9vdEluamVjdG9yOiBJbmplY3RvciwgcGx1Z2luU2VydmljZTogUGx1Z2luc1Jlc29sdmVTZXJ2aWNlKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmluamVjdG9ycyA9IFtyb290SW5qZWN0b3JdO1xuICAgIHBsdWdpblNlcnZpY2UuaW5qZWN0b3JzJC5zdWJzY3JpYmUoaW5qZWN0b3IgPT4ge1xuICAgICAgdGhpcy5pbmplY3RvcnMucHVzaChpbmplY3Rvcik7XG4gICAgfSk7XG4gICAgdGhpcy5yZWZyZXNoJCA9IG1lcmdlKHRoaXMucmVmcmVzaFRyaWdnZXIsIHBsdWdpblNlcnZpY2UucmVmcmVzaCQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnJlc2ggdGhlIGV4dGVuc2lvbiBmYWN0b3JpZXNcbiAgICovXG4gIHJlZnJlc2goKTogdm9pZCB7XG4gICAgdGhpcy5yZWZyZXNoVHJpZ2dlci5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogU2hvdWxkIGJlIGNhbGxlZCB3aXRoaW4gdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBleHRlbmRpbmcgY2xhc3MgYW5kIHNldCB0aGUgaXRlbXMkIGF0dHJpYnV0ZS5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzZXR1cEl0ZW1zT2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPFRbXT47XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgYWN0aXZhdGVkIHJvdXRlIGluXG4gKiBhIHNlcnZpY2UgKGFzIEFjdGl2YXRlZFJvdXRlIGluamVjdGlvbiBvbmx5XG4gKiB3b3JrcyBpbiBjb21wb25lbnRzKS4gV29ya3MgYXMgbG9uZyBhcyB3ZSBvbmx5IHVzZVxuICogYSB0cmVlIGFuZCBubyBjaGlsZCBpcyBhY3RpdmUgYXQgdGhlIHNhbWUgdGltZS5cbiAqXG4gKiBAcGFyYW0gcm91dGVyIFRoZSBjdXJyZW50IHJvdXRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZhdGVkUm91dGUocm91dGVyOiBSb3V0ZXIpOiBBY3RpdmF0ZWRSb3V0ZSB7XG4gIGlmIChyb3V0ZXIgJiYgcm91dGVyLnJvdXRlclN0YXRlICYmIHJvdXRlci5yb3V0ZXJTdGF0ZS5yb290KSB7XG4gICAgbGV0IHJvdXRlID0gcm91dGVyLnJvdXRlclN0YXRlLnJvb3Q7XG4gICAgd2hpbGUgKHJvdXRlLmZpcnN0Q2hpbGQpIHtcbiAgICAgIHJvdXRlID0gcm91dGUuZmlyc3RDaGlsZDtcbiAgICB9XG4gICAgcmV0dXJuIHJvdXRlO1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIEdlbmVyaWNIb29rVHlwZTxUPiA9IFQgfCBUW10gfCBUeXBlPEV4dGVuc2lvbkZhY3Rvcnk8VD4+O1xuZXhwb3J0IHR5cGUgSG9va1ZhbHVlVHlwZTxUPiA9IFQgfCBUW10gfCBUeXBlPFQ+O1xuXG4vKipcbiAqIEEgZ2VuZXJpYyBmdW5jdGlvbiB0byBiZSB1c2VkIGJ5IHNwZWNpZmljIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgSE9PSyBjb25jZXB0LlxuICogQHBhcmFtIGl0ZW1zIFRoZSBpdGVtcyB0aGF0IHNob3VsZCBiZSBwcm92aWRlZCB1bmRlciB0aGUgYHVzZVZhbHVlYCBvciBgdXNlQ2xhc3NgIGF0dHJpYnV0ZS5cbiAqIEFsbG93cyBhbiBleHRlbnNpb24gZmFjdG9yeSB0byBiZSBwYXNzZWQgYXMgYW4gYXJndW1lbnQsIHdoaWNoIGNhbiBjcmVhdGUgaW5zdGFuY2VzIG9mIHR5cGUgVC5cbiAqIEBwYXJhbSB0b2tlbiBUaGUgSW5qZWN0aW9uVG9rZW4vSE9PSyB0byBiZSBwcm92aWRlZC5cbiAqIEBwYXJhbSBvcHRpb25zIElmIHRoaXMgaXMgYSBtdWx0aSBwcm92aWRlciBvciBub3QgKGRlZmF1bHRzIHRvIHRydWUpIGFuZCBwcm92aWRlciB0eXBlIGRlZmluaXRpb24gKGRlZmF1bHRzIHRvIENsYXNzUHJvdmlkZXIpIC0gYEhvb2tPcHRpb25zYC5cbiAqIEByZXR1cm5zIEEgYFByb3ZpZGVyYCAoZWl0aGVyIGBWYWx1ZVByb3ZpZGVyYCBvciBgQ2xhc3NQcm92aWRlcmApIHRvIGJlIHByb3ZpZGVkIGluIGEgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaG9va0dlbmVyaWM8VD4oXG4gIGl0ZW1zOiBHZW5lcmljSG9va1R5cGU8VD4gfCBIb29rVmFsdWVUeXBlPFQ+LFxuICB0b2tlbjogSW5qZWN0aW9uVG9rZW48VD4sXG4gIG9wdGlvbnM/OiBQYXJ0aWFsPEdlbmVyaWNIb29rT3B0aW9ucz5cbik6IFZhbHVlUHJvdmlkZXIgfCBDbGFzc1Byb3ZpZGVyIHwgRXhpc3RpbmdQcm92aWRlciB7XG4gIGNvbnN0IGZpbmFsT3B0aW9uczogR2VuZXJpY0hvb2tPcHRpb25zID0gT2JqZWN0LmFzc2lnbihcbiAgICB7IG11bHRpOiB0cnVlLCBwcm92aWRlclR5cGU6IEhvb2tQcm92aWRlclR5cGVzLkNsYXNzUHJvdmlkZXIgfSxcbiAgICBvcHRpb25zXG4gICk7XG4gIGNvbnN0IHsgbXVsdGksIHByb3ZpZGVyVHlwZSB9ID0gZmluYWxPcHRpb25zO1xuICBpZiAodHlwZW9mIGl0ZW1zICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHByb3ZpZGU6IHRva2VuLFxuICAgICAgdXNlVmFsdWU6IGl0ZW1zLFxuICAgICAgbXVsdGlcbiAgICB9IGFzIFZhbHVlUHJvdmlkZXI7XG4gIH1cblxuICBpZiAocHJvdmlkZXJUeXBlID09PSBIb29rUHJvdmlkZXJUeXBlcy5FeGlzdGluZ1Byb3ZpZGVyKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHByb3ZpZGU6IHRva2VuLFxuICAgICAgdXNlRXhpc3Rpbmc6IGl0ZW1zLFxuICAgICAgbXVsdGlcbiAgICB9IGFzIEV4aXN0aW5nUHJvdmlkZXI7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHByb3ZpZGU6IHRva2VuLFxuICAgIHVzZUNsYXNzOiBpdGVtcyxcbiAgICBtdWx0aVxuICB9IGFzIENsYXNzUHJvdmlkZXI7XG59XG5leHBvcnQgaW50ZXJmYWNlIEdlbmVyaWNIb29rT3B0aW9ucyB7XG4gIG11bHRpOiBib29sZWFuO1xuICBwcm92aWRlclR5cGU6IEhvb2tQcm92aWRlclR5cGVzO1xufVxuXG5leHBvcnQgZW51bSBIb29rUHJvdmlkZXJUeXBlcyB7XG4gIEV4aXN0aW5nUHJvdmlkZXIgPSAnRXhpc3RpbmdQcm92aWRlcicsXG4gIENsYXNzUHJvdmlkZXIgPSAnQ2xhc3NQcm92aWRlcidcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbEVudHJpZXNBcmVFcXVhbChwcmV2aW91czogQXJyYXk8dW5rbm93bj4sIG5leHQ6IEFycmF5PHVua25vd24+KTogYm9vbGVhbiB7XG4gIGlmIChwcmV2aW91cyA9PT0gbmV4dCkgcmV0dXJuIHRydWU7XG4gIGlmIChwcmV2aW91cyA9PSBudWxsIHx8IG5leHQgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAocHJldmlvdXMubGVuZ3RoICE9PSBuZXh0Lmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldmlvdXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAocHJldmlvdXNbaV0gIT09IG5leHRbaV0pIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==