ngx-quill
Version:
An angular (>= v2) component for the easy use of the QuillJS richt text editor.
609 lines • 53.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
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
/** @type {?} */
let Quill = null;
/**
* @record
*/
export function CustomOption() { }
if (false) {
/** @type {?} */
CustomOption.prototype.import;
/** @type {?} */
CustomOption.prototype.whitelist;
}
/**
* @record
*/
export function Range() { }
if (false) {
/** @type {?} */
Range.prototype.index;
/** @type {?} */
Range.prototype.length;
}
export class QuillEditorComponent {
// used to store initial value before ViewInit
/**
* @param {?} elementRef
* @param {?} domSanitizer
* @param {?} doc
* @param {?} platformId
* @param {?} renderer
* @param {?} zone
* @param {?} config
*/
constructor(elementRef, domSanitizer, doc, 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.format = 'html';
this.required = false;
this.customToolbarPosition = 'top';
this.sanitize = false;
this.style = null;
this.strict = true;
this.customOptions = [];
this.onEditorCreated = new EventEmitter();
this.onContentChanged = new EventEmitter();
this.onSelectionChanged = new EventEmitter();
this.disabled = false; // used to store initial value before ViewInit
this.valueGetter = (/**
* @param {?} quillEditor
* @param {?} editorElement
* @return {?}
*/
(quillEditor, editorElement) => {
/** @type {?} */
let html = editorElement.children[0].innerHTML;
if (html === '<p><br></p>' || html === '<div><br><div>') {
html = null;
}
/** @type {?} */
let modelValue = html;
if (this.format === 'text') {
modelValue = quillEditor.getText();
}
else if (this.format === 'object') {
modelValue = quillEditor.getContents();
}
else if (this.format === 'json') {
try {
modelValue = JSON.stringify(quillEditor.getContents());
}
catch (e) {
modelValue = quillEditor.getText();
}
}
return modelValue;
});
this.valueSetter = (/**
* @param {?} quillEditor
* @param {?} value
* @return {?}
*/
(quillEditor, value) => {
if (this.format === 'html') {
if (this.sanitize) {
value = this.domSanitizer.sanitize(SecurityContext.HTML, value);
}
return quillEditor.clipboard.convert(value);
}
else if (this.format === 'json') {
try {
return JSON.parse(value);
}
catch (e) {
return [{ insert: value }];
}
}
return value;
});
this.selectionChangeHandler = (/**
* @param {?} range
* @param {?} oldRange
* @param {?} source
* @return {?}
*/
(range, oldRange, source) => {
this.zone.run((/**
* @return {?}
*/
() => {
this.onSelectionChanged.emit({
editor: this.quillEditor,
oldRange,
range,
source
});
if (!range && this.onModelTouched) {
this.onModelTouched();
}
}));
});
this.textChangeHandler = (/**
* @param {?} delta
* @param {?} oldDelta
* @param {?} source
* @return {?}
*/
(delta, oldDelta, source) => {
// only emit changes emitted by user interactions
// only emit changes emitted by user interactions
/** @type {?} */
const text = this.quillEditor.getText();
/** @type {?} */
const content = this.quillEditor.getContents();
/** @type {?} */
let html = (/** @type {?} */ (this.editorElem)).children[0].innerHTML;
if (html === '<p><br></p>' || html === '<div><br><div>') {
html = null;
}
this.zone.run((/**
* @return {?}
*/
() => {
/** @type {?} */
const trackChanges = this.trackChanges || this.config.trackChanges;
if ((source === Quill.sources.USER || trackChanges && trackChanges === 'all') && this.onModelChange) {
this.onModelChange(this.valueGetter(this.quillEditor, (/** @type {?} */ (this.editorElem))));
}
this.onContentChanged.emit({
content,
delta,
editor: this.quillEditor,
html,
oldDelta,
source,
text
});
}));
});
}
// tslint:disable-next-line:no-empty
/**
* @param {?=} _modelValue
* @return {?}
*/
onModelChange(_modelValue) { }
// tslint:disable-next-line:no-empty
/**
* @return {?}
*/
onModelTouched() { }
/**
* @return {?}
*/
ngAfterViewInit() {
if (isPlatformServer(this.platformId)) {
return;
}
if (!Quill) {
Quill = require('quill');
}
if (this.customToolbarPosition === 'top') {
this.elementRef.nativeElement.insertAdjacentHTML('beforeend', '<div quill-editor-element></div>');
}
else {
this.elementRef.nativeElement.insertAdjacentHTML('afterbegin', '<div quill-editor-element></div>');
}
this.editorElem = this.elementRef.nativeElement.querySelector('[quill-editor-element]');
/** @type {?} */
const toolbarElem = this.elementRef.nativeElement.querySelector('[quill-editor-toolbar]');
/** @type {?} */
const modules = this.modules || (this.config.modules || defaultModules);
if (modules.toolbar === undefined) {
modules.toolbar = defaultModules.toolbar;
}
/** @type {?} */
let placeholder = this.placeholder !== undefined ? this.placeholder : this.config.placeholder;
if (placeholder === undefined) {
placeholder = 'Insert text here ...';
}
if (toolbarElem) {
// tslint:disable-next-line:no-string-literal
modules['toolbar'] = toolbarElem;
}
if (this.style) {
Object.keys(this.style).forEach((/**
* @param {?} key
* @return {?}
*/
(key) => {
this.renderer.setStyle(this.editorElem, key, this.style[key]);
}));
}
this.customOptions.forEach((/**
* @param {?} customOption
* @return {?}
*/
(customOption) => {
/** @type {?} */
const newCustomOption = Quill.import(customOption.import);
newCustomOption.whitelist = customOption.whitelist;
Quill.register(newCustomOption, true);
}));
/** @type {?} */
let bounds = this.bounds && this.bounds === 'self' ? this.editorElem : this.bounds;
if (!bounds) {
bounds = this.config.bounds ? this.config.bounds : this.doc.body;
}
/** @type {?} */
let debug = this.debug;
if (!debug && debug !== false && this.config.debug) {
debug = this.config.debug;
}
/** @type {?} */
let readOnly = this.readOnly;
if (!readOnly && this.readOnly !== false) {
readOnly = this.config.readOnly !== undefined ? this.config.readOnly : false;
}
/** @type {?} */
let scrollingContainer = this.scrollingContainer;
if (!scrollingContainer && this.scrollingContainer !== null) {
scrollingContainer = this.config.scrollingContainer === null || this.config.scrollingContainer ? this.config.scrollingContainer : null;
}
/** @type {?} */
let formats = this.formats;
if (!formats && formats === undefined) {
formats = this.config.formats || this.config.formats === null ? this.config.formats : 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) {
if (this.format === 'object') {
this.quillEditor.setContents(this.content, 'silent');
}
else if (this.format === 'text') {
this.quillEditor.setText(this.content, 'silent');
}
else if (this.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);
}
/** @type {?} */
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();
this.onEditorCreated.emit(this.quillEditor);
// 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);
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.quillEditor) {
this.quillEditor.off('selection-change', this.selectionChangeHandler);
this.quillEditor.off('text-change', this.textChangeHandler);
}
}
/**
* @param {?} changes
* @return {?}
*/
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['style']) {
/** @type {?} */
const currentStyling = changes['style'].currentValue;
/** @type {?} */
const previousStyling = changes['style'].previousValue;
if (previousStyling) {
Object.keys(previousStyling).forEach((/**
* @param {?} key
* @return {?}
*/
(key) => {
this.renderer.removeStyle(this.editorElem, key);
}));
}
if (currentStyling) {
Object.keys(currentStyling).forEach((/**
* @param {?} key
* @return {?}
*/
(key) => {
this.renderer.setStyle(this.editorElem, key, this.style[key]);
}));
}
}
// tslint:enable:no-string-literal
}
/**
* @param {?} currentValue
* @return {?}
*/
writeValue(currentValue) {
this.content = currentValue;
if (this.quillEditor) {
if (currentValue) {
if (this.format === 'text') {
this.quillEditor.setText(currentValue);
}
else {
this.quillEditor.setContents(this.valueSetter(this.quillEditor, this.content));
}
return;
}
this.quillEditor.setText('');
}
}
/**
* @param {?=} isDisabled
* @return {?}
*/
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');
}
}
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onModelChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onModelTouched = fn;
}
/**
* @return {?}
*/
validate() {
if (!this.quillEditor) {
return null;
}
/** @type {?} */
const err = {};
/** @type {?} */
let valid = true;
/** @type {?} */
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;
}
}
QuillEditorComponent.decorators = [
{ type: Component, args: [{
encapsulation: ViewEncapsulation.None,
providers: [
{
multi: true,
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
() => QuillEditorComponent))
},
{
multi: true,
provide: NG_VALIDATORS,
useExisting: forwardRef((/**
* @return {?}
*/
() => QuillEditorComponent))
}
],
selector: 'quill-editor',
template: `
<ng-content select="[quill-editor-toolbar]"></ng-content>
`
}] }
];
/** @nocollapse */
QuillEditorComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: DomSanitizer },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
{ type: Renderer2 },
{ type: NgZone },
{ type: undefined, decorators: [{ type: Inject, args: [QUILL_CONFIG_TOKEN,] }] }
];
QuillEditorComponent.propDecorators = {
format: [{ type: Input }],
theme: [{ type: Input }],
modules: [{ type: Input }],
debug: [{ type: Input }],
readOnly: [{ type: Input }],
placeholder: [{ type: Input }],
maxLength: [{ type: Input }],
minLength: [{ type: Input }],
required: [{ type: Input }],
formats: [{ type: Input }],
customToolbarPosition: [{ type: Input }],
sanitize: [{ type: Input }],
style: [{ type: Input }],
strict: [{ type: Input }],
scrollingContainer: [{ type: Input }],
bounds: [{ type: Input }],
customOptions: [{ type: Input }],
trackChanges: [{ type: Input }],
onEditorCreated: [{ type: Output }],
onContentChanged: [{ type: Output }],
onSelectionChanged: [{ type: Output }],
valueGetter: [{ type: Input }],
valueSetter: [{ type: Input }]
};
if (false) {
/** @type {?} */
QuillEditorComponent.prototype.quillEditor;
/** @type {?} */
QuillEditorComponent.prototype.editorElem;
/** @type {?} */
QuillEditorComponent.prototype.content;
/** @type {?} */
QuillEditorComponent.prototype.format;
/** @type {?} */
QuillEditorComponent.prototype.theme;
/** @type {?} */
QuillEditorComponent.prototype.modules;
/** @type {?} */
QuillEditorComponent.prototype.debug;
/** @type {?} */
QuillEditorComponent.prototype.readOnly;
/** @type {?} */
QuillEditorComponent.prototype.placeholder;
/** @type {?} */
QuillEditorComponent.prototype.maxLength;
/** @type {?} */
QuillEditorComponent.prototype.minLength;
/** @type {?} */
QuillEditorComponent.prototype.required;
/** @type {?} */
QuillEditorComponent.prototype.formats;
/** @type {?} */
QuillEditorComponent.prototype.customToolbarPosition;
/** @type {?} */
QuillEditorComponent.prototype.sanitize;
/** @type {?} */
QuillEditorComponent.prototype.style;
/** @type {?} */
QuillEditorComponent.prototype.strict;
/** @type {?} */
QuillEditorComponent.prototype.scrollingContainer;
/** @type {?} */
QuillEditorComponent.prototype.bounds;
/** @type {?} */
QuillEditorComponent.prototype.customOptions;
/** @type {?} */
QuillEditorComponent.prototype.trackChanges;
/** @type {?} */
QuillEditorComponent.prototype.onEditorCreated;
/** @type {?} */
QuillEditorComponent.prototype.onContentChanged;
/** @type {?} */
QuillEditorComponent.prototype.onSelectionChanged;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.disabled;
/** @type {?} */
QuillEditorComponent.prototype.valueGetter;
/** @type {?} */
QuillEditorComponent.prototype.valueSetter;
/** @type {?} */
QuillEditorComponent.prototype.selectionChangeHandler;
/** @type {?} */
QuillEditorComponent.prototype.textChangeHandler;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.elementRef;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.domSanitizer;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.doc;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.platformId;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.renderer;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.zone;
/**
* @type {?}
* @private
*/
QuillEditorComponent.prototype.config;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpbGwtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1xdWlsbC8iLCJzb3VyY2VzIjpbInNyYy9xdWlsbC1lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFFeEQsT0FBTyxFQUFFLGtCQUFrQixFQUE2QixNQUFNLDJCQUEyQixDQUFBO0FBRXpGLE9BQU8sRUFFTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBR04sTUFBTSxFQUNOLFdBQVcsRUFDWCxTQUFTLEVBQ1QsZUFBZSxFQUVmLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQTtBQUV0QixPQUFPLEVBRUwsYUFBYSxFQUNiLGlCQUFpQixFQUVsQixNQUFNLGdCQUFnQixDQUFBO0FBRXZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7OztJQU03QyxLQUFLLEdBQVEsSUFBSTs7OztBQUVyQixrQ0FHQzs7O0lBRkMsOEJBQWM7O0lBQ2QsaUNBQWdCOzs7OztBQUdsQiwyQkFHQzs7O0lBRkMsc0JBQWE7O0lBQ2IsdUJBQWM7O0FBc0JoQixNQUFNLE9BQU8sb0JBQW9COzs7Ozs7Ozs7OztJQTZDL0IsWUFDVSxVQUFzQixFQUN0QixZQUEwQixFQUNSLEdBQVEsRUFFTCxVQUFrQixFQUN2QyxRQUFtQixFQUNuQixJQUFZLEVBQ2dCLE1BQW1CO1FBUC9DLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDUixRQUFHLEdBQUgsR0FBRyxDQUFLO1FBRUwsZUFBVSxHQUFWLFVB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LGtEQUF5RDs7SUFDekQsc0NBQXNDOztJQUN0Qyw2Q0FBMkM7O0lBQzNDLDRDQUFzQzs7SUFFdEMsK0NBQWlFOztJQUNqRSxnREFRdUI7O0lBQ3ZCLGtEQUt1Qjs7Ozs7SUFFdkIsd0NBQXdCOztJQWtCeEIsMkNBcUJDOztJQUVELDJDQWdCQzs7SUFvSUQsc0RBYUM7O0lBRUQsaURBNkJDOzs7OztJQXRPQywwQ0FBOEI7Ozs7O0lBQzlCLDRDQUFrQzs7Ozs7SUFDbEMsbUNBQWtDOzs7OztJQUVsQywwQ0FBK0M7Ozs7O0lBQy9DLHdDQUEyQjs7Ozs7SUFDM0Isb0NBQW9COzs7OztJQUNwQixzQ0FBdUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYXRmb3JtU2VydmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJ1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3NlcidcblxuaW1wb3J0IHsgUVVJTExfQ09ORklHX1RPS0VOLCBRdWlsbENvbmZpZywgUXVpbGxNb2R1bGVzIH0gZnJvbSAnLi9xdWlsbC1lZGl0b3IuaW50ZXJmYWNlcydcblxuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUExBVEZPUk1fSUQsXG4gIFJlbmRlcmVyMixcbiAgU2VjdXJpdHlDb250ZXh0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuXG5pbXBvcnQge1xuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgTkdfVkFMSURBVE9SUyxcbiAgTkdfVkFMVUVfQUNDRVNTT1IsXG4gIFZhbGlkYXRvclxufSBmcm9tICdAYW5ndWxhci9mb3JtcydcblxuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nXG5pbXBvcnQgeyBkZWZhdWx0TW9kdWxlcyB9IGZyb20gJy4vcXVpbGwtZGVmYXVsdHMnXG5cbi8vIEJlY2F1c2UgcXVpbGwgdXNlcyBgZG9jdW1lbnRgIGRpcmVjdGx5LCB3ZSBjYW5ub3QgYGltcG9ydGAgZHVyaW5nIFNTUlxuLy8gaW5zdGVhZCwgd2UgbG9hZCBkeW5hbWljYWxseSB2aWEgYHJlcXVpcmUoJ3F1aWxsJylgIGluIGBuZ0FmdGVyVmlld0luaXQoKWBcbmRlY2xhcmUgdmFyIHJlcXVpcmU6IGFueVxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbmxldCBRdWlsbDogYW55ID0gbnVsbFxuXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbU9wdGlvbiB7XG4gIGltcG9ydDogc3RyaW5nXG4gIHdoaXRlbGlzdDogYW55W11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSYW5nZSB7XG4gIGluZGV4OiBudW1iZXJcbiAgbGVuZ3RoOiBudW1iZXJcbn1cblxuQENvbXBvbmVudCh7XG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBRdWlsbEVkaXRvckNvbXBvbmVudClcbiAgICB9LFxuICAgIHtcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFF1aWxsRWRpdG9yQ29tcG9uZW50KVxuICAgIH1cbiAgXSxcbiAgc2VsZWN0b3I6ICdxdWlsbC1lZGl0b3InLFxuICB0ZW1wbGF0ZTogYFxuICA8bmctY29udGVudCBzZWxlY3Q9XCJbcXVpbGwtZWRpdG9yLXRvb2xiYXJdXCI+PC9uZy1jb250ZW50PlxuYFxufSlcbmV4cG9ydCBjbGFzcyBRdWlsbEVkaXRvckNvbXBvbmVudFxuICBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgVmFsaWRhdG9yIHtcblxuICBxdWlsbEVkaXRvcjogYW55XG4gIGVkaXRvckVsZW06IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkXG4gIGNvbnRlbnQ6IGFueVxuXG4gIEBJbnB1dCgpIGZvcm1hdD86ICdvYmplY3QnIHwgJ2h0bWwnIHwgJ3RleHQnIHwgJ2pzb24nID0gJ2h0bWwnXG4gIEBJbnB1dCgpIHRoZW1lPzogc3RyaW5nXG4gIEBJbnB1dCgpIG1vZHVsZXM/OiBRdWlsbE1vZHVsZXNcbiAgQElucHV0KCkgZGVidWc/OiAnd2FybicgfMKgJ2xvZycgfMKgJ2Vycm9yJyB8wqBmYWxzZVxuICBASW5wdXQoKSByZWFkT25seT86IGJvb2xlYW5cbiAgQElucHV0KCkgcGxhY2Vob2xkZXI/OiBzdHJpbmdcbiAgQElucHV0KCkgbWF4TGVuZ3RoPzogbnVtYmVyXG4gIEBJbnB1dCgpIG1pbkxlbmd0aD86IG51bWJlclxuICBASW5wdXQoKSByZXF1aXJlZDogYm9vbGVhbiA9IGZhbHNlXG4gIEBJbnB1dCgpIGZvcm1hdHM/OiBzdHJpbmdbXSB8wqBudWxsXG4gIEBJbnB1dCgpIGN1c3RvbVRvb2xiYXJQb3NpdGlvbjogJ3RvcCcgfMKgJ2JvdHRvbScgPSAndG9wJ1xuICBASW5wdXQoKSBzYW5pdGl6ZTogYm9vbGVhbiA9IGZhbHNlXG4gIEBJbnB1dCgpIHN0eWxlOiBhbnkgPSBudWxsXG4gIEBJbnB1dCgpIHN0cmljdDogYm9vbGVhbiA9IHRydWVcbiAgQElucHV0KCkgc2Nyb2xsaW5nQ29udGFpbmVyPzogSFRNTEVsZW1lbnQgfCBzdHJpbmcgfCBudWxsXG4gIEBJbnB1dCgpIGJvdW5kcz86IEhUTUxFbGVtZW50IHwgc3RyaW5nXG4gIEBJbnB1dCgpIGN1c3RvbU9wdGlvbnM6IEN1c3RvbU9wdGlvbltdID0gW11cbiAgQElucHV0KCkgdHJhY2tDaGFuZ2VzPzogJ3VzZXInIHzCoCdhbGwnXG5cbiAgQE91dHB1dCgpIG9uRWRpdG9yQ3JlYXRlZDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKClcbiAgQE91dHB1dCgpIG9uQ29udGVudENoYW5nZWQ6IEV2ZW50RW1pdHRlcjx7XG4gICAgY29udGVudDogYW55XG4gICAgZGVsdGE6IGFueVxuICAgIGVkaXRvcjogYW55XG4gICAgaHRtbDogc3RyaW5nIHwgbnVsbFxuICAgIG9sZERlbHRhOiBhbnlcbiAgICBzb3VyY2U6IHN0cmluZ1xuICAgIHRleHQ6IHN0cmluZ1xuICB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuICBAT3V0cHV0KCkgb25TZWxlY3Rpb25DaGFuZ2VkOiBFdmVudEVtaXR0ZXI8e1xuICAgIGVkaXRvcjogYW55XG4gICAgb2xkUmFuZ2U6IFJhbmdlIHwgbnVsbFxuICAgIHJhbmdlOiBSYW5nZSB8wqBudWxsXG4gICAgc291cmNlOiBzdHJpbmdcbiAgfT4gPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBwcml2YXRlIGRpc2FibGVkID0gZmFsc2UgLy8gdXNlZCB0byBzdG9yZSBpbml0aWFsIHZhbHVlIGJlZm9yZSBWaWV3SW5pdFxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIGRvbVNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jOiBhbnksXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmJhbi10eXBlc1xuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHpvbmU6IE5nWm9uZSxcbiAgICBASW5qZWN0KFFVSUxMX0NPTkZJR19UT0tFTikgcHJpdmF0ZSBjb25maWc6IFF1aWxsQ29uZmlnXG4gICkge31cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgb25Nb2RlbENoYW5nZShfbW9kZWxWYWx1ZT86IGFueSkge31cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gIG9uTW9kZWxUb3VjaGVkKCkge31cblxuICBASW5wdXQoKVxuICB2YWx1ZUdldHRlciA9IChxdWlsbEVkaXRvcjogYW55LCBlZGl0b3JFbGVtZW50OiBIVE1MRWxlbWVudCk6IHN0cmluZyB8IGFuecKgID0+IHtcbiAgICBsZXQgaHRtbDogc3RyaW5nIHwgbnVsbCA9IGVkaXRvckVsZW1lbnQuY2hpbGRyZW5bMF0uaW5uZXJIVE1MXG4gICAgaWYgKGh0bWwgPT09ICc8cD48YnI+PC9wPicgfHwgaHRtbCA9PT0gJzxkaXY+PGJyPjxkaXY+Jykge1xuICAgICAgaHRtbCA9IG51bGxcbiAgICB9XG4gICAgbGV0IG1vZGVsVmFsdWUgPSBodG1sXG5cbiAgICBpZiAodGhpcy5mb3JtYXQgPT09ICd0ZXh0Jykge1xuICAgICAgbW9kZWxWYWx1ZSA9IHF1aWxsRWRpdG9yLmdldFRleHQoKVxuICAgIH0gZWxzZSBpZiAodGhpcy5mb3JtYXQgPT09ICdvYmplY3QnKSB7XG4gICAgICBtb2RlbFZhbHVlID0gcXVpbGxFZGl0b3IuZ2V0Q29udGVudHMoKVxuICAgIH0gZWxzZSBpZiAodGhpcy5mb3JtYXQgPT09ICdqc29uJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbW9kZWxWYWx1ZSA9IEpTT04uc3RyaW5naWZ5KHF1aWxsRWRpdG9yLmdldENvbnRlbnRzKCkpXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIG1vZGVsVmFsdWUgPSBxdWlsbEVkaXRvci5nZXRUZXh0KClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWxWYWx1ZVxuICB9XG5cbiAgQElucHV0KClcbiAgdmFsdWVTZXR0ZXIgPSAocXVpbGxFZGl0b3I6IGFueSwgdmFsdWU6IGFueSk6IGFueSA9PiB7XG4gICAgaWYgKHRoaXMuZm9ybWF0ID09PSAnaHRtbCcpIHtcbiAgICAgIGlmICh0aGlzLnNhbml0aXplKSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5kb21TYW5pdGl6ZXIuc2FuaXRpemUoU2VjdXJpdHlDb250ZXh0LkhUTUwsIHZhbHVlKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHF1aWxsRWRpdG9yLmNsaXBib2FyZC5jb252ZXJ0KHZhbHVlKVxuICAgIH0gZWxzZSBpZiAodGhpcy5mb3JtYXQgPT09ICdqc29uJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBbeyBpbnNlcnQ6IHZhbHVlIH1dXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmICghUXVpbGwpIHtcbiAgICAgIFF1aWxsID0gcmVxdWlyZSgncXVpbGwnKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmN1c3RvbVRvb2xiYXJQb3NpdGlvbiA9PT0gJ3RvcCcpIHtcbiAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50Lmluc2VydEFkamFjZW50SFRNTChcbiAgICAgICAgJ2JlZm9yZWVuZCcsXG4gICAgICAgICc8ZGl2IHF1aWxsLWVkaXRvci1lbGVtZW50PjwvZGl2PidcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuaW5zZXJ0QWRqYWNlbnRIVE1MKFxuICAgICAgICAnYWZ0ZXJiZWdpbicsXG4gICAgICAgICc8ZGl2IHF1aWxsLWVkaXRvci1lbGVtZW50PjwvZGl2PidcbiAgICAgIClcbiAgICB9XG4gICAgdGhpcy5lZGl0b3JFbGVtID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICdbcXVpbGwtZWRpdG9yLWVsZW1lbnRdJ1xuICAgIClcblxuICAgIGNvbnN0IHRvb2xiYXJFbGVtID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICdbcXVpbGwtZWRpdG9yLXRvb2xiYXJdJ1xuICAgIClcbiAgICBjb25zdCBtb2R1bGVzID0gdGhpcy5tb2R1bGVzIHx8ICh0aGlzLmNvbmZpZy5tb2R1bGVzIHx8wqBkZWZhdWx0TW9kdWxlcylcbiAgICBpZiAobW9kdWxlcy50b29sYmFyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG1vZHVsZXMudG9vbGJhciA9IGRlZmF1bHRNb2R1bGVzLnRvb2xiYXJcbiAgICB9XG5cbiAgICBsZXQgcGxhY2Vob2xkZXIgPSB0aGlzLnBsYWNlaG9sZGVyICE9PSB1bmRlZmluZWQgPyB0aGlzLnBsYWNlaG9sZGVyIDogdGhpcy5jb25maWcucGxhY2Vob2xkZXJcbiAgICBpZiAocGxhY2Vob2xkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGxhY2Vob2xkZXIgPSAnSW5zZXJ0IHRleHQgaGVyZSAuLi4nXG4gICAgfVxuXG4gICAgaWYgKHRvb2xiYXJFbGVtKSB7XG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tc3RyaW5nLWxpdGVyYWxcbiAgICAgIG1vZHVsZXNbJ3Rvb2xiYXInXSA9IHRvb2xiYXJFbGVtXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3R5bGUpIHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuc3R5bGUpLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lZGl0b3JFbGVtLCBrZXksIHRoaXMuc3R5bGVba2V5XSlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdGhpcy5jdXN0b21PcHRpb25zLmZvckVhY2goKGN1c3RvbU9wdGlvbikgPT4ge1xuICAgICAgY29uc3QgbmV3Q3VzdG9tT3B0aW9uID0gUXVpbGwuaW1wb3J0KGN1c3RvbU9wdGlvbi5pbXBvcnQpXG4gICAgICBuZXdDdXN0b21PcHRpb24ud2hpdGVsaXN0ID0gY3VzdG9tT3B0aW9uLndoaXRlbGlzdFxuICAgICAgUXVpbGwucmVnaXN0ZXIobmV3Q3VzdG9tT3B0aW9uLCB0cnVlKVxuICAgIH0pXG5cbiAgICBsZXQgYm91bmRzID0gdGhpcy5ib3VuZHMgJiYgdGhpcy5ib3VuZHMgPT09ICdzZWxmJyA/IHRoaXMuZWRpdG9yRWxlbSA6IHRoaXMuYm91bmRzXG4gICAgaWYgKCFib3VuZHMpIHtcbiAgICAgIGJvdW5kcyA9IHRoaXMuY29uZmlnLmJvdW5kcyA/IHRoaXMuY29uZmlnLmJvdW5kcyA6IHRoaXMuZG9jLmJvZHlcbiAgICB9XG5cbiAgICBsZXQgZGVidWcgPSB0aGlzLmRlYnVnXG4gICAgaWYgKCFkZWJ1ZyAmJiBkZWJ1ZyAhPT0gZmFsc2UgJiYgdGhpcy5jb25maWcuZGVidWcpIHtcbiAgICAgIGRlYnVnID0gdGhpcy5jb25maWcuZGVidWdcbiAgICB9XG5cbiAgICBsZXQgcmVhZE9ubHkgPSB0aGlzLnJlYWRPbmx5XG4gICAgaWYgKCFyZWFkT25seSAmJiB0aGlzLnJlYWRPbmx5ICE9PSBmYWxzZSkge1xuICAgICAgcmVhZE9ubHkgPSB0aGlzLmNvbmZpZy5yZWFkT25seSAhPT0gdW5kZWZpbmVkID8gdGhpcy5jb25maWcucmVhZE9ubHkgOiBmYWxzZVxuICAgIH1cblxuICAgIGxldCBzY3JvbGxpbmdDb250YWluZXIgPSB0aGlzLnNjcm9sbGluZ0NvbnRhaW5lclxuICAgIGlmICghc2Nyb2xsaW5nQ29udGFpbmVyICYmIHRoaXMuc2Nyb2xsaW5nQ29udGFpbmVyICE9PSBudWxsKSB7XG4gICAgICBzY3JvbGxpbmdDb250YWluZXIgPSB0aGlzLmNvbmZpZy5zY3JvbGxpbmdDb250YWluZXIgPT09IG51bGwgfHzCoHRoaXMuY29uZmlnLnNjcm9sbGluZ0NvbnRhaW5lciA/IHRoaXMuY29uZmlnLnNjcm9sbGluZ0NvbnRhaW5lciA6IG51bGxcbiAgICB9XG5cbiAgICBsZXQgZm9ybWF0cyA9IHRoaXMuZm9ybWF0c1xuICAgIGlmICghZm9ybWF0cyAmJiBmb3JtYXRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvcm1hdHMgPSB0aGlzLmNvbmZpZy5mb3JtYXRzIHx8wqB0aGlzLmNvbmZpZy5mb3JtYXRzID09PSBudWxsID8gdGhpcy5jb25maWcuZm9ybWF0cyA6IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHRoaXMucXVpbGxFZGl0b3IgPSBuZXcgUXVpbGwodGhpcy5lZGl0b3JFbGVtLCB7XG4gICAgICBib3VuZHMsXG4gICAgICBkZWJ1ZyxcbiAgICAgIGZvcm1hdHMsXG4gICAgICBtb2R1bGVzLFxuICAgICAgcGxhY2Vob2xkZXIsXG4gICAgICByZWFkT25seSxcbiAgICAgIHNjcm9sbGluZ0NvbnRhaW5lcixcbiAgICAgIHN0cmljdDogdGhpcy5zdHJpY3QsXG4gICAgICB0aGVtZTogdGhpcy50aGVtZSB8fCAodGhpcy5jb25maWcudGhlbWUgPyB0aGlzLmNvbmZpZy50aGVtZSA6ICdzbm93JylcbiAgICB9KVxuXG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgaWYgKHRoaXMuZm9ybWF0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLnF1aWxsRWRpdG9yLnNldENvbnRlbnRzKHRoaXMuY29udGVudCwgJ3NpbGVudCcpXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZm9ybWF0ID09PSAndGV4dCcpIHtcbiAgICAgICAgdGhpcy5xdWlsbEVkaXRvci5zZXRUZXh0KHRoaXMuY29udGVudCwgJ3NpbGVudCcpXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZm9ybWF0ID09PSAnanNvbicpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLnF1aWxsRWRpdG9yLnNldENvbnRlbnRzKEpTT04ucGFyc2UodGhpcy5jb250ZW50KSwgJ3NpbGVudCcpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICB0aGlzLnF1aWxsRWRpdG9yLnNldFRleHQodGhpcy5jb250ZW50LCAnc2lsZW50JylcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuc2FuaXRpemUpIHtcbiAgICAgICAgICB0aGlzLmNvbnRlbnQgPSB0aGlzLmRvbVNhbml0aXplci5zYW5pdGl6ZShTZWN1cml0eUNvbnRleHQuSFRNTCwgdGhpcy5jb250ZW50KVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnRlbnRzID0gdGhpcy5xdWlsbEVkaXRvci5jbGlwYm9hcmQuY29udmVydCh0aGlzLmNvbnRlbnQpXG4gICAgICAgIHRoaXMucXVpbGxFZGl0b3Iuc2V0Q29udGVudHMoY29udGVudHMsICdzaWxlbnQnKVxuICAgICAgfVxuXG4gICAgICB0aGlzLnF1aWxsRWRpdG9yLmhpc3RvcnkuY2xlYXIoKVxuICAgIH1cblxuICAgIC8vIGluaXRpYWxpemUgZGlzYWJsZWQgc3RhdHVzIGJhc2VkIG9uIHRoaXMuZGlzYWJsZWQgYXMgZGVmYXVsdCB2YWx1ZVxuICAgIHRoaXMuc2V0RGlzYWJsZWRTdGF0ZSgpXG5cbiAgICB0aGlzLm9uRWRpdG9yQ3JlYXRlZC5lbWl0KHRoaXMucXVpbGxFZGl0b3IpXG5cbiAgICAvLyBtYXJrIG1vZGVsIGFzIHRvdWNoZWQgaWYgZWRpdG9yIGxvc3QgZm9jdXNcbiAgICB0aGlzLnF1aWxsRWRpdG9yLm9uKFxuICAgICAgJ3NlbGVjdGlvbi1jaGFuZ2UnLFxuICAgICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2VIYW5kbGVyXG4gICAgKVxuXG4gICAgLy8gdXBkYXRlIG1vZGVsIGlmIHRleHQgY2hhbmdlc1xuICAgIHRoaXMucXVpbGxFZGl0b3Iub24oXG4gICAgICAndGV4dC1jaGFuZ2UnLFxuICAgICAgdGhpcy50ZXh0Q2hhbmdlSGFuZGxlclxuICAgIClcbiAgfVxuXG4gIHNlbGVjdGlvbkNoYW5nZUhhbmRsZXIgPSAocmFuZ2U6IFJhbmdlIHzCoG51bGwsIG9sZFJhbmdlOiBSYW5nZSB8IG51bGwsIHNvdXJjZTogc3RyaW5nKSA9PiB7XG4gICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHtcbiAgICAgICAgZWRpdG9yOiB0aGlzLnF1aWxsRWRpdG9yLFxuICAgICAgICBvbGRSYW5nZSxcbiAgICAgICAgcmFuZ2UsXG4gICAgICAgIHNvdXJjZVxuICAgICAgfSlcblxuICAgICAgaWYgKCFyYW5nZSAmJiB0aGlzLm9uTW9kZWxUb3VjaGVkKSB7XG4gICAgICAgIHRoaXMub25Nb2RlbFRvdWNoZWQoKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICB0ZXh0Q2hhbmdlSGFuZGxlciA9IChkZWx0YTogYW55LCBvbGREZWx0YTogYW55LCBzb3VyY2U6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIC8vIG9ubHkgZW1pdCBjaGFuZ2VzIGVtaXR0ZWQgYnkgdXNlciBpbnRlcmFjdGlvbnNcblxuICAgIGNvbnN0IHRleHQgPSB0aGlzLnF1aWxsRWRpdG9yLmdldFRleHQoKVxuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnF1aWxsRWRpdG9yLmdldENvbnRlbnRzKClcblxuICAgIGxldCBodG1sOiBzdHJpbmcgfCBudWxsID0gdGhpcy5lZGl0b3JFbGVtIS5jaGlsZHJlblswXS5pbm5lckhUTUxcbiAgICBpZiAoaHRtbCA9PT0gJzxwPjxicj48L3A+JyB8fCBodG1sID09PSAnPGRpdj48YnI+PGRpdj4nKSB7XG4gICAgICBodG1sID0gbnVsbFxuICAgIH1cblxuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3QgdHJhY2tDaGFuZ2VzID0gdGhpcy50cmFja0NoYW5nZXMgfHzCoHRoaXMuY29uZmlnLnRyYWNrQ2hhbmdlc1xuICAgICAgaWYgKChzb3VyY2UgPT09IFF1aWxsLnNvdXJjZXMuVVNFUiB8fCB0cmFja0NoYW5nZXMgJiYgdHJhY2tDaGFuZ2VzID09PSAnYWxsJykgJiYgdGhpcy5vbk1vZGVsQ2hhbmdlKSB7XG4gICAgICAgIHRoaXMub25Nb2RlbENoYW5nZShcbiAgICAgICAgICB0aGlzLnZhbHVlR2V0dGVyKHRoaXMucXVpbGxFZGl0b3IsIHRoaXMuZWRpdG9yRWxlbSEpXG4gICAgICAgIClcbiAgICAgIH1cblxuICAgICAgdGhpcy5vbkNvbnRlbnRDaGFuZ2VkLmVtaXQoe1xuICAgICAgICBjb250ZW50LFxuICAgICAgICBkZWx0YSxcbiAgICAgICAgZWRpdG9yOiB0aGlzLnF1aWxsRWRpdG9yLFxuICAgICAgICBodG1sLFxuICAgICAgICBvbGREZWx0YSxcbiAgICAgICAgc291cmNlLFxuICAgICAgICB0ZXh0XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5xdWlsbEVkaXRvcikge1xuICAgICAgdGhpcy5xdWlsbEVkaXRvci5vZmYoJ3NlbGVjdGlvbi1jaGFuZ2UnLCB0aGlzLnNlbGVjdGlvbkNoYW5nZUhhbmRsZXIpXG4gICAgICB0aGlzLnF1aWxsRWRpdG9yLm9mZigndGV4dC1jaGFuZ2UnLCB0aGlzLnRleHRDaGFuZ2VIYW5kbGVyKVxuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucXVpbGxFZGl0b3IpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuICAgIGlmIChjaGFuZ2VzWydyZWFkT25seSddKSB7XG4gICAgICB0aGlzLnF