UNPKG

@noaestudio/forms

Version:

Dynamic forms extension for Covalent

560 lines (559 loc) 57 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; 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 */ var /** * Node for to-do item */ ItemNode = /** @class */ (function () { function ItemNode() { } return ItemNode; }()); /** * Node for to-do item */ export { 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 */ var /** * Flat to-do item node with expandable and level information */ ItemFlatNode = /** @class */ (function () { function ItemFlatNode() { } return ItemFlatNode; }()); /** * Flat to-do item node with expandable and level information */ export { 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 var /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(function () { return TreeSelectorComponent; }), multi: true, }; var TreeSelectorComponent = /** @class */ (function (_super) { tslib_1.__extends(TreeSelectorComponent, _super); function TreeSelectorComponent(translator, dialog, changeDetector) { var _this = _super.call(this) || this; _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 = function (node) { return node.level; }; _this.isExpandable = function (node) { return node.expandable; }; _this.getChildren = function (node) { return observableOf(node.children); }; _this.hasChild = function (_, _nodeData) { return _nodeData.expandable; }; _this.hasNoContent = function (_, _nodeData) { return _nodeData.name === ''; }; /** * Transformer to convert nested node to flat node. Record the nodes in maps for later use. */ _this.transformer = function (node, level) { var /** @type {?} */ existingNode = _this.nestedNodeMap.get(node); var /** @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 _this; } /** * @return {?} */ TreeSelectorComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (this.treeItems != null && this.treeItems.length > 0) { //Generamos los nodos var /** @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 {?} */ TreeSelectorComponent.prototype.flattenItems = /** * @param {?} items * @return {?} */ function (items) { var /** @type {?} */ flattened = []; try { for (var items_1 = tslib_1.__values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) { var item = items_1_1.value; flattened.push({ id: item.id, name: item.name }); var /** @type {?} */ childFlattened = this.flattenItems(item.children); flattened.push.apply(flattened, tslib_1.__spread(childFlattened)); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1); } finally { if (e_1) throw e_1.error; } } return flattened; var e_1, _a; }; Object.defineProperty(TreeSelectorComponent.prototype, "selectItems", { get: /** * @return {?} */ function () { //TODO: Solo selectMultiple=false if (this.value) { return this.value[0]; } else { return []; } }, set: /** * @param {?} value * @return {?} */ function (value) { //TODO: Solo selectMultiple=false if (value) { this.value = [value]; } else { this.value = []; } this.loadSearchData(); }, enumerable: true, configurable: true }); /** * @return {?} */ TreeSelectorComponent.prototype.loadSearchData = /** * @return {?} */ function () { var /** @type {?} */ checked = JSON.parse(JSON.stringify(this.value)); var /** @type {?} */ outputPreview = []; for (var /** @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; }; //Genera el arbol /** * @param {?} input * @param {?} parent * @return {?} */ TreeSelectorComponent.prototype.generateTree = /** * @param {?} input * @param {?} parent * @return {?} */ function (input, parent) { var /** @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) { (_a = output.children).push.apply(_a, tslib_1.__spread(this.generateTree(input.children[i], input.id))); } return [output]; var _a; }; //Refresca los nodos padre, los desmarca si no estan selccionados todos su hijos /** * @param {?} node * @param {?} status * @return {?} */ TreeSelectorComponent.prototype.refrescaPadre = /** * @param {?} node * @param {?} status * @return {?} */ function (node, status) { var /** @type {?} */ nodoPadre = null; if (status == true) { if (node != null) { for (var /** @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 (var /** @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 (var /** @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(); }; //Marca o desmarca un nodo /** * @param {?} event * @param {?} node * @return {?} */ TreeSelectorComponent.prototype.checkNode = /** * @param {?} event * @param {?} node * @return {?} */ function (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 (var /** @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); }; //Cambia el estado de todos los descendientes en funcion de la elccion /** * @param {?} node * @param {?} status * @return {?} */ TreeSelectorComponent.prototype.changeAllDescendants = /** * @param {?} node * @param {?} status * @return {?} */ function (node, status) { for (var /** @type {?} */ i = 0; i < node.children.length; i++) { var /** @type {?} */ child = node.children[i]; for (var /** @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); } }; //funcion que devuelve los id de los nodos seleccionados utiles /** * @param {?} node * @return {?} */ TreeSelectorComponent.prototype.getSelectedItems = /** * @param {?} node * @return {?} */ function (node) { this.outputItems = []; this.outputPreview = []; //Buscamos el nodo maestro var /** @type {?} */ nodoMaster = null; for (var /** @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 {?} */ TreeSelectorComponent.prototype.getOutputNodes = /** * @param {?} node * @return {?} */ function (node) { if (!node.checked || node.id == this.masterNode) { for (var /** @type {?} */ i = 0; i < node.children.length; i++) { var /** @type {?} */ child = node.children[i]; for (var /** @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]); } } } } }; //Funcion que carga marca los checks con los ids pasados al componente /** * @return {?} */ TreeSelectorComponent.prototype.loadData = /** * @return {?} */ function () { var /** @type {?} */ defaults = JSON.parse(JSON.stringify(this.control.value)); for (var /** @type {?} */ i = 0; i < defaults.length; i++) { for (var /** @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 {?} */ TreeSelectorComponent.prototype.toggleTree = /** * @return {?} */ function () { 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>\n<div class=\"buttons\">\n\t<button mat-raised-button color=\"primary\" (click)=\"toggleTree()\">\n\t\t<mat-icon *ngIf=\"!treeControl.isExpanded(treeControl.dataNodes[0])\">add</mat-icon>\n\t\t<mat-icon *ngIf=\"treeControl.isExpanded(treeControl.dataNodes[0])\">remove</mat-icon>\n\t</button>\n</div>\n<div *ngIf=\"searchable\" class=\"search-bar\">\n\t<ng-select [(ngModel)]=\"selectItems\" placeholder=\"Buscar\" [multiple]=\"selectMultiple\" [items]=\"flattenedItems\"\n\t\t[required]=\"required\" [searchable]=\"true\" bindLabel=\"name\" bindValue=\"id\" appendTo=\"body\" [style.flex]=\"100\">\n\t</ng-select>\n</div>\n<div class=\"container\">\n\t<mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n\t\t<mat-tree-node *matTreeNodeDef=\"let node; when: hasChild\" matTreeNodePadding>\n\t\t\t<button mat-icon-button matTreeNodeToggle\n\t\t\t\t[attr.aria-label]=\"'toggle ' + node.filename\">\n\t\t\t\t<mat-icon class=\"mat-icon-rtl-mirror\" *ngIf=\"node.children.length > 0\">\n\t\t\t\t\t{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}\n\t\t\t\t</mat-icon>\n\t\t\t</button>\n\t\t\t<mat-checkbox [checked]=\"node.checked\" (change)=\"checkNode($event, node)\">{{node.name}}</mat-checkbox>\n\t\t</mat-tree-node>\n\t</mat-tree>\n</div>\n<div class=\"selected-items\">\n\t<span *ngFor=\"let item of outputPreview\">{{item.name}}</span>\n</div>\n", },] }, ]; /** @nocollapse */ TreeSelectorComponent.ctorParameters = function () { return [ { type: TranslateService, }, { type: MatDialog, }, { type: ChangeDetectorRef, }, ]; }; return TreeSelectorComponent; }(AbstractControlValueAccessor)); export { TreeSelectorComponent }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AY292YWxlbnQvZHluYW1pYy1mb3Jtcy8iLCJzb3VyY2VzIjpbImR5bmFtaWMtZWxlbWVudHMvdHJlZS1zZWxlY3Rvci90cmVlLXNlbGVjdG9yLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBcUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RixPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUdqRixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU5QyxPQUFPLEVBQUMsRUFBRSxJQUFJLFlBQVksRUFBQyxNQUFNLE1BQU0sQ0FBQzs7OztBQU14Qzs7O0FBQUE7OzttQkFsQkE7SUF3QkMsQ0FBQTs7OztBQU5ELG9CQU1DOzs7Ozs7Ozs7Ozs7Ozs7O0FBR0Q7OztBQUFBOzs7dUJBM0JBO0lBbUNDLENBQUE7Ozs7QUFSRCx3QkFRQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFRCxNQUFNLENBQUMscUJBQU0sa0NBQWtDLEdBQVE7SUFDdEQsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLGNBQU0sT0FBQSxxQkFBcUIsRUFBckIsQ0FBcUIsQ0FBQztJQUNwRCxLQUFLLEVBQUUsSUFBSTtDQUNYLENB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QkFBaUI7O2dDQUFqRDtFQTZFMkMsNEJBQTRCO1NBQTFELHFCQUFxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgZm9yd2FyZFJlZiwgQ2hhbmdlRGV0ZWN0b3JSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTkdfVkFMVUVfQUNDRVNTT1IsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbFZhbHVlQWNjZXNzb3IgfSBmcm9tICcuLi9hYnN0cmFjdC1jb250cm9sLXZhbHVlLWFjY2Vzb3InO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcblxyXG5pbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XHJcbmltcG9ydCB7IEZsYXRUcmVlQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay90cmVlJztcclxuaW1wb3J0IHsgTWF0VHJlZUZsYXREYXRhU291cmNlLCBNYXRUcmVlRmxhdHRlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdHJlZSc7XHJcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcclxuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xyXG5cclxuaW1wb3J0IHtvZiBhcyBvYnNlcnZhYmxlT2Z9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG4vKipcclxuICogTm9kZSBmb3IgdG8tZG8gaXRlbVxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEl0ZW1Ob2RlIHtcclxuXHRpZDogbnVtYmVyO1xyXG5cdG5hbWU6IHN0cmluZzsgLy9pdGVtXHJcblx0Y2hpbGRyZW46IEl0ZW1Ob2RlW107XHJcblx0cGFyZW50OiBudW1iZXI7XHJcblx0Y2hlY2tlZDogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqIEZsYXQgdG8tZG8gaXRlbSBub2RlIHdpdGggZXhwYW5kYWJsZSBhbmQgbGV2ZWwgaW5mb3JtYXRpb24gKi9cclxuZXhwb3J0IGNsYXNzIEl0ZW1GbGF0Tm9kZSB7XHJcblx0aWQ6IG51bWJlcjtcclxuXHRuYW1lOiBzdHJpbmc7IC8vaXRlbVxyXG5cdHBhcmVudDogbnVtYmVyO1xyXG5cdGxldmVsOiBudW1iZXI7XHJcblx0ZXhwYW5kYWJsZTogYm9vbGVhbjtcclxuXHRjaGVja2VkOiBib29sZWFuO1xyXG5cdGNoaWxkcmVuOiBJdGVtRmxhdE5vZGVbXTtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IElOUFVUX0lOUFVUX0NPTlRST0xfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcclxuXHRwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuXHR1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBUcmVlU2VsZWN0b3JDb21wb25lbnQpLFxyXG5cdG11bHRpOiB0cnVlLFxyXG59O1xyXG5cclxuQENvbXBvbmVudCh7XHJcblx0cHJvdmlkZXJzOiBbIElOUFVUX0lOUFVUX0NPTlRST0xfVkFMVUVfQUNDRVNTT1IgXSxcclxuXHRzZWxlY3RvcjogJ3RyZWUtc2VsZWN0b3InLFxyXG5cdHN0eWxlczogW2AudGQtZHluYW1pYy1pbnB1dC13cmFwcGVyey1tcy1mbGV4LWRpcmVjdGlvbjpyb3c7ZmxleC1kaXJlY3Rpb246cm93O2Rpc3BsYXk6LW1zLWZsZXhib3g7ZGlzcGxheTpmbGV4O2JveC1zaXppbmc6Ym9yZGVyLWJveH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyIC50ZC1keW5hbWljLWlucHV0LWZpZWxkey1tcy1mbGV4OjE7ZmxleDoxO2JveC1zaXppbmc6Ym9yZGVyLWJveH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyIC5uZ3gtZWRpdG9ye21hcmdpbi10b3A6MTBweH0ubGFiZWx7cGFkZGluZzoxMHB4IDA7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NTAlfS5jb250YWluZXJ7b3ZlcmZsb3c6YXV0bztib3JkZXI6MXB4IHNvbGlkICNmM2YzZjM7Ym9yZGVyLXJhZGl1czo1cHggNXB4IDAgMH0uc2VsZWN0ZWQtaXRlbXN7cGFkZGluZzo1cHg7ZGlzcGxheTpibG9jaztiYWNrZ3JvdW5kOiNmM2YzZjM7Ym9yZGVyLXJhZGl1czowIDAgNXB4IDVweDttaW4taGVpZ2h0OjMwcHh9LnNlbGVjdGVkLWl0ZW1zIHNwYW57YmFja2dyb3VuZDojNjg5ZjM4O21hcmdpbjoycHg7cGFkZGluZzo1cHg7Ym9yZGVyLXJhZGl1czo1cHg7Y29sb3I6I2ZmZjtkaXNwbGF5OmlubGluZS1ibG9ja30uc2VhcmNoLWJhcntkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDo1MCU7dGV4dC1hbGlnbjpsZWZ0O21hcmdpbi1ib3R0b206MTBweH0uYnV0dG9uc3tkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDo1MCU7dGV4dC1hbGlnbjpyaWdodH0uYnV0dG9ucyBidXR0b257cGFkZGluZzowO3dpZHRoOjMwcHghaW1wb3J0YW50O21pbi13aWR0aDozMHB4O2JvcmRlci1yYWRpdXM6NTBweDtoZWlnaHQ6MzBweH0uYnV0dG9ucyBidXR0b24gbWF0LWljb257cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDotNHB4IWltcG9ydGFudH1gXSxcclxuXHR0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJsYWJlbFwiPnt7bGFiZWx9fSB7e3JlcXVpcmVkID8gJyonIDogJyd9fTwvZGl2PlxyXG48ZGl2IGNsYXNzPVwiYnV0dG9uc1wiPlxyXG5cdDxidXR0b24gbWF0LXJhaXNlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInRvZ2dsZVRyZWUoKVwiPlxyXG5cdFx0PG1hdC1pY29uICpuZ0lmPVwiIXRyZWVDb250cm9sLmlzRXhwYW5kZWQodHJlZUNvbnRyb2wuZGF0YU5vZGVzWzBdKVwiPmFkZDwvbWF0LWljb24+XHJcblx0XHQ8bWF0LWljb24gKm5nSWY9XCJ0cmVlQ29udHJvbC5pc0V4cGFuZGVkKHRyZWVDb250cm9sLmRhdGFOb2Rlc1swXSlcIj5yZW1vdmU8L21hdC1pY29uPlxyXG5cdDwvYnV0dG9uPlxyXG48L2Rpdj5cclxuPGRpdiAqbmdJZj1cInNlYXJjaGFibGVcIiBjbGFzcz1cInNlYXJjaC1iYXJcIj5cclxuXHQ8bmctc2VsZWN0IFsobmdNb2RlbCldPVwic2VsZWN0SXRlbXNcIiBwbGFjZWhvbGRlcj1cIkJ1c2NhclwiIFttdWx0aXBsZV09XCJzZWxlY3RNdWx0aXBsZVwiIFtpdGVtc109XCJmbGF0dGVuZWRJdGVtc1wiXHJcblx0XHRbcmVxdWlyZWRdPVwicmVxdWlyZWRcIiBbc2VhcmNoYWJsZV09XCJ0cnVlXCIgYmluZExhYmVsPVwibmFtZVwiIGJpbmRWYWx1ZT1cImlkXCIgYXBwZW5kVG89XCJib2R5XCIgW3N0eWxlLmZsZXhdPVwiMTAwXCI+XHJcblx0PC9uZy1zZWxlY3Q+XHJcbjwvZGl2PlxyXG48ZGl2IGNsYXNzPVwiY29udGFpbmVyXCI+XHJcblx0PG1hdC10cmVlIFtkYXRhU291cmNlXT1cImRhdGFTb3VyY2VcIiBbdHJlZUNvbnRyb2xdPVwidHJlZUNvbnRyb2xcIj5cclxuXHRcdDxtYXQtdHJlZS1ub2RlICptYXRUcmVlTm9kZURlZj1cImxldCBub2RlOyB3aGVuOiBoYXNDaGlsZFwiIG1hdFRyZWVOb2RlUGFkZGluZz5cclxuXHRcdFx0PGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gbWF0VHJlZU5vZGVUb2dnbGVcclxuXHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cIid0b2dnbGUgJyArIG5vZGUuZmlsZW5hbWVcIj5cclxuXHRcdFx0XHQ8bWF0LWljb24gY2xhc3M9XCJtYXQtaWNvbi1ydGwtbWlycm9yXCIgKm5nSWY9XCJub2RlLmNoaWxkcmVuLmxlbmd0aCA+IDBcIj5cclxuXHRcdFx0XHRcdHt7dHJlZUNvbnRyb2wuaXNFeHBhbmRlZChub2RlKSA/ICdleHBhbmRfbW9yZScgOiAnY2hldnJvbl9yaWdodCd9fVxyXG5cdFx0XHRcdDwvbWF0LWljb24+XHJcblx0XHRcdDwvYnV0dG9uPlxyXG5cdFx0XHQ8bWF0LWNoZWNrYm94IFtjaGVja2VkXT1cIm5vZGUuY2hlY2tlZFwiIChjaGFuZ2UpPVwiY2hlY2tOb2RlKCRldmVudCwgbm9kZSlcIj57e25vZGUubmFtZX19PC9tYXQtY2hlY2tib3g+XHJcblx0XHQ8L21hdC10cmVlLW5vZGU+XHJcblx0PC9tYXQtdHJlZT5cclxuPC9kaXY+XHJcbjxkaXYgY2xhc3M9XCJzZWxlY3RlZC1pdGVtc1wiPlxyXG5cdDxzcGFuICpuZ0Zvcj1cImxldCBpdGVtIG9mIG91dHB1dFByZXZpZXdcIj57e2l0ZW0ubmFtZX19PC9zcGFuPlxyXG48L2Rpdj5cclxuYCxcclxufSlcclxuZXhwb3J0IGNsYXNzIFRyZWVTZWxlY3RvckNvbXBvbmVudCBleHRlbmRzIEFic3RyYWN0Q29udHJvbFZhbHVlQWNjZXNzb3IgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciB7XHJcblxyXG5cdC8vQ29udHJvbFxyXG5cdGNvbnRyb2w6IEZvcm1Db250cm9sO1xyXG5cclxuXHQvKiogTWFwIGZyb20gZmxhdCBub2RlIHRvIG5lc3RlZCBub2RlLiBUaGlzIGhlbHBzIHVzIGZpbmRpbmcgdGhlIG5lc3RlZCBub2RlIHRvIGJlIG1vZGlmaWVkICovXHJcblx0ZmxhdE5vZGVNYXAgPSBuZXcgTWFwPEl0ZW1GbGF0Tm9kZSwgSXRlbU5vZGU+KCk7XHJcblxyXG5cdC8qKiBNYXAgZnJvbSBuZXN0ZWQgbm9kZSB0byBmbGF0dGVuZWQgbm9kZS4gVGhpcyBoZWxwcyB1cyB0byBrZWVwIHRoZSBzYW1lIG9iamVjdCBmb3Igc2VsZWN0aW9uICovXHJcblx0bmVzdGVkTm9kZU1hcCA9IG5ldyBNYXA8SXRlbU5vZGUsIEl0ZW1GbGF0Tm9kZT4oKTtcclxuXHJcblx0LyoqIEEgc2VsZWN0ZWQgcGFyZW50IG5vZGUgdG8gYmUgaW5zZXJ0ZWQgKi9cclxuXHRzZWxlY3RlZFBhcmVudDogSXRlbUZsYXROb2RlIHwgbnVsbCA9IG51bGw7XHJcblxyXG5cdHRyZWVDb250cm9sOiBGbGF0VHJlZUNvbnRyb2w8SXRlbUZsYXROb2RlPjtcclxuXHR0cmVlRmxhdHRlbmVyOiBNYXRUcmVlRmxhdHRlbmVyPEl0ZW1Ob2RlLCBJdGVtRmxhdE5vZGU+O1xyXG5cdGRhdGFTb3VyY2U6IE1hdFRyZWVGbGF0RGF0YVNvdXJjZTxJdGVtTm9kZSwgSXRlbUZsYXROb2RlPjtcclxuXHJcblx0LyoqIFRoZSBzZWxlY3Rpb24gZm9yIGNoZWNrbGlzdCAqL1xyXG5cdGNoZWNrbGlzdFNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxJdGVtRmxhdE5vZGU+KHRydWUgLyogbXVsdGlwbGUgKi8pO1xyXG5cclxuXHRzZWxlY3RNdWx0aXBsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuXHQvKiogQ29tcG9uZW50IEF0dHJpYnV0ZXMgKi9cclxuXHJcblx0Ly9MYWJlbCBkZWwgY29tcG9uZW50ZVxyXG5cdGxhYmVsOiBzdHJpbmcgPSAnJztcclxuXHJcblx0Ly9SZXF1aXJlZCBvciBub3RcclxuXHRyZXF1aXJlZDogYm9vbGVhbjtcclxuXHJcblx0Ly9TZWFyY2hhYmxlIG9yIG5vdFxyXG5cdHNlYXJjaGFibGU6IGJvb2xlYW47XHJcblx0Ly9TZWFyY2ggYXR0cmlidXRlcyAobm90IGNvbXBvbmVudHMpXHJcblx0ZmxhdHRlbmVkSXRlbXM6IGFueVtdID0gW107XHJcblxyXG5cdC8vSXRlbXNcclxuXHR0cmVlSXRlbXM6IGFueTtcclxuXHJcblx0Ly9Ob2RvIHBhZHJlIGRlIHRvZG9zXHJcblx0bWFzdGVyTm9kZTogbnVtYmVyID0gMDtcclxuXHJcblx0Ly9FbGVtZW50b3MgYSBkZXZvbHZlclxyXG5cdG91dHB1dEl0ZW1zOiBudW1iZXJbXSA9IFtdO1xyXG5cclxuXHQvL1ByZXZpZXcgU2VsZWN0ZWRcclxuXHRvdXRwdXRQcmV2aWV3OiBhbnlbXSA9IFtdO1xyXG5cclxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIHRyYW5zbGF0b3I6IFRyYW5zbGF0ZVNlcnZpY2UsIHB1YmxpYyBkaWFsb2c6IE1hdERpYWxvZywgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcclxuXHRcdHN1cGVyKCk7XHJcblx0XHR0aGlzLnRyZWVGbGF0dGVuZXIgPSBuZXcgTWF0VHJlZUZsYXR0ZW5lcih0aGlzLnRyYW5zZm9ybWVyLCB0aGlzLmdldExldmVsLCB0aGlzLmlzRXhwYW5kYWJsZSwgdGhpcy5nZXRDaGlsZHJlbik7XHJcblx0XHR0aGlzLnRyZWVDb250cm9sID0gbmV3IEZsYXRUcmVlQ29udHJvbDxJdGVtRmxhdE5vZGU+KHRoaXMuZ2V0TGV2ZWwsIHRoaXMuaXNFeHBhbmRhYmxlKTtcclxuXHRcdHRoaXMuZGF0YVNvdXJjZSA9IG5ldyBNYXRUcmVlRmxhdERhdGFTb3VyY2UodGhpcy50cmVlQ29udHJvbCwgdGhpcy50cmVlRmxhdHRlbmVyKTtcclxuXHR9XHJcblxyXG5cdG5nT25Jbml0KCkge1xyXG5cdFx0aWYodGhpcy50cmVlSXRlbXMgIT0gbnVsbCAmJiB0aGlzLnRyZWVJdGVtcy5sZW5ndGggPiAwKSB7XHJcblx0XHRcdC8vR2VuZXJhbW9zIGxvcyBub2Rvc1xyXG5cdFx0XHRsZXQgdHJlZUl0ZW1zID0gdGhpcy5nZW5lcmF0ZVRyZWUodGhpcy50cmVlSXRlbXNbMF0sIG51bGwpO1xyXG5cdFx0XHR0aGlzLmRhdGFTb3VyY2UuZGF0YSA9IHRyZWVJdGVtcztcclxuXHRcdFx0Ly9Db2dlbW9zIGVsIG5vZG8gcGFkcmUgZGUgdG9kb3NcclxuXHRcdFx0dGhpcy5tYXN0ZXJOb2RlID0gdGhpcy50cmVlSXRlbXNbMF0uaWQ7XHJcblxyXG5cdFx0XHR0aGlzLmZsYXR0ZW5lZEl0ZW1zID0gdGhpcy5mbGF0dGVuSXRlbXModGhpcy50cmVlSXRlbXMpO1xyXG5cdFx0XHQvL0NhcmdhbW9zIGxvcyBub2RvcyBzZWxlY2Npb25hZG9zXHJcblx0XHRcdGlmKHRoaXMuY29udHJvbC52YWx1ZSAhPSBudWxsKXtcclxuXHRcdFx0XHR0aGlzLmxvYWREYXRhKCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHByaXZhdGUgZmxhdHRlbkl0ZW1zKGl0ZW1zOiBhbnlbXSk6IGFueVtdIHtcclxuXHRcdGxldCBmbGF0dGVuZWQ6IGFueVtdID0gW107XHJcblxyXG5cdFx0Zm9yIChsZXQgaXRlbSBvZiBpdGVtcykge1xyXG5cdFx0XHRmbGF0dGVuZWQucHVzaCh7aWQ6IGl0ZW0uaWQsIG5hbWU6IGl0ZW0ubmFtZX0pO1xyXG5cdFx0XHRsZXQgY2hpbGRGbGF0dGVuZWQ6IGFueVtdID0gdGhpcy5mbGF0dGVuSXRlbXMoaXRlbS5jaGlsZHJlbik7XHJcblx0XHRcdGZsYXR0ZW5lZC5wdXNoKC4uLmNoaWxkRmxhdHRlbmVkKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmbGF0dGVuZWQ7XHJcblx0fVxyXG5cclxuXHRnZXQgc2VsZWN0SXRlbXMoKTogYW55IHtcclxuXHRcdC8vVE9ETzogU29sbyBzZWxlY3RNdWx0aXBsZT1mYWxzZVxyXG5cdFx0aWYgKHRoaXMudmFsdWUpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMudmFsdWVbMF07XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4gW107XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRzZXQgc2VsZWN0SXRlbXModmFsdWU6IGFueSkge1xyXG5cdFx0Ly9UT0RPOiBTb2xvIHNlbGVjdE11bHRpcGxlPWZhbHNlXHJcblx0XHRpZiAodmFsdWUpIHtcclxuXHRcdFx0dGhpcy52YWx1ZSA9IFt2YWx1ZV07XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLnZhbHVlID0gW107XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5sb2FkU2VhcmNoRGF0YSgpO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBsb2FkU2VhcmNoRGF0YSgpIHtcclxuXHRcdGxldCBjaGVja2VkOiBhbnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMudmFsdWUpKTtcclxuXHRcdGxldCBvdXRwdXRQcmV2aWV3ID0gW107XHJcblx0XHRmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzLmxlbmd0aDsgaisrKSB7XHJcblx0XHRcdGlmKGNoZWNrZWQuaW5jbHVkZXModGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbal0uaWQpKSB7XHJcblx0XHRcdFx0dGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbal0uY2hlY2tlZCA9IHRydWU7XHJcblx0XHRcdFx0b3V0cHV0UHJldmlldy5wdXNoKHtuYW1lOiB0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlc1tqXS5uYW1lfSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbal0uY2hlY2tlZCA9IGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5vdXRwdXRQcmV2aWV3ID0gb3V0cHV0UHJldmlldztcclxuXHR9XHJcblxyXG5cdC8vR2VuZXJhIGVsIGFyYm9sXHJcblx0Z2VuZXJhdGVUcmVlKGlucHV0LCBwYXJlbnQpOiBJdGVtRmxhdE5vZGVbXSB7XHJcblx0XHRsZXQgb3V0cHV0ID0gbmV3IEl0ZW1GbGF0Tm9kZSgpO1xyXG5cdFx0b3V0cHV0LmlkID0gaW5wdXQuaWQ7XHJcblx0XHRvdXRwdXQubmFtZSA9IGlucHV0Lm5hbWU7XHJcblx0XHRvdXRwdXQucGFyZW50ID0gcGFyZW50O1xyXG5cdFx0b3V0cHV0LmNoZWNrZWQgPSBpbnB1dC5jaGVja2VkO1xyXG5cdFx0b3V0cHV0LmNoaWxkcmVuID0gaW5wdXQuY2hpbGRyZW47XHJcblx0XHRpZihpbnB1dC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XHJcblx0XHRcdG91dHB1dC5jaGlsZHJlbiA9IFtdO1xyXG5cdFx0fVxyXG5cdFx0Zm9yKHZhciBpIGluIGlucHV0LmNoaWxkcmVuKSB7XHJcblx0XHRcdG91dHB1dC5jaGlsZHJlbi5wdXNoKC4uLnRoaXMuZ2VuZXJhdGVUcmVlKGlucHV0LmNoaWxkcmVuW2ldLCBpbnB1dC5pZCkpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBbb3V0cHV0XTtcclxuXHR9XHJcblxyXG5cdC8vUmVmcmVzY2EgbG9zIG5vZG9zIHBhZHJlLCBsb3MgZGVzbWFyY2Egc2kgbm8gZXN0YW4gc2VsY2Npb25hZG9zIHRvZG9zIHN1IGhpam9zXHJcblx0cmVmcmVzY2FQYWRyZShub2RlLCBzdGF0dXMpe1xyXG5cdFx0bGV0IG5vZG9QYWRyZSA6IEl0ZW1GbGF0Tm9kZSA9IG51bGw7XHJcblxyXG5cdFx0aWYoc3RhdHVzID09IHRydWUpIHtcclxuXHRcdFx0aWYobm9kZSAhPSBudWxsKSB7XHJcblx0XHRcdFx0Zm9yKGxldCBpPTA7IGkgPCB0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdFx0aWYodGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbaV0uaWQgPT0gbm9kZS5wYXJlbnQpIHtcclxuXHRcdFx0XHRcdFx0bm9kb1BhZHJlID0gdGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbaV07XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKG5vZG9QYWRyZSAhPSBudWxsKSB7XHJcblx0XHRcdFx0XHRub2RvUGFkcmUuY2hlY2tlZCA9IHRydWU7XHJcblx0XHRcdFx0XHRmb3IobGV0IGk9MDtpPHRoaXMudHJlZUNvbnRyb2wuZGF0YU5vZGVzLmxlbmd0aDtpKyspIHtcclxuXHRcdFx0XHRcdFx0aWYodGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbaV0ucGFyZW50ID09IG5vZG9QYWRyZS5pZCAmJiAhdGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbaV0uY2hlY2tlZCkge1xyXG5cdFx0XHRcdFx0XHRcdG5vZG9QYWRyZS5jaGVja2VkID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0aWYobm9kb1BhZHJlICE9IG51bGwpIHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2NhUGFkcmUobm9kb1BhZHJlLCBzdGF0dXMpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRpZihub2RlICE9IG51bGwpIHtcclxuXHRcdFx0XHRmb3IobGV0IGk9MDsgaTx0aGlzLnRyZWVDb250cm9sLmRhdGFOb2Rlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdFx0aWYodGhpcy50cmVlQ29udHJvbC5kYXRhTm9kZXNbaV0uaWQgPT0gbm9kZS5wYXJlbnQpIHtcclxuXHRcdFx0XHRcdFx0bm9kb1BhZHJ