@kolektor/nucleus-notifications 0.0.12-pre.7931 → 0.1.130-pre.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ # nucleus-notifications
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Running unit tests
6
+
7
+ Run `nx test nucleus-notifications` to execute the unit tests.
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25nL251Y2xldXMvbnVjbGV1cy1ub3RpZmljYXRpb25zL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHFDQUFxQyxDQUFDO0FBQ3BELGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMuc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMubW9kdWxlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscyc7XG4iXX0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia29sZWt0b3ItbnVjbGV1cy1ub3RpZmljYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9uZy9udWNsZXVzL251Y2xldXMtbm90aWZpY2F0aW9ucy9zcmMva29sZWt0b3ItbnVjbGV1cy1ub3RpZmljYXRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9uZy9udWNsZXVzL251Y2xldXMtbm90aWZpY2F0aW9ucy9zcmMvbGliL21vZGVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sWUFBWTtDQU94QjtBQUVELE1BQU0sT0FBTyxRQUFRO0NBSXBCO0FBRUQsTUFBTSxPQUFPLFNBQVM7Q0FJckI7QUFFRCxNQUFNLE9BQU8sZ0JBQWdCO0NBTTVCO0FBRUQsTUFBTSxPQUFPLE1BQU07Q0FFbEI7QUFFRCxNQUFNLE9BQU8sWUFBWTtDQUl4QjtBQUVELE1BQU0sT0FBTyxrQkFBa0I7Q0FFOUI7QUFFRCxNQUFNLE9BQU8sV0FBVztDQUd2QjtBQUVELE1BQU0sT0FBTywwQkFBMEI7Q0FFdEM7QUFFRCxNQUFNLE9BQU8saUJBQWlCO0NBSTdCO0FBbUJELE1BQU0sT0FBTyxpQkFBaUI7Q0FPN0IiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uIHtcbiAgcHVibGljIGlkOiBzdHJpbmc7XG4gIHB1YmxpYyBzZW5kZXI6IElkZW50aXR5O1xuICBwdWJsaWMgZGF0YTogTm90aWZpY2F0aW9uRGF0YTtcbiAgcHVibGljIGlzUmVhZDogYm9vbGVhbjtcbiAgcHVibGljIGRhdGVDcmVhdGVkOiBEYXRlO1xuICBwdWJsaWMgZXhwaXJhdGlvbkRhdGU6IERhdGU7XG59XG5cbmV4cG9ydCBjbGFzcyBJZGVudGl0eSB7XG4gIHB1YmxpYyBzdWJqZWN0OiBzdHJpbmc7XG4gIHB1YmxpYyBuYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyBwaWN0dXJlVXJsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWNpcGllbnQge1xuICBwdWJsaWMgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgZGlyZWN0b3J5TmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYXR0cmlidXRlVmFsdWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvbkRhdGEge1xuICB0aXRsZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGh0bWxNZXNzYWdlOiBzdHJpbmc7XG4gIHByZXZlbnREaXNtaXNzYWw6IGJvb2xlYW47XG4gIGRlZXBMaW5rOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJLZXkge1xuICBwdWJsaWNLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFJlZ2lzdHJhdGlvbiB7XG4gIGlkOiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIHBsYXRmb3JtOiBQbGF0Zm9ybVZhbHVlO1xufVxuXG5leHBvcnQgY2xhc3MgUmVnaXN0cmF0aW9uUmVzdWx0IHtcbiAgaWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFBheWxvYWREYXRhIHtcbiAgbm90aWZpY2F0aW9uSWQ6IHN0cmluZztcbiAgZXZlbnRUeXBlOiBOb3RpZmljYXRpb25FdmVudFR5cGU7XG59XG5cbmV4cG9ydCBjbGFzcyBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZyB7XG4gIHNlcnZlckFwaVVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uQ2xpY2sge1xuICBpZDogc3RyaW5nO1xuICB0eXBlOiBOb3RpZmljYXRpb25UeXBlO1xuICByb3V0ZXJMaW5rPzogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25FdmVudFR5cGUgPVxuICB8ICduZXcnXG4gIHwgJ3VwZGF0ZWQnXG4gIHwgJ2RlbGV0ZWQnXG4gIHwgJ2RlbGV0ZWRBbGwnXG4gIHwgJ3VwZGF0ZWRBbGwnXG4gIHwgJ25ld1NpbGVudCc7XG5cbmV4cG9ydCB0eXBlIFBsYXRmb3JtVmFsdWUgPSAnaW9zJyB8ICdhbmRyb2lkJyB8ICd3ZWInIHwgJ25vbmUnO1xuXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25UeXBlID0gJ2RlZmF1bHQnIHwgJ2RlZXBsaW5rJztcblxuZXhwb3J0IGludGVyZmFjZSBDaGFubmVsSWQge1xuICBzZW5kZXJJZDogc3RyaW5nO1xuICBjaGFubmVsSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFVzZXJDaGFubmVsQ29uZmlnIHtcbiAgY2hhbm5lbElkOiBzdHJpbmc7XG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIGlzU3Vic2NyaWJlZDogYm9vbGVhbjtcbiAgc3Vic2NyaXB0aW9uVHlwZTogQ2hhbm5lbFN1YnNjcmlwdGlvblR5cGU7XG4gIG1ldGhvZHM6IE5vdGlmeU1ldGhvZFtdO1xuICBhbGxvd2VkTWV0aG9kczogTm90aWZ5TWV0aG9kW107XG59XG5cbmV4cG9ydCB0eXBlIENoYW5uZWxTdWJzY3JpcHRpb25UeXBlID0gJ2ludmFyaWFudCcgfCAnb3B0SW4nIHwgJ29wdE91dCc7XG5cbmV4cG9ydCB0eXBlIE5vdGlmeU1ldGhvZCA9ICdwdXNoJyB8ICdlbWFpbCcgfCAnc21zJztcbiJdfQ==
@@ -0,0 +1,23 @@
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: [{ provide: NucleusNotificationsConfig, useValue: config }],
9
+ };
10
+ }
11
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
12
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
13
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
14
+ }
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, decorators: [{
16
+ type: NgModule,
17
+ args: [{
18
+ declarations: [],
19
+ imports: [],
20
+ exports: [],
21
+ }]
22
+ }] });
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmcvbnVjbGV1cy9udWNsZXVzLW5vdGlmaWNhdGlvbnMvc3JjL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQXVCLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7QUFPdEQsTUFBTSxPQUFPLDBCQUEwQjtJQUNyQyxNQUFNLENBQUMsT0FBTyxDQUNaLE1BQWtDO1FBRWxDLE9BQU87WUFDTCxRQUFRLEVBQUUsMEJBQTBCO1lBQ3BDLFNBQVMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQztTQUN2RSxDQUFDO0lBQ0osQ0FBQzsrR0FSVSwwQkFBMEI7Z0hBQTFCLDBCQUEwQjtnSEFBMUIsMEJBQTBCOzs0RkFBMUIsMEJBQTBCO2tCQUx0QyxRQUFRO21CQUFDO29CQUNSLFlBQVksRUFBRSxFQUFFO29CQUNoQixPQUFPLEVBQUUsRUFBRTtvQkFDWCxPQUFPLEVBQUUsRUFBRTtpQkFDWiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlLCBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZyB9IGZyb20gJy4vbW9kZWxzJztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbXSxcbiAgaW1wb3J0czogW10sXG4gIGV4cG9ydHM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBOdWNsZXVzTm90aWZpY2F0aW9uc01vZHVsZSB7XG4gIHN0YXRpYyBmb3JSb290KFxuICAgIGNvbmZpZzogTnVjbGV1c05vdGlmaWNhdGlvbnNDb25maWdcbiAgKTogTW9kdWxlV2l0aFByb3ZpZGVyczxOdWNsZXVzTm90aWZpY2F0aW9uc01vZHVsZT4ge1xuICAgIHJldHVybiB7XG4gICAgICBuZ01vZHVsZTogTnVjbGV1c05vdGlmaWNhdGlvbnNNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnLCB1c2VWYWx1ZTogY29uZmlnIH1dLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,387 @@
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()
72
+ .then((info) => {
73
+ this.http
74
+ .post(this.apiUrl + 'registration', info)
75
+ .subscribe((regResult) => {
76
+ window.localStorage.setItem(this.registrationStorageKey, regResult.id);
77
+ _resolve(null);
78
+ }, (error) => {
79
+ console.log('Nucleus.Notifications: Failed to send notification registration to server.', error);
80
+ _reject(error);
81
+ });
82
+ })
83
+ .catch((error) => _reject(error));
84
+ });
85
+ }
86
+ unregister() {
87
+ return new Promise((_resolve, _reject) => {
88
+ this.getRegistrationInfo()
89
+ .then((info) => {
90
+ this.http
91
+ .request('DELETE', this.apiUrl + 'registration', {
92
+ body: info,
93
+ })
94
+ .subscribe(() => {
95
+ window.localStorage.removeItem(this.registrationStorageKey);
96
+ _resolve(null);
97
+ }, (error) => {
98
+ console.log('Nucleus.Notifications: Failed to remove registration from server.', error);
99
+ _reject(error);
100
+ });
101
+ })
102
+ .catch((error) => _reject(error));
103
+ });
104
+ }
105
+ refresh(notifyAboutNew = false) {
106
+ this.http
107
+ .get(this.apiUrl + 'notifications')
108
+ .subscribe((res) => {
109
+ this.updateNotifications(res, notifyAboutNew);
110
+ });
111
+ }
112
+ getNotification(id) {
113
+ const localNotification = this.notifications.find((x) => x.id === id);
114
+ if (localNotification) {
115
+ return of(localNotification);
116
+ }
117
+ return this.http.get(this.apiUrl + 'notifications/' + id);
118
+ }
119
+ readNotification(id) {
120
+ const n = this.notifications.find((x) => x.id === id);
121
+ if (n && !n.isRead) {
122
+ n.isRead = true;
123
+ this.notifyStateChanged();
124
+ }
125
+ this.http.get(this.apiUrl + 'notifications/read/' + id).subscribe();
126
+ }
127
+ dismissNotification(id) {
128
+ this.deleteNotificaton(id);
129
+ this.http.delete(this.apiUrl + 'notifications/' + id).subscribe();
130
+ this.removeDeliveredNotification(id);
131
+ }
132
+ dismissAll() {
133
+ this.notifications.splice(0);
134
+ this.notifyStateChanged();
135
+ this.http.delete(this.apiUrl + 'notifications/all').subscribe();
136
+ if (this._platform === 'ios' || this._platform === 'android') {
137
+ PushNotifications.removeAllDeliveredNotifications();
138
+ }
139
+ else if (this._platform === 'web') {
140
+ // TODO: remove all web push notifications
141
+ }
142
+ }
143
+ readAll() {
144
+ for (const n of this.notifications) {
145
+ n.isRead = true;
146
+ }
147
+ this.notifyStateChanged();
148
+ this.http.get(this.apiUrl + 'notifications/read/all').subscribe();
149
+ }
150
+ getChannelConfig(senderId, channelId, language) {
151
+ return this.http.get(this.apiUrl +
152
+ `settings/channel/${senderId}/${channelId}?language=${language}`);
153
+ }
154
+ getChannelConfigsForSender(senderId, channelIds, language) {
155
+ const idsStr = channelIds.map((x) => senderId + ',' + x).join(';');
156
+ return this.getChannelConfigsInternal(idsStr, language);
157
+ }
158
+ getChannelConfigs(ids, language) {
159
+ const idsStr = ids.map((x) => x.senderId + ',' + x.channelId).join(';');
160
+ return this.getChannelConfigsInternal(idsStr, language);
161
+ }
162
+ setChannelConfig(senderId, config) {
163
+ return this.http.post(`${this.apiUrl}settings/channel/${senderId}`, config);
164
+ }
165
+ setChannelConfigs(configs) {
166
+ return this.http.post(`${this.apiUrl}settings/channels`, configs);
167
+ }
168
+ getChannelConfigsInternal(ids, language) {
169
+ return this.http.get(`${this.apiUrl}settings/channels?ids=${ids}&language=${language}`);
170
+ }
171
+ updateNotifications(newNotifications, notifyAboutNew = false) {
172
+ let stateChanged = false;
173
+ for (const n of newNotifications) {
174
+ const existing = this.notifications.find((x) => x.id === n.id);
175
+ if (existing) {
176
+ if (existing.isRead !== n.isRead) {
177
+ existing.isRead = n.isRead;
178
+ stateChanged = true;
179
+ }
180
+ }
181
+ else {
182
+ let i = 0;
183
+ while (i < this.notifications.length &&
184
+ n.dateCreated < this.notifications[i].dateCreated) {
185
+ i++;
186
+ }
187
+ this.notifications.splice(i, 0, n);
188
+ stateChanged = true;
189
+ if (notifyAboutNew) {
190
+ this._newNotifications.next(n);
191
+ }
192
+ }
193
+ }
194
+ const now = Date.now();
195
+ for (let i = this.notifications.length - 1; i >= 0; i--) {
196
+ const n = this.notifications[i];
197
+ if (new Date(n.expirationDate).getTime() < now ||
198
+ !newNotifications.find((x) => x.id === n.id)) {
199
+ this.notifications.splice(i, 1);
200
+ stateChanged = true;
201
+ }
202
+ }
203
+ if (stateChanged) {
204
+ this.notifyStateChanged();
205
+ }
206
+ }
207
+ saveToStorage() {
208
+ const str = JSON.stringify(this.notifications);
209
+ window.localStorage.setItem(this.notificationsStorageKey, str);
210
+ }
211
+ loadFromStorage() {
212
+ try {
213
+ const str = window.localStorage.getItem(this.notificationsStorageKey);
214
+ if (str) {
215
+ const notifications = JSON.parse(str);
216
+ this.notifications = notifications.filter((x) => !!x);
217
+ // precaution for notification.isRead of undefined error
218
+ this.notifyStateChanged(false);
219
+ }
220
+ }
221
+ catch {
222
+ /* empty */
223
+ }
224
+ }
225
+ handleNotificationEvent(id, eventType) {
226
+ if (eventType.startsWith('new') || eventType === 'updated') {
227
+ // we are handling new and newSilent
228
+ this.getNotification(id).subscribe((n) => {
229
+ if (eventType.startsWith('new') && !n.isRead) {
230
+ this._newNotifications.next(n);
231
+ }
232
+ const existing = this.notifications.find((x) => x.id === n.id);
233
+ if (existing) {
234
+ existing.isRead = n.isRead;
235
+ }
236
+ else {
237
+ this.notifications.splice(0, 0, n);
238
+ }
239
+ this.notifyStateChanged();
240
+ });
241
+ }
242
+ else if (eventType === 'deleted') {
243
+ this.deleteNotificaton(id);
244
+ }
245
+ else {
246
+ this.refresh();
247
+ }
248
+ }
249
+ deleteNotificaton(id) {
250
+ const i = this.notifications.findIndex((x) => x.id === id);
251
+ if (i >= 0) {
252
+ this.notifications.splice(i, 1);
253
+ this.notifyStateChanged();
254
+ }
255
+ }
256
+ notifyStateChanged(persistState = true) {
257
+ if (persistState) {
258
+ this.saveToStorage();
259
+ }
260
+ this._stateChangesSubject.next();
261
+ }
262
+ handleNotificationAction(notificationAction) {
263
+ if (!notificationAction) {
264
+ throw new Error('Notification action is empty!');
265
+ }
266
+ const arr = notificationAction.split(':');
267
+ const notificationClick = {
268
+ id: arr[0],
269
+ type: arr[1],
270
+ routerLink: arr[2],
271
+ };
272
+ const validNotificationClickTypes = ['default', 'deeplink'];
273
+ if (validNotificationClickTypes.includes(notificationClick.type)) {
274
+ this._clicksSubject.next(notificationClick);
275
+ }
276
+ else {
277
+ console.error(`Nucleus.Notifications: Unknown notification action: '${notificationAction}'.`);
278
+ }
279
+ }
280
+ removeDeliveredNotification(id) {
281
+ if (this._platform === 'ios' || this._platform === 'android') {
282
+ PushNotifications.getDeliveredNotifications().then((list) => {
283
+ const toRemove = list.notifications.filter((n) => {
284
+ const data = this.getNotificationPayloadData(n);
285
+ return data.notificationId === id;
286
+ });
287
+ // TODO: On Android this does not currently work because notificationID is not set.
288
+ // This my solve the issue: https://github.com/ionic-team/capacitor/pull/3523
289
+ PushNotifications.removeDeliveredNotifications({
290
+ notifications: toRemove,
291
+ });
292
+ });
293
+ }
294
+ else if (this._platform === 'web') {
295
+ // TODO: remove web push notification
296
+ }
297
+ }
298
+ getNotificationPayloadData(pushNotification) {
299
+ return this._platform === 'ios'
300
+ ? pushNotification.data.data
301
+ : pushNotification.data;
302
+ }
303
+ async registerCapacitorEvents() {
304
+ await PushNotifications.addListener('pushNotificationReceived', (n) => {
305
+ const data = this.getNotificationPayloadData(n);
306
+ console.log('Nucleus.Notifications: Received capacitor push event: ' +
307
+ data.eventType, n);
308
+ this.handleNotificationEvent(data.notificationId, data.eventType);
309
+ });
310
+ await PushNotifications.addListener('pushNotificationActionPerformed', (a) => {
311
+ let action = a.notification.data.notificationAction;
312
+ if (this._platform === 'ios') {
313
+ action = a.notification.data.data.notificationAction;
314
+ }
315
+ console.log('Nucleus.Notifications: Received capacitor action event', action);
316
+ this.handleNotificationAction(action);
317
+ });
318
+ }
319
+ registerWebPushEvents() {
320
+ this.swPush.messages.subscribe((n) => {
321
+ const data = n.data;
322
+ console.log('Nucleus.Notifications: Received WebPush event: ' + data.eventType, n);
323
+ this.handleNotificationEvent(data.notificationId, data.eventType);
324
+ });
325
+ this.swPush.notificationClicks.subscribe((action) => {
326
+ console.log('Nucleus.Notifications: Received WebPush action event', action);
327
+ const tag = action.notification.tag;
328
+ this.handleNotificationAction(tag);
329
+ });
330
+ }
331
+ getRegistrationInfo() {
332
+ return new Promise((_resolve, _reject) => {
333
+ const registrationId = window.localStorage.getItem(this.registrationStorageKey);
334
+ if (this._platform === 'android' || this._platform === 'ios') {
335
+ // capacitor platform
336
+ const listener = PushNotifications.addListener('registration', (token) => {
337
+ listener.remove();
338
+ _resolve({
339
+ id: registrationId,
340
+ token: token.value,
341
+ platform: this._platform,
342
+ });
343
+ });
344
+ PushNotifications.register().catch((error) => _reject('Could not register for notifications:' + error));
345
+ }
346
+ else if (this._platform === 'web') {
347
+ // Web Push API
348
+ this.http.get(this.apiUrl + 'registration/webkey').subscribe((key) => {
349
+ this.getWebPushSubscription(key.publicKey).then((subscription) => {
350
+ const t = JSON.stringify(subscription.toJSON());
351
+ _resolve({ id: registrationId, token: t, platform: 'web' });
352
+ });
353
+ }, (error) => _reject(error));
354
+ }
355
+ else {
356
+ _reject(`Nucleus.Notifications: Platform is not supported`);
357
+ }
358
+ });
359
+ }
360
+ getWebPushSubscription(publicKey) {
361
+ return new Promise((_resolve, _reject) => {
362
+ this.swPush.subscription.subscribe((subscription) => {
363
+ if (subscription != null) {
364
+ _resolve(subscription);
365
+ }
366
+ else {
367
+ this.swPush
368
+ .requestSubscription({ serverPublicKey: publicKey })
369
+ .then((s) => _resolve(s))
370
+ .catch((e) => _reject(e));
371
+ }
372
+ }, (error) => {
373
+ console.error('Nucleus.Notifications: Cannot get web push subscription', error);
374
+ _reject(error);
375
+ });
376
+ });
377
+ }
378
+ 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 }); }
379
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, providedIn: 'root' }); }
380
+ }
381
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, decorators: [{
382
+ type: Injectable,
383
+ args: [{
384
+ providedIn: 'root',
385
+ }]
386
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.SwPush }, { type: i3.NucleusAppService }, { type: i4.NucleusNotificationsConfig }]; } });
387
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL25nL251Y2xldXMvbnVjbGV1cy1ub3RpZmljYXRpb25zL3NyYy9saWIvbnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRCxPQUFPLEVBQ0wsaUJBQWlCLEdBRWxCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0QsT0FBTyxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQU1MLDBCQUEwQixHQU8zQixNQUFNLFVBQVUsQ0FBQzs7Ozs7O0FBS2xCLE1BQU0sT0FBTywyQkFBMkI7SUFDdEMsWUFDVSxJQUFnQixFQUNoQixNQUFjLEVBQ2QsVUFBNkIsRUFDckMsTUFBa0M7UUFIMUIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNoQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7UUFXdEIsMkJBQXNCLEdBQ3JDLG9DQUFvQyxDQUFDO1FBQ3RCLDRCQUF1QixHQUFHLGdDQUFnQyxDQUFDO1FBRXBFLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFnQixDQUFDO1FBQ2hELG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQXFCLENBQUM7UUFDbEQseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUU1Qyxr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OzRGQUVQLDJCQUEyQjtrQkFIdkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3dQdXNoIH0gZnJvbSAnQGFuZ3VsYXIvc2VydmljZS13b3JrZXInO1xuaW1wb3J0IHtcbiAgUHVzaE5vdGlmaWNhdGlvbnMsXG4gIFB1c2hOb3RpZmljYXRpb25TY2hlbWEsXG59IGZyb20gJ0BjYXBhY2l0b3IvcHVzaC1ub3RpZmljYXRpb25zJztcbmltcG9ydCB7IE51Y2xldXNBcHBTZXJ2aWNlIH0gZnJvbSAnQGtvbGVrdG9yL251Y2xldXMtY29tbW9uJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBDaGFubmVsSWQsXG4gIE5vdGlmaWNhdGlvbixcbiAgTm90aWZpY2F0aW9uQ2xpY2ssXG4gIE5vdGlmaWNhdGlvbkV2ZW50VHlwZSxcbiAgTm90aWZpY2F0aW9uVHlwZSxcbiAgTnVjbGV1c05vdGlmaWNhdGlvbnNDb25maWcsXG4gIFBheWxvYWREYXRhLFxuICBQbGF0Zm9ybVZhbHVlLFxuICBSZWdpc3RyYXRpb24sXG4gIFJlZ2lzdHJhdGlvblJlc3VsdCxcbiAgVXNlckNoYW5uZWxDb25maWcsXG4gIFdlYktleSxcbn0gZnJvbSAnLi9tb2RlbHMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgTnVjbGV1c05vdGlmaWNhdGlvbnNTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgc3dQdXNoOiBTd1B1c2gsXG4gICAgcHJpdmF0ZSBhcHBTZXJ2aWNlOiBOdWNsZXVzQXBwU2VydmljZSxcbiAgICBjb25maWc6IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnXG4gICkge1xuICAgIGxldCB1cmwgPSBjb25maWcuc2VydmVyQXBpVXJsO1xuICAgIGlmICghdXJsLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgIHVybCArPSAnLyc7XG4gICAgfVxuICAgIHRoaXMuYXBpVXJsID0gdXJsO1xuICB9XG5cbiAgcHJpdmF0ZSBhcGlVcmw6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpc3RyYXRpb25TdG9yYWdlS2V5ID1cbiAgICAnTnVjbGV1c05vdGlmaWNhdGlvbnNSZWdpc3RyYXRpb25JZCc7XG4gIHByaXZhdGUgcmVhZG9ubHkgbm90aWZpY2F0aW9uc1N0b3JhZ2VLZXkgPSAnTnVjbGV1c05vdGlmaWNhdGlvbnNMb2NhbENhY2hlJztcbiAgcHJpdmF0ZSBfcGxhdGZvcm06IFBsYXRmb3JtVmFsdWU7XG4gIHByaXZhdGUgX2lzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfbmV3Tm90aWZpY2F0aW9ucyA9IG5ldyBTdWJqZWN0PE5vdGlmaWNhdGlvbj4oKTtcbiAgcHJpdmF0ZSBfY2xpY2tzU3ViamVjdCA9IG5ldyBTdWJqZWN0PE5vdGlmaWNhdGlvbkNsaWNrPigpO1xuICBwcml2YXRlIF9zdGF0ZUNoYW5nZXNTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwdWJsaWMgbm90aWZpY2F0aW9uczogTm90aWZpY2F0aW9uW10gPSBbXTtcblxuICBwdWJsaWMgZ2V0IHVucmVhZENvdW50KCkge1xuICAgIHJldHVybiB0aGlzLm5vdGlmaWNhdGlvbnMuZmlsdGVyKCh4KSA9PiAheC5pc1JlYWQpLmxlbmd0aDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgbmV3Tm90aWZpY2F0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgY2xpY2tzKCkge1xuICAgIHJldHVybiB0aGlzLl9jbGlja3NTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB9XG4gIHB1YmxpYyBnZXQgc3RhdGVDaGFuZ2VzKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZUNoYW5nZXNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHVibGljIGdldCBpc0luaXRpYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0luaXRpYWxpemVkO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGluaXRpYWxpemUoKSB7XG4gICAgLy8gbWFrZSBzdXJlIGFwcCBzZXJ2aWNlIGhhcyBmaW5pc2hlZCBpbml0aWFsaXppbmdcbiAgICBhd2FpdCB0aGlzLmFwcFNlcnZpY2UuaW5pdCgpO1xuXG4gICAgdGhpcy5sb2FkRnJvbVN0b3JhZ2UoKTtcblxuICAgIGlmICh0aGlzLmFwcFNlcnZpY2UuaXNOYXRpdmUpIHtcbiAgICAgIHRoaXMuX3BsYXRmb3JtID0gdGhpcy5hcHBTZXJ2aWNlLmRldmljZUluZm8ucGxhdGZvcm0gYXMgUGxhdGZvcm1WYWx1ZTtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJDYXBhY2l0b3JFdmVudHMoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3dQdXNoLmlzRW5hYmxlZCkge1xuICAgICAgdGhpcy5fcGxhdGZvcm0gPSAnd2ViJztcbiAgICAgIHRoaXMucmVnaXN0ZXJXZWJQdXNoRXZlbnRzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ051Y2xldXMuTm90aWZpY2F0aW9uczogVGhlcmUgaXMgbm8gcHVzaCBjYXBhYmlsaXR5LCB0aW1lciB3aWxsIGJlIHVzZWQgdG8gdXBkYXRlIG5vdGlmaWNhdGlvbnMnXG4gICAgICApO1xuICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnVXBkYXRpbmcgbm90aWZpY2F0aW9ucy4uLicpO1xuICAgICAgICB0aGlzLnJlZnJlc2godHJ1ZSk7XG4gICAgICB9LCA1ICogNjAgKiAxMDAwKTtcbiAgICB9XG4gICAgdGhpcy5faXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldFJlZ2lzdHJhdGlvbkluZm8oKVxuICAgICAgICAudGhlbigoaW5mbykgPT4ge1xuICAgICAgICAgIHRoaXMuaHR0cFxuICAgICAgICAgICAgLnBvc3Q8UmVnaXN0cmF0aW9uUmVzdWx0Pih0aGlzLmFwaVVybCArICdyZWdpc3RyYXRpb24nLCBpbmZvKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgKHJlZ1Jlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcbiAgICAgICAgICAgICAgICAgIHRoaXMucmVnaXN0cmF0aW9uU3RvcmFnZUtleSxcbiAgICAgICAgICAgICAgICAgIHJlZ1Jlc3VsdC5pZFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgX3Jlc29sdmUobnVsbCk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgJ051Y2xldXMuTm90aWZpY2F0aW9uczogRmFpbGVkIHRvIHNlbmQgbm90aWZpY2F0aW9uIHJlZ2lzdHJhdGlvbiB0byBzZXJ2ZXIuJyxcbiAgICAgICAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBfcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gX3JlamVjdChlcnJvcikpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHVucmVnaXN0ZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldFJlZ2lzdHJhdGlvbkluZm8oKVxuICAgICAgICAudGhlbigoaW5mbykgPT4ge1xuICAgICAgICAgIHRoaXMuaHR0cFxuICAgICAgICAgICAgLnJlcXVlc3Q8YW55PignREVMRVRFJywgdGhpcy5hcGlVcmwgKyAncmVnaXN0cmF0aW9uJywge1xuICAgICAgICAgICAgICBib2R5OiBpbmZvLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5yZWdpc3RyYXRpb25TdG9yYWdlS2V5KTtcbiAgICAgICAgICAgICAgICBfcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBGYWlsZWQgdG8gcmVtb3ZlIHJlZ2lzdHJhdGlvbiBmcm9tIHNlcnZlci4nLFxuICAgICAgICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIF9yZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiBfcmVqZWN0KGVycm9yKSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVmcmVzaChub3RpZnlBYm91dE5ldyA9IGZhbHNlKSB7XG4gICAgdGhpcy5odHRwXG4gICAgICAuZ2V0PE5vdGlmaWNhdGlvbltdPih0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zJylcbiAgICAgIC5zdWJzY3JpYmUoKHJlcykgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZU5vdGlmaWNhdGlvbnMocmVzLCBub3RpZnlBYm91dE5ldyk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXROb3RpZmljYXRpb24oaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Tm90aWZpY2F0aW9uPiB7XG4gICAgY29uc3QgbG9jYWxOb3RpZmljYXRpb24gPSB0aGlzLm5vdGlmaWNhdGlvbnMuZmluZCgoeCkgPT4geC5pZCA9PT0gaWQpO1xuICAgIGlmIChsb2NhbE5vdGlmaWNhdGlvbikge1xuICAgICAgcmV0dXJuIG9mKGxvY2FsTm90aWZpY2F0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Tm90aWZpY2F0aW9uPih0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zLycgKyBpZCk7XG4gIH1cblxuICBwdWJsaWMgcmVhZE5vdGlmaWNhdGlvbihpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgbiA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKCh4KSA9PiB4LmlkID09PSBpZCk7XG4gICAgaWYgKG4gJiYgIW4uaXNSZWFkKSB7XG4gICAgICBuLmlzUmVhZCA9IHRydWU7XG4gICAgICB0aGlzLm5vdGlmeVN0YXRlQ2hhbmdlZCgpO1xuICAgIH1cbiAgICB0aGlzLmh0dHAuZ2V0KHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvcmVhZC8nICsgaWQpLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHVibGljIGRpc21pc3NOb3RpZmljYXRpb24oaWQ6IHN0cmluZykge1xuICAgIHRoaXMuZGVsZXRlTm90aWZpY2F0b24oaWQpO1xuICAgIHRoaXMuaHR0cC5kZWxldGUodGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucy8nICsgaWQpLnN1YnNjcmliZSgpO1xuICAgIHRoaXMucmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9uKGlkKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNtaXNzQWxsKCkge1xuICAgIHRoaXMubm90aWZpY2F0aW9ucy5zcGxpY2UoMCk7XG4gICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB0aGlzLmh0dHAuZGVsZXRlKHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvYWxsJykuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnaW9zJyB8fCB0aGlzLl9wbGF0Zm9ybSA9PT0gJ2FuZHJvaWQnKSB7XG4gICAgICBQdXNoTm90aWZpY2F0aW9ucy5yZW1vdmVBbGxEZWxpdmVyZWROb3RpZmljYXRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ3dlYicpIHtcbiAgICAgIC8vIFRPRE86IHJlbW92ZSBhbGwgd2ViIHB1c2ggbm90aWZpY2F0aW9uc1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZWFkQWxsKCkge1xuICAgIGZvciAoY29uc3QgbiBvZiB0aGlzLm5vdGlmaWNhdGlvbnMpIHtcbiAgICAgIG4uaXNSZWFkID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB0aGlzLmh0dHAuZ2V0KHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvcmVhZC9hbGwnKS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFubmVsQ29uZmlnKFxuICAgIHNlbmRlcklkOiBzdHJpbmcsXG4gICAgY2hhbm5lbElkOiBzdHJpbmcsXG4gICAgbGFuZ3VhZ2U/OiBzdHJpbmdcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8VXNlckNoYW5uZWxDb25maWc+KFxuICAgICAgdGhpcy5hcGlVcmwgK1xuICAgICAgICBgc2V0dGluZ3MvY2hhbm5lbC8ke3NlbmRlcklkfS8ke2NoYW5uZWxJZH0/bGFuZ3VhZ2U9JHtsYW5ndWFnZX1gXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFubmVsQ29uZmlnc0ZvclNlbmRlcihcbiAgICBzZW5kZXJJZDogc3RyaW5nLFxuICAgIGNoYW5uZWxJZHM6IHN0cmluZ1tdLFxuICAgIGxhbmd1YWdlPzogc3RyaW5nXG4gICkge1xuICAgIGNvbnN0IGlkc1N0ciA9IGNoYW5uZWxJZHMubWFwKCh4KSA9PiBzZW5kZXJJZCArICcsJyArIHgpLmpvaW4oJzsnKTtcbiAgICByZXR1cm4gdGhpcy5nZXRDaGFubmVsQ29uZmlnc0ludGVybmFsKGlkc1N0ciwgbGFuZ3VhZ2UpO1xuICB9XG5cbiAgcHVibGljIGdldENoYW5uZWxDb25maWdzKGlkczogQ2hhbm5lbElkW10sIGxhbmd1YWdlPzogc3RyaW5nKSB7XG4gICAgY29uc3QgaWRzU3RyID0gaWRzLm1hcCgoeCkgPT4geC5zZW5kZXJJZCArICcsJyArIHguY2hhbm5lbElkKS5qb2luKCc7Jyk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2hhbm5lbENvbmZpZ3NJbnRlcm5hbChpZHNTdHIsIGxhbmd1YWdlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDaGFubmVsQ29uZmlnKHNlbmRlcklkOiBzdHJpbmcsIGNvbmZpZzogVXNlckNoYW5uZWxDb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8dm9pZD4oXG4gICAgICBgJHt0aGlzLmFwaVVybH1zZXR0aW5ncy9jaGFubmVsLyR7c2VuZGVySWR9YCxcbiAgICAgIGNvbmZpZ1xuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc2V0Q2hhbm5lbENvbmZpZ3MoY29uZmlnczogVXNlckNoYW5uZWxDb25maWdbXSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPihgJHt0aGlzLmFwaVVybH1zZXR0aW5ncy9jaGFubmVsc2AsIGNvbmZpZ3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDaGFubmVsQ29uZmlnc0ludGVybmFsKGlkczogc3RyaW5nLCBsYW5ndWFnZT86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFVzZXJDaGFubmVsQ29uZmlnW10+KFxuICAgICAgYCR7dGhpcy5hcGlVcmx9c2V0dGluZ3MvY2hhbm5lbHM/aWRzPSR7aWRzfSZsYW5ndWFnZT0ke2xhbmd1YWdlfWBcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVOb3RpZmljYXRpb25zKFxuICAgIG5ld05vdGlmaWNhdGlvbnM6IE5vdGlmaWNhdGlvbltdLFxuICAgIG5vdGlmeUFib3V0TmV3ID0gZmFsc2VcbiAgKSB7XG4gICAgbGV0IHN0YXRlQ2hhbmdlZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgbiBvZiBuZXdOb3RpZmljYXRpb25zKSB7XG4gICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKCh4KSA9PiB4LmlkID09PSBuLmlkKTtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICBpZiAoZXhpc3RpbmcuaXNSZWFkICE9PSBuLmlzUmVhZCkge1xuICAgICAgICAgIGV4aXN0aW5nLmlzUmVhZCA9IG4uaXNSZWFkO1xuICAgICAgICAgIHN0YXRlQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgd2hpbGUgKFxuICAgICAgICAgIGkgPCB0aGlzLm5vdGlmaWNhdGlvbnMubGVuZ3RoICYmXG4gICAgICAgICAgbi5kYXRlQ3JlYXRlZCA8IHRoaXMubm90aWZpY2F0aW9uc1tpXS5kYXRlQ3JlYXRlZFxuICAgICAgICApIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub3RpZmljYXRpb25zLnNwbGljZShpLCAwLCBuKTtcbiAgICAgICAgc3RhdGVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgaWYgKG5vdGlmeUFib3V0TmV3KSB7XG4gICAgICAgICAgdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5uZXh0KG4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5ub3RpZmljYXRpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCBuID0gdGhpcy5ub3RpZmljYXRpb25zW2ldO1xuICAgICAgaWYgKFxuICAgICAgICBuZXcgRGF0ZShuLmV4cGlyYXRpb25EYXRlKS5nZXRUaW1lKCkgPCBub3cgfHxcbiAgICAgICAgIW5ld05vdGlmaWNhdGlvbnMuZmluZCgoeCkgPT4geC5pZCA9PT0gbi5pZClcbiAgICAgICkge1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDEpO1xuICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGF0ZUNoYW5nZWQpIHtcbiAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzYXZlVG9TdG9yYWdlKCkge1xuICAgIGNvbnN0IHN0ciA9IEpTT04uc3RyaW5naWZ5KHRoaXMubm90aWZpY2F0aW9ucyk7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMubm90aWZpY2F0aW9uc1N0b3JhZ2VLZXksIHN0cik7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tU3RvcmFnZSgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RyID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubm90aWZpY2F0aW9uc1N0b3JhZ2VLZXkpO1xuICAgICAgaWYgKHN0cikge1xuICAgICAgICBjb25zdCBub3RpZmljYXRpb25zID0gSlNPTi5wYXJzZShzdHIpIGFzIE5vdGlmaWNhdGlvbltdO1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMgPSBub3RpZmljYXRpb25zLmZpbHRlcigoeCkgPT4gISF4KTtcbiAgICAgICAgLy8gcHJlY2F1dGlvbiBmb3Igbm90aWZpY2F0aW9uLmlzUmVhZCBvZiB1bmRlZmluZWQgZXJyb3JcbiAgICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoZmFsc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLyogZW1wdHkgKi9cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZU5vdGlmaWNhdGlvbkV2ZW50KFxuICAgIGlkOiBzdHJpbmcsXG4gICAgZXZlbnRUeXBlOiBOb3RpZmljYXRpb25FdmVudFR5cGVcbiAgKSB7XG4gICAgaWYgKGV2ZW50VHlwZS5zdGFydHNXaXRoKCduZXcnKSB8fCBldmVudFR5cGUgPT09ICd1cGRhdGVkJykge1xuICAgICAgLy8gd2UgYXJlIGhhbmRsaW5nIG5ldyBhbmQgbmV3U2lsZW50XG4gICAgICB0aGlzLmdldE5vdGlmaWNhdGlvbihpZCkuc3Vic2NyaWJlKChuKSA9PiB7XG4gICAgICAgIGlmIChldmVudFR5cGUuc3RhcnRzV2l0aCgnbmV3JykgJiYgIW4uaXNSZWFkKSB7XG4gICAgICAgICAgdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5uZXh0KG4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5ub3RpZmljYXRpb25zLmZpbmQoKHgpID0+IHguaWQgPT09IG4uaWQpO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICBleGlzdGluZy5pc1JlYWQgPSBuLmlzUmVhZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKDAsIDAsIG4pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50VHlwZSA9PT0gJ2RlbGV0ZWQnKSB7XG4gICAgICB0aGlzLmRlbGV0ZU5vdGlmaWNhdG9uKGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZWZyZXNoKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVOb3RpZmljYXRvbihpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgaSA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kSW5kZXgoKHgpID0+IHguaWQgPT09IGlkKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDEpO1xuICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG5vdGlmeVN0YXRlQ2hhbmdlZChwZXJzaXN0U3RhdGUgPSB0cnVlKSB7XG4gICAgaWYgKHBlcnNpc3RTdGF0ZSkge1xuICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XG4gICAgfVxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlc1N1YmplY3QubmV4dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVOb3RpZmljYXRpb25BY3Rpb24obm90aWZpY2F0aW9uQWN0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoIW5vdGlmaWNhdGlvbkFjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3RpZmljYXRpb24gYWN0aW9uIGlzIGVtcHR5IScpO1xuICAgIH1cblxuICAgIGNvbnN0IGFyciA9IG5vdGlmaWNhdGlvbkFjdGlvbi5zcGxpdCgnOicpO1xuICAgIGNvbnN0IG5vdGlmaWNhdGlvbkNsaWNrOiBOb3RpZmljYXRpb25DbGljayA9IHtcbiAgICAgIGlkOiBhcnJbMF0sXG4gICAgICB0eXBlOiBhcnJbMV0gYXMgTm90aWZpY2F0aW9uVHlwZSxcbiAgICAgIHJvdXRlckxpbms6IGFyclsyXSxcbiAgICB9O1xuXG4gICAgY29uc3QgdmFsaWROb3RpZmljYXRpb25DbGlja1R5cGVzID0gWydkZWZhdWx0JywgJ2RlZXBsaW5rJ107XG4gICAgaWYgKHZhbGlkTm90aWZpY2F0aW9uQ2xpY2tUeXBlcy5pbmNsdWRlcyhub3RpZmljYXRpb25DbGljay50eXBlKSkge1xuICAgICAgdGhpcy5fY2xpY2tzU3ViamVjdC5uZXh0KG5vdGlmaWNhdGlvbkNsaWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgYE51Y2xldXMuTm90aWZpY2F0aW9uczogVW5rbm93biBub3RpZmljYXRpb24gYWN0aW9uOiAnJHtub3RpZmljYXRpb25BY3Rpb259Jy5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9uKGlkOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5fcGxhdGZvcm0gPT09ICdpb3MnIHx8IHRoaXMuX3BsYXRmb3JtID09PSAnYW5kcm9pZCcpIHtcbiAgICAgIFB1c2hOb3RpZmljYXRpb25zLmdldERlbGl2ZXJlZE5vdGlmaWNhdGlvbnMoKS50aGVuKChsaXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHRvUmVtb3ZlID0gbGlzdC5ub3RpZmljYXRpb25zLmZpbHRlcigobikgPT4ge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldE5vdGlmaWNhdGlvblBheWxvYWREYXRhKG4pO1xuICAgICAgICAgIHJldHVybiBkYXRhLm5vdGlmaWNhdGlvbklkID09PSBpZDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVE9ETzogT24gQW5kcm9pZCB0aGlzIGRvZXMgbm90IGN1cnJlbnRseSB3b3JrIGJlY2F1c2Ugbm90aWZpY2F0aW9uSUQgaXMgbm90IHNldC5cbiAgICAgICAgLy8gVGhpcyBteSBzb2x2ZSB0aGUgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9pb25pYy10ZWFtL2NhcGFjaXRvci9wdWxsLzM1MjNcbiAgICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9ucyh7XG4gICAgICAgICAgbm90aWZpY2F0aW9uczogdG9SZW1vdmUsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ3dlYicpIHtcbiAgICAgIC8vIFRPRE86IHJlbW92ZSB3ZWIgcHVzaCBub3RpZmljYXRpb25cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldE5vdGlmaWNhdGlvblBheWxvYWREYXRhKFxuICAgIHB1c2hOb3RpZmljYXRpb246IFB1c2hOb3RpZmljYXRpb25TY2hlbWFcbiAgKTogUGF5bG9hZERhdGEge1xuICAgIHJldHVybiB0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcydcbiAgICAgID8gcHVzaE5vdGlmaWNhdGlvbi5kYXRhLmRhdGFcbiAgICAgIDogcHVzaE5vdGlmaWNhdGlvbi5kYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckNhcGFjaXRvckV2ZW50cygpIHtcbiAgICBhd2FpdCBQdXNoTm90aWZpY2F0aW9ucy5hZGRMaXN0ZW5lcigncHVzaE5vdGlmaWNhdGlvblJlY2VpdmVkJywgKG4pID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldE5vdGlmaWNhdGlvblBheWxvYWREYXRhKG4pO1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIGNhcGFjaXRvciBwdXNoIGV2ZW50OiAnICtcbiAgICAgICAgICBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgblxuICAgICAgKTtcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZGF0YS5ub3RpZmljYXRpb25JZCwgZGF0YS5ldmVudFR5cGUpO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgUHVzaE5vdGlmaWNhdGlvbnMuYWRkTGlzdGVuZXIoXG4gICAgICAncHVzaE5vdGlmaWNhdGlvbkFjdGlvblBlcmZvcm1lZCcsXG4gICAgICAoYSkgPT4ge1xuICAgICAgICBsZXQgYWN0aW9uID0gKGEgYXMgYW55KS5ub3RpZmljYXRpb24uZGF0YS5ub3RpZmljYXRpb25BY3Rpb247XG4gICAgICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycpIHtcbiAgICAgICAgICBhY3Rpb24gPSAoYSBhcyBhbnkpLm5vdGlmaWNhdGlvbi5kYXRhLmRhdGEubm90aWZpY2F0aW9uQWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIGNhcGFjaXRvciBhY3Rpb24gZXZlbnQnLFxuICAgICAgICAgIGFjdGlvblxuICAgICAgICApO1xuICAgICAgICB0aGlzLmhhbmRsZU5vdGlmaWNhdGlvbkFjdGlvbihhY3Rpb24pO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyV2ViUHVzaEV2ZW50cygpIHtcbiAgICB0aGlzLnN3UHVzaC5tZXNzYWdlcy5zdWJzY3JpYmUoKG4pID0+IHtcbiAgICAgIGNvbnN0IGRhdGE6IFBheWxvYWREYXRhID0gKG4gYXMgYW55KS5kYXRhO1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIFdlYlB1c2ggZXZlbnQ6ICcgKyBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgblxuICAgICAgKTtcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZGF0YS5ub3RpZmljYXRpb25JZCwgZGF0YS5ldmVudFR5cGUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zd1B1c2gubm90aWZpY2F0aW9uQ2xpY2tzLnN1YnNjcmliZSgoYWN0aW9uKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJ051Y2xldXMuTm90aWZpY2F0aW9uczogUmVjZWl2ZWQgV2ViUHVzaCBhY3Rpb24gZXZlbnQnLFxuICAgICAgICBhY3Rpb25cbiAgICAgICk7XG4gICAgICBjb25zdCB0YWcgPSBhY3Rpb24ubm90aWZpY2F0aW9uLnRhZztcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uQWN0aW9uKHRhZyk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFJlZ2lzdHJhdGlvbkluZm8oKTogUHJvbWlzZTxSZWdpc3RyYXRpb24+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCByZWdpc3RyYXRpb25JZCA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShcbiAgICAgICAgdGhpcy5yZWdpc3RyYXRpb25TdG9yYWdlS2V5XG4gICAgICApIGFzIHN0cmluZztcbiAgICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2FuZHJvaWQnIHx8IHRoaXMuX3BsYXRmb3JtID09PSAnaW9zJykge1xuICAgICAgICAvLyBjYXBhY2l0b3IgcGxhdGZvcm1cbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBQdXNoTm90aWZpY2F0aW9ucy5hZGRMaXN0ZW5lcihcbiAgICAgICAgICAncmVnaXN0cmF0aW9uJyxcbiAgICAgICAgICAodG9rZW4pID0+IHtcbiAgICAgICAgICAgIGxpc3RlbmVyLnJlbW92ZSgpO1xuICAgICAgICAgICAgX3Jlc29sdmUoe1xuICAgICAgICAgICAgICBpZDogcmVnaXN0cmF0aW9uSWQsXG4gICAgICAgICAgICAgIHRva2VuOiB0b2tlbi52YWx1ZSxcbiAgICAgICAgICAgICAgcGxhdGZvcm06IHRoaXMuX3BsYXRmb3JtLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBQdXNoTm90aWZpY2F0aW9ucy5yZWdpc3RlcigpLmNhdGNoKChlcnJvcikgPT5cbiAgICAgICAgICBfcmVqZWN0KCdDb3VsZCBub3QgcmVnaXN0ZXIgZm9yIG5vdGlmaWNhdGlvbnM6JyArIGVycm9yKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ3dlYicpIHtcbiAgICAgICAgLy8gV2ViIFB1c2ggQVBJXG4gICAgICAgIHRoaXMuaHR0cC5nZXQ8V2ViS2V5Pih0aGlzLmFwaVVybCArICdyZWdpc3RyYXRpb24vd2Via2V5Jykuc3Vic2NyaWJlKFxuICAgICAgICAgIChrZXkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2V0V2ViUHVzaFN1YnNjcmlwdGlvbihrZXkucHVibGljS2V5KS50aGVuKChzdWJzY3JpcHRpb24pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdCA9IEpTT04uc3RyaW5naWZ5KHN1YnNjcmlwdGlvbi50b0pTT04oKSk7XG4gICAgICAgICAgICAgIF9yZXNvbHZlKHsgaWQ6IHJlZ2lzdHJhdGlvbklkLCB0b2tlbjogdCwgcGxhdGZvcm06ICd3ZWInIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoZXJyb3IpID0+IF9yZWplY3QoZXJyb3IpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfcmVqZWN0KGBOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFBsYXRmb3JtIGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0V2ViUHVzaFN1YnNjcmlwdGlvbihwdWJsaWNLZXk6IHN0cmluZyk6IFByb21pc2U8UHVzaFN1YnNjcmlwdGlvbj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgIHRoaXMuc3dQdXNoLnN1YnNjcmlwdGlvbi5zdWJzY3JpYmUoXG4gICAgICAgIChzdWJzY3JpcHRpb24pID0+IHtcbiAgICAgICAgICBpZiAoc3Vic2NyaXB0aW9uICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9yZXNvbHZlKHN1YnNjcmlwdGlvbik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3dQdXNoXG4gICAgICAgICAgICAgIC5yZXF1ZXN0U3Vic2NyaXB0aW9uKHsgc2VydmVyUHVibGljS2V5OiBwdWJsaWNLZXkgfSlcbiAgICAgICAgICAgICAgLnRoZW4oKHMpID0+IF9yZXNvbHZlKHMpKVxuICAgICAgICAgICAgICAuY2F0Y2goKGUpID0+IF9yZWplY3QoZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IENhbm5vdCBnZXQgd2ViIHB1c2ggc3Vic2NyaXB0aW9uJyxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgICBfcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxufVxuIl19