angular-traversal
Version:
A traversal navigation library for Angular (v2+)
334 lines • 49.1 kB
JavaScript
import { Injectable, ComponentFactoryResolver, Inject, InjectionToken, Optional, Compiler, Injector, } from '@angular/core';
import { Location } from '@angular/common';
import { HttpParams } from '@angular/common/http';
import { BehaviorSubject, of, Subject } from 'rxjs';
import { take, withLatestFrom, map } from 'rxjs/operators';
import { Resolver } from './resolver';
import { Marker } from './marker';
import { Normalizer } from './normalizer';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "./resolver";
import * as i3 from "./marker";
import * as i4 from "./normalizer";
export const NAVIGATION_PREFIX = new InjectionToken('traversal.prefix');
export class Traverser {
constructor(location, resolver, marker, normalizer, ngResolver, compiler, injector, prefix) {
this.location = location;
this.resolver = resolver;
this.marker = marker;
this.normalizer = normalizer;
this.ngResolver = ngResolver;
this.compiler = compiler;
this.injector = injector;
this.prefix = prefix;
this.beforeTraverse = new Subject();
this.traverseTo = new Subject();
this.echo = new Subject();
this.canTraverse = new Subject();
this.tilesContexts = {};
this.tileUpdates = new Subject();
this.views = {};
this.lazy = {};
this.lazyModules = {};
this.tiles = {};
this.target = new BehaviorSubject(this.getEmptyTarget());
let answers = [];
this.echo.subscribe((ok) => {
answers.push(ok);
if (answers.length === this.beforeTraverse.observers.length) {
this.canTraverse.next(answers.every((yes) => yes));
}
});
this.traverseTo.pipe(withLatestFrom(this.canTraverse)).subscribe(([traverse, ok]) => {
if (ok) {
this._traverse(traverse.path, traverse.navigate);
}
else {
this.location.replaceState(this.target.getValue().path);
}
answers = [];
});
}
traverse(path, navigate = true) {
path = this.normalizer.normalize(this.getFullPath(path));
const obsCount = this.beforeTraverse.observers.length;
if (obsCount > 0) {
this.beforeTraverse.next([this.echo, path]);
}
else {
this.canTraverse.next(true);
}
this.traverseTo.next({ path, navigate });
}
_traverse(path, navigate) {
let contextPath = path;
let queryString = '';
let view = 'view';
if (path.indexOf('?') > -1) {
[contextPath, queryString] = contextPath.split('?');
}
else if (path.indexOf(';') > -1) {
[contextPath, queryString] = contextPath.split(';');
}
if (path.indexOf('@@') > -1) {
view = contextPath.split('@@')[1];
contextPath = contextPath.split('@@')[0];
if (contextPath.length > 1 && contextPath.slice(-1) === '/') {
contextPath = contextPath.slice(0, -1);
}
}
if (navigate) {
let navigateTo = path;
if (!contextPath) {
// if no contextPath, preserve the previous one
if (navigateTo[0] !== '/') {
navigateTo = '/' + navigateTo;
}
navigateTo = this.target.value.contextPath + navigateTo;
}
if (this.location.path() !== this.getPrefix() + navigateTo) {
this.location.go(this.getPrefix() + navigateTo);
}
}
let components = this.views[view];
if (!components && view.includes('/')) {
const prefix = view.split('/')[0];
if (!!this.lazyModules[prefix] && this.views[prefix]) {
components = this.views[prefix];
}
}
this.emitTarget(path, contextPath, queryString, view, this.target, components);
}
traverseHere(includeHash = true) {
const here = this.location.path().replace(this.getPrefix(), '');
this.traverse(!includeHash ? here.split('?')[0] : here);
}
addView(name, target, component) {
if (!this.views[name]) {
this.views[name] = {};
}
this.views[name][target] = component;
}
addLazyView(name, target, loader) {
if (!this.views[name]) {
this.views[name] = {};
}
const id = name + ';' + target;
this.views[name][target] = id;
this.lazy[id] = loader;
this.lazyModules[name] = true;
}
loadLazyView(moduleId, viewName, isTile = false) {
return this.lazy[moduleId]().then((module) => {
this.compiler.compileModuleAsync(module).then((factory) => {
factory.create(this.injector);
});
const moduleViews = module.traverserViews || [];
moduleViews.forEach((view) => {
this.views[view.name] = !!this.views[view.name]
? Object.assign(Object.assign({}, this.views[view.name]), view.components) : view.components;
});
const moduleTiles = module.traverserTiles || [];
moduleTiles.forEach((tile) => {
this.tiles[tile.name] = !!this.tiles[tile.name]
? Object.assign(Object.assign({}, this.tiles[tile.name]), tile.components) : tile.components;
});
const target = moduleId.split(';')[1];
return (isTile ? this.tiles : this.views)[viewName][target];
});
}
addTile(name, target, component) {
if (!this.tiles[name]) {
this.tiles[name] = {};
}
this.tiles[name][target] = component;
this.tilesContexts[name] = new BehaviorSubject(this.getEmptyTarget());
}
loadTile(name, path) {
path = this.normalizer.normalize(this.getFullPath(path));
let contextPath = path;
let queryString = '';
if (path.includes('?')) {
[contextPath, queryString] = contextPath.split('?');
}
this.emitTarget(path, contextPath, queryString, name, this.tilesContexts[name], this.tiles[name], true);
}
emptyTile(name) {
if (!!this.tilesContexts[name]) {
this._emit(this.tilesContexts[name], this.getEmptyTarget(), name, true);
}
}
addLazyTile(name, target, loader) {
if (!this.tiles[name]) {
this.tiles[name] = {};
}
const id = name + ';' + target;
this.tiles[name][target] = id;
this.tilesContexts[name] = new BehaviorSubject(this.getEmptyTarget());
this.lazy[id] = loader;
this.lazyModules[name] = true;
}
emitTarget(path, contextPath, queryString, viewOrTile, targetObs, components, isTile = false, currentContext) {
if (!!targetObs && !!components) {
let resolver;
if (!!currentContext) {
resolver = of(currentContext);
}
else if (!contextPath && // if we have no context path
Object.keys(targetObs.value.context).length > 0 && // and we have context
// and query string did not change
!!targetObs.value.query &&
queryString === Object.assign(new HttpParams(), targetObs.value.query).toString()) {
// then we keep the current context
resolver = of(targetObs.value.context);
contextPath = targetObs.value.contextPath;
}
else {
resolver = this._resolve(contextPath, viewOrTile, queryString);
}
if (resolver) {
resolver.pipe(take(1)).subscribe((context) => {
const marker = this.marker.mark(context);
let component = '';
if (marker instanceof Array) {
const matches = marker.filter((m) => components[m]);
if (matches.length > 0) {
component = components[matches[0]];
}
}
else {
component = components[marker];
}
if (!component) {
component = components['*'];
}
if (!!component) {
const promise = typeof component === 'string'
? this.loadLazyView(component, viewOrTile, isTile)
: Promise.resolve(component);
promise.then((comp) => {
const target = !!component
? {
context,
path,
prefixedPath: this.getPrefix() + path,
contextPath,
prefixedContextPath: this.getPrefix() + contextPath,
view: viewOrTile,
component: comp,
query: new HttpParams({ fromString: queryString || '' }),
}
: this.getEmptyTarget();
this._emit(targetObs, target, viewOrTile, isTile);
});
}
else {
this._emit(targetObs, this.getEmptyTarget(), viewOrTile, isTile);
}
});
}
}
}
_emit(targetObs, target, viewOrTile, isTile) {
targetObs.next(target);
if (isTile) {
this.tileUpdates.next({
tile: viewOrTile,
target,
});
}
}
_resolve(path, view, queryString) {
return this.resolver.resolve(path, view, queryString);
}
resolve(path, view, queryString) {
return this._resolve(this.normalizer.normalize(this.getFullPath(path)), view, queryString);
}
getFullPath(path) {
if (path === '.') {
path = this.target.value.contextPath;
}
else if (path.startsWith('./')) {
path =
this.target.value.contextPath === '/' ? path.slice(1) : this.target.value.contextPath + path.slice(1);
}
else if (path.startsWith('../') || path === '..') {
const current = this.target.value.contextPath.split('/');
path = path
.split('/')
.reduce((all, chunk) => {
if (chunk === '..') {
all.pop();
}
else {
all.push(chunk);
}
return all;
}, current)
.join('/');
}
return path;
}
getComponent(component) {
return this.ngResolver.resolveComponentFactory(component);
}
getEmptyTarget() {
return {
component: null,
context: {},
contextPath: '',
prefixedContextPath: this.getPrefix(),
path: '',
prefixedPath: this.getPrefix(),
query: new HttpParams(),
view: 'view',
};
}
getQueryParams() {
return this.target.pipe(take(1), map((target) => {
const queryParams = Object.assign(new HttpParams(), target.query);
if (!queryParams) {
return {};
}
else {
return queryParams.keys().reduce((all, key) => {
const value = queryParams.getAll(key);
if (!value) {
return all;
}
if (value.length > 1) {
all[key] = value;
}
else {
all[key] = value[0];
}
return all;
}, {});
}
}));
}
getPrefix() {
return !!this.prefix ? this.prefix.getValue() : '';
}
setPrefix(prefix) {
this.prefix.next(prefix.startsWith('/') ? prefix : `/${prefix}`);
}
}
Traverser.ɵprov = i0.ɵɵdefineInjectable({ factory: function Traverser_Factory() { return new Traverser(i0.ɵɵinject(i1.Location), i0.ɵɵinject(i2.Resolver), i0.ɵɵinject(i3.Marker), i0.ɵɵinject(i4.Normalizer), i0.ɵɵinject(i0.ComponentFactoryResolver), i0.ɵɵinject(i0.Compiler), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(NAVIGATION_PREFIX, 8)); }, token: Traverser, providedIn: "root" });
Traverser.decorators = [
{ type: Injectable, args: [{
providedIn: 'root',
},] }
];
Traverser.ctorParameters = () => [
{ type: Location },
{ type: Resolver },
{ type: Marker },
{ type: Normalizer },
{ type: ComponentFactoryResolver },
{ type: Compiler },
{ type: Injector },
{ type: BehaviorSubject, decorators: [{ type: Optional }, { type: Inject, args: [NAVIGATION_PREFIX,] }] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhdmVyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdHJhdmVyc2FsL3NyYy9saWIvdHJhdmVyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCxVQUFVLEVBQ1Ysd0JBQXdCLEVBRXhCLE1BQU0sRUFDTixjQUFjLEVBQ2QsUUFBUSxFQUVSLFFBQVEsRUFDUixRQUFRLEdBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEVBQUUsRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEUsT0FBTyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7OztBQUsxQyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGNBQWMsQ0FBMEIsa0JBQWtCLENBQUMsQ0FBQztBQUtqRyxNQUFNLE9BQU8sU0FBUztJQWFsQixZQUNZLFFBQWtCLEVBQ2xCLFFBQWtCLEVBQ2xCLE1BQWMsRUFDZCxVQUFzQixFQUN0QixVQUFvQyxFQUNwQyxRQUFrQixFQUNsQixRQUFrQixFQUNxQixNQUErQjtRQVB0RSxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsZUFBVSxHQUFWLFVBQVUsQ0FBMEI7UUFD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QUFlLHVCQW1DZixRQUFRLFlBQUksTUFBTSxTQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgSW5qZWN0YWJsZSxcbiAgICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgQ29tcG9uZW50RmFjdG9yeSxcbiAgICBJbmplY3QsXG4gICAgSW5qZWN0aW9uVG9rZW4sXG4gICAgT3B0aW9uYWwsXG4gICAgVHlwZSxcbiAgICBDb21waWxlcixcbiAgICBJbmplY3Rvcixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwUGFyYW1zIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBvZiwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZSwgd2l0aExhdGVzdEZyb20sIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFJlc29sdmVyIH0gZnJvbSAnLi9yZXNvbHZlcic7XG5pbXBvcnQgeyBNYXJrZXIgfSBmcm9tICcuL21hcmtlcic7XG5pbXBvcnQgeyBOb3JtYWxpemVyIH0gZnJvbSAnLi9ub3JtYWxpemVyJztcbmltcG9ydCB7IFRhcmdldCwgSHR0cFBhcmFtc09wdGlvbnMsIE1vZHVsZVdpdGhWaWV3cywgVmlld01hcHBpbmcgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuXG5leHBvcnQgdHlwZSBMYXp5VmlldyA9ICgpID0+IFByb21pc2U8VHlwZTxhbnk+PjtcblxuZXhwb3J0IGNvbnN0IE5BVklHQVRJT05fUFJFRklYID0gbmV3IEluamVjdGlvblRva2VuPEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+PigndHJhdmVyc2FsLnByZWZpeCcpO1xuXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBUcmF2ZXJzZXIge1xuICAgIHRhcmdldDogQmVoYXZpb3JTdWJqZWN0PFRhcmdldD47XG4gICAgYmVmb3JlVHJhdmVyc2U6IFN1YmplY3Q8W1N1YmplY3Q8Ym9vbGVhbj4sIHN0cmluZ10+ID0gbmV3IFN1YmplY3QoKTtcbiAgICB0cmF2ZXJzZVRvOiBTdWJqZWN0PHsgcGF0aDogc3RyaW5nOyBuYXZpZ2F0ZTogYm9vbGVhbiB9PiA9IG5ldyBTdWJqZWN0KCk7XG4gICAgZWNobzogU3ViamVjdDxib29sZWFuPiA9IG5ldyBTdWJqZWN0KCk7XG4gICAgY2FuVHJhdmVyc2U6IFN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgU3ViamVjdCgpO1xuICAgIHRpbGVzQ29udGV4dHM6IHsgW25hbWU6IHN0cmluZ106IEJlaGF2aW9yU3ViamVjdDxUYXJnZXQ+IH0gPSB7fTtcbiAgICB0aWxlVXBkYXRlczogU3ViamVjdDx7IHRpbGU6IHN0cmluZzsgdGFyZ2V0OiBUYXJnZXQgfT4gPSBuZXcgU3ViamVjdCgpO1xuICAgIHByaXZhdGUgdmlld3M6IHsgW25hbWU6IHN0cmluZ106IFZpZXdNYXBwaW5nIHwgeyBbdGFyZ2V0OiBzdHJpbmddOiBzdHJpbmcgfSB9ID0ge307XG4gICAgcHJpdmF0ZSBsYXp5OiB7IFtpZDogc3RyaW5nXTogTGF6eVZpZXcgfSA9IHt9O1xuICAgIHByaXZhdGUgbGF6eU1vZHVsZXM6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcbiAgICBwcml2YXRlIHRpbGVzOiB7IFtuYW1lOiBzdHJpbmddOiB7IFt0YXJnZXQ6IHN0cmluZ106IGFueSB9IH0gPSB7fTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgICAgICAgcHJpdmF0ZSByZXNvbHZlcjogUmVzb2x2ZXIsXG4gICAgICAgIHByaXZhdGUgbWFya2VyOiBNYXJrZXIsXG4gICAgICAgIHByaXZhdGUgbm9ybWFsaXplcjogTm9ybWFsaXplcixcbiAgICAgICAgcHJpdmF0ZSBuZ1Jlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgICAgIHByaXZhdGUgY29tcGlsZXI6IENvbXBpbGVyLFxuICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChOQVZJR0FUSU9OX1BSRUZJWCkgcHJpdmF0ZSBwcmVmaXg6IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+XG4gICAgKSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gbmV3IEJlaGF2aW9yU3ViamVjdCh0aGlzLmdldEVtcHR5VGFyZ2V0KCkpO1xuICAgICAgICBsZXQgYW5zd2VyczogYm9vbGVhbltdID0gW107XG4gICAgICAgIHRoaXMuZWNoby5zdWJzY3JpYmUoKG9rKSA9PiB7XG4gICAgICAgICAgICBhbnN3ZXJzLnB1c2gob2spO1xuICAgICAgICAgICAgaWYgKGFuc3dlcnMubGVuZ3RoID09PSB0aGlzLmJlZm9yZVRyYXZlcnNlLm9ic2VydmVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhblRyYXZlcnNlLm5leHQoYW5zd2Vycy5ldmVyeSgoeWVzKSA9PiB5ZXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudHJhdmVyc2VUby5waXBlKHdpdGhMYXRlc3RGcm9tKHRoaXMuY2FuVHJhdmVyc2UpKS5zdWJzY3JpYmUoKFt0cmF2ZXJzZSwgb2tdKSA9PiB7XG4gICAgICAgICAgICBpZiAob2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmF2ZXJzZSh0cmF2ZXJzZS5wYXRoLCB0cmF2ZXJzZS5uYXZpZ2F0ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9jYXRpb24ucmVwbGFjZVN0YXRlKHRoaXMudGFyZ2V0LmdldFZhbHVlKCkucGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhbnN3ZXJzID0gW107XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHRyYXZlcnNlKHBhdGg6IHN0cmluZywgbmF2aWdhdGU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgICAgIHBhdGggPSB0aGlzLm5vcm1hbGl6ZXIubm9ybWFsaXplKHRoaXMuZ2V0RnVsbFBhdGgocGF0aCkpO1xuICAgICAgICBjb25zdCBvYnNDb3VudCA9IHRoaXMuYmVmb3JlVHJhdmVyc2Uub2JzZXJ2ZXJzLmxlbmd0aDtcbiAgICAgICAgaWYgKG9ic0NvdW50ID4gMCkge1xuICAgICAgICAgICAgdGhpcy5iZWZvcmVUcmF2ZXJzZS5uZXh0KFt0aGlzLmVjaG8sIHBhdGhdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FuVHJhdmVyc2UubmV4dCh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyYXZlcnNlVG8ubmV4dCh7IHBhdGgsIG5hdmlnYXRlIH0pO1xuICAgIH1cblxuICAgIF90cmF2ZXJzZShwYXRoOiBzdHJpbmcsIG5hdmlnYXRlOiBib29sZWFuKSB7XG4gICAgICAgIGxldCBjb250ZXh0UGF0aDogc3RyaW5nID0gcGF0aDtcbiAgICAgICAgbGV0IHF1ZXJ5U3RyaW5nID0gJyc7XG4gICAgICAgIGxldCB2aWV3ID0gJ3ZpZXcnO1xuICAgICAgICBpZiAocGF0aC5pbmRleE9mKCc/JykgPiAtMSkge1xuICAgICAgICAgICAgW2NvbnRleHRQYXRoLCBxdWVyeVN0cmluZ10gPSBjb250ZXh0UGF0aC5zcGxpdCgnPycpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhdGguaW5kZXhPZignOycpID4gLTEpIHtcbiAgICAgICAgICAgIFtjb250ZXh0UGF0aCwgcXVlcnlTdHJpbmddID0gY29udGV4dFBhdGguc3BsaXQoJzsnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGF0aC5pbmRleE9mKCdAQCcpID4gLTEpIHtcbiAgICAgICAgICAgIHZpZXcgPSBjb250ZXh0UGF0aC5zcGxpdCgnQEAnKVsxXTtcbiAgICAgICAgICAgIGNvbnRleHRQYXRoID0gY29udGV4dFBhdGguc3BsaXQoJ0BAJylbMF07XG4gICAgICAgICAgICBpZiAoY29udGV4dFBhdGgubGVuZ3RoID4gMSAmJiBjb250ZXh0UGF0aC5zbGljZSgtMSkgPT09ICcvJykge1xuICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoID0gY29udGV4dFBhdGguc2xpY2UoMCwgLTEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChuYXZpZ2F0ZSkge1xuICAgICAgICAgICAgbGV0IG5hdmlnYXRlVG8gPSBwYXRoO1xuICAgICAgICAgICAgaWYgKCFjb250ZXh0UGF0aCkge1xuICAgICAgICAgICAgICAgIC8vIGlmIG5vIGNvbnRleHRQYXRoLCBwcmVzZXJ2ZSB0aGUgcHJldmlvdXMgb25lXG4gICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRlVG9bMF0gIT09ICcvJykge1xuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0ZVRvID0gJy8nICsgbmF2aWdhdGVUbztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmF2aWdhdGVUbyA9IHRoaXMudGFyZ2V0LnZhbHVlLmNvbnRleHRQYXRoICsgbmF2aWdhdGVUbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmxvY2F0aW9uLnBhdGgoKSAhPT0gdGhpcy5nZXRQcmVmaXgoKSArIG5hdmlnYXRlVG8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2F0aW9uLmdvKHRoaXMuZ2V0UHJlZml4KCkgKyBuYXZpZ2F0ZVRvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgY29tcG9uZW50cyA9IHRoaXMudmlld3Nbdmlld107XG4gICAgICAgIGlmICghY29tcG9uZW50cyAmJiB2aWV3LmluY2x1ZGVzKCcvJykpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IHZpZXcuc3BsaXQoJy8nKVswXTtcbiAgICAgICAgICAgIGlmICghIXRoaXMubGF6eU1vZHVsZXNbcHJlZml4XSAmJiB0aGlzLnZpZXdzW3ByZWZpeF0pIHtcbiAgICAgICAgICAgICAgICBjb21wb25lbnRzID0gdGhpcy52aWV3c1twcmVmaXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuZW1pdFRhcmdldChwYXRoLCBjb250ZXh0UGF0aCwgcXVlcnlTdHJpbmcsIHZpZXcsIHRoaXMudGFyZ2V0LCBjb21wb25lbnRzKTtcbiAgICB9XG5cbiAgICB0cmF2ZXJzZUhlcmUoaW5jbHVkZUhhc2ggPSB0cnVlKSB7XG4gICAgICAgIGNvbnN0IGhlcmUgPSB0aGlzLmxvY2F0aW9uLnBhdGgoKS5yZXBsYWNlKHRoaXMuZ2V0UHJlZml4KCksICcnKTtcbiAgICAgICAgdGhpcy50cmF2ZXJzZSghaW5jbHVkZUhhc2ggPyBoZXJlLnNwbGl0KCc/JylbMF0gOiBoZXJlKTtcbiAgICB9XG5cbiAgICBhZGRWaWV3KG5hbWU6IHN0cmluZywgdGFyZ2V0OiBzdHJpbmcsIGNvbXBvbmVudDogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy52aWV3c1tuYW1lXSkge1xuICAgICAgICAgICAgdGhpcy52aWV3c1tuYW1lXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgICh0aGlzLnZpZXdzW25hbWVdIGFzIHsgW3RhcmdldDogc3RyaW5nXTogc3RyaW5nIH0pW3RhcmdldF0gPSBjb21wb25lbnQ7XG4gICAgfVxuXG4gICAgYWRkTGF6eVZpZXcobmFtZTogc3RyaW5nLCB0YXJnZXQ6IHN0cmluZywgbG9hZGVyOiBMYXp5Vmlldykge1xuICAgICAgICBpZiAoIXRoaXMudmlld3NbbmFtZV0pIHtcbiAgICAgICAgICAgIHRoaXMudmlld3NbbmFtZV0gPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpZCA9IG5hbWUgKyAnOycgKyB0YXJnZXQ7XG4gICAgICAgICh0aGlzLnZpZXdzW25hbWVdIGFzIHsgW3RhcmdldDogc3RyaW5nXTogc3RyaW5nIH0pW3RhcmdldF0gPSBpZDtcbiAgICAgICAgdGhpcy5sYXp5W2lkXSA9IGxvYWRlcjtcbiAgICAgICAgdGhpcy5sYXp5TW9kdWxlc1tuYW1lXSA9IHRydWU7XG4gICAgfVxuXG4gICAgbG9hZExhenlWaWV3KG1vZHVsZUlkOiBzdHJpbmcsIHZpZXdOYW1lOiBzdHJpbmcsIGlzVGlsZSA9IGZhbHNlKTogUHJvbWlzZTxUeXBlPGFueT4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGF6eVttb2R1bGVJZF0oKS50aGVuKChtb2R1bGUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29tcGlsZXIuY29tcGlsZU1vZHVsZUFzeW5jKG1vZHVsZSkudGhlbigoZmFjdG9yeSkgPT4ge1xuICAgICAgICAgICAgICAgIGZhY3RvcnkuY3JlYXRlKHRoaXMuaW5qZWN0b3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBtb2R1bGVWaWV3cyA9IChtb2R1bGUgYXMgTW9kdWxlV2l0aFZpZXdzKS50cmF2ZXJzZXJWaWV3cyB8fCBbXTtcbiAgICAgICAgICAgIG1vZHVsZVZpZXdzLmZvckVhY2goKHZpZXcpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdzW3ZpZXcubmFtZV0gPSAhIXRoaXMudmlld3Nbdmlldy5uYW1lXVxuICAgICAgICAgICAgICAgICAgICA/IHsgLi4udGhpcy52aWV3c1t2aWV3Lm5hbWVdLCAuLi52aWV3LmNvbXBvbmVudHMgfVxuICAgICAgICAgICAgICAgICAgICA6IHZpZXcuY29tcG9uZW50cztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlVGlsZXMgPSAobW9kdWxlIGFzIE1vZHVsZVdpdGhWaWV3cykudHJhdmVyc2VyVGlsZXMgfHwgW107XG4gICAgICAgICAgICBtb2R1bGVUaWxlcy5mb3JFYWNoKCh0aWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50aWxlc1t0aWxlLm5hbWVdID0gISF0aGlzLnRpbGVzW3RpbGUubmFtZV1cbiAgICAgICAgICAgICAgICAgICAgPyB7IC4uLnRoaXMudGlsZXNbdGlsZS5uYW1lXSwgLi4udGlsZS5jb21wb25lbnRzIH1cbiAgICAgICAgICAgICAgICAgICAgOiB0aWxlLmNvbXBvbmVudHM7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IG1vZHVsZUlkLnNwbGl0KCc7JylbMV07XG4gICAgICAgICAgICByZXR1cm4gKGlzVGlsZSA/IHRoaXMudGlsZXMgOiB0aGlzLnZpZXdzKVt2aWV3TmFtZV1bdGFyZ2V0XSBhcyBUeXBlPGFueT47XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFkZFRpbGUobmFtZTogc3RyaW5nLCB0YXJnZXQ6IHN0cmluZywgY29tcG9uZW50OiBhbnkpIHtcbiAgICAgICAgaWYgKCF0aGlzLnRpbGVzW25hbWVdKSB7XG4gICAgICAgICAgICB0aGlzLnRpbGVzW25hbWVdID0ge307XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aWxlc1tuYW1lXVt0YXJnZXRdID0gY29tcG9uZW50O1xuICAgICAgICB0aGlzLnRpbGVzQ29udGV4dHNbbmFtZV0gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHRoaXMuZ2V0RW1wdHlUYXJnZXQoKSk7XG4gICAgfVxuXG4gICAgbG9hZFRpbGUobmFtZTogc3RyaW5nLCBwYXRoOiBzdHJpbmcpIHtcbiAgICAgICAgcGF0aCA9IHRoaXMubm9ybWFsaXplci5ub3JtYWxpemUodGhpcy5nZXRGdWxsUGF0aChwYXRoKSk7XG4gICAgICAgIGxldCBjb250ZXh0UGF0aDogc3RyaW5nID0gcGF0aDtcbiAgICAgICAgbGV0IHF1ZXJ5U3RyaW5nID0gJyc7XG4gICAgICAgIGlmIChwYXRoLmluY2x1ZGVzKCc/JykpIHtcbiAgICAgICAgICAgIFtjb250ZXh0UGF0aCwgcXVlcnlTdHJpbmddID0gY29udGV4dFBhdGguc3BsaXQoJz8nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXRUYXJnZXQocGF0aCwgY29udGV4dFBhdGgsIHF1ZXJ5U3RyaW5nLCBuYW1lLCB0aGlzLnRpbGVzQ29udGV4dHNbbmFtZV0sIHRoaXMudGlsZXNbbmFtZV0sIHRydWUpO1xuICAgIH1cblxuICAgIGVtcHR5VGlsZShuYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCEhdGhpcy50aWxlc0NvbnRleHRzW25hbWVdKSB7XG4gICAgICAgICAgICB0aGlzLl9lbWl0KHRoaXMudGlsZXNDb250ZXh0c1tuYW1lXSwgdGhpcy5nZXRFbXB0eVRhcmdldCgpLCBuYW1lLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZExhenlUaWxlKG5hbWU6IHN0cmluZywgdGFyZ2V0OiBzdHJpbmcsIGxvYWRlcjogTGF6eVZpZXcpIHtcbiAgICAgICAgaWYgKCF0aGlzLnRpbGVzW25hbWVdKSB7XG4gICAgICAgICAgICB0aGlzLnRpbGVzW25hbWVdID0ge307XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaWQgPSBuYW1lICsgJzsnICsgdGFyZ2V0O1xuICAgICAgICB0aGlzLnRpbGVzW25hbWVdW3RhcmdldF0gPSBpZDtcbiAgICAgICAgdGhpcy50aWxlc0NvbnRleHRzW25hbWVdID0gbmV3IEJlaGF2aW9yU3ViamVjdCh0aGlzLmdldEVtcHR5VGFyZ2V0KCkpO1xuICAgICAgICB0aGlzLmxhenlbaWRdID0gbG9hZGVyO1xuICAgICAgICB0aGlzLmxhenlNb2R1bGVzW25hbWVdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBlbWl0VGFyZ2V0KFxuICAgICAgICBwYXRoOiBzdHJpbmcsXG4gICAgICAgIGNvbnRleHRQYXRoOiBzdHJpbmcsXG4gICAgICAgIHF1ZXJ5U3RyaW5nOiBzdHJpbmcsXG4gICAgICAgIHZpZXdPclRpbGU6IHN0cmluZyxcbiAgICAgICAgdGFyZ2V0T2JzOiBCZWhhdmlvclN1YmplY3Q8VGFyZ2V0PixcbiAgICAgICAgY29tcG9uZW50czogeyBbdGFyZ2V0OiBzdHJpbmddOiBhbnkgfSxcbiAgICAgICAgaXNUaWxlID0gZmFsc2UsXG4gICAgICAgIGN1cnJlbnRDb250ZXh0PzogYW55XG4gICAgKSB7XG4gICAgICAgIGlmICghIXRhcmdldE9icyAmJiAhIWNvbXBvbmVudHMpIHtcbiAgICAgICAgICAgIGxldCByZXNvbHZlcjogT2JzZXJ2YWJsZTxhbnk+O1xuICAgICAgICAgICAgaWYgKCEhY3VycmVudENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlciA9IG9mKGN1cnJlbnRDb250ZXh0KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgIWNvbnRleHRQYXRoICYmIC8vIGlmIHdlIGhhdmUgbm8gY29udGV4dCBwYXRoXG4gICAgICAgICAgICAgICAgT2JqZWN0LmtleXModGFyZ2V0T2JzLnZhbHVlLmNvbnRleHQpLmxlbmd0aCA+IDAgJiYgLy8gYW5kIHdlIGhhdmUgY29udGV4dFxuICAgICAgICAgICAgICAgIC8vIGFuZCBxdWVyeSBzdHJpbmcgZGlkIG5vdCBjaGFuZ2VcbiAgICAgICAgICAgICAgICAhIXRhcmdldE9icy52YWx1ZS5xdWVyeSAmJlxuICAgICAgICAgICAgICAgIHF1ZXJ5U3RyaW5nID09PSBPYmplY3QuYXNzaWduKG5ldyBIdHRwUGFyYW1zKCksIHRhcmdldE9icy52YWx1ZS5xdWVyeSkudG9TdHJpbmcoKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhlbiB3ZSBrZWVwIHRoZSBjdXJyZW50IGNvbnRleHRcbiAgICAgICAgICAgICAgICByZXNvbHZlciA9IG9mKHRhcmdldE9icy52YWx1ZS5jb250ZXh0KTtcbiAgICAgICAgICAgICAgICBjb250ZXh0UGF0aCA9IHRhcmdldE9icy52YWx1ZS5jb250ZXh0UGF0aDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZXIgPSB0aGlzLl9yZXNvbHZlKGNvbnRleHRQYXRoLCB2aWV3T3JUaWxlLCBxdWVyeVN0cmluZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzb2x2ZXIpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlci5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoY29udGV4dDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMubWFya2VyLm1hcmsoY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnQ6IFR5cGU8YW55PiB8IHN0cmluZyA9ICcnO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWFya2VyIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSBtYXJrZXIuZmlsdGVyKChtKSA9PiBjb21wb25lbnRzW21dKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnRzW21hdGNoZXNbMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50ID0gY29tcG9uZW50c1ttYXJrZXJdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnRzWycqJ107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgY29tcG9uZW50ID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMubG9hZExhenlWaWV3KGNvbXBvbmVudCwgdmlld09yVGlsZSwgaXNUaWxlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFByb21pc2UucmVzb2x2ZShjb21wb25lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZS50aGVuKChjb21wKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gISFjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlZFBhdGg6IHRoaXMuZ2V0UHJlZml4KCkgKyBwYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0UGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ZWRDb250ZXh0UGF0aDogdGhpcy5nZXRQcmVmaXgoKSArIGNvbnRleHRQYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3OiB2aWV3T3JUaWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQ6IGNvbXAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5OiBuZXcgSHR0cFBhcmFtcyh7IGZyb21TdHJpbmc6IHF1ZXJ5U3RyaW5nIHx8ICcnIH0gYXMgSHR0cFBhcmFtc09wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gYXMgVGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuZ2V0RW1wdHlUYXJnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbWl0KHRhcmdldE9icywgdGFyZ2V0LCB2aWV3T3JUaWxlLCBpc1RpbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbWl0KHRhcmdldE9icywgdGhpcy5nZXRFbXB0eVRhcmdldCgpLCB2aWV3T3JUaWxlLCBpc1RpbGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfZW1pdCh0YXJnZXRPYnM6IEJlaGF2aW9yU3ViamVjdDxUYXJnZXQ+LCB0YXJnZXQ6IFRhcmdldCwgdmlld09yVGlsZTogc3RyaW5nLCBpc1RpbGU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGFyZ2V0T2JzLm5leHQodGFyZ2V0KTtcbiAgICAgICAgaWYgKGlzVGlsZSkge1xuICAgICAgICAgICAgdGhpcy50aWxlVXBkYXRlcy5uZXh0KHtcbiAgICAgICAgICAgICAgICB0aWxlOiB2aWV3T3JUaWxlLFxuICAgICAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3Jlc29sdmUocGF0aDogc3RyaW5nLCB2aWV3PzogYW55LCBxdWVyeVN0cmluZz86IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVyLnJlc29sdmUocGF0aCwgdmlldywgcXVlcnlTdHJpbmcpO1xuICAgIH1cblxuICAgIHJlc29sdmUocGF0aDogc3RyaW5nLCB2aWV3PzogYW55LCBxdWVyeVN0cmluZz86IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNvbHZlKHRoaXMubm9ybWFsaXplci5ub3JtYWxpemUodGhpcy5nZXRGdWxsUGF0aChwYXRoKSksIHZpZXcsIHF1ZXJ5U3RyaW5nKTtcbiAgICB9XG5cbiAgICBnZXRGdWxsUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAocGF0aCA9PT0gJy4nKSB7XG4gICAgICAgICAgICBwYXRoID0gdGhpcy50YXJnZXQudmFsdWUuY29udGV4dFBhdGg7XG4gICAgICAgIH0gZWxzZSBpZiAocGF0aC5zdGFydHNXaXRoKCcuLycpKSB7XG4gICAgICAgICAgICBwYXRoID1cbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC52YWx1ZS5jb250ZXh0UGF0aCA9PT0gJy8nID8gcGF0aC5zbGljZSgxKSA6IHRoaXMudGFyZ2V0LnZhbHVlLmNvbnRleHRQYXRoICsgcGF0aC5zbGljZSgxKTtcbiAgICAgICAgfSBlbHNlIGlmIChwYXRoLnN0YXJ0c1dpdGgoJy4uLycpIHx8IHBhdGggPT09ICcuLicpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnRhcmdldC52YWx1ZS5jb250ZXh0UGF0aC5zcGxpdCgnLycpO1xuICAgICAgICAgICAgcGF0aCA9IHBhdGhcbiAgICAgICAgICAgICAgICAuc3BsaXQoJy8nKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKGFsbCwgY2h1bmspID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNodW5rID09PSAnLi4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbGwucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbGwucHVzaChjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFsbDtcbiAgICAgICAgICAgICAgICB9LCBjdXJyZW50KVxuICAgICAgICAgICAgICAgIC5qb2luKCcvJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfVxuXG4gICAgZ2V0Q29tcG9uZW50KGNvbXBvbmVudDogYW55KTogQ29tcG9uZW50RmFjdG9yeTx1bmtub3duPiB7XG4gICAgICAgIHJldHVybiB0aGlzLm5nUmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoY29tcG9uZW50KTtcbiAgICB9XG5cbiAgICBnZXRFbXB0eVRhcmdldCgpOiBUYXJnZXQge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29tcG9uZW50OiBudWxsLFxuICAgICAgICAgICAgY29udGV4dDoge30sXG4gICAgICAgICAgICBjb250ZXh0UGF0aDogJycsXG4gICAgICAgICAgICBwcmVmaXhlZENvbnRleHRQYXRoOiB0aGlzLmdldFByZWZpeCgpLFxuICAgICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgICBwcmVmaXhlZFBhdGg6IHRoaXMuZ2V0UHJlZml4KCksXG4gICAgICAgICAgICBxdWVyeTogbmV3IEh0dHBQYXJhbXMoKSxcbiAgICAgICAgICAgIHZpZXc6ICd2aWV3JyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXRRdWVyeVBhcmFtczxUID0gc3RyaW5nPigpOiBPYnNlcnZhYmxlPHsgW2tleTogc3RyaW5nXTogVCB9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRhcmdldC5waXBlKFxuICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgIG1hcCgodGFyZ2V0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBPYmplY3QuYXNzaWduKG5ldyBIdHRwUGFyYW1zKCksIHRhcmdldC5xdWVyeSk7XG4gICAgICAgICAgICAgICAgaWYgKCFxdWVyeVBhcmFtcykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHF1ZXJ5UGFyYW1zLmtleXMoKS5yZWR1Y2UoKGFsbDogeyBba2V5OiBzdHJpbmddOiBUIH0sIGtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBxdWVyeVBhcmFtcy5nZXRBbGwoa2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxba2V5XSA9ICh2YWx1ZSBhcyB1bmtub3duKSBhcyBUO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxba2V5XSA9ICh2YWx1ZVswXSBhcyB1bmtub3duKSBhcyBUO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFsbDtcbiAgICAgICAgICAgICAgICAgICAgfSwge30pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZ2V0UHJlZml4KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAhIXRoaXMucHJlZml4ID8gdGhpcy5wcmVmaXguZ2V0VmFsdWUoKSA6ICcnO1xuICAgIH1cblxuICAgIHNldFByZWZpeChwcmVmaXg6IHN0cmluZykge1xuICAgICAgICB0aGlzLnByZWZpeC5uZXh0KHByZWZpeC5zdGFydHNXaXRoKCcvJykgPyBwcmVmaXggOiBgLyR7cHJlZml4fWApO1xuICAgIH1cbn1cbiJdfQ==