UNPKG

ngx-tiptap-editor

Version:

[![Build and Publish](https://github.com/HuiiBuh/ngx-tiptap-editor/actions/workflows/publish.yml/badge.svg)](https://github.com/HuiiBuh/ngx-tiptap-editor/actions/workflows/publish.yml) [![Deploy to Github Pages](https://github.com/HuiiBuh/ngx-tiptap-edito

202 lines 37.8 kB
import { DOCUMENT } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Inject, Input, Output, SecurityContext, ViewChild } from '@angular/core'; import { fromEvent, merge, Subject } from 'rxjs'; import { filter, startWith, switchMap, takeUntil } from 'rxjs/operators'; import { FadeInAnimation } from '../../animations'; import { ExpandHeight } from './select.animations'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; import * as i2 from "@angular/common"; export class OptionComponent { constructor(element) { this.element = element; this.onSelect = new EventEmitter(); this.enforceHeight = false; this.useHtml = false; this._disabled = false; } set disabled(value) { if (this.option && value) { this.option.nativeElement.setAttribute('disabled', 'true'); } else { this.option && this.option.nativeElement.removeAttribute('disabled'); } this._disabled = false; } setSelected(value) { this.addOrRemoveClass(value, 'active'); } emit($event) { $event.preventDefault(); this.onSelect.emit(this); } getContent() { return this.useHtml ? this.element.nativeElement.innerHTML : this.element.nativeElement.textContent; } addOrRemoveClass(add, className) { const operation = add ? 'add' : 'remove'; this.option && this.option.nativeElement.classList[operation](className); } } OptionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: OptionComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); OptionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: OptionComponent, selector: "tip-option[value]", inputs: { value: "value", enforceHeight: "enforceHeight", useHtml: "useHtml", disabled: "disabled" }, viewQueries: [{ propertyName: "option", first: true, predicate: ["option"], descendants: true }], ngImport: i0, template: ` <button type="button" (click)="emit($event)" (keydown.enter)="emit($event)" class="select-option select-overflow-wrapper" #option> <ng-content></ng-content> </button>`, isInline: true, styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: OptionComponent, decorators: [{ type: Component, args: [{ selector: 'tip-option[value]', template: ` <button type="button" (click)="emit($event)" (keydown.enter)="emit($event)" class="select-option select-overflow-wrapper" #option> <ng-content></ng-content> </button>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { value: [{ type: Input }], enforceHeight: [{ type: Input }], useHtml: [{ type: Input }], option: [{ type: ViewChild, args: ['option'] }], disabled: [{ type: Input }] } }); // @dynamic export class SelectComponent { constructor(cd, element, ngZone, renderer2, sanitizer, document) { this.cd = cd; this.element = element; this.ngZone = ngZone; this.renderer2 = renderer2; this.sanitizer = sanitizer; this.document = document; this.width = '150px'; this.placeholder = ''; this.defaultValue = ''; this.showIcon = true; this.disablePreviewSanitation = false; // tslint:disable-next-line:no-output-native this.change = new EventEmitter(); // Is the dropdown visible this.visible = false; this.destroy$ = new Subject(); } get value() { return this._value; } set value(value) { // Nothing changed if (value === this._value) return; this._value = value; this.updateComponent(false); } ngOnInit() { this.ngZone.runOutsideAngular(() => { fromEvent(this.document, 'keyup').pipe(filter(e => e.key === 'Escape'), filter(() => this.visible), takeUntil(this.destroy$)).subscribe(() => { this.ngZone.run(() => { this.visible = false; this.cd.markForCheck(); }); }); fromEvent(this.document, 'click').pipe(filter(e => !this.element.nativeElement.contains(e.target) && this.visible), filter(e => ( // Dont trigger close if the event comes from the own toggle button, or its children e.target === this.toggleElement?.nativeElement || !!this.selectPreview && !this.selectPreview.nativeElement.contains(e.target))), takeUntil(this.destroy$)).subscribe(() => { this.ngZone.run(() => { this.visible = false; this.cd.markForCheck(); }); }); }); } ngAfterViewInit() { // Subscribe to click events on the options const options = this.optionList; this.optionList.changes.pipe(startWith(...options), switchMap(() => merge(...options.map(o => o.onSelect))), takeUntil(this.destroy$)).subscribe(component => { // Nothing changed if (this._value === component.value) return; this._value = component.value; this.visible = false; this.updateComponent(true); }); // Update the selected value for the initial select this.updateComponent(false); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } toggle() { this.visible = !this.visible; } /** * Select the current component depending on the selected value * @param emitUpdate Should the change be propagated */ updateComponent(emitUpdate) { // No options => no update if (!this.optionList) return; // If no value is provided use the default value if (!this.value && this.defaultValue) { this._value = this.defaultValue; } // Deselect all this.optionList.forEach(o => o.setSelected(false)); // Select right one const selectedComponent = this.optionList.find(o => o.value === this._value); let previewText = this.placeholder; // A component is selected, so select the component if (selectedComponent) { selectedComponent.setSelected(true); previewText = selectedComponent.getContent(); emitUpdate && this.change.emit(selectedComponent.value); } let sanitizedHtml = previewText; if (!this.disablePreviewSanitation) { sanitizedHtml = this.sanitizer.sanitize(SecurityContext.HTML, previewText); } // Dont update if ou don't have to updaet if (this.selectPreview?.nativeElement.innerHTML === sanitizedHtml) return; this.selectPreview && this.renderer2.setProperty(this.selectPreview?.nativeElement, 'innerHTML', sanitizedHtml); } } SelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SelectComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i1.DomSanitizer }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); SelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: SelectComponent, selector: "tip-select", inputs: { width: "width", placeholder: "placeholder", defaultValue: "defaultValue", showIcon: "showIcon", disablePreviewSanitation: "disablePreviewSanitation", value: "value" }, outputs: { change: "change" }, queries: [{ propertyName: "optionList", predicate: OptionComponent, descendants: true }], viewQueries: [{ propertyName: "selectPreview", first: true, predicate: ["selectPreview"], descendants: true }, { propertyName: "toggleElement", first: true, predicate: ["toggleElement"], descendants: true }], ngImport: i0, template: "<div [ngStyle]=\"{width: width}\" class=\"select-wrapper\">\n <div (click)=\"toggle()\" (keydown.enter)=\"toggle()\" [class.icon-placeholder]=\"showIcon\"\n class=\"select-preview\"\n tabindex=\"0\" #toggleElement>\n <div #selectPreview\n class=\"select-overflow-wrapper select-preview-content\">\n </div>\n <i *ngIf=\"showIcon\" [class.rotate180]=\"visible\" class=\"select-icon\">\n <svg focusable=\"false\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\">\n <path d=\"M7 10l5 5 5-5z\"/>\n </svg>\n </i>\n </div>\n <div *ngIf=\"visible\" class=\"select-options-overlay\" @expandHeight>\n <ng-content></ng-content>\n </div>\n</div>\n\n", styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [FadeInAnimation, ExpandHeight], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SelectComponent, decorators: [{ type: Component, args: [{ selector: 'tip-select', animations: [FadeInAnimation, ExpandHeight], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngStyle]=\"{width: width}\" class=\"select-wrapper\">\n <div (click)=\"toggle()\" (keydown.enter)=\"toggle()\" [class.icon-placeholder]=\"showIcon\"\n class=\"select-preview\"\n tabindex=\"0\" #toggleElement>\n <div #selectPreview\n class=\"select-overflow-wrapper select-preview-content\">\n </div>\n <i *ngIf=\"showIcon\" [class.rotate180]=\"visible\" class=\"select-icon\">\n <svg focusable=\"false\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\">\n <path d=\"M7 10l5 5 5-5z\"/>\n </svg>\n </i>\n </div>\n <div *ngIf=\"visible\" class=\"select-options-overlay\" @expandHeight>\n <ng-content></ng-content>\n </div>\n</div>\n\n", styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"] }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.DomSanitizer }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; }, propDecorators: { width: [{ type: Input }], placeholder: [{ type: Input }], defaultValue: [{ type: Input }], showIcon: [{ type: Input }], disablePreviewSanitation: [{ type: Input }], change: [{ type: Output }], optionList: [{ type: ContentChildren, args: [OptionComponent, { descendants: true }] }], selectPreview: [{ type: ViewChild, args: ['selectPreview'] }], toggleElement: [{ type: ViewChild, args: ['toggleElement'] }], value: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10aXB0YXAtZWRpdG9yL3NyYy9saWIvY29tcG9uZW50cy9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10aXB0YXAtZWRpdG9yL3NyYy9saWIvY29tcG9uZW50cy9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxlQUFlLEVBRWYsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBSUwsTUFBTSxFQUdOLGVBQWUsRUFDZixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2pELE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7O0FBWW5ELE1BQU0sT0FBTyxlQUFlO0lBUTFCLFlBQW9CLE9BQW1CO1FBQW5CLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFQaEMsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFtQixDQUFDO1FBRTdDLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDbEIsY0FBUyxHQUFHLEtBQUssQ0FBQztJQUl6QixDQUFDO0lBRUQsSUFBYSxRQUFRLENBQUMsS0FBYztRQUNsQyxJQUFJLElB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QUFlLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBRSxDQUFDO1NBQzdFO1FBRUQseUNBQXlDO1FBQ3pDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsU0FBUyxLQUFLLGFBQWE7WUFBRSxPQUFPO1FBQzFFLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ2xILENBQUM7OzRHQXBJVSxlQUFlLHdKQXVCaEIsUUFBUTtnR0F2QlAsZUFBZSw4UkFXVCxlQUFlLGlRQy9GbEMsMnJCQWtCQSwwbkVEOERjLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQzsyRkFJaEMsZUFBZTtrQkFQM0IsU0FBUzsrQkFDRSxZQUFZLGNBRVYsQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLG1CQUUxQix1QkFBdUIsQ0FBQyxNQUFNOzJMQXlCVCxRQUFROzBCQUEzQyxNQUFNOzJCQUFDLFFBQVE7NENBckJGLEtBQUs7c0JBQXBCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxZQUFZO3NCQUEzQixLQUFLO2dCQUNVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBQ1Usd0JBQXdCO3NCQUF2QyxLQUFLO2dCQUVXLE1BQU07c0JBQXRCLE1BQU07Z0JBR3dELFVBQVU7c0JBQXhFLGVBQWU7dUJBQUMsZUFBZSxFQUFFLEVBQUMsV0FBVyxFQUFFLElBQUksRUFBQztnQkFDakIsYUFBYTtzQkFBaEQsU0FBUzt1QkFBQyxlQUFlO2dCQUNVLGFBQWE7c0JBQWhELFNBQVM7dUJBQUMsZUFBZTtnQkFtQnRCLEtBQUs7c0JBRFIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMixcbiAgU2VjdXJpdHlDb250ZXh0LFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IGZyb21FdmVudCwgbWVyZ2UsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgc3RhcnRXaXRoLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEZhZGVJbkFuaW1hdGlvbiB9IGZyb20gJy4uLy4uL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgRXhwYW5kSGVpZ2h0IH0gZnJvbSAnLi9zZWxlY3QuYW5pbWF0aW9ucyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RpcC1vcHRpb25bdmFsdWVdJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiZW1pdCgkZXZlbnQpXCIgKGtleWRvd24uZW50ZXIpPVwiZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2VsZWN0LW9wdGlvbiBzZWxlY3Qtb3ZlcmZsb3ctd3JhcHBlclwiICNvcHRpb24+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9idXR0b24+YCxcbiAgc3R5bGVVcmxzOiBbJ3NlbGVjdC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBPcHRpb25Db21wb25lbnQge1xuICBwdWJsaWMgb25TZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPE9wdGlvbkNvbXBvbmVudD4oKTtcbiAgQElucHV0KCkgdmFsdWU6IGFueTtcbiAgQElucHV0KCkgZW5mb3JjZUhlaWdodCA9IGZhbHNlO1xuICBASW5wdXQoKSB1c2VIdG1sID0gZmFsc2U7XG4gIHB1YmxpYyBfZGlzYWJsZWQgPSBmYWxzZTtcbiAgQFZpZXdDaGlsZCgnb3B0aW9uJykgcHJpdmF0ZSBvcHRpb246IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+IHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZikge1xuICB9XG5cbiAgQElucHV0KCkgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMub3B0aW9uICYmIHZhbHVlKSB7XG4gICAgICB0aGlzLm9wdGlvbi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAndHJ1ZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wdGlvbiAmJiB0aGlzLm9wdGlvbi5uYXRpdmVFbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICB9XG4gICAgdGhpcy5fZGlzYWJsZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRTZWxlY3RlZCh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzcyh2YWx1ZSwgJ2FjdGl2ZScpO1xuICB9XG5cbiAgcHVibGljIGVtaXQoJGV2ZW50OiBNb3VzZUV2ZW50IHwgRXZlbnQpOiB2b2lkIHtcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLm9uU2VsZWN0LmVtaXQodGhpcyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29udGVudCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnVzZUh0bWwgPyB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5pbm5lckhUTUwgOiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC50ZXh0Q29udGVudDtcbiAgfVxuXG4gIHByaXZhdGUgYWRkT3JSZW1vdmVDbGFzcyhhZGQ6IGJvb2xlYW4sIGNsYXNzTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgb3BlcmF0aW9uID0gYWRkID8gJ2FkZCcgOiAncmVtb3ZlJztcbiAgICB0aGlzLm9wdGlvbiAmJiB0aGlzLm9wdGlvbi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdFtvcGVyYXRpb25dKGNsYXNzTmFtZSk7XG4gIH1cblxufVxuXG4vLyBAZHluYW1pY1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndGlwLXNlbGVjdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9zZWxlY3QuY29tcG9uZW50Lmh0bWwnLFxuICBhbmltYXRpb25zOiBbRmFkZUluQW5pbWF0aW9uLCBFeHBhbmRIZWlnaHRdLFxuICBzdHlsZVVybHM6IFsnLi9zZWxlY3QuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgU2VsZWN0Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkluaXQge1xuXG4gIEBJbnB1dCgpIHB1YmxpYyB3aWR0aCA9ICcxNTBweCc7XG4gIEBJbnB1dCgpIHB1YmxpYyBwbGFjZWhvbGRlciA9ICcnO1xuICBASW5wdXQoKSBwdWJsaWMgZGVmYXVsdFZhbHVlID0gJyc7XG4gIEBJbnB1dCgpIHB1YmxpYyBzaG93SWNvbiA9IHRydWU7XG4gIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlUHJldmlld1Nhbml0YXRpb24gPSBmYWxzZTtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLW91dHB1dC1uYXRpdmVcbiAgQE91dHB1dCgpIHB1YmxpYyBjaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgLy8gSXMgdGhlIGRyb3Bkb3duIHZpc2libGVcbiAgcHVibGljIHZpc2libGUgPSBmYWxzZTtcbiAgQENvbnRlbnRDaGlsZHJlbihPcHRpb25Db21wb25lbnQsIHtkZXNjZW5kYW50czogdHJ1ZX0pIHByaXZhdGUgb3B0aW9uTGlzdCE6IFF1ZXJ5TGlzdDxPcHRpb25Db21wb25lbnQ+O1xuICBAVmlld0NoaWxkKCdzZWxlY3RQcmV2aWV3JykgcHJpdmF0ZSBzZWxlY3RQcmV2aWV3OiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PiB8IHVuZGVmaW5lZDtcbiAgQFZpZXdDaGlsZCgndG9nZ2xlRWxlbWVudCcpIHByaXZhdGUgdG9nZ2xlRWxlbWVudDogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD4gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIF92YWx1ZTogYW55O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVuZGVyZXIyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudFxuICApIHtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCB2YWx1ZSh2YWx1ZTogYW55KSB7XG4gICAgLy8gTm90aGluZyBjaGFuZ2VkXG4gICAgaWYgKHZhbHVlID09PSB0aGlzLl92YWx1ZSkgcmV0dXJuO1xuXG4gICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZUNvbXBvbmVudChmYWxzZSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuZG9jdW1lbnQsICdrZXl1cCcpLnBpcGUoXG4gICAgICAgIGZpbHRlcihlID0+IGUua2V5ID09PSAnRXNjYXBlJyksXG4gICAgICAgIGZpbHRlcigoKSA9PiB0aGlzLnZpc2libGUpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuZG9jdW1lbnQsICdjbGljaycpLnBpcGUoXG4gICAgICAgIGZpbHRlcihlID0+ICF0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5jb250YWlucyhlLnRhcmdldCBhcyBOb2RlKSAmJiB0aGlzLnZpc2libGUpLFxuICAgICAgICBmaWx0ZXIoZSA9PiAoXG4gICAgICAgICAgLy8gRG9udCB0cmlnZ2VyIGNsb3NlIGlmIHRoZSBldmVudCBjb21lcyBmcm9tIHRoZSBvd24gdG9nZ2xlIGJ1dHRvbiwgb3IgaXRzIGNoaWxkcmVuXG4gICAgICAgICAgKGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50KSA9PT0gdGhpcy50b2dnbGVFbGVtZW50Py5uYXRpdmVFbGVtZW50IHx8XG4gICAgICAgICAgISF0aGlzLnNlbGVjdFByZXZpZXcgJiYgIXRoaXMuc2VsZWN0UHJldmlldy5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCkpKVxuICAgICAgICApLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAvLyBTdWJzY3JpYmUgdG8gY2xpY2sgZXZlbnRzIG9uIHRoZSBvcHRpb25zXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9uTGlzdDtcbiAgICB0aGlzLm9wdGlvbkxpc3QuY2hhbmdlcy5waXBlKFxuICAgICAgc3RhcnRXaXRoKC4uLm9wdGlvbnMpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IG1lcmdlKC4uLm9wdGlvbnMubWFwKG8gPT4gby5vblNlbGVjdCkpKSxcbiAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcbiAgICApLnN1YnNjcmliZShjb21wb25lbnQgPT4ge1xuICAgICAgLy8gTm90aGluZyBjaGFuZ2VkXG4gICAgICBpZiAodGhpcy5fdmFsdWUgPT09IGNvbXBvbmVudC52YWx1ZSkgcmV0dXJuO1xuICAgICAgdGhpcy5fdmFsdWUgPSBjb21wb25lbnQudmFsdWU7XG4gICAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50KHRydWUpO1xuICAgIH0pO1xuICAgIC8vIFVwZGF0ZSB0aGUgc2VsZWN0ZWQgdmFsdWUgZm9yIHRoZSBpbml0aWFsIHNlbGVjdFxuICAgIHRoaXMudXBkYXRlQ29tcG9uZW50KGZhbHNlKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlKCk6IHZvaWQge1xuICAgIHRoaXMudmlzaWJsZSA9ICF0aGlzLnZpc2libGU7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IHRoZSBjdXJyZW50IGNvbXBvbmVudCBkZXBlbmRpbmcgb24gdGhlIHNlbGVjdGVkIHZhbHVlXG4gICAqIEBwYXJhbSBlbWl0VXBkYXRlIFNob3VsZCB0aGUgY2hhbmdlIGJlIHByb3BhZ2F0ZWRcbiAgICovXG4gIHByaXZhdGUgdXBkYXRlQ29tcG9uZW50KGVtaXRVcGRhdGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAvLyBObyBvcHRpb25zID0+IG5vIHVwZGF0ZVxuICAgIGlmICghdGhpcy5vcHRpb25MaXN0KSByZXR1cm47XG5cbiAgICAvLyBJZiBubyB2YWx1ZSBpcyBwcm92aWRlZCB1c2UgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICBpZiAoIXRoaXMudmFsdWUgJiYgdGhpcy5kZWZhdWx0VmFsdWUpIHtcbiAgICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5kZWZhdWx0VmFsdWU7XG4gICAgfVxuXG4gICAgLy8gRGVzZWxlY3QgYWxsXG4gICAgdGhpcy5vcHRpb25MaXN0LmZvckVhY2gobyA9PiBvLnNldFNlbGVjdGVkKGZhbHNlKSk7XG5cbiAgICAvLyBTZWxlY3QgcmlnaHQgb25lXG4gICAgY29uc3Qgc2VsZWN0ZWRDb21wb25lbnQgPSB0aGlzLm9wdGlvbkxpc3QuZmluZChvID0+IG8udmFsdWUgPT09IHRoaXMuX3ZhbHVlKTtcblxuICAgIGxldCBwcmV2aWV3VGV4dCA9IHRoaXMucGxhY2Vob2xkZXI7XG4gICAgLy8gQSBjb21wb25lbnQgaXMgc2VsZWN0ZWQsIHNvIHNlbGVjdCB0aGUgY29tcG9uZW50XG4gICAgaWYgKHNlbGVjdGVkQ29tcG9uZW50KSB7XG4gICAgICBzZWxlY3RlZENvbXBvbmVudC5zZXRTZWxlY3RlZCh0cnVlKTtcbiAgICAgIHByZXZpZXdUZXh0ID0gc2VsZWN0ZWRDb21wb25lbnQuZ2V0Q29udGVudCgpO1xuXG4gICAgICBlbWl0VXBkYXRlICYmIHRoaXMuY2hhbmdlLmVtaXQoc2VsZWN0ZWRDb21wb25lbnQudmFsdWUpO1xuICAgIH1cblxuICAgIGxldCBzYW5pdGl6ZWRIdG1sID0gcHJldmlld1RleHQ7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVQcmV2aWV3U2FuaXRhdGlvbikge1xuICAgICAgc2FuaXRpemVkSHRtbCA9IHRoaXMuc2FuaXRpemVyLnNhbml0aXplKFNlY3VyaXR5Q29udGV4dC5IVE1MLCBwcmV2aWV3VGV4dCkhO1xuICAgIH1cblxuICAgIC8vIERvbnQgdXBkYXRlIGlmIG91IGRvbid0IGhhdmUgdG8gdXBkYWV0XG4gICAgaWYgKHRoaXMuc2VsZWN0UHJldmlldz8ubmF0aXZlRWxlbWVudC5pbm5lckhUTUwgPT09IHNhbml0aXplZEh0bWwpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdFByZXZpZXcgJiYgdGhpcy5yZW5kZXJlcjIuc2V0UHJvcGVydHkodGhpcy5zZWxlY3RQcmV2aWV3Py5uYXRpdmVFbGVtZW50LCAnaW5uZXJIVE1MJywgc2FuaXRpemVkSHRtbCk7XG4gIH1cbn1cbiIsIjxkaXYgW25nU3R5bGVdPVwie3dpZHRoOiB3aWR0aH1cIiBjbGFzcz1cInNlbGVjdC13cmFwcGVyXCI+XG4gIDxkaXYgKGNsaWNrKT1cInRvZ2dsZSgpXCIgKGtleWRvd24uZW50ZXIpPVwidG9nZ2xlKClcIiBbY2xhc3MuaWNvbi1wbGFjZWhvbGRlcl09XCJzaG93SWNvblwiXG4gICAgICAgY2xhc3M9XCJzZWxlY3QtcHJldmlld1wiXG4gICAgICAgdGFiaW5kZXg9XCIwXCIgI3RvZ2dsZUVsZW1lbnQ+XG4gICAgPGRpdiAjc2VsZWN0UHJldmlld1xuICAgICAgICAgY2xhc3M9XCJzZWxlY3Qtb3ZlcmZsb3ctd3JhcHBlciBzZWxlY3QtcHJldmlldy1jb250ZW50XCI+XG4gICAgPC9kaXY+XG4gICAgPGkgKm5nSWY9XCJzaG93SWNvblwiIFtjbGFzcy5yb3RhdGUxODBdPVwidmlzaWJsZVwiIGNsYXNzPVwic2VsZWN0LWljb25cIj5cbiAgICAgIDxzdmcgZm9jdXNhYmxlPVwiZmFsc2VcIiBoZWlnaHQ9XCIyNHB4XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIHdpZHRoPVwiMjRweFwiPlxuICAgICAgICA8cGF0aCBkPVwiTTcgMTBsNSA1IDUtNXpcIi8+XG4gICAgICA8L3N2Zz5cbiAgICA8L2k+XG4gIDwvZGl2PlxuICA8ZGl2ICpuZ0lmPVwidmlzaWJsZVwiIGNsYXNzPVwic2VsZWN0LW9wdGlvbnMtb3ZlcmxheVwiIEBleHBhbmRIZWlnaHQ+XG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG4iXX0=