UNPKG

flx-ui-datatable

Version:

## AUTHOR Felix Kakra Acheampong from (`Orcons Systems`) Ghana

1,300 lines 187 kB
import { Injectable, Component, Input, Output, EventEmitter, Directive, ElementRef, Pipe, NgModule } from '@angular/core';
import { Http, Headers, HttpModule } from '@angular/http';
import { map, retry } from 'rxjs/operators';
import { BehaviorSubject } from 'rxjs';
import { __values } from 'tslib';
import { Validators, FormBuilder, ReactiveFormsModule, FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { PerfectScrollbarModule, PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar';

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var FlxUiDatatableService = /** @class */ (function () {
    function FlxUiDatatableService(http) {
        this.http = http;
        this.dataUrl = '';
        this.behavior = new BehaviorSubject([]);
        this.flxData = this.behavior.asObservable();
        this.pagination = [];
        this.totalItems = 0;
        this.dataOffset = 0;
        this.limit = 20;
        this.dataSrcKey = '';
        //Hold items selected for multiple select
        this.multipleDeletion = [];
        //Keep track if API call is completed
        this.loadFinish = false;
        this.lazyloadingConfig = {};
        this.processedData = {};
    }
    /**
     * @param {?} config
     * @return {?}
     */
    FlxUiDatatableService.prototype.setLazyloadingConfig = /**
     * @param {?} config
     * @return {?}
     */
    function (config) {
        this.lazyloadingConfig = config;
    };
    /**
     *
     * @param {?} url User api rul
     * @return {?}
     */
    FlxUiDatatableService.prototype.getData = /**
     *
     * @param {?} url User api rul
     * @return {?}
     */
    function (url) {
        var /** @type {?} */ headers = new Headers();
        headers.append('Content-Type', 'application/x-www-form-urlencoded');
        return this.http.get(url, { headers: headers }).pipe(retry(5), map(function (response) { return response.json(); }));
    };
    /**
     *
     * @param {?} url Service api url
     * @param {?} id Datatype id to export
     * @param {?} data Data to export
     * @return {?}
     */
    FlxUiDatatableService.prototype.postData = /**
     *
     * @param {?} url Service api url
     * @param {?} id Datatype id to export
     * @param {?} data Data to export
     * @return {?}
     */
    function (url, id, data) {
        var /** @type {?} */ headers = new Headers();
        headers.append('Content-Type', 'application/json; charset=utf-8');
        return this.http.post(url + id, data, { headers: headers }).pipe(map(function (resp) { return resp.json(); }));
    };
    /**
     *
     * @param {?} dataUrl Set dataurl
     * @return {?}
     */
    FlxUiDatatableService.prototype.setDataUrl = /**
     *
     * @param {?} dataUrl Set dataurl
     * @return {?}
     */
    function (dataUrl) {
        this.dataUrl = dataUrl;
    };
    /**
     * @return {?}
     */
    FlxUiDatatableService.prototype.getDataUrl = /**
     * @return {?}
     */
    function () {
        return this.dataUrl;
    };
    /**
     *
     * @param {?} data Register new data from user API
     * @return {?}
     */
    FlxUiDatatableService.prototype.chageDataTable = /**
     *
     * @param {?} data Register new data from user API
     * @return {?}
     */
    function (data) {
        this.behavior.next(data);
    };
    /**
     *
     * @param {?} numberOfList Total number of list
     * @param {?} limit Pagination limit
     * @return {?}
     */
    FlxUiDatatableService.prototype.createPagination = /**
     *
     * @param {?} numberOfList Total number of list
     * @param {?} limit Pagination limit
     * @return {?}
     */
    function (numberOfList, limit) {
        var /** @type {?} */ obj = [];
        var /** @type {?} */ counter = 1;
        for (var /** @type {?} */ i = 0; i < numberOfList; i += limit) {
            obj.push({ label: counter, value: i });
            counter++;
        }
        if (!this.isLazyLoadingEnabled) {
            obj.push({ label: 'All', value: 'all' });
        }
        return obj;
    };
    /**
     * @return {?}
     */
    FlxUiDatatableService.prototype.isLazyLoadingEnabled = /**
     * @return {?}
     */
    function () {
        return this.lazyloadingConfig.hasOwnProperty("apiOffsetKey") && this.lazyloadingConfig.apiOffsetKey;
    };
    /**
     * @param {?} dataUrl
     * @param {?=} setSelectPagination
     * @return {?}
     */
    FlxUiDatatableService.prototype.loadFlxDataTableData = /**
     * @param {?} dataUrl
     * @param {?=} setSelectPagination
     * @return {?}
     */
    function (dataUrl, setSelectPagination) {
        var _this = this;
        if (setSelectPagination === void 0) { setSelectPagination = true; }
        this.loadFinish = false;
        this.loader = this.getData(dataUrl).subscribe(function (responseData) {
            try {
                _this.multipleDeletion = [];
                var /** @type {?} */ data = (_this.dataSrcKey) ? responseData[_this.dataSrcKey] : responseData;
                _this.chageDataTable(data);
                if (_this.isLazyLoadingEnabled()) {
                    _this.totalItems = responseData.total;
                    // Handle 1 pagination out of zero problem 1/0  instead of 0/0 if no data is comming
                    if (data.length > 0) {
                        _this.dataOffset = _this.dataOffset + _this.limit;
                    }
                }
                else {
                    _this.totalItems = data.length;
                    _this.dataOffset = 1;
                }
                if (setSelectPagination) {
                    if (_this.isLazyLoadingEnabled()) {
                        _this.pagination = _this.createPagination(responseData.total, _this.limit);
                    }
                    else {
                        _this.pagination = _this.createPagination(data.length, _this.limit);
                    }
                }
                _this.loadFinish = true;
            }
            catch (/** @type {?} */ e) {
                console.log('Error in reading data in ', e);
            }
        }, (function (e) {
            _this.loadFinish = true;
        }));
    };
    /**
     * @return {?}
     */
    FlxUiDatatableService.prototype.cancelLoading = /**
     * @return {?}
     */
    function () {
        this.loader.unsubscribe();
    };
    //Set source key to read from payload response JSON
    /**
     * @param {?} srcKey
     * @return {?}
     */
    FlxUiDatatableService.prototype.setDataSrcKey = /**
     * @param {?} srcKey
     * @return {?}
     */
    function (srcKey) {
        this.dataSrcKey = srcKey;
    };
    /**
     * @return {?}
     */
    FlxUiDatatableService.prototype.getDataLength = /**
     * @return {?}
     */
    function () {
        var _this = this;
        return new Promise(function (resolve) {
            _this.flxData.subscribe(function (resp) {
                resolve(resp.length);
            }, (function (e) {
                resolve(0);
            }));
        });
    };
    FlxUiDatatableService.decorators = [
        { type: Injectable },
    ];
    /** @nocollapse */
    FlxUiDatatableService.ctorParameters = function () { return [
        { type: Http }
    ]; };
    return FlxUiDatatableService;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var FlxUiDataTable = /** @class */ (function () {
    function FlxUiDataTable(service) {
        var _this = this;
        this.service = service;
        this.behavior = new BehaviorSubject([]);
        this.flxDatatableData = this.behavior.asObservable();
        this.service.flxData.subscribe(function (resp) {
            _this.ChangeData(resp);
        });
    }
    /**
     *
     * @param data Change table data with new data
     */
    /**
     *
     * @param {?} data Change table data with new data
     * @return {?}
     */
    FlxUiDataTable.prototype.ChangeData = /**
     *
     * @param {?} data Change table data with new data
     * @return {?}
     */
    function (data) {
        this.behavior.next(data);
    };
    /**
     * Reload data from api: void
     * @return {?}
     */
    FlxUiDataTable.prototype.reloadData = /**
     * Reload data from api: void
     * @return {?}
     */
    function () {
        this.service.loadFlxDataTableData(this.service.getDataUrl());
    };
    /**
     * @return {?}
     */
    FlxUiDataTable.prototype.abortRequest = /**
     * @return {?}
     */
    function () {
        this.service.cancelLoading();
    };
    FlxUiDataTable.decorators = [
        { type: Injectable },
    ];
    /** @nocollapse */
    FlxUiDataTable.ctorParameters = function () { return [
        { type: FlxUiDatatableService }
    ]; };
    return FlxUiDataTable;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var FlxUiDatatableComponent = /** @class */ (function () {
    function FlxUiDatatableComponent(__form, service) {
        this.__form = __form;
        this.service = service;
        this.classes = {};
        this.headers = [];
        this.lazyloadingConfig = {};
        this.embedPictures = {};
        this.dataKeys = [];
        this.enableDataExports = false;
        this.dataExportsConfig = {};
        this.searchKeys = [];
        this.dataSrcKey = '';
        this.hasActionButtons = false;
        this.hideNumbers = false;
        this.enableMultipleSelection = false;
        this.multipleSelectKey = '';
        this.hasAddButton = false;
        this.dataUrl = '';
        this.actionButtonStart = false;
        this.multipleSelectButton = { text: 'Selected', icon: '' };
        this.searchPlaceholder = 'Enter name to search';
        this.actionHeader = 'Actions';
        this.limit = 20;
        this.spinnerSrc = '';
        this.actionButtons = [];
        this.paginationButtons = { background: '#dddddd', textColor: '#335599' };
        this.tableHeader = { background: '#ffffff', textColor: '#335599' };
        this.searchButton = { background: '#cccccc', textColor: '#335599' };
        this.addButton = {};
        this.searchBar = { borderSize: '1px', borderColor: '#ccc', background: '#ffffff', textColor: '#000000' };
        this.actionButtonsConfig = { position: 'right', beforeNumbers: true };
        this.firstActionButtonClicked = new EventEmitter();
        this.secondActionButtonClicked = new EventEmitter();
        this.thirdActionButtonClicked = new EventEmitter();
        this.multipleSelectClicked = new EventEmitter();
        this.addButtonClicked = new EventEmitter();
        /**
         * 18/12/2018
         */
        this.textSubstring = {};
        this.conditionManipulator = {};
        this.isExportAll = false;
        this.tData = [];
        this.behavior = new BehaviorSubject([]);
        this.searchDataTempOffset = [];
        this.displayData = this.behavior.asObservable();
        this.offset = 1;
        this.searchResultFound = [];
    }
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.reload = /**
     * @return {?}
     */
    function () {
        this.service.loadFlxDataTableData(this.reloadUrl, true);
    };
    /**
     *
     * @param checked Export all selection
     */
    /**
     *
     * @param {?} checked Export all selection
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.checkToExportOption = /**
     *
     * @param {?} checked Export all selection
     * @return {?}
     */
    function (checked) {
        this.isExportAll = checked;
    };
    /**
     *
     * @param exportType Export type: print|pdf|excel|word
     */
    /**
     *
     * @param {?} exportType Export type: print|pdf|excel|word
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.exportDocumentsAs = /**
     *
     * @param {?} exportType Export type: print|pdf|excel|word
     * @return {?}
     */
    function (exportType) {
        var _this = this;
        var /** @type {?} */ loading = /** @type {?} */ (document.getElementById("export_loading"));
        loading.style.display = 'block';
        var /** @type {?} */ headers = (!this.dataExportsConfig.dataColumns || this.dataExportsConfig.dataColumns.length < 1) ? this.dataKeys : this.dataExportsConfig.dataColumns;
        var /** @type {?} */ dataToExport = (!this.isExportAll) ? this.displayData : this.service.flxData;
        //Subscribe to data
        dataToExport.subscribe(function (data) {
            var /** @type {?} */ arrayObj = [];
            try {
                //Loop and push data
                for (var data_1 = __values(data), data_1_1 = data_1.next(); !data_1_1.done; data_1_1 = data_1.next()) {
                    var d = data_1_1.value;
                    var /** @type {?} */ obj = {};
                    for (var /** @type {?} */ h = 0; h < headers.length; h++) {
                        obj[headers[h]] = d[headers[h]];
                    }
                    arrayObj.push(obj);
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (data_1_1 && !data_1_1.done && (_a = data_1.return)) _a.call(data_1);
                }
                finally { if (e_1) throw e_1.error; }
            }
            if (exportType == 'print') {
                try {
                    printJS({ printable: arrayObj, properties: headers, type: 'json' });
                    loading.style.display = 'none';
                }
                catch (/** @type {?} */ e) {
                    loading.style.display = 'none';
                    // console.log('PrintJS not found. Add `https://printjs-4de6.kxcdn.com/print.min.js` to your index.html or add as part of angular.json script') ;
                }
            }
            else {
                var /** @type {?} */ extension_1 = (exportType == 'pdf') ? 'pdf' : (exportType == 'excel') ? 'xlsx' : 'docx';
                var /** @type {?} */ pageId = (exportType == 'pdf') ? 3 : (exportType == 'excel') ? 5 : 4;
                var /** @type {?} */ requestData = { "data": JSON.stringify(arrayObj) };
                _this.service.postData('http://exporter.azurewebsites.net/api/export/ExportFromJSON/', pageId, requestData).subscribe(function (resp) {
                    var /** @type {?} */ download = 'http://exporter.azurewebsites.net/api/export/GetFile/' + resp;
                    download += "?fileName=andrei&extension=" + extension_1;
                    window.location.href = download;
                    loading.style.display = 'none';
                }, (function (e) {
                    //console.log('file export error',e) ;
                }));
            }
            var e_1, _a;
        }).unsubscribe();
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.hasImageEmbeded = /**
     * @return {?}
     */
    function () {
        return this.embedPictures.hasOwnProperty("index");
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.getImage = /**
     * @return {?}
     */
    function () {
        console.log('eoeoe');
        //   let img = new Image() ;
        //   img.src = imageSrc ;
        //   img.onload = ((e)=>{
        //       return imageSrc ;
        //   }) ;
        //   img.onerror = ((e)=>{
        //     return this.embedPictures.fallbackUrl ;
        //   })
    };
    /**
     * @param {?} JSONData
     * @param {?} ReportTitle
     * @param {?} ShowLabel
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.JSONToCSVConvertor = /**
     * @param {?} JSONData
     * @param {?} ReportTitle
     * @param {?} ShowLabel
     * @return {?}
     */
    function (JSONData, ReportTitle, ShowLabel) {
        //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
        var /** @type {?} */ arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
        var /** @type {?} */ CSV = '';
        //Set Report title in first row or line
        CSV += ReportTitle + '\r\n\n';
        //This condition will generate the Label/Header
        if (ShowLabel) {
            var /** @type {?} */ row = "";
            //This loop will extract the label from 1st index of on array
            for (var /** @type {?} */ index in arrData[0]) {
                //Now convert each value to string and comma-seprated
                row += index + ',';
            }
            row = row.slice(0, -1);
            //append Label row with line break
            CSV += row + '\r\n';
        }
        //1st loop is to extract each row
        for (var /** @type {?} */ i = 0; i < arrData.length; i++) {
            var /** @type {?} */ row = "";
            //2nd loop will extract each column and convert it in string comma-seprated
            for (var /** @type {?} */ index in arrData[i]) {
                row += '"' + arrData[i][index] + '",';
            }
            row.slice(0, row.length - 1);
            //add a line break after each row
            CSV += row + '\r\n';
        }
        if (CSV == '') {
            alert("Invalid data");
            return;
        }
        //Generate a file name
        var /** @type {?} */ fileName = "MyReport_";
        //this will remove the blank-spaces from the title and replace it with an underscore
        fileName += ReportTitle.replace(/ /g, "_");
        //Initialize file format you want csv or xls
        var /** @type {?} */ uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
        // Now the little tricky part.
        // you can use either>> window.open(uri);
        // but this will not work in some browsers
        // or you will not get the correct file extension
        //this trick will generate a temp <a /> tag
        var /** @type {?} */ link = document.createElement("a");
        link.href = uri;
        //set the visibility hidden so it will not effect on your web-layout
        link.style = "visibility:hidden";
        link.download = fileName + ".csv";
        //this part will append the anchor tag and remove it after automatic click
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };
    /**
     *
     * @param newData
     */
    /**
     *
     * @param {?} newData
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.changeDisplayData = /**
     *
     * @param {?} newData
     * @return {?}
     */
    function (newData) {
        this.behavior.next(newData);
        this.setColumnWidths();
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.ngOnInit = /**
     * @return {?}
     */
    function () {
        var _this = this;
        $(window).resize(function () {
            /* Same as before */
        }).resize();
        if (this.isLazyloadingEnabled()) {
            this.reloadUrl = this.dataUrl + '&' + this.lazyloadingConfig.apiOffsetKey + '=0&' + this.lazyloadingConfig.apiSearchKey + '=';
        }
        else {
            this.reloadUrl = this.dataUrl;
        }
        this.searchForm = this.__form.group({
            searchString: ['', Validators.required]
        });
        this.searchForm = this.__form.group({
            searchString: ['', Validators.required]
        });
        this.service.limit = this.limit;
        this.service.setLazyloadingConfig(this.lazyloadingConfig);
        this.service.setDataUrl(this.dataUrl);
        this.service.setDataSrcKey(this.dataSrcKey);
        var /** @type {?} */ url = (this.isLazyloadingEnabled()) ? this.dataUrl + '&' + this.lazyloadingConfig.apiOffsetKey + '=0&' + this.lazyloadingConfig.apiSearchKey + '=' : this.dataUrl;
        this.service.loadFlxDataTableData(url);
        this.service.flxData.subscribe(function (resp) {
            _this.tData = resp;
            var /** @type {?} */ obj = [];
            if (_this.tData.length > _this.limit) {
                for (var /** @type {?} */ i = 0; i < _this.limit; i++) {
                    obj.push(_this.tData[i]);
                }
                // this.service.dataOffset = this.limit;
            }
            else {
                for (var /** @type {?} */ i = 0; i < _this.tData.length; i++) {
                    obj.push(_this.tData[i]);
                }
                // this.service.dataOffset = obj.length;
            }
            _this.searchDataTempOffset = obj;
            _this.changeDisplayData(obj);
        });
    };
    /**
     * @param {?} values
     * @param {?} form
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.searchDataInApi = /**
     * @param {?} values
     * @param {?} form
     * @return {?}
     */
    function (values, form) {
        this.service.chageDataTable([]);
        this.service.loadFlxDataTableData(this.dataUrl + '&' + this.lazyloadingConfig.apiOffsetKey + '=0&' + this.lazyloadingConfig.apiSearchKey + '=' + values.searchString);
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.ngAfterViewInit = /**
     * @return {?}
     */
    function () {
        var /** @type {?} */ eachColumnWidth = this.returColumnswidth();
        $(window).ready(function () {
            $(".flx-table-thead tr th").css({ 'width': eachColumnWidth + '%' });
        });
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.setColumnWidths = /**
     * @return {?}
     */
    function () {
        var /** @type {?} */ eachColumnWidth = this.returColumnswidth();
        $(window).ready(function () {
            $(".flx-table-data tbody tr td").css({ 'width': eachColumnWidth + '%' });
        });
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.returColumnswidth = /**
     * @return {?}
     */
    function () {
        var /** @type {?} */ hasNumbers = (!this.hideNumbers) ? 0 : 1;
        var /** @type {?} */ hasActionButtons = (!this.hasActionButtons) ? 0 : 1;
        var /** @type {?} */ numberOfColumns = (this.headers.length + 1) + hasActionButtons + hasNumbers;
        console.log('number_of_columns', numberOfColumns);
        var /** @type {?} */ eachColumnWidth = 100 / numberOfColumns;
        return eachColumnWidth;
    };
    /**
     * @param {?} index
     * @param {?} buttonIndex
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.actionButtonClicked = /**
     * @param {?} index
     * @param {?} buttonIndex
     * @return {?}
     */
    function (index, buttonIndex) {
        var _this = this;
        this.displayData.subscribe(function (data) {
            if (buttonIndex == 0) {
                return _this.firstActionButtonClicked.emit({ index: index, data: data[index] });
            }
            else if (buttonIndex == 1) {
                return _this.secondActionButtonClicked.emit({ index: index, data: data[index] });
            }
            else {
                _this.thirdActionButtonClicked.emit({ index: index, data: data[index] });
            }
        }).unsubscribe();
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.addButtonClick = /**
     * @return {?}
     */
    function () {
        this.addButtonClicked.emit();
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.confirmDelete = /**
     * @return {?}
     */
    function () {
        return this.multipleSelectClicked.emit(this.service.multipleDeletion);
    };
    /**
     * @param {?} checked
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.addRemove = /**
     * @param {?} checked
     * @return {?}
     */
    function (checked) {
        var _this = this;
        if (checked) {
            this.displayData.subscribe(function (data) {
                try {
                    for (var data_2 = __values(data), data_2_1 = data_2.next(); !data_2_1.done; data_2_1 = data_2.next()) {
                        var i = data_2_1.value;
                        try {
                            _this.service.multipleDeletion.push(i[_this.multipleSelectKey]);
                        }
                        catch (/** @type {?} */ e) { }
                    }
                }
                catch (e_2_1) { e_2 = { error: e_2_1 }; }
                finally {
                    try {
                        if (data_2_1 && !data_2_1.done && (_a = data_2.return)) _a.call(data_2);
                    }
                    finally { if (e_2) throw e_2.error; }
                }
                // console.log(this.service.multipleDeletion) ;
                var e_2, _a;
            }).unsubscribe();
        }
        else {
            this.service.multipleDeletion = [];
        }
    };
    /**
     * @param {?} dataKeyvalue
     * @param {?} index
     * @param {?} selected
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.addRemoveDeleteItem = /**
     * @param {?} dataKeyvalue
     * @param {?} index
     * @param {?} selected
     * @return {?}
     */
    function (dataKeyvalue, index, selected) {
        var _this = this;
        if (!selected) {
            for (var /** @type {?} */ i = 0; i < this.service.multipleDeletion.length; i++) {
                if (dataKeyvalue == this.service.multipleDeletion[i]) {
                    this.service.multipleDeletion.splice(i, 1);
                    break;
                }
            }
        }
        else {
            this.displayData.subscribe(function (resp) {
                _this.service.multipleDeletion.push(resp[index][_this.multipleSelectKey]);
            }).unsubscribe();
        }
        // console.log('left '+dataKeyvalue,this.service.multipleDeletion) ;
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.getSearchColumns = /**
     * @return {?}
     */
    function () {
        return (this.hasAddButton) ? (this.enableDataExports) ? 'col-md-6 search-container' : 'col-md-7 search-container' :
            (this.enableDataExports) ? 'col-md-7 search-container' : 'col-md-8 search-container';
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.disablePrevtButton = /**
     * @return {?}
     */
    function () {
        return Math.ceil(this.service.dataOffset / this.limit) <= 1;
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.disableNextButton = /**
     * @return {?}
     */
    function () {
        return Math.ceil(this.service.dataOffset / this.limit) == Math.ceil(this.service.totalItems / this.limit);
    };
    /**
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.isLazyloadingEnabled = /**
     * @return {?}
     */
    function () {
        return this.lazyloadingConfig.hasOwnProperty("apiOffsetKey") && this.lazyloadingConfig.apiOffsetKey;
    };
    /**
     * @param {?} type
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.nextPrevItem = /**
     * @param {?} type
     * @return {?}
     */
    function (type) {
        var _this = this;
        if (this.isLazyloadingEnabled()) {
            this.service.loadFinish = false;
            this.service.getDataLength().then(function (dataLength) {
                _this.service.chageDataTable([]);
                _this.service.dataOffset = (type == 'prev') ? ((_this.service.dataOffset - _this.limit) - _this.limit) : _this.service.dataOffset;
                var /** @type {?} */ url = (_this.isLazyloadingEnabled()) ? _this.dataUrl + '&' + _this.lazyloadingConfig.apiOffsetKey + '=' + _this.service.dataOffset + '&' + _this.lazyloadingConfig.apiSearchKey + '=' : _this.dataUrl;
                _this.service.loadFlxDataTableData(url);
            }).catch(function (e) {
                //console.log('error',e) ;
            });
            return;
        }
        // Paginate if lazyloading is disabled
        if (type == 'prev') {
            this.paginateDatatableRecord((this.service.dataOffset - this.limit) - this.limit);
        }
        else {
            if (this.service.dataOffset < this.limit) {
                this.paginateDatatableRecord(this.service.dataOffset + (this.limit - 1));
            }
            else {
                this.paginateDatatableRecord(this.service.dataOffset);
            }
        }
    };
    /**
     * @param {?=} searchString
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.filterData = /**
     * @param {?=} searchString
     * @return {?}
     */
    function (searchString) {
        var _this = this;
        if (searchString === void 0) { searchString = ''; }
        if (searchString == '') {
            this.isSearching = false;
        }
        else {
            this.isSearching = true;
        }
        this.changeDisplayData([]);
        this.service.flxData.subscribe(function (data) {
            var /** @type {?} */ searchResults = [];
            //If no string provided. Register all the previous data to the dataset
            if (searchString.trim() == '') {
                _this.changeDisplayData(_this.searchDataTempOffset);
                return;
            }
            //Check if searchKeys are set else use dataKeys as searchKeys
            var /** @type {?} */ searchKeys = (_this.searchKeys.length < 1) ? _this.dataKeys : _this.searchKeys;
            for (var /** @type {?} */ i = 0; i < data.length; i++) {
                //Variable to check if data is found
                var /** @type {?} */ found = -1;
                for (var /** @type {?} */ x = 0; x < searchKeys.length; x++) {
                    try {
                        if (data[i][String(searchKeys[x])].toLowerCase().indexOf(searchString.toLocaleLowerCase()) !== -1) {
                            found = i;
                            break;
                        }
                    }
                    catch (/** @type {?} */ e) { }
                }
                //If found push the index of the data to the searchResults variable
                if (found > -1) {
                    searchResults.push(data[found]);
                }
            }
            _this.searchResultFound = searchResults;
            //Register the results to the dataset
            //Register the results to the dataset
            _this.changeDisplayData(searchResults);
            _this.setColumnWidths();
        }).unsubscribe();
    };
    /**
     * @param value offset value
     */
    /**
     * @param {?} value offset value
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.paginateDatatable = /**
     * @param {?} value offset value
     * @return {?}
     */
    function (value) {
        var _this = this;
        // Check if lazy loading is enabled
        if (this.isLazyloadingEnabled()) {
            this.service.loadFinish = false;
            // Subscribe to get the data length
            this.service.getDataLength().then(function () {
                _this.service.chageDataTable([]);
                // Check if all is selected to prevent NAN value
                if (value != 'all') {
                    _this.service.dataOffset = parseInt(value);
                }
                // setup url
                var /** @type {?} */ url = (_this.isLazyloadingEnabled()) ? _this.dataUrl + '&' + _this.lazyloadingConfig['apiOffsetKey'] + '=' + value + '&' + _this.lazyloadingConfig.apiSearchKey + '=' : _this.dataUrl;
                // paginate
                // paginate
                _this.service.loadFlxDataTableData(url, false);
            }).catch(function (e) {
                // console.log('error',e) ;
            });
            return;
        }
        this.paginateDatatableRecord(value);
    };
    /**
     *
     * @param value pagination number
     * Perform pagination to the dataset
     * @return
     */
    /**
     *
     * @param {?} value pagination number
     * Perform pagination to the dataset
     * @return {?}
     */
    FlxUiDatatableComponent.prototype.paginateDatatableRecord = /**
     *
     * @param {?} value pagination number
     * Perform pagination to the dataset
     * @return {?}
     */
    function (value) {
        var _this = this;
        if (this.lazyloadingConfig.hasOwnProperty("apiOffsetKey") && this.lazyloadingConfig['apiOffsetKey']) {
            this.service.loadFinish = false;
            this.service.getDataLength().then(function (dataLength) {
                _this.service.chageDataTable([]);
                _this.service.dataOffset = parseInt(value) + _this.limit;
                _this.service.loadFlxDataTableData(_this.dataUrl + '&' + _this.lazyloadingConfig.apiOffsetKey + '=' + value + '&' + _this.lazyloadingConfig.apiSearchKey + '=');
                _this.setColumnWidths();
            }).catch(function (e) {
                // console.log('error',e) ;
            });
            return;
        }
        var /** @type {?} */ num = parseInt(value);
        if (num <= 0) {
            this.offset = 1;
            this.service.dataOffset = this.limit;
        }
        else {
            if (value != 'all') {
                this.offset = num + 1;
                this.service.dataOffset = num + this.limit;
            }
            else {
                this.offset = 1;
            }
        }
        this.service.flxData.subscribe(function (data) {
            if (value !== 'all') {
                var /** @type {?} */ paginateResult = [];
                for (var /** @type {?} */ i = value; i < (_this.limit + parseInt(value)); i++) {
                    if (data[i]) {
                        paginateResult.push(data[i]);
                    }
                }
                if (paginateResult.length > 0) {
                    _this.changeDisplayData(paginateResult);
                }
            }
            else {
                _this.changeDisplayData(data);
                _this.searchDataTempOffset = data;
            }
            _this.setColumnWidths();
        }).unsubscribe();
    };
    FlxUiDatatableComponent.decorators = [
        { type: Component, args: [{
                    selector: 'flx-ui-datatable',
                    template: "<div class=\"col-md-12 flx-ui-datatable-main {{ classes?.maincontainer }}\">\n    <div id=\"export_loading\" class=\"col-md-12 text-center\" style=\"display: none;margin-bottom:0.5em;color:#dddddd;font-size:13px;font-weight:bold;\">Exporting...</div>\n    <div class=\"col-md-12 flx-ui-datatable-header\">\n        <div class=\"container-fluid\">\n            <div class=\"row\">\n                <div class=\"col-xs-3 col-sm-3 pagination-select col-md-2\" style=\"position:relative;z-index: 1;\">\n                    <select class=\"form-control rmsh rmrd {{ classes?.paginationselect }}\" (change)=\"paginateDatatable($event?.target?.value)\">\n                        <option *ngFor=\"let paging of service?.pagination\" [value]=\"paging?.value\">{{ paging?.label }}</option>\n                    </select>\n                </div>\n                <div class=\"col-xs-5 col-sm-5 col-md-2 text-center flx-datatable-pagination rmpd\" style=\"position:relative;z-index: 2;\">\n                    <button mat-icon-button [ngClass]=\"{'flx-pagination-end': disablePrevtButton()}\" (click)=\"nextPrevItem('prev')\" [disabled]=\"disablePrevtButton()\" class=\"flx-ui-datatable-pagination-buttons {{ classes?.paginationButton }}\"><span class=\"fa fa-angle-double-left fa-1x\"></span> <span class=\"flx-datatable-tooltip-prev\" [ngClass]=\"{'flx-pagination-end': disablePrevtButton()}\">Previous</span> </button>\n                        <span *ngIf=\"!isSearching;else searching\">{{ service?.dataOffset | ceil: limit }} / {{ service?.totalItems | ceil: limit }}</span>\n                        <ng-template #searching>\n                            \n                        </ng-template>\n                    <button mat-icon-button [ngClass]=\"{'flx-pagination-end': disableNextButton()}\" (click)=\"nextPrevItem('next')\" [disabled]=\"disableNextButton()\" class=\"flx-ui-datatable-pagination-buttons {{ classes?.paginationButton }}\"><span class=\"fa fa-angle-double-right fa-1x\"></span> <span class=\"flx-datatable-tooltip-next\" [ngClass]=\"{'flx-pagination-end': disableNextButton()}\">Next</span></button>\n                </div>\n                <div [class]=\"'search-bar '+getSearchColumns()\">\n                    <input type=\"text\" *ngIf=\"!isLazyloadingEnabled()\" [style.background]=\"searchBar?.background\" [style.color]=\"searchBar?.textColor\" [ngStyle]=\"{border:searchBar?.borderSize +' solid '+ searchBar?.borderColor} \" (keyup)=\"filterData($event?.target?.value)\" class=\"form-control rmsh rmrd customclass\" [placeholder]=\"searchPlaceholder\">\n                    <form (ngSubmit)=\"searchDataInApi(srch?.value,srch)\" #srch=\"ngForm\" *ngIf=\"isLazyloadingEnabled()\">\n                        <div class=\"input-group\">\n                            <input type=\"text\" required name=\"searchString\" ngModel [style.background]=\"searchBar?.background\" [style.color]=\"searchBar?.textColor\" [ngStyle]=\"{border:searchBar?.borderSize +' solid '+ searchBar?.borderColor} \" class=\"form-control rmsh rmrd {{ classes?.searchbar }}\" [placeholder]=\"searchPlaceholder\">\n                            <span class=\"input-group-addon\">\n                                <button [disabled]=\"!srch?.valid\" type=\"submit\" class=\"btn btn-default btn-clear btn-md\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                        </div>\n                    </form>\n                </div>\n                <div class=\"col-md-1 text-right rmpd\" *ngIf=\"hasAddButton\">\n                    <button (click)=\"addButtonClick()\" class=\"{{ classes?.addButton }}\" [style.background]=\"addButton?.background\" [style.borderColor]=\"addButton?.background\" [style.color]=\"addButton?.textColor\"><span class=\"fa fa-plus\"></span> Add</button>\n                </div>\n                <div class=\"col-md-1 text-right rmpd export-cnt\" *ngIf=\"enableDataExports\">\n                    <div class=\"dropdown\">\n                        <button class=\"btn btn-default {{ classes?.exportButton }} dropdown-toggle\" type=\"button\" data-toggle=\"dropdown\">\n                            <i class=\"fa fa-angle-down\"></i>\n                        </button>\n                        <ul class=\"dropdown-menu dropdown-menu-export {{ classes?.exportDropdown }}\">\n                            <li class=\"dropdown-header\">{{ dataExportsConfig?.title }}. <input type=\"checkbox\" (change)=\"checkToExportOption($event?.target?.checked)\" style=\"position: relative;top:0.3em;\"> <sup style=\"font-size:10px;color:#999;\"> All</sup></li> \n                            <li class=\"divider\"></li>\n                            <li class=\"dropdown-submenu\" *ngFor=\"let export of dataExportsConfig?.exportsTo\" (click)=\"exportDocumentsAs(export)\">\n                                <a href=\"javascript:void(0)\" class=\"btn btn-default btn-sm form-control\" *ngIf=\"export=='print'\"><i class=\"glyphicon glyphicon-print\"></i> Print</a>\n                                <a href=\"javascript:void(0)\" class=\"btn btn-default btn-sm form-control\" *ngIf=\"export=='pdf'\" style=\"color:#ff0000\"><i class=\"glyphicon glyphicon-file\"></i> PDF</a>\n                                <a href=\"javascript:void(0)\" class=\"btn btn-default btn-sm form-control\" *ngIf=\"export=='excel'\" style=\"color:#009900;\"><i class=\"glyphicon glyphicon-file\"></i> Excel</a>            \n                                <a href=\"javascript:void(0)\" class=\"btn btn-default btn-sm form-control\" *ngIf=\"export=='word'\" style=\"color:#335599;\"><i class=\"glyphicon glyphicon-file\"></i> Word</a>                        \n                            </li>\n                            <li class=\"divider\"></li>\n                            <li class=\"dropdown-header\">\n                                <span  *ngIf=\"!isExportAll\">{{ (displayData | async)?.length }}</span>\n                                <span  *ngIf=\"isExportAll\">{{ (service?.flxData | async)?.length }}</span> \n                            </li>\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <div class=\"container-fluid\">\n        <div class=\"row\">\n            <div class=\"col-md-12 rmpd table-responsive flx-tabl-container\">\n                <table class=\"table {{ classes?.tableType }} th-table\">\n                    <thead class=\"{{ classes?.tableHeader }} flx-table-thead\">\n                        <tr>\n                            <!-- Actions buttons header left before numbers -->\n                            <th *ngIf=\"hasActionButtons && (actionButtonsConfig?.position=='left' && actionButtonsConfig?.beforeNumbers)\">{{ actionHeader }} \n                                <input type=\"checkbox\" [checked]=\"service?.multipleDeletion?.length>0\" (change)=\"addRemove($event?.target?.checked)\" *ngIf=\"enableMultipleSelection\">\n                                <button class=\"btn btn-danger btn-xs flx-multiple-deletion-button\" *ngIf=\"enableMultipleSelection && service?.multipleDeletion?.length>0\" (click)=\"confirmDelete()\"><span [class]=\"multipleSelectButton?.icon\"></span> {{ multipleSelectButton?.text }}</button>\n                            </th>\n\n\n                            <th *ngIf=\"!hideNumbers\">N<sup><u>o</u></sup></th>\n\n                            <!-- Actions buttons header left after numbers -->\n                            <th *ngIf=\"hasActionButtons && (actionButtonsConfig?.position=='left' && !actionButtonsConfig?.beforeNumbers)\">{{ actionHeader }} \n                                <input type=\"checkbox\" [checked]=\"service?.multipleDeletion?.length>0\" (change)=\"addRemove($event?.target?.checked)\" *ngIf=\"enableMultipleSelection\">\n                                <button class=\"btn btn-danger btn-xs flx-multiple-deletion-button\" *ngIf=\"enableMultipleSelection && service?.multipleDeletion?.length>0\" (click)=\"confirmDelete()\"><span [class]=\"multipleSelectButton?.icon\"></span> {{ multipleSelectButton?.text }}</button>\n                            </th>\n\n\n                            <th *ngFor=\"let header of headers\">{{ header }}</th>\n\n                            <!-- Actions buttons header right -->\n                            <th *ngIf=\"hasActionButtons  && (actionButtonsConfig?.position=='right')\">{{ actionHeader }} \n                                <input type=\"checkbox\" [checked]=\"service?.multipleDeletion?.length>0\" (change)=\"addRemove($event?.target?.checked)\" *ngIf=\"enableMultipleSelection\">\n                                <button class=\"btn btn-danger btn-xs flx-multiple-deletion-button\" *ngIf=\"enableMultipleSelection && service?.multipleDeletion?.length>0\" (click)=\"confirmDelete()\"><span [class]=\"multipleSelectButton?.icon\"></span> {{ multipleSelectButton?.text }}</button>\n                            </th>\n                        </tr>\n                    </thead>\n                </table>\n                <perfect-scrollbar class=\"data-scroll-content {{ classes?.dataScrollContent }}\">\n                    <table class=\"table {{ classes?.tableType }} flx-table-data\">                        \n                        <tbody class=\"flxdatatablebodyscrollbar\">\n                            <tr *ngIf=\"!service?.loadFinish\">                    \n                                <td colspan=\"20\" class=\"text-center\">\n                                    <img *ngIf=\"spinnerSrc\" [class]=\"classes?.spinner\" [src]=\"spinnerSrc\" style=\"margin-top:1em;margin-bottom:1em;\">\n                                </td>\n                            </tr>\n                            <tr class=\"flxuidatatablerow\" id=\"flxdatatable_singlerow\" *ngFor=\"let data of displayData | async;let i=index\">\n                                \n                                <!-- Buttons Left Before Numbers -->\n                                <td class=\"table-buttons\" *ngIf=\"hasActionButtons && (actionButtonsConfig?.position=='left' && actionButtonsConfig?.beforeNumbers)\" scope=\"row\">\n                                    <span *ngFor=\"let aButton of actionButtons;let buttonIndex=index\">\n                                        <button type=\"button\" (click)=\"actionButtonClicked(i,buttonIndex)\" class=\"btn {{ aButton?.class }}\">\n                                            <div class=\"toltip\" class=\"flx-tooltip\" [ngClass]=\"{'flx-tooltip-left':aButton?.tooltipPosition=='left','flx-tooltip-bottom':aButton?.tooltipPosition=='bottom','flx-tooltip-right':aButton?.tooltipPosition=='right'}\" *ngIf=\"aButton?.tooltip\">{{ aButton?.tooltip }}</div>\n                                            <span class=\"action-button-icon-left\" [class]=\"aButton?.icon\" *ngIf=\"!aButton?.iconPosition || aButton?.iconPosition!='right'\"></span>\n                                            <span class=\"button-text\"> {{ aButton?.text }} </span>\n                                            <span [class]=\"aButton?.icon\" *ngIf=\"aButton?.iconPosition=='right'\"></span>\n                                        </button>\n                                    </span> \n                                    <input type=\"checkbox\" checked (change)=\"addRemoveDeleteItem(data[multipleSelectKey],i,$event?.target?.checked)\" *ngIf=\"enableMultipleSelection && service?.multipleDeletion?.length>0\">\n                                </td>\n                                \n                                <!-- Numbers -->\n                                <td class=\"{{ classes?.tableData }}\" *ngIf=\"!hideNumbers\" style=\"color: #999;\">{{ offset+i }}</td>\n                                \n                                <!-- Buttons Left After Numbers -->\n                                <td class=\"table-buttons\" *ngIf=\"hasActionButtons && (actionButtonsConfig?.position=='left' && !actionButtonsConfig?.beforeNumbers)\" scope=\"row\">\n                                    <span *ngFor=\"let aButton of actionButtons;let buttonIndex=index\">\n                                        <button type=\"button\" (click)=\"actionButtonClicked(i,buttonIndex)\" class=\"btn {{ aButton?.class }}\">\n                                            <div class=\"toltip\" class=\"flx-tooltip\" [ngClass]=\"{'flx-tooltip-left':aButton?.tooltipPosition=='left','flx-tooltip-bottom':aButton?.tooltipPosition=='bottom','flx-tooltip-right':aButton?.tooltipPosition=='right'}\" *ngIf=\"aButton?.tooltip\">{{ aButton?.tooltip }}</div>\n                                            <span class=\"action-button-icon-left\" [class]=\"aButton?.icon\" *ngIf=\"!aButton?.iconPosition || aButton?.iconPosition!='right'\"></span>\n                                            <span class=\"button-text\"> {{ aButton?.text }} </span>\n                                            <span [class]=\"aButton?.icon\" *ngIf=\"aButton?.iconPosition=='right'\"></span>\n                                        </button>\n                                    </span> \n                                    <input type=\"checkbox\" checked (change)=\"addRemoveDeleteItem(data[multipleSelectKey],i,$event?.target?.checked)\" *ngIf=\"enableMultipleSelection && service?.multipleDeletion?.length>0\">\n                                </td>\n                                \n                                <!-- Main -->\n                                <td class=\"{{ classes?.tableData }}\" *ngFor=\"let dataKey of dataKeys;let x=index\">\n                                    <img *ngIf=\"hasImageEmbeded() && x==embedPictures?.index; else nopicture\" [class]=\"'img-fall-back ' +embedPictures?.class\" [src]=\"embedPictures?.rootFolder+data[dataKey]\" [flx-ui-datatable-img-fallback]=\"embedPictures?.fallbackUrl\" >\n                                    <ng-template #nopicture>\n                                        <section *ngIf=\"textSubstring?.atIndexes && (textSubstring?.atIndexes | haslimittext:x);else nolimittext\">\n                                            {{ textSubstring | limittext: data[dataKey] }}\n                                        </section>\n                                        <ng-template #nolimittext>\n                                            <span>{{ data[dataKey] }}</span>\n                                        </ng-template>\n                                    </ng-template> \n                                </td>\n                                <!-- Buttons -->\n                                <td class=\"table-buttons\" *ngIf=\"hasActionButtons && actionButtonsConfig?.position!='left'\">\n                                    <span *ngFor=\"let aButton of actionButtons;let buttonIndex=index\">\n                                        <button type=\"button\" (click)=\"actionButtonClicked(i,buttonIndex)\" class=\"btn {{ aButton?.class }}\">\n                                            <div class=\"toltip\" class=\"flx-tooltip\" [ngClass]=\"{'flx-tooltip-left':aButton?.tooltipPosition=='left','flx-tooltip-bottom':aButton?.tooltipPosition=='bottom','flx-tooltip-right':aButton?.tooltipPosition=='right'}\" *ngIf=\"aButton?.tooltip\">{{ aButton?.tooltip }}</div>\n                                            <span class=\"action-button-icon-left\" [class]=\"aButton?.icon\" *ngIf=\"!aButton?.iconPosition || aButton?.iconPosition!='right'\"></span>\n                                            <span class=\"button-text\"> {{ aButton?.text }} </span>\n                                            <span [class]=\"aButton?.icon\" *ngIf=\"aButton?.iconPosition=='right'\"></span>\n                                        </button>\n                                    </span> \n                                    <input type=\"checkbox\" checked (change)=\"addRemoveDeleteItem(data[multipleSelectKey],i,$event?.target?.checked)\" *ngIf=\"enableMultipleSelection && service?.multipleDeletion?.length>0\">\n                                </td>\n                            </tr>\n                            <tr *ngIf=\"tData?.length<1\">\n                                <td colspan=\"10\" class=\"text-center\" *ngIf=\"service?.loadFinish\">\n                                    <span style=\"color:#ff0000;font-size:13px;\">No data found</span> <br>\n                                    <button type=\"button\" style=\"margin-top:1em;\" (click)=\"reload()\" class=\"btn btn-default {{ classes?.reloadbutton }}\" color=\"primary\"><span class=\"fa fa-refresh\"></span> Reload</button>\n                                </td>\n                            </tr>\n                        </tbody>\n                    </table>\n                </perfect-scrollbar>\n                <div class=\"row\">\n                    <div class=\"col-md-12 rmpd flx-total-data\" *ngIf=\"showBottomInfo\">\n                        <div class=\"row\" *ngIf=\"!isSearching;else bottomInfoSearching\">\n                            <div class=\"col-md-4 text-left rmpd\">Total pagination: <span> {{ service?.totalItems | ceil: limit }}</span></div>\n                            <div class=\"col-md-4 text-center rmpd\"># of items per pagination: <span>{{ limit }}</span></div>\n                            <div class=\"col-md-4 text-right rmpd\">Total items: <span>{{ (service?.flxData | async)?.length }}</span></div>\n                        </div>\n                        <ng-template #bottomInfoSearching>\n                            <div class=\"row\">\n                                <div class=\"col-md-12 text-right rmpd\">Total search result: <span>{{ searchResultFound?.length }}</span></div>\n                            </div>\n                        </ng-template>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>",
                    styles: [".flx-ui-datatable-main{background-color:#fff;padding-top:1em;padding-bottom:1em}.flx-ui-datatable-main .btn-danger{background-color:#f50057;border:1px solid #f50057;box-shadow:0 3px 5px 1px #ddd;-moz-box-shadow:0 3px 5px 1px #ddd;-webkit-box-shadow:0 3px 5px 1px #ddd;-o-box-shadow:0 3px 5px 1px #ddd;-ms-box-shadow:0 3px 5px 1px #ddd;border-radius:3px;margin-left:.3em}.flx-ui-datatable-main #flxdatatablebodyscrollbar,.flx-ui-datatable-main .table-responsive,.flx-ui-datatable-main .table-responsive table{width:100%}.flx-ui-datatable-main img.img-fall-back{width:30px;height:30px}.flx-ui-datatable-main .pagination-select input[type=text],.flx-ui-datatable-main .pagination-select select,.flx-ui-datatable-main .search-bar input[type=text],.flx-ui-datatable-main .search-bar select{border-top:none!important;border-left:none!important;border-right:none!important;border-bottom:2px solid #ddd!important;border-radius:0!important;box-shadow:0 0 0 0 transparent!important;-moz-box-shadow:0 0 0 0 transparent!important;-webkit-box-shadow:0 0 0 0 transparent!important;-o-box-shadow:0 0 0 0 transparent!important;-ms-box-shadow:0 0 0 0 transparent!important}.flx-ui-datatable-main .pagination-select input[type=text]:focus,.flx-ui-datatable-main .pagination-select select:focus,.flx-ui-datatable-main .search-bar input[type=text]:focus,.flx-ui-datatable-main .search-bar select:focus{border-bottom-color:#359!important;transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;-o-transition:.5s;-ms-transition:.5s}.flx-ui-datatable-main .pagination-select select,.flx-ui-datatable-main .search-bar select{-webkit-appearance:none;appearance:none;-moz-appearance:none}.flx-ui-datatable-main .dropdown-toggle::after{display:none}.flx-ui-datatable-main .dropdown-menu-export{margin-left:-130px;padding-left:1em;padding-right:1em;width:100px!important;margin-top:1em;border:1px solid #ddd!important}.flx-ui-datatable-main .dropdown-menu-export::before{content:\"\";width:auto;height:auto;position:absolute;top:-20px;right:3px;border:10px solid;border-color:transparent transparent #ddd}.flx-ui-datatable-main .flx-datatable-pagination{padding-top:.5em}.flx-ui-datatable-main .flx-datatable-pagination button{width:35px!important;height:35px!important;border-radius:50em!important;border:none!important;box-shadow:0 3px 10px 0 #b3c4e6;-moz-box-shadow:0 3px 10px 0 #b3c4e6;-webkit-box-shadow:0 3px 10px 0 #b3c4e6;-o-box-shadow:0 3px 10px 0 #b3c4e6;-ms-box-shadow:0 3px 10px 0 #b3c4e6;background-color:#359;color:#fff;font-size:23px;font-weight:700;position:absolute;top:0}.flx-ui-datatable-main .flx-datatable-pagination button:first-child{left:0}.flx-ui-datatable-main .flx-datatable-pagination button:first-child .flx-datatable-tooltip-prev{position:absolute;left:0;font-size:13px;font-weight:400;color:#fff;background-color:#359;padding-left:.3em;padding-right:.3em;border-radius:3px;margin-left:-57px;margin-top:.3em;box-shadow:0 3px 10px 0 #b3c4e6!important;-moz-box-shadow:0 3px 10px 0 #b3c4e6!important;-webkit-box-shadow:0 3px 10px 0 #b3c4e6!important;-o-box-shadow:0 3px 10px 0 #b3c4e6!important;-ms-box-shadow:0 3px 10px 0 #b3c4e6!important;visibility:hidden}.flx-ui-datatable-main .flx-datatable-pagination button:hover>span.flx-datatable-tooltip-next,.flx-ui-datatable-main .flx-datatable-pagination button:hover>span.flx-datatable-tooltip-prev{visibility:visible}.flx-ui-datatable-main .flx-datatable-pagination .flx-pagination-end{background-color:#f50057!important;box-shadow:0 3px 10px 0 #ffc2d8!important;-moz-box-shadow:0 3px 10px 0 #ffc2d8!important;-webkit-box-shadow:0 3px 10px 0 #ffc2d8!important;-o-box-shadow:0 3px 10px 0 #ffc2d8!important;-ms-box-shadow:0 3px 10px 0 #ffc2d8!important;cursor:not-allowed}.flx-ui-datatable-main .flx-datatable-pagination .flx-pagination-end:hover>span.flx-datatable-tooltip-next,.flx-ui-datatable-main .flx-datatable-pagination .flx-pagination-end:hover>span.flx-datatable-tooltip-prev{visibility:hidden}.flx-ui-datatable-main .flx-datatable-pagination button:last-child{right:0}.flx-ui-datatable-main .flx-datatable-pagination button:last-child .flx-datatable-tooltip-next{position:absolute;left:0;font-size:13px;font-weight:400;color:#fff;background-color:#359;padding-left:.3em;padding-right:.3em;border-radius:3px;margin-left:35px;margin-top:.5em;box-shadow:0 3px 10px 0 #b3c4e6!important;-moz-box-shadow:0 3px 10px 0 #b3c4e6!important;-webkit-box-shadow:0 3px 10px 0 #b3c4e6!important;-o-box-shadow:0 3px 10px 0 #b3c4e6!important;-ms-box-shadow:0 3px 10px 0 #b3c4e6!important;visibility:hidden}.flx-ui-datatable-main .export-cnt button{border-radius:50em!important}.flx-ui-datatable-main .flx-tabl-container table.th-table{margin-top:.5em}.flx-ui-datatable-main table tbody tr{padding-top:0!important}.flx-ui-datatable-main table tbody tr td{padding-top:.5em;border-top:1px solid #f0f0f0;border-bottom:1px solid #f0f0f0}.flx-ui-datatable-main table tbody tr td button{margin-right:.3em;margin-left:0}.flx-ui-datatable-main table tbody tr td button div.flx-tooltip{position:absolute;background-color:rgba(32,27,27,.808);text-align:center;font-size:13px;color:#fff;border-radius:3px;box-shadow:0 3px 20px 0 #4b4949;-moz-box-shadow:0 3px 20px 0 #4b4949;-webkit-box-shadow:0 3px 20px 0 #4b4949;-o-box-shadow:0 3px 20px 0 #4b4949;-ms-box-shadow:0 3px 20px 0 #4b4949;margin-left:-2.5em;margin-top:-2.8em;visibility:hidden;width:80px;padding:.3em .5em}.flx-ui-datatable-main table tbody tr td button .flx-tooltip-left{margin-left:-95px!important;margin-top:-.3em!important}.flx-ui-datatable-main table tbody tr td button .flx-tooltip-bottom{margin-top:2.3em!important}.flx-ui-datatable-main table tbody tr td button .flx-tooltip-right{margin-left:28px!important;margin-top:-.3em!important}.flx-ui-datatable-main table tbody tr td button:hover>div.flx-tooltip{transition:.3s;visibility:visible}.flx-ui-datatable-main table tbody tr td.table-buttons{padding-top:.2em;padding-bottom:.2em}.flx-ui-datatable-main table tbody tr:nth-of-type(even){background-color:#f8f9fa}.flx-ui-datatable-main table tbody tr:nth-of-type(odd){background-color:#fff}.flx-ui-datatable-main .btn-danger:hover{background-color:#ff146b;border:1px solid #ff146b;box-shadow:0 3px 10px 1px #ff5fb6;-moz-box-shadow:0 3px 10px 1px #ff5fb6;-webkit-box-shadow:0 3px 10px 1px #ff5fb6;-o-box-shadow:0 3px 10px 1px #ff5fb6;-ms-box-shadow:0 3px 10px 1px #ff5fb6;transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;-o-transition:.5s;-ms-transition:.5s}.flx-ui-datatable-main .btn-danger:focus{background-color:#f50057;border:1px solid #f50057}.flx-ui-datatable-main .btn-white{background-color:#fff}.flx-ui-datatable-main .btn-dark{background-color:#222!important}.flx-ui-datatable-main .btn-primary{background-color:#359;color:#fff;border:1px solid #359;box-shadow:0 3px 5px 1px #ddd;-moz-box-shadow:0 3px 5px 1px #ddd;-webkit-box-shadow:0 3px 5px 1px #ddd;-o-box-shadow:0 3px 5px 1px #ddd;-ms-box-shadow:0 3px 5px 1px #ddd;border-radius:3px}.flx-ui-datatable-main .btn-primary:hover{background-color:#4769ad;border:1px solid #4769ad;box-shadow:0 3px 10px 0 #b3c4e6;-moz-box-shadow:0 3px 10px 0 #b3c4e6;-webkit-box-shadow:0 3px 10px 0 #b3c4e6;-o-box-shadow:0 3px 10px 0 #b3c4e6;-ms-box-shadow:0 3px 10px 0 #b3c4e6;transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;-o-transition:.5s;-ms-transition:.5s}.flx-ui-datatable-main .btn-primary:focus{background-color:#359;border:1px solid #359}.flx-ui-datatable-main .btn-large{padding-top:1em!important;padding-bottom:1em!important}.flx-ui-datatable-main .btn-medium{padding-top:.7em!important;padding-bottom:.7em!important}.flx-ui-datatable-main .btn-success{box-shadow:0 3px 5px 1px #ddd;-moz-box-shadow:0 3px 5px 1px #ddd;-webkit-box-shadow:0 3px 5px 1px #ddd;-o-box-shadow:0 3px 5px 1px #ddd;-ms-box-shadow:0 3px 5px 1px #ddd;border-radius:3px;background-color:#5cb85c;border:1px solid #5cb85c}.flx-ui-datatable-main .btn-success:hover{background-color:#70cc70;border:1px solid #70cc70;box-shadow:0 3px 10px 1px #9df99d;-moz-box-shadow:0 3px 10px 1px #9df99d;-webkit-box-shadow:0 3px 10px 1px #9df99d;-o-box-shadow:0 3px 10px 1px #9df99d;-ms-box-shadow:0 3px 10px 1px #9df99d;transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;-o-transition:.5s;-ms-transition:.5s}.flx-ui-datatable-main .btn-success:focus{background-color:#5cb85c;border:1px solid #5cb85c}.flx-ui-datatable-main .btn-default{background-color:#fff;box-shadow:0 3px 5px 1px #eee;-moz-box-shadow:0 3px 5px 1px #eee;-webkit-box-shadow:0 3px 5px 1px #eee;-o-box-shadow:0 3px 5px 1px #eee;-ms-box-shadow:0 3px 5px 1px #eee;border-radius:3px;border:1px solid #ddd}.flx-ui-datatable-main .btn-default:hover{background-color:#fff;border:1px solid #e7e7e7;box-shadow:0 3px 10px 1px #e2e2e2;-moz-box-shadow:0 3px 10px 1px #e2e2e2;-webkit-box-shadow:0 3px 10px 1px #e2e2e2;-o-box-shadow:0 3px 10px 1px #e2e2e2;-ms-box-shadow:0 3px 10px 1px #e2e2e2;transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;-o-transition:.5s;-ms-transition:.5s}.flx-ui-datatable-main .btn-default:focus{background-color:#fff;border:1px solid #ddd}.flx-ui-datatable-main .btn-secondary{box-shadow:0 3px 5px 1px #ddd;-moz-box-shadow:0 3px 5px 1px #ddd;-webkit-box-shadow:0 3px 5px 1px #ddd;-o-box-shadow:0 3px 5px 1px #ddd;-ms-box-shadow:0 3px 5px 1px #ddd;border-radius:3px;background-color:#1e88e5;color:#fff}.flx-ui-datatable-main .btn-secondary:hover{color:#fff;background-color:#2892ef;border:1px solid #2892ef;box-shadow:0 3px 10px 1px #55bfff;-moz-box-shadow:0 3px 10px 1px #55bfff;-webkit-box-shadow:0 3px 10px 1px #55bfff;-o-box-shadow:0 3px 10px 1px #55bfff;-ms-box-shadow:0 3px 10px 1px #55bfff;transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;-o-transition:.5s;-ms-transition:.5s}.flx-ui-datatable-main .btn-secondary:focus{color:#fff}.flx-ui-datatable-main .pagination-button{background-color:#359;color:#fff}.flx-ui-datatable-main .table-font{font-family:Khula,sans-serif!important}.flx-ui-datatable-main .table-header-icon{position:absolute;right:.2em;width:80px;height:80px;font-size:50px;margin-top:-30px;border-radius:5px!important}.flx-ui-datatable-main .table-title{background-color:#359;color:#fff;border-radius:2px;padding:1em;font-size:15px;font-weight:700;margin-bottom:1.5em;font-family:Roboto,sans-serif;box-shadow:0 1px 5px 1px #ddd;-moz-box-shadow:0 1px 5px 1px #ddd;-webkit-box-shadow:0 1px 5px 1px #ddd;-o-box-shadow:0 1px 5px 1px #ddd;-ms-box-shadow:0 1px 5px 1px #ddd}.flx-ui-datatable-main .danger{background-color:#f50057;color:#fff}.flx-ui-datatable-main .primary{background-color:#359;color:#fff}.flx-ui-datatable-main .success{background-color:#5cb85c;color:#fff}.flx-ui-datatable-main .default{background-color:#fff;color:#000}.flx-ui-datatable-main .secondary{background-color:#1e88e5;color:#fff}.flx-ui-datatable-main .btn-clear{border:none!important;box-shadow:none!important}.flx-ui-datatable-main .input-group,.flx-ui-datatable-main .input-group input{background-color:transparent!important}.flx-ui-datatable-main .input-group-addon{border:none!important;padding:0!important;box-shadow:none!important;background-color:transparent!important}.flx-ui-datatable-main .input-group-addon button{border:1px solid transparent!important;box-shadow:none!important;border-top:none!important;border-bottom:none!important;background-color:transparent!important;border-radius:50em!important;color:#359;width:30px;height:30px}.flx-ui-datatable-main .input-group-addon button i{font-size:18px}.flx-ui-datatable-main .input-group-addon button:disabled{background-color:transparent!important}.flx-ui-datatable-main .input-group-addon button:disabled i{color:#f50057}.flx-ui-datatable-main .data-scroll-content{max-width:100%;max-height:400px;margin-top:-1em}.flx-ui-datatable-main .data-scroll-content table tbody tr:first-child td,.flx-ui-datatable-main .flx-table-thead tr th{border-top:none!important}"]
                },] },
    ];
    /** @nocollapse */
    FlxUiDatatableComponent.ctorParameters = function () { return [
        { type: FormBuilder },
        { type: FlxUiDatatableService }
    ]; };
    FlxUiDatatableComponent.propDecorators = {
        classes: [{ type: Input }],
        headers: [{ type: Input }],
        lazyloadingConfig: [{ type: Input }],
        embedPictures: [{ type: Input }],
        dataKeys: [{ type: Input }],
        enableDataExports: [{ type: Input }],
        dataExportsConfig: [{ type: Input }],
        showBottomInfo: [{ type: Input }],
        searchKeys: [{ type: Input }],
        dataSrcKey: [{ type: Input }],
        hasActionButtons: [{ type: Input }],
        hideNumbers: [{ type: Input }],
        enableMultipleSelection: [{ type: Input }],
        multipleSelectKey: [{ type: Input }],
        hasAddButton: [{ type: Input }],
        dataUrl: [{ type: Input }],
        actionButtonStart: [{ type: Input }],
        multipleSelectButton: [{ type: Input }],
        searchPlaceholder: [{ type: Input }],
        actionHeader: [{ type: Input }],
        limit: [{ type: Input }],
        spinnerSrc: [{ type: Input }],
        actionButtons: [{ type: Input }],
        paginationButtons: [{ type: Input }],
        tableHeader: [{ type: Input }],
        searchButton: [{ type: Input }],
        addButton: [{ type: Input }],
        searchBar: [{ type: Input }],
        actionButtonsConfig: [{ type: Input }],
        firstActionButtonClicked: [{ type: Output }],
        secondActionButtonClicked: [{ type: Output }],
        thirdActionButtonClicked: [{ type: Output }],
        multipleSelectClicked: [{ type: Output }],
        addButtonClicked: [{ type: Output }],
        textSubstring: [{ type: Input }],
        conditionManipulator: [{ type: Input }]
    };
    return FlxUiDatatableComponent;
}());
var ImageFallBack = /** @class */ (function () {
    function ImageFallBack(el) {
        this.isApplied = false;
        this.EVENT_TYPE = 'error';
        this.el = el.nativeElement;
        this.el.addEventListener(this.EVENT_TYPE, this.onError.bind(this));
    }
    /**
     * @return {?}
     */
    ImageFallBack.prototype.onError = /**
     * @return {?}
     */
    function () {
        this.removeEvents();
        if (!this.isApplied) {
            this.isApplied = true;
            this.el.setAttribute('src', this.imgSrc);
        }
    };
    /**
     * @return {?}
     */
    ImageFallBack.prototype.removeEvents = /**
     * @return {?}
     */
    function () {
        this.el.removeEventListener(this.EVENT_TYPE, this.onError);
    };
    /**
     * @return {?}
     */
    ImageFallBack.prototype.ngOnDestroy = /**
     * @return {?}
     */
    function () {
        this.removeEvents();
    };
    ImageFallBack.decorators = [
        { type: Directive, args: [{
                    selector: '[flx-ui-datatable-img-fallback]'
                },] },
    ];
    /** @nocollapse */
    ImageFallBack.ctorParameters = function () { return [
        { type: ElementRef }
    ]; };
    ImageFallBack.propDecorators = {
        imgSrc: [{ type: Input, args: ['flx-ui-datatable-img-fallback',] }]
    };
    return ImageFallBack;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var Ceil = /** @class */ (function () {
    function Ceil() {
    }
    /**
     * @param {?} value
     * @param {?} limit
     * @return {?}
     */
    Ceil.prototype.transform = /**
     * @param {?} value
     * @param {?} limit
     * @return {?}
     */
    function (value, limit) {
        return Math.ceil(value / limit);
    };
    Ceil.decorators = [
        { type: Pipe, args: [{
                    name: 'ceil'
                },] },
    ];
    /** @nocollapse */
    Ceil.ctorParameters = function () { return []; };
    return Ceil;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var HasLimitText = /** @class */ (function () {
    function HasLimitText(service) {
        this.service = service;
    }
    /**
     * @param {?} array
     * @param {?} indexReached
     * @return {?}
     */
    HasLimitText.prototype.transform = /**
     * @param {?} array
     * @param {?} indexReached
     * @return {?}
     */
    function (array, indexReached) {
        var /** @type {?} */ found;
        try {
            for (var array_1 = __values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
                var i = array_1_1.value;
                if (i == indexReached) {
                    found = true;
                    break;
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return found;
        var e_1, _a;
    };
    HasLimitText.decorators = [
        { type: Pipe, args: [{
                    name: 'haslimittext'
                },] },
    ];
    /** @nocollapse */
    HasLimitText.ctorParameters = function () { return [
        { type: FlxUiDatatableService }
    ]; };
    return HasLimitText;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var LimitText = /** @class */ (function () {
    function LimitText(service) {
        this.service = service;
    }
    /**
     * @param {?} mainpulationConfig
     * @param {?} text
     * @return {?}
     */
    LimitText.prototype.transform = /**
     * @param {?} mainpulationConfig
     * @param {?} text
     * @return {?}
     */
    function (mainpulationConfig, text) {
        var /** @type {?} */ from = (mainpulationConfig.hasOwnProperty("from")) ? mainpulationConfig['from'] : 0;
        var /** @type {?} */ to = (mainpulationConfig.hasOwnProperty("to")) ? mainpulationConfig["to"] : text.length;
        var /** @type {?} */ appendDots = (mainpulationConfig.hasOwnProperty("appendDots")) ? mainpulationConfig["appendDots"] : "";
        var /** @type {?} */ txt = "";
        if (text.length > to) {
            txt = text.substring(from, to) + appendDots;
        }
        else {
            txt = text;
        }
        return txt;
    };
    LimitText.decorators = [
        { type: Pipe, args: [{
                    name: 'limittext'
                },] },
    ];
    /** @nocollapse */
    LimitText.ctorParameters = function () { return [
        { type: FlxUiDatatableService }
    ]; };
    return LimitText;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var ProcessedData = /** @class */ (function () {
    function ProcessedData(service) {
        this.service = service;
    }
    /**
     * @param {?} dataIndex
     * @return {?}
     */
    ProcessedData.prototype.transform = /**
     * @param {?} dataIndex
     * @return {?}
     */
    function (dataIndex) {
        var /** @type {?} */ isProcessed = false;
        var /** @type {?} */ foundIndex = -1;
        for (var /** @type {?} */ i = 0; i < this.service.processedData.length; i++) {
            if (i == dataIndex) {
                isProcessed = true;
                foundIndex = i;
            }
        }
        if (foundIndex < 0) {
            this.service.processedData.push(dataIndex);
        }
        return isProcessed;
    };
    ProcessedData.decorators = [
        { type: Pipe, args: [{
                    name: 'isprocessed'
                },] },
    ];
    /** @nocollapse */
    ProcessedData.ctorParameters = function () { return [
        { type: FlxUiDatatableService }
    ]; };
    return ProcessedData;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
var /** @type {?} */ DEFAULT_PERFECT_SCROLLBAR_CONFIG = {
    suppressScrollX: true
};
var ɵ0 = DEFAULT_PERFECT_SCROLLBAR_CONFIG;
var FlxUiDatatableModule = /** @class */ (function () {
    function FlxUiDatatableModule() {
    }
    FlxUiDatatableModule.decorators = [
        { type: NgModule, args: [{
                    imports: [
                        CommonModule, ReactiveFormsModule, FormsModule, HttpModule, PerfectScrollbarModule
                    ],
                    declarations: [
                        FlxUiDatatableComponent, Ceil, ImageFallBack, HasLimitText, LimitText, ProcessedData
                    ],
                    exports: [FlxUiDatatableComponent, Ceil],
                    providers: [FlxUiDatatableService,
                        {
                            provide: PERFECT_SCROLLBAR_CONFIG,
                            useValue: ɵ0
                        }]
                },] },
    ];
    return FlxUiDatatableModule;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */

export { FlxUiDataTable, FlxUiDatatableModule, FlxUiDatatableComponent as ɵb, ImageFallBack as ɵc, FlxUiDatatableService as ɵa, Ceil as ɵd, HasLimitText as ɵe, LimitText as ɵf, ProcessedData as ɵg };

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmx4LXVpLWRhdGF0YWJsZS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vZmx4LXVpLWRhdGF0YWJsZS9saWIvZmx4LXVpLWRhdGF0YWJsZS5zZXJ2aWNlLnRzIiwibmc6Ly9mbHgtdWktZGF0YXRhYmxlL2xpYi9mbHgtdWktZGF0YXRhYmxlLXNlcnZpY2Uuc2VydmljZS50cyIsIm5nOi8vZmx4LXVpLWRhdGF0YWJsZS9saWIvZmx4LXVpLWRhdGF0YWJsZS5jb21wb25lbnQudHMiLCJuZzovL2ZseC11aS1kYXRhdGFibGUvbGliL3BpcGVzL2NlaWwucGlwZS50cyIsIm5nOi8vZmx4LXVpLWRhdGF0YWJsZS9saWIvcGlwZXMvaGFzTGltaXRUZXh0LnBpcGUudHMiLCJuZzovL2ZseC11aS1kYXRhdGFibGUvbGliL3BpcGVzL2xpbWl0VGV4dC5waXBlLnRzIiwibmc6Ly9mbHgtdWktZGF0YXRhYmxlL2xpYi9waXBlcy9wcm9jZXNzZWRkYXRhLnBpcGUudHMiLCJuZzovL2ZseC11aS1kYXRhdGFibGUvbGliL2ZseC11aS1kYXRhdGFibGUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XG5pbXBvcnQgeyBIdHRwLEhlYWRlcnMsUmVzcG9uc2V9IGZyb20gJ0Bhbmd1bGFyL2h0dHAnIDtcbmltcG9ydCB7IG1hcCxyZXRyeSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJyA7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLHBpcGUsQmVoYXZpb3JTdWJqZWN0LFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZseFVpRGF0YXRhYmxlU2VydmljZXtcbiAgLy9Vc2VyIGRhdGEgQVBJIHVybFxuICBwcml2YXRlIGRhdGFVcmw6IHN0cmluZyA9ICcnIDtcbiAgcHVibGljIGJlaGF2aW9yOiBCZWhhdmlvclN1YmplY3Q8YW55PiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55PihbXSkgO1xuICAvL0hvbGQgYWxsIGRhdGEgZnJvbSBBUElcbiAgcHVibGljIGZseERhdGEgPSB0aGlzLmJlaGF2aW9yLmFzT2JzZXJ2YWJsZSgpOyAgXG4gIC8vSGVhZGVyIHNlbGVjdCBwYWdpbmF0aW9uXG4gIHB1YmxpYyBwYWdpbmF0aW9uOiBBcnJheTxPYmplY3Q+ID0gW10gO1xuICAvL0hvbGQgdG90YWwgaXRlbXMgbG9hZGVkIGZyb20gQVBJXG4gIHB1YmxpYyB0b3RhbEl0ZW1zOiBudW1iZXIgPSAwIDtcbiAgLy9LZWVwIHRyYWNrIG9mIGN1cnJlbnQgcGFnaW5hdGlvbiBvZmZzZXRcbiAgcHVibGljIGRhdGFPZmZzZXQ6IG51bWJlciA9IDAgO1xuICAvL1VzZXIgZGVmaW5lZCBsaW1pdCBmb3IgbnVtYmVyIG9mIGl0ZW1zIHBlciBwYWdpbmF0aW9uXG4gIHB1YmxpYyBsaW1pdDogbnVtYmVyID0gMjAgO1xuICAvL0RhdGEgc291cmNlIGtleSB0byByZWFkIGZyb20gQVBJIHBheWxvYWQgcmVzcG9uc2VcbiAgcHVibGljIGRhdGFTcmNLZXk6c3RyaW5nID0gJyc7XG4gIC8vSG9sZCBpdGVtcyBzZWxlY3RlZCBmb3IgbXVsdGlwbGUgc2VsZWN0XG4gIG11bHRpcGxlRGVsZXRpb246QXJyYXk8YW55PiA9IFtdIDtcbiAgLy9Ib2xkIHN1YnNjcmlwdGlvbiBvZiBhcGkgY2FsbHMgd2hpY2ggY2FuIGJlIGNhbmNlZCBieSBjYWxsaW5nIGNhbmNlbExvYWRpbmcoKSBcbiAgbG9hZGVyOiBTdWJzY3JpcHRpb24gOyAgXG4gIC8vS2VlcCB0cmFjayBpZiBBUEkgY2FsbCBpcyBjb21wbGV0ZWRcbiAgbG9hZEZpbmlzaDogYm9vbGVhbiA9IGZhbHNlIDtcbiAgLy8gTGF6eSBsb2FkaW5nIGNvbmZpZ1xuICBwcml2YXRlIGxhenlsb2FkaW5nQ29uZmlnOiBhbnkgPSB7fSA7XG4gIHB1YmxpYyBwcm9jZXNzZWREYXRhOiBhbnkgPSB7fSA7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBodHRwOiBIdHRwKXtcbiAgICAgIFxuICB9XG5cbiAgcHVibGljIHNldExhenlsb2FkaW5nQ29uZmlnKGNvbmZpZzphbnkpe1xuICAgIHRoaXMubGF6eWxvYWRpbmdDb25maWcgPSBjb25maWcgO1xuICB9XG5cbiAgLy9HRVQgcmVxdWVzdCB0byB1c2VyJ3MgQVBJIHVybFxuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSB1cmwgVXNlciBhcGkgcnVsXG4gICAqL1xuICBwdWJsaWMgZ2V0RGF0YSh1cmw6c3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+e1xuICAgICAgbGV0IGhlYWRlcnM6IEhlYWRlcnMgPSBuZXcgSGVhZGVycygpIDtcbiAgICAgIGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSA7XG4gICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwse2hlYWRlcnM6aGVhZGVyc30pLnBpcGUocmV0cnkoNSksbWFwKChyZXNwb25zZTogUmVzcG9uc2UpID0+IHJlc3BvbnNlLmpzb24oKSkpIDtcbiAgfVxuXG4gIC8vUG9zdCByZXF1ZXN0IGZvciBkYXRhIGV4cG9ydFxuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSB1cmwgU2VydmljZSBhcGkgdXJsXG4gICAqIEBwYXJhbSBpZCBEYXRhdHlwZSBpZCB0byBleHBvcnRcbiAgICogQHBhcmFtIGRhdGEgRGF0YSB0byBleHBvcnRcbiAgICovXG4gIHB1YmxpYyBwb3N0RGF0YSh1cmw6c3RyaW5nLGlkOmFueSxkYXRhOnN0cmluZyk6IE9ic2VydmFibGU8YW55PntcbiAgICBsZXQgaGVhZGVyczogSGVhZGVycyA9IG5ldyBIZWFkZXJzKCkgO1xuICAgIGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04JykgO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh1cmwraWQsZGF0YSx7aGVhZGVyczpoZWFkZXJzfSkucGlwZShtYXAoKHJlc3A6IFJlc3BvbnNlKSA9PiByZXNwLmpzb24oKSkpIDtcbiAgfVxuXG4gIC8qKlxuICAgKiBcbiAgICogQHBhcmFtIGRhdGFVcmwgU2V0IGRhdGF1cmxcbiAgICovXG4gIHB1YmxpYyBzZXREYXRhVXJsKGRhdGFVcmw6c3RyaW5nKTp2b2lke1xuICAgIHRoaXMuZGF0YVVybCA9IGRhdGFVcmwgO1xuICB9XG5cbiAgLy9HZXQgZGF0YSB1cmwgXG4gIHB1YmxpYyBnZXREYXRhVXJsKCk6c3RyaW5ne1xuICAgIHJldHVybiB0aGlzLmRhdGFVcmwgO1xuICB9XG5cbiAgLyoqXG4gICAqIFxuICAgKiBAcGFyYW0gZGF0YSBSZWdpc3RlciBuZXcgZGF0YSBmcm9tIHVzZXIgQVBJXG4gICAqL1xuICBwdWJsaWMgY2hhZ2VEYXRhVGFibGUoZGF0YTphbnkpe1xuICAgIHRoaXMuYmVoYXZpb3IubmV4dChkYXRhKSA7XG4gIH1cblxuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSBudW1iZXJPZkxpc3QgVG90YWwgbnVtYmVyIG9mIGxpc3RcbiAgICogQHBhcmFtIGxpbWl0IFBhZ2luYXRpb24gbGltaXRcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUGFnaW5hdGlvbihudW1iZXJPZkxpc3Q6bnVtYmVyLGxpbWl0Om51bWJlcik6IEFycmF5PE9iamVjdD57XG4gICAgbGV0IG9iajogQXJyYXk8T2JqZWN0PiA9IFtdIDtcbiAgICBsZXQgY291bnRlcjogbnVtYmVyID0gMSA7XG4gICAgZm9yKGxldCBpPTA7aTxudW1iZXJPZkxpc3Q7aSs9bGltaXQpe1xuICAgICAgICBvYmoucHVzaCh7bGFiZWw6Y291bnRlcix2YWx1ZTppfSkgO1xuICAgICAgICBjb3VudGVyKysgO1xuICAgIH1cbiAgICBpZighdGhpcy5pc0xhenlMb2FkaW5nRW5hYmxlZCl7XG4gICAgICBvYmoucHVzaCh7IGxhYmVsOiAnQWxsJywgdmFsdWU6ICdhbGwnIH0pO1xuICAgIH1cbiAgICByZXR1cm4gb2JqIDtcbiAgfVxuXG4gIHB1YmxpYyBpc0xhenlMb2FkaW5nRW5hYmxlZCgpe1xuICAgIHJldHVybiB0aGlzLmxhenlsb2FkaW5nQ29uZmlnLmhhc093blByb3BlcnR5KFwiYXBpT2Zmc2V0S2V5XCIpICYmIHRoaXMubGF6eWxvYWRpbmdDb25maWcuYXBpT2Zmc2V0S2V5IDtcbiAgfVxuXG4gIC8vRXZlbnQgdG8gbG9hZCBkYXRhIGZyb20gdXNlcnMgYXBpXG4gIHB1YmxpYyBsb2FkRmx4RGF0YVRhYmxlRGF0YShkYXRhVXJsOnN0cmluZyxzZXRTZWxlY3RQYWdpbmF0aW9uOmJvb2xlYW49dHJ1ZSl7XG4gICAgdGhpcy5sb2FkRmluaXNoID0gZmFsc2UgO1xuICAgICAgdGhpcy5sb2FkZXIgPSB0aGlzLmdldERhdGEoZGF0YVVybCkuc3Vic2NyaWJlKChyZXNwb25zZURhdGEpID0+IHtcbiAgICAgICAgICB0cnl7XG4gICAgICAgICAgICAgIHRoaXMubXVsdGlwbGVEZWxldGlvbiA9IFtdIDtcbiAgICAgICAgICAgICAgdmFyIGRhdGEgPSAodGhpcy5kYXRhU3JjS2V5KSA/IHJlc3BvbnNlRGF0YVt0aGlzLmRhdGFTcmNLZXldIDogcmVzcG9uc2VEYXRhO1xuICAgICAgICAgICAgICB0aGlzLmNoYWdlRGF0YVRhYmxlKGRhdGEpIDtcbiAgICAgICAgICAgICAgaWYodGhpcy5pc0xhenlMb2FkaW5nRW5hYmxlZCgpKXsgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdGhpcy50b3RhbEl0ZW1zID0gcmVzcG9uc2VEYXRhLnRvdGFsIDtcbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgMSBwYWdpbmF0aW9uIG91dCBvZiB6ZXJvIHByb2JsZW0gMS8wICBpbnN0ZWFkIG9mIDAvMCBpZiBubyBkYXRhIGlzIGNvbW1pbmdcbiAgICAgICAgICAgICAgICBpZihkYXRhLmxlbmd0aD4wKXtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YU9mZnNldCA9IHRoaXMuZGF0YU9mZnNldCt0aGlzLmxpbWl0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICAgICAgdGhpcy50b3RhbEl0ZW1zID0gZGF0YS5sZW5ndGggO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YU9mZnNldCA9IDE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYoc2V0U2VsZWN0UGFnaW5hdGlvbil7XG4gICAgICAgICAgICAgICAgaWYodGhpcy5pc0xhenlMb2FkaW5nRW5hYmxlZCgpKXtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFnaW5hdGlvbiA9IHRoaXMuY3JlYXRlUGFnaW5hdGlvbihyZXNwb25zZURhdGEudG90YWwsIHRoaXMubGltaXQpO1xuICAgICAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYWdpbmF0aW9uID0gdGhpcy5jcmVhdGVQYWdpbmF0aW9uKGRhdGEubGVuZ3RoLCB0aGlzLmxpbWl0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5sb2FkRmluaXNoID0gdHJ1ZTtcbiAgICAgICAgICB9Y2F0Y2goZSl7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdFcnJvciBpbiByZWFkaW5nIGRhdGEgaW4gJyxlKSA7XG4gICAgICAgICAgfVxuICAgICAgfSwoZSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2FkRmluaXNoID0gdHJ1ZSA7XG4gICAgICB9KSlcbiAgfVxuXG4gIC8vQ2FuY2VsIGFwaSBHRVQgcmVxdWVzdCB0byBhcGlcbiAgcHVibGljIGNhbmNlbExvYWRpbmcoKXtcbiAgICB0aGlzLmxvYWRlci51bnN1YnNjcmliZSgpIDtcbiAgfSAgXG5cbiAgLy9TZXQgc291cmNlIGtleSB0byByZWFkIGZyb20gcGF5bG9hZCByZXNwb25zZSBKU09OXG4gIHNldERhdGFTcmNLZXkoc3JjS2V5OnN0cmluZyk6dm9pZCB7XG4gICAgdGhpcy5kYXRhU3JjS2V5ID0gc3JjS2V5O1xuICB9XG5cbiAgZ2V0RGF0YUxlbmd0aCgpOiBQcm9taXNlPG51bWJlcj57XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPG51bWJlcj4oKHJlc29sdmUpID0+e1xuICAgICAgdGhpcy5mbHhEYXRhLnN1YnNjcmliZSgocmVzcCkgPT57XG4gICAgICAgIHJlc29sdmUocmVzcC5sZW5ndGgpIDtcbiAgICAgIH0sKGU9PntcbiAgICAgICAgcmVzb2x2ZSgwKSA7XG4gICAgICB9KSlcbiAgICB9KSA7XG4gIH1cbn0iLCJpbXBvcnQgeyBJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XG5pbXBvcnQgeyBGbHhVaURhdGF0YWJsZVNlcnZpY2UgfSBmcm9tICcuL2ZseC11aS1kYXRhdGFibGUuc2VydmljZScgO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBGbHhVaURhdGFUYWJsZXtcbiAgICBiZWhhdmlvcjogQmVoYXZpb3JTdWJqZWN0PGFueT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KFtdKTtcbiAgICBmbHhEYXRhdGFibGVEYXRhID0gdGhpcy5iZWhhdmlvci5hc09ic2VydmFibGUoKTtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlcnZpY2U6IEZseFVpRGF0YXRhYmxlU2VydmljZSl7XG4gICAgICAgIHRoaXMuc2VydmljZS5mbHhEYXRhLnN1YnNjcmliZSgocmVzcCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5DaGFuZ2VEYXRhKHJlc3ApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gZGF0YSBDaGFuZ2UgdGFibGUgZGF0YSB3aXRoIG5ldyBkYXRhXG4gICAgICovXG4gICAgQ2hhbmdlRGF0YShkYXRhKSB7XG4gICAgICAgIHRoaXMuYmVoYXZpb3IubmV4dChkYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWxvYWQgZGF0YSBmcm9tIGFwaTogdm9pZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWxvYWREYXRhKCk6IHZvaWR7XG4gICAgICAgIHRoaXMuc2VydmljZS5sb2FkRmx4RGF0YVRhYmxlRGF0YSh0aGlzLnNlcnZpY2UuZ2V0RGF0YVVybCgpKSA7XG4gICAgfVxuXG4gICAgcHVibGljIGFib3J0UmVxdWVzdCgpe1xuICAgICAgICB0aGlzLnNlcnZpY2UuY2FuY2VsTG9hZGluZygpIDtcbiAgICB9XG59IiwiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCxPdXRwdXQsRXZlbnRFbWl0dGVyLCBPbkluaXQsQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwLFZhbGlkYXRvcnMsRm9ybUJ1aWxkZXJ9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJyA7XG5pbXBvcnQgeyBGbHhVaURhdGF0YWJsZVNlcnZpY2UgfSBmcm9tICcuL2ZseC11aS1kYXRhdGFibGUuc2VydmljZScgO1xuaW1wb3J0IHsgQXN5bmNQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJyA7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5kZWNsYXJlIHZhciBwcmludEpTOiBhbnkgO1xuZGVjbGFyZSB2YXIgUGVyZmVjdFNjcm9sbGJhcjogYW55IDtcbmRlY2xhcmUgdmFyICQ6IGFueSA7XG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6J2ZseC11aS1kYXRhdGFibGUnLFxuICB0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgZmx4LXVpLWRhdGF0YWJsZS1tYWluIHt7IGNsYXNzZXM/Lm1haW5jb250YWluZXIgfX1cIj5cbiAgICA8ZGl2IGlkPVwiZXhwb3J0X2xvYWRpbmdcIiBjbGFzcz1cImNvbC1tZC0xMiB0ZXh0LWNlbnRlclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTttYXJnaW4tYm90dG9tOjAuNWVtO2NvbG9yOiNkZGRkZGQ7Zm9udC1zaXplOjEzcHg7Zm9udC13ZWlnaHQ6Ym9sZDtcIj5FeHBvcnRpbmcuLi48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIGZseC11aS1kYXRhdGFibGUtaGVhZGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXhzLTMgY29sLXNtLTMgcGFnaW5hdGlvbi1zZWxlY3QgY29sLW1kLTJcIiBzdHlsZT1cInBvc2l0aW9uOnJlbGF0aXZlO3otaW5kZXg6IDE7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2wgcm1zaCBybXJkIHt7IGNsYXNzZXM/LnBhZ2luYXRpb25zZWxlY3QgfX1cIiAoY2hhbmdlKT1cInBhZ2luYXRlRGF0YXRhYmxlKCRldmVudD8udGFyZ2V0Py52YWx1ZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHBhZ2luZyBvZiBzZXJ2aWNlPy5wYWdpbmF0aW9uXCIgW3ZhbHVlXT1cInBhZ2luZz8udmFsdWVcIj57eyBwYWdpbmc/LmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wteHMtNSBjb2wtc20tNSBjb2wtbWQtMiB0ZXh0LWNlbnRlciBmbHgtZGF0YXRhYmxlLXBhZ2luYXRpb24gcm1wZFwiIHN0eWxlPVwicG9zaXRpb246cmVsYXRpdmU7ei1pbmRleDogMjtcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW25nQ2xhc3NdPVwieydmbHgtcGFnaW5hdGlvbi1lbmQnOiBkaXNhYmxlUHJldnRCdXR0b24oKX1cIiAoY2xpY2spPVwibmV4dFByZXZJdGVtKCdwcmV2JylcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZVByZXZ0QnV0dG9uKClcIiBjbGFzcz1cImZseC11aS1kYXRhdGFibGUtcGFnaW5hdGlvbi1idXR0b25zIHt7IGNsYXNzZXM/LnBhZ2luYXRpb25CdXR0b24gfX1cIj48c3BhbiBjbGFzcz1cImZhIGZhLWFuZ2xlLWRvdWJsZS1sZWZ0IGZhLTF4XCI+PC9zcGFuPiA8c3BhbiBjbGFzcz1cImZseC1kYXRhdGFibGUtdG9vbHRpcC1wcmV2XCIgW25nQ2xhc3NdPVwieydmbHgtcGFnaW5hdGlvbi1lbmQnOiBkaXNhYmxlUHJldnRCdXR0b24oKX1cIj5QcmV2aW91czwvc3Bhbj4gPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFpc1NlYXJjaGluZztlbHNlIHNlYXJjaGluZ1wiPnt7IHNlcnZpY2U/LmRhdGFPZmZzZXQgfCBjZWlsOiBsaW1pdCB9fSAvIHt7IHNlcnZpY2U/LnRvdGFsSXRlbXMgfCBjZWlsOiBsaW1pdCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2VhcmNoaW5nPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW25nQ2xhc3NdPVwieydmbHgtcGFnaW5hdGlvbi1lbmQnOiBkaXNhYmxlTmV4dEJ1dHRvbigpfVwiIChjbGljayk9XCJuZXh0UHJldkl0ZW0oJ25leHQnKVwiIFtkaXNhYmxlZF09XCJkaXNhYmxlTmV4dEJ1dHRvbigpXCIgY2xhc3M9XCJmbHgtdWktZGF0YXRhYmxlLXBhZ2luYXRpb24tYnV0dG9ucyB7eyBjbGFzc2VzPy5wYWdpbmF0aW9uQnV0dG9uIH19XCI+PHNwYW4gY2xhc3M9XCJmYSBmYS1hbmdsZS1kb3VibGUtcmlnaHQgZmEtMXhcIj48L3NwYW4+IDxzcGFuIGNsYXNzPVwiZmx4LWRhdGF0YWJsZS10b29sdGlwLW5leHRcIiBbbmdDbGFzc109XCJ7J2ZseC1wYWdpbmF0aW9uLWVuZCc6IGRpc2FibGVOZXh0QnV0dG9uKCl9XCI+TmV4dDwvc3Bhbj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IFtjbGFzc109XCInc2VhcmNoLWJhciAnK2dldFNlYXJjaENvbHVtbnMoKVwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiAqbmdJZj1cIiFpc0xhenlsb2FkaW5nRW5hYmxlZCgpXCIgW3N0eWxlLmJhY2tncm91bmRdPVwic2VhcmNoQmFyPy5iYWNrZ3JvdW5kXCIgW3N0eWxlLmNvbG9yXT1cInNlYXJjaEJhcj8udGV4dENvbG9yXCIgW25nU3R5bGVdPVwie2JvcmRlcjpzZWFyY2hCYXI/LmJvcmRlclNpemUgKycgc29saWQgJysgc2VhcmNoQmFyPy5ib3JkZXJDb2xvcn0gXCIgKGtleXVwKT1cImZpbHRlckRhdGEoJGV2ZW50Py50YXJnZXQ/LnZhbHVlKVwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHJtc2ggcm1yZCBjdXN0b21jbGFzc1wiIFtwbGFjZWhvbGRlcl09XCJzZWFyY2hQbGFjZWhvbGRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8Zm9ybSAobmdTdWJtaXQpPVwic2VhcmNoRGF0YUluQXBpKHNyY2g/LnZhbHVlLHNyY2gpXCIgI3NyY2g9XCJuZ0Zvcm1cIiAqbmdJZj1cImlzTGF6eWxvYWRpbmdFbmFibGVkKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIHJlcXVpcmVkIG5hbWU9XCJzZWFyY2hTdHJpbmdcIiBuZ01vZGVsIFtzdHlsZS5iYWNrZ3JvdW5kXT1cInNlYXJjaEJhcj8uYmFja2dyb3VuZFwiIFtzdHlsZS5jb2xvcl09XCJzZWFyY2hCYXI/LnRleHRDb2xvclwiIFtuZ1N0eWxlXT1cIntib3JkZXI6c2VhcmNoQmFyPy5ib3JkZXJTaXplICsnIHNvbGlkICcrIHNlYXJjaEJhcj8uYm9yZGVyQ29sb3J9IFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHJtc2ggcm1yZCB7eyBjbGFzc2VzPy5zZWFyY2hiYXIgfX1cIiBbcGxhY2Vob2xkZXJdPVwic2VhcmNoUGxhY2Vob2xkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLWFkZG9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiFzcmNoPy52YWxpZFwiIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCBidG4tY2xlYXIgYnRuLW1kXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXNlYXJjaFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEgdGV4dC1yaWdodCBybXBkXCIgKm5nSWY9XCJoYXNBZGRCdXR0b25cIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiYWRkQnV0dG9uQ2xpY2soKVwiIGNsYXNzPVwie3sgY2xhc3Nlcz8uYWRkQnV0dG9uIH19XCIgW3N0eWxlLmJhY2tncm91bmRdPVwiYWRkQnV0dG9uPy5iYWNrZ3JvdW5kXCIgW3N0eWxlLmJvcmRlckNvbG9yXT1cImFkZEJ1dHRvbj8uYmFja2dyb3VuZFwiIFtzdHlsZS5jb2xvcl09XCJhZGRCdXR0b24/LnRleHRDb2xvclwiPjxzcGFuIGNsYXNzPVwiZmEgZmEtcGx1c1wiPjwvc3Bhbj4gQWRkPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xIHRleHQtcmlnaHQgcm1wZCBleHBvcnQtY250XCIgKm5nSWY9XCJlbmFibGVEYXRhRXhwb3J0c1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQge3sgY2xhc3Nlcz8uZXhwb3J0QnV0dG9uIH19IGRyb3Bkb3duLXRvZ2dsZVwiIHR5cGU9XCJidXR0b25cIiBkYXRhLXRvZ2dsZT1cImRyb3Bkb3duXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1hbmdsZS1kb3duXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJkcm9wZG93bi1tZW51IGRyb3Bkb3duLW1lbnUtZXhwb3J0IHt7IGNsYXNzZXM/LmV4cG9ydERyb3Bkb3duIH19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiZHJvcGRvd24taGVhZGVyXCI+e3sgZGF0YUV4cG9ydHNDb25maWc/LnRpdGxlIH19LiA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgKGNoYW5nZSk9XCJjaGVja1RvRXhwb3J0T3B0aW9uKCRldmVudD8udGFyZ2V0Py5jaGVja2VkKVwiIHN0eWxlPVwicG9zaXRpb246IHJlbGF0aXZlO3RvcDowLjNlbTtcIj4gPHN1cCBzdHlsZT1cImZvbnQtc2l6ZToxMHB4O2NvbG9yOiM5OTk7XCI+IEFsbDwvc3VwPjwvbGk+IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImRpdmlkZXJcIj48L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImRyb3Bkb3duLXN1Ym1lbnVcIiAqbmdGb3I9XCJsZXQgZXhwb3J0IG9mIGRhdGFFeHBvcnRzQ29uZmlnPy5leHBvcnRzVG9cIiAoY2xpY2spPVwiZXhwb3J0RG9jdW1lbnRzQXMoZXhwb3J0KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgYnRuLXNtIGZvcm0tY29udHJvbFwiICpuZ0lmPVwiZXhwb3J0PT0ncHJpbnQnXCI+PGkgY2xhc3M9XCJnbHlwaGljb24gZ2x5cGhpY29uLXByaW50XCI+PC9pPiBQcmludDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbSBmb3JtLWNvbnRyb2xcIiAqbmdJZj1cImV4cG9ydD09J3BkZidcIiBzdHlsZT1cImNvbG9yOiNmZjAwMDBcIj48aSBjbGFzcz1cImdseXBoaWNvbiBnbHlwaGljb24tZmlsZVwiPjwvaT4gUERGPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgYnRuLXNtIGZvcm0tY29udHJvbFwiICpuZ0lmPVwiZXhwb3J0PT0nZXhjZWwnXCIgc3R5bGU9XCJjb2xvcjojMDA5OTAwO1wiPjxpIGNsYXNzPVwiZ2x5cGhpY29uIGdseXBoaWNvbi1maWxlXCI+PC9pPiBFeGNlbDwvYT4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbSBmb3JtLWNvbnRyb2xcIiAqbmdJZj1cImV4cG9ydD09J3dvcmQnXCIgc3R5bGU9XCJjb2xvcjojMzM1NTk5O1wiPjxpIGNsYXNzPVwiZ2x5cGhpY29uIGdseXBoaWNvbi1maWxlXCI+PC9pPiBXb3JkPC9hPiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiZGl2aWRlclwiPjwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiZHJvcGRvd24taGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICAqbmdJZj1cIiFpc0V4cG9ydEFsbFwiPnt7IChkaXNwbGF5RGF0YSB8IGFzeW5jKT8ubGVuZ3RoIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAgKm5nSWY9XCJpc0V4cG9ydEFsbFwiPnt7IChzZXJ2aWNlPy5mbHhEYXRhIHwgYXN5bmMpPy5sZW5ndGggfX08L3NwYW4+IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgcm1wZCB0YWJsZS1yZXNwb25zaXZlIGZseC10YWJsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHt7IGNsYXNzZXM/LnRhYmxlVHlwZSB9fSB0aC10YWJsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8dGhlYWQgY2xhc3M9XCJ7eyBjbGFzc2VzPy50YWJsZUhlYWRlciB9fSBmbHgtdGFibGUtdGhlYWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEFjdGlvbnMgYnV0dG9ucyBoZWFkZXIgbGVmdCBiZWZvcmUgbnVtYmVycyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCJoYXNBY3Rpb25CdXR0b25zICYmIChhY3Rpb25CdXR0b25zQ29uZmlnPy5wb3NpdGlvbj09J2xlZnQnICYmIGFjdGlvbkJ1dHRvbnNDb25maWc/LmJlZm9yZU51bWJlcnMpXCI+e3sgYWN0aW9uSGVhZGVyIH19IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwic2VydmljZT8ubXVsdGlwbGVEZWxldGlvbj8ubGVuZ3RoPjBcIiAoY2hhbmdlKT1cImFkZFJlbW92ZSgkZXZlbnQ/LnRhcmdldD8uY2hlY2tlZClcIiAqbmdJZj1cImVuYWJsZU11bHRpcGxlU2VsZWN0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlciBidG4teHMgZmx4LW11bHRpcGxlLWRlbGV0aW9uLWJ1dHRvblwiICpuZ0lmPVwiZW5hYmxlTXVsdGlwbGVTZWxlY3Rpb24gJiYgc2VydmljZT8ubXVsdGlwbGVEZWxldGlvbj8ubGVuZ3RoPjBcIiAoY2xpY2spPVwiY29uZmlybURlbGV0ZSgpXCI+PHNwYW4gW2NsYXNzXT1cIm11bHRpcGxlU2VsZWN0QnV0dG9uPy5pY29uXCI+PC9zcGFuPiB7eyBtdWx0aXBsZVNlbGVjdEJ1dHRvbj8udGV4dCB9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCAqbmdJZj1cIiFoaWRlTnVtYmVyc1wiPk48c3VwPjx1Pm88L3U+PC9zdXA+PC90aD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQWN0aW9ucyBidXR0b25zIGhlYWRlciBsZWZ0IGFmdGVyIG51bWJlcnMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0lmPVwiaGFzQWN0aW9uQnV0dG9ucyAmJiAoYWN0aW9uQnV0dG9uc0NvbmZpZz8ucG9zaXRpb249PSdsZWZ0JyAmJiAhYWN0aW9uQnV0dG9uc0NvbmZpZz8uYmVmb3JlTnVtYmVycylcIj57eyBhY3Rpb25IZWFkZXIgfX0gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJzZXJ2aWNlPy5tdWx0aXBsZURlbGV0aW9uPy5sZW5ndGg+MFwiIChjaGFuZ2UpPVwiYWRkUmVtb3ZlKCRldmVudD8udGFyZ2V0Py5jaGVja2VkKVwiICpuZ0lmPVwiZW5hYmxlTXVsdGlwbGVTZWxlY3Rpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyIGJ0bi14cyBmbHgtbXVsdGlwbGUtZGVsZXRpb24tYnV0dG9uXCIgKm5nSWY9XCJlbmFibGVNdWx0aXBsZVNlbGVjdGlvbiAmJiBzZXJ2aWNlPy5tdWx0aXBsZURlbGV0aW9uPy5sZW5ndGg+MFwiIChjbGljayk9XCJjb25maXJtRGVsZXRlKClcIj48c3BhbiBbY2xhc3NdPVwibXVsdGlwbGVTZWxlY3RCdXR0b24/Lmljb25cIj48L3NwYW4+IHt7IG11bHRpcGxlU2VsZWN0QnV0dG9uPy50ZXh0IH19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBoZWFkZXIgb2YgaGVhZGVyc1wiPnt7IGhlYWRlciB9fTwvdGg+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEFjdGlvbnMgYnV0dG9ucyBoZWFkZXIgcmlnaHQgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0lmPVwiaGFzQWN0aW9uQnV0dG9ucyAgJiYgKGFjdGlvbkJ1dHRvbnNDb25maWc/LnBvc2l0aW9uPT0ncmlnaHQnKVwiPnt7IGFjdGlvbkhlYWRlciB9fSBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cInNlcnZpY2U/Lm11bHRpcGxlRGVsZXRpb24/Lmxlbmd0aD4wXCIgKGNoYW5nZSk9XCJhZGRSZW1vdmUoJGV2ZW50Py50YXJnZXQ/LmNoZWNrZWQpXCIgKm5nSWY9XCJlbmFibGVNdWx0aXBsZVNlbGVjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXIgYnRuLXhzIGZseC1tdWx0aXBsZS1kZWxldGlvbi1idXR0b25cIiAqbmdJZj1cImVuYWJsZU11bHRpcGxlU2VsZWN0aW9uICYmIHNlcnZpY2U/Lm11bHRpcGxlRGVsZXRpb24/Lmxlbmd0aD4wXCIgKGNsaWNrKT1cImNvbmZpcm1EZWxldGUoKVwiPjxzcGFuIFtjbGFzc109XCJtdWx0aXBsZVNlbGVjdEJ1dHRvbj8uaWNvblwiPjwvc3Bhbj4ge3sgbXVsdGlwbGVTZWxlY3RCdXR0b24/LnRleHQgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgICAgIDxwZXJmZWN0LXNjcm9sbGJhciBjbGFzcz1cImRhdGEtc2Nyb2xsLWNvbnRlbnQge3sgY2xhc3Nlcz8uZGF0YVNjcm9sbENvbnRlbnQgfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUge3sgY2xhc3Nlcz8udGFibGVUeXBlIH19IGZseC10YWJsZS1kYXRhXCI+ICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJmbHhkYXRhdGFibGVib2R5c2Nyb2xsYmFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0lmPVwiIXNlcnZpY2U/LmxvYWRGaW5pc2hcIj4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjIwXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyAqbmdJZj1cInNwaW5uZXJTcmNcIiBbY2xhc3NdPVwiY2xhc3Nlcz8uc3Bpbm5lclwiIFtzcmNdPVwic3Bpbm5lclNyY1wiIHN0eWxlPVwibWFyZ2luLXRvcDoxZW07bWFyZ2luLWJvdHRvbToxZW07XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgY2xhc3M9XCJmbHh1aWRhdGF0YWJsZXJvd1wiIGlkPVwiZmx4ZGF0YXRhYmxlX3NpbmdsZXJvd1wiICpuZ0Zvcj1cImxldCBkYXRhIG9mIGRpc3BsYXlEYXRhIHwgYXN5bmM7bGV0IGk9aW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQnV0dG9ucyBMZWZ0IEJlZm9yZSBOdW1iZXJzIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0YWJsZS1idXR0b25zXCIgKm5nSWY9XCJoYXNBY3Rpb25CdXR0b25zICYmIChhY3Rpb25CdXR0b25zQ29uZmlnPy5wb3NpdGlvbj09J2xlZnQnICYmIGFjdGlvbkJ1dHRvbnNDb25maWc/LmJlZm9yZU51bWJlcnMpXCIgc2NvcGU9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCBhQnV0dG9uIG9mIGFjdGlvbkJ1dHRvbnM7bGV0IGJ1dHRvbkluZGV4PWluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGlvbkJ1dHRvbkNsaWNrZWQoaSxidXR0b25JbmRleClcIiBjbGFzcz1cImJ0biB7eyBhQnV0dG9uPy5jbGFzcyB9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9sdGlwXCIgY2xhc3M9XCJmbHgtdG9vbHRpcFwiIFtuZ0NsYXNzXT1cInsnZmx4LXRvb2x0aXAtbGVmdCc6YUJ1dHRvbj8udG9vbHRpcFBvc2l0aW9uPT0nbGVmdCcsJ2ZseC10b29sdGlwLWJvdHRvbSc6YUJ1dHRvbj8udG9vbHRpcFBvc2l0aW9uPT0nYm90dG9tJywnZmx4LXRvb2x0aXAtcmlnaHQnOmFCdXR0b24/LnRvb2x0aXBQb3NpdGlvbj09J3JpZ2h0J31cIiAqbmdJZj1cImFCdXR0b24/LnRvb2x0aXBcIj57eyBhQnV0dG9uPy50b29sdGlwIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWN0aW9uLWJ1dHRvbi1pY29uLWxlZnRcIiBbY2xhc3NdPVwiYUJ1dHRvbj8uaWNvblwiICpuZ0lmPVwiIWFCdXR0b24/Lmljb25Qb3NpdGlvbiB8fCBhQnV0dG9uPy5pY29uUG9zaXRpb24hPSdyaWdodCdcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnV0dG9uLXRleHRcIj4ge3sgYUJ1dHRvbj8udGV4dCB9fSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtjbGFzc109XCJhQnV0dG9uPy5pY29uXCIgKm5nSWY9XCJhQnV0dG9uPy5pY29uUG9zaXRpb249PSdyaWdodCdcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNoZWNrZWQgKGNoYW5nZSk9XCJhZGRSZW1vdmVEZWxldGVJdGVtKGRhdGFbbXVsdGlwbGVTZWxlY3RLZXldLGksJGV2ZW50Py50YXJnZXQ/LmNoZWNrZWQpXCIgKm5nSWY9XCJlbmFibGVNdWx0aXBsZVNlbGVjdGlvbiAmJiBzZXJ2aWNlPy5tdWx0aXBsZURlbGV0aW9uPy5sZW5ndGg+MFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOdW1iZXJzIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ7eyBjbGFzc2VzPy50YWJsZURhdGEgfX1cIiAqbmdJZj1cIiFoaWRlTnVtYmVyc1wiIHN0eWxlPVwiY29sb3I6ICM5OTk7XCI+e3sgb2Zmc2V0K2kgfX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBCdXR0b25zIExlZnQgQWZ0ZXIgTnVtYmVycyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGFibGUtYnV0dG9uc1wiICpuZ0lmPVwiaGFzQWN0aW9uQnV0dG9ucyAmJiAoYWN0aW9uQnV0dG9uc0NvbmZpZz8ucG9zaXRpb249PSdsZWZ0JyAmJiAhYWN0aW9uQnV0dG9uc0NvbmZpZz8uYmVmb3JlTnVtYmVycylcIiBzY29wZT1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IGFCdXR0b24gb2YgYWN0aW9uQnV0dG9ucztsZXQgYnV0dG9uSW5kZXg9aW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWN0aW9uQnV0dG9uQ2xpY2tlZChpLGJ1dHRvbkluZGV4KVwiIGNsYXNzPVwiYnRuIHt7IGFCdXR0b24/LmNsYXNzIH19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2x0aXBcIiBjbGFzcz1cImZseC10b29sdGlwXCIgW25nQ2xhc3NdPVwieydmbHgtdG9vbHRpcC1sZWZ0JzphQnV0dG9uPy50b29sdGlwUG9zaXRpb249PSdsZWZ0JywnZmx4LXRvb2x0aXAtYm90dG9tJzphQnV0dG9uPy50b29sdGlwUG9zaXRpb249PSdib3R0b20nLCdmbHgtdG9vbHRpcC1yaWdodCc6YUJ1dHRvbj8udG9vbHRpcFBvc2l0aW9uPT0ncmlnaHQnfVwiICpuZ0lmPVwiYUJ1dHRvbj8udG9vbHRpcFwiPnt7IGFCdXR0b24/LnRvb2x0aXAgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhY3Rpb24tYnV0dG9uLWljb24tbGVmdFwiIFtjbGFzc109XCJhQnV0dG9uPy5pY29uXCIgKm5nSWY9XCIhYUJ1dHRvbj8uaWNvblBvc2l0aW9uIHx8IGFCdXR0b24/Lmljb25Qb3NpdGlvbiE9J3JpZ2h0J1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJidXR0b24tdGV4dFwiPiB7eyBhQnV0dG9uPy50ZXh0IH19IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2NsYXNzXT1cImFCdXR0b24/Lmljb25cIiAqbmdJZj1cImFCdXR0b24/Lmljb25Qb3NpdGlvbj09J3JpZ2h0J1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2hlY2tlZCAoY2hhbmdlKT1cImFkZFJlbW92ZURlbGV0ZUl0ZW0oZGF0YVttdWx0aXBsZVNlbGVjdEtleV0saSwkZXZlbnQ/LnRhcmdldD8uY2hlY2tlZClcIiAqbmdJZj1cImVuYWJsZU11bHRpcGxlU2VsZWN0aW9uICYmIHNlcnZpY2U/Lm11bHRpcGxlRGVsZXRpb24/Lmxlbmd0aD4wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1haW4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInt7IGNsYXNzZXM/LnRhYmxlRGF0YSB9fVwiICpuZ0Zvcj1cImxldCBkYXRhS2V5IG9mIGRhdGFLZXlzO2xldCB4PWluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nICpuZ0lmPVwiaGFzSW1hZ2VFbWJlZGVkKCkgJiYgeD09ZW1iZWRQaWN0dXJlcz8uaW5kZXg7IGVsc2Ugbm9waWN0dXJlXCIgW2NsYXNzXT1cIidpbWctZmFsbC1iYWNrICcgK2VtYmVkUGljdHVyZXM/LmNsYXNzXCIgW3NyY109XCJlbWJlZFBpY3R1cmVzPy5yb290Rm9sZGVyK2RhdGFbZGF0YUtleV1cIiBbZmx4LXVpLWRhdGF0YWJsZS1pbWctZmFsbGJhY2tdPVwiZW1iZWRQaWN0dXJlcz8uZmFsbGJhY2tVcmxcIiA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vcGljdHVyZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VjdGlvbiAqbmdJZj1cInRleHRTdWJzdHJpbmc/LmF0SW5kZXhlcyAmJiAodGV4dFN1YnN0cmluZz8uYXRJbmRleGVzIHwgaGFzbGltaXR0ZXh0OngpO2Vsc2Ugbm9saW1pdHRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdGV4dFN1YnN0cmluZyB8IGxpbWl0dGV4dDogZGF0YVtkYXRhS2V5XSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VjdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vbGltaXR0ZXh0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBkYXRhW2RhdGFLZXldIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBCdXR0b25zIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0YWJsZS1idXR0b25zXCIgKm5nSWY9XCJoYXNBY3Rpb25CdXR0b25zICYmIGFjdGlvbkJ1dHRvbnNDb25maWc/LnBvc2l0aW9uIT0nbGVmdCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCBhQnV0dG9uIG9mIGFjdGlvbkJ1dHRvbnM7bGV0IGJ1dHRvbkluZGV4PWluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGlvbkJ1dHRvbkNsaWNrZWQoaSxidXR0b25JbmRleClcIiBjbGFzcz1cImJ0biB7eyBhQnV0dG9uPy5jbGFzcyB9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9sdGlwXCIgY2xhc3M9XCJmbHgtdG9vbHRpcFwiIFtuZ0NsYXNzXT1cInsnZmx4LXRvb2x0aXAtbGVmdCc6YUJ1dHRvbj8udG9vbHRpcFBvc2l0aW9uPT0nbGVmdCcsJ2ZseC10b29sdGlwLWJvdHRvbSc6YUJ1dHRvbj8udG9vbHRpcFBvc2l0aW9uPT0nYm90dG9tJywnZmx4LXRvb2x0aXAtcmlnaHQnOmFCdXR0b24/LnRvb2x0aXBQb3NpdGlvbj09J3JpZ2h0J31cIiAqbmdJZj1cImFCdXR0b24/LnRvb2x0aXBcIj57eyBhQnV0dG9uPy50b29sdGlwIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWN0aW9uLWJ1dHRvbi1pY29uLWxlZnRcIiBbY2xhc3NdPVwiYUJ1dHRvbj8uaWNvblwiICpuZ0lmPVwiIWFCdXR0b24/Lmljb25Qb3NpdGlvbiB8fCBhQnV0dG9uPy5pY29uUG9zaXRpb24hPSdyaWdodCdcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnV0dG9uLXRleHRcIj4ge3sgYUJ1dHRvbj8udGV4dCB9fSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtjbGFzc109XCJhQnV0dG9uPy5pY29uXCIgKm5nSWY9XCJhQnV0dG9uPy5pY29uUG9zaXRpb249PSdyaWdodCdcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNoZWNrZWQgKGNoYW5nZSk9XCJhZGRSZW1vdmVEZWxldGVJdGVtKGRhdGFbbXVsdGlwbGVTZWxlY3RLZXldLGksJGV2ZW50Py50YXJnZXQ/LmNoZWNrZWQpXCIgKm5nSWY9XCJlbmFibGVNdWx0aXBsZVNlbGVjdGlvbiAmJiBzZXJ2aWNlPy5tdWx0aXBsZURlbGV0aW9uPy5sZW5ndGg+MFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0lmPVwidERhdGE/Lmxlbmd0aDwxXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiMTBcIiBjbGFzcz1cInRleHQtY2VudGVyXCIgKm5nSWY9XCJzZXJ2aWNlPy5sb2FkRmluaXNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiNmZjAwMDA7Zm9udC1zaXplOjEzcHg7XCI+Tm8gZGF0YSBmb3VuZDwvc3Bhbj4gPGJyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgc3R5bGU9XCJtYXJnaW4tdG9wOjFlbTtcIiAoY2xpY2spPVwicmVsb2FkKClcIiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCB7eyBjbGFzc2VzPy5yZWxvYWRidXR0b24gfX1cIiBjb2xvcj1cInByaW1hcnlcIj48c3BhbiBjbGFzcz1cImZhIGZhLXJlZnJlc2hcIj48L3NwYW4+IFJlbG9hZDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgICAgIDwvcGVyZmVjdC1zY3JvbGxiYXI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHJtcGQgZmx4LXRvdGFsLWRhdGFcIiAqbmdJZj1cInNob3dCb3R0b21JbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nSWY9XCIhaXNTZWFyY2hpbmc7ZWxzZSBib3R0b21JbmZvU2VhcmNoaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC00IHRleHQtbGVmdCBybXBkXCI+VG90YWwgcGFnaW5hdGlvbjogPHNwYW4+IHt7IHNlcnZpY2U/LnRvdGFsSXRlbXMgfCBjZWlsOiBsaW1pdCB9fTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgdGV4dC1jZW50ZXIgcm1wZFwiPiMgb2YgaXRlbXMgcGVyIHBhZ2luYXRpb246IDxzcGFuPnt7IGxpbWl0IH19PC9zcGFuPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCB0ZXh0LXJpZ2h0IHJtcGRcIj5Ub3RhbCBpdGVtczogPHNwYW4+e3sgKHNlcnZpY2U/LmZseERhdGEgfCBhc3luYyk/Lmxlbmd0aCB9fTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNib3R0b21JbmZvU2VhcmNoaW5nPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiB0ZXh0LXJpZ2h0IHJtcGRcIj5Ub3RhbCBzZWFyY2ggcmVzdWx0OiA8c3Bhbj57eyBzZWFyY2hSZXN1bHRGb3VuZD8ubGVuZ3RoIH19PC9zcGFuPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5gLFxuICBzdHlsZXM6IFtgLmZseC11aS1kYXRhdGFibGUtbWFpbntiYWNrZ3JvdW5kLWNvbG9yOiNmZmY7cGFkZGluZy10b3A6MWVtO3BhZGRpbmctYm90dG9tOjFlbX0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tZGFuZ2Vye2JhY2tncm91bmQtY29sb3I6I2Y1MDA1Nztib3JkZXI6MXB4IHNvbGlkICNmNTAwNTc7Ym94LXNoYWRvdzowIDNweCA1cHggMXB4ICNkZGQ7LW1vei1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1vLWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1tcy1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDtib3JkZXItcmFkaXVzOjNweDttYXJnaW4tbGVmdDouM2VtfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gI2ZseGRhdGF0YWJsZWJvZHlzY3JvbGxiYXIsLmZseC11aS1kYXRhdGFibGUtbWFpbiAudGFibGUtcmVzcG9uc2l2ZSwuZmx4LXVpLWRhdGF0YWJsZS1tYWluIC50YWJsZS1yZXNwb25zaXZlIHRhYmxle3dpZHRoOjEwMCV9LmZseC11aS1kYXRhdGFibGUtbWFpbiBpbWcuaW1nLWZhbGwtYmFja3t3aWR0aDozMHB4O2hlaWdodDozMHB4fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLnBhZ2luYXRpb24tc2VsZWN0IGlucHV0W3R5cGU9dGV4dF0sLmZseC11aS1kYXRhdGFibGUtbWFpbiAucGFnaW5hdGlvbi1zZWxlY3Qgc2VsZWN0LC5mbHgtdWktZGF0YXRhYmxlLW1haW4gLnNlYXJjaC1iYXIgaW5wdXRbdHlwZT10ZXh0XSwuZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5zZWFyY2gtYmFyIHNlbGVjdHtib3JkZXItdG9wOm5vbmUhaW1wb3J0YW50O2JvcmRlci1sZWZ0Om5vbmUhaW1wb3J0YW50O2JvcmRlci1yaWdodDpub25lIWltcG9ydGFudDtib3JkZXItYm90dG9tOjJweCBzb2xpZCAjZGRkIWltcG9ydGFudDtib3JkZXItcmFkaXVzOjAhaW1wb3J0YW50O2JveC1zaGFkb3c6MCAwIDAgMCB0cmFuc3BhcmVudCFpbXBvcnRhbnQ7LW1vei1ib3gtc2hhZG93OjAgMCAwIDAgdHJhbnNwYXJlbnQhaW1wb3J0YW50Oy13ZWJraXQtYm94LXNoYWRvdzowIDAgMCAwIHRyYW5zcGFyZW50IWltcG9ydGFudDstby1ib3gtc2hhZG93OjAgMCAwIDAgdHJhbnNwYXJlbnQhaW1wb3J0YW50Oy1tcy1ib3gtc2hhZG93OjAgMCAwIDAgdHJhbnNwYXJlbnQhaW1wb3J0YW50fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLnBhZ2luYXRpb24tc2VsZWN0IGlucHV0W3R5cGU9dGV4dF06Zm9jdXMsLmZseC11aS1kYXRhdGFibGUtbWFpbiAucGFnaW5hdGlvbi1zZWxlY3Qgc2VsZWN0OmZvY3VzLC5mbHgtdWktZGF0YXRhYmxlLW1haW4gLnNlYXJjaC1iYXIgaW5wdXRbdHlwZT10ZXh0XTpmb2N1cywuZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5zZWFyY2gtYmFyIHNlbGVjdDpmb2N1c3tib3JkZXItYm90dG9tLWNvbG9yOiMzNTkhaW1wb3J0YW50O3RyYW5zaXRpb246LjVzOy1tb3otdHJhbnNpdGlvbjouNXM7LXdlYmtpdC10cmFuc2l0aW9uOi41czstby10cmFuc2l0aW9uOi41czstbXMtdHJhbnNpdGlvbjouNXN9LmZseC11aS1kYXRhdGFibGUtbWFpbiAucGFnaW5hdGlvbi1zZWxlY3Qgc2VsZWN0LC5mbHgtdWktZGF0YXRhYmxlLW1haW4gLnNlYXJjaC1iYXIgc2VsZWN0ey13ZWJraXQtYXBwZWFyYW5jZTpub25lO2FwcGVhcmFuY2U6bm9uZTstbW96LWFwcGVhcmFuY2U6bm9uZX0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5kcm9wZG93bi10b2dnbGU6OmFmdGVye2Rpc3BsYXk6bm9uZX0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5kcm9wZG93bi1tZW51LWV4cG9ydHttYXJnaW4tbGVmdDotMTMwcHg7cGFkZGluZy1sZWZ0OjFlbTtwYWRkaW5nLXJpZ2h0OjFlbTt3aWR0aDoxMDBweCFpbXBvcnRhbnQ7bWFyZ2luLXRvcDoxZW07Ym9yZGVyOjFweCBzb2xpZCAjZGRkIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5kcm9wZG93bi1tZW51LWV4cG9ydDo6YmVmb3Jle2NvbnRlbnQ6XCJcIjt3aWR0aDphdXRvO2hlaWdodDphdXRvO3Bvc2l0aW9uOmFic29sdXRlO3RvcDotMjBweDtyaWdodDozcHg7Ym9yZGVyOjEwcHggc29saWQ7Ym9yZGVyLWNvbG9yOnRyYW5zcGFyZW50IHRyYW5zcGFyZW50ICNkZGR9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuZmx4LWRhdGF0YWJsZS1wYWdpbmF0aW9ue3BhZGRpbmctdG9wOi41ZW19LmZseC11aS1kYXRhdGFibGUtbWFpbiAuZmx4LWRhdGF0YWJsZS1wYWdpbmF0aW9uIGJ1dHRvbnt3aWR0aDozNXB4IWltcG9ydGFudDtoZWlnaHQ6MzVweCFpbXBvcnRhbnQ7Ym9yZGVyLXJhZGl1czo1MGVtIWltcG9ydGFudDtib3JkZXI6bm9uZSFpbXBvcnRhbnQ7Ym94LXNoYWRvdzowIDNweCAxMHB4IDAgI2IzYzRlNjstbW96LWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTY7LXdlYmtpdC1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2Oy1vLWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTY7LW1zLWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTY7YmFja2dyb3VuZC1jb2xvcjojMzU5O2NvbG9yOiNmZmY7Zm9udC1zaXplOjIzcHg7Zm9udC13ZWlnaHQ6NzAwO3Bvc2l0aW9uOmFic29sdXRlO3RvcDowfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC1kYXRhdGFibGUtcGFnaW5hdGlvbiBidXR0b246Zmlyc3QtY2hpbGR7bGVmdDowfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC1kYXRhdGFibGUtcGFnaW5hdGlvbiBidXR0b246Zmlyc3QtY2hpbGQgLmZseC1kYXRhdGFibGUtdG9vbHRpcC1wcmV2e3Bvc2l0aW9uOmFic29sdXRlO2xlZnQ6MDtmb250LXNpemU6MTNweDtmb250LXdlaWdodDo0MDA7Y29sb3I6I2ZmZjtiYWNrZ3JvdW5kLWNvbG9yOiMzNTk7cGFkZGluZy1sZWZ0Oi4zZW07cGFkZGluZy1yaWdodDouM2VtO2JvcmRlci1yYWRpdXM6M3B4O21hcmdpbi1sZWZ0Oi01N3B4O21hcmdpbi10b3A6LjNlbTtib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2IWltcG9ydGFudDstbW96LWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTYhaW1wb3J0YW50Oy13ZWJraXQtYm94LXNoYWRvdzowIDNweCAxMHB4IDAgI2IzYzRlNiFpbXBvcnRhbnQ7LW8tYm94LXNoYWRvdzowIDNweCAxMHB4IDAgI2IzYzRlNiFpbXBvcnRhbnQ7LW1zLWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTYhaW1wb3J0YW50O3Zpc2liaWxpdHk6aGlkZGVufS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC1kYXRhdGFibGUtcGFnaW5hdGlvbiBidXR0b246aG92ZXI+c3Bhbi5mbHgtZGF0YXRhYmxlLXRvb2x0aXAtbmV4dCwuZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5mbHgtZGF0YXRhYmxlLXBhZ2luYXRpb24gYnV0dG9uOmhvdmVyPnNwYW4uZmx4LWRhdGF0YWJsZS10b29sdGlwLXByZXZ7dmlzaWJpbGl0eTp2aXNpYmxlfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC1kYXRhdGFibGUtcGFnaW5hdGlvbiAuZmx4LXBhZ2luYXRpb24tZW5ke2JhY2tncm91bmQtY29sb3I6I2Y1MDA1NyFpbXBvcnRhbnQ7Ym94LXNoYWRvdzowIDNweCAxMHB4IDAgI2ZmYzJkOCFpbXBvcnRhbnQ7LW1vei1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjZmZjMmQ4IWltcG9ydGFudDstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNmZmMyZDghaW1wb3J0YW50Oy1vLWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNmZmMyZDghaW1wb3J0YW50Oy1tcy1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjZmZjMmQ4IWltcG9ydGFudDtjdXJzb3I6bm90LWFsbG93ZWR9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuZmx4LWRhdGF0YWJsZS1wYWdpbmF0aW9uIC5mbHgtcGFnaW5hdGlvbi1lbmQ6aG92ZXI+c3Bhbi5mbHgtZGF0YXRhYmxlLXRvb2x0aXAtbmV4dCwuZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5mbHgtZGF0YXRhYmxlLXBhZ2luYXRpb24gLmZseC1wYWdpbmF0aW9uLWVuZDpob3Zlcj5zcGFuLmZseC1kYXRhdGFibGUtdG9vbHRpcC1wcmV2e3Zpc2liaWxpdHk6aGlkZGVufS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC1kYXRhdGFibGUtcGFnaW5hdGlvbiBidXR0b246bGFzdC1jaGlsZHtyaWdodDowfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC1kYXRhdGFibGUtcGFnaW5hdGlvbiBidXR0b246bGFzdC1jaGlsZCAuZmx4LWRhdGF0YWJsZS10b29sdGlwLW5leHR7cG9zaXRpb246YWJzb2x1dGU7bGVmdDowO2ZvbnQtc2l6ZToxM3B4O2ZvbnQtd2VpZ2h0OjQwMDtjb2xvcjojZmZmO2JhY2tncm91bmQtY29sb3I6IzM1OTtwYWRkaW5nLWxlZnQ6LjNlbTtwYWRkaW5nLXJpZ2h0Oi4zZW07Ym9yZGVyLXJhZGl1czozcHg7bWFyZ2luLWxlZnQ6MzVweDttYXJnaW4tdG9wOi41ZW07Ym94LXNoYWRvdzowIDNweCAxMHB4IDAgI2IzYzRlNiFpbXBvcnRhbnQ7LW1vei1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2IWltcG9ydGFudDstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTYhaW1wb3J0YW50Oy1vLWJveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTYhaW1wb3J0YW50Oy1tcy1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2IWltcG9ydGFudDt2aXNpYmlsaXR5OmhpZGRlbn0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5leHBvcnQtY250IGJ1dHRvbntib3JkZXItcmFkaXVzOjUwZW0haW1wb3J0YW50fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmZseC10YWJsLWNvbnRhaW5lciB0YWJsZS50aC10YWJsZXttYXJnaW4tdG9wOi41ZW19LmZseC11aS1kYXRhdGFibGUtbWFpbiB0YWJsZSB0Ym9keSB0cntwYWRkaW5nLXRvcDowIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIHRhYmxlIHRib2R5IHRyIHRke3BhZGRpbmctdG9wOi41ZW07Ym9yZGVyLXRvcDoxcHggc29saWQgI2YwZjBmMDtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZjBmMGYwfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gdGFibGUgdGJvZHkgdHIgdGQgYnV0dG9ue21hcmdpbi1yaWdodDouM2VtO21hcmdpbi1sZWZ0OjB9LmZseC11aS1kYXRhdGFibGUtbWFpbiB0YWJsZSB0Ym9keSB0ciB0ZCBidXR0b24gZGl2LmZseC10b29sdGlwe3Bvc2l0aW9uOmFic29sdXRlO2JhY2tncm91bmQtY29sb3I6cmdiYSgzMiwyNywyNywuODA4KTt0ZXh0LWFsaWduOmNlbnRlcjtmb250LXNpemU6MTNweDtjb2xvcjojZmZmO2JvcmRlci1yYWRpdXM6M3B4O2JveC1zaGFkb3c6MCAzcHggMjBweCAwICM0YjQ5NDk7LW1vei1ib3gtc2hhZG93OjAgM3B4IDIwcHggMCAjNGI0OTQ5Oy13ZWJraXQtYm94LXNoYWRvdzowIDNweCAyMHB4IDAgIzRiNDk0OTstby1ib3gtc2hhZG93OjAgM3B4IDIwcHggMCAjNGI0OTQ5Oy1tcy1ib3gtc2hhZG93OjAgM3B4IDIwcHggMCAjNGI0OTQ5O21hcmdpbi1sZWZ0Oi0yLjVlbTttYXJnaW4tdG9wOi0yLjhlbTt2aXNpYmlsaXR5OmhpZGRlbjt3aWR0aDo4MHB4O3BhZGRpbmc6LjNlbSAuNWVtfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gdGFibGUgdGJvZHkgdHIgdGQgYnV0dG9uIC5mbHgtdG9vbHRpcC1sZWZ0e21hcmdpbi1sZWZ0Oi05NXB4IWltcG9ydGFudDttYXJnaW4tdG9wOi0uM2VtIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIHRhYmxlIHRib2R5IHRyIHRkIGJ1dHRvbiAuZmx4LXRvb2x0aXAtYm90dG9te21hcmdpbi10b3A6Mi4zZW0haW1wb3J0YW50fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gdGFibGUgdGJvZHkgdHIgdGQgYnV0dG9uIC5mbHgtdG9vbHRpcC1yaWdodHttYXJnaW4tbGVmdDoyOHB4IWltcG9ydGFudDttYXJnaW4tdG9wOi0uM2VtIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIHRhYmxlIHRib2R5IHRyIHRkIGJ1dHRvbjpob3Zlcj5kaXYuZmx4LXRvb2x0aXB7dHJhbnNpdGlvbjouM3M7dmlzaWJpbGl0eTp2aXNpYmxlfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gdGFibGUgdGJvZHkgdHIgdGQudGFibGUtYnV0dG9uc3twYWRkaW5nLXRvcDouMmVtO3BhZGRpbmctYm90dG9tOi4yZW19LmZseC11aS1kYXRhdGFibGUtbWFpbiB0YWJsZSB0Ym9keSB0cjpudGgtb2YtdHlwZShldmVuKXtiYWNrZ3JvdW5kLWNvbG9yOiNmOGY5ZmF9LmZseC11aS1kYXRhdGFibGUtbWFpbiB0YWJsZSB0Ym9keSB0cjpudGgtb2YtdHlwZShvZGQpe2JhY2tncm91bmQtY29sb3I6I2ZmZn0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tZGFuZ2VyOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2ZmMTQ2Yjtib3JkZXI6MXB4IHNvbGlkICNmZjE0NmI7Ym94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjZmY1ZmI2Oy1tb3otYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjZmY1ZmI2Oy13ZWJraXQtYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjZmY1ZmI2Oy1vLWJveC1zaGFkb3c6MCAzcHggMTBweCAxcHggI2ZmNWZiNjstbXMtYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjZmY1ZmI2O3RyYW5zaXRpb246LjVzOy1tb3otdHJhbnNpdGlvbjouNXM7LXdlYmtpdC10cmFuc2l0aW9uOi41czstby10cmFuc2l0aW9uOi41czstbXMtdHJhbnNpdGlvbjouNXN9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuYnRuLWRhbmdlcjpmb2N1c3tiYWNrZ3JvdW5kLWNvbG9yOiNmNTAwNTc7Ym9yZGVyOjFweCBzb2xpZCAjZjUwMDU3fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmJ0bi13aGl0ZXtiYWNrZ3JvdW5kLWNvbG9yOiNmZmZ9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuYnRuLWRhcmt7YmFja2dyb3VuZC1jb2xvcjojMjIyIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tcHJpbWFyeXtiYWNrZ3JvdW5kLWNvbG9yOiMzNTk7Y29sb3I6I2ZmZjtib3JkZXI6MXB4IHNvbGlkICMzNTk7Ym94LXNoYWRvdzowIDNweCA1cHggMXB4ICNkZGQ7LW1vei1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1vLWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1tcy1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDtib3JkZXItcmFkaXVzOjNweH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tcHJpbWFyeTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM0NzY5YWQ7Ym9yZGVyOjFweCBzb2xpZCAjNDc2OWFkO2JveC1zaGFkb3c6MCAzcHggMTBweCAwICNiM2M0ZTY7LW1vei1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2Oy13ZWJraXQtYm94LXNoYWRvdzowIDNweCAxMHB4IDAgI2IzYzRlNjstby1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2Oy1tcy1ib3gtc2hhZG93OjAgM3B4IDEwcHggMCAjYjNjNGU2O3RyYW5zaXRpb246LjVzOy1tb3otdHJhbnNpdGlvbjouNXM7LXdlYmtpdC10cmFuc2l0aW9uOi41czstby10cmFuc2l0aW9uOi41czstbXMtdHJhbnNpdGlvbjouNXN9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuYnRuLXByaW1hcnk6Zm9jdXN7YmFja2dyb3VuZC1jb2xvcjojMzU5O2JvcmRlcjoxcHggc29saWQgIzM1OX0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tbGFyZ2V7cGFkZGluZy10b3A6MWVtIWltcG9ydGFudDtwYWRkaW5nLWJvdHRvbToxZW0haW1wb3J0YW50fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmJ0bi1tZWRpdW17cGFkZGluZy10b3A6LjdlbSFpbXBvcnRhbnQ7cGFkZGluZy1ib3R0b206LjdlbSFpbXBvcnRhbnR9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuYnRuLXN1Y2Nlc3N7Ym94LXNoYWRvdzowIDNweCA1cHggMXB4ICNkZGQ7LW1vei1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1vLWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1tcy1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDtib3JkZXItcmFkaXVzOjNweDtiYWNrZ3JvdW5kLWNvbG9yOiM1Y2I4NWM7Ym9yZGVyOjFweCBzb2xpZCAjNWNiODVjfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmJ0bi1zdWNjZXNzOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzcwY2M3MDtib3JkZXI6MXB4IHNvbGlkICM3MGNjNzA7Ym94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjOWRmOTlkOy1tb3otYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjOWRmOTlkOy13ZWJraXQtYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjOWRmOTlkOy1vLWJveC1zaGFkb3c6MCAzcHggMTBweCAxcHggIzlkZjk5ZDstbXMtYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjOWRmOTlkO3RyYW5zaXRpb246LjVzOy1tb3otdHJhbnNpdGlvbjouNXM7LXdlYmtpdC10cmFuc2l0aW9uOi41czstby10cmFuc2l0aW9uOi41czstbXMtdHJhbnNpdGlvbjouNXN9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuYnRuLXN1Y2Nlc3M6Zm9jdXN7YmFja2dyb3VuZC1jb2xvcjojNWNiODVjO2JvcmRlcjoxcHggc29saWQgIzVjYjg1Y30uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tZGVmYXVsdHtiYWNrZ3JvdW5kLWNvbG9yOiNmZmY7Ym94LXNoYWRvdzowIDNweCA1cHggMXB4ICNlZWU7LW1vei1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2VlZTstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZWVlOy1vLWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZWVlOy1tcy1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2VlZTtib3JkZXItcmFkaXVzOjNweDtib3JkZXI6MXB4IHNvbGlkICNkZGR9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuYnRuLWRlZmF1bHQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojZmZmO2JvcmRlcjoxcHggc29saWQgI2U3ZTdlNztib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICNlMmUyZTI7LW1vei1ib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICNlMmUyZTI7LXdlYmtpdC1ib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICNlMmUyZTI7LW8tYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjZTJlMmUyOy1tcy1ib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICNlMmUyZTI7dHJhbnNpdGlvbjouNXM7LW1vei10cmFuc2l0aW9uOi41czstd2Via2l0LXRyYW5zaXRpb246LjVzOy1vLXRyYW5zaXRpb246LjVzOy1tcy10cmFuc2l0aW9uOi41c30uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tZGVmYXVsdDpmb2N1c3tiYWNrZ3JvdW5kLWNvbG9yOiNmZmY7Ym9yZGVyOjFweCBzb2xpZCAjZGRkfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmJ0bi1zZWNvbmRhcnl7Ym94LXNoYWRvdzowIDNweCA1cHggMXB4ICNkZGQ7LW1vei1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDstd2Via2l0LWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1vLWJveC1zaGFkb3c6MCAzcHggNXB4IDFweCAjZGRkOy1tcy1ib3gtc2hhZG93OjAgM3B4IDVweCAxcHggI2RkZDtib3JkZXItcmFkaXVzOjNweDtiYWNrZ3JvdW5kLWNvbG9yOiMxZTg4ZTU7Y29sb3I6I2ZmZn0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tc2Vjb25kYXJ5OmhvdmVye2NvbG9yOiNmZmY7YmFja2dyb3VuZC1jb2xvcjojMjg5MmVmO2JvcmRlcjoxcHggc29saWQgIzI4OTJlZjtib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICM1NWJmZmY7LW1vei1ib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICM1NWJmZmY7LXdlYmtpdC1ib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICM1NWJmZmY7LW8tYm94LXNoYWRvdzowIDNweCAxMHB4IDFweCAjNTViZmZmOy1tcy1ib3gtc2hhZG93OjAgM3B4IDEwcHggMXB4ICM1NWJmZmY7dHJhbnNpdGlvbjouNXM7LW1vei10cmFuc2l0aW9uOi41czstd2Via2l0LXRyYW5zaXRpb246LjVzOy1vLXRyYW5zaXRpb246LjVzOy1tcy10cmFuc2l0aW9uOi41c30uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5idG4tc2Vjb25kYXJ5OmZvY3Vze2NvbG9yOiNmZmZ9LmZseC11aS1kYXRhdGFibGUtbWFpbiAucGFnaW5hdGlvbi1idXR0b257YmFja2dyb3VuZC1jb2xvcjojMzU5O2NvbG9yOiNmZmZ9LmZseC11aS1kYXRhdGFibGUtbWFpbiAudGFibGUtZm9udHtmb250LWZhbWlseTpLaHVsYSxzYW5zLXNlcmlmIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC50YWJsZS1oZWFkZXItaWNvbntwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDouMmVtO3dpZHRoOjgwcHg7aGVpZ2h0OjgwcHg7Zm9udC1zaXplOjUwcHg7bWFyZ2luLXRvcDotMzBweDtib3JkZXItcmFkaXVzOjVweCFpbXBvcnRhbnR9LmZseC11aS1kYXRhdGFibGUtbWFpbiAudGFibGUtdGl0bGV7YmFja2dyb3VuZC1jb2xvcjojMzU5O2NvbG9yOiNmZmY7Ym9yZGVyLXJhZGl1czoycHg7cGFkZGluZzoxZW07Zm9udC1zaXplOjE1cHg7Zm9udC13ZWlnaHQ6NzAwO21hcmdpbi1ib3R0b206MS41ZW07Zm9udC1mYW1pbHk6Um9ib3RvLHNhbnMtc2VyaWY7Ym94LXNoYWRvdzowIDFweCA1cHggMXB4ICNkZGQ7LW1vei1ib3gtc2hhZG93OjAgMXB4IDVweCAxcHggI2RkZDstd2Via2l0LWJveC1zaGFkb3c6MCAxcHggNXB4IDFweCAjZGRkOy1vLWJveC1zaGFkb3c6MCAxcHggNXB4IDFweCAjZGRkOy1tcy1ib3gtc2hhZG93OjAgMXB4IDVweCAxcHggI2RkZH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5kYW5nZXJ7YmFja2dyb3VuZC1jb2xvcjojZjUwMDU3O2NvbG9yOiNmZmZ9LmZseC11aS1kYXRhdGFibGUtbWFpbiAucHJpbWFyeXtiYWNrZ3JvdW5kLWNvbG9yOiMzNTk7Y29sb3I6I2ZmZn0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5zdWNjZXNze2JhY2tncm91bmQtY29sb3I6IzVjYjg1Yztjb2xvcjojZmZmfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmRlZmF1bHR7YmFja2dyb3VuZC1jb2xvcjojZmZmO2NvbG9yOiMwMDB9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuc2Vjb25kYXJ5e2JhY2tncm91bmQtY29sb3I6IzFlODhlNTtjb2xvcjojZmZmfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmJ0bi1jbGVhcntib3JkZXI6bm9uZSFpbXBvcnRhbnQ7Ym94LXNoYWRvdzpub25lIWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5pbnB1dC1ncm91cCwuZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5pbnB1dC1ncm91cCBpbnB1dHtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50IWltcG9ydGFudH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5pbnB1dC1ncm91cC1hZGRvbntib3JkZXI6bm9uZSFpbXBvcnRhbnQ7cGFkZGluZzowIWltcG9ydGFudDtib3gtc2hhZG93Om5vbmUhaW1wb3J0YW50O2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQhaW1wb3J0YW50fS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmlucHV0LWdyb3VwLWFkZG9uIGJ1dHRvbntib3JkZXI6MXB4IHNvbGlkIHRyYW5zcGFyZW50IWltcG9ydGFudDtib3gtc2hhZG93Om5vbmUhaW1wb3J0YW50O2JvcmRlci10b3A6bm9uZSFpbXBvcnRhbnQ7Ym9yZGVyLWJvdHRvbTpub25lIWltcG9ydGFudDtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50IWltcG9ydGFudDtib3JkZXItcmFkaXVzOjUwZW0haW1wb3J0YW50O2NvbG9yOiMzNTk7d2lkdGg6MzBweDtoZWlnaHQ6MzBweH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5pbnB1dC1ncm91cC1hZGRvbiBidXR0b24gaXtmb250LXNpemU6MThweH0uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5pbnB1dC1ncm91cC1hZGRvbiBidXR0b246ZGlzYWJsZWR7YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudCFpbXBvcnRhbnR9LmZseC11aS1kYXRhdGFibGUtbWFpbiAuaW5wdXQtZ3JvdXAtYWRkb24gYnV0dG9uOmRpc2FibGVkIGl7Y29sb3I6I2Y1MDA1N30uZmx4LXVpLWRhdGF0YWJsZS1tYWluIC5kYXRhLXNjcm9sbC1jb250ZW50e21heC13aWR0aDoxMDAlO21heC1oZWlnaHQ6NDAwcHg7bWFyZ2luLXRvcDotMWVtfS5mbHgtdWktZGF0YXRhYmxlLW1haW4gLmRhdGEtc2Nyb2xsLWNvbnRlbnQgdGFibGUgdGJvZHkgdHI6Zmlyc3QtY2hpbGQgdGQsLmZseC11aS1kYXRhdGFibGUtbWFpbiAuZmx4LXRhYmxlLXRoZWFkIHRyIHRoe2JvcmRlci10b3A6bm9uZSFpbXBvcnRhbnR9YF1cbn0pXG5leHBvcnQgY2xhc3MgRmx4VWlEYXRhdGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsQWZ0ZXJWaWV3SW5pdHtcbiAgQElucHV0KCkgY2xhc3NlczogYW55ID0ge30gOy8ve21haW5jb250YWluZXJ8c3Bpbm5lcnxhZGRCdXR0b258dGFibGVIZWFkZXJ8dGFibGVEYXRhfGV4cG9ydEJ1dHRvbnxTZWFyY2hCYXJ8dGFibGVUeXBlfVxuICBASW5wdXQoKSBoZWFkZXJzOiBBcnJheTxzdHJpbmc+ID0gW10gOyAvLyBUYWJsZSBoZWFkZXJzICh2OiAxLjAuMCkgXG4gIEBJbnB1dCgpIGxhenlsb2FkaW5nQ29uZmlnOiBhbnkgPSB7fSA7XG4gIEBJbnB1dCgpIGVtYmVkUGljdHVyZXM6IGFueSA9IHt9IDtcbiAgQElucHV0KCkgZGF0YUtleXM6IEFycmF5PHN0cmluZz4gPSBbXSA7IC8vIERhdGEga2V5cyB0byBwb3B1bGF0ZS4gICh2OiAxLjAuMClcbiAgQElucHV0KCkgZW5hYmxlRGF0YUV4cG9ydHM6IGJvb2xlYW4gPSBmYWxzZSA7Ly9EZWZhdWx0IHRvIGZhbHNlOyAodjogMS4wLjEpXG4gIEBJbnB1dCgpIGRhdGFFeHBvcnRzQ29uZmlnOiBhbnkgPSB7fSA7Ly8gZGF0YSBleHBvcnRzIGNvbmZpZ3VyYXRpb246IHtleHBvcnRzVG86WydwcmludCcsJ3dvcmQnLCdwZGYnLCdleGNlbCddLHRpdGxlOidFeHBvcnRzIGRhdGEnLGRhdGFDb2x1bW5zOltdfX0gRGF0YSBjb2x1bW5zIHRvIGV4cG9ydFxuICBASW5wdXQoKSBzaG93Qm90dG9tSW5mbzogZmFsc2UgOyAvLyBUbyBlbmFibGUgdGFibGUgYm90dG9tIGluZm9ybWF0aW9uXG4gIEBJbnB1dCgpIHNlYXJjaEtleXMgPSBbXSA7IC8vIEtleXMgdG8gc2VhcmNoIGZvciBzZWFyY2ggb3B0aW1pemF0aW9uLiAgKHY6IDEuMC4wKVxuICBASW5wdXQoKSBkYXRhU3JjS2V5OiBzdHJpbmcgPSAnJyAvLyBEYXRhIHRvIHJlYWQgZnJvbSBqc29uIHJlc3BvbnNlLiAgKHY6IDEuMC4wKVxuICBASW5wdXQoKSBoYXNBY3Rpb25CdXR0b25zOiBib29sZWFuID0gZmFsc2UgOyAvL3NwZWNpZnkgaWYgZGF0YXRhYmxlIHNob3VsZCBoYXZlIGFuZCBhZGQgYnV0dG9uLiAodjogMS4wLjApXG4gIEBJbnB1dCgpIGhpZGVOdW1iZXJzOiBib29sZWFuID0gZmFsc2UgOyAvL3NwZWNpZnkgaWYgdGhlIG51bWJlcnMuICAodjogMS4wLjApXG4gIEBJbnB1dCgpIGVuYWJsZU11bHRpcGxlU2VsZWN0aW9uOiBib29sZWFuID0gZmFsc2UgOyAvLyBFbmFibGUgbXVsdGlwbGUgc2VsZWN0IGlucHV0IGJveCB0byBhcHBlYXIuICh2OiAxLjAuMCkgZW5hYmxlTXVsdGlwbGVEZWxldGUgcmVuYW1lZCB0byBlbmFibGVNdWx0aXBsZVNlbGVjdGlvbiBpbiAodjoxLjAuMSlcbiAgQElucHV0KCkgbXVsdGlwbGVTZWxlY3RLZXk6IHN0cmluZyA9ICcnIDsgLy8gU3BlY2lmeSB3aGljaCBrZXkgdG8gc2VsZWN0LiAodjoxLjAuMCkgbXVsdGlwbGVEZWxldGVLZXkgcmVuYW1lZCB0byBtdWx0aXBsZVNlbGVjdEtleSBpbiAodjoxLjAuMCkgO1xuICBASW5wdXQoKSBoYXNBZGRCdXR0b246IGJvb2xlYW4gPSBmYWxzZSA7IC8vIEVuYWJsZSB0byBzaG93IGFkZCBidXR0b24gb24gdGhlIGhlYWRlci4gKHY6IDEuMC4wKVxuICBASW5wdXQoKSBkYXRhVXJsOiBzdHJpbmcgPSAnJyA7IC8vIFVybCB0byBsb2FkIHRhYmxlIGRhdGEuICh2OiAxLjAuMClcbiAgQElucHV0KCkgYWN0aW9uQnV0dG9uU3RhcnQ6IGJvb2xlYW4gPSBmYWxzZSA7XG4gIEBJbnB1dCgpIG11bHRpcGxlU2VsZWN0QnV0dG9uID0geyB0ZXh0OiAnU2VsZWN0ZWQnLCBpY29uOiAnJyB9OyAvLyBDaGFuZ2UgdGV4dCBhbmQgaWNvbiBvbiBtdWx0aXBsZSBzZWxlY3QgYnV0dG9uLiAodjogMS4wLjEpXG4gIEBJbnB1dCgpIHNlYXJjaFBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnRW50ZXIgbmFtZSB0byBzZWFyY2gnIDsgLy8gQ2hhbmdlIHNlYXJjaCBiYXIgcGxhY2Vob2xkZXIuICh2OiAxLjAuMClcbiAgQElucHV0KCkgYWN0aW9uSGVhZGVyOiBzdHJpbmcgPSAnQWN0aW9ucycgOyAvLyBDaGFuZ2UgdGV4dCBmb3IgYWN0aW9uIGJ1dHRvbnMgaGVhZGVyLiAodjogMS4wLjApXG4gIEBJbnB1dCgpIGxpbWl0OiBudW1iZXIgPSAyMCA7IC8vIFNwZWNpZnkgbnVtYmVyIG9mIGl0ZW1zIHBlciBwYWdpbmF0aW9uLiAodjogMS4wLjApXG4gIEBJbnB1dCgpIHNwaW5uZXJTcmM6IGFueSA9ICcnIDsgLy8gU3Bpbm5lciB0byBzaG93IHdoZW4gbG9hZGluZyBkYXRhIGZyb20gQVBJLiAodjogMS4wLjEpXG4gIEBJbnB1dCgpIGFjdGlvbkJ1dHRvbnM6IEFycmF5PE9iamVjdD4gPSBbXSA7IC8vIFNwZWNpZnkgYWN0aW9uIGJ1dHRvbnMuIE1ha2Ugc3VyZSB0byBzZXQgaGFzQWN0aW9uQnV0dG9ucyB0byB0cnVlIGlmIHlvdSB3YW50IHRvIHNob3cgYnV0dG9uIGluIHRoZSB0YWJsZSByb3cuICh2OiAxLjAuMClcbiAgQElucHV0KCkgcGFnaW5hdGlvbkJ1dHRvbnM6IGFueSA9IHtiYWNrZ3JvdW5kOicjZGRkZGRkJyx0ZXh0Q29sb3I6JyMzMzU1OTknfSA7IC8vIENoYW5nZSBidXR0b24gYnV0dG9uIGJhY2tncm91bmQgYW5kIHRleHRDb2xvci4gKHY6IDEuMC4wKVxuICBASW5wdXQoKSB0YWJsZUhlYWRlcjogYW55ID0ge2JhY2tncm91bmQ6JyNmZmZmZmYnLHRleHRDb2xvcjonIzMzNTU5OSd9IDsgLy8gQ2hhbmdlIHRhYmxlIGhlYWRlciBiYWNrZ3JvdW5kIGFuZCB0ZXh0IGNvbG9yLiAodjogMS4wLjApXG4gIEBJbnB1dCgpIHNlYXJjaEJ1dHRvbjogYW55ID0ge2JhY2tncm91bmQ6JyNjY2NjY2MnLHRleHRDb2xvcjonIzMzNTU5OSd9IDsgLy8gQ2hhbmdlIGJhY2tncm91bmQgYW5kIHRleHQgY29sb3Igb2YgdGhlIHNlYXJjaCBidXR0b24uICh2OiAxLjAuMClcbiAgQElucHV0KCkgYWRkQnV0dG9uOiBhbnkgPSB7fSA7IC8vQ2hhbmdlIGJhY2tncm91bmQgYW5kIHRleHQgY29sb3Igb2YgdGhlIGFkZCBidXR0b24uICh2OiAxLjAuMClcbiAgQElucHV0KCkgc2VhcmNoQmFyOiBhbnkgPSB7Ym9yZGVyU2l6ZTonMXB4Jyxib3JkZXJDb2xvcjonI2NjYycsYmFja2dyb3VuZDonI2ZmZmZmZicsdGV4dENvbG9yOicjMDAwMDAwJ30gOyAvLyBDaGFuZ2UgYmFja2dyb3VuZCBhbmQgdGV4dCBjb2xvciBvZiB0aGUgc2VhcmNoIGJhci4gKHY6IDEuMC4wKVxuICBASW5wdXQoKSBhY3Rpb25CdXR0b25zQ29uZmlnOiBhbnkgPSB7cG9zaXRpb246J3JpZ2h0JyxiZWZvcmVOdW1iZXJzOnRydWV9IC8vIGxlZnQgfCByaWdodFxuICBAT3V0cHV0KCkgZmlyc3RBY3Rpb25CdXR0b25DbGlja2VkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpIDsgLy8gSGFuZGxlIGZpcnN0IGFjdGlvbiBidXR0b24uICh2OiAxLjAuMClcbiAgQE91dHB1dCgpIHNlY29uZEFjdGlvbkJ1dHRvbkNsaWNrZWQ6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCkgOyAvLyBIYW5kbGUgc2Vjb25kIGFjdGlvbiBidXR0b24uICh2OiAxLjAuMClcbiAgQE91dHB1dCgpIHRoaXJkQWN0aW9uQnV0dG9uQ2xpY2tlZDogRXZlbnRFbWl0dGVyPGFueT4gPSAgIG5ldyBFdmVudEVtaXR0ZXI8YW55PigpIDsgLy8gSGFuZGxlIHRoaXJkIGFjdGlvbiBidXR0b24uICh2OiAxLjAuMClcbiAgQE91dHB1dCgpIG11bHRpcGxlU2VsZWN0Q2xpY2tlZDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKSA7IC8vIEhhbmRsZSBtdWx0aXBsZSBzZWxlY3QgYnV0dG9uLiAodjogMS4wLjApXG4gIEBPdXRwdXQoKSBhZGRCdXR0b25DbGlja2VkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpIDsgLy8gSGFuZGxlIGFkZCBidXR0b24uICh2OiAxLjAuMClcbiAgLyoqICAxOC8xMi8yMDE4ICovXG5cbiAgLy8ge2F0SW5kZXhlczpbMF0sZnJvbTowLHRvOjIsYXBwZW5kRG90czonLi4nfVxuICBASW5wdXQoKSB0ZXh0U3Vic3RyaW5nOiBhbnkgPSB7fSA7IFxuICBASW5wdXQoKSBjb25kaXRpb25NYW5pcHVsYXRvcjogYW55ID0ge30gO1xuICBpc0V4cG9ydEFsbDogYm9vbGVhbiA9IGZhbHNlIDtcbiAgc2VhcmNoRm9ybTogRm9ybUdyb3VwIDtcbiAgdERhdGE6IGFueSA9IFtdIDtcbiAgYmVoYXZpb3I6IEJlaGF2aW9yU3ViamVjdDxhbnk+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChbXSk7XG4gIC8vS2VlcCB0cmFjayBvZiBjdXJyZW50IGRhdGEgYWZ0ZXIgc2VhcmNoLiBJZiBzZWFyY2ggc3RyaW5nIGlzIGVtcHR5IHNldCBjdXJyZW50IHZpZXcgZGF0YVxuICBwdWJsaWMgc2VhcmNoRGF0YVRlbXBPZmZzZXQgPSBbXTtcbiAgLy9EYXRhIHRvIGRpc3BsYXkgaW4gdGhlIHRhYmxlIGJhc2VkIG9uIG9mZnNldFxuICBwdWJsaWMgZGlzcGxheURhdGEgPSB0aGlzLmJlaGF2aW9yLmFzT2JzZXJ2YWJsZSgpOyBcbiAgLy9LZWVwIHRyYWNrIG9mIHBhZ2luYXRpb24gbnVtYmVyc1xuICBwdWJsaWMgb2Zmc2V0ID0gMTtcbiAgcHVibGljIHJlbG9hZFVybDpzdHJpbmcgIDtcbiAgcHVibGljIGlzU2VhcmNoaW5nOiBib29sZWFuIDsgLy8gSW5kaWNhdGUgaWYgdXNlciBpcyBzZWFyY2hpbmdcbiAgc2VhcmNoUmVzdWx0Rm91bmQ6QXJyYXk8YW55PiA9IFtdIDsgLy8gU3RvcmUgdGhlIHNlYXJjaCByZXN1bHRzXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBfX2Zvcm06IEZvcm1CdWlsZGVyLHB1YmxpYyBzZXJ2aWNlOiBGbHhVaURhdGF0YWJsZVNlcnZpY2Upe1xuICAgIFxuICB9ICBcbiAgXG4gIHJlbG9hZCgpe1xuICAgICAgdGhpcy5zZXJ2aWNlLmxvYWRGbHhEYXRhVGFibGVEYXRhKHRoaXMucmVsb2FkVXJsLHRydWUpXG4gIH1cblxuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSBjaGVja2VkIEV4cG9ydCBhbGwgc2VsZWN0aW9uXG4gICAqL1xuICBjaGVja1RvRXhwb3J0T3B0aW9uKGNoZWNrZWQ6Ym9vbGVhbil7XG4gICAgdGhpcy5pc0V4cG9ydEFsbCA9IGNoZWNrZWQgO1xuICB9XG5cbiAgLyoqXG4gICAqIFxuICAgKiBAcGFyYW0gZXhwb3J0VHlwZSBFeHBvcnQgdHlwZTogcHJpbnR8cGRmfGV4Y2VsfHdvcmRcbiAgICovXG4gIGV4cG9ydERvY3VtZW50c0FzKGV4cG9ydFR5cGU6c3RyaW5nKXtcbiAgICBsZXQgbG9hZGluZzogSFRNTERpdkVsZW1lbnQgPSA8SFRNTERpdkVsZW1lbnQ+IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZXhwb3J0X2xvYWRpbmdcIikgO1xuICAgIGxvYWRpbmcuc3R5bGUuZGlzcGxheSA9ICdibG9jaycgO1xuICAgIGxldCBoZWFkZXJzID0gKCF0aGlzLmRhdGFFeHBvcnRzQ29uZmlnLmRhdGFDb2x1bW5zIHx8IHRoaXMuZGF0YUV4cG9ydHNDb25maWcuZGF0YUNvbHVtbnMubGVuZ3RoPDEpID8gdGhpcy5kYXRhS2V5cyA6IHRoaXMuZGF0YUV4cG9ydHNDb25maWcuZGF0YUNvbHVtbnMgO1xuICAgIGxldCBkYXRhVG9FeHBvcnQgPSAoIXRoaXMuaXNFeHBvcnRBbGwpID8gdGhpcy5kaXNwbGF5RGF0YSA6IHRoaXMuc2VydmljZS5mbHhEYXRhIDtcbiAgICBcbiAgICAvL1N1YnNjcmliZSB0byBkYXRhXG4gICAgZGF0YVRvRXhwb3J0LnN1YnNjcmliZSgoZGF0YSkgPT4geyAgICAgICAgICAgICAgXG4gICAgICAgIGxldCBhcnJheU9iajogQXJyYXk8YW55PiA9IFtdIDtcbiAgICAgICAgLy9Mb29wIGFuZCBwdXNoIGRhdGFcbiAgICAgICAgZm9yKGxldCBkIG9mIGRhdGEpe1xuICAgICAgICAgICAgbGV0IG9iajogYW55ID0ge30gO1xuICAgICAgICAgICAgZm9yKGxldCBoPTA7aDxoZWFkZXJzLmxlbmd0aDtoKyspe1xuICAgICAgICAgICAgICAgIG9ialtoZWFkZXJzW2hdXSA9IGRbaGVhZGVyc1toXV0gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXJyYXlPYmoucHVzaChvYmopIDtcbiAgICAgICAgfVxuICAgICAgICBpZihleHBvcnRUeXBlPT0ncHJpbnQnKXtcbiAgICAgICAgICAgIHRyeXtcbiAgICAgICAgICAgIHByaW50SlMoe3ByaW50YWJsZTphcnJheU9iaixwcm9wZXJ0aWVzOmhlYWRlcnMsdHlwZTonanNvbid9KSA7XG4gICAgICAgICAgICBsb2FkaW5nLnN0eWxlLmRpc3BsYXkgPSAnbm9uZScgO1xuICAgICAgICAgICAgfWNhdGNoKGUpe1xuICAgICAgICAgICAgbG9hZGluZy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnIDtcbiAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdQcmludEpTIG5vdCBmb3VuZC4gQWRkIGBodHRwczovL3ByaW50anMtNGRlNi5reGNkbi5jb20vcHJpbnQubWluLmpzYCB0byB5b3VyIGluZGV4Lmh0bWwgb3IgYWRkIGFzIHBhcnQgb2YgYW5ndWxhci5qc29uIHNjcmlwdCcpIDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICBsZXQgZXh0ZW5zaW9uID0gKGV4cG9ydFR5cGU9PSdwZGYnKSA/ICdwZGYnOiAoZXhwb3J0VHlwZT09J2V4Y2VsJykgPyAneGxzeCc6ICdkb2N4J1xuICAgICAgICAgICAgbGV0IHBhZ2VJZCA9IChleHBvcnRUeXBlPT0ncGRmJykgPyAzOiAoZXhwb3J0VHlwZT09J2V4Y2VsJykgPyA1OiA0IDtcblxuICAgICAgICAgICAgbGV0IHJlcXVlc3REYXRhOiBhbnkgPSB7XCJkYXRhXCI6SlNPTi5zdHJpbmdpZnkoYXJyYXlPYmopfVxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLnBvc3REYXRhKCdodHRwOi8vZXhwb3J0ZXIuYXp1cmV3ZWJzaXRlcy5uZXQvYXBpL2V4cG9ydC9FeHBvcnRGcm9tSlNPTi8nLHBhZ2VJZCxyZXF1ZXN0RGF0YSkuc3Vic2NyaWJlKChyZXNwKSA9PntcbiAgICAgICAgICAgICAgICB2YXIgZG93bmxvYWQgPSAnaHR0cDovL2V4cG9ydGVyLmF6dXJld2Vic2l0ZXMubmV0L2FwaS9leHBvcnQvR2V0RmlsZS8nICsgcmVzcCA7XG4gICAgICAgICAgICAgICAgZG93bmxvYWQgKz0gXCI/ZmlsZU5hbWU9YW5kcmVpJmV4dGVuc2lvbj1cIisgZXh0ZW5zaW9uO1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gZG93bmxvYWQgO1xuICAgICAgICAgICAgICAgIGxvYWRpbmcuc3R5bGUuZGlzcGxheSA9ICdub25lJyA7XG4gICAgICAgICAgICB9LChlID0+IHtcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdmaWxlIGV4cG9ydCBlcnJvcicsZSkgO1xuICAgICAgICAgICAgfSkpXG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgfSkudW5zdWJzY3JpYmUoKSA7ICAgIFxuICB9XG5cbiAgaGFzSW1hZ2VFbWJlZGVkKCk6IGJvb2xlYW57XG4gICAgcmV0dXJuIHRoaXMuZW1iZWRQaWN0dXJlcy5oYXNPd25Qcm9wZXJ0eShcImluZGV4XCIpIDtcbiAgfVxuXG4gIGdldEltYWdlKCl7XG4gICAgICBjb25zb2xlLmxvZygnZW9lb2UnKVxuICAgIC8vICAgbGV0IGltZyA9IG5ldyBJbWFnZSgpIDtcbiAgICAvLyAgIGltZy5zcmMgPSBpbWFnZVNyYyA7XG4gICAgLy8gICBpbWcub25sb2FkID0gKChlKT0+e1xuICAgIC8vICAgICAgIHJldHVybiBpbWFnZVNyYyA7XG4gICAgLy8gICB9KSA7XG4gICAgLy8gICBpbWcub25lcnJvciA9ICgoZSk9PntcbiAgICAvLyAgICAgcmV0dXJuIHRoaXMuZW1iZWRQaWN0dXJlcy5mYWxsYmFja1VybCA7XG4gICAgLy8gICB9KVxuICB9XG5cbiAgSlNPTlRvQ1NWQ29udmVydG9yKEpTT05EYXRhLCBSZXBvcnRUaXRsZSwgU2hvd0xhYmVsKSB7XG4gICAgLy9JZiBKU09ORGF0YSBpcyBub3QgYW4gb2JqZWN0IHRoZW4gSlNPTi5wYXJzZSB3aWxsIHBhcnNlIHRoZSBKU09OIHN0cmluZyBpbiBhbiBPYmplY3RcbiAgICB2YXIgYXJyRGF0YSA9IHR5cGVvZiBKU09ORGF0YSAhPSAnb2JqZWN0JyA/IEpTT04ucGFyc2UoSlNPTkRhdGEpIDogSlNPTkRhdGE7XG4gICAgXG4gICAgdmFyIENTViA9ICcnOyAgICBcbiAgICAvL1NldCBSZXBvcnQgdGl0bGUgaW4gZmlyc3Qgcm93IG9yIGxpbmVcbiAgICBcbiAgICBDU1YgKz0gUmVwb3J0VGl0bGUgKyAnXFxyXFxuXFxuJztcblxuICAgIC8vVGhpcyBjb25kaXRpb24gd2lsbCBnZW5lcmF0ZSB0aGUgTGFiZWwvSGVhZGVyXG4gICAgaWYgKFNob3dMYWJlbCkge1xuICAgICAgICB2YXIgcm93ID0gXCJcIjtcbiAgICAgICAgXG4gICAgICAgIC8vVGhpcyBsb29wIHdpbGwgZXh0cmFjdCB0aGUgbGFiZWwgZnJvbSAxc3QgaW5kZXggb2Ygb24gYXJyYXlcbiAgICAgICAgZm9yICh2YXIgaW5kZXggaW4gYXJyRGF0YVswXSkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvL05vdyBjb252ZXJ0IGVhY2ggdmFsdWUgdG8gc3RyaW5nIGFuZCBjb21tYS1zZXByYXRlZFxuICAgICAgICAgICAgcm93ICs9IGluZGV4ICsgJywnO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93ID0gcm93LnNsaWNlKDAsIC0xKTtcbiAgICAgICAgXG4gICAgICAgIC8vYXBwZW5kIExhYmVsIHJvdyB3aXRoIGxpbmUgYnJlYWtcbiAgICAgICAgQ1NWICs9IHJvdyArICdcXHJcXG4nO1xuICAgIH1cbiAgICBcbiAgICAvLzFzdCBsb29wIGlzIHRvIGV4dHJhY3QgZWFjaCByb3dcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyckRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHJvdyA9IFwiXCI7XG4gICAgICAgIFxuICAgICAgICAvLzJuZCBsb29wIHdpbGwgZXh0cmFjdCBlYWNoIGNvbHVtbiBhbmQgY29udmVydCBpdCBpbiBzdHJpbmcgY29tbWEtc2VwcmF0ZWRcbiAgICAgICAgZm9yICh2YXIgaW5kZXggaW4gYXJyRGF0YVtpXSkge1xuICAgICAgICAgICAgcm93ICs9ICdcIicgKyBhcnJEYXRhW2ldW2luZGV4XSArICdcIiwnO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93LnNsaWNlKDAsIHJvdy5sZW5ndGggLSAxKTtcbiAgICAgICAgXG4gICAgICAgIC8vYWRkIGEgbGluZSBicmVhayBhZnRlciBlYWNoIHJvd1xuICAgICAgICBDU1YgKz0gcm93ICsgJ1xcclxcbic7XG4gICAgfVxuXG4gICAgaWYgKENTViA9PSAnJykgeyAgICAgICAgXG4gICAgICAgIGFsZXJ0KFwiSW52YWxpZCBkYXRhXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgfSAgIFxuICAgIFxuICAgIC8vR2VuZXJhdGUgYSBmaWxlIG5hbWVcbiAgICB2YXIgZmlsZU5hbWUgPSBcIk15UmVwb3J0X1wiO1xuICAgIC8vdGhpcyB3aWxsIHJlbW92ZSB0aGUgYmxhbmstc3BhY2VzIGZyb20gdGhlIHRpdGxlIGFuZCByZXBsYWNlIGl0IHdpdGggYW4gdW5kZXJzY29yZVxuICAgIGZpbGVOYW1lICs9IFJlcG9ydFRpdGxlLnJlcGxhY2UoLyAvZyxcIl9cIik7ICAgXG4gICAgXG4gICAgLy9Jbml0aWFsaXplIGZpbGUgZm9ybWF0IHlvdSB3YW50IGNzdiBvciB4bHNcbiAgICB2YXIgdXJpID0gJ2RhdGE6dGV4dC9jc3Y7Y2hhcnNldD11dGYtOCwnICsgZXNjYXBlKENTVik7XG4gICAgXG4gICAgLy8gTm93IHRoZSBsaXR0bGUgdHJpY2t5IHBhcnQuXG4gICAgLy8geW91IGNhbiB1c2UgZWl0aGVyPj4gd2luZG93Lm9wZW4odXJpKTtcbiAgICAvLyBidXQgdGhpcyB3aWxsIG5vdCB3b3JrIGluIHNvbWUgYnJvd3NlcnNcbiAgICAvLyBvciB5b3Ugd2lsbCBub3QgZ2V0IHRoZSBjb3JyZWN0IGZpbGUgZXh0ZW5zaW9uICAgIFxuICAgIFxuICAgIC8vdGhpcyB0cmljayB3aWxsIGdlbmVyYXRlIGEgdGVtcCA8YSAvPiB0YWdcbiAgICB2YXIgbGluazogYW55ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7ICAgIFxuICAgIGxpbmsuaHJlZiA9IHVyaTtcbiAgICBcbiAgICAvL3NldCB0aGUgdmlzaWJpbGl0eSBoaWRkZW4gc28gaXQgd2lsbCBub3QgZWZmZWN0IG9uIHlvdXIgd2ViLWxheW91dFxuICAgIGxpbmsuc3R5bGUgPSBcInZpc2liaWxpdHk6aGlkZGVuXCI7XG4gICAgbGluay5kb3dubG9hZCA9IGZpbGVOYW1lICsgXCIuY3N2XCI7XG4gICAgXG4gICAgLy90aGlzIHBhcnQgd2lsbCBhcHBlbmQgdGhlIGFuY2hvciB0YWcgYW5kIHJlbW92ZSBpdCBhZnRlciBhdXRvbWF0aWMgY2xpY2tcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xuICAgIGxpbmsuY2xpY2soKTtcbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGxpbmspO1xufVxuXG4gIC8qKlxuICAgKiBcbiAgICogQHBhcmFtIG5ld0RhdGEgXG4gICAqL1xuICBjaGFuZ2VEaXNwbGF5RGF0YShuZXdEYXRhKSB7XG4gICAgdGhpcy5iZWhhdmlvci5uZXh0KG5ld0RhdGEpO1xuICAgIHRoaXMuc2V0Q29sdW1uV2lkdGhzKCkgO1xuICB9XG5cbiAgbmdPbkluaXQoKXtcbiAgICAkKHdpbmRvdykucmVzaXplKGZ1bmN0aW9uKCkge1xuICAgICAgICAvKiBTYW1lIGFzIGJlZm9yZSAqLyBcbiAgICB9KS5yZXNpemUoKTsgXG5cbiAgICBpZih0aGlzLmlzTGF6eWxvYWRpbmdFbmFibGVkKCkpe1xuICAgICAgICB0aGlzLnJlbG9hZFVybCA9IHRoaXMuZGF0YVVybCsnJicrdGhpcy5sYXp5bG9hZGluZ0NvbmZpZy5hcGlPZmZzZXRLZXkrJz0wJicrdGhpcy5sYXp5bG9hZGluZ0NvbmZpZy5hcGlTZWFyY2hLZXkrJz0nIDtcbiAgICB9ZWxzZXtcbiAgICAgICAgdGhpcy5yZWxvYWRVcmwgPSB0aGlzLmRhdGFVcmwgO1xuICAgIH1cbiAgICAgIHRoaXMuc2VhcmNoRm9ybSA9IHRoaXMuX19mb3JtLmdyb3VwKHtcbiAgICAgICAgICBzZWFyY2hTdHJpbmc6WycnLFZhbGlkYXRvcnMucmVxdWlyZWRdXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2VhcmNoRm9ybSA9IHRoaXMuX19mb3JtLmdyb3VwKHtcbiAgICAgICAgc2VhcmNoU3RyaW5nOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdXG4gICAgfSk7XG4gICAgdGhpcy5zZXJ2aWNlLmxpbWl0ID0gdGhpcy5saW1pdDtcbiAgICB0aGlzLnNlcnZpY2Uuc2V0TGF6eWxvYWRpbmdDb25maWcodGhpcy5sYXp5bG9hZGluZ0NvbmZpZykgO1xuICAgIHRoaXMuc2VydmljZS5zZXREYXRhVXJsKHRoaXMuZGF0YVVybCk7XG4gICAgdGhpcy5zZXJ2aWNlLnNldERhdGFTcmNLZXkodGhpcy5kYXRhU3JjS2V5KTtcbiAgICBsZXQgdXJsID0gKHRoaXMuaXNMYXp5bG9hZGluZ0VuYWJsZWQoKSkgPyB0aGlzLmRhdGFVcmwrJyYnK3RoaXMubGF6eWxvYWRpbmdDb25maWcuYXBpT2Zmc2V0S2V5Kyc9MCYnK3RoaXMubGF6eWxvYWRpbmdDb25maWcuYXBpU2VhcmNoS2V5Kyc9JyA6ICB0aGlzLmRhdGFVcmwgO1xuICAgIHRoaXMuc2VydmljZS5sb2FkRmx4RGF0YVRhYmxlRGF0YSh1cmwpO1xuICAgICAgdGhpcy5zZXJ2aWNlLmZseERhdGEuc3Vic2NyaWJlKChyZXNwKSA9PiB7XG4gICAgICAgIHRoaXMudERhdGEgPSByZXNwIDtcbiAgICAgICAgbGV0IG9iajogQXJyYXk8YW55PiA9IFtdO1xuICAgICAgICBpZiAodGhpcy50RGF0YS5sZW5ndGggPiB0aGlzLmxpbWl0KSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGltaXQ7IGkrKykge1xuICAgICAgICAgICAgICAgIG9iai5wdXNoKHRoaXMudERhdGFbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAvLyB0aGlzLnNlcnZpY2UuZGF0YU9mZnNldCA9IHRoaXMubGltaXQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgY291bnRlcjogbnVtYmVyID0gMDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50RGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG9iai5wdXNoKHRoaXMudERhdGFbaV0pO1xuICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgLy8gdGhpcy5zZXJ2aWNlLmRhdGFPZmZzZXQgPSBvYmoubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VhcmNoRGF0YVRlbXBPZmZzZXQgPSBvYmo7XG4gICAgICAgIHRoaXMuY2hhbmdlRGlzcGxheURhdGEob2JqKTtcbiAgICB9KVxuICB9XG5cbiAgICBzZWFyY2hEYXRhSW5BcGkodmFsdWVzLGZvcm0pe1xuICAgICAgICB0aGlzLnNlcnZpY2UuY2hhZ2VEYXRhVGFibGUoW10pIDsgICAgICAgICAgIFxuICAgICAgICB0aGlzLnNlcnZpY2UubG9hZEZseERhdGFUYWJsZURhdGEodGhpcy5kYXRhVXJsKycmJyt0aGlzLmxhenlsb2FkaW5nQ29uZmlnLmFwaU9mZnNldEtleSsnPTAmJyt0aGlzLmxhenlsb2FkaW5nQ29uZmlnLmFwaVNlYXJjaEtleSsnPScrdmFsdWVzLnNlYXJjaFN0cmluZykgO1xuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAgICBsZXQgZWFjaENvbHVtbldpZHRoID0gdGhpcy5yZXR1ckNvbHVtbnN3aWR0aCgpIDtcbiAgICAgICAgXG4gICAgICAgICQod2luZG93KS5yZWFkeShmdW5jdGlvbigpe1xuICAgICAgICAgICAgJChcIi5mbHgtdGFibGUtdGhlYWQgdHIgdGhcIikuY3NzKHsnd2lkdGgnOmVhY2hDb2x1bW5XaWR0aCsnJSd9KTtcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBzZXRDb2x1bW5XaWR0aHMoKXsgICAgICAgIFxuICAgICAgICBsZXQgZWFjaENvbHVtbldpZHRoID0gdGhpcy5yZXR1ckNvbHVtbnN3aWR0aCgpIDtcbiAgICAgICAgJCh3aW5kb3cpLnJlYWR5KGZ1bmN0aW9uKCl7ICAgXG4gICAgICAgICAgICAkKFwiLmZseC10YWJsZS1kYXRhIHRib2R5IHRyIHRkXCIpLmNzcyh7J3dpZHRoJzplYWNoQ29sdW1uV2lkdGgrJyUnfSk7ICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgcHJpdmF0ZSByZXR1ckNvbHVtbnN3aWR0aCgpe1xuICAgIGxldCBoYXNOdW1iZXJzID0gKCF0aGlzLmhpZGVOdW1iZXJzKSA/IDAgOiAxIDtcbiAgICBsZXQgaGFzQWN0aW9uQnV0dG9ucyA9ICghdGhpcy5oYXNBY3Rpb25CdXR0b25zKSA/IDAgOiAxIDtcblxuICAgIGxldCBudW1iZXJPZkNvbHVtbnMgPSAodGhpcy5oZWFkZXJzLmxlbmd0aCsxKStoYXNBY3Rpb25CdXR0b25zK2hhc051bWJlcnMgO1xuICAgIGNvbnNvbGUubG9nKCdudW1iZXJfb2ZfY29sdW1ucycsbnVtYmVyT2ZDb2x1bW5zKVxuICAgIGxldCBlYWNoQ29sdW1uV2lkdGggPSAxMDAvbnVtYmVyT2ZDb2x1bW5zIDtcblxuICAgIHJldHVybiBlYWNoQ29sdW1uV2lkdGggO1xuICB9XG5cbiAgYWN0aW9uQnV0dG9uQ2xpY2tlZChpbmRleDpudW1iZXIsYnV0dG9uSW5kZXg6bnVtYmVyKXtcbiAgICB0aGlzLmRpc3BsYXlEYXRhLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICBpZiAoYnV0dG9uSW5kZXggPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3RBY3Rpb25CdXR0b25DbGlja2VkLmVtaXQoeyBpbmRleDogaW5kZXgsIGRhdGE6IGRhdGFbaW5kZXhdIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJ1dHRvbkluZGV4ID09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlY29uZEFjdGlvbkJ1dHRvbkNsaWNrZWQuZW1pdCh7IGluZGV4OiBpbmRleCwgZGF0YTogZGF0YVtpbmRleF0gfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRoaXJkQWN0aW9uQnV0dG9uQ2xpY2tlZC5lbWl0KHsgaW5kZXg6IGluZGV4LCBkYXRhOiBkYXRhW2luZGV4XSB9KTtcbiAgICAgICAgfVxuICAgIH0pLnVuc3Vic2NyaWJlKCkgO1xuICB9XG5cbiAgYWRkQnV0dG9uQ2xpY2soKXtcbiAgICB0aGlzLmFkZEJ1dHRvbkNsaWNrZWQuZW1pdCgpIDtcbiAgfVxuXG4gIGNvbmZpcm1EZWxldGUoKXtcbiAgICByZXR1cm4gdGhpcy5tdWx0aXBsZVNlbGVjdENsaWNrZWQuZW1pdCh0aGlzLnNlcnZpY2UubXVsdGlwbGVEZWxldGlvbik7XG4gIH1cblxuICBhZGRSZW1vdmUoY2hlY2tlZDpib29sZWFuKXtcbiAgICBpZiAoY2hlY2tlZCkge1xuICAgICAgICB0aGlzLmRpc3BsYXlEYXRhLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgbGV0IGNvdW50ZXI6IG51bWJlciA9IDA7XG4gICAgICAgICAgICBmb3IgKGxldCBpIG9mIGRhdGEpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlcnZpY2UubXVsdGlwbGVEZWxldGlvbi5wdXNoKGlbdGhpcy5tdWx0aXBsZVNlbGVjdEtleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZSkgeyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuc2VydmljZS5tdWx0aXBsZURlbGV0aW9uKSA7XG4gICAgICAgIH0pLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnNlcnZpY2UubXVsdGlwbGVEZWxldGlvbiA9IFtdO1xuICAgIH0gICAgICAgIFxuICB9XG5cbiAgYWRkUmVtb3ZlRGVsZXRlSXRlbShkYXRhS2V5dmFsdWU6YW55LCBpbmRleDpudW1iZXIsIHNlbGVjdGVkOmJvb2xlYW4pe1xuICAgIGlmICghc2VsZWN0ZWQpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNlcnZpY2UubXVsdGlwbGVEZWxldGlvbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGRhdGFLZXl2YWx1ZSA9PSB0aGlzLnNlcnZpY2UubXVsdGlwbGVEZWxldGlvbltpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VydmljZS5tdWx0aXBsZURlbGV0aW9uLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5RGF0YS5zdWJzY3JpYmUoKHJlc3ApID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5tdWx0aXBsZURlbGV0aW9uLnB1c2gocmVzcFtpbmRleF1bdGhpcy5tdWx0aXBsZVNlbGVjdEtleV0pO1xuICAgICAgICB9KS51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgIC8vIGNvbnNvbGUubG9nKCdsZWZ0ICcrZGF0YUtleXZhbHVlLHRoaXMuc2VydmljZS5tdWx0aXBsZURlbGV0aW9uKSA7XG4gIH1cblxuICBnZXRTZWFyY2hDb2x1bW5zKCl7XG4gICAgcmV0dXJuICh0aGlzLmhhc0FkZEJ1dHRvbikgPyAodGhpcy5lbmFibGVEYXRhRXhwb3J0cykgPyAnY29sLW1kLTYgc2VhcmNoLWNvbnRhaW5lcicgOiAnY29sLW1kLTcgc2VhcmNoLWNvbnRhaW5lcicgOlxuICAgICh0aGlzLmVuYWJsZURhdGFFeHBvcnRzKSA/ICdjb2wtbWQtNyBzZWFyY2gtY29udGFpbmVyJyA6ICdjb2wtbWQtOCBzZWFyY2gtY29udGFpbmVyJztcbiAgfVxuXG4gIGRpc2FibGVQcmV2dEJ1dHRvbigpe1xuICAgICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLnNlcnZpY2UuZGF0YU9mZnNldC90aGlzLmxpbWl0KTw9MSA7XG4gIH1cblxuICBkaXNhYmxlTmV4dEJ1dHRvbigpe1xuICAgICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLnNlcnZpY2UuZGF0YU9mZnNldC90aGlzLmxpbWl0KT09TWF0aC5jZWlsKHRoaXMuc2VydmljZS50b3RhbEl0ZW1zL3RoaXMubGltaXQpIDtcbiAgfVxuXG4gIGlzTGF6eWxvYWRpbmdFbmFibGVkKCk6IGJvb2xlYW57XG4gICAgICByZXR1cm4gdGhpcy5sYXp5bG9hZGluZ0NvbmZpZy5oYXNPd25Qcm9wZXJ0eShcImFwaU9mZnNldEtleVwiKSAmJiB0aGlzLmxhenlsb2FkaW5nQ29uZmlnLmFwaU9mZnNldEtleSA7XG4gIH1cblxuICBuZXh0UHJldkl0ZW0odHlwZTpzdHJpbmcpe1xuICAgIGlmKHRoaXMuaXNMYXp5bG9hZGluZ0VuYWJsZWQoKSl7XG4gICAgICAgIHRoaXMuc2VydmljZS5sb2FkRmluaXNoID0gZmFsc2UgO1xuICAgICAgICB0aGlzLnNlcnZpY2UuZ2V0RGF0YUxlbmd0aCgpLnRoZW4oZGF0YUxlbmd0aD0+eyAgICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5jaGFnZURhdGFUYWJsZShbXSkgOyAgIFxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmRhdGFPZmZzZXQgPSAodHlwZT09J3ByZXYnKSA/ICgodGhpcy5zZXJ2aWNlLmRhdGFPZmZzZXQgLSB0aGlzLmxpbWl0KSAtIHRoaXMubGltaXQpIDogdGhpcy5zZXJ2aWNlLmRhdGFPZmZzZXQ7ICBcbiAgICAgICAgICAgIGxldCB1cmwgPSAodGhpcy5pc0xhenlsb2FkaW5nRW5hYmxlZCgpKSA/IHRoaXMuZGF0YVVybCsnJicrdGhpcy5sYXp5bG9hZGluZ0NvbmZpZy5hcGlPZmZzZXRLZXkrJz0nKyB0aGlzLnNlcnZpY2UuZGF0YU9mZnNldCArJyYnK3RoaXMubGF6eWxvYWRpbmdDb25maWcuYXBpU2VhcmNoS2V5Kyc9JyA6ICB0aGlzLmRhdGFVcmwgOyAgXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UubG9hZEZseERhdGFUYWJsZURhdGEodXJsKSA7XG4gICAgICAgIH0pLmNhdGNoKGU9PntcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ2Vycm9yJyxlKSA7XG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiA7XG4gICAgfVxuXG4gICAgLy8gUGFnaW5hdGUgaWYgbGF6eWxvYWRpbmcgaXMgZGlzYWJsZWRcbiAgICBpZiAodHlwZSA9PSAncHJldicpIHtcbiAgICAgICAgdGhpcy5wYWdpbmF0ZURhdGF0YWJsZVJlY29yZCgodGhpcy5zZXJ2aWNlLmRhdGFPZmZzZXQgLSB0aGlzLmxpbWl0KSAtIHRoaXMubGltaXQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuc2VydmljZS5kYXRhT2Zmc2V0IDwgdGhpcy5saW1pdCkge1xuICAgICAgICAgICAgdGhpcy5wYWdpbmF0ZURhdGF0YWJsZVJlY29yZCh0aGlzLnNlcnZpY2UuZGF0YU9mZnNldCArICh0aGlzLmxpbWl0IC0gMSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wYWdpbmF0ZURhdGF0YWJsZVJlY29yZCh0aGlzLnNlcnZpY2UuZGF0YU9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmaWx0ZXJEYXRhKHNlYXJjaFN0cmluZyA9ICcnKSB7XG4gICAgaWYoc2VhcmNoU3RyaW5nPT0nJyl7XG4gICAgICAgIHRoaXMuaXNTZWFyY2hpbmcgPSBmYWxzZSA7XG4gICAgfWVsc2V7XG4gICAgICAgIHRoaXMuaXNTZWFyY2hpbmcgPSB0cnVlIDtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZURpc3BsYXlEYXRhKFtdKTtcbiAgICB0aGlzLnNlcnZpY2UuZmx4RGF0YS5zdWJzY3JpYmUoKGRhdGEpID0+IHtcbiAgICAgICAgbGV0IHNlYXJjaFJlc3VsdHM6IEFycmF5PGFueT4gPSBbXTtcbiAgICAgICAgLy9JZiBubyBzdHJpbmcgcHJvdmlkZWQuIFJlZ2lzdGVyIGFsbCB0aGUgcHJldmlvdXMgZGF0YSB0byB0aGUgZGF0YXNldFxuICAgICAgICBpZiAoc2VhcmNoU3RyaW5nLnRyaW0oKSA9PSAnJykge1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VEaXNwbGF5RGF0YSh0aGlzLnNlYXJjaERhdGFUZW1wT2Zmc2V0KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvL0NoZWNrIGlmIHNlYXJjaEtleXMgYXJlIHNldCBlbHNlIHVzZSBkYXRhS2V5cyBhcyBzZWFyY2hLZXlzXG4gICAgICAgIGxldCBzZWFyY2hLZXlzOiBBcnJheTxzdHJpbmc+ID0gKHRoaXMuc2VhcmNoS2V5cy5sZW5ndGggPCAxKSA/IHRoaXMuZGF0YUtleXMgOiB0aGlzLnNlYXJjaEtleXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgLy9WYXJpYWJsZSB0byBjaGVjayBpZiBkYXRhIGlzIGZvdW5kXG4gICAgICAgICAgICBsZXQgZm91bmQgPSAtMTtcbiAgICAgICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgc2VhcmNoS2V5cy5sZW5ndGg7IHgrKykge1xuICAgICAgICAgICAgICAgIHRyeXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFbaV1bU3RyaW5nKHNlYXJjaEtleXNbeF0pXS50b0xvd2VyQ2FzZSgpLmluZGV4T2Yoc2VhcmNoU3RyaW5nLnRvTG9jYWxlTG93ZXJDYXNlKCkpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy9JZiBmb3VuZCBwdXNoIHRoZSBpbmRleCBvZiB0aGUgZGF0YSB0byB0aGUgc2VhcmNoUmVzdWx0cyB2YXJpYWJsZVxuICAgICAgICAgICAgaWYgKGZvdW5kID4gLTEpIHtcbiAgICAgICAgICAgICAgICBzZWFyY2hSZXN1bHRzLnB1c2goZGF0YVtmb3VuZF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VhcmNoUmVzdWx0Rm91bmQgPSBzZWFyY2hSZXN1bHRzIDtcbiAgICAgICAgLy9SZWdpc3RlciB0aGUgcmVzdWx0cyB0byB0aGUgZGF0YXNldFxuICAgICAgICB0aGlzLmNoYW5nZURpc3BsYXlEYXRhKHNlYXJjaFJlc3VsdHMpO1xuICAgICAgICB0aGlzLnNldENvbHVtbldpZHRocygpIDtcbiAgICB9KS51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB2YWx1ZSBvZmZzZXQgdmFsdWVcbiAgICAgKi9cbiAgICBwYWdpbmF0ZURhdGF0YWJsZSh2YWx1ZSkge1xuICAgICAgICAvLyBDaGVjayBpZiBsYXp5IGxvYWRpbmcgaXMgZW5hYmxlZFxuICAgICAgICBpZih0aGlzLmlzTGF6eWxvYWRpbmdFbmFibGVkKCkpe1xuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmxvYWRGaW5pc2ggPSBmYWxzZSA7XG4gICAgICAgICAgICAvLyBTdWJzY3JpYmUgdG8gZ2V0IHRoZSBkYXRhIGxlbmd0aFxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmdldERhdGFMZW5ndGgoKS50aGVuKCgpPT57ICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIHRoaXMuc2VydmljZS5jaGFnZURhdGFUYWJsZShbXSkgO1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGFsbCBpcyBzZWxlY3RlZCB0byBwcmV2ZW50IE5BTiB2YWx1ZSAgIFxuICAgICAgICAgICAgICAgIGlmKHZhbHVlIT0nYWxsJyl7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VydmljZS5kYXRhT2Zmc2V0ID0gcGFyc2VJbnQodmFsdWUpIDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gc2V0dXAgdXJsXG4gICAgICAgICAgICAgICAgbGV0IHVybCA9ICh0aGlzLmlzTGF6eWxvYWRpbmdFbmFibGVkKCkpID8gdGhpcy5kYXRhVXJsKycmJyt0aGlzLmxhenlsb2FkaW5nQ29uZmlnWydhcGlPZmZzZXRLZXknXSsnPScrIHZhbHVlICsnJicrdGhpcy5sYXp5bG9hZGluZ0NvbmZpZy5hcGlTZWFyY2hLZXkrJz0nIDogdGhpcy5kYXRhVXJsIDtcbiAgICAgICAgICAgICAgICAvLyBwYWdpbmF0ZVxuICAgICAgICAgICAgICAgIHRoaXMuc2VydmljZS5sb2FkRmx4RGF0YVRhYmxlRGF0YSh1cmwsZmFsc2UpIDtcbiAgICAgICAgICAgIH0pLmNhdGNoKGU9PntcbiAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdlcnJvcicsZSkgO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgIH1cbiAgICAgICBcbiAgICAgICAgdGhpcy5wYWdpbmF0ZURhdGF0YWJsZVJlY29yZCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgcGFnaW5hdGlvbiBudW1iZXJcbiAgICAgKiBQZXJmb3JtIHBhZ2luYXRpb24gdG8gdGhlIGRhdGFzZXRcbiAgICAgKiBAcmV0dXJuXG4gICAgICovXG4gICAgcGFnaW5hdGVEYXRhdGFibGVSZWNvcmQodmFsdWU6YW55KSB7XG4gICAgICAgIGlmKHRoaXMubGF6eWxvYWRpbmdDb25maWcuaGFzT3duUHJvcGVydHkoXCJhcGlPZmZzZXRLZXlcIikgJiYgdGhpcy5sYXp5bG9hZGluZ0NvbmZpZ1snYXBpT2Zmc2V0S2V5J10peyAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5sb2FkRmluaXNoID0gZmFsc2UgO1xuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmdldERhdGFMZW5ndGgoKS50aGVuKGRhdGFMZW5ndGg9PnsgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmNoYWdlRGF0YVRhYmxlKFtdKSA7IFxuICAgICAgICAgICAgICAgIHRoaXMuc2VydmljZS5kYXRhT2Zmc2V0ID0gcGFyc2VJbnQodmFsdWUpK3RoaXMubGltaXQgOyAgICAgICAgICBcbiAgICAgICAgICAgICAgICB0aGlzLnNlcnZpY2UubG9hZEZseERhdGFUYWJsZURhdGEodGhpcy5kYXRhVXJsKycmJyt0aGlzLmxhenlsb2FkaW5nQ29uZmlnLmFwaU9mZnNldEtleSsnPScrdmFsdWUrJyYnK3RoaXMubGF6eWxvYWRpbmdDb25maWcuYXBpU2VhcmNoS2V5Kyc9JykgO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q29sdW1uV2lkdGhzKCkgO1xuICAgICAgICAgICAgfSkuY2F0Y2goZT0+e1xuICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ2Vycm9yJyxlKSA7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgcmV0dXJuIDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBudW06bnVtYmVyID0gcGFyc2VJbnQodmFsdWUpO1xuICAgICAgICBpZiAobnVtIDw9IDApIHtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMTtcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5kYXRhT2Zmc2V0ID0gdGhpcy5saW1pdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSAnYWxsJykge1xuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gbnVtICsgMTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlcnZpY2UuZGF0YU9mZnNldCA9IG51bSArIHRoaXMubGltaXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldCA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXJ2aWNlLmZseERhdGEuc3Vic2NyaWJlKChkYXRhKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09ICdhbGwnKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBhZ2luYXRlUmVzdWx0OiBBcnJheTxhbnk+ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHZhbHVlOyBpIDwgKHRoaXMubGltaXQgKyBwYXJzZUludCh2YWx1ZSkpOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luYXRlUmVzdWx0LnB1c2goZGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHBhZ2luYXRlUmVzdWx0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEaXNwbGF5RGF0YShwYWdpbmF0ZVJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEaXNwbGF5RGF0YShkYXRhKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaERhdGFUZW1wT2Zmc2V0ID0gZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0Q29sdW1uV2lkdGhzKCk7XG4gICAgICAgIH0pLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxufVxuXG5pbXBvcnQge0RpcmVjdGl2ZSxFbGVtZW50UmVmfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1tmbHgtdWktZGF0YXRhYmxlLWltZy1mYWxsYmFja10nXG59KVxuZXhwb3J0IGNsYXNzIEltYWdlRmFsbEJhY2sge1xuICAgIEBJbnB1dCgnZmx4LXVpLWRhdGF0YWJsZS1pbWctZmFsbGJhY2snKSBpbWdTcmM6IHN0cmluZztcbiAgICBwcml2YXRlIGVsOiBIVE1MRWxlbWVudDtcbiAgICBwcml2YXRlIGlzQXBwbGllZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHByaXZhdGUgRVZFTlRfVFlQRTogc3RyaW5nID0gJ2Vycm9yJztcbiAgXG4gICAgY29uc3RydWN0b3IoZWw6IEVsZW1lbnRSZWYpIHtcbiAgICAgIHRoaXMuZWwgPSBlbC5uYXRpdmVFbGVtZW50O1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKHRoaXMuRVZFTlRfVFlQRSwgdGhpcy5vbkVycm9yLmJpbmQodGhpcykpXG4gICAgfVxuICBcbiAgICBwcml2YXRlIG9uRXJyb3IoKSB7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50cygpO1xuICBcbiAgICAgIGlmICghdGhpcy5pc0FwcGxpZWQpIHtcbiAgICAgICAgdGhpcy5pc0FwcGxpZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnc3JjJywgdGhpcy5pbWdTcmMpO1xuICAgICAgfVxuICAgIH1cbiAgXG4gICAgcHJpdmF0ZSByZW1vdmVFdmVudHMoKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodGhpcy5FVkVOVF9UWVBFLCB0aGlzLm9uRXJyb3IpO1xuICAgIH1cbiAgXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50cygpO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBQaXBlLFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XG5AUGlwZSh7XG4gICAgbmFtZTonY2VpbCdcbn0pXG5leHBvcnQgY2xhc3MgQ2VpbCBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm17XG4gICAgY29uc3RydWN0b3IoKXtcblxuICAgIH1cblxuICAgIHRyYW5zZm9ybSh2YWx1ZTpudW1iZXIsbGltaXQ6bnVtYmVyKXtcbiAgICAgICAgcmV0dXJuIE1hdGguY2VpbCh2YWx1ZS9saW1pdCkgO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZScgO1xyXG5pbXBvcnQgeyBGbHhVaURhdGF0YWJsZVNlcnZpY2UgfSBmcm9tICcuLi9mbHgtdWktZGF0YXRhYmxlLnNlcnZpY2UnO1xyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTonaGFzbGltaXR0ZXh0J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgSGFzTGltaXRUZXh0IGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybXtcclxuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBzZXJ2aWNlOiBGbHhVaURhdGF0YWJsZVNlcnZpY2Upe31cclxuXHJcbiAgICB0cmFuc2Zvcm0oYXJyYXk6QXJyYXk8bnVtYmVyPixpbmRleFJlYWNoZWQ6bnVtYmVyKTogYW55e1xyXG4gICAgICAgbGV0IGZvdW5kOiBib29sZWFuIDtcclxuICAgICAgIGZvcihsZXQgaSBvZiBhcnJheSl7XHJcbiAgICAgICAgICAgaWYoaT09aW5kZXhSZWFjaGVkKXtcclxuICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZSA7XHJcbiAgICAgICAgICAgICAgICBicmVhayA7XHJcbiAgICAgICAgICAgfVxyXG4gICAgICAgfVxyXG5cclxuICAgICAgIHJldHVybiBmb3VuZCA7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBQaXBlLFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XHJcbmltcG9ydCB7IEZseFVpRGF0YXRhYmxlU2VydmljZSB9IGZyb20gJy4uL2ZseC11aS1kYXRhdGFibGUuc2VydmljZSc7XHJcbkBQaXBlKHtcclxuICAgIG5hbWU6J2xpbWl0dGV4dCdcclxufSlcclxuZXhwb3J0IGNsYXNzIExpbWl0VGV4dCBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm17XHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgc2VydmljZTpGbHhVaURhdGF0YWJsZVNlcnZpY2Upe1xyXG5cclxuICAgIH1cclxuXHJcbiAgICB0cmFuc2Zvcm0obWFpbnB1bGF0aW9uQ29uZmlnOk9iamVjdCx0ZXh0OnN0cmluZyk6c3RyaW5ne1xyXG4gICAgICAgIGxldCBmcm9tID0gKG1haW5wdWxhdGlvbkNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcImZyb21cIikpID8gbWFpbnB1bGF0aW9uQ29uZmlnWydmcm9tJ10gOiAwIDtcclxuICAgICAgICBsZXQgdG8gPSAobWFpbnB1bGF0aW9uQ29uZmlnLmhhc093blByb3BlcnR5KFwidG9cIikpID8gbWFpbnB1bGF0aW9uQ29uZmlnW1widG9cIl0gOiB0ZXh0Lmxlbmd0aCA7XHJcbiAgICAgICAgbGV0IGFwcGVuZERvdHMgPSAobWFpbnB1bGF0aW9uQ29uZmlnLmhhc093blByb3BlcnR5KFwiYXBwZW5kRG90c1wiKSkgPyBtYWlucHVsYXRpb25Db25maWdbXCJhcHBlbmREb3RzXCJdIDogXCJcIiA7XHJcbiAgICAgICAgbGV0IHR4dDogc3RyaW5nID1cIlwiIDtcclxuICAgICAgICBpZih0ZXh0Lmxlbmd0aD50byl7XHJcbiAgICAgICAgICAgIHR4dCA9IHRleHQuc3Vic3RyaW5nKGZyb20sdG8pKyBhcHBlbmREb3RzIDtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgdHh0ID0gdGV4dCA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHh0IDtcclxuICAgIH1cclxufSIsImltcG9ydCB7IFBpcGUsUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnIDtcclxuaW1wb3J0IHsgRmx4VWlEYXRhdGFibGVTZXJ2aWNlIH0gZnJvbSAnLi4vZmx4LXVpLWRhdGF0YWJsZS5zZXJ2aWNlJztcclxuXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6J2lzcHJvY2Vzc2VkJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgUHJvY2Vzc2VkRGF0YSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm17XHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgc2VydmljZTogRmx4VWlEYXRhdGFibGVTZXJ2aWNlKXtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgdHJhbnNmb3JtKGRhdGFJbmRleDpudW1iZXIpOiBib29sZWFue1xyXG4gICAgICAgIGxldCBpc1Byb2Nlc3NlZDogYm9vbGVhbiA9IGZhbHNlIDtcclxuICAgICAgICBsZXQgZm91bmRJbmRleDogbnVtYmVyID0gLTEgO1xyXG4gICAgICAgIGZvcihsZXQgaT0wO2k8dGhpcy5zZXJ2aWNlLnByb2Nlc3NlZERhdGEubGVuZ3RoO2krKyl7XHJcbiAgICAgICAgICAgIGlmKGk9PWRhdGFJbmRleCl7XHJcbiAgICAgICAgICAgICAgICBpc1Byb2Nlc3NlZCA9IHRydWUgO1xyXG4gICAgICAgICAgICAgICAgZm91bmRJbmRleCA9IGkgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZihmb3VuZEluZGV4PDApeyAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UucHJvY2Vzc2VkRGF0YS5wdXNoKGRhdGFJbmRleCkgO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGlzUHJvY2Vzc2VkIDtcclxuICAgIH1cclxufSIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSxGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJyA7XG5pbXBvcnQgeyBGbHhVaURhdGF0YWJsZUNvbXBvbmVudCxJbWFnZUZhbGxCYWNrIH0gZnJvbSAnLi9mbHgtdWktZGF0YXRhYmxlLmNvbXBvbmVudCcgO1xuaW1wb3J0IHsgSHR0cE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2h0dHAnIDtcbmltcG9ydCB7IEZseFVpRGF0YXRhYmxlU2VydmljZSB9IGZyb20gJy4vZmx4LXVpLWRhdGF0YWJsZS5zZXJ2aWNlJyA7XG5pbXBvcnQgeyBDZWlsIH0gZnJvbSAnLi9waXBlcy9jZWlsLnBpcGUnIDtcbmltcG9ydCB7IEhhc0xpbWl0VGV4dCB9IGZyb20gJy4vcGlwZXMvaGFzTGltaXRUZXh0LnBpcGUnXG5pbXBvcnQgeyBMaW1pdFRleHQgfSBmcm9tICcuL3BpcGVzL2xpbWl0VGV4dC5waXBlJztcbmltcG9ydCB7IFByb2Nlc3NlZERhdGEgfSBmcm9tICcuL3BpcGVzL3Byb2Nlc3NlZGRhdGEucGlwZSc7XG5pbXBvcnQgeyBQZXJmZWN0U2Nyb2xsYmFyTW9kdWxlIH0gZnJvbSAnbmd4LXBlcmZlY3Qtc2Nyb2xsYmFyJztcbmltcG9ydCB7IFBFUkZFQ1RfU0NST0xMQkFSX0NPTkZJRyB9IGZyb20gJ25neC1wZXJmZWN0LXNjcm9sbGJhcic7XG5pbXBvcnQgeyBQZXJmZWN0U2Nyb2xsYmFyQ29uZmlnSW50ZXJmYWNlIH0gZnJvbSAnbmd4LXBlcmZlY3Qtc2Nyb2xsYmFyJztcbiBcbmNvbnN0IERFRkFVTFRfUEVSRkVDVF9TQ1JPTExCQVJfQ09ORklHOiBQZXJmZWN0U2Nyb2xsYmFyQ29uZmlnSW50ZXJmYWNlID0ge1xuICBzdXBwcmVzc1Njcm9sbFg6IHRydWVcbn07XG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFJlYWN0aXZlRm9ybXNNb2R1bGUsRm9ybXNNb2R1bGUsSHR0cE1vZHVsZSxQZXJmZWN0U2Nyb2xsYmFyTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIEZseFVpRGF0YXRhYmxlQ29tcG9uZW50LENlaWwsSW1hZ2VGYWxsQmFjayxIYXNMaW1pdFRleHQsTGltaXRUZXh0LFByb2Nlc3NlZERhdGFcbiAgXSxcbiAgZXhwb3J0czpbRmx4VWlEYXRhdGFibGVDb21wb25lbnQsQ2VpbF0sXG4gIHByb3ZpZGVyczpbRmx4VWlEYXRhdGFibGVTZXJ2aWNlLFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IFBFUkZFQ1RfU0NST0xMQkFSX0NPTkZJRyxcbiAgICAgIHVzZVZhbHVlOiBERUZBVUxUX1BFUkZFQ1RfU0NST0xMQkFSX0NPTkZJR1xuICAgIH1dXG59KVxuZXhwb3J0IGNsYXNzIEZseFVpRGF0YXRhYmxlTW9kdWxlIHtcbiAgXG59XG4iXSwibmFtZXMiOlsidHNsaWJfMS5fX3ZhbHVlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBO0lBOEJFLCtCQUFtQixJQUFVO1FBQVYsU0FBSSxHQUFKLElBQUksQ0FBTTt1QkF2QkgsRUFBRTt3QkFDWSxJQUFJLGVBQWUsQ0FBTSxFQUFFLENBQUM7dUJBRW5ELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFOzBCQUVWLEVBQUU7MEJBRVQsQ0FBQzswQkFFRCxDQUFDO3FCQUVOLEVBQUU7MEJBRUUsRUFBRTs7Z0NBRUMsRUFBRTs7MEJBSVYsS0FBSztpQ0FFTSxFQUFFOzZCQUNQLEVBQUU7S0FHN0I7Ozs7O0lBRU0sb0RBQW9COzs7O2NBQUMsTUFBVTtRQUNwQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsTUFBTSxDQUFFOzs7Ozs7O0lBUTVCLHVDQUFPOzs7OztjQUFDLEdBQVU7UUFDckIscUJBQUksT0FBTyxHQUFZLElBQUksT0FBTyxFQUFFLENBQUU7UUFDdEMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUMsbUNBQW1DLENBQUMsQ0FBRTtRQUNwRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxD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