UNPKG

com.phloxui

Version:

PhloxUI Ng2+ Framework

551 lines (550 loc) 56.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import { Component, ViewChild } from '@angular/core'; import { DialogModel, ConfirmDialogModel } from './model/models'; import { PhloxAppInfoService } from '../service/PhloxAppInfoService.service'; import { NeedFocusService } from '../service/NeedFocusService.service'; import { ConfirmDialog } from './dialog.internal/ConfirmDialog.component'; import { MessageDialog } from './dialog.internal/MessageDialog.component'; import { ComponentDialog } from './dialog.internal/ComponentDialog.component'; var /** @type {?} */ TYPE_NAME = "phx-dialog"; var /** @type {?} */ CONFIRM_DIALOG = 'confirm'; var /** @type {?} */ MESSAGE_DIALOG = 'message'; var /** @type {?} */ COMPONENT_DIALOG = 'component'; /** * <p style="text-indent: 2em;"> * A <code>singleton</code> UI component controlling <code>application</code> pop-up dialog logic. This dialog is a <code>modal</code> dialog, saying that, * when it is displayed, all user's UI actions will be blocked and the user will be forced to focus on this dialog. When the user completes the interaction * with this dialog, for example, clicking on "OK" button, this dialog will be hidden and the user can resume normal UI operations. Normally, you <b>should * NOT</b> directly access this component instance but you could control it via <b>[[DialogService]]</b>. * </p> * <p style="text-indent: 2em;"> * Please note that there is a dialog <code>display queue</code> operating behind the scenes. This <code>display queue</code> is a <code>FIFO</code> queue * keeping all dialog models ([[DialogModel]]) --which are automatically generated and kept in the queue when <code><i>show...Dialog</i></code> methods are called-- * but those dialog models cannot be displayed suddenly. For example, if there already is a dialog being displayed currently, but, there is also someone else * calling <code><i>show...Dialog</i></code> method simultaneously, the dialog model generated from the later <code><i>show...Dialog</i></code> method will * not be showed suddenly. Nevertheless, it'll be showed immediately when the first dialog is closed. For this mechanism, the dialog model can be firstly kept * in the queue, then, it will be showed and removed from the queue when its preceding dialog is closed. * </p> * <p style="text-indent: 2em;"> * If you want to implement your own <b>custom dialog</b>, you should do it using <code>component dialog</code> rather than building it all up from scratches. The only thing * which you need to do is just implementing the component being displayed inside the dialog body. All other mechanisms, such as dialog <code>display queue</code> * listed above, should be left to be handled by the framework or by this class. For more information about building custom dialog, please see [[showComponentDialog]]. * </p> * * @author shiorin, tee4cute * @see [[DialogService]] */ var PhloxDialog = /** @class */ (function () { function PhloxDialog(phloxAppService, needFocusService) { var _this = this; this.show = false; this.dialogQueue = []; this.dialogResolverQueue = []; this.needFocusService = needFocusService; if (phloxAppService != null) { phloxAppService.getAppInfo().then(function (result) { _this.phloxAppInfo = result; }); } if (window.history && window.history.pushState) { $(window).on('popstate', function (event) { _this.hideDialog(); }); } } Object.defineProperty(PhloxDialog.prototype, "show", { get: /** * @return {?} */ function () { return this._show; }, set: /** * @param {?} show * @return {?} */ function (show) { this._show = show; if (this._show) { // if true add class to body $("body").addClass("phx-dialog-fixed"); } else { // if false remove class from body $("body").removeClass("phx-dialog-fixed"); } }, enumerable: true, configurable: true }); /** * @return {?} */ PhloxDialog.prototype.showNextDialog = /** * @return {?} */ function () { this.currentModel = null; if (this.dialogQueue.length > 0) { this.currentModel = this.dialogQueue[0]; this.dialogQueue.splice(0, 1); if (this.dialogResolverQueue.length > 0) { this.currentResolver = this.dialogResolverQueue[0]; this.dialogResolverQueue.splice(0, 1); } if (this.currentModel !== null && typeof this.currentModel !== 'undefined') { this.showDialog(); return true; } else { this.currentResolver = null; this.hideDialog(); return false; } } return false; }; /** * @param {?} key * @return {?} */ PhloxDialog.prototype.getI18NMessage = /** * @param {?} key * @return {?} */ function (key) { if (this.phloxAppInfo != null && this.phloxAppInfo.i18n != null) { if (this.phloxAppInfo.i18n[key] !== null && typeof this.phloxAppInfo.i18n[key] !== 'undefined') { return this.phloxAppInfo.i18n[key]; } } return key; }; /** * @param {?} model * @param {?} resolve * @param {?} reject * @return {?} */ PhloxDialog.prototype.getResolverWrapper = /** * @param {?} model * @param {?} resolve * @param {?} reject * @return {?} */ function (model, resolve, reject) { var /** @type {?} */ result = { model: model, resolve: resolve, reject: reject }; return result; }; /** * @return {?} */ PhloxDialog.prototype.getDialogWidth = /** * @return {?} */ function () { if (this.currentModel !== null && typeof this.currentModel !== 'undefined') { if (this.currentModel.width !== null && typeof this.currentModel.width === 'string') { return this.currentModel.width; } } return ""; }; /** * @return {?} */ PhloxDialog.prototype.getDialogHeight = /** * @return {?} */ function () { if (this.currentModel !== null && typeof this.currentModel !== 'undefined') { if (this.currentModel.height !== null && typeof this.currentModel.height === 'string') { return this.currentModel.height; } } return ""; }; /** * @param {?} dialogType * @return {?} */ PhloxDialog.prototype.getDialogResult = /** * @param {?} dialogType * @return {?} */ function (dialogType) { if (dialogType === null || typeof dialogType === 'undefined') { return null; } if (dialogType === CONFIRM_DIALOG) { if (this.confirmDialog !== null && typeof this.confirmDialog !== 'undefined') { return this.confirmDialog.getDialogResult(); } } else if (dialogType === MESSAGE_DIALOG) { if (this.messageDialog !== null && typeof this.messageDialog !== 'undefined') { return this.messageDialog.getDialogResult(); } } else if (dialogType === COMPONENT_DIALOG) { if (this.componentDialog !== null && typeof this.componentDialog !== 'undefined') { return this.componentDialog.getDialogResult(); } } return null; }; /** * @return {?} */ PhloxDialog.prototype._showDialog = /** * @return {?} */ function () { this.show = true; }; /** * <p style="text-indent: 1em;"> * Show current dialog described by the <code><b>[[currentModel]]</b></code>. This usually be the last model generated by * the last <code><i>show...Dialog</i></code> method call. * </p> * @return {?} */ PhloxDialog.prototype.showDialog = /** * <p style="text-indent: 1em;"> * Show current dialog described by the <code><b>[[currentModel]]</b></code>. This usually be the last model generated by * the last <code><i>show...Dialog</i></code> method call. * </p> * @return {?} */ function () { if (this.currentModel !== null && typeof this.currentModel !== 'undefined') { var /** @type {?} */ dialogType = this.currentModel.type; if (typeof dialogType === 'string') { if (dialogType === CONFIRM_DIALOG) { if (this.confirmDialog !== null && typeof this.confirmDialog !== 'undefined') { this.confirmDialog.showDialog(); this._showDialog(); } } else if (dialogType === MESSAGE_DIALOG) { if (this.messageDialog !== null && typeof this.messageDialog !== 'undefined') { this.messageDialog.showDialog(); this._showDialog(); } } else if (dialogType === COMPONENT_DIALOG) { if (this.componentDialog !== null && typeof this.componentDialog !== 'undefined') { this.componentDialog.showDialog(); this._showDialog(); } } } } }; /** * <p style="text-indent: 1em;"> * Hide the current showing dialog and show the next dialog in the queue (if any). * </p> * @return {?} */ PhloxDialog.prototype.hideDialog = /** * <p style="text-indent: 1em;"> * Hide the current showing dialog and show the next dialog in the queue (if any). * </p> * @return {?} */ function () { // hide all dialog if (this.confirmDialog !== null && typeof this.confirmDialog !== 'undefined') { this.confirmDialog.hideDialog(); } if (this.messageDialog !== null && typeof this.messageDialog !== 'undefined') { this.messageDialog.hideDialog(); } if (this.componentDialog !== null && typeof this.componentDialog !== 'undefined') { this.componentDialog.hideDialog(); } // resolve if (this.currentResolver !== null && typeof this.currentResolver !== 'undefined') { if (this.currentModel !== null && typeof this.currentModel !== 'undefined') { this.currentResolver.resolve(this.getDialogResult(this.currentModel.type)); } else { this.currentResolver.resolve(null); } } this.currentModel = null; this.currentResolver = null; if (this.showNextDialog()) { return; } this.show = false; }; /** * <p style="text-indent: 1em;"> * Display a confirmation dialog on the screen. * </p> * * @see [[ConfirmDialog]] * @param {?} title The dialog title text. * @param {?} message The dialog message which will be displayed in the dialog body. * @param {?} showCancelBtn To display the <code>CANCEL</code> button or not. By default, the confirmation dialog will contain only * <code>YES</code> and <code>NO</code> button. * @param {?=} width The css <code>"width"</code> style value governing dialog width e.g. <code>100px</code>, <code>50pt</code>. * @param {?=} height The css <code>"height"</code> style value governing dialog height e.g. <code>100px</code>, <code>50pt</code>. * * @return {?} The <code>promise</code> which will be resolved when this dialog is closed. The resolving result will be the value * returned from [[ConfirmDialog.getDialogResult]] method. * */ PhloxDialog.prototype.showConfirmDialog = /** * <p style="text-indent: 1em;"> * Display a confirmation dialog on the screen. * </p> * * @see [[ConfirmDialog]] * @param {?} title The dialog title text. * @param {?} message The dialog message which will be displayed in the dialog body. * @param {?} showCancelBtn To display the <code>CANCEL</code> button or not. By default, the confirmation dialog will contain only * <code>YES</code> and <code>NO</code> button. * @param {?=} width The css <code>"width"</code> style value governing dialog width e.g. <code>100px</code>, <code>50pt</code>. * @param {?=} height The css <code>"height"</code> style value governing dialog height e.g. <code>100px</code>, <code>50pt</code>. * * @return {?} The <code>promise</code> which will be resolved when this dialog is closed. The resolving result will be the value * returned from [[ConfirmDialog.getDialogResult]] method. * */ function (title, message, showCancelBtn, width, height) { var _this = this; return new Promise(function (resolve, reject) { var /** @type {?} */ confirmDialog = new ConfirmDialogModel(title, message, CONFIRM_DIALOG, showCancelBtn, width, height); var /** @type {?} */ resolver = _this.getResolverWrapper(confirmDialog, resolve, reject); _this.currentResolver = resolver; if (_this.currentModel == null) { _this.currentModel = confirmDialog; if (_this.confirmDialog != null) { _this.confirmDialog.showDialog(); _this._showDialog(); } } else { // stack in // stack in _this.dialogQueue.push(confirmDialog); _this.dialogResolverQueue.push(resolver); } }); }; /** * <p style="text-indent: 1em;"> * Display a message dialog on the screen. * </p> * * @see [[MessageDialog]] * @param {?} title The dialog title text. * @param {?} message The dialog message which will be displayed in the dialog body. * @param {?=} width The css <code>"width"</code> style value governing dialog width e.g. <code>100px</code>, <code>50pt</code>. * @param {?=} height The css <code>"height"</code> style value governing dialog height e.g. <code>100px</code>, <code>50pt</code>. * * @return {?} The <code>promise</code> which will be resolved when this dialog is closed. The resolving result will be the value * returned from [[MessageDialog.getDialogResult]] method (which always returns <code>true</code>). * */ PhloxDialog.prototype.showMessageDialog = /** * <p style="text-indent: 1em;"> * Display a message dialog on the screen. * </p> * * @see [[MessageDialog]] * @param {?} title The dialog title text. * @param {?} message The dialog message which will be displayed in the dialog body. * @param {?=} width The css <code>"width"</code> style value governing dialog width e.g. <code>100px</code>, <code>50pt</code>. * @param {?=} height The css <code>"height"</code> style value governing dialog height e.g. <code>100px</code>, <code>50pt</code>. * * @return {?} The <code>promise</code> which will be resolved when this dialog is closed. The resolving result will be the value * returned from [[MessageDialog.getDialogResult]] method (which always returns <code>true</code>). * */ function (title, message, width, height) { var _this = this; return new Promise(function (resolve, reject) { var /** @type {?} */ messageDialog = new DialogModel(title, message, MESSAGE_DIALOG, width, height); var /** @type {?} */ resolver = _this.getResolverWrapper(messageDialog, resolve, reject); _this.currentResolver = resolver; if (_this.currentModel == null) { _this.currentModel = messageDialog; if (_this.messageDialog != null) { _this.messageDialog.showDialog(); _this._showDialog(); } } else { // stack in // stack in _this.dialogQueue.push(messageDialog); _this.dialogResolverQueue.push(resolver); } }); }; /** * <p style="text-indent: 1em;"> * Display a component dialog on the screen. A component dialog is a dialog allowing you to display your own custom dialog by specifying * a <code>component type</code> being displayed as its body. That <code>component type</code> must be a class which is an instance of * [[IDialogController]]. * </p> * * @see [[ComponentDialog]] * @param {?} componentDialogModel A dialog model being displayed. * * @return {?} The <code>promise</code> which will be resolved when this dialog is closed. The resolving result will be the value returned * from [[IDialogController.getDialogResult]] method. * */ PhloxDialog.prototype.showComponentDialog = /** * <p style="text-indent: 1em;"> * Display a component dialog on the screen. A component dialog is a dialog allowing you to display your own custom dialog by specifying * a <code>component type</code> being displayed as its body. That <code>component type</code> must be a class which is an instance of * [[IDialogController]]. * </p> * * @see [[ComponentDialog]] * @param {?} componentDialogModel A dialog model being displayed. * * @return {?} The <code>promise</code> which will be resolved when this dialog is closed. The resolving result will be the value returned * from [[IDialogController.getDialogResult]] method. * */ function (componentDialogModel) { var _this = this; if (componentDialogModel === null || typeof componentDialogModel === 'undefined') { return Promise.resolve(null); } return new Promise(function (resolve, reject) { var /** @type {?} */ componentDialog = componentDialogModel; componentDialog.type = COMPONENT_DIALOG; var /** @type {?} */ resolver = _this.getResolverWrapper(componentDialog, resolve, reject); _this.currentResolver = resolver; if (componentDialogModel.dialogStyleClass !== undefined && componentDialogModel.dialogStyleClass !== null) { _this.dialogClass = componentDialogModel.dialogStyleClass; } else { _this.dialogClass = []; } if (_this.currentModel == null) { _this.currentModel = componentDialog; if (_this.componentDialog != null) { _this.componentDialog.showDialog(); _this._showDialog(); } } else { // stack in // stack in _this.dialogQueue.push(componentDialog); _this.dialogResolverQueue.push(resolver); } }); }; /** * @return {?} */ PhloxDialog.prototype.isShow = /** * @return {?} */ function () { return this.show; }; /** * @return {?} */ PhloxDialog.prototype.getCurrentModel = /** * @return {?} */ function () { return this.currentModel; }; /** * @return {?} */ PhloxDialog.prototype.getDialogClass = /** * @return {?} */ function () { return this.dialogClass; }; PhloxDialog.TYPE_NAME = TYPE_NAME; PhloxDialog.CONFIRM_DIALOG = CONFIRM_DIALOG; PhloxDialog.MESSAGE_DIALOG = MESSAGE_DIALOG; PhloxDialog.COMPONENT_DIALOG = COMPONENT_DIALOG; PhloxDialog.decorators = [ { type: Component, args: [{ moduleId: module.id, selector: TYPE_NAME, template: "<div class=\"phx-dialog-background\" [class.show]=\"isShow()\">\n\t<div class=\"phx-dialog\" [ngClass]=\"getDialogClass()\" [class.show]=\"isShow()\" [style.width]=\"getDialogWidth()\" [style.height]=\"getDialogHeight()\">\n\t\t<phx-confirm-dialog #confirmdialog [model]=\"getCurrentModel()\" [dialog]=\"this\"></phx-confirm-dialog>\n\t\t<phx-message-dialog #messagedialog [model]=\"getCurrentModel()\" [dialog]=\"this\"></phx-message-dialog>\n\t\t<phx-component-dialog #componentdialog [model]=\"getCurrentModel()\" [dialog]=\"this\"></phx-component-dialog>\n\t</div>\n</div>\n" },] }, ]; /** @nocollapse */ PhloxDialog.ctorParameters = function () { return [ { type: PhloxAppInfoService, }, { type: NeedFocusService, }, ]; }; PhloxDialog.propDecorators = { "confirmDialog": [{ type: ViewChild, args: ['confirmdialog',] },], "messageDialog": [{ type: ViewChild, args: ['messagedialog',] },], "componentDialog": [{ type: ViewChild, args: ['componentdialog',] },], }; return PhloxDialog; }()); export { PhloxDialog }; function PhloxDialog_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ PhloxDialog.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ PhloxDialog.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ PhloxDialog.propDecorators; /** @type {?} */ PhloxDialog.TYPE_NAME; /** @type {?} */ PhloxDialog.CONFIRM_DIALOG; /** @type {?} */ PhloxDialog.MESSAGE_DIALOG; /** @type {?} */ PhloxDialog.COMPONENT_DIALOG; /** @type {?} */ PhloxDialog.prototype.dialogQueue; /** @type {?} */ PhloxDialog.prototype.dialogClass; /** @type {?} */ PhloxDialog.prototype.dialogResolverQueue; /** @type {?} */ PhloxDialog.prototype.confirmDialog; /** @type {?} */ PhloxDialog.prototype.messageDialog; /** @type {?} */ PhloxDialog.prototype.componentDialog; /** @type {?} */ PhloxDialog.prototype.currentModel; /** @type {?} */ PhloxDialog.prototype.currentResolver; /** @type {?} */ PhloxDialog.prototype.phloxAppInfo; /** @type {?} */ PhloxDialog.prototype.needFocusService; /** @type {?} */ PhloxDialog.prototype._show; } export { YES, NO, CANCEL, ConfirmDialog } from './dialog.internal/ConfirmDialog.component'; export { MessageDialog } from './dialog.internal/MessageDialog.component'; export { ComponentDialog } from './dialog.internal/ComponentDialog.component'; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGhsb3hEaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vY29tLnBobG94dWkvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50L1BobG94RGlhbG9nLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFFLFdBQVcsRUFBc0Msa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN2RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUU5RSxxQkFBTSxTQUFTLEdBQVcsWUFBWSxDQUFDO0FBRXZDLHFCQUFNLGNBQWMsR0FBVyxTQUFTLENBQUM7QUFDekMscUJBQU0sY0FBYyxHQUFXLFNBQVMsQ0FBQztBQUN6QyxxQkFBTSxnQkFBZ0IsR0FBVyxXQUFXLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBOEUzQyxxQkFBWSxlQUFvQyxFQUFFLGdCQUFrQztRQUFwRixpQkFpQkM7UUFoQkMsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDbEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7UUFFekMsRUFBRSxDQUFDLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDNUIsZUFBZSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFDLE1BQU07Z0JBQ3ZDLEtBQUksQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDO2FBQzVCLENBQUMsQ0FBQztTQUNKO1FBRUQsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsVUFBQyxLQUFLO2dCQUM3QixLQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7YUFDbkIsQ0FBQyxDQUFBO1NBQ0g7S0FDRjswQkFsQ1csNkJBQUk7Ozs7O1lBY2QsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Ozs7OztrQkFkSCxJQUFhO1lBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBR2xCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDOztnQkFFZixDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7YUFDeEM7WUFBQyxJQUFJLENBQUMsQ0FBQzs7Z0JBRU4sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2FBQzNDOzs7Ozs7OztJQTBCSyxvQ0FBYzs7OztRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFOUIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDdkM7WUFFRCxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDM0UsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDO2FBQ2I7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNsQixNQUFNLENBQUMsS0FBSyxDQUFDO2FBQ2Q7U0FDRjtRQUVELE1BQU0sQ0FBQyxLQUFLLENBQUM7Ozs7OztJQUdQLG9DQUFjOzs7O2NBQUMsR0FBVztRQUNoQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQy9GLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNwQztTQUNGO1FBQ0QsTUFBTSxDQUFDLEdBQUcsQ0FBQzs7Ozs7Ozs7SUFHTCx3Q0FBa0I7Ozs7OztjQUFDLEtBQVUsRUFBRSxPQUFZLEVBQUUsTUFBVztRQUM5RCxxQkFBSSxNQUFNLEdBQUc7WUFDWCxLQUFLLEVBQUUsS0FBSztZQUNaLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxNQUFNO1NBQ2YsQ0FBQztRQUVGLE1BQU0sQ0FBQyxNQUFNLENBQUM7Ozs7O0lBR1Qsb0NBQWM7Ozs7UUFDbkIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsWUFBWSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDM0UsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDcEYsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDO2FBQ2hDO1NBQ0Y7UUFFRCxNQUFNLENBQUMsRUFBRSxDQUFDOzs7OztJQUdMLHFDQUFlOzs7O1FBQ3BCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEtBQUssSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzNFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RGLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQzthQUNqQztTQUNGO1FBRUQsTUFBTSxDQUFDLEVBQUUsQ0FBQzs7Ozs7O0lBR0oscUNBQWU7Ozs7Y0FBQyxVQUFrQjtRQUN4QyxFQUFFLENBQUMsQ0FBQyxVQUFVLEtBQUssSUFBSSxJQUFJLE9BQU8sVUFBVSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDN0QsTUFBTSxDQUFDLElBQUksQ0FBQztTQUNiO1FBRUQsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDbEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQzdFLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQzdDO1NBQ0Y7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDekMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQzdFLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQzdDO1NBQ0Y7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUMzQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxlQUFlLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDakYsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDL0M7U0FDRjtRQUVELE1BQU0sQ0FBQyxJQUFJLENBQUM7Ozs7O0lBR04saUNBQVc7Ozs7UUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Ozs7Ozs7OztJQVNaLGdDQUFVOzs7Ozs7OztRQUNmLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEtBQUssSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzNFLHFCQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztZQUN4QyxFQUFFLENBQUMsQ0FBQyxPQUFPLFVBQVUsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxFQUFFLENBQUMsQ0FBQyxVQUFVLEtBQUssY0FBYyxDQUFDLENBQUMsQ0FBQztvQkFDbEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7d0JBQzdFLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQ2hDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztxQkFDcEI7aUJBQ0Y7Z0JBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFVBQVUsS0FBSyxjQUFjLENBQUMsQ0FBQyxDQUFDO29CQUN6QyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxhQUFhLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQzt3QkFDN0UsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFDaEMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO3FCQUNwQjtpQkFDRjtnQkFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLGdCQUFnQixDQUFDLENBQUMsQ0FBQztvQkFDM0MsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsZUFBZSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7d0JBQ2pGLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQ2xDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztxQkFDcEI7aUJBQ0Y7YUFDRjtTQUNGOzs7Ozs7OztJQVFJLGdDQUFVOzs7Ozs7OztRQUVmLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLGFBQWEsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzdFLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDakM7UUFDRCxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxhQUFhLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZQUM3RSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDO1NBQ2pDO1FBQ0QsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsZUFBZSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDakYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNuQzs7UUFHRCxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxlQUFlLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNqRixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDM0UsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDNUU7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNwQztTQUNGO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDNUIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMxQixNQUFNLENBQUM7U0FDUjtRQUNELElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBb0JiLHVDQUFpQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Y0FBQyxLQUFhLEVBQUUsT0FBZSxFQUFFLGFBQXNCLEVBQUUsS0FBYyxFQUFFLE1BQWU7O1FBQzlHLE1BQU0sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLHFCQUFJLGFBQWEsR0FBRyxJQUFJLGtCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDekcscUJBQUksUUFBUSxHQUFHLEtBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZFLEtBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDO1lBRWhDLEVBQUUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDOUIsS0FBSSxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUM7Z0JBRWxDLEVBQUUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDL0IsS0FBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDaEMsS0FBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2lCQUNwQjthQUNGO1lBQUMsSUFBSSxDQUFDLENBQUM7O2dCQUVOLEFBREEsV0FBVztnQkFDWCxLQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDckMsS0FBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUN6QztTQUNGLENBQUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFrQkUsdUNBQWlCOzs7Ozs7Ozs7Ozs7Ozs7Y0FBQyxLQUFhLEVBQUUsT0FBZSxFQUFFLEtBQWMsRUFBRSxNQUFlOztRQUN0RixNQUFNLENBQUMsSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUNqQyxxQkFBSSxhQUFhLEdBQUcsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRW5GLHFCQUFJLFFBQVEsR0FBRyxLQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RSxLQUFJLENBQUMsZUFBZSxHQUFHLFFBQVEsQ0FBQztZQUVoQyxFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLEtBQUksQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDO2dCQUVsQyxFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQy9CLEtBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ2hDLEtBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztpQkFDcEI7YUFDRjtZQUFDLElBQUksQ0FBQyxDQUFDOztnQkFFTixBQURBLFdBQVc7Z0JBQ1gsS0FBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ3JDLEtBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDekM7U0FFRixDQUFDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7SUFpQkUseUNBQW1COzs7Ozs7Ozs7Ozs7OztjQUFDLG9CQUEwQzs7UUFDbkUsRUFBRSxDQUFDLENBQUMsb0JBQW9CLEtBQUssSUFBSSxJQUFJLE9BQU8sb0JBQW9CLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNqRixNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM5QjtRQUVELE1BQU0sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ2pDLHFCQUFJLGVBQWUsR0FBRyxvQkFBb0IsQ0FBQztZQUMzQyxlQUFlLENBQUMsSUFBSSxHQUFHLGdCQUFnQixDQUFDO1lBQ3hDLHFCQUFJLFFBQVEsR0FBRyxLQUFJLENBQUMsa0JBQWtCLENBQUMsZUFBZSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN6RSxLQUFJLENBQUMsZUFBZSxHQUFHLFFBQVEsQ0FBQztZQUNoQyxFQUFFLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLElBQUksb0JBQW9CLENBQUMsZ0JBQWdCLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDMUcsS0FBSSxDQUFDLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQyxnQkFBZ0IsQ0FBQzthQUMxRDtZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNOLEtBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO2FBQ3ZCO1lBQ0QsRUFBRSxDQUFDLENBQUMsS0FBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUM5QixLQUFJLENBQUMsWUFBWSxHQUFHLGVBQWUsQ0FBQztnQkFFcEMsRUFBRSxDQUFDLENBQUMsS0FBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO29CQUNqQyxLQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxDQUFDO29CQUNsQyxLQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7aUJBQ3BCO2FBQ0Y7WUFBQyxJQUFJLENBQUMsQ0FBQzs7Z0JBRU4sQUFEQSxXQUFXO2dCQUNYLEtBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUN2QyxLQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3pDO1NBRUYsQ0FBQyxDQUFDOzs7OztJQUdFLDRCQUFNOzs7O1FBQ1gsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Ozs7O0lBR1oscUNBQWU7Ozs7UUFDcEIsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7Ozs7O0lBR3BCLG9DQUFjOzs7O1FBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDOzs0QkFwVmlCLFNBQVM7aUNBRUosY0FBYztpQ0FDZCxjQUFjO21DQUNaLGdCQUFnQjs7Z0JBbEJuRSxTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFO29CQUNuQixRQUFRLEVBQUUsU0FBUztvQkFDbkIsUUFBUSxFQUFFLG9rQkFPWDtpQkFDQTs7OztnQkEvQ1EsbUJBQW1CO2dCQUNuQixnQkFBZ0I7OztrQ0EwRHRCLFNBQVMsU0FBQyxlQUFlO2tDQUV6QixTQUFTLFNBQUMsZUFBZTtvQ0FFekIsU0FBUyxTQUFDLGlCQUFpQjs7c0JBakU5Qjs7U0FrRGEsV0FBVzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMFZ4QiwrQ0FBYywyQ0FBMkMsQ0FBQztBQUMxRCw4QkFBYywyQ0FBMkMsQ0FBQztBQUMxRCxnQ0FBYyw2Q0FBNkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEaWFsb2dNb2RlbCwgUGhsb3hBcHBJbmZvLCBDb21wb25lbnREaWFsb2dNb2RlbCwgQ29uZmlybURpYWxvZ01vZGVsIH0gZnJvbSAnLi9tb2RlbC9tb2RlbHMnO1xuaW1wb3J0IHsgUGhsb3hBcHBJbmZvU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2UvUGhsb3hBcHBJbmZvU2VydmljZS5zZXJ2aWNlJztcbmltcG9ydCB7IE5lZWRGb2N1c1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlL05lZWRGb2N1c1NlcnZpY2Uuc2VydmljZSc7XG5pbXBvcnQgeyBDb25maXJtRGlhbG9nIH0gZnJvbSAnLi9kaWFsb2cuaW50ZXJuYWwvQ29uZmlybURpYWxvZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgTWVzc2FnZURpYWxvZyB9IGZyb20gJy4vZGlhbG9nLmludGVybmFsL01lc3NhZ2VEaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7IENvbXBvbmVudERpYWxvZyB9IGZyb20gJy4vZGlhbG9nLmludGVybmFsL0NvbXBvbmVudERpYWxvZy5jb21wb25lbnQnO1xuXG5jb25zdCBUWVBFX05BTUU6IHN0cmluZyA9IFwicGh4LWRpYWxvZ1wiO1xuXG5jb25zdCBDT05GSVJNX0RJQUxPRzogc3RyaW5nID0gJ2NvbmZpcm0nO1xuY29uc3QgTUVTU0FHRV9ESUFMT0c6IHN0cmluZyA9ICdtZXNzYWdlJztcbmNvbnN0IENPTVBPTkVOVF9ESUFMT0c6IHN0cmluZyA9ICdjb21wb25lbnQnO1xuXG4vKipcbiAqIDxwIHN0eWxlPVwidGV4dC1pbmRlbnQ6IDJlbTtcIj5cbiAqIEEgPGNvZGU+c2luZ2xldG9uPC9jb2RlPiBVSSBjb21wb25lbnQgY29udHJvbGxpbmcgPGNvZGU+YXBwbGljYXRpb248L2NvZGU+IHBvcC11cCBkaWFsb2cgbG9naWMuIFRoaXMgZGlhbG9nIGlzIGEgPGNvZGU+bW9kYWw8L2NvZGU+IGRpYWxvZywgc2F5aW5nIHRoYXQsXG4gKiB3aGVuIGl0IGlzIGRpc3BsYXllZCwgYWxsIHVzZXIncyBVSSBhY3Rpb25zIHdpbGwgYmUgYmxvY2tlZCBhbmQgdGhlIHVzZXIgd2lsbCBiZSBmb3JjZWQgdG8gZm9jdXMgb24gdGhpcyBkaWFsb2cuIFdoZW4gdGhlIHVzZXIgY29tcGxldGVzIHRoZSBpbnRlcmFjdGlvblxuICogd2l0aCB0aGlzIGRpYWxvZywgZm9yIGV4YW1wbGUsIGNsaWNraW5nIG9uIFwiT0tcIiBidXR0b24sIHRoaXMgZGlhbG9nIHdpbGwgYmUgaGlkZGVuIGFuZCB0aGUgdXNlciBjYW4gcmVzdW1lIG5vcm1hbCBVSSBvcGVyYXRpb25zLiBOb3JtYWxseSwgeW91IDxiPnNob3VsZFxuICogTk9UPC9iPiBkaXJlY3RseSBhY2Nlc3MgdGhpcyBjb21wb25lbnQgaW5zdGFuY2UgYnV0IHlvdSBjb3VsZCBjb250cm9sIGl0IHZpYSA8Yj5bW0RpYWxvZ1NlcnZpY2VdXTwvYj4uXG4gKiA8L3A+XG4gKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAyZW07XCI+XG4gKiBQbGVhc2Ugbm90ZSB0aGF0IHRoZXJlIGlzIGEgZGlhbG9nIDxjb2RlPmRpc3BsYXkgcXVldWU8L2NvZGU+IG9wZXJhdGluZyBiZWhpbmQgdGhlIHNjZW5lcy4gVGhpcyA8Y29kZT5kaXNwbGF5IHF1ZXVlPC9jb2RlPiBpcyBhIDxjb2RlPkZJRk88L2NvZGU+IHF1ZXVlXG4gKiBrZWVwaW5nIGFsbCBkaWFsb2cgbW9kZWxzIChbW0RpYWxvZ01vZGVsXV0pIC0td2hpY2ggYXJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGFuZCBrZXB0IGluIHRoZSBxdWV1ZSB3aGVuIDxjb2RlPjxpPnNob3cuLi5EaWFsb2c8L2k+PC9jb2RlPiBtZXRob2RzIGFyZSBjYWxsZWQtLVxuICogYnV0IHRob3NlIGRpYWxvZyBtb2RlbHMgY2Fubm90IGJlIGRpc3BsYXllZCBzdWRkZW5seS4gRm9yIGV4YW1wbGUsIGlmIHRoZXJlIGFscmVhZHkgaXMgYSBkaWFsb2cgYmVpbmcgZGlzcGxheWVkIGN1cnJlbnRseSwgYnV0LCB0aGVyZSBpcyBhbHNvIHNvbWVvbmUgZWxzZVxuICogY2FsbGluZyA8Y29kZT48aT5zaG93Li4uRGlhbG9nPC9pPjwvY29kZT4gbWV0aG9kIHNpbXVsdGFuZW91c2x5LCB0aGUgZGlhbG9nIG1vZGVsIGdlbmVyYXRlZCBmcm9tIHRoZSBsYXRlciA8Y29kZT48aT5zaG93Li4uRGlhbG9nPC9pPjwvY29kZT4gbWV0aG9kIHdpbGxcbiAqIG5vdCBiZSBzaG93ZWQgc3VkZGVubHkuIE5ldmVydGhlbGVzcywgaXQnbGwgYmUgc2hvd2VkIGltbWVkaWF0ZWx5IHdoZW4gdGhlIGZpcnN0IGRpYWxvZyBpcyBjbG9zZWQuIEZvciB0aGlzIG1lY2hhbmlzbSwgdGhlIGRpYWxvZyBtb2RlbCBjYW4gYmUgZmlyc3RseSBrZXB0XG4gKiBpbiB0aGUgcXVldWUsIHRoZW4sIGl0IHdpbGwgYmUgc2hvd2VkIGFuZCByZW1vdmVkIGZyb20gdGhlIHF1ZXVlIHdoZW4gaXRzIHByZWNlZGluZyBkaWFsb2cgaXMgY2xvc2VkLlxuICogPC9wPlxuICogPHAgc3R5bGU9XCJ0ZXh0LWluZGVudDogMmVtO1wiPlxuICogSWYgeW91IHdhbnQgdG8gaW1wbGVtZW50IHlvdXIgb3duIDxiPmN1c3RvbSBkaWFsb2c8L2I+LCB5b3Ugc2hvdWxkIGRvIGl0IHVzaW5nIDxjb2RlPmNvbXBvbmVudCBkaWFsb2c8L2NvZGU+IHJhdGhlciB0aGFuIGJ1aWxkaW5nIGl0IGFsbCB1cCBmcm9tIHNjcmF0Y2hlcy4gVGhlIG9ubHkgdGhpbmdcbiAqIHdoaWNoIHlvdSBuZWVkIHRvIGRvIGlzIGp1c3QgaW1wbGVtZW50aW5nIHRoZSBjb21wb25lbnQgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgZGlhbG9nIGJvZHkuIEFsbCBvdGhlciBtZWNoYW5pc21zLCBzdWNoIGFzIGRpYWxvZyA8Y29kZT5kaXNwbGF5IHF1ZXVlPC9jb2RlPlxuICogbGlzdGVkIGFib3ZlLCBzaG91bGQgYmUgbGVmdCB0byBiZSBoYW5kbGVkIGJ5IHRoZSBmcmFtZXdvcmsgb3IgYnkgdGhpcyBjbGFzcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgYnVpbGRpbmcgY3VzdG9tIGRpYWxvZywgcGxlYXNlIHNlZSBbW3Nob3dDb21wb25lbnREaWFsb2ddXS5cbiAqIDwvcD5cbiAqXG4gKiBAYXV0aG9yIHNoaW9yaW4sIHRlZTRjdXRlXG4gKiBAc2VlIFtbRGlhbG9nU2VydmljZV1dXG4gKi9cbkBDb21wb25lbnQoe1xuICBtb2R1bGVJZDogbW9kdWxlLmlkLFxuICBzZWxlY3RvcjogVFlQRV9OQU1FLFxuICB0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJwaHgtZGlhbG9nLWJhY2tncm91bmRcIiBbY2xhc3Muc2hvd109XCJpc1Nob3coKVwiPlxuXHQ8ZGl2IGNsYXNzPVwicGh4LWRpYWxvZ1wiIFtuZ0NsYXNzXT1cImdldERpYWxvZ0NsYXNzKClcIiBbY2xhc3Muc2hvd109XCJpc1Nob3coKVwiIFtzdHlsZS53aWR0aF09XCJnZXREaWFsb2dXaWR0aCgpXCIgW3N0eWxlLmhlaWdodF09XCJnZXREaWFsb2dIZWlnaHQoKVwiPlxuXHRcdDxwaHgtY29uZmlybS1kaWFsb2cgI2NvbmZpcm1kaWFsb2cgW21vZGVsXT1cImdldEN1cnJlbnRNb2RlbCgpXCIgW2RpYWxvZ109XCJ0aGlzXCI+PC9waHgtY29uZmlybS1kaWFsb2c+XG5cdFx0PHBoeC1tZXNzYWdlLWRpYWxvZyAjbWVzc2FnZWRpYWxvZyBbbW9kZWxdPVwiZ2V0Q3VycmVudE1vZGVsKClcIiBbZGlhbG9nXT1cInRoaXNcIj48L3BoeC1tZXNzYWdlLWRpYWxvZz5cblx0XHQ8cGh4LWNvbXBvbmVudC1kaWFsb2cgI2NvbXBvbmVudGRpYWxvZyBbbW9kZWxdPVwiZ2V0Q3VycmVudE1vZGVsKClcIiBbZGlhbG9nXT1cInRoaXNcIj48L3BoeC1jb21wb25lbnQtZGlhbG9nPlxuXHQ8L2Rpdj5cbjwvZGl2PlxuYFxufSlcbmV4cG9ydCBjbGFzcyBQaGxveERpYWxvZyB7XG5cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBUWVBFX05BTUU6IHN0cmluZyA9IFRZUEVfTkFNRTtcblxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENPTkZJUk1fRElBTE9HOiBzdHJpbmcgPSBDT05GSVJNX0RJQUxPRztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBNRVNTQUdFX0RJQUxPRzogc3RyaW5nID0gTUVTU0FHRV9ESUFMT0c7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ09NUE9ORU5UX0RJQUxPRzogc3RyaW5nID0gQ09NUE9ORU5UX0RJQUxPRztcblxuICBwcml2YXRlIGRpYWxvZ1F1ZXVlOiBEaWFsb2dNb2RlbFtdO1xuICBwcml2YXRlIGRpYWxvZ0NsYXNzOiBzdHJpbmdbXTtcbiAgcHJpdmF0ZSBkaWFsb2dSZXNvbHZlclF1ZXVlOiBhbnlbXTtcbiAgQFZpZXdDaGlsZCgnY29uZmlybWRpYWxvZycpXG4gIHByaXZhdGUgY29uZmlybURpYWxvZzogQ29uZmlybURpYWxvZztcbiAgQFZpZXdDaGlsZCgnbWVzc2FnZWRpYWxvZycpXG4gIHByaXZhdGUgbWVzc2FnZURpYWxvZzogTWVzc2FnZURpYWxvZztcbiAgQFZpZXdDaGlsZCgnY29tcG9uZW50ZGlhbG9nJylcbiAgcHJpdmF0ZSBjb21wb25lbnREaWFsb2c6IENvbXBvbmVudERpYWxvZztcbiAgcHJpdmF0ZSBjdXJyZW50TW9kZWw6IERpYWxvZ01vZGVsO1xuICBwcml2YXRlIGN1cnJlbnRSZXNvbHZlcjogYW55O1xuICBwcml2YXRlIHBobG94QXBwSW5mbzogUGhsb3hBcHBJbmZvO1xuICBwcml2YXRlIG5lZWRGb2N1c1NlcnZpY2U6IE5lZWRGb2N1c1NlcnZpY2U7XG4gIHByaXZhdGUgX3Nob3c6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBzZXQgc2hvdyhzaG93OiBib29sZWFuKSB7XG4gICAgdGhpcy5fc2hvdyA9IHNob3c7XG5cblxuICAgIGlmICh0aGlzLl9zaG93KSB7XG4gICAgICAvLyBpZiB0cnVlIGFkZCBjbGFzcyB0byBib2R5XG4gICAgICAkKFwiYm9keVwiKS5hZGRDbGFzcyhcInBoeC1kaWFsb2ctZml4ZWRcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIGZhbHNlIHJlbW92ZSBjbGFzcyBmcm9tIGJvZHlcbiAgICAgICQoXCJib2R5XCIpLnJlbW92ZUNsYXNzKFwicGh4LWRpYWxvZy1maXhlZFwiKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCBzaG93KCkge1xuICAgIHJldHVybiB0aGlzLl9zaG93O1xuICB9XG5cbiAgY29uc3RydWN0b3IocGhsb3hBcHBTZXJ2aWNlOiBQaGxveEFwcEluZm9TZXJ2aWNlLCBuZWVkRm9jdXNTZXJ2aWNlOiBOZWVkRm9jdXNTZXJ2aWNlKSB7XG4gICAgdGhpcy5zaG93ID0gZmFsc2U7XG4gICAgdGhpcy5kaWFsb2dRdWV1ZSA9IFtdO1xuICAgIHRoaXMuZGlhbG9nUmVzb2x2ZXJRdWV1ZSA9IFtdO1xuICAgIHRoaXMubmVlZEZvY3VzU2VydmljZSA9IG5lZWRGb2N1c1NlcnZpY2U7XG5cbiAgICBpZiAocGhsb3hBcHBTZXJ2aWNlICE9IG51bGwpIHtcbiAgICAgIHBobG94QXBwU2VydmljZS5nZXRBcHBJbmZvKCkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIHRoaXMucGhsb3hBcHBJbmZvID0gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHdpbmRvdy5oaXN0b3J5ICYmIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSkge1xuICAgICAgJCh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLmhpZGVEaWFsb2coKTtcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzaG93TmV4dERpYWxvZygpOiBib29sZWFuIHtcbiAgICB0aGlzLmN1cnJlbnRNb2RlbCA9IG51bGw7XG4gICAgaWYgKHRoaXMuZGlhbG9nUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5jdXJyZW50TW9kZWwgPSB0aGlzLmRpYWxvZ1F1ZXVlWzBdO1xuICAgICAgdGhpcy5kaWFsb2dRdWV1ZS5zcGxpY2UoMCwgMSk7XG5cbiAgICAgIGlmICh0aGlzLmRpYWxvZ1Jlc29sdmVyUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRSZXNvbHZlciA9IHRoaXMuZGlhbG9nUmVzb2x2ZXJRdWV1ZVswXTtcbiAgICAgICAgdGhpcy5kaWFsb2dSZXNvbHZlclF1ZXVlLnNwbGljZSgwLCAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuY3VycmVudE1vZGVsICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLmN1cnJlbnRNb2RlbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy5zaG93RGlhbG9nKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UmVzb2x2ZXIgPSBudWxsO1xuICAgICAgICB0aGlzLmhpZGVEaWFsb2coKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0STE4Tk1lc3NhZ2Uoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnBobG94QXBwSW5mbyAhPSBudWxsICYmIHRoaXMucGhsb3hBcHBJbmZvLmkxOG4gIT0gbnVsbCkge1xuICAgICAgaWYgKHRoaXMucGhsb3hBcHBJbmZvLmkxOG5ba2V5XSAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5waGxveEFwcEluZm8uaTE4bltrZXldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gdGhpcy5waGxveEFwcEluZm8uaTE4bltrZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRSZXNvbHZlcldyYXBwZXIobW9kZWw6IGFueSwgcmVzb2x2ZTogYW55LCByZWplY3Q6IGFueSk6IGFueSB7XG4gICAgbGV0IHJlc3VsdCA9IHtcbiAgICAgIG1vZGVsOiBtb2RlbCxcbiAgICAgIHJlc29sdmU6IHJlc29sdmUsXG4gICAgICByZWplY3Q6IHJlamVjdFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHVibGljIGdldERpYWxvZ1dpZHRoKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuY3VycmVudE1vZGVsICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLmN1cnJlbnRNb2RlbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRNb2RlbC53aWR0aCAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jdXJyZW50TW9kZWwud2lkdGggPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRNb2RlbC53aWR0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuXG4gIHB1YmxpYyBnZXREaWFsb2dIZWlnaHQoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5jdXJyZW50TW9kZWwgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuY3VycmVudE1vZGVsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHRoaXMuY3VycmVudE1vZGVsLmhlaWdodCAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jdXJyZW50TW9kZWwuaGVpZ2h0ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50TW9kZWwuaGVpZ2h0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBcIlwiO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREaWFsb2dSZXN1bHQoZGlhbG9nVHlwZTogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoZGlhbG9nVHlwZSA9PT0gbnVsbCB8fCB0eXBlb2YgZGlhbG9nVHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChkaWFsb2dUeXBlID09PSBDT05GSVJNX0RJQUxPRykge1xuICAgICAgaWYgKHRoaXMuY29uZmlybURpYWxvZyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jb25maXJtRGlhbG9nICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maXJtRGlhbG9nLmdldERpYWxvZ1Jlc3VsdCgpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZGlhbG9nVHlwZSA9PT0gTUVTU0FHRV9ESUFMT0cpIHtcbiAgICAgIGlmICh0aGlzLm1lc3NhZ2VEaWFsb2cgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMubWVzc2FnZURpYWxvZyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZURpYWxvZy5nZXREaWFsb2dSZXN1bHQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGRpYWxvZ1R5cGUgPT09IENPTVBPTkVOVF9ESUFMT0cpIHtcbiAgICAgIGlmICh0aGlzLmNvbXBvbmVudERpYWxvZyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jb21wb25lbnREaWFsb2cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudERpYWxvZy5nZXREaWFsb2dSZXN1bHQoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX3Nob3dEaWFsb2coKTogdm9pZCB7XG4gICAgdGhpcy5zaG93ID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAxZW07XCI+XG4gICAqIFNob3cgY3VycmVudCBkaWFsb2cgZGVzY3JpYmVkIGJ5IHRoZSA8Y29kZT48Yj5bW2N1cnJlbnRNb2RlbF1dPC9iPjwvY29kZT4uIFRoaXMgdXN1YWxseSBiZSB0aGUgbGFzdCBtb2RlbCBnZW5lcmF0ZWQgYnlcbiAgICogdGhlIGxhc3QgPGNvZGU+PGk+c2hvdy4uLkRpYWxvZzwvaT48L2NvZGU+IG1ldGhvZCBjYWxsLlxuICAgKiA8L3A+XG4gICAqL1xuICBwdWJsaWMgc2hvd0RpYWxvZygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50TW9kZWwgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuY3VycmVudE1vZGVsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgbGV0IGRpYWxvZ1R5cGUgPSB0aGlzLmN1cnJlbnRNb2RlbC50eXBlO1xuICAgICAgaWYgKHR5cGVvZiBkaWFsb2dUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoZGlhbG9nVHlwZSA9PT0gQ09ORklSTV9ESUFMT0cpIHtcbiAgICAgICAgICBpZiAodGhpcy5jb25maXJtRGlhbG9nICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLmNvbmZpcm1EaWFsb2cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpcm1EaWFsb2cuc2hvd0RpYWxvZygpO1xuICAgICAgICAgICAgdGhpcy5fc2hvd0RpYWxvZygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChkaWFsb2dUeXBlID09PSBNRVNTQUdFX0RJQUxPRykge1xuICAgICAgICAgIGlmICh0aGlzLm1lc3NhZ2VEaWFsb2cgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMubWVzc2FnZURpYWxvZyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZURpYWxvZy5zaG93RGlhbG9nKCk7XG4gICAgICAgICAgICB0aGlzLl9zaG93RGlhbG9nKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGRpYWxvZ1R5cGUgPT09IENPTVBPTkVOVF9ESUFMT0cpIHtcbiAgICAgICAgICBpZiAodGhpcy5jb21wb25lbnREaWFsb2cgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuY29tcG9uZW50RGlhbG9nICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnREaWFsb2cuc2hvd0RpYWxvZygpO1xuICAgICAgICAgICAgdGhpcy5fc2hvd0RpYWxvZygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAxZW07XCI+XG4gICAqIEhpZGUgdGhlIGN1cnJlbnQgc2hvd2luZyBkaWFsb2cgYW5kIHNob3cgdGhlIG5leHQgZGlhbG9nIGluIHRoZSBxdWV1ZSAoaWYgYW55KS5cbiAgICogPC9wPlxuICAgKi9cbiAgcHVibGljIGhpZGVEaWFsb2coKTogdm9pZCB7XG4gICAgLy8gaGlkZSBhbGwgZGlhbG9nXG4gICAgaWYgKHRoaXMuY29uZmlybURpYWxvZyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jb25maXJtRGlhbG9nICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5jb25maXJtRGlhbG9nLmhpZGVEaWFsb2coKTtcbiAgICB9XG4gICAgaWYgKHRoaXMubWVzc2FnZURpYWxvZyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5tZXNzYWdlRGlhbG9nICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5tZXNzYWdlRGlhbG9nLmhpZGVEaWFsb2coKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29tcG9uZW50RGlhbG9nICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLmNvbXBvbmVudERpYWxvZyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuY29tcG9uZW50RGlhbG9nLmhpZGVEaWFsb2coKTtcbiAgICB9XG5cbiAgICAvLyByZXNvbHZlXG4gICAgaWYgKHRoaXMuY3VycmVudFJlc29sdmVyICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLmN1cnJlbnRSZXNvbHZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRNb2RlbCAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jdXJyZW50TW9kZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFJlc29sdmVyLnJlc29sdmUodGhpcy5nZXREaWFsb2dSZXN1bHQodGhpcy5jdXJyZW50TW9kZWwudHlwZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UmVzb2x2ZXIucmVzb2x2ZShudWxsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnRNb2RlbCA9IG51bGw7XG4gICAgdGhpcy5jdXJyZW50UmVzb2x2ZXIgPSBudWxsO1xuICAgIGlmICh0aGlzLnNob3dOZXh0RGlhbG9nKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zaG93ID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogPHAgc3R5bGU9XCJ0ZXh0LWluZGVudDogMWVtO1wiPlxuICAgKiBEaXNwbGF5IGEgY29uZmlybWF0aW9uIGRpYWxvZyBvbiB0aGUgc2NyZWVuLlxuICAgKiA8L3A+XG4gICAqXG4gICAqIEBwYXJhbSB0aXRsZSBUaGUgZGlhbG9nIHRpdGxlIHRleHQuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkaWFsb2cgbWVzc2FnZSB3aGljaCB3aWxsIGJlIGRpc3BsYXllZCBpbiB0aGUgZGlhbG9nIGJvZHkuXG4gICAqIEBwYXJhbSBzaG93Q2FuY2VsQnRuIFRvIGRpc3BsYXkgdGhlIDxjb2RlPkNBTkNFTDwvY29kZT4gYnV0dG9uIG9yIG5vdC4gQnkgZGVmYXVsdCwgdGhlIGNvbmZpcm1hdGlvbiBkaWFsb2cgd2lsbCBjb250YWluIG9ubHlcbiAgICogPGNvZGU+WUVTPC9jb2RlPiBhbmQgPGNvZGU+Tk88L2NvZGU+IGJ1dHRvbi5cbiAgICogQHBhcmFtIHdpZHRoIFRoZSBjc3MgPGNvZGU+XCJ3aWR0aFwiPC9jb2RlPiBzdHlsZSB2YWx1ZSBnb3Zlcm5pbmcgZGlhbG9nIHdpZHRoIGUuZy4gPGNvZGU+MTAwcHg8L2NvZGU+LCA8Y29kZT41MHB0PC9jb2RlPi5cbiAgICogQHBhcmFtIGhlaWdodCBUaGUgY3NzIDxjb2RlPlwiaGVpZ2h0XCI8L2NvZGU+IHN0e