@ieeesa-npm/dashboard 0.0.3 → 0.0.4

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 (31) hide show
  1. package/esm2022/lib/assets/constants.json +7 -3
  2. package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +103 -13
  3. package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +101 -23
  4. package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +70 -6
  5. package/esm2022/lib/dashboard.component.mjs +93 -9
  6. package/esm2022/lib/models/attendance-state.model.mjs +8 -1
  7. package/esm2022/lib/models/dashboard-route-config.model.mjs +1 -1
  8. package/esm2022/lib/models/event-meeting-list-item.model.mjs +1 -1
  9. package/esm2022/lib/models/event-meeting-list-payload.model.mjs +7 -5
  10. package/esm2022/lib/models/meeting-row.model.mjs +1 -1
  11. package/esm2022/lib/models/upcoming-event.model.mjs +1 -1
  12. package/esm2022/lib/services/dashboard.service.mjs +71 -126
  13. package/esm2022/lib/services/user-permissions.service.mjs +23 -9
  14. package/esm2022/lib/utils/event-meeting-mapper.util.mjs +47 -41
  15. package/fesm2022/ieeesa-npm-dashboard.mjs +526 -284
  16. package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -1
  17. package/lib/components/event-group-card/event-group-card.component.d.ts +75 -6
  18. package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +61 -7
  19. package/lib/components/member-level-badge/member-level-badge.component.d.ts +12 -1
  20. package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +51 -3
  21. package/lib/dashboard.component.d.ts +53 -3
  22. package/lib/models/attendance-state.model.d.ts +8 -1
  23. package/lib/models/dashboard-route-config.model.d.ts +14 -0
  24. package/lib/models/event-meeting-list-item.model.d.ts +68 -68
  25. package/lib/models/event-meeting-list-payload.model.d.ts +14 -25
  26. package/lib/models/meeting-row.model.d.ts +2 -0
  27. package/lib/models/upcoming-event.model.d.ts +9 -0
  28. package/lib/services/dashboard.service.d.ts +25 -53
  29. package/lib/services/user-permissions.service.d.ts +8 -4
  30. package/lib/utils/event-meeting-mapper.util.d.ts +15 -21
  31. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { BehaviorSubject, catchError, map, of, } from 'rxjs';
2
+ import { BehaviorSubject, catchError, map, } from 'rxjs';
3
3
  import { AttendanceState } from '../models/attendance-state.model';
4
4
  import { DashboardSectionState } from '../models/dashboard-section-state.model';
5
5
  import { UpcomingItemKind, } from '../models/upcoming-event.model';
@@ -11,18 +11,10 @@ import * as i1 from "@ieeesa-npm/utility";
11
11
  const UNASSIGNED_LABEL = 'Unassigned';
12
12
  /** Placeholder for an empty cell value. */
13
13
  const EMPTY_VALUE = '-';
14
- /** Statuses included in the upcoming section, matching the view-events-meetings-list screen. */
15
- const UPCOMING_STATUSES = ['In Progress', 'Upcoming'];
16
- /** Sort column used for the top-level events & meetings list. */
17
- const UPCOMING_SORT_COLUMN = 'startDateTime';
18
- /** Sort column used for an event's expanded child-meeting list (meetingsDetails). */
19
- const EVENT_MEETINGS_SORT_COLUMN = 'meetingStDate';
20
- /** Default page size for the top-level upcoming section list. */
14
+ /** Default page size for the top-level home events-&-meetings list. */
21
15
  const UPCOMING_PAGE_SIZE = 10;
22
- /** Default page size for an event's expanded child-meeting list. */
16
+ /** Default page size for an event's drill-down child-meeting list. */
23
17
  const EVENT_MEETINGS_PAGE_SIZE = 5;
24
- /** Large page size used by the eager count prefetch to capture the full set. */
25
- const EVENT_COUNT_PAGE_SIZE = 200;
26
18
  /**
27
19
  * DashboardService is the single source of truth for the dashboard landing
28
20
  * page's data and attendance state. It mirrors the `events-and-meetings`
@@ -80,33 +72,30 @@ export class DashboardService {
80
72
  this.userPermissions = userPermissions;
81
73
  }
82
74
  /**
83
- * Loads the user's upcoming events & meetings from the real backend via
84
- * `POST {apiBaseUrl}/meetings/eventsAndMeetings`, the same endpoint the
85
- * `view-events-meetings-list` screen uses. The response is mapped into the
86
- * dashboard view models (with STANDALONE_MEETING rows ordered last), the
87
- * per-meeting attendance-state map is seeded, and the section advances through
88
- * LOADING → LOADED/EMPTY on success, leaving the caller to set ERROR on
89
- * failure. Follows the shared `pipe(map, catchError(throw))` pattern.
90
- * @return {Observable<EventMeetingListResponse>} The upcoming events & meetings response envelope.
75
+ * Loads the user's combined upcoming events & standalone meetings from the
76
+ * backend via `POST {apiBaseUrl}/meetings/home/eventsAndMeetings`. The response
77
+ * (which carries per-event `totalMeetingCount` / `meetingsOpenForAttendanceCount`
78
+ * and per-standalone `attendanceState` directly) is mapped into the dashboard
79
+ * view models (STANDALONE_MEETING rows ordered last), the per-meeting
80
+ * attendance-state map is seeded, and the section advances through
81
+ * LOADING → LOADED/EMPTY on success. `appId` is taken from the JWT, so it is
82
+ * not sent. Follows the shared `pipe(map, catchError(throw))` pattern.
83
+ * @return {Observable<EventMeetingListResponse>} The home events-&-meetings response envelope.
91
84
  * @memberof DashboardService
92
85
  */
