@kolektor/nucleus-notifications 0.0.12-pre.7931 → 0.1.0-pre.124
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/README.md +7 -0
- package/esm2022/index.mjs +4 -0
- package/esm2022/kolektor-nucleus-notifications.mjs +5 -0
- package/esm2022/lib/models.mjs +23 -0
- package/esm2022/lib/nucleus-notifications.module.mjs +25 -0
- package/esm2022/lib/nucleus-notifications.service.mjs +359 -0
- package/{fesm2020 → fesm2022}/kolektor-nucleus-notifications.mjs +388 -389
- package/fesm2022/kolektor-nucleus-notifications.mjs.map +1 -0
- package/index.d.ts +3 -5
- package/lib/models.d.ts +65 -65
- package/lib/nucleus-notifications.module.d.ts +9 -9
- package/lib/nucleus-notifications.service.d.ts +56 -56
- package/package.json +25 -31
- package/esm2020/kolektor-nucleus-notifications.mjs +0 -5
- package/esm2020/lib/models.mjs +0 -23
- package/esm2020/lib/nucleus-notifications.module.mjs +0 -25
- package/esm2020/lib/nucleus-notifications.service.mjs +0 -356
- package/esm2020/public-api.mjs +0 -7
- package/fesm2015/kolektor-nucleus-notifications.mjs +0 -412
- package/fesm2015/kolektor-nucleus-notifications.mjs.map +0 -1
- package/fesm2020/kolektor-nucleus-notifications.mjs.map +0 -1
- package/public-api.d.ts +0 -3
package/README.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './lib/nucleus-notifications.service';
|
|
2
|
+
export * from './lib/nucleus-notifications.module';
|
|
3
|
+
export * from './lib/models';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL25nL251Y2xldXMtbm90aWZpY2F0aW9ucy9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxxQ0FBcUMsQ0FBQztBQUNwRCxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsY0FBYyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9saWIvbnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvbnVjbGV1cy1ub3RpZmljYXRpb25zLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9tb2RlbHMnO1xuIl19
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia29sZWt0b3ItbnVjbGV1cy1ub3RpZmljYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9uZy9udWNsZXVzLW5vdGlmaWNhdGlvbnMvc3JjL2tvbGVrdG9yLW51Y2xldXMtbm90aWZpY2F0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHZW5lcmF0ZWQgYnVuZGxlIGluZGV4LiBEbyBub3QgZWRpdC5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2luZGV4JztcbiJdfQ==
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class Notification {
|
|
2
|
+
}
|
|
3
|
+
export class Identity {
|
|
4
|
+
}
|
|
5
|
+
export class Recipient {
|
|
6
|
+
}
|
|
7
|
+
export class NotificationData {
|
|
8
|
+
}
|
|
9
|
+
export class WebKey {
|
|
10
|
+
}
|
|
11
|
+
export class Registration {
|
|
12
|
+
}
|
|
13
|
+
export class RegistrationResult {
|
|
14
|
+
}
|
|
15
|
+
export class PayloadData {
|
|
16
|
+
}
|
|
17
|
+
export class NucleusNotificationsConfig {
|
|
18
|
+
}
|
|
19
|
+
export class NotificationClick {
|
|
20
|
+
}
|
|
21
|
+
export class UserChannelConfig {
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9uZy9udWNsZXVzLW5vdGlmaWNhdGlvbnMvc3JjL2xpYi9tb2RlbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFPLFlBQVk7Q0FPeEI7QUFFRCxNQUFNLE9BQU8sUUFBUTtDQUlwQjtBQUVELE1BQU0sT0FBTyxTQUFTO0NBSXJCO0FBRUQsTUFBTSxPQUFPLGdCQUFnQjtDQU01QjtBQUVELE1BQU0sT0FBTyxNQUFNO0NBRWxCO0FBRUQsTUFBTSxPQUFPLFlBQVk7Q0FJeEI7QUFFRCxNQUFNLE9BQU8sa0JBQWtCO0NBRTlCO0FBRUQsTUFBTSxPQUFPLFdBQVc7Q0FHdkI7QUFFRCxNQUFNLE9BQU8sMEJBQTBCO0NBRXRDO0FBRUQsTUFBTSxPQUFPLGlCQUFpQjtDQUk3QjtBQWFELE1BQU0sT0FBTyxpQkFBaUI7Q0FPN0IiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uIHtcbiAgcHVibGljIGlkOiBzdHJpbmc7XG4gIHB1YmxpYyBzZW5kZXI6IElkZW50aXR5O1xuICBwdWJsaWMgZGF0YTogTm90aWZpY2F0aW9uRGF0YTtcbiAgcHVibGljIGlzUmVhZDogYm9vbGVhbjtcbiAgcHVibGljIGRhdGVDcmVhdGVkOiBEYXRlO1xuICBwdWJsaWMgZXhwaXJhdGlvbkRhdGU6IERhdGU7XG59XG5cbmV4cG9ydCBjbGFzcyBJZGVudGl0eSB7XG4gIHB1YmxpYyBzdWJqZWN0OiBzdHJpbmc7XG4gIHB1YmxpYyBuYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyBwaWN0dXJlVXJsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWNpcGllbnQge1xuICBwdWJsaWMgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgZGlyZWN0b3J5TmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYXR0cmlidXRlVmFsdWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvbkRhdGEge1xuICB0aXRsZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGh0bWxNZXNzYWdlOiBzdHJpbmc7XG4gIHByZXZlbnREaXNtaXNzYWw6IGJvb2xlYW47XG4gIGRlZXBMaW5rOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJLZXkge1xuICBwdWJsaWNLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFJlZ2lzdHJhdGlvbiB7XG4gIGlkOiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIHBsYXRmb3JtOiBQbGF0Zm9ybVZhbHVlO1xufVxuXG5leHBvcnQgY2xhc3MgUmVnaXN0cmF0aW9uUmVzdWx0IHtcbiAgaWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFBheWxvYWREYXRhIHtcbiAgbm90aWZpY2F0aW9uSWQ6IHN0cmluZztcbiAgZXZlbnRUeXBlOiBOb3RpZmljYXRpb25FdmVudFR5cGU7XG59XG5cbmV4cG9ydCBjbGFzcyBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZyB7XG4gIHNlcnZlckFwaVVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uQ2xpY2sge1xuICBpZDogc3RyaW5nO1xuICB0eXBlOiBOb3RpZmljYXRpb25UeXBlO1xuICByb3V0ZXJMaW5rPzogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25FdmVudFR5cGUgPSAnbmV3JyB8ICd1cGRhdGVkJyB8ICdkZWxldGVkJyB8ICdkZWxldGVkQWxsJyB8ICd1cGRhdGVkQWxsJyB8ICduZXdTaWxlbnQnO1xuXG5leHBvcnQgdHlwZSBQbGF0Zm9ybVZhbHVlID0gJ2lvcycgfCAnYW5kcm9pZCcgfCAnd2ViJyB8ICdub25lJztcblxuZXhwb3J0IHR5cGUgTm90aWZpY2F0aW9uVHlwZSA9ICdkZWZhdWx0JyB8ICdkZWVwbGluayc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbm5lbElkIHtcbiAgc2VuZGVySWQ6IHN0cmluZztcbiAgY2hhbm5lbElkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBVc2VyQ2hhbm5lbENvbmZpZyB7XG4gIGNoYW5uZWxJZDogc3RyaW5nO1xuICBkaXNwbGF5TmFtZTogc3RyaW5nO1xuICBpc1N1YnNjcmliZWQ6IGJvb2xlYW47XG4gIHN1YnNjcmlwdGlvblR5cGU6IENoYW5uZWxTdWJzY3JpcHRpb25UeXBlO1xuICBtZXRob2RzOiBOb3RpZnlNZXRob2RbXTtcbiAgYWxsb3dlZE1ldGhvZHM6IE5vdGlmeU1ldGhvZFtdO1xufVxuXG5leHBvcnQgdHlwZSBDaGFubmVsU3Vic2NyaXB0aW9uVHlwZSA9ICdpbnZhcmlhbnQnIHwgJ29wdEluJyB8ICdvcHRPdXQnO1xuXG5leHBvcnQgdHlwZSBOb3RpZnlNZXRob2QgPSAncHVzaCcgfCAnZW1haWwnIHwgJ3Ntcyc7XG4iXX0=
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { NucleusNotificationsConfig } from './models';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class NucleusNotificationsModule {
|
|
5
|
+
static forRoot(config) {
|
|
6
|
+
return {
|
|
7
|
+
ngModule: NucleusNotificationsModule,
|
|
8
|
+
providers: [
|
|
9
|
+
{ provide: NucleusNotificationsConfig, useValue: config }
|
|
10
|
+
]
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
14
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
|
|
15
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
|
|
16
|
+
}
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, decorators: [{
|
|
18
|
+
type: NgModule,
|
|
19
|
+
args: [{
|
|
20
|
+
declarations: [],
|
|
21
|
+
imports: [],
|
|
22
|
+
exports: []
|
|
23
|
+
}]
|
|
24
|
+
}] });
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmcvbnVjbGV1cy1ub3RpZmljYXRpb25zL3NyYy9saWIvbnVjbGV1cy1ub3RpZmljYXRpb25zLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUF1QixNQUFNLGVBQWUsQ0FBQztBQUM5RCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxVQUFVLENBQUM7O0FBUXRELE1BQU0sT0FBTywwQkFBMEI7SUFFckMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFrQztRQUMvQyxPQUFPO1lBQ0wsUUFBUSxFQUFFLDBCQUEwQjtZQUNwQyxTQUFTLEVBQUU7Z0JBQ1QsRUFBRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRTthQUMxRDtTQUNGLENBQUM7SUFDSixDQUFDOytHQVRVLDBCQUEwQjtnSEFBMUIsMEJBQTBCO2dIQUExQiwwQkFBMEI7OzRGQUExQiwwQkFBMEI7a0JBTnRDLFFBQVE7bUJBQUM7b0JBQ1IsWUFBWSxFQUFFLEVBQUU7b0JBQ2hCLE9BQU8sRUFBRSxFQUNSO29CQUNELE9BQU8sRUFBRSxFQUFFO2lCQUNaIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnIH0gZnJvbSAnLi9tb2RlbHMnO1xuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtdLFxuICBpbXBvcnRzOiBbXG4gIF0sXG4gIGV4cG9ydHM6IFtdXG59KVxuZXhwb3J0IGNsYXNzIE51Y2xldXNOb3RpZmljYXRpb25zTW9kdWxlIHtcblxuICBzdGF0aWMgZm9yUm9vdChjb25maWc6IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnKTogTW9kdWxlV2l0aFByb3ZpZGVyczxOdWNsZXVzTm90aWZpY2F0aW9uc01vZHVsZT4ge1xuICAgIHJldHVybiB7XG4gICAgICBuZ01vZHVsZTogTnVjbGV1c05vdGlmaWNhdGlvbnNNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgeyBwcm92aWRlOiBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZywgdXNlVmFsdWU6IGNvbmZpZyB9XG4gICAgICBdXG4gICAgfTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { HttpClient } from '@angular/common/http';
|
|
3
|
+
import { Injectable } from '@angular/core';
|
|
4
|
+
import { SwPush } from '@angular/service-worker';
|
|
5
|
+
import { PushNotifications } from '@capacitor/push-notifications';
|
|
6
|
+
import { NucleusAppService } from '@kolektor/nucleus-common';
|
|
7
|
+
import { of, Subject } from 'rxjs';
|
|
8
|
+
import { NucleusNotificationsConfig } from './models';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/common/http";
|
|
11
|
+
import * as i2 from "@angular/service-worker";
|
|
12
|
+
import * as i3 from "@kolektor/nucleus-common";
|
|
13
|
+
import * as i4 from "./models";
|
|
14
|
+
export class NucleusNotificationsService {
|
|
15
|
+
constructor(http, swPush, appService, config) {
|
|
16
|
+
this.http = http;
|
|
17
|
+
this.swPush = swPush;
|
|
18
|
+
this.appService = appService;
|
|
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) {
|
|
139
|
+
return this.http.get(this.apiUrl + `settings/channel/${senderId}/${channelId}?language=${language}`);
|
|
140
|
+
}
|
|
141
|
+
getChannelConfigsForSender(senderId, channelIds, language) {
|
|
142
|
+
const idsStr = channelIds.map(x => senderId + ',' + x).join(';');
|
|
143
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
144
|
+
}
|
|
145
|
+
getChannelConfigs(ids, language) {
|
|
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 { /* empty */ }
|
|
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
|
+
if (!notificationAction) {
|
|
246
|
+
throw new Error('Notification action is empty!');
|
|
247
|
+
}
|
|
248
|
+
const arr = notificationAction.split(':');
|
|
249
|
+
const notificationClick = {
|
|
250
|
+
id: arr[0],
|
|
251
|
+
type: arr[1],
|
|
252
|
+
routerLink: arr[2]
|
|
253
|
+
};
|
|
254
|
+
const validNotificationClickTypes = ['default', 'deeplink'];
|
|
255
|
+
if (validNotificationClickTypes.includes(notificationClick.type)) {
|
|
256
|
+
this._clicksSubject.next(notificationClick);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
console.error(`Nucleus.Notifications: Unknown notification action: '${notificationAction}'.`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
removeDeliveredNotification(id) {
|
|
263
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
264
|
+
PushNotifications.getDeliveredNotifications().then(list => {
|
|
265
|
+
const toRemove = list.notifications.filter(n => {
|
|
266
|
+
const data = this.getNotificationPayloadData(n);
|
|
267
|
+
return (data.notificationId === id);
|
|
268
|
+
});
|
|
269
|
+
// TODO: On Android this does not currently work because notificationID is not set.
|
|
270
|
+
// This my solve the issue: https://github.com/ionic-team/capacitor/pull/3523
|
|
271
|
+
PushNotifications.removeDeliveredNotifications({
|
|
272
|
+
notifications: toRemove
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
else if (this._platform === 'web') {
|
|
277
|
+
// TODO: remove web push notification
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
getNotificationPayloadData(pushNotification) {
|
|
281
|
+
return (this._platform === 'ios') ? pushNotification.data.data : pushNotification.data;
|
|
282
|
+
}
|
|
283
|
+
async registerCapacitorEvents() {
|
|
284
|
+
await PushNotifications.addListener('pushNotificationReceived', n => {
|
|
285
|
+
const data = this.getNotificationPayloadData(n);
|
|
286
|
+
console.log('Nucleus.Notifications: Received capacitor push event: ' + data.eventType, n);
|
|
287
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
288
|
+
});
|
|
289
|
+
await PushNotifications.addListener('pushNotificationActionPerformed', a => {
|
|
290
|
+
let action = a.notification.data.notificationAction;
|
|
291
|
+
if (this._platform === 'ios') {
|
|
292
|
+
action = a.notification.data.data.notificationAction;
|
|
293
|
+
}
|
|
294
|
+
console.log('Nucleus.Notifications: Received capacitor action event', action);
|
|
295
|
+
this.handleNotificationAction(action);
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
registerWebPushEvents() {
|
|
299
|
+
this.swPush.messages.subscribe((n) => {
|
|
300
|
+
const data = n.data;
|
|
301
|
+
console.log('Nucleus.Notifications: Received WebPush event: ' + data.eventType, n);
|
|
302
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
303
|
+
});
|
|
304
|
+
this.swPush.notificationClicks.subscribe((action) => {
|
|
305
|
+
console.log('Nucleus.Notifications: Received WebPush action event', action);
|
|
306
|
+
const tag = action.notification.tag;
|
|
307
|
+
this.handleNotificationAction(tag);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
getRegistrationInfo() {
|
|
311
|
+
return new Promise((_resolve, _reject) => {
|
|
312
|
+
const registrationId = window.localStorage.getItem(this.registrationStorageKey);
|
|
313
|
+
if (this._platform === 'android' || this._platform === 'ios') {
|
|
314
|
+
// capacitor platform
|
|
315
|
+
const listener = PushNotifications.addListener('registration', token => {
|
|
316
|
+
listener.remove();
|
|
317
|
+
_resolve({ id: registrationId, token: token.value, platform: this._platform });
|
|
318
|
+
});
|
|
319
|
+
PushNotifications.register().catch(error => _reject('Could not register for notifications:' + error));
|
|
320
|
+
}
|
|
321
|
+
else if (this._platform === 'web') {
|
|
322
|
+
// Web Push API
|
|
323
|
+
this.http.get(this.apiUrl + 'registration/webkey').subscribe(key => {
|
|
324
|
+
this.getWebPushSubscription(key.publicKey).then(subscription => {
|
|
325
|
+
const t = JSON.stringify(subscription.toJSON());
|
|
326
|
+
_resolve({ id: registrationId, token: t, platform: 'web' });
|
|
327
|
+
});
|
|
328
|
+
}, error => _reject(error));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
_reject(`Nucleus.Notifications: Platform is not supported`);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
getWebPushSubscription(publicKey) {
|
|
336
|
+
return new Promise((_resolve, _reject) => {
|
|
337
|
+
this.swPush.subscription.subscribe(subscription => {
|
|
338
|
+
if (subscription != null) {
|
|
339
|
+
_resolve(subscription);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
this.swPush.requestSubscription({ serverPublicKey: publicKey }).then(s => _resolve(s)).catch(e => _reject(e));
|
|
343
|
+
}
|
|
344
|
+
}, error => {
|
|
345
|
+
console.error('Nucleus.Notifications: Cannot get web push subscription', error);
|
|
346
|
+
_reject(error);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, deps: [{ token: i1.HttpClient }, { token: i2.SwPush }, { token: i3.NucleusAppService }, { token: i4.NucleusNotificationsConfig }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
351
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, providedIn: 'root' }); }
|
|
352
|
+
}
|
|
353
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, decorators: [{
|
|
354
|
+
type: Injectable,
|
|
355
|
+
args: [{
|
|
356
|
+
providedIn: 'root'
|
|
357
|
+
}]
|
|
358
|
+
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.SwPush }, { type: i3.NucleusAppService }, { type: i4.NucleusNotificationsConfig }]; } });
|
|
359
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25nL251Y2xldXMtbm90aWZpY2F0aW9ucy9zcmMvbGliL251Y2xldXMtbm90aWZpY2F0aW9ucy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakQsT0FBTyxFQUFFLGlCQUFpQixFQUEwQixNQUFNLCtCQUErQixDQUFDO0FBQzFGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzdELE9BQU8sRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFNTCwwQkFBMEIsRUFPM0IsTUFBTSxVQUFVLENBQUM7Ozs7OztBQUtsQixNQUFNLE9BQU8sMkJBQTJCO0lBRXRDLFlBQ1UsSUFBZ0IsRUFDaEIsTUFBYyxFQUNkLFVBQTZCLEVBQ3JDLE1BQWtDO1FBSDFCLFNBQUksR0FBSixJQUFJLENBQVk7UUFDaEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGVBQVUsR0FBVixVQUFVLENBQW1CO1FBV3RCLDJCQUFzQixHQUFHLG9DQUFvQyxDQUFDO1FBQzlELDRCQUF1QixHQUFHLGdDQUFnQyxDQUFDO1FBRXBFLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFnQixDQUFDO1FBQ2hELG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQXFCLENBQUM7UUFDbEQseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUU1QyxrQkFBYSxHQUFtQixFQUFFLENBQUM7UUFoQnhDLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDOUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDdEIsR0FBRyxJQUFJLEdBQUcsQ0FBQztTQUNaO1FBQ0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUM7SUFDcEIsQ0FBQztJQWFELElBQVcsV0FBVztRQUNwQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzFELENBQUM7SUFFRCxJQUFXLGdCQUFnQjtRQUN6QixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRUQsSUFBVyxNQUFNO1FBQ2YsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFDRCxJQUFXLFlBQVk7UUFDckIsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDbEQsQ0FBQztJQUVELElBQVcsYUFBYTtRQUN0QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVNLEtBQUssQ0FBQyxVQUFVO1FBQ3JCLGtEQUFrRDtRQUNsRCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFN0IsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXZCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxRQUF5QixDQUFDO1lBQ3RFLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7U0FDdEM7YUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1NBQzlCO2FBQU07WUFDTCxPQUFPLENBQUMsSUFBSSxDQUFDLGdHQUFnRyxDQUFDLENBQUM7WUFDL0csV0FBVyxDQUFDLEdBQUcsRUFBRTtnQkFDZixPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFDLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckIsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7U0FDbkI7UUFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVNLFFBQVE7UUFDYixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBcUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7b0JBQzdGLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3ZFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDakIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUNULE9BQU8sQ0FBQyxHQUFHLENBQUMsNEVBQTRFLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ2pHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDakIsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFVBQVU7UUFDZixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBTSxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxjQUFjLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO29CQUM1RixNQUFNLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztvQkFDNUQsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqQixDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUU7b0JBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtRUFBbUUsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDeEYsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqQixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sT0FBTyxDQUFDLGNBQWMsR0FBRyxLQUFLO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFpQixJQUFJLENBQUMsTUFBTSxHQUFHLGVBQWUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUMzRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLGVBQWUsQ0FBQyxFQUFVO1FBQy9CLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLElBQUksaUJBQWlCLEVBQUU7WUFDckIsT0FBTyxFQUFFLENBQUMsaUJBQWlCLENBQUMsQ0FBQztTQUM5QjtRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQWUsSUFBSSxDQUFDLE1BQU0sR0FBRyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsRUFBVTtRQUNoQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFO1lBQ2xCLENBQUMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzNCO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxxQkFBcUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN0RSxDQUFDO0lBRU0sbUJBQW1CLENBQUMsRUFBVTtRQUNuQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNsRSxJQUFJLENBQUMsMkJBQTJCLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVNLFVBQVU7UUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLG1CQUFtQixDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDaEUsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRTtZQUM1RCxpQkFBaUIsQ0FBQywrQkFBK0IsRUFBRSxDQUFDO1NBQ3JEO2FBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssRUFBRTtZQUNuQywwQ0FBMEM7U0FDM0M7SUFDSCxDQUFDO0lBRU0sT0FBTztRQUNaLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNsQyxDQUFDLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztTQUNqQjtRQUNELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsd0JBQXdCLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNwRSxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsUUFBZ0IsRUFBRSxTQUFpQixFQUFFLFFBQWlCO1FBQzVFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQW9CLElBQUksQ0FBQyxNQUFNLEdBQUcsb0JBQW9CLFFBQVEsSUFBSSxTQUFTLGFBQWEsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUMxSCxDQUFDO0lBRU0sMEJBQTBCLENBQUMsUUFBZ0IsRUFBRSxVQUFvQixFQUFFLFFBQWlCO1FBQ3pGLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNqRSxPQUFPLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVNLGlCQUFpQixDQUFDLEdBQWdCLEVBQUUsUUFBaUI7UUFDMUQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEUsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFTSxnQkFBZ0IsQ0FBQyxRQUFnQixFQUFFLE1BQXlCO1FBQ2pFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxvQkFBb0IsUUFBUSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUVNLGlCQUFpQixDQUFDLE9BQTRCO1FBQ25ELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxtQkFBbUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRU8seUJBQXlCLENBQUMsR0FBVyxFQUFFLFFBQWlCO1FBQzlELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQXNCLEdBQUcsSUFBSSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsYUFBYSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxnQkFBZ0MsRUFBRSxjQUFjLEdBQUcsS0FBSztRQUNsRixJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDekIsS0FBSyxNQUFNLENBQUMsSUFBSSxnQkFBZ0IsRUFBRTtZQUNoQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzdELElBQUksUUFBUSxFQUFFO2dCQUNaLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFO29CQUNoQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7b0JBQzNCLFlBQVksR0FBRyxJQUFJLENBQUM7aUJBQ3JCO2FBQ0Y7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNWLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUU7b0JBQ3pGLENBQUMsRUFBRSxDQUFDO2lCQUNMO2dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ25DLFlBQVksR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLElBQUksY0FBYyxFQUFFO29CQUNsQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUNoQzthQUNGO1NBQ0Y7UUFFRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkIsS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN2RCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUM1RixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hDLFlBQVksR0FBRyxJQUFJLENBQUM7YUFDckI7U0FDRjtRQUVELElBQUksWUFBWSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzNCO0lBQ0gsQ0FBQztJQUVPLGFBQWE7UUFDbkIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDL0MsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFTyxlQUFlO1FBQ3JCLElBQUk7WUFDRixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUN0RSxJQUFJLEdBQUcsRUFBRTtnQkFDUCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBbUIsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCx3REFBd0Q7Z0JBQ3hELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNoQztTQUNGO1FBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRTtJQUN6QixDQUFDO0lBRU8sdUJBQXVCLENBQUMsRUFBVSxFQUFFLFNBQWdDO1FBQzFFLElBQUksU0FBUyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLEVBQUUsb0NBQW9DO1lBQ2hHLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNyQyxJQUFJLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFO29CQUM1QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUNoQztnQkFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RCxJQUFJLFFBQVEsRUFBRTtvQkFDWixRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7aUJBQzVCO3FCQUFNO29CQUNMLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ3BDO2dCQUNELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzVCLENBQUMsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUU7WUFDbEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzVCO2FBQU07WUFDTCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDaEI7SUFDSCxDQUFDO0lBRU8saUJBQWlCLENBQUMsRUFBVTtRQUNsQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ1YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzNCO0lBQ0gsQ0FBQztJQUVPLGtCQUFrQixDQUFDLFlBQVksR0FBRyxJQUFJO1FBQzVDLElBQUksWUFBWSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUN0QjtRQUNELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRU8sd0JBQXdCLENBQUMsa0JBQXNDO1FBQ3JFLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7U0FDbEQ7UUFFRCxNQUFNLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDMUMsTUFBTSxpQkFBaUIsR0FBc0I7WUFDM0MsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDVixJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBcUI7WUFDaEMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDbkIsQ0FBQztRQUVGLE1BQU0sMkJBQTJCLEdBQUcsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDNUQsSUFBSSwyQkFBMkIsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDaEUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztTQUM3QzthQUFNO1lBQ0wsT0FBTyxDQUFDLEtBQUssQ0FBQyx3REFBd0Qsa0JBQWtCLElBQUksQ0FBQyxDQUFDO1NBQy9GO0lBQ0gsQ0FBQztJQUVPLDJCQUEyQixDQUFDLEVBQVU7UUFDNUMsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRTtZQUM1RCxpQkFBaUIsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDeEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQzdDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDaEQsT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLEtBQUssRUFBRSxDQUFDLENBQUM7Z0JBQ3RDLENBQUMsQ0FBQyxDQUFDO2dCQUVILG1GQUFtRjtnQkFDbkYsNkVBQTZFO2dCQUM3RSxpQkFBaUIsQ0FBQyw0QkFBNEIsQ0FBQztvQkFDN0MsYUFBYSxFQUFFLFFBQVE7aUJBQ3hCLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxFQUFFO1lBQ25DLHFDQUFxQztTQUN0QztJQUNILENBQUM7SUFFTywwQkFBMEIsQ0FBQyxnQkFBd0M7UUFDekUsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQztJQUN6RixDQUFDO0lBRU8sS0FBSyxDQUFDLHVCQUF1QjtRQUNuQyxNQUFNLGlCQUFpQixDQUFDLFdBQVcsQ0FBQywwQkFBMEIsRUFBRSxDQUFDLENBQUMsRUFBRTtZQUNsRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3REFBd0QsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFGLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwRSxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0saUJBQWlCLENBQUMsV0FBVyxDQUFDLGlDQUFpQyxFQUFFLENBQUMsQ0FBQyxFQUFFO1lBQ3pFLElBQUksTUFBTSxHQUFJLENBQVMsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1lBQzdELElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxLQUFLLEVBQUU7Z0JBQzVCLE1BQU0sR0FBSSxDQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUM7YUFDL0Q7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLHdEQUF3RCxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzlFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsTUFBTSxJQUFJLEdBQWlCLENBQVMsQ0FBQyxJQUFJLENBQUM7WUFDMUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpREFBaUQsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ25GLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwRSxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzREFBc0QsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1RSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQztZQUNwQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sbUJBQW1CO1FBQ3pCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDdkMsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFXLENBQUM7WUFDMUYsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssRUFBRTtnQkFDNUQscUJBQXFCO2dCQUNyQixNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUNyRSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ2xCLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRixDQUFDLENBQUMsQ0FBQztnQkFDSCxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsdUNBQXVDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUN2RztpQkFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxFQUFFO2dCQUNuQyxlQUFlO2dCQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFTLElBQUksQ0FBQyxNQUFNLEdBQUcscUJBQXFCLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUU7b0JBQ3pFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFO3dCQUM3RCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO3dCQUNoRCxRQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7b0JBQzlELENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQzdCO2lCQUFNO2dCQUNMLE9BQU8sQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO2FBQzdEO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsU0FBaUI7UUFDOUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUN2QyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQ2hELElBQUksWUFBWSxJQUFJLElBQUksRUFBRTtvQkFDeEIsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN4QjtxQkFBTTtvQkFDTCxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQy9HO1lBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFO2dCQUNULE9BQU8sQ0FBQyxLQUFLLENBQUMseURBQXlELEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ2hGLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzsrR0FsWFUsMkJBQTJCO21IQUEzQiwyQkFBMkIsY0FGMUIsTUFBTTs7NEZBRVAsMkJBQTJCO2tCQUh2QyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTd1B1c2ggfSBmcm9tICdAYW5ndWxhci9zZXJ2aWNlLXdvcmtlcic7XG5pbXBvcnQgeyBQdXNoTm90aWZpY2F0aW9ucywgUHVzaE5vdGlmaWNhdGlvblNjaGVtYSB9IGZyb20gJ0BjYXBhY2l0b3IvcHVzaC1ub3RpZmljYXRpb25zJztcbmltcG9ydCB7IE51Y2xldXNBcHBTZXJ2aWNlIH0gZnJvbSAnQGtvbGVrdG9yL251Y2xldXMtY29tbW9uJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBDaGFubmVsSWQsXG4gIE5vdGlmaWNhdGlvbixcbiAgTm90aWZpY2F0aW9uQ2xpY2ssXG4gIE5vdGlmaWNhdGlvbkV2ZW50VHlwZSxcbiAgTm90aWZpY2F0aW9uVHlwZSxcbiAgTnVjbGV1c05vdGlmaWNhdGlvbnNDb25maWcsXG4gIFBheWxvYWREYXRhLFxuICBQbGF0Zm9ybVZhbHVlLFxuICBSZWdpc3RyYXRpb24sXG4gIFJlZ2lzdHJhdGlvblJlc3VsdCxcbiAgVXNlckNoYW5uZWxDb25maWcsXG4gIFdlYktleVxufSBmcm9tICcuL21vZGVscyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE51Y2xldXNOb3RpZmljYXRpb25zU2VydmljZSB7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgc3dQdXNoOiBTd1B1c2gsXG4gICAgcHJpdmF0ZSBhcHBTZXJ2aWNlOiBOdWNsZXVzQXBwU2VydmljZSxcbiAgICBjb25maWc6IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnXG4gICkge1xuICAgIGxldCB1cmwgPSBjb25maWcuc2VydmVyQXBpVXJsO1xuICAgIGlmICghdXJsLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgIHVybCArPSAnLyc7XG4gICAgfVxuICAgIHRoaXMuYXBpVXJsID0gdXJsO1xuICB9XG5cbiAgcHJpdmF0ZSBhcGlVcmw6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpc3RyYXRpb25TdG9yYWdlS2V5ID0gJ051Y2xldXNOb3RpZmljYXRpb25zUmVnaXN0cmF0aW9uSWQnO1xuICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmaWNhdGlvbnNTdG9yYWdlS2V5ID0gJ051Y2xldXNOb3RpZmljYXRpb25zTG9jYWxDYWNoZSc7XG4gIHByaXZhdGUgX3BsYXRmb3JtOiBQbGF0Zm9ybVZhbHVlO1xuICBwcml2YXRlIF9pc0luaXRpYWxpemVkID0gZmFsc2U7XG4gIHByaXZhdGUgX25ld05vdGlmaWNhdGlvbnMgPSBuZXcgU3ViamVjdDxOb3RpZmljYXRpb24+KCk7XG4gIHByaXZhdGUgX2NsaWNrc1N1YmplY3QgPSBuZXcgU3ViamVjdDxOb3RpZmljYXRpb25DbGljaz4oKTtcbiAgcHJpdmF0ZSBfc3RhdGVDaGFuZ2VzU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHVibGljIG5vdGlmaWNhdGlvbnM6IE5vdGlmaWNhdGlvbltdID0gW107XG5cbiAgcHVibGljIGdldCB1bnJlYWRDb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5ub3RpZmljYXRpb25zLmZpbHRlcih4ID0+ICF4LmlzUmVhZCkubGVuZ3RoO1xuICB9XG5cbiAgcHVibGljIGdldCBuZXdOb3RpZmljYXRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl9uZXdOb3RpZmljYXRpb25zLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHVibGljIGdldCBjbGlja3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWNrc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cbiAgcHVibGljIGdldCBzdGF0ZUNoYW5nZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlQ2hhbmdlc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGlzSW5pdGlhbGl6ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzSW5pdGlhbGl6ZWQ7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaW5pdGlhbGl6ZSgpIHtcbiAgICAvLyBtYWtlIHN1cmUgYXBwIHNlcnZpY2UgaGFzIGZpbmlzaGVkIGluaXRpYWxpemluZ1xuICAgIGF3YWl0IHRoaXMuYXBwU2VydmljZS5pbml0KCk7XG5cbiAgICB0aGlzLmxvYWRGcm9tU3RvcmFnZSgpO1xuXG4gICAgaWYgKHRoaXMuYXBwU2VydmljZS5pc05hdGl2ZSkge1xuICAgICAgdGhpcy5fcGxhdGZvcm0gPSB0aGlzLmFwcFNlcnZpY2UuZGV2aWNlSW5mby5wbGF0Zm9ybSBhcyBQbGF0Zm9ybVZhbHVlO1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckNhcGFjaXRvckV2ZW50cygpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zd1B1c2guaXNFbmFibGVkKSB7XG4gICAgICB0aGlzLl9wbGF0Zm9ybSA9ICd3ZWInO1xuICAgICAgdGhpcy5yZWdpc3RlcldlYlB1c2hFdmVudHMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKCdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFRoZXJlIGlzIG5vIHB1c2ggY2FwYWJpbGl0eSwgdGltZXIgd2lsbCBiZSB1c2VkIHRvIHVwZGF0ZSBub3RpZmljYXRpb25zJyk7XG4gICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdVcGRhdGluZyBub3RpZmljYXRpb25zLi4uJyk7XG4gICAgICAgIHRoaXMucmVmcmVzaCh0cnVlKTtcbiAgICAgIH0sIDUgKiA2MCAqIDEwMDApO1xuICAgIH1cbiAgICB0aGlzLl9pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlZnJlc2goKTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlcigpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2V0UmVnaXN0cmF0aW9uSW5mbygpLnRoZW4oKGluZm8pID0+IHtcbiAgICAgICAgdGhpcy5odHRwLnBvc3Q8UmVnaXN0cmF0aW9uUmVzdWx0Pih0aGlzLmFwaVVybCArICdyZWdpc3RyYXRpb24nLCBpbmZvKS5zdWJzY3JpYmUoKHJlZ1Jlc3VsdCkgPT4ge1xuICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLnJlZ2lzdHJhdGlvblN0b3JhZ2VLZXksIHJlZ1Jlc3VsdC5pZCk7XG4gICAgICAgICAgX3Jlc29sdmUobnVsbCk7XG4gICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBGYWlsZWQgdG8gc2VuZCBub3RpZmljYXRpb24gcmVnaXN0cmF0aW9uIHRvIHNlcnZlci4nLCBlcnJvcik7XG4gICAgICAgICAgX3JlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiBfcmVqZWN0KGVycm9yKSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgdW5yZWdpc3RlcigpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZ2V0UmVnaXN0cmF0aW9uSW5mbygpLnRoZW4oKGluZm8pID0+IHtcbiAgICAgICAgdGhpcy5odHRwLnJlcXVlc3Q8YW55PignREVMRVRFJywgdGhpcy5hcGlVcmwgKyAncmVnaXN0cmF0aW9uJywgeyBib2R5OiBpbmZvIH0pLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMucmVnaXN0cmF0aW9uU3RvcmFnZUtleSk7XG4gICAgICAgICAgX3Jlc29sdmUobnVsbCk7XG4gICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBGYWlsZWQgdG8gcmVtb3ZlIHJlZ2lzdHJhdGlvbiBmcm9tIHNlcnZlci4nLCBlcnJvcik7XG4gICAgICAgICAgX3JlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiBfcmVqZWN0KGVycm9yKSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVmcmVzaChub3RpZnlBYm91dE5ldyA9IGZhbHNlKSB7XG4gICAgdGhpcy5odHRwLmdldDxOb3RpZmljYXRpb25bXT4odGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucycpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgdGhpcy51cGRhdGVOb3RpZmljYXRpb25zKHJlcywgbm90aWZ5QWJvdXROZXcpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldE5vdGlmaWNhdGlvbihpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxOb3RpZmljYXRpb24+IHtcbiAgICBjb25zdCBsb2NhbE5vdGlmaWNhdGlvbiA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKHggPT4geC5pZCA9PT0gaWQpO1xuICAgIGlmIChsb2NhbE5vdGlmaWNhdGlvbikge1xuICAgICAgcmV0dXJuIG9mKGxvY2FsTm90aWZpY2F0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Tm90aWZpY2F0aW9uPih0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zLycgKyBpZCk7XG4gIH1cblxuICBwdWJsaWMgcmVhZE5vdGlmaWNhdGlvbihpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgbiA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKHggPT4geC5pZCA9PT0gaWQpO1xuICAgIGlmIChuICYmICFuLmlzUmVhZCkge1xuICAgICAgbi5pc1JlYWQgPSB0cnVlO1xuICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB9XG4gICAgdGhpcy5odHRwLmdldCh0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zL3JlYWQvJyArIGlkKS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNtaXNzTm90aWZpY2F0aW9uKGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmRlbGV0ZU5vdGlmaWNhdG9uKGlkKTtcbiAgICB0aGlzLmh0dHAuZGVsZXRlKHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvJyArIGlkKS5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnJlbW92ZURlbGl2ZXJlZE5vdGlmaWNhdGlvbihpZCk7XG4gIH1cblxuICBwdWJsaWMgZGlzbWlzc0FsbCgpIHtcbiAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKDApO1xuICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgdGhpcy5odHRwLmRlbGV0ZSh0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zL2FsbCcpLnN1YnNjcmliZSgpO1xuICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycgfHwgdGhpcy5fcGxhdGZvcm0gPT09ICdhbmRyb2lkJykge1xuICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVtb3ZlQWxsRGVsaXZlcmVkTm90aWZpY2F0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5fcGxhdGZvcm0gPT09ICd3ZWInKSB7XG4gICAgICAvLyBUT0RPOiByZW1vdmUgYWxsIHdlYiBwdXNoIG5vdGlmaWNhdGlvbnNcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVhZEFsbCgpIHtcbiAgICBmb3IgKGNvbnN0IG4gb2YgdGhpcy5ub3RpZmljYXRpb25zKSB7XG4gICAgICBuLmlzUmVhZCA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgdGhpcy5odHRwLmdldCh0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zL3JlYWQvYWxsJykuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2hhbm5lbENvbmZpZyhzZW5kZXJJZDogc3RyaW5nLCBjaGFubmVsSWQ6IHN0cmluZywgbGFuZ3VhZ2U/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxVc2VyQ2hhbm5lbENvbmZpZz4odGhpcy5hcGlVcmwgKyBgc2V0dGluZ3MvY2hhbm5lbC8ke3NlbmRlcklkfS8ke2NoYW5uZWxJZH0/bGFuZ3VhZ2U9JHtsYW5ndWFnZX1gKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFubmVsQ29uZmlnc0ZvclNlbmRlcihzZW5kZXJJZDogc3RyaW5nLCBjaGFubmVsSWRzOiBzdHJpbmdbXSwgbGFuZ3VhZ2U/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBpZHNTdHIgPSBjaGFubmVsSWRzLm1hcCh4ID0+IHNlbmRlcklkICsgJywnICsgeCkuam9pbignOycpO1xuICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxDb25maWdzSW50ZXJuYWwoaWRzU3RyLCBsYW5ndWFnZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2hhbm5lbENvbmZpZ3MoaWRzOiBDaGFubmVsSWRbXSwgbGFuZ3VhZ2U/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBpZHNTdHIgPSBpZHMubWFwKHggPT4geC5zZW5kZXJJZCArICcsJyArIHguY2hhbm5lbElkKS5qb2luKCc7Jyk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2hhbm5lbENvbmZpZ3NJbnRlcm5hbChpZHNTdHIsIGxhbmd1YWdlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDaGFubmVsQ29uZmlnKHNlbmRlcklkOiBzdHJpbmcsIGNvbmZpZzogVXNlckNoYW5uZWxDb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8dm9pZD4oYCR7dGhpcy5hcGlVcmx9c2V0dGluZ3MvY2hhbm5lbC8ke3NlbmRlcklkfWAsIGNvbmZpZyk7XG4gIH1cblxuICBwdWJsaWMgc2V0Q2hhbm5lbENvbmZpZ3MoY29uZmlnczogVXNlckNoYW5uZWxDb25maWdbXSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPihgJHt0aGlzLmFwaVVybH1zZXR0aW5ncy9jaGFubmVsc2AsIGNvbmZpZ3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDaGFubmVsQ29uZmlnc0ludGVybmFsKGlkczogc3RyaW5nLCBsYW5ndWFnZT86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFVzZXJDaGFubmVsQ29uZmlnW10+KGAke3RoaXMuYXBpVXJsfXNldHRpbmdzL2NoYW5uZWxzP2lkcz0ke2lkc30mbGFuZ3VhZ2U9JHtsYW5ndWFnZX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTm90aWZpY2F0aW9ucyhuZXdOb3RpZmljYXRpb25zOiBOb3RpZmljYXRpb25bXSwgbm90aWZ5QWJvdXROZXcgPSBmYWxzZSkge1xuICAgIGxldCBzdGF0ZUNoYW5nZWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IG4gb2YgbmV3Tm90aWZpY2F0aW9ucykge1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLm5vdGlmaWNhdGlvbnMuZmluZCh4ID0+IHguaWQgPT09IG4uaWQpO1xuICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgIGlmIChleGlzdGluZy5pc1JlYWQgIT09IG4uaXNSZWFkKSB7XG4gICAgICAgICAgZXhpc3RpbmcuaXNSZWFkID0gbi5pc1JlYWQ7XG4gICAgICAgICAgc3RhdGVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IHRoaXMubm90aWZpY2F0aW9ucy5sZW5ndGggJiYgbi5kYXRlQ3JlYXRlZCA8IHRoaXMubm90aWZpY2F0aW9uc1tpXS5kYXRlQ3JlYXRlZCkge1xuICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDAsIG4pO1xuICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xuICAgICAgICBpZiAobm90aWZ5QWJvdXROZXcpIHtcbiAgICAgICAgICB0aGlzLl9uZXdOb3RpZmljYXRpb25zLm5leHQobik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGZvciAobGV0IGkgPSB0aGlzLm5vdGlmaWNhdGlvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IG4gPSB0aGlzLm5vdGlmaWNhdGlvbnNbaV07XG4gICAgICBpZiAobmV3IERhdGUobi5leHBpcmF0aW9uRGF0ZSkuZ2V0VGltZSgpIDwgbm93IHx8ICFuZXdOb3RpZmljYXRpb25zLmZpbmQoeCA9PiB4LmlkID09PSBuLmlkKSkge1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDEpO1xuICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGF0ZUNoYW5nZWQpIHtcbiAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzYXZlVG9TdG9yYWdlKCkge1xuICAgIGNvbnN0IHN0ciA9IEpTT04uc3RyaW5naWZ5KHRoaXMubm90aWZpY2F0aW9ucyk7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMubm90aWZpY2F0aW9uc1N0b3JhZ2VLZXksIHN0cik7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tU3RvcmFnZSgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RyID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubm90aWZpY2F0aW9uc1N0b3JhZ2VLZXkpO1xuICAgICAgaWYgKHN0cikge1xuICAgICAgICBjb25zdCBub3RpZmljYXRpb25zID0gSlNPTi5wYXJzZShzdHIpIGFzIE5vdGlmaWNhdGlvbltdO1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMgPSBub3RpZmljYXRpb25zLmZpbHRlcih4ID0+ICEheCk7XG4gICAgICAgIC8vIHByZWNhdXRpb24gZm9yIG5vdGlmaWNhdGlvbi5pc1JlYWQgb2YgdW5kZWZpbmVkIGVycm9yXG4gICAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHsgLyogZW1wdHkgKi8gfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVOb3RpZmljYXRpb25FdmVudChpZDogc3RyaW5nLCBldmVudFR5cGU6IE5vdGlmaWNhdGlvbkV2ZW50VHlwZSkge1xuICAgIGlmIChldmVudFR5cGUuc3RhcnRzV2l0aCgnbmV3JykgfHwgZXZlbnRUeXBlID09PSAndXBkYXRlZCcpIHsgLy8gd2UgYXJlIGhhbmRsaW5nIG5ldyBhbmQgbmV3U2lsZW50XG4gICAgICB0aGlzLmdldE5vdGlmaWNhdGlvbihpZCkuc3Vic2NyaWJlKG4gPT4ge1xuICAgICAgICBpZiAoZXZlbnRUeXBlLnN0YXJ0c1dpdGgoJ25ldycpICYmICFuLmlzUmVhZCkge1xuICAgICAgICAgIHRoaXMuX25ld05vdGlmaWNhdGlvbnMubmV4dChuKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKHggPT4geC5pZCA9PT0gbi5pZCk7XG4gICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgIGV4aXN0aW5nLmlzUmVhZCA9IG4uaXNSZWFkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9ucy5zcGxpY2UoMCwgMCwgbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoZXZlbnRUeXBlID09PSAnZGVsZXRlZCcpIHtcbiAgICAgIHRoaXMuZGVsZXRlTm90aWZpY2F0b24oaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlZnJlc2goKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZU5vdGlmaWNhdG9uKGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBpID0gdGhpcy5ub3RpZmljYXRpb25zLmZpbmRJbmRleCh4ID0+IHguaWQgPT09IGlkKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDEpO1xuICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG5vdGlmeVN0YXRlQ2hhbmdlZChwZXJzaXN0U3RhdGUgPSB0cnVlKSB7XG4gICAgaWYgKHBlcnNpc3RTdGF0ZSkge1xuICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XG4gICAgfVxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlc1N1YmplY3QubmV4dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVOb3RpZmljYXRpb25BY3Rpb24obm90aWZpY2F0aW9uQWN0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoIW5vdGlmaWNhdGlvbkFjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3RpZmljYXRpb24gYWN0aW9uIGlzIGVtcHR5IScpO1xuICAgIH1cblxuICAgIGNvbnN0IGFyciA9IG5vdGlmaWNhdGlvbkFjdGlvbi5zcGxpdCgnOicpO1xuICAgIGNvbnN0IG5vdGlmaWNhdGlvbkNsaWNrOiBOb3RpZmljYXRpb25DbGljayA9IHtcbiAgICAgIGlkOiBhcnJbMF0sXG4gICAgICB0eXBlOiBhcnJbMV0gYXMgTm90aWZpY2F0aW9uVHlwZSxcbiAgICAgIHJvdXRlckxpbms6IGFyclsyXVxuICAgIH07XG5cbiAgICBjb25zdCB2YWxpZE5vdGlmaWNhdGlvbkNsaWNrVHlwZXMgPSBbJ2RlZmF1bHQnLCAnZGVlcGxpbmsnXTtcbiAgICBpZiAodmFsaWROb3RpZmljYXRpb25DbGlja1R5cGVzLmluY2x1ZGVzKG5vdGlmaWNhdGlvbkNsaWNrLnR5cGUpKSB7XG4gICAgICB0aGlzLl9jbGlja3NTdWJqZWN0Lm5leHQobm90aWZpY2F0aW9uQ2xpY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFVua25vd24gbm90aWZpY2F0aW9uIGFjdGlvbjogJyR7bm90aWZpY2F0aW9uQWN0aW9ufScuYCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVEZWxpdmVyZWROb3RpZmljYXRpb24oaWQ6IHN0cmluZykge1xuICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycgfHwgdGhpcy5fcGxhdGZvcm0gPT09ICdhbmRyb2lkJykge1xuICAgICAgUHVzaE5vdGlmaWNhdGlvbnMuZ2V0RGVsaXZlcmVkTm90aWZpY2F0aW9ucygpLnRoZW4obGlzdCA9PiB7XG4gICAgICAgIGNvbnN0IHRvUmVtb3ZlID0gbGlzdC5ub3RpZmljYXRpb25zLmZpbHRlcihuID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5nZXROb3RpZmljYXRpb25QYXlsb2FkRGF0YShuKTtcbiAgICAgICAgICByZXR1cm4gKGRhdGEubm90aWZpY2F0aW9uSWQgPT09IGlkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVE9ETzogT24gQW5kcm9pZCB0aGlzIGRvZXMgbm90IGN1cnJlbnRseSB3b3JrIGJlY2F1c2Ugbm90aWZpY2F0aW9uSUQgaXMgbm90IHNldC5cbiAgICAgICAgLy8gVGhpcyBteSBzb2x2ZSB0aGUgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9pb25pYy10ZWFtL2NhcGFjaXRvci9wdWxsLzM1MjNcbiAgICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9ucyh7XG4gICAgICAgICAgbm90aWZpY2F0aW9uczogdG9SZW1vdmVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnd2ViJykge1xuICAgICAgLy8gVE9ETzogcmVtb3ZlIHdlYiBwdXNoIG5vdGlmaWNhdGlvblxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Tm90aWZpY2F0aW9uUGF5bG9hZERhdGEocHVzaE5vdGlmaWNhdGlvbjogUHVzaE5vdGlmaWNhdGlvblNjaGVtYSk6IFBheWxvYWREYXRhIHtcbiAgICByZXR1cm4gKHRoaXMuX3BsYXRmb3JtID09PSAnaW9zJykgPyBwdXNoTm90aWZpY2F0aW9uLmRhdGEuZGF0YSA6IHB1c2hOb3RpZmljYXRpb24uZGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVnaXN0ZXJDYXBhY2l0b3JFdmVudHMoKSB7XG4gICAgYXdhaXQgUHVzaE5vdGlmaWNhdGlvbnMuYWRkTGlzdGVuZXIoJ3B1c2hOb3RpZmljYXRpb25SZWNlaXZlZCcsIG4gPT4ge1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2V0Tm90aWZpY2F0aW9uUGF5bG9hZERhdGEobik7XG4gICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBSZWNlaXZlZCBjYXBhY2l0b3IgcHVzaCBldmVudDogJyArIGRhdGEuZXZlbnRUeXBlLCBuKTtcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZGF0YS5ub3RpZmljYXRpb25JZCwgZGF0YS5ldmVudFR5cGUpO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgUHVzaE5vdGlmaWNhdGlvbnMuYWRkTGlzdGVuZXIoJ3B1c2hOb3RpZmljYXRpb25BY3Rpb25QZXJmb3JtZWQnLCBhID0+IHtcbiAgICAgIGxldCBhY3Rpb24gPSAoYSBhcyBhbnkpLm5vdGlmaWNhdGlvbi5kYXRhLm5vdGlmaWNhdGlvbkFjdGlvbjtcbiAgICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycpIHtcbiAgICAgICAgYWN0aW9uID0gKGEgYXMgYW55KS5ub3RpZmljYXRpb24uZGF0YS5kYXRhLm5vdGlmaWNhdGlvbkFjdGlvbjtcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKCdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIGNhcGFjaXRvciBhY3Rpb24gZXZlbnQnLCBhY3Rpb24pO1xuICAgICAgdGhpcy5oYW5kbGVOb3RpZmljYXRpb25BY3Rpb24oYWN0aW9uKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJXZWJQdXNoRXZlbnRzKCkge1xuICAgIHRoaXMuc3dQdXNoLm1lc3NhZ2VzLnN1YnNjcmliZSgobikgPT4ge1xuICAgICAgY29uc3QgZGF0YTogUGF5bG9hZERhdGEgPSAobiBhcyBhbnkpLmRhdGE7XG4gICAgICBjb25zb2xlLmxvZygnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBSZWNlaXZlZCBXZWJQdXNoIGV2ZW50OiAnICsgZGF0YS5ldmVudFR5cGUsIG4pO1xuICAgICAgdGhpcy5oYW5kbGVOb3RpZmljYXRpb25FdmVudChkYXRhLm5vdGlmaWNhdGlvbklkLCBkYXRhLmV2ZW50VHlwZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN3UHVzaC5ub3RpZmljYXRpb25DbGlja3Muc3Vic2NyaWJlKChhY3Rpb24pID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKCdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIFdlYlB1c2ggYWN0aW9uIGV2ZW50JywgYWN0aW9uKTtcbiAgICAgIGNvbnN0IHRhZyA9IGFjdGlvbi5ub3RpZmljYXRpb24udGFnO1xuICAgICAgdGhpcy5oYW5kbGVOb3RpZmljYXRpb25BY3Rpb24odGFnKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UmVnaXN0cmF0aW9uSW5mbygpOiBQcm9taXNlPFJlZ2lzdHJhdGlvbj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2lzdHJhdGlvbklkID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMucmVnaXN0cmF0aW9uU3RvcmFnZUtleSkgYXMgc3RyaW5nO1xuICAgICAgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnYW5kcm9pZCcgfHwgdGhpcy5fcGxhdGZvcm0gPT09ICdpb3MnKSB7XG4gICAgICAgIC8vIGNhcGFjaXRvciBwbGF0Zm9ybVxuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IFB1c2hOb3RpZmljYXRpb25zLmFkZExpc3RlbmVyKCdyZWdpc3RyYXRpb24nLCB0b2tlbiA9PiB7XG4gICAgICAgICAgbGlzdGVuZXIucmVtb3ZlKCk7XG4gICAgICAgICAgX3Jlc29sdmUoeyBpZDogcmVnaXN0cmF0aW9uSWQsIHRva2VuOiB0b2tlbi52YWx1ZSwgcGxhdGZvcm06IHRoaXMuX3BsYXRmb3JtIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVnaXN0ZXIoKS5jYXRjaChlcnJvciA9PiBfcmVqZWN0KCdDb3VsZCBub3QgcmVnaXN0ZXIgZm9yIG5vdGlmaWNhdGlvbnM6JyArIGVycm9yKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnd2ViJykge1xuICAgICAgICAvLyBXZWIgUHVzaCBBUElcbiAgICAgICAgdGhpcy5odHRwLmdldDxXZWJLZXk+KHRoaXMuYXBpVXJsICsgJ3JlZ2lzdHJhdGlvbi93ZWJrZXknKS5zdWJzY3JpYmUoa2V5ID0+IHtcbiAgICAgICAgICB0aGlzLmdldFdlYlB1c2hTdWJzY3JpcHRpb24oa2V5LnB1YmxpY0tleSkudGhlbihzdWJzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3QgdCA9IEpTT04uc3RyaW5naWZ5KHN1YnNjcmlwdGlvbi50b0pTT04oKSk7XG4gICAgICAgICAgICBfcmVzb2x2ZSh7IGlkOiByZWdpc3RyYXRpb25JZCwgdG9rZW46IHQsIHBsYXRmb3JtOiAnd2ViJyB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZXJyb3IgPT4gX3JlamVjdChlcnJvcikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX3JlamVjdChgTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBQbGF0Zm9ybSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFdlYlB1c2hTdWJzY3JpcHRpb24ocHVibGljS2V5OiBzdHJpbmcpOiBQcm9taXNlPFB1c2hTdWJzY3JpcHRpb24+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnN3UHVzaC5zdWJzY3JpcHRpb24uc3Vic2NyaWJlKHN1YnNjcmlwdGlvbiA9PiB7XG4gICAgICAgIGlmIChzdWJzY3JpcHRpb24gIT0gbnVsbCkge1xuICAgICAgICAgIF9yZXNvbHZlKHN1YnNjcmlwdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zd1B1c2gucmVxdWVzdFN1YnNjcmlwdGlvbih7IHNlcnZlclB1YmxpY0tleTogcHVibGljS2V5IH0pLnRoZW4ocyA9PiBfcmVzb2x2ZShzKSkuY2F0Y2goZSA9PiBfcmVqZWN0KGUpKTtcbiAgICAgICAgfVxuICAgICAgfSwgZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IENhbm5vdCBnZXQgd2ViIHB1c2ggc3Vic2NyaXB0aW9uJywgZXJyb3IpO1xuICAgICAgICBfcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG4iXX0=
|