@techextensor/tab-core-utility 2.2.199 → 2.2.200
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/esm2022/index.mjs +4 -1
- package/esm2022/lib/tab-core-utility/app/constants/common.mjs +2 -1
- package/esm2022/lib/tab-core-utility/app/interfaces/notification.interface.mjs +50 -0
- package/esm2022/lib/tab-core-utility/core/service/notification/notification-inbox.service.mjs +269 -0
- package/esm2022/lib/tab-core-utility/core/service/notification/notification-websocket.service.mjs +209 -0
- package/esm2022/lib/tab-core-utility/core/service/signalr/operation-tracker.service.mjs +23 -6
- package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs +53 -7
- package/esm2022/lib/tab-core-utility/core/service/signalr/signalr.service.mjs +21 -5
- package/index.d.ts +3 -0
- package/lib/tab-core-utility/app/constants/common.d.ts +2 -0
- package/lib/tab-core-utility/app/interfaces/notification.interface.d.ts +154 -0
- package/lib/tab-core-utility/core/service/notification/notification-inbox.service.d.ts +80 -0
- package/lib/tab-core-utility/core/service/notification/notification-websocket.service.d.ts +56 -0
- package/lib/tab-core-utility/core/service/signalr/operation-tracker.service.d.ts +9 -1
- package/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.d.ts +11 -0
- package/lib/tab-core-utility/core/service/signalr/signalr.service.d.ts +15 -3
- package/package.json +1 -1
package/esm2022/lib/tab-core-utility/core/service/notification/notification-websocket.service.mjs
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { Injectable, signal } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import { webSocket } from 'rxjs/webSocket';
|
|
4
|
+
import { Common } from '../../../app/constants/common';
|
|
5
|
+
import { NOTIFICATION_WS_CONFIG, WS_CONNECTION_STATE, WS_MESSAGE_TYPE, } from '../../../app/interfaces/notification.interface';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/**
|
|
8
|
+
* Low-level Notification WebSocket transport.
|
|
9
|
+
*
|
|
10
|
+
* Pure — no storage / auth coupling. The caller (SDK facade or app layer)
|
|
11
|
+
* supplies all auth identifiers via `connect(params)`.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the SignalR infrastructure pattern:
|
|
14
|
+
* - connect() is idempotent, dedupes concurrent calls, tears down stale sockets
|
|
15
|
+
* - disconnect() flips an explicit-disconnected flag so retries don't revive
|
|
16
|
+
* - state exposed as Angular signal
|
|
17
|
+
* - inbound messages forwarded on `messages$` for higher-level service to route
|
|
18
|
+
*
|
|
19
|
+
* Internal use — consumers should use `NotificationInboxService` instead.
|
|
20
|
+
*/
|
|
21
|
+
export class NotificationWebSocketService {
|
|
22
|
+
constructor() {
|
|
23
|
+
this.socket = null;
|
|
24
|
+
this.socketSub = null;
|
|
25
|
+
// In-flight connect promise — used to dedupe concurrent connect() calls
|
|
26
|
+
this.connectingPromise = null;
|
|
27
|
+
// Set true on explicit disconnect() so scheduled retries don't resurrect the connection
|
|
28
|
+
this.explicitlyDisconnected = false;
|
|
29
|
+
// Last connect params — kept so reconnect can rebuild the URL without the caller
|
|
30
|
+
// re-supplying them. Cleared on disconnect().
|
|
31
|
+
this.lastParams = null;
|
|
32
|
+
// Reconnect attempt counter (resets on successful connect)
|
|
33
|
+
this.reconnectAttempt = 0;
|
|
34
|
+
this.reconnectTimer = null;
|
|
35
|
+
// Connection state as Angular signal — for UI indicators / route resolvers
|
|
36
|
+
this.connectionState = signal(WS_CONNECTION_STATE.DISCONNECTED);
|
|
37
|
+
// Inbound message stream — NotificationInboxService subscribes and routes per type
|
|
38
|
+
this.messages$ = new Subject();
|
|
39
|
+
}
|
|
40
|
+
// ----------- public API -----------
|
|
41
|
+
/**
|
|
42
|
+
* Establish the WebSocket connection.
|
|
43
|
+
*
|
|
44
|
+
* Idempotent — if already OPEN, resolves immediately.
|
|
45
|
+
* In-flight calls are de-duplicated.
|
|
46
|
+
* Any stale (non-OPEN) socket is torn down before rebuild.
|
|
47
|
+
*/
|
|
48
|
+
async connect(params) {
|
|
49
|
+
this.explicitlyDisconnected = false;
|
|
50
|
+
this.lastParams = params;
|
|
51
|
+
if (this.connectionState() === WS_CONNECTION_STATE.CONNECTED) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (this.connectingPromise) {
|
|
55
|
+
return this.connectingPromise;
|
|
56
|
+
}
|
|
57
|
+
if (this.socket) {
|
|
58
|
+
try {
|
|
59
|
+
this.socket.complete();
|
|
60
|
+
}
|
|
61
|
+
catch { /* ignore */ }
|
|
62
|
+
this.socket = null;
|
|
63
|
+
this.socketSub?.unsubscribe();
|
|
64
|
+
this.socketSub = null;
|
|
65
|
+
}
|
|
66
|
+
this.connectingPromise = this.doConnect(params);
|
|
67
|
+
try {
|
|
68
|
+
await this.connectingPromise;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
this.connectingPromise = null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async doConnect(params) {
|
|
75
|
+
const baseUrl = Common.notificationWebSocketUrl;
|
|
76
|
+
if (!baseUrl) {
|
|
77
|
+
this.connectionState.set(WS_CONNECTION_STATE.DISCONNECTED);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!params.userId) {
|
|
81
|
+
console.warn('[NotificationWS] No userId provided — skipping connect');
|
|
82
|
+
this.connectionState.set(WS_CONNECTION_STATE.FAILED);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// BE doc: ws://host/ws?userId=...&appId=...&tenantId=...
|
|
86
|
+
const url = `${baseUrl}?userId=${encodeURIComponent(params.userId)}` +
|
|
87
|
+
(params.appId ? `&appId=${encodeURIComponent(params.appId)}` : '') +
|
|
88
|
+
(params.tenantId ? `&tenantId=${encodeURIComponent(params.tenantId)}` : '');
|
|
89
|
+
this.connectionState.set(WS_CONNECTION_STATE.CONNECTING);
|
|
90
|
+
return new Promise((resolve) => {
|
|
91
|
+
this.socket = webSocket({
|
|
92
|
+
url,
|
|
93
|
+
openObserver: {
|
|
94
|
+
next: () => {
|
|
95
|
+
this.connectionState.set(WS_CONNECTION_STATE.CONNECTED);
|
|
96
|
+
this.reconnectAttempt = 0;
|
|
97
|
+
resolve();
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
closeObserver: {
|
|
101
|
+
next: () => {
|
|
102
|
+
if (this.connectionState() !== WS_CONNECTION_STATE.CLOSED) {
|
|
103
|
+
this.connectionState.set(WS_CONNECTION_STATE.DISCONNECTED);
|
|
104
|
+
}
|
|
105
|
+
this.scheduleReconnect();
|
|
106
|
+
resolve();
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
this.socketSub = this.socket.subscribe({
|
|
111
|
+
next: (msg) => this.handleIncoming(msg),
|
|
112
|
+
error: (err) => {
|
|
113
|
+
console.error('[NotificationWS] Socket error:', err);
|
|
114
|
+
this.connectionState.set(WS_CONNECTION_STATE.FAILED);
|
|
115
|
+
this.scheduleReconnect();
|
|
116
|
+
resolve();
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Send a message over the socket. Silently no-ops if not connected.
|
|
123
|
+
*/
|
|
124
|
+
send(message) {
|
|
125
|
+
if (!this.socket || this.connectionState() !== WS_CONNECTION_STATE.CONNECTED) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
this.socket.next(message);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error('[NotificationWS] Failed to send message:', error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Tear down the socket.
|
|
137
|
+
*
|
|
138
|
+
* Sets explicitlyDisconnected so any pending retry timers become no-ops,
|
|
139
|
+
* then closes the socket and clears state.
|
|
140
|
+
*/
|
|
141
|
+
async disconnect() {
|
|
142
|
+
this.explicitlyDisconnected = true;
|
|
143
|
+
this.connectingPromise = null;
|
|
144
|
+
this.lastParams = null;
|
|
145
|
+
if (this.reconnectTimer) {
|
|
146
|
+
clearTimeout(this.reconnectTimer);
|
|
147
|
+
this.reconnectTimer = null;
|
|
148
|
+
}
|
|
149
|
+
if (this.socket) {
|
|
150
|
+
try {
|
|
151
|
+
this.socket.complete();
|
|
152
|
+
}
|
|
153
|
+
catch { /* ignore */ }
|
|
154
|
+
this.socket = null;
|
|
155
|
+
}
|
|
156
|
+
this.socketSub?.unsubscribe();
|
|
157
|
+
this.socketSub = null;
|
|
158
|
+
this.reconnectAttempt = 0;
|
|
159
|
+
this.connectionState.set(WS_CONNECTION_STATE.CLOSED);
|
|
160
|
+
}
|
|
161
|
+
// ----------- internal -----------
|
|
162
|
+
handleIncoming(message) {
|
|
163
|
+
if (!message || typeof message !== 'object')
|
|
164
|
+
return;
|
|
165
|
+
// Heartbeat: server pings every ~30s; we MUST reply or BE will close the socket.
|
|
166
|
+
if (message.type === WS_MESSAGE_TYPE.HEARTBEAT) {
|
|
167
|
+
this.send({ type: WS_MESSAGE_TYPE.HEARTBEAT });
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (message.type === WS_MESSAGE_TYPE.CONNECTION_ESTABLISHED) {
|
|
171
|
+
this.connectionState.set(WS_CONNECTION_STATE.CONNECTED);
|
|
172
|
+
}
|
|
173
|
+
if (message.type === WS_MESSAGE_TYPE.ERROR) {
|
|
174
|
+
console.warn('[NotificationWS] Server error:', message.error);
|
|
175
|
+
}
|
|
176
|
+
this.messages$.next(message);
|
|
177
|
+
}
|
|
178
|
+
scheduleReconnect() {
|
|
179
|
+
if (this.explicitlyDisconnected)
|
|
180
|
+
return;
|
|
181
|
+
if (this.reconnectTimer)
|
|
182
|
+
return;
|
|
183
|
+
if (!this.lastParams)
|
|
184
|
+
return; // can't reconnect without params
|
|
185
|
+
const delays = NOTIFICATION_WS_CONFIG.RECONNECT_DELAYS_MS;
|
|
186
|
+
const delay = delays[Math.min(this.reconnectAttempt, delays.length - 1)];
|
|
187
|
+
this.reconnectAttempt++;
|
|
188
|
+
this.connectionState.set(WS_CONNECTION_STATE.RECONNECTING);
|
|
189
|
+
this.reconnectTimer = setTimeout(() => {
|
|
190
|
+
this.reconnectTimer = null;
|
|
191
|
+
if (!this.explicitlyDisconnected && this.lastParams) {
|
|
192
|
+
this.connect(this.lastParams);
|
|
193
|
+
}
|
|
194
|
+
}, delay);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Snapshot of current connection state — for debugging.
|
|
198
|
+
*/
|
|
199
|
+
isConnected() {
|
|
200
|
+
return this.connectionState() === WS_CONNECTION_STATE.CONNECTED;
|
|
201
|
+
}
|
|
202
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
203
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, providedIn: 'root' }); }
|
|
204
|
+
}
|
|
205
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, decorators: [{
|
|
206
|
+
type: Injectable,
|
|
207
|
+
args: [{ providedIn: 'root' }]
|
|
208
|
+
}] });
|
|
209
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLXdlYnNvY2tldC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL25vdGlmaWNhdGlvbi9ub3RpZmljYXRpb24td2Vic29ja2V0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdkQsT0FBTyxFQUNMLHNCQUFzQixFQUV0QixtQkFBbUIsRUFDbkIsZUFBZSxHQUVoQixNQUFNLGdEQUFnRCxDQUFDOztBQUV4RDs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsTUFBTSxPQUFPLDRCQUE0QjtJQUR6QztRQUVVLFdBQU0sR0FBaUMsSUFBSSxDQUFDO1FBQzVDLGNBQVMsR0FBd0IsSUFBSSxDQUFDO1FBRTlDLHdFQUF3RTtRQUNoRSxzQkFBaUIsR0FBeUIsSUFBSSxDQUFDO1FBRXZELHdGQUF3RjtRQUNoRiwyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFFdkMsaUZBQWlGO1FBQ2pGLDhDQUE4QztRQUN0QyxlQUFVLEdBQThDLElBQUksQ0FBQztRQUVyRSwyREFBMkQ7UUFDbkQscUJBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLG1CQUFjLEdBQXlDLElBQUksQ0FBQztRQUVwRSwyRUFBMkU7UUFDbEUsb0JBQWUsR0FBRyxNQUFNLENBQW9CLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXZGLG1GQUFtRjtRQUMxRSxjQUFTLEdBQUcsSUFBSSxP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QUNwRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ1osQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLGVBQWUsRUFBRSxLQUFLLG1CQUFtQixDQUFDLFNBQVMsQ0FBQztJQUNsRSxDQUFDOytHQXpNVSw0QkFBNEI7bUhBQTVCLDRCQUE0QixjQURmLE1BQU07OzRGQUNuQiw0QkFBNEI7a0JBRHhDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyB3ZWJTb2NrZXQsIFdlYlNvY2tldFN1YmplY3QgfSBmcm9tICdyeGpzL3dlYlNvY2tldCc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBOT1RJRklDQVRJT05fV1NfQ09ORklHLFxyXG4gIE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMsXHJcbiAgV1NfQ09OTkVDVElPTl9TVEFURSxcclxuICBXU19NRVNTQUdFX1RZUEUsXHJcbiAgV3NDb25uZWN0aW9uU3RhdGUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvbm90aWZpY2F0aW9uLmludGVyZmFjZSc7XHJcblxyXG4vKipcclxuICogTG93LWxldmVsIE5vdGlmaWNhdGlvbiBXZWJTb2NrZXQgdHJhbnNwb3J0LlxyXG4gKlxyXG4gKiBQdXJlIOKAlCBubyBzdG9yYWdlIC8gYXV0aCBjb3VwbGluZy4gVGhlIGNhbGxlciAoU0RLIGZhY2FkZSBvciBhcHAgbGF5ZXIpXHJcbiAqIHN1cHBsaWVzIGFsbCBhdXRoIGlkZW50aWZpZXJzIHZpYSBgY29ubmVjdChwYXJhbXMpYC5cclxuICpcclxuICogTWlycm9ycyB0aGUgU2lnbmFsUiBpbmZyYXN0cnVjdHVyZSBwYXR0ZXJuOlxyXG4gKiAgLSBjb25uZWN0KCkgaXMgaWRlbXBvdGVudCwgZGVkdXBlcyBjb25jdXJyZW50IGNhbGxzLCB0ZWFycyBkb3duIHN0YWxlIHNvY2tldHNcclxuICogIC0gZGlzY29ubmVjdCgpIGZsaXBzIGFuIGV4cGxpY2l0LWRpc2Nvbm5lY3RlZCBmbGFnIHNvIHJldHJpZXMgZG9uJ3QgcmV2aXZlXHJcbiAqICAtIHN0YXRlIGV4cG9zZWQgYXMgQW5ndWxhciBzaWduYWxcclxuICogIC0gaW5ib3VuZCBtZXNzYWdlcyBmb3J3YXJkZWQgb24gYG1lc3NhZ2VzJGAgZm9yIGhpZ2hlci1sZXZlbCBzZXJ2aWNlIHRvIHJvdXRlXHJcbiAqXHJcbiAqIEludGVybmFsIHVzZSDigJQgY29uc3VtZXJzIHNob3VsZCB1c2UgYE5vdGlmaWNhdGlvbkluYm94U2VydmljZWAgaW5zdGVhZC5cclxuICovXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25XZWJTb2NrZXRTZXJ2aWNlIHtcclxuICBwcml2YXRlIHNvY2tldDogV2ViU29ja2V0U3ViamVjdDxhbnk+IHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBzb2NrZXRTdWI6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBJbi1mbGlnaHQgY29ubmVjdCBwcm9taXNlIOKAlCB1c2VkIHRvIGRlZHVwZSBjb25jdXJyZW50IGNvbm5lY3QoKSBjYWxsc1xyXG4gIHByaXZhdGUgY29ubmVjdGluZ1Byb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gU2V0IHRydWUgb24gZXhwbGljaXQgZGlzY29ubmVjdCgpIHNvIHNjaGVkdWxlZCByZXRyaWVzIGRvbid0IHJlc3VycmVjdCB0aGUgY29ubmVjdGlvblxyXG4gIHByaXZhdGUgZXhwbGljaXRseURpc2Nvbm5lY3RlZCA9IGZhbHNlO1xyXG5cclxuICAvLyBMYXN0IGNvbm5lY3QgcGFyYW1zIOKAlCBrZXB0IHNvIHJlY29ubmVjdCBjYW4gcmVidWlsZCB0aGUgVVJMIHdpdGhvdXQgdGhlIGNhbGxlclxyXG4gIC8vIHJlLXN1cHBseWluZyB0aGVtLiBDbGVhcmVkIG9uIGRpc2Nvbm5lY3QoKS5cclxuICBwcml2YXRlIGxhc3RQYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gUmVjb25uZWN0IGF0dGVtcHQgY291bnRlciAocmVzZXRzIG9uIHN1Y2Nlc3NmdWwgY29ubmVjdClcclxuICBwcml2YXRlIHJlY29ubmVjdEF0dGVtcHQgPSAwO1xyXG4gIHByaXZhdGUgcmVjb25uZWN0VGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIENvbm5lY3Rpb24gc3RhdGUgYXMgQW5ndWxhciBzaWduYWwg4oCUIGZvciBVSSBpbmRpY2F0b3JzIC8gcm91dGUgcmVzb2x2ZXJzXHJcbiAgcmVhZG9ubHkgY29ubmVjdGlvblN0YXRlID0gc2lnbmFsPFdzQ29ubmVjdGlvblN0YXRlPihXU19DT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gIC8vIEluYm91bmQgbWVzc2FnZSBzdHJlYW0g4oCUIE5vdGlmaWNhdGlvbkluYm94U2VydmljZSBzdWJzY3JpYmVzIGFuZCByb3V0ZXMgcGVyIHR5cGVcclxuICByZWFkb25seSBtZXNzYWdlcyQgPSBuZXcgU3ViamVjdDxhbnk+KCk7XHJcblxyXG4gIC8vIC0tLS0tLS0tLS0tIHB1YmxpYyBBUEkgLS0tLS0tLS0tLS1cclxuXHJcbiAgLyoqXHJcbiAgICogRXN0YWJsaXNoIHRoZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cclxuICAgKlxyXG4gICAqIElkZW1wb3RlbnQg4oCUIGlmIGFscmVhZHkgT1BFTiwgcmVzb2x2ZXMgaW1tZWRpYXRlbHkuXHJcbiAgICogSW4tZmxpZ2h0IGNhbGxzIGFyZSBkZS1kdXBsaWNhdGVkLlxyXG4gICAqIEFueSBzdGFsZSAobm9uLU9QRU4pIHNvY2tldCBpcyB0b3JuIGRvd24gYmVmb3JlIHJlYnVpbGQuXHJcbiAgICovXHJcbiAgYXN5bmMgY29ubmVjdChwYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0gcGFyYW1zO1xyXG5cclxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY29ubmVjdGluZ1Byb21pc2UpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGluZ1Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc29ja2V0KSB7XHJcbiAgICAgIHRyeSB7IHRoaXMuc29ja2V0LmNvbXBsZXRlKCk7IH0gY2F0Y2ggeyAvKiBpZ25vcmUgKi8gfVxyXG4gICAgICB0aGlzLnNvY2tldCA9IG51bGw7XHJcbiAgICAgIHRoaXMuc29ja2V0U3ViPy51bnN1YnNjcmliZSgpO1xyXG4gICAgICB0aGlzLnNvY2tldFN1YiA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IHRoaXMuZG9Db25uZWN0KHBhcmFtcyk7XHJcbiAgICB0cnkge1xyXG4gICAgICBhd2FpdCB0aGlzLmNvbm5lY3RpbmdQcm9taXNlO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRvQ29ubmVjdChwYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGJhc2VVcmwgPSBDb21tb24ubm90aWZpY2F0aW9uV2ViU29ja2V0VXJsO1xyXG4gICAgaWYgKCFiYXNlVXJsKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChXU19DT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXBhcmFtcy51c2VySWQpIHtcclxuICAgICAgY29uc29sZS53YXJuKCdbTm90aWZpY2F0aW9uV1NdIE5vIHVzZXJJZCBwcm92aWRlZCDigJQgc2tpcHBpbmcgY29ubmVjdCcpO1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQkUgZG9jOiB3czovL2hvc3Qvd3M/dXNlcklkPS4uLiZhcHBJZD0uLi4mdGVuYW50SWQ9Li4uXHJcbiAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfT91c2VySWQ9JHtlbmNvZGVVUklDb21wb25lbnQocGFyYW1zLnVzZXJJZCl9YCArXHJcbiAgICAgIChwYXJhbXMuYXBwSWQgPyBgJmFwcElkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtcy5hcHBJZCl9YCA6ICcnKSArXHJcbiAgICAgIChwYXJhbXMudGVuYW50SWQgPyBgJnRlbmFudElkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtcy50ZW5hbnRJZCl9YCA6ICcnKTtcclxuXHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcclxuICAgICAgdGhpcy5zb2NrZXQgPSB3ZWJTb2NrZXQ8YW55Pih7XHJcbiAgICAgICAgdXJsLFxyXG4gICAgICAgIG9wZW5PYnNlcnZlcjoge1xyXG4gICAgICAgICAgbmV4dDogKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdEF0dGVtcHQgPSAwO1xyXG4gICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY2xvc2VPYnNlcnZlcjoge1xyXG4gICAgICAgICAgbmV4dDogKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUoKSAhPT0gV1NfQ09OTkVDVElPTl9TVEFURS5DTE9TRUQpIHtcclxuICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVSZWNvbm5lY3QoKTtcclxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHRoaXMuc29ja2V0U3ViID0gdGhpcy5zb2NrZXQuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0OiAobXNnKSA9PiB0aGlzLmhhbmRsZUluY29taW5nKG1zZyksXHJcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tOb3RpZmljYXRpb25XU10gU29ja2V0IGVycm9yOicsIGVycik7XHJcbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG4gICAgICAgICAgdGhpcy5zY2hlZHVsZVJlY29ubmVjdCgpO1xyXG4gICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZW5kIGEgbWVzc2FnZSBvdmVyIHRoZSBzb2NrZXQuIFNpbGVudGx5IG5vLW9wcyBpZiBub3QgY29ubmVjdGVkLlxyXG4gICAqL1xyXG4gIHNlbmQobWVzc2FnZTogUmVjb3JkPHN0cmluZywgYW55Pik6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNvY2tldCB8fCB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpICE9PSBXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLnNvY2tldC5uZXh0KG1lc3NhZ2UpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignW05vdGlmaWNhdGlvbldTXSBGYWlsZWQgdG8gc2VuZCBtZXNzYWdlOicsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRlYXIgZG93biB0aGUgc29ja2V0LlxyXG4gICAqXHJcbiAgICogU2V0cyBleHBsaWNpdGx5RGlzY29ubmVjdGVkIHNvIGFueSBwZW5kaW5nIHJldHJ5IHRpbWVycyBiZWNvbWUgbm8tb3BzLFxyXG4gICAqIHRoZW4gY2xvc2VzIHRoZSBzb2NrZXQgYW5kIGNsZWFycyBzdGF0ZS5cclxuICAgKi9cclxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkID0gdHJ1ZTtcclxuICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSBudWxsO1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0gbnVsbDtcclxuXHJcbiAgICBpZiAodGhpcy5yZWNvbm5lY3RUaW1lcikge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5yZWNvbm5lY3RUaW1lcik7XHJcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNvY2tldCkge1xyXG4gICAgICB0cnkgeyB0aGlzLnNvY2tldC5jb21wbGV0ZSgpOyB9IGNhdGNoIHsgLyogaWdub3JlICovIH1cclxuICAgICAgdGhpcy5zb2NrZXQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc29ja2V0U3ViPy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5zb2NrZXRTdWIgPSBudWxsO1xyXG5cclxuICAgIHRoaXMucmVjb25uZWN0QXR0ZW1wdCA9IDA7XHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DTE9TRUQpO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0gaW50ZXJuYWwgLS0tLS0tLS0tLS1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVJbmNvbWluZyhtZXNzYWdlOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICghbWVzc2FnZSB8fCB0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcpIHJldHVybjtcclxuXHJcbiAgICAvLyBIZWFydGJlYXQ6IHNlcnZlciBwaW5ncyBldmVyeSB+MzBzOyB3ZSBNVVNUIHJlcGx5IG9yIEJFIHdpbGwgY2xvc2UgdGhlIHNvY2tldC5cclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFdTX01FU1NBR0VfVFlQRS5IRUFSVEJFQVQpIHtcclxuICAgICAgdGhpcy5zZW5kKHsgdHlwZTogV1NfTUVTU0FHRV9UWVBFLkhFQVJUQkVBVCB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFdTX01FU1NBR0VfVFlQRS5DT05ORUNUSU9OX0VTVEFCTElTSEVEKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gV1NfTUVTU0FHRV9UWVBFLkVSUk9SKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybignW05vdGlmaWNhdGlvbldTXSBTZXJ2ZXIgZXJyb3I6JywgbWVzc2FnZS5lcnJvcik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2NoZWR1bGVSZWNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkKSByZXR1cm47XHJcbiAgICBpZiAodGhpcy5yZWNvbm5lY3RUaW1lcikgcmV0dXJuO1xyXG4gICAgaWYgKCF0aGlzLmxhc3RQYXJhbXMpIHJldHVybjsgLy8gY2FuJ3QgcmVjb25uZWN0IHdpdGhvdXQgcGFyYW1zXHJcblxyXG4gICAgY29uc3QgZGVsYXlzID0gTk9USUZJQ0FUSU9OX1dTX0NPTkZJRy5SRUNPTk5FQ1RfREVMQVlTX01TO1xyXG4gICAgY29uc3QgZGVsYXkgPSBkZWxheXNbTWF0aC5taW4odGhpcy5yZWNvbm5lY3RBdHRlbXB0LCBkZWxheXMubGVuZ3RoIC0gMSldO1xyXG4gICAgdGhpcy5yZWNvbm5lY3RBdHRlbXB0Kys7XHJcblxyXG4gICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KFdTX0NPTk5FQ1RJT05fU1RBVEUuUkVDT05ORUNUSU5HKTtcclxuXHJcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBudWxsO1xyXG4gICAgICBpZiAoIXRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCAmJiB0aGlzLmxhc3RQYXJhbXMpIHtcclxuICAgICAgICB0aGlzLmNvbm5lY3QodGhpcy5sYXN0UGFyYW1zKTtcclxuICAgICAgfVxyXG4gICAgfSwgZGVsYXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU25hcHNob3Qgb2YgY3VycmVudCBjb25uZWN0aW9uIHN0YXRlIOKAlCBmb3IgZGVidWdnaW5nLlxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblN0YXRlKCkgPT09IFdTX0NPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEO1xyXG4gIH1cclxufVxyXG4iXX0=
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
|
-
import { Subject, throwError, TimeoutError } from 'rxjs';
|
|
3
|
-
import { filter, take, timeout, catchError } from 'rxjs/operators';
|
|
2
|
+
import { merge, Subject, throwError, TimeoutError } from 'rxjs';
|
|
3
|
+
import { filter, take, timeout, catchError, switchMap } from 'rxjs/operators';
|
|
4
4
|
import { SIGNALR_CONFIG, } from '../../../app/interfaces/signalr.interface';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
/**
|
|
@@ -14,6 +14,8 @@ export class OperationTrackerService {
|
|
|
14
14
|
this.pendingOperations = new Map();
|
|
15
15
|
// Observable for completed operations
|
|
16
16
|
this.operationCompleted$ = new Subject();
|
|
17
|
+
// Cancellation channel — emitted by cancelAll() to error any open waitForOperation observers
|
|
18
|
+
this.cancellation$ = new Subject();
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
21
|
* Register an async operation for tracking
|
|
@@ -29,7 +31,8 @@ export class OperationTrackerService {
|
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
33
|
* Wait for operation to complete via SignalR notification
|
|
32
|
-
* Returns Observable that emits when notification with matching correlationId is received
|
|
34
|
+
* Returns Observable that emits when notification with matching correlationId is received,
|
|
35
|
+
* or errors if cancelAll() is invoked (e.g. on disconnect / signOut).
|
|
33
36
|
*/
|
|
34
37
|
waitForOperation(correlationId, timeoutMs = SIGNALR_CONFIG.DEFAULT_TIMEOUT) {
|
|
35
38
|
// Auto-register so handleNotification can match it
|
|
@@ -40,8 +43,10 @@ export class OperationTrackerService {
|
|
|
40
43
|
timeout: timeoutMs
|
|
41
44
|
});
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
const completed$ = this.operationCompleted$.pipe(filter((notification) => notification.correlationId === correlationId), take(1));
|
|
47
|
+
const cancelled$ = this.cancellation$.pipe(take(1), switchMap((reason) => throwError(() => new Error(`SignalR operation cancelled: ${reason}`))));
|
|
48
|
+
return merge(completed$, cancelled$).pipe(take(1), timeout(timeoutMs), catchError((error) => {
|
|
49
|
+
// Cleanup on timeout / cancellation
|
|
45
50
|
this.pendingOperations.delete(correlationId);
|
|
46
51
|
if (error instanceof TimeoutError) {
|
|
47
52
|
return throwError(() => new Error('Operation timed out'));
|
|
@@ -62,6 +67,18 @@ export class OperationTrackerService {
|
|
|
62
67
|
this.pendingOperations.delete(notification.correlationId);
|
|
63
68
|
}
|
|
64
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Cancel all pending operations — errors all open waitForOperation() observers.
|
|
72
|
+
* Called by SignalRService.disconnect() so in-flight CRUD UIs resolve fast
|
|
73
|
+
* instead of stranding until the 120s timeout.
|
|
74
|
+
*/
|
|
75
|
+
cancelAll(reason) {
|
|
76
|
+
if (this.pendingOperations.size === 0) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.pendingOperations.clear();
|
|
80
|
+
this.cancellation$.next(reason);
|
|
81
|
+
}
|
|
65
82
|
/**
|
|
66
83
|
* Check if operation is pending
|
|
67
84
|
*/
|
|
@@ -87,4 +104,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
87
104
|
type: Injectable,
|
|
88
105
|
args: [{ providedIn: 'root' }]
|
|
89
106
|
}] });
|
|
90
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0aW9uLXRyYWNrZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZGF0YS1hY2Nlc3Mvc3JjL2xpYi90YWItY29yZS11dGlsaXR5L2NvcmUvc2VydmljZS9zaWduYWxyL29wZXJhdGlvbi10cmFja2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUUsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLDJDQUEyQyxDQUFDOztBQUVuRDs7OztHQUlHO0FBRUgsTUFBTSxPQUFPLHVCQUF1QjtJQURwQztRQUVFLHVDQUF1QztRQUMvQixzQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztRQUVoRSxzQ0FBc0M7UUFDOUIsd0JBQW1CLEdBQUcsSUFBSSxPQUFPLEVBQW9CLENBQUM7UUFFOUQsNkZBQTZGO1FBQ3JGLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztLQXdHL0M7SUF0R0M7O09BRUc7SUFDSCxpQkFBaUIsQ0FBQyxTQUEyQjtRQUMzQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFL0QsNkJBQTZCO1FBQzdCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hELElBQUksQ0FBQyxp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QUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQztJQUNyQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhO1FBQ1gsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3JELENBQUM7K0dBL0dVLHVCQUF1QjttSEFBdkIsdUJBQXVCLGNBRFYsTUFBTTs7NEZBQ25CLHVCQUF1QjtrQkFEbkMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IG1lcmdlLCBPYnNlcnZhYmxlLCBTdWJqZWN0LCB0aHJvd0Vycm9yLCBUaW1lb3V0RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZmlsdGVyLCB0YWtlLCB0aW1lb3V0LCBjYXRjaEVycm9yLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7XHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBQZW5kaW5nT3BlcmF0aW9uLFxyXG4gIFNJR05BTFJfQ09ORklHLFxyXG59IGZyb20gJy4uLy4uLy4uL2FwcC9pbnRlcmZhY2VzL3NpZ25hbHIuaW50ZXJmYWNlJztcclxuXHJcbi8qKlxyXG4gKiBPcGVyYXRpb24gVHJhY2tlciBTZXJ2aWNlXHJcbiAqIFRyYWNrcyBhc3luYyBvcGVyYXRpb25zIGJ5IGNvcnJlbGF0aW9uSWQgYW5kIG1hdGNoZXMgdGhlbSB3aXRoIFNpZ25hbFIgbm90aWZpY2F0aW9uc1xyXG4gKiBVc2VkIGJ5IFRhYkZvcm1pb1NlcnZpY2UgZm9yIGhhbmRsaW5nIGFzeW5jIHByb2Nlc3NSZXF1ZXN0IG9wZXJhdGlvbnNcclxuICovXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBPcGVyYXRpb25UcmFja2VyU2VydmljZSB7XHJcbiAgLy8gTWFwPGNvcnJlbGF0aW9uSWQsIFBlbmRpbmdPcGVyYXRpb24+XHJcbiAgcHJpdmF0ZSBwZW5kaW5nT3BlcmF0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBQZW5kaW5nT3BlcmF0aW9uPigpO1xyXG5cclxuICAvLyBPYnNlcnZhYmxlIGZvciBjb21wbGV0ZWQgb3BlcmF0aW9uc1xyXG4gIHByaXZhdGUgb3BlcmF0aW9uQ29tcGxldGVkJCA9IG5ldyBTdWJqZWN0PENydWROb3RpZmljYXRpb24+KCk7XHJcblxyXG4gIC8vIENhbmNlbGxhdGlvbiBjaGFubmVsIOKAlCBlbWl0dGVkIGJ5IGNhbmNlbEFsbCgpIHRvIGVycm9yIGFueSBvcGVuIHdhaXRGb3JPcGVyYXRpb24gb2JzZXJ2ZXJzXHJcbiAgcHJpdmF0ZSBjYW5jZWxsYXRpb24kID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBhbiBhc3luYyBvcGVyYXRpb24gZm9yIHRyYWNraW5nXHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPcGVyYXRpb24ob3BlcmF0aW9uOiBQZW5kaW5nT3BlcmF0aW9uKTogdm9pZCB7XHJcbiAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLnNldChvcGVyYXRpb24uY29ycmVsYXRpb25JZCwgb3BlcmF0aW9uKTtcclxuXHJcbiAgICAvLyBBdXRvLWNsZWFudXAgYWZ0ZXIgdGltZW91dFxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmhhcyhvcGVyYXRpb24uY29ycmVsYXRpb25JZCkpIHtcclxuICAgICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShvcGVyYXRpb24uY29ycmVsYXRpb25JZCk7XHJcbiAgICAgIH1cclxuICAgIH0sIG9wZXJhdGlvbi50aW1lb3V0IHx8IFNJR05BTFJfQ09ORklHLkRFRkFVTFRfVElNRU9VVCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBXYWl0IGZvciBvcGVyYXRpb24gdG8gY29tcGxldGUgdmlhIFNpZ25hbFIgbm90aWZpY2F0aW9uXHJcbiAgICogUmV0dXJucyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBub3RpZmljYXRpb24gd2l0aCBtYXRjaGluZyBjb3JyZWxhdGlvbklkIGlzIHJlY2VpdmVkLFxyXG4gICAqIG9yIGVycm9ycyBpZiBjYW5jZWxBbGwoKSBpcyBpbnZva2VkIChlLmcuIG9uIGRpc2Nvbm5lY3QgLyBzaWduT3V0KS5cclxuICAgKi9cclxuICB3YWl0Rm9yT3BlcmF0aW9uKGNvcnJlbGF0aW9uSWQ6IHN0cmluZywgdGltZW91dE1zOiBudW1iZXIgPSBTSUdOQUxSX0NPTkZJRy5ERUZBVUxUX1RJTUVPVVQpOiBPYnNlcnZhYmxlPENydWROb3RpZmljYXRpb24+IHtcclxuICAgIC8vIEF1dG8tcmVnaXN0ZXIgc28gaGFuZGxlTm90aWZpY2F0aW9uIGNhbiBtYXRjaCBpdFxyXG4gICAgaWYgKCF0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmhhcyhjb3JyZWxhdGlvbklkKSkge1xyXG4gICAgICB0aGlzLnJlZ2lzdGVyT3BlcmF0aW9uKHtcclxuICAgICAgICBjb3JyZWxhdGlvbklkLFxyXG4gICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcclxuICAgICAgICB0aW1lb3V0OiB0aW1lb3V0TXNcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29tcGxldGVkJCA9IHRoaXMub3BlcmF0aW9uQ29tcGxldGVkJC5waXBlKFxyXG4gICAgICBmaWx0ZXIoKG5vdGlmaWNhdGlvbikgPT4gbm90aWZpY2F0aW9uLmNvcnJlbGF0aW9uSWQgPT09IGNvcnJlbGF0aW9uSWQpLFxyXG4gICAgICB0YWtlKDEpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGNhbmNlbGxlZCQgPSB0aGlzLmNhbmNlbGxhdGlvbiQucGlwZShcclxuICAgICAgdGFrZSgxKSxcclxuICAgICAgc3dpdGNoTWFwKChyZWFzb24pID0+IHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKGBTaWduYWxSIG9wZXJhdGlvbiBjYW5jZWxsZWQ6ICR7cmVhc29ufWApKSlcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIG1lcmdlKGNvbXBsZXRlZCQsIGNhbmNlbGxlZCQpLnBpcGUoXHJcbiAgICAgIHRha2UoMSksXHJcbiAgICAgIHRpbWVvdXQodGltZW91dE1zKSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICAvLyBDbGVhbnVwIG9uIHRpbWVvdXQgLyBjYW5jZWxsYXRpb25cclxuICAgICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShjb3JyZWxhdGlvbklkKTtcclxuXHJcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVGltZW91dEVycm9yKSB7XHJcbiAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoJ09wZXJhdGlvbiB0aW1lZCBvdXQnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgaW5jb21pbmcgU2lnbmFsUiBub3RpZmljYXRpb25cclxuICAgKiBDYWxsZWQgYnkgU2lnbmFsUlNlcnZpY2Ugd2hlbiBub3RpZmljYXRpb24gaXMgcmVjZWl2ZWRcclxuICAgKi9cclxuICBoYW5kbGVOb3RpZmljYXRpb24obm90aWZpY2F0aW9uOiBDcnVkTm90aWZpY2F0aW9uKTogdm9pZCB7XHJcbiAgICBjb25zdCBvcGVyYXRpb24gPSB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmdldChub3RpZmljYXRpb24uY29ycmVsYXRpb25JZCk7XHJcbiAgICBpZiAob3BlcmF0aW9uKSB7XHJcbiAgICAgIC8vIEVtaXQgdG8gb2JzZXJ2ZXJzIHdhaXRpbmcgZm9yIHRoaXMgb3BlcmF0aW9uXHJcbiAgICAgIHRoaXMub3BlcmF0aW9uQ29tcGxldGVkJC5uZXh0KG5vdGlmaWNhdGlvbik7XHJcblxyXG4gICAgICAvLyBDbGVhbnVwXHJcbiAgICAgIHRoaXMucGVuZGluZ09wZXJhdGlvbnMuZGVsZXRlKG5vdGlmaWNhdGlvbi5jb3JyZWxhdGlvbklkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbmNlbCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIOKAlCBlcnJvcnMgYWxsIG9wZW4gd2FpdEZvck9wZXJhdGlvbigpIG9ic2VydmVycy5cclxuICAgKiBDYWxsZWQgYnkgU2lnbmFsUlNlcnZpY2UuZGlzY29ubmVjdCgpIHNvIGluLWZsaWdodCBDUlVEIFVJcyByZXNvbHZlIGZhc3RcclxuICAgKiBpbnN0ZWFkIG9mIHN0cmFuZGluZyB1bnRpbCB0aGUgMTIwcyB0aW1lb3V0LlxyXG4gICAqL1xyXG4gIGNhbmNlbEFsbChyZWFzb246IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMucGVuZGluZ09wZXJhdGlvbnMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmNsZWFyKCk7XHJcbiAgICB0aGlzLmNhbmNlbGxhdGlvbiQubmV4dChyZWFzb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgb3BlcmF0aW9uIGlzIHBlbmRpbmdcclxuICAgKi9cclxuICBpc1BlbmRpbmcoY29ycmVsYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5oYXMoY29ycmVsYXRpb25JZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgcGVuZGluZyBvcGVyYXRpb25zIGNvdW50IChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFBlbmRpbmdDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ09wZXJhdGlvbnMuc2l6ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldEFsbFBlbmRpbmcoKTogUGVuZGluZ09wZXJhdGlvbltdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMucGVuZGluZ09wZXJhdGlvbnMudmFsdWVzKCkpO1xyXG4gIH1cclxufSJdfQ==
|
package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs
CHANGED
|
@@ -15,6 +15,10 @@ import * as i0 from "@angular/core";
|
|
|
15
15
|
export class SignalRInfrastructure {
|
|
16
16
|
constructor() {
|
|
17
17
|
this.hubConnection = null;
|
|
18
|
+
// In-flight connect() promise — used to dedupe concurrent calls
|
|
19
|
+
this.connectingPromise = null;
|
|
20
|
+
// Set true on explicit disconnect() so scheduled retries don't resurrect the connection
|
|
21
|
+
this.explicitlyDisconnected = false;
|
|
18
22
|
// Session storage
|
|
19
23
|
this.sessionStorageService = inject(SessionStorageService);
|
|
20
24
|
// local storage
|
|
@@ -73,11 +77,39 @@ export class SignalRInfrastructure {
|
|
|
73
77
|
}
|
|
74
78
|
/**
|
|
75
79
|
* Connect to SignalR hub
|
|
80
|
+
*
|
|
81
|
+
* Idempotent and safe to call from multiple sites:
|
|
82
|
+
* - already CONNECTED → returns immediately
|
|
83
|
+
* - already CONNECTING → returns the in-flight promise
|
|
84
|
+
* - any non-Connected leftover hubConnection → torn down before rebuild
|
|
76
85
|
*/
|
|
77
86
|
async connect() {
|
|
87
|
+
this.explicitlyDisconnected = false;
|
|
78
88
|
if (this.hubConnection?.state === signalR.HubConnectionState.Connected) {
|
|
79
89
|
return;
|
|
80
90
|
}
|
|
91
|
+
if (this.connectingPromise) {
|
|
92
|
+
return this.connectingPromise;
|
|
93
|
+
}
|
|
94
|
+
// Tear down any stale (non-Connected) hubConnection before rebuilding
|
|
95
|
+
if (this.hubConnection) {
|
|
96
|
+
try {
|
|
97
|
+
await this.hubConnection.stop();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// ignore — we're discarding it anyway
|
|
101
|
+
}
|
|
102
|
+
this.hubConnection = null;
|
|
103
|
+
}
|
|
104
|
+
this.connectingPromise = this.doConnect();
|
|
105
|
+
try {
|
|
106
|
+
await this.connectingPromise;
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.connectingPromise = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async doConnect() {
|
|
81
113
|
// Get hub URL from Common (set during app initialization via Common.init())
|
|
82
114
|
const hubUrl = Common.signalRHubUrl;
|
|
83
115
|
if (!hubUrl) {
|
|
@@ -110,8 +142,12 @@ export class SignalRInfrastructure {
|
|
|
110
142
|
}
|
|
111
143
|
catch (error) {
|
|
112
144
|
this.connectionState.set(CONNECTION_STATE.FAILED);
|
|
113
|
-
// Retry after 1 minute
|
|
114
|
-
setTimeout(() =>
|
|
145
|
+
// Retry after 1 minute, but only if the caller hasn't explicitly disconnected
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
if (!this.explicitlyDisconnected) {
|
|
148
|
+
this.connect();
|
|
149
|
+
}
|
|
150
|
+
}, 60 * 1000);
|
|
115
151
|
}
|
|
116
152
|
}
|
|
117
153
|
/**
|
|
@@ -168,8 +204,12 @@ export class SignalRInfrastructure {
|
|
|
168
204
|
});
|
|
169
205
|
this.hubConnection.onclose(() => {
|
|
170
206
|
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
171
|
-
// Try to reconnect
|
|
172
|
-
setTimeout(() =>
|
|
207
|
+
// Try to reconnect — but only if the caller hasn't explicitly disconnected
|
|
208
|
+
setTimeout(() => {
|
|
209
|
+
if (!this.explicitlyDisconnected) {
|
|
210
|
+
this.connect();
|
|
211
|
+
}
|
|
212
|
+
}, 60 * 1000);
|
|
173
213
|
});
|
|
174
214
|
}
|
|
175
215
|
/**
|
|
@@ -237,18 +277,24 @@ export class SignalRInfrastructure {
|
|
|
237
277
|
}
|
|
238
278
|
/**
|
|
239
279
|
* Disconnect from SignalR hub (cleanup)
|
|
280
|
+
*
|
|
281
|
+
* Sets explicitlyDisconnected so any pending retry timers from connect()/onclose
|
|
282
|
+
* become no-ops, then stops the hub and clears tracked groups.
|
|
240
283
|
*/
|
|
241
284
|
async disconnect() {
|
|
285
|
+
this.explicitlyDisconnected = true;
|
|
286
|
+
this.connectingPromise = null;
|
|
242
287
|
if (this.hubConnection) {
|
|
243
288
|
try {
|
|
244
289
|
await this.hubConnection.stop();
|
|
245
|
-
this.hubConnection = null;
|
|
246
|
-
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
247
290
|
}
|
|
248
291
|
catch (error) {
|
|
249
292
|
console.error('[SignalR] Error during disconnect:', error);
|
|
250
293
|
}
|
|
294
|
+
this.hubConnection = null;
|
|
251
295
|
}
|
|
296
|
+
this.activeGroups.clear();
|
|
297
|
+
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
252
298
|
}
|
|
253
299
|
/**
|
|
254
300
|
* Get active groups (for debugging)
|
|
@@ -265,4 +311,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
265
311
|
providedIn: 'root',
|
|
266
312
|
}]
|
|
267
313
|
}] });
|
|
268
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFJTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0Qsa0JBQWtCO1FBQ1QsMEJBQXFCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ1Asd0JBQW1CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsNkJBQTZCO1FBQ3BCLG9CQUFlLEdBQUcsTUFBTSxDQUFrQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRiwyREFBMkQ7UUFDbEQs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SCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssS0FBSyxPQUFPLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0lBQzVFLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxVQUFVO1FBQ2QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDOytHQXpTVSxxQkFBcUI7bUhBQXJCLHFCQUFxQixjQUZwQixNQUFNOzs0RkFFUCxxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgc2lnbmFsUiBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBDb25uZWN0aW9uU3RhdGUsXHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBTaWduYWxSTWVzc2FnZSxcclxuICBTSUdOQUxSX0hVQl9NRVRIT0RTLFxyXG4gIFNJR05BTFJfRVZFTlRTLFxyXG4gIENSVURfT1BFUkFUSU9OLFxyXG4gIENPTk5FQ1RJT05fU1RBVEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlQ29uc3RhbnRzIH0gZnJvbSAnLi4vLi4vLi4vYXBwL2NvbnN0YW50cy9zdG9yYWdlLWNvbnN0YW50cyc7XHJcbmltcG9ydCB7IFNlc3Npb25TdG9yYWdlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGgvc2Vzc2lvbi1zdG9yYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXV0aC9sb2NhbC1zdG9yYWdlLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgSW5mcmFzdHJ1Y3R1cmUgU2VydmljZVxyXG4gKiBIYW5kbGVzIGxvdy1sZXZlbCBXZWJTb2NrZXQgY29ubmVjdGlvbiwgZ3JvdXAgbWFuYWdlbWVudCwgYW5kIHJlY29ubmVjdGlvblxyXG4gKiBJbnRlcm5hbCB1c2Ugb25seSAtIGNvbXBvbmVudHMgc2hvdWxkIHVzZSBTaWduYWxSU2VydmljZSBpbnN0ZWFkXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2lnbmFsUkluZnJhc3RydWN0dXJlIHtcclxuICBwcml2YXRlIGh1YkNvbm5lY3Rpb246IHNpZ25hbFIuSHViQ29ubmVjdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBTZXNzaW9uIHN0b3JhZ2VcclxuICByZWFkb25seSBzZXNzaW9uU3RvcmFnZVNlcnZpY2UgPSBpbmplY3QoU2Vzc2lvblN0b3JhZ2VTZXJ2aWNlKTtcclxuXHJcbiAgLy8gbG9jYWwgc3RvcmFnZVxyXG4gIHJlYWRvbmx5IGxvY2FsU3RvcmFnZVNlcnZpY2UgPSBpbmplY3QoTG9jYWxTdG9yYWdlU2VydmljZSk7XHJcblxyXG4gIC8vIENvbm5lY3Rpb24gc3RhdGUgYXMgc2lnbmFsXHJcbiAgcmVhZG9ubHkgY29ubmVjdGlvblN0YXRlID0gc2lnbmFsPENvbm5lY3Rpb25TdGF0ZT4oQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG5cclxuICAvLyBOb3RpZmljYXRpb24gc3RyZWFtIChpbnRlcm5hbCAtIGVtaXRzIHRvIFNpZ25hbFJTZXJ2aWNlKVxyXG4gIHJlYWRvbmx5IG5vdGlmaWNhdGlvbnMkID0gbmV3IFN1YmplY3Q8Q3J1ZE5vdGlmaWNhdGlvbj4oKTtcclxuXHJcbiAgLy8gVHJhY2sgYWN0aXZlIGdyb3VwcyB0byByZWpvaW4gYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgcHJpdmF0ZSBhY3RpdmVHcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogSGVscGVyIG1ldGhvZCB0byBnZXQgdmFsdWUgZnJvbSBzdG9yYWdlXHJcbiAgICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2Ygc3RvcmFnZSwgJ1Nlc3Npb24nIG9yICdMb2NhbCdcclxuICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdG8gcmV0cmlldmUgdGhlIHZhbHVlIGZvclxyXG4gICAqIEByZXR1cm5zIFRoZSB2YWx1ZSBmcm9tIHN0b3JhZ2UsIG9yIG51bGwgaWYgbm90IGF2YWlsYWJsZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0RnJvbVN0b3JhZ2UodHlwZTogc3RyaW5nLCBrZXk6IHN0cmluZykge1xyXG4gICAgdHJ5IHtcclxuICAgICAgbGV0IGluZm86IGFueSA9IG51bGw7XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ1Nlc3Npb24nKSB7XHJcbiAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gc2Vzc2lvbiBzdG9yYWdlXHJcbiAgICAgICAgaW5mbyA9IHRoaXMuc2Vzc2lvblN0b3JhZ2VTZXJ2aWNlLmdldFNlc3Npb25TdG9yYWdlKGtleSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0eXBlID09PSAnTG9jYWwnKSB7XHJcbiAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gbG9jYWwgc3RvcmFnZVxyXG4gICAgICAgIGluZm8gPSB0aGlzLmxvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0TG9jYWxTdG9yYWdlKGtleSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChpbmZvICYmIHR5cGVvZiBpbmZvID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIC8vIFBhcnNlIHRoZSB2YWx1ZSBpZiBpdCdzIGEgc3RyaW5nXHJcbiAgICAgICAgaW5mbyA9IEpTT04ucGFyc2UoaW5mbyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBpbmZvO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgLy8gTG9nIGVycm9yIGlmIGZhaWxlZCB0byBnZXQgdmFsdWUgZnJvbSBzdG9yYWdlXHJcbiAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIGdldCBjdXJyZW50IGFwcCBJRCBmcm9tIHNlc3Npb246JywgZXJyb3IpO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBhcHBJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGFwcEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdTZXNzaW9uJywgU3RvcmFnZUNvbnN0YW50cy5hcHBJbmZvKTtcclxuICAgIHJldHVybiBhcHBJbmZvPy5JZCB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGVudmlyb25tZW50SWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBlbnZJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnU2Vzc2lvbicsIFN0b3JhZ2VDb25zdGFudHMuZW52aXJvbm1lbnRJbmZvKTtcclxuICAgIHJldHVybiBlbnZJbmZvPy5JZCB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHRlbmFudElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgdGVuYW50SW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ0xvY2FsJywgU3RvcmFnZUNvbnN0YW50cy5vcmdJbmZvKTtcclxuICAgIHJldHVybiB0ZW5hbnRJbmZvPy5JZCB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHRva2VuKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgYXV0aEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdMb2NhbCcsIFN0b3JhZ2VDb25zdGFudHMudG9rZW5JbmZvKTtcclxuICAgIHJldHVybiBhdXRoSW5mbz8udG9rZW4gfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbm5lY3QgdG8gU2lnbmFsUiBodWJcclxuICAgKi9cclxuICBhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGh1YiBVUkwgZnJvbSBDb21tb24gKHNldCBkdXJpbmcgYXBwIGluaXRpYWxpemF0aW9uIHZpYSBDb21tb24uaW5pdCgpKVxyXG4gICAgY29uc3QgaHViVXJsID0gQ29tbW9uLnNpZ25hbFJIdWJVcmw7XHJcblxyXG4gICAgaWYgKCFodWJVcmwpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignW1NpZ25hbFJdIEh1YiBVUkwgbm90IGNvbmZpZ3VyZWQuIE1ha2Ugc3VyZSBDb21tb24uaW5pdCgpIGlzIGNhbGxlZCB3aXRoIGVudmlyb25tZW50LicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVElORyk7XHJcblxyXG4gICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBuZXcgc2lnbmFsUi5IdWJDb25uZWN0aW9uQnVpbGRlcigpXHJcbiAgICAgICAgLndpdGhVcmwoaHViVXJsLCB7XHJcbiAgICAgICAgICBhY2Nlc3NUb2tlbkZhY3Rvcnk6ICgpID0+IHRoaXMudG9rZW4gfHwgJycsXHJcbiAgICAgICAgICBza2lwTmVnb3RpYXRpb246IGZhbHNlLFxyXG4gICAgICAgICAgdHJhbnNwb3J0OiBzaWduYWxSLkh0dHBUcmFuc3BvcnRUeXBlLldlYlNvY2tldHMgfCBzaWduYWxSLkh0dHBUcmFuc3BvcnRUeXBlLlNlcnZlclNlbnRFdmVudHMsXHJcbiAgICAgICAgfSlcclxuICAgICAgICAud2l0aEF1dG9tYXRpY1JlY29ubmVjdCh7XHJcbiAgICAgICAgICBuZXh0UmV0cnlEZWxheUluTWlsbGlzZWNvbmRzOiAocmV0cnlDb250ZXh0OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgLy8gRXhwb25lbnRpYWwgYmFja29mZjogMHMsIDJzLCAxMHMsIDMwcywgbWF4IDYwc1xyXG4gICAgICAgICAgICBpZiAocmV0cnlDb250ZXh0LmVsYXBzZWRNaWxsaXNlY29uZHMgPCA2MDAwMCkge1xyXG4gICAgICAgICAgICAgIHJldHVybiBNYXRoLm1pbigxMDAwICogTWF0aC5wb3coMiwgcmV0cnlDb250ZXh0LnByZXZpb3VzUmV0cnlDb3VudCksIDYwMDAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gU3RvcCByZXRyeWluZyBhZnRlciAxIG1pbnV0ZVxyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5jb25maWd1cmVMb2dnaW5nKHNpZ25hbFIuTG9nTGV2ZWwuSW5mb3JtYXRpb24pXHJcbiAgICAgICAgLmJ1aWxkKCk7XHJcblxyXG4gICAgICB0aGlzLnJlZ2lzdGVyRXZlbnRIYW5kbGVycygpO1xyXG4gICAgICB0aGlzLnJlZ2lzdGVyQ29ubmVjdGlvbkxpZmVjeWNsZSgpO1xyXG5cclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLnN0YXJ0KCk7XHJcblxyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuRkFJTEVEKTtcclxuXHJcbiAgICAgIC8vIFJldHJ5IGFmdGVyIDEgbWludXRlXHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb25uZWN0KCksIDYwICogMTAwMCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBTaWduYWxSIGV2ZW50IGhhbmRsZXJzIGZvciBDUlVEIG5vdGlmaWNhdGlvbnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlZ2lzdGVyRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uKSByZXR1cm47XHJcblxyXG4gICAgLy8gSU5TRVJUIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5JTlNFUlRfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLklOU0VSVCwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVVBEQVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5VUERBVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLlVQREFURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gREVMRVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5ERUxFVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLkRFTEVURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IG5vdGlmaWNhdGlvbiBmcm9tIFNpZ25hbFIgY2FsbGJhY2sgYXJnc1xyXG4gICAqIEhhbmRsZXMgYm90aCB1bndyYXBwZWQgKGRpcmVjdCBvYmplY3QpIGFuZCB3cmFwcGVkICh7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzIH0pIGZvcm1hdHNcclxuICAgKi9cclxuICBwcml2YXRlIGV4dHJhY3ROb3RpZmljYXRpb24oYXJnczogYW55W10pOiBDcnVkTm90aWZpY2F0aW9uIHtcclxuICAgIGNvbnN0IGRhdGEgPSBhcmdzWzBdO1xyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgZGlkbid0IHVud3JhcDogZGF0YSBpcyByYXcgU2lnbmFsUk1lc3NhZ2Ugd2l0aCB7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzOiBbLi4uXSB9XHJcbiAgICBpZiAoZGF0YT8uYXJndW1lbnRzICYmIEFycmF5LmlzQXJyYXkoZGF0YS5hcmd1bWVudHMpKSB7XHJcbiAgICAgIHJldHVybiAoZGF0YSBhcyBTaWduYWxSTWVzc2FnZSkuYXJndW1lbnRzWzBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgdW53cmFwcGVkOiBkYXRhIGlzIHRoZSBub3RpZmljYXRpb24gZGlyZWN0bHlcclxuICAgIHJldHVybiBkYXRhIGFzIENydWROb3RpZmljYXRpb247XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBjb25uZWN0aW9uIGxpZmVjeWNsZSBoYW5kbGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24pIHJldHVybjtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25yZWNvbm5lY3RpbmcoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5SRUNPTk5FQ1RJTkcpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9ucmVjb25uZWN0ZWQoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG5cclxuICAgICAgLy8gUmVqb2luIGFsbCBncm91cHMgYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgICAgIHRoaXMucmVqb2luR3JvdXBzKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25jbG9zZSgoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAvLyBUcnkgdG8gcmVjb25uZWN0XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb25uZWN0KCksIDYwICogMTAwMCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEpvaW4gU2lnbmFsUiBncm91cCBmb3IgYW4gQXBwT2JqZWN0XHJcbiAgICovXHJcbiAgYXN5bmMgam9pbkdyb3VwKGFwcE9iamVjdElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uIHx8IHRoaXMuaHViQ29ubmVjdGlvbi5zdGF0ZSAhPT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBpZiAoIXRoaXMudGVuYW50SWQgfHwgIXRoaXMuYXBwSWQgfHwgIXRoaXMuZW52aXJvbm1lbnRJZCB8fCAhYXBwT2JqZWN0SWQpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5pbnZva2UoXHJcbiAgICAgICAgU0lHTkFMUl9IVUJfTUVUSE9EUy5KT0lOX0dST1VQLFxyXG4gICAgICAgIHRoaXMudGVuYW50SWQsXHJcbiAgICAgICAgdGhpcy5hcHBJZCxcclxuICAgICAgICB0aGlzLmVudmlyb25tZW50SWQsXHJcbiAgICAgICAgYXBwT2JqZWN0SWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIFRyYWNrIHRoaXMgZ3JvdXAgZm9yIHJlY29ubmVjdGlvblxyXG4gICAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5hZGQoYXBwT2JqZWN0SWQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgW1NpZ25hbFJdIEZhaWxlZCB0byBqb2luIGdyb3VwOiAke2FwcE9iamVjdElkfWAsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlIFNpZ25hbFIgZ3JvdXBcclxuICAgKi9cclxuICBhc3luYyBsZWF2ZUdyb3VwKGFwcE9iamVjdElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uIHx8IHRoaXMuaHViQ29ubmVjdGlvbi5zdGF0ZSAhPT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSB7XHJcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nIGV2ZW4gaWYgbm90IGNvbm5lY3RlZFxyXG4gICAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5kZWxldGUoYXBwT2JqZWN0SWQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLnRlbmFudElkIHx8ICF0aGlzLmFwcElkIHx8ICF0aGlzLmVudmlyb25tZW50SWQgfHwgIWFwcE9iamVjdElkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uaW52b2tlKFxyXG4gICAgICAgIFNJR05BTFJfSFVCX01FVEhPRFMuTEVBVkVfR1JPVVAsXHJcbiAgICAgICAgdGhpcy50ZW5hbnRJZCxcclxuICAgICAgICB0aGlzLmFwcElkLFxyXG4gICAgICAgIHRoaXMuZW52aXJvbm1lbnRJZCxcclxuICAgICAgICBhcHBPYmplY3RJZFxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8gUmVtb3ZlIGZyb20gdHJhY2tpbmdcclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuZGVsZXRlKGFwcE9iamVjdElkKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSXSBGYWlsZWQgdG8gbGVhdmUgZ3JvdXA6ICR7YXBwT2JqZWN0SWR9YCwgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVqb2luIGFsbCBhY3RpdmUgZ3JvdXBzIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gICAqIFRoaXMgZW5zdXJlcyBjb21wb25lbnRzIGNvbnRpbnVlIHJlY2VpdmluZyBub3RpZmljYXRpb25zIGFmdGVyIG5ldHdvcmsgaW50ZXJydXB0aW9uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyByZWpvaW5Hcm91cHMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5hY3RpdmVHcm91cHMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGxpc3Qgb2YgZ3JvdXBzIHRvIHJlam9pblxyXG4gICAgY29uc3QgZ3JvdXBzID0gQXJyYXkuZnJvbSh0aGlzLmFjdGl2ZUdyb3Vwcyk7XHJcblxyXG4gICAgLy8gQ2xlYXIgdGhlIHNldCAod2lsbCBiZSByZS1hZGRlZCBkdXJpbmcgam9pbkdyb3VwKVxyXG4gICAgdGhpcy5hY3RpdmVHcm91cHMuY2xlYXIoKTtcclxuXHJcbiAgICAvLyBSZWpvaW4gZWFjaCBncm91cFxyXG4gICAgZm9yIChjb25zdCBhcHBPYmplY3RJZCBvZiBncm91cHMpIHtcclxuICAgICAgYXdhaXQgdGhpcy5qb2luR3JvdXAoYXBwT2JqZWN0SWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY29ubmVjdGVkXHJcbiAgICovXHJcbiAgaXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5odWJDb25uZWN0aW9uPy5zdGF0ZSA9PT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGlzY29ubmVjdCBmcm9tIFNpZ25hbFIgaHViIChjbGVhbnVwKVxyXG4gICAqL1xyXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5odWJDb25uZWN0aW9uKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLnN0b3AoKTtcclxuICAgICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBudWxsO1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW1NpZ25hbFJdIEVycm9yIGR1cmluZyBkaXNjb25uZWN0OicsIGVycm9yKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFjdGl2ZSBncm91cHMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWN0aXZlR3JvdXBzKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuYWN0aXZlR3JvdXBzKTtcclxuICB9XHJcbn0iXX0=
|
|
314
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFJTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0QsZ0VBQWdFO1FBQ3hELHNCQUFpQixHQUF5QixJQUFJLENBQUM7UUFFdkQsd0ZBQXdGO1FBQ2hGLDJCQUFzQixHQUFHLEtBQUssQ0FBQztRQUV2QyxrQkFBa0I7UUFDVCwwQkFBcUIsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUUvRCxnQkFBZ0I7UUFDUCx3QkFBbUIsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUUz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QXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFFOUIsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzdELENBQUM7WUFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUM1QixDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDOytHQTdWVSxxQkFBcUI7bUhBQXJCLHFCQUFxQixjQUZwQixNQUFNOzs0RkFFUCxxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgc2lnbmFsUiBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBDb25uZWN0aW9uU3RhdGUsXHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBTaWduYWxSTWVzc2FnZSxcclxuICBTSUdOQUxSX0hVQl9NRVRIT0RTLFxyXG4gIFNJR05BTFJfRVZFTlRTLFxyXG4gIENSVURfT1BFUkFUSU9OLFxyXG4gIENPTk5FQ1RJT05fU1RBVEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlQ29uc3RhbnRzIH0gZnJvbSAnLi4vLi4vLi4vYXBwL2NvbnN0YW50cy9zdG9yYWdlLWNvbnN0YW50cyc7XHJcbmltcG9ydCB7IFNlc3Npb25TdG9yYWdlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGgvc2Vzc2lvbi1zdG9yYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXV0aC9sb2NhbC1zdG9yYWdlLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgSW5mcmFzdHJ1Y3R1cmUgU2VydmljZVxyXG4gKiBIYW5kbGVzIGxvdy1sZXZlbCBXZWJTb2NrZXQgY29ubmVjdGlvbiwgZ3JvdXAgbWFuYWdlbWVudCwgYW5kIHJlY29ubmVjdGlvblxyXG4gKiBJbnRlcm5hbCB1c2Ugb25seSAtIGNvbXBvbmVudHMgc2hvdWxkIHVzZSBTaWduYWxSU2VydmljZSBpbnN0ZWFkXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2lnbmFsUkluZnJhc3RydWN0dXJlIHtcclxuICBwcml2YXRlIGh1YkNvbm5lY3Rpb246IHNpZ25hbFIuSHViQ29ubmVjdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBJbi1mbGlnaHQgY29ubmVjdCgpIHByb21pc2Ug4oCUIHVzZWQgdG8gZGVkdXBlIGNvbmN1cnJlbnQgY2FsbHNcclxuICBwcml2YXRlIGNvbm5lY3RpbmdQcm9taXNlOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIFNldCB0cnVlIG9uIGV4cGxpY2l0IGRpc2Nvbm5lY3QoKSBzbyBzY2hlZHVsZWQgcmV0cmllcyBkb24ndCByZXN1cnJlY3QgdGhlIGNvbm5lY3Rpb25cclxuICBwcml2YXRlIGV4cGxpY2l0bHlEaXNjb25uZWN0ZWQgPSBmYWxzZTtcclxuXHJcbiAgLy8gU2Vzc2lvbiBzdG9yYWdlXHJcbiAgcmVhZG9ubHkgc2Vzc2lvblN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KFNlc3Npb25TdG9yYWdlU2VydmljZSk7XHJcblxyXG4gIC8vIGxvY2FsIHN0b3JhZ2VcclxuICByZWFkb25seSBsb2NhbFN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KExvY2FsU3RvcmFnZVNlcnZpY2UpO1xyXG5cclxuICAvLyBDb25uZWN0aW9uIHN0YXRlIGFzIHNpZ25hbFxyXG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25TdGF0ZSA9IHNpZ25hbDxDb25uZWN0aW9uU3RhdGU+KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuXHJcbiAgLy8gTm90aWZpY2F0aW9uIHN0cmVhbSAoaW50ZXJuYWwgLSBlbWl0cyB0byBTaWduYWxSU2VydmljZSlcclxuICByZWFkb25seSBub3RpZmljYXRpb25zJCA9IG5ldyBTdWJqZWN0PENydWROb3RpZmljYXRpb24+KCk7XHJcblxyXG4gIC8vIFRyYWNrIGFjdGl2ZSBncm91cHMgdG8gcmVqb2luIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gIHByaXZhdGUgYWN0aXZlR3JvdXBzID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHN0b3JhZ2UsICdTZXNzaW9uJyBvciAnTG9jYWwnXHJcbiAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmb3JcclxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgZnJvbSBzdG9yYWdlLCBvciBudWxsIGlmIG5vdCBhdmFpbGFibGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldEZyb21TdG9yYWdlKHR5cGU6IHN0cmluZywga2V5OiBzdHJpbmcpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBpbmZvOiBhbnkgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdTZXNzaW9uJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIHNlc3Npb24gc3RvcmFnZVxyXG4gICAgICAgIGluZm8gPSB0aGlzLnNlc3Npb25TdG9yYWdlU2VydmljZS5nZXRTZXNzaW9uU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ0xvY2FsJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICBpbmZvID0gdGhpcy5sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldExvY2FsU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaW5mbyAmJiB0eXBlb2YgaW5mbyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAvLyBQYXJzZSB0aGUgdmFsdWUgaWYgaXQncyBhIHN0cmluZ1xyXG4gICAgICAgIGluZm8gPSBKU09OLnBhcnNlKGluZm8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gaW5mbztcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIC8vIExvZyBlcnJvciBpZiBmYWlsZWQgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBnZXQgY3VycmVudCBhcHAgSUQgZnJvbSBzZXNzaW9uOicsIGVycm9yKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgYXBwSWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBhcHBJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnU2Vzc2lvbicsIFN0b3JhZ2VDb25zdGFudHMuYXBwSW5mbyk7XHJcbiAgICByZXR1cm4gYXBwSW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBlbnZpcm9ubWVudElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgZW52SW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ1Nlc3Npb24nLCBTdG9yYWdlQ29uc3RhbnRzLmVudmlyb25tZW50SW5mbyk7XHJcbiAgICByZXR1cm4gZW52SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0ZW5hbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IHRlbmFudEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdMb2NhbCcsIFN0b3JhZ2VDb25zdGFudHMub3JnSW5mbyk7XHJcbiAgICByZXR1cm4gdGVuYW50SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0b2tlbigpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGF1dGhJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnTG9jYWwnLCBTdG9yYWdlQ29uc3RhbnRzLnRva2VuSW5mbyk7XHJcbiAgICByZXR1cm4gYXV0aEluZm8/LnRva2VuIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb25uZWN0IHRvIFNpZ25hbFIgaHViXHJcbiAgICpcclxuICAgKiBJZGVtcG90ZW50IGFuZCBzYWZlIHRvIGNhbGwgZnJvbSBtdWx0aXBsZSBzaXRlczpcclxuICAgKiAtIGFscmVhZHkgQ09OTkVDVEVEIOKGkiByZXR1cm5zIGltbWVkaWF0ZWx5XHJcbiAgICogLSBhbHJlYWR5IENPTk5FQ1RJTkcg4oaSIHJldHVybnMgdGhlIGluLWZsaWdodCBwcm9taXNlXHJcbiAgICogLSBhbnkgbm9uLUNvbm5lY3RlZCBsZWZ0b3ZlciBodWJDb25uZWN0aW9uIOKGkiB0b3JuIGRvd24gYmVmb3JlIHJlYnVpbGRcclxuICAgKi9cclxuICBhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY29ubmVjdGluZ1Byb21pc2UpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGluZ1Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGVhciBkb3duIGFueSBzdGFsZSAobm9uLUNvbm5lY3RlZCkgaHViQ29ubmVjdGlvbiBiZWZvcmUgcmVidWlsZGluZ1xyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbikge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdG9wKCk7XHJcbiAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgIC8vIGlnbm9yZSDigJQgd2UncmUgZGlzY2FyZGluZyBpdCBhbnl3YXlcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSB0aGlzLmRvQ29ubmVjdCgpO1xyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgdGhpcy5jb25uZWN0aW5nUHJvbWlzZTtcclxuICAgIH0gZmluYWxseSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkb0Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBHZXQgaHViIFVSTCBmcm9tIENvbW1vbiAoc2V0IGR1cmluZyBhcHAgaW5pdGlhbGl6YXRpb24gdmlhIENvbW1vbi5pbml0KCkpXHJcbiAgICBjb25zdCBodWJVcmwgPSBDb21tb24uc2lnbmFsUkh1YlVybDtcclxuXHJcbiAgICBpZiAoIWh1YlVybCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdbU2lnbmFsUl0gSHViIFVSTCBub3QgY29uZmlndXJlZC4gTWFrZSBzdXJlIENvbW1vbi5pbml0KCkgaXMgY2FsbGVkIHdpdGggZW52aXJvbm1lbnQuJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICAgIHRoaXMuaHViQ29ubmVjdGlvbiA9IG5ldyBzaWduYWxSLkh1YkNvbm5lY3Rpb25CdWlsZGVyKClcclxuICAgICAgICAud2l0aFVybChodWJVcmwsIHtcclxuICAgICAgICAgIGFjY2Vzc1Rva2VuRmFjdG9yeTogKCkgPT4gdGhpcy50b2tlbiB8fCAnJyxcclxuICAgICAgICAgIHNraXBOZWdvdGlhdGlvbjogZmFsc2UsXHJcbiAgICAgICAgICB0cmFuc3BvcnQ6IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuV2ViU29ja2V0cyB8IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cyxcclxuICAgICAgICB9KVxyXG4gICAgICAgIC53aXRoQXV0b21hdGljUmVjb25uZWN0KHtcclxuICAgICAgICAgIG5leHRSZXRyeURlbGF5SW5NaWxsaXNlY29uZHM6IChyZXRyeUNvbnRleHQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBFeHBvbmVudGlhbCBiYWNrb2ZmOiAwcywgMnMsIDEwcywgMzBzLCBtYXggNjBzXHJcbiAgICAgICAgICAgIGlmIChyZXRyeUNvbnRleHQuZWxhcHNlZE1pbGxpc2Vjb25kcyA8IDYwMDAwKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKDEwMDAgKiBNYXRoLnBvdygyLCByZXRyeUNvbnRleHQucHJldmlvdXNSZXRyeUNvdW50KSwgNjAwMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBTdG9wIHJldHJ5aW5nIGFmdGVyIDEgbWludXRlXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNvbmZpZ3VyZUxvZ2dpbmcoc2lnbmFsUi5Mb2dMZXZlbC5JbmZvcm1hdGlvbilcclxuICAgICAgICAuYnVpbGQoKTtcclxuXHJcbiAgICAgIHRoaXMucmVnaXN0ZXJFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgIHRoaXMucmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk7XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhcnQoKTtcclxuXHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG5cclxuICAgICAgLy8gUmV0cnkgYWZ0ZXIgMSBtaW51dGUsIGJ1dCBvbmx5IGlmIHRoZSBjYWxsZXIgaGFzbid0IGV4cGxpY2l0bHkgZGlzY29ubmVjdGVkXHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIDYwICogMTAwMCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBTaWduYWxSIGV2ZW50IGhhbmRsZXJzIGZvciBDUlVEIG5vdGlmaWNhdGlvbnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlZ2lzdGVyRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uKSByZXR1cm47XHJcblxyXG4gICAgLy8gSU5TRVJUIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5JTlNFUlRfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLklOU0VSVCwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVVBEQVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5VUERBVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLlVQREFURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gREVMRVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5ERUxFVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLkRFTEVURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IG5vdGlmaWNhdGlvbiBmcm9tIFNpZ25hbFIgY2FsbGJhY2sgYXJnc1xyXG4gICAqIEhhbmRsZXMgYm90aCB1bndyYXBwZWQgKGRpcmVjdCBvYmplY3QpIGFuZCB3cmFwcGVkICh7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzIH0pIGZvcm1hdHNcclxuICAgKi9cclxuICBwcml2YXRlIGV4dHJhY3ROb3RpZmljYXRpb24oYXJnczogYW55W10pOiBDcnVkTm90aWZpY2F0aW9uIHtcclxuICAgIGNvbnN0IGRhdGEgPSBhcmdzWzBdO1xyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgZGlkbid0IHVud3JhcDogZGF0YSBpcyByYXcgU2lnbmFsUk1lc3NhZ2Ugd2l0aCB7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzOiBbLi4uXSB9XHJcbiAgICBpZiAoZGF0YT8uYXJndW1lbnRzICYmIEFycmF5LmlzQXJyYXkoZGF0YS5hcmd1bWVudHMpKSB7XHJcbiAgICAgIHJldHVybiAoZGF0YSBhcyBTaWduYWxSTWVzc2FnZSkuYXJndW1lbnRzWzBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgdW53cmFwcGVkOiBkYXRhIGlzIHRoZSBub3RpZmljYXRpb24gZGlyZWN0bHlcclxuICAgIHJldHVybiBkYXRhIGFzIENydWROb3RpZmljYXRpb247XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBjb25uZWN0aW9uIGxpZmVjeWNsZSBoYW5kbGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24pIHJldHVybjtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25yZWNvbm5lY3RpbmcoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5SRUNPTk5FQ1RJTkcpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9ucmVjb25uZWN0ZWQoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG5cclxuICAgICAgLy8gUmVqb2luIGFsbCBncm91cHMgYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgICAgIHRoaXMucmVqb2luR3JvdXBzKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25jbG9zZSgoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAvLyBUcnkgdG8gcmVjb25uZWN0IOKAlCBidXQgb25seSBpZiB0aGUgY2FsbGVyIGhhc24ndCBleHBsaWNpdGx5IGRpc2Nvbm5lY3RlZFxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgdGhpcy5jb25uZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCA2MCAqIDEwMDApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBKb2luIFNpZ25hbFIgZ3JvdXAgZm9yIGFuIEFwcE9iamVjdFxyXG4gICAqL1xyXG4gIGFzeW5jIGpvaW5Hcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKCF0aGlzLnRlbmFudElkIHx8ICF0aGlzLmFwcElkIHx8ICF0aGlzLmVudmlyb25tZW50SWQgfHwgIWFwcE9iamVjdElkKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uaW52b2tlKFxyXG4gICAgICAgIFNJR05BTFJfSFVCX01FVEhPRFMuSk9JTl9HUk9VUCxcclxuICAgICAgICB0aGlzLnRlbmFudElkLFxyXG4gICAgICAgIHRoaXMuYXBwSWQsXHJcbiAgICAgICAgdGhpcy5lbnZpcm9ubWVudElkLFxyXG4gICAgICAgIGFwcE9iamVjdElkXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBUcmFjayB0aGlzIGdyb3VwIGZvciByZWNvbm5lY3Rpb25cclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuYWRkKGFwcE9iamVjdElkKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSXSBGYWlsZWQgdG8gam9pbiBncm91cDogJHthcHBPYmplY3RJZH1gLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMZWF2ZSBTaWduYWxSIGdyb3VwXHJcbiAgICovXHJcbiAgYXN5bmMgbGVhdmVHcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZyBldmVuIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuZGVsZXRlKGFwcE9iamVjdElkKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5hcHBJZCB8fCAhdGhpcy5lbnZpcm9ubWVudElkIHx8ICFhcHBPYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLmludm9rZShcclxuICAgICAgICBTSUdOQUxSX0hVQl9NRVRIT0RTLkxFQVZFX0dST1VQLFxyXG4gICAgICAgIHRoaXMudGVuYW50SWQsXHJcbiAgICAgICAgdGhpcy5hcHBJZCxcclxuICAgICAgICB0aGlzLmVudmlyb25tZW50SWQsXHJcbiAgICAgICAgYXBwT2JqZWN0SWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmRlbGV0ZShhcHBPYmplY3RJZCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBbU2lnbmFsUl0gRmFpbGVkIHRvIGxlYXZlIGdyb3VwOiAke2FwcE9iamVjdElkfWAsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlam9pbiBhbGwgYWN0aXZlIGdyb3VwcyBhZnRlciByZWNvbm5lY3Rpb25cclxuICAgKiBUaGlzIGVuc3VyZXMgY29tcG9uZW50cyBjb250aW51ZSByZWNlaXZpbmcgbm90aWZpY2F0aW9ucyBhZnRlciBuZXR3b3JrIGludGVycnVwdGlvblxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVqb2luR3JvdXBzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBzLnNpemUgPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBsaXN0IG9mIGdyb3VwcyB0byByZWpvaW5cclxuICAgIGNvbnN0IGdyb3VwcyA9IEFycmF5LmZyb20odGhpcy5hY3RpdmVHcm91cHMpO1xyXG5cclxuICAgIC8vIENsZWFyIHRoZSBzZXQgKHdpbGwgYmUgcmUtYWRkZWQgZHVyaW5nIGpvaW5Hcm91cClcclxuICAgIHRoaXMuYWN0aXZlR3JvdXBzLmNsZWFyKCk7XHJcblxyXG4gICAgLy8gUmVqb2luIGVhY2ggZ3JvdXBcclxuICAgIGZvciAoY29uc3QgYXBwT2JqZWN0SWQgb2YgZ3JvdXBzKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuam9pbkdyb3VwKGFwcE9iamVjdElkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGNvbm5lY3RlZFxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc2Nvbm5lY3QgZnJvbSBTaWduYWxSIGh1YiAoY2xlYW51cClcclxuICAgKlxyXG4gICAqIFNldHMgZXhwbGljaXRseURpc2Nvbm5lY3RlZCBzbyBhbnkgcGVuZGluZyByZXRyeSB0aW1lcnMgZnJvbSBjb25uZWN0KCkvb25jbG9zZVxyXG4gICAqIGJlY29tZSBuby1vcHMsIHRoZW4gc3RvcHMgdGhlIGh1YiBhbmQgY2xlYXJzIHRyYWNrZWQgZ3JvdXBzLlxyXG4gICAqL1xyXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICB0aGlzLmV4cGxpY2l0bHlEaXNjb25uZWN0ZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IG51bGw7XHJcblxyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbikge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdG9wKCk7XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW1NpZ25hbFJdIEVycm9yIGR1cmluZyBkaXNjb25uZWN0OicsIGVycm9yKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuYWN0aXZlR3JvdXBzLmNsZWFyKCk7XHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFjdGl2ZSBncm91cHMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWN0aXZlR3JvdXBzKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuYWN0aXZlR3JvdXBzKTtcclxuICB9XHJcbn0iXX0=
|