UNPKG

com.phloxui

Version:

PhloxUI Ng2+ Framework

231 lines (230 loc) 21.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Injectable } from '@angular/core'; import { ObservableManager } from './ObservableManager.service'; var /** @type {?} */ FOCUS_TOPIC_NAME = 'needfocus.focus'; var /** @type {?} */ LOST_FOCUS_TOPIC_NAME = 'needfocus.lostfocus'; var /** @type {?} */ FOCUS_CMD_TOPIC_NAME = 'needfocus.cmd.focus'; /** * <p style="text-indent: 2em;"> * A <code>ng</code> service class mainly handles the logic of UI component user's focus. For example, a notification pop up which will be disappered when * a user clicks on anywhere else out of its area --or, saying that losing its focus. A notification pop up component class must implement the [[INeedFocus]] * interface and register itself to <code>this</code> service via [[setFocusingComponent]] method to obtain the user's focus. Then, it must implement the * [[INeedFocus.onLostFocus]] method to hide itself when losing the focus. The [[NeedFocusService]] will mark a component losing the focus when the * [[resetFocusingComponent]] method is called or another [[INeedFocus]] component is getting focus instead. * </p> * * @author shiorin, tee4cute * @see [[INeedFocus]] */ var NeedFocusService = /** @class */ (function () { function NeedFocusService(obsvMgr) { var _this = this; this.observableMgr = obsvMgr; // Init Observer topics this.focusSubject = obsvMgr.createSubject(NeedFocusService.FOCUS_TOPIC_NAME); this.lostFocusSubject = obsvMgr.createSubject(NeedFocusService.LOST_FOCUS_TOPIC_NAME); // Subscribe to cmd topics obsvMgr.subscribe(NeedFocusService.FOCUS_CMD_TOPIC_NAME, function (component) { _this.setFocusingComponent(component); }); } /** * @param {?} component * @return {?} */ NeedFocusService.prototype.getDataParent = /** * @param {?} component * @return {?} */ function (component) { if (component === null || typeof component === 'undefined') { return null; } var /** @type {?} */ parent = null; // Try to resolve parent from getDataParent() method. if (typeof component['getDataParent'] === 'function') { parent = component.getDataParent(); } if (parent !== null && typeof parent !== 'undefined') { return parent; } // Try to resolve parent from field "dataParent". return component['dataParent']; }; /** * @param {?} component * @return {?} */ NeedFocusService.prototype.getDataAncestorChain = /** * @param {?} component * @return {?} */ function (component) { var /** @type {?} */ ancestors = []; if (component !== null && typeof component !== 'undefined') { ancestors.push(component); var /** @type {?} */ parent_1 = this.getDataParent(component); while (parent_1 !== null && typeof parent_1 !== 'undefined') { ancestors.push(parent_1); parent_1 = this.getDataParent(parent_1); } } return ancestors; }; /** * <p style="text-indent: 1em;"> * Get the component instance currently being focused. * </p> * @return {?} */ NeedFocusService.prototype.getFocusingComponent = /** * <p style="text-indent: 1em;"> * Get the component instance currently being focused. * </p> * @return {?} */ function () { return this.focusingComponent; }; /** * <p style="text-indent: 1em;"> * Set focusing component to the given <code><b>component</b></code>. If there is current focusing component, the [[NeedFocusService]] * will automatically call [[INeedFocus.onLostFocus]] callback method on the current focusing component before setting focus to a new * one. * </p> * * @param {?} component The component to set focus to. * @param {?=} event The source UI event --for example, click events, etc.-- causing this <code><b>component</b></code> to be focused. * @return {?} */ NeedFocusService.prototype.setFocusingComponent = /** * <p style="text-indent: 1em;"> * Set focusing component to the given <code><b>component</b></code>. If there is current focusing component, the [[NeedFocusService]] * will automatically call [[INeedFocus.onLostFocus]] callback method on the current focusing component before setting focus to a new * one. * </p> * * @param {?} component The component to set focus to. * @param {?=} event The source UI event --for example, click events, etc.-- causing this <code><b>component</b></code> to be focused. * @return {?} */ function (component, event) { if (this.focusingComponent === component) { // The component is currently focused. Do nothing. return; } var /** @type {?} */ losingFocusChain = this.getDataAncestorChain(this.focusingComponent); var /** @type {?} */ focusingChain = this.getDataAncestorChain(component); try { // Chain losing focus to ancestors. for (var losingFocusChain_1 = tslib_1.__values(losingFocusChain), losingFocusChain_1_1 = losingFocusChain_1.next(); !losingFocusChain_1_1.done; losingFocusChain_1_1 = losingFocusChain_1.next()) { var comp = losingFocusChain_1_1.value; if (focusingChain.indexOf(comp) >= 0) { // If current losing focus chain is found in focusing chain, // break it here (not to chain anymore). break; } if (typeof comp.onLostFocus === 'function') { // Call onLostFocus() method. comp.onLostFocus(event); // Publish event to observableMgr this.lostFocusSubject.next(comp); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (losingFocusChain_1_1 && !losingFocusChain_1_1.done && (_a = losingFocusChain_1.return)) _a.call(losingFocusChain_1); } finally { if (e_1) throw e_1.error; } } this.focusingComponent = component; try { // Chain focusing to ancestors. for (var focusingChain_1 = tslib_1.__values(focusingChain), focusingChain_1_1 = focusingChain_1.next(); !focusingChain_1_1.done; focusingChain_1_1 = focusingChain_1.next()) { var comp = focusingChain_1_1.value; if (losingFocusChain.indexOf(comp) >= 0) { // If current focusing chain is found in losing focus chain, // break it here (not to chain anymore). break; } if (typeof comp.onFocus === 'function') { // Call onFocus() method. comp.onFocus(event); // Publish event to observableMgr this.focusSubject.next(comp); } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (focusingChain_1_1 && !focusingChain_1_1.done && (_b = focusingChain_1.return)) _b.call(focusingChain_1); } finally { if (e_2) throw e_2.error; } } var e_1, _a, e_2, _b; }; /** * <p style="text-indent: 1em;"> * Reset the focusing component. This method will automatically call [[INeedFocus.onLostFocus]] callback method on the current focusing component. * If there is no current focusing component, this method will do nothing. * </p> * * @param {?=} event The source UI event --for example, click events, etc.-- causing the component's focus to be reset. * @return {?} */ NeedFocusService.prototype.resetFocusingComponent = /** * <p style="text-indent: 1em;"> * Reset the focusing component. This method will automatically call [[INeedFocus.onLostFocus]] callback method on the current focusing component. * If there is no current focusing component, this method will do nothing. * </p> * * @param {?=} event The source UI event --for example, click events, etc.-- causing the component's focus to be reset. * @return {?} */ function (event) { this.setFocusingComponent(null, event); }; NeedFocusService.FOCUS_TOPIC_NAME = FOCUS_TOPIC_NAME; NeedFocusService.LOST_FOCUS_TOPIC_NAME = LOST_FOCUS_TOPIC_NAME; NeedFocusService.FOCUS_CMD_TOPIC_NAME = FOCUS_CMD_TOPIC_NAME; NeedFocusService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ NeedFocusService.ctorParameters = function () { return [ { type: ObservableManager, }, ]; }; return NeedFocusService; }()); export { NeedFocusService }; function NeedFocusService_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ NeedFocusService.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ NeedFocusService.ctorParameters; /** @type {?} */ NeedFocusService.FOCUS_TOPIC_NAME; /** @type {?} */ NeedFocusService.LOST_FOCUS_TOPIC_NAME; /** @type {?} */ NeedFocusService.FOCUS_CMD_TOPIC_NAME; /** @type {?} */ NeedFocusService.prototype.observableMgr; /** @type {?} */ NeedFocusService.prototype.focusingComponent; /** @type {?} */ NeedFocusService.prototype.focusSubject; /** @type {?} */ NeedFocusService.prototype.lostFocusSubject; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTmVlZEZvY3VzU2VydmljZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vY29tLnBobG94dWkvIiwic291cmNlcyI6WyJsaWIvc2VydmljZS9OZWVkRm9jdXNTZXJ2aWNlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSTNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRWhFLHFCQUFNLGdCQUFnQixHQUFXLGlCQUFpQixDQUFDO0FBQ25ELHFCQUFNLHFCQUFxQixHQUFXLHFCQUFxQixDQUFDO0FBQzVELHFCQUFNLG9CQUFvQixHQUFXLHFCQUFxQixDQUFDOzs7Ozs7Ozs7Ozs7OztJQTBCekQsMEJBQVksT0FBMEI7UUFBdEMsaUJBV0M7UUFWQyxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQzs7UUFHN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMscUJBQXFCLENBQUMsQ0FBQzs7UUFHdEYsT0FBTyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxvQkFBb0IsRUFBRSxVQUFDLFNBQWM7WUFDdEUsS0FBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3RDLENBQUMsQ0FBQztLQUNKOzs7OztJQUVPLHdDQUFhOzs7O2NBQUMsU0FBYztRQUNsQyxFQUFFLENBQUMsQ0FBQyxTQUFTLEtBQUssSUFBSSxJQUFJLE9BQU8sU0FBUyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDM0QsTUFBTSxDQUFDLElBQUksQ0FBQztTQUNiO1FBRUQscUJBQUksTUFBTSxHQUFRLElBQUksQ0FBQzs7UUFHdkIsRUFBRSxDQUFDLENB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Ozs7Ozs7Ozs7Ozs7SUFXSSxpREFBc0I7Ozs7Ozs7OztjQUFDLEtBQVc7UUFDdkMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQzs7d0NBcklTLGdCQUFnQjs2Q0FDWCxxQkFBcUI7NENBQ3RCLG9CQUFvQjs7Z0JBTDNFLFVBQVU7Ozs7Z0JBbEJGLGlCQUFpQjs7MkJBSjFCOztTQXVCYSxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcy9TdWJqZWN0JztcblxuaW1wb3J0IHsgSU5lZWRGb2N1cyB9IGZyb20gJy4uL2NvbXBvbmVudC9JTmVlZEZvY3VzJztcbmltcG9ydCB7IE9ic2VydmFibGVNYW5hZ2VyIH0gZnJvbSAnLi9PYnNlcnZhYmxlTWFuYWdlci5zZXJ2aWNlJztcblxuY29uc3QgRk9DVVNfVE9QSUNfTkFNRTogc3RyaW5nID0gJ25lZWRmb2N1cy5mb2N1cyc7XG5jb25zdCBMT1NUX0ZPQ1VTX1RPUElDX05BTUU6IHN0cmluZyA9ICduZWVkZm9jdXMubG9zdGZvY3VzJztcbmNvbnN0IEZPQ1VTX0NNRF9UT1BJQ19OQU1FOiBzdHJpbmcgPSAnbmVlZGZvY3VzLmNtZC5mb2N1cyc7XG5cbi8qKlxuICogPHAgc3R5bGU9XCJ0ZXh0LWluZGVudDogMmVtO1wiPlxuICogQSA8Y29kZT5uZzwvY29kZT4gc2VydmljZSBjbGFzcyBtYWlubHkgaGFuZGxlcyB0aGUgbG9naWMgb2YgVUkgY29tcG9uZW50IHVzZXIncyBmb2N1cy4gRm9yIGV4YW1wbGUsIGEgbm90aWZpY2F0aW9uIHBvcCB1cCB3aGljaCB3aWxsIGJlIGRpc2FwcGVyZWQgd2hlblxuICogYSB1c2VyIGNsaWNrcyBvbiBhbnl3aGVyZSBlbHNlIG91dCBvZiBpdHMgYXJlYSAtLW9yLCBzYXlpbmcgdGhhdCBsb3NpbmcgaXRzIGZvY3VzLiBBIG5vdGlmaWNhdGlvbiBwb3AgdXAgY29tcG9uZW50IGNsYXNzIG11c3QgaW1wbGVtZW50IHRoZSBbW0lOZWVkRm9jdXNdXVxuICogaW50ZXJmYWNlIGFuZCByZWdpc3RlciBpdHNlbGYgdG8gPGNvZGU+dGhpczwvY29kZT4gc2VydmljZSB2aWEgW1tzZXRGb2N1c2luZ0NvbXBvbmVudF1dIG1ldGhvZCB0byBvYnRhaW4gdGhlIHVzZXIncyBmb2N1cy4gVGhlbiwgaXQgbXVzdCBpbXBsZW1lbnQgdGhlXG4gKiBbW0lOZWVkRm9jdXMub25Mb3N0Rm9jdXNdXSBtZXRob2QgdG8gaGlkZSBpdHNlbGYgd2hlbiBsb3NpbmcgdGhlIGZvY3VzLiBUaGUgW1tOZWVkRm9jdXNTZXJ2aWNlXV0gd2lsbCBtYXJrIGEgY29tcG9uZW50IGxvc2luZyB0aGUgZm9jdXMgd2hlbiB0aGVcbiAqIFtbcmVzZXRGb2N1c2luZ0NvbXBvbmVudF1dIG1ldGhvZCBpcyBjYWxsZWQgb3IgYW5vdGhlciBbW0lOZWVkRm9jdXNdXSBjb21wb25lbnQgaXMgZ2V0dGluZyBmb2N1cyBpbnN0ZWFkLlxuICogPC9wPlxuICpcbiAqIEBhdXRob3Igc2hpb3JpbiwgdGVlNGN1dGVcbiAqIEBzZWUgW1tJTmVlZEZvY3VzXV1cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5lZWRGb2N1c1NlcnZpY2Uge1xuXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRk9DVVNfVE9QSUNfTkFNRTogc3RyaW5nID0gRk9DVVNfVE9QSUNfTkFNRTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBMT1NUX0ZPQ1VTX1RPUElDX05BTUU6IHN0cmluZyA9IExPU1RfRk9DVVNfVE9QSUNfTkFNRTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBGT0NVU19DTURfVE9QSUNfTkFNRTogc3RyaW5nID0gRk9DVVNfQ01EX1RPUElDX05BTUU7XG5cbiAgcHJpdmF0ZSBvYnNlcnZhYmxlTWdyOiBPYnNlcnZhYmxlTWFuYWdlcjtcbiAgcHJpdmF0ZSBmb2N1c2luZ0NvbXBvbmVudDogSU5lZWRGb2N1cztcbiAgcHJpdmF0ZSBmb2N1c1N1YmplY3Q6IFN1YmplY3Q8YW55PjtcbiAgcHJpdmF0ZSBsb3N0Rm9jdXNTdWJqZWN0OiBTdWJqZWN0PGFueT47XG5cbiAgY29uc3RydWN0b3Iob2Jzdk1ncjogT2JzZXJ2YWJsZU1hbmFnZXIpIHtcbiAgICB0aGlzLm9ic2VydmFibGVNZ3IgPSBvYnN2TWdyO1xuXG4gICAgLy8gSW5pdCBPYnNlcnZlciB0b3BpY3NcbiAgICB0aGlzLmZvY3VzU3ViamVjdCA9IG9ic3ZNZ3IuY3JlYXRlU3ViamVjdChOZWVkRm9jdXNTZXJ2aWNlLkZPQ1VTX1RPUElDX05BTUUpO1xuICAgIHRoaXMubG9zdEZvY3VzU3ViamVjdCA9IG9ic3ZNZ3IuY3JlYXRlU3ViamVjdChOZWVkRm9jdXNTZXJ2aWNlLkxPU1RfRk9DVVNfVE9QSUNfTkFNRSk7XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gY21kIHRvcGljc1xuICAgIG9ic3ZNZ3Iuc3Vic2NyaWJlKE5lZWRGb2N1c1NlcnZpY2UuRk9DVVNfQ01EX1RPUElDX05BTUUsIChjb21wb25lbnQ6IGFueSkgPT4ge1xuICAgICAgdGhpcy5zZXRGb2N1c2luZ0NvbXBvbmVudChjb21wb25lbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREYXRhUGFyZW50KGNvbXBvbmVudDogYW55KTogYW55IHtcbiAgICBpZiAoY29tcG9uZW50ID09PSBudWxsIHx8IHR5cGVvZiBjb21wb25lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgcGFyZW50OiBhbnkgPSBudWxsO1xuXG4gICAgLy8gVHJ5IHRvIHJlc29sdmUgcGFyZW50IGZyb20gZ2V0RGF0YVBhcmVudCgpIG1ldGhvZC5cbiAgICBpZiAodHlwZW9mIGNvbXBvbmVudFsnZ2V0RGF0YVBhcmVudCddID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwYXJlbnQgPSBjb21wb25lbnQuZ2V0RGF0YVBhcmVudCgpO1xuICAgIH1cblxuICAgIGlmIChwYXJlbnQgIT09IG51bGwgJiYgdHlwZW9mIHBhcmVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHJlc29sdmUgcGFyZW50IGZyb20gZmllbGQgXCJkYXRhUGFyZW50XCIuXG4gICAgcmV0dXJuIGNvbXBvbmVudFsnZGF0YVBhcmVudCddO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREYXRhQW5jZXN0b3JDaGFpbihjb21wb25lbnQ6IGFueSk6IGFueVtdIHtcbiAgICBsZXQgYW5jZXN0b3JzOiBhbnlbXSA9IFtdO1xuXG4gICAgaWYgKGNvbXBvbmVudCAhPT0gbnVsbCAmJiB0eXBlb2YgY29tcG9uZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgYW5jZXN0b3JzLnB1c2goY29tcG9uZW50KTtcblxuICAgICAgbGV0IHBhcmVudDogYW55ID0gdGhpcy5nZXREYXRhUGFyZW50KGNvbXBvbmVudCk7XG4gICAgICB3aGlsZSAocGFyZW50ICE9PSBudWxsICYmIHR5cGVvZiBwYXJlbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGFuY2VzdG9ycy5wdXNoKHBhcmVudCk7XG5cbiAgICAgICAgcGFyZW50ID0gdGhpcy5nZXREYXRhUGFyZW50KHBhcmVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGFuY2VzdG9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAxZW07XCI+XG4gICAqIEdldCB0aGUgY29tcG9uZW50IGluc3RhbmNlIGN1cnJlbnRseSBiZWluZyBmb2N1c2VkLlxuICAgKiA8L3A+XG4gICAqL1xuICBwdWJsaWMgZ2V0Rm9jdXNpbmdDb21wb25lbnQoKTogSU5lZWRGb2N1cyB7XG4gICAgcmV0dXJuIHRoaXMuZm9jdXNpbmdDb21wb25lbnQ7XG4gIH1cblxuICAvKipcbiAgICogPHAgc3R5bGU9XCJ0ZXh0LWluZGVudDogMWVtO1wiPlxuICAgKiBTZXQgZm9jdXNpbmcgY29tcG9uZW50IHRvIHRoZSBnaXZlbiA8Y29kZT48Yj5jb21wb25lbnQ8L2I+PC9jb2RlPi4gSWYgdGhlcmUgaXMgY3VycmVudCBmb2N1c2luZyBjb21wb25lbnQsIHRoZSBbW05lZWRGb2N1c1NlcnZpY2VdXVxuICAgKiB3aWxsIGF1dG9tYXRpY2FsbHkgY2FsbCBbW0lOZWVkRm9jdXMub25Mb3N0Rm9jdXNdXSBjYWxsYmFjayBtZXRob2Qgb24gdGhlIGN1cnJlbnQgZm9jdXNpbmcgY29tcG9uZW50IGJlZm9yZSBzZXR0aW5nIGZvY3VzIHRvIGEgbmV3XG4gICAqIG9uZS5cbiAgICogPC9wPlxuICAgKlxuICAgKiBAcGFyYW0gY29tcG9uZW50IFRoZSBjb21wb25lbnQgdG8gc2V0IGZvY3VzIHRvLlxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIHNvdXJjZSBVSSBldmVudCAtLWZvciBleGFtcGxlLCBjbGljayBldmVudHMsIGV0Yy4tLSBjYXVzaW5nIHRoaXMgPGNvZGU+PGI+Y29tcG9uZW50PC9iPjwvY29kZT4gdG8gYmUgZm9jdXNlZC5cbiAgICovXG4gIHB1YmxpYyBzZXRGb2N1c2luZ0NvbXBvbmVudChjb21wb25lbnQ6IElOZWVkRm9jdXMsIGV2ZW50PzogYW55KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZm9jdXNpbmdDb21wb25lbnQgPT09IGNvbXBvbmVudCkge1xuICAgICAgLy8gVGhlIGNvbXBvbmVudCBpcyBjdXJyZW50bHkgZm9jdXNlZC4gRG8gbm90aGluZy5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgbG9zaW5nRm9jdXNDaGFpbjogYW55W10gPSB0aGlzLmdldERhdGFBbmNlc3RvckNoYWluKHRoaXMuZm9jdXNpbmdDb21wb25lbnQpO1xuICAgIGxldCBmb2N1c2luZ0NoYWluOiBhbnlbXSA9IHRoaXMuZ2V0RGF0YUFuY2VzdG9yQ2hhaW4oY29tcG9uZW50KTtcblxuICAgIC8vIENoYWluIGxvc2luZyBmb2N1cyB0byBhbmNlc3RvcnMuXG4gICAgZm9yIChsZXQgY29tcCBvZiBsb3NpbmdGb2N1c0NoYWluKSB7XG4gICAgICBpZiAoZm9jdXNpbmdDaGFpbi5pbmRleE9mKGNvbXApID49IDApIHtcbiAgICAgICAgLy8gSWYgY3VycmVudCBsb3NpbmcgZm9jdXMgY2hhaW4gaXMgZm91bmQgaW4gZm9jdXNpbmcgY2hhaW4sXG4gICAgICAgIC8vIGJyZWFrIGl0IGhlcmUgKG5vdCB0byBjaGFpbiBhbnltb3JlKS5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgY29tcC5vbkxvc3RGb2N1cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBDYWxsIG9uTG9zdEZvY3VzKCkgbWV0aG9kLlxuICAgICAgICBjb21wLm9uTG9zdEZvY3VzKGV2ZW50KTtcblxuICAgICAgICAvLyBQdWJsaXNoIGV2ZW50IHRvIG9ic2VydmFibGVNZ3JcbiAgICAgICAgdGhpcy5sb3N0Rm9jdXNTdWJqZWN0Lm5leHQoY29tcCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5mb2N1c2luZ0NvbXBvbmVudCA9IGNvbXBvbmVudDtcblxuICAgIC8vIENoYWluIGZvY3VzaW5nIHRvIGFuY2VzdG9ycy5cbiAgICBmb3IgKGxldCBjb21wIG9mIGZvY3VzaW5nQ2hhaW4pIHtcbiAgICAgIGlmIChsb3NpbmdGb2N1c0NoYWluLmluZGV4T2YoY29tcCkgPj0gMCkge1xuICAgICAgICAvLyBJZiBjdXJyZW50IGZvY3VzaW5nIGNoYWluIGlzIGZvdW5kIGluIGxvc2luZyBmb2N1cyBjaGFpbixcbiAgICAgICAgLy8gYnJlYWsgaXQgaGVyZSAobm90IHRvIGNoYWluIGFueW1vcmUpLlxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBjb21wLm9uRm9jdXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gQ2FsbCBvbkZvY3VzKCkgbWV0aG9kLlxuICAgICAgICBjb21wLm9uRm9jdXMoZXZlbnQpO1xuXG4gICAgICAgIC8vIFB1Ymxpc2ggZXZlbnQgdG8gb2JzZXJ2YWJsZU1nclxuICAgICAgICB0aGlzLmZvY3VzU3ViamVjdC5uZXh0KGNvbXApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAxZW07XCI+XG4gICAqIFJlc2V0IHRoZSBmb2N1c2luZyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIHdpbGwgYXV0b21hdGljYWxseSBjYWxsIFtbSU5lZWRGb2N1cy5vbkxvc3RGb2N1c11dIGNhbGxiYWNrIG1ldGhvZCBvbiB0aGUgY3VycmVudCBmb2N1c2luZyBjb21wb25lbnQuXG4gICAqIElmIHRoZXJlIGlzIG5vIGN1cnJlbnQgZm9jdXNpbmcgY29tcG9uZW50LCB0aGlzIG1ldGhvZCB3aWxsIGRvIG5vdGhpbmcuXG4gICAqIDwvcD5cbiAgICpcbiAgICogQHBhcmFtIGV2ZW50IFRoZSBzb3VyY2UgVUkgZXZlbnQgLS1mb3IgZXhhbXBsZSwgY2xpY2sgZXZlbnRzLCBldGMuLS0gY2F1c2luZyB0aGUgY29tcG9uZW50J3MgZm9jdXMgdG8gYmUgcmVzZXQuXG4gICAqL1xuICBwdWJsaWMgcmVzZXRGb2N1c2luZ0NvbXBvbmVudChldmVudD86IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc2V0Rm9jdXNpbmdDb21wb25lbnQobnVsbCwgZXZlbnQpO1xuICB9XG5cbn1cbiJdfQ==