93
86
  loadUpcomingEvents() {
94
87
  this.upcomingState.next(DashboardSectionState.LOADING);
95
88
  const payload = {
96
89
  payload: {
97
- eventId: null,
98
- sortColumn: UPCOMING_SORT_COLUMN,
99
- ascendingOrder: true,
100
90
  page: 1,
101
91
  size: UPCOMING_PAGE_SIZE,
102
- filter: {
103
- status: UPCOMING_STATUSES,
104
- isAllMeetingSelected: false,
105
- },
92
+ sortColumn: 'startDateTime',
93
+ ascendingOrder: true,
94
+ searchTerm: null,
106
95
  },
107
96
  };
108
97
  return this.httpService
109
- .postData(`${this.apiBaseUrl}/meetings/eventsAndMeetings`, payload)
98
+ .postData(`${this.apiBaseUrl}/meetings/home/eventsAndMeetings`, payload)
110
99
  .pipe(map((response) => {
111
100
  const events = mapEventMeetingList(response?.body?.eventMeetingList ?? []);
112
101
  this.upcomingEvents.next(events);
@@ -114,9 +103,6 @@ export class DashboardService {
114
103
  this.upcomingState.next(events.length > 0
115
104
  ? DashboardSectionState.LOADED
116
105
  : DashboardSectionState.EMPTY);
117
- // Eagerly fetch each EVENT's meeting count so the "{n} meetings" and
118
- // "{n} open for attendance" summaries are correct before expanding.
119
- this.loadEventCounts(events);
120
106
  return response;
121
107
  }), catchError((error) => {
122
108
  this.upcomingState.next(DashboardSectionState.ERROR);
@@ -124,28 +110,29 @@ export class DashboardService {
124
110
  }));
125
111
  }
126
112
  /**
127
- * Lazily loads (and paginates) the child meetings of an EVENT row via
128
- * `POST {apiBaseUrl}/meetings/meetingsDetails` — the per-event expand endpoint
129
- * used by the reference screen. On success the loaded meetings are mapped and
130
- * merged onto the matching event in the `upcomingEvents` list (with its
131
- * `meetingCount` / `openForAttendanceCount` refreshed), and the per-meeting
132
- * attendance-state map is extended. Each event paginates independently.
113
+ * Lazily loads (and paginates) the child meetings of an EVENT via
114
+ * `POST {apiBaseUrl}/meetings/home/events/{eventId}/meetings` (the drill-down
115
+ * endpoint). The `eventId` is sent in the URL path; only `page` / `size` are
116
+ * used in the body. On success the drill-down body (day indicator, counts,
117
+ * paginator total, and the paged meetings) is merged onto the matching event,
118
+ * and the per-meeting attendance-state map is extended. Each event paginates
119
+ * independently.
133
120
  * @param {string} eventId - The event whose meetings to load.
134
121
  * @param {number} [page=1] - The one-based page to request.
135
122
  * @param {number} [size=EVENT_MEETINGS_PAGE_SIZE] - The page size.
136
- * @return {Observable<EventMeetingDetailResponse>} The child-meetings response envelope.
123
+ * @return {Observable<EventMeetingDetailResponse>} The drill-down response envelope.
137
124
  * @memberof DashboardService
138
125
  */
139
126
  loadEventMeetings(eventId, page = 1, size = EVENT_MEETINGS_PAGE_SIZE) {
140
- return this.fetchEventMeetingsPage(eventId, page, size).pipe(map((response) => {
141
- const meetings = mapEventMeetingDetails(response?.body?.meetings ?? []);
142
- const total = response?.body?.totalRecords ?? meetings.length;
143
- // Prefer the already-known full open count on the event; fall back to
144
- // the current page's open count when it hasn't been prefetched.
145
- const existing = this.upcomingEvents.value.find((event) => event.eventId === eventId);
146
- const pageOpenCount = meetings.filter((meeting) => meeting.isOpenForAttendance).length;
147
- const openForAttendanceCount = existing?.openForAttendanceCount || pageOpenCount;
148
- this.mergeEventMeetings(eventId, meetings, total, openForAttendanceCount);
127
+ const payload = {
128
+ payload: { page, size },
129
+ };
130
+ return this.httpService
131
+ .postData(`${this.apiBaseUrl}/meetings/home/events/${encodeURIComponent(eventId)}/meetings`, payload)
132
+ .pipe(map((response) => {
133
+ const body = response?.body;
134
+ const meetings = mapEventMeetingDetails(body?.meetings ?? [], eventId);
135
+ this.mergeEventMeetings(eventId, meetings, body);
149
136
  this.seedAttendanceStatesFromMeetings(meetings);
150
137
  return response;
151
138
  }), catchError((error) => {
@@ -153,17 +140,25 @@ export class DashboardService {
153
140
  }));
154
141
  }
155
142
  /**
156
- * Merges a freshly loaded page of child meetings onto the matching event in
157
- * the `upcomingEvents` list, refreshing the event's `meetings`,
158
- * `meetingCount` (from the backend `totalRecords`), and
159
- * `openForAttendanceCount`. Leaves all other events untouched.
143
+ * Merges a freshly loaded drill-down page onto the matching event in the
144
+ * `upcomingEvents` list: the paged `meetings`, the paginator total
145
+ * (`totalRecords` = the user's tied upcoming meetings), the event's full
146
+ * `totalMeetingCount` / `meetingsOpenForAttendanceCount`, and the
147
+ * "Day X of Y" indicator derived from `currentDay` / `totalDays`. Leaves all
148
+ * other events untouched.
160
149
  * @param {string} eventId - The event to merge meetings onto.
161
- * @param {MeetingRow[]} meetings - The mapped child meetings for the page.
162
- * @param {number} totalRecords - The event's total meeting count from the backend.
150
+ * @param {MeetingRow[]} meetings - The mapped drill-down meetings for the page.
151
+ * @param {EventMeetingDetailBody | undefined} body - The drill-down response body.
163
152
  * @return {void}
164
153
  * @memberof DashboardService
165
154
  */
166
- mergeEventMeetings(eventId, meetings, totalRecords, openForAttendanceCount) {
155
+ mergeEventMeetings(eventId, meetings, body) {
156
+ const totalRecords = body?.totalRecords ?? meetings.length;
157
+ const totalMeetingCount = body?.totalMeetingCount ?? totalRecords;
158
+ const openForAttendanceCount = body?.meetingsOpenForAttendanceCount ?? 0;
159
+ const currentDay = body?.currentDay;
160
+ const totalDays = body?.totalDays;
161
+ const dayIndicator = currentDay && totalDays ? `Day ${currentDay} of ${totalDays}` : '';
167
162
  const next = this.upcomingEvents.value.map((event) => {
168
163
  if (event.eventId !== eventId) {
169
164
  return event;
@@ -171,81 +166,15 @@ export class DashboardService {
171
166
  return {
172
167
  ...event,
173
168
  meetings,
174
- meetingCount: totalRecords,
169
+ // Paginator length = count of the user's tied upcoming meetings.
170
+ meetingPageTotal: totalRecords,
171
+ meetingCount: totalMeetingCount,
175
172
  openForAttendanceCount,
173
+ dayIndicator: dayIndicator || event.dayIndicator,
176
174
  };
177
175
  });
178
176
  this.upcomingEvents.next(next);
179
177
  }
180
- /**
181
- * Eagerly fetches each EVENT's total meeting count and open-for-attendance
182
- * count by requesting a large first page of its child meetings, then merging
183
- * only the counts (not the rows) so the collapsed card summaries are accurate
184
- * before the user expands. Standalone meetings are skipped. Failures per event
185
- * are swallowed so one failing count never breaks the list.
186
- * @param {UpcomingEvent[]} events - The loaded events to fetch counts for.
187
- * @return {void}
188
- * @memberof DashboardService
189
- */
190
- loadEventCounts(events) {
191
- events
192
- .filter((event) => event.kind === UpcomingItemKind.EVENT && event.eventId)
193
- .forEach((event) => {
194
- this.fetchEventMeetingsPage(event.eventId, 1, EVENT_COUNT_PAGE_SIZE)
195
- .pipe(catchError(() => of(null)))
196
- .subscribe((response) => {
197
- if (!response) {
198
- return;
199
- }
200
- const meetings = mapEventMeetingDetails(response?.body?.meetings ?? []);
201
- const total = response?.body?.totalRecords ?? meetings.length;
202
- const openCount = meetings.filter((meeting) => meeting.isOpenForAttendance).length;
203
- this.mergeEventCounts(event.eventId, total, openCount);
204
- this.seedAttendanceStatesFromMeetings(meetings);
205
- });
206
- });
207
- }
208
- /**
209
- * Merges only the meeting counts onto the matching event, leaving its
210
- * `meetings` rows untouched (used by the eager count prefetch).
211
- * @param {string} eventId - The event to update.
212
- * @param {number} totalRecords - The event's total meeting count.
213
- * @param {number} openForAttendanceCount - The open-for-attendance count.
214
- * @return {void}
215
- * @memberof DashboardService
216
- */
217
- mergeEventCounts(eventId, totalRecords, openForAttendanceCount) {
218
- const next = this.upcomingEvents.value.map((event) => event.eventId === eventId
219
- ? { ...event, meetingCount: totalRecords, openForAttendanceCount }
220
- : event);
221
- this.upcomingEvents.next(next);
222
- }
223
- /**
224
- * Builds and posts the `meetingsDetails` request for a single event page,
225
- * returning the raw response envelope. Shared by {@link loadEventMeetings} and
226
- * the eager count prefetch.
227
- * @param {string} eventId - The event whose meetings to fetch.
228
- * @param {number} page - The one-based page to request.
229
- * @param {number} size - The page size.
230
- * @return {Observable<EventMeetingDetailResponse>} The child-meetings response.
231
- * @memberof DashboardService
232
- */
233
- fetchEventMeetingsPage(eventId, page, size) {
234
- const payload = {
235
- payload: {
236
- eventId,
237
- sortColumn: EVENT_MEETINGS_SORT_COLUMN,
238
- ascendingOrder: true,
239
- page,
240
- size,
241
- filter: {
242
- status: UPCOMING_STATUSES,
243
- isAllMeetingSelected: false,
244
- },
245
- },
246
- };
247
- return this.httpService.postData(`${this.apiBaseUrl}/meetings/meetingsDetails`, payload);
248
- }
249
178
  /**
250
179
  * Loads the user's groups, driving the groups section through
251
180
  * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
@@ -364,8 +293,24 @@ export class DashboardService {
364
293
  * @memberof DashboardService
365
294
  */
366
295
  seedAttendanceStates(events) {
367
- const meetings = events.flatMap((event) => event.meetings ?? []);
368
- this.seedAttendanceStatesFromMeetings(meetings);
296
+ const next = {
297
+ ...this.attendanceStates.value,
298
+ };
299
+ events.forEach((event) => {
300
+ // Standalone meetings carry their own attendance state keyed by their id
301
+ // (eventId == meetingId for standalone rows).
302
+ if (event.kind === UpcomingItemKind.STANDALONE_MEETING && event.eventId) {
303
+ next[event.eventId] =
304
+ event.attendanceState ?? AttendanceState.NOT_ATTENDING;
305
+ }
306
+ (event.meetings ?? []).forEach((meeting) => {
307
+ if (meeting.meetingId) {
308
+ next[meeting.meetingId] =
309
+ meeting.attendanceState ?? AttendanceState.NOT_ATTENDING;
310
+ }
311
+ });
312
+ });
313
+ this.attendanceStates.next(next);
369
314
  }
370
315
  /**
371
316
  * Seeds the attendance-state map from a list of meeting rows, using each
@@ -399,4 +344,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
399
344
  providedIn: 'root',
400
345
  }]
401
346
  }], ctorParameters: function () { return [{ type: i1.HttpService }]; } });
402
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsRUFDSCxFQUFFLEdBQ0gsTUFBTSxNQUFNLENBQUM7QUFHZCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFNaEYsT0FBTyxFQUVMLGdCQUFnQixHQUNqQixNQUFNLGdDQUFnQyxDQUFDO0FBU3hDLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsbUJBQW1CLEdBQ3BCLE1BQU0sb0NBQW9DLENBQUM7QUFtQjVDLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQixtQkFBbUIsR0FDcEIsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBckIvQix5RkFBeUY7QUFDekYsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFDdEMsMkNBQTJDO0FBQzNDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4QixnR0FBZ0c7QUFDaEcsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUN0RCxpRUFBaUU7QUFDakUsTUFBTSxvQkFBb0IsR0FBRyxlQUFlLENBQUM7QUFDN0MscUZBQXFGO0FBQ3JGLE1BQU0sMEJBQTBCLEdBQUcsZUFBZSxDQUFDO0FBQ25ELGlFQUFpRTtBQUNqRSxNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQUM5QixvRUFBb0U7QUFDcEUsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLENBQUM7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LENBQUMsS0FBSztTQUMvQixDQUFDO1FBQ0YsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzNCLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRTtnQkFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7b0JBQ3JCLE9BQU8sQ0FBQyxlQUFlO3dCQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQzt3QkFDdkIsZUFBZSxDQUFDLGFBQWEsQ0FBQzthQUNqQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQTFjVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbiAgb2YsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIE15R3JvdXBzVmlldyxcclxuICBNeUdyb3VwVmlldyxcclxufSBmcm9tICcuLi9tb2RlbHMvbXktZ3JvdXBzLXZpZXcubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIFVwY29taW5nRXZlbnQsXHJcbiAgVXBjb21pbmdJdGVtS2luZCxcclxufSBmcm9tICcuLi9tb2RlbHMvdXBjb21pbmctZXZlbnQubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIEV2ZW50TWVldGluZ0RldGFpbFBheWxvYWQsXHJcbiAgRXZlbnRNZWV0aW5nTGlzdFBheWxvYWQsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1wYXlsb2FkLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBFdmVudE1lZXRpbmdEZXRhaWxSZXNwb25zZSxcclxuICBFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2UsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1pdGVtLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBtYXBFdmVudE1lZXRpbmdEZXRhaWxzLFxyXG4gIG1hcEV2ZW50TWVldGluZ0xpc3QsXHJcbn0gZnJvbSAnLi4vdXRpbHMvZXZlbnQtbWVldGluZy1tYXBwZXIudXRpbCc7XHJcbmltcG9ydCB7IE1lZXRpbmdSb3cgfSBmcm9tICcuLi9tb2RlbHMvbWVldGluZy1yb3cubW9kZWwnO1xyXG5cclxuLyoqIEZhbGxiYWNrIGxhYmVsIGZvciBhbiBlbXB0eSBncm91cCB0eXBlIC8gbWVtYmVyIGxldmVsLCBtYXRjaGluZyB0aGUgTXkgR3JvdXBzIHRhYi4gKi9cclxuY29uc3QgVU5BU1NJR05FRF9MQUJFTCA9ICdVbmFzc2lnbmVkJztcclxuLyoqIFBsYWNlaG9sZGVyIGZvciBhbiBlbXB0eSBjZWxsIHZhbHVlLiAqL1xyXG5jb25zdCBFTVBUWV9WQUxVRSA9ICctJztcclxuLyoqIFN0YXR1c2VzIGluY2x1ZGVkIGluIHRoZSB1cGNvbWluZyBzZWN0aW9uLCBtYXRjaGluZyB0aGUgdmlldy1ldmVudHMtbWVldGluZ3MtbGlzdCBzY3JlZW4uICovXHJcbmNvbnN0IFVQQ09NSU5HX1NUQVRVU0VTID0gWydJbiBQcm9ncmVzcycsICdVcGNvbWluZyddO1xyXG4vKiogU29ydCBjb2x1bW4gdXNlZCBmb3IgdGhlIHRvcC1sZXZlbCBldmVudHMgJiBtZWV0aW5ncyBsaXN0LiAqL1xyXG5jb25zdCBVUENPTUlOR19TT1JUX0NPTFVNTiA9ICdzdGFydERhdGVUaW1lJztcclxuLyoqIFNvcnQgY29sdW1uIHVzZWQgZm9yIGFuIGV2ZW50J3MgZXhwYW5kZWQgY2hpbGQtbWVldGluZyBsaXN0IChtZWV0aW5nc0RldGFpbHMpLiAqL1xyXG5jb25zdCBFVkVOVF9NRUVUSU5HU19TT1JUX0NPTFVNTiA9ICdtZWV0aW5nU3REYXRlJztcclxuLyoqIERlZmF1bHQgcGFnZSBzaXplIGZvciB0aGUgdG9wLWxldmVsIHVwY29taW5nIHNlY3Rpb24gbGlzdC4gKi9cclxuY29uc3QgVVBDT01JTkdfUEFHRV9TSVpFID0gMTA7XHJcbi8qKiBEZWZhdWx0IHBhZ2Ugc2l6ZSBmb3IgYW4gZXZlbnQncyBleHBhbmRlZCBjaGlsZC1tZWV0aW5nIGxpc3QuICovXHJcbmNvbnN0IEVWRU5UX01FRVRJTkdTX1BBR0VfU0laRSA9IDU7XHJcbi8qKiBMYXJnZSBwYWdlIHNpemUgdXNlZCBieSB0aGUgZWFnZXIgY291bnQgcHJlZmV0Y2ggdG8gY2FwdHVyZSB0aGUgZnVsbCBzZXQuICovXHJcbmNvbnN0IEVWRU5UX0NPVU5UX1BBR0VfU0laRSA9IDIwMDtcclxuaW1wb3J0IHtcclxuICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3MsXHJcbiAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2VzcyxcclxuICBiZWdpbkF0dGVuZGFuY2VBY3Rpb24sXHJcbiAgZW5kQXR0ZW5kYW5jZUFjdGlvbixcclxufSBmcm9tICcuL2F0dGVuZGFuY2UtcmVkdWNlcnMnO1xyXG5cclxuLyoqXHJcbiAqIERhc2hib2FyZFNlcnZpY2UgaXMgdGhlIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIHRoZSBkYXNoYm9hcmQgbGFuZGluZ1xyXG4gKiBwYWdlJ3MgZGF0YSBhbmQgYXR0ZW5kYW5jZSBzdGF0ZS4gSXQgbWlycm9ycyB0aGUgYGV2ZW50cy1hbmQtbWVldGluZ3NgXHJcbiAqIHNlcnZpY2UgY29udmVudGlvbnM6IGl0IGlzIGEgYHByb3ZpZGVkSW46ICdyb290J2Agc2luZ2xldG9uLCBob2xkcyB0aGUgaG9zdFxyXG4gKiBgYXBpQmFzZVVybGAgLyBgdXNlclBlcm1pc3Npb25zYCBzZXQgdmlhIHtAbGluayBzZXRBcHBDb25maWd9LCBvd25zIGl0cyBzdGF0ZVxyXG4gKiB2aWEgYEJlaGF2aW9yU3ViamVjdGBzIGV4cG9zZWQgYXMgb2JzZXJ2YWJsZXMsIGFuZCByZWFjaGVzIHRoZSBiYWNrZW5kIG9ubHlcclxuICogdGhyb3VnaCB0aGUgc2hhcmVkIGBIdHRwU2VydmljZWAgZnJvbSBgQGllZWVzYS1ucG0vdXRpbGl0eWAgKG5ldmVyXHJcbiAqIGBIdHRwQ2xpZW50YCBkaXJlY3RseSkuXHJcbiAqXHJcbiAqIFRoZSB1cGNvbWluZy1ldmVudHMgbG9hZCBjYWxscyB0aGUgcmVhbCBgUE9TVCAvbWVldGluZ3MvZXZlbnRzQW5kTWVldGluZ3NgXHJcbiAqIGVuZHBvaW50IChjaGlsZCBtZWV0aW5ncyBhcmUgbGF6aWx5IGxvYWRlZCBwZXItZXZlbnQgdmlhXHJcbiAqIGBQT1NUIC9tZWV0aW5ncy9tZWV0aW5nc0RldGFpbHNgKTsgdGhlIGdyb3VwcyBsb2FkIGNhbGxzIGBHRVRcclxuICogL2dyb3Vwcy9teS1ncm91cHNgLiBUaGUgYXR0ZW5kYW5jZSBhY3Rpb25zIGNvbXBvc2UgdGhlIHB1cmUgcmVkdWNlcnMgZnJvbVxyXG4gKiBgYXR0ZW5kYW5jZS1yZWR1Y2Vycy50c2Agc28gdGhlIGRpc3BsYXllZCBgQXR0ZW5kYW5jZVN0YXRlYCBvbmx5IGFkdmFuY2VzIG9uIGFcclxuICogc3VjY2Vzc2Z1bCByZXNvbHV0aW9uIGFuZCB0aGUgcHJpb3Igc3RhdGUgaXMgcmV0YWluZWQgb24gZmFpbHVyZS5cclxuICogQGV4cG9ydFxyXG4gKiBAY2xhc3MgRGFzaGJvYXJkU2VydmljZVxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIERhc2hib2FyZFNlcnZpY2Uge1xyXG4gIGFwaUJhc2VVcmwhOiBzdHJpbmc7XHJcbiAgdXNlclBlcm1pc3Npb25zITogVXNlclBlcm1pc3Npb25bXTtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSB1cGNvbWluZ0V2ZW50cyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8VXBjb21pbmdFdmVudFtdPihbXSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEdyb3VwUm93W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nU3RhdGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERhc2hib2FyZFNlY3Rpb25TdGF0ZT4oXHJcbiAgICBEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElOR1xyXG4gICk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHNTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGF0dGVuZGFuY2VTdGF0ZXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPlxyXG4gID4oe30pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHRNZWV0aW5nSWRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcclxuICAgIFJlYWRvbmx5U2V0PHN0cmluZz5cclxuICA+KG5ldyBTZXQ8c3RyaW5nPigpKTtcclxuXHJcbiAgLyoqIEVtaXRzIHRoZSBsaXN0IG9mIHRoZSB1c2VyJ3MgdXBjb21pbmcgZXZlbnRzLiAqL1xyXG4gIHVwY29taW5nRXZlbnRzJDogT2JzZXJ2YWJsZTxVcGNvbWluZ0V2ZW50W10+ID1cclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsaXN0IG9mIHRoZSB1c2VyJ3MgZ3JvdXBzLiAqL1xyXG4gIGdyb3VwcyQ6IE9ic2VydmFibGU8R3JvdXBSb3dbXT4gPSB0aGlzLmdyb3Vwcy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxvYWQvZW1wdHkvZXJyb3Igc3RhdGUgb2YgdGhlIHVwY29taW5nLWV2ZW50cyBzZWN0aW9uLiAqL1xyXG4gIHVwY29taW5nU3RhdGUkOiBPYnNlcnZhYmxlPERhc2hib2FyZFNlY3Rpb25TdGF0ZT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgZ3JvdXBzIHNlY3Rpb24uICovXHJcbiAgZ3JvdXBzU3RhdGUkOiBPYnNlcnZhYmxlPERhc2hib2FyZFNlY3Rpb25TdGF0ZT4gPVxyXG4gICAgdGhpcy5ncm91cHNTdGF0ZS5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLiAqL1xyXG4gIGF0dGVuZGFuY2VTdGF0ZXMkOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4+ID1cclxuICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIHNldCBvZiBtZWV0aW5nIGlkcyB3aXRoIGFuIGF0dGVuZGFuY2UgYWN0aW9uIGluIGZsaWdodC4gKi9cclxuICBpbkZsaWdodE1lZXRpbmdJZHMkOiBPYnNlcnZhYmxlPFJlYWRvbmx5U2V0PHN0cmluZz4+ID1cclxuICAgIHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gICAgcHJpdmF0ZSBodHRwU2VydmljZTogSHR0cFNlcnZpY2UgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5LWZ1bmN0aW9uXHJcbiAgKSB7fVxyXG5cclxuICAvKipcclxuICAgKiBTdG9yZXMgdGhlIGhvc3Qtc3VwcGxpZWQgQVBJIGJhc2UgVVJMIGFuZCB1c2VyIHBlcm1pc3Npb25zIHVzZWQgdG8gYnVpbGRcclxuICAgKiByZXF1ZXN0IFVSTHMgYW5kIGdhdGUgcGVybWlzc2lvbi1jb250cm9sbGVkIGFjdGlvbnMuIE1pcnJvcnMgdGhlXHJcbiAgICogYGV2ZW50cy1hbmQtbWVldGluZ3NgIHNlcnZpY2UgYHNldEFwcENvbmZpZ2AuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFwaUJhc2VVUkwgLSBUaGUgaG9zdCBhcHBsaWNhdGlvbidzIEFQSSBiYXNlIFVSTC5cclxuICAgKiBAcGFyYW0ge1VzZXJQZXJtaXNzaW9uW119IHVzZXJQZXJtaXNzaW9ucyAtIFRoZSBzaWduZWQtaW4gdXNlcidzIHBlcm1pc3Npb25zLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBzZXRBcHBDb25maWcoYXBpQmFzZVVSTDogc3RyaW5nLCB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW10pOiB2b2lkIHtcclxuICAgIHRoaXMuYXBpQmFzZVVybCA9IGFwaUJhc2VVUkw7XHJcbiAgICB0aGlzLnVzZXJQZXJtaXNzaW9ucyA9IHVzZXJQZXJtaXNzaW9ucztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWRzIHRoZSB1c2VyJ3MgdXBjb21pbmcgZXZlbnRzICYgbWVldGluZ3MgZnJvbSB0aGUgcmVhbCBiYWNrZW5kIHZpYVxyXG4gICAqIGBQT1NUIHthcGlCYXNlVXJsfS9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2AsIHRoZSBzYW1lIGVuZHBvaW50IHRoZVxyXG4gICAqIGB2aWV3LWV2ZW50cy1tZWV0aW5ncy1saXN0YCBzY3JlZW4gdXNlcy4gVGhlIHJlc3BvbnNlIGlzIG1hcHBlZCBpbnRvIHRoZVxyXG4gICAqIGRhc2hib2FyZCB2aWV3IG1vZGVscyAod2l0aCBTVEFOREFMT05FX01FRVRJTkcgcm93cyBvcmRlcmVkIGxhc3QpLCB0aGVcclxuICAgKiBwZXItbWVldGluZyBhdHRlbmRhbmNlLXN0YXRlIG1hcCBpcyBzZWVkZWQsIGFuZCB0aGUgc2VjdGlvbiBhZHZhbmNlcyB0aHJvdWdoXHJcbiAgICogTE9BRElORyDihpIgTE9BREVEL0VNUFRZIG9uIHN1Y2Nlc3MsIGxlYXZpbmcgdGhlIGNhbGxlciB0byBzZXQgRVJST1Igb25cclxuICAgKiBmYWlsdXJlLiBGb2xsb3dzIHRoZSBzaGFyZWQgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICogQHJldHVybiB7T2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2U+fSBUaGUgdXBjb21pbmcgZXZlbnRzICYgbWVldGluZ3MgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkVXBjb21pbmdFdmVudHMoKTogT2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2U+IHtcclxuICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HKTtcclxuICAgIGNvbnN0IHBheWxvYWQ6IEV2ZW50TWVldGluZ0xpc3RQYXlsb2FkID0ge1xyXG4gICAgICBwYXlsb2FkOiB7XHJcbiAgICAgICAgZXZlbnRJZDogbnVsbCxcclxuICAgICAgICBzb3J0Q29sdW1uOiBVUENPTUlOR19TT1JUX0NPTFVNTixcclxuICAgICAgICBhc2NlbmRpbmdPcmRlcjogdHJ1ZSxcclxuICAgICAgICBwYWdlOiAxLFxyXG4gICAgICAgIHNpemU6IFVQQ09NSU5HX1BBR0VfU0laRSxcclxuICAgICAgICBmaWx0ZXI6IHtcclxuICAgICAgICAgIHN0YXR1czogVVBDT01JTkdfU1RBVFVTRVMsXHJcbiAgICAgICAgICBpc0FsbE1lZXRpbmdTZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAucG9zdERhdGEoYCR7dGhpcy5hcGlCYXNlVXJsfS9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2AsIHBheWxvYWQpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2U6IEV2ZW50TWVldGluZ0xpc3RSZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZXZlbnRzID0gbWFwRXZlbnRNZWV0aW5nTGlzdChcclxuICAgICAgICAgICAgcmVzcG9uc2U/LmJvZHk/LmV2ZW50TWVldGluZ0xpc3QgPz8gW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLnVwY29taW5nRXZlbnRzLm5leHQoZXZlbnRzKTtcclxuICAgICAgICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXMoZXZlbnRzKTtcclxuICAgICAgICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBldmVudHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgLy8gRWFnZXJseSBmZXRjaCBlYWNoIEVWRU5UJ3MgbWVldGluZyBjb3VudCBzbyB0aGUgXCJ7bn0gbWVldGluZ3NcIiBhbmRcclxuICAgICAgICAgIC8vIFwie259IG9wZW4gZm9yIGF0dGVuZGFuY2VcIiBzdW1tYXJpZXMgYXJlIGNvcnJlY3QgYmVmb3JlIGV4cGFuZGluZy5cclxuICAgICAgICAgIHRoaXMubG9hZEV2ZW50Q291bnRzKGV2ZW50cyk7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FUlJPUik7XHJcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICB9KVxyXG4gICAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGF6aWx5IGxvYWRzIChhbmQgcGFnaW5hdGVzKSB0aGUgY2hpbGQgbWVldGluZ3Mgb2YgYW4gRVZFTlQgcm93IHZpYVxyXG4gICAqIGBQT1NUIHthcGlCYXNlVXJsfS9tZWV0aW5ncy9tZWV0aW5nc0RldGFpbHNgIOKAlCB0aGUgcGVyLWV2ZW50IGV4cGFuZCBlbmRwb2ludFxyXG4gICAqIHVzZWQgYnkgdGhlIHJlZmVyZW5jZSBzY3JlZW4uIE9uIHN1Y2Nlc3MgdGhlIGxvYWRlZCBtZWV0aW5ncyBhcmUgbWFwcGVkIGFuZFxyXG4gICAqIG1lcmdlZCBvbnRvIHRoZSBtYXRjaGluZyBldmVudCBpbiB0aGUgYHVwY29taW5nRXZlbnRzYCBsaXN0ICh3aXRoIGl0c1xyXG4gICAqIGBtZWV0aW5nQ291bnRgIC8gYG9wZW5Gb3JBdHRlbmRhbmNlQ291bnRgIHJlZnJlc2hlZCksIGFuZCB0aGUgcGVyLW1lZXRpbmdcclxuICAgKiBhdHRlbmRhbmNlLXN0YXRlIG1hcCBpcyBleHRlbmRlZC4gRWFjaCBldmVudCBwYWdpbmF0ZXMgaW5kZXBlbmRlbnRseS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBsb2FkLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbcGFnZT0xXSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT1FVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVdIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGNoaWxkLW1lZXRpbmdzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZEV2ZW50TWVldGluZ3MoXHJcbiAgICBldmVudElkOiBzdHJpbmcsXHJcbiAgICBwYWdlID0gMSxcclxuICAgIHNpemUgPSBFVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVcclxuICApOiBPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPiB7XHJcbiAgICByZXR1cm4gdGhpcy5mZXRjaEV2ZW50TWVldGluZ3NQYWdlKGV2ZW50SWQsIHBhZ2UsIHNpemUpLnBpcGUoXHJcbiAgICAgIG1hcCgocmVzcG9uc2U6IEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgbWVldGluZ3MgPSBtYXBFdmVudE1lZXRpbmdEZXRhaWxzKFxyXG4gICAgICAgICAgcmVzcG9uc2U/LmJvZHk/Lm1lZXRpbmdzID8/IFtdXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCB0b3RhbCA9IHJlc3BvbnNlPy5ib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgICAgIC8vIFByZWZlciB0aGUgYWxyZWFkeS1rbm93biBmdWxsIG9wZW4gY291bnQgb24gdGhlIGV2ZW50OyBmYWxsIGJhY2sgdG9cclxuICAgICAgICAvLyB0aGUgY3VycmVudCBwYWdlJ3Mgb3BlbiBjb3VudCB3aGVuIGl0IGhhc24ndCBiZWVuIHByZWZldGNoZWQuXHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLnVwY29taW5nRXZlbnRzLnZhbHVlLmZpbmQoXHJcbiAgICAgICAgICAoZXZlbnQpID0+IGV2ZW50LmV2ZW50SWQgPT09IGV2ZW50SWRcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnN0IHBhZ2VPcGVuQ291bnQgPSBtZWV0aW5ncy5maWx0ZXIoXHJcbiAgICAgICAgICAobWVldGluZykgPT4gbWVldGluZy5pc09wZW5Gb3JBdHRlbmRhbmNlXHJcbiAgICAgICAgKS5sZW5ndGg7XHJcbiAgICAgICAgY29uc3Qgb3BlbkZvckF0dGVuZGFuY2VDb3VudCA9XHJcbiAgICAgICAgICBleGlzdGluZz8ub3BlbkZvckF0dGVuZGFuY2VDb3VudCB8fCBwYWdlT3BlbkNvdW50O1xyXG4gICAgICAgIHRoaXMubWVyZ2VFdmVudE1lZXRpbmdzKGV2ZW50SWQsIG1lZXRpbmdzLCB0b3RhbCwgb3BlbkZvckF0dGVuZGFuY2VDb3VudCk7XHJcbiAgICAgICAgdGhpcy5zZWVkQXR0ZW5kYW5jZVN0YXRlc0Zyb21NZWV0aW5ncyhtZWV0aW5ncyk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXJnZXMgYSBmcmVzaGx5IGxvYWRlZCBwYWdlIG9mIGNoaWxkIG1lZXRpbmdzIG9udG8gdGhlIG1hdGNoaW5nIGV2ZW50IGluXHJcbiAgICogdGhlIGB1cGNvbWluZ0V2ZW50c2AgbGlzdCwgcmVmcmVzaGluZyB0aGUgZXZlbnQncyBgbWVldGluZ3NgLFxyXG4gICAqIGBtZWV0aW5nQ291bnRgIChmcm9tIHRoZSBiYWNrZW5kIGB0b3RhbFJlY29yZHNgKSwgYW5kXHJcbiAgICogYG9wZW5Gb3JBdHRlbmRhbmNlQ291bnRgLiBMZWF2ZXMgYWxsIG90aGVyIGV2ZW50cyB1bnRvdWNoZWQuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50SWQgLSBUaGUgZXZlbnQgdG8gbWVyZ2UgbWVldGluZ3Mgb250by5cclxuICAgKiBAcGFyYW0ge01lZXRpbmdSb3dbXX0gbWVldGluZ3MgLSBUaGUgbWFwcGVkIGNoaWxkIG1lZXRpbmdzIGZvciB0aGUgcGFnZS5cclxuICAgKiBAcGFyYW0ge251bWJlcn0gdG90YWxSZWNvcmRzIC0gVGhlIGV2ZW50J3MgdG90YWwgbWVldGluZyBjb3VudCBmcm9tIHRoZSBiYWNrZW5kLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1lcmdlRXZlbnRNZWV0aW5ncyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIG1lZXRpbmdzOiBNZWV0aW5nUm93W10sXHJcbiAgICB0b3RhbFJlY29yZHM6IG51bWJlcixcclxuICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQ6IG51bWJlclxyXG4gICk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dCA9IHRoaXMudXBjb21pbmdFdmVudHMudmFsdWUubWFwKChldmVudCkgPT4ge1xyXG4gICAgICBpZiAoZXZlbnQuZXZlbnRJZCAhPT0gZXZlbnRJZCkge1xyXG4gICAgICAgIHJldHVybiBldmVudDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIC4uLmV2ZW50LFxyXG4gICAgICAgIG1lZXRpbmdzLFxyXG4gICAgICAgIG1lZXRpbmdDb3VudDogdG90YWxSZWNvcmRzLFxyXG4gICAgICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQsXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChuZXh0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVhZ2VybHkgZmV0Y2hlcyBlYWNoIEVWRU5UJ3MgdG90YWwgbWVldGluZyBjb3VudCBhbmQgb3Blbi1mb3ItYXR0ZW5kYW5jZVxyXG4gICAqIGNvdW50IGJ5IHJlcXVlc3RpbmcgYSBsYXJnZSBmaXJzdCBwYWdlIG9mIGl0cyBjaGlsZCBtZWV0aW5ncywgdGhlbiBtZXJnaW5nXHJcbiAgICogb25seSB0aGUgY291bnRzIChub3QgdGhlIHJvd3MpIHNvIHRoZSBjb2xsYXBzZWQgY2FyZCBzdW1tYXJpZXMgYXJlIGFjY3VyYXRlXHJcbiAgICogYmVmb3JlIHRoZSB1c2VyIGV4cGFuZHMuIFN0YW5kYWxvbmUgbWVldGluZ3MgYXJlIHNraXBwZWQuIEZhaWx1cmVzIHBlciBldmVudFxyXG4gICAqIGFyZSBzd2FsbG93ZWQgc28gb25lIGZhaWxpbmcgY291bnQgbmV2ZXIgYnJlYWtzIHRoZSBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIGV2ZW50cyB0byBmZXRjaCBjb3VudHMgZm9yLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIGxvYWRFdmVudENvdW50cyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgZXZlbnRzXHJcbiAgICAgIC5maWx0ZXIoKGV2ZW50KSA9PiBldmVudC5raW5kID09PSBVcGNvbWluZ0l0ZW1LaW5kLkVWRU5UICYmIGV2ZW50LmV2ZW50SWQpXHJcbiAgICAgIC5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICAgIHRoaXMuZmV0Y2hFdmVudE1lZXRpbmdzUGFnZShldmVudC5ldmVudElkLCAxLCBFVkVOVF9DT1VOVF9QQUdFX1NJWkUpXHJcbiAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihudWxsKSlcclxuICAgICAgICAgIClcclxuICAgICAgICAgIC5zdWJzY3JpYmUoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgbWVldGluZ3MgPSBtYXBFdmVudE1lZXRpbmdEZXRhaWxzKFxyXG4gICAgICAgICAgICAgIHJlc3BvbnNlPy5ib2R5Py5tZWV0aW5ncyA/PyBbXVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBjb25zdCB0b3RhbCA9IHJlc3BvbnNlPy5ib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgICAgICAgICBjb25zdCBvcGVuQ291bnQgPSBtZWV0aW5ncy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgKG1lZXRpbmcpID0+IG1lZXRpbmcuaXNPcGVuRm9yQXR0ZW5kYW5jZVxyXG4gICAgICAgICAgICApLmxlbmd0aDtcclxuICAgICAgICAgICAgdGhpcy5tZXJnZUV2ZW50Q291bnRzKGV2ZW50LmV2ZW50SWQsIHRvdGFsLCBvcGVuQ291bnQpO1xyXG4gICAgICAgICAgICB0aGlzLnNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyBvbmx5IHRoZSBtZWV0aW5nIGNvdW50cyBvbnRvIHRoZSBtYXRjaGluZyBldmVudCwgbGVhdmluZyBpdHNcclxuICAgKiBgbWVldGluZ3NgIHJvd3MgdW50b3VjaGVkICh1c2VkIGJ5IHRoZSBlYWdlciBjb3VudCBwcmVmZXRjaCkuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50SWQgLSBUaGUgZXZlbnQgdG8gdXBkYXRlLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b3RhbFJlY29yZHMgLSBUaGUgZXZlbnQncyB0b3RhbCBtZWV0aW5nIGNvdW50LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGVuRm9yQXR0ZW5kYW5jZUNvdW50IC0gVGhlIG9wZW4tZm9yLWF0dGVuZGFuY2UgY291bnQuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgbWVyZ2VFdmVudENvdW50cyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIHRvdGFsUmVjb3JkczogbnVtYmVyLFxyXG4gICAgb3BlbkZvckF0dGVuZGFuY2VDb3VudDogbnVtYmVyXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCBuZXh0ID0gdGhpcy51cGNvbWluZ0V2ZW50cy52YWx1ZS5tYXAoKGV2ZW50KSA9PlxyXG4gICAgICBldmVudC5ldmVudElkID09PSBldmVudElkXHJcbiAgICAgICAgPyB7IC4uLmV2ZW50LCBtZWV0aW5nQ291bnQ6IHRvdGFsUmVjb3Jkcywgb3BlbkZvckF0dGVuZGFuY2VDb3VudCB9XHJcbiAgICAgICAgOiBldmVudFxyXG4gICAgKTtcclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChuZXh0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1aWxkcyBhbmQgcG9zdHMgdGhlIGBtZWV0aW5nc0RldGFpbHNgIHJlcXVlc3QgZm9yIGEgc2luZ2xlIGV2ZW50IHBhZ2UsXHJcbiAgICogcmV0dXJuaW5nIHRoZSByYXcgcmVzcG9uc2UgZW52ZWxvcGUuIFNoYXJlZCBieSB7QGxpbmsgbG9hZEV2ZW50TWVldGluZ3N9IGFuZFxyXG4gICAqIHRoZSBlYWdlciBjb3VudCBwcmVmZXRjaC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBmZXRjaC5cclxuICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGNoaWxkLW1lZXRpbmdzIHJlc3BvbnNlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBmZXRjaEV2ZW50TWVldGluZ3NQYWdlKFxyXG4gICAgZXZlbnRJZDogc3RyaW5nLFxyXG4gICAgcGFnZTogbnVtYmVyLFxyXG4gICAgc2l6ZTogbnVtYmVyXHJcbiAgKTogT2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdEZXRhaWxSZXNwb25zZT4ge1xyXG4gICAgY29uc3QgcGF5bG9hZDogRXZlbnRNZWV0aW5nRGV0YWlsUGF5bG9hZCA9IHtcclxuICAgICAgcGF5bG9hZDoge1xyXG4gICAgICAgIGV2ZW50SWQsXHJcbiAgICAgICAgc29ydENvbHVtbjogRVZFTlRfTUVFVElOR1NfU09SVF9DT0xVTU4sXHJcbiAgICAgICAgYXNjZW5kaW5nT3JkZXI6IHRydWUsXHJcbiAgICAgICAgcGFnZSxcclxuICAgICAgICBzaXplLFxyXG4gICAgICAgIGZpbHRlcjoge1xyXG4gICAgICAgICAgc3RhdHVzOiBVUENPTUlOR19TVEFUVVNFUyxcclxuICAgICAgICAgIGlzQWxsTWVldGluZ1NlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2aWNlLnBvc3REYXRhKFxyXG4gICAgICBgJHt0aGlzLmFwaUJhc2VVcmx9L21lZXRpbmdzL21lZXRpbmdzRGV0YWlsc2AsXHJcbiAgICAgIHBheWxvYWRcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2FkcyB0aGUgdXNlcidzIGdyb3VwcywgZHJpdmluZyB0aGUgZ3JvdXBzIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICpcclxuICAgKiBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxHcm91cFJvd1tdPj59IFRoZSBncm91cHMgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkR3JvdXBzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPE15R3JvdXBzVmlldz4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAuZ2V0RGF0YShgJHt0aGlzLmFwaUJhc2VVcmx9L2dyb3Vwcy9teS1ncm91cHNgKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlOiBEYXNoYm9hcmRMaXN0UmVzcG9uc2U8TXlHcm91cHNWaWV3PikgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZ3JvdXBzID0gKHJlc3BvbnNlPy5ib2R5Py5ncm91cHMgPz8gW10pLm1hcCgoZ3JvdXApID0+XHJcbiAgICAgICAgICAgIHRoaXMubWFwR3JvdXAoZ3JvdXApXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHMubmV4dChncm91cHMpO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVSUk9SKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNYXBzIGEgYmFja2VuZCB7QGxpbmsgTXlHcm91cFZpZXd9IHRvIHRoZSB0YWJsZS1mYWNpbmcge0BsaW5rIEdyb3VwUm93fS5cclxuICAgKiBNaXJyb3JzIHRoZSBNeSBHcm91cHMgcHJvZmlsZSB0YWI6IHRoZSB0eXBlIGZhbGxzIGJhY2sgdG8gXCJVbmFzc2lnbmVkXCIgd2hlblxyXG4gICAqIGBncm91cFR5cGVOYW1lYCBpcyBudWxsLCBhZmZpbGlhdGlvbnMgYXJlIGNvbW1hLWpvaW5lZCwgZW1wdHkgb2ZmaWNlciByb2xlIC9cclxuICAgKiBhZmZpbGlhdGlvbiByZW5kZXIgYXMgYSBwbGFjZWhvbGRlciwgYW5kIGEgYmxhbmsgbWVtYmVyIGxldmVsIGJlY29tZXNcclxuICAgKiBcIlVuYXNzaWduZWRcIiAocmVuZGVyZWQgYXMgdGhlIHdhcm5pbmcgcGlsbCBieSB0aGUgWW91ciBHcm91cHMgY29tcG9uZW50KS5cclxuICAgKiBAcGFyYW0ge015R3JvdXBWaWV3fSBncm91cCAtIFRoZSBiYWNrZW5kIGdyb3VwIHZpZXcuXHJcbiAgICogQHJldHVybiB7R3JvdXBSb3d9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1hcEdyb3VwKGdyb3VwOiBNeUdyb3VwVmlldyk6IEdyb3VwUm93IHtcclxuICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybnMgb2ZmaWNlciByb2xlcyBhcyBhbiBgb2ZmaWNlcmAgYXJyYXkgb2ZcclxuICAgIC8vIHsgb2ZmaWNlcklkLCBvZmZpY2VyTmFtZSB9LiBKb2luIHRoZSBuYW1lcyBmb3IgdGhlIE9mZmljZXIgUm9sZSBjb2x1bW5cclxuICAgIC8vIChlLmcuIFwiQ2hhaXJcIiBvciBcIkNoYWlyLCBWaWNlIENoYWlyXCIpOyBzaG93IHRoZSBwbGFjZWhvbGRlciB3aGVuIGVtcHR5LlxyXG4gICAgY29uc3Qgb2ZmaWNlclJvbGUgPVxyXG4gICAgICAoZ3JvdXAub2ZmaWNlciA/PyBbXSlcclxuICAgICAgICAubWFwKChvZmZpY2VyKSA9PiBvZmZpY2VyPy5vZmZpY2VyTmFtZT8udHJpbSgpKVxyXG4gICAgICAgIC5maWx0ZXIoKG5hbWUpID0+ICEhbmFtZSlcclxuICAgICAgICAuam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBncm91cElkOiBncm91cC5ncm91cElkLFxyXG4gICAgICBncm91cDogZ3JvdXAuZ3JvdXBOYW1lLFxyXG4gICAgICB0eXBlOiBncm91cC5ncm91cFR5cGVOYW1lIHx8IGdyb3VwLmdyb3VwVHlwZSB8fCBVTkFTU0lHTkVEX0xBQkVMLFxyXG4gICAgICBvZmZpY2VyUm9sZSxcclxuICAgICAgYWZmaWxpYXRpb246IGdyb3VwLmFmZmlsaWF0aW9ucz8uam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRSxcclxuICAgICAgbWVtYmVyTGV2ZWw6IGdyb3VwLm1lbWJlckxldmVsPy50cmltKCkgfHwgVU5BU1NJR05FRF9MQUJFTCxcclxuICAgICAgLy8gQ2FycnkgdGhlIGFuY2VzdG9yIGhpZXJhcmNoeSB0aHJvdWdoIGZvciB0aGUgZXhwYW5kYWJsZSBoaWVyYXJjaHkgcm93cy5cclxuICAgICAgaGllcmFyY2h5OiBncm91cC5oaWVyYXJjaHkgPz8gW10sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbWVldGluZ3MgPSBldmVudHMuZmxhdE1hcCgoZXZlbnQpID0+IGV2ZW50Lm1lZXRpbmdzID8/IFtdKTtcclxuICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXNGcm9tTWVldGluZ3MobWVldGluZ3MpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VlZHMgdGhlIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGZyb20gYSBsaXN0IG9mIG1lZXRpbmcgcm93cywgdXNpbmcgZWFjaFxyXG4gICAqIG1lZXRpbmcncyBgYXR0ZW5kYW5jZVN0YXRlYCAoZGVmYXVsdGluZyB0byBgTk9UX0FUVEVORElOR2ApIHdpdGhvdXRcclxuICAgKiBvdmVyd3JpdGluZyBpZHMgYWJzZW50IGZyb20gdGhlIG5ldyBsaXN0LiBTaGFyZWQgYnkgdGhlIGxpc3QgbG9hZCBhbmQgdGhlXHJcbiAgICogcGVyLWV2ZW50IGV4cGFuZCBzbyBmcmVzaGx5IGxvYWRlZCBjaGlsZCBtZWV0aW5ncyBwaWNrIHVwIHRoZWlyIHN0YXRlLlxyXG4gICAqIEBwYXJhbSB7TWVldGluZ1Jvd1tdfSBtZWV0aW5ncyAtIFRoZSBtZWV0aW5nIHJvd3MgdG8gc2VlZCBmcm9tLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIHNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzOiBNZWV0aW5nUm93W10pOiB2b2lkIHtcclxuICAgIGNvbnN0IG5leHQ6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4gPSB7XHJcbiAgICAgIC4uLnRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZSxcclxuICAgIH07XHJcbiAgICBtZWV0aW5ncy5mb3JFYWNoKChtZWV0aW5nKSA9PiB7XHJcbiAgICAgIGlmIChtZWV0aW5nLm1lZXRpbmdJZCkge1xyXG4gICAgICAgIG5leHRbbWVldGluZy5tZWV0aW5nSWRdID1cclxuICAgICAgICAgIG1lZXRpbmcuYXR0ZW5kYW5jZVN0YXRlID8/XHJcbiAgICAgICAgICBuZXh0W21lZXRpbmcubWVldGluZ0lkXSA/P1xyXG4gICAgICAgICAgQXR0ZW5kYW5jZVN0YXRlLk5PVF9BVFRFTkRJTkc7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLm5leHQobmV4dCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
347
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsR0FDSixNQUFNLE1BQU0sQ0FBQztBQUdkLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUVuRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQU1oRixPQUFPLEVBRUwsZ0JBQWdCLEdBQ2pCLE1BQU0sZ0NBQWdDLENBQUM7QUFVeEMsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixtQkFBbUIsR0FDcEIsTUFBTSxvQ0FBb0MsQ0FBQztBQVc1QyxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QixxQkFBcUIsRUFDckIsbUJBQW1CLEdBQ3BCLE1BQU0sdUJBQXVCLENBQUM7OztBQWIvQix5RkFBeUY7QUFDekYsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFDdEMsMkNBQTJDO0FBQzNDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4Qix1RUFBdUU7QUFDdkUsTUFBTSxrQkFBa0IsR0FBRyxFQUFFLENBQUM7QUFDOUIsc0VBQXNFO0FBQ3RFLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxDQUFDO0FBUW5DOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUlILE1BQU0sT0FBTyxnQkFBZ0I7SUFxQzNCO0lBQ0UsMENBQTBDO0lBQ2xDLFdBQXdCLENBQUMsNkNBQTZDOztRQUF0RSxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQW5DakIsbUJBQWMsR0FBRyxJQUFJLGVBQWUsQ0FBa0IsRUFBRSxDQUFDLENBQUM7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QixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIE15R3JvdXBzVmlldyxcclxuICBNeUdyb3VwVmlldyxcclxufSBmcm9tICcuLi9tb2RlbHMvbXktZ3JvdXBzLXZpZXcubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIFVwY29taW5nRXZlbnQsXHJcbiAgVXBjb21pbmdJdGVtS2luZCxcclxufSBmcm9tICcuLi9tb2RlbHMvdXBjb21pbmctZXZlbnQubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIEV2ZW50TWVldGluZ0RldGFpbFBheWxvYWQsXHJcbiAgRXZlbnRNZWV0aW5nTGlzdFBheWxvYWQsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1wYXlsb2FkLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBFdmVudE1lZXRpbmdEZXRhaWxCb2R5LFxyXG4gIEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlLFxyXG4gIEV2ZW50TWVldGluZ0xpc3RSZXNwb25zZSxcclxufSBmcm9tICcuLi9tb2RlbHMvZXZlbnQtbWVldGluZy1saXN0LWl0ZW0ubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIG1hcEV2ZW50TWVldGluZ0RldGFpbHMsXHJcbiAgbWFwRXZlbnRNZWV0aW5nTGlzdCxcclxufSBmcm9tICcuLi91dGlscy9ldmVudC1tZWV0aW5nLW1hcHBlci51dGlsJztcclxuaW1wb3J0IHsgTWVldGluZ1JvdyB9IGZyb20gJy4uL21vZGVscy9tZWV0aW5nLXJvdy5tb2RlbCc7XHJcblxyXG4vKiogRmFsbGJhY2sgbGFiZWwgZm9yIGFuIGVtcHR5IGdyb3VwIHR5cGUgLyBtZW1iZXIgbGV2ZWwsIG1hdGNoaW5nIHRoZSBNeSBHcm91cHMgdGFiLiAqL1xyXG5jb25zdCBVTkFTU0lHTkVEX0xBQkVMID0gJ1VuYXNzaWduZWQnO1xyXG4vKiogUGxhY2Vob2xkZXIgZm9yIGFuIGVtcHR5IGNlbGwgdmFsdWUuICovXHJcbmNvbnN0IEVNUFRZX1ZBTFVFID0gJy0nO1xyXG4vKiogRGVmYXVsdCBwYWdlIHNpemUgZm9yIHRoZSB0b3AtbGV2ZWwgaG9tZSBldmVudHMtJi1tZWV0aW5ncyBsaXN0LiAqL1xyXG5jb25zdCBVUENPTUlOR19QQUdFX1NJWkUgPSAxMDtcclxuLyoqIERlZmF1bHQgcGFnZSBzaXplIGZvciBhbiBldmVudCdzIGRyaWxsLWRvd24gY2hpbGQtbWVldGluZyBsaXN0LiAqL1xyXG5jb25zdCBFVkVOVF9NRUVUSU5HU19QQUdFX1NJWkUgPSA1O1xyXG5pbXBvcnQge1xyXG4gIGFwcGx5TGVhdmVNZWV0aW5nU3VjY2VzcyxcclxuICBhcHBseUxvZ0F0dGVuZGFuY2VTdWNjZXNzLFxyXG4gIGJlZ2luQXR0ZW5kYW5jZUFjdGlvbixcclxuICBlbmRBdHRlbmRhbmNlQWN0aW9uLFxyXG59IGZyb20gJy4vYXR0ZW5kYW5jZS1yZWR1Y2Vycyc7XHJcblxyXG4vKipcclxuICogRGFzaGJvYXJkU2VydmljZSBpcyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgdGhlIGRhc2hib2FyZCBsYW5kaW5nXHJcbiAqIHBhZ2UncyBkYXRhIGFuZCBhdHRlbmRhbmNlIHN0YXRlLiBJdCBtaXJyb3JzIHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2BcclxuICogc2VydmljZSBjb252ZW50aW9uczogaXQgaXMgYSBgcHJvdmlkZWRJbjogJ3Jvb3QnYCBzaW5nbGV0b24sIGhvbGRzIHRoZSBob3N0XHJcbiAqIGBhcGlCYXNlVXJsYCAvIGB1c2VyUGVybWlzc2lvbnNgIHNldCB2aWEge0BsaW5rIHNldEFwcENvbmZpZ30sIG93bnMgaXRzIHN0YXRlXHJcbiAqIHZpYSBgQmVoYXZpb3JTdWJqZWN0YHMgZXhwb3NlZCBhcyBvYnNlcnZhYmxlcywgYW5kIHJlYWNoZXMgdGhlIGJhY2tlbmQgb25seVxyXG4gKiB0aHJvdWdoIHRoZSBzaGFyZWQgYEh0dHBTZXJ2aWNlYCBmcm9tIGBAaWVlZXNhLW5wbS91dGlsaXR5YCAobmV2ZXJcclxuICogYEh0dHBDbGllbnRgIGRpcmVjdGx5KS5cclxuICpcclxuICogVGhlIHVwY29taW5nLWV2ZW50cyBsb2FkIGNhbGxzIHRoZSByZWFsIGBQT1NUIC9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2BcclxuICogZW5kcG9pbnQgKGNoaWxkIG1lZXRpbmdzIGFyZSBsYXppbHkgbG9hZGVkIHBlci1ldmVudCB2aWFcclxuICogYFBPU1QgL21lZXRpbmdzL21lZXRpbmdzRGV0YWlsc2ApOyB0aGUgZ3JvdXBzIGxvYWQgY2FsbHMgYEdFVFxyXG4gKiAvZ3JvdXBzL215LWdyb3Vwc2AuIFRoZSBhdHRlbmRhbmNlIGFjdGlvbnMgY29tcG9zZSB0aGUgcHVyZSByZWR1Y2VycyBmcm9tXHJcbiAqIGBhdHRlbmRhbmNlLXJlZHVjZXJzLnRzYCBzbyB0aGUgZGlzcGxheWVkIGBBdHRlbmRhbmNlU3RhdGVgIG9ubHkgYWR2YW5jZXMgb24gYVxyXG4gKiBzdWNjZXNzZnVsIHJlc29sdXRpb24gYW5kIHRoZSBwcmlvciBzdGF0ZSBpcyByZXRhaW5lZCBvbiBmYWlsdXJlLlxyXG4gKiBAZXhwb3J0XHJcbiAqIEBjbGFzcyBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGFzaGJvYXJkU2VydmljZSB7XHJcbiAgYXBpQmFzZVVybCE6IHN0cmluZztcclxuICB1c2VyUGVybWlzc2lvbnMhOiBVc2VyUGVybWlzc2lvbltdO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nRXZlbnRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxVcGNvbWluZ0V2ZW50W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8R3JvdXBSb3dbXT4oW10pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBjb21pbmdTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3Vwc1N0YXRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEYXNoYm9hcmRTZWN0aW9uU3RhdGU+KFxyXG4gICAgRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURJTkdcclxuICApO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgYXR0ZW5kYW5jZVN0YXRlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XHJcbiAgICBSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+XHJcbiAgPih7fSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBpbkZsaWdodE1lZXRpbmdJZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVhZG9ubHlTZXQ8c3RyaW5nPlxyXG4gID4obmV3IFNldDxzdHJpbmc+KCkpO1xyXG5cclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMuICovXHJcbiAgdXBjb21pbmdFdmVudHMkOiBPYnNlcnZhYmxlPFVwY29taW5nRXZlbnRbXT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ0V2ZW50cy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyBncm91cHMuICovXHJcbiAgZ3JvdXBzJDogT2JzZXJ2YWJsZTxHcm91cFJvd1tdPiA9IHRoaXMuZ3JvdXBzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgdXBjb21pbmctZXZlbnRzIHNlY3Rpb24uICovXHJcbiAgdXBjb21pbmdTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLnVwY29taW5nU3RhdGUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsb2FkL2VtcHR5L2Vycm9yIHN0YXRlIG9mIHRoZSBncm91cHMgc2VjdGlvbi4gKi9cclxuICBncm91cHNTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLmdyb3Vwc1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgcGVyLW1lZXRpbmcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAuICovXHJcbiAgYXR0ZW5kYW5jZVN0YXRlcyQ6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPj4gPVxyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgc2V0IG9mIG1lZXRpbmcgaWRzIHdpdGggYW4gYXR0ZW5kYW5jZSBhY3Rpb24gaW4gZmxpZ2h0LiAqL1xyXG4gIGluRmxpZ2h0TWVldGluZ0lkcyQ6IE9ic2VydmFibGU8UmVhZG9ubHlTZXQ8c3RyaW5nPj4gPVxyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXHJcbiAgICBwcml2YXRlIGh0dHBTZXJ2aWNlOiBIdHRwU2VydmljZSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHktZnVuY3Rpb25cclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN0b3JlcyB0aGUgaG9zdC1zdXBwbGllZCBBUEkgYmFzZSBVUkwgYW5kIHVzZXIgcGVybWlzc2lvbnMgdXNlZCB0byBidWlsZFxyXG4gICAqIHJlcXVlc3QgVVJMcyBhbmQgZ2F0ZSBwZXJtaXNzaW9uLWNvbnRyb2xsZWQgYWN0aW9ucy4gTWlycm9ycyB0aGVcclxuICAgKiBgZXZlbnRzLWFuZC1tZWV0aW5nc2Agc2VydmljZSBgc2V0QXBwQ29uZmlnYC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXBpQmFzZVVSTCAtIFRoZSBob3N0IGFwcGxpY2F0aW9uJ3MgQVBJIGJhc2UgVVJMLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zIC0gVGhlIHNpZ25lZC1pbiB1c2VyJ3MgcGVybWlzc2lvbnMuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHNldEFwcENvbmZpZyhhcGlCYXNlVVJMOiBzdHJpbmcsIHVzZXJQZXJtaXNzaW9uczogVXNlclBlcm1pc3Npb25bXSk6IHZvaWQge1xyXG4gICAgdGhpcy5hcGlCYXNlVXJsID0gYXBpQmFzZVVSTDtcclxuICAgIHRoaXMudXNlclBlcm1pc3Npb25zID0gdXNlclBlcm1pc3Npb25zO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZHMgdGhlIHVzZXIncyBjb21iaW5lZCB1cGNvbWluZyBldmVudHMgJiBzdGFuZGFsb25lIG1lZXRpbmdzIGZyb20gdGhlXHJcbiAgICogYmFja2VuZCB2aWEgYFBPU1Qge2FwaUJhc2VVcmx9L21lZXRpbmdzL2hvbWUvZXZlbnRzQW5kTWVldGluZ3NgLiBUaGUgcmVzcG9uc2VcclxuICAgKiAod2hpY2ggY2FycmllcyBwZXItZXZlbnQgYHRvdGFsTWVldGluZ0NvdW50YCAvIGBtZWV0aW5nc09wZW5Gb3JBdHRlbmRhbmNlQ291bnRgXHJcbiAgICogYW5kIHBlci1zdGFuZGFsb25lIGBhdHRlbmRhbmNlU3RhdGVgIGRpcmVjdGx5KSBpcyBtYXBwZWQgaW50byB0aGUgZGFzaGJvYXJkXHJcbiAgICogdmlldyBtb2RlbHMgKFNUQU5EQUxPTkVfTUVFVElORyByb3dzIG9yZGVyZWQgbGFzdCksIHRoZSBwZXItbWVldGluZ1xyXG4gICAqIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGlzIHNlZWRlZCwgYW5kIHRoZSBzZWN0aW9uIGFkdmFuY2VzIHRocm91Z2hcclxuICAgKiBMT0FESU5HIOKGkiBMT0FERUQvRU1QVFkgb24gc3VjY2Vzcy4gYGFwcElkYCBpcyB0YWtlbiBmcm9tIHRoZSBKV1QsIHNvIGl0IGlzXHJcbiAgICogbm90IHNlbnQuIEZvbGxvd3MgdGhlIHNoYXJlZCBgcGlwZShtYXAsIGNhdGNoRXJyb3IodGhyb3cpKWAgcGF0dGVybi5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0xpc3RSZXNwb25zZT59IFRoZSBob21lIGV2ZW50cy0mLW1lZXRpbmdzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZFVwY29taW5nRXZlbnRzKCk6IE9ic2VydmFibGU8RXZlbnRNZWV0aW5nTGlzdFJlc3BvbnNlPiB7XHJcbiAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICBjb25zdCBwYXlsb2FkOiBFdmVudE1lZXRpbmdMaXN0UGF5bG9hZCA9IHtcclxuICAgICAgcGF5bG9hZDoge1xyXG4gICAgICAgIHBhZ2U6IDEsXHJcbiAgICAgICAgc2l6ZTogVVBDT01JTkdfUEFHRV9TSVpFLFxyXG4gICAgICAgIHNvcnRDb2x1bW46ICdzdGFydERhdGVUaW1lJyxcclxuICAgICAgICBhc2NlbmRpbmdPcmRlcjogdHJ1ZSxcclxuICAgICAgICBzZWFyY2hUZXJtOiBudWxsLFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2aWNlXHJcbiAgICAgIC5wb3N0RGF0YShgJHt0aGlzLmFwaUJhc2VVcmx9L21lZXRpbmdzL2hvbWUvZXZlbnRzQW5kTWVldGluZ3NgLCBwYXlsb2FkKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlOiBFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IG1hcEV2ZW50TWVldGluZ0xpc3QoXHJcbiAgICAgICAgICAgIHJlc3BvbnNlPy5ib2R5Py5ldmVudE1lZXRpbmdMaXN0ID8/IFtdXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy51cGNvbWluZ0V2ZW50cy5uZXh0KGV2ZW50cyk7XHJcbiAgICAgICAgICB0aGlzLnNlZWRBdHRlbmRhbmNlU3RhdGVzKGV2ZW50cyk7XHJcbiAgICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChcclxuICAgICAgICAgICAgZXZlbnRzLmxlbmd0aCA+IDBcclxuICAgICAgICAgICAgICA/IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FERURcclxuICAgICAgICAgICAgICA6IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FTVBUWVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgdGhpcy51cGNvbWluZ1N0YXRlLm5leHQoRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVSUk9SKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMYXppbHkgbG9hZHMgKGFuZCBwYWdpbmF0ZXMpIHRoZSBjaGlsZCBtZWV0aW5ncyBvZiBhbiBFVkVOVCB2aWFcclxuICAgKiBgUE9TVCB7YXBpQmFzZVVybH0vbWVldGluZ3MvaG9tZS9ldmVudHMve2V2ZW50SWR9L21lZXRpbmdzYCAodGhlIGRyaWxsLWRvd25cclxuICAgKiBlbmRwb2ludCkuIFRoZSBgZXZlbnRJZGAgaXMgc2VudCBpbiB0aGUgVVJMIHBhdGg7IG9ubHkgYHBhZ2VgIC8gYHNpemVgIGFyZVxyXG4gICAqIHVzZWQgaW4gdGhlIGJvZHkuIE9uIHN1Y2Nlc3MgdGhlIGRyaWxsLWRvd24gYm9keSAoZGF5IGluZGljYXRvciwgY291bnRzLFxyXG4gICAqIHBhZ2luYXRvciB0b3RhbCwgYW5kIHRoZSBwYWdlZCBtZWV0aW5ncykgaXMgbWVyZ2VkIG9udG8gdGhlIG1hdGNoaW5nIGV2ZW50LFxyXG4gICAqIGFuZCB0aGUgcGVyLW1lZXRpbmcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgaXMgZXh0ZW5kZWQuIEVhY2ggZXZlbnQgcGFnaW5hdGVzXHJcbiAgICogaW5kZXBlbmRlbnRseS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBsb2FkLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbcGFnZT0xXSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT1FVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVdIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGRyaWxsLWRvd24gcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkRXZlbnRNZWV0aW5ncyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIHBhZ2UgPSAxLFxyXG4gICAgc2l6ZSA9IEVWRU5UX01FRVRJTkdTX1BBR0VfU0laRVxyXG4gICk6IE9ic2VydmFibGU8RXZlbnRNZWV0aW5nRGV0YWlsUmVzcG9uc2U+IHtcclxuICAgIGNvbnN0IHBheWxvYWQ6IEV2ZW50TWVldGluZ0RldGFpbFBheWxvYWQgPSB7XHJcbiAgICAgIHBheWxvYWQ6IHsgcGFnZSwgc2l6ZSB9LFxyXG4gICAgfTtcclxuICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2aWNlXHJcbiAgICAgIC5wb3N0RGF0YShcclxuICAgICAgICBgJHt0aGlzLmFwaUJhc2VVcmx9L21lZXRpbmdzL2hvbWUvZXZlbnRzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KFxyXG4gICAgICAgICAgZXZlbnRJZFxyXG4gICAgICAgICl9L21lZXRpbmdzYCxcclxuICAgICAgICBwYXlsb2FkXHJcbiAgICAgIClcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgbWFwKChyZXNwb25zZTogRXZlbnRNZWV0aW5nRGV0YWlsUmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGJvZHkgPSByZXNwb25zZT8uYm9keTtcclxuICAgICAgICAgIGNvbnN0IG1lZXRpbmdzID0gbWFwRXZlbnRNZWV0aW5nRGV0YWlscyhib2R5Py5tZWV0aW5ncyA/PyBbXSwgZXZlbnRJZCk7XHJcbiAgICAgICAgICB0aGlzLm1lcmdlRXZlbnRNZWV0aW5ncyhldmVudElkLCBtZWV0aW5ncywgYm9keSk7XHJcbiAgICAgICAgICB0aGlzLnNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyBhIGZyZXNobHkgbG9hZGVkIGRyaWxsLWRvd24gcGFnZSBvbnRvIHRoZSBtYXRjaGluZyBldmVudCBpbiB0aGVcclxuICAgKiBgdXBjb21pbmdFdmVudHNgIGxpc3Q6IHRoZSBwYWdlZCBgbWVldGluZ3NgLCB0aGUgcGFnaW5hdG9yIHRvdGFsXHJcbiAgICogKGB0b3RhbFJlY29yZHNgID0gdGhlIHVzZXIncyB0aWVkIHVwY29taW5nIG1lZXRpbmdzKSwgdGhlIGV2ZW50J3MgZnVsbFxyXG4gICAqIGB0b3RhbE1lZXRpbmdDb3VudGAgLyBgbWVldGluZ3NPcGVuRm9yQXR0ZW5kYW5jZUNvdW50YCwgYW5kIHRoZVxyXG4gICAqIFwiRGF5IFggb2YgWVwiIGluZGljYXRvciBkZXJpdmVkIGZyb20gYGN1cnJlbnREYXlgIC8gYHRvdGFsRGF5c2AuIExlYXZlcyBhbGxcclxuICAgKiBvdGhlciBldmVudHMgdW50b3VjaGVkLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudElkIC0gVGhlIGV2ZW50IHRvIG1lcmdlIG1lZXRpbmdzIG9udG8uXHJcbiAgICogQHBhcmFtIHtNZWV0aW5nUm93W119IG1lZXRpbmdzIC0gVGhlIG1hcHBlZCBkcmlsbC1kb3duIG1lZXRpbmdzIGZvciB0aGUgcGFnZS5cclxuICAgKiBAcGFyYW0ge0V2ZW50TWVldGluZ0RldGFpbEJvZHkgfCB1bmRlZmluZWR9IGJvZHkgLSBUaGUgZHJpbGwtZG93biByZXNwb25zZSBib2R5LlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1lcmdlRXZlbnRNZWV0aW5ncyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIG1lZXRpbmdzOiBNZWV0aW5nUm93W10sXHJcbiAgICBib2R5OiBFdmVudE1lZXRpbmdEZXRhaWxCb2R5IHwgdW5kZWZpbmVkXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCB0b3RhbFJlY29yZHMgPSBib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgY29uc3QgdG90YWxNZWV0aW5nQ291bnQgPSBib2R5Py50b3RhbE1lZXRpbmdDb3VudCA/PyB0b3RhbFJlY29yZHM7XHJcbiAgICBjb25zdCBvcGVuRm9yQXR0ZW5kYW5jZUNvdW50ID0gYm9keT8ubWVldGluZ3NPcGVuRm9yQXR0ZW5kYW5jZUNvdW50ID8/IDA7XHJcbiAgICBjb25zdCBjdXJyZW50RGF5ID0gYm9keT8uY3VycmVudERheTtcclxuICAgIGNvbnN0IHRvdGFsRGF5cyA9IGJvZHk/LnRvdGFsRGF5cztcclxuICAgIGNvbnN0IGRheUluZGljYXRvciA9XHJcbiAgICAgIGN1cnJlbnREYXkgJiYgdG90YWxEYXlzID8gYERheSAke2N1cnJlbnREYXl9IG9mICR7dG90YWxEYXlzfWAgOiAnJztcclxuICAgIGNvbnN0IG5leHQgPSB0aGlzLnVwY29taW5nRXZlbnRzLnZhbHVlLm1hcCgoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKGV2ZW50LmV2ZW50SWQgIT09IGV2ZW50SWQpIHtcclxuICAgICAgICByZXR1cm4gZXZlbnQ7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICAuLi5ldmVudCxcclxuICAgICAgICBtZWV0aW5ncyxcclxuICAgICAgICAvLyBQYWdpbmF0b3IgbGVuZ3RoID0gY291bnQgb2YgdGhlIHVzZXIncyB0aWVkIHVwY29taW5nIG1lZXRpbmdzLlxyXG4gICAgICAgIG1lZXRpbmdQYWdlVG90YWw6IHRvdGFsUmVjb3JkcyxcclxuICAgICAgICBtZWV0aW5nQ291bnQ6IHRvdGFsTWVldGluZ0NvdW50LFxyXG4gICAgICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQsXHJcbiAgICAgICAgZGF5SW5kaWNhdG9yOiBkYXlJbmRpY2F0b3IgfHwgZXZlbnQuZGF5SW5kaWNhdG9yLFxyXG4gICAgICB9O1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLnVwY29taW5nRXZlbnRzLm5leHQobmV4dCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2FkcyB0aGUgdXNlcidzIGdyb3VwcywgZHJpdmluZyB0aGUgZ3JvdXBzIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICpcclxuICAgKiBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxHcm91cFJvd1tdPj59IFRoZSBncm91cHMgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkR3JvdXBzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPE15R3JvdXBzVmlldz4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAuZ2V0RGF0YShgJHt0aGlzLmFwaUJhc2VVcmx9L2dyb3Vwcy9teS1ncm91cHNgKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlOiBEYXNoYm9hcmRMaXN0UmVzcG9uc2U8TXlHcm91cHNWaWV3PikgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZ3JvdXBzID0gKHJlc3BvbnNlPy5ib2R5Py5ncm91cHMgPz8gW10pLm1hcCgoZ3JvdXApID0+XHJcbiAgICAgICAgICAgIHRoaXMubWFwR3JvdXAoZ3JvdXApXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHMubmV4dChncm91cHMpO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVSUk9SKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNYXBzIGEgYmFja2VuZCB7QGxpbmsgTXlHcm91cFZpZXd9IHRvIHRoZSB0YWJsZS1mYWNpbmcge0BsaW5rIEdyb3VwUm93fS5cclxuICAgKiBNaXJyb3JzIHRoZSBNeSBHcm91cHMgcHJvZmlsZSB0YWI6IHRoZSB0eXBlIGZhbGxzIGJhY2sgdG8gXCJVbmFzc2lnbmVkXCIgd2hlblxyXG4gICAqIGBncm91cFR5cGVOYW1lYCBpcyBudWxsLCBhZmZpbGlhdGlvbnMgYXJlIGNvbW1hLWpvaW5lZCwgZW1wdHkgb2ZmaWNlciByb2xlIC9cclxuICAgKiBhZmZpbGlhdGlvbiByZW5kZXIgYXMgYSBwbGFjZWhvbGRlciwgYW5kIGEgYmxhbmsgbWVtYmVyIGxldmVsIGJlY29tZXNcclxuICAgKiBcIlVuYXNzaWduZWRcIiAocmVuZGVyZWQgYXMgdGhlIHdhcm5pbmcgcGlsbCBieSB0aGUgWW91ciBHcm91cHMgY29tcG9uZW50KS5cclxuICAgKiBAcGFyYW0ge015R3JvdXBWaWV3fSBncm91cCAtIFRoZSBiYWNrZW5kIGdyb3VwIHZpZXcuXHJcbiAgICogQHJldHVybiB7R3JvdXBSb3d9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1hcEdyb3VwKGdyb3VwOiBNeUdyb3VwVmlldyk6IEdyb3VwUm93IHtcclxuICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybnMgb2ZmaWNlciByb2xlcyBhcyBhbiBgb2ZmaWNlcmAgYXJyYXkgb2ZcclxuICAgIC8vIHsgb2ZmaWNlcklkLCBvZmZpY2VyTmFtZSB9LiBKb2luIHRoZSBuYW1lcyBmb3IgdGhlIE9mZmljZXIgUm9sZSBjb2x1bW5cclxuICAgIC8vIChlLmcuIFwiQ2hhaXJcIiBvciBcIkNoYWlyLCBWaWNlIENoYWlyXCIpOyBzaG93IHRoZSBwbGFjZWhvbGRlciB3aGVuIGVtcHR5LlxyXG4gICAgY29uc3Qgb2ZmaWNlclJvbGUgPVxyXG4gICAgICAoZ3JvdXAub2ZmaWNlciA/PyBbXSlcclxuICAgICAgICAubWFwKChvZmZpY2VyKSA9PiBvZmZpY2VyPy5vZmZpY2VyTmFtZT8udHJpbSgpKVxyXG4gICAgICAgIC5maWx0ZXIoKG5hbWUpID0+ICEhbmFtZSlcclxuICAgICAgICAuam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBncm91cElkOiBncm91cC5ncm91cElkLFxyXG4gICAgICBncm91cDogZ3JvdXAuZ3JvdXBOYW1lLFxyXG4gICAgICB0eXBlOiBncm91cC5ncm91cFR5cGVOYW1lIHx8IGdyb3VwLmdyb3VwVHlwZSB8fCBVTkFTU0lHTkVEX0xBQkVMLFxyXG4gICAgICBvZmZpY2VyUm9sZSxcclxuICAgICAgYWZmaWxpYXRpb246IGdyb3VwLmFmZmlsaWF0aW9ucz8uam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRSxcclxuICAgICAgbWVtYmVyTGV2ZWw6IGdyb3VwLm1lbWJlckxldmVsPy50cmltKCkgfHwgVU5BU1NJR05FRF9MQUJFTCxcclxuICAgICAgLy8gQ2FycnkgdGhlIGFuY2VzdG9yIGhpZXJhcmNoeSB0aHJvdWdoIGZvciB0aGUgZXhwYW5kYWJsZSBoaWVyYXJjaHkgcm93cy5cclxuICAgICAgaGllcmFyY2h5OiBncm91cC5oaWVyYXJjaHkgPz8gW10sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dDogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9IHtcclxuICAgICAgLi4udGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLFxyXG4gICAgfTtcclxuICAgIGV2ZW50cy5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICAvLyBTdGFuZGFsb25lIG1lZXRpbmdzIGNhcnJ5IHRoZWlyIG93biBhdHRlbmRhbmNlIHN0YXRlIGtleWVkIGJ5IHRoZWlyIGlkXHJcbiAgICAgIC8vIChldmVudElkID09IG1lZXRpbmdJZCBmb3Igc3RhbmRhbG9uZSByb3dzKS5cclxuICAgICAgaWYgKGV2ZW50LmtpbmQgPT09IFVwY29taW5nSXRlbUtpbmQuU1RBTkRBTE9ORV9NRUVUSU5HICYmIGV2ZW50LmV2ZW50SWQpIHtcclxuICAgICAgICBuZXh0W2V2ZW50LmV2ZW50SWRdID1cclxuICAgICAgICAgIGV2ZW50LmF0dGVuZGFuY2VTdGF0ZSA/PyBBdHRlbmRhbmNlU3RhdGUuTk9UX0FUVEVORElORztcclxuICAgICAgfVxyXG4gICAgICAoZXZlbnQubWVldGluZ3MgPz8gW10pLmZvckVhY2goKG1lZXRpbmcpID0+IHtcclxuICAgICAgICBpZiAobWVldGluZy5tZWV0aW5nSWQpIHtcclxuICAgICAgICAgIG5leHRbbWVldGluZy5tZWV0aW5nSWRdID1cclxuICAgICAgICAgICAgbWVldGluZy5hdHRlbmRhbmNlU3RhdGUgPz8gQXR0ZW5kYW5jZVN0YXRlLk5PVF9BVFRFTkRJTkc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLm5leHQobmV4dCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZWVkcyB0aGUgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgZnJvbSBhIGxpc3Qgb2YgbWVldGluZyByb3dzLCB1c2luZyBlYWNoXHJcbiAgICogbWVldGluZydzIGBhdHRlbmRhbmNlU3RhdGVgIChkZWZhdWx0aW5nIHRvIGBOT1RfQVRURU5ESU5HYCkgd2l0aG91dFxyXG4gICAqIG92ZXJ3cml0aW5nIGlkcyBhYnNlbnQgZnJvbSB0aGUgbmV3IGxpc3QuIFNoYXJlZCBieSB0aGUgbGlzdCBsb2FkIGFuZCB0aGVcclxuICAgKiBwZXItZXZlbnQgZXhwYW5kIHNvIGZyZXNobHkgbG9hZGVkIGNoaWxkIG1lZXRpbmdzIHBpY2sgdXAgdGhlaXIgc3RhdGUuXHJcbiAgICogQHBhcmFtIHtNZWV0aW5nUm93W119IG1lZXRpbmdzIC0gVGhlIG1lZXRpbmcgcm93cyB0byBzZWVkIGZyb20uXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgc2VlZEF0dGVuZGFuY2VTdGF0ZXNGcm9tTWVldGluZ3MobWVldGluZ3M6IE1lZXRpbmdSb3dbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dDogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9IHtcclxuICAgICAgLi4udGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLFxyXG4gICAgfTtcclxuICAgIG1lZXRpbmdzLmZvckVhY2goKG1lZXRpbmcpID0+IHtcclxuICAgICAgaWYgKG1lZXRpbmcubWVldGluZ0lkKSB7XHJcbiAgICAgICAgbmV4dFttZWV0aW5nLm1lZXRpbmdJZF0gPVxyXG4gICAgICAgICAgbWVldGluZy5hdHRlbmRhbmNlU3RhdGUgPz9cclxuICAgICAgICAgIG5leHRbbWVldGluZy5tZWV0aW5nSWRdID8/XHJcbiAgICAgICAgICBBdHRlbmRhbmNlU3RhdGUuTk9UX0FUVEVORElORztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChuZXh0KTtcclxuICB9XHJcbn1cclxuIl19
@@ -1,9 +1,10 @@
1
1
  import { Injectable } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  /**
4
- * Permission identifiers (by name) that gate the dashboard attendance actions.
5
- * Mirrors the permission-type pattern used by the `events-and-meetings` and
6
- * `groups` user-permissions services.
4
+ * Permission display names that gate the dashboard attendance actions. These
5
+ * match the local demo mock. The real backend grants attendance capability via
6
+ * a permission id (see {@link ATTENDANCE_PERMISSION_IDS}) rather than these
7
+ * display names, so both are accepted.
7
8
  */
8
9
  /* eslint-disable no-unused-vars */
9
10
  export var DashboardPermissionType;
@@ -12,19 +13,32 @@ export var DashboardPermissionType;
12
13
  DashboardPermissionType["LEAVE_MEETING"] = "Leave Meeting";
13
14
  })(DashboardPermissionType || (DashboardPermissionType = {}));
14
15
  /* eslint-enable no-unused-vars */
16
+ /**
17
+ * Real backend permission ids that grant attendance capability. The attendance
18
+ * (log / leave) actions on the dashboard are gated by the same permission the
19
+ * `events-and-meetings` library uses for attendance — "View and Export
20
+ * Attendance" (`PERM_SAAPPS_VIEW_EXPORT_ATTENDANCE`).
21
+ */
22
+ const ATTENDANCE_PERMISSION_IDS = [
23
+ 'PERM_SAAPPS_VIEW_EXPORT_ATTENDANCE',
24
+ ];
15
25
  export class UserPermissionsService {
16
26
  /**
17
- * Returns access provision for the passed action/feature based on whether the signed in user has appropriate permission.
27
+ * Returns access provision for the passed action/feature based on whether the
28
+ * signed-in user has an appropriate permission — matched by the legacy display
29
+ * name (used by the local demo mock) OR by one of the real backend permission
30
+ * ids in {@link ATTENDANCE_PERMISSION_IDS}.
18
31
  * @param {DashboardPermissionType} permission
19
32
  * @param {UserPermission[]} userPermissions
20
33
  * @return {boolean}
21
34
  * @memberof UserPermissionsService
22
35
  */
23
36
  validateAccessPermission(permission, userPermissions) {
24
- const isPermitted = userPermissions?.length > 0
25
- ? userPermissions?.some(({ permissionName }) => permissionName === permission)
26
- : false;
27
- return isPermitted;
37
+ if (!(userPermissions?.length > 0)) {
38
+ return false;
39
+ }
40
+ return userPermissions.some(({ permissionName, permissionId }) => permissionName === permission ||
41
+ ATTENDANCE_PERMISSION_IDS.includes(permissionId));
28
42
  }
29
43
  /**
30
44
  * Maps the host-supplied user permissions to the attendance-action permissions consumed by the dashboard rows.
@@ -47,4 +61,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
47
61
  providedIn: 'root',
48
62
  }]
49
63
  }] });
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGFzaGJvYXJkL3NyYy9saWIvc2VydmljZXMvdXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSTNDOzs7O0dBSUc7QUFDSCxtQ0FBbUM7QUFDbkMsTUFBTSxDQUFOLElBQVksdUJBR1g7QUFIRCxXQUFZLHVCQUF1QjtJQUNqQyw0REFBaUMsQ0FBQTtJQUNqQywwREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBSFcsdUJBQXVCLEtBQXZCLHVCQUF1QixRQUdsQztBQUNELGtDQUFrQztBQUtsQyxNQUFNLE9BQU8sc0JBQXNCO0lBQ2pDOzs7Ozs7T0FNRztJQUNILHdCQUF3QixDQUN0QixVQUFtQyxFQUNuQyxlQUFpQztRQUVqQyxNQUFNLFdBQVcsR0FDZixlQUFlLEVBQUUsTUFBTSxHQUFHLENBQUM7WUFDekIsQ0FBQyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQ25CLENBQUMsRUFBRSxjQUFjLEVBQUUsRUFBRSxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsQ0FDdEQ7WUFDSCxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ1osT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZ0NBQWdDLENBQzlCLGVBQWlDO1FBRWpDLE9BQU87WUFDTCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQzdDLHVCQUF1QixDQUFDLGNBQWMsRUFDdEMsZUFBZSxDQUNoQjtZQUNELGVBQWUsRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQzVDLHVCQUF1QixDQUFDLGFBQWEsRUFDckMsZUFBZSxDQUNoQjtTQUNGLENBQUM7SUFDSixDQUFDOytHQXhDVSxzQkFBc0I7bUhBQXRCLHNCQUFzQixjQUZyQixNQUFNOzs0RkFFUCxzQkFBc0I7a0JBSGxDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBVc2VyUGVybWlzc2lvbiB9IGZyb20gJ0BpZWVlc2EtbnBtL21vZGVscyc7XHJcbmltcG9ydCB7IEF0dGVuZGFuY2VBY3Rpb25QZXJtaXNzaW9ucyB9IGZyb20gJy4uL21vZGVscy9hdHRlbmRhbmNlLWFjdGlvbi1wZXJtaXNzaW9ucy5tb2RlbCc7XHJcblxyXG4vKipcclxuICogUGVybWlzc2lvbiBpZGVudGlmaWVycyAoYnkgbmFtZSkgdGhhdCBnYXRlIHRoZSBkYXNoYm9hcmQgYXR0ZW5kYW5jZSBhY3Rpb25zLlxyXG4gKiBNaXJyb3JzIHRoZSBwZXJtaXNzaW9uLXR5cGUgcGF0dGVybiB1c2VkIGJ5IHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2AgYW5kXHJcbiAqIGBncm91cHNgIHVzZXItcGVybWlzc2lvbnMgc2VydmljZXMuXHJcbiAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5leHBvcnQgZW51bSBEYXNoYm9hcmRQZXJtaXNzaW9uVHlwZSB7XHJcbiAgTE9HX0FUVEVOREFOQ0UgPSAnTG9nIEF0dGVuZGFuY2UnLFxyXG4gIExFQVZFX01FRVRJTkcgPSAnTGVhdmUgTWVldGluZycsXHJcbn1cclxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFVzZXJQZXJtaXNzaW9uc1NlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgYWNjZXNzIHByb3Zpc2lvbiBmb3IgdGhlIHBhc3NlZCBhY3Rpb24vZmVhdHVyZSBiYXNlZCBvbiB3aGV0aGVyIHRoZSBzaWduZWQgaW4gdXNlciBoYXMgYXBwcm9wcmlhdGUgcGVybWlzc2lvbi5cclxuICAgKiBAcGFyYW0ge0Rhc2hib2FyZFBlcm1pc3Npb25UeXBlfSBwZXJtaXNzaW9uXHJcbiAgICogQHBhcmFtIHtVc2VyUGVybWlzc2lvbltdfSB1c2VyUGVybWlzc2lvbnNcclxuICAgKiBAcmV0dXJuIHtib29sZWFufVxyXG4gICAqIEBtZW1iZXJvZiBVc2VyUGVybWlzc2lvbnNTZXJ2aWNlXHJcbiAgICovXHJcbiAgdmFsaWRhdGVBY2Nlc3NQZXJtaXNzaW9uKFxyXG4gICAgcGVybWlzc2lvbjogRGFzaGJvYXJkUGVybWlzc2lvblR5cGUsXHJcbiAgICB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW11cclxuICApOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGlzUGVybWl0dGVkID1cclxuICAgICAgdXNlclBlcm1pc3Npb25zPy5sZW5ndGggPiAwXHJcbiAgICAgICAgPyB1c2VyUGVybWlzc2lvbnM/LnNvbWUoXHJcbiAgICAgICAgICAgICh7IHBlcm1pc3Npb25OYW1lIH0pID0+IHBlcm1pc3Npb25OYW1lID09PSBwZXJtaXNzaW9uXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgOiBmYWxzZTtcclxuICAgIHJldHVybiBpc1Blcm1pdHRlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hcHMgdGhlIGhvc3Qtc3VwcGxpZWQgdXNlciBwZXJtaXNzaW9ucyB0byB0aGUgYXR0ZW5kYW5jZS1hY3Rpb24gcGVybWlzc2lvbnMgY29uc3VtZWQgYnkgdGhlIGRhc2hib2FyZCByb3dzLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zXHJcbiAgICogQHJldHVybiB7QXR0ZW5kYW5jZUFjdGlvblBlcm1pc3Npb25zfVxyXG4gICAqIEBtZW1iZXJvZiBVc2VyUGVybWlzc2lvbnNTZXJ2aWNlXHJcbiAgICovXHJcbiAgbWFwVG9BdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMoXHJcbiAgICB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW11cclxuICApOiBBdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY2FuTG9nQXR0ZW5kYW5jZTogdGhpcy52YWxpZGF0ZUFjY2Vzc1Blcm1pc3Npb24oXHJcbiAgICAgICAgRGFzaGJvYXJkUGVybWlzc2lvblR5cGUuTE9HX0FUVEVOREFOQ0UsXHJcbiAgICAgICAgdXNlclBlcm1pc3Npb25zXHJcbiAgICAgICksXHJcbiAgICAgIGNhbkxlYXZlTWVldGluZzogdGhpcy52YWxpZGF0ZUFjY2Vzc1Blcm1pc3Npb24oXHJcbiAgICAgICAgRGFzaGJvYXJkUGVybWlzc2lvblR5cGUuTEVBVkVfTUVFVElORyxcclxuICAgICAgICB1c2VyUGVybWlzc2lvbnNcclxuICAgICAgKSxcclxuICAgIH07XHJcbiAgfVxyXG59XHJcbiJdfQ==
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGFzaGJvYXJkL3NyYy9saWIvc2VydmljZXMvdXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSTNDOzs7OztHQUtHO0FBQ0gsbUNBQW1DO0FBQ25DLE1BQU0sQ0FBTixJQUFZLHVCQUdYO0FBSEQsV0FBWSx1QkFBdUI7SUFDakMsNERBQWlDLENBQUE7SUFDakMsMERBQStCLENBQUE7QUFDakMsQ0FBQyxFQUhXLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFHbEM7QUFDRCxrQ0FBa0M7QUFFbEM7Ozs7O0dBS0c7QUFDSCxNQUFNLHlCQUF5QixHQUFzQjtJQUNuRCxvQ0FBb0M7Q0FDckMsQ0FBQztBQUtGLE1BQU0sT0FBTyxzQkFBc0I7SUFDakM7Ozs7Ozs7OztPQVNHO0lBQ0gsd0JBQXdCLENBQ3RCLFVBQW1DLEVBQ25DLGVBQWlDO1FBRWpDLElBQUksQ0FBQyxDQUFDLGVBQWUsRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDbEMsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUNELE9BQU8sZUFBZSxDQUFDLElBQUksQ0FDekIsQ0FBQyxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLENBQ25DLGNBQWMsS0FBSyxVQUFVO1lBQzdCLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FDbkQsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGdDQUFnQyxDQUM5QixlQUFpQztRQUVqQyxPQUFPO1lBQ0wsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLHdCQUF3QixDQUM3Qyx1QkFBdUIsQ0FBQyxjQUFjLEVBQ3RDLGVBQWUsQ0FDaEI7WUFDRCxlQUFlLEVBQUUsSUFBSSxDQUFDLHdCQUF3QixDQUM1Qyx1QkFBdUIsQ0FBQyxhQUFhLEVBQ3JDLGVBQWUsQ0FDaEI7U0FDRixDQUFDO0lBQ0osQ0FBQzsrR0E1Q1Usc0JBQXNCO21IQUF0QixzQkFBc0IsY0FGckIsTUFBTTs7NEZBRVAsc0JBQXNCO2tCQUhsQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVXNlclBlcm1pc3Npb24gfSBmcm9tICdAaWVlZXNhLW5wbS9tb2RlbHMnO1xyXG5pbXBvcnQgeyBBdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMgfSBmcm9tICcuLi9tb2RlbHMvYXR0ZW5kYW5jZS1hY3Rpb24tcGVybWlzc2lvbnMubW9kZWwnO1xyXG5cclxuLyoqXHJcbiAqIFBlcm1pc3Npb24gZGlzcGxheSBuYW1lcyB0aGF0IGdhdGUgdGhlIGRhc2hib2FyZCBhdHRlbmRhbmNlIGFjdGlvbnMuIFRoZXNlXHJcbiAqIG1hdGNoIHRoZSBsb2NhbCBkZW1vIG1vY2suIFRoZSByZWFsIGJhY2tlbmQgZ3JhbnRzIGF0dGVuZGFuY2UgY2FwYWJpbGl0eSB2aWFcclxuICogYSBwZXJtaXNzaW9uIGlkIChzZWUge0BsaW5rIEFUVEVOREFOQ0VfUEVSTUlTU0lPTl9JRFN9KSByYXRoZXIgdGhhbiB0aGVzZVxyXG4gKiBkaXNwbGF5IG5hbWVzLCBzbyBib3RoIGFyZSBhY2NlcHRlZC5cclxuICovXHJcbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXHJcbmV4cG9ydCBlbnVtIERhc2hib2FyZFBlcm1pc3Npb25UeXBlIHtcclxuICBMT0dfQVRURU5EQU5DRSA9ICdMb2cgQXR0ZW5kYW5jZScsXHJcbiAgTEVBVkVfTUVFVElORyA9ICdMZWF2ZSBNZWV0aW5nJyxcclxufVxyXG4vKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC12YXJzICovXHJcblxyXG4vKipcclxuICogUmVhbCBiYWNrZW5kIHBlcm1pc3Npb24gaWRzIHRoYXQgZ3JhbnQgYXR0ZW5kYW5jZSBjYXBhYmlsaXR5LiBUaGUgYXR0ZW5kYW5jZVxyXG4gKiAobG9nIC8gbGVhdmUpIGFjdGlvbnMgb24gdGhlIGRhc2hib2FyZCBhcmUgZ2F0ZWQgYnkgdGhlIHNhbWUgcGVybWlzc2lvbiB0aGVcclxuICogYGV2ZW50cy1hbmQtbWVldGluZ3NgIGxpYnJhcnkgdXNlcyBmb3IgYXR0ZW5kYW5jZSDigJQgXCJWaWV3IGFuZCBFeHBvcnRcclxuICogQXR0ZW5kYW5jZVwiIChgUEVSTV9TQUFQUFNfVklFV19FWFBPUlRfQVRURU5EQU5DRWApLlxyXG4gKi9cclxuY29uc3QgQVRURU5EQU5DRV9QRVJNSVNTSU9OX0lEUzogcmVhZG9ubHkgc3RyaW5nW10gPSBbXHJcbiAgJ1BFUk1fU0FBUFBTX1ZJRVdfRVhQT1JUX0FUVEVOREFOQ0UnLFxyXG5dO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFVzZXJQZXJtaXNzaW9uc1NlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgYWNjZXNzIHByb3Zpc2lvbiBmb3IgdGhlIHBhc3NlZCBhY3Rpb24vZmVhdHVyZSBiYXNlZCBvbiB3aGV0aGVyIHRoZVxyXG4gICAqIHNpZ25lZC1pbiB1c2VyIGhhcyBhbiBhcHByb3ByaWF0ZSBwZXJtaXNzaW9uIOKAlCBtYXRjaGVkIGJ5IHRoZSBsZWdhY3kgZGlzcGxheVxyXG4gICAqIG5hbWUgKHVzZWQgYnkgdGhlIGxvY2FsIGRlbW8gbW9jaykgT1IgYnkgb25lIG9mIHRoZSByZWFsIGJhY2tlbmQgcGVybWlzc2lvblxyXG4gICAqIGlkcyBpbiB7QGxpbmsgQVRURU5EQU5DRV9QRVJNSVNTSU9OX0lEU30uXHJcbiAgICogQHBhcmFtIHtEYXNoYm9hcmRQZXJtaXNzaW9uVHlwZX0gcGVybWlzc2lvblxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zXHJcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cclxuICAgKiBAbWVtYmVyb2YgVXNlclBlcm1pc3Npb25zU2VydmljZVxyXG4gICAqL1xyXG4gIHZhbGlkYXRlQWNjZXNzUGVybWlzc2lvbihcclxuICAgIHBlcm1pc3Npb246IERhc2hib2FyZFBlcm1pc3Npb25UeXBlLFxyXG4gICAgdXNlclBlcm1pc3Npb25zOiBVc2VyUGVybWlzc2lvbltdXHJcbiAgKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoISh1c2VyUGVybWlzc2lvbnM/Lmxlbmd0aCA+IDApKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VyUGVybWlzc2lvbnMuc29tZShcclxuICAgICAgKHsgcGVybWlzc2lvbk5hbWUsIHBlcm1pc3Npb25JZCB9KSA9PlxyXG4gICAgICAgIHBlcm1pc3Npb25OYW1lID09PSBwZXJtaXNzaW9uIHx8XHJcbiAgICAgICAgQVRURU5EQU5DRV9QRVJNSVNTSU9OX0lEUy5pbmNsdWRlcyhwZXJtaXNzaW9uSWQpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWFwcyB0aGUgaG9zdC1zdXBwbGllZCB1c2VyIHBlcm1pc3Npb25zIHRvIHRoZSBhdHRlbmRhbmNlLWFjdGlvbiBwZXJtaXNzaW9ucyBjb25zdW1lZCBieSB0aGUgZGFzaGJvYXJkIHJvd3MuXHJcbiAgICogQHBhcmFtIHtVc2VyUGVybWlzc2lvbltdfSB1c2VyUGVybWlzc2lvbnNcclxuICAgKiBAcmV0dXJuIHtBdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnN9XHJcbiAgICogQG1lbWJlcm9mIFVzZXJQZXJtaXNzaW9uc1NlcnZpY2VcclxuICAgKi9cclxuICBtYXBUb0F0dGVuZGFuY2VBY3Rpb25QZXJtaXNzaW9ucyhcclxuICAgIHVzZXJQZXJtaXNzaW9uczogVXNlclBlcm1pc3Npb25bXVxyXG4gICk6IEF0dGVuZGFuY2VBY3Rpb25QZXJtaXNzaW9ucyB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBjYW5Mb2dBdHRlbmRhbmNlOiB0aGlzLnZhbGlkYXRlQWNjZXNzUGVybWlzc2lvbihcclxuICAgICAgICBEYXNoYm9hcmRQZXJtaXNzaW9uVHlwZS5MT0dfQVRURU5EQU5DRSxcclxuICAgICAgICB1c2VyUGVybWlzc2lvbnNcclxuICAgICAgKSxcclxuICAgICAgY2FuTGVhdmVNZWV0aW5nOiB0aGlzLnZhbGlkYXRlQWNjZXNzUGVybWlzc2lvbihcclxuICAgICAgICBEYXNoYm9hcmRQZXJtaXNzaW9uVHlwZS5MRUFWRV9NRUVUSU5HLFxyXG4gICAgICAgIHVzZXJQZXJtaXNzaW9uc1xyXG4gICAgICApLFxyXG4gICAgfTtcclxuICB9XHJcbn1cclxuIl19