UNPKG

@kolkov/ngx-dadata

Version:

Angular 6+ and 13+ DaData suggestion (подсказки) implementation

237 lines 31.6 kB
import { Component, EventEmitter, forwardRef, HostListener, Inject, Input, Output, ViewChild } from '@angular/core'; import { DadataType } from './ngx-dadata.service'; import { Subject, timer } from 'rxjs'; import { debounce } from 'rxjs/operators'; import { DadataConfigDefault } from './dadata-config'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { DOCUMENT } from '@angular/common'; import { unwrapHtmlForSink } from 'safevalues'; import { createHtml } from 'safevalues/implementation/html_impl'; import * as i0 from "@angular/core"; import * as i1 from "./ngx-dadata.service"; import * as i2 from "@angular/forms"; import * as i3 from "@angular/common"; /*const NGX_DADATA_VALIDATOR = { provide: NG_VALIDATORS, useExisting: forwardRef(() => NgxDadataComponent), multi: true, };*/ export function createDaDataValidator(value) { return (c) => { const err = { rangeError: { given: c.value, expected: value, } }; return (c.value !== value) ? err : null; }; } /** * Autocomplete IDs need to be unique across components, so this counter exists outside of * the component definition. */ let uniqueDadataIdCounter = 0; export class NgxDadataComponent { constructor(dataService, r, elRef, document) { this.dataService = dataService; this.r = r; this.elRef = elRef; this.document = document; this.v = ''; this.currentFocus = -1; this.opened = false; this.data = []; this.config = DadataConfigDefault; this.disabled = null; this.type = DadataType.address; this.limit = DadataConfigDefault.limit; this.placeholder = ''; this.locations = null; this.selected = new EventEmitter(); this.inputString$ = new Subject(); /** Unique ID to be used by autocomplete trigger's "aria-owns" property. */ this.id = `ngx-dadata-${uniqueDadataIdCounter++}`; // onSuggestionSelected = (value: string) => {}; this.onTouched = () => { }; this.propagateChange = () => { }; this.validateFn = () => { }; } get value() { return this.v; } set value(v) { if (v !== this.v) { this.v = v; this.propagateChange(v); } } ngOnInit() { /*this.validateFn = createDaDataValidator(this._value); this.propagateChange(this._value);*/ this.type = this.config.type; this.locations = this.config.locations; this.dataService.setApiKey(this.apiKey ? this.apiKey : this.config.apiKey); this.inputString$.pipe(debounce(() => timer(this.config.delay ? this.config.delay : 500))).subscribe(x => { this.dataService.getData(x, this.type, this.config) .subscribe((y) => { this.data = y.suggestions; if (this.data.length) { this.opened = true; } }); }); } ngOnChanges(changes) { if (changes.value) { // console.log('ngOnChanges'); } } getData(value) { this.inputString$.next(value); this.currentFocus = -1; } onClick(e, item) { this.inputValue.nativeElement.value = item.value; this.propagateChange(item.value); this.inputValue.nativeElement.focus(); this.selectedSuggestion = item; this.data = []; this.currentFocus = -1; this.opened = false; this.selected.emit(item); // this.selectedData.emit(item.data); // this.selectedString.emit(item.value); } onOutsideClick($event) { if (!this.opened) { return; } if (!this.elRef.nativeElement.contains($event.target)) { this.data = []; this.opened = false; } } onArrowDown() { this.removeFocus(this.currentFocus); if (this.currentFocus >= this.data.length - 1) { this.currentFocus = 0; } else { this.currentFocus++; } this.setFocus(this.currentFocus); } onArrowUp() { this.removeFocus(this.currentFocus); if (this.currentFocus === 0) { this.currentFocus = this.data.length - 1; } else { this.currentFocus--; } this.setFocus(this.currentFocus); } onEnter(event) { this.selectedSuggestion = this.data[this.currentFocus]; this.inputValue.nativeElement.value = this.selectedSuggestion.value; this.data = []; this.currentFocus = -1; this.propagateChange(this.selectedSuggestion.value); this.selected.emit(this.selectedSuggestion); // this.selectedData.emit(this.selectedSuggestion.data); // this.selectedString.emit(this.selectedSuggestion.value); } setFocus(id) { const activeEl = this.document.getElementById(id + 'item'); this.r.addClass(activeEl, 'active'); } removeFocus(id) { if (id !== -1) { const activeEl = this.document.getElementById(id + 'item'); this.r.removeClass(activeEl, 'active'); } } writeValue(value) { if (value !== undefined && value !== null) { this.v = value; } else { this.v = ''; } this.r.setProperty(this.inputValue.nativeElement, 'innerHTML', unwrapHtmlForSink(createHtml(this.v))); } /** * Set the function to be called * when the control receives a change event. * * @param fn a function */ registerOnChange(fn) { // this.onSuggestionSelected = fn; this.propagateChange = fn; } /** * Set the function to be called * when the control receives a touch event. * * @param fn a function */ registerOnTouched(fn) { this.onTouched = fn; } /** * Implements disabled state for this element * * @param isDisabled Disabled state flag */ setDisabledState(isDisabled) { this.disabled = isDisabled; } } NgxDadataComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: NgxDadataComponent, deps: [{ token: i1.NgxDadataService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); NgxDadataComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: NgxDadataComponent, selector: "ngx-dadata", inputs: { config: "config", apiKey: "apiKey", disabled: "disabled", type: "type", limit: "limit", placeholder: "placeholder", locations: "locations" }, outputs: { selectedSuggestion: "selectedSuggestion", selected: "selected" }, host: { listeners: { "document:click": "onOutsideClick($event)" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxDadataComponent), multi: true }, /*NGX_DADATA_VALIDATOR*/ ], viewQueries: [{ propertyName: "inputValue", first: true, predicate: ["inputValue"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"autocomplete\">\n <input [disabled]=\"disabled ? true : null\" type=\"text\" class=\"search\" #inputValue (input)=\"getData(inputValue.value)\"\n [placeholder]=\"placeholder\" (keyup.ArrowDown)=\"onArrowDown()\" (keyup.ArrowUp)=\"onArrowUp()\"\n (keyup.Enter)=\"onEnter($event)\" spellcheck=\"false\" [(ngModel)]=\"value\" autocomplete=\"off\" />\n <div *ngIf=\"data.length\">\n <div class=\"autocomplete-items\">\n <div class=\"autocomplele-item\" *ngFor=\"let item of data; let i = index\" (click)=\"onClick($event, item)\" [id]=\"i+'item'\">\n {{item.value}}\n <ng-template [ngIf]=\"type==='party'\">\n <br/>\n <span>{{item.data?.inn}} {{config.partyAddress === 'full' ? item.data?.address?.value : item.data?.address?.data?.city}}</span>\n </ng-template>\n </div>\n </div>\n </div>\n</div>\n", styles: [".autocomplete{position:relative}input{border:0 solid transparent;background-color:#f1f1f1;padding:5px}input[type=text]{background-color:#f1f1f1;width:100%}input[type=submit]{background-color:#1e90ff;color:#fff}.autocomplete-items{position:absolute;border:1px solid #d4d4d4;border-bottom:none;border-top:none;z-index:99;top:100%;left:0;right:0}.autocomplete-items .autocomplele-item{padding:5px 10px;cursor:pointer;background-color:#fff;border-bottom:1px solid #d4d4d4}.autocomplete-items .autocomplele-item:hover{background-color:#e9e9e9}.autocomplete-items .autocomplele-item.active{background-color:#1e90ff!important;color:#fff}.autocomplete-items .autocomplele-item span{color:#555;font-size:80%}\n"], directives: [{ type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: NgxDadataComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-dadata', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxDadataComponent), multi: true }, /*NGX_DADATA_VALIDATOR*/ ], template: "<div class=\"autocomplete\">\n <input [disabled]=\"disabled ? true : null\" type=\"text\" class=\"search\" #inputValue (input)=\"getData(inputValue.value)\"\n [placeholder]=\"placeholder\" (keyup.ArrowDown)=\"onArrowDown()\" (keyup.ArrowUp)=\"onArrowUp()\"\n (keyup.Enter)=\"onEnter($event)\" spellcheck=\"false\" [(ngModel)]=\"value\" autocomplete=\"off\" />\n <div *ngIf=\"data.length\">\n <div class=\"autocomplete-items\">\n <div class=\"autocomplele-item\" *ngFor=\"let item of data; let i = index\" (click)=\"onClick($event, item)\" [id]=\"i+'item'\">\n {{item.value}}\n <ng-template [ngIf]=\"type==='party'\">\n <br/>\n <span>{{item.data?.inn}} {{config.partyAddress === 'full' ? item.data?.address?.value : item.data?.address?.data?.city}}</span>\n </ng-template>\n </div>\n </div>\n </div>\n</div>\n", styles: [".autocomplete{position:relative}input{border:0 solid transparent;background-color:#f1f1f1;padding:5px}input[type=text]{background-color:#f1f1f1;width:100%}input[type=submit]{background-color:#1e90ff;color:#fff}.autocomplete-items{position:absolute;border:1px solid #d4d4d4;border-bottom:none;border-top:none;z-index:99;top:100%;left:0;right:0}.autocomplete-items .autocomplele-item{padding:5px 10px;cursor:pointer;background-color:#fff;border-bottom:1px solid #d4d4d4}.autocomplete-items .autocomplele-item:hover{background-color:#e9e9e9}.autocomplete-items .autocomplele-item.active{background-color:#1e90ff!important;color:#fff}.autocomplete-items .autocomplele-item span{color:#555;font-size:80%}\n"] }] }], ctorParameters: function () { return [{ type: i1.NgxDadataService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; }, propDecorators: { config: [{ type: Input }], apiKey: [{ type: Input }], disabled: [{ type: Input }], type: [{ type: Input }], limit: [{ type: Input }], placeholder: [{ type: Input }], locations: [{ type: Input }], selectedSuggestion: [{ type: Output }], selected: [{ type: Output }], inputValue: [{ type: ViewChild, args: ['inputValue', { static: true }] }], onOutsideClick: [{ type: HostListener, args: ['document:click', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRhZGF0YS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZGFkYXRhL3NyYy9saWIvbmd4LWRhZGF0YS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZGFkYXRhL3NyYy9saWIvbmd4LWRhZGF0YS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUFFLE1BQU0sRUFDcEIsS0FBSyxFQUdMLE1BQU0sRUFHTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFVBQVUsRUFBbUIsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRSxPQUFPLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFHeEMsT0FBTyxFQUFlLG1CQUFtQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDbEUsT0FBTyxFQUFtRCxpQkFBaUIsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ25HLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDN0MsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLHFDQUFxQyxDQUFDOzs7OztBQUUvRDs7OztJQUlJO0FBRUosTUFBTSxVQUFVLHFCQUFxQixDQUFDLEtBQUs7SUFDekMsT0FBTyxDQUFDLENBQWMsRUFBRSxFQUFFO1FBQ3hCLE1BQU0sR0FBRyxHQUFHO1lBQ1YsVUFBVSxFQUFFO2dCQUNWLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSztnQkFDZCxRQUFRLEVBQUUsS0FBSzthQUNoQjtTQUNGLENBQUM7UUFFRixPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUMsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILElBQUkscUJBQXFCLEdBQUcsQ0FBQyxDQUFDO0FBYTlCLE1BQU0sT0FBTyxrQkFBa0I7SUFpQzdCLFlBQ1UsV0FBNkIsRUFDN0IsQ0FBWSxFQUNaLEtBQWlCLEVBQ0MsUUFBa0I7UUFIcEMsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO1FBQzdCLE1BQUMsR0FBRCxDQUFDLENBQVc7UUFDWixVQUFLLEdBQUwsS0FBSyxDQUFZO1FBQ0MsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQXBDdEMsTUFBQyxHQUFRLEVBQUUsQ0FBQztRQUNwQixpQkFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRWxCLFdBQU0sR0FBRyxLQUFLLENBQUM7UUFFZixTQUFJLEdBQXVCLEVBQUUsQ0FBQztRQUVyQixXQUFNLEdBQWlCLG1CQUFtQixDQUFDO1FBRTNDLGFBQVEsR0FBRyxJQUFJLENBQUM7UUFDaEIsU0FBSSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUM7UUFDMUIsVUFBSyxHQUFHLG1CQUFtQixDQUFDLEtBQUssQ0FBQztRQUNsQyxnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUNqQixjQUFTLEdBQUcsSUFBSSxDQUFDO1FBR2hCLGFBQVEsR0FBbUMsSUFBSSxZQUFZLEVBQW9CLENBQUM7UUFNbEYsaUJBQVksR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO1FBRTdDLDJFQUEyRTtRQUMzRSxPQUFFLEdBQUcsY0FBYyxxQkFBcUIsRUFBRSxFQUFFLENBQUM7UUFFN0MsZ0RBQWdEO1FBQ2hELGNBQVMsR0FBRyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDckIsb0JBQWUsR0FBUSxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDaEMsZUFBVSxHQUFRLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQVEzQixDQUFDO0lBRUQsSUFBSSxLQUFLO1FBQ1AsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2hCLENBQUM7SUFFRCxJQUFJLEtBQUssQ0FBQyxDQUFNO1FBQ2QsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsRUFBRTtZQUNoQixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNYLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDekI7SUFDSCxDQUFDO0lBRUQsUUFBUTtRQUNOOzRDQUNvQztRQUNwQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDdkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDcEIsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQ25FLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ2QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztpQkFDaEQsU0FBUyxDQUFDLENBQUMsQ0FBaUIsRUFBRSxFQUFFO2dCQUNqQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUM7Z0JBQzFCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7b0JBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO2lCQUNwQjtZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRTtZQUNqQiw4QkFBOEI7U0FDL0I7SUFDSCxDQUFDO0lBRUQsT0FBTyxDQUFDLEtBQWE7UUFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRUQsT0FBTyxDQUFDLENBQWEsRUFBRSxJQUFzQjtRQUMzQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNqRCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixxQ0FBcUM7UUFDckMsd0NBQXdDO0lBQzFDLENBQUM7SUFHRCxjQUFjLENBQUMsTUFBa0I7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDckQsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztTQUNyQjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEMsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM3QyxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztTQUN2QjthQUFNO1lBQ0wsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ3JCO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwQyxJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssQ0FBQyxFQUFFO1lBQzNCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1NBQzFDO2FBQU07WUFDTCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDckI7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsT0FBTyxDQUFDLEtBQW9CO1FBQzFCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUNwRSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNmLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDNUMsd0RBQXdEO1FBQ3hELDJEQUEyRDtJQUM3RCxDQUFDO0lBRUQsUUFBUSxDQUFDLEVBQVU7UUFDakIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsV0FBVyxDQUFDLEVBQVU7UUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFDYixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ3hDO0lBQ0gsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFVO1FBQ25CLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSSxFQUFFO1lBQ3pDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1NBQ2hCO2FBQU07WUFDTCxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNiO1FBRUQsSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGdCQUFnQixDQUFDLEVBQU87UUFDdEIsa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGlCQUFpQixDQUFDLEVBQU87UUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxnQkFBZ0IsQ0FBQyxVQUFtQjtRQUNsQyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztJQUM3QixDQUFDOztnSEEzTFUsa0JBQWtCLHFHQXFDbkIsUUFBUTtvR0FyQ1Asa0JBQWtCLCtVQVBsQjtRQUNUO1lBQ0EsT0FBTyxFQUFFLGlCQUFpQjtZQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDO1lBQ2pELEtBQUssRUFBRSxJQUFJO1NBQ1osRUFBRSx3QkFBd0I7S0FBQyx1S0MzRDlCLHEzQkFnQkE7NEZENkNhLGtCQUFrQjtrQkFYOUIsU0FBUzsrQkFDRSxZQUFZLGFBR1g7d0JBQ1Q7NEJBQ0EsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLENBQUM7NEJBQ2pELEtBQUssRUFBRSxJQUFJO3lCQUNaLEVBQUUsd0JBQXdCO3FCQUFDOzBJQXVDVSxRQUFROzBCQUEzQyxNQUFNOzJCQUFDLFFBQVE7NENBN0JULE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFFSSxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTTtnQkFJb0MsVUFBVTtzQkFBcEQsU0FBUzt1QkFBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQTJFekMsY0FBYztzQkFEYixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RMaXN0ZW5lciwgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0RhZGF0YVR5cGUsIE5neERhZGF0YVNlcnZpY2V9IGZyb20gJy4vbmd4LWRhZGF0YS5zZXJ2aWNlJztcbmltcG9ydCB7U3ViamVjdCwgdGltZXJ9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZX0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtEYWRhdGFSZXNwb25zZX0gZnJvbSAnLi9tb2RlbHMvZGFkYXRhLXJlc3BvbnNlJztcbmltcG9ydCB7RGFkYXRhU3VnZ2VzdGlvbn0gZnJvbSAnLi9tb2RlbHMvc3VnZ2VzdGlvbic7XG5pbXBvcnQge0RhZGF0YUNvbmZpZywgRGFkYXRhQ29uZmlnRGVmYXVsdH0gZnJvbSAnLi9kYWRhdGEtY29uZmlnJztcbmltcG9ydCB7Q29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBOR19WQUxJREFUT1JTLCBOR19WQUxVRV9BQ0NFU1NPUn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7dW53cmFwSHRtbEZvclNpbmt9IGZyb20gJ3NhZmV2YWx1ZXMnO1xuaW1wb3J0IHtjcmVhdGVIdG1sfSBmcm9tICdzYWZldmFsdWVzL2ltcGxlbWVudGF0aW9uL2h0bWxfaW1wbCc7XG5cbi8qY29uc3QgTkdYX0RBREFUQV9WQUxJREFUT1IgPSB7XG4gIHByb3ZpZGU6IE5HX1ZBTElEQVRPUlMsXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neERhZGF0YUNvbXBvbmVudCksXG4gIG11bHRpOiB0cnVlLFxufTsqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGFEYXRhVmFsaWRhdG9yKHZhbHVlKSB7XG4gIHJldHVybiAoYzogRm9ybUNvbnRyb2wpID0+IHtcbiAgICBjb25zdCBlcnIgPSB7XG4gICAgICByYW5nZUVycm9yOiB7XG4gICAgICAgIGdpdmVuOiBjLnZhbHVlLFxuICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiAoYy52YWx1ZSAhPT0gdmFsdWUpID8gZXJyIDogbnVsbDtcbiAgfTtcbn1cblxuLyoqXG4gKiBBdXRvY29tcGxldGUgSURzIG5lZWQgdG8gYmUgdW5pcXVlIGFjcm9zcyBjb21wb25lbnRzLCBzbyB0aGlzIGNvdW50ZXIgZXhpc3RzIG91dHNpZGUgb2ZcbiAqIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbi5cbiAqL1xubGV0IHVuaXF1ZURhZGF0YUlkQ291bnRlciA9IDA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1kYWRhdGEnLFxuICB0ZW1wbGF0ZVVybDogJy4vbmd4LWRhZGF0YS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25neC1kYWRhdGEuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neERhZGF0YUNvbXBvbmVudCksXG4gICAgbXVsdGk6IHRydWVcbiAgfSwgLypOR1hfREFEQVRBX1ZBTElEQVRPUiovXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hEYWRhdGFDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMge1xuICBwcml2YXRlIHY6IGFueSA9ICcnO1xuICBjdXJyZW50Rm9jdXMgPSAtMTtcblxuICBvcGVuZWQgPSBmYWxzZTtcblxuICBkYXRhOiBEYWRhdGFTdWdnZXN0aW9uW10gPSBbXTtcblxuICBASW5wdXQoKSBjb25maWc6IERhZGF0YUNvbmZpZyA9IERhZGF0YUNvbmZpZ0RlZmF1bHQ7XG4gIEBJbnB1dCgpIGFwaUtleTogc3RyaW5nO1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IG51bGw7XG4gIEBJbnB1dCgpIHR5cGUgPSBEYWRhdGFUeXBlLmFkZHJlc3M7XG4gIEBJbnB1dCgpIGxpbWl0ID0gRGFkYXRhQ29uZmlnRGVmYXVsdC5saW1pdDtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXIgPSAnJztcbiAgQElucHV0KCkgbG9jYXRpb25zID0gbnVsbDtcblxuICBAT3V0cHV0KCkgc2VsZWN0ZWRTdWdnZXN0aW9uOiBEYWRhdGFTdWdnZXN0aW9uO1xuICBAT3V0cHV0KCkgc2VsZWN0ZWQ6IEV2ZW50RW1pdHRlcjxEYWRhdGFTdWdnZXN0aW9uPiA9IG5ldyBFdmVudEVtaXR0ZXI8RGFkYXRhU3VnZ2VzdGlvbj4oKTtcbiAgLy8gQE91dHB1dCgpIHNlbGVjdGVkRGF0YSA9IG5ldyBFdmVudEVtaXR0ZXI8RGFEYXRhQWRkcmVzcyB8IERhRGF0YUZJTyB8IERhRGF0YUJhbmsgfCBEYURhdGFQYXJ0eSB8IERhRGF0YUVtYWlsPigpO1xuICAvLyBAT3V0cHV0KCkgc2VsZWN0ZWRTdHJpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICBAVmlld0NoaWxkKCdpbnB1dFZhbHVlJywgeyBzdGF0aWM6IHRydWUgfSkgaW5wdXRWYWx1ZTogRWxlbWVudFJlZjtcblxuICBwcml2YXRlIGlucHV0U3RyaW5nJCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcblxuICAvKiogVW5pcXVlIElEIHRvIGJlIHVzZWQgYnkgYXV0b2NvbXBsZXRlIHRyaWdnZXIncyBcImFyaWEtb3duc1wiIHByb3BlcnR5LiAqL1xuICBpZCA9IGBuZ3gtZGFkYXRhLSR7dW5pcXVlRGFkYXRhSWRDb3VudGVyKyt9YDtcblxuICAvLyBvblN1Z2dlc3Rpb25TZWxlY3RlZCA9ICh2YWx1ZTogc3RyaW5nKSA9PiB7fTtcbiAgb25Ub3VjaGVkID0gKCkgPT4ge307XG4gIHByb3BhZ2F0ZUNoYW5nZTogYW55ID0gKCkgPT4ge307XG4gIHZhbGlkYXRlRm46IGFueSA9ICgpID0+IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZGF0YVNlcnZpY2U6IE5neERhZGF0YVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBlbFJlZjogRWxlbWVudFJlZixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICApIHtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLnY7XG4gIH1cblxuICBzZXQgdmFsdWUodjogYW55KSB7XG4gICAgaWYgKHYgIT09IHRoaXMudikge1xuICAgICAgdGhpcy52ID0gdjtcbiAgICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlKHYpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIC8qdGhpcy52YWxpZGF0ZUZuID0gY3JlYXRlRGFEYXRhVmFsaWRhdG9yKHRoaXMuX3ZhbHVlKTtcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLl92YWx1ZSk7Ki9cbiAgICB0aGlzLnR5cGUgPSB0aGlzLmNvbmZpZy50eXBlO1xuICAgIHRoaXMubG9jYXRpb25zID0gdGhpcy5jb25maWcubG9jYXRpb25zO1xuICAgIHRoaXMuZGF0YVNlcnZpY2Uuc2V0QXBpS2V5KHRoaXMuYXBpS2V5ID8gdGhpcy5hcGlLZXkgOiB0aGlzLmNvbmZpZy5hcGlLZXkpO1xuICAgIHRoaXMuaW5wdXRTdHJpbmckLnBpcGUoXG4gICAgICBkZWJvdW5jZSgoKSA9PiB0aW1lcih0aGlzLmNvbmZpZy5kZWxheSA/IHRoaXMuY29uZmlnLmRlbGF5IDogNTAwKSksXG4gICAgKS5zdWJzY3JpYmUoeCA9PiB7XG4gICAgICB0aGlzLmRhdGFTZXJ2aWNlLmdldERhdGEoeCwgdGhpcy50eXBlLCB0aGlzLmNvbmZpZylcbiAgICAgICAgLnN1YnNjcmliZSgoeTogRGFkYXRhUmVzcG9uc2UpID0+IHtcbiAgICAgICAgdGhpcy5kYXRhID0geS5zdWdnZXN0aW9ucztcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLm9wZW5lZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzLnZhbHVlKSB7XG4gICAgICAvLyBjb25zb2xlLmxvZygnbmdPbkNoYW5nZXMnKTtcbiAgICB9XG4gIH1cblxuICBnZXREYXRhKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmlucHV0U3RyaW5nJC5uZXh0KHZhbHVlKTtcbiAgICB0aGlzLmN1cnJlbnRGb2N1cyA9IC0xO1xuICB9XG5cbiAgb25DbGljayhlOiBNb3VzZUV2ZW50LCBpdGVtOiBEYWRhdGFTdWdnZXN0aW9uKSB7XG4gICAgdGhpcy5pbnB1dFZhbHVlLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSBpdGVtLnZhbHVlO1xuICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlKGl0ZW0udmFsdWUpO1xuICAgIHRoaXMuaW5wdXRWYWx1ZS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgdGhpcy5zZWxlY3RlZFN1Z2dlc3Rpb24gPSBpdGVtO1xuICAgIHRoaXMuZGF0YSA9IFtdO1xuICAgIHRoaXMuY3VycmVudEZvY3VzID0gLTE7XG4gICAgdGhpcy5vcGVuZWQgPSBmYWxzZTtcbiAgICB0aGlzLnNlbGVjdGVkLmVtaXQoaXRlbSk7XG4gICAgLy8gdGhpcy5zZWxlY3RlZERhdGEuZW1pdChpdGVtLmRhdGEpO1xuICAgIC8vIHRoaXMuc2VsZWN0ZWRTdHJpbmcuZW1pdChpdGVtLnZhbHVlKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcbiAgb25PdXRzaWRlQ2xpY2soJGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLm9wZW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5jb250YWlucygkZXZlbnQudGFyZ2V0KSkge1xuICAgICAgdGhpcy5kYXRhID0gW107XG4gICAgICB0aGlzLm9wZW5lZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIG9uQXJyb3dEb3duKCkge1xuICAgIHRoaXMucmVtb3ZlRm9jdXModGhpcy5jdXJyZW50Rm9jdXMpO1xuICAgIGlmICh0aGlzLmN1cnJlbnRGb2N1cyA+PSB0aGlzLmRhdGEubGVuZ3RoIC0gMSkge1xuICAgICAgdGhpcy5jdXJyZW50Rm9jdXMgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN1cnJlbnRGb2N1cysrO1xuICAgIH1cbiAgICB0aGlzLnNldEZvY3VzKHRoaXMuY3VycmVudEZvY3VzKTtcbiAgfVxuXG4gIG9uQXJyb3dVcCgpIHtcbiAgICB0aGlzLnJlbW92ZUZvY3VzKHRoaXMuY3VycmVudEZvY3VzKTtcbiAgICBpZiAodGhpcy5jdXJyZW50Rm9jdXMgPT09IDApIHtcbiAgICAgIHRoaXMuY3VycmVudEZvY3VzID0gdGhpcy5kYXRhLmxlbmd0aCAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudEZvY3VzLS07XG4gICAgfVxuICAgIHRoaXMuc2V0Rm9jdXModGhpcy5jdXJyZW50Rm9jdXMpO1xuICB9XG5cbiAgb25FbnRlcihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIHRoaXMuc2VsZWN0ZWRTdWdnZXN0aW9uID0gdGhpcy5kYXRhW3RoaXMuY3VycmVudEZvY3VzXTtcbiAgICB0aGlzLmlucHV0VmFsdWUubmF0aXZlRWxlbWVudC52YWx1ZSA9IHRoaXMuc2VsZWN0ZWRTdWdnZXN0aW9uLnZhbHVlO1xuICAgIHRoaXMuZGF0YSA9IFtdO1xuICAgIHRoaXMuY3VycmVudEZvY3VzID0gLTE7XG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy5zZWxlY3RlZFN1Z2dlc3Rpb24udmFsdWUpO1xuICAgIHRoaXMuc2VsZWN0ZWQuZW1pdCh0aGlzLnNlbGVjdGVkU3VnZ2VzdGlvbik7XG4gICAgLy8gdGhpcy5zZWxlY3RlZERhdGEuZW1pdCh0aGlzLnNlbGVjdGVkU3VnZ2VzdGlvbi5kYXRhKTtcbiAgICAvLyB0aGlzLnNlbGVjdGVkU3RyaW5nLmVtaXQodGhpcy5zZWxlY3RlZFN1Z2dlc3Rpb24udmFsdWUpO1xuICB9XG5cbiAgc2V0Rm9jdXMoaWQ6IG51bWJlcikge1xuICAgIGNvbnN0IGFjdGl2ZUVsID0gdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCArICdpdGVtJyk7XG4gICAgdGhpcy5yLmFkZENsYXNzKGFjdGl2ZUVsLCAnYWN0aXZlJyk7XG4gIH1cblxuICByZW1vdmVGb2N1cyhpZDogbnVtYmVyKSB7XG4gICAgaWYgKGlkICE9PSAtMSkge1xuICAgICAgY29uc3QgYWN0aXZlRWwgPSB0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkICsgJ2l0ZW0nKTtcbiAgICAgIHRoaXMuci5yZW1vdmVDbGFzcyhhY3RpdmVFbCwgJ2FjdGl2ZScpO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnYgPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52ID0gJyc7XG4gICAgfVxuXG4gICAgdGhpcy5yLnNldFByb3BlcnR5KHRoaXMuaW5wdXRWYWx1ZS5uYXRpdmVFbGVtZW50LCAnaW5uZXJIVE1MJywgdW53cmFwSHRtbEZvclNpbmsoY3JlYXRlSHRtbCh0aGlzLnYpKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBmdW5jdGlvbiB0byBiZSBjYWxsZWRcbiAgICogd2hlbiB0aGUgY29udHJvbCByZWNlaXZlcyBhIGNoYW5nZSBldmVudC5cbiAgICpcbiAgICogQHBhcmFtIGZuIGEgZnVuY3Rpb25cbiAgICovXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIC8vIHRoaXMub25TdWdnZXN0aW9uU2VsZWN0ZWQgPSBmbjtcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG4gICAqIHdoZW4gdGhlIGNvbnRyb2wgcmVjZWl2ZXMgYSB0b3VjaCBldmVudC5cbiAgICpcbiAgICogQHBhcmFtIGZuIGEgZnVuY3Rpb25cbiAgICovXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcGxlbWVudHMgZGlzYWJsZWQgc3RhdGUgZm9yIHRoaXMgZWxlbWVudFxuICAgKlxuICAgKiBAcGFyYW0gaXNEaXNhYmxlZCBEaXNhYmxlZCBzdGF0ZSBmbGFnXG4gICAqL1xuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImF1dG9jb21wbGV0ZVwiPlxuICA8aW5wdXQgW2Rpc2FibGVkXT1cImRpc2FibGVkICA/IHRydWUgOiBudWxsXCIgdHlwZT1cInRleHRcIiBjbGFzcz1cInNlYXJjaFwiICNpbnB1dFZhbHVlIChpbnB1dCk9XCJnZXREYXRhKGlucHV0VmFsdWUudmFsdWUpXCJcbiAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiIChrZXl1cC5BcnJvd0Rvd24pPVwib25BcnJvd0Rvd24oKVwiIChrZXl1cC5BcnJvd1VwKT1cIm9uQXJyb3dVcCgpXCJcbiAgICAgICAgIChrZXl1cC5FbnRlcik9XCJvbkVudGVyKCRldmVudClcIiBzcGVsbGNoZWNrPVwiZmFsc2VcIiBbKG5nTW9kZWwpXT1cInZhbHVlXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgLz5cbiAgPGRpdiAqbmdJZj1cImRhdGEubGVuZ3RoXCI+XG4gICAgPGRpdiBjbGFzcz1cImF1dG9jb21wbGV0ZS1pdGVtc1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImF1dG9jb21wbGVsZS1pdGVtXCIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZGF0YTsgbGV0IGkgPSBpbmRleFwiIChjbGljayk9XCJvbkNsaWNrKCRldmVudCwgaXRlbSlcIiBbaWRdPVwiaSsnaXRlbSdcIj5cbiAgICAgICAge3tpdGVtLnZhbHVlfX1cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInR5cGU9PT0ncGFydHknXCI+XG4gICAgICAgICAgPGJyLz5cbiAgICAgICAgICA8c3Bhbj57e2l0ZW0uZGF0YT8uaW5ufX0ge3tjb25maWcucGFydHlBZGRyZXNzID09PSAnZnVsbCcgPyBpdGVtLmRhdGE/LmFkZHJlc3M/LnZhbHVlIDogaXRlbS5kYXRhPy5hZGRyZXNzPy5kYXRhPy5jaXR5fX08L3NwYW4+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==