ts-events
Version:
Various EventEmitter event replacements with synchronous, a-synchronous, and queued events. Made in TypeScript so usable with JavaScript and TypeScript.
142 lines • 14.4 kB
JavaScript
// Copyright © 2015 Rogier Schouten<github@workingcode.ninja>
// License: ISC
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorSyncEvent = exports.VoidSyncEvent = exports.SyncEvent = void 0;
var base_event_1 = require("./base-event");
/**
* This is a true EventEmitter replacement: the handlers are called synchronously when
* you post the event.
* - Allows better error handling by aggregating any errors thrown by handlers.
* - Prevents livelock by throwing an error when recursion depth is above a maximum.
* - Handlers are called only for events posted after they were attached.
* - Handlers are not called anymore when they are detached, even if a post() is in progress
*/
var SyncEvent = /** @class */ (function (_super) {
__extends(SyncEvent, _super);
function SyncEvent() {
var _this = _super !== null && _super.apply(this, arguments) || this;
/**
* Recursive post() invocations
*/
_this._recursion = 0;
return _this;
}
Object.defineProperty(SyncEvent.prototype, "evtListenersChanged", {
/**
* Sent when someone attaches or detaches
*/
get: function () {
if (!this._listenersChanged) {
// need to delay-load to avoid stack overflow in constructor
this._listenersChanged = new VoidSyncEvent();
}
return this._listenersChanged;
},
enumerable: false,
configurable: true
});
SyncEvent.prototype.post = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this._listeners || this._listeners.length === 0) {
return;
}
this._recursion++;
if (typeof SyncEvent.MAX_RECURSION_DEPTH === 'number'
&& Number.isInteger(SyncEvent.MAX_RECURSION_DEPTH)
&& SyncEvent.MAX_RECURSION_DEPTH > 0
&& this._recursion > SyncEvent.MAX_RECURSION_DEPTH) {
throw new Error('event fired recursively');
}
// copy a reference to the array because this._listeners might be replaced during
// the handler calls
var listeners = this._listeners;
for (var i = 0; i < listeners.length; ++i) {
var listener = listeners[i];
this._call(listener, args);
}
this._recursion--;
};
/** @inheritdoc */
SyncEvent.prototype._attach = function (a, b, once) {
var _a, _b, _c, _d;
var count = (_b = (_a = this._listeners) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
var result = _super.prototype._attach.call(this, a, b, once);
if (this.evtListenersChanged && count !== ((_d = (_c = this._listeners) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0)) {
this.evtListenersChanged.post();
}
return result;
};
/** @inheritdoc */
SyncEvent.prototype._detach = function () {
var _a, _b, _c, _d;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var count = (_b = (_a = this._listeners) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
var result = _super.prototype._detach.apply(this, args);
if (this.evtListenersChanged && count !== ((_d = (_c = this._listeners) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0)) {
this.evtListenersChanged.post();
}
return result;
};
/**
* Maximum number of times that an event handler may cause the same event
* recursively.
*/
SyncEvent.MAX_RECURSION_DEPTH = 10;
return SyncEvent;
}(base_event_1.BaseEvent));
exports.SyncEvent = SyncEvent;
/**
* Convenience class for events without data
*/
var VoidSyncEvent = /** @class */ (function (_super) {
__extends(VoidSyncEvent, _super);
function VoidSyncEvent() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Send the event.
*/
VoidSyncEvent.prototype.post = function () {
_super.prototype.post.call(this, undefined);
};
return VoidSyncEvent;
}(SyncEvent));
exports.VoidSyncEvent = VoidSyncEvent;
/**
* Similar to 'error' event on EventEmitter: throws when a post() occurs while no handlers set.
*/
var ErrorSyncEvent = /** @class */ (function (_super) {
__extends(ErrorSyncEvent, _super);
function ErrorSyncEvent() {
return _super !== null && _super.apply(this, arguments) || this;
}
ErrorSyncEvent.prototype.post = function (data) {
if (this.listenerCount() === 0) {
throw new Error("error event posted while no listeners attached. Error: " + data.message);
}
_super.prototype.post.call(this, data);
};
return ErrorSyncEvent;
}(SyncEvent));
exports.ErrorSyncEvent = ErrorSyncEvent;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1ldmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvc3luYy1ldmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw2REFBNkQ7QUFDN0QsZUFBZTtBQUVmLFlBQVksQ0FBQzs7Ozs7Ozs7Ozs7Ozs7OztBQUViLDJDQUFpRDtBQUVqRDs7Ozs7OztHQU9HO0FBQ0g7SUFBa0MsNkJBQVk7SUFBOUM7UUFBQSxxRUE0RUM7UUFyREc7O1dBRUc7UUFDSyxnQkFBVSxHQUFXLENBQUMsQ0FBQzs7SUFrRG5DLENBQUM7SUF4RUcsc0JBQVcsMENBQW1CO1FBSDlCOztXQUVHO2FBQ0g7WUFDSSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO2dCQUN6Qiw0REFBNEQ7Z0JBQzVELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDO2FBQ2hEO1lBQ0QsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFDbEMsQ0FBQzs7O09BQUE7SUF3Qk0sd0JBQUksR0FBWDtRQUFZLGNBQWM7YUFBZCxVQUFjLEVBQWQscUJBQWMsRUFBZCxJQUFjO1lBQWQseUJBQWM7O1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUNsRCxPQUFPO1NBQ1Y7UUFDRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEIsSUFDSSxPQUFPLFNBQVMsQ0FBQyxtQkFBbUIsS0FBSyxRQUFRO2VBQzlDLE1BQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDO2VBQy9DLFNBQVMsQ0FBQyxtQkFBbUIsR0FBRyxDQUFDO2VBQ2pDLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixFQUNwRDtZQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztTQUM5QztRQUNELGlGQUFpRjtRQUNqRixvQkFBb0I7UUFDcEIsSUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNsQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtZQUN2QyxJQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDOUI7UUFDRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELGtCQUFrQjtJQUNSLDJCQUFPLEdBQWpCLFVBQWtCLENBQTZDLEVBQUUsQ0FBa0MsRUFBRSxJQUFhOztRQUM5RyxJQUFNLEtBQUssZUFBRyxJQUFJLENBQUMsVUFBVSwwQ0FBRSxNQUFNLG1DQUFJLENBQUMsQ0FBQztRQUMzQyxJQUFNLE1BQU0sR0FBRyxpQkFBTSxPQUFPLFlBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxLQUFLLEtBQUssYUFBQyxJQUFJLENBQUMsVUFBVSwwQ0FBRSxNQUFNLG1DQUFJLENBQUMsQ0FBQyxFQUFFO1lBQ3RFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNuQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxrQkFBa0I7SUFDUiwyQkFBTyxHQUFqQjs7UUFBa0IsY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDNUIsSUFBTSxLQUFLLGVBQUcsSUFBSSxDQUFDLFVBQVUsMENBQUUsTUFBTSxtQ0FBSSxDQUFDLENBQUM7UUFDM0MsSUFBTSxNQUFNLEdBQUcsaUJBQU0sT0FBTyxhQUFJLElBQUksQ0FBQyxDQUFDO1FBQ3RDLElBQUksSUFBSSxDQUFDLG1CQUFtQixJQUFJLEtBQUssS0FBSyxhQUFDLElBQUksQ0FBQyxVQUFVLDBDQUFFLE1BQU0sbUNBQUksQ0FBQyxDQUFDLEVBQUU7WUFDdEUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1NBQ25DO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztJQTFERDs7O09BR0c7SUFDVyw2QkFBbUIsR0FBbUIsRUFBRSxDQUFDO0lBdUQzRCxnQkFBQztDQUFBLEFBNUVELENBQWtDLHNCQUFTLEdBNEUxQztBQTVFWSw4QkFBUztBQThFdEI7O0dBRUc7QUFDSDtJQUFtQyxpQ0FBZTtJQUFsRDs7SUFRQSxDQUFDO0lBTkc7O09BRUc7SUFDSSw0QkFBSSxHQUFYO1FBQ0ksaUJBQU0sSUFBSSxZQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFDTCxvQkFBQztBQUFELENBQUMsQUFSRCxDQUFtQyxTQUFTLEdBUTNDO0FBUlksc0NBQWE7QUFVMUI7O0dBRUc7QUFDSDtJQUFvQyxrQ0FBZ0I7SUFBcEQ7O0lBUUEsQ0FBQztJQU5VLDZCQUFJLEdBQVgsVUFBWSxJQUFXO1FBQ25CLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsRUFBRTtZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDREQUEwRCxJQUFJLENBQUMsT0FBUyxDQUFDLENBQUM7U0FDN0Y7UUFDRCxpQkFBTSxJQUFJLFlBQUMsSUFBSSxDQUFDLENBQUM7SUFDckIsQ0FBQztJQUNMLHFCQUFDO0FBQUQsQ0FBQyxBQVJELENBQW9DLFNBQVMsR0FRNUM7QUFSWSx3Q0FBYyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCDCqSAyMDE1IFJvZ2llciBTY2hvdXRlbjxnaXRodWJAd29ya2luZ2NvZGUubmluamE+XG4vLyBMaWNlbnNlOiBJU0NcblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge0Jhc2VFdmVudCwgUG9zdGFibGV9IGZyb20gJy4vYmFzZS1ldmVudCc7XG5cbi8qKlxuICogVGhpcyBpcyBhIHRydWUgRXZlbnRFbWl0dGVyIHJlcGxhY2VtZW50OiB0aGUgaGFuZGxlcnMgYXJlIGNhbGxlZCBzeW5jaHJvbm91c2x5IHdoZW5cbiAqIHlvdSBwb3N0IHRoZSBldmVudC5cbiAqIC0gQWxsb3dzIGJldHRlciBlcnJvciBoYW5kbGluZyBieSBhZ2dyZWdhdGluZyBhbnkgZXJyb3JzIHRocm93biBieSBoYW5kbGVycy5cbiAqIC0gUHJldmVudHMgbGl2ZWxvY2sgYnkgdGhyb3dpbmcgYW4gZXJyb3Igd2hlbiByZWN1cnNpb24gZGVwdGggaXMgYWJvdmUgYSBtYXhpbXVtLlxuICogLSBIYW5kbGVycyBhcmUgY2FsbGVkIG9ubHkgZm9yIGV2ZW50cyBwb3N0ZWQgYWZ0ZXIgdGhleSB3ZXJlIGF0dGFjaGVkLlxuICogLSBIYW5kbGVycyBhcmUgbm90IGNhbGxlZCBhbnltb3JlIHdoZW4gdGhleSBhcmUgZGV0YWNoZWQsIGV2ZW4gaWYgYSBwb3N0KCkgaXMgaW4gcHJvZ3Jlc3NcbiAqL1xuZXhwb3J0IGNsYXNzIFN5bmNFdmVudDxUPiBleHRlbmRzIEJhc2VFdmVudDxUPiBpbXBsZW1lbnRzIFBvc3RhYmxlPFQ+IHtcbiAgICAvKipcbiAgICAgKiBTZW50IHdoZW4gc29tZW9uZSBhdHRhY2hlcyBvciBkZXRhY2hlc1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZXZ0TGlzdGVuZXJzQ2hhbmdlZCgpOiBWb2lkU3luY0V2ZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9saXN0ZW5lcnNDaGFuZ2VkKSB7XG4gICAgICAgICAgICAvLyBuZWVkIHRvIGRlbGF5LWxvYWQgdG8gYXZvaWQgc3RhY2sgb3ZlcmZsb3cgaW4gY29uc3RydWN0b3JcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyc0NoYW5nZWQgPSBuZXcgVm9pZFN5bmNFdmVudCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9saXN0ZW5lcnNDaGFuZ2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGZvciBsaXN0ZW5pbmcgdG8gbGlzdGVuZXIgY291bnRcbiAgICAgKi9cbiAgICBwcml2YXRlIF9saXN0ZW5lcnNDaGFuZ2VkPzogVm9pZFN5bmNFdmVudDtcblxuICAgIC8qKlxuICAgICAqIE1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoYXQgYW4gZXZlbnQgaGFuZGxlciBtYXkgY2F1c2UgdGhlIHNhbWUgZXZlbnRcbiAgICAgKiByZWN1cnNpdmVseS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIE1BWF9SRUNVUlNJT05fREVQVEg/OiBudW1iZXIgfCBudWxsID0gMTA7XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmUgcG9zdCgpIGludm9jYXRpb25zXG4gICAgICovXG4gICAgcHJpdmF0ZSBfcmVjdXJzaW9uOiBudW1iZXIgPSAwO1xuXG4gICAgLyoqXG4gICAgICogU2VuZCB0aGUgZXZlbnQuIEhhbmRsZXJzIGFyZSBjYWxsZWQgaW1tZWRpYXRlbHkgYW5kIHN5bmNocm9ub3VzbHkuXG4gICAgICogSWYgYW4gZXJyb3IgaXMgdGhyb3duIGJ5IGEgaGFuZGxlciwgdGhlIHJlbWFpbmluZyBoYW5kbGVycyBhcmUgc3RpbGwgY2FsbGVkLlxuICAgICAqIEFmdGVyd2FyZCwgYW4gQWdncmVnYXRlRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIG9yaWdpbmFsIGVycm9yKHMpIGluIGl0cyAnY2F1c2VzJyBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBwdWJsaWMgcG9zdChkYXRhOiBUKTogdm9pZDtcbiAgICBwdWJsaWMgcG9zdCguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuX2xpc3RlbmVycyB8fCB0aGlzLl9saXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcmVjdXJzaW9uKys7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBTeW5jRXZlbnQuTUFYX1JFQ1VSU0lPTl9ERVBUSCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICYmIE51bWJlci5pc0ludGVnZXIoU3luY0V2ZW50Lk1BWF9SRUNVUlNJT05fREVQVEgpXG4gICAgICAgICAgICAmJiBTeW5jRXZlbnQuTUFYX1JFQ1VSU0lPTl9ERVBUSCA+IDBcbiAgICAgICAgICAgICYmIHRoaXMuX3JlY3Vyc2lvbiA+IFN5bmNFdmVudC5NQVhfUkVDVVJTSU9OX0RFUFRIXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdldmVudCBmaXJlZCByZWN1cnNpdmVseScpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvcHkgYSByZWZlcmVuY2UgdG8gdGhlIGFycmF5IGJlY2F1c2UgdGhpcy5fbGlzdGVuZXJzIG1pZ2h0IGJlIHJlcGxhY2VkIGR1cmluZ1xuICAgICAgICAvLyB0aGUgaGFuZGxlciBjYWxsc1xuICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpXTtcbiAgICAgICAgICAgIHRoaXMuX2NhbGwobGlzdGVuZXIsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3JlY3Vyc2lvbi0tO1xuICAgIH1cblxuICAgIC8qKiBAaW5oZXJpdGRvYyAqL1xuICAgIHByb3RlY3RlZCBfYXR0YWNoKGE6ICgoZGF0YTogVCkgPT4gdm9pZCkgfCBPYmplY3QgfCBQb3N0YWJsZTxUPiwgYjogKChkYXRhOiBUKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCwgb25jZTogYm9vbGVhbik6ICgpID0+IHZvaWQge1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuX2xpc3RlbmVycz8ubGVuZ3RoID8/IDA7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHN1cGVyLl9hdHRhY2goYSwgYiwgb25jZSk7XG4gICAgICAgIGlmICh0aGlzLmV2dExpc3RlbmVyc0NoYW5nZWQgJiYgY291bnQgIT09ICh0aGlzLl9saXN0ZW5lcnM/Lmxlbmd0aCA/PyAwKSkge1xuICAgICAgICAgICAgdGhpcy5ldnRMaXN0ZW5lcnNDaGFuZ2VkLnBvc3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKiBAaW5oZXJpdGRvYyAqL1xuICAgIHByb3RlY3RlZCBfZGV0YWNoKC4uLmFyZ3M6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gdGhpcy5fbGlzdGVuZXJzPy5sZW5ndGggPz8gMDtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc3VwZXIuX2RldGFjaCguLi5hcmdzKTtcbiAgICAgICAgaWYgKHRoaXMuZXZ0TGlzdGVuZXJzQ2hhbmdlZCAmJiBjb3VudCAhPT0gKHRoaXMuX2xpc3RlbmVycz8ubGVuZ3RoID8/IDApKSB7XG4gICAgICAgICAgICB0aGlzLmV2dExpc3RlbmVyc0NoYW5nZWQucG9zdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufVxuXG4vKipcbiAqIENvbnZlbmllbmNlIGNsYXNzIGZvciBldmVudHMgd2l0aG91dCBkYXRhXG4gKi9cbmV4cG9ydCBjbGFzcyBWb2lkU3luY0V2ZW50IGV4dGVuZHMgU3luY0V2ZW50PHZvaWQ+IHtcblxuICAgIC8qKlxuICAgICAqIFNlbmQgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBwb3N0KCk6IHZvaWQge1xuICAgICAgICBzdXBlci5wb3N0KHVuZGVmaW5lZCk7XG4gICAgfVxufVxuXG4vKipcbiAqIFNpbWlsYXIgdG8gJ2Vycm9yJyBldmVudCBvbiBFdmVudEVtaXR0ZXI6IHRocm93cyB3aGVuIGEgcG9zdCgpIG9jY3VycyB3aGlsZSBubyBoYW5kbGVycyBzZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFcnJvclN5bmNFdmVudCBleHRlbmRzIFN5bmNFdmVudDxFcnJvcj4ge1xuXG4gICAgcHVibGljIHBvc3QoZGF0YTogRXJyb3IpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMubGlzdGVuZXJDb3VudCgpID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVycm9yIGV2ZW50IHBvc3RlZCB3aGlsZSBubyBsaXN0ZW5lcnMgYXR0YWNoZWQuIEVycm9yOiAke2RhdGEubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlci5wb3N0KGRhdGEpO1xuICAgIH1cbn1cbiJdfQ==