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/admin/html/assets/javascript/engine/widgets/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/moncbefd/www.moneta.at/admin/html/assets/javascript/engine/widgets//filemanager.js
'use strict';

/* --------------------------------------------------------------
 filemanager.js 2017-11-23
 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]
 --------------------------------------------------------------
 */

/**
 * ## Filemanager Widget
 *
 * Creates an input field and a button in order to make it possible to upload files or to select already
 * uploaded files. This widget checks if the responsive filemanager is present, if it is, the responsive
 * filemanager will be used, else a fallback will be used, which is an input field of type 'file'.
 *
 * ### Options
 *
 * **Type | `data-filemanager-type` | String | Optional**
 *
 * Provide the allowed file upload type. Currently there are 3 options which are:
 *    * 'all' - All file types are allowed
 *    * 'videos' - Only video files are allowed
 *    * 'images' - Only images are allowed
 * If you don't provide any type, the filemanager will default to 'all'.
 *
 * **Content Directory | `data-filemanager-content-directory` | String | Required**
 *
 * Provide the directory which should be opened when the filemanager gets opened, e.g. 'media'.
 * You can also provide a path from the root of your shop e.g 'images/slider_images'.
 *
 * **Name | `data-filemanager-name` | String | Required**
 *
 * The name of the input field. It will be set as the HTML name attribute.
 *
 * **Previous File | `data-filemanager-previous-file` | String | Optional**
 *
 * Name of the previous file. The name will be used in order to auto fill the input field.
 *
 * **Page | `data-filemanager-page` | String | Optional**
 *
 * The name of the current page in snake case, for example: new_category or responsive_filemanager.
 * This option will be used in order to load custom configuration files for the responsive file manager like
 * responsive_filemanager.config.php. These custom configuration files will be available or should be created
 * in the 'page' directory of the responsive file manager.
 *
 * **Page Active | `data-filemanager-page-active` | Boolean | Required**
 *
 * This option is required in order to check whether the file manager module is active, and if the configuration
 * option from the file manager is set to active, for the current page. If the module is not active, or active
 * in general but not active for the current page, the fallback will be used, which is a standard input field.
 *
 * ### Example
 *
 * ```html
 * <div data-gx-widget="filemanager"
 *     data-filemanager-name="categories_icon" // Required
 *     data-filemanager-type="images" // Optional
 *     data-filemanager-content-directory="images/categories/icons" // Required
 *     data-filemanager-previous-file="filename.extension" // Optional
 *     data-filemanager-page="responsive_filemanager" // Optional
 *     data-filemanager-page-active="true"> // Required
 * </div>
 * ```
 *
 * @module Admin/Widgets/filemanager
 */
