@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.
@@ -12,21 +12,8 @@ import * as i1 from "./audio-analyzer.service";
12
12
  import * as i2 from "./websocket-voice-client.service";
13
13
  import * as i3 from "./daily-voice-client.service";
14
14
  import * as i4 from "../../../services/platform-token-refresh.service";
15
- /**
16
- * Voice agent orchestrator. Coordinates WebSocket (signaling) and Daily.js (WebRTC audio).
17
- *
18
- * CRITICAL: This service must NEVER use Socket.IO or ngx-socket-io. Voice flow uses only:
19
- * - Native WebSocket (WebSocketVoiceClientService) for signaling (room_created, transcripts)
20
- * - Daily.js (DailyVoiceClientService) for WebRTC audio. Audio does NOT flow over WebSocket.
21
- *
22
- * - Maintains callState, statusText, duration, isMicMuted, isUserSpeaking, audioLevels
23
- * - Uses WebSocket for room_created and transcripts only (no audio)
24
- * - Uses Daily.js for all audio, mic, and real-time speaking detection
25
- */
26
15
  export class VoiceAgentService {
27
- constructor(audioAnalyzer, wsClient, dailyClient, platformTokenRefresh,
28
- /** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
29
- platformId) {
16
+ constructor(audioAnalyzer, wsClient, dailyClient, platformTokenRefresh, platformId) {
30
17
  this.audioAnalyzer = audioAnalyzer;
31
18
  this.wsClient = wsClient;
32
19
  this.dailyClient = dailyClient;
@@ -35,7 +22,7 @@ export class VoiceAgentService {
35
22
  this.callStateSubject = new BehaviorSubject('idle');
36
23
  this.statusTextSubject = new BehaviorSubject('');
37
24
  this.durationSubject = new BehaviorSubject('00:00');
38
- this.isMicMutedSubject = new BehaviorSubject(false);
25
+ this.isMicMutedSubject = new BehaviorSubject(true);
39
26
  this.isUserSpeakingSubject = new BehaviorSubject(false);
40
27
  this.audioLevelsSubject = new BehaviorSubject([]);
41
28
  this.userTranscriptSubject = new Subject();
@@ -52,7 +39,6 @@ export class VoiceAgentService {
52
39
  this.audioLevels$ = this.audioLevelsSubject.asObservable();
53
40
  this.userTranscript$ = this.userTranscriptSubject.asObservable();
54
41
  this.botTranscript$ = this.botTranscriptSubject.asObservable();
55
- // Waveform visualization only - do NOT use for speaking state
56
42
  this.subscriptions.add(this.audioAnalyzer.audioLevels$.subscribe((levels) => this.audioLevelsSubject.next(levels)));
57
43
  }
58
44
  ngOnDestroy() {
@@ -60,32 +46,30 @@ export class VoiceAgentService {
60
46
  this.subscriptions.unsubscribe();
61
47
  this.disconnect();
62
48
  }
63
- /** Reset to idle state (e.g. when modal opens so user can click Start Call). */
49
+ /**
50
+ * Tear down transports and reset UI state so a new `connect()` can run.
51
+ * `connect()` only proceeds from `idle`; use this after `ended` or when reopening the modal.
52
+ */
64
53
  resetToIdle() {
65
- if (this.callStateSubject.value === 'idle')
66
- return;
67
54
  this.stopDurationTimer();
68
55
  this.audioAnalyzer.stop();
69
56
  this.wsClient.disconnect();
70
- // Fire-and-forget: Daily disconnect is async; connect() will await if needed
71
57
  void this.dailyClient.disconnect();
72
58
  this.callStateSubject.next('idle');
73
59
  this.statusTextSubject.next('');
74
- this.durationSubject.next('0:00');
60
+ this.durationSubject.next('00:00');
61
+ this.isMicMutedSubject.next(true);
62
+ this.isUserSpeakingSubject.next(false);
63
+ this.audioLevelsSubject.next([]);
75
64
  }
76
65
  connect(apiUrl, token, botId, conversationId, apiKey, eventToken, eventUrl, domainAuthority, usersApiUrl) {
77
66
  return __awaiter(this, void 0, void 0, function* () {
78
- if (this.callStateSubject.value !== 'idle') {
79
- console.warn('Call already in progress');
67
+ if (this.callStateSubject.value !== 'idle')
80
68
  return;
81
- }
82
69
  try {
83
70
  this.callStateSubject.next('connecting');
84
- this.statusTextSubject.next('Connecting...');
71
+ this.statusTextSubject.next('Connecting to agent...');
85
72
  let accessToken = token;
86
- // Align with chat drawer token handling: always delegate to
87
- // PlatformTokenRefreshService when we have a usersApiUrl, so it can
88
- // fall back to stored tokens even if the caller passed an empty token.
89
73
  if (usersApiUrl && isPlatformBrowser(this.platformId)) {
90
74
  try {
91
75
  const ensured = yield this.platformTokenRefresh
@@ -96,93 +80,73 @@ export class VoiceAgentService {
96
80
  accessToken = ensured.accessToken;
97
81
  }
98
82
  }
99
- catch (e) {
100
- console.warn('[HiveGpt Voice] Token refresh before connect failed', e);
101
- }
83
+ catch (_a) { }
102
84
  }
103
- const baseUrl = apiUrl.replace(/\/$/, '');
104
85
  const postUrl = `https://1356-103-210-33-236.ngrok-free.app/ai/ask-voice`;
105
- const headers = {
106
- 'Content-Type': 'application/json',
107
- Authorization: `Bearer ${accessToken}`,
108
- 'domain-authority': domainAuthority,
109
- 'eventtoken': eventToken,
110
- 'eventurl': eventUrl,
111
- 'hive-bot-id': botId,
112
- 'x-api-key': apiKey,
113
- 'ngrok-skip-browser-warning': 'true',
114
- };
115
- // POST to get ws_url for signaling
116
86
  const res = yield fetch(postUrl, {
117
87
  method: 'POST',
118
- headers,
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ Authorization: `Bearer ${accessToken}`,
91
+ 'domain-authority': domainAuthority,
92
+ eventtoken: eventToken,
93
+ eventurl: eventUrl,
94
+ 'hive-bot-id': botId,
95
+ 'x-api-key': apiKey,
96
+ },
119
97
  body: JSON.stringify({
120
98
  bot_id: botId,
121
99
  conversation_id: conversationId,
122
100
  voice: 'alloy',
123
101
  }),
124
102
  });
125
- if (!res.ok) {
126
- throw new Error(`HTTP ${res.status}`);
127
- }
128
103
  const json = yield res.json();
129
104
  const wsUrl = json === null || json === void 0 ? void 0 : json.rn_ws_url;
130
- if (!wsUrl || typeof wsUrl !== 'string') {
131
- throw new Error('No ws_url in response');
132
- }
133
- // Subscribe to room_created BEFORE connecting to avoid race
134
105
  this.wsClient.roomCreated$
135
106
  .pipe(take(1), takeUntil(this.destroy$))
136
107
  .subscribe((roomUrl) => __awaiter(this, void 0, void 0, function* () {
137
- try {
138
- yield this.onRoomCreated(roomUrl);
139
- }
140
- catch (err) {
141
- console.error('Daily join failed:', err);
142
- this.callStateSubject.next('ended');
143
- this.statusTextSubject.next('Connection failed');
144
- yield this.disconnect();
145
- throw err;
146
- }
108
+ yield this.onRoomCreated(roomUrl);
147
109
  }));
148
- // Forward transcripts from WebSocket
149
- this.subscriptions.add(this.wsClient.userTranscript$
150
- .pipe(takeUntil(this.destroy$))
151
- .subscribe((t) => this.userTranscriptSubject.next(t)));
152
- this.subscriptions.add(this.wsClient.botTranscript$
153
- .pipe(takeUntil(this.destroy$))
154
- .subscribe((t) => this.botTranscriptSubject.next(t)));
155
- // Connect signaling WebSocket (no audio over WS)
110
+ this.subscriptions.add(this.wsClient.userTranscript$.subscribe((t) => this.userTranscriptSubject.next(t)));
111
+ this.subscriptions.add(this.wsClient.botTranscript$.subscribe((t) => this.botTranscriptSubject.next(t)));
156
112
  this.wsClient.connect(wsUrl);
157
113
  }
158
- catch (error) {
159
- console.error('Error connecting voice agent:', error);
114
+ catch (e) {
160
115
  this.callStateSubject.next('ended');
161
- yield this.disconnect();
162
- this.statusTextSubject.next('Connection failed');
163
- throw error;
164
116
  }
165
117
  });
166
118
  }
167
119
  onRoomCreated(roomUrl) {
168
120
  return __awaiter(this, void 0, void 0, function* () {
169
- // Connect Daily.js for WebRTC audio
170
121
  yield this.dailyClient.connect(roomUrl);
171
- // Waveform: use local mic stream from Daily client
172
- this.dailyClient.localStream$
173
- .pipe(filter((s) => s != null), take(1))
174
- .subscribe((stream) => {
175
- this.audioAnalyzer.start(stream);
122
+ // 🔴 Start MUTED
123
+ this.dailyClient.setMuted(true);
124
+ this.isMicMutedSubject.next(true);
125
+ this.statusTextSubject.next('Listening to agent...');
126
+ // ✅ Enable mic on FIRST bot speech
127
+ let handled = false;
128
+ this.dailyClient.speaking$.pipe(filter(Boolean), take(1)).subscribe(() => {
129
+ if (handled)
130
+ return;
131
+ handled = true;
132
+ console.log('[VoiceFlow] First bot response → enabling mic');
133
+ this.dailyClient.setMuted(false);
134
+ this.statusTextSubject.next('You can speak now');
176
135
  });
177
- this.subscriptions.add(this.dailyClient.userSpeaking$.subscribe((s) => this.isUserSpeakingSubject.next(s)));
136
+ // ⛑️ Fallback (if bot fails)
137
+ setTimeout(() => {
138
+ if (!handled) {
139
+ console.warn('[VoiceFlow] Fallback → enabling mic');
140
+ this.dailyClient.setMuted(false);
141
+ this.statusTextSubject.next('You can speak now');
142
+ }
143
+ }, 8000);
144
+ // rest same
178
145
  this.subscriptions.add(combineLatest([
179
146
  this.dailyClient.speaking$,
180
147
  this.dailyClient.userSpeaking$,
181
148
  ]).subscribe(([bot, user]) => {
182
149
  const current = this.callStateSubject.value;
183
- if (current === 'connecting' && !bot) {
184
- return;
185
- }
186
150
  if (current === 'connecting' && bot) {
187
151
  this.callStartTime = Date.now();
188
152
  this.startDurationTimer();
@@ -195,19 +159,16 @@ export class VoiceAgentService {
195
159
  else if (bot) {
196
160
  this.callStateSubject.next('talking');
197
161
  }
198
- else if (current === 'talking' || current === 'listening') {
162
+ else {
199
163
  this.callStateSubject.next('connected');
200
164
  }
201
165
  }));
202
- this.subscriptions.add(this.dailyClient.micMuted$.subscribe((muted) => this.isMicMutedSubject.next(muted)));
203
- this.statusTextSubject.next('Connecting...');
204
166
  });
205
167
  }
206
168
  disconnect() {
207
169
  return __awaiter(this, void 0, void 0, function* () {
208
170
  this.stopDurationTimer();
209
171
  this.audioAnalyzer.stop();
210
- // Daily first, then WebSocket
211
172
  yield this.dailyClient.disconnect();
212
173
  this.wsClient.disconnect();
213
174
  this.callStateSubject.next('ended');
@@ -219,22 +180,16 @@ export class VoiceAgentService {
219
180
  this.dailyClient.setMuted(!current);
220
181
  }
221
182
  startDurationTimer() {
222
- const updateDuration = () => {
223
- if (this.callStartTime > 0) {
224
- const elapsed = Math.floor((Date.now() - this.callStartTime) / 1000);
225
- const minutes = Math.floor(elapsed / 60);
226
- const seconds = elapsed % 60;
227
- this.durationSubject.next(`${minutes}:${String(seconds).padStart(2, '0')}`);
228
- }
229
- };
230
- updateDuration();
231
- this.durationInterval = setInterval(updateDuration, 1000);
183
+ this.durationInterval = setInterval(() => {
184
+ const elapsed = Math.floor((Date.now() - this.callStartTime) / 1000);
185
+ const m = Math.floor(elapsed / 60);
186
+ const s = elapsed % 60;
187
+ this.durationSubject.next(`${m}:${String(s).padStart(2, '0')}`);
188
+ }, 1000);
232
189
  }
233
190
  stopDurationTimer() {
234
- if (this.durationInterval) {
191
+ if (this.durationInterval)
235
192
  clearInterval(this.durationInterval);
236
- this.durationInterval = null;
237
- }
238
193
  }
239
194
  }
240
195
  VoiceAgentService.ɵprov = i0.ɵɵdefineInjectable({ factory: function VoiceAgentService_Factory() { return new VoiceAgentService(i0.ɵɵinject(i1.AudioAnalyzerService), i0.ɵɵinject(i2.WebSocketVoiceClientService), i0.ɵɵinject(i3.DailyVoiceClientService), i0.ɵɵinject(i4.PlatformTokenRefreshService), i0.ɵɵinject(i0.PLATFORM_ID)); }, token: VoiceAgentService, providedIn: "root" });
@@ -250,4 +205,4 @@ VoiceAgentService.ctorParameters = () => [
250
205
  { type: PlatformTokenRefreshService },
251
206
  { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
252
207
  ];
253
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9oaXR0aGFrdXIvaGl2ZS1ncHQvSGl2ZUFJLVBhY2thZ2VzL0FuZ3VsYXIvcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy92b2ljZS1hZ2VudC9zZXJ2aWNlcy92b2ljZS1hZ2VudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBYSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBRWIsT0FBTyxFQUNQLFlBQVksR0FDYixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pELE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQy9GLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQy9FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7QUFldkU7Ozs7Ozs7Ozs7R0FVRztBQUlILE1BQU0sT0FBTyxpQkFBaUI7SUEyQjVCLFlBQ1UsYUFBbUMsRUFDbkMsUUFBcUMsRUFDckMsV0FBb0MsRUFDcEMsb0JBQWlEO0lBQ3pELDhGQUE4RjtJQUNqRSxVQUFrQjtRQUx2QyxrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFDbkMsYUFBUSxHQUFSLFFBQVEsQ0FBNkI7UUFDckMsZ0JBQVcsR0FBWCxXQUFXLENBQXlCO1FBQ3BDLHlCQUFvQixHQUFwQixvQkFB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QUMsZ0JBQWdCLEVBQUU7WUFDekIsYUFBYSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7U0FDOUI7SUFDSCxDQUFDOzs7O1lBMVFGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7O1lBOUJRLG9CQUFvQjtZQUNwQiwyQkFBMkI7WUFDM0IsdUJBQXVCO1lBSHZCLDJCQUEyQjtZQWlFUyxNQUFNLHVCQUE5QyxNQUFNLFNBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQmVoYXZpb3JTdWJqZWN0LFxuICBjb21iaW5lTGF0ZXN0LFxuICBPYnNlcnZhYmxlLFxuICBTdWJqZWN0LFxuICBTdWJzY3JpcHRpb24sXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBQbGF0Zm9ybVRva2VuUmVmcmVzaFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9wbGF0Zm9ybS10b2tlbi1yZWZyZXNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXVkaW9BbmFseXplclNlcnZpY2UgfSBmcm9tICcuL2F1ZGlvLWFuYWx5emVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgV2ViU29ja2V0Vm9pY2VDbGllbnRTZXJ2aWNlIH0gZnJvbSAnLi93ZWJzb2NrZXQtdm9pY2UtY2xpZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgRGFpbHlWb2ljZUNsaWVudFNlcnZpY2UgfSBmcm9tICcuL2RhaWx5LXZvaWNlLWNsaWVudC5zZXJ2aWNlJztcblxuZXhwb3J0IHR5cGUgQ2FsbFN0YXRlID1cbiAgfCAnaWRsZSdcbiAgfCAnY29ubmVjdGluZydcbiAgfCAnY29ubmVjdGVkJ1xuICB8ICdsaXN0ZW5pbmcnXG4gIHwgJ3RhbGtpbmcnXG4gIHwgJ2VuZGVkJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2NyaXB0RGF0YSB7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVm9pY2UgYWdlbnQgb3JjaGVzdHJhdG9yLiBDb29yZGluYXRlcyBXZWJTb2NrZXQgKHNpZ25hbGluZykgYW5kIERhaWx5LmpzIChXZWJSVEMgYXVkaW8pLlxuICpcbiAqIENSSVRJQ0FMOiBUaGlzIHNlcnZpY2UgbXVzdCBORVZFUiB1c2UgU29ja2V0LklPIG9yIG5neC1zb2NrZXQtaW8uIFZvaWNlIGZsb3cgdXNlcyBvbmx5OlxuICogLSBOYXRpdmUgV2ViU29ja2V0IChXZWJTb2NrZXRWb2ljZUNsaWVudFNlcnZpY2UpIGZvciBzaWduYWxpbmcgKHJvb21fY3JlYXRlZCwgdHJhbnNjcmlwdHMpXG4gKiAtIERhaWx5LmpzIChEYWlseVZvaWNlQ2xpZW50U2VydmljZSkgZm9yIFdlYlJUQyBhdWRpby4gQXVkaW8gZG9lcyBOT1QgZmxvdyBvdmVyIFdlYlNvY2tldC5cbiAqXG4gKiAtIE1haW50YWlucyBjYWxsU3RhdGUsIHN0YXR1c1RleHQsIGR1cmF0aW9uLCBpc01pY011dGVkLCBpc1VzZXJTcGVha2luZywgYXVkaW9MZXZlbHNcbiAqIC0gVXNlcyBXZWJTb2NrZXQgZm9yIHJvb21fY3JlYXRlZCBhbmQgdHJhbnNjcmlwdHMgb25seSAobm8gYXVkaW8pXG4gKiAtIFVzZXMgRGFpbHkuanMgZm9yIGFsbCBhdWRpbywgbWljLCBhbmQgcmVhbC10aW1lIHNwZWFraW5nIGRldGVjdGlvblxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgVm9pY2VBZ2VudFNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGNhbGxTdGF0ZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENhbGxTdGF0ZT4oJ2lkbGUnKTtcbiAgcHJpdmF0ZSBzdGF0dXNUZXh0U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XG4gIHByaXZhdGUgZHVyYXRpb25TdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcwMDowMCcpO1xuICBwcml2YXRlIGlzTWljTXV0ZWRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgaXNVc2VyU3BlYWtpbmdTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgYXVkaW9MZXZlbHNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXJbXT4oW10pO1xuICBwcml2YXRlIHVzZXJUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PFRyYW5zY3JpcHREYXRhPigpO1xuICBwcml2YXRlIGJvdFRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuXG4gIHByaXZhdGUgY2FsbFN0YXJ0VGltZSA9IDA7XG4gIHByaXZhdGUgZHVyYXRpb25JbnRlcnZhbDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjYWxsU3RhdGUkOiBPYnNlcnZhYmxlPENhbGxTdGF0ZT4gPSB0aGlzLmNhbGxTdGF0ZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHN0YXR1c1RleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLnN0YXR1c1RleHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBkdXJhdGlvbiQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuZHVyYXRpb25TdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBpc01pY011dGVkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuaXNNaWNNdXRlZFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGlzVXNlclNwZWFraW5nJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9XG4gICAgdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGF1ZGlvTGV2ZWxzJDogT2JzZXJ2YWJsZTxudW1iZXJbXT4gPSB0aGlzLmF1ZGlvTGV2ZWxzU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgdXNlclRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPFRyYW5zY3JpcHREYXRhPiA9XG4gICAgdGhpcy51c2VyVHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGJvdFRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLmJvdFRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXVkaW9BbmFseXplcjogQXVkaW9BbmFseXplclNlcnZpY2UsXG4gICAgcHJpdmF0ZSB3c0NsaWVudDogV2ViU29ja2V0Vm9pY2VDbGllbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGFpbHlDbGllbnQ6IERhaWx5Vm9pY2VDbGllbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGxhdGZvcm1Ub2tlblJlZnJlc2g6IFBsYXRmb3JtVG9rZW5SZWZyZXNoU2VydmljZSxcbiAgICAvKiogYE9iamVjdGAgbm90IGBvYmplY3RgIOKAlCBuZ2MgbWV0YWRhdGEgY29sbGVjdGlvbiByZWplY3RzIHRoZSBgb2JqZWN0YCB0eXBlIGluIERJIHBhcmFtcy4gKi9cbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgKSB7XG4gICAgLy8gV2F2ZWZvcm0gdmlzdWFsaXphdGlvbiBvbmx5IC0gZG8gTk9UIHVzZSBmb3Igc3BlYWtpbmcgc3RhdGVcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5hdWRpb0FuYWx5emVyLmF1ZGlvTGV2ZWxzJC5zdWJzY3JpYmUoKGxldmVscykgPT5cbiAgICAgICAgdGhpcy5hdWRpb0xldmVsc1N1YmplY3QubmV4dChsZXZlbHMpLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICAvKiogUmVzZXQgdG8gaWRsZSBzdGF0ZSAoZS5nLiB3aGVuIG1vZGFsIG9wZW5zIHNvIHVzZXIgY2FuIGNsaWNrIFN0YXJ0IENhbGwpLiAqL1xuICByZXNldFRvSWRsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jYWxsU3RhdGVTdWJqZWN0LnZhbHVlID09PSAnaWRsZScpIHJldHVybjtcbiAgICB0aGlzLnN0b3BEdXJhdGlvblRpbWVyKCk7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLndzQ2xpZW50LmRpc2Nvbm5lY3QoKTtcbiAgICAvLyBGaXJlLWFuZC1mb3JnZXQ6IERhaWx5IGRpc2Nvbm5lY3QgaXMgYXN5bmM7IGNvbm5lY3QoKSB3aWxsIGF3YWl0IGlmIG5lZWRlZFxuICAgIHZvaWQgdGhpcy5kYWlseUNsaWVudC5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2lkbGUnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJycpO1xuICAgIHRoaXMuZHVyYXRpb25TdWJqZWN0Lm5leHQoJzA6MDAnKTtcbiAgfVxuXG4gIGFzeW5jIGNvbm5lY3QoXG4gICAgYXBpVXJsOiBzdHJpbmcsXG4gICAgdG9rZW46IHN0cmluZyxcbiAgICBib3RJZDogc3RyaW5nLFxuICAgIGNvbnZlcnNhdGlvbklkOiBzdHJpbmcsXG4gICAgYXBpS2V5OiBzdHJpbmcsXG4gICAgZXZlbnRUb2tlbjogc3RyaW5nLFxuICAgIGV2ZW50VXJsOiBzdHJpbmcsXG4gICAgZG9tYWluQXV0aG9yaXR5OiBzdHJpbmcsXG4gICAgdXNlcnNBcGlVcmw/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgIT09ICdpZGxlJykge1xuICAgICAgY29uc29sZS53YXJuKCdDYWxsIGFscmVhZHkgaW4gcHJvZ3Jlc3MnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RpbmcnKTtcbiAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnQ29ubmVjdGluZy4uLicpO1xuXG4gICAgICBsZXQgYWNjZXNzVG9rZW4gPSB0b2tlbjtcbiAgICAgIC8vIEFsaWduIHdpdGggY2hhdCBkcmF3ZXIgdG9rZW4gaGFuZGxpbmc6IGFsd2F5cyBkZWxlZ2F0ZSB0b1xuICAgICAgLy8gUGxhdGZvcm1Ub2tlblJlZnJlc2hTZXJ2aWNlIHdoZW4gd2UgaGF2ZSBhIHVzZXJzQXBpVXJsLCBzbyBpdCBjYW5cbiAgICAgIC8vIGZhbGwgYmFjayB0byBzdG9yZWQgdG9rZW5zIGV2ZW4gaWYgdGhlIGNhbGxlciBwYXNzZWQgYW4gZW1wdHkgdG9rZW4uXG4gICAgICBpZiAodXNlcnNBcGlVcmwgJiYgaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGVuc3VyZWQgPSBhd2FpdCB0aGlzLnBsYXRmb3JtVG9rZW5SZWZyZXNoXG4gICAgICAgICAgICAuZW5zdXJlVmFsaWRBY2Nlc3NUb2tlbih0b2tlbiwgdXNlcnNBcGlVcmwpXG4gICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgLnRvUHJvbWlzZSgpO1xuICAgICAgICAgIGlmIChlbnN1cmVkPy5hY2Nlc3NUb2tlbikge1xuICAgICAgICAgICAgYWNjZXNzVG9rZW4gPSBlbnN1cmVkLmFjY2Vzc1Rva2VuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybignW0hpdmVHcHQgVm9pY2VdIFRva2VuIHJlZnJlc2ggYmVmb3JlIGNvbm5lY3QgZmFpbGVkJywgZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFzZVVybCA9IGFwaVVybC5yZXBsYWNlKC9cXC8kLywgJycpO1xuICAgICAgY29uc3QgcG9zdFVybCA9IGBodHRwczovLzEzNTYtMTAzLTIxMC0zMy0yMzYubmdyb2stZnJlZS5hcHAvYWkvYXNrLXZvaWNlYDtcblxuICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2FjY2Vzc1Rva2VufWAsXG4gICAgICAgICdkb21haW4tYXV0aG9yaXR5JzogZG9tYWluQXV0aG9yaXR5LFxuICAgICAgICAnZXZlbnR0b2tlbic6IGV2ZW50VG9rZW4sXG4gICAgICAgICdldmVudHVybCc6IGV2ZW50VXJsLFxuICAgICAgICAnaGl2ZS1ib3QtaWQnOiBib3RJZCxcbiAgICAgICAgJ3gtYXBpLWtleSc6IGFwaUtleSxcbiAgICAgICAgJ25ncm9rLXNraXAtYnJvd3Nlci13YXJuaW5nJzogJ3RydWUnLFxuICAgICAgfTtcblxuICAgICAgLy8gUE9TVCB0byBnZXQgd3NfdXJsIGZvciBzaWduYWxpbmdcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHBvc3RVcmwsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBib3RfaWQ6IGJvdElkLFxuICAgICAgICAgIGNvbnZlcnNhdGlvbl9pZDogY29udmVyc2F0aW9uSWQsXG4gICAgICAgICAgdm9pY2U6ICdhbGxveScsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghcmVzLm9rKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSFRUUCAke3Jlcy5zdGF0dXN9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCByZXMuanNvbigpO1xuICAgICAgY29uc3Qgd3NVcmwgPSBqc29uPy5ybl93c191cmw7XG4gICAgICBpZiAoIXdzVXJsIHx8IHR5cGVvZiB3c1VybCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB3c191cmwgaW4gcmVzcG9uc2UnKTtcbiAgICAgIH1cblxuICAgICAgLy8gU3Vic2NyaWJlIHRvIHJvb21fY3JlYXRlZCBCRUZPUkUgY29ubmVjdGluZyB0byBhdm9pZCByYWNlXG4gICAgICB0aGlzLndzQ2xpZW50LnJvb21DcmVhdGVkJFxuICAgICAgICAucGlwZSh0YWtlKDEpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoYXN5bmMgKHJvb21VcmwpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5vblJvb21DcmVhdGVkKHJvb21VcmwpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRGFpbHkgam9pbiBmYWlsZWQ6JywgZXJyKTtcbiAgICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdlbmRlZCcpO1xuICAgICAgICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW9uIGZhaWxlZCcpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgLy8gRm9yd2FyZCB0cmFuc2NyaXB0cyBmcm9tIFdlYlNvY2tldFxuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgICAgdGhpcy53c0NsaWVudC51c2VyVHJhbnNjcmlwdCRcbiAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgLnN1YnNjcmliZSgodCkgPT4gdGhpcy51c2VyVHJhbnNjcmlwdFN1YmplY3QubmV4dCh0KSksXG4gICAgICApO1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgICAgdGhpcy53c0NsaWVudC5ib3RUcmFuc2NyaXB0JFxuICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgICAuc3Vic2NyaWJlKCh0KSA9PiB0aGlzLmJvdFRyYW5zY3JpcHRTdWJqZWN0Lm5leHQodCkpLFxuICAgICAgKTtcblxuICAgICAgLy8gQ29ubmVjdCBzaWduYWxpbmcgV2ViU29ja2V0IChubyBhdWRpbyBvdmVyIFdTKVxuICAgICAgdGhpcy53c0NsaWVudC5jb25uZWN0KHdzVXJsKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY29ubmVjdGluZyB2b2ljZSBhZ2VudDonLCBlcnJvcik7XG4gICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICAgIGF3YWl0IHRoaXMuZGlzY29ubmVjdCgpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW9uIGZhaWxlZCcpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBvblJvb21DcmVhdGVkKHJvb21Vcmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIENvbm5lY3QgRGFpbHkuanMgZm9yIFdlYlJUQyBhdWRpb1xuICAgIGF3YWl0IHRoaXMuZGFpbHlDbGllbnQuY29ubmVjdChyb29tVXJsKTtcblxuICAgIC8vIFdhdmVmb3JtOiB1c2UgbG9jYWwgbWljIHN0cmVhbSBmcm9tIERhaWx5IGNsaWVudFxuICAgIHRoaXMuZGFpbHlDbGllbnQubG9jYWxTdHJlYW0kXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKChzKTogcyBpcyBNZWRpYVN0cmVhbSA9PiBzICE9IG51bGwpLFxuICAgICAgICB0YWtlKDEpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoc3RyZWFtKSA9PiB7XG4gICAgICAgIHRoaXMuYXVkaW9BbmFseXplci5zdGFydChzdHJlYW0pO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5kYWlseUNsaWVudC51c2VyU3BlYWtpbmckLnN1YnNjcmliZSgocykgPT5cbiAgICAgICAgdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QubmV4dChzKSxcbiAgICAgICksXG4gICAgKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgY29tYmluZUxhdGVzdChbXG4gICAgICAgIHRoaXMuZGFpbHlDbGllbnQuc3BlYWtpbmckLFxuICAgICAgICB0aGlzLmRhaWx5Q2xpZW50LnVzZXJTcGVha2luZyQsXG4gICAgICBdKS5zdWJzY3JpYmUoKFtib3QsIHVzZXJdKSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWU7XG4gICAgICAgIGlmIChjdXJyZW50ID09PSAnY29ubmVjdGluZycgJiYgIWJvdCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3VycmVudCA9PT0gJ2Nvbm5lY3RpbmcnICYmIGJvdCkge1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgdGhpcy5zdGFydER1cmF0aW9uVGltZXIoKTtcbiAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgndGFsa2luZycpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdsaXN0ZW5pbmcnKTtcbiAgICAgICAgfSBlbHNlIGlmIChib3QpIHtcbiAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgndGFsa2luZycpO1xuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnQgPT09ICd0YWxraW5nJyB8fCBjdXJyZW50ID09PSAnbGlzdGVuaW5nJykge1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLmRhaWx5Q2xpZW50Lm1pY011dGVkJC5zdWJzY3JpYmUoKG11dGVkKSA9PlxuICAgICAgICB0aGlzLmlzTWljTXV0ZWRTdWJqZWN0Lm5leHQobXV0ZWQpLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW5nLi4uJyk7XG4gIH1cblxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RvcER1cmF0aW9uVGltZXIoKTtcbiAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuc3RvcCgpO1xuXG4gICAgLy8gRGFpbHkgZmlyc3QsIHRoZW4gV2ViU29ja2V0XG4gICAgYXdhaXQgdGhpcy5kYWlseUNsaWVudC5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy53c0NsaWVudC5kaXNjb25uZWN0KCk7XG5cbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgfVxuXG4gIHRvZ2dsZU1pYygpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5pc01pY011dGVkU3ViamVjdC52YWx1ZTtcbiAgICB0aGlzLmRhaWx5Q2xpZW50LnNldE11dGVkKCFjdXJyZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnREdXJhdGlvblRpbWVyKCk6IHZvaWQge1xuICAgIGNvbnN0IHVwZGF0ZUR1cmF0aW9uID0gKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY2FsbFN0YXJ0VGltZSA+IDApIHtcbiAgICAgICAgY29uc3QgZWxhcHNlZCA9IE1hdGguZmxvb3IoKERhdGUubm93KCkgLSB0aGlzLmNhbGxTdGFydFRpbWUpIC8gMTAwMCk7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKGVsYXBzZWQgLyA2MCk7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSBlbGFwc2VkICUgNjA7XG4gICAgICAgIHRoaXMuZHVyYXRpb25TdWJqZWN0Lm5leHQoXG4gICAgICAgICAgYCR7bWludXRlc306JHtTdHJpbmcoc2Vjb25kcykucGFkU3RhcnQoMiwgJzAnKX1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH07XG4gICAgdXBkYXRlRHVyYXRpb24oKTtcbiAgICB0aGlzLmR1cmF0aW9uSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCh1cGRhdGVEdXJhdGlvbiwgMTAwMCk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BEdXJhdGlvblRpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmR1cmF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kdXJhdGlvbkludGVydmFsKTtcbiAgICAgIHRoaXMuZHVyYXRpb25JbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICB9XG59XG4iXX0=
208
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvVXNlcnMvcm9oaXR0aGFrdXIvaGl2ZS1ncHQvSGl2ZUFJLVBhY2thZ2VzL0FuZ3VsYXIvcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy92b2ljZS1hZ2VudC9zZXJ2aWNlcy92b2ljZS1hZ2VudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBYSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBRWIsT0FBTyxFQUNQLFlBQVksR0FDYixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pELE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQy9GLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQy9FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7QUFrQnZFLE1BQU0sT0FBTyxpQkFBaUI7SUF5QjVCLFlBQ1UsYUFBbUMsRUFDbkMsUUFBcUMsRUFDckMsV0FBb0MsRUFDcEMsb0JBQWlELEVBQzVCLFVBQWtCO1FBSnZDLGtCQUFhLEdBQWIsYUFBYSxDQUFzQjtRQUNuQyxhQUFRLEdBQVIsUUFBUSxDQUE2QjtRQUNyQyxnQkFBVyxHQUFYLFdBQVcsQ0FBeUI7UUFDcEMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUE2QjtRQUM1QixlQUFVLEdBQVYsVUFBVSxD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TUFBTSxTQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9uRGVzdHJveSwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEJlaGF2aW9yU3ViamVjdCxcbiAgY29tYmluZUxhdGVzdCxcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbiAgU3Vic2NyaXB0aW9uLFxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgUGxhdGZvcm1Ub2tlblJlZnJlc2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvcGxhdGZvcm0tdG9rZW4tcmVmcmVzaC5zZXJ2aWNlJztcbmltcG9ydCB7IEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlIH0gZnJvbSAnLi9hdWRpby1hbmFseXplci5zZXJ2aWNlJztcbmltcG9ydCB7IFdlYlNvY2tldFZvaWNlQ2xpZW50U2VydmljZSB9IGZyb20gJy4vd2Vic29ja2V0LXZvaWNlLWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IERhaWx5Vm9pY2VDbGllbnRTZXJ2aWNlIH0gZnJvbSAnLi9kYWlseS12b2ljZS1jbGllbnQuc2VydmljZSc7XG5cbmV4cG9ydCB0eXBlIENhbGxTdGF0ZSA9XG4gIHwgJ2lkbGUnXG4gIHwgJ2Nvbm5lY3RpbmcnXG4gIHwgJ2Nvbm5lY3RlZCdcbiAgfCAnbGlzdGVuaW5nJ1xuICB8ICd0YWxraW5nJ1xuICB8ICdlbmRlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNjcmlwdERhdGEge1xuICB0ZXh0OiBzdHJpbmc7XG4gIGZpbmFsOiBib29sZWFuO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgVm9pY2VBZ2VudFNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGNhbGxTdGF0ZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENhbGxTdGF0ZT4oJ2lkbGUnKTtcbiAgcHJpdmF0ZSBzdGF0dXNUZXh0U3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XG4gIHByaXZhdGUgZHVyYXRpb25TdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcwMDowMCcpO1xuICBwcml2YXRlIGlzTWljTXV0ZWRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0cnVlKTtcbiAgcHJpdmF0ZSBpc1VzZXJTcGVha2luZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBhdWRpb0xldmVsc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcltdPihbXSk7XG4gIHByaXZhdGUgdXNlclRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8VHJhbnNjcmlwdERhdGE+KCk7XG4gIHByaXZhdGUgYm90VHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG5cbiAgcHJpdmF0ZSBjYWxsU3RhcnRUaW1lID0gMDtcbiAgcHJpdmF0ZSBkdXJhdGlvbkludGVydmFsOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNhbGxTdGF0ZSQgPSB0aGlzLmNhbGxTdGF0ZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHN0YXR1c1RleHQkID0gdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgZHVyYXRpb24kID0gdGhpcy5kdXJhdGlvblN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGlzTWljTXV0ZWQkID0gdGhpcy5pc01pY011dGVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgaXNVc2VyU3BlYWtpbmckID0gdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGF1ZGlvTGV2ZWxzJCA9IHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB1c2VyVHJhbnNjcmlwdCQgPSB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYm90VHJhbnNjcmlwdCQgPSB0aGlzLmJvdFRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXVkaW9BbmFseXplcjogQXVkaW9BbmFseXplclNlcnZpY2UsXG4gICAgcHJpdmF0ZSB3c0NsaWVudDogV2ViU29ja2V0Vm9pY2VDbGllbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGFpbHlDbGllbnQ6IERhaWx5Vm9pY2VDbGllbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGxhdGZvcm1Ub2tlblJlZnJlc2g6IFBsYXRmb3JtVG9rZW5SZWZyZXNoU2VydmljZSxcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMuYXVkaW9BbmFseXplci5hdWRpb0xldmVscyQuc3Vic2NyaWJlKChsZXZlbHMpID0+XG4gICAgICAgIHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0Lm5leHQobGV2ZWxzKSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRlYXIgZG93biB0cmFuc3BvcnRzIGFuZCByZXNldCBVSSBzdGF0ZSBzbyBhIG5ldyBgY29ubmVjdCgpYCBjYW4gcnVuLlxuICAgKiBgY29ubmVjdCgpYCBvbmx5IHByb2NlZWRzIGZyb20gYGlkbGVgOyB1c2UgdGhpcyBhZnRlciBgZW5kZWRgIG9yIHdoZW4gcmVvcGVuaW5nIHRoZSBtb2RhbC5cbiAgICovXG4gIHJlc2V0VG9JZGxlKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcER1cmF0aW9uVGltZXIoKTtcbiAgICB0aGlzLmF1ZGlvQW5hbHl6ZXIuc3RvcCgpO1xuICAgIHRoaXMud3NDbGllbnQuZGlzY29ubmVjdCgpO1xuICAgIHZvaWQgdGhpcy5kYWlseUNsaWVudC5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2lkbGUnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJycpO1xuICAgIHRoaXMuZHVyYXRpb25TdWJqZWN0Lm5leHQoJzAwOjAwJyk7XG4gICAgdGhpcy5pc01pY011dGVkU3ViamVjdC5uZXh0KHRydWUpO1xuICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0Lm5leHQoW10pO1xuICB9XG5cbiAgYXN5bmMgY29ubmVjdChcbiAgICBhcGlVcmw6IHN0cmluZyxcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIGJvdElkOiBzdHJpbmcsXG4gICAgY29udmVyc2F0aW9uSWQ6IHN0cmluZyxcbiAgICBhcGlLZXk6IHN0cmluZyxcbiAgICBldmVudFRva2VuOiBzdHJpbmcsXG4gICAgZXZlbnRVcmw6IHN0cmluZyxcbiAgICBkb21haW5BdXRob3JpdHk6IHN0cmluZyxcbiAgICB1c2Vyc0FwaVVybD86IHN0cmluZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZSAhPT0gJ2lkbGUnKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RpbmcnKTtcbiAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnQ29ubmVjdGluZyB0byBhZ2VudC4uLicpO1xuXG4gICAgICBsZXQgYWNjZXNzVG9rZW4gPSB0b2tlbjtcblxuICAgICAgaWYgKHVzZXJzQXBpVXJsICYmIGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBlbnN1cmVkID0gYXdhaXQgdGhpcy5wbGF0Zm9ybVRva2VuUmVmcmVzaFxuICAgICAgICAgICAgLmVuc3VyZVZhbGlkQWNjZXNzVG9rZW4odG9rZW4sIHVzZXJzQXBpVXJsKVxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgICAgIC50b1Byb21pc2UoKTtcblxuICAgICAgICAgIGlmIChlbnN1cmVkPy5hY2Nlc3NUb2tlbikge1xuICAgICAgICAgICAgYWNjZXNzVG9rZW4gPSBlbnN1cmVkLmFjY2Vzc1Rva2VuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwb3N0VXJsID0gYGh0dHBzOi8vMTM1Ni0xMDMtMjEwLTMzLTIzNi5uZ3Jvay1mcmVlLmFwcC9haS9hc2stdm9pY2VgO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChwb3N0VXJsLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YWNjZXNzVG9rZW59YCxcbiAgICAgICAgICAnZG9tYWluLWF1dGhvcml0eSc6IGRvbWFpbkF1dGhvcml0eSxcbiAgICAgICAgICBldmVudHRva2VuOiBldmVudFRva2VuLFxuICAgICAgICAgIGV2ZW50dXJsOiBldmVudFVybCxcbiAgICAgICAgICAnaGl2ZS1ib3QtaWQnOiBib3RJZCxcbiAgICAgICAgICAneC1hcGkta2V5JzogYXBpS2V5LFxuICAgICAgICB9LFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgYm90X2lkOiBib3RJZCxcbiAgICAgICAgICBjb252ZXJzYXRpb25faWQ6IGNvbnZlcnNhdGlvbklkLFxuICAgICAgICAgIHZvaWNlOiAnYWxsb3knLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBqc29uID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGNvbnN0IHdzVXJsID0ganNvbj8ucm5fd3NfdXJsO1xuXG4gICAgICB0aGlzLndzQ2xpZW50LnJvb21DcmVhdGVkJFxuICAgICAgICAucGlwZSh0YWtlKDEpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoYXN5bmMgKHJvb21VcmwpID0+IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLm9uUm9vbUNyZWF0ZWQocm9vbVVybCk7XG4gICAgICAgIH0pO1xuXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgICB0aGlzLndzQ2xpZW50LnVzZXJUcmFuc2NyaXB0JC5zdWJzY3JpYmUoKHQpID0+XG4gICAgICAgICAgdGhpcy51c2VyVHJhbnNjcmlwdFN1YmplY3QubmV4dCh0KSxcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICAgIHRoaXMud3NDbGllbnQuYm90VHJhbnNjcmlwdCQuc3Vic2NyaWJlKCh0KSA9PlxuICAgICAgICAgIHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QubmV4dCh0KSxcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMud3NDbGllbnQuY29ubmVjdCh3c1VybCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBvblJvb21DcmVhdGVkKHJvb21Vcmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZGFpbHlDbGllbnQuY29ubmVjdChyb29tVXJsKTtcblxuICAgIC8vIPCflLQgU3RhcnQgTVVURURcbiAgICB0aGlzLmRhaWx5Q2xpZW50LnNldE11dGVkKHRydWUpO1xuICAgIHRoaXMuaXNNaWNNdXRlZFN1YmplY3QubmV4dCh0cnVlKTtcblxuICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnTGlzdGVuaW5nIHRvIGFnZW50Li4uJyk7XG5cbiAgICAvLyDinIUgRW5hYmxlIG1pYyBvbiBGSVJTVCBib3Qgc3BlZWNoXG4gICAgbGV0IGhhbmRsZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuZGFpbHlDbGllbnQuc3BlYWtpbmckLnBpcGUoZmlsdGVyKEJvb2xlYW4pLCB0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgaWYgKGhhbmRsZWQpIHJldHVybjtcbiAgICAgIGhhbmRsZWQgPSB0cnVlO1xuXG4gICAgICBjb25zb2xlLmxvZygnW1ZvaWNlRmxvd10gRmlyc3QgYm90IHJlc3BvbnNlIOKGkiBlbmFibGluZyBtaWMnKTtcblxuICAgICAgdGhpcy5kYWlseUNsaWVudC5zZXRNdXRlZChmYWxzZSk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ1lvdSBjYW4gc3BlYWsgbm93Jyk7XG4gICAgfSk7XG5cbiAgICAvLyDim5HvuI8gRmFsbGJhY2sgKGlmIGJvdCBmYWlscylcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghaGFuZGxlZCkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tWb2ljZUZsb3ddIEZhbGxiYWNrIOKGkiBlbmFibGluZyBtaWMnKTtcbiAgICAgICAgdGhpcy5kYWlseUNsaWVudC5zZXRNdXRlZChmYWxzZSk7XG4gICAgICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnWW91IGNhbiBzcGVhayBub3cnKTtcbiAgICAgIH1cbiAgICB9LCA4MDAwKTtcblxuICAgIC8vIHJlc3Qgc2FtZVxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICBjb21iaW5lTGF0ZXN0KFtcbiAgICAgICAgdGhpcy5kYWlseUNsaWVudC5zcGVha2luZyQsXG4gICAgICAgIHRoaXMuZGFpbHlDbGllbnQudXNlclNwZWFraW5nJCxcbiAgICAgIF0pLnN1YnNjcmliZSgoW2JvdCwgdXNlcl0pID0+IHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY2FsbFN0YXRlU3ViamVjdC52YWx1ZTtcblxuICAgICAgICBpZiAoY3VycmVudCA9PT0gJ2Nvbm5lY3RpbmcnICYmIGJvdCkge1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgdGhpcy5zdGFydER1cmF0aW9uVGltZXIoKTtcbiAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgndGFsa2luZycpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2xpc3RlbmluZycpO1xuICAgICAgICB9IGVsc2UgaWYgKGJvdCkge1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCd0YWxraW5nJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RlZCcpO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnN0b3BEdXJhdGlvblRpbWVyKCk7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcblxuICAgIGF3YWl0IHRoaXMuZGFpbHlDbGllbnQuZGlzY29ubmVjdCgpO1xuICAgIHRoaXMud3NDbGllbnQuZGlzY29ubmVjdCgpO1xuXG4gICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDYWxsIEVuZGVkJyk7XG4gIH1cblxuICB0b2dnbGVNaWMoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuaXNNaWNNdXRlZFN1YmplY3QudmFsdWU7XG4gICAgdGhpcy5kYWlseUNsaWVudC5zZXRNdXRlZCghY3VycmVudCk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0RHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICB0aGlzLmR1cmF0aW9uSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBjb25zdCBlbGFwc2VkID0gTWF0aC5mbG9vcigoRGF0ZS5ub3coKSAtIHRoaXMuY2FsbFN0YXJ0VGltZSkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IG0gPSBNYXRoLmZsb29yKGVsYXBzZWQgLyA2MCk7XG4gICAgICBjb25zdCBzID0gZWxhcHNlZCAlIDYwO1xuICAgICAgdGhpcy5kdXJhdGlvblN1YmplY3QubmV4dChgJHttfToke1N0cmluZyhzKS5wYWRTdGFydCgyLCAnMCcpfWApO1xuICAgIH0sIDEwMDApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wRHVyYXRpb25UaW1lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kdXJhdGlvbkludGVydmFsKSBjbGVhckludGVydmFsKHRoaXMuZHVyYXRpb25JbnRlcnZhbCk7XG4gIH1cbn1cbiJdfQ==