"
);
dialog.find(".js-insert-link-button").text(__tr(["Add link"], undefined, "en", [])).click(function () {
var linkUrl = $(this).parent().find("input").val();
linkUrl = linkUrl.replace(/^https:\/\/(https?|ftp):\/\//, '$1://');
if (!/^(?:https?|ftp):\/\//.test(linkUrl))
linkUrl = 'https://' + linkUrl;
onClosingInlineDialog = null;
closeInlineDialog();
callback(linkUrl);
return false;
}).end().insertAfter(buttonBar).hide().slideDown(100).find("input").val("https://").keydown(function (e) {
if (e.which === _constants_mod__WEBPACK_IMPORTED_MODULE_0__.KEY_CODE.ENTER) {
dialog.find(".js-insert-link-button").click();
return false;
}
});
$("#wmd-input" + postfix).prop("disabled", true);
// If this is done synchronously, Safari and Edge will not correctly focus the element (in Safari it'll have focus styling, but
// it won't have actual keyboard focus; in Edge it doesn't do anything). Reason for this is unclear (the fact that the dialog is
// initially hidden seems not related). I'm filing it under "Edge is an Edge case" and "Safari is the new IE".
// In all fairness, it actually works fine in IE.
setTimeout(function () {
var input = dialog.find("input");
input.caret(0, 8);
input.focus();
}, 0)
onClosingInlineDialog = function () { callback(null); }
afterOpeningInlineDialog(dialog);
return true;
});
editor.hooks.set("insertImageDialog", function (callback) {
var button = $("#wmd-image-button" + postfix);
beforeOpeningInlineDialog(button);
var buttonBar = $("#wmd-button-bar" + postfix);
var dialog = $(
"
"
+ __tr(["Images are useful in a post, but make sure the post is still clear without them. If you post images of code or error messages, copy and paste or type the actual code or message into the post directly."], undefined, "en", [])
+ "
" +
(editorOptions.imageUploader.allowUrls
?
// these two are identical except for "or link" (but moonspeak requires literals even for the second argument)
__tr(["$browseStart$Browse$browseEnd$, drag & drop, or $pasteStart$paste$pasteEnd$ an image or link"], {browseStart: "",pasteStart: ""}, "en", [])
:
__tr(["$browseStart$Browse$browseEnd$, drag & drop, or $pasteStart$paste$pasteEnd$ an image"], {browseStart: "",pasteStart: ""}, "en", [])
) +
"
" +
// Unit is intentionally set to MiB, not MB. Please do not change the unit back (https://meta.stackexchange.com/q/346272)
"
"
);
dialog.insertAfter(buttonBar).hide().slideDown(100, function () {
var submitButton = dialog.find(".js-add-picture");
if (!submitButton.prop("disabled")) {
submitButton.focus();
} else {
setTimeout(function () {
$("#image-upload-file-input" + postfix).trigger("focus");
}, 100); // in FireFox, focusing immediately doesn't work reliably (even though this is the animation callback)
}
});
dialog.find(".js-url-input-container input").keydown(function (e) {
if (e.which === _constants_mod__WEBPACK_IMPORTED_MODULE_0__.KEY_CODE.ENTER) {
dialog.find(".js-add-picture").click();
return false;
}
});
var validationHandler = StackExchange.stacksValidation.handlerFor(dialog.find(".js-pseudo-input"));
var uploadInProgress = false;
$("#wmd-input" + postfix).prop("disabled", true);
var imageFile;
var objectURL;
var imageUrl;
function revokeExistingObjectURL() {
if (objectURL) {
URL.revokeObjectURL(objectURL);
objectURL = null;
}
}
var chosenType = "file";
setImageUrl = function (url) {
if (url && !editorOptions.imageUploader.allowUrls) {
return;
}
if (url && !/^https?:\/\//i.test(url)) {
url = "https://" + url;
}
validationHandler.clear();
validationHandler = StackExchange.stacksValidation.handlerFor($("#image-upload-url-input" + postfix));
revokeExistingObjectURL();
chosenType = "url";
imageUrl = url;
dialog.find(".js-image-upload-preview, .js-cta-container").addClass("d-none");
dialog.find(".js-url-input-container").removeClass("d-none").find("input").val(url).trigger("input").focus();
}
setImageFile = function (f) {
if (uploadInProgress) {
return;
}
validationHandler.clear();
validationHandler = StackExchange.stacksValidation.handlerFor(dialog.find(".js-pseudo-input"));
revokeExistingObjectURL();
chosenType = "file";
dialog.find(".js-url-input-container").addClass("d-none");
dialog.find(".js-cta-container").removeClass("d-none");
if (f) {
objectURL = URL.createObjectURL(f);
dialog.find(".js-image-upload-preview").attr("src", objectURL).removeClass("d-none");
//dialog.find(".js-image-upload-label").removeClass("d-none");
var tooBig = f.size >= 0x200000;
if (tooBig) {
// Unit is intentionally set to MiB, not MB. Please do not change the unit back (https://meta.stackexchange.com/q/346272)
validationHandler.add("error", __tr(["Your image is too large to upload (over 2 MiB)."], undefined, "en", []))
}
dialog.find(".js-add-picture").prop("disabled", tooBig).focus();
} else {
dialog.find(".js-image-upload-preview").removeAttr("src").addClass("d-none");
dialog.find(".js-add-picture").prop("disabled", true);
}
imageFile = f;
}
var cancelled = false;
onClosingInlineDialog = function () {
cancelled = true;
revokeExistingObjectURL();
callback(null);
}
if (fileOnLoad) {
setImageFile(fileOnLoad);
fileOnLoad = null;
}
var $fileInput = $("#image-upload-file-input" + postfix).on("change", function (evt) {
setImageFile(getImageFileFrom(evt));
});
$("#image-upload-url-input" + postfix).on("input", function () {
var disabled;
if (editorOptions.imageUploader.allowUrls) {
disabled = !$(this).val();
} else {
validationHandler.clear();
if ($(this).val()) {
validationHandler.add("error",
__tr(["Uploading images via web links is not supported on this site. Paste an image from the clipboard or $browseStart$browse$browseEnd$ files on your device."], {browseStart: ""}, "en", []));
}
}
dialog.find(".js-add-picture").prop("disabled", disabled);
});
dialog.find(".js-show-url-input").click(function () {
setImageUrl("");
return false;
});
dialog.find(".js-cancel-url").click(function () {
setImageFile(null);
return false;
})
dialog.find(".js-drop-target").on("drop", function (e) {
if (!uploadInProgress)
setImageFile(getImageFileFrom(e));
return false;
}).on("dragenter dragover", function (e) {
var validImage = dragEventContainsImage(e) !== "no";
e.originalEvent.dataTransfer.dropEffect = validImage && !uploadInProgress ? "copy" : "none";
return false;
});
dialog.find(".js-add-picture").on("click", function (e) {
e.preventDefault();
uploadInProgress = true;
validationHandler.clear();
var disabledInputs = $fileInput.add("#image-upload-url-input" + postfix).prop("disabled", true);
var formData = new FormData();
if (chosenType === "file") {
formData.append('file', imageFile);
} else {
setImageUrl($("#image-upload-url-input" + postfix).val());
formData.append("uploadUrl", imageUrl);
}
var $button = $(this).addClass("is-loading").prop("disabled", true);
formData.append('fkey', StackExchange.options.user.fkey);
$.ajax({
url: '/upload/image',
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST'
}).done(function (result) {
if (cancelled) {
return;
}
if (result.Success) {
var linkUrl = result.UploadedImage;
onClosingInlineDialog = null;
revokeExistingObjectURL();
closeInlineDialog();
callback(linkUrl);
} else if (result.ErrorMessage) {
validationHandler.add("error", $("").text(result.ErrorMessage).html());
} else {
validationHandler.add("error", __tr(["An error occurred when uploading the image."], undefined, "en", []));
}
}).fail(function (req, textStatus, errorThrown) {
validationHandler.add("error", __tr(["An error occurred when uploading the image: $message$"], {message: errorThrown}, "en", []));
}).always(function () {
$button.removeClass("is-loading").prop("disabled", false);
disabledInputs.prop("disabled", false);
uploadInProgress = false;
});
});
afterOpeningInlineDialog(dialog);
return true;
});
return {
closeInlineDialog: closeInlineDialog
}
}
////////////////////////////////
// //
// MATHJAX STUBS //
// //
////////////////////////////////
if (typeof MathJax !== 'undefined') {
var config = MathJax.Hub.config;
var loaded = false;
var loadCallbacks = $.Callbacks();
var prepareEditor = function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, config.tex2jax.inlineMath);
};
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
if (loaded) {
prepareEditor(editor, postfix);
} else {
loadCallbacks.add(function () { prepareEditor(editor, postfix); editor.refreshPreview(); });
}
});
StackExchange.using(config.SEEditor, function () {
loaded = true;
loadCallbacks.fire();
loadCallbacks.empty();
}, "mathjax-editing");
}
////////////////////////////////
// //
// ONEBOX //
// //
////////////////////////////////
var scheduledOnebox;
function createOnebox(jPreview) {
clearTimeout(scheduledOnebox);
inlineOnebox(jPreview);
}
function inlineOnebox(jPreview) {
$(jPreview).find('p > a:not(a:has(img))').each(function () {
var $previewLink = $(this);
var href = $(this).attr('href');
// GD: We only want oneboxes for raw urls on their own line
// Modifications to the client site preview must match the server side baking
//
var paragraphText = $previewLink.closest('p').text().trim();
if (href != paragraphText) return;
if (!oneboxMatch.hasOwnProperty(href)) {
$previewLink.parent().addSpinner({ 'padding-left': '3px' });
scheduledOnebox = setTimeout(resolveOnebox, 1000, $previewLink.parent(), href);
} else {
$previewLink.parent().html(oneboxMatch[href]);
}
});
}
function resolveOnebox(element, href) {
$.post(
'/posts/onebox',
{
url: href,
fkey: StackExchange.options.user.fkey
})
.done(function (data) {
if (data.success) {
oneboxMatch[href] = data.data;
element.html(oneboxMatch[href]);
if (data.poll) {
element.addSpinner({ 'padding-left': '3px' });
setTimeout(resolveOnebox, 3000, element, href);
}
} else {
oneboxMatch[href] = data.data;
element.removeSpinner();
}
});
}
})();
/***/ }),
/***/ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/02_EditorInitialization.js":
/*!*************************************************************************************!*\
!*** ./_Scripts/LegacyJS/markdown/MarkdownStackExchange/02_EditorInitialization.js ***!
\*************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _constants_mod__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants.mod */ "./_Scripts/LegacyJS/constants.mod.js");
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
// Post Editor scripts
StackExchange.editor = (function () {
var init = function (options) {
options = options || {};
var postfix = options.postfix || "";
var resize = options.resize === undefined ? true : options.resize;
var heartbeatType = options.heartbeatType, //when null/empty, no heartbeat
bindNavPrevention = options.bindNavPrevention,
jForm = $('#post-form' + postfix),
jWmd = $("#wmd-input" + postfix),
jEntryFields, jOverlayedFields;
jOverlayedFields = $("#title, #edit-comment, #m-address, .edit-comment"); // the tag editor takes care of its overlay
jEntryFields = jOverlayedFields.add(".tag-editor input"); // TODO check timing
// validate form before submission
jForm.submit(function () {
// Give other listeners a chance to prevent submission and the below side-effects.
var event = $.Event('post:will-submit');
jForm.trigger(event);
if (event.isDefaultPrevented()) {
return false;
}
StackExchange.helpers.disableSubmitButton(jForm); // THIS IS IMPORTANT. If we don't have this, users will double click and SUBMIT TWICE!
StackExchange.navPrevention.pause(); // unbind the onbeforeunload handler to allow proper submission
return true;
});
if (resize) {
$(".original-question").not(".processed").TextAreaResizer();
jWmd.not(".processed").TextAreaResizer();
}
jWmd.typeWatch({ highlight: false, wait: 5000, captureLength: 5, callback: styleCode });
var wmd = new StackExchange.MarkdownEditor(options);
if (heartbeatType) {
var discardLink = options.discardSelector ? $(options.discardSelector) : null;
StackExchange.cardiologist.addHeart(heartbeatType, jWmd, wmd, discardLink, options.postId, options.autoActivateHeartbeat);
}
wmd.hooks.chain("imageConvertedToLink", function () {
var jContainer = jWmd.parent();
var msg = __tr(["You're not allowed to embed images in your posts yet, so we've included a link instead."], undefined, "en", []);
if (options.reputationToPostImages) {
msg += '
' + __tr(["As soon as you earn $rep$ reputation on the site, you'll be able to embed images."], {rep: options.reputationToPostImages}, "en", []);
}
StackExchange.helpers.showInfoMessage(
jContainer,
msg,
{
position: {
at: "right top",
my: "left bottom"
},
cssClass: "convert-image-to-link"
}
);
});
// when focusing inputs, load the javascript anti-spam field
if (heartbeatType == 'ask' || heartbeatType == 'answer') {
var fields = jWmd.add(jEntryFields);
var loadTicks = function () {
StackExchange.helpers.loadTicks(jForm);
fields.unbind("keydown", loadTicks);
return true;
};
fields.bind("keydown", loadTicks);
}
// once a new post is started, bind a handler to prevent form loss via accidential navigation
if (bindNavPrevention) {
var navPreventionFields = (heartbeatType == 'edit' || heartbeatType == 'ask')
? jWmd.add('#title').add('#tagnames')
: jWmd;
StackExchange.navPrevention.init(navPreventionFields);
}
jForm
.find('.js-wmd-preview')
.click(
function (evt) {
if (evt.target.className === "show-hide" || evt.target.localName.startsWith("input"))
return;
if (window.getSelection) {
var selection = window.getSelection();
if ((selection.anchorNode !== selection.focusNode) || (selection.anchorOffset !== selection.focusOffset))
return;
}
if (evt.which != _constants_mod__WEBPACK_IMPORTED_MODULE_0__.KEY_CODE.MIDDLE_MOUSE) { // 2 = middle click
$(this).siblings().find('textarea').focus();
}
}
);
// set the focus if user hasn't focused anything yet
if ($("#ask-page-has-errors").length == 0 && $("#title").is("input") && jForm.find(':focus').length === 0) {
//$("#title").focus();
}
if (options.onCreated) options.onCreated(wmd);
// Hook up the "discard" draft link, if present
if (options.discardSelector && (heartbeatType == 'ask' || heartbeatType == 'answer' || heartbeatType == 'moderatormessage' || heartbeatType == 'article')) {
var discard = $(options.discardSelector);
discard.click(
function (e) {
e.preventDefault();
if (!confirm(__tr(["Are you sure you want to discard your draft?"], undefined, "en", []))) {
return;
}
// blur the fields after clearing them to trigger removal of any validation errors
$('#title').val('').blur();
$('#question-suggestions').empty();
// discard answer box on question ask
$('#wmd-input-42').val('');
$('#wmd-preview-42').html('');
// uncheck Answer your own question
$('.js-post-answer-while-asking-checkbox').filter(':visible').filter(':checked').click();
var tags = (heartbeatType == 'article') ? $(".js-edit-article-form #tagnames") : discard.closest('.post-form').find('#tagnames');
if (tags.length > 0 && tags[0].func_clear) {
tags[0].func_clear();
tags.blur();
}
jWmd.val('').blur();
wmd.refreshPreview();
$.post(
'/post/discard-draft',
{ fkey: StackExchange.options.user.fkey, postType: heartbeatType },
function () {
$('#draft-saved').hide();
$('#draft-discarded').show();
var hideDiscard = null;
hideDiscard = function () {
$('#draft-discarded').hide();
$('#title').unbind('keypress', hideDiscard);
jWmd.unbind('keypress', hideDiscard);
};
$('#title').bind('keypress', hideDiscard);
jWmd.bind('keypress', hideDiscard);
}
);
discard.hide();
if (options.onDraftDiscarded) {
options.onDraftDiscarded();
}
return false;
}
);
}
// community wiki can accidentally be enabled - inform users of this nuclear option
StackExchange.bindCommunityWikiConfirmation($('.js-post-editor'));
}; // END init
// this behavior is *not* ready for multiple editors (but that doesn't currently matter, since it's only relevant
// to the in-page rendered answer-editor and the answer-on-ask editor, so at most one editor will be hidden).
var initIfShown = function (options) {
// sometimes, the editor is hidden (e.g. question askers on their question page, mobile devices, answer-on-ask)
var postfix = (options || {}).postfix || "";
var initnow =
$("#wmd-preview" + postfix).length != 0 // there is an editor in the first place,
&& (postfix !== "-42" || $('.js-post-answer-while-asking-checkbox').length === 0) // and it's not the answer-on-ask editor
&& $("#show-editor-button" + postfix).length === 0; // and there's no "really wanna answer this question" button
if (initnow) {
init(options);
if (!StackExchange.editor.finallyInit) // don't overwrite if it's already there (https://meta.stackexchange.com/q/112004)
StackExchange.editor.finallyInit = function () { };
} else {
StackExchange.editor.finallyInit = function () { init(options); } // called after the user has confirmed they want to answer
}
};
return {
init: init,
initIfShown: initIfShown
}
})();
/***/ }),
/***/ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/03_Heartbeat.js":
/*!**************************************************************************!*\
!*** ./_Scripts/LegacyJS/markdown/MarkdownStackExchange/03_Heartbeat.js ***!
\**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _constants_mod__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants.mod */ "./_Scripts/LegacyJS/constants.mod.js");
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
// When users are entering an answer, heartbeat will call back to parent question for status updates, e.g. "1 new answer", "question is closed",
// when they edit, it checks for concurrent edits by other users.
// It also handles drafts.
//
// There can be several hearts in a page; one per editor. They all start out as inactive. A heart is
// activated by a keypress event in the corresponding editor. At most one heart is the [master] heart, namely
// the one whose editor received the last keypress event. Only the master heart sends the editor content
// to the server for saving as draft and/or similar questions finding.
//
// The beat queue starts out empty, and it is emptied every time the master heart changes. When filling the
// queue, the master heart is inserted first; all other hearts are inserted in order of their activation. A heart
// (whether master or not) is not inserted if it has beaten 30 times.
// The queue interval X is set to 60 divided by N (where N is the number of hearts in the queue), capped between 15 and 45.
//
// The first time a heart is activated, a timer of 45 seconds is started; after it has elapsed, the queue handler is called.
//
// Queue handler
// -------------
// If the queue handler finds the queue empty, it is repopulated, and X is set accordingly (in particular, on the first call).
// The handler takes the first heart from the queue. It makes the ping to the server (including the editor
// content iff it is the master heart and has a type != "edit").
//
// If the request returns successfully, the result is handled, and Y is set to zero.
//
// If it causes an error, Y is set to a random number between 0 and 10. The heart is *prepended* to the queue iff it is the master heart.
//
// In both cases, a new timer is started with a timeout of X + Y seconds.
StackExchange.cardiologist = (function () { // I would have called it "heartbeatManager", but the boss doesn't like that: http://www.codinghorror.com/blog/2006/03/i-shall-call-it-somethingmanager.html
var activeHearts = [],
masterHeart,
queue = [],
previousDraft,
previousRelated,
defaultQueueInterval = 45,
customHeartbeatInterval = defaultQueueInterval,
queueInterval = defaultQueueInterval,
intervalDelta = 0,
hasBeenNotifiedOfNewAnswer = false,
notifyMessageTypeId = -2,
defaultMaxHeartbeatCount = 30,
lastPingTime, timeoutId;
function startTimeout(intervalOverrideMs) {
var delay = (typeof intervalOverrideMs === "number") ? intervalOverrideMs : (queueInterval + intervalDelta) * 1000;
if (lastPingTime)
delay = Math.max(delay, 6000 - (new Date().getTime() - lastPingTime)); // the heartbeat route is throttled to 5 seconds -- so we don't want to be too fast!
if (timeoutId)
clearTimeout(timeoutId)
timeoutId = setTimeout(handleQueue, delay);
}
function handleQueue() {
timeoutId = null;
if (!queue.length)
populateQueue();
if (!queue.length) {
startTimeout();
return;
}
var heart = queue.shift();
if (heart.checkActive())
heart.beat();
else
startTimeout();
}
function populateQueue() {
var heart;
queue = [];
if (masterHeart && !masterHeart.isDisabled && masterHeart.beatCount < masterHeart.maxHeartbeatCount)
queue.push(masterHeart)
for (var i = 0; i < activeHearts.length; i++) {
heart = activeHearts[i];
if (heart != masterHeart && !heart.isDisabled && heart.beatCount < heart.maxHeartbeatCount) {
queue.push(heart);
}
}
// for multiple heartbeats, we should attempt to stagger them a bit
// e.g. 1 heart = 45s interval, 2 = 30s, 3 = 20s, 4 = 15s, 5 = 15s, ...
const multipleHeartsInterval = customHeartbeatInterval + (customHeartbeatInterval / 3);
queueInterval = Math.max(15, Math.min(customHeartbeatInterval, multipleHeartsInterval / (queue.length || 1)));
}
/**
* Check if the passed editor is a Stacks-Editor instance so we can alter our behavior to match
* @param {any} editor
*/
function isStacksEditor(editor) {
return "content" in editor;
}
var resultHandlers = {
ask: function (json) {
if (json.relatedQuestions) {
var similarQuestions = $(".js-similar-questions");
similarQuestions.empty().append(json.relatedQuestions);
StackExchange.gps.bindTrackClicks($('.js-similar-questions-data-track'));
$('.js-similar-questions-outer-div').removeClass('d-none');
$('.js-question-summary-scroll').one('scroll', function () {
StackExchange.using("gps", function () { StackExchange.gps.track("similarquestions.body_scroll"); });
});
}
if (json.suggestedTags && StackExchange.tagSuggestions) {
StackExchange.tagSuggestions.suggest(json.suggestedTags);
}
},
answer: function (json, heart) {
if (json && !hasBeenNotifiedOfNewAnswer) {
if (json.disableEditor) {
StackExchange.notify.show(json.message, notifyMessageTypeId);
hasBeenNotifiedOfNewAnswer = true;
}
else { // server will return the difference in client-loaded answers and what exists on server
var count = parseInt(json.message);
if (count > 0) {
var msg2 = __tr(["$count$ new answer has been posted - $startAnchor$load new answers.$endAnchor$","$count$ new answers have been posted - $startAnchor$load new answers.$endAnchor$"], {count: count,startAnchor: '',endAnchor: ''}, "en", ["count"]);
StackExchange.notify.show(msg2, notifyMessageTypeId);
hasBeenNotifiedOfNewAnswer = true;
$("#load-new-answers").click(function () { updateAnswers(heart.postId); });
}
}
}
},
edit: function (json) {
if (json && json.message) {
var old = StackExchange.notify.getMessageText(notifyMessageTypeId);
if (old != $("").html(json.message).text()) {
StackExchange.notify.close(notifyMessageTypeId);
StackExchange.notify.show(json.message, notifyMessageTypeId);
}
}
},
moderatormessage: function (json) {
// does nothing, by design
},
article: function (json) {
// does nothing, by design
}
};
function Heart() { };
Heart.prototype = {
activate: function () {
masterHeart = this;
if (this.isActive)
return;
this.isActive = true;
this.beatCount = 0;
activeHearts.push(this);
if (activeHearts.length === 1) // it's the first one
startTimeout();
},
checkActive: function () {
if (!this.isActive || this.isDisabled)
return false;
if (!this.jTextarea.closest("body").length) { // removed from the DOM
delete this.jTextarea;
this.isDisabled = true;
return false;
}
return true;
},
beat: function (onlyIfSavingDraft) {
var that = this,
options = {
type: 'POST',
url: '/posts/' + this.postId + '/editor-heartbeat/' + this.type,
dataType: 'json',
data: { fkey: StackExchange.options.user.fkey }
};
if (!onlyIfSavingDraft) {
options.success = function (json) { that.success(json); };
options.error = function () { that.error(); };
options.complete = function () { that.complete(); };
}
if (this.shouldSendDraft()) {
var editorValue = this.jTextarea.val();
var data = {
text: editorValue
};
if (this.type === "ask") {
data.title = $('#title').val();
data.tagnames = $('#tagnames').val();
data.answertext = $('#wmd-input-42').val();
};
if (this.type === "article") {
data.title = $('#title').val();
data.tagnames = $('#tagnames').val();
data.articletype = $('input[name="articleType"]:checked').val();
//subcommunity article
let subcommunitySlugSelector = $('#js-subcommunity-slug');
let postStateSelector = $('#js-post-state');
let editorUserIdsSelector = $('.js-editor-usersids');
if (subcommunitySlugSelector.val()) {
data.subcommunitySlug = subcommunitySlugSelector.val();
data.postState = postStateSelector.val();
//only pass on new article, subsequent edits are done via ajax
if (this.postId === 0) {
data.editorUserIdsRaw = editorUserIdsSelector.val();
}
}
}
if (!previousDraft
|| previousDraft.heart !== this
|| previousDraft.title !== data.title
|| previousDraft.tagnames !== data.tagnames
|| previousDraft.text !== data.text
|| previousDraft.answertext !== data.answertext
) {
options.data = data;
previousDraft = {
heart: this,
title: data.title,
tagnames: data.tagnames,
text: data.text,
answertext: data.answertext
};
}
}
if (onlyIfSavingDraft && !("text" in options.data)) {
return $.Deferred().resolve().promise();
}
if (this.revisionGuid) {
options.data.clientRevisionGuid = this.revisionGuid;
}
if (this.type === "answer") {
// when answers are present, we'll have a header "3 Answers"
var h2 = $('#answers-header .answers-subheader h2');
var clientCount = h2.data('answercount');
if (clientCount == null)
{
// try to parse from html
clientCount = h2.text().replace(/ answers?/i, '') || '0';
}
options.data.clientCount = clientCount;
}
options.data.fkey = StackExchange.options.user.fkey;
lastPingTime = new Date().getTime();
return $.ajax(options).always(function (data) {
const event = new CustomEvent('heartbeat', { detail: data });
that.jTextarea.get(0).dispatchEvent(event);
}).promise();
},
shouldSendDraft: function () {
return this.type !== "edit" && masterHeart === this;
},
success: function (json) {
resultHandlers[this.type](json, this);
if (json.disableEditor) {
if (isStacksEditor(this.editor)) {
this.editor.disable();
}
else {
this.editor.disableSubmission();
}
this.isDisabled = true;
}
if (json.draftSaved) {
informDraftSaved(this.jTextarea, this.discardDraftLink);
//subcommunity article
if (this.type == 'article' && $('#js-subcommunity-slug').val()) {
this.postId = json.postId;
this.revisionGuid = json.revisionGuid;
}
}
this.beatCount++;
intervalDelta = 0;
},
error: function () {
$('#draft-saved').hide();
if (masterHeart === this)
queue.unshift(this);
intervalDelta = (new Date().getTime() % 100) / 10;
},
complete: function () {
startTimeout();
}
};
// Note: This functionality doesn't handle multiple editors yet; which is fine until we start
// saving drafts for edits.
var informDraftSaved = function (jWmd, discardLink) {
var jDraft = $('#draft-saved');
var inform = function () {
jDraft.text(__tr(["Draft saved"], undefined, "en", [])).fadeIn('fast');
};
if (jDraft.is(':visible')) {
jDraft.fadeOut('fast', inform);
}
else {
inform();
}
if (discardLink) {
discardLink.removeClass('dno').removeClass('d-none').show();
}
var hideDraftSaved = function (event) {
if (event.which != _constants_mod__WEBPACK_IMPORTED_MODULE_0__.KEY_CODE.F4 /*F4*/ || !event.ctrlKey || event.shiftKey || event.altKey) {
jWmd.unbind('keypress', hideDraftSaved);
$('#draft-saved').fadeOut('fast');
}
};
jWmd.bind('keypress', hideDraftSaved);
$('#draft-discarded').hide();
};
function updateAnswers(postId) {
var divIdsToAdd = [];
// For now (naively), fetch the entire page again..
$.get('/questions/' + postId, function (html) {
var jHtml = $(html);
jHtml.find('div.answer').each(function () {
var id = this.id.substring('answer-'.length);
if ($('#answer-' + id).length == 0) {
divIdsToAdd.push(this.id);
}
});
if (divIdsToAdd.length > 0) {
var selector = '#' + divIdsToAdd.join(',#');
var divs = jHtml.find(selector);
var appendAfter = $('div.answer:last');
if (appendAfter.length == 0)
appendAfter = $('#answers-header');
divs.hide();
appendAfter.after(divs);
divs.fadeIn('slow');
// update the answer count...
var newH2 = jHtml.find('#answers-header .answers-subheader h2'), oldH2 = $('#answers-header .answers-subheader h2');
if (newH2.length && oldH2.length)
{
oldH2.replaceWith(newH2);
}
// Rebind all click handlers on page..
StackExchange.vote.init(postId);
StackExchange.comments.init({ post: divs });
}
StackExchange.notify.close(notifyMessageTypeId);
hasBeenNotifiedOfNewAnswer = false;
}, 'html');
}
function addHeart(type, jTextarea, editor, discardDraftLink, editId, autoActivateHeartbeat, maxHeartbeatCount, heartbeatInterval) {
var heart = new Heart(),
postId;
heart.type = type;
heart.jTextarea = jTextarea;
heart.discardDraftLink = discardDraftLink;
heart.maxHeartbeatCount = maxHeartbeatCount || defaultMaxHeartbeatCount;
//Overriden with each heart, queueInterval is recalculated on each beat so we also save to customHeartbeatInterval to keep original val
customHeartbeatInterval = heartbeatInterval || defaultQueueInterval;
queueInterval = heartbeatInterval || defaultQueueInterval;
switch (type) {
case "ask":
postId = 0;
break;
case "stagingground":
postId = 0;
break;
case "article":
postId = editId;
let revisionGuidSelector = $('#client-revision-guid');
if (revisionGuidSelector.val()) {
heart.revisionGuid = revisionGuidSelector.val();
}
break;
case "answer":
postId = $('#post-id').val() || location.href.match(/\/questions\/(\d+)/i)[1];
break;
case "edit":
postId = editId || $('#post-id').val() || jTextarea.closest('.question, .answer').find('.vote input').val();
var inline = jTextarea.closest('.inline-post');
var revisionGuid = null;
if (inline.length > 0) {
revisionGuid = inline[0].action.split('/').pop();
}
if (!revisionGuid) {
revisionGuid = $('#client-revision-guid').val();
}
heart.revisionGuid = revisionGuid;
break;
case "moderatormessage":
postId = +$("#moderator-message-to-user").attr('data-userid');
break;
}
heart.postId = postId;
heart.editor = editor;
jTextarea.on("keypress paste input", function () { heart.activate(); });
if (autoActivateHeartbeat) {
heart.activate();
}
}
// TODO: The name of this method really implies onlyIfSavingDraft=true; check whether any use of it assumes differently
function ensureDraftSaved(callback, onlyIfSavingDraft) {
if (!masterHeart || !masterHeart.checkActive()) {
callback();
return;
}
masterHeart.beat(onlyIfSavingDraft).done(callback);
}
function beatASAP() {
startTimeout(1);
}
function notifiedOfNewAnswer() {
hasBeenNotifiedOfNewAnswer = true;
}
function isHeartBeating() {
if (activeHearts == null) return false;
for (var i = 0; i < activeHearts.length; i++) {
if (activeHearts[i].checkActive() == true) {
return true;
}
}
return false;
}
return { addHeart: addHeart, ensureDraftSaved: ensureDraftSaved, beatASAP: beatASAP, notifiedOfNewAnswer: notifiedOfNewAnswer, isHeartBeating: isHeartBeating };
})();
/***/ }),
/***/ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/04_NavPrevention.js":
/*!******************************************************************************!*\
!*** ./_Scripts/LegacyJS/markdown/MarkdownStackExchange/04_NavPrevention.js ***!
\******************************************************************************/
/***/ (() => {
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
// TODO: This can't handle multiple editors in a page yet
StackExchange.navPrevention = (function () {
var _jInput, origContents, editorInstance, origEditorContents;
// returns true if any of the input elements' contents have changed
var actualChange = function () {
var result = false;
_jInput.each(function (index) {
result = result || ($(this).val().replace(/\s+$/g, '') !== origContents[index].replace(/\s+$/g, '')); // ignore trailing whitespace
});
if (editorInstance) {
result = result || (editorInstance.content.replace(/\s+$/g, '') !== origEditorContents.replace(/\s+$/g, ''));
}
return result;
}
var setConfirmUnload = function (message) {
// when message is null, unbind, otherwise also check that our input has actually been changed before showing the confirm unload message
window.onbeforeunload = message ? function () { if (_jInput && actualChange()) return message; } : null;
}
var handler = function (evt) {
setConfirmUnload(__tr(["You have started writing or editing a post."], undefined, "en", []));
};
var update = function () {
if (!_jInput)
return;
origContents = [];
_jInput.each(function () { origContents.push($(this).val()); });
if (editorInstance) {
origEditorContents = editorInstance.content;
}
}
return {
init: function (jInput, stacksEditorInstance) {
_jInput = jInput.one("keypress", handler);
origContents = [];
if (stacksEditorInstance && "content" in stacksEditorInstance) {
$(stacksEditorInstance.target).one("keypress", handler);
editorInstance = stacksEditorInstance;
}
update();
},
start: function() {
if (_jInput) {
handler();
}
},
stop: function () {
if (!_jInput)
return;
_jInput.unbind("keypress", handler);
setConfirmUnload(null);
_jInput = null;
},
pause: function () {
if (_jInput) {
setConfirmUnload(null);
}
},
confirm: function (message) {
if (_jInput && actualChange())
return confirm(message);
return true;
},
hasChange: function () {
return _jInput && actualChange();
},
update: update
};
})();
/***/ }),
/***/ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/10_TextareaResizerPlugin.js":
/*!**************************************************************************************!*\
!*** ./_Scripts/LegacyJS/markdown/MarkdownStackExchange/10_TextareaResizerPlugin.js ***!
\**************************************************************************************/
/***/ (() => {
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
// BEGIN: jquery.textarearesizer.js
/*
jQuery TextAreaResizer plugin
Created on 17th January 2008 by Ryan O'Dell
Version 1.0.4
Converted from Drupal -> textarea.js
Found source: http://plugins.jquery.com/misc/textarea.js
$Id: textarea.js,v 1.11.2.1 2007/04/18 02:41:19 drumm Exp $
1.0.1 Updates to missing global 'var', added extra global variables, fixed multiple instances, improved iFrame support
1.0.2 Updates according to textarea.focus
1.0.3 Further updates including removing the textarea.focus and moving private variables to top
1.0.4 Re-instated the blur/focus events, according to information supplied by dec
1.0.5 Fixed a bug in dynamic html and IE7 - Geoff Dalgas
*/
(function ($) {
/* private variable "oHover" used to determine if you're still hovering over the same element */
var textarea, staticOffset; // added the var declaration for 'staticOffset' thanks to issue logged by dec.
var iLastMousePos = 0;
var iMin = 32;
var grip;
/* TextAreaResizer plugin */
$.fn.TextAreaResizer = function () {
return this.each(function () {
textarea = $(this).addClass('processed');
staticOffset = null;
// 18-01-08 jQuery bind to pass data element rather than direct mousedown - Ryan O'Dell
// When wrapping the text area, work around an IE margin bug. See:
// http://jaspan.com/ie-inherited-margin-bug-form-elements-and-haslayout
$(this).parent().append($('').bind("mousedown", { el: this }, startDrag));
var grippie = $('div.grippie', $(this).parent())[0];
grippie.style.marginRight = (grippie.offsetWidth - $(this)[0].offsetWidth) + 'px';
});
};
/* private functions */
function startDrag(e) {
textarea = $(e.data.el);
textarea.blur();
iLastMousePos = mousePosition(e).y;
staticOffset = textarea.height() - iLastMousePos;
$(document).mousemove(performDrag).mouseup(endDrag);
return false;
}
function performDrag(e) {
var iThisMousePos = mousePosition(e).y;
var iMousePos = staticOffset + iThisMousePos;
if (iLastMousePos >= (iThisMousePos)) {
iMousePos -= 5;
}
iLastMousePos = iThisMousePos;
iMousePos = Math.max(iMin, iMousePos);
textarea.height(iMousePos + 'px');
if (iMousePos < iMin) {
endDrag(e);
}
return false;
}
function endDrag(e) {
$(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag);
textarea.focus();
textarea = null;
staticOffset = null;
iLastMousePos = 0;
}
function mousePosition(e) {
return { x: e.clientX + document.documentElement.scrollLeft, y: e.clientY + document.documentElement.scrollTop };
}
})(jQuery);
// END: jquery.textarearesizer.js
/***/ }),
/***/ "./_Scripts/LegacyJS/post-validation.js":
/*!**********************************************!*\
!*** ./_Scripts/LegacyJS/post-validation.js ***!
\**********************************************/
/***/ (() => {
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
StackExchange.postValidation = (function () {
var onAskPageV2 = $('body').hasClass('js-ask-page-v2');
var onAskWizard = $('body').hasClass('js-staging-ground-wizard');
// These correspond to different values of PostValidationErrorLocation
var TitleField = 'Title';
var BodyField = 'Body';
var TagsField = 'Tags';
var MentionsField = 'Mentions';
var EditCommentField = 'EditComment';
var ExcerptField = 'Excerpt';
var EmailField = 'Email';
var GeneralField = 'General';
var ArticleTypeField = 'ArticleType';
var DateField = 'Date';
var CommentFormField = 'CommentForm';
var SubtitleField = 'Subtitle';
var CtaLabelField = 'CtaLabel';
var CtaUrlField = 'CtaUrl';
var TargetUrlField = 'TargetUrl';
// This is used for `.data()` on form fields to disable re-validation on blur until a change
// has been made. For example, an empty title field is an error on submission validation, but okay
// on blur validation. If you try to submit an empty title, the validation error message shouldn't
// disappear until you've actually made a change.
const DISABLE_BLUR_VALIDATION_KEY = "disable-blur-validation";
// This selects the input in the container that are actual form elements `` and such that will be sent to the server.
function getFormInput($container, postTypeId, property) {
var fieldSelectors = {
'Title': '.js-post-title-field',
'Body': '.js-post-body-field[data-post-type-id=' + postTypeId + ']', // use postTypeId to handle "Answer your own question"
'Tags': '.js-post-tags-field',
'Mentions': '.js-post-mentions-field',
'EditComment': '.js-post-edit-comment-field', // must match regular edit comments, as well as tag wiki edit comments
'Excerpt': '.js-post-excerpt-field',
'Email': '.js-post-email-field',
'ArticleType': '.js-article-type-field',
'Date': '.js-post-date-field',
'CommentForm': '.js-comment-text-input',
'Subtitle': '.js-post-subtitle-field',
'CtaLabel': '.js-post-cta-label-field',
'CtaUrl': '.js-post-cta-url-field',
'TargetUrl' : '.js-target-url',
};
var $el = fieldSelectors[property]
? $container.find(fieldSelectors[property])
: $();
return $el
}
// This selects the visual representation of a form element that the user will interact with. For the most part they are the same,
// but for tag and mention fields, they will be the tag editor component.
function getVisibleField($container, postTypeId, property) {
var $el = getFormInput($container, postTypeId, property);
if (property === TagsField || property === MentionsField) {
return $container.find('.js-tag-editor').filter(function () {
return $(this).data('target-field') === $el.get(0);
});
} else {
return $el;
}
}
var blurTimeoutIds = [];
var blurTimeoutDelay = 250;
function initOnBlur($container, postTypeId, formType, isSuggestedEdit) {
// Temporarily disable all submit buttons while we wait for the tag editor to load.
const $submit = $container.find('input[type="submit"]:visible, button[type="submit"]:visible');
const wasEnabled = $submit.filter(":enabled");
wasEnabled.prop('disabled', true);
initTitleValidation($container, postTypeId, formType);
initBodyValidation($container, postTypeId, formType, isSuggestedEdit);
initEditCommentValidation($container, postTypeId, formType);
initExcerptValidation($container, postTypeId, formType);
initEmailValidation($container, postTypeId, formType);
whenTagEditorIsDoneLoading($container, postTypeId, function () {
initTagsValidation($container, postTypeId, formType);
wasEnabled.prop('disabled', false);
});
}
function initOnBlurAndSubmit($form, postTypeId, formType, isSuggestedEdit, optionalSuccessCallback) {
initOnBlur($form, postTypeId, formType, isSuggestedEdit);
var submitCallback = function (json) {
let isRedirecting = false;
$form.trigger('post:submit-completed', [{
formType: formType,
postTypeId: postTypeId,
response: json,
}]);
if (json.success) {
if (optionalSuccessCallback) {
optionalSuccessCallback(json);
} else {
var from = window.location.href.split('#')[0];
var to = json.redirectTo.split('#')[0];
if (to.indexOf('/') === 0) {
to = window.location.protocol + '//' + window.location.hostname + to;
}
// We already called navPrevention.pause() but Safari is still getting the popup.
// Let's blast this and hope for the best.
window.onbeforeunload = null;
isRedirecting = true;
window.location = json.redirectTo;
// When redirecting to the same url (or a different url, differing only by the hash) such as the case with #autocomment,
// we need to explicitly reload the page, since setting window.location alone won't do the trick.
if (from.toLowerCase() === to.toLowerCase()) {
window.location.reload(true);
}
}
} else if (json.captchaHtml) {
StackExchange.nocaptcha.init(json.captchaHtml, submitCallback);
} else if (json.errors) {
$form.find('.js-post-prior-attempt-count').val(function(_, val) {
return ((+val + 1) || 0).toString();
});
showErrorsAfterSubmission($form, postTypeId, formType, json.errors, json.warnings);
}
else {
showSubmissionErrorMessage($form, postTypeId, formType, { General: [$('').text(json.message).html()] }, 0);
}
cleanUpAfterSubmit($form, isRedirecting);
};
$form.submit(function (submitEvent) {
if ($form.find('.js-post-answer-while-asking-checkbox').is(':checked')) {
return true; // don't ajaxify answering while asking
}
if (rejectSystemEditComment($form, postTypeId, formType)) {
StackExchange.helpers.enableSubmitButton($form);
return false;
}
clearBlurTimeouts();
if (StackExchange.navPrevention) {
StackExchange.navPrevention.stop();
}
$form.find('input[type="submit"]:visible, button[type="submit"]').addClass('is-loading');
StackExchange.helpers.disableSubmitButton($form);
// we don't allow tag creation for announcements or discussions
if (StackExchange.options.site.enableNewTagCreationWarning && postTypeId != 14 && postTypeId != 15) {
var $tags = getFormInput($form, postTypeId, TagsField);
var oldtags = $tags.prop('defaultValue');
if ($tags.val() !== oldtags) {
$.ajax({
type: 'GET',
url: '/posts/new-tags-warning',
dataType: 'json',
data: {
tags: $tags.val()
},
success: function(json) {
if (json.showWarning) {
var modalSettings = {
closeOthers: true,
shown: function () {
$('.js-confirm-tag-creation').on('click', function (e) {
// Use 'submit' as the close trigger so that we can detect it in dismissing() below
StackExchange.helpers.closePopups(null, "submit");
doSubmit($form, postTypeId, formType, submitCallback, submitEvent);
e.preventDefault();
return false;
});
},
dismissing: function (closeTrigger) {
// If the closeTrigger is 'submit' we are on the success
// path and will therefore redirect. In that case we shouldn't
// enable the submit buttons
cleanUpAfterSubmit($form, closeTrigger === "submit");
},
returnElements: getVisibleField($form, postTypeId, TagsField).find('input:visible')
};
StackExchange.helpers.showModal($(json.html).elementNodesOnly(), modalSettings);
StackExchange.helpers.bindMovablePopups();
} else {
doSubmit($form, postTypeId, formType, submitCallback, submitEvent);
}
}
});
return false;
}
}
// do the submission in nextTick, so that anything else that has attached itself
// to the submit even has a chance to add their stuff to the form, even if they
// bound their handler *after* this one was bound
setTimeout(function () {
doSubmit($form, postTypeId, formType, submitCallback, submitEvent);
}, 0);
return false;
});
}
function cleanUpAfterSubmit($form, isRedirecting) {
$form.find('input[type="submit"]:visible, button[type="submit"]').removeClass('is-loading');
if (!isRedirecting) {
StackExchange.helpers.enableSubmitButton($form);
if (StackExchange.navPrevention) {
StackExchange.navPrevention.start();
}
}
}
function doSubmit($form, postTypeId, formType, submitCallback, submitEvent) {
$.ajax({
type: 'POST',
dataType: 'json',
data: formType === 'article-on-teams' ? serializeFormWithSource($form, submitEvent) : $form.serialize(),
url: $form.attr('action'),
success: submitCallback,
error: function () {
var errorMessage = submissionErrorMessage(formType, 0);
showSubmissionErrorMessage($form, postTypeId, formType, { General: [$('').text(errorMessage).html()] }, 0);
cleanUpAfterSubmit($form, false);
}
});
}
/**
* Serializes the form and adds the source of the submission to the serialized data. This is used to determine the
* state of the post. In the case of Articles on Teams it decides whether the post is a draft or not.
*
* This is needed because `jQuery.serialize()` excludes buttons/inputs of `type="submit"` by design.
*
* @param $form jquery form element
* @param submitEvent accompanying event that triggered submission
*/
function serializeFormWithSource($form, submitEvent) {
var serialized = $form.serializeArray();
// extract value field from the button that triggered the submission, if present
if (submitEvent && submitEvent.originalEvent && submitEvent.originalEvent.submitter) {
var value = submitEvent.originalEvent.submitter.getAttribute('value');
var name= submitEvent.originalEvent.submitter.getAttribute('name');
if (value && name) {
serialized.push({ name, value });
}
}
return $.param(serialized);
}
function clearBlurTimeouts() {
for (var i = 0; i < blurTimeoutIds.length; i++) {
clearTimeout(blurTimeoutIds[i]);
}
blurTimeoutIds = [];
}
function bindOnBlurDelayed($container, postTypeId, formType, property, func) {
getFormInput($container, postTypeId, property).blur(function () {
var thisArg = this;
var $target = $(this);
if ($target.data(DISABLE_BLUR_VALIDATION_KEY)) {
return;
}
var setError = function (message) {
handleFieldError($container, postTypeId, formType, property, message);
};
var validate = function (requestObject) {
return performValidation(requestObject, $container, postTypeId, formType, [property]);
};
blurTimeoutIds.push(setTimeout(function () {
// Clear Stacks validation messages at the start of validation.
var handler = StackExchange.stacksValidation.handlerFor($target);
if (handler && !onAskPageV2) {
handler.clear();
}
func.call(thisArg, $target, setError, validate, postTypeId);
}, blurTimeoutDelay));
});
}
function validatePostFields($container, postTypeId, formType, isSuggestedEdit, beforeShow) {
if (postTypeId === 1) {
return performValidation({
type: 'POST',
url: '/posts/validate-question',
data: {
title: getFormInput($container, postTypeId, TitleField).val(),
body: getFormInput($container, postTypeId, BodyField).val(),
tags: getFormInput($container, postTypeId, TagsField).val(),
fkey: StackExchange.options.user.fkey,
isAskWizard: onAskWizard
}
}, $container, postTypeId, formType, [TitleField, BodyField, TagsField], beforeShow).promise();
} else if (postTypeId === 2) {
return performValidation({
type: 'POST',
url: '/posts/validate-body',
data: {
body: getFormInput($container, postTypeId, BodyField).val(),
oldBody: getFormInput($container, postTypeId, BodyField).prop('defaultValue'),
isQuestion: false,
isSuggestedEdit: isSuggestedEdit || false,
fkey: StackExchange.options.user.fkey
}
}, $container, postTypeId, formType, [BodyField], beforeShow).promise();
} else {
// TODO: This can be expanded as needed to handle other cases where validation is delayed.
var deferred = $.Deferred();
deferred.reject();
return deferred.promise();
}
}
function initTitleValidation($container, postTypeId, formType) {
bindOnBlurDelayed($container, postTypeId, formType, TitleField, function ($title, setError, validate) {
var title = $title.val();
var trimmedLength = $.trim(title).length;
var minLength = $title.data('min-length');
var maxLength = $title.data('max-length');
if (trimmedLength === 0 && !onAskPageV2) {
setError();
return;
}
if (minLength && trimmedLength < minLength) {
setError(__tr(["Title must be at least $minLength$ character.","Title must be at least $minLength$ characters."], {minLength: minLength}, "en", ["minLength"]));
return;
}
if (maxLength && trimmedLength > maxLength) {
setError(__tr(["Title cannot be longer than $maxLength$ character.","Title cannot be longer than $maxLength$ characters."], {maxLength: maxLength}, "en", ["maxLength"]));
return;
}
validate({
type: 'POST',
url: '/posts/validate-title',
data: {
title: title,
postTypeId: postTypeId,
fkey: StackExchange.options.user.fkey
}
});
});
}
function initBodyValidation($container, postTypeId, formType, isSuggestedEdit) {
bindOnBlurDelayed($container, postTypeId, formType, BodyField, function ($body, setError, validate) {
var body = $body.val();
var trimmedLength = $.trim(body).length;
var minLength = $body.data('min-length');
if (trimmedLength === 0 && !onAskPageV2) {
setError();
return;
}
// Only do client-side length validation for tag wikis and announcements.
if (postTypeId === 5) {
if (minLength && trimmedLength < minLength) {
setError(__tr(["Wiki Body must be at least $minLength$ characters. You entered $actual$."], {minLength: minLength,actual: trimmedLength}, "en", []));
} else {
setError();
}
return;
}
else if (postTypeId === 14) {
if (minLength && trimmedLength < minLength) {
setError(__tr(["Body must be at least $minLength$ characters."], {minLength: minLength}, "en", []));
} else {
setError();
}
return;
}
if (postTypeId === 1 || postTypeId === 2 || postTypeId === 15) {
validate({
type: 'POST',
url: '/posts/validate-body',
data: {
body: body,
oldBody: $body.prop('defaultValue'),
isQuestion: (postTypeId === 1),
isSuggestedEdit: isSuggestedEdit,
isAskWizard: onAskWizard,
fkey: StackExchange.options.user.fkey
}
});
}
});
}
function initTagsValidation($container, postTypeId, formType) {
bindOnBlurDelayed($container, postTypeId, formType, TagsField, function ($tags, setError, validate, postTypeId) {
var tags = $tags.val();
var trimmedLength = $.trim(tags).length;
var postState = $('#js-post-state').val();
if (trimmedLength === 0 && !onAskPageV2) {
setError();
return;
}
validate({
type: 'POST',
url: '/posts/validate-tags',
data: {
tags: tags,
oldTags: $tags.prop('defaultValue'),
fkey: StackExchange.options.user.fkey,
postTypeId: postTypeId,
postState: postState
},
success: function (data) {
var $field = $tags.closest('.js-post-form').find('.js-warned-tags-field');
if ($field.length) {
var value = $field.val();
var warnedTags = $field.data('warned-tags') || [];
var unwarnedTags = ((data.source || {}).Tags || []).filter(function (tag) { return tag && warnedTags.indexOf(tag) === -1; });
if (unwarnedTags.length > 0) {
StackExchange.using("gps", function () {
unwarnedTags.forEach(function (tag) {
StackExchange.gps.track("tag_warning.show", { tag: tag }, true);
value += ' ' + tag;
warnedTags.push(tag);
});
$field.val($.trim(value)).data('warned-tags', warnedTags);
StackExchange.gps.sendPending();
});
}
}
}
});
});
}
function rejectSystemEditComment($container, postTypeId, formType) {
if ($.trim(getFormInput($container, postTypeId, EditCommentField).val()) === '[Edit removed during grace period]') {
handleFieldError($container, postTypeId, formType, EditCommentField,
__tr(["Comment reserved for system use. Please use an appropriate comment."], undefined, "en", []));
return true;
}
return false;
}
function initEditCommentValidation($container, postTypeId, formType) {
bindOnBlurDelayed($container, postTypeId, formType, EditCommentField, function ($editComment, setError, validate) {
var editComment = $editComment.val();
var trimmedLength = $.trim(editComment).length;
var minLength = $editComment.data('min-length');
var maxLength = $editComment.data('max-length');
if (trimmedLength === 0) {
setError();
return;
}
if (minLength && trimmedLength < minLength) {
setError(__tr(["Your edit summary must be at least $minLength$ character.","Your edit summary must be at least $minLength$ characters."], {minLength: minLength}, "en", ["minLength"]));
return;
}
if (maxLength && trimmedLength > maxLength) {
setError(__tr(["Your edit summary cannot be longer than $maxLength$ character.","Your edit summary cannot be longer than $maxLength$ characters."], {maxLength: maxLength}, "en", ["maxLength"]));
return;
}
if (rejectSystemEditComment($container, postTypeId, formType)) {
return;
}
setError();
});
}
function initExcerptValidation($container, postTypeId, formType) {
bindOnBlurDelayed($container, postTypeId, formType, ExcerptField, function ($excerpt, setError, validate) {
var excerpt = $excerpt.val();
var trimmedLength = $.trim(excerpt).length;
var minLength = $excerpt.data('min-length');
var maxLength = $excerpt.data('max-length');
if (trimmedLength === 0) {
setError();
return;
}
if (minLength && trimmedLength < minLength) {
setError(__tr(["Wiki Excerpt must be at least $minLength$ characters; you entered $actual$."], {minLength: minLength,actual: trimmedLength}, "en", []));
return;
}
if (maxLength && trimmedLength > maxLength) {
setError(__tr(["Wiki Excerpt cannot be longer than $maxLength$ characters; you entered $actual$."], {maxLength: maxLength,actual: trimmedLength}, "en", []));
return;
}
setError();
});
}
function initEmailValidation($container, postTypeId, formType) {
bindOnBlurDelayed($container, postTypeId, formType, EmailField, function ($email, setError, validate) {
var email = $email.val();
var trimmed = $.trim(email);
var trimmedLength = trimmed.length;
if (trimmedLength === 0) {
setError();
return;
}
if (!StackExchange.helpers.isEmailAddress(trimmed)) {
setError(__tr(["This email does not appear to be valid."], undefined, "en", []));
return;
}
setError();
});
}
function getSidebarPopupOptions(property, type) {
var sidebarWidth = $('#sidebar, .sidebar').first().width() || 270;
var large = StackExchange.responsive.currentRange() === "lg";
if (property === GeneralField) {
return {
position: 'inline',
css: { 'display': 'inline-block', 'margin-bottom': '10px' },
closeOthers: false,
dismissable: false,
type: type
};
}
return {
position: { my: large ? 'left top' : 'top center' , at: large ? 'right center' : 'bottom center' },
css: { 'max-width': sidebarWidth, 'min-width': sidebarWidth },
closeOthers: false,
type: type
};
}
function submissionErrorMessage(formType, specificErrorCount) {
if (specificErrorCount > 0) {
switch (formType) {
case 'question':
return __tr(["Your question couldn't be submitted. Please see the error above.","Your question couldn't be submitted. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
case 'answer':
return __tr(["Your answer couldn't be submitted. Please see the error above.","Your answer couldn't be submitted. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
case 'edit':
return __tr(["Your edit couldn't be submitted. Please see the error above.","Your edit couldn't be submitted. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
case 'tags':
return __tr(["Your tags couldn't be submitted. Please see the error above.","Your tags couldn't be submitted. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
case 'article':
case 'article-on-teams':
return __tr(["Your article couldn't be submitted. Please see the errors above.","Your article couldn't be submitted. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
case 'announcement':
return __tr(["Your bulletin couldn't be published. Please see the errors above.","Your bulletin couldn't be published. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
default:
return __tr(["Your post couldn't be submitted. Please see the error above.","Your post couldn't be submitted. Please see the errors above."], {specificErrorCount: specificErrorCount}, "en", ["specificErrorCount"]);
}
} else {
switch (formType) {
case 'question':
return __tr(["An error occurred submitting the question."], undefined, "en", []);
case 'answer':
return __tr(["An error occurred submitting the answer."], undefined, "en", []);
case 'edit':
return __tr(["An error occurred submitting the edit."], undefined, "en", []);
case 'tags':
return __tr(["An error occurred submitting the tags."], undefined, "en", []);
case 'article':
case 'article-on-teams':
return __tr(["An error occurred submitting the article."], undefined, "en", []);
case 'announcement':
return __tr(["An error occurred publishing the bulletin."], undefined, "en", []);
default:
return __tr(["An error occurred submitting the post."], undefined, "en", []);
}
}
}
function showSubmissionErrorMessage($form, postTypeId, formType, errorsJson, specificErrorCount) {
var $generalErrorBox = $form.find('.js-general-error').text('').removeClass('d-none');
if (handleErrorsAndWarnings($form, $generalErrorBox, errorsJson, null, GeneralField, postTypeId, formType)) {
return;
}
if (specificErrorCount > 0) {
$generalErrorBox.text(submissionErrorMessage(formType, specificErrorCount));
return;
}
$generalErrorBox.addClass('d-none');
}
function scrollToErrors($container) {
// Scroll to the post review sidebar, if it exists.
var $reviewSummaryContainer = $('.js-post-review-summary').closest('.js-post-review-summary-container');
if ($reviewSummaryContainer.length > 0) {
$reviewSummaryContainer.filter(':visible').scrollIntoView();
return;
}
var intervalId;
if (areAnyErrorsOverSidebar()) {
$('#sidebar').animate({ 'opacity': 0.4 }, 500);
intervalId = setInterval(function () {
if (!areAnyErrorsOverSidebar()) {
$('#sidebar').animate({ 'opacity': 1 }, 500);
clearInterval(intervalId);
}
}, 500);
}
var scrollTop;
$container.find('.validation-error, .js-stacks-validation.has-error').each(function () {
var top = $(this).offset().top;
if (!scrollTop || top < scrollTop) {
scrollTop = top;
}
});
var shakeErrors = function () {
for (var i = 0; i < 3; i++) {
$container.find('.message').animate({ left: '+=5px' }, 100).animate({ left: '-=5px' }, 100);
}
};
if (scrollTop) {
var isReview = $('.review-bar').length;
scrollTop = Math.max(0, scrollTop - (isReview ? 125 : 30)); // leave some breathing room, and leave extra room for the review bar
$('html, body').animate({ scrollTop: scrollTop }, shakeErrors);
} else {
shakeErrors();
}
}
function showErrorsAfterSubmission($form, postTypeId, formType, errorsJson, optionalWarningsJson) {
if (!errorsJson) {
return;
}
// if we have a comments container, add it to the avail containers
const $container = $form.add("#js-comments-container")
whenTagEditorIsDoneLoading($form, postTypeId, function () {
var specificErrorCount =
handleFieldValidationResults(
$container,
postTypeId,
formType,
[
TitleField,
BodyField,
TagsField,
MentionsField,
EditCommentField,
ExcerptField,
EmailField,
ArticleTypeField,
DateField,
CommentFormField,
SubtitleField,
CtaLabelField,
CtaUrlField,
TargetUrlField,
],
errorsJson,
optionalWarningsJson).length;
showSubmissionErrorMessage($container, postTypeId, formType, errorsJson, specificErrorCount);
scrollToErrors($container);
});
}
// This waits for the tag editor to finish loading before executing the passed function.
// It will return instantly if we aren't editing a question.
function whenTagEditorIsDoneLoading($container, postTypeId, func) {
// Wait until the tag editor creates its UI.
var tryIt = function () {
if (postTypeId !== 1 || getVisibleField($container, postTypeId, TagsField).length) {
func();
} else {
setTimeout(tryIt, 250);
}
};
tryIt();
}
function performValidation(requestObject, $container, postTypeId, formType, properties, beforeShow) {
return $.ajax(requestObject)
.then(function (data) {
return beforeShow ? $.when(beforeShow()).then(function () { return data; }) : data;
})
.done(function (data) {
handleFieldValidationResults($container, postTypeId, formType, properties, data.errors, data.warnings);
})
.fail(function () {
handleFieldValidationResults($container, postTypeId, formType, properties, {}, {});
});
}
function handleFieldValidationResults($container, postTypeId, formType, properties, errors, warnings) {
var propertiesWithErrors = [];
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
if (handleErrorsAndWarnings($container, getVisibleField($container, postTypeId, property), errors, warnings, property, postTypeId, formType)) {
propertiesWithErrors.push(property);
}
}
// fire event that we're done handling validation
window.dispatchEvent(new Event("validation:complete"));
return propertiesWithErrors;
}
function handleFieldError($container, postTypeId, formType, property, error) {
handleScopedErrorsAndWarnings($container, getVisibleField($container, postTypeId, property), error ? [$('').text(error).html()] : [], [], property, postTypeId, formType);
}
function handleErrorsAndWarnings($container, $field, errors, warnings, property, postTypeId, formType) {
var scopedErrors = errors[property] || [];
var scopedWarnings = (warnings || {})[property] || [];
return handleScopedErrorsAndWarnings($container, $field, scopedErrors, scopedWarnings, property, postTypeId, formType);
}
function handleScopedErrorsAndWarnings($container, $field, scopedErrors, scopedWarnings, property, postTypeId, formType) {
var handler = StackExchange.stacksValidation.handlerFor($field);
if (handler) {
updateStacksValidation(handler, postTypeId, formType, scopedErrors, scopedWarnings, property);
} else {
updatePopupErrors($field, property, scopedErrors);
}
if (scopedErrors.length) {
getFormInput($container, postTypeId, property)
.data(DISABLE_BLUR_VALIDATION_KEY, true)
.one("input change", function () { $(this).data(DISABLE_BLUR_VALIDATION_KEY, null); });
}
// remove "Your post couldn't be submitted. Please see the errors above."
if (!$container.find('.validation-error, .js-stacks-validation.has-error').length) {
$container.find('.js-general-error').text('');
}
$field.trigger('post:validated-field', [{
errors: scopedErrors,
warnings: scopedWarnings,
field: property,
postTypeId: postTypeId,
formType: formType,
}]);
return scopedErrors.length > 0;
}
function updateStacksValidation(handler, postTypeId, formType, errors, warnings) {
handler.clear('error');
errors.forEach(function (msg) { handler.add('error', msg); });
if (formType === 'edit'
|| (formType === 'question' && onAskPageV2)) {
return;
}
handler.clear('warning');
warnings.forEach(function (msg) { handler.add('warning', msg); });
}
function updatePopupErrors($elem, property, errors) {
if (!$elem || !$elem.length) {
return;
}
if (errors.length === 0
|| (errors.length === 1 && errors[0] === '')
|| !$('html').has($elem).length) {
clearPopupError($elem);
} else {
showErrorPopup($elem, errors, getSidebarPopupOptions(property, 'error'));
}
}
function showErrorPopup($elem, messagesArray, popupOptions) {
var message = messagesArray.length === 1
? messagesArray[0]
: '
' + messagesArray.join('
') + '
';
var $existingPopup = $elem.data('error-popup');
if ($existingPopup && $existingPopup.is(':visible')) {
var existingMessage = $elem.data('error-message');
if (existingMessage === message) {
// inline error messages don't have animateOffsetTop
if ($existingPopup.animateOffsetTop) {
// this existing popup could have been underneath another; adjust its position
$existingPopup.animateOffsetTop(0);
}
return;
}
$existingPopup.fadeOutAndRemove();
}
var $popup = StackExchange.helpers.showMessage($elem, message, popupOptions);
$popup.find('a').attr('target', '_blank');
// Don't trigger validation when the user is just clicking an error message to close it.
// This way, we won't re-show the just-closed message if the validation response arrives after the first message fades out.
$popup.click(clearBlurTimeouts);
$elem
.addClass('validation-error')
.data('error-popup', $popup)
.data('error-message', message);
}
function clearPopupError($elem) {
var $popup = $elem.data('error-popup');
if ($popup && $popup.is(':visible')) {
$popup.fadeOutAndRemove();
}
$elem.removeClass('validation-error');
$elem.removeData('error-popup');
$elem.removeData('error-message');
}
function areAnyErrorsOverSidebar() {
var ret = false;
var $sidebar = $('#sidebar, .sidebar').first();
if (!$sidebar.length) {
return false;
}
var sidebarLeft = $sidebar.offset().left;
$('.message').each(function () {
var $message = $(this);
if ($message.offset().left + $message.outerWidth() > sidebarLeft) {
ret = true;
return false; // break
}
});
return ret;
}
return {
initOnBlur: initOnBlur,
initOnBlurAndSubmit: initOnBlurAndSubmit,
showErrorsAfterSubmission: showErrorsAfterSubmission,
validatePostFields: validatePostFields,
scrollToErrors: scrollToErrors
};
})();
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ __webpack_require__.p = "";
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
var __webpack_exports__ = {};
/*!***************************************************!*\
!*** ./_Scripts/_Includes/set-public-path.mod.ts ***!
\***************************************************/
__webpack_require__.r(__webpack_exports__);
// We need to set the public path at runtime based on the GlobalRoot site setting.
// (We don't know at build time where the static files will be,
// since we could be deployed on-premise.)
// The value of that site setting gets written out to the dom in Master.cshtml
// (see JavaScriptHelper.PublicPath()) so that we can read it here
__webpack_require__.p = document.getElementById("webpack-public-path").innerText + "Js/";
})();
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
/*!***********************************!*\
!*** ./_Scripts/PartialJS/wmd.ts ***!
\***********************************/
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _LegacyJS_markdown_Commonmark_Converter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../LegacyJS/markdown/Commonmark.Converter.js */ "./_Scripts/LegacyJS/markdown/Commonmark.Converter.js");
/* harmony import */ var _LegacyJS_markdown_Commonmark_Converter_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_LegacyJS_markdown_Commonmark_Converter_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _LegacyJS_markdown_Markdown_Converter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../LegacyJS/markdown/Markdown.Converter.js */ "./_Scripts/LegacyJS/markdown/Markdown.Converter.js");
/* harmony import */ var _LegacyJS_markdown_Markdown_Converter_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_LegacyJS_markdown_Markdown_Converter_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _LegacyJS_markdown_Markdown_Editor_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../LegacyJS/markdown/Markdown.Editor.js */ "./_Scripts/LegacyJS/markdown/Markdown.Editor.js");
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_01_MarkdownEditor_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../LegacyJS/markdown/MarkdownStackExchange/01_MarkdownEditor.js */ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/01_MarkdownEditor.js");
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_02_EditorInitialization_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../LegacyJS/markdown/MarkdownStackExchange/02_EditorInitialization.js */ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/02_EditorInitialization.js");
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_03_Heartbeat_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../LegacyJS/markdown/MarkdownStackExchange/03_Heartbeat.js */ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/03_Heartbeat.js");
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_04_NavPrevention_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../LegacyJS/markdown/MarkdownStackExchange/04_NavPrevention.js */ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/04_NavPrevention.js");
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_04_NavPrevention_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_LegacyJS_markdown_MarkdownStackExchange_04_NavPrevention_js__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_10_TextareaResizerPlugin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../LegacyJS/markdown/MarkdownStackExchange/10_TextareaResizerPlugin.js */ "./_Scripts/LegacyJS/markdown/MarkdownStackExchange/10_TextareaResizerPlugin.js");
/* harmony import */ var _LegacyJS_markdown_MarkdownStackExchange_10_TextareaResizerPlugin_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_LegacyJS_markdown_MarkdownStackExchange_10_TextareaResizerPlugin_js__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _LegacyJS_image_upload_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../LegacyJS/image-upload.js */ "./_Scripts/LegacyJS/image-upload.js");
/* harmony import */ var _LegacyJS_post_validation_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../LegacyJS/post-validation.js */ "./_Scripts/LegacyJS/post-validation.js");
/* harmony import */ var _LegacyJS_post_validation_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_LegacyJS_post_validation_js__WEBPACK_IMPORTED_MODULE_9__);
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
// cache breaker
})();
/******/ })()
;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid21kLltsb2NhbGU6YjY0YjJlM2ZdLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBLENBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN2REE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDQTRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ0EvQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7VUNBQTtVQUNBOztVQUVBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBOztVQUVBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBOzs7OztXQ3RCQTtXQUNBO1dBQ0E7V0FDQTtXQUNBO1dBQ0EsaUNBQWlDLFdBQVc7V0FDNUM7V0FDQTs7Ozs7V0NQQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLHlDQUF5Qyx3Q0FBd0M7V0FDakY7V0FDQTtXQUNBOzs7OztXQ1BBOzs7OztXQ0FBO1dBQ0E7V0FDQTtXQUNBLHVEQUF1RCxpQkFBaUI7V0FDeEU7V0FDQSxnREFBZ0QsYUFBYTtXQUM3RDs7Ozs7V0NOQTs7Ozs7Ozs7Ozs7OztBQ0FBLGtGQUFrRjtBQUNsRiwrREFBK0Q7QUFDL0QsMENBQTBDO0FBQzFDLDhFQUE4RTtBQUM5RSxrRUFBa0U7QUFDbEUscUJBQXVCLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNMckM7QUFDRjtBQUNIO0FBQ3dCO0FBQ007QUFDWDtBQUNJO0FBQ1E7QUFDM0M7QUFDRztBQUN4QyxnQkFBZ0IiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9zdGFja292ZXJmbG93Ly4vX1NjcmlwdHMvTGVnYWN5SlMvY29uc3RhbnRzLm1vZC5qcyIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93Ly4vX1NjcmlwdHMvTGVnYWN5SlMvaW1hZ2UtdXBsb2FkLmpzIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvLi9fU2NyaXB0cy9MZWdhY3lKUy9tYXJrZG93bi9Db21tb25tYXJrLkNvbnZlcnRlci5qcyIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93Ly4vX1NjcmlwdHMvTGVnYWN5SlMvbWFya2Rvd24vTWFya2Rvd24uQ29udmVydGVyLmpzIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvLi9fU2NyaXB0cy9MZWdhY3lKUy9tYXJrZG93bi9NYXJrZG93bi5FZGl0b3IuanMiLCJ3ZWJwYWNrOi8vc3RhY2tvdmVyZmxvdy8uL19TY3JpcHRzL0xlZ2FjeUpTL21hcmtkb3duL01hcmtkb3duU3RhY2tFeGNoYW5nZS8wMV9NYXJrZG93bkVkaXRvci5qcyIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93Ly4vX1NjcmlwdHMvTGVnYWN5SlMvbWFya2Rvd24vTWFya2Rvd25TdGFja0V4Y2hhbmdlLzAyX0VkaXRvckluaXRpYWxpemF0aW9uLmpzIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvLi9fU2NyaXB0cy9MZWdhY3lKUy9tYXJrZG93bi9NYXJrZG93blN0YWNrRXhjaGFuZ2UvMDNfSGVhcnRiZWF0LmpzIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvLi9fU2NyaXB0cy9MZWdhY3lKUy9tYXJrZG93bi9NYXJrZG93blN0YWNrRXhjaGFuZ2UvMDRfTmF2UHJldmVudGlvbi5qcyIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93Ly4vX1NjcmlwdHMvTGVnYWN5SlMvbWFya2Rvd24vTWFya2Rvd25TdGFja0V4Y2hhbmdlLzEwX1RleHRhcmVhUmVzaXplclBsdWdpbi5qcyIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93Ly4vX1NjcmlwdHMvTGVnYWN5SlMvcG9zdC12YWxpZGF0aW9uLmpzIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vc3RhY2tvdmVyZmxvdy93ZWJwYWNrL3J1bnRpbWUvY29tcGF0IGdldCBkZWZhdWx0IGV4cG9ydCIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93L3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93L3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vc3RhY2tvdmVyZmxvdy93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvd2VicGFjay9ydW50aW1lL3B1YmxpY1BhdGgiLCJ3ZWJwYWNrOi8vc3RhY2tvdmVyZmxvdy8uL19TY3JpcHRzL19JbmNsdWRlcy9zZXQtcHVibGljLXBhdGgubW9kLnRzIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvLi9fU2NyaXB0cy9QYXJ0aWFsSlMvd21kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIu+7v2V4cG9ydCBjb25zdCBLRVlfQ09ERSA9IHtcbiAgICBMRUZUX01PVVNFOiAxLFxuICAgIE1JRERMRV9NT1VTRTogMixcbiAgICBCQUNLU1BBQ0U6IDgsXG4gICAgVEFCOiA5LFxuICAgIEVOVEVSOiAxMyxcbiAgICBFU0M6IDI3LFxuICAgIFNQQUNFOiAzMixcbiAgICBQQUdFVVA6IDMzLFxuICAgIFBBR0VET1dOOiAzNCxcbiAgICBFTkQ6IDM1LFxuICAgIEhPTUU6IDM2LFxuICAgIExFRlQ6IDM3LFxuICAgIFVQOiAzOCxcbiAgICBSSUdIVDogMzksXG4gICAgRE9XTjogNDAsXG4gICAgREVMOiA0NixcbiAgICAwOiA0OCxcbiAgICAxOiA0OSxcbiAgICAyOiA1MCxcbiAgICAzOiA1MSxcbiAgICA0OiA1MixcbiAgICA1OiA1MyxcbiAgICA2OiA1NCxcbiAgICA3OiA1NSxcbiAgICA4OiA1NixcbiAgICA5OiA1NyxcbiAgICBBOiA2NSxcbiAgICBCOiA2NixcbiAgICBDOiA2NyxcbiAgICBEOiA2OCxcbiAgICBFOiA2OSxcbiAgICBGOiA3MCxcbiAgICBHOiA3MSxcbiAgICBIOiA3MixcbiAgICBJOiA3MyxcbiAgICBKOiA3NCxcbiAgICBLOiA3NSxcbiAgICBMOiA3NixcbiAgICBNOiA3NyxcbiAgICBOOiA3OCxcbiAgICBPOiA3OSxcbiAgICBQOiA4MCxcbiAgICBROiA4MSxcbiAgICBSOiA4MixcbiAgICBTOiA4MyxcbiAgICBUOiA4NCxcbiAgICBVOiA4NSxcbiAgICBWOiA4NixcbiAgICBXOiA4NyxcbiAgICBYOiA4OCxcbiAgICBZOiA4OSxcbiAgICBaOiA5MCxcbiAgICBGNDogMTE1LFxuICAgIENPTU1BOiAxODgsXG59OyIsIid1c2Ugc3RyaWN0JztcbmltcG9ydCB7IEtFWV9DT0RFIH0gZnJvbSAnLi9jb25zdGFudHMubW9kJztcblxuU3RhY2tFeGNoYW5nZS5pbWFnZVVwbG9hZGVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMO1xuXG4gICAgdmFyIGRpYWxvZ0NhY2hlID0ge307IC8vIHVzZWQgd2l0aCBhc3luY0xvYWRcblxuICAgIHZhciBnZXRQYWdlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRvYyA9IHdpbmRvdy5kb2N1bWVudCxcbiAgICAgICAgICAgIHNlbGYgPSB3aW5kb3cuc2VsZjtcblxuICAgICAgICB2YXIgc2Nyb2xsV2lkdGgsIHNjcm9sbEhlaWdodDtcbiAgICAgICAgdmFyIGlubmVyV2lkdGgsIGlubmVySGVpZ2h0O1xuXG4gICAgICAgIC8vIEl0J3Mgbm90IHZlcnkgY2xlYXIgd2hpY2ggYmxvY2tzIHdvcmsgd2l0aCB3aGljaCBicm93c2Vycy5cbiAgICAgICAgaWYgKHNlbGYuaW5uZXJIZWlnaHQgJiYgc2VsZi5zY3JvbGxNYXhZKSB7XG4gICAgICAgICAgICBzY3JvbGxXaWR0aCA9IGRvYy5ib2R5LnNjcm9sbFdpZHRoO1xuICAgICAgICAgICAgc2Nyb2xsSGVpZ2h0ID0gc2VsZi5pbm5lckhlaWdodCArIHNlbGYuc2Nyb2xsTWF4WTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkb2MuYm9keS5zY3JvbGxIZWlnaHQgPiBkb2MuYm9keS5vZmZzZXRIZWlnaHQpIHtcbiAgICAgICAgICAgIHNjcm9sbFdpZHRoID0gZG9jLmJvZHkuc2Nyb2xsV2lkdGg7XG4gICAgICAgICAgICBzY3JvbGxIZWlnaHQgPSBkb2MuYm9keS5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzY3JvbGxXaWR0aCA9IGRvYy5ib2R5Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgc2Nyb2xsSGVpZ2h0ID0gZG9jLmJvZHkub2Zmc2V0SGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNlbGYuaW5uZXJIZWlnaHQpIHtcbiAgICAgICAgICAgIC8vIE5vbi1JRSBicm93c2VyXG4gICAgICAgICAgICBpbm5lcldpZHRoID0gc2VsZi5pbm5lcldpZHRoO1xuICAgICAgICAgICAgaW5uZXJIZWlnaHQgPSBzZWxmLmlubmVySGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRvYy5kb2N1bWVudEVsZW1lbnQgJiYgZG9jLmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpIHtcbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSUUgKElFIDYgdy8gYSBET0NUWVBFIGRlY2xhcmF0aW9uKVxuICAgICAgICAgICAgaW5uZXJXaWR0aCA9IGRvYy5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gICAgICAgICAgICBpbm5lckhlaWdodCA9IGRvYy5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRvYy5ib2R5KSB7XG4gICAgICAgICAgICAvLyBPdGhlciB2ZXJzaW9ucyBvZiBJRVxuICAgICAgICAgICAgaW5uZXJXaWR0aCA9IGRvYy5ib2R5LmNsaWVudFdpZHRoO1xuICAgICAgICAgICAgaW5uZXJIZWlnaHQgPSBkb2MuYm9keS5jbGllbnRIZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbWF4V2lkdGggPSBNYXRoLm1heChzY3JvbGxXaWR0aCwgaW5uZXJXaWR0aCk7XG4gICAgICAgIHZhciBtYXhIZWlnaHQgPSBNYXRoLm1heChzY3JvbGxIZWlnaHQsIGlubmVySGVpZ2h0KTtcbiAgICAgICAgcmV0dXJuIFttYXhXaWR0aCwgbWF4SGVpZ2h0LCBpbm5lcldpZHRoLCBpbm5lckhlaWdodF07XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgICAgICB1cGxvYWRVcmw6ICcvdXBsb2FkL2ltYWdlJyxcbiAgICAgICAgc2hvd0xvd1JlcFdhcm5pbmc6IGZhbHNlXG4gICAgfTtcblxuICAgIHZhciByZW1vdmVJbWFnZVVwbG9hZEJhY2tncm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICQoJy53bWQtcHJvbXB0LWJhY2tncm91bmQnKS5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICB2YXIgY3JlYXRlSW1hZ2VVcGxvYWRCYWNrZ3JvdW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZG9jID0gd2luZG93LmRvY3VtZW50LFxuICAgICAgICAgICAgbmF2ID0gd2luZG93Lm5hdmlnYXRvcjtcblxuICAgICAgICB2YXIgYmFja2dyb3VuZCA9IGRvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLFxuICAgICAgICAgICAgc3R5bGUgPSBiYWNrZ3JvdW5kLnN0eWxlO1xuXG4gICAgICAgIGJhY2tncm91bmQuY2xhc3NOYW1lID0gXCJ3bWQtcHJvbXB0LWJhY2tncm91bmRcIjtcblxuICAgICAgICBzdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgc3R5bGUudG9wID0gXCIwXCI7XG5cbiAgICAgICAgc3R5bGUuekluZGV4ID0gXCIxMDAwXCI7XG5cbiAgICAgICAgc3R5bGUub3BhY2l0eSA9IFwiMC41XCI7XG5cbiAgICAgICAgdmFyIHBhZ2VTaXplID0gZ2V0UGFnZVNpemUoKTtcbiAgICAgICAgc3R5bGUuaGVpZ2h0ID0gcGFnZVNpemVbMV0gKyBcInB4XCI7XG5cbiAgICAgICAgc3R5bGUubGVmdCA9IFwiMFwiO1xuICAgICAgICBzdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuXG4gICAgICAgIGRvYy5ib2R5LmFwcGVuZENoaWxkKGJhY2tncm91bmQpO1xuICAgICAgICByZXR1cm4gYmFja2dyb3VuZDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY3JlYXRlSW1hZ2VVcGxvYWRCYWNrZ3JvdW5kOiBjcmVhdGVJbWFnZVVwbG9hZEJhY2tncm91bmQsXG4gICAgICAgIHJlbW92ZUltYWdlVXBsb2FkQmFja2dyb3VuZDogcmVtb3ZlSW1hZ2VVcGxvYWRCYWNrZ3JvdW5kLFxuXG4gICAgICAgIGVuYWJsZUxvd1JlcFdhcm5pbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmF1bHRPcHRpb25zW1wic2hvd0xvd1JlcFdhcm5pbmdcIl0gPSB0cnVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIHVwbG9hZEltYWdlRGlhbG9nOiBmdW5jdGlvbiAoY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgKG9wdGlvbnMpID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IHVwbG9hZFVybDogb3B0aW9ucyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcHRpb25zID0gJC5leHRlbmQoZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICB2YXIgZGlhbG9nVXJsID0gXCIvcmVuZGVyL2ltYWdlLXVwbG9hZD91cGxvYWRVcmw9ezB9JnNob3dMb3dSZXBXYXJuaW5nPXsyfVwiLmZvcm1hdFVuaWNvcm4oXG4gICAgICAgICAgICAgICAgICAgIGVuY29kZVVSSUNvbXBvbmVudChvcHRpb25zLnVwbG9hZFVybCksXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuc2hvd0xvd1JlcFdhcm5pbmcgPyAndHJ1ZScgOiAnZmFsc2UnXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBkaWFsb2cgPSAkKCc8ZGl2IGNsYXNzPVwibW9kYWwgaW1hZ2UtdXBsb2FkIHdtZC1wcm9tcHQtZGlhbG9nIGF1dG8tY2VudGVyXCIgdGFiaW5kZXg9XCItMVwiPjwvZGl2PicpXG4gICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnanMtYXN5bmMtbG9hZCcpXG4gICAgICAgICAgICAgICAgICAgIC5kYXRhKCdsb2FkLXVybCcsIGRpYWxvZ1VybCksXG4gICAgICAgICAgICAgICAgZHJvcFpvbmUsXG4gICAgICAgICAgICAgICAgZHJvcEhvdmVyQ291bnQgPSAwO1xuXG4gICAgICAgICAgICAvLyBUaGlzIGlzIGNhbGxlZCB3aGVuIHRoZSB1cGxvYWQgZmluaXNoZXMsIGFuZCBpcyBwYXNzZWQgdGhlIGltZ3VyIHVybFxuICAgICAgICAgICAgdmFyIGNsb3NlID0gZnVuY3Rpb24gKHVybCkge1xuICAgICAgICAgICAgICAgIGlmIChkaWFsb2cpXG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZy5mYWRlT3V0QW5kUmVtb3ZlKCk7XG5cbiAgICAgICAgICAgICAgICAkKCdib2R5Jykub2ZmKCdrZXlkb3duJywgZXZlbnRMaXN0ZW5lcnMuY2hlY2tFc2NhcGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgLm9mZigncGFzdGUnLCBldmVudExpc3RlbmVycy5wYXN0ZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodXJsICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVybCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgaXNJbWFnZVR5cGUgPSBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLnR5cGUuaW5kZXhPZignaW1hZ2UvJykgPT09IDA7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgZmluZEltYWdlID0gZnVuY3Rpb24gKGRhdGFUcmFuc2Zlcikge1xuICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJlZDtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YVRyYW5zZmVyLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkID0gJC5ncmVwKGRhdGFUcmFuc2Zlci5pdGVtcywgaXNJbWFnZVR5cGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlcmVkWzBdLmdldEFzRmlsZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGRhdGFUcmFuc2Zlci5maWxlcykge1xuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZCA9ICQuZ3JlcChkYXRhVHJhbnNmZXIuZmlsZXMsIGlzSW1hZ2VUeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJlZFswXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciBzZXRUYWJQYWdlID0gZnVuY3Rpb24gKHRhYkdyb3VwTmFtZSwgcGFnZU5hbWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFiR3JvdXAgPSBkaWFsb2cuZmluZCgnLicgKyB0YWJHcm91cE5hbWUpO1xuICAgICAgICAgICAgICAgIHRhYkdyb3VwLmZpbmQoJy50YWItcGFnZScpLmhpZGUoKTtcbiAgICAgICAgICAgICAgICB0YWJHcm91cC5maW5kKCcuJyArIHRhYkdyb3VwTmFtZSArICctJyArIHBhZ2VOYW1lKS5zaG93KCk7XG4gICAgICAgICAgICAgICAgdGFiR3JvdXAuZGF0YSgnYWN0aXZlLXRhYicsIHBhZ2VOYW1lKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciBzZXRVcFN1Ym1pdENhbGxiYWNrcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xvc2VEaWFsb2cgPSBjbG9zZTtcbiAgICAgICAgICAgICAgICB3aW5kb3cuZGlzcGxheVVwbG9hZEVycm9yID0gbWlzY0NhbGxiYWNrcy51cGxvYWRFcnJvcjtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciBtaXNjQ2FsbGJhY2tzID0ge1xuICAgICAgICAgICAgICAgIHJlc2V0SW5wdXRzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKCcuanMtbW9kYWwtaW5wdXQtZmlsZSwgLmpzLW1vZGFsLWlucHV0LXVybCcpLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ3ZhbHVlJywgJycpO1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICB1cGxvYWRFcnJvcjogZnVuY3Rpb24gKG1zZykge1xuICAgICAgICAgICAgICAgICAgICBtaXNjQ2FsbGJhY2tzLnJlc2V0SW5wdXRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKCcubW9kYWwtb3B0aW9ucy1lcnJvciAubW9kYWwtb3B0aW9ucy1lcnJvci1tZXNzYWdlJykudGV4dChtc2cpO1xuICAgICAgICAgICAgICAgICAgICBzZXRUYWJQYWdlKCdtb2RhbC1vcHRpb25zJywgJ2Vycm9yJyk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGFqYXhSZXN1bHQ6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLlN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5jbG9zZURpYWxvZyhkYXRhLlVwbG9hZGVkSW1hZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmRpc3BsYXlVcGxvYWRFcnJvcihkYXRhLkVycm9yTWVzc2FnZSk7IFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGFqYXhFcnJvcjogZnVuY3Rpb24gKF8sIHN0YXR1cywgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbWlzY0NhbGxiYWNrcy51cGxvYWRFcnJvcihfcygnUmVxdWVzdCByZXR1cm5lZCBhbiBlcnJvcjogWyRzdGF0dXMkXSAkZXJyb3IkJywgeyBzdGF0dXM6IHN0YXR1cywgZXJyb3I6IGVycm9yIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgZXZlbnRMaXN0ZW5lcnMgPSB7XG4gICAgICAgICAgICAgICAgc2hvd0xpbms6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2V0VGFiUGFnZSgnbW9kYWwtb3B0aW9ucycsICd1cmwnKTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5qcy1tb2RhbC1pbnB1dC11cmwnKS50cmlnZ2VyKCdmb2N1cycpO1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICByZXNldFZpZXc6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2V0VGFiUGFnZSgnbW9kYWwtZHJvcHpvbmUnLCAnZGVmYXVsdCcpO1xuICAgICAgICAgICAgICAgICAgICBzZXRUYWJQYWdlKCdtb2RhbC1vcHRpb25zJywgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5qcy1tb2RhbC1jdGEtc3VibWl0JykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1kcm9wem9uZS1wcmV2aWV3JykuZW1wdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5qcy1tb2RhbC1pbnB1dC1maWxlJykudmFsKCcnKTtcbiAgICAgICAgICAgICAgICAgICAgbWlzY0NhbGxiYWNrcy5yZXNldElucHV0cygpO1xuICAgICAgICAgICAgICAgICAgICBkcm9wSG92ZXJDb3VudCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGRyb3Bab25lLnJlbW92ZUNsYXNzKCdob3ZlcicpO1xuICAgICAgICAgICAgICAgICAgICBkaWFsb2cuZmluZCgnZm9ybScpXG4gICAgICAgICAgICAgICAgICAgICAgICAub2ZmKCdzdWJtaXQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLm9uKCdzdWJtaXQnLCBldmVudExpc3RlbmVycy5hamF4U3VibWl0KTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJ2Zvcm0gaW5wdXRbbmFtZT1ma2V5XScpLnZhbChTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5KTsgLy8gY2FuIGdldCBvdXQgb2Ygc3luYyB2aWEgbG9jYWwtc3RvcmFnZSBwdXNoZXNcbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgaW5wdXRGaWxlT3JVcmw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1ZhbHVlID0gISFkaWFsb2cuZmluZCgnLmpzLXVzZXItaW5wdXQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMudmFsdWUubGVuZ3RoOyB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5qcy1tb2RhbC1jdGEtc3VibWl0JykucHJvcCgnZGlzYWJsZWQnLCAhaGFzVmFsdWUpO1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBkaXNhYmxlUGFzdGVIYW5kbGluZzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAkKCdib2R5Jykub2ZmKCdwYXN0ZScsIGV2ZW50TGlzdGVuZXJzLnByZXZpZXdJbWFnZSk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGVuYWJsZVBhc3RlSGFuZGxpbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgJCgnYm9keScpLm9uKCdwYXN0ZScsIHsgcHJvcGVydHk6ICdjbGlwYm9hcmREYXRhJyB9LCBldmVudExpc3RlbmVycy5wcmV2aWV3SW1hZ2UpO1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBzZWxlY3RGaWxlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKCcuanMtbW9kYWwtaW5wdXQtZmlsZScpLnRyaWdnZXIoJ2NsaWNrJyk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGNsaWNrRmlsZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgcHJldmlld0ltYWdlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0b29CaWcsIHByZXZpZXcsIHVybDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbGUgPSBmaW5kSW1hZ2UoZS5vcmlnaW5hbEV2ZW50W2UuZGF0YS5wcm9wZXJ0eV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW1ndXIgaGFzIGEgMk1CIGltYWdlIHVwbG9hZCBsaW1pdC5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb0JpZyA9IGZpbGUuc2l6ZSA+PSAweDIwMDAwMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpZXcgPSBkaWFsb2cuZmluZCgnLm1vZGFsLWRyb3B6b25lLXByZXZpZXcnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpZXcuZW1wdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlld1dpZHRoID0gcGFyc2VJbnQocHJldmlldy5jc3MoJ3dpZHRoJykpIC0gMzBcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aWV3SGVpZ2h0ID0gcGFyc2VJbnQocHJldmlldy5jc3MoJ2hlaWdodCcpKSAtIDMwXG4gICAgICAgICAgICAgICAgICAgICAgICAkKCc8aW1nPicpLmF0dHIoJ3NyYycsIHVybClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3NzKHsgbWF4V2lkdGg6IGAke3ByZXZpZXdXaWR0aH1weGAsIG1heEhlaWdodDogYCR7cHJldmlld0hlaWdodH1weGB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbignbG9hZCcsIHsgdXJsOiB1cmwgfSwgZXZlbnRMaXN0ZW5lcnMubG9hZFByZXZpZXdJbWFnZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG8ocHJldmlldyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2cuZmluZCgnZm9ybScpLm9mZignc3VibWl0JylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oJ3N1Ym1pdCcsIGZpbGUsIGV2ZW50TGlzdGVuZXJzLmFqYXhTdWJtaXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5qcy1tb2RhbC1jdGEtc3VibWl0JykucHJvcCgnZGlzYWJsZWQnLCB0b29CaWcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGFiUGFnZSgnbW9kYWwtZHJvcHpvbmUnLCAncHJldmlldycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGFiUGFnZSgnbW9kYWwtb3B0aW9ucycsIHRvb0JpZyA/ICd0b29iaWcnIDogJ3ByZXZpZXcnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBkcmFnRW50ZXI6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIxMDAyNTQ0LzEzXG4gICAgICAgICAgICAgICAgICAgIGRyb3BIb3ZlckNvdW50Kys7XG4gICAgICAgICAgICAgICAgICAgIGRyb3Bab25lLmFkZENsYXNzKCdob3ZlcicpO1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBkcmFnTGVhdmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKC0tZHJvcEhvdmVyQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyb3Bab25lLnJlbW92ZUNsYXNzKCdob3ZlcicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGNsaWNrQ2xvc2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgY2xvc2UobnVsbCk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGxvYWRQcmV2aWV3SW1hZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoZS5kYXRhLnVybCk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGFqYXhTdWJtaXQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGFiUGFnZSgnbW9kYWwtb3B0aW9ucycsICd1cGxvYWRpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKGUuY3VycmVudFRhcmdldCk7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLnNldCgnZmlsZScsIGUuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHNldFVwU3VibWl0Q2FsbGJhY2tzKCk7XG4gICAgICAgICAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmw6IG9wdGlvbnMudXBsb2FkVXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogZm9ybURhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWNoZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50VHlwZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBtaXNjQ2FsbGJhY2tzLmFqYXhSZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogbWlzY0NhbGxiYWNrcy5hamF4RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIGNoZWNrRXNjYXBlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZS53aGljaCA9PT0gS0VZX0NPREUuRVNDKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbG9zZShudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciBpbml0RGlhbG9nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGRpYWxvZy5jc3MoJ2hlaWdodCcsICdhdXRvJyk7XG4gICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1vcHRpb25zLXVwbG9hZGluZyBwJykuYWRkU3Bpbm5lcigpO1xuICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKCcubW9kYWwtb3B0aW9ucy1kZWZhdWx0IGEnKS5vbignY2xpY2snLCBldmVudExpc3RlbmVycy5zaG93TGluayk7XG4gICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1vcHRpb25zLWNhbmNlbCcpLm9uKCdjbGljaycsIGV2ZW50TGlzdGVuZXJzLnJlc2V0Vmlldyk7XG4gICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5qcy1tb2RhbC1pbnB1dC1maWxlJykub24oJ2NsaWNrJywgZXZlbnRMaXN0ZW5lcnMuY2xpY2tGaWxlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKCdjaGFuZ2UnLCBldmVudExpc3RlbmVycy5pbnB1dEZpbGVPclVybCk7XG4gICAgICAgICAgICAgICAgdmFyICR1cmxJbnB1dCA9IGRpYWxvZy5maW5kKCcuanMtbW9kYWwtaW5wdXQtdXJsJykub24oJ2lucHV0IGtleWRvd24nLCBldmVudExpc3RlbmVycy5pbnB1dEZpbGVPclVybCk7XG4gICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoJy5tb2RhbC1kcm9wem9uZS1kZWZhdWx0Jykub24oJ2NsaWNrJywgZXZlbnRMaXN0ZW5lcnMuc2VsZWN0RmlsZSk7XG5cbiAgICAgICAgICAgICAgICBkaWFsb2cuZmluZCgnLmpzLW1vZGFsLWlucHV0LWZpbGUnKS5vbignY2hhbmdlJyx7IHByb3BlcnR5OiAndGFyZ2V0JyB9LCBldmVudExpc3RlbmVycy5wcmV2aWV3SW1hZ2UpO1xuICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKCcuanMtbW9kYWwtaW5wdXQtdXJsJykub24oJ2ZvY3VzJywgZXZlbnRMaXN0ZW5lcnMuZGlzYWJsZVBhc3RlSGFuZGxpbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbignYmx1cicsIGV2ZW50TGlzdGVuZXJzLmVuYWJsZVBhc3RlSGFuZGxpbmcpO1xuICAgICAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJzLmVuYWJsZVBhc3RlSGFuZGxpbmcoKTtcblxuICAgICAgICAgICAgICAgIGRyb3Bab25lID0gZGlhbG9nLmZpbmQoJy5tb2RhbC1kcm9wem9uZS1kZWZhdWx0JylcbiAgICAgICAgICAgICAgICAgICAgLm9uKCdkcmFnZW50ZXInLCBldmVudExpc3RlbmVycy5kcmFnRW50ZXIpXG4gICAgICAgICAgICAgICAgICAgIC5vbignZHJhZ2xlYXZlJywgZXZlbnRMaXN0ZW5lcnMuZHJhZ0xlYXZlKVxuICAgICAgICAgICAgICAgICAgICAub24oJ2RyYWdvdmVyJywgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgIC5vbignZHJvcCcsIHsgcHJvcGVydHk6ICdkYXRhVHJhbnNmZXInIH0sIGV2ZW50TGlzdGVuZXJzLnByZXZpZXdJbWFnZSk7XG5cbiAgICAgICAgICAgICAgICBkaWFsb2cuZmluZCgnLmpzLW1vZGFsLWNsb3NlJykub24oJ2NsaWNrJywgZXZlbnRMaXN0ZW5lcnMuY2xpY2tDbG9zZSk7XG4gICAgICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnMucmVzZXRWaWV3KCk7XG4gICAgICAgICAgICAgICAgZGlhbG9nLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5pbWFnZVVybCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5zaG93TGluaygpXG4gICAgICAgICAgICAgICAgICAgICR1cmxJbnB1dC52YWwob3B0aW9ucy5pbWFnZVVybCk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJzLmlucHV0RmlsZU9yVXJsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdmFyIGxvYWREaWFsb2cgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBkaWFsb2cuYXN5bmNMb2FkKHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXREaWFsb2coKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgY2FjaGU6IGRpYWxvZ0NhY2hlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBkaWFsb2cuYXBwZW5kVG8oJ2JvZHknKS5jZW50ZXIoKS5mYWRlSW4oJ2Zhc3QnKS5wcm9taXNlKCkuZG9uZShsb2FkRGlhbG9nKTtcbiAgICAgICAgICAgIGRpYWxvZy5vbigncG9wdXBDbG9zZScsIGV2ZW50TGlzdGVuZXJzLmRpc2FibGVQYXN0ZUhhbmRsaW5nKTtcbiAgICAgICAgICAgICQoJ2JvZHknKS5vbigna2V5ZG93bicsIGV2ZW50TGlzdGVuZXJzLmNoZWNrRXNjYXBlKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIHRlbGwgdGhlIGVkaXRvciB0aGF0IHdlJ3JlIGNyZWF0aW5nIG91ciBvd24gZGlhbG9nLlxuICAgICAgICB9XG4gICAgfTtcbn0pKCk7XG4iLCJ2YXIgQ29tbW9ubWFyayA9IHdpbmRvdy5Db21tb25tYXJrID0gd2luZG93LkNvbW1vbm1hcmsgfHwge307XG5cbihmdW5jdGlvbiAoKSB7XG5cbiAgICBmdW5jdGlvbiBpZGVudGl0eSh4KSB7IHJldHVybiB4OyB9XG4gICAgZnVuY3Rpb24gcmV0dXJuRmFsc2UoeCkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgIGZ1bmN0aW9uIEhvb2tDb2xsZWN0aW9uKCkgeyB9XG5cbiAgICBIb29rQ29sbGVjdGlvbi5wcm90b3R5cGUgPSB7XG5cbiAgICAgICAgY2hhaW46IGZ1bmN0aW9uIChob29rbmFtZSwgZnVuYykge1xuICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gdGhpc1tob29rbmFtZV07XG4gICAgICAgICAgICBpZiAoIW9yaWdpbmFsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biBob29rIFwiICsgaG9va25hbWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob3JpZ2luYWwgPT09IGlkZW50aXR5KSB7XG4gICAgICAgICAgICAgICAgdGhpc1tob29rbmFtZV0gPSBmdW5jO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzW2hvb2tuYW1lXSA9IGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1swXSA9IG9yaWdpbmFsLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChob29rbmFtZSwgZnVuYykge1xuICAgICAgICAgICAgaWYgKCF0aGlzW2hvb2tuYW1lXSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVua25vd24gaG9vayBcIiArIGhvb2tuYW1lKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpc1tob29rbmFtZV0gPSBmdW5jO1xuICAgICAgICB9LFxuICAgICAgICBhZGROb29wOiBmdW5jdGlvbiAoaG9va25hbWUpIHtcbiAgICAgICAgICAgIHRoaXNbaG9va25hbWVdID0gaWRlbnRpdHk7XG4gICAgICAgIH0sXG4gICAgICAgIGFkZEZhbHNlOiBmdW5jdGlvbiAoaG9va25hbWUpIHtcbiAgICAgICAgICAgIHRoaXNbaG9va25hbWVdID0gcmV0dXJuRmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbW1vbm1hcmsuSG9va0NvbGxlY3Rpb24gPSBIb29rQ29sbGVjdGlvbjtcblxuICAgIENvbW1vbm1hcmsuQ29udmVydGVyID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICAgICAgQ29tbW9ubWFyay5tYXJrZG93bml0ID0gbnVsbDtcblxuICAgICAgICB2YXIgcGx1Z2luSG9va3MgPSB0aGlzLmhvb2tzID0gbmV3IEhvb2tDb2xsZWN0aW9uKCk7XG4gICAgICAgIHBsdWdpbkhvb2tzLmFkZE5vb3AoXCJwbGFpbkxpbmtUZXh0XCIpO1xuXG4gICAgICAgIHBsdWdpbkhvb2tzLmFkZE5vb3AoXCJwcmVDb252ZXJzaW9uXCIpO1xuICAgICAgICBwbHVnaW5Ib29rcy5hZGROb29wKFwicG9zdE5vcm1hbGl6YXRpb25cIik7XG4gICAgICAgIHBsdWdpbkhvb2tzLmFkZE5vb3AoXCJwcmVCbG9ja0dhbXV0XCIpO1xuICAgICAgICBwbHVnaW5Ib29rcy5hZGROb29wKFwicG9zdEJsb2NrR2FtdXRcIik7XG4gICAgICAgIHBsdWdpbkhvb2tzLmFkZE5vb3AoXCJwcmVTcGFuR2FtdXRcIik7XG4gICAgICAgIHBsdWdpbkhvb2tzLmFkZE5vb3AoXCJwb3N0U3BhbkdhbXV0XCIpO1xuICAgICAgICBwbHVnaW5Ib29rcy5hZGROb29wKFwicG9zdENvbnZlcnNpb25cIik7XG5cbiAgICAgICAgdGhpcy5tYWtlSHRtbEFzeW5jID0gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKTtcblxuICAgICAgICAgICAgLy8gZXhpdCBlYXJseSBpZiB0aGVyZSdzIG5vIHRleHQgdG8gYmUgY29udmVydGVkIC0gd2UgZG9uJ3QgbmVlZCB0byBsb2FkIG91ciBtYXJrZG93biByZW5kZXJlciBmb3Igbm90aGluZ1xuICAgICAgICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZSh0ZXh0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBsYXp5LWxvYWQgbWFya2Rvd24taXQgcmVuZGVyZXIgd2hlbiB3ZSBuZWVkIGl0IGZvciB0aGUgZmlyc3QgdGltZVxuICAgICAgICAgICAgaWYgKENvbW1vbm1hcmsubWFya2Rvd25pdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhciBtYWtlSHRtbCA9IHRoaXMubWFrZUh0bWw7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZE1hcmtkb3duUmVuZGVyZXJBc3luYygpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uKCkgeyByZXR1cm4gbWFrZUh0bWwodGV4dCkgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZSh0aGlzLm1ha2VIdG1sKHRleHQpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmxvYWRNYXJrZG93blJlbmRlcmVyQXN5bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCk7XG4gICAgICAgICAgICBpZiAoQ29tbW9ubWFyay5tYXJrZG93bml0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS51c2luZyhcIm1hcmtkb3duaXRcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIENvbW1vbm1hcmsubWFya2Rvd25pdCA9IFN0YWNrRXhjaGFuZ2UubWFya2Rvd25pdC5pbml0KG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWFrZUh0bWwgPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgICAgICAgICBpZiAoQ29tbW9ubWFyay5tYXJrZG93bml0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWFya2Rvd24gcmVuZGVyZXIgaXMgbm90IGluaXRpYWxpemVkXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0ZXh0ID0gcGx1Z2luSG9va3MucHJlQ29udmVyc2lvbih0ZXh0KTtcblxuICAgICAgICAgICAgdGV4dCA9IGRldGFiKHRleHQpO1xuICAgICAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXlsgXFx0XSskL21nLCBcIlwiKTtcbiAgICAgICAgICAgIHRleHQgPSBwbHVnaW5Ib29rcy5wb3N0Tm9ybWFsaXphdGlvbih0ZXh0KTtcblxuICAgICAgICAgICAgdGV4dCA9IENvbW1vbm1hcmsubWFya2Rvd25pdC5yZW5kZXIodGV4dCk7XG4gICAgICAgICAgICB0ZXh0ID0gZXh0cmFjdENvZGVibG9ja0xhbmd1YWdlQ29tbWVudCh0ZXh0KTtcbiAgICAgICAgICAgIHRleHQgPSBwbHVnaW5Ib29rcy5wb3N0Q29udmVyc2lvbih0ZXh0KTtcbiAgICAgICAgICAgIHJldHVybiB0ZXh0O1xuICAgICAgICB9O1xuICAgIH07IC8vIGVuZCBvZiB0aGUgQ29tbW9ubWFyay5Db252ZXJ0ZXIgY29uc3RydWN0b3JcblxuICAgIC8vIHRoZSBlZGl0b3IncyBodG1sIHNhbml0aXphdGlvbiBzdGVwIHN0cmlwcyBhbGwgY2xhc3NlcyBhbmQgYXR0cmlidXRlcyBmcm9tIHRhZ3MsXG4gICAgLy8gc28gaW4gb3JkZXIgdG8gcHJlc2VydmUgb3VyIGJsb2NrJ3Mgc3BlY2lmaWVkIGxhbmd1YWdlIHdlIG5lZWQgdG8gdHJhbnNsYXRlIGl0IHRvXG4gICAgLy8gc29tZXRoaW5nIHRoZSBzYW5pdGl6ZXIgdW5kZXJzdGFuZHM6IGEgYDwhLS0gbGFuZ3VhZ2U6IHh5eiAtLT5gIGNvbW1lbnRcbiAgICAvLyBzZWU6IDAxXzA1X1Nhbml0aXplQW5kSGlnaGxpZ2h0LmpzIC0+IHN5bnRheEhpZ2hsaWdodE92ZXJyaWRlUHJlcGFyZVxuICAgIHZhciBsYW5ndWFnZUF0dHJpYnV0ZVBhdHRlcm4gPSAvPHByZT48Y29kZSBjbGFzcz1cImxhbmd1YWdlLShbYS16MC05IytcXC0uXSspXCI+L2dpO1xuICAgIGZ1bmN0aW9uIGV4dHJhY3RDb2RlYmxvY2tMYW5ndWFnZUNvbW1lbnQoaHRtbCkge1xuICAgICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKGxhbmd1YWdlQXR0cmlidXRlUGF0dGVybiwgXCI8IS0tIGxhbmd1YWdlOiAkMSAtLT48cHJlPjxjb2RlPlwiKTtcbiAgICB9XG5cbiAgICAvLyByZXBsYWNlIHNwYWNlcyB3aXRoIHRhYnMgaW4gdGhlIHNhbWUgd2F5IHRoZSBvbGQgcHJldmlldyBkaWRcbiAgICAvLyBieSBmaWxsaW5nIHVwIHNwYWNlcyB1bnRpbCB3ZSByZWFjaCB0aGUgbmV4dCB0YWIgc3RvcFxuICAgIGZ1bmN0aW9uIGRldGFiKHRleHQpIHtcbiAgICAgICAgaWYgKCEvXFx0Ly50ZXN0KHRleHQpKVxuICAgICAgICAgICAgcmV0dXJuIHRleHQ7XG5cbiAgICAgICAgdmFyIHNwYWNlcyA9IFtcIiAgICBcIiwgXCIgICBcIiwgXCIgIFwiLCBcIiBcIl0sXG4gICAgICAgICAgICBza2V3ID0gMCxcbiAgICAgICAgICAgIHY7XG5cbiAgICAgICAgcmV0dXJuIHRleHQucmVwbGFjZSgvW1xcblxcdF0vZywgZnVuY3Rpb24gKG1hdGNoLCBvZmZzZXQpIHtcbiAgICAgICAgICAgIGlmIChtYXRjaCA9PT0gXCJcXG5cIikge1xuICAgICAgICAgICAgICAgIHNrZXcgPSBvZmZzZXQgKyAxO1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHYgPSAob2Zmc2V0IC0gc2tldykgJSA0O1xuICAgICAgICAgICAgc2tldyA9IG9mZnNldCArIDE7XG4gICAgICAgICAgICByZXR1cm4gc3BhY2VzW3ZdO1xuICAgICAgICB9KTtcbiAgICB9XG59KSgpO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgTWFya2Rvd24gPSB3aW5kb3cuTWFya2Rvd24gPSB3aW5kb3cuTWFya2Rvd24gfHwge307XG5cbihmdW5jdGlvbiAoKSB7XG5cbiAgICBmdW5jdGlvbiBpZGVudGl0eSh4KSB7IHJldHVybiB4OyB9XG4gICAgZnVuY3Rpb24gcmV0dXJuRmFsc2UoeCkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgIGZ1bmN0aW9uIEhvb2tDb2xsZWN0aW9uKCkgeyB9XG5cbiAgICBIb29rQ29sbGVjdGlvbi5wcm90b3R5cGUgPSB7XG5cbiAgICAgICAgY2hhaW46IGZ1bmN0aW9uIChob29rbmFtZSwgZnVuYykge1xuICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gdGhpc1tob29rbmFtZV07XG4gICAgICAgICAgICBpZiAoIW9yaWdpbmFsKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVua25vd24gaG9vayBcIiArIGhvb2tuYW1lKTtcblxuICAgICAgICAgICAgaWYgKG9yaWdpbmFsID09PSBpZGVudGl0eSlcbiAgICAgICAgICAgICAgICB0aGlzW2hvb2tuYW1lXSA9IGZ1bmM7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhpc1tob29rbmFtZV0gPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBvcmlnaW5hbC5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoaG9va25hbWUsIGZ1bmMpIHtcbiAgICAgICAgICAgIGlmICghdGhpc1tob29rbmFtZV0pXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biBob29rIFwiICsgaG9va25hbWUpO1xuICAgICAgICAgICAgdGhpc1tob29rbmFtZV0gPSBmdW5jO1xuICAgICAgICB9LFxuICAgICAgICBhZGROb29wOiBmdW5jdGlvbiAoaG9va25hbWUpIHtcbiAgICAgICAgICAgIHRoaXNbaG9va25hbWVdID0gaWRlbnRpdHk7XG4gICAgICAgIH0sXG4gICAgICAgIGFkZEZhbHNlOiBmdW5jdGlvbiAoaG9va25hbWUpIHtcbiAgICAgICAgICAgIHRoaXNbaG9va25hbWVdID0gcmV0dXJuRmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgTWFya2Rvd24uSG9va0NvbGxlY3Rpb24gPSBIb29rQ29sbGVjdGlvbjtcblxuICAgIC8vIGdfdXJscyBhbmQgZ190aXRsZXMgYWxsb3cgYXJiaXRyYXJ5IHVzZXItZW50ZXJlZCBzdHJpbmdzIGFzIGtleXMuIFRoaXNcbiAgICAvLyBjYXVzZWQgYW4gZXhjZXB0aW9uIChhbmQgaGVuY2Ugc3RvcHBlZCB0aGUgcmVuZGVyaW5nKSB3aGVuIHRoZSB1c2VyIGVudGVyZWRcbiAgICAvLyBlLmcuIFtwdXNoXSBvciBbX19wcm90b19fXS4gQWRkaW5nIGEgcHJlZml4IHRvIHRoZSBhY3R1YWwga2V5IHByZXZlbnRzIHRoaXNcbiAgICAvLyAoc2luY2Ugbm8gYnVpbHRpbiBwcm9wZXJ0eSBzdGFydHMgd2l0aCBcInNfXCIpLiBTZWVcbiAgICAvLyBodHRwczovL21ldGEuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzY0NjU1L3N0cmFuZ2Utd21kLWJ1Z1xuICAgIC8vIChncmFudGVkLCBzd2l0Y2hpbmcgZnJvbSBBcnJheSgpIHRvIE9iamVjdCgpIGFsb25lIHdvdWxkIGhhdmUgbGVmdCBvbmx5IF9fcHJvdG9fX1xuICAgIC8vIHRvIGJlIGEgcHJvYmxlbSlcbiAgICBmdW5jdGlvbiBTYXZlSGFzaCgpIHsgfVxuICAgIFNhdmVIYXNoLnByb3RvdHlwZSA9IHtcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpc1tcInNfXCIgKyBrZXldID0gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIGdldDogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbXCJzX1wiICsga2V5XTtcbiAgICAgICAgfVxuICAgIH07XG59KSgpOyIsImltcG9ydCB7IEtFWV9DT0RFIH0gZnJvbSAnLi4vY29uc3RhbnRzLm1vZCc7XG4vLyBuZWVkcyBNYXJrZG93bi5Db252ZXJ0ZXIuanMgYXQgdGhlIG1vbWVudFxuXG52YXIgTWFya2Rvd24gPSB3aW5kb3cuTWFya2Rvd24gPSB3aW5kb3cuTWFya2Rvd24gfHwge307XG5cbihmdW5jdGlvbiAoKSB7XG5cbiAgICB2YXIgdXRpbCA9IHt9LFxuICAgICAgICBwb3NpdGlvbiA9IHt9LFxuICAgICAgICB1aSA9IHt9LFxuICAgICAgICBkb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG4gICAgICAgIHJlID0gd2luZG93LlJlZ0V4cCxcbiAgICAgICAgbmF2ID0gd2luZG93Lm5hdmlnYXRvcixcbiAgICAgICAgU0VUVElOR1MgPSB7IGxpbmVMZW5ndGg6IDcyIH0sXG5cbiAgICAvLyBVc2VkIHRvIHdvcmsgYXJvdW5kIHNvbWUgYnJvd3NlciBidWdzIHdoZXJlIHdlIGNhbid0IHVzZSBmZWF0dXJlIHRlc3RpbmcuXG4gICAgICAgIHVhU25pZmZlZCA9IHtcbiAgICAgICAgICAgIGlzSUU6IC9tc2llLy50ZXN0KG5hdi51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICAgICBpc0lFXzVvcjY6IC9tc2llIDYvLnRlc3QobmF2LnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpKSB8fCAvbXNpZSA1Ly50ZXN0KG5hdi51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICAgICBpc09wZXJhOiAvb3BlcmEvLnRlc3QobmF2LnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpKVxuICAgICAgICB9O1xuXG4gICAgdmFyIGRlZmF1bHRzU3RyaW5ncyA9IHtcbiAgICAgICAgYm9sZDogXCJTdHJvbmcgPHN0cm9uZz4gQ3RybCtCXCIsXG4gICAgICAgIGJvbGRleGFtcGxlOiBcInN0cm9uZyB0ZXh0XCIsXG5cbiAgICAgICAgaXRhbGljOiBcIkVtcGhhc2lzIDxlbT4gQ3RybCtJXCIsXG4gICAgICAgIGl0YWxpY2V4YW1wbGU6IFwiZW1waGFzaXplZCB0ZXh0XCIsXG5cbiAgICAgICAgbGluazogXCJIeXBlcmxpbmsgPGE+IEN0cmwrTFwiLFxuICAgICAgICBsaW5rZGVzY3JpcHRpb246IFwiZW50ZXIgbGluayBkZXNjcmlwdGlvbiBoZXJlXCIsXG4gICAgICAgIGxpbmtkaWFsb2c6IFwiPHA+PGxhYmVsIGZvcj1cXFwicHJvbXB0LWRpYWxvZy1pbnB1dFxcXCIgY2xhc3M9XFxcImZ3LWJvbGRcXFwiPkluc2VydCBIeXBlcmxpbms8L2xhYmVsPjwvcD48cD5odHRwOi8vZXhhbXBsZS5jb20vIFxcXCJvcHRpb25hbCB0aXRsZVxcXCI8L3A+XCIsXG5cbiAgICAgICAgcXVvdGU6IFwiQmxvY2txdW90ZSA8YmxvY2txdW90ZT4gQ3RybCtRXCIsXG4gICAgICAgIHF1b3RlZXhhbXBsZTogXCJCbG9ja3F1b3RlXCIsXG5cbiAgICAgICAgY29kZTogXCJDb2RlIFNhbXBsZSA8cHJlPjxjb2RlPiBDdHJsK0tcIixcbiAgICAgICAgY29kZWV4YW1wbGU6IFwiZW50ZXIgY29kZSBoZXJlXCIsXG5cbiAgICAgICAgaW1hZ2U6IFwiSW1hZ2UgPGltZz4gQ3RybCtHXCIsXG4gICAgICAgIGltYWdlZGVzY3JpcHRpb246IFwiZW50ZXIgaW1hZ2UgZGVzY3JpcHRpb24gaGVyZVwiLFxuICAgICAgICBpbWFnZWRpYWxvZzogXCI8cD48Yj5JbnNlcnQgSW1hZ2U8L2I+PC9wPjxwPmh0dHA6Ly9leGFtcGxlLmNvbS9pbWFnZXMvZGlhZ3JhbS5qcGcgXFxcIm9wdGlvbmFsIHRpdGxlXFxcIjwvcD5cIixcblxuICAgICAgICBvbGlzdDogXCJOdW1iZXJlZCBMaXN0IDxvbD4gQ3RybCtPXCIsXG4gICAgICAgIHVsaXN0OiBcIkJ1bGxldGVkIExpc3QgPHVsPiBDdHJsK1VcIixcbiAgICAgICAgbGl0ZW06IFwiTGlzdCBpdGVtXCIsXG5cbiAgICAgICAgaGVhZGluZzogXCJIZWFkaW5nIDxoMT4vPGgyPiBDdHJsK0hcIixcbiAgICAgICAgaGVhZGluZ2V4YW1wbGU6IFwiSGVhZGluZ1wiLFxuXG4gICAgICAgIGhyOiBcIkhvcml6b250YWwgUnVsZSA8aHI+IEN0cmwrUlwiLFxuXG4gICAgICAgIHVuZG86IFwiVW5kbyAtIEN0cmwrWlwiLFxuICAgICAgICByZWRvOiBcIlJlZG8gLSBDdHJsK1lcIixcbiAgICAgICAgcmVkb21hYzogXCJSZWRvIC0gQ3RybCtTaGlmdCtaXCIsXG5cbiAgICAgICAgaGVscDogXCJNYXJrZG93biBFZGl0aW5nIEhlbHBcIixcblxuICAgICAgICBvazogXCJPS1wiLFxuICAgICAgICBjYW5jZWw6IFwiQ2FuY2VsXCJcbiAgICB9O1xuXG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gIFlPVVIgQ0hBTkdFUyBHTyBIRVJFXG4gICAgLy9cbiAgICAvLyBJJ3ZlIHRyaWVkIHRvIGxvY2FsaXplIHRoZSB0aGluZ3MgeW91IGFyZSBsaWtlbHkgdG8gY2hhbmdlIHRvXG4gICAgLy8gdGhpcyBhcmVhLlxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIC8vIFRoZSBkZWZhdWx0IHRleHQgdGhhdCBhcHBlYXJzIGluIHRoZSBkaWFsb2cgaW5wdXQgYm94IHdoZW4gZW50ZXJpbmdcbiAgICAvLyBsaW5rcy5cbiAgICB2YXIgaW1hZ2VEZWZhdWx0VGV4dCA9IFwiaHR0cDovL1wiO1xuICAgIHZhciBsaW5rRGVmYXVsdFRleHQgPSBcImh0dHA6Ly9cIjtcblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyAgRU5EIE9GIFlPVVIgQ0hBTkdFU1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIC8vIG9wdGlvbnMsIGlmIGdpdmVuLCBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAgLy8gICBvcHRpb25zLmhlbHBCdXR0b24gPSB7IGhhbmRsZXI6IHlvdXJFdmVudEhhbmRsZXIgfVxuICAgIC8vICAgb3B0aW9ucy5zdHJpbmdzID0geyBpdGFsaWNleGFtcGxlOiBcInNsYW50ZWQgdGV4dFwiIH1cbiAgICAvLyAgIG9wdGlvbnMud3JhcEltYWdlSW5MaW5rID0gdHJ1ZVxuICAgIC8vICAgb3B0aW9ucy5jb252ZXJ0SW1hZ2VzVG9MaW5rcyA9IHRydWVcbiAgICAvLyBgeW91ckV2ZW50SGFuZGxlcmAgaXMgdGhlIGNsaWNrIGhhbmRsZXIgZm9yIHRoZSBoZWxwIGJ1dHRvbi5cbiAgICAvLyBJZiBgb3B0aW9ucy5oZWxwQnV0dG9uYCBpc24ndCBnaXZlbiwgbm90IGhlbHAgYnV0dG9uIGlzIGNyZWF0ZWQuXG4gICAgLy8gYG9wdGlvbnMuc3RyaW5nc2AgY2FuIGhhdmUgYW55IG9yIGFsbCBvZiB0aGUgc2FtZSBwcm9wZXJ0aWVzIGFzXG4gICAgLy8gYGRlZmF1bHRTdHJpbmdzYCBhYm92ZSwgc28geW91IGNhbiBqdXN0IG92ZXJyaWRlIHNvbWUgc3RyaW5nIGRpc3BsYXllZFxuICAgIC8vIHRvIHRoZSB1c2VyIG9uIGEgY2FzZS1ieS1jYXNlIGJhc2lzLCBvciB0cmFuc2xhdGUgYWxsIHN0cmluZ3MgdG9cbiAgICAvLyBhIGRpZmZlcmVudCBsYW5ndWFnZS5cbiAgICAvL1xuICAgIC8vIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSByZWFzb25zLCB0aGUgYG9wdGlvbnNgIGFyZ3VtZW50IGNhbiBhbHNvXG4gICAgLy8gYmUganVzdCB0aGUgYGhlbHBCdXR0b25gIG9iamVjdCwgYW5kIGBzdHJpbmdzLmhlbHBgIGNhbiBhbHNvIGJlIHNldCB2aWFcbiAgICAvLyBgaGVscEJ1dHRvbi50aXRsZWAuIFRoaXMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgbGVnYWN5LlxuICAgIC8vXG4gICAgLy8gVGhlIGNvbnN0cnVjdGVkIGVkaXRvciBvYmplY3QgaGFzIHRoZSBtZXRob2RzOlxuICAgIC8vIC0gZ2V0Q29udmVydGVyKCkgcmV0dXJucyB0aGUgbWFya2Rvd24gY29udmVydGVyIG9iamVjdCB0aGF0IHdhcyBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gLSBydW4oKSBhY3R1YWxseSBzdGFydHMgdGhlIGVkaXRvcjsgc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBhbGwgbmVjZXNzYXJ5IHBsdWdpbnMgYXJlIHJlZ2lzdGVyZWQuIENhbGxpbmcgdGhpcyBtb3JlIHRoYW4gb25jZSBpcyBhIG5vLW9wLlxuICAgIC8vIC0gcmVmcmVzaFByZXZpZXcoKSBmb3JjZXMgdGhlIHByZXZpZXcgdG8gYmUgdXBkYXRlZC4gVGhpcyBtZXRob2QgaXMgb25seSBhdmFpbGFibGUgYWZ0ZXIgcnVuKCkgd2FzIGNhbGxlZC5cbiAgICBNYXJrZG93bi5FZGl0b3IgPSBmdW5jdGlvbiAobWFya2Rvd25Db252ZXJ0ZXIsIGlkUG9zdGZpeCwgb3B0aW9ucykge1xuXG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5oYW5kbGVyID09PSBcImZ1bmN0aW9uXCIpIHsgLy9iYWNrd2FyZHMgY29tcGF0aWJsZSBiZWhhdmlvclxuICAgICAgICAgICAgb3B0aW9ucyA9IHsgaGVscEJ1dHRvbjogb3B0aW9ucyB9O1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMuc3RyaW5ncyA9IG9wdGlvbnMuc3RyaW5ncyB8fCB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuaGVscEJ1dHRvbikge1xuICAgICAgICAgICAgb3B0aW9ucy5zdHJpbmdzLmhlbHAgPSBvcHRpb25zLnN0cmluZ3MuaGVscCB8fCBvcHRpb25zLmhlbHBCdXR0b24udGl0bGU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGdldFN0cmluZyA9IGZ1bmN0aW9uIChpZGVudGlmaWVyKSB7IHJldHVybiBvcHRpb25zLnN0cmluZ3NbaWRlbnRpZmllcl0gfHwgZGVmYXVsdHNTdHJpbmdzW2lkZW50aWZpZXJdOyB9XG5cbiAgICAgICAgaWRQb3N0Zml4ID0gaWRQb3N0Zml4IHx8IFwiXCI7XG5cbiAgICAgICAgdGhpcy5nZXRQb3N0Zml4ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gaWRQb3N0Zml4OyB9XG5cbiAgICAgICAgdmFyIGhvb2tzID0gdGhpcy5ob29rcyA9IG5ldyBNYXJrZG93bi5Ib29rQ29sbGVjdGlvbigpO1xuICAgICAgICBob29rcy5hZGROb29wKFwib25QcmV2aWV3UmVmcmVzaFwiKTsgICAgICAgLy8gY2FsbGVkIHdpdGggbm8gYXJndW1lbnRzIGFmdGVyIHRoZSBwcmV2aWV3IGhhcyBiZWVuIHJlZnJlc2hlZFxuICAgICAgICBob29rcy5hZGROb29wKFwicG9zdEJsb2NrcXVvdGVDcmVhdGlvblwiKTsgLy8gY2FsbGVkIHdpdGggdGhlIHVzZXIncyBzZWxlY3Rpb24gKmFmdGVyKiB0aGUgYmxvY2txdW90ZSB3YXMgY3JlYXRlZDsgc2hvdWxkIHJldHVybiB0aGUgYWN0dWFsIHRvLWJlLWluc2VydGVkIHRleHRcbiAgICAgICAgaG9va3MuYWRkRmFsc2UoXCJpbnNlcnRJbWFnZURpYWxvZ1wiKTsgICAgIC8qIGNhbGxlZCB3aXRoIG9uZSBwYXJhbWV0ZXI6IGEgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIHdpdGggdGhlIFVSTCBvZiB0aGUgaW1hZ2UuIElmIHRoZSBhcHBsaWNhdGlvbiBjcmVhdGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaXRzIG93biBpbWFnZSBpbnNlcnRpb24gZGlhbG9nLCB0aGlzIGhvb2sgc2hvdWxkIHJldHVybiB0cnVlLCBhbmQgdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBjYWxsZWQgd2l0aCB0aGUgY2hvc2VuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaW1hZ2UgdXJsIChvciBudWxsIGlmIHRoZSB1c2VyIGNhbmNlbGxlZCkuIElmIHRoaXMgaG9vayByZXR1cm5zIGZhbHNlLCB0aGUgZGVmYXVsdCBkaWFsb2cgd2lsbCBiZSB1c2VkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICBob29rcy5hZGROb29wKFwiaW1hZ2VDb252ZXJ0ZWRUb0xpbmtcIik7ICAvLyBjYWxsZWQgd2l0aCBubyBhcmd1bWVudHMgaWYgYW4gaW1hZ2Ugd2FzIGNvbnZlcnRlZFxuICAgICAgICBob29rcy5hZGRGYWxzZShcImluc2VydExpbmtEaWFsb2dcIik7ICAgICAvKiBjYWxsZWQgd2l0aCBvbmUgcGFyYW1ldGVyOiBhIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aXRoIHRoZSBVUkwuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBXaGVuIERvY3VtZW50YXRpb24gY29udGVudCB0eXBlIGlzIGVuYWJsZWQsIHRoaXMgaG9vayBzaG91bGQgcmV0dXJuIHRydWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgaG9va3MuYWRkRmFsc2UoXCJpbnRlcmNlcHRCdXR0b25DbGlja1wiKTtcbiAgICAgICAgaG9va3MuYWRkRmFsc2UoXCJza2lwTW9kYWxCYWNrZ3JvdW5kXCIpO1xuICAgICAgICBcbiAgICAgICAgdGhpcy5nZXRDb252ZXJ0ZXIgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBtYXJrZG93bkNvbnZlcnRlcjsgfVxuXG4gICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgIHBhbmVscztcblxuICAgICAgICB0aGlzLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChwYW5lbHMpXG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBhbHJlYWR5IGluaXRpYWxpemVkXG5cbiAgICAgICAgICAgIHBhbmVscyA9IG5ldyBQYW5lbENvbGxlY3Rpb24oaWRQb3N0Zml4KTtcbiAgICAgICAgICAgIHZhciBjb21tYW5kTWFuYWdlciA9IG5ldyBDb21tYW5kTWFuYWdlcihob29rcywgZ2V0U3RyaW5nLCBtYXJrZG93bkNvbnZlcnRlciwgb3B0aW9ucy53cmFwSW1hZ2VJbkxpbmssIG9wdGlvbnMuY29udmVydEltYWdlc1RvTGlua3MpO1xuICAgICAgICAgICAgdmFyIHByZXZpZXdNYW5hZ2VyID0gbmV3IFByZXZpZXdNYW5hZ2VyKG1hcmtkb3duQ29udmVydGVyLCBwYW5lbHMsIGZ1bmN0aW9uICgpIHsgaG9va3Mub25QcmV2aWV3UmVmcmVzaCgpOyB9KTtcbiAgICAgICAgICAgIHZhciB1bmRvTWFuYWdlciwgdWlNYW5hZ2VyO1xuXG4gICAgICAgICAgICBpZiAoIS9cXD9ub3VuZG8vLnRlc3QoZG9jLmxvY2F0aW9uLmhyZWYpKSB7XG4gICAgICAgICAgICAgICAgdW5kb01hbmFnZXIgPSBuZXcgVW5kb01hbmFnZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBwcmV2aWV3TWFuYWdlci5yZWZyZXNoKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1aU1hbmFnZXIpIC8vIG5vdCBhdmFpbGFibGUgb24gdGhlIGZpcnN0IGNhbGxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVpTWFuYWdlci5zZXRVbmRvUmVkb0J1dHRvblN0YXRlcygpO1xuICAgICAgICAgICAgICAgIH0sIHBhbmVscyk7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0T3BlcmF0aW9uID0gZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgdW5kb01hbmFnZXIuc2V0Q29tbWFuZE1vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZigpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LnJlZnJlc2hQcmV2aWV3KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1aU1hbmFnZXIgPSBuZXcgVUlNYW5hZ2VyKGlkUG9zdGZpeCwgcGFuZWxzLCB1bmRvTWFuYWdlciwgcHJldmlld01hbmFnZXIsIGNvbW1hbmRNYW5hZ2VyLCBvcHRpb25zLmhlbHBCdXR0b24sIGdldFN0cmluZyk7XG4gICAgICAgICAgICB1aU1hbmFnZXIuc2V0VW5kb1JlZG9CdXR0b25TdGF0ZXMoKTtcblxuICAgICAgICAgICAgdmFyIGZvcmNlUmVmcmVzaCA9IHRoYXQucmVmcmVzaFByZXZpZXcgPSBmdW5jdGlvbiAoKSB7IHByZXZpZXdNYW5hZ2VyLnJlZnJlc2godHJ1ZSk7IH07XG5cbiAgICAgICAgICAgIGZvcmNlUmVmcmVzaCgpO1xuICAgICAgICB9O1xuXG4gICAgfVxuXG4gICAgLy8gYmVmb3JlOiBjb250YWlucyBhbGwgdGhlIHRleHQgaW4gdGhlIGlucHV0IGJveCBCRUZPUkUgdGhlIHNlbGVjdGlvbi5cbiAgICAvLyBhZnRlcjogY29udGFpbnMgYWxsIHRoZSB0ZXh0IGluIHRoZSBpbnB1dCBib3ggQUZURVIgdGhlIHNlbGVjdGlvbi5cbiAgICBmdW5jdGlvbiBDaHVua3MoKSB7IH1cblxuICAgIC8vIHN0YXJ0UmVnZXg6IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGZpbmQgdGhlIHN0YXJ0IHRhZ1xuICAgIC8vIGVuZFJlZ2V4OiBhIHJlZ3VsYXIgZXhwcmVzc3Npb24gdG8gZmluZCB0aGUgZW5kIHRhZ1xuICAgIENodW5rcy5wcm90b3R5cGUuZmluZFRhZ3MgPSBmdW5jdGlvbiAoc3RhcnRSZWdleCwgZW5kUmVnZXgpIHtcblxuICAgICAgICB2YXIgY2h1bmtPYmogPSB0aGlzO1xuICAgICAgICB2YXIgcmVnZXg7XG5cbiAgICAgICAgaWYgKHN0YXJ0UmVnZXgpIHtcblxuICAgICAgICAgICAgcmVnZXggPSB1dGlsLmV4dGVuZFJlZ0V4cChzdGFydFJlZ2V4LCBcIlwiLCBcIiRcIik7XG5cbiAgICAgICAgICAgIHRoaXMuYmVmb3JlID0gdGhpcy5iZWZvcmUucmVwbGFjZShyZWdleCxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmtPYmouc3RhcnRUYWcgPSBjaHVua09iai5zdGFydFRhZyArIG1hdGNoO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmVnZXggPSB1dGlsLmV4dGVuZFJlZ0V4cChzdGFydFJlZ2V4LCBcIl5cIiwgXCJcIik7XG5cbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShyZWdleCxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmtPYmouc3RhcnRUYWcgPSBjaHVua09iai5zdGFydFRhZyArIG1hdGNoO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmRSZWdleCkge1xuXG4gICAgICAgICAgICByZWdleCA9IHV0aWwuZXh0ZW5kUmVnRXhwKGVuZFJlZ2V4LCBcIlwiLCBcIiRcIik7XG5cbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShyZWdleCxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmtPYmouZW5kVGFnID0gbWF0Y2ggKyBjaHVua09iai5lbmRUYWc7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZWdleCA9IHV0aWwuZXh0ZW5kUmVnRXhwKGVuZFJlZ2V4LCBcIl5cIiwgXCJcIik7XG5cbiAgICAgICAgICAgIHRoaXMuYWZ0ZXIgPSB0aGlzLmFmdGVyLnJlcGxhY2UocmVnZXgsXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNodW5rT2JqLmVuZFRhZyA9IG1hdGNoICsgY2h1bmtPYmouZW5kVGFnO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBJZiByZW1vdmUgaXMgZmFsc2UsIHRoZSB3aGl0ZXNwYWNlIGlzIHRyYW5zZmVycmVkXG4gICAgLy8gdG8gdGhlIGJlZm9yZS9hZnRlciByZWdpb25zLlxuICAgIC8vXG4gICAgLy8gSWYgcmVtb3ZlIGlzIHRydWUsIHRoZSB3aGl0ZXNwYWNlIGRpc2FwcGVhcnMuXG4gICAgQ2h1bmtzLnByb3RvdHlwZS50cmltV2hpdGVzcGFjZSA9IGZ1bmN0aW9uIChyZW1vdmUpIHtcbiAgICAgICAgdmFyIGJlZm9yZVJlcGxhY2VyLCBhZnRlclJlcGxhY2VyLCB0aGF0ID0gdGhpcztcbiAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgYmVmb3JlUmVwbGFjZXIgPSBhZnRlclJlcGxhY2VyID0gXCJcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJlZm9yZVJlcGxhY2VyID0gZnVuY3Rpb24gKHMpIHsgdGhhdC5iZWZvcmUgKz0gczsgcmV0dXJuIFwiXCI7IH1cbiAgICAgICAgICAgIGFmdGVyUmVwbGFjZXIgPSBmdW5jdGlvbiAocykgeyB0aGF0LmFmdGVyID0gcyArIHRoYXQuYWZ0ZXI7IHJldHVybiBcIlwiOyB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoL14oXFxzKikvLCBiZWZvcmVSZXBsYWNlcikucmVwbGFjZSgvKFxccyopJC8sIGFmdGVyUmVwbGFjZXIpO1xuICAgIH07XG5cblxuICAgIENodW5rcy5wcm90b3R5cGUuc2tpcExpbmVzID0gZnVuY3Rpb24gKG5MaW5lc0JlZm9yZSwgbkxpbmVzQWZ0ZXIsIGZpbmRFeHRyYU5ld2xpbmVzKSB7XG5cbiAgICAgICAgaWYgKG5MaW5lc0JlZm9yZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBuTGluZXNCZWZvcmUgPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5MaW5lc0FmdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5MaW5lc0FmdGVyID0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5MaW5lc0JlZm9yZSsrO1xuICAgICAgICBuTGluZXNBZnRlcisrO1xuXG4gICAgICAgIHZhciByZWdleFRleHQ7XG4gICAgICAgIHZhciByZXBsYWNlbWVudFRleHQ7XG5cbiAgICAgICAgLy8gY2hyb21lIGJ1ZyAuLi4gZG9jdW1lbnRlZCBhdDogaHR0cHM6Ly9tZXRhLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy82MzMwNy9ibG9ja3F1b3RlLWdsaXRjaC1pbi1lZGl0b3ItaW4tY2hyb21lLTYtYW5kLTcvNjU5ODUjNjU5ODVcbiAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0Nocm9tZS8pKSB7XG4gICAgICAgICAgICBcIlhcIi5tYXRjaCgvKCkuLyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoLyheXFxuKikvLCBcIlwiKTtcblxuICAgICAgICB0aGlzLnN0YXJ0VGFnID0gdGhpcy5zdGFydFRhZyArIHJlLiQxO1xuXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb24ucmVwbGFjZSgvKFxcbiokKS8sIFwiXCIpO1xuICAgICAgICB0aGlzLmVuZFRhZyA9IHRoaXMuZW5kVGFnICsgcmUuJDE7XG4gICAgICAgIHRoaXMuc3RhcnRUYWcgPSB0aGlzLnN0YXJ0VGFnLnJlcGxhY2UoLyheXFxuKikvLCBcIlwiKTtcbiAgICAgICAgdGhpcy5iZWZvcmUgPSB0aGlzLmJlZm9yZSArIHJlLiQxO1xuICAgICAgICB0aGlzLmVuZFRhZyA9IHRoaXMuZW5kVGFnLnJlcGxhY2UoLyhcXG4qJCkvLCBcIlwiKTtcbiAgICAgICAgdGhpcy5hZnRlciA9IHRoaXMuYWZ0ZXIgKyByZS4kMTtcblxuICAgICAgICBpZiAodGhpcy5iZWZvcmUpIHtcblxuICAgICAgICAgICAgcmVnZXhUZXh0ID0gcmVwbGFjZW1lbnRUZXh0ID0gXCJcIjtcblxuICAgICAgICAgICAgd2hpbGUgKG5MaW5lc0JlZm9yZS0tKSB7XG4gICAgICAgICAgICAgICAgcmVnZXhUZXh0ICs9IFwiXFxcXG4/XCI7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnRUZXh0ICs9IFwiXFxuXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChmaW5kRXh0cmFOZXdsaW5lcykge1xuICAgICAgICAgICAgICAgIHJlZ2V4VGV4dCA9IFwiXFxcXG4qXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmJlZm9yZSA9IHRoaXMuYmVmb3JlLnJlcGxhY2UobmV3IHJlKHJlZ2V4VGV4dCArIFwiJFwiLCBcIlwiKSwgcmVwbGFjZW1lbnRUZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFmdGVyKSB7XG5cbiAgICAgICAgICAgIHJlZ2V4VGV4dCA9IHJlcGxhY2VtZW50VGV4dCA9IFwiXCI7XG5cbiAgICAgICAgICAgIHdoaWxlIChuTGluZXNBZnRlci0tKSB7XG4gICAgICAgICAgICAgICAgcmVnZXhUZXh0ICs9IFwiXFxcXG4/XCI7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnRUZXh0ICs9IFwiXFxuXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmluZEV4dHJhTmV3bGluZXMpIHtcbiAgICAgICAgICAgICAgICByZWdleFRleHQgPSBcIlxcXFxuKlwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmFmdGVyID0gdGhpcy5hZnRlci5yZXBsYWNlKG5ldyByZShyZWdleFRleHQsIFwiXCIpLCByZXBsYWNlbWVudFRleHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vIGVuZCBvZiBDaHVua3NcblxuICAgIC8vIEEgY29sbGVjdGlvbiBvZiB0aGUgaW1wb3J0YW50IHJlZ2lvbnMgb24gdGhlIHBhZ2UuXG4gICAgLy8gQ2FjaGVkIHNvIHdlIGRvbid0IGhhdmUgdG8ga2VlcCB0cmF2ZXJzaW5nIHRoZSBET00uXG4gICAgLy8gQWxzbyBob2xkcyBpZUNhY2hlZFJhbmdlIGFuZCBpZUNhY2hlZFNjcm9sbFRvcCwgd2hlcmUgbmVjZXNzYXJ5OyB3b3JraW5nIGFyb3VuZFxuICAgIC8vIHRoaXMgaXNzdWU6XG4gICAgLy8gSW50ZXJuZXQgZXhwbG9yZXIgaGFzIHByb2JsZW1zIHdpdGggQ1NTIHNwcml0ZSBidXR0b25zIHRoYXQgdXNlIEhUTUxcbiAgICAvLyBsaXN0cy4gIFdoZW4geW91IGNsaWNrIG9uIHRoZSBiYWNrZ3JvdW5kIGltYWdlIFwiYnV0dG9uXCIsIElFIHdpbGxcbiAgICAvLyBzZWxlY3QgdGhlIG5vbi1leGlzdGVudCBsaW5rIHRleHQgYW5kIGRpc2NhcmQgdGhlIHNlbGVjdGlvbiBpbiB0aGVcbiAgICAvLyB0ZXh0YXJlYS4gIFRoZSBzb2x1dGlvbiB0byB0aGlzIGlzIHRvIGNhY2hlIHRoZSB0ZXh0YXJlYSBzZWxlY3Rpb25cbiAgICAvLyBvbiB0aGUgYnV0dG9uJ3MgbW91c2Vkb3duIGV2ZW50IGFuZCBzZXQgYSBmbGFnLiAgSW4gdGhlIHBhcnQgb2YgdGhlXG4gICAgLy8gY29kZSB3aGVyZSB3ZSBuZWVkIHRvIGdyYWIgdGhlIHNlbGVjdGlvbiwgd2UgY2hlY2sgZm9yIHRoZSBmbGFnXG4gICAgLy8gYW5kLCBpZiBpdCdzIHNldCwgdXNlIHRoZSBjYWNoZWQgYXJlYSBpbnN0ZWFkIG9mIHF1ZXJ5aW5nIHRoZVxuICAgIC8vIHRleHRhcmVhLlxuICAgIC8vXG4gICAgLy8gVGhpcyBPTkxZIGFmZmVjdHMgSW50ZXJuZXQgRXhwbG9yZXIgKHRlc3RlZCBvbiB2ZXJzaW9ucyA2LCA3XG4gICAgLy8gYW5kIDgpIGFuZCBPTkxZIG9uIGJ1dHRvbiBjbGlja3MuICBLZXlib2FyZCBzaG9ydGN1dHMgd29ya1xuICAgIC8vIG5vcm1hbGx5IHNpbmNlIHRoZSBmb2N1cyBuZXZlciBsZWF2ZXMgdGhlIHRleHRhcmVhLlxuICAgIGZ1bmN0aW9uIFBhbmVsQ29sbGVjdGlvbihwb3N0Zml4KSB7XG4gICAgICAgIHRoaXMuYnV0dG9uQmFyID0gZG9jLmdldEVsZW1lbnRCeUlkKFwid21kLWJ1dHRvbi1iYXJcIiArIHBvc3RmaXgpO1xuICAgICAgICB0aGlzLnByZXZpZXcgPSBkb2MuZ2V0RWxlbWVudEJ5SWQoXCJ3bWQtcHJldmlld1wiICsgcG9zdGZpeCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBkb2MuZ2V0RWxlbWVudEJ5SWQoXCJ3bWQtaW5wdXRcIiArIHBvc3RmaXgpO1xuICAgIH07XG5cbiAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIERPTSBlbGVtZW50IGlzIHZpc2libGUsIGZhbHNlIGlmIGl0J3MgaGlkZGVuLlxuICAgIC8vIENoZWNrcyBpZiBkaXNwbGF5IGlzIGFueXRoaW5nIG90aGVyIHRoYW4gbm9uZS5cbiAgICB1dGlsLmlzVmlzaWJsZSA9IGZ1bmN0aW9uIChlbGVtKSB7XG5cbiAgICAgICAgaWYgKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKSB7XG4gICAgICAgICAgICAvLyBNb3N0IGJyb3dzZXJzXG4gICAgICAgICAgICByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbSwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShcImRpc3BsYXlcIikgIT09IFwibm9uZVwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGVsZW0uY3VycmVudFN0eWxlKSB7XG4gICAgICAgICAgICAvLyBJRVxuICAgICAgICAgICAgcmV0dXJuIGVsZW0uY3VycmVudFN0eWxlW1wiZGlzcGxheVwiXSAhPT0gXCJub25lXCI7XG4gICAgICAgIH1cbiAgICB9O1xuXG5cbiAgICAvLyBBZGRzIGEgbGlzdGVuZXIgY2FsbGJhY2sgdG8gYSBET00gZWxlbWVudCB3aGljaCBpcyBmaXJlZCBvbiBhIHNwZWNpZmllZFxuICAgIC8vIGV2ZW50LlxuICAgIHV0aWwuYWRkRXZlbnQgPSBmdW5jdGlvbiAoZWxlbSwgZXZlbnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmIChlbGVtLmF0dGFjaEV2ZW50KSB7XG4gICAgICAgICAgICAvLyBJRSBvbmx5LiAgVGhlIFwib25cIiBpcyBtYW5kYXRvcnkuXG4gICAgICAgICAgICBlbGVtLmF0dGFjaEV2ZW50KFwib25cIiArIGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBPdGhlciBicm93c2Vycy5cbiAgICAgICAgICAgIGVsZW0uYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH07XG5cblxuICAgIC8vIFJlbW92ZXMgYSBsaXN0ZW5lciBjYWxsYmFjayBmcm9tIGEgRE9NIGVsZW1lbnQgd2hpY2ggaXMgZmlyZWQgb24gYSBzcGVjaWZpZWRcbiAgICAvLyBldmVudC5cbiAgICB1dGlsLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gKGVsZW0sIGV2ZW50LCBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoZWxlbS5kZXRhY2hFdmVudCkge1xuICAgICAgICAgICAgLy8gSUUgb25seS4gIFRoZSBcIm9uXCIgaXMgbWFuZGF0b3J5LlxuICAgICAgICAgICAgZWxlbS5kZXRhY2hFdmVudChcIm9uXCIgKyBldmVudCwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gT3RoZXIgYnJvd3NlcnMuXG4gICAgICAgICAgICBlbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gQ29udmVydHMgXFxyXFxuIGFuZCBcXHIgdG8gXFxuLlxuICAgIHV0aWwuZml4RW9sQ2hhcnMgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKC9cXHJcXG4vZywgXCJcXG5cIik7XG4gICAgICAgIHRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcci9nLCBcIlxcblwiKTtcbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfTtcblxuICAgIC8vIEV4dGVuZHMgYSByZWd1bGFyIGV4cHJlc3Npb24uICBSZXR1cm5zIGEgbmV3IFJlZ0V4cFxuICAgIC8vIHVzaW5nIHByZSArIHJlZ2V4ICsgcG9zdCBhcyB0aGUgZXhwcmVzc2lvbi5cbiAgICAvLyBVc2VkIGluIGEgZmV3IGZ1bmN0aW9ucyB3aGVyZSB3ZSBoYXZlIGEgYmFzZVxuICAgIC8vIGV4cHJlc3Npb24gYW5kIHdlIHdhbnQgdG8gcHJlLSBvciBhcHBlbmQgc29tZVxuICAgIC8vIGNvbmRpdGlvbnMgdG8gaXQgKGUuZy4gYWRkaW5nIFwiJFwiIHRvIHRoZSBlbmQpLlxuICAgIC8vIFRoZSBmbGFncyBhcmUgdW5jaGFuZ2VkLlxuICAgIC8vXG4gICAgLy8gcmVnZXggaXMgYSBSZWdFeHAsIHByZSBhbmQgcG9zdCBhcmUgc3RyaW5ncy5cbiAgICB1dGlsLmV4dGVuZFJlZ0V4cCA9IGZ1bmN0aW9uIChyZWdleCwgcHJlLCBwb3N0KSB7XG5cbiAgICAgICAgaWYgKHByZSA9PT0gbnVsbCB8fCBwcmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHJlID0gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zdCA9PT0gbnVsbCB8fCBwb3N0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBvc3QgPSBcIlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHBhdHRlcm4gPSByZWdleC50b1N0cmluZygpO1xuICAgICAgICB2YXIgZmxhZ3M7XG5cbiAgICAgICAgLy8gUmVwbGFjZSB0aGUgZmxhZ3Mgd2l0aCBlbXB0eSBzcGFjZSBhbmQgc3RvcmUgdGhlbS5cbiAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4ucmVwbGFjZSgvXFwvKFtnaW1dKikkLywgZnVuY3Rpb24gKHdob2xlTWF0Y2gsIGZsYWdzUGFydCkge1xuICAgICAgICAgICAgZmxhZ3MgPSBmbGFnc1BhcnQ7XG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBzbGFzaCBkZWxpbWl0ZXJzIG9uIHRoZSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UoLyheXFwvfFxcLyQpL2csIFwiXCIpO1xuICAgICAgICBwYXR0ZXJuID0gcHJlICsgcGF0dGVybiArIHBvc3Q7XG5cbiAgICAgICAgcmV0dXJuIG5ldyByZShwYXR0ZXJuLCBmbGFncyk7XG4gICAgfVxuXG4gICAgLy8gVU5GSU5JU0hFRFxuICAgIC8vIFRoZSBhc3NpZ25tZW50IGluIHRoZSB3aGlsZSBsb29wIG1ha2VzIGpzbGludCBjcmFua3kuXG4gICAgLy8gSSdsbCBjaGFuZ2UgaXQgdG8gYSBiZXR0ZXIgbG9vcCBsYXRlci5cbiAgICBwb3NpdGlvbi5nZXRUb3AgPSBmdW5jdGlvbiAoZWxlbSwgaXNJbm5lcikge1xuICAgICAgICB2YXIgcmVzdWx0ID0gZWxlbS5vZmZzZXRUb3A7XG4gICAgICAgIGlmICghaXNJbm5lcikge1xuICAgICAgICAgICAgd2hpbGUgKGVsZW0gPSBlbGVtLm9mZnNldFBhcmVudCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBlbGVtLm9mZnNldFRvcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBwb3NpdGlvbi5nZXRIZWlnaHQgPSBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICByZXR1cm4gZWxlbS5vZmZzZXRIZWlnaHQgfHwgZWxlbS5zY3JvbGxIZWlnaHQ7XG4gICAgfTtcblxuICAgIHBvc2l0aW9uLmdldFdpZHRoID0gZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgcmV0dXJuIGVsZW0ub2Zmc2V0V2lkdGggfHwgZWxlbS5zY3JvbGxXaWR0aDtcbiAgICB9O1xuXG4gICAgcG9zaXRpb24uZ2V0UGFnZVNpemUgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgdmFyIHNjcm9sbFdpZHRoLCBzY3JvbGxIZWlnaHQ7XG4gICAgICAgIHZhciBpbm5lcldpZHRoLCBpbm5lckhlaWdodDtcblxuICAgICAgICAvLyBJdCdzIG5vdCB2ZXJ5IGNsZWFyIHdoaWNoIGJsb2NrcyB3b3JrIHdpdGggd2hpY2ggYnJvd3NlcnMuXG4gICAgICAgIGlmIChzZWxmLmlubmVySGVpZ2h0ICYmIHNlbGYuc2Nyb2xsTWF4WSkge1xuICAgICAgICAgICAgc2Nyb2xsV2lkdGggPSBkb2MuYm9keS5zY3JvbGxXaWR0aDtcbiAgICAgICAgICAgIHNjcm9sbEhlaWdodCA9IHNlbGYuaW5uZXJIZWlnaHQgKyBzZWxmLnNjcm9sbE1heFk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9jLmJvZHkuc2Nyb2xsSGVpZ2h0ID4gZG9jLmJvZHkub2Zmc2V0SGVpZ2h0KSB7XG4gICAgICAgICAgICBzY3JvbGxXaWR0aCA9IGRvYy5ib2R5LnNjcm9sbFdpZHRoO1xuICAgICAgICAgICAgc2Nyb2xsSGVpZ2h0ID0gZG9jLmJvZHkuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc2Nyb2xsV2lkdGggPSBkb2MuYm9keS5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgIHNjcm9sbEhlaWdodCA9IGRvYy5ib2R5Lm9mZnNldEhlaWdodDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxmLmlubmVySGVpZ2h0KSB7XG4gICAgICAgICAgICAvLyBOb24tSUUgYnJvd3NlclxuICAgICAgICAgICAgaW5uZXJXaWR0aCA9IHNlbGYuaW5uZXJXaWR0aDtcbiAgICAgICAgICAgIGlubmVySGVpZ2h0ID0gc2VsZi5pbm5lckhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkb2MuZG9jdW1lbnRFbGVtZW50ICYmIGRvYy5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSB7XG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIElFIChJRSA2IHcvIGEgRE9DVFlQRSBkZWNsYXJhdGlvbilcbiAgICAgICAgICAgIGlubmVyV2lkdGggPSBkb2MuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgICAgICAgICAgaW5uZXJIZWlnaHQgPSBkb2MuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkb2MuYm9keSkge1xuICAgICAgICAgICAgLy8gT3RoZXIgdmVyc2lvbnMgb2YgSUVcbiAgICAgICAgICAgIGlubmVyV2lkdGggPSBkb2MuYm9keS5jbGllbnRXaWR0aDtcbiAgICAgICAgICAgIGlubmVySGVpZ2h0ID0gZG9jLmJvZHkuY2xpZW50SGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG1heFdpZHRoID0gTWF0aC5tYXgoc2Nyb2xsV2lkdGgsIGlubmVyV2lkdGgpO1xuICAgICAgICB2YXIgbWF4SGVpZ2h0ID0gTWF0aC5tYXgoc2Nyb2xsSGVpZ2h0LCBpbm5lckhlaWdodCk7XG4gICAgICAgIHJldHVybiBbbWF4V2lkdGgsIG1heEhlaWdodCwgaW5uZXJXaWR0aCwgaW5uZXJIZWlnaHRdO1xuICAgIH07XG5cbiAgICAvLyBIYW5kbGVzIHB1c2hpbmcgYW5kIHBvcHBpbmcgVGV4dGFyZWFTdGF0ZXMgZm9yIHVuZG8vcmVkbyBjb21tYW5kcy5cbiAgICAvLyBJIHNob3VsZCByZW5hbWUgdGhlIHN0YWNrIHZhcmlhYmxlcyB0byBsaXN0LlxuICAgIGZ1bmN0aW9uIFVuZG9NYW5hZ2VyKGNhbGxiYWNrLCBwYW5lbHMpIHtcblxuICAgICAgICB2YXIgdW5kb09iaiA9IHRoaXM7XG4gICAgICAgIHZhciB1bmRvU3RhY2sgPSBbXTsgLy8gQSBzdGFjayBvZiB1bmRvIHN0YXRlc1xuICAgICAgICB2YXIgc3RhY2tQdHIgPSAwOyAvLyBUaGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgc3RhdGVcbiAgICAgICAgdmFyIG1vZGUgPSBcIm5vbmVcIjtcbiAgICAgICAgdmFyIGxhc3RTdGF0ZTsgLy8gVGhlIGxhc3Qgc3RhdGVcbiAgICAgICAgdmFyIHRpbWVyOyAvLyBUaGUgc2V0VGltZW91dCBoYW5kbGUgZm9yIGNhbmNlbGxpbmcgdGhlIHRpbWVyXG4gICAgICAgIHZhciBpbnB1dFN0YXRlT2JqO1xuXG4gICAgICAgIC8vIFNldCB0aGUgbW9kZSBmb3IgbGF0ZXIgbG9naWMgc3RlcHMuXG4gICAgICAgIHZhciBzZXRNb2RlID0gZnVuY3Rpb24gKG5ld01vZGUsIG5vU2F2ZSkge1xuICAgICAgICAgICAgaWYgKG1vZGUgIT0gbmV3TW9kZSkge1xuICAgICAgICAgICAgICAgIG1vZGUgPSBuZXdNb2RlO1xuICAgICAgICAgICAgICAgIGlmICghbm9TYXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHNhdmVTdGF0ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF1YVNuaWZmZWQuaXNJRSB8fCBtb2RlICE9IFwibW92aW5nXCIpIHtcbiAgICAgICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQocmVmcmVzaFN0YXRlLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlucHV0U3RhdGVPYmogPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHZhciByZWZyZXNoU3RhdGUgPSBmdW5jdGlvbiAoaXNJbml0aWFsU3RhdGUpIHtcbiAgICAgICAgICAgIGlucHV0U3RhdGVPYmogPSBuZXcgVGV4dGFyZWFTdGF0ZShwYW5lbHMsIGlzSW5pdGlhbFN0YXRlKTtcbiAgICAgICAgICAgIHRpbWVyID0gdW5kZWZpbmVkO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc2V0Q29tbWFuZE1vZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtb2RlID0gXCJjb21tYW5kXCI7XG4gICAgICAgICAgICBzYXZlU3RhdGUoKTtcbiAgICAgICAgICAgIHRpbWVyID0gc2V0VGltZW91dChyZWZyZXNoU3RhdGUsIDApO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuY2FuVW5kbyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGFja1B0ciA+IDE7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5jYW5SZWRvID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHVuZG9TdGFja1tzdGFja1B0ciArIDFdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmVtb3ZlcyB0aGUgbGFzdCBzdGF0ZSBhbmQgcmVzdG9yZXMgaXQuXG4gICAgICAgIHRoaXMudW5kbyA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaWYgKHVuZG9PYmouY2FuVW5kbygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGF0IGFib3V0IHNldHRpbmcgc3RhdGUgLTEgdG8gbnVsbCBvciBjaGVja2luZyBmb3IgdW5kZWZpbmVkP1xuICAgICAgICAgICAgICAgICAgICBsYXN0U3RhdGUucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICBsYXN0U3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdW5kb1N0YWNrW3N0YWNrUHRyXSA9IG5ldyBUZXh0YXJlYVN0YXRlKHBhbmVscyk7XG4gICAgICAgICAgICAgICAgICAgIHVuZG9TdGFja1stLXN0YWNrUHRyXS5yZXN0b3JlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtb2RlID0gXCJub25lXCI7XG4gICAgICAgICAgICBwYW5lbHMuaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgIHJlZnJlc2hTdGF0ZSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJlZG8gYW4gYWN0aW9uLlxuICAgICAgICB0aGlzLnJlZG8gPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIGlmICh1bmRvT2JqLmNhblJlZG8oKSkge1xuXG4gICAgICAgICAgICAgICAgdW5kb1N0YWNrWysrc3RhY2tQdHJdLnJlc3RvcmUoKTtcblxuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbW9kZSA9IFwibm9uZVwiO1xuICAgICAgICAgICAgcGFuZWxzLmlucHV0LmZvY3VzKCk7XG4gICAgICAgICAgICByZWZyZXNoU3RhdGUoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBQdXNoIHRoZSBpbnB1dCBhcmVhIHN0YXRlIHRvIHRoZSBzdGFjay5cbiAgICAgICAgdmFyIHNhdmVTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBjdXJyU3RhdGUgPSBpbnB1dFN0YXRlT2JqIHx8IG5ldyBUZXh0YXJlYVN0YXRlKHBhbmVscyk7XG5cbiAgICAgICAgICAgIGlmICghY3VyclN0YXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1vZGUgPT0gXCJtb3ZpbmdcIikge1xuICAgICAgICAgICAgICAgIGlmICghbGFzdFN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RTdGF0ZSA9IGN1cnJTdGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmICh1bmRvU3RhY2tbc3RhY2tQdHIgLSAxXS50ZXh0ICE9IGxhc3RTdGF0ZS50ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHVuZG9TdGFja1tzdGFja1B0cisrXSA9IGxhc3RTdGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGFzdFN0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVuZG9TdGFja1tzdGFja1B0cisrXSA9IGN1cnJTdGF0ZTtcbiAgICAgICAgICAgIHVuZG9TdGFja1tzdGFja1B0ciArIDFdID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIGhhbmRsZUN0cmxZWiA9IGZ1bmN0aW9uIChldmVudCkge1xuXG4gICAgICAgICAgICB2YXIgaGFuZGxlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkgJiYgIWV2ZW50LmFsdEtleSkge1xuXG4gICAgICAgICAgICAgICAgLy8gSUUgYW5kIE9wZXJhIGRvIG5vdCBzdXBwb3J0IGNoYXJDb2RlLlxuICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQua2V5Q29kZTtcbiAgICAgICAgICAgICAgICB2YXIga2V5Q29kZUNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleUNvZGUpO1xuXG4gICAgICAgICAgICAgICAgc3dpdGNoIChrZXlDb2RlQ2hhci50b0xvd2VyQ2FzZSgpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInlcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuZG9PYmoucmVkbygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwielwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZG9PYmoudW5kbygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kb09iai5yZWRvKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGhhbmRsZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHdpbmRvdy5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB0aGUgbW9kZSBkZXBlbmRpbmcgb24gd2hhdCBpcyBnb2luZyBvbiBpbiB0aGUgaW5wdXQgYXJlYS5cbiAgICAgICAgdmFyIGhhbmRsZU1vZGVDaGFuZ2UgPSBmdW5jdGlvbiAoZXZlbnQpIHtcblxuICAgICAgICAgICAgaWYgKCFldmVudC5jdHJsS2V5ICYmICFldmVudC5tZXRhS2V5KSB7XG5cbiAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7XG5cbiAgICAgICAgICAgICAgICBpZiAoKGtleUNvZGUgPj0gMzMgJiYga2V5Q29kZSA8PSA0MCkgfHwgKGtleUNvZGUgPj0gNjMyMzIgJiYga2V5Q29kZSA8PSA2MzIzNSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMzMgLSA0MDogcGFnZSB1cC9kbiBhbmQgYXJyb3cga2V5c1xuICAgICAgICAgICAgICAgICAgICAvLyA2MzIzMiAtIDYzMjM1OiBwYWdlIHVwL2RuIGFuZCBhcnJvdyBrZXlzIG9uIHNhZmFyaVxuICAgICAgICAgICAgICAgICAgICBzZXRNb2RlKFwibW92aW5nXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChrZXlDb2RlID09IDggfHwga2V5Q29kZSA9PSA0NiB8fCBrZXlDb2RlID09IDEyNykge1xuICAgICAgICAgICAgICAgICAgICAvLyA4OiBiYWNrc3BhY2VcbiAgICAgICAgICAgICAgICAgICAgLy8gNDY6IGRlbGV0ZVxuICAgICAgICAgICAgICAgICAgICAvLyAxMjc6IGRlbGV0ZVxuICAgICAgICAgICAgICAgICAgICBzZXRNb2RlKFwiZGVsZXRpbmdcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGtleUNvZGUgPT0gMTMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMTM6IEVudGVyXG4gICAgICAgICAgICAgICAgICAgIHNldE1vZGUoXCJuZXdsaW5lc1wiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoa2V5Q29kZSA9PSAyNykge1xuICAgICAgICAgICAgICAgICAgICAvLyAyNzogZXNjYXBlXG4gICAgICAgICAgICAgICAgICAgIHNldE1vZGUoXCJlc2NhcGVcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChrZXlDb2RlIDwgMTYgfHwga2V5Q29kZSA+IDIwKSAmJiBrZXlDb2RlICE9IDkxKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDE2LTIwIGFyZSBzaGlmdCwgZXRjLlxuICAgICAgICAgICAgICAgICAgICAvLyA5MTogbGVmdCB3aW5kb3cga2V5XG4gICAgICAgICAgICAgICAgICAgIC8vIEkgdGhpbmsgdGhpcyBtaWdodCBiZSBhIGxpdHRsZSBtZXNzZWQgdXAgc2luY2UgdGhlcmUgYXJlXG4gICAgICAgICAgICAgICAgICAgIC8vIGEgbG90IG9mIG5vbnByaW50aW5nIGtleXMgYWJvdmUgMjAuXG4gICAgICAgICAgICAgICAgICAgIHNldE1vZGUoXCJ0eXBpbmdcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBzZXRFdmVudEhhbmRsZXJzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdXRpbC5hZGRFdmVudChwYW5lbHMuaW5wdXQsIFwia2V5cHJlc3NcIiwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgLy8ga2V5Q29kZSA4OTogeVxuICAgICAgICAgICAgICAgIC8vIGtleUNvZGUgOTA6IHpcbiAgICAgICAgICAgICAgICBpZiAoKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkgJiYgIWV2ZW50LmFsdEtleSAmJiAoZXZlbnQua2V5Q29kZSA9PSBLRVlfQ09ERS5ZIHx8IGV2ZW50LmtleUNvZGUgPT0gS0VZX0NPREUuWikpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdmFyIGhhbmRsZVBhc3RlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh1YVNuaWZmZWQuaXNJRSB8fCAoaW5wdXRTdGF0ZU9iaiAmJiBpbnB1dFN0YXRlT2JqLnRleHQgIT0gcGFuZWxzLmlucHV0LnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGltZXIgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gXCJwYXN0ZVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZVN0YXRlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU3RhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHV0aWwuYWRkRXZlbnQocGFuZWxzLmlucHV0LCBcImtleWRvd25cIiwgaGFuZGxlQ3RybFlaKTtcbiAgICAgICAgICAgIHV0aWwuYWRkRXZlbnQocGFuZWxzLmlucHV0LCBcImtleWRvd25cIiwgaGFuZGxlTW9kZUNoYW5nZSk7XG4gICAgICAgICAgICB1dGlsLmFkZEV2ZW50KHBhbmVscy5pbnB1dCwgXCJtb3VzZWRvd25cIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldE1vZGUoXCJtb3ZpbmdcIik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcGFuZWxzLmlucHV0Lm9ucGFzdGUgPSBoYW5kbGVQYXN0ZTtcbiAgICAgICAgICAgIHBhbmVscy5pbnB1dC5vbmRyb3AgPSBoYW5kbGVQYXN0ZTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldEV2ZW50SGFuZGxlcnMoKTtcbiAgICAgICAgICAgIHJlZnJlc2hTdGF0ZSh0cnVlKTtcbiAgICAgICAgICAgIHNhdmVTdGF0ZSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBlbmQgb2YgVW5kb01hbmFnZXJcblxuICAgIC8vIFRoZSBpbnB1dCB0ZXh0YXJlYSBzdGF0ZS9jb250ZW50cy5cbiAgICAvLyBUaGlzIGlzIHVzZWQgdG8gaW1wbGVtZW50IHVuZG8vcmVkbyBieSB0aGUgdW5kbyBtYW5hZ2VyLlxuICAgIGZ1bmN0aW9uIFRleHRhcmVhU3RhdGUocGFuZWxzLCBpc0luaXRpYWxTdGF0ZSkge1xuXG4gICAgICAgIC8vIEFsaWFzZXNcbiAgICAgICAgdmFyIHN0YXRlT2JqID0gdGhpcztcbiAgICAgICAgdmFyIGlucHV0QXJlYSA9IHBhbmVscy5pbnB1dDtcbiAgICAgICAgdGhpcy5pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF1dGlsLmlzVmlzaWJsZShpbnB1dEFyZWEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0luaXRpYWxTdGF0ZSAmJiBkb2MuYWN0aXZlRWxlbWVudCAmJiBkb2MuYWN0aXZlRWxlbWVudCAhPT0gaW5wdXRBcmVhKSB7IC8vIHRoaXMgaGFwcGVucyB3aGVuIHRhYmJpbmcgb3V0IG9mIHRoZSBpbnB1dCBib3hcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc2V0SW5wdXRBcmVhU2VsZWN0aW9uU3RhcnRFbmQoKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9wID0gaW5wdXRBcmVhLnNjcm9sbFRvcDtcbiAgICAgICAgICAgIGlmICghdGhpcy50ZXh0ICYmIGlucHV0QXJlYS5zZWxlY3Rpb25TdGFydCB8fCBpbnB1dEFyZWEuc2VsZWN0aW9uU3RhcnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHQgPSBpbnB1dEFyZWEudmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldHMgdGhlIHNlbGVjdGVkIHRleHQgaW4gdGhlIGlucHV0IGJveCBhZnRlciB3ZSd2ZSBwZXJmb3JtZWQgYW5cbiAgICAgICAgLy8gb3BlcmF0aW9uLlxuICAgICAgICB0aGlzLnNldElucHV0QXJlYVNlbGVjdGlvbiA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaWYgKCF1dGlsLmlzVmlzaWJsZShpbnB1dEFyZWEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaW5wdXRBcmVhLnNlbGVjdGlvblN0YXJ0ICE9PSB1bmRlZmluZWQgJiYgIXVhU25pZmZlZC5pc09wZXJhKSB7XG5cbiAgICAgICAgICAgICAgICBpbnB1dEFyZWEuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICBpbnB1dEFyZWEuc2VsZWN0aW9uU3RhcnQgPSBzdGF0ZU9iai5zdGFydDtcbiAgICAgICAgICAgICAgICBpbnB1dEFyZWEuc2VsZWN0aW9uRW5kID0gc3RhdGVPYmouZW5kO1xuICAgICAgICAgICAgICAgIGlucHV0QXJlYS5zY3JvbGxUb3AgPSBzdGF0ZU9iai5zY3JvbGxUb3A7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkb2Muc2VsZWN0aW9uKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoZG9jLmFjdGl2ZUVsZW1lbnQgJiYgZG9jLmFjdGl2ZUVsZW1lbnQgIT09IGlucHV0QXJlYSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaW5wdXRBcmVhLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gaW5wdXRBcmVhLmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgICAgICAgICAgIHJhbmdlLm1vdmVTdGFydChcImNoYXJhY3RlclwiLCAtaW5wdXRBcmVhLnZhbHVlLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgcmFuZ2UubW92ZUVuZChcImNoYXJhY3RlclwiLCAtaW5wdXRBcmVhLnZhbHVlLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgcmFuZ2UubW92ZUVuZChcImNoYXJhY3RlclwiLCBzdGF0ZU9iai5lbmQpO1xuICAgICAgICAgICAgICAgIHJhbmdlLm1vdmVTdGFydChcImNoYXJhY3RlclwiLCBzdGF0ZU9iai5zdGFydCk7XG4gICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zZXRJbnB1dEFyZWFTZWxlY3Rpb25TdGFydEVuZCA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgaWYgKCFwYW5lbHMuaWVDYWNoZWRSYW5nZSAmJiAoaW5wdXRBcmVhLnNlbGVjdGlvblN0YXJ0IHx8IGlucHV0QXJlYS5zZWxlY3Rpb25TdGFydCA9PT0gMCkpIHtcblxuICAgICAgICAgICAgICAgIHN0YXRlT2JqLnN0YXJ0ID0gaW5wdXRBcmVhLnNlbGVjdGlvblN0YXJ0O1xuICAgICAgICAgICAgICAgIHN0YXRlT2JqLmVuZCA9IGlucHV0QXJlYS5zZWxlY3Rpb25FbmQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkb2Muc2VsZWN0aW9uKSB7XG5cbiAgICAgICAgICAgICAgICBzdGF0ZU9iai50ZXh0ID0gdXRpbC5maXhFb2xDaGFycyhpbnB1dEFyZWEudmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgLy8gSUUgbG9zZXMgdGhlIHNlbGVjdGlvbiBpbiB0aGUgdGV4dGFyZWEgd2hlbiBidXR0b25zIGFyZVxuICAgICAgICAgICAgICAgIC8vIGNsaWNrZWQuICBPbiBJRSB3ZSBjYWNoZSB0aGUgc2VsZWN0aW9uLiBIZXJlLCBpZiBzb21ldGhpbmcgaXMgY2FjaGVkLFxuICAgICAgICAgICAgICAgIC8vIHdlIHRha2UgaXQuXG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gcGFuZWxzLmllQ2FjaGVkUmFuZ2UgfHwgZG9jLnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO1xuXG4gICAgICAgICAgICAgICAgdmFyIGZpeGVkUmFuZ2UgPSB1dGlsLmZpeEVvbENoYXJzKHJhbmdlLnRleHQpO1xuICAgICAgICAgICAgICAgIHZhciBtYXJrZXIgPSBcIlxceDA3XCI7XG4gICAgICAgICAgICAgICAgdmFyIG1hcmtlZFJhbmdlID0gbWFya2VyICsgZml4ZWRSYW5nZSArIG1hcmtlcjtcbiAgICAgICAgICAgICAgICByYW5nZS50ZXh0ID0gbWFya2VkUmFuZ2U7XG4gICAgICAgICAgICAgICAgdmFyIGlucHV0VGV4dCA9IHV0aWwuZml4RW9sQ2hhcnMoaW5wdXRBcmVhLnZhbHVlKTtcblxuICAgICAgICAgICAgICAgIHJhbmdlLm1vdmVTdGFydChcImNoYXJhY3RlclwiLCAtbWFya2VkUmFuZ2UubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICByYW5nZS50ZXh0ID0gZml4ZWRSYW5nZTtcblxuICAgICAgICAgICAgICAgIHN0YXRlT2JqLnN0YXJ0ID0gaW5wdXRUZXh0LmluZGV4T2YobWFya2VyKTtcbiAgICAgICAgICAgICAgICBzdGF0ZU9iai5lbmQgPSBpbnB1dFRleHQubGFzdEluZGV4T2YobWFya2VyKSAtIG1hcmtlci5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICB2YXIgbGVuID0gc3RhdGVPYmoudGV4dC5sZW5ndGggLSB1dGlsLmZpeEVvbENoYXJzKGlucHV0QXJlYS52YWx1ZSkubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgaWYgKGxlbikge1xuICAgICAgICAgICAgICAgICAgICByYW5nZS5tb3ZlU3RhcnQoXCJjaGFyYWN0ZXJcIiwgLWZpeGVkUmFuZ2UubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaXhlZFJhbmdlICs9IFwiXFxuXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZU9iai5lbmQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByYW5nZS50ZXh0ID0gZml4ZWRSYW5nZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocGFuZWxzLmllQ2FjaGVkUmFuZ2UpXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlT2JqLnNjcm9sbFRvcCA9IHBhbmVscy5pZUNhY2hlZFNjcm9sbFRvcDsgLy8gdGhpcyBpcyBzZXQgYWxvbmdzaWRlIHdpdGggaWVDYWNoZWRSYW5nZVxuXG4gICAgICAgICAgICAgICAgcGFuZWxzLmllQ2FjaGVkUmFuZ2UgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRJbnB1dEFyZWFTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXN0b3JlIHRoaXMgc3RhdGUgaW50byB0aGUgaW5wdXQgYXJlYS5cbiAgICAgICAgdGhpcy5yZXN0b3JlID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBpZiAoc3RhdGVPYmoudGV4dCAhPSB1bmRlZmluZWQgJiYgc3RhdGVPYmoudGV4dCAhPSBpbnB1dEFyZWEudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEFyZWEudmFsdWUgPSBzdGF0ZU9iai50ZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRJbnB1dEFyZWFTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIGlucHV0QXJlYS5zY3JvbGxUb3AgPSBzdGF0ZU9iai5zY3JvbGxUb3A7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gR2V0cyBhIGNvbGxlY3Rpb24gb2YgSFRNTCBjaHVua3MgZnJvbSB0aGUgaW5wdHV0IHRleHRhcmVhLlxuICAgICAgICB0aGlzLmdldENodW5rcyA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgdmFyIGNodW5rID0gbmV3IENodW5rcygpO1xuICAgICAgICAgICAgY2h1bmsuYmVmb3JlID0gdXRpbC5maXhFb2xDaGFycyhzdGF0ZU9iai50ZXh0LnN1YnN0cmluZygwLCBzdGF0ZU9iai5zdGFydCkpO1xuICAgICAgICAgICAgY2h1bmsuc3RhcnRUYWcgPSBcIlwiO1xuICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gdXRpbC5maXhFb2xDaGFycyhzdGF0ZU9iai50ZXh0LnN1YnN0cmluZyhzdGF0ZU9iai5zdGFydCwgc3RhdGVPYmouZW5kKSk7XG4gICAgICAgICAgICBjaHVuay5lbmRUYWcgPSBcIlwiO1xuICAgICAgICAgICAgY2h1bmsuYWZ0ZXIgPSB1dGlsLmZpeEVvbENoYXJzKHN0YXRlT2JqLnRleHQuc3Vic3RyaW5nKHN0YXRlT2JqLmVuZCkpO1xuICAgICAgICAgICAgY2h1bmsuc2Nyb2xsVG9wID0gc3RhdGVPYmouc2Nyb2xsVG9wO1xuXG4gICAgICAgICAgICByZXR1cm4gY2h1bms7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0cyB0aGUgVGV4dGFyZWFTdGF0ZSBwcm9wZXJ0aWVzIGdpdmVuIGEgY2h1bmsgb2YgbWFya2Rvd24uXG4gICAgICAgIHRoaXMuc2V0Q2h1bmtzID0gZnVuY3Rpb24gKGNodW5rKSB7XG5cbiAgICAgICAgICAgIGNodW5rLmJlZm9yZSA9IGNodW5rLmJlZm9yZSArIGNodW5rLnN0YXJ0VGFnO1xuICAgICAgICAgICAgY2h1bmsuYWZ0ZXIgPSBjaHVuay5lbmRUYWcgKyBjaHVuay5hZnRlcjtcblxuICAgICAgICAgICAgdGhpcy5zdGFydCA9IGNodW5rLmJlZm9yZS5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLmVuZCA9IGNodW5rLmJlZm9yZS5sZW5ndGggKyBjaHVuay5zZWxlY3Rpb24ubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy50ZXh0ID0gY2h1bmsuYmVmb3JlICsgY2h1bmsuc2VsZWN0aW9uICsgY2h1bmsuYWZ0ZXI7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbFRvcCA9IGNodW5rLnNjcm9sbFRvcDtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIFByZXZpZXdNYW5hZ2VyKGNvbnZlcnRlciwgcGFuZWxzLCBwcmV2aWV3UmVmcmVzaENhbGxiYWNrKSB7XG5cbiAgICAgICAgdmFyIG1hbmFnZXJPYmogPSB0aGlzO1xuICAgICAgICB2YXIgdGltZW91dDtcbiAgICAgICAgdmFyIGVsYXBzZWRUaW1lO1xuICAgICAgICB2YXIgb2xkSW5wdXRUZXh0O1xuICAgICAgICB2YXIgbWF4RGVsYXkgPSAzMDAwO1xuICAgICAgICB2YXIgc3RhcnRUeXBlID0gXCJkZWxheWVkXCI7IC8vIFRoZSBvdGhlciBsZWdhbCB2YWx1ZSBpcyBcIm1hbnVhbFwiXG5cbiAgICAgICAgLy8gQWRkcyBldmVudCBsaXN0ZW5lcnMgdG8gZWxlbWVudHNcbiAgICAgICAgdmFyIHNldHVwRXZlbnRzID0gZnVuY3Rpb24gKGlucHV0RWxlbSwgbGlzdGVuZXIpIHtcblxuICAgICAgICAgICAgdXRpbC5hZGRFdmVudChpbnB1dEVsZW0sIFwiaW5wdXRcIiwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgaW5wdXRFbGVtLm9ucGFzdGUgPSBsaXN0ZW5lcjtcbiAgICAgICAgICAgIGlucHV0RWxlbS5vbmRyb3AgPSBsaXN0ZW5lcjtcblxuICAgICAgICAgICAgdXRpbC5hZGRFdmVudChpbnB1dEVsZW0sIFwia2V5cHJlc3NcIiwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgdXRpbC5hZGRFdmVudChpbnB1dEVsZW0sIFwia2V5ZG93blwiLCBsaXN0ZW5lcik7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIGdldERvY1Njcm9sbFRvcCA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IDA7XG5cbiAgICAgICAgICAgIGlmICh3aW5kb3cuaW5uZXJIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB3aW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgaWYgKGRvYy5kb2N1bWVudEVsZW1lbnQgJiYgZG9jLmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3ApIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZG9jLmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvYy5ib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBkb2MuYm9keS5zY3JvbGxUb3A7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgbWFrZVByZXZpZXdIdG1sID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyByZWdpc3RlcmVkIHByZXZpZXcgcGFuZWxcbiAgICAgICAgICAgIC8vIHRoZXJlIGlzIG5vdGhpbmcgdG8gZG8uXG4gICAgICAgICAgICBpZiAoIXBhbmVscy5wcmV2aWV3KVxuICAgICAgICAgICAgICAgIHJldHVybjtcblxuXG4gICAgICAgICAgICB2YXIgdGV4dCA9IHBhbmVscy5pbnB1dC52YWx1ZTtcbiAgICAgICAgICAgIGlmICh0ZXh0ICYmIHRleHQgPT0gb2xkSW5wdXRUZXh0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBJbnB1dCB0ZXh0IGhhc24ndCBjaGFuZ2VkLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgb2xkSW5wdXRUZXh0ID0gdGV4dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHByZXZUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgICAgIGNvbnZlcnRlci5tYWtlSHRtbEFzeW5jKHRleHQpLnRoZW4oZnVuY3Rpb24oaHRtbCkge1xuICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgcHJvY2Vzc2luZyB0aW1lIG9mIHRoZSBIVE1MIGNyZWF0aW9uLlxuICAgICAgICAgICAgICAgIC8vIEl0J3MgdXNlZCBhcyB0aGUgZGVsYXkgdGltZSBpbiB0aGUgZXZlbnQgbGlzdGVuZXIuXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpbWUgPSBjdXJyVGltZSAtIHByZXZUaW1lO1xuXG4gICAgICAgICAgICAgICAgcHVzaFByZXZpZXdIdG1sKGh0bWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gc2V0VGltZW91dCBpcyBhbHJlYWR5IHVzZWQuICBVc2VkIGFzIGFuIGV2ZW50IGxpc3RlbmVyLlxuICAgICAgICB2YXIgYXBwbHlUaW1lb3V0ID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBpZiAodGltZW91dCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgICAgICB0aW1lb3V0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3RhcnRUeXBlICE9PSBcIm1hbnVhbFwiKSB7XG5cbiAgICAgICAgICAgICAgICB2YXIgZGVsYXkgPSAwO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0VHlwZSA9PT0gXCJkZWxheWVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsYXkgPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZGVsYXkgPiBtYXhEZWxheSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxheSA9IG1heERlbGF5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChtYWtlUHJldmlld0h0bWwsIGRlbGF5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgZ2V0U2NhbGVGYWN0b3IgPSBmdW5jdGlvbiAocGFuZWwpIHtcbiAgICAgICAgICAgIGlmIChwYW5lbC5zY3JvbGxIZWlnaHQgPD0gcGFuZWwuY2xpZW50SGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGFuZWwuc2Nyb2xsVG9wIC8gKHBhbmVsLnNjcm9sbEhlaWdodCAtIHBhbmVsLmNsaWVudEhlaWdodCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIHNldFBhbmVsU2Nyb2xsVG9wcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChwYW5lbHMucHJldmlldykge1xuICAgICAgICAgICAgICAgIHBhbmVscy5wcmV2aWV3LnNjcm9sbFRvcCA9IChwYW5lbHMucHJldmlldy5zY3JvbGxIZWlnaHQgLSBwYW5lbHMucHJldmlldy5jbGllbnRIZWlnaHQpICogZ2V0U2NhbGVGYWN0b3IocGFuZWxzLnByZXZpZXcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucmVmcmVzaCA9IGZ1bmN0aW9uIChyZXF1aXJlc1JlZnJlc2gpIHtcblxuICAgICAgICAgICAgaWYgKHJlcXVpcmVzUmVmcmVzaCkge1xuICAgICAgICAgICAgICAgIG9sZElucHV0VGV4dCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgbWFrZVByZXZpZXdIdG1sKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhcHBseVRpbWVvdXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnByb2Nlc3NpbmdUaW1lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGVsYXBzZWRUaW1lO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBpc0ZpcnN0VGltZUZpbGxlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gSUUgZG9lc24ndCBsZXQgeW91IHVzZSBpbm5lckhUTUwgaWYgdGhlIGVsZW1lbnQgaXMgY29udGFpbmVkIHNvbWV3aGVyZSBpbiBhIHRhYmxlXG4gICAgICAgIC8vICh3aGljaCBpcyB0aGUgY2FzZSBmb3IgaW5saW5lIGVkaXRpbmcpIC0tIGluIHRoYXQgY2FzZSwgZGV0YWNoIHRoZSBlbGVtZW50LCBzZXQgdGhlXG4gICAgICAgIC8vIHZhbHVlLCBhbmQgcmVhdHRhY2guIFllcywgdGhhdCAqaXMqIHJpZGljdWxvdXMuXG4gICAgICAgIHZhciBpZVNhZmVQcmV2aWV3U2V0ID0gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIHZhciBwcmV2aWV3ID0gcGFuZWxzLnByZXZpZXc7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gcHJldmlldy5wYXJlbnROb2RlO1xuICAgICAgICAgICAgdmFyIHNpYmxpbmcgPSBwcmV2aWV3Lm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHByZXZpZXcpO1xuICAgICAgICAgICAgcHJldmlldy5pbm5lckhUTUwgPSB0ZXh0O1xuICAgICAgICAgICAgaWYgKCFzaWJsaW5nKVxuICAgICAgICAgICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChwcmV2aWV3KTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHByZXZpZXcsIHNpYmxpbmcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG5vblN1Y2t5QnJvd3NlclByZXZpZXdTZXQgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICAgICAgcGFuZWxzLnByZXZpZXcuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcmV2aWV3U2V0dGVyO1xuXG4gICAgICAgIHZhciBwcmV2aWV3U2V0ID0gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIGlmIChwcmV2aWV3U2V0dGVyKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcmV2aWV3U2V0dGVyKHRleHQpO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5vblN1Y2t5QnJvd3NlclByZXZpZXdTZXQodGV4dCk7XG4gICAgICAgICAgICAgICAgcHJldmlld1NldHRlciA9IG5vblN1Y2t5QnJvd3NlclByZXZpZXdTZXQ7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcHJldmlld1NldHRlciA9IGllU2FmZVByZXZpZXdTZXQ7XG4gICAgICAgICAgICAgICAgcHJldmlld1NldHRlcih0ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgcHVzaFByZXZpZXdIdG1sID0gZnVuY3Rpb24gKHRleHQpIHtcblxuICAgICAgICAgICAgdmFyIGVtcHR5VG9wID0gcG9zaXRpb24uZ2V0VG9wKHBhbmVscy5pbnB1dCkgLSBnZXREb2NTY3JvbGxUb3AoKTtcblxuICAgICAgICAgICAgaWYgKHBhbmVscy5wcmV2aWV3KSB7XG4gICAgICAgICAgICAgICAgcHJldmlld1NldCh0ZXh0KTtcbiAgICAgICAgICAgICAgICBwcmV2aWV3UmVmcmVzaENhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNldFBhbmVsU2Nyb2xsVG9wcygpO1xuXG4gICAgICAgICAgICBpZiAoaXNGaXJzdFRpbWVGaWxsZWQpIHtcbiAgICAgICAgICAgICAgICBpc0ZpcnN0VGltZUZpbGxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGZ1bGxUb3AgPSBwb3NpdGlvbi5nZXRUb3AocGFuZWxzLmlucHV0KSAtIGdldERvY1Njcm9sbFRvcCgpO1xuXG4gICAgICAgICAgICBpZiAodWFTbmlmZmVkLmlzSUUpIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbEJ5KDAsIGZ1bGxUb3AgLSBlbXB0eVRvcCk7XG4gICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2Nyb2xsQnkoMCwgZnVsbFRvcCAtIGVtcHR5VG9wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgaW5pdCA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgc2V0dXBFdmVudHMocGFuZWxzLmlucHV0LCBhcHBseVRpbWVvdXQpO1xuICAgICAgICAgICAgbWFrZVByZXZpZXdIdG1sKCk7XG5cbiAgICAgICAgICAgIGlmIChwYW5lbHMucHJldmlldykge1xuICAgICAgICAgICAgICAgIHBhbmVscy5wcmV2aWV3LnNjcm9sbFRvcCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaW5pdCgpO1xuICAgIH07XG5cbiAgICAvLyBDcmVhdGVzIHRoZSBiYWNrZ3JvdW5kIGJlaGluZCB0aGUgaHlwZXJsaW5rIHRleHQgZW50cnkgYm94LlxuICAgIC8vIEFuZCBkb3dubG9hZCBkaWFsb2dcbiAgICAvLyBNb3N0IG9mIHRoaXMgaGFzIGJlZW4gbW92ZWQgdG8gQ1NTIGJ1dCB0aGUgZGl2IGNyZWF0aW9uIGFuZFxuICAgIC8vIGJyb3dzZXItc3BlY2lmaWMgaGFja3MgcmVtYWluIGhlcmUuXG4gICAgdWkuY3JlYXRlQmFja2dyb3VuZCA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICB2YXIgYmFja2dyb3VuZCA9IGRvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLFxuICAgICAgICAgICAgc3R5bGUgPSBiYWNrZ3JvdW5kLnN0eWxlO1xuXG4gICAgICAgIGJhY2tncm91bmQuY2xhc3NOYW1lID0gXCJ3bWQtcHJvbXB0LWJhY2tncm91bmRcIjtcblxuICAgICAgICBzdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgc3R5bGUudG9wID0gXCIwXCI7XG5cbiAgICAgICAgLy8gIHotaW5kZXggd2FzIGNoYW5nZWQgZnJvbSAxMDMwIHRvIDg5NTAgYmVjYXVzZSB6LWluZGV4XG4gICAgICAgIC8vICB2YXJpYWJsZXMgd2VyZSB1cGRhdGVkLiA4OTUwID09IHZhcigtLXppLW1vZGFscy1iYWNrZ3JvdW5kKVxuICAgICAgICBzdHlsZS56SW5kZXggPSBcIjg5NTBcIjtcblxuICAgICAgICBpZiAodWFTbmlmZmVkLmlzSUUpIHtcbiAgICAgICAgICAgIHN0eWxlLmZpbHRlciA9IFwiYWxwaGEob3BhY2l0eT01MClcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0eWxlLm9wYWNpdHkgPSBcIjAuNVwiO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHBhZ2VTaXplID0gcG9zaXRpb24uZ2V0UGFnZVNpemUoKTtcbiAgICAgICAgc3R5bGUuaGVpZ2h0ID0gcGFnZVNpemVbMV0gKyBcInB4XCI7XG5cbiAgICAgICAgaWYgKHVhU25pZmZlZC5pc0lFKSB7XG4gICAgICAgICAgICBzdHlsZS5sZWZ0ID0gZG9jLmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgICAgICAgICAgc3R5bGUud2lkdGggPSBkb2MuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3R5bGUubGVmdCA9IFwiMFwiO1xuICAgICAgICAgICAgc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvYy5ib2R5LmFwcGVuZENoaWxkKGJhY2tncm91bmQpO1xuICAgICAgICByZXR1cm4gYmFja2dyb3VuZDtcbiAgICB9O1xuXG4gICAgLy8gVGhpcyBzaW11bGF0ZXMgYSBtb2RhbCBkaWFsb2cgYm94IGFuZCBhc2tzIGZvciB0aGUgVVJMIHdoZW4geW91XG4gICAgLy8gY2xpY2sgdGhlIGh5cGVybGluayBvciBpbWFnZSBidXR0b25zLlxuICAgIC8vXG4gICAgLy8gdGV4dDogVGhlIGh0bWwgZm9yIHRoZSBpbnB1dCBib3guXG4gICAgLy8gZGVmYXVsdElucHV0VGV4dDogVGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBhcHBlYXJzIGluIHRoZSBpbnB1dCBib3guXG4gICAgLy8gb2s6IFRoZSB0ZXh0IGZvciB0aGUgT0sgYnV0dG9uXG4gICAgLy8gY2FuY2VsOiBUaGUgdGV4dCBmb3IgdGhlIENhbmNlbCBidXR0b25cbiAgICAvLyBjYWxsYmFjazogVGhlIGZ1bmN0aW9uIHdoaWNoIGlzIGV4ZWN1dGVkIHdoZW4gdGhlIHByb21wdCBpcyBkaXNtaXNzZWQsIGVpdGhlciB2aWEgT0sgb3IgQ2FuY2VsLlxuICAgIC8vICAgICAgSXQgcmVjZWl2ZXMgYSBzaW5nbGUgYXJndW1lbnQ7IGVpdGhlciB0aGUgZW50ZXJlZCB0ZXh0IChpZiBPSyB3YXMgY2hvc2VuKSBvciBudWxsIChpZiBDYW5jZWxcbiAgICAvLyAgICAgIHdhcyBjaG9zZW4pLlxuICAgIHVpLnByb21wdCA9IGZ1bmN0aW9uICh0ZXh0LCBkZWZhdWx0SW5wdXRUZXh0LCBvaywgY2FuY2VsLCBjYWxsYmFjaykge1xuXG4gICAgICAgIC8vIFRoZXNlIHZhcmlhYmxlcyBuZWVkIHRvIGJlIGRlY2xhcmVkIGF0IHRoaXMgbGV2ZWwgc2luY2UgdGhleSBhcmUgdXNlZFxuICAgICAgICAvLyBpbiBtdWx0aXBsZSBmdW5jdGlvbnMuXG4gICAgICAgIHZhciBkaWFsb2c7ICAgICAgICAgLy8gVGhlIGRpYWxvZyBib3guXG4gICAgICAgIHZhciBpbnB1dDsgICAgICAgICAvLyBUaGUgdGV4dCBib3ggd2hlcmUgeW91IGVudGVyIHRoZSBoeXBlcmxpbmsuXG5cblxuICAgICAgICBpZiAoZGVmYXVsdElucHV0VGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkZWZhdWx0SW5wdXRUZXh0ID0gXCJcIjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVzZWQgYXMgYSBrZXlkb3duIGV2ZW50IGhhbmRsZXIuIEVzYyBkaXNtaXNzZXMgdGhlIHByb21wdC5cbiAgICAgICAgLy8gS2V5IGNvZGUgMjcgaXMgRVNDLlxuICAgICAgICB2YXIgY2hlY2tFc2NhcGUgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICB2YXIgY29kZSA9IChrZXkuY2hhckNvZGUgfHwga2V5LmtleUNvZGUpO1xuICAgICAgICAgICAgaWYgKGNvZGUgPT09IDI3KSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleS5zdG9wUHJvcGFnYXRpb24pIGtleS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBjbG9zZSh0cnVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gRGlzbWlzc2VzIHRoZSBoeXBlcmxpbmsgaW5wdXQgYm94LlxuICAgICAgICAvLyBpc0NhbmNlbCBpcyB0cnVlIGlmIHdlIGRvbid0IGNhcmUgYWJvdXQgdGhlIGlucHV0IHRleHQuXG4gICAgICAgIC8vIGlzQ2FuY2VsIGlzIGZhbHNlIGlmIHdlIGFyZSBnb2luZyB0byBrZWVwIHRoZSB0ZXh0LlxuICAgICAgICB2YXIgY2xvc2UgPSBmdW5jdGlvbiAoaXNDYW5jZWwpIHtcbiAgICAgICAgICAgIHV0aWwucmVtb3ZlRXZlbnQoZG9jLmJvZHksIFwia2V5dXBcIiwgY2hlY2tFc2NhcGUpO1xuICAgICAgICAgICAgdmFyIHRleHQgPSBpbnB1dC52YWx1ZTtcblxuICAgICAgICAgICAgaWYgKGlzQ2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgdGV4dCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBGaXhlcyBjb21tb24gcGFzdGluZyBlcnJvcnMuXG4gICAgICAgICAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXmh0dHA6XFwvXFwvKGh0dHBzP3xmdHApOlxcL1xcLy8sICckMTovLycpO1xuICAgICAgICAgICAgICAgIGlmICghL14oPzpodHRwcz98ZnRwKTpcXC9cXC8vLnRlc3QodGV4dCkpXG4gICAgICAgICAgICAgICAgICAgIHRleHQgPSAnaHR0cDovLycgKyB0ZXh0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkaWFsb2cucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkaWFsb2cpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayh0ZXh0KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfTtcblxuXG5cbiAgICAgICAgLy8gQ3JlYXRlIHRoZSB0ZXh0IGlucHV0IGJveCBmb3JtL3dpbmRvdy5cbiAgICAgICAgdmFyIGNyZWF0ZURpYWxvZyA9IGZ1bmN0aW9uIChvaywgY2FuY2VsKSB7XG5cbiAgICAgICAgICAgIC8vIFRoZSBtYWluIGRpYWxvZyBib3guXG4gICAgICAgICAgICBkaWFsb2cgPSBkb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgICAgIGRpYWxvZy5jbGFzc05hbWUgPSBcIndtZC1wcm9tcHQtZGlhbG9nXCI7XG4gICAgICAgICAgICBkaWFsb2cuc3R5bGUucGFkZGluZyA9IFwiMTBweDtcIjtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS5wb3NpdGlvbiA9IFwiZml4ZWRcIjtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS53aWR0aCA9IFwiNDAwcHhcIjtcblxuICAgICAgICAgICAgLy8gIHotaW5kZXggdmFsdWUgd2FzIGNoYW5nZWQgZnJvbSAxMDQwIHRvIDkwMDAgYXMgdGhpc1xuICAgICAgICAgICAgLy8gIG1hdGNoZXMgd2l0aCB0aGUgY3VycmVudCB2YWx1ZSBmb3IgdmFyKC0temktbW9kYWxzKVxuICAgICAgICAgICAgZGlhbG9nLnN0eWxlLnpJbmRleCA9IFwiOTAwMFwiO1xuXG4gICAgICAgICAgICAvLyBUaGUgZGlhbG9nIHRleHQuXG4gICAgICAgICAgICB2YXIgcXVlc3Rpb24gPSBkb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgICAgIHF1ZXN0aW9uLmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgICAgICBxdWVzdGlvbi5zdHlsZS5wYWRkaW5nID0gXCI1cHhcIjtcbiAgICAgICAgICAgIGRpYWxvZy5hcHBlbmRDaGlsZChxdWVzdGlvbik7XG5cbiAgICAgICAgICAgIC8vIFRoZSB3ZWIgZm9ybSBjb250YWluZXIgZm9yIHRoZSB0ZXh0IGJveCBhbmQgYnV0dG9ucy5cbiAgICAgICAgICAgIHZhciBmb3JtID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJmb3JtXCIpLFxuICAgICAgICAgICAgICAgIHN0eWxlID0gZm9ybS5zdHlsZTtcbiAgICAgICAgICAgIGZvcm0ub25zdWJtaXQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBjbG9zZShmYWxzZSk7IH07XG4gICAgICAgICAgICBzdHlsZS5wYWRkaW5nID0gXCIwXCI7XG4gICAgICAgICAgICBzdHlsZS5tYXJnaW4gPSBcIjBcIjtcbiAgICAgICAgICAgIHN0eWxlLmNzc0Zsb2F0ID0gXCJsZWZ0XCI7XG4gICAgICAgICAgICBzdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICAgICAgICAgICAgc3R5bGUudGV4dEFsaWduID0gXCJjZW50ZXJcIjtcbiAgICAgICAgICAgIHN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICAgICAgICAgICAgZGlhbG9nLmFwcGVuZENoaWxkKGZvcm0pO1xuXG4gICAgICAgICAgICAvLyBUaGUgaW5wdXQgdGV4dCBib3hcbiAgICAgICAgICAgIGlucHV0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcbiAgICAgICAgICAgIGlucHV0LnR5cGUgPSBcInRleHRcIjtcbiAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9IFwicy1pbnB1dCBtYjE2XCI7XG4gICAgICAgICAgICBpbnB1dC52YWx1ZSA9IGRlZmF1bHRJbnB1dFRleHQ7XG4gICAgICAgICAgICBpbnB1dC5pZCA9IFwicHJvbXB0LWRpYWxvZy1pbnB1dFwiO1xuICAgICAgICAgICAgc3R5bGUgPSBpbnB1dC5zdHlsZTtcbiAgICAgICAgICAgIHN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICAgICAgICBzdHlsZS53aWR0aCA9IFwiODAlXCI7XG4gICAgICAgICAgICBzdHlsZS5tYXJnaW5MZWZ0ID0gc3R5bGUubWFyZ2luUmlnaHQgPSBcImF1dG9cIjtcbiAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoaW5wdXQpO1xuXG4gICAgICAgICAgICAvLyBUaGUgb2sgYnV0dG9uXG4gICAgICAgICAgICB2YXIgb2tCdXR0b24gPSBkb2MuY3JlYXRlRWxlbWVudChcImJ1dHRvblwiKTtcbiAgICAgICAgICAgIG9rQnV0dG9uLmNsYXNzTmFtZSA9IFwicy1idG4gcy1idG5fX2ZpbGxlZFwiO1xuICAgICAgICAgICAgb2tCdXR0b24udHlwZSA9IFwiYnV0dG9uXCI7XG4gICAgICAgICAgICBva0J1dHRvbi5vbmNsaWNrID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gY2xvc2UoZmFsc2UpOyB9O1xuICAgICAgICAgICAgb2tCdXR0b24uaW5uZXJUZXh0ID0gXCJJbnNlcnRcIjtcblxuXG4gICAgICAgICAgICAvLyBUaGUgY2FuY2VsIGJ1dHRvblxuICAgICAgICAgICAgdmFyIGNhbmNlbEJ1dHRvbiA9IGRvYy5jcmVhdGVFbGVtZW50KFwiYnV0dG9uXCIpO1xuICAgICAgICAgICAgY2FuY2VsQnV0dG9uLnR5cGUgPSBcImJ1dHRvblwiO1xuICAgICAgICAgICAgY2FuY2VsQnV0dG9uLm9uY2xpY2sgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBjbG9zZSh0cnVlKTsgfTtcbiAgICAgICAgICAgIGNhbmNlbEJ1dHRvbi5jbGFzc05hbWUgPSBcInMtYnRuIG1sOFwiO1xuICAgICAgICAgICAgY2FuY2VsQnV0dG9uLmlubmVyVGV4dCA9IFwiQ2FuY2VsXCI7XG5cbiAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQob2tCdXR0b24pO1xuICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChjYW5jZWxCdXR0b24pO1xuXG4gICAgICAgICAgICB1dGlsLmFkZEV2ZW50KGRvYy5ib2R5LCBcImtleXVwXCIsIGNoZWNrRXNjYXBlKTtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS50b3AgPSBcIjUwJVwiO1xuICAgICAgICAgICAgZGlhbG9nLnN0eWxlLmxlZnQgPSBcIjUwJVwiO1xuICAgICAgICAgICAgZGlhbG9nLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICAgICAgICBpZiAodWFTbmlmZmVkLmlzSUVfNW9yNikge1xuICAgICAgICAgICAgICAgIGRpYWxvZy5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgICAgICAgICBkaWFsb2cuc3R5bGUudG9wID0gZG9jLmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgKyAyMDAgKyBcInB4XCI7XG4gICAgICAgICAgICAgICAgZGlhbG9nLnN0eWxlLmxlZnQgPSBcIjUwJVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9jLmJvZHkuYXBwZW5kQ2hpbGQoZGlhbG9nKTtcblxuICAgICAgICAgICAgLy8gVGhpcyBoYXMgdG8gYmUgZG9uZSBBRlRFUiBhZGRpbmcgdGhlIGRpYWxvZyB0byB0aGUgZm9ybSBpZiB5b3VcbiAgICAgICAgICAgIC8vIHdhbnQgaXQgdG8gYmUgY2VudGVyZWQuXG4gICAgICAgICAgICBkaWFsb2cuc3R5bGUubWFyZ2luVG9wID0gLShwb3NpdGlvbi5nZXRIZWlnaHQoZGlhbG9nKSAvIDIpICsgXCJweFwiO1xuICAgICAgICAgICAgZGlhbG9nLnN0eWxlLm1hcmdpbkxlZnQgPSAtKHBvc2l0aW9uLmdldFdpZHRoKGRpYWxvZykgLyAyKSArIFwicHhcIjtcblxuICAgICAgICB9O1xuICAgICAgICAvLyBXaHkgaXMgdGhpcyBpbiBhIHplcm8tbGVuZ3RoIHRpbWVvdXQ/XG4gICAgICAgIC8vIEl0IHNlZW1zIHRvIHdvcmsgYXJvdW5kIGEgYnJvd3NlciBpc3N1ZSB3aGVyZSB0aGUgc2VsZWN0aW9uL2ZvY3VzIGRvZXNuJ3Qgd29yayBvdGhlcndpc2UuXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICBjcmVhdGVEaWFsb2cob2ssIGNhbmNlbCk7XG5cbiAgICAgICAgICAgIHZhciBkZWZUZXh0TGVuID0gZGVmYXVsdElucHV0VGV4dC5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoaW5wdXQuc2VsZWN0aW9uU3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlucHV0LnNlbGVjdGlvblN0YXJ0ID0gMDtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZWxlY3Rpb25FbmQgPSBkZWZUZXh0TGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaW5wdXQuY3JlYXRlVGV4dFJhbmdlKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gaW5wdXQuY3JlYXRlVGV4dFJhbmdlKCk7XG4gICAgICAgICAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgICAgICAgICAgICAgIHJhbmdlLm1vdmVTdGFydChcImNoYXJhY3RlclwiLCAtZGVmVGV4dExlbik7XG4gICAgICAgICAgICAgICAgcmFuZ2UubW92ZUVuZChcImNoYXJhY3RlclwiLCBkZWZUZXh0TGVuKTtcbiAgICAgICAgICAgICAgICByYW5nZS5zZWxlY3QoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgfSwgMCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIFVJTWFuYWdlcihwb3N0Zml4LCBwYW5lbHMsIHVuZG9NYW5hZ2VyLCBwcmV2aWV3TWFuYWdlciwgY29tbWFuZE1hbmFnZXIsIGhlbHBPcHRpb25zLCBnZXRTdHJpbmcpIHtcblxuICAgICAgICB2YXIgaW5wdXRCb3ggPSBwYW5lbHMuaW5wdXQsXG4gICAgICAgICAgICBidXR0b25zID0ge307IC8vIGJ1dHRvbnMudW5kbywgYnV0dG9ucy5saW5rLCBldGMuIFRoZSBhY3R1YWwgRE9NIGVsZW1lbnRzLlxuXG4gICAgICAgIG1ha2VTcHJpdGVkQnV0dG9uUm93KCk7XG5cbiAgICAgICAgdmFyIGtleUV2ZW50ID0gXCJrZXlkb3duXCI7XG4gICAgICAgIGlmICh1YVNuaWZmZWQuaXNPcGVyYSkge1xuICAgICAgICAgICAga2V5RXZlbnQgPSBcImtleXByZXNzXCI7XG4gICAgICAgIH1cblxuICAgICAgICB1dGlsLmFkZEV2ZW50KGlucHV0Qm94LCBrZXlFdmVudCwgZnVuY3Rpb24gKGtleSkge1xuXG4gICAgICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIGJ1dHRvbiBrZXkgYW5kLCBpZiBzbyBleGVjdXRlIHRoZSBjYWxsYmFjay5cbiAgICAgICAgICAgIGlmICgoa2V5LmN0cmxLZXkgfHwga2V5Lm1ldGFLZXkpICYmICFrZXkuYWx0S2V5ICYmICFrZXkuc2hpZnRLZXkpIHtcblxuICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0ga2V5LmNoYXJDb2RlIHx8IGtleS5rZXlDb2RlO1xuICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlU3RyID0gU3RyaW5nLmZyb21DaGFyQ29kZShrZXlDb2RlKS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAgICAgICAgICAgc3dpdGNoIChrZXlDb2RlU3RyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJiXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKGJ1dHRvbnMuYm9sZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImlcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvQ2xpY2soYnV0dG9ucy5pdGFsaWMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJsXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKGJ1dHRvbnMubGluayk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInFcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvQ2xpY2soYnV0dG9ucy5xdW90ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImtcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvQ2xpY2soYnV0dG9ucy5jb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZ1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZG9DbGljayhidXR0b25zLmltYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwib1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZG9DbGljayhidXR0b25zLm9saXN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZG9DbGljayhidXR0b25zLnVsaXN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiaFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZG9DbGljayhidXR0b25zLmhlYWRpbmcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKGJ1dHRvbnMuaHIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ5XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKGJ1dHRvbnMucmVkbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInpcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXkuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKGJ1dHRvbnMucmVkbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKGJ1dHRvbnMudW5kbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIGlmIChrZXkucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHdpbmRvdy5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF1dG8taW5kZW50IG9uIHNoaWZ0LWVudGVyXG4gICAgICAgIHV0aWwuYWRkRXZlbnQoaW5wdXRCb3gsIFwia2V5dXBcIiwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgaWYgKGtleS5zaGlmdEtleSAmJiAha2V5LmN0cmxLZXkgJiYgIWtleS5tZXRhS2V5KSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBrZXkuY2hhckNvZGUgfHwga2V5LmtleUNvZGU7XG4gICAgICAgICAgICAgICAgLy8gQ2hhcmFjdGVyIDEzIGlzIEVudGVyXG4gICAgICAgICAgICAgICAgaWYgKGtleUNvZGUgPT09IDEzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmYWtlQnV0dG9uID0ge307XG4gICAgICAgICAgICAgICAgICAgIGZha2VCdXR0b24udGV4dE9wID0gYmluZENvbW1hbmQoXCJkb0F1dG9pbmRlbnRcIik7XG4gICAgICAgICAgICAgICAgICAgIGRvQ2xpY2soZmFrZUJ1dHRvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBzcGVjaWFsIGhhbmRsZXIgYmVjYXVzZSBJRSBjbGVhcnMgdGhlIGNvbnRleHQgb2YgdGhlIHRleHRib3ggb24gRVNDXG4gICAgICAgIGlmICh1YVNuaWZmZWQuaXNJRSkge1xuICAgICAgICAgICAgdXRpbC5hZGRFdmVudChpbnB1dEJveCwgXCJrZXlkb3duXCIsIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICB2YXIgY29kZSA9IGtleS5rZXlDb2RlO1xuICAgICAgICAgICAgICAgIGlmIChjb2RlID09PSAyNykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcGx1Z2dhYmxlQnV0dG9ucyA9IHtsaW5rOiB0cnVlLCBpbWFnZTogdHJ1ZX07XG5cbiAgICAgICAgLy8gUGVyZm9ybSB0aGUgYnV0dG9uJ3MgYWN0aW9uLlxuICAgICAgICBmdW5jdGlvbiBkb0NsaWNrKGJ1dHRvbiwgbm9JbnRlcmNlcHQpIHtcblxuICAgICAgICAgICAgaW5wdXRCb3guZm9jdXMoKTtcblxuICAgICAgICAgICAgaWYgKGJ1dHRvbi5pZCAmJiAhbm9JbnRlcmNlcHQpIHtcbiAgICAgICAgICAgICAgICB2YXIga2luZCA9IGJ1dHRvbi5pZC5yZXBsYWNlKC9ed21kLShcXHcrKS0uKiQvLCBcIiQxXCIpO1xuICAgICAgICAgICAgICAgIGlmIChwbHVnZ2FibGVCdXR0b25zW2tpbmRdKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb21tYW5kTWFuYWdlci5ob29rcy5pbnRlcmNlcHRCdXR0b25DbGljayhidXR0b24sIGtpbmQsIGZ1bmN0aW9uICgpIHsgZG9DbGljayhidXR0b24sIHRydWUpOyB9KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGlmIChidXR0b24udGV4dE9wKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodW5kb01hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdW5kb01hbmFnZXIuc2V0Q29tbWFuZE1vZGUoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBuZXcgVGV4dGFyZWFTdGF0ZShwYW5lbHMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFzdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGNodW5rcyA9IHN0YXRlLmdldENodW5rcygpO1xuXG4gICAgICAgICAgICAgICAgLy8gU29tZSBjb21tYW5kcyBsYXVuY2ggYSBcIm1vZGFsXCIgcHJvbXB0IGRpYWxvZy4gIEphdmFzY3JpcHRcbiAgICAgICAgICAgICAgICAvLyBjYW4ndCByZWFsbHkgbWFrZSBhIG1vZGFsIGRpYWxvZyBib3ggYW5kIHRoZSBXTUQgY29kZVxuICAgICAgICAgICAgICAgIC8vIHdpbGwgY29udGludWUgdG8gZXhlY3V0ZSB3aGlsZSB0aGUgZGlhbG9nIGlzIGRpc3BsYXllZC5cbiAgICAgICAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIHRoZSBkaWFsb2cgcGF0dGVybiBJJ20gdXNlZCB0byBhbmQgbWVhbnNcbiAgICAgICAgICAgICAgICAvLyBJIGNhbid0IGRvIHNvbWV0aGluZyBsaWtlIHRoaXM6XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyB2YXIgbGluayA9IENyZWF0ZUxpbmtEaWFsb2coKTtcbiAgICAgICAgICAgICAgICAvLyBtYWtlTWFya2Rvd25MaW5rKGxpbmspO1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gSW5zdGVhZCBvZiB0aGlzIHN0cmFpZ2h0Zm9yd2FyZCBtZXRob2Qgb2YgaGFuZGxpbmcgYVxuICAgICAgICAgICAgICAgIC8vIGRpYWxvZyBJIGhhdmUgdG8gcGFzcyBhbnkgY29kZSB3aGljaCB3b3VsZCBleGVjdXRlXG4gICAgICAgICAgICAgICAgLy8gYWZ0ZXIgdGhlIGRpYWxvZyBpcyBkaXNtaXNzZWQgKGUuZy4gbGluayBjcmVhdGlvbilcbiAgICAgICAgICAgICAgICAvLyBpbiBhIGZ1bmN0aW9uIHBhcmFtZXRlci5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIFllcyB0aGlzIGlzIGF3a3dhcmQgYW5kIEkgdGhpbmsgaXQgc3Vja3MsIGJ1dCB0aGVyZSdzXG4gICAgICAgICAgICAgICAgLy8gbm8gcmVhbCB3b3JrYXJvdW5kLiAgT25seSB0aGUgaW1hZ2UgYW5kIGxpbmsgY29kZVxuICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBkaWFsb2dzIGFuZCByZXF1aXJlIHRoZSBmdW5jdGlvbiBwb2ludGVycy5cbiAgICAgICAgICAgICAgICB2YXIgZml4dXBJbnB1dEFyZWEgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaW5wdXRCb3guZm9jdXMoKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY2h1bmtzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZS5zZXRDaHVua3MoY2h1bmtzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnJlc3RvcmUoKTtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlld01hbmFnZXIucmVmcmVzaCgpO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICB2YXIgbm9DbGVhbnVwID0gYnV0dG9uLnRleHRPcChjaHVua3MsIGZpeHVwSW5wdXRBcmVhKTtcblxuICAgICAgICAgICAgICAgIGlmICghbm9DbGVhbnVwKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpeHVwSW5wdXRBcmVhKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChidXR0b24uZXhlY3V0ZSkge1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5leGVjdXRlKHVuZG9NYW5hZ2VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBmdW5jdGlvbiBzZXR1cEJ1dHRvbihidXR0b24sIGlzRW5hYmxlZCkge1xuXG4gICAgICAgICAgICB2YXIgbm9ybWFsWVNoaWZ0ID0gXCIwcHhcIjtcbiAgICAgICAgICAgIHZhciBkaXNhYmxlZFlTaGlmdCA9IFwiLTIwcHhcIjtcbiAgICAgICAgICAgIHZhciBoaWdobGlnaHRZU2hpZnQgPSBcIi00MHB4XCI7XG4gICAgICAgICAgICB2YXIgaW1hZ2UgPSBidXR0b24uZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzcGFuXCIpWzBdO1xuICAgICAgICAgICAgaWYgKGlzRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIGltYWdlLnN0eWxlLmJhY2tncm91bmRQb3NpdGlvbiA9IGJ1dHRvbi5YU2hpZnQgKyBcIiBcIiArIG5vcm1hbFlTaGlmdDtcbiAgICAgICAgICAgICAgICBidXR0b24ub25tb3VzZW92ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGltYWdlLnN0eWxlLmJhY2tncm91bmRQb3NpdGlvbiA9IHRoaXMuWFNoaWZ0ICsgXCIgXCIgKyBoaWdobGlnaHRZU2hpZnQ7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGJ1dHRvbi5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpbWFnZS5zdHlsZS5iYWNrZ3JvdW5kUG9zaXRpb24gPSB0aGlzLlhTaGlmdCArIFwiIFwiICsgbm9ybWFsWVNoaWZ0O1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAvLyBJRSB0cmllcyB0byBzZWxlY3QgdGhlIGJhY2tncm91bmQgaW1hZ2UgXCJidXR0b25cIiB0ZXh0IChpdCdzXG4gICAgICAgICAgICAgICAgLy8gaW1wbGVtZW50ZWQgaW4gYSBsaXN0IGl0ZW0pIHNvIHdlIGhhdmUgdG8gY2FjaGUgdGhlIHNlbGVjdGlvblxuICAgICAgICAgICAgICAgIC8vIG9uIG1vdXNlZG93bi5cbiAgICAgICAgICAgICAgICBpZiAodWFTbmlmZmVkLmlzSUUpIHtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvYy5hY3RpdmVFbGVtZW50ICYmIGRvYy5hY3RpdmVFbGVtZW50ICE9PSBwYW5lbHMuaW5wdXQpIHsgLy8gd2UncmUgbm90IGV2ZW4gaW4gdGhlIGlucHV0IGJveCwgc28gdGhlcmUncyBubyBzZWxlY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBwYW5lbHMuaWVDYWNoZWRSYW5nZSA9IGRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFuZWxzLmllQ2FjaGVkU2Nyb2xsVG9wID0gcGFuZWxzLmlucHV0LnNjcm9sbFRvcDtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIWJ1dHRvbi5pc0hlbHApIHtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uLm9uY2xpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vbm1vdXNlb3V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbm1vdXNlb3V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkb0NsaWNrKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaW1hZ2Uuc3R5bGUuYmFja2dyb3VuZFBvc2l0aW9uID0gYnV0dG9uLlhTaGlmdCArIFwiIFwiICsgZGlzYWJsZWRZU2hpZnQ7XG4gICAgICAgICAgICAgICAgYnV0dG9uLm9ubW91c2VvdmVyID0gYnV0dG9uLm9ubW91c2VvdXQgPSBidXR0b24ub25jbGljayA9IGZ1bmN0aW9uICgpIHsgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGJpbmRDb21tYW5kKG1ldGhvZCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXRob2QgPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgbWV0aG9kID0gY29tbWFuZE1hbmFnZXJbbWV0aG9kXTtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IG1ldGhvZC5hcHBseShjb21tYW5kTWFuYWdlciwgYXJndW1lbnRzKTsgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gbWFrZVNwcml0ZWRCdXR0b25Sb3coKSB7XG5cbiAgICAgICAgICAgIHZhciBidXR0b25CYXIgPSBwYW5lbHMuYnV0dG9uQmFyO1xuXG4gICAgICAgICAgICB2YXIgbm9ybWFsWVNoaWZ0ID0gXCIwcHhcIjtcbiAgICAgICAgICAgIHZhciBkaXNhYmxlZFlTaGlmdCA9IFwiLTIwcHhcIjtcbiAgICAgICAgICAgIHZhciBoaWdobGlnaHRZU2hpZnQgPSBcIi00MHB4XCI7XG5cbiAgICAgICAgICAgIHZhciBidXR0b25Sb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidWxcIik7XG4gICAgICAgICAgICBidXR0b25Sb3cuaWQgPSBcIndtZC1idXR0b24tcm93XCIgKyBwb3N0Zml4O1xuICAgICAgICAgICAgYnV0dG9uUm93LmNsYXNzTmFtZSA9ICd3bWQtYnV0dG9uLXJvdyc7XG4gICAgICAgICAgICBidXR0b25Sb3cgPSBidXR0b25CYXIuYXBwZW5kQ2hpbGQoYnV0dG9uUm93KTtcbiAgICAgICAgICAgIHZhciBtYWtlQnV0dG9uID0gZnVuY3Rpb24gKGlkLCB0aXRsZSwgWFNoaWZ0LCB0ZXh0T3ApIHtcbiAgICAgICAgICAgICAgICB2YXIgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpXCIpO1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5jbGFzc05hbWUgPSBcIndtZC1idXR0b25cIjtcbiAgICAgICAgICAgICAgICB2YXIgYnV0dG9uSW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgICAgICAgICBidXR0b24uaWQgPSBpZCArIHBvc3RmaXg7XG4gICAgICAgICAgICAgICAgYnV0dG9uLmFwcGVuZENoaWxkKGJ1dHRvbkltYWdlKTtcbiAgICAgICAgICAgICAgICBidXR0b24udGl0bGUgPSB0aXRsZTtcbiAgICAgICAgICAgICAgICBidXR0b24uWFNoaWZ0ID0gWFNoaWZ0O1xuICAgICAgICAgICAgICAgIGlmICh0ZXh0T3ApXG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbi50ZXh0T3AgPSB0ZXh0T3A7XG4gICAgICAgICAgICAgICAgc2V0dXBCdXR0b24oYnV0dG9uLCB0cnVlKTtcbiAgICAgICAgICAgICAgICBidXR0b25Sb3cuYXBwZW5kQ2hpbGQoYnV0dG9uKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnV0dG9uO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhciBtYWtlU3BhY2VyID0gZnVuY3Rpb24gKG51bSkge1xuICAgICAgICAgICAgICAgIHZhciBzcGFjZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibGlcIik7XG4gICAgICAgICAgICAgICAgc3BhY2VyLmNsYXNzTmFtZSA9IFwid21kLXNwYWNlciB3bWQtc3BhY2VyXCIgKyBudW07XG4gICAgICAgICAgICAgICAgc3BhY2VyLmlkID0gXCJ3bWQtc3BhY2VyXCIgKyBudW0gKyBwb3N0Zml4O1xuICAgICAgICAgICAgICAgIGJ1dHRvblJvdy5hcHBlbmRDaGlsZChzcGFjZXIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBidXR0b25zLmJvbGQgPSBtYWtlQnV0dG9uKFwid21kLWJvbGQtYnV0dG9uXCIsIGdldFN0cmluZyhcImJvbGRcIiksIFwiMHB4XCIsIGJpbmRDb21tYW5kKFwiZG9Cb2xkXCIpKTtcbiAgICAgICAgICAgIGJ1dHRvbnMuaXRhbGljID0gbWFrZUJ1dHRvbihcIndtZC1pdGFsaWMtYnV0dG9uXCIsIGdldFN0cmluZyhcIml0YWxpY1wiKSwgXCItMjBweFwiLCBiaW5kQ29tbWFuZChcImRvSXRhbGljXCIpKTtcbiAgICAgICAgICAgIG1ha2VTcGFjZXIoMSk7XG4gICAgICAgICAgICBidXR0b25zLmxpbmsgPSBtYWtlQnV0dG9uKFwid21kLWxpbmstYnV0dG9uXCIsIGdldFN0cmluZyhcImxpbmtcIiksIFwiLTQwcHhcIiwgYmluZENvbW1hbmQoZnVuY3Rpb24gKGNodW5rLCBwb3N0UHJvY2Vzc2luZykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvTGlua09ySW1hZ2UoY2h1bmssIHBvc3RQcm9jZXNzaW5nLCBmYWxzZSk7XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBidXR0b25zLnF1b3RlID0gbWFrZUJ1dHRvbihcIndtZC1xdW90ZS1idXR0b25cIiwgZ2V0U3RyaW5nKFwicXVvdGVcIiksIFwiLTYwcHhcIiwgYmluZENvbW1hbmQoXCJkb0Jsb2NrcXVvdGVcIikpO1xuICAgICAgICAgICAgYnV0dG9ucy5jb2RlID0gbWFrZUJ1dHRvbihcIndtZC1jb2RlLWJ1dHRvblwiLCBnZXRTdHJpbmcoXCJjb2RlXCIpLCBcIi04MHB4XCIsIGJpbmRDb21tYW5kKFwiZG9Db2RlXCIpKTtcbiAgICAgICAgICAgIGJ1dHRvbnMuaW1hZ2UgPSBtYWtlQnV0dG9uKFwid21kLWltYWdlLWJ1dHRvblwiLCBnZXRTdHJpbmcoXCJpbWFnZVwiKSwgXCItMTAwcHhcIiwgYmluZENvbW1hbmQoZnVuY3Rpb24gKGNodW5rLCBwb3N0UHJvY2Vzc2luZykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvTGlua09ySW1hZ2UoY2h1bmssIHBvc3RQcm9jZXNzaW5nLCB0cnVlKTtcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIG1ha2VTcGFjZXIoMik7XG4gICAgICAgICAgICBidXR0b25zLm9saXN0ID0gbWFrZUJ1dHRvbihcIndtZC1vbGlzdC1idXR0b25cIiwgZ2V0U3RyaW5nKFwib2xpc3RcIiksIFwiLTEyMHB4XCIsIGJpbmRDb21tYW5kKGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvTGlzdChjaHVuaywgcG9zdFByb2Nlc3NpbmcsIHRydWUpO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgYnV0dG9ucy51bGlzdCA9IG1ha2VCdXR0b24oXCJ3bWQtdWxpc3QtYnV0dG9uXCIsIGdldFN0cmluZyhcInVsaXN0XCIpLCBcIi0xNDBweFwiLCBiaW5kQ29tbWFuZChmdW5jdGlvbiAoY2h1bmssIHBvc3RQcm9jZXNzaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kb0xpc3QoY2h1bmssIHBvc3RQcm9jZXNzaW5nLCBmYWxzZSk7XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBidXR0b25zLmhlYWRpbmcgPSBtYWtlQnV0dG9uKFwid21kLWhlYWRpbmctYnV0dG9uXCIsIGdldFN0cmluZyhcImhlYWRpbmdcIiksIFwiLTE2MHB4XCIsIGJpbmRDb21tYW5kKFwiZG9IZWFkaW5nXCIpKTtcbiAgICAgICAgICAgIGJ1dHRvbnMuaHIgPSBtYWtlQnV0dG9uKFwid21kLWhyLWJ1dHRvblwiLCBnZXRTdHJpbmcoXCJoclwiKSwgXCItMTgwcHhcIiwgYmluZENvbW1hbmQoXCJkb0hvcml6b250YWxSdWxlXCIpKTtcbiAgICAgICAgICAgIG1ha2VTcGFjZXIoMyk7XG4gICAgICAgICAgICBidXR0b25zLnVuZG8gPSBtYWtlQnV0dG9uKFwid21kLXVuZG8tYnV0dG9uXCIsIGdldFN0cmluZyhcInVuZG9cIiksIFwiLTIwMHB4XCIsIG51bGwpO1xuICAgICAgICAgICAgYnV0dG9ucy51bmRvLmV4ZWN1dGUgPSBmdW5jdGlvbiAobWFuYWdlcikgeyBpZiAobWFuYWdlcikgbWFuYWdlci51bmRvKCk7IH07XG5cbiAgICAgICAgICAgIHZhciByZWRvVGl0bGUgPSAvd2luLy50ZXN0KG5hdi5wbGF0Zm9ybS50b0xvd2VyQ2FzZSgpKSA/XG4gICAgICAgICAgICAgICAgZ2V0U3RyaW5nKFwicmVkb1wiKSA6XG4gICAgICAgICAgICAgICAgZ2V0U3RyaW5nKFwicmVkb21hY1wiKTsgLy8gbWFjIGFuZCBvdGhlciBub24tV2luZG93cyBwbGF0Zm9ybXNcblxuICAgICAgICAgICAgYnV0dG9ucy5yZWRvID0gbWFrZUJ1dHRvbihcIndtZC1yZWRvLWJ1dHRvblwiLCByZWRvVGl0bGUsIFwiLTIyMHB4XCIsIG51bGwpO1xuICAgICAgICAgICAgYnV0dG9ucy5yZWRvLmV4ZWN1dGUgPSBmdW5jdGlvbiAobWFuYWdlcikgeyBpZiAobWFuYWdlcikgbWFuYWdlci5yZWRvKCk7IH07XG5cbiAgICAgICAgICAgIC8vIHRoaXMgaXMgaW5zZXJ0ZWQgc28gdGhhdCB0aGUgaGVscCBidXR0b24gaXMgcmlnaHQtYWxpZ25lZCAqYW5kKiB0aGUgbGF5b3V0IGlzIGlkZW50aWNhbFxuICAgICAgICAgICAgLy8gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBoZWxwIGJ1dHRvbiBleGlzdHMgb3Igbm90XG4gICAgICAgICAgICB2YXIgbWF4U3BhY2VyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpXCIpO1xuICAgICAgICAgICAgbWF4U3BhY2VyLmNsYXNzTmFtZSA9IFwid21kLXNwYWNlciB3bWQtc3BhY2VyLW1heFwiO1xuICAgICAgICAgICAgYnV0dG9uUm93LmFwcGVuZENoaWxkKG1heFNwYWNlcik7XG5cbiAgICAgICAgICAgIGlmIChoZWxwT3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHZhciBvbkFza1BhZ2VWMiA9ICQoJ2JvZHknKS5oYXNDbGFzcygnanMtYXNrLXBhZ2UtdjInKTtcblxuICAgICAgICAgICAgICAgIHZhciBoZWxwQnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpXCIpO1xuICAgICAgICAgICAgICAgIHZhciBoZWxwQnV0dG9uSW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgICAgICAgICBoZWxwQnV0dG9uLmFwcGVuZENoaWxkKGhlbHBCdXR0b25JbWFnZSk7XG4gICAgICAgICAgICAgICAgaWYgKG9uQXNrUGFnZVYyKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlbHBCdXR0b24uY2xhc3NOYW1lID0gJ3MtYnRuIHMtYnRuX19tdXRlZCBzLWJ0bl9fc20gYXMtY2VudGVyJztcbiAgICAgICAgICAgICAgICAgICAgaGVscEJ1dHRvbi5pbm5lclRleHQgPSBfcygnU2hvdyBmb3JtYXR0aW5nIHRpcHMnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBoZWxwQnV0dG9uLmNsYXNzTmFtZSA9IFwid21kLWJ1dHRvbiB3bWQtaGVscC1idXR0b25cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaGVscEJ1dHRvbi5pZCA9IFwid21kLWhlbHAtYnV0dG9uXCIgKyBwb3N0Zml4O1xuICAgICAgICAgICAgICAgIGhlbHBCdXR0b24uWFNoaWZ0ID0gXCItMjQwcHhcIjtcbiAgICAgICAgICAgICAgICBoZWxwQnV0dG9uLmlzSGVscCA9IHRydWU7XG4gICAgICAgICAgICAgICAgaGVscEJ1dHRvbi5zdHlsZS5yaWdodCA9IFwiMHB4XCI7XG4gICAgICAgICAgICAgICAgaGVscEJ1dHRvbi50aXRsZSA9IGdldFN0cmluZyhcImhlbHBcIik7XG4gICAgICAgICAgICAgICAgaGVscEJ1dHRvbi5vbmNsaWNrID0gaGVscE9wdGlvbnMuaGFuZGxlcjtcblxuICAgICAgICAgICAgICAgIGlmICghb25Bc2tQYWdlVjIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBCdXR0b24oaGVscEJ1dHRvbiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJ1dHRvblJvdy5hcHBlbmRDaGlsZChoZWxwQnV0dG9uKTtcbiAgICAgICAgICAgICAgICBidXR0b25zLmhlbHAgPSBoZWxwQnV0dG9uO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXRVbmRvUmVkb0J1dHRvblN0YXRlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gc2V0VW5kb1JlZG9CdXR0b25TdGF0ZXMoKSB7XG4gICAgICAgICAgICBpZiAodW5kb01hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICBzZXR1cEJ1dHRvbihidXR0b25zLnVuZG8sIHVuZG9NYW5hZ2VyLmNhblVuZG8oKSk7XG4gICAgICAgICAgICAgICAgc2V0dXBCdXR0b24oYnV0dG9ucy5yZWRvLCB1bmRvTWFuYWdlci5jYW5SZWRvKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc2V0VW5kb1JlZG9CdXR0b25TdGF0ZXMgPSBzZXRVbmRvUmVkb0J1dHRvblN0YXRlcztcblxuICAgIH1cblxuICAgIGZ1bmN0aW9uIENvbW1hbmRNYW5hZ2VyKHBsdWdpbkhvb2tzLCBnZXRTdHJpbmcsIGNvbnZlcnRlciwgd3JhcEltYWdlSW5MaW5rLCBjb252ZXJ0SW1hZ2VzVG9MaW5rcykge1xuICAgICAgICB0aGlzLmhvb2tzID0gcGx1Z2luSG9va3M7XG4gICAgICAgIHRoaXMuZ2V0U3RyaW5nID0gZ2V0U3RyaW5nO1xuICAgICAgICB0aGlzLmNvbnZlcnRlciA9IGNvbnZlcnRlcjtcbiAgICAgICAgdGhpcy53cmFwSW1hZ2VJbkxpbmsgPSB3cmFwSW1hZ2VJbkxpbms7XG4gICAgICAgIHRoaXMuY29udmVydEltYWdlc1RvTGlua3MgPSBjb252ZXJ0SW1hZ2VzVG9MaW5rcztcbiAgICB9XG5cbiAgICB2YXIgY29tbWFuZFByb3RvID0gQ29tbWFuZE1hbmFnZXIucHJvdG90eXBlO1xuXG4gICAgLy8gVGhlIG1hcmtkb3duIHN5bWJvbHMgLSA0IHNwYWNlcyA9IGNvZGUsID4gPSBibG9ja3F1b3RlLCBldGMuXG4gICAgY29tbWFuZFByb3RvLnByZWZpeGVzID0gXCIoPzpcXFxcc3s0LH18XFxcXHMqPnxcXFxccyotXFxcXHMrfFxcXFxzKlxcXFxkK1xcXFwufD18XFxcXCt8LXxffFxcXFwqfCN8XFxcXHMqXFxcXFtbXlxcbl1dK1xcXFxdOilcIjtcblxuICAgIC8vIFJlbW92ZSBtYXJrZG93biBzeW1ib2xzIGZyb20gdGhlIGNodW5rIHNlbGVjdGlvbi5cbiAgICBjb21tYW5kUHJvdG8udW53cmFwID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgIHZhciB0eHQgPSBuZXcgcmUoXCIoW15cXFxcbl0pXFxcXG4oPyEoXFxcXG58XCIgKyB0aGlzLnByZWZpeGVzICsgXCIpKVwiLCBcImdcIik7XG4gICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IGNodW5rLnNlbGVjdGlvbi5yZXBsYWNlKHR4dCwgXCIkMSAkMlwiKTtcbiAgICB9O1xuXG4gICAgY29tbWFuZFByb3RvLndyYXAgPSBmdW5jdGlvbiAoY2h1bmssIGxlbikge1xuICAgICAgICB0aGlzLnVud3JhcChjaHVuayk7XG4gICAgICAgIHZhciByZWdleCA9IG5ldyByZShcIiguezEsXCIgKyBsZW4gKyBcIn0pKCArfCRcXFxcbj8pXCIsIFwiZ21cIiksXG4gICAgICAgICAgICB0aGF0ID0gdGhpcztcblxuICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZShyZWdleCwgZnVuY3Rpb24gKGxpbmUsIG1hcmtlZCkge1xuICAgICAgICAgICAgaWYgKG5ldyByZShcIl5cIiArIHRoYXQucHJlZml4ZXMsIFwiXCIpLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGluZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtYXJrZWQgKyBcIlxcblwiO1xuICAgICAgICB9KTtcblxuICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvXFxzKyQvLCBcIlwiKTtcbiAgICB9O1xuXG4gICAgY29tbWFuZFByb3RvLmRvQm9sZCA9IGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9Cb3JJKGNodW5rLCBwb3N0UHJvY2Vzc2luZywgMiwgdGhpcy5nZXRTdHJpbmcoXCJib2xkZXhhbXBsZVwiKSk7XG4gICAgfTtcblxuICAgIGNvbW1hbmRQcm90by5kb0l0YWxpYyA9IGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9Cb3JJKGNodW5rLCBwb3N0UHJvY2Vzc2luZywgMSwgdGhpcy5nZXRTdHJpbmcoXCJpdGFsaWNleGFtcGxlXCIpKTtcbiAgICB9O1xuXG4gICAgLy8gY2h1bms6IFRoZSBzZWxlY3RlZCByZWdpb24gdGhhdCB3aWxsIGJlIGVuY2xvc2VkIHdpdGggKi8qKlxuICAgIC8vIG5TdGFyczogMSBmb3IgaXRhbGljcywgMiBmb3IgYm9sZFxuICAgIC8vIGluc2VydFRleHQ6IElmIHlvdSBqdXN0IGNsaWNrIHRoZSBidXR0b24gd2l0aG91dCBoaWdobGlnaHRpbmcgdGV4dCwgdGhpcyBnZXRzIGluc2VydGVkXG4gICAgY29tbWFuZFByb3RvLmRvQm9ySSA9IGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcsIG5TdGFycywgaW5zZXJ0VGV4dCkge1xuXG4gICAgICAgIC8vIEdldCByaWQgb2Ygd2hpdGVzcGFjZSBhbmQgZml4dXAgbmV3bGluZXMuXG4gICAgICAgIGNodW5rLnRyaW1XaGl0ZXNwYWNlKCk7XG4gICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IGNodW5rLnNlbGVjdGlvbi5yZXBsYWNlKC9cXG57Mix9L2csIFwiXFxuXCIpO1xuXG4gICAgICAgIC8vIExvb2sgZm9yIHN0YXJzIGJlZm9yZSBhbmQgYWZ0ZXIuICBJcyB0aGUgY2h1bmsgYWxyZWFkeSBtYXJrZWQgdXA/XG4gICAgICAgIC8vIG5vdGUgdGhhdCB0aGVzZSByZWdleCBtYXRjaGVzIGNhbm5vdCBmYWlsXG4gICAgICAgIHZhciBzdGFyc0JlZm9yZSA9IC8oXFwqKiQpLy5leGVjKGNodW5rLmJlZm9yZSlbMF07XG4gICAgICAgIHZhciBzdGFyc0FmdGVyID0gLyheXFwqKikvLmV4ZWMoY2h1bmsuYWZ0ZXIpWzBdO1xuXG4gICAgICAgIHZhciBwcmV2U3RhcnMgPSBNYXRoLm1pbihzdGFyc0JlZm9yZS5sZW5ndGgsIHN0YXJzQWZ0ZXIubGVuZ3RoKTtcblxuICAgICAgICAvLyBSZW1vdmUgc3RhcnMgaWYgd2UgaGF2ZSB0byBzaW5jZSB0aGUgYnV0dG9uIGFjdHMgYXMgYSB0b2dnbGUuXG4gICAgICAgIGlmICgocHJldlN0YXJzID49IG5TdGFycykgJiYgKHByZXZTdGFycyAhPSAyIHx8IG5TdGFycyAhPSAxKSkge1xuICAgICAgICAgICAgY2h1bmsuYmVmb3JlID0gY2h1bmsuYmVmb3JlLnJlcGxhY2UocmUoXCJbKl17XCIgKyBuU3RhcnMgKyBcIn0kXCIsIFwiXCIpLCBcIlwiKTtcbiAgICAgICAgICAgIGNodW5rLmFmdGVyID0gY2h1bmsuYWZ0ZXIucmVwbGFjZShyZShcIl5bKl17XCIgKyBuU3RhcnMgKyBcIn1cIiwgXCJcIiksIFwiXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFjaHVuay5zZWxlY3Rpb24gJiYgc3RhcnNBZnRlcikge1xuICAgICAgICAgICAgLy8gSXQncyBub3QgcmVhbGx5IGNsZWFyIHdoeSB0aGlzIGNvZGUgaXMgbmVjZXNzYXJ5LiAgSXQganVzdCBtb3Zlc1xuICAgICAgICAgICAgLy8gc29tZSBhcmJpdHJhcnkgc3R1ZmYgYXJvdW5kLlxuICAgICAgICAgICAgY2h1bmsuYWZ0ZXIgPSBjaHVuay5hZnRlci5yZXBsYWNlKC9eKFsqX10qKS8sIFwiXCIpO1xuICAgICAgICAgICAgY2h1bmsuYmVmb3JlID0gY2h1bmsuYmVmb3JlLnJlcGxhY2UoLyhcXHM/KSQvLCBcIlwiKTtcbiAgICAgICAgICAgIHZhciB3aGl0ZXNwYWNlID0gcmUuJDE7XG4gICAgICAgICAgICBjaHVuay5iZWZvcmUgPSBjaHVuay5iZWZvcmUgKyBzdGFyc0FmdGVyICsgd2hpdGVzcGFjZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcblxuICAgICAgICAgICAgLy8gSW4gbW9zdCBjYXNlcywgaWYgeW91IGRvbid0IGhhdmUgYW55IHNlbGVjdGVkIHRleHQgYW5kIGNsaWNrIHRoZSBidXR0b25cbiAgICAgICAgICAgIC8vIHlvdSdsbCBnZXQgYSBzZWxlY3RlZCwgbWFya2VkIHVwIHJlZ2lvbiB3aXRoIHRoZSBkZWZhdWx0IHRleHQgaW5zZXJ0ZWQuXG4gICAgICAgICAgICBpZiAoIWNodW5rLnNlbGVjdGlvbiAmJiAhc3RhcnNBZnRlcikge1xuICAgICAgICAgICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IGluc2VydFRleHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCB0aGUgdHJ1ZSBtYXJrdXAuXG4gICAgICAgICAgICB2YXIgbWFya3VwID0gblN0YXJzIDw9IDEgPyBcIipcIiA6IFwiKipcIjsgLy8gc2hvdWxkbid0IHRoZSB0ZXN0IGJlID0gP1xuICAgICAgICAgICAgY2h1bmsuYmVmb3JlID0gY2h1bmsuYmVmb3JlICsgbWFya3VwO1xuICAgICAgICAgICAgY2h1bmsuYWZ0ZXIgPSBtYXJrdXAgKyBjaHVuay5hZnRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICB9O1xuXG4gICAgY29tbWFuZFByb3RvLnN0cmlwTGlua0RlZnMgPSBmdW5jdGlvbiAodGV4dCwgZGVmc1RvQWRkKSB7XG5cbiAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXlsgXXswLDN9XFxbKFxcZCspXFxdOlsgXFx0XSpcXG4/WyBcXHRdKjw/KFxcUys/KT4/WyBcXHRdKlxcbj9bIFxcdF0qKD86KFxcbiopW1wiKF0oLis/KVtcIildWyBcXHRdKik/KD86XFxuK3wkKS9nbSxcbiAgICAgICAgICAgIGZ1bmN0aW9uICh0b3RhbE1hdGNoLCBpZCwgbGluaywgbmV3bGluZXMsIHRpdGxlKSB7XG4gICAgICAgICAgICAgICAgZGVmc1RvQWRkW2lkXSA9IHRvdGFsTWF0Y2gucmVwbGFjZSgvXFxzKiQvLCBcIlwiKTtcbiAgICAgICAgICAgICAgICBpZiAobmV3bGluZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RyaXAgdGhlIHRpdGxlIGFuZCByZXR1cm4gdGhhdCBzZXBhcmF0ZWx5LlxuICAgICAgICAgICAgICAgICAgICBkZWZzVG9BZGRbaWRdID0gdG90YWxNYXRjaC5yZXBsYWNlKC9bXCIoXSguKz8pW1wiKV0kLywgXCJcIik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXdsaW5lcyArIHRpdGxlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH07XG5cbiAgICBjb21tYW5kUHJvdG8uYWRkTGlua0RlZiA9IGZ1bmN0aW9uIChjaHVuaywgbGlua0RlZikge1xuXG4gICAgICAgIHZhciByZWZOdW1iZXIgPSAwOyAvLyBUaGUgY3VycmVudCByZWZlcmVuY2UgbnVtYmVyXG4gICAgICAgIHZhciBkZWZzVG9BZGQgPSB7fTsgLy9cbiAgICAgICAgLy8gU3RhcnQgd2l0aCBhIGNsZWFuIHNsYXRlIGJ5IHJlbW92aW5nIGFsbCBwcmV2aW91cyBsaW5rIGRlZmluaXRpb25zLlxuICAgICAgICBjaHVuay5iZWZvcmUgPSB0aGlzLnN0cmlwTGlua0RlZnMoY2h1bmsuYmVmb3JlLCBkZWZzVG9BZGQpO1xuICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSB0aGlzLnN0cmlwTGlua0RlZnMoY2h1bmsuc2VsZWN0aW9uLCBkZWZzVG9BZGQpO1xuICAgICAgICBjaHVuay5hZnRlciA9IHRoaXMuc3RyaXBMaW5rRGVmcyhjaHVuay5hZnRlciwgZGVmc1RvQWRkKTtcblxuICAgICAgICB2YXIgZGVmcyA9IFwiXCI7XG4gICAgICAgIHZhciByZWdleCA9IC9cXFsoXFxkKylcXF0vZztcblxuICAgICAgICAvLyBUaGUgYWJvdmUgcmVnZXgsIHVzZWQgdG8gdXBkYXRlIFtmb29dWzEzXSByZWZlcmVuY2VzIGFmdGVyIHJlbnVtYmVyaW5nLFxuICAgICAgICAvLyBpcyBtdWNoIHRvbyBsaWJlcmFsOyBpdCBjYW4gY2F0Y2ggdGhpbmdzIHRoYXQgYXJlIG5vdCBhY3R1YWxseSBwYXJzZWRcbiAgICAgICAgLy8gYXMgcmVmZXJlbmNlcyAobm90YWJseTogY29kZSkuIEl0J3MgaW1wb3NzaWJsZSB0byBrbm93IHdoaWNoIG1hdGNoZXMgYXJlXG4gICAgICAgIC8vIHJlYWwgcmVmZXJlbmNlcyB3aXRob3V0IHBlcmZvcm1pbmcgYSBtYXJrZG93biBjb252ZXJzaW9uLCBzbyB0aGF0J3Mgd2hhdFxuICAgICAgICAvLyB3ZSBkby4gQWxsIG1hdGNoZXMgYXJlIHJlcGxhY2VkIHdpdGggYSB1bmlxdWUgcmVmZXJlbmNlIG51bWJlciwgd2hpY2ggaXNcbiAgICAgICAgLy8gZ2l2ZW4gYSB1bmlxdWUgbGluay4gVGhlIHVuaXF1aWZpZXIgaW4gYm90aCBjYXNlcyBpcyB0aGUgY2hhcmFjdGVyIG9mZnNldFxuICAgICAgICAvLyBvZiB0aGUgbWF0Y2ggaW5zaWRlIHRoZSBzb3VyY2Ugc3RyaW5nLiBUaGUgbW9kaWZpZWQgdmVyc2lvbiBpcyB0aGVuIHNlbnRcbiAgICAgICAgLy8gdGhyb3VnaCB0aGUgTWFya2Rvd24gcmVuZGVyZXIuIEJlY2F1c2UgbGluayByZWZlcmVuY2UgYXJlIHN0cmlwcGVkIGR1cmluZ1xuICAgICAgICAvLyByZW5kZXJpbmcsIHRoZSB1bmlxdWUgbGluayBpcyBwcmVzZW50IGluIHRoZSByZW5kZXJlZCB2ZXJzaW9uIGlmIGFuZCBvbmx5XG4gICAgICAgIC8vIGlmIHRoZSBtYXRjaCBhdCBpdHMgb2Zmc2V0IHdhcyBpbiBmYWN0IHJlbmRlcmVkIGFzIGEgbGluayBvciBpbWFnZS5cbiAgICAgICAgdmFyIGNvbXBsZXRlID0gY2h1bmsuYmVmb3JlICsgY2h1bmsuc2VsZWN0aW9uICsgY2h1bmsuYWZ0ZXI7XG4gICAgICAgIHZhciByZW5kZXJlZCA9IHRoaXMuY29udmVydGVyLm1ha2VIdG1sKGNvbXBsZXRlKTtcbiAgICAgICAgdmFyIHRlc3RsaW5rID0gXCJodHRwczovL3RoaXMtaXMtYS1yZWFsLWxpbmsuYml6L1wiO1xuXG4gICAgICAgIC8vIElmIG91ciBmYWtlIGxpbmsgYXBwZWFycyBpbiB0aGUgcmVuZGVyZWQgdmVyc2lvbiAqYmVmb3JlKiB3ZSBoYXZlIGFkZGVkIGl0LFxuICAgICAgICAvLyB0aGlzIHByb2JhYmx5IG1lYW5zIHlvdSdyZSBhIE1ldGEgU3RhY2sgRXhjaGFuZ2UgdXNlciB3aG8gaXMgZGVsaWJlcmF0ZWx5XG4gICAgICAgIC8vIHRyeWluZyB0byBicmVhayB0aGlzIGZlYXR1cmUuIFlvdSBjYW4gc3RpbGwgYnJlYWsgdGhpcyB3b3JrYXJvdW5kIGlmIHlvdVxuICAgICAgICAvLyBhdHRhY2ggYSBwbHVnaW4gdG8gdGhlIGNvbnZlcnRlciB0aGF0IHNvbWV0aW1lcyAoISkgaW5zZXJ0cyB0aGlzIGxpbmsuIEluXG4gICAgICAgIC8vIHRoYXQgY2FzZSwgY29uc2lkZXIgeW91cnNlbGYgdW5zdXBwb3J0ZWQuXG4gICAgICAgIHdoaWxlIChyZW5kZXJlZC5pbmRleE9mKHRlc3RsaW5rKSAhPSAtMSlcbiAgICAgICAgICAgIHRlc3RsaW5rICs9IFwibmljZXRyeS9cIjtcblxuICAgICAgICB2YXIgZmFrZWRlZnMgPSBcIlxcblxcblwiO1xuXG4gICAgICAgIHZhciB1bmlxdWlmaWVkID0gY29tcGxldGUucmVwbGFjZShyZWdleCwgZnVuY3Rpb24gdW5pcXVpZnkod2hvbGVNYXRjaCwgaWQsIG9mZnNldCkge1xuICAgICAgICAgICAgZmFrZWRlZnMgKz0gXCIgW1wiICsgb2Zmc2V0ICsgXCJdOiBcIiArIHRlc3RsaW5rICsgb2Zmc2V0ICsgXCIvdW5pY29yblxcblwiO1xuICAgICAgICAgICAgcmV0dXJuIFwiW1wiICsgb2Zmc2V0ICsgXCJdXCI7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlbmRlcmVkID0gdGhpcy5jb252ZXJ0ZXIubWFrZUh0bWwodW5pcXVpZmllZCArIGZha2VkZWZzKTtcblxuICAgICAgICB2YXIgb2theVRvTW9kaWZ5ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVuZGVyZWQuaW5kZXhPZih0ZXN0bGluayArIG9mZnNldCArIFwiL3VuaWNvcm5cIikgIT09IC0xO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcHJvcGVydHkgbmFtZXMgYXJlIFwiTF9cIiArIGxpbmsgKHByZWZpeGVkIHRvIHByZXZlbnQgY29sbGlzaW9ucyB3aXRoIGJ1aWx0LWluIHByb3BlcnRpZXMpLFxuICAgICAgICAvLyB2YWx1ZXMgYXJlIHRoZSBkZWZpbml0aW9uIG51bWJlcnNcbiAgICAgICAgdmFyIGFkZGVkRGVmc0J5VXJsID0ge307XG4gICAgICAgIHZhciBhZGRPclJldXNlRGVmTnVtYmVyID0gZnVuY3Rpb24gKGRlZikge1xuICAgICAgICAgICAgdmFyIHN0cmlwcGVkID0gZGVmLnJlcGxhY2UoL15bIF17MCwzfVxcWyhcXGQrKVxcXTovLCBcIlwiKTtcbiAgICAgICAgICAgIHZhciBrZXkgPSBcIkxfXCIgKyBzdHJpcHBlZDtcbiAgICAgICAgICAgIGlmIChrZXkgaW4gYWRkZWREZWZzQnlVcmwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZGVkRGVmc0J5VXJsW2tleV07XG4gICAgICAgICAgICByZWZOdW1iZXIrKztcbiAgICAgICAgICAgIGRlZiA9IFwiICBbXCIgKyByZWZOdW1iZXIgKyBcIl06XCIgKyBzdHJpcHBlZDtcbiAgICAgICAgICAgIGRlZnMgKz0gXCJcXG5cIiArIGRlZjtcbiAgICAgICAgICAgIGFkZGVkRGVmc0J5VXJsW2tleV0gPSByZWZOdW1iZXI7XG4gICAgICAgICAgICByZXR1cm4gcmVmTnVtYmVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIHRoZSByZWdleCBpcyB0ZXN0ZWQgb24gdGhlICh1cCB0bykgdGhyZWUgY2h1bmtzIHNlcGFyYXRlbHksXG4gICAgICAgIC8vIHNvIGluIG9yZGVyIHRvIGhhdmUgdGhlIGNvcnJlY3Qgb2Zmc2V0cyB0byBjaGVjayBhZ2FpbnN0IG9rYXlUb01vZGlmeSgpLCB3ZVxuICAgICAgICAvLyBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgaG93IG1hbnkgY2hhcmFjdGVycyBhcmUgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSBiZWZvcmVcbiAgICAgICAgLy8gdGhlIHN1YnN0cmluZyB0aGF0IHdlJ3JlIGxvb2tpbmcgYXQuIE5vdGUgdGhhdCBkb0xpbmtPckltYWdlIGFsaWducyB0aGUgc2VsZWN0aW9uXG4gICAgICAgIC8vIG9uIHBvdGVudGlhbCBicmFja2V0cywgc28gdGhlcmUgc2hvdWxkIGJlIG5vIG1ham9yIGJyZWFrYWdlIGZyb20gdGhlIGNodW5rXG4gICAgICAgIC8vIHNlcGFyYXRpb24uXG4gICAgICAgIHZhciBza2lwcGVkQ2hhcnMgPSAwO1xuXG4gICAgICAgIC8vIG5vdGUgdGhhdFxuICAgICAgICAvLyBhKSB0aGUgcmVjdXJzaXZlIGNhbGwgdG8gZ2V0TGluayBjYW5ub3QgZ28gaW5maW5pdGUsIGJlY2F1c2UgYnkgZGVmaW5pdGlvblxuICAgICAgICAvLyAgICBvZiByZWdleCwgaW5uZXIgaXMgYWx3YXlzIGEgcHJvcGVyIHN1YnN0cmluZyBvZiB3aG9sZU1hdGNoLCBhbmRcbiAgICAgICAgLy8gYikgbW9yZSB0aGFuIG9uZSBsZXZlbCBvZiBuZXN0aW5nIGlzIG5laXRoZXIgc3VwcG9ydGVkIGJ5IHRoZSByZWdleFxuICAgICAgICAvLyAgICBub3IgbWFraW5nIGEgbG90IG9mIHNlbnNlICh0aGUgb25seSB1c2UgY2FzZSBmb3IgbmVzdGluZyBpcyBhIGxpbmtlZCBpbWFnZSlcbiAgICAgICAgdmFyIGdldExpbmsgPSBmdW5jdGlvbiAod2hvbGVNYXRjaCwgaWQsIG9mZnNldCkge1xuICAgICAgICAgICAgaWYgKCFva2F5VG9Nb2RpZnkoc2tpcHBlZENoYXJzICsgb2Zmc2V0KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gd2hvbGVNYXRjaDtcbiAgICAgICAgICAgIGlmIChkZWZzVG9BZGRbaWRdKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlZm51bSA9IGFkZE9yUmV1c2VEZWZOdW1iZXIoZGVmc1RvQWRkW2lkXSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiW1wiICsgcmVmbnVtICsgXCJdXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gd2hvbGVNYXRjaDtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgbGVuID0gY2h1bmsuYmVmb3JlLmxlbmd0aDtcbiAgICAgICAgY2h1bmsuYmVmb3JlID0gY2h1bmsuYmVmb3JlLnJlcGxhY2UocmVnZXgsIGdldExpbmspO1xuICAgICAgICBza2lwcGVkQ2hhcnMgKz0gbGVuO1xuXG4gICAgICAgIGxlbiA9IGNodW5rLnNlbGVjdGlvbi5sZW5ndGg7XG4gICAgICAgIHZhciByZWZPdXQ7XG4gICAgICAgIGlmIChsaW5rRGVmKSB7XG4gICAgICAgICAgICByZWZPdXQgPSBhZGRPclJldXNlRGVmTnVtYmVyKGxpbmtEZWYpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gY2h1bmsuc2VsZWN0aW9uLnJlcGxhY2UocmVnZXgsIGdldExpbmspO1xuICAgICAgICB9XG4gICAgICAgIHNraXBwZWRDaGFycyArPSBsZW47XG5cbiAgICAgICAgY2h1bmsuYWZ0ZXIgPSBjaHVuay5hZnRlci5yZXBsYWNlKHJlZ2V4LCBnZXRMaW5rKTtcblxuICAgICAgICBpZiAoY2h1bmsuYWZ0ZXIpIHtcbiAgICAgICAgICAgIGNodW5rLmFmdGVyID0gY2h1bmsuYWZ0ZXIucmVwbGFjZSgvXFxuKiQvLCBcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNodW5rLmFmdGVyKSB7XG4gICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvXFxuKiQvLCBcIlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNodW5rLmFmdGVyICs9IFwiXFxuXFxuXCIgKyBkZWZzO1xuXG4gICAgICAgIHJldHVybiByZWZPdXQ7XG4gICAgfTtcblxuICAgIC8vIHRha2VzIHRoZSBsaW5lIGFzIGVudGVyZWQgaW50byB0aGUgYWRkIGxpbmsvYXMgaW1hZ2UgZGlhbG9nIGFuZCBtYWtlc1xuICAgIC8vIHN1cmUgdGhlIFVSTCBhbmQgdGhlIG9wdGluYWwgdGl0bGUgYXJlIFwibmljZVwiLlxuICAgIGZ1bmN0aW9uIHByb3Blcmx5RW5jb2RlZChsaW5rZGVmKSB7XG4gICAgICAgIHJldHVybiBsaW5rZGVmLnJlcGxhY2UoL15cXHMqKC4qPykoPzpcXHMrXCIoLispXCIpP1xccyokLywgZnVuY3Rpb24gKHdob2xlbWF0Y2gsIGxpbmssIHRpdGxlKSB7XG5cbiAgICAgICAgICAgIHZhciBpblF1ZXJ5U3RyaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgIC8vIEhhdmluZyBgW15cXHdcXGQtLi9dYCBpbiB0aGVyZSBpcyBqdXN0IGEgc2hvcnRjdXQgdGhhdCBsZXRzIHVzIHNraXBcbiAgICAgICAgICAgIC8vIHRoZSBtb3N0IGNvbW1vbiBjaGFyYWN0ZXJzIGluIFVSTHMuIFJlcGxhY2luZyB0aGF0IGl0IHdpdGggYC5gIHdvdWxkIG5vdCBjaGFuZ2VcbiAgICAgICAgICAgIC8vIHRoZSByZXN1bHQsIGJlY2F1c2UgZW5jb2RlVVJJIHJldHVybnMgdGhvc2UgY2hhcmFjdGVycyB1bmNoYW5nZWQsIGJ1dCBpdFxuICAgICAgICAgICAgLy8gd291bGQgbWVhbiBsb3RzIG9mIHVubmVjZXNzYXJ5IHJlcGxhY2VtZW50IGNhbGxzLiBIYXZpbmcgYFtgIGFuZCBgXWAgaW4gdGhhdFxuICAgICAgICAgICAgLy8gc2VjdGlvbiBhcyB3ZWxsIG1lYW5zIHdlIGRvICpub3QqIGVub2NkZSBzcXVhcmUgYnJhY2tldHMuIFRoZXNlIGNoYXJhY3RlcnMgYXJlXG4gICAgICAgICAgICAvLyBhIHN0cmFuZ2UgYmVhc3QgaW4gVVJMcywgYnV0IGlmIGFueXRoaW5nLCB0aGlzIGNhdXNlcyBVUkxzIHRvIGJlIG1vcmUgcmVhZGFibGUsXG4gICAgICAgICAgICAvLyBhbmQgd2UgbGVhdmUgaXQgdG8gdGhlIGJyb3dzZXIgdG8gbWFrZSBzdXJlIHRoYXQgdGhlc2UgbGlua3MgYXJlIGhhbmRsZWQgd2l0aG91dFxuICAgICAgICAgICAgLy8gcHJvYmxlbXMuXG4gICAgICAgICAgICBsaW5rID0gbGluay5yZXBsYWNlKC8lKD86W1xcZGEtZkEtRl17Mn0pfFxcP3xcXCt8W15cXHdcXGQtLi9bXFxdXS9nLCBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAvLyBWYWxpZCBwZXJjZW50IGVuY29kaW5nLiBDb3VsZCBqdXN0IHJldHVybiBpdCBhcyBpcywgYnV0IHdlIGZvbGxvdyBSRkMzOTg2XG4gICAgICAgICAgICAgICAgLy8gU2VjdGlvbiAyLjEgd2hpY2ggc2F5cyBcIkZvciBjb25zaXN0ZW5jeSwgVVJJIHByb2R1Y2VycyBhbmQgbm9ybWFsaXplcnNcbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgdXNlIHVwcGVyY2FzZSBoZXhhZGVjaW1hbCBkaWdpdHMgZm9yIGFsbCBwZXJjZW50LWVuY29kaW5ncy5cIlxuICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB3ZSBhbHNvIGhhbmRsZSAoaWxsZWdhbCkgc3RhbmQtYWxvbmUgcGVyY2VudCBjaGFyYWN0ZXJzIGJ5XG4gICAgICAgICAgICAgICAgLy8gcmVwbGFjaW5nIHRoZW0gd2l0aCBcIiUyNVwiXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoLmxlbmd0aCA9PT0gMyAmJiBtYXRjaC5jaGFyQXQoMCkgPT0gXCIlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXRjaCAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIj9cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGluUXVlcnlTdHJpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiP1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gdGhlIHF1ZXJ5IHN0cmluZywgYSBwbHVzIGFuZCBhIHNwYWNlIGFyZSBpZGVudGljYWwgLS0gbm9ybWFsaXplLlxuICAgICAgICAgICAgICAgICAgICAvLyBOb3Qgc3RyaWN0bHkgbmVjZXNzYXJ5LCBidXQgaWRlbnRpY2FsIGJlaGF2aW9yIHRvIHRoZSBwcmV2aW91cyB2ZXJzaW9uXG4gICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoaXMgZnVuY3Rpb24uXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCIrXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5RdWVyeVN0cmluZylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCIlMjBcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZW5jb2RlVVJJKG1hdGNoKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGlmICh0aXRsZSkge1xuICAgICAgICAgICAgICAgIHRpdGxlID0gdGl0bGUudHJpbSA/IHRpdGxlLnRyaW0oKSA6IHRpdGxlLnJlcGxhY2UoL15cXHMqLywgXCJcIikucmVwbGFjZSgvXFxzKiQvLCBcIlwiKTtcbiAgICAgICAgICAgICAgICB0aXRsZSA9IHRpdGxlLnJlcGxhY2UoL1wiL2csIFwicXVvdDtcIikucmVwbGFjZSgvXFwoL2csIFwiJiM0MDtcIikucmVwbGFjZSgvXFwpL2csIFwiJiM0MTtcIikucmVwbGFjZSgvPC9nLCBcIiZsdDtcIikucmVwbGFjZSgvPi9nLCBcIiZndDtcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGl0bGUgPyBsaW5rICsgJyBcIicgKyB0aXRsZSArICdcIicgOiBsaW5rO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjb21tYW5kUHJvdG8uZG9MaW5rT3JJbWFnZSA9IGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcsIGlzSW1hZ2UpIHtcblxuICAgICAgICAvLyBlbnN1cmUgdGhlIG1hcmtkb3duIHJlbmRlcmVyIGlzIGxvYWRlZCBzbyB0aGF0IGl0J3MgcmVhZHlcbiAgICAgICAgLy8gb25jZSB0aGUgdXNlciBpbnNlcnRzIGEgbGluay9pbWFnZS4gSWRlYWxseSB3ZSdkIGF3YWl0IHRoaXMgY2FsbFxuICAgICAgICAvLyBidXQgY2FuJ3QgZm9yIGNvbXBhdGliaWxpdHkgcmVhc29ucy5cbiAgICAgICAgdGhpcy5jb252ZXJ0ZXIubG9hZE1hcmtkb3duUmVuZGVyZXJBc3luYygpO1xuXG4gICAgICAgIGNodW5rLnRyaW1XaGl0ZXNwYWNlKCk7XG4gICAgICAgIGNodW5rLmZpbmRUYWdzKC9cXHMqIT9cXFsvLCAvXFxdWyBdPyg/OlxcblsgXSopPyhcXFsuKj9cXF0pPy8pO1xuICAgICAgICB2YXIgYmFja2dyb3VuZDtcbiAgICAgICAgdmFyIHdyYXBJbWFnZUluTGluayA9IHRoaXMud3JhcEltYWdlSW5MaW5rO1xuICAgICAgICB2YXIgY29udmVydEltYWdlc1RvTGlua3MgPSB0aGlzLmNvbnZlcnRJbWFnZXNUb0xpbmtzO1xuXG4gICAgICAgIGlmIChjaHVuay5lbmRUYWcubGVuZ3RoID4gMSAmJiBjaHVuay5zdGFydFRhZy5sZW5ndGggPiAwKSB7XG5cbiAgICAgICAgICAgIGNodW5rLnN0YXJ0VGFnID0gY2h1bmsuc3RhcnRUYWcucmVwbGFjZSgvIT9cXFsvLCBcIlwiKTtcbiAgICAgICAgICAgIGNodW5rLmVuZFRhZyA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLmFkZExpbmtEZWYoY2h1bmssIG51bGwpO1xuXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG5cbiAgICAgICAgICAgIC8vIFdlJ3JlIG1vdmluZyBzdGFydCBhbmQgZW5kIHRhZyBiYWNrIGludG8gdGhlIHNlbGVjdGlvbiwgc2luY2UgKGFzIHdlJ3JlIGluIHRoZSBlbHNlIGJsb2NrKSB3ZSdyZSBub3RcbiAgICAgICAgICAgIC8vICpyZW1vdmluZyogYSBsaW5rLCBidXQgKmFkZGluZyogb25lLCBzbyB3aGF0ZXZlciBmaW5kVGFncygpIGZvdW5kIGlzIG5vdyBiYWNrIHRvIGJlaW5nIHBhcnQgb2YgdGhlXG4gICAgICAgICAgICAvLyBsaW5rIHRleHQuIGxpbmtFbnRlcmVkQ2FsbGJhY2sgdGFrZXMgY2FyZSBvZiBlc2NhcGluZyBhbnkgYnJhY2tldHMuXG4gICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zdGFydFRhZyArIGNodW5rLnNlbGVjdGlvbiArIGNodW5rLmVuZFRhZztcbiAgICAgICAgICAgIGNodW5rLnN0YXJ0VGFnID0gY2h1bmsuZW5kVGFnID0gXCJcIjtcblxuICAgICAgICAgICAgaWYgKC9cXG5cXG4vLnRlc3QoY2h1bmsuc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkTGlua0RlZihjaHVuaywgbnVsbCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgICAgICAgLy8gVGhlIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIHdoZW4geW91IGVudGVyIGEgbGluayBhbmQgcHJlc3MgT0sgb3IgQ2FuY2VsLlxuICAgICAgICAgICAgLy8gTWFya3MgdXAgdGhlIGxpbmsgYW5kIGFkZHMgdGhlIHJlZi5cbiAgICAgICAgICAgIHZhciBsaW5rRW50ZXJlZENhbGxiYWNrID0gZnVuY3Rpb24gKGxpbmspIHtcblxuICAgICAgICAgICAgICAgIGlmIChiYWNrZ3JvdW5kICYmIGJhY2tncm91bmQucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoYmFja2dyb3VuZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGxpbmsgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gKCAgICAgICAgICAgICAgICAgICAgICAgICAgJDFcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIFteXFxcXF0gICAgICAgICAgICAgICAgICBhbnl0aGluZyB0aGF0J3Mgbm90IGEgYmFja3NsYXNoXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAoPzpcXFxcXFxcXCkqICAgICAgICAgICAgICBhbiBldmVuIG51bWJlciAodGhpcyBpbmNsdWRlcyB6ZXJvKSBvZiBiYWNrc2xhc2hlc1xuICAgICAgICAgICAgICAgICAgICAvLyApXG4gICAgICAgICAgICAgICAgICAgIC8vICg/PSAgICAgICAgICAgICAgICAgICAgICAgIGZvbGxvd2VkIGJ5XG4gICAgICAgICAgICAgICAgICAgIC8vICAgICBbW1xcXV0gICAgICAgICAgICAgICAgICBhbiBvcGVuaW5nIG9yIGNsb3NpbmcgYnJhY2tldFxuICAgICAgICAgICAgICAgICAgICAvLyApXG4gICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgIC8vIEluIG90aGVyIHdvcmRzLCBhIG5vbi1lc2NhcGVkIGJyYWNrZXQuIFRoZXNlIGhhdmUgdG8gYmUgZXNjYXBlZCBub3cgdG8gbWFrZSBzdXJlIHRoZXlcbiAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgY291bnQgYXMgdGhlIGVuZCBvZiB0aGUgbGluayBvciBzaW1pbGFyLlxuICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHRoYXQgdGhlIGFjdHVhbCBicmFja2V0IGhhcyB0byBiZSBhIGxvb2thaGVhZCwgYmVjYXVzZSAoaW4gY2FzZSBvZiB0byBzdWJzZXF1ZW50IGJyYWNrZXRzKSxcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGJyYWNrZXQgaW4gb25lIG1hdGNoIG1heSBiZSB0aGUgXCJub3QgYSBiYWNrc2xhc2hcIiBjaGFyYWN0ZXIgaW4gdGhlIG5leHQgbWF0Y2gsIHNvIGl0XG4gICAgICAgICAgICAgICAgICAgIC8vIHNob3VsZCBub3QgYmUgY29uc3VtZWQgYnkgdGhlIGZpcnN0IG1hdGNoLlxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgXCJwcmVwZW5kIGEgc3BhY2UgYW5kIGZpbmFsbHkgcmVtb3ZlIGl0XCIgc3RlcHMgbWFrZXMgc3VyZSB0aGVyZSBpcyBhIFwibm90IGEgYmFja3NsYXNoXCIgYXQgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0IG9mIHRoZSBzdHJpbmcsIHNvIHRoaXMgYWxzbyB3b3JrcyBpZiB0aGUgc2VsZWN0aW9uIGJlZ2lucyB3aXRoIGEgYnJhY2tldC4gV2UgY2Fubm90IHNvbHZlXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgYnkgYW5jaG9yaW5nIHdpdGggXiwgYmVjYXVzZSBpbiB0aGUgY2FzZSB0aGF0IHRoZSBzZWxlY3Rpb24gc3RhcnRzIHdpdGggdHdvIGJyYWNrZXRzLCB0aGlzXG4gICAgICAgICAgICAgICAgICAgIC8vIHdvdWxkIG1lYW4gYSB6ZXJvLXdpZHRoIG1hdGNoIGF0IHRoZSBzdGFydC4gU2luY2UgemVyby13aWR0aCBtYXRjaGVzIGFkdmFuY2UgdGhlIHN0cmluZyBwb3NpdGlvbixcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGJyYWNrZXQgY291bGQgdGhlbiBub3QgYWN0IGFzIHRoZSBcIm5vdCBhIGJhY2tzbGFzaFwiIGZvciB0aGUgc2Vjb25kLlxuICAgICAgICAgICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSAoXCIgXCIgKyBjaHVuay5zZWxlY3Rpb24pLnJlcGxhY2UoLyhbXlxcXFxdKD86XFxcXFxcXFwpKikoPz1bW1xcXV0pL2csIFwiJDFcXFxcXCIpLnN1YnN0cigxKTtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgbGlua0RlZiA9IFwiIFs5OTldOiBcIiArIHByb3Blcmx5RW5jb2RlZChsaW5rKTtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgbnVtID0gdGhhdC5hZGRMaW5rRGVmKGNodW5rLCBsaW5rRGVmKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0ltYWdlIHx8ICh3cmFwSW1hZ2VJbkxpbmsgJiYgIWNvbnZlcnRJbWFnZXNUb0xpbmtzKSlcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmsuc3RhcnRUYWcgPSBcIltcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLmVuZFRhZyA9IFwiXVtcIiArIG51bSArIFwiXVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0ltYWdlKVxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbnZlcnRJbWFnZXNUb0xpbmtzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmsuc3RhcnRUYWcgKz0gXCIhW1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVuay5zdGFydFRhZyArPSBcIltcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLmVuZFRhZyA9IFwiXVtcIiArIG51bSArIFwiXVwiICsgY2h1bmsuZW5kVGFnO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaHVuay5zZWxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0ltYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gdGhhdC5nZXRTdHJpbmcoXCJpbWFnZWRlc2NyaXB0aW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gdGhhdC5nZXRTdHJpbmcoXCJsaW5rZGVzY3JpcHRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbWFnZSAmJiBjb252ZXJ0SW1hZ2VzVG9MaW5rcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5ob29rcy5pbWFnZUNvbnZlcnRlZFRvTGluaygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBvc3RQcm9jZXNzaW5nKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuaG9va3Muc2tpcE1vZGFsQmFja2dyb3VuZChpc0ltYWdlID8gXCJpbWFnZVwiIDogXCJsaW5rXCIpKSB7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHVpLmNyZWF0ZUJhY2tncm91bmQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzSW1hZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaG9va3MuaW5zZXJ0SW1hZ2VEaWFsb2cobGlua0VudGVyZWRDYWxsYmFjaykpXG4gICAgICAgICAgICAgICAgICAgIHVpLnByb21wdCh0aGlzLmdldFN0cmluZyhcImltYWdlZGlhbG9nXCIpLCBpbWFnZURlZmF1bHRUZXh0LCB0aGlzLmdldFN0cmluZyhcIm9rXCIpLCB0aGlzLmdldFN0cmluZyhcImNhbmNlbFwiKSwgbGlua0VudGVyZWRDYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaG9va3MuaW5zZXJ0TGlua0RpYWxvZyhsaW5rRW50ZXJlZENhbGxiYWNrKSlcbiAgICAgICAgICAgICAgICAgICAgdWkucHJvbXB0KHRoaXMuZ2V0U3RyaW5nKFwibGlua2RpYWxvZ1wiKSwgbGlua0RlZmF1bHRUZXh0LCB0aGlzLmdldFN0cmluZyhcIm9rXCIpLCB0aGlzLmdldFN0cmluZyhcImNhbmNlbFwiKSwgbGlua0VudGVyZWRDYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBXaGVuIG1ha2luZyBhIGxpc3QsIGhpdHRpbmcgc2hpZnQtZW50ZXIgd2lsbCBwdXQgeW91ciBjdXJzb3Igb24gdGhlIG5leHQgbGluZVxuICAgIC8vIGF0IHRoZSBjdXJyZW50IGluZGVudCBsZXZlbC5cbiAgICBjb21tYW5kUHJvdG8uZG9BdXRvaW5kZW50ID0gZnVuY3Rpb24gKGNodW5rLCBwb3N0UHJvY2Vzc2luZykge1xuXG4gICAgICAgIHZhciBjb21tYW5kTWdyID0gdGhpcyxcbiAgICAgICAgICAgIGZha2VTZWxlY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICBjaHVuay5iZWZvcmUgPSBjaHVuay5iZWZvcmUucmVwbGFjZSgvKFxcbnxeKVsgXXswLDN9KFsqKy1dfFxcZCtbLl0pWyBcXHRdKlxcbiQvLCBcIlxcblxcblwiKTtcbiAgICAgICAgY2h1bmsuYmVmb3JlID0gY2h1bmsuYmVmb3JlLnJlcGxhY2UoLyhcXG58XilbIF17MCwzfT5bIFxcdF0qXFxuJC8sIFwiXFxuXFxuXCIpO1xuICAgICAgICBjaHVuay5iZWZvcmUgPSBjaHVuay5iZWZvcmUucmVwbGFjZSgvKFxcbnxeKVsgXFx0XStcXG4kLywgXCJcXG5cXG5cIik7XG5cbiAgICAgICAgLy8gVGhlcmUncyBubyBzZWxlY3Rpb24sIGVuZCB0aGUgY3Vyc29yIHdhc24ndCBhdCB0aGUgZW5kIG9mIHRoZSBsaW5lOlxuICAgICAgICAvLyBUaGUgdXNlciB3YW50cyB0byBzcGxpdCB0aGUgY3VycmVudCBsaXN0IGl0ZW0gLyBjb2RlIGxpbmUgLyBibG9ja3F1b3RlIGxpbmVcbiAgICAgICAgLy8gKGZvciB0aGUgbGF0dGVyIGl0IGRvZXNuJ3QgcmVhbGx5IG1hdHRlcikgaW4gdHdvLiBUZW1wb3JhcmlseSBzZWxlY3QgdGhlXG4gICAgICAgIC8vIChyZXN0IG9mIHRoZSkgbGluZSB0byBhY2hpZXZlIHRoaXMuXG4gICAgICAgIGlmICghY2h1bmsuc2VsZWN0aW9uICYmICEvXlsgXFx0XSooPzpcXG58JCkvLnRlc3QoY2h1bmsuYWZ0ZXIpKSB7XG4gICAgICAgICAgICBjaHVuay5hZnRlciA9IGNodW5rLmFmdGVyLnJlcGxhY2UoL15bXlxcbl0qLywgZnVuY3Rpb24gKHdob2xlTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSB3aG9sZU1hdGNoO1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmYWtlU2VsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgvKFxcbnxeKVsgXXswLDN9KFsqKy1dfFxcZCtbLl0pWyBcXHRdKy4qXFxuJC8udGVzdChjaHVuay5iZWZvcmUpKSB7XG4gICAgICAgICAgICBpZiAoY29tbWFuZE1nci5kb0xpc3QpIHtcbiAgICAgICAgICAgICAgICBjb21tYW5kTWdyLmRvTGlzdChjaHVuayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKC8oXFxufF4pWyBdezAsM30+WyBcXHRdKy4qXFxuJC8udGVzdChjaHVuay5iZWZvcmUpKSB7XG4gICAgICAgICAgICBpZiAoY29tbWFuZE1nci5kb0Jsb2NrcXVvdGUpIHtcbiAgICAgICAgICAgICAgICBjb21tYW5kTWdyLmRvQmxvY2txdW90ZShjaHVuayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKC8oXFxufF4pKFxcdHxbIF17NCx9KS4qXFxuJC8udGVzdChjaHVuay5iZWZvcmUpKSB7XG4gICAgICAgICAgICBpZiAoY29tbWFuZE1nci5kb0NvZGUpIHtcbiAgICAgICAgICAgICAgICBjb21tYW5kTWdyLmRvQ29kZShjaHVuayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmFrZVNlbGVjdGlvbikge1xuICAgICAgICAgICAgY2h1bmsuYWZ0ZXIgPSBjaHVuay5zZWxlY3Rpb24gKyBjaHVuay5hZnRlcjtcbiAgICAgICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IFwiXCI7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29tbWFuZFByb3RvLmRvQmxvY2txdW90ZSA9IGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcpIHtcblxuICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvXihcXG4qKShbXlxccl0rPykoXFxuKikkLyxcbiAgICAgICAgICAgIGZ1bmN0aW9uICh0b3RhbE1hdGNoLCBuZXdsaW5lc0JlZm9yZSwgdGV4dCwgbmV3bGluZXNBZnRlcikge1xuICAgICAgICAgICAgICAgIGNodW5rLmJlZm9yZSArPSBuZXdsaW5lc0JlZm9yZTtcbiAgICAgICAgICAgICAgICBjaHVuay5hZnRlciA9IG5ld2xpbmVzQWZ0ZXIgKyBjaHVuay5hZnRlcjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNodW5rLmJlZm9yZSA9IGNodW5rLmJlZm9yZS5yZXBsYWNlKC8oPlsgXFx0XSopJC8sXG4gICAgICAgICAgICBmdW5jdGlvbiAodG90YWxNYXRjaCwgYmxhbmtMaW5lKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gYmxhbmtMaW5lICsgY2h1bmsuc2VsZWN0aW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gY2h1bmsuc2VsZWN0aW9uLnJlcGxhY2UoL14oXFxzfD4pKyQvLCBcIlwiKTtcbiAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gY2h1bmsuc2VsZWN0aW9uIHx8IHRoaXMuZ2V0U3RyaW5nKFwicXVvdGVleGFtcGxlXCIpO1xuXG4gICAgICAgIC8vIFRoZSBvcmlnaW5hbCBjb2RlIHVzZXMgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZmluZCBvdXQgaG93IG11Y2ggb2YgdGhlXG4gICAgICAgIC8vIHRleHQgKmRpcmVjdGx5IGJlZm9yZSogdGhlIHNlbGVjdGlvbiBhbHJlYWR5IHdhcyBhIGJsb2NrcXVvdGU6XG5cbiAgICAgICAgLypcbiAgICAgICAgaWYgKGNodW5rLmJlZm9yZSkge1xuICAgICAgICBjaHVuay5iZWZvcmUgPSBjaHVuay5iZWZvcmUucmVwbGFjZSgvXFxuPyQvLCBcIlxcblwiKTtcbiAgICAgICAgfVxuICAgICAgICBjaHVuay5iZWZvcmUgPSBjaHVuay5iZWZvcmUucmVwbGFjZSgvKCgoXFxufF4pKFxcblsgXFx0XSopKj4oLitcXG4pKi4qKSsoXFxuWyBcXHRdKikqJCkvLFxuICAgICAgICBmdW5jdGlvbiAodG90YWxNYXRjaCkge1xuICAgICAgICBjaHVuay5zdGFydFRhZyA9IHRvdGFsTWF0Y2g7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9KTtcbiAgICAgICAgKi9cblxuICAgICAgICAvLyBUaGlzIGNvbWVzIGRvd24gdG86XG4gICAgICAgIC8vIEdvIGJhY2t3YXJkcyBhcyBtYW55IGxpbmVzIGEgcG9zc2libGUsIHN1Y2ggdGhhdCBlYWNoIGxpbmVcbiAgICAgICAgLy8gIGEpIHN0YXJ0cyB3aXRoIFwiPlwiLCBvclxuICAgICAgICAvLyAgYikgaXMgYWxtb3N0IGVtcHR5LCBleGNlcHQgZm9yIHdoaXRlc3BhY2UsIG9yXG4gICAgICAgIC8vICBjKSBpcyBwcmVjZWVkZWQgYnkgYW4gdW5icm9rZW4gY2hhaW4gb2Ygbm9uLWVtcHR5IGxpbmVzXG4gICAgICAgIC8vICAgICBsZWFkaW5nIHVwIHRvIGEgbGluZSB0aGF0IHN0YXJ0cyB3aXRoIFwiPlwiIGFuZCBhdCBsZWFzdCBvbmUgbW9yZSBjaGFyYWN0ZXJcbiAgICAgICAgLy8gYW5kIGluIGFkZGl0aW9uXG4gICAgICAgIC8vICBkKSBhdCBsZWFzdCBvbmUgbGluZSBmdWxmaWxscyBhKVxuICAgICAgICAvL1xuICAgICAgICAvLyBTaW5jZSB0aGlzIGlzIGVzc2VudGlhbGx5IGEgYmFja3dhcmRzLW1vdmluZyByZWdleCwgaXQncyBzdXNjZXB0aWJsZSB0b1xuICAgICAgICAvLyBjYXRzdHJvcGhpYyBiYWNrdHJhY2tpbmcgYW5kIGNhbiBjYXVzZSB0aGUgYnJvd3NlciB0byBoYW5nO1xuICAgICAgICAvLyBzZWUgZS5nLiBodHRwczovL21ldGEuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzk4MDcuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEhlbmNlIHdlIHJlcGxhY2VkIHRoaXMgYnkgYSBzaW1wbGUgc3RhdGUgbWFjaGluZSB0aGF0IGp1c3QgZ29lcyB0aHJvdWdoIHRoZVxuICAgICAgICAvLyBsaW5lcyBhbmQgY2hlY2tzIGZvciBhKSwgYiksIGFuZCBjKS5cblxuICAgICAgICB2YXIgbWF0Y2ggPSBcIlwiLFxuICAgICAgICAgICAgbGVmdE92ZXIgPSBcIlwiLFxuICAgICAgICAgICAgbGluZTtcbiAgICAgICAgaWYgKGNodW5rLmJlZm9yZSkge1xuICAgICAgICAgICAgdmFyIGxpbmVzID0gY2h1bmsuYmVmb3JlLnJlcGxhY2UoL1xcbiQvLCBcIlwiKS5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgICAgIHZhciBpbkNoYWluID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGdvb2QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBsaW5lID0gbGluZXNbaV07XG4gICAgICAgICAgICAgICAgaW5DaGFpbiA9IGluQ2hhaW4gJiYgbGluZS5sZW5ndGggPiAwOyAvLyBjKSBhbnkgbm9uLWVtcHR5IGxpbmUgY29udGludWVzIHRoZSBjaGFpblxuICAgICAgICAgICAgICAgIGlmICgvXj4vLnRlc3QobGluZSkpIHsgICAgICAgICAgICAgICAgLy8gYSlcbiAgICAgICAgICAgICAgICAgICAgZ29vZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaW5DaGFpbiAmJiBsaW5lLmxlbmd0aCA+IDEpICAvLyBjKSBhbnkgbGluZSB0aGF0IHN0YXJ0cyB3aXRoIFwiPlwiIGFuZCBoYXMgYXQgbGVhc3Qgb25lIG1vcmUgY2hhcmFjdGVyIHN0YXJ0cyB0aGUgY2hhaW5cbiAgICAgICAgICAgICAgICAgICAgICAgIGluQ2hhaW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL15bIFxcdF0qJC8udGVzdChsaW5lKSkgeyAgIC8vIGIpXG4gICAgICAgICAgICAgICAgICAgIGdvb2QgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGdvb2QgPSBpbkNoYWluOyAgICAgICAgICAgICAgICAgICAvLyBjKSB0aGUgbGluZSBpcyBub3QgZW1wdHkgYW5kIGRvZXMgbm90IHN0YXJ0IHdpdGggXCI+XCIsIHNvIGl0IG1hdGNoZXMgaWYgYW5kIG9ubHkgaWYgd2UncmUgaW4gdGhlIGNoYWluXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChnb29kKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hdGNoICs9IGxpbmUgKyBcIlxcblwiO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxlZnRPdmVyICs9IG1hdGNoICsgbGluZTtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBcIlxcblwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghLyhefFxcbik+Ly50ZXN0KG1hdGNoKSkgeyAgICAgICAgICAgICAvLyBkKVxuICAgICAgICAgICAgICAgIGxlZnRPdmVyICs9IG1hdGNoO1xuICAgICAgICAgICAgICAgIG1hdGNoID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNodW5rLnN0YXJ0VGFnID0gbWF0Y2g7XG4gICAgICAgIGNodW5rLmJlZm9yZSA9IGxlZnRPdmVyO1xuXG4gICAgICAgIC8vIGVuZCBvZiBjaGFuZ2VcblxuICAgICAgICBpZiAoY2h1bmsuYWZ0ZXIpIHtcbiAgICAgICAgICAgIGNodW5rLmFmdGVyID0gY2h1bmsuYWZ0ZXIucmVwbGFjZSgvXlxcbj8vLCBcIlxcblwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNodW5rLmFmdGVyID0gY2h1bmsuYWZ0ZXIucmVwbGFjZSgvXigoKFxcbnxeKShcXG5bIFxcdF0qKSo+KC4rXFxuKSouKikrKFxcblsgXFx0XSopKikvLFxuICAgICAgICAgICAgZnVuY3Rpb24gKHRvdGFsTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBjaHVuay5lbmRUYWcgPSB0b3RhbE1hdGNoO1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIHZhciByZXBsYWNlQmxhbmtzSW5UYWdzID0gZnVuY3Rpb24gKHVzZUJyYWNrZXQpIHtcblxuICAgICAgICAgICAgdmFyIHJlcGxhY2VtZW50ID0gdXNlQnJhY2tldCA/IFwiPiBcIiA6IFwiXCI7XG5cbiAgICAgICAgICAgIGlmIChjaHVuay5zdGFydFRhZykge1xuICAgICAgICAgICAgICAgIGNodW5rLnN0YXJ0VGFnID0gY2h1bmsuc3RhcnRUYWcucmVwbGFjZSgvXFxuKCg+fFxccykqKVxcbiQvLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAodG90YWxNYXRjaCwgbWFya2Rvd24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlxcblwiICsgbWFya2Rvd24ucmVwbGFjZSgvXlsgXXswLDN9Pj9bIFxcdF0qJC9nbSwgcmVwbGFjZW1lbnQpICsgXCJcXG5cIjtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2h1bmsuZW5kVGFnKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsuZW5kVGFnID0gY2h1bmsuZW5kVGFnLnJlcGxhY2UoL15cXG4oKD58XFxzKSopXFxuLyxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHRvdGFsTWF0Y2gsIG1hcmtkb3duKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcXG5cIiArIG1hcmtkb3duLnJlcGxhY2UoL15bIF17MCwzfT4/WyBcXHRdKiQvZ20sIHJlcGxhY2VtZW50KSArIFwiXFxuXCI7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICgvXig/IVsgXXswLDN9PikvbS50ZXN0KGNodW5rLnNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgIHRoaXMud3JhcChjaHVuaywgU0VUVElOR1MubGluZUxlbmd0aCAtIDIpO1xuICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gY2h1bmsuc2VsZWN0aW9uLnJlcGxhY2UoL14vZ20sIFwiPiBcIik7XG4gICAgICAgICAgICByZXBsYWNlQmxhbmtzSW5UYWdzKHRydWUpO1xuICAgICAgICAgICAgY2h1bmsuc2tpcExpbmVzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvXlsgXXswLDN9PiA/L2dtLCBcIlwiKTtcbiAgICAgICAgICAgIHRoaXMudW53cmFwKGNodW5rKTtcbiAgICAgICAgICAgIHJlcGxhY2VCbGFua3NJblRhZ3MoZmFsc2UpO1xuXG4gICAgICAgICAgICBpZiAoIS9eKFxcbnxeKVsgXXswLDN9Pi8udGVzdChjaHVuay5zZWxlY3Rpb24pICYmIGNodW5rLnN0YXJ0VGFnKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsuc3RhcnRUYWcgPSBjaHVuay5zdGFydFRhZy5yZXBsYWNlKC9cXG57MCwyfSQvLCBcIlxcblxcblwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCEvKFxcbnxeKVsgXXswLDN9Pi4qJC8udGVzdChjaHVuay5zZWxlY3Rpb24pICYmIGNodW5rLmVuZFRhZykge1xuICAgICAgICAgICAgICAgIGNodW5rLmVuZFRhZyA9IGNodW5rLmVuZFRhZy5yZXBsYWNlKC9eXFxuezAsMn0vLCBcIlxcblxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IHRoaXMuaG9va3MucG9zdEJsb2NrcXVvdGVDcmVhdGlvbihjaHVuay5zZWxlY3Rpb24pO1xuXG4gICAgICAgIGlmICghL1xcbi8udGVzdChjaHVuay5zZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvXig+ICopLyxcbiAgICAgICAgICAgIGZ1bmN0aW9uICh3aG9sZU1hdGNoLCBibGFua3MpIHtcbiAgICAgICAgICAgICAgICBjaHVuay5zdGFydFRhZyArPSBibGFua3M7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjb21tYW5kUHJvdG8uZG9Db2RlID0gZnVuY3Rpb24gKGNodW5rLCBwb3N0UHJvY2Vzc2luZykge1xuXG4gICAgICAgIHZhciBoYXNUZXh0QmVmb3JlID0gL1xcU1sgXSokLy50ZXN0KGNodW5rLmJlZm9yZSk7XG4gICAgICAgIHZhciBoYXNUZXh0QWZ0ZXIgPSAvXlsgXSpcXFMvLnRlc3QoY2h1bmsuYWZ0ZXIpO1xuXG4gICAgICAgIC8vIFVzZSAnZm91ciBzcGFjZScgbWFya2Rvd24gaWYgdGhlIHNlbGVjdGlvbiBpcyBvbiBpdHMgb3duXG4gICAgICAgIC8vIGxpbmUgb3IgaXMgbXVsdGlsaW5lLlxuICAgICAgICBpZiAoKCFoYXNUZXh0QWZ0ZXIgJiYgIWhhc1RleHRCZWZvcmUpIHx8IC9cXG4vLnRlc3QoY2h1bmsuc2VsZWN0aW9uKSkge1xuXG4gICAgICAgICAgICBjaHVuay5iZWZvcmUgPSBjaHVuay5iZWZvcmUucmVwbGFjZSgvWyBdezR9JC8sXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKHRvdGFsTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gdG90YWxNYXRjaCArIGNodW5rLnNlbGVjdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHZhciBuTGluZXNCYWNrID0gMTtcbiAgICAgICAgICAgIHZhciBuTGluZXNGb3J3YXJkID0gMTtcblxuICAgICAgICAgICAgaWYgKC8oXFxufF4pKFxcdHxbIF17NCx9KS4qXFxuJC8udGVzdChjaHVuay5iZWZvcmUpKSB7XG4gICAgICAgICAgICAgICAgbkxpbmVzQmFjayA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoL15cXG4oXFx0fFsgXXs0LH0pLy50ZXN0KGNodW5rLmFmdGVyKSkge1xuICAgICAgICAgICAgICAgIG5MaW5lc0ZvcndhcmQgPSAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjaHVuay5za2lwTGluZXMobkxpbmVzQmFjaywgbkxpbmVzRm9yd2FyZCk7XG5cbiAgICAgICAgICAgIGlmICghY2h1bmsuc2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsuc3RhcnRUYWcgPSBcIiAgICBcIjtcbiAgICAgICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSB0aGlzLmdldFN0cmluZyhcImNvZGVleGFtcGxlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKC9eWyBdezAsM31cXFMvbS50ZXN0KGNodW5rLnNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKC9cXG4vLnRlc3QoY2h1bmsuc2VsZWN0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IGNodW5rLnNlbGVjdGlvbi5yZXBsYWNlKC9eL2dtLCBcIiAgICBcIik7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgLy8gaWYgaXQncyBub3QgbXVsdGlsaW5lLCBkbyBub3Qgc2VsZWN0IHRoZSBmb3VyIGFkZGVkIHNwYWNlczsgdGhpcyBpcyBtb3JlIGNvbnNpc3RlbnQgd2l0aCB0aGUgZG9MaXN0IGJlaGF2aW9yXG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVuay5iZWZvcmUgKz0gXCIgICAgXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvXig/OlsgXXs0fXxbIF17MCwzfVxcdCkvZ20sIFwiXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFVzZSBiYWNrdGlja3MgKGApIHRvIGRlbGltaXQgdGhlIGNvZGUgYmxvY2suXG5cbiAgICAgICAgICAgIGNodW5rLnRyaW1XaGl0ZXNwYWNlKCk7XG4gICAgICAgICAgICBjaHVuay5maW5kVGFncygvYC8sIC9gLyk7XG5cbiAgICAgICAgICAgIGlmICghY2h1bmsuc3RhcnRUYWcgJiYgIWNodW5rLmVuZFRhZykge1xuICAgICAgICAgICAgICAgIGNodW5rLnN0YXJ0VGFnID0gY2h1bmsuZW5kVGFnID0gXCJgXCI7XG4gICAgICAgICAgICAgICAgaWYgKCFjaHVuay5zZWxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gdGhpcy5nZXRTdHJpbmcoXCJjb2RlZXhhbXBsZVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaHVuay5lbmRUYWcgJiYgIWNodW5rLnN0YXJ0VGFnKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsuYmVmb3JlICs9IGNodW5rLmVuZFRhZztcbiAgICAgICAgICAgICAgICBjaHVuay5lbmRUYWcgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY2h1bmsuc3RhcnRUYWcgPSBjaHVuay5lbmRUYWcgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvbW1hbmRQcm90by5kb0xpc3QgPSBmdW5jdGlvbiAoY2h1bmssIHBvc3RQcm9jZXNzaW5nLCBpc051bWJlcmVkTGlzdCkge1xuXG4gICAgICAgIC8vIFRoZXNlIGFyZSBpZGVudGljYWwgZXhjZXB0IGF0IHRoZSB2ZXJ5IGJlZ2lubmluZyBhbmQgZW5kLlxuICAgICAgICAvLyBTaG91bGQgcHJvYmFibHkgdXNlIHRoZSByZWdleCBleHRlbnNpb24gZnVuY3Rpb24gdG8gbWFrZSB0aGlzIGNsZWFyZXIuXG4gICAgICAgIHZhciBwcmV2aW91c0l0ZW1zUmVnZXggPSAvKFxcbnxeKSgoWyBdezAsM30oWyorLV18XFxkK1suXSlbIFxcdF0rLiopKFxcbi4rfFxcbnsyLH0oWyorLV0uKnxcXGQrWy5dKVsgXFx0XSsuKnxcXG57Mix9WyBcXHRdK1xcUy4qKSopXFxuKiQvO1xuICAgICAgICB2YXIgbmV4dEl0ZW1zUmVnZXggPSAvXlxcbiooKFsgXXswLDN9KFsqKy1dfFxcZCtbLl0pWyBcXHRdKy4qKShcXG4uK3xcXG57Mix9KFsqKy1dLip8XFxkK1suXSlbIFxcdF0rLip8XFxuezIsfVsgXFx0XStcXFMuKikqKVxcbiovO1xuXG4gICAgICAgIC8vIFRoZSBkZWZhdWx0IGJ1bGxldCBpcyBhIGRhc2ggYnV0IG90aGVycyBhcmUgcG9zc2libGUuXG4gICAgICAgIC8vIFRoaXMgaGFzIG5vdGhpbmcgdG8gZG8gd2l0aCB0aGUgcGFydGljdWxhciBIVE1MIGJ1bGxldCxcbiAgICAgICAgLy8gaXQncyBqdXN0IGEgbWFya2Rvd24gYnVsbGV0LlxuICAgICAgICB2YXIgYnVsbGV0ID0gXCItXCI7XG5cbiAgICAgICAgLy8gVGhlIG51bWJlciBpbiBhIG51bWJlcmVkIGxpc3QuXG4gICAgICAgIHZhciBudW0gPSAxO1xuXG4gICAgICAgIC8vIEdldCB0aGUgaXRlbSBwcmVmaXggLSBlLmcuIFwiIDEuIFwiIGZvciBhIG51bWJlcmVkIGxpc3QsIFwiIC0gXCIgZm9yIGEgYnVsbGV0ZWQgbGlzdC5cbiAgICAgICAgdmFyIGdldEl0ZW1QcmVmaXggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgcHJlZml4O1xuICAgICAgICAgICAgaWYgKGlzTnVtYmVyZWRMaXN0KSB7XG4gICAgICAgICAgICAgICAgcHJlZml4ID0gXCIgXCIgKyBudW0gKyBcIi4gXCI7XG4gICAgICAgICAgICAgICAgbnVtKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmVmaXggPSBcIiBcIiArIGJ1bGxldCArIFwiIFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBGaXhlcyB0aGUgcHJlZml4ZXMgb2YgdGhlIG90aGVyIGxpc3QgaXRlbXMuXG4gICAgICAgIHZhciBnZXRQcmVmaXhlZEl0ZW0gPSBmdW5jdGlvbiAoaXRlbVRleHQpIHtcblxuICAgICAgICAgICAgLy8gVGhlIG51bWJlcmluZyBmbGFnIGlzIHVuc2V0IHdoZW4gY2FsbGVkIGJ5IGF1dG9pbmRlbnQuXG4gICAgICAgICAgICBpZiAoaXNOdW1iZXJlZExpc3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlzTnVtYmVyZWRMaXN0ID0gL15cXHMqXFxkLy50ZXN0KGl0ZW1UZXh0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmVudW1iZXIvYnVsbGV0IHRoZSBsaXN0IGVsZW1lbnQuXG4gICAgICAgICAgICBpdGVtVGV4dCA9IGl0ZW1UZXh0LnJlcGxhY2UoL15bIF17MCwzfShbKistXXxcXGQrWy5dKVxccy9nbSxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoXykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0SXRlbVByZWZpeCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gaXRlbVRleHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgY2h1bmsuZmluZFRhZ3MoLyhcXG58XikqWyBdezAsM30oWyorLV18XFxkK1suXSlcXHMrLywgbnVsbCk7XG5cbiAgICAgICAgaWYgKGNodW5rLmJlZm9yZSAmJiAhL1xcbiQvLnRlc3QoY2h1bmsuYmVmb3JlKSAmJiAhL15cXG4vLnRlc3QoY2h1bmsuc3RhcnRUYWcpKSB7XG4gICAgICAgICAgICBjaHVuay5iZWZvcmUgKz0gY2h1bmsuc3RhcnRUYWc7XG4gICAgICAgICAgICBjaHVuay5zdGFydFRhZyA9IFwiXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2h1bmsuc3RhcnRUYWcpIHtcblxuICAgICAgICAgICAgdmFyIGhhc0RpZ2l0cyA9IC9cXGQrWy5dLy50ZXN0KGNodW5rLnN0YXJ0VGFnKTtcbiAgICAgICAgICAgIGNodW5rLnN0YXJ0VGFnID0gXCJcIjtcbiAgICAgICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IGNodW5rLnNlbGVjdGlvbi5yZXBsYWNlKC9cXG5bIF17NH0vZywgXCJcXG5cIik7XG4gICAgICAgICAgICB0aGlzLnVud3JhcChjaHVuayk7XG4gICAgICAgICAgICBjaHVuay5za2lwTGluZXMoKTtcblxuICAgICAgICAgICAgaWYgKGhhc0RpZ2l0cykge1xuICAgICAgICAgICAgICAgIC8vIEhhdmUgdG8gcmVudW1iZXIgdGhlIGJ1bGxldCBwb2ludHMgaWYgdGhpcyBpcyBhIG51bWJlcmVkIGxpc3QuXG4gICAgICAgICAgICAgICAgY2h1bmsuYWZ0ZXIgPSBjaHVuay5hZnRlci5yZXBsYWNlKG5leHRJdGVtc1JlZ2V4LCBnZXRQcmVmaXhlZEl0ZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTnVtYmVyZWRMaXN0ID09IGhhc0RpZ2l0cykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBuTGluZXNVcCA9IDE7XG5cbiAgICAgICAgY2h1bmsuYmVmb3JlID0gY2h1bmsuYmVmb3JlLnJlcGxhY2UocHJldmlvdXNJdGVtc1JlZ2V4LFxuICAgICAgICAgICAgZnVuY3Rpb24gKGl0ZW1UZXh0KSB7XG4gICAgICAgICAgICAgICAgaWYgKC9eXFxzKihbKistXSkvLnRlc3QoaXRlbVRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1bGxldCA9IHJlLiQxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuTGluZXNVcCA9IC9bXlxcbl1cXG5cXG5bXlxcbl0vLnRlc3QoaXRlbVRleHQpID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldFByZWZpeGVkSXRlbShpdGVtVGV4dCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIWNodW5rLnNlbGVjdGlvbikge1xuICAgICAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gdGhpcy5nZXRTdHJpbmcoXCJsaXRlbVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcmVmaXggPSBnZXRJdGVtUHJlZml4KCk7XG5cbiAgICAgICAgdmFyIG5MaW5lc0Rvd24gPSAxO1xuXG4gICAgICAgIGNodW5rLmFmdGVyID0gY2h1bmsuYWZ0ZXIucmVwbGFjZShuZXh0SXRlbXNSZWdleCxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChpdGVtVGV4dCkge1xuICAgICAgICAgICAgICAgIG5MaW5lc0Rvd24gPSAvW15cXG5dXFxuXFxuW15cXG5dLy50ZXN0KGl0ZW1UZXh0KSA/IDEgOiAwO1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRQcmVmaXhlZEl0ZW0oaXRlbVRleHQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgY2h1bmsudHJpbVdoaXRlc3BhY2UodHJ1ZSk7XG4gICAgICAgIGNodW5rLnNraXBMaW5lcyhuTGluZXNVcCwgbkxpbmVzRG93biwgdHJ1ZSk7XG4gICAgICAgIGNodW5rLnN0YXJ0VGFnID0gcHJlZml4O1xuICAgICAgICB2YXIgc3BhY2VzID0gcHJlZml4LnJlcGxhY2UoLy4vZywgXCIgXCIpO1xuICAgICAgICB0aGlzLndyYXAoY2h1bmssIFNFVFRJTkdTLmxpbmVMZW5ndGggLSBzcGFjZXMubGVuZ3RoKTtcbiAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gY2h1bmsuc2VsZWN0aW9uLnJlcGxhY2UoL1xcbi9nLCBcIlxcblwiICsgc3BhY2VzKTtcblxuICAgIH07XG5cbiAgICBjb21tYW5kUHJvdG8uZG9IZWFkaW5nID0gZnVuY3Rpb24gKGNodW5rLCBwb3N0UHJvY2Vzc2luZykge1xuXG4gICAgICAgIC8vIFJlbW92ZSBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2UgYW5kIHJlZHVjZSBpbnRlcm5hbCBzcGFjZXMgdG8gc2luZ2xlIHNwYWNlcy5cbiAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gY2h1bmsuc2VsZWN0aW9uLnJlcGxhY2UoL1xccysvZywgXCIgXCIpO1xuICAgICAgICBjaHVuay5zZWxlY3Rpb24gPSBjaHVuay5zZWxlY3Rpb24ucmVwbGFjZSgvKF5cXHMrfFxccyskKS9nLCBcIlwiKTtcblxuICAgICAgICAvLyBJZiB3ZSBjbGlja2VkIHRoZSBidXR0b24gd2l0aCBubyBzZWxlY3RlZCB0ZXh0LCB3ZSBqdXN0XG4gICAgICAgIC8vIG1ha2UgYSBsZXZlbCAyIGhhc2ggaGVhZGVyIGFyb3VuZCBzb21lIGRlZmF1bHQgdGV4dC5cbiAgICAgICAgaWYgKCFjaHVuay5zZWxlY3Rpb24pIHtcbiAgICAgICAgICAgIGNodW5rLnN0YXJ0VGFnID0gXCIjIyBcIjtcbiAgICAgICAgICAgIGNodW5rLnNlbGVjdGlvbiA9IHRoaXMuZ2V0U3RyaW5nKFwiaGVhZGluZ2V4YW1wbGVcIik7XG4gICAgICAgICAgICBjaHVuay5lbmRUYWcgPSBcIiAjI1wiO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGhlYWRlckxldmVsID0gMDsgICAgIC8vIFRoZSBleGlzdGluZyBoZWFkZXIgbGV2ZWwgb2YgdGhlIHNlbGVjdGVkIHRleHQuXG5cbiAgICAgICAgLy8gUmVtb3ZlIGFueSBleGlzdGluZyBoYXNoIGhlYWRpbmcgbWFya2Rvd24gYW5kIHNhdmUgdGhlIGhlYWRlciBsZXZlbC5cbiAgICAgICAgY2h1bmsuZmluZFRhZ3MoLyMrWyBdKi8sIC9bIF0qIysvKTtcbiAgICAgICAgaWYgKC8jKy8udGVzdChjaHVuay5zdGFydFRhZykpIHtcbiAgICAgICAgICAgIGhlYWRlckxldmVsID0gcmUubGFzdE1hdGNoLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBjaHVuay5zdGFydFRhZyA9IGNodW5rLmVuZFRhZyA9IFwiXCI7XG5cbiAgICAgICAgLy8gVHJ5IHRvIGdldCB0aGUgY3VycmVudCBoZWFkZXIgbGV2ZWwgYnkgbG9va2luZyBmb3IgLSBhbmQgPSBpbiB0aGUgbGluZVxuICAgICAgICAvLyBiZWxvdyB0aGUgc2VsZWN0aW9uLlxuICAgICAgICBjaHVuay5maW5kVGFncyhudWxsLCAvXFxzPygtK3w9KykvKTtcbiAgICAgICAgaWYgKC89Ky8udGVzdChjaHVuay5lbmRUYWcpKSB7XG4gICAgICAgICAgICBoZWFkZXJMZXZlbCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKC8tKy8udGVzdChjaHVuay5lbmRUYWcpKSB7XG4gICAgICAgICAgICBoZWFkZXJMZXZlbCA9IDI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTa2lwIHRvIHRoZSBuZXh0IGxpbmUgc28gd2UgY2FuIGNyZWF0ZSB0aGUgaGVhZGVyIG1hcmtkb3duLlxuICAgICAgICBjaHVuay5zdGFydFRhZyA9IGNodW5rLmVuZFRhZyA9IFwiXCI7XG4gICAgICAgIGNodW5rLnNraXBMaW5lcygxLCAxKTtcblxuICAgICAgICAvLyBXZSBtYWtlIGEgbGV2ZWwgMiBoZWFkZXIgaWYgdGhlcmUgaXMgbm8gY3VycmVudCBoZWFkZXIuXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIGEgaGVhZGVyIGxldmVsLCB3ZSBzdWJzdHJhY3Qgb25lIGZyb20gdGhlIGhlYWRlciBsZXZlbC5cbiAgICAgICAgLy8gSWYgaXQncyBhbHJlYWR5IGEgbGV2ZWwgMSBoZWFkZXIsIGl0J3MgcmVtb3ZlZC5cbiAgICAgICAgdmFyIGhlYWRlckxldmVsVG9DcmVhdGUgPSBoZWFkZXJMZXZlbCA9PSAwID8gMiA6IGhlYWRlckxldmVsIC0gMTtcblxuICAgICAgICBpZiAoaGVhZGVyTGV2ZWxUb0NyZWF0ZSA+IDApIHtcblxuICAgICAgICAgICAgLy8gVGhlIGJ1dHRvbiBvbmx5IGNyZWF0ZXMgbGV2ZWwgMSBhbmQgMiB1bmRlcmxpbmUgaGVhZGVycy5cbiAgICAgICAgICAgIC8vIFdoeSBub3QgaGF2ZSBpdCBpdGVyYXRlIG92ZXIgaGFzaCBoZWFkZXIgbGV2ZWxzPyAgV291bGRuJ3QgdGhhdCBiZSBlYXNpZXIgYW5kIGNsZWFuZXI/XG4gICAgICAgICAgICB2YXIgaGVhZGVyQ2hhciA9IGhlYWRlckxldmVsVG9DcmVhdGUgPj0gMiA/IFwiLVwiIDogXCI9XCI7XG4gICAgICAgICAgICB2YXIgbGVuID0gY2h1bmsuc2VsZWN0aW9uLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChsZW4gPiBTRVRUSU5HUy5saW5lTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbGVuID0gU0VUVElOR1MubGluZUxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNodW5rLmVuZFRhZyA9IFwiXFxuXCI7XG4gICAgICAgICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgICAgICAgICBjaHVuay5lbmRUYWcgKz0gaGVhZGVyQ2hhcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjb21tYW5kUHJvdG8uZG9Ib3Jpem9udGFsUnVsZSA9IGZ1bmN0aW9uIChjaHVuaywgcG9zdFByb2Nlc3NpbmcpIHtcbiAgICAgICAgY2h1bmsuc3RhcnRUYWcgPSBcIi0tLS0tLS0tLS1cXG5cIjtcbiAgICAgICAgY2h1bmsuc2VsZWN0aW9uID0gXCJcIjtcbiAgICAgICAgY2h1bmsuc2tpcExpbmVzKDIsIDEsIHRydWUpO1xuICAgIH1cblxuXG59KSgpO1xuIiwiaW1wb3J0IHsgS0VZX0NPREUgfSBmcm9tICcuLi8uLi9jb25zdGFudHMubW9kJztcbihmdW5jdGlvbiAoKSB7XG5cbiAgICBpZiAoU3RhY2tFeGNoYW5nZS5NYXJrZG93bkVkaXRvcilcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIGFsbEluc3RhbmNlcyA9IFtdO1xuICAgIHZhciBvbmVib3hNYXRjaCA9IHt9O1xuICAgIHZhciB3ZUFyZU9uTWV0YSwgZW5hYmxlVGFibGVzO1xuXG4gICAgZnVuY3Rpb24gcmVmcmVzaEFsbCgpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGxJbnN0YW5jZXMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBhbGxJbnN0YW5jZXNbaV0ucmVmcmVzaFByZXZpZXcoKTtcbiAgICB9XG4gICAgdmFyIHF1ZXN0aW9uTGlua01ha2VyID0gZ2V0UXVlc3Rpb25MaW5rUHJvY2Vzc29yKHJlZnJlc2hBbGwpLFxuICAgICAgICBpbWd1ckh0dHBzTWFrZXIgPSBnZXRJbWd1ckh0dHBzUHJvY2Vzc29yKCksXG4gICAgICAgIGNyZWF0aW9uQ2FsbGJhY2tzID0gJC5DYWxsYmFja3MoKTtcblxuICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3IgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXG4gICAgICAgIHZhciBwb3N0Zml4ID0gb3B0aW9ucy5wb3N0Zml4IHx8IFwiXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgd2VBcmVPbk1ldGEgPSBTdGFja0V4Y2hhbmdlLm9wdGlvbnMuc2l0ZS5pc01ldGFTaXRlO1xuICAgICAgICBlbmFibGVUYWJsZXMgPSBvcHRpb25zLmVuYWJsZVRhYmxlcztcblxuICAgICAgICBmdW5jdGlvbiBjb21tb25tYXJrQ29udmVydGVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21tb25tYXJrLkNvbnZlcnRlcih7XG4gICAgICAgICAgICAgICAgYXV0b05ld2xpbmVzOiBTdGFja0V4Y2hhbmdlLnNldHRpbmdzLm1hcmtkb3duLmF1dG9OZXdsaW5lcyxcbiAgICAgICAgICAgICAgICBlbmFibGVUYWJsZXM6IG9wdGlvbnMuZW5hYmxlVGFibGVzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY29udmVydGVyID0gY29tbW9ubWFya0NvbnZlcnRlcihvcHRpb25zKTtcblxuICAgICAgICBpZihvcHRpb25zLm11dGF0ZUNvbnZlcnRlcikge1xuICAgICAgICAgICAgY29udmVydGVyID0gb3B0aW9ucy5tdXRhdGVDb252ZXJ0ZXIoY29udmVydGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzYW5pdGl6ZUFuZEhpZ2hsaWdodEZ1bmMgPSBvcHRpb25zLnNhbml0aXplQW5kSGlnaGxpZ2h0IHx8IHNhbml0aXplQW5kSGlnaGxpZ2h0O1xuXG4gICAgICAgIHZhciBob29rcyA9IGNvbnZlcnRlci5ob29rcztcbiAgICAgICAgaG9va3MuYWRkTm9vcChcInByZVNhZmVcIik7XG4gICAgICAgIGlmICghb3B0aW9ucy5kaXNhYmxlQXV0b1F1ZXN0aW9uTGlua3MpXG4gICAgICAgICAgICBob29rcy5jaGFpbihcInBvc3RDb252ZXJzaW9uXCIsIHF1ZXN0aW9uTGlua01ha2VyKTtcblxuICAgICAgICBob29rcy5jaGFpbihcInBvc3RDb252ZXJzaW9uXCIsIGZ1bmN0aW9uIChzKSB7IHJldHVybiBob29rcy5wcmVTYWZlKHMpOyB9KTtcbiAgICAgICAgaG9va3MuY2hhaW4oXCJwb3N0Q29udmVyc2lvblwiLCBzYW5pdGl6ZUFuZEhpZ2hsaWdodEZ1bmMpO1xuICAgICAgICBob29rcy5jaGFpbihcInBvc3RDb252ZXJzaW9uXCIsIGJhbGFuY2VUYWdzKTtcbiAgICAgICAgaG9va3MuY2hhaW4oXCJwb3N0Q29udmVyc2lvblwiLCBjcmVhdGVTcG9pbGVycyk7XG4gICAgICAgIGhvb2tzLmNoYWluKFwicG9zdENvbnZlcnNpb25cIiwgbWFrZVRhZ0xpbmtzKTtcbiAgICAgICAgaWYod2luZG93Lm1vZFN1c3BlbmRUb2tlbnMpIGhvb2tzLmNoYWluKFwicG9zdENvbnZlcnNpb25cIiwgd2luZG93Lm1vZFN1c3BlbmRUb2tlbnMpO1xuXG4gICAgICAgIHZhciBoZWxwID0gbmV3IE1hcmtkb3duSGVscCh7IHBvc3RmaXg6IHBvc3RmaXgsIHVzZXJJZDogb3B0aW9ucy51c2VySWQgfSk7XG4gICAgICAgIHZhciBjbG9zZUlubGluZURpYWxvZztcblxuICAgICAgICBpZiAob3B0aW9ucy5pbWFnZVVwbG9hZGVyICYmICEoXCJzaG93TG93UmVwSW1hZ2VVcGxvYWRXYXJuaW5nXCIgaW4gb3B0aW9ucy5pbWFnZVVwbG9hZGVyKSkge1xuICAgICAgICAgICAgb3B0aW9ucy5pbWFnZVVwbG9hZGVyLnNob3dMb3dSZXBJbWFnZVVwbG9hZFdhcm5pbmcgPSBvcHRpb25zLnNob3dMb3dSZXBJbWFnZVVwbG9hZFdhcm5pbmc7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZWRpdG9yT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGhlbHBCdXR0b246IHsgaGFuZGxlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChjbG9zZUlubGluZURpYWxvZykge1xuICAgICAgICAgICAgICAgICAgICBjbG9zZUlubGluZURpYWxvZygpO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgaGVscC50b2dnbGUoKTtcbiAgICAgICAgICAgIH19LFxuICAgICAgICAgICAgc3RyaW5nczogZ2V0TG9jYWxpemVkU3RyaW5ncyhvcHRpb25zLm5vQ29kZSksXG4gICAgICAgICAgICB3cmFwSW1hZ2VJbkxpbms6ICFvcHRpb25zLmRpc2FibGVJbWFnZUxpbmtXcmFwcGluZyxcbiAgICAgICAgICAgIGNvbnZlcnRJbWFnZXNUb0xpbmtzOiBvcHRpb25zLmNvbnZlcnRJbWFnZXNUb0xpbmtzLFxuICAgICAgICAgICAgaW1hZ2VVcGxvYWRlcjogb3B0aW9ucy5pbWFnZVVwbG9hZGVyXG4gICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICB2YXIgZWRpdG9yID0gbmV3IE1hcmtkb3duLkVkaXRvcihjb252ZXJ0ZXIsIHBvc3RmaXgsIGVkaXRvck9wdGlvbnMpO1xuXG4gICAgICAgIGVkaXRvci5ob29rcy5jaGFpbihcInBvc3RCbG9ja3F1b3RlQ3JlYXRpb25cIiwgcHJldmVudEF1dG9tYXRpY1Nwb2lsZXIpO1xuXG4gICAgICAgIGlmIChTdGFja0V4Y2hhbmdlLnNldHRpbmdzLnNpdGUuYWxsb3dJbWFnZVVwbG9hZHMgJiYgIW9wdGlvbnMubm9Nb2RhbHMpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3dMb3dSZXBJbWFnZVVwbG9hZFdhcm5pbmcpIHtcbiAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmltYWdlVXBsb2FkZXIuZW5hYmxlTG93UmVwV2FybmluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWRpdG9yLmhvb2tzLnNldChcImluc2VydEltYWdlRGlhbG9nXCIsIFN0YWNrRXhjaGFuZ2UuaW1hZ2VVcGxvYWRlci51cGxvYWRJbWFnZURpYWxvZyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5ub01vZGFscykge1xuICAgICAgICAgICAgY2xvc2VJbmxpbmVEaWFsb2cgPSBpbmxpbmVMaW5rQW5kSW1hZ2VEaWFsb2dzKGVkaXRvciwgZWRpdG9yT3B0aW9ucywgcG9zdGZpeCwgaGVscCkuY2xvc2VJbmxpbmVEaWFsb2c7XG4gICAgICAgIH1cblxuICAgICAgICBpZihTdGFja0V4Y2hhbmdlLnNldHRpbmdzLnNpdGUuZW5hYmxlSW1ndXJIdHRwcylcbiAgICAgICAgICAgIGhvb2tzLmNoYWluKFwicG9zdENvbnZlcnNpb25cIiwgaW1ndXJIdHRwc01ha2VyKTtcblxuICAgICAgICBjcmVhdGlvbkNhbGxiYWNrcy5maXJlKGVkaXRvciwgb3B0aW9ucy5wb3N0Zml4KTtcblxuICAgICAgICB2YXIgalByZXZpZXcgPSAkKFwiI3dtZC1wcmV2aWV3XCIgKyBwb3N0Zml4KTtcblxuICAgICAgICBlZGl0b3IuaG9va3MuY2hhaW4oXCJvblByZXZpZXdSZWZyZXNoXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGpQcmV2aWV3LnRyaWdnZXIoXCJ3bWRyZWZyZXNoXCIpO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25lYm94RW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIGNyZWF0ZU9uZWJveChqUHJldmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGFsbEluc3RhbmNlcy5wdXNoKGVkaXRvcik7IC8vIFRPRE86IFRoaXMgaXMgYSBtZW1vcnkgbGVhay5cblxuICAgICAgICBlZGl0b3IucnVuKCk7XG4gICAgICAgIFxuICAgICAgICBpZiAob3B0aW9ucy5pbW1lZGlhdGVseVNob3dNYXJrZG93bkhlbHApXG4gICAgICAgICAgICBoZWxwLnNob3dPbmNlKG9wdGlvbnMpO1xuICAgICAgICBlbHNlIGlmIChvcHRpb25zLmF1dG9TaG93TWFya2Rvd25IZWxwKVxuICAgICAgICAgICAgJChcIiN3bWQtaW5wdXRcIiArIHBvc3RmaXgpLm9uZShcImZvY3VzXCIsIGZ1bmN0aW9uICgpIHsgaGVscC5zaG93T25jZShvcHRpb25zKTsgfSk7XG5cbiAgICAgICAgZWRpdG9yLmRpc2FibGVTdWJtaXNzaW9uID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAkKFwiI3N1Ym1pdC1idXR0b25cIiArIHBvc3RmaXgpLmF0dHIoXCJkaXNhYmxlZFwiLCBcImRpc2FibGVkXCIpO1xuICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5uYXZQcmV2ZW50aW9uLnBhdXNlKCk7IC8vIFRPRE86IG1ha2UgdGhpcyBoYW5kbGUgbXVsdGlwbGUgZWRpdG9yc1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBlZGl0b3I7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGdldExvY2FsaXplZFN0cmluZ3Mobm9Db2RlKSB7XG4gICAgICAgIHZhciBoeXBlcmxpbmtFeGFtcGxlID0gXCI8cD5odHRwczovL2V4YW1wbGUuY29tLyBcXFwiXCIgKyBfcyhcIm9wdGlvbmFsIHRpdGxlXCIpICsgXCJcXFwiPC9wPlwiO1xuICAgICAgICB2YXIgaHlwZXJsaW5rVGFiVGl0bGUgPSBfcyhcIkluc2VydCBIeXBlcmxpbmtcIik7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJvbGQ6IF9zKFwiU3Ryb25nIDxzdHJvbmc+IEN0cmwrQlwiKSxcbiAgICAgICAgICAgIGJvbGRleGFtcGxlOiBfcyhcInN0cm9uZyB0ZXh0XCIpLFxuICAgIFxuICAgICAgICAgICAgaXRhbGljOiBfcyhcIkVtcGhhc2lzIDxlbT4gQ3RybCtJXCIpLFxuICAgICAgICAgICAgaXRhbGljZXhhbXBsZTogX3MoXCJlbXBoYXNpemVkIHRleHRcIiksXG4gICAgXG4gICAgICAgICAgICBsaW5rOiBfcyhcIkh5cGVybGluayA8YT4gQ3RybCtMXCIpLFxuICAgICAgICAgICAgbGlua2Rlc2NyaXB0aW9uOiBfcyhcImVudGVyIGxpbmsgZGVzY3JpcHRpb24gaGVyZVwiKSxcbiAgICAgICAgICAgIGxpbmtkaWFsb2c6IFwiPHA+PGxhYmVsIGNsYXNzPVxcXCJmdy1ib2xkXFxcIiBmb3I9XFxcInByb21wdC1kaWFsb2ctaW5wdXRcXFwiPlwiKyBoeXBlcmxpbmtUYWJUaXRsZSArIFwiPC9sYWJlbD48L3A+XCIgKyBoeXBlcmxpbmtFeGFtcGxlLFxuICAgICAgICAgICAgbGlua3RhYnRpdGxlOiBoeXBlcmxpbmtUYWJUaXRsZSxcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcXVvdGU6IF9zKFwiQmxvY2txdW90ZSA8YmxvY2txdW90ZT4gQ3RybCtRXCIpLFxuICAgICAgICAgICAgcXVvdGVleGFtcGxlOiBfcyhcIkJsb2NrcXVvdGVcIiksXG4gICAgXG4gICAgICAgICAgICBjb2RlOiBub0NvZGUgPyBfcyhcIlByZWZvcm1hdHRlZCB0ZXh0IDxwcmU+PGNvZGU+IEN0cmwtS1wiKSA6IF9zKFwiQ29kZSBTYW1wbGUgPHByZT48Y29kZT4gQ3RybCtLXCIpLFxuICAgICAgICAgICAgY29kZWV4YW1wbGU6IG5vQ29kZSA/IF9zKFwiZW50ZXIgcHJlZm9ybWF0dGVkIHRleHQgaGVyZVwiKSA6IF9zKFwiZW50ZXIgY29kZSBoZXJlXCIpLFxuICAgIFxuICAgICAgICAgICAgaW1hZ2U6IF9zKFwiSW1hZ2UgPGltZz4gQ3RybCtHXCIpLFxuICAgICAgICAgICAgaW1hZ2VkZXNjcmlwdGlvbjogX3MoXCJlbnRlciBpbWFnZSBkZXNjcmlwdGlvbiBoZXJlXCIpLFxuICAgICAgICAgICAgaW1hZ2VkaWFsb2c6IFwiPHA+PGI+XCIgKyBfcyhcIkluc2VydCBJbWFnZVwiKSArIFwiPC9iPjwvcD48cD5odHRwczovL2V4YW1wbGUuY29tL2ltYWdlcy9kaWFncmFtLmpwZyBcXFwiXCIgKyBfcyhcIm9wdGlvbmFsIHRpdGxlXCIpICsgXCJcXFwiPC9wPlwiLFxuICAgIFxuICAgICAgICAgICAgb2xpc3Q6IF9zKFwiTnVtYmVyZWQgTGlzdCA8b2w+IEN0cmwrT1wiKSxcbiAgICAgICAgICAgIHVsaXN0OiBfcyhcIkJ1bGxldGVkIExpc3QgPHVsPiBDdHJsK1VcIiksXG4gICAgICAgICAgICBsaXRlbTogX3MoXCJMaXN0IGl0ZW1cIiksXG4gICAgXG4gICAgICAgICAgICBoZWFkaW5nOiBfcyhcIkhlYWRpbmcgPGgxPi88aDI+IEN0cmwrSFwiKSxcbiAgICAgICAgICAgIGhlYWRpbmdleGFtcGxlOiBfcyhcIkhlYWRpbmdcIiksXG4gICAgXG4gICAgICAgICAgICBocjogX3MoXCJIb3Jpem9udGFsIFJ1bGUgPGhyPiBDdHJsK1JcIiksXG4gICAgXG4gICAgICAgICAgICB1bmRvOiBfcyhcIlVuZG8gLSBDdHJsK1pcIiksXG4gICAgICAgICAgICByZWRvOiBfcyhcIlJlZG8gLSBDdHJsK1lcIiksXG4gICAgICAgICAgICByZWRvbWFjOiBfcyhcIlJlZG8gLSBDdHJsK1NoaWZ0K1pcIiksXG4gICAgXG4gICAgICAgICAgICBoZWxwOiBfcyhcIk1hcmtkb3duIEVkaXRpbmcgSGVscFwiKSxcblxuICAgICAgICAgICAgb2s6IF9zKFwiT0tcIiksXG4gICAgICAgICAgICBjYW5jZWw6IF9zKFwiQ2FuY2VsXCIpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBTdGFja0V4Y2hhbmdlLk1hcmtkb3duRWRpdG9yLmNyZWF0aW9uQ2FsbGJhY2tzID0gY3JlYXRpb25DYWxsYmFja3M7XG4gICAgU3RhY2tFeGNoYW5nZS5NYXJrZG93bkVkaXRvci5yZWZyZXNoQWxsUHJldmlld3MgPSByZWZyZXNoQWxsO1xuICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3IucXVlc3Rpb25MaW5rTWFrZXIgPSBnZXRRdWVzdGlvbkxpbmtQcm9jZXNzb3IocmVmcmVzaEFsbCk7XG4gICAgU3RhY2tFeGNoYW5nZS5NYXJrZG93bkVkaXRvci5pbWd1ckh0dHBzTWFrZXIgPSBnZXRJbWd1ckh0dHBzUHJvY2Vzc29yO1xuICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3IubWFrZVRhZ0xpbmtzID0gbWFrZVRhZ0xpbmtzO1xuICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3Iuc2FuaXRpemVBbmRIaWdobGlnaHQgPSBzYW5pdGl6ZUFuZEhpZ2hsaWdodDtcbiAgICBTdGFja0V4Y2hhbmdlLk1hcmtkb3duRWRpdG9yLmNyZWF0ZVNwb2lsZXJzID0gY3JlYXRlU3BvaWxlcnM7XG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8gICAgICAgICAgU1BPSUxFUlMgICAgICAgICAgLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cblxuICAgIC8vIFByZXZlbnQgdGhlIHF1b3RlIGJ1dHRvbiBmcm9tICpldmVyKiBnZW5lcmF0aW5nIGEgc3BvaWxlciAoPiEgc3ludGF4KVxuICAgIC8vICAgQSB1c2VyIG11c3QgYWx3YXlzIGRvIHRoYXQgYnktaGFuZFxuICAgIGZ1bmN0aW9uIHByZXZlbnRBdXRvbWF0aWNTcG9pbGVyKHRleHQpIHtcbiAgICAgICAgdmFyIHNwb2lsZWQgPSB0ZXh0Lm1hdGNoKC9eXFxzKj5cXHMqIS9tZyk7XG4gICAgICAgIGlmIChzcG9pbGVkICYmIHNwb2lsZWQubGVuZ3RoID09IHRleHQuc3BsaXQoJ1xcbicpLmxlbmd0aCkge1xuXG4gICAgICAgICAgICAvLyBJZiBwb3NzaWJsZSwganVzdCBtb3ZlIHRoZSBsYXN0IHdvcmQgdG8gYSBuZXcgbGluZSwgc28gdGhlIGJsb2NrcXVvdGVcbiAgICAgICAgICAgIC8vIGhhcyBhdCBsZWFzdCBvbmUgbGluZSB0aGF0IGRvZXMgKm5vdCogc3RhcnQgd2l0aCBhICFcbiAgICAgICAgICAgIC8vIElmIHRoYXQgZmFpbHMsIHJlcGxhY2UgdGhlIGZpcnN0ICEgYnkgdGhlIGNvcnJlc3BvbmRpbmcgZW50aXR5LlxuICAgICAgICAgICAgdmFyIGZpeGVkID0gZmFsc2U7XG4gICAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKC8oLiopIChcXHcpLywgZnVuY3Rpb24gKHdob2xlLCBtb3N0LCBsZXR0ZXIpIHtcbiAgICAgICAgICAgICAgICBmaXhlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1vc3QgKyBcIlxcbj4gXCIgKyBsZXR0ZXI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghZml4ZWQpXG4gICAgICAgICAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXihcXHMqPlxccyopIS9tLCBcIiQxJiMzMztcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlU3BvaWxlcnModGV4dCkge1xuXG4gICAgICAgIHZhciBxdW90ZVJlZ2V4ID0gL1xcPGJsb2NrcXVvdGVcXD5bXFxuXFxzXSo/XFw8cFxcPltcXG5cXHNdKj8oIVtcXHNcXFNdKj8pXFw8XFwvcFxcPltcXG5cXHNdKj9cXDxcXC9ibG9ja3F1b3RlXFw+L2c7XG4gICAgICAgIHZhciBkb2VzbnRTdGFydFdpdGhCYW5nID0gL15cXHMqP1teXFxzIV0vbTtcbiAgICAgICAgdmFyIGxlYWRpbmdCYW5nID0gL15cXHMqPyEvZ207XG5cbiAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZShxdW90ZVJlZ2V4LFxuICAgICAgICAgICAgZnVuY3Rpb24gKHN0ciwgcDEsIG9mZnNldCwgcykge1xuICAgICAgICAgICAgICAgIGlmIChkb2VzbnRTdGFydFdpdGhCYW5nLnRlc3QocDEpKSByZXR1cm4gc3RyO1xuXG4gICAgICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocDEsIHAxLnJlcGxhY2UobGVhZGluZ0JhbmcsICcnKS5yZXBsYWNlKC9bJF0vZywgJyQkJCQnKSk7XG4gICAgICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoJzxibG9ja3F1b3RlPicsICc8YmxvY2txdW90ZSBjbGFzcz1cInNwb2lsZXJcIiBkYXRhLXNwb2lsZXI9XCInICsgX3MoJ1JldmVhbCBzcG9pbGVyJykgKyAnXCI+Jyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAvLyAgICAgICAgICBTRUNUSU9OUyAgICAgICAgICAvL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgIGZ1bmN0aW9uIGdldFNlY3Rpb25zRnJvbU1hcmtkb3duKG1hcmtkb3duKSB7XG4gICAgICAgIHZhciBiZWZvcmVTZWN0aW9ucyA9ICcnOyAvLyBvdXRcbiAgICAgICAgdmFyIHRpdGxlcyA9IFtdOyAgICAgICAgIC8vIG91dFxuICAgICAgICB2YXIgc2VjdGlvblRhZ3MgPSBbXTsgICAgLy8gb3V0XG5cbiAgICAgICAgdmFyIG1hdGNoZXNSYXcgPSBtYXJrZG93bi5tYXRjaCgvXlxcW3NlY3Rpb246W15cXF1dKz9cXF1cXHMqPyQvaWdtKTtcblxuICAgICAgICB2YXIgbWF0Y2hlcyA9IFtdO1xuXG4gICAgICAgIHZhciBjdXIgPSAwO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWF0Y2hlc1Jhdy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIG1hdGNoID0gbWF0Y2hlc1Jhd1tpXTtcbiAgICAgICAgICAgIHZhciBqID0gbWF0Y2guaW5kZXhPZignOicpICsgMTtcbiAgICAgICAgICAgIHZhciBrID0gbWF0Y2guaW5kZXhPZignXScsIGopO1xuICAgICAgICAgICAgdmFyIHRpdGxlID0gbWF0Y2guc3Vic3RyKGosIGsgLSBqKTtcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUucmVwbGFjZSgvXlxccysvLCAnJykucmVwbGFjZSgvXFxzKyQvLCAnJyk7XG5cbiAgICAgICAgICAgIGlmICh0aXRsZS5sZW5ndGggPT0gMCkgY29udGludWU7XG5cbiAgICAgICAgICAgIHZhciBpbmRleCA9IG1hcmtkb3duLmluZGV4T2YobWF0Y2gsIGN1cik7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gbWF0Y2gubGVuZ3RoO1xuXG4gICAgICAgICAgICBtYXRjaGVzLnB1c2goeyBpbmRleDogaW5kZXgsIGxlbmd0aDogbGVuZ3RoLCB0aXRsZTogdGl0bGUgfSk7XG5cbiAgICAgICAgICAgIGN1ciA9IGluZGV4ICsgbGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hdGNoZXMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIGJlZm9yZVNlY3Rpb25zID0gbWFya2Rvd247XG4gICAgICAgICAgICB0aXRsZXMgPSBbXTtcbiAgICAgICAgICAgIHNlY3Rpb25UYWdzID0gW107XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHNlY3Rpb25zOiBbXSxcbiAgICAgICAgICAgICAgICBiZWZvcmVTZWN0aW9uczogYmVmb3JlU2VjdGlvbnMsXG4gICAgICAgICAgICAgICAgdGl0bGVzOiB0aXRsZXMsXG4gICAgICAgICAgICAgICAgc2VjdGlvblRhZ3M6IHNlY3Rpb25UYWdzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgYmVmb3JlU2VjdGlvbnMgPSBtYXJrZG93bi5zdWJzdHIoMCwgbWF0Y2hlc1swXS5pbmRleCk7XG5cbiAgICAgICAgdmFyIGVhY2ggPSBmdW5jdGlvbiAoYXJyLCBmKSB7XG4gICAgICAgICAgICB2YXIgcmV0ID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHJldC5wdXNoKGYoYXJyW2ldKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIGluZGljZXMgPSBlYWNoKG1hdGNoZXMsIGZ1bmN0aW9uIChtKSB7IHJldHVybiBtLmluZGV4OyB9KTtcbiAgICAgICAgdGl0bGVzID0gZWFjaChtYXRjaGVzLCBmdW5jdGlvbiAobSkgeyByZXR1cm4gbS50aXRsZTsgfSk7XG4gICAgICAgIHNlY3Rpb25UYWdzID0gZWFjaChtYXRjaGVzLCBmdW5jdGlvbiAobSkgeyByZXR1cm4geyBpdGVtMTogbS5pbmRleCwgaXRlbTI6IG0ubGVuZ3RoIH07IH0pO1xuXG4gICAgICAgIHZhciByZXQgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjdXIgPSBpbmRpY2VzW2ldO1xuICAgICAgICAgICAgdmFyIG5leHQ7XG5cbiAgICAgICAgICAgIGlmIChpICsgMSA8IGluZGljZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbmV4dCA9IGluZGljZXNbaSArIDFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dCA9IG1hcmtkb3duLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0LnB1c2gobWFya2Rvd24uc3Vic3RyKGN1ciwgbmV4dCAtIGN1cikpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTW92ZSB3aGl0ZXNwYWNlIGJlZm9yZSBzZWN0aW9uIGhlYWRlcnMgaW50byB0aGUgcHJlY2VlZGluZyBzZWN0aW9uXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgbGVhZGluZ1doaXRlU3BhY2UgPSAvXlxccys/Ly5leGVjKHJldFtpXSk7XG5cbiAgICAgICAgICAgIGlmIChsZWFkaW5nV2hpdGVTcGFjZSkge1xuICAgICAgICAgICAgICAgIGlmIChpID09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlU2VjdGlvbnMgKz0gbGVhZGluZ1doaXRlU3BhY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXRbaSAtIDFdICs9IGxlYWRpbmdXaGl0ZVNwYWNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldFtpXSA9IHJldFtpXS5zdWJzdHIobGVhZGluZ1doaXRlU3BhY2UuSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlY3Rpb25zOiByZXQsXG4gICAgICAgICAgICBiZWZvcmVTZWN0aW9uczogYmVmb3JlU2VjdGlvbnMsXG4gICAgICAgICAgICB0aXRsZXM6IHRpdGxlcyxcbiAgICAgICAgICAgIHNlY3Rpb25UYWdzOiBzZWN0aW9uVGFnc1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBzZWN0aW9uTWFya2VycyA9IFtdO1xuXG4gICAgZnVuY3Rpb24gcHJlU3R5bGVTZWN0aW9ucyh0ZXh0KSB7XG4gICAgICAgIHNlY3Rpb25NYXJrZXJzID0gW107XG5cbiAgICAgICAgdmFyIHBhcnNlZCA9IGdldFNlY3Rpb25zRnJvbU1hcmtkb3duKHRleHQpO1xuXG4gICAgICAgIHZhciBuZXdHdWlkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJycgKyAoKE1hdGgucmFuZG9tKCkgKiAxMDAwMDAwKSArICcnICsgKCtuZXcgRGF0ZSgpKSArICcnICsgKE1hdGgucmFuZG9tKCkgKiAxMDAwMDAwKSk7IH07XG5cbiAgICAgICAgdmFyIHJldCA9IFwiXCI7XG4gICAgICAgIHJldCArPSBwYXJzZWQuYmVmb3JlU2VjdGlvbnM7XG5cbiAgICAgICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXJzZWQuc2VjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBzZWN0aW9uID0gcGFyc2VkLnNlY3Rpb25zW2ldO1xuICAgICAgICAgICAgdmFyIHRpdGxlID0gcGFyc2VkLnRpdGxlc1tpXTtcbiAgICAgICAgICAgIHZhciB0YWcgPSBwYXJzZWQuc2VjdGlvblRhZ3NbaV07XG5cbiAgICAgICAgICAgIHZhciBndWlkID0gXCJcXG48cD5cIiArIG5ld0d1aWQoKSArIFwiPC9wPlxcblwiO1xuXG4gICAgICAgICAgICByZXQgKz0gZ3VpZDtcblxuICAgICAgICAgICAgb2Zmc2V0ICs9IGd1aWQubGVuZ3RoO1xuXG4gICAgICAgICAgICByZXQgKz0gc2VjdGlvbjtcblxuICAgICAgICAgICAgdGFnID0geyBpdGVtMTogdGFnLml0ZW0xICsgb2Zmc2V0LCBpdGVtMjogdGFnLml0ZW0yIH07XG5cbiAgICAgICAgICAgIHZhciBmaXJzdEhhbGYgPSByZXQuc3Vic3RyKDAsIHRhZy5pdGVtMSk7XG4gICAgICAgICAgICB2YXIgc2Vjb25kSGFsZiA9IHJldC5zdWJzdHJpbmcodGFnLml0ZW0xICsgdGFnLml0ZW0yKTtcblxuICAgICAgICAgICAgcmV0ID0gZmlyc3RIYWxmICsgc2Vjb25kSGFsZjtcblxuICAgICAgICAgICAgb2Zmc2V0IC09IHRhZy5pdGVtMjtcblxuICAgICAgICAgICAgc2VjdGlvbk1hcmtlcnMucHVzaCh7IGl0ZW0xOiBndWlkLCBpdGVtMjogdGl0bGUgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBvc3RTdHlsZVNlY3Rpb25zKHRleHQpIHtcbiAgICAgICAgaWYgKHNlY3Rpb25NYXJrZXJzLmxlbmd0aCA9PSAwKSByZXR1cm4gdGV4dDtcblxuICAgICAgICB2YXIgdHJpbSA9IGZ1bmN0aW9uICh0KSB7IHJldHVybiB0LnJlcGxhY2UoL15cXHMrLywgJycpLnJlcGxhY2UoL1xccyskLywgJycpOyB9O1xuICAgICAgICB2YXIgZW5jb2RlID0gZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQucmVwbGFjZSgnPCcsICcmbHQ7JykucmVwbGFjZSgnPicsICcmZ3Q7JykucmVwbGFjZSgnXCInLCAnJnF1b3Q7JykucmVwbGFjZShcIidcIiwgJyZhcG9zOycpOyB9O1xuXG4gICAgICAgIHZhciByZXQgPSAnJztcblxuICAgICAgICB2YXIgeCA9IDA7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VjdGlvbk1hcmtlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBzZWN0aW9uID0gc2VjdGlvbk1hcmtlcnNbaV07XG5cbiAgICAgICAgICAgIHZhciBzdGFydE9mU2VjdGlvbiA9IHRleHQuaW5kZXhPZih0cmltKHNlY3Rpb24uaXRlbTEpKTtcbiAgICAgICAgICAgIHZhciBlbmRPZlNlY3Rpb247XG5cbiAgICAgICAgICAgIGlmIChpICsgMSA8IHNlY3Rpb25NYXJrZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGVuZE9mU2VjdGlvbiA9IHRleHQuaW5kZXhPZih0cmltKHNlY3Rpb25NYXJrZXJzW2kgKyAxXS5pdGVtMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZW5kT2ZTZWN0aW9uID0gdGV4dC5sZW5ndGg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldCArPSB0ZXh0LnN1YnN0cih4LCBzdGFydE9mU2VjdGlvbiAtIHgpO1xuXG4gICAgICAgICAgICByZXQgKz0gJzxkaXYgY2xhc3M9XCJwb3N0LXNlY3Rpb25cIiBkYXRhLXBvc3Qtc2VjdGlvbi1pZD1cIicgKyBpICsgJ1wiIGRhdGEtcG9zdC1zZWN0aW9uLXRpdGxlPVwiJyArIGVuY29kZShzZWN0aW9uLml0ZW0yKSArICdcIj4nO1xuICAgICAgICAgICAgcmV0ICs9ICc8cCBjbGFzcz1cInBvc3Qtc2VjdGlvbi10aXRsZVwiPicgKyBlbmNvZGUoc2VjdGlvbi5pdGVtMikgKyAnPC9wPic7XG5cbiAgICAgICAgICAgIHJldCArPSB0ZXh0LnN1YnN0cihzdGFydE9mU2VjdGlvbiArIHNlY3Rpb24uaXRlbTEubGVuZ3RoLCBlbmRPZlNlY3Rpb24gLSAoc3RhcnRPZlNlY3Rpb24gKyBzZWN0aW9uLml0ZW0xLmxlbmd0aCkpO1xuXG5cbiAgICAgICAgICAgIHJldCArPSBcIjwvZGl2PlwiO1xuXG4gICAgICAgICAgICB4ID0gZW5kT2ZTZWN0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8gICAgICAgICBUQUcgTElOS1MgICAgICAgICAgLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvLyByZXR1cm5zIGFuIGFycmF5IG9mIG9mZnNldHMgaW4gdGhlIHN0cmluZyB3aGVyZSA8YT4gYW5kIDxjb2RlPiB0YWdzIHN0YXJ0L2VuZCAoZXZlbiBpbmRleCBtZWFucyBzdGFydCwgb2RkIGluZGV4IG1lYW5zIGVuZClcbiAgICAvLyBOb3RlIHRoYXQgdGhpcyBpc24ndCAxMDAlIGlkZW50aWNhbCB0byB0aGUgc2VydmVyc2lkZSB2ZXJzaW9uIChpdCBiZWhhdmVzIGRpZmZlcmVudGx5IHdoZW4gPGE+IGFuZCA8Y29kZT4gYXJlIGluY29ycmVjdGx5IG5lc3RlZClcbiAgICBmdW5jdGlvbiBnZXRFeGNsdWRlUmFuZ2VzKHRleHQpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICB2YXIgc3RhcnRSZSA9IC88KGF8Y29kZSlbXj5dKj4vaWc7XG4gICAgICAgIHZhciBtYXRjaDtcbiAgICAgICAgd2hpbGUgKChtYXRjaCA9IHN0YXJ0UmUuZXhlYyh0ZXh0KSkgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gobWF0Y2guaW5kZXgpO1xuICAgICAgICAgICAgdmFyIGVuZFJlID0gbmV3IFJlZ0V4cChcIjwvXCIgKyBtYXRjaFsxXSArIFwiPlwiLCBcImlnXCIpOyAvLyB3ZSBuZWVkIFwiZ1wiIGV2ZW4gdGhvdWdoIHdlIG9ubHkgc2VhcmNoIG9uY2UgKGxhc3RJbmRleCBpcyBvbmx5IHNldCBpZiB0aGUgcmVnZXggaGFzIHRoZSBcImdcIiBmbGFnKVxuICAgICAgICAgICAgZW5kUmUubGFzdEluZGV4ID0gc3RhcnRSZS5sYXN0SW5kZXg7XG4gICAgICAgICAgICB2YXIgZW5kTWF0Y2ggPSBlbmRSZS5leGVjKHRleHQpO1xuICAgICAgICAgICAgaWYgKGVuZE1hdGNoID09IG51bGwpIC8vIHRoZSB0YWcgaXMgbmV2ZXIgY2xvc2VkLCBpLmUuIGV4dGVuZHMgdG8gdGhlIGVuZCBvZiB0ZXh0LiBXZSdyZSBkb25lLlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goZW5kUmUubGFzdEluZGV4KTtcbiAgICAgICAgICAgIHN0YXJ0UmUubGFzdEluZGV4ID0gZW5kUmUubGFzdEluZGV4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG5cbiAgICAvLyByZXBsYWNlIFt0YWc6Li4uXSB3aXRoIGNvcnJlc3BvbmRpbmcgbGlua3NcbiAgICBmdW5jdGlvbiBtYWtlVGFnTGlua3ModGV4dCkge1xuICAgICAgICBpZiAoIXdpbmRvdy50YWdSZW5kZXJlclJhdykgLy8gd2UgaGF2ZSBub2JvZHkgdG8gZG8gdGhlIHJlbmRlcmluZyBmb3IgdXNcbiAgICAgICAgICAgIHJldHVybiB0ZXh0O1xuXG4gICAgICAgIC8vIGRlZmVyIHNlYXJjaGluZyBmb3IgPGE+IGFuZCA8Y29kZT4gYmxvY2tzIHRvIHdpdGhpbiB0aGUgcmVwbGFjZW1lbnQgZnVuY3Rpb24sXG4gICAgICAgIC8vIHNvIGluICh0aGUgdXN1YWwpIGNhc2Ugd2hlbiB0aGVyZSBhcmUgbm8gW3RhZzouLi5dIGxpbmtzIChhbmQgdGhlIHJlcGxhY2VtZW50IGZ1bmN0aW9uXG4gICAgICAgIC8vIHRodXMgbmV2ZXIgZ2V0cyBjYWxsZWQpLCB0aGlzIHdvcmsgZG9lc24ndCBoYXZlIHRvIGJlIGRvbmVcbiAgICAgICAgdmFyIGV4Y2x1ZGVSYW5nZXMsIGV4Y2x1ZGVSYW5nZXNMZW47XG5cbiAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA3MzQxMi9qYXZhc2NyaXB0LXZhbGlkYXRpb24taXNzdWUtd2l0aC1pbnRlcm5hdGlvbmFsLWNoYXJhY3RlcnNcbiAgICAgICAgLy8gZ29vZCBsdWNrIHdpdGggdGhhdCB3aGVuIHdlIHdhbnQgdG8gc3VwcG9ydCBKYXBhbmVzZSFcbiAgICAgICAgdmFyIHRhZ0xpbmtSZWdleCA9IFN0YWNrRXhjaGFuZ2Uuc2V0dGluZ3MudGFncy5hbGxvd05vbkFzY2lpVGFnc1xuICAgICAgICAgICAgPyAvXFxbKG1ldGEtKT90YWc6KFthLXowLTlcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUYjKy4tXSspXFxdL2dpXG4gICAgICAgICAgICA6IC9cXFsobWV0YS0pP3RhZzooW2EtejAtOSMrLi1dKylcXF0vZ2k7XG5cbiAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSh0YWdMaW5rUmVnZXgsIGZ1bmN0aW9uICh3aG9sZU1hdGNoLCBpc01ldGEsIHRhZ05hbWUsIG9mZnNldCkge1xuICAgICAgICAgICAgaWYgKCF3ZUFyZU9uTWV0YSAmJiBpc01ldGEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHdob2xlTWF0Y2g7XG5cbiAgICAgICAgICAgIGlmICghZXhjbHVkZVJhbmdlcykge1xuICAgICAgICAgICAgICAgIGV4Y2x1ZGVSYW5nZXMgPSBnZXRFeGNsdWRlUmFuZ2VzKHRleHQpO1xuICAgICAgICAgICAgICAgIGV4Y2x1ZGVSYW5nZXNMZW4gPSBleGNsdWRlUmFuZ2VzLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQXJlIHdlIHdpdGhpbiBhIDxhPiBvciA8Y29kZT4gYmxvY2s/IEluIHRoYXQgY2FzZSwgZG9uJ3QgcmVuZGVyLlxuICAgICAgICAgICAgdmFyIHNraXAgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXhjbHVkZVJhbmdlc0xlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVSYW5nZXNbaV0gPiBvZmZzZXQpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIHNraXAgPSAhc2tpcDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNraXApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHdob2xlTWF0Y2g7XG5cbiAgICAgICAgICAgIHZhciBsaW5rX3Jvb3QgPSBudWxsO1xuICAgICAgICAgICAgaWYgKFN0YWNrRXhjaGFuZ2Uub3B0aW9ucy5zaXRlLnBhcmVudFVybCAmJiAhaXNNZXRhKSAvLyBvbmx5IGNoaWxkIG1ldGFzIGhhdmUgLnBhcmVudFVybFxuICAgICAgICAgICAgICAgIGxpbmtfcm9vdCA9IFN0YWNrRXhjaGFuZ2Uub3B0aW9ucy5zaXRlLnBhcmVudFVybDtcblxuICAgICAgICAgICAgaWYgKFN0YWNrRXhjaGFuZ2Uub3B0aW9ucy5zaXRlLnJvdXRlUHJlZml4ICYmICFsaW5rX3Jvb3QpIHtcbiAgICAgICAgICAgICAgICAvLyB3ZSdyZSBpbiBhIGNoYW5uZWwsIHNvIG1ha2UgYW55IHRhZ3MgcG9pbnQgdG8gdGhlIGlubmVyIHRhZ1xuICAgICAgICAgICAgICAgIGxpbmtfcm9vdCA9IFN0YWNrRXhjaGFuZ2Uub3B0aW9ucy5zaXRlLnJvdXRlUHJlZml4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc2FuZSA9IFN0YWNrRXhjaGFuZ2UuaGVscGVycy5zYW5pdGl6ZUFuZFNwbGl0VGFncyh0YWdOYW1lKTtcbiAgICAgICAgICAgIGlmIChzYW5lLmxlbmd0aCAhPT0gMSlcbiAgICAgICAgICAgICAgICByZXR1cm4gd2hvbGVNYXRjaDtcbiAgICAgICAgICAgIHJldHVybiB0YWdSZW5kZXJlclJhdyhzYW5lWzBdLCBsaW5rX3Jvb3QpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8gICBTQU5JVElaRSBBTkQgSElHSExJR0hUICAgLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgdmFyIGhhc1N5bnRheEhpZ2hsaWdodDtcblxuICAgIC8vIFRPRE86IE1vdmUgdGhlIHN5bnRheCBoaWdobGlnaHRpbmcgb2Ygc2FuaXRpemVIdG1sLCBiZWNhdXNlIHRoYXQncyAuLi4gc2FuZXJcbiAgICBmdW5jdGlvbiBzYW5pdGl6ZUFuZEhpZ2hsaWdodChodG1sLCBlbmFibGVUYWJsZXNPdmVycmlkZSkge1xuICAgICAgICB2YXIgc2VudGluZWwsIGdsb2JhbFNlbnRpbmVsLFxuICAgICAgICAgICAgc2FuaXRpemVkLFxuICAgICAgICAgICAgcmV0O1xuXG4gICAgICAgIGlmICh0eXBlb2YgZW5hYmxlVGFibGVzT3ZlcnJpZGUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGVuYWJsZVRhYmxlcyA9IGVuYWJsZVRhYmxlc092ZXJyaWRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBoYXNTeW50YXhIaWdobGlnaHQgPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgaGFzU3ludGF4SGlnaGxpZ2h0ID0gU3RhY2tFeGNoYW5nZS5zZXR0aW5ncy5zaXRlLnN0eWxlQ29kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzU3ludGF4SGlnaGxpZ2h0KSB7XG4gICAgICAgICAgICBzZW50aW5lbCA9IGdldFNlbnRpbmVsKGh0bWwpO1xuICAgICAgICAgICAgZ2xvYmFsU2VudGluZWwgPSBnZXRTZW50aW5lbChzZW50aW5lbCArIGh0bWwpO1xuICAgICAgICAgICAgaHRtbCA9IHN5bnRheEhpZ2hsaWdodE92ZXJyaWRlUHJlcGFyZShodG1sLCBzZW50aW5lbCwgZ2xvYmFsU2VudGluZWwpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzYW5pdGl6ZWQgPSBzYW5pdGl6ZUh0bWwoaHRtbCk7XG4gICAgICAgIGlmIChoYXNTeW50YXhIaWdobGlnaHQpIHtcbiAgICAgICAgICAgIHNhbml0aXplZCA9IHN5bnRheEhpZ2hsaWdodE92ZXJyaWRlRmluaXNoKHNhbml0aXplZCwgc2VudGluZWwsIGdsb2JhbFNlbnRpbmVsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2FuaXRpemVkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNhbml0aXplSHRtbChodG1sKSB7XG4gICAgICAgIHJldHVybiBodG1sLnJlcGxhY2UoLzxbXj5dKj4/L2dpLCBzYW5pdGl6ZVRhZyk7XG4gICAgfVxuICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3Iuc2FuaXRpemVIdG1sID0gc2FuaXRpemVIdG1sO1xuXG4gICAgLy8gKHRhZ3MgdGhhdCBjYW4gYmUgb3BlbmVkL2Nsb3NlZCkgfCAodGFncyB0aGF0IHN0YW5kIGFsb25lKVxuICAgIHZhciBiYXNpY190YWdfd2hpdGVsaXN0ID0gL14oPFxcLz8oYnxibG9ja3F1b3RlfGNvZGV8ZGVsfGRkfGRsfGR0fGVtfGgxfGgyfGgzfGg0fGg1fGg2fGl8a2JkfGxpfG9sKD86IHN0YXJ0PVwiXFxkK1wiKT98cHxwcmV8c3xzdXB8c3VifHN0cm9uZ3xzdHJpa2V8dWwpPnw8KGJyfGhyKVxccz9cXC8/PikkL2k7XG4gICAgLy8gPGEgaHJlZj1cInVybC4uLlwiIG9wdGlvbmFsIHRpdGxlPnw8L2E+XG4gICAgLy8gPGEgY2xhc3M9XCJzLWxpbmtcIiBocmVmPVwidXJsLi4uXCIgb3B0aW9uYWwgdGl0bGU+fDwvYT5cbiAgICB2YXIgYV93aGl0ZSA9IC9eKDxhXFxzKGNsYXNzPVwicy1saW5rXCJcXHMpP2hyZWY9XCIoKGh0dHBzP3xmdHApOlxcL1xcL3xcXC8pWy1BLVphLXowLTkrJkAjXFwvJT89fl98ITosLjtcXChcXCkqW1xcXSRdK1wiKFxcc3RpdGxlPVwiW15cIjw+XStcIik/XFxzPz58PFxcL2E+KSQvaTtcblxuICAgIC8vIDxpbWcgc3JjPVwidXJsLi4uXCIgb3B0aW9uYWwgd2lkdGggIG9wdGlvbmFsIGhlaWdodCAgb3B0aW9uYWwgYWx0ICBvcHRpb25hbCB0aXRsZVxuICAgIHZhciBpbWdfd2hpdGUgPSAvXig8aW1nXFxzc3JjPVwiKGh0dHBzPzpcXC9cXC98XFwvKVstQS1aYS16MC05KyZAI1xcLyU/PX5ffCE6LC47XFwoXFwpKltcXF0kXStcIihcXHN3aWR0aD1cIlxcZHsxLDN9XCIpPyhcXHNoZWlnaHQ9XCJcXGR7MSwzfVwiKT8oXFxzYWx0PVwiW15cIjw+XSpcIik/KFxcc3RpdGxlPVwiW15cIjw+XSpcIik/XFxzP1xcLz8+KSQvaTtcblxuICAgIC8vIG1haWx0byBsaW5rcyByZXF1aXJlIE1hcmtkb3duU2V0dGluZ3MuTGlua0VtYWlscyB0byBiZSB0cnVlXG4gICAgdmFyIGFfbWFpbHRvID0gL14oPGFcXHNocmVmPVwibWFpbHRvOlstLlxcd10rXFxAWy1hLXowLTldKyhcXC5bLWEtejAtOV0rKSpcXC5bYS16XStcIj4kKS9pO1xuXG4gICAgLy8gdGFibGUgdGFncyAodGFibGUsIHRoZWFkLCB0Ym9keSwgdHIsIHRkLCB0aCkgYXMgd2VsbCBhcyBvdXIgdGFibGUgd3JhcHBpbmcgZGl2ICg8ZGl2IGNsYXNzPVwicy10YWJsZVwiPilcbiAgICB2YXIgdGFibGVfdGFnc19hbGxvd2xpc3QgPSAvXig/Ojx0YWJsZVxcc2NsYXNzPVwicy10YWJsZVwiPnw8XFwvdGFibGU+fDxcXC8/KHQoaGVhZHxib2R5fHJ8W2RoXSg/OlsgXXN0eWxlPVsnXCJddGV4dC1hbGlnbjpbIF0/KGNlbnRlcnxsZWZ0fHJpZ2h0KTs/WydcIl0pPykpPnw8XFwvZGl2Pnw8ZGl2XFxzY2xhc3M9XCJzLXRhYmxlLWNvbnRhaW5lclwiPikkL2k7XG5cbiAgICBmdW5jdGlvbiBzYW5pdGl6ZVRhZyh0YWcpIHtcbiAgICAgICAgaWYgKHRhZy5tYXRjaChiYXNpY190YWdfd2hpdGVsaXN0KVxuICAgICAgICAgICAgfHwgdGFnLm1hdGNoKGFfd2hpdGUpXG4gICAgICAgICAgICB8fCB0YWcubWF0Y2goaW1nX3doaXRlKVxuICAgICAgICAgICAgfHwgKFN0YWNrRXhjaGFuZ2Uuc2V0dGluZ3MubWFya2Rvd24ubGlua0VtYWlscyA9PT0gdHJ1ZSAmJiB0YWcubWF0Y2goYV9tYWlsdG8pKVxuICAgICAgICAgICAgfHwgKGVuYWJsZVRhYmxlcyA9PT0gdHJ1ZSAmJiB0YWcubWF0Y2godGFibGVfdGFnc19hbGxvd2xpc3QpKSlcbiAgICAgICAgICAgIHJldHVybiB0YWc7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGFueUNoYW5nZSA9IGZhbHNlO1xuICAgICAgICAgICAgLy8gaWYgaXQgbG9va3MgbGlrZSBpdCAqbWlnaHQqIGJlIHZhbGlkLCB0aGVuIHRyeSBwZXJjZW50LWVuY29kaW5nIGlsbGVnYWwgY2hhcmFjdGVycyBpbiB0aGUgc3JjIG9yIGhyZWYgYXR0cmlidXRlXG4gICAgICAgICAgICAvLyBhbmQgdGhlbiB0cnkgdGhlIHdoaXRlbGlzdCBhZ2FpbiAtLSBpZiB0aGF0IGZpeGVzIGl0LCB0aGVuIHJlcGxhY2UgdGhlIGZvdW5kIHRhZyB3aXRoIHRoZSBmaXhlZCBvbmUuXG4gICAgICAgICAgICB2YXIgZW5jb2RlZCA9IHRhZy5yZXBsYWNlKC9eKDxhIGhyZWY9XCJ8PGltZyBzcmM9XCIpKFteXCJdKikvaSwgZnVuY3Rpb24gKHdob2xlbWF0Y2gsIHByZWZpeCwgdXJsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByZWZpeCArIHVybC5yZXBsYWNlKC9bXi1BLVphLXowLTkrJkAjXFwvJT89fl98ITosLjtcXChcXCkqW1xcXSRdL2csIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgICAgICAgIGFueUNoYW5nZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjID09IFwiJ1wiKSAvLyB0aGlzIGlzIHRoZSBvbmx5IGNoYXJhY3RlciB0aGF0IGlzbid0IGluIG91ciB3aGl0ZWxpc3QgYW5kIHRoYXQgaXMgcmV0dXJuZWQgdW5jaGFuZ2VkIGJ5IGVuY29kZVVSSUNvbXBvbmVudCgpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCIlMjdcIjtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChjKTtcblxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoYW55Q2hhbmdlICYmIChlbmNvZGVkLm1hdGNoKGFfd2hpdGUpIHx8IGVuY29kZWQubWF0Y2goaW1nX3doaXRlKSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGVuY29kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuXG4gICAgLy8vIDxzdW1tYXJ5PlxuICAgIC8vLyBhdHRlbXB0IHRvIGJhbGFuY2UgSFRNTCB0YWdzIGluIHRoZSBodG1sIHN0cmluZ1xuICAgIC8vLyBieSByZW1vdmluZyBhbnkgdW5tYXRjaGVkIG9wZW5pbmcgb3IgY2xvc2luZyB0YWdzXG4gICAgLy8vIElNUE9SVEFOVDogd2UgKmFzc3VtZSogSFRNTCBoYXMgKmFscmVhZHkqIGJlZW4gXG4gICAgLy8vIHNhbml0aXplZCBhbmQgaXMgc2FmZS9zYW5lIGJlZm9yZSBiYWxhbmNpbmchXG4gICAgLy8vIFxuICAgIC8vLyBhZGFwdGVkIGZyb20gQ09ERVNOSVBQRVQ6IEE4NTkxREJBLUQxRDMtMTFERS05NDdDLUJBNTU1NkQ4OTU5M1xuICAgIC8vLyA8L3N1bW1hcnk+XG4gICAgZnVuY3Rpb24gYmFsYW5jZVRhZ3MoaHRtbCkge1xuXG4gICAgICAgIGlmIChodG1sID09IFwiXCIpXG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcblxuICAgICAgICB2YXIgcmUgPSAvPFxcLz9cXHcrW14+XSooXFxzfCR8PikvZztcbiAgICAgICAgLy8gY29udmVydCBldmVyeXRoaW5nIHRvIGxvd2VyIGNhc2U7IHRoaXMgbWFrZXNcbiAgICAgICAgLy8gb3VyIGNhc2UgaW5zZW5zaXRpdmUgY29tcGFyaXNvbnMgZWFzaWVyXG4gICAgICAgIHZhciB0YWdzID0gaHRtbC50b0xvd2VyQ2FzZSgpLm1hdGNoKHJlKTtcblxuICAgICAgICAvLyBubyBIVE1MIHRhZ3MgcHJlc2VudD8gbm90aGluZyB0byBkbzsgZXhpdCBub3dcbiAgICAgICAgdmFyIHRhZ2NvdW50ID0gKHRhZ3MgfHwgW10pLmxlbmd0aDtcbiAgICAgICAgaWYgKHRhZ2NvdW50ID09IDApXG4gICAgICAgICAgICByZXR1cm4gaHRtbDtcblxuICAgICAgICB2YXIgdGFnbmFtZSwgdGFnO1xuICAgICAgICB2YXIgaWdub3JlZHRhZ3MgPSBcIjxwPjxpbWc+PGJyPjxsaT48aHI+XCI7XG4gICAgICAgIHZhciBtYXRjaDtcbiAgICAgICAgdmFyIHRhZ3BhaXJlZCA9IFtdO1xuICAgICAgICB2YXIgdGFncmVtb3ZlID0gW107XG4gICAgICAgIHZhciBuZWVkc1JlbW92YWwgPSBmYWxzZTtcblxuICAgICAgICAvLyBsb29wIHRocm91Z2ggbWF0Y2hlZCB0YWdzIGluIGZvcndhcmQgb3JkZXJcbiAgICAgICAgZm9yICh2YXIgY3RhZyA9IDA7IGN0YWcgPCB0YWdjb3VudDsgY3RhZysrKSB7XG4gICAgICAgICAgICB0YWduYW1lID0gdGFnc1tjdGFnXS5yZXBsYWNlKC88XFwvPyhcXHcrKS4qLywgXCIkMVwiKTtcbiAgICAgICAgICAgIC8vIHNraXAgYW55IGFscmVhZHkgcGFpcmVkIHRhZ3NcbiAgICAgICAgICAgIC8vIGFuZCBza2lwIHRhZ3MgaW4gb3VyIGlnbm9yZSBsaXN0OyBhc3N1bWUgdGhleSdyZSBzZWxmLWNsb3NlZFxuICAgICAgICAgICAgaWYgKHRhZ3BhaXJlZFtjdGFnXSB8fCBpZ25vcmVkdGFncy5zZWFyY2goXCI8XCIgKyB0YWduYW1lICsgXCI+XCIpID4gLTEpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG5cbiAgICAgICAgICAgIHRhZyA9IHRhZ3NbY3RhZ107XG4gICAgICAgICAgICBtYXRjaCA9IC0xO1xuXG4gICAgICAgICAgICBpZiAoIS9ePFxcLy8udGVzdCh0YWcpKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBhbiBvcGVuaW5nIHRhZ1xuICAgICAgICAgICAgICAgIC8vIHNlYXJjaCBmb3J3YXJkcyAobmV4dCB0YWdzKSwgbG9vayBmb3IgY2xvc2luZyB0YWdzXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbnRhZyA9IGN0YWcgKyAxOyBudGFnIDwgdGFnY291bnQ7IG50YWcrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRhZ3BhaXJlZFtudGFnXSAmJiB0YWdzW250YWddID09IFwiPC9cIiArIHRhZ25hbWUgKyBcIj5cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBudGFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYXRjaCA9PSAtMSlcbiAgICAgICAgICAgICAgICBuZWVkc1JlbW92YWwgPSB0YWdyZW1vdmVbY3RhZ10gPSB0cnVlOyAvLyBtYXJrIGZvciByZW1vdmFsXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGFncGFpcmVkW21hdGNoXSA9IHRydWU7IC8vIG1hcmsgcGFpcmVkXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW5lZWRzUmVtb3ZhbClcbiAgICAgICAgICAgIHJldHVybiBodG1sO1xuXG4gICAgICAgIC8vIGRlbGV0ZSBhbGwgb3JwaGFuZWQgdGFncyBmcm9tIHRoZSBzdHJpbmdcblxuICAgICAgICB2YXIgY3RhZyA9IDA7XG4gICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UocmUsIGZ1bmN0aW9uIChtYXRjaCkge1xuICAgICAgICAgICAgdmFyIHJlcyA9IHRhZ3JlbW92ZVtjdGFnXSA/IFwiXCIgOiBtYXRjaDtcbiAgICAgICAgICAgIGN0YWcrKztcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG5cbiAgICBTdGFja0V4Y2hhbmdlLk1hcmtkb3duRWRpdG9yLmJhbGFuY2VUYWdzID0gYmFsYW5jZVRhZ3M7XG5cbiAgICAvLyBIZXJlIGNvbWVzIHRoZSBwcmV0dHlwcmludCBvdmVycmlkZSBoYW5kbGluZzpcblxuICAgIC8vIHJldHVybnMgYSBzdHJpbmcgdGhhdCBjYW4gc2FmZWx5IGJlIHVzZWQgYXMgYSBtYXJrZXIgaW4gdGhlIGdpdmVuIHRleHQsXG4gICAgLy8gYmVjYXVzZSBpdCBkb2Vzbid0IGFwcGVhciBpbiBpdC5cbiAgICBmdW5jdGlvbiBnZXRTZW50aW5lbCh0ZXh0KSB7XG4gICAgICAgIHZhciB0aWxkZUNvdW50ID0gKHRleHQubWF0Y2goL34vZykgfHwgW10pLmxlbmd0aDtcblxuICAgICAgICAvLyBPbmUgdGlsZGUgY2hhcmFjdGVyIG1vcmUgdGhhbiB0aGUgd2hvbGUgbWFya2Rvd24gc291cmNlIGNvbnRhaW5zLFxuICAgICAgICAvLyBzbyB3ZSBkb24ndCBoYXZlIGNvbGxpc2lvbnMuXG4gICAgICAgIHJldHVybiBuZXcgQXJyYXkodGlsZGVDb3VudCArIDIpLmpvaW4oXCJ+XCIpO1xuICAgIH1cblxuICAgIHZhciBwcENsYXNzZXMgPSB7fSwgICAgIC8vIFRoZSBvbmVzIHdlIGFscmVhZHkgZmV0Y2hlZC4gS2V5cyBhcmUgdGFncywgdmFsdWVzIGFyZSB0aGUgYWN0dWFsIHByZXR0eXByaW50IGNsYXNzZXNcbiAgICAgICAgcHBSZXF1ZXN0ZWQgPSB7fSwgICAvLyBuZXZlciByZXF1ZXN0IGFueXRoaW5nIG1vcmUgdGhhbiBvbmNlXG4gICAgICAgIHBwRmV0Y2hRdWV1ZSA9IFtdO1xuXG4gICAgLy8gcmV0cmlldmUgdGhlIGNvZGVibG9jayBsYW5ndWFnZXMgZm9yIHRoZSBlbnF1ZXVlZCB0YWdzIGZyb20gdGhlIHNlcnZlcjtcbiAgICAvLyBhZnRlciBuZXcgZGF0YSBcbiAgICB2YXIgcHBGZXRjaERlbGF5ZWQgPSBTdGFja0V4Y2hhbmdlLmhlbHBlcnMuRGVsYXllZFJlYWN0aW9uKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHBwRmV0Y2hRdWV1ZS5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAkLmFqYXgoXCIvYXBpL3RhZ3MvXCIgKyBlbmNvZGVVUklDb21wb25lbnQocHBGZXRjaFF1ZXVlLmpvaW4oXCI7XCIpKSArIFwiL3N5bnRheC1oaWdobGlnaHRcIiwgeyBjYWNoZTogdHJ1ZSB9KVxuICAgICAgICAgICAgLmRvbmUoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmV3ZGF0YSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIHRhZyBpbiBkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGF0YS5oYXNPd25Qcm9wZXJ0eSh0YWcpKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIHBwQ2xhc3Nlc1tcImNfXCIgKyB0YWddID0gZGF0YVt0YWddO1xuICAgICAgICAgICAgICAgICAgICBuZXdkYXRhID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5ld2RhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5NYXJrZG93bkVkaXRvci5yZWZyZXNoQWxsUHJldmlld3MoKTtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGVDb2RlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIHBwRmV0Y2hRdWV1ZSA9IFtdO1xuICAgIH0sIDIwMDAsIHsgc2xpZGluZzogdHJ1ZSB9KTtcblxuICAgIC8vIHB1dCB0aGUgZ2l2ZW4gdGFnIGludG8gdGhlIHF1ZXVlIGFuZCByZXNldCB0aGUgdGltZXJcbiAgICBmdW5jdGlvbiBwcEVucXVldWUoaWRlbnRpZmllcikge1xuICAgICAgICB2YXIgbGVuID0gcHBGZXRjaFF1ZXVlLmxlbmd0aDtcbiAgICAgICAgaWYgKGxlbiA+IDAgJiYgaWRlbnRpZmllci5pbmRleE9mKHBwRmV0Y2hRdWV1ZVtsZW4gLSAxXSkgPT09IDApIC8vIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlIHF1ZXVlIGlzIHRoZSBzdGFydCBvZiB0aGUgbmV3IGVsZW1lbnQgLS0gSU9XLCB0aGUgdXNlciBqdXN0IGtlcHQgdHlwaW5nLiBSZXBsYWNlIGluc3RlYWQgb2YgcHVzaGluZy5cbiAgICAgICAgICAgIHBwRmV0Y2hRdWV1ZVtsZW4gLSAxXSA9IGlkZW50aWZpZXI7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHBwRmV0Y2hRdWV1ZS5wdXNoKGlkZW50aWZpZXIpO1xuICAgICAgICBwcEZldGNoRGVsYXllZC50cmlnZ2VyKCk7XG5cbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gdGhlIGNvZGVibG9jayBsYW5ndWFnZSBjbGFzcyBmb3IgdGhlIGdpdmVuIHRhZywgaWYga25vd24gKG9yIGlmIGl0J3MgYSBsYW5nLS4uLiBhbHJlYWR5LCBqdXN0IHJldHVybiBpdClcbiAgICAvLyBPdGhlcndpc2UgcmV0dXJuIG51bGwgYW5kIGVucXVldWUgdGhlIHRhZyBmb3IgcmV0cmlldmluZyB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgc2VydmVyXG4gICAgZnVuY3Rpb24gZ2V0TGFuZ3VhZ2VGcm9tQ2xhc3MoaWRlbnRpZmllcikge1xuICAgICAgICBpZiAoL15sYW5nLS8udGVzdChpZGVudGlmaWVyKSlcbiAgICAgICAgICAgIHJldHVybiBpZGVudGlmaWVyO1xuICAgICAgICB2YXIgc2FmZSA9IFwiY19cIiArIGlkZW50aWZpZXIsXG4gICAgICAgICAgICBrbm93biA9IHBwQ2xhc3Nlc1tzYWZlXTtcbiAgICAgICAgaWYgKGtub3duKVxuICAgICAgICAgICAgcmV0dXJuIGtub3duO1xuICAgICAgICBpZiAocHBSZXF1ZXN0ZWRbc2FmZV0pXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcHBSZXF1ZXN0ZWRbc2FmZV0gPSB0cnVlO1xuICAgICAgICBwcEVucXVldWUoaWRlbnRpZmllcik7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBsYW5ndWFnZUNvbW1lbnRSZSA9IC88IS0tIGxhbmd1YWdlOiAoW2EtejAtOSMrXFwtLl0rKSAtLT4oXFxzKj88cHJlPlxccyo/PGNvZGU+KS9naSxcbiAgICAgICAgZ2xvYmFsTGFuZ3VhZ2VDb21tZW50UmUgPSAvPCEtLSBsYW5ndWFnZS1hbGw6IChbYS16MC05IytcXC0uXSspIC0tPi9naTtcblxuICAgIGZ1bmN0aW9uIHN5bnRheEhpZ2hsaWdodE92ZXJyaWRlUHJlcGFyZShodG1sLCBzZW50aW5lbCwgZ2xvYmFsU2VudGluZWwpIHtcbiAgICAgICAgaHRtbCA9IGh0bWwucmVwbGFjZShsYW5ndWFnZUNvbW1lbnRSZSwgZnVuY3Rpb24gKHdob2xlTWF0Y2gsIGxhbmd1YWdlSWRlbnRpZmllciwgcHJlQ29kZSkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbnRpbmVsICsgbGFuZ3VhZ2VJZGVudGlmaWVyICsgc2VudGluZWwgKyBwcmVDb2RlO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGh0bWwucmVwbGFjZShnbG9iYWxMYW5ndWFnZUNvbW1lbnRSZSwgZnVuY3Rpb24gKHdob2xlTWF0Y2gsIGxhbmd1YWdlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgcmV0dXJuIGdsb2JhbFNlbnRpbmVsICsgbGFuZ3VhZ2VJZGVudGlmaWVyICsgZ2xvYmFsU2VudGluZWw7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN5bnRheEhpZ2hsaWdodE92ZXJyaWRlRmluaXNoKGh0bWwsIHNlbnRpbmVsLCBnbG9iYWxTZW50aW5lbCkge1xuICAgICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKHNlbnRpbmVsICsgXCIoW2EtejAtOSMrLi1dKylcIiArIHNlbnRpbmVsICsgXCIoXFxcXHMqPzxwcmUpXCIsIFwiZ2lcIik7XG4gICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UocmUsIGZ1bmN0aW9uICh3aG9sZU1hdGNoLCBsYW5ndWFnZUlkZW50aWZpZXIsIHByZSkge1xuICAgICAgICAgICAgdmFyIGxhbmcgPSBnZXRMYW5ndWFnZUZyb21DbGFzcyhsYW5ndWFnZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgaWYgKCFsYW5nKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcmU7XG4gICAgICAgICAgICByZXR1cm4gcHJlICsgXCIgY2xhc3M9J1wiICsgbGFuZyArIFwiIHByZXR0eXByaW50LW92ZXJyaWRlJ1wiO1xuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgZ2xvYmFsUmUgPSBuZXcgUmVnRXhwKFwiKFwiICsgZ2xvYmFsU2VudGluZWwgKyBcIihbYS16MC05IysuLV0rKVwiICsgZ2xvYmFsU2VudGluZWwgKyBcIil8KDxwcmU+PGNvZGU+KVwiLCBcImdpXCIpO1xuICAgICAgICB2YXIgY3VycmVudEdsb2JhbDtcbiAgICAgICAgcmV0dXJuIGh0bWwucmVwbGFjZShnbG9iYWxSZSwgZnVuY3Rpb24gKHdob2xlTWF0Y2gsIG92ZXJyaWRlLCBsYW5ndWFnZUlkZW50aWZpZXIsIHByZUNvZGUpIHtcbiAgICAgICAgICAgIGlmIChvdmVycmlkZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRHbG9iYWwgPSBsYW5ndWFnZUlkZW50aWZpZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghY3VycmVudEdsb2JhbClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdob2xlTWF0Y2g7XG4gICAgICAgICAgICAgICAgdmFyIGxhbmcgPSBnZXRMYW5ndWFnZUZyb21DbGFzcyhjdXJyZW50R2xvYmFsKTtcbiAgICAgICAgICAgICAgICBpZiAoIWxhbmcpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB3aG9sZU1hdGNoO1xuICAgICAgICAgICAgICAgIHJldHVybiBcIjxwcmUgY2xhc3M9J1wiICsgbGFuZyArIFwiIHByZXR0eXByaW50LW92ZXJyaWRlJz48Y29kZT5cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8gICAgICAgTUFSS0RPV04gSEVMUCAgICAgICAgLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICBmdW5jdGlvbiBNYXJrZG93bkhlbHAob3B0aW9ucykge1xuICAgICAgICB2YXIgaGVscERpdiwgaGVscEJ1dHRvbixcbiAgICAgICAgICAgIGxvYWRpbmcgPSBmYWxzZTtcblxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgdmFyIHBvc3RmaXggPSBvcHRpb25zLnBvc3RmaXggfHwgXCJcIjtcbiAgICAgICAgdmFyIGZvckFza1BhZ2VWMiA9ICQoJ2JvZHknKS5oYXNDbGFzcygnanMtYXNrLXBhZ2UtdjInKTtcblxuICAgICAgICB2YXIgd21kID0gJChcIiN3bWQtaW5wdXRcIiArIHBvc3RmaXgpXG5cbiAgICAgICAgZnVuY3Rpb24gYm91bmNlKGVsZW0pIHtcbiAgICAgICAgICAgIGlmIChlbGVtLmlzKFwiOmFuaW1hdGVkXCIpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGVsZW0uYW5pbWF0ZSh7IG1hcmdpblRvcDogLTE1IH0sIDQwMClcbiAgICAgICAgICAgICAgICAuYW5pbWF0ZSh7IG1hcmdpblRvcDogMCB9LCA0MDApXG4gICAgICAgICAgICAgICAgLmFuaW1hdGUoeyBtYXJnaW5Ub3A6IC04IH0sIDMwMClcbiAgICAgICAgICAgICAgICAuYW5pbWF0ZSh7IG1hcmdpblRvcDogMCB9LCAzMDApXG4gICAgICAgICAgICAgICAgLmFuaW1hdGUoeyBtYXJnaW5Ub3A6IC00IH0sIDIwMClcbiAgICAgICAgICAgICAgICAuYW5pbWF0ZSh7IG1hcmdpblRvcDogMCB9LCAyMDApXG4gICAgICAgICAgICAgICAgLmFuaW1hdGUoeyBtYXJnaW5Ub3A6IC0yIH0sIDEwMClcbiAgICAgICAgICAgICAgICAuYW5pbWF0ZSh7IG1hcmdpblRvcDogMCB9LCAxMDApXG4gICAgICAgICAgICAgICAgLmFuaW1hdGUoeyBtYXJnaW5Ub3A6IC0xIH0sIDUwKVxuICAgICAgICAgICAgICAgIC5hbmltYXRlKHsgbWFyZ2luVG9wOiAwIH0sIDUwKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBsb2FkKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpZiAoaGVscERpdikgeyAvLyBhbHJlYWR5IGxvYWRlZFxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobG9hZGluZylcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBsb2FkaW5nID0gdHJ1ZTtcblxuICAgICAgICAgICAgdmFyIHdtZE9mZnNldCA9IHdtZC5vZmZzZXQoKTtcblxuICAgICAgICAgICAgaGVscEJ1dHRvbiA9ICQoXCIjd21kLWhlbHAtYnV0dG9uXCIgKyBwb3N0Zml4KTtcblxuICAgICAgICAgICAgdmFyIHJpZ2h0QnV0dG9uRWRnZSA9IGhlbHBCdXR0b24ub2Zmc2V0KCkubGVmdCArIGhlbHBCdXR0b24ub3V0ZXJXaWR0aCgpLFxuICAgICAgICAgICAgICAgIGxlZnRFZGdlID0gd21kT2Zmc2V0LmxlZnQsXG4gICAgICAgICAgICAgICAgcmlnaHRXbWRFZGdlID0gd21kLm91dGVyV2lkdGgoKSArIGxlZnRFZGdlLFxuICAgICAgICAgICAgICAgIHJpZ2h0RWRnZSA9IE1hdGgubWF4KHJpZ2h0QnV0dG9uRWRnZSwgcmlnaHRXbWRFZGdlKTtcblxuICAgICAgICAgICAgdXBkYXRlSGVscEJ1dHRvbih0cnVlKTtcbiAgICAgICAgICAgIHZhciBvZmZXaGl0ZUJhY2tncm91bmQgPSBmb3JBc2tQYWdlVjIgPyBcIiBiZy1ibGFjay0xMDAgXCIgOiBcIlwiO1xuXG4gICAgICAgICAgICBoZWxwRGl2ID0gJCgnPGRpdiBpZD1cIm1kaGVscCcgKyBwb3N0Zml4ICsgJ1wiIGNsYXNzPVwibWRoZWxwXCI+PHVsIGlkPVwibWRoZWxwLXRhYnMnICsgcG9zdGZpeCArICdcIiBjbGFzcz1cIm1kaGVscC10YWJzJyArIG9mZldoaXRlQmFja2dyb3VuZCArICdcIj48bGkgLz48L3VsPjwvZGl2PicpLmZpbmQoXCJsaVwiKS5hZGRTcGlubmVyKCkuZW5kKClcbiAgICAgICAgICAgICAgICAuaGlkZSgpLmluc2VydEFmdGVyKGhlbHBCdXR0b24ucGFyZW50KCkucGFyZW50KCkpLnNsaWRlRG93bihcImZhc3RcIik7XG5cbiAgICAgICAgICAgICQuZ2V0KFwiL3Bvc3RzL21hcmtkb3duLWhlbHBcIiwgeyBwb3N0Zml4OiBwb3N0Zml4LCB1c2VWMjogZm9yQXNrUGFnZVYyIH0pLmRvbmUoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICBoZWxwRGl2LnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIGhlbHBEaXYgPSAkKGRhdGEpLmluc2VydEFmdGVyKGhlbHBCdXR0b24ucGFyZW50KCkucGFyZW50KCkpLyouY3NzKGNzcykqLztcbiAgICAgICAgICAgICAgICAkKFwiI21kaGVscC10YWJzXCIgKyBwb3N0Zml4KS5vbihcImNsaWNrXCIsIFwibGk6bm90KDpsYXN0LWNoaWxkKVwiLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoaWRlT25seSA9ICQodGhpcykuaGFzQ2xhc3MoXCJzZWxlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgaGVscERpdi5maW5kKFwiLm1kaGVscC10YWJcIikuc2xpZGVVcChcImZhc3RcIik7XG4gICAgICAgICAgICAgICAgICAgICQoXCIjbWRoZWxwLXRhYnNcIiArIHBvc3RmaXggKyBcIiBsaVwiKS5yZW1vdmVDbGFzcyhcInNlbGVjdGVkIGZ3LWJvbGRcIik7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaGlkZU9ubHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICQoXCIjXCIgKyAkKHRoaXMpLmF0dHIoXCJkYXRhLXRhYlwiKSkuc2xpZGVEb3duKFwiZmFzdFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuYWRkQ2xhc3MoXCJzZWxlY3RlZCBmdy1ib2xkXCIgKyBvZmZXaGl0ZUJhY2tncm91bmQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSAkKHRoaXMpLmF0dHIoXCJkYXRhLWJ1dHRvbnNcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnV0dG9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzcGxpdHRlZCA9IGJ1dHRvbnMuc3BsaXQoXCIsXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3BsaXR0ZWQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5jZSgkKFwiI3dtZC1cIiArIHNwbGl0dGVkW2ldICsgXCItYnV0dG9uXCIgKyBwb3N0Zml4KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuZ3BzLmJpbmRUcmFja0NsaWNrcyhoZWxwRGl2KTtcbiAgICAgICAgICAgICAgICBsb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBldmVyU2hvd24gPSBmYWxzZTtcbiAgICAgICAgZnVuY3Rpb24gc2hvdygpIHtcbiAgICAgICAgICAgIGV2ZXJTaG93biA9IHRydWU7XG4gICAgICAgICAgICBsb2FkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVIZWxwQnV0dG9uKHRydWUpO1xuICAgICAgICAgICAgICAgIGhlbHBEaXYuc2xpZGVEb3duKFwiZmFzdFwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHNob3dPbmNlKCkge1xuICAgICAgICAgICAgaWYgKCFldmVyU2hvd24pXG4gICAgICAgICAgICAgICAgc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGhpZGUocHJvZ3JhbW1hdGljYWxseSkge1xuICAgICAgICAgICAgaGVscERpdi5zbGlkZVVwKFwiZmFzdFwiKTtcbiAgICAgICAgICAgIHVwZGF0ZUhlbHBCdXR0b24oZmFsc2UpO1xuICAgICAgICAgICAgaWYgKHByb2dyYW1tYXRpY2FsbHkgfHwgU3RhY2tFeGNoYW5nZS5vcHRpb25zLnVzZXIuaXNBbm9ueW1vdXMpIHJldHVybjtcbiAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaGVscGVycy50b2dnbGVVc2VyRmxhZ3MoU3RhY2tPdmVyZmxvdy5Nb2RlbHMuVXNlckZsYWdzLkRpc21pc3NNYXJrZG93bkVkaXRvckhlbHAsIHRydWUpO1xuXG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdG9nZ2xlKCkge1xuICAgICAgICAgICAgaWYgKGhlbHBEaXYgJiYgaGVscERpdi5pcyhcIjp2aXNpYmxlXCIpKVxuICAgICAgICAgICAgICAgIGhpZGUoKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBzaG93KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRvZ2dsZSA9IHRvZ2dsZTtcbiAgICAgICAgdGhpcy5zaG93T25jZSA9IHNob3dPbmNlO1xuICAgICAgICB0aGlzLmhpZGUgPSBmdW5jdGlvbiAoKSB7IGlmIChoZWxwRGl2ICYmIGhlbHBEaXYuaXMoXCI6dmlzaWJsZVwiKSkgaGlkZSh0cnVlKTsgfTtcblxuICAgICAgICBmdW5jdGlvbiB1cGRhdGVIZWxwQnV0dG9uKGFjdGl2ZSkge1xuICAgICAgICAgICAgaGVscEJ1dHRvbi50b2dnbGVDbGFzcyhcImFjdGl2ZS1oZWxwXCIsIGFjdGl2ZSk7XG5cbiAgICAgICAgICAgIGlmIChmb3JBc2tQYWdlVjIpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlbHBCdXR0b24uYWRkQ2xhc3MoJ2lzLXNlbGVjdGVkJykudGV4dChfcygnSGlkZSBmb3JtYXR0aW5nIHRpcHMnKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaGVscEJ1dHRvbi5yZW1vdmVDbGFzcygnaXMtc2VsZWN0ZWQnKS50ZXh0KF9zKCdTaG93IGZvcm1hdHRpbmcgdGlwcycpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8gICAgICBRVUVTVElPTiBMSU5LUyAgICAgICAgLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvLyBSZXR1cm5zIHRoZSBmdW5jdGlvbiBnaXZlbiB0byBXTUQgYXMgYSBwb3N0LWNvbnZlcnNpb24gcGx1Z2luLCB0byB0dXJuIGEgcGxhaW4gVVJMIHRvIGEgcXVlc3Rpb25cbiAgICAvLyBvbiBhbiBlbGlnaWJsZSBzaXRlIGludG8gdGhlIHF1ZXN0aW9uJ3MgdGl0bGUsIGxpa2UgdGhlIFF1ZXN0aW9uTGluayBwb3N0IHByb2Nlc3NvciBkb2VzXG4gICAgLy8gb24gdGhlIHNlcnZlciBzaWRlLlxuICAgIC8vIElmIGEgcXVlc3Rpb24gdGl0bGUgaXMgbm90ICh5ZXQpIGtub3duLCB0aGUgaGFuZGxlciByZXR1cm5zIGltbWVkaWF0ZWx5LCBnaXZpbmcgdGhlIHVuY2hhbmdlZFxuICAgIC8vIFVSTCBhcyB0aGUgcmVzdWx0LiBUaGUgcXVlc3Rpb24gaXMgYXN5bmNocm9ub3VzbHkgY2hlY2tlZCB2aWEgdGhlIEFQSSAoaWYgdGhlIGxpbmtlZC10byBzaXRlXG4gICAgLy8gaXMgZWxpZ2libGUpLiBuZXdEYXRhQ2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgd2l0aG91dCBhcmd1bWVudHMgd2hlbiB0aGUgbGluayBwcm9jZXNzb3IgaGFzXG4gICAgLy8gcmVjZWl2ZWQgbmV3IGRhdGEgZnJvbSB0aGUgQVBJLCB0byBzaWduYWwgdGhhdCBhbm90aGVyIGNhbGwgbWlnaHQgbm93IGdpdmUgZGlmZmVyZW50IHJlc3VsdHMuXG5cbiAgICAvLyBwcmVjYWxjdWxhdGUgdGhlIGFwaSBob3N0IHVybCBvbmNlIGZvciB1c2UgaW4gdGhlIGZpbGVcbiAgICBsZXQgYXBpSG9zdCA9IFwiYXBpLnN0YWNrZXhjaGFuZ2UuY29tXCI7XG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5ob3N0LmVuZHNXaXRoKFwiLmxvY2FsXCIpKSB7XG4gICAgICAgIGFwaUhvc3QgPSBcImFwaS5zdGFja2V4Y2hhbmdlLmxvY2FsXCI7XG4gICAgfSBlbHNlIGlmICh3aW5kb3cubG9jYXRpb24uaG9zdC5zdGFydHNXaXRoKFwiZGV2LlwiKSkge1xuICAgICAgICBhcGlIb3N0ID0gXCJkZXYuYXBpLnN0YWNrZXhjaGFuZ2UuY29tXCI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0UXVlc3Rpb25MaW5rUHJvY2Vzc29yKG5ld0RhdGFDYWxsYmFjaykge1xuICAgICAgICAvLyAkMTogcmF3VXJsLCAkMjogcHJvdG9jb2wgJiBzaXRlLCAkMzogaWRcbiAgICAgICAgdmFyIHF1ZXN0aW9uUmVnZXggPSAvPGEgaHJlZj1cIigoXFxTKylcXC9xKD86dWVzdGlvbnMpP1xcLyhcXGQrKSg/OnxcXC9cXFMqPykpXCI+XFwxPFxcL2E+L2csXG4gICAgICAgICAgICB0aGlzSG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZS50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgc2l0ZU9wdGlvbnMgPSBTdGFja0V4Y2hhbmdlLm9wdGlvbnMuc2l0ZSxcbiAgICAgICAgICAgIHRoaXNQYXJlbnRIb3N0ID0gc2l0ZU9wdGlvbnMucGFyZW50VXJsICYmIFN0YWNrRXhjaGFuZ2UuaGVscGVycy5wYXJzZVVybChzaXRlT3B0aW9ucy5wYXJlbnRVcmwpLmhvc3RuYW1lLFxuICAgICAgICAgICAgdGhpc0NoaWxkSG9zdCA9IHNpdGVPcHRpb25zLmNoaWxkVXJsICYmIFN0YWNrRXhjaGFuZ2UuaGVscGVycy5wYXJzZVVybChzaXRlT3B0aW9ucy5jaGlsZFVybCkuaG9zdG5hbWU7XG5cbiAgICAgICAgdmFyIHRpdGxlcyA9IHt9OyAvLyBrZXlzL3ZhbHVlcyBhcmUgXCJzaXRlfGlkXCIgYW5kIHRoZSBxdWVzdGlvbiB0aXRsZSwgZS5nLiB0aXRsZXNbXCJzdGFja292ZXJmbG93LmNvbXwxMDAzODQxXCJdID09IFwiSG93IGRvIEkgbW92ZSB0aGUgdHVydGxlIGluIExPR08/XCJcblxuICAgICAgICBmdW5jdGlvbiBnZXRRdWVzdGlvblRpdGxlKHNpdGUsIGlkKSB7XG4gICAgICAgICAgICB2YXIgdGl0bGUgPSB0aXRsZXNbc2l0ZSArIFwifFwiICsgaWRdO1xuICAgICAgICAgICAgaWYgKHRpdGxlKVxuICAgICAgICAgICAgICAgIHJldHVybiB0aXRsZTtcblxuICAgICAgICAgICAgZ2V0UXVlc3Rpb25UaXRsZUZyb21BcGkoc2l0ZSwgaWQpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdFN0YXJ0ZWQgPSB7fTsgLy8gc2FtZSBrZXlzIGFzIGFzIGluIHRpdGxlczsgdXNlZCB0byBtYWtlIHN1cmUgd2UgZG9uJ3QgcmVxdWVzdCB0aGUgdGl0bGUgZm9yIGEgcXVlc3Rpb24gbW9yZSB0aGFuIG9uY2VcbiAgICAgICAgdmFyIGFwaVF1ZXVlID0ge307IC8vIHsgXCJzdGFja292ZXJmbG93LmNvbVwiIDogW1wiNFwiLCBcIjEwMDM4NDFcIl0gfVxuXG4gICAgICAgIHZhciBhcGlLZXkgPSBcIjZBVTc4RFopR2Nkak5qQXN6WW1UTFEoKFwiLFxuICAgICAgICAgICAgYXBpRmlsdGVyID0gXCIhNkc3UlB4V1VOVGxlVlwiOyAvLyBlcnJvcl9tZXNzYWdlLCBxdWVzdGlvbl9pZCwgdGl0bGUuIHNhZmUuXG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0UXVlc3Rpb25UaXRsZUZyb21BcGkoc2l0ZSwgaWQpIHtcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0U3RhcnRlZFtzaXRlICsgXCJ8XCIgKyBpZF0pXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgICBpZiAoaXNVbnJlZmVycmFibGVTaXRlKHNpdGUpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgICAgcmVxdWVzdFN0YXJ0ZWRbc2l0ZSArIFwifFwiICsgaWRdID0gdHJ1ZTtcblxuICAgICAgICAgICAgdmFyIHFzID0gYXBpUXVldWVbc2l0ZV07XG4gICAgICAgICAgICBpZiAoIXFzKVxuICAgICAgICAgICAgICAgIHFzID0gYXBpUXVldWVbc2l0ZV0gPSBbXTtcbiAgICAgICAgICAgIHFzLnB1c2goaWQpO1xuXG4gICAgICAgICAgICBoYW5kbGVRdWV1ZURlbGF5ZWQudHJpZ2dlcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGhhbmRsZVF1ZXVlRGVsYXllZCA9IFN0YWNrRXhjaGFuZ2UuaGVscGVycy5EZWxheWVkUmVhY3Rpb24oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGZvdW5kU29tZXRoaW5nID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKHZhciBzaXRlIGluIGFwaVF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFhcGlRdWV1ZS5oYXNPd25Qcm9wZXJ0eShzaXRlKSlcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gZ2V0Q2FsbGJhY2tGb3JTaXRlKHNpdGUpO1xuICAgICAgICAgICAgICAgIHZhciBpZHM7XG4gICAgICAgICAgICAgICAgaWYgKGFwaVF1ZXVlW3NpdGVdLmxlbmd0aCA+IDMwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlkcyA9IGFwaVF1ZXVlW3NpdGVdLnNwbGljZSgwLCAzMCkuam9pbihcIjtcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWRzID0gYXBpUXVldWVbc2l0ZV0uam9pbihcIjtcIik7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhcGlRdWV1ZVtzaXRlXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmb3VuZFNvbWV0aGluZyA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgICAgICB1cmw6IFwiaHR0cHM6Ly9cIiArIGFwaUhvc3QgKyBcIi8yLjAvcXVlc3Rpb25zL1wiICsgaWRzICsgXCI/cGFnZXNpemU9MzAma2V5PVwiICsgYXBpS2V5ICsgXCImZmlsdGVyPVwiICsgYXBpRmlsdGVyICsgXCImc2l0ZT1cIiArIHNpdGUsXG4gICAgICAgICAgICAgICAgICAgIGNyb3NzRG9tYWluOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBqc29ucENhbGxiYWNrOiBjYWxsYmFjayxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IFwianNvbnBcIlxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICBicmVhazsgLy8gb25seSBvbmUgcmVxdWVzdCBwZXIgY2FsbFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZvdW5kU29tZXRoaW5nKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlUXVldWVEZWxheWVkLnRyaWdnZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgMTAwMCwgeyBzbGlkaW5nOiB0cnVlIH0pO1xuXG4gICAgICAgIHZhciB1bnJlZmVycmFibGVTaXRlcyA9IHt9O1xuICAgICAgICB2YXIgcmVxdWVzdGVkRnJvbVN0YWNrYXV0aCA9IGZhbHNlOyAvLyBvbmx5IGNhbGwgc3RhY2thdXRoIG9uY2VcblxuICAgICAgICAvLyBPbiBNZXRhIFN0YWNrb3ZlcmZsb3csIHF1ZXN0aW9uIGxpbmtzIHRvIGFueSBzaXRlIHdpbGwgYmUgaGFuZGxlZCwgb24gYWxsIG90aGVyXG4gICAgICAgIC8vIHNpdGVzLCBvbmx5IGxpbmtzIHRvIHRoZSBzaXRlIGl0c2VsZiBhbmQgaXRzIG1ldGEuIElmIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0cnVlLFxuICAgICAgICAvLyBubyByZXF1ZXN0IHdpbGwgYmUgbWFkZSwgYXMgd2UgYWxyZWFkeSBrbm93IHRoYXQgdGhpcyBpc24ndCBnb29kLiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybnNcbiAgICAgICAgLy8gZmFsc2UsIGl0IG1heSBzdGlsbCBiZSBhIGJhZCAoaS5lLiBub24tZXhpc3RpbmcpIHNpdGUsIGJ1dCB3ZSdsbCBvbmx5IGtub3cgdGhhdCB3aGVuXG4gICAgICAgIC8vIHRoZSBhcGkgcmV0dXJucyBhbiBlcnJvci4gdW5yZWZlcnJhYmxlU2l0ZXNbLi4uXSB3aWxsIHRoZW4gYmUgc2V0IGFjY29yZGluZ2x5LCBzbyB3ZSBrbm93XG4gICAgICAgIC8vIGl0IG5leHQgdGltZS5cbiAgICAgICAgZnVuY3Rpb24gaXNVbnJlZmVycmFibGVTaXRlKGxpbmtIb3N0KSB7XG5cbiAgICAgICAgICAgIC8vIHF1ZXN0aW9uIG9uIHRoaXMgdmVyeSBzaXRlIC0tIGFsd2F5cyBva2F5XG4gICAgICAgICAgICBpZiAobGlua0hvc3QgPT09IHRoaXNIb3N0KVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgLy8gdGhlIEFQSSBoYXMgdG9sZCB1cyB0aGF0IHRoaXMgc2l0ZSBkb2Vzbid0IGV4aXN0XG4gICAgICAgICAgICBpZiAodW5yZWZlcnJhYmxlU2l0ZXNbXCJzX1wiICsgbGlua0hvc3RdKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgICAgICAvLyBjaGlsZCBtZXRhIDwtPiBwYXJlbnQgaXMgb2theVxuICAgICAgICAgICAgLy8gd2UncmUgYSBtYWluIHNpdGUgLSBhbGxvdyBsaW5raW5nIHRvIGNoaWxkIG1ldGFcbiAgICAgICAgICAgIGlmICh0aGlzQ2hpbGRIb3N0ICYmIGxpbmtIb3N0ID09PSB0aGlzQ2hpbGRIb3N0KVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgLy8gd2UncmUgYSBjaGlsZCBtZXRhIC0gYWxsb3cgbGlua2luZyB0byBwYXJlbnRcbiAgICAgICAgICAgIGlmICh0aGlzUGFyZW50SG9zdCAmJiBsaW5rSG9zdCA9PT0gdGhpc1BhcmVudEhvc3QpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBhbnkgY2hpbGQgbWV0YSBtYXkgcmVmZXIgdG8gbWV0YS5zZVxuICAgICAgICAgICAgaWYgKFN0YWNrRXhjaGFuZ2Uub3B0aW9ucy5zaXRlLmlzTWV0YVNpdGUgJiYgbGlua0hvc3QgPT09IFN0YWNrRXhjaGFuZ2Uub3B0aW9ucy5uZXR3b3JrTWV0YUhvc3RuYW1lKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgLy8gb24gbWV0YS5zZSwgYW55dGhpbmcgZ29lcyAoaWYgdGhlIHNpdGUgZXhpc3RzIGF0IGFsbDsgaWYgaXQgZG9lc24ndCwgdGhlIEFQSSB3aWxsIHRlbGwgdXMgc28sIGNhdXNpbmdcbiAgICAgICAgICAgIC8vIHVucmVmZXJyYWJsZVNpdGVzIHRvIGJlIHVwZGF0ZWQsIHNvIHdlIGRvbid0IHRyeSBhZ2FpbilcbiAgICAgICAgICAgIGlmICh0aGlzSG9zdCA9PT0gU3RhY2tFeGNoYW5nZS5vcHRpb25zLm5ldHdvcmtNZXRhSG9zdG5hbWUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBpZiB3ZSdyZSBoZXJlLCB3ZSBhcmUgbm90IG9uIG1ldGEuc28sIGFuZCB0aGUgbGlua2VkLXRvIHNpdGUgaXMgbmVpdGhlciBvdXIgY2hpbGQgbWV0YSBub3Igb3VyIHBhcmVudCBzaXRlXG4gICAgICAgICAgICAvLyB0aHVzIG5vIGxpbmsgcmVwbGFjZW1lbnQgaGFwcGVucy5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSlNPTlAgY2FsbGJhY2tzXG4gICAgICAgIHdpbmRvdy5hcGlDYWxsYmFja3MgPSB7fTtcbiAgICAgICAgZnVuY3Rpb24gZ2V0Q2FsbGJhY2tGb3JTaXRlKHNpdGUpIHtcbiAgICAgICAgICAgIHZhciBpZGVudGlmaWVyID0gc2l0ZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1xcLi9nLCBcIiRcIikucmVwbGFjZSgvLS9nLCBcIl9cIikucmVwbGFjZSgvW15fJGEtel0vLCBcIlwiKTtcbiAgICAgICAgICAgIGlmICghd2luZG93LmFwaUNhbGxiYWNrc1tpZGVudGlmaWVyXSlcbiAgICAgICAgICAgICAgICB3aW5kb3cuYXBpQ2FsbGJhY2tzW2lkZW50aWZpZXJdID0gZnVuY3Rpb24gKGRhdGEpIHsgYXBpUXVlc3Rpb25DYWxsYmFjayhkYXRhLCBzaXRlKTsgfVxuICAgICAgICAgICAgcmV0dXJuIFwiYXBpQ2FsbGJhY2tzLlwiICsgaWRlbnRpZmllcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhcGlRdWVzdGlvbkNhbGxiYWNrID0gZnVuY3Rpb24gKGRhdGEsIHNpdGUpIHtcbiAgICAgICAgICAgIGlmICghZGF0YSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgIGlmIChkYXRhLmVycm9yX21lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoL15ObyBzaXRlIGZvdW5kLy50ZXN0KGRhdGEuZXJyb3JfbWVzc2FnZSkpXG4gICAgICAgICAgICAgICAgICAgIHVucmVmZXJyYWJsZVNpdGVzW1wic19cIiArIHNpdGVdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghZGF0YS5pdGVtcylcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgIHZhciBxdWVzdGlvbnMgPSBkYXRhLml0ZW1zO1xuICAgICAgICAgICAgdmFyIGxlbiA9IHF1ZXN0aW9ucy5sZW5ndGg7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgcXVlc3Rpb24gPSBxdWVzdGlvbnNbaV07XG4gICAgICAgICAgICAgICAgdGl0bGVzW3NpdGUgKyBcInxcIiArIHF1ZXN0aW9uLnF1ZXN0aW9uX2lkXSA9IHF1ZXN0aW9uLnRpdGxlOyAvLyB3ZSdyZSB1c2luZyBhIHNhZmUgZmlsdGVyLCB0aHVzIHRydXN0aW5nIHRoZSBBUEkgdG8gaGF2ZSBlbmNvZGVkIGZvciB1c1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5ld0RhdGFDYWxsYmFjaylcbiAgICAgICAgICAgICAgICBuZXdEYXRhQ2FsbGJhY2soKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwZXJTaXRlQ291bnRzID0ge307XG4gICAgICAgIHZhciB0aHJlc2hvbGQgPSBTdGFja0V4Y2hhbmdlLm9wdGlvbnMuc2l0ZS5pc01ldGFTaXRlID8gNDAgOiAxMDsgLy8gbWF4IHBlci1zaXRlIGludGVyLXNpdGUgcXVlc3Rpb25zXG5cbiAgICAgICAgZnVuY3Rpb24gY2hlY2tDb3VudChob3N0LCBpZCkge1xuICAgICAgICAgICAgaWYgKGhvc3QgPT09IHRoaXNIb3N0KVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBubyByZXN0cmljdGlvbnMgb24gaW50cmEtc2l0ZSBsaW5rc1xuXG4gICAgICAgICAgICB2YXIgY3VycmVudCA9IHBlclNpdGVDb3VudHNbaG9zdF07XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnQpXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IHBlclNpdGVDb3VudHNbaG9zdF0gPSB7IGNvdW50OiAwLCBpZHM6IHt9IH07XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50Lmlkc1tpZF0pIC8vIGFscmVhZHkgaGFkIHRoaXMgKHNlcnZlciBzaWRlIHVzZXMgRGlzdGluY3QoKSwgc28gb25lIHF1ZXN0aW9uIGNhbiBiZSByZWZlcnJlZCBzZXZlcmFsIHRpbWVzKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY3VycmVudC5jb3VudCA+PSB0aHJlc2hvbGQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICBjdXJyZW50LmNvdW50Kys7XG4gICAgICAgICAgICBjdXJyZW50Lmlkc1tpZF0gPSB0cnVlO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoaHRtbCkge1xuICAgICAgICAgICAgcGVyU2l0ZUNvdW50cyA9IHt9O1xuXG4gICAgICAgICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKHF1ZXN0aW9uUmVnZXgsIGZ1bmN0aW9uICh3aG9sZU1hdGNoLCB1cmwsIHNpdGUsIGlkKSB7XG4gICAgICAgICAgICAgICAgc2l0ZSA9IHNpdGUudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9eaHR0cHM/OlxcL1xcLy8sIFwiXCIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKC9bXmEtejAtOS5dLy50ZXN0KHNpdGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2hvbGVNYXRjaDtcblxuICAgICAgICAgICAgICAgIGlmICghY2hlY2tDb3VudChzaXRlLCBpZCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB3aG9sZU1hdGNoO1xuXG4gICAgICAgICAgICAgICAgdmFyIHRpdGxlID0gZ2V0UXVlc3Rpb25UaXRsZShzaXRlLCBpZCk7XG4gICAgICAgICAgICAgICAgaWYgKCF0aXRsZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdob2xlTWF0Y2g7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gXCI8YSBocmVmPVxcXCJcIiArIHVybCArIFwiXFxcIj5cIiArIHRpdGxlICsgXCI8L2E+XCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9OyAvLyBFTkQgZ2V0UXVlc3Rpb25MaW5rUHJvY2Vzc29yXG5cblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAvLyAgICAgICAgSFRUUFMgSU1BR0VTICAgICAgICAvL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgIGZ1bmN0aW9uIGdldEltZ3VySHR0cHNQcm9jZXNzb3IoKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoaHRtbCkge1xuICAgICAgICAgICAgcmV0dXJuIGh0bWwucmVwbGFjZSgvPChhXFxzaHJlZnxpbWdcXHNzcmMpPVwiKGh0dHA6KT8oXFwvXFwvKFteXCJcIlxcL10rP1xcLik/aW1ndXIuY29tXFwvW15cIlwiXSs/KVwiL2dpLCAnPCQxPVwiaHR0cHM6JDNcIicpO1xuICAgICAgICB9O1xuICAgIH07IC8vIEVORCBnZXRJbWd1ckh0dHBzUHJvY2Vzc29yXG5cblxuICAgIGlmIChTdGFja0V4Y2hhbmdlLnNldHRpbmdzLnNpdGUuZm9yY2VIdHRwc0ltYWdlcykge1xuICAgICAgICAvLyB3ZSB3YW50IHRoaXMgdG8gcnVuIGFzIGxhdGUgYXMgcG9zc2libGUsIHdlIGFsc28gbmVlZCBhbiBlZGl0b3Igc2luY2UgdGhpcyBjYW4gbW9kaWZ5IHRoZSBjb250ZW50XG4gICAgICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3IuY3JlYXRpb25DYWxsYmFja3MuYWRkKGZ1bmN0aW9uIChlZGl0b3IsIHBvc3RmaXgpIHtcbiAgICAgICAgICAgIHBvc3RmaXggPSBwb3N0Zml4IHx8IFwiXCI7XG4gICAgICAgICAgICB2YXIgaG9va3MgPSBlZGl0b3IuZ2V0Q29udmVydGVyKCkuaG9va3M7XG4gICAgICAgICAgICB2YXIgalRleHRBcmVhID0gJChcIiN3bWQtaW5wdXRcIiArIHBvc3RmaXgpO1xuICAgICAgICAgICAgdmFyIGpQcmV2aWV3ID0gJChcIiN3bWQtcHJldmlld1wiICsgcG9zdGZpeCk7XG5cbiAgICAgICAgICAgIGhvb2tzLmNoYWluKFwicG9zdENvbnZlcnNpb25cIiwgZnVuY3Rpb24gKGh0bWwpIHtcbiAgICAgICAgICAgICAgICAvLyBzdHJpcCBsaW5rcyBhcm91bmQgSFRUUCBpbWFnZXMsIG9ubHkga2VlcCBpbm5lckhUTUwgKGluY2x1ZGluZyB0aGUgaW1hZ2UpXG4gICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGUgaHJlZiBVUkwgaGVyZSAoYW5kIHdoZXRoZXIgaXQgbWF0Y2hlcyB0aGUgb25lIGluIHRoZSBpbWcpLFxuICAgICAgICAgICAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCBub3QgbmVzdGluZyB0aGUgYS5qcy13bWQtdXBsb2FkLWltYWdlIGluc2lkZSBhbm90aGVyIDxhPlxuICAgICAgICAgICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBSZWdFeHAoXG4gICAgICAgICAgICAgICAgICAgICAgICAvPGFbXj5dKj8+Ly5zb3VyY2UgKyAvLyA8YSAuLi4+IHRhZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8oPyEuKj88YSkvLnNvdXJjZSArIC8vIG5vdCBmb2xsb3dlZCBieSBhbm90aGVyIDxhIChpdCBjYW4gY29udGFpbiB0ZXh0IHdpdGggb3RoZXIgbWFya2Rvd24gKGUuZy4gWyp0ZXN0KiAhW11bMV0gKiptb3JlIHRlc3QqKl1bMV0pXG4gICAgICAgICAgICAgICAgICAgICAgICAvKD89Lio/PGltZ1xcc3NyYz1cIig/Omh0dHA6KT9cXC9cXC8pLy5zb3VyY2UgKyAvLyBmb2xsb3dlZCBieSBhbiA8aW1nIHNyYz1cImh0dHA6Ly8gb3Igc3JjPVwiLy9cbiAgICAgICAgICAgICAgICAgICAgICAgIC8oLio/KTxcXC9hPi8uc291cmNlLCAvLyAkMSAtPiBpbm5lckhUTUxcbiAgICAgICAgICAgICAgICAgICAgICAgICdnaScpXG4gICAgICAgICAgICAgICAgICAgICwgJyQxJyk7XG5cbiAgICAgICAgICAgICAgICAvLyByZXBsYWNlIGltYWdlcyB3aXRoIGFjdGlvbiBidXR0b25zXG4gICAgICAgICAgICAgICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvPGltZ1xcc3NyYz1cIigoPzpodHRwOik/XFwvXFwvW15cIl0qKVwiW14+XSo/Pi9naSwgZnVuY3Rpb24gKF8sIHVybCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwibWVzc2FnZSBlcnJvciBjZW50ZXJlZC1ibG9jayB0YS1jZW50ZXJcIiA+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnQWxsIGltYWdlIFVSTHMgbXVzdCBzdGFydCB3aXRoIDxzdHJvbmc+aHR0cHM6Ly88L3N0cm9uZz4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICc8YSBocmVmPVwiamF2YXNjcmlwdDogdm9pZCgwKVwiIGRhdGEtaW1hZ2UtdXJsPVwiJyArIHVybCArICdcIiBjbGFzcz1cImpzLXdtZC11cGxvYWQtaW1hZ2VcIj5VcGxvYWQgdG8gaW1ndXI8L2E+IG9yIHNwZWNpZnkgYW4gSFRUUFMgVVJMJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9zcGFuPic7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIGpQcmV2aWV3Lm9uKCdjbGljaycsICcuanMtd21kLXVwbG9hZC1pbWFnZScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsVXJsID0gJChlLnRhcmdldCkuZGF0YSgnaW1hZ2UtdXJsJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBzaG93IHRoZSB1cGxvYWRlciBVSSwgZG9uJ3QgbWFrZXMgdXNlcnMgYXdhcmUgdGhleSdyZSBjYy1ieS1zYS1pbmcgdGhlIGltYWdlXG4gICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5pbWFnZVVwbG9hZGVyLmNyZWF0ZUltYWdlVXBsb2FkQmFja2dyb3VuZCgpO1xuICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaW1hZ2VVcGxvYWRlci51cGxvYWRJbWFnZURpYWxvZyhcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHVwbG9hZGVkVXJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXBsb2FkZWRVcmwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGl0b3IudGV4dE9wZXJhdGlvbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0galRleHRBcmVhLnZhbCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKG9yaWdpbmFsVXJsLCB1cGxvYWRlZFVybCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpUZXh0QXJlYS52YWwodGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaW1hZ2VVcGxvYWRlci5yZW1vdmVJbWFnZVVwbG9hZEJhY2tncm91bmQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGpUZXh0QXJlYS5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7IGltYWdlVXJsOiBvcmlnaW5hbFVybCB9KTtcblxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8gSU5MSU5FIExJTksgQU5EIElNQUdFIERJQUxPR1MgLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cblxuICAgIGZ1bmN0aW9uIGlubGluZUxpbmtBbmRJbWFnZURpYWxvZ3MoZWRpdG9yLCBlZGl0b3JPcHRpb25zLCBwb3N0Zml4LCBoZWxwKSB7XG5cbiAgICAgICAgdmFyIG9uQ2xvc2luZ0lubGluZURpYWxvZztcbiAgICAgICAgZnVuY3Rpb24gY2xvc2VJbmxpbmVEaWFsb2coaW1tZWRpYXRlKSB7XG4gICAgICAgICAgICBzZXRJbWFnZUZpbGUgPSBudWxsO1xuICAgICAgICAgICAgJChcIiN3bWQtYnV0dG9uLWJhclwiICsgcG9zdGZpeCArIFwiIC53bWQtYnV0dG9uX19hY3RpdmVcIikucmVtb3ZlQ2xhc3MoXCJ3bWQtYnV0dG9uX19hY3RpdmVcIik7XG4gICAgICAgICAgICBpZiAoaW1tZWRpYXRlKVxuICAgICAgICAgICAgICAgICQoXCIuanMtd21kLWlubGluZS1kaWFsb2ctXCIgKyBwb3N0Zml4KS5yZW1vdmUoKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAkKFwiLmpzLXdtZC1pbmxpbmUtZGlhbG9nLVwiICsgcG9zdGZpeCkuc2xpZGVVcCgxMDAsIGZ1bmN0aW9uICgpIHsgJCh0aGlzKS5yZW1vdmUoKTsgfSk7XG5cbiAgICAgICAgICAgICQoXCIjd21kLWlucHV0XCIgKyBwb3N0Zml4KS5wcm9wKFwiZGlzYWJsZWRcIiwgZmFsc2UpLnRyaWdnZXIoXCJmb2N1c1wiKTtcbiAgICAgICAgICAgICQoXCIjd21kLWJ1dHRvbi1iYXJcIiArIHBvc3RmaXgpLnJlbW92ZUNsYXNzKFwiaGFzLWFjdGl2ZS1idXR0b25cIik7XG4gICAgICAgICAgICBpZiAob25DbG9zaW5nSW5saW5lRGlhbG9nKSB7XG4gICAgICAgICAgICAgICAgb25DbG9zaW5nSW5saW5lRGlhbG9nKCk7XG4gICAgICAgICAgICAgICAgb25DbG9zaW5nSW5saW5lRGlhbG9nID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGVkaXRvci5ob29rcy5zZXQoXCJza2lwTW9kYWxCYWNrZ3JvdW5kXCIsIGZ1bmN0aW9uIChraW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIGZpbGVPbkxvYWQ7XG4gICAgICAgIHZhciBzZXRJbWFnZUZpbGU7XG4gICAgICAgIHZhciBzZXRJbWFnZVVybDtcblxuICAgICAgICB2YXIgZWRpdG9yRWxlbSA9ICQoXCIjcG9zdC1lZGl0b3JcIiArIHBvc3RmaXgpO1xuXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKFwicGFzdGVcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIGltYWdlIGluc2VydGVyIGlzIG9wZW5lZCwgdGhlIDxpbnB1dCB0eXBlPWZpbGU+IGdldHMgdGhlIGZvY3VzLCBhbmQgZm9yIGFjY2Vzc2liaWxpdHkgcmVhc29ucyB0aGF0IHNob3VsZFxuICAgICAgICAgICAgLy8gcmVhbGx5IGJlIHRoZSBjYXNlLiBGaXJlZm94IGlzIGhhcHB5IHRvIGZpcmUgdGhlIHBhc3RlIGV2ZW50IG9uIHRoYXQuIENocm9tZSBkb2Vzbid0LCBidXQgaXQgYXQgbGVhc3QgZmlyZXMgaXQgb24gdGhlXG4gICAgICAgICAgICAvLyBkb2N1bWVudCwgc28gd2UgY2FuIGNoZWNrIHRoYXQgdGhlICpmb2N1c2VkKiBlbGVtZW50IGlzIGluc2lkZSB0aGUgZWRpdG9yIGRpdi4gRWRnZSBkb2Vzbid0IGZpcmUgYW55dGhpbmcsIHNvIGl0IGN1cnJlbnRseVxuICAgICAgICAgICAgLy8gZG9lc24ndCB3b3JrLiBJdCdzIGJlZW4gcmVwb3J0ZWQgdG8gd29yayBpbiBTYWZhcmkuXG4gICAgICAgICAgICBpZiAoISQoZS50YXJnZXQpLmFkZChcIjpmb2N1c1wiKS5jbG9zZXN0KGVkaXRvckVsZW0pLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBmaWxlID0gZ2V0SW1hZ2VGaWxlRnJvbShlKTtcbiAgICAgICAgICAgIGlmICghZmlsZSkge1xuICAgICAgICAgICAgICAgIGlmICgkKFwiI3dtZC1pbWFnZS1idXR0b25cIiArIHBvc3RmaXggKyBcIi53bWQtYnV0dG9uX19hY3RpdmVcIikubGVuZ3RoICYmICEkKGUudGFyZ2V0KS5pcyhcImlucHV0W3R5cGU9dGV4dF0sIHRleHRhcmVhXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gZS5vcmlnaW5hbEV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YShcInRleHQvcGxhaW5cIik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbWFnZVVybChzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcGVuSW1hZ2VVcGxvYWRlcldpdGhGaWxlKGZpbGUpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKFwiI3dtZC1pbnB1dFwiICsgcG9zdGZpeCkub24oXCJkcmFnZW50ZXIgZHJhZ292ZXJcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciB2YWxpZEltYWdlID0gZHJhZ0V2ZW50Q29udGFpbnNJbWFnZShlKSAhPT0gXCJub1wiO1xuICAgICAgICAgICAgZS5vcmlnaW5hbEV2ZW50LmRhdGFUcmFuc2Zlci5kcm9wRWZmZWN0ID0gdmFsaWRJbWFnZSA/IFwiY29weVwiIDogXCJub25lXCI7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pLm9uKFwiZHJvcFwiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIGZpbGUgPSBnZXRJbWFnZUZpbGVGcm9tKGUpO1xuICAgICAgICAgICAgaWYgKGZpbGUpIHtcbiAgICAgICAgICAgICAgICBvcGVuSW1hZ2VVcGxvYWRlcldpdGhGaWxlKGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9KTtcblxuICAgICAgICBmdW5jdGlvbiBvcGVuSW1hZ2VVcGxvYWRlcldpdGhGaWxlKGZpbGUpIHtcbiAgICAgICAgICAgIGlmICgkKFwiI3dtZC1pbWFnZS1idXR0b25cIiArIHBvc3RmaXggKyBcIi53bWQtYnV0dG9uX19hY3RpdmVcIikubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgc2V0SW1hZ2VGaWxlKGZpbGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmaWxlT25Mb2FkID0gZmlsZTtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgZmlsZU9uTG9hZCA9IG51bGw7IH0sIDUwMCk7XG4gICAgICAgICAgICAgICAgJChcIiN3bWQtaW1hZ2UtYnV0dG9uXCIgKyBwb3N0Zml4KS50cmlnZ2VyKFwiY2xpY2tcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZXR1cm5zIFwieWVzXCIsIFwibWF5YmVcIiwgb3IgXCJub1wiLCBiZWNhdXNlIG5vdCBhbGwgYnJvd3NlcnMgKFNhZmFyaSEpIGxldCB5b3Uga25vdyB0aGUgbWltZSB0eXBlcyBhdCBkcmFnIHRpbWVcbiAgICAgICAgZnVuY3Rpb24gZHJhZ0V2ZW50Q29udGFpbnNJbWFnZShldmVudCkge1xuICAgICAgICAgICAgZXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xuICAgICAgICAgICAgdmFyIGl0ZW1zID0gZXZlbnQuZGF0YVRyYW5zZmVyLml0ZW1zO1xuICAgICAgICAgICAgdmFyIGFueUZpbGVJdGVtID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoaXRlbXMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgvXmltYWdlXFwvLy50ZXN0KGl0ZW1zW2ldLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ5ZXNcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbXNbaV0ua2luZCA9PT0gXCJmaWxlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFueUZpbGVJdGVtID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIElmIC5pdGVtcyB3YXMgYXZhaWxhYmxlICphbmQqIGFuIGl0ZW0gb2YgLmtpbmQgXCJmaWxlXCIsIHdhcyBvZmZlcmVkIHRvIHVzLCB0aGVuIHdlIGtub3cgdGhpcyBicm93c2VyXG4gICAgICAgICAgICAvLyBkb2VzIG9mZmVyIGZpbGVzIGluIC5pdGVtcywgYW5kIHRodXMgaWYgd2UgZGlkbid0IGZpbmQgYW4gaW1hZ2UgZmlsZSBpbiAuaXRlbXMsIHdlIGtub3cgdGhlcmUgaXNuJ3Qgb25lLlxuICAgICAgICAgICAgaWYgKGFueUZpbGVJdGVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibm9cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIElmIG5vdCwgdGhlbiBlaXRoZXIgLml0ZW1zIHdhc24ndCBhIHRoaW5nLCBvciBpdCB3YXMgYnV0IGl0IGV4Y2x1ZGVkIGZpbGVzIChib3RoIG9mIHRoZXNlIHNlZW0gcG9zc2libGVcbiAgICAgICAgICAgIC8vIGluIFNhZmFyaSksIHRoZXJlZm9yZSB3ZSBoYXZlIHRvIGNoZWNrIC50eXBlcyBvbiB3aGV0aGVyIHRoZXJlIGlzIGEgXCJGaWxlc1wiLiBJbiB0aGF0IGNhc2UsIHdlIGRvbid0IGtub3dcbiAgICAgICAgICAgIC8vIGlmIHRoZSBmaWxlIGlzIGFjdHVhbGx5IGFuIGltYWdlLCBidXQgd2Ugd29uJ3Qga25vdyB0aGF0IHVudGlsIHRoZSBkcm9wIGV2ZW50LCBzbyB3ZSdsbCBoYXZlIHRvIGFzc3VtZVxuICAgICAgICAgICAgLy8gdGhhdCAqaWYqIHRoZXJlJ3MgYSBmaWxlLCBpdCdzIGFuIGltYWdlLlxuICAgICAgICAgICAgdmFyIHR5cGVzID0gZXZlbnQuZGF0YVRyYW5zZmVyLnR5cGVzO1xuICAgICAgICAgICAgaWYgKHR5cGVzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZXNbaV0gPT09IFwiRmlsZXNcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibWF5YmVcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBcIm5vXCI7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZ2V0SW1hZ2VGaWxlRnJvbShldmVudCkge1xuICAgICAgICAgICAgdmFyIGl0ZW0gPSBnZXRJbWFnZUl0ZW1Gcm9tKGV2ZW50KTtcbiAgICAgICAgICAgIGlmICghaXRlbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0uZ2V0QXNGaWxlID8gaXRlbS5nZXRBc0ZpbGUoKSA6IGl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZ2V0SW1hZ2VJdGVtRnJvbShldmVudCkge1xuICAgICAgICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBldmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XG4gICAgICAgICAgICB2YXIgZGF0YTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImNoYW5nZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGV2ZW50LnRhcmdldC5maWxlczsgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwYXN0ZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGV2ZW50LmNsaXBib2FyZERhdGEuaXRlbXM7IGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJvcFwiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJhZ292ZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImRyYWdlbnRlclwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGV2ZW50LmRhdGFUcmFuc2Zlci5pdGVtcyB8fCBldmVudC5kYXRhVHJhbnNmZXIuZmlsZXM7IGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7IH1cbiAgICAgICAgICAgIGlmICghZGF0YSB8fCAhZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpdGVtO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKC9eaW1hZ2VcXC8vLnRlc3QoZGF0YVtpXS50eXBlKSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtID0gZGF0YVtpXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgIH1cblxuICAgICAgICBlZGl0b3IuaG9va3Muc2V0KFwiaW50ZXJjZXB0QnV0dG9uQ2xpY2tcIiwgZnVuY3Rpb24gKGJ1dHRvbiwga2luZCwgcGVyZm9ybUFjdGlvbikge1xuICAgICAgICAgICAgaWYgKGtpbmQgIT09IFwiaW1hZ2VcIiAmJiBraW5kICE9PSBcImxpbmtcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgkKGJ1dHRvbikuaGFzQ2xhc3MoXCJ3bWQtYnV0dG9uX19hY3RpdmVcIikpIHtcbiAgICAgICAgICAgICAgICBjbG9zZUlubGluZURpYWxvZygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZ1bmN0aW9uIGJlZm9yZU9wZW5pbmdJbmxpbmVEaWFsb2coYnV0dG9uKSB7XG4gICAgICAgICAgICB2YXIgYnV0dG9uQmFyID0gJChcIiN3bWQtYnV0dG9uLWJhclwiICsgcG9zdGZpeCk7XG5cbiAgICAgICAgICAgIGNsb3NlSW5saW5lRGlhbG9nKHRydWUpOyAvLyB0aGVyZSBzaG91bGRuJ3QgYmUgb25lLCBidXQgaWYgZm9yIHdoYXRldmVyIHJlYXNvbiB0aGVyZSB3YXMsIHRoaW5ncyB3b3VsZCBnZXQgd2VpcmRcbiAgICAgICAgICAgIGhlbHAuaGlkZSgpO1xuICAgICAgICAgICAgYnV0dG9uLmFkZENsYXNzKFwid21kLWJ1dHRvbl9fYWN0aXZlXCIpO1xuICAgICAgICAgICAgYnV0dG9uQmFyLmFkZENsYXNzKFwiaGFzLWFjdGl2ZS1idXR0b25cIik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBhZnRlck9wZW5pbmdJbmxpbmVEaWFsb2coZGlhbG9nKSB7XG4gICAgICAgICAgICBkaWFsb2cuZmluZChcIi5qcy1jYW5jZWwtYnV0dG9uXCIpLmNsaWNrKGZ1bmN0aW9uICgpIHsgY2xvc2VJbmxpbmVEaWFsb2coKTsgcmV0dXJuIGZhbHNlOyB9KTtcbiAgICAgICAgICAgIGRpYWxvZy5rZXlkb3duKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUud2hpY2ggPT09IEtFWV9DT0RFLkVTQykge1xuICAgICAgICAgICAgICAgICAgICBjbG9zZUlubGluZURpYWxvZygpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBlZGl0b3IuaG9va3Muc2V0KFwiaW5zZXJ0TGlua0RpYWxvZ1wiLCBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBidXR0b24gPSAkKFwiI3dtZC1saW5rLWJ1dHRvblwiICsgcG9zdGZpeCk7XG4gICAgICAgICAgICBiZWZvcmVPcGVuaW5nSW5saW5lRGlhbG9nKGJ1dHRvbik7XG5cbiAgICAgICAgICAgIHZhciBidXR0b25CYXIgPSAkKFwiI3dtZC1idXR0b24tYmFyXCIgKyBwb3N0Zml4KTtcblxuICAgICAgICAgICAgdmFyIGRpYWxvZyA9ICQoXCI8ZGl2IGNsYXNzPSd3bWQtaW5saW5lLWRpYWxvZyBqcy13bWQtaW5saW5lLWRpYWxvZy1cIiArIHBvc3RmaXggKyBcIic+PHA+PGxhYmVsIGNsYXNzPSdzLWxhYmVsJyBmb3I9J2h5cGVybGluay1pbnB1dC1cIiArIHBvc3RmaXggKyBcIic+XCIgKyBfbShcIkluc2VydCBIeXBlcmxpbmtcIikgKyBcIjwvbGFiZWw+PC9wPlwiICtcbiAgICAgICAgICAgICAgICBcIjxkaXYgY2xhc3M9J2QtZmxleCc+PGlucHV0IGNsYXNzPSdzLWlucHV0JyBpZD0naHlwZXJsaW5rLWlucHV0LVwiICsgcG9zdGZpeCArIFwiJyAvPjxidXR0b24gY2xhc3M9J3MtYnRuIHMtYnRuX19vdXRsaW5lZCB3cy1ub3dyYXAgbWwxNiBqcy1pbnNlcnQtbGluay1idXR0b24nLz5cIiArXG4gICAgICAgICAgICAgICAgJzxidXR0b24gY2xhc3M9XCJzLWJ0biBtbDQganMtY2FuY2VsLWJ1dHRvblwiPicgKyBfbShcIkNhbmNlbFwiKSArICc8L2J1dHRvbj4nICtcbiAgICAgICAgICAgICAgICBcIjwvZGl2PjwvZGl2PlwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZGlhbG9nLmZpbmQoXCIuanMtaW5zZXJ0LWxpbmstYnV0dG9uXCIpLnRleHQoX3MoXCJBZGQgbGlua1wiKSkuY2xpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBsaW5rVXJsID0gJCh0aGlzKS5wYXJlbnQoKS5maW5kKFwiaW5wdXRcIikudmFsKCk7XG4gICAgICAgICAgICAgICAgbGlua1VybCA9IGxpbmtVcmwucmVwbGFjZSgvXmh0dHBzOlxcL1xcLyhodHRwcz98ZnRwKTpcXC9cXC8vLCAnJDE6Ly8nKTtcbiAgICAgICAgICAgICAgICBpZiAoIS9eKD86aHR0cHM/fGZ0cCk6XFwvXFwvLy50ZXN0KGxpbmtVcmwpKVxuICAgICAgICAgICAgICAgICAgICBsaW5rVXJsID0gJ2h0dHBzOi8vJyArIGxpbmtVcmw7XG5cbiAgICAgICAgICAgICAgICBvbkNsb3NpbmdJbmxpbmVEaWFsb2cgPSBudWxsO1xuICAgICAgICAgICAgICAgIGNsb3NlSW5saW5lRGlhbG9nKCk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobGlua1VybCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSkuZW5kKCkuaW5zZXJ0QWZ0ZXIoYnV0dG9uQmFyKS5oaWRlKCkuc2xpZGVEb3duKDEwMCkuZmluZChcImlucHV0XCIpLnZhbChcImh0dHBzOi8vXCIpLmtleWRvd24oZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZS53aGljaCA9PT0gS0VZX0NPREUuRU5URVIpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoXCIuanMtaW5zZXJ0LWxpbmstYnV0dG9uXCIpLmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICQoXCIjd21kLWlucHV0XCIgKyBwb3N0Zml4KS5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSk7XG5cbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgZG9uZSBzeW5jaHJvbm91c2x5LCBTYWZhcmkgYW5kIEVkZ2Ugd2lsbCBub3QgY29ycmVjdGx5IGZvY3VzIHRoZSBlbGVtZW50IChpbiBTYWZhcmkgaXQnbGwgaGF2ZSBmb2N1cyBzdHlsaW5nLCBidXRcbiAgICAgICAgICAgIC8vIGl0IHdvbid0IGhhdmUgYWN0dWFsIGtleWJvYXJkIGZvY3VzOyBpbiBFZGdlIGl0IGRvZXNuJ3QgZG8gYW55dGhpbmcpLiBSZWFzb24gZm9yIHRoaXMgaXMgdW5jbGVhciAodGhlIGZhY3QgdGhhdCB0aGUgZGlhbG9nIGlzXG4gICAgICAgICAgICAvLyBpbml0aWFsbHkgaGlkZGVuIHNlZW1zIG5vdCByZWxhdGVkKS4gSSdtIGZpbGluZyBpdCB1bmRlciBcIkVkZ2UgaXMgYW4gRWRnZSBjYXNlXCIgYW5kIFwiU2FmYXJpIGlzIHRoZSBuZXcgSUVcIi5cbiAgICAgICAgICAgIC8vIEluIGFsbCBmYWlybmVzcywgaXQgYWN0dWFsbHkgd29ya3MgZmluZSBpbiBJRS5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGRpYWxvZy5maW5kKFwiaW5wdXRcIik7XG4gICAgICAgICAgICAgICAgaW5wdXQuY2FyZXQoMCwgOCk7XG4gICAgICAgICAgICAgICAgaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgIH0sIDApXG5cbiAgICAgICAgICAgIG9uQ2xvc2luZ0lubGluZURpYWxvZyA9IGZ1bmN0aW9uICgpIHsgY2FsbGJhY2sobnVsbCk7IH1cblxuICAgICAgICAgICAgYWZ0ZXJPcGVuaW5nSW5saW5lRGlhbG9nKGRpYWxvZyk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBlZGl0b3IuaG9va3Muc2V0KFwiaW5zZXJ0SW1hZ2VEaWFsb2dcIiwgZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgYnV0dG9uID0gJChcIiN3bWQtaW1hZ2UtYnV0dG9uXCIgKyBwb3N0Zml4KTtcbiAgICAgICAgICAgIGJlZm9yZU9wZW5pbmdJbmxpbmVEaWFsb2coYnV0dG9uKTtcblxuICAgICAgICAgICAgdmFyIGJ1dHRvbkJhciA9ICQoXCIjd21kLWJ1dHRvbi1iYXJcIiArIHBvc3RmaXgpO1xuXG4gICAgICAgICAgICB2YXIgZGlhbG9nID0gJChcbiAgICAgICAgICAgICAgICBcIjxkaXYgY2xhc3M9J3dtZC1pbmxpbmUtZGlhbG9nIHAwIGpzLXdtZC1pbmxpbmUtZGlhbG9nLVwiICsgcG9zdGZpeCArIFwiJz5cIiArXG4gICAgICAgICAgICAgICAgJzxpbnB1dCBjbGFzcz1cInBzLWFic29sdXRlIG8wXCIgdHlwZT1cImZpbGVcIiBuYW1lPVwiZmlsZVwiIGFjY2VwdD1cImltYWdlLypcIiBpZD1cImltYWdlLXVwbG9hZC1maWxlLWlucHV0JyArIHBvc3RmaXggKyAnXCIgLz4nICtcbiAgICAgICAgICAgICAgICBcIjxkaXYgY2xhc3M9J2QtZmxleCBmZC1jb2x1bW4ganMtc3RhY2tzLXZhbGlkYXRpb24nPlwiICtcbiAgICAgICAgICAgICAgICAoZWRpdG9yT3B0aW9ucy5pbWFnZVVwbG9hZGVyLnNob3dMb3dSZXBJbWFnZVVwbG9hZFdhcm5pbmdcbiAgICAgICAgICAgICAgICAgICAgPyBcIjxkaXYgY2xhc3M9J3Mtbm90aWNlIHMtbm90aWNlX193YXJuaW5nIG0xNiBtYjAnPlwiXG4gICAgICAgICAgICAgICAgICAgICsgX20oXCJJbWFnZXMgYXJlIHVzZWZ1bCBpbiBhIHBvc3QsIGJ1dCAqKm1ha2Ugc3VyZSB0aGUgcG9zdCBpcyBzdGlsbCBjbGVhciB3aXRob3V0IHRoZW0qKi4gIElmIHlvdSBwb3N0IGltYWdlcyBvZiBjb2RlIG9yIGVycm9yIG1lc3NhZ2VzLCBjb3B5IGFuZCBwYXN0ZSBvciB0eXBlIHRoZSBhY3R1YWwgY29kZSBvciBtZXNzYWdlIGludG8gdGhlIHBvc3QgZGlyZWN0bHkuXCIpXG4gICAgICAgICAgICAgICAgICAgICsgXCI8L2Rpdj5cIlxuICAgICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICBcIjxkaXYgY2xhc3M9J2ZsZXgtLWl0ZW0gZC1mbGV4IHBzLXJlbGF0aXZlIHAxNiBobW4xIGpzLWRyb3AtdGFyZ2V0Jz5cIiArIC8vYmEgYmF3MiBiYXMtZGFzaGVkIGJjLWJsYWNrLTMwMCBiZy1ibGFjay0xNTAgXG4gICAgICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdmbGV4LS1pdGVtIGQtZmxleCBhaS1jZW50ZXIgZmwtZ3JvdzEganMtcHNldWRvLWlucHV0Jz5cIiArXG4gICAgICAgICAgICAgICAgXCI8aW1nIGNsYXNzPSdmbGV4LS1pdGVtIGhteDEgd214MiBtcjMyIGQtbm9uZSBqcy1pbWFnZS11cGxvYWQtcHJldmlldycgYWx0PSdcIisgX3MoXCJ1cGxvYWRlZCBpbWFnZSBwcmV2aWV3XCIpICsgXCInIC8+XCIgK1xuICAgICAgICAgICAgICAgIFwiPGRpdiBjbGFzcz0nZmxleC0taXRlbSBkLWZsZXggZmwtZ3JvdzEgYWktYmFzZWxpbmUgc206ZmQtY29sdW1uIHNtOmFpLXN0cmV0Y2ggZC1ub25lIGpzLXVybC1pbnB1dC1jb250YWluZXInPlwiICtcbiAgICAgICAgICAgICAgICBcIjxsYWJlbCBjbGFzcz0ncy1sYWJlbCBtcjggc206bXIwIHNtOm1iNCcgZm9yPSdpbWFnZS11cGxvYWQtdXJsLWlucHV0XCIgKyBwb3N0Zml4ICsgXCInPlwiICtcbiAgICAgICAgICAgICAgICAoZWRpdG9yT3B0aW9ucy5pbWFnZVVwbG9hZGVyLmFsbG93VXJscyA/IF9tKFwiUGFzdGUgaW1hZ2Ugb3IgbGluazpcIikgOiBfbShcIlBhc3RlIGltYWdlOlwiKSkgK1xuICAgICAgICAgICAgICAgIFwiPC9sYWJlbD5cIiArXG4gICAgICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdmbDEgcHMtcmVsYXRpdmUnPjxpbnB1dCB0eXBlPSd0ZXh0JyBjbGFzcz0ncy1pbnB1dCcgaWQ9J2ltYWdlLXVwbG9hZC11cmwtaW5wdXRcIiArIHBvc3RmaXggKyBcIicgLz48L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8YnV0dG9uIGNsYXNzPSdzLWJ0biBzbTphcy1zdGFydCBqcy1jYW5jZWwtdXJsJz5cIiArIF9tKFwiQ2FuY2VsXCIpICsgXCI8L2J1dHRvbj5cIiArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdmbGV4LS1pdGVtIGQtZmxleCBnczggZ3N5IGZkLWNvbHVtbiBqcy1jdGEtY29udGFpbmVyJz5cIiArXG4gICAgICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdmbGV4LS1pdGVtIGZzLWJvZHkyJz5cIiArXG4gICAgICAgICAgICAgICAgKGVkaXRvck9wdGlvbnMuaW1hZ2VVcGxvYWRlci5hbGxvd1VybHNcbiAgICAgICAgICAgICAgICAgICAgP1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGVzZSB0d28gYXJlIGlkZW50aWNhbCBleGNlcHQgZm9yIFwib3IgbGlua1wiIChidXQgbW9vbnNwZWFrIHJlcXVpcmVzIGxpdGVyYWxzIGV2ZW4gZm9yIHRoZSBzZWNvbmQgYXJndW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIF9tKFwiJGJyb3dzZVN0YXJ0JEJyb3dzZSRicm93c2VFbmQkLCBkcmFnICYgZHJvcCwgb3IgJHBhc3RlU3RhcnQkcGFzdGUkcGFzdGVFbmQkIGFuIGltYWdlIG9yIGxpbmtcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJvd3NlU3RhcnQ6IFwiPGxhYmVsIGNsYXNzPSdzLWxpbmsganMtaW1hZ2UtdXBsb2FkLWxhYmVsJyBmb3I9J2ltYWdlLXVwbG9hZC1maWxlLWlucHV0XCIgKyBwb3N0Zml4ICsgXCInPlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJvd3NlRW5kOiBcIjwvbGFiZWw+XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZVN0YXJ0OiBcIjxidXR0b24gY2xhc3M9J3MtYnRuIHMtYnRuX19saW5rIGpzLXNob3ctdXJsLWlucHV0Jz5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlRW5kOiBcIjwvYnV0dG9uPlwiXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIDpcbiAgICAgICAgICAgICAgICAgICAgX20oXCIkYnJvd3NlU3RhcnQkQnJvd3NlJGJyb3dzZUVuZCQsIGRyYWcgJiBkcm9wLCBvciAkcGFzdGVTdGFydCRwYXN0ZSRwYXN0ZUVuZCQgYW4gaW1hZ2VcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJvd3NlU3RhcnQ6IFwiPGxhYmVsIGNsYXNzPSdzLWxpbmsganMtaW1hZ2UtdXBsb2FkLWxhYmVsJyBmb3I9J2ltYWdlLXVwbG9hZC1maWxlLWlucHV0XCIgKyBwb3N0Zml4ICsgXCInPlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJvd3NlRW5kOiBcIjwvbGFiZWw+XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZVN0YXJ0OiBcIjxidXR0b24gY2xhc3M9J3MtYnRuIHMtYnRuX19saW5rIGpzLXNob3ctdXJsLWlucHV0Jz5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlRW5kOiBcIjwvYnV0dG9uPlwiXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKSArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgLy8gVW5pdCBpcyBpbnRlbnRpb25hbGx5IHNldCB0byBNaUIsIG5vdCBNQi4gUGxlYXNlIGRvIG5vdCBjaGFuZ2UgdGhlIHVuaXQgYmFjayAoaHR0cHM6Ly9tZXRhLnN0YWNrZXhjaGFuZ2UuY29tL3EvMzQ2MjcyKVxuICAgICAgICAgICAgICAgIFwiPGRpdiBjbGFzcz0nZnMtY2FwdGlvbiBmYy1ibGFjay0zNTAnPlwiICsgX3MoXCJTdXBwb3J0ZWQgZmlsZSB0eXBlczoganBlZywgcG5nLCBnaWYsIG9yIGJtcCAoTWF4IHNpemUgMiBNaUIpXCIpICsgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8cCBjbGFzcz0nZmxleC0taXRlbSBweDE2IHMtaW5wdXQtbWVzc2FnZSBkLW5vbmUganMtc3RhY2tzLXZhbGlkYXRpb24tbWVzc2FnZScgLz5cIiArXG4gICAgICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdkLWZsZXggYWktY2VudGVyIHAxNiBidCBiYy1ibGFjay0zMDAnPlwiICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cImQtZmxleCBnczggZ3N4XCI+JyArXG4gICAgICAgICAgICAgICAgJzxidXR0b24gY2xhc3M9XCJmbGV4LS1pdGVtIHMtYnRuIHMtYnRuX19maWxsZWQgd3Mtbm93cmFwIGpzLWFkZC1waWN0dXJlXCIgZGlzYWJsZWQ+JyArIF9tKFwiQWRkIHBpY3R1cmVcIikgKyAnPC9idXR0b24+JyArXG4gICAgICAgICAgICAgICAgJzxidXR0b24gY2xhc3M9XCJmbGV4LS1pdGVtIHMtYnRuIHdzLW5vd3JhcCBqcy1jYW5jZWwtYnV0dG9uXCI+JyArIF9tKFwiQ2FuY2VsXCIpICsgJzwvYnV0dG9uPicgK1xuICAgICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cIm1sNjQgc206bWwwIGQtZmxleCBmZC1jb2x1bW4gZnMtY2FwdGlvbiBmYy1ibGFjay0zNTAgcy1hbmNob3JzIHMtYW5jaG9yc19fbXV0ZWRcIj4nICtcbiAgICAgICAgICAgICAgICAoZWRpdG9yT3B0aW9ucy5pbWFnZVVwbG9hZGVyLmJyYW5kaW5nSHRtbCA/ICc8c3Bhbj4nICsgZWRpdG9yT3B0aW9ucy5pbWFnZVVwbG9hZGVyLmJyYW5kaW5nSHRtbCArICc8L3NwYW4+JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgKGVkaXRvck9wdGlvbnMuaW1hZ2VVcGxvYWRlci5jb250ZW50UG9saWN5SHRtbCA/ICc8c3Bhbj4nICsgZWRpdG9yT3B0aW9ucy5pbWFnZVVwbG9hZGVyLmNvbnRlbnRQb2xpY3lIdG1sICsgJzwvc3Bhbj4nIDogJycpICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIiArXG4gICAgICAgICAgICAgICAgXCI8L2Rpdj5cIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGRpYWxvZy5pbnNlcnRBZnRlcihidXR0b25CYXIpLmhpZGUoKS5zbGlkZURvd24oMTAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN1Ym1pdEJ1dHRvbiA9IGRpYWxvZy5maW5kKFwiLmpzLWFkZC1waWN0dXJlXCIpO1xuICAgICAgICAgICAgICAgIGlmICghc3VibWl0QnV0dG9uLnByb3AoXCJkaXNhYmxlZFwiKSkge1xuICAgICAgICAgICAgICAgICAgICBzdWJtaXRCdXR0b24uZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICQoXCIjaW1hZ2UtdXBsb2FkLWZpbGUtaW5wdXRcIiArIHBvc3RmaXgpLnRyaWdnZXIoXCJmb2N1c1wiKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTsgLy8gaW4gRmlyZUZveCwgZm9jdXNpbmcgaW1tZWRpYXRlbHkgZG9lc24ndCB3b3JrIHJlbGlhYmx5IChldmVuIHRob3VnaCB0aGlzIGlzIHRoZSBhbmltYXRpb24gY2FsbGJhY2spXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLXVybC1pbnB1dC1jb250YWluZXIgaW5wdXRcIikua2V5ZG93bihmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChlLndoaWNoID09PSBLRVlfQ09ERS5FTlRFUikge1xuICAgICAgICAgICAgICAgICAgICBkaWFsb2cuZmluZChcIi5qcy1hZGQtcGljdHVyZVwiKS5jbGljaygpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHZhciB2YWxpZGF0aW9uSGFuZGxlciA9IFN0YWNrRXhjaGFuZ2Uuc3RhY2tzVmFsaWRhdGlvbi5oYW5kbGVyRm9yKGRpYWxvZy5maW5kKFwiLmpzLXBzZXVkby1pbnB1dFwiKSk7XG5cbiAgICAgICAgICAgIHZhciB1cGxvYWRJblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgICAgICAkKFwiI3dtZC1pbnB1dFwiICsgcG9zdGZpeCkucHJvcChcImRpc2FibGVkXCIsIHRydWUpO1xuICAgICAgICAgICAgdmFyIGltYWdlRmlsZTtcbiAgICAgICAgICAgIHZhciBvYmplY3RVUkw7XG4gICAgICAgICAgICB2YXIgaW1hZ2VVcmw7XG4gICAgICAgICAgICBmdW5jdGlvbiByZXZva2VFeGlzdGluZ09iamVjdFVSTCgpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0VVJMKSB7XG4gICAgICAgICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwob2JqZWN0VVJMKTtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0VVJMID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgY2hvc2VuVHlwZSA9IFwiZmlsZVwiO1xuICAgICAgICAgICAgc2V0SW1hZ2VVcmwgPSBmdW5jdGlvbiAodXJsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHVybCAmJiAhZWRpdG9yT3B0aW9ucy5pbWFnZVVwbG9hZGVyLmFsbG93VXJscykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh1cmwgJiYgIS9eaHR0cHM/OlxcL1xcLy9pLnRlc3QodXJsKSkge1xuICAgICAgICAgICAgICAgICAgICB1cmwgPSBcImh0dHBzOi8vXCIgKyB1cmw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25IYW5kbGVyLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGlvbkhhbmRsZXIgPSBTdGFja0V4Y2hhbmdlLnN0YWNrc1ZhbGlkYXRpb24uaGFuZGxlckZvcigkKFwiI2ltYWdlLXVwbG9hZC11cmwtaW5wdXRcIiArIHBvc3RmaXgpKTtcbiAgICAgICAgICAgICAgICByZXZva2VFeGlzdGluZ09iamVjdFVSTCgpO1xuICAgICAgICAgICAgICAgIGNob3NlblR5cGUgPSBcInVybFwiO1xuICAgICAgICAgICAgICAgIGltYWdlVXJsID0gdXJsO1xuICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLWltYWdlLXVwbG9hZC1wcmV2aWV3LCAuanMtY3RhLWNvbnRhaW5lclwiKS5hZGRDbGFzcyhcImQtbm9uZVwiKTtcbiAgICAgICAgICAgICAgICBkaWFsb2cuZmluZChcIi5qcy11cmwtaW5wdXQtY29udGFpbmVyXCIpLnJlbW92ZUNsYXNzKFwiZC1ub25lXCIpLmZpbmQoXCJpbnB1dFwiKS52YWwodXJsKS50cmlnZ2VyKFwiaW5wdXRcIikuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNldEltYWdlRmlsZSA9IGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICAgICAgaWYgKHVwbG9hZEluUHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YWxpZGF0aW9uSGFuZGxlci5jbGVhcigpO1xuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25IYW5kbGVyID0gU3RhY2tFeGNoYW5nZS5zdGFja3NWYWxpZGF0aW9uLmhhbmRsZXJGb3IoZGlhbG9nLmZpbmQoXCIuanMtcHNldWRvLWlucHV0XCIpKTtcbiAgICAgICAgICAgICAgICByZXZva2VFeGlzdGluZ09iamVjdFVSTCgpO1xuICAgICAgICAgICAgICAgIGNob3NlblR5cGUgPSBcImZpbGVcIjtcbiAgICAgICAgICAgICAgICBkaWFsb2cuZmluZChcIi5qcy11cmwtaW5wdXQtY29udGFpbmVyXCIpLmFkZENsYXNzKFwiZC1ub25lXCIpO1xuICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLWN0YS1jb250YWluZXJcIikucmVtb3ZlQ2xhc3MoXCJkLW5vbmVcIik7XG4gICAgICAgICAgICAgICAgaWYgKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0VVJMID0gVVJMLmNyZWF0ZU9iamVjdFVSTChmKTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoXCIuanMtaW1hZ2UtdXBsb2FkLXByZXZpZXdcIikuYXR0cihcInNyY1wiLCBvYmplY3RVUkwpLnJlbW92ZUNsYXNzKFwiZC1ub25lXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vZGlhbG9nLmZpbmQoXCIuanMtaW1hZ2UtdXBsb2FkLWxhYmVsXCIpLnJlbW92ZUNsYXNzKFwiZC1ub25lXCIpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdG9vQmlnID0gZi5zaXplID49IDB4MjAwMDAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAodG9vQmlnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVbml0IGlzIGludGVudGlvbmFsbHkgc2V0IHRvIE1pQiwgbm90IE1CLiBQbGVhc2UgZG8gbm90IGNoYW5nZSB0aGUgdW5pdCBiYWNrIChodHRwczovL21ldGEuc3RhY2tleGNoYW5nZS5jb20vcS8zNDYyNzIpXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uSGFuZGxlci5hZGQoXCJlcnJvclwiLCBfbShcIllvdXIgaW1hZ2UgaXMgdG9vIGxhcmdlIHRvIHVwbG9hZCAob3ZlciAyIE1pQikuXCIpKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLWFkZC1waWN0dXJlXCIpLnByb3AoXCJkaXNhYmxlZFwiLCB0b29CaWcpLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoXCIuanMtaW1hZ2UtdXBsb2FkLXByZXZpZXdcIikucmVtb3ZlQXR0cihcInNyY1wiKS5hZGRDbGFzcyhcImQtbm9uZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmZpbmQoXCIuanMtYWRkLXBpY3R1cmVcIikucHJvcChcImRpc2FibGVkXCIsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbWFnZUZpbGUgPSBmO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNhbmNlbGxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgb25DbG9zaW5nSW5saW5lRGlhbG9nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGNhbmNlbGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV2b2tlRXhpc3RpbmdPYmplY3RVUkwoKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmaWxlT25Mb2FkKSB7XG4gICAgICAgICAgICAgICAgc2V0SW1hZ2VGaWxlKGZpbGVPbkxvYWQpO1xuICAgICAgICAgICAgICAgIGZpbGVPbkxvYWQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyICRmaWxlSW5wdXQgPSAkKFwiI2ltYWdlLXVwbG9hZC1maWxlLWlucHV0XCIgKyBwb3N0Zml4KS5vbihcImNoYW5nZVwiLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgICAgICAgICAgc2V0SW1hZ2VGaWxlKGdldEltYWdlRmlsZUZyb20oZXZ0KSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICQoXCIjaW1hZ2UtdXBsb2FkLXVybC1pbnB1dFwiICsgcG9zdGZpeCkub24oXCJpbnB1dFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRpc2FibGVkO1xuICAgICAgICAgICAgICAgIGlmIChlZGl0b3JPcHRpb25zLmltYWdlVXBsb2FkZXIuYWxsb3dVcmxzKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkID0gISQodGhpcykudmFsKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbkhhbmRsZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCQodGhpcykudmFsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25IYW5kbGVyLmFkZChcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX20oXCJVcGxvYWRpbmcgaW1hZ2VzIHZpYSB3ZWIgbGlua3MgaXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHNpdGUuIFBhc3RlIGFuIGltYWdlIGZyb20gdGhlIGNsaXBib2FyZCBvciAkYnJvd3NlU3RhcnQkYnJvd3NlJGJyb3dzZUVuZCQgZmlsZXMgb24geW91ciBkZXZpY2UuXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBmYy0uLi4gYW5kIHRkLS4uLiBjbGFzc2VzIGNhbiBiZSByZW1vdmVkIHdoZW4gU3RhY2tzIGhhbmRsZXMgcy1saW5rIGluIHZhbGlkYXRpb24gbWVzc2FnZXMgbGlrZSBpdCBoYW5kbGVzIDxhPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJvd3NlU3RhcnQ6IFwiPGxhYmVsIGNsYXNzPSdzLWxpbmsgZmMtcmVkLTYwMCB0ZC11bmRlcmxpbmUnIGZvcj0naW1hZ2UtdXBsb2FkLWZpbGUtaW5wdXRcIiArIHBvc3RmaXggKyBcIic+XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicm93c2VFbmQ6IFwiPC9sYWJlbD5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLWFkZC1waWN0dXJlXCIpLnByb3AoXCJkaXNhYmxlZFwiLCBkaXNhYmxlZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLXNob3ctdXJsLWlucHV0XCIpLmNsaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzZXRJbWFnZVVybChcIlwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLWNhbmNlbC11cmxcIikuY2xpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltYWdlRmlsZShudWxsKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZGlhbG9nLmZpbmQoXCIuanMtZHJvcC10YXJnZXRcIikub24oXCJkcm9wXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1cGxvYWRJblByb2dyZXNzKVxuICAgICAgICAgICAgICAgICAgICBzZXRJbWFnZUZpbGUoZ2V0SW1hZ2VGaWxlRnJvbShlKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSkub24oXCJkcmFnZW50ZXIgZHJhZ292ZXJcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsaWRJbWFnZSA9IGRyYWdFdmVudENvbnRhaW5zSW1hZ2UoZSkgIT09IFwibm9cIjtcbiAgICAgICAgICAgICAgICBlLm9yaWdpbmFsRXZlbnQuZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSB2YWxpZEltYWdlICYmICF1cGxvYWRJblByb2dyZXNzID8gXCJjb3B5XCIgOiBcIm5vbmVcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpYWxvZy5maW5kKFwiLmpzLWFkZC1waWN0dXJlXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdXBsb2FkSW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGlvbkhhbmRsZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB2YXIgZGlzYWJsZWRJbnB1dHMgPSAkZmlsZUlucHV0LmFkZChcIiNpbWFnZS11cGxvYWQtdXJsLWlucHV0XCIgKyBwb3N0Zml4KS5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgdmFyIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgaWYgKGNob3NlblR5cGUgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZScsIGltYWdlRmlsZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0SW1hZ2VVcmwoJChcIiNpbWFnZS11cGxvYWQtdXJsLWlucHV0XCIgKyBwb3N0Zml4KS52YWwoKSk7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZChcInVwbG9hZFVybFwiLCBpbWFnZVVybCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciAkYnV0dG9uID0gJCh0aGlzKS5hZGRDbGFzcyhcImlzLWxvYWRpbmdcIikucHJvcChcImRpc2FibGVkXCIsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdma2V5JywgU3RhY2tFeGNoYW5nZS5vcHRpb25zLnVzZXIuZmtleSk7XG4gICAgICAgICAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgICAgICAgICAgdXJsOiAnL3VwbG9hZC9pbWFnZScsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGZvcm1EYXRhLFxuICAgICAgICAgICAgICAgICAgICBjYWNoZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0RhdGE6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUE9TVCdcbiAgICAgICAgICAgICAgICB9KS5kb25lKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbmNlbGxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuU3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxpbmtVcmwgPSByZXN1bHQuVXBsb2FkZWRJbWFnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xvc2luZ0lubGluZURpYWxvZyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXZva2VFeGlzdGluZ09iamVjdFVSTCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VJbmxpbmVEaWFsb2coKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGxpbmtVcmwpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5FcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25IYW5kbGVyLmFkZChcImVycm9yXCIsICQoXCI8c3Bhbi8+XCIpLnRleHQocmVzdWx0LkVycm9yTWVzc2FnZSkuaHRtbCgpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25IYW5kbGVyLmFkZChcImVycm9yXCIsIF9tKFwiQW4gZXJyb3Igb2NjdXJyZWQgd2hlbiB1cGxvYWRpbmcgdGhlIGltYWdlLlwiKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KS5mYWlsKGZ1bmN0aW9uIChyZXEsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25IYW5kbGVyLmFkZChcImVycm9yXCIsIF9tKFwiQW4gZXJyb3Igb2NjdXJyZWQgd2hlbiB1cGxvYWRpbmcgdGhlIGltYWdlOiAkbWVzc2FnZSRcIiwgeyBtZXNzYWdlOiBlcnJvclRocm93biB9KSk7XG4gICAgICAgICAgICAgICAgfSkuYWx3YXlzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgJGJ1dHRvbi5yZW1vdmVDbGFzcyhcImlzLWxvYWRpbmdcIikucHJvcChcImRpc2FibGVkXCIsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWRJbnB1dHMucHJvcChcImRpc2FibGVkXCIsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgdXBsb2FkSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGFmdGVyT3BlbmluZ0lubGluZURpYWxvZyhkaWFsb2cpO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2xvc2VJbmxpbmVEaWFsb2c6IGNsb3NlSW5saW5lRGlhbG9nXG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAvLyAgICAgICBNQVRISkFYIFNUVUJTICAgICAgICAvL1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICBpZiAodHlwZW9mIE1hdGhKYXggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHZhciBjb25maWcgPSBNYXRoSmF4Lkh1Yi5jb25maWc7XG4gICAgICAgIHZhciBsb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIGxvYWRDYWxsYmFja3MgPSAkLkNhbGxiYWNrcygpO1xuXG4gICAgICAgIHZhciBwcmVwYXJlRWRpdG9yID0gZnVuY3Rpb24gKGVkaXRvciwgcG9zdGZpeCkge1xuICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5tYXRoamF4RWRpdGluZy5wcmVwYXJlV21kRm9yTWF0aEpheChlZGl0b3IsIHBvc3RmaXgsIGNvbmZpZy50ZXgyamF4LmlubGluZU1hdGgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3IuY3JlYXRpb25DYWxsYmFja3MuYWRkKGZ1bmN0aW9uIChlZGl0b3IsIHBvc3RmaXgpIHtcbiAgICAgICAgICAgIGlmIChsb2FkZWQpIHtcbiAgICAgICAgICAgICAgICBwcmVwYXJlRWRpdG9yKGVkaXRvciwgcG9zdGZpeCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvYWRDYWxsYmFja3MuYWRkKGZ1bmN0aW9uICgpIHsgcHJlcGFyZUVkaXRvcihlZGl0b3IsIHBvc3RmaXgpOyBlZGl0b3IucmVmcmVzaFByZXZpZXcoKTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFN0YWNrRXhjaGFuZ2UudXNpbmcoY29uZmlnLlNFRWRpdG9yLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgbG9hZENhbGxiYWNrcy5maXJlKCk7XG4gICAgICAgICAgICBsb2FkQ2FsbGJhY2tzLmVtcHR5KCk7XG4gICAgICAgIH0sIFwibWF0aGpheC1lZGl0aW5nXCIpO1xuICAgIH1cblxuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgIC8vICAgICAgICAgICBPTkVCT1ggICAgICAgICAgIC8vXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIHZhciBzY2hlZHVsZWRPbmVib3g7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVPbmVib3goalByZXZpZXcpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHNjaGVkdWxlZE9uZWJveCk7XG4gICAgICAgIGlubGluZU9uZWJveChqUHJldmlldyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5saW5lT25lYm94KGpQcmV2aWV3KSB7XG4gICAgICAgICQoalByZXZpZXcpLmZpbmQoJ3AgPiBhOm5vdChhOmhhcyhpbWcpKScpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICRwcmV2aWV3TGluayA9ICQodGhpcyk7XG4gICAgICAgICAgICB2YXIgaHJlZiA9ICQodGhpcykuYXR0cignaHJlZicpO1xuXG4gICAgICAgICAgICAvLyBHRDogV2Ugb25seSB3YW50IG9uZWJveGVzIGZvciByYXcgdXJscyBvbiB0aGVpciBvd24gbGluZVxuICAgICAgICAgICAgLy8gICAgIE1vZGlmaWNhdGlvbnMgdG8gdGhlIGNsaWVudCBzaXRlIHByZXZpZXcgbXVzdCBtYXRjaCB0aGUgc2VydmVyIHNpZGUgYmFraW5nXG4gICAgICAgICAgICAvLyAgICAgXG4gICAgICAgICAgICB2YXIgcGFyYWdyYXBoVGV4dCA9ICRwcmV2aWV3TGluay5jbG9zZXN0KCdwJykudGV4dCgpLnRyaW0oKTtcbiAgICAgICAgICAgIGlmIChocmVmICE9IHBhcmFncmFwaFRleHQpIHJldHVybjtcblxuICAgICAgICAgICAgaWYgKCFvbmVib3hNYXRjaC5oYXNPd25Qcm9wZXJ0eShocmVmKSkge1xuICAgICAgICAgICAgICAgICRwcmV2aWV3TGluay5wYXJlbnQoKS5hZGRTcGlubmVyKHsgJ3BhZGRpbmctbGVmdCc6ICczcHgnIH0pO1xuICAgICAgICAgICAgICAgIHNjaGVkdWxlZE9uZWJveCA9IHNldFRpbWVvdXQocmVzb2x2ZU9uZWJveCwgMTAwMCwgJHByZXZpZXdMaW5rLnBhcmVudCgpLCBocmVmKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgJHByZXZpZXdMaW5rLnBhcmVudCgpLmh0bWwob25lYm94TWF0Y2hbaHJlZl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlT25lYm94KGVsZW1lbnQsIGhyZWYpIHtcbiAgICAgICAgJC5wb3N0KFxuICAgICAgICAgICAgJy9wb3N0cy9vbmVib3gnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHVybDogaHJlZixcbiAgICAgICAgICAgICAgICBma2V5OiBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmRvbmUoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9uZWJveE1hdGNoW2hyZWZdID0gZGF0YS5kYXRhO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lmh0bWwob25lYm94TWF0Y2hbaHJlZl0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLnBvbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkU3Bpbm5lcih7ICdwYWRkaW5nLWxlZnQnOiAnM3B4JyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZU9uZWJveCwgMzAwMCwgZWxlbWVudCwgaHJlZik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvbmVib3hNYXRjaFtocmVmXSA9IGRhdGEuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVTcGlubmVyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG59KSgpO1xuIiwiaW1wb3J0IHsgS0VZX0NPREUgfSBmcm9tICcuLi8uLi9jb25zdGFudHMubW9kJztcblxuLy8gUG9zdCBFZGl0b3Igc2NyaXB0c1xuXG5TdGFja0V4Y2hhbmdlLmVkaXRvciA9IChmdW5jdGlvbiAoKSB7XG5cbiAgICB2YXIgaW5pdCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICB2YXIgcG9zdGZpeCA9IG9wdGlvbnMucG9zdGZpeCB8fCBcIlwiO1xuICAgICAgICB2YXIgcmVzaXplID0gb3B0aW9ucy5yZXNpemUgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLnJlc2l6ZTtcblxuICAgICAgICB2YXIgaGVhcnRiZWF0VHlwZSA9IG9wdGlvbnMuaGVhcnRiZWF0VHlwZSwgLy93aGVuIG51bGwvZW1wdHksIG5vIGhlYXJ0YmVhdFxuICAgICAgICAgICAgYmluZE5hdlByZXZlbnRpb24gPSBvcHRpb25zLmJpbmROYXZQcmV2ZW50aW9uLFxuICAgICAgICAgICAgakZvcm0gPSAkKCcjcG9zdC1mb3JtJyArIHBvc3RmaXgpLFxuICAgICAgICAgICAgaldtZCA9ICQoXCIjd21kLWlucHV0XCIgKyBwb3N0Zml4KSxcbiAgICAgICAgICAgIGpFbnRyeUZpZWxkcywgak92ZXJsYXllZEZpZWxkcztcblxuICAgICAgICBqT3ZlcmxheWVkRmllbGRzID0gJChcIiN0aXRsZSwgI2VkaXQtY29tbWVudCwgI20tYWRkcmVzcywgLmVkaXQtY29tbWVudFwiKTsgLy8gdGhlIHRhZyBlZGl0b3IgdGFrZXMgY2FyZSBvZiBpdHMgb3ZlcmxheVxuICAgICAgICBqRW50cnlGaWVsZHMgPSBqT3ZlcmxheWVkRmllbGRzLmFkZChcIi50YWctZWRpdG9yIGlucHV0XCIpOyAvLyBUT0RPIGNoZWNrIHRpbWluZ1xuXG4gICAgICAgIC8vIHZhbGlkYXRlIGZvcm0gYmVmb3JlIHN1Ym1pc3Npb25cbiAgICAgICAgakZvcm0uc3VibWl0KGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgLy8gR2l2ZSBvdGhlciBsaXN0ZW5lcnMgYSBjaGFuY2UgdG8gcHJldmVudCBzdWJtaXNzaW9uIGFuZCB0aGUgYmVsb3cgc2lkZS1lZmZlY3RzLlxuICAgICAgICAgICAgdmFyIGV2ZW50ID0gJC5FdmVudCgncG9zdDp3aWxsLXN1Ym1pdCcpO1xuICAgICAgICAgICAgakZvcm0udHJpZ2dlcihldmVudCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaGVscGVycy5kaXNhYmxlU3VibWl0QnV0dG9uKGpGb3JtKTsgLy8gVEhJUyBJUyBJTVBPUlRBTlQuIElmIHdlIGRvbid0IGhhdmUgdGhpcywgdXNlcnMgd2lsbCBkb3VibGUgY2xpY2sgYW5kIFNVQk1JVCBUV0lDRSFcbiAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UubmF2UHJldmVudGlvbi5wYXVzZSgpOyAvLyB1bmJpbmQgdGhlIG9uYmVmb3JldW5sb2FkIGhhbmRsZXIgdG8gYWxsb3cgcHJvcGVyIHN1Ym1pc3Npb25cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaWYgKHJlc2l6ZSkge1xuICAgICAgICAgICAgJChcIi5vcmlnaW5hbC1xdWVzdGlvblwiKS5ub3QoXCIucHJvY2Vzc2VkXCIpLlRleHRBcmVhUmVzaXplcigpO1xuICAgICAgICAgICAgaldtZC5ub3QoXCIucHJvY2Vzc2VkXCIpLlRleHRBcmVhUmVzaXplcigpO1xuICAgICAgICB9XG4gICAgICAgIGpXbWQudHlwZVdhdGNoKHsgaGlnaGxpZ2h0OiBmYWxzZSwgd2FpdDogNTAwMCwgY2FwdHVyZUxlbmd0aDogNSwgY2FsbGJhY2s6IHN0eWxlQ29kZSB9KTtcblxuICAgICAgICB2YXIgd21kID0gbmV3IFN0YWNrRXhjaGFuZ2UuTWFya2Rvd25FZGl0b3Iob3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKGhlYXJ0YmVhdFR5cGUpIHtcbiAgICAgICAgICAgIHZhciBkaXNjYXJkTGluayA9IG9wdGlvbnMuZGlzY2FyZFNlbGVjdG9yID8gJChvcHRpb25zLmRpc2NhcmRTZWxlY3RvcikgOiBudWxsO1xuICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5jYXJkaW9sb2dpc3QuYWRkSGVhcnQoaGVhcnRiZWF0VHlwZSwgaldtZCwgd21kLCBkaXNjYXJkTGluaywgb3B0aW9ucy5wb3N0SWQsIG9wdGlvbnMuYXV0b0FjdGl2YXRlSGVhcnRiZWF0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdtZC5ob29rcy5jaGFpbihcImltYWdlQ29udmVydGVkVG9MaW5rXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBqQ29udGFpbmVyID0galdtZC5wYXJlbnQoKTtcblxuICAgICAgICAgICAgdmFyIG1zZyA9IF9zKFwiWW91J3JlIG5vdCBhbGxvd2VkIHRvIGVtYmVkIGltYWdlcyBpbiB5b3VyIHBvc3RzIHlldCwgc28gd2UndmUgaW5jbHVkZWQgYSBsaW5rIGluc3RlYWQuXCIpO1xuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5yZXB1dGF0aW9uVG9Qb3N0SW1hZ2VzKSB7XG4gICAgICAgICAgICAgICAgbXNnICs9ICc8YnIvPjxici8+JyArIF9zKFwiQXMgc29vbiBhcyB5b3UgZWFybiAkcmVwJCByZXB1dGF0aW9uIG9uIHRoZSBzaXRlLCB5b3UnbGwgYmUgYWJsZSB0byBlbWJlZCBpbWFnZXMuXCIsIHsgcmVwOiBvcHRpb25zLnJlcHV0YXRpb25Ub1Bvc3RJbWFnZXMgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaGVscGVycy5zaG93SW5mb01lc3NhZ2UoXG4gICAgICAgICAgICAgICAgakNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICBtc2csXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXQ6IFwicmlnaHQgdG9wXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBteTogXCJsZWZ0IGJvdHRvbVwiXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGNzc0NsYXNzOiBcImNvbnZlcnQtaW1hZ2UtdG8tbGlua1wiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gd2hlbiBmb2N1c2luZyBpbnB1dHMsIGxvYWQgdGhlIGphdmFzY3JpcHQgYW50aS1zcGFtIGZpZWxkXG4gICAgICAgIGlmIChoZWFydGJlYXRUeXBlID09ICdhc2snIHx8IGhlYXJ0YmVhdFR5cGUgPT0gJ2Fuc3dlcicpIHtcblxuICAgICAgICAgICAgdmFyIGZpZWxkcyA9IGpXbWQuYWRkKGpFbnRyeUZpZWxkcyk7XG5cbiAgICAgICAgICAgIHZhciBsb2FkVGlja3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5oZWxwZXJzLmxvYWRUaWNrcyhqRm9ybSk7XG4gICAgICAgICAgICAgICAgZmllbGRzLnVuYmluZChcImtleWRvd25cIiwgbG9hZFRpY2tzKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGZpZWxkcy5iaW5kKFwia2V5ZG93blwiLCBsb2FkVGlja3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gb25jZSBhIG5ldyBwb3N0IGlzIHN0YXJ0ZWQsIGJpbmQgYSBoYW5kbGVyIHRvIHByZXZlbnQgZm9ybSBsb3NzIHZpYSBhY2NpZGVudGlhbCBuYXZpZ2F0aW9uXG4gICAgICAgIGlmIChiaW5kTmF2UHJldmVudGlvbikge1xuICAgICAgICAgICAgdmFyIG5hdlByZXZlbnRpb25GaWVsZHMgPSAoaGVhcnRiZWF0VHlwZSA9PSAnZWRpdCcgfHwgaGVhcnRiZWF0VHlwZSA9PSAnYXNrJylcbiAgICAgICAgICAgICAgICA/IGpXbWQuYWRkKCcjdGl0bGUnKS5hZGQoJyN0YWduYW1lcycpXG4gICAgICAgICAgICAgICAgOiBqV21kO1xuICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5uYXZQcmV2ZW50aW9uLmluaXQobmF2UHJldmVudGlvbkZpZWxkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBqRm9ybVxuICAgICAgICAgICAgLmZpbmQoJy5qcy13bWQtcHJldmlldycpXG4gICAgICAgICAgICAuY2xpY2soXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXZ0LnRhcmdldC5jbGFzc05hbWUgPT09IFwic2hvdy1oaWRlXCIgfHwgZXZ0LnRhcmdldC5sb2NhbE5hbWUuc3RhcnRzV2l0aChcImlucHV0XCIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICBpZiAod2luZG93LmdldFNlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoc2VsZWN0aW9uLmFuY2hvck5vZGUgIT09IHNlbGVjdGlvbi5mb2N1c05vZGUpIHx8IChzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0ICE9PSBzZWxlY3Rpb24uZm9jdXNPZmZzZXQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZXZ0LndoaWNoICE9IEtFWV9DT0RFLk1JRERMRV9NT1VTRSkgeyAvLyAyID0gbWlkZGxlIGNsaWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnNpYmxpbmdzKCkuZmluZCgndGV4dGFyZWEnKS5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAvLyBzZXQgdGhlIGZvY3VzIGlmIHVzZXIgaGFzbid0IGZvY3VzZWQgYW55dGhpbmcgeWV0XG4gICAgICAgIGlmICgkKFwiI2Fzay1wYWdlLWhhcy1lcnJvcnNcIikubGVuZ3RoID09IDAgJiYgJChcIiN0aXRsZVwiKS5pcyhcImlucHV0XCIpICYmIGpGb3JtLmZpbmQoJzpmb2N1cycpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8kKFwiI3RpdGxlXCIpLmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMub25DcmVhdGVkKSBvcHRpb25zLm9uQ3JlYXRlZCh3bWQpO1xuXG4gICAgICAgIC8vIEhvb2sgdXAgdGhlIFwiZGlzY2FyZFwiIGRyYWZ0IGxpbmssIGlmIHByZXNlbnRcbiAgICAgICAgaWYgKG9wdGlvbnMuZGlzY2FyZFNlbGVjdG9yICYmIChoZWFydGJlYXRUeXBlID09ICdhc2snIHx8IGhlYXJ0YmVhdFR5cGUgPT0gJ2Fuc3dlcicgfHwgaGVhcnRiZWF0VHlwZSA9PSAnbW9kZXJhdG9ybWVzc2FnZScgfHwgaGVhcnRiZWF0VHlwZSA9PSAnYXJ0aWNsZScpKSB7XG4gICAgICAgICAgICB2YXIgZGlzY2FyZCA9ICQob3B0aW9ucy5kaXNjYXJkU2VsZWN0b3IpO1xuXG4gICAgICAgICAgICBkaXNjYXJkLmNsaWNrKFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbmZpcm0oX3MoJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkaXNjYXJkIHlvdXIgZHJhZnQ/JykpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBibHVyIHRoZSBmaWVsZHMgYWZ0ZXIgY2xlYXJpbmcgdGhlbSB0byB0cmlnZ2VyIHJlbW92YWwgb2YgYW55IHZhbGlkYXRpb24gZXJyb3JzXG4gICAgICAgICAgICAgICAgICAgICQoJyN0aXRsZScpLnZhbCgnJykuYmx1cigpO1xuICAgICAgICAgICAgICAgICAgICAkKCcjcXVlc3Rpb24tc3VnZ2VzdGlvbnMnKS5lbXB0eSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGRpc2NhcmQgYW5zd2VyIGJveCBvbiBxdWVzdGlvbiBhc2tcbiAgICAgICAgICAgICAgICAgICAgJCgnI3dtZC1pbnB1dC00MicpLnZhbCgnJyk7XG4gICAgICAgICAgICAgICAgICAgICQoJyN3bWQtcHJldmlldy00MicpLmh0bWwoJycpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIHVuY2hlY2sgQW5zd2VyIHlvdXIgb3duIHF1ZXN0aW9uXG4gICAgICAgICAgICAgICAgICAgICQoJy5qcy1wb3N0LWFuc3dlci13aGlsZS1hc2tpbmctY2hlY2tib3gnKS5maWx0ZXIoJzp2aXNpYmxlJykuZmlsdGVyKCc6Y2hlY2tlZCcpLmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhZ3MgPSAoaGVhcnRiZWF0VHlwZSA9PSAnYXJ0aWNsZScpID8gJChcIi5qcy1lZGl0LWFydGljbGUtZm9ybSAjdGFnbmFtZXNcIikgOiBkaXNjYXJkLmNsb3Nlc3QoJy5wb3N0LWZvcm0nKS5maW5kKCcjdGFnbmFtZXMnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhZ3MubGVuZ3RoID4gMCAmJiB0YWdzWzBdLmZ1bmNfY2xlYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3NbMF0uZnVuY19jbGVhcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFncy5ibHVyKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBqV21kLnZhbCgnJykuYmx1cigpO1xuXG4gICAgICAgICAgICAgICAgICAgIHdtZC5yZWZyZXNoUHJldmlldygpO1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgJC5wb3N0KFxuICAgICAgICAgICAgICAgICAgICAgICAgJy9wb3N0L2Rpc2NhcmQtZHJhZnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBma2V5OiBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5LCBwb3N0VHlwZTogaGVhcnRiZWF0VHlwZSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNkcmFmdC1zYXZlZCcpLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjZHJhZnQtZGlzY2FyZGVkJykuc2hvdygpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGVEaXNjYXJkID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlRGlzY2FyZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnI2RyYWZ0LWRpc2NhcmRlZCcpLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnI3RpdGxlJykudW5iaW5kKCdrZXlwcmVzcycsIGhpZGVEaXNjYXJkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaldtZC51bmJpbmQoJ2tleXByZXNzJywgaGlkZURpc2NhcmQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjdGl0bGUnKS5iaW5kKCdrZXlwcmVzcycsIGhpZGVEaXNjYXJkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqV21kLmJpbmQoJ2tleXByZXNzJywgaGlkZURpc2NhcmQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGRpc2NhcmQuaGlkZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm9uRHJhZnREaXNjYXJkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMub25EcmFmdERpc2NhcmRlZCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb21tdW5pdHkgd2lraSBjYW4gYWNjaWRlbnRhbGx5IGJlIGVuYWJsZWQgLSBpbmZvcm0gdXNlcnMgb2YgdGhpcyBudWNsZWFyIG9wdGlvblxuICAgICAgICBTdGFja0V4Y2hhbmdlLmJpbmRDb21tdW5pdHlXaWtpQ29uZmlybWF0aW9uKCQoJy5qcy1wb3N0LWVkaXRvcicpKTtcblxuICAgIH07IC8vIEVORCBpbml0XG5cbiAgICAvLyB0aGlzIGJlaGF2aW9yIGlzICpub3QqIHJlYWR5IGZvciBtdWx0aXBsZSBlZGl0b3JzIChidXQgdGhhdCBkb2Vzbid0IGN1cnJlbnRseSBtYXR0ZXIsIHNpbmNlIGl0J3Mgb25seSByZWxldmFudFxuICAgIC8vIHRvIHRoZSBpbi1wYWdlIHJlbmRlcmVkIGFuc3dlci1lZGl0b3IgYW5kIHRoZSBhbnN3ZXItb24tYXNrIGVkaXRvciwgc28gYXQgbW9zdCBvbmUgZWRpdG9yIHdpbGwgYmUgaGlkZGVuKS5cbiAgICB2YXIgaW5pdElmU2hvd24gPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAvLyBzb21ldGltZXMsIHRoZSBlZGl0b3IgaXMgaGlkZGVuIChlLmcuIHF1ZXN0aW9uIGFza2VycyBvbiB0aGVpciBxdWVzdGlvbiBwYWdlLCBtb2JpbGUgZGV2aWNlcywgYW5zd2VyLW9uLWFzaylcblxuICAgICAgICB2YXIgcG9zdGZpeCA9IChvcHRpb25zIHx8IHt9KS5wb3N0Zml4IHx8IFwiXCI7XG5cbiAgICAgICAgdmFyIGluaXRub3cgPVxuICAgICAgICAgICAgJChcIiN3bWQtcHJldmlld1wiICsgcG9zdGZpeCkubGVuZ3RoICE9IDAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYW4gZWRpdG9yIGluIHRoZSBmaXJzdCBwbGFjZSxcbiAgICAgICAgICAgICYmIChwb3N0Zml4ICE9PSBcIi00MlwiIHx8ICQoJy5qcy1wb3N0LWFuc3dlci13aGlsZS1hc2tpbmctY2hlY2tib3gnKS5sZW5ndGggPT09IDApICAgIC8vIGFuZCBpdCdzIG5vdCB0aGUgYW5zd2VyLW9uLWFzayBlZGl0b3JcbiAgICAgICAgICAgICYmICQoXCIjc2hvdy1lZGl0b3ItYnV0dG9uXCIgKyBwb3N0Zml4KS5sZW5ndGggPT09IDA7ICAgICAgICAgICAgIC8vIGFuZCB0aGVyZSdzIG5vIFwicmVhbGx5IHdhbm5hIGFuc3dlciB0aGlzIHF1ZXN0aW9uXCIgYnV0dG9uXG5cbiAgICAgICAgaWYgKGluaXRub3cpIHtcbiAgICAgICAgICAgIGluaXQob3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAoIVN0YWNrRXhjaGFuZ2UuZWRpdG9yLmZpbmFsbHlJbml0KSAvLyBkb24ndCBvdmVyd3JpdGUgaWYgaXQncyBhbHJlYWR5IHRoZXJlIChodHRwczovL21ldGEuc3RhY2tleGNoYW5nZS5jb20vcS8xMTIwMDQpXG4gICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5lZGl0b3IuZmluYWxseUluaXQgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmVkaXRvci5maW5hbGx5SW5pdCA9IGZ1bmN0aW9uICgpIHsgaW5pdChvcHRpb25zKTsgfSAvLyBjYWxsZWQgYWZ0ZXIgdGhlIHVzZXIgaGFzIGNvbmZpcm1lZCB0aGV5IHdhbnQgdG8gYW5zd2VyXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgaW5pdDogaW5pdCxcbiAgICAgICAgaW5pdElmU2hvd246IGluaXRJZlNob3duXG4gICAgfVxufSkoKTtcbiIsImltcG9ydCB7IEtFWV9DT0RFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzLm1vZCc7XG5cbi8vIFdoZW4gdXNlcnMgYXJlIGVudGVyaW5nIGFuIGFuc3dlciwgaGVhcnRiZWF0IHdpbGwgY2FsbCBiYWNrIHRvIHBhcmVudCBxdWVzdGlvbiBmb3Igc3RhdHVzIHVwZGF0ZXMsIGUuZy4gXCIxIG5ldyBhbnN3ZXJcIiwgXCJxdWVzdGlvbiBpcyBjbG9zZWRcIixcbi8vIHdoZW4gdGhleSBlZGl0LCBpdCBjaGVja3MgZm9yIGNvbmN1cnJlbnQgZWRpdHMgYnkgb3RoZXIgdXNlcnMuXG4vLyBJdCBhbHNvIGhhbmRsZXMgZHJhZnRzLlxuLy9cbi8vIFRoZXJlIGNhbiBiZSBzZXZlcmFsIGhlYXJ0cyBpbiBhIHBhZ2U7IG9uZSBwZXIgZWRpdG9yLiBUaGV5IGFsbCBzdGFydCBvdXQgYXMgaW5hY3RpdmUuIEEgaGVhcnQgaXNcbi8vIGFjdGl2YXRlZCBieSBhIGtleXByZXNzIGV2ZW50IGluIHRoZSBjb3JyZXNwb25kaW5nIGVkaXRvci4gQXQgbW9zdCBvbmUgaGVhcnQgaXMgdGhlIFttYXN0ZXJdIGhlYXJ0LCBuYW1lbHlcbi8vIHRoZSBvbmUgd2hvc2UgZWRpdG9yIHJlY2VpdmVkIHRoZSBsYXN0IGtleXByZXNzIGV2ZW50LiBPbmx5IHRoZSBtYXN0ZXIgaGVhcnQgc2VuZHMgdGhlIGVkaXRvciBjb250ZW50XG4vLyB0byB0aGUgc2VydmVyIGZvciBzYXZpbmcgYXMgZHJhZnQgYW5kL29yIHNpbWlsYXIgcXVlc3Rpb25zIGZpbmRpbmcuXG4vL1xuLy8gVGhlIGJlYXQgcXVldWUgc3RhcnRzIG91dCBlbXB0eSwgYW5kIGl0IGlzIGVtcHRpZWQgZXZlcnkgdGltZSB0aGUgbWFzdGVyIGhlYXJ0IGNoYW5nZXMuIFdoZW4gZmlsbGluZyB0aGVcbi8vIHF1ZXVlLCB0aGUgbWFzdGVyIGhlYXJ0IGlzIGluc2VydGVkIGZpcnN0OyBhbGwgb3RoZXIgaGVhcnRzIGFyZSBpbnNlcnRlZCBpbiBvcmRlciBvZiB0aGVpciBhY3RpdmF0aW9uLiBBIGhlYXJ0XG4vLyAod2hldGhlciBtYXN0ZXIgb3Igbm90KSBpcyBub3QgaW5zZXJ0ZWQgaWYgaXQgaGFzIGJlYXRlbiAzMCB0aW1lcy5cbi8vIFRoZSBxdWV1ZSBpbnRlcnZhbCBYIGlzIHNldCB0byA2MCBkaXZpZGVkIGJ5IE4gKHdoZXJlIE4gaXMgdGhlIG51bWJlciBvZiBoZWFydHMgaW4gdGhlIHF1ZXVlKSwgY2FwcGVkIGJldHdlZW4gMTUgYW5kIDQ1LlxuLy9cbi8vIFRoZSBmaXJzdCB0aW1lIGEgaGVhcnQgaXMgYWN0aXZhdGVkLCBhIHRpbWVyIG9mIDQ1IHNlY29uZHMgaXMgc3RhcnRlZDsgYWZ0ZXIgaXQgaGFzIGVsYXBzZWQsIHRoZSBxdWV1ZSBoYW5kbGVyIGlzIGNhbGxlZC5cbi8vXG4vLyBRdWV1ZSBoYW5kbGVyXG4vLyAtLS0tLS0tLS0tLS0tXG4vLyBJZiB0aGUgcXVldWUgaGFuZGxlciBmaW5kcyB0aGUgcXVldWUgZW1wdHksIGl0IGlzIHJlcG9wdWxhdGVkLCBhbmQgWCBpcyBzZXQgYWNjb3JkaW5nbHkgKGluIHBhcnRpY3VsYXIsIG9uIHRoZSBmaXJzdCBjYWxsKS5cbi8vIFRoZSBoYW5kbGVyIHRha2VzIHRoZSBmaXJzdCBoZWFydCBmcm9tIHRoZSBxdWV1ZS4gSXQgbWFrZXMgdGhlIHBpbmcgdG8gdGhlIHNlcnZlciAoaW5jbHVkaW5nIHRoZSBlZGl0b3Jcbi8vIGNvbnRlbnQgaWZmIGl0IGlzIHRoZSBtYXN0ZXIgaGVhcnQgYW5kIGhhcyBhIHR5cGUgIT0gXCJlZGl0XCIpLlxuLy9cbi8vIElmIHRoZSByZXF1ZXN0IHJldHVybnMgc3VjY2Vzc2Z1bGx5LCB0aGUgcmVzdWx0IGlzIGhhbmRsZWQsIGFuZCBZIGlzIHNldCB0byB6ZXJvLlxuLy9cbi8vIElmIGl0IGNhdXNlcyBhbiBlcnJvciwgWSBpcyBzZXQgdG8gYSByYW5kb20gbnVtYmVyIGJldHdlZW4gMCBhbmQgMTAuIFRoZSBoZWFydCBpcyAqcHJlcGVuZGVkKiB0byB0aGUgcXVldWUgaWZmIGl0IGlzIHRoZSBtYXN0ZXIgaGVhcnQuXG4vL1xuLy8gSW4gYm90aCBjYXNlcywgYSBuZXcgdGltZXIgaXMgc3RhcnRlZCB3aXRoIGEgdGltZW91dCBvZiBYICsgWSBzZWNvbmRzLlxuXG5TdGFja0V4Y2hhbmdlLmNhcmRpb2xvZ2lzdCA9IChmdW5jdGlvbiAoKSB7IC8vIEkgd291bGQgaGF2ZSBjYWxsZWQgaXQgXCJoZWFydGJlYXRNYW5hZ2VyXCIsIGJ1dCB0aGUgYm9zcyBkb2Vzbid0IGxpa2UgdGhhdDogaHR0cDovL3d3dy5jb2Rpbmdob3Jyb3IuY29tL2Jsb2cvMjAwNi8wMy9pLXNoYWxsLWNhbGwtaXQtc29tZXRoaW5nbWFuYWdlci5odG1sXG5cbiAgICB2YXIgYWN0aXZlSGVhcnRzID0gW10sXG4gICAgICAgIG1hc3RlckhlYXJ0LFxuICAgICAgICBxdWV1ZSA9IFtdLFxuICAgICAgICBwcmV2aW91c0RyYWZ0LFxuICAgICAgICBwcmV2aW91c1JlbGF0ZWQsXG4gICAgICAgIGRlZmF1bHRRdWV1ZUludGVydmFsID0gNDUsXG4gICAgICAgIGN1c3RvbUhlYXJ0YmVhdEludGVydmFsID0gZGVmYXVsdFF1ZXVlSW50ZXJ2YWwsXG4gICAgICAgIHF1ZXVlSW50ZXJ2YWwgPSBkZWZhdWx0UXVldWVJbnRlcnZhbCxcbiAgICAgICAgaW50ZXJ2YWxEZWx0YSA9IDAsXG4gICAgICAgIGhhc0JlZW5Ob3RpZmllZE9mTmV3QW5zd2VyID0gZmFsc2UsXG4gICAgICAgIG5vdGlmeU1lc3NhZ2VUeXBlSWQgPSAtMixcbiAgICAgICAgZGVmYXVsdE1heEhlYXJ0YmVhdENvdW50ID0gMzAsXG4gICAgICAgIGxhc3RQaW5nVGltZSwgdGltZW91dElkO1xuXG4gICAgZnVuY3Rpb24gc3RhcnRUaW1lb3V0KGludGVydmFsT3ZlcnJpZGVNcykge1xuICAgICAgICB2YXIgZGVsYXkgPSAodHlwZW9mIGludGVydmFsT3ZlcnJpZGVNcyA9PT0gXCJudW1iZXJcIikgPyBpbnRlcnZhbE92ZXJyaWRlTXMgOiAocXVldWVJbnRlcnZhbCArIGludGVydmFsRGVsdGEpICogMTAwMDtcbiAgICAgICAgaWYgKGxhc3RQaW5nVGltZSlcbiAgICAgICAgICAgIGRlbGF5ID0gTWF0aC5tYXgoZGVsYXksIDYwMDAgLSAobmV3IERhdGUoKS5nZXRUaW1lKCkgLSBsYXN0UGluZ1RpbWUpKTsgLy8gdGhlIGhlYXJ0YmVhdCByb3V0ZSBpcyB0aHJvdHRsZWQgdG8gNSBzZWNvbmRzIC0tIHNvIHdlIGRvbid0IHdhbnQgdG8gYmUgdG9vIGZhc3QhXG4gICAgICAgIGlmICh0aW1lb3V0SWQpXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKVxuICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGhhbmRsZVF1ZXVlLCBkZWxheSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFuZGxlUXVldWUoKSB7XG4gICAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgIGlmICghcXVldWUubGVuZ3RoKVxuICAgICAgICAgICAgcG9wdWxhdGVRdWV1ZSgpO1xuICAgICAgICBpZiAoIXF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgc3RhcnRUaW1lb3V0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGhlYXJ0ID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgaWYgKGhlYXJ0LmNoZWNrQWN0aXZlKCkpXG4gICAgICAgICAgICBoZWFydC5iZWF0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHN0YXJ0VGltZW91dCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBvcHVsYXRlUXVldWUoKSB7XG4gICAgICAgIHZhciBoZWFydDtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgaWYgKG1hc3RlckhlYXJ0ICYmICFtYXN0ZXJIZWFydC5pc0Rpc2FibGVkICYmIG1hc3RlckhlYXJ0LmJlYXRDb3VudCA8IG1hc3RlckhlYXJ0Lm1heEhlYXJ0YmVhdENvdW50KVxuICAgICAgICAgICAgcXVldWUucHVzaChtYXN0ZXJIZWFydClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhY3RpdmVIZWFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGhlYXJ0ID0gYWN0aXZlSGVhcnRzW2ldO1xuICAgICAgICAgICAgaWYgKGhlYXJ0ICE9IG1hc3RlckhlYXJ0ICYmICFoZWFydC5pc0Rpc2FibGVkICYmIGhlYXJ0LmJlYXRDb3VudCA8IGhlYXJ0Lm1heEhlYXJ0YmVhdENvdW50KSB7XG4gICAgICAgICAgICAgICAgcXVldWUucHVzaChoZWFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZm9yIG11bHRpcGxlIGhlYXJ0YmVhdHMsIHdlIHNob3VsZCBhdHRlbXB0IHRvIHN0YWdnZXIgdGhlbSBhIGJpdFxuICAgICAgICAvLyBlLmcuIDEgaGVhcnQgPSA0NXMgaW50ZXJ2YWwsIDIgPSAzMHMsIDMgPSAyMHMsIDQgPSAxNXMsIDUgPSAxNXMsIC4uLlxuICAgICAgICBjb25zdCBtdWx0aXBsZUhlYXJ0c0ludGVydmFsID0gY3VzdG9tSGVhcnRiZWF0SW50ZXJ2YWwgKyAoY3VzdG9tSGVhcnRiZWF0SW50ZXJ2YWwgLyAzKTtcbiAgICAgICAgcXVldWVJbnRlcnZhbCA9IE1hdGgubWF4KDE1LCBNYXRoLm1pbihjdXN0b21IZWFydGJlYXRJbnRlcnZhbCwgbXVsdGlwbGVIZWFydHNJbnRlcnZhbCAvIChxdWV1ZS5sZW5ndGggfHwgMSkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiB0aGUgcGFzc2VkIGVkaXRvciBpcyBhIFN0YWNrcy1FZGl0b3IgaW5zdGFuY2Ugc28gd2UgY2FuIGFsdGVyIG91ciBiZWhhdmlvciB0byBtYXRjaFxuICAgICAqIEBwYXJhbSB7YW55fSBlZGl0b3JcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0YWNrc0VkaXRvcihlZGl0b3IpIHtcbiAgICAgICAgcmV0dXJuIFwiY29udGVudFwiIGluIGVkaXRvcjtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0SGFuZGxlcnMgPSB7XG4gICAgICAgIGFzazogZnVuY3Rpb24gKGpzb24pIHtcbiAgICAgICAgICAgIGlmIChqc29uLnJlbGF0ZWRRdWVzdGlvbnMpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2ltaWxhclF1ZXN0aW9ucyA9ICQoXCIuanMtc2ltaWxhci1xdWVzdGlvbnNcIik7XG4gICAgICAgICAgICAgICAgc2ltaWxhclF1ZXN0aW9ucy5lbXB0eSgpLmFwcGVuZChqc29uLnJlbGF0ZWRRdWVzdGlvbnMpO1xuICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuZ3BzLmJpbmRUcmFja0NsaWNrcygkKCcuanMtc2ltaWxhci1xdWVzdGlvbnMtZGF0YS10cmFjaycpKTtcbiAgICAgICAgICAgICAgICAkKCcuanMtc2ltaWxhci1xdWVzdGlvbnMtb3V0ZXItZGl2JykucmVtb3ZlQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgICAgICQoJy5qcy1xdWVzdGlvbi1zdW1tYXJ5LXNjcm9sbCcpLm9uZSgnc2Nyb2xsJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLnVzaW5nKFwiZ3BzXCIsIGZ1bmN0aW9uICgpIHsgU3RhY2tFeGNoYW5nZS5ncHMudHJhY2soXCJzaW1pbGFycXVlc3Rpb25zLmJvZHlfc2Nyb2xsXCIpOyB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqc29uLnN1Z2dlc3RlZFRhZ3MgJiYgU3RhY2tFeGNoYW5nZS50YWdTdWdnZXN0aW9ucykge1xuICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UudGFnU3VnZ2VzdGlvbnMuc3VnZ2VzdChqc29uLnN1Z2dlc3RlZFRhZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBhbnN3ZXI6IGZ1bmN0aW9uIChqc29uLCBoZWFydCkge1xuICAgICAgICAgICAgaWYgKGpzb24gJiYgIWhhc0JlZW5Ob3RpZmllZE9mTmV3QW5zd2VyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGpzb24uZGlzYWJsZUVkaXRvcikge1xuICAgICAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLm5vdGlmeS5zaG93KGpzb24ubWVzc2FnZSwgbm90aWZ5TWVzc2FnZVR5cGVJZCk7XG4gICAgICAgICAgICAgICAgICAgIGhhc0JlZW5Ob3RpZmllZE9mTmV3QW5zd2VyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7IC8vIHNlcnZlciB3aWxsIHJldHVybiB0aGUgZGlmZmVyZW5jZSBpbiBjbGllbnQtbG9hZGVkIGFuc3dlcnMgYW5kIHdoYXQgZXhpc3RzIG9uIHNlcnZlclxuICAgICAgICAgICAgICAgICAgICB2YXIgY291bnQgPSBwYXJzZUludChqc29uLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXNnMiA9IF9tKCcjY291bnQjIG5ldyBhbnN3ZXJzIGhhdmUgYmVlbiBwb3N0ZWQgLSAkc3RhcnRBbmNob3IkbG9hZCBuZXcgYW5zd2Vycy4kZW5kQW5jaG9yJCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudDogY291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0QW5jaG9yOiAnPGEgaWQ9XCJsb2FkLW5ldy1hbnN3ZXJzXCI+JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kQW5jaG9yOiAnPC9hPidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2Uubm90aWZ5LnNob3cobXNnMiwgbm90aWZ5TWVzc2FnZVR5cGVJZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNCZWVuTm90aWZpZWRPZk5ld0Fuc3dlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKFwiI2xvYWQtbmV3LWFuc3dlcnNcIikuY2xpY2soZnVuY3Rpb24gKCkgeyB1cGRhdGVBbnN3ZXJzKGhlYXJ0LnBvc3RJZCk7IH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlZGl0OiBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICAgICAgaWYgKGpzb24gJiYganNvbi5tZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9sZCA9IFN0YWNrRXhjaGFuZ2Uubm90aWZ5LmdldE1lc3NhZ2VUZXh0KG5vdGlmeU1lc3NhZ2VUeXBlSWQpO1xuICAgICAgICAgICAgICAgIGlmIChvbGQgIT0gJChcIjxzcGFuIC8+XCIpLmh0bWwoanNvbi5tZXNzYWdlKS50ZXh0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5ub3RpZnkuY2xvc2Uobm90aWZ5TWVzc2FnZVR5cGVJZCk7XG4gICAgICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2Uubm90aWZ5LnNob3coanNvbi5tZXNzYWdlLCBub3RpZnlNZXNzYWdlVHlwZUlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG1vZGVyYXRvcm1lc3NhZ2U6IGZ1bmN0aW9uIChqc29uKSB7XG4gICAgICAgICAgICAvLyBkb2VzIG5vdGhpbmcsIGJ5IGRlc2lnblxuICAgICAgICB9LFxuICAgICAgICBhcnRpY2xlOiBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICAgICAgLy8gZG9lcyBub3RoaW5nLCBieSBkZXNpZ25cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBIZWFydCgpIHsgfTtcbiAgICBIZWFydC5wcm90b3R5cGUgPSB7XG4gICAgICAgIGFjdGl2YXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYXN0ZXJIZWFydCA9IHRoaXM7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0FjdGl2ZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB0aGlzLmlzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuYmVhdENvdW50ID0gMDtcbiAgICAgICAgICAgIGFjdGl2ZUhlYXJ0cy5wdXNoKHRoaXMpO1xuICAgICAgICAgICAgaWYgKGFjdGl2ZUhlYXJ0cy5sZW5ndGggPT09IDEpIC8vIGl0J3MgdGhlIGZpcnN0IG9uZVxuICAgICAgICAgICAgICAgIHN0YXJ0VGltZW91dCgpO1xuICAgICAgICB9LFxuICAgICAgICBjaGVja0FjdGl2ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzQWN0aXZlIHx8IHRoaXMuaXNEaXNhYmxlZClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIXRoaXMualRleHRhcmVhLmNsb3Nlc3QoXCJib2R5XCIpLmxlbmd0aCkgeyAvLyByZW1vdmVkIGZyb20gdGhlIERPTVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmpUZXh0YXJlYTtcbiAgICAgICAgICAgICAgICB0aGlzLmlzRGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBiZWF0OiBmdW5jdGlvbiAob25seUlmU2F2aW5nRHJhZnQpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgICAgIHVybDogJy9wb3N0cy8nICsgdGhpcy5wb3N0SWQgKyAnL2VkaXRvci1oZWFydGJlYXQvJyArIHRoaXMudHlwZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogeyBma2V5OiBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5IH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoIW9ubHlJZlNhdmluZ0RyYWZ0KSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5zdWNjZXNzID0gZnVuY3Rpb24gKGpzb24pIHsgdGhhdC5zdWNjZXNzKGpzb24pOyB9O1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IgPSBmdW5jdGlvbiAoKSB7IHRoYXQuZXJyb3IoKTsgfTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmNvbXBsZXRlID0gZnVuY3Rpb24gKCkgeyB0aGF0LmNvbXBsZXRlKCk7IH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNob3VsZFNlbmREcmFmdCgpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVkaXRvclZhbHVlID0gdGhpcy5qVGV4dGFyZWEudmFsKCk7XG5cbiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogZWRpdG9yVmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09IFwiYXNrXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS50aXRsZSA9ICQoJyN0aXRsZScpLnZhbCgpO1xuICAgICAgICAgICAgICAgICAgICBkYXRhLnRhZ25hbWVzID0gJCgnI3RhZ25hbWVzJykudmFsKCk7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEuYW5zd2VydGV4dCA9ICQoJyN3bWQtaW5wdXQtNDInKS52YWwoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09IFwiYXJ0aWNsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEudGl0bGUgPSAkKCcjdGl0bGUnKS52YWwoKTtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS50YWduYW1lcyA9ICQoJyN0YWduYW1lcycpLnZhbCgpO1xuICAgICAgICAgICAgICAgICAgICBkYXRhLmFydGljbGV0eXBlID0gJCgnaW5wdXRbbmFtZT1cImFydGljbGVUeXBlXCJdOmNoZWNrZWQnKS52YWwoKTtcblxuICAgICAgICAgICAgICAgICAgICAvL3N1YmNvbW11bml0eSBhcnRpY2xlXG4gICAgICAgICAgICAgICAgICAgIGxldCBzdWJjb21tdW5pdHlTbHVnU2VsZWN0b3IgPSAkKCcjanMtc3ViY29tbXVuaXR5LXNsdWcnKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBvc3RTdGF0ZVNlbGVjdG9yID0gJCgnI2pzLXBvc3Qtc3RhdGUnKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGVkaXRvclVzZXJJZHNTZWxlY3RvciA9ICQoJy5qcy1lZGl0b3ItdXNlcnNpZHMnKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoc3ViY29tbXVuaXR5U2x1Z1NlbGVjdG9yLnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLnN1YmNvbW11bml0eVNsdWcgPSBzdWJjb21tdW5pdHlTbHVnU2VsZWN0b3IudmFsKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLnBvc3RTdGF0ZSA9IHBvc3RTdGF0ZVNlbGVjdG9yLnZhbCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy9vbmx5IHBhc3Mgb24gbmV3IGFydGljbGUsIHN1YnNlcXVlbnQgZWRpdHMgYXJlIGRvbmUgdmlhIGFqYXhcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnBvc3RJZCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuZWRpdG9yVXNlcklkc1JhdyA9IGVkaXRvclVzZXJJZHNTZWxlY3Rvci52YWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghcHJldmlvdXNEcmFmdFxuICAgICAgICAgICAgICAgICAgICB8fCBwcmV2aW91c0RyYWZ0LmhlYXJ0ICE9PSB0aGlzXG4gICAgICAgICAgICAgICAgICAgIHx8IHByZXZpb3VzRHJhZnQudGl0bGUgIT09IGRhdGEudGl0bGVcbiAgICAgICAgICAgICAgICAgICAgfHwgcHJldmlvdXNEcmFmdC50YWduYW1lcyAhPT0gZGF0YS50YWduYW1lc1xuICAgICAgICAgICAgICAgICAgICB8fCBwcmV2aW91c0RyYWZ0LnRleHQgIT09IGRhdGEudGV4dFxuICAgICAgICAgICAgICAgICAgICB8fCBwcmV2aW91c0RyYWZ0LmFuc3dlcnRleHQgIT09IGRhdGEuYW5zd2VydGV4dFxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGEgPSBkYXRhO1xuICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0RyYWZ0ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGVhcnQ6IHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogZGF0YS50aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ25hbWVzOiBkYXRhLnRhZ25hbWVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogZGF0YS50ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgYW5zd2VydGV4dDogZGF0YS5hbnN3ZXJ0ZXh0XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9ubHlJZlNhdmluZ0RyYWZ0ICYmICEoXCJ0ZXh0XCIgaW4gb3B0aW9ucy5kYXRhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZSgpLnByb21pc2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMucmV2aXNpb25HdWlkKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5kYXRhLmNsaWVudFJldmlzaW9uR3VpZCA9IHRoaXMucmV2aXNpb25HdWlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gXCJhbnN3ZXJcIikge1xuICAgICAgICAgICAgICAgIC8vIHdoZW4gYW5zd2VycyBhcmUgcHJlc2VudCwgd2UnbGwgaGF2ZSBhIGhlYWRlciBcIjMgQW5zd2Vyc1wiXG4gICAgICAgICAgICAgICAgdmFyIGgyID0gJCgnI2Fuc3dlcnMtaGVhZGVyIC5hbnN3ZXJzLXN1YmhlYWRlciBoMicpO1xuICAgICAgICAgICAgICAgIHZhciBjbGllbnRDb3VudCA9IGgyLmRhdGEoJ2Fuc3dlcmNvdW50Jyk7XG4gICAgICAgICAgICAgICAgaWYgKGNsaWVudENvdW50ID09IG51bGwpXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgLy8gdHJ5IHRvIHBhcnNlIGZyb20gaHRtbFxuICAgICAgICAgICAgICAgICAgICAgY2xpZW50Q291bnQgPSBoMi50ZXh0KCkucmVwbGFjZSgvIGFuc3dlcnM/L2ksICcnKSB8fCAnMCc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9wdGlvbnMuZGF0YS5jbGllbnRDb3VudCA9IGNsaWVudENvdW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb3B0aW9ucy5kYXRhLmZrZXkgPSBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5O1xuICAgICAgICAgICAgbGFzdFBpbmdUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICByZXR1cm4gJC5hamF4KG9wdGlvbnMpLmFsd2F5cyhmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCdoZWFydGJlYXQnLCB7IGRldGFpbDogZGF0YSB9KTtcbiAgICAgICAgICAgICAgICB0aGF0LmpUZXh0YXJlYS5nZXQoMCkuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9KS5wcm9taXNlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIHNob3VsZFNlbmREcmFmdDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHlwZSAhPT0gXCJlZGl0XCIgJiYgbWFzdGVySGVhcnQgPT09IHRoaXM7XG4gICAgICAgIH0sXG4gICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChqc29uKSB7XG4gICAgICAgICAgICByZXN1bHRIYW5kbGVyc1t0aGlzLnR5cGVdKGpzb24sIHRoaXMpO1xuICAgICAgICAgICAgaWYgKGpzb24uZGlzYWJsZUVkaXRvcikge1xuICAgICAgICAgICAgICAgIGlmIChpc1N0YWNrc0VkaXRvcih0aGlzLmVkaXRvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IuZGlzYWJsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IuZGlzYWJsZVN1Ym1pc3Npb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5pc0Rpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChqc29uLmRyYWZ0U2F2ZWQpIHtcblxuICAgICAgICAgICAgICAgIGluZm9ybURyYWZ0U2F2ZWQodGhpcy5qVGV4dGFyZWEsIHRoaXMuZGlzY2FyZERyYWZ0TGluayk7XG5cbiAgICAgICAgICAgICAgICAvL3N1YmNvbW11bml0eSBhcnRpY2xlXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PSAnYXJ0aWNsZScgJiYgJCgnI2pzLXN1YmNvbW11bml0eS1zbHVnJykudmFsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0SWQgPSBqc29uLnBvc3RJZDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXZpc2lvbkd1aWQgPSBqc29uLnJldmlzaW9uR3VpZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9ICAgICAgIFxuICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLmJlYXRDb3VudCsrO1xuICAgICAgICAgICAgaW50ZXJ2YWxEZWx0YSA9IDA7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKCcjZHJhZnQtc2F2ZWQnKS5oaWRlKCk7XG4gICAgICAgICAgICBpZiAobWFzdGVySGVhcnQgPT09IHRoaXMpXG4gICAgICAgICAgICAgICAgcXVldWUudW5zaGlmdCh0aGlzKTtcbiAgICAgICAgICAgIGludGVydmFsRGVsdGEgPSAobmV3IERhdGUoKS5nZXRUaW1lKCkgJSAxMDApIC8gMTA7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzdGFydFRpbWVvdXQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBOb3RlOiBUaGlzIGZ1bmN0aW9uYWxpdHkgZG9lc24ndCBoYW5kbGUgbXVsdGlwbGUgZWRpdG9ycyB5ZXQ7IHdoaWNoIGlzIGZpbmUgdW50aWwgd2Ugc3RhcnRcbiAgICAvLyBzYXZpbmcgZHJhZnRzIGZvciBlZGl0cy5cbiAgICB2YXIgaW5mb3JtRHJhZnRTYXZlZCA9IGZ1bmN0aW9uIChqV21kLCBkaXNjYXJkTGluaykge1xuICAgICAgICB2YXIgakRyYWZ0ID0gJCgnI2RyYWZ0LXNhdmVkJyk7XG5cbiAgICAgICAgdmFyIGluZm9ybSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGpEcmFmdC50ZXh0KF9zKCdEcmFmdCBzYXZlZCcpKS5mYWRlSW4oJ2Zhc3QnKTtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoakRyYWZ0LmlzKCc6dmlzaWJsZScpKSB7XG4gICAgICAgICAgICBqRHJhZnQuZmFkZU91dCgnZmFzdCcsIGluZm9ybSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbmZvcm0oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkaXNjYXJkTGluaykge1xuICAgICAgICAgICAgZGlzY2FyZExpbmsucmVtb3ZlQ2xhc3MoJ2RubycpLnJlbW92ZUNsYXNzKCdkLW5vbmUnKS5zaG93KCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaGlkZURyYWZ0U2F2ZWQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC53aGljaCAhPSBLRVlfQ09ERS5GNCAvKkY0Ki8gfHwgIWV2ZW50LmN0cmxLZXkgfHwgZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgICAgICAgaldtZC51bmJpbmQoJ2tleXByZXNzJywgaGlkZURyYWZ0U2F2ZWQpO1xuICAgICAgICAgICAgICAgICQoJyNkcmFmdC1zYXZlZCcpLmZhZGVPdXQoJ2Zhc3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBqV21kLmJpbmQoJ2tleXByZXNzJywgaGlkZURyYWZ0U2F2ZWQpO1xuXG4gICAgICAgICQoJyNkcmFmdC1kaXNjYXJkZWQnKS5oaWRlKCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHVwZGF0ZUFuc3dlcnMocG9zdElkKSB7XG4gICAgICAgIHZhciBkaXZJZHNUb0FkZCA9IFtdO1xuXG4gICAgICAgIC8vIEZvciBub3cgKG5haXZlbHkpLCBmZXRjaCB0aGUgZW50aXJlIHBhZ2UgYWdhaW4uLlxuICAgICAgICAkLmdldCgnL3F1ZXN0aW9ucy8nICsgcG9zdElkLCBmdW5jdGlvbiAoaHRtbCkge1xuICAgICAgICAgICAgdmFyIGpIdG1sID0gJChodG1sKTtcblxuICAgICAgICAgICAgakh0bWwuZmluZCgnZGl2LmFuc3dlcicpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBpZCA9IHRoaXMuaWQuc3Vic3RyaW5nKCdhbnN3ZXItJy5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIGlmICgkKCcjYW5zd2VyLScgKyBpZCkubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZGl2SWRzVG9BZGQucHVzaCh0aGlzLmlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGRpdklkc1RvQWRkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3IgPSAnIycgKyBkaXZJZHNUb0FkZC5qb2luKCcsIycpO1xuICAgICAgICAgICAgICAgIHZhciBkaXZzID0gakh0bWwuZmluZChzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgdmFyIGFwcGVuZEFmdGVyID0gJCgnZGl2LmFuc3dlcjpsYXN0Jyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYXBwZW5kQWZ0ZXIubGVuZ3RoID09IDApXG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZEFmdGVyID0gJCgnI2Fuc3dlcnMtaGVhZGVyJyk7XG5cbiAgICAgICAgICAgICAgICBkaXZzLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBhcHBlbmRBZnRlci5hZnRlcihkaXZzKTtcbiAgICAgICAgICAgICAgICBkaXZzLmZhZGVJbignc2xvdycpO1xuXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBhbnN3ZXIgY291bnQuLi5cbiAgICAgICAgICAgICAgICB2YXIgbmV3SDIgPSBqSHRtbC5maW5kKCcjYW5zd2Vycy1oZWFkZXIgLmFuc3dlcnMtc3ViaGVhZGVyIGgyJyksIG9sZEgyID0gJCgnI2Fuc3dlcnMtaGVhZGVyIC5hbnN3ZXJzLXN1YmhlYWRlciBoMicpO1xuICAgICAgICAgICAgICAgIGlmIChuZXdIMi5sZW5ndGggJiYgb2xkSDIubGVuZ3RoKVxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb2xkSDIucmVwbGFjZVdpdGgobmV3SDIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFJlYmluZCBhbGwgY2xpY2sgaGFuZGxlcnMgb24gcGFnZS4uXG4gICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS52b3RlLmluaXQocG9zdElkKTtcbiAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmNvbW1lbnRzLmluaXQoeyBwb3N0OiBkaXZzIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBTdGFja0V4Y2hhbmdlLm5vdGlmeS5jbG9zZShub3RpZnlNZXNzYWdlVHlwZUlkKTtcbiAgICAgICAgICAgIGhhc0JlZW5Ob3RpZmllZE9mTmV3QW5zd2VyID0gZmFsc2U7XG4gICAgICAgIH0sICdodG1sJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkSGVhcnQodHlwZSwgalRleHRhcmVhLCBlZGl0b3IsIGRpc2NhcmREcmFmdExpbmssIGVkaXRJZCwgYXV0b0FjdGl2YXRlSGVhcnRiZWF0LCBtYXhIZWFydGJlYXRDb3VudCwgaGVhcnRiZWF0SW50ZXJ2YWwpIHtcbiAgICAgICAgdmFyIGhlYXJ0ID0gbmV3IEhlYXJ0KCksXG4gICAgICAgICAgICBwb3N0SWQ7XG5cbiAgICAgICAgaGVhcnQudHlwZSA9IHR5cGU7XG4gICAgICAgIGhlYXJ0LmpUZXh0YXJlYSA9IGpUZXh0YXJlYTtcbiAgICAgICAgaGVhcnQuZGlzY2FyZERyYWZ0TGluayA9IGRpc2NhcmREcmFmdExpbms7XG4gICAgICAgIGhlYXJ0Lm1heEhlYXJ0YmVhdENvdW50ID0gbWF4SGVhcnRiZWF0Q291bnQgfHwgZGVmYXVsdE1heEhlYXJ0YmVhdENvdW50O1xuXG4gICAgICAgIC8vT3ZlcnJpZGVuIHdpdGggZWFjaCBoZWFydCwgcXVldWVJbnRlcnZhbCBpcyByZWNhbGN1bGF0ZWQgb24gZWFjaCBiZWF0IHNvIHdlIGFsc28gc2F2ZSB0byBjdXN0b21IZWFydGJlYXRJbnRlcnZhbCB0byBrZWVwIG9yaWdpbmFsIHZhbFxuICAgICAgICBjdXN0b21IZWFydGJlYXRJbnRlcnZhbCA9IGhlYXJ0YmVhdEludGVydmFsIHx8IGRlZmF1bHRRdWV1ZUludGVydmFsO1xuICAgICAgICBxdWV1ZUludGVydmFsID0gaGVhcnRiZWF0SW50ZXJ2YWwgfHwgZGVmYXVsdFF1ZXVlSW50ZXJ2YWw7XG4gICAgICAgIFxuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJhc2tcIjpcbiAgICAgICAgICAgICAgICBwb3N0SWQgPSAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInN0YWdpbmdncm91bmRcIjpcbiAgICAgICAgICAgICAgICBwb3N0SWQgPSAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImFydGljbGVcIjpcbiAgICAgICAgICAgICAgICBwb3N0SWQgPSBlZGl0SWQ7XG4gICAgICAgICAgICAgICAgbGV0IHJldmlzaW9uR3VpZFNlbGVjdG9yID0gJCgnI2NsaWVudC1yZXZpc2lvbi1ndWlkJyk7XG4gICAgICAgICAgICAgICAgaWYgKHJldmlzaW9uR3VpZFNlbGVjdG9yLnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYXJ0LnJldmlzaW9uR3VpZCA9IHJldmlzaW9uR3VpZFNlbGVjdG9yLnZhbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJhbnN3ZXJcIjpcbiAgICAgICAgICAgICAgICBwb3N0SWQgPSAkKCcjcG9zdC1pZCcpLnZhbCgpIHx8IGxvY2F0aW9uLmhyZWYubWF0Y2goL1xcL3F1ZXN0aW9uc1xcLyhcXGQrKS9pKVsxXTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJlZGl0XCI6XG4gICAgICAgICAgICAgICAgcG9zdElkID0gZWRpdElkIHx8ICQoJyNwb3N0LWlkJykudmFsKCkgfHwgalRleHRhcmVhLmNsb3Nlc3QoJy5xdWVzdGlvbiwgLmFuc3dlcicpLmZpbmQoJy52b3RlIGlucHV0JykudmFsKCk7XG4gICAgICAgICAgICAgICAgdmFyIGlubGluZSA9IGpUZXh0YXJlYS5jbG9zZXN0KCcuaW5saW5lLXBvc3QnKTtcbiAgICAgICAgICAgICAgICB2YXIgcmV2aXNpb25HdWlkID0gbnVsbDtcblxuICAgICAgICAgICAgICAgIGlmIChpbmxpbmUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXZpc2lvbkd1aWQgPSBpbmxpbmVbMF0uYWN0aW9uLnNwbGl0KCcvJykucG9wKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghcmV2aXNpb25HdWlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldmlzaW9uR3VpZCA9ICQoJyNjbGllbnQtcmV2aXNpb24tZ3VpZCcpLnZhbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBoZWFydC5yZXZpc2lvbkd1aWQgPSByZXZpc2lvbkd1aWQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwibW9kZXJhdG9ybWVzc2FnZVwiOlxuICAgICAgICAgICAgICAgIHBvc3RJZCA9ICskKFwiI21vZGVyYXRvci1tZXNzYWdlLXRvLXVzZXJcIikuYXR0cignZGF0YS11c2VyaWQnKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBoZWFydC5wb3N0SWQgPSBwb3N0SWQ7XG4gICAgICAgIGhlYXJ0LmVkaXRvciA9IGVkaXRvcjtcblxuICAgICAgICBqVGV4dGFyZWEub24oXCJrZXlwcmVzcyBwYXN0ZSBpbnB1dFwiLCBmdW5jdGlvbiAoKSB7IGhlYXJ0LmFjdGl2YXRlKCk7IH0pO1xuXG4gICAgICAgIGlmIChhdXRvQWN0aXZhdGVIZWFydGJlYXQpIHtcbiAgICAgICAgICAgIGhlYXJ0LmFjdGl2YXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBUaGUgbmFtZSBvZiB0aGlzIG1ldGhvZCByZWFsbHkgaW1wbGllcyBvbmx5SWZTYXZpbmdEcmFmdD10cnVlOyBjaGVjayB3aGV0aGVyIGFueSB1c2Ugb2YgaXQgYXNzdW1lcyBkaWZmZXJlbnRseVxuICAgIGZ1bmN0aW9uIGVuc3VyZURyYWZ0U2F2ZWQoY2FsbGJhY2ssIG9ubHlJZlNhdmluZ0RyYWZ0KSB7XG4gICAgICAgIGlmICghbWFzdGVySGVhcnQgfHwgIW1hc3RlckhlYXJ0LmNoZWNrQWN0aXZlKCkpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbWFzdGVySGVhcnQuYmVhdChvbmx5SWZTYXZpbmdEcmFmdCkuZG9uZShjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYmVhdEFTQVAoKSB7XG4gICAgICAgIHN0YXJ0VGltZW91dCgxKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3RpZmllZE9mTmV3QW5zd2VyKCkge1xuICAgICAgICBoYXNCZWVuTm90aWZpZWRPZk5ld0Fuc3dlciA9IHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNIZWFydEJlYXRpbmcoKSB7XG4gICAgICAgIGlmIChhY3RpdmVIZWFydHMgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWN0aXZlSGVhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoYWN0aXZlSGVhcnRzW2ldLmNoZWNrQWN0aXZlKCkgPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB7IGFkZEhlYXJ0OiBhZGRIZWFydCwgZW5zdXJlRHJhZnRTYXZlZDogZW5zdXJlRHJhZnRTYXZlZCwgYmVhdEFTQVA6IGJlYXRBU0FQLCBub3RpZmllZE9mTmV3QW5zd2VyOiBub3RpZmllZE9mTmV3QW5zd2VyLCBpc0hlYXJ0QmVhdGluZzogaXNIZWFydEJlYXRpbmcgfTtcblxufSkoKTtcbiIsIlxuLy8gVE9ETzogVGhpcyBjYW4ndCBoYW5kbGUgbXVsdGlwbGUgZWRpdG9ycyBpbiBhIHBhZ2UgeWV0XG5TdGFja0V4Y2hhbmdlLm5hdlByZXZlbnRpb24gPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBfaklucHV0LCBvcmlnQ29udGVudHMsIGVkaXRvckluc3RhbmNlLCBvcmlnRWRpdG9yQ29udGVudHM7XG5cbiAgICAvLyByZXR1cm5zIHRydWUgaWYgYW55IG9mIHRoZSBpbnB1dCBlbGVtZW50cycgY29udGVudHMgaGF2ZSBjaGFuZ2VkXG4gICAgdmFyIGFjdHVhbENoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICBfaklucHV0LmVhY2goZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwgKCQodGhpcykudmFsKCkucmVwbGFjZSgvXFxzKyQvZywgJycpICE9PSBvcmlnQ29udGVudHNbaW5kZXhdLnJlcGxhY2UoL1xccyskL2csICcnKSk7IC8vIGlnbm9yZSB0cmFpbGluZyB3aGl0ZXNwYWNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChlZGl0b3JJbnN0YW5jZSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IChlZGl0b3JJbnN0YW5jZS5jb250ZW50LnJlcGxhY2UoL1xccyskL2csICcnKSAhPT0gb3JpZ0VkaXRvckNvbnRlbnRzLnJlcGxhY2UoL1xccyskL2csICcnKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHZhciBzZXRDb25maXJtVW5sb2FkID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgLy8gd2hlbiBtZXNzYWdlIGlzIG51bGwsIHVuYmluZCwgb3RoZXJ3aXNlIGFsc28gY2hlY2sgdGhhdCBvdXIgaW5wdXQgaGFzIGFjdHVhbGx5IGJlZW4gY2hhbmdlZCBiZWZvcmUgc2hvd2luZyB0aGUgY29uZmlybSB1bmxvYWQgbWVzc2FnZVxuICAgICAgICB3aW5kb3cub25iZWZvcmV1bmxvYWQgPSBtZXNzYWdlID8gZnVuY3Rpb24gKCkgeyBpZiAoX2pJbnB1dCAmJiBhY3R1YWxDaGFuZ2UoKSkgcmV0dXJuIG1lc3NhZ2U7IH0gOiBudWxsO1xuICAgIH1cblxuICAgIHZhciBoYW5kbGVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZXRDb25maXJtVW5sb2FkKF9zKFwiWW91IGhhdmUgc3RhcnRlZCB3cml0aW5nIG9yIGVkaXRpbmcgYSBwb3N0LlwiKSk7XG4gICAgfTtcblxuICAgIHZhciB1cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghX2pJbnB1dClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBvcmlnQ29udGVudHMgPSBbXTtcblxuICAgICAgICBfaklucHV0LmVhY2goZnVuY3Rpb24gKCkgeyBvcmlnQ29udGVudHMucHVzaCgkKHRoaXMpLnZhbCgpKTsgfSk7XG5cbiAgICAgICAgaWYgKGVkaXRvckluc3RhbmNlKSB7XG4gICAgICAgICAgICBvcmlnRWRpdG9yQ29udGVudHMgPSBlZGl0b3JJbnN0YW5jZS5jb250ZW50O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgaW5pdDogZnVuY3Rpb24gKGpJbnB1dCwgc3RhY2tzRWRpdG9ySW5zdGFuY2UpIHtcbiAgICAgICAgICAgIF9qSW5wdXQgPSBqSW5wdXQub25lKFwia2V5cHJlc3NcIiwgaGFuZGxlcik7XG4gICAgICAgICAgICBvcmlnQ29udGVudHMgPSBbXTtcblxuICAgICAgICAgICAgaWYgKHN0YWNrc0VkaXRvckluc3RhbmNlICYmIFwiY29udGVudFwiIGluIHN0YWNrc0VkaXRvckluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgJChzdGFja3NFZGl0b3JJbnN0YW5jZS50YXJnZXQpLm9uZShcImtleXByZXNzXCIsIGhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIGVkaXRvckluc3RhbmNlID0gc3RhY2tzRWRpdG9ySW5zdGFuY2U7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVwZGF0ZSgpO1xuICAgICAgICB9LFxuICAgICAgICBzdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAoX2pJbnB1dCkge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgc3RvcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCFfaklucHV0KVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIF9qSW5wdXQudW5iaW5kKFwia2V5cHJlc3NcIiwgaGFuZGxlcik7XG4gICAgICAgICAgICBzZXRDb25maXJtVW5sb2FkKG51bGwpO1xuICAgICAgICAgICAgX2pJbnB1dCA9IG51bGw7XG4gICAgICAgIH0sXG4gICAgICAgIHBhdXNlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoX2pJbnB1dCkge1xuICAgICAgICAgICAgICAgIHNldENvbmZpcm1VbmxvYWQobnVsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpcm06IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAoX2pJbnB1dCAmJiBhY3R1YWxDaGFuZ2UoKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlybShtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBoYXNDaGFuZ2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfaklucHV0ICYmIGFjdHVhbENoYW5nZSgpO1xuICAgICAgICB9LFxuICAgICAgICB1cGRhdGU6IHVwZGF0ZVxuICAgIH07XG59KSgpO1xuIiwiXG4vLyBCRUdJTjoganF1ZXJ5LnRleHRhcmVhcmVzaXplci5qc1xuLyogXG5qUXVlcnkgVGV4dEFyZWFSZXNpemVyIHBsdWdpblxuQ3JlYXRlZCBvbiAxN3RoIEphbnVhcnkgMjAwOCBieSBSeWFuIE8nRGVsbCBcblZlcnNpb24gMS4wLjRcbiAgICBcbkNvbnZlcnRlZCBmcm9tIERydXBhbCAtPiB0ZXh0YXJlYS5qc1xuRm91bmQgc291cmNlOiBodHRwOi8vcGx1Z2lucy5qcXVlcnkuY29tL21pc2MvdGV4dGFyZWEuanNcbiRJZDogdGV4dGFyZWEuanMsdiAxLjExLjIuMSAyMDA3LzA0LzE4IDAyOjQxOjE5IGRydW1tIEV4cCAkXG5cbjEuMC4xIFVwZGF0ZXMgdG8gbWlzc2luZyBnbG9iYWwgJ3ZhcicsIGFkZGVkIGV4dHJhIGdsb2JhbCB2YXJpYWJsZXMsIGZpeGVkIG11bHRpcGxlIGluc3RhbmNlcywgaW1wcm92ZWQgaUZyYW1lIHN1cHBvcnRcbjEuMC4yIFVwZGF0ZXMgYWNjb3JkaW5nIHRvIHRleHRhcmVhLmZvY3VzXG4xLjAuMyBGdXJ0aGVyIHVwZGF0ZXMgaW5jbHVkaW5nIHJlbW92aW5nIHRoZSB0ZXh0YXJlYS5mb2N1cyBhbmQgbW92aW5nIHByaXZhdGUgdmFyaWFibGVzIHRvIHRvcFxuMS4wLjQgUmUtaW5zdGF0ZWQgdGhlIGJsdXIvZm9jdXMgZXZlbnRzLCBhY2NvcmRpbmcgdG8gaW5mb3JtYXRpb24gc3VwcGxpZWQgYnkgZGVjXG4xLjAuNSBGaXhlZCBhIGJ1ZyBpbiBkeW5hbWljIGh0bWwgYW5kIElFNyAtIEdlb2ZmIERhbGdhc1xuICAgIFxuKi9cbihmdW5jdGlvbiAoJCkge1xuICAgIC8qIHByaXZhdGUgdmFyaWFibGUgXCJvSG92ZXJcIiB1c2VkIHRvIGRldGVybWluZSBpZiB5b3UncmUgc3RpbGwgaG92ZXJpbmcgb3ZlciB0aGUgc2FtZSBlbGVtZW50ICovXG4gICAgdmFyIHRleHRhcmVhLCBzdGF0aWNPZmZzZXQ7ICAvLyBhZGRlZCB0aGUgdmFyIGRlY2xhcmF0aW9uIGZvciAnc3RhdGljT2Zmc2V0JyB0aGFua3MgdG8gaXNzdWUgbG9nZ2VkIGJ5IGRlYy5cbiAgICB2YXIgaUxhc3RNb3VzZVBvcyA9IDA7XG4gICAgdmFyIGlNaW4gPSAzMjtcbiAgICB2YXIgZ3JpcDtcbiAgICAvKiBUZXh0QXJlYVJlc2l6ZXIgcGx1Z2luICovXG4gICAgJC5mbi5UZXh0QXJlYVJlc2l6ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGV4dGFyZWEgPSAkKHRoaXMpLmFkZENsYXNzKCdwcm9jZXNzZWQnKTtcbiAgICAgICAgICAgIHN0YXRpY09mZnNldCA9IG51bGw7XG5cbiAgICAgICAgICAgIC8vIDE4LTAxLTA4IGpRdWVyeSBiaW5kIHRvIHBhc3MgZGF0YSBlbGVtZW50IHJhdGhlciB0aGFuIGRpcmVjdCBtb3VzZWRvd24gLSBSeWFuIE8nRGVsbFxuICAgICAgICAgICAgLy8gV2hlbiB3cmFwcGluZyB0aGUgdGV4dCBhcmVhLCB3b3JrIGFyb3VuZCBhbiBJRSBtYXJnaW4gYnVnLiAgU2VlOlxuICAgICAgICAgICAgLy8gaHR0cDovL2phc3Bhbi5jb20vaWUtaW5oZXJpdGVkLW1hcmdpbi1idWctZm9ybS1lbGVtZW50cy1hbmQtaGFzbGF5b3V0XG4gICAgICAgICAgICAkKHRoaXMpLnBhcmVudCgpLmFwcGVuZCgkKCc8ZGl2IGNsYXNzPVwiZ3JpcHBpZSBiYnItc21cIj48L2Rpdj4nKS5iaW5kKFwibW91c2Vkb3duXCIsIHsgZWw6IHRoaXMgfSwgc3RhcnREcmFnKSk7XG5cbiAgICAgICAgICAgIHZhciBncmlwcGllID0gJCgnZGl2LmdyaXBwaWUnLCAkKHRoaXMpLnBhcmVudCgpKVswXTtcbiAgICAgICAgICAgIGdyaXBwaWUuc3R5bGUubWFyZ2luUmlnaHQgPSAoZ3JpcHBpZS5vZmZzZXRXaWR0aCAtICQodGhpcylbMF0ub2Zmc2V0V2lkdGgpICsgJ3B4JztcblxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8qIHByaXZhdGUgZnVuY3Rpb25zICovXG4gICAgZnVuY3Rpb24gc3RhcnREcmFnKGUpIHtcbiAgICAgICAgdGV4dGFyZWEgPSAkKGUuZGF0YS5lbCk7XG4gICAgICAgIHRleHRhcmVhLmJsdXIoKTtcbiAgICAgICAgaUxhc3RNb3VzZVBvcyA9IG1vdXNlUG9zaXRpb24oZSkueTtcbiAgICAgICAgc3RhdGljT2Zmc2V0ID0gdGV4dGFyZWEuaGVpZ2h0KCkgLSBpTGFzdE1vdXNlUG9zO1xuICAgICAgICAkKGRvY3VtZW50KS5tb3VzZW1vdmUocGVyZm9ybURyYWcpLm1vdXNldXAoZW5kRHJhZyk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZXJmb3JtRHJhZyhlKSB7XG4gICAgICAgIHZhciBpVGhpc01vdXNlUG9zID0gbW91c2VQb3NpdGlvbihlKS55O1xuICAgICAgICB2YXIgaU1vdXNlUG9zID0gc3RhdGljT2Zmc2V0ICsgaVRoaXNNb3VzZVBvcztcbiAgICAgICAgaWYgKGlMYXN0TW91c2VQb3MgPj0gKGlUaGlzTW91c2VQb3MpKSB7XG4gICAgICAgICAgICBpTW91c2VQb3MgLT0gNTtcbiAgICAgICAgfVxuICAgICAgICBpTGFzdE1vdXNlUG9zID0gaVRoaXNNb3VzZVBvcztcbiAgICAgICAgaU1vdXNlUG9zID0gTWF0aC5tYXgoaU1pbiwgaU1vdXNlUG9zKTtcbiAgICAgICAgdGV4dGFyZWEuaGVpZ2h0KGlNb3VzZVBvcyArICdweCcpO1xuICAgICAgICBpZiAoaU1vdXNlUG9zIDwgaU1pbikge1xuICAgICAgICAgICAgZW5kRHJhZyhlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZW5kRHJhZyhlKSB7XG4gICAgICAgICQoZG9jdW1lbnQpLnVuYmluZCgnbW91c2Vtb3ZlJywgcGVyZm9ybURyYWcpLnVuYmluZCgnbW91c2V1cCcsIGVuZERyYWcpO1xuICAgICAgICB0ZXh0YXJlYS5mb2N1cygpO1xuICAgICAgICB0ZXh0YXJlYSA9IG51bGw7XG4gICAgICAgIHN0YXRpY09mZnNldCA9IG51bGw7XG4gICAgICAgIGlMYXN0TW91c2VQb3MgPSAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vdXNlUG9zaXRpb24oZSkge1xuICAgICAgICByZXR1cm4geyB4OiBlLmNsaWVudFggKyBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCwgeTogZS5jbGllbnRZICsgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB9O1xuICAgIH1cbn0pKGpRdWVyeSk7XG5cbi8vIEVORDoganF1ZXJ5LnRleHRhcmVhcmVzaXplci5qc1xuXG4iLCJTdGFja0V4Y2hhbmdlLnBvc3RWYWxpZGF0aW9uID0gKGZ1bmN0aW9uICgpIHtcblxuICAgIHZhciBvbkFza1BhZ2VWMiA9ICQoJ2JvZHknKS5oYXNDbGFzcygnanMtYXNrLXBhZ2UtdjInKTtcbiAgICB2YXIgb25Bc2tXaXphcmQgPSAkKCdib2R5JykuaGFzQ2xhc3MoJ2pzLXN0YWdpbmctZ3JvdW5kLXdpemFyZCcpO1xuXG4gICAgLy8gVGhlc2UgY29ycmVzcG9uZCB0byBkaWZmZXJlbnQgdmFsdWVzIG9mIFBvc3RWYWxpZGF0aW9uRXJyb3JMb2NhdGlvblxuICAgIHZhciBUaXRsZUZpZWxkID0gJ1RpdGxlJztcbiAgICB2YXIgQm9keUZpZWxkID0gJ0JvZHknO1xuICAgIHZhciBUYWdzRmllbGQgPSAnVGFncyc7XG4gICAgdmFyIE1lbnRpb25zRmllbGQgPSAnTWVudGlvbnMnO1xuICAgIHZhciBFZGl0Q29tbWVudEZpZWxkID0gJ0VkaXRDb21tZW50JztcbiAgICB2YXIgRXhjZXJwdEZpZWxkID0gJ0V4Y2VycHQnO1xuICAgIHZhciBFbWFpbEZpZWxkID0gJ0VtYWlsJztcbiAgICB2YXIgR2VuZXJhbEZpZWxkID0gJ0dlbmVyYWwnO1xuICAgIHZhciBBcnRpY2xlVHlwZUZpZWxkID0gJ0FydGljbGVUeXBlJztcbiAgICB2YXIgRGF0ZUZpZWxkID0gJ0RhdGUnO1xuICAgIHZhciBDb21tZW50Rm9ybUZpZWxkID0gJ0NvbW1lbnRGb3JtJztcbiAgICB2YXIgU3VidGl0bGVGaWVsZCA9ICdTdWJ0aXRsZSc7XG4gICAgdmFyIEN0YUxhYmVsRmllbGQgPSAnQ3RhTGFiZWwnO1xuICAgIHZhciBDdGFVcmxGaWVsZCA9ICdDdGFVcmwnO1xuICAgIHZhciBUYXJnZXRVcmxGaWVsZCA9ICdUYXJnZXRVcmwnO1xuXG4gICAgLy8gVGhpcyBpcyB1c2VkIGZvciBgLmRhdGEoKWAgb24gZm9ybSBmaWVsZHMgdG8gZGlzYWJsZSByZS12YWxpZGF0aW9uIG9uIGJsdXIgdW50aWwgYSBjaGFuZ2VcbiAgICAvLyBoYXMgYmVlbiBtYWRlLiBGb3IgZXhhbXBsZSwgYW4gZW1wdHkgdGl0bGUgZmllbGQgaXMgYW4gZXJyb3Igb24gc3VibWlzc2lvbiB2YWxpZGF0aW9uLCBidXQgb2theVxuICAgIC8vIG9uIGJsdXIgdmFsaWRhdGlvbi4gSWYgeW91IHRyeSB0byBzdWJtaXQgYW4gZW1wdHkgdGl0bGUsIHRoZSB2YWxpZGF0aW9uIGVycm9yIG1lc3NhZ2Ugc2hvdWxkbid0XG4gICAgLy8gZGlzYXBwZWFyIHVudGlsIHlvdSd2ZSBhY3R1YWxseSBtYWRlIGEgY2hhbmdlLlxuICAgIGNvbnN0IERJU0FCTEVfQkxVUl9WQUxJREFUSU9OX0tFWSA9IFwiZGlzYWJsZS1ibHVyLXZhbGlkYXRpb25cIjtcblxuICAgIC8vIFRoaXMgc2VsZWN0cyB0aGUgaW5wdXQgaW4gdGhlIGNvbnRhaW5lciB0aGF0IGFyZSBhY3R1YWwgZm9ybSBlbGVtZW50cyBgPGlucHV0PmAgYW5kIHN1Y2ggdGhhdCB3aWxsIGJlIHNlbnQgdG8gdGhlIHNlcnZlci5cbiAgICBmdW5jdGlvbiBnZXRGb3JtSW5wdXQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgcHJvcGVydHkpIHtcblxuICAgICAgICB2YXIgZmllbGRTZWxlY3RvcnMgPSB7XG4gICAgICAgICAgICAnVGl0bGUnOiAnLmpzLXBvc3QtdGl0bGUtZmllbGQnLFxuICAgICAgICAgICAgJ0JvZHknOiAnLmpzLXBvc3QtYm9keS1maWVsZFtkYXRhLXBvc3QtdHlwZS1pZD0nICsgcG9zdFR5cGVJZCArICddJywgLy8gdXNlIHBvc3RUeXBlSWQgdG8gaGFuZGxlIFwiQW5zd2VyIHlvdXIgb3duIHF1ZXN0aW9uXCJcbiAgICAgICAgICAgICdUYWdzJzogJy5qcy1wb3N0LXRhZ3MtZmllbGQnLFxuICAgICAgICAgICAgJ01lbnRpb25zJzogJy5qcy1wb3N0LW1lbnRpb25zLWZpZWxkJyxcbiAgICAgICAgICAgICdFZGl0Q29tbWVudCc6ICcuanMtcG9zdC1lZGl0LWNvbW1lbnQtZmllbGQnLCAvLyBtdXN0IG1hdGNoIHJlZ3VsYXIgZWRpdCBjb21tZW50cywgYXMgd2VsbCBhcyB0YWcgd2lraSBlZGl0IGNvbW1lbnRzXG4gICAgICAgICAgICAnRXhjZXJwdCc6ICcuanMtcG9zdC1leGNlcnB0LWZpZWxkJyxcbiAgICAgICAgICAgICdFbWFpbCc6ICcuanMtcG9zdC1lbWFpbC1maWVsZCcsXG4gICAgICAgICAgICAnQXJ0aWNsZVR5cGUnOiAnLmpzLWFydGljbGUtdHlwZS1maWVsZCcsXG4gICAgICAgICAgICAnRGF0ZSc6ICcuanMtcG9zdC1kYXRlLWZpZWxkJyxcbiAgICAgICAgICAgICdDb21tZW50Rm9ybSc6ICcuanMtY29tbWVudC10ZXh0LWlucHV0JyxcbiAgICAgICAgICAgICdTdWJ0aXRsZSc6ICcuanMtcG9zdC1zdWJ0aXRsZS1maWVsZCcsXG4gICAgICAgICAgICAnQ3RhTGFiZWwnOiAnLmpzLXBvc3QtY3RhLWxhYmVsLWZpZWxkJyxcbiAgICAgICAgICAgICdDdGFVcmwnOiAnLmpzLXBvc3QtY3RhLXVybC1maWVsZCcsXG4gICAgICAgICAgICAnVGFyZ2V0VXJsJyA6ICcuanMtdGFyZ2V0LXVybCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyICRlbCA9IGZpZWxkU2VsZWN0b3JzW3Byb3BlcnR5XVxuICAgICAgICAgICAgPyAkY29udGFpbmVyLmZpbmQoZmllbGRTZWxlY3RvcnNbcHJvcGVydHldKVxuICAgICAgICAgICAgOiAkKCk7XG5cbiAgICAgICAgcmV0dXJuICRlbFxuICAgIH1cblxuICAgIC8vIFRoaXMgc2VsZWN0cyB0aGUgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIGEgZm9ybSBlbGVtZW50IHRoYXQgdGhlIHVzZXIgd2lsbCBpbnRlcmFjdCB3aXRoLiAgRm9yIHRoZSBtb3N0IHBhcnQgdGhleSBhcmUgdGhlIHNhbWUsXG4gICAgLy8gYnV0IGZvciB0YWcgYW5kIG1lbnRpb24gZmllbGRzLCB0aGV5IHdpbGwgYmUgdGhlIHRhZyBlZGl0b3IgY29tcG9uZW50LlxuICAgIGZ1bmN0aW9uIGdldFZpc2libGVGaWVsZCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBwcm9wZXJ0eSkge1xuICAgICAgICB2YXIgJGVsID0gZ2V0Rm9ybUlucHV0KCRjb250YWluZXIsIHBvc3RUeXBlSWQsIHByb3BlcnR5KTtcbiAgICAgICAgaWYgKHByb3BlcnR5ID09PSBUYWdzRmllbGQgfHwgcHJvcGVydHkgPT09IE1lbnRpb25zRmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiAkY29udGFpbmVyLmZpbmQoJy5qcy10YWctZWRpdG9yJykuZmlsdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJCh0aGlzKS5kYXRhKCd0YXJnZXQtZmllbGQnKSA9PT0gJGVsLmdldCgwKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICRlbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBibHVyVGltZW91dElkcyA9IFtdO1xuICAgIHZhciBibHVyVGltZW91dERlbGF5ID0gMjUwO1xuXG4gICAgZnVuY3Rpb24gaW5pdE9uQmx1cigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgaXNTdWdnZXN0ZWRFZGl0KSB7XG5cbiAgICAgICAgLy8gVGVtcG9yYXJpbHkgZGlzYWJsZSBhbGwgc3VibWl0IGJ1dHRvbnMgd2hpbGUgd2Ugd2FpdCBmb3IgdGhlIHRhZyBlZGl0b3IgdG8gbG9hZC5cbiAgICAgICAgY29uc3QgJHN1Ym1pdCA9ICRjb250YWluZXIuZmluZCgnaW5wdXRbdHlwZT1cInN1Ym1pdFwiXTp2aXNpYmxlLCBidXR0b25bdHlwZT1cInN1Ym1pdFwiXTp2aXNpYmxlJyk7XG4gICAgICAgIGNvbnN0IHdhc0VuYWJsZWQgPSAkc3VibWl0LmZpbHRlcihcIjplbmFibGVkXCIpO1xuICAgICAgICB3YXNFbmFibGVkLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cbiAgICAgICAgaW5pdFRpdGxlVmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSk7XG4gICAgICAgIGluaXRCb2R5VmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgaXNTdWdnZXN0ZWRFZGl0KTtcbiAgICAgICAgaW5pdEVkaXRDb21tZW50VmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSk7XG4gICAgICAgIGluaXRFeGNlcnB0VmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSk7XG4gICAgICAgIGluaXRFbWFpbFZhbGlkYXRpb24oJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUpO1xuXG4gICAgICAgIHdoZW5UYWdFZGl0b3JJc0RvbmVMb2FkaW5nKCRjb250YWluZXIsIHBvc3RUeXBlSWQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGluaXRUYWdzVmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSk7XG4gICAgICAgICAgICB3YXNFbmFibGVkLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbml0T25CbHVyQW5kU3VibWl0KCRmb3JtLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgaXNTdWdnZXN0ZWRFZGl0LCBvcHRpb25hbFN1Y2Nlc3NDYWxsYmFjaykge1xuICAgICAgICBpbml0T25CbHVyKCRmb3JtLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgaXNTdWdnZXN0ZWRFZGl0KTtcblxuICAgICAgICB2YXIgc3VibWl0Q2FsbGJhY2sgPSBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICAgICAgbGV0IGlzUmVkaXJlY3RpbmcgPSBmYWxzZTtcblxuICAgICAgICAgICAgJGZvcm0udHJpZ2dlcigncG9zdDpzdWJtaXQtY29tcGxldGVkJywgW3tcbiAgICAgICAgICAgICAgICBmb3JtVHlwZTogZm9ybVR5cGUsXG4gICAgICAgICAgICAgICAgcG9zdFR5cGVJZDogcG9zdFR5cGVJZCxcbiAgICAgICAgICAgICAgICByZXNwb25zZToganNvbixcbiAgICAgICAgICAgIH1dKTtcblxuICAgICAgICAgICAgaWYgKGpzb24uc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25hbFN1Y2Nlc3NDYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25hbFN1Y2Nlc3NDYWxsYmFjayhqc29uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZnJvbSA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF07XG4gICAgICAgICAgICAgICAgICAgIHZhciB0byA9IGpzb24ucmVkaXJlY3RUby5zcGxpdCgnIycpWzBdO1xuICAgICAgICAgICAgICAgICAgICBpZiAodG8uaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0byA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgKyB0bztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGFscmVhZHkgY2FsbGVkIG5hdlByZXZlbnRpb24ucGF1c2UoKSBidXQgU2FmYXJpIGlzIHN0aWxsIGdldHRpbmcgdGhlIHBvcHVwLlxuICAgICAgICAgICAgICAgICAgICAvLyBMZXQncyBibGFzdCB0aGlzIGFuZCBob3BlIGZvciB0aGUgYmVzdC5cbiAgICAgICAgICAgICAgICAgICAgd2luZG93Lm9uYmVmb3JldW5sb2FkID0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICBpc1JlZGlyZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0ganNvbi5yZWRpcmVjdFRvO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gcmVkaXJlY3RpbmcgdG8gdGhlIHNhbWUgdXJsIChvciBhIGRpZmZlcmVudCB1cmwsIGRpZmZlcmluZyBvbmx5IGJ5IHRoZSBoYXNoKSBzdWNoIGFzIHRoZSBjYXNlIHdpdGggI2F1dG9jb21tZW50LFxuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGV4cGxpY2l0bHkgcmVsb2FkIHRoZSBwYWdlLCBzaW5jZSBzZXR0aW5nIHdpbmRvdy5sb2NhdGlvbiBhbG9uZSB3b24ndCBkbyB0aGUgdHJpY2suXG4gICAgICAgICAgICAgICAgICAgIGlmIChmcm9tLnRvTG93ZXJDYXNlKCkgPT09IHRvLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGpzb24uY2FwdGNoYUh0bWwpIHtcbiAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLm5vY2FwdGNoYS5pbml0KGpzb24uY2FwdGNoYUh0bWwsIHN1Ym1pdENhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoanNvbi5lcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAkZm9ybS5maW5kKCcuanMtcG9zdC1wcmlvci1hdHRlbXB0LWNvdW50JykudmFsKGZ1bmN0aW9uKF8sIHZhbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCgrdmFsICsgMSkgfHwgMCkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzaG93RXJyb3JzQWZ0ZXJTdWJtaXNzaW9uKCRmb3JtLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwganNvbi5lcnJvcnMsIGpzb24ud2FybmluZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2hvd1N1Ym1pc3Npb25FcnJvck1lc3NhZ2UoJGZvcm0sIHBvc3RUeXBlSWQsIGZvcm1UeXBlLCB7IEdlbmVyYWw6IFskKCc8c3Bhbi8+JykudGV4dChqc29uLm1lc3NhZ2UpLmh0bWwoKV0gfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNsZWFuVXBBZnRlclN1Ym1pdCgkZm9ybSwgaXNSZWRpcmVjdGluZyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgJGZvcm0uc3VibWl0KGZ1bmN0aW9uIChzdWJtaXRFdmVudCkge1xuICAgICAgICAgICAgaWYgKCRmb3JtLmZpbmQoJy5qcy1wb3N0LWFuc3dlci13aGlsZS1hc2tpbmctY2hlY2tib3gnKS5pcygnOmNoZWNrZWQnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBkb24ndCBhamF4aWZ5IGFuc3dlcmluZyB3aGlsZSBhc2tpbmdcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlamVjdFN5c3RlbUVkaXRDb21tZW50KCRmb3JtLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSkpIHtcbiAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmhlbHBlcnMuZW5hYmxlU3VibWl0QnV0dG9uKCRmb3JtKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNsZWFyQmx1clRpbWVvdXRzKCk7XG5cbiAgICAgICAgICAgIGlmIChTdGFja0V4Y2hhbmdlLm5hdlByZXZlbnRpb24pIHtcbiAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLm5hdlByZXZlbnRpb24uc3RvcCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkZm9ybS5maW5kKCdpbnB1dFt0eXBlPVwic3VibWl0XCJdOnZpc2libGUsIGJ1dHRvblt0eXBlPVwic3VibWl0XCJdJykuYWRkQ2xhc3MoJ2lzLWxvYWRpbmcnKTtcbiAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaGVscGVycy5kaXNhYmxlU3VibWl0QnV0dG9uKCRmb3JtKTtcblxuICAgICAgICAgICAgLy8gd2UgZG9uJ3QgYWxsb3cgdGFnIGNyZWF0aW9uIGZvciBhbm5vdW5jZW1lbnRzIG9yIGRpc2N1c3Npb25zXG4gICAgICAgICAgICBpZiAoU3RhY2tFeGNoYW5nZS5vcHRpb25zLnNpdGUuZW5hYmxlTmV3VGFnQ3JlYXRpb25XYXJuaW5nICYmIHBvc3RUeXBlSWQgIT0gMTQgJiYgcG9zdFR5cGVJZCAhPSAxNSkge1xuICAgICAgICAgICAgICAgIHZhciAkdGFncyA9IGdldEZvcm1JbnB1dCgkZm9ybSwgcG9zdFR5cGVJZCwgVGFnc0ZpZWxkKTtcbiAgICAgICAgICAgICAgICB2YXIgb2xkdGFncyA9ICR0YWdzLnByb3AoJ2RlZmF1bHRWYWx1ZScpO1xuICAgICAgICAgICAgICAgIGlmICgkdGFncy52YWwoKSAhPT0gb2xkdGFncykge1xuICAgICAgICAgICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0dFVCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICcvcG9zdHMvbmV3LXRhZ3Mtd2FybmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3M6ICR0YWdzLnZhbCgpXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24oanNvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uLnNob3dXYXJuaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb2RhbFNldHRpbmdzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VPdGhlcnM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93bjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJy5qcy1jb25maXJtLXRhZy1jcmVhdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVzZSAnc3VibWl0JyBhcyB0aGUgY2xvc2UgdHJpZ2dlciBzbyB0aGF0IHdlIGNhbiBkZXRlY3QgaXQgaW4gZGlzbWlzc2luZygpIGJlbG93XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UuaGVscGVycy5jbG9zZVBvcHVwcyhudWxsLCBcInN1Ym1pdFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9TdWJtaXQoJGZvcm0sIHBvc3RUeXBlSWQsIGZvcm1UeXBlLCBzdWJtaXRDYWxsYmFjaywgc3VibWl0RXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNtaXNzaW5nOiBmdW5jdGlvbiAoY2xvc2VUcmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGNsb3NlVHJpZ2dlciBpcyAnc3VibWl0JyB3ZSBhcmUgb24gdGhlIHN1Y2Nlc3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXRoIGFuZCB3aWxsIHRoZXJlZm9yZSByZWRpcmVjdC4gSW4gdGhhdCBjYXNlIHdlIHNob3VsZG4ndFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVuYWJsZSB0aGUgc3VibWl0IGJ1dHRvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhblVwQWZ0ZXJTdWJtaXQoJGZvcm0sIGNsb3NlVHJpZ2dlciA9PT0gXCJzdWJtaXRcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuRWxlbWVudHM6IGdldFZpc2libGVGaWVsZCgkZm9ybSwgcG9zdFR5cGVJZCwgVGFnc0ZpZWxkKS5maW5kKCdpbnB1dDp2aXNpYmxlJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmhlbHBlcnMuc2hvd01vZGFsKCQoanNvbi5odG1sKS5lbGVtZW50Tm9kZXNPbmx5KCksIG1vZGFsU2V0dGluZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmhlbHBlcnMuYmluZE1vdmFibGVQb3B1cHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb1N1Ym1pdCgkZm9ybSwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHN1Ym1pdENhbGxiYWNrLCBzdWJtaXRFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZG8gdGhlIHN1Ym1pc3Npb24gaW4gbmV4dFRpY2ssIHNvIHRoYXQgYW55dGhpbmcgZWxzZSB0aGF0IGhhcyBhdHRhY2hlZCBpdHNlbGZcbiAgICAgICAgICAgIC8vIHRvIHRoZSBzdWJtaXQgZXZlbiBoYXMgYSBjaGFuY2UgdG8gYWRkIHRoZWlyIHN0dWZmIHRvIHRoZSBmb3JtLCBldmVuIGlmIHRoZXlcbiAgICAgICAgICAgIC8vIGJvdW5kIHRoZWlyIGhhbmRsZXIgKmFmdGVyKiB0aGlzIG9uZSB3YXMgYm91bmRcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGRvU3VibWl0KCRmb3JtLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgc3VibWl0Q2FsbGJhY2ssIHN1Ym1pdEV2ZW50KTtcbiAgICAgICAgICAgIH0sIDApO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFuVXBBZnRlclN1Ym1pdCgkZm9ybSwgaXNSZWRpcmVjdGluZykge1xuICAgICAgICAkZm9ybS5maW5kKCdpbnB1dFt0eXBlPVwic3VibWl0XCJdOnZpc2libGUsIGJ1dHRvblt0eXBlPVwic3VibWl0XCJdJykucmVtb3ZlQ2xhc3MoJ2lzLWxvYWRpbmcnKTtcbiAgICAgICAgaWYgKCFpc1JlZGlyZWN0aW5nKSB7XG4gICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmhlbHBlcnMuZW5hYmxlU3VibWl0QnV0dG9uKCRmb3JtKTtcblxuICAgICAgICAgICAgaWYgKFN0YWNrRXhjaGFuZ2UubmF2UHJldmVudGlvbikge1xuICAgICAgICAgICAgICAgIFN0YWNrRXhjaGFuZ2UubmF2UHJldmVudGlvbi5zdGFydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZG9TdWJtaXQoJGZvcm0sIHBvc3RUeXBlSWQsIGZvcm1UeXBlLCBzdWJtaXRDYWxsYmFjaywgc3VibWl0RXZlbnQpIHtcbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHR5cGU6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICAgICAgICBkYXRhOiBmb3JtVHlwZSA9PT0gJ2FydGljbGUtb24tdGVhbXMnID8gc2VyaWFsaXplRm9ybVdpdGhTb3VyY2UoJGZvcm0sIHN1Ym1pdEV2ZW50KSA6ICRmb3JtLnNlcmlhbGl6ZSgpLFxuICAgICAgICAgICAgdXJsOiAkZm9ybS5hdHRyKCdhY3Rpb24nKSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHN1Ym1pdENhbGxiYWNrLFxuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3JNZXNzYWdlID0gc3VibWlzc2lvbkVycm9yTWVzc2FnZShmb3JtVHlwZSwgMCk7XG4gICAgICAgICAgICAgICAgc2hvd1N1Ym1pc3Npb25FcnJvck1lc3NhZ2UoJGZvcm0sIHBvc3RUeXBlSWQsIGZvcm1UeXBlLCB7IEdlbmVyYWw6IFskKCc8c3Bhbi8+JykudGV4dChlcnJvck1lc3NhZ2UpLmh0bWwoKV0gfSwgMCk7XG5cbiAgICAgICAgICAgICAgICBjbGVhblVwQWZ0ZXJTdWJtaXQoJGZvcm0sIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VyaWFsaXplcyB0aGUgZm9ybSBhbmQgYWRkcyB0aGUgc291cmNlIG9mIHRoZSBzdWJtaXNzaW9uIHRvIHRoZSBzZXJpYWxpemVkIGRhdGEuIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIFxuICAgICAqIHN0YXRlIG9mIHRoZSBwb3N0LiBJbiB0aGUgY2FzZSBvZiBBcnRpY2xlcyBvbiBUZWFtcyBpdCBkZWNpZGVzIHdoZXRoZXIgdGhlIHBvc3QgaXMgYSBkcmFmdCBvciBub3QuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIGBqUXVlcnkuc2VyaWFsaXplKClgIGV4Y2x1ZGVzIGJ1dHRvbnMvaW5wdXRzIG9mIGB0eXBlPVwic3VibWl0XCJgIGJ5IGRlc2lnbi5cbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gJGZvcm0ganF1ZXJ5IGZvcm0gZWxlbWVudFxuICAgICAqIEBwYXJhbSBzdWJtaXRFdmVudCBhY2NvbXBhbnlpbmcgZXZlbnQgdGhhdCB0cmlnZ2VyZWQgc3VibWlzc2lvblxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNlcmlhbGl6ZUZvcm1XaXRoU291cmNlKCRmb3JtLCBzdWJtaXRFdmVudCkge1xuICAgICAgICB2YXIgc2VyaWFsaXplZCA9ICRmb3JtLnNlcmlhbGl6ZUFycmF5KCk7XG4gICAgICAgIC8vIGV4dHJhY3QgdmFsdWUgZmllbGQgZnJvbSB0aGUgYnV0dG9uIHRoYXQgdHJpZ2dlcmVkIHRoZSBzdWJtaXNzaW9uLCBpZiBwcmVzZW50XG4gICAgICAgIGlmIChzdWJtaXRFdmVudCAmJiBzdWJtaXRFdmVudC5vcmlnaW5hbEV2ZW50ICYmIHN1Ym1pdEV2ZW50Lm9yaWdpbmFsRXZlbnQuc3VibWl0dGVyKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBzdWJtaXRFdmVudC5vcmlnaW5hbEV2ZW50LnN1Ym1pdHRlci5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJyk7XG4gICAgICAgICAgICB2YXIgbmFtZT0gc3VibWl0RXZlbnQub3JpZ2luYWxFdmVudC5zdWJtaXR0ZXIuZ2V0QXR0cmlidXRlKCduYW1lJyk7XG4gICAgICAgICAgICBpZiAodmFsdWUgJiYgbmFtZSkge1xuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWQucHVzaCh7IG5hbWUsIHZhbHVlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAkLnBhcmFtKHNlcmlhbGl6ZWQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFyQmx1clRpbWVvdXRzKCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsdXJUaW1lb3V0SWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQoYmx1clRpbWVvdXRJZHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGJsdXJUaW1lb3V0SWRzID0gW107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYmluZE9uQmx1ckRlbGF5ZWQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHByb3BlcnR5LCBmdW5jKSB7XG4gICAgICAgIGdldEZvcm1JbnB1dCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBwcm9wZXJ0eSkuYmx1cihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdGhpc0FyZyA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgJHRhcmdldCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJHRhcmdldC5kYXRhKERJU0FCTEVfQkxVUl9WQUxJREFUSU9OX0tFWSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgc2V0RXJyb3IgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIGhhbmRsZUZpZWxkRXJyb3IoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHByb3BlcnR5LCBtZXNzYWdlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB2YXIgdmFsaWRhdGUgPSBmdW5jdGlvbiAocmVxdWVzdE9iamVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwZXJmb3JtVmFsaWRhdGlvbihyZXF1ZXN0T2JqZWN0LCAkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgW3Byb3BlcnR5XSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBibHVyVGltZW91dElkcy5wdXNoKHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgLy8gQ2xlYXIgU3RhY2tzIHZhbGlkYXRpb24gbWVzc2FnZXMgYXQgdGhlIHN0YXJ0IG9mIHZhbGlkYXRpb24uXG4gICAgICAgICAgICAgICAgdmFyIGhhbmRsZXIgPSBTdGFja0V4Y2hhbmdlLnN0YWNrc1ZhbGlkYXRpb24uaGFuZGxlckZvcigkdGFyZ2V0KTtcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlciAmJiAhb25Bc2tQYWdlVjIpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5jbGVhcigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZ1bmMuY2FsbCh0aGlzQXJnLCAkdGFyZ2V0LCBzZXRFcnJvciwgdmFsaWRhdGUsIHBvc3RUeXBlSWQpO1xuICAgICAgICAgICAgfSwgYmx1clRpbWVvdXREZWxheSkpO1xuICAgICAgICB9KTtcblxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbGlkYXRlUG9zdEZpZWxkcygkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgaXNTdWdnZXN0ZWRFZGl0LCBiZWZvcmVTaG93KSB7XG4gICAgICAgIGlmIChwb3N0VHlwZUlkID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVyZm9ybVZhbGlkYXRpb24oe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICB1cmw6ICcvcG9zdHMvdmFsaWRhdGUtcXVlc3Rpb24nLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGdldEZvcm1JbnB1dCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBUaXRsZUZpZWxkKS52YWwoKSxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogZ2V0Rm9ybUlucHV0KCRjb250YWluZXIsIHBvc3RUeXBlSWQsIEJvZHlGaWVsZCkudmFsKCksXG4gICAgICAgICAgICAgICAgICAgIHRhZ3M6IGdldEZvcm1JbnB1dCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBUYWdzRmllbGQpLnZhbCgpLFxuICAgICAgICAgICAgICAgICAgICBma2V5OiBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5LFxuICAgICAgICAgICAgICAgICAgICBpc0Fza1dpemFyZDogb25Bc2tXaXphcmRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgW1RpdGxlRmllbGQsIEJvZHlGaWVsZCwgVGFnc0ZpZWxkXSwgYmVmb3JlU2hvdykucHJvbWlzZSgpO1xuICAgICAgICB9IGVsc2UgaWYgKHBvc3RUeXBlSWQgPT09IDIpIHtcbiAgICAgICAgICAgIHJldHVybiBwZXJmb3JtVmFsaWRhdGlvbih7XG4gICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIHVybDogJy9wb3N0cy92YWxpZGF0ZS1ib2R5JyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGJvZHk6IGdldEZvcm1JbnB1dCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBCb2R5RmllbGQpLnZhbCgpLFxuICAgICAgICAgICAgICAgICAgICBvbGRCb2R5OiBnZXRGb3JtSW5wdXQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgQm9keUZpZWxkKS5wcm9wKCdkZWZhdWx0VmFsdWUnKSxcbiAgICAgICAgICAgICAgICAgICAgaXNRdWVzdGlvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGlzU3VnZ2VzdGVkRWRpdDogaXNTdWdnZXN0ZWRFZGl0IHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBma2V5OiBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIFtCb2R5RmllbGRdLCBiZWZvcmVTaG93KS5wcm9taXNlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBUaGlzIGNhbiBiZSBleHBhbmRlZCBhcyBuZWVkZWQgdG8gaGFuZGxlIG90aGVyIGNhc2VzIHdoZXJlIHZhbGlkYXRpb24gaXMgZGVsYXllZC5cbiAgICAgICAgICAgIHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKTtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdCgpO1xuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluaXRUaXRsZVZhbGlkYXRpb24oJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUpIHtcbiAgICAgICAgYmluZE9uQmx1ckRlbGF5ZWQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIFRpdGxlRmllbGQsIGZ1bmN0aW9uICgkdGl0bGUsIHNldEVycm9yLCB2YWxpZGF0ZSkge1xuICAgICAgICAgICAgdmFyIHRpdGxlID0gJHRpdGxlLnZhbCgpO1xuICAgICAgICAgICAgdmFyIHRyaW1tZWRMZW5ndGggPSAkLnRyaW0odGl0bGUpLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBtaW5MZW5ndGggPSAkdGl0bGUuZGF0YSgnbWluLWxlbmd0aCcpO1xuICAgICAgICAgICAgdmFyIG1heExlbmd0aCA9ICR0aXRsZS5kYXRhKCdtYXgtbGVuZ3RoJyk7XG5cbiAgICAgICAgICAgIGlmICh0cmltbWVkTGVuZ3RoID09PSAwICYmICFvbkFza1BhZ2VWMikge1xuICAgICAgICAgICAgICAgIHNldEVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobWluTGVuZ3RoICYmIHRyaW1tZWRMZW5ndGggPCBtaW5MZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvcihfcygnVGl0bGUgbXVzdCBiZSBhdCBsZWFzdCAjbWluTGVuZ3RoIyBjaGFyYWN0ZXJzLicsIHsgbWluTGVuZ3RoOiBtaW5MZW5ndGggfSkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG1heExlbmd0aCAmJiB0cmltbWVkTGVuZ3RoID4gbWF4TGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgc2V0RXJyb3IoX3MoJ1RpdGxlIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAjbWF4TGVuZ3RoIyBjaGFyYWN0ZXJzLicsIHsgbWF4TGVuZ3RoOiBtYXhMZW5ndGggfSkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFsaWRhdGUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICB1cmw6ICcvcG9zdHMvdmFsaWRhdGUtdGl0bGUnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgICAgICAgICBwb3N0VHlwZUlkOiBwb3N0VHlwZUlkLFxuICAgICAgICAgICAgICAgICAgICBma2V5OiBTdGFja0V4Y2hhbmdlLm9wdGlvbnMudXNlci5ma2V5XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluaXRCb2R5VmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgaXNTdWdnZXN0ZWRFZGl0KSB7XG4gICAgICAgIGJpbmRPbkJsdXJEZWxheWVkKCRjb250YWluZXIsIHBvc3RUeXBlSWQsIGZvcm1UeXBlLCBCb2R5RmllbGQsIGZ1bmN0aW9uICgkYm9keSwgc2V0RXJyb3IsIHZhbGlkYXRlKSB7XG4gICAgICAgICAgICB2YXIgYm9keSA9ICRib2R5LnZhbCgpO1xuICAgICAgICAgICAgdmFyIHRyaW1tZWRMZW5ndGggPSAkLnRyaW0oYm9keSkubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIG1pbkxlbmd0aCA9ICRib2R5LmRhdGEoJ21pbi1sZW5ndGgnKTtcblxuICAgICAgICAgICAgaWYgKHRyaW1tZWRMZW5ndGggPT09IDAgJiYgIW9uQXNrUGFnZVYyKSB7XG4gICAgICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE9ubHkgZG8gY2xpZW50LXNpZGUgbGVuZ3RoIHZhbGlkYXRpb24gZm9yIHRhZyB3aWtpcyBhbmQgYW5ub3VuY2VtZW50cy5cblxuICAgICAgICAgICAgaWYgKHBvc3RUeXBlSWQgPT09IDUpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluTGVuZ3RoICYmIHRyaW1tZWRMZW5ndGggPCBtaW5MZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoX3MoJ1dpa2kgQm9keSBtdXN0IGJlIGF0IGxlYXN0ICRtaW5MZW5ndGgkIGNoYXJhY3RlcnMuIFlvdSBlbnRlcmVkICRhY3R1YWwkLicsIHsgbWluTGVuZ3RoOiBtaW5MZW5ndGgsIGFjdHVhbDogdHJpbW1lZExlbmd0aCB9KSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAocG9zdFR5cGVJZCA9PT0gMTQpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluTGVuZ3RoICYmIHRyaW1tZWRMZW5ndGggPCBtaW5MZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoX3MoJ0JvZHkgbXVzdCBiZSBhdCBsZWFzdCAkbWluTGVuZ3RoJCBjaGFyYWN0ZXJzLicsIHsgbWluTGVuZ3RoOiBtaW5MZW5ndGggfSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNldEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBvc3RUeXBlSWQgPT09IDEgfHwgcG9zdFR5cGVJZCA9PT0gMiB8fCBwb3N0VHlwZUlkID09PSAxNSkge1xuICAgICAgICAgICAgICAgIHZhbGlkYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICB1cmw6ICcvcG9zdHMvdmFsaWRhdGUtYm9keScsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk6IGJvZHksXG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRCb2R5OiAkYm9keS5wcm9wKCdkZWZhdWx0VmFsdWUnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzUXVlc3Rpb246IChwb3N0VHlwZUlkID09PSAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzU3VnZ2VzdGVkRWRpdDogaXNTdWdnZXN0ZWRFZGl0LFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNBc2tXaXphcmQ6IG9uQXNrV2l6YXJkLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmtleTogU3RhY2tFeGNoYW5nZS5vcHRpb25zLnVzZXIuZmtleVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluaXRUYWdzVmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSkge1xuICAgICAgICBiaW5kT25CbHVyRGVsYXllZCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgVGFnc0ZpZWxkLCBmdW5jdGlvbiAoJHRhZ3MsIHNldEVycm9yLCB2YWxpZGF0ZSwgcG9zdFR5cGVJZCkge1xuICAgICAgICAgICAgdmFyIHRhZ3MgPSAkdGFncy52YWwoKTtcbiAgICAgICAgICAgIHZhciB0cmltbWVkTGVuZ3RoID0gJC50cmltKHRhZ3MpLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBwb3N0U3RhdGUgPSAkKCcjanMtcG9zdC1zdGF0ZScpLnZhbCgpO1xuXG4gICAgICAgICAgICBpZiAodHJpbW1lZExlbmd0aCA9PT0gMCAmJiAhb25Bc2tQYWdlVjIpIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFsaWRhdGUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICB1cmw6ICcvcG9zdHMvdmFsaWRhdGUtdGFncycsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICB0YWdzOiB0YWdzLFxuICAgICAgICAgICAgICAgICAgICBvbGRUYWdzOiAkdGFncy5wcm9wKCdkZWZhdWx0VmFsdWUnKSxcbiAgICAgICAgICAgICAgICAgICAgZmtleTogU3RhY2tFeGNoYW5nZS5vcHRpb25zLnVzZXIuZmtleSxcbiAgICAgICAgICAgICAgICAgICAgcG9zdFR5cGVJZDogcG9zdFR5cGVJZCxcbiAgICAgICAgICAgICAgICAgICAgcG9zdFN0YXRlOiBwb3N0U3RhdGVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyICRmaWVsZCA9ICR0YWdzLmNsb3Nlc3QoJy5qcy1wb3N0LWZvcm0nKS5maW5kKCcuanMtd2FybmVkLXRhZ3MtZmllbGQnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCRmaWVsZC5sZW5ndGgpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gJGZpZWxkLnZhbCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdhcm5lZFRhZ3MgPSAkZmllbGQuZGF0YSgnd2FybmVkLXRhZ3MnKSB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB1bndhcm5lZFRhZ3MgPSAoKGRhdGEuc291cmNlIHx8IHt9KS5UYWdzIHx8IFtdKS5maWx0ZXIoZnVuY3Rpb24gKHRhZykgeyByZXR1cm4gdGFnICYmIHdhcm5lZFRhZ3MuaW5kZXhPZih0YWcpID09PSAtMTsgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1bndhcm5lZFRhZ3MubGVuZ3RoID4gMCkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS51c2luZyhcImdwc1wiLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW53YXJuZWRUYWdzLmZvckVhY2goZnVuY3Rpb24gKHRhZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5ncHMudHJhY2soXCJ0YWdfd2FybmluZy5zaG93XCIsIHsgdGFnOiB0YWcgfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSAnICcgKyB0YWc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJuZWRUYWdzLnB1c2godGFnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZpZWxkLnZhbCgkLnRyaW0odmFsdWUpKS5kYXRhKCd3YXJuZWQtdGFncycsIHdhcm5lZFRhZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmdwcy5zZW5kUGVuZGluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlamVjdFN5c3RlbUVkaXRDb21tZW50KCRjb250YWluZXIsIHBvc3RUeXBlSWQsIGZvcm1UeXBlKSB7XG5cbiAgICAgICAgaWYgKCQudHJpbShnZXRGb3JtSW5wdXQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgRWRpdENvbW1lbnRGaWVsZCkudmFsKCkpID09PSAnW0VkaXQgcmVtb3ZlZCBkdXJpbmcgZ3JhY2UgcGVyaW9kXScpIHtcbiAgICAgICAgICAgIGhhbmRsZUZpZWxkRXJyb3IoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIEVkaXRDb21tZW50RmllbGQsXG4gICAgICAgICAgICAgICAgX3MoJ0NvbW1lbnQgcmVzZXJ2ZWQgZm9yIHN5c3RlbSB1c2UuICBQbGVhc2UgdXNlIGFuIGFwcHJvcHJpYXRlIGNvbW1lbnQuJykpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluaXRFZGl0Q29tbWVudFZhbGlkYXRpb24oJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUpIHtcbiAgICAgICAgYmluZE9uQmx1ckRlbGF5ZWQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIEVkaXRDb21tZW50RmllbGQsIGZ1bmN0aW9uICgkZWRpdENvbW1lbnQsIHNldEVycm9yLCB2YWxpZGF0ZSkge1xuICAgICAgICAgICAgdmFyIGVkaXRDb21tZW50ID0gJGVkaXRDb21tZW50LnZhbCgpO1xuICAgICAgICAgICAgdmFyIHRyaW1tZWRMZW5ndGggPSAkLnRyaW0oZWRpdENvbW1lbnQpLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBtaW5MZW5ndGggPSAkZWRpdENvbW1lbnQuZGF0YSgnbWluLWxlbmd0aCcpO1xuICAgICAgICAgICAgdmFyIG1heExlbmd0aCA9ICRlZGl0Q29tbWVudC5kYXRhKCdtYXgtbGVuZ3RoJyk7XG5cbiAgICAgICAgICAgIGlmICh0cmltbWVkTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtaW5MZW5ndGggJiYgdHJpbW1lZExlbmd0aCA8IG1pbkxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHNldEVycm9yKF9zKCdZb3VyIGVkaXQgc3VtbWFyeSBtdXN0IGJlIGF0IGxlYXN0ICNtaW5MZW5ndGgjIGNoYXJhY3RlcnMuJywgeyBtaW5MZW5ndGg6IG1pbkxlbmd0aCB9KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobWF4TGVuZ3RoICYmIHRyaW1tZWRMZW5ndGggPiBtYXhMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvcihfcygnWW91ciBlZGl0IHN1bW1hcnkgY2Fubm90IGJlIGxvbmdlciB0aGFuICNtYXhMZW5ndGgjIGNoYXJhY3RlcnMuJywgeyBtYXhMZW5ndGg6IG1heExlbmd0aCB9KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVqZWN0U3lzdGVtRWRpdENvbW1lbnQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXRFcnJvcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbml0RXhjZXJwdFZhbGlkYXRpb24oJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUpIHtcbiAgICAgICAgYmluZE9uQmx1ckRlbGF5ZWQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIEV4Y2VycHRGaWVsZCwgZnVuY3Rpb24gKCRleGNlcnB0LCBzZXRFcnJvciwgdmFsaWRhdGUpIHtcbiAgICAgICAgICAgIHZhciBleGNlcnB0ID0gJGV4Y2VycHQudmFsKCk7XG4gICAgICAgICAgICB2YXIgdHJpbW1lZExlbmd0aCA9ICQudHJpbShleGNlcnB0KS5sZW5ndGg7XG4gICAgICAgICAgICB2YXIgbWluTGVuZ3RoID0gJGV4Y2VycHQuZGF0YSgnbWluLWxlbmd0aCcpO1xuICAgICAgICAgICAgdmFyIG1heExlbmd0aCA9ICRleGNlcnB0LmRhdGEoJ21heC1sZW5ndGgnKTtcblxuICAgICAgICAgICAgaWYgKHRyaW1tZWRMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG1pbkxlbmd0aCAmJiB0cmltbWVkTGVuZ3RoIDwgbWluTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgc2V0RXJyb3IoX3MoJ1dpa2kgRXhjZXJwdCBtdXN0IGJlIGF0IGxlYXN0ICRtaW5MZW5ndGgkIGNoYXJhY3RlcnM7IHlvdSBlbnRlcmVkICRhY3R1YWwkLicsIHsgbWluTGVuZ3RoOiBtaW5MZW5ndGgsIGFjdHVhbDogdHJpbW1lZExlbmd0aCB9KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobWF4TGVuZ3RoICYmIHRyaW1tZWRMZW5ndGggPiBtYXhMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvcihfcygnV2lraSBFeGNlcnB0IGNhbm5vdCBiZSBsb25nZXIgdGhhbiAkbWF4TGVuZ3RoJCBjaGFyYWN0ZXJzOyB5b3UgZW50ZXJlZCAkYWN0dWFsJC4nLCB7IG1heExlbmd0aDogbWF4TGVuZ3RoLCBhY3R1YWw6IHRyaW1tZWRMZW5ndGggfSkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5pdEVtYWlsVmFsaWRhdGlvbigkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSkge1xuICAgICAgICBiaW5kT25CbHVyRGVsYXllZCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgRW1haWxGaWVsZCwgZnVuY3Rpb24gKCRlbWFpbCwgc2V0RXJyb3IsIHZhbGlkYXRlKSB7XG4gICAgICAgICAgICB2YXIgZW1haWwgPSAkZW1haWwudmFsKCk7XG4gICAgICAgICAgICB2YXIgdHJpbW1lZCA9ICQudHJpbShlbWFpbCk7XG4gICAgICAgICAgICB2YXIgdHJpbW1lZExlbmd0aCA9IHRyaW1tZWQubGVuZ3RoO1xuXG4gICAgICAgICAgICBpZiAodHJpbW1lZExlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNldEVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIVN0YWNrRXhjaGFuZ2UuaGVscGVycy5pc0VtYWlsQWRkcmVzcyh0cmltbWVkKSkge1xuICAgICAgICAgICAgICAgIHNldEVycm9yKF9zKCdUaGlzIGVtYWlsIGRvZXMgbm90IGFwcGVhciB0byBiZSB2YWxpZC4nKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXRFcnJvcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTaWRlYmFyUG9wdXBPcHRpb25zKHByb3BlcnR5LCB0eXBlKSB7XG4gICAgICAgIHZhciBzaWRlYmFyV2lkdGggPSAkKCcjc2lkZWJhciwgLnNpZGViYXInKS5maXJzdCgpLndpZHRoKCkgfHwgMjcwO1xuXG4gICAgICAgIHZhciBsYXJnZSA9IFN0YWNrRXhjaGFuZ2UucmVzcG9uc2l2ZS5jdXJyZW50UmFuZ2UoKSA9PT0gXCJsZ1wiO1xuXG4gICAgICAgIGlmIChwcm9wZXJ0eSA9PT0gR2VuZXJhbEZpZWxkKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnaW5saW5lJyxcbiAgICAgICAgICAgICAgICBjc3M6IHsgJ2Rpc3BsYXknOiAnaW5saW5lLWJsb2NrJywgJ21hcmdpbi1ib3R0b20nOiAnMTBweCcgfSxcbiAgICAgICAgICAgICAgICBjbG9zZU90aGVyczogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzbWlzc2FibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcG9zaXRpb246IHsgbXk6IGxhcmdlID8gJ2xlZnQgdG9wJyA6ICd0b3AgY2VudGVyJyAsIGF0OiBsYXJnZSA/ICdyaWdodCBjZW50ZXInIDogJ2JvdHRvbSBjZW50ZXInIH0sXG4gICAgICAgICAgICBjc3M6IHsgJ21heC13aWR0aCc6IHNpZGViYXJXaWR0aCwgJ21pbi13aWR0aCc6IHNpZGViYXJXaWR0aCB9LFxuICAgICAgICAgICAgY2xvc2VPdGhlcnM6IGZhbHNlLFxuICAgICAgICAgICAgdHlwZTogdHlwZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Ym1pc3Npb25FcnJvck1lc3NhZ2UoZm9ybVR5cGUsIHNwZWNpZmljRXJyb3JDb3VudCkge1xuICAgICAgICBpZiAoc3BlY2lmaWNFcnJvckNvdW50ID4gMCkge1xuICAgICAgICAgICAgc3dpdGNoIChmb3JtVHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3F1ZXN0aW9uJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zKFwiWW91ciBxdWVzdGlvbiBjb3VsZG4ndCBiZSBzdWJtaXR0ZWQuIFBsZWFzZSBzZWUgdGhlICN+c3BlY2lmaWNFcnJvckNvdW50I2Vycm9ycyBhYm92ZS5cIiwgeyBzcGVjaWZpY0Vycm9yQ291bnQ6IHNwZWNpZmljRXJyb3JDb3VudCB9KTtcbiAgICAgICAgICAgICAgICBjYXNlICdhbnN3ZXInOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3MoXCJZb3VyIGFuc3dlciBjb3VsZG4ndCBiZSBzdWJtaXR0ZWQuIFBsZWFzZSBzZWUgdGhlICN+c3BlY2lmaWNFcnJvckNvdW50I2Vycm9ycyBhYm92ZS5cIiwgeyBzcGVjaWZpY0Vycm9yQ291bnQ6IHNwZWNpZmljRXJyb3JDb3VudCB9KTtcbiAgICAgICAgICAgICAgICBjYXNlICdlZGl0JzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zKFwiWW91ciBlZGl0IGNvdWxkbid0IGJlIHN1Ym1pdHRlZC4gUGxlYXNlIHNlZSB0aGUgI35zcGVjaWZpY0Vycm9yQ291bnQjZXJyb3JzIGFib3ZlLlwiLCB7IHNwZWNpZmljRXJyb3JDb3VudDogc3BlY2lmaWNFcnJvckNvdW50IH0pO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3RhZ3MnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3MoXCJZb3VyIHRhZ3MgY291bGRuJ3QgYmUgc3VibWl0dGVkLiBQbGVhc2Ugc2VlIHRoZSAjfnNwZWNpZmljRXJyb3JDb3VudCNlcnJvcnMgYWJvdmUuXCIsIHsgc3BlY2lmaWNFcnJvckNvdW50OiBzcGVjaWZpY0Vycm9yQ291bnQgfSk7XG4gICAgICAgICAgICAgICAgY2FzZSAnYXJ0aWNsZSc6XG4gICAgICAgICAgICAgICAgY2FzZSAnYXJ0aWNsZS1vbi10ZWFtcyc6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcyhcIllvdXIgYXJ0aWNsZSBjb3VsZG4ndCBiZSBzdWJtaXR0ZWQuIFBsZWFzZSBzZWUgdGhlICN+c3BlY2lmaWNFcnJvckNvdW50I2Vycm9ycyBhYm92ZS5cIiwgeyBzcGVjaWZpY0Vycm9yQ291bnQ6IHNwZWNpZmljRXJyb3JDb3VudCB9KTtcbiAgICAgICAgICAgICAgICBjYXNlICdhbm5vdW5jZW1lbnQnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3MoXCJZb3VyIGJ1bGxldGluIGNvdWxkbid0IGJlIHB1Ymxpc2hlZC4gUGxlYXNlIHNlZSB0aGUgI35zcGVjaWZpY0Vycm9yQ291bnQjZXJyb3JzIGFib3ZlLlwiLCB7IHNwZWNpZmljRXJyb3JDb3VudDogc3BlY2lmaWNFcnJvckNvdW50IH0pO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcyhcIllvdXIgcG9zdCBjb3VsZG4ndCBiZSBzdWJtaXR0ZWQuIFBsZWFzZSBzZWUgdGhlICN+c3BlY2lmaWNFcnJvckNvdW50I2Vycm9ycyBhYm92ZS5cIiwgeyBzcGVjaWZpY0Vycm9yQ291bnQ6IHNwZWNpZmljRXJyb3JDb3VudCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN3aXRjaCAoZm9ybVR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdxdWVzdGlvbic6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcygnQW4gZXJyb3Igb2NjdXJyZWQgc3VibWl0dGluZyB0aGUgcXVlc3Rpb24uJyk7XG4gICAgICAgICAgICAgICAgY2FzZSAnYW5zd2VyJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zKCdBbiBlcnJvciBvY2N1cnJlZCBzdWJtaXR0aW5nIHRoZSBhbnN3ZXIuJyk7XG4gICAgICAgICAgICAgICAgY2FzZSAnZWRpdCc6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcygnQW4gZXJyb3Igb2NjdXJyZWQgc3VibWl0dGluZyB0aGUgZWRpdC4nKTtcbiAgICAgICAgICAgICAgICBjYXNlICd0YWdzJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zKCdBbiBlcnJvciBvY2N1cnJlZCBzdWJtaXR0aW5nIHRoZSB0YWdzLicpO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2FydGljbGUnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2FydGljbGUtb24tdGVhbXMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3MoJ0FuIGVycm9yIG9jY3VycmVkIHN1Ym1pdHRpbmcgdGhlIGFydGljbGUuJyk7XG4gICAgICAgICAgICAgICAgY2FzZSAnYW5ub3VuY2VtZW50JzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zKCdBbiBlcnJvciBvY2N1cnJlZCBwdWJsaXNoaW5nIHRoZSBidWxsZXRpbi4nKTtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3MoJ0FuIGVycm9yIG9jY3VycmVkIHN1Ym1pdHRpbmcgdGhlIHBvc3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzaG93U3VibWlzc2lvbkVycm9yTWVzc2FnZSgkZm9ybSwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIGVycm9yc0pzb24sIHNwZWNpZmljRXJyb3JDb3VudCkge1xuXG4gICAgICAgIHZhciAkZ2VuZXJhbEVycm9yQm94ID0gJGZvcm0uZmluZCgnLmpzLWdlbmVyYWwtZXJyb3InKS50ZXh0KCcnKS5yZW1vdmVDbGFzcygnZC1ub25lJyk7XG5cbiAgICAgICAgaWYgKGhhbmRsZUVycm9yc0FuZFdhcm5pbmdzKCRmb3JtLCAkZ2VuZXJhbEVycm9yQm94LCBlcnJvcnNKc29uLCBudWxsLCBHZW5lcmFsRmllbGQsIHBvc3RUeXBlSWQsIGZvcm1UeXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNwZWNpZmljRXJyb3JDb3VudCA+IDApIHtcbiAgICAgICAgICAgICRnZW5lcmFsRXJyb3JCb3gudGV4dChzdWJtaXNzaW9uRXJyb3JNZXNzYWdlKGZvcm1UeXBlLCBzcGVjaWZpY0Vycm9yQ291bnQpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgICRnZW5lcmFsRXJyb3JCb3guYWRkQ2xhc3MoJ2Qtbm9uZScpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjcm9sbFRvRXJyb3JzKCRjb250YWluZXIpIHtcblxuICAgICAgICAvLyBTY3JvbGwgdG8gdGhlIHBvc3QgcmV2aWV3IHNpZGViYXIsIGlmIGl0IGV4aXN0cy5cbiAgICAgICAgdmFyICRyZXZpZXdTdW1tYXJ5Q29udGFpbmVyID0gJCgnLmpzLXBvc3QtcmV2aWV3LXN1bW1hcnknKS5jbG9zZXN0KCcuanMtcG9zdC1yZXZpZXctc3VtbWFyeS1jb250YWluZXInKTtcbiAgICAgICAgaWYgKCRyZXZpZXdTdW1tYXJ5Q29udGFpbmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICRyZXZpZXdTdW1tYXJ5Q29udGFpbmVyLmZpbHRlcignOnZpc2libGUnKS5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGludGVydmFsSWQ7XG4gICAgICAgIGlmIChhcmVBbnlFcnJvcnNPdmVyU2lkZWJhcigpKSB7XG4gICAgICAgICAgICAkKCcjc2lkZWJhcicpLmFuaW1hdGUoeyAnb3BhY2l0eSc6IDAuNCB9LCA1MDApO1xuICAgICAgICAgICAgaW50ZXJ2YWxJZCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWFyZUFueUVycm9yc092ZXJTaWRlYmFyKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgJCgnI3NpZGViYXInKS5hbmltYXRlKHsgJ29wYWNpdHknOiAxIH0sIDUwMCk7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzY3JvbGxUb3A7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLnZhbGlkYXRpb24tZXJyb3IsIC5qcy1zdGFja3MtdmFsaWRhdGlvbi5oYXMtZXJyb3InKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB0b3AgPSAkKHRoaXMpLm9mZnNldCgpLnRvcDtcbiAgICAgICAgICAgIGlmICghc2Nyb2xsVG9wIHx8IHRvcCA8IHNjcm9sbFRvcCkge1xuICAgICAgICAgICAgICAgIHNjcm9sbFRvcCA9IHRvcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHNoYWtlRXJyb3JzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5tZXNzYWdlJykuYW5pbWF0ZSh7IGxlZnQ6ICcrPTVweCcgfSwgMTAwKS5hbmltYXRlKHsgbGVmdDogJy09NXB4JyB9LCAxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChzY3JvbGxUb3ApIHtcbiAgICAgICAgICAgIHZhciBpc1JldmlldyA9ICQoJy5yZXZpZXctYmFyJykubGVuZ3RoO1xuICAgICAgICAgICAgc2Nyb2xsVG9wID0gTWF0aC5tYXgoMCwgc2Nyb2xsVG9wIC0gKGlzUmV2aWV3ID8gMTI1IDogMzApKTsgLy8gbGVhdmUgc29tZSBicmVhdGhpbmcgcm9vbSwgYW5kIGxlYXZlIGV4dHJhIHJvb20gZm9yIHRoZSByZXZpZXcgYmFyXG4gICAgICAgICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZSh7IHNjcm9sbFRvcDogc2Nyb2xsVG9wIH0sIHNoYWtlRXJyb3JzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNoYWtlRXJyb3JzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzaG93RXJyb3JzQWZ0ZXJTdWJtaXNzaW9uKCRmb3JtLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgZXJyb3JzSnNvbiwgb3B0aW9uYWxXYXJuaW5nc0pzb24pIHtcblxuICAgICAgICBpZiAoIWVycm9yc0pzb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHdlIGhhdmUgYSBjb21tZW50cyBjb250YWluZXIsIGFkZCBpdCB0byB0aGUgYXZhaWwgY29udGFpbmVyc1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gJGZvcm0uYWRkKFwiI2pzLWNvbW1lbnRzLWNvbnRhaW5lclwiKVxuXG4gICAgICAgIHdoZW5UYWdFZGl0b3JJc0RvbmVMb2FkaW5nKCRmb3JtLCBwb3N0VHlwZUlkLCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgIHZhciBzcGVjaWZpY0Vycm9yQ291bnQgPVxuICAgICAgICAgICAgICAgIGhhbmRsZUZpZWxkVmFsaWRhdGlvblJlc3VsdHMoXG4gICAgICAgICAgICAgICAgICAgICRjb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgIHBvc3RUeXBlSWQsXG4gICAgICAgICAgICAgICAgICAgIGZvcm1UeXBlLFxuICAgICAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICAgICBUaXRsZUZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgQm9keUZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgVGFnc0ZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgTWVudGlvbnNGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRDb21tZW50RmllbGQsXG4gICAgICAgICAgICAgICAgICAgICAgICBFeGNlcnB0RmllbGQsXG4gICAgICAgICAgICAgICAgICAgICAgICBFbWFpbEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgQXJ0aWNsZVR5cGVGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIERhdGVGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIENvbW1lbnRGb3JtRmllbGQsXG4gICAgICAgICAgICAgICAgICAgICAgICBTdWJ0aXRsZUZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgQ3RhTGFiZWxGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIEN0YVVybEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgVGFyZ2V0VXJsRmllbGQsXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIGVycm9yc0pzb24sXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsV2FybmluZ3NKc29uKS5sZW5ndGg7XG5cbiAgICAgICAgICAgIHNob3dTdWJtaXNzaW9uRXJyb3JNZXNzYWdlKCRjb250YWluZXIsIHBvc3RUeXBlSWQsIGZvcm1UeXBlLCBlcnJvcnNKc29uLCBzcGVjaWZpY0Vycm9yQ291bnQpO1xuXG4gICAgICAgICAgICBzY3JvbGxUb0Vycm9ycygkY29udGFpbmVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyB3YWl0cyBmb3IgdGhlIHRhZyBlZGl0b3IgdG8gZmluaXNoIGxvYWRpbmcgYmVmb3JlIGV4ZWN1dGluZyB0aGUgcGFzc2VkIGZ1bmN0aW9uLlxuICAgIC8vIEl0IHdpbGwgcmV0dXJuIGluc3RhbnRseSBpZiB3ZSBhcmVuJ3QgZWRpdGluZyBhIHF1ZXN0aW9uLlxuICAgIGZ1bmN0aW9uIHdoZW5UYWdFZGl0b3JJc0RvbmVMb2FkaW5nKCRjb250YWluZXIsIHBvc3RUeXBlSWQsIGZ1bmMpIHtcblxuICAgICAgICAvLyBXYWl0IHVudGlsIHRoZSB0YWcgZWRpdG9yIGNyZWF0ZXMgaXRzIFVJLlxuICAgICAgICB2YXIgdHJ5SXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAocG9zdFR5cGVJZCAhPT0gMSB8fCBnZXRWaXNpYmxlRmllbGQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgVGFnc0ZpZWxkKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmdW5jKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQodHJ5SXQsIDI1MCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5SXQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZXJmb3JtVmFsaWRhdGlvbihyZXF1ZXN0T2JqZWN0LCAkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgcHJvcGVydGllcywgYmVmb3JlU2hvdykge1xuXG4gICAgICAgIHJldHVybiAkLmFqYXgocmVxdWVzdE9iamVjdClcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJlZm9yZVNob3cgPyAkLndoZW4oYmVmb3JlU2hvdygpKS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRhdGE7IH0pIDogZGF0YTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuZG9uZShmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGhhbmRsZUZpZWxkVmFsaWRhdGlvblJlc3VsdHMoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHByb3BlcnRpZXMsIGRhdGEuZXJyb3JzLCBkYXRhLndhcm5pbmdzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuZmFpbChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlRmllbGRWYWxpZGF0aW9uUmVzdWx0cygkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgcHJvcGVydGllcywge30sIHt9KTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZUZpZWxkVmFsaWRhdGlvblJlc3VsdHMoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHByb3BlcnRpZXMsIGVycm9ycywgd2FybmluZ3MpIHtcbiAgICAgICAgdmFyIHByb3BlcnRpZXNXaXRoRXJyb3JzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcGVydGllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHByb3BlcnR5ID0gcHJvcGVydGllc1tpXTtcbiAgICAgICAgICAgIGlmIChoYW5kbGVFcnJvcnNBbmRXYXJuaW5ncygkY29udGFpbmVyLCBnZXRWaXNpYmxlRmllbGQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgcHJvcGVydHkpLCBlcnJvcnMsIHdhcm5pbmdzLCBwcm9wZXJ0eSwgcG9zdFR5cGVJZCwgZm9ybVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllc1dpdGhFcnJvcnMucHVzaChwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaXJlIGV2ZW50IHRoYXQgd2UncmUgZG9uZSBoYW5kbGluZyB2YWxpZGF0aW9uXG4gICAgICAgIHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInZhbGlkYXRpb246Y29tcGxldGVcIikpO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHByb3BlcnRpZXNXaXRoRXJyb3JzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZUZpZWxkRXJyb3IoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHByb3BlcnR5LCBlcnJvcikge1xuICAgICAgICBoYW5kbGVTY29wZWRFcnJvcnNBbmRXYXJuaW5ncygkY29udGFpbmVyLCBnZXRWaXNpYmxlRmllbGQoJGNvbnRhaW5lciwgcG9zdFR5cGVJZCwgcHJvcGVydHkpLCBlcnJvciA/IFskKCc8c3Bhbi8+JykudGV4dChlcnJvcikuaHRtbCgpXSA6IFtdLCBbXSwgcHJvcGVydHksIHBvc3RUeXBlSWQsIGZvcm1UeXBlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVFcnJvcnNBbmRXYXJuaW5ncygkY29udGFpbmVyLCAkZmllbGQsIGVycm9ycywgd2FybmluZ3MsIHByb3BlcnR5LCBwb3N0VHlwZUlkLCBmb3JtVHlwZSkge1xuXG4gICAgICAgIHZhciBzY29wZWRFcnJvcnMgPSBlcnJvcnNbcHJvcGVydHldIHx8IFtdO1xuICAgICAgICB2YXIgc2NvcGVkV2FybmluZ3MgPSAod2FybmluZ3MgfHwge30pW3Byb3BlcnR5XSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZVNjb3BlZEVycm9yc0FuZFdhcm5pbmdzKCRjb250YWluZXIsICRmaWVsZCwgc2NvcGVkRXJyb3JzLCBzY29wZWRXYXJuaW5ncywgcHJvcGVydHksIHBvc3RUeXBlSWQsIGZvcm1UeXBlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVTY29wZWRFcnJvcnNBbmRXYXJuaW5ncygkY29udGFpbmVyLCAkZmllbGQsIHNjb3BlZEVycm9ycywgc2NvcGVkV2FybmluZ3MsIHByb3BlcnR5LCBwb3N0VHlwZUlkLCBmb3JtVHlwZSkge1xuXG4gICAgICAgIHZhciBoYW5kbGVyID0gU3RhY2tFeGNoYW5nZS5zdGFja3NWYWxpZGF0aW9uLmhhbmRsZXJGb3IoJGZpZWxkKTtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICAgIHVwZGF0ZVN0YWNrc1ZhbGlkYXRpb24oaGFuZGxlciwgcG9zdFR5cGVJZCwgZm9ybVR5cGUsIHNjb3BlZEVycm9ycywgc2NvcGVkV2FybmluZ3MsIHByb3BlcnR5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVwZGF0ZVBvcHVwRXJyb3JzKCRmaWVsZCwgcHJvcGVydHksIHNjb3BlZEVycm9ycyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjb3BlZEVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGdldEZvcm1JbnB1dCgkY29udGFpbmVyLCBwb3N0VHlwZUlkLCBwcm9wZXJ0eSlcbiAgICAgICAgICAgICAgICAuZGF0YShESVNBQkxFX0JMVVJfVkFMSURBVElPTl9LRVksIHRydWUpXG4gICAgICAgICAgICAgICAgLm9uZShcImlucHV0IGNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7ICQodGhpcykuZGF0YShESVNBQkxFX0JMVVJfVkFMSURBVElPTl9LRVksIG51bGwpOyB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbW92ZSBcIllvdXIgcG9zdCBjb3VsZG4ndCBiZSBzdWJtaXR0ZWQuIFBsZWFzZSBzZWUgdGhlIGVycm9ycyBhYm92ZS5cIlxuICAgICAgICBpZiAoISRjb250YWluZXIuZmluZCgnLnZhbGlkYXRpb24tZXJyb3IsIC5qcy1zdGFja3MtdmFsaWRhdGlvbi5oYXMtZXJyb3InKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICRjb250YWluZXIuZmluZCgnLmpzLWdlbmVyYWwtZXJyb3InKS50ZXh0KCcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgICRmaWVsZC50cmlnZ2VyKCdwb3N0OnZhbGlkYXRlZC1maWVsZCcsIFt7XG4gICAgICAgICAgICBlcnJvcnM6IHNjb3BlZEVycm9ycyxcbiAgICAgICAgICAgIHdhcm5pbmdzOiBzY29wZWRXYXJuaW5ncyxcbiAgICAgICAgICAgIGZpZWxkOiBwcm9wZXJ0eSxcbiAgICAgICAgICAgIHBvc3RUeXBlSWQ6IHBvc3RUeXBlSWQsXG4gICAgICAgICAgICBmb3JtVHlwZTogZm9ybVR5cGUsXG4gICAgICAgIH1dKTtcblxuICAgICAgICByZXR1cm4gc2NvcGVkRXJyb3JzLmxlbmd0aCA+IDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlU3RhY2tzVmFsaWRhdGlvbihoYW5kbGVyLCBwb3N0VHlwZUlkLCBmb3JtVHlwZSwgZXJyb3JzLCB3YXJuaW5ncykge1xuXG4gICAgICAgIGhhbmRsZXIuY2xlYXIoJ2Vycm9yJyk7XG4gICAgICAgIGVycm9ycy5mb3JFYWNoKGZ1bmN0aW9uIChtc2cpIHsgaGFuZGxlci5hZGQoJ2Vycm9yJywgbXNnKTsgfSk7XG5cbiAgICAgICAgaWYgKGZvcm1UeXBlID09PSAnZWRpdCdcbiAgICAgICAgICAgIHx8IChmb3JtVHlwZSA9PT0gJ3F1ZXN0aW9uJyAmJiBvbkFza1BhZ2VWMikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGhhbmRsZXIuY2xlYXIoJ3dhcm5pbmcnKTtcbiAgICAgICAgd2FybmluZ3MuZm9yRWFjaChmdW5jdGlvbiAobXNnKSB7IGhhbmRsZXIuYWRkKCd3YXJuaW5nJywgbXNnKTsgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlUG9wdXBFcnJvcnMoJGVsZW0sIHByb3BlcnR5LCBlcnJvcnMpIHtcblxuICAgICAgICBpZiAoISRlbGVtIHx8ICEkZWxlbS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvcnMubGVuZ3RoID09PSAwXG4gICAgICAgICAgICB8fCAoZXJyb3JzLmxlbmd0aCA9PT0gMSAmJiBlcnJvcnNbMF0gPT09ICcnKVxuICAgICAgICAgICAgfHwgISQoJ2h0bWwnKS5oYXMoJGVsZW0pLmxlbmd0aCkge1xuICAgICAgICAgICAgY2xlYXJQb3B1cEVycm9yKCRlbGVtKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNob3dFcnJvclBvcHVwKCRlbGVtLCBlcnJvcnMsIGdldFNpZGViYXJQb3B1cE9wdGlvbnMocHJvcGVydHksICdlcnJvcicpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNob3dFcnJvclBvcHVwKCRlbGVtLCBtZXNzYWdlc0FycmF5LCBwb3B1cE9wdGlvbnMpIHtcblxuICAgICAgICB2YXIgbWVzc2FnZSA9IG1lc3NhZ2VzQXJyYXkubGVuZ3RoID09PSAxXG4gICAgICAgICAgICA/IG1lc3NhZ2VzQXJyYXlbMF1cbiAgICAgICAgICAgIDogJzx1bD48bGk+JyArIG1lc3NhZ2VzQXJyYXkuam9pbignPC9saT48bGk+JykgKyAnPC9saT48L3VsPic7XG5cbiAgICAgICAgdmFyICRleGlzdGluZ1BvcHVwID0gJGVsZW0uZGF0YSgnZXJyb3ItcG9wdXAnKTtcbiAgICAgICAgaWYgKCRleGlzdGluZ1BvcHVwICYmICRleGlzdGluZ1BvcHVwLmlzKCc6dmlzaWJsZScpKSB7XG4gICAgICAgICAgICB2YXIgZXhpc3RpbmdNZXNzYWdlID0gJGVsZW0uZGF0YSgnZXJyb3ItbWVzc2FnZScpO1xuICAgICAgICAgICAgaWYgKGV4aXN0aW5nTWVzc2FnZSA9PT0gbWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIC8vIGlubGluZSBlcnJvciBtZXNzYWdlcyBkb24ndCBoYXZlIGFuaW1hdGVPZmZzZXRUb3BcbiAgICAgICAgICAgICAgICBpZiAoJGV4aXN0aW5nUG9wdXAuYW5pbWF0ZU9mZnNldFRvcCkge1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGV4aXN0aW5nIHBvcHVwIGNvdWxkIGhhdmUgYmVlbiB1bmRlcm5lYXRoIGFub3RoZXI7IGFkanVzdCBpdHMgcG9zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgJGV4aXN0aW5nUG9wdXAuYW5pbWF0ZU9mZnNldFRvcCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJGV4aXN0aW5nUG9wdXAuZmFkZU91dEFuZFJlbW92ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyICRwb3B1cCA9IFN0YWNrRXhjaGFuZ2UuaGVscGVycy5zaG93TWVzc2FnZSgkZWxlbSwgbWVzc2FnZSwgcG9wdXBPcHRpb25zKTtcbiAgICAgICAgJHBvcHVwLmZpbmQoJ2EnKS5hdHRyKCd0YXJnZXQnLCAnX2JsYW5rJyk7XG5cbiAgICAgICAgLy8gRG9uJ3QgdHJpZ2dlciB2YWxpZGF0aW9uIHdoZW4gdGhlIHVzZXIgaXMganVzdCBjbGlja2luZyBhbiBlcnJvciBtZXNzYWdlIHRvIGNsb3NlIGl0LlxuICAgICAgICAvLyBUaGlzIHdheSwgd2Ugd29uJ3QgcmUtc2hvdyB0aGUganVzdC1jbG9zZWQgbWVzc2FnZSBpZiB0aGUgdmFsaWRhdGlvbiByZXNwb25zZSBhcnJpdmVzIGFmdGVyIHRoZSBmaXJzdCBtZXNzYWdlIGZhZGVzIG91dC5cbiAgICAgICAgJHBvcHVwLmNsaWNrKGNsZWFyQmx1clRpbWVvdXRzKTtcblxuICAgICAgICAkZWxlbVxuICAgICAgICAgICAgLmFkZENsYXNzKCd2YWxpZGF0aW9uLWVycm9yJylcbiAgICAgICAgICAgIC5kYXRhKCdlcnJvci1wb3B1cCcsICRwb3B1cClcbiAgICAgICAgICAgIC5kYXRhKCdlcnJvci1tZXNzYWdlJywgbWVzc2FnZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xlYXJQb3B1cEVycm9yKCRlbGVtKSB7XG4gICAgICAgIHZhciAkcG9wdXAgPSAkZWxlbS5kYXRhKCdlcnJvci1wb3B1cCcpO1xuICAgICAgICBpZiAoJHBvcHVwICYmICRwb3B1cC5pcygnOnZpc2libGUnKSkge1xuICAgICAgICAgICAgJHBvcHVwLmZhZGVPdXRBbmRSZW1vdmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgICRlbGVtLnJlbW92ZUNsYXNzKCd2YWxpZGF0aW9uLWVycm9yJyk7XG4gICAgICAgICRlbGVtLnJlbW92ZURhdGEoJ2Vycm9yLXBvcHVwJyk7XG4gICAgICAgICRlbGVtLnJlbW92ZURhdGEoJ2Vycm9yLW1lc3NhZ2UnKTtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIGFyZUFueUVycm9yc092ZXJTaWRlYmFyKCkge1xuICAgICAgICB2YXIgcmV0ID0gZmFsc2U7XG4gICAgICAgIHZhciAkc2lkZWJhciA9ICQoJyNzaWRlYmFyLCAuc2lkZWJhcicpLmZpcnN0KCk7XG5cbiAgICAgICAgaWYgKCEkc2lkZWJhci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzaWRlYmFyTGVmdCA9ICRzaWRlYmFyLm9mZnNldCgpLmxlZnQ7XG5cbiAgICAgICAgJCgnLm1lc3NhZ2UnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkbWVzc2FnZSA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJG1lc3NhZ2Uub2Zmc2V0KCkubGVmdCArICRtZXNzYWdlLm91dGVyV2lkdGgoKSA+IHNpZGViYXJMZWZ0KSB7XG4gICAgICAgICAgICAgICAgcmV0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGluaXRPbkJsdXI6IGluaXRPbkJsdXIsXG4gICAgICAgIGluaXRPbkJsdXJBbmRTdWJtaXQ6IGluaXRPbkJsdXJBbmRTdWJtaXQsXG4gICAgICAgIHNob3dFcnJvcnNBZnRlclN1Ym1pc3Npb246IHNob3dFcnJvcnNBZnRlclN1Ym1pc3Npb24sXG4gICAgICAgIHZhbGlkYXRlUG9zdEZpZWxkczogdmFsaWRhdGVQb3N0RmllbGRzLFxuICAgICAgICBzY3JvbGxUb0Vycm9yczogc2Nyb2xsVG9FcnJvcnNcbiAgICB9O1xufSkoKTtcbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuX193ZWJwYWNrX3JlcXVpcmVfXy5uID0gKG1vZHVsZSkgPT4ge1xuXHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cblx0XHQoKSA9PiAobW9kdWxlWydkZWZhdWx0J10pIDpcblx0XHQoKSA9PiAobW9kdWxlKTtcblx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgeyBhOiBnZXR0ZXIgfSk7XG5cdHJldHVybiBnZXR0ZXI7XG59OyIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18ubyA9IChvYmosIHByb3ApID0+IChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkiLCIvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSAoZXhwb3J0cykgPT4ge1xuXHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcblx0fVxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiOyIsIi8vIFdlIG5lZWQgdG8gc2V0IHRoZSBwdWJsaWMgcGF0aCBhdCBydW50aW1lIGJhc2VkIG9uIHRoZSBHbG9iYWxSb290IHNpdGUgc2V0dGluZy5cbi8vIChXZSBkb24ndCBrbm93IGF0IGJ1aWxkIHRpbWUgd2hlcmUgdGhlIHN0YXRpYyBmaWxlcyB3aWxsIGJlLFxuLy8gc2luY2Ugd2UgY291bGQgYmUgZGVwbG95ZWQgb24tcHJlbWlzZS4pXG4vLyBUaGUgdmFsdWUgb2YgdGhhdCBzaXRlIHNldHRpbmcgZ2V0cyB3cml0dGVuIG91dCB0byB0aGUgZG9tIGluIE1hc3Rlci5jc2h0bWxcbi8vIChzZWUgSmF2YVNjcmlwdEhlbHBlci5QdWJsaWNQYXRoKCkpIHNvIHRoYXQgd2UgY2FuIHJlYWQgaXQgaGVyZVxuX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIndlYnBhY2stcHVibGljLXBhdGhcIikuaW5uZXJUZXh0ICsgXCJKcy9cIjtcblxuZXhwb3J0IHsgfTtcbiIsImltcG9ydCBcIi4uL0xlZ2FjeUpTL21hcmtkb3duL0NvbW1vbm1hcmsuQ29udmVydGVyLmpzXCI7XG5pbXBvcnQgXCIuLi9MZWdhY3lKUy9tYXJrZG93bi9NYXJrZG93bi5Db252ZXJ0ZXIuanNcIjtcbmltcG9ydCBcIi4uL0xlZ2FjeUpTL21hcmtkb3duL01hcmtkb3duLkVkaXRvci5qc1wiO1xuaW1wb3J0IFwiLi4vTGVnYWN5SlMvbWFya2Rvd24vTWFya2Rvd25TdGFja0V4Y2hhbmdlLzAxX01hcmtkb3duRWRpdG9yLmpzXCI7XG5pbXBvcnQgXCIuLi9MZWdhY3lKUy9tYXJrZG93bi9NYXJrZG93blN0YWNrRXhjaGFuZ2UvMDJfRWRpdG9ySW5pdGlhbGl6YXRpb24uanNcIjtcbmltcG9ydCBcIi4uL0xlZ2FjeUpTL21hcmtkb3duL01hcmtkb3duU3RhY2tFeGNoYW5nZS8wM19IZWFydGJlYXQuanNcIjtcbmltcG9ydCBcIi4uL0xlZ2FjeUpTL21hcmtkb3duL01hcmtkb3duU3RhY2tFeGNoYW5nZS8wNF9OYXZQcmV2ZW50aW9uLmpzXCI7XG5pbXBvcnQgXCIuLi9MZWdhY3lKUy9tYXJrZG93bi9NYXJrZG93blN0YWNrRXhjaGFuZ2UvMTBfVGV4dGFyZWFSZXNpemVyUGx1Z2luLmpzXCI7XG5pbXBvcnQgXCIuLi9MZWdhY3lKUy9pbWFnZS11cGxvYWQuanNcIjtcbmltcG9ydCBcIi4uL0xlZ2FjeUpTL3Bvc3QtdmFsaWRhdGlvbi5qc1wiO1xuLy8gY2FjaGUgYnJlYWtlclxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9