@ng-bootstrap/ng-bootstrap
Version:
Angular powered Bootstrap
358 lines • 50.9 kB
JavaScript
import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, forwardRef, inject, Input, NgZone, Output, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { DOCUMENT } from '@angular/common';
import { BehaviorSubject, fromEvent, of, Subject } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
import { Live } from '../util/accessibility/live';
import { ngbAutoClose } from '../util/autoclose';
import { Key } from '../util/key';
import { PopupService } from '../util/popup';
import { ngbPositioning } from '../util/positioning';
import { isDefined, toString } from '../util/util';
import { NgbTypeaheadConfig } from './typeahead-config';
import { NgbTypeaheadWindow } from './typeahead-window';
import { addPopperOffset } from '../util/positioning-util';
import * as i0 from "@angular/core";
let nextWindowId = 0;
/**
* A directive providing a simple way of creating powerful typeaheads from any text input.
*/
export class NgbTypeahead {
constructor() {
this._nativeElement = inject(ElementRef).nativeElement;
this._config = inject(NgbTypeaheadConfig);
this._live = inject(Live);
this._document = inject(DOCUMENT);
this._ngZone = inject(NgZone);
this._changeDetector = inject(ChangeDetectorRef);
this._popupService = new PopupService(NgbTypeaheadWindow);
this._positioning = ngbPositioning();
this._subscription = null;
this._closed$ = new Subject();
this._inputValueBackup = null;
this._inputValueForSelectOnExact = null;
this._valueChanges$ = fromEvent(this._nativeElement, 'input').pipe(map(($event) => $event.target.value));
this._resubscribeTypeahead$ = new BehaviorSubject(null);
this._windowRef = null;
/**
* The value for the `autocomplete` attribute for the `<input>` element.
*
* Defaults to `"off"` to disable the native browser autocomplete, but you can override it if necessary.
*
* @since 2.1.0
*/
this.autocomplete = 'off';
/**
* A selector specifying the element the typeahead popup will be appended to.
*
* Currently only supports `"body"`.
*/
this.container = this._config.container;
/**
* If `true`, model values will not be restricted only to items selected from the popup.
*/
this.editable = this._config.editable;
/**
* If `true`, the first item in the result list will always stay focused while typing.
*/
this.focusFirst = this._config.focusFirst;
/**
* If `true`, automatically selects the item when it is the only one that exactly matches the user input
*
* @since 14.2.0
*/
this.selectOnExact = this._config.selectOnExact;
/**
* If `true`, will show the hint in the `<input>` when an item in the result list matches.
*/
this.showHint = this._config.showHint;
/**
* The preferred placement of the typeahead, among the [possible values](#/guides/positioning#api).
*
* The default order of preference is `"bottom-start bottom-end top-start top-end"`
*
* Please see the [positioning overview](#/positioning) for more details.
*/
this.placement = this._config.placement;
/**
* Allows to change default Popper options when positioning the typeahead.
* Receives current popper options and returns modified ones.
*
* @since 13.1.0
*/
this.popperOptions = this._config.popperOptions;
/**
* An event emitted right before an item is selected from the result list.
*
* Event payload is of type [`NgbTypeaheadSelectItemEvent`](#/components/typeahead/api#NgbTypeaheadSelectItemEvent).
*/
this.selectItem = new EventEmitter();
this.activeDescendant = null;
this.popupId = `ngb-typeahead-${nextWindowId++}`;
this._onTouched = () => { };
this._onChange = (_) => { };
}
ngOnInit() {
this._subscribeToUserInput();
}
ngOnChanges({ ngbTypeahead }) {
if (ngbTypeahead && !ngbTypeahead.firstChange) {
this._unsubscribeFromUserInput();
this._subscribeToUserInput();
}
}
ngOnDestroy() {
this._closePopup();
this._unsubscribeFromUserInput();
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
writeValue(value) {
this._writeInputValue(this._formatItemForInput(value));
if (this.showHint) {
this._inputValueBackup = value;
}
}
setDisabledState(isDisabled) {
this._nativeElement.disabled = isDisabled;
}
/**
* Dismisses typeahead popup window
*/
dismissPopup() {
if (this.isPopupOpen()) {
this._resubscribeTypeahead$.next(null);
this._closePopup();
if (this.showHint && this._inputValueBackup !== null) {
this._writeInputValue(this._inputValueBackup);
}
this._changeDetector.markForCheck();
}
}
/**
* Returns true if the typeahead popup window is displayed
*/
isPopupOpen() {
return this._windowRef != null;
}
handleBlur() {
this._resubscribeTypeahead$.next(null);
this._onTouched();
}
handleKeyDown(event) {
if (!this.isPopupOpen()) {
return;
}
/* eslint-disable-next-line deprecation/deprecation */
switch (event.which) {
case Key.ArrowDown:
event.preventDefault();
this._windowRef.instance.next();
this._showHint();
break;
case Key.ArrowUp:
event.preventDefault();
this._windowRef.instance.prev();
this._showHint();
break;
case Key.Enter:
case Key.Tab: {
const result = this._windowRef.instance.getActive();
if (isDefined(result)) {
event.preventDefault();
event.stopPropagation();
this._selectResult(result);
}
this._closePopup();
break;
}
}
}
_openPopup() {
if (!this.isPopupOpen()) {
this._inputValueBackup = this._nativeElement.value;
const { windowRef } = this._popupService.open();
this._windowRef = windowRef;
this._windowRef.setInput('id', this.popupId);
this._windowRef.setInput('popupClass', this.popupClass);
this._windowRef.instance.selectEvent.subscribe((result) => this._selectResultClosePopup(result));
this._windowRef.instance.activeChangeEvent.subscribe((activeId) => (this.activeDescendant = activeId));
if (this.container === 'body') {
this._windowRef.location.nativeElement.style.zIndex = '1055';
this._document.body.appendChild(this._windowRef.location.nativeElement);
}
this._changeDetector.markForCheck();
// Setting up popper and scheduling updates when zone is stable
this._ngZone.runOutsideAngular(() => {
if (this._windowRef) {
this._positioning.createPopper({
hostElement: this._nativeElement,
targetElement: this._windowRef.location.nativeElement,
placement: this.placement,
appendToBody: this.container === 'body',
updatePopperOptions: (options) => this.popperOptions(addPopperOffset([0, 2])(options)),
});
this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positioning.update());
}
});
ngbAutoClose(this._ngZone, this._document, 'outside', () => this.dismissPopup(), this._closed$, [
this._nativeElement,
this._windowRef.location.nativeElement,
]);
}
}
_closePopup() {
this._popupService.close().subscribe(() => {
this._positioning.destroy();
this._zoneSubscription?.unsubscribe();
this._closed$.next();
this._windowRef = null;
this.activeDescendant = null;
});
}
_selectResult(result) {
let defaultPrevented = false;
this.selectItem.emit({
item: result,
preventDefault: () => {
defaultPrevented = true;
},
});
this._resubscribeTypeahead$.next(null);
if (!defaultPrevented) {
this.writeValue(result);
this._onChange(result);
}
}
_selectResultClosePopup(result) {
this._selectResult(result);
this._closePopup();
}
_showHint() {
if (this.showHint && this._windowRef?.instance.hasActive() && this._inputValueBackup != null) {
const userInputLowerCase = this._inputValueBackup.toLowerCase();
const formattedVal = this._formatItemForInput(this._windowRef.instance.getActive());
if (userInputLowerCase === formattedVal.substring(0, this._inputValueBackup.length).toLowerCase()) {
this._writeInputValue(this._inputValueBackup + formattedVal.substring(this._inputValueBackup.length));
this._nativeElement['setSelectionRange'].apply(this._nativeElement, [
this._inputValueBackup.length,
formattedVal.length,
]);
}
else {
this._writeInputValue(formattedVal);
}
}
}
_formatItemForInput(item) {
return item != null && this.inputFormatter ? this.inputFormatter(item) : toString(item);
}
_writeInputValue(value) {
this._nativeElement.value = toString(value);
}
_subscribeToUserInput() {
const results$ = this._valueChanges$.pipe(tap((value) => {
this._inputValueBackup = this.showHint ? value : null;
this._inputValueForSelectOnExact = this.selectOnExact ? value : null;
this._onChange(this.editable ? value : undefined);
}), this.ngbTypeahead ? this.ngbTypeahead : () => of([]));
this._subscription = this._resubscribeTypeahead$.pipe(switchMap(() => results$)).subscribe((results) => {
if (!results || results.length === 0) {
this._closePopup();
}
else {
// when there is only one result and this matches the input value
if (this.selectOnExact &&
results.length === 1 &&
this._formatItemForInput(results[0]) === this._inputValueForSelectOnExact) {
this._selectResult(results[0]);
this._closePopup();
}
else {
this._openPopup();
this._windowRef.setInput('focusFirst', this.focusFirst);
this._windowRef.setInput('results', results);
this._windowRef.setInput('term', this._nativeElement.value);
if (this.resultFormatter) {
this._windowRef.setInput('formatter', this.resultFormatter);
}
if (this.resultTemplate) {
this._windowRef.setInput('resultTemplate', this.resultTemplate);
}
this._windowRef.instance.resetActive();
// The observable stream we are subscribing to might have async steps
// and if a component containing typeahead is using the OnPush strategy
// the change detection turn wouldn't be invoked automatically.
this._windowRef.changeDetectorRef.detectChanges();
this._showHint();
}
}
// live announcer
const count = results ? results.length : 0;
this._live.say(count === 0 ? 'No results available' : `${count} result${count === 1 ? '' : 's'} available`);
});
}
_unsubscribeFromUserInput() {
if (this._subscription) {
this._subscription.unsubscribe();
}
this._subscription = null;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbTypeahead, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbTypeahead, isStandalone: true, selector: "input[ngbTypeahead]", inputs: { autocomplete: "autocomplete", container: "container", editable: "editable", focusFirst: "focusFirst", inputFormatter: "inputFormatter", ngbTypeahead: "ngbTypeahead", resultFormatter: "resultFormatter", resultTemplate: "resultTemplate", selectOnExact: "selectOnExact", showHint: "showHint", placement: "placement", popperOptions: "popperOptions", popupClass: "popupClass" }, outputs: { selectItem: "selectItem" }, host: { attributes: { "autocapitalize": "off", "autocorrect": "off", "role": "combobox" }, listeners: { "blur": "handleBlur()", "keydown": "handleKeyDown($event)" }, properties: { "class.open": "isPopupOpen()", "autocomplete": "autocomplete", "attr.aria-autocomplete": "showHint ? \"both\" : \"list\"", "attr.aria-activedescendant": "activeDescendant", "attr.aria-owns": "isPopupOpen() ? popupId : null", "attr.aria-expanded": "isPopupOpen()" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgbTypeahead), multi: true }], exportAs: ["ngbTypeahead"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbTypeahead, decorators: [{
type: Directive,
args: [{
selector: 'input[ngbTypeahead]',
exportAs: 'ngbTypeahead',
standalone: true,
host: {
'(blur)': 'handleBlur()',
'[class.open]': 'isPopupOpen()',
'(keydown)': 'handleKeyDown($event)',
'[autocomplete]': 'autocomplete',
autocapitalize: 'off',
autocorrect: 'off',
role: 'combobox',
'[attr.aria-autocomplete]': 'showHint ? "both" : "list"',
'[attr.aria-activedescendant]': 'activeDescendant',
'[attr.aria-owns]': 'isPopupOpen() ? popupId : null',
'[attr.aria-expanded]': 'isPopupOpen()',
},
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgbTypeahead), multi: true }],
}]
}], propDecorators: { autocomplete: [{
type: Input
}], container: [{
type: Input
}], editable: [{
type: Input
}], focusFirst: [{
type: Input
}], inputFormatter: [{
type: Input
}], ngbTypeahead: [{
type: Input
}], resultFormatter: [{
type: Input
}], resultTemplate: [{
type: Input
}], selectOnExact: [{
type: Input
}], showHint: [{
type: Input
}], placement: [{
type: Input
}], popperOptions: [{
type: Input
}], popupClass: [{
type: Input
}], selectItem: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWFoZWFkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3R5cGVhaGVhZC90eXBlYWhlYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNOLGlCQUFpQixFQUVqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBSU4sTUFBTSxHQUdOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFvQixPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQy9GLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXJELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVuRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQXlCLE1BQU0sb0JBQW9CLENBQUM7QUFDL0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDOztBQWlCM0QsSUFBSSxZQUFZLEdBQUcsQ0FBQyxD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U0FBUzttQkFBQztvQkFDVixRQUFRLEVBQUUscUJBQXFCO29CQUMvQixRQUFRLEVBQUUsY0FBYztvQkFDeEIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLElBQUksRUFBRTt3QkFDTCxRQUFRLEVBQUUsY0FBYzt3QkFDeEIsY0FBYyxFQUFFLGVBQWU7d0JBQy9CLFdBQVcsRUFBRSx1QkFBdUI7d0JBQ3BDLGdCQUFnQixFQUFFLGNBQWM7d0JBQ2hDLGNBQWMsRUFBRSxLQUFLO3dCQUNyQixXQUFXLEVBQUUsS0FBSzt3QkFDbEIsSUFBSSxFQUFFLFVBQVU7d0JBQ2hCLDBCQUEwQixFQUFFLDRCQUE0Qjt3QkFDeEQsOEJBQThCLEVBQUUsa0JBQWtCO3dCQUNsRCxrQkFBa0IsRUFBRSxnQ0FBZ0M7d0JBQ3BELHNCQUFzQixFQUFFLGVBQWU7cUJBQ3ZDO29CQUNELFNBQVMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLGFBQWEsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztpQkFDckc7OEJBOEJTLFlBQVk7c0JBQXBCLEtBQUs7Z0JBT0csU0FBUztzQkFBakIsS0FBSztnQkFLRyxRQUFRO3NCQUFoQixLQUFLO2dCQUtHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBUUcsY0FBYztzQkFBdEIsS0FBSztnQkFhRyxZQUFZO3NCQUFwQixLQUFLO2dCQVNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBU0csY0FBYztzQkFBdEIsS0FBSztnQkFPRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBU0csU0FBUztzQkFBakIsS0FBSztnQkFRRyxhQUFhO3NCQUFyQixLQUFLO2dCQVdHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBT0ksVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENoYW5nZURldGVjdG9yUmVmLFxuXHRDb21wb25lbnRSZWYsXG5cdERpcmVjdGl2ZSxcblx0RWxlbWVudFJlZixcblx0RXZlbnRFbWl0dGVyLFxuXHRmb3J3YXJkUmVmLFxuXHRpbmplY3QsXG5cdElucHV0LFxuXHROZ1pvbmUsXG5cdE9uQ2hhbmdlcyxcblx0T25EZXN0cm95LFxuXHRPbkluaXQsXG5cdE91dHB1dCxcblx0U2ltcGxlQ2hhbmdlcyxcblx0VGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmcm9tRXZlbnQsIG9mLCBPcGVyYXRvckZ1bmN0aW9uLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IExpdmUgfSBmcm9tICcuLi91dGlsL2FjY2Vzc2liaWxpdHkvbGl2ZSc7XG5pbXBvcnQgeyBuZ2JBdXRvQ2xvc2UgfSBmcm9tICcuLi91dGlsL2F1dG9jbG9zZSc7XG5pbXBvcnQgeyBLZXkgfSBmcm9tICcuLi91dGlsL2tleSc7XG5pbXBvcnQgeyBQb3B1cFNlcnZpY2UgfSBmcm9tICcuLi91dGlsL3BvcHVwJztcbmltcG9ydCB7IG5nYlBvc2l0aW9uaW5nIH0gZnJvbSAnLi4vdXRpbC9wb3NpdGlvbmluZyc7XG5pbXBvcnQgeyBpc0RlZmluZWQsIHRvU3RyaW5nIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcblxuaW1wb3J0IHsgTmdiVHlwZWFoZWFkQ29uZmlnIH0gZnJvbSAnLi90eXBlYWhlYWQtY29uZmlnJztcbmltcG9ydCB7IE5nYlR5cGVhaGVhZFdpbmRvdywgUmVzdWx0VGVtcGxhdGVDb250ZXh0IH0gZnJvbSAnLi90eXBlYWhlYWQtd2luZG93JztcbmltcG9ydCB7IGFkZFBvcHBlck9mZnNldCB9IGZyb20gJy4uL3V0aWwvcG9zaXRpb25pbmctdXRpbCc7XG5cbi8qKlxuICogQW4gZXZlbnQgZW1pdHRlZCByaWdodCBiZWZvcmUgYW4gaXRlbSBpcyBzZWxlY3RlZCBmcm9tIHRoZSByZXN1bHQgbGlzdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZ2JUeXBlYWhlYWRTZWxlY3RJdGVtRXZlbnQ8VCA9IGFueT4ge1xuXHQvKipcblx0ICogVGhlIGl0ZW0gZnJvbSB0aGUgcmVzdWx0IGxpc3QgYWJvdXQgdG8gYmUgc2VsZWN0ZWQuXG5cdCAqL1xuXHRpdGVtOiBUO1xuXG5cdC8qKlxuXHQgKiBDYWxsaW5nIHRoaXMgZnVuY3Rpb24gd2lsbCBwcmV2ZW50IGl0ZW0gc2VsZWN0aW9uIGZyb20gaGFwcGVuaW5nLlxuXHQgKi9cblx0cHJldmVudERlZmF1bHQ6ICgpID0+IHZvaWQ7XG59XG5cbmxldCBuZXh0V2luZG93SWQgPSAwO1xuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHByb3ZpZGluZyBhIHNpbXBsZSB3YXkgb2YgY3JlYXRpbmcgcG93ZXJmdWwgdHlwZWFoZWFkcyBmcm9tIGFueSB0ZXh0IGlucHV0LlxuICovXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdpbnB1dFtuZ2JUeXBlYWhlYWRdJyxcblx0ZXhwb3J0QXM6ICduZ2JUeXBlYWhlYWQnLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHRob3N0OiB7XG5cdFx0JyhibHVyKSc6ICdoYW5kbGVCbHVyKCknLFxuXHRcdCdbY2xhc3Mub3Blbl0nOiAnaXNQb3B1cE9wZW4oKScsXG5cdFx0JyhrZXlkb3duKSc6ICdoYW5kbGVLZXlEb3duKCRldmVudCknLFxuXHRcdCdbYXV0b2NvbXBsZXRlXSc6ICdhdXRvY29tcGxldGUnLFxuXHRcdGF1dG9jYXBpdGFsaXplOiAnb2ZmJyxcblx0XHRhdXRvY29ycmVjdDogJ29mZicsXG5cdFx0cm9sZTogJ2NvbWJvYm94Jyxcblx0XHQnW2F0dHIuYXJpYS1hdXRvY29tcGxldGVdJzogJ3Nob3dIaW50ID8gXCJib3RoXCIgOiBcImxpc3RcIicsXG5cdFx0J1thdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF0nOiAnYWN0aXZlRGVzY2VuZGFudCcsXG5cdFx0J1thdHRyLmFyaWEtb3duc10nOiAnaXNQb3B1cE9wZW4oKSA/IHBvcHVwSWQgOiBudWxsJyxcblx0XHQnW2F0dHIuYXJpYS1leHBhbmRlZF0nOiAnaXNQb3B1cE9wZW4oKScsXG5cdH0sXG5cdHByb3ZpZGVyczogW3sgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5nYlR5cGVhaGVhZCksIG11bHRpOiB0cnVlIH1dLFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JUeXBlYWhlYWQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cdHByaXZhdGUgX25hdGl2ZUVsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZikubmF0aXZlRWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuXHRwcml2YXRlIF9jb25maWcgPSBpbmplY3QoTmdiVHlwZWFoZWFkQ29uZmlnKTtcblx0cHJpdmF0ZSBfbGl2ZSA9IGluamVjdChMaXZlKTtcblx0cHJpdmF0ZSBfZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuXHRwcml2YXRlIF9uZ1pvbmUgPSBpbmplY3QoTmdab25lKTtcblx0cHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3IgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuXG5cdHByaXZhdGUgX3BvcHVwU2VydmljZSA9IG5ldyBQb3B1cFNlcnZpY2UoTmdiVHlwZWFoZWFkV2luZG93KTtcblx0cHJpdmF0ZSBfcG9zaXRpb25pbmcgPSBuZ2JQb3NpdGlvbmluZygpO1xuXG5cdHByaXZhdGUgX3N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgX2Nsb3NlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXHRwcml2YXRlIF9pbnB1dFZhbHVlQmFja3VwOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblx0cHJpdmF0ZSBfaW5wdXRWYWx1ZUZvclNlbGVjdE9uRXhhY3Q6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIF92YWx1ZUNoYW5nZXMkID0gZnJvbUV2ZW50PEV2ZW50Pih0aGlzLl9uYXRpdmVFbGVtZW50LCAnaW5wdXQnKS5waXBlKFxuXHRcdG1hcCgoJGV2ZW50KSA9PiAoJGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZSksXG5cdCk7XG5cdHByaXZhdGUgX3Jlc3Vic2NyaWJlVHlwZWFoZWFkJCA9IG5ldyBCZWhhdmlvclN1YmplY3QobnVsbCk7XG5cdHByaXZhdGUgX3dpbmRvd1JlZjogQ29tcG9uZW50UmVmPE5nYlR5cGVhaGVhZFdpbmRvdz4gfCBudWxsID0gbnVsbDtcblx0cHJpdmF0ZSBfem9uZVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG5cdC8qKlxuXHQgKiBUaGUgdmFsdWUgZm9yIHRoZSBgYXV0b2NvbXBsZXRlYCBhdHRyaWJ1dGUgZm9yIHRoZSBgPGlucHV0PmAgZWxlbWVudC5cblx0ICpcblx0ICogRGVmYXVsdHMgdG8gYFwib2ZmXCJgIHRvIGRpc2FibGUgdGhlIG5hdGl2ZSBicm93c2VyIGF1dG9jb21wbGV0ZSwgYnV0IHlvdSBjYW4gb3ZlcnJpZGUgaXQgaWYgbmVjZXNzYXJ5LlxuXHQgKlxuXHQgKiBAc2luY2UgMi4xLjBcblx0ICovXG5cdEBJbnB1dCgpIGF1dG9jb21wbGV0ZSA9ICdvZmYnO1xuXG5cdC8qKlxuXHQgKiBBIHNlbGVjdG9yIHNwZWNpZnlpbmcgdGhlIGVsZW1lbnQgdGhlIHR5cGVhaGVhZCBwb3B1cCB3aWxsIGJlIGFwcGVuZGVkIHRvLlxuXHQgKlxuXHQgKiBDdXJyZW50bHkgb25seSBzdXBwb3J0cyBgXCJib2R5XCJgLlxuXHQgKi9cblx0QElucHV0KCkgY29udGFpbmVyID0gdGhpcy5fY29uZmlnLmNvbnRhaW5lcjtcblxuXHQvKipcblx0ICogSWYgYHRydWVgLCBtb2RlbCB2YWx1ZXMgd2lsbCBub3QgYmUgcmVzdHJpY3RlZCBvbmx5IHRvIGl0ZW1zIHNlbGVjdGVkIGZyb20gdGhlIHBvcHVwLlxuXHQgKi9cblx0QElucHV0KCkgZWRpdGFibGUgPSB0aGlzLl9jb25maWcuZWRpdGFibGU7XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIHJlc3VsdCBsaXN0IHdpbGwgYWx3YXlzIHN0YXkgZm9jdXNlZCB3aGlsZSB0eXBpbmcuXG5cdCAqL1xuXHRASW5wdXQoKSBmb2N1c0ZpcnN0ID0gdGhpcy5fY29uZmlnLmZvY3VzRmlyc3Q7XG5cblx0LyoqXG5cdCAqIFRoZSBmdW5jdGlvbiB0aGF0IGNvbnZlcnRzIGFuIGl0ZW0gZnJvbSB0aGUgcmVzdWx0IGxpc3QgdG8gYSBgc3RyaW5nYCB0byBkaXNwbGF5IGluIHRoZSBgPGlucHV0PmAgZmllbGQuXG5cdCAqXG5cdCAqIEl0IGlzIGNhbGxlZCB3aGVuIHRoZSB1c2VyIHNlbGVjdHMgc29tZXRoaW5nIGluIHRoZSBwb3B1cCBvciB0aGUgbW9kZWwgdmFsdWUgY2hhbmdlcywgc28gdGhlIGlucHV0IG5lZWRzIHRvXG5cdCAqIGJlIHVwZGF0ZWQuXG5cdCAqL1xuXHRASW5wdXQoKSBpbnB1dEZvcm1hdHRlcjogKGl0ZW06IGFueSkgPT4gc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBUaGUgZnVuY3Rpb24gdGhhdCBjb252ZXJ0cyBhIHN0cmVhbSBvZiB0ZXh0IHZhbHVlcyBmcm9tIHRoZSBgPGlucHV0PmAgZWxlbWVudCB0byB0aGUgc3RyZWFtIG9mIHRoZSBhcnJheSBvZiBpdGVtc1xuXHQgKiB0byBkaXNwbGF5IGluIHRoZSB0eXBlYWhlYWQgcG9wdXAuXG5cdCAqXG5cdCAqIElmIHRoZSByZXN1bHRpbmcgb2JzZXJ2YWJsZSBlbWl0cyBhIG5vbi1lbXB0eSBhcnJheSAtIHRoZSBwb3B1cCB3aWxsIGJlIHNob3duLiBJZiBpdCBlbWl0cyBhbiBlbXB0eSBhcnJheSAtIHRoZVxuXHQgKiBwb3B1cCB3aWxsIGJlIGNsb3NlZC5cblx0ICpcblx0ICogU2VlIHRoZSBbYmFzaWMgZXhhbXBsZV0oIy9jb21wb25lbnRzL3R5cGVhaGVhZC9leGFtcGxlcyNiYXNpYykgZm9yIG1vcmUgZGV0YWlscy5cblx0ICpcblx0ICogTm90ZSB0aGF0IHRoZSBgdGhpc2AgYXJndW1lbnQgaXMgYHVuZGVmaW5lZGAgc28geW91IG5lZWQgdG8gZXhwbGljaXRseSBiaW5kIGl0IHRvIGEgZGVzaXJlZCBcInRoaXNcIiB0YXJnZXQuXG5cdCAqL1xuXHRASW5wdXQoKSBuZ2JUeXBlYWhlYWQ6IE9wZXJhdG9yRnVuY3Rpb248c3RyaW5nLCByZWFkb25seSBhbnlbXT4gfCBudWxsIHwgdW5kZWZpbmVkO1xuXG5cdC8qKlxuXHQgKiBUaGUgZnVuY3Rpb24gdGhhdCBjb252ZXJ0cyBhbiBpdGVtIGZyb20gdGhlIHJlc3VsdCBsaXN0IHRvIGEgYHN0cmluZ2AgdG8gZGlzcGxheSBpbiB0aGUgcG9wdXAuXG5cdCAqXG5cdCAqIE11c3QgYmUgcHJvdmlkZWQsIGlmIHlvdXIgYG5nYlR5cGVhaGVhZGAgcmV0dXJucyBzb21ldGhpbmcgb3RoZXIgdGhhbiBgT2JzZXJ2YWJsZTxzdHJpbmdbXT5gLlxuXHQgKlxuXHQgKiBBbHRlcm5hdGl2ZWx5IGZvciBtb3JlIGNvbXBsZXggbWFya3VwIGluIHRoZSBwb3B1cCB5b3Ugc2hvdWxkIHVzZSBgcmVzdWx0VGVtcGxhdGVgLlxuXHQgKi9cblx0QElucHV0KCkgcmVzdWx0Rm9ybWF0dGVyOiAoaXRlbTogYW55KSA9PiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFRoZSB0ZW1wbGF0ZSB0byBvdmVycmlkZSB0aGUgd2F5IHJlc3VsdGluZyBpdGVtcyBhcmUgZGlzcGxheWVkIGluIHRoZSBwb3B1cC5cblx0ICpcblx0ICogU2VlIHRoZSBbUmVzdWx0VGVtcGxhdGVDb250ZXh0XSgjL2NvbXBvbmVudHMvdHlwZWFoZWFkL2FwaSNSZXN1bHRUZW1wbGF0ZUNvbnRleHQpIGZvciB0aGUgdGVtcGxhdGUgY29udGV4dC5cblx0ICpcblx0ICogQWxzbyBzZWUgdGhlIFt0ZW1wbGF0ZSBmb3IgcmVzdWx0cyBkZW1vXSgjL2NvbXBvbmVudHMvdHlwZWFoZWFkL2V4YW1wbGVzI3RlbXBsYXRlKSBmb3IgbW9yZSBkZXRhaWxzLlxuXHQgKi9cblx0QElucHV0KCkgcmVzdWx0VGVtcGxhdGU6IFRlbXBsYXRlUmVmPFJlc3VsdFRlbXBsYXRlQ29udGV4dD47XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgYXV0b21hdGljYWxseSBzZWxlY3RzIHRoZSBpdGVtIHdoZW4gaXQgaXMgdGhlIG9ubHkgb25lIHRoYXQgZXhhY3RseSBtYXRjaGVzIHRoZSB1c2VyIGlucHV0XG5cdCAqXG5cdCAqIEBzaW5jZSAxNC4yLjBcblx0ICovXG5cdEBJbnB1dCgpIHNlbGVjdE9uRXhhY3QgPSB0aGlzLl9jb25maWcuc2VsZWN0T25FeGFjdDtcblxuXHQvKipcblx0ICogSWYgYHRydWVgLCB3aWxsIHNob3cgdGhlIGhpbnQgaW4gdGhlIGA8aW5wdXQ+YCB3aGVuIGFuIGl0ZW0gaW4gdGhlIHJlc3VsdCBsaXN0IG1hdGNoZXMuXG5cdCAqL1xuXHRASW5wdXQoKSBzaG93SGludCA9IHRoaXMuX2NvbmZpZy5zaG93SGludDtcblxuXHQvKipcblx0ICogVGhlIHByZWZlcnJlZCBwbGFjZW1lbnQgb2YgdGhlIHR5cGVhaGVhZCwgYW1vbmcgdGhlIFtwb3NzaWJsZSB2YWx1ZXNdKCMvZ3VpZGVzL3Bvc2l0aW9uaW5nI2FwaSkuXG5cdCAqXG5cdCAqIFRoZSBkZWZhdWx0IG9yZGVyIG9mIHByZWZlcmVuY2UgaXMgYFwiYm90dG9tLXN0YXJ0IGJvdHRvbS1lbmQgdG9wLXN0YXJ0IHRvcC1lbmRcImBcblx0ICpcblx0ICogUGxlYXNlIHNlZSB0aGUgW3Bvc2l0aW9uaW5nIG92ZXJ2aWV3XSgjL3Bvc2l0aW9uaW5nKSBmb3IgbW9yZSBkZXRhaWxzLlxuXHQgKi9cblx0QElucHV0KCkgcGxhY2VtZW50ID0gdGhpcy5fY29uZmlnLnBsYWNlbWVudDtcblxuXHQvKipcblx0ICogQWxsb3dzIHRvIGNoYW5nZSBkZWZhdWx0IFBvcHBlciBvcHRpb25zIHdoZW4gcG9zaXRpb25pbmcgdGhlIHR5cGVhaGVhZC5cblx0ICogUmVjZWl2ZXMgY3VycmVudCBwb3BwZXIgb3B0aW9ucyBhbmQgcmV0dXJucyBtb2RpZmllZCBvbmVzLlxuXHQgKlxuXHQgKiBAc2luY2UgMTMuMS4wXG5cdCAqL1xuXHRASW5wdXQoKSBwb3BwZXJPcHRpb25zID0gdGhpcy5fY29uZmlnLnBvcHBlck9wdGlvbnM7XG5cblx0LyoqXG5cdCAqIEEgY3VzdG9tIGNsYXNzIHRvIGFwcGVuZCB0byB0aGUgdHlwZWFoZWFkIHBvcHVwIHdpbmRvd1xuXHQgKlxuXHQgKiBBY2NlcHRzIGEgc3RyaW5nIGNvbnRhaW5pbmcgQ1NTIGNsYXNzIHRvIGJlIGFwcGxpZWQgb24gdGhlIGBuZ2ItdHlwZWFoZWFkLXdpbmRvd2AuXG5cdCAqXG5cdCAqIFRoaXMgY2FuIGJlIHVzZWQgdG8gcHJvdmlkZSBpbnN0YW5jZS1zcGVjaWZpYyBzdHlsaW5nLCBleC4geW91IGNhbiBvdmVycmlkZSBwb3B1cCB3aW5kb3cgYHotaW5kZXhgXG5cdCAqXG5cdCAqIEBzaW5jZSA5LjEuMFxuXHQgKi9cblx0QElucHV0KCkgcG9wdXBDbGFzczogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBBbiBldmVudCBlbWl0dGVkIHJpZ2h0IGJlZm9yZSBhbiBpdGVtIGlzIHNlbGVjdGVkIGZyb20gdGhlIHJlc3VsdCBsaXN0LlxuXHQgKlxuXHQgKiBFdmVudCBwYXlsb2FkIGlzIG9mIHR5cGUgW2BOZ2JUeXBlYWhlYWRTZWxlY3RJdGVtRXZlbnRgXSgjL2NvbXBvbmVudHMvdHlwZWFoZWFkL2FwaSNOZ2JUeXBlYWhlYWRTZWxlY3RJdGVtRXZlbnQpLlxuXHQgKi9cblx0QE91dHB1dCgpIHNlbGVjdEl0ZW0gPSBuZXcgRXZlbnRFbWl0dGVyPE5nYlR5cGVhaGVhZFNlbGVjdEl0ZW1FdmVudD4oKTtcblxuXHRhY3RpdmVEZXNjZW5kYW50OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblx0cG9wdXBJZCA9IGBuZ2ItdHlwZWFoZWFkLSR7bmV4dFdpbmRvd0lkKyt9YDtcblxuXHRwcml2YXRlIF9vblRvdWNoZWQgPSAoKSA9PiB7fTtcblx0cHJpdmF0ZSBfb25DaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcblxuXHRuZ09uSW5pdCgpOiB2b2lkIHtcblx0XHR0aGlzLl9zdWJzY3JpYmVUb1VzZXJJbnB1dCgpO1xuXHR9XG5cblx0bmdPbkNoYW5nZXMoeyBuZ2JUeXBlYWhlYWQgfTogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuXHRcdGlmIChuZ2JUeXBlYWhlYWQgJiYgIW5nYlR5cGVhaGVhZC5maXJzdENoYW5nZSkge1xuXHRcdFx0dGhpcy5fdW5zdWJzY3JpYmVGcm9tVXNlcklucHV0KCk7XG5cdFx0XHR0aGlzLl9zdWJzY3JpYmVUb1VzZXJJbnB1dCgpO1xuXHRcdH1cblx0fVxuXG5cdG5nT25EZXN0cm95KCk6IHZvaWQge1xuXHRcdHRoaXMuX2Nsb3NlUG9wdXAoKTtcblx0XHR0aGlzLl91bnN1YnNjcmliZUZyb21Vc2VySW5wdXQoKTtcblx0fVxuXG5cdHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogYW55KSA9PiBhbnkpOiB2b2lkIHtcblx0XHR0aGlzLl9vbkNoYW5nZSA9IGZuO1xuXHR9XG5cblx0cmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IGFueSk6IHZvaWQge1xuXHRcdHRoaXMuX29uVG91Y2hlZCA9IGZuO1xuXHR9XG5cblx0d3JpdGVWYWx1ZSh2YWx1ZSkge1xuXHRcdHRoaXMuX3dyaXRlSW5wdXRWYWx1ZSh0aGlzLl9mb3JtYXRJdGVtRm9ySW5wdXQodmFsdWUpKTtcblx0XHRpZiAodGhpcy5zaG93SGludCkge1xuXHRcdFx0dGhpcy5faW5wdXRWYWx1ZUJhY2t1cCA9IHZhbHVlO1xuXHRcdH1cblx0fVxuXG5cdHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuXHRcdHRoaXMuX25hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc21pc3NlcyB0eXBlYWhlYWQgcG9wdXAgd2luZG93XG5cdCAqL1xuXHRkaXNtaXNzUG9wdXAoKSB7XG5cdFx0aWYgKHRoaXMuaXNQb3B1cE9wZW4oKSkge1xuXHRcdFx0dGhpcy5fcmVzdWJzY3JpYmVUeXBlYWhlYWQkLm5leHQobnVsbCk7XG5cdFx0XHR0aGlzLl9jbG9zZVBvcHVwKCk7XG5cdFx0XHRpZiAodGhpcy5zaG93SGludCAmJiB0aGlzLl9pbnB1dFZhbHVlQmFja3VwICE9PSBudWxsKSB7XG5cdFx0XHRcdHRoaXMuX3dyaXRlSW5wdXRWYWx1ZSh0aGlzLl9pbnB1dFZhbHVlQmFja3VwKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuX2NoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR5cGVhaGVhZCBwb3B1cCB3aW5kb3cgaXMgZGlzcGxheWVkXG5cdCAqL1xuXHRpc1BvcHVwT3BlbigpIHtcblx0XHRyZXR1cm4gdGhpcy5fd2luZG93UmVmICE9IG51bGw7XG5cdH1cblxuXHRoYW5kbGVCbHVyKCkge1xuXHRcdHRoaXMuX3Jlc3Vic2NyaWJlVHlwZWFoZWFkJC5uZXh0KG51bGwpO1xuXHRcdHRoaXMuX29uVG91Y2hlZCgpO1xuXHR9XG5cblx0aGFuZGxlS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuXHRcdGlmICghdGhpcy5pc1BvcHVwT3BlbigpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0LyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uICovXG5cdFx0c3dpdGNoIChldmVudC53aGljaCkge1xuXHRcdFx0Y2FzZSBLZXkuQXJyb3dEb3duOlxuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR0aGlzLl93aW5kb3dSZWYhLmluc3RhbmNlLm5leHQoKTtcblx0XHRcdFx0dGhpcy5fc2hvd0hpbnQoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIEtleS5BcnJvd1VwOlxuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR0aGlzLl93aW5kb3dSZWYhLmluc3RhbmNlLnByZXYoKTtcblx0XHRcdFx0dGhpcy5fc2hvd0hpbnQoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIEtleS5FbnRlcjpcblx0XHRcdGNhc2UgS2V5LlRhYjoge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSB0aGlzLl93aW5kb3dSZWYhLmluc3RhbmNlLmdldEFjdGl2ZSgpO1xuXHRcdFx0XHRpZiAoaXNEZWZpbmVkKHJlc3VsdCkpIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdHRoaXMuX3NlbGVjdFJlc3VsdChyZXN1bHQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuX2Nsb3NlUG9wdXAoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBfb3BlblBvcHVwKCkge1xuXHRcdGlmICghdGhpcy5pc1BvcHVwT3BlbigpKSB7XG5cdFx0XHR0aGlzLl9pbnB1dFZhbHVlQmFja3VwID0gdGhpcy5fbmF0aXZlRWxlbWVudC52YWx1ZTtcblx0XHRcdGNvbnN0IHsgd2luZG93UmVmIH0gPSB0aGlzLl9wb3B1cFNlcnZpY2Uub3BlbigpO1xuXHRcdFx0dGhpcy5fd2luZG93UmVmID0gd2luZG93UmVmO1xuXHRcdFx0dGhpcy5fd2luZG93UmVmLnNldElucHV0KCdpZCcsIHRoaXMucG9wdXBJZCk7XG5cdFx0XHR0aGlzLl93aW5kb3dSZWYuc2V0SW5wdXQoJ3BvcHVwQ2xhc3MnLCB0aGlzLnBvcHVwQ2xhc3MpO1xuXHRcdFx0dGhpcy5fd2luZG93UmVmLmluc3RhbmNlLnNlbGVjdEV2ZW50LnN1YnNjcmliZSgocmVzdWx0OiBhbnkpID0+IHRoaXMuX3NlbGVjdFJlc3VsdENsb3NlUG9wdXAocmVzdWx0KSk7XG5cdFx0XHR0aGlzLl93aW5kb3dSZWYuaW5zdGFuY2UuYWN0aXZlQ2hhbmdlRXZlbnQuc3Vic2NyaWJlKChhY3RpdmVJZDogc3RyaW5nKSA9PiAodGhpcy5hY3RpdmVEZXNjZW5kYW50ID0gYWN0aXZlSWQpKTtcblxuXHRcdFx0aWYgKHRoaXMuY29udGFpbmVyID09PSAnYm9keScpIHtcblx0XHRcdFx0KHRoaXMuX3dpbmRvd1JlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50KS5zdHlsZS56SW5kZXggPSAnMTA1NSc7XG5cdFx0XHRcdHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fd2luZG93UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcblxuXHRcdFx0Ly8gU2V0dGluZyB1cCBwb3BwZXIgYW5kIHNjaGVkdWxpbmcgdXBkYXRlcyB3aGVuIHpvbmUgaXMgc3RhYmxlXG5cdFx0XHR0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5fd2luZG93UmVmKSB7XG5cdFx0XHRcdFx0dGhpcy5fcG9zaXRpb25pbmcuY3JlYXRlUG9wcGVyKHtcblx0XHRcdFx0XHRcdGhvc3RFbGVtZW50OiB0aGlzLl9uYXRpdmVFbGVtZW50LFxuXHRcdFx0XHRcdFx0dGFyZ2V0RWxlbWVudDogdGhpcy5fd2luZG93UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQsXG5cdFx0XHRcdFx0XHRwbGFjZW1lbnQ6IHRoaXMucGxhY2VtZW50LFxuXHRcdFx0XHRcdFx0YXBwZW5kVG9Cb2R5OiB0aGlzLmNvbnRhaW5lciA9PT0gJ2JvZHknLFxuXHRcdFx0XHRcdFx0dXBkYXRlUG9wcGVyT3B0aW9uczogKG9wdGlvbnMpID0+IHRoaXMucG9wcGVyT3B0aW9ucyhhZGRQb3BwZXJPZmZzZXQoWzAsIDJdKShvcHRpb25zKSksXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHR0aGlzLl96b25lU3Vic2NyaXB0aW9uID0gdGhpcy5fbmdab25lLm9uU3RhYmxlLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9wb3NpdGlvbmluZy51cGRhdGUoKSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRuZ2JBdXRvQ2xvc2UodGhpcy5fbmdab25lLCB0aGlzLl9kb2N1bWVudCwgJ291dHNpZGUnLCAoKSA9PiB0aGlzLmRpc21pc3NQb3B1cCgpLCB0aGlzLl9jbG9zZWQkLCBbXG5cdFx0XHRcdHRoaXMuX25hdGl2ZUVsZW1lbnQsXG5cdFx0XHRcdHRoaXMuX3dpbmRvd1JlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50LFxuXHRcdFx0XSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBfY2xvc2VQb3B1cCgpIHtcblx0XHR0aGlzLl9wb3B1cFNlcnZpY2UuY2xvc2UoKS5zdWJzY3JpYmUoKCkgPT4ge1xuXHRcdFx0dGhpcy5fcG9zaXRpb25pbmcuZGVzdHJveSgpO1xuXHRcdFx0dGhpcy5fem9uZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblx0XHRcdHRoaXMuX2Nsb3NlZCQubmV4dCgpO1xuXHRcdFx0dGhpcy5fd2luZG93UmVmID0gbnVsbDtcblx0XHRcdHRoaXMuYWN0aXZlRGVzY2VuZGFudCA9IG51bGw7XG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIF9zZWxlY3RSZXN1bHQocmVzdWx0OiBhbnkpIHtcblx0XHRsZXQgZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuXHRcdHRoaXMuc2VsZWN0SXRlbS5lbWl0KHtcblx0XHRcdGl0ZW06IHJlc3VsdCxcblx0XHRcdHByZXZlbnREZWZhdWx0OiAoKSA9PiB7XG5cdFx0XHRcdGRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuXHRcdFx0fSxcblx0XHR9KTtcblx0XHR0aGlzLl9yZXN1YnNjcmliZVR5cGVhaGVhZCQubmV4dChudWxsKTtcblxuXHRcdGlmICghZGVmYXVsdFByZXZlbnRlZCkge1xuXHRcdFx0dGhpcy53cml0ZVZhbHVlKHJlc3VsdCk7XG5cdFx0XHR0aGlzLl9vbkNoYW5nZShyZXN1bHQpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgX3NlbGVjdFJlc3VsdENsb3NlUG9wdXAocmVzdWx0OiBhbnkpIHtcblx0XHR0aGlzLl9zZWxlY3RSZXN1bHQocmVzdWx0KTtcblx0XHR0aGlzLl9jbG9zZVBvcHVwKCk7XG5cdH1cblxuXHRwcml2YXRlIF9zaG93SGludCgpIHtcblx0XHRpZiAodGhpcy5zaG93SGludCAmJiB0aGlzLl93aW5kb3dSZWY/Lmluc3RhbmNlLmhhc0FjdGl2ZSgpICYmIHRoaXMuX2lucHV0VmFsdWVCYWNrdXAgIT0gbnVsbCkge1xuXHRcdFx0Y29uc3QgdXNlcklucHV0TG93ZXJDYXNlID0gdGhpcy5faW5wdXRWYWx1ZUJhY2t1cC50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0Y29uc3QgZm9ybWF0dGVkVmFsID0gdGhpcy5fZm9ybWF0SXRlbUZvcklucHV0KHRoaXMuX3dpbmRvd1JlZi5pbnN0YW5jZS5nZXRBY3RpdmUoKSk7XG5cblx0XHRcdGlmICh1c2VySW5wdXRMb3dlckNhc2UgPT09IGZvcm1hdHRlZFZhbC5zdWJzdHJpbmcoMCwgdGhpcy5faW5wdXRWYWx1ZUJhY2t1cC5sZW5ndGgpLnRvTG93ZXJDYXNlKCkpIHtcblx0XHRcdFx0dGhpcy5fd3JpdGVJbnB1dFZhbHVlKHRoaXMuX2lucHV0VmFsdWVCYWNrdXAgKyBmb3JtYXR0ZWRWYWwuc3Vic3RyaW5nKHRoaXMuX2lucHV0VmFsdWVCYWNrdXAubGVuZ3RoKSk7XG5cdFx0XHRcdHRoaXMuX25hdGl2ZUVsZW1lbnRbJ3NldFNlbGVjdGlvblJhbmdlJ10uYXBwbHkodGhpcy5fbmF0aXZlRWxlbWVudCwgW1xuXHRcdFx0XHRcdHRoaXMuX2lucHV0VmFsdWVCYWNrdXAubGVuZ3RoLFxuXHRcdFx0XHRcdGZvcm1hdHRlZFZhbC5sZW5ndGgsXG5cdFx0XHRcdF0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5fd3JpdGVJbnB1dFZhbHVlKGZvcm1hdHRlZFZhbCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBfZm9ybWF0SXRlbUZvcklucHV0KGl0ZW06IGFueSk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIGl0ZW0gIT0gbnVsbCAmJiB0aGlzLmlucHV0Rm9ybWF0dGVyID8gdGhpcy5pbnB1dEZvcm1hdHRlcihpdGVtKSA6IHRvU3RyaW5nKGl0ZW0pO1xuXHR9XG5cblx0cHJpdmF0ZSBfd3JpdGVJbnB1dFZhbHVlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcblx0XHR0aGlzLl9uYXRpdmVFbGVtZW50LnZhbHVlID0gdG9TdHJpbmcodmFsdWUpO1xuXHR9XG5cblx0cHJpdmF0ZSBfc3Vic2NyaWJlVG9Vc2VySW5wdXQoKTogdm9pZCB7XG5cdFx0Y29uc3QgcmVzdWx0cyQgPSB0aGlzLl92YWx1ZUNoYW5nZXMkLnBpcGUoXG5cdFx0XHR0YXAoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMuX2lucHV0VmFsdWVCYWNrdXAgPSB0aGlzLnNob3dIaW50ID8gdmFsdWUgOiBudWxsO1xuXHRcdFx0XHR0aGlzLl9pbnB1dFZhbHVlRm9yU2VsZWN0T25FeGFjdCA9IHRoaXMuc2VsZWN0T25FeGFjdCA/IHZhbHVlIDogbnVsbDtcblx0XHRcdFx0dGhpcy5fb25DaGFuZ2UodGhpcy5lZGl0YWJsZSA/IHZhbHVlIDogdW5kZWZpbmVkKTtcblx0XHRcdH0pLFxuXHRcdFx0dGhpcy5uZ2JUeXBlYWhlYWQgPyB0aGlzLm5nYlR5cGVhaGVhZCA6ICgpID0+IG9mKFtdKSxcblx0XHQpO1xuXG5cdFx0dGhpcy5fc3Vic2NyaXB0aW9uID0gdGhpcy5fcmVzdWJzY3JpYmVUeXBlYWhlYWQkLnBpcGUoc3dpdGNoTWFwKCgpID0+IHJlc3VsdHMkKSkuc3Vic2NyaWJlKChyZXN1bHRzKSA9PiB7XG5cdFx0XHRpZiAoIXJlc3VsdHMgfHwgcmVzdWx0cy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0dGhpcy5fY2xvc2VQb3B1cCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gd2hlbiB0aGVyZSBpcyBvbmx5IG9uZSByZXN1bHQgYW5kIHRoaXMgbWF0Y2hlcyB0aGUgaW5wdXQgdmFsdWVcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdHRoaXMuc2VsZWN0T25FeGFjdCAmJlxuXHRcdFx0XHRcdHJlc3VsdHMubGVuZ3RoID09PSAxICYmXG5cdFx0XHRcdFx0dGhpcy5fZm9ybWF0SXRlbUZvcklucHV0KHJlc3VsdHNbMF0pID09PSB0aGlzLl9pbnB1dFZhbHVlRm9yU2VsZWN0T25FeGFjdFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHR0aGlzLl9zZWxlY3RSZXN1bHQocmVzdWx0c1swXSk7XG5cdFx0XHRcdFx0dGhpcy5fY2xvc2VQb3B1cCgpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuX29wZW5Qb3B1cCgpO1xuXHRcdFx0XHRcdHRoaXMuX3dpbmRvd1JlZiEuc2V0SW5wdXQoJ2ZvY3VzRmlyc3QnLCB0aGlzLmZvY3VzRmlyc3QpO1xuXHRcdFx0XHRcdHRoaXMuX3dpbmRvd1JlZiEuc2V0SW5wdXQoJ3Jlc3VsdHMnLCByZXN1bHRzKTtcblx0XHRcdFx0XHR0aGlzLl93aW5kb3dSZWYhLnNldElucHV0KCd0ZXJtJywgdGhpcy5fbmF0aXZlRWxlbWVudC52YWx1ZSk7XG5cdFx0XHRcdFx0aWYgKHRoaXMucmVzdWx0Rm9ybWF0dGVyKSB7XG5cdFx0XHRcdFx0XHR0aGlzLl93aW5kb3dSZWYhLnNldElucHV0KCdmb3JtYXR0ZXInLCB0aGlzLnJlc3VsdEZvcm1hdHRlcik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh0aGlzLnJlc3VsdFRlbXBsYXRlKSB7XG5cdFx0XHRcdFx0XHR0aGlzLl93aW5kb3dSZWYhLnNldElucHV0KCdyZXN1bHRUZW1wbGF0ZScsIHRoaXMucmVzdWx0VGVtcGxhdGUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLl93aW5kb3dSZWYhLmluc3RhbmNlLnJlc2V0QWN0aXZlKCk7XG5cblx0XHRcdFx0XHQvLyBUaGUgb2JzZXJ2YWJsZSBzdHJlYW0gd2UgYXJlIHN1YnNjcmliaW5nIHRvIG1pZ2h0IGhhdmUgYXN5bmMg