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/cart_handler.js
'use strict';

/* --------------------------------------------------------------
 cart_handler.js 2019-06-20
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2019 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

/**
 * Component for handling the add to cart and wishlist features
 * at the product details and the category listing pages. It cares
 * for attributes, properties, quantity and all other
 * relevant data for adding an item to the basket or wishlist
 */
gambio.widgets.module('cart_handler', ['hooks', 'form', 'xhr', gambio.source + '/libs/events', gambio.source + '/libs/modal.ext-magnific', gambio.source + '/libs/modal'], function (data) {

    'use strict';

    // ########## VARIABLE INITIALIZATION ##########

    var $this = $(this),
        $body = $('body'),
        $window = $(window),
        busy = false,
        ajax = null,
        timeout = 0,
        defaults = {
        // AJAX "add to cart" URL
        addCartUrl: 'shop.php?do=Cart/BuyProduct',
        // AJAX "add to cart" URL for customizer products
        addCartCustomizerUrl: 'shop.php?do=Cart/Add',
        // AJAX URL to perform a value check
        checkUrl: 'shop.php?do=CheckStatus',
        // AJAX URL to perform the add to wishlist
        wishlistUrl: 'shop.php?do=WishList/Add',
        // Submit URL for price offer button
        priceOfferUrl: 'gm_price_offer.php',
        // Submit method for price offer
        priceOfferMethod: 'get',
        // Selector for the cart dropdown
        dropdown: '#head_shopping_cart',
        // "Add to cart" buttons selectors
        cartButtons: '.js-btn-add-to-cart',
        // "Wishlist" buttons selectors
        wishlistButtons: '.btn-wishlist',
        // "Price offer" buttons selectors
        priceOfferButtons: '.btn-price-offer',
        // Selector for the attribute fields
        attributes: '.js-calculate',
        // Selector for the quantity
        quantity: '.js-calculate-qty',
        // URL where to get the template for the dropdown
        tpl: null,
        // Show attribute images in product images swiper (if possible)
        // -- this feature is not supported yet --
        attributImagesSwiper: false,
        // Trigger the attribute images to this selectors
        triggerAttrImagesTo: '#product_image_swiper, #product_thumbnail_swiper, ' + '#product_thumbnail_swiper_mobile',
        // Class that gets added to the button on processing
        processingClass: 'loading',
        // Duration for that the success or fail class gets added to the button
        processingDuration: 2000,
        // AJAX response content selectors
        selectorMapping: {
            attributeImages: '.attribute-images',
            buttons: '.shopping-cart-button',
            giftContent: '.gift-cart-content-wrapper',
            giftLayer: '.gift-cart-layer',
            shareContent: '.share-cart-content-wrapper',
            shareLayer: '.share-cart-layer',
            hiddenOptions: '#cart_quantity .hidden-options',
            message: '.global-error-messages',
            messageCart: '.cart-error-msg',
            messageHelp: '.help-block',
            modelNumber: '.model-number',
            modelNumberText: '.model-number-text',
            price: '.current-price-container',
            propertiesForm: '.properties-selection-form',
            quantity: '.products-quantity-value',
            ribbonSpecial: '.ribbon-special',
            shippingInformation: '#shipping-information-layer',
            shippingTime: '.products-shipping-time-value',
            shippingTimeImage: '.img-shipping-time img',
            totals: '#cart_quantity .total-box',
            weight: '.products-details-weight-container span'
        },
        page: 'product-listing'
    },
        options = $.extend(true, {}, defaults, data),
        module = {},
        mobile = $(window).width() <= 767;

    // ########## HELPER FUNCTIONS ##########

    /**
     * Helper function that updates the button
     * state with an error or success class for
     * a specified duration
     * @param   {object}        $target         jQuery selection of the target button
     * @param   {string}        state           The state string that gets added to the loading class
     * @private
     */
    var _addButtonState = function _addButtonState($target, state) {
        var timer = setTimeout(function () {
            $target.removeClass(options.processingClass + ' ' + options.processingClass + state);
        }, options.processingDuration);

        $target.data('timer', timer).addClass(options.processingClass + state);
    };

    /**
     * Helper function to set the messages and the
     * button state.
     * @param       {object}    data                Result form the ajax request
     * @param       {object}    $form               jQuery selecion of the form
     * @param       {boolean}   disableButtons      If true, the button state gets set to (in)active
     * @param       {boolean}   showNoCombiMesssage If true, the error message for missing property combination selection will be displayed
     * @private
     */
    var _stateManager = function _stateManager(data, $form, disableButtons, showNoCombiSelectedMesssage) {

        // Remove the attribute images from the common content
        // so that it doesn't get rendered anymore. Then trigger
        // an event to the given selectors and deliver the
        // attrImages object
        if (options.attributImagesSwiper && data.attrImages && data.attrImages.length) {
            delete data.content.images;
            $(options.triggerAttrImagesTo).trigger(jse.libs.theme.events.SLIDES_UPDATE(), { attributes: data.attrImages });
        }

        // Set the messages given inside the data.content object
        $.each(data.content, function (i, v) {
            var $element = $form.parent().find(options.selectorMapping[v.selector]);

            if ((!showNoCombiSelectedMesssage || v.value === '') && i === 'messageNoCombiSelected') {
                return true;
            }

            switch (v.type) {
                case 'hide':
                    if (v.value === 'true') {
                        $element.hide();
                    } else {
                        $element.show();
                    }
                    break;
                case 'html':
                    $element.html(v.value);
                    break;
                case 'attribute':
                    $element.attr(v.key, v.value);
                    break;
                case 'replace':
                    if (v.value) {
                        $element.replaceWith(v.value);
                    } else {
                        $element.addClass('hidden').empty();
                    }
                    break;
                default:
                    $element.text(v.value);
                    break;
            }
        });

        // Dis- / Enable the buttons
        if (disableButtons) {
            var $buttons = $form.find(options.cartButtons);
            if (data.success) {
                $buttons.removeClass('inactive');
                $buttons.removeClass('btn-inactive');
                $buttons.prop("disabled", false);
            } else {
                $buttons.addClass('inactive');
                $buttons.addClass('btn-inactive');
                $buttons.prop("disabled", true);
            }
        }

        if (data.content.message) {
            var $errorField = $form.find(options.selectorMapping[data.content.message.selector]);
            if (data.content.message.value) {
                $errorField.removeClass('hidden').show();
            } else {
                $errorField.addClass('hidden').hide();

                if (showNoCombiSelectedMesssage && data.content.messageNoCombiSelected !== undefined && data.content.messageNoCombiSelected) {
                    if (data.content.messageNoCombiSelected.value) {
                        $errorField.removeClass('hidden').show();
                    } else {
                        $errorField.addClass('hidden').hide();
                    }
                }
            }
        }

        $window.trigger(jse.libs.theme.events.STICKYBOX_CONTENT_CHANGE());
    };

    /**
     * Helper function to send the ajax
     * On success redirect to a given url, open a layer with
     * a message or add the item to the cart-dropdown directly
     * (by triggering an event to the body)
     * @param       {object}      data      Form data
     * @param       {object}      $form     The form to fill
     * @param       {string}      url       The URL for the AJAX request
     * @private
     */
    var _addToSomewhere = function _addToSomewhere(data, $form, url, $button) {
        function callback() {
            jse.libs.xhr.post({ url: url, data: data }, true).done(function (result) {
                try {
                    // Fill the page with the result from the ajax
                    _stateManager(result, $form, false);

                    // If the AJAX was successful execute
                    // a custom functionality
                    if (result.success) {
                        switch (result.type) {
                            case 'url':
                                if (result.url.substr(0, 4) !== 'http') {
                                    location.href = jse.core.config.get('appUrl') + '/' + result.url;
                                } else {
                                    location.href = result.url;
                                }

                                break;
                            case 'dropdown':
                                $body.trigger(jse.libs.theme.events.CART_UPDATE(), [true]);
                                break;
                            case 'layer':
                                jse.libs.theme.modal.info({ title: result.title, content: result.msg });
                                break;
                            default:
                                break;
                        }
                    }
                } catch (ignore) {}
                _addButtonState($button, '-success');
            }).fail(function () {
                _addButtonState($button, '-fail');
            }).always(function () {
                // Reset the busy flag to be able to perform
                // further AJAX requests
                busy = false;
            });
        }

        if (!busy) {
            // only execute the ajax
            // if there is no pending ajax call
            busy = true;

            jse.libs.hooks.execute(jse.libs.hooks.keys.shop.cart.add, data, 500).then(callback).catch(callback);
        }
    };

    // ########## EVENT HANDLER ##########

    /**
     * Handler for the submit form / click
     * on "add to cart" & "wishlist" button.
     * It performs a check on the availability
     * of the combination and quantity. If
     * successful it performs the add to cart
     * or wishlist action, if it's not a
     * "check" call
     * @param       {object}    e      jQuery event object
     * @private
     */
    var _submitHandler = function _submitHandler(e) {
        if (e) {
            e.preventDefault();
        }

        var $self = $(this),
            $form = $self.is('form') ? $self : $self.closest('form'),
            customizer = $form.hasClass('customizer'),
            properties = !!$form.find('.properties-selection-form').length,
            module = properties ? '' : '/Attributes',
            showNoCombiSelectedMesssage = e && e.data && e.data.target && e.data.target !== 'check';

        if ($form.length) {

            // Show properties overlay
            // to disable user interaction
            // before markup replace
            if (properties) {
                $this.addClass('loading');
            }

            var formdata = jse.libs.form.getData($form, null, true);
            formdata.target = e && e.data && e.data.target ? e.data.target : 'check';
            formdata.isProductInfo = $form.hasClass('product-info') ? 1 : 0;

            // Abort previous check ajax if
            // there is one in progress
            if (ajax && e) {
                ajax.abort();
            }

            // Add processing-class to the button
            // and remove old timed events
            if (formdata.target !== 'check') {
                var timer = $self.data('timer');
                if (timer) {
                    clearTimeout(timer);
                }

                $self.removeClass(options.processingClass + '-success ' + options.processingClass + '-fail').addClass(options.processingClass);
            }

            ajax = jse.libs.xhr.get({
                url: options.checkUrl + module,
                data: formdata
            }, true).done(function (result) {
                _stateManager(result, $form, true, showNoCombiSelectedMesssage);
                $this.removeClass('loading');

                if (result.success) {
                    var event = null,
                        url = null;

                    switch (formdata.target) {
                        case 'wishlist':
                            if (customizer) {
                                event = jse.libs.theme.events.ADD_CUSTOMIZER_WISHLIST();
                            }
                            url = options.wishlistUrl;
                            break;
                        case 'cart':
                            if (customizer) {
                                event = jse.libs.theme.events.ADD_CUSTOMIZER_CART();
                                url = options.addCartCustomizerUrl;
                            } else {
                                url = options.addCartUrl;
                            }
                            break;
                        case 'price_offer':
                            $form.attr('action', options.priceOfferUrl).attr('method', options.priceOfferMethod);
                            $form.off('submit');
                            $form.submit();

                            return;
                        default:
                            setTimeout(function () {
                                $window.trigger(jse.libs.theme.events.STICKYBOX_CONTENT_CHANGE());
                            }, 250);
                            break;
                    }

                    if (event) {
                        var deferred = $.Deferred();
                        deferred.done(function (customizerRandom) {
                            formdata[customizerRandom] = 0;
                            _addToSomewhere(formdata, $form, url, $self);
                        }).fail(function () {
                            _addButtonState($self, '-fail');
                        });
                        $body.trigger(event, [{ 'deferred': deferred, 'dataset': formdata }]);
                    } else if (url) {
                        _addToSomewhere(formdata, $form, url, $self);
                    }
                }
            }).fail(function () {
                _addButtonState($self, '-fail');
            });
        }
    };

    /**
     * Keyup handler for quantity input field
     *
     * @param e
     * @private
     */
    var _keyupHandler = function _keyupHandler(e) {
        clearTimeout(timeout);

        timeout = setTimeout(function () {
            _submitHandler.call(this, e);
        }.bind(this), 300);
    };

    /**
     * Event handler for the add to cart button, that shows or hides the throbber.
     */
    var _addToCartThrobberHandler = function _addToCartThrobberHandler(e) {
        var $btn = $(this);
        var $btnFake = $this.find(".btn-add-to-cart-fake");
        var formReady = true;

        $(".properties-selection-form select").each(function () {
            var val = $(this).val();
            if (!val || val < 1) {
                formReady = false;
            }
        });

        if (formReady) {
            $btn.hide();
            $btnFake.show().prop("disabled", true).prepend('<span class="throbbler"></span>');
        }
    };

    /**
     * Cart dropdown oben event handler for the body.
     */
    var _cartDropdownOpenHandler = function _cartDropdownOpenHandler(e) {
        var $btn = $this.find("[name=btn-add-to-cart]");
        var $btnFake = $this.find(".btn-add-to-cart-fake");
        var fakeOrigLabel = $btnFake.html();
        var productCount = $(".cart-products-count").html();

        var textPhrases = JSON.parse($('#product-details-text-phrases').html());
        console.log(textPhrases['productsInCartSuffix']);

        $btnFake.html("<i class=\"fa fa-check\"></i> " + parseInt(productCount) + textPhrases['productsInCartSuffix']).prop("disabled", true).addClass("btn-buy-complete");

        setTimeout(function () {
            $btnFake.html(fakeOrigLabel).removeClass("btn-buy-complete").hide().prop("disabled", false);
            $(".throbbler", $btn).remove();
            $btn.show();
        }, 5000);
    };

    // ########## INITIALIZATION ##########

    /**
     * Init function of the widget
     * @constructor
     */
    module.init = function (done) {

        var $forms = $this.find('form');

        if (options.page === 'product-info') {
            $forms.find("[name=btn-add-to-cart]").on('mouseup', _addToCartThrobberHandler);
            $("body").on('CART_DROPDOWN_OPEN', _cartDropdownOpenHandler);
        }

        $forms.on('submit', { 'target': 'cart' }, _submitHandler).on('click', options.wishlistButtons, { 'target': 'wishlist' }, _submitHandler).on('click', options.priceOfferButtons, { 'target': 'price_offer' }, _submitHandler).on('change', options.attributes, { 'target': 'check' }, _submitHandler).on('blur', options.quantity, { 'target': 'check' }, function (e) {
            _submitHandler(e);
        }).on('keyup', options.quantity, { 'target': 'check' }, _keyupHandler);

        // Fallback if the backend renders incorrect data
        // on initial page call
        $forms.not('.no-status-check').each(function () {
            _submitHandler.call($(this));
        });

        done();
    };

    // Return data to widget engine
    return module;
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndpZGdldHMvY2FydF9oYW5kbGVyLmpzIl0sIm5hbWVzIjpbImdhbWJpbyIsIndpZGdldHMiLCJtb2R1bGUiLCJzb3VyY2UiLCJkYXRhIiwiJHRoaXMiLCIkIiwiJGJvZHkiLCIkd2luZG93Iiwid2luZG93IiwiYnVzeSIsImFqYXgiLCJ0aW1lb3V0IiwiZGVmYXVsdHMiLCJhZGRDYXJ0VXJsIiwiYWRkQ2FydEN1c3RvbWl6ZXJVcmwiLCJjaGVja1VybCIsIndpc2hsaXN0VXJsIiwicHJpY2VPZmZlclVybCIsInByaWNlT2ZmZXJNZXRob2QiLCJkcm9wZG93biIsImNhcnRCdXR0b25zIiwid2lzaGxpc3RCdXR0b25zIiwicHJpY2VPZmZlckJ1dHRvbnMiLCJhdHRyaWJ1dGVzIiwicXVhbnRpdHkiLCJ0cGwiLCJhdHRyaWJ1dEltYWdlc1N3aXBlciIsInRyaWdnZXJBdHRySW1hZ2VzVG8iLCJwcm9jZXNzaW5nQ2xhc3MiLCJwcm9jZXNzaW5nRHVyYXRpb24iLCJzZWxlY3Rvck1hcHBpbmciLCJhdHRyaWJ1dGVJbWFnZXMiLCJidXR0b25zIiwiZ2lmdENvbnRlbnQiLCJnaWZ0TGF5ZXIiLCJzaGFyZUNvbnRlbnQiLCJzaGFyZUxheWVyIiwiaGlkZGVuT3B0aW9ucyIsIm1lc3NhZ2UiLCJtZXNzYWdlQ2FydCIsIm1lc3NhZ2VIZWxwIiwibW9kZWxOdW1iZXIiLCJtb2RlbE51bWJlclRleHQiLCJwcmljZSIsInByb3BlcnRpZXNGb3JtIiwicmliYm9uU3BlY2lhbCIsInNoaXBwaW5nSW5mb3JtYXRpb24iLCJzaGlwcGluZ1RpbWUiLCJzaGlwcGluZ1RpbWVJbWFnZSIsInRvdGFscyIsIndlaWdodCIsInBhZ2UiLCJvcHRpb25zIiwiZXh0ZW5kIiwibW9iaWxlIiwid2lkdGgiLCJfYWRkQnV0dG9uU3RhdGUiLCIkdGFyZ2V0Iiwic3RhdGUiLCJ0aW1lciIsInNldFRpbWVvdXQiLCJyZW1vdmVDbGFzcyIsImFkZENsYXNzIiwiX3N0YXRlTWFuYWdlciIsIiRmb3JtIiwiZGlzYWJsZUJ1dHRvbnMiLCJzaG93Tm9Db21iaVNlbGVjdGVkTWVzc3NhZ2UiLCJhdHRySW1hZ2VzIiwibGVuZ3RoIiwiY29udGVudCIsImltYWdlcyIsInRyaWdnZXIiLCJqc2UiLCJsaWJzIiwidGhlbWUiLCJldmVudHMiLCJTTElERVNfVVBEQVRFIiwiZWFjaCIsImkiLCJ2IiwiJGVsZW1lbnQiLCJwYXJlbnQiLCJmaW5kIiwic2VsZWN0b3IiLCJ2YWx1ZSIsInR5cGUiLCJoaWRlIiwic2hvdyIsImh0bWwiLCJhdHRyIiwia2V5IiwicmVwbGFjZVdpdGgiLCJlbXB0eSIsInRleHQiLCIkYnV0dG9ucyIsInN1Y2Nlc3MiLCJwcm9wIiwiJGVycm9yRmllbGQiLCJtZXNzYWdlTm9Db21iaVNlbGVjdGVkIiwidW5kZWZpbmVkIiwiU1RJQ0tZQk9YX0NPTlRFTlRfQ0hBTkdFIiwiX2FkZFRvU29tZXdoZXJlIiwidXJsIiwiJGJ1dHRvbiIsImNhbGxiYWNrIiwieGhyIiwicG9zdCIsImRvbmUiLCJyZXN1bHQiLCJzdWJzdHIiLCJsb2NhdGlvbiIsImhyZWYiLCJjb3JlIiwiY29uZmlnIiwiZ2V0IiwiQ0FSVF9VUERBVEUiLCJtb2RhbCIsImluZm8iLCJ0aXRsZSIsIm1zZyIsImlnbm9yZSIsImZhaWwiLCJhbHdheXMiLCJob29rcyIsImV4ZWN1dGUiLCJrZXlzIiwic2hvcCIsImNhcnQiLCJhZGQiLCJ0aGVuIiwiY2F0Y2giLCJfc3VibWl0SGFuZGxlciIsImUiLCJwcmV2ZW50RGVmYXVsdCIsIiRzZWxmIiwiaXMiLCJjbG9zZXN0IiwiY3VzdG9taXplciIsImhhc0NsYXNzIiwicHJvcGVydGllcyIsInRhcmdldCIsImZvcm1kYXRhIiwiZm9ybSIsImdldERhdGEiLCJpc1Byb2R1Y3RJbmZvIiwiYWJvcnQiLCJjbGVhclRpbWVvdXQiLCJldmVudCIsIkFERF9DVVNUT01JWkVSX1dJU0hMSVNUIiwiQUREX0NVU1RPTUlaRVJfQ0FSVCIsIm9mZiIsInN1Ym1pdCIsImRlZmVycmVkIiwiRGVmZXJyZWQiLCJjdXN0b21pemVyUmFuZG9tIiwiX2tleXVwSGFuZGxlciIsImNhbGwiLCJiaW5kIiwiX2FkZFRvQ2FydFRocm9iYmVySGFuZGxlciIsIiRidG4iLCIkYnRuRmFrZSIsImZvcm1SZWFkeSIsInZhbCIsInByZXBlbmQiLCJfY2FydERyb3Bkb3duT3BlbkhhbmRsZXIiLCJmYWtlT3JpZ0xhYmVsIiwicHJvZHVjdENvdW50IiwidGV4dFBocmFzZXMiLCJKU09OIiwicGFyc2UiLCJjb25zb2xlIiwibG9nIiwicGFyc2VJbnQiLCJyZW1vdmUiLCJpbml0IiwiJGZvcm1zIiwib24iLCJub3QiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7QUFVQTs7Ozs7O0FBTUFBLE9BQU9DLE9BQVAsQ0FBZUMsTUFBZixDQUNJLGNBREosRUFHSSxDQUNJLE9BREosRUFFSSxNQUZKLEVBR0ksS0FISixFQUlJRixPQUFPRyxNQUFQLEdBQWdCLGNBSnBCLEVBS0lILE9BQU9HLE1BQVAsR0FBZ0IsMEJBTHBCLEVBTUlILE9BQU9HLE1BQVAsR0FBZ0IsYUFOcEIsQ0FISixFQVlJLFVBQVVDLElBQVYsRUFBZ0I7O0FBRVo7O0FBRVI7O0FBRVEsUUFBSUMsUUFBUUMsRUFBRSxJQUFGLENBQVo7QUFBQSxRQUNJQyxRQUFRRCxFQUFFLE1BQUYsQ0FEWjtBQUFBLFFBRUlFLFVBQVVGLEVBQUVHLE1BQUYsQ0FGZDtBQUFBLFFBR0lDLE9BQU8sS0FIWDtBQUFBLFFBSUlDLE9BQU8sSUFKWDtBQUFBLFFBS0lDLFVBQVUsQ0FMZDtBQUFBLFFBTUlDLFdBQVc7QUFDUDtBQUNBQyxvQkFBWSw2QkFGTDtBQUdQO0FBQ0FDLDhCQUFzQixzQkFKZjtBQUtQO0FBQ0FDLGtCQUFVLHlCQU5IO0FBT1A7QUFDQUMscUJBQWEsMEJBUk47QUFTUDtBQUNBQyx1QkFBZSxvQkFWUjtBQVdQO0FBQ0FDLDBCQUFrQixLQVpYO0FBYVA7QUFDQUMsa0JBQVUscUJBZEg7QUFlUDtBQUNBQyxxQkFBYSxxQkFoQk47QUFpQlA7QUFDQUMseUJBQWlCLGVBbEJW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QUFDSCxLQTFCRDs7QUE0QkE7QUFDQSxXQUFPMUcsTUFBUDtBQUNILENBaGZMIiwiZmlsZSI6IndpZGdldHMvY2FydF9oYW5kbGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiBjYXJ0X2hhbmRsZXIuanMgMjAxOS0wNi0yMFxuIEdhbWJpbyBHbWJIXG4gaHR0cDovL3d3dy5nYW1iaW8uZGVcbiBDb3B5cmlnaHQgKGMpIDIwMTkgR2FtYmlvIEdtYkhcbiBSZWxlYXNlZCB1bmRlciB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKFZlcnNpb24gMilcbiBbaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAuaHRtbF1cbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbi8qKlxuICogQ29tcG9uZW50IGZvciBoYW5kbGluZyB0aGUgYWRkIHRvIGNhcnQgYW5kIHdpc2hsaXN0IGZlYXR1cmVzXG4gKiBhdCB0aGUgcHJvZHVjdCBkZXRhaWxzIGFuZCB0aGUgY2F0ZWdvcnkgbGlzdGluZyBwYWdlcy4gSXQgY2FyZXNcbiAqIGZvciBhdHRyaWJ1dGVzLCBwcm9wZXJ0aWVzLCBxdWFudGl0eSBhbmQgYWxsIG90aGVyXG4gKiByZWxldmFudCBkYXRhIGZvciBhZGRpbmcgYW4gaXRlbSB0byB0aGUgYmFza2V0IG9yIHdpc2hsaXN0XG4gKi9cbmdhbWJpby53aWRnZXRzLm1vZHVsZShcbiAgICAnY2FydF9oYW5kbGVyJyxcblxuICAgIFtcbiAgICAgICAgJ2hvb2tzJyxcbiAgICAgICAgJ2Zvcm0nLFxuICAgICAgICAneGhyJyxcbiAgICAgICAgZ2FtYmlvLnNvdXJjZSArICcvbGlicy9ldmVudHMnLFxuICAgICAgICBnYW1iaW8uc291cmNlICsgJy9saWJzL21vZGFsLmV4dC1tYWduaWZpYycsXG4gICAgICAgIGdhbWJpby5zb3VyY2UgKyAnL2xpYnMvbW9kYWwnXG4gICAgXSxcblxuICAgIGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4vLyAjIyMjIyMjIyMjIFZBUklBQkxFIElOSVRJQUxJWkFUSU9OICMjIyMjIyMjIyNcblxuICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpLFxuICAgICAgICAgICAgJGJvZHkgPSAkKCdib2R5JyksXG4gICAgICAgICAgICAkd2luZG93ID0gJCh3aW5kb3cpLFxuICAgICAgICAgICAgYnVzeSA9IGZhbHNlLFxuICAgICAgICAgICAgYWpheCA9IG51bGwsXG4gICAgICAgICAgICB0aW1lb3V0ID0gMCxcbiAgICAgICAgICAgIGRlZmF1bHRzID0ge1xuICAgICAgICAgICAgICAgIC8vIEFKQVggXCJhZGQgdG8gY2FydFwiIFVSTFxuICAgICAgICAgICAgICAgIGFkZENhcnRVcmw6ICdzaG9wLnBocD9kbz1DYXJ0L0J1eVByb2R1Y3QnLFxuICAgICAgICAgICAgICAgIC8vIEFKQVggXCJhZGQgdG8gY2FydFwiIFVSTCBmb3IgY3VzdG9taXplciBwcm9kdWN0c1xuICAgICAgICAgICAgICAgIGFkZENhcnRDdXN0b21pemVyVXJsOiAnc2hvcC5waHA/ZG89Q2FydC9BZGQnLFxuICAgICAgICAgICAgICAgIC8vIEFKQVggVVJMIHRvIHBlcmZvcm0gYSB2YWx1ZSBjaGVja1xuICAgICAgICAgICAgICAgIGNoZWNrVXJsOiAnc2hvcC5waHA/ZG89Q2hlY2tTdGF0dXMnLFxuICAgICAgICAgICAgICAgIC8vIEFKQVggVVJMIHRvIHBlcmZvcm0gdGhlIGFkZCB0byB3aXNobGlzdFxuICAgICAgICAgICAgICAgIHdpc2hsaXN0VXJsOiAnc2hvcC5waHA/ZG89V2lzaExpc3QvQWRkJyxcbiAgICAgICAgICAgICAgICAvLyBTdWJtaXQgVVJMIGZvciBwcmljZSBvZmZlciBidXR0b25cbiAgICAgICAgICAgICAgICBwcmljZU9mZmVyVXJsOiAnZ21fcHJpY2Vfb2ZmZXIucGhwJyxcbiAgICAgICAgICAgICAgICAvLyBTdWJtaXQgbWV0aG9kIGZvciBwcmljZSBvZmZlclxuICAgICAgICAgICAgICAgIHByaWNlT2ZmZXJNZXRob2Q6ICdnZXQnLFxuICAgICAgICAgICAgICAgIC8vIFNlbGVjdG9yIGZvciB0aGUgY2FydCBkcm9wZG93blxuICAgICAgICAgICAgICAgIGRyb3Bkb3duOiAnI2hlYWRfc2hvcHBpbmdfY2FydCcsXG4gICAgICAgICAgICAgICAgLy8gXCJBZGQgdG8gY2FydFwiIGJ1dHRvbnMgc2VsZWN0b3JzXG4gICAgICAgICAgICAgICAgY2FydEJ1dHRvbnM6ICcuanMtYnRuLWFkZC10by1jYXJ0JyxcbiAgICAgICAgICAgICAgICAvLyBcIldpc2hsaXN0XCIgYnV0dG9ucyBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICB3aXNobGlzdEJ1dHRvbnM6ICcuYnRuLXdpc2hsaXN0JyxcbiAgICAgICAgICAgICAgICAvLyBcIlByaWNlIG9mZmVyXCIgYnV0dG9ucyBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICBwcmljZU9mZmVyQnV0dG9uczogJy5idG4tcHJpY2Utb2ZmZXInLFxuICAgICAgICAgICAgICAgIC8vIFNlbGVjdG9yIGZvciB0aGUgYXR0cmlidXRlIGZpZWxkc1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6ICcuanMtY2FsY3VsYXRlJyxcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3RvciBmb3IgdGhlIHF1YW50aXR5XG4gICAgICAgICAgICAgICAgcXVhbnRpdHk6ICcuanMtY2FsY3VsYXRlLXF0eScsXG4gICAgICAgICAgICAgICAgLy8gVVJMIHdoZXJlIHRvIGdldCB0aGUgdGVtcGxhdGUgZm9yIHRoZSBkcm9wZG93blxuICAgICAgICAgICAgICAgIHRwbDogbnVsbCxcbiAgICAgICAgICAgICAgICAvLyBTaG93IGF0dHJpYnV0ZSBpbWFnZXMgaW4gcHJvZHVjdCBpbWFnZXMgc3dpcGVyIChpZiBwb3NzaWJsZSlcbiAgICAgICAgICAgICAgICAvLyAtLSB0aGlzIGZlYXR1cmUgaXMgbm90IHN1cHBvcnRlZCB5ZXQgLS1cbiAgICAgICAgICAgICAgICBhdHRyaWJ1dEltYWdlc1N3aXBlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgLy8gVHJpZ2dlciB0aGUgYXR0cmlidXRlIGltYWdlcyB0byB0aGlzIHNlbGVjdG9yc1xuICAgICAgICAgICAgICAgIHRyaWdnZXJBdHRySW1hZ2VzVG86ICcjcHJvZHVjdF9pbWFnZV9zd2lwZXIsICNwcm9kdWN0X3RodW1ibmFpbF9zd2lwZXIsICdcbiAgICAgICAgICAgICAgICAgICAgKyAnI3Byb2R1Y3RfdGh1bWJuYWlsX3N3aXBlcl9tb2JpbGUnLFxuICAgICAgICAgICAgICAgIC8vIENsYXNzIHRoYXQgZ2V0cyBhZGRlZCB0byB0aGUgYnV0dG9uIG9uIHByb2Nlc3NpbmdcbiAgICAgICAgICAgICAgICBwcm9jZXNzaW5nQ2xhc3M6ICdsb2FkaW5nJyxcbiAgICAgICAgICAgICAgICAvLyBEdXJhdGlvbiBmb3IgdGhhdCB0aGUgc3VjY2VzcyBvciBmYWlsIGNsYXNzIGdldHMgYWRkZWQgdG8gdGhlIGJ1dHRvblxuICAgICAgICAgICAgICAgIHByb2Nlc3NpbmdEdXJhdGlvbjogMjAwMCxcbiAgICAgICAgICAgICAgICAvLyBBSkFYIHJlc3BvbnNlIGNvbnRlbnQgc2VsZWN0b3JzXG4gICAgICAgICAgICAgICAgc2VsZWN0b3JNYXBwaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUltYWdlczogJy5hdHRyaWJ1dGUtaW1hZ2VzJyxcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uczogJy5zaG9wcGluZy1jYXJ0LWJ1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgIGdpZnRDb250ZW50OiAnLmdpZnQtY2FydC1jb250ZW50LXdyYXBwZXInLFxuICAgICAgICAgICAgICAgICAgICBnaWZ0TGF5ZXI6ICcuZ2lmdC1jYXJ0LWxheWVyJyxcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVDb250ZW50OiAnLnNoYXJlLWNhcnQtY29udGVudC13cmFwcGVyJyxcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVMYXllcjogJy5zaGFyZS1jYXJ0LWxheWVyJyxcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuT3B0aW9uczogJyNjYXJ0X3F1YW50aXR5IC5oaWRkZW4tb3B0aW9ucycsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICcuZ2xvYmFsLWVycm9yLW1lc3NhZ2VzJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNhcnQ6ICcuY2FydC1lcnJvci1tc2cnLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlSGVscDogJy5oZWxwLWJsb2NrJyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxOdW1iZXI6ICcubW9kZWwtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxOdW1iZXJUZXh0OiAnLm1vZGVsLW51bWJlci10ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgcHJpY2U6ICcuY3VycmVudC1wcmljZS1jb250YWluZXInLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzRm9ybTogJy5wcm9wZXJ0aWVzLXNlbGVjdGlvbi1mb3JtJyxcbiAgICAgICAgICAgICAgICAgICAgcXVhbnRpdHk6ICcucHJvZHVjdHMtcXVhbnRpdHktdmFsdWUnLFxuICAgICAgICAgICAgICAgICAgICByaWJib25TcGVjaWFsOiAnLnJpYmJvbi1zcGVjaWFsJyxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdJbmZvcm1hdGlvbjogJyNzaGlwcGluZy1pbmZvcm1hdGlvbi1sYXllcicsXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nVGltZTogJy5wcm9kdWN0cy1zaGlwcGluZy10aW1lLXZhbHVlJyxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdUaW1lSW1hZ2U6ICcuaW1nLXNoaXBwaW5nLXRpbWUgaW1nJyxcbiAgICAgICAgICAgICAgICAgICAgdG90YWxzOiAnI2NhcnRfcXVhbnRpdHkgLnRvdGFsLWJveCcsXG4gICAgICAgICAgICAgICAgICAgIHdlaWdodDogJy5wcm9kdWN0cy1kZXRhaWxzLXdlaWdodC1jb250YWluZXIgc3BhbidcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBhZ2U6ICdwcm9kdWN0LWxpc3RpbmcnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHRydWUsIHt9LCBkZWZhdWx0cywgZGF0YSksXG4gICAgICAgICAgICBtb2R1bGUgPSB7fSxcbiAgICAgICAgICAgIG1vYmlsZSA9ICQod2luZG93KS53aWR0aCgpIDw9IDc2NztcblxuXG4vLyAjIyMjIyMjIyMjIEhFTFBFUiBGVU5DVElPTlMgIyMjIyMjIyMjI1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCB1cGRhdGVzIHRoZSBidXR0b25cbiAgICAgICAgICogc3RhdGUgd2l0aCBhbiBlcnJvciBvciBzdWNjZXNzIGNsYXNzIGZvclxuICAgICAgICAgKiBhIHNwZWNpZmllZCBkdXJhdGlvblxuICAgICAgICAgKiBAcGFyYW0gICB7b2JqZWN0fSAgICAgICAgJHRhcmdldCAgICAgICAgIGpRdWVyeSBzZWxlY3Rpb24gb2YgdGhlIHRhcmdldCBidXR0b25cbiAgICAgICAgICogQHBhcmFtICAge3N0cmluZ30gICAgICAgIHN0YXRlICAgICAgICAgICBUaGUgc3RhdGUgc3RyaW5nIHRoYXQgZ2V0cyBhZGRlZCB0byB0aGUgbG9hZGluZyBjbGFzc1xuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9hZGRCdXR0b25TdGF0ZSA9IGZ1bmN0aW9uICgkdGFyZ2V0LCBzdGF0ZSkge1xuICAgICAgICAgICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgJHRhcmdldC5yZW1vdmVDbGFzcyhvcHRpb25zLnByb2Nlc3NpbmdDbGFzcyArICcgJyArIG9wdGlvbnMucHJvY2Vzc2luZ0NsYXNzICsgc3RhdGUpO1xuICAgICAgICAgICAgfSwgb3B0aW9ucy5wcm9jZXNzaW5nRHVyYXRpb24pO1xuXG4gICAgICAgICAgICAkdGFyZ2V0XG4gICAgICAgICAgICAgICAgLmRhdGEoJ3RpbWVyJywgdGltZXIpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKG9wdGlvbnMucHJvY2Vzc2luZ0NsYXNzICsgc3RhdGUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gc2V0IHRoZSBtZXNzYWdlcyBhbmQgdGhlXG4gICAgICAgICAqIGJ1dHRvbiBzdGF0ZS5cbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgIGRhdGEgICAgICAgICAgICAgICAgUmVzdWx0IGZvcm0gdGhlIGFqYXggcmVxdWVzdFxuICAgICAgICAgKiBAcGFyYW0gICAgICAge29iamVjdH0gICAgJGZvcm0gICAgICAgICAgICAgICBqUXVlcnkgc2VsZWNpb24gb2YgdGhlIGZvcm1cbiAgICAgICAgICogQHBhcmFtICAgICAgIHtib29sZWFufSAgIGRpc2FibGVCdXR0b25zICAgICAgSWYgdHJ1ZSwgdGhlIGJ1dHRvbiBzdGF0ZSBnZXRzIHNldCB0byAoaW4pYWN0aXZlXG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7Ym9vbGVhbn0gICBzaG93Tm9Db21iaU1lc3NzYWdlIElmIHRydWUsIHRoZSBlcnJvciBtZXNzYWdlIGZvciBtaXNzaW5nIHByb3BlcnR5IGNvbWJpbmF0aW9uIHNlbGVjdGlvbiB3aWxsIGJlIGRpc3BsYXllZFxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9zdGF0ZU1hbmFnZXIgPSBmdW5jdGlvbiAoZGF0YSwgJGZvcm0sIGRpc2FibGVCdXR0b25zLCBzaG93Tm9Db21iaVNlbGVjdGVkTWVzc3NhZ2UpIHtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBhdHRyaWJ1dGUgaW1hZ2VzIGZyb20gdGhlIGNvbW1vbiBjb250ZW50XG4gICAgICAgICAgICAvLyBzbyB0aGF0IGl0IGRvZXNuJ3QgZ2V0IHJlbmRlcmVkIGFueW1vcmUuIFRoZW4gdHJpZ2dlclxuICAgICAgICAgICAgLy8gYW4gZXZlbnQgdG8gdGhlIGdpdmVuIHNlbGVjdG9ycyBhbmQgZGVsaXZlciB0aGVcbiAgICAgICAgICAgIC8vIGF0dHJJbWFnZXMgb2JqZWN0XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hdHRyaWJ1dEltYWdlc1N3aXBlciAmJiBkYXRhLmF0dHJJbWFnZXMgJiYgZGF0YS5hdHRySW1hZ2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBkYXRhLmNvbnRlbnQuaW1hZ2VzO1xuICAgICAgICAgICAgICAgICQob3B0aW9ucy50cmlnZ2VyQXR0ckltYWdlc1RvKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcihqc2UubGlicy50aGVtZS5ldmVudHMuU0xJREVTX1VQREFURSgpLCB7YXR0cmlidXRlczogZGF0YS5hdHRySW1hZ2VzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNldCB0aGUgbWVzc2FnZXMgZ2l2ZW4gaW5zaWRlIHRoZSBkYXRhLmNvbnRlbnQgb2JqZWN0XG4gICAgICAgICAgICAkLmVhY2goZGF0YS5jb250ZW50LCBmdW5jdGlvbiAoaSwgdikge1xuICAgICAgICAgICAgICAgIHZhciAkZWxlbWVudCA9ICRmb3JtLnBhcmVudCgpLmZpbmQob3B0aW9ucy5zZWxlY3Rvck1hcHBpbmdbdi5zZWxlY3Rvcl0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCghc2hvd05vQ29tYmlTZWxlY3RlZE1lc3NzYWdlIHx8IHYudmFsdWUgPT09ICcnKSAmJiBpID09PSAnbWVzc2FnZU5vQ29tYmlTZWxlY3RlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc3dpdGNoICh2LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaGlkZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodi52YWx1ZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5odG1sKHYudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2F0dHJpYnV0ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5hdHRyKHYua2V5LCB2LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyZXBsYWNlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQucmVwbGFjZVdpdGgodi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnaGlkZGVuJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVtcHR5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtZW50LnRleHQodi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gRGlzLSAvIEVuYWJsZSB0aGUgYnV0dG9uc1xuICAgICAgICAgICAgaWYgKGRpc2FibGVCdXR0b25zKSB7XG4gICAgICAgICAgICAgICAgdmFyICRidXR0b25zID0gJGZvcm0uZmluZChvcHRpb25zLmNhcnRCdXR0b25zKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICRidXR0b25zLnJlbW92ZUNsYXNzKCdpbmFjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAkYnV0dG9ucy5yZW1vdmVDbGFzcygnYnRuLWluYWN0aXZlJyk7XG5cdCAgICAgICAgICAgICAgICAkYnV0dG9ucy5wcm9wKFwiZGlzYWJsZWRcIiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICRidXR0b25zLmFkZENsYXNzKCdpbmFjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAkYnV0dG9ucy5hZGRDbGFzcygnYnRuLWluYWN0aXZlJyk7XG5cdCAgICAgICAgICAgICAgICAkYnV0dG9ucy5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZGF0YS5jb250ZW50Lm1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgJGVycm9yRmllbGQgPSAkZm9ybS5maW5kKG9wdGlvbnMuc2VsZWN0b3JNYXBwaW5nW2RhdGEuY29udGVudC5tZXNzYWdlLnNlbGVjdG9yXSk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuY29udGVudC5tZXNzYWdlLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICRlcnJvckZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2hpZGRlbicpXG4gICAgICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICRlcnJvckZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2hpZGRlbicpXG4gICAgICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaG93Tm9Db21iaVNlbGVjdGVkTWVzc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIGRhdGEuY29udGVudC5tZXNzYWdlTm9Db21iaVNlbGVjdGVkICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIGRhdGEuY29udGVudC5tZXNzYWdlTm9Db21iaVNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5jb250ZW50Lm1lc3NhZ2VOb0NvbWJpU2VsZWN0ZWQudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZXJyb3JGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2hpZGRlbicpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlcnJvckZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnaGlkZGVuJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHdpbmRvdy50cmlnZ2VyKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TVElDS1lCT1hfQ09OVEVOVF9DSEFOR0UoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhlbHBlciBmdW5jdGlvbiB0byBzZW5kIHRoZSBhamF4XG4gICAgICAgICAqIE9uIHN1Y2Nlc3MgcmVkaXJlY3QgdG8gYSBnaXZlbiB1cmwsIG9wZW4gYSBsYXllciB3aXRoXG4gICAgICAgICAqIGEgbWVzc2FnZSBvciBhZGQgdGhlIGl0ZW0gdG8gdGhlIGNhcnQtZHJvcGRvd24gZGlyZWN0bHlcbiAgICAgICAgICogKGJ5IHRyaWdnZXJpbmcgYW4gZXZlbnQgdG8gdGhlIGJvZHkpXG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7b2JqZWN0fSAgICAgIGRhdGEgICAgICBGb3JtIGRhdGFcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgICAgJGZvcm0gICAgIFRoZSBmb3JtIHRvIGZpbGxcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtzdHJpbmd9ICAgICAgdXJsICAgICAgIFRoZSBVUkwgZm9yIHRoZSBBSkFYIHJlcXVlc3RcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfYWRkVG9Tb21ld2hlcmUgPSBmdW5jdGlvbiAoZGF0YSwgJGZvcm0sIHVybCwgJGJ1dHRvbikge1xuICAgICAgICAgICAgZnVuY3Rpb24gY2FsbGJhY2soKSB7XG4gICAgICAgICAgICAgICAganNlLmxpYnMueGhyLnBvc3Qoe3VybDogdXJsLCBkYXRhOiBkYXRhfSwgdHJ1ZSkuZG9uZShmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaWxsIHRoZSBwYWdlIHdpdGggdGhlIHJlc3VsdCBmcm9tIHRoZSBhamF4XG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RhdGVNYW5hZ2VyKHJlc3VsdCwgJGZvcm0sIGZhbHNlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIEFKQVggd2FzIHN1Y2Nlc3NmdWwgZXhlY3V0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYSBjdXN0b20gZnVuY3Rpb25hbGl0eVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChyZXN1bHQudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd1cmwnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC51cmwuc3Vic3RyKDAsIDQpICE9PSAnaHR0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbi5ocmVmID0ganNlLmNvcmUuY29uZmlnLmdldCgnYXBwVXJsJykgKyAnLycgKyByZXN1bHQudXJsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gcmVzdWx0LnVybDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Ryb3Bkb3duJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRib2R5LnRyaWdnZXIoanNlLmxpYnMudGhlbWUuZXZlbnRzLkNBUlRfVVBEQVRFKCksIFt0cnVlXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGF5ZXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNlLmxpYnMudGhlbWUubW9kYWwuaW5mbyh7dGl0bGU6IHJlc3VsdC50aXRsZSwgY29udGVudDogcmVzdWx0Lm1zZ30pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGlnbm9yZSkge1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF9hZGRCdXR0b25TdGF0ZSgkYnV0dG9uLCAnLXN1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICB9KS5mYWlsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX2FkZEJ1dHRvblN0YXRlKCRidXR0b24sICctZmFpbCcpO1xuICAgICAgICAgICAgICAgIH0pLmFsd2F5cyhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBidXN5IGZsYWcgdG8gYmUgYWJsZSB0byBwZXJmb3JtXG4gICAgICAgICAgICAgICAgICAgIC8vIGZ1cnRoZXIgQUpBWCByZXF1ZXN0c1xuICAgICAgICAgICAgICAgICAgICBidXN5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghYnVzeSkge1xuICAgICAgICAgICAgICAgIC8vIG9ubHkgZXhlY3V0ZSB0aGUgYWpheFxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHBlbmRpbmcgYWpheCBjYWxsXG4gICAgICAgICAgICAgICAgYnVzeSA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBqc2UubGlicy5ob29rcy5leGVjdXRlKGpzZS5saWJzLmhvb2tzLmtleXMuc2hvcC5jYXJ0LmFkZCwgZGF0YSwgNTAwKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihjYWxsYmFjaylcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9O1xuXG5cbi8vICMjIyMjIyMjIyMgRVZFTlQgSEFORExFUiAjIyMjIyMjIyMjXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZXIgZm9yIHRoZSBzdWJtaXQgZm9ybSAvIGNsaWNrXG4gICAgICAgICAqIG9uIFwiYWRkIHRvIGNhcnRcIiAmIFwid2lzaGxpc3RcIiBidXR0b24uXG4gICAgICAgICAqIEl0IHBlcmZvcm1zIGEgY2hlY2sgb24gdGhlIGF2YWlsYWJpbGl0eVxuICAgICAgICAgKiBvZiB0aGUgY29tYmluYXRpb24gYW5kIHF1YW50aXR5LiBJZlxuICAgICAgICAgKiBzdWNjZXNzZnVsIGl0IHBlcmZvcm1zIHRoZSBhZGQgdG8gY2FydFxuICAgICAgICAgKiBvciB3aXNobGlzdCBhY3Rpb24sIGlmIGl0J3Mgbm90IGFcbiAgICAgICAgICogXCJjaGVja1wiIGNhbGxcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgIGUgICAgICBqUXVlcnkgZXZlbnQgb2JqZWN0XG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3N1Ym1pdEhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKGUpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciAkc2VsZiA9ICQodGhpcyksXG4gICAgICAgICAgICAgICAgJGZvcm0gPSAoJHNlbGYuaXMoJ2Zvcm0nKSkgPyAkc2VsZiA6ICRzZWxmLmNsb3Nlc3QoJ2Zvcm0nKSxcbiAgICAgICAgICAgICAgICBjdXN0b21pemVyID0gJGZvcm0uaGFzQ2xhc3MoJ2N1c3RvbWl6ZXInKSxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0gISEkZm9ybS5maW5kKCcucHJvcGVydGllcy1zZWxlY3Rpb24tZm9ybScpLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBtb2R1bGUgPSBwcm9wZXJ0aWVzID8gJycgOiAnL0F0dHJpYnV0ZXMnLFxuICAgICAgICAgICAgICAgIHNob3dOb0NvbWJpU2VsZWN0ZWRNZXNzc2FnZSA9IGUgJiYgZS5kYXRhICYmIGUuZGF0YS50YXJnZXQgJiYgZS5kYXRhLnRhcmdldCAhPT0gJ2NoZWNrJztcblxuICAgICAgICAgICAgaWYgKCRmb3JtLmxlbmd0aCkge1xuXG4gICAgICAgICAgICAgICAgLy8gU2hvdyBwcm9wZXJ0aWVzIG92ZXJsYXlcbiAgICAgICAgICAgICAgICAvLyB0byBkaXNhYmxlIHVzZXIgaW50ZXJhY3Rpb25cbiAgICAgICAgICAgICAgICAvLyBiZWZvcmUgbWFya3VwIHJlcGxhY2VcbiAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgICAgICAkdGhpcy5hZGRDbGFzcygnbG9hZGluZycpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBmb3JtZGF0YSA9IGpzZS5saWJzLmZvcm0uZ2V0RGF0YSgkZm9ybSwgbnVsbCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgZm9ybWRhdGEudGFyZ2V0ID0gKGUgJiYgZS5kYXRhICYmIGUuZGF0YS50YXJnZXQpID8gZS5kYXRhLnRhcmdldCA6ICdjaGVjayc7XG4gICAgICAgICAgICAgICAgZm9ybWRhdGEuaXNQcm9kdWN0SW5mbyA9ICRmb3JtLmhhc0NsYXNzKCdwcm9kdWN0LWluZm8nKSA/IDEgOiAwO1xuXG4gICAgICAgICAgICAgICAgLy8gQWJvcnQgcHJldmlvdXMgY2hlY2sgYWpheCBpZlxuICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIG9uZSBpbiBwcm9ncmVzc1xuICAgICAgICAgICAgICAgIGlmIChhamF4ICYmIGUpIHtcbiAgICAgICAgICAgICAgICAgICAgYWpheC5hYm9ydCgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFkZCBwcm9jZXNzaW5nLWNsYXNzIHRvIHRoZSBidXR0b25cbiAgICAgICAgICAgICAgICAvLyBhbmQgcmVtb3ZlIG9sZCB0aW1lZCBldmVudHNcbiAgICAgICAgICAgICAgICBpZiAoZm9ybWRhdGEudGFyZ2V0ICE9PSAnY2hlY2snKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0aW1lciA9ICRzZWxmLmRhdGEoJ3RpbWVyJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aW1lcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICRzZWxmXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3Mob3B0aW9ucy5wcm9jZXNzaW5nQ2xhc3MgKyAnLXN1Y2Nlc3MgJyArIG9wdGlvbnMucHJvY2Vzc2luZ0NsYXNzICsgJy1mYWlsJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhvcHRpb25zLnByb2Nlc3NpbmdDbGFzcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYWpheCA9IGpzZS5saWJzLnhoci5nZXQoe1xuICAgICAgICAgICAgICAgICAgICB1cmw6IG9wdGlvbnMuY2hlY2tVcmwgKyBtb2R1bGUsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGZvcm1kYXRhXG4gICAgICAgICAgICAgICAgfSwgdHJ1ZSkuZG9uZShmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIF9zdGF0ZU1hbmFnZXIocmVzdWx0LCAkZm9ybSwgdHJ1ZSwgc2hvd05vQ29tYmlTZWxlY3RlZE1lc3NzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgJHRoaXMucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldmVudCA9IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChmb3JtZGF0YS50YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd3aXNobGlzdCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGpzZS5saWJzLnRoZW1lLmV2ZW50cy5BRERfQ1VTVE9NSVpFUl9XSVNITElTVCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IG9wdGlvbnMud2lzaGxpc3RVcmw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2NhcnQnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBqc2UubGlicy50aGVtZS5ldmVudHMuQUREX0NVU1RPTUlaRVJfQ0FSVCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gb3B0aW9ucy5hZGRDYXJ0Q3VzdG9taXplclVybDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IG9wdGlvbnMuYWRkQ2FydFVybDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdwcmljZV9vZmZlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmb3JtLmF0dHIoJ2FjdGlvbicsIG9wdGlvbnMucHJpY2VPZmZlclVybCkuYXR0cignbWV0aG9kJywgb3B0aW9ucy5wcmljZU9mZmVyTWV0aG9kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZvcm0ub2ZmKCdzdWJtaXQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZvcm0uc3VibWl0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHdpbmRvdy50cmlnZ2VyKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TVElDS1lCT1hfQ09OVEVOVF9DSEFOR0UoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDI1MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVmZXJyZWQgPSAkLkRlZmVycmVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQuZG9uZShmdW5jdGlvbiAoY3VzdG9taXplclJhbmRvbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtZGF0YVtjdXN0b21pemVyUmFuZG9tXSA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hZGRUb1NvbWV3aGVyZShmb3JtZGF0YSwgJGZvcm0sIHVybCwgJHNlbGYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLmZhaWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWRkQnV0dG9uU3RhdGUoJHNlbGYsICctZmFpbCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRib2R5LnRyaWdnZXIoZXZlbnQsIFt7J2RlZmVycmVkJzogZGVmZXJyZWQsICdkYXRhc2V0JzogZm9ybWRhdGF9XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hZGRUb1NvbWV3aGVyZShmb3JtZGF0YSwgJGZvcm0sIHVybCwgJHNlbGYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB9KS5mYWlsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX2FkZEJ1dHRvblN0YXRlKCRzZWxmLCAnLWZhaWwnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogS2V5dXAgaGFuZGxlciBmb3IgcXVhbnRpdHkgaW5wdXQgZmllbGRcbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIGVcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfa2V5dXBIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblxuICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF9zdWJtaXRIYW5kbGVyLmNhbGwodGhpcywgZSlcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgMzAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRXZlbnQgaGFuZGxlciBmb3IgdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiwgdGhhdCBzaG93cyBvciBoaWRlcyB0aGUgdGhyb2JiZXIuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBfYWRkVG9DYXJ0VGhyb2JiZXJIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGNvbnN0ICRidG4gPSAkKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgJGJ0bkZha2UgPSAkdGhpcy5maW5kKFwiLmJ0bi1hZGQtdG8tY2FydC1mYWtlXCIpO1xuICAgICAgICAgICAgbGV0IGZvcm1SZWFkeSA9IHRydWU7XG5cbiAgICAgICAgICAgICQoXCIucHJvcGVydGllcy1zZWxlY3Rpb24tZm9ybSBzZWxlY3RcIikuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gJCh0aGlzKS52YWwoKTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbCB8fCB2YWwgPCAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1SZWFkeSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoZm9ybVJlYWR5KSB7XG4gICAgICAgICAgICAgICAgJGJ0bi5oaWRlKCk7XG4gICAgICAgICAgICAgICAgJGJ0bkZha2Uuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgLnByZXBlbmQoJzxzcGFuIGNsYXNzPVwidGhyb2JibGVyXCI+PC9zcGFuPicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYXJ0IGRyb3Bkb3duIG9iZW4gZXZlbnQgaGFuZGxlciBmb3IgdGhlIGJvZHkuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBfY2FydERyb3Bkb3duT3BlbkhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgY29uc3QgJGJ0biA9ICR0aGlzLmZpbmQoXCJbbmFtZT1idG4tYWRkLXRvLWNhcnRdXCIpO1xuICAgICAgICAgICAgY29uc3QgJGJ0bkZha2UgPSAkdGhpcy5maW5kKFwiLmJ0bi1hZGQtdG8tY2FydC1mYWtlXCIpO1xuICAgICAgICAgICAgY29uc3QgZmFrZU9yaWdMYWJlbCA9ICRidG5GYWtlLmh0bWwoKTtcbiAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RDb3VudCA9ICQoXCIuY2FydC1wcm9kdWN0cy1jb3VudFwiKS5odG1sKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHRleHRQaHJhc2VzID0gSlNPTi5wYXJzZSgkKCcjcHJvZHVjdC1kZXRhaWxzLXRleHQtcGhyYXNlcycpLmh0bWwoKSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0ZXh0UGhyYXNlc1sncHJvZHVjdHNJbkNhcnRTdWZmaXgnXSk7XG5cbiAgICAgICAgICAgICRidG5GYWtlLmh0bWwoXCI8aSBjbGFzcz1cXFwiZmEgZmEtY2hlY2tcXFwiPjwvaT4gXCIgKyBwYXJzZUludChwcm9kdWN0Q291bnQpXG4gICAgICAgICAgICAgICAgKyB0ZXh0UGhyYXNlc1sncHJvZHVjdHNJbkNhcnRTdWZmaXgnXSlcbiAgICAgICAgICAgICAgICAucHJvcChcImRpc2FibGVkXCIsIHRydWUpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKFwiYnRuLWJ1eS1jb21wbGV0ZVwiKTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgJGJ0bkZha2UuaHRtbChmYWtlT3JpZ0xhYmVsKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoXCJidG4tYnV5LWNvbXBsZXRlXCIpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLnByb3AoXCJkaXNhYmxlZFwiLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgJChcIi50aHJvYmJsZXJcIiwgJGJ0bikucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgJGJ0bi5zaG93KCk7XG4gICAgICAgICAgICB9LCA1MDAwKTtcbiAgICAgICAgICAgIFxuICAgICAgICB9O1xuXG5cbi8vICMjIyMjIyMjIyMgSU5JVElBTElaQVRJT04gIyMjIyMjIyMjI1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbml0IGZ1bmN0aW9uIG9mIHRoZSB3aWRnZXRcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqL1xuICAgICAgICBtb2R1bGUuaW5pdCA9IGZ1bmN0aW9uIChkb25lKSB7XG5cbiAgICAgICAgICAgIHZhciAkZm9ybXMgPSAkdGhpcy5maW5kKCdmb3JtJyk7XG5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnBhZ2UgPT09ICdwcm9kdWN0LWluZm8nKSB7XG4gICAgICAgICAgICAgICAgJGZvcm1zLmZpbmQoXCJbbmFtZT1idG4tYWRkLXRvLWNhcnRdXCIpLm9uKCdtb3VzZXVwJywgX2FkZFRvQ2FydFRocm9iYmVySGFuZGxlcik7XG4gICAgICAgICAgICAgICAgJChcImJvZHlcIikub24oJ0NBUlRfRFJPUERPV05fT1BFTicsIF9jYXJ0RHJvcGRvd25PcGVuSGFuZGxlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICRmb3Jtc1xuICAgICAgICAgICAgICAgIC5vbignc3VibWl0Jywgeyd0YXJnZXQnOiAnY2FydCd9LCBfc3VibWl0SGFuZGxlcilcbiAgICAgICAgICAgICAgICAub24oJ2NsaWNrJywgb3B0aW9ucy53aXNobGlzdEJ1dHRvbnMsIHsndGFyZ2V0JzogJ3dpc2hsaXN0J30sIF9zdWJtaXRIYW5kbGVyKVxuICAgICAgICAgICAgICAgIC5vbignY2xpY2snLCBvcHRpb25zLnByaWNlT2ZmZXJCdXR0b25zLCB7J3RhcmdldCc6ICdwcmljZV9vZmZlcid9LCBfc3VibWl0SGFuZGxlcilcbiAgICAgICAgICAgICAgICAub24oJ2NoYW5nZScsIG9wdGlvbnMuYXR0cmlidXRlcywgeyd0YXJnZXQnOiAnY2hlY2snfSwgX3N1Ym1pdEhhbmRsZXIpXG4gICAgICAgICAgICAgICAgLm9uKCdibHVyJywgb3B0aW9ucy5xdWFudGl0eSwgeyd0YXJnZXQnOiAnY2hlY2snfSwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgX3N1Ym1pdEhhbmRsZXIoZSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAub24oJ2tleXVwJywgb3B0aW9ucy5xdWFudGl0eSwgeyd0YXJnZXQnOiAnY2hlY2snfSwgX2tleXVwSGFuZGxlcik7XG5cbiAgICAgICAgICAgIC8vIEZhbGxiYWNrIGlmIHRoZSBiYWNrZW5kIHJlbmRlcnMgaW5jb3JyZWN0IGRhdGFcbiAgICAgICAgICAgIC8vIG9uIGluaXRpYWwgcGFnZSBjYWxsXG4gICAgICAgICAgICAkZm9ybXMubm90KCcubm8tc3RhdHVzLWNoZWNrJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3N1Ym1pdEhhbmRsZXIuY2FsbCgkKHRoaXMpKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJuIGRhdGEgdG8gd2lkZ2V0IGVuZ2luZVxuICAgICAgICByZXR1cm4gbW9kdWxlO1xuICAgIH0pO1xuIl19

Youez - 2016 - github.com/yon3zu
LinuXploit