@sumaris-net/ngx-components 1.18.7 → 1.19.2

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.
Files changed (60) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +804 -429
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/doc/changelog.md +10 -0
  6. package/esm2015/public_api.js +10 -5
  7. package/esm2015/src/app/admin/admin-routing.module.js +3 -1
  8. package/esm2015/src/app/admin/admin.module.js +2 -1
  9. package/esm2015/src/app/admin/users/list/users.js +45 -7
  10. package/esm2015/src/app/core/services/base-entity-service.class.js +6 -6
  11. package/esm2015/src/app/core/services/local-settings.service.js +5 -5
  12. package/esm2015/src/app/core/services/model/referential.model.js +1 -1
  13. package/esm2015/src/app/core/services/platform.service.js +3 -4
  14. package/esm2015/src/app/shared/material/datetime/material.date.js +82 -70
  15. package/esm2015/src/app/shared/material/datetime/material.datetime.js +3 -3
  16. package/esm2015/src/app/shared/material/datetime/testing/mat-date.test.js +7 -5
  17. package/esm2015/src/app/shared/platforms.js +20 -4
  18. package/esm2015/src/app/shared/validator/validators.js +2 -2
  19. package/esm2015/src/app/social/message/message.form.js +73 -0
  20. package/esm2015/src/app/social/message/message.modal.js +96 -0
  21. package/esm2015/src/app/social/message/message.model.js +65 -0
  22. package/esm2015/src/app/social/message/message.service.js +87 -0
  23. package/esm2015/src/app/social/social.errors.js +6 -0
  24. package/esm2015/src/app/social/social.module.js +12 -15
  25. package/esm2015/src/app/social/user-event/user-event.fragments.js +27 -0
  26. package/esm2015/src/app/social/user-event/user-event.model.js +46 -0
  27. package/esm2015/src/app/social/user-event/user-event.service.js +367 -0
  28. package/esm2015/src/app/social/user-event/user-events.table.js +154 -0
  29. package/fesm2015/sumaris-net.ngx-components.js +734 -411
  30. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  31. package/package.json +4 -3
  32. package/public_api.d.ts +9 -4
  33. package/src/app/admin/users/list/users.d.ts +10 -6
  34. package/src/app/core/services/local-settings.service.d.ts +3 -2
  35. package/src/app/core/services/model/referential.model.d.ts +7 -7
  36. package/src/app/shared/material/datetime/material.date.d.ts +6 -8
  37. package/src/app/shared/material/datetime/material.datetime.d.ts +2 -2
  38. package/src/app/shared/platforms.d.ts +1 -1
  39. package/src/app/social/message/message.form.d.ts +27 -0
  40. package/src/app/social/message/message.modal.d.ts +36 -0
  41. package/src/app/social/message/message.model.d.ts +31 -0
  42. package/src/app/social/message/message.service.d.ts +24 -0
  43. package/src/app/social/{services/errors.d.ts → social.errors.d.ts} +2 -1
  44. package/src/app/social/social.module.d.ts +0 -2
  45. package/src/app/social/{services/social.fragments.d.ts → user-event/user-event.fragments.d.ts} +1 -1
  46. package/src/app/social/{services/model → user-event}/user-event.model.d.ts +1 -1
  47. package/src/app/social/{services → user-event}/user-event.service.d.ts +4 -3
  48. package/src/app/social/{list → user-event}/user-events.table.d.ts +2 -2
  49. package/src/assets/i18n/en-US.json +23 -4
  50. package/src/assets/i18n/en.json +23 -4
  51. package/src/assets/i18n/fr.json +25 -5
  52. package/src/theme/_ionic.globals.scss +2 -1
  53. package/sumaris-net.ngx-components.metadata.json +1 -1
  54. package/esm2015/src/app/admin/services/errors.js +0 -6
  55. package/esm2015/src/app/social/list/user-events.table.js +0 -154
  56. package/esm2015/src/app/social/services/errors.js +0 -5
  57. package/esm2015/src/app/social/services/model/user-event.model.js +0 -46
  58. package/esm2015/src/app/social/services/social.fragments.js +0 -27
  59. package/esm2015/src/app/social/services/user-event.service.js +0 -367
  60. package/src/app/admin/services/errors.d.ts +0 -5
