ngx-editor
Version:
Rich Text Editor for angular using ProseMirror
120 lines • 18.6 kB
JavaScript
import { Component, Input, } from '@angular/core';
import { MenuService } from './menu.service';
import * as i0 from "@angular/core";
import * as i1 from "./menu.service";
import * as i2 from "./toggle-command/toggle-command.component";
import * as i3 from "./link/link.component";
import * as i4 from "./image/image.component";
import * as i5 from "./dropdown/dropdown.component";
import * as i6 from "./color-picker/color-picker.component";
import * as i7 from "@angular/common";
export const DEFAULT_TOOLBAR = [
['bold', 'italic'],
['code', 'blockquote'],
['underline', 'strike'],
['ordered_list', 'bullet_list'],
[{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }],
['link', 'image'],
['text_color', 'background_color'],
['align_left', 'align_center', 'align_right', 'align_justify'],
];
export const TOOLBAR_MINIMAL = [
['bold', 'italic'],
[{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }],
['link', 'image'],
['text_color', 'background_color'],
];
const DEFAULT_COLOR_PRESETS = [
'#b60205',
'#d93f0b',
'#fbca04',
'#0e8a16',
'#006b75',
'#1d76db',
'#0052cc',
'#5319e7',
'#e99695',
'#f9d0c4',
'#fef2c0',
'#c2e0c6',
'#bfdadc',
'#c5def5',
'#bfd4f2',
'#d4c5f9',
];
export class MenuComponent {
constructor(menuService) {
this.menuService = menuService;
this.toolbar = TOOLBAR_MINIMAL;
this.colorPresets = DEFAULT_COLOR_PRESETS;
this.disabled = false;
this.customMenuRef = null;
this.dropdownPlacement = 'bottom';
this.toggleCommands = [
'bold',
'italic',
'underline',
'strike',
'code',
'blockquote',
'ordered_list',
'bullet_list',
'align_left',
'align_center',
'align_right',
'align_justify',
];
this.iconContainerClass = ['NgxEditor__MenuItem', 'NgxEditor__MenuItem--Icon'];
this.dropdownContainerClass = ['NgxEditor__Dropdown'];
this.seperatorClass = ['NgxEditor__Seperator'];
}
get presets() {
const col = 8;
const colors = [];
this.colorPresets.forEach((color, index) => {
const row = Math.floor(index / col);
if (!colors[row]) {
colors.push([]);
}
colors[row].push(color);
});
return colors;
}
trackByIndex(index) {
return index;
}
isDropDown(item) {
if (item?.heading) {
return true;
}
return false;
}
getDropdownItems(item) {
return item;
}
ngOnInit() {
if (!this.editor) {
throw new Error('NgxEditor: Required editor instance');
}
this.menuService.editor = this.editor;
}
}
MenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: MenuComponent, deps: [{ token: i1.MenuService }], target: i0.ɵɵFactoryTarget.Component });
MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: MenuComponent, selector: "ngx-editor-menu", inputs: { toolbar: "toolbar", colorPresets: "colorPresets", disabled: "disabled", editor: "editor", customMenuRef: "customMenuRef", dropdownPlacement: "dropdownPlacement" }, providers: [MenuService], ngImport: i0, template: "<div class=\"NgxEditor__MenuBar\"\n [ngClass]=\"{'NgxEditor--Disabled': disabled, 'NgxEditor__MenuBar--Reverse': dropdownPlacement === 'top'}\">\n\n <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\n <!-- toggle icons -->\n <ngx-toggle-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"toggleCommands.includes(item)\">\n </ngx-toggle-command>\n\n <!-- link -->\n <ngx-link [class]=\"iconContainerClass\" *ngIf=\"item === 'link'\"></ngx-link>\n\n <!-- image -->\n <ngx-image [class]=\"iconContainerClass\" *ngIf=\"item === 'image'\">\n </ngx-image>\n\n <!-- dropdown -->\n <ng-container *ngIf=\"isDropDown(item)\">\n <ngx-dropdown *ngFor=\"let dropdownItem of getDropdownItems(item) | keyvalue; trackBy: trackByIndex\"\n [class]=\"dropdownContainerClass\" [group]=\"dropdownItem.key\" [items]=\"dropdownItem.value\">\n </ngx-dropdown>\n </ng-container>\n\n <!-- text color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'text_color'\" type=\"text_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n <!-- background color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'background_color'\" type=\"background_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n\n <!-- seperator -->\n <div [class]=\"seperatorClass\" *ngIf=\"lastItem && !lastToolbarItem\"></div>\n </ng-container>\n </ng-container>\n\n <!-- custom menu -->\n <ng-container *ngIf=\"customMenuRef\">\n <ng-container [ngTemplateOutlet]=\"customMenuRef\"></ng-container>\n </ng-container>\n\n</div>\n", styles: [""], components: [{ type: i2.ToggleCommandComponent, selector: "ngx-toggle-command", inputs: ["toolbarItem"] }, { type: i3.LinkComponent, selector: "ngx-link" }, { type: i4.ImageComponent, selector: "ngx-image" }, { type: i5.DropdownComponent, selector: "ngx-dropdown", inputs: ["group", "items"] }, { type: i6.ColorPickerComponent, selector: "ngx-color-picker", inputs: ["presets", "type"] }], directives: [{ type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "keyvalue": i7.KeyValuePipe } });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: MenuComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-editor-menu', providers: [MenuService], template: "<div class=\"NgxEditor__MenuBar\"\n [ngClass]=\"{'NgxEditor--Disabled': disabled, 'NgxEditor__MenuBar--Reverse': dropdownPlacement === 'top'}\">\n\n <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\n <!-- toggle icons -->\n <ngx-toggle-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"toggleCommands.includes(item)\">\n </ngx-toggle-command>\n\n <!-- link -->\n <ngx-link [class]=\"iconContainerClass\" *ngIf=\"item === 'link'\"></ngx-link>\n\n <!-- image -->\n <ngx-image [class]=\"iconContainerClass\" *ngIf=\"item === 'image'\">\n </ngx-image>\n\n <!-- dropdown -->\n <ng-container *ngIf=\"isDropDown(item)\">\n <ngx-dropdown *ngFor=\"let dropdownItem of getDropdownItems(item) | keyvalue; trackBy: trackByIndex\"\n [class]=\"dropdownContainerClass\" [group]=\"dropdownItem.key\" [items]=\"dropdownItem.value\">\n </ngx-dropdown>\n </ng-container>\n\n <!-- text color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'text_color'\" type=\"text_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n <!-- background color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'background_color'\" type=\"background_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n\n <!-- seperator -->\n <div [class]=\"seperatorClass\" *ngIf=\"lastItem && !lastToolbarItem\"></div>\n </ng-container>\n </ng-container>\n\n <!-- custom menu -->\n <ng-container *ngIf=\"customMenuRef\">\n <ng-container [ngTemplateOutlet]=\"customMenuRef\"></ng-container>\n </ng-container>\n\n</div>\n", styles: [""] }]
}], ctorParameters: function () { return [{ type: i1.MenuService }]; }, propDecorators: { toolbar: [{
type: Input
}], colorPresets: [{
type: Input
}], disabled: [{
type: Input
}], editor: [{
type: Input
}], customMenuRef: [{
type: Input
}], dropdownPlacement: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L21lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVkaXRvci9zcmMvbGliL21vZHVsZXMvbWVudS9tZW51LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQUUsS0FBSyxHQUVqQixNQUFNLGVBQWUsQ0FBQztBQUl2QixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7OztBQUc3QyxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQVk7SUFDdEMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO0lBQ2xCLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQztJQUN0QixDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUM7SUFDdkIsQ0FBQyxjQUFjLEVBQUUsYUFBYSxDQUFDO0lBQy9CLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkQsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDO0lBQ2pCLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDO0lBQ2xDLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsZUFBZSxDQUFDO0NBQy9ELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQVk7SUFDdEMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO0lBQ2xCLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7SUFD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cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LCBJbnB1dCxcbiAgT25Jbml0LCBUZW1wbGF0ZVJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFRvb2xiYXIsIFRvb2xiYXJJdGVtLCBUb29sYmFyRHJvcGRvd24gfSBmcm9tICcuLi8uLi90eXBlcyc7XG5cbmltcG9ydCB7IE1lbnVTZXJ2aWNlIH0gZnJvbSAnLi9tZW51LnNlcnZpY2UnO1xuaW1wb3J0IEVkaXRvciBmcm9tICcuLi8uLi9FZGl0b3InO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9UT09MQkFSOiBUb29sYmFyID0gW1xuICBbJ2JvbGQnLCAnaXRhbGljJ10sXG4gIFsnY29kZScsICdibG9ja3F1b3RlJ10sXG4gIFsndW5kZXJsaW5lJywgJ3N0cmlrZSddLFxuICBbJ29yZGVyZWRfbGlzdCcsICdidWxsZXRfbGlzdCddLFxuICBbeyBoZWFkaW5nOiBbJ2gxJywgJ2gyJywgJ2gzJywgJ2g0JywgJ2g1JywgJ2g2J10gfV0sXG4gIFsnbGluaycsICdpbWFnZSddLFxuICBbJ3RleHRfY29sb3InLCAnYmFja2dyb3VuZF9jb2xvciddLFxuICBbJ2FsaWduX2xlZnQnLCAnYWxpZ25fY2VudGVyJywgJ2FsaWduX3JpZ2h0JywgJ2FsaWduX2p1c3RpZnknXSxcbl07XG5cbmV4cG9ydCBjb25zdCBUT09MQkFSX01JTklNQUw6IFRvb2xiYXIgPSBbXG4gIFsnYm9sZCcsICdpdGFsaWMnXSxcbiAgW3sgaGVhZGluZzogWydoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNiddIH1dLFxuICBbJ2xpbmsnLCAnaW1hZ2UnXSxcbiAgWyd0ZXh0X2NvbG9yJywgJ2JhY2tncm91bmRfY29sb3InXSxcbl07XG5cbmNvbnN0IERFRkFVTFRfQ09MT1JfUFJFU0VUUyA9IFtcbiAgJyNiNjAyMDUnLFxuICAnI2Q5M2YwYicsXG4gICcjZmJjYTA0JyxcbiAgJyMwZThhMTYnLFxuICAnIzAwNmI3NScsXG4gICcjMWQ3NmRiJyxcbiAgJyMwMDUyY2MnLFxuICAnIzUzMTllNycsXG4gICcjZTk5Njk1JyxcbiAgJyNmOWQwYzQnLFxuICAnI2ZlZjJjMCcsXG4gICcjYzJlMGM2JyxcbiAgJyNiZmRhZGMnLFxuICAnI2M1ZGVmNScsXG4gICcjYmZkNGYyJyxcbiAgJyNkNGM1ZjknLFxuXTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWVkaXRvci1tZW51JyxcbiAgdGVtcGxhdGVVcmw6ICcuL21lbnUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tZW51LmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW01lbnVTZXJ2aWNlXSxcbn0pXG5cbmV4cG9ydCBjbGFzcyBNZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgdG9vbGJhcjogVG9vbGJhciA9IFRPT0xCQVJfTUlOSU1BTDtcbiAgQElucHV0KCkgY29sb3JQcmVzZXRzOiBzdHJpbmdbXSA9IERFRkFVTFRfQ09MT1JfUFJFU0VUUztcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgZWRpdG9yOiBFZGl0b3I7XG4gIEBJbnB1dCgpIGN1c3RvbU1lbnVSZWY6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgZHJvcGRvd25QbGFjZW1lbnQ6ICd0b3AnIHwgJ2JvdHRvbScgPSAnYm90dG9tJztcblxuICB0b2dnbGVDb21tYW5kczogYW55W10gPSBbXG4gICAgJ2JvbGQnLFxuICAgICdpdGFsaWMnLFxuICAgICd1bmRlcmxpbmUnLFxuICAgICdzdHJpa2UnLFxuICAgICdjb2RlJyxcbiAgICAnYmxvY2txdW90ZScsXG4gICAgJ29yZGVyZWRfbGlzdCcsXG4gICAgJ2J1bGxldF9saXN0JyxcbiAgICAnYWxpZ25fbGVmdCcsXG4gICAgJ2FsaWduX2NlbnRlcicsXG4gICAgJ2FsaWduX3JpZ2h0JyxcbiAgICAnYWxpZ25fanVzdGlmeScsXG4gIF07XG5cbiAgaWNvbkNvbnRhaW5lckNsYXNzID0gWydOZ3hFZGl0b3JfX01lbnVJdGVtJywgJ05neEVkaXRvcl9fTWVudUl0ZW0tLUljb24nXTtcbiAgZHJvcGRvd25Db250YWluZXJDbGFzcyA9IFsnTmd4RWRpdG9yX19Ecm9wZG93biddO1xuICBzZXBlcmF0b3JDbGFzcyA9IFsnTmd4RWRpdG9yX19TZXBlcmF0b3InXTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1lbnVTZXJ2aWNlOiBNZW51U2VydmljZSkgeyB9XG5cbiAgZ2V0IHByZXNldHMoKTogc3RyaW5nW11bXSB7XG4gICAgY29uc3QgY29sID0gODtcbiAgICBjb25zdCBjb2xvcnM6IHN0cmluZ1tdW10gPSBbXTtcblxuICAgIHRoaXMuY29sb3JQcmVzZXRzLmZvckVhY2goKGNvbG9yLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qgcm93ID0gTWF0aC5mbG9vcihpbmRleCAvIGNvbCk7XG5cbiAgICAgIGlmICghY29sb3JzW3Jvd10pIHtcbiAgICAgICAgY29sb3JzLnB1c2goW10pO1xuICAgICAgfVxuXG4gICAgICBjb2xvcnNbcm93XS5wdXNoKGNvbG9yKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjb2xvcnM7XG4gIH1cblxuICB0cmFja0J5SW5kZXgoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgaXNEcm9wRG93bihpdGVtOiBUb29sYmFySXRlbSk6IGJvb2xlYW4ge1xuICAgIGlmICgoaXRlbSBhcyBUb29sYmFyRHJvcGRvd24pPy5oZWFkaW5nKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBnZXREcm9wZG93bkl0ZW1zKGl0ZW06IFRvb2xiYXJJdGVtKTogVG9vbGJhckRyb3Bkb3duIHtcbiAgICByZXR1cm4gaXRlbSBhcyBUb29sYmFyRHJvcGRvd247XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05neEVkaXRvcjogUmVxdWlyZWQgZWRpdG9yIGluc3RhbmNlJyk7XG4gICAgfVxuXG4gICAgdGhpcy5tZW51U2VydmljZS5lZGl0b3IgPSB0aGlzLmVkaXRvcjtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIk5neEVkaXRvcl9fTWVudUJhclwiXG4gIFtuZ0NsYXNzXT1cInsnTmd4RWRpdG9yLS1EaXNhYmxlZCc6IGRpc2FibGVkLCAnTmd4RWRpdG9yX19NZW51QmFyLS1SZXZlcnNlJzogZHJvcGRvd25QbGFjZW1lbnQgPT09ICd0b3AnfVwiPlxuXG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHRvb2xiYXJJdGVtIG9mIHRvb2xiYXI7IGxldCBsYXN0VG9vbGJhckl0ZW0gPSBsYXN0OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHRvb2xiYXJJdGVtOyBsZXQgbGFzdEl0ZW0gPSBsYXN0OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cblxuICAgICAgPCEtLSB0b2dnbGUgaWNvbnMgLS0+XG4gICAgICA8bmd4LXRvZ2dsZS1jb21tYW5kIFt0b29sYmFySXRlbV09XCJpdGVtXCIgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwidG9nZ2xlQ29tbWFuZHMuaW5jbHVkZXMoaXRlbSlcIj5cbiAgICAgIDwvbmd4LXRvZ2dsZS1jb21tYW5kPlxuXG4gICAgICA8IS0tIGxpbmsgLS0+XG4gICAgICA8bmd4LWxpbmsgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwiaXRlbSA9PT0gJ2xpbmsnXCI+PC9uZ3gtbGluaz5cblxuICAgICAgPCEtLSBpbWFnZSAtLT5cbiAgICAgIDxuZ3gtaW1hZ2UgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwiaXRlbSA9PT0gJ2ltYWdlJ1wiPlxuICAgICAgPC9uZ3gtaW1hZ2U+XG5cbiAgICAgIDwhLS0gZHJvcGRvd24gLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNEcm9wRG93bihpdGVtKVwiPlxuICAgICAgICA8bmd4LWRyb3Bkb3duICpuZ0Zvcj1cImxldCBkcm9wZG93bkl0ZW0gb2YgZ2V0RHJvcGRvd25JdGVtcyhpdGVtKSB8IGtleXZhbHVlOyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIlxuICAgICAgICAgIFtjbGFzc109XCJkcm9wZG93bkNvbnRhaW5lckNsYXNzXCIgW2dyb3VwXT1cImRyb3Bkb3duSXRlbS5rZXlcIiBbaXRlbXNdPVwiZHJvcGRvd25JdGVtLnZhbHVlXCI+XG4gICAgICAgIDwvbmd4LWRyb3Bkb3duPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gdGV4dCBjb2xvciBwaWNrZXIgLS0+XG4gICAgICA8bmd4LWNvbG9yLXBpY2tlciBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpdGVtID09PSAndGV4dF9jb2xvcidcIiB0eXBlPVwidGV4dF9jb2xvclwiXG4gICAgICAgIFtwcmVzZXRzXT1cInByZXNldHNcIj5cbiAgICAgIDwvbmd4LWNvbG9yLXBpY2tlcj5cbiAgICAgIDwhLS0gYmFja2dyb3VuZCBjb2xvciBwaWNrZXIgLS0+XG4gICAgICA8bmd4LWNvbG9yLXBpY2tlciBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpdGVtID09PSAnYmFja2dyb3VuZF9jb2xvcidcIiB0eXBlPVwiYmFja2dyb3VuZF9jb2xvclwiXG4gICAgICAgIFtwcmVzZXRzXT1cInByZXNldHNcIj5cbiAgICAgIDwvbmd4LWNvbG9yLXBpY2tlcj5cblxuICAgICAgPCEtLSBzZXBlcmF0b3IgLS0+XG4gICAgICA8ZGl2IFtjbGFzc109XCJzZXBlcmF0b3JDbGFzc1wiICpuZ0lmPVwibGFzdEl0ZW0gJiYgIWxhc3RUb29sYmFySXRlbVwiPjwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8IS0tIGN1c3RvbSBtZW51IC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiY3VzdG9tTWVudVJlZlwiPlxuICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tTWVudVJlZlwiPjwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cblxuPC9kaXY+XG4iXX0=