UNPKG

ngx-pluto

Version:
407 lines 31.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { Injectable, NgZone, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { Subject } from 'rxjs'; import { normalizePassiveListenerOptions } from './utils/passive-listeners'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; /** * Event options that can be used to bind an active, capturing event. * @type {?} */ var activeCapturingEventOptions = normalizePassiveListenerOptions({ passive: false, capture: true }); /** * @ignore * Service that keeps track of all the drag item and drop container * instances, and manages global event listeners on the `document`. * \@docs-private * @template I, C */ // Note: this class is generic, rather than referencing CdkDrag and CdkDropList directly, in order // to avoid circular imports. If we were to reference them here, importing the registry into the // classes that are registering themselves will introduce a circular import. var DragDropRegistry = /** @class */ (function () { function DragDropRegistry(_ngZone, _document) { var _this = this; this._ngZone = _ngZone; /** * Registered drop container instances. */ this._dropInstances = new Set(); /** * Registered drag item instances. */ this._dragInstances = new Set(); /** * Drag item instances that are currently being dragged. */ this._activeDragInstances = new Set(); /** * Keeps track of the event listeners that we've bound to the `document`. */ this._globalListeners = new Map(); /** * Emits the `touchmove` or `mousemove` events that are dispatched * while the user is dragging a drag item instance. */ this.pointerMove = new Subject(); /** * Emits the `touchend` or `mouseup` events that are dispatched * while the user is dragging a drag item instance. */ this.pointerUp = new Subject(); /** * Event listener that will prevent the default browser action while the user is dragging. * @param event Event whose default action should be prevented. */ this._preventDefaultWhileDragging = (/** * @param {?} event * @return {?} */ function (event) { if (_this._activeDragInstances.size) { event.preventDefault(); } }); this._document = _document; } /** Adds a drop container to the registry. */ /** * Adds a drop container to the registry. * @param {?} drop * @return {?} */ DragDropRegistry.prototype.registerDropContainer = /** * Adds a drop container to the registry. * @param {?} drop * @return {?} */ function (drop) { if (!this._dropInstances.has(drop)) { if (this.getDropContainer(drop.id)) { throw Error("Drop instance with id \"" + drop.id + "\" has already been registered."); } this._dropInstances.add(drop); } }; /** Adds a drag item instance to the registry. */ /** * Adds a drag item instance to the registry. * @param {?} drag * @return {?} */ DragDropRegistry.prototype.registerDragItem = /** * Adds a drag item instance to the registry. * @param {?} drag * @return {?} */ function (drag) { var _this = this; this._dragInstances.add(drag); // The `touchmove` event gets bound once, ahead of time, because WebKit // won't preventDefault on a dynamically-added `touchmove` listener. // See https://bugs.webkit.org/show_bug.cgi?id=184250. if (this._dragInstances.size === 1) { this._ngZone.runOutsideAngular((/** * @return {?} */ function () { // The event handler has to be explicitly active, // because newer browsers make it passive by default. _this._document.addEventListener('touchmove', _this._preventDefaultWhileDragging, activeCapturingEventOptions); })); } }; /** Removes a drop container from the registry. */ /** * Removes a drop container from the registry. * @param {?} drop * @return {?} */ DragDropRegistry.prototype.removeDropContainer = /** * Removes a drop container from the registry. * @param {?} drop * @return {?} */ function (drop) { this._dropInstances.delete(drop); }; /** Removes a drag item instance from the registry. */ /** * Removes a drag item instance from the registry. * @param {?} drag * @return {?} */ DragDropRegistry.prototype.removeDragItem = /** * Removes a drag item instance from the registry. * @param {?} drag * @return {?} */ function (drag) { this._dragInstances.delete(drag); this.stopDragging(drag); if (this._dragInstances.size === 0) { this._document.removeEventListener('touchmove', this._preventDefaultWhileDragging, activeCapturingEventOptions); } }; /** * Starts the dragging sequence for a drag instance. * @param drag Drag instance which is being dragged. * @param event Event that initiated the dragging. */ /** * Starts the dragging sequence for a drag instance. * @param {?} drag Drag instance which is being dragged. * @param {?} event Event that initiated the dragging. * @return {?} */ DragDropRegistry.prototype.startDragging = /** * Starts the dragging sequence for a drag instance. * @param {?} drag Drag instance which is being dragged. * @param {?} event Event that initiated the dragging. * @return {?} */ function (drag, event) { var _this = this; this._activeDragInstances.add(drag); if (this._activeDragInstances.size === 1) { /** @type {?} */ var isTouchEvent = event.type.startsWith('touch'); /** @type {?} */ var moveEvent = isTouchEvent ? 'touchmove' : 'mousemove'; /** @type {?} */ var upEvent = isTouchEvent ? 'touchend' : 'mouseup'; // We explicitly bind __active__ listeners here, because newer browsers will default to // passive ones for `mousemove` and `touchmove`. The events need to be active, because we // use `preventDefault` to prevent the page from scrolling while the user is dragging. this._globalListeners .set(moveEvent, { handler: (/** * @param {?} e * @return {?} */ function (e) { return _this.pointerMove.next((/** @type {?} */ (e))); }), options: activeCapturingEventOptions }) .set(upEvent, { handler: (/** * @param {?} e * @return {?} */ function (e) { return _this.pointerUp.next((/** @type {?} */ (e))); }), options: true }) // Preventing the default action on `mousemove` isn't enough to disable text selection // on Safari so we need to prevent the selection event as well. Alternatively this can // be done by setting `user-select: none` on the `body`, however it has causes a style // recalculation which can be expensive on pages with a lot of elements. .set('selectstart', { handler: this._preventDefaultWhileDragging, options: activeCapturingEventOptions }); // TODO(crisbeto): prevent mouse wheel scrolling while // dragging until we've set up proper scroll handling. if (!isTouchEvent) { this._globalListeners.set('wheel', { handler: this._preventDefaultWhileDragging, options: activeCapturingEventOptions }); } this._ngZone.runOutsideAngular((/** * @return {?} */ function () { _this._globalListeners.forEach((/** * @param {?} config * @param {?} name * @return {?} */ function (config, name) { _this._document.addEventListener(name, config.handler, config.options); })); })); } }; /** Stops dragging a drag item instance. */ /** * Stops dragging a drag item instance. * @param {?} drag * @return {?} */ DragDropRegistry.prototype.stopDragging = /** * Stops dragging a drag item instance. * @param {?} drag * @return {?} */ function (drag) { this._activeDragInstances.delete(drag); if (this._activeDragInstances.size === 0) { this._clearGlobalListeners(); } }; /** Gets whether a drag item instance is currently being dragged. */ /** * Gets whether a drag item instance is currently being dragged. * @param {?} drag * @return {?} */ DragDropRegistry.prototype.isDragging = /** * Gets whether a drag item instance is currently being dragged. * @param {?} drag * @return {?} */ function (drag) { return this._activeDragInstances.has(drag); }; /** * Gets a drop container by its id. * @deprecated No longer being used. To be removed. * @breaking-change 8.0.0 */ /** * Gets a drop container by its id. * @deprecated No longer being used. To be removed. * \@breaking-change 8.0.0 * @param {?} id * @return {?} */ DragDropRegistry.prototype.getDropContainer = /** * Gets a drop container by its id. * @deprecated No longer being used. To be removed. * \@breaking-change 8.0.0 * @param {?} id * @return {?} */ function (id) { return Array.from(this._dropInstances).find((/** * @param {?} instance * @return {?} */ function (instance) { return instance.id === id; })); }; /** * @return {?} */ DragDropRegistry.prototype.ngOnDestroy = /** * @return {?} */ function () { var _this = this; this._dragInstances.forEach((/** * @param {?} instance * @return {?} */ function (instance) { return _this.removeDragItem(instance); })); this._dropInstances.forEach((/** * @param {?} instance * @return {?} */ function (instance) { return _this.removeDropContainer(instance); })); this._clearGlobalListeners(); this.pointerMove.complete(); this.pointerUp.complete(); }; /** Clears out the global event listeners from the `document`. */ /** * Clears out the global event listeners from the `document`. * @private * @return {?} */ DragDropRegistry.prototype._clearGlobalListeners = /** * Clears out the global event listeners from the `document`. * @private * @return {?} */ function () { var _this = this; this._globalListeners.forEach((/** * @param {?} config * @param {?} name * @return {?} */ function (config, name) { _this._document.removeEventListener(name, config.handler, config.options); })); this._globalListeners.clear(); }; DragDropRegistry.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ DragDropRegistry.ctorParameters = function () { return [ { type: NgZone }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] } ]; }; /** @nocollapse */ DragDropRegistry.ngInjectableDef = i0.defineInjectable({ factory: function DragDropRegistry_Factory() { return new DragDropRegistry(i0.inject(i0.NgZone), i0.inject(i1.DOCUMENT)); }, token: DragDropRegistry, providedIn: "root" }); return DragDropRegistry; }()); export { DragDropRegistry }; if (false) { /** * @type {?} * @private */ DragDropRegistry.prototype._document; /** * Registered drop container instances. * @type {?} * @private */ DragDropRegistry.prototype._dropInstances; /** * Registered drag item instances. * @type {?} * @private */ DragDropRegistry.prototype._dragInstances; /** * Drag item instances that are currently being dragged. * @type {?} * @private */ DragDropRegistry.prototype._activeDragInstances; /** * Keeps track of the event listeners that we've bound to the `document`. * @type {?} * @private */ DragDropRegistry.prototype._globalListeners; /** * Emits the `touchmove` or `mousemove` events that are dispatched * while the user is dragging a drag item instance. * @type {?} */ DragDropRegistry.prototype.pointerMove; /** * Emits the `touchend` or `mouseup` events that are dispatched * while the user is dragging a drag item instance. * @type {?} */ DragDropRegistry.prototype.pointerUp; /** * Event listener that will prevent the default browser action while the user is dragging. * \@param event Event whose default action should be prevented. * @type {?} * @private */ DragDropRegistry.prototype._preventDefaultWhileDragging; /** * @type {?} * @private */ DragDropRegistry.prototype._ngZone; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZy1kcm9wLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXBsdXRvLyIsInNvdXJjZXMiOlsibGliL2RyYWctZHJvcC9kcmFnLWRyb3AtcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBYSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDcEUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7Ozs7Ozs7SUFHdEUsMkJBQTJCLEdBQUcsK0JBQStCLENBQUM7SUFDbEUsT0FBTyxFQUFFLEtBQUs7SUFDZCxPQUFPLEVBQUUsSUFBSTtDQUNkLENBQUM7Ozs7Ozs7Ozs7O0FBV0Y7SUErQkUsMEJBQ1UsT0FBZSxFQUNMLFNBQWM7UUFGbEMsaUJBSUM7UUFIUyxZQUFPLEdBQVAsT0FBTyxDQUFROzs7O1FBM0JqQixtQkFBYyxHQUFHLElBQUksR0FBRyxFQUFLLENBQUM7Ozs7UUFHOUIsbUJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBSyxDQUFDOzs7O1FBRzlCLHlCQUFvQixHQUFHLElBQUksR0FBRyxFQUFLLENBQUM7Ozs7UUFHcEMscUJBQWdCLEdBQUcsSUFBSSxHQUFHLEVBRzlCLENBQUM7Ozs7O1FBTUksZ0JBQVcsR0FBcUMsSUFBSSxPQUFPLEVBQTJCLENBQUM7Ozs7O1FBTXZGLGNBQVMsR0FBcUMsSUFBSSxPQUFPLEVBQTJCLENBQUM7Ozs7O1FBMEl0RixpQ0FBNEI7Ozs7UUFBRyxVQUFDLEtBQVk7WUFDbEQsSUFBSSxLQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFO2dCQUNsQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDeEI7UUFDSCxDQUFDLEVBQUE7UUF6SUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7SUFDN0IsQ0FBQztJQUVELDZDQUE2Qzs7Ozs7O0lBQzdDLGdEQUFxQjs7Ozs7SUFBckIsVUFBc0IsSUFBTztRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbEMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUNsQyxNQUFNLEtBQUssQ0FBQyw2QkFBMEIsSUFBSSxDQUFDLEVBQUUsb0NBQWdDLENBQUMsQ0FBQzthQUNoRjtZQUVELElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQy9CO0lBQ0gsQ0FBQztJQUVELGlEQUFpRDs7Ozs7O0lBQ2pELDJDQUFnQjs7Ozs7SUFBaEIsVUFBaUIsSUFBTztRQUF4QixpQkFjQztRQWJDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTlCLHVFQUF1RTtRQUN2RSxvRUFBb0U7UUFDcEUsc0RBQXNEO1FBQ3RELElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO1lBQ2xDLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCOzs7WUFBQztnQkFDN0IsaURBQWlEO2dCQUNqRCxxREFBcUQ7Z0JBQ3JELEtBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLEtBQUksQ0FBQyw0QkFBNEIsRUFDMUUsMkJBQTJCLENBQUMsQ0FBQztZQUNuQyxDQUFDLEVBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQztJQUVELGtEQUFrRDs7Ozs7O0lBQ2xELDhDQUFtQjs7Ozs7SUFBbkIsVUFBb0IsSUFBTztRQUN6QixJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsc0RBQXNEOzs7Ozs7SUFDdEQseUNBQWM7Ozs7O0lBQWQsVUFBZSxJQUFPO1FBQ3BCLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEIsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksS0FBSyxDQUFDLEVBQUU7WUFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLDRCQUE0QixFQUM3RSwyQkFBMkIsQ0FBQyxDQUFDO1NBQ2xDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7Ozs7Ozs7SUFDSCx3Q0FBYTs7Ozs7O0lBQWIsVUFBYyxJQUFPLEVBQUUsS0FBOEI7UUFBckQsaUJBNENDO1FBM0NDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTs7Z0JBQ2xDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7O2dCQUM3QyxTQUFTLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVc7O2dCQUNwRCxPQUFPLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFFckQsdUZBQXVGO1lBQ3ZGLHlGQUF5RjtZQUN6RixzRkFBc0Y7WUFDdEYsSUFBSSxDQUFDLGdCQUFnQjtpQkFDbEIsR0FBRyxDQUFDLFNBQVMsRUFBRTtnQkFDZCxPQUFPOzs7O2dCQUFFLFVBQUMsQ0FBUSxJQUFLLE9BQUEsS0FBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsbUJBQUEsQ0FBQyxFQUEyQixDQUFDLEVBQW5ELENBQW1ELENBQUE7Z0JBQzFFLE9BQU8sRUFBRSwyQkFBMkI7YUFDckMsQ0FBQztpQkFDRCxHQUFHLENBQUMsT0FBTyxFQUFFO2dCQUNaLE9BQU87Ozs7Z0JBQUUsVUFBQyxDQUFRLElBQUssT0FBQSxLQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxtQkFBQSxDQUFDLEVBQTJCLENBQUMsRUFBakQsQ0FBaUQsQ0FBQTtnQkFDeEUsT0FBTyxFQUFFLElBQUk7YUFDZCxDQUFDO2dCQUNGLHNGQUFzRjtnQkFDdEYsc0ZBQXNGO2dCQUN0RixzRkFBc0Y7Z0JBQ3RGLHdFQUF3RTtpQkFDdkUsR0FBRyxDQUFDLGFBQWEsRUFBRTtnQkFDbEIsT0FBTyxFQUFFLElBQUksQ0FBQyw0QkFBNEI7Z0JBQzFDLE9BQU8sRUFBRSwyQkFBMkI7YUFDckMsQ0FBQyxDQUFDO1lBRUwsc0RBQXNEO1lBQ3RELHNEQUFzRDtZQUN0RCxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUNqQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRTtvQkFDakMsT0FBTyxFQUFFLElBQUksQ0FBQyw0QkFBNEI7b0JBQzFDLE9BQU8sRUFBRSwyQkFBMkI7aUJBQ3JDLENBQUMsQ0FBQzthQUNKO1lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUI7OztZQUFDO2dCQUM3QixLQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTzs7Ozs7Z0JBQUMsVUFBQyxNQUFNLEVBQUUsSUFBSTtvQkFDekMsS0FBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3hFLENBQUMsRUFBQyxDQUFDO1lBQ0wsQ0FBQyxFQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCwyQ0FBMkM7Ozs7OztJQUMzQyx1Q0FBWTs7Ozs7SUFBWixVQUFhLElBQU87UUFDbEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO1lBQ3hDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQztJQUVELG9FQUFvRTs7Ozs7O0lBQ3BFLHFDQUFVOzs7OztJQUFWLFVBQVcsSUFBTztRQUNoQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7O09BSUc7Ozs7Ozs7O0lBQ0gsMkNBQWdCOzs7Ozs7O0lBQWhCLFVBQWlCLEVBQVU7UUFDekIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJOzs7O1FBQUMsVUFBQSxRQUFRLElBQUksT0FBQSxRQUFRLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBbEIsQ0FBa0IsRUFBQyxDQUFDO0lBQzlFLENBQUM7Ozs7SUFFRCxzQ0FBVzs7O0lBQVg7UUFBQSxpQkFNQztRQUxDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTzs7OztRQUFDLFVBQUEsUUFBUSxJQUFJLE9BQUEsS0FBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBN0IsQ0FBNkIsRUFBQyxDQUFDO1FBQ3ZFLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTzs7OztRQUFDLFVBQUEsUUFBUSxJQUFJLE9BQUEsS0FBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxFQUFsQyxDQUFrQyxFQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFZRCxpRUFBaUU7Ozs7OztJQUN6RCxnREFBcUI7Ozs7O0lBQTdCO1FBQUEsaUJBTUM7UUFMQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTzs7Ozs7UUFBQyxVQUFDLE1BQU0sRUFBRSxJQUFJO1lBQ3pDLEtBQUksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzNFLENBQUMsRUFBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2hDLENBQUM7O2dCQXBMRixVQUFVLFNBQUMsRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFDOzs7O2dCQXBCWixNQUFNO2dEQXFEckIsTUFBTSxTQUFDLFFBQVE7OzsyQkE3RHBCO0NBaU5DLEFBckxELElBcUxDO1NBcExZLGdCQUFnQjs7Ozs7O0lBQzNCLHFDQUE0Qjs7Ozs7O0lBRzVCLDBDQUFzQzs7Ozs7O0lBR3RDLDBDQUFzQzs7Ozs7O0lBR3RDLGdEQUE0Qzs7Ozs7O0lBRzVDLDRDQUdLOzs7Ozs7SUFNTCx1Q0FBZ0c7Ozs7OztJQU1oRyxxQ0FBOEY7Ozs7Ozs7SUEwSTlGLHdEQUlDOzs7OztJQTNJQyxtQ0FBdUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICpcclxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcclxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7SW5qZWN0YWJsZSwgTmdab25lLCBPbkRlc3Ryb3ksIEluamVjdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7U3ViamVjdH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMgfSBmcm9tICcuL3V0aWxzL3Bhc3NpdmUtbGlzdGVuZXJzJztcclxuXHJcbi8qKiBFdmVudCBvcHRpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gYmluZCBhbiBhY3RpdmUsIGNhcHR1cmluZyBldmVudC4gKi9cclxuY29uc3QgYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zID0gbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyh7XHJcbiAgcGFzc2l2ZTogZmFsc2UsXHJcbiAgY2FwdHVyZTogdHJ1ZVxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBAaWdub3JlXHJcbiAqIFNlcnZpY2UgdGhhdCBrZWVwcyB0cmFjayBvZiBhbGwgdGhlIGRyYWcgaXRlbSBhbmQgZHJvcCBjb250YWluZXJcclxuICogaW5zdGFuY2VzLCBhbmQgbWFuYWdlcyBnbG9iYWwgZXZlbnQgbGlzdGVuZXJzIG9uIHRoZSBgZG9jdW1lbnRgLlxyXG4gKiBAZG9jcy1wcml2YXRlXHJcbiAqL1xyXG4vLyBOb3RlOiB0aGlzIGNsYXNzIGlzIGdlbmVyaWMsIHJhdGhlciB0aGFuIHJlZmVyZW5jaW5nIENka0RyYWcgYW5kIENka0Ryb3BMaXN0IGRpcmVjdGx5LCBpbiBvcmRlclxyXG4vLyB0byBhdm9pZCBjaXJjdWxhciBpbXBvcnRzLiBJZiB3ZSB3ZXJlIHRvIHJlZmVyZW5jZSB0aGVtIGhlcmUsIGltcG9ydGluZyB0aGUgcmVnaXN0cnkgaW50byB0aGVcclxuLy8gY2xhc3NlcyB0aGF0IGFyZSByZWdpc3RlcmluZyB0aGVtc2VsdmVzIHdpbGwgaW50cm9kdWNlIGEgY2lyY3VsYXIgaW1wb3J0LlxyXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcclxuZXhwb3J0IGNsYXNzIERyYWdEcm9wUmVnaXN0cnk8SSwgQyBleHRlbmRzIHtpZDogc3RyaW5nfT4gaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIHByaXZhdGUgX2RvY3VtZW50OiBEb2N1bWVudDtcclxuXHJcbiAgLyoqIFJlZ2lzdGVyZWQgZHJvcCBjb250YWluZXIgaW5zdGFuY2VzLiAqL1xyXG4gIHByaXZhdGUgX2Ryb3BJbnN0YW5jZXMgPSBuZXcgU2V0PEM+KCk7XHJcblxyXG4gIC8qKiBSZWdpc3RlcmVkIGRyYWcgaXRlbSBpbnN0YW5jZXMuICovXHJcbiAgcHJpdmF0ZSBfZHJhZ0luc3RhbmNlcyA9IG5ldyBTZXQ8ST4oKTtcclxuXHJcbiAgLyoqIERyYWcgaXRlbSBpbnN0YW5jZXMgdGhhdCBhcmUgY3VycmVudGx5IGJlaW5nIGRyYWdnZWQuICovXHJcbiAgcHJpdmF0ZSBfYWN0aXZlRHJhZ0luc3RhbmNlcyA9IG5ldyBTZXQ8ST4oKTtcclxuXHJcbiAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZSd2ZSBib3VuZCB0byB0aGUgYGRvY3VtZW50YC4gKi9cclxuICBwcml2YXRlIF9nbG9iYWxMaXN0ZW5lcnMgPSBuZXcgTWFwPHN0cmluZywge1xyXG4gICAgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCxcclxuICAgIG9wdGlvbnM/OiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyB8IGJvb2xlYW5cclxuICB9PigpO1xyXG5cclxuICAvKipcclxuICAgKiBFbWl0cyB0aGUgYHRvdWNobW92ZWAgb3IgYG1vdXNlbW92ZWAgZXZlbnRzIHRoYXQgYXJlIGRpc3BhdGNoZWRcclxuICAgKiB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZyBhIGRyYWcgaXRlbSBpbnN0YW5jZS5cclxuICAgKi9cclxuICByZWFkb25seSBwb2ludGVyTW92ZTogU3ViamVjdDxUb3VjaEV2ZW50IHwgTW91c2VFdmVudD4gPSBuZXcgU3ViamVjdDxUb3VjaEV2ZW50IHwgTW91c2VFdmVudD4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHMgdGhlIGB0b3VjaGVuZGAgb3IgYG1vdXNldXBgIGV2ZW50cyB0aGF0IGFyZSBkaXNwYXRjaGVkXHJcbiAgICogd2hpbGUgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgYSBkcmFnIGl0ZW0gaW5zdGFuY2UuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgcG9pbnRlclVwOiBTdWJqZWN0PFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50PiA9IG5ldyBTdWJqZWN0PFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50PigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxyXG4gICAgQEluamVjdChET0NVTUVOVCkgX2RvY3VtZW50OiBhbnkpIHtcclxuICAgIHRoaXMuX2RvY3VtZW50ID0gX2RvY3VtZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqIEFkZHMgYSBkcm9wIGNvbnRhaW5lciB0byB0aGUgcmVnaXN0cnkuICovXHJcbiAgcmVnaXN0ZXJEcm9wQ29udGFpbmVyKGRyb3A6IEMpIHtcclxuICAgIGlmICghdGhpcy5fZHJvcEluc3RhbmNlcy5oYXMoZHJvcCkpIHtcclxuICAgICAgaWYgKHRoaXMuZ2V0RHJvcENvbnRhaW5lcihkcm9wLmlkKSkge1xyXG4gICAgICAgIHRocm93IEVycm9yKGBEcm9wIGluc3RhbmNlIHdpdGggaWQgXCIke2Ryb3AuaWR9XCIgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkLmApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmFkZChkcm9wKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBBZGRzIGEgZHJhZyBpdGVtIGluc3RhbmNlIHRvIHRoZSByZWdpc3RyeS4gKi9cclxuICByZWdpc3RlckRyYWdJdGVtKGRyYWc6IEkpIHtcclxuICAgIHRoaXMuX2RyYWdJbnN0YW5jZXMuYWRkKGRyYWcpO1xyXG5cclxuICAgIC8vIFRoZSBgdG91Y2htb3ZlYCBldmVudCBnZXRzIGJvdW5kIG9uY2UsIGFoZWFkIG9mIHRpbWUsIGJlY2F1c2UgV2ViS2l0XHJcbiAgICAvLyB3b24ndCBwcmV2ZW50RGVmYXVsdCBvbiBhIGR5bmFtaWNhbGx5LWFkZGVkIGB0b3VjaG1vdmVgIGxpc3RlbmVyLlxyXG4gICAgLy8gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xODQyNTAuXHJcbiAgICBpZiAodGhpcy5fZHJhZ0luc3RhbmNlcy5zaXplID09PSAxKSB7XHJcbiAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgLy8gVGhlIGV2ZW50IGhhbmRsZXIgaGFzIHRvIGJlIGV4cGxpY2l0bHkgYWN0aXZlLFxyXG4gICAgICAgIC8vIGJlY2F1c2UgbmV3ZXIgYnJvd3NlcnMgbWFrZSBpdCBwYXNzaXZlIGJ5IGRlZmF1bHQuXHJcbiAgICAgICAgdGhpcy5fZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGhpcy5fcHJldmVudERlZmF1bHRXaGlsZURyYWdnaW5nLFxyXG4gICAgICAgICAgICBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnMpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBSZW1vdmVzIGEgZHJvcCBjb250YWluZXIgZnJvbSB0aGUgcmVnaXN0cnkuICovXHJcbiAgcmVtb3ZlRHJvcENvbnRhaW5lcihkcm9wOiBDKSB7XHJcbiAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmRlbGV0ZShkcm9wKTtcclxuICB9XHJcblxyXG4gIC8qKiBSZW1vdmVzIGEgZHJhZyBpdGVtIGluc3RhbmNlIGZyb20gdGhlIHJlZ2lzdHJ5LiAqL1xyXG4gIHJlbW92ZURyYWdJdGVtKGRyYWc6IEkpIHtcclxuICAgIHRoaXMuX2RyYWdJbnN0YW5jZXMuZGVsZXRlKGRyYWcpO1xyXG4gICAgdGhpcy5zdG9wRHJhZ2dpbmcoZHJhZyk7XHJcblxyXG4gICAgaWYgKHRoaXMuX2RyYWdJbnN0YW5jZXMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICB0aGlzLl9kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLl9wcmV2ZW50RGVmYXVsdFdoaWxlRHJhZ2dpbmcsXHJcbiAgICAgICAgICBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnMpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU3RhcnRzIHRoZSBkcmFnZ2luZyBzZXF1ZW5jZSBmb3IgYSBkcmFnIGluc3RhbmNlLlxyXG4gICAqIEBwYXJhbSBkcmFnIERyYWcgaW5zdGFuY2Ugd2hpY2ggaXMgYmVpbmcgZHJhZ2dlZC5cclxuICAgKiBAcGFyYW0gZXZlbnQgRXZlbnQgdGhhdCBpbml0aWF0ZWQgdGhlIGRyYWdnaW5nLlxyXG4gICAqL1xyXG4gIHN0YXJ0RHJhZ2dpbmcoZHJhZzogSSwgZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLmFkZChkcmFnKTtcclxuXHJcbiAgICBpZiAodGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5zaXplID09PSAxKSB7XHJcbiAgICAgIGNvbnN0IGlzVG91Y2hFdmVudCA9IGV2ZW50LnR5cGUuc3RhcnRzV2l0aCgndG91Y2gnKTtcclxuICAgICAgY29uc3QgbW92ZUV2ZW50ID0gaXNUb3VjaEV2ZW50ID8gJ3RvdWNobW92ZScgOiAnbW91c2Vtb3ZlJztcclxuICAgICAgY29uc3QgdXBFdmVudCA9IGlzVG91Y2hFdmVudCA/ICd0b3VjaGVuZCcgOiAnbW91c2V1cCc7XHJcblxyXG4gICAgICAvLyBXZSBleHBsaWNpdGx5IGJpbmQgX19hY3RpdmVfXyBsaXN0ZW5lcnMgaGVyZSwgYmVjYXVzZSBuZXdlciBicm93c2VycyB3aWxsIGRlZmF1bHQgdG9cclxuICAgICAgLy8gcGFzc2l2ZSBvbmVzIGZvciBgbW91c2Vtb3ZlYCBhbmQgYHRvdWNobW92ZWAuIFRoZSBldmVudHMgbmVlZCB0byBiZSBhY3RpdmUsIGJlY2F1c2Ugd2VcclxuICAgICAgLy8gdXNlIGBwcmV2ZW50RGVmYXVsdGAgdG8gcHJldmVudCB0aGUgcGFnZSBmcm9tIHNjcm9sbGluZyB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZy5cclxuICAgICAgdGhpcy5fZ2xvYmFsTGlzdGVuZXJzXHJcbiAgICAgICAgLnNldChtb3ZlRXZlbnQsIHtcclxuICAgICAgICAgIGhhbmRsZXI6IChlOiBFdmVudCkgPT4gdGhpcy5wb2ludGVyTW92ZS5uZXh0KGUgYXMgVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpLFxyXG4gICAgICAgICAgb3B0aW9uczogYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zXHJcbiAgICAgICAgfSlcclxuICAgICAgICAuc2V0KHVwRXZlbnQsIHtcclxuICAgICAgICAgIGhhbmRsZXI6IChlOiBFdmVudCkgPT4gdGhpcy5wb2ludGVyVXAubmV4dChlIGFzIFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSxcclxuICAgICAgICAgIG9wdGlvbnM6IHRydWVcclxuICAgICAgICB9KVxyXG4gICAgICAgIC8vIFByZXZlbnRpbmcgdGhlIGRlZmF1bHQgYWN0aW9uIG9uIGBtb3VzZW1vdmVgIGlzbid0IGVub3VnaCB0byBkaXNhYmxlIHRleHQgc2VsZWN0aW9uXHJcbiAgICAgICAgLy8gb24gU2FmYXJpIHNvIHdlIG5lZWQgdG8gcHJldmVudCB0aGUgc2VsZWN0aW9uIGV2ZW50IGFzIHdlbGwuIEFsdGVybmF0aXZlbHkgdGhpcyBjYW5cclxuICAgICAgICAvLyBiZSBkb25lIGJ5IHNldHRpbmcgYHVzZXItc2VsZWN0OiBub25lYCBvbiB0aGUgYGJvZHlgLCBob3dldmVyIGl0IGhhcyBjYXVzZXMgYSBzdHlsZVxyXG4gICAgICAgIC8vIHJlY2FsY3VsYXRpb24gd2hpY2ggY2FuIGJlIGV4cGVuc2l2ZSBvbiBwYWdlcyB3aXRoIGEgbG90IG9mIGVsZW1lbnRzLlxyXG4gICAgICAgIC5zZXQoJ3NlbGVjdHN0YXJ0Jywge1xyXG4gICAgICAgICAgaGFuZGxlcjogdGhpcy5fcHJldmVudERlZmF1bHRXaGlsZURyYWdnaW5nLFxyXG4gICAgICAgICAgb3B0aW9uczogYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBUT0RPKGNyaXNiZXRvKTogcHJldmVudCBtb3VzZSB3aGVlbCBzY3JvbGxpbmcgd2hpbGVcclxuICAgICAgLy8gZHJhZ2dpbmcgdW50aWwgd2UndmUgc2V0IHVwIHByb3BlciBzY3JvbGwgaGFuZGxpbmcuXHJcbiAgICAgIGlmICghaXNUb3VjaEV2ZW50KSB7XHJcbiAgICAgICAgdGhpcy5fZ2xvYmFsTGlzdGVuZXJzLnNldCgnd2hlZWwnLCB7XHJcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLl9wcmV2ZW50RGVmYXVsdFdoaWxlRHJhZ2dpbmcsXHJcbiAgICAgICAgICBvcHRpb25zOiBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnNcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgICB0aGlzLl9nbG9iYWxMaXN0ZW5lcnMuZm9yRWFjaCgoY29uZmlnLCBuYW1lKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGNvbmZpZy5oYW5kbGVyLCBjb25maWcub3B0aW9ucyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIFN0b3BzIGRyYWdnaW5nIGEgZHJhZyBpdGVtIGluc3RhbmNlLiAqL1xyXG4gIHN0b3BEcmFnZ2luZyhkcmFnOiBJKSB7XHJcbiAgICB0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLmRlbGV0ZShkcmFnKTtcclxuXHJcbiAgICBpZiAodGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5zaXplID09PSAwKSB7XHJcbiAgICAgIHRoaXMuX2NsZWFyR2xvYmFsTGlzdGVuZXJzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogR2V0cyB3aGV0aGVyIGEgZHJhZyBpdGVtIGluc3RhbmNlIGlzIGN1cnJlbnRseSBiZWluZyBkcmFnZ2VkLiAqL1xyXG4gIGlzRHJhZ2dpbmcoZHJhZzogSSkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMuaGFzKGRyYWcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBhIGRyb3AgY29udGFpbmVyIGJ5IGl0cyBpZC5cclxuICAgKiBAZGVwcmVjYXRlZCBObyBsb25nZXIgYmVpbmcgdXNlZC4gVG8gYmUgcmVtb3ZlZC5cclxuICAgKiBAYnJlYWtpbmctY2hhbmdlIDguMC4wXHJcbiAgICovXHJcbiAgZ2V0RHJvcENvbnRhaW5lcihpZDogc3RyaW5nKTogQyB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLl9kcm9wSW5zdGFuY2VzKS5maW5kKGluc3RhbmNlID0+IGluc3RhbmNlLmlkID09PSBpZCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuX2RyYWdJbnN0YW5jZXMuZm9yRWFjaChpbnN0YW5jZSA9PiB0aGlzLnJlbW92ZURyYWdJdGVtKGluc3RhbmNlKSk7XHJcbiAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmZvckVhY2goaW5zdGFuY2UgPT4gdGhpcy5yZW1vdmVEcm9wQ29udGFpbmVyKGluc3RhbmNlKSk7XHJcbiAgICB0aGlzLl9jbGVhckdsb2JhbExpc3RlbmVycygpO1xyXG4gICAgdGhpcy5wb2ludGVyTW92ZS5jb21wbGV0ZSgpO1xyXG4gICAgdGhpcy5wb2ludGVyVXAuY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50IGxpc3RlbmVyIHRoYXQgd2lsbCBwcmV2ZW50IHRoZSBkZWZhdWx0IGJyb3dzZXIgYWN0aW9uIHdoaWxlIHRoZSB1c2VyIGlzIGRyYWdnaW5nLlxyXG4gICAqIEBwYXJhbSBldmVudCBFdmVudCB3aG9zZSBkZWZhdWx0IGFjdGlvbiBzaG91bGQgYmUgcHJldmVudGVkLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3ByZXZlbnREZWZhdWx0V2hpbGVEcmFnZ2luZyA9IChldmVudDogRXZlbnQpID0+IHtcclxuICAgIGlmICh0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLnNpemUpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBDbGVhcnMgb3V0IHRoZSBnbG9iYWwgZXZlbnQgbGlzdGVuZXJzIGZyb20gdGhlIGBkb2N1bWVudGAuICovXHJcbiAgcHJpdmF0ZSBfY2xlYXJHbG9iYWxMaXN0ZW5lcnMoKSB7XHJcbiAgICB0aGlzLl9nbG9iYWxMaXN0ZW5lcnMuZm9yRWFjaCgoY29uZmlnLCBuYW1lKSA9PiB7XHJcbiAgICAgIHRoaXMuX2RvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgY29uZmlnLmhhbmRsZXIsIGNvbmZpZy5vcHRpb25zKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX2dsb2JhbExpc3RlbmVycy5jbGVhcigpO1xyXG4gIH1cclxufVxyXG4iXX0=