UNPKG

ngx-tagify

Version:

Angular library that wraps @yaireo/tagify

229 lines 28.5 kB
import { Component, EventEmitter, forwardRef, Input, Output, ViewChild, } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { asyncScheduler, BehaviorSubject, fromEvent, Subject, } from 'rxjs'; import { takeUntil, throttleTime } from 'rxjs/operators'; import Tagify from '@yaireo/tagify'; import * as i0 from "@angular/core"; import * as i1 from "./tagify.service"; import * as i2 from "@angular/common"; export class TagifyComponent { set inputClass(v) { this.setTagsClass(v); this.inputClassValue = v; } set readonly(v) { this.readonlyValue = !!v; this.setReadonly(); } set disabled(v) { this.disabledValue = !!v; this.setDisabled(); } get value() { return this.valueData; } set value(v) { if (v !== this.valueData) { this.valueData = v; this.onChange(v); } } constructor(tagifyService, element) { this.tagifyService = tagifyService; this.element = element; this.valueType = 'undefined'; this.onChange = Function.prototype; this.onTouched = Function.prototype; this.unsubscribe$ = new Subject(); this.value$ = new BehaviorSubject(null); this.skip = false; this.inputClassValue = ''; this.readonlyValue = false; this.disabledValue = false; this.settings = {}; this.name = ''; this.add = new EventEmitter(); this.remove = new EventEmitter(); this.tInput = new EventEmitter(); } ngAfterViewInit() { this.settings.callbacks = this.settings.callbacks || {}; if (!Object.prototype.hasOwnProperty.call(this.settings.callbacks, 'add')) { this.settings.callbacks.add = () => this.add.emit({ tags: this.tagify.value, added: this.tagify.value[this.tagify.value.length - 1], }); } if (!Object.prototype.hasOwnProperty.call(this.settings.callbacks, 'remove')) { this.settings.callbacks.remove = () => this.remove.emit(this.tagify.value); } const innerText = this.element.nativeElement.textContent; this.tagify = new Tagify(this.inputRef.nativeElement, this.settings); // add to service if name is provided if (this.name.length) { this.tagifyService.add(this.name, this.tagify); } this.setReadonly(); this.setDisabled(); // if there is some text inside component, load this value and skip first change check if (innerText.length) { this.tagify.loadOriginalValues(innerText); this.skip = true; setTimeout(() => { this.setValue(); }); } // listen to value changes from outside this.value$.pipe(takeUntil(this.unsubscribe$)).subscribe((tags) => { if (tags === null) return; if (this.skip) { this.skip = false; return; } if (this.valueType === 'undefined') { this.valueType = typeof tags; } // if string is passed, e.g. via reactive forms if (typeof tags === 'string') { this.tagify.loadOriginalValues(tags); setTimeout(() => { this.setValue(); }); return; } // add all tags (already existing tags will be skipped this.tagify.addTags(tags, false, true); // remove all tags that are not part of value anymore this.tagify.value.forEach((v) => { if (!tags.find((t) => t.value === v.value)) { // somehow removeTags() with string parameter doesn't always find the tag element // this is a workaround for finding the right tag element const tagElm = this.tagify .getTagElms() .find((el) => el.attributes.getNamedItem('value').textContent === v.value); this.tagify.removeTags(tagElm); } }); }); // listen to tagify events this.tagify.on('input', (e) => { const value = 'value' in e.detail ? e.detail.value : e.detail.textContent; this.tInput.emit(value); if (this.valueType === 'string' && this.tagify.settings.mode === 'mix') { this.value = this.tagify.getMixedTagsAsString(); } }); fromEvent(this.tagify, 'change') .pipe( // throttle used to reduce number of value changes when adding/removing a bunch of tags throttleTime(0, asyncScheduler, { leading: false, trailing: true }), takeUntil(this.unsubscribe$)) .subscribe(() => { this.setValue(); }); // listen to suggestions updates if (this.whitelist) { this.whitelist.pipe(takeUntil(this.unsubscribe$)).subscribe((list) => { this.tagify.settings.whitelist = list; }); } } writeValue(tags) { this.value$.next(tags); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setValue() { if (this.valueType === 'string') { if (this.tagify.settings.mode === 'mix') { this.value = this.tagify.getMixedTagsAsString(); } else { this.value = this.tagify.DOM.originalInput.value; } } else { this.value = this.tagify.value.slice(); } } /** * Tagify creates a `tags` element to which the classes of the `input` element are applied. * Changes of `inputClass` are applied automatically to the `input` element, but have to be * manually applied to the `tags` element. */ setTagsClass(v) { const tagsElement = this.element.nativeElement.querySelector('tags'); if (tagsElement) { tagsElement.classList.remove(...this.inputClassValue.split(/\s+/)); tagsElement.classList.add(...v.split(/\s+/)); } } setReadonly() { if (this.tagify) { this.tagify.setReadonly(this.readonlyValue); } } setDisabled() { if (this.tagify) { this.tagify.setDisabled(this.disabledValue); } } ngOnDestroy() { this.unsubscribe$.next(); this.unsubscribe$.complete(); this.tagify.destroy(); if (this.name.length) { this.tagifyService.remove(this.name); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TagifyComponent, deps: [{ token: i1.TagifyService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TagifyComponent, selector: "tagify", inputs: { settings: "settings", name: "name", whitelist: "whitelist", inputClass: "inputClass", readonly: "readonly", disabled: "disabled" }, outputs: { add: "add", remove: "remove", tInput: "tInput" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TagifyComponent), multi: true, }, ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, static: true }], ngImport: i0, template: `<input [ngClass]="inputClassValue" #inputRef /> <span style="display: none"><ng-content></ng-content></span>`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TagifyComponent, decorators: [{ type: Component, args: [{ selector: 'tagify', template: `<input [ngClass]="inputClassValue" #inputRef /> <span style="display: none"><ng-content></ng-content></span>`, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TagifyComponent), multi: true, }, ], }] }], ctorParameters: () => [{ type: i1.TagifyService }, { type: i0.ElementRef }], propDecorators: { inputRef: [{ type: ViewChild, args: ['inputRef', { static: true }] }], settings: [{ type: Input }], name: [{ type: Input }], whitelist: [{ type: Input }], inputClass: [{ type: Input }], readonly: [{ type: Input }], disabled: [{ type: Input }], add: [{ type: Output }], remove: [{ type: Output }], tInput: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnaWZ5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10YWdpZnkvc3JjL2xpYi90YWdpZnkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBRVQsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUNMLGNBQWMsRUFDZCxlQUFlLEVBQ2YsU0FBUyxFQUVULE9BQU8sR0FDUixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxNQUFtQyxNQUFNLGdCQUFnQixDQUFDOzs7O0FBZWpFLE1BQU0sT0FBTyxlQUFlO0lBMEIxQixJQUFhLFVBQVUsQ0FBQyxDQUFTO1FBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQWEsUUFBUSxDQUFDLENBQVU7UUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsSUFBYSxRQUFRLENBQUMsQ0FBVTtRQUM5QixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLENBQXFCO1FBQzdC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QUFDLE9BQU8sRUFBRSxDQUFDO1FBRXRCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7K0dBbE9VLGVBQWU7bUdBQWYsZUFBZSw0T0FSZjtZQUNUO2dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDO2dCQUM5QyxLQUFLLEVBQUUsSUFBSTthQUNaO1NBQ0YsOElBUlM7aUVBQ3FEOzs0RkFTcEQsZUFBZTtrQkFaM0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsUUFBUTtvQkFDbEIsUUFBUSxFQUFFO2lFQUNxRDtvQkFDL0QsU0FBUyxFQUFFO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLGdCQUFnQixDQUFDOzRCQUM5QyxLQUFLLEVBQUUsSUFBSTt5QkFDWjtxQkFDRjtpQkFDRjsyR0FtQkMsUUFBUTtzQkFEUCxTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBRzlCLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRU8sVUFBVTtzQkFBdEIsS0FBSztnQkFLTyxRQUFRO3NCQUFwQixLQUFLO2dCQUtPLFFBQVE7c0JBQXBCLEtBQUs7Z0JBZ0JJLEdBQUc7c0JBQVosTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIGFzeW5jU2NoZWR1bGVyLFxuICBCZWhhdmlvclN1YmplY3QsXG4gIGZyb21FdmVudCxcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwsIHRocm90dGxlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCBUYWdpZnksIHsgVGFnRGF0YSwgVGFnaWZ5U2V0dGluZ3MgfSBmcm9tICdAeWFpcmVvL3RhZ2lmeSc7XG5pbXBvcnQgeyBUYWdpZnlTZXJ2aWNlIH0gZnJvbSAnLi90YWdpZnkuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RhZ2lmeScsXG4gIHRlbXBsYXRlOiBgPGlucHV0IFtuZ0NsYXNzXT1cImlucHV0Q2xhc3NWYWx1ZVwiICNpbnB1dFJlZiAvPlxuICAgIDxzcGFuIHN0eWxlPVwiZGlzcGxheTogbm9uZVwiPjxuZy1jb250ZW50PjwvbmctY29udGVudD48L3NwYW4+YCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBUYWdpZnlDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVGFnaWZ5Q29tcG9uZW50XG4gIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uRGVzdHJveVxue1xuICBwcml2YXRlIHZhbHVlRGF0YTogc3RyaW5nIHwgVGFnRGF0YVtdO1xuICBwcml2YXRlIHZhbHVlVHlwZSA9ICd1bmRlZmluZWQnO1xuICBwcml2YXRlIG9uQ2hhbmdlOiBhbnkgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG4gIHByaXZhdGUgb25Ub3VjaGVkOiBhbnkgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHZhbHVlJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nIHwgVGFnRGF0YVtdPihudWxsKTtcbiAgcHJpdmF0ZSB0YWdpZnk6IFRhZ2lmeTtcbiAgcHJpdmF0ZSBza2lwID0gZmFsc2U7XG5cbiAgaW5wdXRDbGFzc1ZhbHVlID0gJyc7XG4gIHByaXZhdGUgcmVhZG9ubHlWYWx1ZSA9IGZhbHNlO1xuICBwcml2YXRlIGRpc2FibGVkVmFsdWUgPSBmYWxzZTtcblxuICBAVmlld0NoaWxkKCdpbnB1dFJlZicsIHsgc3RhdGljOiB0cnVlIH0pXG4gIGlucHV0UmVmOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuXG4gIEBJbnB1dCgpIHNldHRpbmdzOiBUYWdpZnlTZXR0aW5ncyA9IHt9O1xuXG4gIEBJbnB1dCgpIG5hbWUgPSAnJztcblxuICBASW5wdXQoKSB3aGl0ZWxpc3Q6IE9ic2VydmFibGU8c3RyaW5nW10gfCBUYWdEYXRhW10+O1xuXG4gIEBJbnB1dCgpIHNldCBpbnB1dENsYXNzKHY6IHN0cmluZykge1xuICAgIHRoaXMuc2V0VGFnc0NsYXNzKHYpO1xuICAgIHRoaXMuaW5wdXRDbGFzc1ZhbHVlID0gdjtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCByZWFkb25seSh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5yZWFkb25seVZhbHVlID0gISF2O1xuICAgIHRoaXMuc2V0UmVhZG9ubHkoKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBkaXNhYmxlZCh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5kaXNhYmxlZFZhbHVlID0gISF2O1xuICAgIHRoaXMuc2V0RGlzYWJsZWQoKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBzdHJpbmcgfCBUYWdEYXRhW10ge1xuICAgIHJldHVybiB0aGlzLnZhbHVlRGF0YTtcbiAgfVxuXG4gIHNldCB2YWx1ZSh2OiBzdHJpbmcgfCBUYWdEYXRhW10pIHtcbiAgICBpZiAodiAhPT0gdGhpcy52YWx1ZURhdGEpIHtcbiAgICAgIHRoaXMudmFsdWVEYXRhID0gdjtcbiAgICAgIHRoaXMub25DaGFuZ2Uodik7XG4gICAgfVxuICB9XG5cbiAgQE91dHB1dCgpIGFkZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHJlbW92ZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHRJbnB1dCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdGFnaWZ5U2VydmljZTogVGFnaWZ5U2VydmljZSxcbiAgICBwcml2YXRlIGVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0dGluZ3MuY2FsbGJhY2tzID0gdGhpcy5zZXR0aW5ncy5jYWxsYmFja3MgfHwge307XG5cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLnNldHRpbmdzLmNhbGxiYWNrcywgJ2FkZCcpKSB7XG4gICAgICB0aGlzLnNldHRpbmdzLmNhbGxiYWNrcy5hZGQgPSAoKSA9PlxuICAgICAgICB0aGlzLmFkZC5lbWl0KHtcbiAgICAgICAgICB0YWdzOiB0aGlzLnRhZ2lmeS52YWx1ZSxcbiAgICAgICAgICBhZGRlZDogdGhpcy50YWdpZnkudmFsdWVbdGhpcy50YWdpZnkudmFsdWUubGVuZ3RoIC0gMV0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5zZXR0aW5ncy5jYWxsYmFja3MsICdyZW1vdmUnKVxuICAgICkge1xuICAgICAgdGhpcy5zZXR0aW5ncy5jYWxsYmFja3MucmVtb3ZlID0gKCkgPT5cbiAgICAgICAgdGhpcy5yZW1vdmUuZW1pdCh0aGlzLnRhZ2lmeS52YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5uZXJUZXh0ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQudGV4dENvbnRlbnQ7XG5cbiAgICB0aGlzLnRhZ2lmeSA9IG5ldyBUYWdpZnkodGhpcy5pbnB1dFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLnNldHRpbmdzKTtcblxuICAgIC8vIGFkZCB0byBzZXJ2aWNlIGlmIG5hbWUgaXMgcHJvdmlkZWRcbiAgICBpZiAodGhpcy5uYW1lLmxlbmd0aCkge1xuICAgICAgdGhpcy50YWdpZnlTZXJ2aWNlLmFkZCh0aGlzLm5hbWUsIHRoaXMudGFnaWZ5KTtcbiAgICB9XG5cbiAgICB0aGlzLnNldFJlYWRvbmx5KCk7XG4gICAgdGhpcy5zZXREaXNhYmxlZCgpO1xuXG4gICAgLy8gaWYgdGhlcmUgaXMgc29tZSB0ZXh0IGluc2lkZSBjb21wb25lbnQsIGxvYWQgdGhpcyB2YWx1ZSBhbmQgc2tpcCBmaXJzdCBjaGFuZ2UgY2hlY2tcbiAgICBpZiAoaW5uZXJUZXh0Lmxlbmd0aCkge1xuICAgICAgdGhpcy50YWdpZnkubG9hZE9yaWdpbmFsVmFsdWVzKGlubmVyVGV4dCk7XG4gICAgICB0aGlzLnNraXAgPSB0cnVlO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGxpc3RlbiB0byB2YWx1ZSBjaGFuZ2VzIGZyb20gb3V0c2lkZVxuICAgIHRoaXMudmFsdWUkLnBpcGUodGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUkKSkuc3Vic2NyaWJlKCh0YWdzKSA9PiB7XG4gICAgICBpZiAodGFncyA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgICBpZiAodGhpcy5za2lwKSB7XG4gICAgICAgIHRoaXMuc2tpcCA9IGZhbHNlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnZhbHVlVHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy52YWx1ZVR5cGUgPSB0eXBlb2YgdGFncztcbiAgICAgIH1cblxuICAgICAgLy8gaWYgc3RyaW5nIGlzIHBhc3NlZCwgZS5nLiB2aWEgcmVhY3RpdmUgZm9ybXNcbiAgICAgIGlmICh0eXBlb2YgdGFncyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhpcy50YWdpZnkubG9hZE9yaWdpbmFsVmFsdWVzKHRhZ3MpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFZhbHVlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBhbGwgdGFncyAoYWxyZWFkeSBleGlzdGluZyB0YWdzIHdpbGwgYmUgc2tpcHBlZFxuICAgICAgdGhpcy50YWdpZnkuYWRkVGFncyh0YWdzLCBmYWxzZSwgdHJ1ZSk7XG5cbiAgICAgIC8vIHJlbW92ZSBhbGwgdGFncyB0aGF0IGFyZSBub3QgcGFydCBvZiB2YWx1ZSBhbnltb3JlXG4gICAgICB0aGlzLnRhZ2lmeS52YWx1ZS5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgIGlmICghdGFncy5maW5kKCh0KSA9PiB0LnZhbHVlID09PSB2LnZhbHVlKSkge1xuICAgICAgICAgIC8vIHNvbWVob3cgcmVtb3ZlVGFncygpIHdpdGggc3RyaW5nIHBhcmFtZXRlciBkb2Vzbid0IGFsd2F5cyBmaW5kIHRoZSB0YWcgZWxlbWVudFxuICAgICAgICAgIC8vIHRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciBmaW5kaW5nIHRoZSByaWdodCB0YWcgZWxlbWVudFxuICAgICAgICAgIGNvbnN0IHRhZ0VsbSA9IHRoaXMudGFnaWZ5XG4gICAgICAgICAgICAuZ2V0VGFnRWxtcygpXG4gICAgICAgICAgICAuZmluZChcbiAgICAgICAgICAgICAgKGVsKSA9PlxuICAgICAgICAgICAgICAgIGVsLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCd2YWx1ZScpLnRleHRDb250ZW50ID09PSB2LnZhbHVlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLnRhZ2lmeS5yZW1vdmVUYWdzKHRhZ0VsbSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gbGlzdGVuIHRvIHRhZ2lmeSBldmVudHNcbiAgICB0aGlzLnRhZ2lmeS5vbignaW5wdXQnLCAoZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSAndmFsdWUnIGluIGUuZGV0YWlsID8gZS5kZXRhaWwudmFsdWUgOiBlLmRldGFpbC50ZXh0Q29udGVudDtcbiAgICAgIHRoaXMudElucHV0LmVtaXQodmFsdWUpO1xuICAgICAgaWYgKHRoaXMudmFsdWVUeXBlID09PSAnc3RyaW5nJyAmJiB0aGlzLnRhZ2lmeS5zZXR0aW5ncy5tb2RlID09PSAnbWl4Jykge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy50YWdpZnkuZ2V0TWl4ZWRUYWdzQXNTdHJpbmcoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZyb21FdmVudCh0aGlzLnRhZ2lmeSwgJ2NoYW5nZScpXG4gICAgICAucGlwZShcbiAgICAgICAgLy8gdGhyb3R0bGUgdXNlZCB0byByZWR1Y2UgbnVtYmVyIG9mIHZhbHVlIGNoYW5nZXMgd2hlbiBhZGRpbmcvcmVtb3ZpbmcgYSBidW5jaCBvZiB0YWdzXG4gICAgICAgIHRocm90dGxlVGltZSgwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiBmYWxzZSwgdHJhaWxpbmc6IHRydWUgfSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLnVuc3Vic2NyaWJlJCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZSgpO1xuICAgICAgfSk7XG5cbiAgICAvLyBsaXN0ZW4gdG8gc3VnZ2VzdGlvbnMgdXBkYXRlc1xuICAgIGlmICh0aGlzLndoaXRlbGlzdCkge1xuICAgICAgdGhpcy53aGl0ZWxpc3QucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZSQpKS5zdWJzY3JpYmUoKGxpc3QpID0+IHtcbiAgICAgICAgdGhpcy50YWdpZnkuc2V0dGluZ3Mud2hpdGVsaXN0ID0gbGlzdDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodGFnczogc3RyaW5nIHwgVGFnRGF0YVtdKSB7XG4gICAgdGhpcy52YWx1ZSQubmV4dCh0YWdzKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSkge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRWYWx1ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52YWx1ZVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAodGhpcy50YWdpZnkuc2V0dGluZ3MubW9kZSA9PT0gJ21peCcpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMudGFnaWZ5LmdldE1peGVkVGFnc0FzU3RyaW5nKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy50YWdpZnkuRE9NLm9yaWdpbmFsSW5wdXQudmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnRhZ2lmeS52YWx1ZS5zbGljZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUYWdpZnkgY3JlYXRlcyBhIGB0YWdzYCBlbGVtZW50IHRvIHdoaWNoIHRoZSBjbGFzc2VzIG9mIHRoZSBgaW5wdXRgIGVsZW1lbnQgYXJlIGFwcGxpZWQuXG4gICAqIENoYW5nZXMgb2YgYGlucHV0Q2xhc3NgIGFyZSBhcHBsaWVkIGF1dG9tYXRpY2FsbHkgdG8gdGhlIGBpbnB1dGAgZWxlbWVudCwgYnV0IGhhdmUgdG8gYmVcbiAgICogbWFudWFsbHkgYXBwbGllZCB0byB0aGUgYHRhZ3NgIGVsZW1lbnQuXG4gICAqL1xuICBwcml2YXRlIHNldFRhZ3NDbGFzcyh2OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0YWdzRWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3RhZ3MnKTtcbiAgICBpZiAodGFnc0VsZW1lbnQpIHtcbiAgICAgIHRhZ3NFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoLi4udGhpcy5pbnB1dENsYXNzVmFsdWUuc3BsaXQoL1xccysvKSk7XG4gICAgICB0YWdzRWxlbWVudC5jbGFzc0xpc3QuYWRkKC4uLnYuc3BsaXQoL1xccysvKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRSZWFkb25seSgpIHtcbiAgICBpZiAodGhpcy50YWdpZnkpIHtcbiAgICAgIHRoaXMudGFnaWZ5LnNldFJlYWRvbmx5KHRoaXMucmVhZG9ubHlWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXREaXNhYmxlZCgpIHtcbiAgICBpZiAodGhpcy50YWdpZnkpIHtcbiAgICAgIHRoaXMudGFnaWZ5LnNldERpc2FibGVkKHRoaXMuZGlzYWJsZWRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnN1YnNjcmliZSQubmV4dCgpO1xuICAgIHRoaXMudW5zdWJzY3JpYmUkLmNvbXBsZXRlKCk7XG5cbiAgICB0aGlzLnRhZ2lmeS5kZXN0cm95KCk7XG5cbiAgICBpZiAodGhpcy5uYW1lLmxlbmd0aCkge1xuICAgICAgdGhpcy50YWdpZnlTZXJ2aWNlLnJlbW92ZSh0aGlzLm5hbWUpO1xuICAgIH1cbiAgfVxufVxuIl19