UNPKG

data-transport

Version:
272 lines 40.8 kB
var _a; import { __assign, __awaiter, __generator, __rest } from "tslib"; import { listenerKey, originalListensMapKey, requestsMapKey, listensMapKey, senderKey, timeoutKey, transportKey, prefixKey, transportType, produceKey, listenKey, serializerKey, logKey, verboseKey, beforeEmitKey, beforeEmitResolveKey, } from './constant'; import { generateId } from './utils'; var DEFAULT_TIMEOUT = 60 * 1000; var DEFAULT_RESPOND = true; var DEFAULT_SILENT = false; var DEFAULT_PREFIX = 'DataTransport'; export var getAction = function (prefix, name) { return "".concat(prefix, "-").concat(name.toString()); }; var getListenName = function (prefix, action) { return action.replace(new RegExp("^".concat(prefix, "-")), ''); }; /** * Create a base transport */ var Transport = /** @class */ (function () { function Transport(_b) { var listener = _b.listener, sender = _b.sender, _c = _b.timeout, timeout = _c === void 0 ? DEFAULT_TIMEOUT : _c, _d = _b.verbose, verbose = _d === void 0 ? false : _d, _e = _b.prefix, prefix = _e === void 0 ? DEFAULT_PREFIX : _e, _f = _b.listenKeys, listenKeys = _f === void 0 ? [] : _f, _g = _b.checkListen, checkListen = _g === void 0 ? true : _g, serializer = _b.serializer, logger = _b.logger; var _this = this; var _h, _j; this[_a] = new Map(); this.id = generateId(); this[listensMapKey] = (_h = this[listensMapKey]) !== null && _h !== void 0 ? _h : new Map(); this[originalListensMapKey] = (_j = this[originalListensMapKey]) !== null && _j !== void 0 ? _j : new Map(); this[listenerKey] = listener.bind(this); this[senderKey] = sender.bind(this); this[timeoutKey] = timeout; this[prefixKey] = prefix; this[serializerKey] = serializer; this[verboseKey] = verbose; this[logKey] = logger; new Set(listenKeys).forEach(function (key) { var _b; var fn = _this[key]; if (__DEV__) { if (typeof fn !== 'function') { console.warn("'".concat(key, "' is NOT a methods or function.")); } } _this[originalListensMapKey].set(key, fn); Object.assign(_this, (_b = {}, _b[key] = function () { if (__DEV__) { throw new Error("The method '".concat(key, "' is a listen function that can NOT be actively called.")); } }, _b)); }); this[originalListensMapKey].forEach(function (value, name) { _this[produceKey](name, value); }); this[listenKey] = function (options) { var _b, _c; if (_this[verboseKey]) { if (typeof _this[logKey] === 'function' && options) { _this[logKey](options); } else { console.info('DataTransport Receive: ', options); } } if (options === null || options === void 0 ? void 0 : options[transportKey]) { var listenName = getListenName(_this[prefixKey], options.action); var hasListen = typeof _this[listenName] === 'function'; if (options.type === transportType.response) { var resolve = _this[requestsMapKey].get(options[transportKey]); if (resolve) { var response = options.response; resolve(typeof response === 'string' && ((_b = _this[serializerKey]) === null || _b === void 0 ? void 0 : _b.parse) ? _this[serializerKey].parse(response) : response); } else if (hasListen) { if (__DEV__ && checkListen) { console.warn("The type '".concat(options.action, "' event '").concat(options[transportKey], "' has been resolved. Please check for a duplicate response.")); } } } else if (options.type === transportType.request) { var respond = _this[listensMapKey].get(options.action); if (typeof respond === 'function') { var request = options.request; respond(typeof request === 'string' && ((_c = _this[serializerKey]) === null || _c === void 0 ? void 0 : _c.parse) ? _this[serializerKey].parse(request) : request, __assign(__assign({}, options), { transportId: options[transportKey], hasRespond: options.hasRespond })); } else if (hasListen) { if (__DEV__ && checkListen) { console.error("The listen method or function '".concat(listenName, "' is NOT decorated by decorator '@listen' or be added 'listenKeys' list.")); } } } } }; var dispose = this[listenerKey](this[listenKey]); this.dispose = function () { if (typeof dispose === 'function') { _this[requestsMapKey].clear(); _this[listensMapKey].clear(); _this[originalListensMapKey].clear(); return dispose(); } else if (__DEV__) { console.warn("The return value of the the '".concat(_this.constructor.name, "' transport's listener should be a 'dispose' function for removing the listener")); } }; } Transport.prototype[(_a = requestsMapKey, produceKey)] = function (name, fn) { var _this = this; // https://github.com/microsoft/TypeScript/issues/40465 var action = getAction(this[prefixKey], name); this[listensMapKey].set(action, function (request, _b) { return __awaiter(_this, void 0, void 0, function () { var response, data; var _c; var _d; var hasRespond = _b.hasRespond, transportId = _b.transportId, _ = _b.request, args = __rest(_b, ["hasRespond", "transportId", "request"]); return __generator(this, function (_e) { switch (_e.label) { case 0: if (!(typeof fn === 'function')) return [3 /*break*/, 2]; return [4 /*yield*/, fn.apply(this, request)]; case 1: response = _e.sent(); if (!hasRespond) return [2 /*return*/]; data = __assign(__assign({}, args), (_c = { action: action, response: (typeof response !== 'undefined' && ((_d = this[serializerKey]) === null || _d === void 0 ? void 0 : _d.stringify) ? this[serializerKey].stringify(response) : response), hasRespond: hasRespond }, _c[transportKey] = transportId, _c.type = transportType.response, _c.responseId = this.id, _c)); this[senderKey](data); return [3 /*break*/, 3]; case 2: throw new Error("The listener for event ".concat(name, " should be a function.")); case 3: return [2 /*return*/]; } }); }); }); }; /** * Listen an event that transport data. * * @param name A transport action as listen message data action type * @param fn A transport listener */ Transport.prototype.listen = function (name, fn) { var _this = this; if (typeof name === 'string') { if (this[originalListensMapKey].get(name)) { throw new Error("Failed to listen to the event \"".concat(name, "\", the event \"").concat(name, "\" is already listened to.")); } if (typeof fn === 'function') { this[originalListensMapKey].set(name, fn); this[produceKey](name, fn); } else { throw new Error("The listener for event ".concat(name, " should be a function.")); } } else { throw new Error("The event name \"".concat(name.toString(), "\" is not a string, it should be a string.")); } return function () { _this[originalListensMapKey].delete(name); var action = getAction(_this[prefixKey], name); _this[listensMapKey].delete(action); }; }; /** * Emit an event that transport data. * * @param emitOptions A option for the transport data * @param request A request data * * @returns Return a response for the request. */ Transport.prototype.emit = function (options) { var request = []; for (var _i = 1; _i < arguments.length; _i++) { request[_i - 1] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var params, hasRespond, isSilent, timeout, name, transportId, action, rawRequestData, timeoutId, promise; var _b; var _this = this; var _c, _d, _e, _f, _g; return __generator(this, function (_h) { switch (_h.label) { case 0: params = typeof options === 'object' ? options : {}; hasRespond = (_c = params.respond) !== null && _c !== void 0 ? _c : DEFAULT_RESPOND; isSilent = (_d = params.silent) !== null && _d !== void 0 ? _d : DEFAULT_SILENT; timeout = (_e = params.timeout) !== null && _e !== void 0 ? _e : this[timeoutKey]; name = (_f = params.name) !== null && _f !== void 0 ? _f : options; transportId = generateId(); if (__DEV__ && (!name || typeof name !== 'string')) { throw new Error("The event name should be a string, and it's required."); } action = getAction(this[prefixKey], name); rawRequestData = __assign(__assign({}, (params._extra ? { _extra: params._extra } : {})), (_b = { type: transportType.request, action: action, request: (typeof request !== 'undefined' && ((_g = this[serializerKey]) === null || _g === void 0 ? void 0 : _g.stringify) ? this[serializerKey].stringify(request) : request), hasRespond: hasRespond }, _b[transportKey] = transportId, _b.requestId = this.id, _b)); if (this[verboseKey]) { if (typeof this[logKey] === 'function') { this[logKey](rawRequestData); } else { console.info('DataTransport Send: ', rawRequestData); } } if (!!hasRespond) return [3 /*break*/, 3]; if (!(this[beforeEmitKey] && !params.skipBeforeEmit)) return [3 /*break*/, 2]; return [4 /*yield*/, this[beforeEmitKey]]; case 1: _h.sent(); _h.label = 2; case 2: this[senderKey](rawRequestData); return [2 /*return*/, Promise.resolve(undefined)]; case 3: promise = Promise.race([ new Promise(function (resolve) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_b) { switch (_b.label) { case 0: if (!(this[beforeEmitKey] && !params.skipBeforeEmit)) return [3 /*break*/, 2]; return [4 /*yield*/, this[beforeEmitKey]]; case 1: _b.sent(); _b.label = 2; case 2: this[requestsMapKey].set(transportId, resolve); this[senderKey](rawRequestData); return [2 /*return*/]; } }); }); }), new Promise(function (_, reject) { timeoutId = setTimeout(function () { reject(); }, timeout); }), ]); return [2 /*return*/, promise .then(function (response) { // support Safari 10-11.1 clearTimeout(timeoutId); _this[requestsMapKey].delete(transportId); return response; }) .catch(function (error) { clearTimeout(timeoutId); _this[requestsMapKey].delete(transportId); if (typeof error === 'undefined') { if (isSilent) return; console.warn("The event '".concat(action, "' timed out for ").concat(timeout, " seconds..."), rawRequestData); } else { if (__DEV__) { throw error; } } })]; } }); }); }; return Transport; }()); export { Transport }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3RyYW5zcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFDTCxXQUFXLEVBQ1gscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osU0FBUyxFQUNULGFBQWEsRUFDYixVQUFVLEVBQ1YsU0FBUyxFQUNULGFBQWEsRUFDYixNQUFNLEVBQ04sVUFBVSxFQUNWLGFBQWEsRUFDYixvQkFBb0IsR0FDckIsTUFBTSxZQUFZLENBQUM7QUFhcEIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVyQyxJQUFNLGVBQWUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ2xDLElBQU0sZUFBZSxHQUFHLElBQUksQ0FBQztBQUM3QixJQUFNLGNBQWMsR0FBRyxLQUFLLENBQUM7QUFDN0IsSUFBTSxjQUFjLEdBQUcsZUFBZSxDQUFDO0FBRXZDLE1BQU0sQ0FBQyxJQUFNLFNBQVMsR0FBRyxVQUFDLE1BQWMsRUFBRSxJQUFZO0lBQ3BELE9BQUEsVUFBRyxNQUFNLGNBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFFO0FBQTlCLENBQThCLENBQUM7QUFDakMsSUFBTSxhQUFhLEdBQUcsVUFBQyxNQUFjLEVBQUUsTUFBYztJQUNuRCxPQUFBLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxNQUFNLENBQUMsV0FBSSxNQUFNLE1BQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUE3QyxDQUE2QyxDQUFDO0FBRWhEOztHQUVHO0FBQ0g7SUFtQkUsbUJBQVksRUFVTztZQVRqQixRQUFRLGNBQUEsRUFDUixNQUFNLFlBQUEsRUFDTixlQUF5QixFQUF6QixPQUFPLG1CQUFHLGVBQWUsS0FBQSxFQUN6QixlQUFlLEVBQWYsT0FBTyxtQkFBRyxLQUFLLEtBQUEsRUFDZixjQUF1QixFQUF2QixNQUFNLG1CQUFHLGNBQWMsS0FBQSxFQUN2QixrQkFBZSxFQUFmLFVBQVUsbUJBQUcsRUFBRSxLQUFBLEVBQ2YsbUJBQWtCLEVBQWxCLFdBQVcsbUJBQUcsSUFBSSxLQUFBLEVBQ2xCLFVBQVUsZ0JBQUEsRUFDVixNQUFNLFlBQUE7UUFUUixpQkE4R0M7O1FBMUhPLFFBQWdCLEdBQTBDLElBQUksR0FBRyxFQUFFLENBQUM7UUE2THJFLE9BQUUsR0FBRyxVQUFVLEVBQUUsQ0FBQztRQXRLdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLE1BQUEsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQ0FBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLE1BQUEsSUFBSSxDQUFDLHFCQUFxQixDQUFDLG1DQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdkUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUMzQixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxVQUFVLENBQUM7UUFDakMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBRXRCLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEdBQUc7O1lBQzlCLElBQU0sRUFBRSxHQUFJLEtBQXdDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUQsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDWixJQUFJLE9BQU8sRUFBRSxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUM3QixPQUFPLENBQUMsSUFBSSxDQUFDLFdBQUksR0FBRyxvQ0FBaUMsQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO1lBQ0gsQ0FBQztZQUNELEtBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDekMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFJO2dCQUNoQixHQUFDLEdBQUcsSUFBSjtvQkFDRSxJQUFJLE9BQU8sRUFBRSxDQUFDO3dCQUNaLE1BQU0sSUFBSSxLQUFLLENBQ2Isc0JBQWUsR0FBRyw0REFBeUQsQ0FDNUUsQ0FBQztvQkFDSixDQUFDO2dCQUNILENBQUM7b0JBQ0QsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSyxFQUFFLElBQUk7WUFDOUMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxVQUFDLE9BQXlCOztZQUMxQyxJQUFJLEtBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUNyQixJQUFJLE9BQU8sS0FBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDbEQsS0FBSSxDQUFDLE1BQU0sQ0FBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QixDQUFDO3FCQUFNLENBQUM7b0JBQ04sT0FBTyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbkQsQ0FBQztZQUNILENBQUM7WUFDRCxJQUFJLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRyxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUM1QixJQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsS0FBSSxDQUFDLFNBQVMsQ0FBRSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDbkUsSUFBTSxTQUFTLEdBQUcsT0FBUSxLQUFZLENBQUMsVUFBVSxDQUFDLEtBQUssVUFBVSxDQUFDO2dCQUNsRSxJQUFLLE9BQXFCLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDM0QsSUFBTSxPQUFPLEdBQUcsS0FBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztvQkFDaEUsSUFBSSxPQUFPLEVBQUUsQ0FBQzt3QkFDSixJQUFBLFFBQVEsR0FBSyxPQUFvQixTQUF6QixDQUEwQjt3QkFDMUMsT0FBTyxDQUNMLE9BQU8sUUFBUSxLQUFLLFFBQVEsS0FBSSxNQUFBLEtBQUksQ0FBQyxhQUFhLENBQUMsMENBQUUsS0FBSyxDQUFBOzRCQUN4RCxDQUFDLENBQUMsS0FBSSxDQUFDLGFBQWEsQ0FBRSxDQUFDLEtBQU0sQ0FBQyxRQUFRLENBQUM7NEJBQ3ZDLENBQUMsQ0FBQyxRQUFRLENBQ2IsQ0FBQztvQkFDSixDQUFDO3lCQUFNLElBQUksU0FBUyxFQUFFLENBQUM7d0JBQ3JCLElBQUksT0FBTyxJQUFJLFdBQVcsRUFBRSxDQUFDOzRCQUMzQixPQUFPLENBQUMsSUFBSSxDQUNWLG9CQUFhLE9BQU8sQ0FBQyxNQUFNLHNCQUFZLE9BQU8sQ0FBQyxZQUFZLENBQUMsZ0VBQTZELENBQzFILENBQUM7d0JBQ0osQ0FBQztvQkFDSCxDQUFDO2dCQUNILENBQUM7cUJBQU0sSUFBSyxPQUFvQixDQUFDLElBQUksS0FBSyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ2hFLElBQU0sT0FBTyxHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN4RCxJQUFJLE9BQU8sT0FBTyxLQUFLLFVBQVUsRUFBRSxDQUFDO3dCQUMxQixJQUFBLE9BQU8sR0FBSyxPQUFtQixRQUF4QixDQUF5Qjt3QkFDeEMsT0FBTyxDQUNMLE9BQU8sT0FBTyxLQUFLLFFBQVEsS0FBSSxNQUFBLEtBQUksQ0FBQyxhQUFhLENBQUMsMENBQUUsS0FBSyxDQUFBOzRCQUN2RCxDQUFDLENBQUMsS0FBSSxDQUFDLGFBQWEsQ0FBRSxDQUFDLEtBQU0sQ0FBQyxPQUFPLENBQUM7NEJBQ3RDLENBQUMsQ0FBQyxPQUFPLHdCQUVOLE9BQU8sS0FDVixXQUFXLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUNsQyxVQUFVLEVBQUcsT0FBb0IsQ0FBQyxVQUFVLElBRS9DLENBQUM7b0JBQ0osQ0FBQzt5QkFBTSxJQUFJLFNBQVMsRUFBRSxDQUFDO3dCQUNyQixJQUFJLE9BQU8sSUFBSSxXQUFXLEVBQUUsQ0FBQzs0QkFDM0IsT0FBTyxDQUFDLEtBQUssQ0FDWCx5Q0FBa0MsVUFBVSw2RUFBMEUsQ0FDdkgsQ0FBQzt3QkFDSixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixJQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFbkQsSUFBSSxDQUFDLE9BQU8sR0FBRztZQUNiLElBQUksT0FBTyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ2xDLEtBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0IsS0FBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUM1QixLQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDcEMsT0FBTyxPQUFPLEVBQUUsQ0FBQztZQUNuQixDQUFDO2lCQUFNLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQ1YsdUNBQWdDLEtBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxvRkFBaUYsQ0FDdkksQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDLENBQUM7SUFDSixDQUFDO0lBRU8sMEJBNUhDLGNBQWMsRUE0SGQsVUFBVSxFQUFDLEdBQXBCLFVBQ0UsSUFBTyxFQUNQLEVBQVE7UUFGVixpQkFnQ0M7UUE1QkMsdURBQXVEO1FBQ3ZELElBQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEdBQUcsQ0FDckIsTUFBTSxFQUNOLFVBQU8sT0FBTyxFQUFFLEVBQWdEOzs7O1lBQTlDLElBQUEsVUFBVSxnQkFBQSxFQUFFLFdBQVcsaUJBQUEsRUFBVyxDQUFDLGFBQUEsRUFBSyxJQUFJLGNBQTlDLHdDQUFnRCxDQUFGOzs7OzZCQUN4RCxDQUFBLE9BQU8sRUFBRSxLQUFLLFVBQVUsQ0FBQSxFQUF4Qix3QkFBd0I7d0JBQ08scUJBQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEVBQUE7O3dCQUF4RCxRQUFRLEdBQW1CLFNBQTZCO3dCQUM5RCxJQUFJLENBQUMsVUFBVTs0QkFBRSxzQkFBTzt3QkFDbEIsSUFBSSx5QkFDTCxJQUFJLFdBQ1AsTUFBTSxRQUFBLEVBQ04sUUFBUSxFQUFFLENBQUMsT0FBTyxRQUFRLEtBQUssV0FBVztxQ0FDMUMsTUFBQSxJQUFJLENBQUMsYUFBYSxDQUFDLDBDQUFFLFNBQVMsQ0FBQTtvQ0FDNUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUUsQ0FBQyxTQUFVLENBQUMsUUFBUSxDQUFDO29DQUMzQyxDQUFDLENBQUMsUUFBUSxDQUF1QixFQUNuQyxVQUFVLFlBQUEsT0FDVCxZQUFZLElBQUcsV0FBVyxFQUMzQixPQUFJLEdBQUUsYUFBYSxDQUFDLFFBQVEsRUFDNUIsYUFBVSxHQUFFLElBQUksQ0FBQyxFQUFFLE1BQ3BCLENBQUM7d0JBQ0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDOzs0QkFFdEIsTUFBTSxJQUFJLEtBQUssQ0FDYixpQ0FBMEIsSUFBSSwyQkFBd0IsQ0FDdkQsQ0FBQzs7OzthQUVMLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLDBCQUFNLEdBQWIsVUFBMkMsSUFBTyxFQUFFLEVBQWtCO1FBQXRFLGlCQXVCQztRQXRCQyxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzdCLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sSUFBSSxLQUFLLENBQ2IsMENBQWtDLElBQUksNkJBQWlCLElBQUksK0JBQTJCLENBQ3ZGLENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxPQUFPLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM3QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBMEIsSUFBSSwyQkFBd0IsQ0FBQyxDQUFDO1lBQzFFLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxLQUFLLENBQ2IsMkJBQW1CLElBQUksQ0FBQyxRQUFRLEVBQUUsK0NBQTJDLENBQzlFLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTztZQUNMLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QyxJQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsS0FBSSxDQUFDLFNBQVMsQ0FBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pELEtBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUlEOzs7Ozs7O09BT0c7SUFDVSx3QkFBSSxHQUFqQixVQUNFLE9BQXVCO1FBQ3ZCLGlCQUFpQzthQUFqQyxVQUFpQyxFQUFqQyxxQkFBaUMsRUFBakMsSUFBaUM7WUFBakMsZ0NBQWlDOzs7Ozs7Ozs7O3dCQUUzQixNQUFNLEdBQ1YsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFFLEVBQXVCLENBQUM7d0JBQzdELFVBQVUsR0FBRyxNQUFBLE1BQU0sQ0FBQyxPQUFPLG1DQUFJLGVBQWUsQ0FBQzt3QkFDL0MsUUFBUSxHQUFHLE1BQUEsTUFBTSxDQUFDLE1BQU0sbUNBQUksY0FBYyxDQUFDO3dCQUMzQyxPQUFPLEdBQUcsTUFBQSxNQUFNLENBQUMsT0FBTyxtQ0FBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQzdDLElBQUksR0FBRyxNQUFBLE1BQU0sQ0FBQyxJQUFJLG1DQUFJLE9BQU8sQ0FBQzt3QkFDOUIsV0FBVyxHQUFHLFVBQVUsRUFBRSxDQUFDO3dCQUNqQyxJQUFJLE9BQU8sSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxFQUFFLENBQUM7NEJBQ25ELE1BQU0sSUFBSSxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQzt3QkFDM0UsQ0FBQzt3QkFDSyxNQUFNLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUUsRUFBRSxJQUFjLENBQUMsQ0FBQzt3QkFDckQsY0FBYyx5QkFDZixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFdBQ25ELElBQUksRUFBRSxhQUFhLENBQUMsT0FBTyxFQUMzQixNQUFNLFFBQUEsRUFDTixPQUFPLEVBQUUsQ0FBQyxPQUFPLE9BQU8sS0FBSyxXQUFXLEtBQUksTUFBQSxJQUFJLENBQUMsYUFBYSxDQUFDLDBDQUFFLFNBQVMsQ0FBQTtvQ0FDeEUsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUUsQ0FBQyxTQUFVLENBQUMsT0FBTyxDQUFDO29DQUMxQyxDQUFDLENBQUMsT0FBTyxDQUFjLEVBQ3pCLFVBQVUsWUFBQSxPQUNULFlBQVksSUFBRyxXQUFXLEVBQzNCLFlBQVMsR0FBRSxJQUFJLENBQUMsRUFBRSxNQUNuQixDQUFDO3dCQUNGLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7NEJBQ3JCLElBQUksT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssVUFBVSxFQUFFLENBQUM7Z0NBQ3ZDLElBQUksQ0FBQyxNQUFNLENBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQzs0QkFDaEMsQ0FBQztpQ0FBTSxDQUFDO2dDQUNOLE9BQU8sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsY0FBYyxDQUFDLENBQUM7NEJBQ3ZELENBQUM7d0JBQ0gsQ0FBQzs2QkFDRyxDQUFDLFVBQVUsRUFBWCx3QkFBVzs2QkFDVCxDQUFBLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUEsRUFBN0Msd0JBQTZDO3dCQUMvQyxxQkFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUE7O3dCQUF6QixTQUF5QixDQUFDOzs7d0JBRTVCLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQzt3QkFDaEMsc0JBQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFtQyxDQUFDLEVBQUM7O3dCQUd4RCxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBTTs0QkFDaEMsSUFBSSxPQUFPLENBQUMsVUFBTyxPQUFPOzs7O2lEQUNwQixDQUFBLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUEsRUFBN0Msd0JBQTZDOzRDQUMvQyxxQkFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUE7OzRDQUF6QixTQUF5QixDQUFDOzs7NENBRTVCLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDOzRDQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUM7Ozs7aUNBQ2pDLENBQUM7NEJBQ0YsSUFBSSxPQUFPLENBQUMsVUFBQyxDQUFDLEVBQUUsTUFBTTtnQ0FDcEIsU0FBUyxHQUFHLFVBQVUsQ0FBQztvQ0FDckIsTUFBTSxFQUFFLENBQUM7Z0NBQ1gsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDOzRCQUNkLENBQUMsQ0FBQzt5QkFDSCxDQUFDLENBQUM7d0JBQ0gsc0JBQU8sT0FBTztpQ0FDWCxJQUFJLENBQUMsVUFBQyxRQUFRO2dDQUNiLHlCQUF5QjtnQ0FDekIsWUFBWSxDQUFDLFNBQTJCLENBQUMsQ0FBQztnQ0FDMUMsS0FBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQ0FDekMsT0FBTyxRQUFRLENBQUM7NEJBQ2xCLENBQUMsQ0FBQztpQ0FDRCxLQUFLLENBQUMsVUFBQyxLQUFLO2dDQUNYLFlBQVksQ0FBQyxTQUEyQixDQUFDLENBQUM7Z0NBQzFDLEtBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7Z0NBQ3pDLElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7b0NBQ2pDLElBQUksUUFBUTt3Q0FBRSxPQUFPO29DQUNyQixPQUFPLENBQUMsSUFBSSxDQUNWLHFCQUFjLE1BQU0sNkJBQW1CLE9BQU8sZ0JBQWEsRUFDM0QsY0FBYyxDQUNmLENBQUM7Z0NBQ0osQ0FBQztxQ0FBTSxDQUFDO29DQUNOLElBQUksT0FBTyxFQUFFLENBQUM7d0NBQ1osTUFBTSxLQUFLLENBQUM7b0NBQ2QsQ0FBQztnQ0FDSCxDQUFDOzRCQUNILENBQUMsQ0FBQyxFQUFDOzs7O0tBQ047SUFDSCxnQkFBQztBQUFELENBQUMsQUE1UkQsSUE0UkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBsaXN0ZW5lcktleSxcbiAgb3JpZ2luYWxMaXN0ZW5zTWFwS2V5LFxuICByZXF1ZXN0c01hcEtleSxcbiAgbGlzdGVuc01hcEtleSxcbiAgc2VuZGVyS2V5LFxuICB0aW1lb3V0S2V5LFxuICB0cmFuc3BvcnRLZXksXG4gIHByZWZpeEtleSxcbiAgdHJhbnNwb3J0VHlwZSxcbiAgcHJvZHVjZUtleSxcbiAgbGlzdGVuS2V5LFxuICBzZXJpYWxpemVyS2V5LFxuICBsb2dLZXksXG4gIHZlcmJvc2VLZXksXG4gIGJlZm9yZUVtaXRLZXksXG4gIGJlZm9yZUVtaXRSZXNvbHZlS2V5LFxufSBmcm9tICcuL2NvbnN0YW50JztcbmltcG9ydCB0eXBlIHtcbiAgRW1pdE9wdGlvbnMsXG4gIElSZXF1ZXN0LFxuICBJUmVzcG9uc2UsXG4gIExpc3RlbmVyT3B0aW9ucyxcbiAgUmVxdWVzdCxcbiAgTGlzdGVuc01hcCxcbiAgUmVzcG9uc2UsXG4gIFRyYW5zcG9ydE9wdGlvbnMsXG4gIEVtaXRQYXJhbWV0ZXIsXG4gIEJhc2VJbnRlcmFjdGlvbixcbn0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgZ2VuZXJhdGVJZCB9IGZyb20gJy4vdXRpbHMnO1xuXG5jb25zdCBERUZBVUxUX1RJTUVPVVQgPSA2MCAqIDEwMDA7XG5jb25zdCBERUZBVUxUX1JFU1BPTkQgPSB0cnVlO1xuY29uc3QgREVGQVVMVF9TSUxFTlQgPSBmYWxzZTtcbmNvbnN0IERFRkFVTFRfUFJFRklYID0gJ0RhdGFUcmFuc3BvcnQnO1xuXG5leHBvcnQgY29uc3QgZ2V0QWN0aW9uID0gKHByZWZpeDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpID0+XG4gIGAke3ByZWZpeH0tJHtuYW1lLnRvU3RyaW5nKCl9YDtcbmNvbnN0IGdldExpc3Rlbk5hbWUgPSAocHJlZml4OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nKSA9PlxuICBhY3Rpb24ucmVwbGFjZShuZXcgUmVnRXhwKGBeJHtwcmVmaXh9LWApLCAnJyk7XG5cbi8qKlxuICogQ3JlYXRlIGEgYmFzZSB0cmFuc3BvcnRcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRyYW5zcG9ydDxUIGV4dGVuZHMgQmFzZUludGVyYWN0aW9uID0gYW55PiB7XG4gIHByaXZhdGUgW2xpc3RlbmVyS2V5XTogVHJhbnNwb3J0T3B0aW9uc1snbGlzdGVuZXInXTtcbiAgcHJpdmF0ZSBbbGlzdGVuS2V5XTogKG9wdGlvbnM/OiBMaXN0ZW5lck9wdGlvbnMpID0+IHZvaWQ7XG4gIHByaXZhdGUgW3NlbmRlcktleV06IFRyYW5zcG9ydE9wdGlvbnNbJ3NlbmRlciddO1xuICBwcml2YXRlIFt0aW1lb3V0S2V5XTogVHJhbnNwb3J0T3B0aW9uc1sndGltZW91dCddO1xuICBwcml2YXRlIFtwcmVmaXhLZXldOiBUcmFuc3BvcnRPcHRpb25zWydwcmVmaXgnXTtcbiAgcHJpdmF0ZSBbc2VyaWFsaXplcktleV06IFRyYW5zcG9ydE9wdGlvbnNbJ3NlcmlhbGl6ZXInXTtcbiAgcHJpdmF0ZSBbcmVxdWVzdHNNYXBLZXldOiBNYXA8c3RyaW5nLCAodmFsdWU6IHVua25vd24pID0+IHZvaWQ+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIFtsaXN0ZW5zTWFwS2V5XSE6IExpc3RlbnNNYXA7XG4gIHByaXZhdGUgW29yaWdpbmFsTGlzdGVuc01hcEtleV0hOiBNYXA8c3RyaW5nLCBGdW5jdGlvbj47XG4gIHByaXZhdGUgW2xvZ0tleV0/OiAobGlzdGVuT3B0aW9uczogTGlzdGVuZXJPcHRpb25zPGFueT4pID0+IHZvaWQ7XG4gIHByaXZhdGUgW3ZlcmJvc2VLZXldOiBib29sZWFuO1xuICBwcm90ZWN0ZWQgW2JlZm9yZUVtaXRLZXldPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJvdGVjdGVkIFtiZWZvcmVFbWl0UmVzb2x2ZUtleV0/OiAoKSA9PiB2b2lkO1xuICAvKipcbiAgICogZGlzcG9zZSB0cmFuc3BvcnRcbiAgICovXG4gIHB1YmxpYyBkaXNwb3NlOiAoKSA9PiBhbnk7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGxpc3RlbmVyLFxuICAgIHNlbmRlcixcbiAgICB0aW1lb3V0ID0gREVGQVVMVF9USU1FT1VULFxuICAgIHZlcmJvc2UgPSBmYWxzZSxcbiAgICBwcmVmaXggPSBERUZBVUxUX1BSRUZJWCxcbiAgICBsaXN0ZW5LZXlzID0gW10sXG4gICAgY2hlY2tMaXN0ZW4gPSB0cnVlLFxuICAgIHNlcmlhbGl6ZXIsXG4gICAgbG9nZ2VyLFxuICB9OiBUcmFuc3BvcnRPcHRpb25zKSB7XG4gICAgdGhpc1tsaXN0ZW5zTWFwS2V5XSA9IHRoaXNbbGlzdGVuc01hcEtleV0gPz8gbmV3IE1hcCgpO1xuICAgIHRoaXNbb3JpZ2luYWxMaXN0ZW5zTWFwS2V5XSA9IHRoaXNbb3JpZ2luYWxMaXN0ZW5zTWFwS2V5XSA/PyBuZXcgTWFwKCk7XG4gICAgdGhpc1tsaXN0ZW5lcktleV0gPSBsaXN0ZW5lci5iaW5kKHRoaXMpO1xuICAgIHRoaXNbc2VuZGVyS2V5XSA9IHNlbmRlci5iaW5kKHRoaXMpO1xuICAgIHRoaXNbdGltZW91dEtleV0gPSB0aW1lb3V0O1xuICAgIHRoaXNbcHJlZml4S2V5XSA9IHByZWZpeDtcbiAgICB0aGlzW3NlcmlhbGl6ZXJLZXldID0gc2VyaWFsaXplcjtcbiAgICB0aGlzW3ZlcmJvc2VLZXldID0gdmVyYm9zZTtcbiAgICB0aGlzW2xvZ0tleV0gPSBsb2dnZXI7XG5cbiAgICBuZXcgU2V0KGxpc3RlbktleXMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY29uc3QgZm4gPSAodGhpcyBhcyBhbnkgYXMgUmVjb3JkPHN0cmluZywgRnVuY3Rpb24+KVtrZXldO1xuICAgICAgaWYgKF9fREVWX18pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGNvbnNvbGUud2FybihgJyR7a2V5fScgaXMgTk9UIGEgbWV0aG9kcyBvciBmdW5jdGlvbi5gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpc1tvcmlnaW5hbExpc3RlbnNNYXBLZXldLnNldChrZXksIGZuKTtcbiAgICAgIE9iamVjdC5hc3NpZ24odGhpcywge1xuICAgICAgICBba2V5XSgpIHtcbiAgICAgICAgICBpZiAoX19ERVZfXykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgVGhlIG1ldGhvZCAnJHtrZXl9JyBpcyBhIGxpc3RlbiBmdW5jdGlvbiB0aGF0IGNhbiBOT1QgYmUgYWN0aXZlbHkgY2FsbGVkLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzW29yaWdpbmFsTGlzdGVuc01hcEtleV0uZm9yRWFjaCgodmFsdWUsIG5hbWUpID0+IHtcbiAgICAgIHRoaXNbcHJvZHVjZUtleV0obmFtZSwgdmFsdWUpO1xuICAgIH0pO1xuXG4gICAgdGhpc1tsaXN0ZW5LZXldID0gKG9wdGlvbnM/OiBMaXN0ZW5lck9wdGlvbnMpID0+IHtcbiAgICAgIGlmICh0aGlzW3ZlcmJvc2VLZXldKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpc1tsb2dLZXldID09PSAnZnVuY3Rpb24nICYmIG9wdGlvbnMpIHtcbiAgICAgICAgICB0aGlzW2xvZ0tleV0hKG9wdGlvbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuaW5mbygnRGF0YVRyYW5zcG9ydCBSZWNlaXZlOiAnLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnM/Llt0cmFuc3BvcnRLZXldKSB7XG4gICAgICAgIGNvbnN0IGxpc3Rlbk5hbWUgPSBnZXRMaXN0ZW5OYW1lKHRoaXNbcHJlZml4S2V5XSEsIG9wdGlvbnMuYWN0aW9uKTtcbiAgICAgICAgY29uc3QgaGFzTGlzdGVuID0gdHlwZW9mICh0aGlzIGFzIGFueSlbbGlzdGVuTmFtZV0gPT09ICdmdW5jdGlvbic7XG4gICAgICAgIGlmICgob3B0aW9ucyBhcyBJUmVzcG9uc2UpLnR5cGUgPT09IHRyYW5zcG9ydFR5cGUucmVzcG9uc2UpIHtcbiAgICAgICAgICBjb25zdCByZXNvbHZlID0gdGhpc1tyZXF1ZXN0c01hcEtleV0uZ2V0KG9wdGlvbnNbdHJhbnNwb3J0S2V5XSk7XG4gICAgICAgICAgaWYgKHJlc29sdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgcmVzcG9uc2UgfSA9IG9wdGlvbnMgYXMgSVJlc3BvbnNlO1xuICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgdHlwZW9mIHJlc3BvbnNlID09PSAnc3RyaW5nJyAmJiB0aGlzW3NlcmlhbGl6ZXJLZXldPy5wYXJzZVxuICAgICAgICAgICAgICAgID8gdGhpc1tzZXJpYWxpemVyS2V5XSEucGFyc2UhKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIDogcmVzcG9uc2VcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChoYXNMaXN0ZW4pIHtcbiAgICAgICAgICAgIGlmIChfX0RFVl9fICYmIGNoZWNrTGlzdGVuKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICBgVGhlIHR5cGUgJyR7b3B0aW9ucy5hY3Rpb259JyBldmVudCAnJHtvcHRpb25zW3RyYW5zcG9ydEtleV19JyBoYXMgYmVlbiByZXNvbHZlZC4gUGxlYXNlIGNoZWNrIGZvciBhIGR1cGxpY2F0ZSByZXNwb25zZS5gXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKChvcHRpb25zIGFzIElSZXF1ZXN0KS50eXBlID09PSB0cmFuc3BvcnRUeXBlLnJlcXVlc3QpIHtcbiAgICAgICAgICBjb25zdCByZXNwb25kID0gdGhpc1tsaXN0ZW5zTWFwS2V5XS5nZXQob3B0aW9ucy5hY3Rpb24pO1xuICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29uc3QgeyByZXF1ZXN0IH0gPSBvcHRpb25zIGFzIElSZXF1ZXN0O1xuICAgICAgICAgICAgcmVzcG9uZChcbiAgICAgICAgICAgICAgdHlwZW9mIHJlcXVlc3QgPT09ICdzdHJpbmcnICYmIHRoaXNbc2VyaWFsaXplcktleV0/LnBhcnNlXG4gICAgICAgICAgICAgICAgPyB0aGlzW3NlcmlhbGl6ZXJLZXldIS5wYXJzZSEocmVxdWVzdClcbiAgICAgICAgICAgICAgICA6IHJlcXVlc3QsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgICAgIHRyYW5zcG9ydElkOiBvcHRpb25zW3RyYW5zcG9ydEtleV0sXG4gICAgICAgICAgICAgICAgaGFzUmVzcG9uZDogKG9wdGlvbnMgYXMgSVJlcXVlc3QpLmhhc1Jlc3BvbmQsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChoYXNMaXN0ZW4pIHtcbiAgICAgICAgICAgIGlmIChfX0RFVl9fICYmIGNoZWNrTGlzdGVuKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgYFRoZSBsaXN0ZW4gbWV0aG9kIG9yIGZ1bmN0aW9uICcke2xpc3Rlbk5hbWV9JyBpcyBOT1QgZGVjb3JhdGVkIGJ5IGRlY29yYXRvciAnQGxpc3Rlbicgb3IgYmUgYWRkZWQgJ2xpc3RlbktleXMnIGxpc3QuYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBkaXNwb3NlID0gdGhpc1tsaXN0ZW5lcktleV0odGhpc1tsaXN0ZW5LZXldKTtcblxuICAgIHRoaXMuZGlzcG9zZSA9ICgpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzW3JlcXVlc3RzTWFwS2V5XS5jbGVhcigpO1xuICAgICAgICB0aGlzW2xpc3RlbnNNYXBLZXldLmNsZWFyKCk7XG4gICAgICAgIHRoaXNbb3JpZ2luYWxMaXN0ZW5zTWFwS2V5XS5jbGVhcigpO1xuICAgICAgICByZXR1cm4gZGlzcG9zZSgpO1xuICAgICAgfSBlbHNlIGlmIChfX0RFVl9fKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgVGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgdGhlICcke3RoaXMuY29uc3RydWN0b3IubmFtZX0nIHRyYW5zcG9ydCdzIGxpc3RlbmVyIHNob3VsZCBiZSBhICdkaXNwb3NlJyBmdW5jdGlvbiBmb3IgcmVtb3ZpbmcgdGhlIGxpc3RlbmVyYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIFtwcm9kdWNlS2V5XTxLIGV4dGVuZHMgc3RyaW5nLCBQIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgRnVuY3Rpb24+PihcbiAgICBuYW1lOiBLLFxuICAgIGZuOiBQW0tdXG4gICkge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvNDA0NjVcbiAgICBjb25zdCBhY3Rpb24gPSBnZXRBY3Rpb24odGhpc1twcmVmaXhLZXldISwgbmFtZSk7XG4gICAgdGhpc1tsaXN0ZW5zTWFwS2V5XS5zZXQoXG4gICAgICBhY3Rpb24sXG4gICAgICBhc3luYyAocmVxdWVzdCwgeyBoYXNSZXNwb25kLCB0cmFuc3BvcnRJZCwgcmVxdWVzdDogXywgLi4uYXJncyB9KSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBjb25zdCByZXNwb25zZTogUmVzcG9uc2U8UFtLXT4gPSBhd2FpdCBmbi5hcHBseSh0aGlzLCByZXF1ZXN0KTtcbiAgICAgICAgICBpZiAoIWhhc1Jlc3BvbmQpIHJldHVybjtcbiAgICAgICAgICBjb25zdCBkYXRhOiBJUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICAuLi5hcmdzLFxuICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgcmVzcG9uc2U6ICh0eXBlb2YgcmVzcG9uc2UgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICB0aGlzW3NlcmlhbGl6ZXJLZXldPy5zdHJpbmdpZnlcbiAgICAgICAgICAgICAgPyB0aGlzW3NlcmlhbGl6ZXJLZXldIS5zdHJpbmdpZnkhKHJlc3BvbnNlKVxuICAgICAgICAgICAgICA6IHJlc3BvbnNlKSBhcyBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICAgICAgICBoYXNSZXNwb25kLFxuICAgICAgICAgICAgW3RyYW5zcG9ydEtleV06IHRyYW5zcG9ydElkLFxuICAgICAgICAgICAgdHlwZTogdHJhbnNwb3J0VHlwZS5yZXNwb25zZSxcbiAgICAgICAgICAgIHJlc3BvbnNlSWQ6IHRoaXMuaWQsXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzW3NlbmRlcktleV0oZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFRoZSBsaXN0ZW5lciBmb3IgZXZlbnQgJHtuYW1lfSBzaG91bGQgYmUgYSBmdW5jdGlvbi5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuIGFuIGV2ZW50IHRoYXQgdHJhbnNwb3J0IGRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIEEgdHJhbnNwb3J0IGFjdGlvbiBhcyBsaXN0ZW4gbWVzc2FnZSBkYXRhIGFjdGlvbiB0eXBlXG4gICAqIEBwYXJhbSBmbiBBIHRyYW5zcG9ydCBsaXN0ZW5lclxuICAgKi9cbiAgcHVibGljIGxpc3RlbjxLIGV4dGVuZHMga2V5b2YgVFsnbGlzdGVuJ10+KG5hbWU6IEssIGZuOiBUWydsaXN0ZW4nXVtLXSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICh0aGlzW29yaWdpbmFsTGlzdGVuc01hcEtleV0uZ2V0KG5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgRmFpbGVkIHRvIGxpc3RlbiB0byB0aGUgZXZlbnQgXCIke25hbWV9XCIsIHRoZSBldmVudCBcIiR7bmFtZX1cIiBpcyBhbHJlYWR5IGxpc3RlbmVkIHRvLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpc1tvcmlnaW5hbExpc3RlbnNNYXBLZXldLnNldChuYW1lLCBmbik7XG4gICAgICAgIHRoaXNbcHJvZHVjZUtleV0obmFtZSwgZm4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgbGlzdGVuZXIgZm9yIGV2ZW50ICR7bmFtZX0gc2hvdWxkIGJlIGEgZnVuY3Rpb24uYCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoZSBldmVudCBuYW1lIFwiJHtuYW1lLnRvU3RyaW5nKCl9XCIgaXMgbm90IGEgc3RyaW5nLCBpdCBzaG91bGQgYmUgYSBzdHJpbmcuYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHRoaXNbb3JpZ2luYWxMaXN0ZW5zTWFwS2V5XS5kZWxldGUobmFtZSk7XG4gICAgICBjb25zdCBhY3Rpb24gPSBnZXRBY3Rpb24odGhpc1twcmVmaXhLZXldISwgbmFtZSk7XG4gICAgICB0aGlzW2xpc3RlbnNNYXBLZXldLmRlbGV0ZShhY3Rpb24pO1xuICAgIH07XG4gIH1cblxuICBwdWJsaWMgaWQgPSBnZW5lcmF0ZUlkKCk7XG5cbiAgLyoqXG4gICAqIEVtaXQgYW4gZXZlbnQgdGhhdCB0cmFuc3BvcnQgZGF0YS5cbiAgICpcbiAgICogQHBhcmFtIGVtaXRPcHRpb25zIEEgb3B0aW9uIGZvciB0aGUgdHJhbnNwb3J0IGRhdGFcbiAgICogQHBhcmFtIHJlcXVlc3QgQSByZXF1ZXN0IGRhdGFcbiAgICpcbiAgICogQHJldHVybnMgUmV0dXJuIGEgcmVzcG9uc2UgZm9yIHRoZSByZXF1ZXN0LlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGVtaXQ8SyBleHRlbmRzIGtleW9mIFRbJ2VtaXQnXT4oXG4gICAgb3B0aW9uczogRW1pdE9wdGlvbnM8Sz4sXG4gICAgLi4ucmVxdWVzdDogUmVxdWVzdDxUWydlbWl0J11bS10+XG4gICk6IFByb21pc2U8UmVzcG9uc2U8VFsnZW1pdCddW0tdPj4ge1xuICAgIGNvbnN0IHBhcmFtcyA9XG4gICAgICB0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgPyBvcHRpb25zIDogKHt9IGFzIEVtaXRQYXJhbWV0ZXI8Sz4pO1xuICAgIGNvbnN0IGhhc1Jlc3BvbmQgPSBwYXJhbXMucmVzcG9uZCA/PyBERUZBVUxUX1JFU1BPTkQ7XG4gICAgY29uc3QgaXNTaWxlbnQgPSBwYXJhbXMuc2lsZW50ID8/IERFRkFVTFRfU0lMRU5UO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBwYXJhbXMudGltZW91dCA/PyB0aGlzW3RpbWVvdXRLZXldO1xuICAgIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZSA/PyBvcHRpb25zO1xuICAgIGNvbnN0IHRyYW5zcG9ydElkID0gZ2VuZXJhdGVJZCgpO1xuICAgIGlmIChfX0RFVl9fICYmICghbmFtZSB8fCB0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBldmVudCBuYW1lIHNob3VsZCBiZSBhIHN0cmluZywgYW5kIGl0J3MgcmVxdWlyZWQuYCk7XG4gICAgfVxuICAgIGNvbnN0IGFjdGlvbiA9IGdldEFjdGlvbih0aGlzW3ByZWZpeEtleV0hLCBuYW1lIGFzIHN0cmluZyk7XG4gICAgY29uc3QgcmF3UmVxdWVzdERhdGE6IElSZXF1ZXN0ID0ge1xuICAgICAgLi4uKHBhcmFtcy5fZXh0cmEgPyB7IF9leHRyYTogcGFyYW1zLl9leHRyYSB9IDoge30pLFxuICAgICAgdHlwZTogdHJhbnNwb3J0VHlwZS5yZXF1ZXN0LFxuICAgICAgYWN0aW9uLFxuICAgICAgcmVxdWVzdDogKHR5cGVvZiByZXF1ZXN0ICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzW3NlcmlhbGl6ZXJLZXldPy5zdHJpbmdpZnlcbiAgICAgICAgPyB0aGlzW3NlcmlhbGl6ZXJLZXldIS5zdHJpbmdpZnkhKHJlcXVlc3QpXG4gICAgICAgIDogcmVxdWVzdCkgYXMgdW5rbm93bltdLFxuICAgICAgaGFzUmVzcG9uZCxcbiAgICAgIFt0cmFuc3BvcnRLZXldOiB0cmFuc3BvcnRJZCxcbiAgICAgIHJlcXVlc3RJZDogdGhpcy5pZCxcbiAgICB9O1xuICAgIGlmICh0aGlzW3ZlcmJvc2VLZXldKSB7XG4gICAgICBpZiAodHlwZW9mIHRoaXNbbG9nS2V5XSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzW2xvZ0tleV0hKHJhd1JlcXVlc3REYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnRGF0YVRyYW5zcG9ydCBTZW5kOiAnLCByYXdSZXF1ZXN0RGF0YSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghaGFzUmVzcG9uZCkge1xuICAgICAgaWYgKHRoaXNbYmVmb3JlRW1pdEtleV0gJiYgIXBhcmFtcy5za2lwQmVmb3JlRW1pdCkge1xuICAgICAgICBhd2FpdCB0aGlzW2JlZm9yZUVtaXRLZXldO1xuICAgICAgfVxuICAgICAgdGhpc1tzZW5kZXJLZXldKHJhd1JlcXVlc3REYXRhKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodW5kZWZpbmVkIGFzIFJlc3BvbnNlPFRbJ2VtaXQnXVtLXT4pO1xuICAgIH1cbiAgICBsZXQgdGltZW91dElkOiBOb2RlSlMuVGltZW91dCB8IG51bWJlcjtcbiAgICBjb25zdCBwcm9taXNlID0gUHJvbWlzZS5yYWNlPGFueT4oW1xuICAgICAgbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUpID0+IHtcbiAgICAgICAgaWYgKHRoaXNbYmVmb3JlRW1pdEtleV0gJiYgIXBhcmFtcy5za2lwQmVmb3JlRW1pdCkge1xuICAgICAgICAgIGF3YWl0IHRoaXNbYmVmb3JlRW1pdEtleV07XG4gICAgICAgIH1cbiAgICAgICAgdGhpc1tyZXF1ZXN0c01hcEtleV0uc2V0KHRyYW5zcG9ydElkLCByZXNvbHZlKTtcbiAgICAgICAgdGhpc1tzZW5kZXJLZXldKHJhd1JlcXVlc3REYXRhKTtcbiAgICAgIH0pLFxuICAgICAgbmV3IFByb21pc2UoKF8sIHJlamVjdCkgPT4ge1xuICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICByZWplY3QoKTtcbiAgICAgICAgfSwgdGltZW91dCk7XG4gICAgICB9KSxcbiAgICBdKTtcbiAgICByZXR1cm4gcHJvbWlzZVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIC8vIHN1cHBvcnQgU2FmYXJpIDEwLTExLjFcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCBhcyBOb2RlSlMuVGltZW91dCk7XG4gICAgICAgIHRoaXNbcmVxdWVzdHNNYXBLZXldLmRlbGV0ZSh0cmFuc3BvcnRJZCk7XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQgYXMgTm9kZUpTLlRpbWVvdXQpO1xuICAgICAgICB0aGlzW3JlcXVlc3RzTWFwS2V5XS5kZWxldGUodHJhbnNwb3J0SWQpO1xuICAgICAgICBpZiAodHlwZW9mIGVycm9yID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGlmIChpc1NpbGVudCkgcmV0dXJuO1xuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIGBUaGUgZXZlbnQgJyR7YWN0aW9ufScgdGltZWQgb3V0IGZvciAke3RpbWVvdXR9IHNlY29uZHMuLi5gLFxuICAgICAgICAgICAgcmF3UmVxdWVzdERhdGFcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG4iXX0=