com.phloxui
Version:
PhloxUI Ng2+ Framework
662 lines (661 loc) • 57 kB
JavaScript
/**
* @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