UNPKG

ngx-editor

Version:

Rich Text Editor for angular using ProseMirror

91 lines 14.1 kB
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==