@kolektor/nucleus-notifications 0.0.8-pre.5676 → 0.0.9-pre.5874
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/{esm2015/kolektor-nucleus-notifications.js → esm2020/kolektor-nucleus-notifications.mjs} +0 -0
- package/{esm2015/lib/models.js → esm2020/lib/models.mjs} +0 -0
- package/{esm2015/lib/nucleus-notifications.module.js → esm2020/lib/nucleus-notifications.module.mjs} +4 -4
- package/esm2020/lib/nucleus-notifications.service.mjs +356 -0
- package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
- package/fesm2015/{kolektor-nucleus-notifications.js → kolektor-nucleus-notifications.mjs} +10 -11
- package/fesm2015/kolektor-nucleus-notifications.mjs.map +1 -0
- package/fesm2020/kolektor-nucleus-notifications.mjs +406 -0
- package/fesm2020/kolektor-nucleus-notifications.mjs.map +1 -0
- package/package.json +23 -10
- package/bundles/kolektor-nucleus-notifications.umd.js +0 -894
- package/bundles/kolektor-nucleus-notifications.umd.js.map +0 -1
- package/esm2015/lib/nucleus-notifications.service.js +0 -361
- package/fesm2015/kolektor-nucleus-notifications.js.map +0 -1
package/{esm2015/kolektor-nucleus-notifications.js → esm2020/kolektor-nucleus-notifications.mjs}
RENAMED
|
File without changes
|
|
File without changes
|
package/{esm2015/lib/nucleus-notifications.module.js → esm2020/lib/nucleus-notifications.module.mjs}
RENAMED
|
@@ -11,10 +11,10 @@ export class NucleusNotificationsModule {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
NucleusNotificationsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
15
|
-
NucleusNotificationsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "
|
|
16
|
-
NucleusNotificationsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
17
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
14
|
+
NucleusNotificationsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
15
|
+
NucleusNotificationsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule });
|
|
16
|
+
NucleusNotificationsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule, imports: [[]] });
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule, decorators: [{
|
|
18
18
|
type: NgModule,
|
|
19
19
|
args: [{
|
|
20
20
|
declarations: [],
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { SwPush } from '@angular/service-worker';
|
|
4
|
+
import { PushNotifications } from '@capacitor/push-notifications';
|
|
5
|
+
import { NucleusAppService } from '@kolektor/nucleus-common';
|
|
6
|
+
import { of, Subject } from 'rxjs';
|
|
7
|
+
import { NucleusNotificationsConfig } from './models';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/common/http";
|
|
10
|
+
import * as i2 from "@angular/service-worker";
|
|
11
|
+
import * as i3 from "@kolektor/nucleus-common";
|
|
12
|
+
import * as i4 from "./models";
|
|
13
|
+
export class NucleusNotificationsService {
|
|
14
|
+
constructor(http, swPush, appService, config) {
|
|
15
|
+
this.http = http;
|
|
16
|
+
this.swPush = swPush;
|
|
17
|
+
this.appService = appService;
|
|
18
|
+
this.apiUrl = null;
|
|
19
|
+
this.registrationStorageKey = 'NucleusNotificationsRegistrationId';
|
|
20
|
+
this.notificationsStorageKey = 'NucleusNotificationsLocalCache';
|
|
21
|
+
this._isInitialized = false;
|
|
22
|
+
this._newNotifications = new Subject();
|
|
23
|
+
this._clicksSubject = new Subject();
|
|
24
|
+
this._stateChangesSubject = new Subject();
|
|
25
|
+
this.notifications = [];
|
|
26
|
+
let url = config.serverApiUrl;
|
|
27
|
+
if (!url.endsWith('/')) {
|
|
28
|
+
url += '/';
|
|
29
|
+
}
|
|
30
|
+
this.apiUrl = url;
|
|
31
|
+
}
|
|
32
|
+
get unreadCount() {
|
|
33
|
+
return this.notifications.filter(x => !x.isRead).length;
|
|
34
|
+
}
|
|
35
|
+
get newNotifications() {
|
|
36
|
+
return this._newNotifications.asObservable();
|
|
37
|
+
}
|
|
38
|
+
get clicks() {
|
|
39
|
+
return this._clicksSubject.asObservable();
|
|
40
|
+
}
|
|
41
|
+
get stateChanges() {
|
|
42
|
+
return this._stateChangesSubject.asObservable();
|
|
43
|
+
}
|
|
44
|
+
get isInitialized() {
|
|
45
|
+
return this._isInitialized;
|
|
46
|
+
}
|
|
47
|
+
async initialize() {
|
|
48
|
+
// make sure app service has finished initializing
|
|
49
|
+
await this.appService.init();
|
|
50
|
+
this.loadFromStorage();
|
|
51
|
+
if (this.appService.isNative) {
|
|
52
|
+
this._platform = this.appService.deviceInfo.platform;
|
|
53
|
+
await this.registerCapacitorEvents();
|
|
54
|
+
}
|
|
55
|
+
else if (this.swPush.isEnabled) {
|
|
56
|
+
this._platform = 'web';
|
|
57
|
+
this.registerWebPushEvents();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.warn('Nucleus.Notifications: There is no push capability, timer will be used to update notifications');
|
|
61
|
+
setInterval(() => {
|
|
62
|
+
console.log('Updating notifications...');
|
|
63
|
+
this.refresh(true);
|
|
64
|
+
}, 5 * 60 * 1000);
|
|
65
|
+
}
|
|
66
|
+
this._isInitialized = true;
|
|
67
|
+
this.refresh();
|
|
68
|
+
}
|
|
69
|
+
register() {
|
|
70
|
+
return new Promise((_resolve, _reject) => {
|
|
71
|
+
this.getRegistrationInfo().then((info) => {
|
|
72
|
+
this.http.post(this.apiUrl + 'registration', info).subscribe((regResult) => {
|
|
73
|
+
window.localStorage.setItem(this.registrationStorageKey, regResult.id);
|
|
74
|
+
_resolve(null);
|
|
75
|
+
}, error => {
|
|
76
|
+
console.log('Nucleus.Notifications: Failed to send notification registration to server.', error);
|
|
77
|
+
_reject(error);
|
|
78
|
+
});
|
|
79
|
+
}).catch((error) => _reject(error));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
unregister() {
|
|
83
|
+
return new Promise((_resolve, _reject) => {
|
|
84
|
+
this.getRegistrationInfo().then((info) => {
|
|
85
|
+
this.http.request('DELETE', this.apiUrl + 'registration', { body: info }).subscribe(() => {
|
|
86
|
+
window.localStorage.removeItem(this.registrationStorageKey);
|
|
87
|
+
_resolve(null);
|
|
88
|
+
}, error => {
|
|
89
|
+
console.log('Nucleus.Notifications: Failed to remove registration from server.', error);
|
|
90
|
+
_reject(error);
|
|
91
|
+
});
|
|
92
|
+
}).catch((error) => _reject(error));
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
refresh(notifyAboutNew = false) {
|
|
96
|
+
this.http.get(this.apiUrl + 'notifications').subscribe(res => {
|
|
97
|
+
this.updateNotifications(res, notifyAboutNew);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
getNotification(id) {
|
|
101
|
+
const localNotification = this.notifications.find(x => x.id === id);
|
|
102
|
+
if (localNotification) {
|
|
103
|
+
return of(localNotification);
|
|
104
|
+
}
|
|
105
|
+
return this.http.get(this.apiUrl + 'notifications/' + id);
|
|
106
|
+
}
|
|
107
|
+
readNotification(id) {
|
|
108
|
+
const n = this.notifications.find(x => x.id === id);
|
|
109
|
+
if (n && !n.isRead) {
|
|
110
|
+
n.isRead = true;
|
|
111
|
+
this.notifyStateChanged();
|
|
112
|
+
}
|
|
113
|
+
this.http.get(this.apiUrl + 'notifications/read/' + id).subscribe();
|
|
114
|
+
}
|
|
115
|
+
dismissNotification(id) {
|
|
116
|
+
this.deleteNotificaton(id);
|
|
117
|
+
this.http.delete(this.apiUrl + 'notifications/' + id).subscribe();
|
|
118
|
+
this.removeDeliveredNotification(id);
|
|
119
|
+
}
|
|
120
|
+
dismissAll() {
|
|
121
|
+
this.notifications.splice(0);
|
|
122
|
+
this.notifyStateChanged();
|
|
123
|
+
this.http.delete(this.apiUrl + 'notifications/all').subscribe();
|
|
124
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
125
|
+
PushNotifications.removeAllDeliveredNotifications();
|
|
126
|
+
}
|
|
127
|
+
else if (this._platform === 'web') {
|
|
128
|
+
// TODO: remove all web push notifications
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
readAll() {
|
|
132
|
+
for (const n of this.notifications) {
|
|
133
|
+
n.isRead = true;
|
|
134
|
+
}
|
|
135
|
+
this.notifyStateChanged();
|
|
136
|
+
this.http.get(this.apiUrl + 'notifications/read/all').subscribe();
|
|
137
|
+
}
|
|
138
|
+
getChannelConfig(senderId, channelId, language = null) {
|
|
139
|
+
return this.http.get(this.apiUrl + `settings/channel/${senderId}/${channelId}?language=${language}`);
|
|
140
|
+
}
|
|
141
|
+
getChannelConfigsForSender(senderId, channelIds, language = null) {
|
|
142
|
+
const idsStr = channelIds.map(x => senderId + ',' + x).join(';');
|
|
143
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
144
|
+
}
|
|
145
|
+
getChannelConfigs(ids, language = null) {
|
|
146
|
+
const idsStr = ids.map(x => x.senderId + ',' + x.channelId).join(';');
|
|
147
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
148
|
+
}
|
|
149
|
+
setChannelConfig(senderId, config) {
|
|
150
|
+
return this.http.post(`${this.apiUrl}settings/channel/${senderId}`, config);
|
|
151
|
+
}
|
|
152
|
+
setChannelConfigs(configs) {
|
|
153
|
+
return this.http.post(`${this.apiUrl}settings/channels`, configs);
|
|
154
|
+
}
|
|
155
|
+
getChannelConfigsInternal(ids, language) {
|
|
156
|
+
return this.http.get(`${this.apiUrl}settings/channels?ids=${ids}&language=${language}`);
|
|
157
|
+
}
|
|
158
|
+
updateNotifications(newNotifications, notifyAboutNew = false) {
|
|
159
|
+
let stateChanged = false;
|
|
160
|
+
for (const n of newNotifications) {
|
|
161
|
+
const existing = this.notifications.find(x => x.id === n.id);
|
|
162
|
+
if (existing) {
|
|
163
|
+
if (existing.isRead !== n.isRead) {
|
|
164
|
+
existing.isRead = n.isRead;
|
|
165
|
+
stateChanged = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
let i = 0;
|
|
170
|
+
while (i < this.notifications.length && n.dateCreated < this.notifications[i].dateCreated) {
|
|
171
|
+
i++;
|
|
172
|
+
}
|
|
173
|
+
this.notifications.splice(i, 0, n);
|
|
174
|
+
stateChanged = true;
|
|
175
|
+
if (notifyAboutNew) {
|
|
176
|
+
this._newNotifications.next(n);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const now = Date.now();
|
|
181
|
+
for (let i = this.notifications.length - 1; i >= 0; i--) {
|
|
182
|
+
const n = this.notifications[i];
|
|
183
|
+
if (new Date(n.expirationDate).getTime() < now || !newNotifications.find(x => x.id === n.id)) {
|
|
184
|
+
this.notifications.splice(i, 1);
|
|
185
|
+
stateChanged = true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (stateChanged) {
|
|
189
|
+
this.notifyStateChanged();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
saveToStorage() {
|
|
193
|
+
const str = JSON.stringify(this.notifications);
|
|
194
|
+
window.localStorage.setItem(this.notificationsStorageKey, str);
|
|
195
|
+
}
|
|
196
|
+
loadFromStorage() {
|
|
197
|
+
try {
|
|
198
|
+
const str = window.localStorage.getItem(this.notificationsStorageKey);
|
|
199
|
+
if (str) {
|
|
200
|
+
const notifications = JSON.parse(str);
|
|
201
|
+
this.notifications = notifications.filter(x => !!x);
|
|
202
|
+
// precaution for notification.isRead of undefined error
|
|
203
|
+
this.notifyStateChanged(false);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch { }
|
|
207
|
+
}
|
|
208
|
+
handleNotificationEvent(id, eventType) {
|
|
209
|
+
if (eventType.startsWith('new') || eventType === 'updated') { // we are handling new and newSilent
|
|
210
|
+
this.getNotification(id).subscribe(n => {
|
|
211
|
+
if (eventType.startsWith('new') && !n.isRead) {
|
|
212
|
+
this._newNotifications.next(n);
|
|
213
|
+
}
|
|
214
|
+
const existing = this.notifications.find(x => x.id === n.id);
|
|
215
|
+
if (existing) {
|
|
216
|
+
existing.isRead = n.isRead;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this.notifications.splice(0, 0, n);
|
|
220
|
+
}
|
|
221
|
+
this.notifyStateChanged();
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else if (eventType === 'deleted') {
|
|
225
|
+
this.deleteNotificaton(id);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
this.refresh();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
deleteNotificaton(id) {
|
|
232
|
+
const i = this.notifications.findIndex(x => x.id === id);
|
|
233
|
+
if (i >= 0) {
|
|
234
|
+
this.notifications.splice(i, 1);
|
|
235
|
+
this.notifyStateChanged();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
notifyStateChanged(persistState = true) {
|
|
239
|
+
if (persistState) {
|
|
240
|
+
this.saveToStorage();
|
|
241
|
+
}
|
|
242
|
+
this._stateChangesSubject.next();
|
|
243
|
+
}
|
|
244
|
+
handleNotificationAction(notificationAction) {
|
|
245
|
+
const arr = notificationAction.split(':');
|
|
246
|
+
const notificationClick = {
|
|
247
|
+
id: arr[0],
|
|
248
|
+
type: arr[1],
|
|
249
|
+
routerLink: arr[2]
|
|
250
|
+
};
|
|
251
|
+
const validNotificationClickTypes = ['default', 'deeplink'];
|
|
252
|
+
if (validNotificationClickTypes.includes(notificationClick.type)) {
|
|
253
|
+
this._clicksSubject.next(notificationClick);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
console.error(`Nucleus.Notifications: Unknown notification action: '${notificationAction}'.`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
removeDeliveredNotification(id) {
|
|
260
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
261
|
+
PushNotifications.getDeliveredNotifications().then(list => {
|
|
262
|
+
const toRemove = list.notifications.filter(n => {
|
|
263
|
+
const data = this.getNotificationPayloadData(n);
|
|
264
|
+
return (data.notificationId === id);
|
|
265
|
+
});
|
|
266
|
+
// TODO: On Android this does not currently work because notificationID is not set.
|
|
267
|
+
// This my solve the issue: https://github.com/ionic-team/capacitor/pull/3523
|
|
268
|
+
PushNotifications.removeDeliveredNotifications({
|
|
269
|
+
notifications: toRemove
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
else if (this._platform === 'web') {
|
|
274
|
+
// TODO: remove web push notification
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
getNotificationPayloadData(pushNotification) {
|
|
278
|
+
return (this._platform === 'ios') ? pushNotification.data.data : pushNotification.data;
|
|
279
|
+
}
|
|
280
|
+
async registerCapacitorEvents() {
|
|
281
|
+
await PushNotifications.addListener('pushNotificationReceived', n => {
|
|
282
|
+
const data = this.getNotificationPayloadData(n);
|
|
283
|
+
console.log('Nucleus.Notifications: Received capacitor push event: ' + data.eventType, n);
|
|
284
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
285
|
+
});
|
|
286
|
+
await PushNotifications.addListener('pushNotificationActionPerformed', a => {
|
|
287
|
+
let action = a.notification.data.notificationAction;
|
|
288
|
+
if (this._platform === 'ios') {
|
|
289
|
+
action = a.notification.data.data.notificationAction;
|
|
290
|
+
}
|
|
291
|
+
console.log('Nucleus.Notifications: Received capacitor action event', action);
|
|
292
|
+
this.handleNotificationAction(action);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
registerWebPushEvents() {
|
|
296
|
+
this.swPush.messages.subscribe((n) => {
|
|
297
|
+
const data = n.data;
|
|
298
|
+
console.log('Nucleus.Notifications: Received WebPush event: ' + data.eventType, n);
|
|
299
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
300
|
+
});
|
|
301
|
+
this.swPush.notificationClicks.subscribe((action) => {
|
|
302
|
+
console.log('Nucleus.Notifications: Received WebPush action event', action);
|
|
303
|
+
const tag = action.notification.tag;
|
|
304
|
+
this.handleNotificationAction(tag);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
getRegistrationInfo() {
|
|
308
|
+
return new Promise((_resolve, _reject) => {
|
|
309
|
+
const registrationId = window.localStorage.getItem(this.registrationStorageKey);
|
|
310
|
+
if (this._platform === 'android' || this._platform === 'ios') {
|
|
311
|
+
// capacitor platform
|
|
312
|
+
const listener = PushNotifications.addListener('registration', token => {
|
|
313
|
+
listener.remove();
|
|
314
|
+
_resolve({ id: registrationId, token: token.value, platform: this._platform });
|
|
315
|
+
});
|
|
316
|
+
PushNotifications.register().catch(error => _reject('Could not register for notifications:' + error));
|
|
317
|
+
}
|
|
318
|
+
else if (this._platform === 'web') {
|
|
319
|
+
// Web Push API
|
|
320
|
+
this.http.get(this.apiUrl + 'registration/webkey').subscribe(key => {
|
|
321
|
+
this.getWebPushSubscription(key.publicKey).then(subscription => {
|
|
322
|
+
const t = JSON.stringify(subscription.toJSON());
|
|
323
|
+
_resolve({ id: registrationId, token: t, platform: 'web' });
|
|
324
|
+
});
|
|
325
|
+
}, error => _reject(error));
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
_reject(`Nucleus.Notifications: Platform is not supported`);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
getWebPushSubscription(publicKey) {
|
|
333
|
+
return new Promise((_resolve, _reject) => {
|
|
334
|
+
this.swPush.subscription.subscribe(subscription => {
|
|
335
|
+
if (subscription != null) {
|
|
336
|
+
_resolve(subscription);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
this.swPush.requestSubscription({ serverPublicKey: publicKey }).then(s => _resolve(s)).catch(e => _reject(e));
|
|
340
|
+
}
|
|
341
|
+
}, error => {
|
|
342
|
+
console.error('Nucleus.Notifications: Cannot get web push subscription', error);
|
|
343
|
+
_reject(error);
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
NucleusNotificationsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsService, deps: [{ token: i1.HttpClient }, { token: i2.SwPush }, { token: i3.NucleusAppService }, { token: i4.NucleusNotificationsConfig }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
349
|
+
NucleusNotificationsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsService, providedIn: 'root' });
|
|
350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsService, decorators: [{
|
|
351
|
+
type: Injectable,
|
|
352
|
+
args: [{
|
|
353
|
+
providedIn: 'root'
|
|
354
|
+
}]
|
|
355
|
+
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.SwPush }, { type: i3.NucleusAppService }, { type: i4.NucleusNotificationsConfig }]; } });
|
|
356
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9udWNsZXVzLW5vdGlmaWNhdGlvbnMvc3JjL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakQsT0FBTyxFQUFFLGlCQUFpQixFQUEwQixNQUFNLCtCQUErQixDQUFDO0FBQzFGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzdELE9BQU8sRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFNTCwwQkFBMEIsRUFPM0IsTUFBTSxVQUFVLENBQUM7Ozs7OztBQUtsQixNQUFNLE9BQU8sMkJBQTJCO0lBRXRDLFlBQ1UsSUFBZ0IsRUFDaEIsTUFBYyxFQUNkLFVBQTZCLEVBQ3JDLE1BQWtDO1FBSDFCLFNBQUksR0FBSixJQUFJLENBQVk7UUFDaEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGVBQVUsR0FBVixVQUFVLENBQW1CO1FBVS9CLFdBQU0sR0FBRyxJQUFJLENBQUM7UUFDTCwyQkFBc0IsR0FBRyxvQ0FBb0MsQ0FBQztRQUM5RCw0QkFBdUIsR0FBRyxnQ0FBZ0MsQ0FBQztRQUVwRSxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUN2QixzQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBZ0IsQ0FBQztRQUNoRCxtQkFBYyxHQUFHLElBQUksT0FBTyxFQUFxQixDQUFDO1FBQ2xELHlCQUFvQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFNUMsa0JBQWEs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Q0FBQzthQUM3RDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHNCQUFzQixDQUFDLFNBQWlCO1FBQzlDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNoRCxJQUFJLFlBQVksSUFBSSxJQUFJLEVBQUU7b0JBQ3hCLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztpQkFDeEI7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUMvRztZQUNILENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDVCxPQUFPLENBQUMsS0FBSyxDQUFDLHlEQUF5RCxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNoRixPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7O3dIQTlXVSwyQkFBMkI7NEhBQTNCLDJCQUEyQixjQUYxQixNQUFNOzJGQUVQLDJCQUEyQjtrQkFIdkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN3UHVzaCB9IGZyb20gJ0Bhbmd1bGFyL3NlcnZpY2Utd29ya2VyJztcclxuaW1wb3J0IHsgUHVzaE5vdGlmaWNhdGlvbnMsIFB1c2hOb3RpZmljYXRpb25TY2hlbWEgfSBmcm9tICdAY2FwYWNpdG9yL3B1c2gtbm90aWZpY2F0aW9ucyc7XHJcbmltcG9ydCB7IE51Y2xldXNBcHBTZXJ2aWNlIH0gZnJvbSAnQGtvbGVrdG9yL251Y2xldXMtY29tbW9uJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtcclxuICBDaGFubmVsSWQsXHJcbiAgTm90aWZpY2F0aW9uLFxyXG4gIE5vdGlmaWNhdGlvbkNsaWNrLFxyXG4gIE5vdGlmaWNhdGlvbkV2ZW50VHlwZSxcclxuICBOb3RpZmljYXRpb25UeXBlLFxyXG4gIE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnLFxyXG4gIFBheWxvYWREYXRhLFxyXG4gIFBsYXRmb3JtVmFsdWUsXHJcbiAgUmVnaXN0cmF0aW9uLFxyXG4gIFJlZ2lzdHJhdGlvblJlc3VsdCxcclxuICBVc2VyQ2hhbm5lbENvbmZpZyxcclxuICBXZWJLZXlcclxufSBmcm9tICcuL21vZGVscyc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOdWNsZXVzTm90aWZpY2F0aW9uc1NlcnZpY2Uge1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgc3dQdXNoOiBTd1B1c2gsXHJcbiAgICBwcml2YXRlIGFwcFNlcnZpY2U6IE51Y2xldXNBcHBTZXJ2aWNlLFxyXG4gICAgY29uZmlnOiBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZ1xyXG4gICkge1xyXG4gICAgbGV0IHVybCA9IGNvbmZpZy5zZXJ2ZXJBcGlVcmw7XHJcbiAgICBpZiAoIXVybC5lbmRzV2l0aCgnLycpKSB7XHJcbiAgICAgIHVybCArPSAnLyc7XHJcbiAgICB9XHJcbiAgICB0aGlzLmFwaVVybCA9IHVybDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXBpVXJsID0gbnVsbDtcclxuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lzdHJhdGlvblN0b3JhZ2VLZXkgPSAnTnVjbGV1c05vdGlmaWNhdGlvbnNSZWdpc3RyYXRpb25JZCc7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBub3RpZmljYXRpb25zU3RvcmFnZUtleSA9ICdOdWNsZXVzTm90aWZpY2F0aW9uc0xvY2FsQ2FjaGUnO1xyXG4gIHByaXZhdGUgX3BsYXRmb3JtOiBQbGF0Zm9ybVZhbHVlO1xyXG4gIHByaXZhdGUgX2lzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcclxuICBwcml2YXRlIF9uZXdOb3RpZmljYXRpb25zID0gbmV3IFN1YmplY3Q8Tm90aWZpY2F0aW9uPigpO1xyXG4gIHByaXZhdGUgX2NsaWNrc1N1YmplY3QgPSBuZXcgU3ViamVjdDxOb3RpZmljYXRpb25DbGljaz4oKTtcclxuICBwcml2YXRlIF9zdGF0ZUNoYW5nZXNTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgcHVibGljIG5vdGlmaWNhdGlvbnM6IE5vdGlmaWNhdGlvbltdID0gW107XHJcblxyXG4gIHB1YmxpYyBnZXQgdW5yZWFkQ291bnQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5ub3RpZmljYXRpb25zLmZpbHRlcih4ID0+ICF4LmlzUmVhZCkubGVuZ3RoO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBuZXdOb3RpZmljYXRpb25zKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX25ld05vdGlmaWNhdGlvbnMuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGNsaWNrcygpIHtcclxuICAgIHJldHVybiB0aGlzLl9jbGlja3NTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xyXG4gIH1cclxuICBwdWJsaWMgZ2V0IHN0YXRlQ2hhbmdlcygpIHtcclxuICAgIHJldHVybiB0aGlzLl9zdGF0ZUNoYW5nZXNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBpc0luaXRpYWxpemVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lzSW5pdGlhbGl6ZWQ7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgaW5pdGlhbGl6ZSgpIHtcclxuICAgIC8vIG1ha2Ugc3VyZSBhcHAgc2VydmljZSBoYXMgZmluaXNoZWQgaW5pdGlhbGl6aW5nXHJcbiAgICBhd2FpdCB0aGlzLmFwcFNlcnZpY2UuaW5pdCgpO1xyXG5cclxuICAgIHRoaXMubG9hZEZyb21TdG9yYWdlKCk7XHJcblxyXG4gICAgaWYgKHRoaXMuYXBwU2VydmljZS5pc05hdGl2ZSkge1xyXG4gICAgICB0aGlzLl9wbGF0Zm9ybSA9IHRoaXMuYXBwU2VydmljZS5kZXZpY2VJbmZvLnBsYXRmb3JtIGFzIFBsYXRmb3JtVmFsdWU7XHJcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJDYXBhY2l0b3JFdmVudHMoKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5zd1B1c2guaXNFbmFibGVkKSB7XHJcbiAgICAgIHRoaXMuX3BsYXRmb3JtID0gJ3dlYic7XHJcbiAgICAgIHRoaXMucmVnaXN0ZXJXZWJQdXNoRXZlbnRzKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zb2xlLndhcm4oJ051Y2xldXMuTm90aWZpY2F0aW9uczogVGhlcmUgaXMgbm8gcHVzaCBjYXBhYmlsaXR5LCB0aW1lciB3aWxsIGJlIHVzZWQgdG8gdXBkYXRlIG5vdGlmaWNhdGlvbnMnKTtcclxuICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdVcGRhdGluZyBub3RpZmljYXRpb25zLi4uJyk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoKHRydWUpO1xyXG4gICAgICB9LCA1ICogNjAgKiAxMDAwKTtcclxuICAgIH1cclxuICAgIHRoaXMuX2lzSW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5yZWZyZXNoKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcmVnaXN0ZXIoKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcclxuICAgICAgdGhpcy5nZXRSZWdpc3RyYXRpb25JbmZvKCkudGhlbigoaW5mbykgPT4ge1xyXG4gICAgICAgIHRoaXMuaHR0cC5wb3N0PFJlZ2lzdHJhdGlvblJlc3VsdD4odGhpcy5hcGlVcmwgKyAncmVnaXN0cmF0aW9uJywgaW5mbykuc3Vic2NyaWJlKChyZWdSZXN1bHQpID0+IHtcclxuICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLnJlZ2lzdHJhdGlvblN0b3JhZ2VLZXksIHJlZ1Jlc3VsdC5pZCk7XHJcbiAgICAgICAgICBfcmVzb2x2ZShudWxsKTtcclxuICAgICAgICB9LCBlcnJvciA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBGYWlsZWQgdG8gc2VuZCBub3RpZmljYXRpb24gcmVnaXN0cmF0aW9uIHRvIHNlcnZlci4nLCBlcnJvcik7XHJcbiAgICAgICAgICBfcmVqZWN0KGVycm9yKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiBfcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB1bnJlZ2lzdGVyKCk6IFByb21pc2U8YW55PiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XHJcbiAgICAgIHRoaXMuZ2V0UmVnaXN0cmF0aW9uSW5mbygpLnRoZW4oKGluZm8pID0+IHtcclxuICAgICAgICB0aGlzLmh0dHAucmVxdWVzdDxhbnk+KCdERUxFVEUnLCB0aGlzLmFwaVVybCArICdyZWdpc3RyYXRpb24nLCB7IGJvZHk6IGluZm8gfSkuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSh0aGlzLnJlZ2lzdHJhdGlvblN0b3JhZ2VLZXkpO1xyXG4gICAgICAgICAgX3Jlc29sdmUobnVsbCk7XHJcbiAgICAgICAgfSwgZXJyb3IgPT4ge1xyXG4gICAgICAgICAgY29uc29sZS5sb2coJ051Y2xldXMuTm90aWZpY2F0aW9uczogRmFpbGVkIHRvIHJlbW92ZSByZWdpc3RyYXRpb24gZnJvbSBzZXJ2ZXIuJywgZXJyb3IpO1xyXG4gICAgICAgICAgX3JlamVjdChlcnJvcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gX3JlamVjdChlcnJvcikpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcmVmcmVzaChub3RpZnlBYm91dE5ldyA9IGZhbHNlKSB7XHJcbiAgICB0aGlzLmh0dHAuZ2V0PE5vdGlmaWNhdGlvbltdPih0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zJykuc3Vic2NyaWJlKHJlcyA9PiB7XHJcbiAgICAgIHRoaXMudXBkYXRlTm90aWZpY2F0aW9ucyhyZXMsIG5vdGlmeUFib3V0TmV3KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldE5vdGlmaWNhdGlvbihpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxOb3RpZmljYXRpb24+IHtcclxuICAgIGNvbnN0IGxvY2FsTm90aWZpY2F0aW9uID0gdGhpcy5ub3RpZmljYXRpb25zLmZpbmQoeCA9PiB4LmlkID09PSBpZCk7XHJcbiAgICBpZiAobG9jYWxOb3RpZmljYXRpb24pIHtcclxuICAgICAgcmV0dXJuIG9mKGxvY2FsTm90aWZpY2F0aW9uKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5vdGlmaWNhdGlvbj4odGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucy8nICsgaWQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlYWROb3RpZmljYXRpb24oaWQ6IHN0cmluZykge1xyXG4gICAgY29uc3QgbiA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKHggPT4geC5pZCA9PT0gaWQpO1xyXG4gICAgaWYgKG4gJiYgIW4uaXNSZWFkKSB7XHJcbiAgICAgIG4uaXNSZWFkID0gdHJ1ZTtcclxuICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcclxuICAgIH1cclxuICAgIHRoaXMuaHR0cC5nZXQodGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucy9yZWFkLycgKyBpZCkuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZGlzbWlzc05vdGlmaWNhdGlvbihpZDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLmRlbGV0ZU5vdGlmaWNhdG9uKGlkKTtcclxuICAgIHRoaXMuaHR0cC5kZWxldGUodGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucy8nICsgaWQpLnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5yZW1vdmVEZWxpdmVyZWROb3RpZmljYXRpb24oaWQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRpc21pc3NBbGwoKSB7XHJcbiAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKDApO1xyXG4gICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcclxuICAgIHRoaXMuaHR0cC5kZWxldGUodGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucy9hbGwnKS5zdWJzY3JpYmUoKTtcclxuICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycgfHwgdGhpcy5fcGxhdGZvcm0gPT09ICdhbmRyb2lkJykge1xyXG4gICAgICBQdXNoTm90aWZpY2F0aW9ucy5yZW1vdmVBbGxEZWxpdmVyZWROb3RpZmljYXRpb25zKCk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnd2ViJykge1xyXG4gICAgICAvLyBUT0RPOiByZW1vdmUgYWxsIHdlYiBwdXNoIG5vdGlmaWNhdGlvbnNcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyByZWFkQWxsKCkge1xyXG4gICAgZm9yIChjb25zdCBuIG9mIHRoaXMubm90aWZpY2F0aW9ucykge1xyXG4gICAgICBuLmlzUmVhZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLm5vdGlmeVN0YXRlQ2hhbmdlZCgpO1xyXG4gICAgdGhpcy5odHRwLmdldCh0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zL3JlYWQvYWxsJykuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0Q2hhbm5lbENvbmZpZyhzZW5kZXJJZDogc3RyaW5nLCBjaGFubmVsSWQ6IHN0cmluZywgbGFuZ3VhZ2U6IHN0cmluZyA9IG51bGwpIHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFVzZXJDaGFubmVsQ29uZmlnPih0aGlzLmFwaVVybCArIGBzZXR0aW5ncy9jaGFubmVsLyR7c2VuZGVySWR9LyR7Y2hhbm5lbElkfT9sYW5ndWFnZT0ke2xhbmd1YWdlfWApO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldENoYW5uZWxDb25maWdzRm9yU2VuZGVyKHNlbmRlcklkOiBzdHJpbmcsIGNoYW5uZWxJZHM6IHN0cmluZ1tdLCBsYW5ndWFnZTogc3RyaW5nID0gbnVsbCkge1xyXG4gICAgY29uc3QgaWRzU3RyID0gY2hhbm5lbElkcy5tYXAoeCA9PiBzZW5kZXJJZCArICcsJyArIHgpLmpvaW4oJzsnKTtcclxuICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxDb25maWdzSW50ZXJuYWwoaWRzU3RyLCBsYW5ndWFnZSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0Q2hhbm5lbENvbmZpZ3MoaWRzOiBDaGFubmVsSWRbXSwgbGFuZ3VhZ2U6IHN0cmluZyA9IG51bGwpIHtcclxuICAgIGNvbnN0IGlkc1N0ciA9IGlkcy5tYXAoeCA9PiB4LnNlbmRlcklkICsgJywnICsgeC5jaGFubmVsSWQpLmpvaW4oJzsnKTtcclxuICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxDb25maWdzSW50ZXJuYWwoaWRzU3RyLCBsYW5ndWFnZSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0Q2hhbm5lbENvbmZpZyhzZW5kZXJJZDogc3RyaW5nLCBjb25maWc6IFVzZXJDaGFubmVsQ29uZmlnKSB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8dm9pZD4oYCR7dGhpcy5hcGlVcmx9c2V0dGluZ3MvY2hhbm5lbC8ke3NlbmRlcklkfWAsIGNvbmZpZyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0Q2hhbm5lbENvbmZpZ3MoY29uZmlnczogVXNlckNoYW5uZWxDb25maWdbXSkge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PHZvaWQ+KGAke3RoaXMuYXBpVXJsfXNldHRpbmdzL2NoYW5uZWxzYCwgY29uZmlncyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldENoYW5uZWxDb25maWdzSW50ZXJuYWwoaWRzOiBzdHJpbmcsIGxhbmd1YWdlOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFVzZXJDaGFubmVsQ29uZmlnW10+KGAke3RoaXMuYXBpVXJsfXNldHRpbmdzL2NoYW5uZWxzP2lkcz0ke2lkc30mbGFuZ3VhZ2U9JHtsYW5ndWFnZX1gKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlTm90aWZpY2F0aW9ucyhuZXdOb3RpZmljYXRpb25zOiBOb3RpZmljYXRpb25bXSwgbm90aWZ5QWJvdXROZXcgPSBmYWxzZSkge1xyXG4gICAgbGV0IHN0YXRlQ2hhbmdlZCA9IGZhbHNlO1xyXG4gICAgZm9yIChjb25zdCBuIG9mIG5ld05vdGlmaWNhdGlvbnMpIHtcclxuICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLm5vdGlmaWNhdGlvbnMuZmluZCh4ID0+IHguaWQgPT09IG4uaWQpO1xyXG4gICAgICBpZiAoZXhpc3RpbmcpIHtcclxuICAgICAgICBpZiAoZXhpc3RpbmcuaXNSZWFkICE9PSBuLmlzUmVhZCkge1xyXG4gICAgICAgICAgZXhpc3RpbmcuaXNSZWFkID0gbi5pc1JlYWQ7XHJcbiAgICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsZXQgaSA9IDA7XHJcbiAgICAgICAgd2hpbGUgKGkgPCB0aGlzLm5vdGlmaWNhdGlvbnMubGVuZ3RoICYmIG4uZGF0ZUNyZWF0ZWQgPCB0aGlzLm5vdGlmaWNhdGlvbnNbaV0uZGF0ZUNyZWF0ZWQpIHtcclxuICAgICAgICAgIGkrKztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5ub3RpZmljYXRpb25zLnNwbGljZShpLCAwLCBuKTtcclxuICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICAgIGlmIChub3RpZnlBYm91dE5ldykge1xyXG4gICAgICAgICAgdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5uZXh0KG4pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XHJcbiAgICBmb3IgKGxldCBpID0gdGhpcy5ub3RpZmljYXRpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgIGNvbnN0IG4gPSB0aGlzLm5vdGlmaWNhdGlvbnNbaV07XHJcbiAgICAgIGlmIChuZXcgRGF0ZShuLmV4cGlyYXRpb25EYXRlKS5nZXRUaW1lKCkgPCBub3cgfHwgIW5ld05vdGlmaWNhdGlvbnMuZmluZCh4ID0+IHguaWQgPT09IG4uaWQpKSB7XHJcbiAgICAgICAgdGhpcy5ub3RpZmljYXRpb25zLnNwbGljZShpLCAxKTtcclxuICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHN0YXRlQ2hhbmdlZCkge1xyXG4gICAgICB0aGlzLm5vdGlmeVN0YXRlQ2hhbmdlZCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzYXZlVG9TdG9yYWdlKCkge1xyXG4gICAgY29uc3Qgc3RyID0gSlNPTi5zdHJpbmdpZnkodGhpcy5ub3RpZmljYXRpb25zKTtcclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLm5vdGlmaWNhdGlvbnNTdG9yYWdlS2V5LCBzdHIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBsb2FkRnJvbVN0b3JhZ2UoKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCBzdHIgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5ub3RpZmljYXRpb25zU3RvcmFnZUtleSk7XHJcbiAgICAgIGlmIChzdHIpIHtcclxuICAgICAgICBjb25zdCBub3RpZmljYXRpb25zID0gSlNPTi5wYXJzZShzdHIpIGFzIE5vdGlmaWNhdGlvbltdO1xyXG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9ucyA9IG5vdGlmaWNhdGlvbnMuZmlsdGVyKHggPT4gISF4KTtcclxuICAgICAgICAvLyBwcmVjYXV0aW9uIGZvciBub3RpZmljYXRpb24uaXNSZWFkIG9mIHVuZGVmaW5lZCBlcnJvclxyXG4gICAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKGZhbHNlKTtcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCB7IH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoaWQ6IHN0cmluZywgZXZlbnRUeXBlOiBOb3RpZmljYXRpb25FdmVudFR5cGUpIHtcclxuICAgIGlmIChldmVudFR5cGUuc3RhcnRzV2l0aCgnbmV3JykgfHwgZXZlbnRUeXBlID09PSAndXBkYXRlZCcpIHsgLy8gd2UgYXJlIGhhbmRsaW5nIG5ldyBhbmQgbmV3U2lsZW50XHJcbiAgICAgIHRoaXMuZ2V0Tm90aWZpY2F0aW9uKGlkKS5zdWJzY3JpYmUobiA9PiB7XHJcbiAgICAgICAgaWYgKGV2ZW50VHlwZS5zdGFydHNXaXRoKCduZXcnKSAmJiAhbi5pc1JlYWQpIHtcclxuICAgICAgICAgIHRoaXMuX25ld05vdGlmaWNhdGlvbnMubmV4dChuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLm5vdGlmaWNhdGlvbnMuZmluZCh4ID0+IHguaWQgPT09IG4uaWQpO1xyXG4gICAgICAgIGlmIChleGlzdGluZykge1xyXG4gICAgICAgICAgZXhpc3RpbmcuaXNSZWFkID0gbi5pc1JlYWQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9ucy5zcGxpY2UoMCwgMCwgbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmIChldmVudFR5cGUgPT09ICdkZWxldGVkJykge1xyXG4gICAgICB0aGlzLmRlbGV0ZU5vdGlmaWNhdG9uKGlkKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucmVmcmVzaCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZWxldGVOb3RpZmljYXRvbihpZDogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBpID0gdGhpcy5ub3RpZmljYXRpb25zLmZpbmRJbmRleCh4ID0+IHguaWQgPT09IGlkKTtcclxuICAgIGlmIChpID49IDApIHtcclxuICAgICAgdGhpcy5ub3RpZmljYXRpb25zLnNwbGljZShpLCAxKTtcclxuICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgbm90aWZ5U3RhdGVDaGFuZ2VkKHBlcnNpc3RTdGF0ZSA9IHRydWUpIHtcclxuICAgIGlmIChwZXJzaXN0U3RhdGUpIHtcclxuICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9zdGF0ZUNoYW5nZXNTdWJqZWN0Lm5leHQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlTm90aWZpY2F0aW9uQWN0aW9uKG5vdGlmaWNhdGlvbkFjdGlvbjogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBhcnIgPSBub3RpZmljYXRpb25BY3Rpb24uc3BsaXQoJzonKTtcclxuICAgIGNvbnN0IG5vdGlmaWNhdGlvbkNsaWNrOiBOb3RpZmljYXRpb25DbGljayA9IHtcclxuICAgICAgaWQ6IGFyclswXSxcclxuICAgICAgdHlwZTogYXJyWzFdIGFzIE5vdGlmaWNhdGlvblR5cGUsXHJcbiAgICAgIHJvdXRlckxpbms6IGFyclsyXVxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCB2YWxpZE5vdGlmaWNhdGlvbkNsaWNrVHlwZXMgPSBbJ2RlZmF1bHQnLCAnZGVlcGxpbmsnXTtcclxuICAgIGlmICh2YWxpZE5vdGlmaWNhdGlvbkNsaWNrVHlwZXMuaW5jbHVkZXMobm90aWZpY2F0aW9uQ2xpY2sudHlwZSkpIHtcclxuICAgICAgdGhpcy5fY2xpY2tzU3ViamVjdC5uZXh0KG5vdGlmaWNhdGlvbkNsaWNrKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYE51Y2xldXMuTm90aWZpY2F0aW9uczogVW5rbm93biBub3RpZmljYXRpb24gYWN0aW9uOiAnJHtub3RpZmljYXRpb25BY3Rpb259Jy5gKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9uKGlkOiBzdHJpbmcpIHtcclxuICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycgfHwgdGhpcy5fcGxhdGZvcm0gPT09ICdhbmRyb2lkJykge1xyXG4gICAgICBQdXNoTm90aWZpY2F0aW9ucy5nZXREZWxpdmVyZWROb3RpZmljYXRpb25zKCkudGhlbihsaXN0ID0+IHtcclxuICAgICAgICBjb25zdCB0b1JlbW92ZSA9IGxpc3Qubm90aWZpY2F0aW9ucy5maWx0ZXIobiA9PiB7XHJcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5nZXROb3RpZmljYXRpb25QYXlsb2FkRGF0YShuKTtcclxuICAgICAgICAgIHJldHVybiAoZGF0YS5ub3RpZmljYXRpb25JZCA9PT0gaWQpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBUT0RPOiBPbiBBbmRyb2lkIHRoaXMgZG9lcyBub3QgY3VycmVudGx5IHdvcmsgYmVjYXVzZSBub3RpZmljYXRpb25JRCBpcyBub3Qgc2V0LlxyXG4gICAgICAgIC8vIFRoaXMgbXkgc29sdmUgdGhlIGlzc3VlOiBodHRwczovL2dpdGh1Yi5jb20vaW9uaWMtdGVhbS9jYXBhY2l0b3IvcHVsbC8zNTIzXHJcbiAgICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9ucyh7XHJcbiAgICAgICAgICBub3RpZmljYXRpb25zOiB0b1JlbW92ZVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5fcGxhdGZvcm0gPT09ICd3ZWInKSB7XHJcbiAgICAgIC8vIFRPRE86IHJlbW92ZSB3ZWIgcHVzaCBub3RpZmljYXRpb25cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Tm90aWZpY2F0aW9uUGF5bG9hZERhdGEocHVzaE5vdGlmaWNhdGlvbjogUHVzaE5vdGlmaWNhdGlvblNjaGVtYSk6IFBheWxvYWREYXRhIHtcclxuICAgIHJldHVybiAodGhpcy5fcGxhdGZvcm0gPT09ICdpb3MnKSA/IHB1c2hOb3RpZmljYXRpb24uZGF0YS5kYXRhIDogcHVzaE5vdGlmaWNhdGlvbi5kYXRhO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckNhcGFjaXRvckV2ZW50cygpIHtcclxuICAgIGF3YWl0IFB1c2hOb3RpZmljYXRpb25zLmFkZExpc3RlbmVyKCdwdXNoTm90aWZpY2F0aW9uUmVjZWl2ZWQnLCBuID0+IHtcclxuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2V0Tm90aWZpY2F0aW9uUGF5bG9hZERhdGEobik7XHJcbiAgICAgIGNvbnNvbGUubG9nKCdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIGNhcGFjaXRvciBwdXNoIGV2ZW50OiAnICsgZGF0YS5ldmVudFR5cGUsIG4pO1xyXG4gICAgICB0aGlzLmhhbmRsZU5vdGlmaWNhdGlvbkV2ZW50KGRhdGEubm90aWZpY2F0aW9uSWQsIGRhdGEuZXZlbnRUeXBlKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGF3YWl0IFB1c2hOb3RpZmljYXRpb25zLmFkZExpc3RlbmVyKCdwdXNoTm90aWZpY2F0aW9uQWN0aW9uUGVyZm9ybWVkJywgYSA9PiB7XHJcbiAgICAgIGxldCBhY3Rpb24gPSAoYSBhcyBhbnkpLm5vdGlmaWNhdGlvbi5kYXRhLm5vdGlmaWNhdGlvbkFjdGlvbjtcclxuICAgICAgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnaW9zJykge1xyXG4gICAgICAgIGFjdGlvbiA9IChhIGFzIGFueSkubm90aWZpY2F0aW9uLmRhdGEuZGF0YS5ub3RpZmljYXRpb25BY3Rpb247XHJcbiAgICAgIH1cclxuICAgICAgY29uc29sZS5sb2coJ051Y2xldXMuTm90aWZpY2F0aW9uczogUmVjZWl2ZWQgY2FwYWNpdG9yIGFjdGlvbiBldmVudCcsIGFjdGlvbik7XHJcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uQWN0aW9uKGFjdGlvbik7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVnaXN0ZXJXZWJQdXNoRXZlbnRzKCkge1xyXG4gICAgdGhpcy5zd1B1c2gubWVzc2FnZXMuc3Vic2NyaWJlKChuKSA9PiB7XHJcbiAgICAgIGNvbnN0IGRhdGE6IFBheWxvYWREYXRhID0gKG4gYXMgYW55KS5kYXRhO1xyXG4gICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBSZWNlaXZlZCBXZWJQdXNoIGV2ZW50OiAnICsgZGF0YS5ldmVudFR5cGUsIG4pO1xyXG4gICAgICB0aGlzLmhhbmRsZU5vdGlmaWNhdGlvbkV2ZW50KGRhdGEubm90aWZpY2F0aW9uSWQsIGRhdGEuZXZlbnRUeXBlKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuc3dQdXNoLm5vdGlmaWNhdGlvbkNsaWNrcy5zdWJzY3JpYmUoKGFjdGlvbikgPT4ge1xyXG4gICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBSZWNlaXZlZCBXZWJQdXNoIGFjdGlvbiBldmVudCcsIGFjdGlvbik7XHJcbiAgICAgIGNvbnN0IHRhZyA9IGFjdGlvbi5ub3RpZmljYXRpb24udGFnO1xyXG4gICAgICB0aGlzLmhhbmRsZU5vdGlmaWNhdGlvbkFjdGlvbih0YWcpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFJlZ2lzdHJhdGlvbkluZm8oKTogUHJvbWlzZTxSZWdpc3RyYXRpb24+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcclxuICAgICAgY29uc3QgcmVnaXN0cmF0aW9uSWQgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5yZWdpc3RyYXRpb25TdG9yYWdlS2V5KTtcclxuICAgICAgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnYW5kcm9pZCcgfHwgdGhpcy5fcGxhdGZvcm0gPT09ICdpb3MnKSB7XHJcbiAgICAgICAgLy8gY2FwYWNpdG9yIHBsYXRmb3JtXHJcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBQdXNoTm90aWZpY2F0aW9ucy5hZGRMaXN0ZW5lcigncmVnaXN0cmF0aW9uJywgdG9rZW4gPT4ge1xyXG4gICAgICAgICAgbGlzdGVuZXIucmVtb3ZlKCk7XHJcbiAgICAgICAgICBfcmVzb2x2ZSh7IGlkOiByZWdpc3RyYXRpb25JZCwgdG9rZW46IHRva2VuLnZhbHVlLCBwbGF0Zm9ybTogdGhpcy5fcGxhdGZvcm0gfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVnaXN0ZXIoKS5jYXRjaChlcnJvciA9PiBfcmVqZWN0KCdDb3VsZCBub3QgcmVnaXN0ZXIgZm9yIG5vdGlmaWNhdGlvbnM6JyArIGVycm9yKSk7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fcGxhdGZvcm0gPT09ICd3ZWInKSB7XHJcbiAgICAgICAgLy8gV2ViIFB1c2ggQVBJXHJcbiAgICAgICAgdGhpcy5odHRwLmdldDxXZWJLZXk+KHRoaXMuYXBpVXJsICsgJ3JlZ2lzdHJhdGlvbi93ZWJrZXknKS5zdWJzY3JpYmUoa2V5ID0+IHtcclxuICAgICAgICAgIHRoaXMuZ2V0V2ViUHVzaFN1YnNjcmlwdGlvbihrZXkucHVibGljS2V5KS50aGVuKHN1YnNjcmlwdGlvbiA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHQgPSBKU09OLnN0cmluZ2lmeShzdWJzY3JpcHRpb24udG9KU09OKCkpO1xyXG4gICAgICAgICAgICBfcmVzb2x2ZSh7IGlkOiByZWdpc3RyYXRpb25JZCwgdG9rZW46IHQsIHBsYXRmb3JtOiAnd2ViJyB9KTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sIGVycm9yID0+IF9yZWplY3QoZXJyb3IpKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfcmVqZWN0KGBOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFBsYXRmb3JtIGlzIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFdlYlB1c2hTdWJzY3JpcHRpb24ocHVibGljS2V5OiBzdHJpbmcpOiBQcm9taXNlPFB1c2hTdWJzY3JpcHRpb24+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcclxuICAgICAgdGhpcy5zd1B1c2guc3Vic2NyaXB0aW9uLnN1YnNjcmliZShzdWJzY3JpcHRpb24gPT4ge1xyXG4gICAgICAgIGlmIChzdWJzY3JpcHRpb24gIT0gbnVsbCkge1xyXG4gICAgICAgICAgX3Jlc29sdmUoc3Vic2NyaXB0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5zd1B1c2gucmVxdWVzdFN1YnNjcmlwdGlvbih7IHNlcnZlclB1YmxpY0tleTogcHVibGljS2V5IH0pLnRoZW4ocyA9PiBfcmVzb2x2ZShzKSkuY2F0Y2goZSA9PiBfcmVqZWN0KGUpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIGVycm9yID0+IHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IENhbm5vdCBnZXQgd2ViIHB1c2ggc3Vic2NyaXB0aW9uJywgZXJyb3IpO1xyXG4gICAgICAgIF9yZWplY3QoZXJyb3IpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG4iXX0=
|
|
File without changes
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
|
-
import * as i1 from '@angular/common/http';
|
|
3
2
|
import * as i0 from '@angular/core';
|
|
4
3
|
import { Injectable, NgModule } from '@angular/core';
|
|
5
|
-
import * as i2 from '@angular/service-worker';
|
|
6
4
|
import { PushNotifications } from '@capacitor/push-notifications';
|
|
7
|
-
import * as i3 from '@kolektor/nucleus-common';
|
|
8
5
|
import { Subject, of } from 'rxjs';
|
|
6
|
+
import * as i1 from '@angular/common/http';
|
|
7
|
+
import * as i2 from '@angular/service-worker';
|
|
8
|
+
import * as i3 from '@kolektor/nucleus-common';
|
|
9
9
|
|
|
10
10
|
class Notification {
|
|
11
11
|
}
|
|
@@ -369,9 +369,9 @@ class NucleusNotificationsService {
|
|
|
369
369
|
});
|
|
370
370
|
}
|
|
371
371
|
}
|
|
372
|
-
NucleusNotificationsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
373
|
-
NucleusNotificationsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
374
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
372
|
+
NucleusNotificationsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsService, deps: [{ token: i1.HttpClient }, { token: i2.SwPush }, { token: i3.NucleusAppService }, { token: NucleusNotificationsConfig }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
373
|
+
NucleusNotificationsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsService, providedIn: 'root' });
|
|
374
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsService, decorators: [{
|
|
375
375
|
type: Injectable,
|
|
376
376
|
args: [{
|
|
377
377
|
providedIn: 'root'
|
|
@@ -388,10 +388,10 @@ class NucleusNotificationsModule {
|
|
|
388
388
|
};
|
|
389
389
|
}
|
|
390
390
|
}
|
|
391
|
-
NucleusNotificationsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
392
|
-
NucleusNotificationsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "
|
|
393
|
-
NucleusNotificationsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
394
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
391
|
+
NucleusNotificationsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
392
|
+
NucleusNotificationsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule });
|
|
393
|
+
NucleusNotificationsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule, imports: [[]] });
|
|
394
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NucleusNotificationsModule, decorators: [{
|
|
395
395
|
type: NgModule,
|
|
396
396
|
args: [{
|
|
397
397
|
declarations: [],
|
|
@@ -409,4 +409,3 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.3", ngImpor
|
|
|
409
409
|
*/
|
|
410
410
|
|
|
411
411
|
export { Identity, Notification, NotificationClick, NotificationData, NucleusNotificationsConfig, NucleusNotificationsModule, NucleusNotificationsService, PayloadData, Recipient, Registration, RegistrationResult, UserChannelConfig, WebKey };
|
|
412
|
-
//# sourceMappingURL=kolektor-nucleus-notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kolektor-nucleus-notifications.mjs","sources":["../../../projects/nucleus-notifications/src/lib/models.ts","../../../projects/nucleus-notifications/src/lib/nucleus-notifications.service.ts","../../../projects/nucleus-notifications/src/lib/nucleus-notifications.module.ts","../../../projects/nucleus-notifications/src/public-api.ts","../../../projects/nucleus-notifications/src/kolektor-nucleus-notifications.ts"],"sourcesContent":["export class Notification {\r\n public id: string;\r\n public sender: Identity;\r\n public data: NotificationData;\r\n public isRead: boolean;\r\n public dateCreated: Date;\r\n public expirationDate: Date;\r\n}\r\n\r\nexport class Identity {\r\n public subject: string;\r\n public name: string;\r\n public pictureUrl: string;\r\n}\r\n\r\nexport class Recipient {\r\n public attributeName: string;\r\n public directoryName: string;\r\n public attributeValue: string;\r\n}\r\n\r\nexport class NotificationData {\r\n title: string;\r\n message: string;\r\n htmlMessage: string;\r\n preventDismissal: boolean;\r\n deepLink: string;\r\n}\r\n\r\nexport class WebKey {\r\n publicKey: string;\r\n}\r\n\r\nexport class Registration {\r\n id: string;\r\n token: string;\r\n platform: PlatformValue;\r\n}\r\n\r\nexport class RegistrationResult {\r\n id: string;\r\n}\r\n\r\nexport class PayloadData {\r\n notificationId: string;\r\n eventType: NotificationEventType;\r\n}\r\n\r\nexport class NucleusNotificationsConfig {\r\n serverApiUrl: string;\r\n}\r\n\r\nexport class NotificationClick {\r\n id: string;\r\n type: NotificationType;\r\n routerLink?: string;\r\n}\r\n\r\nexport type NotificationEventType = 'new' | 'updated' | 'deleted' | 'deletedAll' | 'updatedAll' | 'newSilent';\r\n\r\nexport type PlatformValue = 'ios' | 'android' | 'web' | 'none';\r\n\r\nexport type NotificationType = 'default' | 'deeplink';\r\n\r\nexport interface ChannelId {\r\n senderId: string;\r\n channelId: string;\r\n}\r\n\r\nexport class UserChannelConfig {\r\n channelId: string;\r\n displayName: string;\r\n isSubscribed: boolean;\r\n subscriptionType: ChannelSubscriptionType;\r\n methods: NotifyMethod[];\r\n allowedMethods: NotifyMethod[];\r\n}\r\n\r\nexport type ChannelSubscriptionType = 'invariant' | 'optIn' | 'optOut';\r\n\r\nexport type NotifyMethod = 'push' | 'email' | 'sms';\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { SwPush } from '@angular/service-worker';\r\nimport { PushNotifications, PushNotificationSchema } from '@capacitor/push-notifications';\r\nimport { NucleusAppService } from '@kolektor/nucleus-common';\r\nimport { Observable, of, Subject } from 'rxjs';\r\nimport {\r\n ChannelId,\r\n Notification,\r\n NotificationClick,\r\n NotificationEventType,\r\n NotificationType,\r\n NucleusNotificationsConfig,\r\n PayloadData,\r\n PlatformValue,\r\n Registration,\r\n RegistrationResult,\r\n UserChannelConfig,\r\n WebKey\r\n} from './models';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class NucleusNotificationsService {\r\n\r\n constructor(\r\n private http: HttpClient,\r\n private swPush: SwPush,\r\n private appService: NucleusAppService,\r\n config: NucleusNotificationsConfig\r\n ) {\r\n let url = config.serverApiUrl;\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n this.apiUrl = url;\r\n }\r\n\r\n private apiUrl = null;\r\n private readonly registrationStorageKey = 'NucleusNotificationsRegistrationId';\r\n private readonly notificationsStorageKey = 'NucleusNotificationsLocalCache';\r\n private _platform: PlatformValue;\r\n private _isInitialized = false;\r\n private _newNotifications = new Subject<Notification>();\r\n private _clicksSubject = new Subject<NotificationClick>();\r\n private _stateChangesSubject = new Subject<void>();\r\n\r\n public notifications: Notification[] = [];\r\n\r\n public get unreadCount() {\r\n return this.notifications.filter(x => !x.isRead).length;\r\n }\r\n\r\n public get newNotifications() {\r\n return this._newNotifications.asObservable();\r\n }\r\n\r\n public get clicks() {\r\n return this._clicksSubject.asObservable();\r\n }\r\n public get stateChanges() {\r\n return this._stateChangesSubject.asObservable();\r\n }\r\n\r\n public get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n\r\n public async initialize() {\r\n // make sure app service has finished initializing\r\n await this.appService.init();\r\n\r\n this.loadFromStorage();\r\n\r\n if (this.appService.isNative) {\r\n this._platform = this.appService.deviceInfo.platform as PlatformValue;\r\n await this.registerCapacitorEvents();\r\n } else if (this.swPush.isEnabled) {\r\n this._platform = 'web';\r\n this.registerWebPushEvents();\r\n } else {\r\n console.warn('Nucleus.Notifications: There is no push capability, timer will be used to update notifications');\r\n setInterval(() => {\r\n console.log('Updating notifications...');\r\n this.refresh(true);\r\n }, 5 * 60 * 1000);\r\n }\r\n this._isInitialized = true;\r\n this.refresh();\r\n }\r\n\r\n public register(): Promise<any> {\r\n return new Promise((_resolve, _reject) => {\r\n this.getRegistrationInfo().then((info) => {\r\n this.http.post<RegistrationResult>(this.apiUrl + 'registration', info).subscribe((regResult) => {\r\n window.localStorage.setItem(this.registrationStorageKey, regResult.id);\r\n _resolve(null);\r\n }, error => {\r\n console.log('Nucleus.Notifications: Failed to send notification registration to server.', error);\r\n _reject(error);\r\n });\r\n }).catch((error) => _reject(error));\r\n });\r\n }\r\n\r\n public unregister(): Promise<any> {\r\n return new Promise((_resolve, _reject) => {\r\n this.getRegistrationInfo().then((info) => {\r\n this.http.request<any>('DELETE', this.apiUrl + 'registration', { body: info }).subscribe(() => {\r\n window.localStorage.removeItem(this.registrationStorageKey);\r\n _resolve(null);\r\n }, error => {\r\n console.log('Nucleus.Notifications: Failed to remove registration from server.', error);\r\n _reject(error);\r\n });\r\n }).catch((error) => _reject(error));\r\n });\r\n }\r\n\r\n public refresh(notifyAboutNew = false) {\r\n this.http.get<Notification[]>(this.apiUrl + 'notifications').subscribe(res => {\r\n this.updateNotifications(res, notifyAboutNew);\r\n });\r\n }\r\n\r\n public getNotification(id: string): Observable<Notification> {\r\n const localNotification = this.notifications.find(x => x.id === id);\r\n if (localNotification) {\r\n return of(localNotification);\r\n }\r\n return this.http.get<Notification>(this.apiUrl + 'notifications/' + id);\r\n }\r\n\r\n public readNotification(id: string) {\r\n const n = this.notifications.find(x => x.id === id);\r\n if (n && !n.isRead) {\r\n n.isRead = true;\r\n this.notifyStateChanged();\r\n }\r\n this.http.get(this.apiUrl + 'notifications/read/' + id).subscribe();\r\n }\r\n\r\n public dismissNotification(id: string) {\r\n this.deleteNotificaton(id);\r\n this.http.delete(this.apiUrl + 'notifications/' + id).subscribe();\r\n this.removeDeliveredNotification(id);\r\n }\r\n\r\n public dismissAll() {\r\n this.notifications.splice(0);\r\n this.notifyStateChanged();\r\n this.http.delete(this.apiUrl + 'notifications/all').subscribe();\r\n if (this._platform === 'ios' || this._platform === 'android') {\r\n PushNotifications.removeAllDeliveredNotifications();\r\n } else if (this._platform === 'web') {\r\n // TODO: remove all web push notifications\r\n }\r\n }\r\n\r\n public readAll() {\r\n for (const n of this.notifications) {\r\n n.isRead = true;\r\n }\r\n this.notifyStateChanged();\r\n this.http.get(this.apiUrl + 'notifications/read/all').subscribe();\r\n }\r\n\r\n public getChannelConfig(senderId: string, channelId: string, language: string = null) {\r\n return this.http.get<UserChannelConfig>(this.apiUrl + `settings/channel/${senderId}/${channelId}?language=${language}`);\r\n }\r\n\r\n public getChannelConfigsForSender(senderId: string, channelIds: string[], language: string = null) {\r\n const idsStr = channelIds.map(x => senderId + ',' + x).join(';');\r\n return this.getChannelConfigsInternal(idsStr, language);\r\n }\r\n\r\n public getChannelConfigs(ids: ChannelId[], language: string = null) {\r\n const idsStr = ids.map(x => x.senderId + ',' + x.channelId).join(';');\r\n return this.getChannelConfigsInternal(idsStr, language);\r\n }\r\n\r\n public setChannelConfig(senderId: string, config: UserChannelConfig) {\r\n return this.http.post<void>(`${this.apiUrl}settings/channel/${senderId}`, config);\r\n }\r\n\r\n public setChannelConfigs(configs: UserChannelConfig[]) {\r\n return this.http.post<void>(`${this.apiUrl}settings/channels`, configs);\r\n }\r\n\r\n private getChannelConfigsInternal(ids: string, language: string) {\r\n return this.http.get<UserChannelConfig[]>(`${this.apiUrl}settings/channels?ids=${ids}&language=${language}`);\r\n }\r\n\r\n private updateNotifications(newNotifications: Notification[], notifyAboutNew = false) {\r\n let stateChanged = false;\r\n for (const n of newNotifications) {\r\n const existing = this.notifications.find(x => x.id === n.id);\r\n if (existing) {\r\n if (existing.isRead !== n.isRead) {\r\n existing.isRead = n.isRead;\r\n stateChanged = true;\r\n }\r\n } else {\r\n let i = 0;\r\n while (i < this.notifications.length && n.dateCreated < this.notifications[i].dateCreated) {\r\n i++;\r\n }\r\n this.notifications.splice(i, 0, n);\r\n stateChanged = true;\r\n if (notifyAboutNew) {\r\n this._newNotifications.next(n);\r\n }\r\n }\r\n }\r\n\r\n const now = Date.now();\r\n for (let i = this.notifications.length - 1; i >= 0; i--) {\r\n const n = this.notifications[i];\r\n if (new Date(n.expirationDate).getTime() < now || !newNotifications.find(x => x.id === n.id)) {\r\n this.notifications.splice(i, 1);\r\n stateChanged = true;\r\n }\r\n }\r\n\r\n if (stateChanged) {\r\n this.notifyStateChanged();\r\n }\r\n }\r\n\r\n private saveToStorage() {\r\n const str = JSON.stringify(this.notifications);\r\n window.localStorage.setItem(this.notificationsStorageKey, str);\r\n }\r\n\r\n private loadFromStorage() {\r\n try {\r\n const str = window.localStorage.getItem(this.notificationsStorageKey);\r\n if (str) {\r\n const notifications = JSON.parse(str) as Notification[];\r\n this.notifications = notifications.filter(x => !!x);\r\n // precaution for notification.isRead of undefined error\r\n this.notifyStateChanged(false);\r\n }\r\n } catch { }\r\n }\r\n\r\n private handleNotificationEvent(id: string, eventType: NotificationEventType) {\r\n if (eventType.startsWith('new') || eventType === 'updated') { // we are handling new and newSilent\r\n this.getNotification(id).subscribe(n => {\r\n if (eventType.startsWith('new') && !n.isRead) {\r\n this._newNotifications.next(n);\r\n }\r\n const existing = this.notifications.find(x => x.id === n.id);\r\n if (existing) {\r\n existing.isRead = n.isRead;\r\n } else {\r\n this.notifications.splice(0, 0, n);\r\n }\r\n this.notifyStateChanged();\r\n });\r\n } else if (eventType === 'deleted') {\r\n this.deleteNotificaton(id);\r\n } else {\r\n this.refresh();\r\n }\r\n }\r\n\r\n private deleteNotificaton(id: string) {\r\n const i = this.notifications.findIndex(x => x.id === id);\r\n if (i >= 0) {\r\n this.notifications.splice(i, 1);\r\n this.notifyStateChanged();\r\n }\r\n }\r\n\r\n private notifyStateChanged(persistState = true) {\r\n if (persistState) {\r\n this.saveToStorage();\r\n }\r\n this._stateChangesSubject.next();\r\n }\r\n\r\n private handleNotificationAction(notificationAction: string) {\r\n const arr = notificationAction.split(':');\r\n const notificationClick: NotificationClick = {\r\n id: arr[0],\r\n type: arr[1] as NotificationType,\r\n routerLink: arr[2]\r\n };\r\n\r\n const validNotificationClickTypes = ['default', 'deeplink'];\r\n if (validNotificationClickTypes.includes(notificationClick.type)) {\r\n this._clicksSubject.next(notificationClick);\r\n } else {\r\n console.error(`Nucleus.Notifications: Unknown notification action: '${notificationAction}'.`);\r\n }\r\n }\r\n\r\n private removeDeliveredNotification(id: string) {\r\n if (this._platform === 'ios' || this._platform === 'android') {\r\n PushNotifications.getDeliveredNotifications().then(list => {\r\n const toRemove = list.notifications.filter(n => {\r\n const data = this.getNotificationPayloadData(n);\r\n return (data.notificationId === id);\r\n });\r\n\r\n // TODO: On Android this does not currently work because notificationID is not set.\r\n // This my solve the issue: https://github.com/ionic-team/capacitor/pull/3523\r\n PushNotifications.removeDeliveredNotifications({\r\n notifications: toRemove\r\n });\r\n });\r\n } else if (this._platform === 'web') {\r\n // TODO: remove web push notification\r\n }\r\n }\r\n\r\n private getNotificationPayloadData(pushNotification: PushNotificationSchema): PayloadData {\r\n return (this._platform === 'ios') ? pushNotification.data.data : pushNotification.data;\r\n }\r\n\r\n private async registerCapacitorEvents() {\r\n await PushNotifications.addListener('pushNotificationReceived', n => {\r\n const data = this.getNotificationPayloadData(n);\r\n console.log('Nucleus.Notifications: Received capacitor push event: ' + data.eventType, n);\r\n this.handleNotificationEvent(data.notificationId, data.eventType);\r\n });\r\n\r\n await PushNotifications.addListener('pushNotificationActionPerformed', a => {\r\n let action = (a as any).notification.data.notificationAction;\r\n if (this._platform === 'ios') {\r\n action = (a as any).notification.data.data.notificationAction;\r\n }\r\n console.log('Nucleus.Notifications: Received capacitor action event', action);\r\n this.handleNotificationAction(action);\r\n });\r\n }\r\n\r\n private registerWebPushEvents() {\r\n this.swPush.messages.subscribe((n) => {\r\n const data: PayloadData = (n as any).data;\r\n console.log('Nucleus.Notifications: Received WebPush event: ' + data.eventType, n);\r\n this.handleNotificationEvent(data.notificationId, data.eventType);\r\n });\r\n\r\n this.swPush.notificationClicks.subscribe((action) => {\r\n console.log('Nucleus.Notifications: Received WebPush action event', action);\r\n const tag = action.notification.tag;\r\n this.handleNotificationAction(tag);\r\n });\r\n }\r\n\r\n private getRegistrationInfo(): Promise<Registration> {\r\n return new Promise((_resolve, _reject) => {\r\n const registrationId = window.localStorage.getItem(this.registrationStorageKey);\r\n if (this._platform === 'android' || this._platform === 'ios') {\r\n // capacitor platform\r\n const listener = PushNotifications.addListener('registration', token => {\r\n listener.remove();\r\n _resolve({ id: registrationId, token: token.value, platform: this._platform });\r\n });\r\n PushNotifications.register().catch(error => _reject('Could not register for notifications:' + error));\r\n } else if (this._platform === 'web') {\r\n // Web Push API\r\n this.http.get<WebKey>(this.apiUrl + 'registration/webkey').subscribe(key => {\r\n this.getWebPushSubscription(key.publicKey).then(subscription => {\r\n const t = JSON.stringify(subscription.toJSON());\r\n _resolve({ id: registrationId, token: t, platform: 'web' });\r\n });\r\n }, error => _reject(error));\r\n } else {\r\n _reject(`Nucleus.Notifications: Platform is not supported`);\r\n }\r\n });\r\n }\r\n\r\n private getWebPushSubscription(publicKey: string): Promise<PushSubscription> {\r\n return new Promise((_resolve, _reject) => {\r\n this.swPush.subscription.subscribe(subscription => {\r\n if (subscription != null) {\r\n _resolve(subscription);\r\n } else {\r\n this.swPush.requestSubscription({ serverPublicKey: publicKey }).then(s => _resolve(s)).catch(e => _reject(e));\r\n }\r\n }, error => {\r\n console.error('Nucleus.Notifications: Cannot get web push subscription', error);\r\n _reject(error);\r\n });\r\n });\r\n }\r\n}\r\n","import { NgModule, ModuleWithProviders } from '@angular/core';\r\nimport { NucleusNotificationsConfig } from './models';\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [\r\n ],\r\n exports: []\r\n})\r\nexport class NucleusNotificationsModule {\r\n\r\n static forRoot(config: NucleusNotificationsConfig): ModuleWithProviders<NucleusNotificationsModule> {\r\n return {\r\n ngModule: NucleusNotificationsModule,\r\n providers: [\r\n { provide: NucleusNotificationsConfig, useValue: config }\r\n ]\r\n };\r\n }\r\n}\r\n","/*\r\n * Public API Surface of nucleus-notifications\r\n */\r\n\r\nexport * from './lib/nucleus-notifications.service';\r\nexport * from './lib/nucleus-notifications.module';\r\nexport * from './lib/models';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|