gx.widgets.module('filemanager', ['xhr', 'modal'],

/** @lends module:Widgets/filemanager */

function (data) {

    'use strict';

    // ------------------------------------------------------------------------
    // VARIABLE DEFINITION
    // ------------------------------------------------------------------------

    /**
     * Widget Reference
     *
     * @type {object}
     */

    var $this = $(this);

    /**
     * Default Widget Options
     *
     * @type {object}
     */
    var defaults = {};

    /**
     * Final Widget Options
     *
     * @type {object}
     */
    var options = $.extend(true, {}, defaults, data);

    /**
     * Module Object
     *
     * @type {object}
     */
    var module = {};

    /**
     * Id of the file manager input field.
     *
     * @type {string}
     */
    var fieldId = void 0;

    /**
     * Ajax request url fetch the file managers configuration settings.
     *
     * @type {string}
     */
    var fileManagerConfigurationUrl = jse.core.config.get('appUrl') + '/admin/admin.php?do=ResponsiveFileManagerModuleCenterModule/GetConfiguration';

    /**
     *  Cache key.
     *
     * @type {string}
     */
    var cacheKey = 'responsiveFileManager';

    // ------------------------------------------------------------------------
    // FUNCTIONS
    // ------------------------------------------------------------------------

    // ------------------------------------------------------------------------
    // FILE MANAGER CONFIGURATIONS
    // ------------------------------------------------------------------------
    /**
     * Returns the allowed file type as an integer, which is mapped
     * for the external Responsive Filemanager plugin. It will be used
     * as a GET parameter in the URL for the file manager.
     *
     * @returns {number} Flag integer value between 0 and 3.
     */
    var _getFMType = function _getFMType() {
        switch (options.type) {
            case 'images':
                return 1;
            case 'all':
                return 2;
            case 'videos':
                return 3;
            default:
                return 0;
        }
    };

    /**
     * File managers request url.
     *
     * @returns {string} Request url of file manager.
     */
    var _getFMUrl = function _getFMUrl() {
        // Language parameter used for the file manager
        var lang = jse.core.registry.get('languageId') === 2 ? 'de' : 'en_EN';

        // Don't use the popup mode if the file manager will be opened in a modal.
        var popUp = _isCompatibilityModeEnabled() ? 1 : '';

        return jse.core.config.get('appUrl') + '/' + 'ResponsiveFilemanager/filemanager/filemanager.php?type=' + _getFMType() + _getSubDirectoryQueryString() + '&field_id=' + fieldId + '&popup=' + popUp + '&relative_url=1&lang=' + lang + _getPageQueryString();
    };

    /**
     * Returns the 'sub_folder' query argument for the file manager request.
     *
     * @returns {string} Query parameter for file manager request to set the root directory.
     */
    var _getSubDirectoryQueryString = function _getSubDirectoryQueryString() {
        if (options.contentDirectory !== undefined) {
            return '&sub_folder=' + options.contentDirectory;
        }

        return '';
    };

    /**
     * Returns the 'page' query string for the file manager request.
     *
     * @returns {string} Query parameter for the file manager request to load a custom configuration file.
     */
    var _getPageQueryString = function _getPageQueryString() {
        if (options.page !== undefined) {
            return '&page=' + options.page;
        }

        return '';
    };

    /**
     * Generates a global unique identifier for each input that is generated by this widget.
     * This ID will be used in order to identify an input fields. With the help of this ID,
     * the widget knows, in which input field the file name of the chose file should be entered.
     *
     * @returns {string} Global unique identifier as string.
     */
    var guidGenerator = function guidGenerator() {
        var s4 = function s4() {
            return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
        };

        return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
    };

    // ------------------------------------------------------------------------
    // CREATING THE FILE MANAGER
    // ------------------------------------------------------------------------
    /**
     * Factory, which creates either the responsive file manager or the fallback,
     * which is a standard input field of the type 'file'.
     *
     * @type {{responsive: (function()), fallback: (function())}}
     */
    var factory = {
        responsive: function responsive() {
            var $uploadIcon = $('<i/>', {
                'class': 'fa fa-upload',
                'aria-hidden': true
            });

            var $removeIcon = $('<i/>', {
                'class': 'fa fa-remove',
                'aria-hidden': true
            });

            var $input = $('<input/>', {
                'type': 'text',
                'name': options.name,
                'id': fieldId,
                'class': 'form-control',
                'readonly': 'readonly'
            });

            // Auto fill the input field with the previous file name
            if (options.previousFile) {
                $input.val(options.previousFile);
            }

            var $uploadButton = $('<a/>', {
                'class': 'btn responsive-file-manager',
                'type': 'button',
                'html': $uploadIcon,
                'on': {
                    'click': function click() {
                        return _openFileManager();
                    }
                }
            });

            var $removeButton = $('<a/>', {
                'class': 'btn responsive-file-manager',
                'type': 'button',
                'html': $removeIcon,
                'on': {
                    'click': function click() {
                        return $input.val('');
                    }
                }
            });

            var $span = $('<span/>', {
                'class': 'input-group-btn'
            });

            var $container = $('<div/>', {
                'class': 'input-group responsive-file-manager'
            });

            $span.append($uploadButton);
            $span.append($removeButton);

            $container.append($input).append($span);
            $this.append($container);
        },

        fallback: function fallback() {
            var $input = $('<input/>', {
                'name': options.name,
                'type': 'file'
            });

            $this.append($input);
        }
    };

    /**
     /**
     * Creates the widget after the request the responsive file manager
     * request is being made. After the request, either the 'responsive'
     * widget is created or the fallback, depending on if the file manager
     * is available.
     *
     * @param done Done callback function for module.init.
     */
    var _createWidget = function _createWidget(done) {
        jse.libs.xhr.get({ url: fileManagerConfigurationUrl }).done(function (response) {
            return jse.core.registry.set(cacheKey, response.isInstalled ? 'responsive' : 'fallback');
        }).fail(function () {
            return jse.core.registry.set(cacheKey, 'fallback');
        }).always(function () {
            // Create the file manager or fallback.
            factory[jse.core.registry.get(cacheKey)]();
            done();
        });
    };

    /**
     * Creates the widget when the cache key changes from pending.
     * After the cache key changed to either the 'responsive' or 'fallback',
     * the according widget will be created, depending on if the file manager
     * is available.
     *
     * @param done Done callback function for module.init.
     */
    var _createWidgetWhenCacheKeyAvailable = function _createWidgetWhenCacheKeyAvailable(done) {
        var interval = setInterval(function () {
            if (jse.core.registry.get(cacheKey) !== 'pending') {
                clearInterval(interval);

                // Create the file manager or fallback.
                factory[jse.core.registry.get(cacheKey)]();
                done();
            }
        }, 100);
    };

    // ------------------------------------------------------------------------
    // OPENING THE FILE MANAGER
    // ------------------------------------------------------------------------
    /**
     * Opens the file manager in a new window popup.
     */
    var _openFMPopup = function _openFMPopup() {
        var w = 880;
        var h = 570;
        var l = Math.floor((screen.width - w) / 2);
        var t = Math.floor((screen.height - h) / 2);

        window.open(_getFMUrl(), 'ResponsiveFilemanager', "scrollbars=1,width=" + w + ",height=" + h + ",top=" + t + ",left=" + l);
    };

    /**
     * Opens the file manager in a bootstrap modal.
     */
    var _openFMModal = function _openFMModal() {

        // Use the fallback if bootstraps modal function is not available.
        if ($.fn.modal === undefined) {
            return _openFMPopup();
        }

        var iFrame = '<iframe src="' + _getFMUrl() + '" width="100%" height="550" frameborder="0"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass="responsive-filemanager"></iframe>';

        jse.libs.modal.showMessage('Filemanager', iFrame);
        _makeModalLarge();
    };

    /**
     * Makes the modal large by adding the modal-lg css class.
     */
    var _makeModalLarge = function _makeModalLarge() {
        $('.modal-dialog:last').addClass('modal-lg');
    };

    /**
     * Checks if compatibility mode is active.
     *
     * @returns {boolean} True on compatibility mode, false otherwise.
     */
    var _isCompatibilityModeEnabled = function _isCompatibilityModeEnabled() {
        return $('body.gx-compatibility').length !== 0;
    };

    /**
     * Opens the file manager in a modal, dialog or window with the priority in
     * the same order. If bootstrap is not available, the file
     * manager will be opened in a new window.
     */
    var _openFileManager = function _openFileManager() {
        if (_isCompatibilityModeEnabled()) {
            return _openFMPopup();
        }

        _openFMModal();
    };

    // ------------------------------------------------------------------------
    // INITIALIZATION
    // ------------------------------------------------------------------------

    /**
     * Initialize method of the widget, called by the engine.
     */
    module.init = function (done) {
        fieldId = guidGenerator();

        // Required option not provided
        if (options.contentDirectory === undefined || options.contentDirectory === '') {
            jse.core.debug.error('content-directory attribute was not provided for the "filemanager" widget.');
            return;
        }

        // Required option not provided
        if (options.name === undefined || options.name === '') {
            jse.core.debug.error('name attribute was not provided for the "filemanager" widget.');
            return;
        }

        // Required option not provided
        if (options.pageActive === undefined) {
            jse.core.debug.error('page-active attribute was not provided for the "filemanager" widget.');
            return;
        }

        // Module is not active at all or not active for the used page.
        if (!options.pageActive) {
            factory.fallback();
            done();
            return;
        }

        // No cache key available yet. Create the widget and set the cache key to 'fallback' or 'responsive'
        // after the responsive has arrived (done by the _createWidget function).
        if (jse.core.registry.get(cacheKey) === undefined) {
            jse.core.registry.set(cacheKey, 'pending');
            _createWidget(done);
            return;
        }

        // Cache key is on 'pending' which means we have to wait until the key changes (done by the _createWidget function).
        // Afterwards we can create the correct widget.
        if (jse.core.registry.get(cacheKey) === 'pending') {
            _createWidgetWhenCacheKeyAvailable(done);
            return;
        }

        // Build the fallback or responsive file manager.
        factory[jse.core.registry.get(cacheKey)]();
    };

    // Return data to module engine.
    return module;
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGVtYW5hZ2VyLmpzIl0sIm5hbWVzIjpbImd4Iiwid2lkZ2V0cyIsIm1vZHVsZSIsImRhdGEiLCIkdGhpcyIsIiQiLCJkZWZhdWx0cyIsIm9wdGlvbnMiLCJleHRlbmQiLCJmaWVsZElkIiwiZmlsZU1hbmFnZXJDb25maWd1cmF0aW9uVXJsIiwianNlIiwiY29yZSIsImNvbmZpZyIsImdldCIsImNhY2hlS2V5IiwiX2dldEZNVHlwZSIsInR5cGUiLCJfZ2V0Rk1VcmwiLCJsYW5nIiwicmVnaXN0cnkiLCJwb3BVcCIsIl9pc0NvbXBhdGliaWxpdHlNb2RlRW5hYmxlZCIsIl9nZXRTdWJEaXJlY3RvcnlRdWVyeVN0cmluZyIsIl9nZXRQYWdlUXVlcnlTdHJpbmciLCJjb250ZW50RGlyZWN0b3J5IiwidW5kZWZpbmVkIiwicGFnZSIsImd1aWRHZW5lcmF0b3IiLCJzNCIsIk1hdGgiLCJyYW5kb20iLCJ0b1N0cmluZyIsInN1YnN0cmluZyIsImZhY3RvcnkiLCJyZXNwb25zaXZlIiwiJHVwbG9hZEljb24iLCIkcmVtb3ZlSWNvbiIsIiRpbnB1dCIsIm5hbWUiLCJwcmV2aW91c0ZpbGUiLCJ2YWwiLCIkdXBsb2FkQnV0dG9uIiwiX29wZW5GaWxlTWFuYWdlciIsIiRyZW1vdmVCdXR0b24iLCIkc3BhbiIsIiRjb250YWluZXIiLCJhcHBlbmQiLCJmYWxsYmFjayIsIl9jcmVhdGVXaWRnZXQiLCJsaWJzIiwieGhyIiwidXJsIiwiZG9uZSIsInNldCIsInJlc3BvbnNlIiwiaXNJbnN0YWxsZWQiLCJmYWlsIiwiYWx3YXlzIiwiX2NyZWF0ZVdpZGdldFdoZW5DYWNoZUtleUF2YWlsYWJsZSIsImludGVydmFsIiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwiX29wZW5GTVBvcHVwIiwidyIsImgiLCJsIiwiZmxvb3IiLCJzY3JlZW4iLCJ3aWR0aCIsInQiLCJoZWlnaHQiLCJ3aW5kb3ciLCJvcGVuIiwiX29wZW5GTU1vZGFsIiwiZm4iLCJtb2RhbCIsImlGcmFtZSIsInNob3dNZXNzYWdlIiwiX21ha2VNb2RhbExhcmdlIiwiYWRkQ2xhc3MiLCJsZW5ndGgiLCJpbml0IiwiZGVidWciLCJlcnJvciIsInBhZ2VBY3RpdmUiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7QUFVQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBEQUEsR0FBR0MsT0FBSCxDQUFXQyxNQUFYLENBQ0ksYUFESixFQUdJLENBQUMsS0FBRCxFQUFRLE9BQVIsQ0FISjs7QUFLSTs7QUFFQSxVQUFVQyxJQUFWLEVBQWdCOztBQUVaOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7O0FBS0EsUUFBTUMsUUFBUUMsRUFBRSxJQUFGLENBQWQ7O0FBRUE7Ozs7O0FBS0EsUUFBTUMsV0FBVyxFQUFqQjs7QUFFQTs7Ozs7QUFLQSxRQUFNQyxVQUFVRixFQUFFRyxNQUFGLENBQVMsSUFBVCxFQUFlLEVBQWYsRUFBbUJGLFFBQW5CLEVBQTZCSCxJQUE3QixDQUFoQjs7QUFFQTs7Ozs7QUFLQSxRQUFNRCxTQUFTLEVBQWY7O0FBRUE7Ozs7O0FBS0EsUUFBSU8sZ0JBQUo7O0FBRUE7Ozs7O0FBS0EsUUFBTUMsOEJBQThCQyxJQUFJQyxJQUFKLENBQVNDLE1BQVQsQ0FBZ0JDLEdBQWhCLENBQW9CLFFBQXBCLElBQzlCLDhFQUROOztBQUdBOzs7OztBQUtBLFFBQU1DLFdBQVcsdUJBQWpCOztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQU9BLFFBQU1DLGFBQWEsU0FBYkEsVUFBYSxHQUFNO0FBQ3JCLGdCQUFRVCxRQUFRVSxJQUFoQjtBQUNJLGlCQUFLLFFBQUw7QUFDSSx1QkFBTyxDQUFQO0FBQ0osaUJBQUssS0FBTDtBQUNJLHVCQUFPLENBQVA7QUFDSixpQkFBSyxRQUFMO0FBQ0ksdUJBQU8sQ0FBUDtBQUNKO0FBQ0ksdUJBQU8sQ0FBUDtBQVJSO0FBVUgsS0FYRDs7QUFhQTs7Ozs7QUFLQSxRQUFN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QUFULENBQWVDLEtBQWYsQ0FBcUIsc0VBQXJCO0FBQ0E7QUFDSDs7QUFFRDtBQUNBLFlBQUksQ0FBQzdFLFFBQVE4RSxVQUFiLEVBQXlCO0FBQ3JCbkQsb0JBQVFjLFFBQVI7QUFDQUs7QUFDQTtBQUNIOztBQUVEO0FBQ0E7QUFDQSxZQUFJMUMsSUFBSUMsSUFBSixDQUFTUSxRQUFULENBQWtCTixHQUFsQixDQUFzQkMsUUFBdEIsTUFBb0NXLFNBQXhDLEVBQW1EO0FBQy9DZixnQkFBSUMsSUFBSixDQUFTUSxRQUFULENBQWtCa0MsR0FBbEIsQ0FBc0J2QyxRQUF0QixFQUFnQyxTQUFoQztBQUNBa0MsMEJBQWNJLElBQWQ7QUFDQTtBQUNIOztBQUVEO0FBQ0E7QUFDQSxZQUFJMUMsSUFBSUMsSUFBSixDQUFTUSxRQUFULENBQWtCTixHQUFsQixDQUFzQkMsUUFBdEIsTUFBb0MsU0FBeEMsRUFBbUQ7QUFDL0M0QywrQ0FBbUNOLElBQW5DO0FBQ0E7QUFDSDs7QUFFRDtBQUNBbkIsZ0JBQVF2QixJQUFJQyxJQUFKLENBQVNRLFFBQVQsQ0FBa0JOLEdBQWxCLENBQXNCQyxRQUF0QixDQUFSO0FBQ0gsS0E3Q0Q7O0FBK0NBO0FBQ0EsV0FBT2IsTUFBUDtBQUNILENBcFlMIiwiZmlsZSI6ImZpbGVtYW5hZ2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiBmaWxlbWFuYWdlci5qcyAyMDE3LTExLTIzXG4gR2FtYmlvIEdtYkhcbiBodHRwOi8vd3d3LmdhbWJpby5kZVxuIENvcHlyaWdodCAoYykgMjAxNyBHYW1iaW8gR21iSFxuIFJlbGVhc2VkIHVuZGVyIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoVmVyc2lvbiAyKVxuIFtodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC5odG1sXVxuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuLyoqXG4gKiAjIyBGaWxlbWFuYWdlciBXaWRnZXRcbiAqXG4gKiBDcmVhdGVzIGFuIGlucHV0IGZpZWxkIGFuZCBhIGJ1dHRvbiBpbiBvcmRlciB0byBtYWtlIGl0IHBvc3NpYmxlIHRvIHVwbG9hZCBmaWxlcyBvciB0byBzZWxlY3QgYWxyZWFkeVxuICogdXBsb2FkZWQgZmlsZXMuIFRoaXMgd2lkZ2V0IGNoZWNrcyBpZiB0aGUgcmVzcG9uc2l2ZSBmaWxlbWFuYWdlciBpcyBwcmVzZW50LCBpZiBpdCBpcywgdGhlIHJlc3BvbnNpdmVcbiAqIGZpbGVtYW5hZ2VyIHdpbGwgYmUgdXNlZCwgZWxzZSBhIGZhbGxiYWNrIHdpbGwgYmUgdXNlZCwgd2hpY2ggaXMgYW4gaW5wdXQgZmllbGQgb2YgdHlwZSAnZmlsZScuXG4gKlxuICogIyMjIE9wdGlvbnNcbiAqXG4gKiAqKlR5cGUgfCBgZGF0YS1maWxlbWFuYWdlci10eXBlYCB8IFN0cmluZyB8IE9wdGlvbmFsKipcbiAqXG4gKiBQcm92aWRlIHRoZSBhbGxvd2VkIGZpbGUgdXBsb2FkIHR5cGUuIEN1cnJlbnRseSB0aGVyZSBhcmUgMyBvcHRpb25zIHdoaWNoIGFyZTpcbiAqICAgICogJ2FsbCcgLSBBbGwgZmlsZSB0eXBlcyBhcmUgYWxsb3dlZFxuICogICAgKiAndmlkZW9zJyAtIE9ubHkgdmlkZW8gZmlsZXMgYXJlIGFsbG93ZWRcbiAqICAgICogJ2ltYWdlcycgLSBPbmx5IGltYWdlcyBhcmUgYWxsb3dlZFxuICogSWYgeW91IGRvbid0IHByb3ZpZGUgYW55IHR5cGUsIHRoZSBmaWxlbWFuYWdlciB3aWxsIGRlZmF1bHQgdG8gJ2FsbCcuXG4gKlxuICogKipDb250ZW50IERpcmVjdG9yeSB8IGBkYXRhLWZpbGVtYW5hZ2VyLWNvbnRlbnQtZGlyZWN0b3J5YCB8IFN0cmluZyB8IFJlcXVpcmVkKipcbiAqXG4gKiBQcm92aWRlIHRoZSBkaXJlY3Rvcnkgd2hpY2ggc2hvdWxkIGJlIG9wZW5lZCB3aGVuIHRoZSBmaWxlbWFuYWdlciBnZXRzIG9wZW5lZCwgZS5nLiAnbWVkaWEnLlxuICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYSBwYXRoIGZyb20gdGhlIHJvb3Qgb2YgeW91ciBzaG9wIGUuZyAnaW1hZ2VzL3NsaWRlcl9pbWFnZXMnLlxuICpcbiAqICoqTmFtZSB8IGBkYXRhLWZpbGVtYW5hZ2VyLW5hbWVgIHwgU3RyaW5nIHwgUmVxdWlyZWQqKlxuICpcbiAqIFRoZSBuYW1lIG9mIHRoZSBpbnB1dCBmaWVsZC4gSXQgd2lsbCBiZSBzZXQgYXMgdGhlIEhUTUwgbmFtZSBhdHRyaWJ1dGUuXG4gKlxuICogKipQcmV2aW91cyBGaWxlIHwgYGRhdGEtZmlsZW1hbmFnZXItcHJldmlvdXMtZmlsZWAgfCBTdHJpbmcgfCBPcHRpb25hbCoqXG4gKlxuICogTmFtZSBvZiB0aGUgcHJldmlvdXMgZmlsZS4gVGhlIG5hbWUgd2lsbCBiZSB1c2VkIGluIG9yZGVyIHRvIGF1dG8gZmlsbCB0aGUgaW5wdXQgZmllbGQuXG4gKlxuICogKipQYWdlIHwgYGRhdGEtZmlsZW1hbmFnZXItcGFnZWAgfCBTdHJpbmcgfCBPcHRpb25hbCoqXG4gKlxuICogVGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgcGFnZSBpbiBzbmFrZSBjYXNlLCBmb3IgZXhhbXBsZTogbmV3X2NhdGVnb3J5IG9yIHJlc3BvbnNpdmVfZmlsZW1hbmFnZXIuXG4gKiBUaGlzIG9wdGlvbiB3aWxsIGJlIHVzZWQgaW4gb3JkZXIgdG8gbG9hZCBjdXN0b20gY29uZmlndXJhdGlvbiBmaWxlcyBmb3IgdGhlIHJlc3BvbnNpdmUgZmlsZSBtYW5hZ2VyIGxpa2VcbiAqIHJlc3BvbnNpdmVfZmlsZW1hbmFnZXIuY29uZmlnLnBocC4gVGhlc2UgY3VzdG9tIGNvbmZpZ3VyYXRpb24gZmlsZXMgd2lsbCBiZSBhdmFpbGFibGUgb3Igc2hvdWxkIGJlIGNyZWF0ZWRcbiAqIGluIHRoZSAncGFnZScgZGlyZWN0b3J5IG9mIHRoZSByZXNwb25zaXZlIGZpbGUgbWFuYWdlci5cbiAqXG4gKiAqKlBhZ2UgQWN0aXZlIHwgYGRhdGEtZmlsZW1hbmFnZXItcGFnZS1hY3RpdmVgIHwgQm9vbGVhbiB8IFJlcXVpcmVkKipcbiAqXG4gKiBUaGlzIG9wdGlvbiBpcyByZXF1aXJlZCBpbiBvcmRlciB0byBjaGVjayB3aGV0aGVyIHRoZSBmaWxlIG1hbmFnZXIgbW9kdWxlIGlzIGFjdGl2ZSwgYW5kIGlmIHRoZSBjb25maWd1cmF0aW9uXG4gKiBvcHRpb24gZnJvbSB0aGUgZmlsZSBtYW5hZ2VyIGlzIHNldCB0byBhY3RpdmUsIGZvciB0aGUgY3VycmVudCBwYWdlLiBJZiB0aGUgbW9kdWxlIGlzIG5vdCBhY3RpdmUsIG9yIGFjdGl2ZVxuICogaW4gZ2VuZXJhbCBidXQgbm90IGFjdGl2ZSBmb3IgdGhlIGN1cnJlbnQgcGFnZSwgdGhlIGZhbGxiYWNrIHdpbGwgYmUgdXNlZCwgd2hpY2ggaXMgYSBzdGFuZGFyZCBpbnB1dCBmaWVsZC5cbiAqXG4gKiAjIyMgRXhhbXBsZVxuICpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgZGF0YS1neC13aWRnZXQ9XCJmaWxlbWFuYWdlclwiXG4gKiAgICAgZGF0YS1maWxlbWFuYWdlci1uYW1lPVwiY2F0ZWdvcmllc19pY29uXCIgLy8gUmVxdWlyZWRcbiAqICAgICBkYXRhLWZpbGVtYW5hZ2VyLXR5cGU9XCJpbWFnZXNcIiAvLyBPcHRpb25hbFxuICogICAgIGRhdGEtZmlsZW1hbmFnZXItY29udGVudC1kaXJlY3Rvcnk9XCJpbWFnZXMvY2F0ZWdvcmllcy9pY29uc1wiIC8vIFJlcXVpcmVkXG4gKiAgICAgZGF0YS1maWxlbWFuYWdlci1wcmV2aW91cy1maWxlPVwiZmlsZW5hbWUuZXh0ZW5zaW9uXCIgLy8gT3B0aW9uYWxcbiAqICAgICBkYXRhLWZpbGVtYW5hZ2VyLXBhZ2U9XCJyZXNwb25zaXZlX2ZpbGVtYW5hZ2VyXCIgLy8gT3B0aW9uYWxcbiAqICAgICBkYXRhLWZpbGVtYW5hZ2VyLXBhZ2UtYWN0aXZlPVwidHJ1ZVwiPiAvLyBSZXF1aXJlZFxuICogPC9kaXY+XG4gKiBgYGBcbiAqXG4gKiBAbW9kdWxlIEFkbWluL1dpZGdldHMvZmlsZW1hbmFnZXJcbiAqL1xuZ3gud2lkZ2V0cy5tb2R1bGUoXG4gICAgJ2ZpbGVtYW5hZ2VyJyxcblxuICAgIFsneGhyJywgJ21vZGFsJ10sXG5cbiAgICAvKiogQGxlbmRzIG1vZHVsZTpXaWRnZXRzL2ZpbGVtYW5hZ2VyICovXG5cbiAgICBmdW5jdGlvbiAoZGF0YSkge1xuXG4gICAgICAgICd1c2Ugc3RyaWN0JztcblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gVkFSSUFCTEUgREVGSU5JVElPTlxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgICAgICAvKipcbiAgICAgICAgICogV2lkZ2V0IFJlZmVyZW5jZVxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgJHRoaXMgPSAkKHRoaXMpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWZhdWx0IFdpZGdldCBPcHRpb25zXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0eXBlIHtvYmplY3R9XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBkZWZhdWx0cyA9IHt9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGaW5hbCBXaWRnZXQgT3B0aW9uc1xuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9ICQuZXh0ZW5kKHRydWUsIHt9LCBkZWZhdWx0cywgZGF0YSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZHVsZSBPYmplY3RcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge29iamVjdH1cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IG1vZHVsZSA9IHt9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZCBvZiB0aGUgZmlsZSBtYW5hZ2VyIGlucHV0IGZpZWxkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGZpZWxkSWQ7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFqYXggcmVxdWVzdCB1cmwgZmV0Y2ggdGhlIGZpbGUgbWFuYWdlcnMgY29uZmlndXJhdGlvbiBzZXR0aW5ncy5cbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGZpbGVNYW5hZ2VyQ29uZmlndXJhdGlvblVybCA9IGpzZS5jb3JlLmNvbmZpZy5nZXQoJ2FwcFVybCcpXG4gICAgICAgICAgICArICcvYWRtaW4vYWRtaW4ucGhwP2RvPVJlc3BvbnNpdmVGaWxlTWFuYWdlck1vZHVsZUNlbnRlck1vZHVsZS9HZXRDb25maWd1cmF0aW9uJztcblxuICAgICAgICAvKipcbiAgICAgICAgICogIENhY2hlIGtleS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGNhY2hlS2V5ID0gJ3Jlc3BvbnNpdmVGaWxlTWFuYWdlcic7XG5cblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gRlVOQ1RJT05TXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBGSUxFIE1BTkFHRVIgQ09ORklHVVJBVElPTlNcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBhbGxvd2VkIGZpbGUgdHlwZSBhcyBhbiBpbnRlZ2VyLCB3aGljaCBpcyBtYXBwZWRcbiAgICAgICAgICogZm9yIHRoZSBleHRlcm5hbCBSZXNwb25zaXZlIEZpbGVtYW5hZ2VyIHBsdWdpbi4gSXQgd2lsbCBiZSB1c2VkXG4gICAgICAgICAqIGFzIGEgR0VUIHBhcmFtZXRlciBpbiB0aGUgVVJMIGZvciB0aGUgZmlsZSBtYW5hZ2VyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBGbGFnIGludGVnZXIgdmFsdWUgYmV0d2VlbiAwIGFuZCAzLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgX2dldEZNVHlwZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnaW1hZ2VzJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgY2FzZSAnYWxsJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDI7XG4gICAgICAgICAgICAgICAgY2FzZSAndmlkZW9zJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDM7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZpbGUgbWFuYWdlcnMgcmVxdWVzdCB1cmwuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJlcXVlc3QgdXJsIG9mIGZpbGUgbWFuYWdlci5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9nZXRGTVVybCA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIExhbmd1YWdlIHBhcmFtZXRlciB1c2VkIGZvciB0aGUgZmlsZSBtYW5hZ2VyXG4gICAgICAgICAgICBjb25zdCBsYW5nID0ganNlLmNvcmUucmVnaXN0cnkuZ2V0KCdsYW5ndWFnZUlkJykgPT09IDIgPyAnZGUnIDogJ2VuX0VOJztcblxuICAgICAgICAgICAgLy8gRG9uJ3QgdXNlIHRoZSBwb3B1cCBtb2RlIGlmIHRoZSBmaWxlIG1hbmFnZXIgd2lsbCBiZSBvcGVuZWQgaW4gYSBtb2RhbC5cbiAgICAgICAgICAgIGNvbnN0IHBvcFVwID0gX2lzQ29tcGF0aWJpbGl0eU1vZGVFbmFibGVkKCkgPyAxIDogJyc7XG5cbiAgICAgICAgICAgIHJldHVybiBqc2UuY29yZS5jb25maWcuZ2V0KCdhcHBVcmwnKSArICcvJ1xuICAgICAgICAgICAgICAgICsgJ1Jlc3BvbnNpdmVGaWxlbWFuYWdlci9maWxlbWFuYWdlci9maWxlbWFuYWdlci5waHA/dHlwZT0nICsgX2dldEZNVHlwZSgpXG4gICAgICAgICAgICAgICAgKyBfZ2V0U3ViRGlyZWN0b3J5UXVlcnlTdHJpbmcoKSArICcmZmllbGRfaWQ9JyArIGZpZWxkSWRcbiAgICAgICAgICAgICAgICArICcmcG9wdXA9JyArIHBvcFVwICsgJyZyZWxhdGl2ZV91cmw9MSZsYW5nPScgKyBsYW5nXG4gICAgICAgICAgICAgICAgKyBfZ2V0UGFnZVF1ZXJ5U3RyaW5nKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJldHVybnMgdGhlICdzdWJfZm9sZGVyJyBxdWVyeSBhcmd1bWVudCBmb3IgdGhlIGZpbGUgbWFuYWdlciByZXF1ZXN0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBRdWVyeSBwYXJhbWV0ZXIgZm9yIGZpbGUgbWFuYWdlciByZXF1ZXN0IHRvIHNldCB0aGUgcm9vdCBkaXJlY3RvcnkuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBfZ2V0U3ViRGlyZWN0b3J5UXVlcnlTdHJpbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5jb250ZW50RGlyZWN0b3J5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJyZzdWJfZm9sZGVyPScgKyBvcHRpb25zLmNvbnRlbnREaXJlY3Rvcnk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUmV0dXJucyB0aGUgJ3BhZ2UnIHF1ZXJ5IHN0cmluZyBmb3IgdGhlIGZpbGUgbWFuYWdlciByZXF1ZXN0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBRdWVyeSBwYXJhbWV0ZXIgZm9yIHRoZSBmaWxlIG1hbmFnZXIgcmVxdWVzdCB0byBsb2FkIGEgY3VzdG9tIGNvbmZpZ3VyYXRpb24gZmlsZS5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9nZXRQYWdlUXVlcnlTdHJpbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5wYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJyZwYWdlPScgKyBvcHRpb25zLnBhZ2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR2VuZXJhdGVzIGEgZ2xvYmFsIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBlYWNoIGlucHV0IHRoYXQgaXMgZ2VuZXJhdGVkIGJ5IHRoaXMgd2lkZ2V0LlxuICAgICAgICAgKiBUaGlzIElEIHdpbGwgYmUgdXNlZCBpbiBvcmRlciB0byBpZGVudGlmeSBhbiBpbnB1dCBmaWVsZHMuIFdpdGggdGhlIGhlbHAgb2YgdGhpcyBJRCxcbiAgICAgICAgICogdGhlIHdpZGdldCBrbm93cywgaW4gd2hpY2ggaW5wdXQgZmllbGQgdGhlIGZpbGUgbmFtZSBvZiB0aGUgY2hvc2UgZmlsZSBzaG91bGQgYmUgZW50ZXJlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gR2xvYmFsIHVuaXF1ZSBpZGVudGlmaWVyIGFzIHN0cmluZy5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGd1aWRHZW5lcmF0b3IgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzNCA9ICgpID0+ICgoKDEgKyBNYXRoLnJhbmRvbSgpKSAqIDB4MTAwMDApIHwgMCkudG9TdHJpbmcoMTYpLnN1YnN0cmluZygxKTtcblxuICAgICAgICAgICAgcmV0dXJuIChzNCgpICsgczQoKSArIFwiLVwiICsgczQoKSArIFwiLVwiICsgczQoKSArIFwiLVwiICsgczQoKSArIFwiLVwiICsgczQoKSArIHM0KCkgKyBzNCgpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gQ1JFQVRJTkcgVEhFIEZJTEUgTUFOQUdFUlxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZhY3RvcnksIHdoaWNoIGNyZWF0ZXMgZWl0aGVyIHRoZSByZXNwb25zaXZlIGZpbGUgbWFuYWdlciBvciB0aGUgZmFsbGJhY2ssXG4gICAgICAgICAqIHdoaWNoIGlzIGEgc3RhbmRhcmQgaW5wdXQgZmllbGQgb2YgdGhlIHR5cGUgJ2ZpbGUnLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAdHlwZSB7e3Jlc3BvbnNpdmU6IChmdW5jdGlvbigpKSwgZmFsbGJhY2s6IChmdW5jdGlvbigpKX19XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBmYWN0b3J5ID0ge1xuICAgICAgICAgICAgcmVzcG9uc2l2ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0ICR1cGxvYWRJY29uID0gJCgnPGkvPicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ2NsYXNzJzogJ2ZhIGZhLXVwbG9hZCcsXG4gICAgICAgICAgICAgICAgICAgICdhcmlhLWhpZGRlbic6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0ICRyZW1vdmVJY29uID0gJCgnPGkvPicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ2NsYXNzJzogJ2ZhIGZhLXJlbW92ZScsXG4gICAgICAgICAgICAgICAgICAgICdhcmlhLWhpZGRlbic6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0ICRpbnB1dCA9ICQoJzxpbnB1dC8+Jywge1xuICAgICAgICAgICAgICAgICAgICAndHlwZSc6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgJ25hbWUnOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICdpZCc6IGZpZWxkSWQsXG4gICAgICAgICAgICAgICAgICAgICdjbGFzcyc6ICdmb3JtLWNvbnRyb2wnLFxuICAgICAgICAgICAgICAgICAgICAncmVhZG9ubHknOiAncmVhZG9ubHknXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBBdXRvIGZpbGwgdGhlIGlucHV0IGZpZWxkIHdpdGggdGhlIHByZXZpb3VzIGZpbGUgbmFtZVxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnByZXZpb3VzRmlsZSkge1xuICAgICAgICAgICAgICAgICAgICAkaW5wdXQudmFsKG9wdGlvbnMucHJldmlvdXNGaWxlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCAkdXBsb2FkQnV0dG9uID0gJCgnPGEvPicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ2NsYXNzJzogJ2J0biByZXNwb25zaXZlLWZpbGUtbWFuYWdlcicsXG4gICAgICAgICAgICAgICAgICAgICd0eXBlJzogJ2J1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgICdodG1sJzogJHVwbG9hZEljb24sXG4gICAgICAgICAgICAgICAgICAgICdvbic6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICdjbGljayc6ICgpID0+IF9vcGVuRmlsZU1hbmFnZXIoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCAkcmVtb3ZlQnV0dG9uID0gJCgnPGEvPicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ2NsYXNzJzogJ2J0biByZXNwb25zaXZlLWZpbGUtbWFuYWdlcicsXG4gICAgICAgICAgICAgICAgICAgICd0eXBlJzogJ2J1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgICdodG1sJzogJHJlbW92ZUljb24sXG4gICAgICAgICAgICAgICAgICAgICdvbic6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICdjbGljayc6ICgpID0+ICRpbnB1dC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0ICRzcGFuID0gJCgnPHNwYW4vPicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ2NsYXNzJzogJ2lucHV0LWdyb3VwLWJ0bidcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0ICRjb250YWluZXIgPSAkKCc8ZGl2Lz4nLCB7XG4gICAgICAgICAgICAgICAgICAgICdjbGFzcyc6ICdpbnB1dC1ncm91cCByZXNwb25zaXZlLWZpbGUtbWFuYWdlcidcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICRzcGFuLmFwcGVuZCgkdXBsb2FkQnV0dG9uKTtcbiAgICAgICAgICAgICAgICAkc3Bhbi5hcHBlbmQoJHJlbW92ZUJ1dHRvbik7XG5cbiAgICAgICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkaW5wdXQpLmFwcGVuZCgkc3Bhbik7XG4gICAgICAgICAgICAgICAgJHRoaXMuYXBwZW5kKCRjb250YWluZXIpO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgZmFsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCAkaW5wdXQgPSAkKCc8aW5wdXQvPicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ25hbWUnOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICd0eXBlJzogJ2ZpbGUnXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAkdGhpcy5hcHBlbmQoJGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIHRoZSB3aWRnZXQgYWZ0ZXIgdGhlIHJlcXVlc3QgdGhlIHJlc3BvbnNpdmUgZmlsZSBtYW5hZ2VyXG4gICAgICAgICAqIHJlcXVlc3QgaXMgYmVpbmcgbWFkZS4gQWZ0ZXIgdGhlIHJlcXVlc3QsIGVpdGhlciB0aGUgJ3Jlc3BvbnNpdmUnXG4gICAgICAgICAqIHdpZGdldCBpcyBjcmVhdGVkIG9yIHRoZSBmYWxsYmFjaywgZGVwZW5kaW5nIG9uIGlmIHRoZSBmaWxlIG1hbmFnZXJcbiAgICAgICAgICogaXMgYXZhaWxhYmxlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZG9uZSBEb25lIGNhbGxiYWNrIGZ1bmN0aW9uIGZvciBtb2R1bGUuaW5pdC5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9jcmVhdGVXaWRnZXQgPSBkb25lID0+IHtcbiAgICAgICAgICAgIGpzZS5saWJzLnhoci5nZXQoe3VybDogZmlsZU1hbmFnZXJDb25maWd1cmF0aW9uVXJsfSlcbiAgICAgICAgICAgICAgICAuZG9uZShyZXNwb25zZSA9PiBqc2UuY29yZS5yZWdpc3RyeS5zZXQoY2FjaGVLZXksIHJlc3BvbnNlLmlzSW5zdGFsbGVkID8gJ3Jlc3BvbnNpdmUnIDogJ2ZhbGxiYWNrJykpXG4gICAgICAgICAgICAgICAgLmZhaWwoKCkgPT4ganNlLmNvcmUucmVnaXN0cnkuc2V0KGNhY2hlS2V5LCAnZmFsbGJhY2snKSlcbiAgICAgICAgICAgICAgICAuYWx3YXlzKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBmaWxlIG1hbmFnZXIgb3IgZmFsbGJhY2suXG4gICAgICAgICAgICAgICAgICAgIGZhY3RvcnlbanNlLmNvcmUucmVnaXN0cnkuZ2V0KGNhY2hlS2V5KV0oKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIHRoZSB3aWRnZXQgd2hlbiB0aGUgY2FjaGUga2V5IGNoYW5nZXMgZnJvbSBwZW5kaW5nLlxuICAgICAgICAgKiBBZnRlciB0aGUgY2FjaGUga2V5IGNoYW5nZWQgdG8gZWl0aGVyIHRoZSAncmVzcG9uc2l2ZScgb3IgJ2ZhbGxiYWNrJyxcbiAgICAgICAgICogdGhlIGFjY29yZGluZyB3aWRnZXQgd2lsbCBiZSBjcmVhdGVkLCBkZXBlbmRpbmcgb24gaWYgdGhlIGZpbGUgbWFuYWdlclxuICAgICAgICAgKiBpcyBhdmFpbGFibGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSBkb25lIERvbmUgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIG1vZHVsZS5pbml0LlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgX2NyZWF0ZVdpZGdldFdoZW5DYWNoZUtleUF2YWlsYWJsZSA9IGRvbmUgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGpzZS5jb3JlLnJlZ2lzdHJ5LmdldChjYWNoZUtleSkgIT09ICdwZW5kaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgdGhlIGZpbGUgbWFuYWdlciBvciBmYWxsYmFjay5cbiAgICAgICAgICAgICAgICAgICAgZmFjdG9yeVtqc2UuY29yZS5yZWdpc3RyeS5nZXQoY2FjaGVLZXkpXSgpO1xuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gT1BFTklORyBUSEUgRklMRSBNQU5BR0VSXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogT3BlbnMgdGhlIGZpbGUgbWFuYWdlciBpbiBhIG5ldyB3aW5kb3cgcG9wdXAuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBfb3BlbkZNUG9wdXAgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3ID0gODgwO1xuICAgICAgICAgICAgY29uc3QgaCA9IDU3MDtcbiAgICAgICAgICAgIGNvbnN0IGwgPSBNYXRoLmZsb29yKChzY3JlZW4ud2lkdGggLSB3KSAvIDIpO1xuICAgICAgICAgICAgY29uc3QgdCA9IE1hdGguZmxvb3IoKHNjcmVlbi5oZWlnaHQgLSBoKSAvIDIpO1xuXG4gICAgICAgICAgICB3aW5kb3cub3BlbihfZ2V0Rk1VcmwoKSwgJ1Jlc3BvbnNpdmVGaWxlbWFuYWdlcicsIFwic2Nyb2xsYmFycz0xLHdpZHRoPVwiICsgdyArIFwiLGhlaWdodD1cIiArIGhcbiAgICAgICAgICAgICAgICArIFwiLHRvcD1cIlxuICAgICAgICAgICAgICAgICsgdCArIFwiLGxlZnQ9XCIgKyBsKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3BlbnMgdGhlIGZpbGUgbWFuYWdlciBpbiBhIGJvb3RzdHJhcCBtb2RhbC5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9vcGVuRk1Nb2RhbCA9ICgpID0+IHtcblxuICAgICAgICAgICAgLy8gVXNlIHRoZSBmYWxsYmFjayBpZiBib290c3RyYXBzIG1vZGFsIGZ1bmN0aW9uIGlzIG5vdCBhdmFpbGFibGUuXG4gICAgICAgICAgICBpZiAoJC5mbi5tb2RhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9vcGVuRk1Qb3B1cCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBpRnJhbWUgPSBgPGlmcmFtZSBzcmM9XCIke19nZXRGTVVybCgpfVwiIHdpZHRoPVwiMTAwJVwiIGhlaWdodD1cIjU1MFwiIGZyYW1lYm9yZGVyPVwiMFwiXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjbGFzcz1cInJlc3BvbnNpdmUtZmlsZW1hbmFnZXJcIj48L2lmcmFtZT5gO1xuXG4gICAgICAgICAgICBqc2UubGlicy5tb2RhbC5zaG93TWVzc2FnZSgnRmlsZW1hbmFnZXInLCBpRnJhbWUpO1xuICAgICAgICAgICAgX21ha2VNb2RhbExhcmdlKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1ha2VzIHRoZSBtb2RhbCBsYXJnZSBieSBhZGRpbmcgdGhlIG1vZGFsLWxnIGNzcyBjbGFzcy5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9tYWtlTW9kYWxMYXJnZSA9ICgpID0+IHtcbiAgICAgICAgICAgICQoJy5tb2RhbC1kaWFsb2c6bGFzdCcpLmFkZENsYXNzKCdtb2RhbC1sZycpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgY29tcGF0aWJpbGl0eSBtb2RlIGlzIGFjdGl2ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgb24gY29tcGF0aWJpbGl0eSBtb2RlLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBfaXNDb21wYXRpYmlsaXR5TW9kZUVuYWJsZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gJCgnYm9keS5neC1jb21wYXRpYmlsaXR5JykubGVuZ3RoICE9PSAwO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcGVucyB0aGUgZmlsZSBtYW5hZ2VyIGluIGEgbW9kYWwsIGRpYWxvZyBvciB3aW5kb3cgd2l0aCB0aGUgcHJpb3JpdHkgaW5cbiAgICAgICAgICogdGhlIHNhbWUgb3JkZXIuIElmIGJvb3RzdHJhcCBpcyBub3QgYXZhaWxhYmxlLCB0aGUgZmlsZVxuICAgICAgICAgKiBtYW5hZ2VyIHdpbGwgYmUgb3BlbmVkIGluIGEgbmV3IHdpbmRvdy5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IF9vcGVuRmlsZU1hbmFnZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoX2lzQ29tcGF0aWJpbGl0eU1vZGVFbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX29wZW5GTVBvcHVwKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIF9vcGVuRk1Nb2RhbCgpO1xuICAgICAgICB9O1xuXG5cbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIElOSVRJQUxJWkFUSU9OXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbml0aWFsaXplIG1ldGhvZCBvZiB0aGUgd2lkZ2V0LCBjYWxsZWQgYnkgdGhlIGVuZ2luZS5cbiAgICAgICAgICovXG4gICAgICAgIG1vZHVsZS5pbml0ID0gZG9uZSA9PiB7XG4gICAgICAgICAgICBmaWVsZElkID0gZ3VpZEdlbmVyYXRvcigpO1xuXG4gICAgICAgICAgICAvLyBSZXF1aXJlZCBvcHRpb24gbm90IHByb3ZpZGVkXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5jb250ZW50RGlyZWN0b3J5ID09PSB1bmRlZmluZWQgfHwgb3B0aW9ucy5jb250ZW50RGlyZWN0b3J5ID09PSAnJykge1xuICAgICAgICAgICAgICAgIGpzZS5jb3JlLmRlYnVnLmVycm9yKCdjb250ZW50LWRpcmVjdG9yeSBhdHRyaWJ1dGUgd2FzIG5vdCBwcm92aWRlZCBmb3IgdGhlIFwiZmlsZW1hbmFnZXJcIiB3aWRnZXQuJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZXF1aXJlZCBvcHRpb24gbm90IHByb3ZpZGVkXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5uYW1lID09PSB1bmRlZmluZWQgfHwgb3B0aW9ucy5uYW1lID09PSAnJykge1xuICAgICAgICAgICAgICAgIGpzZS5jb3JlLmRlYnVnLmVycm9yKCduYW1lIGF0dHJpYnV0ZSB3YXMgbm90IHByb3ZpZGVkIGZvciB0aGUgXCJmaWxlbWFuYWdlclwiIHdpZGdldC4nKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlcXVpcmVkIG9wdGlvbiBub3QgcHJvdmlkZWRcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnBhZ2VBY3RpdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGpzZS5jb3JlLmRlYnVnLmVycm9yKCdwYWdlLWFjdGl2ZSBhdHRyaWJ1dGUgd2FzIG5vdCBwcm92aWRlZCBmb3IgdGhlIFwiZmlsZW1hbmFnZXJcIiB3aWRnZXQuJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBNb2R1bGUgaXMgbm90IGFjdGl2ZSBhdCBhbGwgb3Igbm90IGFjdGl2ZSBmb3IgdGhlIHVzZWQgcGFnZS5cbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5wYWdlQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgZmFjdG9yeS5mYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE5vIGNhY2hlIGtleSBhdmFpbGFibGUgeWV0LiBDcmVhdGUgdGhlIHdpZGdldCBhbmQgc2V0IHRoZSBjYWNoZSBrZXkgdG8gJ2ZhbGxiYWNrJyBvciAncmVzcG9uc2l2ZSdcbiAgICAgICAgICAgIC8vIGFmdGVyIHRoZSByZXNwb25zaXZlIGhhcyBhcnJpdmVkIChkb25lIGJ5IHRoZSBfY3JlYXRlV2lkZ2V0IGZ1bmN0aW9uKS5cbiAgICAgICAgICAgIGlmIChqc2UuY29yZS5yZWdpc3RyeS5nZXQoY2FjaGVLZXkpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBqc2UuY29yZS5yZWdpc3RyeS5zZXQoY2FjaGVLZXksICdwZW5kaW5nJyk7XG4gICAgICAgICAgICAgICAgX2NyZWF0ZVdpZGdldChkb25lKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENhY2hlIGtleSBpcyBvbiAncGVuZGluZycgd2hpY2ggbWVhbnMgd2UgaGF2ZSB0byB3YWl0IHVudGlsIHRoZSBrZXkgY2hhbmdlcyAoZG9uZSBieSB0aGUgX2NyZWF0ZVdpZGdldCBmdW5jdGlvbikuXG4gICAgICAgICAgICAvLyBBZnRlcndhcmRzIHdlIGNhbiBjcmVhdGUgdGhlIGNvcnJlY3Qgd2lkZ2V0LlxuICAgICAgICAgICAgaWYgKGpzZS5jb3JlLnJlZ2lzdHJ5LmdldChjYWNoZUtleSkgPT09ICdwZW5kaW5nJykge1xuICAgICAgICAgICAgICAgIF9jcmVhdGVXaWRnZXRXaGVuQ2FjaGVLZXlBdmFpbGFibGUoZG9uZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBCdWlsZCB0aGUgZmFsbGJhY2sgb3IgcmVzcG9uc2l2ZSBmaWxlIG1hbmFnZXIuXG4gICAgICAgICAgICBmYWN0b3J5W2pzZS5jb3JlLnJlZ2lzdHJ5LmdldChjYWNoZUtleSldKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJuIGRhdGEgdG8gbW9kdWxlIGVuZ2luZS5cbiAgICAgICAgcmV0dXJuIG1vZHVsZTtcbiAgICB9KTtcbiJdfQ==

Youez - 2016 - github.com/yon3zu
LinuXploit