UNPKG

truly-ui

Version:

Web Components for Desktop Applications.

360 lines (358 loc) 51.8 kB
/* MIT License Copyright (c) 2019 Temainfo Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Component, Input, Output, Inject, Optional, ViewChild, EventEmitter, Self, } from '@angular/core'; import * as objectPath from 'object-path'; import { OverlayAnimation } from '../core/directives/overlay-animation'; import { KeyEvent } from '../core/enums/key-events'; import { DROPDOWN_CONFIG } from './interfaces/dropdown.config'; import { ValueAccessorBase } from '../input/core/value-accessor'; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; import * as i2 from "@angular/common"; import * as i3 from "../overlaylist/overlay-list"; import * as i4 from "../icons/icons"; import * as i5 from "../loader/loader"; import * as i6 from "@angular/cdk/overlay"; import * as i7 from "../internals/components/label/label"; export class TlDropDownList extends ValueAccessorBase { set data(data) { if (data) { this._data = data; this.initializeComponent(); } } get data() { return this._data; } constructor(dropdownConfig, changes, ngControl) { super(); this.changes = changes; this.ngControl = ngControl; this.keyText = null; this.icon = null; this.debounceTime = 200; this.disabled = false; this.labelPlacement = 'left'; this.labelSize = '100px'; this.itemHeight = '23px'; this.keyValue = null; this.maxHeight = '150px'; this.identifier = null; this.defaultOption = false; this.groupBy = null; this.width = '100%'; this.placeholder = 'Select Item'; this.modelMode = 'object'; this.searchOnList = false; this.selectItem = new EventEmitter(); this.typeOfData = 'complex'; this.selectedDescription = ''; this.isOpen = false; this.datasource = []; this.isLoading = true; this.setControl(); this.setOptions(dropdownConfig); } get control() { return this.ngControl?.control; } ngOnInit() { this.listenModelChange(); this.getModelValue(); } setControl() { if (this.ngControl) { this.ngControl.valueAccessor = this; } } onSearch(searchTextValue) { const filter = []; this.datasource = this.data.slice(); this.datasource.filter((item) => { if (this.getItemText(item).toLowerCase().includes(searchTextValue.toLowerCase())) { filter.push(item); } }); this.datasource = filter; } getItemText(item) { if (this.typeOfData === 'simple') { return item; } return objectPath.get(item, this.keyText); } onKeyDown($event) { this.handleSelectInLetter($event.key); const keyEvent = { [KeyEvent.SPACE]: () => this.handleOpenList($event), [KeyEvent.ARROWDOWN]: () => this.stopEvent($event), [KeyEvent.ARROWUP]: () => this.stopEvent($event), [KeyEvent.ESCAPE]: () => this.handleEscape($event) }; if (keyEvent[$event.code]) { keyEvent[$event.code](); } } handleEscape($event) { if (this.isOpen) { this.isOpen = false; this.stopEvent($event); } } getNativeInput() { return this.input.nativeElement; } onFindByLetter(value) { this.handleSelectInLetter(value); } onSelectOption($event) { this.isOpen = false; this.optionSelected = $event; this.selectedDescription = this.isSimpleData() ? $event.option.item : objectPath.get($event.option.item, this.keyText); this.selectItem.emit($event.option.item); this.handleKeyModelValue($event.option.item); this.setInputFocus(); } onDefaultOption() { this.value = ''; this.selectedDescription = this.placeholder; this.optionSelected = null; this.isOpen = false; } isModelModeString() { return this.modelMode === 'string'; } handleOpenList($event) { this.stopEvent($event); if (!this.isOpen && !this.disabled && !this.isLoading) { this.isOpen = true; this.setUpComponent(); } } onBackdropClick() { this.isOpen = false; this.changes.detectChanges(); } initializeComponent() { this.setUpComponent(); this.validateData(); this.getModelValue(); } setUpComponent() { this.datasource = this.data; if (this.data.length > 0) { this.isLoading = false; } } validateData() { const key = Object.keys(this.data)[0]; if (typeof this.data[key] === 'string') { this.typeOfData = 'simple'; } } handleCloseDropdown() { this.isOpen = false; this.setInputFocus(); } setInputFocus() { this.input.nativeElement.focus(); } isSimpleData() { return this.typeOfData === 'simple'; } listenModelChange() { if (this.control) { this.control.valueChanges.subscribe(() => { this.getModelValue(); }); } } handleKeyModelValue(itemValue) { if (this.isSimpleData()) { return this.value = itemValue; } if (!this.keyValue) { return this.value = itemValue; } return this.value = objectPath.get(itemValue, this.keyValue); } getModelValue() { if (!this.control) { return; } this.datasource.forEach((value, index) => { if (this.control.value) { if (this.getCompare(value) === this.getCompareModel()) { this.selectedDescription = this.getDescription(value); this.indexOptionSelectedModel = index; this.changes.detectChanges(); this.handleKeyModelValue(value); return; } } }); } setOptions(options) { if (options) { const self = this; Object.keys(options).forEach(function (key) { self[key] = options[key]; }); } } getCompareModel() { if (this.isSimpleData()) { return this.control.value; } if (!this.keyValue) { return objectPath.get(this.control.value, this.identifier); } if (this.isModelModeString()) { return this.control.value; } return objectPath.get(this.control.value, this.keyValue); } getCompare(value) { if (this.isSimpleData()) { return value; } if (!this.keyValue) { return objectPath.get(value, this.identifier); } return objectPath.get(value, this.keyValue); } getDescription(value) { if (this.isSimpleData()) { return value; } return objectPath.get(value, this.keyText); } handleSelectInLetter(keyInput) { const selected = this.selectByFirst(keyInput); if (selected) { this.selectedDescription = this.getDescription(selected.option); this.optionSelected = { option: selected.option, index: selected.index }; this.handleKeyModelValue(selected.option); } } stopEvent($event) { $event.stopPropagation(); $event.preventDefault(); } selectByFirst(keyInput) { let selected = null; this.datasource.forEach((option, index) => { if (this.getFirstLetterOfItem(option) === this.getKeyInputLowerCase(keyInput)) { selected = { option, index }; return; } }); return selected; } getKeyInputLowerCase(keyInput) { return String(keyInput).toLowerCase(); } getFirstLetterOfItem(item) { return String(objectPath.get(item, this.keyText)).substring(0, 1).toLowerCase(); } ngOnChanges({ data }) { if (data) { if (!data.firstChange && data.currentValue.length === 0) { this.isLoading = false; } } } } /** @nocollapse */ TlDropDownList.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlDropDownList, deps: [{ token: DROPDOWN_CONFIG, optional: true }, { token: i0.ChangeDetectorRef }, { token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ TlDropDownList.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlDropDownList, selector: "tl-dropdown-list", inputs: { data: "data", keyText: "keyText", icon: "icon", label: "label", debounceTime: "debounceTime", disabled: "disabled", labelPlacement: "labelPlacement", labelSize: "labelSize", itemHeight: "itemHeight", keyValue: "keyValue", maxHeight: "maxHeight", identifier: "identifier", defaultOption: "defaultOption", groupBy: "groupBy", width: "width", placeholder: "placeholder", modelMode: "modelMode", searchOnList: "searchOnList" }, outputs: { selectItem: "selectItem" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"ui-dropdown-box\" [ngStyle]=\"{'line-height' : itemHeight, 'width': width}\">\n\n <div class=\"ui-loading-icon\" [style.height]=\"itemHeight\" *ngIf=\"isLoading\">\n <tl-loader></tl-loader>\n </div>\n\n <tl-label *ngIf=\"label\"\n [labelPlacement]=\"labelPlacement\"\n [labelSize]=\"labelSize\"\n [labelTitle]=\"label\">\n </tl-label>\n\n <div class=\"ui-dropdown-wrapper\">\n <input cdkOverlayOrigin\n #input\n readonly\n #trigger=\"cdkOverlayOrigin\"\n [attr.disabled]=\"disabled ? true : null\"\n (keydown)=\"onKeyDown($event)\"\n (click)=\"handleOpenList($event)\"\n value=\"{{ selectedDescription ? selectedDescription : placeholder }}\"\n [ngClass]=\"{ 'ng-invalid' : control?.invalid, 'disabled': disabled }\"\n [ngStyle]=\"{'height' : itemHeight, 'line-height' : itemHeight}\"\n class=\"ui-dropdown\">\n <div class=\"ui-dropdown-icon\"\n [style.height]=\"itemHeight\"\n [style.transform]=\"isOpen ? 'rotate(180deg)' : 'rotate(0)'\"\n [ngClass]=\"{ 'disabled': disabled, 'ng-invalid' : control?.invalid }\">\n <tl-icon [lib]=\"'ion'\" [style]=\"'ios'\">arrow-down</tl-icon>\n </div>\n </div>\n <input readonly notform class=\"ui-hidden-input\" [(ngModel)]=\"value\">\n <ng-template cdkConnectedOverlay\n (backdropClick)=\"onBackdropClick()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n [cdkConnectedOverlayOpen]=\"isOpen\">\n <tl-overlay-list\n @overlay\n (selectOption)=\"onSelectOption($event)\"\n (search)=\"onSearch($event)\"\n (close)=\"handleCloseDropdown()\"\n (defaultOption)=\"onDefaultOption()\"\n (findByLetter)=\"onFindByLetter($event)\"\n [customInput]=\"input\"\n [typeOfData]=\"typeOfData\"\n [hasDefaultOption]=\"defaultOption\"\n [defaultOptionText]=\"placeholder\"\n [groupBy]=\"groupBy\"\n [optionSelected]=\"optionSelected\"\n [inputModelIndex]=\"indexOptionSelectedModel\"\n [datasource]=\"datasource\"\n [maxHeight]=\"maxHeight\"\n [itemHeight]=\"itemHeight\"\n [width]=\"input.offsetWidth + 'px'\"\n [icon]=\"icon\"\n [keyText]=\"keyText\"\n [searchOnList]=\"searchOnList\">\n </tl-overlay-list>\n </ng-template>\n</div>\n", styles: ["*{box-sizing:border-box}.ui-dropdown-box{width:100%;position:relative;display:table}.ui-dropdown-box>.ui-dropdown-wrapper{position:relative}.ui-dropdown-box>.ui-dropdown-wrapper>.ui-dropdown{border-radius:3px;width:100%;padding-left:5px;cursor:pointer;font-size:1em;font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-weight:400;user-select:none;-webkit-user-select:none}.ui-dropdown-box>.ui-dropdown-wrapper>.ui-dropdown-icon{position:absolute;top:0;width:20px;right:10px;text-align:center;font-size:1em;font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-weight:400;transition:transform linear .2s;pointer-events:none}.ui-dropdown-box>.ui-dropdown-wrapper>.ui-dropdown-icon i{padding:0}.ui-dropdown-box>.ui-hidden-input{position:absolute;left:0;opacity:0;width:0;bottom:0}.ui-dropdown-box .ui-loading-icon{position:absolute;width:18px;height:18px;z-index:1;margin:0;right:35px}.ui-dropdown-box tl-icon{position:absolute;right:5px;opacity:.5}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.TlOverlayList, selector: "tl-overlay-list", inputs: ["datasource", "searchOnList", "itemHeight", "inputModelIndex", "optionSelected", "typeOfData", "keyText", "groupBy", "keyIcon", "icon", "defaultIcon", "defaultOptionText", "width", "maxHeight", "customInput", "customFocus", "hasDefaultOption"], outputs: ["selectOption", "defaultOption", "search", "findByLetter", "close"] }, { kind: "component", type: i4.TlIcons, selector: "tl-icon", inputs: ["icon", "lib", "style", "size", "animation", "color", "align"] }, { kind: "component", type: i5.TlLoader, selector: "tl-loader", inputs: ["color", "strokeWidth"] }, { kind: "directive", type: i6.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i6.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i7.TlLabel, selector: "tl-label", inputs: ["labelPlacement", "required", "labelSize", "labelTitle"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], animations: [OverlayAnimation] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlDropDownList, decorators: [{ type: Component, args: [{ selector: 'tl-dropdown-list', animations: [OverlayAnimation], template: "<div class=\"ui-dropdown-box\" [ngStyle]=\"{'line-height' : itemHeight, 'width': width}\">\n\n <div class=\"ui-loading-icon\" [style.height]=\"itemHeight\" *ngIf=\"isLoading\">\n <tl-loader></tl-loader>\n </div>\n\n <tl-label *ngIf=\"label\"\n [labelPlacement]=\"labelPlacement\"\n [labelSize]=\"labelSize\"\n [labelTitle]=\"label\">\n </tl-label>\n\n <div class=\"ui-dropdown-wrapper\">\n <input cdkOverlayOrigin\n #input\n readonly\n #trigger=\"cdkOverlayOrigin\"\n [attr.disabled]=\"disabled ? true : null\"\n (keydown)=\"onKeyDown($event)\"\n (click)=\"handleOpenList($event)\"\n value=\"{{ selectedDescription ? selectedDescription : placeholder }}\"\n [ngClass]=\"{ 'ng-invalid' : control?.invalid, 'disabled': disabled }\"\n [ngStyle]=\"{'height' : itemHeight, 'line-height' : itemHeight}\"\n class=\"ui-dropdown\">\n <div class=\"ui-dropdown-icon\"\n [style.height]=\"itemHeight\"\n [style.transform]=\"isOpen ? 'rotate(180deg)' : 'rotate(0)'\"\n [ngClass]=\"{ 'disabled': disabled, 'ng-invalid' : control?.invalid }\">\n <tl-icon [lib]=\"'ion'\" [style]=\"'ios'\">arrow-down</tl-icon>\n </div>\n </div>\n <input readonly notform class=\"ui-hidden-input\" [(ngModel)]=\"value\">\n <ng-template cdkConnectedOverlay\n (backdropClick)=\"onBackdropClick()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n [cdkConnectedOverlayOpen]=\"isOpen\">\n <tl-overlay-list\n @overlay\n (selectOption)=\"onSelectOption($event)\"\n (search)=\"onSearch($event)\"\n (close)=\"handleCloseDropdown()\"\n (defaultOption)=\"onDefaultOption()\"\n (findByLetter)=\"onFindByLetter($event)\"\n [customInput]=\"input\"\n [typeOfData]=\"typeOfData\"\n [hasDefaultOption]=\"defaultOption\"\n [defaultOptionText]=\"placeholder\"\n [groupBy]=\"groupBy\"\n [optionSelected]=\"optionSelected\"\n [inputModelIndex]=\"indexOptionSelectedModel\"\n [datasource]=\"datasource\"\n [maxHeight]=\"maxHeight\"\n [itemHeight]=\"itemHeight\"\n [width]=\"input.offsetWidth + 'px'\"\n [icon]=\"icon\"\n [keyText]=\"keyText\"\n [searchOnList]=\"searchOnList\">\n </tl-overlay-list>\n </ng-template>\n</div>\n", styles: ["*{box-sizing:border-box}.ui-dropdown-box{width:100%;position:relative;display:table}.ui-dropdown-box>.ui-dropdown-wrapper{position:relative}.ui-dropdown-box>.ui-dropdown-wrapper>.ui-dropdown{border-radius:3px;width:100%;padding-left:5px;cursor:pointer;font-size:1em;font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-weight:400;user-select:none;-webkit-user-select:none}.ui-dropdown-box>.ui-dropdown-wrapper>.ui-dropdown-icon{position:absolute;top:0;width:20px;right:10px;text-align:center;font-size:1em;font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-weight:400;transition:transform linear .2s;pointer-events:none}.ui-dropdown-box>.ui-dropdown-wrapper>.ui-dropdown-icon i{padding:0}.ui-dropdown-box>.ui-hidden-input{position:absolute;left:0;opacity:0;width:0;bottom:0}.ui-dropdown-box .ui-loading-icon{position:absolute;width:18px;height:18px;z-index:1;margin:0;right:35px}.ui-dropdown-box tl-icon{position:absolute;right:5px;opacity:.5}\n"] }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DROPDOWN_CONFIG] }] }, { type: i0.ChangeDetectorRef }, { type: i1.NgControl, decorators: [{ type: Optional }, { type: Self }] }]; }, propDecorators: { data: [{ type: Input, args: ['data'] }], keyText: [{ type: Input, args: ['keyText'] }], icon: [{ type: Input, args: ['icon'] }], label: [{ type: Input, args: ['label'] }], debounceTime: [{ type: Input, args: ['debounceTime'] }], disabled: [{ type: Input, args: ['disabled'] }], labelPlacement: [{ type: Input, args: ['labelPlacement'] }], labelSize: [{ type: Input, args: ['labelSize'] }], itemHeight: [{ type: Input, args: ['itemHeight'] }], keyValue: [{ type: Input, args: ['keyValue'] }], maxHeight: [{ type: Input, args: ['maxHeight'] }], identifier: [{ type: Input, args: ['identifier'] }], defaultOption: [{ type: Input, args: ['defaultOption'] }], groupBy: [{ type: Input, args: ['groupBy'] }], width: [{ type: Input, args: ['width'] }], placeholder: [{ type: Input, args: ['placeholder'] }], modelMode: [{ type: Input, args: ['modelMode'] }], searchOnList: [{ type: Input, args: ['searchOnList'] }], selectItem: [{ type: Output, args: ['selectItem'] }], input: [{ type: ViewChild, args: ['input', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd25saXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdHJ1bHktdWkvc3JjL2NvbXBvbmVudHMvZHJvcGRvd25saXN0L2Ryb3Bkb3dubGlzdC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL2Ryb3Bkb3dubGlzdC9kcm9wZG93bmxpc3QuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFFBQVEsRUFDUixTQUFTLEVBQ2MsWUFBWSxFQUFvQyxJQUFJLEdBQzVFLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sS0FBSyxVQUFVLE1BQU0sYUFBYSxDQUFDO0FBRzFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZUFBZSxFQUFrQixNQUFNLDhCQUE4QixDQUFDO0FBRy9FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7Ozs7QUFRakUsTUFBTSxPQUFPLGNBQWUsU0FBUSxpQkFBc0I7SUFFeEQsSUFDSSxJQUFJLENBQUUsSUFBVztRQUNuQixJQUFLLElBQUksRUFBRztZQUNWLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1NBQzVCO0lBQ0gsQ0FBQztJQUVELElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBd0RELFlBQW9ELGNBQThCLEVBQ3hFLE9BQTBCLEVBQTZCLFNBQW9CO1FBQ25GLEtBQUssRUFBRSxDQUFDO1FBREEsWUFBTyxH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QU0sRUFBRSxJQUFJLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuIE1JVCBMaWNlbnNlXG5cbiBDb3B5cmlnaHQgKGMpIDIwMTkgVGVtYWluZm8gU29mdHdhcmVcblxuIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gU09GVFdBUkUuXG4gKi9cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgSW5qZWN0LFxuICBPcHRpb25hbCxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLCBPbkNoYW5nZXMsIEV2ZW50RW1pdHRlciwgQ2hhbmdlRGV0ZWN0b3JSZWYsIFNpbXBsZUNoYW5nZXMsIFNlbGYsIE9uSW5pdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCAqIGFzIG9iamVjdFBhdGggZnJvbSAnb2JqZWN0LXBhdGgnO1xuXG5pbXBvcnQgeyBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBPdmVybGF5QW5pbWF0aW9uIH0gZnJvbSAnLi4vY29yZS9kaXJlY3RpdmVzL292ZXJsYXktYW5pbWF0aW9uJztcbmltcG9ydCB7IEtleUV2ZW50IH0gZnJvbSAnLi4vY29yZS9lbnVtcy9rZXktZXZlbnRzJztcbmltcG9ydCB7IERST1BET1dOX0NPTkZJRywgRHJvcGRvd25Db25maWcgfSBmcm9tICcuL2ludGVyZmFjZXMvZHJvcGRvd24uY29uZmlnJztcbmltcG9ydCB7IExpc3RJdGVtSW50ZXJmYWNlIH0gZnJvbSAnLi9pbnRlcmZhY2VzL2xpc3QtaXRlbSc7XG5pbXBvcnQgeyBUbExpc3RJdGVtIH0gZnJvbSAnLi4vb3ZlcmxheWxpc3QvbGlzdC1pdGVtL2xpc3QtaXRlbSc7XG5pbXBvcnQgeyBWYWx1ZUFjY2Vzc29yQmFzZSB9IGZyb20gJy4uL2lucHV0L2NvcmUvdmFsdWUtYWNjZXNzb3InO1xuXG5AQ29tcG9uZW50KCB7XG4gIHNlbGVjdG9yOiAndGwtZHJvcGRvd24tbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9kcm9wZG93bmxpc3QuaHRtbCcsXG4gIHN0eWxlVXJsczogWyAnLi9kcm9wZG93bmxpc3Quc2NzcycgXSxcbiAgYW5pbWF0aW9uczogWyBPdmVybGF5QW5pbWF0aW9uIF1cbn0gKVxuZXhwb3J0IGNsYXNzIFRsRHJvcERvd25MaXN0IGV4dGVuZHMgVmFsdWVBY2Nlc3NvckJhc2U8YW55PiBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoICdkYXRhJyApXG4gIHNldCBkYXRhKCBkYXRhOiBhbnlbXSApIHtcbiAgICBpZiAoIGRhdGEgKSB7XG4gICAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUNvbXBvbmVudCgpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICB9XG5cbiAgQElucHV0KCAna2V5VGV4dCcgKSBrZXlUZXh0ID0gbnVsbDtcblxuICBASW5wdXQoICdpY29uJyApIGljb24gPSBudWxsO1xuXG4gIEBJbnB1dCggJ2xhYmVsJyApIGxhYmVsOiBzdHJpbmc7XG5cbiAgQElucHV0KCAnZGVib3VuY2VUaW1lJyApIGRlYm91bmNlVGltZSA9IDIwMDtcblxuICBASW5wdXQoICdkaXNhYmxlZCcgKSBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBJbnB1dCggJ2xhYmVsUGxhY2VtZW50JyApIGxhYmVsUGxhY2VtZW50ID0gJ2xlZnQnO1xuXG4gIEBJbnB1dCggJ2xhYmVsU2l6ZScgKSBsYWJlbFNpemUgPSAnMTAwcHgnO1xuXG4gIEBJbnB1dCggJ2l0ZW1IZWlnaHQnICkgaXRlbUhlaWdodCA9ICcyM3B4JztcblxuICBASW5wdXQoICdrZXlWYWx1ZScgKSBrZXlWYWx1ZSA9IG51bGw7XG5cbiAgQElucHV0KCAnbWF4SGVpZ2h0JyApIG1heEhlaWdodCA9ICcxNTBweCc7XG5cbiAgQElucHV0KCAnaWRlbnRpZmllcicgKSBpZGVudGlmaWVyID0gbnVsbDtcblxuICBASW5wdXQoICdkZWZhdWx0T3B0aW9uJyApIGRlZmF1bHRPcHRpb24gPSBmYWxzZTtcblxuICBASW5wdXQoICdncm91cEJ5JyApIGdyb3VwQnkgPSBudWxsO1xuXG4gIEBJbnB1dCggJ3dpZHRoJyApIHdpZHRoID0gJzEwMCUnO1xuXG4gIEBJbnB1dCggJ3BsYWNlaG9sZGVyJyApIHBsYWNlaG9sZGVyID0gJ1NlbGVjdCBJdGVtJztcblxuICBASW5wdXQoICdtb2RlbE1vZGUnICkgbW9kZWxNb2RlOiAnc3RyaW5nJyB8ICdvYmplY3QnID0gJ29iamVjdCc7XG5cbiAgQElucHV0KCAnc2VhcmNoT25MaXN0JyApIHNlYXJjaE9uTGlzdCA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoICdzZWxlY3RJdGVtJyApIHNlbGVjdEl0ZW06IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBWaWV3Q2hpbGQoICdpbnB1dCcsIHtzdGF0aWM6IHRydWV9ICApIGlucHV0OiBFbGVtZW50UmVmO1xuXG4gIHB1YmxpYyB0eXBlT2ZEYXRhID0gJ2NvbXBsZXgnO1xuXG4gIHB1YmxpYyBzZWxlY3RlZERlc2NyaXB0aW9uID0gJyc7XG5cbiAgcHVibGljIF9kYXRhO1xuXG4gIHB1YmxpYyBpbmRleE9wdGlvblNlbGVjdGVkTW9kZWw7XG5cbiAgcHVibGljIG9wdGlvblNlbGVjdGVkO1xuXG4gIHB1YmxpYyBpc09wZW4gPSBmYWxzZTtcblxuICBwdWJsaWMgZGF0YXNvdXJjZSA9IFtdO1xuXG4gIHB1YmxpYyBpc0xvYWRpbmcgPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKCBAT3B0aW9uYWwoKSBASW5qZWN0KCBEUk9QRE9XTl9DT05GSUcgKSBkcm9wZG93bkNvbmZpZzogRHJvcGRvd25Db25maWcsXG4gICAgcHJpdmF0ZSBjaGFuZ2VzOiBDaGFuZ2VEZXRlY3RvclJlZiwgQE9wdGlvbmFsKCkgQFNlbGYoKSBwdWJsaWMgbmdDb250cm9sOiBOZ0NvbnRyb2wgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNldENvbnRyb2woKTtcbiAgICB0aGlzLnNldE9wdGlvbnMoIGRyb3Bkb3duQ29uZmlnICk7XG4gIH1cblxuICBnZXQgY29udHJvbCgpIHtcbiAgICByZXR1cm4gdGhpcy5uZ0NvbnRyb2w/LmNvbnRyb2w7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmxpc3Rlbk1vZGVsQ2hhbmdlKCk7XG4gICAgdGhpcy5nZXRNb2RlbFZhbHVlKCk7XG4gIH1cblxuICBzZXRDb250cm9sKCkge1xuICAgIGlmICggdGhpcy5uZ0NvbnRyb2wgKSB7XG4gICAgICB0aGlzLm5nQ29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICB9XG4gIH1cblxuICBvblNlYXJjaCggc2VhcmNoVGV4dFZhbHVlICkge1xuICAgIGNvbnN0IGZpbHRlciA9IFtdO1xuICAgIHRoaXMuZGF0YXNvdXJjZSA9IHRoaXMuZGF0YS5zbGljZSgpO1xuICAgIHRoaXMuZGF0YXNvdXJjZS5maWx0ZXIoICggaXRlbSApID0+IHtcbiAgICAgIGlmICggdGhpcy5nZXRJdGVtVGV4dCggaXRlbSApLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoVGV4dFZhbHVlLnRvTG93ZXJDYXNlKCkpICkge1xuICAgICAgICBmaWx0ZXIucHVzaCggaXRlbSApO1xuICAgICAgfVxuICAgIH0gKTtcbiAgICB0aGlzLmRhdGFzb3VyY2UgPSBmaWx0ZXI7XG4gIH1cblxuICBnZXRJdGVtVGV4dCggaXRlbSApIHtcbiAgICBpZiAoIHRoaXMudHlwZU9mRGF0YSA9PT0gJ3NpbXBsZScgKSB7XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFBhdGguZ2V0KCBpdGVtLCB0aGlzLmtleVRleHQgKTtcbiAgfVxuXG4gIG9uS2V5RG93biggJGV2ZW50ICkge1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0SW5MZXR0ZXIoICRldmVudC5rZXkgKTtcbiAgICBjb25zdCBrZXlFdmVudCA9IHtcbiAgICAgIFtLZXlFdmVudC5TUEFDRV06ICgpID0+IHRoaXMuaGFuZGxlT3Blbkxpc3QoICRldmVudCApLFxuICAgICAgW0tleUV2ZW50LkFSUk9XRE9XTl06ICgpID0+IHRoaXMuc3RvcEV2ZW50KCAkZXZlbnQgKSxcbiAgICAgIFtLZXlFdmVudC5BUlJPV1VQXTogKCkgPT4gdGhpcy5zdG9wRXZlbnQoICRldmVudCApLFxuICAgICAgW0tleUV2ZW50LkVTQ0FQRV06ICgpID0+IHRoaXMuaGFuZGxlRXNjYXBlKCAkZXZlbnQgKVxuICAgIH07XG4gICAgaWYgKCBrZXlFdmVudFsgJGV2ZW50LmNvZGUgXSApIHtcbiAgICAgIGtleUV2ZW50WyAkZXZlbnQuY29kZSBdKCk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlRXNjYXBlKCAkZXZlbnQgKSB7XG4gICAgaWYgKCB0aGlzLmlzT3BlbiApIHtcbiAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gICAgICB0aGlzLnN0b3BFdmVudCggJGV2ZW50ICk7XG4gICAgfVxuICB9XG5cbiAgZ2V0TmF0aXZlSW5wdXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudDtcbiAgfVxuXG5cbiAgb25GaW5kQnlMZXR0ZXIoIHZhbHVlOiBzdHJpbmcgKSB7XG4gICAgdGhpcy5oYW5kbGVTZWxlY3RJbkxldHRlciggdmFsdWUgKTtcbiAgfVxuXG4gIG9uU2VsZWN0T3B0aW9uKCAkZXZlbnQ6IExpc3RJdGVtSW50ZXJmYWNlICkge1xuICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5vcHRpb25TZWxlY3RlZCA9ICRldmVudDtcbiAgICB0aGlzLnNlbGVjdGVkRGVzY3JpcHRpb24gPSB0aGlzLmlzU2ltcGxlRGF0YSgpID8gJGV2ZW50Lm9wdGlvbi5pdGVtIDogb2JqZWN0UGF0aC5nZXQoICRldmVudC5vcHRpb24uaXRlbSwgdGhpcy5rZXlUZXh0ICk7XG4gICAgdGhpcy5zZWxlY3RJdGVtLmVtaXQoICRldmVudC5vcHRpb24uaXRlbSApO1xuICAgIHRoaXMuaGFuZGxlS2V5TW9kZWxWYWx1ZSggJGV2ZW50Lm9wdGlvbi5pdGVtICk7XG4gICAgdGhpcy5zZXRJbnB1dEZvY3VzKCk7XG4gIH1cblxuICBvbkRlZmF1bHRPcHRpb24oKSB7XG4gICAgdGhpcy52YWx1ZSA9ICcnO1xuICAgIHRoaXMuc2VsZWN0ZWREZXNjcmlwdGlvbiA9IHRoaXMucGxhY2Vob2xkZXI7XG4gICAgdGhpcy5vcHRpb25TZWxlY3RlZCA9IG51bGw7XG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgaXNNb2RlbE1vZGVTdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMubW9kZWxNb2RlID09PSAnc3RyaW5nJztcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVPcGVuTGlzdCggJGV2ZW50ICkge1xuICAgIHRoaXMuc3RvcEV2ZW50KCAkZXZlbnQgKTtcbiAgICBpZiAoICF0aGlzLmlzT3BlbiAmJiAhdGhpcy5kaXNhYmxlZCAmJiAhdGhpcy5pc0xvYWRpbmcgKSB7XG4gICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgICB0aGlzLnNldFVwQ29tcG9uZW50KCk7XG4gICAgfVxuICB9XG5cbiAgb25CYWNrZHJvcENsaWNrKCkge1xuICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5jaGFuZ2VzLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXBvbmVudCgpIHtcbiAgICB0aGlzLnNldFVwQ29tcG9uZW50KCk7XG4gICAgdGhpcy52YWxpZGF0ZURhdGEoKTtcbiAgICB0aGlzLmdldE1vZGVsVmFsdWUoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VXBDb21wb25lbnQoKSB7XG4gICAgdGhpcy5kYXRhc291cmNlID0gdGhpcy5kYXRhO1xuICAgIGlmICggdGhpcy5kYXRhLmxlbmd0aCA+IDAgKSB7XG4gICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVEYXRhKCkge1xuICAgIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKCB0aGlzLmRhdGEgKVsgMCBdO1xuICAgIGlmICggdHlwZW9mIHRoaXMuZGF0YVsga2V5IF0gPT09ICdzdHJpbmcnICkge1xuICAgICAgdGhpcy50eXBlT2ZEYXRhID0gJ3NpbXBsZSc7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ2xvc2VEcm9wZG93bigpIHtcbiAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMuc2V0SW5wdXRGb2N1cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRJbnB1dEZvY3VzKCkge1xuICAgIHRoaXMuaW5wdXQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1NpbXBsZURhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMudHlwZU9mRGF0YSA9PT0gJ3NpbXBsZSc7XG4gIH1cblxuICBwcml2YXRlIGxpc3Rlbk1vZGVsQ2hhbmdlKCkge1xuICAgIGlmICggdGhpcy5jb250cm9sICkge1xuICAgICAgdGhpcy5jb250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoICgpID0+IHtcbiAgICAgICAgdGhpcy5nZXRNb2RlbFZhbHVlKCk7XG4gICAgICB9ICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVLZXlNb2RlbFZhbHVlKCBpdGVtVmFsdWUgKSB7XG4gICAgaWYgKCB0aGlzLmlzU2ltcGxlRGF0YSgpICkge1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWUgPSBpdGVtVmFsdWU7XG4gICAgfVxuICAgIGlmICggIXRoaXMua2V5VmFsdWUgKSB7XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZSA9IGl0ZW1WYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmFsdWUgPSBvYmplY3RQYXRoLmdldCggaXRlbVZhbHVlLCB0aGlzLmtleVZhbHVlICk7XG4gIH1cblxuICBwcml2YXRlIGdldE1vZGVsVmFsdWUoKSB7XG4gICAgaWYgKCAhdGhpcy5jb250cm9sICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRhdGFzb3VyY2UuZm9yRWFjaCggKCB2YWx1ZSwgaW5kZXggKSA9PiB7XG4gICAgICBpZiAoIHRoaXMuY29udHJvbC52YWx1ZSApIHtcbiAgICAgICAgaWYgKCB0aGlzLmdldENvbXBhcmUoIHZhbHVlICkgPT09IHRoaXMuZ2V0Q29tcGFyZU1vZGVsKCkgKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZERlc2NyaXB0aW9uID0gdGhpcy5nZXREZXNjcmlwdGlvbiggdmFsdWUgKTtcbiAgICAgICAgICB0aGlzLmluZGV4T3B0aW9uU2VsZWN0ZWRNb2RlbCA9IGluZGV4O1xuICAgICAgICAgIHRoaXMuY2hhbmdlcy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgdGhpcy5oYW5kbGVLZXlNb2RlbFZhbHVlKCB2YWx1ZSApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0T3B0aW9ucyggb3B0aW9uczogRHJvcGRvd25Db25maWcgKSB7XG4gICAgaWYgKCBvcHRpb25zICkge1xuICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICBPYmplY3Qua2V5cyggb3B0aW9ucyApLmZvckVhY2goIGZ1bmN0aW9uICgga2V5ICkge1xuICAgICAgICBzZWxmWyBrZXkgXSA9IG9wdGlvbnNbIGtleSBdO1xuICAgICAgfSApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29tcGFyZU1vZGVsKCkge1xuICAgIGlmICggdGhpcy5pc1NpbXBsZURhdGEoKSApIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRyb2wudmFsdWU7XG4gICAgfVxuICAgIGlmICggIXRoaXMua2V5VmFsdWUgKSB7XG4gICAgICByZXR1cm4gb2JqZWN0UGF0aC5nZXQoIHRoaXMuY29udHJvbC52YWx1ZSwgdGhpcy5pZGVudGlmaWVyICk7XG4gICAgfVxuICAgIGlmICggdGhpcy5pc01vZGVsTW9kZVN0cmluZygpICkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udHJvbC52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFBhdGguZ2V0KCB0aGlzLmNvbnRyb2wudmFsdWUsIHRoaXMua2V5VmFsdWUgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29tcGFyZSggdmFsdWUgKSB7XG4gICAgaWYgKCB0aGlzLmlzU2ltcGxlRGF0YSgpICkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAoICF0aGlzLmtleVZhbHVlICkge1xuICAgICAgcmV0dXJuIG9iamVjdFBhdGguZ2V0KCB2YWx1ZSwgdGhpcy5pZGVudGlmaWVyICk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RQYXRoLmdldCggdmFsdWUsIHRoaXMua2V5VmFsdWUgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGVzY3JpcHRpb24oIHZhbHVlICkge1xuICAgIGlmICggdGhpcy5pc1NpbXBsZURhdGEoKSApIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFBhdGguZ2V0KCB2YWx1ZSwgdGhpcy5rZXlUZXh0ICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVNlbGVjdEluTGV0dGVyKCBrZXlJbnB1dDogc3RyaW5nICkge1xuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5zZWxlY3RCeUZpcnN0KCBrZXlJbnB1dCApO1xuICAgIGlmICggc2VsZWN0ZWQgKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGVzY3JpcHRpb24gPSB0aGlzLmdldERlc2NyaXB0aW9uKCBzZWxlY3RlZC5vcHRpb24gKTtcbiAgICAgIHRoaXMub3B0aW9uU2VsZWN0ZWQgPSB7IG9wdGlvbjogc2VsZWN0ZWQub3B0aW9uLCBpbmRleDogc2VsZWN0ZWQuaW5kZXggfTtcbiAgICAgIHRoaXMuaGFuZGxlS2V5TW9kZWxWYWx1ZSggc2VsZWN0ZWQub3B0aW9uICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdG9wRXZlbnQoICRldmVudCApIHtcbiAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdEJ5Rmlyc3QoIGtleUlucHV0OiBzdHJpbmcgKTogTGlzdEl0ZW1JbnRlcmZhY2Uge1xuICAgIGxldCBzZWxlY3RlZDogTGlzdEl0ZW1JbnRlcmZhY2UgPSBudWxsO1xuICAgIHRoaXMuZGF0YXNvdXJjZS5mb3JFYWNoKCAoIG9wdGlvbjogVGxMaXN0SXRlbSwgaW5kZXg6IG51bWJlciApID0+IHtcbiAgICAgIGlmICggdGhpcy5nZXRGaXJzdExldHRlck9mSXRlbSggb3B0aW9uICkgPT09IHRoaXMuZ2V0S2V5SW5wdXRMb3dlckNhc2UoIGtleUlucHV0ICkgKSB7XG4gICAgICAgIHNlbGVjdGVkID0gPExpc3RJdGVtSW50ZXJmYWNlPnsgb3B0aW9uLCBpbmRleCB9O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSApO1xuICAgIHJldHVybiBzZWxlY3RlZDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0S2V5SW5wdXRMb3dlckNhc2UoIGtleUlucHV0OiBzdHJpbmcgKTogc3RyaW5nIHtcbiAgICByZXR1cm4gU3RyaW5nKCBrZXlJbnB1dCApLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEZpcnN0TGV0dGVyT2ZJdGVtKCBpdGVtICk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFN0cmluZyggb2JqZWN0UGF0aC5nZXQoIGl0ZW0sIHRoaXMua2V5VGV4dCApICkuc3Vic3RyaW5nKCAwLCAxICkudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCB7IGRhdGEgfTogU2ltcGxlQ2hhbmdlcyApIHtcbiAgICBpZiAoIGRhdGEgKSB7XG4gICAgICBpZiAoIWRhdGEuZmlyc3RDaGFuZ2UgJiYgZGF0YS5jdXJyZW50VmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwidWktZHJvcGRvd24tYm94XCIgIFtuZ1N0eWxlXT1cInsnbGluZS1oZWlnaHQnIDogaXRlbUhlaWdodCwgJ3dpZHRoJzogd2lkdGh9XCI+XG5cbiAgPGRpdiBjbGFzcz1cInVpLWxvYWRpbmctaWNvblwiIFtzdHlsZS5oZWlnaHRdPVwiaXRlbUhlaWdodFwiICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgPHRsLWxvYWRlcj48L3RsLWxvYWRlcj5cbiAgPC9kaXY+XG5cbiAgPHRsLWxhYmVsICpuZ0lmPVwibGFiZWxcIlxuICAgICAgICAgICAgW2xhYmVsUGxhY2VtZW50XT1cImxhYmVsUGxhY2VtZW50XCJcbiAgICAgICAgICAgIFtsYWJlbFNpemVdPVwibGFiZWxTaXplXCJcbiAgICAgICAgICAgIFtsYWJlbFRpdGxlXT1cImxhYmVsXCI+XG4gIDwvdGwtbGFiZWw+XG5cbiAgPGRpdiBjbGFzcz1cInVpLWRyb3Bkb3duLXdyYXBwZXJcIj5cbiAgPGlucHV0IGNka092ZXJsYXlPcmlnaW5cbiAgICAgICAgICNpbnB1dFxuICAgICAgICAgcmVhZG9ubHlcbiAgICAgICAgICN0cmlnZ2VyPVwiY2RrT3ZlcmxheU9yaWdpblwiXG4gICAgICAgICBbYXR0ci5kaXNhYmxlZF09XCJkaXNhYmxlZCA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCJcbiAgICAgICAgIChjbGljayk9XCJoYW5kbGVPcGVuTGlzdCgkZXZlbnQpXCJcbiAgICAgICAgIHZhbHVlPVwie3sgc2VsZWN0ZWREZXNjcmlwdGlvbiA/IHNlbGVjdGVkRGVzY3JpcHRpb24gOiBwbGFjZWhvbGRlciB9fVwiXG4gICAgICAgICBbbmdDbGFzc109XCJ7ICduZy1pbnZhbGlkJyA6IGNvbnRyb2w/LmludmFsaWQsICdkaXNhYmxlZCc6IGRpc2FibGVkIH1cIlxuICAgICAgICAgW25nU3R5bGVdPVwieydoZWlnaHQnIDogaXRlbUhlaWdodCwgJ2xpbmUtaGVpZ2h0JyA6IGl0ZW1IZWlnaHR9XCJcbiAgICAgICAgIGNsYXNzPVwidWktZHJvcGRvd25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInVpLWRyb3Bkb3duLWljb25cIlxuICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHRdPVwiaXRlbUhlaWdodFwiXG4gICAgICAgICAgICAgW3N0eWxlLnRyYW5zZm9ybV09XCJpc09wZW4gPyAncm90YXRlKDE4MGRlZyknIDogJ3JvdGF0ZSgwKSdcIlxuICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ2Rpc2FibGVkJzogZGlzYWJsZWQsICduZy1pbnZhbGlkJyA6IGNvbnRyb2w/LmludmFsaWQgfVwiPlxuICAgICAgICAgIDx0bC1pY29uIF