velocious 1.0.683 → 1.0.684

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -196,6 +196,11 @@ export default class VelociousHttpServerWorkerHandlerWorkerThread {
196
196
  if (client) {
197
197
  settlements.push(client.abortPendingFileResponses());
198
198
  settlements.push(client.abortStreamResponses());
199
+ // Buffered responses have no stream to abort, so their in-flight
200
+ // handlers never hear about the socket teardown through the streaming
201
+ // path: notify the running requests directly so they can settle
202
+ // resources (e.g. admission queue positions) in-process.
203
+ client.notifyClientDisconnect();
199
204
  }
200
205
  for (const [transferId, transfer] of this.fileTransfers) {
201
206
  if (transfer.clientCount !== clientCount)
@@ -327,4 +332,4 @@ export default class VelociousHttpServerWorkerHandlerWorkerThread {
327
332
  await Promise.all(sendTasks);
328
333
  }
329
334
  }
330
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyLXRocmVhZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9odHRwLXNlcnZlci93b3JrZXItaGFuZGxlci93b3JrZXItdGhyZWFkLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLFdBQVcsTUFBTSxzQkFBc0IsQ0FBQTtBQUM5QyxPQUFPLE1BQU0sTUFBTSxvQkFBb0IsQ0FBQTtBQUN2QyxPQUFPLDBCQUEwQixNQUFNLGtDQUFrQyxDQUFBO0FBQ3pFLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxXQUFXLE1BQU0sdUJBQXVCLENBQUE7QUFDL0MsT0FBTyxNQUFNLE1BQU0saUJBQWlCLENBQUE7QUFDcEMsT0FBTyxpQkFBaUIsTUFBTSxvQ0FBb0MsQ0FBQTtBQUNsRSxPQUFPLGVBQWUsTUFBTSx3QkFBd0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQTtBQUVwRTs7OztHQUlHO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxLQUFLO0lBQ3RDLE1BQU0sZUFBZSxHQUFHLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMzRixNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBRTVJLE9BQU8sRUFBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLE1BQU0sRUFBRSxPQUFP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IEFwcGxpY2F0aW9uIGZyb20gXCIuLi8uLi9hcHBsaWNhdGlvbi5qc1wiXG5pbXBvcnQgQ2xpZW50IGZyb20gXCIuLi9jbGllbnQvaW5kZXguanNcIlxuaW1wb3J0IGRpc3BhdGNoQ2hhbm5lbFN1YnNjcmliZXJzIGZyb20gXCIuL2NoYW5uZWwtc3Vic2NyaWJlci1kaXNwYXRjaC5qc1wiXG5pbXBvcnQge2RpZ2d9IGZyb20gXCJkaWdnZXJpemVcIlxuaW1wb3J0IGVycm9yTG9nZ2VyIGZyb20gXCIuLi8uLi9lcnJvci1sb2dnZXIuanNcIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vLi4vbG9nZ2VyLmpzXCJcbmltcG9ydCB0b0ltcG9ydFNwZWNpZmllciBmcm9tIFwiLi4vLi4vdXRpbHMvdG8taW1wb3J0LXNwZWNpZmllci5qc1wiXG5pbXBvcnQgV2Vic29ja2V0RXZlbnRzIGZyb20gXCIuLi93ZWJzb2NrZXQtZXZlbnRzLmpzXCJcbmltcG9ydCB7IHJ1blNodXRkb3duU3RlcHMgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc2h1dGRvd24tbGlmZWN5Y2xlLmpzXCJcblxuLyoqXG4gKiBSdW5zIHN1bW1hcml6ZSBjbGllbnQgd3JpdGUgY2h1bmsuXG4gKiBAcGFyYW0ge0J1ZmZlciB8IFVpbnQ4QXJyYXkgfCBzdHJpbmd9IGNodW5rIC0gQ2xpZW50IGlucHV0IHBheWxvYWQuXG4gKiBAcmV0dXJucyB7e2xlbmd0aDogbnVtYmVyLCBwcmV2aWV3OiBzdHJpbmd9fSAtIENodW5rIHN1bW1hcnkgZm9yIGxvZ2dpbmcuXG4gKi9cbmZ1bmN0aW9uIHN1bW1hcml6ZUNsaWVudFdyaXRlQ2h1bmsoY2h1bmspIHtcbiAgY29uc3Qgbm9ybWFsaXplZENodW5rID0gdHlwZW9mIGNodW5rID09PSBcInN0cmluZ1wiID8gQnVmZmVyLmZyb20oY2h1bmspIDogQnVmZmVyLmZyb20oY2h1bmspXG4gIGNvbnN0IHByZXZpZXcgPSBub3JtYWxpemVkQ2h1bmsudG9TdHJpbmcoXCJsYXRpbjFcIiwgMCwgTWF0aC5taW4obm9ybWFsaXplZENodW5rLmxlbmd0aCwgMTYwKSkucmVwbGFjZUFsbChcIlxcclwiLCBcIlxcXFxyXCIpLnJlcGxhY2VBbGwoXCJcXG5cIiwgXCJcXFxcblwiKVxuXG4gIHJldHVybiB7bGVuZ3RoOiBub3JtYWxpemVkQ2h1bmsubGVuZ3RoLCBwcmV2aWV3fVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNIdHRwU2VydmVyV29ya2VySGFuZGxlcldvcmtlclRocmVhZCB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIm5vZGU6d29ya2VyX3RocmVhZHNcIikuTWVzc2FnZVBvcnQgfCBudWxsfSBhcmdzLnBhcmVudFBvcnQgLSBQYXJlbnQgcG9ydC5cbiAgICogQHBhcmFtIHt7ZGVidWc6IGJvb2xlYW4sIGRpcmVjdG9yeTogc3RyaW5nLCBlbnZpcm9ubWVudDogc3RyaW5nLCB3b3JrZXJDb3VudDogbnVtYmVyfX0gYXJncy53b3JrZXJEYXRhIC0gV29ya2VyIGNvbmZpZ3VyYXRpb24gZGV0YWlscy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtwYXJlbnRQb3J0LCB3b3JrZXJEYXRhfSkge1xuICAgIGlmICghcGFyZW50UG9ydCkgdGhyb3cgbmV3IEVycm9yKFwicGFyZW50UG9ydCBpcyByZXF1aXJlZFwiKVxuXG4gICAgY29uc3Qge3dvcmtlckNvdW50fSA9IHdvcmtlckRhdGFcblxuICAgIC8qKlxuICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgKiBAdHlwZSB7UmVjb3JkPG51bWJlciwgQ2xpZW50Pn0gKi9cbiAgICB0aGlzLmNsaWVudHMgPSB7fVxuXG4gICAgdGhpcy5sb2dnZXIgPSBuZXcgTG9nZ2VyKHRoaXMpXG4gICAgdGhpcy5wYXJlbnRQb3J0ID0gcGFyZW50UG9ydFxuICAgIHRoaXMud29ya2VyRGF0YSA9IHdvcmtlckRhdGFcbiAgICB0aGlzLndvcmtlckNvdW50ID0gd29ya2VyQ291bnRcbiAgICB0aGlzLmZpbGVUcmFuc2ZlckNvdW50ID0gMFxuXG4gICAgLyoqIEB0eXBlIHtNYXA8bnVtYmVyLCB7Y2xpZW50Q291bnQ6IG51bWJlciwgc2V0dGxlOiAocmVzdWx0OiBcImNvbXBsZXRlZFwiIHwgXCJhYm9ydGVkXCIpID0+IFByb21pc2U8dm9pZD59Pn0gKi9cbiAgICB0aGlzLmZpbGVUcmFuc2ZlcnMgPSBuZXcgTWFwKClcblxuICAgIHBhcmVudFBvcnQub24oXCJtZXNzYWdlXCIsIGVycm9yTG9nZ2VyKHRoaXMub25Db21tYW5kKSlcblxuICAgIHRoaXMuaW5pdGlhbGl6ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmFwcGxpY2F0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJBcHBsaWNhdGlvbiBub3QgaW5pdGlhbGl6ZWRcIilcblxuICAgICAgdGhpcy5hcHBsaWNhdGlvbi5pbml0aWFsaXplKCkudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnTG93TGV2ZWwoKCkgPT4gYFdvcmtlciAke3dvcmtlckNvdW50fSBzdGFydGVkYClcbiAgICAgICAgcGFyZW50UG9ydC5wb3N0TWVzc2FnZSh7Y29tbWFuZDogXCJzdGFydGVkXCJ9KVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaW5pdGlhbGl6ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGluaXRpYWxpemUoKSB7XG4gICAgY29uc3Qge2RlYnVnLCBkaXJlY3RvcnksIGVudmlyb25tZW50fSA9IHRoaXMud29ya2VyRGF0YVxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb25QYXRoID0gYCR7ZGlyZWN0b3J5fS9zcmMvY29uZmlnL2NvbmZpZ3VyYXRpb24uanNgXG4gICAgY29uc3QgY29uZmlndXJhdGlvbkltcG9ydCA9IGF3YWl0IGltcG9ydCh0b0ltcG9ydFNwZWNpZmllcihjb25maWd1cmF0aW9uUGF0aCkpXG5cbiAgICAvKipcbiAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uSW1wb3J0LmRlZmF1bHRcblxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoYENvbmZpZ3VyYXRpb24gY291bGRuJ3QgYmUgbG9hZGVkIGZyb206ICR7Y29uZmlndXJhdGlvblBhdGh9YClcblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb25cblxuICAgIGNvbmZpZ3VyYXRpb24uZGVidWcgPSBkZWJ1ZyA9PT0gdHJ1ZVxuICAgIGNvbmZpZ3VyYXRpb24uc2V0RW52aXJvbm1lbnQoZW52aXJvbm1lbnQpXG4gICAgY29uZmlndXJhdGlvbi5zZXRDdXJyZW50KClcbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1ZygoKSA9PiBbXCJXb3JrZXIgdGhyZWFkIGNvbmZpZ3VyYXRpb24gbG9hZGVkXCIsIHtkZWJ1ZzogY29uZmlndXJhdGlvbi5kZWJ1Zywgd29ya2VyQ291bnQ6IHRoaXMud29ya2VyQ291bnR9XSlcbiAgICB0aGlzLndlYnNvY2tldEV2ZW50cyA9IG5ldyBXZWJzb2NrZXRFdmVudHMoe3BhcmVudFBvcnQ6IHRoaXMucGFyZW50UG9ydCwgd29ya2VyQ291bnQ6IHRoaXMud29ya2VyQ291bnR9KVxuICAgIGNvbmZpZ3VyYXRpb24uc2V0V2Vic29ja2V0RXZlbnRzKHRoaXMud2Vic29ja2V0RXZlbnRzKVxuXG4gICAgdGhpcy5hcHBsaWNhdGlvbiA9IG5ldyBBcHBsaWNhdGlvbih7Y29uZmlndXJhdGlvbiwgdHlwZTogXCJ3b3JrZXItaGFuZGxlclwifSlcblxuICAgIGlmICghY29uZmlndXJhdGlvbi5pc0luaXRpYWxpemVkKCkpIHtcbiAgICAgIGF3YWl0IGNvbmZpZ3VyYXRpb24uaW5pdGlhbGl6ZSh7dHlwZTogXCJ3b3JrZXItaGFuZGxlclwifSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogT24gY29tbWFuZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBEYXRhIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhLmNvbW1hbmQgLSBDb21tYW5kLlxuICAgKiBAcGFyYW0ge0J1ZmZlciB8IFVpbnQ4QXJyYXkgfCBzdHJpbmd9IFtkYXRhLmNodW5rXSAtIENodW5rLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEucmVtb3RlQWRkcmVzc10gLSBSZW1vdGUgYWRkcmVzcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhLmNsaWVudENvdW50XSAtIENsaWVudCBjb3VudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkYXRhLmNoYW5uZWxdIC0gQ2hhbm5lbCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEuY3JlYXRlZEF0XSAtIEV2ZW50IGNyZWF0aW9uIHRpbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGF0YS5ldmVudElkXSAtIEV2ZW50IGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YS5yZXF1ZXN0SWRdIC0gRGVidWcgcmVxdWVzdCBpZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhLnRyYW5zZmVySWRdIC0gRmlsZSB0cmFuc2ZlciBpZC5cbiAgICogQHBhcmFtIHtcImNvbXBsZXRlZFwiIHwgXCJhYm9ydGVkXCJ9IFtkYXRhLnJlc3VsdF0gLSBGaWxlIHRyYW5zZmVyIHJlc3VsdC5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gW2RhdGEucGF5bG9hZF0gLSBQYXlsb2FkIGRhdGEuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBbZGF0YS5icm9hZGNhc3RQYXJhbXNdIC0gVjIgYnJvYWRjYXN0IGZpbHRlciBwYXJhbXMuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IFtkYXRhLmJvZHldIC0gVjIgYnJvYWRjYXN0IGJvZHkuXG4gICAqL1xuICBvbkNvbW1hbmQgPSBhc3luYyAoZGF0YSkgPT4ge1xuICAgIGF3YWl0IHRoaXMubG9nZ2VyLmRlYnVnTG93TGV2ZWwoKCkgPT4gW2BXb3JrZXIgJHt0aGlzLndvcmtlckNvdW50fSByZWNlaXZlZCBjb21tYW5kYCwgZGF0YV0pXG5cbiAgICBjb25zdCBjb21tYW5kID0gZGF0YS5jb21tYW5kXG5cbiAgICBpZiAoY29tbWFuZCA9PSBcIm5ld0NsaWVudFwiKSB7XG4gICAgICB0aGlzLmhhbmRsZU5ld0NsaWVudChkYXRhKVxuICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcImNsaWVudFdyaXRlXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ2xpZW50V3JpdGUoZGF0YSlcbiAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJjbGllbnRGaWxlUmVzdWx0XCIpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ2xpZW50RmlsZVJlc3VsdChkYXRhKVxuICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcImNsaWVudEFib3J0XCIpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ2xpZW50QWJvcnQoZGF0YSlcbiAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJ3ZWJzb2NrZXRFdmVudFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZVdlYnNvY2tldEV2ZW50KGRhdGEpXG4gICAgfSBlbHNlIGlmIChjb21tYW5kID09IFwid2Vic29ja2V0VjJCcm9hZGNhc3RcIikge1xuICAgICAgdGhpcy5oYW5kbGVXZWJzb2NrZXRWMkJyb2FkY2FzdChkYXRhKVxuICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcImRlYnVnU25hcHNob3RcIikge1xuICAgICAgdGhpcy5oYW5kbGVEZWJ1Z1NuYXBzaG90KGRhdGEpXG4gICAgfSBlbHNlIGlmIChjb21tYW5kID09IFwic2h1dGRvd25cIikge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVTaHV0ZG93bigpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjb21tYW5kOiAke2NvbW1hbmR9YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYW5kbGUgbmV3IGNsaWVudC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBEYXRhIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YS5jbGllbnRDb3VudF0gLSBDbGllbnQgY291bnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGF0YS5yZW1vdGVBZGRyZXNzXSAtIFJlbW90ZSBhZGRyZXNzLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGhhbmRsZU5ld0NsaWVudChkYXRhKSB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24pIHRocm93IG5ldyBFcnJvcihcIkNvbmZpZ3VyYXRpb24gbm90IGluaXRpYWxpemVkXCIpXG5cbiAgICBjb25zdCB7Y2xpZW50Q291bnQsIHJlbW90ZUFkZHJlc3N9ID0gZGF0YVxuXG4gICAgaWYgKHR5cGVvZiBjbGllbnRDb3VudCAhPT0gXCJudW1iZXJcIikgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50Q291bnQgbXVzdCBiZSBhIG51bWJlclwiKVxuXG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudCh7XG4gICAgICBjbGllbnRDb3VudCxcbiAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuY29uZmlndXJhdGlvbixcbiAgICAgIHJlbW90ZUFkZHJlc3NcbiAgICB9KVxuXG4gICAgY2xpZW50LmV2ZW50cy5vbihcIm91dHB1dFwiLCAob3V0cHV0LCB7d2Vic29ja2V0RnJhbWUgPSBmYWxzZX0gPSB7fSkgPT4ge1xuICAgICAgdGhpcy5wYXJlbnRQb3J0LnBvc3RNZXNzYWdlKHtjb21tYW5kOiBcImNsaWVudE91dHB1dFwiLCBjbGllbnRDb3VudCwgb3V0cHV0LCB3ZWJzb2NrZXRGcmFtZX0pXG4gICAgfSlcblxuICAgIGNsaWVudC5ldmVudHMub24oXCJmaWxlXCIsICh7ZmlsZVBhdGgsIHNlbmRCb2R5LCBzZXR0bGV9KSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2ZlcklkID0gKyt0aGlzLmZpbGVUcmFuc2ZlckNvdW50XG5cbiAgICAgIHRoaXMuZmlsZVRyYW5zZmVycy5zZXQodHJhbnNmZXJJZCwge2NsaWVudENvdW50LCBzZXR0bGV9KVxuICAgICAgdGhpcy5wYXJlbnRQb3J0LnBvc3RNZXNzYWdlKHtjb21tYW5kOiBcImNsaWVudEZpbGVcIiwgY2xpZW50Q291bnQsIGZpbGVQYXRoLCBzZW5kQm9keSwgdHJhbnNmZXJJZH0pXG4gICAgfSlcblxuICAgIGNsaWVudC5ldmVudHMub24oXCJjbG9zZVwiLCAob3V0cHV0KSA9PiB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1Z0xvd0xldmVsKCgpID0+IFwiQ2xvc2UgcmVjZWl2ZWQgZnJvbSBjbGllbnQgaW4gd29ya2VyIC0gZm9yd2FyZGluZyB0byB3b3JrZXIgcGFyZW50XCIpXG4gICAgICB0aGlzLnBhcmVudFBvcnQucG9zdE1lc3NhZ2Uoe2NvbW1hbmQ6IFwiY2xpZW50Q2xvc2VcIiwgY2xpZW50Q291bnQsIG91dHB1dH0pXG4gICAgfSlcblxuICAgIGNsaWVudC5ldmVudHMub24oXCJ3ZWJzb2NrZXRTZXNzaW9uT3duZWRcIiwgKHtzZXNzaW9uSWR9KSA9PiB7XG4gICAgICB0aGlzLnBhcmVudFBvcnQucG9zdE1lc3NhZ2Uoe2NvbW1hbmQ6IFwid2Vic29ja2V0U2Vzc2lvbk93bmVkXCIsIHNlc3Npb25JZH0pXG4gICAgfSlcblxuICAgIGNsaWVudC5ldmVudHMub24oXCJ3ZWJzb2NrZXRTZXNzaW9uUmVsZWFzZWRcIiwgKHtzZXNzaW9uSWR9KSA9PiB7XG4gICAgICB0aGlzLnBhcmVudFBvcnQucG9zdE1lc3NhZ2Uoe2NvbW1hbmQ6IFwid2Vic29ja2V0U2Vzc2lvblJlbGVhc2VkXCIsIHNlc3Npb25JZH0pXG4gICAgfSlcblxuICAgIHRoaXMuY2xpZW50c1tjbGllbnRDb3VudF0gPSBjbGllbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXR0bGVzIGEgZmlsZSByZXNwb25zZSBhZnRlciB0aGUgcGFyZW50IGZpbmlzaGVzIHNvY2tldCBkZWxpdmVyeS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBGaWxlIHJlc3VsdCBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RhdGEudHJhbnNmZXJJZF0gLSBGaWxlIHRyYW5zZmVyIGlkLlxuICAgKiBAcGFyYW0ge1wiY29tcGxldGVkXCIgfCBcImFib3J0ZWRcIn0gW2RhdGEucmVzdWx0XSAtIEZpbGUgdHJhbnNmZXIgcmVzdWx0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciB0aGUgd29ya2VyLXNpZGUgY29tcGxldGlvbiBjYWxsYmFjayBzZXR0bGVzLlxuICAgKi9cbiAgYXN5bmMgaGFuZGxlQ2xpZW50RmlsZVJlc3VsdChkYXRhKSB7XG4gICAgY29uc3Qge3Jlc3VsdCwgdHJhbnNmZXJJZH0gPSBkYXRhXG5cbiAgICBpZiAodHlwZW9mIHRyYW5zZmVySWQgIT09IFwibnVtYmVyXCIpIHRocm93IG5ldyBFcnJvcihcInRyYW5zZmVySWQgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIGlmIChyZXN1bHQgIT09IFwiY29tcGxldGVkXCIgJiYgcmVzdWx0ICE9PSBcImFib3J0ZWRcIikgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGZpbGUgdHJhbnNmZXIgcmVzdWx0OiAke3Jlc3VsdH1gKVxuXG4gICAgY29uc3QgdHJhbnNmZXIgPSB0aGlzLmZpbGVUcmFuc2ZlcnMuZ2V0KHRyYW5zZmVySWQpXG5cbiAgICBpZiAoIXRyYW5zZmVyKSByZXR1cm5cblxuICAgIHRoaXMuZmlsZVRyYW5zZmVycy5kZWxldGUodHJhbnNmZXJJZClcbiAgICBhd2FpdCB0cmFuc2Zlci5zZXR0bGUocmVzdWx0KVxuICB9XG5cbiAgLyoqXG4gICAqIEFib3J0cyBmaWxlIHJlc3BvbnNlcyBiZWxvbmdpbmcgdG8gYSBjbG9zZWQgcGFyZW50LXNpZGUgc29ja2V0LlxuICAgKiBAcGFyYW0ge29iamVjdH0gZGF0YSAtIENsaWVudCBhYm9ydCBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RhdGEuY2xpZW50Q291bnRdIC0gQ2xpZW50IGNvdW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBwZW5kaW5nIGNvbXBsZXRpb24gY2FsbGJhY2tzIHNldHRsZS5cbiAgICovXG4gIGFzeW5jIGhhbmRsZUNsaWVudEFib3J0KGRhdGEpIHtcbiAgICBjb25zdCB7Y2xpZW50Q291bnR9ID0gZGF0YVxuXG4gICAgaWYgKHR5cGVvZiBjbGllbnRDb3VudCAhPT0gXCJudW1iZXJcIikgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50Q291bnQgbXVzdCBiZSBhIG51bWJlclwiKVxuXG4gICAgY29uc3Qgc2V0dGxlbWVudHMgPSBbXVxuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50c1tjbGllbnRDb3VudF1cblxuICAgIGlmIChjbGllbnQpIHtcbiAgICAgIHNldHRsZW1lbnRzLnB1c2goY2xpZW50LmFib3J0UGVuZGluZ0ZpbGVSZXNwb25zZXMoKSlcbiAgICAgIHNldHRsZW1lbnRzLnB1c2goY2xpZW50LmFib3J0U3RyZWFtUmVzcG9uc2VzKCkpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbdHJhbnNmZXJJZCwgdHJhbnNmZXJdIG9mIHRoaXMuZmlsZVRyYW5zZmVycykge1xuICAgICAgaWYgKHRyYW5zZmVyLmNsaWVudENvdW50ICE9PSBjbGllbnRDb3VudCkgY29udGludWVcblxuICAgICAgdGhpcy5maWxlVHJhbnNmZXJzLmRlbGV0ZSh0cmFuc2ZlcklkKVxuICAgICAgc2V0dGxlbWVudHMucHVzaCh0cmFuc2Zlci5zZXR0bGUoXCJhYm9ydGVkXCIpKVxuICAgIH1cblxuICAgIGRlbGV0ZSB0aGlzLmNsaWVudHNbY2xpZW50Q291bnRdXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoc2V0dGxlbWVudHMpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYW5kbGUgY2xpZW50IHdyaXRlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gZGF0YSAtIERhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtCdWZmZXIgfCBVaW50OEFycmF5IHwgc3RyaW5nfSBbZGF0YS5jaHVua10gLSBDaHVuay5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhLmNsaWVudENvdW50XSAtIENsaWVudCBjb3VudC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIHdoZW4gdGhlIGNsaWVudCB3cml0ZSBpcyBkaXNwYXRjaGVkLlxuICAgKi9cbiAgYXN5bmMgaGFuZGxlQ2xpZW50V3JpdGUoZGF0YSkge1xuICAgIGF3YWl0IHRoaXMubG9nZ2VyLmRlYnVnTG93TGV2ZWwoXCJMb29raW5nIHVwIGNsaWVudFwiKVxuXG4gICAgY29uc3Qge2NodW5rLCBjbGllbnRDb3VudH0gPSBkYXRhXG4gICAgaWYgKCFjaHVuaykgdGhyb3cgbmV3IEVycm9yKFwiTm8gY2h1bmsgZ2l2ZW5cIilcbiAgICBjb25zdCBjbGllbnQgPSAvKiogQHR5cGUge0NsaWVudCB8IHVuZGVmaW5lZH0gKi8gKGRpZ2codGhpcy5jbGllbnRzLCBjbGllbnRDb3VudCkpXG5cbiAgICBpZiAoIWNsaWVudCkgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgbm90IGZvdW5kIGZvciBjbGllbnRXcml0ZTogJHtjbGllbnRDb3VudH1gKVxuXG4gICAgY29uc3QgY2xpZW50Q2h1bmsgPSB0eXBlb2YgY2h1bmsgPT09IFwic3RyaW5nXCIgPyBCdWZmZXIuZnJvbShjaHVuaykgOiBCdWZmZXIuZnJvbShjaHVuaylcblxuICAgIGF3YWl0IHRoaXMubG9nZ2VyLmRlYnVnKCgpID0+IFtcIlNlbmRpbmcgY2xpZW50V3JpdGUgdG8gcGFyc2VyXCIsIHtjbGllbnRDb3VudCwgLi4uc3VtbWFyaXplQ2xpZW50V3JpdGVDaHVuayhjbGllbnRDaHVuayl9XSlcblxuICAgIGNsaWVudC5vbldyaXRlKGNsaWVudENodW5rKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIHdlYnNvY2tldCBldmVudC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBEYXRhIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGF0YS5jaGFubmVsXSAtIENoYW5uZWwgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkYXRhLmNyZWF0ZWRBdF0gLSBFdmVudCBjcmVhdGlvbiB0aW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEuZXZlbnRJZF0gLSBFdmVudCBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBbZGF0YS5wYXlsb2FkXSAtIFBheWxvYWQgZGF0YS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIHdoZW4gdGhlIHdlYnNvY2tldCBldmVudCBpcyBkaXNwYXRjaGVkLlxuICAgKi9cbiAgYXN5bmMgaGFuZGxlV2Vic29ja2V0RXZlbnQoZGF0YSkge1xuICAgIGNvbnN0IHtjaGFubmVsLCBjcmVhdGVkQXQsIGV2ZW50SWQsIHBheWxvYWR9ID0gZGF0YVxuXG4gICAgaWYgKHR5cGVvZiBjaGFubmVsICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBjaGFubmVsIGdpdmVuXCIpXG5cbiAgICBhd2FpdCB0aGlzLmJyb2FkY2FzdFdlYnNvY2tldEV2ZW50KHtjaGFubmVsLCBjcmVhdGVkQXQsIGV2ZW50SWQsIHBheWxvYWR9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIHdlYnNvY2tldCB2MiBicm9hZGNhc3QuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gRGF0YSBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gW2RhdGEuYnJvYWRjYXN0UGFyYW1zXSAtIFYyIGJyb2FkY2FzdCBmaWx0ZXIgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBbZGF0YS5ib2R5XSAtIFYyIGJyb2FkY2FzdCBib2R5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEuY2hhbm5lbF0gLSBDaGFubmVsIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGF0YS5ldmVudElkXSAtIEV2ZW50IGlkZW50aWZpZXIuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgaGFuZGxlV2Vic29ja2V0VjJCcm9hZGNhc3QoZGF0YSkge1xuICAgIGNvbnN0IHtib2R5LCBicm9hZGNhc3RQYXJhbXMsIGNoYW5uZWwsIGV2ZW50SWR9ID0gZGF0YVxuXG4gICAgaWYgKHR5cGVvZiBjaGFubmVsICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBjaGFubmVsIGdpdmVuXCIpXG4gICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24pIHRocm93IG5ldyBFcnJvcihcIkNvbmZpZ3VyYXRpb24gbm90IGluaXRpYWxpemVkXCIpXG5cbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24uX2Jyb2FkY2FzdFRvQ2hhbm5lbExvY2FsKGNoYW5uZWwsIGJyb2FkY2FzdFBhcmFtcyB8fCB7fSwgYm9keSwge2V2ZW50SWR9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIGRlYnVnIHNuYXBzaG90LlxuICAgKiBAcGFyYW0ge29iamVjdH0gZGF0YSAtIERhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhLnJlcXVlc3RJZF0gLSBEZWJ1ZyByZXF1ZXN0IGlkLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGhhbmRsZURlYnVnU25hcHNob3QoZGF0YSkge1xuICAgIGNvbnN0IHtyZXF1ZXN0SWR9ID0gZGF0YVxuXG4gICAgaWYgKHR5cGVvZiByZXF1ZXN0SWQgIT09IFwibnVtYmVyXCIpIHRocm93IG5ldyBFcnJvcihcImRlYnVnU25hcHNob3QgcmVxdWVzdElkIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICBpZiAoIXRoaXMuY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiQ29uZmlndXJhdGlvbiBub3QgaW5pdGlhbGl6ZWRcIilcblxuICAgIHRoaXMucGFyZW50UG9ydC5wb3N0TWVzc2FnZSh7XG4gICAgICBjb21tYW5kOiBcImRlYnVnU25hcHNob3RcIixcbiAgICAgIHJlcXVlc3RJZCxcbiAgICAgIHNuYXBzaG90OiB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxEZWJ1Z1NuYXBzaG90KClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIHNodXRkb3duLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gUmVzb2x2ZXMgYWZ0ZXIgd29ya2VyIHNodXRkb3duIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAgICovXG4gIGFzeW5jIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGNvbnN0IGNsaWVudHMgPSBPYmplY3QudmFsdWVzKHRoaXMuY2xpZW50cylcblxuICAgIGF3YWl0IHJ1blNodXRkb3duU3RlcHMoe1xuICAgICAgbWVzc2FnZTogXCJIVFRQIHdvcmtlci1oYW5kbGVyIHNodXRkb3duIGZhaWxlZFwiLFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAgLi4uY2xpZW50cy5tYXAoKGNsaWVudCkgPT4gYXN5bmMgKCkgPT4gYXdhaXQgY2xpZW50LmFib3J0UGVuZGluZ0ZpbGVSZXNwb25zZXMoKSksXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0aGlzLmZpbGVUcmFuc2ZlcnMuY2xlYXIoKVxuICAgICAgICAgIGF3YWl0IHRoaXMuYXBwbGljYXRpb24/LnN0b3AoKVxuICAgICAgICB9XG4gICAgICBdXG4gICAgfSlcblxuICAgIHRoaXMucGFyZW50UG9ydC5wb3N0TWVzc2FnZSh7Y29tbWFuZDogXCJzaHV0ZG93bkNvbXBsZXRlXCJ9KVxuICAgIHByb2Nlc3MuZXhpdCgwKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYnJvYWRjYXN0IHdlYnNvY2tldCBldmVudC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY2hhbm5lbCAtIENoYW5uZWwgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IGFyZ3MuY3JlYXRlZEF0IC0gRXZlbnQgY3JlYXRpb24gdGltZS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IGFyZ3MuZXZlbnRJZCAtIEV2ZW50IGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IGFyZ3MucGF5bG9hZCAtIFBheWxvYWQgZGF0YS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGJyb2FkY2FzdFdlYnNvY2tldEV2ZW50KHtjaGFubmVsLCBjcmVhdGVkQXQsIGV2ZW50SWQsIHBheWxvYWR9KSB7XG4gICAgY29uc3Qgc2VuZFRhc2tzID0gW11cblxuICAgIGZvciAoY29uc3QgY2xpZW50S2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuY2xpZW50cykpIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50c1tOdW1iZXIoY2xpZW50S2V5KV1cbiAgICAgIGlmICghY2xpZW50KSBjb250aW51ZVxuICAgICAgY29uc3Qgc2Vzc2lvbiA9IGNsaWVudC53ZWJzb2NrZXRTZXNzaW9uXG5cbiAgICAgIGlmICghc2Vzc2lvbikgY29udGludWVcblxuICAgICAgc2VuZFRhc2tzLnB1c2goc2Vzc2lvbi5zZW5kRXZlbnQoY2hhbm5lbCwgcGF5bG9hZCwge1xuICAgICAgICBjcmVhdGVkQXQsXG4gICAgICAgIGV2ZW50SWRcbiAgICAgIH0pKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIC8vIElzb2xhdGUgY2hhbm5lbCBzdWJzY3JpYmVyIGZhaWx1cmVzIHNvIGEgYnVnZ3kgaW4tcHJvY2VzcyBjYWxsYmFja1xuICAgICAgLy8gY2Fubm90IHJlamVjdCB0aGlzIGNvbW1hbmQgYW5kIGNyYXNoIHRoZSB3b3JrZXIgdGhyZWFkLCBidXQgc3RpbGxcbiAgICAgIC8vIHN1cmZhY2UgdGhlIGVycm9yIHRvIHRoZSBmcmFtZXdvcmsgZXJyb3IgZXZlbnRzIHNvIGJ1ZyByZXBvcnRlcnNcbiAgICAgIC8vIGNhbiBwaWNrIGl0IHVwLlxuICAgICAgc2VuZFRhc2tzLnB1c2goZGlzcGF0Y2hDaGFubmVsU3Vic2NyaWJlcnMoe2NoYW5uZWwsIGNvbmZpZ3VyYXRpb246IHRoaXMuY29uZmlndXJhdGlvbiwgY3JlYXRlZEF0LCBldmVudElkLCBsb2dnZXI6IHRoaXMubG9nZ2VyLCBwYXlsb2FkfSkpXG4gICAgfVxuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoc2VuZFRhc2tzKVxuICB9XG59XG4iXX0=
335
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyLXRocmVhZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9odHRwLXNlcnZlci93b3JrZXItaGFuZGxlci93b3JrZXItdGhyZWFkLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLFdBQVcsTUFBTSxzQkFBc0IsQ0FBQTtBQUM5QyxPQUFPLE1BQU0sTUFBTSxvQkFBb0IsQ0FBQTtBQUN2QyxPQUFPLDBCQUEwQixNQUFNLGtDQUFrQyxDQUFBO0FBQ3pFLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxXQUFXLE1BQU0sdUJBQXVCLENBQUE7QUFDL0MsT0FBTyxNQUFNLE1BQU0saUJBQWlCLENBQUE7QUFDcEMsT0FBTyxpQkFBaUIsTUFBTSxvQ0FBb0MsQ0FBQTtBQUNsRSxPQUFPLGVBQWUsTUFBTSx3QkFBd0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQTtBQUVwRTs7OztHQUlHO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxLQUFLO0lBQ3RDLE1BQU0sZUFBZSxHQUFHLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMzRixNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBRTVJLE9BQU8sRUFBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLE1BQU0sRUFBRSxPQUFP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QyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDOUIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBBcHBsaWNhdGlvbiBmcm9tIFwiLi4vLi4vYXBwbGljYXRpb24uanNcIlxuaW1wb3J0IENsaWVudCBmcm9tIFwiLi4vY2xpZW50L2luZGV4LmpzXCJcbmltcG9ydCBkaXNwYXRjaENoYW5uZWxTdWJzY3JpYmVycyBmcm9tIFwiLi9jaGFubmVsLXN1YnNjcmliZXItZGlzcGF0Y2guanNcIlxuaW1wb3J0IHtkaWdnfSBmcm9tIFwiZGlnZ2VyaXplXCJcbmltcG9ydCBlcnJvckxvZ2dlciBmcm9tIFwiLi4vLi4vZXJyb3ItbG9nZ2VyLmpzXCJcbmltcG9ydCBMb2dnZXIgZnJvbSBcIi4uLy4uL2xvZ2dlci5qc1wiXG5pbXBvcnQgdG9JbXBvcnRTcGVjaWZpZXIgZnJvbSBcIi4uLy4uL3V0aWxzL3RvLWltcG9ydC1zcGVjaWZpZXIuanNcIlxuaW1wb3J0IFdlYnNvY2tldEV2ZW50cyBmcm9tIFwiLi4vd2Vic29ja2V0LWV2ZW50cy5qc1wiXG5pbXBvcnQgeyBydW5TaHV0ZG93blN0ZXBzIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3NodXRkb3duLWxpZmVjeWNsZS5qc1wiXG5cbi8qKlxuICogUnVucyBzdW1tYXJpemUgY2xpZW50IHdyaXRlIGNodW5rLlxuICogQHBhcmFtIHtCdWZmZXIgfCBVaW50OEFycmF5IHwgc3RyaW5nfSBjaHVuayAtIENsaWVudCBpbnB1dCBwYXlsb2FkLlxuICogQHJldHVybnMge3tsZW5ndGg6IG51bWJlciwgcHJldmlldzogc3RyaW5nfX0gLSBDaHVuayBzdW1tYXJ5IGZvciBsb2dnaW5nLlxuICovXG5mdW5jdGlvbiBzdW1tYXJpemVDbGllbnRXcml0ZUNodW5rKGNodW5rKSB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRDaHVuayA9IHR5cGVvZiBjaHVuayA9PT0gXCJzdHJpbmdcIiA/IEJ1ZmZlci5mcm9tKGNodW5rKSA6IEJ1ZmZlci5mcm9tKGNodW5rKVxuICBjb25zdCBwcmV2aWV3ID0gbm9ybWFsaXplZENodW5rLnRvU3RyaW5nKFwibGF0aW4xXCIsIDAsIE1hdGgubWluKG5vcm1hbGl6ZWRDaHVuay5sZW5ndGgsIDE2MCkpLnJlcGxhY2VBbGwoXCJcXHJcIiwgXCJcXFxcclwiKS5yZXBsYWNlQWxsKFwiXFxuXCIsIFwiXFxcXG5cIilcblxuICByZXR1cm4ge2xlbmd0aDogbm9ybWFsaXplZENodW5rLmxlbmd0aCwgcHJldmlld31cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVsb2Npb3VzSHR0cFNlcnZlcldvcmtlckhhbmRsZXJXb3JrZXJUaHJlYWQge1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJub2RlOndvcmtlcl90aHJlYWRzXCIpLk1lc3NhZ2VQb3J0IHwgbnVsbH0gYXJncy5wYXJlbnRQb3J0IC0gUGFyZW50IHBvcnQuXG4gICAqIEBwYXJhbSB7e2RlYnVnOiBib29sZWFuLCBkaXJlY3Rvcnk6IHN0cmluZywgZW52aXJvbm1lbnQ6IHN0cmluZywgd29ya2VyQ291bnQ6IG51bWJlcn19IGFyZ3Mud29ya2VyRGF0YSAtIFdvcmtlciBjb25maWd1cmF0aW9uIGRldGFpbHMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7cGFyZW50UG9ydCwgd29ya2VyRGF0YX0pIHtcbiAgICBpZiAoIXBhcmVudFBvcnQpIHRocm93IG5ldyBFcnJvcihcInBhcmVudFBvcnQgaXMgcmVxdWlyZWRcIilcblxuICAgIGNvbnN0IHt3b3JrZXJDb3VudH0gPSB3b3JrZXJEYXRhXG5cbiAgICAvKipcbiAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICogQHR5cGUge1JlY29yZDxudW1iZXIsIENsaWVudD59ICovXG4gICAgdGhpcy5jbGllbnRzID0ge31cblxuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICAgIHRoaXMucGFyZW50UG9ydCA9IHBhcmVudFBvcnRcbiAgICB0aGlzLndvcmtlckRhdGEgPSB3b3JrZXJEYXRhXG4gICAgdGhpcy53b3JrZXJDb3VudCA9IHdvcmtlckNvdW50XG4gICAgdGhpcy5maWxlVHJhbnNmZXJDb3VudCA9IDBcblxuICAgIC8qKiBAdHlwZSB7TWFwPG51bWJlciwge2NsaWVudENvdW50OiBudW1iZXIsIHNldHRsZTogKHJlc3VsdDogXCJjb21wbGV0ZWRcIiB8IFwiYWJvcnRlZFwiKSA9PiBQcm9taXNlPHZvaWQ+fT59ICovXG4gICAgdGhpcy5maWxlVHJhbnNmZXJzID0gbmV3IE1hcCgpXG5cbiAgICBwYXJlbnRQb3J0Lm9uKFwibWVzc2FnZVwiLCBlcnJvckxvZ2dlcih0aGlzLm9uQ29tbWFuZCkpXG5cbiAgICB0aGlzLmluaXRpYWxpemUoKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5hcHBsaWNhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiQXBwbGljYXRpb24gbm90IGluaXRpYWxpemVkXCIpXG5cbiAgICAgIHRoaXMuYXBwbGljYXRpb24uaW5pdGlhbGl6ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1Z0xvd0xldmVsKCgpID0+IGBXb3JrZXIgJHt3b3JrZXJDb3VudH0gc3RhcnRlZGApXG4gICAgICAgIHBhcmVudFBvcnQucG9zdE1lc3NhZ2Uoe2NvbW1hbmQ6IFwic3RhcnRlZFwifSlcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGluaXRpYWxpemUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBpbml0aWFsaXplKCkge1xuICAgIGNvbnN0IHtkZWJ1ZywgZGlyZWN0b3J5LCBlbnZpcm9ubWVudH0gPSB0aGlzLndvcmtlckRhdGFcbiAgICBjb25zdCBjb25maWd1cmF0aW9uUGF0aCA9IGAke2RpcmVjdG9yeX0vc3JjL2NvbmZpZy9jb25maWd1cmF0aW9uLmpzYFxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb25JbXBvcnQgPSBhd2FpdCBpbXBvcnQodG9JbXBvcnRTcGVjaWZpZXIoY29uZmlndXJhdGlvblBhdGgpKVxuXG4gICAgLyoqXG4gICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvbkltcG9ydC5kZWZhdWx0XG5cbiAgICBpZiAoIXRoaXMuY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKGBDb25maWd1cmF0aW9uIGNvdWxkbid0IGJlIGxvYWRlZCBmcm9tOiAke2NvbmZpZ3VyYXRpb25QYXRofWApXG5cbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uXG5cbiAgICBjb25maWd1cmF0aW9uLmRlYnVnID0gZGVidWcgPT09IHRydWVcbiAgICBjb25maWd1cmF0aW9uLnNldEVudmlyb25tZW50KGVudmlyb25tZW50KVxuICAgIGNvbmZpZ3VyYXRpb24uc2V0Q3VycmVudCgpXG4gICAgYXdhaXQgdGhpcy5sb2dnZXIuZGVidWcoKCkgPT4gW1wiV29ya2VyIHRocmVhZCBjb25maWd1cmF0aW9uIGxvYWRlZFwiLCB7ZGVidWc6IGNvbmZpZ3VyYXRpb24uZGVidWcsIHdvcmtlckNvdW50OiB0aGlzLndvcmtlckNvdW50fV0pXG4gICAgdGhpcy53ZWJzb2NrZXRFdmVudHMgPSBuZXcgV2Vic29ja2V0RXZlbnRzKHtwYXJlbnRQb3J0OiB0aGlzLnBhcmVudFBvcnQsIHdvcmtlckNvdW50OiB0aGlzLndvcmtlckNvdW50fSlcbiAgICBjb25maWd1cmF0aW9uLnNldFdlYnNvY2tldEV2ZW50cyh0aGlzLndlYnNvY2tldEV2ZW50cylcblxuICAgIHRoaXMuYXBwbGljYXRpb24gPSBuZXcgQXBwbGljYXRpb24oe2NvbmZpZ3VyYXRpb24sIHR5cGU6IFwid29ya2VyLWhhbmRsZXJcIn0pXG5cbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24uaXNJbml0aWFsaXplZCgpKSB7XG4gICAgICBhd2FpdCBjb25maWd1cmF0aW9uLmluaXRpYWxpemUoe3R5cGU6IFwid29ya2VyLWhhbmRsZXJcIn0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9uIGNvbW1hbmQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gRGF0YSBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YS5jb21tYW5kIC0gQ29tbWFuZC5cbiAgICogQHBhcmFtIHtCdWZmZXIgfCBVaW50OEFycmF5IHwgc3RyaW5nfSBbZGF0YS5jaHVua10gLSBDaHVuay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkYXRhLnJlbW90ZUFkZHJlc3NdIC0gUmVtb3RlIGFkZHJlc3MuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YS5jbGllbnRDb3VudF0gLSBDbGllbnQgY291bnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGF0YS5jaGFubmVsXSAtIENoYW5uZWwgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkYXRhLmNyZWF0ZWRBdF0gLSBFdmVudCBjcmVhdGlvbiB0aW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEuZXZlbnRJZF0gLSBFdmVudCBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RhdGEucmVxdWVzdElkXSAtIERlYnVnIHJlcXVlc3QgaWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YS50cmFuc2ZlcklkXSAtIEZpbGUgdHJhbnNmZXIgaWQuXG4gICAqIEBwYXJhbSB7XCJjb21wbGV0ZWRcIiB8IFwiYWJvcnRlZFwifSBbZGF0YS5yZXN1bHRdIC0gRmlsZSB0cmFuc2ZlciByZXN1bHQuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IFtkYXRhLnBheWxvYWRdIC0gUGF5bG9hZCBkYXRhLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gW2RhdGEuYnJvYWRjYXN0UGFyYW1zXSAtIFYyIGJyb2FkY2FzdCBmaWx0ZXIgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBbZGF0YS5ib2R5XSAtIFYyIGJyb2FkY2FzdCBib2R5LlxuICAgKi9cbiAgb25Db21tYW5kID0gYXN5bmMgKGRhdGEpID0+IHtcbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1Z0xvd0xldmVsKCgpID0+IFtgV29ya2VyICR7dGhpcy53b3JrZXJDb3VudH0gcmVjZWl2ZWQgY29tbWFuZGAsIGRhdGFdKVxuXG4gICAgY29uc3QgY29tbWFuZCA9IGRhdGEuY29tbWFuZFxuXG4gICAgaWYgKGNvbW1hbmQgPT0gXCJuZXdDbGllbnRcIikge1xuICAgICAgdGhpcy5oYW5kbGVOZXdDbGllbnQoZGF0YSlcbiAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJjbGllbnRXcml0ZVwiKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUNsaWVudFdyaXRlKGRhdGEpXG4gICAgfSBlbHNlIGlmIChjb21tYW5kID09IFwiY2xpZW50RmlsZVJlc3VsdFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUNsaWVudEZpbGVSZXN1bHQoZGF0YSlcbiAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJjbGllbnRBYm9ydFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUNsaWVudEFib3J0KGRhdGEpXG4gICAgfSBlbHNlIGlmIChjb21tYW5kID09IFwid2Vic29ja2V0RXZlbnRcIikge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVXZWJzb2NrZXRFdmVudChkYXRhKVxuICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcIndlYnNvY2tldFYyQnJvYWRjYXN0XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlV2Vic29ja2V0VjJCcm9hZGNhc3QoZGF0YSlcbiAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJkZWJ1Z1NuYXBzaG90XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlRGVidWdTbmFwc2hvdChkYXRhKVxuICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcInNodXRkb3duXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlU2h1dGRvd24oKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gY29tbWFuZDogJHtjb21tYW5kfWApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIG5ldyBjbGllbnQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gRGF0YSBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RhdGEuY2xpZW50Q291bnRdIC0gQ2xpZW50IGNvdW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEucmVtb3RlQWRkcmVzc10gLSBSZW1vdGUgYWRkcmVzcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBoYW5kbGVOZXdDbGllbnQoZGF0YSkge1xuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJDb25maWd1cmF0aW9uIG5vdCBpbml0aWFsaXplZFwiKVxuXG4gICAgY29uc3Qge2NsaWVudENvdW50LCByZW1vdGVBZGRyZXNzfSA9IGRhdGFcblxuICAgIGlmICh0eXBlb2YgY2xpZW50Q291bnQgIT09IFwibnVtYmVyXCIpIHRocm93IG5ldyBFcnJvcihcImNsaWVudENvdW50IG11c3QgYmUgYSBudW1iZXJcIilcblxuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoe1xuICAgICAgY2xpZW50Q291bnQsXG4gICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sXG4gICAgICByZW1vdGVBZGRyZXNzXG4gICAgfSlcblxuICAgIGNsaWVudC5ldmVudHMub24oXCJvdXRwdXRcIiwgKG91dHB1dCwge3dlYnNvY2tldEZyYW1lID0gZmFsc2V9ID0ge30pID0+IHtcbiAgICAgIHRoaXMucGFyZW50UG9ydC5wb3N0TWVzc2FnZSh7Y29tbWFuZDogXCJjbGllbnRPdXRwdXRcIiwgY2xpZW50Q291bnQsIG91dHB1dCwgd2Vic29ja2V0RnJhbWV9KVxuICAgIH0pXG5cbiAgICBjbGllbnQuZXZlbnRzLm9uKFwiZmlsZVwiLCAoe2ZpbGVQYXRoLCBzZW5kQm9keSwgc2V0dGxlfSkgPT4ge1xuICAgICAgY29uc3QgdHJhbnNmZXJJZCA9ICsrdGhpcy5maWxlVHJhbnNmZXJDb3VudFxuXG4gICAgICB0aGlzLmZpbGVUcmFuc2ZlcnMuc2V0KHRyYW5zZmVySWQsIHtjbGllbnRDb3VudCwgc2V0dGxlfSlcbiAgICAgIHRoaXMucGFyZW50UG9ydC5wb3N0TWVzc2FnZSh7Y29tbWFuZDogXCJjbGllbnRGaWxlXCIsIGNsaWVudENvdW50LCBmaWxlUGF0aCwgc2VuZEJvZHksIHRyYW5zZmVySWR9KVxuICAgIH0pXG5cbiAgICBjbGllbnQuZXZlbnRzLm9uKFwiY2xvc2VcIiwgKG91dHB1dCkgPT4ge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWdMb3dMZXZlbCgoKSA9PiBcIkNsb3NlIHJlY2VpdmVkIGZyb20gY2xpZW50IGluIHdvcmtlciAtIGZvcndhcmRpbmcgdG8gd29ya2VyIHBhcmVudFwiKVxuICAgICAgdGhpcy5wYXJlbnRQb3J0LnBvc3RNZXNzYWdlKHtjb21tYW5kOiBcImNsaWVudENsb3NlXCIsIGNsaWVudENvdW50LCBvdXRwdXR9KVxuICAgIH0pXG5cbiAgICBjbGllbnQuZXZlbnRzLm9uKFwid2Vic29ja2V0U2Vzc2lvbk93bmVkXCIsICh7c2Vzc2lvbklkfSkgPT4ge1xuICAgICAgdGhpcy5wYXJlbnRQb3J0LnBvc3RNZXNzYWdlKHtjb21tYW5kOiBcIndlYnNvY2tldFNlc3Npb25Pd25lZFwiLCBzZXNzaW9uSWR9KVxuICAgIH0pXG5cbiAgICBjbGllbnQuZXZlbnRzLm9uKFwid2Vic29ja2V0U2Vzc2lvblJlbGVhc2VkXCIsICh7c2Vzc2lvbklkfSkgPT4ge1xuICAgICAgdGhpcy5wYXJlbnRQb3J0LnBvc3RNZXNzYWdlKHtjb21tYW5kOiBcIndlYnNvY2tldFNlc3Npb25SZWxlYXNlZFwiLCBzZXNzaW9uSWR9KVxuICAgIH0pXG5cbiAgICB0aGlzLmNsaWVudHNbY2xpZW50Q291bnRdID0gY2xpZW50XG4gIH1cblxuICAvKipcbiAgICogU2V0dGxlcyBhIGZpbGUgcmVzcG9uc2UgYWZ0ZXIgdGhlIHBhcmVudCBmaW5pc2hlcyBzb2NrZXQgZGVsaXZlcnkuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gRmlsZSByZXN1bHQgbWVzc2FnZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhLnRyYW5zZmVySWRdIC0gRmlsZSB0cmFuc2ZlciBpZC5cbiAgICogQHBhcmFtIHtcImNvbXBsZXRlZFwiIHwgXCJhYm9ydGVkXCJ9IFtkYXRhLnJlc3VsdF0gLSBGaWxlIHRyYW5zZmVyIHJlc3VsdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIHdvcmtlci1zaWRlIGNvbXBsZXRpb24gY2FsbGJhY2sgc2V0dGxlcy5cbiAgICovXG4gIGFzeW5jIGhhbmRsZUNsaWVudEZpbGVSZXN1bHQoZGF0YSkge1xuICAgIGNvbnN0IHtyZXN1bHQsIHRyYW5zZmVySWR9ID0gZGF0YVxuXG4gICAgaWYgKHR5cGVvZiB0cmFuc2ZlcklkICE9PSBcIm51bWJlclwiKSB0aHJvdyBuZXcgRXJyb3IoXCJ0cmFuc2ZlcklkIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICBpZiAocmVzdWx0ICE9PSBcImNvbXBsZXRlZFwiICYmIHJlc3VsdCAhPT0gXCJhYm9ydGVkXCIpIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBmaWxlIHRyYW5zZmVyIHJlc3VsdDogJHtyZXN1bHR9YClcblxuICAgIGNvbnN0IHRyYW5zZmVyID0gdGhpcy5maWxlVHJhbnNmZXJzLmdldCh0cmFuc2ZlcklkKVxuXG4gICAgaWYgKCF0cmFuc2ZlcikgcmV0dXJuXG5cbiAgICB0aGlzLmZpbGVUcmFuc2ZlcnMuZGVsZXRlKHRyYW5zZmVySWQpXG4gICAgYXdhaXQgdHJhbnNmZXIuc2V0dGxlKHJlc3VsdClcbiAgfVxuXG4gIC8qKlxuICAgKiBBYm9ydHMgZmlsZSByZXNwb25zZXMgYmVsb25naW5nIHRvIGEgY2xvc2VkIHBhcmVudC1zaWRlIHNvY2tldC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBDbGllbnQgYWJvcnQgbWVzc2FnZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhLmNsaWVudENvdW50XSAtIENsaWVudCBjb3VudC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgcGVuZGluZyBjb21wbGV0aW9uIGNhbGxiYWNrcyBzZXR0bGUuXG4gICAqL1xuICBhc3luYyBoYW5kbGVDbGllbnRBYm9ydChkYXRhKSB7XG4gICAgY29uc3Qge2NsaWVudENvdW50fSA9IGRhdGFcblxuICAgIGlmICh0eXBlb2YgY2xpZW50Q291bnQgIT09IFwibnVtYmVyXCIpIHRocm93IG5ldyBFcnJvcihcImNsaWVudENvdW50IG11c3QgYmUgYSBudW1iZXJcIilcblxuICAgIGNvbnN0IHNldHRsZW1lbnRzID0gW11cbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHNbY2xpZW50Q291bnRdXG5cbiAgICBpZiAoY2xpZW50KSB7XG4gICAgICBzZXR0bGVtZW50cy5wdXNoKGNsaWVudC5hYm9ydFBlbmRpbmdGaWxlUmVzcG9uc2VzKCkpXG4gICAgICBzZXR0bGVtZW50cy5wdXNoKGNsaWVudC5hYm9ydFN0cmVhbVJlc3BvbnNlcygpKVxuICAgICAgLy8gQnVmZmVyZWQgcmVzcG9uc2VzIGhhdmUgbm8gc3RyZWFtIHRvIGFib3J0LCBzbyB0aGVpciBpbi1mbGlnaHRcbiAgICAgIC8vIGhhbmRsZXJzIG5ldmVyIGhlYXIgYWJvdXQgdGhlIHNvY2tldCB0ZWFyZG93biB0aHJvdWdoIHRoZSBzdHJlYW1pbmdcbiAgICAgIC8vIHBhdGg6IG5vdGlmeSB0aGUgcnVubmluZyByZXF1ZXN0cyBkaXJlY3RseSBzbyB0aGV5IGNhbiBzZXR0bGVcbiAgICAgIC8vIHJlc291cmNlcyAoZS5nLiBhZG1pc3Npb24gcXVldWUgcG9zaXRpb25zKSBpbi1wcm9jZXNzLlxuICAgICAgY2xpZW50Lm5vdGlmeUNsaWVudERpc2Nvbm5lY3QoKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3RyYW5zZmVySWQsIHRyYW5zZmVyXSBvZiB0aGlzLmZpbGVUcmFuc2ZlcnMpIHtcbiAgICAgIGlmICh0cmFuc2Zlci5jbGllbnRDb3VudCAhPT0gY2xpZW50Q291bnQpIGNvbnRpbnVlXG5cbiAgICAgIHRoaXMuZmlsZVRyYW5zZmVycy5kZWxldGUodHJhbnNmZXJJZClcbiAgICAgIHNldHRsZW1lbnRzLnB1c2godHJhbnNmZXIuc2V0dGxlKFwiYWJvcnRlZFwiKSlcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5jbGllbnRzW2NsaWVudENvdW50XVxuICAgIGF3YWl0IFByb21pc2UuYWxsKHNldHRsZW1lbnRzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIGNsaWVudCB3cml0ZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBEYXRhIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7QnVmZmVyIHwgVWludDhBcnJheSB8IHN0cmluZ30gW2RhdGEuY2h1bmtdIC0gQ2h1bmsuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YS5jbGllbnRDb3VudF0gLSBDbGllbnQgY291bnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyB3aGVuIHRoZSBjbGllbnQgd3JpdGUgaXMgZGlzcGF0Y2hlZC5cbiAgICovXG4gIGFzeW5jIGhhbmRsZUNsaWVudFdyaXRlKGRhdGEpIHtcbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1Z0xvd0xldmVsKFwiTG9va2luZyB1cCBjbGllbnRcIilcblxuICAgIGNvbnN0IHtjaHVuaywgY2xpZW50Q291bnR9ID0gZGF0YVxuICAgIGlmICghY2h1bmspIHRocm93IG5ldyBFcnJvcihcIk5vIGNodW5rIGdpdmVuXCIpXG4gICAgY29uc3QgY2xpZW50ID0gLyoqIEB0eXBlIHtDbGllbnQgfCB1bmRlZmluZWR9ICovIChkaWdnKHRoaXMuY2xpZW50cywgY2xpZW50Q291bnQpKVxuXG4gICAgaWYgKCFjbGllbnQpIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IG5vdCBmb3VuZCBmb3IgY2xpZW50V3JpdGU6ICR7Y2xpZW50Q291bnR9YClcblxuICAgIGNvbnN0IGNsaWVudENodW5rID0gdHlwZW9mIGNodW5rID09PSBcInN0cmluZ1wiID8gQnVmZmVyLmZyb20oY2h1bmspIDogQnVmZmVyLmZyb20oY2h1bmspXG5cbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1ZygoKSA9PiBbXCJTZW5kaW5nIGNsaWVudFdyaXRlIHRvIHBhcnNlclwiLCB7Y2xpZW50Q291bnQsIC4uLnN1bW1hcml6ZUNsaWVudFdyaXRlQ2h1bmsoY2xpZW50Q2h1bmspfV0pXG5cbiAgICBjbGllbnQub25Xcml0ZShjbGllbnRDaHVuaylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhbmRsZSB3ZWJzb2NrZXQgZXZlbnQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gRGF0YSBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEuY2hhbm5lbF0gLSBDaGFubmVsIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGF0YS5jcmVhdGVkQXRdIC0gRXZlbnQgY3JlYXRpb24gdGltZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkYXRhLmV2ZW50SWRdIC0gRXZlbnQgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gW2RhdGEucGF5bG9hZF0gLSBQYXlsb2FkIGRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyB3aGVuIHRoZSB3ZWJzb2NrZXQgZXZlbnQgaXMgZGlzcGF0Y2hlZC5cbiAgICovXG4gIGFzeW5jIGhhbmRsZVdlYnNvY2tldEV2ZW50KGRhdGEpIHtcbiAgICBjb25zdCB7Y2hhbm5lbCwgY3JlYXRlZEF0LCBldmVudElkLCBwYXlsb2FkfSA9IGRhdGFcblxuICAgIGlmICh0eXBlb2YgY2hhbm5lbCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IEVycm9yKFwiTm8gY2hhbm5lbCBnaXZlblwiKVxuXG4gICAgYXdhaXQgdGhpcy5icm9hZGNhc3RXZWJzb2NrZXRFdmVudCh7Y2hhbm5lbCwgY3JlYXRlZEF0LCBldmVudElkLCBwYXlsb2FkfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhbmRsZSB3ZWJzb2NrZXQgdjIgYnJvYWRjYXN0LlxuICAgKiBAcGFyYW0ge29iamVjdH0gZGF0YSAtIERhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IFtkYXRhLmJyb2FkY2FzdFBhcmFtc10gLSBWMiBicm9hZGNhc3QgZmlsdGVyIHBhcmFtcy5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gW2RhdGEuYm9keV0gLSBWMiBicm9hZGNhc3QgYm9keS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkYXRhLmNoYW5uZWxdIC0gQ2hhbm5lbCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RhdGEuZXZlbnRJZF0gLSBFdmVudCBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGhhbmRsZVdlYnNvY2tldFYyQnJvYWRjYXN0KGRhdGEpIHtcbiAgICBjb25zdCB7Ym9keSwgYnJvYWRjYXN0UGFyYW1zLCBjaGFubmVsLCBldmVudElkfSA9IGRhdGFcblxuICAgIGlmICh0eXBlb2YgY2hhbm5lbCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IEVycm9yKFwiTm8gY2hhbm5lbCBnaXZlblwiKVxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJDb25maWd1cmF0aW9uIG5vdCBpbml0aWFsaXplZFwiKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uLl9icm9hZGNhc3RUb0NoYW5uZWxMb2NhbChjaGFubmVsLCBicm9hZGNhc3RQYXJhbXMgfHwge30sIGJvZHksIHtldmVudElkfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhbmRsZSBkZWJ1ZyBzbmFwc2hvdC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBEYXRhIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YS5yZXF1ZXN0SWRdIC0gRGVidWcgcmVxdWVzdCBpZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBoYW5kbGVEZWJ1Z1NuYXBzaG90KGRhdGEpIHtcbiAgICBjb25zdCB7cmVxdWVzdElkfSA9IGRhdGFcblxuICAgIGlmICh0eXBlb2YgcmVxdWVzdElkICE9PSBcIm51bWJlclwiKSB0aHJvdyBuZXcgRXJyb3IoXCJkZWJ1Z1NuYXBzaG90IHJlcXVlc3RJZCBtdXN0IGJlIGEgbnVtYmVyXCIpXG4gICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24pIHRocm93IG5ldyBFcnJvcihcIkNvbmZpZ3VyYXRpb24gbm90IGluaXRpYWxpemVkXCIpXG5cbiAgICB0aGlzLnBhcmVudFBvcnQucG9zdE1lc3NhZ2Uoe1xuICAgICAgY29tbWFuZDogXCJkZWJ1Z1NuYXBzaG90XCIsXG4gICAgICByZXF1ZXN0SWQsXG4gICAgICBzbmFwc2hvdDogdGhpcy5jb25maWd1cmF0aW9uLmdldExvY2FsRGVidWdTbmFwc2hvdCgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhbmRsZSBzaHV0ZG93bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIGFmdGVyIHdvcmtlciBzaHV0ZG93biBoYXMgYmVlbiByZXF1ZXN0ZWQuXG4gICAqL1xuICBhc3luYyBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBjb25zdCBjbGllbnRzID0gT2JqZWN0LnZhbHVlcyh0aGlzLmNsaWVudHMpXG5cbiAgICBhd2FpdCBydW5TaHV0ZG93blN0ZXBzKHtcbiAgICAgIG1lc3NhZ2U6IFwiSFRUUCB3b3JrZXItaGFuZGxlciBzaHV0ZG93biBmYWlsZWRcIixcbiAgICAgIHN0ZXBzOiBbXG4gICAgICAgIC4uLmNsaWVudHMubWFwKChjbGllbnQpID0+IGFzeW5jICgpID0+IGF3YWl0IGNsaWVudC5hYm9ydFBlbmRpbmdGaWxlUmVzcG9uc2VzKCkpLFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5maWxlVHJhbnNmZXJzLmNsZWFyKClcbiAgICAgICAgICBhd2FpdCB0aGlzLmFwcGxpY2F0aW9uPy5zdG9wKClcbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pXG5cbiAgICB0aGlzLnBhcmVudFBvcnQucG9zdE1lc3NhZ2Uoe2NvbW1hbmQ6IFwic2h1dGRvd25Db21wbGV0ZVwifSlcbiAgICBwcm9jZXNzLmV4aXQoMClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGJyb2FkY2FzdCB3ZWJzb2NrZXQgZXZlbnQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNoYW5uZWwgLSBDaGFubmVsIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBhcmdzLmNyZWF0ZWRBdCAtIEV2ZW50IGNyZWF0aW9uIHRpbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBhcmdzLmV2ZW50SWQgLSBFdmVudCBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhcmdzLnBheWxvYWQgLSBQYXlsb2FkIGRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBicm9hZGNhc3RXZWJzb2NrZXRFdmVudCh7Y2hhbm5lbCwgY3JlYXRlZEF0LCBldmVudElkLCBwYXlsb2FkfSkge1xuICAgIGNvbnN0IHNlbmRUYXNrcyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGNsaWVudEtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmNsaWVudHMpKSB7XG4gICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHNbTnVtYmVyKGNsaWVudEtleSldXG4gICAgICBpZiAoIWNsaWVudCkgY29udGludWVcbiAgICAgIGNvbnN0IHNlc3Npb24gPSBjbGllbnQud2Vic29ja2V0U2Vzc2lvblxuXG4gICAgICBpZiAoIXNlc3Npb24pIGNvbnRpbnVlXG5cbiAgICAgIHNlbmRUYXNrcy5wdXNoKHNlc3Npb24uc2VuZEV2ZW50KGNoYW5uZWwsIHBheWxvYWQsIHtcbiAgICAgICAgY3JlYXRlZEF0LFxuICAgICAgICBldmVudElkXG4gICAgICB9KSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uKSB7XG4gICAgICAvLyBJc29sYXRlIGNoYW5uZWwgc3Vic2NyaWJlciBmYWlsdXJlcyBzbyBhIGJ1Z2d5IGluLXByb2Nlc3MgY2FsbGJhY2tcbiAgICAgIC8vIGNhbm5vdCByZWplY3QgdGhpcyBjb21tYW5kIGFuZCBjcmFzaCB0aGUgd29ya2VyIHRocmVhZCwgYnV0IHN0aWxsXG4gICAgICAvLyBzdXJmYWNlIHRoZSBlcnJvciB0byB0aGUgZnJhbWV3b3JrIGVycm9yIGV2ZW50cyBzbyBidWcgcmVwb3J0ZXJzXG4gICAgICAvLyBjYW4gcGljayBpdCB1cC5cbiAgICAgIHNlbmRUYXNrcy5wdXNoKGRpc3BhdGNoQ2hhbm5lbFN1YnNjcmliZXJzKHtjaGFubmVsLCBjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sIGNyZWF0ZWRBdCwgZXZlbnRJZCwgbG9nZ2VyOiB0aGlzLmxvZ2dlciwgcGF5bG9hZH0pKVxuICAgIH1cblxuICAgIGF3YWl0IFByb21pc2UuYWxsKHNlbmRUYXNrcylcbiAgfVxufVxuIl19
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "build/bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.683",
6
+ "version": "1.0.684",
7
7
  "main": "build/index.js",
8
8
  "types": "build/index.d.ts",
9
9
  "files": [
@@ -803,6 +803,21 @@ export default class VeoliciousHttpServerClient {
803
803
  }
804
804
  }
805
805
 
806
+ /**
807
+ * Marks every in-flight request as client-disconnected and runs its
808
+ * disconnect callbacks. The worker handler calls this when the underlying
809
+ * socket tears down, so a handler whose response is still buffered (e.g.
810
+ * waiting in an admission queue) can observe the client leaving without
811
+ * waiting for the response to be sent.
812
+ * @returns {void}
813
+ */
814
+ notifyClientDisconnect() {
815
+ for (const requestRunner of this.requestRunners) {
816
+ if (requestRunner.getState() !== "running") continue
817
+ requestRunner.getRequest().markClientDisconnected()
818
+ }
819
+ }
820
+
806
821
  /**
807
822
  * Runs the close callbacks of a finished or aborted stream exactly once.
808
823
  * @param {import("./response.js").default} response - Finished stream.
@@ -19,6 +19,17 @@ export default class VelociousHttpServerClientRequest {
19
19
  this.client = client
20
20
  this.configuration = configuration
21
21
  this.requestParser = new RequestParser({configuration})
22
+
23
+ /**
24
+ * Whether the owning client connection was torn down while this request
25
+ * was still running. Set once by the client on socket teardown and read
26
+ * by handlers that need to settle in-flight work (e.g. admission queue
27
+ * positions) without waiting for the response to be sent.
28
+ * @type {boolean} */
29
+ this.clientDisconnected = false
30
+
31
+ /** @type {Set<() => void>} */
32
+ this.clientDisconnectCallbacks = new Set()
22
33
  }
23
34
 
24
35
  baseURL() { return `${this.protocol()}://${this.hostWithPort()}` }
@@ -114,6 +125,39 @@ export default class VelociousHttpServerClientRequest {
114
125
  rawBody() { return this.getRequestBuffer().getRawBody() }
115
126
  socketRemoteAddress() { return this.client?.remoteAddress }
116
127
 
128
+ /**
129
+ * Marks this request as client-disconnected and runs every registered
130
+ * disconnect callback exactly once. The owning client invokes it when the
131
+ * socket tears down; handlers that register afterwards learn of the
132
+ * disconnect through the `clientDisconnected` field instead.
133
+ * @returns {void}
134
+ */
135
+ markClientDisconnected() {
136
+ if (this.clientDisconnected) return
137
+ this.clientDisconnected = true
138
+ for (const callback of this.clientDisconnectCallbacks) {
139
+ callback()
140
+ }
141
+ this.clientDisconnectCallbacks.clear()
142
+ }
143
+
144
+ /**
145
+ * Registers a callback that fires once when the client connection tears
146
+ * down while this request is still running. Buffered requests cannot rely
147
+ * on the streaming response's `onStreamClose` for that: no stream has
148
+ * been opened yet, so a queued request's queue position is otherwise
149
+ * stranded until its admission deadline.
150
+ * @param {() => void} callback - Disconnect callback.
151
+ * @returns {void}
152
+ */
153
+ onClientDisconnect(callback) {
154
+ if (this.clientDisconnected) {
155
+ callback()
156
+ return
157
+ }
158
+ this.clientDisconnectCallbacks.add(callback)
159
+ }
160
+
117
161
  getRequestBuffer() { return this.getRequestParser().getRequestBuffer() }
118
162
  getRequestParser() { return this.requestParser }
119
163
  }
@@ -50,6 +50,51 @@ export default class VelociousHttpServerClientWebsocketRequest {
50
50
  const queryParams = this._parseQueryParams()
51
51
 
52
52
  this.paramsObject = {...queryParams, ...this.paramsObject}
53
+
54
+ /**
55
+ * Whether the owning client connection was torn down while this request
56
+ * was still running. Websocket requests are session-owned and never
57
+ * enter the client's in-flight request list, so this stays false for
58
+ * them; the field exists so the request union shares one surface.
59
+ * @type {boolean} */
60
+ this.clientDisconnected = false
61
+
62
+ /** @type {Set<() => void>} */
63
+ this.clientDisconnectCallbacks = new Set()
64
+ }
65
+
66
+ /**
67
+ * Marks this request as client-disconnected and runs every registered
68
+ * disconnect callback exactly once. The owning client invokes it when the
69
+ * socket tears down; handlers that register afterwards learn of the
70
+ * disconnect through the `clientDisconnected` field instead. Websocket
71
+ * requests are session-owned and never enter the client's in-flight
72
+ * request list, so this is inert for them; the shared surface keeps the
73
+ * request union uniform.
74
+ * @returns {void}
75
+ */
76
+ markClientDisconnected() {
77
+ if (this.clientDisconnected) return
78
+ this.clientDisconnected = true
79
+ for (const callback of this.clientDisconnectCallbacks) {
80
+ callback()
81
+ }
82
+ this.clientDisconnectCallbacks.clear()
83
+ }
84
+
85
+ /**
86
+ * Registers a callback that fires once when the client connection tears
87
+ * down while this request is still running. See the HTTP request's
88
+ * {@linkcode markClientDisconnected} for the shared-surface note.
89
+ * @param {() => void} callback - Disconnect callback.
90
+ * @returns {void}
91
+ */
92
+ onClientDisconnect(callback) {
93
+ if (this.clientDisconnected) {
94
+ callback()
95
+ return
96
+ }
97
+ this.clientDisconnectCallbacks.add(callback)
53
98
  }
54
99
 
55
100
  baseURL() {
@@ -116,7 +116,13 @@ export default class VelociousHttpServerInProcessHandler {
116
116
  httpClient.abortPendingFileResponses(),
117
117
  httpClient.abortStreamResponses()
118
118
  ])
119
- .then(() => {})
119
+ .then(() => {
120
+ // Buffered responses have no stream to abort, so their in-flight
121
+ // handlers never hear about the socket teardown through the
122
+ // streaming path: notify the running requests directly so they can
123
+ // settle resources (e.g. admission queue positions) in-process.
124
+ httpClient.notifyClientDisconnect()
125
+ })
120
126
  .catch((error) => {
121
127
  this.logger.warn("Failed to abort responses after client close", error)
122
128
  })
@@ -220,6 +220,11 @@ export default class VelociousHttpServerWorkerHandlerWorkerThread {
220
220
  if (client) {
221
221
  settlements.push(client.abortPendingFileResponses())
222
222
  settlements.push(client.abortStreamResponses())
223
+ // Buffered responses have no stream to abort, so their in-flight
224
+ // handlers never hear about the socket teardown through the streaming
225
+ // path: notify the running requests directly so they can settle
226
+ // resources (e.g. admission queue positions) in-process.
227
+ client.notifyClientDisconnect()
223
228
  }
224
229
 
225
230
  for (const [transferId, transfer] of this.fileTransfers) {