@jokio/ts-events
Version:
Various EventEmitter event replacements with synchronous, a-synchronous, and queued events. Made in TypeScript so usable with JavaScript and TypeScript.
195 lines • 23.6 kB
JavaScript
// Copyright © 2015 Rogier Schouten<github@workingcode.ninja>
// License: ISC
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
return { next: verb(0), "throw": verb(1), "return": verb(2) };
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Base class for events.
* Handles attaching and detaching listeners
*/
var BaseEvent = (function () {
function BaseEvent() {
}
/**
* Attach implementation
*/
BaseEvent.prototype.attach = function (a, b) {
this._attach(a, b, false);
};
/**
* Attach implementation
*/
BaseEvent.prototype.once = function (a, b) {
this._attach(a, b, true);
};
/**
* Attach / once implementation
* @param a
* @param b
* @param once
*/
BaseEvent.prototype._attach = function (a, b, once) {
return __awaiter(this, void 0, void 0, function () {
var boundTo, handler, event;
return __generator(this, function (_a) {
if (typeof a === 'function') {
handler = a;
}
else if (!b && typeof a.post === 'function') {
event = a;
}
else {
if (typeof a !== 'object') {
throw new Error('Expect a function or object as first argument');
}
if (typeof b !== 'function') {
throw new Error('Expect a function as second argument');
}
boundTo = a;
handler = b;
}
if (!this._listeners) {
this._listeners = [];
}
else {
// make a copy of the array so events that are underway have a stable local copy
// of the listeners array at the time of post()
this._listeners = this._listeners.slice();
}
this._listeners.push({
deleted: false,
boundTo: boundTo,
handler: handler,
event: event,
once: once
});
return [2 /*return*/];
});
});
};
/**
* Detach implementation. See the overloads for description.
*/
BaseEvent.prototype.detach = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this._listeners || this._listeners.length === 0) {
return;
}
var boundTo;
var handler;
var event;
if (args.length >= 1) {
if (typeof (args[0]) === 'function') {
handler = args[0];
}
else if (args.length === 1 && typeof args[0].post === 'function') {
event = args[0];
}
else {
boundTo = args[0];
}
}
if (args.length >= 2) {
handler = args[1];
}
// remove listeners AND mark them as deleted so subclasses don't send any more events to them
this._listeners = this._listeners.filter(function (listener) {
if ((typeof handler === 'undefined' || listener.handler === handler)
&& (typeof event === 'undefined' || listener.event === event)
&& (typeof boundTo === 'undefined' || listener.boundTo === boundTo)) {
listener.deleted = true;
return false;
}
return true;
});
if (this._listeners.length === 0) {
delete this._listeners;
}
};
/**
* Abstract post() method to be able to connect any type of event to any other directly
* @abstract
*/
BaseEvent.prototype.post = function (data) {
throw new Error('abstract');
};
/**
* The number of attached listeners
*/
BaseEvent.prototype.listenerCount = function () {
return (this._listeners ? this._listeners.length : 0);
};
/**
* Call the given listener, if it is not marked as 'deleted'
* @param listener The listener to call
* @param args The arguments to the handler
*/
BaseEvent.prototype._call = function (listener, args) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!!listener.deleted) return [3 /*break*/, 4];
if (listener.once) {
// remove listeners AND mark as deleted so subclasses don't send any more events to them
listener.deleted = true;
this._listeners = this._listeners.filter(function (l) { return l !== listener; });
if (this._listeners.length === 0) {
delete this._listeners;
}
}
if (!listener.event) return [3 /*break*/, 2];
return [4 /*yield*/, listener.event.post.apply(listener.event, args)];
case 1:
_a.sent();
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, listener.handler.apply((typeof listener.boundTo === 'object' ? listener.boundTo : this), args)];
case 3:
_a.sent();
_a.label = 4;
case 4: return [2 /*return*/];
}
});
});
};
return BaseEvent;
}());
exports.BaseEvent = BaseEvent;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1ldmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9saWIvYmFzZS1ldmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw2REFBNkQ7QUFDN0QsZUFBZTtBQUVmLFlBQVksQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdDYjs7O0dBR0c7QUFDSDtJQUFBO0lBZ01BLENBQUM7SUF2S0c7O09BRUc7SUFDSSwwQkFBTSxHQUFiLFVBQWMsQ0FBc0QsRUFBRSxDQUE4QjtRQUNoRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQWtCRDs7T0FFRztJQUNJLHdCQUFJLEdBQVgsVUFBWSxDQUFzRCxFQUFFLENBQThCO1FBQzlGLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDVywyQkFBTyxHQUFyQixVQUFzQixDQUFzRCxFQUFFLENBQTJDLEVBQUUsSUFBYTs7Z0JBQ2hJLE9BQU8sRUFDUCxPQUFPLEVBQ1AsS0FBSzs7Z0JBQ1QsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQztvQkFDMUIsT0FBTyxHQUFHLENBQUMsQ0FBQztnQkFDaEIsQ0FBQztnQkFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBUSxDQUFpQixDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDO29CQUM3RCxLQUFLLEdBQUcsQ0FBZ0IsQ0FBQztnQkFDN0IsQ0FBQztnQkFBQyxJQUFJLENBQUMsQ0FBQztvQkFDSixFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO3dCQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLCtDQUEr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QUFLLEVBQUUsSUFBSSxDQUFDLEVBQUE7O3dCQUFyRCxTQUFxRCxDQUFDOzs0QkFFdEQscUJBQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLFFBQVEsQ0FBQyxPQUFPLEtBQUssUUFBUSxHQUFHLFFBQVEsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUE7O3dCQUFwRyxTQUFvRyxDQUFDOzs7Ozs7S0FHaEg7SUFFTCxnQkFBQztBQUFELENBQUMsQUFoTUQsSUFnTUM7QUFoTVksOEJBQVMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgwqkgMjAxNSBSb2dpZXIgU2Nob3V0ZW48Z2l0aHViQHdvcmtpbmdjb2RlLm5pbmphPlxuLy8gTGljZW5zZTogSVNDXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0IGludGVyZmFjZSBQb3N0YWJsZTxUPiB7XG4gICAgcG9zdChkYXRhOiBUKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBpbnRlcmZhY2UgYmV0d2VlbiBCYXNlRXZlbnQgYW5kIGl0cyBzdWJjbGFzc2VzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdGVuZXI8VD4ge1xuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyB0aGF0IHRoZSBsaXN0ZW5lciB3YXMgZGV0YWNoZWRcbiAgICAgKi9cbiAgICBkZWxldGVkOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFRoZSBoYW5kbGVyXG4gICAgICovXG4gICAgaGFuZGxlcj86IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIC8qKlxuICAgICAqIFRoZSB0aGlzIHBvaW50ZXIgZm9yIHRoZSBoYW5kbGVyXG4gICAgICovXG4gICAgYm91bmRUbz86IE9iamVjdDtcbiAgICAvKipcbiAgICAgKiBJbnN0ZWFkIG9mIGEgaGFuZGxlciwgYW4gYXR0YWNoZWQgZXZlbnRcbiAgICAgKi9cbiAgICBldmVudD86IFBvc3RhYmxlPFQ+O1xuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhZnRlciBmaXJzdCBjYWxsP1xuICAgICAqL1xuICAgIG9uY2U6IGJvb2xlYW47XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZXZlbnRzLlxuICogSGFuZGxlcyBhdHRhY2hpbmcgYW5kIGRldGFjaGluZyBsaXN0ZW5lcnNcbiAqL1xuZXhwb3J0IGNsYXNzIEJhc2VFdmVudDxUPiBpbXBsZW1lbnRzIFBvc3RhYmxlPFQ+IHtcblxuICAgIC8qKlxuICAgICAqIEF0dGFjaGVkIGxpc3RlbmVycy4gTk9URTogZG8gbm90IG1vZGlmeS5cbiAgICAgKiBJbnN0ZWFkLCByZXBsYWNlIHdpdGggYSBuZXcgYXJyYXkgd2l0aCBwb3NzaWJseSB0aGUgc2FtZSBlbGVtZW50cy4gVGhpcyBlbnN1cmVzXG4gICAgICogdGhhdCBhbnkgcmVmZXJlbmNlcyB0byB0aGUgYXJyYXkgYnkgZXZlbnRzIHRoYXQgYXJlIHVuZGVyd2F5IHJlbWFpbiB0aGUgc2FtZS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2xpc3RlbmVyczogTGlzdGVuZXI8VD5bXTtcblxuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhbiBldmVudCBoYW5kbGVyXG4gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGZ1bmN0aW9uIHRvIGNhbGwuIFRoZSB0aGlzIGFyZ3VtZW50IG9mIHRoZSBmdW5jdGlvbiB3aWxsIGJlIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2goaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhbiBldmVudCBoYW5kbGVyXG4gICAgICogQHBhcmFtIGJvdW5kVG8gVGhlIHRoaXMgYXJndW1lbnQgb2YgdGhlIGhhbmRsZXJcbiAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgZnVuY3Rpb24gdG8gY2FsbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgYXR0YWNoKGJvdW5kVG86IE9iamVjdCwgaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhbiBldmVudCBkaXJlY3RseVxuICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdG8gYmUgcG9zdGVkXG4gICAgICovXG4gICAgcHVibGljIGF0dGFjaChldmVudDogUG9zdGFibGU8VD4pOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEF0dGFjaCBpbXBsZW1lbnRhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2goYTogKChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+KSB8IE9iamVjdCB8IFBvc3RhYmxlPFQ+LCBiPzogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fYXR0YWNoKGEsIGIsIGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2ggYW4gZXZlbnQgaGFuZGxlciB3aGljaCBhdXRvbWF0aWNhbGx5IGdldHMgcmVtb3ZlZCBhZnRlciB0aGUgZmlyc3QgY2FsbFxuICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBmdW5jdGlvbiB0byBjYWxsLiBUaGUgdGhpcyBhcmd1bWVudCBvZiB0aGUgZnVuY3Rpb24gd2lsbCBiZSB0aGlzIG9iamVjdC5cbiAgICAgKi9cbiAgICBwdWJsaWMgb25jZShoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQXR0YWNoIGFuIGV2ZW50IGhhbmRsZXIgd2hpY2ggYXV0b21hdGljYWxseSBnZXRzIHJlbW92ZWQgYWZ0ZXIgdGhlIGZpcnN0IGNhbGxcbiAgICAgKiBAcGFyYW0gYm91bmRUbyBUaGUgdGhpcyBhcmd1bWVudCBvZiB0aGUgaGFuZGxlclxuICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBmdW5jdGlvbiB0byBjYWxsLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbmNlKGJvdW5kVG86IE9iamVjdCwgaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEF0dGFjaCBhbiBldmVudCBkaXJlY3RseSBhbmQgZGUtYXR0YWNoIGFmdGVyIHRoZSBmaXJzdCBjYWxsXG4gICAgICogQHBhcmFtIGV2ZW50IFRoZSBldmVudCB0byBiZSBwb3N0ZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgb25jZShldmVudDogUG9zdGFibGU8VD4pOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEF0dGFjaCBpbXBsZW1lbnRhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBvbmNlKGE6ICgoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPikgfCBPYmplY3QgfCBQb3N0YWJsZTxUPiwgYj86IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2F0dGFjaChhLCBiLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2ggLyBvbmNlIGltcGxlbWVudGF0aW9uXG4gICAgICogQHBhcmFtIGFcbiAgICAgKiBAcGFyYW0gYlxuICAgICAqIEBwYXJhbSBvbmNlXG4gICAgICovXG4gICAgcHJpdmF0ZSBhc3luYyBfYXR0YWNoKGE6ICgoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPikgfCBPYmplY3QgfCBQb3N0YWJsZTxUPiwgYjogKChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+KSB8IHVuZGVmaW5lZCwgb25jZTogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgYm91bmRUbzogT2JqZWN0O1xuICAgICAgICBsZXQgaGFuZGxlcjogKGRhdGE6IFQpID0+IFByb21pc2U8dm9pZD47XG4gICAgICAgIGxldCBldmVudDogUG9zdGFibGU8VD47XG4gICAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgaGFuZGxlciA9IGE7XG4gICAgICAgIH0gZWxzZSBpZiAoIWIgJiYgdHlwZW9mIChhIGFzIFBvc3RhYmxlPFQ+KS5wb3N0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBldmVudCA9IGEgYXMgUG9zdGFibGU8VD47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGEgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgYSBmdW5jdGlvbiBvciBvYmplY3QgYXMgZmlyc3QgYXJndW1lbnQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IGEgZnVuY3Rpb24gYXMgc2Vjb25kIGFyZ3VtZW50Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBib3VuZFRvID0gYTtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBiO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIG1ha2UgYSBjb3B5IG9mIHRoZSBhcnJheSBzbyBldmVudHMgdGhhdCBhcmUgdW5kZXJ3YXkgaGF2ZSBhIHN0YWJsZSBsb2NhbCBjb3B5XG4gICAgICAgICAgICAvLyBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGF0IHRoZSB0aW1lIG9mIHBvc3QoKVxuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzLnNsaWNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnB1c2goe1xuICAgICAgICAgICAgZGVsZXRlZDogZmFsc2UsXG4gICAgICAgICAgICBib3VuZFRvLFxuICAgICAgICAgICAgaGFuZGxlcixcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgb25jZVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRhY2ggYWxsIGxpc3RlbmVycyB3aXRoIHRoZSBnaXZlbiBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcHVibGljIGRldGFjaChoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogRGV0YWNoIGFsbCBsaXN0ZW5lcnMgd2l0aCB0aGUgZ2l2ZW4gaGFuZGxlciBmdW5jdGlvbiBhbmQgYm91bmRUbyBvYmplY3QuXG4gICAgICovXG4gICAgcHVibGljIGRldGFjaChib3VuZFRvOiBPYmplY3QsIGhhbmRsZXI6IChkYXRhOiBUKSA9PiBQcm9taXNlPHZvaWQ+KTogdm9pZDtcbiAgICAvKipcbiAgICAgKiBEZXRhY2ggYWxsIGxpc3RlbmVycyB0aGF0IHdlcmUgYXR0YWNoZWQgd2l0aCB0aGUgZ2l2ZW4gYm91bmRUbyBvYmplY3QuXG4gICAgICovXG4gICAgcHVibGljIGRldGFjaChib3VuZFRvOiBPYmplY3QpOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIERldGFjaCB0aGUgZ2l2ZW4gZXZlbnQuXG4gICAgICovXG4gICAgcHVibGljIGRldGFjaChldmVudDogUG9zdGFibGU8VD4pOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIERldGFjaCBhbGwgbGlzdGVuZXJzXG4gICAgICovXG4gICAgcHVibGljIGRldGFjaCgpOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIERldGFjaCBpbXBsZW1lbnRhdGlvbi4gU2VlIHRoZSBvdmVybG9hZHMgZm9yIGRlc2NyaXB0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBkZXRhY2goLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLl9saXN0ZW5lcnMgfHwgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBib3VuZFRvOiBPYmplY3Q7XG4gICAgICAgIGxldCBoYW5kbGVyOiAoZGF0YTogVCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgICAgICAgbGV0IGV2ZW50OiBQb3N0YWJsZTxUPjtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID49IDEpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgKGFyZ3NbMF0pID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlciA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIHR5cGVvZiBhcmdzWzBdLnBvc3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBldmVudCA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJvdW5kVG8gPSBhcmdzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICBoYW5kbGVyID0gYXJnc1sxXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbW92ZSBsaXN0ZW5lcnMgQU5EIG1hcmsgdGhlbSBhcyBkZWxldGVkIHNvIHN1YmNsYXNzZXMgZG9uJ3Qgc2VuZCBhbnkgbW9yZSBldmVudHMgdG8gdGhlbVxuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnMuZmlsdGVyKChsaXN0ZW5lcjogTGlzdGVuZXI8VD4pOiBib29sZWFuID0+IHtcbiAgICAgICAgICAgIGlmICgodHlwZW9mIGhhbmRsZXIgPT09ICd1bmRlZmluZWQnIHx8IGxpc3RlbmVyLmhhbmRsZXIgPT09IGhhbmRsZXIpXG4gICAgICAgICAgICAgICAgJiYgKHR5cGVvZiBldmVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgbGlzdGVuZXIuZXZlbnQgPT09IGV2ZW50KVxuICAgICAgICAgICAgICAgICYmICh0eXBlb2YgYm91bmRUbyA9PT0gJ3VuZGVmaW5lZCcgfHwgbGlzdGVuZXIuYm91bmRUbyA9PT0gYm91bmRUbykpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lci5kZWxldGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2xpc3RlbmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBYnN0cmFjdCBwb3N0KCkgbWV0aG9kIHRvIGJlIGFibGUgdG8gY29ubmVjdCBhbnkgdHlwZSBvZiBldmVudCB0byBhbnkgb3RoZXIgZGlyZWN0bHlcbiAgICAgKiBAYWJzdHJhY3RcbiAgICAgKi9cbiAgICBwdWJsaWMgcG9zdChkYXRhOiBUKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWJzdHJhY3QnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGF0dGFjaGVkIGxpc3RlbmVyc1xuICAgICAqL1xuICAgIHB1YmxpYyBsaXN0ZW5lckNvdW50KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAodGhpcy5fbGlzdGVuZXJzID8gdGhpcy5fbGlzdGVuZXJzLmxlbmd0aCA6IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGwgdGhlIGdpdmVuIGxpc3RlbmVyLCBpZiBpdCBpcyBub3QgbWFya2VkIGFzICdkZWxldGVkJ1xuICAgICAqIEBwYXJhbSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgdG8gY2FsbFxuICAgICAqIEBwYXJhbSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gdGhlIGhhbmRsZXJcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgYXN5bmMgX2NhbGwobGlzdGVuZXI6IExpc3RlbmVyPFQ+LCBhcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIWxpc3RlbmVyLmRlbGV0ZWQpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lci5vbmNlKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGxpc3RlbmVycyBBTkQgbWFyayBhcyBkZWxldGVkIHNvIHN1YmNsYXNzZXMgZG9uJ3Qgc2VuZCBhbnkgbW9yZSBldmVudHMgdG8gdGhlbVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmRlbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycy5maWx0ZXIoKGw6IExpc3RlbmVyPFQ+KTogYm9vbGVhbiA9PiBsICE9PSBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2xpc3RlbmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2xpc3RlbmVycztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGlzdGVuZXIuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBsaXN0ZW5lci5ldmVudC5wb3N0LmFwcGx5KGxpc3RlbmVyLmV2ZW50LCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgbGlzdGVuZXIuaGFuZGxlci5hcHBseSgodHlwZW9mIGxpc3RlbmVyLmJvdW5kVG8gPT09ICdvYmplY3QnID8gbGlzdGVuZXIuYm91bmRUbyA6IHRoaXMpLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxufVxuIl19