ng-material-multilevel-menu-2
Version:
625 lines • 63.7 kB
JavaScript
import { NgModule, Injectable, Component, Input, Output, EventEmitter, defineInjectable } from '@angular/core';
import { MatIconModule, MatListModule, MatRippleModule } from '@angular/material';
import { Router, NavigationEnd } from '@angular/router';
import { trigger, style, transition, animate, state, group } from '@angular/animations';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class MaterialsModule {
}
MaterialsModule.decorators = [
{ type: NgModule, args: [{
imports: [
MatIconModule,
MatListModule,
MatRippleModule,
],
declarations: [],
exports: [
MatIconModule,
MatListModule,
MatRippleModule,
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class MultilevelMenuService {
/**
* @return {?}
*/
generateId() {
/** @type {?} */
let text = '';
/** @type {?} */
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 20; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
/**
* @param {?} nodes
* @return {?}
*/
addRandomId(nodes) {
nodes.forEach((node) => {
node.id = this.generateId();
if (node.items !== undefined) {
this.addRandomId(node.items);
}
});
}
/**
* @param {?} node
* @param {?} nodeId
* @return {?}
*/
recursiveCheckId(node, nodeId) {
if (node.id === nodeId) {
return true;
}
else {
if (node.items !== undefined) {
return node.items.some((nestedNode) => {
return this.recursiveCheckId(nestedNode, nodeId);
});
}
}
}
/**
* @param {?} nodes
* @param {?} link
* @return {?}
*/
recursiveCheckLink(nodes, link) {
for (let nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
/** @type {?} */
const node = nodes[nodeIndex];
for (const key in node) {
if (node.hasOwnProperty(key)) {
if (encodeURI(node.link) === link) {
this.foundLinkObject = node;
}
else {
if (node.items !== undefined) {
this.recursiveCheckLink(node.items, link);
}
}
}
}
}
}
/**
* @param {?} node
* @param {?} link
* @return {?}
*/
getMatchedObjectByUrl(node, link) {
this.recursiveCheckLink(node, link);
return this.foundLinkObject;
}
}
MultilevelMenuService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */ MultilevelMenuService.ngInjectableDef = defineInjectable({ factory: function MultilevelMenuService_Factory() { return new MultilevelMenuService(); }, token: MultilevelMenuService, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @type {?} */
const CONSTANT = {
PADDING_AT_START: true,
DEFAULT_CLASS_NAME: `amml-container`,
DEFAULT_LIST_CLASS_NAME: `amml-item`,
SELECTED_LIST_CLASS_NAME: `selected-amml-item`,
DEFAULT_SELECTED_FONT_COLOR: `#1976d2`,
DEFAULT_LIST_BACKGROUND_COLOR: `transparent`,
DEFAULT_LIST_FONT_COLOR: `rgba(0,0,0,.87)`,
ERROR_MESSAGE: `Invalid data for material Multilevel List Component`
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class NgMaterialMultilevelMenuComponent {
/**
* @param {?} router
* @param {?} multilevelMenuService
*/
constructor(router, multilevelMenuService) {
this.router = router;
this.multilevelMenuService = multilevelMenuService;
this.configuration = null;
this.selectedItem = new EventEmitter();
this.selectedLabel = new EventEmitter();
this.hasDivider = true;
this.nodeConfig = {
paddingAtStart: true,
listBackgroundColor: null,
fontColor: null,
selectedListFontColor: null,
interfaceWithRoute: null,
collapseOnSelect: null,
highlightOnSelect: false,
rtlLayout: false
};
this.isInvalidConfig = true;
}
/**
* @return {?}
*/
ngOnChanges() {
this.checkValiddata();
this.detectInvalidConfig();
}
/**
* @return {?}
*/
ngOnInit() {
if (this.configuration !== null &&
this.configuration !== undefined &&
this.configuration !== '' &&
this.configuration.interfaceWithRoute !== null &&
this.configuration.interfaceWithRoute) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
this.updateNodeByURL(event.url);
}
});
this.updateNodeByURL(this.router.url);
}
}
/**
* @param {?} url
* @return {?}
*/
updateNodeByURL(url) {
/** @type {?} */
const foundNode = this.multilevelMenuService.getMatchedObjectByUrl(this.items, url);
if (foundNode !== undefined &&
foundNode.link !== undefined &&
foundNode.link !== null &&
foundNode.link !== '') {
this.currentNode = foundNode;
this.selectedListItem(foundNode);
}
}
/**
* @return {?}
*/
checkValiddata() {
if (this.items.length === 0) {
console.warn(CONSTANT.ERROR_MESSAGE);
}
else {
this.items = this.items.filter(n => !n.hidden);
this.multilevelMenuService.addRandomId(this.items);
}
}
/**
* @return {?}
*/
detectInvalidConfig() {
if (this.configuration === null ||
this.configuration === undefined ||
this.configuration === '') {
this.isInvalidConfig = true;
}
else {
this.isInvalidConfig = false;
/** @type {?} */
const config = this.configuration;
if (config.paddingAtStart !== undefined &&
config.paddingAtStart !== null &&
typeof config.paddingAtStart === 'boolean') {
this.nodeConfig.paddingAtStart = config.paddingAtStart;
}
if (config.listBackgroundColor !== '' &&
config.listBackgroundColor !== null &&
config.listBackgroundColor !== undefined) {
this.nodeConfig.listBackgroundColor = config.listBackgroundColor;
}
if (config.fontColor !== '' &&
config.fontColor !== null &&
config.fontColor !== undefined) {
this.nodeConfig.fontColor = config.fontColor;
}
if (config.selectedListFontColor !== '' &&
config.selectedListFontColor !== null &&
config.selectedListFontColor !== undefined) {
this.nodeConfig.selectedListFontColor = config.selectedListFontColor;
}
if (config.interfaceWithRoute !== null &&
config.interfaceWithRoute !== undefined &&
typeof config.interfaceWithRoute === 'boolean') {
this.nodeConfig.interfaceWithRoute = config.interfaceWithRoute;
}
if (config.collapseOnSelect !== null &&
config.collapseOnSelect !== undefined &&
typeof config.collapseOnSelect === 'boolean') {
this.nodeConfig.collapseOnSelect = config.collapseOnSelect;
}
if (config.highlightOnSelect !== null &&
config.highlightOnSelect !== undefined &&
typeof config.highlightOnSelect === 'boolean') {
this.nodeConfig.highlightOnSelect = config.highlightOnSelect;
}
if (config.rtlLayout !== null &&
config.rtlLayout !== undefined &&
typeof config.rtlLayout === 'boolean') {
this.nodeConfig.rtlLayout = config.rtlLayout;
}
}
}
/**
* @return {?}
*/
getClassName() {
if (this.isInvalidConfig) {
return CONSTANT.DEFAULT_CLASS_NAME;
}
else {
if (this.configuration.classname !== '' &&
this.configuration.classname !== null &&
this.configuration.classname !== undefined) {
return `${CONSTANT.DEFAULT_CLASS_NAME} ${this.configuration.classname}`;
}
else {
return CONSTANT.DEFAULT_CLASS_NAME;
}
}
}
/**
* @return {?}
*/
getGlobalStyle() {
if (!this.isInvalidConfig) {
/** @type {?} */
const styles = {
background: null
};
if (this.configuration.backgroundColor !== '' &&
this.configuration.backgroundColor !== null &&
this.configuration.backgroundColor !== undefined) {
styles.background = this.configuration.backgroundColor;
}
return styles;
}
}
/**
* @return {?}
*/
isRtlLayout() {
return this.nodeConfig.rtlLayout;
}
/**
* @param {?} event
* @return {?}
*/
selectedListItem(event) {
this.currentNode = event;
if (event.items === undefined &&
(!event.onSelected || typeof event.onSelected !== 'function')) {
this.selectedItem.emit(event);
}
else {
this.selectedLabel.emit(event);
}
}
}
NgMaterialMultilevelMenuComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-material-multilevel-menu',
template: `<div [ngClass]="getClassName()" [ngStyle]="getGlobalStyle()" *ngIf='items.length !== 0' [dir]="isRtlLayout() ? 'rtl' : 'ltr'">
<mat-list>
<ng-list-item *ngFor="let node of items" [nodeConfiguration]='nodeConfig' [node]='node' [selectedNode]='currentNode' [hasDivider]="hasDivider" (selectedItem)="selectedListItem($event)
">
</ng-list-item>
</mat-list>
</div>`,
styles: [`.amml-item{line-height:48px;display:flex;justify-content:space-between;position:relative}.anml-data{width:100%;text-transform:capitalize;display:flex;justify-content:start}.amml-icon-fa{font-size:20px}.amml-icon{line-height:48px}.active{color:#1976d2}div[dir=ltr] .amml-icon{margin-right:15px}div[dir=ltr] .amml-submenu{margin-left:16px}div[dir=rtl] .amml-icon{margin-left:15px}div[dir=rtl] .amml-submenu{margin-right:16px}`]
},] },
];
NgMaterialMultilevelMenuComponent.ctorParameters = () => [
{ type: Router },
{ type: MultilevelMenuService }
];
NgMaterialMultilevelMenuComponent.propDecorators = {
items: [{ type: Input }],
configuration: [{ type: Input }],
selectedItem: [{ type: Output }],
selectedLabel: [{ type: Output }],
hasDivider: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class ListItemComponent {
/**
* @param {?} router
* @param {?} multilevelMenuService
*/
constructor(router, multilevelMenuService) {
this.router = router;
this.multilevelMenuService = multilevelMenuService;
this.level = 1;
this.nodeConfiguration = null;
this.selectedItem = new EventEmitter();
this.hasDivider = true;
this.isSelected = false;
this.expanded = false;
this.firstInitializer = false;
this.selectedListClasses = {
[CONSTANT.DEFAULT_LIST_CLASS_NAME]: true,
[CONSTANT.SELECTED_LIST_CLASS_NAME]: false
};
}
/**
* @return {?}
*/
ngOnChanges() {
this.nodeChildren =
this.node && this.node.items
? this.node.items.filter(n => !n.hidden)
: [];
if (this.selectedNode !== undefined && this.selectedNode !== null) {
this.setSelectedClass(this.multilevelMenuService.recursiveCheckId(this.node, this.selectedNode.id));
}
}
/**
* @param {?} isFound
* @return {?}
*/
setSelectedClass(isFound) {
if (isFound) {
if (!this.firstInitializer) {
this.expanded = true;
}
this.isSelected =
this.nodeConfiguration.highlightOnSelect ||
this.selectedNode.items === undefined
? true
: false;
}
else {
this.isSelected = false;
if (this.nodeConfiguration.collapseOnSelect) {
this.expanded = false;
}
}
this.selectedListClasses = {
[CONSTANT.DEFAULT_LIST_CLASS_NAME]: true,
[CONSTANT.SELECTED_LIST_CLASS_NAME]: this.isSelected
};
this.setClasses();
}
/**
* @return {?}
*/
getPaddingAtStart() {
return this.nodeConfiguration.paddingAtStart ? true : false;
}
/**
* @return {?}
*/
getListStyle() {
/** @type {?} */
const styles = {
background: CONSTANT.DEFAULT_LIST_BACKGROUND_COLOR,
color: CONSTANT.DEFAULT_LIST_FONT_COLOR
};
if (this.nodeConfiguration.listBackgroundColor !== null) {
styles.background = this.nodeConfiguration.listBackgroundColor;
}
if (this.isSelected) {
this.nodeConfiguration.selectedListFontColor !== null
? (styles.color = this.nodeConfiguration.selectedListFontColor)
: (styles.color = CONSTANT.DEFAULT_SELECTED_FONT_COLOR);
}
else if (this.nodeConfiguration.fontColor !== null) {
styles.color = this.nodeConfiguration.fontColor;
}
return styles;
}
/**
* @param {?} node
* @return {?}
*/
getListIcon(node) {
if (node.icon !== null && node.icon !== undefined && node.icon !== '') {
return `icon`;
}
else if (node.faIcon !== null &&
node.faIcon !== undefined &&
node.faIcon !== '') {
return `faicon`;
}
else if (node.imageIcon !== null &&
node.imageIcon !== undefined &&
node.imageIcon !== '') {
return `imageicon`;
}
else {
return ``;
}
}
/**
* @return {?}
*/
hasItems() {
return this.nodeChildren.length > 0 ? true : false;
}
/**
* @return {?}
*/
isRtlLayout() {
return this.nodeConfiguration.rtlLayout;
}
/**
* @return {?}
*/
setClasses() {
this.classes = {
['level-' + this.level]: true,
'amml-submenu': this.hasItems() && this.getPaddingAtStart()
};
}
/**
* @param {?} node
* @return {?}
*/
expand(node) {
this.expanded = !this.expanded;
this.firstInitializer = true;
this.setClasses();
if (this.nodeConfiguration.interfaceWithRoute !== null &&
this.nodeConfiguration.interfaceWithRoute &&
node.link !== undefined &&
node.link) {
if (node.externalRedirect !== undefined && node.externalRedirect) {
window.location.href = node.link;
}
else {
this.router.navigate([node.link]);
}
}
else if (node.onSelected && typeof node.onSelected === 'function') {
node.onSelected(node);
this.selectedListItem(node);
}
else if (node.items === undefined ||
this.nodeConfiguration.collapseOnSelect) {
this.selectedListItem(node);
}
}
/**
* @param {?} node
* @return {?}
*/
selectedListItem(node) {
this.selectedItem.emit(node);
}
}
ListItemComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-list-item',
template: `<mat-list-item matRipple [ngClass]="selectedListClasses" *ngIf="!node.hidden" (click)="expand(node)" title="{{node.label}}" [ngStyle]="getListStyle()">
<div class="anml-data" [dir]="isRtlLayout() ? 'rtl' : 'ltr'">
<div class="icon-container" [ngSwitch]="getListIcon(node)">
<span *ngSwitchCase="'faicon'" class="amml-icon amml-icon-fa">
<i [ngClass]="node.faIcon"></i>
</span>
<mat-icon *ngSwitchCase="'icon'" class="amml-icon">
{{node.icon}}
</mat-icon>
<img matListAvatar *ngSwitchCase="'imageicon'" class="amml-icon" src="{{node.imageIcon}}" alt="{{node.label}}" />
</div>
<span class="label">{{node.label}}</span>
</div>
<ng-container *ngIf='hasItems()'>
<mat-icon *ngIf='!isRtlLayout()' [@isExpandedLTR]="hasItems() && expanded ? 'yes' : 'no'">
keyboard_arrow_down
</mat-icon>
<mat-icon *ngIf='isRtlLayout()' [@isExpandedRTL]="hasItems() && expanded ? 'yes' : 'no'">
keyboard_arrow_down
</mat-icon>
</ng-container>
</mat-list-item>
<mat-divider *ngIf="hasDivider"></mat-divider>
<div *ngIf="hasItems() && expanded" [@slideInOut] [dir]="isRtlLayout() ? 'rtl' : 'ltr'" [ngClass]="classes">
<ng-list-item *ngFor="let singleNode of nodeChildren" [hasDivider]="hasDivider" [nodeConfiguration]='nodeConfiguration' [node]='singleNode' [level]="level + 1" [selectedNode]='selectedNode' (selectedItem)="selectedListItem($event)">
</ng-list-item>
</div>`,
styles: [`.amml-item{line-height:48px;position:relative;cursor:pointer}.anml-data{width:100%;text-transform:capitalize;display:flex;justify-content:start;height:48px}.amml-icon-fa{font-size:20px}.amml-icon,.label{line-height:48px}div[dir=ltr] .amml-icon{margin-right:16px}div[dir=ltr].amml-submenu,div[dir=rtl] .amml-icon{margin-left:16px}div[dir=rtl].amml-submenu{margin-right:16px}`],
animations: [
trigger('slideInOut', [
state('in', style({ height: '*', opacity: 0 })),
transition(':leave', [
style({ height: '*', opacity: 0.2 }),
group([
animate(200, style({ height: 0 })),
animate('200ms ease-out', style({ opacity: 0 }))
])
]),
transition(':enter', [
style({ height: '0', opacity: 0 }),
group([
animate(200, style({ height: '*' })),
animate('400ms ease-out', style({ opacity: 1 }))
])
])
]),
trigger('isExpandedLTR', [
state('no', style({ transform: 'rotate(-90deg)' })),
state('yes', style({ transform: 'rotate(0deg)' })),
transition('no => yes', animate(200)),
transition('yes => no', animate(200))
]),
trigger('isExpandedRTL', [
state('no', style({ transform: 'rotate(90deg)' })),
state('yes', style({ transform: 'rotate(0deg)' })),
transition('no => yes', animate(200)),
transition('yes => no', animate(200))
])
]
},] },
];
ListItemComponent.ctorParameters = () => [
{ type: Router },
{ type: MultilevelMenuService }
];
ListItemComponent.propDecorators = {
node: [{ type: Input }],
level: [{ type: Input }],
selectedNode: [{ type: Input }],
nodeConfiguration: [{ type: Input }],
selectedItem: [{ type: Output }],
hasDivider: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class NgMaterialMultilevelMenuModule {
}
NgMaterialMultilevelMenuModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
MaterialsModule
],
declarations: [NgMaterialMultilevelMenuComponent, ListItemComponent],
exports: [NgMaterialMultilevelMenuComponent]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
export { NgMaterialMultilevelMenuModule, ListItemComponent as ɵd, MaterialsModule as ɵa, MultilevelMenuService as ɵc, NgMaterialMultilevelMenuComponent as ɵb };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctbWF0ZXJpYWwtbXVsdGlsZXZlbC1tZW51LTIuanMubWFwIiwic291cmNlcyI6WyJuZzovL25nLW1hdGVyaWFsLW11bHRpbGV2ZWwtbWVudS0yL2xpYi9tYXRlcmlhbHMubW9kdWxlLnRzIiwibmc6Ly9uZy1tYXRlcmlhbC1tdWx0aWxldmVsLW1lbnUtMi9saWIvbXVsdGlsZXZlbC1tZW51LnNlcnZpY2UudHMiLCJuZzovL25nLW1hdGVyaWFsLW11bHRpbGV2ZWwtbWVudS0yL2xpYi9jb25zdGFudHMudHMiLCJuZzovL25nLW1hdGVyaWFsLW11bHRpbGV2ZWwtbWVudS0yL2xpYi9uZy1tYXRlcmlhbC1tdWx0aWxldmVsLW1lbnUuY29tcG9uZW50LnRzIiwibmc6Ly9uZy1tYXRlcmlhbC1tdWx0aWxldmVsLW1lbnUtMi9saWIvbGlzdC1pdGVtL2xpc3QtaXRlbS5jb21wb25lbnQudHMiLCJuZzovL25nLW1hdGVyaWFsLW11bHRpbGV2ZWwtbWVudS0yL2xpYi9uZy1tYXRlcmlhbC1tdWx0aWxldmVsLW1lbnUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQge1xyXG4gIE1hdEljb25Nb2R1bGUsXHJcbiAgTWF0TGlzdE1vZHVsZSxcclxuICBNYXRSaXBwbGVNb2R1bGUsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBpbXBvcnRzOiBbXHJcbiAgICBNYXRJY29uTW9kdWxlLFxyXG4gICAgTWF0TGlzdE1vZHVsZSxcclxuICAgIE1hdFJpcHBsZU1vZHVsZSxcclxuICBdLFxyXG4gIGRlY2xhcmF0aW9uczogW10sXHJcbiAgZXhwb3J0czogW1xyXG4gICAgTWF0SWNvbk1vZHVsZSxcclxuICAgIE1hdExpc3RNb2R1bGUsXHJcbiAgICBNYXRSaXBwbGVNb2R1bGUsXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTWF0ZXJpYWxzTW9kdWxlIHsgfVxyXG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE11bHRpbGV2ZWxOb2RlcyB9IGZyb20gJy4vYXBwLm1vZGVsJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIE11bHRpbGV2ZWxNZW51U2VydmljZSB7XHJcbiAgZm91bmRMaW5rT2JqZWN0OiBNdWx0aWxldmVsTm9kZXM7XHJcbiAgZ2VuZXJhdGVJZCgpOiBzdHJpbmcge1xyXG4gICAgbGV0IHRleHQgPSAnJztcclxuICAgIGNvbnN0IHBvc3NpYmxlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMjA7IGkrKykge1xyXG4gICAgICB0ZXh0ICs9IHBvc3NpYmxlLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBwb3NzaWJsZS5sZW5ndGgpKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0ZXh0O1xyXG4gIH1cclxuICBhZGRSYW5kb21JZChub2RlczogTXVsdGlsZXZlbE5vZGVzW10pOiB2b2lkIHtcclxuICAgIG5vZGVzLmZvckVhY2goKG5vZGU6IE11bHRpbGV2ZWxOb2RlcykgPT4ge1xyXG4gICAgICBub2RlLmlkID0gdGhpcy5nZW5lcmF0ZUlkKCk7XHJcbiAgICAgIGlmIChub2RlLml0ZW1zICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aGlzLmFkZFJhbmRvbUlkKG5vZGUuaXRlbXMpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgcmVjdXJzaXZlQ2hlY2tJZChub2RlOiBNdWx0aWxldmVsTm9kZXMsIG5vZGVJZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBpZiAobm9kZS5pZCA9PT0gbm9kZUlkKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKG5vZGUuaXRlbXMgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiBub2RlLml0ZW1zLnNvbWUoKG5lc3RlZE5vZGU6IE11bHRpbGV2ZWxOb2RlcykgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVjdXJzaXZlQ2hlY2tJZChuZXN0ZWROb2RlLCBub2RlSWQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJlY3Vyc2l2ZUNoZWNrTGluayhub2RlczogTXVsdGlsZXZlbE5vZGVzW10sIGxpbms6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgZm9yIChsZXQgbm9kZUluZGV4ID0gMDsgbm9kZUluZGV4IDwgbm9kZXMubGVuZ3RoOyBub2RlSW5kZXgrKykge1xyXG4gICAgICBjb25zdCBub2RlID0gbm9kZXNbbm9kZUluZGV4XTtcclxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gbm9kZSkge1xyXG4gICAgICAgIGlmIChub2RlLmhhc093blByb3BlcnR5KGtleSkpIHtcclxuICAgICAgICAgIGlmIChlbmNvZGVVUkkobm9kZS5saW5rKSA9PT0gbGluaykge1xyXG4gICAgICAgICAgICB0aGlzLmZvdW5kTGlua09iamVjdCA9IG5vZGU7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAobm9kZS5pdGVtcyAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5yZWN1cnNpdmVDaGVja0xpbmsobm9kZS5pdGVtcywgbGluayk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgZ2V0TWF0Y2hlZE9iamVjdEJ5VXJsKG5vZGU6IE11bHRpbGV2ZWxOb2Rlc1tdLCBsaW5rOiBzdHJpbmcpOiBNdWx0aWxldmVsTm9kZXMge1xyXG4gICAgdGhpcy5yZWN1cnNpdmVDaGVja0xpbmsobm9kZSwgbGluayk7XHJcbiAgICByZXR1cm4gdGhpcy5mb3VuZExpbmtPYmplY3Q7XHJcbiAgfVxyXG59XHJcbiIsImV4cG9ydCBjb25zdCBDT05TVEFOVCA9IHtcclxuICAgIFBBRERJTkdfQVRfU1RBUlQ6IHRydWUsXHJcbiAgICBERUZBVUxUX0NMQVNTX05BTUU6IGBhbW1sLWNvbnRhaW5lcmAsXHJcbiAgICBERUZBVUxUX0xJU1RfQ0xBU1NfTkFNRTogYGFtbWwtaXRlbWAsXHJcbiAgICBTRUxFQ1RFRF9MSVNUX0NMQVNTX05BTUU6IGBzZWxlY3RlZC1hbW1sLWl0ZW1gLFxyXG4gICAgREVGQVVMVF9TRUxFQ1RFRF9GT05UX0NPTE9SOiBgIzE5NzZkMmAsXHJcbiAgICBERUZBVUxUX0xJU1RfQkFDS0dST1VORF9DT0xPUjogYHRyYW5zcGFyZW50YCxcclxuICAgIERFRkFVTFRfTElTVF9GT05UX0NPTE9SOiBgcmdiYSgwLDAsMCwuODcpYCxcclxuICAgIEVSUk9SX01FU1NBR0U6IGBJbnZhbGlkIGRhdGEgZm9yIG1hdGVyaWFsIE11bHRpbGV2ZWwgTGlzdCBDb21wb25lbnRgXHJcbn07XHJcbiIsImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIE9uSW5pdCxcclxuICBPbkNoYW5nZXMsXHJcbiAgSW5wdXQsXHJcbiAgT3V0cHV0LFxyXG4gIEV2ZW50RW1pdHRlclxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBSb3V0ZXIsIE5hdmlnYXRpb25FbmQgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5cclxuaW1wb3J0IHsgTXVsdGlsZXZlbE1lbnVTZXJ2aWNlIH0gZnJvbSAnLi9tdWx0aWxldmVsLW1lbnUuc2VydmljZSc7XHJcblxyXG5pbXBvcnQgeyBDb25maWd1cmF0aW9uLCBNdWx0aWxldmVsTm9kZXMsIEJhY2tncm91bmRTdHlsZSB9IGZyb20gJy4vYXBwLm1vZGVsJztcclxuaW1wb3J0IHsgQ09OU1RBTlQgfSBmcm9tICcuL2NvbnN0YW50cyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25nLW1hdGVyaWFsLW11bHRpbGV2ZWwtbWVudScsXHJcbiAgdGVtcGxhdGU6IGA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZSgpXCIgW25nU3R5bGVdPVwiZ2V0R2xvYmFsU3R5bGUoKVwiICpuZ0lmPSdpdGVtcy5sZW5ndGggIT09IDAnIFtkaXJdPVwiaXNSdGxMYXlvdXQoKSA/ICdydGwnIDogJ2x0cidcIj5cclxuICAgIDxtYXQtbGlzdD5cclxuICAgICAgICA8bmctbGlzdC1pdGVtICpuZ0Zvcj1cImxldCBub2RlIG9mIGl0ZW1zXCIgW25vZGVDb25maWd1cmF0aW9uXT0nbm9kZUNvbmZpZycgW25vZGVdPSdub2RlJyBbc2VsZWN0ZWROb2RlXT0nY3VycmVudE5vZGUnIFtoYXNEaXZpZGVyXT1cImhhc0RpdmlkZXJcIiAoc2VsZWN0ZWRJdGVtKT1cInNlbGVjdGVkTGlzdEl0ZW0oJGV2ZW50KVxyXG4gICAgXCI+XHJcbiAgICAgICAgPC9uZy1saXN0LWl0ZW0+XHJcbiAgICA8L21hdC1saXN0PlxyXG48L2Rpdj5gLFxyXG4gIHN0eWxlczogW2AuYW1tbC1pdGVte2xpbmUtaGVpZ2h0OjQ4cHg7ZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpzcGFjZS1iZXR3ZWVuO3Bvc2l0aW9uOnJlbGF0aXZlfS5hbm1sLWRhdGF7d2lkdGg6MTAwJTt0ZXh0LXRyYW5zZm9ybTpjYXBpdGFsaXplO2Rpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3RhcnR9LmFtbWwtaWNvbi1mYXtmb250LXNpemU6MjBweH0uYW1tbC1pY29ue2xpbmUtaGVpZ2h0OjQ4cHh9LmFjdGl2ZXtjb2xvcjojMTk3NmQyfWRpdltkaXI9bHRyXSAuYW1tbC1pY29ue21hcmdpbi1yaWdodDoxNXB4fWRpdltkaXI9bHRyXSAuYW1tbC1zdWJtZW51e21hcmdpbi1sZWZ0OjE2cHh9ZGl2W2Rpcj1ydGxdIC5hbW1sLWljb257bWFyZ2luLWxlZnQ6MTVweH1kaXZbZGlyPXJ0bF0gLmFtbWwtc3VibWVudXttYXJnaW4tcmlnaHQ6MTZweH1gXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmdNYXRlcmlhbE11bHRpbGV2ZWxNZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xyXG4gIEBJbnB1dCgpIGl0ZW1zOiBNdWx0aWxldmVsTm9kZXNbXTtcclxuICBASW5wdXQoKSBjb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uID0gbnVsbDtcclxuICBAT3V0cHV0KCkgc2VsZWN0ZWRJdGVtID0gbmV3IEV2ZW50RW1pdHRlcjxNdWx0aWxldmVsTm9kZXM+KCk7XHJcbiAgQE91dHB1dCgpIHNlbGVjdGVkTGFiZWwgPSBuZXcgRXZlbnRFbWl0dGVyPE11bHRpbGV2ZWxOb2Rlcz4oKTtcclxuICBASW5wdXQoKSBoYXNEaXZpZGVyID0gdHJ1ZTtcclxuICBjdXJyZW50Tm9kZTogTXVsdGlsZXZlbE5vZGVzO1xyXG4gIG5vZGVDb25maWc6IENvbmZpZ3VyYXRpb24gPSB7XHJcbiAgICBwYWRkaW5nQXRTdGFydDogdHJ1ZSxcclxuICAgIGxpc3RCYWNrZ3JvdW5kQ29sb3I6IG51bGwsXHJcbiAgICBmb250Q29sb3I6IG51bGwsXHJcbiAgICBzZWxlY3RlZExpc3RGb250Q29sb3I6IG51bGwsXHJcbiAgICBpbnRlcmZhY2VXaXRoUm91dGU6IG51bGwsXHJcbiAgICBjb2xsYXBzZU9uU2VsZWN0OiBudWxsLFxyXG4gICAgaGlnaGxpZ2h0T25TZWxlY3Q6IGZhbHNlLFxyXG4gICAgcnRsTGF5b3V0OiBmYWxzZVxyXG4gIH07XHJcbiAgaXNJbnZhbGlkQ29uZmlnID0gdHJ1ZTtcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXHJcbiAgICBwcml2YXRlIG11bHRpbGV2ZWxNZW51U2VydmljZTogTXVsdGlsZXZlbE1lbnVTZXJ2aWNlXHJcbiAgKSB7fVxyXG4gIG5nT25DaGFuZ2VzKCkge1xyXG4gICAgdGhpcy5jaGVja1ZhbGlkZGF0YSgpO1xyXG4gICAgdGhpcy5kZXRlY3RJbnZhbGlkQ29uZmlnKCk7XHJcbiAgfVxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gIT09IG51bGwgJiZcclxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uICE9PSAnJyAmJlxyXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uaW50ZXJmYWNlV2l0aFJvdXRlICE9PSBudWxsICYmXHJcbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pbnRlcmZhY2VXaXRoUm91dGVcclxuICAgICkge1xyXG4gICAgICB0aGlzLnJvdXRlci5ldmVudHMuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kKSB7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZU5vZGVCeVVSTChldmVudC51cmwpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMudXBkYXRlTm9kZUJ5VVJMKHRoaXMucm91dGVyLnVybCk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHVwZGF0ZU5vZGVCeVVSTCh1cmw6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgY29uc3QgZm91bmROb2RlID0gdGhpcy5tdWx0aWxldmVsTWVudVNlcnZpY2UuZ2V0TWF0Y2hlZE9iamVjdEJ5VXJsKFxyXG4gICAgICB0aGlzLml0ZW1zLFxyXG4gICAgICB1cmxcclxuICAgICk7XHJcbiAgICBpZiAoXHJcbiAgICAgIGZvdW5kTm9kZSAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgIGZvdW5kTm9kZS5saW5rICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgZm91bmROb2RlLmxpbmsgIT09IG51bGwgJiZcclxuICAgICAgZm91bmROb2RlLmxpbmsgIT09ICcnXHJcbiAgICApIHtcclxuICAgICAgdGhpcy5jdXJyZW50Tm9kZSA9IGZvdW5kTm9kZTtcclxuICAgICAgdGhpcy5zZWxlY3RlZExpc3RJdGVtKGZvdW5kTm9kZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGNoZWNrVmFsaWRkYXRhKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXRlbXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihDT05TVEFOVC5FUlJPUl9NRVNTQUdFKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaXRlbXMgPSB0aGlzLml0ZW1zLmZpbHRlcihuID0+ICFuLmhpZGRlbik7XHJcbiAgICAgIHRoaXMubXVsdGlsZXZlbE1lbnVTZXJ2aWNlLmFkZFJhbmRvbUlkKHRoaXMuaXRlbXMpO1xyXG4gICAgfVxyXG4gIH1cclxuICBkZXRlY3RJbnZhbGlkQ29uZmlnKCk6IHZvaWQge1xyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPT09IG51bGwgfHxcclxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uID09PSAnJ1xyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuaXNJbnZhbGlkQ29uZmlnID0gdHJ1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaXNJbnZhbGlkQ29uZmlnID0gZmFsc2U7XHJcbiAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlndXJhdGlvbjtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIGNvbmZpZy5wYWRkaW5nQXRTdGFydCAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgY29uZmlnLnBhZGRpbmdBdFN0YXJ0ICE9PSBudWxsICYmXHJcbiAgICAgICAgdHlwZW9mIGNvbmZpZy5wYWRkaW5nQXRTdGFydCA9PT0gJ2Jvb2xlYW4nXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRoaXMubm9kZUNvbmZpZy5wYWRkaW5nQXRTdGFydCA9IGNvbmZpZy5wYWRkaW5nQXRTdGFydDtcclxuICAgICAgfVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgY29uZmlnLmxpc3RCYWNrZ3JvdW5kQ29sb3IgIT09ICcnICYmXHJcbiAgICAgICAgY29uZmlnLmxpc3RCYWNrZ3JvdW5kQ29sb3IgIT09IG51bGwgJiZcclxuICAgICAgICBjb25maWcubGlzdEJhY2tncm91bmRDb2xvciAhPT0gdW5kZWZpbmVkXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRoaXMubm9kZUNvbmZpZy5saXN0QmFja2dyb3VuZENvbG9yID0gY29uZmlnLmxpc3RCYWNrZ3JvdW5kQ29sb3I7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKFxyXG4gICAgICAgIGNvbmZpZy5mb250Q29sb3IgIT09ICcnICYmXHJcbiAgICAgICAgY29uZmlnLmZvbnRDb2xvciAhPT0gbnVsbCAmJlxyXG4gICAgICAgIGNvbmZpZy5mb250Q29sb3IgIT09IHVuZGVmaW5lZFxyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLm5vZGVDb25maWcuZm9udENvbG9yID0gY29uZmlnLmZvbnRDb2xvcjtcclxuICAgICAgfVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgY29uZmlnLnNlbGVjdGVkTGlzdEZvbnRDb2xvciAhPT0gJycgJiZcclxuICAgICAgICBjb25maWcuc2VsZWN0ZWRMaXN0Rm9udENvbG9yICE9PSBudWxsICYmXHJcbiAgICAgICAgY29uZmlnLnNlbGVjdGVkTGlzdEZvbnRDb2xvciAhPT0gdW5kZWZpbmVkXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRoaXMubm9kZUNvbmZpZy5zZWxlY3RlZExpc3RGb250Q29sb3IgPSBjb25maWcuc2VsZWN0ZWRMaXN0Rm9udENvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChcclxuICAgICAgICBjb25maWcuaW50ZXJmYWNlV2l0aFJvdXRlICE9PSBudWxsICYmXHJcbiAgICAgICAgY29uZmlnLmludGVyZmFjZVdpdGhSb3V0ZSAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgdHlwZW9mIGNvbmZpZy5pbnRlcmZhY2VXaXRoUm91dGUgPT09ICdib29sZWFuJ1xyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLm5vZGVDb25maWcuaW50ZXJmYWNlV2l0aFJvdXRlID0gY29uZmlnLmludGVyZmFjZVdpdGhSb3V0ZTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgY29uZmlnLmNvbGxhcHNlT25TZWxlY3QgIT09IG51bGwgJiZcclxuICAgICAgICBjb25maWcuY29sbGFwc2VPblNlbGVjdCAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgdHlwZW9mIGNvbmZpZy5jb2xsYXBzZU9uU2VsZWN0ID09PSAnYm9vbGVhbidcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy5ub2RlQ29uZmlnLmNvbGxhcHNlT25TZWxlY3QgPSBjb25maWcuY29sbGFwc2VPblNlbGVjdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgY29uZmlnLmhpZ2hsaWdodE9uU2VsZWN0ICE9PSBudWxsICYmXHJcbiAgICAgICAgY29uZmlnLmhpZ2hsaWdodE9uU2VsZWN0ICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgICB0eXBlb2YgY29uZmlnLmhpZ2hsaWdodE9uU2VsZWN0ID09PSAnYm9vbGVhbidcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy5ub2RlQ29uZmlnLmhpZ2hsaWdodE9uU2VsZWN0ID0gY29uZmlnLmhpZ2hsaWdodE9uU2VsZWN0O1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChcclxuICAgICAgICBjb25maWcucnRsTGF5b3V0ICE9PSBudWxsICYmXHJcbiAgICAgICAgY29uZmlnLnJ0bExheW91dCAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgdHlwZW9mIGNvbmZpZy5ydGxMYXlvdXQgPT09ICdib29sZWFuJ1xyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLm5vZGVDb25maWcucnRsTGF5b3V0ID0gY29uZmlnLnJ0bExheW91dDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBnZXRDbGFzc05hbWUoKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLmlzSW52YWxpZENvbmZpZykge1xyXG4gICAgICByZXR1cm4gQ09OU1RBTlQuREVGQVVMVF9DTEFTU19OQU1FO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5jbGFzc25hbWUgIT09ICcnICYmXHJcbiAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmNsYXNzbmFtZSAhPT0gbnVsbCAmJlxyXG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5jbGFzc25hbWUgIT09IHVuZGVmaW5lZFxyXG4gICAgICApIHtcclxuICAgICAgICByZXR1cm4gYCR7Q09OU1RBTlQuREVGQVVMVF9DTEFTU19OQU1FfSAke3RoaXMuY29uZmlndXJhdGlvbi5jbGFzc25hbWV9YDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gQ09OU1RBTlQuREVGQVVMVF9DTEFTU19OQU1FO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIGdldEdsb2JhbFN0eWxlKCk6IEJhY2tncm91bmRTdHlsZSB7XHJcbiAgICBpZiAoIXRoaXMuaXNJbnZhbGlkQ29uZmlnKSB7XHJcbiAgICAgIGNvbnN0IHN0eWxlcyA9IHtcclxuICAgICAgICBiYWNrZ3JvdW5kOiBudWxsXHJcbiAgICAgIH07XHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uYmFja2dyb3VuZENvbG9yICE9PSAnJyAmJlxyXG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5iYWNrZ3JvdW5kQ29sb3IgIT09IG51bGwgJiZcclxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uYmFja2dyb3VuZENvbG9yICE9PSB1bmRlZmluZWRcclxuICAgICAgKSB7XHJcbiAgICAgICAgc3R5bGVzLmJhY2tncm91bmQgPSB0aGlzLmNvbmZpZ3VyYXRpb24uYmFja2dyb3VuZENvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBzdHlsZXM7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGlzUnRsTGF5b3V0KCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMubm9kZUNvbmZpZy5ydGxMYXlvdXQ7XHJcbiAgfVxyXG4gIHNlbGVjdGVkTGlzdEl0ZW0oZXZlbnQ6IE11bHRpbGV2ZWxOb2Rlcyk6IHZvaWQge1xyXG4gICAgdGhpcy5jdXJyZW50Tm9kZSA9IGV2ZW50O1xyXG4gICAgaWYgKFxyXG4gICAgICBldmVudC5pdGVtcyA9PT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICghZXZlbnQub25TZWxlY3RlZCB8fCB0eXBlb2YgZXZlbnQub25TZWxlY3RlZCAhPT0gJ2Z1bmN0aW9uJylcclxuICAgICkge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbS5lbWl0KGV2ZW50KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRMYWJlbC5lbWl0KGV2ZW50KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIElucHV0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXJcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHtcclxuICB0cmlnZ2VyLFxyXG4gIHN0eWxlLFxyXG4gIHRyYW5zaXRpb24sXHJcbiAgYW5pbWF0ZSxcclxuICBzdGF0ZSxcclxuICBncm91cFxyXG59IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xyXG5cclxuaW1wb3J0IHsgTXVsdGlsZXZlbE1lbnVTZXJ2aWNlIH0gZnJvbSAnLi8uLi9tdWx0aWxldmVsLW1lbnUuc2VydmljZSc7XHJcblxyXG5pbXBvcnQgeyBDb25maWd1cmF0aW9uLCBNdWx0aWxldmVsTm9kZXMsIExpc3RTdHlsZSB9IGZyb20gJy4vLi4vYXBwLm1vZGVsJztcclxuaW1wb3J0IHsgQ09OU1RBTlQgfSBmcm9tICcuLy4uL2NvbnN0YW50cyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25nLWxpc3QtaXRlbScsXHJcbiAgdGVtcGxhdGU6IGA8bWF0LWxpc3QtaXRlbSBtYXRSaXBwbGUgW25nQ2xhc3NdPVwic2VsZWN0ZWRMaXN0Q2xhc3Nlc1wiICpuZ0lmPVwiIW5vZGUuaGlkZGVuXCIgKGNsaWNrKT1cImV4cGFuZChub2RlKVwiIHRpdGxlPVwie3tub2RlLmxhYmVsfX1cIiBbbmdTdHlsZV09XCJnZXRMaXN0U3R5bGUoKVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImFubWwtZGF0YVwiIFtkaXJdPVwiaXNSdGxMYXlvdXQoKSA/ICdydGwnIDogJ2x0cidcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1jb250YWluZXJcIiBbbmdTd2l0Y2hdPVwiZ2V0TGlzdEljb24obm9kZSlcIj5cclxuICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidmYWljb24nXCIgY2xhc3M9XCJhbW1sLWljb24gYW1tbC1pY29uLWZhXCI+XHJcbiAgICAgICAgPGkgW25nQ2xhc3NdPVwibm9kZS5mYUljb25cIj48L2k+XHJcbiAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgPG1hdC1pY29uICpuZ1N3aXRjaENhc2U9XCInaWNvbidcIiBjbGFzcz1cImFtbWwtaWNvblwiPlxyXG4gICAgICAgICAgICAgICAge3tub2RlLmljb259fVxyXG4gICAgICAgICAgICA8L21hdC1pY29uPlxyXG4gICAgICAgICAgICA8aW1nIG1hdExpc3RBdmF0YXIgKm5nU3dpdGNoQ2FzZT1cIidpbWFnZWljb24nXCIgY2xhc3M9XCJhbW1sLWljb25cIiBzcmM9XCJ7e25vZGUuaW1hZ2VJY29ufX1cIiBhbHQ9XCJ7e25vZGUubGFiZWx9fVwiIC8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPnt7bm9kZS5sYWJlbH19PC9zcGFuPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPSdoYXNJdGVtcygpJz5cclxuICAgICAgICA8bWF0LWljb24gKm5nSWY9JyFpc1J0bExheW91dCgpJyBbQGlzRXhwYW5kZWRMVFJdPVwiaGFzSXRlbXMoKSAmJiBleHBhbmRlZCA/ICd5ZXMnIDogJ25vJ1wiPlxyXG4gICAgICAgICAgICBrZXlib2FyZF9hcnJvd19kb3duXHJcbiAgICAgICAgPC9tYXQtaWNvbj5cclxuICAgICAgICA8bWF0LWljb24gKm5nSWY9J2lzUnRsTGF5b3V0KCknIFtAaXNFeHBhbmRlZFJUTF09XCJoYXNJdGVtcygpICYmIGV4cGFuZGVkID8gJ3llcycgOiAnbm8nXCI+XHJcbiAgICAgICAgICAgIGtleWJvYXJkX2Fycm93X2Rvd25cclxuICAgICAgICA8L21hdC1pY29uPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbjwvbWF0LWxpc3QtaXRlbT5cclxuXHJcbjxtYXQtZGl2aWRlciAqbmdJZj1cImhhc0RpdmlkZXJcIj48L21hdC1kaXZpZGVyPlxyXG5cclxuPGRpdiAqbmdJZj1cImhhc0l0ZW1zKCkgJiYgZXhwYW5kZWRcIiBbQHNsaWRlSW5PdXRdIFtkaXJdPVwiaXNSdGxMYXlvdXQoKSA/ICdydGwnIDogJ2x0cidcIiBbbmdDbGFzc109XCJjbGFzc2VzXCI+XHJcbiAgICA8bmctbGlzdC1pdGVtICpuZ0Zvcj1cImxldCBzaW5nbGVOb2RlIG9mIG5vZGVDaGlsZHJlblwiIFtoYXNEaXZpZGVyXT1cImhhc0RpdmlkZXJcIiBbbm9kZUNvbmZpZ3VyYXRpb25dPSdub2RlQ29uZmlndXJhdGlvbicgW25vZGVdPSdzaW5nbGVOb2RlJyBbbGV2ZWxdPVwibGV2ZWwgKyAxXCIgW3NlbGVjdGVkTm9kZV09J3NlbGVjdGVkTm9kZScgKHNlbGVjdGVkSXRlbSk9XCJzZWxlY3RlZExpc3RJdGVtKCRldmVudClcIj5cclxuICAgIDwvbmctbGlzdC1pdGVtPlxyXG48L2Rpdj5gLFxyXG4gIHN0eWxlczogW2AuYW1tbC1pdGVte2xpbmUtaGVpZ2h0OjQ4cHg7cG9zaXRpb246cmVsYXRpdmU7Y3Vyc29yOnBvaW50ZXJ9LmFubWwtZGF0YXt3aWR0aDoxMDAlO3RleHQtdHJhbnNmb3JtOmNhcGl0YWxpemU7ZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpzdGFydDtoZWlnaHQ6NDhweH0uYW1tbC1pY29uLWZhe2ZvbnQtc2l6ZToyMHB4fS5hbW1sLWljb24sLmxhYmVse2xpbmUtaGVpZ2h0OjQ4cHh9ZGl2W2Rpcj1sdHJdIC5hbW1sLWljb257bWFyZ2luLXJpZ2h0OjE2cHh9ZGl2W2Rpcj1sdHJdLmFtbWwtc3VibWVudSxkaXZbZGlyPXJ0bF0gLmFtbWwtaWNvbnttYXJnaW4tbGVmdDoxNnB4fWRpdltkaXI9cnRsXS5hbW1sLXN1Ym1lbnV7bWFyZ2luLXJpZ2h0OjE2cHh9YF0sXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgdHJpZ2dlcignc2xpZGVJbk91dCcsIFtcclxuICAgICAgc3RhdGUoJ2luJywgc3R5bGUoeyBoZWlnaHQ6ICcqJywgb3BhY2l0eTogMCB9KSksXHJcbiAgICAgIHRyYW5zaXRpb24oJzpsZWF2ZScsIFtcclxuICAgICAgICBzdHlsZSh7IGhlaWdodDogJyonLCBvcGFjaXR5OiAwLjIgfSksXHJcbiAgICAgICAgZ3JvdXAoW1xyXG4gICAgICAgICAgYW5pbWF0ZSgyMDAsIHN0eWxlKHsgaGVpZ2h0OiAwIH0pKSxcclxuICAgICAgICAgIGFuaW1hdGUoJzIwMG1zIGVhc2Utb3V0Jywgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKVxyXG4gICAgICAgIF0pXHJcbiAgICAgIF0pLFxyXG4gICAgICB0cmFuc2l0aW9uKCc6ZW50ZXInLCBbXHJcbiAgICAgICAgc3R5bGUoeyBoZWlnaHQ6ICcwJywgb3BhY2l0eTogMCB9KSxcclxuICAgICAgICBncm91cChbXHJcbiAgICAgICAgICBhbmltYXRlKDIwMCwgc3R5bGUoeyBoZWlnaHQ6ICcqJyB9KSksXHJcbiAgICAgICAgICBhbmltYXRlKCc0MDBtcyBlYXNlLW91dCcsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcclxuICAgICAgICBdKVxyXG4gICAgICBdKVxyXG4gICAgXSksXHJcbiAgICB0cmlnZ2VyKCdpc0V4cGFuZGVkTFRSJywgW1xyXG4gICAgICBzdGF0ZSgnbm8nLCBzdHlsZSh7IHRyYW5zZm9ybTogJ3JvdGF0ZSgtOTBkZWcpJyB9KSksXHJcbiAgICAgIHN0YXRlKCd5ZXMnLCBzdHlsZSh7IHRyYW5zZm9ybTogJ3JvdGF0ZSgwZGVnKScgfSkpLFxyXG5cclxuICAgICAgdHJhbnNpdGlvbignbm8gPT4geWVzJywgYW5pbWF0ZSgyMDApKSxcclxuICAgICAgdHJhbnNpdGlvbigneWVzID0+IG5vJywgYW5pbWF0ZSgyMDApKVxyXG4gICAgXSksXHJcbiAgICB0cmlnZ2VyKCdpc0V4cGFuZGVkUlRMJywgW1xyXG4gICAgICBzdGF0ZSgnbm8nLCBzdHlsZSh7IHRyYW5zZm9ybTogJ3JvdGF0ZSg5MGRlZyknIH0pKSxcclxuICAgICAgc3RhdGUoJ3llcycsIHN0eWxlKHsgdHJhbnNmb3JtOiAncm90YXRlKDBkZWcpJyB9KSksXHJcblxyXG4gICAgICB0cmFuc2l0aW9uKCdubyA9PiB5ZXMnLCBhbmltYXRlKDIwMCkpLFxyXG4gICAgICB0cmFuc2l0aW9uKCd5ZXMgPT4gbm8nLCBhbmltYXRlKDIwMCkpXHJcbiAgICBdKVxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIExpc3RJdGVtQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcclxuICBASW5wdXQoKSBub2RlOiBNdWx0aWxldmVsTm9kZXM7XHJcbiAgQElucHV0KCkgbGV2ZWwgPSAxO1xyXG4gIEBJbnB1dCgpIHNlbGVjdGVkTm9kZTogTXVsdGlsZXZlbE5vZGVzO1xyXG4gIEBJbnB1dCgpIG5vZGVDb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uID0gbnVsbDtcclxuICBAT3V0cHV0KCkgc2VsZWN0ZWRJdGVtID0gbmV3IEV2ZW50RW1pdHRlcjxNdWx0aWxldmVsTm9kZXM+KCk7XHJcbiAgQElucHV0KCkgaGFzRGl2aWRlciA9IHRydWU7XHJcbiAgaXNTZWxlY3RlZCA9IGZhbHNlO1xyXG4gIG5vZGVDaGlsZHJlbjogTXVsdGlsZXZlbE5vZGVzW107XHJcbiAgY2xhc3NlczogeyBbaW5kZXg6IHN0cmluZ106IGJvb2xlYW4gfTtcclxuICBzZWxlY3RlZExpc3RDbGFzc2VzOiB7IFtpbmRleDogc3RyaW5nXTogYm9vbGVhbiB9O1xyXG4gIGV4cGFuZGVkID0gZmFsc2U7XHJcbiAgZmlyc3RJbml0aWFsaXplciA9IGZhbHNlO1xyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcclxuICAgIHByaXZhdGUgbXVsdGlsZXZlbE1lbnVTZXJ2aWNlOiBNdWx0aWxldmVsTWVudVNlcnZpY2VcclxuICApIHtcclxuICAgIHRoaXMuc2VsZWN0ZWRMaXN0Q2xhc3NlcyA9IHtcclxuICAgICAgW0NPTlNUQU5ULkRFRkFVTFRfTElTVF9DTEFTU19OQU1FXTogdHJ1ZSxcclxuICAgICAgW0NPTlNUQU5ULlNFTEVDVEVEX0xJU1RfQ0xBU1NfTkFNRV06IGZhbHNlXHJcbiAgICB9O1xyXG4gIH1cclxuICBuZ09uQ2hhbmdlcygpIHtcclxuICAgIHRoaXMubm9kZUNoaWxkcmVuID1cclxuICAgICAgdGhpcy5ub2RlICYmIHRoaXMubm9kZS5pdGVtc1xyXG4gICAgICAgID8gdGhpcy5ub2RlLml0ZW1zLmZpbHRlcihuID0+ICFuLmhpZGRlbilcclxuICAgICAgICA6IFtdO1xyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWROb2RlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zZWxlY3RlZE5vZGUgIT09IG51bGwpIHtcclxuICAgICAgdGhpcy5zZXRTZWxlY3RlZENsYXNzKFxyXG4gICAgICAgIHRoaXMubXVsdGlsZXZlbE1lbnVTZXJ2aWNlLnJlY3Vyc2l2ZUNoZWNrSWQoXHJcbiAgICAgICAgICB0aGlzLm5vZGUsXHJcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkTm9kZS5pZFxyXG4gICAgICAgIClcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcbiAgc2V0U2VsZWN0ZWRDbGFzcyhpc0ZvdW5kOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBpZiAoaXNGb3VuZCkge1xyXG4gICAgICBpZiAoIXRoaXMuZmlyc3RJbml0aWFsaXplcikge1xyXG4gICAgICAgIHRoaXMuZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuaXNTZWxlY3RlZCA9XHJcbiAgICAgICAgdGhpcy5ub2RlQ29uZmlndXJhdGlvbi5oaWdobGlnaHRPblNlbGVjdCB8fFxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWROb2RlLml0ZW1zID09PSB1bmRlZmluZWRcclxuICAgICAgICAgID8gdHJ1ZVxyXG4gICAgICAgICAgOiBmYWxzZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaXNTZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgICBpZiAodGhpcy5ub2RlQ29uZmlndXJhdGlvbi5jb2xsYXBzZU9uU2VsZWN0KSB7XHJcbiAgICAgICAgdGhpcy5leHBhbmRlZCA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLnNlbGVjdGVkTGlzdENsYXNzZXMgPSB7XHJcbiAgICAgIFtDT05TVEFOVC5ERUZBVUxUX0xJU1RfQ0xBU1NfTkFNRV06IHRydWUsXHJcbiAgICAgIFtDT05TVEFOVC5TRUxFQ1RFRF9MSVNUX0NMQVNTX05BTUVdOiB0aGlzLmlzU2VsZWN0ZWRcclxuICAgIH07XHJcbiAgICB0aGlzLnNldENsYXNzZXMoKTtcclxuICB9XHJcbiAgZ2V0UGFkZGluZ0F0U3RhcnQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5ub2RlQ29uZmlndXJhdGlvbi5wYWRkaW5nQXRTdGFydCA/IHRydWUgOiBmYWxzZTtcclxuICB9XHJcbiAgZ2V0TGlzdFN0eWxlKCk6IExpc3RTdHlsZSB7XHJcbiAgICBjb25zdCBzdHlsZXMgPSB7XHJcbiAgICAgIGJhY2tncm91bmQ6IENPTlNUQU5ULkRFRkFVTFRfTElTVF9CQUNLR1JPVU5EX0NPTE9SLFxyXG4gICAgICBjb2xvcjogQ09OU1RBTlQuREVGQVVMVF9MSVNUX0ZPTlRfQ09MT1JcclxuICAgIH07XHJcbiAgICBpZiAodGhpcy5ub2RlQ29uZmlndXJhdGlvbi5saXN0QmFja2dyb3VuZENvbG9yICE9PSBudWxsKSB7XHJcbiAgICAgIHN0eWxlcy5iYWNrZ3JvdW5kID0gdGhpcy5ub2RlQ29uZmlndXJhdGlvbi5saXN0QmFja2dyb3VuZENvbG9yO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuaXNTZWxlY3RlZCkge1xyXG4gICAgICB0aGlzLm5vZGVDb25maWd1cmF0aW9uLnNlbGVjdGVkTGlzdEZvbnRDb2xvciAhPT0gbnVsbFxyXG4gICAgICAgID8gKHN0eWxlcy5jb2xvciA9IHRoaXMubm9kZUNvbmZpZ3VyYXRpb24uc2VsZWN0ZWRMaXN0Rm9udENvbG9yKVxyXG4gICAgICAgIDogKHN0eWxlcy5jb2xvciA9IENPTlNUQU5ULkRFRkFVTFRfU0VMRUNURURfRk9OVF9DT0xPUik7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMubm9kZUNvbmZpZ3VyYXRpb24uZm9udENvbG9yICE9PSBudWxsKSB7XHJcbiAgICAgIHN0eWxlcy5jb2xvciA9IHRoaXMubm9kZUNvbmZpZ3VyYXRpb24uZm9udENvbG9yO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN0eWxlcztcclxuICB9XHJcbiAgZ2V0TGlzdEljb24obm9kZTogTXVsdGlsZXZlbE5vZGVzKTogc3RyaW5nIHtcclxuICAgIGlmIChub2RlLmljb24gIT09IG51bGwgJiYgbm9kZS5pY29uICE9PSB1bmRlZmluZWQgJiYgbm9kZS5pY29uICE9PSAnJykge1xyXG4gICAgICByZXR1cm4gYGljb25gO1xyXG4gICAgfSBlbHNlIGlmIChcclxuICAgICAgbm9kZS5mYUljb24gIT09IG51bGwgJiZcclxuICAgICAgbm9kZS5mYUljb24gIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICBub2RlLmZhSWNvbiAhPT0gJydcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gYGZhaWNvbmA7XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICBub2RlLmltYWdlSWNvbiAhPT0gbnVsbCAmJlxyXG4gICAgICBub2RlLmltYWdlSWNvbiAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgIG5vZGUuaW1hZ2VJY29uICE9PSAnJ1xyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBgaW1hZ2VpY29uYDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBgYDtcclxuICAgIH1cclxuICB9XHJcbiAgaGFzSXRlbXMoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5ub2RlQ2hpbGRyZW4ubGVuZ3RoID4gMCA/IHRydWUgOiBmYWxzZTtcclxuICB9XHJcbiAgaXNSdGxMYXlvdXQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5ub2RlQ29uZmlndXJhdGlvbi5ydGxMYXlvdXQ7XHJcbiAgfVxyXG4gIHNldENsYXNzZXMoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNsYXNzZXMgPSB7XHJcbiAgICAgIFsnbGV2ZWwtJyArIHRoaXMubGV2ZWxdOiB0cnVlLFxyXG4gICAgICAnYW1tbC1zdWJtZW51JzogdGhpcy5oYXNJdGVtcygpICYmIHRoaXMuZ2V0UGFkZGluZ0F0U3RhcnQoKVxyXG4gICAgfTtcclxuICB9XHJcbiAgZXhwYW5kKG5vZGU6IE11bHRpbGV2ZWxOb2Rlcyk6IHZvaWQge1xyXG4gICAgdGhpcy5leHBhbmRlZCA9ICF0aGlzLmV4cGFuZGVkO1xyXG4gICAgdGhpcy5maXJzdEluaXRpYWxpemVyID0gdHJ1ZTtcclxuICAgIHRoaXMuc2V0Q2xhc3NlcygpO1xyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLm5vZGVDb25maWd1cmF0aW9uLmludGVyZmFjZVdpdGhSb3V0ZSAhPT0gbnVsbCAmJlxyXG4gICAgICB0aGlzLm5vZGVDb25maWd1cmF0aW9uLmludGVyZmFjZVdpdGhSb3V0ZSAmJlxyXG4gICAgICBub2RlLmxpbmsgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICBub2RlLmxpbmtcclxuICAgICkge1xyXG4gICAgICBpZiAobm9kZS5leHRlcm5hbFJlZGlyZWN0ICE9PSB1bmRlZmluZWQgJiYgbm9kZS5leHRlcm5hbFJlZGlyZWN0KSB7XHJcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSBub2RlLmxpbms7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW25vZGUubGlua10pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKG5vZGUub25TZWxlY3RlZCAmJiB0eXBlb2Ygbm9kZS5vblNlbGVjdGVkID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIG5vZGUub25TZWxlY3RlZChub2RlKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZExpc3RJdGVtKG5vZGUpO1xyXG4gICAgfSBlbHNlIGlmIChcclxuICAgICAgbm9kZS5pdGVtcyA9PT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgIHRoaXMubm9kZUNvbmZpZ3VyYXRpb24uY29sbGFwc2VPblNlbGVjdFxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRMaXN0SXRlbShub2RlKTtcclxuICAgIH1cclxuICB9XHJcbiAgc2VsZWN0ZWRMaXN0SXRlbShub2RlOiBNdWx0aWxldmVsTm9kZXMpOiB2b2lkIHtcclxuICAgIHRoaXMuc2VsZWN0ZWRJdGVtLmVtaXQobm9kZSk7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IE1hdGVyaWFsc01vZHVsZSB9IGZyb20gJy4vbWF0ZXJpYWxzLm1vZHVsZSc7XHJcblxyXG5pbXBvcnQgeyBOZ01hdGVyaWFsTXVsdGlsZXZlbE1lbnVDb21wb25lbnQgfSBmcm9tICcuL25nLW1hdGVyaWFsLW11bHRpbGV2ZWwtbWVudS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBMaXN0SXRlbUNvbXBvbmVudCB9IGZyb20gJy4vbGlzdC1pdGVtL2xpc3QtaXRlbS5jb21wb25lbnQnO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBNYXRlcmlhbHNNb2R1bGVcclxuICBdLFxyXG4gIGRlY2xhcmF0aW9uczogW05nTWF0ZXJpYWxNdWx0aWxldmVsTWVudUNvbXBvbmVudCwgTGlzdEl0ZW1Db21wb25lbnRdLFxyXG4gIGV4cG9ydHM6IFtOZ01hdGVyaWFsTXVsdGlsZXZlbE1lbnVDb21wb25lbnRdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOZ01hdGVyaWFsTXVsdGlsZXZlbE1lbnVNb2R1bGUgeyB9XHJcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7OztZQVFDLFFBQVEsU0FBQztnQkFDUixPQUFPLEVBQUU7b0JBQ1AsYUFBYTtvQkFDYixhQUFhO29CQUNiLGVBQWU7aUJBQ2hCO2dCQUNELFlBQVksRUFBRSxFQUFFO2dCQUNoQixPQUFPLEVBQUU7b0JBQ1AsYUFBYTtvQkFDYixhQUFhO29CQUNiLGVBQWU7aUJBQ2hCO2FBQ0Y7Ozs7Ozs7QUNwQkQ7Ozs7SUFRRSxVQUFVOztZQUNKLElBQUksR0FBRyxFQUFFOztjQUNQLFFBQVEsR0FBRyxnRUFBZ0U7UUFDakYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUMzQixJQUFJLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FB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