@noaestudio/forms
Version:
Dynamic forms extension for Covalent
502 lines (501 loc) • 53.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { Component, forwardRef, ChangeDetectorRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { AbstractControlValueAccessor } from '../abstract-control-value-accesor';
import { SelectionModel } from '@angular/cdk/collections';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material';
import { of as observableOf } from 'rxjs';
/**
* Node for to-do item
*/
export class ItemNode {
}
function ItemNode_tsickle_Closure_declarations() {
/** @type {?} */
ItemNode.prototype.id;
/** @type {?} */
ItemNode.prototype.name;
/** @type {?} */
ItemNode.prototype.children;
/** @type {?} */
ItemNode.prototype.parent;
/** @type {?} */
ItemNode.prototype.checked;
}
/**
* Flat to-do item node with expandable and level information
*/
export class ItemFlatNode {
}
function ItemFlatNode_tsickle_Closure_declarations() {
/** @type {?} */
ItemFlatNode.prototype.id;
/** @type {?} */
ItemFlatNode.prototype.name;
/** @type {?} */
ItemFlatNode.prototype.parent;
/** @type {?} */
ItemFlatNode.prototype.level;
/** @type {?} */
ItemFlatNode.prototype.expandable;
/** @type {?} */
ItemFlatNode.prototype.checked;
/** @type {?} */
ItemFlatNode.prototype.children;
}
export const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TreeSelectorComponent),
multi: true,
};
export class TreeSelectorComponent extends AbstractControlValueAccessor {
/**
* @param {?} translator
* @param {?} dialog
* @param {?} changeDetector
*/
constructor(translator, dialog, changeDetector) {
super();
this.translator = translator;
this.dialog = dialog;
this.changeDetector = changeDetector;
/**
* Map from flat node to nested node. This helps us finding the nested node to be modified
*/
this.flatNodeMap = new Map();
/**
* Map from nested node to flattened node. This helps us to keep the same object for selection
*/
this.nestedNodeMap = new Map();
/**
* A selected parent node to be inserted
*/
this.selectedParent = null;
/**
* The selection for checklist
*/
this.checklistSelection = new SelectionModel(true /* multiple */);
this.selectMultiple = false;
/**
* Component Attributes
*/
this.label = '';
//Search attributes (not components)
this.flattenedItems = [];
//Nodo padre de todos
this.masterNode = 0;
//Elementos a devolver
this.outputItems = [];
//Preview Selected
this.outputPreview = [];
//Funcionamiento interno del arbol
this.getLevel = (node) => node.level;
this.isExpandable = (node) => node.expandable;
this.getChildren = (node) => observableOf(node.children);
this.hasChild = (_, _nodeData) => _nodeData.expandable;
this.hasNoContent = (_, _nodeData) => _nodeData.name === '';
/**
* Transformer to convert nested node to flat node. Record the nodes in maps for later use.
*/
this.transformer = (node, level) => {
const /** @type {?} */ existingNode = this.nestedNodeMap.get(node);
const /** @type {?} */ flatNode = existingNode && existingNode.id === node.id ? existingNode : new ItemFlatNode();
flatNode.id = node.id;
flatNode.name = node.name;
flatNode.parent = node.parent;
flatNode.checked = node.checked;
flatNode.children = node.children;
flatNode.level = level;
flatNode.expandable = !!node.children;
this.flatNodeMap.set(flatNode, node);
this.nestedNodeMap.set(node, flatNode);
return flatNode;
};
this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren);
this.treeControl = new FlatTreeControl(this.getLevel, this.isExpandable);
this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
}
/**
* @return {?}
*/
ngOnInit() {
if (this.treeItems != null && this.treeItems.length > 0) {
//Generamos los nodos
let /** @type {?} */ treeItems = this.generateTree(this.treeItems[0], null);
this.dataSource.data = treeItems;
//Cogemos el nodo padre de todos
this.masterNode = this.treeItems[0].id;
this.flattenedItems = this.flattenItems(this.treeItems);
//Cargamos los nodos seleccionados
if (this.control.value != null) {
this.loadData();
}
}
}
/**
* @param {?} items
* @return {?}
*/
flattenItems(items) {
let /** @type {?} */ flattened = [];
for (let /** @type {?} */ item of items) {
flattened.push({ id: item.id, name: item.name });
let /** @type {?} */ childFlattened = this.flattenItems(item.children);
flattened.push(...childFlattened);
}
return flattened;
}
/**
* @return {?}
*/
get selectItems() {
//TODO: Solo selectMultiple=false
if (this.value) {
return this.value[0];
}
else {
return [];
}
}
/**
* @param {?} value
* @return {?}
*/
set selectItems(value) {
//TODO: Solo selectMultiple=false
if (value) {
this.value = [value];
}
else {
this.value = [];
}
this.loadSearchData();
}
/**
* @return {?}
*/
loadSearchData() {
let /** @type {?} */ checked = JSON.parse(JSON.stringify(this.value));
let /** @type {?} */ outputPreview = [];
for (let /** @type {?} */ j = 0; j < this.treeControl.dataNodes.length; j++) {
if (checked.includes(this.treeControl.dataNodes[j].id)) {
this.treeControl.dataNodes[j].checked = true;
outputPreview.push({ name: this.treeControl.dataNodes[j].name });
}
else {
this.treeControl.dataNodes[j].checked = false;
}
}
this.outputPreview = outputPreview;
}
/**
* @param {?} input
* @param {?} parent
* @return {?}
*/
generateTree(input, parent) {
let /** @type {?} */ output = new ItemFlatNode();
output.id = input.id;
output.name = input.name;
output.parent = parent;
output.checked = input.checked;
output.children = input.children;
if (input.children.length > 0) {
output.children = [];
}
for (var /** @type {?} */ i in input.children) {
output.children.push(...this.generateTree(input.children[i], input.id));
}
return [output];
}
/**
* @param {?} node
* @param {?} status
* @return {?}
*/
refrescaPadre(node, status) {
let /** @type {?} */ nodoPadre = null;
if (status == true) {
if (node != null) {
for (let /** @type {?} */ i = 0; i < this.treeControl.dataNodes.length; i++) {
if (this.treeControl.dataNodes[i].id == node.parent) {
nodoPadre = this.treeControl.dataNodes[i];
}
}
if (nodoPadre != null) {
nodoPadre.checked = true;
for (let /** @type {?} */ i = 0; i < this.treeControl.dataNodes.length; i++) {
if (this.treeControl.dataNodes[i].parent == nodoPadre.id && !this.treeControl.dataNodes[i].checked) {
nodoPadre.checked = false;
}
}
}
}
if (nodoPadre != null) {
this.refrescaPadre(nodoPadre, status);
}
}
else {
if (node != null) {
for (let /** @type {?} */ i = 0; i < this.treeControl.dataNodes.length; i++) {
if (this.treeControl.dataNodes[i].id == node.parent) {
nodoPadre = this.treeControl.dataNodes[i];
this.treeControl.dataNodes[i].checked = status;
}
}
}
if (nodoPadre != null) {
this.refrescaPadre(nodoPadre, status);
}
}
this.changeDetector.detectChanges();
}
/**
* @param {?} event
* @param {?} node
* @return {?}
*/
checkNode(event, node) {
node.checked = event.checked;
if (this.selectMultiple) {
if (event.checked) {
this.changeAllDescendants(node, true);
this.refrescaPadre(node, true);
}
else {
this.changeAllDescendants(node, false);
this.refrescaPadre(node, false);
}
this.getSelectedItems(node);
}
else {
if (event.checked) {
for (let /** @type {?} */ j = 0; j < this.treeControl.dataNodes.length; j++) {
if (this.treeControl.dataNodes[j].id != node.id) {
this.treeControl.dataNodes[j].checked = false;
}
}
this.outputItems = [node.id];
this.outputPreview = [node];
}
else {
this.outputItems = [];
this.outputPreview = [];
}
}
this.control.setValue(this.outputItems);
}
/**
* @param {?} node
* @param {?} status
* @return {?}
*/
changeAllDescendants(node, status) {
for (var /** @type {?} */ i = 0; i < node.children.length; i++) {
var /** @type {?} */ child = node.children[i];
for (let /** @type {?} */ j = 0; j < this.treeControl.dataNodes.length; j++) {
if (this.treeControl.dataNodes[j].id == child.id) {
this.treeControl.dataNodes[j].checked = status;
}
}
this.changeAllDescendants(child, status);
}
}
/**
* @param {?} node
* @return {?}
*/
getSelectedItems(node) {
this.outputItems = [];
this.outputPreview = [];
//Buscamos el nodo maestro
let /** @type {?} */ nodoMaster = null;
for (let /** @type {?} */ i = 0; i < this.treeControl.dataNodes.length; i++) {
if (this.treeControl.dataNodes[i].id == this.masterNode) {
nodoMaster = this.treeControl.dataNodes[i];
}
}
//Buscamos los elementos que definiran el valor del componente
if (nodoMaster.checked) {
this.outputItems = [this.masterNode];
this.outputPreview = [{ name: this.treeItems[0].name }];
}
else {
this.getOutputNodes(nodoMaster);
}
//Refrescamos el valor del componente
this.control.setValue(this.outputItems);
}
/**
* @param {?} node
* @return {?}
*/
getOutputNodes(node) {
if (!node.checked || node.id == this.masterNode) {
for (let /** @type {?} */ i = 0; i < node.children.length; i++) {
var /** @type {?} */ child = node.children[i];
for (let /** @type {?} */ j = 0; j < this.treeControl.dataNodes.length; j++) {
if (this.treeControl.dataNodes[j].id == child.id && this.treeControl.dataNodes[j].checked) {
var /** @type {?} */ index = this.outputItems.indexOf(child.id);
if (index !== -1)
this.outputItems.splice(index, 1);
this.outputItems.push(child.id);
if (index !== -1)
this.outputPreview.splice(index, 1);
this.outputPreview.push(child);
}
else if (this.treeControl.dataNodes[j].id == child.id && !this.treeControl.dataNodes[j].checked) {
this.getOutputNodes(this.treeControl.dataNodes[j]);
}
}
}
}
}
/**
* @return {?}
*/
loadData() {
let /** @type {?} */ defaults = JSON.parse(JSON.stringify(this.control.value));
for (let /** @type {?} */ i = 0; i < defaults.length; i++) {
for (let /** @type {?} */ j = 0; j < this.treeControl.dataNodes.length; j++) {
if (this.treeControl.dataNodes[j].id == defaults[i]) {
this.checkNode({ checked: true }, this.treeControl.dataNodes[j]);
}
}
}
}
/**
* @return {?}
*/
toggleTree() {
this.treeControl.isExpanded(this.treeControl.dataNodes[0]) ? this.treeControl.collapseAll() : this.treeControl.expandAll();
}
}
TreeSelectorComponent.decorators = [
{ type: Component, args: [{
providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR],
selector: 'tree-selector',
styles: [`.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}.td-dynamic-input-wrapper .ngx-editor{margin-top:10px}.label{padding:10px 0;display:inline-block;width:50%}.container{overflow:auto;border:1px solid #f3f3f3;border-radius:5px 5px 0 0}.selected-items{padding:5px;display:block;background:#f3f3f3;border-radius:0 0 5px 5px;min-height:30px}.selected-items span{background:#689f38;margin:2px;padding:5px;border-radius:5px;color:#fff;display:inline-block}.search-bar{display:inline-block;width:50%;text-align:left;margin-bottom:10px}.buttons{display:inline-block;width:50%;text-align:right}.buttons button{padding:0;width:30px!important;min-width:30px;border-radius:50px;height:30px}.buttons button mat-icon{position:relative!important;top:-4px!important}`],
template: `<div class="label">{{label}} {{required ? '*' : ''}}</div>
<div class="buttons">
<button mat-raised-button color="primary" (click)="toggleTree()">
<mat-icon *ngIf="!treeControl.isExpanded(treeControl.dataNodes[0])">add</mat-icon>
<mat-icon *ngIf="treeControl.isExpanded(treeControl.dataNodes[0])">remove</mat-icon>
</button>
</div>
<div *ngIf="searchable" class="search-bar">
<ng-select [(ngModel)]="selectItems" placeholder="Buscar" [multiple]="selectMultiple" [items]="flattenedItems"
[required]="required" [searchable]="true" bindLabel="name" bindValue="id" appendTo="body" [style.flex]="100">
</ng-select>
</div>
<div class="container">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'toggle ' + node.filename">
<mat-icon class="mat-icon-rtl-mirror" *ngIf="node.children.length > 0">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
<mat-checkbox [checked]="node.checked" (change)="checkNode($event, node)">{{node.name}}</mat-checkbox>
</mat-tree-node>
</mat-tree>
</div>
<div class="selected-items">
<span *ngFor="let item of outputPreview">{{item.name}}</span>
</div>
`,
},] },
];
/** @nocollapse */
TreeSelectorComponent.ctorParameters = () => [
{ type: TranslateService, },
{ type: MatDialog, },
{ type: ChangeDetectorRef, },
];
function TreeSelectorComponent_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
TreeSelectorComponent.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
TreeSelectorComponent.ctorParameters;
/** @type {?} */
TreeSelectorComponent.prototype.control;
/**
* Map from flat node to nested node. This helps us finding the nested node to be modified
* @type {?}
*/
TreeSelectorComponent.prototype.flatNodeMap;
/**
* Map from nested node to flattened node. This helps us to keep the same object for selection
* @type {?}
*/
TreeSelectorComponent.prototype.nestedNodeMap;
/**
* A selected parent node to be inserted
* @type {?}
*/
TreeSelectorComponent.prototype.selectedParent;
/** @type {?} */
TreeSelectorComponent.prototype.treeControl;
/** @type {?} */
TreeSelectorComponent.prototype.treeFlattener;
/** @type {?} */
TreeSelectorComponent.prototype.dataSource;
/**
* The selection for checklist
* @type {?}
*/
TreeSelectorComponent.prototype.checklistSelection;
/** @type {?} */
TreeSelectorComponent.prototype.selectMultiple;
/**
* Component Attributes
* @type {?}
*/
TreeSelectorComponent.prototype.label;
/** @type {?} */
TreeSelectorComponent.prototype.required;
/** @type {?} */
TreeSelectorComponent.prototype.searchable;
/** @type {?} */
TreeSelectorComponent.prototype.flattenedItems;
/** @type {?} */
TreeSelectorComponent.prototype.treeItems;
/** @type {?} */
TreeSelectorComponent.prototype.masterNode;
/** @type {?} */
TreeSelectorComponent.prototype.outputItems;
/** @type {?} */
TreeSelectorComponent.prototype.outputPreview;
/** @type {?} */
TreeSelectorComponent.prototype.getLevel;
/** @type {?} */
TreeSelectorComponent.prototype.isExpandable;
/** @type {?} */
TreeSelectorComponent.prototype.getChildren;
/** @type {?} */
TreeSelectorComponent.prototype.hasChild;
/** @type {?} */
TreeSelectorComponent.prototype.hasNoContent;
/**
* Transformer to convert nested node to flat node. Record the nodes in maps for later use.
* @type {?}
*/
TreeSelectorComponent.prototype.transformer;
/** @type {?} */
TreeSelectorComponent.prototype.translator;
/** @type {?} */
TreeSelectorComponent.prototype.dialog;
/** @type {?} */
TreeSelectorComponent.prototype.changeDetector;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AY292YWxlbnQvZHluYW1pYy1mb3Jtcy8iLCJzb3VyY2VzIjpbImR5bmFtaWMtZWxlbWVudHMvdHJlZS1zZWxlY3Rvci90cmVlLXNlbGVjdG9yLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekUsT0FBTyxFQUFFLGlCQUFpQixFQUFxQyxNQUFNLGdCQUFnQixDQUFDO0FBRXRGLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBR2pGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTlDLE9BQU8sRUFBQyxFQUFFLElBQUksWUFBWSxFQUFDLE1BQU0sTUFBTSxDQUFDOzs7O0FBTXhDLE1BQU07Q0FNTDs7Ozs7Ozs7Ozs7Ozs7OztBQUdELE1BQU07Q0FRTDs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFRCxNQUFNLENBQUMsdUJBQU0sa0NBQWtDLEdBQVE7SUFDdEQsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDO0lBQ3BELEtBQUssRUFBRSxJQUFJO0NBQ1gsQ0FBQztBQW9DRixNQUFNLDRCQUE2QixTQUFRLDRCQUE0Qjs7Ozs7O0lBZ0R0RSxZQUFvQixVQUE0QixFQUFTLE1BQWlCLEVB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RUFBRSxDQUFBLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3BELElBQUksQ0FBQyxTQUFTLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFDLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDL0Q7YUFDRDtTQUNEO0tBQ0Q7Ozs7SUEyQkQsVUFBVTtRQUNULElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7S0FDM0g7OztZQTVVRCxTQUFTLFNBQUM7Z0JBQ1YsU0FBUyxFQUFFLENBQUUsa0NBQWtDLENBQUU7Z0JBQ2pELFFBQVEsRUFBRSxlQUFlO2dCQUN6QixNQUFNLEVBQUUsQ0FBQyxrNUJBQWs1QixDQUFDO2dCQUM1NUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBNEJWO2FBQ0E7Ozs7WUFuRVEsZ0JBQWdCO1lBQ2hCLFNBQVM7WUFWYyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGZvcndhcmRSZWYsIENoYW5nZURldGVjdG9yUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE5HX1ZBTFVFX0FDQ0VTU09SLCBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2xWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnLi4vYWJzdHJhY3QtY29udHJvbC12YWx1ZS1hY2Nlc29yJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHsgU2VsZWN0aW9uTW9kZWwgfSBmcm9tICdAYW5ndWxhci9jZGsvY29sbGVjdGlvbnMnO1xyXG5pbXBvcnQgeyBGbGF0VHJlZUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9jZGsvdHJlZSc7XHJcbmltcG9ydCB7IE1hdFRyZWVGbGF0RGF0YVNvdXJjZSwgTWF0VHJlZUZsYXR0ZW5lciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RyZWUnO1xyXG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XHJcbmltcG9ydCB7IE1hdERpYWxvZyB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsJztcclxuXHJcbmltcG9ydCB7b2YgYXMgb2JzZXJ2YWJsZU9mfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVib3VuY2VUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuLyoqXHJcbiAqIE5vZGUgZm9yIHRvLWRvIGl0ZW1cclxuICovXHJcbmV4cG9ydCBjbGFzcyBJdGVtTm9kZSB7XHJcblx0aWQ6IG51bWJlcjtcclxuXHRuYW1lOiBzdHJpbmc7IC8vaXRlbVxyXG5cdGNoaWxkcmVuOiBJdGVtTm9kZVtdO1xyXG5cdHBhcmVudDogbnVtYmVyO1xyXG5cdGNoZWNrZWQ6IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qKiBGbGF0IHRvLWRvIGl0ZW0gbm9kZSB3aXRoIGV4cGFuZGFibGUgYW5kIGxldmVsIGluZm9ybWF0aW9uICovXHJcbmV4cG9ydCBjbGFzcyBJdGVtRmxhdE5vZGUge1xyXG5cdGlkOiBudW1iZXI7XHJcblx0bmFtZTogc3RyaW5nOyAvL2l0ZW1cclxuXHRwYXJlbnQ6IG51bWJlcjtcclxuXHRsZXZlbDogbnVtYmVyO1xyXG5cdGV4cGFuZGFibGU6IGJvb2xlYW47XHJcblx0Y2hlY2tlZDogYm9vbGVhbjtcclxuXHRjaGlsZHJlbjogSXRlbUZsYXROb2RlW107XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBJTlBVVF9JTlBVVF9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SOiBhbnkgPSB7XHJcblx0cHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcblx0dXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gVHJlZVNlbGVjdG9yQ29tcG9uZW50KSxcclxuXHRtdWx0aTogdHJ1ZSxcclxufTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cdHByb3ZpZGVyczogWyBJTlBVVF9JTlBVVF9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SIF0sXHJcblx0c2VsZWN0b3I6ICd0cmVlLXNlbGVjdG9yJyxcclxuXHRzdHlsZXM6IFtgLnRkLWR5bmFtaWMtaW5wdXQtd3JhcHBlcnstbXMtZmxleC1kaXJlY3Rpb246cm93O2ZsZXgtZGlyZWN0aW9uOnJvdztkaXNwbGF5Oi1tcy1mbGV4Ym94O2Rpc3BsYXk6ZmxleDtib3gtc2l6aW5nOmJvcmRlci1ib3h9LnRkLWR5bmFtaWMtaW5wdXQtd3JhcHBlciAudGQtZHluYW1pYy1pbnB1dC1maWVsZHstbXMtZmxleDoxO2ZsZXg6MTtib3gtc2l6aW5nOmJvcmRlci1ib3h9LnRkLWR5bmFtaWMtaW5wdXQtd3JhcHBlciAubmd4LWVkaXRvcnttYXJnaW4tdG9wOjEwcHh9LmxhYmVse3BhZGRpbmc6MTBweCAwO2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjUwJX0uY29udGFpbmVye292ZXJmbG93OmF1dG87Ym9yZGVyOjFweCBzb2xpZCAjZjNmM2YzO2JvcmRlci1yYWRpdXM6NXB4IDVweCAwIDB9LnNlbGVjdGVkLWl0ZW1ze3BhZGRpbmc6NXB4O2Rpc3BsYXk6YmxvY2s7YmFja2dyb3VuZDojZjNmM2YzO2JvcmRlci1yYWRpdXM6MCAwIDVweCA1cHg7bWluLWhlaWdodDozMHB4fS5zZWxlY3RlZC1pdGVtcyBzcGFue2JhY2tncm91bmQ6IzY4OWYzODttYXJnaW46MnB4O3BhZGRpbmc6NXB4O2JvcmRlci1yYWRpdXM6NXB4O2NvbG9yOiNmZmY7ZGlzcGxheTppbmxpbmUtYmxvY2t9LnNlYXJjaC1iYXJ7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NTAlO3RleHQtYWxpZ246bGVmdDttYXJnaW4tYm90dG9tOjEwcHh9LmJ1dHRvbnN7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NTAlO3RleHQtYWxpZ246cmlnaHR9LmJ1dHRvbnMgYnV0dG9ue3BhZGRpbmc6MDt3aWR0aDozMHB4IWltcG9ydGFudDttaW4td2lkdGg6MzBweDtib3JkZXItcmFkaXVzOjUwcHg7aGVpZ2h0OjMwcHh9LmJ1dHRvbnMgYnV0dG9uIG1hdC1pY29ue3Bvc2l0aW9uOnJlbGF0aXZlIWltcG9ydGFudDt0b3A6LTRweCFpbXBvcnRhbnR9YF0sXHJcblx0dGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwibGFiZWxcIj57e2xhYmVsfX0ge3tyZXF1aXJlZCA/ICcqJyA6ICcnfX08L2Rpdj5cclxuPGRpdiBjbGFzcz1cImJ1dHRvbnNcIj5cclxuXHQ8YnV0dG9uIG1hdC1yYWlzZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJ0b2dnbGVUcmVlKClcIj5cclxuXHRcdDxtYXQtaWNvbiAqbmdJZj1cIiF0cmVlQ29udHJvbC5pc0V4cGFuZGVkKHRyZWVDb250cm9sLmRhdGFOb2Rlc1swXSlcIj5hZGQ8L21hdC1pY29uPlxyXG5cdFx0PG1hdC1pY29uICpuZ0lmPVwidHJlZUNvbnRyb2wuaXNFeHBhbmRlZCh0cmVlQ29udHJvbC5kYXRhTm9kZXNbMF0pXCI+cmVtb3ZlPC9tYXQtaWNvbj5cclxuXHQ8L2J1dHRvbj5cclxuPC9kaXY+XHJcbjxkaXYgKm5nSWY9XCJzZWFyY2hhYmxlXCIgY2xhc3M9XCJzZWFyY2gtYmFyXCI+XHJcblx0PG5nLXNlbGVjdCBbKG5nTW9kZWwpXT1cInNlbGVjdEl0ZW1zXCIgcGxhY2Vob2xkZXI9XCJCdXNjYXJcIiBbbXVsdGlwbGVdPVwic2VsZWN0TXVsdGlwbGVcIiBbaXRlbXNdPVwiZmxhdHRlbmVkSXRlbXNcIlxyXG5cdFx0W3JlcXVpcmVkXT1cInJlcXVpcmVkXCIgW3NlYXJjaGFibGVdPVwidHJ1ZVwiIGJpbmRMYWJlbD1cIm5hbWVcIiBiaW5kVmFsdWU9XCJpZFwiIGFwcGVuZFRvPVwiYm9keVwiIFtzdHlsZS5mbGV4XT1cIjEwMFwiPlxyXG5cdDwvbmctc2VsZWN0PlxyXG48L2Rpdj5cclxuPGRpdiBjbGFzcz1cImNvbnRhaW5lclwiPlxyXG5cdDxtYXQtdHJlZSBbZGF0YVNvdXJjZV09XCJkYXRhU291cmNlXCIgW3RyZWVDb250cm9sXT1cInRyZWVDb250cm9sXCI+XHJcblx0XHQ8bWF0LXRyZWUtbm9kZSAqbWF0VHJlZU5vZGVEZWY9XCJsZXQgbm9kZTsgd2hlbjogaGFzQ2hpbGRcIiBtYXRUcmVlTm9kZVBhZGRpbmc+XHJcblx0XHRcdDxidXR0b24gbWF0LWljb24tYnV0dG9uIG1hdFRyZWVOb2RlVG9nZ2xlXHJcblx0XHRcdFx0W2F0dHIuYXJpYS1sYWJlbF09XCIndG9nZ2xlICcgKyBub2RlLmZpbGVuYW1lXCI+XHJcblx0XHRcdFx0PG1hdC1pY29uIGNsYXNzPVwibWF0LWljb24tcnRsLW1pcnJvclwiICpuZ0lmPVwibm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwXCI+XHJcblx0XHRcdFx0XHR7e3RyZWVDb250cm9sLmlzRXhwYW5kZWQobm9kZSkgPyAnZXhwYW5kX21vcmUnIDogJ2NoZXZyb25fcmlnaHQnfX1cclxuXHRcdFx0XHQ8L21hdC1pY29uPlxyXG5cdFx0XHQ8L2J1dHRvbj5cclxuXHRcdFx0PG1hdC1jaGVja2JveCBbY2hlY2tlZF09XCJub2RlLmNoZWNrZWRcIiAoY2hhbmdlKT1cImNoZWNrTm9kZSgkZXZlbnQsIG5vZGUpXCI+e3tub2RlLm5hbWV9fTwvbWF0LWNoZWNrYm94PlxyXG5cdFx0PC9tYXQtdHJlZS1ub2RlPlxyXG5cdDwvbWF0LXRyZWU+XHJcbjwvZGl2PlxyXG48ZGl2IGNsYXNzPVwic2VsZWN0ZWQtaXRlbXNcIj5cclxuXHQ8c3BhbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBvdXRwdXRQcmV2aWV3XCI+e3tpdGVtLm5hbWV9fTwvc3Bhbj5cclxuPC9kaXY+XHJcbmAsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUcmVlU2VsZWN0b3JDb21wb25lbnQgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2xWYWx1ZUFjY2Vzc29yIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xyXG5cclxuXHQvL0NvbnRyb2xcclxuXHRjb250cm9sOiBGb3JtQ29udHJvbDtcclxuXHJcblx0LyoqIE1hcCBmcm9tIGZsYXQgbm9kZSB0byBuZXN0ZWQgbm9kZS4gVGhpcyBoZWxwcyB1cyBmaW5kaW5nIHRoZSBuZXN0ZWQgbm9kZSB0byBiZSBtb2RpZmllZCAqL1xyXG5cdGZsYXROb2RlTWFwID0gbmV3IE1hcDxJdGVtRmxhdE5vZGUsIEl0ZW1Ob2RlPigpO1xyXG5cclxuXHQvKiogTWFwIGZyb20gbmVzdGVkIG5vZGUgdG8gZmxhdHRlbmVkIG5vZGUuIFRoaXMgaGVscHMgdXMgdG8ga2VlcCB0aGUgc2FtZSBvYmplY3QgZm9yIHNlbGVjdGlvbiAqL1xyXG5cdG5lc3RlZE5vZGVNYXAgPSBuZXcgTWFwPEl0ZW1Ob2RlLCBJdGVtRmxhdE5vZGU+KCk7XHJcblxyXG5cdC8qKiBBIHNlbGVjdGVkIHBhcmVudCBub2RlIHRvIGJlIGluc2VydGVkICovXHJcblx0c2VsZWN0ZWRQYXJlbnQ6IEl0ZW1GbGF0Tm9kZSB8IG51bGwgPSBudWxsO1xyXG5cclxuXHR0cmVlQ29udHJvbDogRmxhdFRyZWVDb250cm9sPEl0ZW1GbGF0Tm9kZT47XHJcblx0dHJlZUZsYXR0ZW5lcjogTWF0VHJlZUZsYXR0ZW5lcjxJdGVtTm9kZSwgSXRlbUZsYXROb2RlPjtcclxuXHRkYXRhU291cmNlOiBNYXRUcmVlRmxhdERhdGFTb3VyY2U8SXRlbU5vZGUsIEl0ZW1GbGF0Tm9kZT47XHJcblxyXG5cdC8qKiBUaGUgc2VsZWN0aW9uIGZvciBjaGVja2xpc3QgKi9cclxuXHRjaGVja2xpc3RTZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWw8SXRlbUZsYXROb2RlPih0cnVlIC8qIG11bHRpcGxlICovKTtcclxuXHJcblx0c2VsZWN0TXVsdGlwbGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcblx0LyoqIENvbXBvbmVudCBBdHRyaWJ1dGVzICovXHJcblxyXG5cdC8vTGFiZWwgZGVsIGNvbXBvbmVudGVcclxuXHRsYWJlbDogc3RyaW5nID0gJyc7XHJcblxyXG5cdC8vUmVxdWlyZWQgb3Igbm90XHJcblx0cmVxdWlyZWQ6IGJvb2xlYW47XHJcblxyXG5cdC8vU2VhcmNoYWJsZSBvciBub3RcclxuXHRzZWFyY2hhYmxlOiBib29sZWFuO1xyXG5cdC8vU2VhcmNoIGF0dHJpYnV0ZXMgKG5vdCBjb21wb25lbnRzKVxyXG5cdGZsYXR0ZW5lZEl0ZW1zOiBhbnlbXSA9IFtdO1xyXG5cclxuXHQvL0l0ZW1zXHJcblx0dHJlZUl0ZW1zOiBhbnk7XHJcblxyXG5cdC8vTm9kbyBwYWRyZSBkZSB0b2Rvc1xyXG5cdG1hc3Rlck5vZGU6IG51bWJlciA9IDA7XHJcblxyXG5cdC8vRWxlbWVudG9zIGEgZGV2b2x2ZXJcclxuXHRvdXRwdXRJdGVtczogbnVtYmVyW10gPSBbXTtcclxuXHJcblx0Ly9QcmV2aWV3IFNlbGVjdGVkXHJcblx0b3V0cHV0UHJldmlldzogYW55W10gPSBbXTtcclxuXHJcblx0Y29uc3RydWN0b3IocHJpdmF0ZSB0cmFuc2xhdG9yOiBUcmFuc2xhdGVTZXJ2aWNlLCBwdWJsaWMgZGlhbG9nOiBNYXREaWFsb2csIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmKSB7XHJcblx0XHRzdXBlcigpO1xyXG5cdFx0dGhpcy50cmVlRmxhdHRlbmVyID0gbmV3IE1hdFRyZWVGbGF0dGVuZXIodGhpcy50cmFuc2Zvcm1lciwgdGhpcy5nZXRMZXZlbCwgdGhpcy5pc0V4cGFuZGFibGUsIHRoaXMuZ2V0Q2hpbGRyZW4pO1xyXG5cdFx0dGhpcy50cmVlQ29udHJvbCA9IG5ldyBGbGF0VHJlZUNvbnRyb2w8SXRlbUZsYXROb2RlPih0aGlzLmdldExldmVsLCB0aGlzLmlzRXhwYW5kYWJsZSk7XHJcblx0XHR0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VHJlZUZsYXREYXRhU291cmNlKHRoaXMudHJlZUNvbnRyb2wsIHRoaXMudHJlZUZsYXR0ZW5lcik7XHJcblx0fVxyXG5cclxuXHRuZ09uSW5pdCgpIHtcclxuXHRcdGlmKHRoaXMudHJlZUl0ZW1zICE9IG51bGwgJiYgdGhpcy50cmVlSXRlbXMubGVuZ3RoID4gMCkge1xyXG5cdFx0XHQvL0dlbmVyYW1vcyBsb3Mgbm9kb3NcclxuXHRcdFx0bGV0IHRyZWVJdGVtcyA9IHRoaXMuZ2VuZXJhdGVUcmVlKHRoaXMudHJlZUl0ZW1zWzBdLCBudWxsKTtcclxuXHRcdFx0dGhpcy5kYXRhU291cmNlLmRhdGEgPSB0cmVlSXRlbXM7XHJcblx0XHRcdC8vQ29nZW1vcyBlbCBub2RvIHBhZHJlIGRlIHRvZG9zXHJcblx0XHRcdHRoaXMubWFzdGVyTm9kZSA9IHRoaXMudHJlZUl0ZW1zWzBdLmlkO1xyXG5cclxuXHRcdFx0dGhpcy5mbGF0dGVuZWRJdGVtcyA9IHRoaXMuZmxhdHRlbkl0ZW1zKHRoaXMudHJlZUl0ZW1zKTtcclxuXHRcdFx0Ly9DYXJnYW1vcyBsb3Mgbm9kb3Mgc2VsZWNjaW9uYWRvc1xyXG5cdFx0XHRpZih0aGlzLmNvbnRyb2wudmFsdWUgIT0gbnVsbCl7XHJcblx0XHRcdFx0dGhpcy5sb2FkRGF0YSgpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGZsYXR0ZW5JdGVtcyhpdGVtczogYW55W10pOiBhbnlbXSB7XHJcblx0XHRsZXQgZmxhdHRlbmVkOiBhbnlbXSA9IFtdO1xyXG5cclxuXHRcdGZvciAobGV0IGl0ZW0gb2YgaXRlbXMpIHtcclxuXHRcdFx0ZmxhdHRlbmVkLnB1c2goe2lkOiBpdGVtLmlkLCBuYW1lOiBpdGVtLm5hbWV9KTtcclxuXHRcdFx0bGV0IGNoaWxkRmxhdHRlbmVkOiBhbnlbXSA9IHRoaXMuZmxhdHRlbkl0ZW1zKGl0ZW0uY2hpbGRyZW4pO1xyXG5cdFx0XHRmbGF0dGVuZWQucHVzaCguLi5jaGlsZEZsYXR0ZW5lZCk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZmxhdHRlbmVkO1xyXG5cdH1cclxuXHJcblx0Z2V0IHNlbGVjdEl0ZW1zKCk6IGFueSB7XHJcblx0XHQvL1RPRE86IFNvbG8gc2VsZWN0TXVsdGlwbGU9ZmFsc2VcclxuXHRcdGlmICh0aGlzLnZhbHVlKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLnZhbHVlWzBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIFtdO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0c2V0IHNlbGVjdEl0ZW1zKHZhbHVlOiBhbnkpIHtcclxuXHRcdC8vVE9ETzogU29sbyBzZWxlY3RNdWx0aXBsZT1mYWxzZVxyXG5cdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdHRoaXMudmFsdWUgPSBbdmFsdWVdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy52YWx1ZSA9IFtdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMubG9hZFNlYXJjaERhdGEoKTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgbG9hZFNlYXJjaERhdGEoKSB7XHJcblx0XHRsZXQgY2hlY2tlZDogYW55ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnZhbHVlKSk7XHJcblx0XHRsZXQgb3V0cHV0UHJldmlldyA9IFtdO1xyXG5cdFx0Zm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlcy5sZW5ndGg7IGorKykge1xyXG5cdFx0XHRpZihjaGVja2VkLmluY2x1ZGVzKHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2pdLmlkKSkge1xyXG5cdFx0XHRcdHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2pdLmNoZWNrZWQgPSB0cnVlO1xyXG5cdFx0XHRcdG91dHB1dFByZXZpZXcucHVzaCh7bmFtZTogdGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbal0ubmFtZX0pO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2pdLmNoZWNrZWQgPSBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMub3V0cHV0UHJldmlldyA9IG91dHB1dFByZXZpZXc7XHJcblx0fVxyXG5cclxuXHQvL0dlbmVyYSBlbCBhcmJvbFxyXG5cdGdlbmVyYXRlVHJlZShpbnB1dCwgcGFyZW50KTogSXRlbUZsYXROb2RlW10ge1xyXG5cdFx0bGV0IG91dHB1dCA9IG5ldyBJdGVtRmxhdE5vZGUoKTtcclxuXHRcdG91dHB1dC5pZCA9IGlucHV0LmlkO1xyXG5cdFx0b3V0cHV0Lm5hbWUgPSBpbnB1dC5uYW1lO1xyXG5cdFx0b3V0cHV0LnBhcmVudCA9IHBhcmVudDtcclxuXHRcdG91dHB1dC5jaGVja2VkID0gaW5wdXQuY2hlY2tlZDtcclxuXHRcdG91dHB1dC5jaGlsZHJlbiA9IGlucHV0LmNoaWxkcmVuO1xyXG5cdFx0aWYoaW5wdXQuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRvdXRwdXQuY2hpbGRyZW4gPSBbXTtcclxuXHRcdH1cclxuXHRcdGZvcih2YXIgaSBpbiBpbnB1dC5jaGlsZHJlbikge1xyXG5cdFx0XHRvdXRwdXQuY2hpbGRyZW4ucHVzaCguLi50aGlzLmdlbmVyYXRlVHJlZShpbnB1dC5jaGlsZHJlbltpXSwgaW5wdXQuaWQpKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gW291dHB1dF07XHJcblx0fVxyXG5cclxuXHQvL1JlZnJlc2NhIGxvcyBub2RvcyBwYWRyZSwgbG9zIGRlc21hcmNhIHNpIG5vIGVzdGFuIHNlbGNjaW9uYWRvcyB0b2RvcyBzdSBoaWpvc1xyXG5cdHJlZnJlc2NhUGFkcmUobm9kZSwgc3RhdHVzKXtcclxuXHRcdGxldCBub2RvUGFkcmUgOiBJdGVtRmxhdE5vZGUgPSBudWxsO1xyXG5cclxuXHRcdGlmKHN0YXR1cyA9PSB0cnVlKSB7XHJcblx0XHRcdGlmKG5vZGUgIT0gbnVsbCkge1xyXG5cdFx0XHRcdGZvcihsZXQgaT0wOyBpIDwgdGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0XHRcdGlmKHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2ldLmlkID09IG5vZGUucGFyZW50KSB7XHJcblx0XHRcdFx0XHRcdG5vZG9QYWRyZSA9IHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2ldO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihub2RvUGFkcmUgIT0gbnVsbCkge1xyXG5cdFx0XHRcdFx0bm9kb1BhZHJlLmNoZWNrZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0Zm9yKGxldCBpPTA7aTx0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlcy5sZW5ndGg7aSsrKSB7XHJcblx0XHRcdFx0XHRcdGlmKHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2ldLnBhcmVudCA9PSBub2RvUGFkcmUuaWQgJiYgIXRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2ldLmNoZWNrZWQpIHtcclxuXHRcdFx0XHRcdFx0XHRub2RvUGFkcmUuY2hlY2tlZCA9IGZhbHNlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdGlmKG5vZG9QYWRyZSAhPSBudWxsKSB7XHJcblx0XHRcdFx0dGhpcy5yZWZyZXNjYVBhZHJlKG5vZG9QYWRyZSwgc3RhdHVzKTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0aWYobm9kZSAhPSBudWxsKSB7XHJcblx0XHRcdFx0Zm9yKGxldCBpPTA7IGk8dGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0XHRcdGlmKHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2ldLmlkID09IG5vZGUucGFyZW50KSB7XHJcblx0XHRcdFx0XHRcdG5vZG9QYWRyZSA9IHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2ldO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlc1tpXS5jaGVja2VkID0gc3RhdHVzO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRpZihub2RvUGFkcmUgIT0gbnVsbCkge1xyXG5cdFx0XHRcdHRoaXMucmVmcmVzY2FQYWRyZShub2RvUGFkcmUsIHN0YXR1cyk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcclxuXHR9XHJcblxyXG5cdC8vTWFyY2EgbyBkZXNtYXJjYSB1biBub2RvXHJcblx0Y2hlY2tOb2RlKGV2ZW50OiBhbnksIG5vZGU6IEl0ZW1GbGF0Tm9kZSkge1xyXG5cdFx0bm9kZS5jaGVja2VkID0gZXZlbnQuY2hlY2tlZDtcclxuXHRcdGlmKHRoaXMuc2VsZWN0TXVsdGlwbGUpe1xyXG5cdFx0XHRpZihldmVudC5jaGVja2VkKSB7XHJcblx0XHRcdFx0dGhpcy5jaGFuZ2VBbGxEZXNjZW5kYW50cyhub2RlLCB0cnVlKTtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2NhUGFkcmUobm9kZSwgdHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGhpcy5jaGFuZ2VBbGxEZXNjZW5kYW50cyhub2RlLCBmYWxzZSk7XHJcblx0XHRcdFx0dGhpcy5yZWZyZXNjYVBhZHJlKG5vZGUsIGZhbHNlKTtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLmdldFNlbGVjdGVkSXRlbXMobm9kZSk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0aWYoZXZlbnQuY2hlY2tlZCkge1xyXG5cdFx0XHRcdGZvcihsZXQgaiA9IDA7IGogPCB0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlcy5sZW5ndGg7IGorKykge1xyXG5cdFx0XHRcdFx0aWYodGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbal0uaWQgIT0gbm9kZS5pZCl7XHJcblx0XHRcdFx0XHRcdHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2pdLmNoZWNrZWQgPSBmYWxzZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dGhpcy5vdXRwdXRJdGVtcyA9IFtub2RlLmlkXTtcclxuXHRcdFx0XHR0aGlzLm91dHB1dFByZXZpZXcgPSBbbm9kZV07XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHRoaXMub3V0cHV0SXRlbXMgPSBbXTtcclxuXHRcdFx0XHR0aGlzLm91dHB1dFByZXZpZXcgPSBbXTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0dGhpcy5jb250cm9sLnNldFZhbHVlKHRoaXMub3V0cHV0SXRlbXMpO1xyXG5cdH1cclxuXHJcblx0Ly9DYW1iaWEgZWwgZXN0YWRvIGRlIHRvZG9zIGxvcyBkZXNjZW5kaWVudGVzIGVuIGZ1bmNpb24gZGUgbGEgZWxjY2lvblxyXG5cdGNoYW5nZUFsbERlc2NlbmRhbnRzIChub2RlLCBzdGF0dXMpIHtcclxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcblx0XHQgIFx0dmFyIGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXTtcclxuXHJcblx0XHQgIFx0Zm9yKGxldCBqID0gMDsgaiA8IHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzLmxlbmd0aDsgaisrKSB7XHJcblx0XHRcdFx0aWYodGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbal0uaWQgPT0gY2hpbGQuaWQpIHtcclxuXHRcdFx0XHRcdHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzW2pdLmNoZWNrZWQgPSBzdGF0dXM7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHRoaXMuY2hhbmdlQWxsRGVzY2VuZGFudHMoY2hpbGQsIHN0YXR1cyk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvL2Z1bmNpb24gcXVlIGRldnVlbHZlIGxvcyBpZCBkZSBsb3Mgbm9kb3Mgc2VsZWNjaW9uYWRvcyB1dGlsZXNcclxuXHRnZXRTZWxlY3RlZEl0ZW1zKG5vZGUpIHtcclxuXHRcdHRoaXMub3V0cHV0SXRlbXMgPSBbXTtcclxuXHRcdHRoaXMub3V0cHV0UHJldmlldyA9IFtdO1xyXG5cdFx0Ly9CdXNjYW1vcyBlbCBub2RvIG1hZXN0cm9cclxuXHRcdGxldCBub2RvTWFzdGVyIDogSXRlbUZsYXROb2RlID0gbnVsbDtcclxuXHRcdGZvcihsZXQgaSA9IDA7IGkgPCB0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRpZih0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlc1tpXS5pZCA9PSB0aGlzLm1hc3Rlck5vZGUpIHtcclxuXHRcdFx0XHRub2RvTWFzdGVyID0gdGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbaV07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdC8vQnVzY2Ftb3MgbG9zIGVsZW1lbnRvcyBxdWUgZGVmaW5pcmFuIGVsIHZhbG9yIGRlbCBjb21wb25lbnRlXHJcblx0XHRpZihub2RvTWFzdGVyLmNoZWNrZWQpIHtcclxuXHRcdFx0dGhpcy5vdXRwdXRJdGVtcyA9IFt0aGlzLm1hc3Rlck5vZGVdO1xyXG5cdFx0XHR0aGlzLm91dHB1dFByZXZpZXcgPSBbe25hbWU6IHRoaXMudHJlZUl0ZW1zWzBdLm5hbWV9XTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuZ2V0T3V0cHV0Tm9kZXMobm9kb01hc3Rlcik7XHJcblx0XHR9XHJcblx0XHQvL1JlZnJlc2NhbW9zIGVsIHZhbG9yIGRlbCBjb21wb25lbnRlXHJcblx0XHR0aGlzLmNvbnRyb2wuc2V0VmFsdWUodGhpcy5vdXRwdXRJdGVtcyk7XHJcblx0fVxyXG5cclxuXHRnZXRPdXRwdXROb2Rlcyhub2RlKXtcclxuXHRcdGlmKCFub2RlLmNoZWNrZWQgfHwgbm9kZS5pZCA9PSB