UNPKG

@synerty/vortexjs

Version:

Custom observable data serialisation and routing based on Angular 2+

170 lines 22.2 kB
import { bind, dateStr, getFiltStr } from "./UtilMisc"; import { VortexClientABC } from "./VortexClientABC"; import { PayloadEnvelope } from "./PayloadEnvelope"; export class VortexClientHttp extends VortexClientABC { /** * RapUI VortexService, This class is responsible for sending and receiving payloads to/from * the server. */ lastConn = null; constructor(vortexStatusService, url, vortexClientName) { super(vortexStatusService, url, vortexClientName); } shutdown() { if (this.lastConn) { this.lastConn.shutdown(); this.lastConn = null; } return Promise.resolve(); } setClosedByConnection() { this.setClosed(); } sendVortexMsg(vortexMsgs) { this.lastConn = new _VortexClientHttpConnection(this, this.vortexStatusService, (payload) => this.receive(payload), () => this.beat()); this.lastConn.send(vortexMsgs); // console.log(dateStr() + "Sent payload with filt : " + JSON.stringify(payload.filt)); } } // ############################################################################ class _VortexClientHttpConnection { vortex; vortexStatusService; receiveCallback; vortexBeatCallback; static RECONNECT_SIZE_LIMIT = 20 * 1024 * 1024; // 20 megabytes _vortex; _http; _updateTimer; _responseParseIndex; _closing; _aborting; constructor(vortex, vortexStatusService, receiveCallback, vortexBeatCallback) { this.vortex = vortex; this.vortexStatusService = vortexStatusService; this.receiveCallback = receiveCallback; this.vortexBeatCallback = vortexBeatCallback; let self = this; let randArg = Math.random() + "." + new Date().getTime(); let args = { vortexUuid: vortex.uuid, vortexName: vortex.name, __randArg__: randArg, }; self._http = new XMLHttpRequest(); self._http.open("POST", self.vortex.url + getFiltStr(args), true); self._updateTimer = null; // Good events self._http.onloadstart = function (e) { self._received(); // Force a 50-millisecond timer, as some browsers don't call "onprogress" // very often. self._updateTimer = setInterval(function () { self._received(); }, 50); }; self._http.onprogress = function (e) { self._received(); }; self._http.onload = function (e) { if (self._updateTimer) clearInterval(self._updateTimer); self._received(); }; // Bad events self._http.onabort = bind(self, self._error); self._http.onerror = bind(self, self._error); self._http.ontimeout = bind(self, self._error); self._responseParseIndex = 0; self._closing = false; self._aborting = false; } shutdown() { this._closing = true; if (this._http) this._http.abort(); } send(vortexMsgs) { let data = ""; for (let vortexMsg of vortexMsgs) { // Serialise the payload data += vortexMsg + "."; } // console.log("sending payload"); // console.log(xmlStr); this._http.send(data); } _received() { let self = this; /* * Received * * Called when progress is made on receiving data from the vortex server. * * This means that it needs to be able to handle : * partial payloads (in * which case it does nothing) * multiple payloads (in which case, it breaks * them up, parses them and sends them to vortex individually) */ if (self._aborting) return; // If we receive something that is not valid vortex data, then reload the page // This typically occurs when we're receving HTML because we're not logged in. if (/^</.test(self._http.responseText)) { self.vortex.setClosedByConnection(); self._closing = true; self._aborting = true; self._http.abort(); location.reload(); return; } // Split out the payloads of data, they are delimited by a '.' let data = self._http.responseText.substr(self._responseParseIndex); let payloadSeparatorIndex = data.indexOf("."); while (payloadSeparatorIndex !== -1) { self._responseParseIndex += payloadSeparatorIndex + 1; // Get the b64encoded string let vortexStr = data.substr(0, payloadSeparatorIndex); if (vortexStr.length === 0) { self.vortexBeatCallback(); } else { // Create payload object from it // Send to vortex PayloadEnvelope.fromVortexMsg(vortexStr) .then((pe) => self.receiveCallback(pe)) .catch((e) => console.log(`${dateStr()} An error occured deserialising ${e}`)); } data = self._http.responseText.substr(self._responseParseIndex); payloadSeparatorIndex = data.indexOf("."); } // In the event that the browser is buffering all this data, we should // reconnect to allow the browser to cleanup. if (self._http.responseText.length >= _VortexClientHttpConnection.RECONNECT_SIZE_LIMIT && !self._closing) { self._closing = true; self.vortex.reconnect(); } } _error(e) { let self = this; if (self._updateTimer) clearInterval(self._updateTimer); if (self._aborting || this._closing) return; let msg = ""; if (e.type === "abort") { msg = "Request was aborted and not by VortexJS"; } else { try { msg = e.toString(); } catch (e) { } } this.vortexStatusService.setOnline(false); this.vortexStatusService.logError(msg); // console.log("VortexConnection, connection errored out: " + msg); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVm9ydGV4Q2xpZW50SHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy92b3J0ZXgvVm9ydGV4Q2xpZW50SHR0cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXBELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQVVwRCxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsZUFBZTtJQUNqRDs7O09BR0c7SUFDSyxRQUFRLEdBQXVDLElBQUksQ0FBQztJQUU1RCxZQUNJLG1CQUF3QyxFQUN4QyxHQUFXLEVBQ1gsZ0JBQXdCO1FBRXhCLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRVMsUUFBUTtRQUNkLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7U0FDeEI7UUFDRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQscUJBQXFCO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRVMsYUFBYSxDQUFDLFVBQW9CO1FBQ3hDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSwyQkFBMkIsQ0FDM0MsSUFBSSxFQUNKLElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQ2xDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FDcEIsQ0FBQztRQUNGLElBQUks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QUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV4RCxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBRTVDLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUViLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDcEIsR0FBRyxHQUFHLHlDQUF5QyxDQUFDO1NBQ25EO2FBQU07WUFDSCxJQUFJO2dCQUNBLEdBQUcsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7YUFDdEI7WUFBQyxPQUFPLENBQUMsRUFBRSxHQUFFO1NBQ2pCO1FBRUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLG1FQUFtRTtJQUN2RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYmluZCwgZGF0ZVN0ciwgZ2V0RmlsdFN0ciB9IGZyb20gXCIuL1V0aWxNaXNjXCI7XG5pbXBvcnQgeyBWb3J0ZXhDbGllbnRBQkMgfSBmcm9tIFwiLi9Wb3J0ZXhDbGllbnRBQkNcIjtcbmltcG9ydCB7IFZvcnRleFN0YXR1c1NlcnZpY2UgfSBmcm9tIFwiLi9Wb3J0ZXhTdGF0dXNTZXJ2aWNlXCI7XG5pbXBvcnQgeyBQYXlsb2FkRW52ZWxvcGUgfSBmcm9tIFwiLi9QYXlsb2FkRW52ZWxvcGVcIjtcblxuaW50ZXJmYWNlIFJlY2VpdmVQYXlsb2FkQ2FsbGFibGUge1xuICAgIChQYXlsb2FkKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIFZvcnRleEJlYXRDYWxsYWJsZSB7XG4gICAgKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBWb3J0ZXhDbGllbnRIdHRwIGV4dGVuZHMgVm9ydGV4Q2xpZW50QUJDIHtcbiAgICAvKipcbiAgICAgKiBSYXBVSSBWb3J0ZXhTZXJ2aWNlLCBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzZW5kaW5nIGFuZCByZWNlaXZpbmcgcGF5bG9hZHMgdG8vZnJvbVxuICAgICAqIHRoZSBzZXJ2ZXIuXG4gICAgICovXG4gICAgcHJpdmF0ZSBsYXN0Q29ubjogX1ZvcnRleENsaWVudEh0dHBDb25uZWN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgdm9ydGV4U3RhdHVzU2VydmljZTogVm9ydGV4U3RhdHVzU2VydmljZSxcbiAgICAgICAgdXJsOiBzdHJpbmcsXG4gICAgICAgIHZvcnRleENsaWVudE5hbWU6IHN0cmluZ1xuICAgICkge1xuICAgICAgICBzdXBlcih2b3J0ZXhTdGF0dXNTZXJ2aWNlLCB1cmwsIHZvcnRleENsaWVudE5hbWUpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMubGFzdENvbm4pIHtcbiAgICAgICAgICAgIHRoaXMubGFzdENvbm4uc2h1dGRvd24oKTtcbiAgICAgICAgICAgIHRoaXMubGFzdENvbm4gPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBzZXRDbG9zZWRCeUNvbm5lY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc2V0Q2xvc2VkKCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNlbmRWb3J0ZXhNc2codm9ydGV4TXNnczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sYXN0Q29ubiA9IG5ldyBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24oXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgdGhpcy52b3J0ZXhTdGF0dXNTZXJ2aWNlLFxuICAgICAgICAgICAgKHBheWxvYWQpID0+IHRoaXMucmVjZWl2ZShwYXlsb2FkKSxcbiAgICAgICAgICAgICgpID0+IHRoaXMuYmVhdCgpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubGFzdENvbm4uc2VuZCh2b3J0ZXhNc2dzKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coZGF0ZVN0cigpICsgXCJTZW50IHBheWxvYWQgd2l0aCBmaWx0IDogXCIgKyBKU09OLnN0cmluZ2lmeShwYXlsb2FkLmZpbHQpKTtcbiAgICB9XG59XG5cbi8vICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbmNsYXNzIF9Wb3J0ZXhDbGllbnRIdHRwQ29ubmVjdGlvbiB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUkVDT05ORUNUX1NJWkVfTElNSVQgPSAyMCAqIDEwMjQgKiAxMDI0OyAvLyAyMCBtZWdhYnl0ZXNcblxuICAgIHByaXZhdGUgX3ZvcnRleDogVm9ydGV4Q2xpZW50SHR0cDtcbiAgICBwcml2YXRlIF9odHRwOiBYTUxIdHRwUmVxdWVzdDtcbiAgICBwcml2YXRlIF91cGRhdGVUaW1lcjogYW55O1xuICAgIHByaXZhdGUgX3Jlc3BvbnNlUGFyc2VJbmRleDogbnVtYmVyO1xuICAgIHByaXZhdGUgX2Nsb3Npbmc6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBfYWJvcnRpbmc6IGJvb2xlYW47XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSB2b3J0ZXg6IFZvcnRleENsaWVudEh0dHAsXG4gICAgICAgIHByaXZhdGUgdm9ydGV4U3RhdHVzU2VydmljZTogVm9ydGV4U3RhdHVzU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWNlaXZlQ2FsbGJhY2s6IFJlY2VpdmVQYXlsb2FkQ2FsbGFibGUsXG4gICAgICAgIHByaXZhdGUgdm9ydGV4QmVhdENhbGxiYWNrOiBWb3J0ZXhCZWF0Q2FsbGFibGVcbiAgICApIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGxldCByYW5kQXJnID0gTWF0aC5yYW5kb20oKSArIFwiLlwiICsgbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGxldCBhcmdzID0ge1xuICAgICAgICAgICAgdm9ydGV4VXVpZDogdm9ydGV4LnV1aWQsXG4gICAgICAgICAgICB2b3J0ZXhOYW1lOiB2b3J0ZXgubmFtZSxcbiAgICAgICAgICAgIF9fcmFuZEFyZ19fOiByYW5kQXJnLFxuICAgICAgICB9O1xuXG4gICAgICAgIHNlbGYuX2h0dHAgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgc2VsZi5faHR0cC5vcGVuKFwiUE9TVFwiLCBzZWxmLnZvcnRleC51cmwgKyBnZXRGaWx0U3RyKGFyZ3MpLCB0cnVlKTtcblxuICAgICAgICBzZWxmLl91cGRhdGVUaW1lciA9IG51bGw7XG5cbiAgICAgICAgLy8gR29vZCBldmVudHNcbiAgICAgICAgc2VsZi5faHR0cC5vbmxvYWRzdGFydCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuXG4gICAgICAgICAgICAvLyBGb3JjZSBhIDUwLW1pbGxpc2Vjb25kIHRpbWVyLCBhcyBzb21lIGJyb3dzZXJzIGRvbid0IGNhbGwgXCJvbnByb2dyZXNzXCJcbiAgICAgICAgICAgIC8vIHZlcnkgb2Z0ZW4uXG4gICAgICAgICAgICBzZWxmLl91cGRhdGVUaW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuICAgICAgICAgICAgfSwgNTApO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNlbGYuX2h0dHAub25wcm9ncmVzcyA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNlbGYuX2h0dHAub25sb2FkID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmIChzZWxmLl91cGRhdGVUaW1lcikgY2xlYXJJbnRlcnZhbChzZWxmLl91cGRhdGVUaW1lcik7XG4gICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEJhZCBldmVudHNcbiAgICAgICAgc2VsZi5faHR0cC5vbmFib3J0ID0gYmluZChzZWxmLCBzZWxmLl9lcnJvcik7XG4gICAgICAgIHNlbGYuX2h0dHAub25lcnJvciA9IGJpbmQoc2VsZiwgc2VsZi5fZXJyb3IpO1xuICAgICAgICBzZWxmLl9odHRwLm9udGltZW91dCA9IGJpbmQoc2VsZiwgc2VsZi5fZXJyb3IpO1xuXG4gICAgICAgIHNlbGYuX3Jlc3BvbnNlUGFyc2VJbmRleCA9IDA7XG4gICAgICAgIHNlbGYuX2Nsb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgc2VsZi5fYWJvcnRpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fY2xvc2luZyA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLl9odHRwKSB0aGlzLl9odHRwLmFib3J0KCk7XG4gICAgfVxuXG4gICAgc2VuZCh2b3J0ZXhNc2dzOiBzdHJpbmdbXSkge1xuICAgICAgICBsZXQgZGF0YSA9IFwiXCI7XG5cbiAgICAgICAgZm9yIChsZXQgdm9ydGV4TXNnIG9mIHZvcnRleE1zZ3MpIHtcbiAgICAgICAgICAgIC8vIFNlcmlhbGlzZSB0aGUgcGF5bG9hZFxuICAgICAgICAgICAgZGF0YSArPSB2b3J0ZXhNc2cgKyBcIi5cIjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwic2VuZGluZyBwYXlsb2FkXCIpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyh4bWxTdHIpO1xuICAgICAgICB0aGlzLl9odHRwLnNlbmQoZGF0YSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVjZWl2ZWQoKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcbiAgICAgICAgLypcbiAgICAgICAgICogUmVjZWl2ZWRcbiAgICAgICAgICpcbiAgICAgICAgICogQ2FsbGVkIHdoZW4gcHJvZ3Jlc3MgaXMgbWFkZSBvbiByZWNlaXZpbmcgZGF0YSBmcm9tIHRoZSB2b3J0ZXggc2VydmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIG1lYW5zIHRoYXQgaXQgbmVlZHMgdG8gYmUgYWJsZSB0byBoYW5kbGUgOiAqIHBhcnRpYWwgcGF5bG9hZHMgKGluXG4gICAgICAgICAqIHdoaWNoIGNhc2UgaXQgZG9lcyBub3RoaW5nKSAqIG11bHRpcGxlIHBheWxvYWRzIChpbiB3aGljaCBjYXNlLCBpdCBicmVha3NcbiAgICAgICAgICogdGhlbSB1cCwgcGFyc2VzIHRoZW0gYW5kIHNlbmRzIHRoZW0gdG8gdm9ydGV4IGluZGl2aWR1YWxseSlcbiAgICAgICAgICovXG5cbiAgICAgICAgaWYgKHNlbGYuX2Fib3J0aW5nKSByZXR1cm47XG5cbiAgICAgICAgLy8gSWYgd2UgcmVjZWl2ZSBzb21ldGhpbmcgdGhhdCBpcyBub3QgdmFsaWQgdm9ydGV4IGRhdGEsIHRoZW4gcmVsb2FkIHRoZSBwYWdlXG4gICAgICAgIC8vIFRoaXMgdHlwaWNhbGx5IG9jY3VycyB3aGVuIHdlJ3JlIHJlY2V2aW5nIEhUTUwgYmVjYXVzZSB3ZSdyZSBub3QgbG9nZ2VkIGluLlxuICAgICAgICBpZiAoL148Ly50ZXN0KHNlbGYuX2h0dHAucmVzcG9uc2VUZXh0KSkge1xuICAgICAgICAgICAgc2VsZi52b3J0ZXguc2V0Q2xvc2VkQnlDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICBzZWxmLl9jbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHNlbGYuX2Fib3J0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHNlbGYuX2h0dHAuYWJvcnQoKTtcblxuICAgICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTcGxpdCBvdXQgdGhlIHBheWxvYWRzIG9mIGRhdGEsIHRoZXkgYXJlIGRlbGltaXRlZCBieSBhICcuJ1xuICAgICAgICBsZXQgZGF0YSA9IHNlbGYuX2h0dHAucmVzcG9uc2VUZXh0LnN1YnN0cihzZWxmLl9yZXNwb25zZVBhcnNlSW5kZXgpO1xuICAgICAgICBsZXQgcGF5bG9hZFNlcGFyYXRvckluZGV4ID0gZGF0YS5pbmRleE9mKFwiLlwiKTtcblxuICAgICAgICB3aGlsZSAocGF5bG9hZFNlcGFyYXRvckluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgc2VsZi5fcmVzcG9uc2VQYXJzZUluZGV4ICs9IHBheWxvYWRTZXBhcmF0b3JJbmRleCArIDE7XG5cbiAgICAgICAgICAgIC8vIEdldCB0aGUgYjY0ZW5jb2RlZCBzdHJpbmdcbiAgICAgICAgICAgIGxldCB2b3J0ZXhTdHIgPSBkYXRhLnN1YnN0cigwLCBwYXlsb2FkU2VwYXJhdG9ySW5kZXgpO1xuXG4gICAgICAgICAgICBpZiAodm9ydGV4U3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNlbGYudm9ydGV4QmVhdENhbGxiYWNrKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBwYXlsb2FkIG9iamVjdCBmcm9tIGl0XG4gICAgICAgICAgICAgICAgLy8gU2VuZCB0byB2b3J0ZXhcbiAgICAgICAgICAgICAgICBQYXlsb2FkRW52ZWxvcGUuZnJvbVZvcnRleE1zZyh2b3J0ZXhTdHIpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChwZTogUGF5bG9hZEVudmVsb3BlKSA9PiBzZWxmLnJlY2VpdmVDYWxsYmFjayhwZSkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gQW4gZXJyb3Igb2NjdXJlZCBkZXNlcmlhbGlzaW5nICR7ZX1gXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGEgPSBzZWxmLl9odHRwLnJlc3BvbnNlVGV4dC5zdWJzdHIoc2VsZi5fcmVzcG9uc2VQYXJzZUluZGV4KTtcbiAgICAgICAgICAgIHBheWxvYWRTZXBhcmF0b3JJbmRleCA9IGRhdGEuaW5kZXhPZihcIi5cIik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbiB0aGUgZXZlbnQgdGhhdCB0aGUgYnJvd3NlciBpcyBidWZmZXJpbmcgYWxsIHRoaXMgZGF0YSwgd2Ugc2hvdWxkXG4gICAgICAgIC8vIHJlY29ubmVjdCB0byBhbGxvdyB0aGUgYnJvd3NlciB0byBjbGVhbnVwLlxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBzZWxmLl9odHRwLnJlc3BvbnNlVGV4dC5sZW5ndGggPj1cbiAgICAgICAgICAgICAgICBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24uUkVDT05ORUNUX1NJWkVfTElNSVQgJiZcbiAgICAgICAgICAgICFzZWxmLl9jbG9zaW5nXG4gICAgICAgICkge1xuICAgICAgICAgICAgc2VsZi5fY2xvc2luZyA9IHRydWU7XG4gICAgICAgICAgICBzZWxmLnZvcnRleC5yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2Vycm9yKGUpIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICBpZiAoc2VsZi5fdXBkYXRlVGltZXIpIGNsZWFySW50ZXJ2YWwoc2VsZi5fdXBkYXRlVGltZXIpO1xuXG4gICAgICAgIGlmIChzZWxmLl9hYm9ydGluZyB8fCB0aGlzLl9jbG9zaW5nKSByZXR1cm47XG5cbiAgICAgICAgbGV0IG1zZyA9IFwiXCI7XG5cbiAgICAgICAgaWYgKGUudHlwZSA9PT0gXCJhYm9ydFwiKSB7XG4gICAgICAgICAgICBtc2cgPSBcIlJlcXVlc3Qgd2FzIGFib3J0ZWQgYW5kIG5vdCBieSBWb3J0ZXhKU1wiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtc2cgPSBlLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52b3J0ZXhTdGF0dXNTZXJ2aWNlLnNldE9ubGluZShmYWxzZSk7XG4gICAgICAgIHRoaXMudm9ydGV4U3RhdHVzU2VydmljZS5sb2dFcnJvcihtc2cpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlZvcnRleENvbm5lY3Rpb24sIGNvbm5lY3Rpb24gZXJyb3JlZCBvdXQ6IFwiICsgbXNnKTtcbiAgICB9XG59XG4iXX0=