@ngx-i18nsupport/ngx-i18nsupport-lib
Version:
A Typescript library to work with Angular generated i18n files (xliff, xmb)
437 lines • 42.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
/**
* An XmlSerializer that supports formatting.
* Original code is based on [xmldom](https://www.npmjs.com/package/xmldom)
* It is extended to support formatting including handling of elements with mixed content.
* Example formatted output:
* <pre>
* <doc>
* <element>An element with
* <b>mixed</b>
* content
* </element>
* </doc>
* </pre>
* Same when "element" is indicated as "mixedContentElement":
* <pre>
* <doc>
* <element>An element with <b>mixed</b> content</element>
* </doc>
* </pre>
*/
/**
* @record
*/
function Namespace() { }
if (false) {
/** @type {?} */
Namespace.prototype.prefix;
/** @type {?} */
Namespace.prototype.namespace;
}
/**
* Options used to control the formatting
* @record
*/
export function XmlSerializerOptions() { }
if (false) {
/** @type {?|undefined} */
XmlSerializerOptions.prototype.beautify;
/** @type {?|undefined} */
XmlSerializerOptions.prototype.indentString;
/** @type {?|undefined} */
XmlSerializerOptions.prototype.mixedContentElements;
}
/** @type {?} */
var DEFAULT_INDENT_STRING = ' ';
var XmlSerializer = /** @class */ (function () {
function XmlSerializer() {
}
/**
* Serialze xml document to string.
* @param document the document
* @param options can be used to activate beautifying.
*/
/**
* Serialze xml document to string.
* @param {?} document the document
* @param {?=} options can be used to activate beautifying.
* @return {?}
*/
XmlSerializer.prototype.serializeToString = /**
* Serialze xml document to string.
* @param {?} document the document
* @param {?=} options can be used to activate beautifying.
* @return {?}
*/
function (document, options) {
/** @type {?} */
var buf = [];
/** @type {?} */
var visibleNamespaces = [];
/** @type {?} */
var refNode = document.documentElement;
/** @type {?} */
var prefix = refNode.prefix;
/** @type {?} */
var uri = refNode.namespaceURI;
if (uri && prefix == null) {
prefix = refNode.lookupPrefix(uri);
if (prefix == null) {
visibleNamespaces = [
{ namespace: uri, prefix: null }
// {namespace:uri,prefix:''}
];
}
}
if (!options) {
options = {};
}
if (options.indentString) {
if (!this.containsOnlyWhiteSpace(options.indentString)) {
throw new Error('indentString must not contain non white characters');
}
}
this.doSerializeToString(document, options, buf, 0, false, visibleNamespaces);
return buf.join('');
};
/**
* Main format method that does all the work.
* Outputs a node to the outputbuffer.
* @param node the node to be formatted.
* @param options options
* @param buf outputbuffer, new output will be appended to this array.
* @param indentLevel Lever of indentation for formatted output.
* @param partOfMixedContent true, if node is a subelement of an element containind mixed content.
* @param visibleNamespaces visibleNamespaces
*/
/**
* Main format method that does all the work.
* Outputs a node to the outputbuffer.
* @private
* @param {?} node the node to be formatted.
* @param {?} options options
* @param {?} buf outputbuffer, new output will be appended to this array.
* @param {?} indentLevel Lever of indentation for formatted output.
* @param {?} partOfMixedContent true, if node is a subelement of an element containind mixed content.
* @param {?} visibleNamespaces visibleNamespaces
* @return {?}
*/
XmlSerializer.prototype.doSerializeToString = /**
* Main format method that does all the work.
* Outputs a node to the outputbuffer.
* @private
* @param {?} node the node to be formatted.
* @param {?} options options
* @param {?} buf outputbuffer, new output will be appended to this array.
* @param {?} indentLevel Lever of indentation for formatted output.
* @param {?} partOfMixedContent true, if node is a subelement of an element containind mixed content.
* @param {?} visibleNamespaces visibleNamespaces
* @return {?}
*/
function (node, options, buf, indentLevel, partOfMixedContent, visibleNamespaces) {
/** @type {?} */
var child;
switch (node.nodeType) {
case node.ELEMENT_NODE:
/** @type {?} */
var elementNode = (/** @type {?} */ (node));
/** @type {?} */
var attrs = elementNode.attributes;
/** @type {?} */
var len = attrs.length;
child = elementNode.firstChild;
/** @type {?} */
var nodeName = elementNode.tagName;
/** @type {?} */
var elementHasMixedContent = this.isMixedContentElement(nodeName, options);
if (partOfMixedContent) {
buf.push('<', nodeName);
}
else {
this.outputIndented(options, buf, indentLevel, '<', nodeName);
}
for (var i = 0; i < len; i++) {
// add namespaces for attributes
/** @type {?} */
var attr = attrs.item(i);
if (attr.prefix === 'xmlns') {
visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
}
else if (attr.nodeName === 'xmlns') {
visibleNamespaces.push({ prefix: '', namespace: attr.value });
}
}
for (var i = 0; i < len; i++) {
/** @type {?} */
var attr = attrs.item(i);
if (this.needNamespaceDefine(attr, visibleNamespaces)) {
/** @type {?} */
var prefix = attr.prefix || '';
/** @type {?} */
var uri = attr.namespaceURI;
/** @type {?} */
var ns = prefix ? ' xmlns:' + prefix : ' xmlns';
buf.push(ns, '="', uri, '"');
visibleNamespaces.push({ prefix: prefix, namespace: uri });
}
this.doSerializeToString(attr, options, buf, indentLevel, false, visibleNamespaces);
}
// add namespace for current node
if (this.needNamespaceDefine(elementNode, visibleNamespaces)) {
/** @type {?} */
var prefix = elementNode.prefix || '';
/** @type {?} */
var uri = node.namespaceURI;
/** @type {?} */
var ns = prefix ? ' xmlns:' + prefix : ' xmlns';
buf.push(ns, '="', uri, '"');
visibleNamespaces.push({ prefix: prefix, namespace: uri });
}
if (child) {
buf.push('>');
// if is cdata child node
/** @type {?} */
var hasComplexContent = false;
while (child) {
if (child.nodeType === child.ELEMENT_NODE) {
hasComplexContent = true;
}
this.doSerializeToString(child, options, buf, indentLevel + 1, partOfMixedContent || elementHasMixedContent, visibleNamespaces);
child = child.nextSibling;
}
if (!partOfMixedContent && !elementHasMixedContent && hasComplexContent) {
this.outputIndented(options, buf, indentLevel, '</', nodeName, '>');
}
else {
buf.push('</', nodeName, '>');
}
}
else {
buf.push('/>');
}
return;
case node.DOCUMENT_NODE:
case node.DOCUMENT_FRAGMENT_NODE:
child = node.firstChild;
while (child) {
this.doSerializeToString(child, options, buf, indentLevel, false, visibleNamespaces);
child = child.nextSibling;
}
return;
case node.ATTRIBUTE_NODE:
/** @type {?} */
var attrNode = (/** @type {?} */ (node));
return buf.push(' ', attrNode.name, '="', attrNode.value.replace(/[<&"]/g, this._xmlEncoder), '"');
case node.TEXT_NODE:
/** @type {?} */
var textNode = (/** @type {?} */ (node));
if (!options.beautify || partOfMixedContent || !this.containsOnlyWhiteSpace(textNode.data)) {
return buf.push(textNode.data.replace(/[<&]/g, this._xmlEncoder));
}
return;
case node.CDATA_SECTION_NODE:
/** @type {?} */
var cdatasectionNode = (/** @type {?} */ (node));
return buf.push('<![CDATA[', cdatasectionNode.data, ']]>');
case node.COMMENT_NODE:
/** @type {?} */
var commentNode = (/** @type {?} */ (node));
return buf.push('<!--', commentNode.data, '-->');
case node.DOCUMENT_TYPE_NODE:
/** @type {?} */
var documenttypeNode = (/** @type {?} */ (node));
/** @type {?} */
var pubid = documenttypeNode.publicId;
/** @type {?} */
var sysid = documenttypeNode.systemId;
buf.push('<!DOCTYPE ', documenttypeNode.name);
if (pubid) {
buf.push(' PUBLIC "', pubid);
if (sysid && sysid !== '.') {
buf.push('" "', sysid);
}
buf.push('">');
}
else if (sysid && sysid !== '.') {
buf.push(' SYSTEM "', sysid, '">');
}
else {
buf.push('>');
}
return;
case node.PROCESSING_INSTRUCTION_NODE:
/** @type {?} */
var piNode = (/** @type {?} */ (node));
return buf.push('<?', piNode.target, ' ', piNode.data, '?>');
case node.ENTITY_REFERENCE_NODE:
return buf.push('&', node.nodeName, ';');
// case ENTITY_NODE:
// case NOTATION_NODE:
default:
buf.push('??', node.nodeName);
}
};
/**
* @private
* @param {?} node
* @param {?} visibleNamespaces
* @return {?}
*/
XmlSerializer.prototype.needNamespaceDefine = /**
* @private
* @param {?} node
* @param {?} visibleNamespaces
* @return {?}
*/
function (node, visibleNamespaces) {
/** @type {?} */
var prefix = node.prefix || '';
/** @type {?} */
var uri = node.namespaceURI;
if (!prefix && !uri) {
return false;
}
if (prefix === 'xml' && uri === 'http://www.w3.org/XML/1998/namespace'
|| uri === 'http://www.w3.org/2000/xmlns/') {
return false;
}
/** @type {?} */
var i = visibleNamespaces.length;
while (i--) {
/** @type {?} */
var ns = visibleNamespaces[i];
// get namespace prefix
if (ns.prefix === prefix) {
return ns.namespace !== uri;
}
}
return true;
};
/**
* @private
* @param {?} c
* @return {?}
*/
XmlSerializer.prototype._xmlEncoder = /**
* @private
* @param {?} c
* @return {?}
*/
function (c) {
return c === '<' && '<' ||
c === '>' && '>' ||
c === '&' && '&' ||
c === '"' && '"' ||
'&#' + c.charCodeAt(0) + ';';
};
/**
* @private
* @param {?} options
* @param {?} buf
* @param {?} indentLevel
* @param {...?} outputParts
* @return {?}
*/
XmlSerializer.prototype.outputIndented = /**
* @private
* @param {?} options
* @param {?} buf
* @param {?} indentLevel
* @param {...?} outputParts
* @return {?}
*/
function (options, buf, indentLevel) {
var outputParts = [];
for (var _i = 3; _i < arguments.length; _i++) {
outputParts[_i - 3] = arguments[_i];
}
if (options.beautify) {
buf.push('\n');
if (indentLevel > 0) {
buf.push(this.indentationString(options, indentLevel));
}
}
buf.push.apply(buf, tslib_1.__spread(outputParts));
};
/**
* @private
* @param {?} options
* @param {?} indentLevel
* @return {?}
*/
XmlSerializer.prototype.indentationString = /**
* @private
* @param {?} options
* @param {?} indentLevel
* @return {?}
*/
function (options, indentLevel) {
/** @type {?} */
var indent = (options.indentString) ? options.indentString : DEFAULT_INDENT_STRING;
/** @type {?} */
var result = '';
for (var i = 0; i < indentLevel; i++) {
result = result + indent;
}
return result;
};
/**
* Test, wether tagName is an element containing mixed content.
* @param tagName tagName
* @param options options
*/
/**
* Test, wether tagName is an element containing mixed content.
* @private
* @param {?} tagName tagName
* @param {?} options options
* @return {?}
*/
XmlSerializer.prototype.isMixedContentElement = /**
* Test, wether tagName is an element containing mixed content.
* @private
* @param {?} tagName tagName
* @param {?} options options
* @return {?}
*/
function (tagName, options) {
if (options && options.mixedContentElements) {
return !!options.mixedContentElements.find((/**
* @param {?} tag
* @return {?}
*/
function (tag) { return tag === tagName; }));
}
else {
return false;
}
};
/**
* @private
* @param {?} text
* @return {?}
*/
XmlSerializer.prototype.containsOnlyWhiteSpace = /**
* @private
* @param {?} text
* @return {?}
*/
function (text) {
for (var i = 0; i < text.length; i++) {
/** @type {?} */
var c = text.charAt(i);
if (!(c === ' ' || c === '\t' || c === '\r' || c === '\n')) {
return false;
}
}
return true;
};
return XmlSerializer;
}());
export { XmlSerializer };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1sLXNlcmlhbGl6ZXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LWkxOG5zdXBwb3J0L25neC1pMThuc3VwcG9ydC1saWIvIiwic291cmNlcyI6WyJpbXBsL3htbC1zZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFxQkEsd0JBR0M7OztJQUZHLDJCQUFlOztJQUNmLDhCQUFrQjs7Ozs7O0FBTXRCLDBDQUlDOzs7SUFIRyx3Q0FBbUI7O0lBQ25CLDRDQUFzQjs7SUFDdEIsb0RBQWdDOzs7SUFHOUIscUJBQXFCLEdBQUcsSUFBSTtBQUVsQztJQUVJO0lBRUEsQ0FBQztJQUVEOzs7O09BSUc7Ozs7Ozs7SUFDSCx5Q0FBaUI7Ozs7OztJQUFqQixVQUFrQixRQUFrQixFQUFFLE9BQThCOztZQUMxRCxHQUFHLEdBQUcsRUFBRTs7WUFDVixpQkFBaUIsR0FBZ0IsRUFBRTs7WUFDakMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxlQUFlOztZQUNwQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU07O1lBQ3JCLEdBQUcsR0FBRyxPQUFPLENBQUMsWUFBWTtRQUVoQyxJQUFJLEdBQUcsSUFBSSxNQUFNLElBQUksSUFBSSxFQUFFO1lBQ3ZCLE1BQU0sR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25DLElBQUksTUFBTSxJQUFJLElBQUksRUFBRTtnQkFDaEIsaUJBQWlCLEdBQUc7b0JBQ2hCLEVBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDO29CQUM5Qiw0QkFBNEI7aUJBQy9CLENBQUM7YUFDTDtTQUNKO1FBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNWLE9BQU8sR0FBRyxFQUFFLENBQUM7U0FDaEI7UUFDRCxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUU7WUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMs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LE1BQU0sR0FBRyxNQUFNLENBQUM7U0FDNUI7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNsQixDQUFDO0lBRUQ7Ozs7T0FJRzs7Ozs7Ozs7SUFDSyw2Q0FBcUI7Ozs7Ozs7SUFBN0IsVUFBOEIsT0FBZSxFQUFFLE9BQTZCO1FBQ3hFLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxvQkFBb0IsRUFBRTtZQUN6QyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSTs7OztZQUFDLFVBQUMsR0FBRyxJQUFLLE9BQUEsR0FBRyxLQUFLLE9BQU8sRUFBZixDQUFlLEVBQUMsQ0FBQztTQUN4RTthQUFNO1lBQ0gsT0FBTyxLQUFLLENBQUM7U0FDaEI7SUFDTCxDQUFDOzs7Ozs7SUFFTyw4Q0FBc0I7Ozs7O0lBQTlCLFVBQStCLElBQVk7UUFDdkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O2dCQUM1QixDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxFQUFFO2dCQUN4RCxPQUFPLEtBQUssQ0FBQzthQUNoQjtTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNMLG9CQUFDO0FBQUQsQ0FBQyxBQS9PRCxJQStPQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBBbiBYbWxTZXJpYWxpemVyIHRoYXQgc3VwcG9ydHMgZm9ybWF0dGluZy5cclxuICogT3JpZ2luYWwgY29kZSBpcyBiYXNlZCBvbiBbeG1sZG9tXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS94bWxkb20pXHJcbiAqIEl0IGlzIGV4dGVuZGVkIHRvIHN1cHBvcnQgZm9ybWF0dGluZyBpbmNsdWRpbmcgaGFuZGxpbmcgb2YgZWxlbWVudHMgd2l0aCBtaXhlZCBjb250ZW50LlxyXG4gKiBFeGFtcGxlIGZvcm1hdHRlZCBvdXRwdXQ6XHJcbiAqIDxwcmU+XHJcbiAqICAgICA8ZG9jPlxyXG4gKiAgICAgICAgIDxlbGVtZW50PkFuIGVsZW1lbnQgd2l0aFxyXG4gKiAgICAgICAgICAgICA8Yj5taXhlZDwvYj5cclxuICogICAgICAgICAgICAgIGNvbnRlbnRcclxuICogICAgICAgICA8L2VsZW1lbnQ+XHJcbiAqICAgICA8L2RvYz5cclxuICogPC9wcmU+XHJcbiAqIFNhbWUgd2hlbiBcImVsZW1lbnRcIiBpcyBpbmRpY2F0ZWQgYXMgXCJtaXhlZENvbnRlbnRFbGVtZW50XCI6XHJcbiAqIDxwcmU+XHJcbiAqICAgICA8ZG9jPlxyXG4gKiAgICAgICAgIDxlbGVtZW50PkFuIGVsZW1lbnQgd2l0aCA8Yj5taXhlZDwvYj4gY29udGVudDwvZWxlbWVudD5cclxuICogICAgIDwvZG9jPlxyXG4gKiA8L3ByZT5cclxuICovXHJcblxyXG5pbnRlcmZhY2UgTmFtZXNwYWNlIHtcclxuICAgIHByZWZpeDogc3RyaW5nO1xyXG4gICAgbmFtZXNwYWNlOiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPcHRpb25zIHVzZWQgdG8gY29udHJvbCB0aGUgZm9ybWF0dGluZ1xyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBYbWxTZXJpYWxpemVyT3B0aW9ucyB7XHJcbiAgICBiZWF1dGlmeT86IGJvb2xlYW47IC8vIHNldCB0byBhY3RpdmF0ZSBiZWF1dGlmeVxyXG4gICAgaW5kZW50U3RyaW5nPzogc3RyaW5nOyAvLyBTZXF1ZW5jZSB1c2VzIGZvciBpbmRlbnRhdGlvbiwgbXVzdCBvbmx5IGNvbnRhaW4gd2hpdGUgc3BhY2UgY2hhcnMsIGUuZy4gXCIgIFwiIG9yIFwiICAgIFwiIG9yIFwiXFx0XCJcclxuICAgIG1peGVkQ29udGVudEVsZW1lbnRzPzogc3RyaW5nW107IC8vIE5hbWVzIG9mIGVsZW1lbnRzIGNvbnRhaW5pbmcgbWl4ZWQgY29udGVudCAodGhlc2UgYXJlIG5vdCBiZWF1dGlmaWVkKVxyXG59XHJcblxyXG5jb25zdCBERUZBVUxUX0lOREVOVF9TVFJJTkcgPSAnICAnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFhtbFNlcmlhbGl6ZXIge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlcmlhbHplIHhtbCBkb2N1bWVudCB0byBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0gZG9jdW1lbnQgdGhlIGRvY3VtZW50XHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBjYW4gYmUgdXNlZCB0byBhY3RpdmF0ZSBiZWF1dGlmeWluZy5cclxuICAgICAqL1xyXG4gICAgc2VyaWFsaXplVG9TdHJpbmcoZG9jdW1lbnQ6IERvY3VtZW50LCBvcHRpb25zPzogWG1sU2VyaWFsaXplck9wdGlvbnMpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGJ1ZiA9IFtdO1xyXG4gICAgICAgIGxldCB2aXNpYmxlTmFtZXNwYWNlczogTmFtZXNwYWNlW10gPSBbXTtcclxuICAgICAgICBjb25zdCByZWZOb2RlID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xyXG4gICAgICAgIGxldCBwcmVmaXggPSByZWZOb2RlLnByZWZpeDtcclxuICAgICAgICBjb25zdCB1cmkgPSByZWZOb2RlLm5hbWVzcGFjZVVSSTtcclxuXHJcbiAgICAgICAgaWYgKHVyaSAmJiBwcmVmaXggPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBwcmVmaXggPSByZWZOb2RlLmxvb2t1cFByZWZpeCh1cmkpO1xyXG4gICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHZpc2libGVOYW1lc3BhY2VzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgIHtuYW1lc3BhY2U6IHVyaSwgcHJlZml4OiBudWxsfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHtuYW1lc3BhY2U6dXJpLHByZWZpeDonJ31cclxuICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG9wdGlvbnMuaW5kZW50U3RyaW5nKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250YWluc09ubHlXaGl0ZVNwYWNlKG9wdGlvbnMuaW5kZW50U3RyaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbmRlbnRTdHJpbmcgbXVzdCBub3QgY29udGFpbiBub24gd2hpdGUgY2hhcmFjdGVycycpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZG9TZXJpYWxpemVUb1N0cmluZyhkb2N1bWVudCwgb3B0aW9ucywgYnVmLCAwLCBmYWxzZSwgdmlzaWJsZU5hbWVzcGFjZXMpO1xyXG4gICAgICAgIHJldHVybiBidWYuam9pbignJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYWluIGZvcm1hdCBtZXRob2QgdGhhdCBkb2VzIGFsbCB0aGUgd29yay5cclxuICAgICAqIE91dHB1dHMgYSBub2RlIHRvIHRoZSBvdXRwdXRidWZmZXIuXHJcbiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSB0byBiZSBmb3JtYXR0ZWQuXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBvcHRpb25zXHJcbiAgICAgKiBAcGFyYW0gYnVmIG91dHB1dGJ1ZmZlciwgbmV3IG91dHB1dCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoaXMgYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0gaW5kZW50TGV2ZWwgTGV2ZXIgb2YgaW5kZW50YXRpb24gZm9yIGZvcm1hdHRlZCBvdXRwdXQuXHJcbiAgICAgKiBAcGFyYW0gcGFydE9mTWl4ZWRDb250ZW50IHRydWUsIGlmIG5vZGUgaXMgYSBzdWJlbGVtZW50IG9mIGFuIGVsZW1lbnQgY29udGFpbmluZCBtaXhlZCBjb250ZW50LlxyXG4gICAgICogQHBhcmFtIHZpc2libGVOYW1lc3BhY2VzIHZpc2libGVOYW1lc3BhY2VzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZG9TZXJpYWxpemVUb1N0cmluZyhub2RlOiBOb2RlLCBvcHRpb25zOiBYbWxTZXJpYWxpemVyT3B0aW9ucywgYnVmOiBzdHJpbmdbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRlbnRMZXZlbDogbnVtYmVyLCBwYXJ0T2ZNaXhlZENvbnRlbnQ6IGJvb2xlYW4sIHZpc2libGVOYW1lc3BhY2VzOiBOYW1lc3BhY2VbXSkge1xyXG4gICAgICAgIGxldCBjaGlsZDogTm9kZTtcclxuICAgICAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBub2RlLkVMRU1FTlRfTk9ERTpcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnROb2RlOiBFbGVtZW50ID0gPEVsZW1lbnQ+IG5vZGU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRycyA9IGVsZW1lbnROb2RlLmF0dHJpYnV0ZXM7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBsZW4gPSBhdHRycy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGVsZW1lbnROb2RlLmZpcnN0Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlTmFtZSA9IGVsZW1lbnROb2RlLnRhZ05hbWU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50SGFzTWl4ZWRDb250ZW50ID0gdGhpcy5pc01peGVkQ29udGVudEVsZW1lbnQobm9kZU5hbWUsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcnRPZk1peGVkQ29udGVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1Zi5wdXNoKCc8JyAsIG5vZGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRJbmRlbnRlZChvcHRpb25zLCBidWYsIGluZGVudExldmVsLCAnPCcgLCBub2RlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCBuYW1lc3BhY2VzIGZvciBhdHRyaWJ1dGVzXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXR0ciA9IGF0dHJzLml0ZW0oaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHIucHJlZml4ID09PSAneG1sbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2libGVOYW1lc3BhY2VzLnB1c2goe3ByZWZpeDogYXR0ci5sb2NhbE5hbWUsIG5hbWVzcGFjZTogYXR0ci52YWx1ZX0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0ci5ub2RlTmFtZSA9PT0gJ3htbG5zJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmxlTmFtZXNwYWNlcy5wdXNoKHtwcmVmaXg6ICcnLCBuYW1lc3BhY2U6IGF0dHIudmFsdWV9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXR0ciA9IGF0dHJzLml0ZW0oaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubmVlZE5hbWVzcGFjZURlZmluZShhdHRyLCB2aXNpYmxlTmFtZXNwYWNlcykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJlZml4ID0gYXR0ci5wcmVmaXggfHwgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVyaSA9IGF0dHIubmFtZXNwYWNlVVJJO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBucyA9IHByZWZpeCA/ICcgeG1sbnM6JyArIHByZWZpeCA6ICcgeG1sbnMnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBidWYucHVzaChucywgJz1cIicsIHVyaSwgJ1wiJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2libGVOYW1lc3BhY2VzLnB1c2goe3ByZWZpeDogcHJlZml4LCBuYW1lc3BhY2U6IHVyaX0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvU2VyaWFsaXplVG9TdHJpbmcoYXR0ciwgb3B0aW9ucywgYnVmLCBpbmRlbnRMZXZlbCwgZmFsc2UsIHZpc2libGVOYW1lc3BhY2VzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGFkZCBuYW1lc3BhY2UgZm9yIGN1cnJlbnQgbm9kZVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubmVlZE5hbWVzcGFjZURlZmluZShlbGVtZW50Tm9kZSwgdmlzaWJsZU5hbWVzcGFjZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJlZml4ID0gZWxlbWVudE5vZGUucHJlZml4IHx8ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVyaSA9IG5vZGUubmFtZXNwYWNlVVJJO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5zID0gcHJlZml4ID8gJyB4bWxuczonICsgcHJlZml4IDogJyB4bWxucyc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2gobnMsICc9XCInLCB1cmksICdcIicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZpc2libGVOYW1lc3BhY2VzLnB1c2goe3ByZWZpeDogcHJlZml4LCBuYW1lc3BhY2U6IHVyaX0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1Zi5wdXNoKCc+Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgaXMgY2RhdGEgY2hpbGQgbm9kZVxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBoYXNDb21wbGV4Q29udGVudCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IGNoaWxkLkVMRU1FTlRfTk9ERSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzQ29tcGxleENvbnRlbnQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9TZXJpYWxpemVUb1N0cmluZyhjaGlsZCwgb3B0aW9ucywgYnVmLCBpbmRlbnRMZXZlbCArIDEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0T2ZNaXhlZENvbnRlbnQgfHwgZWxlbWVudEhhc01peGVkQ29udGVudCwgdmlzaWJsZU5hbWVzcGFjZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcnRPZk1peGVkQ29udGVudCAmJiAhZWxlbWVudEhhc01peGVkQ29udGVudCAmJiBoYXNDb21wbGV4Q29udGVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEluZGVudGVkKG9wdGlvbnMsIGJ1ZiwgaW5kZW50TGV2ZWwsICc8LycsIG5vZGVOYW1lLCAnPicpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5wdXNoKCc8LycsIG5vZGVOYW1lLCAnPicpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJy8+Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIGNhc2Ugbm9kZS5ET0NVTUVOVF9OT0RFOlxyXG4gICAgICAgICAgICBjYXNlIG5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERTpcclxuICAgICAgICAgICAgICAgIGNoaWxkID0gbm9kZS5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb1NlcmlhbGl6ZVRvU3RyaW5nKGNoaWxkLCBvcHRpb25zLCBidWYsIGluZGVudExldmVsLCBmYWxzZSwgdmlzaWJsZU5hbWVzcGFjZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIGNhc2Ugbm9kZS5BVFRSSUJVVEVfTk9ERTpcclxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJOb2RlID0gPEF0dHI+IG5vZGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmLnB1c2goJyAnLCBhdHRyTm9kZS5uYW1lLCAnPVwiJywgYXR0ck5vZGUudmFsdWUucmVwbGFjZSgvWzwmXCJdL2csIHRoaXMuX3htbEVuY29kZXIpLCAnXCInKTtcclxuICAgICAgICAgICAgY2FzZSBub2RlLlRFWFRfTk9ERTpcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRleHROb2RlID0gPFRleHQ+IG5vZGU7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMuYmVhdXRpZnkgfHwgcGFydE9mTWl4ZWRDb250ZW50IHx8ICF0aGlzLmNvbnRhaW5zT25seVdoaXRlU3BhY2UodGV4dE5vZGUuZGF0YSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnVmLnB1c2godGV4dE5vZGUuZGF0YS5yZXBsYWNlKC9bPCZdL2csIHRoaXMuX3htbEVuY29kZXIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgY2FzZSBub2RlLkNEQVRBX1NFQ1RJT05fTk9ERTpcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNkYXRhc2VjdGlvbk5vZGUgPSA8Q0RBVEFTZWN0aW9uPiBub2RlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1Zi5wdXNoKCc8IVtDREFUQVsnLCBjZGF0YXNlY3Rpb25Ob2RlLmRhdGEsICddXT4nKTtcclxuICAgICAgICAgICAgY2FzZSBub2RlLkNPTU1FTlRfTk9ERTpcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbW1lbnROb2RlID0gPENvbW1lbnQ+IG5vZGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmLnB1c2goJzwhLS0nLCBjb21tZW50Tm9kZS5kYXRhLCAnLS0+Jyk7XHJcbiAgICAgICAgICAgIGNhc2Ugbm9kZS5ET0NVTUVOVF9UWVBFX05PREU6XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkb2N1bWVudHR5cGVOb2RlID0gPERvY3VtZW50VHlwZT4gbm9kZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHB1YmlkID0gZG9jdW1lbnR0eXBlTm9kZS5wdWJsaWNJZDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN5c2lkID0gZG9jdW1lbnR0eXBlTm9kZS5zeXN0ZW1JZDtcclxuICAgICAgICAgICAgICAgIGJ1Zi5wdXNoKCc8IURPQ1RZUEUgJywgZG9jdW1lbnR0eXBlTm9kZS5uYW1lKTtcclxuICAgICAgICAgICAgICAgIGlmIChwdWJpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1Zi5wdXNoKCcgUFVCTElDIFwiJywgcHViaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzeXNpZCAmJiBzeXNpZCAhPT0gJy4nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5wdXNoKCdcIiBcIicsIHN5c2lkKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ1wiPicpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzeXNpZCAmJiBzeXNpZCAhPT0gJy4nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJyBTWVNURU0gXCInLCBzeXNpZCwgJ1wiPicpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBidWYucHVzaCgnPicpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICBjYXNlIG5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOlxyXG4gICAgICAgICAgICAgICAgY29uc3QgcGlOb2RlID0gPFByb2Nlc3NpbmdJbnN0cnVjdGlvbj4gbm9kZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBidWYucHVzaCggJzw/JywgcGlOb2RlLnRhcmdldCwgJyAnLCBwaU5vZGUuZGF0YSwgJz8+Jyk7XHJcbiAgICAgICAgICAgIGNhc2Ugbm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmLnB1c2goJyYnLCBub2RlLm5vZGVOYW1lLCAnOycpO1xyXG4gICAgICAgICAgICAvLyBjYXNlIEVOVElUWV9OT0RFOlxyXG4gICAgICAgICAgICAvLyBjYXNlIE5PVEFUSU9OX05PREU6XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICBidWYucHVzaCgnPz8nLCBub2RlLm5vZGVOYW1lKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBuZWVkTmFtZXNwYWNlRGVmaW5lKG5vZGU6IEVsZW1lbnQgfCBBdHRyLCB2aXNpYmxlTmFtZXNwYWNlczogTmFtZXNwYWNlW10pOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBwcmVmaXggPSBub2RlLnByZWZpeCB8fCAnJztcclxuICAgICAgICBjb25zdCB1cmkgPSBub2RlLm5hbWVzcGFjZVVSSTtcclxuICAgICAgICBpZiAoIXByZWZpeCAmJiAhdXJpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHByZWZpeCA9PT0gJ3htbCcgJiYgdXJpID09PSAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJ1xyXG4gICAgICAgICAgICB8fCB1cmkgPT09ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLycpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGkgPSB2aXNpYmxlTmFtZXNwYWNlcy5sZW5ndGg7XHJcbiAgICAgICAgd2hpbGUgKGktLSkge1xyXG4gICAgICAgICAgICBjb25zdCBucyA9IHZpc2libGVOYW1lc3BhY2VzW2ldO1xyXG4gICAgICAgICAgICAvLyBnZXQgbmFtZXNwYWNlIHByZWZpeFxyXG4gICAgICAgICAgICBpZiAobnMucHJlZml4ID09PSBwcmVmaXgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBucy5uYW1lc3BhY2UgIT09IHVyaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF94bWxFbmNvZGVyKGM6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIGMgPT09ICc8JyAmJiAnJmx0OycgfHxcclxuICAgICAgICAgICAgYyA9PT0gJz4nICYmICcmZ3Q7JyB8fFxyXG4gICAgICAgICAgICBjID09PSAnJicgJiYgJyZhbXA7JyB8fFxyXG4gICAgICAgICAgICBjID09PSAnXCInICYmICcmcXVvdDsnIHx8XHJcbiAgICAgICAgICAgICcmIycgKyBjLmNoYXJDb2RlQXQoMCkgKyAnOyc7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBvdXRwdXRJbmRlbnRlZChvcHRpb25zOiBYbWxTZXJpYWxpemVyT3B0aW9ucywgYnVmOiBzdHJpbmdbXSwgaW5kZW50TGV2ZWw6IG51bWJlciwgLi4ub3V0cHV0UGFydHM6IHN0cmluZ1tdKSB7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMuYmVhdXRpZnkpIHtcclxuICAgICAgICAgICAgYnVmLnB1c2goJ1xcbicpO1xyXG4gICAgICAgICAgICBpZiAoaW5kZW50TGV2ZWwgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBidWYucHVzaCh0aGlzLmluZGVudGF0aW9uU3RyaW5nKG9wdGlvbnMsIGluZGVudExldmVsKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgYnVmLnB1c2goLi4ub3V0cHV0UGFydHMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaW5kZW50YXRpb25TdHJpbmcob3B0aW9uczogWG1sU2VyaWFsaXplck9wdGlvbnMsIGluZGVudExldmVsOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGluZGVudCA9IChvcHRpb25zLmluZGVudFN0cmluZykgPyBvcHRpb25zLmluZGVudFN0cmluZyA6IERFRkFVTFRfSU5ERU5UX1NUUklORztcclxuICAgICAgICBsZXQgcmVzdWx0ID0gJyc7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRlbnRMZXZlbDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIGluZGVudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3QsIHdldGhlciB0YWdOYW1lIGlzIGFuIGVsZW1lbnQgY29udGFpbmluZyBtaXhlZCBjb250ZW50LlxyXG4gICAgICogQHBhcmFtIHRhZ05hbWUgdGFnTmFtZVxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgb3B0aW9uc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzTWl4ZWRDb250ZW50RWxlbWVudCh0YWdOYW1lOiBzdHJpbmcsIG9wdGlvbnM6IFhtbFNlcmlhbGl6ZXJPcHRpb25zKTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5taXhlZENvbnRlbnRFbGVtZW50cykge1xyXG4gICAgICAgICAgICByZXR1cm4gISFvcHRpb25zLm1peGVkQ29udGVudEVsZW1lbnRzLmZpbmQoKHRhZykgPT4gdGFnID09PSB0YWdOYW1lKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY29udGFpbnNPbmx5V2hpdGVTcGFjZSh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgYyA9IHRleHQuY2hhckF0KGkpO1xyXG4gICAgICAgICAgICBpZiAoIShjID09PSAnICcgfHwgYyA9PT0gJ1xcdCcgfHwgYyA9PT0gJ1xccicgfHwgYyA9PT0gJ1xcbicpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbn1cclxuIl19