@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.
- package/bundles/sumaris-net.ngx-components.umd.js +804 -429
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/doc/changelog.md +10 -0
- package/esm2015/public_api.js +10 -5
- package/esm2015/src/app/admin/admin-routing.module.js +3 -1
- package/esm2015/src/app/admin/admin.module.js +2 -1
- package/esm2015/src/app/admin/users/list/users.js +45 -7
- package/esm2015/src/app/core/services/base-entity-service.class.js +6 -6
- package/esm2015/src/app/core/services/local-settings.service.js +5 -5
- package/esm2015/src/app/core/services/model/referential.model.js +1 -1
- package/esm2015/src/app/core/services/platform.service.js +3 -4
- package/esm2015/src/app/shared/material/datetime/material.date.js +82 -70
- package/esm2015/src/app/shared/material/datetime/material.datetime.js +3 -3
- package/esm2015/src/app/shared/material/datetime/testing/mat-date.test.js +7 -5
- package/esm2015/src/app/shared/platforms.js +20 -4
- package/esm2015/src/app/shared/validator/validators.js +2 -2
- package/esm2015/src/app/social/message/message.form.js +73 -0
- package/esm2015/src/app/social/message/message.modal.js +96 -0
- package/esm2015/src/app/social/message/message.model.js +65 -0
- package/esm2015/src/app/social/message/message.service.js +87 -0
- package/esm2015/src/app/social/social.errors.js +6 -0
- package/esm2015/src/app/social/social.module.js +12 -15
- package/esm2015/src/app/social/user-event/user-event.fragments.js +27 -0
- package/esm2015/src/app/social/user-event/user-event.model.js +46 -0
- package/esm2015/src/app/social/user-event/user-event.service.js +367 -0
- package/esm2015/src/app/social/user-event/user-events.table.js +154 -0
- package/fesm2015/sumaris-net.ngx-components.js +734 -411
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +4 -3
- package/public_api.d.ts +9 -4
- package/src/app/admin/users/list/users.d.ts +10 -6
- package/src/app/core/services/local-settings.service.d.ts +3 -2
- package/src/app/core/services/model/referential.model.d.ts +7 -7
- package/src/app/shared/material/datetime/material.date.d.ts +6 -8
- package/src/app/shared/material/datetime/material.datetime.d.ts +2 -2
- package/src/app/shared/platforms.d.ts +1 -1
- package/src/app/social/message/message.form.d.ts +27 -0
- package/src/app/social/message/message.modal.d.ts +36 -0
- package/src/app/social/message/message.model.d.ts +31 -0
- package/src/app/social/message/message.service.d.ts +24 -0
- package/src/app/social/{services/errors.d.ts → social.errors.d.ts} +2 -1
- package/src/app/social/social.module.d.ts +0 -2
- package/src/app/social/{services/social.fragments.d.ts → user-event/user-event.fragments.d.ts} +1 -1
- package/src/app/social/{services/model → user-event}/user-event.model.d.ts +1 -1
- package/src/app/social/{services → user-event}/user-event.service.d.ts +4 -3
- package/src/app/social/{list → user-event}/user-events.table.d.ts +2 -2
- package/src/assets/i18n/en-US.json +23 -4
- package/src/assets/i18n/en.json +23 -4
- package/src/assets/i18n/fr.json +25 -5
- package/src/theme/_ionic.globals.scss +2 -1
- package/sumaris-net.ngx-components.metadata.json +1 -1
- package/esm2015/src/app/admin/services/errors.js +0 -6
- package/esm2015/src/app/social/list/user-events.table.js +0 -154
- package/esm2015/src/app/social/services/errors.js +0 -5
- package/esm2015/src/app/social/services/model/user-event.model.js +0 -46
- package/esm2015/src/app/social/services/social.fragments.js +0 -27
- package/esm2015/src/app/social/services/user-event.service.js +0 -367
- package/src/app/admin/services/errors.d.ts +0 -5
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
import { __awaiter, __decorate } from "tslib";
|
|
2
|
-
import { Inject, Injectable } from '@angular/core';
|
|
3
|
-
import { gql } from '@apollo/client/core';
|
|
4
|
-
import { ErrorCodes } from './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 './model/user-event.model';
|
|
9
|
-
import { SocialFragments } from './social.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 } 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: 'UserEventVO' })
|
|
54
|
-
], UserEventFilter);
|
|
55
|
-
export { UserEventFilter };
|
|
56
|
-
const SaveQuery = gql `
|
|
57
|
-
mutation SaveUserEvent($data: UserEventVOInput){
|
|
58
|
-
data: saveUserEvent(userEvent: $data){
|
|
59
|
-
...UserEventFragment
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
${SocialFragments.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
|
-
${SocialFragments.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
|
-
${SocialFragments.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.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: ErrorCodes.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: ErrorCodes.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)); }, 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: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
366
|
-
];
|
|
367
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1ldmVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zb2NpYWwvc2VydmljZXMvdXNlci1ldmVudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUMsR0FBRyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDeEMsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNwQyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDbkUsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQ2xFLE9BQU8sRUFBYSxFQUFFLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUFDLFNBQVMsRUFBbUIsY0FBYyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDcEYsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBR25ELE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuQyxPQUFPLEVBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDbkYsT0FBTyxFQUFtQixNQUFNLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUVuRSxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0MsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBQ25FLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLGdEQUFnRCxDQUFDO0FBQ2xGLE9BQU8sRUFBQyxNQUFNLEVBQUUsV0FBVyxFQUFDLE1BQU0sd0NB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RGQsY0FBYztZQWFkLGNBQWM7WUFEZCxnQkFBZ0I7WUFEaEIsZUFBZTs0Q0E2RmxCLE1BQU0sU0FBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtncWx9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2NvcmUnO1xuaW1wb3J0IHtFcnJvckNvZGVzfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQge0FjY291bnRTZXJ2aWNlfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5pbXBvcnQge0dyYXBocWxTZXJ2aWNlfSBmcm9tICcuLi8uLi9jb3JlL2dyYXBocWwvZ3JhcGhxbC5zZXJ2aWNlJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgb2Z9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtVc2VyRXZlbnQsIFVzZXJFdmVudEFjdGlvbiwgVXNlckV2ZW50VHlwZXN9IGZyb20gJy4vbW9kZWwvdXNlci1ldmVudC5tb2RlbCc7XG5pbXBvcnQge1NvY2lhbEZyYWdtZW50c30gZnJvbSAnLi9zb2NpYWwuZnJhZ21lbnRzJztcbmltcG9ydCB7U29ydERpcmVjdGlvbn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc29ydCc7XG5pbXBvcnQge0VudGl0aWVzU2VydmljZVdhdGNoT3B0aW9ucywgRW50aXR5U2VydmljZUxvYWRPcHRpb25zLCBGaWx0ZXJGbiwgSUVudGl0aWVzU2VydmljZSwgTG9hZFJlc3VsdCwgUGFnZX0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlcnZpY2VzL2VudGl0eS1zZXJ2aWNlLmNsYXNzJztcbmltcG9ydCB7bWFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2lzRW1wdHlBcnJheSwgaXNOaWwsIGlzTmlsT3JCbGFuaywgdG9OdW1iZXJ9IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtTaG93VG9hc3RPcHRpb25zLCBUb2FzdHN9IGZyb20gJy4uLy4uL3NoYXJlZC90b2FzdC90b2FzdHMnO1xuaW1wb3J0IHtPdmVybGF5RXZlbnREZXRhaWx9IGZyb20gJ0Bpb25pYy9jb3JlJztcbmltcG9ydCB7VG9hc3RDb250cm9sbGVyfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtOZXR3b3JrU2VydmljZX0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHtCYXNlR3JhcGhxbFNlcnZpY2V9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvYmFzZS1ncmFwaHFsLXNlcnZpY2UuY2xhc3MnO1xuaW1wb3J0IHtFbnRpdHksIEVudGl0eVV0aWxzfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL21vZGVsL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQge0VOVklST05NRU5UfSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQuY2xhc3MnO1xuaW1wb3J0IHtFbnRpdHlGaWx0ZXJ9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvbW9kZWwvZmlsdGVyLm1vZGVsJztcbmltcG9ydCB7RW50aXR5Q2xhc3N9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvbW9kZWwvZW50aXR5LmRlY29yYXRvcnMnO1xuXG4vLyBAZHluYW1pY1xuQEVudGl0eUNsYXNzKHt0eXBlbmFtZTogJ1VzZXJFdmVudFZPJ30pXG5leHBvcnQgY2xhc3MgVXNlckV2ZW50RmlsdGVyIGV4dGVuZHMgRW50aXR5RmlsdGVyPFVzZXJFdmVudEZpbHRlciwgVXNlckV2ZW50PiB7XG5cbiAgc3RhdGljIGZyb21PYmplY3Q6IChzb3VyY2U6IGFueSwgb3B0cz86IGFueSkgPT4gVXNlckV2ZW50RmlsdGVyO1xuXG4gIGlzc3Vlcjogc3RyaW5nID0gbnVsbDtcbiAgcmVjaXBpZW50OiBzdHJpbmcgPSBudWxsO1xuXG4gIGZyb21PYmplY3Qoc291cmNlOiBhbnksIG9wdHM/OiBhbnkpIHtcbiAgICBzdXBlci5mcm9tT2JqZWN0KHNvdXJjZSwgb3B0cyk7XG4gICAgdGhpcy5pc3N1ZXIgPSBzb3VyY2UuaXNzdWVyO1xuICAgIHRoaXMucmVjaXBpZW50ID0gc291cmNlLnJlY2lwaWVudDtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZEZpbHRlcigpOiBGaWx0ZXJGbjxVc2VyRXZlbnQ+W10ge1xuICAgIGNvbnN0IGZpbHRlckZucyA9IHN1cGVyLmJ1aWxkRmlsdGVyKCk7XG5cbiAgICAvLyBpc3N1ZXJcbiAgICBpZiAodGhpcy5pc3N1ZXIpIHtcbiAgICAgIGZpbHRlckZucy5wdXNoKHQgPT4gKHQuaXNzdWVyID09PSB0aGlzLmlzc3VlcikpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWNpcGllbnQpIHtcbiAgICAgIGZpbHRlckZucy5wdXNoKHQgPT4gKHQucmVjaXBpZW50ID09PSB0aGlzLnJlY2lwaWVudCkpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJGbnM7XG4gIH1cbn1cblxuY29uc3QgU2F2ZVF1ZXJ5OiBhbnkgPSBncWxgXG4gIG11dGF0aW9uIFNhdmVVc2VyRXZlbnQoJGRhdGE6IFVzZXJFdmVudFZPSW5wdXQpe1xuICAgIGRhdGE6IHNhdmVVc2VyRXZlbnQodXNlckV2ZW50OiAkZGF0YSl7XG4gICAgICAuLi5Vc2VyRXZlbnRGcmFnbWVudFxuICAgIH1cbiAgfVxuICAke1NvY2lhbEZyYWdtZW50cy51c2VyRXZlbnR9XG5gO1xuXG5jb25zdCBMb2FkQWxsUXVlcnk6IGFueSA9IGdxbGBcbiAgcXVlcnkgVXNlckV2ZW50cygkZmlsdGVyOiBVc2VyRXZlbnRGaWx0ZXJWT0lucHV0LCAkcGFnZTogUGFnZUlucHV0KXtcbiAgICBkYXRhOiB1c2VyRXZlbnRzKGZpbHRlcjogJGZpbHRlciwgcGFnZTogJHBhZ2Upe1xuICAgICAgLi4uTGlnaHRVc2VyRXZlbnRGcmFnbWVudFxuICAgIH1cbiAgfVxuICAke1NvY2lhbEZyYWdtZW50cy5saWdodFVzZXJFdmVudH1cbmA7XG5cbmNvbnN0IERlbGV0ZUJ5SWRzTXV0YXRpb246IGFueSA9IGdxbGBcbiAgbXV0YXRpb24gRGVsZXRlVXNlckV2ZW50cygkaWRzOltJbnRdKXtcbiAgICBkZWxldGVVc2VyRXZlbnRzKGlkczogJGlkcylcbiAgfVxuYDtcblxuY29uc3QgTG9hZEFsbFdpdGhDb250ZW50UXVlcnk6IGFueSA9IGdxbGBcbiAgcXVlcnkgVXNlckV2ZW50c1dpdGhDb250ZW50KCRmaWx0ZXI6IFVzZXJFdmVudEZpbHRlclZPSW5wdXQsICRwYWdlOiBQYWdlSW5wdXQpe1xuICAgIGRhdGE6IHVzZXJFdmVudHMoZmlsdGVyOiAkZmlsdGVyLCBwYWdlOiAkcGFnZSl7XG4gICAgICAuLi5Vc2VyRXZlbnRGcmFnbWVudFxuICAgIH1cbiAgfVxuICAke1NvY2lhbEZyYWdtZW50cy51c2VyRXZlbnR9XG5gO1xuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgVXNlckV2ZW50V2F0Y2hPcHRpb25zIGV4dGVuZHMgRW50aXRpZXNTZXJ2aWNlV2F0Y2hPcHRpb25zIHtcbiAgd2l0aENvbnRlbnQ/OiBib29sZWFuOyAvLyBEZWZhdWx0IHRvIGZhbHNlXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlckV2ZW50QWN0aW9uRGVmaW5pdGlvbiBleHRlbmRzIFVzZXJFdmVudEFjdGlvbjxhbnk+IHtcbiAgX190eXBlbmFtZTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcbmV4cG9ydCBjbGFzcyBVc2VyRXZlbnRTZXJ2aWNlXG4gIGV4dGVuZHMgQmFzZUdyYXBocWxTZXJ2aWNlPFVzZXJFdmVudCwgVXNlckV2ZW50RmlsdGVyPlxuICBpbXBsZW1lbnRzIElFbnRpdGllc1NlcnZpY2U8VXNlckV2ZW50LCBVc2VyRXZlbnRGaWx0ZXIsIFVzZXJFdmVudFdhdGNoT3B0aW9ucz4ge1xuXG4gIHByaXZhdGUgX3VzZXJFdmVudEFjdGlvbnM6IFVzZXJFdmVudEFjdGlvbkRlZmluaXRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBncmFwaHFsOiBHcmFwaHFsU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgYWNjb3VudFNlcnZpY2U6IEFjY291bnRTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBuZXR3b3JrOiBOZXR3b3JrU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCB0b2FzdENvbnRyb2xsZXI6IFRvYXN0Q29udHJvbGxlcixcbiAgICBASW5qZWN0KEVOVklST05NRU5UKSBwcm90ZWN0ZWQgZW52aXJvbm1lbnQsXG4gICkge1xuICAgIHN1cGVyKGdyYXBocWwsIGVudmlyb25tZW50KTtcblxuICAgIC8vIEZvciBERVYgb25seVxuICAgIHRoaXMuX2RlYnVnID0gIWVudmlyb25tZW50LnByb2R1Y3Rpb247XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gc2l6ZVxuICAgKiBAcGFyYW0gc29ydEJ5XG4gICAqIEBwYXJhbSBzb3J0RGlyZWN0aW9uXG4gICAqIEBwYXJhbSBmaWx0ZXJcbiAgICogQHBhcmFtIG9wdGlvbnNcbiAgICogQGRlcHJlY2F0ZWQgdXNlIHdhdGNoUGFnZSgpIGluc3RlYWRcbiAgICovXG4gIHdhdGNoQWxsKG9mZnNldDogbnVtYmVyLFxuICAgICAgICAgICBzaXplOiBudW1iZXIsXG4gICAgICAgICAgIHNvcnRCeT86IHN0cmluZyxcbiAgICAgICAgICAgc29ydERpcmVjdGlvbj86IFNvcnREaXJlY3Rpb24sXG4gICAgICAgICAgIGZpbHRlcj86IFVzZXJFdmVudEZpbHRlcixcbiAgICAgICAgICAgb3B0aW9ucz86IFVzZXJFdmVudFdhdGNoT3B0aW9ucyk6IE9ic2VydmFibGU8TG9hZFJlc3VsdDxVc2VyRXZlbnQ+PiB7XG4gICAgcmV0dXJuIHRoaXMud2F0Y2hQYWdlKDxQYWdlPntvZmZzZXQsIHNpemUsIHNvcnRCeSwgc29ydERpcmVjdGlvbn0sIGZpbHRlciwgb3B0aW9ucyk7XG4gIH1cblxuICB3YXRjaFBhZ2UocGFnZTogUGFnZSxcbiAgICAgICAgICAgIGZpbHRlcj86IFBhcnRpYWw8VXNlckV2ZW50RmlsdGVyPixcbiAgICAgICAgICAgIG9wdGlvbnM/OiBVc2VyRXZlbnRXYXRjaE9wdGlvbnMpOiBPYnNlcnZhYmxlPExvYWRSZXN1bHQ8VXNlckV2ZW50Pj4ge1xuXG4gICAgbGV0IG5vdyA9IHRoaXMuX2RlYnVnICYmIERhdGUubm93KCk7XG4gICAgLy9pZiAodGhpcy5fZGVidWcpXG4gICAgY29uc29sZS5kZWJ1ZygnW3VzZXItZXZlbnQtc2VydmljZV0gTG9hZGluZyB1c2VyIGV2ZW50cy4uLicsIGZpbHRlcik7XG5cbiAgICBmaWx0ZXIgPSB0aGlzLmFzRmlsdGVyKGZpbHRlcik7XG5cbiAgICAvLyBGb3JjZSByZWNpcGllbnQgdG8gY3VycmVudCBpc3N1ZXIsIGlmIG5vdCBhZG1pbiBhbmQgbm90IHNwZWNpZmllZFxuICAgIGlmIChpc05pbE9yQmxhbmsoZmlsdGVyLnJlY2lwaWVudCkgfHwgIXRoaXMuYWNjb3VudFNlcnZpY2UuaXNBZG1pbigpKSB7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQucHVia2V5O1xuICAgICAgaWYgKHJlY2lwaWVudCAhPT0gZmlsdGVyLnJlY2lwaWVudCkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1t1c2VyLWV2ZW50cy1zZXJ2aWNlXSBGb3JjZSB1c2VyIGV2ZW50IGZpbHRlci5yZWNpcGllbnQ9JyArIHJlY2lwaWVudCk7XG4gICAgICAgIGZpbHRlci5yZWNpcGllbnQgPSByZWNpcGllbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgd2l0aENvbnRlbnQgPSBvcHRpb25zICYmIG9wdGlvbnMud2l0aENvbnRlbnQgPT09IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcy5tdXRhYmxlV2F0Y2hRdWVyeTxMb2FkUmVzdWx0PGFueT4+KHtcbiAgICAgIHF1ZXJ5TmFtZTogd2l0aENvbnRlbnQgPyAnTG9hZEFsbFdpdGhDb250ZW50JyA6ICdMb2FkQWxsJyxcbiAgICAgIHF1ZXJ5OiB3aXRoQ29udGVudCA/IExvYWRBbGxXaXRoQ29udGVudFF1ZXJ5IDogTG9hZEFsbFF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIHBhZ2U6IHtcbiAgICAgICAgICBzb3J0Qnk6ICd1cGRhdGVEYXRlJyxcbiAgICAgICAgICAuLi5wYWdlLFxuICAgICAgICAgIHNvcnREaXJlY3Rpb246IChwYWdlLnNvcnREaXJlY3Rpb24gfHwgJ0RFU0MnKS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICB9LFxuICAgICAgICBmaWx0ZXI6IGZpbHRlciAmJiBmaWx0ZXIuYXNQb2RPYmplY3QoKVxuICAgICAgfSxcbiAgICAgIGFycmF5RmllbGROYW1lOiAnZGF0YScsXG4gICAgICBlcnJvcjoge2NvZGU6IEVycm9yQ29kZXMuTE9BRF9VU0VSX0VWRU5UU19FUlJPUiwgbWVzc2FnZTogJ1NPQ0lBTC5FUlJPUi5MT0FEX1VTRVJfRVZFTlRTX0VSUk9SJ30sXG4gICAgICBmZXRjaFBvbGljeTogb3B0aW9ucyAmJiBvcHRpb25zLmZldGNoUG9saWN5IHx8IHVuZGVmaW5lZFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKHJlcyA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IHJlcyAmJiAocmVzLmRhdGEgfHwgW10pLm1hcChVc2VyRXZlbnQuZnJvbU9iamVjdCk7XG5cbiAgICAgICAgICBpZiAobm93KSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBbdXNlci1ldmVudC1zZXJ2aWNlXSAke2RhdGEubGVuZ3RofSB1c2VyIGV2ZW50cyBsb2FkZWQgaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zYCk7XG4gICAgICAgICAgICBub3cgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHRvdGFsOiByZXMgJiYgdG9OdW1iZXIocmVzLnRvdGFsLCBkYXRhLmxlbmd0aClcbiAgICAgICAgICB9O1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgfVxuXG4gIHNhdmVBbGwoZGF0YTogVXNlckV2ZW50W10sIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPFVzZXJFdmVudFtdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGRhdGFcbiAgICAgIC5tYXAoZW50aXR5ID0+IHRoaXMuc2F2ZShlbnRpdHksIG9wdGlvbnMpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBhIHVzZXJFdmVudCBlbnRpdHlcbiAgICpcbiAgICogQHBhcmFtIGVudGl0eVxuICAgKi9cbiAgYXN5bmMgc2F2ZShlbnRpdHk6IFVzZXJFdmVudCwgb3B0aW9ucz86IEVudGl0eVNlcnZpY2VMb2FkT3B0aW9ucyk6IFByb21pc2U8VXNlckV2ZW50PiB7XG5cbiAgICB0aGlzLmZpbGxEZWZhdWx0UHJvcGVydGllcyhlbnRpdHkpO1xuXG4gICAgLy8gVHJhbnNmb3JtIGludG8ganNvblxuICAgIGNvbnN0IGlzTmV3ID0gaXNOaWwoZW50aXR5LmlkKTtcbiAgICBjb25zdCBqc29uID0gZW50aXR5LmFzT2JqZWN0KCk7XG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW3VzZXItZXZlbnQtc2VydmljZV0gU2F2aW5nIHVzZXIgZXZlbnQuLi5gLCBqc29uKTtcblxuICAgIGF3YWl0IHRoaXMuZ3JhcGhxbC5tdXRhdGU8eyBkYXRhOiBhbnkgfT4oe1xuICAgICAgbXV0YXRpb246IFNhdmVRdWVyeSxcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBkYXRhOiBqc29uXG4gICAgICB9LFxuICAgICAgZXJyb3I6IHsgY29kZTogRXJyb3JDb2Rlcy5TQVZFX1VTRVJfRVZFTlRfRVJST1IsIG1lc3NhZ2U6ICdTT0NJQUwuRVJST1IuU0FWRV9VU0VSX0VWRU5UX0VSUk9SJyB9LFxuICAgICAgdXBkYXRlOiAocHJveHksIHtkYXRhfSkgPT4ge1xuICAgICAgICAvLyBVcGRhdGUgZW50aXR5XG4gICAgICAgIGNvbnN0IHNhdmVkRW50aXR5ID0gZGF0YSAmJiBkYXRhLmRhdGE7XG4gICAgICAgIGlmIChzYXZlZEVudGl0eSkge1xuICAgICAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW3VzZXItZXZlbnQtc2VydmljZV0gVXNlciBldmVudCBzYXZlZCBpbiAke0RhdGUubm93KCkgLSBub3d9bXNgLCBlbnRpdHkpO1xuICAgICAgICAgIHRoaXMuY29weUlkQW5kVXBkYXRlRGF0ZShzYXZlZEVudGl0eSwgZW50aXR5KTtcblxuICAgICAgICAgIC8vIEFkZCB0byBjYWNoZVxuICAgICAgICAgIGlmIChpc05ldykge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRJbnRvTXV0YWJsZUNhY2hlZFF1ZXJpZXMocHJveHkse1xuICAgICAgICAgICAgICBxdWVyeTogTG9hZEFsbFF1ZXJ5LFxuICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgLi4uc2F2ZWRFbnRpdHksXG4gICAgICAgICAgICAgICAgY29udGVudDogbnVsbFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0SW50b011dGFibGVDYWNoZWRRdWVyaWVzKHByb3h5LHtcbiAgICAgICAgICAgICAgcXVlcnk6IExvYWRBbGxXaXRoQ29udGVudFF1ZXJ5LFxuICAgICAgICAgICAgICBkYXRhOiBzYXZlZEVudGl0eVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZW50aXR5O1xuICB9XG5cblxuXG4gIC8qKlxuICAgKiBTYXZlIG1hbnkgdHJpcHNcbiAgICpcbiAgICogQHBhcmFtIGVudGl0aWVzXG4gICAqIEBwYXJhbSBvcHRzXG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoZW50aXRpZXM6IFVzZXJFdmVudFtdLCBvcHRzPzoge1xuICAgIHRyYXNoPzogYm9vbGVhbjsgLy8gVHJ1ZSBieSBkZWZhdWx0XG4gIH0pOiBQcm9taXNlPGFueT4ge1xuXG4gICAgY29uc3QgaWRzID0gZW50aXRpZXMgJiYgZW50aXRpZXNcbiAgICAgIC5tYXAodCA9PiB0LmlkKTtcbiAgICBpZiAoaXNFbXB0eUFycmF5KGlkcykpIHJldHVybjsgLy8gc3RvcCwgaWYgbm90aGluZyBlbHNlIHRvIGRvXG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZygnW3VzZXItZXZlbnQtc2VydmljZV0gRGVsZXRpbmcgZXZlbnRzLi4uIGlkczonLCBpZHMpO1xuXG4gICAgYXdhaXQgdGhpcy5ncmFwaHFsLm11dGF0ZTxhbnk+KHtcbiAgICAgIG11dGF0aW9uOiBEZWxldGVCeUlkc011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlkc1xuICAgICAgfSxcbiAgICAgIHVwZGF0ZTogKHByb3h5KSA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIGNhY2hlc1xuICAgICAgICB0aGlzLnJlbW92ZUZyb21NdXRhYmxlQ2FjaGVkUXVlcmllc0J5SWRzKHByb3h5LCB7XG4gICAgICAgICAgcXVlcnk6IExvYWRBbGxRdWVyeSxcbiAgICAgICAgICBpZHNcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVtb3ZlRnJvbU11dGFibGVDYWNoZWRRdWVyaWVzQnlJZHMocHJveHksIHtcbiAgICAgICAgICBxdWVyeTogTG9hZEFsbFdpdGhDb250ZW50UXVlcnksXG4gICAgICAgICAgaWRzXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLl9kZWJ1ZykgY29uc29sZS5kZWJ1ZyhgW3VzZXItZXZlbnQtc2VydmljZV0gRXZlbnRzIGRlbGV0ZWQgaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zYCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHVzZXJFdmVudCBlbnRpdGllc1xuICAgKi9cbiAgYXN5bmMgZGVsZXRlKGRhdGE6IFVzZXJFdmVudCk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm47IC8vIHNraXBcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZUFsbChbZGF0YV0pO1xuICB9XG5cbiAgbGlzdGVuQ2hhbmdlcyhpZDogbnVtYmVyLCBvcHRpb25zPzogYW55KTogT2JzZXJ2YWJsZTxVc2VyRXZlbnQgfCB1bmRlZmluZWQ+IHtcbiAgICAvLyBUT0RPXG4gICAgY29uc29sZS53YXJuKCdUT0RPOiBpbXBsZW1lbnQgbGlzdGVuIGNoYW5nZXMgb24gdXNlciBldmVudHMnKTtcbiAgICByZXR1cm4gb2YoKTtcbiAgfVxuXG4gIHJlZ2lzdGVyQWN0aW9uKGRlZmluaXRpb246IFVzZXJFdmVudEFjdGlvbkRlZmluaXRpb24pIHtcbiAgICBjb25zb2xlLmluZm8oYFt1c2VyLWV2ZW50LXNlcnZpY2VdIFJlZ2lzdGVyaW5nIGFjdGlvbiAke2RlZmluaXRpb24ubmFtZX0gZm9yICR7ZGVmaW5pdGlvbi5fX3R5cGVuYW1lfWApO1xuICAgIHRoaXMuX3VzZXJFdmVudEFjdGlvbnMucHVzaChkZWZpbml0aW9uKTtcbiAgfVxuXG4gIGdldEFjdGlvbnNCeVR5cGVuYW1lKHR5cGVuYW1lOiBzdHJpbmcpOiBVc2VyRXZlbnRBY3Rpb248YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fdXNlckV2ZW50QWN0aW9ucy5maWx0ZXIoZGVmID0+IGRlZi5fX3R5cGVuYW1lID09PSB0eXBlbmFtZSk7XG4gIH1cblxuICBhc3luYyBzaG93VG9hc3RFcnJvcldpdGhDb250ZXh0KG9wdHM6IHtcbiAgICBlcnJvcj86IGFueTtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIGNvbnRleHQ6IGFueSB8ICgoKSA9PiBhbnkpIHwgUHJvbWlzZTxhbnk+O30pIHtcblxuICAgIGxldCBtZXNzYWdlID0gb3B0cy5tZXNzYWdlIHx8IChvcHRzLmVycm9yICYmIG9wdHMuZXJyb3IubWVzc2FnZSB8fCBvcHRzLmVycm9yKTtcblxuICAgIC8vIE1ha2Ugc3VyZSBtZXNzYWdlIGEgc3RyaW5nXG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgbWVzc2FnZSA9ICdFUlJPUi5VTktOT1dOX1RFQ0hOSUNBTF9FUlJPUic7XG4gICAgfVxuXG4gICAgLy8gSWYgb2ZmbGluZSwgZGlzcGxheSBhIHNpbXBsZSBhbGVydFxuICAgIGlmICh0aGlzLm5ldHdvcmsub2ZmbGluZSkge1xuICAgICAgdGhpcy5zaG93VG9hc3Qoe21lc3NhZ2UsIHR5cGU6ICdlcnJvcid9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2xhdGUgdGhlIG1lc3NhZ2UgKHRvIGJlIGFibGUgdG8gZXh0cmFjdCBkZXRhaWxzIGNvbnRlbnQpXG4gICAgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlLmluc3RhbnQobWVzc2FnZSk7XG5cbiAgICAvLyBDbGVhbiBkZXRhaWxzIHBhcnRzXG4gICAgaWYgKG1lc3NhZ2UgJiYgbWVzc2FnZS5pbmRleE9mKCc8c21hbGw+JykgIT09IC0xKSB7XG4gICAgICBtZXNzYWdlID0gbWVzc2FnZS5zdWJzdHIoMCwgbWVzc2FnZS5pbmRleE9mKCc8c21hbGw+JykgLSAxKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnNob3dUb2FzdCh7XG4gICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgZHVyYXRpb246IDE1MDAwLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZSArICc8YnIvPjxici8+PGI+JyArIHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ0NPTkZJUk0uU0VORF9ERUJVR19EQVRBJykgKyAnPC9iPicsXG4gICAgICBidXR0b25zOiBbe1xuICAgICAgICBpY29uOiAnYnVnJyxcbiAgICAgICAgdGV4dDogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnQ09NTU9OLkJUTl9TRU5EJyksXG4gICAgICAgIHJvbGU6ICdzZW5kJ1xuICAgICAgfV1cbiAgICB9KTtcbiAgICBpZiAoIXJlcyB8fCByZXMucm9sZSAhPT0gJ3NlbmQnKSByZXR1cm47XG5cbiAgICAvLyBTZW5kIGRlYnVnIGRhdGFcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuX2RlYnVnKSBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIGRlYnVnIGRhdGEuLi4nKTtcblxuICAgICAgLy8gQ2FsbCBjb250ZW50IGZhY3RvcnlcbiAgICAgIGxldCBjb250ZXh0OiBhbnkgPSBvcHRzICYmIG9wdHMuY29udGV4dDtcbiAgICAgIGlmICh0eXBlb2YgY29udGV4dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb250ZXh0ID0gY29udGV4dCgpO1xuICAgICAgfVxuICAgICAgaWYgKGNvbnRleHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIGNvbnRleHQgPSBhd2FpdCBjb250ZXh0O1xuICAgICAgfVxuXG4gICAgICAvLyBTZW5kIHRoZSBtZXNzYWdlXG4gICAgICBjb25zdCB1c2VyRXZlbnQgPSBhd2FpdCB0aGlzLnNlbmREYXRhRm9yRGVidWcoe1xuICAgICAgICBtZXNzYWdlLFxuICAgICAgICBlcnJvcjogb3B0cy5lcnJvciB8fCB1bmRlZmluZWQsXG4gICAgICAgIGNvbnRleHQ6IHRoaXMuY29udmVydE9iamVjdFRvU3RyaW5nKGNvbnRleHQpXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5pbmZvKCdEZWJ1ZyBkYXRhIHN1Y2Nlc3NmdWxseSBzZW50IHRvIGFkbWluJywgdXNlckV2ZW50KTtcbiAgICAgIHRoaXMuc2hvd1RvYXN0KHtcbiAgICAgICAgdHlwZTogJ2luZm8nLFxuICAgICAgICBtZXNzYWdlOiAnSU5GTy5ERUJVR19EQVRBX1NFTkQnLFxuICAgICAgICBzaG93Q2xvc2VCdXR0b246IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciB3aGlsZSBzZW5kaW5nIGRlYnVnIGRhdGE6JywgZXJyKTtcbiAgICB9XG4gIH1cblxuICBzZW5kRGF0YUZvckRlYnVnKGRhdGE6IGFueSk6IFByb21pc2U8VXNlckV2ZW50PiB7XG4gICAgY29uc3QgdXNlckV2ZW50ID0gbmV3IFVzZXJFdmVudCgpO1xuICAgIHVzZXJFdmVudC5ldmVudFR5cGUgPSBVc2VyRXZlbnRUeXBlcy5ERUJVR19EQVRBO1xuICAgIHVzZXJFdmVudC5jb250ZW50ID0gdGhpcy5jb252ZXJ0T2JqZWN0VG9TdHJpbmcoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuc2F2ZSh1c2VyRXZlbnQpO1xuICB9XG5cbiAgYXNGaWx0ZXIoZmlsdGVyOiBQYXJ0aWFsPFVzZXJFdmVudEZpbHRlcj4pOiBVc2VyRXZlbnRGaWx0ZXIge1xuICAgIHJldHVybiBVc2VyRXZlbnRGaWx0ZXIuZnJvbU9iamVjdChmaWx0ZXIpO1xuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIG1ldGhvZHMgLS0gKi9cblxuICBwcm90ZWN0ZWQgY29udmVydE9iamVjdFRvU3RyaW5nKGRhdGE6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJyl7XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLy8gU2VyaWFsaXplIGNvbnRlbnQgaW50byBzdHJpbmdcbiAgICBlbHNlIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpe1xuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBFbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEuYXNPYmplY3Qoe2tlZXBUeXBlbmFtZTogdHJ1ZSwga2VlcExvY2FsSWQ6IHRydWUsIG1pbmlmeTogZmFsc2V9KSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzaG93VG9hc3Q8VD1hbnk+KG9wdHM6IFNob3dUb2FzdE9wdGlvbnMpOiBQcm9taXNlPE92ZXJsYXlFdmVudERldGFpbDxUPj4ge1xuICAgIGlmICghdGhpcy50b2FzdENvbnRyb2xsZXIpIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0b2FzdENvbnRyb2xsZXIgaW4gY29tcG9uZW50XFwncyBjb25zdHJ1Y3RvcicpO1xuICAgIHJldHVybiBhd2FpdCBUb2FzdHMuc2hvdyh0aGlzLnRvYXN0Q29udHJvbGxlciwgdGhpcy50cmFuc2xhdGUsIG9wdHMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGZpbGxEZWZhdWx0UHJvcGVydGllcyhlbnRpdHk6IFVzZXJFdmVudCkge1xuICAgIGVudGl0eS5pc3N1ZXIgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQucHVia2V5O1xuXG4gICAgLy8gVE9ETzogY29tcHV0ZSBoYXNoICh1c2luZyBjcnlwdG9TZXJ2aWNlKVxuICAgIC8vIFRPRE86IGNvbXB1dGUgc2lnblxuICAgIGNvbnNvbGUud2FybignVE9ETzogc2lnbiB1c2VyIGV2ZW50IGJlZm9yZSBzZW5kaW5nJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29weUlkQW5kVXBkYXRlRGF0ZShzb3VyY2U6IFVzZXJFdmVudCwgdGFyZ2V0OiBVc2VyRXZlbnQpIHtcbiAgICBFbnRpdHlVdGlscy5jb3B5SWRBbmRVcGRhdGVEYXRlKHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxufVxuIl19
|