angular-xml-editor
Version:
XML editor component for Angular
192 lines (191 loc) • 26.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { XMLCursorPositions } from './xmlCursorPos.class';
import { XmlToolbox } from '../xmlToolbox.class';
import { DomDummyNodeManager } from '../dummyNodes/domDummyNodeManager.class';
import { Xml2html } from '../xml-html-converter/xml2html.class';
export class XmlCursorPosMover {
/**
* @param {?} pos
* @param {?} rootNode
* @param {?} xmlRules
* @return {?}
*/
static moveLeft(pos, rootNode, xmlRules) {
if (pos === undefined) {
return false;
}
switch (pos.PosAtNode) {
case XMLCursorPositions.CursorOnCompleteNode:
// Put in front of the node
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorInFrontOfNode);
break;
case XMLCursorPositions.CursorInFrontOfNode:
if (pos.ActualNode === rootNode) {
return false;
}
else {
/** @type {?} */
const previousSibling = DomDummyNodeManager.getPreviousSibling(pos.ActualNode);
if (previousSibling) {
// Previous sibling node exists
pos.setCursorpBehindNodeForLeftMovement(previousSibling);
}
else {
// no previous sibling node available -> set before parent node
pos.SetCursor(pos.ActualNode.parentNode, XMLCursorPositions.CursorInFrontOfNode);
}
}
break;
case XMLCursorPositions.CursorBehindNode:
pos.setCursorpBehindNodeForLeftMovement(pos.ActualNode);
break;
case XMLCursorPositions.CursorInEmptyNode:
// Put in front of the node
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorInFrontOfNode);
break;
case XMLCursorPositions.CursorInsideTextNode:
if (XmlToolbox.IsTextOrCommentNode(pos.ActualNode)) {
// Node is Textnode
if (pos.PosInTextnode > 1) {
// Cursor one character to the left
pos.SetCursor(pos.ActualNode, pos.PosAtNode, pos.PosInTextnode - 1);
}
else {
// Put in front of the node
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorInFrontOfNode);
}
}
else {
/** @type {?} */
const elemt = /** @type {?} */ (pos.ActualNode);
throw new Error(`XMLCursorPos.MoveLeft: CursorPos is XMLCursorPositionen.CursorInnerhalbDesTextNodes,
but no text node has been chosen, but the node ${elemt ? elemt.outerHTML : ''}`);
}
break;
default:
throw new Error(`XMLCursorPos.MoveLeft: unknown CursorPos ${pos.PosAtNode}`);
}
return true;
}
/**
* @param {?} pos
* @param {?} rootNode
* @param {?} xmlRules
* @return {?}
*/
static moveRight(pos, rootNode, xmlRules) {
if (pos === undefined) {
return false;
}
switch (pos.PosAtNode) {
case XMLCursorPositions.CursorOnCompleteNode:
/** @type {?} */
const tagName = Xml2html.getTagNameFromNode(pos.ActualNode);
/** @type {?} */
const rule = xmlRules.ruleElements.get(tagName);
if (rule && rule.empty === true) {
pos.setCursorBehindNodeForDefaultOrRightMovement(pos.ActualNode);
}
else {
/** @type {?} */
const firstChild = DomDummyNodeManager.getFirstChild(pos.ActualNode);
if (firstChild) {
pos.SetCursor(firstChild, XMLCursorPositions.CursorInFrontOfNode);
}
else {
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorInEmptyNode);
}
}
break;
case XMLCursorPositions.CursorBehindNode:
/** @type {?} */
const nextSibling = DomDummyNodeManager.getNextSibling(pos.ActualNode);
if (nextSibling) {
/** @type {?} */
const elemt = /** @type {?} */ (pos.ActualNode);
throw new Error(`XMLCursorPos.MoveRight: cursor behind node should only be set, when no other siblings are following ${elemt ? elemt.outerHTML : ''}`);
}
else {
/** @type {?} */
const parentNextSibling = DomDummyNodeManager.getNextSibling(pos.ActualNode.parentElement);
if (parentNextSibling) {
pos.SetCursor(parentNextSibling, XMLCursorPositions.CursorInFrontOfNode);
}
else {
pos.SetCursor(pos.ActualNode.parentElement, XMLCursorPositions.CursorBehindNode);
}
}
break;
case XMLCursorPositions.CursorInEmptyNode:
// Place behind the node
pos.setCursorBehindNodeForDefaultOrRightMovement(pos.ActualNode);
break;
case XMLCursorPositions.CursorInFrontOfNode:
if (XmlToolbox.IsTextOrCommentNode(pos.ActualNode)) {
// Node is Textnode
if ((/** @type {?} */ (pos.ActualNode)).textContent.length > 1) {
// Textnode is not empty
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorInsideTextNode, 1); // one character forward, behind the first character
}
else {
// Textnode is empty
// put behind the node
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorBehindNode);
// Because "CursorBehindNode" is not attractive, one more step
this.moveRight(pos, rootNode, xmlRules);
}
}
else {
/** @type {?} */
const childNodeCount = DomDummyNodeManager.getChildNodeCount(pos.ActualNode);
if (childNodeCount === 0) {
// no Children existing
if (Xml2html.isNoClosingElement(pos.ActualNode)) {
// If no closed tag is displayed for this node, then directly behind the node
// Place behind the node
pos.setCursorBehindNodeForDefaultOrRightMovement(pos.ActualNode);
}
else {
// Node has closing tag, so put in between
// Place in empty node
pos.SetCursor(pos.ActualNode, XMLCursorPositions.CursorInEmptyNode);
}
}
else {
/** @type {?} */
const firstChild = DomDummyNodeManager.getFirstChild(pos.ActualNode);
pos.SetCursor(firstChild, XMLCursorPositions.CursorInFrontOfNode);
}
}
break;
case XMLCursorPositions.CursorInsideTextNode:
if (XmlToolbox.IsTextOrCommentNode(pos.ActualNode)) {
// Node is Textnode
if ((/** @type {?} */ (pos.ActualNode)).textContent.length > pos.PosInTextnode + 1) {
// there is still text in the right of the textnode
// step one character forwards: behind the first char
pos.SetCursor(pos.ActualNode, pos.PosAtNode, pos.PosInTextnode + 1);
}
else {
// no text after the textnode
// place cursor behind the node
pos.setCursorBehindNodeForDefaultOrRightMovement(pos.ActualNode);
}
}
else {
/** @type {?} */
const elemt = /** @type {?} */ (pos.ActualNode);
throw new Error(`XMLCursorPos.MoveRight: CursorPos is XMLCursorPositionen.CursorInnerhalbDesTextNodes,
but no text node has been chosen, but the node ${elemt ? elemt.outerHTML : ''}`);
}
break;
default:
throw new Error(`String.Format("XMLCursorPos.MoveRight: unknown CursorPos ${pos.PosAtNode}`);
}
return true;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1sQ3Vyc29yUG9zTW92ZXIuY2xhc3MuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyLXhtbC1lZGl0b3IvIiwic291cmNlcyI6WyJsaWIvY29kZS9jdXJzb3IveG1sQ3Vyc29yUG9zTW92ZXIuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBZ0Isa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDOUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRWhFLE1BQU07Ozs7Ozs7SUFDRyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQWlCLEVBQUUsUUFBaUIsRUFBRSxRQUFrQjtRQUM3RSxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUU7WUFDckIsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUVELFFBQVEsR0FBRyxDQUFDLFNBQVMsRUFBRTtZQUNyQixLQUFLLGtCQUFrQixDQUFDLG9CQUFvQjs7Z0JBRTFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO2dCQUN0RSxNQUFNO1lBRVIsS0FBSyxrQkFBa0IsQ0FBQyxtQkFBbUI7Z0JBQ3pDLElBQUksR0FBRyxDQUFDLFVBQVUsS0FBSyxRQUFRLEVBQUU7b0JBQy9CLE9BQU8sS0FBSyxDQUFDO2lCQUNkO3FCQUFNOztvQkFDTCxNQUFNLGVBQWUsR0FBRyxtQkFBbUIsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQy9FLElBQUksZUFBZSxFQUFFOzt3QkFFbkIsR0FBRyxDQUFDLG1DQUFtQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO3FCQUMxRDt5QkFBTTs7d0JBRUwsR0FBRyxDQUFDLFNB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cUIsRUFBQztvQkFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQzt5RUFDK0MsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2lCQUNoRztnQkFDRCxNQUFNO1lBQ1I7Z0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyw0REFBNEQsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7U0FDaEc7UUFFRCxPQUFPLElBQUksQ0FBQzs7Q0FFZiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFhtbEN1cnNvclBvcywgWE1MQ3Vyc29yUG9zaXRpb25zIH0gZnJvbSAnLi94bWxDdXJzb3JQb3MuY2xhc3MnO1xyXG5pbXBvcnQgeyBYbWxSdWxlcyB9IGZyb20gJy4uL3htbC1ydWxlcy1jaGVjay94bWxSdWxlcy5jbGFzcyc7XHJcbmltcG9ydCB7IFhtbFRvb2xib3ggfSBmcm9tICcuLi94bWxUb29sYm94LmNsYXNzJztcclxuaW1wb3J0IHsgRG9tRHVtbXlOb2RlTWFuYWdlciB9IGZyb20gJy4uL2R1bW15Tm9kZXMvZG9tRHVtbXlOb2RlTWFuYWdlci5jbGFzcyc7XHJcbmltcG9ydCB7IFhtbDJodG1sIH0gZnJvbSAnLi4veG1sLWh0bWwtY29udmVydGVyL3htbDJodG1sLmNsYXNzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBYbWxDdXJzb3JQb3NNb3ZlciB7XHJcbiAgcHVibGljIHN0YXRpYyBtb3ZlTGVmdChwb3M6IFhtbEN1cnNvclBvcywgcm9vdE5vZGU6IEVsZW1lbnQsIHhtbFJ1bGVzOiBYbWxSdWxlcyk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHBvcyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBzd2l0Y2ggKHBvcy5Qb3NBdE5vZGUpIHtcclxuICAgICAgY2FzZSBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29yT25Db21wbGV0ZU5vZGU6XHJcbiAgICAgICAgLy8gUHV0IGluIGZyb250IG9mIHRoZSBub2RlXHJcbiAgICAgICAgcG9zLlNldEN1cnNvcihwb3MuQWN0dWFsTm9kZSwgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRnJvbnRPZk5vZGUpO1xyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29ySW5Gcm9udE9mTm9kZTpcclxuICAgICAgICBpZiAocG9zLkFjdHVhbE5vZGUgPT09IHJvb3ROb2RlKSB7XHJcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbnN0IHByZXZpb3VzU2libGluZyA9IERvbUR1bW15Tm9kZU1hbmFnZXIuZ2V0UHJldmlvdXNTaWJsaW5nKHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcpIHtcclxuICAgICAgICAgICAgLy8gUHJldmlvdXMgc2libGluZyBub2RlIGV4aXN0c1xyXG4gICAgICAgICAgICBwb3Muc2V0Q3Vyc29ycEJlaGluZE5vZGVGb3JMZWZ0TW92ZW1lbnQocHJldmlvdXNTaWJsaW5nKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIG5vIHByZXZpb3VzIHNpYmxpbmcgbm9kZSBhdmFpbGFibGUgLT4gc2V0IGJlZm9yZSBwYXJlbnQgbm9kZVxyXG4gICAgICAgICAgICBwb3MuU2V0Q3Vyc29yKHBvcy5BY3R1YWxOb2RlLnBhcmVudE5vZGUsIFhNTEN1cnNvclBvc2l0aW9ucy5DdXJzb3JJbkZyb250T2ZOb2RlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFhNTEN1cnNvclBvc2l0aW9ucy5DdXJzb3JCZWhpbmROb2RlOlxyXG4gICAgICAgIHBvcy5zZXRDdXJzb3JwQmVoaW5kTm9kZUZvckxlZnRNb3ZlbWVudChwb3MuQWN0dWFsTm9kZSk7XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFhNTEN1cnNvclBvc2l0aW9ucy5DdXJzb3JJbkVtcHR5Tm9kZTpcclxuICAgICAgICAvLyBQdXQgaW4gZnJvbnQgb2YgdGhlIG5vZGVcclxuICAgICAgICBwb3MuU2V0Q3Vyc29yKHBvcy5BY3R1YWxOb2RlLCBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29ySW5Gcm9udE9mTm9kZSk7XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFhNTEN1cnNvclBvc2l0aW9ucy5DdXJzb3JJbnNpZGVUZXh0Tm9kZTpcclxuICAgICAgICBpZiAoWG1sVG9vbGJveC5Jc1RleHRPckNvbW1lbnROb2RlKHBvcy5BY3R1YWxOb2RlKSkge1xyXG4gICAgICAgICAgLy8gTm9kZSBpcyBUZXh0bm9kZVxyXG4gICAgICAgICAgaWYgKHBvcy5Qb3NJblRleHRub2RlID4gMSkge1xyXG4gICAgICAgICAgICAvLyBDdXJzb3Igb25lIGNoYXJhY3RlciB0byB0aGUgbGVmdFxyXG4gICAgICAgICAgICBwb3MuU2V0Q3Vyc29yKHBvcy5BY3R1YWxOb2RlLCBwb3MuUG9zQXROb2RlLCBwb3MuUG9zSW5UZXh0bm9kZSAtIDEpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gUHV0IGluIGZyb250IG9mIHRoZSBub2RlXHJcbiAgICAgICAgICAgIHBvcy5TZXRDdXJzb3IocG9zLkFjdHVhbE5vZGUsIFhNTEN1cnNvclBvc2l0aW9ucy5DdXJzb3JJbkZyb250T2ZOb2RlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gbm8gVGV4dG5vZGVcclxuICAgICAgICAgIGNvbnN0IGVsZW10ID0gcG9zLkFjdHVhbE5vZGUgYXMgRWxlbWVudDtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgWE1MQ3Vyc29yUG9zLk1vdmVMZWZ0OiBDdXJzb3JQb3MgaXMgWE1MQ3Vyc29yUG9zaXRpb25lbi5DdXJzb3JJbm5lcmhhbGJEZXNUZXh0Tm9kZXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dCBubyB0ZXh0IG5vZGUgaGFzIGJlZW4gY2hvc2VuLCBidXQgdGhlIG5vZGUgJHtlbGVtdCA/IGVsZW10Lm91dGVySFRNTCA6ICcnfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBYTUxDdXJzb3JQb3MuTW92ZUxlZnQ6IHVua25vd24gQ3Vyc29yUG9zICR7cG9zLlBvc0F0Tm9kZX1gKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXRpYyBtb3ZlUmlnaHQocG9zOiBYbWxDdXJzb3JQb3MsIHJvb3ROb2RlOiBFbGVtZW50LCB4bWxSdWxlczogWG1sUnVsZXMpOiBib29sZWFuIHtcclxuICAgIGlmIChwb3MgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgc3dpdGNoIChwb3MuUG9zQXROb2RlKSB7XHJcbiAgICAgIGNhc2UgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvck9uQ29tcGxldGVOb2RlOlxyXG4gICAgICAgIC8vIEhpbnRlciBkZW4gTm9kZSBzZXR6ZW5cclxuICAgICAgICBjb25zdCB0YWdOYW1lID0gWG1sMmh0bWwuZ2V0VGFnTmFtZUZyb21Ob2RlKHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICBjb25zdCBydWxlID0geG1sUnVsZXMucnVsZUVsZW1lbnRzLmdldCh0YWdOYW1lKTtcclxuICAgICAgICBpZiAocnVsZSAmJiBydWxlLmVtcHR5ID09PSB0cnVlKSB7XHJcbiAgICAgICAgICBwb3Muc2V0Q3Vyc29yQmVoaW5kTm9kZUZvckRlZmF1bHRPclJpZ2h0TW92ZW1lbnQocG9zLkFjdHVhbE5vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb25zdCBmaXJzdENoaWxkID0gRG9tRHVtbXlOb2RlTWFuYWdlci5nZXRGaXJzdENoaWxkKHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICAgIGlmIChmaXJzdENoaWxkKSB7XHJcbiAgICAgICAgICAgIHBvcy5TZXRDdXJzb3IoZmlyc3RDaGlsZCwgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRnJvbnRPZk5vZGUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcG9zLlNldEN1cnNvcihwb3MuQWN0dWFsTm9kZSwgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRW1wdHlOb2RlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFhNTEN1cnNvclBvc2l0aW9ucy5DdXJzb3JCZWhpbmROb2RlOlxyXG4gICAgICAgIGNvbnN0IG5leHRTaWJsaW5nID0gRG9tRHVtbXlOb2RlTWFuYWdlci5nZXROZXh0U2libGluZyhwb3MuQWN0dWFsTm9kZSk7XHJcbiAgICAgICAgaWYgKG5leHRTaWJsaW5nKSB7XHJcbiAgICAgICAgICAvLyBjdXJzb3IgYmVoaW5kIG5vZGUgc2hvdWxkIG9ubHkgYmUgc2V0LCB3aGVuIG5vIG90aGVyIHNpYmxpbmdzIGFyZSBmb2xsb3dpbmdcclxuICAgICAgICAgIGNvbnN0IGVsZW10ID0gcG9zLkFjdHVhbE5vZGUgYXMgRWxlbWVudDtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgWE1MQ3Vyc29yUG9zLk1vdmVSaWdodDogY3Vyc29yIGJlaGluZCBub2RlIHNob3VsZCBvbmx5IGJlIHNldCwgd2hlbiBubyBvdGhlciBzaWJsaW5ncyBhcmUgZm9sbG93aW5nICR7ZWxlbXQgPyBlbGVtdC5vdXRlckhUTUwgOiAnJ31gKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gTm8gZm9sbG93aW5nIHNpYmxpbmdzIHByZXNlbnQsIHRoZW4gc2V0IGFmdGVyIHBhcmVudCBub2RlXHJcbiAgICAgICAgICBjb25zdCBwYXJlbnROZXh0U2libGluZyA9IERvbUR1bW15Tm9kZU1hbmFnZXIuZ2V0TmV4dFNpYmxpbmcocG9zLkFjdHVhbE5vZGUucGFyZW50RWxlbWVudCk7XHJcbiAgICAgICAgICBpZiAocGFyZW50TmV4dFNpYmxpbmcpIHtcclxuICAgICAgICAgICAgcG9zLlNldEN1cnNvcihwYXJlbnROZXh0U2libGluZywgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRnJvbnRPZk5vZGUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcG9zLlNldEN1cnNvcihwb3MuQWN0dWFsTm9kZS5wYXJlbnRFbGVtZW50LCBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29yQmVoaW5kTm9kZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29ySW5FbXB0eU5vZGU6XHJcbiAgICAgICAgLy8gUGxhY2UgYmVoaW5kIHRoZSBub2RlXHJcbiAgICAgICAgcG9zLnNldEN1cnNvckJlaGluZE5vZGVGb3JEZWZhdWx0T3JSaWdodE1vdmVtZW50KHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRnJvbnRPZk5vZGU6XHJcbiAgICAgICAgaWYgKFhtbFRvb2xib3guSXNUZXh0T3JDb21tZW50Tm9kZShwb3MuQWN0dWFsTm9kZSkpIHtcclxuICAgICAgICAgIC8vIE5vZGUgaXMgVGV4dG5vZGVcclxuICAgICAgICAgIGlmICgocG9zLkFjdHVhbE5vZGUgYXMgRWxlbWVudCkudGV4dENvbnRlbnQubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICAvLyBUZXh0bm9kZSBpcyBub3QgZW1wdHlcclxuICAgICAgICAgICAgcG9zLlNldEN1cnNvcihwb3MuQWN0dWFsTm9kZSwgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluc2lkZVRleHROb2RlLCAxKTsgLy8gb25lIGNoYXJhY3RlciBmb3J3YXJkLCBiZWhpbmQgdGhlIGZpcnN0IGNoYXJhY3RlclxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gVGV4dG5vZGUgaXMgZW1wdHlcclxuICAgICAgICAgICAgLy8gcHV0IGJlaGluZCB0aGUgbm9kZVxyXG4gICAgICAgICAgICBwb3MuU2V0Q3Vyc29yKHBvcy5BY3R1YWxOb2RlLCBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29yQmVoaW5kTm9kZSk7XHJcbiAgICAgICAgICAgIC8vIEJlY2F1c2UgXCJDdXJzb3JCZWhpbmROb2RlXCIgaXMgbm90IGF0dHJhY3RpdmUsIG9uZSBtb3JlIHN0ZXBcclxuICAgICAgICAgICAgdGhpcy5tb3ZlUmlnaHQocG9zLCByb290Tm9kZSwgeG1sUnVsZXMpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBOb2RlIGlzIG5vdCBUZXh0bm9kZVxyXG4gICAgICAgICAgY29uc3QgY2hpbGROb2RlQ291bnQgPSBEb21EdW1teU5vZGVNYW5hZ2VyLmdldENoaWxkTm9kZUNvdW50KHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICAgIGlmIChjaGlsZE5vZGVDb3VudCA9PT0gMCkge1xyXG4gICAgICAgICAgICAvLyBubyBDaGlsZHJlbiBleGlzdGluZ1xyXG4gICAgICAgICAgICBpZiAoWG1sMmh0bWwuaXNOb0Nsb3NpbmdFbGVtZW50KHBvcy5BY3R1YWxOb2RlKSkge1xyXG4gICAgICAgICAgICAgIC8vIElmIG5vIGNsb3NlZCB0YWcgaXMgZGlzcGxheWVkIGZvciB0aGlzIG5vZGUsIHRoZW4gZGlyZWN0bHkgYmVoaW5kIHRoZSBub2RlXHJcbiAgICAgICAgICAgICAgLy8gUGxhY2UgYmVoaW5kIHRoZSBub2RlXHJcbiAgICAgICAgICAgICAgcG9zLnNldEN1cnNvckJlaGluZE5vZGVGb3JEZWZhdWx0T3JSaWdodE1vdmVtZW50KHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAvLyBOb2RlIGhhcyBjbG9zaW5nIHRhZywgc28gcHV0IGluIGJldHdlZW5cclxuICAgICAgICAgICAgICAvLyBQbGFjZSBpbiBlbXB0eSBub2RlXHJcbiAgICAgICAgICAgICAgcG9zLlNldEN1cnNvcihwb3MuQWN0dWFsTm9kZSwgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRW1wdHlOb2RlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gQ2hpbGRyZW4gZXhpc3RpbmdcclxuICAgICAgICAgICAgY29uc3QgZmlyc3RDaGlsZCA9IERvbUR1bW15Tm9kZU1hbmFnZXIuZ2V0Rmlyc3RDaGlsZChwb3MuQWN0dWFsTm9kZSk7XHJcbiAgICAgICAgICAgIHBvcy5TZXRDdXJzb3IoZmlyc3RDaGlsZCwgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluRnJvbnRPZk5vZGUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgWE1MQ3Vyc29yUG9zaXRpb25zLkN1cnNvckluc2lkZVRleHROb2RlOlxyXG4gICAgICAgIGlmIChYbWxUb29sYm94LklzVGV4dE9yQ29tbWVudE5vZGUocG9zLkFjdHVhbE5vZGUpKSB7XHJcbiAgICAgICAgICAvLyBOb2RlIGlzIFRleHRub2RlXHJcbiAgICAgICAgICBpZiAoKHBvcy5BY3R1YWxOb2RlIGFzIEVsZW1lbnQpLnRleHRDb250ZW50Lmxlbmd0aCA+IHBvcy5Qb3NJblRleHRub2RlICsgMSkge1xyXG4gICAgICAgICAgICAvLyB0aGVyZSBpcyBzdGlsbCB0ZXh0IGluIHRoZSByaWdodCBvZiB0aGUgdGV4dG5vZGVcclxuICAgICAgICAgICAgLy8gc3RlcCBvbmUgY2hhcmFjdGVyIGZvcndhcmRzOiBiZWhpbmQgdGhlIGZpcnN0IGNoYXJcclxuICAgICAgICAgICAgcG9zLlNldEN1cnNvcihwb3MuQWN0dWFsTm9kZSwgcG9zLlBvc0F0Tm9kZSwgcG9zLlBvc0luVGV4dG5vZGUgKyAxKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIG5vIHRleHQgYWZ0ZXIgdGhlIHRleHRub2RlXHJcbiAgICAgICAgICAgIC8vIHBsYWNlIGN1cnNvciBiZWhpbmQgdGhlIG5vZGVcclxuICAgICAgICAgICAgcG9zLnNldEN1cnNvckJlaGluZE5vZGVGb3JEZWZhdWx0T3JSaWdodE1vdmVtZW50KHBvcy5BY3R1YWxOb2RlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gTm9kZSBpcyBubyBUZXh0bm9kZVxyXG4gICAgICAgICAgY29uc3QgZWxlbXQgPSBwb3MuQWN0dWFsTm9kZSBhcyBFbGVtZW50O1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBYTUxDdXJzb3JQb3MuTW92ZVJpZ2h0OiBDdXJzb3JQb3MgaXMgWE1MQ3Vyc29yUG9zaXRpb25lbi5DdXJzb3JJbm5lcmhhbGJEZXNUZXh0Tm9kZXMsIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBidXQgbm8gdGV4dCBub2RlIGhhcyBiZWVuIGNob3NlbiwgYnV0IHRoZSBub2RlICR7ZWxlbXQgPyBlbGVtdC5vdXRlckhUTUwgOiAnJ31gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdHJpbmcuRm9ybWF0KFwiWE1MQ3Vyc29yUG9zLk1vdmVSaWdodDogdW5rbm93biBDdXJzb3JQb3MgJHtwb3MuUG9zQXROb2RlfWApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxufVxyXG4iXX0=