@ngx-i18nsupport/ngx-i18nsupport-lib
Version:
A Typescript library to work with Angular generated i18n files (xliff, xmb)
344 lines • 41.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { AbstractMessageParser } from './abstract-message-parser';
import { ParsedMessagePartType } from './parsed-message-part';
import { TagMapping } from './tag-mapping';
/**
* Created by roobm on 10.05.2017.
* A message parser for XLIFF 2.0
*/
export class Xliff2MessageParser extends AbstractMessageParser {
/**
* Handle this element node.
* This is called before the children are done.
* @protected
* @param {?} elementNode elementNode
* @param {?} message message to be altered
* @return {?} true, if children should be processed too, false otherwise (children ignored then)
*/
processStartElement(elementNode, message) {
/** @type {?} */
const tagName = elementNode.tagName;
if (tagName === 'ph') {
// placeholder are like <ph id="0" equiv="INTERPOLATION" disp="{{number()}}"/>
// They contain the id and also a name (number in the example)
// TODO make some use of the name (but it is not available in XLIFF 1.2)
// ICU message are handled with the same tag
// Before 4.3.2 they did not have an equiv and disp (Bug #17344):
// e.g. <ph id="0"/>
// Beginning with 4.3.2 they do have an equiv ICU and disp:
// e.g. <ph id="0" equiv="ICU" disp="{count, plural, =0 {...} =1 {...} other {...}}"/>
// and empty tags have equiv other then INTERPOLATION:
// e.g. <ph id="3" equiv="TAG_IMG" type="image" disp="<img/>"/>
// or <ph equiv="LINE_BREAK" type="lb" disp="<br/>"/>
/** @type {?} */
let isInterpolation = false;
/** @type {?} */
let isICU = false;
/** @type {?} */
let isEmptyTag = false;
/** @type {?} */
const equiv = elementNode.getAttribute('equiv');
/** @type {?} */
const disp = elementNode.getAttribute('disp');
/** @type {?} */
let indexString = null;
/** @type {?} */
let index = 0;
/** @type {?} */
let emptyTagName = null;
if (!equiv) {
// old ICU syntax, fixed with #17344
isICU = true;
indexString = elementNode.getAttribute('id');
index = Number.parseInt(indexString, 10);
}
else if (equiv.startsWith('ICU')) {
// new ICU syntax, fixed with #17344
isICU = true;
if (equiv === 'ICU') {
indexString = '0';
}
else {
indexString = equiv.substring('ICU_'.length);
}
index = Number.parseInt(indexString, 10);
}
else if (equiv.startsWith('INTERPOLATION')) {
isInterpolation = true;
if (equiv === 'INTERPOLATION') {
indexString = '0';
}
else {
indexString = equiv.substring('INTERPOLATION_'.length);
}
index = Number.parseInt(indexString, 10);
}
else if (new TagMapping().isEmptyTagPlaceholderName(equiv)) {
isEmptyTag = true;
emptyTagName = new TagMapping().getTagnameFromEmptyTagPlaceholderName(equiv);
}
else {
return true;
}
if (isInterpolation) {
message.addPlaceholder(index, disp);
}
else if (isICU) {
message.addICUMessageRef(index, disp);
}
else if (isEmptyTag) {
message.addEmptyTag(emptyTagName, this.parseIdCountFromName(equiv));
}
}
else if (tagName === 'pc') {
// pc example: <pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt"
// dispStart="<b>" dispEnd="</b>">IMPORTANT</pc>
/** @type {?} */
const embeddedTagName = this.tagNameFromPCElement(elementNode);
if (embeddedTagName) {
message.addStartTag(embeddedTagName, this.parseIdCountFromName(elementNode.getAttribute('equivStart')));
}
}
return true;
}
/**
* Handle end of this element node.
* This is called after all children are processed.
* @protected
* @param {?} elementNode elementNode
* @param {?} message message to be altered
* @return {?}
*/
processEndElement(elementNode, message) {
/** @type {?} */
const tagName = elementNode.tagName;
if (tagName === 'pc') {
// pc example: <pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt"
// dispStart="<b>" dispEnd="</b>">IMPORTANT</pc>
/** @type {?} */
const embeddedTagName = this.tagNameFromPCElement(elementNode);
if (embeddedTagName) {
message.addEndTag(embeddedTagName);
}
return;
}
}
/**
* @private
* @param {?} pcNode
* @return {?}
*/
tagNameFromPCElement(pcNode) {
/** @type {?} */
let dispStart = pcNode.getAttribute('dispStart');
if (dispStart.startsWith('<')) {
dispStart = dispStart.substring(1);
}
if (dispStart.endsWith('>')) {
dispStart = dispStart.substring(0, dispStart.length - 1);
}
return dispStart;
}
/**
* reimplemented here, because XLIFF 2.0 uses a deeper xml model.
* So we cannot simply replace the message parts by xml parts.
* @protected
* @param {?} message message
* @param {?} rootElem rootElem
* @return {?}
*/
addXmlRepresentationToRoot(message, rootElem) {
/** @type {?} */
const stack = [{ element: rootElem, tagName: 'root' }];
/** @type {?} */
let id = 0;
message.parts().forEach((/**
* @param {?} part
* @return {?}
*/
(part) => {
switch (part.type) {
case ParsedMessagePartType.TEXT:
stack[stack.length - 1].element.appendChild(this.createXmlRepresentationOfTextPart((/** @type {?} */ (part)), rootElem));
break;
case ParsedMessagePartType.PLACEHOLDER:
stack[stack.length - 1].element.appendChild(this.createXmlRepresentationOfPlaceholderPart((/** @type {?} */ (part)), rootElem, id++));
break;
case ParsedMessagePartType.ICU_MESSAGE_REF:
stack[stack.length - 1].element.appendChild(this.createXmlRepresentationOfICUMessageRefPart((/** @type {?} */ (part)), rootElem));
break;
case ParsedMessagePartType.START_TAG:
/** @type {?} */
const newTagElem = this.createXmlRepresentationOfStartTagPart((/** @type {?} */ (part)), rootElem, id++);
stack[stack.length - 1].element.appendChild(newTagElem);
stack.push({ element: (/** @type {?} */ (newTagElem)), tagName: ((/** @type {?} */ (part))).tagName() });
break;
case ParsedMessagePartType.END_TAG:
/** @type {?} */
const closeTagName = ((/** @type {?} */ (part))).tagName();
if (stack.length <= 1 || stack[stack.length - 1].tagName !== closeTagName) {
// oops, not well formed
throw new Error('unexpected close tag ' + closeTagName);
}
stack.pop();
break;
case ParsedMessagePartType.EMPTY_TAG:
/** @type {?} */
const emptyTagElem = this.createXmlRepresentationOfEmptyTagPart((/** @type {?} */ (part)), rootElem, id++);
stack[stack.length - 1].element.appendChild(emptyTagElem);
break;
}
}));
if (stack.length !== 1) {
// oops, not well closed tags
throw new Error('missing close tag ' + stack[stack.length - 1].tagName);
}
}
/**
* the xml used for start tag in the message.
* Returns an empty pc-Element.
* e.g. <pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="<b>" dispEnd="</b>">
* Text content will be added later.
* @protected
* @param {?} part part
* @param {?} rootElem rootElem
* @param {?} id id number in xliff2
* @return {?}
*/
createXmlRepresentationOfStartTagPart(part, rootElem, id) {
/** @type {?} */
const tagMapping = new TagMapping();
/** @type {?} */
const pcElem = rootElem.ownerDocument.createElement('pc');
/** @type {?} */
const tagName = part.tagName();
/** @type {?} */
const equivStart = tagMapping.getStartTagPlaceholderName(tagName, part.idCounter());
/** @type {?} */
const equivEnd = tagMapping.getCloseTagPlaceholderName(tagName);
/** @type {?} */
const dispStart = '<' + tagName + '>';
/** @type {?} */
const dispEnd = '</' + tagName + '>';
pcElem.setAttribute('id', id.toString(10));
pcElem.setAttribute('equivStart', equivStart);
pcElem.setAttribute('equivEnd', equivEnd);
pcElem.setAttribute('type', this.getTypeForTag(tagName));
pcElem.setAttribute('dispStart', dispStart);
pcElem.setAttribute('dispEnd', dispEnd);
return pcElem;
}
/**
* the xml used for end tag in the message.
* Not used here, because content is child of start tag.
* @protected
* @param {?} part part
* @param {?} rootElem rootElem
* @return {?}
*/
createXmlRepresentationOfEndTagPart(part, rootElem) {
// not used
return null;
}
/**
* the xml used for empty tag in the message.
* Returns an empty ph-Element.
* e.g. <ph id="3" equiv="TAG_IMG" type="image" disp="<img/>"/>
* @protected
* @param {?} part part
* @param {?} rootElem rootElem
* @param {?} id id number in xliff2
* @return {?}
*/
createXmlRepresentationOfEmptyTagPart(part, rootElem, id) {
/** @type {?} */
const tagMapping = new TagMapping();
/** @type {?} */
const phElem = rootElem.ownerDocument.createElement('ph');
/** @type {?} */
const tagName = part.tagName();
/** @type {?} */
const equiv = tagMapping.getEmptyTagPlaceholderName(tagName, part.idCounter());
/** @type {?} */
const disp = '<' + tagName + '/>';
phElem.setAttribute('id', id.toString(10));
phElem.setAttribute('equiv', equiv);
phElem.setAttribute('type', this.getTypeForTag(tagName));
phElem.setAttribute('disp', disp);
return phElem;
}
/**
* @private
* @param {?} tag
* @return {?}
*/
getTypeForTag(tag) {
switch (tag.toLowerCase()) {
case 'br':
case 'b':
case 'i':
case 'u':
return 'fmt';
case 'img':
return 'image';
case 'a':
return 'link';
default:
return 'other';
}
}
/**
* the xml used for placeholder in the message.
* Returns e.g. <ph id="1" equiv="INTERPOLATION_1" disp="{{total()}}"/>
* @protected
* @param {?} part part
* @param {?} rootElem rootElem
* @param {?} id id number in xliff2
* @return {?}
*/
createXmlRepresentationOfPlaceholderPart(part, rootElem, id) {
/** @type {?} */
const phElem = rootElem.ownerDocument.createElement('ph');
/** @type {?} */
let equivAttrib = 'INTERPOLATION';
if (part.index() > 0) {
equivAttrib = 'INTERPOLATION_' + part.index().toString(10);
}
phElem.setAttribute('id', id.toString(10));
phElem.setAttribute('equiv', equivAttrib);
/** @type {?} */
const disp = part.disp();
if (disp) {
phElem.setAttribute('disp', disp);
}
return phElem;
}
/**
* the xml used for icu message refs in the message.
* @protected
* @param {?} part part
* @param {?} rootElem rootElem
* @return {?}
*/
createXmlRepresentationOfICUMessageRefPart(part, rootElem) {
/** @type {?} */
const phElem = rootElem.ownerDocument.createElement('ph');
/** @type {?} */
let equivAttrib = 'ICU';
if (part.index() > 0) {
equivAttrib = 'ICU_' + part.index().toString(10);
}
phElem.setAttribute('id', part.index().toString(10));
phElem.setAttribute('equiv', equivAttrib);
/** @type {?} */
const disp = part.disp();
if (disp) {
phElem.setAttribute('disp', disp);
}
return phElem;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieGxpZmYyLW1lc3NhZ2UtcGFyc2VyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1pMThuc3VwcG9ydC9uZ3gtaTE4bnN1cHBvcnQtbGliLyIsInNvdXJjZXMiOlsiaW1wbC94bGlmZjItbWVzc2FnZS1wYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBTWhFLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQzVELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7Ozs7O0FBT3pDLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxxQkFBcUI7Ozs7Ozs7OztJQVNoRCxtQkFBbUIsQ0FBQyxXQUFvQixFQUFFLE9BQXNCOztjQUNoRSxPQUFPLEdBQUcsV0FBVyxDQUFDLE9BQU87UUFDbkMsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFOzs7Ozs7Ozs7Ozs7O2dCQVlkLGVBQWUsR0FBRyxLQUFLOztnQkFDdkIsS0FBSyxHQUFHLEtBQUs7O2dCQUNiLFVBQVUsR0FBRyxLQUFLOztrQkFDaEIsS0FBSyxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDOztrQkFDekMsSUFBSSxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDOztnQkFDekMsV0FBVyxHQUFHLElBQUk7O2dCQUNsQixLQUFLLEdBQUcsQ0FBQzs7Z0JBQ1QsWUFBWSxHQUFHLElBQUk7WUFDdkIsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDUixvQ0FBb0M7Z0JBQ3BDLEtBQUssR0FBRyxJQUFJLENBQUM7Z0JBQ2IsV0FBVyxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzdDLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUM1QztpQkFBTSxJQUFJLEtBQUssQ0FBQyxV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T0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDOztjQUNwQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRTtRQUN4QixJQUFJLElBQUksRUFBRTtZQUNOLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQ3JDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztDQUVKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBYnN0cmFjdE1lc3NhZ2VQYXJzZXJ9IGZyb20gJy4vYWJzdHJhY3QtbWVzc2FnZS1wYXJzZXInO1xyXG5pbXBvcnQge1BhcnNlZE1lc3NhZ2V9IGZyb20gJy4vcGFyc2VkLW1lc3NhZ2UnO1xyXG5pbXBvcnQge1BhcnNlZE1lc3NhZ2VQYXJ0U3RhcnRUYWd9IGZyb20gJy4vcGFyc2VkLW1lc3NhZ2UtcGFydC1zdGFydC10YWcnO1xyXG5pbXBvcnQge1BhcnNlZE1lc3NhZ2VQYXJ0RW5kVGFnfSBmcm9tICcuL3BhcnNlZC1tZXNzYWdlLXBhcnQtZW5kLXRhZyc7XHJcbmltcG9ydCB7UGFyc2VkTWVzc2FnZVBhcnRQbGFjZWhvbGRlcn0gZnJvbSAnLi9wYXJzZWQtbWVzc2FnZS1wYXJ0LXBsYWNlaG9sZGVyJztcclxuaW1wb3J0IHtQYXJzZWRNZXNzYWdlUGFydFRleHR9IGZyb20gJy4vcGFyc2VkLW1lc3NhZ2UtcGFydC10ZXh0JztcclxuaW1wb3J0IHtQYXJzZWRNZXNzYWdlUGFydFR5cGV9IGZyb20gJy4vcGFyc2VkLW1lc3NhZ2UtcGFydCc7XHJcbmltcG9ydCB7VGFnTWFwcGluZ30gZnJvbSAnLi90YWctbWFwcGluZyc7XHJcbmltcG9ydCB7UGFyc2VkTWVzc2FnZVBhcnRFbXB0eVRhZ30gZnJvbSAnLi9wYXJzZWQtbWVzc2FnZS1wYXJ0LWVtcHR5LXRhZyc7XHJcbmltcG9ydCB7UGFyc2VkTWVzc2FnZVBhcnRJQ1VNZXNzYWdlUmVmfSBmcm9tICcuL3BhcnNlZC1tZXNzYWdlLXBhcnQtaWN1LW1lc3NhZ2UtcmVmJztcclxuLyoqXHJcbiAqIENyZWF0ZWQgYnkgcm9vYm0gb24gMTAuMDUuMjAxNy5cclxuICogQSBtZXNzYWdlIHBhcnNlciBmb3IgWExJRkYgMi4wXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgWGxpZmYyTWVzc2FnZVBhcnNlciBleHRlbmRzIEFic3RyYWN0TWVzc2FnZVBhcnNlciB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGUgdGhpcyBlbGVtZW50IG5vZGUuXHJcbiAgICAgKiBUaGlzIGlzIGNhbGxlZCBiZWZvcmUgdGhlIGNoaWxkcmVuIGFyZSBkb25lLlxyXG4gICAgICogQHBhcmFtIGVsZW1lbnROb2RlIGVsZW1lbnROb2RlXHJcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIGFsdGVyZWRcclxuICAgICAqIEByZXR1cm4gdHJ1ZSwgaWYgY2hpbGRyZW4gc2hvdWxkIGJlIHByb2Nlc3NlZCB0b28sIGZhbHNlIG90aGVyd2lzZSAoY2hpbGRyZW4gaWdub3JlZCB0aGVuKVxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgcHJvY2Vzc1N0YXJ0RWxlbWVudChlbGVtZW50Tm9kZTogRWxlbWVudCwgbWVzc2FnZTogUGFyc2VkTWVzc2FnZSk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IHRhZ05hbWUgPSBlbGVtZW50Tm9kZS50YWdOYW1lO1xyXG4gICAgICAgIGlmICh0YWdOYW1lID09PSAncGgnKSB7XHJcbiAgICAgICAgICAgIC8vIHBsYWNlaG9sZGVyIGFyZSBsaWtlIDxwaCBpZD1cIjBcIiBlcXVpdj1cIklOVEVSUE9MQVRJT05cIiBkaXNwPVwie3tudW1iZXIoKX19XCIvPlxyXG4gICAgICAgICAgICAvLyBUaGV5IGNvbnRhaW4gdGhlIGlkIGFuZCBhbHNvIGEgbmFtZSAobnVtYmVyIGluIHRoZSBleGFtcGxlKVxyXG4gICAgICAgICAgICAvLyBUT0RPIG1ha2Ugc29tZSB1c2Ugb2YgdGhlIG5hbWUgKGJ1dCBpdCBpcyBub3QgYXZhaWxhYmxlIGluIFhMSUZGIDEuMilcclxuICAgICAgICAgICAgLy8gSUNVIG1lc3NhZ2UgYXJlIGhhbmRsZWQgd2l0aCB0aGUgc2FtZSB0YWdcclxuICAgICAgICAgICAgLy8gQmVmb3JlIDQuMy4yIHRoZXkgZGlkIG5vdCBoYXZlIGFuIGVxdWl2IGFuZCBkaXNwIChCdWcgIzE3MzQ0KTpcclxuICAgICAgICAgICAgLy8gZS5nLiA8cGggaWQ9XCIwXCIvPlxyXG4gICAgICAgICAgICAvLyBCZWdpbm5pbmcgd2l0aCA0LjMuMiB0aGV5IGRvIGhhdmUgYW4gZXF1aXYgSUNVIGFuZCBkaXNwOlxyXG4gICAgICAgICAgICAvLyBlLmcuIDxwaCBpZD1cIjBcIiBlcXVpdj1cIklDVVwiIGRpc3A9XCJ7Y291bnQsIHBsdXJhbCwgPTAgey4uLn0gPTEgey4uLn0gb3RoZXIgey4uLn19XCIvPlxyXG4gICAgICAgICAgICAvLyBhbmQgZW1wdHkgdGFncyBoYXZlIGVxdWl2IG90aGVyIHRoZW4gSU5URVJQT0xBVElPTjpcclxuICAgICAgICAgICAgLy8gZS5nLiA8cGggaWQ9XCIzXCIgZXF1aXY9XCJUQUdfSU1HXCIgdHlwZT1cImltYWdlXCIgZGlzcD1cIiZsdDtpbWcvPlwiLz5cclxuICAgICAgICAgICAgLy8gb3IgPHBoIGVxdWl2PVwiTElORV9CUkVBS1wiIHR5cGU9XCJsYlwiIGRpc3A9XCImbHQ7YnIvPlwiLz5cclxuICAgICAgICAgICAgbGV0IGlzSW50ZXJwb2xhdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgaXNJQ1UgPSBmYWxzZTtcclxuICAgICAgICAgICAgbGV0IGlzRW1wdHlUYWcgPSBmYWxzZTtcclxuICAgICAgICAgICAgY29uc3QgZXF1aXYgPSBlbGVtZW50Tm9kZS5nZXRBdHRyaWJ1dGUoJ2VxdWl2Jyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGRpc3AgPSBlbGVtZW50Tm9kZS5nZXRBdHRyaWJ1dGUoJ2Rpc3AnKTtcclxuICAgICAgICAgICAgbGV0IGluZGV4U3RyaW5nID0gbnVsbDtcclxuICAgICAgICAgICAgbGV0IGluZGV4ID0gMDtcclxuICAgICAgICAgICAgbGV0IGVtcHR5VGFnTmFtZSA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICghZXF1aXYpIHtcclxuICAgICAgICAgICAgICAgIC8vIG9sZCBJQ1Ugc3ludGF4LCBmaXhlZCB3aXRoICMxNzM0NFxyXG4gICAgICAgICAgICAgICAgaXNJQ1UgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgaW5kZXhTdHJpbmcgPSBlbGVtZW50Tm9kZS5nZXRBdHRyaWJ1dGUoJ2lkJyk7XHJcbiAgICAgICAgICAgICAgICBpbmRleCA9IE51bWJlci5wYXJzZUludChpbmRleFN0cmluZywgMTApO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVxdWl2LnN0YXJ0c1dpdGgoJ0lDVScpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBuZXcgSUNVIHN5bnRheCwgZml4ZWQgd2l0aCAjMTczNDRcclxuICAgICAgICAgICAgICAgIGlzSUNVID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGlmIChlcXVpdiA9PT0gJ0lDVScpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleFN0cmluZyA9ICcwJztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXhTdHJpbmcgPSBlcXVpdi5zdWJzdHJpbmcoJ0lDVV8nLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpbmRleCA9IE51bWJlci5wYXJzZUludChpbmRleFN0cmluZywgMTApO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVxdWl2LnN0YXJ0c1dpdGgoJ0lOVEVSUE9MQVRJT04nKSkge1xyXG4gICAgICAgICAgICAgICAgaXNJbnRlcnBvbGF0aW9uID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGlmIChlcXVpdiA9PT0gJ0lOVEVSUE9MQVRJT04nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXhTdHJpbmcgPSAnMCc7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4U3RyaW5nID0gZXF1aXYuc3Vic3RyaW5nKCdJTlRFUlBPTEFUSU9OXycubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGluZGV4ID0gTnVtYmVyLnBhcnNlSW50KGluZGV4U3RyaW5nLCAxMCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3IFRhZ01hcHBpbmcoKS5pc0VtcHR5VGFnUGxhY2Vob2xkZXJOYW1lKGVxdWl2KSkge1xyXG4gICAgICAgICAgICAgICAgaXNFbXB0eVRhZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBlbXB0eVRhZ05hbWUgPSBuZXcgVGFnTWFwcGluZygpLmdldFRhZ25hbWVGcm9tRW1wdHlUYWdQbGFjZWhvbGRlck5hbWUoZXF1aXYpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGlzSW50ZXJwb2xhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRQbGFjZWhvbGRlcihpbmRleCwgZGlzcCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNJQ1UpIHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkSUNVTWVzc2FnZVJlZihpbmRleCwgZGlzcCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNFbXB0eVRhZykge1xyXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRFbXB0eVRhZyhlbXB0eVRhZ05hbWUsIHRoaXMucGFyc2VJZENvdW50RnJvbU5hbWUoZXF1aXYpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAodGFnTmFtZSA9PT0gJ3BjJykge1xyXG4gICAgICAgICAgICAvLyBwYyBleGFtcGxlOiA8cGMgaWQ9XCIwXCIgZXF1aXZTdGFydD1cIlNUQVJUX0JPTERfVEVYVFwiIGVxdWl2RW5kPVwiQ0xPU0VfQk9MRF9URVhUXCIgdHlwZT1cImZtdFwiXHJcbiAgICAgICAgICAgIC8vIGRpc3BTdGFydD1cIiZsdDtiJmd0O1wiIGRpc3BFbmQ9XCImbHQ7L2ImZ3Q7XCI+SU1QT1JUQU5UPC9wYz5cclxuICAgICAgICAgICAgY29uc3QgZW1iZWRkZWRUYWdOYW1lID0gdGhpcy50YWdOYW1lRnJvbVBDRWxlbWVudChlbGVtZW50Tm9kZSk7XHJcbiAgICAgICAgICAgIGlmIChlbWJlZGRlZFRhZ05hbWUpIHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkU3RhcnRUYWcoZW1iZWRkZWRUYWdOYW1lLCB0aGlzLnBhcnNlSWRDb3VudEZyb21OYW1lKGVsZW1lbnROb2RlLmdldEF0dHJpYnV0ZSgnZXF1aXZTdGFydCcpKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGUgZW5kIG9mIHRoaXMgZWxlbWVudCBub2RlLlxyXG4gICAgICogVGhpcyBpcyBjYWxsZWQgYWZ0ZXIgYWxsIGNoaWxkcmVuIGFyZSBwcm9jZXNzZWQuXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudE5vZGUgZWxlbWVudE5vZGVcclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgYWx0ZXJlZFxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgcHJvY2Vzc0VuZEVsZW1lbnQoZWxlbWVudE5vZGU6IEVsZW1lbnQsIG1lc3NhZ2U6IFBhcnNlZE1lc3NhZ2UpIHtcclxuICAgICAgICBjb25zdCB0YWdOYW1lID0gZWxlbWVudE5vZGUudGFnTmFtZTtcclxuICAgICAgICBpZiAodGFnTmFtZSA9PT0gJ3BjJykge1xyXG4gICAgICAgICAgICAvLyBwYyBleGFtcGxlOiA8cGMgaWQ9XCIwXCIgZXF1aXZTdGFydD1cIlNUQVJUX0JPTERfVEVYVFwiIGVxdWl2RW5kPVwiQ0xPU0VfQk9MRF9URVhUXCIgdHlwZT1cImZtdFwiXHJcbiAgICAgICAgICAgIC8vIGRpc3BTdGFydD1cIiZsdDtiJmd0O1wiIGRpc3BFbmQ9XCImbHQ7L2ImZ3Q7XCI+SU1QT1JUQU5UPC9wYz5cclxuICAgICAgICAgICAgY29uc3QgZW1iZWRkZWRUYWdOYW1lID0gdGhpcy50YWdOYW1lRnJvbVBDRWxlbWVudChlbGVtZW50Tm9kZSk7XHJcbiAgICAgICAgICAgIGlmIChlbWJlZGRlZFRhZ05hbWUpIHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkRW5kVGFnKGVtYmVkZGVkVGFnTmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHRhZ05hbWVGcm9tUENFbGVtZW50KHBjTm9kZTogRWxlbWVudCk6IHN0cmluZyB7XHJcbiAgICAgICAgbGV0IGRpc3BTdGFydCA9IHBjTm9kZS5nZXRBdHRyaWJ1dGUoJ2Rpc3BTdGFydCcpO1xyXG4gICAgICAgIGlmIChkaXNwU3RhcnQuc3RhcnRzV2l0aCgnPCcpKSB7XHJcbiAgICAgICAgICAgIGRpc3BTdGFydCA9IGRpc3BTdGFydC5zdWJzdHJpbmcoMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXNwU3RhcnQuZW5kc1dpdGgoJz4nKSkge1xyXG4gICAgICAgICAgICBkaXNwU3RhcnQgPSBkaXNwU3RhcnQuc3Vic3RyaW5nKDAsIGRpc3BTdGFydC5sZW5ndGggLSAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGRpc3BTdGFydDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIHJlaW1wbGVtZW50ZWQgaGVyZSwgYmVjYXVzZSBYTElGRiAyLjAgdXNlcyBhIGRlZXBlciB4bWwgbW9kZWwuXHJcbiAgICAgKiBTbyB3ZSBjYW5ub3Qgc2ltcGx5IHJlcGxhY2UgdGhlIG1lc3NhZ2UgcGFydHMgYnkgeG1sIHBhcnRzLlxyXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgbWVzc2FnZVxyXG4gICAgICogQHBhcmFtIHJvb3RFbGVtIHJvb3RFbGVtXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBhZGRYbWxSZXByZXNlbnRhdGlvblRvUm9vdChtZXNzYWdlOiBQYXJzZWRNZXNzYWdlLCByb290RWxlbTogRWxlbWVudCkge1xyXG4gICAgICAgIGNvbnN0IHN0YWNrID0gW3tlbGVtZW50OiByb290RWxlbSwgdGFnTmFtZTogJ3Jvb3QnfV07XHJcbiAgICAgICAgbGV0IGlkID0gMDtcclxuICAgICAgICBtZXNzYWdlLnBhcnRzKCkuZm9yRWFjaCgocGFydCkgPT4ge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBQYXJzZWRNZXNzYWdlUGFydFR5cGUuVEVYVDpcclxuICAgICAgICAgICAgICAgICAgICBzdGFja1tzdGFjay5sZW5ndGggLSAxXS5lbGVtZW50LmFwcGVuZENoaWxkKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVhtbFJlcHJlc2VudGF0aW9uT2ZUZXh0UGFydCg8UGFyc2VkTWVzc2FnZVBhcnRUZXh0PiBwYXJ0LCByb290RWxlbSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBQYXJzZWRNZXNzYWdlUGFydFR5cGUuUExBQ0VIT0xERVI6XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0uZWxlbWVudC5hcHBlbmRDaGlsZChcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVYbWxSZXByZXNlbnRhdGlvbk9mUGxhY2Vob2xkZXJQYXJ0KDxQYXJzZWRNZXNzYWdlUGFydFBsYWNlaG9sZGVyPiBwYXJ0LCByb290RWxlbSwgaWQrKykpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBQYXJzZWRNZXNzYWdlUGFydFR5cGUuSUNVX01FU1NBR0VfUkVGOlxyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdLmVsZW1lbnQuYXBwZW5kQ2hpbGQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlWG1sUmVwcmVzZW50YXRpb25PZklDVU1lc3NhZ2VSZWZQYXJ0KDxQYXJzZWRNZXNzYWdlUGFydElDVU1lc3NhZ2VSZWY+IHBhcnQsIHJvb3RFbGVtKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFBhcnNlZE1lc3NhZ2VQYXJ0VHlwZS5TVEFSVF9UQUc6XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGFnRWxlbSA9IHRoaXMuY3JlYXRlWG1sUmVwcmVzZW50YXRpb25PZlN0YXJ0VGFnUGFydCg8UGFyc2VkTWVzc2FnZVBhcnRTdGFydFRhZz4gcGFydCwgcm9vdEVsZW0sIGlkKyspO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdLmVsZW1lbnQuYXBwZW5kQ2hpbGQobmV3VGFnRWxlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhY2sucHVzaCh7ZWxlbWVudDogPEVsZW1lbnQ+IG5ld1RhZ0VsZW0sIHRhZ05hbWU6ICg8UGFyc2VkTWVzc2FnZVBhcnRTdGFydFRhZz4gcGFydCkudGFnTmFtZSgpfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFBhcnNlZE1lc3NhZ2VQYXJ0VHlwZS5FTkRfVEFHOlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsb3NlVGFnTmFtZSA9ICg8UGFyc2VkTWVzc2FnZVBhcnRFbmRUYWc+IHBhcnQpLnRhZ05hbWUoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhY2subGVuZ3RoIDw9IDEgfHwgc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0udGFnTmFtZSAhPT0gY2xvc2VUYWdOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9vcHMsIG5vdCB3ZWxsIGZvcm1lZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuZXhwZWN0ZWQgY2xvc2UgdGFnICcgKyBjbG9zZVRhZ05hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzdGFjay5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgUGFyc2VkTWVzc2FnZVBhcnRUeXBlLkVNUFRZX1RBRzpcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbXB0eVRhZ0VsZW0gPSB0aGlzLmNyZWF0ZVhtbFJlcHJlc2VudGF0aW9uT2ZFbXB0eVRhZ1BhcnQoPFBhcnNlZE1lc3NhZ2VQYXJ0RW1wdHlUYWc+IHBhcnQsIHJvb3RFbGVtLCBpZCsrKTtcclxuICAgICAgICAgICAgICAgICAgICBzdGFja1tzdGFjay5sZW5ndGggLSAxXS5lbGVtZW50LmFwcGVuZENoaWxkKGVtcHR5VGFnRWxlbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoc3RhY2subGVuZ3RoICE9PSAxKSB7XHJcbiAgICAgICAgICAgIC8vIG9vcHMsIG5vdCB3ZWxsIGNsb3NlZCB0YWdzXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBjbG9zZSB0YWcgJyArIHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdLnRhZ05hbWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIHRoZSB4bWwgdXNlZCBmb3Igc3RhcnQgdGFnIGluIHRoZSBtZXNzYWdlLlxyXG4gICAgICogUmV0dXJucyBhbiBlbXB0eSBwYy1FbGVtZW50LlxyXG4gICAgICogZS5nLiA8cGMgaWQ9XCIwXCIgZXF1aXZTdGFydD1cIlNUQVJUX0JPTERfVEVYVFwiIGVxdWl2RW5kPVwiQ0xPU0VfQk9MRF9URVhUXCIgdHlwZT1cImZtdFwiIGRpc3BTdGFydD1cIiZsdDtiJmd0O1wiIGRpc3BFbmQ9XCImbHQ7L2ImZ3Q7XCI+XHJcbiAgICAgKiBUZXh0IGNvbnRlbnQgd2lsbCBiZSBhZGRlZCBsYXRlci5cclxuICAgICAqIEBwYXJhbSBwYXJ0IHBhcnRcclxuICAgICAqIEBwYXJhbSByb290RWxlbSByb290RWxlbVxyXG4gICAgICogQHBhcmFtIGlkIGlkIG51bWJlciBpbiB4bGlmZjJcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGNyZWF0ZVhtbFJlcHJlc2VudGF0aW9uT2ZTdGFydFRhZ1BhcnQocGFydDogUGFyc2VkTWVzc2FnZVBhcnRTdGFydFRhZywgcm9vdEVsZW06IEVsZW1lbnQsIGlkOiBudW1iZXIpOiBOb2RlIHtcclxuICAgICAgICBjb25zdCB0YWdNYXBwaW5nID0gbmV3IFRhZ01hcHBpbmcoKTtcclxuICAgICAgICBjb25zdCBwY0VsZW0gPSByb290RWxlbS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3BjJyk7XHJcbiAgICAgICAgY29uc3QgdGFnTmFtZSA9IHBhcnQudGFnTmFtZSgpO1xyXG4gICAgICAgIGNvbnN0IGVxdWl2U3RhcnQgPSB0YWdNYXBwaW5nLmdldFN0YXJ0VGFnUGxhY2Vob2xkZXJOYW1lKHRhZ05hbWUsIHBhcnQuaWRDb3VudGVyKCkpO1xyXG4gICAgICAgIGNvbnN0IGVxdWl2RW5kID0gdGFnTWFwcGluZy5nZXRDbG9zZVRhZ1BsYWNlaG9sZGVyTmFtZSh0YWdOYW1lKTtcclxuICAgICAgICBjb25zdCBkaXNwU3RhcnQgPSAnPCcgKyB0YWdOYW1lICsgJz4nO1xyXG4gICAgICAgIGNvbnN0IGRpc3BFbmQgPSAnPC8nICsgdGFnTmFtZSArICc+JztcclxuICAgICAgICBwY0VsZW0uc2V0QXR0cmlidXRlKCdpZCcsIGlkLnRvU3RyaW5nKDEwKSk7XHJcbiAgICAgICAgcGNFbGVtLnNldEF0dHJpYnV0ZSgnZXF1aXZTdGFydCcsIGVxdWl2U3RhcnQpO1xyXG4gICAgICAgIHBjRWxlbS5zZXRBdHRyaWJ1dGUoJ2VxdWl2RW5kJywgZXF1aXZFbmQpO1xyXG4gICAgICAgIHBjRWxlbS5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCB0aGlzLmdldFR5cGVGb3JUYWcodGFnTmFtZSkpO1xyXG4gICAgICAgIHBjRWxlbS5zZXRBdHRyaWJ1dGUoJ2Rpc3BTdGFydCcsIGRpc3BTdGFydCk7XHJcbiAgICAgICAgcGNFbGVtLnNldEF0dHJpYnV0ZSgnZGlzcEVuZCcsIGRpc3BFbmQpO1xyXG4gICAgICAgIHJldHVybiBwY0VsZW07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0aGUgeG1sIHVzZWQgZm9yIGVuZCB0YWcgaW4gdGhlIG1lc3NhZ2UuXHJcbiAgICAgKiBOb3QgdXNlZCBoZXJlLCBiZWNhdXNlIGNvbnRlbnQgaXMgY2hpbGQgb2Ygc3RhcnQgdGFnLlxyXG4gICAgICogQHBhcmFtIHBhcnQgcGFydFxyXG4gICAgICogQHBhcmFtIHJvb3RFbGVtIHJvb3RFbGVtXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBjcmVhdGVYbWxSZXByZXNlbnRhdGlvbk9mRW5kVGFnUGFydChwYXJ0OiBQYXJzZWRNZXNzYWdlUGFydEVuZFRhZywgcm9vdEVsZW06IEVsZW1lbnQpOiBOb2RlIHtcclxuICAgICAgICAvLyBub3QgdXNlZFxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogdGhlIHhtbCB1c2VkIGZvciBlbXB0eSB0YWcgaW4gdGhlIG1lc3NhZ2UuXHJcbiAgICAgKiBSZXR1cm5zIGFuIGVtcHR5IHBoLUVsZW1lbnQuXHJcbiAgICAgKiBlLmcuIDxwaCBpZD1cIjNcIiBlcXVpdj1cIlRBR19JTUdcIiB0eXBlPVwiaW1hZ2VcIiBkaXNwPVwiJmx0O2ltZy8+XCIvPlxyXG4gICAgICogQHBhcmFtIHBhcnQgcGFydFxyXG4gICAgICogQHBhcmFtIHJvb3RFbGVtIHJvb3RFbGVtXHJcbiAgICAgKiBAcGFyYW0gaWQgaWQgbnVtYmVyIGluIHhsaWZmMlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgY3JlYXRlWG1sUmVwcmVzZW50YXRpb25PZkVtcHR5VGFnUGFydChwYXJ0OiBQYXJzZWRNZXNzYWdlUGFydEVtcHR5VGFnLCByb290RWxlbTogRWxlbWVudCwgaWQ6IG51bWJlcik6IE5vZGUge1xyXG4gICAgICAgIGNvbnN0IHRhZ01hcHBpbmcgPSBuZXcgVGFnTWFwcGluZygpO1xyXG4gICAgICAgIGNvbnN0IHBoRWxlbSA9IHJvb3RFbGVtLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncGgnKTtcclxuICAgICAgICBjb25zdCB0YWdOYW1lID0gcGFydC50YWdOYW1lKCk7XHJcbiAgICAgICAgY29uc3QgZXF1aXYgPSB0YWdNYXBwaW5nLmdldEVtcHR5VGFnUGxhY2Vob2xkZXJOYW1lKHRhZ05hbWUsIHBhcnQuaWRDb3VudGVyKCkpO1xyXG4gICAgICAgIGNvbnN0IGRpc3AgPSAnPCcgKyB0YWdOYW1lICsgJy8+JztcclxuICAgICAgICBwaEVsZW0uc2V0QXR0cmlidXRlKCdpZCcsIGlkLnRvU3RyaW5nKDEwKSk7XHJcbiAgICAgICAgcGhFbGVtLnNldEF0dHJpYnV0ZSgnZXF1aXYnLCBlcXVpdik7XHJcbiAgICAgICAgcGhFbGVtLnNldEF0dHJpYnV0ZSgndHlwZScsIHRoaXMuZ2V0VHlwZUZvclRhZyh0YWdOYW1lKSk7XHJcbiAgICAgICAgcGhFbGVtLnNldEF0dHJpYnV0ZSgnZGlzcCcsIGRpc3ApO1xyXG4gICAgICAgIHJldHVybiBwaEVsZW07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRUeXBlRm9yVGFnKHRhZzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBzd2l0Y2ggKHRhZy50b0xvd2VyQ2FzZSgpKSB7XHJcbiAgICAgICAgICAgIGNhc2UgJ2JyJzpcclxuICAgICAgICAgICAgY2FzZSAnYic6XHJcbiAgICAgICAgICAgIGNhc2UgJ2knOlxyXG4gICAgICAgICAgICBjYXNlICd1JzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnZm10JztcclxuICAgICAgICAgICAgY2FzZSAnaW1nJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnaW1hZ2UnO1xyXG4gICAgICAgICAgICBjYXNlICdhJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnbGluayc7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ290aGVyJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0aGUgeG1sIHVzZWQgZm9yIHBsYWNlaG9sZGVyIGluIHRoZSBtZXNzYWdlLlxyXG4gICAgICogUmV0dXJucyBlLmcuIDxwaCBpZD1cIjFcIiBlcXVpdj1cIklOVEVSUE9MQVRJT05fMVwiIGRpc3A9XCJ7e3RvdGFsKCl9fVwiLz5cclxuICAgICAqIEBwYXJhbSBwYXJ0IHBhcnRcclxuICAgICAqIEBwYXJhbSByb290RWxlbSByb290RWxlbVxyXG4gICAgICogQHBhcmFtIGlkIGlkIG51bWJlciBpbiB4bGlmZjJcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGNyZWF0ZVhtbFJlcHJlc2VudGF0aW9uT2ZQbGFjZWhvbGRlclBhcnQocGFydDogUGFyc2VkTWVzc2FnZVBhcnRQbGFjZWhvbGRlciwgcm9vdEVsZW06IEVsZW1lbnQsIGlkOiBudW1iZXIpOiBOb2RlIHtcclxuICAgICAgICBjb25zdCBwaEVsZW0gPSByb290RWxlbS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3BoJyk7XHJcbiAgICAgICAgbGV0IGVxdWl2QXR0cmliID0gJ0lOVEVSUE9MQVRJT04nO1xyXG4gICAgICAgIGlmIChwYXJ0LmluZGV4KCkgPiAwKSB7XHJcbiAgICAgICAgICAgIGVxdWl2QXR0cmliID0gJ0lOVEVSUE9MQVRJT05fJyArIHBhcnQuaW5kZXgoKS50b1N0cmluZygxMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHBoRWxlbS5zZXRBdHRyaWJ1dGUoJ2lkJywgaWQudG9TdHJpbmcoMTApKTtcclxuICAgICAgICBwaEVsZW0uc2V0QXR0cmlidXRlKCdlcXVpdicsIGVxdWl2QXR0cmliKTtcclxuICAgICAgICBjb25zdCBkaXNwID0gcGFydC5kaXNwKCk7XHJcbiAgICAgICAgaWYgKGRpc3ApIHtcclxuICAgICAgICAgICAgcGhFbGVtLnNldEF0dHJpYnV0ZSgnZGlzcCcsIGRpc3ApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcGhFbGVtO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogdGhlIHhtbCB1c2VkIGZvciBpY3UgbWVzc2FnZSByZWZzIGluIHRoZSBtZXNzYWdlLlxyXG4gICAgICogQHBhcmFtIHBhcnQgcGFydFxyXG4gICAgICogQHBhcmFtIHJvb3RFbGVtIHJvb3RFbGVtXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBjcmVhdGVYbWxSZXByZXNlbnRhdGlvbk9mSUNVTWVzc2FnZVJlZlBhcnQocGFydDogUGFyc2VkTWVzc2FnZVBhcnRJQ1VNZXNzYWdlUmVmLCByb290RWxlbTogRWxlbWVudCk6IE5vZGUge1xyXG4gICAgICAgIGNvbnN0IHBoRWxlbSA9IHJvb3RFbGVtLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncGgnKTtcclxuICAgICAgICBsZXQgZXF1aXZBdHRyaWIgPSAnSUNVJztcclxuICAgICAgICBpZiAocGFydC5pbmRleCgpID4gMCkge1xyXG4gICAgICAgICAgICBlcXVpdkF0dHJpYiA9ICdJQ1VfJyArIHBhcnQuaW5kZXgoKS50b1N0cmluZygxMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHBoRWxlbS5zZXRBdHRyaWJ1dGUoJ2lkJywgcGFydC5pbmRleCgpLnRvU3RyaW5nKDEwKSk7XHJcbiAgICAgICAgcGhFbGVtLnNldEF0dHJpYnV0ZSgnZXF1aXYnLCBlcXVpdkF0dHJpYik7XHJcbiAgICAgICAgY29uc3QgZGlzcCA9IHBhcnQuZGlzcCgpO1xyXG4gICAgICAgIGlmIChkaXNwKSB7XHJcbiAgICAgICAgICAgIHBoRWxlbS5zZXRBdHRyaWJ1dGUoJ2Rpc3AnLCBkaXNwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHBoRWxlbTtcclxuICAgIH1cclxuXHJcbn1cclxuIl19