UNPKG

@stratio/egeo

Version:
588 lines 47.1 kB
/** * @fileoverview added by tsickle * Generated from: lib/st-dropdown-menu/st-dropdown-menu.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; /* * © 2017 Stratio Big Data Inc., Sucursal en España. * * This software is licensed under the Apache License, Version 2.0. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the terms of the License for more details. * * SPDX-License-Identifier: Apache-2.0. */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2, ViewChild } from '@angular/core'; import { StPopOffset, StPopPlacement } from '../st-pop/st-pop.model'; import { ARROW_KEY_CODE, StDropDownMenuItem, StDropDownVisualMode } from './st-dropdown-menu.interface'; /** * \@description {Component} [Dropdown Menu] * This directive show a dropdown menu list in element that you attach * * * \@model * * [Menu items] {./st-dropdown-menu.interface.ts#StDropDownMenuItem} * * \@example * * {html} * * ``` * <st-dropdown-menu [items]="list" [active]="show" (change)="onChange(event)"> * <button class="button button-primary" (click)="show = !show">Show menu</button> * </st-dropdown-menu> * ``` */ var StDropdownMenuComponent = /** @class */ (function () { function StDropdownMenuComponent(el, cd, renderer) { this.el = el; this.cd = cd; this.renderer = renderer; /** * \@Input {boolean} [active=false] Show or hide list */ this.active = false; /** * \@Input {StDropDownMenuItem[] | StDropDownMenuGroup[]} [items=\[\]] List of items or groups of them to show in menu */ this.items = []; /* tslint:disable-next-line:max-line-length */ /** * \@Input {StPopPlacement} [placement=StPopPlacement.BOTTOM_START] Possible positions of menu with respect element to attach */ this.placement = StPopPlacement.BOTTOM_START; /** * \@Input {string} [emptyListMessage=''] Message to show in case of empty list */ this.emptyListMessage = ''; /** * \@Input {StDropDownMenuItem | undefined} [selectedItem=undefined] Define selected item without passing as property */ this.selectedItem = undefined; /** * \@Input {StDropDownMenuItem | undefined} [itemsBeforeScroll=undefined] Define selected item without passing as property */ this.itemsBeforeScroll = 8; /** * \@Input {boolean} [moveSelected=true] If true, move selected item to top in menu when open */ this.moveSelected = true; /** * \@Input {boolean} [styleSelected=true] If true, apply class selected to selected item */ this.styleSelected = true; /** * \@Input {boolean} [isLoading=true] If true, show loader at the end of the list */ this.isLoading = false; /** * \@Input {StPopOffset} [offset={x: 0 , y: 0}] For position with offset in x o y axis */ this.offset = { x: 0, y: 0 }; /** * \@Input {boolean} [openToLeft=false] For calculating all positions from the right corner */ this.openToLeft = false; /** * \@Input {StDropdownVisualMode} [visualMode=StDropDownVisualMode.OPTION_LIST] It is needed to specify the styles applied to the list. * By default is displayed as a normal option list */ this.visualMode = StDropDownVisualMode.OPTION_LIST; /** * \@Input {boolean} [keyBoardMove=false] It is needed to activate navigation through options using the keyboard */ this.keyBoardMove = false; /** * \@output {StDropDownMenuItem} [change] Event emitted when user select an item */ this.change = new EventEmitter(); /** * \@output {any} [scrollAtBottom] Event emitted when scroll reach the end of the list */ this.scrollAtBottom = new EventEmitter(); /** * \@output {StDropDownMenuItem} [itemMouseEnter] Event emitted when mouse is over an item */ this.itemMouseEnter = new EventEmitter(); /** * \@output {StDropDownMenuItem} [itemMouseLeave] Event emitted when mouse leaves an item */ this.itemMouseLeave = new EventEmitter(); this.widthMenu = '0px'; this._itemHeight = 42; this._focusedOptionPos = -1; } /** * @return {?} */ StDropdownMenuComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (this.keyBoardMove) { this._focusListenerFn = this.renderer.listen('document', 'keydown', this.arrowKeyListener.bind(this)); } }; Object.defineProperty(StDropdownMenuComponent.prototype, "componentId", { get: /** * @return {?} */ function () { /** @type {?} */ var id = ((/** @type {?} */ (this.el.nativeElement))).getAttribute('id'); return id !== undefined && id !== null ? id : null; }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "menuId", { get: /** * @return {?} */ function () { return this.componentId !== null ? this.componentId + "-menu" : null; }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "isItemGroup", { get: /** * @return {?} */ function () { return this.isDropDownGroup(this.items); }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "menuMaxHeight", { get: /** * @return {?} */ function () { return this.itemsBeforeScroll ? this._itemHeight * this.itemsBeforeScroll + "px" : null; }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "listClasses", { get: /** * @return {?} */ function () { return { 'st-dropdown-menu': true, 'active': this.active, 'menu-list': this.displayAsMenuList() }; }, enumerable: true, configurable: true }); /** * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.getItemId = /** * @param {?} value * @return {?} */ function (value) { return this.componentId !== null && value !== undefined ? this.componentId + "-option-" + this.getItemValueMerged(value) : null; }; /** * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.isDropDownGroup = /** * @param {?} value * @return {?} */ function (value) { return value && value.length > 0 && ((/** @type {?} */ (value[0]))).title !== undefined; }; /** * @return {?} */ StDropdownMenuComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { this.updateWidth(); }; /** * @param {?} changes * @return {?} */ StDropdownMenuComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { var _this = this; if (changes && changes.active && changes.active.currentValue && this.selectedItem && this.moveSelected) { // Only can do this functionality with timeout because we need to wait for angular to load new DOM // with items before move scroll setTimeout((/** * @return {?} */ function () { if (_this.itemListElement) { /** @type {?} */ var parent_1 = _this.itemListElement.nativeElement; /** @type {?} */ var listOfElements = parent_1.getElementsByClassName('selected'); if (listOfElements && listOfElements.length > 0) { /** @type {?} */ var target = ((/** @type {?} */ (listOfElements.item(0)))); parent_1.scrollTop = target.offsetTop - parent_1.offsetTop; } } })); } else { if (changes && changes.active && !changes.active.currentValue) { this._focusedOptionPos = -1; } } }; /** * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.onChange = /** * @param {?} value * @return {?} */ function (value) { this.change.emit(value); }; /** * @return {?} */ StDropdownMenuComponent.prototype.onHandleScroll = /** * @return {?} */ function () { /** @type {?} */ var element = this.itemListElement.nativeElement; if (element.scrollHeight - element.scrollTop === element.clientHeight && !this.isLoading) { this.scrollAtBottom.emit(); } }; /** * @param {?} item * @return {?} */ StDropdownMenuComponent.prototype.onMouseEnter = /** * @param {?} item * @return {?} */ function (item) { this.itemMouseEnter.emit(item); }; /** * @param {?} item * @return {?} */ StDropdownMenuComponent.prototype.onMouseLeave = /** * @param {?} item * @return {?} */ function (item) { this.itemMouseLeave.emit(item); }; /** * @return {?} */ StDropdownMenuComponent.prototype.displayAsMenuList = /** * @return {?} */ function () { return this.visualMode === StDropDownVisualMode.MENU_LIST; }; /** * @return {?} */ StDropdownMenuComponent.prototype.updateWidth = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var button = this.buttonElement.nativeElement; setTimeout((/** * @return {?} */ function () { if (button.children && button.children.length > 0) { _this.widthMenu = button.children[0].getBoundingClientRect().width + 'px'; } else { _this.widthMenu = button.getBoundingClientRect().width + 'px'; } _this.cd.markForCheck(); })); }; /** * @return {?} */ StDropdownMenuComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { if (this._focusListenerFn) { this._focusListenerFn(); } }; /** * @private * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.getItemValueMerged = /** * @private * @param {?} value * @return {?} */ function (value) { return value.toString().replace(/\s+/g, '_'); }; /** * @private * @return {?} */ StDropdownMenuComponent.prototype.getSelectedItemPosition = /** * @private * @return {?} */ function () { var _this = this; if (this.selectedItem && this.items) { /** @type {?} */ var _items_1 = []; if (this.isDropDownGroup(this.items)) { this.items.forEach((/** * @param {?} item * @return {?} */ function (item) { if (((/** @type {?} */ (item))).items) { _items_1.push.apply(_items_1, tslib_1.__spread(((/** @type {?} */ (item))).items)); } else { _items_1.push(((/** @type {?} */ (item)))); } })); } else { _items_1 = this.items; } return _items_1.findIndex((/** * @param {?} item * @return {?} */ function (item) { return item.value === _this.selectedItem.value; })); } else { return -1; } }; /** * @private * @param {?} event * @return {?} */ StDropdownMenuComponent.prototype.arrowKeyListener = /** * @private * @param {?} event * @return {?} */ function (event) { /** @type {?} */ var selectedItemPosition = this.getSelectedItemPosition(); if (selectedItemPosition > -1 && this._focusedOptionPos < 0) { this._focusedOptionPos = selectedItemPosition; } /** @type {?} */ var nextFocus; if (event.key === ARROW_KEY_CODE.ARROW_DOWN || event.key === ARROW_KEY_CODE.ARROW_UP) { event.preventDefault(); /** @type {?} */ var options = this.el.nativeElement.querySelectorAll('.st-dropdown-menu-item'); nextFocus = (event.key === ARROW_KEY_CODE.ARROW_DOWN || this._focusedOptionPos === -1) ? 1 : -1; this._focusedOptionPos = this._focusedOptionPos + nextFocus; if (this._focusedOptionPos < 0) { this._focusedOptionPos = options.length - 1; } else if (this._focusedOptionPos > options.length - 1) { this._focusedOptionPos = 0; } if (options[this._focusedOptionPos]) { options[this._focusedOptionPos].focus(); } } this.cd.markForCheck(); }; StDropdownMenuComponent.decorators = [ { type: Component, args: [{ selector: 'st-dropdown-menu', template: "<!--\n\n \u00A9 2017 Stratio Big Data Inc., Sucursal en Espa\u00F1a.\n\n This software is licensed under the Apache License, Version 2.0.\n This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n See the terms of the License for more details.\n\n SPDX-License-Identifier: Apache-2.0.\n\n-->\n<st-pop [hidden]=\"!active\" [placement]=\"placement\" [offset]=\"offset\" [openToLeft]=\"openToLeft\">\n\n <div pop-button #buttonId>\n <ng-content></ng-content>\n </div>\n\n <div pop-content [style.z-index]=\"9\" class=\"dropdown-content\">\n\n <div *ngIf=\"active\" [ngClass]=\"listClasses\" [style.minWidth]='widthMenu'>\n <ng-content select=[dropdown-header]></ng-content>\n\n <ul *ngIf=\"!isItemGroup && ((items && items.length) || emptyListMessage)\"\n #itemList\n aria-label=\"submenu\"\n [ngClass]=\"{'st-custom-scrollbar': displayAsMenuList()}\"\n [attr.aria-hidden]=\"!active\"\n [style.maxHeight]=\"menuMaxHeight\"\n [attr.id]=\"menuId\"\n (scroll)=\"onHandleScroll()\">\n <st-dropdown-menu-item\n *ngFor=\"let item of items; let i = index\"\n [attr.id]=\"getItemId(item.value)\"\n [index]=\"i\"\n [item]=\"item\"\n [selectedItem]=\"selectedItem\"\n [styleSelected]=\"styleSelected\"\n (change)=\"onChange($event)\"\n (mouseenter)=\"onMouseEnter(item)\"\n (mouseleave)=\"onMouseLeave(item)\">\n </st-dropdown-menu-item>\n <div *ngIf=\"isLoading\" class=\"spinner-container\">\n <st-spinner class=\"spinner\"></st-spinner>\n </div>\n <div *ngIf=\"!items || !items.length\" class=\"without-results st-dropdown-menu-without-results\"\n [style.maxWidth]='widthMenu'>\n {{emptyListMessage}}\n </div>\n </ul>\n\n <div *ngIf=\"isItemGroup\">\n <ul [attr.aria-hidden]=\"!active\" aria-label=\"submenu\" [style.maxHeight]=\"menuMaxHeight\"\n [attr.id]=\"menuId\" #itemList>\n <li class=\"st-dropdown-menu-parent\" *ngFor=\"let group of items\">\n <h3>\n <span>{{ group.title }}</span>\n </h3>\n <ul>\n <st-dropdown-menu-item\n *ngFor=\"let item of group.items || []; let i = index\"\n [attr.id]=\"getItemId(item.value)\"\n [index]=\"i\"\n [item]=\"item\"\n [selectedItem]=\"selectedItem\"\n [styleSelected]=\"styleSelected\"\n (change)=\"onChange($event)\"\n (mouseenter)=\"onMouseEnter(item)\"\n (mouseleave)=\"onMouseLeave(item)\">\n </st-dropdown-menu-item>\n\n <div class=\"without-results st-dropdown-menu-without-results\" [style.maxWidth]='widthMenu'\n *ngIf=\"!group || !group.items || !group.items.length\">\n {{emptyListMessage}}\n </div>\n </ul>\n </li>\n <div *ngIf=\"isLoading\" class=\"spinner-container\">\n <st-spinner class=\"spinner\"></st-spinner>\n </div>\n </ul>\n </div>\n <ng-content select=[dropdown-footer]></ng-content>\n </div>\n </div>\n</st-pop>\n", changeDetection: ChangeDetectionStrategy.OnPush }] } ]; /** @nocollapse */ StDropdownMenuComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: Renderer2 } ]; }; StDropdownMenuComponent.propDecorators = { active: [{ type: Input }], items: [{ type: Input }], placement: [{ type: Input }], emptyListMessage: [{ type: Input }], selectedItem: [{ type: Input }], itemsBeforeScroll: [{ type: Input }], moveSelected: [{ type: Input }], styleSelected: [{ type: Input }], isLoading: [{ type: Input }], offset: [{ type: Input }], openToLeft: [{ type: Input }], visualMode: [{ type: Input }], keyBoardMove: [{ type: Input }], change: [{ type: Output }], scrollAtBottom: [{ type: Output }], itemMouseEnter: [{ type: Output }], itemMouseLeave: [{ type: Output }], buttonElement: [{ type: ViewChild, args: ['buttonId', { static: false },] }], itemListElement: [{ type: ViewChild, args: ['itemList', { static: false },] }], updateWidth: [{ type: HostListener, args: ['window:resize',] }, { type: HostListener, args: ['window:load',] }] }; return StDropdownMenuComponent; }()); export { StDropdownMenuComponent }; if (false) { /** * \@Input {boolean} [active=false] Show or hide list * @type {?} */ StDropdownMenuComponent.prototype.active; /** * \@Input {StDropDownMenuItem[] | StDropDownMenuGroup[]} [items=\[\]] List of items or groups of them to show in menu * @type {?} */ StDropdownMenuComponent.prototype.items; /** * \@Input {StPopPlacement} [placement=StPopPlacement.BOTTOM_START] Possible positions of menu with respect element to attach * @type {?} */ StDropdownMenuComponent.prototype.placement; /** * \@Input {string} [emptyListMessage=''] Message to show in case of empty list * @type {?} */ StDropdownMenuComponent.prototype.emptyListMessage; /** * \@Input {StDropDownMenuItem | undefined} [selectedItem=undefined] Define selected item without passing as property * @type {?} */ StDropdownMenuComponent.prototype.selectedItem; /** * \@Input {StDropDownMenuItem | undefined} [itemsBeforeScroll=undefined] Define selected item without passing as property * @type {?} */ StDropdownMenuComponent.prototype.itemsBeforeScroll; /** * \@Input {boolean} [moveSelected=true] If true, move selected item to top in menu when open * @type {?} */ StDropdownMenuComponent.prototype.moveSelected; /** * \@Input {boolean} [styleSelected=true] If true, apply class selected to selected item * @type {?} */ StDropdownMenuComponent.prototype.styleSelected; /** * \@Input {boolean} [isLoading=true] If true, show loader at the end of the list * @type {?} */ StDropdownMenuComponent.prototype.isLoading; /** * \@Input {StPopOffset} [offset={x: 0 , y: 0}] For position with offset in x o y axis * @type {?} */ StDropdownMenuComponent.prototype.offset; /** * \@Input {boolean} [openToLeft=false] For calculating all positions from the right corner * @type {?} */ StDropdownMenuComponent.prototype.openToLeft; /** * \@Input {StDropdownVisualMode} [visualMode=StDropDownVisualMode.OPTION_LIST] It is needed to specify the styles applied to the list. * By default is displayed as a normal option list * @type {?} */ StDropdownMenuComponent.prototype.visualMode; /** * \@Input {boolean} [keyBoardMove=false] It is needed to activate navigation through options using the keyboard * @type {?} */ StDropdownMenuComponent.prototype.keyBoardMove; /** * \@output {StDropDownMenuItem} [change] Event emitted when user select an item * @type {?} */ StDropdownMenuComponent.prototype.change; /** * \@output {any} [scrollAtBottom] Event emitted when scroll reach the end of the list * @type {?} */ StDropdownMenuComponent.prototype.scrollAtBottom; /** * \@output {StDropDownMenuItem} [itemMouseEnter] Event emitted when mouse is over an item * @type {?} */ StDropdownMenuComponent.prototype.itemMouseEnter; /** * \@output {StDropDownMenuItem} [itemMouseLeave] Event emitted when mouse leaves an item * @type {?} */ StDropdownMenuComponent.prototype.itemMouseLeave; /** @type {?} */ StDropdownMenuComponent.prototype.buttonElement; /** @type {?} */ StDropdownMenuComponent.prototype.itemListElement; /** @type {?} */ StDropdownMenuComponent.prototype.widthMenu; /** * @type {?} * @private */ StDropdownMenuComponent.prototype._itemHeight; /** * @type {?} * @private */ StDropdownMenuComponent.prototype._focusedOptionPos; /** * @type {?} * @private */ StDropdownMenuComponent.prototype._focusListenerFn; /** * @type {?} * @private */ StDropdownMenuComponent.prototype.el; /** * @type {?} * @private */ StDropdownMenuComponent.prototype.cd; /** * @type {?} * @private */ StDropdownMenuComponent.prototype.renderer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3QtZHJvcGRvd24tbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3RyYXRpby9lZ2VvLyIsInNvdXJjZXMiOlsibGliL3N0LWRyb3Bkb3duLW1lbnUvc3QtZHJvcGRvd24tbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQVVBLE9BQU8sRUFFSix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxFQUNOLFNBQVMsRUFFVCxTQUFTLEVBQ1gsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsY0FBYyxFQUF1QixrQkFBa0IsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFCN0g7SUF5REcsaUNBQW9CLEVBQWMsRUFBVSxFQUFxQixFQUFVLFFBQW1CO1FBQTFFLE9BQUUsR0FBRixFQUFFLENBQVk7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUFVLGFBQVEsR0FBUixRQUFRLENBQVc7Ozs7UUFqRHJGLFdBQU0sR0FBWSxLQUFLLENBQUM7Ozs7UUFFeEIsVUFBSyxHQUFpRCxFQUFFLENBQUM7Ozs7O1FBR3pELGNBQVMsR0FBbUIsY0FBYyxDQUFDLFlBQVksQ0FBQzs7OztRQUV4RCxxQkFBZ0IsR0FBVyxFQUFFLENBQUM7Ozs7UUFFOUIsaUJBQVksR0FBdUIsU0FBUyxDQUFDOzs7O1FBRTdDLHNCQUFpQixHQUFXLENBQUMsQ0FBQzs7OztRQUU5QixpQkFBWSxHQUFZLElBQUksQ0FBQzs7OztRQUU3QixrQkFBYSxHQUFZLElBQUksQ0FBQzs7OztRQUU5QixjQUFTLEdBQVksS0FBSyxDQUFDOzs7O1FBRTNCLFdBQU0sR0FBZ0IsRUFBRSxD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Ozs7OztJQUV6QixxQ0FBc0I7Ozs7O0lBQUUscUNBQTZCOzs7OztJQUFFLDJDQUEyQiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiDCqSAyMDE3IFN0cmF0aW8gQmlnIERhdGEgSW5jLiwgU3VjdXJzYWwgZW4gRXNwYcOxYS5cbiAqXG4gKiBUaGlzIHNvZnR3YXJlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZO1xuICogd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS5cbiAqIFNlZSB0aGUgdGVybXMgb2YgdGhlIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMC5cbiAqL1xuaW1wb3J0IHtcbiAgIEFmdGVyVmlld0luaXQsXG4gICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgQ29tcG9uZW50LFxuICAgRWxlbWVudFJlZixcbiAgIEV2ZW50RW1pdHRlcixcbiAgIEhvc3RMaXN0ZW5lcixcbiAgIElucHV0LFxuICAgT25DaGFuZ2VzLFxuICAgT25EZXN0cm95LFxuICAgT25Jbml0LFxuICAgT3V0cHV0LFxuICAgUmVuZGVyZXIyLFxuICAgU2ltcGxlQ2hhbmdlcyxcbiAgIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgU3RQb3BPZmZzZXQsIFN0UG9wUGxhY2VtZW50IH0gZnJvbSAnLi4vc3QtcG9wL3N0LXBvcC5tb2RlbCc7XG5pbXBvcnQgeyBBUlJPV19LRVlfQ09ERSwgU3REcm9wRG93bk1lbnVHcm91cCwgU3REcm9wRG93bk1lbnVJdGVtLCBTdERyb3BEb3duVmlzdWFsTW9kZSB9IGZyb20gJy4vc3QtZHJvcGRvd24tbWVudS5pbnRlcmZhY2UnO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiB7Q29tcG9uZW50fSBbRHJvcGRvd24gTWVudV1cbiAqIFRoaXMgZGlyZWN0aXZlIHNob3cgYSBkcm9wZG93biBtZW51IGxpc3QgaW4gZWxlbWVudCB0aGF0IHlvdSBhdHRhY2hcbiAqXG4gKlxuICogQG1vZGVsXG4gKlxuICogICBbTWVudSBpdGVtc10gey4vc3QtZHJvcGRvd24tbWVudS5pbnRlcmZhY2UudHMjU3REcm9wRG93bk1lbnVJdGVtfVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICoge2h0bWx9XG4gKlxuICogYGBgXG4gKiA8c3QtZHJvcGRvd24tbWVudSBbaXRlbXNdPVwibGlzdFwiIFthY3RpdmVdPVwic2hvd1wiIChjaGFuZ2UpPVwib25DaGFuZ2UoZXZlbnQpXCI+XG4gKiAgICA8YnV0dG9uIGNsYXNzPVwiYnV0dG9uIGJ1dHRvbi1wcmltYXJ5XCIgKGNsaWNrKT1cInNob3cgPSAhc2hvd1wiPlNob3cgbWVudTwvYnV0dG9uPlxuICogPC9zdC1kcm9wZG93bi1tZW51PlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgc2VsZWN0b3I6ICdzdC1kcm9wZG93bi1tZW51JyxcbiAgIHRlbXBsYXRlVXJsOiAnLi9zdC1kcm9wZG93bi1tZW51LmNvbXBvbmVudC5odG1sJyxcbiAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFN0RHJvcGRvd25NZW51Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFthY3RpdmU9ZmFsc2VdIFNob3cgb3IgaGlkZSBsaXN0ICovXG4gICBASW5wdXQoKSBhY3RpdmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgIC8qKiBASW5wdXQge1N0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdfSBbaXRlbXM9XFxbXFxdXSBMaXN0IG9mIGl0ZW1zIG9yIGdyb3VwcyBvZiB0aGVtIHRvIHNob3cgaW4gbWVudSAqL1xuICAgQElucHV0KCkgaXRlbXM6IFN0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdID0gW107XG4gICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoICovXG4gICAvKiogQElucHV0IHtTdFBvcFBsYWNlbWVudH0gW3BsYWNlbWVudD1TdFBvcFBsYWNlbWVudC5CT1RUT01fU1RBUlRdIFBvc3NpYmxlIHBvc2l0aW9ucyBvZiBtZW51IHdpdGggcmVzcGVjdCBlbGVtZW50IHRvIGF0dGFjaCAqL1xuICAgQElucHV0KCkgcGxhY2VtZW50OiBTdFBvcFBsYWNlbWVudCA9IFN0UG9wUGxhY2VtZW50LkJPVFRPTV9TVEFSVDtcbiAgIC8qKiBASW5wdXQge3N0cmluZ30gW2VtcHR5TGlzdE1lc3NhZ2U9JyddIE1lc3NhZ2UgdG8gc2hvdyBpbiBjYXNlIG9mIGVtcHR5IGxpc3QgKi9cbiAgIEBJbnB1dCgpIGVtcHR5TGlzdE1lc3NhZ2U6IHN0cmluZyA9ICcnO1xuICAgLyoqIEBJbnB1dCB7U3REcm9wRG93bk1lbnVJdGVtIHwgdW5kZWZpbmVkfSBbc2VsZWN0ZWRJdGVtPXVuZGVmaW5lZF0gRGVmaW5lIHNlbGVjdGVkIGl0ZW0gd2l0aG91dCBwYXNzaW5nIGFzIHByb3BlcnR5ICovXG4gICBASW5wdXQoKSBzZWxlY3RlZEl0ZW06IFN0RHJvcERvd25NZW51SXRlbSA9IHVuZGVmaW5lZDtcbiAgIC8qKiBASW5wdXQge1N0RHJvcERvd25NZW51SXRlbSB8IHVuZGVmaW5lZH0gW2l0ZW1zQmVmb3JlU2Nyb2xsPXVuZGVmaW5lZF0gRGVmaW5lIHNlbGVjdGVkIGl0ZW0gd2l0aG91dCBwYXNzaW5nIGFzIHByb3BlcnR5ICovXG4gICBASW5wdXQoKSBpdGVtc0JlZm9yZVNjcm9sbDogbnVtYmVyID0gODtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFttb3ZlU2VsZWN0ZWQ9dHJ1ZV0gSWYgdHJ1ZSwgbW92ZSBzZWxlY3RlZCBpdGVtIHRvIHRvcCBpbiBtZW51IHdoZW4gb3BlbiAqL1xuICAgQElucHV0KCkgbW92ZVNlbGVjdGVkOiBib29sZWFuID0gdHJ1ZTtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFtzdHlsZVNlbGVjdGVkPXRydWVdIElmIHRydWUsIGFwcGx5IGNsYXNzIHNlbGVjdGVkIHRvIHNlbGVjdGVkIGl0ZW0gKi9cbiAgIEBJbnB1dCgpIHN0eWxlU2VsZWN0ZWQ6IGJvb2xlYW4gPSB0cnVlO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW2lzTG9hZGluZz10cnVlXSBJZiB0cnVlLCBzaG93IGxvYWRlciBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0ICovXG4gICBASW5wdXQoKSBpc0xvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgIC8qKiBASW5wdXQge1N0UG9wT2Zmc2V0fSBbb2Zmc2V0PXt4OiAwICwgeTogMH1dIEZvciBwb3NpdGlvbiB3aXRoIG9mZnNldCBpbiB4IG8geSBheGlzICovXG4gICBASW5wdXQoKSBvZmZzZXQ6IFN0UG9wT2Zmc2V0ID0geyB4OiAwLCB5OiAwIH07XG4gICAvKiogQElucHV0IHtib29sZWFufSBbb3BlblRvTGVmdD1mYWxzZV0gRm9yIGNhbGN1bGF0aW5nIGFsbCBwb3NpdGlvbnMgZnJvbSB0aGUgcmlnaHQgY29ybmVyICovXG4gICBASW5wdXQoKSBvcGVuVG9MZWZ0OiBib29sZWFuID0gZmFsc2U7XG4gICAvKiogQElucHV0IHtTdERyb3Bkb3duVmlzdWFsTW9kZX0gW3Zpc3VhbE1vZGU9U3REcm9wRG93blZpc3VhbE1vZGUuT1BUSU9OX0xJU1RdIEl0IGlzIG5lZWRlZCB0byBzcGVjaWZ5IHRoZSBzdHlsZXMgYXBwbGllZCB0byB0aGUgbGlzdC5cbiAgICAqICBCeSBkZWZhdWx0IGlzIGRpc3BsYXllZCBhcyBhIG5vcm1hbCBvcHRpb24gbGlzdFxuICAgICovXG4gICBASW5wdXQoKSB2aXN1YWxNb2RlOiBTdERyb3BEb3duVmlzdWFsTW9kZSA9IFN0RHJvcERvd25WaXN1YWxNb2RlLk9QVElPTl9MSVNUO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW2tleUJvYXJkTW92ZT1mYWxzZV0gSXQgaXMgbmVlZGVkIHRvIGFjdGl2YXRlIG5hdmlnYXRpb24gdGhyb3VnaCBvcHRpb25zIHVzaW5nIHRoZSBrZXlib2FyZFxuICAgICovXG4gICBASW5wdXQoKSBrZXlCb2FyZE1vdmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgLyoqIEBvdXRwdXQge1N0RHJvcERvd25NZW51SXRlbX0gW2NoYW5nZV0gRXZlbnQgZW1pdHRlZCB3aGVuIHVzZXIgc2VsZWN0IGFuIGl0ZW0gKi9cbiAgIEBPdXRwdXQoKSBjaGFuZ2U6IEV2ZW50RW1pdHRlcjxTdERyb3BEb3duTWVudUl0ZW0+ID0gbmV3IEV2ZW50RW1pdHRlcjxTdERyb3BEb3duTWVudUl0ZW0+KCk7XG5cbiAgIC8qKiBAb3V0cHV0IHthbnl9IFtzY3JvbGxBdEJvdHRvbV0gRXZlbnQgZW1pdHRlZCB3aGVuIHNjcm9sbCByZWFjaCB0aGUgZW5kIG9mIHRoZSBsaXN0ICovXG4gICBAT3V0cHV0KCkgc2Nyb2xsQXRCb3R0b206IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICAvKiogQG91dHB1dCB7U3REcm9wRG93bk1lbnVJdGVtfSBbaXRlbU1vdXNlRW50ZXJdIEV2ZW50IGVtaXR0ZWQgd2hlbiBtb3VzZSBpcyBvdmVyIGFuIGl0ZW0gKi9cbiAgIEBPdXRwdXQoKSBpdGVtTW91c2VFbnRlcjogRXZlbnRFbWl0dGVyPFN0RHJvcERvd25NZW51SXRlbT4gPSBuZXcgRXZlbnRFbWl0dGVyPFN0RHJvcERvd25NZW51SXRlbT4oKTtcbiAgIC8qKiBAb3V0cHV0IHtTdERyb3BEb3duTWVudUl0ZW19IFtpdGVtTW91c2VMZWF2ZV0gRXZlbnQgZW1pdHRlZCB3aGVuIG1vdXNlIGxlYXZlcyBhbiBpdGVtICovXG4gICBAT3V0cHV0KCkgaXRlbU1vdXNlTGVhdmU6IEV2ZW50RW1pdHRlcjxTdERyb3BEb3duTWVudUl0ZW0+ID0gbmV3IEV2ZW50RW1pdHRlcjxTdERyb3BEb3duTWVudUl0ZW0+KCk7XG5cbiAgIEBWaWV3Q2hpbGQoJ2J1dHRvbklkJywgeyBzdGF0aWM6IGZhbHNlIH0pIGJ1dHRvbkVsZW1lbnQ6IEVsZW1lbnRSZWY7XG4gICBAVmlld0NoaWxkKCdpdGVtTGlzdCcsIHsgc3RhdGljOiBmYWxzZSB9KSBpdGVtTGlzdEVsZW1lbnQ6IEVsZW1lbnRSZWY7XG5cbiAgIHdpZHRoTWVudTogc3RyaW5nID0gJzBweCc7XG5cbiAgIHByaXZhdGUgX2l0ZW1IZWlnaHQ6IG51bWJlciA9IDQyO1xuICAgcHJpdmF0ZSBfZm9jdXNlZE9wdGlvblBvczogbnVtYmVyID0gLTE7XG4gICBwcml2YXRlIF9mb2N1c0xpc3RlbmVyRm46ICgpID0+IHZvaWQ7XG5cbiAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHtcbiAgIH1cblxuICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5rZXlCb2FyZE1vdmUpIHtcbiAgICAgICAgIHRoaXMuX2ZvY3VzTGlzdGVuZXJGbiA9IHRoaXMucmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsICdrZXlkb3duJywgdGhpcy5hcnJvd0tleUxpc3RlbmVyLmJpbmQodGhpcykpO1xuICAgICAgfVxuICAgfVxuXG4gICBnZXQgY29tcG9uZW50SWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICBjb25zdCBpZCA9ICh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpLmdldEF0dHJpYnV0ZSgnaWQnKTtcbiAgICAgIHJldHVybiBpZCAhPT0gdW5kZWZpbmVkICYmIGlkICE9PSBudWxsID8gaWQgOiBudWxsO1xuICAgfVxuXG4gICBnZXQgbWVudUlkKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50SWQgIT09IG51bGwgPyBgJHt0aGlzLmNvbXBvbmVudElkfS1tZW51YCA6IG51bGw7XG4gICB9XG5cbiAgIGdldCBpc0l0ZW1Hcm91cCgpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLmlzRHJvcERvd25Hcm91cCh0aGlzLml0ZW1zKTtcbiAgIH1cblxuICAgZ2V0IG1lbnVNYXhIZWlnaHQoKTogc3RyaW5nIHtcbiAgICAgIHJldHVybiB0aGlzLml0ZW1zQmVmb3JlU2Nyb2xsID8gYCR7dGhpcy5faXRlbUhlaWdodCAqIHRoaXMuaXRlbXNCZWZvcmVTY3JvbGx9cHhgIDogbnVsbDtcbiAgIH1cblxuICAgZ2V0IGxpc3RDbGFzc2VzKCk6IGFueSB7XG4gICAgICByZXR1cm4geyAnc3QtZHJvcGRvd24tbWVudSc6IHRydWUsICdhY3RpdmUnOiB0aGlzLmFjdGl2ZSwgJ21lbnUtbGlzdCc6IHRoaXMuZGlzcGxheUFzTWVudUxpc3QoKSB9O1xuICAgfVxuXG4gICBnZXRJdGVtSWQodmFsdWU6IGFueSB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50SWQgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCA/IGAke3RoaXMuY29tcG9uZW50SWR9LW9wdGlvbi0ke3RoaXMuZ2V0SXRlbVZhbHVlTWVyZ2VkKHZhbHVlKX1gIDogbnVsbDtcbiAgIH1cblxuICAgaXNEcm9wRG93bkdyb3VwKHZhbHVlOiBTdERyb3BEb3duTWVudUl0ZW1bXSB8IFN0RHJvcERvd25NZW51R3JvdXBbXSk6IHZhbHVlIGlzIFN0RHJvcERvd25NZW51R3JvdXBbXSB7XG4gICAgICByZXR1cm4gdmFsdWUgJiYgdmFsdWUubGVuZ3RoID4gMCAmJiAoPFN0RHJvcERvd25NZW51R3JvdXA+dmFsdWVbMF0pLnRpdGxlICE9PSB1bmRlZmluZWQ7XG4gICB9XG5cbiAgIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgIHRoaXMudXBkYXRlV2lkdGgoKTtcbiAgIH1cblxuICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgaWYgKGNoYW5nZXMgJiYgY2hhbmdlcy5hY3RpdmUgJiYgY2hhbmdlcy5hY3RpdmUuY3VycmVudFZhbHVlICYmIHRoaXMuc2VsZWN0ZWRJdGVtICYmIHRoaXMubW92ZVNlbGVjdGVkKSB7XG4gICAgICAgICAvLyBPbmx5IGNhbiBkbyB0aGlzIGZ1bmN0aW9uYWxpdHkgd2l0aCB0aW1lb3V0IGJlY2F1c2Ugd2UgbmVlZCB0byB3YWl0IGZvciBhbmd1bGFyIHRvIGxvYWQgbmV3IERPTVxuICAgICAgICAgLy8gd2l0aCBpdGVtcyBiZWZvcmUgbW92ZSBzY3JvbGxcbiAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXRlbUxpc3RFbGVtZW50KSB7XG4gICAgICAgICAgICAgICBjb25zdCBwYXJlbnQ6IEhUTUxFbGVtZW50ID0gdGhpcy5pdGVtTGlzdEVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgICAgIGNvbnN0IGxpc3RPZkVsZW1lbnRzOiBhbnkgPSBwYXJlbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgICAgIGlmIChsaXN0T2ZFbGVtZW50cyAmJiBsaXN0T2ZFbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQ6IEhUTUxFbGVtZW50ID0gKGxpc3RPZkVsZW1lbnRzLml0ZW0oMCkgYXMgSFRNTEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgcGFyZW50LnNjcm9sbFRvcCA9IHRhcmdldC5vZmZzZXRUb3AgLSBwYXJlbnQub2Zmc2V0VG9wO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgaWYgKGNoYW5nZXMgJiYgY2hhbmdlcy5hY3RpdmUgJiYgIWNoYW5nZXMuYWN0aXZlLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA9IC0xO1xuICAgICAgICAgfVxuICAgICAgfVxuICAgfVxuXG4gICBvbkNoYW5nZSh2YWx1ZTogU3REcm9wRG93bk1lbnVJdGVtKTogdm9pZCB7XG4gICAgICB0aGlzLmNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgIH1cblxuICAgb25IYW5kbGVTY3JvbGwoKTogdm9pZCB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5pdGVtTGlzdEVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICAgIGlmIChlbGVtZW50LnNjcm9sbEhlaWdodCAtIGVsZW1lbnQuc2Nyb2xsVG9wID09PSBlbGVtZW50LmNsaWVudEhlaWdodCAmJiAhdGhpcy5pc0xvYWRpbmcpIHtcbiAgICAgICAgIHRoaXMuc2Nyb2xsQXRCb3R0b20uZW1pdCgpO1xuICAgICAgfVxuICAgfVxuXG4gICBvbk1vdXNlRW50ZXIoaXRlbTogU3REcm9wRG93bk1lbnVJdGVtKTogdm9pZCB7XG4gICAgICB0aGlzLml0ZW1Nb3VzZUVudGVyLmVtaXQoaXRlbSk7XG4gICB9XG5cbiAgIG9uTW91c2VMZWF2ZShpdGVtOiBTdERyb3BEb3duTWVudUl0ZW0pOiB2b2lkIHtcbiAgICAgIHRoaXMuaXRlbU1vdXNlTGVhdmUuZW1pdChpdGVtKTtcbiAgIH1cblxuICAgZGlzcGxheUFzTWVudUxpc3QoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy52aXN1YWxNb2RlID09PSBTdERyb3BEb3duVmlzdWFsTW9kZS5NRU5VX0xJU1Q7XG4gICB9XG5cbiAgIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICAgQEhvc3RMaXN0ZW5lcignd2luZG93OmxvYWQnKVxuICAgdXBkYXRlV2lkdGgoKTogdm9pZCB7XG4gICAgICBjb25zdCBidXR0b246IEhUTUxFbGVtZW50ID0gdGhpcy5idXR0b25FbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgIGlmIChidXR0b24uY2hpbGRyZW4gJiYgYnV0dG9uLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGhNZW51ID0gYnV0dG9uLmNoaWxkcmVuWzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoICsgJ3B4JztcbiAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndpZHRoTWVudSA9IGJ1dHRvbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCArICdweCc7XG4gICAgICAgICB9XG4gICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgIH1cblxuICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5fZm9jdXNMaXN0ZW5lckZuKSB7XG4gICAgICAgICB0aGlzLl9mb2N1c0xpc3RlbmVyRm4oKTtcbiAgICAgIH1cbiAgIH1cblxuXG4gICBwcml2YXRlIGdldEl0ZW1WYWx1ZU1lcmdlZCh2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpLnJlcGxhY2UoL1xccysvZywgJ18nKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBnZXRTZWxlY3RlZEl0ZW1Qb3NpdGlvbigpOiBudW1iZXIge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJdGVtICYmIHRoaXMuaXRlbXMpIHtcbiAgICAgICAgIGxldCBfaXRlbXM6IFN0RHJvcERvd25NZW51SXRlbVtdID0gW107XG4gICAgICAgICBpZiAodGhpcy5pc0Ryb3BEb3duR3JvdXAodGhpcy5pdGVtcykpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbXMuZm9yRWFjaCgoaXRlbTogU3REcm9wRG93bk1lbnVJdGVtIHwgU3REcm9wRG93bk1lbnVHcm91cCkgPT4ge1xuICAgICAgICAgICAgICAgaWYgKCg8U3REcm9wRG93bk1lbnVHcm91cD4gaXRlbSkuaXRlbXMpIHtcbiAgICAgICAgICAgICAgICAgIF9pdGVtcy5wdXNoKC4uLig8U3REcm9wRG93bk1lbnVHcm91cD4gaXRlbSkuaXRlbXMpO1xuICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIF9pdGVtcy5wdXNoKCg8U3REcm9wRG93bk1lbnVJdGVtPiBpdGVtKSk7XG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBfaXRlbXMgPSB0aGlzLml0ZW1zO1xuICAgICAgICAgfVxuICAgICAgICAgcmV0dXJuIF9pdGVtcy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtLnZhbHVlID09PSB0aGlzLnNlbGVjdGVkSXRlbS52YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgfVxuXG4gICBwcml2YXRlIGFycm93S2V5TGlzdGVuZXIoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkSXRlbVBvc2l0aW9uID0gdGhpcy5nZXRTZWxlY3RlZEl0ZW1Qb3NpdGlvbigpO1xuICAgICAgaWYgKHNlbGVjdGVkSXRlbVBvc2l0aW9uID4gLTEgJiYgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA8IDApIHtcbiAgICAgICAgIHRoaXMuX2ZvY3VzZWRPcHRpb25Qb3MgPSBzZWxlY3RlZEl0ZW1Qb3NpdGlvbjtcbiAgICAgIH1cbiAgICAgIGxldCBuZXh0Rm9jdXM6IG51bWJlcjtcbiAgICAgIGlmIChldmVudC5rZXkgPT09IEFSUk9XX0tFWV9DT0RFLkFSUk9XX0RPV04gfHwgZXZlbnQua2V5ID09PSBBUlJPV19LRVlfQ09ERS5BUlJPV19VUCkge1xuICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgY29uc3Qgb3B0aW9uczogSFRNTExJRWxlbWVudFtdID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdC1kcm9wZG93bi1tZW51LWl0ZW0nKTtcbiAgICAgICAgIG5leHRGb2N1cyA9IChldmVudC5rZXkgPT09IEFSUk9XX0tFWV9DT0RFLkFSUk9XX0RPV04gfHwgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA9PT0gLTEpID8gMSA6IC0xO1xuICAgICAgICAgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA9IHRoaXMuX2ZvY3VzZWRPcHRpb25Qb3MgKyBuZXh0Rm9jdXM7XG4gICAgICAgICBpZiAodGhpcy5fZm9jdXNlZE9wdGlvblBvcyA8IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvY3VzZWRPcHRpb25Qb3MgPSBvcHRpb25zLmxlbmd0aCAtIDE7XG4gICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2ZvY3VzZWRPcHRpb25Qb3MgPiBvcHRpb25zLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvY3VzZWRPcHRpb25Qb3MgPSAwO1xuICAgICAgICAgfVxuICAgICAgICAgaWYgKG9wdGlvbnNbdGhpcy5fZm9jdXNlZE9wdGlvblBvc10pIHtcbiAgICAgICAgICAgIG9wdGlvbnNbdGhpcy5fZm9jdXNlZE9wdGlvblBvc10uZm9jdXMoKTtcbiAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICB9XG59XG4iXX0=