@hivegpt/hiveai-angular 0.0.569 → 0.0.570

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.
@@ -3,83 +3,59 @@ import { Injectable, NgZone } from '@angular/core';
3
3
  import { BehaviorSubject } from 'rxjs';
4
4
  import Daily from '@daily-co/daily-js';
5
5
  import * as i0 from "@angular/core";
6
- /**
7
- * Daily.js WebRTC client for voice agent audio.
8
- * Responsibilities:
9
- * - Create and manage Daily CallObject
10
- * - Join Daily room using room_url
11
- * - Handle mic capture + speaker playback
12
- * - Bot speaking detection via AnalyserNode on remote track (instant)
13
- * - User speaking detection via active-speaker-change
14
- * - Expose speaking$ (bot speaking), userSpeaking$ (user speaking), micMuted$
15
- * - Expose localStream$ for waveform visualization (AudioAnalyzerService)
16
- */
17
6
  export class DailyVoiceClientService {
18
7
  constructor(ngZone) {
19
8
  this.ngZone = ngZone;
20
9
  this.callObject = null;
21
10
  this.localStream = null;
22
11
  this.localSessionId = null;
23
- /** Explicit playback of remote (bot) audio; required in some browsers. */
24
12
  this.remoteAudioElement = null;
25
- /** AnalyserNode-based remote audio monitor for instant bot speaking detection. */
26
13
  this.remoteAudioContext = null;
27
14
  this.remoteSpeakingRAF = null;
28
15
  this.speakingSubject = new BehaviorSubject(false);
29
16
  this.userSpeakingSubject = new BehaviorSubject(false);
30
- this.micMutedSubject = new BehaviorSubject(false);
17
+ this.micMutedSubject = new BehaviorSubject(true); // 🔴 default muted
31
18
  this.localStreamSubject = new BehaviorSubject(null);
32
- /** True when bot (remote participant) is the active speaker. */
33
19
  this.speaking$ = this.speakingSubject.asObservable();
34
- /** True when user (local participant) is the active speaker. */
35
20
  this.userSpeaking$ = this.userSpeakingSubject.asObservable();
36
- /** True when mic is muted. */
37
21
  this.micMuted$ = this.micMutedSubject.asObservable();
38
- /** Emits local mic stream for waveform visualization. */
39
22
  this.localStream$ = this.localStreamSubject.asObservable();
40
23
  }
41
- /**
42
- * Connect to Daily room. Acquires mic first for waveform, then joins with audio.
43
- * @param roomUrl Daily room URL (from room_created)
44
- * @param token Optional meeting token
45
- */
46
24
  connect(roomUrl, token) {
47
25
  return __awaiter(this, void 0, void 0, function* () {
48
26
  if (this.callObject) {
49
27
  yield this.disconnect();
50
28
  }
51
29
  try {
52
- // Get mic stream for both Daily and waveform (single capture)
30
+ // 🎤 Get mic (kept for waveform)
53
31
  const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
54
32
  const audioTrack = stream.getAudioTracks()[0];
55
- if (!audioTrack) {
56
- stream.getTracks().forEach((t) => t.stop());
33
+ if (!audioTrack)
57
34
  throw new Error('No audio track');
58
- }
59
35
  this.localStream = stream;
60
36
  this.localStreamSubject.next(stream);
61
- // Create audio-only call object
62
- // videoSource: false = no camera, audioSource = our mic track
63
37
  const callObject = Daily.createCallObject({
64
38
  videoSource: false,
65
39
  audioSource: audioTrack,
66
40
  });
67
41
  this.callObject = callObject;
68
42
  this.setupEventHandlers(callObject);
69
- // Join room; Daily handles playback of remote (bot) audio automatically.
70
- // Only pass token when it's a non-empty string (Daily rejects undefined/non-string).
43
+ // 🔴 Ensure mic is OFF before join
44
+ callObject.setLocalAudio(false);
45
+ this.micMutedSubject.next(true);
71
46
  const joinOptions = { url: roomUrl };
72
- if (typeof token === 'string' && token.trim() !== '') {
47
+ if (typeof token === 'string' && token.trim()) {
73
48
  joinOptions.token = token;
74
49
  }
75
50
  yield callObject.join(joinOptions);
76
- console.log(`[VoiceDebug] Room connected (Daily join complete) — ${new Date().toISOString()}`);
51
+ console.log(`[VoiceDebug] Joined room — ${new Date().toISOString()}`);
77
52
  const participants = callObject.participants();
78
53
  if (participants === null || participants === void 0 ? void 0 : participants.local) {
79
54
  this.localSessionId = participants.local.session_id;
80
55
  }
81
- // Initial mute state: Daily starts with audio on
82
- this.micMutedSubject.next(!callObject.localAudio());
56
+ // 🔴 Force sync again (Daily sometimes overrides)
57
+ callObject.setLocalAudio(false);
58
+ this.micMutedSubject.next(true);
83
59
  }
84
60
  catch (err) {
85
61
  this.cleanup();
@@ -88,8 +64,6 @@ export class DailyVoiceClientService {
88
64
  });
89
65
  }
90
66
  setupEventHandlers(call) {
91
- // active-speaker-change: used ONLY for user speaking detection.
92
- // Bot speaking is detected by our own AnalyserNode (instant, no debounce).
93
67
  call.on('active-speaker-change', (event) => {
94
68
  this.ngZone.run(() => {
95
69
  var _a;
@@ -98,23 +72,20 @@ export class DailyVoiceClientService {
98
72
  this.userSpeakingSubject.next(false);
99
73
  return;
100
74
  }
101
- const isLocal = peerId === this.localSessionId;
102
- this.userSpeakingSubject.next(isLocal);
75
+ this.userSpeakingSubject.next(peerId === this.localSessionId);
103
76
  });
104
77
  });
105
- // track-started / track-stopped: set up remote audio playback + AnalyserNode monitor.
106
78
  call.on('track-started', (event) => {
107
79
  this.ngZone.run(() => {
108
- var _a, _b, _c, _d;
80
+ var _a, _b, _c, _d, _e;
109
81
  const p = event === null || event === void 0 ? void 0 : event.participant;
110
82
  const type = (_a = event === null || event === void 0 ? void 0 : event.type) !== null && _a !== void 0 ? _a : (_b = event === null || event === void 0 ? void 0 : event.track) === null || _b === void 0 ? void 0 : _b.kind;
111
- const track = event === null || event === void 0 ? void 0 : event.track;
112
83
  if (p && !p.local && type === 'audio') {
113
- console.log(`[VoiceDebug] Got audio track from backend (track-started) readyState=${track === null || track === void 0 ? void 0 : track.readyState}, muted=${track === null || track === void 0 ? void 0 : track.muted} ${new Date().toISOString()}`);
114
- const audioTrack = track !== null && track !== void 0 ? track : (_d = (_c = p.tracks) === null || _c === void 0 ? void 0 : _c.audio) === null || _d === void 0 ? void 0 : _d.track;
115
- if (audioTrack && typeof audioTrack === 'object') {
116
- this.playRemoteTrack(audioTrack);
117
- this.monitorRemoteAudio(audioTrack);
84
+ const track = (_c = event.track) !== null && _c !== void 0 ? _c : (_e = (_d = p === null || p === void 0 ? void 0 : p.tracks) === null || _d === void 0 ? void 0 : _d.audio) === null || _e === void 0 ? void 0 : _e.track;
85
+ if (track) {
86
+ console.log('[VoiceDebug] Remote audio track received');
87
+ this.playRemoteTrack(track);
88
+ this.monitorRemoteAudio(track);
118
89
  }
119
90
  }
120
91
  });
@@ -133,57 +104,27 @@ export class DailyVoiceClientService {
133
104
  call.on('left-meeting', () => {
134
105
  this.ngZone.run(() => this.cleanup());
135
106
  });
136
- call.on('error', (event) => {
137
- this.ngZone.run(() => {
138
- var _a;
139
- console.error('DailyVoiceClient: Daily error', (_a = event === null || event === void 0 ? void 0 : event.errorMsg) !== null && _a !== void 0 ? _a : event);
140
- this.cleanup();
141
- });
107
+ call.on('error', (e) => {
108
+ console.error('Daily error:', e);
109
+ this.cleanup();
142
110
  });
143
111
  }
144
- /**
145
- * Play remote (bot) audio track via a dedicated audio element.
146
- * Required in many browsers where Daily's internal playback does not output to speakers.
147
- */
148
112
  playRemoteTrack(track) {
149
113
  this.stopRemoteAudio();
150
114
  try {
151
- console.log(`[VoiceDebug] playRemoteTrack called — track.readyState=${track.readyState}, track.muted=${track.muted} — ${new Date().toISOString()}`);
152
- track.onunmute = () => {
153
- console.log(`[VoiceDebug] Remote audio track UNMUTED (audio data arriving) — ${new Date().toISOString()}`);
154
- };
155
115
  const stream = new MediaStream([track]);
156
116
  const audio = new Audio();
157
117
  audio.autoplay = true;
158
118
  audio.srcObject = stream;
159
119
  this.remoteAudioElement = audio;
160
- audio.onplaying = () => {
161
- console.log(`[VoiceDebug] Audio element PLAYING (browser started playback) — ${new Date().toISOString()}`);
162
- };
163
- let firstTimeUpdate = true;
164
- audio.ontimeupdate = () => {
165
- if (firstTimeUpdate) {
166
- firstTimeUpdate = false;
167
- console.log(`[VoiceDebug] Audio element first TIMEUPDATE (actual audio output) — ${new Date().toISOString()}`);
168
- }
169
- };
170
- const p = audio.play();
171
- if (p && typeof p.then === 'function') {
172
- p.then(() => {
173
- console.log(`[VoiceDebug] audio.play() resolved — ${new Date().toISOString()}`);
174
- }).catch((err) => {
175
- console.warn('DailyVoiceClient: remote audio play failed (may need user gesture)', err);
176
- });
177
- }
120
+ audio.play().catch(() => {
121
+ console.warn('Autoplay blocked');
122
+ });
178
123
  }
179
124
  catch (err) {
180
- console.warn('DailyVoiceClient: failed to create remote audio element', err);
125
+ console.warn('Audio playback error', err);
181
126
  }
182
127
  }
183
- /**
184
- * Monitor remote audio track energy via AnalyserNode.
185
- * Polls at ~60fps and flips speakingSubject based on actual audio energy.
186
- */
187
128
  monitorRemoteAudio(track) {
188
129
  this.stopRemoteAudioMonitor();
189
130
  try {
@@ -193,104 +134,81 @@ export class DailyVoiceClientService {
193
134
  analyser.fftSize = 256;
194
135
  source.connect(analyser);
195
136
  this.remoteAudioContext = ctx;
196
- const dataArray = new Uint8Array(analyser.frequencyBinCount);
197
- const THRESHOLD = 5;
198
- const SILENCE_MS = 1500;
199
- let lastSoundTime = 0;
200
- let isSpeaking = false;
201
- const poll = () => {
137
+ const data = new Uint8Array(analyser.frequencyBinCount);
138
+ let speaking = false;
139
+ let lastSound = 0;
140
+ const loop = () => {
202
141
  if (!this.remoteAudioContext)
203
142
  return;
204
- analyser.getByteFrequencyData(dataArray);
205
- let sum = 0;
206
- for (let i = 0; i < dataArray.length; i++) {
207
- sum += dataArray[i];
208
- }
209
- const avg = sum / dataArray.length;
143
+ analyser.getByteFrequencyData(data);
144
+ const avg = data.reduce((a, b) => a + b, 0) / data.length;
210
145
  const now = Date.now();
211
- if (avg > THRESHOLD) {
212
- lastSoundTime = now;
213
- if (!isSpeaking) {
214
- isSpeaking = true;
215
- console.log(`[VoiceDebug] Bot audio energy detected (speaking=true) — avg=${avg.toFixed(1)} — ${new Date().toISOString()}`);
146
+ if (avg > 5) {
147
+ lastSound = now;
148
+ if (!speaking) {
149
+ speaking = true;
216
150
  this.ngZone.run(() => {
217
151
  this.userSpeakingSubject.next(false);
218
152
  this.speakingSubject.next(true);
219
153
  });
220
154
  }
221
155
  }
222
- else if (isSpeaking && now - lastSoundTime > SILENCE_MS) {
223
- isSpeaking = false;
224
- console.log(`[VoiceDebug] Bot audio silence detected (speaking=false) — ${new Date().toISOString()}`);
156
+ else if (speaking && now - lastSound > 1500) {
157
+ speaking = false;
225
158
  this.ngZone.run(() => this.speakingSubject.next(false));
226
159
  }
227
- this.remoteSpeakingRAF = requestAnimationFrame(poll);
160
+ this.remoteSpeakingRAF = requestAnimationFrame(loop);
228
161
  };
229
- this.remoteSpeakingRAF = requestAnimationFrame(poll);
230
- }
231
- catch (err) {
232
- console.warn('DailyVoiceClient: failed to create remote audio monitor', err);
162
+ this.remoteSpeakingRAF = requestAnimationFrame(loop);
233
163
  }
164
+ catch (_a) { }
234
165
  }
235
166
  stopRemoteAudioMonitor() {
167
+ var _a;
236
168
  if (this.remoteSpeakingRAF) {
237
169
  cancelAnimationFrame(this.remoteSpeakingRAF);
238
170
  this.remoteSpeakingRAF = null;
239
171
  }
240
- if (this.remoteAudioContext) {
241
- this.remoteAudioContext.close().catch(() => { });
242
- this.remoteAudioContext = null;
243
- }
172
+ (_a = this.remoteAudioContext) === null || _a === void 0 ? void 0 : _a.close().catch(() => { });
173
+ this.remoteAudioContext = null;
244
174
  }
245
175
  stopRemoteAudio() {
246
176
  if (this.remoteAudioElement) {
247
- try {
248
- this.remoteAudioElement.pause();
249
- this.remoteAudioElement.srcObject = null;
250
- }
251
- catch (_) { }
177
+ this.remoteAudioElement.pause();
178
+ this.remoteAudioElement.srcObject = null;
252
179
  this.remoteAudioElement = null;
253
180
  }
254
181
  }
255
- /** Set mic muted state. */
256
182
  setMuted(muted) {
257
183
  if (!this.callObject)
258
184
  return;
259
185
  this.callObject.setLocalAudio(!muted);
260
186
  this.micMutedSubject.next(muted);
187
+ console.log(`[VoiceDebug] Mic ${muted ? 'MUTED' : 'UNMUTED'}`);
261
188
  }
262
- /** Disconnect and cleanup. */
263
189
  disconnect() {
264
190
  return __awaiter(this, void 0, void 0, function* () {
265
- if (!this.callObject) {
266
- this.cleanup();
267
- return;
268
- }
191
+ if (!this.callObject)
192
+ return this.cleanup();
269
193
  try {
270
194
  yield this.callObject.leave();
271
195
  }
272
- catch (e) {
273
- // ignore
274
- }
196
+ catch (_a) { }
275
197
  this.cleanup();
276
198
  });
277
199
  }
278
200
  cleanup() {
201
+ var _a, _b;
279
202
  this.stopRemoteAudioMonitor();
280
203
  this.stopRemoteAudio();
281
- if (this.callObject) {
282
- this.callObject.destroy().catch(() => { });
283
- this.callObject = null;
284
- }
285
- if (this.localStream) {
286
- this.localStream.getTracks().forEach((t) => t.stop());
287
- this.localStream = null;
288
- }
204
+ (_a = this.callObject) === null || _a === void 0 ? void 0 : _a.destroy().catch(() => { });
205
+ this.callObject = null;
206
+ (_b = this.localStream) === null || _b === void 0 ? void 0 : _b.getTracks().forEach((t) => t.stop());
207
+ this.localStream = null;
289
208
  this.localSessionId = null;
290
209
  this.speakingSubject.next(false);
291
210
  this.userSpeakingSubject.next(false);
292
211
  this.localStreamSubject.next(null);
293
- // Keep last micMuted state; will reset on next connect
294
212
  }
295
213
  }
296
214
  DailyVoiceClientService.ɵprov = i0.ɵɵdefineInjectable({ factory: function DailyVoiceClientService_Factory() { return new DailyVoiceClientService(i0.ɵɵinject(i0.NgZone)); }, token: DailyVoiceClientService, providedIn: "root" });
@@ -302,4 +220,4 @@ DailyVoiceClientService.decorators = [
302
220
  DailyVoiceClientService.ctorParameters = () => [
303
221
  { type: NgZone }
304
222
  ];
305
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFpbHktdm9pY2UtY2xpZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvaGl0dGhha3VyL2hpdmUtZ3B0L0hpdmVBSS1QYWNrYWdlcy9Bbmd1bGFyL3Byb2plY3RzL2hpdmVncHQvZXZlbnRzZ3B0LWFuZ3VsYXIvc3JjLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvdm9pY2UtYWdlbnQvc2VydmljZXMvZGFpbHktdm9pY2UtY2xpZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxlQUFlLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sb0JBQW9CLENBQUM7O0FBR3ZDOzs7Ozs7Ozs7O0dBVUc7QUFJSCxNQUFNLE9BQU8sdUJBQXVCO0lBNkJsQyxZQUFvQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQTVCMUIsZUFBVSxHQUFxQixJQUFJLENBQUM7UUFDcEMsZ0JBQVcsR0FBdUIsSUFBSSxDQUFDO1FBQ3ZDLG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQUM3QywwRUFBMEU7UUFDbEUsdUJBQWtCLEdBQTRCLElBQUksQ0FBQztRQUUzRCxrRkFBa0Y7UUFDMUUsdUJBQWtCLEdBQXdCLElBQUksQ0FBQztRQUMvQyxzQkFBaUIsR0FBa0IsSUFBSSxDQUFDO1FBRXhDLG9CQUFlLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDdEQsd0JBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDMUQsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUN0RCx1QkFBa0IsR0FBRyxJQUFJLGVBQWUsQ0FBcUIsSUFBSSxDQUFDLENBQUM7UUFFM0UsZ0VBQWdFO1FBQ2hFLGNBQVMsR0FBd0IsSUFBSSxDQUFD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QztLQUFBO0lBRU8sT0FBTztRQUNiLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7U0FDeEI7UUFDRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1NBQ3pCO1FBQ0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25DLHVEQUF1RDtJQUN6RCxDQUFDOzs7O1lBOVNGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7O1lBbEJvQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCBEYWlseSBmcm9tICdAZGFpbHktY28vZGFpbHktanMnO1xuaW1wb3J0IHR5cGUgeyBEYWlseUNhbGwsIERhaWx5UGFydGljaXBhbnQgfSBmcm9tICdAZGFpbHktY28vZGFpbHktanMnO1xuXG4vKipcbiAqIERhaWx5LmpzIFdlYlJUQyBjbGllbnQgZm9yIHZvaWNlIGFnZW50IGF1ZGlvLlxuICogUmVzcG9uc2liaWxpdGllczpcbiAqIC0gQ3JlYXRlIGFuZCBtYW5hZ2UgRGFpbHkgQ2FsbE9iamVjdFxuICogLSBKb2luIERhaWx5IHJvb20gdXNpbmcgcm9vbV91cmxcbiAqIC0gSGFuZGxlIG1pYyBjYXB0dXJlICsgc3BlYWtlciBwbGF5YmFja1xuICogLSBCb3Qgc3BlYWtpbmcgZGV0ZWN0aW9uIHZpYSBBbmFseXNlck5vZGUgb24gcmVtb3RlIHRyYWNrIChpbnN0YW50KVxuICogLSBVc2VyIHNwZWFraW5nIGRldGVjdGlvbiB2aWEgYWN0aXZlLXNwZWFrZXItY2hhbmdlXG4gKiAtIEV4cG9zZSBzcGVha2luZyQgKGJvdCBzcGVha2luZyksIHVzZXJTcGVha2luZyQgKHVzZXIgc3BlYWtpbmcpLCBtaWNNdXRlZCRcbiAqIC0gRXhwb3NlIGxvY2FsU3RyZWFtJCBmb3Igd2F2ZWZvcm0gdmlzdWFsaXphdGlvbiAoQXVkaW9BbmFseXplclNlcnZpY2UpXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBEYWlseVZvaWNlQ2xpZW50U2VydmljZSB7XG4gIHByaXZhdGUgY2FsbE9iamVjdDogRGFpbHlDYWxsIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbG9jYWxTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbG9jYWxTZXNzaW9uSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogRXhwbGljaXQgcGxheWJhY2sgb2YgcmVtb3RlIChib3QpIGF1ZGlvOyByZXF1aXJlZCBpbiBzb21lIGJyb3dzZXJzLiAqL1xuICBwcml2YXRlIHJlbW90ZUF1ZGlvRWxlbWVudDogSFRNTEF1ZGlvRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBBbmFseXNlck5vZGUtYmFzZWQgcmVtb3RlIGF1ZGlvIG1vbml0b3IgZm9yIGluc3RhbnQgYm90IHNwZWFraW5nIGRldGVjdGlvbi4gKi9cbiAgcHJpdmF0ZSByZW1vdGVBdWRpb0NvbnRleHQ6IEF1ZGlvQ29udGV4dCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlbW90ZVNwZWFraW5nUkFGOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHNwZWFraW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIHVzZXJTcGVha2luZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBtaWNNdXRlZFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBsb2NhbFN0cmVhbVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PE1lZGlhU3RyZWFtIHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqIFRydWUgd2hlbiBib3QgKHJlbW90ZSBwYXJ0aWNpcGFudCkgaXMgdGhlIGFjdGl2ZSBzcGVha2VyLiAqL1xuICBzcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLnNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogVHJ1ZSB3aGVuIHVzZXIgKGxvY2FsIHBhcnRpY2lwYW50KSBpcyB0aGUgYWN0aXZlIHNwZWFrZXIuICovXG4gIHVzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLnVzZXJTcGVha2luZ1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIFRydWUgd2hlbiBtaWMgaXMgbXV0ZWQuICovXG4gIG1pY011dGVkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMubWljTXV0ZWRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKiBFbWl0cyBsb2NhbCBtaWMgc3RyZWFtIGZvciB3YXZlZm9ybSB2aXN1YWxpemF0aW9uLiAqL1xuICBsb2NhbFN0cmVhbSQ6IE9ic2VydmFibGU8TWVkaWFTdHJlYW0gfCBudWxsPiA9XG4gICAgdGhpcy5sb2NhbFN0cmVhbVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkge31cblxuICAvKipcbiAgICogQ29ubmVjdCB0byBEYWlseSByb29tLiBBY3F1aXJlcyBtaWMgZmlyc3QgZm9yIHdhdmVmb3JtLCB0aGVuIGpvaW5zIHdpdGggYXVkaW8uXG4gICAqIEBwYXJhbSByb29tVXJsIERhaWx5IHJvb20gVVJMIChmcm9tIHJvb21fY3JlYXRlZClcbiAgICogQHBhcmFtIHRva2VuIE9wdGlvbmFsIG1lZXRpbmcgdG9rZW5cbiAgICovXG4gIGFzeW5jIGNvbm5lY3Qocm9vbVVybDogc3RyaW5nLCB0b2tlbj86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNhbGxPYmplY3QpIHtcbiAgICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBHZXQgbWljIHN0cmVhbSBmb3IgYm90aCBEYWlseSBhbmQgd2F2ZWZvcm0gKHNpbmdsZSBjYXB0dXJlKVxuICAgICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoeyBhdWRpbzogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IGF1ZGlvVHJhY2sgPSBzdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXTtcbiAgICAgIGlmICghYXVkaW9UcmFjaykge1xuICAgICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodCkgPT4gdC5zdG9wKCkpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGF1ZGlvIHRyYWNrJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9jYWxTdHJlYW0gPSBzdHJlYW07XG4gICAgICB0aGlzLmxvY2FsU3RyZWFtU3ViamVjdC5uZXh0KHN0cmVhbSk7XG5cbiAgICAgIC8vIENyZWF0ZSBhdWRpby1vbmx5IGNhbGwgb2JqZWN0XG4gICAgICAvLyB2aWRlb1NvdXJjZTogZmFsc2UgPSBubyBjYW1lcmEsIGF1ZGlvU291cmNlID0gb3VyIG1pYyB0cmFja1xuICAgICAgY29uc3QgY2FsbE9iamVjdCA9IERhaWx5LmNyZWF0ZUNhbGxPYmplY3Qoe1xuICAgICAgICB2aWRlb1NvdXJjZTogZmFsc2UsXG4gICAgICAgIGF1ZGlvU291cmNlOiBhdWRpb1RyYWNrLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuY2FsbE9iamVjdCA9IGNhbGxPYmplY3Q7XG5cbiAgICAgIHRoaXMuc2V0dXBFdmVudEhhbmRsZXJzKGNhbGxPYmplY3QpO1xuXG4gICAgICAvLyBKb2luIHJvb207IERhaWx5IGhhbmRsZXMgcGxheWJhY2sgb2YgcmVtb3RlIChib3QpIGF1ZGlvIGF1dG9tYXRpY2FsbHkuXG4gICAgICAvLyBPbmx5IHBhc3MgdG9rZW4gd2hlbiBpdCdzIGEgbm9uLWVtcHR5IHN0cmluZyAoRGFpbHkgcmVqZWN0cyB1bmRlZmluZWQvbm9uLXN0cmluZykuXG4gICAgICBjb25zdCBqb2luT3B0aW9uczogeyB1cmw6IHN0cmluZzsgdG9rZW4/OiBzdHJpbmcgfSA9IHsgdXJsOiByb29tVXJsIH07XG4gICAgICBpZiAodHlwZW9mIHRva2VuID09PSAnc3RyaW5nJyAmJiB0b2tlbi50cmltKCkgIT09ICcnKSB7XG4gICAgICAgIGpvaW5PcHRpb25zLnRva2VuID0gdG9rZW47XG4gICAgICB9XG4gICAgICBhd2FpdCBjYWxsT2JqZWN0LmpvaW4oam9pbk9wdGlvbnMpO1xuICAgICAgY29uc29sZS5sb2coYFtWb2ljZURlYnVnXSBSb29tIGNvbm5lY3RlZCAoRGFpbHkgam9pbiBjb21wbGV0ZSkg4oCUICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfWApO1xuXG4gICAgICBjb25zdCBwYXJ0aWNpcGFudHMgPSBjYWxsT2JqZWN0LnBhcnRpY2lwYW50cygpO1xuICAgICAgaWYgKHBhcnRpY2lwYW50cz8ubG9jYWwpIHtcbiAgICAgICAgdGhpcy5sb2NhbFNlc3Npb25JZCA9IHBhcnRpY2lwYW50cy5sb2NhbC5zZXNzaW9uX2lkO1xuICAgICAgfVxuXG4gICAgICAvLyBJbml0aWFsIG11dGUgc3RhdGU6IERhaWx5IHN0YXJ0cyB3aXRoIGF1ZGlvIG9uXG4gICAgICB0aGlzLm1pY011dGVkU3ViamVjdC5uZXh0KCFjYWxsT2JqZWN0LmxvY2FsQXVkaW8oKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldHVwRXZlbnRIYW5kbGVycyhjYWxsOiBEYWlseUNhbGwpOiB2b2lkIHtcbiAgICAvLyBhY3RpdmUtc3BlYWtlci1jaGFuZ2U6IHVzZWQgT05MWSBmb3IgdXNlciBzcGVha2luZyBkZXRlY3Rpb24uXG4gICAgLy8gQm90IHNwZWFraW5nIGlzIGRldGVjdGVkIGJ5IG91ciBvd24gQW5hbHlzZXJOb2RlIChpbnN0YW50LCBubyBkZWJvdW5jZSkuXG4gICAgY2FsbC5vbignYWN0aXZlLXNwZWFrZXItY2hhbmdlJywgKGV2ZW50OiB7IGFjdGl2ZVNwZWFrZXI/OiB7IHBlZXJJZD86IHN0cmluZyB9IH0pID0+IHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBlZXJJZCA9IGV2ZW50Py5hY3RpdmVTcGVha2VyPy5wZWVySWQ7XG4gICAgICAgIGlmICghcGVlcklkIHx8ICF0aGlzLmxvY2FsU2Vzc2lvbklkKSB7XG4gICAgICAgICAgdGhpcy51c2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpc0xvY2FsID0gcGVlcklkID09PSB0aGlzLmxvY2FsU2Vzc2lvbklkO1xuICAgICAgICB0aGlzLnVzZXJTcGVha2luZ1N1YmplY3QubmV4dChpc0xvY2FsKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gdHJhY2stc3RhcnRlZCAvIHRyYWNrLXN0b3BwZWQ6IHNldCB1cCByZW1vdGUgYXVkaW8gcGxheWJhY2sgKyBBbmFseXNlck5vZGUgbW9uaXRvci5cbiAgICBjYWxsLm9uKCd0cmFjay1zdGFydGVkJywgKGV2ZW50OiB7IHBhcnRpY2lwYW50PzogRGFpbHlQYXJ0aWNpcGFudCB8IG51bGw7IHR5cGU/OiBzdHJpbmc7IHRyYWNrPzogTWVkaWFTdHJlYW1UcmFjayB9KSA9PiB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICBjb25zdCBwID0gZXZlbnQ/LnBhcnRpY2lwYW50O1xuICAgICAgICBjb25zdCB0eXBlID0gZXZlbnQ/LnR5cGUgPz8gZXZlbnQ/LnRyYWNrPy5raW5kO1xuICAgICAgICBjb25zdCB0cmFjayA9IGV2ZW50Py50cmFjaztcbiAgICAgICAgaWYgKHAgJiYgIXAubG9jYWwgJiYgdHlwZSA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbVm9pY2VEZWJ1Z10gR290IGF1ZGlvIHRyYWNrIGZyb20gYmFja2VuZCAodHJhY2stc3RhcnRlZCkg4oCUIHJlYWR5U3RhdGU9JHt0cmFjaz8ucmVhZHlTdGF0ZX0sIG11dGVkPSR7dHJhY2s/Lm11dGVkfSDigJQgJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9YCk7XG4gICAgICAgICAgY29uc3QgYXVkaW9UcmFjayA9IHRyYWNrID8/IChwIGFzIHsgdHJhY2tzPzogeyBhdWRpbz86IHsgdHJhY2s/OiBNZWRpYVN0cmVhbVRyYWNrIH0gfSB9KS50cmFja3M/LmF1ZGlvPy50cmFjaztcbiAgICAgICAgICBpZiAoYXVkaW9UcmFjayAmJiB0eXBlb2YgYXVkaW9UcmFjayA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRoaXMucGxheVJlbW90ZVRyYWNrKGF1ZGlvVHJhY2spO1xuICAgICAgICAgICAgdGhpcy5tb25pdG9yUmVtb3RlQXVkaW8oYXVkaW9UcmFjayk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNhbGwub24oJ3RyYWNrLXN0b3BwZWQnLCAoZXZlbnQ6IHsgcGFydGljaXBhbnQ/OiBEYWlseVBhcnRpY2lwYW50IHwgbnVsbDsgdHlwZT86IHN0cmluZzsgdHJhY2s/OiBNZWRpYVN0cmVhbVRyYWNrIH0pID0+IHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHAgPSBldmVudD8ucGFydGljaXBhbnQ7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBldmVudD8udHlwZSA/PyBldmVudD8udHJhY2s/LmtpbmQ7XG4gICAgICAgIGlmIChwICYmICFwLmxvY2FsICYmIHR5cGUgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICB0aGlzLnN0b3BSZW1vdGVBdWRpb01vbml0b3IoKTtcbiAgICAgICAgICB0aGlzLnN0b3BSZW1vdGVBdWRpbygpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNhbGwub24oJ2xlZnQtbWVldGluZycsICgpID0+IHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNsZWFudXAoKSk7XG4gICAgfSk7XG5cbiAgICBjYWxsLm9uKCdlcnJvcicsIChldmVudD86IHsgZXJyb3JNc2c/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRGFpbHlWb2ljZUNsaWVudDogRGFpbHkgZXJyb3InLCBldmVudD8uZXJyb3JNc2cgPz8gZXZlbnQpO1xuICAgICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBsYXkgcmVtb3RlIChib3QpIGF1ZGlvIHRyYWNrIHZpYSBhIGRlZGljYXRlZCBhdWRpbyBlbGVtZW50LlxuICAgKiBSZXF1aXJlZCBpbiBtYW55IGJyb3dzZXJzIHdoZXJlIERhaWx5J3MgaW50ZXJuYWwgcGxheWJhY2sgZG9lcyBub3Qgb3V0cHV0IHRvIHNwZWFrZXJzLlxuICAgKi9cbiAgcHJpdmF0ZSBwbGF5UmVtb3RlVHJhY2sodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BSZW1vdGVBdWRpbygpO1xuICAgIHRyeSB7XG4gICAgICBjb25zb2xlLmxvZyhgW1ZvaWNlRGVidWddIHBsYXlSZW1vdGVUcmFjayBjYWxsZWQg4oCUIHRyYWNrLnJlYWR5U3RhdGU9JHt0cmFjay5yZWFkeVN0YXRlfSwgdHJhY2subXV0ZWQ9JHt0cmFjay5tdXRlZH0g4oCUICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfWApO1xuXG4gICAgICB0cmFjay5vbnVubXV0ZSA9ICgpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coYFtWb2ljZURlYnVnXSBSZW1vdGUgYXVkaW8gdHJhY2sgVU5NVVRFRCAoYXVkaW8gZGF0YSBhcnJpdmluZykg4oCUICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfWApO1xuICAgICAgfTtcblxuICAgICAgY29uc3Qgc3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFt0cmFja10pO1xuICAgICAgY29uc3QgYXVkaW8gPSBuZXcgQXVkaW8oKTtcbiAgICAgIGF1ZGlvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgIGF1ZGlvLnNyY09iamVjdCA9IHN0cmVhbTtcbiAgICAgIHRoaXMucmVtb3RlQXVkaW9FbGVtZW50ID0gYXVkaW87XG5cbiAgICAgIGF1ZGlvLm9ucGxheWluZyA9ICgpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coYFtWb2ljZURlYnVnXSBBdWRpbyBlbGVtZW50IFBMQVlJTkcgKGJyb3dzZXIgc3RhcnRlZCBwbGF5YmFjaykg4oCUICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfWApO1xuICAgICAgfTtcblxuICAgICAgbGV0IGZpcnN0VGltZVVwZGF0ZSA9IHRydWU7XG4gICAgICBhdWRpby5vbnRpbWV1cGRhdGUgPSAoKSA9PiB7XG4gICAgICAgIGlmIChmaXJzdFRpbWVVcGRhdGUpIHtcbiAgICAgICAgICBmaXJzdFRpbWVVcGRhdGUgPSBmYWxzZTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgW1ZvaWNlRGVidWddIEF1ZGlvIGVsZW1lbnQgZmlyc3QgVElNRVVQREFURSAoYWN0dWFsIGF1ZGlvIG91dHB1dCkg4oCUICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfWApO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwID0gYXVkaW8ucGxheSgpO1xuICAgICAgaWYgKHAgJiYgdHlwZW9mIHAudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbVm9pY2VEZWJ1Z10gYXVkaW8ucGxheSgpIHJlc29sdmVkIOKAlCAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1gKTtcbiAgICAgICAgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUud2FybignRGFpbHlWb2ljZUNsaWVudDogcmVtb3RlIGF1ZGlvIHBsYXkgZmFpbGVkIChtYXkgbmVlZCB1c2VyIGdlc3R1cmUpJywgZXJyKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0RhaWx5Vm9pY2VDbGllbnQ6IGZhaWxlZCB0byBjcmVhdGUgcmVtb3RlIGF1ZGlvIGVsZW1lbnQnLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNb25pdG9yIHJlbW90ZSBhdWRpbyB0cmFjayBlbmVyZ3kgdmlhIEFuYWx5c2VyTm9kZS5cbiAgICogUG9sbHMgYXQgfjYwZnBzIGFuZCBmbGlwcyBzcGVha2luZ1N1YmplY3QgYmFzZWQgb24gYWN0dWFsIGF1ZGlvIGVuZXJneS5cbiAgICovXG4gIHByaXZhdGUgbW9uaXRvclJlbW90ZUF1ZGlvKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wUmVtb3RlQXVkaW9Nb25pdG9yKCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGN0eCA9IG5ldyBBdWRpb0NvbnRleHQoKTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGN0eC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShuZXcgTWVkaWFTdHJlYW0oW3RyYWNrXSkpO1xuICAgICAgY29uc3QgYW5hbHlzZXIgPSBjdHguY3JlYXRlQW5hbHlzZXIoKTtcbiAgICAgIGFuYWx5c2VyLmZmdFNpemUgPSAyNTY7XG4gICAgICBzb3VyY2UuY29ubmVjdChhbmFseXNlcik7XG4gICAgICB0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dCA9IGN0eDtcblxuICAgICAgY29uc3QgZGF0YUFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYW5hbHlzZXIuZnJlcXVlbmN5QmluQ291bnQpO1xuICAgICAgY29uc3QgVEhSRVNIT0xEID0gNTtcbiAgICAgIGNvbnN0IFNJTEVOQ0VfTVMgPSAxNTAwO1xuICAgICAgbGV0IGxhc3RTb3VuZFRpbWUgPSAwO1xuICAgICAgbGV0IGlzU3BlYWtpbmcgPSBmYWxzZTtcblxuICAgICAgY29uc3QgcG9sbCA9ICgpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dCkgcmV0dXJuO1xuICAgICAgICBhbmFseXNlci5nZXRCeXRlRnJlcXVlbmN5RGF0YShkYXRhQXJyYXkpO1xuXG4gICAgICAgIGxldCBzdW0gPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHN1bSArPSBkYXRhQXJyYXlbaV07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXZnID0gc3VtIC8gZGF0YUFycmF5Lmxlbmd0aDtcblxuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoYXZnID4gVEhSRVNIT0xEKSB7XG4gICAgICAgICAgbGFzdFNvdW5kVGltZSA9IG5vdztcbiAgICAgICAgICBpZiAoIWlzU3BlYWtpbmcpIHtcbiAgICAgICAgICAgIGlzU3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFtWb2ljZURlYnVnXSBCb3QgYXVkaW8gZW5lcmd5IGRldGVjdGVkIChzcGVha2luZz10cnVlKSDigJQgYXZnPSR7YXZnLnRvRml4ZWQoMSl9IOKAlCAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1gKTtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMudXNlclNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgICAgICAgICAgdGhpcy5zcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc1NwZWFraW5nICYmIG5vdyAtIGxhc3RTb3VuZFRpbWUgPiBTSUxFTkNFX01TKSB7XG4gICAgICAgICAgaXNTcGVha2luZyA9IGZhbHNlO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbVm9pY2VEZWJ1Z10gQm90IGF1ZGlvIHNpbGVuY2UgZGV0ZWN0ZWQgKHNwZWFraW5nPWZhbHNlKSDigJQgJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9YCk7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuc3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVtb3RlU3BlYWtpbmdSQUYgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocG9sbCk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLnJlbW90ZVNwZWFraW5nUkFGID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHBvbGwpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS53YXJuKCdEYWlseVZvaWNlQ2xpZW50OiBmYWlsZWQgdG8gY3JlYXRlIHJlbW90ZSBhdWRpbyBtb25pdG9yJywgZXJyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0b3BSZW1vdGVBdWRpb01vbml0b3IoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVtb3RlU3BlYWtpbmdSQUYpIHtcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmVtb3RlU3BlYWtpbmdSQUYpO1xuICAgICAgdGhpcy5yZW1vdGVTcGVha2luZ1JBRiA9IG51bGw7XG4gICAgfVxuICAgIGlmICh0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dCkge1xuICAgICAgdGhpcy5yZW1vdGVBdWRpb0NvbnRleHQuY2xvc2UoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICB0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdG9wUmVtb3RlQXVkaW8oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVtb3RlQXVkaW9FbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnJlbW90ZUF1ZGlvRWxlbWVudC5wYXVzZSgpO1xuICAgICAgICB0aGlzLnJlbW90ZUF1ZGlvRWxlbWVudC5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgfSBjYXRjaCAoXykge31cbiAgICAgIHRoaXMucmVtb3RlQXVkaW9FbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKiogU2V0IG1pYyBtdXRlZCBzdGF0ZS4gKi9cbiAgc2V0TXV0ZWQobXV0ZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2FsbE9iamVjdCkgcmV0dXJuO1xuICAgIHRoaXMuY2FsbE9iamVjdC5zZXRMb2NhbEF1ZGlvKCFtdXRlZCk7XG4gICAgdGhpcy5taWNNdXRlZFN1YmplY3QubmV4dChtdXRlZCk7XG4gIH1cblxuICAvKiogRGlzY29ubmVjdCBhbmQgY2xlYW51cC4gKi9cbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuY2FsbE9iamVjdCkge1xuICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNhbGxPYmplY3QubGVhdmUoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBpZ25vcmVcbiAgICB9XG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFudXAoKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wUmVtb3RlQXVkaW9Nb25pdG9yKCk7XG4gICAgdGhpcy5zdG9wUmVtb3RlQXVkaW8oKTtcbiAgICBpZiAodGhpcy5jYWxsT2JqZWN0KSB7XG4gICAgICB0aGlzLmNhbGxPYmplY3QuZGVzdHJveSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgIHRoaXMuY2FsbE9iamVjdCA9IG51bGw7XG4gICAgfVxuICAgIGlmICh0aGlzLmxvY2FsU3RyZWFtKSB7XG4gICAgICB0aGlzLmxvY2FsU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHQpID0+IHQuc3RvcCgpKTtcbiAgICAgIHRoaXMubG9jYWxTdHJlYW0gPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmxvY2FsU2Vzc2lvbklkID0gbnVsbDtcbiAgICB0aGlzLnNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLnVzZXJTcGVha2luZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgdGhpcy5sb2NhbFN0cmVhbVN1YmplY3QubmV4dChudWxsKTtcbiAgICAvLyBLZWVwIGxhc3QgbWljTXV0ZWQgc3RhdGU7IHdpbGwgcmVzZXQgb24gbmV4dCBjb25uZWN0XG4gIH1cbn1cbiJdfQ==
223
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFpbHktdm9pY2UtY2xpZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL3JvaGl0dGhha3VyL2hpdmUtZ3B0L0hpdmVBSS1QYWNrYWdlcy9Bbmd1bGFyL3Byb2plY3RzL2hpdmVncHQvZXZlbnRzZ3B0LWFuZ3VsYXIvc3JjLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvdm9pY2UtYWdlbnQvc2VydmljZXMvZGFpbHktdm9pY2UtY2xpZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxlQUFlLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sb0JBQW9CLENBQUM7O0FBTXZDLE1BQU0sT0FBTyx1QkFBdUI7SUFtQmxDLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBbEIxQixlQUFVLEdBQXFCLElBQUksQ0FBQztRQUNwQyxnQkFBVyxHQUF1QixJQUFJLENBQUM7UUFDdkMsbUJBQWMsR0FBa0IsSUFBSSxDQUFDO1FBQ3JDLHVCQUFrQixHQUE0QixJQUFJLENBQUM7UUFFbkQsdUJBQWtCLEdBQXdCLElBQUksQ0FBQztRQUMvQyxzQkFBaUIsR0FBa0IsSUFBSSxDQUFDO1FBRXhDLG9CQUFlLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDdEQsd0JBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDMUQsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBVSxJQUFJLENBQUMsQ0FBQyxDQUFDLG1CQUFtQjtRQUN6RSx1QkFBa0IsR0FBRyxJQUFJLGVBQWUsQ0FBcUIsSUFBSSxDQUFDLENBQUM7UUFFM0UsY0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDaEQsa0JBQWEsR0FBRyxJQUFJ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Q0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV2QixNQUFBLElBQUksQ0FBQyxVQUFVLDBDQUFFLE9BQU8sR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFFdkIsTUFBQSxJQUFJLENBQUMsV0FBVywwQ0FBRSxTQUFTLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUV4QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUUzQixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDckMsQ0FBQzs7OztZQWhQRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQVBvQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCBEYWlseSBmcm9tICdAZGFpbHktY28vZGFpbHktanMnO1xuaW1wb3J0IHR5cGUgeyBEYWlseUNhbGwsIERhaWx5UGFydGljaXBhbnQgfSBmcm9tICdAZGFpbHktY28vZGFpbHktanMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgRGFpbHlWb2ljZUNsaWVudFNlcnZpY2Uge1xuICBwcml2YXRlIGNhbGxPYmplY3Q6IERhaWx5Q2FsbCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxvY2FsU3RyZWFtOiBNZWRpYVN0cmVhbSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxvY2FsU2Vzc2lvbklkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZW1vdGVBdWRpb0VsZW1lbnQ6IEhUTUxBdWRpb0VsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlbW90ZUF1ZGlvQ29udGV4dDogQXVkaW9Db250ZXh0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVtb3RlU3BlYWtpbmdSQUY6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgc3BlYWtpbmdTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgdXNlclNwZWFraW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIG1pY011dGVkU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4odHJ1ZSk7IC8vIPCflLQgZGVmYXVsdCBtdXRlZFxuICBwcml2YXRlIGxvY2FsU3RyZWFtU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8TWVkaWFTdHJlYW0gfCBudWxsPihudWxsKTtcblxuICBzcGVha2luZyQgPSB0aGlzLnNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgdXNlclNwZWFraW5nJCA9IHRoaXMudXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgbWljTXV0ZWQkID0gdGhpcy5taWNNdXRlZFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGxvY2FsU3RyZWFtJCA9IHRoaXMubG9jYWxTdHJlYW1TdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUpIHt9XG5cbiAgYXN5bmMgY29ubmVjdChyb29tVXJsOiBzdHJpbmcsIHRva2VuPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2FsbE9iamVjdCkge1xuICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIPCfjqQgR2V0IG1pYyAoa2VwdCBmb3Igd2F2ZWZvcm0pXG4gICAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7IGF1ZGlvOiB0cnVlIH0pO1xuICAgICAgY29uc3QgYXVkaW9UcmFjayA9IHN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgICAgaWYgKCFhdWRpb1RyYWNrKSB0aHJvdyBuZXcgRXJyb3IoJ05vIGF1ZGlvIHRyYWNrJyk7XG5cbiAgICAgIHRoaXMubG9jYWxTdHJlYW0gPSBzdHJlYW07XG4gICAgICB0aGlzLmxvY2FsU3RyZWFtU3ViamVjdC5uZXh0KHN0cmVhbSk7XG5cbiAgICAgIGNvbnN0IGNhbGxPYmplY3QgPSBEYWlseS5jcmVhdGVDYWxsT2JqZWN0KHtcbiAgICAgICAgdmlkZW9Tb3VyY2U6IGZhbHNlLFxuICAgICAgICBhdWRpb1NvdXJjZTogYXVkaW9UcmFjayxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmNhbGxPYmplY3QgPSBjYWxsT2JqZWN0O1xuICAgICAgdGhpcy5zZXR1cEV2ZW50SGFuZGxlcnMoY2FsbE9iamVjdCk7XG5cbiAgICAgIC8vIPCflLQgRW5zdXJlIG1pYyBpcyBPRkYgYmVmb3JlIGpvaW5cbiAgICAgIGNhbGxPYmplY3Quc2V0TG9jYWxBdWRpbyhmYWxzZSk7XG4gICAgICB0aGlzLm1pY011dGVkU3ViamVjdC5uZXh0KHRydWUpO1xuXG4gICAgICBjb25zdCBqb2luT3B0aW9uczogeyB1cmw6IHN0cmluZzsgdG9rZW4/OiBzdHJpbmcgfSA9IHsgdXJsOiByb29tVXJsIH07XG4gICAgICBpZiAodHlwZW9mIHRva2VuID09PSAnc3RyaW5nJyAmJiB0b2tlbi50cmltKCkpIHtcbiAgICAgICAgam9pbk9wdGlvbnMudG9rZW4gPSB0b2tlbjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgY2FsbE9iamVjdC5qb2luKGpvaW5PcHRpb25zKTtcblxuICAgICAgY29uc29sZS5sb2coYFtWb2ljZURlYnVnXSBKb2luZWQgcm9vbSDigJQgJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9YCk7XG5cbiAgICAgIGNvbnN0IHBhcnRpY2lwYW50cyA9IGNhbGxPYmplY3QucGFydGljaXBhbnRzKCk7XG4gICAgICBpZiAocGFydGljaXBhbnRzPy5sb2NhbCkge1xuICAgICAgICB0aGlzLmxvY2FsU2Vzc2lvbklkID0gcGFydGljaXBhbnRzLmxvY2FsLnNlc3Npb25faWQ7XG4gICAgICB9XG5cbiAgICAgIC8vIPCflLQgRm9yY2Ugc3luYyBhZ2FpbiAoRGFpbHkgc29tZXRpbWVzIG92ZXJyaWRlcylcbiAgICAgIGNhbGxPYmplY3Quc2V0TG9jYWxBdWRpbyhmYWxzZSk7XG4gICAgICB0aGlzLm1pY011dGVkU3ViamVjdC5uZXh0KHRydWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cEV2ZW50SGFuZGxlcnMoY2FsbDogRGFpbHlDYWxsKTogdm9pZCB7XG4gICAgY2FsbC5vbignYWN0aXZlLXNwZWFrZXItY2hhbmdlJywgKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBlZXJJZCA9IGV2ZW50Py5hY3RpdmVTcGVha2VyPy5wZWVySWQ7XG4gICAgICAgIGlmICghcGVlcklkIHx8ICF0aGlzLmxvY2FsU2Vzc2lvbklkKSB7XG4gICAgICAgICAgdGhpcy51c2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVzZXJTcGVha2luZ1N1YmplY3QubmV4dChwZWVySWQgPT09IHRoaXMubG9jYWxTZXNzaW9uSWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjYWxsLm9uKCd0cmFjay1zdGFydGVkJywgKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHAgPSBldmVudD8ucGFydGljaXBhbnQ7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBldmVudD8udHlwZSA/PyBldmVudD8udHJhY2s/LmtpbmQ7XG5cbiAgICAgICAgaWYgKHAgJiYgIXAubG9jYWwgJiYgdHlwZSA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgIGNvbnN0IHRyYWNrID0gZXZlbnQudHJhY2sgPz8gcD8udHJhY2tzPy5hdWRpbz8udHJhY2s7XG5cbiAgICAgICAgICBpZiAodHJhY2spIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbVm9pY2VEZWJ1Z10gUmVtb3RlIGF1ZGlvIHRyYWNrIHJlY2VpdmVkJyk7XG4gICAgICAgICAgICB0aGlzLnBsYXlSZW1vdGVUcmFjayh0cmFjayk7XG4gICAgICAgICAgICB0aGlzLm1vbml0b3JSZW1vdGVBdWRpbyh0cmFjayk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNhbGwub24oJ3RyYWNrLXN0b3BwZWQnLCAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgY29uc3QgcCA9IGV2ZW50Py5wYXJ0aWNpcGFudDtcbiAgICAgICAgY29uc3QgdHlwZSA9IGV2ZW50Py50eXBlID8/IGV2ZW50Py50cmFjaz8ua2luZDtcblxuICAgICAgICBpZiAocCAmJiAhcC5sb2NhbCAmJiB0eXBlID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgdGhpcy5zdG9wUmVtb3RlQXVkaW9Nb25pdG9yKCk7XG4gICAgICAgICAgdGhpcy5zdG9wUmVtb3RlQXVkaW8oKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjYWxsLm9uKCdsZWZ0LW1lZXRpbmcnLCAoKSA9PiB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5jbGVhbnVwKCkpO1xuICAgIH0pO1xuXG4gICAgY2FsbC5vbignZXJyb3InLCAoZTogYW55KSA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKCdEYWlseSBlcnJvcjonLCBlKTtcbiAgICAgIHRoaXMuY2xlYW51cCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGF5UmVtb3RlVHJhY2sodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BSZW1vdGVBdWRpbygpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbShbdHJhY2tdKTtcbiAgICAgIGNvbnN0IGF1ZGlvID0gbmV3IEF1ZGlvKCk7XG4gICAgICBhdWRpby5hdXRvcGxheSA9IHRydWU7XG4gICAgICBhdWRpby5zcmNPYmplY3QgPSBzdHJlYW07XG5cbiAgICAgIHRoaXMucmVtb3RlQXVkaW9FbGVtZW50ID0gYXVkaW87XG5cbiAgICAgIGF1ZGlvLnBsYXkoKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUud2FybignQXV0b3BsYXkgYmxvY2tlZCcpO1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0F1ZGlvIHBsYXliYWNrIGVycm9yJywgZXJyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vbml0b3JSZW1vdGVBdWRpbyh0cmFjazogTWVkaWFTdHJlYW1UcmFjayk6IHZvaWQge1xuICAgIHRoaXMuc3RvcFJlbW90ZUF1ZGlvTW9uaXRvcigpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGN0eCA9IG5ldyBBdWRpb0NvbnRleHQoKTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGN0eC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShuZXcgTWVkaWFTdHJlYW0oW3RyYWNrXSkpO1xuICAgICAgY29uc3QgYW5hbHlzZXIgPSBjdHguY3JlYXRlQW5hbHlzZXIoKTtcblxuICAgICAgYW5hbHlzZXIuZmZ0U2l6ZSA9IDI1NjtcbiAgICAgIHNvdXJjZS5jb25uZWN0KGFuYWx5c2VyKTtcblxuICAgICAgdGhpcy5yZW1vdGVBdWRpb0NvbnRleHQgPSBjdHg7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheShhbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudCk7XG5cbiAgICAgIGxldCBzcGVha2luZyA9IGZhbHNlO1xuICAgICAgbGV0IGxhc3RTb3VuZCA9IDA7XG5cbiAgICAgIGNvbnN0IGxvb3AgPSAoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5yZW1vdGVBdWRpb0NvbnRleHQpIHJldHVybjtcblxuICAgICAgICBhbmFseXNlci5nZXRCeXRlRnJlcXVlbmN5RGF0YShkYXRhKTtcbiAgICAgICAgY29uc3QgYXZnID0gZGF0YS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKSAvIGRhdGEubGVuZ3RoO1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIGlmIChhdmcgPiA1KSB7XG4gICAgICAgICAgbGFzdFNvdW5kID0gbm93O1xuICAgICAgICAgIGlmICghc3BlYWtpbmcpIHtcbiAgICAgICAgICAgIHNwZWFraW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMudXNlclNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgICAgICAgICAgdGhpcy5zcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzcGVha2luZyAmJiBub3cgLSBsYXN0U291bmQgPiAxNTAwKSB7XG4gICAgICAgICAgc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5zcGVha2luZ1N1YmplY3QubmV4dChmYWxzZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW1vdGVTcGVha2luZ1JBRiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMucmVtb3RlU3BlYWtpbmdSQUYgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobG9vcCk7XG4gICAgfSBjYXRjaCB7fVxuICB9XG5cbiAgcHJpdmF0ZSBzdG9wUmVtb3RlQXVkaW9Nb25pdG9yKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJlbW90ZVNwZWFraW5nUkFGKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJlbW90ZVNwZWFraW5nUkFGKTtcbiAgICAgIHRoaXMucmVtb3RlU3BlYWtpbmdSQUYgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLnJlbW90ZUF1ZGlvQ29udGV4dD8uY2xvc2UoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgdGhpcy5yZW1vdGVBdWRpb0NvbnRleHQgPSBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wUmVtb3RlQXVkaW8oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVtb3RlQXVkaW9FbGVtZW50KSB7XG4gICAgICB0aGlzLnJlbW90ZUF1ZGlvRWxlbWVudC5wYXVzZSgpO1xuICAgICAgdGhpcy5yZW1vdGVBdWRpb0VsZW1lbnQuc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgIHRoaXMucmVtb3RlQXVkaW9FbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBzZXRNdXRlZChtdXRlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYWxsT2JqZWN0KSByZXR1cm47XG5cbiAgICB0aGlzLmNhbGxPYmplY3Quc2V0TG9jYWxBdWRpbyghbXV0ZWQpO1xuICAgIHRoaXMubWljTXV0ZWRTdWJqZWN0Lm5leHQobXV0ZWQpO1xuXG4gICAgY29uc29sZS5sb2coYFtWb2ljZURlYnVnXSBNaWMgJHttdXRlZCA/ICdNVVRFRCcgOiAnVU5NVVRFRCd9YCk7XG4gIH1cblxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5jYWxsT2JqZWN0KSByZXR1cm4gdGhpcy5jbGVhbnVwKCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jYWxsT2JqZWN0LmxlYXZlKCk7XG4gICAgfSBjYXRjaCB7fVxuXG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFudXAoKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wUmVtb3RlQXVkaW9Nb25pdG9yKCk7XG4gICAgdGhpcy5zdG9wUmVtb3RlQXVkaW8oKTtcblxuICAgIHRoaXMuY2FsbE9iamVjdD8uZGVzdHJveSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB0aGlzLmNhbGxPYmplY3QgPSBudWxsO1xuXG4gICAgdGhpcy5sb2NhbFN0cmVhbT8uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodCkgPT4gdC5zdG9wKCkpO1xuICAgIHRoaXMubG9jYWxTdHJlYW0gPSBudWxsO1xuXG4gICAgdGhpcy5sb2NhbFNlc3Npb25JZCA9IG51bGw7XG5cbiAgICB0aGlzLnNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLnVzZXJTcGVha2luZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgdGhpcy5sb2NhbFN0cmVhbVN1YmplY3QubmV4dChudWxsKTtcbiAgfVxufVxuIl19