UNPKG

ddata-ui-input

Version:

DData UI Input module, components, models & services

116 lines 23.2 kB
import { Component, HostListener, Input, ViewChild } from '@angular/core'; import { faSearch } from '@fortawesome/free-solid-svg-icons'; // tslint:disable-next-line: max-line-length import { DdataCoreModule, Paginate, ProxyFactoryService, SpinnerService } from 'ddata-core'; import { BehaviorSubject, fromEvent } from 'rxjs'; import { debounceTime, distinctUntilChanged, finalize, map, switchMap, take, takeUntil, tap } from 'rxjs/operators'; import { BaseSearch } from '../../models/search/base-search.model'; import { BaseSearchResult } from '../../models/search/result/base-search-result.model'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/common"; import * as i3 from "@fortawesome/angular-fontawesome"; import * as i4 from "@angular/forms"; export class DdataInputSearchComponent { constructor(elementRef, router) { this.elementRef = elementRef; this.router = router; this.model = new BaseSearch().init(); this.pageNumber = 0; this.service = new ProxyFactoryService().get(BaseSearch); this.icon = { search: faSearch, }; this.isActive = new BehaviorSubject(false); this.models = []; this.paginate = new Paginate(BaseSearchResult); this.spinner = DdataCoreModule.InjectorInstance.get(SpinnerService); } clickout(event) { if (!this.elementRef.nativeElement.contains(event.target)) { // click out of component this.close(); } } ngOnDestroy() { this.isActive.next(false); } close() { this.models = []; this.isActive.next(false); } search() { // don't run if search string is empty, but reset models & close previous connection if (this.model.searchText === '') { this.isActive.next(false); this.models = []; return; } // close previous connection this.isActive.next(false); return fromEvent(this.searchInput.nativeElement, 'keyup').pipe( // run after 500 ms of last keyup debounceTime(500), // run only if value is changed distinctUntilChanged(), // run only if search input is still active and value is not empty string takeUntil(this.isActive), // switch on spinner tap(() => this.spinner.on('search')), // run search method switchMap(() => this.service.search(this.model.prepareToSave(), this.pageNumber).pipe(map((result) => { this.setResult(result); return result; }))), // switch off spinner finalize(() => this.spinner.off('search'))); } changePage(turnToPage) { this.service.getPage(turnToPage).pipe( // run only if search input is still active and value is not empty string takeUntil(this.isActive), // take only last result take(1), // switch on spinner tap(() => this.spinner.on('global-search-change-page')), // set result map((result) => { this.setResult(result); return result; }), // switch off spinner finalize(() => this.spinner.off('global-search-change-page'))).subscribe(); } go(model) { const url = model.url + '/edit/' + model.id; this.close(); this.router.navigateByUrl(url); } setResult(result) { this.paginate = result; this.models = []; result.data.forEach((item) => { const model = new BaseSearchResult().init(item); this.models.push(model); }); } } DdataInputSearchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DdataInputSearchComponent, deps: [{ token: i0.ElementRef }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); DdataInputSearchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.2", type: DdataInputSearchComponent, selector: "dd-search", inputs: { model: "model", pageNumber: "pageNumber", service: "service" }, host: { listeners: { "document:click": "clickout($event)" } }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: "<div class=\"col-12 px-0\">\n <!-- keres\u0151 input -->\n <div class=\"input-group\" id=\"dropdownMenuButton\">\n <input #searchInput type=\"text\" autocomplete=\"off\" class=\"form-control border-0\" placeholder=\"Keres\u00E9s...\"\n name=\"search-string\" [(ngModel)]=\"model.searchText\">\n\n <div class=\"input-group-append\">\n <button type=\"submit\" class=\"btn btn-secondary border-0\" (click)=\"search()\">\n <fa-icon [icon]=\"icon.search\" [fixedWidth]=\"true\"></fa-icon>\n </button>\n </div>\n\n </div>\n\n <!-- dropdown men\u00FC -->\n <div class=\"search-dropdown col-12\" *ngIf=\"models.length > 0\" [ngStyle]=\"{'display': models.length > 0 ? 'block' : 'none' }\">\n <div class=\"border-bottom text-left dropdown-item\" *ngFor=\"let model of models\" (click)=\"go(model)\">\n <div class=\"row\">\n <!-- icon -->\n <div class=\"col-1 px-0 text-center text-muted\">\n <fa-icon [icon]=\"model.icon\" [fixedWidth]=\"true\"></fa-icon>\n </div>\n <div class=\"col-10\">\n <!-- name -->\n <div class=\"row\">\n <div class=\"col-12 font-bold\">\n {{ model.name }}\n </div>\n </div>\n <!-- description -->\n <div class=\"row\">\n <div class=\"col-12 small text-muted\" [innerHTML]=\"model.description | description\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <app-paginate [paginate]=\"paginate\" (changePage)=\"changePage($event)\"></app-paginate>\n </div>\n</div>\n", styles: [".search-dropdown{position:absolute;top:100%;left:0;z-index:1000;display:block;float:left;min-width:10rem;max-height:70vh;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;overflow-y:auto}.search-dropdown .dropdown-item{cursor:pointer;white-space:normal}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DdataInputSearchComponent, decorators: [{ type: Component, args: [{ selector: 'dd-search', template: "<div class=\"col-12 px-0\">\n <!-- keres\u0151 input -->\n <div class=\"input-group\" id=\"dropdownMenuButton\">\n <input #searchInput type=\"text\" autocomplete=\"off\" class=\"form-control border-0\" placeholder=\"Keres\u00E9s...\"\n name=\"search-string\" [(ngModel)]=\"model.searchText\">\n\n <div class=\"input-group-append\">\n <button type=\"submit\" class=\"btn btn-secondary border-0\" (click)=\"search()\">\n <fa-icon [icon]=\"icon.search\" [fixedWidth]=\"true\"></fa-icon>\n </button>\n </div>\n\n </div>\n\n <!-- dropdown men\u00FC -->\n <div class=\"search-dropdown col-12\" *ngIf=\"models.length > 0\" [ngStyle]=\"{'display': models.length > 0 ? 'block' : 'none' }\">\n <div class=\"border-bottom text-left dropdown-item\" *ngFor=\"let model of models\" (click)=\"go(model)\">\n <div class=\"row\">\n <!-- icon -->\n <div class=\"col-1 px-0 text-center text-muted\">\n <fa-icon [icon]=\"model.icon\" [fixedWidth]=\"true\"></fa-icon>\n </div>\n <div class=\"col-10\">\n <!-- name -->\n <div class=\"row\">\n <div class=\"col-12 font-bold\">\n {{ model.name }}\n </div>\n </div>\n <!-- description -->\n <div class=\"row\">\n <div class=\"col-12 small text-muted\" [innerHTML]=\"model.description | description\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <app-paginate [paginate]=\"paginate\" (changePage)=\"changePage($event)\"></app-paginate>\n </div>\n</div>\n", styles: [".search-dropdown{position:absolute;top:100%;left:0;z-index:1000;display:block;float:left;min-width:10rem;max-height:70vh;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;overflow-y:auto}.search-dropdown .dropdown-item{cursor:pointer;white-space:normal}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.Router }]; }, propDecorators: { model: [{ type: Input }], pageNumber: [{ type: Input }], service: [{ type: Input }], searchInput: [{ type: ViewChild, args: ['searchInput'] }], clickout: [{ type: HostListener, args: ['document:click', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RkYXRhLXVpLWlucHV0L3NyYy9saWIvY29tcG9uZW50cy9zZWFyY2gvc2VhcmNoLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RkYXRhLXVpLWlucHV0L3NyYy9saWIvY29tcG9uZW50cy9zZWFyY2gvc2VhcmNoLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLEtBQUssRUFBYSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFakcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzdELDRDQUE0QztBQUM1QyxPQUFPLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBcUIsbUJBQW1CLEVBQXlCLGNBQWMsRUFBMkIsTUFBTSxZQUFZLENBQUM7QUFDL0osT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDOUQsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXBILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQzs7Ozs7O0FBU3ZGLE1BQU0sT0FBTyx5QkFBeUI7SUFzQnBDLFlBQ1UsVUFBc0IsRUFDdEIsTUFBYztRQURkLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQXZCZixVQUFLLEdBQW9CLElBQUksVUFBVSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDakQsZUFB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QVVvQixXQUFXO3NCQUFwQyxTQUFTO3VCQUFDLGFBQWE7Z0JBRW9CLFFBQVE7c0JBQW5ELFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25EZXN0cm95LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBmYVNlYXJjaCB9IGZyb20gJ0Bmb3J0YXdlc29tZS9mcmVlLXNvbGlkLXN2Zy1pY29ucyc7XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG1heC1saW5lLWxlbmd0aFxuaW1wb3J0IHsgRGRhdGFDb3JlTW9kdWxlLCBQYWdpbmF0ZSwgUGFnaW5hdGVJbnRlcmZhY2UsIFByb3h5RmFjdG9yeVNlcnZpY2UsIFByb3h5U2VydmljZUludGVyZmFjZSwgU3Bpbm5lclNlcnZpY2UsIFNwaW5uZXJTZXJ2aWNlSW50ZXJmYWNlIH0gZnJvbSAnZGRhdGEtY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGZyb21FdmVudCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmluYWxpemUsIG1hcCwgc3dpdGNoTWFwLCB0YWtlLCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEljb25TZXRJbnRlcmZhY2UgfSBmcm9tICcuLi8uLi9tb2RlbHMvaWNvbi1zZXQvaWNvbi1zZXQuaW50ZXJmYWNlJztcbmltcG9ydCB7IEJhc2VTZWFyY2ggfSBmcm9tICcuLi8uLi9tb2RlbHMvc2VhcmNoL2Jhc2Utc2VhcmNoLm1vZGVsJztcbmltcG9ydCB7IEJhc2VTZWFyY2hSZXN1bHQgfSBmcm9tICcuLi8uLi9tb2RlbHMvc2VhcmNoL3Jlc3VsdC9iYXNlLXNlYXJjaC1yZXN1bHQubW9kZWwnO1xuaW1wb3J0IHsgU2VhcmNoUmVzdWx0SW50ZXJmYWNlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3NlYXJjaC9yZXN1bHQvc2VhcmNoLXJlc3VsdC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgU2VhcmNoSW50ZXJmYWNlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3NlYXJjaC9zZWFyY2guaW50ZXJmYWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZGQtc2VhcmNoJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3NlYXJjaC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NlYXJjaC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIERkYXRhSW5wdXRTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBtb2RlbDogU2VhcmNoSW50ZXJmYWNlID0gbmV3IEJhc2VTZWFyY2goKS5pbml0KCk7XG4gIEBJbnB1dCgpIHBhZ2VOdW1iZXIgPSAwO1xuICBASW5wdXQoKSBzZXJ2aWNlOiBQcm94eVNlcnZpY2VJbnRlcmZhY2U8U2VhcmNoSW50ZXJmYWNlPiA9IG5ldyBQcm94eUZhY3RvcnlTZXJ2aWNlPFNlYXJjaEludGVyZmFjZT4oKS5nZXQoQmFzZVNlYXJjaCk7XG5cbiAgaWNvbjogSWNvblNldEludGVyZmFjZSA9IHtcbiAgICBzZWFyY2g6IGZhU2VhcmNoLFxuICB9O1xuICBpc0FjdGl2ZTogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG4gIG1vZGVsczogU2VhcmNoUmVzdWx0SW50ZXJmYWNlW10gPSBbXTtcbiAgcGFnaW5hdGU6IFBhZ2luYXRlSW50ZXJmYWNlID0gbmV3IFBhZ2luYXRlKEJhc2VTZWFyY2hSZXN1bHQpO1xuICBzcGlubmVyOiBTcGlubmVyU2VydmljZUludGVyZmFjZSA9IERkYXRhQ29yZU1vZHVsZS5JbmplY3Rvckluc3RhbmNlLmdldDxTcGlubmVyU2VydmljZUludGVyZmFjZT4oU3Bpbm5lclNlcnZpY2UpO1xuXG4gIEBWaWV3Q2hpbGQoJ3NlYXJjaElucHV0Jykgc2VhcmNoSW5wdXQ6IEVsZW1lbnRSZWY7XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKSBjbGlja291dChldmVudDogYW55KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICAvLyBjbGljayBvdXQgb2YgY29tcG9uZW50XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICkge31cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmlzQWN0aXZlLm5leHQoZmFsc2UpO1xuICB9XG5cbiAgY2xvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5tb2RlbHMgPSBbXTtcbiAgICB0aGlzLmlzQWN0aXZlLm5leHQoZmFsc2UpO1xuICB9XG5cbiAgc2VhcmNoKCk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgLy8gZG9uJ3QgcnVuIGlmIHNlYXJjaCBzdHJpbmcgaXMgZW1wdHksIGJ1dCByZXNldCBtb2RlbHMgJiBjbG9zZSBwcmV2aW91cyBjb25uZWN0aW9uXG4gICAgaWYgKHRoaXMubW9kZWwuc2VhcmNoVGV4dCA9PT0gJycpIHtcbiAgICAgIHRoaXMuaXNBY3RpdmUubmV4dChmYWxzZSk7XG4gICAgICB0aGlzLm1vZGVscyA9IFtdO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gY2xvc2UgcHJldmlvdXMgY29ubmVjdGlvblxuICAgIHRoaXMuaXNBY3RpdmUubmV4dChmYWxzZSk7XG5cbiAgICByZXR1cm4gZnJvbUV2ZW50KHRoaXMuc2VhcmNoSW5wdXQubmF0aXZlRWxlbWVudCwgJ2tleXVwJykucGlwZShcbiAgICAgIC8vIHJ1biBhZnRlciA1MDAgbXMgb2YgbGFzdCBrZXl1cFxuICAgICAgZGVib3VuY2VUaW1lKDUwMCksXG5cbiAgICAgIC8vIHJ1biBvbmx5IGlmIHZhbHVlIGlzIGNoYW5nZWRcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG5cbiAgICAgIC8vIHJ1biBvbmx5IGlmIHNlYXJjaCBpbnB1dCBpcyBzdGlsbCBhY3RpdmUgYW5kIHZhbHVlIGlzIG5vdCBlbXB0eSBzdHJpbmdcbiAgICAgIHRha2VVbnRpbCh0aGlzLmlzQWN0aXZlKSxcblxuICAgICAgLy8gc3dpdGNoIG9uIHNwaW5uZXJcbiAgICAgIHRhcCgoKSA9PiB0aGlzLnNwaW5uZXIub24oJ3NlYXJjaCcpKSxcblxuICAgICAgLy8gcnVuIHNlYXJjaCBtZXRob2RcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnNlcnZpY2Uuc2VhcmNoKHRoaXMubW9kZWwucHJlcGFyZVRvU2F2ZSgpLCB0aGlzLnBhZ2VOdW1iZXIpLnBpcGUoXG4gICAgICAgIG1hcCgocmVzdWx0OiBQYWdpbmF0ZUludGVyZmFjZSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0UmVzdWx0KHJlc3VsdCk7XG5cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9KVxuICAgICAgKSksXG5cbiAgICAgIC8vIHN3aXRjaCBvZmYgc3Bpbm5lclxuICAgICAgZmluYWxpemUoKCkgPT4gdGhpcy5zcGlubmVyLm9mZignc2VhcmNoJykpLFxuXG4gICAgKTtcbiAgfVxuXG4gIGNoYW5nZVBhZ2UodHVyblRvUGFnZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2aWNlLmdldFBhZ2UodHVyblRvUGFnZSkucGlwZShcbiAgICAgIC8vIHJ1biBvbmx5IGlmIHNlYXJjaCBpbnB1dCBpcyBzdGlsbCBhY3RpdmUgYW5kIHZhbHVlIGlzIG5vdCBlbXB0eSBzdHJpbmdcbiAgICAgIHRha2VVbnRpbCh0aGlzLmlzQWN0aXZlKSxcblxuICAgICAgLy8gdGFrZSBvbmx5IGxhc3QgcmVzdWx0XG4gICAgICB0YWtlKDEpLFxuXG4gICAgICAvLyBzd2l0Y2ggb24gc3Bpbm5lclxuICAgICAgdGFwKCgpID0+IHRoaXMuc3Bpbm5lci5vbignZ2xvYmFsLXNlYXJjaC1jaGFuZ2UtcGFnZScpKSxcblxuICAgICAgLy8gc2V0IHJlc3VsdFxuICAgICAgbWFwKChyZXN1bHQ6IFBhZ2luYXRlSW50ZXJmYWNlKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0UmVzdWx0KHJlc3VsdCk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pLFxuXG4gICAgICAvLyBzd2l0Y2ggb2ZmIHNwaW5uZXJcbiAgICAgIGZpbmFsaXplKCgpID0+IHRoaXMuc3Bpbm5lci5vZmYoJ2dsb2JhbC1zZWFyY2gtY2hhbmdlLXBhZ2UnKSksXG5cbiAgICApLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgZ28obW9kZWw6IFNlYXJjaEludGVyZmFjZSk6IHZvaWQge1xuICAgIGNvbnN0IHVybCA9IG1vZGVsLnVybCArICcvZWRpdC8nICsgbW9kZWwuaWQ7XG5cbiAgICB0aGlzLmNsb3NlKCk7XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybCh1cmwpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRSZXN1bHQocmVzdWx0OiBQYWdpbmF0ZUludGVyZmFjZSk6IHZvaWQge1xuICAgIHRoaXMucGFnaW5hdGUgPSByZXN1bHQ7XG4gICAgdGhpcy5tb2RlbHMgPSBbXTtcblxuICAgIHJlc3VsdC5kYXRhLmZvckVhY2goKGl0ZW06IFNlYXJjaFJlc3VsdEludGVyZmFjZSkgPT4ge1xuICAgICAgY29uc3QgbW9kZWwgPSBuZXcgQmFzZVNlYXJjaFJlc3VsdCgpLmluaXQoaXRlbSk7XG4gICAgICB0aGlzLm1vZGVscy5wdXNoKG1vZGVsKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNvbC0xMiBweC0wXCI+XG4gIDwhLS0ga2VyZXPFkSBpbnB1dCAtLT5cbiAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCIgaWQ9XCJkcm9wZG93bk1lbnVCdXR0b25cIj5cbiAgICA8aW5wdXQgI3NlYXJjaElucHV0IHR5cGU9XCJ0ZXh0XCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYm9yZGVyLTBcIiBwbGFjZWhvbGRlcj1cIktlcmVzw6lzLi4uXCJcbiAgICAgIG5hbWU9XCJzZWFyY2gtc3RyaW5nXCIgWyhuZ01vZGVsKV09XCJtb2RlbC5zZWFyY2hUZXh0XCI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAtYXBwZW5kXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGJvcmRlci0wXCIgKGNsaWNrKT1cInNlYXJjaCgpXCI+XG4gICAgICAgIDxmYS1pY29uIFtpY29uXT1cImljb24uc2VhcmNoXCIgW2ZpeGVkV2lkdGhdPVwidHJ1ZVwiPjwvZmEtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gIDwvZGl2PlxuXG4gIDwhLS0gZHJvcGRvd24gbWVuw7wgLS0+XG4gIDxkaXYgY2xhc3M9XCJzZWFyY2gtZHJvcGRvd24gY29sLTEyXCIgKm5nSWY9XCJtb2RlbHMubGVuZ3RoID4gMFwiIFtuZ1N0eWxlXT1cInsnZGlzcGxheSc6IG1vZGVscy5sZW5ndGggPiAwID8gJ2Jsb2NrJyA6ICdub25lJyB9XCI+XG4gICAgPGRpdiBjbGFzcz1cImJvcmRlci1ib3R0b20gdGV4dC1sZWZ0IGRyb3Bkb3duLWl0ZW1cIiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCIgKGNsaWNrKT1cImdvKG1vZGVsKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICA8IS0tIGljb24gLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMSBweC0wIHRleHQtY2VudGVyIHRleHQtbXV0ZWRcIj5cbiAgICAgICAgICA8ZmEtaWNvbiBbaWNvbl09XCJtb2RlbC5pY29uXCIgW2ZpeGVkV2lkdGhdPVwidHJ1ZVwiPjwvZmEtaWNvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTBcIj5cbiAgICAgICAgICA8IS0tIG5hbWUgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC0xMiBmb250LWJvbGRcIj5cbiAgICAgICAgICAgICAge3sgbW9kZWwubmFtZSB9fVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPCEtLSBkZXNjcmlwdGlvbiAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyIHNtYWxsIHRleHQtbXV0ZWRcIiBbaW5uZXJIVE1MXT1cIm1vZGVsLmRlc2NyaXB0aW9uIHwgZGVzY3JpcHRpb25cIj48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxhcHAtcGFnaW5hdGUgW3BhZ2luYXRlXT1cInBhZ2luYXRlXCIgKGNoYW5nZVBhZ2UpPVwiY2hhbmdlUGFnZSgkZXZlbnQpXCI+PC9hcHAtcGFnaW5hdGU+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=