@@ -0,0 +1,367 @@
1
+ import { __awaiter, __decorate } from "tslib";
2
+ import { Inject, Injectable, Optional } from '@angular/core';
3
+ import { gql } from '@apollo/client/core';
4
+ import { SocialErrorCodes } from '../social.errors';
5
+ import { AccountService } from '../../core/services/account.service';
6
+ import { GraphqlService } from '../../core/graphql/graphql.service';
7
+ import { of } from 'rxjs';
8
+ import { UserEvent, UserEventTypes } from './user-event.model';
9
+ import { UserEventFragments } from './user-event.fragments';
10
+ import { map } from 'rxjs/operators';
11
+ import { isEmptyArray, isNil, isNilOrBlank, toNumber } from '../../shared/functions';
12
+ import { Toasts } from '../../shared/toast/toasts';
13
+ import { ToastController } from '@ionic/angular';
14
+ import { TranslateService } from '@ngx-translate/core';
15
+ import { NetworkService } from '../../core/services/network.service';
16
+ import { BaseGraphqlService } from '../../core/services/base-graphql-service.class';
17
+ import { Entity, EntityUtils } from '../../core/services/model/entity.model';
18
+ import { Environment, ENVIRONMENT } from '../../../environments/environment.class';
19
+ import { EntityFilter } from '../../core/services/model/filter.model';
20
+ import { EntityClass } from '../../core/services/model/entity.decorators';
21
+ import * as i0 from "@angular/core";
22
+ import * as i1 from "../../core/graphql/graphql.service";
23
+ import * as i2 from "../../core/services/account.service";
24
+ import * as i3 from "../../core/services/network.service";
25
+ import * as i4 from "@ngx-translate/core";
26
+ import * as i5 from "@ionic/angular";
27
+ import * as i6 from "../../../environments/environment.class";
28
+ // @dynamic
29
+ let UserEventFilter = class UserEventFilter extends EntityFilter {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.issuer = null;
33
+ this.recipient = null;
34
+ }
35
+ fromObject(source, opts) {
36
+ super.fromObject(source, opts);
37
+ this.issuer = source.issuer;
38
+ this.recipient = source.recipient;
39
+ }
40
+ buildFilter() {
41
+ const filterFns = super.buildFilter();
42
+ // issuer
43
+ if (this.issuer) {
44
+ filterFns.push(t => (t.issuer === this.issuer));
45
+ }
46
+ if (this.recipient) {
47
+ filterFns.push(t => (t.recipient === this.recipient));
48
+ }
49
+ return filterFns;
50
+ }
51
+ };
52
+ UserEventFilter = __decorate([
53
+ EntityClass({ typename: 'UserEventFilterVO' })
54
+ ], UserEventFilter);
55
+ export { UserEventFilter };
56
+ const SaveQuery = gql `
57
+ mutation SaveUserEvent($data: UserEventVOInput){
58
+ data: saveUserEvent(userEvent: $data){
59
+ ...UserEventFragment
60
+ }
61
+ }
62
+ ${UserEventFragments.userEvent}
63
+ `;
64
+ const LoadAllQuery = gql `
65
+ query UserEvents($filter: UserEventFilterVOInput, $page: PageInput){
66
+ data: userEvents(filter: $filter, page: $page){
67
+ ...LightUserEventFragment
68
+ }
69
+ }
70
+ ${UserEventFragments.lightUserEvent}
71
+ `;
72
+ const DeleteByIdsMutation = gql `
73
+ mutation DeleteUserEvents($ids:[Int]){
74
+ deleteUserEvents(ids: $ids)
75
+ }
76
+ `;
77
+ const LoadAllWithContentQuery = gql `
78
+ query UserEventsWithContent($filter: UserEventFilterVOInput, $page: PageInput){
79
+ data: userEvents(filter: $filter, page: $page){
80
+ ...UserEventFragment
81
+ }
82
+ }
83
+ ${UserEventFragments.userEvent}
84
+ `;
85
+ export class UserEventService extends BaseGraphqlService {
86
+ constructor(graphql, accountService, network, translate, toastController, environment) {
87
+ super(graphql, environment);
88
+ this.graphql = graphql;
89
+ this.accountService = accountService;
90
+ this.network = network;
91
+ this.translate = translate;
92
+ this.toastController = toastController;
93
+ this.environment = environment;
94
+ this._userEventActions = [];
95
+ // For DEV only
96
+ this._debug = environment && !environment.production;
97
+ }
98
+ /**
99
+ *
100
+ * @param offset
101
+ * @param size
102
+ * @param sortBy
103
+ * @param sortDirection
104
+ * @param filter
105
+ * @param options
106
+ * @deprecated use watchPage() instead
107
+ */
108
+ watchAll(offset, size, sortBy, sortDirection, filter, options) {
109
+ return this.watchPage({ offset, size, sortBy, sortDirection }, filter, options);
110
+ }
111
+ watchPage(page, filter, options) {
112
+ let now = this._debug && Date.now();
113
+ //if (this._debug)
114
+ console.debug('[user-event-service] Loading user events...', filter);
115
+ filter = this.asFilter(filter);
116
+ // Force recipient to current issuer, if not admin and not specified
117
+ if (isNilOrBlank(filter.recipient) || !this.accountService.isAdmin()) {
118
+ const recipient = this.accountService.account.pubkey;
119
+ if (recipient !== filter.recipient) {
120
+ console.warn('[user-events-service] Force user event filter.recipient=' + recipient);
121
+ filter.recipient = recipient;
122
+ }
123
+ }
124
+ const withContent = options && options.withContent === true;
125
+ return this.mutableWatchQuery({
126
+ queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',
127
+ query: withContent ? LoadAllWithContentQuery : LoadAllQuery,
128
+ variables: {
129
+ page: Object.assign(Object.assign({ sortBy: 'updateDate' }, page), { sortDirection: (page.sortDirection || 'DESC').toUpperCase() }),
130
+ filter: filter && filter.asPodObject()
131
+ },
132
+ arrayFieldName: 'data',
133
+ error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },
134
+ fetchPolicy: options && options.fetchPolicy || undefined
135
+ })
136
+ .pipe(map(res => {
137
+ const data = res && (res.data || []).map(UserEvent.fromObject);
138
+ if (now) {
139
+ console.debug(`[user-event-service] ${data.length} user events loaded in ${Date.now() - now}ms`);
140
+ now = null;
141
+ }
142
+ return {
143
+ data,
144
+ total: res && toNumber(res.total, data.length)
145
+ };
146
+ }));
147
+ }
148
+ saveAll(data, options) {
149
+ return Promise.all(data
150
+ .map(entity => this.save(entity, options)));
151
+ }
152
+ /**
153
+ * Save a userEvent entity
154
+ *
155
+ * @param entity
156
+ */
157
+ save(entity, options) {
158
+ return __awaiter(this, void 0, void 0, function* () {
159
+ this.fillDefaultProperties(entity);
160
+ // Transform into json
161
+ const isNew = isNil(entity.id);
162
+ const json = entity.asObject();
163
+ const now = Date.now();
164
+ if (this._debug)
165
+ console.debug(`[user-event-service] Saving user event...`, json);
166
+ yield this.graphql.mutate({
167
+ mutation: SaveQuery,
168
+ variables: {
169
+ data: json
170
+ },
171
+ error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },
172
+ update: (proxy, { data }) => {
173
+ // Update entity
174
+ const savedEntity = data && data.data;
175
+ if (savedEntity) {
176
+ if (this._debug)
177
+ console.debug(`[user-event-service] User event saved in ${Date.now() - now}ms`, entity);
178
+ this.copyIdAndUpdateDate(savedEntity, entity);
179
+ // Add to cache
180
+ if (isNew) {
181
+ this.insertIntoMutableCachedQueries(proxy, {
182
+ query: LoadAllQuery,
183
+ data: Object.assign(Object.assign({}, savedEntity), { content: null })
184
+ });
185
+ this.insertIntoMutableCachedQueries(proxy, {
186
+ query: LoadAllWithContentQuery,
187
+ data: savedEntity
188
+ });
189
+ }
190
+ }
191
+ }
192
+ });
193
+ return entity;
194
+ });
195
+ }
196
+ /**
197
+ * Save many trips
198
+ *
199
+ * @param entities
200
+ * @param opts
201
+ */
202
+ deleteAll(entities, opts) {
203
+ return __awaiter(this, void 0, void 0, function* () {
204
+ const ids = entities && entities
205
+ .map(t => t.id);
206
+ if (isEmptyArray(ids))
207
+ return; // stop, if nothing else to do
208
+ const now = Date.now();
209
+ if (this._debug)
210
+ console.debug('[user-event-service] Deleting events... ids:', ids);
211
+ yield this.graphql.mutate({
212
+ mutation: DeleteByIdsMutation,
213
+ variables: {
214
+ ids
215
+ },
216
+ update: (proxy) => {
217
+ // Remove from caches
218
+ this.removeFromMutableCachedQueriesByIds(proxy, {
219
+ query: LoadAllQuery,
220
+ ids
221
+ });
222
+ this.removeFromMutableCachedQueriesByIds(proxy, {
223
+ query: LoadAllWithContentQuery,
224
+ ids
225
+ });
226
+ if (this._debug)
227
+ console.debug(`[user-event-service] Events deleted in ${Date.now() - now}ms`);
228
+ }
229
+ });
230
+ });
231
+ }
232
+ /**
233
+ * Delete userEvent entities
234
+ */
235
+ delete(data) {
236
+ return __awaiter(this, void 0, void 0, function* () {
237
+ if (!data)
238
+ return; // skip
239
+ yield this.deleteAll([data]);
240
+ });
241
+ }
242
+ listenChanges(id, options) {
243
+ // TODO
244
+ console.warn('TODO: implement listen changes on user events');
245
+ return of();
246
+ }
247
+ registerAction(definition) {
248
+ console.info(`[user-event-service] Registering action ${definition.name} for ${definition.__typename}`);
249
+ this._userEventActions.push(definition);
250
+ }
251
+ getActionsByTypename(typename) {
252
+ return this._userEventActions.filter(def => def.__typename === typename);
253
+ }
254
+ showToastErrorWithContext(opts) {
255
+ return __awaiter(this, void 0, void 0, function* () {
256
+ let message = opts.message || (opts.error && opts.error.message || opts.error);
257
+ // Make sure message a string
258
+ if (!message || typeof message !== 'string') {
259
+ message = 'ERROR.UNKNOWN_TECHNICAL_ERROR';
260
+ }
261
+ // If offline, display a simple alert
262
+ if (this.network.offline) {
263
+ this.showToast({ message, type: 'error' });
264
+ return;
265
+ }
266
+ // Translate the message (to be able to extract details content)
267
+ message = this.translate.instant(message);
268
+ // Clean details parts
269
+ if (message && message.indexOf('<small>') !== -1) {
270
+ message = message.substr(0, message.indexOf('<small>') - 1);
271
+ }
272
+ const res = yield this.showToast({
273
+ type: 'error',
274
+ duration: 15000,
275
+ message: message + '<br/><br/><b>' + this.translate.instant('CONFIRM.SEND_DEBUG_DATA') + '</b>',
276
+ buttons: [{
277
+ icon: 'bug',
278
+ text: this.translate.instant('COMMON.BTN_SEND'),
279
+ role: 'send'
280
+ }]
281
+ });
282
+ if (!res || res.role !== 'send')
283
+ return;
284
+ // Send debug data
285
+ try {
286
+ if (this._debug)
287
+ console.debug('Sending debug data...');
288
+ // Call content factory
289
+ let context = opts && opts.context;
290
+ if (typeof context === 'function') {
291
+ context = context();
292
+ }
293
+ if (context instanceof Promise) {
294
+ context = yield context;
295
+ }
296
+ // Send the message
297
+ const userEvent = yield this.sendDataForDebug({
298
+ message,
299
+ error: opts.error || undefined,
300
+ context: this.convertObjectToString(context)
301
+ });
302
+ console.info('Debug data successfully sent to admin', userEvent);
303
+ this.showToast({
304
+ type: 'info',
305
+ message: 'INFO.DEBUG_DATA_SEND',
306
+ showCloseButton: true
307
+ });
308
+ }
309
+ catch (err) {
310
+ console.error('Error while sending debug data:', err);
311
+ }
312
+ });
313
+ }
314
+ sendDataForDebug(data) {
315
+ const userEvent = new UserEvent();
316
+ userEvent.eventType = UserEventTypes.DEBUG_DATA;
317
+ userEvent.content = this.convertObjectToString(data);
318
+ return this.save(userEvent);
319
+ }
320
+ asFilter(filter) {
321
+ return UserEventFilter.fromObject(filter);
322
+ }
323
+ /* -- protected methods -- */
324
+ convertObjectToString(data) {
325
+ if (typeof data === 'string') {
326
+ return data;
327
+ }
328
+ // Serialize content into string
329
+ else if (typeof data === 'object') {
330
+ if (data instanceof Entity) {
331
+ return JSON.stringify(data.asObject({ keepTypename: true, keepLocalId: true, minify: false }));
332
+ }
333
+ else {
334
+ return JSON.stringify(data);
335
+ }
336
+ }
337
+ }
338
+ showToast(opts) {
339
+ return __awaiter(this, void 0, void 0, function* () {
340
+ if (!this.toastController)
341
+ throw new Error('Missing toastController in component\'s constructor');
342
+ return yield Toasts.show(this.toastController, this.translate, opts);
343
+ });
344
+ }
345
+ fillDefaultProperties(entity) {
346
+ entity.issuer = this.accountService.account.pubkey;
347
+ // TODO: compute hash (using cryptoService)
348
+ // TODO: compute sign
349
+ console.warn('TODO: sign user event before sending');
350
+ }
351
+ copyIdAndUpdateDate(source, target) {
352
+ EntityUtils.copyIdAndUpdateDate(source, target);
353
+ }
354
+ }
355
+ UserEventService.ɵprov = i0.ɵɵdefineInjectable({ factory: function UserEventService_Factory() { return new UserEventService(i0.ɵɵinject(i1.GraphqlService), i0.ɵɵinject(i2.AccountService), i0.ɵɵinject(i3.NetworkService), i0.ɵɵinject(i4.TranslateService), i0.ɵɵinject(i5.ToastController), i0.ɵɵinject(i6.ENVIRONMENT, 8)); }, token: UserEventService, providedIn: "root" });
356
+ UserEventService.decorators = [
357
+ { type: Injectable, args: [{ providedIn: 'root' },] }
358
+ ];
359
+ UserEventService.ctorParameters = () => [
360
+ { type: GraphqlService },
361
+ { type: AccountService },
362
+ { type: NetworkService },
363
+ { type: TranslateService },
364
+ { type: ToastController },
365
+ { type: Environment, decorators: [{ type: Optional }, { type: Inject, args: [ENVIRONMENT,] }] }
366
+ ];
367
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1ldmVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zb2NpYWwvdXNlci1ldmVudC91c2VyLWV2ZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBQUMsR0FBRyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDeEMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBQ25FLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUNsRSxPQUFPLEVBQWEsRUFBRSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxTQUFTLEVBQW1CLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQzlFLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBRzFELE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuQyxPQUFPLEVBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDbkYsT0FBTyxFQUFtQixNQUFNLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUVuRSxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0MsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBQ25FLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLGdEQUFnRCxDQUFDO0FBQ2xGLE9BQU8sRUFBQyxNQUFNLEVBQUUs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VUFBVSxTQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQzs7O1lBMUZ4QixjQUFjO1lBRGQsY0FBYztZQWFkLGNBQWM7WUFEZCxnQkFBZ0I7WUFEaEIsZUFBZTtZQUtmLFdBQVcsdUJBd0ZkLFFBQVEsWUFBSSxNQUFNLFNBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlLCBPcHRpb25hbH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge2dxbH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY29yZSc7XG5pbXBvcnQge1NvY2lhbEVycm9yQ29kZXN9IGZyb20gJy4uL3NvY2lhbC5lcnJvcnMnO1xuaW1wb3J0IHtBY2NvdW50U2VydmljZX0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9hY2NvdW50LnNlcnZpY2UnO1xuaW1wb3J0IHtHcmFwaHFsU2VydmljZX0gZnJvbSAnLi4vLi4vY29yZS9ncmFwaHFsL2dyYXBocWwuc2VydmljZSc7XG5pbXBvcnQge09ic2VydmFibGUsIG9mfSBmcm9tICdyeGpzJztcbmltcG9ydCB7VXNlckV2ZW50LCBVc2VyRXZlbnRBY3Rpb24sIFVzZXJFdmVudFR5cGVzfSBmcm9tICcuL3VzZXItZXZlbnQubW9kZWwnO1xuaW1wb3J0IHtVc2VyRXZlbnRGcmFnbWVudHN9IGZyb20gJy4vdXNlci1ldmVudC5mcmFnbWVudHMnO1xuaW1wb3J0IHtTb3J0RGlyZWN0aW9ufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcbmltcG9ydCB7RW50aXRpZXNTZXJ2aWNlV2F0Y2hPcHRpb25zLCBFbnRpdHlTZXJ2aWNlTG9hZE9wdGlvbnMsIEZpbHRlckZuLCBJRW50aXRpZXNTZXJ2aWNlLCBMb2FkUmVzdWx0LCBQYWdlfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VydmljZXMvZW50aXR5LXNlcnZpY2UuY2xhc3MnO1xuaW1wb3J0IHttYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7aXNFbXB0eUFycmF5LCBpc05pbCwgaXNOaWxPckJsYW5rLCB0b051bWJlcn0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQge1Nob3dUb2FzdE9wdGlvbnMsIFRvYXN0c30gZnJvbSAnLi4vLi4vc2hhcmVkL3RvYXN0L3RvYXN0cyc7XG5pbXBvcnQge092ZXJsYXlFdmVudERldGFpbH0gZnJvbSAnQGlvbmljL2NvcmUnO1xuaW1wb3J0IHtUb2FzdENvbnRyb2xsZXJ9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7VHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge05ldHdvcmtTZXJ2aWNlfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL25ldHdvcmsuc2VydmljZSc7XG5pbXBvcnQge0Jhc2VHcmFwaHFsU2VydmljZX0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9iYXNlLWdyYXBocWwtc2VydmljZS5jbGFzcyc7XG5pbXBvcnQge0VudGl0eSwgRW50aXR5VXRpbHN9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvbW9kZWwvZW50aXR5Lm1vZGVsJztcbmltcG9ydCB7RW52aXJvbm1lbnQsIEVOVklST05NRU5UfSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQuY2xhc3MnO1xuaW1wb3J0IHtFbnRpdHlGaWx0ZXJ9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvbW9kZWwvZmlsdGVyLm1vZGVsJztcbmltcG9ydCB7RW50aXR5Q2xhc3N9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvbW9kZWwvZW50aXR5LmRlY29yYXRvcnMnO1xuXG4vLyBAZHluYW1pY1xuQEVudGl0eUNsYXNzKHt0eXBlbmFtZTogJ1VzZXJFdmVudEZpbHRlclZPJ30pXG5leHBvcnQgY2xhc3MgVXNlckV2ZW50RmlsdGVyIGV4dGVuZHMgRW50aXR5RmlsdGVyPFVzZXJFdmVudEZpbHRlciwgVXNlckV2ZW50PiB7XG5cbiAgc3RhdGljIGZyb21PYmplY3Q6IChzb3VyY2U6IGFueSwgb3B0cz86IGFueSkgPT4gVXNlckV2ZW50RmlsdGVyO1xuXG4gIGlzc3Vlcjogc3RyaW5nID0gbnVsbDtcbiAgcmVjaXBpZW50OiBzdHJpbmcgPSBudWxsO1xuXG4gIGZyb21PYmplY3Qoc291cmNlOiBhbnksIG9wdHM/OiBhbnkpIHtcbiAgICBzdXBlci5mcm9tT2JqZWN0KHNvdXJjZSwgb3B0cyk7XG4gICAgdGhpcy5pc3N1ZXIgPSBzb3VyY2UuaXNzdWVyO1xuICAgIHRoaXMucmVjaXBpZW50ID0gc291cmNlLnJlY2lwaWVudDtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZEZpbHRlcigpOiBGaWx0ZXJGbjxVc2VyRXZlbnQ+W10ge1xuICAgIGNvbnN0IGZpbHRlckZucyA9IHN1cGVyLmJ1aWxkRmlsdGVyKCk7XG5cbiAgICAvLyBpc3N1ZXJcbiAgICBpZiAodGhpcy5pc3N1ZXIpIHtcbiAgICAgIGZpbHRlckZucy5wdXNoKHQgPT4gKHQuaXNzdWVyID09PSB0aGlzLmlzc3VlcikpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWNpcGllbnQpIHtcbiAgICAgIGZpbHRlckZucy5wdXNoKHQgPT4gKHQucmVjaXBpZW50ID09PSB0aGlzLnJlY2lwaWVudCkpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJGbnM7XG4gIH1cbn1cblxuY29uc3QgU2F2ZVF1ZXJ5OiBhbnkgPSBncWxgXG4gIG11dGF0aW9uIFNhdmVVc2VyRXZlbnQoJGRhdGE6IFVzZXJFdmVudFZPSW5wdXQpe1xuICAgIGRhdGE6IHNhdmVVc2VyRXZlbnQodXNlckV2ZW50OiAkZGF0YSl7XG4gICAgICAuLi5Vc2VyRXZlbnRGcmFnbWVudFxuICAgIH1cbiAgfVxuICAke1VzZXJFdmVudEZyYWdtZW50cy51c2VyRXZlbnR9XG5gO1xuXG5jb25zdCBMb2FkQWxsUXVlcnk6IGFueSA9IGdxbGBcbiAgcXVlcnkgVXNlckV2ZW50cygkZmlsdGVyOiBVc2VyRXZlbnRGaWx0ZXJWT0lucHV0LCAkcGFnZTogUGFnZUlucHV0KXtcbiAgICBkYXRhOiB1c2VyRXZlbnRzKGZpbHRlcjogJGZpbHRlciwgcGFnZTogJHBhZ2Upe1xuICAgICAgLi4uTGlnaHRVc2VyRXZlbnRGcmFnbWVudFxuICAgIH1cbiAgfVxuICAke1VzZXJFdmVudEZyYWdtZW50cy5saWdodFVzZXJFdmVudH1cbmA7XG5cbmNvbnN0IERlbGV0ZUJ5SWRzTXV0YXRpb246IGFueSA9IGdxbGBcbiAgbXV0YXRpb24gRGVsZXRlVXNlckV2ZW50cygkaWRzOltJbnRdKXtcbiAgICBkZWxldGVVc2VyRXZlbnRzKGlkczogJGlkcylcbiAgfVxuYDtcblxuY29uc3QgTG9hZEFsbFdpdGhDb250ZW50UXVlcnk6IGFueSA9IGdxbGBcbiAgcXVlcnkgVXNlckV2ZW50c1dpdGhDb250ZW50KCRmaWx0ZXI6IFVzZXJFdmVudEZpbHRlclZPSW5wdXQsICRwYWdlOiBQYWdlSW5wdXQpe1xuICAgIGRhdGE6IHVzZXJFdmVudHMoZmlsdGVyOiAkZmlsdGVyLCBwYWdlOiAkcGFnZSl7XG4gICAgICAuLi5Vc2VyRXZlbnRGcmFnbWVudFxuICAgIH1cbiAgfVxuICAke1VzZXJFdmVudEZyYWdtZW50cy51c2VyRXZlbnR9XG5gO1xuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgVXNlckV2ZW50V2F0Y2hPcHRpb25zIGV4dGVuZHMgRW50aXRpZXNTZXJ2aWNlV2F0Y2hPcHRpb25zIHtcbiAgd2l0aENvbnRlbnQ/OiBib29sZWFuOyAvLyBEZWZhdWx0IHRvIGZhbHNlXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlckV2ZW50QWN0aW9uRGVmaW5pdGlvbiBleHRlbmRzIFVzZXJFdmVudEFjdGlvbjxhbnk+IHtcbiAgX190eXBlbmFtZTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcbmV4cG9ydCBjbGFzcyBVc2VyRXZlbnRTZXJ2aWNlXG4gIGV4dGVuZHMgQmFzZUdyYXBocWxTZXJ2aWNlPFVzZXJFdmVudCwgVXNlckV2ZW50RmlsdGVyPlxuICBpbXBsZW1lbnRzIElFbnRpdGllc1NlcnZpY2U8VXNlckV2ZW50LCBVc2VyRXZlbnRGaWx0ZXIsIFVzZXJFdmVudFdhdGNoT3B0aW9ucz4ge1xuXG4gIHByaXZhdGUgX3VzZXJFdmVudEFjdGlvbnM6IFVzZXJFdmVudEFjdGlvbkRlZmluaXRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBncmFwaHFsOiBHcmFwaHFsU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgYWNjb3VudFNlcnZpY2U6IEFjY291bnRTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBuZXR3b3JrOiBOZXR3b3JrU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCB0b2FzdENvbnRyb2xsZXI6IFRvYXN0Q29udHJvbGxlcixcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEVOVklST05NRU5UKSBwcm90ZWN0ZWQgZW52aXJvbm1lbnQ6IEVudmlyb25tZW50XG4gICkge1xuICAgIHN1cGVyKGdyYXBocWwsIGVudmlyb25tZW50KTtcblxuICAgIC8vIEZvciBERVYgb25seVxuICAgIHRoaXMuX2RlYnVnID0gZW52aXJvbm1lbnQgJiYgIWVudmlyb25tZW50LnByb2R1Y3Rpb247XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gc2l6ZVxuICAgKiBAcGFyYW0gc29ydEJ5XG4gICAqIEBwYXJhbSBzb3J0RGlyZWN0aW9uXG4gICAqIEBwYXJhbSBmaWx0ZXJcbiAgICogQHBhcmFtIG9wdGlvbnNcbiAgICogQGRlcHJlY2F0ZWQgdXNlIHdhdGNoUGFnZSgpIGluc3RlYWRcbiAgICovXG4gIHdhdGNoQWxsKG9mZnNldDogbnVtYmVyLFxuICAgICAgICAgICBzaXplOiBudW1iZXIsXG4gICAgICAgICAgIHNvcnRCeT86IHN0cmluZyxcbiAgICAgICAgICAgc29ydERpcmVjdGlvbj86IFNvcnREaXJlY3Rpb24sXG4gICAgICAgICAgIGZpbHRlcj86IFVzZXJFdmVudEZpbHRlcixcbiAgICAgICAgICAgb3B0aW9ucz86IFVzZXJFdmVudFdhdGNoT3B0aW9ucyk6IE9ic2VydmFibGU8TG9hZFJlc3VsdDxVc2VyRXZlbnQ+PiB7XG4gICAgcmV0dXJuIHRoaXMud2F0Y2hQYWdlKDxQYWdlPntvZmZzZXQsIHNpemUsIHNvcnRCeSwgc29ydERpcmVjdGlvbn0sIGZpbHRlciwgb3B0aW9ucyk7XG4gIH1cblxuICB3YXRjaFBhZ2UocGFnZTogUGFnZSxcbiAgICAgICAgICAgIGZpbHRlcj86IFBhcnRpYWw8VXNlckV2ZW50RmlsdGVyPixcbiAgICAgICAgICAgIG9wdGlvbnM/OiBVc2VyRXZlbnRXYXRjaE9wdGlvbnMpOiBPYnNlcnZhYmxlPExvYWRSZXN1bHQ8VXNlckV2ZW50Pj4ge1xuXG4gICAgbGV0IG5vdyA9IHRoaXMuX2RlYnVnICYmIERhdGUubm93KCk7XG4gICAgLy9pZiAodGhpcy5fZGVidWcpXG4gICAgY29uc29sZS5kZWJ1ZygnW3VzZXItZXZlbnQtc2VydmljZV0gTG9hZGluZyB1c2VyIGV2ZW50cy4uLicsIGZpbHRlcik7XG5cbiAgICBmaWx0ZXIgPSB0aGlzLmFzRmlsdGVyKGZpbHRlcik7XG5cbiAgICAvLyBGb3JjZSByZWNpcGllbnQgdG8gY3VycmVudCBpc3N1ZXIsIGlmIG5vdCBhZG1pbiBhbmQgbm90IHNwZWNpZmllZFxuICAgIGlmIChpc05pbE9yQmxhbmsoZmlsdGVyLnJlY2lwaWVudCkgfHwgIXRoaXMuYWNjb3VudFNlcnZpY2UuaXNBZG1pbigpKSB7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQucHVia2V5O1xuICAgICAgaWYgKHJlY2lwaWVudCAhPT0gZmlsdGVyLnJlY2lwaWVudCkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1t1c2VyLWV2ZW50cy1zZXJ2aWNlXSBGb3JjZSB1c2VyIGV2ZW50IGZpbHRlci5yZWNpcGllbnQ9JyArIHJlY2lwaWVudCk7XG4gICAgICAgIGZpbHRlci5yZWNpcGllbnQgPSByZWNpcGllbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgd2l0aENvbnRlbnQgPSBvcHRpb25zICYmIG9wdGlvbnMud2l0aENvbnRlbnQgPT09IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcy5tdXRhYmxlV2F0Y2hRdWVyeTxMb2FkUmVzdWx0PGFueT4+KHtcbiAgICAgIHF1ZXJ5TmFtZTogd2l0aENvbnRlbnQgPyAnTG9hZEFsbFdpdGhDb250ZW50JyA6ICdMb2FkQWxsJyxcbiAgICAgIHF1ZXJ5OiB3aXRoQ29udGVudCA/IExvYWRBbGxXaXRoQ29udGVudFF1ZXJ5IDogTG9hZEFsbFF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIHBhZ2U6IHtcbiAgICAgICAgICBzb3J0Qnk6ICd1cGRhdGVEYXRlJyxcbiAgICAgICAgICAuLi5wYWdlLFxuICAgICAgICAgIHNvcnREaXJlY3Rpb246IChwYWdlLnNvcnREaXJlY3Rpb24gfHwgJ0RFU0MnKS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICB9LFxuICAgICAgICBmaWx0ZXI6IGZpbHRlciAmJiBmaWx0ZXIuYXNQb2RPYmplY3QoKVxuICAgICAgfSxcbiAgICAgIGFycmF5RmllbGROYW1lOiAnZGF0YScsXG4gICAgICBlcnJvcjoge2NvZGU6IFNvY2lhbEVycm9yQ29kZXMuTE9BRF9VU0VSX0VWRU5UU19FUlJPUiwgbWVzc2FnZTogJ1NPQ0lBTC5FUlJPUi5MT0FEX1VTRVJfRVZFTlRTX0VSUk9SJ30sXG4gICAgICBmZXRjaFBvbGljeTogb3B0aW9ucyAmJiBvcHRpb25zLmZldGNoUG9saWN5IHx8IHVuZGVmaW5lZFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKHJlcyA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IHJlcyAmJiAocmVzLmRhdGEgfHwgW10pLm1hcChVc2VyRXZlbnQuZnJvbU9iamVjdCk7XG5cbiAgICAgICAgICBpZiAobm93KSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBbdXNlci1ldmVudC1zZXJ2aWNlXSAke2RhdGEubGVuZ3RofSB1c2VyIGV2ZW50cyBsb2FkZWQgaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zYCk7XG4gICAgICAgICAgICBub3cgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHRvdGFsOiByZXMgJiYgdG9OdW1iZXIocmVzLnRvdGFsLCBkYXRhLmxlbmd0aClcbiAgICAgICAgICB9O1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgfVxuXG4gIHNhdmVBbGwoZGF0YTogVXNlckV2ZW50W10sIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPFVzZXJFdmVudFtdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGRhdGFcbiAgICAgIC5tYXAoZW50aXR5ID0+IHRoaXMuc2F2ZShlbnRpdHksIG9wdGlvbnMpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBhIHVzZXJFdmVudCBlbnRpdHlcbiAgICpcbiAgICogQHBhcmFtIGVudGl0eVxuICAgKi9cbiAgYXN5bmMgc2F2ZShlbnRpdHk6IFVzZXJFdmVudCwgb3B0aW9ucz86IEVudGl0eVNlcnZpY2VMb2FkT3B0aW9ucyk6IFByb21pc2U8VXNlckV2ZW50PiB7XG5cbiAgICB0aGlzLmZpbGxEZWZhdWx0UHJvcGVydGllcyhlbnRpdHkpO1xuXG4gICAgLy8gVHJhbnNmb3JtIGludG8ganNvblxuICAgIGNvbnN0IGlzTmV3ID0gaXNOaWwoZW50aXR5LmlkKTtcbiAgICBjb25zdCBqc29uID0gZW50aXR5LmFzT2JqZWN0KCk7XG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW3VzZXItZXZlbnQtc2VydmljZV0gU2F2aW5nIHVzZXIgZXZlbnQuLi5gLCBqc29uKTtcblxuICAgIGF3YWl0IHRoaXMuZ3JhcGhxbC5tdXRhdGU8eyBkYXRhOiBhbnkgfT4oe1xuICAgICAgbXV0YXRpb246IFNhdmVRdWVyeSxcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBkYXRhOiBqc29uXG4gICAgICB9LFxuICAgICAgZXJyb3I6IHsgY29kZTogU29jaWFsRXJyb3JDb2Rlcy5TQVZFX1VTRVJfRVZFTlRfRVJST1IsIG1lc3NhZ2U6ICdTT0NJQUwuRVJST1IuU0FWRV9VU0VSX0VWRU5UX0VSUk9SJyB9LFxuICAgICAgdXBkYXRlOiAocHJveHksIHtkYXRhfSkgPT4ge1xuICAgICAgICAvLyBVcGRhdGUgZW50aXR5XG4gICAgICAgIGNvbnN0IHNhdmVkRW50aXR5ID0gZGF0YSAmJiBkYXRhLmRhdGE7XG4gICAgICAgIGlmIChzYXZlZEVudGl0eSkge1xuICAgICAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW3VzZXItZXZlbnQtc2VydmljZV0gVXNlciBldmVudCBzYXZlZCBpbiAke0RhdGUubm93KCkgLSBub3d9bXNgLCBlbnRpdHkpO1xuICAgICAgICAgIHRoaXMuY29weUlkQW5kVXBkYXRlRGF0ZShzYXZlZEVudGl0eSwgZW50aXR5KTtcblxuICAgICAgICAgIC8vIEFkZCB0byBjYWNoZVxuICAgICAgICAgIGlmIChpc05ldykge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRJbnRvTXV0YWJsZUNhY2hlZFF1ZXJpZXMocHJveHkse1xuICAgICAgICAgICAgICBxdWVyeTogTG9hZEFsbFF1ZXJ5LFxuICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgLi4uc2F2ZWRFbnRpdHksXG4gICAgICAgICAgICAgICAgY29udGVudDogbnVsbFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0SW50b011dGFibGVDYWNoZWRRdWVyaWVzKHByb3h5LHtcbiAgICAgICAgICAgICAgcXVlcnk6IExvYWRBbGxXaXRoQ29udGVudFF1ZXJ5LFxuICAgICAgICAgICAgICBkYXRhOiBzYXZlZEVudGl0eVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZW50aXR5O1xuICB9XG5cblxuXG4gIC8qKlxuICAgKiBTYXZlIG1hbnkgdHJpcHNcbiAgICpcbiAgICogQHBhcmFtIGVudGl0aWVzXG4gICAqIEBwYXJhbSBvcHRzXG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoZW50aXRpZXM6IFVzZXJFdmVudFtdLCBvcHRzPzoge1xuICAgIHRyYXNoPzogYm9vbGVhbjsgLy8gVHJ1ZSBieSBkZWZhdWx0XG4gIH0pOiBQcm9taXNlPGFueT4ge1xuXG4gICAgY29uc3QgaWRzID0gZW50aXRpZXMgJiYgZW50aXRpZXNcbiAgICAgIC5tYXAodCA9PiB0LmlkKTtcbiAgICBpZiAoaXNFbXB0eUFycmF5KGlkcykpIHJldHVybjsgLy8gc3RvcCwgaWYgbm90aGluZyBlbHNlIHRvIGRvXG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW3VzZXItZXZlbnQtc2VydmljZV0gRGVsZXRpbmcgZXZlbnRzLi4uIGlkczonLCBpZHMpO1xuXG4gICAgYXdhaXQgdGhpcy5ncmFwaHFsLm11dGF0ZTxhbnk+KHtcbiAgICAgIG11dGF0aW9uOiBEZWxldGVCeUlkc011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlkc1xuICAgICAgfSxcbiAgICAgIHVwZGF0ZTogKHByb3h5KSA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIGNhY2hlc1xuICAgICAgICB0aGlzLnJlbW92ZUZyb21NdXRhYmxlQ2FjaGVkUXVlcmllc0J5SWRzKHByb3h5LCB7XG4gICAgICAgICAgcXVlcnk6IExvYWRBbGxRdWVyeSxcbiAgICAgICAgICBpZHNcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVtb3ZlRnJvbU11dGFibGVDYWNoZWRRdWVyaWVzQnlJZHMocHJveHksIHtcbiAgICAgICAgICBxdWVyeTogTG9hZEFsbFdpdGhDb250ZW50UXVlcnksXG4gICAgICAgICAgaWRzXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW3VzZXItZXZlbnQtc2VydmljZV0gRXZlbnRzIGRlbGV0ZWQgaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zYCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHVzZXJFdmVudCBlbnRpdGllc1xuICAgKi9cbiAgYXN5bmMgZGVsZXRlKGRhdGE6IFVzZXJFdmVudCk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm47IC8vIHNraXBcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZUFsbChbZGF0YV0pO1xuICB9XG5cbiAgbGlzdGVuQ2hhbmdlcyhpZDogbnVtYmVyLCBvcHRpb25zPzogYW55KTogT2JzZXJ2YWJsZTxVc2VyRXZlbnQgfCB1bmRlZmluZWQ+IHtcbiAgICAvLyBUT0RPXG4gICAgY29uc29sZS53YXJuKCdUT0RPOiBpbXBsZW1lbnQgbGlzdGVuIGNoYW5nZXMgb24gdXNlciBldmVudHMnKTtcbiAgICByZXR1cm4gb2YoKTtcbiAgfVxuXG4gIHJlZ2lzdGVyQWN0aW9uKGRlZmluaXRpb246IFVzZXJFdmVudEFjdGlvbkRlZmluaXRpb24pIHtcbiAgICBjb25zb2xlLmluZm8oYFt1c2VyLWV2ZW50LXNlcnZpY2VdIFJlZ2lzdGVyaW5nIGFjdGlvbiAke2RlZmluaXRpb24ubmFtZX0gZm9yICR7ZGVmaW5pdGlvbi5fX3R5cGVuYW1lfWApO1xuICAgIHRoaXMuX3VzZXJFdmVudEFjdGlvbnMucHVzaChkZWZpbml0aW9uKTtcbiAgfVxuXG4gIGdldEFjdGlvbnNCeVR5cGVuYW1lKHR5cGVuYW1lOiBzdHJpbmcpOiBVc2VyRXZlbnRBY3Rpb248YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fdXNlckV2ZW50QWN0aW9ucy5maWx0ZXIoZGVmID0+IGRlZi5fX3R5cGVuYW1lID09PSB0eXBlbmFtZSk7XG4gIH1cblxuICBhc3luYyBzaG93VG9hc3RFcnJvcldpdGhDb250ZXh0KG9wdHM6IHtcbiAgICBlcnJvcj86IGFueTtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIGNvbnRleHQ6IGFueSB8ICgoKSA9PiBhbnkpIHwgUHJvbWlzZTxhbnk+O30pIHtcblxuICAgIGxldCBtZXNzYWdlID0gb3B0cy5tZXNzYWdlIHx8IChvcHRzLmVycm9yICYmIG9wdHMuZXJyb3IubWVzc2FnZSB8fCBvcHRzLmVycm9yKTtcblxuICAgIC8vIE1ha2Ugc3VyZSBtZXNzYWdlIGEgc3RyaW5nXG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgbWVzc2FnZSA9ICdFUlJPUi5VTktOT1dOX1RFQ0hOSUNBTF9FUlJPUic7XG4gICAgfVxuXG4gICAgLy8gSWYgb2ZmbGluZSwgZGlzcGxheSBhIHNpbXBsZSBhbGVydFxuICAgIGlmICh0aGlzLm5ldHdvcmsub2ZmbGluZSkge1xuICAgICAgdGhpcy5zaG93VG9hc3Qoe21lc3NhZ2UsIHR5cGU6ICdlcnJvcid9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2xhdGUgdGhlIG1lc3NhZ2UgKHRvIGJlIGFibGUgdG8gZXh0cmFjdCBkZXRhaWxzIGNvbnRlbnQpXG4gICAgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlLmluc3RhbnQobWVzc2FnZSk7XG5cbiAgICAvLyBDbGVhbiBkZXRhaWxzIHBhcnRzXG4gICAgaWYgKG1lc3NhZ2UgJiYgbWVzc2FnZS5pbmRleE9mKCc8c21hbGw+JykgIT09IC0xKSB7XG4gICAgICBtZXNzYWdlID0gbWVzc2FnZS5zdWJzdHIoMCwgbWVzc2FnZS5pbmRleE9mKCc8c21hbGw+JykgLSAxKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnNob3dUb2FzdCh7XG4gICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgZHVyYXRpb246IDE1MDAwLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZSArICc8YnIvPjxici8+PGI+JyArIHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ0NPTkZJUk0uU0VORF9ERUJVR19EQVRBJykgKyAnPC9iPicsXG4gICAgICBidXR0b25zOiBbe1xuICAgICAgICBpY29uOiAnYnVnJyxcbiAgICAgICAgdGV4dDogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnQ09NTU9OLkJUTl9TRU5EJyksXG4gICAgICAgIHJvbGU6ICdzZW5kJ1xuICAgICAgfV1cbiAgICB9KTtcbiAgICBpZiAoIXJlcyB8fCByZXMucm9sZSAhPT0gJ3NlbmQnKSByZXR1cm47XG5cbiAgICAvLyBTZW5kIGRlYnVnIGRhdGFcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIGRlYnVnIGRhdGEuLi4nKTtcblxuICAgICAgLy8gQ2FsbCBjb250ZW50IGZhY3RvcnlcbiAgICAgIGxldCBjb250ZXh0OiBhbnkgPSBvcHRzICYmIG9wdHMuY29udGV4dDtcbiAgICAgIGlmICh0eXBlb2YgY29udGV4dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb250ZXh0ID0gY29udGV4dCgpO1xuICAgICAgfVxuICAgICAgaWYgKGNvbnRleHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIGNvbnRleHQgPSBhd2FpdCBjb250ZXh0O1xuICAgICAgfVxuXG4gICAgICAvLyBTZW5kIHRoZSBtZXNzYWdlXG4gICAgICBjb25zdCB1c2VyRXZlbnQgPSBhd2FpdCB0aGlzLnNlbmREYXRhRm9yRGVidWcoe1xuICAgICAgICBtZXNzYWdlLFxuICAgICAgICBlcnJvcjogb3B0cy5lcnJvciB8fCB1bmRlZmluZWQsXG4gICAgICAgIGNvbnRleHQ6IHRoaXMuY29udmVydE9iamVjdFRvU3RyaW5nKGNvbnRleHQpXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5pbmZvKCdEZWJ1ZyBkYXRhIHN1Y2Nlc3NmdWxseSBzZW50IHRvIGFkbWluJywgdXNlckV2ZW50KTtcbiAgICAgIHRoaXMuc2hvd1RvYXN0KHtcbiAgICAgICAgdHlwZTogJ2luZm8nLFxuICAgICAgICBtZXNzYWdlOiAnSU5GTy5ERUJVR19EQVRBX1NFTkQnLFxuICAgICAgICBzaG93Q2xvc2VCdXR0b246IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciB3aGlsZSBzZW5kaW5nIGRlYnVnIGRhdGE6JywgZXJyKTtcbiAgICB9XG4gIH1cblxuICBzZW5kRGF0YUZvckRlYnVnKGRhdGE6IGFueSk6IFByb21pc2U8VXNlckV2ZW50PiB7XG4gICAgY29uc3QgdXNlckV2ZW50ID0gbmV3IFVzZXJFdmVudCgpO1xuICAgIHVzZXJFdmVudC5ldmVudFR5cGUgPSBVc2VyRXZlbnRUeXBlcy5ERUJVR19EQVRBO1xuICAgIHVzZXJFdmVudC5jb250ZW50ID0gdGhpcy5jb252ZXJ0T2JqZWN0VG9TdHJpbmcoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuc2F2ZSh1c2VyRXZlbnQpO1xuICB9XG5cbiAgYXNGaWx0ZXIoZmlsdGVyOiBQYXJ0aWFsPFVzZXJFdmVudEZpbHRlcj4pOiBVc2VyRXZlbnRGaWx0ZXIge1xuICAgIHJldHVybiBVc2VyRXZlbnRGaWx0ZXIuZnJvbU9iamVjdChmaWx0ZXIpO1xuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIG1ldGhvZHMgLS0gKi9cblxuICBwcm90ZWN0ZWQgY29udmVydE9iamVjdFRvU3RyaW5nKGRhdGE6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJyl7XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLy8gU2VyaWFsaXplIGNvbnRlbnQgaW50byBzdHJpbmdcbiAgICBlbHNlIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpe1xuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBFbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEuYXNPYmplY3Qoe2tlZXBUeXBlbmFtZTogdHJ1ZSwga2VlcExvY2FsSWQ6IHRydWUsIG1pbmlmeTogZmFsc2V9KSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzaG93VG9hc3Q8VD1hbnk+KG9wdHM6IFNob3dUb2FzdE9wdGlvbnMpOiBQcm9taXNlPE92ZXJsYXlFdmVudERldGFpbDxUPj4ge1xuICAgIGlmICghdGhpcy50b2FzdENvbnRyb2xsZXIpIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0b2FzdENvbnRyb2xsZXIgaW4gY29tcG9uZW50XFwncyBjb25zdHJ1Y3RvcicpO1xuICAgIHJldHVybiBhd2FpdCBUb2FzdHMuc2hvdyh0aGlzLnRvYXN0Q29udHJvbGxlciwgdGhpcy50cmFuc2xhdGUsIG9wdHMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGZpbGxEZWZhdWx0UHJvcGVydGllcyhlbnRpdHk6IFVzZXJFdmVudCkge1xuICAgIGVudGl0eS5pc3N1ZXIgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQucHVia2V5O1xuXG4gICAgLy8gVE9ETzogY29tcHV0ZSBoYXNoICh1c2luZyBjcnlwdG9TZXJ2aWNlKVxuICAgIC8vIFRPRE86IGNvbXB1dGUgc2lnblxuICAgIGNvbnNvbGUud2FybignVE9ETzogc2lnbiB1c2VyIGV2ZW50IGJlZm9yZSBzZW5kaW5nJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29weUlkQW5kVXBkYXRlRGF0ZShzb3VyY2U6IFVzZXJFdmVudCwgdGFyZ2V0OiBVc2VyRXZlbnQpIHtcbiAgICBFbnRpdHlVdGlscy5jb3B5SWRBbmRVcGRhdGVEYXRlKHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,154 @@
1
+ import { __awaiter } from "tslib";
2
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Injector, Input } from '@angular/core';
3
+ import { UserEventFilter, UserEventService } from './user-event.service';
4
+ import { AccountService } from '../../core/services/account.service';
5
+ import { UserEvent, UserEventTypes } from './user-event.model';
6
+ import { toBoolean } from '../../shared/functions';
7
+ import { AppTable, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS } from '../../core/table/table.class';
8
+ import { EntitiesTableDataSource } from '../../core/table/entities-table-datasource.class';
9
+ import { EntitiesStorage } from '../../core/services/storage/entities-storage.service';
10
+ import { ENVIRONMENT } from '../../../environments/environment.class';
11
+ const ICONS_MAP = {
12
+ DEBUG_DATA: { matIcon: 'bug_report' },
13
+ INBOX_MESSAGE: { matIcon: 'mail' },
14
+ };
15
+ // TODO: refactor with a registration done by data service:
16
+ // - userEventService.registerEventAction({__typename: 'TripVO', ...})
17
+ // - userEventService.getActionsFor(__typename): UserEventDetailAction
18
+ /*const DETAILS_MAP: {[key: string]: UserEventAction<RootDataEntity<any>>} = {
19
+ "TripVO": {
20
+ icon: null,
21
+ matIcon: "content_copy",
22
+ action: 'copyToLocal',
23
+ actionTitle: 'SOCIAL.USER_EVENT.BTN_COPY_TO_LOCAL',
24
+ actionColor: 'primary',
25
+ fromObject: Trip.fromObject,
26
+ childrenFields: ['operation', 'landing']
27
+ },
28
+ "ObservedLocationVO": {
29
+ icon: null,
30
+ matIcon: "content_copy",
31
+ action: 'copyToLocal',
32
+ actionTitle: 'SOCIAL.USER_EVENT.BTN_COPY_TO_LOCAL',
33
+ actionColor: 'primary',
34
+ fromObject: ObservedLocation.fromObject,
35
+ childrenFields: ['landings']
36
+ }
37
+ }*/
38
+ export class UserEventsTable extends AppTable {
39
+ constructor(injector, accountService, service, entities, cd, environment) {
40
+ super(injector,
41
+ // columns
42
+ RESERVED_START_COLUMNS
43
+ .concat([
44
+ 'creationDate',
45
+ 'icon',
46
+ 'eventType',
47
+ 'message'
48
+ ])
49
+ .concat(RESERVED_END_COLUMNS), null, null);
50
+ this.accountService = accountService;
51
+ this.service = service;
52
+ this.entities = entities;
53
+ this.cd = cd;
54
+ this.environment = environment;
55
+ this.i18nColumnPrefix = 'SOCIAL.USER_EVENT.';
56
+ this.autoLoad = false; // this.start()
57
+ this.inlineEdition = false;
58
+ this.defaultSortBy = 'creationDate';
59
+ this.defaultSortDirection = 'desc';
60
+ }
61
+ ngOnInit() {
62
+ super.ngOnInit();
63
+ // Load date/time pattern
64
+ this.dateTimePattern = this.translate.instant('COMMON.DATE_TIME_PATTERN');
65
+ this.withContent = toBoolean(this.withContent, false);
66
+ const account = this.accountService.account;
67
+ const pubkey = account && account.pubkey;
68
+ this.isAdmin = this.accountService.isAdmin();
69
+ this.canEdit = this.isAdmin || pubkey === this.recipient;
70
+ this.canDelete = this.canEdit;
71
+ this.setDatasource(new EntitiesTableDataSource(UserEvent, this.service, null, {
72
+ prependNewElements: false,
73
+ suppressErrors: true,
74
+ dataServiceOptions: {
75
+ withContent: this.withContent
76
+ }
77
+ }));
78
+ const filter = this.filter || new UserEventFilter();
79
+ filter.recipient = this.recipient;
80
+ this.setFilter(filter, { emitEvent: true });
81
+ }
82
+ start() {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ console.debug('[user-event] Starting...');
85
+ // Waiting account to be ready
86
+ yield this.accountService.ready();
87
+ // Load data
88
+ this.onRefresh.emit();
89
+ });
90
+ }
91
+ getIcon(source) {
92
+ return ICONS_MAP[source.eventType];
93
+ }
94
+ getDetail(source) {
95
+ if (!source)
96
+ return undefined;
97
+ if (source.content && source.eventType === UserEventTypes.DEBUG_DATA) {
98
+ const context = source.content.context;
99
+ if (context && context.__typename) {
100
+ const actions = this.service.getActionsByTypename(context.__typename);
101
+ return {
102
+ actions,
103
+ title: source.content.error && source.content.error.message || source.content.message,
104
+ description: source.content.error && source.content.error.details || undefined
105
+ };
106
+ }
107
+ }
108
+ console.debug('TODO: implement getDetail() for event: ', source);
109
+ return {};
110
+ }
111
+ doAction(action, row) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ const event = row.currentData;
114
+ const context = event.content && event.content.context;
115
+ this.markAsLoading();
116
+ if (action && typeof action.executeAction === 'function') {
117
+ try {
118
+ let res = action.executeAction(event, context);
119
+ res = (res instanceof Promise) ? yield res : res;
120
+ }
121
+ catch (err) {
122
+ this.setError(err && err.message || err);
123
+ console.error(`[user-event] Failed to execute action ${action.name}: ${err && err.message || err}`, err);
124
+ }
125
+ finally {
126
+ this.markAsLoaded();
127
+ }
128
+ }
129
+ });
130
+ }
131
+ }
132
+ UserEventsTable.decorators = [
133
+ { type: Component, args: [{
134
+ selector: 'app-user-events-table',
135
+ template: "\n<!-- Type = options menu -->\n<mat-menu #optionsMenu=\"matMenu\" xPosition=\"after\">\n\n <!-- display columns -->\n <button mat-menu-item\n (click)=\"openSelectColumnsModal($event)\">\n <mat-icon>view_column</mat-icon>\n <ion-label translate>COMMON.DISPLAYED_COLUMNS_DOTS</ion-label>\n </button>\n\n</mat-menu>\n\n<!-- top header -->\n<mat-toolbar>\n\n <ng-container *ngIf=\"!selection.hasValue(); else hasSelection\">\n\n <button mat-icon-button [title]=\"'COMMON.BTN_REFRESH'|translate\" (click)=\"onRefresh.emit()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n </ng-container>\n\n <!-- if row selection -->\n <ng-template #hasSelection>\n\n <!-- delete -->\n <button mat-icon-button class=\"hidden-xs hidden-sm\" *ngIf=\"canDelete\"\n [title]=\"'COMMON.BTN_DELETE'|translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete</mat-icon>\n </button>\n </ng-template>\n\n <!-- error -->\n <ion-item *ngIf=\"error\" hidden-xs hidden-sm hidden-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button mat-icon-button\n [title]=\"'COMMON.BTN_OPTIONS'|translate\"\n [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n</mat-toolbar>\n\n\n<mat-table [dataSource]=\"dataSource\" matSort\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear [trackBy]=\"trackByFn\">\n\n <!-- select -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\" [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <!-- id -->\n <ng-container matColumnDef=\"id\">\n <mat-header-cell *matHeaderCellDef mat-sort-header [class.cdk-visually-hidden]=\"!isAdmin\">\n <app-loading-spinner [loading]=\"loadingSubject|async\"><ion-label>#</ion-label></app-loading-spinner>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!isAdmin\">{{ row.currentData.id | mathAbs }}</mat-cell>\n </ng-container>\n\n <!-- creationDate -->\n <ng-container matColumnDef=\"creationDate\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.CREATION_DATE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ion-text>\n {{row.currentData.creationDate | dateFromNow }}<br/>\n <ion-text color=\"medium\"><small>{{row.currentData.creationDate | dateFormat: {time: true} }}</small></ion-text>\n </ion-text>\n </mat-cell>\n </ng-container>\n\n <!-- icon -->\n <ng-container matColumnDef=\"icon\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getIcon(row.currentData); let details\">\n <ion-icon slot=\"start\" *ngIf=\"details.icon\" [name]=\"details.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"details.matIcon\">{{details.matIcon}}</mat-icon>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- event type -->\n <ng-container matColumnDef=\"eventType\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>SOCIAL.USER_EVENT.EVENT_TYPE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <span>{{'SOCIAL.USER_EVENT.TYPE_ENUM.' + row.currentData.eventType | translate}}</span>\n </mat-cell>\n </ng-container>\n\n <!-- message -->\n <ng-container matColumnDef=\"message\">\n <mat-header-cell *matHeaderCellDef>\n <ion-label translate>SOCIAL.USER_EVENT.MESSAGE</ion-label>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row;\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <ion-text [innerHTML]=\"details.title|translate\">\n </ion-text>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <!-- Actions buttons column -->\n <ng-container matColumnDef=\"actions\">\n <mat-header-cell *matHeaderCellDef>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <ng-container *ngIf=\"getDetail(row.currentData); let details\">\n <button mat-icon-button color=\"light\"\n *ngFor=\"let action of details.actions\"\n [title]=\"action.title |translate\"\n [color]=\"action.color\"\n (click)=\"doAction(action, row)\">\n <ion-icon slot=\"start\" *ngIf=\"action.icon\" [name]=\"action.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"action.matIcon\">{{action.matIcon}}</mat-icon>\n </button>\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedColumns;\"\n class=\"mat-row-disabled\"\n (click)=\"clickRow($event, row)\"></mat-row>\n\n</mat-table>\n\n<ion-row class=\"ion-no-padding\">\n <ion-col></ion-col>\n <ion-col class=\"ion-no-padding\" size=\"auto\">\n <mat-paginator [length]=\"totalRowCount\" [pageSize]=\"defaultPageSize\" [pageSizeOptions]=\"defaultPageSizeOptions\" showFirstLastButtons>\n </mat-paginator>\n </ion-col>\n</ion-row>\n",
136
+ changeDetection: ChangeDetectionStrategy.OnPush,
137
+ styles: [".mat-header-row .mat-column-icon,.mat-row .mat-column-icon{max-width:40px;padding-left:0}.mat-header-row .mat-column-icon ion-icon,.mat-header-row .mat-column-icon mat-icon,.mat-row .mat-column-icon ion-icon,.mat-row .mat-column-icon mat-icon{font-size:1.2em;height:1.2em;width:1.2em}.mat-header-row .mat-column-creationDate,.mat-row .mat-column-creationDate{min-width:100px;max-width:120px}"]
138
+ },] }
139
+ ];
140
+ UserEventsTable.ctorParameters = () => [
141
+ { type: Injector },
142
+ { type: AccountService },
143
+ { type: UserEventService },
144
+ { type: EntitiesStorage },
145
+ { type: ChangeDetectorRef },
146
+ { type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
147
+ ];
148
+ UserEventsTable.propDecorators = {
149
+ recipient: [{ type: Input }],
150
+ withContent: [{ type: Input }],
151
+ defaultSortBy: [{ type: Input }],
152
+ defaultSortDirection: [{ type: Input }]
153
+ };
154
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1ldmVudHMudGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NvY2lhbC91c2VyLWV2ZW50L3VzZXItZXZlbnRzLnRhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBRXZILE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDckUsT0FBTyxFQUFFLFNBQVMsRUFBbUIsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFaEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRW5ELE9BQU8sRUFBRSxRQUFRLEVBQUUsb0JBQW9CLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUl0RyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUUzRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFHdkYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBK0J0RSxNQUFNLFNBQVMsR0FBb0M7SUFDakQsVUFBVSxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQztJQUNuQyxhQUFhLEVBQUUsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFDO0NBQ2pDLENBQUM7QUFFRiwyREFBMkQ7QUFDM0Qsc0VBQXNFO0FBQ3RFLHNFQUFzRTtBQUN0RTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQVNILE1BQU0sT0FBTyxlQUFnQixTQUFRLFFBQW9DO0lBY3ZFLFlBQ0UsUUFBa0IsRUFDUixjQUE4QixFQUM5QixP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Q0FBQyxHQUFHLENBQUM7aUJBQ2xEO2dCQUFDLE9BQU8sR0FBRyxFQUFFO29CQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLENBQUM7b0JBQ3pDLE9BQU8sQ0FBQyxLQUFLLENBQUMseUNBQXlDLE1BQU0sQ0FBQyxJQUFJLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLElBQUksR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7aUJBQzFHO3dCQUNPO29CQUNOLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztpQkFDckI7YUFDRjtRQUNILENBQUM7S0FBQTs7O1lBbklGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsdUJBQXVCO2dCQUVqQyxnMkxBQXVDO2dCQUN2QyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTs7YUFDOUM7OztZQW5GcUUsUUFBUTtZQUd2RSxjQUFjO1lBREcsZ0JBQWdCO1lBWWpDLGVBQWU7WUFkVSxpQkFBaUI7NENBd0c5QyxNQUFNLFNBQUMsV0FBVzs7O3dCQVpwQixLQUFLOzBCQUVMLEtBQUs7NEJBQ0wsS0FBSzttQ0FDTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdCwgSW5qZWN0b3IsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRhYmxlRWxlbWVudCB9IGZyb20gJ0BlLWlzL25neC1tYXRlcmlhbC10YWJsZSc7XG5pbXBvcnQgeyBVc2VyRXZlbnRGaWx0ZXIsIFVzZXJFdmVudFNlcnZpY2UgfSBmcm9tICcuL3VzZXItZXZlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBBY2NvdW50U2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7IFVzZXJFdmVudCwgVXNlckV2ZW50QWN0aW9uLCBVc2VyRXZlbnRUeXBlcyB9IGZyb20gJy4vdXNlci1ldmVudC5tb2RlbCc7XG5pbXBvcnQgeyBMb2NhbFNldHRpbmdzU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvbG9jYWwtc2V0dGluZ3Muc2VydmljZSc7XG5pbXBvcnQgeyB0b0Jvb2xlYW4gfSBmcm9tICcuLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7IE1vbWVudCB9IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyBBcHBUYWJsZSwgUkVTRVJWRURfRU5EX0NPTFVNTlMsIFJFU0VSVkVEX1NUQVJUX0NPTFVNTlMgfSBmcm9tICcuLi8uLi9jb3JlL3RhYmxlL3RhYmxlLmNsYXNzJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTW9kYWxDb250cm9sbGVyLCBQbGF0Zm9ybSB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEVudGl0aWVzVGFibGVEYXRhU291cmNlIH0gZnJvbSAnLi4vLi4vY29yZS90YWJsZS9lbnRpdGllcy10YWJsZS1kYXRhc291cmNlLmNsYXNzJztcbmltcG9ydCB7IFNvcnREaXJlY3Rpb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcbmltcG9ydCB7IEVudGl0aWVzU3RvcmFnZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvc3RvcmFnZS9lbnRpdGllcy1zdG9yYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUHJlZGVmaW5lZENvbG9ycyB9IGZyb20gJ0Bpb25pYy9jb3JlJztcbmltcG9ydCB7IElFbnRpdHkgfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL21vZGVsL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQgeyBFTlZJUk9OTUVOVCB9IGZyb20gJy4uLy4uLy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudC5jbGFzcyc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBVc2VyRXZlbnREZXRhaWw8VCBleHRlbmRzIElFbnRpdHk8VD4+IHtcbiAgdGl0bGU6IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIHBhdGg/OiBzdHJpbmc7XG5cbiAgYWN0aW9uPzogc3RyaW5nIHwgYW55O1xuICBhY3Rpb25UaXRsZT86IHN0cmluZztcbiAgYWN0aW9uQ29sb3I/OiBQcmVkZWZpbmVkQ29sb3JzO1xuXG4gIGljb24/OiBzdHJpbmc7XG4gIG1hdEljb24/OiBzdHJpbmc7XG4gIGNvbG9yPzogc3RyaW5nO1xuICBjc3NDbGFzcz86IHN0cmluZztcbiAgdGltZT86IE1vbWVudDtcblxuICAvLyBBIGNvbmZpZyBwcm9wZXJ0eSwgdG8gb3ZlcnJpZGUgdGhlIHRpdGxlXG4gIHRpdGxlUHJvcGVydHk/OiBzdHJpbmc7XG4gIHRpdGxlQXJncz86IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9O1xuXG4gIC8vIGNvbnZlcnNpb25cbiAgZnJvbU9iamVjdD86IChzb3VyY2U6IGFueSkgPT4gVDtcbiAgY2hpbGRyZW5GaWVsZHM/OiBzdHJpbmdbXTtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVXNlckV2ZW50SWNvbntcbiAgaWNvbj86IHN0cmluZztcbiAgbWF0SWNvbj86IHN0cmluZztcbiAgY29sb3I/OiBQcmVkZWZpbmVkQ29sb3JzO1xufVxuY29uc3QgSUNPTlNfTUFQOiB7W2tleTogc3RyaW5nXTogVXNlckV2ZW50SWNvbiB9ID0ge1xuICBERUJVR19EQVRBOiB7bWF0SWNvbjogJ2J1Z19yZXBvcnQnfSxcbiAgSU5CT1hfTUVTU0FHRToge21hdEljb246ICdtYWlsJ30sXG59O1xuXG4vLyBUT0RPOiByZWZhY3RvciB3aXRoIGEgcmVnaXN0cmF0aW9uIGRvbmUgYnkgZGF0YSBzZXJ2aWNlOlxuLy8gLSB1c2VyRXZlbnRTZXJ2aWNlLnJlZ2lzdGVyRXZlbnRBY3Rpb24oe19fdHlwZW5hbWU6ICdUcmlwVk8nLCAuLi59KVxuLy8gLSB1c2VyRXZlbnRTZXJ2aWNlLmdldEFjdGlvbnNGb3IoX190eXBlbmFtZSk6IFVzZXJFdmVudERldGFpbEFjdGlvblxuLypjb25zdCBERVRBSUxTX01BUDoge1trZXk6IHN0cmluZ106IFVzZXJFdmVudEFjdGlvbjxSb290RGF0YUVudGl0eTxhbnk+Pn0gPSB7XG4gIFwiVHJpcFZPXCI6IHtcbiAgICBpY29uOiBudWxsLFxuICAgIG1hdEljb246IFwiY29udGVudF9jb3B5XCIsXG4gICAgYWN0aW9uOiAnY29weVRvTG9jYWwnLFxuICAgIGFjdGlvblRpdGxlOiAnU09DSUFMLlVTRVJfRVZFTlQuQlROX0NPUFlfVE9fTE9DQUwnLFxuICAgIGFjdGlvbkNvbG9yOiAncHJpbWFyeScsXG4gICAgZnJvbU9iamVjdDogVHJpcC5mcm9tT2JqZWN0LFxuICAgIGNoaWxkcmVuRmllbGRzOiBbJ29wZXJhdGlvbicsICdsYW5kaW5nJ11cbiAgfSxcbiAgXCJPYnNlcnZlZExvY2F0aW9uVk9cIjoge1xuICAgIGljb246IG51bGwsXG4gICAgbWF0SWNvbjogXCJjb250ZW50X2NvcHlcIixcbiAgICBhY3Rpb246ICdjb3B5VG9Mb2NhbCcsXG4gICAgYWN0aW9uVGl0bGU6ICdTT0NJQUwuVVNFUl9FVkVOVC5CVE5fQ09QWV9UT19MT0NBTCcsXG4gICAgYWN0aW9uQ29sb3I6ICdwcmltYXJ5JyxcbiAgICBmcm9tT2JqZWN0OiBPYnNlcnZlZExvY2F0aW9uLmZyb21PYmplY3QsXG4gICAgY2hpbGRyZW5GaWVsZHM6IFsnbGFuZGluZ3MnXVxuICB9XG59Ki9cblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtdXNlci1ldmVudHMtdGFibGUnLFxuICBzdHlsZVVybHM6IFsndXNlci1ldmVudHMudGFibGUuc2NzcyddLFxuICB0ZW1wbGF0ZVVybDogJy4vdXNlci1ldmVudHMudGFibGUuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG4gIH0pXG5leHBvcnQgY2xhc3MgVXNlckV2ZW50c1RhYmxlIGV4dGVuZHMgQXBwVGFibGU8VXNlckV2ZW50LCBVc2VyRXZlbnRGaWx0ZXI+XG4gIGltcGxlbWVudHMgT25Jbml0IHtcblxuICBkYXRlVGltZVBhdHRlcm46IHN0cmluZztcbiAgY2FuRWRpdDogYm9vbGVhbjtcbiAgY2FuRGVsZXRlOiBib29sZWFuO1xuICBpc0FkbWluOiBib29sZWFuO1xuXG4gIEBJbnB1dCgpIHJlY2lwaWVudDogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHdpdGhDb250ZW50OiBib29sZWFuO1xuICBASW5wdXQoKSBkZWZhdWx0U29ydEJ5OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGRlZmF1bHRTb3J0RGlyZWN0aW9uOiBTb3J0RGlyZWN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcm90ZWN0ZWQgYWNjb3VudFNlcnZpY2U6IEFjY291bnRTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBzZXJ2aWNlOiBVc2VyRXZlbnRTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBlbnRpdGllczogRW50aXRpZXNTdG9yYWdlLFxuICAgIHByb3RlY3RlZCBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQEluamVjdChFTlZJUk9OTUVOVCkgcHJvdGVjdGVkIGVudmlyb25tZW50XG4gICkge1xuICAgIHN1cGVyKGluamVjdG9yLFxuICAgICAgLy8gY29sdW1uc1xuICAgICAgUkVTRVJWRURfU1RBUlRfQ09MVU1OU1xuICAgICAgICAuY29uY2F0KFtcbiAgICAgICAgICAnY3JlYXRpb25EYXRlJyxcbiAgICAgICAgICAnaWNvbicsXG4gICAgICAgICAgJ2V2ZW50VHlwZScsXG4gICAgICAgICAgJ21lc3NhZ2UnXG4gICAgICAgIF0pXG4gICAgICAgIC5jb25jYXQoUkVTRVJWRURfRU5EX0NPTFVNTlMpLFxuICAgICAgbnVsbCxcbiAgICAgIG51bGwpO1xuXG4gICAgdGhpcy5pMThuQ29sdW1uUHJlZml4ID0gJ1NPQ0lBTC5VU0VSX0VWRU5ULic7XG4gICAgdGhpcy5hdXRvTG9hZCA9IGZhbHNlOyAvLyB0aGlzLnN0YXJ0KClcbiAgICB0aGlzLmlubGluZUVkaXRpb24gPSBmYWxzZTtcbiAgICB0aGlzLmRlZmF1bHRTb3J0QnkgPSAnY3JlYXRpb25EYXRlJztcbiAgICB0aGlzLmRlZmF1bHRTb3J0RGlyZWN0aW9uID0gJ2Rlc2MnO1xuXG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgLy8gTG9hZCBkYXRlL3RpbWUgcGF0dGVyblxuICAgIHRoaXMuZGF0ZVRpbWVQYXR0ZXJuID0gdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnQ09NTU9OLkRBVEVfVElNRV9QQVRURVJOJyk7XG4gICAgdGhpcy53aXRoQ29udGVudCA9IHRvQm9vbGVhbih0aGlzLndpdGhDb250ZW50LCBmYWxzZSk7XG5cbiAgICBjb25zdCBhY2NvdW50ID0gdGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50O1xuICAgIGNvbnN0IHB1YmtleSA9IGFjY291bnQgJiYgYWNjb3VudC5wdWJrZXk7XG4gICAgdGhpcy5pc0FkbWluID0gdGhpcy5hY2NvdW50U2VydmljZS5pc0FkbWluKCk7XG4gICAgdGhpcy5jYW5FZGl0ID0gdGhpcy5pc0FkbWluIHx8IHB1YmtleSA9PT0gdGhpcy5yZWNpcGllbnQ7XG4gICAgdGhpcy5jYW5EZWxldGUgPSB0aGlzLmNhbkVkaXQ7XG5cbiAgICB0aGlzLnNldERhdGFzb3VyY2UobmV3IEVudGl0aWVzVGFibGVEYXRhU291cmNlKFVzZXJFdmVudCxcbiAgICAgIHRoaXMuc2VydmljZSxcbiAgICAgIG51bGwsXG4gICAgICB7XG4gICAgICAgIHByZXBlbmROZXdFbGVtZW50czogZmFsc2UsXG4gICAgICAgIHN1cHByZXNzRXJyb3JzOiB0cnVlLFxuICAgICAgICBkYXRhU2VydmljZU9wdGlvbnM6IHtcbiAgICAgICAgICB3aXRoQ29udGVudDogdGhpcy53aXRoQ29udGVudFxuICAgICAgICB9XG4gICAgICB9KSk7XG5cbiAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLmZpbHRlciB8fCBuZXcgVXNlckV2ZW50RmlsdGVyKCk7XG4gICAgZmlsdGVyLnJlY2lwaWVudCA9IHRoaXMucmVjaXBpZW50O1xuICAgIHRoaXMuc2V0RmlsdGVyKGZpbHRlciwge2VtaXRFdmVudDogdHJ1ZX0pO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgY29uc29sZS5kZWJ1ZygnW3VzZXItZXZlbnRdIFN0YXJ0aW5nLi4uJyk7XG5cbiAgICAvLyBXYWl0aW5nIGFjY291bnQgdG8gYmUgcmVhZHlcbiAgICBhd2FpdCB0aGlzLmFjY291bnRTZXJ2aWNlLnJlYWR5KCk7XG5cbiAgICAvLyBMb2FkIGRhdGFcbiAgICB0aGlzLm9uUmVmcmVzaC5lbWl0KCk7XG4gIH1cblxuICBnZXRJY29uKHNvdXJjZTogVXNlckV2ZW50KTogVXNlckV2ZW50SWNvbiB7XG4gICAgcmV0dXJuIElDT05TX01BUFtzb3VyY2UuZXZlbnRUeXBlXTtcbiAgfVxuXG4gIGdldERldGFpbChzb3VyY2U6IFVzZXJFdmVudCk6IFBhcnRpYWw8VXNlckV2ZW50RGV0YWlsPElFbnRpdHk8YW55Pj4gJiB7YWN0aW9uczogVXNlckV2ZW50QWN0aW9uPGFueT5bXX0+IHtcbiAgICBpZiAoIXNvdXJjZSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGlmIChzb3VyY2UuY29udGVudCAmJiBzb3VyY2UuZXZlbnRUeXBlID09PSBVc2VyRXZlbnRUeXBlcy5ERUJVR19EQVRBKSB7XG4gICAgICBjb25zdCBjb250ZXh0ID0gc291cmNlLmNvbnRlbnQuY29udGV4dDtcbiAgICAgIGlmIChjb250ZXh0ICYmIGNvbnRleHQuX190eXBlbmFtZSkge1xuICAgICAgICBjb25zdCBhY3Rpb25zID0gdGhpcy5zZXJ2aWNlLmdldEFjdGlvbnNCeVR5cGVuYW1lKGNvbnRleHQuX190eXBlbmFtZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgYWN0aW9ucyxcbiAgICAgICAgICB0aXRsZTogc291cmNlLmNvbnRlbnQuZXJyb3IgJiYgc291cmNlLmNvbnRlbnQuZXJyb3IubWVzc2FnZSB8fCBzb3VyY2UuY29udGVudC5tZXNzYWdlLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBzb3VyY2UuY29udGVudC5lcnJvciAmJiBzb3VyY2UuY29udGVudC5lcnJvci5kZXRhaWxzIHx8IHVuZGVmaW5lZFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnNvbGUuZGVidWcoJ1RPRE86IGltcGxlbWVudCBnZXREZXRhaWwoKSBmb3IgZXZlbnQ6ICcsIHNvdXJjZSk7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cblxuICBhc3luYyBkb0FjdGlvbihhY3Rpb246IFVzZXJFdmVudEFjdGlvbjxhbnk+LCByb3c6IFRhYmxlRWxlbWVudDxVc2VyRXZlbnQ+KSB7XG5cbiAgICBjb25zdCBldmVudCA9IHJvdy5jdXJyZW50RGF0YTtcbiAgICBjb25zdCBjb250ZXh0ID0gZXZlbnQuY29udGVudCAmJiBldmVudC5jb250ZW50LmNvbnRleHQ7XG5cbiAgICB0aGlzLm1hcmtBc0xvYWRpbmcoKTtcblxuICAgIGlmIChhY3Rpb24gJiYgdHlwZW9mIGFjdGlvbi5leGVjdXRlQWN0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBsZXQgcmVzID0gYWN0aW9uLmV4ZWN1dGVBY3Rpb24oZXZlbnQsIGNvbnRleHQpO1xuICAgICAgICByZXMgPSAocmVzIGluc3RhbmNlb2YgUHJvbWlzZSkgPyBhd2FpdCByZXMgOiByZXM7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5zZXRFcnJvcihlcnIgJiYgZXJyLm1lc3NhZ2UgfHwgZXJyKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihgW3VzZXItZXZlbnRdIEZhaWxlZCB0byBleGVjdXRlIGFjdGlvbiAke2FjdGlvbi5uYW1lfTogJHtlcnIgJiYgZXJyLm1lc3NhZ2UgfHwgZXJyfWAsIGVycik7XG4gICAgICB9XG4gICAgICBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5tYXJrQXNMb2FkZWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufVxuIl19