@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
159 lines • 26.1 kB
JavaScript
import { DestroyRef, Injectable, Injector } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { ActivationEnd, ActivationStart, ChildActivationEnd, PRIMARY_OUTLET, Router } from '@angular/router';
import { ApiService } from '@c8y/ngx-components/api';
import { NEVER, Subject } from 'rxjs';
import { filter, map, merge, switchMap } from 'rxjs/operators';
import { TabsService } from '../tabs/tabs.service';
import { RouterTabsResolver } from './router-tabs.resolver';
import { ViewContext } from './router.model';
import { ViewContextServices } from './view-context.service';
import * as i0 from "@angular/core";
import * as i1 from "./router-tabs.resolver";
import * as i2 from "../tabs/tabs.service";
import * as i3 from "@angular/router";
import * as i4 from "@c8y/ngx-components/api";
/**
* A service which is injected into the context route component to handle the context data.
*/
export class ScopedContextRouteService {
constructor(tabsResolver, tabsService, router, apiService, injector, destroyRef) {
this.tabsResolver = tabsResolver;
this.tabsService = tabsService;
this.router = router;
this.apiService = apiService;
this.injector = injector;
this.destroyRef = destroyRef;
this.lastAddedTabs = [];
this.refreshTrigger$ = new Subject();
this.ID_REGEX = /([0-9]+)/;
}
/**
* Indicates that the data is loading
* @returns An boolean observable which indicates if the data is loading.
*/
isLoading$() {
return this.router.events.pipe(filter(e => (e instanceof ActivationStart || e instanceof ChildActivationEnd) &&
e.snapshot.routeConfig?.rootContext === this.currentContext), map(e => e instanceof ActivationStart), takeUntilDestroyed(this.destroyRef));
}
/**
* Initializes the context route.
* @param route The current activated route.
*/
init(route) {
this.currentContext = route.routeConfig.rootContext;
if (!this.currentContext) {
throw new Error(`${ScopedContextRouteService.name} should not be used on a route without a rootContext`);
}
this.router.events
.pipe(filter(e => e instanceof ActivationEnd), takeUntilDestroyed(this.destroyRef))
.subscribe((e) => this.redirectToFirstTab(e));
route.data
.pipe(merge(this.updatedContext(route), this.refreshTrigger$), switchMap(() => this.tabsResolver.resolve(route.snapshot)), takeUntilDestroyed(this.destroyRef))
.subscribe(tabs => this.updateTabs(tabs));
}
/**
* Destroys the service.
*/
ngOnDestroy() {
this.lastAddedTabs.forEach(t => this.tabsService.remove(t));
}
/**
* Refreshes the context.
*/
refreshContext() {
this.refreshTrigger$.next();
}
/**
* Sets an API hook to refresh the contextData on changes.
* @param activatedRoute The current activated route.
*/
updatedContext(route) {
const { data } = route.snapshot;
const serviceInstance = ViewContextServices.contextToService(data.context);
if (serviceInstance) {
const service = this.injector.get(serviceInstance);
const detailsUrlRegex = service
.getDetailUrl(data.contextData)
.replace(/\d+/g, '?\\d*');
const contextRegex = new RegExp(detailsUrlRegex, 'i');
const childrenRegex = new RegExp(`${detailsUrlRegex}/child`, 'i');
const filterResponse = ({ url, method }) => {
const contextChanged = contextRegex.test(url) && ['POST', 'PUT'].includes(method);
const childrenAffected = childrenRegex.test(url) && ['POST', 'DELETE'].includes(method);
return contextChanged || childrenAffected;
};
return this.apiService.hookResponse(filterResponse);
}
return NEVER;
}
updateTabs(tabs = []) {
this.lastAddedTabs.forEach(t => this.tabsService.remove(t));
this.lastAddedTabs = tabs;
tabs.forEach(t => this.tabsService.add(t));
this.redirectToFirstTab();
}
redirectToFirstTab(event) {
const currentQueryParams = this.router.routerState.snapshot.root.queryParams;
const queryParamsString = new URLSearchParams(currentQueryParams).toString();
const queryParamsSuffix = queryParamsString ? `?${queryParamsString}` : '';
if (event) {
if (this.needsRedirect(event)) {
const tab = this.tabsService.sortTabs(event.snapshot.data.tabs)?.[0];
if (!tab) {
return;
}
const currentContextId = (this.router.url.match(this.ID_REGEX) || []).shift();
const tabPathId = (tab.path.match(this.ID_REGEX) || []).shift();
if (currentContextId === tabPathId) {
this.router.navigateByUrl(`${tab.path}${queryParamsSuffix}`, {
replaceUrl: true
});
}
}
}
else {
const currentContextId = (this.router.url.match(this.ID_REGEX) || []).shift();
if (this.needsRedirectLegacy()) {
this.tabsService.firstTab$
.pipe(filter((tab) => typeof tab?.path === 'string'))
.subscribe((tab) => {
const tabPathId = (tab.path.match(this.ID_REGEX) || []).shift();
if (currentContextId === tabPathId) {
this.router.navigateByUrl(`${tab.path}${queryParamsSuffix}`, { replaceUrl: true });
}
});
}
}
}
needsRedirectLegacy() {
const tree = this.router.parseUrl(this.router.url);
const groups = tree.root.children[PRIMARY_OUTLET];
const context = this.getMatchingContextRoute(this.router.url);
if (!context) {
return groups.segments.length === 2;
}
return context.split('/').length === groups.segments.length;
}
needsRedirect(event) {
const contextRoute = event.snapshot.routeConfig;
if (!contextRoute.rootContext) {
return false;
}
const contextRouteFromUrl = this.getMatchingContextRoute(this.router.url);
return contextRoute.rootContext === contextRouteFromUrl;
}
getMatchingContextRoute(url) {
const viewContexts = Object.values(ViewContext);
// replace all :id placeholders with a regex matcher for a number
const regexMatchers = viewContexts.map(context => `^/${context.replace(/:id/g, '([0-9]+)')}(\\?.*)?$`);
const matchingRegexContext = regexMatchers.find(context => new RegExp(context).test(url));
return matchingRegexContext ? viewContexts[regexMatchers.indexOf(matchingRegexContext)] : null;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScopedContextRouteService, deps: [{ token: i1.RouterTabsResolver }, { token: i2.TabsService }, { token: i3.Router }, { token: i4.ApiService }, { token: i0.Injector }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScopedContextRouteService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScopedContextRouteService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.RouterTabsResolver }, { type: i2.TabsService }, { type: i3.Router }, { type: i4.ApiService }, { type: i0.Injector }, { type: i0.DestroyRef }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NvcGVkLWNvbnRleHQtcm91dGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2NvcmUvcm91dGVyL3Njb3BlZC1jb250ZXh0LXJvdXRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFtQixNQUFNLGVBQWUsQ0FBQztBQUNsRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBRUwsYUFBYSxFQUNiLGVBQWUsRUFDZixrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLE1BQU0sRUFHUCxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBVyxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFL0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBRSxXQUFXLEVBQXdCLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7OztBQUU3RDs7R0FFRztBQUVILE1BQU0sT0FBTyx5QkFBeUI7SUFVcEMsWUFDVSxZQUFnQyxFQUNoQyxXQUF3QixFQUN4QixNQUFjLEVBQ2QsVUFBc0IsRUFDdEIsUUFBa0IsRUFDbEIsVUFBc0I7UUFMdEIsaUJBQVksR0FBWixZQUFZLENBQW9CO1FBQ2hDLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxl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QW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDakcsQ0FBQzsrR0E1S1UseUJBQXlCO21IQUF6Qix5QkFBeUI7OzRGQUF6Qix5QkFBeUI7a0JBRHJDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZXN0cm95UmVmLCBJbmplY3RhYmxlLCBJbmplY3RvciwgT25EZXN0cm95LCBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge1xuICBBY3RpdmF0ZWRSb3V0ZSxcbiAgQWN0aXZhdGlvbkVuZCxcbiAgQWN0aXZhdGlvblN0YXJ0LFxuICBDaGlsZEFjdGl2YXRpb25FbmQsXG4gIFBSSU1BUllfT1VUTEVULFxuICBSb3V0ZXIsXG4gIFVybFNlZ21lbnRHcm91cCxcbiAgVXJsVHJlZVxufSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQXBpQ2FsbCwgQXBpU2VydmljZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvYXBpJztcbmltcG9ydCB7IE5FVkVSLCBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIG1hcCwgbWVyZ2UsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFRhYiwgVGFiV2l0aFRlbXBsYXRlIH0gZnJvbSAnLi4vdGFicy90YWIubW9kZWwnO1xuaW1wb3J0IHsgVGFic1NlcnZpY2UgfSBmcm9tICcuLi90YWJzL3RhYnMuc2VydmljZSc7XG5pbXBvcnQgeyBSb3V0ZXJUYWJzUmVzb2x2ZXIgfSBmcm9tICcuL3JvdXRlci10YWJzLnJlc29sdmVyJztcbmltcG9ydCB7IFZpZXdDb250ZXh0LCBWaWV3Q29udGV4dFJvb3RSb3V0ZSB9IGZyb20gJy4vcm91dGVyLm1vZGVsJztcbmltcG9ydCB7IFZpZXdDb250ZXh0U2VydmljZXMgfSBmcm9tICcuL3ZpZXctY29udGV4dC5zZXJ2aWNlJztcblxuLyoqXG4gKiBBIHNlcnZpY2Ugd2hpY2ggaXMgaW5qZWN0ZWQgaW50byB0aGUgY29udGV4dCByb3V0ZSBjb21wb25lbnQgdG8gaGFuZGxlIHRoZSBjb250ZXh0IGRhdGEuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBTY29wZWRDb250ZXh0Um91dGVTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBsYXN0QWRkZWRUYWJzID0gW107XG4gIHByaXZhdGUgcmVmcmVzaFRyaWdnZXIkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBJRF9SRUdFWCA9IC8oWzAtOV0rKS87XG5cbiAgLyoqXG4gICAqIFRoZSBjb250ZXh0IHVzZWQgYnkgdGhpcyBzZXJ2aWNlLlxuICAgKi9cbiAgcHJpdmF0ZSBjdXJyZW50Q29udGV4dDogVmlld0NvbnRleHQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0YWJzUmVzb2x2ZXI6IFJvdXRlclRhYnNSZXNvbHZlcixcbiAgICBwcml2YXRlIHRhYnNTZXJ2aWNlOiBUYWJzU2VydmljZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgYXBpU2VydmljZTogQXBpU2VydmljZSxcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcml2YXRlIGRlc3Ryb3lSZWY6IERlc3Ryb3lSZWZcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgZGF0YSBpcyBsb2FkaW5nXG4gICAqIEByZXR1cm5zIEFuIGJvb2xlYW4gb2JzZXJ2YWJsZSB3aGljaCBpbmRpY2F0ZXMgaWYgdGhlIGRhdGEgaXMgbG9hZGluZy5cbiAgICovXG4gIGlzTG9hZGluZyQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMucm91dGVyLmV2ZW50cy5waXBlKFxuICAgICAgZmlsdGVyKFxuICAgICAgICBlID0+XG4gICAgICAgICAgKGUgaW5zdGFuY2VvZiBBY3RpdmF0aW9uU3RhcnQgfHwgZSBpbnN0YW5jZW9mIENoaWxkQWN0aXZhdGlvbkVuZCkgJiZcbiAgICAgICAgICAoZS5zbmFwc2hvdC5yb3V0ZUNvbmZpZyBhcyBWaWV3Q29udGV4dFJvb3RSb3V0ZSk/LnJvb3RDb250ZXh0ID09PSB0aGlzLmN1cnJlbnRDb250ZXh0XG4gICAgICApLFxuICAgICAgbWFwKGUgPT4gZSBpbnN0YW5jZW9mIEFjdGl2YXRpb25TdGFydCksXG4gICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgdGhlIGNvbnRleHQgcm91dGUuXG4gICAqIEBwYXJhbSByb3V0ZSBUaGUgY3VycmVudCBhY3RpdmF0ZWQgcm91dGUuXG4gICAqL1xuICBpbml0KHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudENvbnRleHQgPSAocm91dGUucm91dGVDb25maWcgYXMgVmlld0NvbnRleHRSb290Um91dGUpLnJvb3RDb250ZXh0O1xuICAgIGlmICghdGhpcy5jdXJyZW50Q29udGV4dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgJHtTY29wZWRDb250ZXh0Um91dGVTZXJ2aWNlLm5hbWV9IHNob3VsZCBub3QgYmUgdXNlZCBvbiBhIHJvdXRlIHdpdGhvdXQgYSByb290Q29udGV4dGBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5yb3V0ZXIuZXZlbnRzXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKGUgPT4gZSBpbnN0YW5jZW9mIEFjdGl2YXRpb25FbmQpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoZTogQWN0aXZhdGlvbkVuZCkgPT4gdGhpcy5yZWRpcmVjdFRvRmlyc3RUYWIoZSkpO1xuXG4gICAgcm91dGUuZGF0YVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1lcmdlKHRoaXMudXBkYXRlZENvbnRleHQocm91dGUpLCB0aGlzLnJlZnJlc2hUcmlnZ2VyJCksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnRhYnNSZXNvbHZlci5yZXNvbHZlKHJvdXRlLnNuYXBzaG90KSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHRhYnMgPT4gdGhpcy51cGRhdGVUYWJzKHRhYnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyB0aGUgc2VydmljZS5cbiAgICovXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMubGFzdEFkZGVkVGFicy5mb3JFYWNoKHQgPT4gdGhpcy50YWJzU2VydmljZS5yZW1vdmUodCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnJlc2hlcyB0aGUgY29udGV4dC5cbiAgICovXG4gIHJlZnJlc2hDb250ZXh0KCkge1xuICAgIHRoaXMucmVmcmVzaFRyaWdnZXIkLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFuIEFQSSBob29rIHRvIHJlZnJlc2ggdGhlIGNvbnRleHREYXRhIG9uIGNoYW5nZXMuXG4gICAqIEBwYXJhbSBhY3RpdmF0ZWRSb3V0ZSBUaGUgY3VycmVudCBhY3RpdmF0ZWQgcm91dGUuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZWRDb250ZXh0KHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSk6IE9ic2VydmFibGU8QXBpQ2FsbD4ge1xuICAgIGNvbnN0IHsgZGF0YSB9ID0gcm91dGUuc25hcHNob3Q7XG4gICAgY29uc3Qgc2VydmljZUluc3RhbmNlID0gVmlld0NvbnRleHRTZXJ2aWNlcy5jb250ZXh0VG9TZXJ2aWNlKGRhdGEuY29udGV4dCk7XG4gICAgaWYgKHNlcnZpY2VJbnN0YW5jZSkge1xuICAgICAgY29uc3Qgc2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0KFxuICAgICAgICBzZXJ2aWNlSW5zdGFuY2UgYXMgVHlwZTxJbnN0YW5jZVR5cGU8dHlwZW9mIHNlcnZpY2VJbnN0YW5jZT4+XG4gICAgICApO1xuICAgICAgY29uc3QgZGV0YWlsc1VybFJlZ2V4ID0gKHNlcnZpY2UgYXMgdHlwZW9mIHNlcnZpY2UgJiB7IGdldERldGFpbFVybD86ICguLi5hcmdzKSA9PiBzdHJpbmcgfSlcbiAgICAgICAgLmdldERldGFpbFVybChkYXRhLmNvbnRleHREYXRhKVxuICAgICAgICAucmVwbGFjZSgvXFxkKy9nLCAnP1xcXFxkKicpO1xuICAgICAgY29uc3QgY29udGV4dFJlZ2V4ID0gbmV3IFJlZ0V4cChkZXRhaWxzVXJsUmVnZXgsICdpJyk7XG4gICAgICBjb25zdCBjaGlsZHJlblJlZ2V4ID0gbmV3IFJlZ0V4cChgJHtkZXRhaWxzVXJsUmVnZXh9L2NoaWxkYCwgJ2knKTtcbiAgICAgIGNvbnN0IGZpbHRlclJlc3BvbnNlID0gKHsgdXJsLCBtZXRob2QgfSkgPT4ge1xuICAgICAgICBjb25zdCBjb250ZXh0Q2hhbmdlZCA9IGNvbnRleHRSZWdleC50ZXN0KHVybCkgJiYgWydQT1NUJywgJ1BVVCddLmluY2x1ZGVzKG1ldGhvZCk7XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuQWZmZWN0ZWQgPSBjaGlsZHJlblJlZ2V4LnRlc3QodXJsKSAmJiBbJ1BPU1QnLCAnREVMRVRFJ10uaW5jbHVkZXMobWV0aG9kKTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHRDaGFuZ2VkIHx8IGNoaWxkcmVuQWZmZWN0ZWQ7XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuYXBpU2VydmljZS5ob29rUmVzcG9uc2UoZmlsdGVyUmVzcG9uc2UpO1xuICAgIH1cbiAgICByZXR1cm4gTkVWRVI7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVRhYnModGFicyA9IFtdKSB7XG4gICAgdGhpcy5sYXN0QWRkZWRUYWJzLmZvckVhY2godCA9PiB0aGlzLnRhYnNTZXJ2aWNlLnJlbW92ZSh0KSk7XG4gICAgdGhpcy5sYXN0QWRkZWRUYWJzID0gdGFicztcbiAgICB0YWJzLmZvckVhY2godCA9PiB0aGlzLnRhYnNTZXJ2aWNlLmFkZCh0KSk7XG4gICAgdGhpcy5yZWRpcmVjdFRvRmlyc3RUYWIoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVkaXJlY3RUb0ZpcnN0VGFiKGV2ZW50PzogQWN0aXZhdGlvbkVuZCkge1xuICAgIGNvbnN0IGN1cnJlbnRRdWVyeVBhcmFtcyA9IHRoaXMucm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnJvb3QucXVlcnlQYXJhbXM7XG4gICAgY29uc3QgcXVlcnlQYXJhbXNTdHJpbmcgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKGN1cnJlbnRRdWVyeVBhcmFtcykudG9TdHJpbmcoKTtcbiAgICBjb25zdCBxdWVyeVBhcmFtc1N1ZmZpeCA9IHF1ZXJ5UGFyYW1zU3RyaW5nID8gYD8ke3F1ZXJ5UGFyYW1zU3RyaW5nfWAgOiAnJztcblxuICAgIGlmIChldmVudCkge1xuICAgICAgaWYgKHRoaXMubmVlZHNSZWRpcmVjdChldmVudCkpIHtcbiAgICAgICAgY29uc3QgdGFiID0gdGhpcy50YWJzU2VydmljZS5zb3J0VGFicyhldmVudC5zbmFwc2hvdC5kYXRhLnRhYnMpPy5bMF07XG4gICAgICAgIGlmICghdGFiKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0SWQgPSAodGhpcy5yb3V0ZXIudXJsLm1hdGNoKHRoaXMuSURfUkVHRVgpIHx8IFtdKS5zaGlmdCgpO1xuICAgICAgICBjb25zdCB0YWJQYXRoSWQgPSAodGFiLnBhdGgubWF0Y2godGhpcy5JRF9SRUdFWCkgfHwgW10pLnNoaWZ0KCk7XG4gICAgICAgIGlmIChjdXJyZW50Q29udGV4dElkID09PSB0YWJQYXRoSWQpIHtcbiAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGAke3RhYi5wYXRofSR7cXVlcnlQYXJhbXNTdWZmaXh9YCwge1xuICAgICAgICAgICAgcmVwbGFjZVVybDogdHJ1ZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0SWQgPSAodGhpcy5yb3V0ZXIudXJsLm1hdGNoKHRoaXMuSURfUkVHRVgpIHx8IFtdKS5zaGlmdCgpO1xuICAgICAgaWYgKHRoaXMubmVlZHNSZWRpcmVjdExlZ2FjeSgpKSB7XG4gICAgICAgIHRoaXMudGFic1NlcnZpY2UuZmlyc3RUYWIkXG4gICAgICAgICAgLnBpcGUoZmlsdGVyKCh0YWI6IFRhYikgPT4gdHlwZW9mIHRhYj8ucGF0aCA9PT0gJ3N0cmluZycpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKHRhYjogVGFiV2l0aFRlbXBsYXRlPHN0cmluZz4pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhYlBhdGhJZCA9ICh0YWIucGF0aC5tYXRjaCh0aGlzLklEX1JFR0VYKSB8fCBbXSkuc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50Q29udGV4dElkID09PSB0YWJQYXRoSWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybChgJHt0YWIucGF0aH0ke3F1ZXJ5UGFyYW1zU3VmZml4fWAsIHsgcmVwbGFjZVVybDogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG5lZWRzUmVkaXJlY3RMZWdhY3koKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdHJlZTogVXJsVHJlZSA9IHRoaXMucm91dGVyLnBhcnNlVXJsKHRoaXMucm91dGVyLnVybCk7XG4gICAgY29uc3QgZ3JvdXBzOiBVcmxTZWdtZW50R3JvdXAgPSB0cmVlLnJvb3QuY2hpbGRyZW5bUFJJTUFSWV9PVVRMRVRdO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuZ2V0TWF0Y2hpbmdDb250ZXh0Um91dGUodGhpcy5yb3V0ZXIudXJsKTtcbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgIHJldHVybiBncm91cHMuc2VnbWVudHMubGVuZ3RoID09PSAyO1xuICAgIH1cbiAgICByZXR1cm4gY29udGV4dC5zcGxpdCgnLycpLmxlbmd0aCA9PT0gZ3JvdXBzLnNlZ21lbnRzLmxlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgbmVlZHNSZWRpcmVjdChldmVudDogQWN0aXZhdGlvbkVuZCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGNvbnRleHRSb3V0ZTogVmlld0NvbnRleHRSb290Um91dGUgPSBldmVudC5zbmFwc2hvdC5yb3V0ZUNvbmZpZyBhcyBWaWV3Q29udGV4dFJvb3RSb3V0ZTtcbiAgICBpZiAoIWNvbnRleHRSb3V0ZS5yb290Q29udGV4dCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBjb250ZXh0Um91dGVGcm9tVXJsID0gdGhpcy5nZXRNYXRjaGluZ0NvbnRleHRSb3V0ZSh0aGlzLnJvdXRlci51cmwpO1xuICAgIHJldHVybiBjb250ZXh0Um91dGUucm9vdENvbnRleHQgPT09IGNvbnRleHRSb3V0ZUZyb21Vcmw7XG4gIH1cblxuICBwcml2YXRlIGdldE1hdGNoaW5nQ29udGV4dFJvdXRlKHVybDogc3RyaW5nKTogVmlld0NvbnRleHQge1xuICAgIGNvbnN0IHZpZXdDb250ZXh0cyA9IE9iamVjdC52YWx1ZXMoVmlld0NvbnRleHQpO1xuICAgIC8vIHJlcGxhY2UgYWxsIDppZCBwbGFjZWhvbGRlcnMgd2l0aCBhIHJlZ2V4IG1hdGNoZXIgZm9yIGEgbnVtYmVyXG4gICAgY29uc3QgcmVnZXhNYXRjaGVycyA9IHZpZXdDb250ZXh0cy5tYXAoXG4gICAgICBjb250ZXh0ID0+IGBeLyR7Y29udGV4dC5yZXBsYWNlKC86aWQvZywgJyhbMC05XSspJyl9KFxcXFw/LiopPyRgXG4gICAgKTtcbiAgICBjb25zdCBtYXRjaGluZ1JlZ2V4Q29udGV4dCA9IHJlZ2V4TWF0Y2hlcnMuZmluZChjb250ZXh0ID0+IG5ldyBSZWdFeHAoY29udGV4dCkudGVzdCh1cmwpKTtcbiAgICByZXR1cm4gbWF0Y2hpbmdSZWdleENvbnRleHQgPyB2aWV3Q29udGV4dHNbcmVnZXhNYXRjaGVycy5pbmRleE9mKG1hdGNoaW5nUmVnZXhDb250ZXh0KV0gOiBudWxsO1xuICB9XG59XG4iXX0=