solar-ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
705 lines • 61.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { animate, state, style, transition, trigger } from '@angular/animations';
import { DOWN_ARROW, SPACE, TAB } from '@angular/cdk/keycodes';
import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
import { forwardRef, Component, ContentChildren, EventEmitter, HostListener, Input, Output, QueryList, Renderer2, SimpleChange, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { isNotNil } from '../core/util/check';
import { toBoolean } from '../core/util/convert';
import { NzOptionContainerComponent } from './nz-option-container.component';
import { NzOptionGroupComponent } from './nz-option-group.component';
import { NzOptionComponent } from './nz-option.component';
import { defaultFilterOption } from './nz-option.pipe';
import { NzSelectTopControlComponent } from './nz-select-top-control.component';
export class NzSelectComponent {
/**
* @param {?} renderer
*/
constructor(renderer) {
this.renderer = renderer;
this._disabled = false;
this._allowClear = false;
this._showSearch = false;
this._open = false;
this._autoFocus = false;
this.onChange = () => null;
this.onTouched = () => null;
this.dropDownPosition = 'bottom';
// tslint:disable-next-line:no-any
this.listOfSelectedValue = [];
this.listOfTemplateOption = [];
this.searchValue = '';
this.isDestroy = true;
this.isInit = false;
this.nzOnSearch = new EventEmitter();
this.nzScrollToBottom = new EventEmitter();
this.nzOpenChange = new EventEmitter();
this.nzSize = 'default';
this.nzServerSearch = false;
this.nzMode = 'default';
this.nzDropdownMatchSelectWidth = true;
this.nzFilterOption = defaultFilterOption;
this.nzMaxMultipleCount = Infinity;
/**
* https://github.com/angular/angular/pull/13349/files *
*/
this.compareWith = (o1, o2) => o1 === o2;
}
/**
* @param {?} value
* @return {?}
*/
set nzDropdownClassName(value) {
this._dropdownClassName = value;
this.updateDropDownClassMap();
}
/**
* @return {?}
*/
get nzDropdownClassName() {
return this._dropdownClassName;
}
/**
* @param {?} value
* @return {?}
*/
set nzAutoFocus(value) {
this._autoFocus = toBoolean(value);
this.updateAutoFocus();
}
/**
* @return {?}
*/
get nzAutoFocus() {
return this._autoFocus;
}
/**
* @param {?} value
* @return {?}
*/
set nzOpen(value) {
this._open = value;
this.handleEscBug();
this.updateCdkConnectedOverlayStatus();
this.updateDropDownClassMap();
if (this.nzOpen) {
if (this.nzSelectTopControlComponent) {
this.nzSelectTopControlComponent.focusOnInput();
this.nzSelectTopControlComponent.setInputValue('', true);
}
if (this.nzOptionContainerComponent) {
this.nzOptionContainerComponent.scrollIntoView();
}
if (this.cdkConnectedOverlay && this.cdkConnectedOverlay.overlayRef) {
this.cdkConnectedOverlay.overlayRef.updatePosition();
/** @type {?} */
const backdropElement = this.cdkConnectedOverlay.overlayRef.backdropElement;
/** @type {?} */
const parentNode = this.renderer.parentNode(backdropElement);
/** @type {?} */
const hostElement = this.cdkConnectedOverlay.overlayRef.hostElement;
this.renderer.appendChild(parentNode, backdropElement);
this.renderer.appendChild(parentNode, hostElement);
}
}
else {
if (this.nzSelectTopControlComponent) {
this.nzSelectTopControlComponent.setInputValue('', false);
}
if (this.nzOptionContainerComponent) {
this.nzOptionContainerComponent.resetActiveOption();
}
}
}
/**
* @return {?}
*/
get nzOpen() {
return this._open;
}
/**
* @param {?} value
* @return {?}
*/
set nzDisabled(value) {
this._disabled = toBoolean(value);
if (this.nzDisabled) {
this.closeDropDown();
}
}
/**
* @return {?}
*/
get nzDisabled() {
return this._disabled;
}
/**
* @param {?} value
* @return {?}
*/
set nzAllowClear(value) {
this._allowClear = toBoolean(value);
}
/**
* @return {?}
*/
get nzAllowClear() {
return this._allowClear;
}
/**
* @param {?} value
* @return {?}
*/
set nzShowSearch(value) {
this._showSearch = toBoolean(value);
}
/**
* @return {?}
*/
get nzShowSearch() {
return this._showSearch;
}
/**
* @param {?} value
* @return {?}
*/
set nzPlaceHolder(value) {
this._placeholder = value;
}
/**
* @return {?}
*/
get nzPlaceHolder() {
return this._placeholder;
}
/**
* @return {?}
*/
onClick() {
if (!this.nzDisabled) {
this.nzOpen = !this.nzOpen;
this.nzOpenChange.emit(this.nzOpen);
}
}
/**
* @param {?} event
* @return {?}
*/
_handleKeydown(event) {
if (this._disabled) {
return;
}
/** @type {?} */
const keyCode = event.keyCode;
if (!this._open) {
if (keyCode === SPACE || keyCode === DOWN_ARROW) {
this.nzOpen = true;
this.nzOpenChange.emit(this.nzOpen);
event.preventDefault();
}
}
else {
if (keyCode === TAB) {
// if (keyCode === SPACE || keyCode === TAB) { // #2201
this.nzOpen = false;
this.nzOpenChange.emit(this.nzOpen);
event.preventDefault();
}
}
}
/**
* @return {?}
*/
updateAutoFocus() {
if (this.isInit && this.nzSelectTopControlComponent.inputElement) {
if (this.nzAutoFocus) {
this.renderer.setAttribute(this.nzSelectTopControlComponent.inputElement.nativeElement, 'autofocus', 'autofocus');
}
else {
this.renderer.removeAttribute(this.nzSelectTopControlComponent.inputElement.nativeElement, 'autofocus');
}
}
}
/**
* @return {?}
*/
focus() {
if (this.nzSelectTopControlComponent.inputElement) {
this.nzSelectTopControlComponent.inputElement.nativeElement.focus();
}
}
/**
* @return {?}
*/
blur() {
if (this.nzSelectTopControlComponent.inputElement) {
this.nzSelectTopControlComponent.inputElement.nativeElement.blur();
}
}
/**
* overlay can not be always open , reopen overlay after press esc *
* @return {?}
*/
handleEscBug() {
if (this.nzOpen && this.cdkConnectedOverlay && this.cdkConnectedOverlay.overlayRef && !this.cdkConnectedOverlay.overlayRef.backdropElement) {
this.cdkConnectedOverlay.open = true;
this.cdkConnectedOverlay.ngOnChanges({ open: new SimpleChange(false, true, false) });
}
}
/**
* @param {?} e
* @return {?}
*/
onKeyDownCdkOverlayOrigin(e) {
if (this.nzOptionContainerComponent) {
this.nzOptionContainerComponent.onKeyDownUl(e);
}
}
/**
* @return {?}
*/
closeDropDown() {
if (this.nzOpen) {
this.onTouched();
this.nzOpen = false;
this.nzOpenChange.emit(this.nzOpen);
this.blur();
}
}
/**
* @param {?} position
* @return {?}
*/
onPositionChange(position) {
this.dropDownPosition = position.connectionPair.originY;
this.updateDropDownClassMap();
}
/**
* @return {?}
*/
onClickOptionFromOptionContainer() {
if (this.isSingleMode) {
this.closeDropDown();
}
else if (this.nzMode === 'tags') {
this.onSearch('', true);
}
}
/**
* @return {?}
*/
updateCdkConnectedOverlayStatus() {
if (this.isInit && this.nzOpen && this.cdkOverlayOrigin) {
if (this.nzDropdownMatchSelectWidth) {
this.overlayWidth = this.cdkOverlayOrigin.elementRef.nativeElement.getBoundingClientRect().width;
this.cdkConnectedOverlay.overlayRef.updateSize({ width: this.overlayWidth });
}
else {
this.overlayMinWidth = this.cdkOverlayOrigin.elementRef.nativeElement.getBoundingClientRect().width;
this.cdkConnectedOverlay.overlayRef.updateSize({ minWidth: this.overlayMinWidth });
}
}
this.updateCdkConnectedOverlayPositions();
if (this.cdkConnectedOverlay && this.cdkConnectedOverlay.overlayRef && this.cdkConnectedOverlay.overlayRef.backdropElement) {
if (this.nzOpen) {
this.renderer.removeStyle(this.cdkConnectedOverlay.overlayRef.backdropElement, 'display');
}
else {
this.renderer.setStyle(this.cdkConnectedOverlay.overlayRef.backdropElement, 'display', 'none');
}
}
}
/**
* @return {?}
*/
updateCdkConnectedOverlayPositions() {
/** wait for input size change **/
// FIXME убрал так как селекты не меняют направление когда не влязят
setTimeout(() => this.cdkConnectedOverlay.overlayRef.updatePosition(), 160);
}
/**
* @return {?}
*/
get isSingleMode() {
return this.nzMode === 'default';
}
/**
* @return {?}
*/
get isMultipleOrTags() {
return this.nzMode === 'tags' || this.nzMode === 'multiple';
}
/**
* option container nzListOfSelectedValueChange -> update ngModel *
* @param {?} value
* @return {?}
*/
updateListOfSelectedValueFromOptionContainer(value) {
this.clearSearchValue();
this.updateFromSelectedList(value);
}
/**
* option container nzListOfSelectedValueChange -> update ngModel *
* @param {?} value
* @return {?}
*/
updateListOfSelectedValueFromTopControl(value) {
this.clearSearchValue();
this.updateFromSelectedList(value);
}
/**
* @param {?} value
* @return {?}
*/
updateFromSelectedList(value) {
/** @type {?} */
let modelValue;
if (this.isSingleMode) {
if (value.length) {
modelValue = value[0];
}
}
else {
modelValue = value;
this.updateCdkConnectedOverlayPositions();
}
this.updateNgModel(value, modelValue);
}
/**
* @param {?} value
* @param {?} emit
* @return {?}
*/
onSearch(value, emit) {
if (emit && (this.searchValue !== value)) {
this.nzOnSearch.emit(value);
this.searchValue = value;
}
}
/**
* @return {?}
*/
clearNgModel() {
if (this.isSingleMode) {
this.updateNgModel([], null);
}
else {
this.updateNgModel([], []);
}
}
/**
* @param {?} list
* @param {?} value
* @return {?}
*/
updateNgModel(list, value) {
this.listOfSelectedValue = list;
if (value !== this.value) {
this.value = value;
this.onChange(this.value);
}
}
/**
* @param {?} value
* @return {?}
*/
listOfTemplateOptionChange(value) {
this.listOfTemplateOption = value;
}
/**
* @return {?}
*/
updateDropDownClassMap() {
this.dropDownClassMap = {
['ant-select-dropdown']: true,
[`ant-select-dropdown--single`]: this.isSingleMode,
[`ant-select-dropdown--multiple`]: this.isMultipleOrTags,
[`ant-select-dropdown-placement-bottomLeft`]: this.dropDownPosition === 'bottom',
[`ant-select-dropdown-placement-topLeft`]: this.dropDownPosition === 'top',
[`${this.nzDropdownClassName}`]: !!this.nzDropdownClassName
};
}
/**
* @param {?} e
* @return {?}
*/
onClearSelection(e) {
// TODO: should not clear disabled option ?
e.stopPropagation();
this.clearNgModel();
}
/**
* @return {?}
*/
clearSearchValue() {
if (this.isSingleMode) {
this.nzSelectTopControlComponent.setInputValue('', false);
}
else {
this.nzSelectTopControlComponent.setInputValue('', false);
}
}
/**
* update ngModel -> update listOfSelectedValue *
* @param {?} value
* @return {?}
*/
writeValue(value) {
this.value = value;
if (isNotNil(value)) {
if (Array.isArray(value)) {
this.listOfSelectedValue = value;
}
else {
this.listOfSelectedValue = [value];
}
}
else {
this.listOfSelectedValue = [];
}
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
this.nzDisabled = isDisabled;
}
/**
* @return {?}
*/
ngOnInit() {
this.isDestroy = false;
this.updateDropDownClassMap();
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.isInit = true;
Promise.resolve().then(() => this.updateCdkConnectedOverlayStatus());
}
/**
* @return {?}
*/
ngOnDestroy() {
this.isDestroy = true;
}
}
NzSelectComponent.decorators = [
{ type: Component, args: [{
selector: 'nz-select',
preserveWhitespaces: false,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzSelectComponent),
multi: true
}
],
animations: [
trigger('dropDownAnimation', [
state('hidden', style({
opacity: 0,
display: 'none'
})),
state('bottom', style({
opacity: 1,
transform: 'scaleY(1)',
transformOrigin: '0% 0%'
})),
state('top', style({
opacity: 1,
transform: 'scaleY(1)',
transformOrigin: '0% 100%'
})),
transition('hidden => bottom', [
style({
opacity: 0,
transform: 'scaleY(0.8)',
transformOrigin: '0% 0%'
}),
animate('100ms cubic-bezier(0.755, 0.05, 0.855, 0.06)')
]),
transition('bottom => hidden', [
animate('100ms cubic-bezier(0.755, 0.05, 0.855, 0.06)', style({
opacity: 0,
transform: 'scaleY(0.8)',
transformOrigin: '0% 0%'
}))
]),
transition('hidden => top', [
style({
opacity: 0,
transform: 'scaleY(0.8)',
transformOrigin: '0% 100%'
}),
animate('100ms cubic-bezier(0.755, 0.05, 0.855, 0.06)')
]),
transition('top => hidden', [
animate('100ms cubic-bezier(0.755, 0.05, 0.855, 0.06)', style({
opacity: 0,
transform: 'scaleY(0.8)',
transformOrigin: '0% 100%'
}))
])
])
],
template: "<div\n cdkOverlayOrigin\n class=\"ant-select-selection\"\n [class.ant-select-selection--single]=\"isSingleMode\"\n [class.ant-select-selection--multiple]=\"isMultipleOrTags\"\n (keydown)=\"onKeyDownCdkOverlayOrigin($event)\"\n tabindex=\"0\">\n <div\n nz-select-top-control\n [nzOpen]=\"nzOpen\"\n [compareWith]=\"compareWith\"\n [nzPlaceHolder]=\"nzPlaceHolder\"\n [nzShowSearch]=\"nzShowSearch\"\n [nzDisabled]=\"nzDisabled\"\n [nzMode]=\"nzMode\"\n [nzListTemplateOfOption]=\"listOfTemplateOption\"\n [nzListOfSelectedValue]=\"listOfSelectedValue\"\n (nzOnSearch)=\"onSearch($event.value,$event.emit)\"\n (nzListOfSelectedValueChange)=\"updateListOfSelectedValueFromTopControl($event)\">\n </div>\n <span *ngIf=\"nzAllowClear\" class=\"ant-select-selection__clear\" nz-select-unselectable (click)=\"onClearSelection($event)\">\n <i nz-icon type=\"close-circle\" theme=\"fill\" class=\"ant-select-close-icon\"></i>\n </span>\n <span class=\"ant-select-arrow\" nz-select-unselectable>\n <i nz-icon type=\"down\" class=\"ant-select-arrow-icon\"></i>\n <b></b>\n </span>\n</div>\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayOrigin]=\"cdkOverlayOrigin\"\n (backdropClick)=\"closeDropDown()\"\n (detach)=\"closeDropDown();\"\n (positionChange)=\"onPositionChange($event)\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"!isDestroy\">\n <div [ngClass]=\"dropDownClassMap\" [@dropDownAnimation]=\"nzOpen ? dropDownPosition : 'hidden' \" [ngStyle]=\"nzDropdownStyle\">\n <div\n style=\"overflow: auto\"\n nz-option-container\n [listOfNzOptionComponent]=\"listOfNzOptionComponent\"\n [listOfNzOptionGroupComponent]=\"listOfNzOptionGroupComponent\"\n [nzSearchValue]=\"searchValue\"\n [nzFilterOption]=\"nzFilterOption\"\n [nzServerSearch]=\"nzServerSearch\"\n [compareWith]=\"compareWith\"\n [nzNotFoundContent]=\"nzNotFoundContent\"\n [nzMaxMultipleCount]=\"nzMaxMultipleCount\"\n [nzMode]=\"nzMode\"\n (nzScrollToBottom)=\"nzScrollToBottom.emit()\"\n (nzClickOption)=\"onClickOptionFromOptionContainer()\"\n (nzListOfTemplateOptionChange)=\"listOfTemplateOptionChange($event)\"\n (nzListOfSelectedValueChange)=\"updateListOfSelectedValueFromOptionContainer($event)\"\n [nzListOfSelectedValue]=\"listOfSelectedValue\">\n </div>\n </div>\n</ng-template>\n<!--can not use ViewChild since it will match sub options in option group -->\n<ng-template>\n <ng-content></ng-content>\n</ng-template>",
host: {
'[class.ant-select]': 'true',
'[class.ant-select-lg]': 'nzSize==="large"',
'[class.ant-select-sm]': 'nzSize==="small"',
'[class.ant-select-enabled]': '!nzDisabled',
'[class.ant-select-disabled]': 'nzDisabled',
'[class.ant-select-allow-clear]': 'nzAllowClear',
'[class.ant-select-open]': 'nzOpen'
},
styles: [`
.ant-select-dropdown {
top: 100%;
left: 0;
position: relative;
width: 100%;
margin-top: 4px;
margin-bottom: 4px;
}
`]
}] }
];
/** @nocollapse */
NzSelectComponent.ctorParameters = () => [
{ type: Renderer2 }
];
NzSelectComponent.propDecorators = {
cdkOverlayOrigin: [{ type: ViewChild, args: [CdkOverlayOrigin,] }],
cdkConnectedOverlay: [{ type: ViewChild, args: [CdkConnectedOverlay,] }],
nzSelectTopControlComponent: [{ type: ViewChild, args: [NzSelectTopControlComponent,] }],
nzOptionContainerComponent: [{ type: ViewChild, args: [NzOptionContainerComponent,] }],
listOfNzOptionComponent: [{ type: ContentChildren, args: [NzOptionComponent,] }],
listOfNzOptionGroupComponent: [{ type: ContentChildren, args: [NzOptionGroupComponent,] }],
nzOnSearch: [{ type: Output }],
nzScrollToBottom: [{ type: Output }],
nzOpenChange: [{ type: Output }],
nzSize: [{ type: Input }],
nzServerSearch: [{ type: Input }],
nzMode: [{ type: Input }],
nzDropdownMatchSelectWidth: [{ type: Input }],
nzFilterOption: [{ type: Input }],
nzMaxMultipleCount: [{ type: Input }],
nzDropdownStyle: [{ type: Input }],
nzNotFoundContent: [{ type: Input }],
compareWith: [{ type: Input }],
nzDropdownClassName: [{ type: Input }],
nzAutoFocus: [{ type: Input }],
nzOpen: [{ type: Input }],
nzDisabled: [{ type: Input }],
nzAllowClear: [{ type: Input }],
nzShowSearch: [{ type: Input }],
nzPlaceHolder: [{ type: Input }],
onClick: [{ type: HostListener, args: ['click',] }],
_handleKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }]
};
function NzSelectComponent_tsickle_Closure_declarations() {
/** @type {?} */
NzSelectComponent.prototype._disabled;
/** @type {?} */
NzSelectComponent.prototype._allowClear;
/** @type {?} */
NzSelectComponent.prototype._showSearch;
/** @type {?} */
NzSelectComponent.prototype._open;
/** @type {?} */
NzSelectComponent.prototype._placeholder;
/** @type {?} */
NzSelectComponent.prototype._autoFocus;
/** @type {?} */
NzSelectComponent.prototype._dropdownClassName;
/** @type {?} */
NzSelectComponent.prototype.onChange;
/** @type {?} */
NzSelectComponent.prototype.onTouched;
/** @type {?} */
NzSelectComponent.prototype.dropDownPosition;
/** @type {?} */
NzSelectComponent.prototype.listOfSelectedValue;
/** @type {?} */
NzSelectComponent.prototype.listOfTemplateOption;
/** @type {?} */
NzSelectComponent.prototype.value;
/** @type {?} */
NzSelectComponent.prototype.overlayWidth;
/** @type {?} */
NzSelectComponent.prototype.overlayMinWidth;
/** @type {?} */
NzSelectComponent.prototype.searchValue;
/** @type {?} */
NzSelectComponent.prototype.isDestroy;
/** @type {?} */
NzSelectComponent.prototype.isInit;
/** @type {?} */
NzSelectComponent.prototype.dropDownClassMap;
/** @type {?} */
NzSelectComponent.prototype.cdkOverlayOrigin;
/** @type {?} */
NzSelectComponent.prototype.cdkConnectedOverlay;
/** @type {?} */
NzSelectComponent.prototype.nzSelectTopControlComponent;
/** @type {?} */
NzSelectComponent.prototype.nzOptionContainerComponent;
/**
* should move to nz-option-container when https://github.com/angular/angular/issues/20810 resolved *
* @type {?}
*/
NzSelectComponent.prototype.listOfNzOptionComponent;
/** @type {?} */
NzSelectComponent.prototype.listOfNzOptionGroupComponent;
/** @type {?} */
NzSelectComponent.prototype.nzOnSearch;
/** @type {?} */
NzSelectComponent.prototype.nzScrollToBottom;
/** @type {?} */
NzSelectComponent.prototype.nzOpenChange;
/** @type {?} */
NzSelectComponent.prototype.nzSize;
/** @type {?} */
NzSelectComponent.prototype.nzServerSearch;
/** @type {?} */
NzSelectComponent.prototype.nzMode;
/** @type {?} */
NzSelectComponent.prototype.nzDropdownMatchSelectWidth;
/** @type {?} */
NzSelectComponent.prototype.nzFilterOption;
/** @type {?} */
NzSelectComponent.prototype.nzMaxMultipleCount;
/** @type {?} */
NzSelectComponent.prototype.nzDropdownStyle;
/** @type {?} */
NzSelectComponent.prototype.nzNotFoundContent;
/**
* https://github.com/angular/angular/pull/13349/files *
* @type {?}
*/
NzSelectComponent.prototype.compareWith;
/** @type {?} */
NzSelectComponent.prototype.renderer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnotc2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3NvbGFyLW5nLXpvcnJvLWFudGQvIiwic291cmNlcyI6WyJzZWxlY3Qvbnotc2VsZWN0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNMLE9BQU8sRUFDUCxLQUFLLEVBQ0wsS0FBSyxFQUNMLFVBQVUsRUFDVixPQUFPLEVBQ1IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsZ0JBQWdCLEVBQWtDLE1BQU0sc0JBQXNCLENBQUM7QUFDN0csT0FBTyxFQUNMLFVBQVUsRUFFVixTQUFTLEVBQ1QsZUFBZSxFQUNmLFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDN0UsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLG1CQUFtQixFQUFpQixNQUFNLGtCQUFrQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBaUZoRixNQUFNOzs7O0lBdVZKLFlBQW9CLFFBQW1CO1FBQW5CLGFB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RUFBSyxZQUFZO29CQUM5QyxnQ0FBZ0MsRUFBRSxjQUFjO29CQUNoRCx5QkFBeUIsRUFBUyxRQUFRO2lCQUMzQzt5QkFDc0I7Ozs7Ozs7OztHQVN0QjthQUNGOzs7O1lBM0ZDLFNBQVM7OzsrQkFrSFIsU0FBUyxTQUFDLGdCQUFnQjtrQ0FDMUIsU0FBUyxTQUFDLG1CQUFtQjswQ0FDN0IsU0FBUyxTQUFDLDJCQUEyQjt5Q0FDckMsU0FBUyxTQUFDLDBCQUEwQjtzQ0FFcEMsZUFBZSxTQUFDLGlCQUFpQjsyQ0FDakMsZUFBZSxTQUFDLHNCQUFzQjt5QkFDdEMsTUFBTTsrQkFDTixNQUFNOzJCQUNOLE1BQU07cUJBQ04sS0FBSzs2QkFDTCxLQUFLO3FCQUNMLEtBQUs7eUNBQ0wsS0FBSzs2QkFDTCxLQUFLO2lDQUNMLEtBQUs7OEJBQ0wsS0FBSztnQ0FDTCxLQUFLOzBCQUdMLEtBQUs7a0NBRUwsS0FBSzswQkFVTCxLQUFLO3FCQVVMLEtBQUs7eUJBb0NMLEtBQUs7MkJBWUwsS0FBSzsyQkFTTCxLQUFLOzRCQVNMLEtBQUs7c0JBU0wsWUFBWSxTQUFDLE9BQU87NkJBUXBCLFlBQVksU0FBQyxTQUFTLEVBQUUsQ0FBRSxRQUFRLENBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBhbmltYXRlLFxuICBzdGF0ZSxcbiAgc3R5bGUsXG4gIHRyYW5zaXRpb24sXG4gIHRyaWdnZXJcbn0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBET1dOX0FSUk9XLCBTUEFDRSwgVEFCIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IENka0Nvbm5lY3RlZE92ZXJsYXksIENka092ZXJsYXlPcmlnaW4sIENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7XG4gIGZvcndhcmRSZWYsXG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2UsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGlzTm90TmlsIH0gZnJvbSAnLi4vY29yZS91dGlsL2NoZWNrJztcbmltcG9ydCB7IHRvQm9vbGVhbiB9IGZyb20gJy4uL2NvcmUvdXRpbC9jb252ZXJ0JztcbmltcG9ydCB7IE56T3B0aW9uQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9uei1vcHRpb24tY29udGFpbmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOek9wdGlvbkdyb3VwQ29tcG9uZW50IH0gZnJvbSAnLi9uei1vcHRpb24tZ3JvdXAuY29tcG9uZW50JztcbmltcG9ydCB7IE56T3B0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9uei1vcHRpb24uY29tcG9uZW50JztcbmltcG9ydCB7IGRlZmF1bHRGaWx0ZXJPcHRpb24sIFRGaWx0ZXJPcHRpb24gfSBmcm9tICcuL256LW9wdGlvbi5waXBlJztcbmltcG9ydCB7IE56U2VsZWN0VG9wQ29udHJvbENvbXBvbmVudCB9IGZyb20gJy4vbnotc2VsZWN0LXRvcC1jb250cm9sLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvciAgICAgICAgICAgOiAnbnotc2VsZWN0JyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHByb3ZpZGVycyAgICAgICAgICA6IFtcbiAgICB7XG4gICAgICBwcm92aWRlICAgIDogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOelNlbGVjdENvbXBvbmVudCksXG4gICAgICBtdWx0aSAgICAgIDogdHJ1ZVxuICAgIH1cbiAgXSxcbiAgYW5pbWF0aW9ucyAgICAgICAgIDogW1xuICAgIHRyaWdnZXIoJ2Ryb3BEb3duQW5pbWF0aW9uJywgW1xuICAgICAgc3RhdGUoJ2hpZGRlbicsIHN0eWxlKHtcbiAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICB9KSksXG4gICAgICBzdGF0ZSgnYm90dG9tJywgc3R5bGUoe1xuICAgICAgICBvcGFjaXR5ICAgICAgICA6IDEsXG4gICAgICAgIHRyYW5zZm9ybSAgICAgIDogJ3NjYWxlWSgxKScsXG4gICAgICAgIHRyYW5zZm9ybU9yaWdpbjogJzAlIDAlJ1xuICAgICAgfSkpLFxuICAgICAgc3RhdGUoJ3RvcCcsIHN0eWxlKHtcbiAgICAgICAgb3BhY2l0eSAgICAgICAgOiAxLFxuICAgICAgICB0cmFuc2Zvcm0gICAgICA6ICdzY2FsZVkoMSknLFxuICAgICAgICB0cmFuc2Zvcm1PcmlnaW46ICcwJSAxMDAlJ1xuICAgICAgfSkpLFxuICAgICAgdHJhbnNpdGlvbignaGlkZGVuID0+IGJvdHRvbScsIFtcbiAgICAgICAgc3R5bGUoe1xuICAgICAgICAgIG9wYWNpdHkgICAgICAgIDogMCxcbiAgICAgICAgICB0cmFuc2Zvcm0gICAgICA6ICdzY2FsZVkoMC44KScsXG4gICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiAnMCUgMCUnXG4gICAgICAgIH0pLFxuICAgICAgICBhbmltYXRlKCcxMDBtcyBjdWJpYy1iZXppZXIoMC43NTUsIDAuMDUsIDAuODU1LCAwLjA2KScpXG4gICAgICBdKSxcbiAgICAgIHRyYW5zaXRpb24oJ2JvdHRvbSA9PiBoaWRkZW4nLCBbXG4gICAgICAgIGFuaW1hdGUoJzEwMG1zIGN1YmljLWJlemllcigwLjc1NSwgMC4wNSwgMC44NTUsIDAuMDYpJywgc3R5bGUoe1xuICAgICAgICAgIG9wYWNpdHkgICAgICAgIDogMCxcbiAgICAgICAgICB0cmFuc2Zvcm0gICAgICA6ICdzY2FsZVkoMC44KScsXG4gICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiAnMCUgMCUnXG4gICAgICAgIH0pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCdoaWRkZW4gPT4gdG9wJywgW1xuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgb3BhY2l0eSAgICAgICAgOiAwLFxuICAgICAgICAgIHRyYW5zZm9ybSAgICAgIDogJ3NjYWxlWSgwLjgpJyxcbiAgICAgICAgICB0cmFuc2Zvcm1PcmlnaW46ICcwJSAxMDAlJ1xuICAgICAgICB9KSxcbiAgICAgICAgYW5pbWF0ZSgnMTAwbXMgY3ViaWMtYmV6aWVyKDAuNzU1LCAwLjA1LCAwLjg1NSwgMC4wNiknKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCd0b3AgPT4gaGlkZGVuJywgW1xuICAgICAgICBhbmltYXRlKCcxMDBtcyBjdWJpYy1iZXppZXIoMC43NTUsIDAuMDUsIDAuODU1LCAwLjA2KScsIHN0eWxlKHtcbiAgICAgICAgICBvcGFjaXR5ICAgICAgICA6IDAsXG4gICAgICAgICAgdHJhbnNmb3JtICAgICAgOiAnc2NhbGVZKDAuOCknLFxuICAgICAgICAgIHRyYW5zZm9ybU9yaWdpbjogJzAlIDEwMCUnXG4gICAgICAgIH0pKVxuICAgICAgXSlcbiAgICBdKVxuICBdLFxuICB0ZW1wbGF0ZVVybCAgICAgICAgOiAnLi9uei1zZWxlY3QuY29tcG9uZW50Lmh0bWwnLFxuICBob3N0ICAgICAgICAgICAgICAgOiB7XG4gICAgJ1tjbGFzcy5hbnQtc2VsZWN0XScgICAgICAgICAgICA6ICd0cnVlJyxcbiAgICAnW2NsYXNzLmFudC1zZWxlY3QtbGddJyAgICAgICAgIDogJ256U2l6ZT09PVwibGFyZ2VcIicsXG4gICAgJ1tjbGFzcy5hbnQtc2VsZWN0LXNtXScgICAgICAgICA6ICduelNpemU9PT1cInNtYWxsXCInLFxuICAgICdbY2xhc3MuYW50LXNlbGVjdC1lbmFibGVkXScgICAgOiAnIW56RGlzYWJsZWQnLFxuICAgICdbY2xhc3MuYW50LXNlbGVjdC1kaXNhYmxlZF0nICAgOiAnbnpEaXNhYmxlZCcsXG4gICAgJ1tjbGFzcy5hbnQtc2VsZWN0LWFsbG93LWNsZWFyXSc6ICduekFsbG93Q2xlYXInLFxuICAgICdbY2xhc3MuYW50LXNlbGVjdC1vcGVuXScgICAgICAgOiAnbnpPcGVuJ1xuICB9LFxuICBzdHlsZXMgICAgICAgICAgICAgOiBbIGBcbiAgICAuYW50LXNlbGVjdC1kcm9wZG93biB7XG4gICAgICB0b3A6IDEwMCU7XG4gICAgICBsZWZ0OiAwO1xuICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBtYXJnaW4tdG9wOiA0cHg7XG4gICAgICBtYXJnaW4tYm90dG9tOiA0cHg7XG4gICAgfVxuICBgIF1cbn0pXG5leHBvcnQgY2xhc3MgTnpTZWxlY3RDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9kaXNhYmxlZCA9IGZhbHNlO1xuICBwcml2YXRlIF9hbGxvd0NsZWFyID0gZmFsc2U7XG4gIHByaXZhdGUgX3Nob3dTZWFyY2ggPSBmYWxzZTtcbiAgcHJpdmF0ZSBfb3BlbiA9IGZhbHNlO1xuICBwcml2YXRlIF9wbGFjZWhvbGRlcjogc3RyaW5nO1xuICBwcml2YXRlIF9hdXRvRm9jdXMgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfZHJvcGRvd25DbGFzc05hbWU6IHN0cmluZztcbiAgb25DaGFuZ2U6ICh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10pID0+IHZvaWQgPSAoKSA9PiBudWxsO1xuICBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiBudWxsO1xuICBkcm9wRG93blBvc2l0aW9uOiAndG9wJyB8ICdjZW50ZXInIHwgJ2JvdHRvbScgPSAnYm90dG9tJztcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBsaXN0T2ZTZWxlY3RlZFZhbHVlOiBhbnlbXSA9IFtdO1xuICBsaXN0T2ZUZW1wbGF0ZU9wdGlvbjogTnpPcHRpb25Db21wb25lbnRbXSA9IFtdO1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIHZhbHVlOiBhbnkgfCBhbnlbXTtcbiAgb3ZlcmxheVdpZHRoOiBudW1iZXI7XG4gIG92ZXJsYXlNaW5XaWR0aDogbnVtYmVyO1xuICBzZWFyY2hWYWx1ZTogc3RyaW5nID0gJyc7XG4gIGlzRGVzdHJveSA9IHRydWU7XG4gIGlzSW5pdCA9IGZhbHNlO1xuICBkcm9wRG93bkNsYXNzTWFwO1xuICBAVmlld0NoaWxkKENka092ZXJsYXlPcmlnaW4pIGNka092ZXJsYXlPcmlnaW46IENka092ZXJsYXlPcmlnaW47XG4gIEBWaWV3Q2hpbGQoQ2RrQ29ubmVjdGVkT3ZlcmxheSkgY2RrQ29ubmVjdGVkT3ZlcmxheTogQ2RrQ29ubmVjdGVkT3ZlcmxheTtcbiAgQFZpZXdDaGlsZChOelNlbGVjdFRvcENvbnRyb2xDb21wb25lbnQpIG56U2VsZWN0VG9wQ29udHJvbENvbXBvbmVudDogTnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50O1xuICBAVmlld0NoaWxkKE56T3B0aW9uQ29udGFpbmVyQ29tcG9uZW50KSBuek9wdGlvbkNvbnRhaW5lckNvbXBvbmVudDogTnpPcHRpb25Db250YWluZXJDb21wb25lbnQ7XG4gIC8qKiBzaG91bGQgbW92ZSB0byBuei1vcHRpb24tY29udGFpbmVyIHdoZW4gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMjA4MTAgcmVzb2x2ZWQgKiovXG4gIEBDb250ZW50Q2hpbGRyZW4oTnpPcHRpb25Db21wb25lbnQpIGxpc3RPZk56T3B0aW9uQ29tcG9uZW50OiBRdWVyeUxpc3Q8TnpPcHRpb25Db21wb25lbnQ+O1xuICBAQ29udGVudENoaWxkcmVuKE56T3B0aW9uR3JvdXBDb21wb25lbnQpIGxpc3RPZk56T3B0aW9uR3JvdXBDb21wb25lbnQ6IFF1ZXJ5TGlzdDxOek9wdGlvbkdyb3VwQ29tcG9uZW50PjtcbiAgQE91dHB1dCgpIG56T25TZWFyY2ggPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIG56U2Nyb2xsVG9Cb3R0b20gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBuek9wZW5DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gIEBJbnB1dCgpIG56U2l6ZSA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgbnpTZXJ2ZXJTZWFyY2ggPSBmYWxzZTtcbiAgQElucHV0KCkgbnpNb2RlOiAnZGVmYXVsdCcgfCAnbXVsdGlwbGUnIHwgJ3RhZ3MnID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBuekRyb3Bkb3duTWF0Y2hTZWxlY3RXaWR0aCA9IHRydWU7XG4gIEBJbnB1dCgpIG56RmlsdGVyT3B0aW9uOiBURmlsdGVyT3B0aW9uID0gZGVmYXVsdEZpbHRlck9wdGlvbjtcbiAgQElucHV0KCkgbnpNYXhNdWx0aXBsZUNvdW50ID0gSW5maW5pdHk7XG4gIEBJbnB1dCgpIG56RHJvcGRvd25TdHlsZTogeyBbIGtleTogc3RyaW5nIF06IHN0cmluZzsgfTtcbiAgQElucHV0KCkgbnpOb3RGb3VuZENvbnRlbnQ6IHN0cmluZztcbiAgLyoqIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvcHVsbC8xMzM0OS9maWxlcyAqKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIEBJbnB1dCgpIGNvbXBhcmVXaXRoID0gKG8xOiBhbnksIG8yOiBhbnkpID0+IG8xID09PSBvMjtcblxuICBASW5wdXQoKVxuICBzZXQgbnpEcm9wZG93bkNsYXNzTmFtZSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fZHJvcGRvd25DbGFzc05hbWUgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZURyb3BEb3duQ2xhc3NNYXAoKTtcbiAgfVxuXG4gIGdldCBuekRyb3Bkb3duQ2xhc3NOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2Ryb3Bkb3duQ2xhc3NOYW1lO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IG56QXV0b0ZvY3VzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fYXV0b0ZvY3VzID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgICB0aGlzLnVwZGF0ZUF1dG9Gb2N1cygpO1xuICB9XG5cbiAgZ2V0IG56QXV0b0ZvY3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9hdXRvRm9jdXM7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgbnpPcGVuKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fb3BlbiA9IHZhbHVlO1xuICAgIHRoaXMuaGFuZGxlRXNjQnVnKCk7XG4gICAgdGhpcy51cGRhdGVDZGtDb25uZWN0ZWRPdmVybGF5U3RhdHVzKCk7XG4gICAgdGhpcy51cGRhdGVEcm9wRG93bkNsYXNzTWFwKCk7XG4gICAgaWYgKHRoaXMubnpPcGVuKSB7XG4gICAgICBpZiAodGhpcy5uelNlbGVjdFRvcENvbnRyb2xDb21wb25lbnQpIHtcbiAgICAgICAgdGhpcy5uelNlbGVjdFRvcENvbnRyb2xDb21wb25lbnQuZm9jdXNPbklucHV0KCk7XG4gICAgICAgIHRoaXMubnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50LnNldElucHV0VmFsdWUoJycsIHRydWUpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMubnpPcHRpb25Db250YWluZXJDb21wb25lbnQpIHtcbiAgICAgICAgdGhpcy5uek9wdGlvbkNvbnRhaW5lckNvbXBvbmVudC5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheSAmJiB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZikge1xuICAgICAgICB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZi51cGRhdGVQb3NpdGlvbigpO1xuICAgICAgICBjb25zdCBiYWNrZHJvcEVsZW1lbnQgPSB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZi5iYWNrZHJvcEVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHBhcmVudE5vZGUgPSB0aGlzLnJlbmRlcmVyLnBhcmVudE5vZGUoYmFja2Ryb3BFbGVtZW50KTtcbiAgICAgICAgY29uc3QgaG9zdEVsZW1lbnQgPSB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZi5ob3N0RWxlbWVudDtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZChwYXJlbnROb2RlLCBiYWNrZHJvcEVsZW1lbnQpO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHBhcmVudE5vZGUsIGhvc3RFbGVtZW50KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMubnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50KSB7XG4gICAgICAgIHRoaXMubnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50LnNldElucHV0VmFsdWUoJycsIGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm56T3B0aW9uQ29udGFpbmVyQ29tcG9uZW50KSB7XG4gICAgICAgIHRoaXMubnpPcHRpb25Db250YWluZXJDb21wb25lbnQucmVzZXRBY3RpdmVPcHRpb24oKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgbnpPcGVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9vcGVuO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IG56RGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9kaXNhYmxlZCA9IHRvQm9vbGVhbih2YWx1ZSk7XG4gICAgaWYgKHRoaXMubnpEaXNhYmxlZCkge1xuICAgICAgdGhpcy5jbG9zZURyb3BEb3duKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IG56RGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IG56QWxsb3dDbGVhcih2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2FsbG93Q2xlYXIgPSB0b0Jvb2xlYW4odmFsdWUpO1xuICB9XG5cbiAgZ2V0IG56QWxsb3dDbGVhcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsb3dDbGVhcjtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCBuelNob3dTZWFyY2godmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9zaG93U2VhcmNoID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIGdldCBuelNob3dTZWFyY2goKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3Nob3dTZWFyY2g7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgbnpQbGFjZUhvbGRlcih2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fcGxhY2Vob2xkZXIgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBuelBsYWNlSG9sZGVyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3BsYWNlaG9sZGVyO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snKVxuICBvbkNsaWNrKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5uekRpc2FibGVkKSB7XG4gICAgICB0aGlzLm56T3BlbiA9ICF0aGlzLm56T3BlbjtcbiAgICAgIHRoaXMubnpPcGVuQ2hhbmdlLmVtaXQodGhpcy5uek9wZW4pO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24nLCBbICckZXZlbnQnIF0pXG4gIF9oYW5kbGVLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2Rpc2FibGVkKSB7IHJldHVybjsgfVxuXG4gICAgY29uc3Qga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7XG5cbiAgICBpZiAoIXRoaXMuX29wZW4pIHtcbiAgICAgIGlmIChrZXlDb2RlID09PSBTUEFDRSB8fCBrZXlDb2RlID09PSBET1dOX0FSUk9XKSB7XG4gICAgICAgIHRoaXMubnpPcGVuID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5uek9wZW5DaGFuZ2UuZW1pdCh0aGlzLm56T3Blbik7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChrZXlDb2RlID09PSBUQUIpIHtcbiAgICAgIC8vIGlmIChrZXlDb2RlID09PSBTUEFDRSB8fCBrZXlDb2RlID09PSBUQUIpIHsgLy8gIzIyMDFcbiAgICAgICAgdGhpcy5uek9wZW4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5uek9wZW5DaGFuZ2UuZW1pdCh0aGlzLm56T3Blbik7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQXV0b0ZvY3VzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzSW5pdCAmJiB0aGlzLm56U2VsZWN0VG9wQ29udHJvbENvbXBvbmVudC5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIGlmICh0aGlzLm56QXV0b0ZvY3VzKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMubnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50LmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LCAnYXV0b2ZvY3VzJywgJ2F1dG9mb2N1cycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVBdHRyaWJ1dGUodGhpcy5uelNlbGVjdFRvcENvbnRyb2xDb21wb25lbnQuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsICdhdXRvZm9jdXMnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb2N1cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uelNlbGVjdFRvcENvbnRyb2xDb21wb25lbnQuaW5wdXRFbGVtZW50KSB7XG4gICAgICB0aGlzLm56U2VsZWN0VG9wQ29udHJvbENvbXBvbmVudC5pbnB1dEVsZW1lbnQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIGJsdXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50LmlucHV0RWxlbWVudCkge1xuICAgICAgdGhpcy5uelNlbGVjdFRvcENvbnRyb2xDb21wb25lbnQuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuYmx1cigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBvdmVybGF5IGNhbiBub3QgYmUgYWx3YXlzIG9wZW4gLCByZW9wZW4gb3ZlcmxheSBhZnRlciBwcmVzcyBlc2MgKiovXG4gIGhhbmRsZUVzY0J1ZygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uek9wZW4gJiYgdGhpcy5jZGtDb25uZWN0ZWRPdmVybGF5ICYmIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheS5vdmVybGF5UmVmICYmICF0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZi5iYWNrZHJvcEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheS5vcGVuID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheS5uZ09uQ2hhbmdlcyh7IG9wZW46IG5ldyBTaW1wbGVDaGFuZ2UoZmFsc2UsIHRydWUsIGZhbHNlKSB9KTtcbiAgICB9XG4gIH1cblxuICBvbktleURvd25DZGtPdmVybGF5T3JpZ2luKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uek9wdGlvbkNvbnRhaW5lckNvbXBvbmVudCkge1xuICAgICAgdGhpcy5uek9wdGlvbkNvbnRhaW5lckNvbXBvbmVudC5vbktleURvd25VbChlKTtcbiAgICB9XG4gIH1cblxuICBjbG9zZURyb3BEb3duKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm56T3Blbikge1xuICAgICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICAgIHRoaXMubnpPcGVuID0gZmFsc2U7XG4gICAgICB0aGlzLm56T3BlbkNoYW5nZS5lbWl0KHRoaXMubnpPcGVuKTtcbiAgICAgIHRoaXMuYmx1cigpO1xuICAgIH1cbiAgfVxuXG4gIG9uUG9zaXRpb25DaGFuZ2UocG9zaXRpb246IENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSk6IHZvaWQge1xuICAgIHRoaXMuZHJvcERvd25Qb3NpdGlvbiA9IHBvc2l0aW9uLmNvbm5lY3Rpb25QYWlyLm9yaWdpblk7XG4gICAgdGhpcy51cGRhdGVEcm9wRG93bkNsYXNzTWFwKCk7XG4gIH1cblxuICBvbkNsaWNrT3B0aW9uRnJvbU9wdGlvbkNvbnRhaW5lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1NpbmdsZU1vZGUpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wRG93bigpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uek1vZGUgPT09ICd0YWdzJykge1xuICAgICAgdGhpcy5vblNlYXJjaCgnJywgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQ2RrQ29ubmVjdGVkT3ZlcmxheVN0YXR1cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0luaXQgJiYgdGhpcy5uek9wZW4gJiYgdGhpcy5jZGtPdmVybGF5T3JpZ2luKSB7XG4gICAgICBpZiAodGhpcy5uekRyb3Bkb3duTWF0Y2hTZWxlY3RXaWR0aCkge1xuICAgICAgICB0aGlzLm92ZXJsYXlXaWR0aCA9IHRoaXMuY2RrT3ZlcmxheU9yaWdpbi5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XG4gICAgICAgIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheS5vdmVybGF5UmVmLnVwZGF0ZVNpemUoeyB3aWR0aDogdGhpcy5vdmVybGF5V2lkdGggfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm92ZXJsYXlNaW5XaWR0aCA9IHRoaXMuY2RrT3ZlcmxheU9yaWdpbi5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XG4gICAgICAgIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheS5vdmVybGF5UmVmLnVwZGF0ZVNpemUoeyBtaW5XaWR0aDogdGhpcy5vdmVybGF5TWluV2lkdGggfSk7XG4gICAgICB9XG5cbiAgICB9XG4gICAgdGhpcy51cGRhdGVDZGtDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25zKCk7XG4gICAgaWYgKHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheSAmJiB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZiAmJiB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXkub3ZlcmxheVJlZi5iYWNrZHJvcEVsZW1lbnQpIHtcbiAgICAgIGlmICh0aGlzLm56T3Blbikge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheS5vdmVybGF5UmVmLmJhY2tkcm9wRWxlbWVudCwgJ2Rpc3BsYXknKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jZGtDb25uZWN0ZWRPdmVybGF5Lm92ZXJsYXlSZWYuYmFja2Ryb3BFbGVtZW50LCAnZGlzcGxheScsICdub25lJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQ2RrQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9ucygpOiB2b2lkIHtcbiAgICAvKiogd2FpdCBmb3IgaW5wdXQgc2l6ZSBjaGFuZ2UgKiovXG4gICAgLy8gRklYTUUg0YPQsdGA0LDQuyDRgtCw0Log0LrQsNC6INGB0LXQu9C10LrRgtGLINC90LUg0LzQtdC90Y/RjtGCINC90LDQv9GA0LDQstC70LXQvdC40LUg0LrQvtCz0LTQsCDQvdC1INCy0LvRj9C30Y/RglxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jZGtDb25uZWN0ZWRPdmVybGF5Lm92ZXJsYXlSZWYudXBkYXRlUG9zaXRpb24oKSwgMTYwKTtcbiAgfVxuXG4gIGdldCBpc1NpbmdsZU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubnpNb2RlID09PSAnZGVmYXVsdCc7XG4gIH1cblxuICBnZXQgaXNNdWx0aXBsZU9yVGFncygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uek1vZGUgPT09ICd0YWdzJyB8fCB0aGlzLm56TW9kZSA9PT0gJ211bHRpcGxlJztcbiAgfVxuXG4gIC8qKiBvcHRpb24gY29udGFpbmVyIG56TGlzdE9mU2VsZWN0ZWRWYWx1ZUNoYW5nZSAtPiB1cGRhdGUgbmdNb2RlbCAqKi9cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICB1cGRhdGVMaXN0T2ZTZWxlY3RlZFZhbHVlRnJvbU9wdGlvbkNvbnRhaW5lcih2YWx1ZTogYW55W10pOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyU2VhcmNoVmFsdWUoKTtcbiAgICB0aGlzLnVwZGF0ZUZyb21TZWxlY3RlZExpc3QodmFsdWUpO1xuICB9XG5cbiAgLyoqIG9wdGlvbiBjb250YWluZXIgbnpMaXN0T2ZTZWxlY3RlZFZhbHVlQ2hhbmdlIC0+IHVwZGF0ZSBuZ01vZGVsICoqL1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIHVwZGF0ZUxpc3RPZlNlbGVjdGVkVmFsdWVGcm9tVG9wQ29udHJvbCh2YWx1ZTogYW55W10pOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyU2VhcmNoVmFsdWUoKTtcbiAgICB0aGlzLnVwZGF0ZUZyb21TZWxlY3RlZExpc3QodmFsdWUpO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICB1cGRhdGVGcm9tU2VsZWN0ZWRMaXN0KHZhbHVlOiBhbnlbXSk6IHZvaWQge1xuICAgIGxldCBtb2RlbFZhbHVlO1xuICAgIGlmICh0aGlzLmlzU2luZ2xlTW9kZSkge1xuICAgICAgaWYgKHZhbHVlLmxlbmd0aCkge1xuICAgICAgICBtb2RlbFZhbHVlID0gdmFsdWVbIDAgXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZWxWYWx1ZSA9IHZhbHVlO1xuICAgICAgdGhpcy51cGRhdGVDZGtDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25zKCk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlTmdNb2RlbCh2YWx1ZSwgbW9kZWxWYWx1ZSk7XG4gIH1cblxuICBvblNlYXJjaCh2YWx1ZTogc3RyaW5nLCBlbWl0OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKGVtaXQgJiYgKHRoaXMuc2VhcmNoVmFsdWUgIT09IHZhbHVlKSkge1xuICAgICAgdGhpcy5uek9uU2VhcmNoLmVtaXQodmFsdWUpO1xuICAgICAgdGhpcy5zZWFyY2hWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFyTmdNb2RlbCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1NpbmdsZU1vZGUpIHtcbiAgICAgIHRoaXMudXBkYXRlTmdNb2RlbChbXSwgbnVsbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlTmdNb2RlbChbXSwgW10pO1xuICAgIH1cbiAgfVxuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgdXBkYXRlTmdNb2RlbChsaXN0OiBhbnlbXSwgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgdGhpcy5saXN0T2ZTZWxlY3RlZFZhbHVlID0gbGlzdDtcbiAgICBpZiAodmFsdWUgIT09IHRoaXMudmFsdWUpIHtcbiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRoaXMub25DaGFuZ2UodGhpcy52YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgbGlzdE9mVGVtcGxhdGVPcHRpb25DaGFuZ2UodmFsdWU6IE56T3B0aW9uQ29tcG9uZW50W10pOiB2b2lkIHtcbiAgICB0aGlzLmxpc3RPZlRlbXBsYXRlT3B0aW9uID0gdmFsdWU7XG4gIH1cblxuICB1cGRhdGVEcm9wRG93bkNsYXNzTWFwKCk6IHZvaWQge1xuICAgIHRoaXMuZHJvcERvd25DbGFzc01hcCA9IHtcbiAgICAgIFsgJ2FudC1zZWxlY3QtZHJvcGRvd24nIF0gICAgICAgICAgICAgICAgICAgICA6IHRydWUsXG4gICAgICBbIGBhbnQtc2VsZWN0LWRyb3Bkb3duLS1zaW5nbGVgIF0gICAgICAgICAgICAgOiB0aGlzLmlzU2luZ2xlTW9kZSxcbiAgICAgIFsgYGFudC1zZWxlY3QtZHJvcGRvd24tLW11bHRpcGxlYCBdICAgICAgICAgICA6IHRoaXMuaXNNdWx0aXBsZU9yVGFncyxcbiAgICAgIFsgYGFudC1zZWxlY3QtZHJvcGRvd24tcGxhY2VtZW50LWJvdHRvbUxlZnRgIF06IHRoaXMuZHJvcERvd25Qb3NpdGlvbiA9PT0gJ2JvdHRvbScsXG4gICAgICBbIGBhbnQtc2VsZWN0LWRyb3Bkb3duLXBsYWNlbWVudC10b3BMZWZ0YCBdICAgOiB0aGlzLmRyb3BEb3duUG9zaXRpb24gPT09ICd0b3AnLFxuICAgICAgWyBgJHt0aGlzLm56RHJvcGRvd25DbGFzc05hbWV9YCBdICAgICAgICAgICAgIDogISF0aGlzLm56RHJvcGRvd25DbGFzc05hbWVcbiAgICB9O1xuICB9XG5cbiAgb25DbGVhclNlbGVjdGlvbihlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgLy8gVE9ETzogc2hvdWxkIG5vdCBjbGVhciBkaXNhYmxlZCBvcHRpb24gP1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5jbGVhck5nTW9kZWwoKTtcbiAgfVxuXG4gIGNsZWFyU2VhcmNoVmFsdWUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNTaW5nbGVNb2RlKSB7XG4gICAgICB0aGlzLm56U2VsZWN0VG9wQ29udHJvbENvbXBvbmVudC5zZXRJbnB1dFZhbHVlKCcnLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50LnNldElucHV0VmFsdWUoJycsIGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHtcbiAgfVxuXG4gIC8qKiB1cGRhdGUgbmdNb2RlbCAtPiB1cGRhdGUgbGlzdE9mU2VsZWN0ZWRWYWx1ZSAqKi9cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkgfCBhbnlbXSk6IHZvaWQge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICBpZiAoaXNOb3ROaWwodmFsdWUpKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdGhpcy5saXN0T2ZTZWxlY3RlZFZhbHVlID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxpc3RPZlNlbGVjdGVkVmFsdWUgPSBbIHZhbHVlIF07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGlzdE9mU2VsZWN0ZWRWYWx1ZSA9IFtdO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10pID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLm56RGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pc0Rlc3Ryb3kgPSBmYWxzZTtcbiAgICB0aGlzLnVwZGF0ZURyb3BEb3duQ2xhc3NNYXAoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmlzSW5pdCA9IHRydWU7XG4gICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB0aGlzLnVwZGF0ZUNka0Nvbm5lY3RlZE92ZXJsYXlTdGF0dXMoKSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmlzRGVzdHJveSA9IHRydWU7XG4gIH1cbn1cbiJdfQ==