UNPKG

com.phloxui

Version:

PhloxUI Ng2+ Framework

662 lines (661 loc) 57 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { EventEmitter } from '@angular/core'; import { AbstractSelectOneItem } from './AbstractSelectOneItem'; import { Option } from '../../../decorator/Option.decorator'; import { BEFORE_SHOW_EVENT, SHOW_EVENT, BEFORE_HIDE_EVENT, HIDE_EVENT, BEFORE_CLICK_EVENT, CLICK_EVENT } from '../../../share/CustomEventType'; import { EventUtils } from '../../../share/utils/EventUtils'; const /** @type {?} */ LEFT = "left"; const /** @type {?} */ RIGHT = "right"; const /** @type {?} */ CENTER = "center"; const /** @type {?} */ AUTO_HEIGHT_MIN_ITEMS = 5; const /** @type {?} */ POPUP_DISPLAY_DELAY = 10; /** * @abstract */ export class AbstractSimpleDropdown extends AbstractSelectOneItem { /** * @param {?} needFocusService * @param {?} elementRef * @param {?} phloxAppInfoService */ constructor(needFocusService, elementRef, phloxAppInfoService) { super(elementRef, needFocusService); this.beforeClickEvent = new EventEmitter(); this.clickEvent = new EventEmitter(); this.beforeShowEvent = new EventEmitter(); this.showEvent = new EventEmitter(); this.beforeHideEvent = new EventEmitter(); this.hideEvent = new EventEmitter(); this._isItemClick = false; this.needFocusService = needFocusService; phloxAppInfoService.getAppInfo().then((info) => { this.phloxAppInfo = info; }); } /** * @param {?} align * @return {?} */ set align(align) { if (align !== null && typeof align === 'string') { align = align.toLowerCase(); } if (align === LEFT || align === RIGHT || align === CENTER) { this._align = align; } else { this._align = null; } } /** * @return {?} */ get align() { if (this._align === null || typeof this._align === 'undefined') { return LEFT; } return this._align; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { // fix bug when set selected before item is not loaded if (changes['items'] !== null && typeof changes['items'] !== 'undefined') { let /** @type {?} */ oldType = changes['items'].previousValue; let /** @type {?} */ newType = changes['items'].currentValue; let /** @type {?} */ oldSize = (oldType !== null && typeof oldType !== 'undefined' && Array.isArray(oldType)) ? oldType.length : 0; let /** @type {?} */ newSize = (newType !== null && typeof newType !== 'undefined' && Array.isArray(newType)) ? newType.length : 0; if (oldSize !== newSize) { if (this.dataParent !== null && this.dataParent !== undefined) { // fix bug setData but still has a bug this.comp.setData() in ngOnInit setTimeout(() => { this.loadedItems(); }, 1); } else { this.loadedItems(); } } } } /** * @return {?} */ getSelectItemHeight() { let /** @type {?} */ selector = this.getDropdownPopupSelector(); return $(this.elementRef.nativeElement).find(selector + ' > :eq(0)').outerHeight(); } /** * @return {?} */ scrollToSelectedIndex() { return new Promise((resolve, reject) => { let /** @type {?} */ selectedIndex = this.getSelectedIndex(); if (selectedIndex === null || selectedIndex === undefined || selectedIndex < 0) { selectedIndex = 0; } let /** @type {?} */ selector = this.getDropdownPopupSelector(); let /** @type {?} */ ele = $(this.elementRef.nativeElement).find(selector); // Get DOM element of selected item. let /** @type {?} */ selectedEle = $((ele.children().length > selectedIndex) ? ele.children()[selectedIndex] : ele.children()[ele.children().length - 1]); // Scroll to selected item top relative to its parent. let /** @type {?} */ h = selectedEle.position().top + ele.scrollTop(); ele.stop().animate({ scrollTop: h }, 1, 'swing', () => { ele.scrollTop(h); resolve(); }); }); } /** * @param {?=} $event * @param {?=} fireEvent * @return {?} */ doShow($event, fireEvent) { if (fireEvent === null || fireEvent === undefined) { fireEvent = true; } EventUtils.handleBrowserEvent(this, 'beforeShowEvent', $event, fireEvent, ($event) => { // doEvent this.show = true; return this.resizeDropdownPopup().then(() => { return this.scrollToSelectedIndex(); }).then(() => { if (this.needFocusService) { this.needFocusService.setFocusingComponent(this, $event); } }).catch(() => { if (this.needFocusService) { this.needFocusService.setFocusingComponent(this, $event); } }); }, ($event) => { // emitBeforeEvent this.emitBeforeShowEvent($event); }, ($event, result) => { // emitAfterEvent this.emitShowEvent($event); }, ($event) => { // doPrevented }); } /** * @param {?=} $event * @param {?=} fireEvent * @return {?} */ doHide($event, fireEvent) { if (fireEvent === null || fireEvent === undefined) { fireEvent = true; } EventUtils.handleBrowserEvent(this, 'beforeHideEvent', $event, fireEvent, ($event) => { // doEvent this.show = false; }, ($event) => { // emitBeforeEvent this.emitBeforeHideEvent($event); }, ($event, result) => { // emitAfterEvent this.emitHideEvent($event); }, ($event) => { // doPrevented }); } /** * @return {?} */ resizeDropdownPopup() { return new Promise((resolve, reject) => { // Delay to let DOM update first to be able to get its offset().top and its size. setTimeout(() => { let /** @type {?} */ popup = $(this.elementRef.nativeElement).find(this.getDropdownPopupSelector()); if (this.dropdownHeight !== null && this.dropdownHeight !== undefined && this.dropdownHeight !== '') { // If dropdown height is explicitly defined, do nothing & reset element's css max-height. popup.css({ "max-height": undefined }); resolve(); return; } let /** @type {?} */ popupTop = popup.offset().top; if (!popupTop) { popupTop = 0; } let /** @type {?} */ wndTop = $(window).scrollTop(); if (!wndTop) { wndTop = 0; } let /** @type {?} */ screenTop = popupTop - wndTop; let /** @type {?} */ autoHeight = $(window).height() - screenTop; if (!autoHeight) { autoHeight = 0; } let /** @type {?} */ itemHeight = this.getSelectItemHeight(); let /** @type {?} */ minAutoHeight = AUTO_HEIGHT_MIN_ITEMS * itemHeight; if (autoHeight < minAutoHeight) { autoHeight = minAutoHeight; } popup.css({ "max-height": autoHeight + 'px' }); resolve(); }, POPUP_DISPLAY_DELAY); }); } /** * @param {?} $event * @return {?} */ emitBeforeClickEvent($event) { let /** @type {?} */ sItem = this.getSelectedItem(); let /** @type {?} */ sIndex = this.getSelectedIndex(); let /** @type {?} */ data = { item: sItem, index: sIndex }; let /** @type {?} */ ev = EventUtils.newCustomEvent(BEFORE_CLICK_EVENT, this, data, $event); this.beforeClickEvent.emit(ev); } /** * @param {?} $event * @return {?} */ emitClickEvent($event) { let /** @type {?} */ sItem = this.getSelectedItem(); let /** @type {?} */ sIndex = this.getSelectedIndex(); let /** @type {?} */ data = { item: sItem, index: sIndex }; let /** @type {?} */ ev = EventUtils.newCustomEvent(CLICK_EVENT, this, data, $event); this.clickEvent.emit(ev); } /** * @param {?} $event * @return {?} */ emitBeforeShowEvent($event) { let /** @type {?} */ sItem = this.getSelectedItem(); let /** @type {?} */ sIndex = this.getSelectedIndex(); let /** @type {?} */ data = { item: sItem, index: sIndex }; let /** @type {?} */ ev = EventUtils.newCustomEvent(BEFORE_SHOW_EVENT, this, data, $event); this.beforeShowEvent.emit(ev); } /** * @param {?} $event * @return {?} */ emitShowEvent($event) { let /** @type {?} */ sItem = this.getSelectedItem(); let /** @type {?} */ sIndex = this.getSelectedIndex(); let /** @type {?} */ data = { item: sItem, index: sIndex }; let /** @type {?} */ ev = EventUtils.newCustomEvent(SHOW_EVENT, this, data, $event); this.showEvent.emit(ev); } /** * @param {?} $event * @return {?} */ emitBeforeHideEvent($event) { let /** @type {?} */ sItem = this.getSelectedItem(); let /** @type {?} */ sIndex = this.getSelectedIndex(); let /** @type {?} */ data = { item: sItem, index: sIndex }; let /** @type {?} */ ev = EventUtils.newCustomEvent(BEFORE_HIDE_EVENT, this, data, $event); this.beforeHideEvent.emit(ev); } /** * @param {?} $event * @return {?} */ emitHideEvent($event) { let /** @type {?} */ sItem = this.getSelectedItem(); let /** @type {?} */ sIndex = this.getSelectedIndex(); let /** @type {?} */ data = { item: sItem, index: sIndex }; let /** @type {?} */ ev = EventUtils.newCustomEvent(HIDE_EVENT, this, data, $event); this.hideEvent.emit(ev); } /** * @return {?} */ getUIUpdateInterval() { if (this.phloxAppInfo === null || this.phloxAppInfo === undefined) { return 600; } if (this.phloxAppInfo.settings === null || this.phloxAppInfo.settings === undefined) { return 600; } if (this.phloxAppInfo.settings.UI_ANIMATE_INTERVAL === null || this.phloxAppInfo.settings.UI_ANIMATE_INTERVAL === undefined) { return 600; } return this.phloxAppInfo.settings.UI_ANIMATE_INTERVAL; } /** * @param {?} $event * @return {?} */ doFocus($event) { } /** * @param {?} $event * @return {?} */ doLostFocus($event) { this.setShow(false); } /** * @param {?} $event * @return {?} */ onFocusing($event) { this.needFocusService.setFocusingComponent(this, $event); } /** * @param {?} $event * @return {?} */ onLostFocusing($event) { if ($event !== undefined && $event !== null) { $event.preventDefault(); } if (this._itemLostFocusingTimeout !== null && typeof this._itemLostFocusingTimeout !== 'undefined') { clearTimeout(this._itemLostFocusingTimeout); this._itemLostFocusingTimeout = null; } this._itemLostFocusingTimeout = setTimeout(() => { if (!this._isItemClick) { this.doBlur($event); this.needFocusService.resetFocusingComponent($event); } this._isItemClick = false; }, 130); // if dropdown not hide try to adjust this value } /** * @param {?} $event * @param {?} index * @return {?} */ onSelectItemClicked($event, index) { this._isItemClick = true; this.setSelectedIndex(index, $event, true); // Auto hide popup when select item is clicked. this.setShow(false); } /** * @param {?=} $event * @param {?=} fireEvent * @return {?} */ click($event, fireEvent) { if (this.isReadOnly()) { return; } if (this.isDisabled()) { return; } if (fireEvent === null || fireEvent === undefined) { fireEvent = true; } EventUtils.handleBrowserEvent(this, 'beforeClickEvent', $event, fireEvent, ($event) => { // doEvent this.setShow(true); }, ($event) => { // emitBeforeEvent this.emitBeforeClickEvent($event); }, ($event, result) => { // emitAfterEvent this.emitClickEvent($event); }, ($event) => { // doPrevented }); } /** * @return {?} */ isShow() { return this.show; } /** * @param {?} show * @param {?=} $event * @param {?=} fireEvent * @return {?} */ setShow(show, $event, fireEvent) { if (show === null || typeof show !== 'boolean') { show = false; } if (this.show === show) { return; } if (show) { this.doShow($event, fireEvent); } else { this.doHide($event, fireEvent); } } /** * @return {?} */ getAlign() { return this.align; } /** * @param {?} align * @return {?} */ setAlign(align) { this.align = align; } /** * @return {?} */ getDropdownWidth() { return this.dropdownWidth; } /** * @param {?} dropdownWidth * @return {?} */ setDropdownWidth(dropdownWidth) { this.dropdownWidth = dropdownWidth; } /** * @return {?} */ getDropdownHeight() { return this.dropdownHeight; } /** * @param {?} dropdownHeight * @return {?} */ setDropdownHeight(dropdownHeight) { this.dropdownHeight = dropdownHeight; } /** * @return {?} */ getWidth() { return this.width; } /** * @param {?} width * @return {?} */ setWidth(width) { this.width = width; } /** * @return {?} */ getHeight() { return this.height; } /** * @param {?} height * @return {?} */ setHeight(height) { this.height = height; } /** * @return {?} */ getBeforeClickEvent() { return this.beforeClickEvent; } /** * @param {?} event * @return {?} */ setBeforeClickEvent(event) { this.beforeClickEvent = event; } /** * @return {?} */ getClickEvent() { return this.clickEvent; } /** * @param {?} event * @return {?} */ setClickEvent(event) { this.clickEvent = event; } /** * @return {?} */ getBeforeShowEvent() { return this.beforeShowEvent; } /** * @param {?} event * @return {?} */ setBeforeShowEvent(event) { this.beforeShowEvent = event; } /** * @return {?} */ getShowEvent() { return this.showEvent; } /** * @param {?} event * @return {?} */ setShowEvent(event) { this.showEvent = event; } /** * @return {?} */ getBeforeHideEvent() { return this.beforeHideEvent; } /** * @param {?} event * @return {?} */ setBeforeHideEvent(event) { this.beforeHideEvent = event; } /** * @return {?} */ getHideEvent() { return this.hideEvent; } /** * @param {?} event * @return {?} */ setHideEvent(event) { this.hideEvent = event; } /** * @param {?} data * @return {?} */ setData(data) { super.setData(data); this.setPreloadData(data); } } AbstractSimpleDropdown.LEFT = LEFT; AbstractSimpleDropdown.RIGHT = RIGHT; AbstractSimpleDropdown.CENTER = CENTER; tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], AbstractSimpleDropdown.prototype, "width", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], AbstractSimpleDropdown.prototype, "height", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], AbstractSimpleDropdown.prototype, "dropdownWidth", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], AbstractSimpleDropdown.prototype, "dropdownHeight", void 0); tslib_1.__decorate([ Option('beforeClick'), tslib_1.__metadata("design:type", EventEmitter) ], AbstractSimpleDropdown.prototype, "beforeClickEvent", void 0); tslib_1.__decorate([ Option('click'), tslib_1.__metadata("design:type", EventEmitter) ], AbstractSimpleDropdown.prototype, "clickEvent", void 0); tslib_1.__decorate([ Option('beforeShow'), tslib_1.__metadata("design:type", EventEmitter) ], AbstractSimpleDropdown.prototype, "beforeShowEvent", void 0); tslib_1.__decorate([ Option('show'), tslib_1.__metadata("design:type", EventEmitter) ], AbstractSimpleDropdown.prototype, "showEvent", void 0); tslib_1.__decorate([ Option('beforeHide'), tslib_1.__metadata("design:type", EventEmitter) ], AbstractSimpleDropdown.prototype, "beforeHideEvent", void 0); tslib_1.__decorate([ Option('hide'), tslib_1.__metadata("design:type", EventEmitter) ], AbstractSimpleDropdown.prototype, "hideEvent", void 0); function AbstractSimpleDropdown_tsickle_Closure_declarations() { /** @type {?} */ AbstractSimpleDropdown.LEFT; /** @type {?} */ AbstractSimpleDropdown.RIGHT; /** @type {?} */ AbstractSimpleDropdown.CENTER; /** @type {?} */ AbstractSimpleDropdown.prototype.width; /** @type {?} */ AbstractSimpleDropdown.prototype.height; /** @type {?} */ AbstractSimpleDropdown.prototype.dropdownWidth; /** @type {?} */ AbstractSimpleDropdown.prototype.dropdownHeight; /** @type {?} */ AbstractSimpleDropdown.prototype.beforeClickEvent; /** @type {?} */ AbstractSimpleDropdown.prototype.clickEvent; /** @type {?} */ AbstractSimpleDropdown.prototype.beforeShowEvent; /** @type {?} */ AbstractSimpleDropdown.prototype.showEvent; /** @type {?} */ AbstractSimpleDropdown.prototype.beforeHideEvent; /** @type {?} */ AbstractSimpleDropdown.prototype.hideEvent; /** @type {?} */ AbstractSimpleDropdown.prototype.needFocusService; /** @type {?} */ AbstractSimpleDropdown.prototype.phloxAppInfo; /** @type {?} */ AbstractSimpleDropdown.prototype._align; /** @type {?} */ AbstractSimpleDropdown.prototype._isItemClick; /** @type {?} */ AbstractSimpleDropdown.prototype._itemLostFocusingTimeout; /** @type {?} */ AbstractSimpleDropdown.prototype.show; /** * @abstract * @param {?} $event * @return {?} */ AbstractSimpleDropdown.prototype.doBlur = function ($event) { }; /** * @abstract * @return {?} */ AbstractSimpleDropdown.prototype.getDropdownPopupSelector = function () { }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWJzdHJhY3RTaW1wbGVEcm9wZG93bi5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2NvbS5waGxveHVpLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudC9kYXRhdmlldy9pbnB1dC9BYnN0cmFjdFNpbXBsZURyb3Bkb3duLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFzRCxZQUFZLEVBQXdCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZILE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBTWhFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUc3RCxPQUFPLEVBQ0wsaUJBQWlCLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBRTlGLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTdELHVCQUFNLElBQUksR0FBVyxNQUFNLENBQUM7QUFDNUIsdUJBQU0sS0FBSyxHQUFXLE9BQU8sQ0FBQztBQUM5Qix1QkFBTSxNQUFNLEdBQVcsUUFBUSxDQUFDO0FBQ2hDLHVCQUFNLHFCQUFxQixHQUFXLENBQUMsQ0FBQztBQUN4Qyx1QkFBTSxtQkFBbUIsR0FBVyxFQUFFLENBQUM7Ozs7QUFFdkMsTUFBTSw2QkFBdUMsU0FBUSxxQkFBcUI7Ozs7OztJQXVEeEUsWUFBWSxnQkFBa0MsRUFBRSxVQUFzQixFQUFFLG1CQUF3QztRQUM5RyxLQUFLLENBQUMsVUFBVSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFcEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsU0FBUyxH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Q00sWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBFbGVtZW50UmVmLCBJbnB1dCwgT3V0cHV0LCBUeXBlLCBFdmVudEVtaXR0ZXIsIFZpZXdDaGlsZCwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdFNlbGVjdE9uZUl0ZW0gfSBmcm9tICcuL0Fic3RyYWN0U2VsZWN0T25lSXRlbSc7XG5pbXBvcnQgeyBJTmVlZEZvY3VzIH0gZnJvbSAnLi4vLi4vSU5lZWRGb2N1cyc7XG5pbXBvcnQgeyBJSGFzRGF0YSB9IGZyb20gJy4uLy4uL0lIYXNEYXRhJztcbmltcG9ydCB7IElEYXRhQ29tcGFyYXRvciB9IGZyb20gJy4uLy4uL0lEYXRhQ29tcGFyYXRvcic7XG5pbXBvcnQgeyBOZWVkRm9jdXNTZXJ2aWNlLCBQaGxveEFwcEluZm9TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZS9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBEZWZhdWx0U2VsZWN0SXRlbU1vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWwvRGVmYXVsdFNlbGVjdEl0ZW1Nb2RlbCc7XG5pbXBvcnQgeyBPcHRpb24gfSBmcm9tICcuLi8uLi8uLi9kZWNvcmF0b3IvT3B0aW9uLmRlY29yYXRvcic7XG5pbXBvcnQgeyBQaGxveEFwcEluZm8gfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnQvbW9kZWwvUGhsb3hBcHBJbmZvJztcbmltcG9ydCB7IElTZWxlY3RJdGVtTW9kZWwgfSBmcm9tICcuLi8uLi9tb2RlbC9JU2VsZWN0SXRlbU1vZGVsJztcbmltcG9ydCB7XG4gIEJFRk9SRV9TSE9XX0VWRU5ULCBTSE9XX0VWRU5ULCBCRUZPUkVfSElERV9FVkVOVCwgSElERV9FVkVOVCwgQkVGT1JFX0NMSUNLX0VWRU5ULCBDTElDS19FVkVOVCxcbiAgQkVGT1JFX1NFTEVDVF9FVkVOVCwgU0VMRUNUX0VWRU5UXG59IGZyb20gJy4uLy4uLy4uL3NoYXJlL0N1c3RvbUV2ZW50VHlwZSc7XG5pbXBvcnQgeyBFdmVudFV0aWxzIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmUvdXRpbHMvRXZlbnRVdGlscyc7XG5cbmNvbnN0IExFRlQ6IHN0cmluZyA9IFwibGVmdFwiO1xuY29uc3QgUklHSFQ6IHN0cmluZyA9IFwicmlnaHRcIjtcbmNvbnN0IENFTlRFUjogc3RyaW5nID0gXCJjZW50ZXJcIjtcbmNvbnN0IEFVVE9fSEVJR0hUX01JTl9JVEVNUzogbnVtYmVyID0gNTtcbmNvbnN0IFBPUFVQX0RJU1BMQVlfREVMQVk6IG51bWJlciA9IDEwO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RTaW1wbGVEcm9wZG93biBleHRlbmRzIEFic3RyYWN0U2VsZWN0T25lSXRlbSBpbXBsZW1lbnRzIE9uSW5pdCwgSU5lZWRGb2N1cywgT25DaGFuZ2VzIHtcblxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IExFRlQ6IHN0cmluZyA9IExFRlQ7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUklHSFQ6IHN0cmluZyA9IFJJR0hUO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENFTlRFUjogc3RyaW5nID0gQ0VOVEVSO1xuXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgd2lkdGg6IHN0cmluZztcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBoZWlnaHQ6IHN0cmluZztcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBkcm9wZG93bldpZHRoOiBzdHJpbmc7XG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgZHJvcGRvd25IZWlnaHQ6IHN0cmluZztcbiAgQE9wdGlvbignYmVmb3JlQ2xpY2snKVxuICBwcm90ZWN0ZWQgYmVmb3JlQ2xpY2tFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIEBPcHRpb24oJ2NsaWNrJylcbiAgcHJvdGVjdGVkIGNsaWNrRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3B0aW9uKCdiZWZvcmVTaG93JylcbiAgcHJvdGVjdGVkIGJlZm9yZVNob3dFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG4gIEBPcHRpb24oJ3Nob3cnKVxuICBwcm90ZWN0ZWQgc2hvd0V2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgQE9wdGlvbignYmVmb3JlSGlkZScpXG4gIHByb3RlY3RlZCBiZWZvcmVIaWRlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3B0aW9uKCdoaWRlJylcbiAgcHJvdGVjdGVkIGhpZGVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XG5cbiAgcHJvdGVjdGVkIG5lZWRGb2N1c1NlcnZpY2U6IE5lZWRGb2N1c1NlcnZpY2U7XG4gIHByb3RlY3RlZCBwaGxveEFwcEluZm86IFBobG94QXBwSW5mbztcblxuICBwcml2YXRlIF9hbGlnbjogc3RyaW5nO1xuICBwcml2YXRlIF9pc0l0ZW1DbGljazogYm9vbGVhbjtcbiAgcHJpdmF0ZSBfaXRlbUxvc3RGb2N1c2luZ1RpbWVvdXQ6IGFueTtcblxuICBwcml2YXRlIHNob3c6IGJvb2xlYW47XG5cbiAgcHJvdGVjdGVkIHNldCBhbGlnbihhbGlnbjogc3RyaW5nKSB7XG4gICAgaWYgKGFsaWduICE9PSBudWxsICYmIHR5cGVvZiBhbGlnbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGFsaWduID0gYWxpZ24udG9Mb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAoYWxpZ24gPT09IExFRlQgfHwgYWxpZ24gPT09IFJJR0hUIHx8IGFsaWduID09PSBDRU5URVIpIHtcbiAgICAgIHRoaXMuX2FsaWduID0gYWxpZ247XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2FsaWduID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGFsaWduKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuX2FsaWduID09PSBudWxsIHx8IHR5cGVvZiB0aGlzLl9hbGlnbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBMRUZUO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYWxpZ247XG4gIH1cblxuICBjb25zdHJ1Y3RvcihuZWVkRm9jdXNTZXJ2aWNlOiBOZWVkRm9jdXNTZXJ2aWNlLCBlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwaGxveEFwcEluZm9TZXJ2aWNlOiBQaGxveEFwcEluZm9TZXJ2aWNlKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgbmVlZEZvY3VzU2VydmljZSk7XG5cbiAgICB0aGlzLmJlZm9yZUNsaWNrRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5jbGlja0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuYmVmb3JlU2hvd0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuc2hvd0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuYmVmb3JlSGlkZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuaGlkZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgdGhpcy5faXNJdGVtQ2xpY2sgPSBmYWxzZTtcblxuICAgIHRoaXMubmVlZEZvY3VzU2VydmljZSA9IG5lZWRGb2N1c1NlcnZpY2U7XG5cbiAgICBwaGxveEFwcEluZm9TZXJ2aWNlLmdldEFwcEluZm8oKS50aGVuKChpbmZvKSA9PiB7XG4gICAgICB0aGlzLnBobG94QXBwSW5mbyA9IGluZm87XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KSB7XG4gICAgLy8gZml4IGJ1ZyB3aGVuIHNldCBzZWxlY3RlZCBiZWZvcmUgaXRlbSBpcyBub3QgbG9hZGVkXG4gICAgaWYgKGNoYW5nZXNbJ2l0ZW1zJ10gIT09IG51bGwgJiYgdHlwZW9mIGNoYW5nZXNbJ2l0ZW1zJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsZXQgb2xkVHlwZSA9IGNoYW5nZXNbJ2l0ZW1zJ10ucHJldmlvdXNWYWx1ZTtcbiAgICAgIGxldCBuZXdUeXBlOiBhbnkgPSBjaGFuZ2VzWydpdGVtcyddLmN1cnJlbnRWYWx1ZTtcblxuICAgICAgbGV0IG9sZFNpemUgPSAob2xkVHlwZSAhPT0gbnVsbCAmJiB0eXBlb2Ygb2xkVHlwZSAhPT0gJ3VuZGVmaW5lZCcgJiYgQXJyYXkuaXNBcnJheShvbGRUeXBlKSkgPyBvbGRUeXBlLmxlbmd0aCA6IDA7XG4gICAgICBsZXQgbmV3U2l6ZSA9IChuZXdUeXBlICE9PSBudWxsICYmIHR5cGVvZiBuZXdUeXBlICE9PSAndW5kZWZpbmVkJyAmJiBBcnJheS5pc0FycmF5KG5ld1R5cGUpKSA/IG5ld1R5cGUubGVuZ3RoIDogMDtcblxuICAgICAgaWYgKG9sZFNpemUgIT09IG5ld1NpemUpIHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YVBhcmVudCAhPT0gbnVsbCAmJiB0aGlzLmRhdGFQYXJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIGZpeCBidWcgc2V0RGF0YSBidXQgc3RpbGwgaGFzIGEgYnVnIHRoaXMuY29tcC5zZXREYXRhKCkgaW4gbmdPbkluaXRcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMubG9hZGVkSXRlbXMoKTtcbiAgICAgICAgICB9LCAxKTtcbiAgICAgICAgfWVsc2Uge1xuICAgICAgICAgIHRoaXMubG9hZGVkSXRlbXMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2VsZWN0SXRlbUhlaWdodCgpOiBudW1iZXIge1xuICAgIGxldCBzZWxlY3Rvcjogc3RyaW5nID0gdGhpcy5nZXREcm9wZG93blBvcHVwU2VsZWN0b3IoKTtcblxuICAgIHJldHVybiAkKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KS5maW5kKHNlbGVjdG9yICsgJyA+IDplcSgwKScpLm91dGVySGVpZ2h0KCk7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbFRvU2VsZWN0ZWRJbmRleCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgbGV0IHNlbGVjdGVkSW5kZXg6IG51bWJlciA9IHRoaXMuZ2V0U2VsZWN0ZWRJbmRleCgpO1xuICAgICAgaWYgKHNlbGVjdGVkSW5kZXggPT09IG51bGwgfHwgc2VsZWN0ZWRJbmRleCA9PT0gdW5kZWZpbmVkIHx8IHNlbGVjdGVkSW5kZXggPCAwKSB7XG4gICAgICAgIHNlbGVjdGVkSW5kZXggPSAwO1xuICAgICAgfVxuXG4gICAgICBsZXQgc2VsZWN0b3I6IHN0cmluZyA9IHRoaXMuZ2V0RHJvcGRvd25Qb3B1cFNlbGVjdG9yKCk7XG5cbiAgICAgIGxldCBlbGU6IGFueSA9ICQodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpLmZpbmQoc2VsZWN0b3IpO1xuXG4gICAgICAvLyBHZXQgRE9NIGVsZW1lbnQgb2Ygc2VsZWN0ZWQgaXRlbS5cbiAgICAgIGxldCBzZWxlY3RlZEVsZTogYW55ID0gJCgoZWxlLmNoaWxkcmVuKCkubGVuZ3RoID4gc2VsZWN0ZWRJbmRleCkgPyBlbGUuY2hpbGRyZW4oKVtzZWxlY3RlZEluZGV4XSA6IGVsZS5jaGlsZHJlbigpW2VsZS5jaGlsZHJlbigpLmxlbmd0aCAtIDFdKTtcblxuICAgICAgLy8gU2Nyb2xsIHRvIHNlbGVjdGVkIGl0ZW0gdG9wIHJlbGF0aXZlIHRvIGl0cyBwYXJlbnQuXG4gICAgICBsZXQgaDogbnVtYmVyID0gc2VsZWN0ZWRFbGUucG9zaXRpb24oKS50b3AgKyBlbGUuc2Nyb2xsVG9wKCk7XG5cbiAgICAgIGVsZS5zdG9wKCkuYW5pbWF0ZSh7IHNjcm9sbFRvcDogaCB9LCAxLCAnc3dpbmcnLCAoKSA9PiB7XG4gICAgICAgIGVsZS5zY3JvbGxUb3AoaCk7XG5cbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRvU2hvdygkZXZlbnQ/OiBFdmVudCwgZmlyZUV2ZW50PzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChmaXJlRXZlbnQgPT09IG51bGwgfHwgZmlyZUV2ZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZpcmVFdmVudCA9IHRydWU7XG4gICAgfVxuXG4gICAgRXZlbnRVdGlscy5oYW5kbGVCcm93c2VyRXZlbnQodGhpcywgJ2JlZm9yZVNob3dFdmVudCcsICRldmVudCwgZmlyZUV2ZW50LCAoJGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgLy8gZG9FdmVudFxuICAgICAgdGhpcy5zaG93ID0gdHJ1ZTtcblxuICAgICAgcmV0dXJuIHRoaXMucmVzaXplRHJvcGRvd25Qb3B1cCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zY3JvbGxUb1NlbGVjdGVkSW5kZXgoKTtcbiAgICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5uZWVkRm9jdXNTZXJ2aWNlKSB7XG4gICAgICAgICAgdGhpcy5uZWVkRm9jdXNTZXJ2aWNlLnNldEZvY3VzaW5nQ29tcG9uZW50KHRoaXMsICRldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubmVlZEZvY3VzU2VydmljZSkge1xuICAgICAgICAgIHRoaXMubmVlZEZvY3VzU2VydmljZS5zZXRGb2N1c2luZ0NvbXBvbmVudCh0aGlzLCAkZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9LCAoJGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgLy8gZW1pdEJlZm9yZUV2ZW50XG4gICAgICB0aGlzLmVtaXRCZWZvcmVTaG93RXZlbnQoJGV2ZW50KTtcbiAgICB9LCAoJGV2ZW50OiBFdmVudCwgcmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIC8vIGVtaXRBZnRlckV2ZW50XG4gICAgICB0aGlzLmVtaXRTaG93RXZlbnQoJGV2ZW50KTtcbiAgICB9LCAoJGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgLy8gZG9QcmV2ZW50ZWRcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZG9IaWRlKCRldmVudD86IEV2ZW50LCBmaXJlRXZlbnQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKGZpcmVFdmVudCA9PT0gbnVsbCB8fCBmaXJlRXZlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZmlyZUV2ZW50ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBFdmVudFV0aWxzLmhhbmRsZUJyb3dzZXJFdmVudCh0aGlzLCAnYmVmb3JlSGlkZUV2ZW50JywgJGV2ZW50LCBmaXJlRXZlbnQsICgkZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAvLyBkb0V2ZW50XG4gICAgICB0aGlzLnNob3cgPSBmYWxzZTtcbiAgICB9LCAoJGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgLy8gZW1pdEJlZm9yZUV2ZW50XG4gICAgICB0aGlzLmVtaXRCZWZvcmVIaWRlRXZlbnQoJGV2ZW50KTtcbiAgICB9LCAoJGV2ZW50OiBFdmVudCwgcmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIC8vIGVtaXRBZnRlckV2ZW50XG4gICAgICB0aGlzLmVtaXRIaWRlRXZlbnQoJGV2ZW50KTtcbiAgICB9LCAoJGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgLy8gZG9QcmV2ZW50ZWRcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzaXplRHJvcGRvd25Qb3B1cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gRGVsYXkgdG8gbGV0IERPTSB1cGRhdGUgZmlyc3QgdG8gYmUgYWJsZSB0byBnZXQgaXRzIG9mZnNldCgpLnRvcCBhbmQgaXRzIHNpemUuXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgbGV0IHBvcHVwOiBhbnkgPSAkKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KS5maW5kKHRoaXMuZ2V0RHJvcGRvd25Qb3B1cFNlbGVjdG9yKCkpO1xuXG4gICAgICAgIGlmICh0aGlzLmRyb3Bkb3duSGVpZ2h0ICE9PSBudWxsICYmIHRoaXMuZHJvcGRvd25IZWlnaHQgIT09IHVuZGVmaW5lZCAmJiB0aGlzLmRyb3Bkb3duSGVpZ2h0ICE9PSAnJykge1xuICAgICAgICAgIC8vIElmIGRyb3Bkb3duIGhlaWdodCBpcyBleHBsaWNpdGx5IGRlZmluZWQsIGRvIG5vdGhpbmcgJiByZXNldCBlbGVtZW50J3MgY3NzIG1heC1oZWlnaHQuXG4gICAgICAgICAgcG9wdXAuY3NzKHtcbiAgICAgICAgICAgIFwibWF4LWhlaWdodFwiOiB1bmRlZmluZWRcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJlc29sdmUoKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwb3B1cFRvcDogbnVtYmVyID0gcG9wdXAub2Zmc2V0KCkudG9wO1xuICAgICAgICBpZiAoIXBvcHVwVG9wKSB7XG4gICAgICAgICAgcG9wdXBUb3AgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHduZFRvcDogbnVtYmVyID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xuICAgICAgICBpZiAoIXduZFRvcCkge1xuICAgICAgICAgIHduZFRvcCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc2NyZWVuVG9wOiBudW1iZXIgPSBwb3B1cFRvcCAtIHduZFRvcDtcbiAgICAgICAgbGV0IGF1dG9IZWlnaHQ6IG51bWJlciA9ICQod2luZG93KS5oZWlnaHQoKSAtIHNjcmVlblRvcDtcbiAgICAgICAgaWYgKCFhdXRvSGVpZ2h0KSB7XG4gICAgICAgICAgYXV0b0hlaWdodCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaXRlbUhlaWdodDogbnVtYmVyID0gdGhpcy5nZXRTZWxlY3RJdGVtSGVpZ2h0KCk7XG5cbiAgICAgICAgbGV0IG1pbkF1dG9IZWlnaHQ6IG51bWJlciA9IEFVVE9fSEVJR0hUX01JTl9JVEVNUyAqIGl0ZW1IZWlnaHQ7XG4gICAgICAgIGlmIChhdXRvSGVpZ2h0IDwgbWluQXV0b0hlaWdodCkge1xuICAgICAgICAgIGF1dG9IZWlnaHQgPSBtaW5BdXRvSGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgcG9wdXAuY3NzKHtcbiAgICAgICAgICBcIm1heC1oZWlnaHRcIjogYXV0b0hlaWdodCArICdweCdcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSwgUE9QVVBfRElTUExBWV9ERUxBWSk7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZW1pdEJlZm9yZUNsaWNrRXZlbnQoJGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGxldCBzSXRlbSA9IHRoaXMuZ2V0U2VsZWN0ZWRJdGVtKCk7XG4gICAgbGV0IHNJbmRleCA9IHRoaXMuZ2V0U2VsZWN0ZWRJbmRleCgpO1xuXG4gICAgbGV0IGRhdGE6IGFueSA9IHtcbiAgICAgIGl0ZW06IHNJdGVtLFxuICAgICAgaW5kZXg6IHNJbmRleFxuICAgIH07XG5cbiAgICBsZXQgZXYgPSBFdmVudFV0aWxzLm5ld0N1c3RvbUV2ZW50KEJFRk9SRV9DTElDS19FVkVOVCwgdGhpcywgZGF0YSwgJGV2ZW50KTtcblxuICAgIHRoaXMuYmVmb3JlQ2xpY2tFdmVudC5lbWl0KGV2KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbWl0Q2xpY2tFdmVudCgkZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgbGV0IHNJdGVtID0gdGhpcy5nZXRTZWxlY3RlZEl0ZW0oKTtcbiAgICBsZXQgc0luZGV4ID0gdGhpcy5nZXRTZWxlY3RlZEluZGV4KCk7XG5cbiAgICBsZXQgZGF0YTogYW55ID0ge1xuICAgICAgaXRlbTogc0l0ZW0sXG4gICAgICBpbmRleDogc0luZGV4XG4gICAgfTtcblxuICAgIGxldCBldiA9IEV2ZW50VXRpbHMubmV3Q3VzdG9tRXZlbnQoQ0xJQ0tfRVZFTlQsIHRoaXMsIGRhdGEsICRldmVudCk7XG5cbiAgICB0aGlzLmNsaWNrRXZlbnQuZW1pdChldik7XG4gIH1cblxuICBwcm90ZWN0ZWQgZW1pdEJlZm9yZVNob3dFdmVudCgkZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgbGV0IHNJdGVtID0gdGhpcy5nZXRTZWxlY3RlZEl0ZW0oKTtcbiAgICBsZXQgc0luZGV4ID0gdGhpcy5nZXRTZWxlY3RlZEluZGV4KCk7XG5cbiAgICBsZXQgZGF0YTogYW55ID0ge1xuICAgICAgaXRlbTogc0l0ZW0sXG4gICAgICBpbmRleDogc0luZGV4XG4gICAgfTtcblxuICAgIGxldCBldiA9IEV2ZW50VXRpbHMubmV3Q3VzdG9tRXZlbnQoQkVGT1JFX1NIT1dfRVZFTlQsIHRoaXMsIGRhdGEsICRldmVudCk7XG5cbiAgICB0aGlzLmJlZm9yZVNob3dFdmVudC5lbWl0KGV2KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbWl0U2hvd0V2ZW50KCRldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBsZXQgc0l0ZW0gPSB0aGlzLmdldFNlbGVjdGVkSXRlbSgpO1xuICAgIGxldCBzSW5kZXggPSB0aGlzLmdldFNlbGVjdGVkSW5kZXgoKTtcblxuICAgIGxldCBkYXRhOiBhbnkgPSB7XG4gICAgICBpdGVtOiBzSXRlbSxcbiAgICAgIGluZGV4OiBzSW5kZXhcbiAgICB9O1xuXG4gICAgbGV0IGV2ID0gRXZlbnRVdGlscy5uZXdDdXN0b21FdmVudChTSE9XX0VWRU5ULCB0aGlzLCBkYXRhLCAkZXZlbnQpO1xuXG4gICAgdGhpcy5zaG93RXZlbnQuZW1pdChldik7XG4gIH1cblxuICBwcm90ZWN0ZWQgZW1pdEJlZm9yZUhpZGVFdmVudCgkZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgbGV0IHNJdGVtID0gdGhpcy5nZXRTZWxlY3RlZEl0ZW0oKTtcbiAgICBsZXQgc0luZGV4ID0gdGhpcy5nZXRTZWxlY3RlZEluZGV4KCk7XG5cbiAgICBsZXQgZGF0YTogYW55ID0ge1xuICAgICAgaXRlbTogc0l0ZW0sXG4gICAgICBpbmRleDogc0luZGV4XG4gICAgfTtcblxuICAgIGxldCBldiA9IEV2ZW50VXRpbHMubmV3Q3VzdG9tRXZlbnQoQkVGT1JFX0hJRE