UNPKG

flx-ui-datatable

Version:

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

1,225 lines 176 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 { 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
 */
class FlxUiDatatableService {
    /**
     * @param {?} http
     */
    constructor(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 {?}
     */
    setLazyloadingConfig(config) {
        this.lazyloadingConfig = config;
    }
    /**
     *
     * @param {?} url User api rul
     * @return {?}
     */
    getData(url) {
        let /** @type {?} */ headers = new Headers();
        headers.append('Content-Type', 'application/x-www-form-urlencoded');
        return this.http.get(url, { headers: headers }).pipe(retry(5), map((response) => response.json()));
    }
    /**
     *
     * @param {?} url Service api url
     * @param {?} id Datatype id to export
     * @param {?} data Data to export
     * @return {?}
     */
    postData(url, id, data) {
        let /** @type {?} */ headers = new Headers();
        headers.append('Content-Type', 'application/json; charset=utf-8');
        return this.http.post(url + id, data, { headers: headers }).pipe(map((resp) => resp.json()));
    }
    /**
     *
     * @param {?} dataUrl Set dataurl
     * @return {?}
     */
    setDataUrl(dataUrl) {
        this.dataUrl = dataUrl;
    }
    /**
     * @return {?}
     */
    getDataUrl() {
        return this.dataUrl;
    }
    /**
     *
     * @param {?} data Register new data from user API
     * @return {?}
     */
    chageDataTable(data) {
        this.behavior.next(data);
    }
    /**
     *
     * @param {?} numberOfList Total number of list
     * @param {?} limit Pagination limit
     * @return {?}
     */
    createPagination(numberOfList, limit) {
        let /** @type {?} */ obj = [];
        let /** @type {?} */ counter = 1;
        for (let /** @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 {?}
     */
    isLazyLoadingEnabled() {
        return this.lazyloadingConfig.hasOwnProperty("apiOffsetKey") && this.lazyloadingConfig.apiOffsetKey;
    }
    /**
     * @param {?} dataUrl
     * @param {?=} setSelectPagination
     * @return {?}
     */
    loadFlxDataTableData(dataUrl, setSelectPagination = true) {
        this.loadFinish = false;
        this.loader = this.getData(dataUrl).subscribe((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);
            }
        }, (e => {
            this.loadFinish = true;
        }));
    }
    /**
     * @return {?}
     */
    cancelLoading() {
        this.loader.unsubscribe();
    }
    /**
     * @param {?} srcKey
     * @return {?}
     */
    setDataSrcKey(srcKey) {
        this.dataSrcKey = srcKey;
    }
    /**
     * @return {?}
     */
    getDataLength() {
        return new Promise((resolve) => {
            this.flxData.subscribe((resp) => {
                resolve(resp.length);
            }, (e => {
                resolve(0);
            }));
        });
    }
}
FlxUiDatatableService.decorators = [
    { type: Injectable },
];
/** @nocollapse */
FlxUiDatatableService.ctorParameters = () => [
    { type: Http }
];

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

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class FlxUiDatatableComponent {
    /**
     * @param {?} __form
     * @param {?} service
     */
    constructor(__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 {?}
     */
    reload() {
        this.service.loadFlxDataTableData(this.reloadUrl, true);
    }
    /**
     *
     * @param {?} checked Export all selection
     * @return {?}
     */
    checkToExportOption(checked) {
        this.isExportAll = checked;
    }
    /**
     *
     * @param {?} exportType Export type: print|pdf|excel|word
     * @return {?}
     */
    exportDocumentsAs(exportType) {
        let /** @type {?} */ loading = /** @type {?} */ (document.getElementById("export_loading"));
        loading.style.display = 'block';
        let /** @type {?} */ headers = (!this.dataExportsConfig.dataColumns || this.dataExportsConfig.dataColumns.length < 1) ? this.dataKeys : this.dataExportsConfig.dataColumns;
        let /** @type {?} */ dataToExport = (!this.isExportAll) ? this.displayData : this.service.flxData;
        //Subscribe to data
        dataToExport.subscribe((data) => {
            let /** @type {?} */ arrayObj = [];
            //Loop and push data
            for (let /** @type {?} */ d of data) {
                let /** @type {?} */ obj = {};
                for (let /** @type {?} */ h = 0; h < headers.length; h++) {
                    obj[headers[h]] = d[headers[h]];
                }
                arrayObj.push(obj);
            }
            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 {
                let /** @type {?} */ extension = (exportType == 'pdf') ? 'pdf' : (exportType == 'excel') ? 'xlsx' : 'docx';
                let /** @type {?} */ pageId = (exportType == 'pdf') ? 3 : (exportType == 'excel') ? 5 : 4;
                let /** @type {?} */ requestData = { "data": JSON.stringify(arrayObj) };
                this.service.postData('http://exporter.azurewebsites.net/api/export/ExportFromJSON/', pageId, requestData).subscribe((resp) => {
                    var /** @type {?} */ download = 'http://exporter.azurewebsites.net/api/export/GetFile/' + resp;
                    download += "?fileName=andrei&extension=" + extension;
                    window.location.href = download;
                    loading.style.display = 'none';
                }, (e => {
                    //console.log('file export error',e) ;
                }));
            }
        }).unsubscribe();
    }
    /**
     * @return {?}
     */
    hasImageEmbeded() {
        return this.embedPictures.hasOwnProperty("index");
    }
    /**
     * @return {?}
     */
    getImage() {
        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 {?}
     */
    JSONToCSVConvertor(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
     * @return {?}
     */
    changeDisplayData(newData) {
        this.behavior.next(newData);
        this.setColumnWidths();
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        $(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);
        let /** @type {?} */ url = (this.isLazyloadingEnabled()) ? this.dataUrl + '&' + this.lazyloadingConfig.apiOffsetKey + '=0&' + this.lazyloadingConfig.apiSearchKey + '=' : this.dataUrl;
        this.service.loadFlxDataTableData(url);
        this.service.flxData.subscribe((resp) => {
            this.tData = resp;
            let /** @type {?} */ obj = [];
            if (this.tData.length > this.limit) {
                for (let /** @type {?} */ i = 0; i < this.limit; i++) {
                    obj.push(this.tData[i]);
                }
                // this.service.dataOffset = this.limit;
            }
            else {
                for (let /** @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 {?}
     */
    searchDataInApi(values, form) {
        this.service.chageDataTable([]);
        this.service.loadFlxDataTableData(this.dataUrl + '&' + this.lazyloadingConfig.apiOffsetKey + '=0&' + this.lazyloadingConfig.apiSearchKey + '=' + values.searchString);
    }
    /**
     * @return {?}
     */
    ngAfterViewInit() {
        let /** @type {?} */ eachColumnWidth = this.returColumnswidth();
        $(window).ready(function () {
            $(".flx-table-thead tr th").css({ 'width': eachColumnWidth + '%' });
        });
    }
    /**
     * @return {?}
     */
    setColumnWidths() {
        let /** @type {?} */ eachColumnWidth = this.returColumnswidth();
        $(window).ready(function () {
            $(".flx-table-data tbody tr td").css({ 'width': eachColumnWidth + '%' });
        });
    }
    /**
     * @return {?}
     */
    returColumnswidth() {
        let /** @type {?} */ hasNumbers = (!this.hideNumbers) ? 0 : 1;
        let /** @type {?} */ hasActionButtons = (!this.hasActionButtons) ? 0 : 1;
        let /** @type {?} */ numberOfColumns = (this.headers.length + 1) + hasActionButtons + hasNumbers;
        console.log('number_of_columns', numberOfColumns);
        let /** @type {?} */ eachColumnWidth = 100 / numberOfColumns;
        return eachColumnWidth;
    }
    /**
     * @param {?} index
     * @param {?} buttonIndex
     * @return {?}
     */
    actionButtonClicked(index, buttonIndex) {
        this.displayData.subscribe((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 {?}
     */
    addButtonClick() {
        this.addButtonClicked.emit();
    }
    /**
     * @return {?}
     */
    confirmDelete() {
        return this.multipleSelectClicked.emit(this.service.multipleDeletion);
    }
    /**
     * @param {?} checked
     * @return {?}
     */
    addRemove(checked) {
        if (checked) {
            this.displayData.subscribe((data) => {
                for (let /** @type {?} */ i of data) {
                    try {
                        this.service.multipleDeletion.push(i[this.multipleSelectKey]);
                    }
                    catch (/** @type {?} */ e) { }
                }
                // console.log(this.service.multipleDeletion) ;
            }).unsubscribe();
        }
        else {
            this.service.multipleDeletion = [];
        }
    }
    /**
     * @param {?} dataKeyvalue
     * @param {?} index
     * @param {?} selected
     * @return {?}
     */
    addRemoveDeleteItem(dataKeyvalue, index, selected) {
        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((resp) => {
                this.service.multipleDeletion.push(resp[index][this.multipleSelectKey]);
            }).unsubscribe();
        }
        // console.log('left '+dataKeyvalue,this.service.multipleDeletion) ;
    }
    /**
     * @return {?}
     */
    getSearchColumns() {
        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 {?}
     */
    disablePrevtButton() {
        return Math.ceil(this.service.dataOffset / this.limit) <= 1;
    }
    /**
     * @return {?}
     */
    disableNextButton() {
        return Math.ceil(this.service.dataOffset / this.limit) == Math.ceil(this.service.totalItems / this.limit);
    }
    /**
     * @return {?}
     */
    isLazyloadingEnabled() {
        return this.lazyloadingConfig.hasOwnProperty("apiOffsetKey") && this.lazyloadingConfig.apiOffsetKey;
    }
    /**
     * @param {?} type
     * @return {?}
     */
    nextPrevItem(type) {
        if (this.isLazyloadingEnabled()) {
            this.service.loadFinish = false;
            this.service.getDataLength().then(dataLength => {
                this.service.chageDataTable([]);
                this.service.dataOffset = (type == 'prev') ? ((this.service.dataOffset - this.limit) - this.limit) : this.service.dataOffset;
                let /** @type {?} */ url = (this.isLazyloadingEnabled()) ? this.dataUrl + '&' + this.lazyloadingConfig.apiOffsetKey + '=' + this.service.dataOffset + '&' + this.lazyloadingConfig.apiSearchKey + '=' : this.dataUrl;
                this.service.loadFlxDataTableData(url);
            }).catch(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 {?}
     */
    filterData(searchString = '') {
        if (searchString == '') {
            this.isSearching = false;
        }
        else {
            this.isSearching = true;
        }
        this.changeDisplayData([]);
        this.service.flxData.subscribe((data) => {
            let /** @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
            let /** @type {?} */ searchKeys = (this.searchKeys.length < 1) ? this.dataKeys : this.searchKeys;
            for (let /** @type {?} */ i = 0; i < data.length; i++) {
                //Variable to check if data is found
                let /** @type {?} */ found = -1;
                for (let /** @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
            this.changeDisplayData(searchResults);
            this.setColumnWidths();
        }).unsubscribe();
    }
    /**
     * @param {?} value offset value
     * @return {?}
     */
    paginateDatatable(value) {
        // Check if lazy loading is enabled
        if (this.isLazyloadingEnabled()) {
            this.service.loadFinish = false;
            // Subscribe to get the data length
            this.service.getDataLength().then(() => {
                this.service.chageDataTable([]);
                // Check if all is selected to prevent NAN value
                if (value != 'all') {
                    this.service.dataOffset = parseInt(value);
                }
                // setup url
                let /** @type {?} */ url = (this.isLazyloadingEnabled()) ? this.dataUrl + '&' + this.lazyloadingConfig['apiOffsetKey'] + '=' + value + '&' + this.lazyloadingConfig.apiSearchKey + '=' : this.dataUrl;
                // paginate
                this.service.loadFlxDataTableData(url, false);
            }).catch(e => {
                // console.log('error',e) ;
            });
            return;
        }
        this.paginateDatatableRecord(value);
    }
    /**
     *
     * @param {?} value pagination number
     * Perform pagination to the dataset
     * @return {?}
     */
    paginateDatatableRecord(value) {
        if (this.lazyloadingConfig.hasOwnProperty("apiOffsetKey") && this.lazyloadingConfig['apiOffsetKey']) {
            this.service.loadFinish = false;
            this.service.getDataLength().then(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(e => {
                // console.log('error',e) ;
            });
            return;
        }
        let /** @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((data) => {
            if (value !== 'all') {
                let /** @type {?} */ paginateResult = [];
                for (let /** @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 }}">
    <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>
    <div class="col-md-12 flx-ui-datatable-header">
        <div class="container-fluid">
            <div class="row">
                <div class="col-xs-3 col-sm-3 pagination-select col-md-2" style="position:relative;z-index: 1;">
                    <select class="form-control rmsh rmrd {{ classes?.paginationselect }}" (change)="paginateDatatable($event?.target?.value)">
                        <option *ngFor="let paging of service?.pagination" [value]="paging?.value">{{ paging?.label }}</option>
                    </select>
                </div>
                <div class="col-xs-5 col-sm-5 col-md-2 text-center flx-datatable-pagination rmpd" style="position:relative;z-index: 2;">
                    <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>
                        <span *ngIf="!isSearching;else searching">{{ service?.dataOffset | ceil: limit }} / {{ service?.totalItems | ceil: limit }}</span>
                        <ng-template #searching>
                            
                        </ng-template>
                    <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>
                </div>
                <div [class]="'search-bar '+getSearchColumns()">
                    <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">
                    <form (ngSubmit)="searchDataInApi(srch?.value,srch)" #srch="ngForm" *ngIf="isLazyloadingEnabled()">
                        <div class="input-group">
                            <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">
                            <span class="input-group-addon">
                                <button [disabled]="!srch?.valid" type="submit" class="btn btn-default btn-clear btn-md">
                                    <i class="fa fa-search"></i>
                                </button>
                            </span>
                        </div>
                    </form>
                </div>
                <div class="col-md-1 text-right rmpd" *ngIf="hasAddButton">
                    <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>
                </div>
                <div class="col-md-1 text-right rmpd export-cnt" *ngIf="enableDataExports">
                    <div class="dropdown">
                        <button class="btn btn-default {{ classes?.exportButton }} dropdown-toggle" type="button" data-toggle="dropdown">
                            <i class="fa fa-angle-down"></i>
                        </button>
                        <ul class="dropdown-menu dropdown-menu-export {{ classes?.exportDropdown }}">
                            <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> 
                            <li class="divider"></li>
                            <li class="dropdown-submenu" *ngFor="let export of dataExportsConfig?.exportsTo" (click)="exportDocumentsAs(export)">
                                <a href="javascript:void(0)" class="btn btn-default btn-sm form-control" *ngIf="export=='print'"><i class="glyphicon glyphicon-print"></i> Print</a>
                                <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>
                                <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>            
                                <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>                        
                            </li>
                            <li class="divider"></li>
                            <li class="dropdown-header">
                                <span  *ngIf="!isExportAll">{{ (displayData | async)?.length }}</span>
                                <span  *ngIf="isExportAll">{{ (service?.flxData | async)?.length }}</span> 
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-12 rmpd table-responsive flx-tabl-container">
                <table class="table {{ classes?.tableType }} th-table">
                    <thead class="{{ classes?.tableHeader }} flx-table-thead">
                        <tr>
                            <!-- Actions buttons header left before numbers -->
                            <th *ngIf="hasActionButtons && (actionButtonsConfig?.position=='left' && actionButtonsConfig?.beforeNumbers)">{{ actionHeader }} 
                                <input type="checkbox" [checked]="service?.multipleDeletion?.length>0" (change)="addRemove($event?.target?.checked)" *ngIf="enableMultipleSelection">
                                <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>
                            </th>


                            <th *ngIf="!hideNumbers">N<sup><u>o</u></sup></th>

                            <!-- Actions buttons header left after numbers -->
                            <th *ngIf="hasActionButtons && (actionButtonsConfig?.position=='left' && !actionButtonsConfig?.beforeNumbers)">{{ actionHeader }} 
                                <input type="checkbox" [checked]="service?.multipleDeletion?.length>0" (change)="addRemove($event?.target?.checked)" *ngIf="enableMultipleSelection">
                                <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>
                            </th>


                            <th *ngFor="let header of headers">{{ header }}</th>

                            <!-- Actions buttons header right -->
                            <th *ngIf="hasActionButtons  && (actionButtonsConfig?.position=='right')">{{ actionHeader }} 
                                <input type="checkbox" [checked]="service?.multipleDeletion?.length>0" (change)="addRemove($event?.target?.checked)" *ngIf="enableMultipleSelection">
                                <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>
                            </th>
                        </tr>
                    </thead>
                </table>
                <perfect-scrollbar class="data-scroll-content {{ classes?.dataScrollContent }}">
                    <table class="table {{ classes?.tableType }} flx-table-data">                        
                        <tbody class="flxdatatablebodyscrollbar">
                            <tr *ngIf="!service?.loadFinish">                    
                                <td colspan="20" class="text-center">
                                    <img *ngIf="spinnerSrc" [class]="classes?.spinner" [src]="spinnerSrc" style="margin-top:1em;margin-bottom:1em;">
                                </td>
                            </tr>
                            <tr class="flxuidatatablerow" id="flxdatatable_singlerow" *ngFor="let data of displayData | async;let i=index">
                                
                                <!-- Buttons Left Before Numbers -->
                                <td class="table-buttons" *ngIf="hasActionButtons && (actionButtonsConfig?.position=='left' && actionButtonsConfig?.beforeNumbers)" scope="row">
                                    <span *ngFor="let aButton of actionButtons;let buttonIndex=index">
                                        <button type="button" (click)="actionButtonClicked(i,buttonIndex)" class="btn {{ aButton?.class }}">
                                            <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>
                                            <span class="action-button-icon-left" [class]="aButton?.icon" *ngIf="!aButton?.iconPosition || aButton?.iconPosition!='right'"></span>
                                            <span class="button-text"> {{ aButton?.text }} </span>
                                            <span [class]="aButton?.icon" *ngIf="aButton?.iconPosition=='right'"></span>
                                        </button>
                                    </span> 
                                    <input type="checkbox" checked (change)="addRemoveDeleteItem(data[multipleSelectKey],i,$event?.target?.checked)" *ngIf="enableMultipleSelection && service?.multipleDeletion?.length>0">
                                </td>
                                
                                <!-- Numbers -->
                                <td class="{{ classes?.tableData }}" *ngIf="!hideNumbers" style="color: #999;">{{ offset+i }}</td>
                                
                                <!-- Buttons Left After Numbers -->
                                <td class="table-buttons" *ngIf="hasActionButtons && (actionButtonsConfig?.position=='left' && !actionButtonsConfig?.beforeNumbers)" scope="row">
                                    <span *ngFor="let aButton of actionButtons;let buttonIndex=index">
                                        <button type="button" (click)="actionButtonClicked(i,buttonIndex)" class="btn {{ aButton?.class }}">
                                            <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>
                                            <span class="action-button-icon-left" [class]="aButton?.icon" *ngIf="!aButton?.iconPosition || aButton?.iconPosition!='right'"></span>
                                            <span class="button-text"> {{ aButton?.text }} </span>
                                            <span [class]="aButton?.icon" *ngIf="aButton?.iconPosition=='right'"></span>
                                        </button>
                                    </span> 
                                    <input type="checkbox" checked (change)="addRemoveDeleteItem(data[multipleSelectKey],i,$event?.target?.checked)" *ngIf="enableMultipleSelection && service?.multipleDeletion?.length>0">
                                </td>
                                
                                <!-- Main -->
                                <td class="{{ classes?.tableData }}" *ngFor="let dataKey of dataKeys;let x=index">
                                    <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" >
                                    <ng-template #nopicture>
                                        <section *ngIf="textSubstring?.atIndexes && (textSubstring?.atIndexes | haslimittext:x);else nolimittext">
                                            {{ textSubstring | limittext: data[dataKey] }}
                                        </section>
                                        <ng-template #nolimittext>
                                            <span>{{ data[dataKey] }}</span>
                                        </ng-template>
                                    </ng-template> 
                                </td>
                                <!-- Buttons -->
                                <td class="table-buttons" *ngIf="hasActionButtons && actionButtonsConfig?.position!='left'">
                                    <span *ngFor="let aButton of actionButtons;let buttonIndex=index">
                                        <button type="button" (click)="actionButtonClicked(i,buttonIndex)" class="btn {{ aButton?.class }}">
                                            <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>
                                            <span class="action-button-icon-left" [class]="aButton?.icon" *ngIf="!aButton?.iconPosition || aButton?.iconPosition!='right'"></span>
                                            <span class="button-text"> {{ aButton?.text }} </span>
                                            <span [class]="aButton?.icon" *ngIf="aButton?.iconPosition=='right'"></span>
                                        </button>
                                    </span> 
                                    <input type="checkbox" checked (change)="addRemoveDeleteItem(data[multipleSelectKey],i,$event?.target?.checked)" *ngIf="enableMultipleSelection && service?.multipleDeletion?.length>0">
                                </td>
                            </tr>
                            <tr *ngIf="tData?.length<1">
                                <td colspan="10" class="text-center" *ngIf="service?.loadFinish">
                                    <span style="color:#ff0000;font-size:13px;">No data found</span> <br>
                                    <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>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </perfect-scrollbar>
                <div class="row">
                    <div class="col-md-12 rmpd flx-total-data" *ngIf="showBottomInfo">
                        <div class="row" *ngIf="!isSearching;else bottomInfoSearching">
                            <div class="col-md-4 text-left rmpd">Total pagination: <span> {{ service?.totalItems | ceil: limit }}</span></div>
                            <div class="col-md-4 text-center rmpd"># of items per pagination: <span>{{ limit }}</span></div>
                            <div class="col-md-4 text-right rmpd">Total items: <span>{{ (service?.flxData | async)?.length }}</span></div>
                        </div>
                        <ng-template #bottomInfoSearching>
                            <div class="row">
                                <div class="col-md-12 text-right rmpd">Total search result: <span>{{ searchResultFound?.length }}</span></div>
                            </div>
                        </ng-template>
                    </div>
                </div>
            </div>
        </div>
    </div>
</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 = () => [
    { 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 }]
};
class ImageFallBack {
    /**
     * @param {?} el
     */
    constructor(el) {
        this.isApplied = false;
        this.EVENT_TYPE = 'error';
        this.el = el.nativeElement;
        this.el.addEventListener(this.EVENT_TYPE, this.onError.bind(this));
    }
    /**
     * @return {?}
     */
    onError() {
        this.removeEvents();
        if (!this.isApplied) {
            this.isApplied = true;
            this.el.setAttribute('src', this.imgSrc);
        }
    }
    /**
     * @return {?}
     */
    removeEvents() {
        this.el.removeEventListener(this.EVENT_TYPE, this.onError);
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this.removeEvents();
    }
}
ImageFallBack.decorators = [
    { type: Directive, args: [{
                selector: '[flx-ui-datatable-img-fallback]'
            },] },
];
/** @nocollapse */
ImageFallBack.ctorParameters = () => [
    { type: ElementRef }
];
ImageFallBack.propDecorators = {
    imgSrc: [{ type: Input, args: ['flx-ui-datatable-img-fallback',] }]
};

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

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class HasLimitText {
    /**
     * @param {?} service
     */
    constructor(service) {
        this.service = service;
    }
    /**
     * @param {?} array
     * @param {?} indexReached
     * @return {?}
     */
    transform(array, indexReached) {
        let /** @type {?} */ found;
        for (let /** @type {?} */ i of array) {
            if (i == indexReached) {
                found = true;
                break;
            }
        }
        return found;
    }
}
HasLimitText.decorators = [
    { type: Pipe, args: [{
                name: 'haslimittext'
            },] },
];
/** @nocollapse */
HasLimitText.ctorParameters = () => [
    { type: FlxUiDatatableService }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class LimitText {
    /**
     * @param {?} service
     */
    constructor(service) {
        this.service = service;
    }
    /**
     * @param {?} mainpulationConfig
     * @param {?} text
     * @return {?}
     */
    transform(mainpulationConfig, text) {
        let /** @type {?} */ from = (mainpulationConfig.hasOwnProperty("from")) ? mainpulationConfig['from'] : 0;
        let /** @type {?} */ to = (mainpulationConfig.hasOwnProperty("to")) ? mainpulationConfig["to"] : text.length;
        let /** @type {?} */ appendDots = (mainpulationConfig.hasOwnProperty("appendDots")) ? mainpulationConfig["appendDots"] : "";
        let /** @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 = () => [
    { type: FlxUiDatatableService }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class ProcessedData {
    /**
     * @param {?} service
     */
    constructor(service) {
        this.service = service;
    }
    /**
     * @param {?} dataIndex
     * @return {?}
     */
    transform(dataIndex) {
        let /** @type {?} */ isProcessed = false;
        let /** @type {?} */ foundIndex = -1;
        for (let /** @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 = () => [
    { type: FlxUiDatatableService }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
const /** @type {?} */ DEFAULT_PERFECT_SCROLLBAR_CONFIG = {
    suppressScrollX: true
};
const ɵ0 = DEFAULT_PERFECT_SCROLLBAR_CONFIG;
class 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
                    }]
            },] },
];

/**
 * @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+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEaXNwbGF5RGF0YShwYWdpbmF0ZVJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEaXNwbGF5RGF0YShkYXRhKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaERhdGFUZW1wT2Zmc2V0ID0gZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0Q29sdW1uV2lkdGhzKCk7XG4gICAgICAgIH0pLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxufVxuXG5pbXBvcnQge0RpcmVjdGl2ZSxFbGVtZW50UmVmfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1tmbHgtdWktZGF0YXRhYmxlLWltZy1mYWxsYmFja10nXG59KVxuZXhwb3J0IGNsYXNzIEltYWdlRmFsbEJhY2sge1xuICAgIEBJbnB1dCgnZmx4LXVpLWRhdGF0YWJsZS1pbWctZmFsbGJhY2snKSBpbWdTcmM6IHN0cmluZztcbiAgICBwcml2YXRlIGVsOiBIVE1MRWxlbWVudDtcbiAgICBwcml2YXRlIGlzQXBwbGllZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHByaXZhdGUgRVZFTlRfVFlQRTogc3RyaW5nID0gJ2Vycm9yJztcbiAgXG4gICAgY29uc3RydWN0b3IoZWw6IEVsZW1lbnRSZWYpIHtcbiAgICAgIHRoaXMuZWwgPSBlbC5uYXRpdmVFbGVtZW50O1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKHRoaXMuRVZFTlRfVFlQRSwgdGhpcy5vbkVycm9yLmJpbmQodGhpcykpXG4gICAgfVxuICBcbiAgICBwcml2YXRlIG9uRXJyb3IoKSB7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50cygpO1xuICBcbiAgICAgIGlmICghdGhpcy5pc0FwcGxpZWQpIHtcbiAgICAgICAgdGhpcy5pc0FwcGxpZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnc3JjJywgdGhpcy5pbWdTcmMpO1xuICAgICAgfVxuICAgIH1cbiAgXG4gICAgcHJpdmF0ZSByZW1vdmVFdmVudHMoKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodGhpcy5FVkVOVF9UWVBFLCB0aGlzLm9uRXJyb3IpO1xuICAgIH1cbiAgXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50cygpO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBQaXBlLFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XG5AUGlwZSh7XG4gICAgbmFtZTonY2VpbCdcbn0pXG5leHBvcnQgY2xhc3MgQ2VpbCBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm17XG4gICAgY29uc3RydWN0b3IoKXtcblxuICAgIH1cblxuICAgIHRyYW5zZm9ybSh2YWx1ZTpudW1iZXIsbGltaXQ6bnVtYmVyKXtcbiAgICAgICAgcmV0dXJuIE1hdGguY2VpbCh2YWx1ZS9saW1pdCkgO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZScgO1xyXG5pbXBvcnQgeyBGbHhVaURhdGF0YWJsZVNlcnZpY2UgfSBmcm9tICcuLi9mbHgtdWktZGF0YXRhYmxlLnNlcnZpY2UnO1xyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTonaGFzbGltaXR0ZXh0J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgSGFzTGltaXRUZXh0IGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybXtcclxuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBzZXJ2aWNlOiBGbHhVaURhdGF0YWJsZVNlcnZpY2Upe31cclxuXHJcbiAgICB0cmFuc2Zvcm0oYXJyYXk6QXJyYXk8bnVtYmVyPixpbmRleFJlYWNoZWQ6bnVtYmVyKTogYW55e1xyXG4gICAgICAgbGV0IGZvdW5kOiBib29sZWFuIDtcclxuICAgICAgIGZvcihsZXQgaSBvZiBhcnJheSl7XHJcbiAgICAgICAgICAgaWYoaT09aW5kZXhSZWFjaGVkKXtcclxuICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZSA7XHJcbiAgICAgICAgICAgICAgICBicmVhayA7XHJcbiAgICAgICAgICAgfVxyXG4gICAgICAgfVxyXG5cclxuICAgICAgIHJldHVybiBmb3VuZCA7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBQaXBlLFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJyA7XHJcbmltcG9ydCB7IEZseFVpRGF0YXRhYmxlU2VydmljZSB9IGZyb20gJy4uL2ZseC11aS1kYXRhdGFibGUuc2VydmljZSc7XHJcbkBQaXBlKHtcclxuICAgIG5hbWU6J2xpbWl0dGV4dCdcclxufSlcclxuZXhwb3J0IGNsYXNzIExpbWl0VGV4dCBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm17XHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgc2VydmljZTpGbHhVaURhdGF0YWJsZVNlcnZpY2Upe1xyXG5cclxuICAgIH1cclxuXHJcbiAgICB0cmFuc2Zvcm0obWFpbnB1bGF0aW9uQ29uZmlnOk9iamVjdCx0ZXh0OnN0cmluZyk6c3RyaW5ne1xyXG4gICAgICAgIGxldCBmcm9tID0gKG1haW5wdWxhdGlvbkNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcImZyb21cIikpID8gbWFpbnB1bGF0aW9uQ29uZmlnWydmcm9tJ10gOiAwIDtcclxuICAgICAgICBsZXQgdG8gPSAobWFpbnB1bGF0aW9uQ29uZmlnLmhhc093blByb3BlcnR5KFwidG9cIikpID8gbWFpbnB1bGF0aW9uQ29uZmlnW1widG9cIl0gOiB0ZXh0Lmxlbmd0aCA7XHJcbiAgICAgICAgbGV0IGFwcGVuZERvdHMgPSAobWFpbnB1bGF0aW9uQ29uZmlnLmhhc093blByb3BlcnR5KFwiYXBwZW5kRG90c1wiKSkgPyBtYWlucHVsYXRpb25Db25maWdbXCJhcHBlbmREb3RzXCJdIDogXCJcIiA7XHJcbiAgICAgICAgbGV0IHR4dDogc3RyaW5nID1cIlwiIDtcclxuICAgICAgICBpZih0ZXh0Lmxlbmd0aD50byl7XHJcbiAgICAgICAgICAgIHR4dCA9IHRleHQuc3Vic3RyaW5nKGZyb20sdG8pKyBhcHBlbmREb3RzIDtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgdHh0ID0gdGV4dCA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHh0IDtcclxuICAgIH1cclxufSIsImltcG9ydCB7IFBpcGUsUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnIDtcclxuaW1wb3J0IHsgRmx4VWlEYXRhdGFibGVTZXJ2aWNlIH0gZnJvbSAnLi4vZmx4LXVpLWRhdGF0YWJsZS5zZXJ2aWNlJztcclxuXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6J2lzcHJvY2Vzc2VkJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgUHJvY2Vzc2VkRGF0YSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm17XHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgc2VydmljZTogRmx4VWlEYXRhdGFibGVTZXJ2aWNlKXtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgdHJhbnNmb3JtKGRhdGFJbmRleDpudW1iZXIpOiBib29sZWFue1xyXG4gICAgICAgIGxldCBpc1Byb2Nlc3NlZDogYm9vbGVhbiA9IGZhbHNlIDtcclxuICAgICAgICBsZXQgZm91bmRJbmRleDogbnVtYmVyID0gLTEgO1xyXG4gICAgICAgIGZvcihsZXQgaT0wO2k8dGhpcy5zZXJ2aWNlLnByb2Nlc3NlZERhdGEubGVuZ3RoO2krKyl7XHJcbiAgICAgICAgICAgIGlmKGk9PWRhdGFJbmRleCl7XHJcbiAgICAgICAgICAgICAgICBpc1Byb2Nlc3NlZCA9IHRydWUgO1xyXG4gICAgICAgICAgICAgICAgZm91bmRJbmRleCA9IGkgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZihmb3VuZEluZGV4PDApeyAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UucHJvY2Vzc2VkRGF0YS5wdXNoKGRhdGFJbmRleCkgO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGlzUHJvY2Vzc2VkIDtcclxuICAgIH1cclxufSIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSxGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJyA7XG5pbXBvcnQgeyBGbHhVaURhdGF0YWJsZUNvbXBvbmVudCxJbWFnZUZhbGxCYWNrIH0gZnJvbSAnLi9mbHgtdWktZGF0YXRhYmxlLmNvbXBvbmVudCcgO1xuaW1wb3J0IHsgSHR0cE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2h0dHAnIDtcbmltcG9ydCB7IEZseFVpRGF0YXRhYmxlU2VydmljZSB9IGZyb20gJy4vZmx4LXVpLWRhdGF0YWJsZS5zZXJ2aWNlJyA7XG5pbXBvcnQgeyBDZWlsIH0gZnJvbSAnLi9waXBlcy9jZWlsLnBpcGUnIDtcbmltcG9ydCB7IEhhc0xpbWl0VGV4dCB9IGZyb20gJy4vcGlwZXMvaGFzTGltaXRUZXh0LnBpcGUnXG5pbXBvcnQgeyBMaW1pdFRleHQgfSBmcm9tICcuL3BpcGVzL2xpbWl0VGV4dC5waXBlJztcbmltcG9ydCB7IFByb2Nlc3NlZERhdGEgfSBmcm9tICcuL3BpcGVzL3Byb2Nlc3NlZGRhdGEucGlwZSc7XG5pbXBvcnQgeyBQZXJmZWN0U2Nyb2xsYmFyTW9kdWxlIH0gZnJvbSAnbmd4LXBlcmZlY3Qtc2Nyb2xsYmFyJztcbmltcG9ydCB7IFBFUkZFQ1RfU0NST0xMQkFSX0NPTkZJRyB9IGZyb20gJ25neC1wZXJmZWN0LXNjcm9sbGJhcic7XG5pbXBvcnQgeyBQZXJmZWN0U2Nyb2xsYmFyQ29uZmlnSW50ZXJmYWNlIH0gZnJvbSAnbmd4LXBlcmZlY3Qtc2Nyb2xsYmFyJztcbiBcbmNvbnN0IERFRkFVTFRfUEVSRkVDVF9TQ1JPTExCQVJfQ09ORklHOiBQZXJmZWN0U2Nyb2xsYmFyQ29uZmlnSW50ZXJmYWNlID0ge1xuICBzdXBwcmVzc1Njcm9sbFg6IHRydWVcbn07XG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFJlYWN0aXZlRm9ybXNNb2R1bGUsRm9ybXNNb2R1bGUsSHR0cE1vZHVsZSxQZXJmZWN0U2Nyb2xsYmFyTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIEZseFVpRGF0YXRhYmxlQ29tcG9uZW50LENlaWwsSW1hZ2VGYWxsQmFjayxIYXNMaW1pdFRleHQsTGltaXRUZXh0LFByb2Nlc3NlZERhdGFcbiAgXSxcbiAgZXhwb3J0czpbRmx4VWlEYXRhdGFibGVDb21wb25lbnQsQ2VpbF0sXG4gIHByb3ZpZGVyczpbRmx4VWlEYXRhdGFibGVTZXJ2aWNlLFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IFBFUkZFQ1RfU0NST0xMQkFSX0NPTkZJRyxcbiAgICAgIHVzZVZhbHVlOiBERUZBVUxUX1BFUkZFQ1RfU0NST0xMQkFSX0NPTkZJR1xuICAgIH1dXG59KVxuZXhwb3J0IGNsYXNzIEZseFVpRGF0YXRhYmxlTW9kdWxlIHtcbiAgXG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7Ozs7SUE4QkUsWUFBbUIsSUFBVTtRQUFWLFNBQUksR0FBSixJQUFJLENBQU07dUJBdkJILEVBQUU7d0JBQ1ksSUFBSSxlQUFlLENBQU0sRUFBRSxDQUFDO3VCQUVuRCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRTswQkFFVixFQUFFOzBCQUVULENBQUM7MEJBRUQsQ0FBQztxQkFFTixFQUFFOzBCQUVFLEVBQUU7O2dDQUVDLEVBQUU7OzBCQUlWLEtBQUs7aUNBRU0sRUFBRTs2QkFDUCxFQUFFO0tBRzdCOzs7OztJQUVNLG9CQUFvQixDQUFDLE1BQVU7UUFDcEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBRTs7Ozs7OztJQVE1QixPQUFPLENBQUMsR0FBVTtRQUNyQixxQkFBSSxPQUFPLEdBQVksSUFBSSxPQUFPLEVBQUUsQ0FBRTtRQUN0QyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBQyxtQ0FBbUMsQ0FBQyxDQUFFO1FBQ3BFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDLEVBQUMsT0FBTyxFQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBQyxHQUFHLENBQUMsQ0FBQyxRQUFrQixLQUFLLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUU7Ozs7Ozs7OztJQVV0RyxRQUFRLENBQUMsR0FBVSxFQUFDLEVBQU0sRUFBQyxJQUFXO1FBQzNDLHFCQUFJLE9BQU8sR0FBWSxJQUFJLE9BQU8sRUFBRSxDQUFFO1FBQ3RDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFDLGlDQUFpQyxDQUFDLENBQUU7UUFDbEUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUMsRUFBRSxFQUFDLElBQUksRUFBQyxFQUFDLE9BQU8sRUFBQyxPQUFPLEVBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFjLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBRTs7Ozs7OztJQU81RixVQUFVLENBQUMsT0FBYztRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBRTs7Ozs7SUFJbkIsVUFBVTtRQUNmLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBRTs7Ozs7OztJQU9oQixjQUFjLENBQUMsSUFBUTtRQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBRTs7Ozs7Ozs7SUFRcEIsZ0JBQWdCLENBQUMsWUFBbUIsRUFBQyxLQUFZO1FBQ3ZELHFCQUFJLEdBQUcsR0FBa0IsRUFBRSxDQUFFO1FBQzdCLHFCQUFJLE9BQU8sR0FBVyxDQUFDLENBQUU7UUFDekIsS0FBSSxxQkFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFDLENBQUMsR0FBQyxZQUFZLEVBQUMsQ0FBQyxJQUFFLEtBQUssRUFBQztZQUNoQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUMsS0FBSyxFQUFDLE9BQU8sRUFBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBRTtZQUNuQyxPQUFPLEVBQUUsQ0FBRTtTQUNkO1FBQ0QsSUFBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBQztZQUM1QixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztTQUMxQztRQUNELE9BQU8sR0FBRyxDQUFFOzs7OztJQUdQLG9CQUFvQjtRQUN6QixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBRTs7Ozs7OztJQUloRyxvQkFBb0IsQ0FBQyxPQUFjLEVBQUMsc0JBQTRCLElBQUk7UUFDekUsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUU7UUFDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVk7WUFDdkQsSUFBRztnQkFDQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFFO2dCQUM1QixxQkFBSSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsWUFBWSxDQUFDO2dCQUM1RSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFFO2dCQUMzQixJQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFDO29CQUM3QixJQUFJLENBQUMsVUFBVSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUU7O29CQUV0QyxJQUFHLElBQUksQ0FBQyxNQUFNLEdBQUMsQ0FBQyxFQUFDO3dCQUNmLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUM5QztpQkFDRjtxQkFBSTtvQkFDSCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUU7b0JBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO2lCQUNyQjtnQkFDRCxJQUFHLG1CQUFtQixFQUFDO29CQUNyQixJQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFDO3dCQUM3QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDekU7eUJBQUk7d0JBQ0gsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ2xFO2lCQUNGO2dCQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO2FBQzFCO1lBQUEsd0JBQU0sQ0FBQyxFQUFDO2dCQUNMLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLEVBQUMsQ0FBQyxDQUFDLENBQUU7YUFDL0M7U0FDSixHQUFFLENBQUM7WUFDQSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBRTtTQUMzQixFQUFFLENBQUE7Ozs7O0lBSUEsYUFBYTtRQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFFOzs7Ozs7SUFJN0IsYUFBYSxDQUFDLE1BQWE7UUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUM7S0FDMUI7Ozs7SUFFRCxhQUFhO1FBQ1gsT0FBTyxJQUFJLE9BQU8sQ0FBUyxDQUFDLE9BQU87WUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJO2dCQUMxQixPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFFO2FBQ3ZCLEdBQUUsQ0FBQztnQkFDRixPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUU7YUFDYixFQUFFLENBQUE7U0FDSixDQUFDLENBQUU7S0FDTDs7O1lBekpGLFVBQVU7Ozs7WUFIRixJQUFJOzs7Ozs7O0FDRGI7Ozs7SUFPSSxZQUFvQixPQUE4QjtRQUE5QixZQUFPLEdBQVAsT0FBTyxDQUF1Qjt3QkFGakIsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDO2dDQUNyQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUUzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJO1lBQ2hDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDekIsQ0FBQyxDQUFDO0tBQ047Ozs7OztJQU1ELFVBQVUsQ0FBQyxJQUFJO1FBQ1gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDNUI7Ozs7O0lBS00sVUFBVTtRQUNiLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFFOzs7OztJQUczRCxZQUFZO1FBQ2YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBRTs7OztZQTFCckMsVUFBVTs7OztZQUZGLHFCQUFxQjs7Ozs7OztBQ0Q5Qjs7Ozs7SUF3UEUsWUFBbUIsTUFBbUIsRUFBUSxPQUE4QjtRQUF6RCxXQUFNLEdBQU4sTUFBTSxDQUFhO1FBQVEsWUFBTyxHQUFQLE9BQU8sQ0FBdUI7dUJBcERwRCxFQUFFO3VCQUNRLEVBQUU7aUNBQ0YsRUFBRTs2QkFDTixFQUFFO3dCQUNHLEVBQUU7aUNBQ0MsS0FBSztpQ0FDVCxFQUFFOzBCQUVkLEVBQUU7MEJBQ00sRUFBRTtnQ0FDSyxLQUFLOzJCQUNWLEtBQUs7dUNBQ08sS0FBSztpQ0FDWixFQUFFOzRCQUNOLEtBQUs7dUJBQ1gsRUFBRTtpQ0FDUyxLQUFLO29DQUNYLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFO2lDQUN6QixzQkFBc0I7NEJBQzNCLFNBQVM7cUJBQ2hCLEVBQUU7MEJBQ0EsRUFBRTs2QkFDVyxFQUFFO2lDQUNSLEVBQUMsVUFBVSxFQUFDLFNBQVMsRUFBQyxTQUFTLEVBQUMsU0FBUyxFQUFDOzJCQUNoRCxFQUFDLFVBQVUsRUFBQyxTQUFTLEVBQUMsU0FBUyxFQUFDLFNBQVMsRUFBQzs0QkFDekMsRUFBQyxVQUFVLEVBQUMsU0FBUyxFQUFDLFNBQVMsRUFBQyxTQUFTLEVBQUM7eUJBQzdDLEVBQUU7eUJBQ0YsRUFBQyxVQUFVLEVBQUMsS0FBSyxFQUFDLFdBQVcsRUFBQyxNQUFNLEVBQUMsVUFBVSxFQUFDLFNBQVMsRUFBQyxTQUFTLEVBQUMsU0FBUyxFQUFDO21DQUNwRSxFQUFDLFFBQVEsRUFBQyxPQUFPLEVBQUMsYUFBYSxFQUFDLElBQUksRUFBQzt3Q0FDakIsSUFBSSxZQUFZLEVBQU87eUNBQ3RCLElBQUksWUFBWSxFQUFPO3dDQUN0QixJQUFJLFlBQVksRUFBTztxQ0FDNUIsSUFBSSxZQUFZLEVBQU87Z0NBQzVCLElBQUksWUFBWSxFQUFPOzs7OzZCQUl6QyxFQUFFO29DQUNLLEVBQUU7MkJBQ2hCLEtBQUs7cUJBRWYsRUFBRTt3QkFDa0IsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDO29DQUUxQixFQUFFOzJCQUVYLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFO3NCQUVqQyxDQUFDO2lDQUdjLEVBQUU7S0FHaEM7Ozs7SUFFRCxNQUFNO1FBQ0YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLElBQUksQ0FBQyxDQUFBO0tBQ3pEOzs7Ozs7SUFNRCxtQkFBbUIsQ0FBQyxPQUFlO1FBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFFO0tBQzdCOzs7Ozs7SUFNRCxpQkFBaUIsQ0FBQyxVQUFpQjtRQUNqQyxxQkFBSSxPQUFPLHFCQUFvQyxRQUFRLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUEsQ0FBRTtRQUMxRixPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUU7UUFDakMscUJBQUksT0FBTyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUU7UUFDekoscUJBQUksWUFBWSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUU7O1FBR2xGLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJO1lBQ3hCLHFCQUFJLFFBQVEsR0FBZSxFQUFFLENBQUU7O1lBRS9CLEtBQUkscUJBQUksQ0FBQyxJQUFJLElBQUksRUFBQztnQkFDZCxxQkFBSSxHQUFHLEdBQVEsRUFBRSxDQUFFO2dCQUNuQixLQUFJLHFCQUFJLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQyxHQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUMsQ0FBQyxFQUFFLEVBQUM7b0JBQzdCLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUU7aUJBQ3BDO2dCQUNELFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUU7YUFDdkI7WUFDRCxJQUFHLFVBQVUsSUFBRSxPQUFPLEVBQUM7Z0JBQ25CLElBQUc7b0JBQ0gsT0FBTyxDQUFDLEVBQUMsU0FBUyxFQUFDLFFBQVEsRUFBQyxVQUFVLEVBQUMsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLEVBQUMsQ0FBQyxDQUFFO29CQUM5RCxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUU7aUJBQy9CO2dCQUFBLHdCQUFNLENBQUMsRUFBQztvQkFDVCxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUU7O2lCQUUvQjthQUNKO2lCQUFJO2dCQUNELHFCQUFJLFNBQVMsR0FBRyxDQUFDLFVBQVUsSUFBRSxLQUFLLElBQUksS0FBSyxHQUFFLENBQUMsVUFBVSxJQUFFLE9BQU8sSUFBSSxNQUFNLEdBQUUsTUFBTSxDQUFBO2dCQUNuRixxQkFBSSxNQUFNLEdBQUcsQ0FBQyxVQUFVLElBQUUsS0FBSyxJQUFJLENBQUMsR0FBRSxDQUFDLFVBQVUsSUFBRSxPQUFPLElBQUksQ0FBQyxHQUFFLENBQUMsQ0FBRTtnQkFFcEUscUJBQUksV0FBVyxHQUFRLEVBQUMsTUFBTSxFQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUMsQ0FBQTtnQkFDeEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsOERBQThELEVBQUMsTUFBTSxFQUFDLFdBQVcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUk7b0JBQ3BILHFCQUFJLFFBQVEsR0FBRyx1REFBdUQsR0FBRyxJQUFJLENBQUU7b0JBQy9FLFFBQVEsSUFBSSw2QkFBNkIsR0FBRSxTQUFTLENBQUM7b0JBQ3JELE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBRTtvQkFDakMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFFO2lCQUNuQyxHQUFFLENBQUM7O2lCQUVILEVBQUUsQ0FBQTthQUNOO1NBRUosQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFFO0tBQ25COzs7O0lBRUQsZUFBZTtRQUNiLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUU7S0FDcEQ7Ozs7SUFFRCxRQUFRO1FBQ0osT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQTs7Ozs7Ozs7O0tBU3ZCOzs7Ozs7O0lBRUQsa0JBQWtCLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxTQUFTOztRQUVqRCxxQkFBSSxPQUFPLEdBQUcsT0FBTyxRQUFRLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBRTVFLHFCQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7O1FBR2IsR0FBRyxJQUFJLFdBQVcsR0FBRyxRQUFRLENBQUM7O1FBRzlCLElBQUksU0FBUyxFQUFFO1lBQ1gscUJBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQzs7WUFHYixLQUFLLHFCQUFJLEtBQUssSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7O2dCQUcxQixHQUFHLElBQUksS0FBSyxHQUFHLEdBQUcsQ0FBQzthQUN0QjtZQUVELEdBQUcsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDOztZQUd2QixHQUFHLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQztTQUN2Qjs7UUFHRCxLQUFLLHFCQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDckMscUJBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQzs7WUFHYixLQUFLLHFCQUFJLEtBQUssSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQzFCLEdBQUcsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQzthQUN6QztZQUVELEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7O1lBRzdCLEdBQUcsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxHQUFHLElBQUksRUFBRSxFQUFFO1lBQ1gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3RCLE9BQU87U0FDVjs7UUFHRCxxQkFBSSxRQUFRLEdBQUcsV0FBVyxDQUFDOztRQUUzQixRQUFRLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUMsR0FBRyxDQUFDLENBQUM7O1FBRzFDLHFCQUFJLEdBQUcsR0FBRyw4QkFBOEIsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Ozs7OztRQVF2RCxxQkFBSSxJQUFJLEdBQVEsUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQzs7UUFHaEIsSUFBSSxDQUFDLEtBQUssR0FBRyxtQkFBbUIsQ0FBQztRQUNqQyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsR0FBRyxNQUFNLENBQUM7O1FBR2xDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ25DOzs7Ozs7SUFNQyxpQkFBaUIsQ0FBQyxPQUFPO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBRTtLQUN6Qjs7OztJQUVELFFBQVE7UUFDTixDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDOztTQUVoQixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFWixJQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFDO1lBQzNCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBQyxHQUFHLEdBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksR0FBQyxLQUFLLEdBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksR0FBQyxHQUFHLENBQUU7U0FDeEg7YUFBSTtZQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBRTtTQUNsQztRQUNDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFDaEMsWUFBWSxFQUFDLENBQUMsRUFBRSxFQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7U0FDeEMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztZQUNsQyxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztTQUMxQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUU7UUFDM0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM1QyxxQkFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFDLEdBQUcsR0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxHQUFDLEtBQUssR0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxHQUFDLEdBQUcsR0FBSSxJQUFJLENBQUMsT0FBTyxDQUFFO1FBQzlKLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSTtZQUNsQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBRTtZQUNuQixxQkFBSSxHQUFHLEdBQWUsRUFBRSxDQUFDO1lBQ3pCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDaEMsS0FBSyxxQkFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUNqQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDM0I7O2FBRUo7aUJBQ0k7Z0JBRUQsS0FBSyxxQkFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDeEMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBRTNCOzthQUVKO1lBQ0QsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEdBQUcsQ0FBQztZQUNoQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDL0IsQ0FBQyxDQUFBO0tBQ0g7Ozs7OztJQUVDLGVBQWUsQ0FBQyxNQUFNLEVBQUMsSUFBSTtRQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBRTtRQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUMsR0FBRyxHQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEdBQUMsS0FBSyxHQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEdBQUMsR0FBRyxHQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBRTtLQUM5Sjs7OztJQUVELGVBQWU7UUFDWCxxQkFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUU7UUFFaEQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUNaLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFDLE9BQU8sRUFBQyxlQUFlLEdBQUMsR0FBRyxFQUFDLENBQUMsQ0FBQztTQUNsRSxDQUFDLENBQUE7S0FDTDs7OztJQUVELGVBQWU7UUFDWCxxQkFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUU7UUFDaEQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUNaLENBQUMsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFDLE9BQU8sRUFBQyxlQUFlLEdBQUMsR0FBRyxFQUFDLENBQUMsQ0FBQztTQUN2RSxDQUFDLENBQUE7S0FDTDs7OztJQUVLLGlCQUFpQjtRQUN2QixxQkFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBRTtRQUM5QyxxQkFBSSxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUU7UUFFekQscUJBQUksZUFBZSxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUMsQ0FBQyxJQUFFLGdCQUFnQixHQUFDLFVBQVUsQ0FBRTtRQUMzRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFDLGVBQWUsQ0FBQyxDQUFBO1FBQ2hELHFCQUFJLGVBQWUsR0FBRyxHQUFHLEdBQUMsZUFBZSxDQUFFO1FBRTNDLE9BQU8sZUFBZSxDQUFFOzs7Ozs7O0lBRzFCLG1CQUFtQixDQUFDLEtBQVksRUFBQyxXQUFrQjtRQUNqRCxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUk7WUFDNUIsSUFBSSxXQUFXLElBQUksQ0FBQyxFQUFFO2dCQUNsQixPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ2xGO2lCQUNJLElBQUksV0FBVyxJQUFJLENBQUMsRUFBRTtnQkFDdkIsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUNuRjtpQkFDSTtnQkFDRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUMzRTtTQUNKLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBRTtLQUNuQjs7OztJQUVELGNBQWM7UUFDWixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUU7S0FDL0I7Ozs7SUFFRCxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztLQUN2RTs7Ozs7SUFFRCxTQUFTLENBQUMsT0FBZTtRQUN2QixJQUFJLE9BQU8sRUFBRTtZQUNULElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSTtnQkFFNUIsS0FBSyxxQkFBSSxDQUFDLElBQUksSUFBSSxFQUFFO29CQUNoQixJQUFJO3dCQUNBLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO3FCQUNqRTtvQkFDRCx3QkFBTyxDQUFDLEVBQUUsR0FBRztpQkFDaEI7O2FBRUosQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQ3BCO2FBQ0k7WUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztTQUN0QztLQUNGOzs7Ozs7O0lBRUQsbUJBQW1CLENBQUMsWUFBZ0IsRUFBRSxLQUFZLEVBQUUsUUFBZ0I7UUFDbEUsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNYLEtBQUsscUJBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzNELElBQUksWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2xELElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDM0MsTUFBTTtpQkFDVDthQUNKO1NBQ0o7YUFDSTtZQUNELElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSTtnQkFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7YUFDM0UsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQ3BCOztLQUVGOzs7O0lBRUQsZ0JBQWdCO1FBQ2QsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksMkJBQTJCLEdBQUcsMkJBQTJCO1lBQ2pILENBQUMsSUFBSSxDQUFDLGlCQUFpQixJQUFJLDJCQUEyQixHQUFHLDJCQUEyQixDQUFDO0tBQ3RGOzs7O0lBRUQsa0JBQWtCO1FBQ2QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBRSxDQUFDLENBQUU7S0FDNUQ7Ozs7SUFFRCxpQkFBaUI7UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFFO0tBQ3hHOzs7O0lBRUQsb0JBQW9CO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFFO0tBQ3hHOzs7OztJQUVELFlBQVksQ0FBQyxJQUFXO1FBQ3RCLElBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLEVBQUM7WUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFFO1lBQ2pDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVU7Z0JBQ3hDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFFO2dCQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksSUFBRSxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7Z0JBQzNILHFCQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUMsR0FBRyxHQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEdBQUMsR0FBRyxHQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFFLEdBQUcsR0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxHQUFDLEdBQUcsR0FBSSxJQUFJLENBQUMsT0FBTyxDQUFFO2dCQUMxTCxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFFO2FBQzNDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQzs7YUFFVCxDQUFDLENBQUE7WUFDRixPQUFRO1NBQ1g7O1FBR0QsSUFBSSxJQUFJLElBQUksTUFBTSxFQUFFO1lBQ2hCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ3JGO2FBQ0k7WUFDRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ3RDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDNUU7aUJBQ0k7Z0JBQ0QsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDekQ7U0FDSjtLQUNGOzs7OztJQUVELFVBQVUsQ0FBQyxZQUFZLEdBQUcsRUFBRTtRQUMxQixJQUFHLFlBQVksSUFBRSxFQUFFLEVBQUM7WUFDaEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUU7U0FDN0I7YUFBSTtZQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFFO1NBQzVCO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUk7WUFDaEMscUJBQUksYUFBYSxHQUFlLEVBQUUsQ0FBQzs7WUFFbkMsSUFBSSxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFO2dCQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7Z0JBQ2xELE9BQU87YUFDVjs7WUFFRCxxQkFBSSxVQUFVLEdBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUMvRixLQUFLLHFCQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O2dCQUVsQyxxQkFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2YsS0FBSyxxQkFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUN4QyxJQUFHO3dCQUNDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFOzRCQUMvRixLQUFLLEdBQUcsQ0FBQyxDQUFDOzRCQUNWLE1BQU07eUJBQ1Q7cUJBQ0o7b0JBQUEsd0JBQU0sQ0FBQyxFQUFDLEdBQUU7aUJBQ2Q7O2dCQUVELElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFO29CQUNaLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7aUJBQ25DO2FBQ0o7WUFDRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsYUFBYSxDQUFFOztZQUV4QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFFO1NBQzNCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztLQUNoQjs7Ozs7SUFLRCxpQkFBaUIsQ0FBQyxLQUFLOztRQUVuQixJQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFDO1lBQzNCLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBRTs7WUFFakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFFOztnQkFFakMsSUFBRyxLQUFLLElBQUUsS0FBSyxFQUFDO29CQUNaLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBRTtpQkFDOUM7O2dCQUVELHFCQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUMsR0FBRyxHQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsR0FBQyxHQUFHLEdBQUUsS0FBSyxHQUFFLEdBQUcsR0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxHQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFFOztnQkFFMUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUMsS0FBSyxDQUFDLENBQUU7YUFDakQsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDOzthQUVULENBQUMsQ0FBQTtZQUNGLE9BQVE7U0FDWDtRQUVELElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUN2Qzs7Ozs7OztJQVFELHVCQUF1QixDQUFDLEtBQVM7UUFDN0IsSUFBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsRUFBQztZQUMvRixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUU7WUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVTtnQkFDeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUU7Z0JBQ2pDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBQyxJQUFJLENBQUMsS0FBSyxDQUFFO2dCQUN0RCxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUMsR0FBRyxHQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEdBQUMsR0FBRyxHQUFDLEtBQUssR0FBQyxHQUFHLEdBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksR0FBQyxHQUFHLENBQUMsQ0FBRTtnQkFDL0ksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFFO2FBQzNCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQzs7YUFFVCxDQUFDLENBQUE7WUFDRixPQUFRO1NBQ1g7UUFFRCxxQkFBSSxHQUFHLEdBQVUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLElBQUksR0FBRyxJQUFJLENBQUMsRUFBRTtZQUNWLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2hCLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7U0FDeEM7YUFDSTtZQUNELElBQUksS0FBSyxJQUFJLEtBQUssRUFBRTtnQkFDaEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUM5QztpQkFDSTtnQkFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQzthQUNuQjtTQUNKO1FBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSTtZQUNoQyxJQUFJLEtBQUssS0FBSyxLQUFLLEVBQUU7Z0JBQ2pCLHFCQUFJLGNBQWMsR0FBZSxFQUFFLENBQUM7Z0JBQ3BDLEtBQUsscUJBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDekQsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7d0JBQ1QsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztxQkFDaEM7aUJBQ0o7Z0JBQ0QsSUFBSSxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxDQUFDO2lCQUMxQzthQUNKO2lCQUNJO2dCQUNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQzthQUNwQztZQUNELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUMxQixDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDcEI7OztZQXhyQkosU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBQyxrQkFBa0I7Z0JBQzNCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFMTDtnQkFDTCxNQUFNLEVBQUUsQ0FBQywwa1hBQTBrWCxDQUFDO2FBQ3JsWDs7OztZQWpNNkIsV0FBVztZQUNoQyxxQkFBcUI7OztzQkFrTTNCLEtBQUs7c0JBQ0wsS0FBSztnQ0FDTCxLQUFLOzRCQUNMLEtBQUs7dUJBQ0wsS0FBSztnQ0FDTCxLQUFLO2dDQUNMLEtBQUs7NkJBQ0wsS0FBSzt5QkFDTCxLQUFLO3lCQUNMLEtBQUs7K0JBQ0wsS0FBSzswQkFDTCxLQUFLO3NDQUNMLEtBQUs7Z0NBQ0wsS0FBSzsyQkFDTCxLQUFLO3NCQUNMLEtBQUs7Z0NBQ0wsS0FBSzttQ0FDTCxLQUFLO2dDQUNMLEtBQUs7MkJBQ0wsS0FBSztvQkFDTCxLQUFLO3lCQUNMLEtBQUs7NEJBQ0wsS0FBSztnQ0FDTCxLQUFLOzBCQUNMLEtBQUs7MkJBQ0wsS0FBSzt3QkFDTCxLQUFLO3dCQUNMLEtBQUs7a0NBQ0wsS0FBSzt1Q0FDTCxNQUFNO3dDQUNOLE1BQU07dUNBQ04sTUFBTTtvQ0FDTixNQUFNOytCQUNOLE1BQU07NEJBSU4sS0FBSzttQ0FDTCxLQUFLOzs7Ozs7SUFvZUosWUFBWSxFQUFjO3lCQUhHLEtBQUs7MEJBQ0wsT0FBTztRQUdsQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUM7UUFDM0IsSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7S0FDbkU7Ozs7SUFFTyxPQUFPO1FBQ2IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ25CLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDMUM7Ozs7O0lBR0ssWUFBWTtRQUNsQixJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDOzs7OztJQUc3RCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0tBQ3JCOzs7WUE3QkosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxpQ0FBaUM7YUFDOUM7Ozs7WUFIaUIsVUFBVTs7O3FCQUt2QixLQUFLLFNBQUMsK0JBQStCOzs7Ozs7O0FDenNCMUM7SUFLSTtLQUVDOzs7Ozs7SUFFRCxTQUFTLENBQUMsS0FBWSxFQUFDLEtBQVk7UUFDL0IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBQyxLQUFLLENBQUMsQ0FBRTtLQUNsQzs7O1lBVkosSUFBSSxTQUFDO2dCQUNGLElBQUksRUFBQyxNQUFNO2FBQ2Q7Ozs7Ozs7OztBQ0hEOzs7O0lBT0ksWUFBbUIsT0FBOEI7UUFBOUIsWUFBTyxHQUFQLE9BQU8sQ0FBdUI7S0FBRzs7Ozs7O0lBRXBELFNBQVMsQ0FBQyxLQUFtQixFQUFDLFlBQW1CO1FBQzlDLHFCQUFJLEtBQWMsQ0FBRTtRQUNwQixLQUFJLHFCQUFJLENBQUMsSUFBSSxLQUFLLEVBQUM7WUFDZixJQUFHLENBQUMsSUFBRSxZQUFZLEVBQUM7Z0JBQ2QsS0FBSyxHQUFHLElBQUksQ0FBRTtnQkFDZCxNQUFPO2FBQ1g7U0FDSjtRQUVELE9BQU8sS0FBSyxDQUFFO0tBQ2hCOzs7WUFoQkosSUFBSSxTQUFDO2dCQUNGLElBQUksRUFBQyxjQUFjO2FBQ3RCOzs7O1lBSlEscUJBQXFCOzs7Ozs7O0FDRDlCOzs7O0lBTUksWUFBbUIsT0FBNkI7UUFBN0IsWUFBTyxHQUFQLE9BQU8sQ0FBc0I7S0FFL0M7Ozs7OztJQUVELFNBQVMsQ0FBQyxrQkFBeUIsRUFBQyxJQUFXO1FBQzNDLHFCQUFJLElBQUksR0FBRyxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUU7UUFDekYscUJBQUksRUFBRSxHQUFHLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUU7UUFDN0YscUJBQUksVUFBVSxHQUFHLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBRTtRQUM1RyxxQkFBSSxHQUFHLEdBQVUsRUFBRSxDQUFFO1FBQ3JCLElBQUcsSUFBSSxDQUFDLE1BQU0sR0FBQyxFQUFFLEVBQUM7WUFDZCxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUMsRUFBRSxDQUFDLEdBQUUsVUFBVSxDQUFFO1NBQzlDO2FBQUk7WUFDRCxHQUFHLEdBQUcsSUFBSSxDQUFFO1NBQ2Y7UUFFRCxPQUFPLEdBQUcsQ0FBRTtLQUNmOzs7WUFwQkosSUFBSSxTQUFDO2dCQUNGLElBQUksRUFBQyxXQUFXO2FBQ25COzs7O1lBSFEscUJBQXFCOzs7Ozs7O0FDRDlCOzs7O0lBT0ksWUFBbUIsT0FBOEI7UUFBOUIsWUFBTyxHQUFQLE9BQU8sQ0FBdUI7S0FFaEQ7Ozs7O0lBRUQsU0FBUyxDQUFDLFNBQWdCO1FBQ3RCLHFCQUFJLFdBQVcsR0FBWSxLQUFLLENBQUU7UUFDbEMscUJBQUksVUFBVSxHQUFXLENBQUMsQ0FBQyxDQUFFO1FBQzdCLEtBQUkscUJBQUksQ0FBQyxHQUFDLENBQUMsRUFBQyxDQUFDLEdBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFDLENBQUMsRUFBRSxFQUFDO1lBQ2hELElBQUcsQ0FBQyxJQUFFLFNBQVMsRUFBQztnQkFDWixXQUFXLEdBQUcsSUFBSSxDQUFFO2dCQUNwQixVQUFVLEdBQUcsQ0FBQyxDQUFFO2FBQ25CO1NBQ0o7UUFFRCxJQUFHLFVBQVUsR0FBQyxDQUFDLEVBQUM7WUFDWixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUU7U0FDL0M7UUFFRCxPQUFPLFdBQVcsQ0FBRTtLQUN2Qjs7O1lBdkJKLElBQUksU0FBQztnQkFDRixJQUFJLEVBQUMsYUFBYTthQUNyQjs7OztZQUpRLHFCQUFxQjs7Ozs7OztBQ0Q5QixBQWNBLHVCQUFNLGdDQUFnQyxHQUFvQztJQUN4RSxlQUFlLEVBQUUsSUFBSTtDQUN0QixDQUFDO1dBWWMsZ0NBQWdDO0FBR2hEOzs7WUFkQyxRQUFRLFNBQUM7Z0JBQ1IsT0FBTyxFQUFFO29CQUNQLFlBQVksRUFBQyxtQkFBbUIsRUFBQyxXQUFXLEVBQUMsVUFBVSxFQUFDLHNCQUFzQjtpQkFDL0U7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLHVCQUF1QixFQUFDLElBQUksRUFBQyxhQUFhLEVBQUMsWUFBWSxFQUFDLFNBQVMsRUFBQyxhQUFhO2lCQUNoRjtnQkFDRCxPQUFPLEVBQUMsQ0FBQyx1QkFBdUIsRUFBQyxJQUFJLENBQUM7Z0JBQ3RDLFNBQVMsRUFBQyxDQUFDLHFCQUFxQjtvQkFDOUI7d0JBQ0UsT0FBTyxFQUFFLHdCQUF3Qjt3QkFDakMsUUFBUSxJQUFrQztxQkFDM0MsQ0FBQzthQUNMOzs7Ozs7Ozs7Ozs7Ozs7In0=