@tsi-developpement/tsi-shared-ui 1.9.11 → 1.9.13

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.
@@ -3,19 +3,26 @@ import { firstValueFrom } from 'rxjs';
3
3
  import { LocalizationKeys } from '../../consts/localization-key';
4
4
  import { defaultCardHeader } from '../../consts/tsi-consts';
5
5
  import { AppBaseComponent } from '../../tsi-base/components/app-base/app-base.component';
6
+ import { DisplayTypes } from '../../enums/display-types';
6
7
  import * as i0 from "@angular/core";
7
8
  import * as i1 from "../../services/configuration/entity-configuration.service";
8
9
  import * as i2 from "../../pipes/localize.pipe";
9
10
  import * as i3 from "../../services/status/entityStatus.service";
10
11
  import * as i4 from "../../services/notification/tsi-notification.service";
11
- import * as i5 from "@angular/common";
12
- import * as i6 from "primeng/button";
13
- import * as i7 from "primeng/api";
14
- import * as i8 from "primeng/menu";
15
- import * as i9 from "primeng/paginator";
16
- import * as i10 from "primeng/badge";
17
- import * as i11 from "../button-components/tsi-button/tsi-button.component";
18
- import * as i12 from "../spinner/spinner.component";
12
+ import * as i5 from "../../services/status/status-color.service";
13
+ import * as i6 from "@angular/common";
14
+ import * as i7 from "primeng/button";
15
+ import * as i8 from "primeng/api";
16
+ import * as i9 from "primeng/menu";
17
+ import * as i10 from "primeng/paginator";
18
+ import * as i11 from "primeng/badge";
19
+ import * as i12 from "../output-components/tsi-currency-other-display/tsi-currency-other-display.component";
20
+ import * as i13 from "../output-components/tsi-currency-societe-display/tsi-currency-societe-display.component";
21
+ import * as i14 from "../output-components/tsi-decimal-display/tsi-decimal-display.component";
22
+ import * as i15 from "../output-components/tsi-integer-display/tsi-integer-display.component";
23
+ import * as i16 from "../output-components/tsi-rate-display/tsi-rate-display.component";
24
+ import * as i17 from "../button-components/tsi-button/tsi-button.component";
25
+ import * as i18 from "../spinner/spinner.component";
19
26
  /**
20
27
  * TsiKanbanComponent
21
28
  * Description: Displays a Kanban board view for TSI entities.
@@ -26,13 +33,28 @@ export class TsiKanbanComponent extends AppBaseComponent {
26
33
  this.handlePageChange(value);
27
34
  }
28
35
  get page() { return this._page; }
29
- constructor(cdr, _entityConfig, _localize, _entityStatusService, _notificationService) {
36
+ constructor(cdr, _entityConfig, _localize, _entityStatusService, _notificationService, _statusColorService) {
30
37
  super();
31
38
  this.cdr = cdr;
32
39
  this._entityConfig = _entityConfig;
33
40
  this._localize = _localize;
34
41
  this._entityStatusService = _entityStatusService;
35
42
  this._notificationService = _notificationService;
43
+ this._statusColorService = _statusColorService;
44
+ this._statusLessRecords = {
45
+ key: 'new',
46
+ localized: 'new'
47
+ };
48
+ this._statusLabels = [];
49
+ this._defaultPage = {
50
+ items: [],
51
+ pageSize: 10,
52
+ pageNumber: 1,
53
+ totalCount: 0,
54
+ totalPages: 0,
55
+ summaries: [],
56
+ loading: false,
57
+ };
36
58
  this.buttonClicked = new EventEmitter();
37
59
  this.callSearch = new EventEmitter();
38
60
  this.overflowActionsMenu = [];
@@ -40,8 +62,18 @@ export class TsiKanbanComponent extends AppBaseComponent {
40
62
  this.overflowActionColumns = [];
41
63
  this.selectKeyOnly = true;
42
64
  this.key = 'uid';
65
+ // Columns whose per-column summary should be displayed in the Kanban header, formatted
66
+ // by their display type (like the table footer). Empty by default → no summaries shown.
67
+ this.summaryColumns = [];
68
+ this.displayTypes = DisplayTypes;
69
+ this._page = this._defaultPage;
43
70
  this.cards = [];
44
71
  this.cardMapByStatus = new Map();
72
+ // Populated only when the page is grouped server-side (one group per status):
73
+ // true per-column totals and per-column summaries, independent of the current page.
74
+ this.countByStatus = new Map();
75
+ this.summaryByStatus = new Map();
76
+ this._isGrouped = false;
45
77
  this.draggedCard = null;
46
78
  this.first = 0;
47
79
  this.rows = 10;
@@ -49,15 +81,14 @@ export class TsiKanbanComponent extends AppBaseComponent {
49
81
  this.isLoading = false;
50
82
  this.originalStatus = '';
51
83
  this.localizedStatusLabels = [];
52
- this.localizedStatusLabels = [
53
- {
54
- key: 'new',
55
- localized: this._localize.transform('gesc_param_article_statut_enums_new').trim()
56
- }
57
- ];
58
84
  }
59
85
  async ngOnInit() {
60
86
  await this.getBusinessClassStatus(this.cardBusinessClass);
87
+ // Colors are page-independent, so resolve them once up front. entityInfo carries the
88
+ // status enum name (the 2nd lookup key); getEntityInfoFromCache is cached, so the later
89
+ // mapItemsToCards calls reuse it.
90
+ await this.getEntityInfo();
91
+ this.loadStatusColors();
61
92
  this.page$.subscribe(async (page) => {
62
93
  if (page) {
63
94
  this.isLoading = !!page.loading;
@@ -102,6 +133,12 @@ export class TsiKanbanComponent extends AppBaseComponent {
102
133
  this.draggedCard = null;
103
134
  this.updateCardMap();
104
135
  this.isLoading = false;
136
+ // Grouped headers (true totals + summaries) come from the server, so a
137
+ // client-side re-bucket can't refresh them. Re-fetch the current grouped
138
+ // page for authoritative figures (also reflects any concurrent changes).
139
+ if (this._isGrouped) {
140
+ this.callSearch.emit({ skipCount: this.first, maxResultCount: this.rows });
141
+ }
105
142
  },
106
143
  error: (error) => {
107
144
  let from = this._localize.transform("gesc_param_error_switch_status_from");
@@ -131,9 +168,35 @@ export class TsiKanbanComponent extends AppBaseComponent {
131
168
  this.rows = event.rows ?? 10;
132
169
  this.callSearch.emit({ skipCount: this.first, maxResultCount: this.rows });
133
170
  }
134
- getStatusClass(card) {
135
- const index = this.localizedStatusLabels.findIndex(l => l.key === card.status);
136
- return `status-${index >= 0 ? index : 'default'}`;
171
+ // Fetch the defined colors for this entity's statuses once. Skips when the business class
172
+ // or its status enum is unknown; on error columns simply keep their default background.
173
+ loadStatusColors() {
174
+ const className = this.cardBusinessClass;
175
+ const statusEnumName = this.entityInfo?.statusEnumName;
176
+ if (!className || !statusEnumName)
177
+ return;
178
+ this._statusColorService.getStatusColorDetails(className, statusEnumName).subscribe({
179
+ next: (response) => {
180
+ this.statusMetadata = response;
181
+ this.cdr.markForCheck();
182
+ },
183
+ error: err => {
184
+ console.error('Error loading status colors', err);
185
+ }
186
+ });
187
+ }
188
+ // Resolve the defined hex for a status value (column/card key). Undefined when no color is
189
+ // defined (or the status has no matching option, e.g. the synthetic 'new' bucket).
190
+ getStatusColorHex(statusKey) {
191
+ if (!statusKey)
192
+ return undefined;
193
+ return this.statusMetadata?.options.find(o => o.statusValue === statusKey)?.colorHex || undefined;
194
+ }
195
+ // The single colored element: a left accent bar on the column header, in the real status color.
196
+ // Transparent (invisible, width reserved) when no color is defined. Nothing else is tinted —
197
+ // not the header background, not the header text, not the cards.
198
+ getColumnAccentColor(statusKey) {
199
+ return this.getStatusColorHex(statusKey) ?? 'transparent';
137
200
  }
138
201
  getLocalizedStatus(key) {
139
202
  if (!key)
@@ -141,13 +204,81 @@ export class TsiKanbanComponent extends AppBaseComponent {
141
204
  const match = this.localizedStatusLabels.find(s => s.key === key);
142
205
  return match?.localized ?? key;
143
206
  }
207
+ // True per-column total: the group's unpaged count when grouped server-side,
208
+ // otherwise the number of cards on the current page (legacy client-side grouping).
209
+ getColumnCount(statusKey) {
210
+ if (this._isGrouped) {
211
+ return this.countByStatus.get(statusKey) ?? 0;
212
+ }
213
+ return this.cardMapByStatus.get(statusKey)?.length ?? 0;
214
+ }
215
+ // Whether per-column summaries should render (grouped data + at least one opted-in column).
216
+ get hasColumnSummaries() {
217
+ return this._isGrouped && (this.summaryColumns?.length ?? 0) > 0;
218
+ }
219
+ // The SUM for a summarized column within a status group (undefined when not grouped or absent).
220
+ getColumnSummaryValue(statusKey, field) {
221
+ if (!this._isGrouped) {
222
+ return undefined;
223
+ }
224
+ const match = this.summaryByStatus.get(statusKey)
225
+ ?.find(s => s.proprety?.toLowerCase() === field?.toLowerCase());
226
+ return match?.summary;
227
+ }
144
228
  async handlePageChange(page) {
229
+ if (page?.groups) {
230
+ await this.handleGroupedPage(page);
231
+ return;
232
+ }
145
233
  if (!page?.items)
146
234
  return;
235
+ this._isGrouped = false;
147
236
  this.cards = await this.mapItemsToCards(page.items);
148
237
  this.totalCount = page.totalCount;
149
238
  this.updateCardMap();
150
239
  }
240
+ // Server-side grouped page: one group per status, each carrying its own accurate
241
+ // (unpaged) total count and summaries. Cards on the current page are mapped and
242
+ // bucketed exactly as in the flat path (via updateCardMap); the true per-column
243
+ // counts/summaries come from the groups, and the single board paginator spans the
244
+ // largest column (same skip/take window applied to every group by the backend).
245
+ async handleGroupedPage(page) {
246
+ const groups = page.groups ?? [];
247
+ const validKeys = this._statusLabels.map(s => s.key);
248
+ const counts = new Map();
249
+ const summaries = new Map();
250
+ let maxGroupTotal = 0;
251
+ for (const group of groups) {
252
+ const rawKey = group.key?.trim();
253
+ const bucketKey = rawKey && validKeys.includes(rawKey)
254
+ ? rawKey
255
+ : this._statusLessRecords.key;
256
+ counts.set(bucketKey, (counts.get(bucketKey) ?? 0) + group.totalCount);
257
+ if (!summaries.has(bucketKey)) {
258
+ summaries.set(bucketKey, group.summaries ?? []);
259
+ }
260
+ maxGroupTotal = Math.max(maxGroupTotal, group.totalCount);
261
+ }
262
+ // Data shrank under a later page (drag-drop, a filter, or another user's change):
263
+ // the current offset is now past the end of every column, so the backend returned an
264
+ // empty window and the board would look empty until the user manually pages back.
265
+ // Clamp to the last valid page and re-fetch once. Guarded by first > 0 so a legitimately
266
+ // empty result on the first page can't loop; the clamp target is always < maxGroupTotal,
267
+ // so the re-fetch lands on a populated page and this branch won't re-trigger.
268
+ if (this.first > 0 && this.first >= maxGroupTotal) {
269
+ this.first = maxGroupTotal > 0
270
+ ? Math.floor((maxGroupTotal - 1) / this.rows) * this.rows
271
+ : 0;
272
+ this.callSearch.emit({ skipCount: this.first, maxResultCount: this.rows });
273
+ return;
274
+ }
275
+ this._isGrouped = true;
276
+ this.countByStatus = counts;
277
+ this.summaryByStatus = summaries;
278
+ this.totalCount = maxGroupTotal;
279
+ this.cards = await this.mapItemsToCards(groups.flatMap(g => g.items ?? []));
280
+ this.updateCardMap();
281
+ }
151
282
  async getEntityInfo() {
152
283
  this.entityInfo = await this._entityConfig.getEntityInfoFromCache(this.cardBusinessClass);
153
284
  }
@@ -163,7 +294,7 @@ export class TsiKanbanComponent extends AppBaseComponent {
163
294
  async mapItemsToCards(items) {
164
295
  await this.getEntityInfo();
165
296
  const { col1, col2, col3, photo, status } = this.getColKeys();
166
- const validKeys = this.localizedStatusLabels.map(s => s.key);
297
+ const validKeys = this._statusLabels.map(s => s.key);
167
298
  this.originalStatus = status;
168
299
  return items.map((item, index) => {
169
300
  const keys = Object.keys(item).reduce((acc, key) => {
@@ -186,6 +317,15 @@ export class TsiKanbanComponent extends AppBaseComponent {
186
317
  });
187
318
  }
188
319
  updateCardMap() {
320
+ // Show the status-less column only when at least one card is in the 'new' bucket
321
+ // (a record with an empty or unrecognized status). Recomputed here so the column
322
+ // set stays consistent after both page changes and drag-and-drop moves.
323
+ const hasStatusLess = this._isGrouped
324
+ ? (this.countByStatus.get(this._statusLessRecords.key) ?? 0) > 0
325
+ : this.cards.some(c => c.status === this._statusLessRecords.key);
326
+ this.localizedStatusLabels = hasStatusLess
327
+ ? [this._statusLessRecords, ...this._statusLabels]
328
+ : [...this._statusLabels];
189
329
  const map = new Map();
190
330
  for (const label of this.localizedStatusLabels) {
191
331
  map.set(label.key, []);
@@ -208,13 +348,11 @@ export class TsiKanbanComponent extends AppBaseComponent {
208
348
  async getBusinessClassStatus(className) {
209
349
  const response = await firstValueFrom(this._entityStatusService.getEntityStatus(className));
210
350
  const statuses = response?.entityStatus ?? [];
211
- this.localizedStatusLabels = [
212
- { key: 'new', localized: this._localize.transform('gesc_param_article_statut_enums_new').trim() },
213
- ...statuses.map((s) => ({
214
- key: s.key,
215
- localized: this._localize.transform(s.value).trim()
216
- }))
217
- ];
351
+ this._statusLessRecords.localized = this._localize.transform('gesc_param_article_statut_enums_new').trim();
352
+ this._statusLabels = statuses.map((s) => ({
353
+ key: s.key,
354
+ localized: this._localize.transform(s.value).trim()
355
+ }));
218
356
  }
219
357
  getOverflowMenuModel() {
220
358
  if (!this.hasOverflowActions) {
@@ -254,13 +392,13 @@ export class TsiKanbanComponent extends AppBaseComponent {
254
392
  openModalComponent(uid, mode) {
255
393
  this.buttonClicked.emit({ field: mode, key: uid, selectKeyOnly: true });
256
394
  }
257
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiKanbanComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.EntityConfigurationService }, { token: i2.LocalizePipe }, { token: i3.EntityStatusService }, { token: i4.TsiNotificationService }], target: i0.ɵɵFactoryTarget.Component }); }
258
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiKanbanComponent, selector: "Tsi-kanban", inputs: { cardBusinessClass: "cardBusinessClass", header: "header", id: "id", page$: "page$", crudService: "crudService", overflowActionsMenu: "overflowActionsMenu", selectKeyOnly: "selectKeyOnly", key: "key", page: "page" }, outputs: { buttonClicked: "buttonClicked", callSearch: "callSearch" }, usesInheritance: true, ngImport: i0, template: "<div class=\"card flex justify-content-center\">\r\n <p-paginator [first]=\"first\" [rows]=\"rows\" [totalRecords]=\"totalCount\" [rowsPerPageOptions]=\"[1, 10, 25, 50]\"\r\n (onPageChange)=\"onPageChange($event)\" [showCurrentPageReport]=\"true\"\r\n currentPageReportTemplate=\"{{ 'Showing' | localize }} {first} {{'to' | localize}} {last} {{ 'of' | localize }} {totalRecords}\">\r\n </p-paginator>\r\n</div>\r\n\r\n<div class=\"kanban-board flex gap-4 overflow-auto\">\r\n <div *ngFor=\"let status of localizedStatusLabels; trackBy: trackByStatus\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\" (dragover)=\"allowDrop($event)\"\r\n (drop)=\"drop($event, status.key)\">\r\n\r\n <div class=\"column-header p-3 border-bottom-1 surface-border font-semibold\">\r\n {{ status.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ cardMapByStatus.get(status.key)?.length || 0 }})\r\n </span>\r\n </div>\r\n\r\n <div class=\"column-cards flex-1 overflow-auto p-3\">\r\n <div *ngFor=\"let card of cardMapByStatus.get(status.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\"\r\n [ngClass]=\"getStatusClass(card)\"\r\n draggable=\"true\"\r\n (dragstart)=\"dragStart($event, card)\" \r\n (dragend)=\"dragEnd()\">\r\n\r\n <div class=\"font-bold mb-2\">{{ card.headerTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.subHeaderTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.description }}</div>\r\n <p-menu appendTo=\"body\" #menuMoreActions \r\n [model]=\"overflowActionsMenu\" \r\n [popup]=\"true\" styleClass=\"overflow-menu\"\r\n [style]=\"{ 'width': 'auto', 'min-width': '0px' }\">\r\n <ng-template pTemplate=\"item\" let-menuItem>\r\n <a pRipple class=\"flex align-items-center p-menuitem-link\" \r\n [ngClass]=\"menuItem.styleClass\"\r\n (click)=\"onOverflowActionClicked(card, menuItem)\">\r\n <i *ngIf=\"menuItem.id === 'notes'\" class=\"{{ menuItem.iconClass }} p-menuitem-icon badge-icon has-badge\"\r\n [ngClass]=\"menuItem.iconStyleClass\" pBadge severity=\"danger\" \r\n [value]=\"card.fullRecord.notesCount\"\r\n [badgeDisabled]=\"card.fullRecord.notesCount == null\" badgePosition=\"top-right\">\r\n </i>\r\n\r\n <i *ngIf=\"menuItem.id !== 'notes'\" class=\"{{menuItem.iconClass}} p-menuitem-icon\"\r\n [ngClass]=\"menuItem.iconStyleClass\">\r\n </i>\r\n\r\n <span class=\"menu-label\">\r\n {{ menuItem.label | localize }}\r\n </span>\r\n </a>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <div class=\"flex justify-content-end align-items-center mt-1 gap-2 p-0\">\r\n <Tsi-Button [styleClass]=\"'p-button-rounded p-button-text p-0-5'\" type=\"button\" icon=\"pi pi-pencil\"\r\n (click)=\"edit(card.uid)\">\r\n </Tsi-Button>\r\n <p-button type=\"button\" icon=\"pi pi-ellipsis-v\" styleClass=\"overflow-btn\"\r\n (onClick)=\"overflowColumnClicked(menuMoreActions, $event, card)\">\r\n </p-button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"overlay\" *ngIf=\"isLoading\">\r\n <div class=\"spinner-wrapper\">\r\n <app-spinner></app-spinner>\r\n </div>\r\n </div>", styles: [":host{display:block;padding:1rem}[draggable=true]{-webkit-user-select:none;user-select:none}.kanban-board{height:calc(100vh - 100px);padding:1rem}.kanban-column{width:300px;max-height:100%;display:flex;flex-direction:column;background-color:#f8f9fa}.column-header{font-size:1rem;font-weight:700;background-color:#fff;border-radius:6px 6px 0 0}.column-cards{overflow-y:auto;flex:1}.kanban-card{border-left:4px solid;cursor:move;transition:border-color .3s ease}.status-0{border-left-color:#7269ef}.status-1{border-left-color:#00c853}.status-2{border-left-color:#ffab00}.status-3{border-left-color:#d50000}[class*=status-]{border-left-style:solid;border-left-width:4px}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i7.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i8.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "component", type: i9.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "directive", type: i10.BadgeDirective, selector: "[pBadge]", inputs: ["badgeDisabled", "badgeSize", "size", "severity", "value", "badgeStyle", "badgeStyleClass"] }, { kind: "component", type: i11.TsiButtonComponent, selector: "Tsi-Button", inputs: ["disabled", "text", "style", "tooltipText", "tooltipPosition", "buttonType", "icon", "styleClass", "iconSrc", "id", "iconWidth", "iconClass"], outputs: ["onClick", "rightClick"] }, { kind: "component", type: i12.SpinnerComponent, selector: "app-spinner" }, { kind: "pipe", type: i2.LocalizePipe, name: "localize" }] }); }
395
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiKanbanComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.EntityConfigurationService }, { token: i2.LocalizePipe }, { token: i3.EntityStatusService }, { token: i4.TsiNotificationService }, { token: i5.StatusColorService }], target: i0.ɵɵFactoryTarget.Component }); }
396
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiKanbanComponent, selector: "Tsi-kanban", inputs: { cardBusinessClass: "cardBusinessClass", header: "header", id: "id", page$: "page$", crudService: "crudService", overflowActionsMenu: "overflowActionsMenu", selectKeyOnly: "selectKeyOnly", key: "key", summaryColumns: "summaryColumns", page: "page" }, outputs: { buttonClicked: "buttonClicked", callSearch: "callSearch" }, usesInheritance: true, ngImport: i0, template: "<div class=\"card flex justify-content-center\">\r\n <p-paginator [first]=\"first\" [rows]=\"rows\" [totalRecords]=\"totalCount\" [rowsPerPageOptions]=\"[1, 10, 25, 50]\"\r\n (onPageChange)=\"onPageChange($event)\" [showCurrentPageReport]=\"true\"\r\n currentPageReportTemplate=\"{{ 'Showing' | localize }} {first} {{'to' | localize}} {last} {{ 'of' | localize }} {totalRecords}\">\r\n </p-paginator>\r\n</div>\r\n\r\n<div class=\"kanban-board flex gap-4 overflow-auto\">\r\n <div *ngFor=\"let status of localizedStatusLabels; trackBy: trackByStatus\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\" (dragover)=\"allowDrop($event)\"\r\n (drop)=\"drop($event, status.key)\">\r\n\r\n <div class=\"column-header p-3 font-semibold\"\r\n [style.border-left-color]=\"getColumnAccentColor(status.key)\">\r\n {{ status.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ getColumnCount(status.key) }})\r\n </span>\r\n <div class=\"text-xs font-normal text-gray-500\" *ngIf=\"hasColumnSummaries\">\r\n <div *ngFor=\"let sumCol of summaryColumns\" class=\"flex align-items-center gap-1\">\r\n <span>{{ (sumCol.header ?? sumCol.field) | localize }}:</span>\r\n <ng-container [ngSwitch]=\"sumCol.type\">\r\n <Tsi-Currency-Societe-Display *ngSwitchCase=\"displayTypes.CURRENCY_SOCIETE_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Currency-Societe-Display>\r\n <Tsi-Integer-Display *ngSwitchCase=\"displayTypes.INTEGER_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Integer-Display>\r\n <Tsi-Rate-Display *ngSwitchCase=\"displayTypes.RATE_DISPLAY\"\r\n [isFraction]=\"sumCol.isFraction ?? false\" [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Rate-Display>\r\n <Tsi-Decimal-Display *ngSwitchCase=\"displayTypes.DECIMAL_DISPLAY\"\r\n [formatDecimal]=\"sumCol.formatDecimal\" [numOfDecimal]=\"sumCol.numOfDecimal\"\r\n [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Decimal-Display>\r\n <Tsi-Currency-Other-Display *ngSwitchCase=\"displayTypes.CURRENCY_OTHER_DISPLAY\"\r\n [currency]=\"sumCol.currencyOtherCode\" [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Currency-Other-Display>\r\n <span *ngSwitchDefault>{{ getColumnSummaryValue(status.key, sumCol.field) }}</span>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"column-cards flex-1 overflow-auto p-3\">\r\n <div *ngFor=\"let card of cardMapByStatus.get(status.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\"\r\n draggable=\"true\"\r\n (dragstart)=\"dragStart($event, card)\" \r\n (dragend)=\"dragEnd()\">\r\n\r\n <div class=\"font-bold mb-2\">{{ card.headerTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.subHeaderTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.description }}</div>\r\n <p-menu appendTo=\"body\" #menuMoreActions \r\n [model]=\"overflowActionsMenu\" \r\n [popup]=\"true\" styleClass=\"overflow-menu\"\r\n [style]=\"{ 'width': 'auto', 'min-width': '0px' }\">\r\n <ng-template pTemplate=\"item\" let-menuItem>\r\n <a pRipple class=\"flex align-items-center p-menuitem-link\" \r\n [ngClass]=\"menuItem.styleClass\"\r\n (click)=\"onOverflowActionClicked(card, menuItem)\">\r\n <i *ngIf=\"menuItem.id === 'notes'\" class=\"{{ menuItem.iconClass }} p-menuitem-icon badge-icon has-badge\"\r\n [ngClass]=\"menuItem.iconStyleClass\" pBadge severity=\"danger\" \r\n [value]=\"card.fullRecord.notesCount\"\r\n [badgeDisabled]=\"card.fullRecord.notesCount == null\" badgePosition=\"top-right\">\r\n </i>\r\n\r\n <i *ngIf=\"menuItem.id !== 'notes'\" class=\"{{menuItem.iconClass}} p-menuitem-icon\"\r\n [ngClass]=\"menuItem.iconStyleClass\">\r\n </i>\r\n\r\n <span class=\"menu-label\">\r\n {{ menuItem.label | localize }}\r\n </span>\r\n </a>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <div class=\"flex justify-content-end align-items-center mt-1 gap-2 p-0\">\r\n <Tsi-Button [styleClass]=\"'p-button-rounded p-button-text p-0-5'\" type=\"button\" icon=\"pi pi-pencil\"\r\n (click)=\"edit(card.uid)\">\r\n </Tsi-Button>\r\n <p-button type=\"button\" icon=\"pi pi-ellipsis-v\" styleClass=\"overflow-btn\"\r\n (onClick)=\"overflowColumnClicked(menuMoreActions, $event, card)\">\r\n </p-button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"overlay\" *ngIf=\"isLoading\">\r\n <div class=\"spinner-wrapper\">\r\n <app-spinner></app-spinner>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:block;padding:1rem}[draggable=true]{-webkit-user-select:none;user-select:none}.kanban-board{height:calc(100vh - 100px);padding:1rem}.kanban-column{width:300px;max-height:100%;display:flex;flex-direction:column;background-color:#f8f9fa}.column-header{font-size:1rem;font-weight:700;background-color:#fff;border-radius:6px 6px 0 0;border-bottom:1px solid var(--surface-border);border-left:.75rem solid transparent;transition:border-color .3s ease}.column-cards{overflow-y:auto;flex:1}.kanban-card{cursor:move}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i9.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "component", type: i10.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "directive", type: i11.BadgeDirective, selector: "[pBadge]", inputs: ["badgeDisabled", "badgeSize", "size", "severity", "value", "badgeStyle", "badgeStyleClass"] }, { kind: "component", type: i12.TsiCurrencyOtherDisplayComponent, selector: "Tsi-Currency-Other-Display", inputs: ["inputData", "currency"] }, { kind: "component", type: i13.TsiCurrencySocieteDisplayComponent, selector: "Tsi-Currency-Societe-Display", inputs: ["inputData"] }, { kind: "component", type: i14.TsiDecimalDisplayComponent, selector: "Tsi-Decimal-Display", inputs: ["inputData", "formatDecimal", "numOfDecimal"] }, { kind: "component", type: i15.TsiIntegerDisplayComponent, selector: "Tsi-Integer-Display", inputs: ["inputData"] }, { kind: "component", type: i16.TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: ["isFraction", "inputData", "numOfDecimal"] }, { kind: "component", type: i17.TsiButtonComponent, selector: "Tsi-Button", inputs: ["disabled", "text", "style", "tooltipText", "tooltipPosition", "buttonType", "icon", "styleClass", "iconSrc", "id", "iconWidth", "iconClass"], outputs: ["onClick", "rightClick"] }, { kind: "component", type: i18.SpinnerComponent, selector: "app-spinner" }, { kind: "pipe", type: i2.LocalizePipe, name: "localize" }] }); }
259
397
  }
260
398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiKanbanComponent, decorators: [{
261
399
  type: Component,
262
- args: [{ selector: 'Tsi-kanban', template: "<div class=\"card flex justify-content-center\">\r\n <p-paginator [first]=\"first\" [rows]=\"rows\" [totalRecords]=\"totalCount\" [rowsPerPageOptions]=\"[1, 10, 25, 50]\"\r\n (onPageChange)=\"onPageChange($event)\" [showCurrentPageReport]=\"true\"\r\n currentPageReportTemplate=\"{{ 'Showing' | localize }} {first} {{'to' | localize}} {last} {{ 'of' | localize }} {totalRecords}\">\r\n </p-paginator>\r\n</div>\r\n\r\n<div class=\"kanban-board flex gap-4 overflow-auto\">\r\n <div *ngFor=\"let status of localizedStatusLabels; trackBy: trackByStatus\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\" (dragover)=\"allowDrop($event)\"\r\n (drop)=\"drop($event, status.key)\">\r\n\r\n <div class=\"column-header p-3 border-bottom-1 surface-border font-semibold\">\r\n {{ status.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ cardMapByStatus.get(status.key)?.length || 0 }})\r\n </span>\r\n </div>\r\n\r\n <div class=\"column-cards flex-1 overflow-auto p-3\">\r\n <div *ngFor=\"let card of cardMapByStatus.get(status.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\"\r\n [ngClass]=\"getStatusClass(card)\"\r\n draggable=\"true\"\r\n (dragstart)=\"dragStart($event, card)\" \r\n (dragend)=\"dragEnd()\">\r\n\r\n <div class=\"font-bold mb-2\">{{ card.headerTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.subHeaderTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.description }}</div>\r\n <p-menu appendTo=\"body\" #menuMoreActions \r\n [model]=\"overflowActionsMenu\" \r\n [popup]=\"true\" styleClass=\"overflow-menu\"\r\n [style]=\"{ 'width': 'auto', 'min-width': '0px' }\">\r\n <ng-template pTemplate=\"item\" let-menuItem>\r\n <a pRipple class=\"flex align-items-center p-menuitem-link\" \r\n [ngClass]=\"menuItem.styleClass\"\r\n (click)=\"onOverflowActionClicked(card, menuItem)\">\r\n <i *ngIf=\"menuItem.id === 'notes'\" class=\"{{ menuItem.iconClass }} p-menuitem-icon badge-icon has-badge\"\r\n [ngClass]=\"menuItem.iconStyleClass\" pBadge severity=\"danger\" \r\n [value]=\"card.fullRecord.notesCount\"\r\n [badgeDisabled]=\"card.fullRecord.notesCount == null\" badgePosition=\"top-right\">\r\n </i>\r\n\r\n <i *ngIf=\"menuItem.id !== 'notes'\" class=\"{{menuItem.iconClass}} p-menuitem-icon\"\r\n [ngClass]=\"menuItem.iconStyleClass\">\r\n </i>\r\n\r\n <span class=\"menu-label\">\r\n {{ menuItem.label | localize }}\r\n </span>\r\n </a>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <div class=\"flex justify-content-end align-items-center mt-1 gap-2 p-0\">\r\n <Tsi-Button [styleClass]=\"'p-button-rounded p-button-text p-0-5'\" type=\"button\" icon=\"pi pi-pencil\"\r\n (click)=\"edit(card.uid)\">\r\n </Tsi-Button>\r\n <p-button type=\"button\" icon=\"pi pi-ellipsis-v\" styleClass=\"overflow-btn\"\r\n (onClick)=\"overflowColumnClicked(menuMoreActions, $event, card)\">\r\n </p-button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"overlay\" *ngIf=\"isLoading\">\r\n <div class=\"spinner-wrapper\">\r\n <app-spinner></app-spinner>\r\n </div>\r\n </div>", styles: [":host{display:block;padding:1rem}[draggable=true]{-webkit-user-select:none;user-select:none}.kanban-board{height:calc(100vh - 100px);padding:1rem}.kanban-column{width:300px;max-height:100%;display:flex;flex-direction:column;background-color:#f8f9fa}.column-header{font-size:1rem;font-weight:700;background-color:#fff;border-radius:6px 6px 0 0}.column-cards{overflow-y:auto;flex:1}.kanban-card{border-left:4px solid;cursor:move;transition:border-color .3s ease}.status-0{border-left-color:#7269ef}.status-1{border-left-color:#00c853}.status-2{border-left-color:#ffab00}.status-3{border-left-color:#d50000}[class*=status-]{border-left-style:solid;border-left-width:4px}\n"] }]
263
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.EntityConfigurationService }, { type: i2.LocalizePipe }, { type: i3.EntityStatusService }, { type: i4.TsiNotificationService }], propDecorators: { buttonClicked: [{
400
+ args: [{ selector: 'Tsi-kanban', template: "<div class=\"card flex justify-content-center\">\r\n <p-paginator [first]=\"first\" [rows]=\"rows\" [totalRecords]=\"totalCount\" [rowsPerPageOptions]=\"[1, 10, 25, 50]\"\r\n (onPageChange)=\"onPageChange($event)\" [showCurrentPageReport]=\"true\"\r\n currentPageReportTemplate=\"{{ 'Showing' | localize }} {first} {{'to' | localize}} {last} {{ 'of' | localize }} {totalRecords}\">\r\n </p-paginator>\r\n</div>\r\n\r\n<div class=\"kanban-board flex gap-4 overflow-auto\">\r\n <div *ngFor=\"let status of localizedStatusLabels; trackBy: trackByStatus\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\" (dragover)=\"allowDrop($event)\"\r\n (drop)=\"drop($event, status.key)\">\r\n\r\n <div class=\"column-header p-3 font-semibold\"\r\n [style.border-left-color]=\"getColumnAccentColor(status.key)\">\r\n {{ status.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ getColumnCount(status.key) }})\r\n </span>\r\n <div class=\"text-xs font-normal text-gray-500\" *ngIf=\"hasColumnSummaries\">\r\n <div *ngFor=\"let sumCol of summaryColumns\" class=\"flex align-items-center gap-1\">\r\n <span>{{ (sumCol.header ?? sumCol.field) | localize }}:</span>\r\n <ng-container [ngSwitch]=\"sumCol.type\">\r\n <Tsi-Currency-Societe-Display *ngSwitchCase=\"displayTypes.CURRENCY_SOCIETE_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Currency-Societe-Display>\r\n <Tsi-Integer-Display *ngSwitchCase=\"displayTypes.INTEGER_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Integer-Display>\r\n <Tsi-Rate-Display *ngSwitchCase=\"displayTypes.RATE_DISPLAY\"\r\n [isFraction]=\"sumCol.isFraction ?? false\" [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Rate-Display>\r\n <Tsi-Decimal-Display *ngSwitchCase=\"displayTypes.DECIMAL_DISPLAY\"\r\n [formatDecimal]=\"sumCol.formatDecimal\" [numOfDecimal]=\"sumCol.numOfDecimal\"\r\n [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Decimal-Display>\r\n <Tsi-Currency-Other-Display *ngSwitchCase=\"displayTypes.CURRENCY_OTHER_DISPLAY\"\r\n [currency]=\"sumCol.currencyOtherCode\" [inputData]=\"getColumnSummaryValue(status.key, sumCol.field)\">\r\n </Tsi-Currency-Other-Display>\r\n <span *ngSwitchDefault>{{ getColumnSummaryValue(status.key, sumCol.field) }}</span>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"column-cards flex-1 overflow-auto p-3\">\r\n <div *ngFor=\"let card of cardMapByStatus.get(status.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\"\r\n draggable=\"true\"\r\n (dragstart)=\"dragStart($event, card)\" \r\n (dragend)=\"dragEnd()\">\r\n\r\n <div class=\"font-bold mb-2\">{{ card.headerTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.subHeaderTitle }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.description }}</div>\r\n <p-menu appendTo=\"body\" #menuMoreActions \r\n [model]=\"overflowActionsMenu\" \r\n [popup]=\"true\" styleClass=\"overflow-menu\"\r\n [style]=\"{ 'width': 'auto', 'min-width': '0px' }\">\r\n <ng-template pTemplate=\"item\" let-menuItem>\r\n <a pRipple class=\"flex align-items-center p-menuitem-link\" \r\n [ngClass]=\"menuItem.styleClass\"\r\n (click)=\"onOverflowActionClicked(card, menuItem)\">\r\n <i *ngIf=\"menuItem.id === 'notes'\" class=\"{{ menuItem.iconClass }} p-menuitem-icon badge-icon has-badge\"\r\n [ngClass]=\"menuItem.iconStyleClass\" pBadge severity=\"danger\" \r\n [value]=\"card.fullRecord.notesCount\"\r\n [badgeDisabled]=\"card.fullRecord.notesCount == null\" badgePosition=\"top-right\">\r\n </i>\r\n\r\n <i *ngIf=\"menuItem.id !== 'notes'\" class=\"{{menuItem.iconClass}} p-menuitem-icon\"\r\n [ngClass]=\"menuItem.iconStyleClass\">\r\n </i>\r\n\r\n <span class=\"menu-label\">\r\n {{ menuItem.label | localize }}\r\n </span>\r\n </a>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <div class=\"flex justify-content-end align-items-center mt-1 gap-2 p-0\">\r\n <Tsi-Button [styleClass]=\"'p-button-rounded p-button-text p-0-5'\" type=\"button\" icon=\"pi pi-pencil\"\r\n (click)=\"edit(card.uid)\">\r\n </Tsi-Button>\r\n <p-button type=\"button\" icon=\"pi pi-ellipsis-v\" styleClass=\"overflow-btn\"\r\n (onClick)=\"overflowColumnClicked(menuMoreActions, $event, card)\">\r\n </p-button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"overlay\" *ngIf=\"isLoading\">\r\n <div class=\"spinner-wrapper\">\r\n <app-spinner></app-spinner>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:block;padding:1rem}[draggable=true]{-webkit-user-select:none;user-select:none}.kanban-board{height:calc(100vh - 100px);padding:1rem}.kanban-column{width:300px;max-height:100%;display:flex;flex-direction:column;background-color:#f8f9fa}.column-header{font-size:1rem;font-weight:700;background-color:#fff;border-radius:6px 6px 0 0;border-bottom:1px solid var(--surface-border);border-left:.75rem solid transparent;transition:border-color .3s ease}.column-cards{overflow-y:auto;flex:1}.kanban-card{cursor:move}\n"] }]
401
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.EntityConfigurationService }, { type: i2.LocalizePipe }, { type: i3.EntityStatusService }, { type: i4.TsiNotificationService }, { type: i5.StatusColorService }], propDecorators: { buttonClicked: [{
264
402
  type: Output
265
403
  }], callSearch: [{
266
404
  type: Output
@@ -280,7 +418,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
280
418
  type: Input
281
419
  }], key: [{
282
420
  type: Input
421
+ }], summaryColumns: [{
422
+ type: Input
283
423
  }], page: [{
284
424
  type: Input
285
425
  }] } });
286
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLWthbmJhbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90c2ktc2hhcmVkLXVpL3NyYy9saWIvdHNpLWNvbXBvbmVudHMvdHNpLWthbmJhbi90c2kta2FuYmFuLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy90c2kta2FuYmFuL3RzaS1rYW5iYW4uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFxQixTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbEcsT0FBTyxFQUFtQixjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFRNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdURBQXVELENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBS3pGOzs7R0FHRztBQU1ILE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxnQkFBZ0I7SUFpQnBELElBQWEsSUFBSSxDQUFDLEtBQVU7UUFDeEIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFDRCxJQUFJLElBQUksS0FBSyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBa0JqQyxZQUNZLEdBQXNCLEVBQ3RCLGFBQXlDLEVBQ3pDLFNBQXVCLEVBQ3ZCLG9CQUF5QyxFQUN6QyxvQkFBNEM7UUFFcEQsS0FBSyxFQUFFLENBQUM7UUFOQSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixrQkFBYSxHQUFiLGFBQWEsQ0FBNEI7UUFDekMsY0FBUyxHQUFULFNBQVMsQ0FBYztRQUN2Qix5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXFCO1FBQ3pDLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBd0I7UUExQzlDLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQXFCLENBQUM7UUFDdEQsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFPdEMsd0JBQW1CLEdBQWUsRUFBRSxDQUFDO1FBQzlDLHVCQUFrQixHQUFZLEtBQUssQ0FBQztRQUNwQywwQkFBcUIsR0FBaUIsRUFBRSxDQUFDO1FBRWhDLGtCQUFhLEdBQVksSUFBSSxDQUFDO1FBQzlCLFFBQUcsR0FBVyxLQUFLLENBQUM7UUFRN0IsVUFBSyxHQUFjLEVBQUUsQ0FBQztRQUN0QixvQkFBZSxHQUEyQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRXBELGdCQUFXLEdBQW1CLElBQUksQ0FBQztRQUNuQyxVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsU0FBSSxHQUFHLEVBQUUsQ0FBQztRQUNWLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRWxCLG1CQUFjLEdBQVcsRUFBRSxDQUFDO1FBRzVCLDBCQUFxQixHQUNqQixFQUNDLENBQUM7UUFVRixJQUFJLENBQUMscUJBQXFCLEdBQUc7WUFDekI7Z0JBQ0ksR0FBRyxFQUFFLEtBQUs7Z0JBQ1YsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLHFDQUFxQyxDQUFDLENBQUMsSUFBSSxFQUFFO2FBQ3BGO1NBQ0osQ0FBQTtJQUNMLENBQUM7SUFFUSxLQUFLLENBQUMsUUFBUTtRQUNuQixNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUUxRCxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUMsSUFBSSxFQUFDLEVBQUU7WUFDOUIsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDUCxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUNoQyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsU0FBUyxDQUFDLENBQVksRUFBRSxJQUFhO1FBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUM7SUFDbEQsQ0FBQztJQUVELE9BQU8sS0FBVyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7SUFFNUMsU0FBUyxDQUFDLEtBQWdCLElBQVUsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU3RCxhQUFhLENBQUMsS0FBYSxFQUFFLE1BQTBDLElBQUksT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUUvRixXQUFXLENBQUMsS0FBYSxFQUFFLElBQWEsSUFBSSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBRTlELElBQUksQ0FBQyxLQUFnQixFQUFFLFlBQW9CO1FBQ3ZDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPO1FBRTlCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDOUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUUzQyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxLQUFLLFlBQVksRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQztZQUV2QyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUksQ0FBQztZQUVoQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ3JDLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO29CQUNYLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUN4QyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUNqRSxDQUFDO29CQUVGLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzt3QkFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7d0JBQ3hCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzt3QkFDckIsT0FBTztvQkFDWCxDQUFDO29CQUVELE1BQU0sV0FBVyxHQUFHO3dCQUNoQixHQUFHLElBQUk7d0JBQ1AsQ0FBQyxhQUFhLENBQUMsRUFBRSxZQUFZO3FCQUNoQyxDQUFDO29CQUVGLElBQUksQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUM7d0JBQ2pELElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFOzRCQUNYLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDOzRCQUN0QixJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQzs0QkFDaEcsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7NEJBQ3hCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzs0QkFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7d0JBQzNCLENBQUM7d0JBQ0QsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7NEJBQ2IsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMscUNBQXFDLENBQUMsQ0FBQzs0QkFDM0UsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsbUNBQW1DLENBQUMsQ0FBQzs0QkFFdkUsSUFBSSxPQUFPLEdBQUcsR0FBRyxJQUFJLEtBQUssSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDOzRCQUUxSCxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDOzRCQUN6QyxJQUFJLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQzs0QkFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7NEJBQ3hCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzs0QkFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7d0JBQzNCLENBQUM7cUJBQ0osQ0FBQyxDQUFDO2dCQUNQLENBQUM7Z0JBQ0QsS0FBSyxFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7b0JBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDO29CQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztvQkFDeEIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUNyQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDM0IsQ0FBQzthQUNKLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QixDQUFDO1FBRUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDNUIsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFxQjtRQUM5QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVELGNBQWMsQ0FBQyxJQUFhO1FBQ3hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvRSxPQUFPLFVBQVUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN0RCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsR0FBdUI7UUFDdEMsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNwQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNsRSxPQUFPLEtBQUssRUFBRSxTQUFTLElBQUksR0FBRyxDQUFDO0lBQ25DLENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBUztRQUNwQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUs7WUFBRSxPQUFPO1FBRXpCLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDbEMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFTyxLQUFLLENBQUMsYUFBYTtRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUM5RixDQUFDO0lBRU8sVUFBVTtRQUNkLE9BQU87WUFDSCxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxxQkFBcUIsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO1lBQ2xFLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO1lBQzNELElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7WUFDL0QsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUscUJBQXFCLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtZQUNqRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO1NBQ2pFLENBQUM7SUFDTixDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxLQUFZO1FBQ3RDLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRTNCLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzlELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUM7UUFFN0IsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBUyxFQUFFLEtBQWEsRUFBRSxFQUFFO1lBQzFDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUMvQyxHQUFHLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO2dCQUM3QixPQUFPLEdBQUcsQ0FBQztZQUNmLENBQUMsRUFBRSxFQUE0QixDQUFDLENBQUM7WUFFakMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQzdDLE1BQU0sYUFBYSxHQUFHLFNBQVMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2pFLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7WUFFdEQsT0FBTztnQkFDSCxFQUFFLEVBQUUsS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSztnQkFDMUIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRTtnQkFDbEIsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDeEMsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDM0MsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDeEMsTUFBTSxFQUFFLFdBQVc7Z0JBQ25CLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksaUJBQWlCLENBQUMsS0FBSztnQkFDbkQsVUFBVSxFQUFFLElBQUk7YUFDbkIsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLGFBQWE7UUFDakIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7UUFFekMsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUM3QyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUVELEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzVCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU8sQ0FBQyxDQUFDO1lBQ3BDLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ1IsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyQixDQUFDO2lCQUFNLENBQUM7Z0JBQ0osT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDTCxDQUFDO1FBRUQsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ3ZDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBRUQsSUFBSSxDQUFDLGVBQWUsR0FBRyxHQUFHLENBQUM7UUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU8sS0FBSyxDQUFDLHNCQUFzQixDQUFDLFNBQWtCO1FBQ25ELE1BQU0sUUFBUSxHQUFHLE1BQU0sY0FBYyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUM1RixNQUFNLFFBQVEsR0FBRyxRQUFRLEVBQUUsWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUU5QyxJQUFJLENBQUMscUJBQXFCLEdBQUc7WUFDekIsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2pHLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDekIsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHO2dCQUNWLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFO2FBQ3RELENBQUMsQ0FBQztTQUNOLENBQUM7SUFDTixDQUFDO0lBRUQsb0JBQW9CO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMzQixPQUFPLEVBQUUsQ0FBQztRQUNkLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzFDLEVBQUUsRUFBRSxHQUFHLENBQUMsS0FBSztZQUNiLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTTtZQUNqQixTQUFTLEVBQUUsR0FBRyxDQUFDLFVBQVU7WUFDekIsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVO1lBQzFCLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYztTQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxJQUFVLEVBQUUsS0FBWSxFQUFFLEdBQVE7UUFDcEQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEdBQUcsQ0FBQztRQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFDRCx1QkFBdUIsQ0FBQyxJQUFhLEVBQUUsUUFBa0I7UUFDckQsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNyQyxPQUFPO1FBQ1gsQ0FBQztRQUVELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsVUFBVSxJQUFJLElBQUksRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDbkUsQ0FBQztJQUVELG1CQUFtQixDQUFDLElBQVMsRUFBRSxLQUFhO1FBRXhDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDdEcsQ0FBQzthQUNJLENBQUM7WUFDRixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDNUYsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFJLENBQUMsR0FBWTtRQUNiLElBQUksR0FBRyxFQUFFLENBQUM7WUFDTixJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3pDLENBQUM7SUFDTCxDQUFDO0lBQ08sa0JBQWtCLENBQUMsR0FBVyxFQUFFLElBQVk7UUFDaEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQzsrR0F2U1Esa0JBQWtCO21HQUFsQixrQkFBa0Isa1hDMUIvQiwwZ0hBdUVVOzs0RkQ3Q0csa0JBQWtCO2tCQUw5QixTQUFTOytCQUNJLFlBQVk7aU9BTVosYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVFLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csRUFBRTtzQkFBVixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFJRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFFTyxJQUFJO3NCQUFoQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUGFnaW5hdG9yU3RhdGUgfSBmcm9tICdwcmltZW5nL3BhZ2luYXRvcic7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgTG9jYWxpemF0aW9uS2V5cyB9IGZyb20gJy4uLy4uL2NvbnN0cy9sb2NhbGl6YXRpb24ta2V5JztcclxuaW1wb3J0IHsgZGVmYXVsdENhcmRIZWFkZXIgfSBmcm9tICcuLi8uLi9jb25zdHMvdHNpLWNvbnN0cyc7XHJcbmltcG9ydCB7IEJ1dHRvbkNsaWNrUmVzdWx0LCBHcmlkQ29sdW1uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7IFRzaUNhcmQgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xyXG5pbXBvcnQgeyBMb2NhbGl6ZVBpcGUgfSBmcm9tICcuLi8uLi9waXBlcy9sb2NhbGl6ZS5waXBlJztcclxuaW1wb3J0IHsgQ3J1ZEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYmFzZS9jcnVkLWJhc2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IEVudGl0eUNvbmZpZ3VyYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29uZmlndXJhdGlvbi9lbnRpdHktY29uZmlndXJhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVHNpTm90aWZpY2F0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL25vdGlmaWNhdGlvbi90c2ktbm90aWZpY2F0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBFbnRpdHlTdGF0dXNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc3RhdHVzL2VudGl0eVN0YXR1cy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQXBwQmFzZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3RzaS1iYXNlL2NvbXBvbmVudHMvYXBwLWJhc2UvYXBwLWJhc2UuY29tcG9uZW50JztcclxuaW1wb3J0IHsgQWN0aW9uUGxhY2VtZW50IH0gZnJvbSAnLi4vLi4vZW51bXMnO1xyXG5pbXBvcnQgeyBNZW51SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcclxuaW1wb3J0IHsgTWVudSB9IGZyb20gJ3ByaW1lbmcvbWVudSc7XHJcblxyXG4vKipcclxuICogVHNpS2FuYmFuQ29tcG9uZW50XHJcbiAqIERlc2NyaXB0aW9uOiBEaXNwbGF5cyBhIEthbmJhbiBib2FyZCB2aWV3IGZvciBUU0kgZW50aXRpZXMuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnVHNpLWthbmJhbicsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vdHNpLWthbmJhbi5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybDogJy4vdHNpLWthbmJhbi5jb21wb25lbnQuc2NzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUc2lLYW5iYW5Db21wb25lbnQgZXh0ZW5kcyBBcHBCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuXHJcbiAgICBAT3V0cHV0KCkgYnV0dG9uQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8QnV0dG9uQ2xpY2tSZXN1bHQ+KCk7XHJcbiAgICBAT3V0cHV0KCkgY2FsbFNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIEBJbnB1dCgpIGNhcmRCdXNpbmVzc0NsYXNzOiBhbnk7XHJcbiAgICBASW5wdXQoKSBoZWFkZXI6IGFueTtcclxuICAgIEBJbnB1dCgpIGlkOiBhbnk7XHJcbiAgICBASW5wdXQoKSBwYWdlJCE6IEJlaGF2aW9yU3ViamVjdDxhbnk+O1xyXG4gICAgQElucHV0KCkgY3J1ZFNlcnZpY2U/OiBDcnVkQmFzZVNlcnZpY2U8YW55LCBhbnksIGFueSwgYW55PjtcclxuICAgIEBJbnB1dCgpIG92ZXJmbG93QWN0aW9uc01lbnU6IE1lbnVJdGVtW10gPSBbXTtcclxuICAgIGhhc092ZXJmbG93QWN0aW9uczogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgb3ZlcmZsb3dBY3Rpb25Db2x1bW5zOiBHcmlkQ29sdW1uW10gPSBbXTtcclxuICAgIGN1cnJlbnRBY3Rpb25Sb3c6IGFueTtcclxuICAgIEBJbnB1dCgpIHNlbGVjdEtleU9ubHk6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgQElucHV0KCkga2V5OiBzdHJpbmcgPSAndWlkJztcclxuICAgIHByaXZhdGUgX3BhZ2U6IGFueTtcclxuICAgIEBJbnB1dCgpIHNldCBwYWdlKHZhbHVlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLl9wYWdlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5oYW5kbGVQYWdlQ2hhbmdlKHZhbHVlKTtcclxuICAgIH1cclxuICAgIGdldCBwYWdlKCkgeyByZXR1cm4gdGhpcy5fcGFnZTsgfVxyXG5cclxuICAgIGNhcmRzOiBUc2lDYXJkW10gPSBbXTtcclxuICAgIGNhcmRNYXBCeVN0YXR1czogTWFwPHN0cmluZywgVHNpQ2FyZFtdPiA9IG5ldyBNYXAoKTtcclxuXHJcbiAgICBkcmFnZ2VkQ2FyZDogVHNpQ2FyZCB8IG51bGwgPSBudWxsO1xyXG4gICAgZmlyc3QgPSAwO1xyXG4gICAgcm93cyA9IDEwO1xyXG4gICAgdG90YWxDb3VudCA9IDA7XHJcbiAgICBpc0xvYWRpbmcgPSBmYWxzZTtcclxuXHJcbiAgICBvcmlnaW5hbFN0YXR1czogc3RyaW5nID0gJyc7XHJcbiAgICBwcmV2aW91c1N0YXR1czogYW55O1xyXG5cclxuICAgIGxvY2FsaXplZFN0YXR1c0xhYmVsczogeyBrZXk6IHN0cmluZzsgbG9jYWxpemVkOiBzdHJpbmcgfVtdID1cclxuICAgICAgICBbXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBfZW50aXR5Q29uZmlnOiBFbnRpdHlDb25maWd1cmF0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9sb2NhbGl6ZTogTG9jYWxpemVQaXBlLFxyXG4gICAgICAgIHByaXZhdGUgX2VudGl0eVN0YXR1c1NlcnZpY2U6IEVudGl0eVN0YXR1c1NlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBfbm90aWZpY2F0aW9uU2VydmljZTogVHNpTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5sb2NhbGl6ZWRTdGF0dXNMYWJlbHMgPSBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGtleTogJ25ldycsXHJcbiAgICAgICAgICAgICAgICBsb2NhbGl6ZWQ6IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybSgnZ2VzY19wYXJhbV9hcnRpY2xlX3N0YXR1dF9lbnVtc19uZXcnKS50cmltKClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIF1cclxuICAgIH1cclxuXHJcbiAgICBvdmVycmlkZSBhc3luYyBuZ09uSW5pdCgpIHtcclxuICAgICAgICBhd2FpdCB0aGlzLmdldEJ1c2luZXNzQ2xhc3NTdGF0dXModGhpcy5jYXJkQnVzaW5lc3NDbGFzcyk7XHJcblxyXG4gICAgICAgIHRoaXMucGFnZSQuc3Vic2NyaWJlKGFzeW5jIHBhZ2UgPT4ge1xyXG4gICAgICAgICAgICBpZiAocGFnZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSAhIXBhZ2UubG9hZGluZztcclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlUGFnZUNoYW5nZShwYWdlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGRyYWdTdGFydChfOiBEcmFnRXZlbnQsIGNhcmQ6IFRzaUNhcmQpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gY2FyZDtcclxuICAgICAgICB0aGlzLnByZXZpb3VzU3RhdHVzID0gdGhpcy5kcmFnZ2VkQ2FyZC5zdGF0dXM7XHJcbiAgICB9XHJcblxyXG4gICAgZHJhZ0VuZCgpOiB2b2lkIHsgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7IH1cclxuXHJcbiAgICBhbGxvd0Ryb3AoZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQgeyBldmVudC5wcmV2ZW50RGVmYXVsdCgpOyB9XHJcblxyXG4gICAgdHJhY2tCeVN0YXR1cyhpbmRleDogbnVtYmVyLCBzdGF0dXM6IHsga2V5OiBzdHJpbmc7IGxvY2FsaXplZDogc3RyaW5nIH0pIHsgcmV0dXJuIHN0YXR1cy5rZXk7IH1cclxuXHJcbiAgICB0cmFja0J5Q2FyZChpbmRleDogbnVtYmVyLCBjYXJkOiBUc2lDYXJkKSB7IHJldHVybiBjYXJkLnVpZDsgfVxyXG5cclxuICAgIGRyb3AoZXZlbnQ6IERyYWdFdmVudCwgbmV3U3RhdHVzS2V5OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBpZiAoIXRoaXMuZHJhZ2dlZENhcmQpIHJldHVybjtcclxuXHJcbiAgICAgICAgY29uc3QgY2FyZCA9IHRoaXMuZHJhZ2dlZENhcmQ7XHJcbiAgICAgICAgY29uc3QgcHJldmlvdXNTdGF0dXMgPSB0aGlzLnByZXZpb3VzU3RhdHVzO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5kcmFnZ2VkQ2FyZC5zdGF0dXMgIT09IG5ld1N0YXR1c0tleSkge1xyXG4gICAgICAgICAgICB0aGlzLmRyYWdnZWRDYXJkLnN0YXR1cyA9IG5ld1N0YXR1c0tleTtcclxuXHJcbiAgICAgICAgICAgIGxldCB1aWQgPSB0aGlzLmRyYWdnZWRDYXJkLnVpZCE7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNydWRTZXJ2aWNlPy5nZXRCeUlkKHVpZCkuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgICAgIG5leHQ6IChyZXNwKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVhbFN0YXR1c0tleSA9IE9iamVjdC5rZXlzKHJlc3ApLmZpbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9PiBrZXkudG9Mb3dlckNhc2UoKSA9PT0gdGhpcy5vcmlnaW5hbFN0YXR1cy50b0xvd2VyQ2FzZSgpXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWFsU3RhdHVzS2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dlZENhcmQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUNhcmRNYXAoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBkYXRlZEl0ZW0gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJlc3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFsU3RhdHVzS2V5XTogbmV3U3RhdHVzS2V5XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcnVkU2VydmljZT8udXBkYXRlKHVwZGF0ZWRJdGVtLCB1aWQpLnN1YnNjcmliZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IChyZXNwKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub3RpZmljYXRpb25TZXJ2aWNlLnN1Y2Nlc3ModGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKExvY2FsaXphdGlvbktleXMuc2F2ZWRTdWNjZXNzZnVsbHkpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dlZENhcmQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZnJvbSA9IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybShcImdlc2NfcGFyYW1fZXJyb3Jfc3dpdGNoX3N0YXR1c19mcm9tXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRvID0gdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKFwiZ2VzY19wYXJhbV9lcnJvcl9zd2l0Y2hfc3RhdHVzX3RvXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYCR7ZnJvbX0gJyR7dGhpcy5nZXRMb2NhbGl6ZWRTdGF0dXModGhpcy5wcmV2aW91c1N0YXR1cyl9JyAke3RvfSAnJHt0aGlzLmdldExvY2FsaXplZFN0YXR1cyhjYXJkLnN0YXR1cyl9J2A7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcihtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcmQuc3RhdHVzID0gcHJldmlvdXNTdGF0dXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhcmQuc3RhdHVzID0gcHJldmlvdXNTdGF0dXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBvblBhZ2VDaGFuZ2UoZXZlbnQ6IFBhZ2luYXRvclN0YXRlKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5maXJzdCA9IGV2ZW50LmZpcnN0ID8/IDA7XHJcbiAgICAgICAgdGhpcy5yb3dzID0gZXZlbnQucm93cyA/PyAxMDtcclxuICAgICAgICB0aGlzLmNhbGxTZWFyY2guZW1pdCh7IHNraXBDb3VudDogdGhpcy5maXJzdCwgbWF4UmVzdWx0Q291bnQ6IHRoaXMucm93cyB9KTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRTdGF0dXNDbGFzcyhjYXJkOiBUc2lDYXJkKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMubG9jYWxpemVkU3RhdHVzTGFiZWxzLmZpbmRJbmRleChsID0+IGwua2V5ID09PSBjYXJkLnN0YXR1cyk7XHJcbiAgICAgICAgcmV0dXJuIGBzdGF0dXMtJHtpbmRleCA+PSAwID8gaW5kZXggOiAnZGVmYXVsdCd9YDtcclxuICAgIH1cclxuXHJcbiAgICBnZXRMb2NhbGl6ZWRTdGF0dXMoa2V5OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICgha2V5KSByZXR1cm4gJyc7XHJcbiAgICAgICAgY29uc3QgbWF0Y2ggPSB0aGlzLmxvY2FsaXplZFN0YXR1c0xhYmVscy5maW5kKHMgPT4gcy5rZXkgPT09IGtleSk7XHJcbiAgICAgICAgcmV0dXJuIG1hdGNoPy5sb2NhbGl6ZWQgPz8ga2V5O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlUGFnZUNoYW5nZShwYWdlOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIXBhZ2U/Lml0ZW1zKSByZXR1cm47XHJcblxyXG4gICAgICAgIHRoaXMuY2FyZHMgPSBhd2FpdCB0aGlzLm1hcEl0ZW1zVG9DYXJkcyhwYWdlLml0ZW1zKTtcclxuICAgICAgICB0aGlzLnRvdGFsQ291bnQgPSBwYWdlLnRvdGFsQ291bnQ7XHJcbiAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRFbnRpdHlJbmZvKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHRoaXMuZW50aXR5SW5mbyA9IGF3YWl0IHRoaXMuX2VudGl0eUNvbmZpZy5nZXRFbnRpdHlJbmZvRnJvbUNhY2hlKHRoaXMuY2FyZEJ1c2luZXNzQ2xhc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0Q29sS2V5cygpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBwaG90bzogdGhpcy5lbnRpdHlJbmZvPy5jYXJkSGVhZGVyUGhvdG9Db2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNvbDE6IHRoaXMuZW50aXR5SW5mbz8uY2FyZFRpdGxlQ29sdW1uPy50b0xvd2VyQ2FzZSgpID8/ICcnLFxyXG4gICAgICAgICAgICBjb2wyOiB0aGlzLmVudGl0eUluZm8/LmNhcmRTdWJIZWFkZXJDb2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNvbDM6IHRoaXMuZW50aXR5SW5mbz8uY2FyZERlc2NyaXB0aW9uQ29sdW1uPy50b0xvd2VyQ2FzZSgpID8/ICcnLFxyXG4gICAgICAgICAgICBzdGF0dXM6IHRoaXMuZW50aXR5SW5mbz8uc3RhdHVzQ29sdW1uTmFtZT8udG9Mb3dlckNhc2UoKSA/PyAnJ1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBtYXBJdGVtc1RvQ2FyZHMoaXRlbXM6IGFueVtdKTogUHJvbWlzZTxUc2lDYXJkW10+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmdldEVudGl0eUluZm8oKTtcclxuXHJcbiAgICAgICAgY29uc3QgeyBjb2wxLCBjb2wyLCBjb2wzLCBwaG90bywgc3RhdHVzIH0gPSB0aGlzLmdldENvbEtleXMoKTtcclxuICAgICAgICBjb25zdCB2YWxpZEtleXMgPSB0aGlzLmxvY2FsaXplZFN0YXR1c0xhYmVscy5tYXAocyA9PiBzLmtleSk7XHJcblxyXG4gICAgICAgIHRoaXMub3JpZ2luYWxTdGF0dXMgPSBzdGF0dXM7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcy5tYXAoKGl0ZW06IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoaXRlbSkucmVkdWNlKChhY2MsIGtleSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgYWNjW2tleS50b0xvd2VyQ2FzZSgpXSA9IGtleTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgICAgICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcmF3U3RhdHVzID0gaXRlbVtrZXlzW3N0YXR1c11dPy50cmltKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzVmFsaWRTdGF0dXMgPSByYXdTdGF0dXMgJiYgdmFsaWRLZXlzLmluY2x1ZGVzKHJhd1N0YXR1cyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbmFsU3RhdHVzID0gaXNWYWxpZFN0YXR1cyA/IHJhd1N0YXR1cyA6ICduZXcnO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGlkOiBpbmRleCArIDEgKyB0aGlzLmZpcnN0LFxyXG4gICAgICAgICAgICAgICAgdWlkOiBgJHtpdGVtLnVpZH1gLFxyXG4gICAgICAgICAgICAgICAgaGVhZGVyVGl0bGU6IGAke2l0ZW1ba2V5c1tjb2wxXV0gPz8gJyd9YCxcclxuICAgICAgICAgICAgICAgIHN1YkhlYWRlclRpdGxlOiBgJHtpdGVtW2tleXNbY29sMl1dID8/ICcnfWAsXHJcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYCR7aXRlbVtrZXlzW2NvbDNdXSA/PyAnJ31gLFxyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBmaW5hbFN0YXR1cyxcclxuICAgICAgICAgICAgICAgIHBob3RvOiBpdGVtW2tleXNbcGhvdG9dXSB8fCBkZWZhdWx0Q2FyZEhlYWRlci5pbWFnZSxcclxuICAgICAgICAgICAgICAgIGZ1bGxSZWNvcmQ6IGl0ZW0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVDYXJkTWFwKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBUc2lDYXJkW10+KCk7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgbGFiZWwgb2YgdGhpcy5sb2NhbGl6ZWRTdGF0dXNMYWJlbHMpIHtcclxuICAgICAgICAgICAgbWFwLnNldChsYWJlbC5rZXksIFtdKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgY2FyZCBvZiB0aGlzLmNhcmRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwID0gbWFwLmdldChjYXJkLnN0YXR1cyEpO1xyXG4gICAgICAgICAgICBpZiAoZ3JvdXApIHtcclxuICAgICAgICAgICAgICAgIGdyb3VwLnB1c2goY2FyZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgVW5tYXBwZWQgY2FyZCBzdGF0dXM6ICR7Y2FyZC5zdGF0dXN9YCwgY2FyZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2FyZHNdIG9mIG1hcC5lbnRyaWVzKCkpIHtcclxuICAgICAgICAgICAgY2FyZHMuc29ydCgoYSwgYikgPT4gKGEuaGVhZGVyVGl0bGUgPz8gJycpLmxvY2FsZUNvbXBhcmUoYi5oZWFkZXJUaXRsZSA/PyAnJykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5jYXJkTWFwQnlTdGF0dXMgPSBtYXA7XHJcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRCdXNpbmVzc0NsYXNzU3RhdHVzKGNsYXNzTmFtZT86IHN0cmluZykge1xyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5fZW50aXR5U3RhdHVzU2VydmljZS5nZXRFbnRpdHlTdGF0dXMoY2xhc3NOYW1lKSk7XHJcbiAgICAgICAgY29uc3Qgc3RhdHVzZXMgPSByZXNwb25zZT8uZW50aXR5U3RhdHVzID8/IFtdO1xyXG5cclxuICAgICAgICB0aGlzLmxvY2FsaXplZFN0YXR1c0xhYmVscyA9IFtcclxuICAgICAgICAgICAgeyBrZXk6ICduZXcnLCBsb2NhbGl6ZWQ6IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybSgnZ2VzY19wYXJhbV9hcnRpY2xlX3N0YXR1dF9lbnVtc19uZXcnKS50cmltKCkgfSxcclxuICAgICAgICAgICAgLi4uc3RhdHVzZXMubWFwKChzOiBhbnkpID0+ICh7XHJcbiAgICAgICAgICAgICAgICBrZXk6IHMua2V5LFxyXG4gICAgICAgICAgICAgICAgbG9jYWxpemVkOiB0aGlzLl9sb2NhbGl6ZS50cmFuc2Zvcm0ocy52YWx1ZSkudHJpbSgpXHJcbiAgICAgICAgICAgIH0pKVxyXG4gICAgICAgIF07XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0T3ZlcmZsb3dNZW51TW9kZWwoKTogTWVudUl0ZW1bXSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmhhc092ZXJmbG93QWN0aW9ucykge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5vdmVyZmxvd0FjdGlvbkNvbHVtbnMubWFwKGNvbCA9PiAoe1xyXG4gICAgICAgICAgICBpZDogY29sLmZpZWxkLFxyXG4gICAgICAgICAgICBsYWJlbDogY29sLmhlYWRlcixcclxuICAgICAgICAgICAgaWNvbkNsYXNzOiBjb2wuYnV0dG9uSWNvbixcclxuICAgICAgICAgICAgc3R5bGVDbGFzczogY29sLnN0eWxlQ2xhc3MsXHJcbiAgICAgICAgICAgIGljb25TdHlsZUNsYXNzOiBjb2wuaWNvblN0eWxlQ2xhc3MsXHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIG92ZXJmbG93Q29sdW1uQ2xpY2tlZChtZW51OiBNZW51LCBldmVudDogRXZlbnQsIHJvdzogYW55KSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50QWN0aW9uUm93ID0gcm93O1xyXG4gICAgICAgIG1lbnUudG9nZ2xlKGV2ZW50KTtcclxuICAgIH1cclxuICAgIG9uT3ZlcmZsb3dBY3Rpb25DbGlja2VkKGNhcmQ6IFRzaUNhcmQsIG1lbnVJdGVtOiBNZW51SXRlbSkge1xyXG4gICAgICAgIGlmICghY2FyZCB8fCAhbWVudUl0ZW0gfHwgIW1lbnVJdGVtLmlkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuaGFuZGxlQnV0dG9uQ2xpY2tlZChjYXJkPy5mdWxsUmVjb3JkID8/IGNhcmQsIG1lbnVJdGVtLmlkKVxyXG4gICAgfVxyXG5cclxuICAgIGhhbmRsZUJ1dHRvbkNsaWNrZWQoaXRlbTogYW55LCBmaWVsZDogc3RyaW5nKTogdm9pZCB7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdEtleU9ubHkpIHtcclxuICAgICAgICAgICAgdGhpcy5idXR0b25DbGlja2VkLmVtaXQoeyBmaWVsZDogZmllbGQsIGtleTogaXRlbVt0aGlzLmtleV0sIHNlbGVjdEtleU9ubHk6IHRoaXMuc2VsZWN0S2V5T25seSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnV0dG9uQ2xpY2tlZC5lbWl0KHsgZmllbGQ6IGZpZWxkLCBrZXk6IGl0ZW0sIHNlbGVjdEtleU9ubHk6IHRoaXMuc2VsZWN0S2V5T25seSB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZWRpdCh1aWQ/OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodWlkKSB7XHJcbiAgICAgICAgICAgIHRoaXMub3Blbk1vZGFsQ29tcG9uZW50KHVpZCwgJ2VkaXQnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBwcml2YXRlIG9wZW5Nb2RhbENvbXBvbmVudCh1aWQ6IHN0cmluZywgbW9kZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5idXR0b25DbGlja2VkLmVtaXQoeyBmaWVsZDogbW9kZSwga2V5OiB1aWQsIHNlbGVjdEtleU9ubHk6IHRydWUgfSk7XHJcbiAgICB9XHJcblxyXG59IiwiPGRpdiBjbGFzcz1cImNhcmQgZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XHJcbiAgPHAtcGFnaW5hdG9yIFtmaXJzdF09XCJmaXJzdFwiIFtyb3dzXT1cInJvd3NcIiBbdG90YWxSZWNvcmRzXT1cInRvdGFsQ291bnRcIiBbcm93c1BlclBhZ2VPcHRpb25zXT1cIlsxLCAxMCwgMjUsIDUwXVwiXHJcbiAgICAob25QYWdlQ2hhbmdlKT1cIm9uUGFnZUNoYW5nZSgkZXZlbnQpXCIgW3Nob3dDdXJyZW50UGFnZVJlcG9ydF09XCJ0cnVlXCJcclxuICAgIGN1cnJlbnRQYWdlUmVwb3J0VGVtcGxhdGU9XCJ7eyAnU2hvd2luZycgfCBsb2NhbGl6ZSB9fSB7Zmlyc3R9IHt7J3RvJyB8IGxvY2FsaXplfX0ge2xhc3R9IHt7ICdvZicgfCBsb2NhbGl6ZSB9fSB7dG90YWxSZWNvcmRzfVwiPlxyXG4gIDwvcC1wYWdpbmF0b3I+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cImthbmJhbi1ib2FyZCBmbGV4IGdhcC00IG92ZXJmbG93LWF1dG9cIj5cclxuICA8ZGl2ICpuZ0Zvcj1cImxldCBzdGF0dXMgb2YgbG9jYWxpemVkU3RhdHVzTGFiZWxzOyB0cmFja0J5OiB0cmFja0J5U3RhdHVzXCJcclxuICAgIGNsYXNzPVwia2FuYmFuLWNvbHVtbiBmbGV4IGZsZXgtY29sdW1uIGJvcmRlci1yb3VuZCBzdXJmYWNlLTAgc2hhZG93LTJcIiAoZHJhZ292ZXIpPVwiYWxsb3dEcm9wKCRldmVudClcIlxyXG4gICAgKGRyb3ApPVwiZHJvcCgkZXZlbnQsIHN0YXR1cy5rZXkpXCI+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbi1oZWFkZXIgcC0zIGJvcmRlci1ib3R0b20tMSBzdXJmYWNlLWJvcmRlciBmb250LXNlbWlib2xkXCI+XHJcbiAgICAgIHt7IHN0YXR1cy5sb2NhbGl6ZWQgfX1cclxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXNtIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cclxuICAgICAgICAoe3sgY2FyZE1hcEJ5U3RhdHVzLmdldChzdGF0dXMua2V5KT8ubGVuZ3RoIHx8IDAgfX0pXHJcbiAgICAgIDwvc3Bhbj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4tY2FyZHMgZmxleC0xIG92ZXJmbG93LWF1dG8gcC0zXCI+XHJcbiAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNhcmQgb2YgY2FyZE1hcEJ5U3RhdHVzLmdldChzdGF0dXMua2V5KTsgdHJhY2tCeTogdHJhY2tCeUNhcmRcIlxyXG4gICAgICAgIGNsYXNzPVwia2FuYmFuLWNhcmQgcC0zIGJvcmRlci1yb3VuZCBiZy13aGl0ZSBtYi0zIHNoYWRvdy0xXCJcclxuICAgICAgICBbbmdDbGFzc109XCJnZXRTdGF0dXNDbGFzcyhjYXJkKVwiXHJcbiAgICAgICAgZHJhZ2dhYmxlPVwidHJ1ZVwiXHJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJkcmFnU3RhcnQoJGV2ZW50LCBjYXJkKVwiIFxyXG4gICAgICAgIChkcmFnZW5kKT1cImRyYWdFbmQoKVwiPlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1ib2xkIG1iLTJcIj57eyBjYXJkLmhlYWRlclRpdGxlIH19PC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc20gdGV4dC1ncmF5LTYwMCBtYi0zXCI+e3sgY2FyZC5zdWJIZWFkZXJUaXRsZSB9fTwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXNtIHRleHQtZ3JheS02MDAgbWItM1wiPnt7IGNhcmQuZGVzY3JpcHRpb24gfX08L2Rpdj5cclxuICAgICAgICA8cC1tZW51IGFwcGVuZFRvPVwiYm9keVwiICNtZW51TW9yZUFjdGlvbnMgXHJcbiAgICAgICAgICAgICBbbW9kZWxdPVwib3ZlcmZsb3dBY3Rpb25zTWVudVwiIFxyXG4gICAgICAgICAgICAgW3BvcHVwXT1cInRydWVcIiBzdHlsZUNsYXNzPVwib3ZlcmZsb3ctbWVudVwiXHJcbiAgICAgICAgICAgICBbc3R5bGVdPVwieyAnd2lkdGgnOiAnYXV0bycsICdtaW4td2lkdGgnOiAnMHB4JyB9XCI+XHJcbiAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaXRlbVwiIGxldC1tZW51SXRlbT5cclxuICAgICAgICAgICAgPGEgcFJpcHBsZSBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyIHAtbWVudWl0ZW0tbGlua1wiIFxyXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLnN0eWxlQ2xhc3NcIlxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJvbk92ZXJmbG93QWN0aW9uQ2xpY2tlZChjYXJkLCBtZW51SXRlbSlcIj5cclxuICAgICAgICAgICAgICA8aSAqbmdJZj1cIm1lbnVJdGVtLmlkID09PSAnbm90ZXMnXCIgY2xhc3M9XCJ7eyBtZW51SXRlbS5pY29uQ2xhc3MgfX0gcC1tZW51aXRlbS1pY29uIGJhZGdlLWljb24gaGFzLWJhZGdlXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLmljb25TdHlsZUNsYXNzXCIgcEJhZGdlIHNldmVyaXR5PVwiZGFuZ2VyXCIgXHJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnRcIlxyXG4gICAgICAgICAgICAgICAgW2JhZGdlRGlzYWJsZWRdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnQgPT0gbnVsbFwiIGJhZGdlUG9zaXRpb249XCJ0b3AtcmlnaHRcIj5cclxuICAgICAgICAgICAgICA8L2k+XHJcblxyXG4gICAgICAgICAgICAgIDxpICpuZ0lmPVwibWVudUl0ZW0uaWQgIT09ICdub3RlcydcIiBjbGFzcz1cInt7bWVudUl0ZW0uaWNvbkNsYXNzfX0gcC1tZW51aXRlbS1pY29uXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLmljb25TdHlsZUNsYXNzXCI+XHJcbiAgICAgICAgICAgICAgPC9pPlxyXG5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lbnUtbGFiZWxcIj5cclxuICAgICAgICAgICAgICAgIHt7IG1lbnVJdGVtLmxhYmVsIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC9wLW1lbnU+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1lbmQgYWxpZ24taXRlbXMtY2VudGVyIG10LTEgZ2FwLTIgcC0wXCI+XHJcbiAgICAgICAgICA8VHNpLUJ1dHRvbiBbc3R5bGVDbGFzc109XCIncC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0IHAtMC01J1wiIHR5cGU9XCJidXR0b25cIiBpY29uPVwicGkgcGktcGVuY2lsXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cImVkaXQoY2FyZC51aWQpXCI+XHJcbiAgICAgICAgICA8L1RzaS1CdXR0b24+XHJcbiAgICAgICAgICA8cC1idXR0b24gdHlwZT1cImJ1dHRvblwiIGljb249XCJwaSBwaS1lbGxpcHNpcy12XCIgc3R5bGVDbGFzcz1cIm92ZXJmbG93LWJ0blwiXHJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cIm92ZXJmbG93Q29sdW1uQ2xpY2tlZChtZW51TW9yZUFjdGlvbnMsICRldmVudCwgY2FyZClcIj5cclxuICAgICAgICAgIDwvcC1idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJvdmVybGF5XCIgKm5nSWY9XCJpc0xvYWRpbmdcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItd3JhcHBlclwiPlxyXG4gICAgICAgIDxhcHAtc3Bpbm5lcj48L2FwcC1zcGlubmVyPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PiJdfQ==
426
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLWthbmJhbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90c2ktc2hhcmVkLXVpL3NyYy9saWIvdHNpLWNvbXBvbmVudHMvdHNpLWthbmJhbi90c2kta2FuYmFuLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy90c2kta2FuYmFuL3RzaS1rYW5iYW4uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFxQixTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbEcsT0FBTyxFQUFtQixjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFRNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFJekYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUl6RDs7O0dBR0c7QUFNSCxNQUFNLE9BQU8sa0JBQW1CLFNBQVEsZ0JBQWdCO0lBc0NwRCxJQUFhLElBQUksQ0FBQyxLQUFpQjtRQUMvQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUNELElBQUksSUFBSSxLQUFrQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBNEI5QyxZQUNZLEdBQXNCLEVBQ3RCLGFBQXlDLEVBQ3pDLFNBQXVCLEVBQ3ZCLG9CQUF5QyxFQUN6QyxvQkFBNEMs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QUNHLEdBQUc7c0JBQVgsS0FBSztnQkFHRyxjQUFjO3NCQUF0QixLQUFLO2dCQUlPLElBQUk7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBQYWdpbmF0b3JTdGF0ZSB9IGZyb20gJ3ByaW1lbmcvcGFnaW5hdG9yJztcclxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBMb2NhbGl6YXRpb25LZXlzIH0gZnJvbSAnLi4vLi4vY29uc3RzL2xvY2FsaXphdGlvbi1rZXknO1xyXG5pbXBvcnQgeyBkZWZhdWx0Q2FyZEhlYWRlciB9IGZyb20gJy4uLy4uL2NvbnN0cy90c2ktY29uc3RzJztcclxuaW1wb3J0IHsgQnV0dG9uQ2xpY2tSZXN1bHQsIEdyaWRDb2x1bW4gfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcclxuaW1wb3J0IHsgVHNpQ2FyZCB9IGZyb20gJy4uLy4uL21vZGVscyc7XHJcbmltcG9ydCB7IExvY2FsaXplUGlwZSB9IGZyb20gJy4uLy4uL3BpcGVzL2xvY2FsaXplLnBpcGUnO1xyXG5pbXBvcnQgeyBDcnVkQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9iYXNlL2NydWQtYmFzZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRW50aXR5Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jb25maWd1cmF0aW9uL2VudGl0eS1jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBUc2lOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbm90aWZpY2F0aW9uL3RzaS1ub3RpZmljYXRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IEVudGl0eVN0YXR1c1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zdGF0dXMvZW50aXR5U3RhdHVzLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBBcHBCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vdHNpLWJhc2UvY29tcG9uZW50cy9hcHAtYmFzZS9hcHAtYmFzZS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBNZW51SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcclxuaW1wb3J0IHsgTWVudSB9IGZyb20gJ3ByaW1lbmcvbWVudSc7XHJcbmltcG9ydCB7IElHcm91cGVkUmVzdWx0LCBJUGFnZSwgSVN1bW1hcnlGb3JQcm9wcmV0eSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcGFnaW5hdGlvbi9wYWdpbmF0aW9uLWJhc2UnO1xyXG5pbXBvcnQgeyBEaXNwbGF5VHlwZXMgfSBmcm9tICcuLi8uLi9lbnVtcy9kaXNwbGF5LXR5cGVzJztcclxuaW1wb3J0IHsgU3RhdHVzQ29sb3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc3RhdHVzL3N0YXR1cy1jb2xvci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU3RhdHVzTWV0YWRhdGFSZXNwb25zZSB9IGZyb20gJy4uLy4uL21vZGVscy9zdGF0dXMvY29sb3Itc3RhdHVzJztcclxuXHJcbi8qKlxyXG4gKiBUc2lLYW5iYW5Db21wb25lbnRcclxuICogRGVzY3JpcHRpb246IERpc3BsYXlzIGEgS2FuYmFuIGJvYXJkIHZpZXcgZm9yIFRTSSBlbnRpdGllcy5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdUc2kta2FuYmFuJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi90c2kta2FuYmFuLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsOiAnLi90c2kta2FuYmFuLmNvbXBvbmVudC5zY3NzJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFRzaUthbmJhbkNvbXBvbmVudCBleHRlbmRzIEFwcEJhc2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc3RhdHVzTGVzc1JlY29yZHM6IHsga2V5OiBzdHJpbmc7IGxvY2FsaXplZDogc3RyaW5nIH0gPSB7XHJcbiAgICAgICAga2V5OiAnbmV3JyxcclxuICAgICAgICBsb2NhbGl6ZWQ6ICduZXcnXHJcbiAgICB9O1xyXG5cclxuICAgIHByaXZhdGUgX3N0YXR1c0xhYmVsczogeyBrZXk6IHN0cmluZzsgbG9jYWxpemVkOiBzdHJpbmcgfVtdID0gW107XHJcblxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZGVmYXVsdFBhZ2U6IElQYWdlPGFueT4gPSB7XHJcbiAgICAgICAgaXRlbXM6IFtdLFxyXG4gICAgICAgIHBhZ2VTaXplOiAxMCxcclxuICAgICAgICBwYWdlTnVtYmVyOiAxLFxyXG4gICAgICAgIHRvdGFsQ291bnQ6IDAsXHJcbiAgICAgICAgdG90YWxQYWdlczogMCxcclxuICAgICAgICBzdW1tYXJpZXM6IFtdLFxyXG4gICAgICAgIGxvYWRpbmc6IGZhbHNlLFxyXG4gICAgfTtcclxuXHJcbiAgICBAT3V0cHV0KCkgYnV0dG9uQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8QnV0dG9uQ2xpY2tSZXN1bHQ+KCk7XHJcbiAgICBAT3V0cHV0KCkgY2FsbFNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIEBJbnB1dCgpIGNhcmRCdXNpbmVzc0NsYXNzOiBhbnk7XHJcbiAgICBASW5wdXQoKSBoZWFkZXI6IGFueTtcclxuICAgIEBJbnB1dCgpIGlkOiBhbnk7XHJcbiAgICBASW5wdXQoKSBwYWdlJCE6IEJlaGF2aW9yU3ViamVjdDxJUGFnZTxhbnk+IHwgbnVsbD47XHJcbiAgICBASW5wdXQoKSBjcnVkU2VydmljZT86IENydWRCYXNlU2VydmljZTxhbnksIGFueSwgYW55LCBhbnk+O1xyXG4gICAgQElucHV0KCkgb3ZlcmZsb3dBY3Rpb25zTWVudTogTWVudUl0ZW1bXSA9IFtdO1xyXG4gICAgaGFzT3ZlcmZsb3dBY3Rpb25zOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBvdmVyZmxvd0FjdGlvbkNvbHVtbnM6IEdyaWRDb2x1bW5bXSA9IFtdO1xyXG4gICAgY3VycmVudEFjdGlvblJvdzogYW55O1xyXG4gICAgQElucHV0KCkgc2VsZWN0S2V5T25seTogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBASW5wdXQoKSBrZXk6IHN0cmluZyA9ICd1aWQnO1xyXG4gICAgLy8gQ29sdW1ucyB3aG9zZSBwZXItY29sdW1uIHN1bW1hcnkgc2hvdWxkIGJlIGRpc3BsYXllZCBpbiB0aGUgS2FuYmFuIGhlYWRlciwgZm9ybWF0dGVkXHJcbiAgICAvLyBieSB0aGVpciBkaXNwbGF5IHR5cGUgKGxpa2UgdGhlIHRhYmxlIGZvb3RlcikuIEVtcHR5IGJ5IGRlZmF1bHQg4oaSIG5vIHN1bW1hcmllcyBzaG93bi5cclxuICAgIEBJbnB1dCgpIHN1bW1hcnlDb2x1bW5zOiBHcmlkQ29sdW1uW10gPSBbXTtcclxuXHJcbiAgICByZWFkb25seSBkaXNwbGF5VHlwZXMgPSBEaXNwbGF5VHlwZXM7XHJcbiAgICBwcml2YXRlIF9wYWdlOiBJUGFnZTxhbnk+ID0gdGhpcy5fZGVmYXVsdFBhZ2U7XHJcbiAgICBASW5wdXQoKSBzZXQgcGFnZSh2YWx1ZTogSVBhZ2U8YW55Pikge1xyXG4gICAgICAgIHRoaXMuX3BhZ2UgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmhhbmRsZVBhZ2VDaGFuZ2UodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBhZ2UoKSA6IElQYWdlPGFueT4geyByZXR1cm4gdGhpcy5fcGFnZTsgfVxyXG5cclxuICAgIGNhcmRzOiBUc2lDYXJkW10gPSBbXTtcclxuICAgIGNhcmRNYXBCeVN0YXR1czogTWFwPHN0cmluZywgVHNpQ2FyZFtdPiA9IG5ldyBNYXAoKTtcclxuXHJcbiAgICAvLyBQb3B1bGF0ZWQgb25seSB3aGVuIHRoZSBwYWdlIGlzIGdyb3VwZWQgc2VydmVyLXNpZGUgKG9uZSBncm91cCBwZXIgc3RhdHVzKTpcclxuICAgIC8vIHRydWUgcGVyLWNvbHVtbiB0b3RhbHMgYW5kIHBlci1jb2x1bW4gc3VtbWFyaWVzLCBpbmRlcGVuZGVudCBvZiB0aGUgY3VycmVudCBwYWdlLlxyXG4gICAgY291bnRCeVN0YXR1czogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcclxuICAgIHN1bW1hcnlCeVN0YXR1czogTWFwPHN0cmluZywgSVN1bW1hcnlGb3JQcm9wcmV0eVtdPiA9IG5ldyBNYXAoKTtcclxuICAgIHByaXZhdGUgX2lzR3JvdXBlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8vIFJlYWwgcGVyLXN0YXR1cyBjb2xvcnMgZnJvbSB0aGUgU3RhdHVzQ29sb3IgYXR0cmlidXRpb24gc3lzdGVtLCBrZXllZCBieSAoYnVzaW5lc3NcclxuICAgIC8vIGNsYXNzLCBzdGF0dXMgZW51bSkuIFVuZGVmaW5lZCB1bnRpbCBsb2FkZWQ7IGNvbHVtbnMvY2FyZHMgc3RheSBkZWZhdWx0IG1lYW53aGlsZS5cclxuICAgIHN0YXR1c01ldGFkYXRhPzogU3RhdHVzTWV0YWRhdGFSZXNwb25zZTtcclxuXHJcbiAgICBkcmFnZ2VkQ2FyZDogVHNpQ2FyZCB8IG51bGwgPSBudWxsO1xyXG4gICAgZmlyc3QgPSAwO1xyXG4gICAgcm93cyA9IDEwO1xyXG4gICAgdG90YWxDb3VudCA9IDA7XHJcbiAgICBpc0xvYWRpbmcgPSBmYWxzZTtcclxuXHJcbiAgICBvcmlnaW5hbFN0YXR1czogc3RyaW5nID0gJyc7XHJcbiAgICBwcmV2aW91c1N0YXR1czogYW55O1xyXG5cclxuICAgIGxvY2FsaXplZFN0YXR1c0xhYmVsczogeyBrZXk6IHN0cmluZzsgbG9jYWxpemVkOiBzdHJpbmcgfVtdID1cclxuICAgICAgICBbXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBfZW50aXR5Q29uZmlnOiBFbnRpdHlDb25maWd1cmF0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9sb2NhbGl6ZTogTG9jYWxpemVQaXBlLFxyXG4gICAgICAgIHByaXZhdGUgX2VudGl0eVN0YXR1c1NlcnZpY2U6IEVudGl0eVN0YXR1c1NlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBfbm90aWZpY2F0aW9uU2VydmljZTogVHNpTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9zdGF0dXNDb2xvclNlcnZpY2U6IFN0YXR1c0NvbG9yU2VydmljZSxcclxuICAgICkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb3ZlcnJpZGUgYXN5bmMgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCdXNpbmVzc0NsYXNzU3RhdHVzKHRoaXMuY2FyZEJ1c2luZXNzQ2xhc3MpO1xyXG5cclxuICAgICAgICAvLyBDb2xvcnMgYXJlIHBhZ2UtaW5kZXBlbmRlbnQsIHNvIHJlc29sdmUgdGhlbSBvbmNlIHVwIGZyb250LiBlbnRpdHlJbmZvIGNhcnJpZXMgdGhlXHJcbiAgICAgICAgLy8gc3RhdHVzIGVudW0gbmFtZSAodGhlIDJuZCBsb29rdXAga2V5KTsgZ2V0RW50aXR5SW5mb0Zyb21DYWNoZSBpcyBjYWNoZWQsIHNvIHRoZSBsYXRlclxyXG4gICAgICAgIC8vIG1hcEl0ZW1zVG9DYXJkcyBjYWxscyByZXVzZSBpdC5cclxuICAgICAgICBhd2FpdCB0aGlzLmdldEVudGl0eUluZm8oKTtcclxuICAgICAgICB0aGlzLmxvYWRTdGF0dXNDb2xvcnMoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wYWdlJC5zdWJzY3JpYmUoYXN5bmMgcGFnZSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChwYWdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9ICEhcGFnZS5sb2FkaW5nO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVQYWdlQ2hhbmdlKHBhZ2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZHJhZ1N0YXJ0KF86IERyYWdFdmVudCwgY2FyZDogVHNpQ2FyZCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuZHJhZ2dlZENhcmQgPSBjYXJkO1xyXG4gICAgICAgIHRoaXMucHJldmlvdXNTdGF0dXMgPSB0aGlzLmRyYWdnZWRDYXJkLnN0YXR1cztcclxuICAgIH1cclxuXHJcbiAgICBkcmFnRW5kKCk6IHZvaWQgeyB0aGlzLmRyYWdnZWRDYXJkID0gbnVsbDsgfVxyXG5cclxuICAgIGFsbG93RHJvcChldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7IGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IH1cclxuXHJcbiAgICB0cmFja0J5U3RhdHVzKGluZGV4OiBudW1iZXIsIHN0YXR1czogeyBrZXk6IHN0cmluZzsgbG9jYWxpemVkOiBzdHJpbmcgfSkgeyByZXR1cm4gc3RhdHVzLmtleTsgfVxyXG5cclxuICAgIHRyYWNrQnlDYXJkKGluZGV4OiBudW1iZXIsIGNhcmQ6IFRzaUNhcmQpIHsgcmV0dXJuIGNhcmQudWlkOyB9XHJcblxyXG4gICAgZHJvcChldmVudDogRHJhZ0V2ZW50LCBuZXdTdGF0dXNLZXk6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGlmICghdGhpcy5kcmFnZ2VkQ2FyZCkgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zdCBjYXJkID0gdGhpcy5kcmFnZ2VkQ2FyZDtcclxuICAgICAgICBjb25zdCBwcmV2aW91c1N0YXR1cyA9IHRoaXMucHJldmlvdXNTdGF0dXM7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmRyYWdnZWRDYXJkLnN0YXR1cyAhPT0gbmV3U3RhdHVzS2V5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhZ2dlZENhcmQuc3RhdHVzID0gbmV3U3RhdHVzS2V5O1xyXG5cclxuICAgICAgICAgICAgbGV0IHVpZCA9IHRoaXMuZHJhZ2dlZENhcmQudWlkITtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuY3J1ZFNlcnZpY2U/LmdldEJ5SWQodWlkKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAgICAgbmV4dDogKHJlc3ApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFsU3RhdHVzS2V5ID0gT2JqZWN0LmtleXMocmVzcCkuZmluZChcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0+IGtleS50b0xvd2VyQ2FzZSgpID09PSB0aGlzLm9yaWdpbmFsU3RhdHVzLnRvTG93ZXJDYXNlKClcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlYWxTdGF0dXNLZXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB1cGRhdGVkSXRlbSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmVzcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWxTdGF0dXNLZXldOiBuZXdTdGF0dXNLZXlcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNydWRTZXJ2aWNlPy51cGRhdGUodXBkYXRlZEl0ZW0sIHVpZCkuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dDogKHJlc3ApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25vdGlmaWNhdGlvblNlcnZpY2Uuc3VjY2Vzcyh0aGlzLl9sb2NhbGl6ZS50cmFuc2Zvcm0oTG9jYWxpemF0aW9uS2V5cy5zYXZlZFN1Y2Nlc3NmdWxseSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUNhcmRNYXAoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHcm91cGVkIGhlYWRlcnMgKHRydWUgdG90YWxzICsgc3VtbWFyaWVzKSBjb21lIGZyb20gdGhlIHNlcnZlciwgc28gYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xpZW50LXNpZGUgcmUtYnVja2V0IGNhbid0IHJlZnJlc2ggdGhlbS4gUmUtZmV0Y2ggdGhlIGN1cnJlbnQgZ3JvdXBlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGFnZSBmb3IgYXV0aG9yaXRhdGl2ZSBmaWd1cmVzIChhbHNvIHJlZmxlY3RzIGFueSBjb25jdXJyZW50IGNoYW5nZXMpLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzR3JvdXBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsbFNlYXJjaC5lbWl0KHsgc2tpcENvdW50OiB0aGlzLmZpcnN0LCBtYXhSZXN1bHRDb3VudDogdGhpcy5yb3dzIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZnJvbSA9IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybShcImdlc2NfcGFyYW1fZXJyb3Jfc3dpdGNoX3N0YXR1c19mcm9tXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRvID0gdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKFwiZ2VzY19wYXJhbV9lcnJvcl9zd2l0Y2hfc3RhdHVzX3RvXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYCR7ZnJvbX0gJyR7dGhpcy5nZXRMb2NhbGl6ZWRTdGF0dXModGhpcy5wcmV2aW91c1N0YXR1cyl9JyAke3RvfSAnJHt0aGlzLmdldExvY2FsaXplZFN0YXR1cyhjYXJkLnN0YXR1cyl9J2A7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcihtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcmQuc3RhdHVzID0gcHJldmlvdXNTdGF0dXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhcmQuc3RhdHVzID0gcHJldmlvdXNTdGF0dXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBvblBhZ2VDaGFuZ2UoZXZlbnQ6IFBhZ2luYXRvclN0YXRlKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5maXJzdCA9IGV2ZW50LmZpcnN0ID8/IDA7XHJcbiAgICAgICAgdGhpcy5yb3dzID0gZXZlbnQucm93cyA/PyAxMDtcclxuICAgICAgICB0aGlzLmNhbGxTZWFyY2guZW1pdCh7IHNraXBDb3VudDogdGhpcy5maXJzdCwgbWF4UmVzdWx0Q291bnQ6IHRoaXMucm93cyB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBGZXRjaCB0aGUgZGVmaW5lZCBjb2xvcnMgZm9yIHRoaXMgZW50aXR5J3Mgc3RhdHVzZXMgb25jZS4gU2tpcHMgd2hlbiB0aGUgYnVzaW5lc3MgY2xhc3NcclxuICAgIC8vIG9yIGl0cyBzdGF0dXMgZW51bSBpcyB1bmtub3duOyBvbiBlcnJvciBjb2x1bW5zIHNpbXBseSBrZWVwIHRoZWlyIGRlZmF1bHQgYmFja2dyb3VuZC5cclxuICAgIHByaXZhdGUgbG9hZFN0YXR1c0NvbG9ycygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBjbGFzc05hbWUgPSB0aGlzLmNhcmRCdXNpbmVzc0NsYXNzO1xyXG4gICAgICAgIGNvbnN0IHN0YXR1c0VudW1OYW1lID0gdGhpcy5lbnRpdHlJbmZvPy5zdGF0dXNFbnVtTmFtZTtcclxuXHJcbiAgICAgICAgaWYgKCFjbGFzc05hbWUgfHwgIXN0YXR1c0VudW1OYW1lKSByZXR1cm47XHJcblxyXG4gICAgICAgIHRoaXMuX3N0YXR1c0NvbG9yU2VydmljZS5nZXRTdGF0dXNDb2xvckRldGFpbHMoY2xhc3NOYW1lLCBzdGF0dXNFbnVtTmFtZSkuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgbmV4dDogKHJlc3BvbnNlOiBTdGF0dXNNZXRhZGF0YVJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c01ldGFkYXRhID0gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZXJyb3I6IGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBsb2FkaW5nIHN0YXR1cyBjb2xvcnMnLCBlcnIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVzb2x2ZSB0aGUgZGVmaW5lZCBoZXggZm9yIGEgc3RhdHVzIHZhbHVlIChjb2x1bW4vY2FyZCBrZXkpLiBVbmRlZmluZWQgd2hlbiBubyBjb2xvciBpc1xyXG4gICAgLy8gZGVmaW5lZCAob3IgdGhlIHN0YXR1cyBoYXMgbm8gbWF0Y2hpbmcgb3B0aW9uLCBlLmcuIHRoZSBzeW50aGV0aWMgJ25ldycgYnVja2V0KS5cclxuICAgIGdldFN0YXR1c0NvbG9ySGV4KHN0YXR1c0tleT86IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XHJcbiAgICAgICAgaWYgKCFzdGF0dXNLZXkpIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdHVzTWV0YWRhdGE/Lm9wdGlvbnMuZmluZChvID0+IG8uc3RhdHVzVmFsdWUgPT09IHN0YXR1c0tleSk/LmNvbG9ySGV4IHx8IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGUgc2luZ2xlIGNvbG9yZWQgZWxlbWVudDogYSBsZWZ0IGFjY2VudCBiYXIgb24gdGhlIGNvbHVtbiBoZWFkZXIsIGluIHRoZSByZWFsIHN0YXR1cyBjb2xvci5cclxuICAgIC8vIFRyYW5zcGFyZW50IChpbnZpc2libGUsIHdpZHRoIHJlc2VydmVkKSB3aGVuIG5vIGNvbG9yIGlzIGRlZmluZWQuIE5vdGhpbmcgZWxzZSBpcyB0aW50ZWQg4oCUXHJcbiAgICAvLyBub3QgdGhlIGhlYWRlciBiYWNrZ3JvdW5kLCBub3QgdGhlIGhlYWRlciB0ZXh0LCBub3QgdGhlIGNhcmRzLlxyXG4gICAgZ2V0Q29sdW1uQWNjZW50Q29sb3Ioc3RhdHVzS2V5Pzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0dXNDb2xvckhleChzdGF0dXNLZXkpID8/ICd0cmFuc3BhcmVudCc7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TG9jYWxpemVkU3RhdHVzKGtleTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoIWtleSkgcmV0dXJuICcnO1xyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gdGhpcy5sb2NhbGl6ZWRTdGF0dXNMYWJlbHMuZmluZChzID0+IHMua2V5ID09PSBrZXkpO1xyXG4gICAgICAgIHJldHVybiBtYXRjaD8ubG9jYWxpemVkID8/IGtleTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBUcnVlIHBlci1jb2x1bW4gdG90YWw6IHRoZSBncm91cCdzIHVucGFnZWQgY291bnQgd2hlbiBncm91cGVkIHNlcnZlci1zaWRlLFxyXG4gICAgLy8gb3RoZXJ3aXNlIHRoZSBudW1iZXIgb2YgY2FyZHMgb24gdGhlIGN1cnJlbnQgcGFnZSAobGVnYWN5IGNsaWVudC1zaWRlIGdyb3VwaW5nKS5cclxuICAgIGdldENvbHVtbkNvdW50KHN0YXR1c0tleTogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAodGhpcy5faXNHcm91cGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvdW50QnlTdGF0dXMuZ2V0KHN0YXR1c0tleSkgPz8gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FyZE1hcEJ5U3RhdHVzLmdldChzdGF0dXNLZXkpPy5sZW5ndGggPz8gMDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBXaGV0aGVyIHBlci1jb2x1bW4gc3VtbWFyaWVzIHNob3VsZCByZW5kZXIgKGdyb3VwZWQgZGF0YSArIGF0IGxlYXN0IG9uZSBvcHRlZC1pbiBjb2x1bW4pLlxyXG4gICAgZ2V0IGhhc0NvbHVtblN1bW1hcmllcygpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faXNHcm91cGVkICYmICh0aGlzLnN1bW1hcnlDb2x1bW5zPy5sZW5ndGggPz8gMCkgPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRoZSBTVU0gZm9yIGEgc3VtbWFyaXplZCBjb2x1bW4gd2l0aGluIGEgc3RhdHVzIGdyb3VwICh1bmRlZmluZWQgd2hlbiBub3QgZ3JvdXBlZCBvciBhYnNlbnQpLlxyXG4gICAgZ2V0Q29sdW1uU3VtbWFyeVZhbHVlKHN0YXR1c0tleTogc3RyaW5nLCBmaWVsZDogc3RyaW5nKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2lzR3JvdXBlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtYXRjaCA9IHRoaXMuc3VtbWFyeUJ5U3RhdHVzLmdldChzdGF0dXNLZXkpXHJcbiAgICAgICAgICAgID8uZmluZChzID0+IHMucHJvcHJldHk/LnRvTG93ZXJDYXNlKCkgPT09IGZpZWxkPy50b0xvd2VyQ2FzZSgpKTtcclxuICAgICAgICByZXR1cm4gbWF0Y2g/LnN1bW1hcnk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBoYW5kbGVQYWdlQ2hhbmdlKHBhZ2U6IElQYWdlPGFueT4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAocGFnZT8uZ3JvdXBzKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlR3JvdXBlZFBhZ2UocGFnZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghcGFnZT8uaXRlbXMpIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5faXNHcm91cGVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5jYXJkcyA9IGF3YWl0IHRoaXMubWFwSXRlbXNUb0NhcmRzKHBhZ2UuaXRlbXMpO1xyXG4gICAgICAgIHRoaXMudG90YWxDb3VudCA9IHBhZ2UudG90YWxDb3VudDtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhcmRNYXAoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTZXJ2ZXItc2lkZSBncm91cGVkIHBhZ2U6IG9uZSBncm91cCBwZXIgc3RhdHVzLCBlYWNoIGNhcnJ5aW5nIGl0cyBvd24gYWNjdXJhdGVcclxuICAgIC8vICh1bnBhZ2VkKSB0b3RhbCBjb3VudCBhbmQgc3VtbWFyaWVzLiBDYXJkcyBvbiB0aGUgY3VycmVudCBwYWdlIGFyZSBtYXBwZWQgYW5kXHJcbiAgICAvLyBidWNrZXRlZCBleGFjdGx5IGFzIGluIHRoZSBmbGF0IHBhdGggKHZpYSB1cGRhdGVDYXJkTWFwKTsgdGhlIHRydWUgcGVyLWNvbHVtblxyXG4gICAgLy8gY291bnRzL3N1bW1hcmllcyBjb21lIGZyb20gdGhlIGdyb3VwcywgYW5kIHRoZSBzaW5nbGUgYm9hcmQgcGFnaW5hdG9yIHNwYW5zIHRoZVxyXG4gICAgLy8gbGFyZ2VzdCBjb2x1bW4gKHNhbWUgc2tpcC90YWtlIHdpbmRvdyBhcHBsaWVkIHRvIGV2ZXJ5IGdyb3VwIGJ5IHRoZSBiYWNrZW5kKS5cclxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlR3JvdXBlZFBhZ2UocGFnZTogSVBhZ2U8YW55Pik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwczogSUdyb3VwZWRSZXN1bHQ8YW55PltdID0gcGFnZS5ncm91cHMgPz8gW107XHJcbiAgICAgICAgY29uc3QgdmFsaWRLZXlzID0gdGhpcy5fc3RhdHVzTGFiZWxzLm1hcChzID0+IHMua2V5KTtcclxuXHJcbiAgICAgICAgY29uc3QgY291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcclxuICAgICAgICBjb25zdCBzdW1tYXJpZXMgPSBuZXcgTWFwPHN0cmluZywgSVN1bW1hcnlGb3JQcm9wcmV0eVtdPigpO1xyXG4gICAgICAgIGxldCBtYXhHcm91cFRvdGFsID0gMDtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBncm91cCBvZiBncm91cHMpIHtcclxuICAgICAgICAgICAgY29uc3QgcmF3S2V5ID0gZ3JvdXAua2V5Py50cmltKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1Y2tldEtleSA9IHJhd0tleSAmJiB2YWxpZEtleXMuaW5jbHVkZXMocmF3S2V5KVxyXG4gICAgICAgICAgICAgICAgPyByYXdLZXlcclxuICAgICAgICAgICAgICAgIDogdGhpcy5fc3RhdHVzTGVzc1JlY29yZHMua2V5O1xyXG5cclxuICAgICAgICAgICAgY291bnRzLnNldChidWNrZXRLZXksIChjb3VudHMuZ2V0KGJ1Y2tldEtleSkgPz8gMCkgKyBncm91cC50b3RhbENvdW50KTtcclxuICAgICAgICAgICAgaWYgKCFzdW1tYXJpZXMuaGFzKGJ1Y2tldEtleSkpIHtcclxuICAgICAgICAgICAgICAgIHN1bW1hcmllcy5zZXQoYnVja2V0S2V5LCBncm91cC5zdW1tYXJpZXMgPz8gW10pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG1heEdyb3VwVG90YWwgPSBNYXRoLm1heChtYXhHcm91cFRvdGFsLCBncm91cC50b3RhbENvdW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIERhdGEgc2hyYW5rIHVuZGVyIGEgbGF0ZXIgcGFnZSAoZHJhZy1kcm9wLCBhIGZpbHRlciwgb3IgYW5vdGhlciB1c2VyJ3MgY2hhbmdlKTpcclxuICAgICAgICAvLyB0aGUgY3VycmVudCBvZmZzZXQgaXMgbm93IHBhc3QgdGhlIGVuZCBvZiBldmVyeSBjb2x1bW4sIHNvIHRoZSBiYWNrZW5kIHJldHVybmVkIGFuXHJcbiAgICAgICAgLy8gZW1wdHkgd2luZG93IGFuZCB0aGUgYm9hcmQgd291bGQgbG9vayBlbXB0eSB1bnRpbCB0aGUgdXNlciBtYW51YWxseSBwYWdlcyBiYWNrLlxyXG4gICAgICAgIC8vIENsYW1wIHRvIHRoZSBsYXN0IHZhbGlkIHBhZ2UgYW5kIHJlLWZldGNoIG9uY2UuIEd1YXJkZWQgYnkgZmlyc3QgPiAwIHNvIGEgbGVnaXRpbWF0ZWx5XHJcbiAgICAgICAgLy8gZW1wdHkgcmVzdWx0IG9uIHRoZSBmaXJzdCBwYWdlIGNhbid0IGxvb3A7IHRoZSBjbGFtcCB0YXJnZXQgaXMgYWx3YXlzIDwgbWF4R3JvdXBUb3RhbCxcclxuICAgICAgICAvLyBzbyB0aGUgcmUtZmV0Y2ggbGFuZHMgb24gYSBwb3B1bGF0ZWQgcGFnZSBhbmQgdGhpcyBicmFuY2ggd29uJ3QgcmUtdHJpZ2dlci5cclxuICAgICAgICBpZiAodGhpcy5maXJzdCA+IDAgJiYgdGhpcy5maXJzdCA+PSBtYXhHcm91cFRvdGFsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmlyc3QgPSBtYXhHcm91cFRvdGFsID4gMFxyXG4gICAgICAgICAgICAgICAgPyBNYXRoLmZsb29yKChtYXhHcm91cFRvdGFsIC0gMSkgLyB0aGlzLnJvd3MpICogdGhpcy5yb3dzXHJcbiAgICAgICAgICAgICAgICA6IDA7XHJcbiAgICAgICAgICAgIHRoaXMuY2FsbFNlYXJjaC5lbWl0KHsgc2tpcENvdW50OiB0aGlzLmZpcnN0LCBtYXhSZXN1bHRDb3VudDogdGhpcy5yb3dzIH0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9pc0dyb3VwZWQgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuY291bnRCeVN0YXR1cyA9IGNvdW50cztcclxuICAgICAgICB0aGlzLnN1bW1hcnlCeVN0YXR1cyA9IHN1bW1hcmllcztcclxuICAgICAgICB0aGlzLnRvdGFsQ291bnQgPSBtYXhHcm91cFRvdGFsO1xyXG4gICAgICAgIHRoaXMuY2FyZHMgPSBhd2FpdCB0aGlzLm1hcEl0ZW1zVG9DYXJkcyhncm91cHMuZmxhdE1hcChnID0+IGcuaXRlbXMgPz8gW10pKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhcmRNYXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGdldEVudGl0eUluZm8oKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgdGhpcy5lbnRpdHlJbmZvID0gYXdhaXQgdGhpcy5fZW50aXR5Q29uZmlnLmdldEVudGl0eUluZm9Gcm9tQ2FjaGUodGhpcy5jYXJkQnVzaW5lc3NDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRDb2xLZXlzKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHBob3RvOiB0aGlzLmVudGl0eUluZm8/LmNhcmRIZWFkZXJQaG90b0NvbHVtbj8udG9Mb3dlckNhc2UoKSA/PyAnJyxcclxuICAgICAgICAgICAgY29sMTogdGhpcy5lbnRpdHlJbmZvPy5jYXJkVGl0bGVDb2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNvbDI6IHRoaXMuZW50aXR5SW5mbz8uY2FyZFN1YkhlYWRlckNvbHVtbj8udG9Mb3dlckNhc2UoKSA/PyAnJyxcclxuICAgICAgICAgICAgY29sMzogdGhpcy5lbnRpdHlJbmZvPy5jYXJkRGVzY3JpcHRpb25Db2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIHN0YXR1czogdGhpcy5lbnRpdHlJbmZvPy5zdGF0dXNDb2x1bW5OYW1lPy50b0xvd2VyQ2FzZSgpID8/ICcnXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIG1hcEl0ZW1zVG9DYXJkcyhpdGVtczogYW55W10pOiBQcm9taXNlPFRzaUNhcmRbXT4ge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0RW50aXR5SW5mbygpO1xyXG5cclxuICAgICAgICBjb25zdCB7IGNvbDEsIGNvbDIsIGNvbDMsIHBob3RvLCBzdGF0dXMgfSA9IHRoaXMuZ2V0Q29sS2V5cygpO1xyXG4gICAgICAgIGNvbnN0IHZhbGlkS2V5cyA9IHRoaXMuX3N0YXR1c0xhYmVscy5tYXAocyA9PiBzLmtleSk7XHJcblxyXG4gICAgICAgIHRoaXMub3JpZ2luYWxTdGF0dXMgPSBzdGF0dXM7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcy5tYXAoKGl0ZW06IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoaXRlbSkucmVkdWNlKChhY2MsIGtleSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgYWNjW2tleS50b0xvd2VyQ2FzZSgpXSA9IGtleTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgICAgICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcmF3U3RhdHVzID0gaXRlbVtrZXlzW3N0YXR1c11dPy50cmltKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzVmFsaWRTdGF0dXMgPSByYXdTdGF0dXMgJiYgdmFsaWRLZXlzLmluY2x1ZGVzKHJhd1N0YXR1cyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbmFsU3RhdHVzID0gaXNWYWxpZFN0YXR1cyA/IHJhd1N0YXR1cyA6ICduZXcnO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGlkOiBpbmRleCArIDEgKyB0aGlzLmZpcnN0LFxyXG4gICAgICAgICAgICAgICAgdWlkOiBgJHtpdGVtLnVpZH1gLFxyXG4gICAgICAgICAgICAgICAgaGVhZGVyVGl0bGU6IGAke2l0ZW1ba2V5c1tjb2wxXV0gPz8gJyd9YCxcclxuICAgICAgICAgICAgICAgIHN1YkhlYWRlclRpdGxlOiBgJHtpdGVtW2tleXNbY29sMl1dID8/ICcnfWAsXHJcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYCR7aXRlbVtrZXlzW2NvbDNdXSA/PyAnJ31gLFxyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBmaW5hbFN0YXR1cyxcclxuICAgICAgICAgICAgICAgIHBob3RvOiBpdGVtW2tleXNbcGhvdG9dXSB8fCBkZWZhdWx0Q2FyZEhlYWRlci5pbWFnZSxcclxuICAgICAgICAgICAgICAgIGZ1bGxSZWNvcmQ6IGl0ZW0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVDYXJkTWFwKCk6IHZvaWQge1xyXG4gICAgICAgIC8vIFNob3cgdGhlIHN0YXR1cy1sZXNzIGNvbHVtbiBvbmx5IHdoZW4gYXQgbGVhc3Qgb25lIGNhcmQgaXMgaW4gdGhlICduZXcnIGJ1Y2tldFxyXG4gICAgICAgIC8vIChhIHJlY29yZCB3aXRoIGFuIGVtcHR5IG9yIHVucmVjb2duaXplZCBzdGF0dXMpLiBSZWNvbXB1dGVkIGhlcmUgc28gdGhlIGNvbHVtblxyXG4gICAgICAgIC8vIHNldCBzdGF5cyBjb25zaXN0ZW50IGFmdGVyIGJvdGggcGFnZSBjaGFuZ2VzIGFuZCBkcmFnLWFuZC1kcm9wIG1vdmVzLlxyXG4gICAgICAgIGNvbnN0IGhhc1N0YXR1c0xlc3MgPSB0aGlzLl9pc0dyb3VwZWRcclxuICAgICAgICAgICAgPyAodGhpcy5jb3VudEJ5U3RhdHVzLmdldCh0aGlzLl9zdGF0dXNMZXNzUmVjb3Jkcy5rZXkpID8/IDApID4gMFxyXG4gICAgICAgICAgICA6IHRoaXMuY2FyZHMuc29tZShjID0+IGMuc3RhdHVzID09PSB0aGlzLl9zdGF0dXNMZXNzUmVjb3Jkcy5rZXkpO1xyXG4gICAgICAgIHRoaXMubG9jYWxpemVkU3RhdHVzTGFiZWxzID0gaGFzU3RhdHVzTGVzc1xyXG4gICAgICAgICAgICA/IFt0aGlzLl9zdGF0dXNMZXNzUmVjb3JkcywgLi4udGhpcy5fc3RhdHVzTGFiZWxzXVxyXG4gICAgICAgICAgICA6IFsuLi50aGlzLl9zdGF0dXNMYWJlbHNdO1xyXG5cclxuICAgICAgICBjb25zdCBtYXAgPSBuZXcgTWFwPHN0cmluZywgVHNpQ2FyZFtdPigpO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGxhYmVsIG9mIHRoaXMubG9jYWxpemVkU3RhdHVzTGFiZWxzKSB7XHJcbiAgICAgICAgICAgIG1hcC5zZXQobGFiZWwua2V5LCBbXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGNhcmQgb2YgdGhpcy5jYXJkcykge1xyXG4gICAgICAgICAgICBjb25zdCBncm91cCA9IG1hcC5nZXQoY2FyZC5zdGF0dXMhKTtcclxuICAgICAgICAgICAgaWYgKGdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICBncm91cC5wdXNoKGNhcmQpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFVubWFwcGVkIGNhcmQgc3RhdHVzOiAke2NhcmQuc3RhdHVzfWAsIGNhcmQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIGNhcmRzXSBvZiBtYXAuZW50cmllcygpKSB7XHJcbiAgICAgICAgICAgIGNhcmRzLnNvcnQoKGEsIGIpID0+IChhLmhlYWRlclRpdGxlID8/ICcnKS5sb2NhbGVDb21wYXJlKGIuaGVhZGVyVGl0bGUgPz8gJycpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuY2FyZE1hcEJ5U3RhdHVzID0gbWFwO1xyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgZ2V0QnVzaW5lc3NDbGFzc1N0YXR1cyhjbGFzc05hbWU/OiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuX2VudGl0eVN0YXR1c1NlcnZpY2UuZ2V0RW50aXR5U3RhdHVzKGNsYXNzTmFtZSkpO1xyXG4gICAgICAgIGNvbnN0IHN0YXR1c2VzID0gcmVzcG9uc2U/LmVudGl0eVN0YXR1cyA/PyBbXTtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdHVzTGVzc1JlY29yZHMubG9jYWxpemVkID0gdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKCdnZXNjX3BhcmFtX2FydGljbGVfc3RhdHV0X2VudW1zX25ldycpLnRyaW0oKTtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdHVzTGFiZWxzID0gc3RhdHVzZXMubWFwKChzOiBhbnkpID0+ICh7XHJcbiAgICAgICAgICAgIGtleTogcy5rZXksXHJcbiAgICAgICAgICAgIGxvY2FsaXplZDogdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKHMudmFsdWUpLnRyaW0oKVxyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRPdmVyZmxvd01lbnVNb2RlbCgpOiBNZW51SXRlbVtdIHtcclxuICAgICAgICBpZiAoIXRoaXMuaGFzT3ZlcmZsb3dBY3Rpb25zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLm92ZXJmbG93QWN0aW9uQ29sdW1ucy5tYXAoY29sID0+ICh7XHJcbiAgICAgICAgICAgIGlkOiBjb2wuZmllbGQsXHJcbiAgICAgICAgICAgIGxhYmVsOiBjb2wuaGVhZGVyLFxyXG4gICAgICAgICAgICBpY29uQ2xhc3M6IGNvbC5idXR0b25JY29uLFxyXG4gICAgICAgICAgICBzdHlsZUNsYXNzOiBjb2wuc3R5bGVDbGFzcyxcclxuICAgICAgICAgICAgaWNvblN0eWxlQ2xhc3M6IGNvbC5pY29uU3R5bGVDbGFzcyxcclxuICAgICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgb3ZlcmZsb3dDb2x1bW5DbGlja2VkKG1lbnU6IE1lbnUsIGV2ZW50OiBFdmVudCwgcm93OiBhbnkpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRBY3Rpb25Sb3cgPSByb3c7XHJcbiAgICAgICAgbWVudS50b2dnbGUoZXZlbnQpO1xyXG4gICAgfVxyXG4gICAgb25PdmVyZmxvd0FjdGlvbkNsaWNrZWQoY2FyZDogVHNpQ2FyZCwgbWVudUl0ZW06IE1lbnVJdGVtKSB7XHJcbiAgICAgICAgaWYgKCFjYXJkIHx8ICFtZW51SXRlbSB8fCAhbWVudUl0ZW0uaWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5oYW5kbGVCdXR0b25DbGlja2VkKGNhcmQ/LmZ1bGxSZWNvcmQgPz8gY2FyZCwgbWVudUl0ZW0uaWQpXHJcbiAgICB9XHJcblxyXG4gICAgaGFuZGxlQnV0dG9uQ2xpY2tlZChpdGVtOiBhbnksIGZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0S2V5T25seSkge1xyXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrZWQuZW1pdCh7IGZpZWxkOiBmaWVsZCwga2V5OiBpdGVtW3RoaXMua2V5XSwgc2VsZWN0S2V5T25seTogdGhpcy5zZWxlY3RLZXlPbmx5IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5idXR0b25DbGlja2VkLmVtaXQoeyBmaWVsZDogZmllbGQsIGtleTogaXRlbSwgc2VsZWN0S2V5T25seTogdGhpcy5zZWxlY3RLZXlPbmx5IH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBlZGl0KHVpZD86IHN0cmluZykge1xyXG4gICAgICAgIGlmICh1aWQpIHtcclxuICAgICAgICAgICAgdGhpcy5vcGVuTW9kYWxDb21wb25lbnQodWlkLCAnZWRpdCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHByaXZhdGUgb3Blbk1vZGFsQ29tcG9uZW50KHVpZDogc3RyaW5nLCBtb2RlOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrZWQuZW1pdCh7IGZpZWxkOiBtb2RlLCBrZXk6IHVpZCwgc2VsZWN0S2V5T25seTogdHJ1ZSB9KTtcclxuICAgIH1cclxuXHJcbn0iLCI8ZGl2IGNsYXNzPVwiY2FyZCBmbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cclxuICA8cC1wYWdpbmF0b3IgW2ZpcnN0XT1cImZpcnN0XCIgW3Jvd3NdPVwicm93c1wiIFt0b3RhbFJlY29yZHNdPVwidG90YWxDb3VudFwiIFtyb3dzUGVyUGFnZU9wdGlvbnNdPVwiWzEsIDEwLCAyNSwgNTBdXCJcclxuICAgIChvblBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIiBbc2hvd0N1cnJlbnRQYWdlUmVwb3J0XT1cInRydWVcIlxyXG4gICAgY3VycmVudFBhZ2VSZXBvcnRUZW1wbGF0ZT1cInt7ICdTaG93aW5nJyB8IGxvY2FsaXplIH19IHtmaXJzdH0ge3sndG8nIHwgbG9jYWxpemV9fSB7bGFzdH0ge3sgJ29mJyB8IGxvY2FsaXplIH19IHt0b3RhbFJlY29yZHN9XCI+XHJcbiAgPC9wLXBhZ2luYXRvcj5cclxuPC9kaXY+XHJcblxyXG48ZGl2IGNsYXNzPVwia2FuYmFuLWJvYXJkIGZsZXggZ2FwLTQgb3ZlcmZsb3ctYXV0b1wiPlxyXG4gIDxkaXYgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBsb2NhbGl6ZWRTdGF0dXNMYWJlbHM7IHRyYWNrQnk6IHRyYWNrQnlTdGF0dXNcIlxyXG4gICAgY2xhc3M9XCJrYW5iYW4tY29sdW1uIGZsZXggZmxleC1jb2x1bW4gYm9yZGVyLXJvdW5kIHN1cmZhY2UtMCBzaGFkb3ctMlwiIChkcmFnb3Zlcik9XCJhbGxvd0Ryb3AoJGV2ZW50KVwiXHJcbiAgICAoZHJvcCk9XCJkcm9wKCRldmVudCwgc3RhdHVzLmtleSlcIj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1uLWhlYWRlciBwLTMgZm9udC1zZW1pYm9sZFwiXHJcbiAgICAgIFtzdHlsZS5ib3JkZXItbGVmdC1jb2xvcl09XCJnZXRDb2x1bW5BY2NlbnRDb2xvcihzdGF0dXMua2V5KVwiPlxyXG4gICAgICB7eyBzdGF0dXMubG9jYWxpemVkIH19XHJcbiAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zbSBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XHJcbiAgICAgICAgKHt7IGdldENvbHVtbkNvdW50KHN0YXR1cy5rZXkpIH19KVxyXG4gICAgICA8L3NwYW4+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIiAqbmdJZj1cImhhc0NvbHVtblN1bW1hcmllc1wiPlxyXG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHN1bUNvbCBvZiBzdW1tYXJ5Q29sdW1uc1wiIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTFcIj5cclxuICAgICAgICAgIDxzcGFuPnt7IChzdW1Db2wuaGVhZGVyID8/IHN1bUNvbC5maWVsZCkgfCBsb2NhbGl6ZSB9fTo8L3NwYW4+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJzdW1Db2wudHlwZVwiPlxyXG4gICAgICAgICAgICA8VHNpLUN1cnJlbmN5LVNvY2lldGUtRGlzcGxheSAqbmdTd2l0Y2hDYXNlPVwiZGlzcGxheVR5cGVzLkNVUlJFTkNZX1NPQ0lFVEVfRElTUExBWVwiXHJcbiAgICAgICAgICAgICAgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUoc3RhdHVzLmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1DdXJyZW5jeS1Tb2NpZXRlLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxUc2ktSW50ZWdlci1EaXNwbGF5ICpuZ1N3aXRjaENhc2U9XCJkaXNwbGF5VHlwZXMuSU5URUdFUl9ESVNQTEFZXCJcclxuICAgICAgICAgICAgICBbaW5wdXREYXRhXT1cImdldENvbHVtblN1bW1hcnlWYWx1ZShzdGF0dXMua2V5LCBzdW1Db2wuZmllbGQpXCI+XHJcbiAgICAgICAgICAgIDwvVHNpLUludGVnZXItRGlzcGxheT5cclxuICAgICAgICAgICAgPFRzaS1SYXRlLURpc3BsYXkgKm5nU3dpdGNoQ2FzZT1cImRpc3BsYXlUeXBlcy5SQVRFX0RJU1BMQVlcIlxyXG4gICAgICAgICAgICAgIFtpc0ZyYWN0aW9uXT1cInN1bUNvbC5pc0ZyYWN0aW9uID8/IGZhbHNlXCIgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUoc3RhdHVzLmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1SYXRlLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxUc2ktRGVjaW1hbC1EaXNwbGF5ICpuZ1N3aXRjaENhc2U9XCJkaXNwbGF5VHlwZXMuREVDSU1BTF9ESVNQTEFZXCJcclxuICAgICAgICAgICAgICBbZm9ybWF0RGVjaW1hbF09XCJzdW1Db2wuZm9ybWF0RGVjaW1hbFwiIFtudW1PZkRlY2ltYWxdPVwic3VtQ29sLm51bU9mRGVjaW1hbFwiXHJcbiAgICAgICAgICAgICAgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUoc3RhdHVzLmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1EZWNpbWFsLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxUc2ktQ3VycmVuY3ktT3RoZXItRGlzcGxheSAqbmdTd2l0Y2hDYXNlPVwiZGlzcGxheVR5cGVzLkNVUlJFTkNZX09USEVSX0RJU1BMQVlcIlxyXG4gICAgICAgICAgICAgIFtjdXJyZW5jeV09XCJzdW1Db2wuY3VycmVuY3lPdGhlckNvZGVcIiBbaW5wdXREYXRhXT1cImdldENvbHVtblN1bW1hcnlWYWx1ZShzdGF0dXMua2V5LCBzdW1Db2wuZmllbGQpXCI+XHJcbiAgICAgICAgICAgIDwvVHNpLUN1cnJlbmN5LU90aGVyLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaERlZmF1bHQ+e3sgZ2V0Q29sdW1uU3VtbWFyeVZhbHVlKHN0YXR1cy5rZXksIHN1bUNvbC5maWVsZCkgfX08L3NwYW4+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1uLWNhcmRzIGZsZXgtMSBvdmVyZmxvdy1hdXRvIHAtM1wiPlxyXG4gICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjYXJkIG9mIGNhcmRNYXBCeVN0YXR1cy5nZXQoc3RhdHVzLmtleSk7IHRyYWNrQnk6IHRyYWNrQnlDYXJkXCJcclxuICAgICAgICBjbGFzcz1cImthbmJhbi1jYXJkIHAtMyBib3JkZXItcm91bmQgYmctd2hpdGUgbWItMyBzaGFkb3ctMVwiXHJcbiAgICAgICAgZHJhZ2dhYmxlPVwidHJ1ZVwiXHJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJkcmFnU3RhcnQoJGV2ZW50LCBjYXJkKVwiIFxyXG4gICAgICAgIChkcmFnZW5kKT1cImRyYWdFbmQoKVwiPlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1ib2xkIG1iLTJcIj57eyBjYXJkLmhlYWRlclRpdGxlIH19PC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc20gdGV4dC1ncmF5LTYwMCBtYi0zXCI+e3sgY2FyZC5zdWJIZWFkZXJUaXRsZSB9fTwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXNtIHRleHQtZ3JheS02MDAgbWItM1wiPnt7IGNhcmQuZGVzY3JpcHRpb24gfX08L2Rpdj5cclxuICAgICAgICA8cC1tZW51IGFwcGVuZFRvPVwiYm9keVwiICNtZW51TW9yZUFjdGlvbnMgXHJcbiAgICAgICAgICAgICBbbW9kZWxdPVwib3ZlcmZsb3dBY3Rpb25zTWVudVwiIFxyXG4gICAgICAgICAgICAgW3BvcHVwXT1cInRydWVcIiBzdHlsZUNsYXNzPVwib3ZlcmZsb3ctbWVudVwiXHJcbiAgICAgICAgICAgICBbc3R5bGVdPVwieyAnd2lkdGgnOiAnYXV0bycsICdtaW4td2lkdGgnOiAnMHB4JyB9XCI+XHJcbiAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaXRlbVwiIGxldC1tZW51SXRlbT5cclxuICAgICAgICAgICAgPGEgcFJpcHBsZSBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyIHAtbWVudWl0ZW0tbGlua1wiIFxyXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLnN0eWxlQ2xhc3NcIlxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJvbk92ZXJmbG93QWN0aW9uQ2xpY2tlZChjYXJkLCBtZW51SXRlbSlcIj5cclxuICAgICAgICAgICAgICA8aSAqbmdJZj1cIm1lbnVJdGVtLmlkID09PSAnbm90ZXMnXCIgY2xhc3M9XCJ7eyBtZW51SXRlbS5pY29uQ2xhc3MgfX0gcC1tZW51aXRlbS1pY29uIGJhZGdlLWljb24gaGFzLWJhZGdlXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLmljb25TdHlsZUNsYXNzXCIgcEJhZGdlIHNldmVyaXR5PVwiZGFuZ2VyXCIgXHJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnRcIlxyXG4gICAgICAgICAgICAgICAgW2JhZGdlRGlzYWJsZWRdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnQgPT0gbnVsbFwiIGJhZGdlUG9zaXRpb249XCJ0b3AtcmlnaHRcIj5cclxuICAgICAgICAgICAgICA8L2k+XHJcblxyXG4gICAgICAgICAgICAgIDxpICpuZ0lmPVwibWVudUl0ZW0uaWQgIT09ICdub3RlcydcIiBjbGFzcz1cInt7bWVudUl0ZW0uaWNvbkNsYXNzfX0gcC1tZW51aXRlbS1pY29uXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLmljb25TdHlsZUNsYXNzXCI+XHJcbiAgICAgICAgICAgICAgPC9pPlxyXG5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lbnUtbGFiZWxcIj5cclxuICAgICAgICAgICAgICAgIHt7IG1lbnVJdGVtLmxhYmVsIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC9wLW1lbnU+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1lbmQgYWxpZ24taXRlbXMtY2VudGVyIG10LTEgZ2FwLTIgcC0wXCI+XHJcbiAgICAgICAgICA8VHNpLUJ1dHRvbiBbc3R5bGVDbGFzc109XCIncC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0IHAtMC01J1wiIHR5cGU9XCJidXR0b25cIiBpY29uPVwicGkgcGktcGVuY2lsXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cImVkaXQoY2FyZC51aWQpXCI+XHJcbiAgICAgICAgICA8L1RzaS1CdXR0b24+XHJcbiAgICAgICAgICA8cC1idXR0b24gdHlwZT1cImJ1dHRvblwiIGljb249XCJwaSBwaS1lbGxpcHNpcy12XCIgc3R5bGVDbGFzcz1cIm92ZXJmbG93LWJ0blwiXHJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cIm92ZXJmbG93Q29sdW1uQ2xpY2tlZChtZW51TW9yZUFjdGlvbnMsICRldmVudCwgY2FyZClcIj5cclxuICAgICAgICAgIDwvcC1idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJvdmVybGF5XCIgKm5nSWY9XCJpc0xvYWRpbmdcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItd3JhcHBlclwiPlxyXG4gICAgICAgIDxhcHAtc3Bpbm5lcj48L2FwcC1zcGlubmVyPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L2Rpdj4iXX0=