@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
239 lines • 35.1 kB
JavaScript
import { Component, Input } from '@angular/core';
import { NestedTreeControl } from '@angular/cdk/tree';
import { NavigationEnd } from '@angular/router';
import { MatTreeNestedDataSource } from '@angular/material/tree';
import { ReplaySubject } from 'rxjs';
import { AbstractNavigationResizableDrawerComponent } from '../navigation-drawer/abstract-navigation-resizable-drawer.component';
import { debounceTime, filter } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "../../configuration/configuration.service";
import * as i2 from "@angular/router";
import * as i3 from "../../logger/services/logger.service";
import * as i4 from "../../user/services/user.service";
import * as i5 from "../../authorization/permission/access.service";
import * as i6 from "../../groups/services/active-group.service";
import * as i7 from "../../resources/engine-endpoint/task-resource.service";
import * as i8 from "../../translate/language.service";
import * as i9 from "../../routing/dynamic-navigation-route-provider/dynamic-navigation-route-provider.service";
export class AbstractNavigationTreeComponent extends AbstractNavigationResizableDrawerComponent {
_config;
_router;
_log;
_userService;
_accessService;
_activeGroupService;
_taskResourceService;
_languageService;
_navigationRouteProvider;
viewPath;
parentUrl;
routerChange;
_reloadNavigation;
_subscriptions;
_subGroupResolution;
_subLangChange;
treeControl;
dataSource;
constructor(_config, _router, _log, _userService, _accessService, _activeGroupService, _taskResourceService, _languageService, _navigationRouteProvider) {
super();
this._config = _config;
this._router = _router;
this._log = _log;
this._userService = _userService;
this._accessService = _accessService;
this._activeGroupService = _activeGroupService;
this._taskResourceService = _taskResourceService;
this._languageService = _languageService;
this._navigationRouteProvider = _navigationRouteProvider;
this.treeControl = new NestedTreeControl(node => node.children);
this.dataSource = new MatTreeNestedDataSource();
this.dataSource.data = this.resolveNavigationNodes(_config.getConfigurationSubtree(['views']), '');
this.resolveLevels(this.dataSource.data);
this._reloadNavigation = new ReplaySubject(1);
}
ngOnInit() {
super.ngOnInit();
if (this.viewPath && this.parentUrl !== undefined && this.routerChange) {
this.resolveNavigationNodesWithOffsetRoot();
}
this._subscriptions = [
this._router.events.pipe(filter(event => event instanceof NavigationEnd && this.routerChange))
.subscribe(() => this._reloadNavigation.next()),
this._userService.user$.subscribe(() => this._reloadNavigation.next()),
this._activeGroupService.activeGroups$.subscribe(() => this._reloadNavigation.next())
];
this._subscriptions.push(this._reloadNavigation.pipe(debounceTime(100)).subscribe(() => {
this.resolveNavigation();
}));
}
ngOnDestroy() {
for (const sub of this._subscriptions) {
if (!sub.closed) {
sub.unsubscribe();
}
}
this._reloadNavigation.complete();
if (this._subGroupResolution !== undefined) {
this._subGroupResolution.unsubscribe();
}
if (this._subLangChange !== undefined) {
this._subLangChange.unsubscribe();
}
}
hasChild(_, node) {
return !!node.children && node.children.length > 0;
}
resolveNavigation() {
let nodes;
if (this.viewPath && this.parentUrl !== undefined && this.routerChange) {
nodes = this.resolveNavigationNodesWithOffsetRoot();
}
else {
nodes = this.resolveNavigationNodes(this._config.getConfigurationSubtree(['views']), '');
}
this.dataSource.data = nodes;
this.resolveLevels(this.dataSource.data);
}
resolveNavigationNodesWithOffsetRoot() {
const view = this._config.getViewByPath(this.viewPath);
if (view && view.children) {
return this.resolveNavigationNodes(view.children, this.parentUrl);
}
return this.dataSource.data;
}
/**
* Converts the provided {@link Views} object into the corresponding navigation tree
* @param views navigation configuration
* @param parentUrl URL of the parent navigation tree node
* @param ancestorNodeContainer if the parent node has no navigation this attribute contains the
* closest ancestor that has navigation
* @protected
*/
resolveNavigationNodes(views, parentUrl, ancestorNodeContainer) {
if (!views || Object.keys(views).length === 0) {
return null;
}
const nodes = [];
Object.keys(views).forEach((viewKey) => {
const view = views[viewKey];
if (!this.hasNavigation(view) && !this.hasSubRoutes(view)) {
return; // continue
}
const routeSegment = this.getNodeRouteSegment(view);
if (routeSegment === undefined) {
throw new Error('Route segment doesnt exist in view ' + parentUrl + '/' + viewKey + ' !');
}
if (!this._accessService.canAccessView(view, this.appendRouteSegment(parentUrl, routeSegment))) {
return; // continue
}
if (this.hasNavigation(view)) {
const node = this.buildNode(view, routeSegment, parentUrl);
if (this.hasSubRoutes(view)) {
node.children = this.resolveNavigationNodes(view.children, node.url);
}
nodes.push(node);
}
else {
if (this.hasSubRoutes(view)) {
nodes.push(...this.resolveNavigationNodes(view.children, this.appendRouteSegment(parentUrl, routeSegment), ancestorNodeContainer ?? nodes));
}
}
});
return nodes;
}
hasNavigation(route) {
if (!route.navigation) {
return false;
}
if (typeof route.navigation === 'boolean') {
return route.navigation;
}
if (typeof route.navigation === 'object') {
return Object.keys(route.navigation).length !== 0;
}
}
hasSubRoutes(route) {
if (!route.children) {
return false;
}
if (typeof route.children === 'object') {
return Object.keys(route.children).length !== 0;
}
}
buildNode(view, routeSegment, parentUrl) {
const node = {
name: null,
url: null
};
node.name = this.getNodeName(view, routeSegment);
node.icon = this.getNodeIcon(view);
node.url = this.appendRouteSegment(parentUrl, routeSegment);
node.translate = this.getNodeTranslateFlag(view);
return node;
}
getNodeName(view, routeSegment) {
if (view.navigation['title']) {
return view.navigation['title'];
}
const str = routeSegment.replace('_', ' ');
return str.charAt(0).toUpperCase() + str.substring(1);
}
getNodeIcon(view) {
return !view.navigation['icon'] ? undefined : view.navigation['icon'];
}
/**
* @param view configuration of some view, whose routeSegment we want to determine
* @returns the routeSegment for the provided view, or undefined if none is specified
*/
getNodeRouteSegment(view) {
return !!view.routing && (typeof view.routing.path === 'string') ? view.routing.path : undefined;
}
getNodeTranslateFlag(view) {
return view.navigation['translate'] ?? false;
}
/**
* Appends the route segment to the parent URL.
* @param parentUrl URL of the parent. Should not end with '/'
* @param routeSegment URL segment of the child
* @returns `parentUrl/routeSegment` if the `routeSegment` is truthy (not an empty string).
* Returns `parentUrl` if `routeSegment` is falsy (empty string).
*/
appendRouteSegment(parentUrl, routeSegment) {
return routeSegment ? parentUrl + '/' + routeSegment : parentUrl;
}
resolveLevels(nodes, parentLevel) {
if (!nodes) {
return;
}
const currentLevel = parentLevel === null || parentLevel === undefined ? 0 : parentLevel + 1;
nodes.forEach(node => {
node.level = currentLevel;
if (node.children) {
this.resolveLevels(node.children, currentLevel);
}
});
}
resolveChange() {
const view = this._config.getViewByPath(this.viewPath);
if (view && view.children) {
this.dataSource.data = this.resolveNavigationNodes(view.children, this.parentUrl);
}
this.resolveLevels(this.dataSource.data);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AbstractNavigationTreeComponent, deps: [{ token: i1.ConfigurationService }, { token: i2.Router }, { token: i3.LoggerService }, { token: i4.UserService }, { token: i5.AccessService }, { token: i6.ActiveGroupService }, { token: i7.TaskResourceService }, { token: i8.LanguageService }, { token: i9.DynamicNavigationRouteProviderService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AbstractNavigationTreeComponent, selector: "ncc-abstract-navigation-tree", inputs: { viewPath: "viewPath", parentUrl: "parentUrl", routerChange: "routerChange" }, usesInheritance: true, ngImport: i0, template: '', isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AbstractNavigationTreeComponent, decorators: [{
type: Component,
args: [{
selector: 'ncc-abstract-navigation-tree',
template: ''
}]
}], ctorParameters: () => [{ type: i1.ConfigurationService }, { type: i2.Router }, { type: i3.LoggerService }, { type: i4.UserService }, { type: i5.AccessService }, { type: i6.ActiveGroupService }, { type: i7.TaskResourceService }, { type: i8.LanguageService }, { type: i9.DynamicNavigationRouteProviderService }], propDecorators: { viewPath: [{
type: Input
}], parentUrl: [{
type: Input
}], routerChange: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3QtbmF2aWdhdGlvbi10cmVlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy1jb3JlL3NyYy9saWIvbmF2aWdhdGlvbi9uYXZpZ2F0aW9uLXRyZWUvYWJzdHJhY3QtbmF2aWdhdGlvbi10cmVlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBb0IsTUFBTSxlQUFlLENBQUM7QUFDbEUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFDLGFBQWEsRUFBUyxNQUFNLGlCQUFpQixDQUFDO0FBQ3RELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQy9ELE9BQU8sRUFBQyxhQUFhLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFHakQsT0FBTyxFQUNILDBDQUEwQyxFQUM3QyxNQUFNLHFFQUFxRSxDQUFDO0FBRTdFLE9BQU8sRUFBQyxZQUFZLEVBQUUsTUFBTSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7O0FBcUJwRCxNQUFNLE9BQWdCLCtCQUFnQyxTQUFRLDBDQUEwQztJQWVwRTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFyQmhCLFFBQVEsQ0FBUztJQUNqQixTQUFTLENBQVM7SUFDbEIsWUFBWSxDQUFVO0lBRTVCLGlCQUFpQixDQUFzQjtJQUV6QyxjQUFjLENBQXNCO0lBQ3BDLG1CQUFtQixDQUFlO0lBQ2xDLGNBQWMsQ0FBZTtJQUVyQyxXQUFXLENBQW9DO0lBQy9DLFVBQVUsQ0FBMEM7SUFFcEQsWUFBZ0MsT0FBNkIsRUFDN0IsT0FBZSxFQUNmLElBQW1CLEVBQ25CLFlBQXlCLEVBQ3pCLGNBQTZCLEVBQzdCLG1CQUF1QyxFQUN2QyxvQkFBeUMsRUFD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LENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNyRjtRQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDO3dHQXJPaUIsK0JBQStCOzRGQUEvQiwrQkFBK0IsbUxBRnZDLEVBQUU7OzRGQUVNLCtCQUErQjtrQkFKcEQsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsOEJBQThCO29CQUN4QyxRQUFRLEVBQUUsRUFBRTtpQkFDZjtxVkFHbUIsUUFBUTtzQkFBdkIsS0FBSztnQkFDVSxTQUFTO3NCQUF4QixLQUFLO2dCQUNVLFlBQVk7c0JBQTNCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TmVzdGVkVHJlZUNvbnRyb2x9IGZyb20gJ0Bhbmd1bGFyL2Nkay90cmVlJztcbmltcG9ydCB7Q29uZmlndXJhdGlvblNlcnZpY2V9IGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vY29uZmlndXJhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7VmlldywgVmlld3N9IGZyb20gJy4uLy4uLy4uL2NvbW1vbnMvc2NoZW1hJztcbmltcG9ydCB7TmF2aWdhdGlvbkVuZCwgUm91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtNYXRUcmVlTmVzdGVkRGF0YVNvdXJjZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdHJlZSc7XG5pbXBvcnQge1JlcGxheVN1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0xvZ2dlclNlcnZpY2V9IGZyb20gJy4uLy4uL2xvZ2dlci9zZXJ2aWNlcy9sb2dnZXIuc2VydmljZSc7XG5pbXBvcnQge1VzZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi91c2VyL3NlcnZpY2VzL3VzZXIuc2VydmljZSc7XG5pbXBvcnQge1xuICAgIEFic3RyYWN0TmF2aWdhdGlvblJlc2l6YWJsZURyYXdlckNvbXBvbmVudFxufSBmcm9tICcuLi9uYXZpZ2F0aW9uLWRyYXdlci9hYnN0cmFjdC1uYXZpZ2F0aW9uLXJlc2l6YWJsZS1kcmF3ZXIuY29tcG9uZW50JztcbmltcG9ydCB7QWN0aXZlR3JvdXBTZXJ2aWNlfSBmcm9tICcuLi8uLi9ncm91cHMvc2VydmljZXMvYWN0aXZlLWdyb3VwLnNlcnZpY2UnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGZpbHRlcn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUYXNrUmVzb3VyY2VTZXJ2aWNlfSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvZW5naW5lLWVuZHBvaW50L3Rhc2stcmVzb3VyY2Uuc2VydmljZSc7XG5pbXBvcnQge0xhbmd1YWdlU2VydmljZX0gZnJvbSAnLi4vLi4vdHJhbnNsYXRlL2xhbmd1YWdlLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgICBEeW5hbWljTmF2aWdhdGlvblJvdXRlUHJvdmlkZXJTZXJ2aWNlXG59IGZyb20gJy4uLy4uL3JvdXRpbmcvZHluYW1pYy1uYXZpZ2F0aW9uLXJvdXRlLXByb3ZpZGVyL2R5bmFtaWMtbmF2aWdhdGlvbi1yb3V0ZS1wcm92aWRlci5zZXJ2aWNlJztcbmltcG9ydCB7QWNjZXNzU2VydmljZX0gZnJvbSBcIi4uLy4uL2F1dGhvcml6YXRpb24vcGVybWlzc2lvbi9hY2Nlc3Muc2VydmljZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5hdmlnYXRpb25Ob2RlIHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgaWNvbj86IHN0cmluZztcbiAgICB1cmw6IHN0cmluZztcbiAgICBjaGlsZHJlbj86IEFycmF5PE5hdmlnYXRpb25Ob2RlPjtcbiAgICBsZXZlbD86IG51bWJlcjtcbiAgICB0cmFuc2xhdGU/OiBib29sZWFuO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25jYy1hYnN0cmFjdC1uYXZpZ2F0aW9uLXRyZWUnLFxuICAgIHRlbXBsYXRlOiAnJ1xufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE5hdmlnYXRpb25UcmVlQ29tcG9uZW50IGV4dGVuZHMgQWJzdHJhY3ROYXZpZ2F0aW9uUmVzaXphYmxlRHJhd2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgQElucHV0KCkgcHVibGljIHZpZXdQYXRoOiBzdHJpbmc7XG4gICAgQElucHV0KCkgcHVibGljIHBhcmVudFVybDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHB1YmxpYyByb3V0ZXJDaGFuZ2U6IGJvb2xlYW47XG5cbiAgICBwcm90ZWN0ZWQgX3JlbG9hZE5hdmlnYXRpb246IFJlcGxheVN1YmplY3Q8dm9pZD47XG5cbiAgICBwcml2YXRlIF9zdWJzY3JpcHRpb25zOiBBcnJheTxTdWJzY3JpcHRpb24+O1xuICAgIHByaXZhdGUgX3N1Ykdyb3VwUmVzb2x1dGlvbjogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgX3N1YkxhbmdDaGFuZ2U6IFN1YnNjcmlwdGlvbjtcblxuICAgIHRyZWVDb250cm9sOiBOZXN0ZWRUcmVlQ29udHJvbDxOYXZpZ2F0aW9uTm9kZT47XG4gICAgZGF0YVNvdXJjZTogTWF0VHJlZU5lc3RlZERhdGFTb3VyY2U8TmF2aWdhdGlvbk5vZGU+O1xuXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfY29uZmlnOiBDb25maWd1cmF0aW9uU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9yb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdXNlclNlcnZpY2U6IFVzZXJTZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2FjY2Vzc1NlcnZpY2U6IEFjY2Vzc1NlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfYWN0aXZlR3JvdXBTZXJ2aWNlOiBBY3RpdmVHcm91cFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdGFza1Jlc291cmNlU2VydmljZTogVGFza1Jlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sYW5ndWFnZVNlcnZpY2U6IExhbmd1YWdlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9uYXZpZ2F0aW9uUm91dGVQcm92aWRlcjogRHluYW1pY05hdmlnYXRpb25Sb3V0ZVByb3ZpZGVyU2VydmljZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnRyZWVDb250cm9sID0gbmV3IE5lc3RlZFRyZWVDb250cm9sPE5hdmlnYXRpb25Ob2RlPihub2RlID0+IG5vZGUuY2hpbGRyZW4pO1xuICAgICAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VHJlZU5lc3RlZERhdGFTb3VyY2U8TmF2aWdhdGlvbk5vZGU+KCk7XG4gICAgICAgIHRoaXMuZGF0YVNvdXJjZS5kYXRhID0gdGhpcy5yZXNvbHZlTmF2aWdhdGlvbk5vZGVzKF9jb25maWcuZ2V0Q29uZmlndXJhdGlvblN1YnRyZWUoWyd2aWV3cyddKSwgJycpO1xuICAgICAgICB0aGlzLnJlc29sdmVMZXZlbHModGhpcy5kYXRhU291cmNlLmRhdGEpO1xuICAgICAgICB0aGlzLl9yZWxvYWROYXZpZ2F0aW9uID0gbmV3IFJlcGxheVN1YmplY3Q8dm9pZD4oMSk7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgICAgIGlmICh0aGlzLnZpZXdQYXRoICYmIHRoaXMucGFyZW50VXJsICE9PSB1bmRlZmluZWQgJiYgdGhpcy5yb3V0ZXJDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlc1dpdGhPZmZzZXRSb290KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9zdWJzY3JpcHRpb25zID0gW1xuICAgICAgICAgICAgdGhpcy5fcm91dGVyLmV2ZW50cy5waXBlKGZpbHRlcihldmVudCA9PiBldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQgJiYgdGhpcy5yb3V0ZXJDaGFuZ2UpKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcmVsb2FkTmF2aWdhdGlvbi5uZXh0KCkpLFxuICAgICAgICAgICAgdGhpcy5fdXNlclNlcnZpY2UudXNlciQuc3Vic2NyaWJlKCgpID0+IHRoaXMuX3JlbG9hZE5hdmlnYXRpb24ubmV4dCgpKSxcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZUdyb3VwU2VydmljZS5hY3RpdmVHcm91cHMkLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yZWxvYWROYXZpZ2F0aW9uLm5leHQoKSlcbiAgICAgICAgXTtcblxuICAgICAgICB0aGlzLl9zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgICAgICB0aGlzLl9yZWxvYWROYXZpZ2F0aW9uLnBpcGUoZGVib3VuY2VUaW1lKDEwMCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlTmF2aWdhdGlvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgZm9yIChjb25zdCBzdWIgb2YgdGhpcy5fc3Vic2NyaXB0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFzdWIuY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcmVsb2FkTmF2aWdhdGlvbi5jb21wbGV0ZSgpO1xuICAgICAgICBpZiAodGhpcy5fc3ViR3JvdXBSZXNvbHV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N1Ykdyb3VwUmVzb2x1dGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9zdWJMYW5nQ2hhbmdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N1YkxhbmdDaGFuZ2UudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBoYXNDaGlsZChfOiBudW1iZXIsIG5vZGU6IE5hdmlnYXRpb25Ob2RlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIW5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZXNvbHZlTmF2aWdhdGlvbigpOiB2b2lkIHtcbiAgICAgICAgbGV0IG5vZGVzO1xuICAgICAgICBpZiAodGhpcy52aWV3UGF0aCAmJiB0aGlzLnBhcmVudFVybCAhPT0gdW5kZWZpbmVkICYmIHRoaXMucm91dGVyQ2hhbmdlKSB7XG4gICAgICAgICAgICBub2RlcyA9IHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlc1dpdGhPZmZzZXRSb290KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBub2RlcyA9IHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlcyh0aGlzLl9jb25maWcuZ2V0Q29uZmlndXJhdGlvblN1YnRyZWUoWyd2aWV3cyddKSwgJycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGF0YVNvdXJjZS5kYXRhID0gbm9kZXM7XG4gICAgICAgIHRoaXMucmVzb2x2ZUxldmVscyh0aGlzLmRhdGFTb3VyY2UuZGF0YSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlc29sdmVOYXZpZ2F0aW9uTm9kZXNXaXRoT2Zmc2V0Um9vdCgpOiBBcnJheTxOYXZpZ2F0aW9uTm9kZT4ge1xuICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy5fY29uZmlnLmdldFZpZXdCeVBhdGgodGhpcy52aWV3UGF0aCk7XG4gICAgICAgIGlmICh2aWV3ICYmIHZpZXcuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVOYXZpZ2F0aW9uTm9kZXModmlldy5jaGlsZHJlbiwgdGhpcy5wYXJlbnRVcmwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFTb3VyY2UuZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQge0BsaW5rIFZpZXdzfSBvYmplY3QgaW50byB0aGUgY29ycmVzcG9uZGluZyBuYXZpZ2F0aW9uIHRyZWVcbiAgICAgKiBAcGFyYW0gdmlld3MgbmF2aWdhdGlvbiBjb25maWd1cmF0aW9uXG4gICAgICogQHBhcmFtIHBhcmVudFVybCBVUkwgb2YgdGhlIHBhcmVudCBuYXZpZ2F0aW9uIHRyZWUgbm9kZVxuICAgICAqIEBwYXJhbSBhbmNlc3Rvck5vZGVDb250YWluZXIgaWYgdGhlIHBhcmVudCBub2RlIGhhcyBubyBuYXZpZ2F0aW9uIHRoaXMgYXR0cmlidXRlIGNvbnRhaW5zIHRoZVxuICAgICAqIGNsb3Nlc3QgYW5jZXN0b3IgdGhhdCBoYXMgbmF2aWdhdGlvblxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZU5hdmlnYXRpb25Ob2RlcyhcbiAgICAgICAgdmlld3M6IFZpZXdzLFxuICAgICAgICBwYXJlbnRVcmw6IHN0cmluZyxcbiAgICAgICAgYW5jZXN0b3JOb2RlQ29udGFpbmVyPzogQXJyYXk8TmF2aWdhdGlvbk5vZGU+XG4gICAgKTogQXJyYXk8TmF2aWdhdGlvbk5vZGU+IHtcbiAgICAgICAgaWYgKCF2aWV3cyB8fCBPYmplY3Qua2V5cyh2aWV3cykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5vZGVzOiBBcnJheTxOYXZpZ2F0aW9uTm9kZT4gPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXModmlld3MpLmZvckVhY2goKHZpZXdLZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmlldyA9IHZpZXdzW3ZpZXdLZXldO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFzTmF2aWdhdGlvbih2aWV3KSAmJiAhdGhpcy5oYXNTdWJSb3V0ZXModmlldykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByb3V0ZVNlZ21lbnQgPSB0aGlzLmdldE5vZGVSb3V0ZVNlZ21lbnQodmlldyk7XG5cbiAgICAgICAgICAgIGlmIChyb3V0ZVNlZ21lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUm91dGUgc2VnbWVudCBkb2VzbnQgZXhpc3QgaW4gdmlldyAnICsgcGFyZW50VXJsICsgJy8nICsgdmlld0tleSArICcgIScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMuX2FjY2Vzc1NlcnZpY2UuY2FuQWNjZXNzVmlldyh2aWV3LCB0aGlzLmFwcGVuZFJvdXRlU2VnbWVudChwYXJlbnRVcmwsIHJvdXRlU2VnbWVudCkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBjb250aW51ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5oYXNOYXZpZ2F0aW9uKHZpZXcpKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm9kZTogTmF2aWdhdGlvbk5vZGUgPSB0aGlzLmJ1aWxkTm9kZSh2aWV3LCByb3V0ZVNlZ21lbnQsIHBhcmVudFVybCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFzU3ViUm91dGVzKHZpZXcpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSB0aGlzLnJlc29sdmVOYXZpZ2F0aW9uTm9kZXModmlldy5jaGlsZHJlbiwgbm9kZS51cmwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBub2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNTdWJSb3V0ZXModmlldykpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZXMucHVzaCguLi50aGlzLnJlc29sdmVOYXZpZ2F0aW9uTm9kZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3LmNoaWxkcmVuLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRSb3V0ZVNlZ21lbnQocGFyZW50VXJsLCByb3V0ZVNlZ21lbnQpLCBhbmNlc3Rvck5vZGVDb250YWluZXIgPz8gbm9kZXMpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBoYXNOYXZpZ2F0aW9uKHJvdXRlOiBWaWV3KTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghcm91dGUubmF2aWdhdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygcm91dGUubmF2aWdhdGlvbiA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gcm91dGUubmF2aWdhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHJvdXRlLm5hdmlnYXRpb24gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMocm91dGUubmF2aWdhdGlvbikubGVuZ3RoICE9PSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGhhc1N1YlJvdXRlcyhyb3V0ZTogVmlldyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXJvdXRlLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiByb3V0ZS5jaGlsZHJlbiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhyb3V0ZS5jaGlsZHJlbikubGVuZ3RoICE9PSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGJ1aWxkTm9kZSh2aWV3OiBWaWV3LCByb3V0ZVNlZ21lbnQ6IHN0cmluZywgcGFyZW50VXJsOiBzdHJpbmcpOiBOYXZpZ2F0aW9uTm9kZSB7XG4gICAgICAgIGNvbnN0IG5vZGU6IE5hdmlnYXRpb25Ob2RlID0ge1xuICAgICAgICAgICAgbmFtZTogbnVsbCxcbiAgICAgICAgICAgIHVybDogbnVsbFxuICAgICAgICB9O1xuICAgICAgICBub2RlLm5hbWUgPSB0aGlzLmdldE5vZGVOYW1lKHZpZXcsIHJvdXRlU2VnbWVudCk7XG4gICAgICAgIG5vZGUuaWNvbiA9IHRoaXMuZ2V0Tm9kZUljb24odmlldyk7XG4gICAgICAgIG5vZGUudXJsID0gdGhpcy5hcHBlbmRSb3V0ZVNlZ21lbnQocGFyZW50VXJsLCByb3V0ZVNlZ21lbnQpO1xuICAgICAgICBub2RlLnRyYW5zbGF0ZSA9IHRoaXMuZ2V0Tm9kZVRyYW5zbGF0ZUZsYWcodmlldyk7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXROb2RlTmFtZSh2aWV3OiBWaWV3LCByb3V0ZVNlZ21lbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICh2aWV3Lm5hdmlnYXRpb25bJ3RpdGxlJ10pIHtcbiAgICAgICAgICAgIHJldHVybiB2aWV3Lm5hdmlnYXRpb25bJ3RpdGxlJ107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyID0gcm91dGVTZWdtZW50LnJlcGxhY2UoJ18nLCAnICcpO1xuICAgICAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnN1YnN0cmluZygxKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0Tm9kZUljb24odmlldzogVmlldyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAhdmlldy5uYXZpZ2F0aW9uWydpY29uJ10gPyB1bmRlZmluZWQgOiB2aWV3Lm5hdmlnYXRpb25bJ2ljb24nXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gdmlldyBjb25maWd1cmF0aW9uIG9mIHNvbWUgdmlldywgd2hvc2Ugcm91dGVTZWdtZW50IHdlIHdhbnQgdG8gZGV0ZXJtaW5lXG4gICAgICogQHJldHVybnMgdGhlIHJvdXRlU2VnbWVudCBmb3IgdGhlIHByb3ZpZGVkIHZpZXcsIG9yIHVuZGVmaW5lZCBpZiBub25lIGlzIHNwZWNpZmllZFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBnZXROb2RlUm91dGVTZWdtZW50KHZpZXc6IFZpZXcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gISF2aWV3LnJvdXRpbmcgJiYgKHR5cGVvZiB2aWV3LnJvdXRpbmcucGF0aCA9PT0gJ3N0cmluZycpID8gdmlldy5yb3V0aW5nLnBhdGggOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldE5vZGVUcmFuc2xhdGVGbGFnKHZpZXc6IFZpZXcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHZpZXcubmF2aWdhdGlvblsndHJhbnNsYXRlJ10gPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwZW5kcyB0aGUgcm91dGUgc2VnbWVudCB0byB0aGUgcGFyZW50IFVSTC5cbiAgICAgKiBAcGFyYW0gcGFyZW50VXJsIFVSTCBvZiB0aGUgcGFyZW50LiBTaG91bGQgbm90IGVuZCB3aXRoICcvJ1xuICAgICAqIEBwYXJhbSByb3V0ZVNlZ21lbnQgVVJMIHNlZ21lbnQgb2YgdGhlIGNoaWxkXG4gICAgICogQHJldHVybnMgYHBhcmVudFVybC9yb3V0ZVNlZ21lbnRgIGlmIHRoZSBgcm91dGVTZWdtZW50YCBpcyB0cnV0aHkgKG5vdCBhbiBlbXB0eSBzdHJpbmcpLlxuICAgICAqIFJldHVybnMgYHBhcmVudFVybGAgaWYgYHJvdXRlU2VnbWVudGAgaXMgZmFsc3kgKGVtcHR5IHN0cmluZykuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFwcGVuZFJvdXRlU2VnbWVudChwYXJlbnRVcmw6IHN0cmluZywgcm91dGVTZWdtZW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gcm91dGVTZWdtZW50ID8gcGFyZW50VXJsICsgJy8nICsgcm91dGVTZWdtZW50IDogcGFyZW50VXJsO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZXNvbHZlTGV2ZWxzKG5vZGVzOiBBcnJheTxOYXZpZ2F0aW9uTm9kZT4sIHBhcmVudExldmVsPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICghbm9kZXMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdXJyZW50TGV2ZWwgPSBwYXJlbnRMZXZlbCA9PT0gbnVsbCB8fCBwYXJlbnRMZXZlbCA9PT0gdW5kZWZpbmVkID8gMCA6IHBhcmVudExldmVsICsgMTtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5vZGUubGV2ZWwgPSBjdXJyZW50TGV2ZWw7XG4gICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUxldmVscyhub2RlLmNoaWxkcmVuLCBjdXJyZW50TGV2ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZUNoYW5nZSgpIHtcbiAgICAgICAgY29uc3QgdmlldyA9IHRoaXMuX2NvbmZpZy5nZXRWaWV3QnlQYXRoKHRoaXMudmlld1BhdGgpO1xuICAgICAgICBpZiAodmlldyAmJiB2aWV3LmNoaWxkcmVuKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFTb3VyY2UuZGF0YSA9IHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlcyh2aWV3LmNoaWxkcmVuLCB0aGlzLnBhcmVudFVybCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNvbHZlTGV2ZWxzKHRoaXMuZGF0YVNvdXJjZS5kYXRhKTtcbiAgICB9XG59XG4iXX0=