UNPKG

ngx-editor

Version:

Rich Text Editor for angular using ProseMirror

136 lines 21.2 kB
import { Component, Input, } from '@angular/core'; import { NgxEditorError } from 'ngx-editor/utils'; 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 "./insert-command/insert-command.component"; import * as i4 from "./link/link.component"; import * as i5 from "./image/image.component"; import * as i6 from "./dropdown/dropdown.component"; import * as i7 from "./color-picker/color-picker.component"; import * as i8 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'], ]; export const TOOLBAR_FULL = [ ['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'], ['horizontal_rule'], ]; 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.insertCommands = [ 'horizontal_rule', ]; 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 NgxEditorError('Required editor instance to initialize menu component'); } this.menuService.editor = this.editor; } } MenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MenuComponent, deps: [{ token: i1.MenuService }], target: i0.ɵɵFactoryTarget.Component }); MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", 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 <ngx-insert-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"insertCommands.includes(item)\">\n </ngx-insert-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.InsertCommandComponent, selector: "ngx-insert-command", inputs: ["toolbarItem"] }, { type: i4.LinkComponent, selector: "ngx-link" }, { type: i5.ImageComponent, selector: "ngx-image" }, { type: i6.DropdownComponent, selector: "ngx-dropdown", inputs: ["group", "items"] }, { type: i7.ColorPickerComponent, selector: "ngx-color-picker", inputs: ["presets", "type"] }], directives: [{ type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "keyvalue": i8.KeyValuePipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", 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 <ngx-insert-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"insertCommands.includes(item)\">\n </ngx-insert-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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L21lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVkaXRvci9zcmMvbGliL21vZHVsZXMvbWVudS9tZW51LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQUUsS0FBSyxHQUVqQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7Ozs7O0FBRzdDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBWTtJQUN0QyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7SUFDbEIsQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDO0lBQ3RCLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQztJQUN2QixDQUFDLGNBQWMsRUFBRSxhQUFhLENBQUM7SUFDL0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNuRCxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7SUFDakIsQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUM7SUFDbEMsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxlQUFlLENBQUM7Q0FDL0QsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBWTtJQUN0QyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7SUFDbEIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFF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QUM7SUFDZixDQUFDO0lBRUQsZ0JBQWdCLENBQUMsSUFBaUI7UUFDaEMsT0FBTyxJQUF1QixDQUFDO0lBQ2pDLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsTUFBTSxJQUFJLGNBQWMsQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1NBQ25GO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN4QyxDQUFDOzswR0F4RVUsYUFBYTs4RkFBYixhQUFhLHdOQUhiLENBQUMsV0FBVyxDQUFDLDBCQy9EMUIsdzlEQStDQTsyRkRtQmEsYUFBYTtrQkFQekIsU0FBUzsrQkFDRSxpQkFBaUIsYUFHaEIsQ0FBQyxXQUFXLENBQUM7a0dBSWYsT0FBTztzQkFBZixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsIElucHV0LFxuICBPbkluaXQsIFRlbXBsYXRlUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTmd4RWRpdG9yRXJyb3IgfSBmcm9tICduZ3gtZWRpdG9yL3V0aWxzJztcbmltcG9ydCB7IFRvb2xiYXIsIFRvb2xiYXJJdGVtLCBUb29sYmFyRHJvcGRvd24gfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBNZW51U2VydmljZSB9IGZyb20gJy4vbWVudS5zZXJ2aWNlJztcbmltcG9ydCBFZGl0b3IgZnJvbSAnLi4vLi4vRWRpdG9yJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfVE9PTEJBUjogVG9vbGJhciA9IFtcbiAgWydib2xkJywgJ2l0YWxpYyddLFxuICBbJ2NvZGUnLCAnYmxvY2txdW90ZSddLFxuICBbJ3VuZGVybGluZScsICdzdHJpa2UnXSxcbiAgWydvcmRlcmVkX2xpc3QnLCAnYnVsbGV0X2xpc3QnXSxcbiAgW3sgaGVhZGluZzogWydoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNiddIH1dLFxuICBbJ2xpbmsnLCAnaW1hZ2UnXSxcbiAgWyd0ZXh0X2NvbG9yJywgJ2JhY2tncm91bmRfY29sb3InXSxcbiAgWydhbGlnbl9sZWZ0JywgJ2FsaWduX2NlbnRlcicsICdhbGlnbl9yaWdodCcsICdhbGlnbl9qdXN0aWZ5J10sXG5dO1xuXG5leHBvcnQgY29uc3QgVE9PTEJBUl9NSU5JTUFMOiBUb29sYmFyID0gW1xuICBbJ2JvbGQnLCAnaXRhbGljJ10sXG4gIFt7IGhlYWRpbmc6IFsnaDEnLCAnaDInLCAnaDMnLCAnaDQnLCAnaDUnLCAnaDYnXSB9XSxcbiAgWydsaW5rJywgJ2ltYWdlJ10sXG4gIFsndGV4dF9jb2xvcicsICdiYWNrZ3JvdW5kX2NvbG9yJ10sXG5dO1xuXG5leHBvcnQgY29uc3QgVE9PTEJBUl9GVUxMOiBUb29sYmFyID0gW1xuICBbJ2JvbGQnLCAnaXRhbGljJ10sXG4gIFsnY29kZScsICdibG9ja3F1b3RlJ10sXG4gIFsndW5kZXJsaW5lJywgJ3N0cmlrZSddLFxuICBbJ29yZGVyZWRfbGlzdCcsICdidWxsZXRfbGlzdCddLFxuICBbeyBoZWFkaW5nOiBbJ2gxJywgJ2gyJywgJ2gzJywgJ2g0JywgJ2g1JywgJ2g2J10gfV0sXG4gIFsnbGluaycsICdpbWFnZSddLFxuICBbJ3RleHRfY29sb3InLCAnYmFja2dyb3VuZF9jb2xvciddLFxuICBbJ2FsaWduX2xlZnQnLCAnYWxpZ25fY2VudGVyJywgJ2FsaWduX3JpZ2h0JywgJ2FsaWduX2p1c3RpZnknXSxcbiAgWydob3Jpem9udGFsX3J1bGUnXSxcbl07XG5cbmNvbnN0IERFRkFVTFRfQ09MT1JfUFJFU0VUUyA9IFtcbiAgJyNiNjAyMDUnLFxuICAnI2Q5M2YwYicsXG4gICcjZmJjYTA0JyxcbiAgJyMwZThhMTYnLFxuICAnIzAwNmI3NScsXG4gICcjMWQ3NmRiJyxcbiAgJyMwMDUyY2MnLFxuICAnIzUzMTllNycsXG4gICcjZTk5Njk1JyxcbiAgJyNmOWQwYzQnLFxuICAnI2ZlZjJjMCcsXG4gICcjYzJlMGM2JyxcbiAgJyNiZmRhZGMnLFxuICAnI2M1ZGVmNScsXG4gICcjYmZkNGYyJyxcbiAgJyNkNGM1ZjknLFxuXTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWVkaXRvci1tZW51JyxcbiAgdGVtcGxhdGVVcmw6ICcuL21lbnUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tZW51LmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW01lbnVTZXJ2aWNlXSxcbn0pXG5cbmV4cG9ydCBjbGFzcyBNZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgdG9vbGJhcjogVG9vbGJhciA9IFRPT0xCQVJfTUlOSU1BTDtcbiAgQElucHV0KCkgY29sb3JQcmVzZXRzOiBzdHJpbmdbXSA9IERFRkFVTFRfQ09MT1JfUFJFU0VUUztcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgZWRpdG9yOiBFZGl0b3I7XG4gIEBJbnB1dCgpIGN1c3RvbU1lbnVSZWY6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgZHJvcGRvd25QbGFjZW1lbnQ6ICd0b3AnIHwgJ2JvdHRvbScgPSAnYm90dG9tJztcblxuICB0b2dnbGVDb21tYW5kczogVG9vbGJhckl0ZW1bXSA9IFtcbiAgICAnYm9sZCcsXG4gICAgJ2l0YWxpYycsXG4gICAgJ3VuZGVybGluZScsXG4gICAgJ3N0cmlrZScsXG4gICAgJ2NvZGUnLFxuICAgICdibG9ja3F1b3RlJyxcbiAgICAnb3JkZXJlZF9saXN0JyxcbiAgICAnYnVsbGV0X2xpc3QnLFxuICAgICdhbGlnbl9sZWZ0JyxcbiAgICAnYWxpZ25fY2VudGVyJyxcbiAgICAnYWxpZ25fcmlnaHQnLFxuICAgICdhbGlnbl9qdXN0aWZ5JyxcbiAgXTtcblxuICBpbnNlcnRDb21tYW5kczogVG9vbGJhckl0ZW1bXSA9IFtcbiAgICAnaG9yaXpvbnRhbF9ydWxlJyxcbiAgXTtcblxuICBpY29uQ29udGFpbmVyQ2xhc3MgPSBbJ05neEVkaXRvcl9fTWVudUl0ZW0nLCAnTmd4RWRpdG9yX19NZW51SXRlbS0tSWNvbiddO1xuICBkcm9wZG93bkNvbnRhaW5lckNsYXNzID0gWydOZ3hFZGl0b3JfX0Ryb3Bkb3duJ107XG4gIHNlcGVyYXRvckNsYXNzID0gWydOZ3hFZGl0b3JfX1NlcGVyYXRvciddO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbWVudVNlcnZpY2U6IE1lbnVTZXJ2aWNlKSB7IH1cblxuICBnZXQgcHJlc2V0cygpOiBzdHJpbmdbXVtdIHtcbiAgICBjb25zdCBjb2wgPSA4O1xuICAgIGNvbnN0IGNvbG9yczogc3RyaW5nW11bXSA9IFtdO1xuXG4gICAgdGhpcy5jb2xvclByZXNldHMuZm9yRWFjaCgoY29sb3IsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCByb3cgPSBNYXRoLmZsb29yKGluZGV4IC8gY29sKTtcblxuICAgICAgaWYgKCFjb2xvcnNbcm93XSkge1xuICAgICAgICBjb2xvcnMucHVzaChbXSk7XG4gICAgICB9XG5cbiAgICAgIGNvbG9yc1tyb3ddLnB1c2goY29sb3IpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNvbG9ycztcbiAgfVxuXG4gIHRyYWNrQnlJbmRleChpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBpc0Ryb3BEb3duKGl0ZW06IFRvb2xiYXJJdGVtKTogYm9vbGVhbiB7XG4gICAgaWYgKChpdGVtIGFzIFRvb2xiYXJEcm9wZG93bik/LmhlYWRpbmcpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGdldERyb3Bkb3duSXRlbXMoaXRlbTogVG9vbGJhckl0ZW0pOiBUb29sYmFyRHJvcGRvd24ge1xuICAgIHJldHVybiBpdGVtIGFzIFRvb2xiYXJEcm9wZG93bjtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0b3IpIHtcbiAgICAgIHRocm93IG5ldyBOZ3hFZGl0b3JFcnJvcignUmVxdWlyZWQgZWRpdG9yIGluc3RhbmNlIHRvIGluaXRpYWxpemUgbWVudSBjb21wb25lbnQnKTtcbiAgICB9XG5cbiAgICB0aGlzLm1lbnVTZXJ2aWNlLmVkaXRvciA9IHRoaXMuZWRpdG9yO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiTmd4RWRpdG9yX19NZW51QmFyXCJcbiAgW25nQ2xhc3NdPVwieydOZ3hFZGl0b3ItLURpc2FibGVkJzogZGlzYWJsZWQsICdOZ3hFZGl0b3JfX01lbnVCYXItLVJldmVyc2UnOiBkcm9wZG93blBsYWNlbWVudCA9PT0gJ3RvcCd9XCI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdG9vbGJhckl0ZW0gb2YgdG9vbGJhcjsgbGV0IGxhc3RUb29sYmFySXRlbSA9IGxhc3Q7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgdG9vbGJhckl0ZW07IGxldCBsYXN0SXRlbSA9IGxhc3Q7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiPlxuXG4gICAgICA8IS0tIHRvZ2dsZSBpY29ucyAtLT5cbiAgICAgIDxuZ3gtdG9nZ2xlLWNvbW1hbmQgW3Rvb2xiYXJJdGVtXT1cIml0ZW1cIiBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJ0b2dnbGVDb21tYW5kcy5pbmNsdWRlcyhpdGVtKVwiPlxuICAgICAgPC9uZ3gtdG9nZ2xlLWNvbW1hbmQ+XG5cbiAgICAgIDxuZ3gtaW5zZXJ0LWNvbW1hbmQgW3Rvb2xiYXJJdGVtXT1cIml0ZW1cIiBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpbnNlcnRDb21tYW5kcy5pbmNsdWRlcyhpdGVtKVwiPlxuICAgICAgPC9uZ3gtaW5zZXJ0LWNvbW1hbmQ+XG5cbiAgICAgIDwhLS0gbGluayAtLT5cbiAgICAgIDxuZ3gtbGluayBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpdGVtID09PSAnbGluaydcIj48L25neC1saW5rPlxuXG4gICAgICA8IS0tIGltYWdlIC0tPlxuICAgICAgPG5neC1pbWFnZSBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpdGVtID09PSAnaW1hZ2UnXCI+XG4gICAgICA8L25neC1pbWFnZT5cblxuICAgICAgPCEtLSBkcm9wZG93biAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Ryb3BEb3duKGl0ZW0pXCI+XG4gICAgICAgIDxuZ3gtZHJvcGRvd24gKm5nRm9yPVwibGV0IGRyb3Bkb3duSXRlbSBvZiBnZXREcm9wZG93bkl0ZW1zKGl0ZW0pIHwga2V5dmFsdWU7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiXG4gICAgICAgICAgW2NsYXNzXT1cImRyb3Bkb3duQ29udGFpbmVyQ2xhc3NcIiBbZ3JvdXBdPVwiZHJvcGRvd25JdGVtLmtleVwiIFtpdGVtc109XCJkcm9wZG93bkl0ZW0udmFsdWVcIj5cbiAgICAgICAgPC9uZ3gtZHJvcGRvd24+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSB0ZXh0IGNvbG9yIHBpY2tlciAtLT5cbiAgICAgIDxuZ3gtY29sb3ItcGlja2VyIFtjbGFzc109XCJpY29uQ29udGFpbmVyQ2xhc3NcIiAqbmdJZj1cIml0ZW0gPT09ICd0ZXh0X2NvbG9yJ1wiIHR5cGU9XCJ0ZXh0X2NvbG9yXCJcbiAgICAgICAgW3ByZXNldHNdPVwicHJlc2V0c1wiPlxuICAgICAgPC9uZ3gtY29sb3ItcGlja2VyPlxuICAgICAgPCEtLSBiYWNrZ3JvdW5kIGNvbG9yIHBpY2tlciAtLT5cbiAgICAgIDxuZ3gtY29sb3ItcGlja2VyIFtjbGFzc109XCJpY29uQ29udGFpbmVyQ2xhc3NcIiAqbmdJZj1cIml0ZW0gPT09ICdiYWNrZ3JvdW5kX2NvbG9yJ1wiIHR5cGU9XCJiYWNrZ3JvdW5kX2NvbG9yXCJcbiAgICAgICAgW3ByZXNldHNdPVwicHJlc2V0c1wiPlxuICAgICAgPC9uZ3gtY29sb3ItcGlja2VyPlxuXG4gICAgICA8IS0tIHNlcGVyYXRvciAtLT5cbiAgICAgIDxkaXYgW2NsYXNzXT1cInNlcGVyYXRvckNsYXNzXCIgKm5nSWY9XCJsYXN0SXRlbSAmJiAhbGFzdFRvb2xiYXJJdGVtXCI+PC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDwhLS0gY3VzdG9tIG1lbnUgLS0+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJjdXN0b21NZW51UmVmXCI+XG4gICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjdXN0b21NZW51UmVmXCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG48L2Rpdj5cbiJdfQ==