403Webshell
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 :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/moncbefd/www.moneta.at/templates/Honeygrid/assets/javascript/engine/widgets/swiper.js
'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=

Youez - 2016 - github.com/yon3zu
LinuXploit