| 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/templates/Honeygrid/assets/javascript/engine/widgets/ |
Upload File : |
'use strict';
/* --------------------------------------------------------------
swiper.js 2017-08-03
Gambio GmbH
http://www.gambio.de
Copyright (c) 2017 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
/* globals Swiper */
/**
* Widget that binds the swiper plugin (third party) to a DOM element
*
* @todo Remove the try - catch blocks and and correct the swiper issues.
*/
gambio.widgets.module('swiper', [gambio.source + '/libs/events', gambio.source + '/libs/responsive'], function (data) {
'use strict';
// ########## VARIABLE INITIALIZATION ##########
var $this = $(this),
$body = $('body'),
$slides = null,
$controls = null,
$target = null,
$template = null,
init = true,
swiper = null,
sliderOptions = null,
hasThumbnails = true,
mode = null,
breakpointDataset = null,
duplicates = false,
preventSlideStart = false,
sliderDefaults = { // Default configuration for the swiper
pagination: '.swiper-pagination',
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
paginationClickable: true,
loop: true,
autoplay: 3,
autoplayDisableOnInteraction: false
},
defaults = {
// JSON that gets merged with the sliderDefaults and is passed to "swiper" directly.
sliderOptions: null,
// If this instance is a "main" swiper, the given selector selects the "control" swiper.
controls: null,
// If this instance is a "control" swiper, the given selector selects the "main" swiper.
target: null,
// Sets the initial slide (needed to prevent different init slides in main/controller slider).
initSlide: null,
// Detect if a swiper is needed for the breakpoint. If not, turn it off
autoOff: false,
// The translucence fix enables support for a fade effect between images with different aspect ratio,
// but causing a delay between the change
disableTranslucenceFix: false,
breakpoints: [{
// Until which breakpoint this settings is available
breakpoint: 40,
// If true, the paging bullets will be replaced with the preview images.
usePreviewBullets: false,
// This and all other settings belonging to the swiper plugin.
slidesPerView: 2,
// If true, the current slide gets centered in view (most usefull with an even slidesPerView
// count).
centeredSlides: true
}, {
breakpoint: 60,
usePreviewBullets: true,
slidesPerView: 3
}, {
breakpoint: 80,
usePreviewBullets: true,
slidesPerView: 3
}, {
breakpoint: 100,
usePreviewBullets: true,
slidesPerView: 5
}]
},
options = $.extend({}, defaults, data),
module = {};
// ########## HELPER FUNCTIONS ##########
/**
* Function that generates the markup for
* the preview bullets
* @param {Swiper} swiper Swiper object
* @param {integer} index Index of the slide
* @param {string} className The classname that must be add to the markup
* @return {string} The preview image html string
* @private
*/
var _generatePreviewButtons = function _generatePreviewButtons(swiper, index, className) {
var $currentSlide = $slides.eq(index),
$image = $currentSlide.find('img'),
altTxt = $image.attr('alt'),
thumbImage = $currentSlide.data('thumbImage');
if (thumbImage) {
return '<img src="' + thumbImage + '" alt="' + altTxt + '" class="' + className + '" />';
}
return '';
};
/**
* Helper function to get the index of the
* active slide
* @return {integer} The index of the active slide
* @private
*/
var _getIndex = function _getIndex() {
var index = $this.find('.swiper-slide-active').index();
// If there are duplicate slides (generated
// by the swiper) recalculate the index
index = duplicates ? index - 1 : index;
index = index || 0;
return index;
};
/**
* Helper function to add the active
* class to the active slide
* @param {integer} index The index of the active slide
* @private
*/
var _setActive = function _setActive(index) {
$slides = $this.find('.swiper-slide:not(.swiper-slide-duplicate)');
index = duplicates ? index + 1 : index;
$slides.removeClass('active').eq(index).addClass('active');
};
// ########## EVENT HANDLER ##########
/**
* Event handler for the mouseenter event.
* It disables the autoplay
* @private
*/
var _mouseEnterHandler = function _mouseEnterHandler() {
try {
if (swiper) {
swiper.stopAutoplay();
}
} catch (e) {
// Do not log the error
}
};
/**
* Event handler for the mouseleave event.
* It enables the autoplay
* @private
*/
var _mouseLeaveHandler = function _mouseLeaveHandler() {
try {
if (swiper) {
swiper.startAutoplay();
}
} catch (e) {
// Do not log the error
}
};
/**
* Event handler for the goto event.
* It switches the current slide to the given index
* and adds the active class to the new active slide
* @param {object} e jQuery event object
* @param {number} d Index of the slide to show
* @private
*/
var _gotoHandler = function _gotoHandler(e, d) {
e.stopPropagation();
// Set the active slide
_setActive(d);
// Temporary deactivate the onSlideChangeStart event
// to prevent looping through the goto / changeStart
// events
preventSlideStart = true;
// Remove the autoplay after a goto event
$this.off('mouseleave.swiper');
swiper.stopAutoplay();
// Try to correct the index between sliders
// with and without duplicates
var index = duplicates ? d + 1 : d;
if (index > $slides.length) {
index = 0;
}
// Goto the desired slide
swiper.slideTo(index);
// Reactivate the onSlideChangeEvent
preventSlideStart = false;
};
/**
* Click event handler that triggers a
* "goto" event to the target swiper
* @param {object} e jQuery event object
* @private
*/
var _clickHandler = function _clickHandler(e) {
e.preventDefault();
e.stopPropagation();
var $self = $(this),
index = $self.index();
index = duplicates ? index - 1 : index;
// Set the active slide
_setActive(index);
// Inform the main swiper
$target.trigger(jse.libs.theme.events.SWIPER_GOTO(), index);
};
/**
* Event that gets triggered on slideChange.
* If the slide gets changed, the controls
* will follow the current slide in position
* @private
*/
var _triggerSlideChange = function _triggerSlideChange() {
if (!preventSlideStart) {
var index = _getIndex(),
lastIndex = $slides.length - 2;
// Recalculate index if duplicate slides are inside the slider
if (index < 0) {
index = $slides.length - 3;
} else {
index = duplicates && index === lastIndex ? index - lastIndex : index;
}
// Set the active slide
_setActive(index);
// Inform the controls
$controls.trigger(jse.libs.theme.events.SWIPER_GOTO(), index);
}
};
/**
* Workaround for the translucence issue
* that happens on small screens with enabled
* fade effect. Maybe it can be removed, if the
* swiper gets updated itself
* @private
*/
var _translucenceWorkaround = function _translucenceWorkaround() {
if (!options.disableTranslucenceFix && sliderOptions && sliderOptions.effect === 'fade') {
$this.find('.swiper-slide').filter(':not(.swiper-slide-active)').fadeTo(300, 0, function () {
$(this).css('visibility', 'hidden');
});
$this.find('.swiper-slide').filter('.swiper-slide-active').fadeTo(300, 1, function () {
$(this).css('visibility', '');
});
}
};
/**
* The breakpoint handler initializes the swiper
* with the settings for the current breakpoint.
* Therefore it uses the default slider options,
* the custom slider options given by the options
* object and the breakpoint options object also
* given by the options (in this order)
* @private
*/
var _breakpointHandler = function _breakpointHandler() {
// Get the current viewmode
var oldMode = mode || {},
newMode = jse.libs.theme.responsive.breakpoint(),
extendOptions = options.breakpoints[0] || {},
newBreakpointDataset = null;
// Only do something if the view was changed
if (newMode.id !== oldMode.id) {
// Store the new viewmode
mode = $.extend({}, newMode);
// Iterate through the breakpoints object to detect
// the correct settings for the current breakpoint
$.each(options.breakpoints, function (i, v) {
if (v.breakpoint > newMode.id) {
return false;
}
newBreakpointDataset = i;
extendOptions = v;
});
if (options.sliderOptions && options.sliderOptions.breakpoints) {
$.each(options.sliderOptions.breakpoints, function (i, v) {
if (v.breakpoint === newMode.id) {
extendOptions = v;
return false;
}
});
}
// Only do something if the settings change due browser
// resize or if it's the first time run
if (newBreakpointDataset !== breakpointDataset || init) {
// Combine the settings
sliderOptions = $.extend({}, sliderDefaults, options.sliderOptions || {}, extendOptions);
// Add the preview image bullets function to the options object
if (sliderOptions.usePreviewBullets && hasThumbnails) {
sliderOptions.paginationBulletRender = _generatePreviewButtons;
}
// Add the autoplay interval to the options object
sliderOptions.autoplay = sliderOptions.autoplay ? sliderOptions.autoplay * 1000 : 0;
// Disable loop if there is only one slider.
if ($this.find('.swiper-slide').length === 1) {
sliderOptions.loop = false;
}
// If an swiper exists, get the current
// slide no. and remove the old swiper
if (swiper) {
sliderOptions.initialSlide = _getIndex();
try {
swiper.destroy(true, true);
} catch (ignore) {
swiper = null;
}
} else {
sliderOptions.initialSlide = options.initSlide || sliderOptions.initialSlide || 0;
}
var $duplicate = $this.find('.swiper-slide:not(.swiper-slide-duplicate)');
if (!options.autoOff || $duplicate.length > sliderOptions.slidesPerView && options.autoOff) {
$this.addClass('swiper-is-active').removeClass('swiper-is-not-active');
// Initialize the swiper
try {
swiper = new Swiper($this, sliderOptions);
} catch (e) {
return; // Swiper might throw an error upon initialization that should not halt the script execution.
}
swiper.off('onTransitionEnd onSlideChangeStart').on('onTransitionEnd', _translucenceWorkaround);
// If this is a "main" swiper and has external controls, an
// goto event is triggered if the current slide is changed
if ($controls.length) {
swiper.on('onSlideChangeStart', _triggerSlideChange);
}
// Add the event handler
$this.off('mouseenter.swiper mouseleave.swiper ' + jse.libs.theme.events.SWIPER_GOTO() + ' ' + jse.libs.theme.events.SLIDES_UPDATE()).on('mouseenter.swiper', _mouseEnterHandler).on('mouseleave.swiper', _mouseLeaveHandler).on(jse.libs.theme.events.SWIPER_GOTO(), _gotoHandler).on(jse.libs.theme.events.SLIDES_UPDATE(), _updateSlides);
if (init) {
// Check if there are duplicates slides (generated by the swiper)
// after the first time init of the swiper
duplicates = !!$this.find('.swiper-slide-duplicate').length;
}
// Set the active slide
var index = init && options.initSlide ? options.initSlide : _getIndex();
_setActive(index);
// Inform the controls that the main swiper has changed
// In case that the other slider isn't initialized yet,
// set an data attribute to the markup element to inform
// it on init
if ($controls.length) {
$controls.attr('data-swiper-init-slide', index);
_triggerSlideChange();
}
// Unset the init flag
init = false;
setTimeout(function () {
return swiper.update();
});
} else {
// Disable the swiper buttons
$this.removeClass('swiper-is-active').addClass('swiper-is-not-active');
init = true;
}
}
}
};
/**
* Event handler that adds & removes slides from the
* swiper. After the slides were processed, the first
* slide is shown
* @param {object} e jQuery event object
* @param {object} d JSON object that contains the categories / images
* @private
*/
var _updateSlides = function _updateSlides(e, d) {
// Loops through each category inside the images array
$.each(d, function (category, dataset) {
var catName = category + '-category',
add = [],
remove = [],
markup = $template.html();
// Get all indexes from the slides
// of the same category and remove
// them from the slider
$slides.filter('.' + catName).each(function () {
var $self = $(this),
index = $self.data().swiperSlideIndex;
index = index === undefined ? $self.index() : index;
remove.push(index);
});
swiper.removeSlide(remove);
// Generate the markup for the new slides
// and add them to the slider
$.each(dataset || [], function (i, v) {
v.className = catName;
v.srcattr = 'src="' + v.src + '"';
add.push(Mustache.render(markup, v));
});
swiper.appendSlide(add);
});
$slides = $this.find('.swiper-slide');
// To prevent an inconsistent state
// in control / main slider combinations
// slide to the first slide
_setActive(0);
var index = duplicates ? 1 : 0;
swiper.slideTo(index, 0);
};
/**
* Prevent text selection by clicking on swiper buttons
* @private
*/
var _preventTextSelection = function _preventTextSelection() {
$(options.sliderOptions.nextButton).on('selectstart', function () {
return false;
});
$(options.sliderOptions.prevButton).on('selectstart', function () {
return false;
});
};
/**
* Sets the initial height for one swiper image container to prevent cut off images on smaller swiper heights
* @private
*/
var _scaleThumbnailHeight = function _scaleThumbnailHeight() {
var swiperContainer = $('.swiper-container-vertical .swiper-slide');
var $containerHeight = swiperContainer.css('height');
// Workaround for IE Browsers
if ($('.swiper-container-vertical').hasClass('swiper-wp8-vertical')) {
$containerHeight = swiperContainer.height() + 5;
swiperContainer.css('height', $containerHeight);
}
if ($containerHeight === '0px') {
$containerHeight = $('.product-info-thumbnails-mobile').css('height');
}
$('.align-middle').css('height', $containerHeight);
};
// ########## INITIALIZATION ##########
/**
* Init function of the widget
* @constructor
*/
module.init = function (done) {
$slides = $this.find('.swiper-slide');
$controls = $(options.controls);
$target = $(options.target);
$template = $this.find('template');
// Check if all images inside the swiper have
// thumbnail image given
$slides.each(function () {
if (!$(this).data().thumbImage) {
hasThumbnails = false;
return false;
}
});
// Add the breakpoint handler ty dynamically
// set the options corresponding to the browser size (slider responsive will re-initialize the swiper).
_breakpointHandler();
// If this instance is a "control" swiper the target is the main swiper
// which will be updated on a click inside this control swiper
if (options.target) {
$this.on('click.swiper', '.swiper-slide', _clickHandler);
}
$(document).ready(function () {
$('.swiper-vertical .swiper-slide[data-index]').css('display', 'inline-block');
$('.product-info-image .swiper-slide[data-index]').css('z-index', 'inherit');
$('.product-info-image .swiper-slide[data-index] .swiper-slide-inside img.img-responsive').fadeIn(1000);
});
_translucenceWorkaround();
_preventTextSelection();
_scaleThumbnailHeight();
// Fix for invisible Thumbnail-Images for switching from Tablet-Portrait to Tablet-Landscape
$body.on(jse.libs.theme.events.BREAKPOINT(), function () {
_scaleThumbnailHeight();
});
done();
};
// Return data to widget engine
return module;
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndpZGdldHMvc3dpcGVyLmpzIl0sIm5hbWVzIjpbImdhbWJpbyIsIndpZGdldHMiLCJtb2R1bGUiLCJzb3VyY2UiLCJkYXRhIiwiJHRoaXMiLCIkIiwiJGJvZHkiLCIkc2xpZGVzIiwiJGNvbnRyb2xzIiwiJHRhcmdldCIsIiR0ZW1wbGF0ZSIsImluaXQiLCJzd2lwZXIiLCJzbGlkZXJPcHRpb25zIiwiaGFzVGh1bWJuYWlscyIsIm1vZGUiLCJicmVha3BvaW50RGF0YXNldCIsImR1cGxpY2F0ZXMiLCJwcmV2ZW50U2xpZGVTdGFydCIsInNsaWRlckRlZmF1bHRzIiwicGFnaW5hdGlvbiIsIm5leHRCdXR0b24iLCJwcmV2QnV0dG9uIiwicGFnaW5hdGlvbkNsaWNrYWJsZSIsImxvb3AiLCJhdXRvcGxheSIsImF1dG9wbGF5RGlzYWJsZU9uSW50ZXJhY3Rpb24iLCJkZWZhdWx0cyIsImNvbnRyb2xzIiwidGFyZ2V0IiwiaW5pdFNsaWRlIiwiYXV0b09mZiIsImRpc2FibGVUcmFuc2x1Y2VuY2VGaXgiLCJicmVha3BvaW50cyIsImJyZWFrcG9pbnQiLCJ1c2VQcmV2aWV3QnVsbGV0cyIsInNsaWRlc1BlclZpZXciLCJjZW50ZXJlZFNsaWRlcyIsIm9wdGlvbnMiLCJleHRlbmQiLCJfZ2VuZXJhdGVQcmV2aWV3QnV0dG9ucyIsImluZGV4IiwiY2xhc3NOYW1lIiwiJGN1cnJlbnRTbGlkZSIsImVxIiwiJGltYWdlIiwiZmluZCIsImFsdFR4dCIsImF0dHIiLCJ0aHVtYkltYWdlIiwiX2dldEluZGV4IiwiX3NldEFjdGl2ZSIsInJlbW92ZUNsYXNzIiwiYWRkQ2xhc3MiLCJfbW91c2VFbnRlckhhbmRsZXIiLCJzdG9wQXV0b3BsYXkiLCJlIiwiX21vdXNlTGVhdmVIYW5kbGVyIiwic3RhcnRBdXRvcGxheSIsIl9nb3RvSGFuZGxlciIsImQiLCJzdG9wUHJvcGFnYXRpb24iLCJvZmYiLCJsZW5ndGgiLCJzbGlkZVRvIiwiX2NsaWNrSGFuZGxlciIsInByZXZlbnREZWZhdWx0IiwiJHNlbGYiLCJ0cmlnZ2VyIiwianNlIiwibGlicyIsInRoZW1lIiwiZXZlbnRzIiwiU1dJUEVSX0dPVE8iLCJfdHJpZ2dlclNsaWRlQ2hhbmdlIiwibGFzdEluZGV4IiwiX3RyYW5zbHVjZW5jZVdvcmthcm91bmQiLCJlZmZlY3QiLCJmaWx0ZXIiLCJmYWRlVG8iLCJjc3MiLCJfYnJlYWtwb2ludEhhbmRsZXIiLCJvbGRNb2RlIiwibmV3TW9kZSIsInJlc3BvbnNpdmUiLCJleHRlbmRPcHRpb25zIiwibmV3QnJlYWtwb2ludERhdGFzZXQiLCJpZCIsImVhY2giLCJpIiwidiIsInBhZ2luYXRpb25CdWxsZXRSZW5kZXIiLCJpbml0aWFsU2xpZGUiLCJkZXN0cm95IiwiaWdub3JlIiwiJGR1cGxpY2F0ZSIsIlN3aXBlciIsIm9uIiwiU0xJREVTX1VQREFURSIsIl91cGRhdGVTbGlkZXMiLCJzZXRUaW1lb3V0IiwidXBkYXRlIiwiY2F0ZWdvcnkiLCJkYXRhc2V0IiwiY2F0TmFtZSIsImFkZCIsInJlbW92ZSIsIm1hcmt1cCIsImh0bWwiLCJzd2lwZXJTbGlkZUluZGV4IiwidW5kZWZpbmVkIiwicHVzaCIsInJlbW92ZVNsaWRlIiwic3JjYXR0ciIsInNyYyIsIk11c3RhY2hlIiwicmVuZGVyIiwiYXBwZW5kU2xpZGUiLCJfcHJldmVudFRleHRTZWxlY3Rpb24iLCJfc2NhbGVUaHVtYm5haWxIZWlnaHQiLCJzd2lwZXJDb250YWluZXIiLCIkY29udGFpbmVySGVpZ2h0IiwiaGFzQ2xhc3MiLCJoZWlnaHQiLCJkb25lIiwiZG9jdW1lbnQiLCJyZWFkeSIsImZhZGVJbiIsIkJSRUFLUE9JTlQiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7QUFVQTs7QUFFQTs7Ozs7QUFLQUEsT0FBT0MsT0FBUCxDQUFlQyxNQUFmLENBQ0ksUUFESixFQUdJLENBQ09GLE9BQU9HLE1BRGQsbUJBRU9ILE9BQU9HLE1BRmQsc0JBSEosRUFRSSxVQUFVQyxJQUFWLEVBQWdCOztBQUVaOztBQUVSOztBQUVR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QUFvQjtBQUNoQnpCLGtCQUFNNkYsRUFBTixDQUFTLGNBQVQsRUFBeUIsZUFBekIsRUFBMENoQyxhQUExQztBQUNIOztBQUVENUQsVUFBRXdILFFBQUYsRUFBWUMsS0FBWixDQUFrQixZQUFZO0FBQzFCekgsY0FBRSw0Q0FBRixFQUFnRDJFLEdBQWhELENBQW9ELFNBQXBELEVBQStELGNBQS9EO0FBQ0EzRSxjQUFFLCtDQUFGLEVBQW1EMkUsR0FBbkQsQ0FBdUQsU0FBdkQsRUFBa0UsU0FBbEU7QUFDQTNFLGNBQUUsdUZBQUYsRUFBMkYwSCxNQUEzRixDQUFrRyxJQUFsRztBQUNILFNBSkQ7O0FBTUFuRDtBQUNBMEM7QUFDQUM7O0FBRUE7QUFDQWpILGNBQU0yRixFQUFOLENBQVM1QixJQUFJQyxJQUFKLENBQVNDLEtBQVQsQ0FBZUMsTUFBZixDQUFzQndELFVBQXRCLEVBQVQsRUFBNkMsWUFBWTtBQUNyRFQ7QUFDSCxTQUZEOztBQUlBSztBQUNILEtBMUNEOztBQTRDQTtBQUNBLFdBQU8zSCxNQUFQO0FBQ0gsQ0ExakJMIiwiZmlsZSI6IndpZGdldHMvc3dpcGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiBzd2lwZXIuanMgMjAxNy0wOC0wM1xuIEdhbWJpbyBHbWJIXG4gaHR0cDovL3d3dy5nYW1iaW8uZGVcbiBDb3B5cmlnaHQgKGMpIDIwMTcgR2FtYmlvIEdtYkhcbiBSZWxlYXNlZCB1bmRlciB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKFZlcnNpb24gMilcbiBbaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAuaHRtbF1cbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbi8qIGdsb2JhbHMgU3dpcGVyICovXG5cbi8qKlxuICogV2lkZ2V0IHRoYXQgYmluZHMgdGhlIHN3aXBlciBwbHVnaW4gKHRoaXJkIHBhcnR5KSB0byBhIERPTSBlbGVtZW50XG4gKlxuICogQHRvZG8gUmVtb3ZlIHRoZSB0cnkgLSBjYXRjaCBibG9ja3MgYW5kIGFuZCBjb3JyZWN0IHRoZSBzd2lwZXIgaXNzdWVzLlxuICovXG5nYW1iaW8ud2lkZ2V0cy5tb2R1bGUoXG4gICAgJ3N3aXBlcicsXG5cbiAgICBbXG4gICAgICAgIGAke2dhbWJpby5zb3VyY2V9L2xpYnMvZXZlbnRzYCxcbiAgICAgICAgYCR7Z2FtYmlvLnNvdXJjZX0vbGlicy9yZXNwb25zaXZlYFxuICAgIF0sXG5cbiAgICBmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICd1c2Ugc3RyaWN0JztcblxuLy8gIyMjIyMjIyMjIyBWQVJJQUJMRSBJTklUSUFMSVpBVElPTiAjIyMjIyMjIyMjXG5cbiAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKSxcbiAgICAgICAgICAgICRib2R5ID0gJCgnYm9keScpLFxuICAgICAgICAgICAgJHNsaWRlcyA9IG51bGwsXG4gICAgICAgICAgICAkY29udHJvbHMgPSBudWxsLFxuICAgICAgICAgICAgJHRhcmdldCA9IG51bGwsXG4gICAgICAgICAgICAkdGVtcGxhdGUgPSBudWxsLFxuICAgICAgICAgICAgaW5pdCA9IHRydWUsXG4gICAgICAgICAgICBzd2lwZXIgPSBudWxsLFxuICAgICAgICAgICAgc2xpZGVyT3B0aW9ucyA9IG51bGwsXG4gICAgICAgICAgICBoYXNUaHVtYm5haWxzID0gdHJ1ZSxcbiAgICAgICAgICAgIG1vZGUgPSBudWxsLFxuICAgICAgICAgICAgYnJlYWtwb2ludERhdGFzZXQgPSBudWxsLFxuICAgICAgICAgICAgZHVwbGljYXRlcyA9IGZhbHNlLFxuICAgICAgICAgICAgcHJldmVudFNsaWRlU3RhcnQgPSBmYWxzZSxcbiAgICAgICAgICAgIHNsaWRlckRlZmF1bHRzID0geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciB0aGUgc3dpcGVyXG4gICAgICAgICAgICAgICAgcGFnaW5hdGlvbjogJy5zd2lwZXItcGFnaW5hdGlvbicsXG4gICAgICAgICAgICAgICAgbmV4dEJ1dHRvbjogJy5zd2lwZXItYnV0dG9uLW5leHQnLFxuICAgICAgICAgICAgICAgIHByZXZCdXR0b246ICcuc3dpcGVyLWJ1dHRvbi1wcmV2JyxcbiAgICAgICAgICAgICAgICBwYWdpbmF0aW9uQ2xpY2thYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICAgICAgYXV0b3BsYXk6IDMsXG4gICAgICAgICAgICAgICAgYXV0b3BsYXlEaXNhYmxlT25JbnRlcmFjdGlvbjogZmFsc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZWZhdWx0cyA9IHtcbiAgICAgICAgICAgICAgICAvLyBKU09OIHRoYXQgZ2V0cyBtZXJnZWQgd2l0aCB0aGUgc2xpZGVyRGVmYXVsdHMgYW5kIGlzIHBhc3NlZCB0byBcInN3aXBlclwiIGRpcmVjdGx5LlxuICAgICAgICAgICAgICAgIHNsaWRlck9wdGlvbnM6IG51bGwsXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpbnN0YW5jZSBpcyBhIFwibWFpblwiIHN3aXBlciwgdGhlIGdpdmVuIHNlbGVjdG9yIHNlbGVjdHMgdGhlIFwiY29udHJvbFwiIHN3aXBlci5cbiAgICAgICAgICAgICAgICBjb250cm9sczogbnVsbCxcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGluc3RhbmNlIGlzIGEgXCJjb250cm9sXCIgc3dpcGVyLCB0aGUgZ2l2ZW4gc2VsZWN0b3Igc2VsZWN0cyB0aGUgXCJtYWluXCIgc3dpcGVyLlxuICAgICAgICAgICAgICAgIHRhcmdldDogbnVsbCxcbiAgICAgICAgICAgICAgICAvLyBTZXRzIHRoZSBpbml0aWFsIHNsaWRlIChuZWVkZWQgdG8gcHJldmVudCBkaWZmZXJlbnQgaW5pdCBzbGlkZXMgaW4gbWFpbi9jb250cm9sbGVyIHNsaWRlcikuXG4gICAgICAgICAgICAgICAgaW5pdFNsaWRlOiBudWxsLFxuICAgICAgICAgICAgICAgIC8vIERldGVjdCBpZiBhIHN3aXBlciBpcyBuZWVkZWQgZm9yIHRoZSBicmVha3BvaW50LiBJZiBub3QsIHR1cm4gaXQgb2ZmXG4gICAgICAgICAgICAgICAgYXV0b09mZjogZmFsc2UsXG4gICAgICAgICAgICAgICAgLy8gVGhlIHRyYW5zbHVjZW5jZSBmaXggZW5hYmxlcyBzdXBwb3J0IGZvciBhIGZhZGUgZWZmZWN0IGJldHdlZW4gaW1hZ2VzIHdpdGggZGlmZmVyZW50IGFzcGVjdCByYXRpbyxcbiAgICAgICAgICAgICAgICAvLyBidXQgY2F1c2luZyBhIGRlbGF5IGJldHdlZW4gdGhlIGNoYW5nZVxuICAgICAgICAgICAgICAgIGRpc2FibGVUcmFuc2x1Y2VuY2VGaXg6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGJyZWFrcG9pbnRzOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVudGlsIHdoaWNoIGJyZWFrcG9pbnQgdGhpcyBzZXR0aW5ncyBpcyBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcG9pbnQ6IDQwLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdHJ1ZSwgdGhlIHBhZ2luZyBidWxsZXRzIHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgcHJldmlldyBpbWFnZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VQcmV2aWV3QnVsbGV0czogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGFuZCBhbGwgb3RoZXIgc2V0dGluZ3MgYmVsb25naW5nIHRvIHRoZSBzd2lwZXIgcGx1Z2luLlxuICAgICAgICAgICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMixcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRydWUsIHRoZSBjdXJyZW50IHNsaWRlIGdldHMgY2VudGVyZWQgaW4gdmlldyAobW9zdCB1c2VmdWxsIHdpdGggYW4gZXZlbiBzbGlkZXNQZXJWaWV3XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb3VudCkuXG4gICAgICAgICAgICAgICAgICAgICAgICBjZW50ZXJlZFNsaWRlczogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha3BvaW50OiA2MCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZVByZXZpZXdCdWxsZXRzOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogM1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha3BvaW50OiA4MCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZVByZXZpZXdCdWxsZXRzOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogM1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha3BvaW50OiAxMDAsXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VQcmV2aWV3QnVsbGV0czogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDVcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25zID0gJC5leHRlbmQoe30sIGRlZmF1bHRzLCBkYXRhKSxcbiAgICAgICAgICAgIG1vZHVsZSA9IHt9O1xuXG5cbi8vICMjIyMjIyMjIyMgSEVMUEVSIEZVTkNUSU9OUyAjIyMjIyMjIyMjXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIHRoZSBtYXJrdXAgZm9yXG4gICAgICAgICAqIHRoZSBwcmV2aWV3IGJ1bGxldHNcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtTd2lwZXJ9ICAgICAgICBzd2lwZXIgICAgICAgICAgU3dpcGVyIG9iamVjdFxuICAgICAgICAgKiBAcGFyYW0gICAgICAge2ludGVnZXJ9ICAgICAgIGluZGV4ICAgICAgICAgICBJbmRleCBvZiB0aGUgc2xpZGVcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtzdHJpbmd9ICAgICAgICBjbGFzc05hbWUgICAgICAgVGhlIGNsYXNzbmFtZSB0aGF0IG11c3QgYmUgYWRkIHRvIHRoZSBtYXJrdXBcbiAgICAgICAgICogQHJldHVybiAgICAgIHtzdHJpbmd9ICAgICAgICAgICAgICAgICAgICAgICAgVGhlIHByZXZpZXcgaW1hZ2UgaHRtbCBzdHJpbmdcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfZ2VuZXJhdGVQcmV2aWV3QnV0dG9ucyA9IGZ1bmN0aW9uIChzd2lwZXIsIGluZGV4LCBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIHZhciAkY3VycmVudFNsaWRlID0gJHNsaWRlcy5lcShpbmRleCksXG4gICAgICAgICAgICAgICAgJGltYWdlID0gJGN1cnJlbnRTbGlkZS5maW5kKCdpbWcnKSxcbiAgICAgICAgICAgICAgICBhbHRUeHQgPSAkaW1hZ2UuYXR0cignYWx0JyksXG4gICAgICAgICAgICAgICAgdGh1bWJJbWFnZSA9ICRjdXJyZW50U2xpZGUuZGF0YSgndGh1bWJJbWFnZScpO1xuXG4gICAgICAgICAgICBpZiAodGh1bWJJbWFnZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAnPGltZyBzcmM9XCInICsgdGh1bWJJbWFnZSArICdcIiBhbHQ9XCInICsgYWx0VHh0ICsgJ1wiIGNsYXNzPVwiJyArIGNsYXNzTmFtZSArICdcIiAvPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlXG4gICAgICAgICAqIGFjdGl2ZSBzbGlkZVxuICAgICAgICAgKiBAcmV0dXJuICAgICB7aW50ZWdlcn0gICAgICAgICAgICAgICAgICAgICAgIFRoZSBpbmRleCBvZiB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX2dldEluZGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGluZGV4ID0gJHRoaXNcbiAgICAgICAgICAgICAgICAuZmluZCgnLnN3aXBlci1zbGlkZS1hY3RpdmUnKVxuICAgICAgICAgICAgICAgIC5pbmRleCgpO1xuXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgZHVwbGljYXRlIHNsaWRlcyAoZ2VuZXJhdGVkXG4gICAgICAgICAgICAvLyBieSB0aGUgc3dpcGVyKSByZWNhbGN1bGF0ZSB0aGUgaW5kZXhcbiAgICAgICAgICAgIGluZGV4ID0gZHVwbGljYXRlcyA/IGluZGV4IC0gMSA6IGluZGV4O1xuICAgICAgICAgICAgaW5kZXggPSBpbmRleCB8fCAwO1xuXG4gICAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhlbHBlciBmdW5jdGlvbiB0byBhZGQgdGhlIGFjdGl2ZVxuICAgICAgICAgKiBjbGFzcyB0byB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7aW50ZWdlcn0gICAgICAgICAgIGluZGV4ICAgICAgIFRoZSBpbmRleCBvZiB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3NldEFjdGl2ZSA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICAgICAgJHNsaWRlcyA9ICR0aGlzLmZpbmQoJy5zd2lwZXItc2xpZGU6bm90KC5zd2lwZXItc2xpZGUtZHVwbGljYXRlKScpO1xuICAgICAgICAgICAgaW5kZXggPSBkdXBsaWNhdGVzID8gaW5kZXggKyAxIDogaW5kZXg7XG4gICAgICAgICAgICAkc2xpZGVzXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdhY3RpdmUnKVxuICAgICAgICAgICAgICAgIC5lcShpbmRleClcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICB9O1xuXG5cbi8vICMjIyMjIyMjIyMgRVZFTlQgSEFORExFUiAjIyMjIyMjIyMjXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV2ZW50IGhhbmRsZXIgZm9yIHRoZSBtb3VzZWVudGVyIGV2ZW50LlxuICAgICAgICAgKiBJdCBkaXNhYmxlcyB0aGUgYXV0b3BsYXlcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfbW91c2VFbnRlckhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChzd2lwZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3dpcGVyLnN0b3BBdXRvcGxheSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgbG9nIHRoZSBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFdmVudCBoYW5kbGVyIGZvciB0aGUgbW91c2VsZWF2ZSBldmVudC5cbiAgICAgICAgICogSXQgZW5hYmxlcyB0aGUgYXV0b3BsYXlcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfbW91c2VMZWF2ZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChzd2lwZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3dpcGVyLnN0YXJ0QXV0b3BsYXkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IGxvZyB0aGUgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRXZlbnQgaGFuZGxlciBmb3IgdGhlIGdvdG8gZXZlbnQuXG4gICAgICAgICAqIEl0IHN3aXRjaGVzIHRoZSBjdXJyZW50IHNsaWRlIHRvIHRoZSBnaXZlbiBpbmRleFxuICAgICAgICAgKiBhbmQgYWRkcyB0aGUgYWN0aXZlIGNsYXNzIHRvIHRoZSBuZXcgYWN0aXZlIHNsaWRlXG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7b2JqZWN0fSAgICBlICAgICAgIGpRdWVyeSBldmVudCBvYmplY3RcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtudW1iZXJ9ICAgIGQgICAgICAgSW5kZXggb2YgdGhlIHNsaWRlIHRvIHNob3dcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfZ290b0hhbmRsZXIgPSBmdW5jdGlvbiAoZSwgZCkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBhY3RpdmUgc2xpZGVcbiAgICAgICAgICAgIF9zZXRBY3RpdmUoZCk7XG5cbiAgICAgICAgICAgIC8vIFRlbXBvcmFyeSBkZWFjdGl2YXRlIHRoZSBvblNsaWRlQ2hhbmdlU3RhcnQgZXZlbnRcbiAgICAgICAgICAgIC8vIHRvIHByZXZlbnQgbG9vcGluZyB0aHJvdWdoIHRoZSBnb3RvIC8gY2hhbmdlU3RhcnRcbiAgICAgICAgICAgIC8vIGV2ZW50c1xuICAgICAgICAgICAgcHJldmVudFNsaWRlU3RhcnQgPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGF1dG9wbGF5IGFmdGVyIGEgZ290byBldmVudFxuICAgICAgICAgICAgJHRoaXMub2ZmKCdtb3VzZWxlYXZlLnN3aXBlcicpO1xuICAgICAgICAgICAgc3dpcGVyLnN0b3BBdXRvcGxheSgpO1xuXG4gICAgICAgICAgICAvLyBUcnkgdG8gY29ycmVjdCB0aGUgaW5kZXggYmV0d2VlbiBzbGlkZXJzXG4gICAgICAgICAgICAvLyB3aXRoIGFuZCB3aXRob3V0IGR1cGxpY2F0ZXNcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGR1cGxpY2F0ZXMgPyBkICsgMSA6IGQ7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAkc2xpZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gR290byB0aGUgZGVzaXJlZCBzbGlkZVxuICAgICAgICAgICAgc3dpcGVyLnNsaWRlVG8oaW5kZXgpO1xuXG4gICAgICAgICAgICAvLyBSZWFjdGl2YXRlIHRoZSBvblNsaWRlQ2hhbmdlRXZlbnRcbiAgICAgICAgICAgIHByZXZlbnRTbGlkZVN0YXJ0ID0gZmFsc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENsaWNrIGV2ZW50IGhhbmRsZXIgdGhhdCB0cmlnZ2VycyBhXG4gICAgICAgICAqIFwiZ290b1wiIGV2ZW50IHRvIHRoZSB0YXJnZXQgc3dpcGVyXG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7b2JqZWN0fSAgICAgICAgZSAgICAgICBqUXVlcnkgZXZlbnQgb2JqZWN0XG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX2NsaWNrSGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgICAgICB2YXIgJHNlbGYgPSAkKHRoaXMpLFxuICAgICAgICAgICAgICAgIGluZGV4ID0gJHNlbGYuaW5kZXgoKTtcblxuICAgICAgICAgICAgaW5kZXggPSBkdXBsaWNhdGVzID8gaW5kZXggLSAxIDogaW5kZXg7XG5cbiAgICAgICAgICAgIC8vIFNldCB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAgICBfc2V0QWN0aXZlKGluZGV4KTtcblxuICAgICAgICAgICAgLy8gSW5mb3JtIHRoZSBtYWluIHN3aXBlclxuICAgICAgICAgICAgJHRhcmdldC50cmlnZ2VyKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TV0lQRVJfR09UTygpLCBpbmRleCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV2ZW50IHRoYXQgZ2V0cyB0cmlnZ2VyZWQgb24gc2xpZGVDaGFuZ2UuXG4gICAgICAgICAqIElmIHRoZSBzbGlkZSBnZXRzIGNoYW5nZWQsIHRoZSBjb250cm9sc1xuICAgICAgICAgKiB3aWxsIGZvbGxvdyB0aGUgY3VycmVudCBzbGlkZSBpbiBwb3NpdGlvblxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF90cmlnZ2VyU2xpZGVDaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRTbGlkZVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gX2dldEluZGV4KCksXG4gICAgICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9ICRzbGlkZXMubGVuZ3RoIC0gMjtcblxuXG4gICAgICAgICAgICAgICAgLy8gUmVjYWxjdWxhdGUgaW5kZXggaWYgZHVwbGljYXRlIHNsaWRlcyBhcmUgaW5zaWRlIHRoZSBzbGlkZXJcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gJHNsaWRlcy5sZW5ndGggLSAzO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gKGR1cGxpY2F0ZXMgJiYgaW5kZXggPT09IGxhc3RJbmRleCkgPyBpbmRleCAtIGxhc3RJbmRleCA6IGluZGV4O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAgICAgICAgX3NldEFjdGl2ZShpbmRleCk7XG5cbiAgICAgICAgICAgICAgICAvLyBJbmZvcm0gdGhlIGNvbnRyb2xzXG4gICAgICAgICAgICAgICAgJGNvbnRyb2xzLnRyaWdnZXIoanNlLmxpYnMudGhlbWUuZXZlbnRzLlNXSVBFUl9HT1RPKCksIGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXb3JrYXJvdW5kIGZvciB0aGUgdHJhbnNsdWNlbmNlIGlzc3VlXG4gICAgICAgICAqIHRoYXQgaGFwcGVucyBvbiBzbWFsbCBzY3JlZW5zIHdpdGggZW5hYmxlZFxuICAgICAgICAgKiBmYWRlIGVmZmVjdC4gTWF5YmUgaXQgY2FuIGJlIHJlbW92ZWQsIGlmIHRoZVxuICAgICAgICAgKiBzd2lwZXIgZ2V0cyB1cGRhdGVkIGl0c2VsZlxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF90cmFuc2x1Y2VuY2VXb3JrYXJvdW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmRpc2FibGVUcmFuc2x1Y2VuY2VGaXggJiYgc2xpZGVyT3B0aW9ucyAmJiBzbGlkZXJPcHRpb25zLmVmZmVjdCA9PT0gJ2ZhZGUnKSB7XG4gICAgICAgICAgICAgICAgJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZScpXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoJzpub3QoLnN3aXBlci1zbGlkZS1hY3RpdmUpJylcbiAgICAgICAgICAgICAgICAgICAgLmZhZGVUbygzMDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuY3NzKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICR0aGlzLmZpbmQoJy5zd2lwZXItc2xpZGUnKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCcuc3dpcGVyLXNsaWRlLWFjdGl2ZScpXG4gICAgICAgICAgICAgICAgICAgIC5mYWRlVG8oMzAwLCAxLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmNzcygndmlzaWJpbGl0eScsICcnKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBicmVha3BvaW50IGhhbmRsZXIgaW5pdGlhbGl6ZXMgdGhlIHN3aXBlclxuICAgICAgICAgKiB3aXRoIHRoZSBzZXR0aW5ncyBmb3IgdGhlIGN1cnJlbnQgYnJlYWtwb2ludC5cbiAgICAgICAgICogVGhlcmVmb3JlIGl0IHVzZXMgdGhlIGRlZmF1bHQgc2xpZGVyIG9wdGlvbnMsXG4gICAgICAgICAqIHRoZSBjdXN0b20gc2xpZGVyIG9wdGlvbnMgZ2l2ZW4gYnkgdGhlIG9wdGlvbnNcbiAgICAgICAgICogb2JqZWN0IGFuZCB0aGUgYnJlYWtwb2ludCBvcHRpb25zIG9iamVjdCBhbHNvXG4gICAgICAgICAqIGdpdmVuIGJ5IHRoZSBvcHRpb25zIChpbiB0aGlzIG9yZGVyKVxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9icmVha3BvaW50SGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IHZpZXdtb2RlXG4gICAgICAgICAgICB2YXIgb2xkTW9kZSA9IG1vZGUgfHwge30sXG4gICAgICAgICAgICAgICAgbmV3TW9kZSA9IGpzZS5saWJzLnRoZW1lLnJlc3BvbnNpdmUuYnJlYWtwb2ludCgpLFxuICAgICAgICAgICAgICAgIGV4dGVuZE9wdGlvbnMgPSBvcHRpb25zLmJyZWFrcG9pbnRzWzBdIHx8IHt9LFxuICAgICAgICAgICAgICAgIG5ld0JyZWFrcG9pbnREYXRhc2V0ID0gbnVsbDtcblxuICAgICAgICAgICAgLy8gT25seSBkbyBzb21ldGhpbmcgaWYgdGhlIHZpZXcgd2FzIGNoYW5nZWRcbiAgICAgICAgICAgIGlmIChuZXdNb2RlLmlkICE9PSBvbGRNb2RlLmlkKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBTdG9yZSB0aGUgbmV3IHZpZXdtb2RlXG4gICAgICAgICAgICAgICAgbW9kZSA9ICQuZXh0ZW5kKHt9LCBuZXdNb2RlKTtcblxuICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCB0aGUgYnJlYWtwb2ludHMgb2JqZWN0IHRvIGRldGVjdFxuICAgICAgICAgICAgICAgIC8vIHRoZSBjb3JyZWN0IHNldHRpbmdzIGZvciB0aGUgY3VycmVudCBicmVha3BvaW50XG4gICAgICAgICAgICAgICAgJC5lYWNoKG9wdGlvbnMuYnJlYWtwb2ludHMsIGZ1bmN0aW9uIChpLCB2KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2LmJyZWFrcG9pbnQgPiBuZXdNb2RlLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmV3QnJlYWtwb2ludERhdGFzZXQgPSBpO1xuICAgICAgICAgICAgICAgICAgICBleHRlbmRPcHRpb25zID0gdjtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNsaWRlck9wdGlvbnMgJiYgb3B0aW9ucy5zbGlkZXJPcHRpb25zLmJyZWFrcG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICQuZWFjaChvcHRpb25zLnNsaWRlck9wdGlvbnMuYnJlYWtwb2ludHMsIGZ1bmN0aW9uIChpLCB2KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodi5icmVha3BvaW50ID09PSBuZXdNb2RlLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kT3B0aW9ucyA9IHY7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBPbmx5IGRvIHNvbWV0aGluZyBpZiB0aGUgc2V0dGluZ3MgY2hhbmdlIGR1ZSBicm93c2VyXG4gICAgICAgICAgICAgICAgLy8gcmVzaXplIG9yIGlmIGl0J3MgdGhlIGZpcnN0IHRpbWUgcnVuXG4gICAgICAgICAgICAgICAgaWYgKG5ld0JyZWFrcG9pbnREYXRhc2V0ICE9PSBicmVha3BvaW50RGF0YXNldCB8fCBpbml0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENvbWJpbmUgdGhlIHNldHRpbmdzXG4gICAgICAgICAgICAgICAgICAgIHNsaWRlck9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgc2xpZGVyRGVmYXVsdHMsIG9wdGlvbnMuc2xpZGVyT3B0aW9ucyB8fCB7fSwgZXh0ZW5kT3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIHRoZSBwcmV2aWV3IGltYWdlIGJ1bGxldHMgZnVuY3Rpb24gdG8gdGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGlmIChzbGlkZXJPcHRpb25zLnVzZVByZXZpZXdCdWxsZXRzICYmIGhhc1RodW1ibmFpbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNsaWRlck9wdGlvbnMucGFnaW5hdGlvbkJ1bGxldFJlbmRlciA9IF9nZW5lcmF0ZVByZXZpZXdCdXR0b25zO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIHRoZSBhdXRvcGxheSBpbnRlcnZhbCB0byB0aGUgb3B0aW9ucyBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgc2xpZGVyT3B0aW9ucy5hdXRvcGxheSA9IChzbGlkZXJPcHRpb25zLmF1dG9wbGF5KSA/IChzbGlkZXJPcHRpb25zLmF1dG9wbGF5ICogMTAwMCkgOiAwO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERpc2FibGUgbG9vcCBpZiB0aGVyZSBpcyBvbmx5IG9uZSBzbGlkZXIuXG4gICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy5maW5kKCcuc3dpcGVyLXNsaWRlJykubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXJPcHRpb25zLmxvb3AgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGFuIHN3aXBlciBleGlzdHMsIGdldCB0aGUgY3VycmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBzbGlkZSBuby4gYW5kIHJlbW92ZSB0aGUgb2xkIHN3aXBlclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3dpcGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXJPcHRpb25zLmluaXRpYWxTbGlkZSA9IF9nZXRJbmRleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXIuZGVzdHJveSh0cnVlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGlnbm9yZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNsaWRlck9wdGlvbnMuaW5pdGlhbFNsaWRlID0gb3B0aW9ucy5pbml0U2xpZGUgfHwgc2xpZGVyT3B0aW9ucy5pbml0aWFsU2xpZGUgfHwgMDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciAkZHVwbGljYXRlID0gJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZTpub3QoLnN3aXBlci1zbGlkZS1kdXBsaWNhdGUpJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmF1dG9PZmYgfHwgKCRkdXBsaWNhdGUubGVuZ3RoID4gc2xpZGVyT3B0aW9ucy5zbGlkZXNQZXJWaWV3ICYmIG9wdGlvbnMuYXV0b09mZikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCdzd2lwZXItaXMtYWN0aXZlJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3N3aXBlci1pcy1ub3QtYWN0aXZlJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIHN3aXBlclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXIgPSBuZXcgU3dpcGVyKCR0aGlzLCBzbGlkZXJPcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIFN3aXBlciBtaWdodCB0aHJvdyBhbiBlcnJvciB1cG9uIGluaXRpYWxpemF0aW9uIHRoYXQgc2hvdWxkIG5vdCBoYWx0IHRoZSBzY3JpcHQgZXhlY3V0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub2ZmKCdvblRyYW5zaXRpb25FbmQgb25TbGlkZUNoYW5nZVN0YXJ0JylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oJ29uVHJhbnNpdGlvbkVuZCcsIF90cmFuc2x1Y2VuY2VXb3JrYXJvdW5kKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIFwibWFpblwiIHN3aXBlciBhbmQgaGFzIGV4dGVybmFsIGNvbnRyb2xzLCBhblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ290byBldmVudCBpcyB0cmlnZ2VyZWQgaWYgdGhlIGN1cnJlbnQgc2xpZGUgaXMgY2hhbmdlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjb250cm9scy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXIub24oJ29uU2xpZGVDaGFuZ2VTdGFydCcsIF90cmlnZ2VyU2xpZGVDaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIGV2ZW50IGhhbmRsZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9mZignbW91c2VlbnRlci5zd2lwZXIgbW91c2VsZWF2ZS5zd2lwZXIgJyArIGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TV0lQRVJfR09UTygpICsgJyAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsganNlLmxpYnMudGhlbWUuZXZlbnRzLlNMSURFU19VUERBVEUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oJ21vdXNlZW50ZXIuc3dpcGVyJywgX21vdXNlRW50ZXJIYW5kbGVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbignbW91c2VsZWF2ZS5zd2lwZXInLCBfbW91c2VMZWF2ZUhhbmRsZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TV0lQRVJfR09UTygpLCBfZ290b0hhbmRsZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TTElERVNfVVBEQVRFKCksIF91cGRhdGVTbGlkZXMpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5pdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZXJlIGFyZSBkdXBsaWNhdGVzIHNsaWRlcyAoZ2VuZXJhdGVkIGJ5IHRoZSBzd2lwZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWZ0ZXIgdGhlIGZpcnN0IHRpbWUgaW5pdCBvZiB0aGUgc3dpcGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwbGljYXRlcyA9ICEhJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZS1kdXBsaWNhdGUnKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSAoaW5pdCAmJiBvcHRpb25zLmluaXRTbGlkZSkgPyBvcHRpb25zLmluaXRTbGlkZSA6IF9nZXRJbmRleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgX3NldEFjdGl2ZShpbmRleCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluZm9ybSB0aGUgY29udHJvbHMgdGhhdCB0aGUgbWFpbiBzd2lwZXIgaGFzIGNoYW5nZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIGNhc2UgdGhhdCB0aGUgb3RoZXIgc2xpZGVyIGlzbid0IGluaXRpYWxpemVkIHlldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBhbiBkYXRhIGF0dHJpYnV0ZSB0byB0aGUgbWFya3VwIGVsZW1lbnQgdG8gaW5mb3JtXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBvbiBpbml0XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRyb2xzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250cm9scy5hdHRyKCdkYXRhLXN3aXBlci1pbml0LXNsaWRlJywgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90cmlnZ2VyU2xpZGVDaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW5zZXQgdGhlIGluaXQgZmxhZ1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN3aXBlci51cGRhdGUoKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEaXNhYmxlIHRoZSBzd2lwZXIgYnV0dG9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3N3aXBlci1pcy1hY3RpdmUnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnc3dpcGVyLWlzLW5vdC1hY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRXZlbnQgaGFuZGxlciB0aGF0IGFkZHMgJiByZW1vdmVzIHNsaWRlcyBmcm9tIHRoZVxuICAgICAgICAgKiBzd2lwZXIuIEFmdGVyIHRoZSBzbGlkZXMgd2VyZSBwcm9jZXNzZWQsIHRoZSBmaXJzdFxuICAgICAgICAgKiBzbGlkZSBpcyBzaG93blxuICAgICAgICAgKiBAcGFyYW0gICAgICAge29iamVjdH0gICAgZSAgICAgICBqUXVlcnkgZXZlbnQgb2JqZWN0XG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7b2JqZWN0fSAgICBkICAgICAgIEpTT04gb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGNhdGVnb3JpZXMgLyBpbWFnZXNcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfdXBkYXRlU2xpZGVzID0gZnVuY3Rpb24gKGUsIGQpIHtcblxuICAgICAgICAgICAgLy8gTG9vcHMgdGhyb3VnaCBlYWNoIGNhdGVnb3J5IGluc2lkZSB0aGUgaW1hZ2VzIGFycmF5XG4gICAgICAgICAgICAkLmVhY2goZCwgZnVuY3Rpb24gKGNhdGVnb3J5LCBkYXRhc2V0KSB7XG4gICAgICAgICAgICAgICAgdmFyIGNhdE5hbWUgPSBjYXRlZ29yeSArICctY2F0ZWdvcnknLFxuICAgICAgICAgICAgICAgICAgICBhZGQgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlID0gW10sXG4gICAgICAgICAgICAgICAgICAgIG1hcmt1cCA9ICR0ZW1wbGF0ZS5odG1sKCk7XG5cbiAgICAgICAgICAgICAgICAvLyBHZXQgYWxsIGluZGV4ZXMgZnJvbSB0aGUgc2xpZGVzXG4gICAgICAgICAgICAgICAgLy8gb2YgdGhlIHNhbWUgY2F0ZWdvcnkgYW5kIHJlbW92ZVxuICAgICAgICAgICAgICAgIC8vIHRoZW0gZnJvbSB0aGUgc2xpZGVyXG4gICAgICAgICAgICAgICAgJHNsaWRlc1xuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCcuJyArIGNhdE5hbWUpXG4gICAgICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkc2VsZiA9ICQodGhpcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSAkc2VsZi5kYXRhKCkuc3dpcGVyU2xpZGVJbmRleDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCA9PT0gdW5kZWZpbmVkID8gJHNlbGYuaW5kZXgoKSA6IGluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlLnB1c2goaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzd2lwZXIucmVtb3ZlU2xpZGUocmVtb3ZlKTtcblxuICAgICAgICAgICAgICAgIC8vIEdlbmVyYXRlIHRoZSBtYXJrdXAgZm9yIHRoZSBuZXcgc2xpZGVzXG4gICAgICAgICAgICAgICAgLy8gYW5kIGFkZCB0aGVtIHRvIHRoZSBzbGlkZXJcbiAgICAgICAgICAgICAgICAkLmVhY2goZGF0YXNldCB8fCBbXSwgZnVuY3Rpb24gKGksIHYpIHtcbiAgICAgICAgICAgICAgICAgICAgdi5jbGFzc05hbWUgPSBjYXROYW1lO1xuICAgICAgICAgICAgICAgICAgICB2LnNyY2F0dHIgPSAnc3JjPVwiJyArIHYuc3JjICsgJ1wiJztcbiAgICAgICAgICAgICAgICAgICAgYWRkLnB1c2goTXVzdGFjaGUucmVuZGVyKG1hcmt1cCwgdikpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN3aXBlci5hcHBlbmRTbGlkZShhZGQpO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHNsaWRlcyA9ICR0aGlzLmZpbmQoJy5zd2lwZXItc2xpZGUnKTtcblxuICAgICAgICAgICAgLy8gVG8gcHJldmVudCBhbiBpbmNvbnNpc3RlbnQgc3RhdGVcbiAgICAgICAgICAgIC8vIGluIGNvbnRyb2wgLyBtYWluIHNsaWRlciBjb21iaW5hdGlvbnNcbiAgICAgICAgICAgIC8vIHNsaWRlIHRvIHRoZSBmaXJzdCBzbGlkZVxuICAgICAgICAgICAgX3NldEFjdGl2ZSgwKTtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGR1cGxpY2F0ZXMgPyAxIDogMDtcbiAgICAgICAgICAgIHN3aXBlci5zbGlkZVRvKGluZGV4LCAwKTtcblxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcmV2ZW50IHRleHQgc2VsZWN0aW9uIGJ5IGNsaWNraW5nIG9uIHN3aXBlciBidXR0b25zXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3ByZXZlbnRUZXh0U2VsZWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJChvcHRpb25zLnNsaWRlck9wdGlvbnMubmV4dEJ1dHRvbikub24oJ3NlbGVjdHN0YXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJChvcHRpb25zLnNsaWRlck9wdGlvbnMucHJldkJ1dHRvbikub24oJ3NlbGVjdHN0YXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBpbml0aWFsIGhlaWdodCBmb3Igb25lIHN3aXBlciBpbWFnZSBjb250YWluZXIgdG8gcHJldmVudCBjdXQgb2ZmIGltYWdlcyBvbiBzbWFsbGVyIHN3aXBlciBoZWlnaHRzXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3NjYWxlVGh1bWJuYWlsSGVpZ2h0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHN3aXBlckNvbnRhaW5lciA9ICQoJy5zd2lwZXItY29udGFpbmVyLXZlcnRpY2FsIC5zd2lwZXItc2xpZGUnKTtcbiAgICAgICAgICAgIHZhciAkY29udGFpbmVySGVpZ2h0ID0gc3dpcGVyQ29udGFpbmVyLmNzcygnaGVpZ2h0Jyk7XG5cblxuICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgSUUgQnJvd3NlcnNcbiAgICAgICAgICAgIGlmICgkKCcuc3dpcGVyLWNvbnRhaW5lci12ZXJ0aWNhbCcpLmhhc0NsYXNzKCdzd2lwZXItd3A4LXZlcnRpY2FsJykpIHtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVySGVpZ2h0ID0gc3dpcGVyQ29udGFpbmVyLmhlaWdodCgpICsgNTtcblxuICAgICAgICAgICAgICAgIHN3aXBlckNvbnRhaW5lci5jc3MoJ2hlaWdodCcsICRjb250YWluZXJIZWlnaHQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoJGNvbnRhaW5lckhlaWdodCA9PT0gJzBweCcpIHtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVySGVpZ2h0ID0gJCgnLnByb2R1Y3QtaW5mby10aHVtYm5haWxzLW1vYmlsZScpLmNzcygnaGVpZ2h0Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICQoJy5hbGlnbi1taWRkbGUnKS5jc3MoJ2hlaWdodCcsICRjb250YWluZXJIZWlnaHQpO1xuICAgICAgICB9O1xuXG4vLyAjIyMjIyMjIyMjIElOSVRJQUxJWkFUSU9OICMjIyMjIyMjIyNcblxuICAgICAgICAvKipcbiAgICAgICAgICogSW5pdCBmdW5jdGlvbiBvZiB0aGUgd2lkZ2V0XG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKi9cbiAgICAgICAgbW9kdWxlLmluaXQgPSBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICAkc2xpZGVzID0gJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZScpO1xuICAgICAgICAgICAgJGNvbnRyb2xzID0gJChvcHRpb25zLmNvbnRyb2xzKTtcbiAgICAgICAgICAgICR0YXJnZXQgPSAkKG9wdGlvbnMudGFyZ2V0KTtcbiAgICAgICAgICAgICR0ZW1wbGF0ZSA9ICR0aGlzLmZpbmQoJ3RlbXBsYXRlJyk7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGFsbCBpbWFnZXMgaW5zaWRlIHRoZSBzd2lwZXIgaGF2ZVxuICAgICAgICAgICAgLy8gdGh1bWJuYWlsIGltYWdlIGdpdmVuXG4gICAgICAgICAgICAkc2xpZGVzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICghJCh0aGlzKS5kYXRhKCkudGh1bWJJbWFnZSkge1xuICAgICAgICAgICAgICAgICAgICBoYXNUaHVtYm5haWxzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQWRkIHRoZSBicmVha3BvaW50IGhhbmRsZXIgdHkgZHluYW1pY2FsbHlcbiAgICAgICAgICAgIC8vIHNldCB0aGUgb3B0aW9ucyBjb3JyZXNwb25kaW5nIHRvIHRoZSBicm93c2VyIHNpemUgKHNsaWRlciByZXNwb25zaXZlIHdpbGwgcmUtaW5pdGlhbGl6ZSB0aGUgc3dpcGVyKS5cbiAgICAgICAgICAgIF9icmVha3BvaW50SGFuZGxlcigpO1xuXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGluc3RhbmNlIGlzIGEgXCJjb250cm9sXCIgc3dpcGVyIHRoZSB0YXJnZXQgaXMgdGhlIG1haW4gc3dpcGVyXG4gICAgICAgICAgICAvLyB3aGljaCB3aWxsIGJlIHVwZGF0ZWQgb24gYSBjbGljayBpbnNpZGUgdGhpcyBjb250cm9sIHN3aXBlclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgJHRoaXMub24oJ2NsaWNrLnN3aXBlcicsICcuc3dpcGVyLXNsaWRlJywgX2NsaWNrSGFuZGxlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAkKCcuc3dpcGVyLXZlcnRpY2FsIC5zd2lwZXItc2xpZGVbZGF0YS1pbmRleF0nKS5jc3MoJ2Rpc3BsYXknLCAnaW5saW5lLWJsb2NrJyk7XG4gICAgICAgICAgICAgICAgJCgnLnByb2R1Y3QtaW5mby1pbWFnZSAuc3dpcGVyLXNsaWRlW2RhdGEtaW5kZXhdJykuY3NzKCd6LWluZGV4JywgJ2luaGVyaXQnKTtcbiAgICAgICAgICAgICAgICAkKCcucHJvZHVjdC1pbmZvLWltYWdlIC5zd2lwZXItc2xpZGVbZGF0YS1pbmRleF0gLnN3aXBlci1zbGlkZS1pbnNpZGUgaW1nLmltZy1yZXNwb25zaXZlJykuZmFkZUluKDEwMDApO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIF90cmFuc2x1Y2VuY2VXb3JrYXJvdW5kKCk7XG4gICAgICAgICAgICBfcHJldmVudFRleHRTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIF9zY2FsZVRodW1ibmFpbEhlaWdodCgpO1xuXG4gICAgICAgICAgICAvLyBGaXggZm9yIGludmlzaWJsZSBUaHVtYm5haWwtSW1hZ2VzIGZvciBzd2l0Y2hpbmcgZnJvbSBUYWJsZXQtUG9ydHJhaXQgdG8gVGFibGV0LUxhbmRzY2FwZVxuICAgICAgICAgICAgJGJvZHkub24oanNlLmxpYnMudGhlbWUuZXZlbnRzLkJSRUFLUE9JTlQoKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF9zY2FsZVRodW1ibmFpbEhlaWdodCgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm4gZGF0YSB0byB3aWRnZXQgZW5naW5lXG4gICAgICAgIHJldHVybiBtb2R1bGU7XG4gICAgfSk7XG4iXX0=