UNPKG

ngx-editor

Version:

Rich Text Editor for angular using ProseMirror

161 lines 20.3 kB
import { Component, HostBinding, HostListener, Input } from '@angular/core'; import { NodeSelection } from 'prosemirror-state'; import { asyncScheduler, fromEvent } from 'rxjs'; import { throttleTime } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../../../pipes/sanitize/sanitize-html.pipe"; import * as i2 from "../bubble/bubble.component"; import * as i3 from "@angular/common"; export class FloatingMenuComponent { constructor(el, sanitizeHTML) { this.el = el; this.sanitizeHTML = sanitizeHTML; this.posLeft = 0; this.posTop = 0; this.showMenu = false; this.dragging = false; this.execulableItems = []; this.activeItems = []; } get display() { return { visibility: this.showMenu ? 'visible' : 'hidden', opacity: this.showMenu ? '1' : '0', top: this.posTop + 'px', left: this.posLeft + 'px', }; } get view() { return this.editor.view; } onMouseDown(e) { const target = e.target; if (this.el.nativeElement.contains(target) && target.nodeName !== 'INPUT') { e.preventDefault(); return; } this.dragging = true; } onKeyDown(e) { const target = e.target; if (target.nodeName === 'INPUT') { return; } this.dragging = true; this.hide(); } onMouseUp(e) { const target = e.target; if (this.el.nativeElement.contains(target) || target.nodeName === 'INPUT') { e.preventDefault(); return; } this.dragging = false; this.useUpdate(); } onKeyUp(e) { const target = e.target; if (target.nodeName === 'INPUT') { return; } this.dragging = false; this.useUpdate(); } useUpdate() { if (!this.view) { return; } this.update(this.view); } hide() { this.showMenu = false; } show() { this.showMenu = true; } calculateBubblePosition(view) { const { state: { selection } } = view; const { from } = selection; // the floating bubble itself const bubbleEl = this.el.nativeElement; const bubble = bubbleEl.getBoundingClientRect(); // The box in which the tooltip is positioned, to use as base const box = bubbleEl.parentElement.getBoundingClientRect(); const start = view.coordsAtPos(from); let left = start.left - box.left; const overflowsRight = (box.right < (start.left + bubble.width) || bubble.right > box.right); if (overflowsRight) { left = box.width - bubble.width; } if (left < 0) { left = 0; } const bubbleHeight = bubble.height + parseInt(getComputedStyle(bubbleEl).marginBottom, 10); const top = (start.top - box.top) - bubbleHeight; return { left, top }; } update(view) { const { state } = view; const { selection } = state; const { empty } = selection; if (selection instanceof NodeSelection) { if (selection.node.type.name === 'image') { this.hide(); return; } } const hasFocus = this.view.hasFocus(); if (!hasFocus || empty || this.dragging) { this.hide(); return; } const { top, left } = this.calculateBubblePosition(this.view); this.posLeft = left; this.posTop = top; this.show(); } ngOnInit() { if (!this.editor) { throw new Error('NgxEditor: Required editor instance'); } this.updateSubscription = this.editor.update .subscribe((view) => { this.update(view); }); this.resizeSubscription = fromEvent(window, 'resize').pipe(throttleTime(500, asyncScheduler, { leading: true, trailing: true })).subscribe(() => { this.useUpdate(); }); } ngOnDestroy() { this.updateSubscription.unsubscribe(); this.resizeSubscription.unsubscribe(); } } FloatingMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.0", ngImport: i0, type: FloatingMenuComponent, deps: [{ token: i0.ElementRef }, { token: i1.SanitizeHtmlPipe }], target: i0.ɵɵFactoryTarget.Component }); FloatingMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.0", type: FloatingMenuComponent, selector: "ngx-editor-floating-menu", inputs: { editor: "editor" }, host: { listeners: { "document:mousedown": "onMouseDown($event)", "document:keydown": "onKeyDown($event)", "document:mouseup": "onMouseUp($event)", "document:keyup": "onKeyUp($event)" }, properties: { "style": "this.display" } }, ngImport: i0, template: "<div #ref>\n <ng-content></ng-content>\n</div>\n<ng-container *ngIf=\"ref.children.length === 0\">\n <ngx-bubble [editor]=\"editor\"></ngx-bubble>\n</ng-container>\n", styles: ["*,*:before,*:after{box-sizing:border-box}:host{position:absolute;z-index:20;margin-bottom:5px;visibility:hidden;opacity:0}\n"], components: [{ type: i2.BubbleComponent, selector: "ngx-bubble", inputs: ["editor"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.0", ngImport: i0, type: FloatingMenuComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-editor-floating-menu', template: "<div #ref>\n <ng-content></ng-content>\n</div>\n<ng-container *ngIf=\"ref.children.length === 0\">\n <ngx-bubble [editor]=\"editor\"></ngx-bubble>\n</ng-container>\n", styles: ["*,*:before,*:after{box-sizing:border-box}:host{position:absolute;z-index:20;margin-bottom:5px;visibility:hidden;opacity:0}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.SanitizeHtmlPipe }]; }, propDecorators: { display: [{ type: HostBinding, args: ['style'] }], editor: [{ type: Input }], onMouseDown: [{ type: HostListener, args: ['document:mousedown', ['$event']] }], onKeyDown: [{ type: HostListener, args: ['document:keydown', ['$event']] }], onMouseUp: [{ type: HostListener, args: ['document:mouseup', ['$event']] }], onKeyUp: [{ type: HostListener, args: ['document:keyup', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvYXRpbmctbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L2Zsb2F0aW5nLW1lbnUvZmxvYXRpbmctbWVudS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L2Zsb2F0aW5nLW1lbnUvZmxvYXRpbmctbWVudS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUFjLFdBQVcsRUFDbEMsWUFBWSxFQUFFLEtBQUssRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWxELE9BQU8sRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7O0FBaUI5QyxNQUFNLE9BQU8scUJBQXFCO0lBRWhDLFlBQW1CLEVBQTJCLEVBQVUsWUFBOEI7UUFBbkUsT0FBRSxHQUFGLEVBQUUsQ0FBeUI7UUFBVSxpQkFBWSxHQUFaLFlBQVksQ0FBa0I7UUFpQjlFLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUVqQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRXpCLG9CQUFlLEdBQWMsRUFBRSxDQUFDO1FBQ2hDLGdCQUFXLEdBQWMsRUFBRSxDQUFDO0lBeEI4RCxDQUFDO0lBRTNGLElBQTBCLE9BQU87UUFDL0IsT0FBTztZQUNMLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVE7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c0dBQXJCLHFCQUFxQixvVUN6QmxDLHlLQU1BOzJGRG1CYSxxQkFBcUI7a0JBTGpDLFNBQVM7K0JBQ0UsMEJBQTBCO2dJQVFWLE9BQU87c0JBQWhDLFdBQVc7dUJBQUMsT0FBTztnQkFhWCxNQUFNO3NCQUFkLEtBQUs7Z0JBVzBDLFdBQVc7c0JBQTFELFlBQVk7dUJBQUMsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBV0EsU0FBUztzQkFBdEQsWUFBWTt1QkFBQyxrQkFBa0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFXRSxTQUFTO3NCQUF0RCxZQUFZO3VCQUFDLGtCQUFrQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVlBLE9BQU87c0JBQWxELFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBOb2RlU2VsZWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ3Byb3NlbWlycm9yLXZpZXcnO1xuaW1wb3J0IHsgYXN5bmNTY2hlZHVsZXIsIGZyb21FdmVudCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0aHJvdHRsZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCBFZGl0b3IgZnJvbSAnLi4vLi4vLi4vRWRpdG9yJztcbmltcG9ydCBJY29uIGZyb20gJy4uLy4uLy4uL2ljb25zJztcbmltcG9ydCB7IFRCSXRlbXMgfSBmcm9tICcuLi8uLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBTYW5pdGl6ZUh0bWxQaXBlIH0gZnJvbSAnLi4vLi4vLi4vcGlwZXMvc2FuaXRpemUvc2FuaXRpemUtaHRtbC5waXBlJztcblxuaW50ZXJmYWNlIEJ1YmJsZVBvc2l0aW9uIHtcbiAgdG9wOiBudW1iZXI7XG4gIGxlZnQ6IG51bWJlcjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWVkaXRvci1mbG9hdGluZy1tZW51JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Zsb2F0aW5nLW1lbnUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9mbG9hdGluZy1tZW51LmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRmxvYXRpbmdNZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sIHByaXZhdGUgc2FuaXRpemVIVE1MOiBTYW5pdGl6ZUh0bWxQaXBlKSB7IH1cblxuICBASG9zdEJpbmRpbmcoJ3N0eWxlJykgZ2V0IGRpc3BsYXkoKTogUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZpc2liaWxpdHk6IHRoaXMuc2hvd01lbnUgPyAndmlzaWJsZScgOiAnaGlkZGVuJyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc2hvd01lbnUgPyAnMScgOiAnMCcsXG4gICAgICB0b3A6IHRoaXMucG9zVG9wICsgJ3B4JyxcbiAgICAgIGxlZnQ6IHRoaXMucG9zTGVmdCArICdweCcsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHZpZXcoKTogRWRpdG9yVmlldyB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yLnZpZXc7XG4gIH1cblxuICBASW5wdXQoKSBlZGl0b3I6IEVkaXRvcjtcblxuICBwcml2YXRlIHBvc0xlZnQgPSAwO1xuICBwcml2YXRlIHBvc1RvcCA9IDA7XG4gIHByaXZhdGUgc2hvd01lbnUgPSBmYWxzZTtcbiAgcHJpdmF0ZSB1cGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBkcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIHJlc2l6ZVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBleGVjdWxhYmxlSXRlbXM6IFRCSXRlbXNbXSA9IFtdO1xuICBhY3RpdmVJdGVtczogVEJJdGVtc1tdID0gW107XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vkb3duJywgWyckZXZlbnQnXSkgb25Nb3VzZURvd24oZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIE5vZGVcblxuICAgIGlmICh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSAmJiB0YXJnZXQubm9kZU5hbWUgIT09ICdJTlBVVCcpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24nLCBbJyRldmVudCddKSBvbktleURvd24oZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIE5vZGVcblxuICAgIGlmICh0YXJnZXQubm9kZU5hbWUgPT09ICdJTlBVVCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmhpZGUoKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnLCBbJyRldmVudCddKSBvbk1vdXNlVXAoZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIE5vZGVcblxuICAgIGlmICh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSB8fCB0YXJnZXQubm9kZU5hbWUgPT09ICdJTlBVVCcpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnVzZVVwZGF0ZSgpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5dXAnLCBbJyRldmVudCddKSBvbktleVVwKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBOb2RlXG5cbiAgICBpZiAodGFyZ2V0Lm5vZGVOYW1lID09PSAnSU5QVVQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMudXNlVXBkYXRlKCk7XG4gIH1cblxuICBwcml2YXRlIHVzZVVwZGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudmlldykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlKHRoaXMudmlldyk7XG4gIH1cblxuICBwcml2YXRlIGhpZGUoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93TWVudSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG93KCk6IHZvaWQge1xuICAgIHRoaXMuc2hvd01lbnUgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVCdWJibGVQb3NpdGlvbih2aWV3OiBFZGl0b3JWaWV3KTogQnViYmxlUG9zaXRpb24ge1xuICAgIGNvbnN0IHsgc3RhdGU6IHsgc2VsZWN0aW9uIH0gfSA9IHZpZXc7XG4gICAgY29uc3QgeyBmcm9tIH0gPSBzZWxlY3Rpb247XG5cbiAgICAvLyB0aGUgZmxvYXRpbmcgYnViYmxlIGl0c2VsZlxuICAgIGNvbnN0IGJ1YmJsZUVsID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGJ1YmJsZSA9IGJ1YmJsZUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgLy8gVGhlIGJveCBpbiB3aGljaCB0aGUgdG9vbHRpcCBpcyBwb3NpdGlvbmVkLCB0byB1c2UgYXMgYmFzZVxuICAgIGNvbnN0IGJveCA9IGJ1YmJsZUVsLnBhcmVudEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCBzdGFydCA9IHZpZXcuY29vcmRzQXRQb3MoZnJvbSk7XG5cbiAgICBsZXQgbGVmdCA9IHN0YXJ0LmxlZnQgLSBib3gubGVmdDtcblxuICAgIGNvbnN0IG92ZXJmbG93c1JpZ2h0ID0gKFxuICAgICAgYm94LnJpZ2h0IDwgKHN0YXJ0LmxlZnQgKyBidWJibGUud2lkdGgpIHx8XG4gICAgICBidWJibGUucmlnaHQgPiBib3gucmlnaHRcbiAgICApO1xuXG4gICAgaWYgKG92ZXJmbG93c1JpZ2h0KSB7XG4gICAgICBsZWZ0ID0gYm94LndpZHRoIC0gYnViYmxlLndpZHRoO1xuICAgIH1cblxuICAgIGlmIChsZWZ0IDwgMCkge1xuICAgICAgbGVmdCA9IDA7XG4gICAgfVxuXG4gICAgY29uc3QgYnViYmxlSGVpZ2h0ID0gYnViYmxlLmhlaWdodCArIHBhcnNlSW50KGdldENvbXB1dGVkU3R5bGUoYnViYmxlRWwpLm1hcmdpbkJvdHRvbSwgMTApO1xuICAgIGNvbnN0IHRvcCA9IChzdGFydC50b3AgLSBib3gudG9wKSAtIGJ1YmJsZUhlaWdodDtcblxuICAgIHJldHVybiB7XG4gICAgICBsZWZ0LFxuICAgICAgdG9wXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlKHZpZXc6IEVkaXRvclZpZXcpOiB2b2lkIHtcbiAgICBjb25zdCB7IHN0YXRlIH0gPSB2aWV3O1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBzdGF0ZTtcbiAgICBjb25zdCB7IGVtcHR5IH0gPSBzZWxlY3Rpb247XG5cbiAgICBpZiAoc2VsZWN0aW9uIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbikge1xuICAgICAgaWYgKHNlbGVjdGlvbi5ub2RlLnR5cGUubmFtZSA9PT0gJ2ltYWdlJykge1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGhhc0ZvY3VzID0gdGhpcy52aWV3Lmhhc0ZvY3VzKCk7XG5cbiAgICBpZiAoIWhhc0ZvY3VzIHx8IGVtcHR5IHx8IHRoaXMuZHJhZ2dpbmcpIHtcbiAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdG9wLCBsZWZ0IH0gPSB0aGlzLmNhbGN1bGF0ZUJ1YmJsZVBvc2l0aW9uKHRoaXMudmlldyk7XG5cbiAgICB0aGlzLnBvc0xlZnQgPSBsZWZ0O1xuICAgIHRoaXMucG9zVG9wID0gdG9wO1xuXG4gICAgdGhpcy5zaG93KCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05neEVkaXRvcjogUmVxdWlyZWQgZWRpdG9yIGluc3RhbmNlJyk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVTdWJzY3JpcHRpb24gPSB0aGlzLmVkaXRvci51cGRhdGVcbiAgICAgIC5zdWJzY3JpYmUoKHZpZXcpID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGUodmlldyk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVzaXplU3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50KHdpbmRvdywgJ3Jlc2l6ZScpLnBpcGUoXG4gICAgICB0aHJvdHRsZVRpbWUoNTAwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogdHJ1ZSB9KVxuICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMudXNlVXBkYXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMucmVzaXplU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiIsIjxkaXYgI3JlZj5cbiAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9kaXY+XG48bmctY29udGFpbmVyICpuZ0lmPVwicmVmLmNoaWxkcmVuLmxlbmd0aCA9PT0gMFwiPlxuICA8bmd4LWJ1YmJsZSBbZWRpdG9yXT1cImVkaXRvclwiPjwvbmd4LWJ1YmJsZT5cbjwvbmctY29udGFpbmVyPlxuIl19