UNPKG

ngx-typeahead-search

Version:
399 lines 29 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Subject, BehaviorSubject } from 'rxjs'; import { startWith, takeUntil } from 'rxjs/operators'; import { Component, Input, ChangeDetectionStrategy, ViewChild, ElementRef, forwardRef, ViewEncapsulation, Output, ChangeDetectorRef, } from '@angular/core'; import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; /** @type {?} */ export const TYPEAHEAD_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxTypeaheadComponent), multi: true, }; /** * @template S */ export class NgxTypeaheadComponent { /** * @param {?} cdRef */ constructor(cdRef) { this.cdRef = cdRef; /** * Allow line breaks */ this.multiline = false; /** * The list of suggestions. */ this.suggestions = []; /** * The list of keys which will apply suggestion */ this.applyingKeys = ['Tab', 'Enter']; /** * The part separator */ this.partSeparator = ' '; /** * The property of a list item that should be used for matching. */ this.searchProperty = 'title'; /** * The property of a list item that should be displayed. */ this.displayProperty = this.searchProperty; /** * The stream of focus changes */ this.focused$ = new BehaviorSubject(false); this.plainTextControl = new FormControl(''); this.typeaheadContent = null; this.destroy$ = new Subject(); // -------------------- Control Value Accessor -------------------- /** * Placeholder for a callback which is later provided by the Control Value Accessor. */ this.onTouchedCallback = () => { }; /** * Placeholder for a callback which is later provided by the Control Value Accessor. */ this.onChangeCallback = () => { }; } /** * @return {?} */ ngOnInit() { this.plainTextControl.valueChanges .pipe(startWith(this.plainTextControl.value), takeUntil(this.destroy$)) .subscribe(text => { this.setWithChangeDetection({ typeaheadContent: this.getTypeahead(text) }); this.onChangeCallback(text); }); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { /** @type {?} */ const suggestions = changes.suggestions && changes.suggestions.currentValue; if (suggestions) { this.maxWordsInSuggestionCount = this.getGreatesWordsAmount(suggestions); } } /** * @return {?} */ ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } /** * @param {?} e * @return {?} */ handleKeyDown(e) { if (this.applyingKeys.includes(e.key) && this.typeaheadContent) { e.preventDefault(); /** @type {?} */ const ok = this.applySuggestion(); if (ok) { e.stopPropagation(); } } } /** * @param {?} v * @return {?} */ writeValue(v) { if (v == null) { return; } this.plainTextControl.setValue(v); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChangeCallback = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouchedCallback = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { if (isDisabled) { this.plainTextControl.disable(); } else { this.plainTextControl.enable(); } } // -------------------- Control Value Accessor -------------------- /** * Return suggestion completion * @param {?=} input * @return {?} */ getTypeahead(input) { if (!input) { return null; } /** @type {?} */ const chunks = input.split(this.partSeparator); /** @type {?} */ let chunk; /** @type {?} */ let suggestion; for (let i = 1; i <= this.maxWordsInSuggestionCount; i++) { chunk = chunks.slice(chunks.length - i).join(' '); suggestion = this.getSuggestion(chunk); if (suggestion) { break; } } if (document.activeElement !== this.plainTextElRef.nativeElement || !suggestion || chunk.length === suggestion[this.displayProperty]) { return null; } /** @type {?} */ const displayValue = this.getDisplayValue(suggestion); return [input.substr(0, input.length), displayValue.substr(chunk.length)]; } /** * Return appropriate suggestion or null * @private * @param {?} text * @return {?} */ getSuggestion(text) { /** @type {?} */ const query = text.replace(/\s/g, () => ' '); if (!query) { return null; } try { /** @type {?} */ const searchRegExp = new RegExp(`^${query}.*`, 'i'); return this.suggestions.find(item => searchRegExp.test(this.getSearchValue(item))) || null; } catch (e) { return null; } } /** * @private * @param {?} item * @return {?} */ getSearchValue(item) { try { return typeof item === 'string' ? item : item[this.searchProperty]; } catch (e) { throw Error(`Suggestion should be string or contains searchProperty. You can set it as Input [searchProperty].`); } } /** * @private * @param {?} item * @return {?} */ getDisplayValue(item) { try { return typeof item === 'string' ? item : item[this.displayProperty]; } catch (e) { throw Error(`Suggestion should be string or contains displayProperty. You can set it as Input [displayProperty].`); } } /** * Replace text content part and ahead text on suggestion * @private * @return {?} */ applySuggestion() { /** @type {?} */ const plainText = this.plainTextControl.value; /** @type {?} */ const typeahead = this.getTypeahead(plainText); if (!typeahead) { return false; } this.plainTextControl.setValue(typeahead[0] + typeahead[1]); return true; } /** * @private * @param {?} items * @return {?} */ getGreatesWordsAmount(items) { return items.reduce((result, item) => { /** @type {?} */ const count = this.getSearchValue(item).split(this.partSeparator).length; return count > result ? count : result; }, 0); } /** * @private * @param {?} data * @return {?} */ setWithChangeDetection(data) { Object.assign(this, data); this.cdRef.detectChanges(); } } NgxTypeaheadComponent.decorators = [ { type: Component, args: [{ selector: ' ngx-typeahead', template: ` <div class="ngx-typeahead"> <input #plainText type="text" class="ngx-plain-content text" [placeholder]="placeholder" [formControl]="plainTextControl" (focus)="focused$.next(true)" (blur)="focused$.next(false)" (keydown)="handleKeyDown($event)" /> <p #typeahead class="ngx-typeahead-content"> <ng-container *ngIf="typeaheadContent"> <span [style.visibility]="(focused$ | async) ? 'visible' : 'hidden'" class="text">{{ typeaheadContent[0] }}</span ><span class="text">{{ typeaheadContent[1] }}</span> </ng-container> </p> </div> `, providers: [TYPEAHEAD_CONTROL_VALUE_ACCESSOR], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [` .ngx-typeahead { position: relative; width: 100%; height: 100%; cursor: text; } .ngx-plain-content { white-space: nowrap; overflow: hidden; outline: none; -webkit-appearance: none; padding: 8px 8px; } .ngx-typeahead-content { position: absolute; color: gray; margin: 0; } `] }] } ]; /** @nocollapse */ NgxTypeaheadComponent.ctorParameters = () => [ { type: ChangeDetectorRef } ]; NgxTypeaheadComponent.propDecorators = { multiline: [{ type: Input }], suggestions: [{ type: Input }], placeholder: [{ type: Input }], applyingKeys: [{ type: Input }], partSeparator: [{ type: Input }], searchProperty: [{ type: Input }], displayProperty: [{ type: Input }], focused$: [{ type: Output }], plainTextElRef: [{ type: ViewChild, args: ['plainText',] }] }; if (false) { /** * Allow line breaks * @type {?} */ NgxTypeaheadComponent.prototype.multiline; /** * The list of suggestions. * @type {?} */ NgxTypeaheadComponent.prototype.suggestions; /** * The input placeholder. * @type {?} */ NgxTypeaheadComponent.prototype.placeholder; /** * The list of keys which will apply suggestion * @type {?} */ NgxTypeaheadComponent.prototype.applyingKeys; /** * The part separator * @type {?} */ NgxTypeaheadComponent.prototype.partSeparator; /** * The property of a list item that should be used for matching. * @type {?} */ NgxTypeaheadComponent.prototype.searchProperty; /** * The property of a list item that should be displayed. * @type {?} */ NgxTypeaheadComponent.prototype.displayProperty; /** * The stream of focus changes * @type {?} */ NgxTypeaheadComponent.prototype.focused$; /** @type {?} */ NgxTypeaheadComponent.prototype.plainTextElRef; /** @type {?} */ NgxTypeaheadComponent.prototype.plainTextControl; /** @type {?} */ NgxTypeaheadComponent.prototype.typeaheadContent; /** * @type {?} * @private */ NgxTypeaheadComponent.prototype.maxWordsInSuggestionCount; /** * @type {?} * @private */ NgxTypeaheadComponent.prototype.destroy$; /** * Placeholder for a callback which is later provided by the Control Value Accessor. * @type {?} * @private */ NgxTypeaheadComponent.prototype.onTouchedCallback; /** * Placeholder for a callback which is later provided by the Control Value Accessor. * @type {?} * @private */ NgxTypeaheadComponent.prototype.onChangeCallback; /** * @type {?} * @private */ NgxTypeaheadComponent.prototype.cdRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXR5cGVhaGVhZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtdHlwZWFoZWFkLXNlYXJjaC8iLCJzb3VyY2VzIjpbImxpYi9uZ3gtdHlwZWFoZWFkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFVBQVUsRUFDVixVQUFVLEVBRVYsaUJBQWlCLEVBQ2pCLE1BQU0sRUFFTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFFdEYsTUFBTSxPQUFPLGdDQUFnQyxHQUFHO0lBQzlDLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQztJQUNwRCxLQUFLLEVBQUUsSUFBSTtDQUNaOzs7O0FBa0RELE1BQU0sT0FBTyxxQkFBcUI7Ozs7SUFrRGhDLFlBQW9CLEtBQXdCO1FBQXhCLFVBQUssR0FBTCxLQUFLLENBQW1COzs7O1FBOUM1QixjQUFTLEdBQVksS0FBSyxDQUFDOzs7O1FBSzNCLGdCQUFXLEdBQVEsRUFBRSxDQUFDOzs7O1FBVXRCLGlCQUFZLEdBQWEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7Ozs7UUFLMUMsa0JBQWEsR0FBVyxHQUFHLENBQUM7Ozs7UUFLNUIsbUJBQWMsR0FBVyxPQUFPLENBQUM7Ozs7UUFLakMsb0JBQWUsR0FBVyxJQUFJLENBQUMsY0FBYyxDQUFDOzs7O1FBTXZELGFBQVEsR0FBNkIsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFJaEUscUJBQWdCLEdBQWdCLElBQUksV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELHFCQUFnQixHQUE0QixJQUFJLENBQUM7UUFHaEQsYUFBUSxHQUFrQixJQUFJLE9BQU8sRUFBRSxDQUFDOzs7OztRQThDeEMsc0JBQWlCLEdBQWUsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDOzs7O1FBS3pDLHFCQUFnQixHQUFxQixHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7SUFqRFAsQ0FBQzs7OztJQUVoRCxRQUFRO1FBQ04sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVk7YUFDL0IsSUFBSSxDQUNILFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQ3RDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQ3pCO2FBQ0EsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ2hCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7Ozs7O0lBRUQsV0FBVyxDQUFDLE9BQXNCOztjQUMxQixXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLFlBQVk7UUFFM0UsSUFBSSxXQUFXLEVBQUU7WUFDZixJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQzFFO0lBQ0gsQ0FBQzs7OztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDM0IsQ0FBQzs7Ozs7SUFFTSxhQUFhLENBQUMsQ0FBZ0I7UUFDbkMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzlELENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQzs7a0JBRWIsRUFBRSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFFakMsSUFBSSxFQUFFLEVBQUU7Z0JBQ04sQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQ3JCO1NBQ0Y7SUFDSCxDQUFDOzs7OztJQWNNLFVBQVUsQ0FBQyxDQUFnQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUU7WUFDYixPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7Ozs7O0lBRU0sZ0JBQWdCLENBQUMsRUFBTztRQUM3QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0lBQzdCLENBQUM7Ozs7O0lBRU0saUJBQWlCLENBQUMsRUFBTztRQUM5QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxDQUFDO0lBQzlCLENBQUM7Ozs7O0lBRU0sZ0JBQWdCLENBQUMsVUFBbUI7UUFDekMsSUFBSSxVQUFVLEVBQUU7WUFDZCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDakM7YUFBTTtZQUNMLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUNoQztJQUNILENBQUM7Ozs7Ozs7SUFPTSxZQUFZLENBQUMsS0FBcUI7UUFDdkMsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNWLE9BQU8sSUFBSSxDQUFDO1NBQ2I7O2NBRUssTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQzs7WUFFMUMsS0FBYTs7WUFDYixVQUFhO1FBRWpCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDeEQsS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEQsVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFdkMsSUFBSSxVQUFVLEVBQUU7Z0JBQ2QsTUFBTTthQUNQO1NBQ0Y7UUFFRCxJQUNFLFFBQVEsQ0FBQyxhQUFhLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhO1lBQzVELENBQUMsVUFBVTtZQUNYLEtBQUssQ0FBQyxNQUFNLEtBQUssVUFBVSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsRUFDakQ7WUFDQSxPQUFPLElBQUksQ0FBQztTQUNiOztjQUVLLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQztRQUVyRCxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDNUUsQ0FBQzs7Ozs7OztJQUtPLGFBQWEsQ0FBQyxJQUFZOztjQUMxQixLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDO1FBRTVDLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDVixPQUFPLElBQUksQ0FBQztTQUNiO1FBRUQsSUFBSTs7a0JBQ0ksWUFBWSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDO1lBRW5ELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQztTQUM1RjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUM7Ozs7OztJQUVPLGNBQWMsQ0FBQyxJQUFPO1FBQzVCLElBQUk7WUFDRixPQUFPLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQ3BFO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLEtBQUssQ0FBQyxtR0FBbUcsQ0FBQyxDQUFDO1NBQ2xIO0lBQ0gsQ0FBQzs7Ozs7O0lBRU8sZUFBZSxDQUFDLElBQU87UUFDN0IsSUFBSTtZQUNGLE9BQU8sT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDckU7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLE1BQU0sS0FBSyxDQUNULHFHQUFxRyxDQUN0RyxDQUFDO1NBQ0g7SUFDSCxDQUFDOzs7Ozs7SUFLTyxlQUFlOztjQUNmLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSzs7Y0FDdkMsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDO1FBRTlDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDZCxPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFNUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDOzs7Ozs7SUFFTyxxQkFBcUIsQ0FBQyxLQUFVO1FBQ3RDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRTs7a0JBQzdCLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTTtZQUV4RSxPQUFPLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ3pDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7Ozs7OztJQUVPLHNCQUFzQixDQUFDLElBQXVDO1FBQ3BFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDN0IsQ0FBQzs7O1lBbFJGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO2dCQUMxQixRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQlQ7Z0JBdUJELFNBQVMsRUFBRSxDQUFDLGdDQUFnQyxDQUFDO2dCQUM3QyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtnQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7eUJBdkJuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQW1CQzthQUtKOzs7O1lBekRDLGlCQUFpQjs7O3dCQThEaEIsS0FBSzswQkFLTCxLQUFLOzBCQUtMLEtBQUs7MkJBS0wsS0FBSzs0QkFLTCxLQUFLOzZCQUtMLEtBQUs7OEJBS0wsS0FBSzt1QkFLTCxNQUFNOzZCQUdOLFNBQVMsU0FBQyxXQUFXOzs7Ozs7O0lBdEN0QiwwQ0FBMkM7Ozs7O0lBSzNDLDRDQUFzQzs7Ozs7SUFLdEMsNENBQW9DOzs7OztJQUtwQyw2Q0FBMEQ7Ozs7O0lBSzFELDhDQUE0Qzs7Ozs7SUFLNUMsK0NBQWlEOzs7OztJQUtqRCxnREFBOEQ7Ozs7O0lBSzlELHlDQUN1RTs7SUFFdkUsK0NBQXFFOztJQUVyRSxpREFBMkQ7O0lBQzNELGlEQUF3RDs7Ozs7SUFFeEQsMERBQTBDOzs7OztJQUMxQyx5Q0FBZ0Q7Ozs7OztJQThDaEQsa0RBQWlEOzs7Ozs7SUFLakQsaURBQXNEOzs7OztJQWpEMUMsc0NBQWdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3ViamVjdCwgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzdGFydFdpdGgsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBPbkNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgRWxlbWVudFJlZixcbiAgZm9yd2FyZFJlZixcbiAgT25EZXN0cm95LFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgT3V0cHV0LFxuICBPbkluaXQsXG4gIENoYW5nZURldGVjdG9yUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtQ29udHJvbCwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmV4cG9ydCBjb25zdCBUWVBFQUhFQURfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUiA9IHtcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neFR5cGVhaGVhZENvbXBvbmVudCksXG4gIG11bHRpOiB0cnVlLFxufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnIG5neC10eXBlYWhlYWQnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtdHlwZWFoZWFkXCI+XG4gICAgICA8aW5wdXRcbiAgICAgICAgI3BsYWluVGV4dFxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIGNsYXNzPVwibmd4LXBsYWluLWNvbnRlbnQgdGV4dFwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAgIFtmb3JtQ29udHJvbF09XCJwbGFpblRleHRDb250cm9sXCJcbiAgICAgICAgKGZvY3VzKT1cImZvY3VzZWQkLm5leHQodHJ1ZSlcIlxuICAgICAgICAoYmx1cik9XCJmb2N1c2VkJC5uZXh0KGZhbHNlKVwiXG4gICAgICAgIChrZXlkb3duKT1cImhhbmRsZUtleURvd24oJGV2ZW50KVwiXG4gICAgICAvPlxuICAgICAgPHAgI3R5cGVhaGVhZCBjbGFzcz1cIm5neC10eXBlYWhlYWQtY29udGVudFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidHlwZWFoZWFkQ29udGVudFwiPlxuICAgICAgICAgIDxzcGFuIFtzdHlsZS52aXNpYmlsaXR5XT1cIihmb2N1c2VkJCB8IGFzeW5jKSA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nXCIgY2xhc3M9XCJ0ZXh0XCI+e3sgdHlwZWFoZWFkQ29udGVudFswXSB9fTwvc3BhblxuICAgICAgICAgID48c3BhbiBjbGFzcz1cInRleHRcIj57eyB0eXBlYWhlYWRDb250ZW50WzFdIH19PC9zcGFuPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgLm5neC10eXBlYWhlYWQge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIGN1cnNvcjogdGV4dDtcbiAgICAgIH1cbiAgICAgIC5uZ3gtcGxhaW4tY29udGVudCB7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIG91dGxpbmU6IG5vbmU7XG4gICAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgcGFkZGluZzogOHB4IDhweDtcbiAgICAgIH1cbiAgICAgIC5uZ3gtdHlwZWFoZWFkLWNvbnRlbnQge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGNvbG9yOiBncmF5O1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbiAgcHJvdmlkZXJzOiBbVFlQRUFIRUFEX0NPTlRST0xfVkFMVUVfQUNDRVNTT1JdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgTmd4VHlwZWFoZWFkQ29tcG9uZW50PFM+IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcywgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICAvKipcbiAgICogQWxsb3cgbGluZSBicmVha3NcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBtdWx0aWxpbmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2Ygc3VnZ2VzdGlvbnMuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc3VnZ2VzdGlvbnM6IFNbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5wdXQgcGxhY2Vob2xkZXIuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2Yga2V5cyB3aGljaCB3aWxsIGFwcGx5IHN1Z2dlc3Rpb25cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBhcHBseWluZ0tleXM6IHN0cmluZ1tdID0gWydUYWInLCAnRW50ZXInXTtcblxuICAvKipcbiAgICogVGhlIHBhcnQgc2VwYXJhdG9yXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgcGFydFNlcGFyYXRvcjogc3RyaW5nID0gJyAnO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJvcGVydHkgb2YgYSBsaXN0IGl0ZW0gdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgbWF0Y2hpbmcuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc2VhcmNoUHJvcGVydHk6IHN0cmluZyA9ICd0aXRsZSc7XG5cbiAgLyoqXG4gICAqIFRoZSBwcm9wZXJ0eSBvZiBhIGxpc3QgaXRlbSB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgZGlzcGxheVByb3BlcnR5OiBzdHJpbmcgPSB0aGlzLnNlYXJjaFByb3BlcnR5O1xuXG4gIC8qKlxuICAgKiBUaGUgc3RyZWFtIG9mIGZvY3VzIGNoYW5nZXNcbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgZm9jdXNlZCQ6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuXG4gIEBWaWV3Q2hpbGQoJ3BsYWluVGV4dCcpIHBsYWluVGV4dEVsUmVmOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuXG4gIHB1YmxpYyBwbGFpblRleHRDb250cm9sOiBGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCgnJyk7XG4gIHB1YmxpYyB0eXBlYWhlYWRDb250ZW50OiBbc3RyaW5nLCBzdHJpbmddIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBtYXhXb3Jkc0luU3VnZ2VzdGlvbkNvdW50OiBudW1iZXI7XG4gIHByaXZhdGUgZGVzdHJveSQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2RSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMucGxhaW5UZXh0Q29udHJvbC52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKFxuICAgICAgICBzdGFydFdpdGgodGhpcy5wbGFpblRleHRDb250cm9sLnZhbHVlKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHRleHQgPT4ge1xuICAgICAgICB0aGlzLnNldFdpdGhDaGFuZ2VEZXRlY3Rpb24oeyB0eXBlYWhlYWRDb250ZW50OiB0aGlzLmdldFR5cGVhaGVhZCh0ZXh0KSB9KTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrKHRleHQpO1xuICAgICAgfSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3Qgc3VnZ2VzdGlvbnMgPSBjaGFuZ2VzLnN1Z2dlc3Rpb25zICYmIGNoYW5nZXMuc3VnZ2VzdGlvbnMuY3VycmVudFZhbHVlO1xuXG4gICAgaWYgKHN1Z2dlc3Rpb25zKSB7XG4gICAgICB0aGlzLm1heFdvcmRzSW5TdWdnZXN0aW9uQ291bnQgPSB0aGlzLmdldEdyZWF0ZXNXb3Jkc0Ftb3VudChzdWdnZXN0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZUtleURvd24oZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFwcGx5aW5nS2V5cy5pbmNsdWRlcyhlLmtleSkgJiYgdGhpcy50eXBlYWhlYWRDb250ZW50KSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIGNvbnN0IG9rID0gdGhpcy5hcHBseVN1Z2dlc3Rpb24oKTtcblxuICAgICAgaWYgKG9rKSB7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ29udHJvbCBWYWx1ZSBBY2Nlc3NvciAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBQbGFjZWhvbGRlciBmb3IgYSBjYWxsYmFjayB3aGljaCBpcyBsYXRlciBwcm92aWRlZCBieSB0aGUgQ29udHJvbCBWYWx1ZSBBY2Nlc3Nvci5cbiAgICovXG4gIHByaXZhdGUgb25Ub3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICAvKipcbiAgICogUGxhY2Vob2xkZXIgZm9yIGEgY2FsbGJhY2sgd2hpY2ggaXMgbGF0ZXIgcHJvdmlkZWQgYnkgdGhlIENvbnRyb2wgVmFsdWUgQWNjZXNzb3IuXG4gICAqL1xuICBwcml2YXRlIG9uQ2hhbmdlQ2FsbGJhY2s6IChfOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBwdWJsaWMgd3JpdGVWYWx1ZSh2OiBzdHJpbmcgfCBudWxsKSB7XG4gICAgaWYgKHYgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucGxhaW5UZXh0Q29udHJvbC5zZXRWYWx1ZSh2KTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpIHtcbiAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KSB7XG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9IGZuO1xuICB9XG5cbiAgcHVibGljIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChpc0Rpc2FibGVkKSB7XG4gICAgICB0aGlzLnBsYWluVGV4dENvbnRyb2wuZGlzYWJsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBsYWluVGV4dENvbnRyb2wuZW5hYmxlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ29udHJvbCBWYWx1ZSBBY2Nlc3NvciAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gc3VnZ2VzdGlvbiBjb21wbGV0aW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0VHlwZWFoZWFkKGlucHV0Pzogc3RyaW5nIHwgbnVsbCk6IFtzdHJpbmcsIHN0cmluZ10gfCBudWxsIHtcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBjaHVua3MgPSBpbnB1dC5zcGxpdCh0aGlzLnBhcnRTZXBhcmF0b3IpO1xuXG4gICAgbGV0IGNodW5rOiBzdHJpbmc7XG4gICAgbGV0IHN1Z2dlc3Rpb246IFM7XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSB0aGlzLm1heFdvcmRzSW5TdWdnZXN0aW9uQ291bnQ7IGkrKykge1xuICAgICAgY2h1bmsgPSBjaHVua3Muc2xpY2UoY2h1bmtzLmxlbmd0aCAtIGkpLmpvaW4oJyAnKTtcbiAgICAgIHN1Z2dlc3Rpb24gPSB0aGlzLmdldFN1Z2dlc3Rpb24oY2h1bmspO1xuXG4gICAgICBpZiAoc3VnZ2VzdGlvbikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSB0aGlzLnBsYWluVGV4dEVsUmVmLm5hdGl2ZUVsZW1lbnQgfHxcbiAgICAgICFzdWdnZXN0aW9uIHx8XG4gICAgICBjaHVuay5sZW5ndGggPT09IHN1Z2dlc3Rpb25bdGhpcy5kaXNwbGF5UHJvcGVydHldXG4gICAgKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBkaXNwbGF5VmFsdWUgPSB0aGlzLmdldERpc3BsYXlWYWx1ZShzdWdnZXN0aW9uKTtcblxuICAgIHJldHVybiBbaW5wdXQuc3Vic3RyKDAsIGlucHV0Lmxlbmd0aCksIGRpc3BsYXlWYWx1ZS5zdWJzdHIoY2h1bmsubGVuZ3RoKV07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFwcHJvcHJpYXRlIHN1Z2dlc3Rpb24gb3IgbnVsbFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRTdWdnZXN0aW9uKHRleHQ6IHN0cmluZyk6IFMgfCBudWxsIHtcbiAgICBjb25zdCBxdWVyeSA9IHRleHQucmVwbGFjZSgvXFxzL2csICgpID0+ICcgJyk7XG5cbiAgICBpZiAoIXF1ZXJ5KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgc2VhcmNoUmVnRXhwID0gbmV3IFJlZ0V4cChgXiR7cXVlcnl9LipgLCAnaScpO1xuXG4gICAgICByZXR1cm4gdGhpcy5zdWdnZXN0aW9ucy5maW5kKGl0ZW0gPT4gc2VhcmNoUmVnRXhwLnRlc3QodGhpcy5nZXRTZWFyY2hWYWx1ZShpdGVtKSkpIHx8IG51bGw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRTZWFyY2hWYWx1ZShpdGVtOiBTKTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJyA/IGl0ZW0gOiBpdGVtW3RoaXMuc2VhcmNoUHJvcGVydHldO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IEVycm9yKGBTdWdnZXN0aW9uIHNob3VsZCBiZSBzdHJpbmcgb3IgY29udGFpbnMgc2VhcmNoUHJvcGVydHkuIFlvdSBjYW4gc2V0IGl0IGFzIElucHV0IFtzZWFyY2hQcm9wZXJ0eV0uYCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXREaXNwbGF5VmFsdWUoaXRlbTogUyk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycgPyBpdGVtIDogaXRlbVt0aGlzLmRpc3BsYXlQcm9wZXJ0eV07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgIGBTdWdnZXN0aW9uIHNob3VsZCBiZSBzdHJpbmcgb3IgY29udGFpbnMgZGlzcGxheVByb3BlcnR5LiBZb3UgY2FuIHNldCBpdCBhcyBJbnB1dCBbZGlzcGxheVByb3BlcnR5XS5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRleHQgY29udGVudCBwYXJ0IGFuZCBhaGVhZCB0ZXh0IG9uIHN1Z2dlc3Rpb25cbiAgICovXG4gIHByaXZhdGUgYXBwbHlTdWdnZXN0aW9uKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBsYWluVGV4dCA9IHRoaXMucGxhaW5UZXh0Q29udHJvbC52YWx1ZTtcbiAgICBjb25zdCB0eXBlYWhlYWQgPSB0aGlzLmdldFR5cGVhaGVhZChwbGFpblRleHQpO1xuXG4gICAgaWYgKCF0eXBlYWhlYWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLnBsYWluVGV4dENvbnRyb2wuc2V0VmFsdWUodHlwZWFoZWFkWzBdICsgdHlwZWFoZWFkWzFdKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRHcmVhdGVzV29yZHNBbW91bnQoaXRlbXM6IFNbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGl0ZW1zLnJlZHVjZSgocmVzdWx0LCBpdGVtKSA9PiB7XG4gICAgICBjb25zdCBjb3VudCA9IHRoaXMuZ2V0U2VhcmNoVmFsdWUoaXRlbSkuc3BsaXQodGhpcy5wYXJ0U2VwYXJhdG9yKS5sZW5ndGg7XG5cbiAgICAgIHJldHVybiBjb3VudCA+IHJlc3VsdCA/IGNvdW50IDogcmVzdWx0O1xuICAgIH0sIDApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRXaXRoQ2hhbmdlRGV0ZWN0aW9uKGRhdGE6IFBhcnRpYWw8Tmd4VHlwZWFoZWFkQ29tcG9uZW50PFM+Pik6IHZvaWQge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgZGF0YSk7XG4gICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cbn1cbiJdfQ==