angular-xml-editor
Version:
XML editor component for Angular
363 lines (362 loc) • 31.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { XMLCursorPositions } from './code/cursor/xmlCursorPos.class';
import { DomDummyNodeManager } from './code/dummyNodes/domDummyNodeManager.class';
import { Component, Input, ViewChild, Output, EventEmitter, Renderer2, forwardRef, ViewEncapsulation, ElementRef } from '@angular/core';
import { AngularXmlEditorService } from './angular-xml-editor.service';
import { Xml2html } from './code/xml-html-converter/xml2html.class';
import { Html2xml } from './code/xml-html-converter/html2xml.class';
var AngularXmlEditorComponent = /** @class */ (function () {
function AngularXmlEditorComponent(_renderer, editorService) {
this._renderer = _renderer;
this.editorService = editorService;
this.isDebugMode = false;
this.valueChange = new EventEmitter();
// actualXmlCursor: XmlCursor = new XmlCursor();
this.domDummyNodeManager = new DomDummyNodeManager();
}
Object.defineProperty(AngularXmlEditorComponent.prototype, "config", {
get: /**
* @return {?}
*/
function () {
if (this.editorContext !== undefined && this.editorContext.config !== undefined) {
return this.editorContext && this.editorContext.config;
}
return undefined;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AngularXmlEditorComponent.prototype, "editorContextId", {
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
if (!value) {
return;
}
this.editorContext = this.editorService.getEditorContext(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(AngularXmlEditorComponent.prototype, "debugMode", {
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this.isDebugMode = value;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.ngOnChanges = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.onLostFocus = /**
* @return {?}
*/
function () {
this.editorContext.saveSelection(); // save selection on lost focus
if (typeof this.onTouchedFunction === 'function') {
this.onTouchedFunction();
}
return;
};
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.onGotFocus = /**
* @return {?}
*/
function () {
this.editorContext.restoreSelection();
this.textArea.nativeElement.focus(); // set focus to the text area
};
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.clicked = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.mousedown = /**
* @return {?}
*/
function () { };
/**
* @param {?} mouseEvent
* @return {?}
*/
AngularXmlEditorComponent.prototype.mouseup = /**
* @param {?} mouseEvent
* @return {?}
*/
function (mouseEvent) {
return this.editorContext.mouseUp(mouseEvent);
};
/**
* @param {?} text
* @return {?}
*/
AngularXmlEditorComponent.prototype.pasted = /**
* @param {?} text
* @return {?}
*/
function (text) {
return this.editorContext.pasted(text);
};
/**
* @return {?}
*/
AngularXmlEditorComponent.prototype.copied = /**
* @return {?}
*/
function () {
return this.editorContext.copied();
};
/**
* @param {?} event
* @return {?}
*/
AngularXmlEditorComponent.prototype.keyDown = /**
* @param {?} event
* @return {?}
*/
function (event) {
return this.editorContext.keyDown(event);
};
/**
* @param {?} event
* @return {?}
*/
AngularXmlEditorComponent.prototype.keyUp = /**
* @param {?} event
* @return {?}
*/
function (event) {
return this.editorContext.keyUp(event);
};
// exec(): boolean {
// let userSelection: Selection;
// if (window.getSelection) {
// userSelection = window.getSelection();
// this.editorBreadCrumb.showSelection(userSelection);
// this.actualXmlCursor.StartPos.SetCursor(userSelection.anchorNode, XMLCursorPositionen.CursorInsideTextNode, userSelection.anchorOffset);
// this.commander.setCursorPos(this.actualXmlCursor.StartPos);
// }
// this.domDummyNodeManager.UpdateDummyNodes(this.actualXmlCursor.xmlDocumentRootNode, false);
// return false;
// }
/**
* @param {?} xml
* @return {?}
*/
AngularXmlEditorComponent.prototype.showXml = /**
* @param {?} xml
* @return {?}
*/
function (xml) {
if (this.textArea && this.editorContext && this.editorContext.config && this.editorContext.config.rules) {
if (xml === undefined) {
return;
}
/** @type {?} */
var xml2html = new Xml2html(this.editorContext.config.rules);
/** @type {?} */
var html = xml2html.ToHtml(xml);
/** @type {?} */
var normalizedValue = xml === null ? '' : html;
this._renderer.setProperty(this.textArea.nativeElement, 'innerHTML', normalizedValue);
}
};
/* START OF ControlValueAccessor (see https://angular.io/api/forms/ControlValueAccessor ) */
/**
* Sets the function called when the control gets a change event
*/
/**
* Sets the function called when the control gets a change event
* @param {?} func
* @return {?}
*/
AngularXmlEditorComponent.prototype.registerOnChange = /**
* Sets the function called when the control gets a change event
* @param {?} func
* @return {?}
*/
function (func) {
this.onChangeFunction = func;
};
/**
* Sets the function called when the control gets a touch event
*/
/**
* Sets the function called when the control gets a touch event
* @param {?} func
* @return {?}
*/
AngularXmlEditorComponent.prototype.registerOnTouched = /**
* Sets the function called when the control gets a touch event
* @param {?} func
* @return {?}
*/
function (func) {
this.onTouchedFunction = func;
};
/**
* Write the new value to the element
*/
/**
* Write the new value to the element
* @param {?} value
* @return {?}
*/
AngularXmlEditorComponent.prototype.writeValue = /**
* Write the new value to the element
* @param {?} value
* @return {?}
*/
function (value) {
if (this.editorContext && this.editorContext.config) {
if (value === null || value === undefined || value === '') {
value = undefined;
}
this.showXml(value);
if (value === undefined) {
this.editorContext.actualCursor.xmlDocumentRootNode = undefined;
}
else {
/** @type {?} */
var el = /** @type {?} */ (this.textArea.nativeElement);
/** @type {?} */
var node = /** @type {?} */ (el.firstChild);
this.editorContext.actualCursor.xmlDocumentRootNode = node;
this.editorContext.actualCursor.StartPos.SetCursor(this.editorContext.actualCursor.xmlDocumentRootNode, XMLCursorPositions.CursorOnCompleteNode);
this.domDummyNodeManager.UpdateDummyNodes(this.editorContext.actualCursor.xmlDocumentRootNode);
}
}
};
/**
* Executed from the contenteditable section while the input property changes
* @param html html string from contenteditable
*/
/**
* Executed from the contenteditable section while the input property changes
* @param {?} html html string from contenteditable
* @return {?}
*/
AngularXmlEditorComponent.prototype.onContentChange = /**
* Executed from the contenteditable section while the input property changes
* @param {?} html html string from contenteditable
* @return {?}
*/
function (html) {
if (typeof this.onChangeFunction === 'function') {
/** @type {?} */
var html2xml = new Html2xml(this.editorContext.config.rules);
/** @type {?} */
var xml = html2xml.ToXml(html);
/** @type {?} */
var normalizedValue = xml === null ? '' : xml;
this.onChangeFunction(normalizedValue);
}
return;
};
/**
* sets the disabled state for this element
*/
/**
* sets the disabled state for this element
* @param {?} isDisabled
* @return {?}
*/
AngularXmlEditorComponent.prototype.setDisabledState = /**
* sets the disabled state for this element
* @param {?} isDisabled
* @return {?}
*/
function (isDisabled) {
/** @type {?} */
var div = this.textArea.nativeElement;
/** @type {?} */
var action = isDisabled ? 'addClass' : 'removeClass';
this._renderer[action](div, 'disabled');
};
AngularXmlEditorComponent.decorators = [
{ type: Component, args: [{
selector: 'axed-editor',
template: "<div\r\n *ngIf=\"config\"\r\n #editor\r\n class=\"axed axed-textarea showtags debugOff\"\r\n (focus)=\"onGotFocus()\"\r\n [attr.contenteditable]=\"true\"\r\n [style.height]=\"config.height\"\r\n [style.width]=\"config.width\"\r\n (input)=\"onContentChange($event.target.innerHTML)\"\r\n (blur)=\"onLostFocus()\"\r\n (click)=\"clicked()\"\r\n (mousedown)=\"mousedown()\"\r\n (mouseup)=\"mouseup($event)\"\r\n (keyup)=\"keyUp($event)\"\r\n (keydown)=\"keyDown($event)\"\r\n (copy)=\"copied()\"\r\n (paste)=\"pasted($event.clipboardData.getData('text/plain'))\"\r\n></div>\r\n",
encapsulation: ViewEncapsulation.None,
// to prevent the scss to rename the class names and not match the new generated xml dom
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return AngularXmlEditorComponent; }),
multi: true
}
],
styles: ["a{cursor:pointer}.axed-textarea{min-height:150px;overflow:auto;margin-top:5px;resize:vertical;outline:0;--font-size:15px;--topBottomTagPadding:2px;--tagIndent:20px;font-size:var(--font-size);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}.axed-textarea.showtags{line-height:calc(var(--font-size) + (var(--topBottomTagPadding) * 2) + 10px)}.axed-textarea.showtags div::after,.axed-textarea.showtags div::before{background:orange;white-space:pre-wrap;border:1px solid #778899}.axed-textarea.showtags div::after,.axed-textarea.showtags div:not(.xmlTagNoClosing)::before{content:\" \" attr(data-tagname) \" \";padding:var(--topBottomTagPadding) 0 var(--topBottomTagPadding);margin:0 2px 2px}.axed-textarea.showtags div:not(.xmlTagNoClosing)::after{content:\" \" attr(data-tagname);padding-right:7px;border-radius:10px 0 0 10px}.axed-textarea.showtags div:not(.xmlTagNoClosing)::before{border-radius:0 10px 10px 0}.axed-textarea.showtags div[data-attributes].xmlTagNoClosing:not([data-attributes=''])::after,.axed-textarea.showtags div[data-attributes]:not([data-attributes='']):not(.xmlTagNoClosing)::before{content:\" \" attr(data-tagname) \" \" attr(data-attributes) \" \"}.axed-textarea.showtags div.comment::after,.axed-textarea.showtags div.comment::before{content:' ' 'comment' ' ';background-color:#d3d3d3}.axed-textarea div div:not(.floating){margin-left:var(--tagIndent)}.tagElement>.dummyNode.parent{color:red}div.floating{display:inline}span.dummyNode.beforefirstTag{float:left;width:0}.axed-textarea.debug span.dummyNode{background-color:red;width:inherit}.axed-textarea.debug span.dummyNode.beforefirstTag{background-color:violet;width:inherit}.axed-textarea.showtags div.selected,.axed-textarea.showtags div.selected::after,.axed-textarea.showtags div.selected::before{background:#add8e6!important;color:#fff}[data-tagname=parsererror],[data-tagname=parsererror] div,[data-tagname=parsererror] div ::after,[data-tagname=parsererror] div::before,[data-tagname=parsererror]::after,[data-tagname=parsererror]::before{background:red!important;color:#fff!important;font-weight:700!important;font-size:20px!important;line-height:32px!important}.angular-editor{position:relative}.angular-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);display:block;color:#868e96;opacity:1}.angular-editor .axed-wrapper{position:relative}.angular-editor .axed-wrapper .axed-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border:1px solid #ddd;background-color:transparent;overflow-x:hidden;overflow-y:auto;z-index:2;position:relative}.angular-editor .axed-wrapper .axed-textarea.focus,.angular-editor .axed-wrapper .axed-textarea:focus{outline:0}.angular-editor .axed-wrapper .axed-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.angular-editor .axed-wrapper ::ng-deep p{margin-bottom:0}.angular-editor .axed-wrapper .axed-placeholder{display:none;position:absolute;top:0;padding:.5rem .8rem 1rem .9rem;z-index:1;color:#6c757d;opacity:.75}.angular-editor .axed-wrapper.show-placeholder .angular-editor-placeholder{display:block}.angular-editor .axed-wrapper.disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.axed-attribute-editor-toolbar{min-height:100px;font:100 .8rem/15px Roboto,Arial,sans-serif;background-color:#f5f5f5;padding:15px;border:1px solid #ddd;margin:0}.axed-attribute-editor-toolbar input,.axed-attribute-editor-toolbar select{width:100%}"]
}] }
];
/** @nocollapse */
AngularXmlEditorComponent.ctorParameters = function () { return [
{ type: Renderer2 },
{ type: AngularXmlEditorService }
]; };
AngularXmlEditorComponent.propDecorators = {
config: [{ type: Input, args: ['config',] }],
editorContextId: [{ type: Input, args: ['editorContextId',] }],
debugMode: [{ type: Input, args: ['debugMode',] }],
textArea: [{ type: ViewChild, args: ['editor',] }],
editorWrapper: [{ type: ViewChild, args: ['editorWrapper',] }],
valueChange: [{ type: Output }]
};
return AngularXmlEditorComponent;
}());
export { AngularXmlEditorComponent };
if (false) {
/** @type {?} */
AngularXmlEditorComponent.prototype.editorContext;
/** @type {?} */
AngularXmlEditorComponent.prototype.isDebugMode;
/** @type {?} */
AngularXmlEditorComponent.prototype.textArea;
/** @type {?} */
AngularXmlEditorComponent.prototype.editorWrapper;
/** @type {?} */
AngularXmlEditorComponent.prototype.valueChange;
/** @type {?} */
AngularXmlEditorComponent.prototype.domDummyNodeManager;
/** @type {?} */
AngularXmlEditorComponent.prototype.onTouchedFunction;
/** @type {?} */
AngularXmlEditorComponent.prototype.onChangeFunction;
/** @type {?} */
AngularXmlEditorComponent.prototype._renderer;
/** @type {?} */
AngularXmlEditorComponent.prototype.editorService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci14bWwtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXIteG1sLWVkaXRvci8iLCJzb3VyY2VzIjpbImxpYi9hbmd1bGFyLXhtbC1lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbEYsT0FBTyxFQUFFLFNBQVMsRUFBYSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBYSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUosT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFdkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7SUF1RGxFLG1DQUFvQixTQUFvQixFQUFVLGFBQXNDO1FBQXBFLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFBVSxrQkFBYSxHQUFiLGFBQWEsQ0FBeUI7MkJBckMxRSxLQUFLOzJCQTZCRSxJQUFJLFlBQVksRUFBRTs7bUNBR2pCLElBQUksbUJBQW1CLEVBQUU7S0FLNkM7SUFuQzVGLHNCQUNJLDZDQUFNOzs7O1FBRFY7WUFFRSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtnQkFDL0UsT0FBTyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO2FBQ3hEO1lBQ0QsT0FBTyxTQUFT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QkFDdkUsdUJBQXVCOzs7eUJBdUI3QixLQUFLLFNBQUMsUUFBUTtrQ0FRZCxLQUFLLFNBQUMsaUJBQWlCOzRCQVF2QixLQUFLLFNBQUMsV0FBVzsyQkFLakIsU0FBUyxTQUFDLFFBQVE7Z0NBRWxCLFNBQVMsU0FBQyxlQUFlOzhCQUd6QixNQUFNOztvQ0F0RFQ7O1NBd0JhLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgWG1sRWRpdG9yQ29uZmlnIH0gZnJvbSAnLi9jb2RlL3htbEVkaXRvckNvbmZpZyc7XHJcbmltcG9ydCB7IFhNTEN1cnNvclBvc2l0aW9ucyB9IGZyb20gJy4vY29kZS9jdXJzb3IveG1sQ3Vyc29yUG9zLmNsYXNzJztcclxuaW1wb3J0IHsgRG9tRHVtbXlOb2RlTWFuYWdlciB9IGZyb20gJy4vY29kZS9kdW1teU5vZGVzL2RvbUR1bW15Tm9kZU1hbmFnZXIuY2xhc3MnO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uQ2hhbmdlcywgSW5wdXQsIFZpZXdDaGlsZCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIFJlbmRlcmVyMiwgZm9yd2FyZFJlZiwgVmlld0VuY2Fwc3VsYXRpb24sIE9uRGVzdHJveSwgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBbmd1bGFyWG1sRWRpdG9yU2VydmljZSB9IGZyb20gJy4vYW5ndWxhci14bWwtZWRpdG9yLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBYbWxFZGl0b3JDb250ZXh0IH0gZnJvbSAnLi9jb2RlL3htbEVkaXRvckNvbnRleHQuY2xhc3MnO1xyXG5pbXBvcnQgeyBYbWwyaHRtbCB9IGZyb20gJy4vY29kZS94bWwtaHRtbC1jb252ZXJ0ZXIveG1sMmh0bWwuY2xhc3MnO1xyXG5pbXBvcnQgeyBIdG1sMnhtbCB9IGZyb20gJy4vY29kZS94bWwtaHRtbC1jb252ZXJ0ZXIvaHRtbDJ4bWwuY2xhc3MnO1xyXG5pbXBvcnQgeyBEZWJ1Z0NvbnRleHQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3NyYy92aWV3JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXhlZC1lZGl0b3InLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9hbmd1bGFyLXhtbC1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2FuZ3VsYXIteG1sLWVkaXRvci5jb21wb25lbnQuc2NzcyddLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsIC8vIHRvIHByZXZlbnQgdGhlIHNjc3MgdG8gcmVuYW1lIHRoZSBjbGFzcyBuYW1lcyBhbmQgbm90IG1hdGNoIHRoZSBuZXcgZ2VuZXJhdGVkIHhtbCBkb21cclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEFuZ3VsYXJYbWxFZGl0b3JDb21wb25lbnQpLFxyXG4gICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgfVxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJYbWxFZGl0b3JDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xyXG4gIHByaXZhdGUgZWRpdG9yQ29udGV4dDogWG1sRWRpdG9yQ29udGV4dDtcclxuICBpc0RlYnVnTW9kZSA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoJ2NvbmZpZycpXHJcbiAgZ2V0IGNvbmZpZygpOiBYbWxFZGl0b3JDb25maWcge1xyXG4gICAgaWYgKHRoaXMuZWRpdG9yQ29udGV4dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWcgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5lZGl0b3JDb250ZXh0ICYmIHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWc7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgQElucHV0KCdlZGl0b3JDb250ZXh0SWQnKVxyXG4gIHNldCBlZGl0b3JDb250ZXh0SWQodmFsdWU6IHN0cmluZykge1xyXG4gICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLmVkaXRvckNvbnRleHQgPSB0aGlzLmVkaXRvclNlcnZpY2UuZ2V0RWRpdG9yQ29udGV4dCh2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoJ2RlYnVnTW9kZScpXHJcbiAgc2V0IGRlYnVnTW9kZSh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgdGhpcy5pc0RlYnVnTW9kZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgQFZpZXdDaGlsZCgnZWRpdG9yJylcclxuICB0ZXh0QXJlYTogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdlZGl0b3JXcmFwcGVyJylcclxuICBlZGl0b3JXcmFwcGVyOiBFbGVtZW50UmVmO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBwdWJsaWMgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIC8vIGFjdHVhbFhtbEN1cnNvcjogWG1sQ3Vyc29yID0gbmV3IFhtbEN1cnNvcigpO1xyXG4gIGRvbUR1bW15Tm9kZU1hbmFnZXIgPSBuZXcgRG9tRHVtbXlOb2RlTWFuYWdlcigpO1xyXG5cclxuICBwcml2YXRlIG9uVG91Y2hlZEZ1bmN0aW9uOiAoKSA9PiB2b2lkO1xyXG4gIHByaXZhdGUgb25DaGFuZ2VGdW5jdGlvbjogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQ7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIsIHByaXZhdGUgZWRpdG9yU2VydmljZTogQW5ndWxhclhtbEVkaXRvclNlcnZpY2UpIHt9XHJcblxyXG4gIG5nT25DaGFuZ2VzKCkge31cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7fVxyXG5cclxuICBvbkxvc3RGb2N1cygpIHtcclxuICAgIHRoaXMuZWRpdG9yQ29udGV4dC5zYXZlU2VsZWN0aW9uKCk7IC8vIHNhdmUgc2VsZWN0aW9uIG9uIGxvc3QgZm9jdXNcclxuICAgIGlmICh0eXBlb2YgdGhpcy5vblRvdWNoZWRGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICB0aGlzLm9uVG91Y2hlZEZ1bmN0aW9uKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBvbkdvdEZvY3VzKCkge1xyXG4gICAgdGhpcy5lZGl0b3JDb250ZXh0LnJlc3RvcmVTZWxlY3Rpb24oKTtcclxuICAgIHRoaXMudGV4dEFyZWEubmF0aXZlRWxlbWVudC5mb2N1cygpOyAvLyBzZXQgZm9jdXMgdG8gdGhlIHRleHQgYXJlYVxyXG4gIH1cclxuXHJcbiAgY2xpY2tlZCgpIHt9XHJcblxyXG4gIG1vdXNlZG93bigpIHt9XHJcblxyXG4gIG1vdXNldXAobW91c2VFdmVudDogTW91c2VFdmVudCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yQ29udGV4dC5tb3VzZVVwKG1vdXNlRXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgcGFzdGVkKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yQ29udGV4dC5wYXN0ZWQodGV4dCk7XHJcbiAgfVxyXG5cclxuICBjb3BpZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5lZGl0b3JDb250ZXh0LmNvcGllZCgpO1xyXG4gIH1cclxuXHJcbiAga2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yQ29udGV4dC5rZXlEb3duKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIGtleVVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5lZGl0b3JDb250ZXh0LmtleVVwKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIC8vIGV4ZWMoKTogYm9vbGVhbiB7XHJcbiAgLy8gICBsZXQgdXNlclNlbGVjdGlvbjogU2VsZWN0aW9uO1xyXG4gIC8vICAgaWYgKHdpbmRvdy5nZXRTZWxlY3Rpb24pIHtcclxuICAvLyAgICAgdXNlclNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAvLyAgICAgdGhpcy5lZGl0b3JCcmVhZENydW1iLnNob3dTZWxlY3Rpb24odXNlclNlbGVjdGlvbik7XHJcbiAgLy8gICAgIHRoaXMuYWN0dWFsWG1sQ3Vyc29yLlN0YXJ0UG9zLlNldEN1cnNvcih1c2VyU2VsZWN0aW9uLmFuY2hvck5vZGUsIFhNTEN1cnNvclBvc2l0aW9uZW4uQ3Vyc29ySW5zaWRlVGV4dE5vZGUsIHVzZXJTZWxlY3Rpb24uYW5jaG9yT2Zmc2V0KTtcclxuICAvLyAgICAgdGhpcy5jb21tYW5kZXIuc2V0Q3Vyc29yUG9zKHRoaXMuYWN0dWFsWG1sQ3Vyc29yLlN0YXJ0UG9zKTtcclxuICAvLyAgIH1cclxuXHJcbiAgLy8gICB0aGlzLmRvbUR1bW15Tm9kZU1hbmFnZXIuVXBkYXRlRHVtbXlOb2Rlcyh0aGlzLmFjdHVhbFhtbEN1cnNvci54bWxEb2N1bWVudFJvb3ROb2RlLCBmYWxzZSk7XHJcblxyXG4gIC8vICAgcmV0dXJuIGZhbHNlO1xyXG4gIC8vIH1cclxuXHJcbiAgc2hvd1htbCh4bWw6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMudGV4dEFyZWEgJiYgdGhpcy5lZGl0b3JDb250ZXh0ICYmIHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWcgJiYgdGhpcy5lZGl0b3JDb250ZXh0LmNvbmZpZy5ydWxlcykge1xyXG4gICAgICBpZiAoeG1sID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHhtbDJodG1sID0gbmV3IFhtbDJodG1sKHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWcucnVsZXMpO1xyXG4gICAgICBjb25zdCBodG1sID0geG1sMmh0bWwuVG9IdG1sKHhtbCk7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHhtbCA9PT0gbnVsbCA/ICcnIDogaHRtbDtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0UHJvcGVydHkodGhpcy50ZXh0QXJlYS5uYXRpdmVFbGVtZW50LCAnaW5uZXJIVE1MJywgbm9ybWFsaXplZFZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qIFNUQVJUIE9GIENvbnRyb2xWYWx1ZUFjY2Vzc29yICAoc2VlIGh0dHBzOi8vYW5ndWxhci5pby9hcGkvZm9ybXMvQ29udHJvbFZhbHVlQWNjZXNzb3IgKSAqL1xyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgY29udHJvbCBnZXRzIGEgY2hhbmdlIGV2ZW50XHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmdW5jOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25DaGFuZ2VGdW5jdGlvbiA9IGZ1bmM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgY29udHJvbCBnZXRzIGEgdG91Y2ggZXZlbnRcclxuICAgKi9cclxuICByZWdpc3Rlck9uVG91Y2hlZChmdW5jOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkRnVuY3Rpb24gPSBmdW5jO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV3JpdGUgdGhlIG5ldyB2YWx1ZSB0byB0aGUgZWxlbWVudFxyXG4gICAqL1xyXG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZWRpdG9yQ29udGV4dCAmJiB0aGlzLmVkaXRvckNvbnRleHQuY29uZmlnKSB7XHJcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJykge1xyXG4gICAgICAgIHZhbHVlID0gdW5kZWZpbmVkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnNob3dYbWwodmFsdWUpO1xyXG5cclxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aGlzLmVkaXRvckNvbnRleHQuYWN0dWFsQ3Vyc29yLnhtbERvY3VtZW50Um9vdE5vZGUgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZWwgPSB0aGlzLnRleHRBcmVhLm5hdGl2ZUVsZW1lbnQgYXMgRWxlbWVudDtcclxuICAgICAgICBjb25zdCBub2RlID0gZWwuZmlyc3RDaGlsZCBhcyBFbGVtZW50O1xyXG4gICAgICAgIHRoaXMuZWRpdG9yQ29udGV4dC5hY3R1YWxDdXJzb3IueG1sRG9jdW1lbnRSb290Tm9kZSA9IG5vZGU7XHJcbiAgICAgICAgdGhpcy5lZGl0b3JDb250ZXh0LmFjdHVhbEN1cnNvci5TdGFydFBvcy5TZXRDdXJzb3IodGhpcy5lZGl0b3JDb250ZXh0LmFjdHVhbEN1cnNvci54bWxEb2N1bWVudFJvb3ROb2RlLCBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29yT25Db21wbGV0ZU5vZGUpO1xyXG4gICAgICAgIHRoaXMuZG9tRHVtbXlOb2RlTWFuYWdlci5VcGRhdGVEdW1teU5vZGVzKHRoaXMuZWRpdG9yQ29udGV4dC5hY3R1YWxDdXJzb3IueG1sRG9jdW1lbnRSb290Tm9kZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4ZWN1dGVkIGZyb20gdGhlIGNvbnRlbnRlZGl0YWJsZSBzZWN0aW9uIHdoaWxlIHRoZSBpbnB1dCBwcm9wZXJ0eSBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGh0bWwgaHRtbCBzdHJpbmcgZnJvbSBjb250ZW50ZWRpdGFibGVcclxuICAgKi9cclxuICBvbkNvbnRlbnRDaGFuZ2UoaHRtbDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAodHlwZW9mIHRoaXMub25DaGFuZ2VGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCBodG1sMnhtbCA9IG5ldyBIdG1sMnhtbCh0aGlzLmVkaXRvckNvbnRleHQuY29uZmlnLnJ1bGVzKTtcclxuICAgICAgY29uc3QgeG1sID0gaHRtbDJ4bWwuVG9YbWwoaHRtbCk7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHhtbCA9PT0gbnVsbCA/ICcnIDogeG1sO1xyXG4gICAgICB0aGlzLm9uQ2hhbmdlRnVuY3Rpb24obm9ybWFsaXplZFZhbHVlKTtcclxuICAgIH1cclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHNldHMgdGhlIGRpc2FibGVkIHN0YXRlIGZvciB0aGlzIGVsZW1lbnRcclxuICAgKi9cclxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIGNvbnN0IGRpdiA9IHRoaXMudGV4dEFyZWEubmF0aXZlRWxlbWVudDtcclxuICAgIGNvbnN0IGFjdGlvbiA9IGlzRGlzYWJsZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJztcclxuICAgIHRoaXMuX3JlbmRlcmVyW2FjdGlvbl0oZGl2LCAnZGlzYWJsZWQnKTtcclxuICB9XHJcblxyXG4gIC8qIEVORCBPRiBDb250cm9sVmFsdWVBY2Nlc3NvciAqL1xyXG59XHJcbiJdfQ==