ngx-quill
Version:
An angular (>= v2) component for the easy use of the QuillJS richt text editor.
509 lines • 59.7 kB
JavaScript
import * as tslib_1 from "tslib";
var QuillEditorComponent_1;
import { isPlatformServer } from '@angular/common';
import { DomSanitizer } from '@angular/platform-browser';
import { QUILL_CONFIG_TOKEN } from './quill-editor.interfaces';
import { Component, ElementRef, EventEmitter, forwardRef, Inject, Input, NgZone, Output, PLATFORM_ID, Renderer2, SecurityContext, ViewEncapsulation } from '@angular/core';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { DOCUMENT } from '@angular/common';
import { defaultModules } from './quill-defaults';
// tslint:disable-next-line:variable-name
let Quill = null;
const getFormat = (format, configFormat) => {
const passedFormat = format || configFormat;
return passedFormat || 'html';
};
const ɵ0 = getFormat;
let QuillEditorComponent = QuillEditorComponent_1 = class QuillEditorComponent {
constructor(elementRef, domSanitizer, doc,
// tslint:disable-next-line:ban-types
platformId, renderer, zone, config) {
this.elementRef = elementRef;
this.domSanitizer = domSanitizer;
this.doc = doc;
this.platformId = platformId;
this.renderer = renderer;
this.zone = zone;
this.config = config;
this.required = false;
this.customToolbarPosition = 'top';
this.sanitize = false;
this.styles = null;
this.strict = true;
this.customOptions = [];
this.preserveWhitespace = false;
this.onEditorCreated = new EventEmitter();
this.onEditorChanged = new EventEmitter();
this.onContentChanged = new EventEmitter();
this.onSelectionChanged = new EventEmitter();
this.onFocus = new EventEmitter();
this.onBlur = new EventEmitter();
this.disabled = false; // used to store initial value before ViewInit
this.valueGetter = (quillEditor, editorElement) => {
let html = editorElement.querySelector('.ql-editor').innerHTML;
if (html === '<p><br></p>' || html === '<div><br><div>') {
html = null;
}
let modelValue = html;
const format = getFormat(this.format, this.config.format);
if (format === 'text') {
modelValue = quillEditor.getText();
}
else if (format === 'object') {
modelValue = quillEditor.getContents();
}
else if (format === 'json') {
try {
modelValue = JSON.stringify(quillEditor.getContents());
}
catch (e) {
modelValue = quillEditor.getText();
}
}
return modelValue;
};
this.valueSetter = (quillEditor, value) => {
const format = getFormat(this.format, this.config.format);
if (format === 'html') {
if (this.sanitize) {
value = this.domSanitizer.sanitize(SecurityContext.HTML, value);
}
return quillEditor.clipboard.convert(value);
}
else if (format === 'json') {
try {
return JSON.parse(value);
}
catch (e) {
return [{ insert: value }];
}
}
return value;
};
this.selectionChangeHandler = (range, oldRange, source) => {
this.zone.run(() => {
if (range === null) {
this.onBlur.emit({
editor: this.quillEditor,
source
});
}
else if (oldRange === null) {
this.onFocus.emit({
editor: this.quillEditor,
source
});
}
this.onSelectionChanged.emit({
editor: this.quillEditor,
oldRange,
range,
source
});
if (!range && this.onModelTouched) {
this.onModelTouched();
}
});
};
this.textChangeHandler = (delta, oldDelta, source) => {
// only emit changes emitted by user interactions
const text = this.quillEditor.getText();
const content = this.quillEditor.getContents();
let html = this.editorElem.querySelector('.ql-editor').innerHTML;
if (html === '<p><br></p>' || html === '<div><br><div>') {
html = null;
}
this.zone.run(() => {
const trackChanges = this.trackChanges || this.config.trackChanges;
if ((source === Quill.sources.USER || trackChanges && trackChanges === 'all') && this.onModelChange) {
this.onModelChange(this.valueGetter(this.quillEditor, this.editorElem));
}
this.onContentChanged.emit({
content,
delta,
editor: this.quillEditor,
html,
oldDelta,
source,
text
});
});
};
this.editorChangeHandler = (event, current, old, source) => {
// only emit changes emitted by user interactions
if (event === 'text-change') {
const text = this.quillEditor.getText();
const content = this.quillEditor.getContents();
let html = this.editorElem.querySelector('.ql-editor').innerHTML;
if (html === '<p><br></p>' || html === '<div><br><div>') {
html = null;
}
this.zone.run(() => {
this.onEditorChanged.emit({
content,
delta: current,
editor: this.quillEditor,
event,
html,
oldDelta: old,
source,
text
});
});
}
else {
this.onEditorChanged.emit({
editor: this.quillEditor,
event,
oldRange: old,
range: current,
source
});
}
};
}
// tslint:disable-next-line:no-empty
onModelChange(_modelValue) { }
// tslint:disable-next-line:no-empty
onModelTouched() { }
ngAfterViewInit() {
if (isPlatformServer(this.platformId)) {
return;
}
if (!Quill) {
Quill = require('quill');
}
this.elementRef.nativeElement.insertAdjacentHTML(this.customToolbarPosition === 'top' ? 'beforeend' : 'afterbegin', this.preserveWhitespace ? '<pre quill-editor-element></pre>' : '<div quill-editor-element></div>');
this.editorElem = this.elementRef.nativeElement.querySelector('[quill-editor-element]');
const toolbarElem = this.elementRef.nativeElement.querySelector('[quill-editor-toolbar]');
const modules = Object.assign({}, this.modules || (this.config.modules || defaultModules));
if (toolbarElem) {
modules.toolbar = toolbarElem;
}
else if (modules.toolbar === undefined) {
modules.toolbar = defaultModules.toolbar;
}
let placeholder = this.placeholder !== undefined ? this.placeholder : this.config.placeholder;
if (placeholder === undefined) {
placeholder = 'Insert text here ...';
}
if (this.styles) {
Object.keys(this.styles).forEach((key) => {
this.renderer.setStyle(this.editorElem, key, this.styles[key]);
});
}
this.customOptions.forEach((customOption) => {
const newCustomOption = Quill.import(customOption.import);
newCustomOption.whitelist = customOption.whitelist;
Quill.register(newCustomOption, true);
});
let bounds = this.bounds && this.bounds === 'self' ? this.editorElem : this.bounds;
if (!bounds) {
bounds = this.config.bounds ? this.config.bounds : this.doc.body;
}
let debug = this.debug;
if (!debug && debug !== false && this.config.debug) {
debug = this.config.debug;
}
let readOnly = this.readOnly;
if (!readOnly && this.readOnly !== false) {
readOnly = this.config.readOnly !== undefined ? this.config.readOnly : false;
}
let scrollingContainer = this.scrollingContainer;
if (!scrollingContainer && this.scrollingContainer !== null) {
scrollingContainer = this.config.scrollingContainer === null || this.config.scrollingContainer ? this.config.scrollingContainer : null;
}
let formats = this.formats;
if (!formats && formats === undefined) {
formats = this.config.formats ? Object.assign({}, this.config.formats) : (this.config.formats === null ? null : undefined);
}
this.quillEditor = new Quill(this.editorElem, {
bounds,
debug,
formats,
modules,
placeholder,
readOnly,
scrollingContainer,
strict: this.strict,
theme: this.theme || (this.config.theme ? this.config.theme : 'snow')
});
if (this.content) {
const format = getFormat(this.format, this.config.format);
if (format === 'object') {
this.quillEditor.setContents(this.content, 'silent');
}
else if (format === 'text') {
this.quillEditor.setText(this.content, 'silent');
}
else if (format === 'json') {
try {
this.quillEditor.setContents(JSON.parse(this.content), 'silent');
}
catch (e) {
this.quillEditor.setText(this.content, 'silent');
}
}
else {
if (this.sanitize) {
this.content = this.domSanitizer.sanitize(SecurityContext.HTML, this.content);
}
const contents = this.quillEditor.clipboard.convert(this.content);
this.quillEditor.setContents(contents, 'silent');
}
this.quillEditor.history.clear();
}
// initialize disabled status based on this.disabled as default value
this.setDisabledState();
// triggered if selection or text changed
this.quillEditor.on('editor-change', this.editorChangeHandler);
// mark model as touched if editor lost focus
this.quillEditor.on('selection-change', this.selectionChangeHandler);
// update model if text changes
this.quillEditor.on('text-change', this.textChangeHandler);
// trigger created in a timeout to avoid changed models after checked
// if you are using the editor api in created output to change the editor content
setTimeout(() => this.onEditorCreated.emit(this.quillEditor));
}
ngOnDestroy() {
if (this.quillEditor) {
this.quillEditor.off('selection-change', this.selectionChangeHandler);
this.quillEditor.off('text-change', this.textChangeHandler);
this.quillEditor.off('editor-change', this.editorChangeHandler);
}
}
ngOnChanges(changes) {
if (!this.quillEditor) {
return;
}
// tslint:disable:no-string-literal
if (changes['readOnly']) {
this.quillEditor.enable(!changes['readOnly'].currentValue);
}
if (changes['placeholder']) {
this.quillEditor.root.dataset.placeholder =
changes['placeholder'].currentValue;
}
if (changes['styles']) {
const currentStyling = changes['styles'].currentValue;
const previousStyling = changes['styles'].previousValue;
if (previousStyling) {
Object.keys(previousStyling).forEach((key) => {
this.renderer.removeStyle(this.editorElem, key);
});
}
if (currentStyling) {
Object.keys(currentStyling).forEach((key) => {
this.renderer.setStyle(this.editorElem, key, this.styles[key]);
});
}
}
// tslint:enable:no-string-literal
}
writeValue(currentValue) {
this.content = currentValue;
const format = getFormat(this.format, this.config.format);
if (this.quillEditor) {
if (currentValue) {
if (format === 'text') {
this.quillEditor.setText(currentValue);
}
else {
this.quillEditor.setContents(this.valueSetter(this.quillEditor, this.content));
}
return;
}
this.quillEditor.setText('');
}
}
setDisabledState(isDisabled = this.disabled) {
// store initial value to set appropriate disabled status after ViewInit
this.disabled = isDisabled;
if (this.quillEditor) {
if (isDisabled) {
this.quillEditor.disable();
this.renderer.setAttribute(this.elementRef.nativeElement, 'disabled', 'disabled');
}
else {
if (!this.readOnly) {
this.quillEditor.enable();
}
this.renderer.removeAttribute(this.elementRef.nativeElement, 'disabled');
}
}
}
registerOnChange(fn) {
this.onModelChange = fn;
}
registerOnTouched(fn) {
this.onModelTouched = fn;
}
validate() {
if (!this.quillEditor) {
return null;
}
const err = {};
let valid = true;
const textLength = this.quillEditor.getText().trim().length;
if (this.minLength && textLength && textLength < this.minLength) {
err.minLengthError = {
given: textLength,
minLength: this.minLength
};
valid = false;
}
if (this.maxLength && textLength > this.maxLength) {
err.maxLengthError = {
given: textLength,
maxLength: this.maxLength
};
valid = false;
}
if (this.required && !textLength) {
err.requiredError = {
empty: true
};
valid = false;
}
return valid ? null : err;
}
};
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], QuillEditorComponent.prototype, "format", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], QuillEditorComponent.prototype, "theme", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "modules", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "debug", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Boolean)
], QuillEditorComponent.prototype, "readOnly", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], QuillEditorComponent.prototype, "placeholder", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Number)
], QuillEditorComponent.prototype, "maxLength", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Number)
], QuillEditorComponent.prototype, "minLength", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Boolean)
], QuillEditorComponent.prototype, "required", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Array)
], QuillEditorComponent.prototype, "formats", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], QuillEditorComponent.prototype, "customToolbarPosition", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Boolean)
], QuillEditorComponent.prototype, "sanitize", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "styles", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Boolean)
], QuillEditorComponent.prototype, "strict", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "scrollingContainer", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "bounds", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Array)
], QuillEditorComponent.prototype, "customOptions", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", String)
], QuillEditorComponent.prototype, "trackChanges", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Boolean)
], QuillEditorComponent.prototype, "preserveWhitespace", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], QuillEditorComponent.prototype, "onEditorCreated", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], QuillEditorComponent.prototype, "onEditorChanged", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], QuillEditorComponent.prototype, "onContentChanged", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], QuillEditorComponent.prototype, "onSelectionChanged", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], QuillEditorComponent.prototype, "onFocus", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", EventEmitter)
], QuillEditorComponent.prototype, "onBlur", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "valueGetter", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], QuillEditorComponent.prototype, "valueSetter", void 0);
QuillEditorComponent = QuillEditorComponent_1 = tslib_1.__decorate([
Component({
encapsulation: ViewEncapsulation.None,
providers: [
{
multi: true,
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => QuillEditorComponent_1)
},
{
multi: true,
provide: NG_VALIDATORS,
useExisting: forwardRef(() => QuillEditorComponent_1)
}
],
selector: 'quill-editor',
template: `
<ng-content select="[quill-editor-toolbar]"></ng-content>
`
}),
tslib_1.__param(2, Inject(DOCUMENT)),
tslib_1.__param(3, Inject(PLATFORM_ID)),
tslib_1.__param(6, Inject(QUILL_CONFIG_TOKEN)),
tslib_1.__metadata("design:paramtypes", [ElementRef,
DomSanitizer, Object, Object,
Renderer2,
NgZone, Object])
], QuillEditorComponent);
export { QuillEditorComponent };
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpbGwtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1xdWlsbC8iLCJzb3VyY2VzIjpbInNyYy9xdWlsbC1lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBRXhELE9BQU8sRUFBRSxrQkFBa0IsRUFBMEMsTUFBTSwyQkFBMkIsQ0FBQTtBQUV0RyxPQUFPLEVBRUwsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixXQUFXLEVBQ1gsU0FBUyxFQUNULGVBQWUsRUFFZixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUE7QUFFdEIsT0FBTyxFQUVMLGFBQWEsRUFDYixpQkFBaUIsRUFFbEIsTUFBTSxnQkFBZ0IsQ0FBQTtBQUV2QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDMUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBS2pELHlDQUF5QztBQUN6QyxJQUFJLEtBQUssR0FBUSxJQUFJLENBQUE7QUFZckIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxNQUFvQixFQUFFLFlBQTBCLEVBQWUsRUFBRTtJQUNsRixNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksWUFBWSxDQUFBO0lBQzNDLE9BQU8sWUFBWSxJQUFJLE1BQU0sQ0FBQTtBQUMvQixDQUFDLENBQUE7O0FBcUJELElBQWEsb0JBQW9CLDRCQUFqQyxNQUFhLG9CQUFvQjtJQXNFL0IsWUFDVSxVQUFzQixFQUN0QixZQUEwQixFQUNSLEdBQVE7SUFDbEMscUNBQXFDO0lBQ1IsVUFBa0IsRUFDdkMsUUFBbUIsRUFDbkIsSUFBWSxFQUNnQixNQUFtQjtR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QURDLEtBQUssRUFBRTs7eURBaUJQO0FBL0hVLG9CQUFvQjtJQW5CaEMsU0FBUyxDQUFDO1FBQ1QsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7UUFDckMsU0FBUyxFQUFFO1lBQ1Q7Z0JBQ0UsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsT0FBTyxFQUFFLGlCQUFpQjtnQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxzQkFBb0IsQ0FBQzthQUNwRDtZQUNEO2dCQUNFLEtBQUssRUFBRSxJQUFJO2dCQUNYLE9BQU8sRUFBRSxhQUFhO2dCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHNCQUFvQixDQUFDO2FBQ3BEO1NBQ0Y7UUFDRCxRQUFRLEVBQUUsY0FBYztRQUN4QixRQUFRLEVBQUU7O0NBRVg7S0FDQSxDQUFDO0lBMEVHLG1CQUFBLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUVoQixtQkFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUE7SUFHbkIsbUJBQUEsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUE7NkNBUFAsVUFBVTtRQUNSLFlBQVksVUFHTyxNQUFNO1FBQzdCLFNBQVM7UUFDYixNQUFNO0dBN0VYLG9CQUFvQixDQWtlaEM7U0FsZVksb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbidcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInXG5cbmltcG9ydCB7IFFVSUxMX0NPTkZJR19UT0tFTiwgUXVpbGxDb25maWcsIFF1aWxsRm9ybWF0LCBRdWlsbE1vZHVsZXMgfSBmcm9tICcuL3F1aWxsLWVkaXRvci5pbnRlcmZhY2VzJ1xuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBQTEFURk9STV9JRCxcbiAgUmVuZGVyZXIyLFxuICBTZWN1cml0eUNvbnRleHQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5cbmltcG9ydCB7XG4gIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICBOR19WQUxJREFUT1JTLFxuICBOR19WQUxVRV9BQ0NFU1NPUixcbiAgVmFsaWRhdG9yXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJ1xuXG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbidcbmltcG9ydCB7IGRlZmF1bHRNb2R1bGVzIH0gZnJvbSAnLi9xdWlsbC1kZWZhdWx0cydcblxuLy8gQmVjYXVzZSBxdWlsbCB1c2VzIGBkb2N1bWVudGAgZGlyZWN0bHksIHdlIGNhbm5vdCBgaW1wb3J0YCBkdXJpbmcgU1NSXG4vLyBpbnN0ZWFkLCB3ZSBsb2FkIGR5bmFtaWNhbGx5IHZpYSBgcmVxdWlyZSgncXVpbGwnKWAgaW4gYG5nQWZ0ZXJWaWV3SW5pdCgpYFxuZGVjbGFyZSB2YXIgcmVxdWlyZTogYW55XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFyaWFibGUtbmFtZVxubGV0IFF1aWxsOiBhbnkgPSBudWxsXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3VzdG9tT3B0aW9uIHtcbiAgaW1wb3J0OiBzdHJpbmdcbiAgd2hpdGVsaXN0OiBhbnlbXVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJhbmdlIHtcbiAgaW5kZXg6IG51bWJlclxuICBsZW5ndGg6IG51bWJlclxufVxuXG5jb25zdCBnZXRGb3JtYXQgPSAoZm9ybWF0PzogUXVpbGxGb3JtYXQsIGNvbmZpZ0Zvcm1hdD86IFF1aWxsRm9ybWF0KTogUXVpbGxGb3JtYXQgPT4ge1xuICBjb25zdCBwYXNzZWRGb3JtYXQgPSBmb3JtYXQgfHwgY29uZmlnRm9ybWF0XG4gIHJldHVybiBwYXNzZWRGb3JtYXQgfHwgJ2h0bWwnXG59XG5cbkBDb21wb25lbnQoe1xuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gUXVpbGxFZGl0b3JDb21wb25lbnQpXG4gICAgfSxcbiAgICB7XG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTElEQVRPUlMsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBRdWlsbEVkaXRvckNvbXBvbmVudClcbiAgICB9XG4gIF0sXG4gIHNlbGVjdG9yOiAncXVpbGwtZWRpdG9yJyxcbiAgdGVtcGxhdGU6IGBcbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW3F1aWxsLWVkaXRvci10b29sYmFyXVwiPjwvbmctY29udGVudD5cbmBcbn0pXG5leHBvcnQgY2xhc3MgUXVpbGxFZGl0b3JDb21wb25lbnRcbiAgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFZhbGlkYXRvciB7XG5cbiAgcXVpbGxFZGl0b3I6IGFueVxuICBlZGl0b3JFbGVtOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZFxuICBjb250ZW50OiBhbnlcblxuICBASW5wdXQoKSBmb3JtYXQ/OiAnb2JqZWN0JyB8ICdodG1sJyB8ICd0ZXh0JyB8ICdqc29uJ1xuICBASW5wdXQoKSB0aGVtZT86IHN0cmluZ1xuICBASW5wdXQoKSBtb2R1bGVzPzogUXVpbGxNb2R1bGVzXG4gIEBJbnB1dCgpIGRlYnVnPzogJ3dhcm4nIHzCoCdsb2cnIHzCoCdlcnJvcicgfMKgZmFsc2VcbiAgQElucHV0KCkgcmVhZE9ubHk/OiBib29sZWFuXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyPzogc3RyaW5nXG4gIEBJbnB1dCgpIG1heExlbmd0aD86IG51bWJlclxuICBASW5wdXQoKSBtaW5MZW5ndGg/OiBudW1iZXJcbiAgQElucHV0KCkgcmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICBASW5wdXQoKSBmb3JtYXRzPzogc3RyaW5nW10gfMKgbnVsbFxuICBASW5wdXQoKSBjdXN0b21Ub29sYmFyUG9zaXRpb246ICd0b3AnIHzCoCdib3R0b20nID0gJ3RvcCdcbiAgQElucHV0KCkgc2FuaXRpemU6IGJvb2xlYW4gPSBmYWxzZVxuICBASW5wdXQoKSBzdHlsZXM6IGFueSA9IG51bGxcbiAgQElucHV0KCkgc3RyaWN0OiBib29sZWFuID0gdHJ1ZVxuICBASW5wdXQoKSBzY3JvbGxpbmdDb250YWluZXI/OiBIVE1MRWxlbWVudCB8IHN0cmluZyB8IG51bGxcbiAgQElucHV0KCkgYm91bmRzPzogSFRNTEVsZW1lbnQgfCBzdHJpbmdcbiAgQElucHV0KCkgY3VzdG9tT3B0aW9uczogQ3VzdG9tT3B0aW9uW10gPSBbXVxuICBASW5wdXQoKSB0cmFja0NoYW5nZXM/OiAndXNlcicgfMKgJ2FsbCdcbiAgQElucHV0KCkgcHJlc2VydmVXaGl0ZXNwYWNlOiBib29sZWFuID0gZmFsc2VcblxuICBAT3V0cHV0KCkgb25FZGl0b3JDcmVhdGVkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuICBAT3V0cHV0KCkgb25FZGl0b3JDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8e1xuICAgIGNvbnRlbnQ6IGFueVxuICAgIGRlbHRhOiBhbnlcbiAgICBlZGl0b3I6IGFueVxuICAgIGV2ZW50OiAndGV4dC1jaGFuZ2UnXG4gICAgaHRtbDogc3RyaW5nIHwgbnVsbFxuICAgIG9sZERlbHRhOiBhbnlcbiAgICBzb3VyY2U6IHN0cmluZ1xuICAgIHRleHQ6IHN0cmluZ1xuICB9IHzCoHtcbiAgICBlZGl0b3I6IGFueVxuICAgIGV2ZW50OiAnc2VsZWN0aW9uLWNoYW5nZSdcbiAgICBvbGRSYW5nZTogUmFuZ2UgfCBudWxsXG4gICAgcmFuZ2U6IFJhbmdlIHzCoG51bGxcbiAgICBzb3VyY2U6IHN0cmluZ1xuICB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuICBAT3V0cHV0KCkgb25Db250ZW50Q2hhbmdlZDogRXZlbnRFbWl0dGVyPHtcbiAgICBjb250ZW50OiBhbnlcbiAgICBkZWx0YTogYW55XG4gICAgZWRpdG9yOiBhbnlcbiAgICBodG1sOiBzdHJpbmcgfCBudWxsXG4gICAgb2xkRGVsdGE6IGFueVxuICAgIHNvdXJjZTogc3RyaW5nXG4gICAgdGV4dDogc3RyaW5nXG4gIH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpXG4gIEBPdXRwdXQoKSBvblNlbGVjdGlvbkNoYW5nZWQ6IEV2ZW50RW1pdHRlcjx7XG4gICAgZWRpdG9yOiBhbnlcbiAgICBvbGRSYW5nZTogUmFuZ2UgfCBudWxsXG4gICAgcmFuZ2U6IFJhbmdlIHzCoG51bGxcbiAgICBzb3VyY2U6IHN0cmluZ1xuICB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuICBAT3V0cHV0KCkgb25Gb2N1czogRXZlbnRFbWl0dGVyPHtcbiAgICBlZGl0b3I6IGFueVxuICAgIHNvdXJjZTogc3RyaW5nXG4gIH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpXG4gIEBPdXRwdXQoKSBvbkJsdXI6IEV2ZW50RW1pdHRlcjx7XG4gICAgZWRpdG9yOiBhbnlcbiAgICBzb3VyY2U6IHN0cmluZ1xuICB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIGRpc2FibGVkID0gZmFsc2UgLy8gdXNlZCB0byBzdG9yZSBpbml0aWFsIHZhbHVlIGJlZm9yZSBWaWV3SW5pdFxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIGRvbVNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jOiBhbnksXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmJhbi10eXBlc1xuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHpvbmU6IE5nWm9uZSxcbiAgICBASW5qZWN0KFFVSUxMX0NPTkZJR19UT0tFTikgcHJpdmF0ZSBjb25maWc6IFF1aWxsQ29uZmlnXG4gICkge31cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgb25Nb2RlbENoYW5nZShfbW9kZWxWYWx1ZT86IGFueSkge31cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gIG9uTW9kZWxUb3VjaGVkKCkge31cblxuICBASW5wdXQoKVxuICB2YWx1ZUdldHRlciA9IChxdWlsbEVkaXRvcjogYW55LCBlZGl0b3JFbGVtZW50OiBIVE1MRWxlbWVudCk6IHN0cmluZyB8IGFuecKgID0+IHtcbiAgICBsZXQgaHRtbDogc3RyaW5nIHwgbnVsbCA9IGVkaXRvckVsZW1lbnQucXVlcnlTZWxlY3RvcignLnFsLWVkaXRvcicpIS5pbm5lckhUTUxcbiAgICBpZiAoaHRtbCA9PT0gJzxwPjxicj48L3A+JyB8fCBodG1sID09PSAnPGRpdj48YnI+PGRpdj4nKSB7XG4gICAgICBodG1sID0gbnVsbFxuICAgIH1cbiAgICBsZXQgbW9kZWxWYWx1ZSA9IGh0bWxcbiAgICBjb25zdCBmb3JtYXQgPSBnZXRGb3JtYXQodGhpcy5mb3JtYXQsIHRoaXMuY29uZmlnLmZvcm1hdClcblxuICAgIGlmIChmb3JtYXQgPT09ICd0ZXh0Jykge1xuICAgICAgbW9kZWxWYWx1ZSA9IHF1aWxsRWRpdG9yLmdldFRleHQoKVxuICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnb2JqZWN0Jykge1xuICAgICAgbW9kZWxWYWx1ZSA9IHF1aWxsRWRpdG9yLmdldENvbnRlbnRzKClcbiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2pzb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBtb2RlbFZhbHVlID0gSlNPTi5zdHJpbmdpZnkocXVpbGxFZGl0b3IuZ2V0Q29udGVudHMoKSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbW9kZWxWYWx1ZSA9IHF1aWxsRWRpdG9yLmdldFRleHQoKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtb2RlbFZhbHVlXG4gIH1cblxuICBASW5wdXQoKVxuICB2YWx1ZVNldHRlciA9IChxdWlsbEVkaXRvcjogYW55LCB2YWx1ZTogYW55KTogYW55ID0+IHtcbiAgICBjb25zdCBmb3JtYXQgPSBnZXRGb3JtYXQodGhpcy5mb3JtYXQsIHRoaXMuY29uZmlnLmZvcm1hdClcbiAgICBpZiAoZm9ybWF0ID09PSAnaHRtbCcpIHtcbiAgICAgIGlmICh0aGlzLnNhbml0aXplKSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5kb21TYW5pdGl6ZXIuc2FuaXRpemUoU2VjdXJpdHlDb250ZXh0LkhUTUwsIHZhbHVlKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHF1aWxsRWRpdG9yLmNsaXBib2FyZC5jb252ZXJ0KHZhbHVlKVxuICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnanNvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gW3sgaW5zZXJ0OiB2YWx1ZSB9XVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGlmIChpc1BsYXRmb3JtU2VydmVyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoIVF1aWxsKSB7XG4gICAgICBRdWlsbCA9IHJlcXVpcmUoJ3F1aWxsJylcbiAgICB9XG5cbiAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5pbnNlcnRBZGphY2VudEhUTUwoXG4gICAgICB0aGlzLmN1c3RvbVRvb2xiYXJQb3NpdGlvbiA9PT0gJ3RvcCcgPyAnYmVmb3JlZW5kJyA6ICdhZnRlcmJlZ2luJyxcbiAgICAgIHRoaXMucHJlc2VydmVXaGl0ZXNwYWNlID8gJzxwcmUgcXVpbGwtZWRpdG9yLWVsZW1lbnQ+PC9wcmU+JyA6ICc8ZGl2IHF1aWxsLWVkaXRvci1lbGVtZW50PjwvZGl2PidcbiAgICApXG5cbiAgICB0aGlzLmVkaXRvckVsZW0gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgJ1txdWlsbC1lZGl0b3ItZWxlbWVudF0nXG4gICAgKVxuXG4gICAgY29uc3QgdG9vbGJhckVsZW0gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgJ1txdWlsbC1lZGl0b3ItdG9vbGJhcl0nXG4gICAgKVxuICAgIGNvbnN0IG1vZHVsZXMgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm1vZHVsZXMgfHwgKHRoaXMuY29uZmlnLm1vZHVsZXMgfHzCoGRlZmF1bHRNb2R1bGVzKSlcblxuICAgIGlmICh0b29sYmFyRWxlbSkge1xuICAgICAgbW9kdWxlcy50b29sYmFyID0gdG9vbGJhckVsZW1cbiAgICB9IGVsc2UgaWYgKG1vZHVsZXMudG9vbGJhciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtb2R1bGVzLnRvb2xiYXIgPSBkZWZhdWx0TW9kdWxlcy50b29sYmFyXG4gICAgfVxuXG4gICAgbGV0IHBsYWNlaG9sZGVyID0gdGhpcy5wbGFjZWhvbGRlciAhPT0gdW5kZWZpbmVkID8gdGhpcy5wbGFjZWhvbGRlciA6IHRoaXMuY29uZmlnLnBsYWNlaG9sZGVyXG4gICAgaWYgKHBsYWNlaG9sZGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBsYWNlaG9sZGVyID0gJ0luc2VydCB0ZXh0IGhlcmUgLi4uJ1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0eWxlcykge1xuICAgICAgT2JqZWN0LmtleXModGhpcy5zdHlsZXMpLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lZGl0b3JFbGVtLCBrZXksIHRoaXMuc3R5bGVzW2tleV0pXG4gICAgICB9KVxuICAgIH1cblxuICAgIHRoaXMuY3VzdG9tT3B0aW9ucy5mb3JFYWNoKChjdXN0b21PcHRpb24pID0+IHtcbiAgICAgIGNvbnN0IG5ld0N1c3RvbU9wdGlvbiA9IFF1aWxsLmltcG9ydChjdXN0b21PcHRpb24uaW1wb3J0KVxuICAgICAgbmV3Q3VzdG9tT3B0aW9uLndoaXRlbGlzdCA9IGN1c3RvbU9wdGlvbi53aGl0ZWxpc3RcbiAgICAgIFF1aWxsLnJlZ2lzdGVyKG5ld0N1c3RvbU9wdGlvbiwgdHJ1ZSlcbiAgICB9KVxuXG4gICAgbGV0IGJvdW5kcyA9IHRoaXMuYm91bmRzICYmIHRoaXMuYm91bmRzID09PSAnc2VsZicgPyB0aGlzLmVkaXRvckVsZW0gOiB0aGlzLmJvdW5kc1xuICAgIGlmICghYm91bmRzKSB7XG4gICAgICBib3VuZHMgPSB0aGlzLmNvbmZpZy5ib3VuZHMgPyB0aGlzLmNvbmZpZy5ib3VuZHMgOiB0aGlzLmRvYy5ib2R5XG4gICAgfVxuXG4gICAgbGV0IGRlYnVnID0gdGhpcy5kZWJ1Z1xuICAgIGlmICghZGVidWcgJiYgZGVidWcgIT09IGZhbHNlICYmIHRoaXMuY29uZmlnLmRlYnVnKSB7XG4gICAgICBkZWJ1ZyA9IHRoaXMuY29uZmlnLmRlYnVnXG4gICAgfVxuXG4gICAgbGV0IHJlYWRPbmx5ID0gdGhpcy5yZWFkT25seVxuICAgIGlmICghcmVhZE9ubHkgJiYgdGhpcy5yZWFkT25seSAhPT0gZmFsc2UpIHtcbiAgICAgIHJlYWRPbmx5ID0gdGhpcy5jb25maWcucmVhZE9ubHkgIT09IHVuZGVmaW5lZCA/IHRoaXMuY29uZmlnLnJlYWRPbmx5IDogZmFsc2VcbiAgICB9XG5cbiAgICBsZXQgc2Nyb2xsaW5nQ29udGFpbmVyID0gdGhpcy5zY3JvbGxpbmdDb250YWluZXJcbiAgICBpZiAoIXNjcm9sbGluZ0NvbnRhaW5lciAmJiB0aGlzLnNjcm9sbGluZ0NvbnRhaW5lciAhPT0gbnVsbCkge1xuICAgICAgc2Nyb2xsaW5nQ29udGFpbmVyID0gdGhpcy5jb25maWcuc2Nyb2xsaW5nQ29udGFpbmVyID09PSBudWxsIHx8wqB0aGlzLmNvbmZpZy5zY3JvbGxpbmdDb250YWluZXIgPyB0aGlzLmNvbmZpZy5zY3JvbGxpbmdDb250YWluZXIgOiBudWxsXG4gICAgfVxuXG4gICAgbGV0IGZvcm1hdHMgPSB0aGlzLmZvcm1hdHNcbiAgICBpZiAoIWZvcm1hdHMgJiYgZm9ybWF0cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmb3JtYXRzID0gdGhpcy5jb25maWcuZm9ybWF0cyA/IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuY29uZmlnLmZvcm1hdHMpIDrCoCh0aGlzLmNvbmZpZy5mb3JtYXRzID09PSBudWxsID8gbnVsbCA6IHVuZGVmaW5lZClcbiAgICB9XG5cbiAgICB0aGlzLnF1aWxsRWRpdG9yID0gbmV3IFF1aWxsKHRoaXMuZWRpdG9yRWxlbSwge1xuICAgICAgYm91bmRzLFxuICAgICAgZGVidWcsXG4gICAgICBmb3JtYXRzLFxuICAgICAgbW9kdWxlcyxcbiAgICAgIHBsYWNlaG9sZGVyLFxuICAgICAgcmVhZE9ubHksXG4gICAgICBzY3JvbGxpbmdDb250YWluZXIsXG4gICAgICBzdHJpY3Q6IHRoaXMuc3RyaWN0LFxuICAgICAgdGhlbWU6IHRoaXMudGhlbWUgfHwgKHRoaXMuY29uZmlnLnRoZW1lID8gdGhpcy5jb25maWcudGhlbWUgOiAnc25vdycpXG4gICAgfSlcblxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIGNvbnN0IGZvcm1hdCA9IGdldEZvcm1hdCh0aGlzLmZvcm1hdCwgdGhpcy5jb25maWcuZm9ybWF0KVxuICAgICAgaWYgKGZvcm1hdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhpcy5xdWlsbEVkaXRvci5zZXRDb250ZW50cyh0aGlzLmNvbnRlbnQsICdzaWxlbnQnKVxuICAgICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICd0ZXh0Jykge1xuICAgICAgICB0aGlzLnF1aWxsRWRpdG9yLnNldFRleHQodGhpcy5jb250ZW50LCAnc2lsZW50JylcbiAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnanNvbicpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgI