@rdfc/js-runner 3.1.0-alpha.1 → 3.1.0

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.
package/lib/writer.js CHANGED
@@ -11,7 +11,6 @@ export class WriterInstance {
11
11
  shouldClose = [];
12
12
  closed = false;
13
13
  _canceled = false;
14
- cancelSignal = new AbortController();
15
14
  cancelHandlers = new Set();
16
15
  runnerId;
17
16
  constructor(uri, client, notifyOrchestrator, runnerId, logger) {
@@ -33,51 +32,6 @@ export class WriterInstance {
33
32
  cancellationError() {
34
33
  return new Error(`Writer for channel ${this.uri} was canceled by the connected reader`);
35
34
  }
36
- emitCancel() {
37
- for (const handler of this.cancelHandlers) {
38
- try {
39
- Promise.resolve(handler()).catch((error) => {
40
- this.logger.error(`Cancel listener for channel ${this.uri} failed: ${String(error)}`);
41
- });
42
- }
43
- catch (error) {
44
- this.logger.error(`Cancel listener for channel ${this.uri} failed: ${String(error)}`);
45
- }
46
- }
47
- }
48
- assertCanWrite() {
49
- if (this._canceled) {
50
- throw this.cancellationError();
51
- }
52
- if (this.closed) {
53
- throw new Error(`Writer for channel ${this.uri} is closed`);
54
- }
55
- }
56
- async raceWithCancellation(promise) {
57
- this.assertCanWrite();
58
- return await new Promise((resolve, reject) => {
59
- const onAbort = () => reject(this.cancellationError());
60
- this.cancelSignal.signal.addEventListener('abort', onAbort, {
61
- once: true,
62
- });
63
- promise.then((value) => {
64
- this.cancelSignal.signal.removeEventListener('abort', onAbort);
65
- resolve(value);
66
- }, (error) => {
67
- this.cancelSignal.signal.removeEventListener('abort', onAbort);
68
- reject(error);
69
- });
70
- });
71
- }
72
- rejectPendingProcessed(error) {
73
- while (this.awaitingProcessed.length > 0) {
74
- this.awaitingProcessed.shift().reject(error);
75
- }
76
- }
77
- awaitProcessed() {
78
- this.assertCanWrite();
79
- return new Promise((resolve, reject) => this.awaitingProcessed.push({ resolve, reject }));
80
- }
81
35
  async any(any) {
82
36
  if ('stream' in any) {
83
37
  await this.stream(any.stream);
@@ -89,6 +43,14 @@ export class WriterInstance {
89
43
  await this.string(any.string);
90
44
  }
91
45
  }
46
+ assertCanWrite() {
47
+ if (this._canceled) {
48
+ throw this.cancellationError();
49
+ }
50
+ if (this.closed) {
51
+ throw new Error(`Writer for channel ${this.uri} is closed`);
52
+ }
53
+ }
92
54
  async buffer(buffer) {
93
55
  this.assertCanWrite();
94
56
  this.logger.debug(`${this.uri} sends buffer ${buffer.length} bytes`);
@@ -115,7 +77,7 @@ export class WriterInstance {
115
77
  runner: this.runnerId,
116
78
  },
117
79
  });
118
- const id = await this.raceWithCancellation(new Promise((res) => stream.once('data', res)));
80
+ const id = await new Promise((res) => stream.once('data', res));
119
81
  this.logger.debug(`${this.uri} streams message with id ${JSON.stringify(id)}`);
120
82
  for await (const msg of buffer) {
121
83
  const processedPromise = new Promise((res) => stream.once('data', res));
@@ -150,43 +112,35 @@ export class WriterInstance {
150
112
  await handledPromise;
151
113
  }
152
114
  async close(issued = false) {
153
- if (issued) {
154
- if (!this.closed) {
155
- this._canceled = true;
156
- this.emitCancel();
157
- }
158
- this.closed = true;
159
- const cancelError = this.cancellationError();
160
- this.rejectPendingProcessed(cancelError);
161
- this.cancelSignal.abort(cancelError);
162
- let waiting = this.shouldClose.pop();
163
- while (waiting) {
164
- waiting();
165
- waiting = this.shouldClose.pop();
166
- }
167
- return;
168
- }
169
- if (this.closed) {
170
- return;
115
+ this.closed = true;
116
+ if (issued && !this._canceled) {
117
+ this._canceled = true;
118
+ await this.emitCancel();
171
119
  }
172
120
  if (this.openStreams !== 0) {
173
121
  await new Promise((resolve) => this.shouldClose.push(resolve));
174
122
  return;
175
123
  }
176
124
  this.logger.debug(`${this.uri} closes stream`);
177
- this.closed = true;
178
- await this.notifyOrchestrator({
179
- close: { channel: this.uri },
180
- });
125
+ if (!issued) {
126
+ await this.notifyOrchestrator({
127
+ close: { channel: this.uri },
128
+ });
129
+ }
181
130
  let resolve = this.shouldClose.pop();
182
131
  while (resolve) {
183
132
  resolve();
184
133
  resolve = this.shouldClose.pop();
185
134
  }
186
135
  }
187
- handled() {
136
+ handled(error) {
188
137
  if (this.awaitingProcessed.length > 0) {
189
- this.awaitingProcessed.shift().resolve();
138
+ if (error) {
139
+ this.awaitingProcessed.shift().reject(new Error(error));
140
+ }
141
+ else {
142
+ this.awaitingProcessed.shift().resolve();
143
+ }
190
144
  }
191
145
  else if (this.closed || this._canceled) {
192
146
  return;
@@ -196,5 +150,18 @@ export class WriterInstance {
196
150
  this.uri);
197
151
  }
198
152
  }
153
+ async emitCancel() {
154
+ await Promise.all(Array.from(this.cancelHandlers).map(async (handler) => {
155
+ try {
156
+ await handler();
157
+ }
158
+ catch (error) {
159
+ this.logger.error(`Cancel listener for channel ${this.uri} failed: ${String(error)}`);
160
+ }
161
+ }));
162
+ }
163
+ awaitProcessed() {
164
+ return new Promise((resolve, reject) => this.awaitingProcessed.push({ resolve, reject }));
165
+ }
199
166
  }
200
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBeUJoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEdBQUcsQ0FBUTtJQUNwQixtQkFBbUIsR0FBVyxDQUFDLENBQUE7SUFDZCxNQUFNLENBQWM7SUFDcEIsa0JBQWtCLENBQVU7SUFDNUIsTUFBTSxDQUFRO0lBR3ZCLGlCQUFpQixHQUdwQixFQUFFLENBQUE7SUFFQyxXQUFXLEdBQVcsQ0FBQyxDQUFBO0lBRXZCLFdBQVcsR0FBc0IsRUFBRSxDQUFBO0lBQ25DLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDZCxTQUFTLEdBQUcsS0FBSyxDQUFBO0lBR1IsWUFBWSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUE7SUFFcEMsY0FBYyxHQUFHLElBQUksR0FBRyxFQUFXLENBQUE7SUFFbkMsUUFBUSxDQUFRO0lBRWpDLFlBQ0UsR0FBVyxFQUNYLE1BQW9CLEVBQ3BCLGtCQUE0QixFQUM1QixRQUFnQixFQUNoQixNQUFjO1FBRWQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFBO1FBQzVDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFBO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDMUIsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQTtJQUN2QixDQUFDO0lBRUQsRUFBRSxDQUFDLEtBQWUsRUFBRSxRQUFpQjtRQUNuQyxJQUFJLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN2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RUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtTQUM3QixDQUFDLENBQUE7UUFFRixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ3BDLE9BQU8sT0FBTyxFQUFFLENBQUM7WUFDZixPQUFPLEVBQUUsQ0FBQTtZQUNULE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBS0QsT0FBTztRQUNMLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFHLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDM0MsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFFekMsT0FBTTtRQUNSLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2YsaUZBQWlGO2dCQUMvRSxJQUFJLENBQUMsR0FBRyxDQUNYLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRnJvbVJ1bm5lciwgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnd2luc3RvbidcbmltcG9ydCB7IEFueSB9IGZyb20gJy4vcmVhZGVyJ1xuXG50eXBlIFdyaXRhYmxlID0gKG1zZzogRnJvbVJ1bm5lcikgPT4gUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IHR5cGUgSGFuZGxlcjxUID0gdm9pZD4gPSBbVF0gZXh0ZW5kcyBbdm9pZF1cbiAgPyAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPlxuICA6ICh2YWx1ZTogVCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD5cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICByZWFkb25seSB1cmk6IHN0cmluZ1xuICByZWFkb25seSBjYW5jZWxlZDogYm9vbGVhblxuICBvbihldmVudDogJ2NhbmNlbCcsIGxpc3RlbmVyOiBIYW5kbGVyKTogdGhpc1xuICBidWZmZXIoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmVhbShidWZmZXI6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBQcm9taXNlPHZvaWQ+XG4gIHN0cmVhbTxUPihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtOiAoeDogVCkgPT4gVWludDhBcnJheSxcbiAgKTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmluZyhidWZmZXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cbiAgYW55KGFueTogQW55KTogUHJvbWlzZTx2b2lkPlxuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+XG59XG5jb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKClcbmV4cG9ydCBjbGFzcyBXcml0ZXJJbnN0YW5jZSBpbXBsZW1lbnRzIFdyaXRlciB7XG4gIHJlYWRvbmx5IHVyaTogc3RyaW5nXG4gIGxvY2FsU2VxdWVuY2VOdW1iZXI6IG51bWJlciA9IDFcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFJ1bm5lckNsaWVudFxuICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGVcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlclxuXG4gIC8vIEZJRk8gb2YgbWVzc2FnZS1sZXZlbCBhY2tub3dsZWRnZW1lbnRzIGNvbWluZyBiYWNrIGZyb20gdGhlIG9yY2hlc3RyYXRvci5cbiAgcHJpdmF0ZSBhd2FpdGluZ1Byb2Nlc3NlZDogQXJyYXk8e1xuICAgIHJlc29sdmU6ICgpID0+IHZvaWRcbiAgICByZWplY3Q6IChyZWFzb246IEVycm9yKSA9PiB2b2lkXG4gIH0+ID0gW11cblxuICBwcml2YXRlIG9wZW5TdHJlYW1zOiBudW1iZXIgPSAwXG4gIC8vIENsb3NlIGNhbGxlcnMgd2FpdCBoZXJlIHdoaWxlIGFjdGl2ZSBzdHJlYW1zIGFyZSBzdGlsbCBmbHVzaGluZy5cbiAgcHJpdmF0ZSBzaG91bGRDbG9zZTogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXVxuICBwcml2YXRlIGNsb3NlZCA9IGZhbHNlXG4gIHByaXZhdGUgX2NhbmNlbGVkID0gZmFsc2VcblxuICAvLyBTaGFyZWQgY2FuY2VsbGF0aW9uIHNpZ25hbCB0byBhYm9ydCBpbi1mbGlnaHQgd2FpdHMgd2hlbiB0aGUgcmVtb3RlIGNsb3Nlcy5cbiAgcHJpdmF0ZSByZWFkb25seSBjYW5jZWxTaWduYWwgPSBuZXcgQWJvcnRDb250cm9sbGVyKClcbiAgLy8gUHJvY2Vzc29ycyBjYW4gc3Vic2NyaWJlIGhlcmUgdG8gc3RvcCB1cHN0cmVhbSB3b3JrIHdoZW4gZG93bnN0cmVhbSBjYW5jZWxzLlxuICBwcml2YXRlIHJlYWRvbmx5IGNhbmNlbEhhbmRsZXJzID0gbmV3IFNldDxIYW5kbGVyPigpXG5cbiAgcHJpdmF0ZSByZWFkb25seSBydW5uZXJJZDogc3RyaW5nXG5cbiAgY29uc3RydWN0b3IoXG4gICAgdXJpOiBzdHJpbmcsXG4gICAgY2xpZW50OiBSdW5uZXJDbGllbnQsXG4gICAgbm90aWZ5T3JjaGVzdHJhdG9yOiBXcml0YWJsZSxcbiAgICBydW5uZXJJZDogc3RyaW5nLFxuICAgIGxvZ2dlcjogTG9nZ2VyLFxuICApIHtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudFxuICAgIHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yID0gbm90aWZ5T3JjaGVzdHJhdG9yXG4gICAgdGhpcy51cmkgPSB1cmlcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlclxuICAgIHRoaXMucnVubmVySWQgPSBydW5uZXJJZFxuICB9XG5cbiAgZ2V0IGNhbmNlbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9jYW5jZWxlZFxuICB9XG5cbiAgb24oZXZlbnQ6ICdjYW5jZWwnLCBsaXN0ZW5lcjogSGFuZGxlcik6IHRoaXMge1xuICAgIGlmIChldmVudCA9PT0gJ2NhbmNlbCcpIHtcbiAgICAgIHRoaXMuY2FuY2VsSGFuZGxlcnMuYWRkKGxpc3RlbmVyKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBwcml2YXRlIGNhbmNlbGxhdGlvbkVycm9yKCk6IEVycm9yIHtcbiAgICByZXR1cm4gbmV3IEVycm9yKFxuICAgICAgYFdyaXRlciBmb3IgY2hhbm5lbCAke3RoaXMudXJpfSB3YXMgY2FuY2VsZWQgYnkgdGhlIGNvbm5lY3RlZCByZWFkZXJgLFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgZW1pdENhbmNlbCgpIHtcbiAgICBmb3IgKGNvbnN0IGhhbmRsZXIgb2YgdGhpcy5jYW5jZWxIYW5kbGVycykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKGhhbmRsZXIoKSkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICBgQ2FuY2VsIGxpc3RlbmVyIGZvciBjaGFubmVsICR7dGhpcy51cml9IGZhaWxlZDogJHtTdHJpbmcoZXJyb3IpfWAsXG4gICAgICAgICAgKVxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgYENhbmNlbCBsaXN0ZW5lciBmb3IgY2hhbm5lbCAke3RoaXMudXJpfSBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX1gLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3NlcnRDYW5Xcml0ZSgpIHtcbiAgICBpZiAodGhpcy5fY2FuY2VsZWQpIHtcbiAgICAgIHRocm93IHRoaXMuY2FuY2VsbGF0aW9uRXJyb3IoKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBXcml0ZXIgZm9yIGNoYW5uZWwgJHt0aGlzLnVyaX0gaXMgY2xvc2VkYClcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJhY2VXaXRoQ2FuY2VsbGF0aW9uPFQ+KHByb21pc2U6IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICB0aGlzLmFzc2VydENhbldyaXRlKClcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4gcmVqZWN0KHRoaXMuY2FuY2VsbGF0aW9uRXJyb3IoKSlcbiAgICAgIHRoaXMuY2FuY2VsU2lnbmFsLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQsIHtcbiAgICAgICAgb25jZTogdHJ1ZSxcbiAgICAgIH0pXG5cbiAgICAgIHByb21pc2UudGhlbihcbiAgICAgICAgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgLy8gQ2xlYW4gdXAgdGhlIGFib3J0IGxpc3RlbmVyIGlmIHRoZSBvcmlnaW5hbCBvcGVyYXRpb24gZmluaXNoZWQgZmlyc3QuXG4gICAgICAgICAgdGhpcy5jYW5jZWxTaWduYWwuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydClcbiAgICAgICAgICByZXNvbHZlKHZhbHVlKVxuICAgICAgICB9LFxuICAgICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgICB0aGlzLmNhbmNlbFNpZ25hbC5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkFib3J0KVxuICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgfSxcbiAgICAgIClcbiAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSByZWplY3RQZW5kaW5nUHJvY2Vzc2VkKGVycm9yOiBFcnJvcikge1xuICAgIC8vIFJlamVjdCBhbGwgcXVldWVkIG1lc3NhZ2Ugd2FpdHMgc28gY2FsbGVycyBkbyBub3QgaGFuZyBkdXJpbmcgY2FuY2VsbGF0aW9uLlxuICAgIHdoaWxlICh0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEucmVqZWN0KGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXdhaXRQcm9jZXNzZWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+XG4gICAgICB0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLnB1c2goeyByZXNvbHZlLCByZWplY3QgfSksXG4gICAgKVxuICB9XG5cbiAgYXN5bmMgYW55KGFueTogQW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCdzdHJlYW0nIGluIGFueSkge1xuICAgICAgYXdhaXQgdGhpcy5zdHJlYW0oYW55LnN0cmVhbSlcbiAgICB9XG4gICAgaWYgKCdidWZmZXInIGluIGFueSkge1xuICAgICAgYXdhaXQgdGhpcy5idWZmZXIoYW55LmJ1ZmZlcilcbiAgICB9XG4gICAgaWYgKCdzdHJpbmcnIGluIGFueSkge1xuICAgICAgYXdhaXQgdGhpcy5zdHJpbmcoYW55LnN0cmluZylcbiAgICB9XG4gIH1cblxuICBhc3luYyBidWZmZXIoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7dGhpcy51cml9IHNlbmRzIGJ1ZmZlciAke2J1ZmZlci5sZW5ndGh9IGJ5dGVzYClcbiAgICBjb25zdCBsb2NhbFNlcXVlbmNlTnVtYmVyID0gdGhpcy5sb2NhbFNlcXVlbmNlTnVtYmVyKytcbiAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoKVxuXG4gICAgYXdhaXQgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3Ioe1xuICAgICAgbXNnOiB7IGRhdGE6IGJ1ZmZlciwgY2hhbm5lbDogdGhpcy51cmksIGxvY2FsU2VxdWVuY2VOdW1iZXIgfSxcbiAgICB9KVxuICAgIGF3YWl0IGhhbmRsZWRQcm9taXNlXG4gIH1cblxuICBhc3luYyBzdHJlYW08VCA9IFVpbnQ4QXJyYXk+KFxuICAgIGJ1ZmZlcjogQXN5bmNJdGVyYWJsZTxUPixcbiAgICB0cmFuc2Zvcm0/OiAoeDogVCkgPT4gVWludDhBcnJheSxcbiAgKSB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5vcGVuU3RyZWFtcyArPSAxXG4gICAgY29uc3QgdCA9IHRyYW5zZm9ybSB8fCAoKHg6IHVua25vd24pID0+IDxVaW50OEFycmF5PngpXG4gICAgY29uc3Qgc3RyZWFtID0gdGhpcy5jbGllbnQuc2VuZFN0cmVhbU1lc3NhZ2UoKVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE1lc3NhZ2UtbGV2ZWwgYWNrIHRoYXQgc2lnbmFscyB0aGUgd2hvbGUgc3RyZWFtIG1lc3NhZ2UgaXMgZnVsbHkgaGFuZGxlZC5cbiAgICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG4gICAgICBjb25zdCB3cml0ZVN0cmVhbU1lc3NhZ2VDaHVuayA9IHByb21pc2lmeShzdHJlYW0ud3JpdGUuYmluZChzdHJlYW0pKVxuICAgICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgICBhd2FpdCB3cml0ZVN0cmVhbU1lc3NhZ2VDaHVuayh7XG4gICAgICAgIGlkOiB7XG4gICAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgICAgbG9jYWxTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgICBydW5uZXI6IHRoaXMucnVubmVySWQsXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBGaXJzdCByZXNwb25zZSBjb25maXJtcyBzdHJlYW0gaWQgcmVnaXN0cmF0aW9uIG9uIHRoZSByZW1vdGUgc2lkZS5cbiAgICAgIGNvbnN0IGlkID0gYXdhaXQgdGhpcy5yYWNlV2l0aENhbmNlbGxhdGlvbihcbiAgICAgICAgbmV3IFByb21pc2UoKHJlcykgPT4gc3RyZWFtLm9uY2UoJ2RhdGEnLCByZXMpKSxcbiAgICAgIClcblxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGAke3RoaXMudXJpfSBzdHJlYW1zIG1lc3NhZ2Ugd2l0aCBpZCAke0pTT04uc3RyaW5naWZ5KGlkKX1gLFxuICAgICAgKVxuXG4gICAgICBmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBidWZmZXIpIHtcbiAgICAgICAgY29uc3QgcHJvY2Vzc2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcbiAgICAgICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoeyBkYXRhOiB7IGRhdGE6IHQobXNnKSB9IH0pXG4gICAgICAgIC8vIEF3YWl0IGEgbWVzc2FnZSBvbiB0aGUgc3RyZWFtLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNodW5rIGhhcyBiZWVuIHByb2Nlc3NlZFxuICAgICAgICBhd2FpdCBwcm9jZXNzZWRQcm9taXNlXG4gICAgICB9XG5cbiAgICAgIHN0cmVhbS5lbmQoKVxuXG4gICAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLm9wZW5TdHJlYW1zIC09IDFcblxuICAgICAgaWYgKCFzdHJlYW0ud3JpdGFibGVFbmRlZCkge1xuICAgICAgICBzdHJlYW0uZW5kKClcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYSBjbG9zZSBjYWxsIHdhcyBkZWZlcnJlZCB3aGlsZSBzdHJlYW1pbmcsIGNvbXBsZXRlIGl0IG5vdy5cbiAgICAgIGlmICh0aGlzLnNob3VsZENsb3NlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbG9zZSgpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc3RyaW5nKG1zZzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7dGhpcy51cml9IHNlbmRzIHN0cmluZyAke21zZy5sZW5ndGh9IGNoYXJhY3RlcnNgKVxuICAgIGNvbnN0IGxvY2FsU2VxdWVuY2VOdW1iZXIgPSB0aGlzLmxvY2FsU2VxdWVuY2VOdW1iZXIrK1xuICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG5cbiAgICBhd2FpdCB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvcih7XG4gICAgICBtc2c6IHtcbiAgICAgICAgZGF0YTogZW5jb2Rlci5lbmNvZGUobXNnKSxcbiAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgLyoqXG4gICAqIEdyYWNlZnVsbHkgY2xvc2VzIHRoaXMgY2hhbm5lbC5cbiAgICpcbiAgICogQmVoYXZpb3I6XG4gICAqIC0gSWYgdGhlcmUgYXJlIHN0aWxsIGFjdGl2ZSBzdHJlYW1zLCBjbG9zaW5nIGlzIGRlZmVycmVkIHVudGlsIHRoZXkgY29tcGxldGUuXG4gICAqIC0gSWYgbXVsdGlwbGUgY2FsbGVycyBpbnZva2UgYGNsb3NlKClgIHdoaWxlIHdhaXRpbmcsIHRoZWlyIFByb21pc2VzIGFyZSBxdWV1ZWQgYW5kXG4gICAqICAgcmVzb2x2ZWQgb25jZSB0aGUgY2hhbm5lbCBhY3R1YWxseSBjbG9zZXMuXG4gICAqIC0gSWYgdGhpcyBzaWRlIGluaXRpYXRlZCB0aGUgY2xvc2UgKGBpc3N1ZWQgPSBmYWxzZWApLCBhIGNsb3NlIG1lc3NhZ2UgaXMgc2VudCB0byB0aGUgcmVtb3RlLlxuICAgKlxuICAgKiBAcGFyYW0gaXNzdWVkIC0gSWYgdHJ1ZSwgaW5kaWNhdGVzIHRoZSBjbG9zZSByZXF1ZXN0IG9yaWdpbmF0ZWQgcmVtb3RlbHlcbiAgICovXG4gIGFzeW5jIGNsb3NlKGlzc3VlZCA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGlzc3VlZCkge1xuICAgICAgaWYgKCF0aGlzLmNsb3NlZCkge1xuICAgICAgICAvLyBSZW1vdGUgaW5pdGlhdGVkIGNsb3NlOiBtYXJrIHdyaXRlciBjYW5jZWxlZCB0byBmYWlsIGZ1dHVyZSB3cml0ZXMuXG4gICAgICAgIHRoaXMuX2NhbmNlbGVkID0gdHJ1ZVxuXG4gICAgICAgIC8vIE5vdGlmeSBwcm9jZXNzb3JzIHNvIHRoZXkgY2FuIHN0b3AgcHJvZHVjaW5nIHVwc3RyZWFtIHdvcmsgYXMgd2VsbC5cbiAgICAgICAgdGhpcy5lbWl0Q2FuY2VsKClcbiAgICAgIH1cbiAgICAgIHRoaXMuY2xvc2VkID0gdHJ1ZVxuXG4gICAgICBjb25zdCBjYW5jZWxFcnJvciA9IHRoaXMuY2FuY2VsbGF0aW9uRXJyb3IoKVxuICAgICAgdGhpcy5yZWplY3RQZW5kaW5nUHJvY2Vzc2VkKGNhbmNlbEVycm9yKVxuICAgICAgdGhpcy5jYW5jZWxTaWduYWwuYWJvcnQoY2FuY2VsRXJyb3IpXG5cbiAgICAgIC8vIFVuYmxvY2sgYW55IGxvY2FsIGNsb3NlKCkgY2FsbGVycyB3YWl0aW5nIGZvciBzdHJlYW1zIHRvIHNldHRsZS5cbiAgICAgIGxldCB3YWl0aW5nID0gdGhpcy5zaG91bGRDbG9zZS5wb3AoKVxuICAgICAgd2hpbGUgKHdhaXRpbmcpIHtcbiAgICAgICAgd2FpdGluZygpXG4gICAgICAgIHdhaXRpbmcgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIENhc2UgMTogQWN0aXZlIHN0cmVhbXMgc3RpbGwgcnVubmluZyDihpIgd2FpdCB1bnRpbCB0aGV5IGZpbmlzaFxuICAgIGlmICh0aGlzLm9wZW5TdHJlYW1zICE9PSAwKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gdGhpcy5zaG91bGRDbG9zZS5wdXNoKHJlc29sdmUpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBhY3RpdmUgc3RyZWFtcyDihpIgcGVyZm9ybSBhY3R1YWwgY2xvc2VcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHt0aGlzLnVyaX0gY2xvc2VzIHN0cmVhbWApXG4gICAgdGhpcy5jbG9zZWQgPSB0cnVlXG4gICAgYXdhaXQgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3Ioe1xuICAgICAgY2xvc2U6IHsgY2hhbm5lbDogdGhpcy51cmkgfSxcbiAgICB9KVxuXG4gICAgbGV0IHJlc29sdmUgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgd2hpbGUgKHJlc29sdmUpIHtcbiAgICAgIHJlc29sdmUoKVxuICAgICAgcmVzb2x2ZSA9IHRoaXMuc2hvdWxkQ2xvc2UucG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQSBtZXNzYWdlIGlzIGhhbmRsZWQsIGxldCdzIG5vdGlmeSB0aGUgZmlmbyB7QGxpbmsgYXdhaXRQcm9jZXNzZWR9XG4gICAqL1xuICBoYW5kbGVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEucmVzb2x2ZSgpXG4gICAgfSBlbHNlIGlmICh0aGlzLmNsb3NlZCB8fCB0aGlzLl9jYW5jZWxlZCkge1xuICAgICAgLy8gQSBsYXRlIGFjayBjYW4gYXJyaXZlIGFmdGVyIGEgY2xvc2UvY2FuY2VsIHJhY2U7IG5vdGhpbmcgdG8gcmVzb2x2ZSBhbnltb3JlLlxuICAgICAgcmV0dXJuXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAnRXhwZWN0ZWQgdG8gYmUgd2FpdGluZyBmb3IgYSBtZXNzYWdlIHRvIGJlIHByb2Nlc3NlZCwgYnV0IHRoaXMgaXMgbm90IHRoZSBjYXNlICcgK1xuICAgICAgICAgIHRoaXMudXJpLFxuICAgICAgKVxuICAgIH1cbiAgfVxufVxuIl19
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBK0VoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEdBQUcsQ0FBUTtJQUNwQixtQkFBbUIsR0FBVyxDQUFDLENBQUE7SUFDZCxNQUFNLENBQWM7SUFDcEIsa0JBQWtCLENBQVU7SUFDNUIsTUFBTSxDQUFRO0lBR3ZCLGlCQUFpQixHQUdwQixFQUFFLENBQUE7SUFFQyxXQUFXLEdBQVcsQ0FBQyxDQUFBO0lBRXZCLFdBQVcsR0FBc0IsRUFBRSxDQUFBO0lBQ25DLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDZCxTQUFTLEdBQUcsS0FBSyxDQUFBO0lBR1IsY0FBYyxHQUFHLElBQUksR0FBRyxFQUFXLENBQUE7SUFFbkMsUUFBUSxDQUFRO0lBRWpDLFlBQ0UsR0FBVyxFQUNYLE1BQW9CLEVBQ3BCLGtCQUE0QixFQUM1QixRQUFnQixFQUNoQixNQUFjO1FBRWQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFBO1FBQzVDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFBO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDMUIsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQTtJQUN2QixDQUFDO0lBRUQsRUFBRSxDQUFDLEtBQWUsRUFBRSxRQUFpQjtRQUNuQyxJQUFJLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFR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Q25FLENBQUE7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtJQUNILENBQUM7SUFFTyxjQUFjO1FBQ3BCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FDckMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUNqRCxDQUFBO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRnJvbVJ1bm5lciwgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnd2luc3RvbidcbmltcG9ydCB7IEFueSB9IGZyb20gJy4vcmVhZGVyJ1xuXG50eXBlIFdyaXRhYmxlID0gKG1zZzogRnJvbVJ1bm5lcikgPT4gUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IHR5cGUgSGFuZGxlcjxUID0gdm9pZD4gPSBbVF0gZXh0ZW5kcyBbdm9pZF1cbiAgPyAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPlxuICA6ICh2YWx1ZTogVCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD5cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICByZWFkb25seSB1cmk6IHN0cmluZ1xuICByZWFkb25seSBjYW5jZWxlZDogYm9vbGVhblxuICBvbihldmVudDogJ2NhbmNlbCcsIGxpc3RlbmVyOiBIYW5kbGVyKTogdGhpc1xuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBjb21wbGV0ZSBidWZmZXIgdG8gdGhlIGNoYW5uZWwuIFRoZSBQcm9taXNlIHJlc29sdmVzIG9uY2UgdGhlIG1lc3NhZ2UgaXMgZnVsbHkgcHJvY2Vzc2VkIGJ5IHRoZSByZW1vdGUuXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIG9yIGNhbmNlbGVkIGF0IHRoZSBtb21lbnQgb2YgdGhlIHdyaXRlIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIGJ1ZmZlciAtIFRoZSBkYXRhIHRvIHNlbmQgYXMgYSBVaW50OEFycmF5XG4gICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG1lc3NhZ2UgaXMgYWNrbm93bGVkZ2VkIGFzIHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKi9cbiAgYnVmZmVyKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD5cblxuICAvKipcbiAgICogV3JpdGVzIGEgc3RyZWFtIG9mIGRhdGEgdG8gYSBzZXBhcmF0ZSBzdHJlYW0tc3BlY2lmaWMgY2hhbm5lbC5cbiAgICogVGhlIFByb21pc2UgcmVzb2x2ZXMgb25jZSB0aGUgZW50aXJlIHN0cmVhbSBpcyBmdWxseSBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICpcbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgb3IgY2FuY2VsZWQgYXQgdGhlIG1vbWVudCBvZiBpbml0aWF0aW5nIGEgc3RyZWFtLXNwZWNpZmljIGNoYW5uZWwuXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBc3luY0l0ZXJhYmxlIHRoYXQgcHJvZHVjZXMgdGhlIGRhdGEgdG8gc2VuZCBhcyBVaW50OEFycmF5c1xuICAgKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBlbnRpcmUgc3RyZWFtIGlzIGFja25vd2xlZGdlZCBhcyBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICovXG4gIHN0cmVhbShidWZmZXI6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBQcm9taXNlPHZvaWQ+XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN0cmVhbSBvZiBkYXRhIHRvIGEgc2VwYXJhdGUgc3RyZWFtLXNwZWNpZmljIGNoYW5uZWwuXG4gICAqIFRoZSBQcm9taXNlIHJlc29sdmVzIG9uY2UgdGhlIGVudGlyZSBzdHJlYW0gaXMgZnVsbHkgcHJvY2Vzc2VkIGJ5IHRoZSByZW1vdGUuXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIG9yIGNhbmNlbGVkIGF0IHRoZSBtb21lbnQgb2YgaW5pdGlhdGluZyBhIHN0cmVhbS1zcGVjaWZpYyBjaGFubmVsLlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQW4gQXN5bmNJdGVyYWJsZSB0aGF0IHByb2R1Y2VzIHRoZSBkYXRhIHRvIHNlbmQsIHdoaWNoIHdpbGwgYmUgdHJhbnNmb3JtZWQgaW50byBVaW50OEFycmF5cyB1c2luZyB0aGUgcHJvdmlkZWQgdHJhbnNmb3JtIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB0cmFuc2Zvcm0gLSBBIGZ1bmN0aW9uIHRoYXQgdHJhbnNmb3JtcyBpdGVtcyBmcm9tIHRoZSBidWZmZXIgQXN5bmNJdGVyYWJsZSBpbnRvIFVpbnQ4QXJyYXlzIGZvciBzZW5kaW5nLiBJZiBub3QgcHJvdmlkZWQsIGl0ZW1zIGFyZSBhc3N1bWVkIHRvIGFscmVhZHkgYmUgVWludDhBcnJheXMuXG4gICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGVudGlyZSBzdHJlYW0gaXMgYWNrbm93bGVkZ2VkIGFzIHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKi9cbiAgc3RyZWFtPFQ+KFxuICAgIGJ1ZmZlcjogQXN5bmNJdGVyYWJsZTxUPixcbiAgICB0cmFuc2Zvcm06ICh4OiBUKSA9PiBVaW50OEFycmF5LFxuICApOiBQcm9taXNlPHZvaWQ+XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN0cmluZyBtZXNzYWdlIHRvIHRoZSBjaGFubmVsLiBUaGUgUHJvbWlzZSByZXNvbHZlcyBvbmNlIHRoZSBtZXNzYWdlIGlzIGZ1bGx5IHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBvciBjYW5jZWxlZCBhdCB0aGUgbW9tZW50IG9mIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gICAqIEBwYXJhbSBidWZmZXIgLSBUaGUgc3RyaW5nIG1lc3NhZ2UgdG8gc2VuZFxuICAgKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBtZXNzYWdlIGlzIGFja25vd2xlZGdlZCBhcyBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICovXG4gIHN0cmluZyhidWZmZXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cblxuICAvKipcbiAgICogV3JpdGVzIGEgbWVzc2FnZSBvZiBhbnkgc3VwcG9ydGVkIHR5cGUgKHN0cmluZywgYnVmZmVyLCBvciBzdHJlYW0pIHRvIHRoZSBjaGFubmVsLlxuICAgKiBUaGUgUHJvbWlzZSByZXNvbHZlcyBvbmNlIHRoZSBtZXNzYWdlIGlzIGZ1bGx5IHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBvciBjYW5jZWxlZCBhdCB0aGUgbW9tZW50IG9mIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gICAqIEBwYXJhbSBhbnkgLSBBbiBvYmplY3QgY29udGFpbmluZyBvbmUgb2YgdGhlIHN1cHBvcnRlZCBtZXNzYWdlIHR5cGVzIChzdHJpbmcsIGJ1ZmZlciwgb3Igc3RyZWFtKVxuICAgKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBtZXNzYWdlIGlzIGFja25vd2xlZGdlZCBhcyBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICovXG4gIGFueShhbnk6IEFueSk6IFByb21pc2U8dm9pZD5cblxuICAvKipcbiAgICogR3JhY2VmdWxseSBjbG9zZXMgdGhpcyBjaGFubmVsLlxuICAgKlxuICAgKiBCZWhhdmlvcjpcbiAgICogLSBJZiB0aGVyZSBhcmUgc3RpbGwgYWN0aXZlIHN0cmVhbXMsIGNsb3NpbmcgaXMgZGVmZXJyZWQgdW50aWwgdGhleSBjb21wbGV0ZS5cbiAgICogLSBJZiBtdWx0aXBsZSBjYWxsZXJzIGludm9rZSBgY2xvc2UoKWAgd2hpbGUgd2FpdGluZywgdGhlaXIgUHJvbWlzZXMgYXJlIHF1ZXVlZCBhbmRcbiAgICogICByZXNvbHZlZCBvbmNlIHRoZSBjaGFubmVsIGFjdHVhbGx5IGNsb3Nlcy5cbiAgICogLSBJZiB0aGlzIHNpZGUgaW5pdGlhdGVkIHRoZSBjbG9zZSAoYGlzc3VlZCA9IGZhbHNlYCksIGEgY2xvc2UgbWVzc2FnZSBpcyBzZW50IHRvIHRoZSByZW1vdGUuXG4gICAqXG4gICAqIEBwYXJhbSBpc3N1ZWQgLSBJZiB0cnVlLCBpbmRpY2F0ZXMgdGhlIGNsb3NlIHJlcXVlc3Qgb3JpZ2luYXRlZCByZW1vdGVseVxuICAgKi9cbiAgY2xvc2UoaXNzdWVkPzogYm9vbGVhbik6IFByb21pc2U8dm9pZD5cbn1cbmNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKVxuZXhwb3J0IGNsYXNzIFdyaXRlckluc3RhbmNlIGltcGxlbWVudHMgV3JpdGVyIHtcbiAgcmVhZG9ubHkgdXJpOiBzdHJpbmdcbiAgbG9jYWxTZXF1ZW5jZU51bWJlcjogbnVtYmVyID0gMVxuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogUnVubmVyQ2xpZW50XG4gIHByaXZhdGUgcmVhZG9ubHkgbm90aWZ5T3JjaGVzdHJhdG9yOiBXcml0YWJsZVxuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlcjogTG9nZ2VyXG5cbiAgLy8gRklGTyBvZiBtZXNzYWdlLWxldmVsIGFja25vd2xlZGdlbWVudHMgY29taW5nIGJhY2sgZnJvbSB0aGUgb3JjaGVzdHJhdG9yLlxuICBwcml2YXRlIGF3YWl0aW5nUHJvY2Vzc2VkOiBBcnJheTx7XG4gICAgcmVzb2x2ZTogKCkgPT4gdm9pZFxuICAgIHJlamVjdDogKHJlYXNvbjogRXJyb3IpID0+IHZvaWRcbiAgfT4gPSBbXVxuXG4gIHByaXZhdGUgb3BlblN0cmVhbXM6IG51bWJlciA9IDBcbiAgLy8gQ2xvc2UgY2FsbGVycyB3YWl0IGhlcmUgd2hpbGUgYWN0aXZlIHN0cmVhbXMgYXJlIHN0aWxsIGZsdXNoaW5nLlxuICBwcml2YXRlIHNob3VsZENsb3NlOiBBcnJheTwoKSA9PiB2b2lkPiA9IFtdXG4gIHByaXZhdGUgY2xvc2VkID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FuY2VsZWQgPSBmYWxzZVxuXG4gIC8vIFByb2Nlc3NvcnMgY2FuIHN1YnNjcmliZSBoZXJlIHRvIHN0b3AgdXBzdHJlYW0gd29yayB3aGVuIGRvd25zdHJlYW0gY2FuY2Vscy5cbiAgcHJpdmF0ZSByZWFkb25seSBjYW5jZWxIYW5kbGVycyA9IG5ldyBTZXQ8SGFuZGxlcj4oKVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgcnVubmVySWQ6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHVyaTogc3RyaW5nLFxuICAgIGNsaWVudDogUnVubmVyQ2xpZW50LFxuICAgIG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGUsXG4gICAgcnVubmVySWQ6IHN0cmluZyxcbiAgICBsb2dnZXI6IExvZ2dlcixcbiAgKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnRcbiAgICB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvciA9IG5vdGlmeU9yY2hlc3RyYXRvclxuICAgIHRoaXMudXJpID0gdXJpXG4gICAgdGhpcy5sb2dnZXIgPSBsb2dnZXJcbiAgICB0aGlzLnJ1bm5lcklkID0gcnVubmVySWRcbiAgfVxuXG4gIGdldCBjYW5jZWxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY2FuY2VsZWRcbiAgfVxuXG4gIG9uKGV2ZW50OiAnY2FuY2VsJywgbGlzdGVuZXI6IEhhbmRsZXIpOiB0aGlzIHtcbiAgICBpZiAoZXZlbnQgPT09ICdjYW5jZWwnKSB7XG4gICAgICB0aGlzLmNhbmNlbEhhbmRsZXJzLmFkZChsaXN0ZW5lcilcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHJpdmF0ZSBjYW5jZWxsYXRpb25FcnJvcigpOiBFcnJvciB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihcbiAgICAgIGBXcml0ZXIgZm9yIGNoYW5uZWwgJHt0aGlzLnVyaX0gd2FzIGNhbmNlbGVkIGJ5IHRoZSBjb25uZWN0ZWQgcmVhZGVyYCxcbiAgICApXG4gIH1cblxuICBhc3luYyBhbnkoYW55OiBBbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoJ3N0cmVhbScgaW4gYW55KSB7XG4gICAgICBhd2FpdCB0aGlzLnN0cmVhbShhbnkuc3RyZWFtKVxuICAgIH1cbiAgICBpZiAoJ2J1ZmZlcicgaW4gYW55KSB7XG4gICAgICBhd2FpdCB0aGlzLmJ1ZmZlcihhbnkuYnVmZmVyKVxuICAgIH1cbiAgICBpZiAoJ3N0cmluZycgaW4gYW55KSB7XG4gICAgICBhd2FpdCB0aGlzLnN0cmluZyhhbnkuc3RyaW5nKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXNzZXJ0Q2FuV3JpdGUoKSB7XG4gICAgaWYgKHRoaXMuX2NhbmNlbGVkKSB7XG4gICAgICB0aHJvdyB0aGlzLmNhbmNlbGxhdGlvbkVycm9yKClcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgV3JpdGVyIGZvciBjaGFubmVsICR7dGhpcy51cml9IGlzIGNsb3NlZGApXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYnVmZmVyKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXNzZXJ0Q2FuV3JpdGUoKVxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3RoaXMudXJpfSBzZW5kcyBidWZmZXIgJHtidWZmZXIubGVuZ3RofSBieXRlc2ApXG4gICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgY29uc3QgaGFuZGxlZFByb21pc2UgPSB0aGlzLmF3YWl0UHJvY2Vzc2VkKClcblxuICAgIGF3YWl0IHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yKHtcbiAgICAgIG1zZzogeyBkYXRhOiBidWZmZXIsIGNoYW5uZWw6IHRoaXMudXJpLCBsb2NhbFNlcXVlbmNlTnVtYmVyIH0sXG4gICAgfSlcbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgYXN5bmMgc3RyZWFtPFQgPSBVaW50OEFycmF5PihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtPzogKHg6IFQpID0+IFVpbnQ4QXJyYXksXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXNzZXJ0Q2FuV3JpdGUoKVxuICAgIHRoaXMub3BlblN0cmVhbXMgKz0gMVxuICAgIGNvbnN0IHQgPSB0cmFuc2Zvcm0gfHwgKCh4OiB1bmtub3duKSA9PiA8VWludDhBcnJheT54KVxuICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuY2xpZW50LnNlbmRTdHJlYW1NZXNzYWdlKClcblxuICAgIHRyeSB7XG4gICAgICAvLyBNZXNzYWdlLWxldmVsIGFjayB0aGF0IHNpZ25hbHMgdGhlIHdob2xlIHN0cmVhbSBtZXNzYWdlIGlzIGZ1bGx5IGhhbmRsZWQuXG4gICAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoKVxuICAgICAgY29uc3Qgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsgPSBwcm9taXNpZnkoc3RyZWFtLndyaXRlLmJpbmQoc3RyZWFtKSlcbiAgICAgIGNvbnN0IGxvY2FsU2VxdWVuY2VOdW1iZXIgPSB0aGlzLmxvY2FsU2VxdWVuY2VOdW1iZXIrK1xuICAgICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoe1xuICAgICAgICBpZDoge1xuICAgICAgICAgIGNoYW5uZWw6IHRoaXMudXJpLFxuICAgICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICAgICAgcnVubmVyOiB0aGlzLnJ1bm5lcklkLFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gRmlyc3QgcmVzcG9uc2UgY29uZmlybXMgc3RyZWFtIGlkIHJlZ2lzdHJhdGlvbiBvbiB0aGUgcmVtb3RlIHNpZGUuXG4gICAgICBjb25zdCBpZCA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcblxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGAke3RoaXMudXJpfSBzdHJlYW1zIG1lc3NhZ2Ugd2l0aCBpZCAke0pTT04uc3RyaW5naWZ5KGlkKX1gLFxuICAgICAgKVxuXG4gICAgICAvLyBUT0RPOiBkb24ndCBhd2FpdCB0byBhbGxvdyBjb25zdW1pbmcgcHJvY2Vzc29ycyB0byByZWFkIGFuZCBoYW5kbGUgaW4gcGFyYWxsZWwuXG4gICAgICBmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBidWZmZXIpIHtcbiAgICAgICAgY29uc3QgcHJvY2Vzc2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcbiAgICAgICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoeyBkYXRhOiB7IGRhdGE6IHQobXNnKSB9IH0pXG4gICAgICAgIC8vIEF3YWl0IGEgbWVzc2FnZSBvbiB0aGUgc3RyZWFtLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNodW5rIGhhcyBiZWVuIHByb2Nlc3NlZFxuICAgICAgICBhd2FpdCBwcm9jZXNzZWRQcm9taXNlXG4gICAgICB9XG5cbiAgICAgIHN0cmVhbS5lbmQoKVxuXG4gICAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLm9wZW5TdHJlYW1zIC09IDFcblxuICAgICAgaWYgKCFzdHJlYW0ud3JpdGFibGVFbmRlZCkge1xuICAgICAgICBzdHJlYW0uZW5kKClcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYSBjbG9zZSBjYWxsIHdhcyBkZWZlcnJlZCB3aGlsZSBzdHJlYW1pbmcsIGNvbXBsZXRlIGl0IG5vdy5cbiAgICAgIGlmICh0aGlzLnNob3VsZENsb3NlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbG9zZSgpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc3RyaW5nKG1zZzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7dGhpcy51cml9IHNlbmRzIHN0cmluZyAke21zZy5sZW5ndGh9IGNoYXJhY3RlcnNgKVxuICAgIGNvbnN0IGxvY2FsU2VxdWVuY2VOdW1iZXIgPSB0aGlzLmxvY2FsU2VxdWVuY2VOdW1iZXIrK1xuICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG5cbiAgICBhd2FpdCB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvcih7XG4gICAgICBtc2c6IHtcbiAgICAgICAgZGF0YTogZW5jb2Rlci5lbmNvZGUobXNnKSxcbiAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgYXN5bmMgY2xvc2UoaXNzdWVkID0gZmFsc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNsb3NlZCA9IHRydWVcbiAgICBpZiAoaXNzdWVkICYmICF0aGlzLl9jYW5jZWxlZCkge1xuICAgICAgLy8gUmVtb3RlIGluaXRpYXRlZCBjbG9zZTogbWFyayB3cml0ZXIgY2FuY2VsZWQgdG8gZmFpbCBmdXR1cmUgd3JpdGVzLlxuICAgICAgdGhpcy5fY2FuY2VsZWQgPSB0cnVlXG5cbiAgICAgIC8vIE5vdGlmeSBwcm9jZXNzb3JzIHNvIHRoZXkgY2FuIHN0b3AgcHJvZHVjaW5nIHVwc3RyZWFtIHdvcmsgYXMgd2VsbC5cbiAgICAgIGF3YWl0IHRoaXMuZW1pdENhbmNlbCgpXG4gICAgfVxuICAgIC8vIENhc2UgMTogQWN0aXZlIHN0cmVhbXMgc3RpbGwgcnVubmluZyDihpIgd2FpdCB1bnRpbCB0aGV5IGZpbmlzaFxuICAgIGlmICh0aGlzLm9wZW5TdHJlYW1zICE9PSAwKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gdGhpcy5zaG91bGRDbG9zZS5wdXNoKHJlc29sdmUpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBhY3RpdmUgc3RyZWFtcyDihpIgcGVyZm9ybSBhY3R1YWwgY2xvc2VcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHt0aGlzLnVyaX0gY2xvc2VzIHN0cmVhbWApXG4gICAgaWYgKCFpc3N1ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yKHtcbiAgICAgICAgY2xvc2U6IHsgY2hhbm5lbDogdGhpcy51cmkgfSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgbGV0IHJlc29sdmUgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgd2hpbGUgKHJlc29sdmUpIHtcbiAgICAgIHJlc29sdmUoKVxuICAgICAgcmVzb2x2ZSA9IHRoaXMuc2hvdWxkQ2xvc2UucG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQSBtZXNzYWdlIGlzIGhhbmRsZWQsIGxldCdzIG5vdGlmeSB0aGUgZmlmbyB7QGxpbmsgYXdhaXRQcm9jZXNzZWR9XG4gICAqL1xuICBoYW5kbGVkKGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEucmVqZWN0KG5ldyBFcnJvcihlcnJvcikpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLnNoaWZ0KCkhLnJlc29sdmUoKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5jbG9zZWQgfHwgdGhpcy5fY2FuY2VsZWQpIHtcbiAgICAgIC8vIEEgbGF0ZSBhY2sgY2FuIGFycml2ZSBhZnRlciBhIGNsb3NlL2NhbmNlbCByYWNlOyBub3RoaW5nIHRvIHJlc29sdmUgYW55bW9yZS5cbiAgICAgIHJldHVyblxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIHRvIGJlIHdhaXRpbmcgZm9yIGEgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQsIGJ1dCB0aGlzIGlzIG5vdCB0aGUgY2FzZSAnICtcbiAgICAgICAgICB0aGlzLnVyaSxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVtaXRDYW5jZWwoKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBBcnJheS5mcm9tKHRoaXMuY2FuY2VsSGFuZGxlcnMpLm1hcChhc3luYyAoaGFuZGxlcikgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGhhbmRsZXIoKVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgYENhbmNlbCBsaXN0ZW5lciBmb3IgY2hhbm5lbCAke3RoaXMudXJpfSBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX1gLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKVxuICB9XG5cbiAgcHJpdmF0ZSBhd2FpdFByb2Nlc3NlZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT5cbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQucHVzaCh7IHJlc29sdmUsIHJlamVjdCB9KSxcbiAgICApXG4gIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdfc/js-runner",
3
- "version": "3.1.0-alpha.1",
3
+ "version": "3.1.0",
4
4
  "main": "lib/index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@grpc/grpc-js": "^1.14.3",
58
- "@rdfc/proto": "^0.1.2",
58
+ "@rdfc/proto": "^0.1.3",
59
59
  "@treecg/types": "^0.4.6",
60
60
  "jsonld": "^9.0.0",
61
61
  "jsonld-streaming-parser": "^5.0.1",
package/src/reader.ts CHANGED
@@ -173,6 +173,8 @@ export class ReaderInstance implements Reader {
173
173
  processed: {
174
174
  globalSequenceNumber: msg.globalSequenceNumber,
175
175
  channel: this.uri,
176
+ error:
177
+ 'reader is canceled; message has not been processed by the processor',
176
178
  },
177
179
  })
178
180
  return
package/src/runner.ts CHANGED
@@ -260,7 +260,7 @@ export class Runner {
260
260
  private handleProcessed(processed: LocalAck) {
261
261
  const writer = this.writers[processed.channel]
262
262
  if (writer) {
263
- writer.handled()
263
+ writer.handled(processed.error)
264
264
  } else {
265
265
  this.logger.error(
266
266
  `Received processed message for channel ${processed.channel}, but no writer was present.`,
@@ -83,9 +83,13 @@ export class OrchestratorMock {
83
83
  // Always bounce processed msgs back to the runner
84
84
  connectStream.register(
85
85
  (msg) => msg.processed,
86
- ({ channel, globalSequenceNumber }, send) => {
86
+ ({ channel, globalSequenceNumber, error }, send) => {
87
87
  send({
88
- processed: { channel, localSequenceNumber: globalSequenceNumber },
88
+ processed: {
89
+ channel,
90
+ localSequenceNumber: globalSequenceNumber,
91
+ error,
92
+ },
89
93
  })
90
94
  },
91
95
  )
package/src/writer.ts CHANGED
@@ -12,17 +12,71 @@ export interface Writer {
12
12
  readonly uri: string
13
13
  readonly canceled: boolean
14
14
  on(event: 'cancel', listener: Handler): this
15
+
16
+ /**
17
+ * Writes a complete buffer to the channel. The Promise resolves once the message is fully processed by the remote.
18
+ *
19
+ * @throws Error if the channel is closed or canceled at the moment of the write operation.
20
+ * @param buffer - The data to send as a Uint8Array
21
+ * @returns A Promise that resolves when the message is acknowledged as processed by the remote.
22
+ */
15
23
  buffer(buffer: Uint8Array): Promise<void>
16
24
 
25
+ /**
26
+ * Writes a stream of data to a separate stream-specific channel.
27
+ * The Promise resolves once the entire stream is fully processed by the remote.
28
+ *
29
+ * @throws Error if the channel is closed or canceled at the moment of initiating a stream-specific channel.
30
+ * @param buffer - An AsyncIterable that produces the data to send as Uint8Arrays
31
+ * @returns A Promise that resolves when the entire stream is acknowledged as processed by the remote.
32
+ */
17
33
  stream(buffer: AsyncIterable<Uint8Array>): Promise<void>
34
+
35
+ /**
36
+ * Writes a stream of data to a separate stream-specific channel.
37
+ * The Promise resolves once the entire stream is fully processed by the remote.
38
+ *
39
+ * @throws Error if the channel is closed or canceled at the moment of initiating a stream-specific channel.
40
+ * @param buffer - An AsyncIterable that produces the data to send, which will be transformed into Uint8Arrays using the provided transform function
41
+ * @param transform - A function that transforms items from the buffer AsyncIterable into Uint8Arrays for sending. If not provided, items are assumed to already be Uint8Arrays.
42
+ * @returns A Promise that resolves when the entire stream is acknowledged as processed by the remote.
43
+ */
18
44
  stream<T>(
19
45
  buffer: AsyncIterable<T>,
20
46
  transform: (x: T) => Uint8Array,
21
47
  ): Promise<void>
22
48
 
49
+ /**
50
+ * Writes a string message to the channel. The Promise resolves once the message is fully processed by the remote.
51
+ *
52
+ * @throws Error if the channel is closed or canceled at the moment of the write operation.
53
+ * @param buffer - The string message to send
54
+ * @returns A Promise that resolves when the message is acknowledged as processed by the remote.
55
+ */
23
56
  string(buffer: string): Promise<void>
57
+
58
+ /**
59
+ * Writes a message of any supported type (string, buffer, or stream) to the channel.
60
+ * The Promise resolves once the message is fully processed by the remote.
61
+ *
62
+ * @throws Error if the channel is closed or canceled at the moment of the write operation.
63
+ * @param any - An object containing one of the supported message types (string, buffer, or stream)
64
+ * @returns A Promise that resolves when the message is acknowledged as processed by the remote.
65
+ */
24
66
  any(any: Any): Promise<void>
25
- close(): Promise<void>
67
+
68
+ /**
69
+ * Gracefully closes this channel.
70
+ *
71
+ * Behavior:
72
+ * - If there are still active streams, closing is deferred until they complete.
73
+ * - If multiple callers invoke `close()` while waiting, their Promises are queued and
74
+ * resolved once the channel actually closes.
75
+ * - If this side initiated the close (`issued = false`), a close message is sent to the remote.
76
+ *
77
+ * @param issued - If true, indicates the close request originated remotely
78
+ */
79
+ close(issued?: boolean): Promise<void>
26
80
  }
27
81
  const encoder = new TextEncoder()
28
82
  export class WriterInstance implements Writer {
@@ -44,8 +98,6 @@ export class WriterInstance implements Writer {
44
98
  private closed = false
45
99
  private _canceled = false
46
100
 
47
- // Shared cancellation signal to abort in-flight waits when the remote closes.
48
- private readonly cancelSignal = new AbortController()
49
101
  // Processors can subscribe here to stop upstream work when downstream cancels.
50
102
  private readonly cancelHandlers = new Set<Handler>()
51
103
 
@@ -83,19 +135,15 @@ export class WriterInstance implements Writer {
83
135
  )
84
136
  }
85
137
 
86
- private emitCancel() {
87
- for (const handler of this.cancelHandlers) {
88
- try {
89
- Promise.resolve(handler()).catch((error: unknown) => {
90
- this.logger.error(
91
- `Cancel listener for channel ${this.uri} failed: ${String(error)}`,
92
- )
93
- })
94
- } catch (error: unknown) {
95
- this.logger.error(
96
- `Cancel listener for channel ${this.uri} failed: ${String(error)}`,
97
- )
98
- }
138
+ async any(any: Any): Promise<void> {
139
+ if ('stream' in any) {
140
+ await this.stream(any.stream)
141
+ }
142
+ if ('buffer' in any) {
143
+ await this.buffer(any.buffer)
144
+ }
145
+ if ('string' in any) {
146
+ await this.string(any.string)
99
147
  }
100
148
  }
101
149
 
@@ -109,55 +157,6 @@ export class WriterInstance implements Writer {
109
157
  }
110
158
  }
111
159
 
112
- private async raceWithCancellation<T>(promise: Promise<T>): Promise<T> {
113
- this.assertCanWrite()
114
-
115
- return await new Promise<T>((resolve, reject) => {
116
- const onAbort = () => reject(this.cancellationError())
117
- this.cancelSignal.signal.addEventListener('abort', onAbort, {
118
- once: true,
119
- })
120
-
121
- promise.then(
122
- (value) => {
123
- // Clean up the abort listener if the original operation finished first.
124
- this.cancelSignal.signal.removeEventListener('abort', onAbort)
125
- resolve(value)
126
- },
127
- (error) => {
128
- this.cancelSignal.signal.removeEventListener('abort', onAbort)
129
- reject(error)
130
- },
131
- )
132
- })
133
- }
134
-
135
- private rejectPendingProcessed(error: Error) {
136
- // Reject all queued message waits so callers do not hang during cancellation.
137
- while (this.awaitingProcessed.length > 0) {
138
- this.awaitingProcessed.shift()!.reject(error)
139
- }
140
- }
141
-
142
- private awaitProcessed(): Promise<void> {
143
- this.assertCanWrite()
144
- return new Promise((resolve, reject) =>
145
- this.awaitingProcessed.push({ resolve, reject }),
146
- )
147
- }
148
-
149
- async any(any: Any): Promise<void> {
150
- if ('stream' in any) {
151
- await this.stream(any.stream)
152
- }
153
- if ('buffer' in any) {
154
- await this.buffer(any.buffer)
155
- }
156
- if ('string' in any) {
157
- await this.string(any.string)
158
- }
159
- }
160
-
161
160
  async buffer(buffer: Uint8Array): Promise<void> {
162
161
  this.assertCanWrite()
163
162
  this.logger.debug(`${this.uri} sends buffer ${buffer.length} bytes`)
@@ -173,7 +172,7 @@ export class WriterInstance implements Writer {
173
172
  async stream<T = Uint8Array>(
174
173
  buffer: AsyncIterable<T>,
175
174
  transform?: (x: T) => Uint8Array,
176
- ) {
175
+ ): Promise<void> {
177
176
  this.assertCanWrite()
178
177
  this.openStreams += 1
179
178
  const t = transform || ((x: unknown) => <Uint8Array>x)
@@ -193,14 +192,13 @@ export class WriterInstance implements Writer {
193
192
  })
194
193
 
195
194
  // First response confirms stream id registration on the remote side.
196
- const id = await this.raceWithCancellation(
197
- new Promise((res) => stream.once('data', res)),
198
- )
195
+ const id = await new Promise((res) => stream.once('data', res))
199
196
 
200
197
  this.logger.debug(
201
198
  `${this.uri} streams message with id ${JSON.stringify(id)}`,
202
199
  )
203
200
 
201
+ // TODO: don't await to allow consuming processors to read and handle in parallel.
204
202
  for await (const msg of buffer) {
205
203
  const processedPromise = new Promise((res) => stream.once('data', res))
206
204
  await writeStreamMessageChunk({ data: { data: t(msg) } })
@@ -242,45 +240,15 @@ export class WriterInstance implements Writer {
242
240
  await handledPromise
243
241
  }
244
242
 
245
- /**
246
- * Gracefully closes this channel.
247
- *
248
- * Behavior:
249
- * - If there are still active streams, closing is deferred until they complete.
250
- * - If multiple callers invoke `close()` while waiting, their Promises are queued and
251
- * resolved once the channel actually closes.
252
- * - If this side initiated the close (`issued = false`), a close message is sent to the remote.
253
- *
254
- * @param issued - If true, indicates the close request originated remotely
255
- */
256
243
  async close(issued = false): Promise<void> {
257
- if (issued) {
258
- if (!this.closed) {
259
- // Remote initiated close: mark writer canceled to fail future writes.
260
- this._canceled = true
261
-
262
- // Notify processors so they can stop producing upstream work as well.
263
- this.emitCancel()
264
- }
265
- this.closed = true
266
-
267
- const cancelError = this.cancellationError()
268
- this.rejectPendingProcessed(cancelError)
269
- this.cancelSignal.abort(cancelError)
244
+ this.closed = true
245
+ if (issued && !this._canceled) {
246
+ // Remote initiated close: mark writer canceled to fail future writes.
247
+ this._canceled = true
270
248
 
271
- // Unblock any local close() callers waiting for streams to settle.
272
- let waiting = this.shouldClose.pop()
273
- while (waiting) {
274
- waiting()
275
- waiting = this.shouldClose.pop()
276
- }
277
- return
249
+ // Notify processors so they can stop producing upstream work as well.
250
+ await this.emitCancel()
278
251
  }
279
-
280
- if (this.closed) {
281
- return
282
- }
283
-
284
252
  // Case 1: Active streams still running → wait until they finish
285
253
  if (this.openStreams !== 0) {
286
254
  await new Promise<void>((resolve) => this.shouldClose.push(resolve))
@@ -289,10 +257,11 @@ export class WriterInstance implements Writer {
289
257
 
290
258
  // Case 2: No active streams → perform actual close
291
259
  this.logger.debug(`${this.uri} closes stream`)
292
- this.closed = true
293
- await this.notifyOrchestrator({
294
- close: { channel: this.uri },
295
- })
260
+ if (!issued) {
261
+ await this.notifyOrchestrator({
262
+ close: { channel: this.uri },
263
+ })
264
+ }
296
265
 
297
266
  let resolve = this.shouldClose.pop()
298
267
  while (resolve) {
@@ -304,9 +273,13 @@ export class WriterInstance implements Writer {
304
273
  /**
305
274
  * A message is handled, let's notify the fifo {@link awaitProcessed}
306
275
  */
307
- handled(): void {
276
+ handled(error?: string): void {
308
277
  if (this.awaitingProcessed.length > 0) {
309
- this.awaitingProcessed.shift()!.resolve()
278
+ if (error) {
279
+ this.awaitingProcessed.shift()!.reject(new Error(error))
280
+ } else {
281
+ this.awaitingProcessed.shift()!.resolve()
282
+ }
310
283
  } else if (this.closed || this._canceled) {
311
284
  // A late ack can arrive after a close/cancel race; nothing to resolve anymore.
312
285
  return
@@ -317,4 +290,24 @@ export class WriterInstance implements Writer {
317
290
  )
318
291
  }
319
292
  }
293
+
294
+ private async emitCancel() {
295
+ await Promise.all(
296
+ Array.from(this.cancelHandlers).map(async (handler) => {
297
+ try {
298
+ await handler()
299
+ } catch (error: unknown) {
300
+ this.logger.error(
301
+ `Cancel listener for channel ${this.uri} failed: ${String(error)}`,
302
+ )
303
+ }
304
+ }),
305
+ )
306
+ }
307
+
308
+ private awaitProcessed(): Promise<void> {
309
+ return new Promise((resolve, reject) =>
310
+ this.awaitingProcessed.push({ resolve, reject }),
311
+ )
312
+ }
320
313
  }
package/dist/args.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export type Args = {
2
- input: string
3
- }
4
- export declare function getArgs(): Args