UNPKG

ngx-extended-pdf-viewer

Version:

Embedding PDF files in your Angular application. Highly configurable viewer including the toolbar, sidebar, and all the features you're used to.

645 lines 52.3 kB
/**
 * @fileoverview added by tsickle
 * Generated from: lib/ngx-extended-pdf-viewer.service.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import * as tslib_1 from "tslib";
import { NgxExtendedPdfViewerComponent } from './ngx-extended-pdf-viewer.component';
/**
 * @record
 */
export function FindOptions() { }
if (false) {
    /** @type {?|undefined} */
    FindOptions.prototype.highlightAll;
    /** @type {?|undefined} */
    FindOptions.prototype.matchCase;
    /** @type {?|undefined} */
    FindOptions.prototype.wholeWords;
    /** @type {?|undefined} */
    FindOptions.prototype.ignoreAccents;
    /** @type {?|undefined} */
    FindOptions.prototype.findMultipleSearchTexts;
    /** @type {?|undefined} */
    FindOptions.prototype.fuzzySearch;
}
/**
 * @record
 */
function DrawContext() { }
if (false) {
    /** @type {?} */
    DrawContext.prototype.ctx;
    /** @type {?} */
    DrawContext.prototype.canvas;
}
/**
 * @record
 */
export function PDFExportScaleFactor() { }
if (false) {
    /** @type {?|undefined} */
    PDFExportScaleFactor.prototype.width;
    /** @type {?|undefined} */
    PDFExportScaleFactor.prototype.height;
    /** @type {?|undefined} */
    PDFExportScaleFactor.prototype.scale;
}
var NgxExtendedPdfViewerService = /** @class */ (function () {
    function NgxExtendedPdfViewerService() {
    }
    /**
     * @param {?} text
     * @param {?=} options
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.findMultiple = /**
     * @param {?} text
     * @param {?=} options
     * @return {?}
     */
    function (text, options) {
        if (options === void 0) { options = {}; }
        options = tslib_1.__assign({}, options, { findMultipleSearchTexts: true });
        /** @type {?} */
        var searchString = text.join('\n') + '\n';
        return this.find(searchString, options);
    };
    /**
     * @param {?} text
     * @param {?=} options
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.find = /**
     * @param {?} text
     * @param {?=} options
     * @return {?}
     */
    function (text, options) {
        if (options === void 0) { options = {}; }
        if (!NgxExtendedPdfViewerComponent.ngxExtendedPdfViewerInitialized) {
            // tslint:disable-next-line:quotemark
            console.error("The PDF viewer hasn't finished initializing. Please call find() later.");
            return false;
        }
        else {
            /** @type {?} */
            var highlightAllCheckbox = (/** @type {?} */ (document.getElementById('findHighlightAll')));
            if (highlightAllCheckbox) {
                highlightAllCheckbox.checked = options.highlightAll || false;
            }
            /** @type {?} */
            var matchCaseCheckbox = (/** @type {?} */ (document.getElementById('findMatchCase')));
            if (matchCaseCheckbox) {
                matchCaseCheckbox.checked = options.matchCase || false;
            }
            /** @type {?} */
            var entireWordCheckbox = (/** @type {?} */ (document.getElementById('findEntireWord')));
            if (entireWordCheckbox) {
                entireWordCheckbox.checked = options.wholeWords || false;
            }
            /** @type {?} */
            var findIgnoreAccentsCheckbox = (/** @type {?} */ (document.getElementById('findIgnoreAccents')));
            if (findIgnoreAccentsCheckbox) {
                findIgnoreAccentsCheckbox.checked = options.ignoreAccents || false;
            }
            /** @type {?} */
            var multipleSearchTerms = options.findMultipleSearchTexts || text.includes('\n') || false;
            /** @type {?} */
            var findMultipleSearchTextsCheckbox = (/** @type {?} */ (document.getElementById('findMultipleSearchTexts')));
            if (findMultipleSearchTextsCheckbox) {
                findMultipleSearchTextsCheckbox.checked = multipleSearchTerms;
            }
            /** @type {?} */
            var individualWordsModeCheckbox = (/** @type {?} */ (document.getElementById('individualWordsMode')));
            if (individualWordsModeCheckbox) {
                individualWordsModeCheckbox.checked = false;
            }
            /** @type {?} */
            var fuzzySearchCheckbox = (/** @type {?} */ (document.getElementById('findFuzzy')));
            if (fuzzySearchCheckbox) {
                fuzzySearchCheckbox.checked = options.fuzzySearch || false;
            }
            /** @type {?} */
            var inputField = multipleSearchTerms ? document.getElementById('findInputMultiline') : document.getElementById('findInput');
            if (inputField) {
                if (inputField instanceof HTMLTextAreaElement) {
                    inputField.value = text;
                    // todo dirty hack!
                    inputField.classList.remove('hidden');
                    ((/** @type {?} */ (document.getElementById('findInput')))).classList.add('hidden');
                    ((/** @type {?} */ (document.getElementById('individualWordsModeLabel')))).classList.remove('hidden');
                    ((/** @type {?} */ (document.getElementById('individualWordsMode')))).classList.remove('hidden');
                    // end of the dirty hack
                }
                else if (inputField instanceof HTMLInputElement) {
                    inputField.value = text;
                    // todo dirty hack!
                    inputField.classList.remove('hidden');
                    ((/** @type {?} */ (document.getElementById('findInputMultiline')))).classList.add('hidden');
                    ((/** @type {?} */ (document.getElementById('individualWordsModeLabel')))).classList.add('hidden');
                    ((/** @type {?} */ (document.getElementById('individualWordsMode')))).classList.add('hidden');
                    // end of the dirty hack
                }
                inputField.dispatchEvent(new Event('input'));
                return true;
            }
            else {
                // tslint:disable-next-line:quotemark
                console.error("Unexpected error: the input field used to search isn't part of the DOM.");
                return false;
            }
        }
    };
    /**
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.findNext = /**
     * @return {?}
     */
    function () {
        if (!NgxExtendedPdfViewerComponent.ngxExtendedPdfViewerInitialized) {
            // tslint:disable-next-line:quotemark
            console.error("The PDF viewer hasn't finished initializing. Please call findNext() later.");
            return false;
        }
        else {
            /** @type {?} */
            var button = document.getElementById('findNext');
            if (button) {
                button.click();
                return true;
            }
            return false;
        }
    };
    /**
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.findPrevious = /**
     * @return {?}
     */
    function () {
        if (!NgxExtendedPdfViewerComponent.ngxExtendedPdfViewerInitialized) {
            // tslint:disable-next-line:quotemark
            console.error("The PDF viewer hasn't finished initializing. Please call findPrevious() later.");
            return false;
        }
        else {
            /** @type {?} */
            var button = document.getElementById('findPrevious');
            if (button) {
                button.click();
                return true;
            }
            return false;
        }
    };
    /**
     * @param {?=} printRange
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.print = /**
     * @param {?=} printRange
     * @return {?}
     */
    function (printRange) {
        var _this = this;
        /** @type {?} */
        var PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
        /** @type {?} */
        var alreadyThere = !!window['isInPDFPrintRange'] && !printRange;
        if (!alreadyThere) {
            if (!printRange) {
                printRange = (/** @type {?} */ ({}));
            }
            this.setPrintRange(printRange);
        }
        ((/** @type {?} */ (window))).printPDF();
        if (!alreadyThere) {
            PDFViewerApplication.eventBus.on('afterprint', (/**
             * @return {?}
             */
            function () {
                _this.removePrintRange();
            }));
        }
    };
    /**
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.removePrintRange = /**
     * @return {?}
     */
    function () {
        window['isInPDFPrintRange'] = undefined;
        window['filteredPageCount'] = undefined;
    };
    /**
     * @param {?} printRange
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.setPrintRange = /**
     * @param {?} printRange
     * @return {?}
     */
    function (printRange) {
        var _this = this;
        /** @type {?} */
        var PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
        window['isInPDFPrintRange'] = (/**
         * @param {?} page
         * @return {?}
         */
        function (page) { return _this.isInPDFPrintRange(page, (/** @type {?} */ (printRange))); });
        window['filteredPageCount'] = this.filteredPageCount(PDFViewerApplication.pagesCount, printRange);
    };
    /**
     * @param {?} pageCount
     * @param {?} range
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.filteredPageCount = /**
     * @param {?} pageCount
     * @param {?} range
     * @return {?}
     */
    function (pageCount, range) {
        /** @type {?} */
        var result = 0;
        for (var page = 1; page <= pageCount; page++) {
            if (this.isInPDFPrintRange(page, range)) {
                result++;
            }
        }
        return result;
    };
    /**
     * @param {?} pageIndex
     * @param {?} printRange
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.isInPDFPrintRange = /**
     * @param {?} pageIndex
     * @param {?} printRange
     * @return {?}
     */
    function (pageIndex, printRange) {
        /** @type {?} */
        var page = pageIndex + 1;
        if (printRange.from) {
            if (page < printRange.from) {
                return false;
            }
        }
        if (printRange.to) {
            if (page > printRange.to) {
                return false;
            }
        }
        if (printRange.excluded) {
            /** @type {?} */
            var e = (/** @type {?} */ (printRange.excluded));
            if (e.some((/**
             * @param {?} p
             * @return {?}
             */
            function (p) { return p === page; }))) {
                return false;
            }
        }
        if (printRange.included) {
            if (!printRange.included.some((/**
             * @param {?} p
             * @return {?}
             */
            function (p) { return p === page; }))) {
                return false;
            }
        }
        return true;
    };
    /** @deprecated please use getPageAsText(). The preview method will be removed soon. */
    /**
     * @deprecated please use getPageAsText(). The preview method will be removed soon.
     * @param {?} pageNumber
     * @param {?} callback
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.getPageAsText_preview = /**
     * @deprecated please use getPageAsText(). The preview method will be removed soon.
     * @param {?} pageNumber
     * @param {?} callback
     * @return {?}
     */
    function (pageNumber, callback) {
        var _this = this;
        /** @type {?} */
        var PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
        /** @type {?} */
        var pdfDocument = PDFViewerApplication.pdfDocument;
        return pdfDocument.getPage(pageNumber).then((/**
         * @param {?} pdfPage
         * @return {?}
         */
        function (pdfPage) {
            /** @type {?} */
            var text = pdfPage.getTextContent();
            text.then((/**
             * @param {?} txt
             * @return {?}
             */
            function (txt) { return callback(_this.convertTextInfoToText(txt)); }));
        }));
    };
    /**
     * @param {?} pageNumber
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.getPageAsText = /**
     * @param {?} pageNumber
     * @return {?}
     */
    function (pageNumber) {
        var _this = this;
        /** @type {?} */
        var PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
        /** @type {?} */
        var pdfDocument = PDFViewerApplication.pdfDocument;
        /** @type {?} */
        var pagePromise = pdfDocument.getPage(pageNumber);
        /** @type {?} */
        var extractTextSnippets = (/**
         * @param {?} pdfPage
         * @return {?}
         */
        function (pdfPage) { return new Promise((/**
         * @param {?} resolve
         * @param {?} reject
         * @return {?}
         */
        function (resolve, reject) {
            /** @type {?} */
            var textSnippets = pdfPage.getTextContent();
            resolve(textSnippets);
        })); });
        /** @type {?} */
        var combineTextSnippets = (/**
         * @param {?} textSnippets
         * @return {?}
         */
        function (textSnippets) { return new Promise((/**
         * @param {?} resolve
         * @param {?} reject
         * @return {?}
         */
        function (resolve, reject) {
            /** @type {?} */
            var text = _this.convertTextInfoToText(textSnippets);
            resolve(text);
        })); });
        return pagePromise.then(extractTextSnippets).then(combineTextSnippets);
    };
    /**
     * @private
     * @param {?} textInfo
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.convertTextInfoToText = /**
     * @private
     * @param {?} textInfo
     * @return {?}
     */
    function (textInfo) {
        if (!textInfo) {
            return '';
        }
        return textInfo.items.map((/**
         * @param {?} info
         * @return {?}
         */
        function (info) { return info.str; })).join('');
    };
    /** @deprecated please use getPageAsImage(). The preview method will be removed soon. */
    /**
     * @deprecated please use getPageAsImage(). The preview method will be removed soon.
     * @param {?} pageNumber
     * @param {?} scale
     * @param {?} callback
     * @param {?=} errorCallback
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.getPageAsImage_preview = /**
     * @deprecated please use getPageAsImage(). The preview method will be removed soon.
     * @param {?} pageNumber
     * @param {?} scale
     * @param {?} callback
     * @param {?=} errorCallback
     * @return {?}
     */
    function (pageNumber, scale, callback, errorCallback) {
        var _this = this;
        /** @type {?} */
        var PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
        /** @type {?} */
        var pdfDocument = PDFViewerApplication.pdfDocument;
        pdfDocument
            .getPage(pageNumber)
            .then((/**
         * @param {?} pdfPage
         * @return {?}
         */
        function (pdfPage) {
            _this.draw_preview(pdfPage, scale, callback, errorCallback);
        }))
            .catch((/**
         * @param {?} reason
         * @return {?}
         */
        function (reason) {
            if (errorCallback) {
                errorCallback({ message: 'Unable to initialize PDF page service', reason: reason });
            }
            else {
                console.error('Unable to initialize PDF page service', reason);
            }
        }));
    };
    /**
     * @param {?} pageNumber
     * @param {?} scale
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.getPageAsImage = /**
     * @param {?} pageNumber
     * @param {?} scale
     * @return {?}
     */
    function (pageNumber, scale) {
        var _this = this;
        /** @type {?} */
        var PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
        /** @type {?} */
        var pdfDocument = PDFViewerApplication.pdfDocument;
        /** @type {?} */
        var pagePromise = pdfDocument.getPage(pageNumber);
        /** @type {?} */
        var imagePromise = (/**
         * @param {?} pdfPage
         * @return {?}
         */
        function (pdfPage) { return new Promise((/**
         * @param {?} resolve
         * @param {?} reject
         * @return {?}
         */
        function (resolve, reject) {
            resolve(_this.draw(pdfPage, scale));
        })); });
        return pagePromise.then(imagePromise);
    };
    /**
     * @private
     * @param {?} pdfPage
     * @param {?} scale
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.draw = /**
     * @private
     * @param {?} pdfPage
     * @param {?} scale
     * @return {?}
     */
    function (pdfPage, scale) {
        /** @type {?} */
        var zoomFactor = 1;
        if (scale.scale) {
            zoomFactor = scale.scale;
        }
        else if (scale.width) {
            zoomFactor = scale.width / pdfPage.getViewport({ scale: 1 }).width;
        }
        else if (scale.height) {
            zoomFactor = scale.height / pdfPage.getViewport({ scale: 1 }).height;
        }
        /** @type {?} */
        var viewport = pdfPage.getViewport({
            scale: zoomFactor,
        });
        var _a = this.getPageDrawContext(viewport.width, viewport.height), ctx = _a.ctx, canvas = _a.canvas;
        /** @type {?} */
        var drawViewport = viewport.clone();
        /** @type {?} */
        var renderContext = {
            canvasContext: ctx,
            viewport: drawViewport,
        };
        /** @type {?} */
        var renderTask = pdfPage.render(renderContext);
        /** @type {?} */
        var dataUrlPromise = (/**
         * @return {?}
         */
        function () { return new Promise((/**
         * @param {?} resolve
         * @param {?} reject
         * @return {?}
         */
        function (resolve, reject) {
            resolve(canvas.toDataURL());
        })); });
        return renderTask.promise.then(dataUrlPromise);
    };
    /** @deprecated please use draw(). The preview method will be removed soon. */
    /**
     * @deprecated please use draw(). The preview method will be removed soon.
     * @private
     * @param {?} pdfPage
     * @param {?} scale
     * @param {?} callback
     * @param {?=} errorCallback
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.draw_preview = /**
     * @deprecated please use draw(). The preview method will be removed soon.
     * @private
     * @param {?} pdfPage
     * @param {?} scale
     * @param {?} callback
     * @param {?=} errorCallback
     * @return {?}
     */
    function (pdfPage, scale, callback, errorCallback) {
        /** @type {?} */
        var zoomFactor = 1;
        if (scale.scale) {
            zoomFactor = scale.scale;
        }
        else if (scale.width) {
            zoomFactor = scale.width / pdfPage.getViewport({ scale: 1 }).width;
        }
        else if (scale.height) {
            zoomFactor = scale.height / pdfPage.getViewport({ scale: 1 }).height;
        }
        /** @type {?} */
        var viewport = pdfPage.getViewport({
            scale: zoomFactor,
        });
        var _a = this.getPageDrawContext(viewport.width, viewport.height), ctx = _a.ctx, canvas = _a.canvas;
        /** @type {?} */
        var drawViewport = viewport.clone();
        /** @type {?} */
        var renderContext = {
            canvasContext: ctx,
            viewport: drawViewport,
        };
        /** @type {?} */
        var renderTask = pdfPage.render(renderContext);
        renderTask.promise.then((/**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var dataURL = canvas.toDataURL();
            callback(dataURL);
        }), (/**
         * @param {?} error
         * @return {?}
         */
        function (error) {
            if (errorCallback) {
                errorCallback(error);
            }
        }));
    };
    /**
     * @private
     * @param {?} width
     * @param {?} height
     * @return {?}
     */
    NgxExtendedPdfViewerService.prototype.getPageDrawContext = /**
     * @private
     * @param {?} width
     * @param {?} height
     * @return {?}
     */
    function (width, height) {
        /** @type {?} */
        var canvas = (/** @type {?} */ (document.createElement('canvas')));
        /** @type {?} */
        var ctx = canvas.getContext('2d', { alpha: false });
        if (!ctx) {
            // tslint:disable-next-line: quotemark
            throw new Error("Couldn't create the 2d context");
        }
        canvas.width = width;
        canvas.height = height;
        canvas.style.width = width + 'px';
        canvas.style.height = height + 'px';
        return { ctx: ctx, canvas: canvas };
    };
    return NgxExtendedPdfViewerService;
}());
export { NgxExtendedPdfViewerService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1leHRlbmRlZC1wZGYtdmlld2VyLyIsInNvdXJjZXMiOlsibGliL25neC1leHRlbmRlZC1wZGYtdmlld2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0scUNBQXFDLENBQUM7Ozs7QUFJcEYsaUNBT0M7OztJQU5DLG1DQUF1Qjs7SUFDdkIsZ0NBQW9COztJQUNwQixpQ0FBcUI7O0lBQ3JCLG9DQUF3Qjs7SUFDeEIsOENBQWtDOztJQUNsQyxrQ0FBc0I7Ozs7O0FBR3hCLDBCQUdDOzs7SUFGQywwQkFBOEI7O0lBQzlCLDZCQUEwQjs7Ozs7QUFHNUIsMENBSUM7OztJQUhDLHFDQUFlOztJQUNmLHNDQUFnQjs7SUFDaEIscUNBQWU7O0FBR2pCO0lBQ0U7SUFBZSxDQUFDOzs7Ozs7SUFFVCxrREFBWTs7Ozs7SUFBbkIsVUFBb0IsSUFBbUIsRUFBRSxPQUF5QjtRQUF6Qix3QkFBQSxFQUFBLFlBQXlCO1FBQ2hFLE9BQU8sd0JBQ0YsT0FBTyxJQUNWLHVCQUF1QixFQUFFLElBQUksR0FDOUIsQ0FBQzs7WUFDSSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJO1FBQzNDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQzs7Ozs7O0lBRU0sMENBQUk7Ozs7O0lBQVgsVUFBWSxJQUFZLEVBQUUsT0FBeUI7UUFBekIsd0JBQUEsRUFBQSxZQUF5QjtRQUNqRCxJQUFJLENBQUMsNkJBQTZCLENBQUMsK0JBQStCLEVBQUU7WUFDbEUscUNBQXFDO1lBQ3JDLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztZQUN4RixPQUFPLEtBQUssQ0FBQztTQUNkO2FBQU07O2dCQUNDLG9CQUFvQixHQUFHLG1CQUFBLFFBQVEsQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUMsRUFBb0I7WUFDNUYsSUFBSSxvQkFBb0IsRUFBRTtnQkFDeEIsb0JBQW9CLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDO2FBQzlEOztnQkFDSyxpQkFBaUIsR0FBRyxtQkFBQSxRQUFRLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxFQUFvQjtZQUN0RixJQUFJLGlCQUFpQixFQUFFO2dCQUNyQixpQkFBaUIsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7YUFDeEQ7O2dCQUNLLGtCQUFrQixHQUFHLG1CQUFBLFFBQVEsQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsRUFBb0I7WUFDeEYsSUFBSSxrQkFBa0IsRUFBRTtnQkFDdEIsa0JBQWtCLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDO2FBQzFEOztnQkFDSyx5QkFBeUIsR0FBRyxtQkFBQSxRQUFRLENBQUMsY0FBYyxDQUFDLG1CQUFtQixDQUFDLEVBQW9CO1lBQ2xHLElBQUkseUJBQXlCLEVBQUU7Z0JBQzdCLHlCQUF5QixDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsYUFBYSxJQUFJLEtBQUssQ0FBQzthQUNwRTs7Z0JBQ0ssbUJBQW1CLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSzs7Z0JBQ3JGLCtCQUErQixHQUFHLG1CQUFBLFFBQVEsQ0FBQyxjQUFjLENBQUMseUJBQXlCLENBQUMsRUFBb0I7WUFDOUcsSUFBSSwrQkFBK0IsRUFBRTtnQkFDbkMsK0JBQStCLENBQUMsT0FBTyxHQUFHLG1CQUFtQixDQUFDO2FBQy9EOztnQkFDSywyQkFBMkIsR0FBRyxtQkFBQSxRQUFRLENBQUMsY0FBYyxDQUFDLHFCQUFxQixDQUFDLEVBQW9CO1lBQ3RHLElBQUksMkJBQTJCLEVBQUU7Z0JBQy9CLDJCQUEyQixDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7YUFDN0M7O2dCQUNLLG1CQUFtQixHQUFHLG1CQUFBLFFBQVEsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLEVBQW9CO1lBQ3BGLElBQUksbUJBQW1CLEVBQUU7Z0JBQ3ZCLG1CQUFtQixDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQzthQUM1RDs7Z0JBQ0ssVUFBVSxHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDO1lBQzdILElBQUksVUFBVSxFQUFFO2dCQUNkLElBQUksVUFBVSxZQUFZLG1CQUFtQixFQUFFO29CQUM3QyxVQUFVLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztvQkFFeEIsbUJBQW1CO29CQUNuQixVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdEMsQ0FBQyxtQkFBQSxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxFQUFvQixDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDbkYsQ0FBQyxtQkFBQSxRQUFRLENBQUMsY0FBYyxDQUFDLDBCQUEwQixDQUFDLEVBQW9CLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUNyRyxDQUFDLG1CQUFBLFFBQVEsQ0FBQyxjQUFjLENBQUMscUJBQXFCLENBQUMsRUFBb0IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ2hHLHdCQUF3QjtpQkFDekI7cUJBQU0sSUFBSSxVQUFVLFlBQVksZ0JBQWdCLEVBQUU7b0JBQ2pELFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO29CQUN4QixtQkFBbUI7b0JBQ25CLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUN0QyxDQUFDLG1CQUFBLFFBQVEsQ0FBQyxjQUFjLENBQUMsb0JBQW9CLENBQUMsRUFBb0IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQzVGLENBQUMsbUJBQUEsUUFBUSxDQUFDLGNBQWMsQ0FBQywwQkFBMEIsQ0FBQyxFQUFvQixDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDbEcsQ0FBQyxtQkFBQSxRQUFRLENBQUMsY0FBYyxDQUFDLHFCQUFxQixDQUFDLEVBQW9CLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUM3Rix3QkFBd0I7aUJBQ3pCO2dCQUNELFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDN0MsT0FBTyxJQUFJLENBQUM7YUFDYjtpQkFBTTtnQkFDTCxxQ0FBcUM7Z0JBQ3JDLE9BQU8sQ0FBQyxLQUFLLENBQUMseUVBQXlFLENBQUMsQ0FBQztnQkFDekYsT0FBTyxLQUFLLENBQUM7YUFDZDtTQUNGO0lBQ0gsQ0FBQzs7OztJQUVNLDhDQUFROzs7SUFBZjtRQUNFLElBQUksQ0FBQyw2QkFBNkIsQ0FBQywrQkFBK0IsRUFBRTtZQUNsRSxxQ0FBcUM7WUFDckMsT0FBTyxDQUFDLEtBQUssQ0FBQyw0RUFBNEUsQ0FBQyxDQUFDO1lBQzVGLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7YUFBTTs7Z0JBQ0MsTUFBTSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDO1lBQ2xELElBQUksTUFBTSxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPLElBQUksQ0FBQzthQUNiO1lBQ0QsT0FBTyxLQUFLLENBQUM7U0FDZDtJQUNILENBQUM7Ozs7SUFFTSxrREFBWTs7O0lBQW5CO1FBQ0UsSUFBSSxDQUFDLDZCQUE2QixDQUFDLCtCQUErQixFQUFFO1lBQ2xFLHFDQUFxQztZQUNyQyxPQUFPLENBQUMsS0FBSyxDQUFDLGdGQUFnRixDQUFDLENBQUM7WUFDaEcsT0FBTyxLQUFLLENBQUM7U0FDZDthQUFNOztnQkFDQyxNQUFNLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUM7WUFDdEQsSUFBSSxNQUFNLEVBQUU7Z0JBQ1YsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFDRCxPQUFPLEtBQUssQ0FBQztTQUNkO0lBQ0gsQ0FBQzs7Ozs7SUFFTSwyQ0FBSzs7OztJQUFaLFVBQWEsVUFBMEI7UUFBdkMsaUJBZUM7O1lBZE8sb0JBQW9CLEdBQTBCLENBQUMsbUJBQUEsTUFBTSxFQUFPLENBQUMsQ0FBQyxvQkFBb0I7O1lBQ2xGLFlBQVksR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxVQUFVO1FBQ2pFLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDakIsSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDZixVQUFVLEdBQUcsbUJBQUEsRUFBRSxFQUFpQixDQUFDO2FBQ2xDO1lBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUNoQztRQUNELENBQUMsbUJBQUEsTUFBTSxFQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ2pCLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsWUFBWTs7O1lBQUU7Z0JBQzdDLEtBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFCLENBQUMsRUFBQyxDQUFDO1NBQ0o7SUFDSCxDQUFDOzs7O0lBRU0sc0RBQWdCOzs7SUFBdkI7UUFDRSxNQUFNLENBQUMsbUJBQW1CLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDeEMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsU0FBUyxDQUFDO0lBQzFDLENBQUM7Ozs7O0lBRU0sbURBQWE7Ozs7SUFBcEIsVUFBcUIsVUFBeUI7UUFBOUMsaUJBSUM7O1lBSE8sb0JBQW9CLEdBQTBCLENBQUMsbUJBQUEsTUFBTSxFQUFPLENBQUMsQ0FBQyxvQkFBb0I7UUFDeEYsTUFBTSxDQUFDLG1CQUFtQixDQUFDOzs7O1FBQUcsVUFBQyxJQUFZLElBQUssT0FBQSxLQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLG1CQUFBLFVBQVUsRUFBaUIsQ0FBQyxFQUF6RCxDQUF5RCxDQUFBLENBQUM7UUFDMUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNwRyxDQUFDOzs7Ozs7SUFFTSx1REFBaUI7Ozs7O0lBQXhCLFVBQXlCLFNBQWlCLEVBQUUsS0FBb0I7O1lBQzFELE1BQU0sR0FBRyxDQUFDO1FBQ2QsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxJQUFJLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUM1QyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQ3ZDLE1BQU0sRUFBRSxDQUFDO2FBQ1Y7U0FDRjtRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7Ozs7OztJQUVNLHVEQUFpQjs7Ozs7SUFBeEIsVUFBeUIsU0FBaUIsRUFBRSxVQUF5Qjs7WUFDN0QsSUFBSSxHQUFHLFNBQVMsR0FBRyxDQUFDO1FBQzFCLElBQUksVUFBVSxDQUFDLElBQUksRUFBRTtZQUNuQixJQUFJLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxFQUFFO2dCQUMxQixPQUFPLEtBQUssQ0FBQzthQUNkO1NBQ0Y7UUFDRCxJQUFJLFVBQVUsQ0FBQyxFQUFFLEVBQUU7WUFDakIsSUFBSSxJQUFJLEdBQUcsVUFBVSxDQUFDLEVBQUUsRUFBRTtnQkFDeEIsT0FBTyxLQUFLLENBQUM7YUFDZDtTQUNGO1FBQ0QsSUFBSSxVQUFVLENBQUMsUUFBUSxFQUFFOztnQkFDbkIsQ0FBQyxHQUFHLG1CQUFBLFVBQVUsQ0FBQyxRQUFRLEVBQWlCO1lBQzVDLElBQUksQ0FBQyxDQUFDLElBQUk7Ozs7WUFBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsS0FBSyxJQUFJLEVBQVYsQ0FBVSxFQUFDLEVBQUU7Z0JBQzdCLE9BQU8sS0FBSyxDQUFDO2FBQ2Q7U0FDRjtRQUNELElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRTtZQUN2QixJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJOzs7O1lBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLEtBQUssSUFBSSxFQUFWLENBQVUsRUFBQyxFQUFFO2dCQUNoRCxPQUFPLEtBQUssQ0FBQzthQUNkO1NBQ0Y7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCx1RkFBdUY7Ozs7Ozs7SUFDaEYsMkRBQXFCOzs7Ozs7SUFBNUIsVUFBNkIsVUFBa0IsRUFBRSxRQUF3QjtRQUF6RSxpQkFPQzs7WUFOTyxvQkFBb0IsR0FBMEIsQ0FBQyxtQkFBQSxNQUFNLEVBQU8sQ0FBQyxDQUFDLG9CQUFvQjs7WUFDbEYsV0FBVyxHQUFHLG9CQUFvQixDQUFDLFdBQVc7UUFDcEQsT0FBTyxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUk7Ozs7UUFBQyxVQUFDLE9BQU87O2dCQUM1QyxJQUFJLEdBQUcsT0FBTyxDQUFDLGNBQWMsRUFBRTtZQUNyQyxJQUFJLENBQUMsSUFBSTs7OztZQUFDLFVBQUMsR0FBRyxJQUFLLE9BQUEsUUFBUSxDQUFDLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUF6QyxDQUF5QyxFQUFDLENBQUM7UUFDaEUsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7OztJQUVNLG1EQUFhOzs7O0lBQXBCLFVBQXFCLFVBQWtCO1FBQXZDLGlCQWVDOztZQWRPLG9CQUFvQixHQUEwQixDQUFDLG1CQUFBLE1BQU0sRUFBTyxDQUFDLENBQUMsb0JBQW9COztZQUNsRixXQUFXLEdBQUcsb0JBQW9CLENBQUMsV0FBVzs7WUFFOUMsV0FBVyxHQUFrQixXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQzs7WUFFNUQsbUJBQW1COzs7O1FBQUcsVUFBQSxPQUFPLElBQUksT0FBQSxJQUFJLE9BQU87Ozs7O1FBQU0sVUFBQyxPQUFPLEVBQUUsTUFBTTs7Z0JBQ2hFLFlBQVksR0FBRyxPQUFPLENBQUMsY0FBYyxFQUFFO1lBQzdDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN4QixDQUFDLEVBQUMsRUFIcUMsQ0FHckMsQ0FBQTs7WUFDSSxtQkFBbUI7Ozs7UUFBRyxVQUFBLFlBQVksSUFBSSxPQUFBLElBQUksT0FBTzs7Ozs7UUFBUyxVQUFDLE9BQU8sRUFBRSxNQUFNOztnQkFDeEUsSUFBSSxHQUFHLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQyxZQUFZLENBQUM7WUFDckQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hCLENBQUMsRUFBQyxFQUgwQyxDQUcxQyxDQUFBO1FBQ0YsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDekUsQ0FBQzs7Ozs7O0lBRU8sMkRBQXFCOzs7OztJQUE3QixVQUE4QixRQUFhO1FBQ3pDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDYixPQUFPLEVBQUUsQ0FBQztTQUNYO1FBQ0QsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUc7Ozs7UUFBQyxVQUFDLElBQUksSUFBSyxPQUFBLElBQUksQ0FBQyxHQUFHLEVBQVIsQ0FBUSxFQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCx3RkFBd0Y7Ozs7Ozs7OztJQUNqRiw0REFBc0I7Ozs7Ozs7O0lBQTdCLFVBQThCLFVBQWtCLEVBQUUsS0FBMkIsRUFBRSxRQUEyQixFQUFFLGFBQW9DO1FBQWhKLGlCQWVDOztZQWRPLG9CQUFvQixHQUEwQixDQUFDLG1CQUFBLE1BQU0sRUFBTyxDQUFDLENBQUMsb0JBQW9COztZQUNsRixXQUFXLEdBQUcsb0JBQW9CLENBQUMsV0FBVztRQUNwRCxXQUFXO2FBQ1IsT0FBTyxDQUFDLFVBQVUsQ0FBQzthQUNuQixJQUFJOzs7O1FBQUMsVUFBQyxPQUFPO1lBQ1osS0FBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUM3RCxDQUFDLEVBQUM7YUFDRCxLQUFLOzs7O1FBQUMsVUFBQyxNQUFNO1lBQ1osSUFBSSxhQUFhLEVBQUU7Z0JBQ2pCLGFBQWEsQ0FBQyxFQUFFLE9BQU8sRUFBRSx1Q0FBdUMsRUFBRSxNQUFNLFFBQUEsRUFBRSxDQUFDLENBQUM7YUFDN0U7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUNoRTtRQUNILENBQUMsRUFBQyxDQUFDO0lBQ1AsQ0FBQzs7Ozs7O0lBRU0sb0RBQWM7Ozs7O0lBQXJCLFVBQXNCLFVBQWtCLEVBQUUsS0FBMkI7UUFBckUsaUJBU0M7O1lBUk8sb0JBQW9CLEdBQTBCLENBQUMsbUJBQUEsTUFBTSxFQUFPLENBQUMsQ0FBQyxvQkFBb0I7O1lBQ2xGLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQyxXQUFXOztZQUM5QyxXQUFXLEdBQWtCLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDOztZQUM1RCxZQUFZOzs7O1FBQUcsVUFBQSxPQUFPLElBQUksT0FBQSxJQUFJLE9BQU87Ozs7O1FBQU0sVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvRCxPQUFPLENBQUMsS0FBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNyQyxDQUFDLEVBQUMsRUFGOEIsQ0FFOUIsQ0FBQTtRQUVGLE9BQU8sV0FBVyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN4QyxDQUFDOzs7Ozs7O0lBRU8sMENBQUk7Ozs7OztJQUFaLFVBQWEsT0FBWSxFQUFFLEtBQTJCOztZQUNoRCxVQUFVLEdBQUcsQ0FBQztRQUNsQixJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUU7WUFDZixVQUFVLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztTQUMxQjthQUFNLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtZQUN0QixVQUFVLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDO1NBQ3BFO2FBQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFO1lBQ3ZCLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUM7U0FDdEU7O1lBQ0ssUUFBUSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7WUFDbkMsS0FBSyxFQUFFLFVBQVU7U0FDbEIsQ0FBQztRQUNJLElBQUEsNkRBQTBFLEVBQXhFLFlBQUcsRUFBRSxrQkFBbUU7O1lBQzFFLFlBQVksR0FBRyxRQUFRLENBQUMsS0FBSyxFQUFFOztZQUUvQixhQUFhLEdBQUc7WUFDcEIsYUFBYSxFQUFFLEdBQUc7WUFDbEIsUUFBUSxFQUFFLFlBQVk7U0FDdkI7O1lBQ0ssVUFBVSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDOztZQUUxQyxjQUFjOzs7UUFBRyxjQUFNLE9BQUEsSUFBSSxPQUFPOzs7OztRQUFTLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzlCLENBQUMsRUFBQyxFQUYyQixDQUUzQixDQUFBO1FBRUYsT0FBTyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsOEVBQThFOzs7Ozs7Ozs7O0lBQ3RFLGtEQUFZOzs7Ozs7Ozs7SUFBcEIsVUFBcUIsT0FBWSxFQUFFLEtBQTJCLEVBQUUsUUFBbUMsRUFBRSxhQUFvQzs7WUFDbkksVUFBVSxHQUFHLENBQUM7UUFDbEIsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO1lBQ2YsVUFBVSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7U0FDMUI7YUFBTSxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUU7WUFDdEIsVUFBVSxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQztTQUNwRTthQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtZQUN2QixVQUFVLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDO1NBQ3RFOztZQUNLLFFBQVEsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQ25DLEtBQUssRUFBRSxVQUFVO1NBQ2xCLENBQUM7UUFDSSxJQUFBLDZEQUEwRSxFQUF4RSxZQUFHLEVBQUUsa0JBQW1FOztZQUMxRSxZQUFZLEdBQUcsUUFBUSxDQUFDLEtBQUssRUFBRTs7WUFFL0IsYUFBYSxHQUFHO1lBQ3BCLGFBQWEsRUFBRSxHQUFHO1lBQ2xCLFFBQVEsRUFBRSxZQUFZO1NBQ3ZCOztZQUNLLFVBQVUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztRQUVoRCxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUk7OztRQUNyQjs7Z0JBQ1EsT0FBTyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUU7WUFDbEMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3BCLENBQUM7Ozs7UUFDRCxVQUFVLEtBQUs7WUFDYixJQUFJLGFBQWEsRUFBRTtnQkFDakIsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3RCO1FBQ0gsQ0FBQyxFQUNGLENBQUM7SUFDSixDQUFDOzs7Ozs7O0lBRU8sd0RBQWtCOzs7Ozs7SUFBMUIsVUFBMkIsS0FBYSxFQUFFLE1BQWM7O1lBQ2hELE1BQU0sR0FBRyxtQkFBQSxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxFQUFxQjs7WUFDOUQsR0FBRyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ3JELElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDUixzQ0FBc0M7WUFDdEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1NBQ25EO1FBRUQsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDckIsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDdkIsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBRXBDLE9BQU8sRUFBRSxHQUFHLEtBQUEsRUFBRSxNQUFNLFFBQUEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFDSCxrQ0FBQztBQUFELENBQUMsQUF4VEQsSUF3VEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ3hFeHRlbmRlZFBkZlZpZXdlckNvbXBvbmVudCB9IGZyb20gJy4vbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFBERlByaW50UmFuZ2UgfSBmcm9tICcuL29wdGlvbnMvcGRmLXByaW50LXJhbmdlJztcbmltcG9ydCB7IElQREZWaWV3ZXJBcHBsaWNhdGlvbiB9IGZyb20gJy4vb3B0aW9ucy9wZGYtdmlld2VyLWFwcGxpY2F0aW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBGaW5kT3B0aW9ucyB7XG4gIGhpZ2hsaWdodEFsbD86IGJvb2xlYW47XG4gIG1hdGNoQ2FzZT86IGJvb2xlYW47XG4gIHdob2xlV29yZHM/OiBib29sZWFuO1xuICBpZ25vcmVBY2NlbnRzPzogYm9vbGVhbjtcbiAgZmluZE11bHRpcGxlU2VhcmNoVGV4dHM/OiBib29sZWFuO1xuICBmdXp6eVNlYXJjaD86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBEcmF3Q29udGV4dCB7XG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEO1xuICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBERkV4cG9ydFNjYWxlRmFjdG9yIHtcbiAgd2lkdGg/OiBudW1iZXI7XG4gIGhlaWdodD86IG51bWJlcjtcbiAgc2NhbGU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBOZ3hFeHRlbmRlZFBkZlZpZXdlclNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgcHVibGljIGZpbmRNdWx0aXBsZSh0ZXh0OiBBcnJheTxzdHJpbmc+LCBvcHRpb25zOiBGaW5kT3B0aW9ucyA9IHt9KTogYm9vbGVhbiB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBmaW5kTXVsdGlwbGVTZWFyY2hUZXh0czogdHJ1ZSxcbiAgICB9O1xuICAgIGNvbnN0IHNlYXJjaFN0cmluZyA9IHRleHQuam9pbignXFxuJykgKyAnXFxuJztcbiAgICByZXR1cm4gdGhpcy5maW5kKHNlYXJjaFN0cmluZywgb3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgZmluZCh0ZXh0OiBzdHJpbmcsIG9wdGlvbnM6IEZpbmRPcHRpb25zID0ge30pOiBib29sZWFuIHtcbiAgICBpZiAoIU5neEV4dGVuZGVkUGRmVmlld2VyQ29tcG9uZW50Lm5neEV4dGVuZGVkUGRmVmlld2VySW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpxdW90ZW1hcmtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgUERGIHZpZXdlciBoYXNuJ3QgZmluaXNoZWQgaW5pdGlhbGl6aW5nLiBQbGVhc2UgY2FsbCBmaW5kKCkgbGF0ZXIuXCIpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoaWdobGlnaHRBbGxDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaW5kSGlnaGxpZ2h0QWxsJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmIChoaWdobGlnaHRBbGxDaGVja2JveCkge1xuICAgICAgICBoaWdobGlnaHRBbGxDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5oaWdobGlnaHRBbGwgfHwgZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBtYXRjaENhc2VDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaW5kTWF0Y2hDYXNlJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmIChtYXRjaENhc2VDaGVja2JveCkge1xuICAgICAgICBtYXRjaENhc2VDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5tYXRjaENhc2UgfHwgZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBlbnRpcmVXb3JkQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZEVudGlyZVdvcmQnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgaWYgKGVudGlyZVdvcmRDaGVja2JveCkge1xuICAgICAgICBlbnRpcmVXb3JkQ2hlY2tib3guY2hlY2tlZCA9IG9wdGlvbnMud2hvbGVXb3JkcyB8fCBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbmRJZ25vcmVBY2NlbnRzQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElnbm9yZUFjY2VudHMnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgaWYgKGZpbmRJZ25vcmVBY2NlbnRzQ2hlY2tib3gpIHtcbiAgICAgICAgZmluZElnbm9yZUFjY2VudHNDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5pZ25vcmVBY2NlbnRzIHx8IGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgbXVsdGlwbGVTZWFyY2hUZXJtcyA9IG9wdGlvbnMuZmluZE11bHRpcGxlU2VhcmNoVGV4dHMgfHwgdGV4dC5pbmNsdWRlcygnXFxuJykgfHwgZmFsc2U7XG4gICAgICBjb25zdCBmaW5kTXVsdGlwbGVTZWFyY2hUZXh0c0NoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRNdWx0aXBsZVNlYXJjaFRleHRzJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmIChmaW5kTXVsdGlwbGVTZWFyY2hUZXh0c0NoZWNrYm94KSB7XG4gICAgICAgIGZpbmRNdWx0aXBsZVNlYXJjaFRleHRzQ2hlY2tib3guY2hlY2tlZCA9IG11bHRpcGxlU2VhcmNoVGVybXM7XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRpdmlkdWFsV29yZHNNb2RlQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5kaXZpZHVhbFdvcmRzTW9kZScpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAoaW5kaXZpZHVhbFdvcmRzTW9kZUNoZWNrYm94KSB7XG4gICAgICAgIGluZGl2aWR1YWxXb3Jkc01vZGVDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBmdXp6eVNlYXJjaENoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRGdXp6eScpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAoZnV6enlTZWFyY2hDaGVja2JveCkge1xuICAgICAgICBmdXp6eVNlYXJjaENoZWNrYm94LmNoZWNrZWQgPSBvcHRpb25zLmZ1enp5U2VhcmNoIHx8IGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5wdXRGaWVsZCA9IG11bHRpcGxlU2VhcmNoVGVybXMgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0TXVsdGlsaW5lJykgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0Jyk7XG4gICAgICBpZiAoaW5wdXRGaWVsZCkge1xuICAgICAgICBpZiAoaW5wdXRGaWVsZCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQpIHtcbiAgICAgICAgICBpbnB1dEZpZWxkLnZhbHVlID0gdGV4dDtcblxuICAgICAgICAgIC8vIHRvZG8gZGlydHkgaGFjayFcbiAgICAgICAgICBpbnB1dEZpZWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0JykgYXMgSFRNTElucHV0RWxlbWVudCkuY2xhc3NMaXN0LmFkZCgnaGlkZGVuJyk7XG4gICAgICAgICAgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbmRpdmlkdWFsV29yZHNNb2RlTGFiZWwnKSBhcyBIVE1MSW5wdXRFbGVtZW50KS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW4nKTtcbiAgICAgICAgICAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2luZGl2aWR1YWxXb3Jkc01vZGUnKSBhcyBIVE1MSW5wdXRFbGVtZW50KS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW4nKTtcbiAgICAgICAgICAvLyBlbmQgb2YgdGhlIGRpcnR5IGhhY2tcbiAgICAgICAgfSBlbHNlIGlmIChpbnB1dEZpZWxkIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xuICAgICAgICAgIGlucHV0RmllbGQudmFsdWUgPSB0ZXh0O1xuICAgICAgICAgIC8vIHRvZG8gZGlydHkgaGFjayFcbiAgICAgICAgICBpbnB1dEZpZWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0TXVsdGlsaW5lJykgYXMgSFRNTElucHV0RWxlbWVudCkuY2xhc3NMaXN0LmFkZCgnaGlkZGVuJyk7XG4gICAgICAgICAgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbmRpdmlkdWFsV29yZHNNb2RlTGFiZWwnKSBhcyBIVE1MSW5wdXRFbGVtZW50KS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4nKTtcbiAgICAgICAgICAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2luZGl2aWR1YWxXb3Jkc01vZGUnKSBhcyBIVE1MSW5wdXRFbGVtZW50KS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4nKTtcbiAgICAgICAgICAvLyBlbmQgb2YgdGhlIGRpcnR5IGhhY2tcbiAgICAgICAgfVxuICAgICAgICBpbnB1dEZpZWxkLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdpbnB1dCcpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6cXVvdGVtYXJrXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJVbmV4cGVjdGVkIGVycm9yOiB0aGUgaW5wdXQgZmllbGQgdXNlZCB0byBzZWFyY2ggaXNuJ3QgcGFydCBvZiB0aGUgRE9NLlwiKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBmaW5kTmV4dCgpOiBib29sZWFuIHtcbiAgICBpZiAoIU5neEV4dGVuZGVkUGRmVmlld2VyQ29tcG9uZW50Lm5neEV4dGVuZGVkUGRmVmlld2VySW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpxdW90ZW1hcmtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgUERGIHZpZXdlciBoYXNuJ3QgZmluaXNoZWQgaW5pdGlhbGl6aW5nLiBQbGVhc2UgY2FsbCBmaW5kTmV4dCgpIGxhdGVyLlwiKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmROZXh0Jyk7XG4gICAgICBpZiAoYnV0dG9uKSB7XG4gICAgICAgIGJ1dHRvbi5jbGljaygpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZmluZFByZXZpb3VzKCk6IGJvb2xlYW4ge1xuICAgIGlmICghTmd4RXh0ZW5kZWRQZGZWaWV3ZXJDb21wb25lbnQubmd4RXh0ZW5kZWRQZGZWaWV3ZXJJbml0aWFsaXplZCkge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnF1b3RlbWFya1xuICAgICAgY29uc29sZS5lcnJvcihcIlRoZSBQREYgdmlld2VyIGhhc24ndCBmaW5pc2hlZCBpbml0aWFsaXppbmcuIFBsZWFzZSBjYWxsIGZpbmRQcmV2aW91cygpIGxhdGVyLlwiKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRQcmV2aW91cycpO1xuICAgICAgaWYgKGJ1dHRvbikge1xuICAgICAgICBidXR0b24uY2xpY2soKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHByaW50KHByaW50UmFuZ2U/OiBQREZQcmludFJhbmdlKSB7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBjb25zdCBhbHJlYWR5VGhlcmUgPSAhIXdpbmRvd1snaXNJblBERlByaW50UmFuZ2UnXSAmJiAhcHJpbnRSYW5nZTtcbiAgICBpZiAoIWFscmVhZHlUaGVyZSkge1xuICAgICAgaWYgKCFwcmludFJhbmdlKSB7XG4gICAgICAgIHByaW50UmFuZ2UgPSB7fSBhcyBQREZQcmludFJhbmdlO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRQcmludFJhbmdlKHByaW50UmFuZ2UpO1xuICAgIH1cbiAgICAod2luZG93IGFzIGFueSkucHJpbnRQREYoKTtcbiAgICBpZiAoIWFscmVhZHlUaGVyZSkge1xuICAgICAgUERGVmlld2VyQXBwbGljYXRpb24uZXZlbnRCdXMub24oJ2FmdGVycHJpbnQnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMucmVtb3ZlUHJpbnRSYW5nZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlbW92ZVByaW50UmFuZ2UoKSB7XG4gICAgd2luZG93Wydpc0luUERGUHJpbnRSYW5nZSddID0gdW5kZWZpbmVkO1xuICAgIHdpbmRvd1snZmlsdGVyZWRQYWdlQ291bnQnXSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRQcmludFJhbmdlKHByaW50UmFuZ2U6IFBERlByaW50UmFuZ2UpIHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIHdpbmRvd1snaXNJblBERlByaW50UmFuZ2UnXSA9IChwYWdlOiBudW1iZXIpID0+IHRoaXMuaXNJblBERlByaW50UmFuZ2UocGFnZSwgcHJpbnRSYW5nZSBhcyBQREZQcmludFJhbmdlKTtcbiAgICB3aW5kb3dbJ2ZpbHRlcmVkUGFnZUNvdW50J10gPSB0aGlzLmZpbHRlcmVkUGFnZUNvdW50KFBERlZpZXdlckFwcGxpY2F0aW9uLnBhZ2VzQ291bnQsIHByaW50UmFuZ2UpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlcmVkUGFnZUNvdW50KHBhZ2VDb3VudDogbnVtYmVyLCByYW5nZTogUERGUHJpbnRSYW5nZSk6IG51bWJlciB7XG4gICAgbGV0IHJlc3VsdCA9IDA7XG4gICAgZm9yIChsZXQgcGFnZSA9IDE7IHBhZ2UgPD0gcGFnZUNvdW50OyBwYWdlKyspIHtcbiAgICAgIGlmICh0aGlzLmlzSW5QREZQcmludFJhbmdlKHBhZ2UsIHJhbmdlKSkge1xuICAgICAgICByZXN1bHQrKztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBpc0luUERGUHJpbnRSYW5nZShwYWdlSW5kZXg6IG51bWJlciwgcHJpbnRSYW5nZTogUERGUHJpbnRSYW5nZSkge1xuICAgIGNvbnN0IHBhZ2UgPSBwYWdlSW5kZXggKyAxO1xuICAgIGlmIChwcmludFJhbmdlLmZyb20pIHtcbiAgICAgIGlmIChwYWdlIDwgcHJpbnRSYW5nZS5mcm9tKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHByaW50UmFuZ2UudG8pIHtcbiAgICAgIGlmIChwYWdlID4gcHJpbnRSYW5nZS50bykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcmludFJhbmdlLmV4Y2x1ZGVkKSB7XG4gICAgICBsZXQgZSA9IHByaW50UmFuZ2UuZXhjbHVkZWQgYXMgQXJyYXk8bnVtYmVyPjtcbiAgICAgIGlmIChlLnNvbWUoKHApID0+IHAgPT09IHBhZ2UpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHByaW50UmFuZ2UuaW5jbHVkZWQpIHtcbiAgICAgIGlmICghcHJpbnRSYW5nZS5pbmNsdWRlZC5zb21lKChwKSA9PiBwID09PSBwYWdlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkIHBsZWFzZSB1c2UgZ2V0UGFnZUFzVGV4dCgpLiBUaGUgcHJldmlldyBtZXRob2Qgd2lsbCBiZSByZW1vdmVkIHNvb24uICovXG4gIHB1YmxpYyBnZXRQYWdlQXNUZXh0X3ByZXZpZXcocGFnZU51bWJlcjogbnVtYmVyLCBjYWxsYmFjazogKHRleHQpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBkZkRvY3VtZW50ID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmRG9jdW1lbnQ7XG4gICAgcmV0dXJuIHBkZkRvY3VtZW50LmdldFBhZ2UocGFnZU51bWJlcikudGhlbigocGRmUGFnZSkgPT4ge1xuICAgICAgY29uc3QgdGV4dCA9IHBkZlBhZ2UuZ2V0VGV4dENvbnRlbnQoKTtcbiAgICAgIHRleHQudGhlbigodHh0KSA9PiBjYWxsYmFjayh0aGlzLmNvbnZlcnRUZXh0SW5mb1RvVGV4dCh0eHQpKSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFnZUFzVGV4dChwYWdlTnVtYmVyOiBudW1iZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG4gICAgY29uc3QgcGRmRG9jdW1lbnQgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZEb2N1bWVudDtcblxuICAgIGNvbnN0IHBhZ2VQcm9taXNlOiBQcm9taXNlPGFueT4gPSAgcGRmRG9jdW1lbnQuZ2V0UGFnZShwYWdlTnVtYmVyKTtcblxuICAgIGNvbnN0IGV4dHJhY3RUZXh0U25pcHBldHMgPSBwZGZQYWdlID0+IG5ldyBQcm9taXNlPGFueT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdGV4dFNuaXBwZXRzID0gcGRmUGFnZS5nZXRUZXh0Q29udGVudCgpO1xuICAgICAgcmVzb2x2ZSh0ZXh0U25pcHBldHMpO1xuICAgIH0pO1xuICAgIGNvbnN0IGNvbWJpbmVUZXh0U25pcHBldHMgPSB0ZXh0U25pcHBldHMgPT4gbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhpcy5jb252ZXJ0VGV4dEluZm9Ub1RleHQodGV4dFNuaXBwZXRzKTtcbiAgICAgIHJlc29sdmUodGV4dCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHBhZ2VQcm9taXNlLnRoZW4oZXh0cmFjdFRleHRTbmlwcGV0cykudGhlbihjb21iaW5lVGV4dFNuaXBwZXRzKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFRleHRJbmZvVG9UZXh0KHRleHRJbmZvOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghdGV4dEluZm8pIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHRleHRJbmZvLml0ZW1zLm1hcCgoaW5mbykgPT4gaW5mby5zdHIpLmpvaW4oJycpO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkIHBsZWFzZSB1c2UgZ2V0UGFnZUFzSW1hZ2UoKS4gVGhlIHByZXZpZXcgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBzb29uLiAqL1xuICBwdWJsaWMgZ2V0UGFnZUFzSW1hZ2VfcHJldmlldyhwYWdlTnVtYmVyOiBudW1iZXIsIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3RvciwgY2FsbGJhY2s6IChkYXRhVVJMKSA9PiB2b2lkLCBlcnJvckNhbGxiYWNrPzogKGVycm9yOiBhbnkpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBkZkRvY3VtZW50ID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmRG9jdW1lbnQ7XG4gICAgcGRmRG9jdW1lbnRcbiAgICAgIC5nZXRQYWdlKHBhZ2VOdW1iZXIpXG4gICAgICAudGhlbigocGRmUGFnZSkgPT4ge1xuICAgICAgICB0aGlzLmRyYXdfcHJldmlldyhwZGZQYWdlLCBzY2FsZSwgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgocmVhc29uKSA9PiB7XG4gICAgICAgIGlmIChlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgICAgZXJyb3JDYWxsYmFjayh7IG1lc3NhZ2U6ICdVbmFibGUgdG8gaW5pdGlhbGl6ZSBQREYgcGFnZSBzZXJ2aWNlJywgcmVhc29uIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuYWJsZSB0byBpbml0aWFsaXplIFBERiBwYWdlIHNlcnZpY2UnLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQYWdlQXNJbWFnZShwYWdlTnVtYmVyOiBudW1iZXIsIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3Rvcik6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBjb25zdCBwZGZEb2N1bWVudCA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZkRvY3VtZW50O1xuICAgIGNvbnN0IHBhZ2VQcm9taXNlOiBQcm9taXNlPGFueT4gPSAgcGRmRG9jdW1lbnQuZ2V0UGFnZShwYWdlTnVtYmVyKTtcbiAgICBjb25zdCBpbWFnZVByb21pc2UgPSBwZGZQYWdlID0+IG5ldyBQcm9taXNlPGFueT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgcmVzb2x2ZSh0aGlzLmRyYXcocGRmUGFnZSwgc2NhbGUpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYWdlUHJvbWlzZS50aGVuKGltYWdlUHJvbWlzZSk7XG4gIH1cblxuICBwcml2YXRlIGRyYXcocGRmUGFnZTogYW55LCBzY2FsZTogUERGRXhwb3J0U2NhbGVGYWN0b3IpOiBQcm9taXNlPEhUTUxDYW52YXNFbGVtZW50PiB7XG4gICAgbGV0IHpvb21GYWN0b3IgPSAxO1xuICAgIGlmIChzY2FsZS5zY2FsZSkge1xuICAgICAgem9vbUZhY3RvciA9IHNjYWxlLnNjYWxlO1xuICAgIH0gZWxzZSBpZiAoc2NhbGUud2lkdGgpIHtcbiAgICAgIHpvb21GYWN0b3IgPSBzY2FsZS53aWR0aCAvIHBkZlBhZ2UuZ2V0Vmlld3BvcnQoeyBzY2FsZTogMSB9KS53aWR0aDtcbiAgICB9IGVsc2UgaWYgKHNjYWxlLmhlaWdodCkge1xuICAgICAgem9vbUZhY3RvciA9IHNjYWxlLmhlaWdodCAvIHBkZlBhZ2UuZ2V0Vmlld3BvcnQoeyBzY2FsZTogMSB9KS5oZWlnaHQ7XG4gICAgfVxuICAgIGNvbnN0IHZpZXdwb3J0ID0gcGRmUGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICBzY2FsZTogem9vbUZhY3RvcixcbiAgICB9KTtcbiAgICBjb25zdCB7IGN0eCwgY2FudmFzIH0gPSB0aGlzLmdldFBhZ2VEcmF3Q29udGV4dCh2aWV3cG9ydC53aWR0aCwgdmlld3BvcnQuaGVpZ2h0KTtcbiAgICBjb25zdCBkcmF3Vmlld3BvcnQgPSB2aWV3cG9ydC5jbG9uZSgpO1xuXG4gICAgY29uc3QgcmVuZGVyQ29udGV4dCA9IHtcbiAgICAgIGNhbnZhc0NvbnRleHQ6IGN0eCxcbiAgICAgIHZpZXdwb3J0OiBkcmF3Vmlld3BvcnQsXG4gICAgfTtcbiAgICBjb25zdCByZW5kZXJUYXNrID0gcGRmUGFnZS5yZW5kZXIocmVuZGVyQ29udGV4dCk7XG5cbiAgICBjb25zdCBkYXRhVXJsUHJvbWlzZSA9ICgpID0+IG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgcmVzb2x2ZShjYW52YXMudG9EYXRhVVJMKCkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlbmRlclRhc2sucHJvbWlzZS50aGVuKGRhdGFVcmxQcm9taXNlKTtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCBwbGVhc2UgdXNlIGRyYXcoKS4gVGhlIHByZXZpZXcgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBzb29uLiAqL1xuICBwcml2YXRlIGRyYXdfcHJldmlldyhwZGZQYWdlOiBhbnksIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3RvciwgY2FsbGJhY2s6IChkYXRhVVJMOiBzdHJpbmcpID0+IHZvaWQsIGVycm9yQ2FsbGJhY2s/OiAoZXJyb3I6IGFueSkgPT4gdm9pZCk6IHZvaWQge1xuICAgIGxldCB6b29tRmFjdG9yID0gMTtcbiAgICBpZiAoc2NhbGUuc2NhbGUpIHtcbiAgICAgIHpvb21GYWN0b3IgPSBzY2FsZS5zY2FsZTtcbiAgICB9IGVsc2UgaWYgKHNjYWxlLndpZHRoKSB7XG4gICAgICB6b29tRmFjdG9yID0gc2NhbGUud2lkdGggLyBwZGZQYWdlLmdldFZpZXdwb3J0KHsgc2NhbGU6IDEgfSkud2lkdGg7XG4gICAgfSBlbHNlIGlmIChzY2FsZS5oZWlnaHQpIHtcbiAgICAgIHpvb21GYWN0b3IgPSBzY2FsZS5oZWlnaHQgLyBwZGZQYWdlLmdldFZpZXdwb3J0KHsgc2NhbGU6IDEgfSkuaGVpZ2h0O1xuICAgIH1cbiAgICBjb25zdCB2aWV3cG9ydCA9IHBkZlBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgc2NhbGU6IHpvb21GYWN0b3IsXG4gICAgfSk7XG4gICAgY29uc3QgeyBjdHgsIGNhbnZhcyB9ID0gdGhpcy5nZXRQYWdlRHJhd0NvbnRleHQodmlld3BvcnQud2lkdGgsIHZpZXdwb3J0LmhlaWdodCk7XG4gICAgY29uc3QgZHJhd1ZpZXdwb3J0ID0gdmlld3BvcnQuY2xvbmUoKTtcblxuICAgIGNvbnN0IHJlbmRlckNvbnRleHQgPSB7XG4gICAgICBjYW52YXNDb250ZXh0OiBjdHgsXG4gICAgICB2aWV3cG9ydDogZHJhd1ZpZXdwb3J0LFxuICAgIH07XG4gICAgY29uc3QgcmVuZGVyVGFzayA9IHBkZlBhZ2UucmVuZGVyKHJlbmRlckNvbnRleHQpO1xuXG4gICAgcmVuZGVyVGFzay5wcm9taXNlLnRoZW4oXG4gICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGRhdGFVUkwgPSBjYW52YXMudG9EYXRhVVJMKCk7XG4gICAgICAgIGNhbGxiYWNrKGRhdGFVUkwpO1xuICAgICAgfSxcbiAgICAgIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3JDYWxsYmFjaykge1xuICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UGFnZURyYXdDb250ZXh0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogRHJhd0NvbnRleHQge1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpIGFzIEhUTUxDYW52YXNFbGVtZW50O1xuICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHsgYWxwaGE6IGZhbHNlIH0pO1xuICAgIGlmICghY3R4KSB7XG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IHF1b3RlbWFya1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGRuJ3QgY3JlYXRlIHRoZSAyZCBjb250ZXh0XCIpO1xuICAgIH1cblxuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgY2FudmFzLnN0eWxlLndpZHRoID0gd2lkdGggKyAncHgnO1xuICAgIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xuXG4gICAgcmV0dXJuIHsgY3R4LCBjYW52YXMgfTtcbiAgfVxufVxuIl19