UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

169 lines 23.6 kB
import { importProvidersFrom, Injectable, InjectionToken, Injector } from '@angular/core'; import { Router, ROUTES } from '@angular/router'; import { flatten } from 'lodash'; import { distinctUntilChanged, filter, shareReplay, take } from 'rxjs/operators'; import { ExtensionPointWithoutStateForPlugins, fromTriggerOnce, getInjectedHooks, hookGeneric, InjectionType } from '../common/extension-hooks'; import { OptionsService } from '../common/options.service'; import { PluginsResolveService } from '../plugins'; import { ContextRouteService } from './context-route.service'; import { ViewContext } from './router.model'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "./context-route.service"; import * as i3 from "../plugins"; import * as i4 from "../common/options.service"; /** * A hook to use for Multi Provider extension. * @deprecated Consider using the `hookRoute` function instead. */ export const HOOK_ROUTE = new InjectionToken('HOOK_ROUTE'); /** * You can either provide a single `Route` as parameter: * ```typescript * hookRoute(...) * ``` * * Or an array to directly register multiple: * ```typescript * hookRoute([...]) * ``` * * Or you provide an Service that implements `ExtensionFactory<Route>` * ```typescript * export class MyRouteFactory implements ExtensionFactory<Route> {...} * ... * hookRoute(MyRouteFactory) * ``` * A typed alternative to `HOOK_ROUTE`. * @param route The `Route`'s or `ExtensionFactory` to be provided. * @returns An `Provider` to be provided in your module. */ export function hookRoute(route, options) { return hookGeneric(route, HOOK_ROUTE, options); } /** * A service which defines routes for the application. You can use * HOOK_ROUTES or pass */ export class RouterService extends ExtensionPointWithoutStateForPlugins { constructor(rootInjector, router, contextRouteService, plugins, options) { super(rootInjector, plugins); this.router = router; this.contextRouteService = contextRouteService; this.state = new Map(); this.items$ = this.setupItemsObservable(); // We are doing a self subscription to add the new routes // to the router configuration. this.items$.subscribe((routes) => { const toAddRoutes = routes.filter((route) => { const path = `${route.context || ''}${route.path}`; const isAlreadyAdded = this.state.has(path); if (!isAlreadyAdded) { this.state.set(path, route); } return !isAlreadyAdded; }); this.addRoute(toAddRoutes); }); plugins.pluginDetails$.subscribe(({ moduleRef, remoteNgModule }) => { this.resolveRouterForChildRoutes(moduleRef, remoteNgModule); }); // only needed in case of pure angular application // otherwise handled by bridge service if (!options.upgrade) { plugins.allPluginsLoaded$ .pipe(filter(tmp => !!tmp), take(1)) .subscribe(() => { this.router.initialNavigation(); }); } } /** * Refresh the current context */ refresh() { super.refresh(); this.contextRouteService.refreshContext(); } /** * Add a new route to the router configuration or a context. * @param route The route to add */ addRoute(route) { this.addRoutes(Array.isArray(route) ? route : [route]); } /** * Determines if the given MO is an group or an device and returns * the correct href to link correctly to that MO. * @param groupOrDevice The MO of a group or the device. * @param prefix How should the link be prefixed. */ getHref(groupOrDevice, prefix = '#/') { if (groupOrDevice.c8y_IsDeviceGroup || groupOrDevice.c8y_IsDynamicGroup) { return `${prefix}${ViewContext.Group.replace(':id', groupOrDevice.id)}`; } return `${prefix}${ViewContext.Device.replace(':id', groupOrDevice.id)}`; } setupItemsObservable() { return fromTriggerOnce(this.router, this.refresh$, [ getInjectedHooks(HOOK_ROUTE, this.injectors, InjectionType.ROUTE), () => this.factories ]).pipe(distinctUntilChanged(), shareReplay(1)); } addRoutes(routes) { // Empty route needs to be last as of navigation to angularjs routes // if ** route hit, the angularjs routes are loaded. const emptyRoute = this.router.config.find(r => r.path === '**'); const rootContextRoutes = this.findAllRootContextRoutes([...this.router.config, ...routes]); this.router.resetConfig([ ...this.router.config.filter(r => r.path !== '**'), ...routes.map((r) => this.convertRoute(rootContextRoutes, r)), emptyRoute ].filter(Boolean)); } convertRoute(rootContextRoutes, route) { if (route.context) { rootContextRoutes.forEach((r) => { if (r.rootContext === route.context) { r.children = [route, ...(r.children || [])]; } }); return; } return route; } findAllRootContextRoutes(routes) { const result = []; routes.forEach(route => { if (route.rootContext) { result.push(route); } if (route.children) { const childRoutes = this.findAllRootContextRoutes(route.children); result.push(...childRoutes); } }); return result; } resolveRouterForChildRoutes(moduleRef, remoteNgModule) { // NOTE: stolen from lazy loaded routes from Angular itself. // https://github.com/angular/angular/blob/da58801f95c66c201e332189af25702bdd722f3f/packages/router/src/router_config_loader.ts#L103-L108 const rawRoutes = flatten(moduleRef.injector.get(ROUTES, [], { self: true, optional: true })); if (rawRoutes.length > 0) { const routeWithInjector = rawRoutes.map(route => { route.providers = [importProvidersFrom(remoteNgModule)]; return route; }); this.addRoute(routeWithInjector); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RouterService, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i2.ContextRouteService }, { token: i3.PluginsResolveService }, { token: i4.OptionsService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RouterService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RouterService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.Router }, { type: i2.ContextRouteService }, { type: i3.PluginsResolveService }, { type: i4.OptionsService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9jb3JlL3JvdXRlci9yb3V0ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLFVBQVUsRUFDVixjQUFjLEVBQ2QsUUFBUSxFQUVULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxNQUFNLEVBQVUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFekQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVqQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNqRixPQUFPLEVBRUwsb0NBQW9DLEVBQ3BDLGVBQWUsRUFHZixnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLGFBQWEsRUFDZCxNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbkQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxFQUF1QixXQUFXLEVBQXdCLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQXNCeEY7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLElBQUksY0FBYyxDQUFlLFlBQVksQ0FBQyxDQUFDO0FBRXpFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBNkIsRUFBRSxPQUFxQztJQUM1RixPQUFPLFdBQVcsQ0FBUSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRDs7O0dBR0c7QUFJSCxNQUFNLE9BQU8sYUFBYyxTQUFRLG9D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Q0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUM5QyxLQUFLLENBQUMsU0FBUyxHQUFHLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztnQkFDeEQsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQzsrR0F0SVUsYUFBYTttSEFBYixhQUFhLGNBRlosTUFBTTs7NEZBRVAsYUFBYTtrQkFIekIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBpbXBvcnRQcm92aWRlcnNGcm9tLFxuICBJbmplY3RhYmxlLFxuICBJbmplY3Rpb25Ub2tlbixcbiAgSW5qZWN0b3IsXG4gIE5nTW9kdWxlUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGVyLCBSb3V0ZXMsIFJPVVRFUyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBJTWFuYWdlZE9iamVjdCB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgc2hhcmVSZXBsYXksIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBFeHRlbnNpb25GYWN0b3J5LFxuICBFeHRlbnNpb25Qb2ludFdpdGhvdXRTdGF0ZUZvclBsdWdpbnMsXG4gIGZyb21UcmlnZ2VyT25jZSxcbiAgR2VuZXJpY0hvb2tPcHRpb25zLFxuICBHZW5lcmljSG9va1R5cGUsXG4gIGdldEluamVjdGVkSG9va3MsXG4gIGhvb2tHZW5lcmljLFxuICBJbmplY3Rpb25UeXBlXG59IGZyb20gJy4uL2NvbW1vbi9leHRlbnNpb24taG9va3MnO1xuaW1wb3J0IHsgT3B0aW9uc1NlcnZpY2UgfSBmcm9tICcuLi9jb21tb24vb3B0aW9ucy5zZXJ2aWNlJztcbmltcG9ydCB7IFBsdWdpbnNSZXNvbHZlU2VydmljZSB9IGZyb20gJy4uL3BsdWdpbnMnO1xuaW1wb3J0IHsgQ29udGV4dFJvdXRlU2VydmljZSB9IGZyb20gJy4vY29udGV4dC1yb3V0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFJvdXRlLCBSb3V0ZUZhY3RvcnksIFZpZXdDb250ZXh0LCBWaWV3Q29udGV4dFJvb3RSb3V0ZSB9IGZyb20gJy4vcm91dGVyLm1vZGVsJztcblxuLyoqXG4gKiBBbiBleHRlbnNpb24gSE9PSyBjYW4gdXNlIGVpdGhlciBhIHB1cmUgdmFsdWU6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAgeyBwcm92aWRlOiBIT09LX1gsIHVzZVZhbHVlOiB7IC4uLmhvb2tWYWx1ZSB9LCBtdWx0aTogdHJ1ZSB9XG4gKiBgYGBcbiAqXG4gKiBPciBhbiBhcnJheSB0byBkaXJlY3RseSByZWdpc3RlciBtdWx0aXBsZTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqICB7IHByb3ZpZGU6IEhPT0tfWCwgdXNlVmFsdWU6IFt7IC4uLmhvb2tWYWx1ZXMgfV0sIG11bHRpOiB0cnVlIH1cbiAqIGBgYFxuICpcbiAqIE9yIGFuIEV4dGVuc2lvbkZhY3Rvcnkgd2hpY2ggYWxsb3dzIHRvIGRlZmluZSBhIGdldCgpIGZ1bmN0aW9uLiBUaGlzIGZ1bmN0aW9uXG4gKiBnZXRzIGNhbGxlZCBvbiBlYWNoIG5hdmlnYXRpb24gd2l0aCB0aGUgY3VycmVudCByb3V0ZSBhbmQgY2FuIHJldHVybiB2YWx1ZXNcbiAqIGFzeW5jIChvYnNlcnZhYmxlIG9yIHByb21pc2UpLlxuICogYGBgdHlwZXNjcmlwdFxuICogIHsgcHJvdmlkZTogSE9PS19YLCB1c2VGYWN0b3J5OiB7IGdldDogKHJvdXRlKSA9PiBkb1NvbWV0aGluZ0FzeW5jKHJvdXRlKSB9LCBtdWx0aTogdHJ1ZSB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IHR5cGUgUm91dGVFeHRlbnNpb24gPSBSb3V0ZSB8IFJvdXRlW10gfCBFeHRlbnNpb25GYWN0b3J5PFJvdXRlPjtcblxuLyoqXG4gKiBBIGhvb2sgdG8gdXNlIGZvciBNdWx0aSBQcm92aWRlciBleHRlbnNpb24uXG4gKiBAZGVwcmVjYXRlZCBDb25zaWRlciB1c2luZyB0aGUgYGhvb2tSb3V0ZWAgZnVuY3Rpb24gaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGNvbnN0IEhPT0tfUk9VVEUgPSBuZXcgSW5qZWN0aW9uVG9rZW48Um91dGVGYWN0b3J5PignSE9PS19ST1VURScpO1xuXG4vKipcbiAqIFlvdSBjYW4gZWl0aGVyIHByb3ZpZGUgYSBzaW5nbGUgYFJvdXRlYCBhcyBwYXJhbWV0ZXI6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAgaG9va1JvdXRlKC4uLilcbiAqIGBgYFxuICpcbiAqIE9yIGFuIGFycmF5IHRvIGRpcmVjdGx5IHJlZ2lzdGVyIG11bHRpcGxlOlxuICogYGBgdHlwZXNjcmlwdFxuICogIGhvb2tSb3V0ZShbLi4uXSlcbiAqIGBgYFxuICpcbiAqIE9yIHlvdSBwcm92aWRlIGFuIFNlcnZpY2UgdGhhdCBpbXBsZW1lbnRzIGBFeHRlbnNpb25GYWN0b3J5PFJvdXRlPmBcbiAqIGBgYHR5cGVzY3JpcHRcbiAqICBleHBvcnQgY2xhc3MgTXlSb3V0ZUZhY3RvcnkgaW1wbGVtZW50cyBFeHRlbnNpb25GYWN0b3J5PFJvdXRlPiB7Li4ufVxuICogIC4uLlxuICogIGhvb2tSb3V0ZShNeVJvdXRlRmFjdG9yeSlcbiAqIGBgYFxuICogQSB0eXBlZCBhbHRlcm5hdGl2ZSB0byBgSE9PS19ST1VURWAuXG4gKiBAcGFyYW0gcm91dGUgVGhlIGBSb3V0ZWAncyBvciBgRXh0ZW5zaW9uRmFjdG9yeWAgdG8gYmUgcHJvdmlkZWQuXG4gKiBAcmV0dXJucyBBbiBgUHJvdmlkZXJgIHRvIGJlIHByb3ZpZGVkIGluIHlvdXIgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaG9va1JvdXRlKHJvdXRlOiBHZW5lcmljSG9va1R5cGU8Um91dGU+LCBvcHRpb25zPzogUGFydGlhbDxHZW5lcmljSG9va09wdGlvbnM+KSB7XG4gIHJldHVybiBob29rR2VuZXJpYzxSb3V0ZT4ocm91dGUsIEhPT0tfUk9VVEUsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIEEgc2VydmljZSB3aGljaCBkZWZpbmVzIHJvdXRlcyBmb3IgdGhlIGFwcGxpY2F0aW9uLiBZb3UgY2FuIHVzZVxuICogSE9PS19ST1VURVMgb3IgcGFzc1xuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBSb3V0ZXJTZXJ2aWNlIGV4dGVuZHMgRXh0ZW5zaW9uUG9pbnRXaXRob3V0U3RhdGVGb3JQbHVnaW5zPFJvdXRlPiB7XG4gIHJlYWRvbmx5IHN0YXRlID0gbmV3IE1hcDxzdHJpbmcsIFJvdXRlPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJvb3RJbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHVibGljIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgY29udGV4dFJvdXRlU2VydmljZTogQ29udGV4dFJvdXRlU2VydmljZSxcbiAgICBwbHVnaW5zOiBQbHVnaW5zUmVzb2x2ZVNlcnZpY2UsXG4gICAgb3B0aW9uczogT3B0aW9uc1NlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIocm9vdEluamVjdG9yLCBwbHVnaW5zKTtcbiAgICB0aGlzLml0ZW1zJCA9IHRoaXMuc2V0dXBJdGVtc09ic2VydmFibGUoKTtcblxuICAgIC8vIFdlIGFyZSBkb2luZyBhIHNlbGYgc3Vic2NyaXB0aW9uIHRvIGFkZCB0aGUgbmV3IHJvdXRlc1xuICAgIC8vIHRvIHRoZSByb3V0ZXIgY29uZmlndXJhdGlvbi5cbiAgICB0aGlzLml0ZW1zJC5zdWJzY3JpYmUoKHJvdXRlczogUm91dGVbXSkgPT4ge1xuICAgICAgY29uc3QgdG9BZGRSb3V0ZXMgPSByb3V0ZXMuZmlsdGVyKChyb3V0ZTogUm91dGUpID0+IHtcbiAgICAgICAgY29uc3QgcGF0aCA9IGAke3JvdXRlLmNvbnRleHQgfHwgJyd9JHtyb3V0ZS5wYXRofWA7XG4gICAgICAgIGNvbnN0IGlzQWxyZWFkeUFkZGVkID0gdGhpcy5zdGF0ZS5oYXMocGF0aCk7XG4gICAgICAgIGlmICghaXNBbHJlYWR5QWRkZWQpIHtcbiAgICAgICAgICB0aGlzLnN0YXRlLnNldChwYXRoLCByb3V0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICFpc0FscmVhZHlBZGRlZDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRSb3V0ZSh0b0FkZFJvdXRlcyk7XG4gICAgfSk7XG5cbiAgICBwbHVnaW5zLnBsdWdpbkRldGFpbHMkLnN1YnNjcmliZSgoeyBtb2R1bGVSZWYsIHJlbW90ZU5nTW9kdWxlIH0pID0+IHtcbiAgICAgIHRoaXMucmVzb2x2ZVJvdXRlckZvckNoaWxkUm91dGVzKG1vZHVsZVJlZiwgcmVtb3RlTmdNb2R1bGUpO1xuICAgIH0pO1xuXG4gICAgLy8gb25seSBuZWVkZWQgaW4gY2FzZSBvZiBwdXJlIGFuZ3VsYXIgYXBwbGljYXRpb25cbiAgICAvLyBvdGhlcndpc2UgaGFuZGxlZCBieSBicmlkZ2Ugc2VydmljZVxuICAgIGlmICghb3B0aW9ucy51cGdyYWRlKSB7XG4gICAgICBwbHVnaW5zLmFsbFBsdWdpbnNMb2FkZWQkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIGZpbHRlcih0bXAgPT4gISF0bXApLFxuICAgICAgICAgIHRha2UoMSlcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnJvdXRlci5pbml0aWFsTmF2aWdhdGlvbigpO1xuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVmcmVzaCB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqL1xuICByZWZyZXNoKCkge1xuICAgIHN1cGVyLnJlZnJlc2goKTtcbiAgICB0aGlzLmNvbnRleHRSb3V0ZVNlcnZpY2UucmVmcmVzaENvbnRleHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgcm91dGUgdG8gdGhlIHJvdXRlciBjb25maWd1cmF0aW9uIG9yIGEgY29udGV4dC5cbiAgICogQHBhcmFtIHJvdXRlIFRoZSByb3V0ZSB0byBhZGRcbiAgICovXG4gIGFkZFJvdXRlKHJvdXRlOiBSb3V0ZSB8IFJvdXRlW10pIHtcbiAgICB0aGlzLmFkZFJvdXRlcyhBcnJheS5pc0FycmF5KHJvdXRlKSA/IHJvdXRlIDogW3JvdXRlXSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gTU8gaXMgYW4gZ3JvdXAgb3IgYW4gZGV2aWNlIGFuZCByZXR1cm5zXG4gICAqIHRoZSBjb3JyZWN0IGhyZWYgdG8gbGluayBjb3JyZWN0bHkgdG8gdGhhdCBNTy5cbiAgICogQHBhcmFtIGdyb3VwT3JEZXZpY2UgVGhlIE1PIG9mIGEgZ3JvdXAgb3IgdGhlIGRldmljZS5cbiAgICogQHBhcmFtIHByZWZpeCBIb3cgc2hvdWxkIHRoZSBsaW5rIGJlIHByZWZpeGVkLlxuICAgKi9cbiAgZ2V0SHJlZihncm91cE9yRGV2aWNlOiBJTWFuYWdlZE9iamVjdCwgcHJlZml4ID0gJyMvJyk6IHN0cmluZyB7XG4gICAgaWYgKGdyb3VwT3JEZXZpY2UuYzh5X0lzRGV2aWNlR3JvdXAgfHwgZ3JvdXBPckRldmljZS5jOHlfSXNEeW5hbWljR3JvdXApIHtcbiAgICAgIHJldHVybiBgJHtwcmVmaXh9JHtWaWV3Q29udGV4dC5Hcm91cC5yZXBsYWNlKCc6aWQnLCBncm91cE9yRGV2aWNlLmlkKX1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7cHJlZml4fSR7Vmlld0NvbnRleHQuRGV2aWNlLnJlcGxhY2UoJzppZCcsIGdyb3VwT3JEZXZpY2UuaWQpfWA7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0dXBJdGVtc09ic2VydmFibGUoKTogT2JzZXJ2YWJsZTxSb3V0ZVtdPiB7XG4gICAgcmV0dXJuIGZyb21UcmlnZ2VyT25jZTxSb3V0ZT4odGhpcy5yb3V0ZXIsIHRoaXMucmVmcmVzaCQsIFtcbiAgICAgIGdldEluamVjdGVkSG9va3M8Um91dGU+KEhPT0tfUk9VVEUsIHRoaXMuaW5qZWN0b3JzLCBJbmplY3Rpb25UeXBlLlJPVVRFKSxcbiAgICAgICgpID0+IHRoaXMuZmFjdG9yaWVzXG4gICAgXSkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCBzaGFyZVJlcGxheSgxKSk7XG4gIH1cblxuICBwcml2YXRlIGFkZFJvdXRlcyhyb3V0ZXMpIHtcbiAgICAvLyBFbXB0eSByb3V0ZSBuZWVkcyB0byBiZSBsYXN0IGFzIG9mIG5hdmlnYXRpb24gdG8gYW5ndWxhcmpzIHJvdXRlc1xuICAgIC8vIGlmICoqIHJvdXRlIGhpdCwgdGhlIGFuZ3VsYXJqcyByb3V0ZXMgYXJlIGxvYWRlZC5cbiAgICBjb25zdCBlbXB0eVJvdXRlID0gdGhpcy5yb3V0ZXIuY29uZmlnLmZpbmQociA9PiByLnBhdGggPT09ICcqKicpO1xuICAgIGNvbnN0IHJvb3RDb250ZXh0Um91dGVzID0gdGhpcy5maW5kQWxsUm9vdENvbnRleHRSb3V0ZXMoWy4uLnRoaXMucm91dGVyLmNvbmZpZywgLi4ucm91dGVzXSk7XG5cbiAgICB0aGlzLnJvdXRlci5yZXNldENvbmZpZyhcbiAgICAgIFtcbiAgICAgICAgLi4udGhpcy5yb3V0ZXIuY29uZmlnLmZpbHRlcihyID0+IHIucGF0aCAhPT0gJyoqJyksXG4gICAgICAgIC4uLnJvdXRlcy5tYXAoKHI6IFJvdXRlKSA9PiB0aGlzLmNvbnZlcnRSb3V0ZShyb290Q29udGV4dFJvdXRlcywgcikpLFxuICAgICAgICBlbXB0eVJvdXRlXG4gICAgICBdLmZpbHRlcihCb29sZWFuKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRSb3V0ZShyb290Q29udGV4dFJvdXRlczogUm91dGVzLCByb3V0ZTogUm91dGUpIHtcbiAgICBpZiAocm91dGUuY29udGV4dCkge1xuICAgICAgcm9vdENvbnRleHRSb3V0ZXMuZm9yRWFjaCgocjogVmlld0NvbnRleHRSb290Um91dGUpID0+IHtcbiAgICAgICAgaWYgKHIucm9vdENvbnRleHQgPT09IHJvdXRlLmNvbnRleHQpIHtcbiAgICAgICAgICByLmNoaWxkcmVuID0gW3JvdXRlLCAuLi4oci5jaGlsZHJlbiB8fCBbXSldO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIHJvdXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kQWxsUm9vdENvbnRleHRSb3V0ZXMocm91dGVzOiBSb3V0ZXMpOiBWaWV3Q29udGV4dFJvb3RSb3V0ZVtdIHtcbiAgICBjb25zdCByZXN1bHQ6IFZpZXdDb250ZXh0Um9vdFJvdXRlW10gPSBbXTtcbiAgICByb3V0ZXMuZm9yRWFjaChyb3V0ZSA9PiB7XG4gICAgICBpZiAoKHJvdXRlIGFzIFZpZXdDb250ZXh0Um9vdFJvdXRlKS5yb290Q29udGV4dCkge1xuICAgICAgICByZXN1bHQucHVzaChyb3V0ZSBhcyBWaWV3Q29udGV4dFJvb3RSb3V0ZSk7XG4gICAgICB9XG4gICAgICBpZiAocm91dGUuY2hpbGRyZW4pIHtcbiAgICAgICAgY29uc3QgY2hpbGRSb3V0ZXMgPSB0aGlzLmZpbmRBbGxSb290Q29udGV4dFJvdXRlcyhyb3V0ZS5jaGlsZHJlbik7XG4gICAgICAgIHJlc3VsdC5wdXNoKC4uLmNoaWxkUm91dGVzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlUm91dGVyRm9yQ2hpbGRSb3V0ZXMobW9kdWxlUmVmOiBOZ01vZHVsZVJlZjxhbnk+LCByZW1vdGVOZ01vZHVsZTogYW55KSB7XG4gICAgLy8gTk9URTogc3RvbGVuIGZyb20gbGF6eSBsb2FkZWQgcm91dGVzIGZyb20gQW5ndWxhciBpdHNlbGYuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9ibG9iL2RhNTg4MDFmOTVjNjZjMjAxZTMzMjE4OWFmMjU3MDJiZGQ3MjJmM2YvcGFja2FnZXMvcm91dGVyL3NyYy9yb3V0ZXJfY29uZmlnX2xvYWRlci50cyNMMTAzLUwxMDhcbiAgICBjb25zdCByYXdSb3V0ZXMgPSBmbGF0dGVuKG1vZHVsZVJlZi5pbmplY3Rvci5nZXQoUk9VVEVTLCBbXSwgeyBzZWxmOiB0cnVlLCBvcHRpb25hbDogdHJ1ZSB9KSk7XG5cbiAgICBpZiAocmF3Um91dGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHJvdXRlV2l0aEluamVjdG9yID0gcmF3Um91dGVzLm1hcChyb3V0ZSA9PiB7XG4gICAgICAgIHJvdXRlLnByb3ZpZGVycyA9IFtpbXBvcnRQcm92aWRlcnNGcm9tKHJlbW90ZU5nTW9kdWxlKV07XG4gICAgICAgIHJldHVybiByb3V0ZTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRSb3V0ZShyb3V0ZVdpdGhJbmplY3Rvcik7XG4gICAgfVxuICB9XG59XG4iXX0=