ngx-editor
Version:
Rich Text Editor for angular using ProseMirror
91 lines • 14.1 kB
JavaScript
import { Component, Input } from '@angular/core';
import Icon from '../../../icons';
import { ToggleCommands } from '../MenuCommands';
import * as i0 from "@angular/core";
import * as i1 from "../../../pipes/sanitize/sanitize-html.pipe";
import * as i2 from "../../../editor.service";
import * as i3 from "@angular/common";
export class BubbleComponent {
constructor(sanitizeHTML, ngxeService) {
this.sanitizeHTML = sanitizeHTML;
this.ngxeService = ngxeService;
this.execulableItems = [];
this.activeItems = [];
this.toolbar = [
['bold', 'italic', 'underline', 'strike'],
['ordered_list', 'bullet_list', 'blockquote', 'code'],
['align_left', 'align_center', 'align_right', 'align_justify'],
];
this.toggleCommands = [
'bold',
'italic',
'underline',
'strike',
'ordered_list',
'bullet_list',
'blockquote',
'code',
'align_left',
'align_center',
'align_right',
'align_justify',
];
}
get view() {
return this.editor.view;
}
getIcon(name) {
const icon = Icon.get(name);
return this.sanitizeHTML.transform(icon);
}
getTitle(name) {
return this.ngxeService.locals.get(name);
}
trackByIndex(index) {
return index;
}
onClick(e, commandName) {
e.preventDefault();
e.stopPropagation();
if (e.button !== 0) {
return;
}
const { state, dispatch } = this.view;
const command = ToggleCommands[commandName];
command.toggle()(state, dispatch);
}
update(view) {
this.activeItems = [];
this.execulableItems = [];
const { state } = view;
this.toggleCommands.forEach((toolbarItem) => {
const command = ToggleCommands[toolbarItem];
const isActive = command.isActive(state);
if (isActive) {
this.activeItems.push(toolbarItem);
}
const canExecute = command.canExecute(state);
if (canExecute) {
this.execulableItems.push(toolbarItem);
}
});
}
ngOnInit() {
this.updateSubscription = this.editor.update
.subscribe((view) => {
this.update(view);
});
}
ngOnDestroy() {
this.updateSubscription.unsubscribe();
}
}
BubbleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: BubbleComponent, deps: [{ token: i1.SanitizeHtmlPipe }, { token: i2.NgxEditorService }], target: i0.ɵɵFactoryTarget.Component });
BubbleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: BubbleComponent, selector: "ngx-bubble", inputs: { editor: "editor" }, ngImport: i0, template: "<ng-container *ngFor=\"let toolbarItem of toolbar; let lastToolbarItem = last; trackBy: trackByIndex\">\n <ng-container *ngFor=\"let item of toolbarItem; let lastItem = last; trackBy: trackByIndex\">\n <div class=\"NgxBubbleMenu__Icon\" [ngClass]=\"{'NgxBubbleMenu__Icon--Active': this.activeItems.includes(item),\n 'NgxEditor--Disabled': !this.execulableItems.includes(item)}\" (mousedown)=\"onClick($event, item)\"\n *ngIf=\"toggleCommands.includes(item)\" [title]=\"getTitle(item)\" [innerHTML]=\"getIcon(item)\">\n </div>\n <div class=\"NgxBubbleMenu__Seperator\" *ngIf=\"lastItem && !lastToolbarItem\"></div>\n </ng-container>\n</ng-container>\n", styles: ["*,*:before,*:after{box-sizing:border-box}:host{display:flex;flex-wrap:wrap;background-color:#000;color:#fff;padding:5px;border-radius:4px}.NgxBubbleMenu__Icon{height:30px;width:30px;transition:.3s ease-in-out;border-radius:2px;display:flex;align-items:center;justify-content:center;color:#fff}.NgxBubbleMenu__Icon:hover{background-color:#636262}.NgxBubbleMenu__Icon+.NgxBubbleMenu__Icon{margin-left:5px}.NgxBubbleMenu__Icon.NgxBubbleMenu__Icon--Active{background-color:#fff;color:#000}.NgxBubbleMenu__Seperator{border-left:1px solid white;margin:0 5px}\n"], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: BubbleComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-bubble', template: "<ng-container *ngFor=\"let toolbarItem of toolbar; let lastToolbarItem = last; trackBy: trackByIndex\">\n <ng-container *ngFor=\"let item of toolbarItem; let lastItem = last; trackBy: trackByIndex\">\n <div class=\"NgxBubbleMenu__Icon\" [ngClass]=\"{'NgxBubbleMenu__Icon--Active': this.activeItems.includes(item),\n 'NgxEditor--Disabled': !this.execulableItems.includes(item)}\" (mousedown)=\"onClick($event, item)\"\n *ngIf=\"toggleCommands.includes(item)\" [title]=\"getTitle(item)\" [innerHTML]=\"getIcon(item)\">\n </div>\n <div class=\"NgxBubbleMenu__Seperator\" *ngIf=\"lastItem && !lastToolbarItem\"></div>\n </ng-container>\n</ng-container>\n", styles: ["*,*:before,*:after{box-sizing:border-box}:host{display:flex;flex-wrap:wrap;background-color:#000;color:#fff;padding:5px;border-radius:4px}.NgxBubbleMenu__Icon{height:30px;width:30px;transition:.3s ease-in-out;border-radius:2px;display:flex;align-items:center;justify-content:center;color:#fff}.NgxBubbleMenu__Icon:hover{background-color:#636262}.NgxBubbleMenu__Icon+.NgxBubbleMenu__Icon{margin-left:5px}.NgxBubbleMenu__Icon.NgxBubbleMenu__Icon--Active{background-color:#fff;color:#000}.NgxBubbleMenu__Seperator{border-left:1px solid white;margin:0 5px}\n"] }]
}], ctorParameters: function () { return [{ type: i1.SanitizeHtmlPipe }, { type: i2.NgxEditorService }]; }, propDecorators: { editor: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnViYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1lZGl0b3Ivc3JjL2xpYi9tb2R1bGVzL21lbnUvYnViYmxlL2J1YmJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L2J1YmJsZS9idWJibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBTXBFLE9BQU8sSUFBSSxNQUFNLGdCQUFnQixDQUFDO0FBR2xDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7QUFRakQsTUFBTSxPQUFPLGVBQWU7SUFDMUIsWUFBb0IsWUFBOEIsRUFBVSxXQUE2QjtRQUFyRSxpQkFBWSxHQUFaLFlBQVksQ0FBa0I7UUFBVSxnQkFBVyxHQUFYLFdBQVcsQ0FBa0I7UUFTekYsb0JBQWUsR0FBYyxFQUFFLENBQUM7UUFDaEMsZ0JBQVcsR0FBYyxFQUFFLENBQUM7UUFFNUIsWUFBTyxHQUFnQjtZQUNyQixDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQztZQUN6QyxDQUFDLGNBQWMsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQztZQUNyRCxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQztTQUMvRCxDQUFDO1FBRUYsbUJBQWMsR0FBYztZQUMxQixNQUFNO1lBQ04sUUFBUTtZQUNSLFdBQVc7WUFDWCxRQUFRO1lBQ1IsY0FBYztZQUNkLGFBQWE7WUFDYixZQUFZO1lBQ1osTUFBTTtZQUNOLFlBQVk7WUFDWixjQUFjO1lBQ2QsYUFBYTtZQUNiLGVBQWU7U0FDaEIsQ0FBQztJQS9CMkYsQ0FBQztJQUU5RixJQUFZLElBQUk7UUFDZCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQzFCLENBQUM7SUE2QkQsT0FBTyxDQUFDLElBQWE7UUFDbkIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxRQUFRLENBQUMsSUFBWTtRQUNuQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQWE7UUFDeEIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxDQUFDLENBQWEsRUFBRSxXQUFvQjtRQUN6QyxDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDbkIsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDbEIsT0FBTztTQUNSO1FBRUQsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBRXRDLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM1QyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTyxNQUFNLENBQUMsSUFBZ0I7UUFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7UUFDMUIsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQztRQUV2QixJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQzFDLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUU1QyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pDLElBQUksUUFBUSxFQUFFO2dCQUNaLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQ3BDO1lBRUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU3QyxJQUFJLFVBQVUsRUFBRTtnQkFDZCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUN4QztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO2FBQ3pDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN4QyxDQUFDOzs0R0EzRlUsZUFBZTtnR0FBZixlQUFlLGdGQ2pCNUIsNnBCQVNBOzJGRFFhLGVBQWU7a0JBTDNCLFNBQVM7K0JBQ0UsWUFBWTtzSUFXYixNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU2FmZUh0bWwgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IEVkaXRvclZpZXcgfSBmcm9tICdwcm9zZW1pcnJvci12aWV3JztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgRWRpdG9yIGZyb20gJy4uLy4uLy4uL0VkaXRvcic7XG5pbXBvcnQgSWNvbiBmcm9tICcuLi8uLi8uLi9pY29ucyc7XG5pbXBvcnQgeyBUQkl0ZW1zIH0gZnJvbSAnLi4vLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgU2FuaXRpemVIdG1sUGlwZSB9IGZyb20gJy4uLy4uLy4uL3BpcGVzL3Nhbml0aXplL3Nhbml0aXplLWh0bWwucGlwZSc7XG5pbXBvcnQgeyBUb2dnbGVDb21tYW5kcyB9IGZyb20gJy4uL01lbnVDb21tYW5kcyc7XG5pbXBvcnQgeyBOZ3hFZGl0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vZWRpdG9yLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtYnViYmxlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2J1YmJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2J1YmJsZS5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBCdWJibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2FuaXRpemVIVE1MOiBTYW5pdGl6ZUh0bWxQaXBlLCBwcml2YXRlIG5neGVTZXJ2aWNlOiBOZ3hFZGl0b3JTZXJ2aWNlKSB7IH1cblxuICBwcml2YXRlIGdldCB2aWV3KCk6IEVkaXRvclZpZXcge1xuICAgIHJldHVybiB0aGlzLmVkaXRvci52aWV3O1xuICB9XG5cbiAgQElucHV0KCkgZWRpdG9yOiBFZGl0b3I7XG5cbiAgcHJpdmF0ZSB1cGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgZXhlY3VsYWJsZUl0ZW1zOiBUQkl0ZW1zW10gPSBbXTtcbiAgYWN0aXZlSXRlbXM6IFRCSXRlbXNbXSA9IFtdO1xuXG4gIHRvb2xiYXI6IFRCSXRlbXNbXVtdID0gW1xuICAgIFsnYm9sZCcsICdpdGFsaWMnLCAndW5kZXJsaW5lJywgJ3N0cmlrZSddLFxuICAgIFsnb3JkZXJlZF9saXN0JywgJ2J1bGxldF9saXN0JywgJ2Jsb2NrcXVvdGUnLCAnY29kZSddLFxuICAgIFsnYWxpZ25fbGVmdCcsICdhbGlnbl9jZW50ZXInLCAnYWxpZ25fcmlnaHQnLCAnYWxpZ25fanVzdGlmeSddLFxuICBdO1xuXG4gIHRvZ2dsZUNvbW1hbmRzOiBUQkl0ZW1zW10gPSBbXG4gICAgJ2JvbGQnLFxuICAgICdpdGFsaWMnLFxuICAgICd1bmRlcmxpbmUnLFxuICAgICdzdHJpa2UnLFxuICAgICdvcmRlcmVkX2xpc3QnLFxuICAgICdidWxsZXRfbGlzdCcsXG4gICAgJ2Jsb2NrcXVvdGUnLFxuICAgICdjb2RlJyxcbiAgICAnYWxpZ25fbGVmdCcsXG4gICAgJ2FsaWduX2NlbnRlcicsXG4gICAgJ2FsaWduX3JpZ2h0JyxcbiAgICAnYWxpZ25fanVzdGlmeScsXG4gIF07XG5cbiAgZ2V0SWNvbihuYW1lOiBUQkl0ZW1zKTogU2FmZUh0bWwge1xuICAgIGNvbnN0IGljb24gPSBJY29uLmdldChuYW1lKTtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZUhUTUwudHJhbnNmb3JtKGljb24pO1xuICB9XG5cbiAgZ2V0VGl0bGUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5uZ3hlU2VydmljZS5sb2NhbHMuZ2V0KG5hbWUpO1xuICB9XG5cbiAgdHJhY2tCeUluZGV4KGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIG9uQ2xpY2soZTogTW91c2VFdmVudCwgY29tbWFuZE5hbWU6IFRCSXRlbXMpOiB2b2lkIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGlmIChlLmJ1dHRvbiAhPT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgc3RhdGUsIGRpc3BhdGNoIH0gPSB0aGlzLnZpZXc7XG5cbiAgICBjb25zdCBjb21tYW5kID0gVG9nZ2xlQ29tbWFuZHNbY29tbWFuZE5hbWVdO1xuICAgIGNvbW1hbmQudG9nZ2xlKCkoc3RhdGUsIGRpc3BhdGNoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlKHZpZXc6IEVkaXRvclZpZXcpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUl0ZW1zID0gW107XG4gICAgdGhpcy5leGVjdWxhYmxlSXRlbXMgPSBbXTtcbiAgICBjb25zdCB7IHN0YXRlIH0gPSB2aWV3O1xuXG4gICAgdGhpcy50b2dnbGVDb21tYW5kcy5mb3JFYWNoKCh0b29sYmFySXRlbSkgPT4ge1xuICAgICAgY29uc3QgY29tbWFuZCA9IFRvZ2dsZUNvbW1hbmRzW3Rvb2xiYXJJdGVtXTtcblxuICAgICAgY29uc3QgaXNBY3RpdmUgPSBjb21tYW5kLmlzQWN0aXZlKHN0YXRlKTtcbiAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICB0aGlzLmFjdGl2ZUl0ZW1zLnB1c2godG9vbGJhckl0ZW0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW5FeGVjdXRlID0gY29tbWFuZC5jYW5FeGVjdXRlKHN0YXRlKTtcblxuICAgICAgaWYgKGNhbkV4ZWN1dGUpIHtcbiAgICAgICAgdGhpcy5leGVjdWxhYmxlSXRlbXMucHVzaCh0b29sYmFySXRlbSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZVN1YnNjcmlwdGlvbiA9IHRoaXMuZWRpdG9yLnVwZGF0ZVxuICAgICAgLnN1YnNjcmliZSgodmlldykgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZSh2aWV3KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdG9vbGJhckl0ZW0gb2YgdG9vbGJhcjsgbGV0IGxhc3RUb29sYmFySXRlbSA9IGxhc3Q7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHRvb2xiYXJJdGVtOyBsZXQgbGFzdEl0ZW0gPSBsYXN0OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cbiAgICA8ZGl2IGNsYXNzPVwiTmd4QnViYmxlTWVudV9fSWNvblwiIFtuZ0NsYXNzXT1cInsnTmd4QnViYmxlTWVudV9fSWNvbi0tQWN0aXZlJzogdGhpcy5hY3RpdmVJdGVtcy5pbmNsdWRlcyhpdGVtKSxcbiAgJ05neEVkaXRvci0tRGlzYWJsZWQnOiAhdGhpcy5leGVjdWxhYmxlSXRlbXMuaW5jbHVkZXMoaXRlbSl9XCIgKG1vdXNlZG93bik9XCJvbkNsaWNrKCRldmVudCwgaXRlbSlcIlxuICAgICAgKm5nSWY9XCJ0b2dnbGVDb21tYW5kcy5pbmNsdWRlcyhpdGVtKVwiIFt0aXRsZV09XCJnZXRUaXRsZShpdGVtKVwiIFtpbm5lckhUTUxdPVwiZ2V0SWNvbihpdGVtKVwiPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJOZ3hCdWJibGVNZW51X19TZXBlcmF0b3JcIiAqbmdJZj1cImxhc3RJdGVtICYmICFsYXN0VG9vbGJhckl0ZW1cIj48L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==