| Server IP : 85.158.181.41 / Your IP : 216.73.217.12 Web Server : Apache System : Linux cloud9-vm129 6.1.178+1-ph #ph SMP PREEMPT_DYNAMIC Wed Jul 29 09:00:54 UTC 2026 x86_64 User : moncbefd ( 1024) PHP Version : 7.3.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/moncbefd/www.moneta.at/public/theme/javascripts/system/widgets/ |
Upload File : |
'use strict';
/* --------------------------------------------------------------
cart_handler.js 2019-06-20
Gambio GmbH
http://www.gambio.de
Copyright (c) 2019 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
/**
* Component for handling the add to cart and wishlist features
* at the product details and the category listing pages. It cares
* for attributes, properties, quantity and all other
* relevant data for adding an item to the basket or wishlist
*/
gambio.widgets.module('cart_handler', ['hooks', 'form', 'xhr', gambio.source + '/libs/events', gambio.source + '/libs/modal.ext-magnific', gambio.source + '/libs/modal'], function (data) {
'use strict';
// ########## VARIABLE INITIALIZATION ##########
var $this = $(this),
$body = $('body'),
$window = $(window),
busy = false,
ajax = null,
timeout = 0,
defaults = {
// AJAX "add to cart" URL
addCartUrl: 'shop.php?do=Cart/BuyProduct',
// AJAX "add to cart" URL for customizer products
addCartCustomizerUrl: 'shop.php?do=Cart/Add',
// AJAX URL to perform a value check
checkUrl: 'shop.php?do=CheckStatus',
// AJAX URL to perform the add to wishlist
wishlistUrl: 'shop.php?do=WishList/Add',
// Submit URL for price offer button
priceOfferUrl: 'gm_price_offer.php',
// Submit method for price offer
priceOfferMethod: 'get',
// Selector for the cart dropdown
dropdown: '#head_shopping_cart',
// "Add to cart" buttons selectors
cartButtons: '.js-btn-add-to-cart',
// "Wishlist" buttons selectors
wishlistButtons: '.btn-wishlist',
// "Price offer" buttons selectors
priceOfferButtons: '.btn-price-offer',
// Selector for the attribute fields
attributes: '.js-calculate',
// Selector for the quantity
quantity: '.js-calculate-qty',
// URL where to get the theme for the dropdown
tpl: null,
// Show attribute images in product images swiper (if possible)
// -- this feature is not supported yet --
attributImagesSwiper: false,
// Trigger the attribute images to this selectors
triggerAttrImagesTo: '#product_image_swiper, #product_thumbnail_swiper, ' + '#product_thumbnail_swiper_mobile',
// Class that gets added to the button on processing
processingClass: 'loading',
// Duration for that the success or fail class gets added to the button
processingDuration: 2000,
// AJAX response content selectors
selectorMapping: {
attributeImages: '.attribute-images',
buttons: '.shopping-cart-button',
giftContent: '.gift-cart-content-wrapper',
giftLayer: '.gift-cart-layer',
shareContent: '.share-cart-content-wrapper',
shareLayer: '.share-cart-layer',
hiddenOptions: '#cart_quantity .hidden-options',
message: '.global-error-messages',
messageCart: '.cart-error-msg',
messageHelp: '.help-block',
modelNumber: '.model-number',
modelNumberText: '.model-number-text',
price: '.current-price-container',
propertiesForm: '.properties-selection-form',
quantity: '.products-quantity-value',
ribbonSpecial: '.ribbon-special',
shippingInformation: '#shipping-information-layer',
shippingTime: '.products-shipping-time-value',
shippingTimeImage: '.img-shipping-time img',
totals: '#cart_quantity .total-box',
weight: '.products-details-weight-container span'
},
page: 'product-listing'
},
options = $.extend(true, {}, defaults, data),
module = {},
mobile = $(window).width() <= 767;
// ########## HELPER FUNCTIONS ##########
/**
* Helper function that updates the button
* state with an error or success class for
* a specified duration
* @param {object} $target jQuery selection of the target button
* @param {string} state The state string that gets added to the loading class
* @private
*/
var _addButtonState = function _addButtonState($target, state) {
var timer = setTimeout(function () {
$target.removeClass(options.processingClass + ' ' + options.processingClass + state);
}, options.processingDuration);
$target.data('timer', timer).addClass(options.processingClass + state);
};
/**
* Helper function to set the messages and the
* button state.
* @param {object} data Result form the ajax request
* @param {object} $form jQuery selecion of the form
* @param {boolean} disableButtons If true, the button state gets set to (in)active
* @param {boolean} showNoCombiMesssage If true, the error message for missing property combination selection will be displayed
* @private
*/
var _stateManager = function _stateManager(data, $form, disableButtons, showNoCombiSelectedMesssage) {
// Remove the attribute images from the common content
// so that it doesn't get rendered anymore. Then trigger
// an event to the given selectors and deliver the
// attrImages object
if (options.attributImagesSwiper && data.attrImages && data.attrImages.length) {
delete data.content.images;
$(options.triggerAttrImagesTo).trigger(jse.libs.theme.events.SLIDES_UPDATE(), { attributes: data.attrImages });
}
// Set the messages given inside the data.content object
$.each(data.content, function (i, v) {
var $element = $form.parent().find(options.selectorMapping[v.selector]);
if ((!showNoCombiSelectedMesssage || v.value === '') && i === 'messageNoCombiSelected') {
return true;
}
switch (v.type) {
case 'hide':
if (v.value === 'true') {
$element.hide();
} else {
$element.show();
}
break;
case 'html':
$element.html(v.value);
break;
case 'attribute':
$element.attr(v.key, v.value);
break;
case 'replace':
if (v.value) {
$element.replaceWith(v.value);
} else {
$element.addClass('hidden').empty();
}
break;
default:
$element.text(v.value);
break;
}
});
// Dis- / Enable the buttons
if (disableButtons) {
var $buttons = $form.find(options.cartButtons);
if (data.success) {
$buttons.removeClass('inactive');
$buttons.removeClass('btn-inactive');
$buttons.prop("disabled", false);
} else {
$buttons.addClass('inactive');
$buttons.addClass('btn-inactive');
$buttons.prop("disabled", true);
}
}
if (data.content.message) {
var $errorField = $form.find(options.selectorMapping[data.content.message.selector]);
if (data.content.message.value) {
$errorField.removeClass('hidden').show();
} else {
$errorField.addClass('hidden').hide();
if (showNoCombiSelectedMesssage && data.content.messageNoCombiSelected !== undefined && data.content.messageNoCombiSelected) {
if (data.content.messageNoCombiSelected.value) {
$errorField.removeClass('hidden').show();
} else {
$errorField.addClass('hidden').hide();
}
}
}
}
$window.trigger(jse.libs.theme.events.STICKYBOX_CONTENT_CHANGE());
};
/**
* Helper function to send the ajax
* On success redirect to a given url, open a layer with
* a message or add the item to the cart-dropdown directly
* (by triggering an event to the body)
* @param {object} data Form data
* @param {object} $form The form to fill
* @param {string} url The URL for the AJAX request
* @private
*/
var _addToSomewhere = function _addToSomewhere(data, $form, url, $button) {
function callback() {
jse.libs.xhr.post({ url: url, data: data }, true).done(function (result) {
try {
// Fill the page with the result from the ajax
_stateManager(result, $form, false);
// If the AJAX was successful execute
// a custom functionality
if (result.success) {
switch (result.type) {
case 'url':
if (result.url.substr(0, 4) !== 'http') {
location.href = jse.core.config.get('appUrl') + '/' + result.url;
} else {
location.href = result.url;
}
break;
case 'dropdown':
$body.trigger(jse.libs.theme.events.CART_UPDATE(), [true]);
break;
case 'layer':
jse.libs.theme.modal.info({ title: result.title, content: result.msg });
break;
default:
break;
}
}
} catch (ignore) {}
_addButtonState($button, '-success');
}).fail(function () {
_addButtonState($button, '-fail');
}).always(function () {
// Reset the busy flag to be able to perform
// further AJAX requests
busy = false;
});
}
if (!busy) {
// only execute the ajax
// if there is no pending ajax call
busy = true;
jse.libs.hooks.execute(jse.libs.hooks.keys.shop.cart.add, data, 500).then(callback).catch(callback);
}
};
// ########## EVENT HANDLER ##########
/**
* Handler for the submit form / click
* on "add to cart" & "wishlist" button.
* It performs a check on the availability
* of the combination and quantity. If
* successful it performs the add to cart
* or wishlist action, if it's not a
* "check" call
* @param {object} e jQuery event object
* @private
*/
var _submitHandler = function _submitHandler(e) {
if (e) {
e.preventDefault();
}
var $self = $(this),
$form = $self.is('form') ? $self : $self.closest('form'),
customizer = $form.hasClass('customizer'),
properties = !!$form.find('.properties-selection-form').length,
module = properties ? '' : '/Attributes',
showNoCombiSelectedMesssage = e && e.data && e.data.target && e.data.target !== 'check';
if ($form.length) {
// Show properties overlay
// to disable user interaction
// before markup replace
if (properties) {
$this.addClass('loading');
}
var formdata = jse.libs.form.getData($form, null, true);
formdata.target = e && e.data && e.data.target ? e.data.target : 'check';
formdata.isProductInfo = $form.hasClass('product-info') ? 1 : 0;
// Abort previous check ajax if
// there is one in progress
if (ajax && e) {
ajax.abort();
}
// Add processing-class to the button
// and remove old timed events
if (formdata.target !== 'check') {
var timer = $self.data('timer');
if (timer) {
clearTimeout(timer);
}
$self.removeClass(options.processingClass + '-success ' + options.processingClass + '-fail').addClass(options.processingClass);
}
ajax = jse.libs.xhr.get({
url: options.checkUrl + module,
data: formdata
}, true).done(function (result) {
_stateManager(result, $form, true, showNoCombiSelectedMesssage);
$this.removeClass('loading');
if (result.success) {
var event = null,
url = null;
switch (formdata.target) {
case 'wishlist':
if (customizer) {
event = jse.libs.theme.events.ADD_CUSTOMIZER_WISHLIST();
}
url = options.wishlistUrl;
break;
case 'cart':
if (customizer) {
event = jse.libs.theme.events.ADD_CUSTOMIZER_CART();
url = options.addCartCustomizerUrl;
} else {
url = options.addCartUrl;
}
break;
case 'price_offer':
$form.attr('action', options.priceOfferUrl).attr('method', options.priceOfferMethod);
$form.off('submit');
$form.submit();
return;
default:
setTimeout(function () {
$window.trigger(jse.libs.theme.events.STICKYBOX_CONTENT_CHANGE());
}, 250);
break;
}
if (event) {
var deferred = $.Deferred();
deferred.done(function (customizerRandom) {
formdata[customizerRandom] = 0;
_addToSomewhere(formdata, $form, url, $self);
}).fail(function () {
_addButtonState($self, '-fail');
});
$body.trigger(event, [{ 'deferred': deferred, 'dataset': formdata }]);
} else if (url) {
_addToSomewhere(formdata, $form, url, $self);
}
}
}).fail(function () {
_addButtonState($self, '-fail');
});
}
};
/**
* Keyup handler for quantity input field
*
* @param e
* @private
*/
var _keyupHandler = function _keyupHandler(e) {
clearTimeout(timeout);
timeout = setTimeout(function () {
_submitHandler.call(this, e);
}.bind(this), 300);
};
/**
* Event handler for the add to cart button, that shows or hides the throbber.
*/
var _addToCartThrobberHandler = function _addToCartThrobberHandler(e) {
var $btn = $(this);
var $btnFake = $this.find(".btn-add-to-cart-fake");
var formReady = true;
$(".properties-selection-form select").each(function () {
var val = $(this).val();
if (!val || val < 1) {
formReady = false;
}
});
if (formReady) {
$btn.hide();
$btnFake.show().prop("disabled", true).prepend('<span class="throbbler"></span>');
}
};
/**
* Cart dropdown oben event handler for the body.
*/
var _cartDropdownOpenHandler = function _cartDropdownOpenHandler(e) {
var $btn = $this.find("[name=btn-add-to-cart]");
var $btnFake = $this.find(".btn-add-to-cart-fake");
var fakeOrigLabel = $btnFake.html();
var productCount = $(".cart-products-count").html();
var textPhrases = JSON.parse($('#product-details-text-phrases').html());
console.log(textPhrases['productsInCartSuffix']);
$btnFake.html("<i class=\"fa fa-check\"></i> " + parseInt(productCount) + textPhrases['productsInCartSuffix']).prop("disabled", true).addClass("btn-buy-complete");
setTimeout(function () {
$btnFake.html(fakeOrigLabel).removeClass("btn-buy-complete").hide().prop("disabled", false);
$(".throbbler", $btn).remove();
$btn.show();
}, 5000);
};
// ########## INITIALIZATION ##########
/**
* Init function of the widget
* @constructor
*/
module.init = function (done) {
var $forms = $this.find('form');
if (options.page === 'product-info') {
$forms.find("[name=btn-add-to-cart]").on('mouseup', _addToCartThrobberHandler);
$("body").on('CART_DROPDOWN_OPEN', _cartDropdownOpenHandler);
}
$forms.on('submit', { 'target': 'cart' }, _submitHandler).on('click', options.wishlistButtons, { 'target': 'wishlist' }, _submitHandler).on('click', options.priceOfferButtons, { 'target': 'price_offer' }, _submitHandler).on('change', options.attributes, { 'target': 'check' }, _submitHandler).on('blur', options.quantity, { 'target': 'check' }, function (e) {
_submitHandler(e);
}).on('keyup', options.quantity, { 'target': 'check' }, _keyupHandler);
// Fallback if the backend renders incorrect data
// on initial page call
$forms.not('.no-status-check').each(function () {
_submitHandler.call($(this));
});
done();
};
// Return data to widget engine
return module;
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndpZGdldHMvY2FydF9oYW5kbGVyLmpzIl0sIm5hbWVzIjpbImdhbWJpbyIsIndpZGdldHMiLCJtb2R1bGUiLCJzb3VyY2UiLCJkYXRhIiwiJHRoaXMiLCIkIiwiJGJvZHkiLCIkd2luZG93Iiwid2luZG93IiwiYnVzeSIsImFqYXgiLCJ0aW1lb3V0IiwiZGVmYXVsdHMiLCJhZGRDYXJ0VXJsIiwiYWRkQ2FydEN1c3RvbWl6ZXJVcmwiLCJjaGVja1VybCIsIndpc2hsaXN0VXJsIiwicHJpY2VPZmZlclVybCIsInByaWNlT2ZmZXJNZXRob2QiLCJkcm9wZG93biIsImNhcnRCdXR0b25zIiwid2lzaGxpc3RCdXR0b25zIiwicHJpY2VPZmZlckJ1dHRvbnMiLCJhdHRyaWJ1dGVzIiwicXVhbnRpdHkiLCJ0cGwiLCJhdHRyaWJ1dEltYWdlc1N3aXBlciIsInRyaWdnZXJBdHRySW1hZ2VzVG8iLCJwcm9jZXNzaW5nQ2xhc3MiLCJwcm9jZXNzaW5nRHVyYXRpb24iLCJzZWxlY3Rvck1hcHBpbmciLCJhdHRyaWJ1dGVJbWFnZXMiLCJidXR0b25zIiwiZ2lmdENvbnRlbnQiLCJnaWZ0TGF5ZXIiLCJzaGFyZUNvbnRlbnQiLCJzaGFyZUxheWVyIiwiaGlkZGVuT3B0aW9ucyIsIm1lc3NhZ2UiLCJtZXNzYWdlQ2FydCIsIm1lc3NhZ2VIZWxwIiwibW9kZWxOdW1iZXIiLCJtb2RlbE51bWJlclRleHQiLCJwcmljZSIsInByb3BlcnRpZXNGb3JtIiwicmliYm9uU3BlY2lhbCIsInNoaXBwaW5nSW5mb3JtYXRpb24iLCJzaGlwcGluZ1RpbWUiLCJzaGlwcGluZ1RpbWVJbWFnZSIsInRvdGFscyIsIndlaWdodCIsInBhZ2UiLCJvcHRpb25zIiwiZXh0ZW5kIiwibW9iaWxlIiwid2lkdGgiLCJfYWRkQnV0dG9uU3RhdGUiLCIkdGFyZ2V0Iiwic3RhdGUiLCJ0aW1lciIsInNldFRpbWVvdXQiLCJyZW1vdmVDbGFzcyIsImFkZENsYXNzIiwiX3N0YXRlTWFuYWdlciIsIiRmb3JtIiwiZGlzYWJsZUJ1dHRvbnMiLCJzaG93Tm9Db21iaVNlbGVjdGVkTWVzc3NhZ2UiLCJhdHRySW1hZ2VzIiwibGVuZ3RoIiwiY29udGVudCIsImltYWdlcyIsInRyaWdnZXIiLCJqc2UiLCJsaWJzIiwidGhlbWUiLCJldmVudHMiLCJTTElERVNfVVBEQVRFIiwiZWFjaCIsImkiLCJ2IiwiJGVsZW1lbnQiLCJwYXJlbnQiLCJmaW5kIiwic2VsZWN0b3IiLCJ2YWx1ZSIsInR5cGUiLCJoaWRlIiwic2hvdyIsImh0bWwiLCJhdHRyIiwia2V5IiwicmVwbGFjZVdpdGgiLCJlbXB0eSIsInRleHQiLCIkYnV0dG9ucyIsInN1Y2Nlc3MiLCJwcm9wIiwiJGVycm9yRmllbGQiLCJtZXNzYWdlTm9Db21iaVNlbGVjdGVkIiwidW5kZWZpbmVkIiwiU1RJQ0tZQk9YX0NPTlRFTlRfQ0hBTkdFIiwiX2FkZFRvU29tZXdoZXJlIiwidXJsIiwiJGJ1dHRvbiIsImNhbGxiYWNrIiwieGhyIiwicG9zdCIsImRvbmUiLCJyZXN1bHQiLCJzdWJzdHIiLCJsb2NhdGlvbiIsImhyZWYiLCJjb3JlIiwiY29uZmlnIiwiZ2V0IiwiQ0FSVF9VUERBVEUiLCJtb2RhbCIsImluZm8iLCJ0aXRsZSIsIm1zZyIsImlnbm9yZSIsImZhaWwiLCJhbHdheXMiLCJob29rcyIsImV4ZWN1dGUiLCJrZXlzIiwic2hvcCIsImNhcnQiLCJhZGQiLCJ0aGVuIiwiY2F0Y2giLCJfc3VibWl0SGFuZGxlciIsImUiLCJwcmV2ZW50RGVmYXVsdCIsIiRzZWxmIiwiaXMiLCJjbG9zZXN0IiwiY3VzdG9taXplciIsImhhc0NsYXNzIiwicHJvcGVydGllcyIsInRhcmdldCIsImZvcm1kYXRhIiwiZm9ybSIsImdldERhdGEiLCJpc1Byb2R1Y3RJbmZvIiwiYWJvcnQiLCJjbGVhclRpbWVvdXQiLCJldmVudCIsIkFERF9DVVNUT01JWkVSX1dJU0hMSVNUIiwiQUREX0NVU1RPTUlaRVJfQ0FSVCIsIm9mZiIsInN1Ym1pdCIsImRlZmVycmVkIiwiRGVmZXJyZWQiLCJjdXN0b21pemVyUmFuZG9tIiwiX2tleXVwSGFuZGxlciIsImNhbGwiLCJiaW5kIiwiX2FkZFRvQ2FydFRocm9iYmVySGFuZGxlciIsIiRidG4iLCIkYnRuRmFrZSIsImZvcm1SZWFkeSIsInZhbCIsInByZXBlbmQiLCJfY2FydERyb3Bkb3duT3BlbkhhbmRsZXIiLCJmYWtlT3JpZ0xhYmVsIiwicHJvZHVjdENvdW50IiwidGV4dFBocmFzZXMiLCJKU09OIiwicGFyc2UiLCJjb25zb2xlIiwibG9nIiwicGFyc2VJbnQiLCJyZW1vdmUiLCJpbml0IiwiJGZvcm1zIiwib24iLCJub3QiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7QUFVQTs7Ozs7O0FBTUFBLE9BQU9DLE9BQVAsQ0FBZUMsTUFBZixDQUNJLGNBREosRUFHSSxDQUNJLE9BREosRUFFSSxNQUZKLEVBR0ksS0FISixFQUlJRixPQUFPRyxNQUFQLEdBQWdCLGNBSnBCLEVBS0lILE9BQU9HLE1BQVAsR0FBZ0IsMEJBTHBCLEVBTUlILE9BQU9HLE1BQVAsR0FBZ0IsYUFOcEIsQ0FISixFQVlJLFVBQVVDLElBQVYsRUFBZ0I7O0FBRVo7O0FBRVI7O0FBRVEsUUFBSUMsUUFBUUMsRUFBRSxJQUFGLENBQVo7QUFBQSxRQUNJQyxRQUFRRCxFQUFFLE1BQUYsQ0FEWjtBQUFBLFFBRUlFLFVBQVVGLEVBQUVHLE1BQUYsQ0FGZDtBQUFBLFFBR0lDLE9BQU8sS0FIWDtBQUFBLFFBSUlDLE9BQU8sSUFKWDtBQUFBLFFBS0lDLFVBQVUsQ0FMZDtBQUFBLFFBTUlDLFdBQVc7QUFDUDtBQUNBQyxvQkFBWSw2QkFGTDtBQUdQO0FBQ0FDLDhCQUFzQixzQkFKZjtBQUtQO0FBQ0FDLGtCQUFVLHlCQU5IO0FBT1A7QUFDQUMscUJBQWEsMEJBUk47QUFTUDtBQUNBQyx1QkFBZSxvQkFWUjtBQVdQO0FBQ0FDLDBCQUFrQixLQVpYO0FBYVA7QUFDQUMsa0JBQVUscUJBZEg7QUFlUDtBQUNBQyxxQkFBYSxxQkFoQk47QUFpQlA7QUFDQUMseUJBQWlCLGVBbEJW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QUFDSCxLQTFCRDs7QUE0QkE7QUFDQSxXQUFPMUcsTUFBUDtBQUNILENBaGZMIiwiZmlsZSI6IndpZGdldHMvY2FydF9oYW5kbGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiBjYXJ0X2hhbmRsZXIuanMgMjAxOS0wNi0yMFxuIEdhbWJpbyBHbWJIXG4gaHR0cDovL3d3dy5nYW1iaW8uZGVcbiBDb3B5cmlnaHQgKGMpIDIwMTkgR2FtYmlvIEdtYkhcbiBSZWxlYXNlZCB1bmRlciB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKFZlcnNpb24gMilcbiBbaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAuaHRtbF1cbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbi8qKlxuICogQ29tcG9uZW50IGZvciBoYW5kbGluZyB0aGUgYWRkIHRvIGNhcnQgYW5kIHdpc2hsaXN0IGZlYXR1cmVzXG4gKiBhdCB0aGUgcHJvZHVjdCBkZXRhaWxzIGFuZCB0aGUgY2F0ZWdvcnkgbGlzdGluZyBwYWdlcy4gSXQgY2FyZXNcbiAqIGZvciBhdHRyaWJ1dGVzLCBwcm9wZXJ0aWVzLCBxdWFudGl0eSBhbmQgYWxsIG90aGVyXG4gKiByZWxldmFudCBkYXRhIGZvciBhZGRpbmcgYW4gaXRlbSB0byB0aGUgYmFza2V0IG9yIHdpc2hsaXN0XG4gKi9cbmdhbWJpby53aWRnZXRzLm1vZHVsZShcbiAgICAnY2FydF9oYW5kbGVyJyxcblxuICAgIFtcbiAgICAgICAgJ2hvb2tzJyxcbiAgICAgICAgJ2Zvcm0nLFxuICAgICAgICAneGhyJyxcbiAgICAgICAgZ2FtYmlvLnNvdXJjZSArICcvbGlicy9ldmVudHMnLFxuICAgICAgICBnYW1iaW8uc291cmNlICsgJy9saWJzL21vZGFsLmV4dC1tYWduaWZpYycsXG4gICAgICAgIGdhbWJpby5zb3VyY2UgKyAnL2xpYnMvbW9kYWwnXG4gICAgXSxcblxuICAgIGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4vLyAjIyMjIyMjIyMjIFZBUklBQkxFIElOSVRJQUxJWkFUSU9OICMjIyMjIyMjIyNcblxuICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpLFxuICAgICAgICAgICAgJGJvZHkgPSAkKCdib2R5JyksXG4gICAgICAgICAgICAkd2luZG93ID0gJCh3aW5kb3cpLFxuICAgICAgICAgICAgYnVzeSA9IGZhbHNlLFxuICAgICAgICAgICAgYWpheCA9IG51bGwsXG4gICAgICAgICAgICB0aW1lb3V0ID0gMCxcbiAgICAgICAgICAgIGRlZmF1bHRzID0ge1xuICAgICAgICAgICAgICAgIC8vIEFKQVggXCJhZGQgdG8gY2FydFwiIFVSTFxuICAgICAgICAgICAgICAgIGFkZENhcnRVcmw6ICdzaG9wLnBocD9kbz1DYXJ0L0J1eVByb2R1Y3QnLFxuICAgICAgICAgICAgICAgIC8vIEFKQVggXCJhZGQgdG8gY2FydFwiIFVSTCBmb3IgY3VzdG9taXplciBwcm9kdWN0c1xuICAgICAgICAgICAgICAgIGFkZENhcnRDdXN0b21pemVyVXJsOiAnc2hvcC5waHA/ZG89Q2FydC9BZGQnLFxuICAgICAgICAgICAgICAgIC8vIEFKQVggVVJMIHRvIHBlcmZvcm0gYSB2YWx1ZSBjaGVja1xuICAgICAgICAgICAgICAgIGNoZWNrVXJsOiAnc2hvcC5waHA/ZG89Q2hlY2tTdGF0dXMnLFxuICAgICAgICAgICAgICAgIC8vIEFKQVggVVJMIHRvIHBlcmZvcm0gdGhlIGFkZCB0byB3aXNobGlzdFxuICAgICAgICAgICAgICAgIHdpc2hsaXN0VXJsOiAnc2hvcC5waHA/ZG89V2lzaExpc3QvQWRkJyxcbiAgICAgICAgICAgICAgICAvLyBTdWJtaXQgVVJMIGZvciBwcmljZSBvZmZlciBidXR0b25cbiAgICAgICAgICAgICAgICBwcmljZU9mZmVyVXJsOiAnZ21fcHJpY2Vfb2ZmZXIucGhwJyxcbiAgICAgICAgICAgICAgICAvLyBTdWJtaXQgbWV0aG9kIGZvciBwcmljZSBvZmZlclxuICAgICAgICAgICAgICAgIHByaWNlT2ZmZXJNZXRob2Q6ICdnZXQnLFxuICAgICAgICAgICAgICAgIC8vIFNlbGVjdG9yIGZvciB0aGUgY2FydCBkcm9wZG93blxuICAgICAgICAgICAgICAgIGRyb3Bkb3duOiAnI2hlYWRfc2hvcHBpbmdfY2FydCcsXG4gICAgICAgICAgICAgICAgLy8gXCJBZGQgdG8gY2FydFwiIGJ1dHRvbnMgc2VsZWN0b3JzXG4gICAgICAgICAgICAgICAgY2FydEJ1dHRvbnM6ICcuanMtYnRuLWFkZC10by1jYXJ0JyxcbiAgICAgICAgICAgICAgICAvLyBcIldpc2hsaXN0XCIgYnV0dG9ucyBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICB3aXNobGlzdEJ1dHRvbnM6ICcuYnRuLXdpc2hsaXN0JyxcbiAgICAgICAgICAgICAgICAvLyBcIlByaWNlIG9mZmVyXCIgYnV0dG9ucyBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICBwcmljZU9mZmVyQnV0dG9uczogJy5idG4tcHJpY2Utb2ZmZXInLFxuICAgICAgICAgICAgICAgIC8vIFNlbGVjdG9yIGZvciB0aGUgYXR0cmlidXRlIGZpZWxkc1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6ICcuanMtY2FsY3VsYXRlJyxcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3RvciBmb3IgdGhlIHF1YW50aXR5XG4gICAgICAgICAgICAgICAgcXVhbnRpdHk6ICcuanMtY2FsY3VsYXRlLXF0eScsXG4gICAgICAgICAgICAgICAgLy8gVVJMIHdoZXJlIHRvIGdldCB0aGUgdGhlbWUgZm9yIHRoZSBkcm9wZG93blxuICAgICAgICAgICAgICAgIHRwbDogbnVsbCxcbiAgICAgICAgICAgICAgICAvLyBTaG93IGF0dHJpYnV0ZSBpbWFnZXMgaW4gcHJvZHVjdCBpbWFnZXMgc3dpcGVyIChpZiBwb3NzaWJsZSlcbiAgICAgICAgICAgICAgICAvLyAtLSB0aGlzIGZlYXR1cmUgaXMgbm90IHN1cHBvcnRlZCB5ZXQgLS1cbiAgICAgICAgICAgICAgICBhdHRyaWJ1dEltYWdlc1N3aXBlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgLy8gVHJpZ2dlciB0aGUgYXR0cmlidXRlIGltYWdlcyB0byB0aGlzIHNlbGVjdG9yc1xuICAgICAgICAgICAgICAgIHRyaWdnZXJBdHRySW1hZ2VzVG86ICcjcHJvZHVjdF9pbWFnZV9zd2lwZXIsICNwcm9kdWN0X3RodW1ibmFpbF9zd2lwZXIsICdcbiAgICAgICAgICAgICAgICAgICAgKyAnI3Byb2R1Y3RfdGh1bWJuYWlsX3N3aXBlcl9tb2JpbGUnLFxuICAgICAgICAgICAgICAgIC8vIENsYXNzIHRoYXQgZ2V0cyBhZGRlZCB0byB0aGUgYnV0dG9uIG9uIHByb2Nlc3NpbmdcbiAgICAgICAgICAgICAgICBwcm9jZXNzaW5nQ2xhc3M6ICdsb2FkaW5nJyxcbiAgICAgICAgICAgICAgICAvLyBEdXJhdGlvbiBmb3IgdGhhdCB0aGUgc3VjY2VzcyBvciBmYWlsIGNsYXNzIGdldHMgYWRkZWQgdG8gdGhlIGJ1dHRvblxuICAgICAgICAgICAgICAgIHByb2Nlc3NpbmdEdXJhdGlvbjogMjAwMCxcbiAgICAgICAgICAgICAgICAvLyBBSkFYIHJlc3BvbnNlIGNvbnRlbnQgc2VsZWN0b3JzXG4gICAgICAgICAgICAgICAgc2VsZWN0b3JNYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUltYWdlczogJy5hdHRyaWJ1dGUtaW1hZ2VzJyxcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uczogJy5zaG9wcGluZy1jYXJ0LWJ1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgIGdpZnRDb250ZW50OiAnLmdpZnQtY2FydC1jb250ZW50LXdyYXBwZXInLFxuICAgICAgICAgICAgICAgICAgICBnaWZ0TGF5ZXI6ICcuZ2lmdC1jYXJ0LWxheWVyJyxcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVDb250ZW50OiAnLnNoYXJlLWNhcnQtY29udGVudC13cmFwcGVyJyxcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVMYXllcjogJy5zaGFyZS1jYXJ0LWxheWVyJyxcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuT3B0aW9uczogJyNjYXJ0X3F1YW50aXR5IC5oaWRkZW4tb3B0aW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICcuZ2xvYmFsLWVycm9yLW1lc3NhZ2VzJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNhcnQ6ICcuY2FydC1lcnJvci1tc2cnLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlSGVscDogJy5oZWxwLWJsb2NrJyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxOdW1iZXI6ICcubW9kZWwtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxOdW1iZXJUZXh0OiAnLm1vZGVsLW51bWJlci10ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgcHJpY2U6ICcuY3VycmVudC1wcmljZS1jb250YWluZXInLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzRm9ybTogJy5wcm9wZXJ0aWVzLXNlbGVjdGlvbi1mb3JtJyxcbiAgICAgICAgICAgICAgICAgICAgcXVhbnRpdHk6ICcucHJvZHVjdHMtcXVhbnRpdHktdmFsdWUnLFxuICAgICAgICAgICAgICAgICAgICByaWJib25TcGVjaWFsOiAnLnJpYmJvbi1zcGVjaWFsJyxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdJbmZvcm1hdGlvbjogJyNzaGlwcGluZy1pbmZvcm1hdGlvbi1sYXllcicsXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nVGltZTogJy5wcm9kdWN0cy1zaGlwcGluZy10aW1lLXZhbHVlJyxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdUaW1lSW1hZ2U6ICcuaW1nLXNoaXBwaW5nLXRpbWUgaW1nJyxcbiAgICAgICAgICAgICAgICAgICAgdG90YWxzOiAnI2NhcnRfcXVhbnRpdHkgLnRvdGFsLWJveCcsXG4gICAgICAgICAgICAgICAgICAgIHdlaWdodDogJy5wcm9kdWN0cy1kZXRhaWxzLXdlaWdodC1jb250YWluZXIgc3BhbidcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBhZ2U6ICdwcm9kdWN0LWxpc3RpbmcnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHRydWUsIHt9LCBkZWZhdWx0cywgZGF0YSksXG4gICAgICAgICAgICBtb2R1bGUgPSB7fSxcbiAgICAgICAgICAgIG1vYmlsZSA9ICQod2luZG93KS53aWR0aCgpIDw9IDc2NztcblxuXG4vLyAjIyMjIyMjIyMjIEhFTFBFUiBGVU5DVElPTlMgIyMjIyMjIyMjI1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCB1cGRhdGVzIHRoZSBidXR0b25cbiAgICAgICAgICogc3RhdGUgd2l0aCBhbiBlcnJvciBvciBzdWNjZXNzIGNsYXNzIGZvclxuICAgICAgICAgKiBhIHNwZWNpZmllZCBkdXJhdGlvblxuICAgICAgICAgKiBAcGFyYW0gICB7b2JqZWN0fSAgICAgICAgJHRhcmdldCAgICAgICAgIGpRdWVyeSBzZWxlY3Rpb24gb2YgdGhlIHRhcmdldCBidXR0b25cbiAgICAgICAgICogQHBhcmFtICAge3N0cmluZ30gICAgICAgIHN0YXRlICAgICAgICAgICBUaGUgc3RhdGUgc3RyaW5nIHRoYXQgZ2V0cyBhZGRlZCB0byB0aGUgbG9hZGluZyBjbGFzc1xuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9hZGRCdXR0b25TdGF0ZSA9IGZ1bmN0aW9uICgkdGFyZ2V0LCBzdGF0ZSkge1xuICAgICAgICAgICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgJHRhcmdldC5yZW1vdmVDbGFzcyhvcHRpb25zLnByb2Nlc3NpbmdDbGFzcyArICcgJyArIG9wdGlvbnMucHJvY2Vzc2luZ0NsYXNzICsgc3RhdGUpO1xuICAgICAgICAgICAgfSwgb3B0aW9ucy5wcm9jZXNzaW5nRHVyYXRpb24pO1xuXG4gICAgICAgICAgICAkdGFyZ2V0XG4gICAgICAgICAgICAgICAgLmRhdGEoJ3RpbWVyJywgdGltZXIpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKG9wdGlvbnMucHJvY2Vzc2luZ0NsYXNzICsgc3RhdGUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gc2V0IHRoZSBtZXNzYWdlcyBhbmQgdGhlXG4gICAgICAgICAqIGJ1dHRvbiBzdGF0ZS5cbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgIGRhdGEgICAgICAgICAgICAgICAgUmVzdWx0IGZvcm0gdGhlIGFqYXggcmVxdWVzdFxuICAgICAgICAgKiBAcGFyYW0gICAgICAge29iamVjdH0gICAgJGZvcm0gICAgICAgICAgICAgICBqUXVlcnkgc2VsZWNpb24gb2YgdGhlIGZvcm1cbiAgICAgICAgICogQHBhcmFtICAgICAgIHtib29sZWFufSAgIGRpc2FibGVCdXR0b25zICAgICAgSWYgdHJ1ZSwgdGhlIGJ1dHRvbiBzdGF0ZSBnZXRzIHNldCB0byAoaW4pYWN0aXZlXG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7Ym9vbGVhbn0gICBzaG93Tm9Db21iaU1lc3NzYWdlIElmIHRydWUsIHRoZSBlcnJvciBtZXNzYWdlIGZvciBtaXNzaW5nIHByb3BlcnR5IGNvbWJpbmF0aW9uIHNlbGVjdGlvbiB3aWxsIGJlIGRpc3BsYXllZFxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9zdGF0ZU1hbmFnZXIgPSBmdW5jdGlvbiAoZGF0YSwgJGZvcm0sIGRpc2FibGVCdXR0b25zLCBzaG93Tm9Db21iaVNlbGVjdGVkTWVzc3NhZ2UpIHtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBhdHRyaWJ1dGUgaW1hZ2VzIGZyb20gdGhlIGNvbW1vbiBjb250ZW50XG4gICAgICAgICAgICAvLyBzbyB0aGF0IGl0IGRvZXNuJ3QgZ2V0IHJlbmRlcmVkIGFueW1vcmUuIFRoZW4gdHJpZ2dlclxuICAgICAgICAgICAgLy8gYW4gZXZlbnQgdG8gdGhlIGdpdmVuIHNlbGVjdG9ycyBhbmQgZGVsaXZlciB0aGVcbiAgICAgICAgICAgIC8vIGF0dHJJbWFnZXMgb2JqZWN0XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hdHRyaWJ1dEltYWdlc1N3aXBlciAmJiBkYXRhLmF0dHJJbWFnZXMgJiYgZGF0YS5hdHRySW1hZ2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBkYXRhLmNvbnRlbnQuaW1hZ2VzO1xuICAgICAgICAgICAgICAgICQob3B0aW9ucy50cmlnZ2VyQXR0ckltYWdlc1RvKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcihqc2UubGlicy50aGVtZS5ldmVudHMuU0xJREVTX1VQREFURSgpLCB7YXR0cmlidXRlczogZGF0YS5hdHRySW1hZ2VzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNldCB0aGUgbWVzc2FnZXMgZ2l2ZW4gaW5zaWRlIHRoZSBkYXRhLmNvbnRlbnQgb2JqZWN0XG4gICAgICAgICAgICAkLmVhY2goZGF0YS5jb250ZW50LCBmdW5jdGlvbiAoaSwgdikge1xuICAgICAgICAgICAgICAgIHZhciAkZWxlbWVudCA9ICRmb3JtLnBhcmVudCgpLmZpbmQob3B0aW9ucy5zZWxlY3Rvck1hcHBpbmdbdi5zZWxlY3Rvcl0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCghc2hvd05vQ29tYmlTZWxlY3RlZE1lc3NzYWdlIHx8IHYudmFsdWUgPT09ICcnKSAmJiBpID09PSAnbWVzc2FnZU5vQ29tYmlTZWxlY3RlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc3dpdGNoICh2LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaGlkZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodi52YWx1ZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5odG1sKHYudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2F0dHJpYnV0ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5hdHRyKHYua2V5LCB2LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyZXBsYWNlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQucmVwbGFjZVdpdGgodi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnaGlkZGVuJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVtcHR5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtZW50LnRleHQodi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gRGlzLSAvIEVuYWJsZSB0aGUgYnV0dG9uc1xuICAgICAgICAgICAgaWYgKGRpc2FibGVCdXR0b25zKSB7XG4gICAgICAgICAgICAgICAgdmFyICRidXR0b25zID0gJGZvcm0uZmluZChvcHRpb25zLmNhcnRCdXR0b25zKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICRidXR0b25zLnJlbW92ZUNsYXNzKCdpbmFjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAkYnV0dG9ucy5yZW1vdmVDbGFzcygnYnRuLWluYWN0aXZlJyk7XG5cdCAgICAgICAgICAgICAgICAkYnV0dG9ucy5wcm9wKFwiZGlzYWJsZWRcIiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICRidXR0b25zLmFkZENsYXNzKCdpbmFjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAkYnV0dG9ucy5hZGRDbGFzcygnYnRuLWluYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICRidXR0b25zLnByb3AoXCJkaXNhYmxlZFwiLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkYXRhLmNvbnRlbnQubWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIHZhciAkZXJyb3JGaWVsZCA9ICRmb3JtLmZpbmQob3B0aW9ucy5zZWxlY3Rvck1hcHBpbmdbZGF0YS5jb250ZW50Lm1lc3NhZ2Uuc2VsZWN0b3JdKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5jb250ZW50Lm1lc3NhZ2UudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgJGVycm9yRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnaGlkZGVuJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgJGVycm9yRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnaGlkZGVuJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dOb0NvbWJpU2VsZWN0ZWRNZXNzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgZGF0YS5jb250ZW50Lm1lc3NhZ2VOb0NvbWJpU2VsZWN0ZWQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgZGF0YS5jb250ZW50Lm1lc3NhZ2VOb0NvbWJpU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmNvbnRlbnQubWVzc2FnZU5vQ29tYmlTZWxlY3RlZC52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlcnJvckZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnaGlkZGVuJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVycm9yRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCdoaWRkZW4nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkd2luZG93LnRyaWdnZXIoanNlLmxpYnMudGhlbWUuZXZlbnRzLlNUSUNLWUJPWF9DT05URU5UX0NIQU5HRSgpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHNlbmQgdGhlIGFqYXhcbiAgICAgICAgICogT24gc3VjY2VzcyByZWRpcmVjdCB0byBhIGdpdmVuIHVybCwgb3BlbiBhIGxheWVyIHdpdGhcbiAgICAgICAgICogYSBtZXNzYWdlIG9yIGFkZCB0aGUgaXRlbSB0byB0aGUgY2FydC1kcm9wZG93biBkaXJlY3RseVxuICAgICAgICAgKiAoYnkgdHJpZ2dlcmluZyBhbiBldmVudCB0byB0aGUgYm9keSlcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgICAgZGF0YSAgICAgIEZvcm0gZGF0YVxuICAgICAgICAgKiBAcGFyYW0gICAgICAge29iamVjdH0gICAgICAkZm9ybSAgICAgVGhlIGZvcm0gdG8gZmlsbFxuICAgICAgICAgKiBAcGFyYW0gICAgICAge3N0cmluZ30gICAgICB1cmwgICAgICAgVGhlIFVSTCBmb3IgdGhlIEFKQVggcmVxdWVzdFxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9hZGRUb1NvbWV3aGVyZSA9IGZ1bmN0aW9uIChkYXRhLCAkZm9ybSwgdXJsLCAkYnV0dG9uKSB7XG4gICAgICAgICAgICBmdW5jdGlvbiBjYWxsYmFjaygpIHtcbiAgICAgICAgICAgICAgICBqc2UubGlicy54aHIucG9zdCh7dXJsOiB1cmwsIGRhdGE6IGRhdGF9LCB0cnVlKS5kb25lKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpbGwgdGhlIHBhZ2Ugd2l0aCB0aGUgcmVzdWx0IGZyb20gdGhlIGFqYXhcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdGF0ZU1hbmFnZXIocmVzdWx0LCAkZm9ybSwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgQUpBWCB3YXMgc3VjY2Vzc2Z1bCBleGVjdXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhIGN1c3RvbSBmdW5jdGlvbmFsaXR5XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3VybCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnVybC5zdWJzdHIoMCwgNCkgIT09ICdodHRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLmhyZWYgPSBqc2UuY29yZS5jb25maWcuZ2V0KCdhcHBVcmwnKSArICcvJyArIHJlc3VsdC51cmw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLmhyZWYgPSByZXN1bHQudXJsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZHJvcGRvd24nOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJvZHkudHJpZ2dlcihqc2UubGlicy50aGVtZS5ldmVudHMuQ0FSVF9VUERBVEUoKSwgW3RydWVdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdsYXllcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc2UubGlicy50aGVtZS5tb2RhbC5pbmZvKHt0aXRsZTogcmVzdWx0LnRpdGxlLCBjb250ZW50OiByZXN1bHQubXNnfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoaWdub3JlKSB7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgX2FkZEJ1dHRvblN0YXRlKCRidXR0b24sICctc3VjY2VzcycpO1xuICAgICAgICAgICAgICAgIH0pLmZhaWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfYWRkQnV0dG9uU3RhdGUoJGJ1dHRvbiwgJy1mYWlsJyk7XG4gICAgICAgICAgICAgICAgfSkuYWx3YXlzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIGJ1c3kgZmxhZyB0byBiZSBhYmxlIHRvIHBlcmZvcm1cbiAgICAgICAgICAgICAgICAgICAgLy8gZnVydGhlciBBSkFYIHJlcXVlc3RzXG4gICAgICAgICAgICAgICAgICAgIGJ1c3kgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFidXN5KSB7XG4gICAgICAgICAgICAgICAgLy8gb25seSBleGVjdXRlIHRoZSBhamF4XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgbm8gcGVuZGluZyBhamF4IGNhbGxcbiAgICAgICAgICAgICAgICBidXN5ID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIGpzZS5saWJzLmhvb2tzLmV4ZWN1dGUoanNlLmxpYnMuaG9va3Mua2V5cy5zaG9wLmNhcnQuYWRkLCBkYXRhLCA1MDApXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKGNhbGxiYWNrKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH07XG5cblxuLy8gIyMjIyMjIyMjIyBFVkVOVCBIQU5ETEVSICMjIyMjIyMjIyNcblxuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlciBmb3IgdGhlIHN1Ym1pdCBmb3JtIC8gY2xpY2tcbiAgICAgICAgICogb24gXCJhZGQgdG8gY2FydFwiICYgXCJ3aXNobGlzdFwiIGJ1dHRvbi5cbiAgICAgICAgICogSXQgcGVyZm9ybXMgYSBjaGVjayBvbiB0aGUgYXZhaWxhYmlsaXR5XG4gICAgICAgICAqIG9mIHRoZSBjb21iaW5hdGlvbiBhbmQgcXVhbnRpdHkuIElmXG4gICAgICAgICAqIHN1Y2Nlc3NmdWwgaXQgcGVyZm9ybXMgdGhlIGFkZCB0byBjYXJ0XG4gICAgICAgICAqIG9yIHdpc2hsaXN0IGFjdGlvbiwgaWYgaXQncyBub3QgYVxuICAgICAgICAgKiBcImNoZWNrXCIgY2FsbFxuICAgICAgICAgKiBAcGFyYW0gICAgICAge29iamVjdH0gICAgZSAgICAgIGpRdWVyeSBldmVudCBvYmplY3RcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfc3VibWl0SGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyICRzZWxmID0gJCh0aGlzKSxcbiAgICAgICAgICAgICAgICAkZm9ybSA9ICgkc2VsZi5pcygnZm9ybScpKSA/ICRzZWxmIDogJHNlbGYuY2xvc2VzdCgnZm9ybScpLFxuICAgICAgICAgICAgICAgIGN1c3RvbWl6ZXIgPSAkZm9ybS5oYXNDbGFzcygnY3VzdG9taXplcicpLFxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMgPSAhISRmb3JtLmZpbmQoJy5wcm9wZXJ0aWVzLXNlbGVjdGlvbi1mb3JtJykubGVuZ3RoLFxuICAgICAgICAgICAgICAgIG1vZHVsZSA9IHByb3BlcnRpZXMgPyAnJyA6ICcvQXR0cmlidXRlcycsXG4gICAgICAgICAgICAgICAgc2hvd05vQ29tYmlTZWxlY3RlZE1lc3NzYWdlID0gZSAmJiBlLmRhdGEgJiYgZS5kYXRhLnRhcmdldCAmJiBlLmRhdGEudGFyZ2V0ICE9PSAnY2hlY2snO1xuXG4gICAgICAgICAgICBpZiAoJGZvcm0ubGVuZ3RoKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTaG93IHByb3BlcnRpZXMgb3ZlcmxheVxuICAgICAgICAgICAgICAgIC8vIHRvIGRpc2FibGUgdXNlciBpbnRlcmFjdGlvblxuICAgICAgICAgICAgICAgIC8vIGJlZm9yZSBtYXJrdXAgcmVwbGFjZVxuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgICAgICR0aGlzLmFkZENsYXNzKCdsb2FkaW5nJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGZvcm1kYXRhID0ganNlLmxpYnMuZm9ybS5nZXREYXRhKCRmb3JtLCBudWxsLCB0cnVlKTtcbiAgICAgICAgICAgICAgICBmb3JtZGF0YS50YXJnZXQgPSAoZSAmJiBlLmRhdGEgJiYgZS5kYXRhLnRhcmdldCkgPyBlLmRhdGEudGFyZ2V0IDogJ2NoZWNrJztcbiAgICAgICAgICAgICAgICBmb3JtZGF0YS5pc1Byb2R1Y3RJbmZvID0gJGZvcm0uaGFzQ2xhc3MoJ3Byb2R1Y3QtaW5mbycpID8gMSA6IDA7XG5cbiAgICAgICAgICAgICAgICAvLyBBYm9ydCBwcmV2aW91cyBjaGVjayBhamF4IGlmXG4gICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgb25lIGluIHByb2dyZXNzXG4gICAgICAgICAgICAgICAgaWYgKGFqYXggJiYgZSkge1xuICAgICAgICAgICAgICAgICAgICBhamF4LmFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQWRkIHByb2Nlc3NpbmctY2xhc3MgdG8gdGhlIGJ1dHRvblxuICAgICAgICAgICAgICAgIC8vIGFuZCByZW1vdmUgb2xkIHRpbWVkIGV2ZW50c1xuICAgICAgICAgICAgICAgIGlmIChmb3JtZGF0YS50YXJnZXQgIT09ICdjaGVjaycpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVyID0gJHNlbGYuZGF0YSgndGltZXInKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgJHNlbGZcbiAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhvcHRpb25zLnByb2Nlc3NpbmdDbGFzcyArICctc3VjY2VzcyAnICsgb3B0aW9ucy5wcm9jZXNzaW5nQ2xhc3MgKyAnLWZhaWwnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKG9wdGlvbnMucHJvY2Vzc2luZ0NsYXNzKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBhamF4ID0ganNlLmxpYnMueGhyLmdldCh7XG4gICAgICAgICAgICAgICAgICAgIHVybDogb3B0aW9ucy5jaGVja1VybCArIG1vZHVsZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogZm9ybWRhdGFcbiAgICAgICAgICAgICAgICB9LCB0cnVlKS5kb25lKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgX3N0YXRlTWFuYWdlcihyZXN1bHQsICRmb3JtLCB0cnVlLCBzaG93Tm9Db21iaVNlbGVjdGVkTWVzc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICAkdGhpcy5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGZvcm1kYXRhLnRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3dpc2hsaXN0JzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50ID0ganNlLmxpYnMudGhlbWUuZXZlbnRzLkFERF9DVVNUT01JWkVSX1dJU0hMSVNUKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gb3B0aW9ucy53aXNobGlzdFVybDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnY2FydCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGpzZS5saWJzLnRoZW1lLmV2ZW50cy5BRERfQ1VTVE9NSVpFUl9DQVJUKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSBvcHRpb25zLmFkZENhcnRDdXN0b21pemVyVXJsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gb3B0aW9ucy5hZGRDYXJ0VXJsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ByaWNlX29mZmVyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZvcm0uYXR0cignYWN0aW9uJywgb3B0aW9ucy5wcmljZU9mZmVyVXJsKS5hdHRyKCdtZXRob2QnLCBvcHRpb25zLnByaWNlT2ZmZXJNZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZm9ybS5vZmYoJ3N1Ym1pdCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZm9ybS5zdWJtaXQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkd2luZG93LnRyaWdnZXIoanNlLmxpYnMudGhlbWUuZXZlbnRzLlNUSUNLWUJPWF9DT05URU5UX0NIQU5HRSgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uIChjdXN0b21pemVyUmFuZG9tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1kYXRhW2N1c3RvbWl6ZXJSYW5kb21dID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FkZFRvU29tZXdoZXJlKGZvcm1kYXRhLCAkZm9ybSwgdXJsLCAkc2VsZik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkuZmFpbChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hZGRCdXR0b25TdGF0ZSgkc2VsZiwgJy1mYWlsJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGJvZHkudHJpZ2dlcihldmVudCwgW3snZGVmZXJyZWQnOiBkZWZlcnJlZCwgJ2RhdGFzZXQnOiBmb3JtZGF0YX1dKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodXJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FkZFRvU29tZXdoZXJlKGZvcm1kYXRhLCAkZm9ybSwgdXJsLCAkc2VsZik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH0pLmZhaWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfYWRkQnV0dG9uU3RhdGUoJHNlbGYsICctZmFpbCcpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZXl1cCBoYW5kbGVyIGZvciBxdWFudGl0eSBpbnB1dCBmaWVsZFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZVxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9rZXl1cEhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3N1Ym1pdEhhbmRsZXIuY2FsbCh0aGlzLCBlKVxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCAzMDApO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFdmVudCBoYW5kbGVyIGZvciB0aGUgYWRkIHRvIGNhcnQgYnV0dG9uLCB0aGF0IHNob3dzIG9yIGhpZGVzIHRoZSB0aHJvYmJlci5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9hZGRUb0NhcnRUaHJvYmJlckhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgY29uc3QgJGJ0biA9ICQodGhpcyk7XG4gICAgICAgICAgICBjb25zdCAkYnRuRmFrZSA9ICR0aGlzLmZpbmQoXCIuYnRuLWFkZC10by1jYXJ0LWZha2VcIik7XG4gICAgICAgICAgICBsZXQgZm9ybVJlYWR5ID0gdHJ1ZTtcblxuICAgICAgICAgICAgJChcIi5wcm9wZXJ0aWVzLXNlbGVjdGlvbi1mb3JtIHNlbGVjdFwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSAkKHRoaXMpLnZhbCgpO1xuICAgICAgICAgICAgICAgIGlmICghdmFsIHx8IHZhbCA8IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9ybVJlYWR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChmb3JtUmVhZHkpIHtcbiAgICAgICAgICAgICAgICAkYnRuLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAkYnRuRmFrZS5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnByb3AoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICAucHJlcGVuZCgnPHNwYW4gY2xhc3M9XCJ0aHJvYmJsZXJcIj48L3NwYW4+Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhcnQgZHJvcGRvd24gb2JlbiBldmVudCBoYW5kbGVyIGZvciB0aGUgYm9keS5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9jYXJ0RHJvcGRvd25PcGVuSGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjb25zdCAkYnRuID0gJHRoaXMuZmluZChcIltuYW1lPWJ0bi1hZGQtdG8tY2FydF1cIik7XG4gICAgICAgICAgICBjb25zdCAkYnRuRmFrZSA9ICR0aGlzLmZpbmQoXCIuYnRuLWFkZC10by1jYXJ0LWZha2VcIik7XG4gICAgICAgICAgICBjb25zdCBmYWtlT3JpZ0xhYmVsID0gJGJ0bkZha2UuaHRtbCgpO1xuICAgICAgICAgICAgY29uc3QgcHJvZHVjdENvdW50ID0gJChcIi5jYXJ0LXByb2R1Y3RzLWNvdW50XCIpLmh0bWwoKTtcblxuICAgICAgICAgICAgY29uc3QgdGV4dFBocmFzZXMgPSBKU09OLnBhcnNlKCQoJyNwcm9kdWN0LWRldGFpbHMtdGV4dC1waHJhc2VzJykuaHRtbCgpKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRleHRQaHJhc2VzWydwcm9kdWN0c0luQ2FydFN1ZmZpeCddKTtcblxuICAgICAgICAgICAgJGJ0bkZha2UuaHRtbChcIjxpIGNsYXNzPVxcXCJmYSBmYS1jaGVja1xcXCI+PC9pPiBcIiArIHBhcnNlSW50KHByb2R1Y3RDb3VudClcbiAgICAgICAgICAgICAgICArIHRleHRQaHJhc2VzWydwcm9kdWN0c0luQ2FydFN1ZmZpeCddKVxuICAgICAgICAgICAgICAgIC5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSlcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJidG4tYnV5LWNvbXBsZXRlXCIpO1xuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAkYnRuRmFrZS5odG1sKGZha2VPcmlnTGFiZWwpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImJ0bi1idXktY29tcGxldGVcIilcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAucHJvcChcImRpc2FibGVkXCIsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAkKFwiLnRocm9iYmxlclwiLCAkYnRuKS5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICAkYnRuLnNob3coKTtcbiAgICAgICAgICAgIH0sIDUwMDApO1xuICAgICAgICAgICAgXG4gICAgICAgIH07XG5cblxuLy8gIyMjIyMjIyMjIyBJTklUSUFMSVpBVElPTiAjIyMjIyMjIyMjXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXQgZnVuY3Rpb24gb2YgdGhlIHdpZGdldFxuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICovXG4gICAgICAgIG1vZHVsZS5pbml0ID0gZnVuY3Rpb24gKGRvbmUpIHtcblxuICAgICAgICAgICAgdmFyICRmb3JtcyA9ICR0aGlzLmZpbmQoJ2Zvcm0nKTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFnZSA9PT0gJ3Byb2R1Y3QtaW5mbycpIHtcbiAgICAgICAgICAgICAgICAkZm9ybXMuZmluZChcIltuYW1lPWJ0bi1hZGQtdG8tY2FydF1cIikub24oJ21vdXNldXAnLCBfYWRkVG9DYXJ0VGhyb2JiZXJIYW5kbGVyKTtcbiAgICAgICAgICAgICAgICAkKFwiYm9keVwiKS5vbignQ0FSVF9EUk9QRE9XTl9PUEVOJywgX2NhcnREcm9wZG93bk9wZW5IYW5kbGVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJGZvcm1zXG4gICAgICAgICAgICAgICAgLm9uKCdzdWJtaXQnLCB7J3RhcmdldCc6ICdjYXJ0J30sIF9zdWJtaXRIYW5kbGVyKVxuICAgICAgICAgICAgICAgIC5vbignY2xpY2snLCBvcHRpb25zLndpc2hsaXN0QnV0dG9ucywgeyd0YXJnZXQnOiAnd2lzaGxpc3QnfSwgX3N1Ym1pdEhhbmRsZXIpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsIG9wdGlvbnMucHJpY2VPZmZlckJ1dHRvbnMsIHsndGFyZ2V0JzogJ3ByaWNlX29mZmVyJ30sIF9zdWJtaXRIYW5kbGVyKVxuICAgICAgICAgICAgICAgIC5vbignY2hhbmdlJywgb3B0aW9ucy5hdHRyaWJ1dGVzLCB7J3RhcmdldCc6ICdjaGVjayd9LCBfc3VibWl0SGFuZGxlcilcbiAgICAgICAgICAgICAgICAub24oJ2JsdXInLCBvcHRpb25zLnF1YW50aXR5LCB7J3RhcmdldCc6ICdjaGVjayd9LCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBfc3VibWl0SGFuZGxlcihlKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5vbigna2V5dXAnLCBvcHRpb25zLnF1YW50aXR5LCB7J3RhcmdldCc6ICdjaGVjayd9LCBfa2V5dXBIYW5kbGVyKTtcblxuICAgICAgICAgICAgLy8gRmFsbGJhY2sgaWYgdGhlIGJhY2tlbmQgcmVuZGVycyBpbmNvcnJlY3QgZGF0YVxuICAgICAgICAgICAgLy8gb24gaW5pdGlhbCBwYWdlIGNhbGxcbiAgICAgICAgICAgICRmb3Jtcy5ub3QoJy5uby1zdGF0dXMtY2hlY2snKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfc3VibWl0SGFuZGxlci5jYWxsKCQodGhpcykpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm4gZGF0YSB0byB3aWRnZXQgZW5naW5lXG4gICAgICAgIHJldHVybiBtb2R1bGU7XG4gICAgfSk7XG4iXX0=