@tsi-developpement/tsi-shared-ui 1.11.13 → 1.11.14

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.
@@ -1,7 +1,7 @@
1
- import { Component, EventEmitter, Input, Output } from '@angular/core';
1
+ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
2
2
  import { firstValueFrom } from 'rxjs';
3
3
  import { defaultCardHeader } from '../../consts/tsi-consts';
4
- import { WorkflowEtatKanbanRequest } from '../../models';
4
+ import { WorkflowEtatKanbanMultipleRequest, WorkflowEtatKanbanRequest } from '../../models';
5
5
  import { AppBaseComponent } from '../../tsi-base/components/app-base/app-base.component';
6
6
  import { DisplayTypes } from '../../enums/display-types';
7
7
  import * as i0 from "@angular/core";
@@ -9,36 +9,54 @@ import * as i1 from "../../services/workflow/workflow-configuration.service";
9
9
  import * as i2 from "../../services/configuration/entity-configuration.service";
10
10
  import * as i3 from "../../pipes/localize.pipe";
11
11
  import * as i4 from "../../services/notification/tsi-notification.service";
12
- import * as i5 from "@angular/common";
13
- import * as i6 from "primeng/button";
14
- import * as i7 from "primeng/api";
15
- import * as i8 from "primeng/menu";
16
- import * as i9 from "primeng/paginator";
17
- import * as i10 from "primeng/badge";
18
- import * as i11 from "../output-components/tsi-currency-other-display/tsi-currency-other-display.component";
19
- import * as i12 from "../output-components/tsi-currency-societe-display/tsi-currency-societe-display.component";
20
- import * as i13 from "../output-components/tsi-decimal-display/tsi-decimal-display.component";
21
- import * as i14 from "../output-components/tsi-integer-display/tsi-integer-display.component";
22
- import * as i15 from "../output-components/tsi-rate-display/tsi-rate-display.component";
23
- import * as i16 from "../button-components/tsi-button/tsi-button.component";
24
- import * as i17 from "../spinner/spinner.component";
12
+ import * as i5 from "../../services/notification/tsi-confirmation.service";
13
+ import * as i6 from "../../services/notification/tsi-message.service";
14
+ import * as i7 from "@angular/common";
15
+ import * as i8 from "@angular/forms";
16
+ import * as i9 from "primeng/button";
17
+ import * as i10 from "primeng/api";
18
+ import * as i11 from "primeng/checkbox";
19
+ import * as i12 from "primeng/menu";
20
+ import * as i13 from "primeng/paginator";
21
+ import * as i14 from "primeng/badge";
22
+ import * as i15 from "../output-components/tsi-currency-other-display/tsi-currency-other-display.component";
23
+ import * as i16 from "../output-components/tsi-currency-societe-display/tsi-currency-societe-display.component";
24
+ import * as i17 from "../output-components/tsi-decimal-display/tsi-decimal-display.component";
25
+ import * as i18 from "../output-components/tsi-integer-display/tsi-integer-display.component";
26
+ import * as i19 from "../output-components/tsi-rate-display/tsi-rate-display.component";
27
+ import * as i20 from "../button-components/tsi-button/tsi-button.component";
28
+ import * as i21 from "../spinner/spinner.component";
25
29
  /**
26
30
  * TsiKanbanWorkflowEtatComponent
27
31
  * Description: Displays a Kanban board view for TSI entities using the workflow etat value.
28
32
  */
29
33
  export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
34
+ set cardBusinessClass(value) {
35
+ this._cardBusinessClass = value;
36
+ this.loadEntityInfoAndWorkflowEtats();
37
+ }
38
+ get cardBusinessClass() { return this._cardBusinessClass; }
39
+ set descriminatorValue(value) {
40
+ this._descriminatorValue = value;
41
+ if (this.entityInfo && this.hasDiscriminator) {
42
+ this.loadWorkflowEtatsAndSuivants(value);
43
+ }
44
+ }
45
+ get descriminatorValue() { return this._descriminatorValue; }
30
46
  set page(value) {
31
47
  this._page = value;
32
48
  this.handlePageChange(value);
33
49
  }
34
50
  get page() { return this._page; }
35
- constructor(cdr, _workflowConfigurationService, _entityConfig, _localize, _notificationService) {
51
+ constructor(cdr, _workflowConfigurationService, _entityConfig, _localize, _notificationService, _confirmationService, _messageService) {
36
52
  super();
37
53
  this.cdr = cdr;
38
54
  this._workflowConfigurationService = _workflowConfigurationService;
39
55
  this._entityConfig = _entityConfig;
40
56
  this._localize = _localize;
41
57
  this._notificationService = _notificationService;
58
+ this._confirmationService = _confirmationService;
59
+ this._messageService = _messageService;
42
60
  this.buttonClicked = new EventEmitter();
43
61
  this.callSearch = new EventEmitter();
44
62
  // Columns whose per-column summary should be displayed in the Kanban header, formatted
@@ -60,6 +78,13 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
60
78
  this.rows = 10;
61
79
  this.totalCount = 0;
62
80
  this.isLoading = false;
81
+ // Bulk selection: restricted to a single workflow-etat column (current page only).
82
+ // Dragging any selected card onto another column moves the whole selection.
83
+ this.selectedCardUids = new Set();
84
+ this.selectionColumnKey = null;
85
+ // Allowed next workflow etats per workflow etat, loaded once at init; null if unavailable (the backend still checks every move).
86
+ this.allowedTargetsByWorkflowEtat = null;
87
+ this.isBulkDragging = false;
63
88
  this.workFlowEtatNomLabels = [];
64
89
  this.workFlowEtatNomLabels = [
65
90
  {
@@ -69,8 +94,6 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
69
94
  ];
70
95
  }
71
96
  async ngOnInit() {
72
- await this.getWorkflowEtat(this.descriminatorValue);
73
- await this.getEntityInfo();
74
97
  this.page$.subscribe(async (page) => {
75
98
  if (page) {
76
99
  this.isLoading = !!page.loading;
@@ -78,10 +101,19 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
78
101
  }
79
102
  });
80
103
  }
81
- dragStart(_, card) {
104
+ dragStart(event, card) {
82
105
  this.draggedCard = card;
106
+ // Dragging a selected card while several are selected drags the whole selection;
107
+ // dragging an unselected card (or a single selection) keeps the existing single move.
108
+ this.isBulkDragging = this.selectedCount > 1 && this.isCardSelected(card);
109
+ if (this.isBulkDragging && this.bulkDragPreview && event.dataTransfer) {
110
+ event.dataTransfer.setDragImage(this.bulkDragPreview.nativeElement, 24, 24);
111
+ }
112
+ }
113
+ dragEnd() {
114
+ this.draggedCard = null;
115
+ this.isBulkDragging = false;
83
116
  }
84
- dragEnd() { this.draggedCard = null; }
85
117
  allowDrop(event) { event.preventDefault(); }
86
118
  trackByWorkflowEtat(index, status) { return status.key; }
87
119
  trackByCard(index, card) { return card.uid; }
@@ -93,12 +125,23 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
93
125
  this._notificationService.error("shared_tsi_component_grid_kanban_workflowEtat_view_sans_workflow_forbidden");
94
126
  return;
95
127
  }
128
+ if (this.isBulkDragging) {
129
+ this.dropSelection(newKey);
130
+ this.draggedCard = null;
131
+ this.isBulkDragging = false;
132
+ return;
133
+ }
96
134
  const card = this.draggedCard;
97
135
  const previousWorkflowEtat = this.draggedCard.status;
98
136
  if (previousWorkflowEtat == null) {
99
137
  this._notificationService.error("shared_tsi_component_grid_kanban_workflowEtat_view_no_workflow");
100
138
  return;
101
139
  }
140
+ if (previousWorkflowEtat !== newKey && !this.isAllowedDropTarget(newKey)) {
141
+ this._notificationService.error('shared_tsi_component_grid_kanban_workflowEtat_view_workflow_etat_suivant_error');
142
+ this.draggedCard = null;
143
+ return;
144
+ }
102
145
  if (this.draggedCard.status !== newKey && this.cardBusinessClass) {
103
146
  this.isLoading = true;
104
147
  let request = new WorkflowEtatKanbanRequest();
@@ -112,6 +155,7 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
112
155
  this._workflowConfigurationService.updateWorkflowEtatFromKanbanView(request).subscribe({
113
156
  next: (data) => {
114
157
  card.status = newKey;
158
+ this.removeFromSelection(card.uid);
115
159
  this.updateCardMap();
116
160
  this.isLoading = false;
117
161
  },
@@ -127,10 +171,70 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
127
171
  this.draggedCard = null;
128
172
  }
129
173
  onPageChange(event) {
174
+ this.clearSelection();
130
175
  this.first = event.first ?? 0;
131
176
  this.rows = event.rows ?? 10;
132
177
  this.callSearch.emit({ skipCount: this.first, maxResultCount: this.rows });
133
178
  }
179
+ get selectedCount() {
180
+ return this.selectedCardUids.size;
181
+ }
182
+ // First selected cards, shown as a stack in the bulk drag image.
183
+ get selectedCardsPreview() {
184
+ return this.cards.filter(c => this.isCardSelected(c)).slice(0, 3);
185
+ }
186
+ isCardSelected(card) {
187
+ return !!card.uid && this.selectedCardUids.has(card.uid);
188
+ }
189
+ // Selecting a card in another column restarts the selection in that column.
190
+ toggleCardSelection(columnKey, card) {
191
+ if (!card.uid) {
192
+ return;
193
+ }
194
+ if (this.selectionColumnKey !== columnKey) {
195
+ this.startSelection(columnKey);
196
+ }
197
+ if (this.selectedCardUids.has(card.uid)) {
198
+ this.removeFromSelection(card.uid);
199
+ return;
200
+ }
201
+ this.selectedCardUids.add(card.uid);
202
+ }
203
+ isColumnPageFullySelected(columnKey) {
204
+ const columnCards = this.cardMapByWorkflowEtat.get(columnKey) ?? [];
205
+ return this.selectionColumnKey === columnKey
206
+ && columnCards.length > 0
207
+ && columnCards.every(c => this.isCardSelected(c));
208
+ }
209
+ toggleSelectAllColumnPage(columnKey) {
210
+ if (this.isColumnPageFullySelected(columnKey)) {
211
+ this.clearSelection();
212
+ return;
213
+ }
214
+ if (this.selectionColumnKey !== columnKey) {
215
+ this.startSelection(columnKey);
216
+ }
217
+ (this.cardMapByWorkflowEtat.get(columnKey) ?? []).forEach(c => {
218
+ if (c.uid) {
219
+ this.selectedCardUids.add(c.uid);
220
+ }
221
+ });
222
+ }
223
+ clearSelection() {
224
+ this.selectedCardUids.clear();
225
+ this.selectionColumnKey = null;
226
+ }
227
+ // Used while dragging (one card or a selection), to highlight allowed / forbidden drop columns.
228
+ isAllowedDropTarget(columnKey) {
229
+ const sourceKey = this.draggedCard?.status ?? null;
230
+ if (columnKey === null || sourceKey === null || columnKey === sourceKey) {
231
+ return false;
232
+ }
233
+ if (this.allowedTargetsByWorkflowEtat === null) {
234
+ return true;
235
+ }
236
+ return this.allowedTargetsByWorkflowEtat.get(sourceKey)?.has(columnKey) ?? false;
237
+ }
134
238
  getWorkflowEtatClass(card) {
135
239
  const index = this.workFlowEtatNomLabels.findIndex(l => l.key === card.status);
136
240
  return `workflowEtatColor-${index >= 0 ? index : 'default'}`;
@@ -194,6 +298,8 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
194
298
  this.buttonClicked.emit({ field: mode, key: uid, selectKeyOnly: true });
195
299
  }
196
300
  async handlePageChange(page) {
301
+ // A reload replaces the cards: previously selected uids are no longer reliable.
302
+ this.clearSelection();
197
303
  if (page?.groups) {
198
304
  await this.handleGroupedPage(page);
199
305
  return;
@@ -248,9 +354,99 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
248
354
  this.cards = await this.mapItemsToCards(groups.flatMap(g => g.items ?? []));
249
355
  this.updateCardMap();
250
356
  }
357
+ startSelection(columnKey) {
358
+ this.clearSelection();
359
+ this.selectionColumnKey = columnKey;
360
+ }
361
+ removeFromSelection(uid) {
362
+ if (uid) {
363
+ this.selectedCardUids.delete(uid);
364
+ }
365
+ if (this.selectedCardUids.size === 0) {
366
+ this.clearSelection();
367
+ }
368
+ }
369
+ // Drop of a dragged selection: same guards as the single move, then one confirmation for the batch.
370
+ dropSelection(targetKey) {
371
+ if (targetKey === this.selectionColumnKey || !this.cardBusinessClass) {
372
+ return;
373
+ }
374
+ if (!this.isAllowedDropTarget(targetKey)) {
375
+ this._notificationService.error('shared_tsi_component_grid_kanban_workflowEtat_view_workflow_etat_suivant_error');
376
+ return;
377
+ }
378
+ const confirmMessage = this._localize.transform('shared_tsi_component_grid_kanban_workflowEtat_view_bulk_confirm')
379
+ .replace('{0}', `${this.selectedCount}`)
380
+ .replace('{1}', this.getLocalizedWorkflowEtat(this.selectionColumnKey))
381
+ .replace('{2}', this.getLocalizedWorkflowEtat(targetKey));
382
+ this._confirmationService.confirm(confirmMessage, undefined, (confirmed) => {
383
+ if (confirmed) {
384
+ this.executeBulkMove(targetKey);
385
+ }
386
+ });
387
+ }
388
+ executeBulkMove(targetKey) {
389
+ const request = new WorkflowEtatKanbanMultipleRequest();
390
+ request.businessClass = this.cardBusinessClass;
391
+ request.workFlowEtat = this.selectionColumnKey ?? undefined;
392
+ request.workFlowEtatSuivant = targetKey;
393
+ request.uidObjets = [...this.selectedCardUids];
394
+ request.discriminatorClassName = this.entityInfo?.discriminatorClassName;
395
+ request.discriminatorPropertyName = this.entityInfo?.discriminatorPropertyName;
396
+ request.discriminatorValue = this.descriminatorValue;
397
+ this.isLoading = true;
398
+ this._workflowConfigurationService.updateMultipleWorkflowEtatFromKanbanView(request).subscribe({
399
+ next: (response) => {
400
+ this.showBulkMoveFailures(response);
401
+ this.clearSelection();
402
+ this.isLoading = false;
403
+ this.callSearch.emit({ skipCount: this.first, maxResultCount: this.rows });
404
+ },
405
+ error: (error) => {
406
+ this._notificationService.error(error?.error);
407
+ this.isLoading = false;
408
+ }
409
+ });
410
+ }
411
+ // Only failures are reported; successfully moved cards need no feedback.
412
+ showBulkMoveFailures(response) {
413
+ if (!response?.failed?.length) {
414
+ return;
415
+ }
416
+ const titleByUid = new Map(this.cards.map(c => [c.uid, c.headerTitle]));
417
+ const failureLines = response.failed.map(f => `${titleByUid.get(f.uidObjet) || f.uidObjet} : ${this._localize.transform(f.errorMessage)}`);
418
+ this._messageService.error(`${response.failedCount} / ${response.total} ${this._localize.transform('shared_tsi_component_grid_kanban_workflowEtat_view_bulk_failed')}`, failureLines);
419
+ }
251
420
  async getEntityInfo() {
252
421
  this.entityInfo = await this._entityConfig.getEntityInfoFromCache(this.cardBusinessClass);
253
422
  }
423
+ get hasDiscriminator() {
424
+ return !!(this.entityInfo?.discriminatorClassName || this.entityInfo?.discriminatorPropertyName);
425
+ }
426
+ // Entity info first: it tells whether the workflow etats depend on a discriminator value.
427
+ async loadEntityInfoAndWorkflowEtats() {
428
+ if (!this._cardBusinessClass) {
429
+ return;
430
+ }
431
+ await this.getEntityInfo();
432
+ if (!this.hasDiscriminator) {
433
+ await this.loadWorkflowEtatsAndSuivants();
434
+ }
435
+ else if (this._descriminatorValue) {
436
+ await this.loadWorkflowEtatsAndSuivants(this._descriminatorValue);
437
+ }
438
+ }
439
+ async loadWorkflowEtatsAndSuivants(descriminatorValue) {
440
+ await Promise.all([
441
+ this.getWorkflowEtat(descriminatorValue),
442
+ this.getWorkflowEtatSuivants(descriminatorValue),
443
+ ]);
444
+ // A page may have arrived before the columns were known: re-bucket its cards into them.
445
+ const page = this.page$?.value ?? this._page;
446
+ if (page) {
447
+ await this.handlePageChange(page);
448
+ }
449
+ }
254
450
  getColKeys() {
255
451
  return {
256
452
  photo: this.entityInfo?.cardHeaderPhotoColumn?.toLowerCase() ?? '',
@@ -319,13 +515,26 @@ export class TsiKanbanWorkflowEtatComponent extends AppBaseComponent {
319
515
  console.error('erreur getWorkflowEtatByClassNameAndDescriminator : ', error);
320
516
  }
321
517
  }
322
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiKanbanWorkflowEtatComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.WorkflowConfigurationService }, { token: i2.EntityConfigurationService }, { token: i3.LocalizePipe }, { token: i4.TsiNotificationService }], target: i0.ɵɵFactoryTarget.Component }); }
323
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiKanbanWorkflowEtatComponent, selector: "Tsi-kanban-workflow-etat", inputs: { cardBusinessClass: "cardBusinessClass", header: "header", id: "id", page$: "page$", descriminatorValue: "descriminatorValue", summaryColumns: "summaryColumns", 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\r\n [first]=\"first\"\r\n [rows]=\"rows\"\r\n [totalRecords]=\"totalCount\"\r\n [rowsPerPageOptions]=\"[1, 10, 25, 50]\"\r\n (onPageChange)=\"onPageChange($event)\"\r\n [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 workflowEtat of displayedWorkFlowEtatLabels; trackBy: trackByWorkflowEtat\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\"\r\n (dragover)=\"allowDrop($event)\"\r\n (drop)=\"drop($event, workflowEtat.key)\">\r\n \r\n <div class=\"column-header p-3 border-bottom-1 surface-border font-semibold\">\r\n {{ workflowEtat.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ getColumnCount(workflowEtat.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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Societe-Display>\r\n <Tsi-Integer-Display *ngSwitchCase=\"displayTypes.INTEGER_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(workflowEtat.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(workflowEtat.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(workflowEtat.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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Other-Display>\r\n <span *ngSwitchDefault>{{ getColumnSummaryValue(workflowEtat.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 cardMapByWorkflowEtat.get(workflowEtat.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\"\r\n [ngClass]=\"getWorkflowEtatClass(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.description }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">\r\n <span class=\"font-semibold\">{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_workflow_etat' | localize }}:</span>\r\n <span>{{ getLocalizedWorkflowEtat(card.status) }}</span>\r\n </div>\r\n\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 </div>\r\n</div>\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", 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}.workflowEtatColor-0{border-left-color:#7269ef}.workflowEtatColor-1{border-left-color:#00c853}.workflowEtatColor-2{border-left-color:#ffab00}.workflowEtatColor-3{border-left-color:#d50000}.workflowEtatColor-4{border-left-color:#ff33a8}.workflowEtatColor-5{border-left-color:#3357ff}.workflowEtatColor-6{border-left-color:#ff8c00}.workflowEtatColor-7{border-left-color:indigo}.workflowEtatColor-8{border-left-color:#33ff57}.workflowEtatColor-9{border-left-color:#ff5733}.workflowEtatColor-10{border-left-color:khaki}[class*=workflowEtatColor-]{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: "directive", type: i5.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i5.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i5.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { 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.TsiCurrencyOtherDisplayComponent, selector: "Tsi-Currency-Other-Display", inputs: ["currency", "inputData"] }, { kind: "component", type: i12.TsiCurrencySocieteDisplayComponent, selector: "Tsi-Currency-Societe-Display", inputs: ["inputData"] }, { kind: "component", type: i13.TsiDecimalDisplayComponent, selector: "Tsi-Decimal-Display", inputs: ["inputData", "formatDecimal", "numOfDecimal"] }, { kind: "component", type: i14.TsiIntegerDisplayComponent, selector: "Tsi-Integer-Display", inputs: ["inputData"] }, { kind: "component", type: i15.TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: ["isFraction", "inputData", "numOfDecimal"] }, { kind: "component", type: i16.TsiButtonComponent, selector: "Tsi-Button", inputs: ["disabled", "text", "style", "tooltipText", "tooltipPosition", "buttonType", "icon", "styleClass", "iconSrc", "id", "iconWidth", "iconClass"], outputs: ["onClick", "rightClick"] }, { kind: "component", type: i17.SpinnerComponent, selector: "app-spinner" }, { kind: "pipe", type: i3.LocalizePipe, name: "localize" }] }); }
518
+ async getWorkflowEtatSuivants(descriminatorValue) {
519
+ if (!this.cardBusinessClass) {
520
+ return;
521
+ }
522
+ try {
523
+ const response = await firstValueFrom(this._workflowConfigurationService.getWorkflowEtatSuivantsByClassNameAndDescriminator(this.cardBusinessClass, descriminatorValue));
524
+ this.allowedTargetsByWorkflowEtat = new Map(Object.entries(response ?? {})
525
+ .map(([workflowEtat, suivants]) => [workflowEtat, new Set(suivants)]));
526
+ }
527
+ catch (error) {
528
+ console.error('erreur getWorkflowEtatSuivantsByClassNameAndDescriminator : ', error);
529
+ }
530
+ }
531
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiKanbanWorkflowEtatComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.WorkflowConfigurationService }, { token: i2.EntityConfigurationService }, { token: i3.LocalizePipe }, { token: i4.TsiNotificationService }, { token: i5.TsiConfirmationService }, { token: i6.TsiMessageService }], target: i0.ɵɵFactoryTarget.Component }); }
532
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiKanbanWorkflowEtatComponent, selector: "Tsi-kanban-workflow-etat", inputs: { cardBusinessClass: "cardBusinessClass", header: "header", id: "id", page$: "page$", descriminatorValue: "descriminatorValue", summaryColumns: "summaryColumns", overflowActionsMenu: "overflowActionsMenu", selectKeyOnly: "selectKeyOnly", key: "key", page: "page" }, outputs: { buttonClicked: "buttonClicked", callSearch: "callSearch" }, viewQueries: [{ propertyName: "bulkDragPreview", first: true, predicate: ["bulkDragPreview"], descendants: true }], 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 *ngIf=\"selectedCount > 0\" class=\"kanban-bulk-bar flex flex-wrap align-items-center gap-3 p-2 mx-3 border-round\">\r\n <span class=\"font-semibold\">\r\n {{ selectedCount }} {{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_selected' | localize }}\r\n </span>\r\n <span class=\"text-sm text-gray-600\">\r\n <i class=\"pi pi-arrows-h mr-1\"></i>{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_drag_hint' | localize\r\n }}\r\n </span>\r\n <p-button icon=\"pi pi-times\" styleClass=\"p-button-text\"\r\n [label]=\"'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_clear_selection' | localize\"\r\n [disabled]=\"isLoading\" (onClick)=\"clearSelection()\">\r\n </p-button>\r\n</div>\r\n\r\n<div class=\"kanban-board flex gap-4 overflow-auto\">\r\n <div *ngFor=\"let workflowEtat of displayedWorkFlowEtatLabels; trackBy: trackByWorkflowEtat\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\"\r\n [class.kanban-column-drop-allowed]=\"draggedCard && isAllowedDropTarget(workflowEtat.key)\"\r\n [class.kanban-column-drop-forbidden]=\"draggedCard && workflowEtat.key !== draggedCard.status && !isAllowedDropTarget(workflowEtat.key)\"\r\n (dragover)=\"allowDrop($event)\" (drop)=\"drop($event, workflowEtat.key)\">\r\n\r\n <div class=\"column-header p-3 border-bottom-1 surface-border font-semibold\">\r\n {{ workflowEtat.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ getColumnCount(workflowEtat.key) }})\r\n </span>\r\n <div *ngIf=\"workflowEtat.key !== null && selectionColumnKey === workflowEtat.key\"\r\n class=\"flex align-items-center gap-2 mt-2 text-sm font-normal\">\r\n <p-checkbox [binary]=\"true\" [ngModel]=\"isColumnPageFullySelected(workflowEtat.key)\"\r\n (onChange)=\"toggleSelectAllColumnPage(workflowEtat.key)\" [disabled]=\"isLoading\">\r\n </p-checkbox>\r\n <span>{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_select_all_page' | localize }}</span>\r\n </div>\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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Societe-Display>\r\n <Tsi-Integer-Display *ngSwitchCase=\"displayTypes.INTEGER_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Integer-Display>\r\n <Tsi-Rate-Display *ngSwitchCase=\"displayTypes.RATE_DISPLAY\" [isFraction]=\"sumCol.isFraction ?? false\"\r\n [inputData]=\"getColumnSummaryValue(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Rate-Display>\r\n <Tsi-Decimal-Display *ngSwitchCase=\"displayTypes.DECIMAL_DISPLAY\" [formatDecimal]=\"sumCol.formatDecimal\"\r\n [numOfDecimal]=\"sumCol.numOfDecimal\" [inputData]=\"getColumnSummaryValue(workflowEtat.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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Other-Display>\r\n <span *ngSwitchDefault>{{ getColumnSummaryValue(workflowEtat.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 cardMapByWorkflowEtat.get(workflowEtat.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\" [ngClass]=\"getWorkflowEtatClass(card)\"\r\n [class.kanban-card-selected]=\"isCardSelected(card)\"\r\n [class.kanban-card-drag-source]=\"isBulkDragging && isCardSelected(card)\" draggable=\"true\"\r\n (dragstart)=\"dragStart($event, card)\" (dragend)=\"dragEnd()\">\r\n\r\n <div class=\"flex align-items-center gap-2 mb-2\">\r\n <p-checkbox *ngIf=\"workflowEtat.key !== null\" [binary]=\"true\" [ngModel]=\"isCardSelected(card)\"\r\n (onChange)=\"toggleCardSelection(workflowEtat.key, card)\" [disabled]=\"isLoading\">\r\n </p-checkbox>\r\n <div class=\"font-bold\">{{ card.headerTitle }}</div>\r\n </div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.description }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">\r\n <span class=\"font-semibold\">{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_workflow_etat' | localize\r\n }}:</span>\r\n <span>{{ getLocalizedWorkflowEtat(card.status) }}</span>\r\n </div>\r\n\r\n <p-menu appendTo=\"body\" #menuMoreActions [model]=\"overflowActionsMenu\" [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\" [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\" [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 </div>\r\n</div>\r\n\r\n<div #bulkDragPreview *ngIf=\"selectedCount > 1\" class=\"kanban-bulk-drag-preview\" aria-hidden=\"true\">\r\n <div class=\"kanban-bulk-drag-preview-badge\">\r\n {{ selectedCount }} {{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_selected' | localize }}\r\n </div>\r\n <div *ngFor=\"let previewCard of selectedCardsPreview\" class=\"kanban-bulk-drag-preview-card\"\r\n [ngClass]=\"getWorkflowEtatClass(previewCard)\">\r\n {{ previewCard.headerTitle }}\r\n </div>\r\n <div *ngIf=\"selectedCount > selectedCardsPreview.length\" class=\"kanban-bulk-drag-preview-more\">\r\n + {{ selectedCount - selectedCardsPreview.length }}\r\n </div>\r\n</div>\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}.kanban-card-selected{outline:2px solid var(--primary-color);outline-offset:-2px}.kanban-card-drag-source{opacity:.4}.kanban-bulk-drag-preview{position:fixed;top:-1000px;left:-1000px;width:260px;padding:.5rem;pointer-events:none}.kanban-bulk-drag-preview-badge{display:inline-block;margin-bottom:.5rem;padding:.25rem .75rem;border-radius:1rem;background-color:var(--primary-color);color:var(--primary-color-text);font-weight:600;font-size:.85rem}.kanban-bulk-drag-preview-card{position:relative;padding:.75rem;border-radius:6px;background-color:#fff;box-shadow:0 2px 6px #0003;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kanban-bulk-drag-preview-card+.kanban-bulk-drag-preview-card{margin-top:-.75rem}.kanban-bulk-drag-preview-more{margin-top:.5rem;font-size:.85rem;color:var(--text-color-secondary)}.kanban-bulk-bar{background-color:var(--surface-100)}.kanban-column-drop-allowed{outline:2px dashed var(--green-500);outline-offset:-2px}.kanban-column-drop-forbidden{opacity:.5}.workflowEtatColor-0{border-left-color:#7269ef}.workflowEtatColor-1{border-left-color:#00c853}.workflowEtatColor-2{border-left-color:#ffab00}.workflowEtatColor-3{border-left-color:#d50000}.workflowEtatColor-4{border-left-color:#ff33a8}.workflowEtatColor-5{border-left-color:#3357ff}.workflowEtatColor-6{border-left-color:#ff8c00}.workflowEtatColor-7{border-left-color:indigo}.workflowEtatColor-8{border-left-color:#33ff57}.workflowEtatColor-9{border-left-color:#ff5733}.workflowEtatColor-10{border-left-color:khaki}[class*=workflowEtatColor-]{border-left-style:solid;border-left-width:4px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i7.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i7.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i9.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: i10.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i11.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i12.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: i13.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: i14.BadgeDirective, selector: "[pBadge]", inputs: ["badgeDisabled", "badgeSize", "size", "severity", "value", "badgeStyle", "badgeStyleClass"] }, { kind: "component", type: i15.TsiCurrencyOtherDisplayComponent, selector: "Tsi-Currency-Other-Display", inputs: ["currency", "inputData"] }, { kind: "component", type: i16.TsiCurrencySocieteDisplayComponent, selector: "Tsi-Currency-Societe-Display", inputs: ["inputData"] }, { kind: "component", type: i17.TsiDecimalDisplayComponent, selector: "Tsi-Decimal-Display", inputs: ["inputData", "formatDecimal", "numOfDecimal"] }, { kind: "component", type: i18.TsiIntegerDisplayComponent, selector: "Tsi-Integer-Display", inputs: ["inputData"] }, { kind: "component", type: i19.TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: ["isFraction", "inputData", "numOfDecimal"] }, { kind: "component", type: i20.TsiButtonComponent, selector: "Tsi-Button", inputs: ["disabled", "text", "style", "tooltipText", "tooltipPosition", "buttonType", "icon", "styleClass", "iconSrc", "id", "iconWidth", "iconClass"], outputs: ["onClick", "rightClick"] }, { kind: "component", type: i21.SpinnerComponent, selector: "app-spinner" }, { kind: "pipe", type: i3.LocalizePipe, name: "localize" }] }); }
324
533
  }
325
534
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiKanbanWorkflowEtatComponent, decorators: [{
326
535
  type: Component,
327
- args: [{ selector: 'Tsi-kanban-workflow-etat', template: "<div class=\"card flex justify-content-center\">\r\n <p-paginator\r\n [first]=\"first\"\r\n [rows]=\"rows\"\r\n [totalRecords]=\"totalCount\"\r\n [rowsPerPageOptions]=\"[1, 10, 25, 50]\"\r\n (onPageChange)=\"onPageChange($event)\"\r\n [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 workflowEtat of displayedWorkFlowEtatLabels; trackBy: trackByWorkflowEtat\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\"\r\n (dragover)=\"allowDrop($event)\"\r\n (drop)=\"drop($event, workflowEtat.key)\">\r\n \r\n <div class=\"column-header p-3 border-bottom-1 surface-border font-semibold\">\r\n {{ workflowEtat.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ getColumnCount(workflowEtat.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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Societe-Display>\r\n <Tsi-Integer-Display *ngSwitchCase=\"displayTypes.INTEGER_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(workflowEtat.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(workflowEtat.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(workflowEtat.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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Other-Display>\r\n <span *ngSwitchDefault>{{ getColumnSummaryValue(workflowEtat.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 cardMapByWorkflowEtat.get(workflowEtat.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\"\r\n [ngClass]=\"getWorkflowEtatClass(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.description }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">\r\n <span class=\"font-semibold\">{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_workflow_etat' | localize }}:</span>\r\n <span>{{ getLocalizedWorkflowEtat(card.status) }}</span>\r\n </div>\r\n\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 </div>\r\n</div>\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", 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}.workflowEtatColor-0{border-left-color:#7269ef}.workflowEtatColor-1{border-left-color:#00c853}.workflowEtatColor-2{border-left-color:#ffab00}.workflowEtatColor-3{border-left-color:#d50000}.workflowEtatColor-4{border-left-color:#ff33a8}.workflowEtatColor-5{border-left-color:#3357ff}.workflowEtatColor-6{border-left-color:#ff8c00}.workflowEtatColor-7{border-left-color:indigo}.workflowEtatColor-8{border-left-color:#33ff57}.workflowEtatColor-9{border-left-color:#ff5733}.workflowEtatColor-10{border-left-color:khaki}[class*=workflowEtatColor-]{border-left-style:solid;border-left-width:4px}\n"] }]
328
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.WorkflowConfigurationService }, { type: i2.EntityConfigurationService }, { type: i3.LocalizePipe }, { type: i4.TsiNotificationService }], propDecorators: { buttonClicked: [{
536
+ args: [{ selector: 'Tsi-kanban-workflow-etat', 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 *ngIf=\"selectedCount > 0\" class=\"kanban-bulk-bar flex flex-wrap align-items-center gap-3 p-2 mx-3 border-round\">\r\n <span class=\"font-semibold\">\r\n {{ selectedCount }} {{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_selected' | localize }}\r\n </span>\r\n <span class=\"text-sm text-gray-600\">\r\n <i class=\"pi pi-arrows-h mr-1\"></i>{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_drag_hint' | localize\r\n }}\r\n </span>\r\n <p-button icon=\"pi pi-times\" styleClass=\"p-button-text\"\r\n [label]=\"'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_clear_selection' | localize\"\r\n [disabled]=\"isLoading\" (onClick)=\"clearSelection()\">\r\n </p-button>\r\n</div>\r\n\r\n<div class=\"kanban-board flex gap-4 overflow-auto\">\r\n <div *ngFor=\"let workflowEtat of displayedWorkFlowEtatLabels; trackBy: trackByWorkflowEtat\"\r\n class=\"kanban-column flex flex-column border-round surface-0 shadow-2\"\r\n [class.kanban-column-drop-allowed]=\"draggedCard && isAllowedDropTarget(workflowEtat.key)\"\r\n [class.kanban-column-drop-forbidden]=\"draggedCard && workflowEtat.key !== draggedCard.status && !isAllowedDropTarget(workflowEtat.key)\"\r\n (dragover)=\"allowDrop($event)\" (drop)=\"drop($event, workflowEtat.key)\">\r\n\r\n <div class=\"column-header p-3 border-bottom-1 surface-border font-semibold\">\r\n {{ workflowEtat.localized }}\r\n <span class=\"text-sm font-normal text-gray-500\">\r\n ({{ getColumnCount(workflowEtat.key) }})\r\n </span>\r\n <div *ngIf=\"workflowEtat.key !== null && selectionColumnKey === workflowEtat.key\"\r\n class=\"flex align-items-center gap-2 mt-2 text-sm font-normal\">\r\n <p-checkbox [binary]=\"true\" [ngModel]=\"isColumnPageFullySelected(workflowEtat.key)\"\r\n (onChange)=\"toggleSelectAllColumnPage(workflowEtat.key)\" [disabled]=\"isLoading\">\r\n </p-checkbox>\r\n <span>{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_select_all_page' | localize }}</span>\r\n </div>\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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Societe-Display>\r\n <Tsi-Integer-Display *ngSwitchCase=\"displayTypes.INTEGER_DISPLAY\"\r\n [inputData]=\"getColumnSummaryValue(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Integer-Display>\r\n <Tsi-Rate-Display *ngSwitchCase=\"displayTypes.RATE_DISPLAY\" [isFraction]=\"sumCol.isFraction ?? false\"\r\n [inputData]=\"getColumnSummaryValue(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Rate-Display>\r\n <Tsi-Decimal-Display *ngSwitchCase=\"displayTypes.DECIMAL_DISPLAY\" [formatDecimal]=\"sumCol.formatDecimal\"\r\n [numOfDecimal]=\"sumCol.numOfDecimal\" [inputData]=\"getColumnSummaryValue(workflowEtat.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(workflowEtat.key, sumCol.field)\">\r\n </Tsi-Currency-Other-Display>\r\n <span *ngSwitchDefault>{{ getColumnSummaryValue(workflowEtat.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 cardMapByWorkflowEtat.get(workflowEtat.key); trackBy: trackByCard\"\r\n class=\"kanban-card p-3 border-round bg-white mb-3 shadow-1\" [ngClass]=\"getWorkflowEtatClass(card)\"\r\n [class.kanban-card-selected]=\"isCardSelected(card)\"\r\n [class.kanban-card-drag-source]=\"isBulkDragging && isCardSelected(card)\" draggable=\"true\"\r\n (dragstart)=\"dragStart($event, card)\" (dragend)=\"dragEnd()\">\r\n\r\n <div class=\"flex align-items-center gap-2 mb-2\">\r\n <p-checkbox *ngIf=\"workflowEtat.key !== null\" [binary]=\"true\" [ngModel]=\"isCardSelected(card)\"\r\n (onChange)=\"toggleCardSelection(workflowEtat.key, card)\" [disabled]=\"isLoading\">\r\n </p-checkbox>\r\n <div class=\"font-bold\">{{ card.headerTitle }}</div>\r\n </div>\r\n <div class=\"text-sm text-gray-600 mb-3\">{{ card.description }}</div>\r\n <div class=\"text-sm text-gray-600 mb-3\">\r\n <span class=\"font-semibold\">{{ 'shared_tsi_component_grid_kanban_workflowEtat_view_workflow_etat' | localize\r\n }}:</span>\r\n <span>{{ getLocalizedWorkflowEtat(card.status) }}</span>\r\n </div>\r\n\r\n <p-menu appendTo=\"body\" #menuMoreActions [model]=\"overflowActionsMenu\" [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\" [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\" [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 </div>\r\n</div>\r\n\r\n<div #bulkDragPreview *ngIf=\"selectedCount > 1\" class=\"kanban-bulk-drag-preview\" aria-hidden=\"true\">\r\n <div class=\"kanban-bulk-drag-preview-badge\">\r\n {{ selectedCount }} {{ 'shared_tsi_component_grid_kanban_workflowEtat_view_bulk_selected' | localize }}\r\n </div>\r\n <div *ngFor=\"let previewCard of selectedCardsPreview\" class=\"kanban-bulk-drag-preview-card\"\r\n [ngClass]=\"getWorkflowEtatClass(previewCard)\">\r\n {{ previewCard.headerTitle }}\r\n </div>\r\n <div *ngIf=\"selectedCount > selectedCardsPreview.length\" class=\"kanban-bulk-drag-preview-more\">\r\n + {{ selectedCount - selectedCardsPreview.length }}\r\n </div>\r\n</div>\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}.kanban-card-selected{outline:2px solid var(--primary-color);outline-offset:-2px}.kanban-card-drag-source{opacity:.4}.kanban-bulk-drag-preview{position:fixed;top:-1000px;left:-1000px;width:260px;padding:.5rem;pointer-events:none}.kanban-bulk-drag-preview-badge{display:inline-block;margin-bottom:.5rem;padding:.25rem .75rem;border-radius:1rem;background-color:var(--primary-color);color:var(--primary-color-text);font-weight:600;font-size:.85rem}.kanban-bulk-drag-preview-card{position:relative;padding:.75rem;border-radius:6px;background-color:#fff;box-shadow:0 2px 6px #0003;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kanban-bulk-drag-preview-card+.kanban-bulk-drag-preview-card{margin-top:-.75rem}.kanban-bulk-drag-preview-more{margin-top:.5rem;font-size:.85rem;color:var(--text-color-secondary)}.kanban-bulk-bar{background-color:var(--surface-100)}.kanban-column-drop-allowed{outline:2px dashed var(--green-500);outline-offset:-2px}.kanban-column-drop-forbidden{opacity:.5}.workflowEtatColor-0{border-left-color:#7269ef}.workflowEtatColor-1{border-left-color:#00c853}.workflowEtatColor-2{border-left-color:#ffab00}.workflowEtatColor-3{border-left-color:#d50000}.workflowEtatColor-4{border-left-color:#ff33a8}.workflowEtatColor-5{border-left-color:#3357ff}.workflowEtatColor-6{border-left-color:#ff8c00}.workflowEtatColor-7{border-left-color:indigo}.workflowEtatColor-8{border-left-color:#33ff57}.workflowEtatColor-9{border-left-color:#ff5733}.workflowEtatColor-10{border-left-color:khaki}[class*=workflowEtatColor-]{border-left-style:solid;border-left-width:4px}\n"] }]
537
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.WorkflowConfigurationService }, { type: i2.EntityConfigurationService }, { type: i3.LocalizePipe }, { type: i4.TsiNotificationService }, { type: i5.TsiConfirmationService }, { type: i6.TsiMessageService }], propDecorators: { buttonClicked: [{
329
538
  type: Output
330
539
  }], callSearch: [{
331
540
  type: Output
@@ -349,5 +558,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
349
558
  type: Input
350
559
  }], page: [{
351
560
  type: Input
561
+ }], bulkDragPreview: [{
562
+ type: ViewChild,
563
+ args: ['bulkDragPreview']
352
564
  }] } });
353
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLWthbmJhbi13b3JrZmxvdy1ldGF0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy90c2kta2FuYmFuLXdvcmtmbG93LWV0YXQvdHNpLWthbmJhbi13b3JrZmxvdy1ldGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy90c2kta2FuYmFuLXdvcmtmbG93LWV0YXQvdHNpLWthbmJhbi13b3JrZmxvdy1ldGF0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBcUIsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWxHLE9BQU8sRUFBbUIsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRTVELE9BQU8sRUFBa0gseUJBQXlCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFJekssT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFJekYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBSXpEOzs7R0FHRztBQU1ILE1BQU0sT0FBTyw4QkFBK0IsU0FBUSxnQkFBZ0I7SUFzQmhFLElBQWEsSUFBSSxDQUFDLEtBQWlCO1FBQy9CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBQ0QsSUFBSSxJQUFJLEtBQTZCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7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QXNELEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0UsQ0FBQztJQUNILENBQUM7K0dBcFdRLDhCQUE4QjttR0FBOUIsOEJBQThCLGdiQzFCM0Msd2hMQTJHQTs7NEZEakZhLDhCQUE4QjtrQkFMMUMsU0FBUzsrQkFDSSwwQkFBMEI7ME9BTTFCLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFFRSxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEVBQUU7c0JBQVYsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUdHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csR0FBRztzQkFBWCxLQUFLO2dCQU9PLElBQUk7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBQYWdpbmF0b3JTdGF0ZSB9IGZyb20gJ3ByaW1lbmcvcGFnaW5hdG9yJztcclxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWZhdWx0Q2FyZEhlYWRlciB9IGZyb20gJy4uLy4uL2NvbnN0cy90c2ktY29uc3RzJztcclxuaW1wb3J0IHsgQnV0dG9uQ2xpY2tSZXN1bHQsIEdyaWRDb2x1bW4gfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcclxuaW1wb3J0IHsgR2V0V29ya2Zsb3dJbnN0YW5jZUluZm9ybWF0aW9uUmVxdWVzdCwgVHNpQ2FyZCwgdXBkYXRlRW50aXR5V29ya2Zsb3dJbmZvcm1hdGlvbiwgd29ya2Zsb3dFdGF0RGV0YWlsbGVkUmVzcG9uc2UsIFdvcmtmbG93RXRhdEthbmJhblJlcXVlc3QgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xyXG5pbXBvcnQgeyBMb2NhbGl6ZVBpcGUgfSBmcm9tICcuLi8uLi9waXBlcy9sb2NhbGl6ZS5waXBlJztcclxuaW1wb3J0IHsgRW50aXR5Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jb25maWd1cmF0aW9uL2VudGl0eS1jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBUc2lOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbm90aWZpY2F0aW9uL3RzaS1ub3RpZmljYXRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IEFwcEJhc2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi90c2ktYmFzZS9jb21wb25lbnRzL2FwcC1iYXNlL2FwcC1iYXNlLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFdvcmtmbG93Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy93b3JrZmxvdy93b3JrZmxvdy1jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgSUdyb3VwZWRSZXN1bHQsIElQYWdlLCBJU3VtbWFyeUZvclByb3ByZXR5IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9wYWdpbmF0aW9uL3BhZ2luYXRpb24tYmFzZSc7XHJcbmltcG9ydCB7IERpc3BsYXlUeXBlcyB9IGZyb20gJy4uLy4uL2VudW1zL2Rpc3BsYXktdHlwZXMnO1xyXG5pbXBvcnQgeyBNZW51SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcclxuaW1wb3J0IHsgTWVudSB9IGZyb20gJ3ByaW1lbmcvbWVudSc7XHJcblxyXG4vKipcclxuICogVHNpS2FuYmFuV29ya2Zsb3dFdGF0Q29tcG9uZW50XHJcbiAqIERlc2NyaXB0aW9uOiBEaXNwbGF5cyBhIEthbmJhbiBib2FyZCB2aWV3IGZvciBUU0kgZW50aXRpZXMgdXNpbmcgdGhlIHdvcmtmbG93IGV0YXQgdmFsdWUuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnVHNpLWthbmJhbi13b3JrZmxvdy1ldGF0JyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi90c2kta2FuYmFuLXdvcmtmbG93LWV0YXQuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmw6ICcuL3RzaS1rYW5iYW4td29ya2Zsb3ctZXRhdC5jb21wb25lbnQuc2NzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUc2lLYW5iYW5Xb3JrZmxvd0V0YXRDb21wb25lbnQgZXh0ZW5kcyBBcHBCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuXHJcbiAgICBAT3V0cHV0KCkgYnV0dG9uQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8QnV0dG9uQ2xpY2tSZXN1bHQ+KCk7XHJcbiAgICBAT3V0cHV0KCkgY2FsbFNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIEBJbnB1dCgpIGNhcmRCdXNpbmVzc0NsYXNzOiBhbnk7XHJcbiAgICBASW5wdXQoKSBoZWFkZXI6IGFueTtcclxuICAgIEBJbnB1dCgpIGlkOiBhbnk7XHJcbiAgICBASW5wdXQoKSBwYWdlJCE6IEJlaGF2aW9yU3ViamVjdDxJUGFnZTxhbnk+IHwgbnVsbD47XHJcbiAgICBASW5wdXQoKSBkZXNjcmltaW5hdG9yVmFsdWU/OiBzdHJpbmdcclxuICAgIC8vIENvbHVtbnMgd2hvc2UgcGVyLWNvbHVtbiBzdW1tYXJ5IHNob3VsZCBiZSBkaXNwbGF5ZWQgaW4gdGhlIEthbmJhbiBoZWFkZXIsIGZvcm1hdHRlZFxyXG4gICAgLy8gYnkgdGhlaXIgZGlzcGxheSB0eXBlIChsaWtlIHRoZSB0YWJsZSBmb290ZXIpLiBFbXB0eSBieSBkZWZhdWx0IOKGkiBubyBzdW1tYXJpZXMgc2hvd24uXHJcbiAgICBASW5wdXQoKSBzdW1tYXJ5Q29sdW1uczogR3JpZENvbHVtbltdID0gW107XHJcbiAgICBASW5wdXQoKSBvdmVyZmxvd0FjdGlvbnNNZW51OiBNZW51SXRlbVtdID0gW107XHJcbiAgICBASW5wdXQoKSBzZWxlY3RLZXlPbmx5ID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIGtleSA9ICd1aWQnO1xyXG5cclxuICAgIGN1cnJlbnRBY3Rpb25Sb3c6IGFueTtcclxuXHJcbiAgICByZWFkb25seSBkaXNwbGF5VHlwZXMgPSBEaXNwbGF5VHlwZXM7XHJcblxyXG4gICAgcHJpdmF0ZSBfcGFnZTogSVBhZ2U8YW55PiB8IHVuZGVmaW5lZDtcclxuICAgIEBJbnB1dCgpIHNldCBwYWdlKHZhbHVlOiBJUGFnZTxhbnk+KSB7XHJcbiAgICAgICAgdGhpcy5fcGFnZSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMuaGFuZGxlUGFnZUNoYW5nZSh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBnZXQgcGFnZSgpOiBJUGFnZTxhbnk+IHwgdW5kZWZpbmVkIHsgcmV0dXJuIHRoaXMuX3BhZ2U7IH1cclxuXHJcbiAgICBjYXJkczogVHNpQ2FyZFtdID0gW107XHJcbiAgICBjYXJkTWFwQnlXb3JrZmxvd0V0YXQ6IE1hcDxzdHJpbmcgfCBudWxsLCBUc2lDYXJkW10+ID0gbmV3IE1hcCgpO1xyXG5cclxuICAgIC8vIFBvcHVsYXRlZCBvbmx5IHdoZW4gdGhlIHBhZ2UgaXMgZ3JvdXBlZCBzZXJ2ZXItc2lkZSAob25lIGdyb3VwIHBlciB3b3JrZmxvdyBldGF0KTpcclxuICAgIC8vIHRydWUgcGVyLWNvbHVtbiB0b3RhbHMgYW5kIHBlci1jb2x1bW4gc3VtbWFyaWVzLCBpbmRlcGVuZGVudCBvZiB0aGUgY3VycmVudCBwYWdlLlxyXG4gICAgY291bnRCeVdvcmtmbG93RXRhdDogTWFwPHN0cmluZyB8IG51bGwsIG51bWJlcj4gPSBuZXcgTWFwKCk7XHJcbiAgICBzdW1tYXJ5QnlXb3JrZmxvd0V0YXQ6IE1hcDxzdHJpbmcgfCBudWxsLCBJU3VtbWFyeUZvclByb3ByZXR5W10+ID0gbmV3IE1hcCgpO1xyXG4gICAgcHJpdmF0ZSBfaXNHcm91cGVkID0gZmFsc2U7XHJcblxyXG4gICAgZHJhZ2dlZENhcmQ6IFRzaUNhcmQgfCBudWxsID0gbnVsbDtcclxuICAgIGZpcnN0ID0gMDtcclxuICAgIHJvd3MgPSAxMDtcclxuICAgIHRvdGFsQ291bnQgPSAwO1xyXG4gICAgaXNMb2FkaW5nID0gZmFsc2U7XHJcblxyXG4gICAgd29ya0Zsb3dFdGF0Tm9tTGFiZWxzOiB7IGtleTogc3RyaW5nIHwgbnVsbDsgbG9jYWxpemVkOiBzdHJpbmcgfVtdID1cclxuICAgICAgICBbXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBfd29ya2Zsb3dDb25maWd1cmF0aW9uU2VydmljZTogV29ya2Zsb3dDb25maWd1cmF0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9lbnRpdHlDb25maWc6IEVudGl0eUNvbmZpZ3VyYXRpb25TZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgX2xvY2FsaXplOiBMb2NhbGl6ZVBpcGUsXHJcbiAgICAgICAgcHJpdmF0ZSBfbm90aWZpY2F0aW9uU2VydmljZTogVHNpTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMgPSBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGtleTogbnVsbCxcclxuICAgICAgICAgICAgICAgIGxvY2FsaXplZDogdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKCdzaGFyZWRfdHNpX2NvbXBvbmVudF9ncmlkX2thbmJhbl93b3JrZmxvd0V0YXRfdmlld19zYW5zX3dvcmtmbG93JykudHJpbSgpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBdXHJcbiAgICB9XHJcblxyXG4gICAgb3ZlcnJpZGUgYXN5bmMgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRXb3JrZmxvd0V0YXQodGhpcy5kZXNjcmltaW5hdG9yVmFsdWUpXHJcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRFbnRpdHlJbmZvKCk7XHJcblxyXG4gICAgICAgIHRoaXMucGFnZSQuc3Vic2NyaWJlKGFzeW5jIHBhZ2UgPT4ge1xyXG4gICAgICAgICAgICBpZiAocGFnZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSAhIXBhZ2UubG9hZGluZztcclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlUGFnZUNoYW5nZShwYWdlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGRyYWdTdGFydChfOiBEcmFnRXZlbnQsIGNhcmQ6IFRzaUNhcmQpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gY2FyZDtcclxuICAgIH1cclxuXHJcbiAgICBkcmFnRW5kKCk6IHZvaWQgeyB0aGlzLmRyYWdnZWRDYXJkID0gbnVsbDsgfVxyXG5cclxuICAgIGFsbG93RHJvcChldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7IGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IH1cclxuXHJcbiAgICB0cmFja0J5V29ya2Zsb3dFdGF0KGluZGV4OiBudW1iZXIsIHN0YXR1czogeyBrZXk6IHN0cmluZyB8IG51bGw7IGxvY2FsaXplZDogc3RyaW5nIH0pIHsgcmV0dXJuIHN0YXR1cy5rZXk7IH1cclxuXHJcbiAgICB0cmFja0J5Q2FyZChpbmRleDogbnVtYmVyLCBjYXJkOiBUc2lDYXJkKSB7IHJldHVybiBjYXJkLnVpZDsgfVxyXG5cclxuICAgIGRyb3AoZXZlbnQ6IERyYWdFdmVudCwgbmV3S2V5OiBzdHJpbmcgfCBudWxsKSB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBpZiAoIXRoaXMuZHJhZ2dlZENhcmQpIHJldHVybjtcclxuICAgICAgICBpZihuZXdLZXkgPT0gbnVsbCB8fCBuZXdLZXkgPT0gdW5kZWZpbmVkKVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcihcInNoYXJlZF90c2lfY29tcG9uZW50X2dyaWRfa2FuYmFuX3dvcmtmbG93RXRhdF92aWV3X3NhbnNfd29ya2Zsb3dfZm9yYmlkZGVuXCIpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgY2FyZCA9IHRoaXMuZHJhZ2dlZENhcmQ7XHJcbiAgICAgICAgY29uc3QgcHJldmlvdXNXb3JrZmxvd0V0YXQgPSB0aGlzLmRyYWdnZWRDYXJkLnN0YXR1cztcclxuXHJcbiAgICAgICAgaWYocHJldmlvdXNXb3JrZmxvd0V0YXQgPT0gbnVsbClcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIHRoaXMuX25vdGlmaWNhdGlvblNlcnZpY2UuZXJyb3IoXCJzaGFyZWRfdHNpX2NvbXBvbmVudF9ncmlkX2thbmJhbl93b3JrZmxvd0V0YXRfdmlld19ub193b3JrZmxvd1wiKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICh0aGlzLmRyYWdnZWRDYXJkLnN0YXR1cyAhPT0gbmV3S2V5ICYmIHRoaXMuY2FyZEJ1c2luZXNzQ2xhc3MpIHtcclxuICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlXHJcbiAgICAgICAgICAgIGxldCByZXF1ZXN0OiBXb3JrZmxvd0V0YXRLYW5iYW5SZXF1ZXN0ID0gbmV3IFdvcmtmbG93RXRhdEthbmJhblJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxdWVzdC53b3JrRmxvd0V0YXQgPSB0aGlzLmRyYWdnZWRDYXJkLnN0YXR1c1xyXG4gICAgICAgICAgICByZXF1ZXN0LmJ1c2luZXNzQ2xhc3MgPSB0aGlzLmNhcmRCdXNpbmVzc0NsYXNzLFxyXG4gICAgICAgICAgICByZXF1ZXN0LnVpZE9iamV0ID0gdGhpcy5kcmFnZ2VkQ2FyZC51aWQ7XHJcbiAgICAgICAgICAgIHJlcXVlc3QuZGlzY3JpbWluYXRvckNsYXNzTmFtZSA9IHRoaXMuZW50aXR5SW5mbz8uZGlzY3JpbWluYXRvckNsYXNzTmFtZVxyXG4gICAgICAgICAgICByZXF1ZXN0LmRpc2NyaW1pbmF0b3JQcm9wZXJ0eU5hbWUgPSB0aGlzLmVudGl0eUluZm8/LmRpc2NyaW1pbmF0b3JQcm9wZXJ0eU5hbWVcclxuICAgICAgICAgICAgcmVxdWVzdC5kaXNjcmltaW5hdG9yVmFsdWUgPSB0aGlzLmRlc2NyaW1pbmF0b3JWYWx1ZVxyXG4gICAgICAgICAgICByZXF1ZXN0LndvcmtGbG93RXRhdFN1aXZhbnQgPSBuZXdLZXk7XHJcbiAgICAgICAgICAgIHRoaXMuX3dvcmtmbG93Q29uZmlndXJhdGlvblNlcnZpY2UudXBkYXRlV29ya2Zsb3dFdGF0RnJvbUthbmJhblZpZXcocmVxdWVzdCkuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgICAgIG5leHQ6IChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FyZC5zdGF0dXMgPSBuZXdLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlcnJvcjogKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkgPT5cclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub3RpZmljYXRpb25TZXJ2aWNlLmVycm9yKGVycm9yPy5lcnJvcilcclxuICAgICAgICAgICAgICAgICAgICBjYXJkLnN0YXR1cyA9IHByZXZpb3VzV29ya2Zsb3dFdGF0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2VcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgb25QYWdlQ2hhbmdlKGV2ZW50OiBQYWdpbmF0b3JTdGF0ZSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuZmlyc3QgPSBldmVudC5maXJzdCA/PyAwO1xyXG4gICAgICAgIHRoaXMucm93cyA9IGV2ZW50LnJvd3MgPz8gMTA7XHJcbiAgICAgICAgdGhpcy5jYWxsU2VhcmNoLmVtaXQoeyBza2lwQ291bnQ6IHRoaXMuZmlyc3QsIG1heFJlc3VsdENvdW50OiB0aGlzLnJvd3MgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0V29ya2Zsb3dFdGF0Q2xhc3MoY2FyZDogVHNpQ2FyZCk6IHN0cmluZyB7XHJcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLndvcmtGbG93RXRhdE5vbUxhYmVscy5maW5kSW5kZXgobCA9PiBsLmtleSA9PT0gY2FyZC5zdGF0dXMpO1xyXG4gICAgICAgIHJldHVybiBgd29ya2Zsb3dFdGF0Q29sb3ItJHtpbmRleCA+PSAwID8gaW5kZXggOiAnZGVmYXVsdCd9YDtcclxuICAgIH1cclxuXHJcbiAgICBnZXRMb2NhbGl6ZWRXb3JrZmxvd0V0YXQoa2V5OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoIWtleSkgcmV0dXJuICcnO1xyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMuZmluZChzID0+IHMua2V5ID09PSBrZXkpO1xyXG4gICAgICAgIHJldHVybiBtYXRjaD8ubG9jYWxpemVkID8/IGtleTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBUcnVlIHBlci1jb2x1bW4gdG90YWw6IHRoZSBncm91cCdzIHVucGFnZWQgY291bnQgd2hlbiBncm91cGVkIHNlcnZlci1zaWRlLFxyXG4gICAgLy8gb3RoZXJ3aXNlIHRoZSBudW1iZXIgb2YgY2FyZHMgb24gdGhlIGN1cnJlbnQgcGFnZSAobGVnYWN5IGNsaWVudC1zaWRlIGdyb3VwaW5nKS5cclxuICAgIGdldENvbHVtbkNvdW50KGtleTogc3RyaW5nIHwgbnVsbCk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2lzR3JvdXBlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb3VudEJ5V29ya2Zsb3dFdGF0LmdldChrZXkpID8/IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLmNhcmRNYXBCeVdvcmtmbG93RXRhdC5nZXQoa2V5KT8ubGVuZ3RoID8/IDA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gV2hldGhlciBwZXItY29sdW1uIHN1bW1hcmllcyBzaG91bGQgcmVuZGVyIChncm91cGVkIGRhdGEgKyBhdCBsZWFzdCBvbmUgb3B0ZWQtaW4gY29sdW1uKS5cclxuICAgIGdldCBoYXNDb2x1bW5TdW1tYXJpZXMoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzR3JvdXBlZCAmJiAodGhpcy5zdW1tYXJ5Q29sdW1ucz8ubGVuZ3RoID8/IDApID4gMDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDb2x1bW5zIHRvIHJlbmRlcjogdGhlIFwic2FucyB3b3JrZmxvd1wiIChudWxsLWtleSkgY29sdW1uIGlzIGhpZGRlbiB3aGVuIGl0IGhhcyBubyBjYXJkcztcclxuICAgIC8vIHJlYWwgd29ya2Zsb3ctZXRhdCBjb2x1bW5zIGFsd2F5cyBzaG93IHJlZ2FyZGxlc3Mgb2YgY291bnQuXHJcbiAgICBnZXQgZGlzcGxheWVkV29ya0Zsb3dFdGF0TGFiZWxzKCk6IHsga2V5OiBzdHJpbmcgfCBudWxsOyBsb2NhbGl6ZWQ6IHN0cmluZyB9W10ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLndvcmtGbG93RXRhdE5vbUxhYmVscy5maWx0ZXIobCA9PiBsLmtleSAhPT0gbnVsbCB8fCB0aGlzLmdldENvbHVtbkNvdW50KGwua2V5KSA+IDApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRoZSBTVU0gZm9yIGEgc3VtbWFyaXplZCBjb2x1bW4gd2l0aGluIGEgd29ya2Zsb3ctZXRhdCBncm91cCAodW5kZWZpbmVkIHdoZW4gbm90IGdyb3VwZWQgb3IgYWJzZW50KS5cclxuICAgIGdldENvbHVtblN1bW1hcnlWYWx1ZShrZXk6IHN0cmluZyB8IG51bGwsIGZpZWxkOiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xyXG4gICAgICAgIGlmICghdGhpcy5faXNHcm91cGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gdGhpcy5zdW1tYXJ5QnlXb3JrZmxvd0V0YXQuZ2V0KGtleSlcclxuICAgICAgICAgICAgPy5maW5kKHMgPT4gcy5wcm9wcmV0eT8udG9Mb3dlckNhc2UoKSA9PT0gZmllbGQ/LnRvTG93ZXJDYXNlKCkpO1xyXG4gICAgICAgIHJldHVybiBtYXRjaD8uc3VtbWFyeTtcclxuICAgIH1cclxuXHJcbiAgICBvdmVyZmxvd0NvbHVtbkNsaWNrZWQobWVudTogTWVudSwgZXZlbnQ6IEV2ZW50LCByb3c6IGFueSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudEFjdGlvblJvdyA9IHJvdztcclxuICAgICAgICBtZW51LnRvZ2dsZShldmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25PdmVyZmxvd0FjdGlvbkNsaWNrZWQoY2FyZDogVHNpQ2FyZCwgbWVudUl0ZW06IE1lbnVJdGVtKSB7XHJcbiAgICAgICAgaWYgKCFjYXJkIHx8ICFtZW51SXRlbSB8fCAhbWVudUl0ZW0uaWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5oYW5kbGVCdXR0b25DbGlja2VkKGNhcmQ/LmZ1bGxSZWNvcmQgPz8gY2FyZCwgbWVudUl0ZW0uaWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGhhbmRsZUJ1dHRvbkNsaWNrZWQoaXRlbTogYW55LCBmaWVsZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0S2V5T25seSkge1xyXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrZWQuZW1pdCh7IGZpZWxkOiBmaWVsZCwga2V5OiBpdGVtW3RoaXMua2V5XSwgc2VsZWN0S2V5T25seTogdGhpcy5zZWxlY3RLZXlPbmx5IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5idXR0b25DbGlja2VkLmVtaXQoeyBmaWVsZDogZmllbGQsIGtleTogaXRlbSwgc2VsZWN0S2V5T25seTogdGhpcy5zZWxlY3RLZXlPbmx5IH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBlZGl0KHVpZD86IHN0cmluZykge1xyXG4gICAgICAgIGlmICh1aWQpIHtcclxuICAgICAgICAgICAgdGhpcy5vcGVuTW9kYWxDb21wb25lbnQodWlkLCAnZWRpdCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9wZW5Nb2RhbENvbXBvbmVudCh1aWQ6IHN0cmluZywgbW9kZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5idXR0b25DbGlja2VkLmVtaXQoeyBmaWVsZDogbW9kZSwga2V5OiB1aWQsIHNlbGVjdEtleU9ubHk6IHRydWUgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBoYW5kbGVQYWdlQ2hhbmdlKHBhZ2U6IElQYWdlPGFueT4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAocGFnZT8uZ3JvdXBzKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlR3JvdXBlZFBhZ2UocGFnZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghcGFnZT8uaXRlbXMpIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5faXNHcm91cGVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5jYXJkcyA9IGF3YWl0IHRoaXMubWFwSXRlbXNUb0NhcmRzKHBhZ2UuaXRlbXMpO1xyXG4gICAgICAgIHRoaXMudG90YWxDb3VudCA9IHBhZ2UudG90YWxDb3VudDtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhcmRNYXAoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTZXJ2ZXItc2lkZSBncm91cGVkIHBhZ2U6IG9uZSBncm91cCBwZXIgd29ya2Zsb3cgZXRhdCwgZWFjaCBjYXJyeWluZyBpdHMgb3duIGFjY3VyYXRlXHJcbiAgICAvLyAodW5wYWdlZCkgdG90YWwgY291bnQgYW5kIHN1bW1hcmllcy4gQ2FyZHMgb24gdGhlIGN1cnJlbnQgcGFnZSBhcmUgbWFwcGVkIGFuZCBidWNrZXRlZFxyXG4gICAgLy8gZXhhY3RseSBhcyBpbiB0aGUgZmxhdCBwYXRoICh2aWEgdXBkYXRlQ2FyZE1hcCk7IHRoZSB0cnVlIHBlci1jb2x1bW4gY291bnRzL3N1bW1hcmllc1xyXG4gICAgLy8gY29tZSBmcm9tIHRoZSBncm91cHMsIGFuZCB0aGUgc2luZ2xlIGJvYXJkIHBhZ2luYXRvciBzcGFucyB0aGUgbGFyZ2VzdCBjb2x1bW4gKHNhbWVcclxuICAgIC8vIHNraXAvdGFrZSB3aW5kb3cgYXBwbGllZCB0byBldmVyeSBncm91cCBieSB0aGUgYmFja2VuZCkuXHJcbiAgICBwcml2YXRlIGFzeW5jIGhhbmRsZUdyb3VwZWRQYWdlKHBhZ2U6IElQYWdlPGFueT4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBncm91cHM6IElHcm91cGVkUmVzdWx0PGFueT5bXSA9IHBhZ2UuZ3JvdXBzID8/IFtdO1xyXG4gICAgICAgIGNvbnN0IHZhbGlkS2V5cyA9IHRoaXMud29ya0Zsb3dFdGF0Tm9tTGFiZWxzXHJcbiAgICAgICAgICAgIC5tYXAobCA9PiBsLmtleSlcclxuICAgICAgICAgICAgLmZpbHRlcigoayk6IGsgaXMgc3RyaW5nID0+IGsgIT09IG51bGwpO1xyXG5cclxuICAgICAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwPHN0cmluZyB8IG51bGwsIG51bWJlcj4oKTtcclxuICAgICAgICBjb25zdCBzdW1tYXJpZXMgPSBuZXcgTWFwPHN0cmluZyB8IG51bGwsIElTdW1tYXJ5Rm9yUHJvcHJldHlbXT4oKTtcclxuICAgICAgICBsZXQgbWF4R3JvdXBUb3RhbCA9IDA7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhd0tleSA9IGdyb3VwLmtleT8udHJpbSgpIHx8IG51bGw7XHJcbiAgICAgICAgICAgIGlmIChyYXdLZXkgJiYgIXZhbGlkS2V5cy5pbmNsdWRlcyhyYXdLZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBidWNrZXRLZXkgPSByYXdLZXk7XHJcblxyXG4gICAgICAgICAgICBjb3VudHMuc2V0KGJ1Y2tldEtleSwgKGNvdW50cy5nZXQoYnVja2V0S2V5KSA/PyAwKSArIGdyb3VwLnRvdGFsQ291bnQpO1xyXG4gICAgICAgICAgICBpZiAoIXN1bW1hcmllcy5oYXMoYnVja2V0S2V5KSkge1xyXG4gICAgICAgICAgICAgICAgc3VtbWFyaWVzLnNldChidWNrZXRLZXksIGdyb3VwLnN1bW1hcmllcyA/PyBbXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbWF4R3JvdXBUb3RhbCA9IE1hdGgubWF4KG1heEdyb3VwVG90YWwsIGdyb3VwLnRvdGFsQ291bnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRGF0YSBzaHJhbmsgdW5kZXIgYSBsYXRlciBwYWdlIChkcmFnLWRyb3AsIGEgZmlsdGVyLCBvciBhbm90aGVyIHVzZXIncyBjaGFuZ2UpOlxyXG4gICAgICAgIC8vIHRoZSBjdXJyZW50IG9mZnNldCBpcyBub3cgcGFzdCB0aGUgZW5kIG9mIGV2ZXJ5IGNvbHVtbiwgc28gdGhlIGJhY2tlbmQgcmV0dXJuZWQgYW5cclxuICAgICAgICAvLyBlbXB0eSB3aW5kb3cgYW5kIHRoZSBib2FyZCB3b3VsZCBsb29rIGVtcHR5IHVudGlsIHRoZSB1c2VyIG1hbnVhbGx5IHBhZ2VzIGJhY2suXHJcbiAgICAgICAgLy8gQ2xhbXAgdG8gdGhlIGxhc3QgdmFsaWQgcGFnZSBhbmQgcmUtZmV0Y2ggb25jZS5cclxuICAgICAgICBpZiAodGhpcy5maXJzdCA+IDAgJiYgdGhpcy5maXJzdCA+PSBtYXhHcm91cFRvdGFsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmlyc3QgPSBtYXhHcm91cFRvdGFsID4gMFxyXG4gICAgICAgICAgICAgICAgPyBNYXRoLmZsb29yKChtYXhHcm91cFRvdGFsIC0gMSkgLyB0aGlzLnJvd3MpICogdGhpcy5yb3dzXHJcbiAgICAgICAgICAgICAgICA6IDA7XHJcbiAgICAgICAgICAgIHRoaXMuY2FsbFNlYXJjaC5lbWl0KHsgc2tpcENvdW50OiB0aGlzLmZpcnN0LCBtYXhSZXN1bHRDb3VudDogdGhpcy5yb3dzIH0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9pc0dyb3VwZWQgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuY291bnRCeVdvcmtmbG93RXRhdCA9IGNvdW50cztcclxuICAgICAgICB0aGlzLnN1bW1hcnlCeVdvcmtmbG93RXRhdCA9IHN1bW1hcmllcztcclxuICAgICAgICB0aGlzLnRvdGFsQ291bnQgPSBtYXhHcm91cFRvdGFsO1xyXG4gICAgICAgIHRoaXMuY2FyZHMgPSBhd2FpdCB0aGlzLm1hcEl0ZW1zVG9DYXJkcyhncm91cHMuZmxhdE1hcChnID0+IGcuaXRlbXMgPz8gW10pKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhcmRNYXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGdldEVudGl0eUluZm8oKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgdGhpcy5lbnRpdHlJbmZvID0gYXdhaXQgdGhpcy5fZW50aXR5Q29uZmlnLmdldEVudGl0eUluZm9Gcm9tQ2FjaGUodGhpcy5jYXJkQnVzaW5lc3NDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRDb2xLZXlzKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHBob3RvOiB0aGlzLmVudGl0eUluZm8/LmNhcmRIZWFkZXJQaG90b0NvbHVtbj8udG9Mb3dlckNhc2UoKSA/PyAnJyxcclxuICAgICAgICAgICAgY29sMTogdGhpcy5lbnRpdHlJbmZvPy5jYXJkVGl0bGVDb2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNvbDI6IHRoaXMuZW50aXR5SW5mbz8uY2FyZFN1YkhlYWRlckNvbHVtbj8udG9Mb3dlckNhc2UoKSA/PyAnJyxcclxuICAgICAgICAgICAgY29sMzogdGhpcy5lbnRpdHlJbmZvPy5jYXJkRGVzY3JpcHRpb25Db2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5lbnRpdHlJbmZvPy5jbGFzc05hbWU/LnRvTG93ZXJDYXNlKCkgPz8gJydcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgbWFwSXRlbXNUb0NhcmRzKGl0ZW1zOiBhbnlbXSk6IFByb21pc2U8VHNpQ2FyZFtdPiB7XHJcbiAgICAgICAgY29uc3QgeyBjb2wxLCBjb2wyLCBjb2wzLCBwaG90byB9ID0gdGhpcy5nZXRDb2xLZXlzKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcy5tYXAoKGl0ZW06IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoaXRlbSkucmVkdWNlKChhY2MsIGtleSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgYWNjW2tleS50b0xvd2VyQ2FzZSgpXSA9IGtleTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgICAgICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pO1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgd29ya2Zsb3dFdGF0VmFsdWUgPSBpdGVtLndvcmtmbG93RXRhdCA/PyBudWxsO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGlkOiBpbmRleCArIDEgKyB0aGlzLmZpcnN0LFxyXG4gICAgICAgICAgICAgICAgdWlkOiBgJHtpdGVtLnVpZH1gLFxyXG4gICAgICAgICAgICAgICAgaGVhZGVyVGl0bGU6IGAke2l0ZW1ba2V5c1tjb2wxXV0gPz8gJyd9YCxcclxuICAgICAgICAgICAgICAgIHN1YkhlYWRlclRpdGxlOiBgJHtpdGVtW2tleXNbY29sMl1dID8/ICcnfWAsXHJcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYCR7aXRlbVtrZXlzW2NvbDNdXSA/PyAnJ31gLFxyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiB3b3JrZmxvd0V0YXRWYWx1ZSxcclxuICAgICAgICAgICAgICAgIHBob3RvOiBpdGVtW2tleXNbcGhvdG9dXSB8fCBkZWZhdWx0Q2FyZEhlYWRlci5pbWFnZSxcclxuICAgICAgICAgICAgICAgIGZ1bGxSZWNvcmQ6IGl0ZW0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVDYXJkTWFwKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nIHwgbnVsbCwgVHNpQ2FyZFtdPigpO1xyXG4gICAgICAgIGZvciAoY29uc3QgbGFiZWwgb2YgdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMpIHtcclxuICAgICAgICAgICAgbWFwLnNldChsYWJlbC5rZXksIFtdKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgY2FyZCBvZiB0aGlzLmNhcmRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGNhcmQuc3RhdHVzID8/IG51bGw7XHJcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwID0gbWFwLmdldChrZXkpO1xyXG4gICAgICAgICAgICBpZiAoZ3JvdXApIHtcclxuICAgICAgICAgICAgICAgIGdyb3VwLnB1c2goY2FyZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgVW5tYXBwZWQgY2FyZCBzdGF0dXM6ICR7Y2FyZC5zdGF0dXN9YCwgY2FyZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2FyZHNdIG9mIG1hcC5lbnRyaWVzKCkpIHtcclxuICAgICAgICAgICAgY2FyZHMuc29ydCgoYSwgYikgPT4gKGEuaGVhZGVyVGl0bGUgPz8gJycpLmxvY2FsZUNvbXBhcmUoYi5oZWFkZXJUaXRsZSA/PyAnJykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5jYXJkTWFwQnlXb3JrZmxvd0V0YXQgPSBtYXA7XHJcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9XHJcbiAgICAgICAgXHJcbiAgcHJpdmF0ZSBhc3luYyBnZXRXb3JrZmxvd0V0YXQoZGVzY3JpbWluYXRvclZhbHVlPzogc3RyaW5nKSB7XHJcbiAgICAgIGlmICghdGhpcy5jYXJkQnVzaW5lc3NDbGFzcykge1xyXG4gICAgICAgIHJldHVyblxyXG4gICAgICB9XHJcblxyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5fd29ya2Zsb3dDb25maWd1cmF0aW9uU2VydmljZS5nZXRXb3JrZmxvd0V0YXRCeUNsYXNzTmFtZUFuZERlc2NyaW1pbmF0b3IodGhpcy5jYXJkQnVzaW5lc3NDbGFzcywgZGVzY3JpbWluYXRvclZhbHVlLCB0cnVlKSk7XHJcbiAgICAgICAgdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMgPSBbXHJcbiAgICAgICAgICAgIHsga2V5OiBudWxsLCBsb2NhbGl6ZWQ6IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybSgnc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfc2Fuc193b3JrZmxvdycpLnRyaW0oKSB9LFxyXG4gICAgICAgICAgICAuLi5yZXNwb25zZS5tYXAoKHM6IGFueSkgPT4gKHtcclxuICAgICAgICAgICAgICAgIGtleTogcy5rZXksXHJcbiAgICAgICAgICAgICAgICBsb2NhbGl6ZWQ6IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybShzLnZhbHVlKS50cmltKClcclxuICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgXTtcclxuICAgICAgfVxyXG4gICAgICBjYXRjaChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2VycmV1ciBnZXRXb3JrZmxvd0V0YXRCeUNsYXNzTmFtZUFuZERlc2NyaW1pbmF0b3IgOiAnLCBlcnJvcik7XHJcbiAgICAgIH1cclxuICAgIH1cclxufSIsIjxkaXYgY2xhc3M9XCJjYXJkIGZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gIDxwLXBhZ2luYXRvclxyXG4gICAgW2ZpcnN0XT1cImZpcnN0XCJcclxuICAgIFtyb3dzXT1cInJvd3NcIlxyXG4gICAgW3RvdGFsUmVjb3Jkc109XCJ0b3RhbENvdW50XCJcclxuICAgIFtyb3dzUGVyUGFnZU9wdGlvbnNdPVwiWzEsIDEwLCAyNSwgNTBdXCJcclxuICAgIChvblBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxyXG4gICAgW3Nob3dDdXJyZW50UGFnZVJlcG9ydF09XCJ0cnVlXCJcclxuICAgIGN1cnJlbnRQYWdlUmVwb3J0VGVtcGxhdGU9XCJ7eyAnU2hvd2luZycgfCBsb2NhbGl6ZSB9fSB7Zmlyc3R9IHt7J3RvJyB8IGxvY2FsaXplfX0ge2xhc3R9IHt7ICdvZicgfCBsb2NhbGl6ZSB9fSB7dG90YWxSZWNvcmRzfVwiPlxyXG4gIDwvcC1wYWdpbmF0b3I+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cImthbmJhbi1ib2FyZCBmbGV4IGdhcC00IG92ZXJmbG93LWF1dG9cIj5cclxuICA8ZGl2ICpuZ0Zvcj1cImxldCB3b3JrZmxvd0V0YXQgb2YgZGlzcGxheWVkV29ya0Zsb3dFdGF0TGFiZWxzOyB0cmFja0J5OiB0cmFja0J5V29ya2Zsb3dFdGF0XCJcclxuICAgICAgIGNsYXNzPVwia2FuYmFuLWNvbHVtbiBmbGV4IGZsZXgtY29sdW1uIGJvcmRlci1yb3VuZCBzdXJmYWNlLTAgc2hhZG93LTJcIlxyXG4gICAgICAgKGRyYWdvdmVyKT1cImFsbG93RHJvcCgkZXZlbnQpXCJcclxuICAgICAgIChkcm9wKT1cImRyb3AoJGV2ZW50LCB3b3JrZmxvd0V0YXQua2V5KVwiPlxyXG4gICAgICAgXHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1uLWhlYWRlciBwLTMgYm9yZGVyLWJvdHRvbS0xIHN1cmZhY2UtYm9yZGVyIGZvbnQtc2VtaWJvbGRcIj5cclxuICAgICAge3sgd29ya2Zsb3dFdGF0LmxvY2FsaXplZCB9fVxyXG4gICAgICA8c3BhbiBjbGFzcz1cInRleHQtc20gZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlxyXG4gICAgICAgICh7eyBnZXRDb2x1bW5Db3VudCh3b3JrZmxvd0V0YXQua2V5KSB9fSlcclxuICAgICAgPC9zcGFuPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCIgKm5nSWY9XCJoYXNDb2x1bW5TdW1tYXJpZXNcIj5cclxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBzdW1Db2wgb2Ygc3VtbWFyeUNvbHVtbnNcIiBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0xXCI+XHJcbiAgICAgICAgICA8c3Bhbj57eyAoc3VtQ29sLmhlYWRlciA/PyBzdW1Db2wuZmllbGQpIHwgbG9jYWxpemUgfX06PC9zcGFuPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwic3VtQ29sLnR5cGVcIj5cclxuICAgICAgICAgICAgPFRzaS1DdXJyZW5jeS1Tb2NpZXRlLURpc3BsYXkgKm5nU3dpdGNoQ2FzZT1cImRpc3BsYXlUeXBlcy5DVVJSRU5DWV9TT0NJRVRFX0RJU1BMQVlcIlxyXG4gICAgICAgICAgICAgIFtpbnB1dERhdGFdPVwiZ2V0Q29sdW1uU3VtbWFyeVZhbHVlKHdvcmtmbG93RXRhdC5rZXksIHN1bUNvbC5maWVsZClcIj5cclxuICAgICAgICAgICAgPC9Uc2ktQ3VycmVuY3ktU29jaWV0ZS1EaXNwbGF5PlxyXG4gICAgICAgICAgICA8VHNpLUludGVnZXItRGlzcGxheSAqbmdTd2l0Y2hDYXNlPVwiZGlzcGxheVR5cGVzLklOVEVHRVJfRElTUExBWVwiXHJcbiAgICAgICAgICAgICAgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUod29ya2Zsb3dFdGF0LmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1JbnRlZ2VyLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxUc2ktUmF0ZS1EaXNwbGF5ICpuZ1N3aXRjaENhc2U9XCJkaXNwbGF5VHlwZXMuUkFURV9ESVNQTEFZXCJcclxuICAgICAgICAgICAgICBbaXNGcmFjdGlvbl09XCJzdW1Db2wuaXNGcmFjdGlvbiA/PyBmYWxzZVwiIFtpbnB1dERhdGFdPVwiZ2V0Q29sdW1uU3VtbWFyeVZhbHVlKHdvcmtmbG93RXRhdC5rZXksIHN1bUNvbC5maWVsZClcIj5cclxuICAgICAgICAgICAgPC9Uc2ktUmF0ZS1EaXNwbGF5PlxyXG4gICAgICAgICAgICA8VHNpLURlY2ltYWwtRGlzcGxheSAqbmdTd2l0Y2hDYXNlPVwiZGlzcGxheVR5cGVzLkRFQ0lNQUxfRElTUExBWVwiXHJcbiAgICAgICAgICAgICAgW2Zvcm1hdERlY2ltYWxdPVwic3VtQ29sLmZvcm1hdERlY2ltYWxcIiBbbnVtT2ZEZWNpbWFsXT1cInN1bUNvbC5udW1PZkRlY2ltYWxcIlxyXG4gICAgICAgICAgICAgIFtpbnB1dERhdGFdPVwiZ2V0Q29sdW1uU3VtbWFyeVZhbHVlKHdvcmtmbG93RXRhdC5rZXksIHN1bUNvbC5maWVsZClcIj5cclxuICAgICAgICAgICAgPC9Uc2ktRGVjaW1hbC1EaXNwbGF5PlxyXG4gICAgICAgICAgICA8VHNpLUN1cnJlbmN5LU90aGVyLURpc3BsYXkgKm5nU3dpdGNoQ2FzZT1cImRpc3BsYXlUeXBlcy5DVVJSRU5DWV9PVEhFUl9ESVNQTEFZXCJcclxuICAgICAgICAgICAgICBbY3VycmVuY3ldPVwic3VtQ29sLmN1cnJlbmN5T3RoZXJDb2RlXCIgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUod29ya2Zsb3dFdGF0LmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1DdXJyZW5jeS1PdGhlci1EaXNwbGF5PlxyXG4gICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hEZWZhdWx0Pnt7IGdldENvbHVtblN1bW1hcnlWYWx1ZSh3b3JrZmxvd0V0YXQua2V5LCBzdW1Db2wuZmllbGQpIH19PC9zcGFuPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbi1jYXJkcyBmbGV4LTEgb3ZlcmZsb3ctYXV0byBwLTNcIj5cclxuICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY2FyZCBvZiBjYXJkTWFwQnlXb3JrZmxvd0V0YXQuZ2V0KHdvcmtmbG93RXRhdC5rZXkpOyB0cmFja0J5OiB0cmFja0J5Q2FyZFwiXHJcbiAgICAgICAgICAgY2xhc3M9XCJrYW5iYW4tY2FyZCBwLTMgYm9yZGVyLXJvdW5kIGJnLXdoaXRlIG1iLTMgc2hhZG93LTFcIlxyXG4gICAgICAgICAgIFtuZ0NsYXNzXT1cImdldFdvcmtmbG93RXRhdENsYXNzKGNhcmQpXCJcclxuICAgICAgICAgICBkcmFnZ2FibGU9XCJ0cnVlXCJcclxuICAgICAgICAgICAoZHJhZ3N0YXJ0KT1cImRyYWdTdGFydCgkZXZlbnQsIGNhcmQpXCJcclxuICAgICAgICAgICAoZHJhZ2VuZCk9XCJkcmFnRW5kKClcIj5cclxuICAgICAgICAgICBcclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1ib2xkIG1iLTJcIj57eyBjYXJkLmhlYWRlclRpdGxlIH19PC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc20gdGV4dC1ncmF5LTYwMCBtYi0zXCI+e3sgY2FyZC5kZXNjcmlwdGlvbiB9fTwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXNtIHRleHQtZ3JheS02MDAgbWItM1wiPlxyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb250LXNlbWlib2xkXCI+e3sgJ3NoYXJlZF90c2lfY29tcG9uZW50X2dyaWRfa2FuYmFuX3dvcmtmbG93RXRhdF92aWV3X3dvcmtmbG93X2V0YXQnIHwgbG9jYWxpemUgfX06PC9zcGFuPlxyXG4gICAgICAgICAgPHNwYW4+e3sgZ2V0TG9jYWxpemVkV29ya2Zsb3dFdGF0KGNhcmQuc3RhdHVzKSB9fTwvc3Bhbj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPHAtbWVudSBhcHBlbmRUbz1cImJvZHlcIiAjbWVudU1vcmVBY3Rpb25zXHJcbiAgICAgICAgICAgICBbbW9kZWxdPVwib3ZlcmZsb3dBY3Rpb25zTWVudVwiXHJcbiAgICAgICAgICAgICBbcG9wdXBdPVwidHJ1ZVwiIHN0eWxlQ2xhc3M9XCJvdmVyZmxvdy1tZW51XCJcclxuICAgICAgICAgICAgIFtzdHlsZV09XCJ7ICd3aWR0aCc6ICdhdXRvJywgJ21pbi13aWR0aCc6ICcwcHgnIH1cIj5cclxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpdGVtXCIgbGV0LW1lbnVJdGVtPlxyXG4gICAgICAgICAgICA8YSBwUmlwcGxlIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgcC1tZW51aXRlbS1saW5rXCJcclxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJtZW51SXRlbS5zdHlsZUNsYXNzXCJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwib25PdmVyZmxvd0FjdGlvbkNsaWNrZWQoY2FyZCwgbWVudUl0ZW0pXCI+XHJcbiAgICAgICAgICAgICAgPGkgKm5nSWY9XCJtZW51SXRlbS5pZCA9PT0gJ25vdGVzJ1wiIGNsYXNzPVwie3sgbWVudUl0ZW0uaWNvbkNsYXNzIH19IHAtbWVudWl0ZW0taWNvbiBiYWRnZS1pY29uIGhhcy1iYWRnZVwiXHJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJtZW51SXRlbS5pY29uU3R5bGVDbGFzc1wiIHBCYWRnZSBzZXZlcml0eT1cImRhbmdlclwiXHJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnRcIlxyXG4gICAgICAgICAgICAgICAgW2JhZGdlRGlzYWJsZWRdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnQgPT0gbnVsbFwiIGJhZGdlUG9zaXRpb249XCJ0b3AtcmlnaHRcIj5cclxuICAgICAgICAgICAgICA8L2k+XHJcblxyXG4gICAgICAgICAgICAgIDxpICpuZ0lmPVwibWVudUl0ZW0uaWQgIT09ICdub3RlcydcIiBjbGFzcz1cInt7bWVudUl0ZW0uaWNvbkNsYXNzfX0gcC1tZW51aXRlbS1pY29uXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLmljb25TdHlsZUNsYXNzXCI+XHJcbiAgICAgICAgICAgICAgPC9pPlxyXG5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lbnUtbGFiZWxcIj5cclxuICAgICAgICAgICAgICAgIHt7IG1lbnVJdGVtLmxhYmVsIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC9wLW1lbnU+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1lbmQgYWxpZ24taXRlbXMtY2VudGVyIG10LTEgZ2FwLTIgcC0wXCI+XHJcbiAgICAgICAgICA8VHNpLUJ1dHRvbiBbc3R5bGVDbGFzc109XCIncC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0IHAtMC01J1wiIHR5cGU9XCJidXR0b25cIiBpY29uPVwicGkgcGktcGVuY2lsXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cImVkaXQoY2FyZC51aWQpXCI+XHJcbiAgICAgICAgICA8L1RzaS1CdXR0b24+XHJcbiAgICAgICAgICA8cC1idXR0b24gdHlwZT1cImJ1dHRvblwiIGljb249XCJwaSBwaS1lbGxpcHNpcy12XCIgc3R5bGVDbGFzcz1cIm92ZXJmbG93LWJ0blwiXHJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cIm92ZXJmbG93Q29sdW1uQ2xpY2tlZChtZW51TW9yZUFjdGlvbnMsICRldmVudCwgY2FyZClcIj5cclxuICAgICAgICAgIDwvcC1idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cIm92ZXJsYXlcIiAqbmdJZj1cImlzTG9hZGluZ1wiPlxyXG4gIDxkaXYgY2xhc3M9XCJzcGlubmVyLXdyYXBwZXJcIj5cclxuICAgIDxhcHAtc3Bpbm5lcj48L2FwcC1zcGlubmVyPlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxuIl19
565
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLWthbmJhbi13b3JrZmxvdy1ldGF0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy90c2kta2FuYmFuLXdvcmtmbG93LWV0YXQvdHNpLWthbmJhbi13b3JrZmxvdy1ldGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy90c2kta2FuYmFuLXdvcmtmbG93LWV0YXQvdHNpLWthbmJhbi13b3JrZmxvdy1ldGF0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBcUIsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6SCxPQUFPLEVBQW1CLGNBQWMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUU1RCxPQUFPLEVBQVksaUNBQWlDLEVBQXNDLHlCQUF5QixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBTTFJLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVEQUF1RCxDQUFDO0FBSXpGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFJekQ7OztHQUdHO0FBTUgsTUFBTSxPQUFPLDhCQUErQixTQUFRLGdCQUFnQjtJQU1oRSxJQUFhLGlCQUFpQixDQUFDLEtBQVU7UUFDckMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztRQUNoQyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsSUFBSSxpQkFBaUIsS0FBVSxPQUFPLElBQUksQ0FBQyxr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LE9BQU8sQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO2lCQUNyRSxHQUFHLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxZQUFZLEVBQUUsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0UsQ0FBQztRQUNELE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDhEQUE4RCxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pGLENBQUM7SUFDTCxDQUFDOytHQTNsQlEsOEJBQThCO21HQUE5Qiw4QkFBOEIsb2lCQzVCM0MseTdQQXdJTTs7NEZENUdPLDhCQUE4QjtrQkFMMUMsU0FBUzsrQkFDSSwwQkFBMEI7K1NBTTFCLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFHTSxpQkFBaUI7c0JBQTdCLEtBQUs7Z0JBTUcsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEVBQUU7c0JBQVYsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR08sa0JBQWtCO3NCQUE5QixLQUFLO2dCQVNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csR0FBRztzQkFBWCxLQUFLO2dCQU9PLElBQUk7c0JBQWhCLEtBQUs7Z0JBNkJ3QixlQUFlO3NCQUE1QyxTQUFTO3VCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUGFnaW5hdG9yU3RhdGUgfSBmcm9tICdwcmltZW5nL3BhZ2luYXRvcic7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVmYXVsdENhcmRIZWFkZXIgfSBmcm9tICcuLi8uLi9jb25zdHMvdHNpLWNvbnN0cyc7XHJcbmltcG9ydCB7IEJ1dHRvbkNsaWNrUmVzdWx0LCBHcmlkQ29sdW1uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7IFRzaUNhcmQsICBXb3JrZmxvd0V0YXRLYW5iYW5NdWx0aXBsZVJlcXVlc3QsIFdvcmtmbG93RXRhdEthbmJhbk11bHRpcGxlUmVzcG9uc2UsIFdvcmtmbG93RXRhdEthbmJhblJlcXVlc3QgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xyXG5pbXBvcnQgeyBMb2NhbGl6ZVBpcGUgfSBmcm9tICcuLi8uLi9waXBlcy9sb2NhbGl6ZS5waXBlJztcclxuaW1wb3J0IHsgRW50aXR5Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jb25maWd1cmF0aW9uL2VudGl0eS1jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBUc2lOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbm90aWZpY2F0aW9uL3RzaS1ub3RpZmljYXRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IFRzaUNvbmZpcm1hdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub3RpZmljYXRpb24vdHNpLWNvbmZpcm1hdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVHNpTWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub3RpZmljYXRpb24vdHNpLW1lc3NhZ2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IEFwcEJhc2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi90c2ktYmFzZS9jb21wb25lbnRzL2FwcC1iYXNlL2FwcC1iYXNlLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFdvcmtmbG93Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy93b3JrZmxvdy93b3JrZmxvdy1jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgSUdyb3VwZWRSZXN1bHQsIElQYWdlLCBJU3VtbWFyeUZvclByb3ByZXR5IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9wYWdpbmF0aW9uL3BhZ2luYXRpb24tYmFzZSc7XHJcbmltcG9ydCB7IERpc3BsYXlUeXBlcyB9IGZyb20gJy4uLy4uL2VudW1zL2Rpc3BsYXktdHlwZXMnO1xyXG5pbXBvcnQgeyBNZW51SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcclxuaW1wb3J0IHsgTWVudSB9IGZyb20gJ3ByaW1lbmcvbWVudSc7XHJcblxyXG4vKipcclxuICogVHNpS2FuYmFuV29ya2Zsb3dFdGF0Q29tcG9uZW50XHJcbiAqIERlc2NyaXB0aW9uOiBEaXNwbGF5cyBhIEthbmJhbiBib2FyZCB2aWV3IGZvciBUU0kgZW50aXRpZXMgdXNpbmcgdGhlIHdvcmtmbG93IGV0YXQgdmFsdWUuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnVHNpLWthbmJhbi13b3JrZmxvdy1ldGF0JyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi90c2kta2FuYmFuLXdvcmtmbG93LWV0YXQuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmw6ICcuL3RzaS1rYW5iYW4td29ya2Zsb3ctZXRhdC5jb21wb25lbnQuc2NzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUc2lLYW5iYW5Xb3JrZmxvd0V0YXRDb21wb25lbnQgZXh0ZW5kcyBBcHBCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuXHJcbiAgICBAT3V0cHV0KCkgYnV0dG9uQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8QnV0dG9uQ2xpY2tSZXN1bHQ+KCk7XHJcbiAgICBAT3V0cHV0KCkgY2FsbFNlYXJjaCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIHByaXZhdGUgX2NhcmRCdXNpbmVzc0NsYXNzOiBhbnk7XHJcbiAgICBASW5wdXQoKSBzZXQgY2FyZEJ1c2luZXNzQ2xhc3ModmFsdWU6IGFueSkge1xyXG4gICAgICAgIHRoaXMuX2NhcmRCdXNpbmVzc0NsYXNzID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5sb2FkRW50aXR5SW5mb0FuZFdvcmtmbG93RXRhdHMoKTtcclxuICAgIH1cclxuICAgIGdldCBjYXJkQnVzaW5lc3NDbGFzcygpOiBhbnkgeyByZXR1cm4gdGhpcy5fY2FyZEJ1c2luZXNzQ2xhc3M7IH1cclxuXHJcbiAgICBASW5wdXQoKSBoZWFkZXI6IGFueTtcclxuICAgIEBJbnB1dCgpIGlkOiBhbnk7XHJcbiAgICBASW5wdXQoKSBwYWdlJCE6IEJlaGF2aW9yU3ViamVjdDxJUGFnZTxhbnk+IHwgbnVsbD47XHJcblxyXG4gICAgcHJpdmF0ZSBfZGVzY3JpbWluYXRvclZhbHVlPzogc3RyaW5nO1xyXG4gICAgQElucHV0KCkgc2V0IGRlc2NyaW1pbmF0b3JWYWx1ZSh2YWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgdGhpcy5fZGVzY3JpbWluYXRvclZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgaWYgKHRoaXMuZW50aXR5SW5mbyAmJiB0aGlzLmhhc0Rpc2NyaW1pbmF0b3IpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2FkV29ya2Zsb3dFdGF0c0FuZFN1aXZhbnRzKHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgZGVzY3JpbWluYXRvclZhbHVlKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7IHJldHVybiB0aGlzLl9kZXNjcmltaW5hdG9yVmFsdWU7IH1cclxuICAgIC8vIENvbHVtbnMgd2hvc2UgcGVyLWNvbHVtbiBzdW1tYXJ5IHNob3VsZCBiZSBkaXNwbGF5ZWQgaW4gdGhlIEthbmJhbiBoZWFkZXIsIGZvcm1hdHRlZFxyXG4gICAgLy8gYnkgdGhlaXIgZGlzcGxheSB0eXBlIChsaWtlIHRoZSB0YWJsZSBmb290ZXIpLiBFbXB0eSBieSBkZWZhdWx0IOKGkiBubyBzdW1tYXJpZXMgc2hvd24uXHJcbiAgICBASW5wdXQoKSBzdW1tYXJ5Q29sdW1uczogR3JpZENvbHVtbltdID0gW107XHJcbiAgICBASW5wdXQoKSBvdmVyZmxvd0FjdGlvbnNNZW51OiBNZW51SXRlbVtdID0gW107XHJcbiAgICBASW5wdXQoKSBzZWxlY3RLZXlPbmx5ID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIGtleSA9ICd1aWQnO1xyXG5cclxuICAgIGN1cnJlbnRBY3Rpb25Sb3c6IGFueTtcclxuXHJcbiAgICByZWFkb25seSBkaXNwbGF5VHlwZXMgPSBEaXNwbGF5VHlwZXM7XHJcblxyXG4gICAgcHJpdmF0ZSBfcGFnZTogSVBhZ2U8YW55PiB8IHVuZGVmaW5lZDtcclxuICAgIEBJbnB1dCgpIHNldCBwYWdlKHZhbHVlOiBJUGFnZTxhbnk+KSB7XHJcbiAgICAgICAgdGhpcy5fcGFnZSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMuaGFuZGxlUGFnZUNoYW5nZSh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBnZXQgcGFnZSgpOiBJUGFnZTxhbnk+IHwgdW5kZWZpbmVkIHsgcmV0dXJuIHRoaXMuX3BhZ2U7IH1cclxuXHJcbiAgICBjYXJkczogVHNpQ2FyZFtdID0gW107XHJcbiAgICBjYXJkTWFwQnlXb3JrZmxvd0V0YXQ6IE1hcDxzdHJpbmcgfCBudWxsLCBUc2lDYXJkW10+ID0gbmV3IE1hcCgpO1xyXG5cclxuICAgIC8vIFBvcHVsYXRlZCBvbmx5IHdoZW4gdGhlIHBhZ2UgaXMgZ3JvdXBlZCBzZXJ2ZXItc2lkZSAob25lIGdyb3VwIHBlciB3b3JrZmxvdyBldGF0KTpcclxuICAgIC8vIHRydWUgcGVyLWNvbHVtbiB0b3RhbHMgYW5kIHBlci1jb2x1bW4gc3VtbWFyaWVzLCBpbmRlcGVuZGVudCBvZiB0aGUgY3VycmVudCBwYWdlLlxyXG4gICAgY291bnRCeVdvcmtmbG93RXRhdDogTWFwPHN0cmluZyB8IG51bGwsIG51bWJlcj4gPSBuZXcgTWFwKCk7XHJcbiAgICBzdW1tYXJ5QnlXb3JrZmxvd0V0YXQ6IE1hcDxzdHJpbmcgfCBudWxsLCBJU3VtbWFyeUZvclByb3ByZXR5W10+ID0gbmV3IE1hcCgpO1xyXG4gICAgcHJpdmF0ZSBfaXNHcm91cGVkID0gZmFsc2U7XHJcblxyXG4gICAgZHJhZ2dlZENhcmQ6IFRzaUNhcmQgfCBudWxsID0gbnVsbDtcclxuICAgIGZpcnN0ID0gMDtcclxuICAgIHJvd3MgPSAxMDtcclxuICAgIHRvdGFsQ291bnQgPSAwO1xyXG4gICAgaXNMb2FkaW5nID0gZmFsc2U7XHJcblxyXG4gICAgLy8gQnVsayBzZWxlY3Rpb246IHJlc3RyaWN0ZWQgdG8gYSBzaW5nbGUgd29ya2Zsb3ctZXRhdCBjb2x1bW4gKGN1cnJlbnQgcGFnZSBvbmx5KS5cclxuICAgIC8vIERyYWdnaW5nIGFueSBzZWxlY3RlZCBjYXJkIG9udG8gYW5vdGhlciBjb2x1bW4gbW92ZXMgdGhlIHdob2xlIHNlbGVjdGlvbi5cclxuICAgIHNlbGVjdGVkQ2FyZFVpZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICAgIHNlbGVjdGlvbkNvbHVtbktleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XHJcbiAgICAvLyBBbGxvd2VkIG5leHQgd29ya2Zsb3cgZXRhdHMgcGVyIHdvcmtmbG93IGV0YXQsIGxvYWRlZCBvbmNlIGF0IGluaXQ7IG51bGwgaWYgdW5hdmFpbGFibGUgKHRoZSBiYWNrZW5kIHN0aWxsIGNoZWNrcyBldmVyeSBtb3ZlKS5cclxuICAgIGFsbG93ZWRUYXJnZXRzQnlXb3JrZmxvd0V0YXQ6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PiB8IG51bGwgPSBudWxsO1xyXG4gICAgaXNCdWxrRHJhZ2dpbmcgPSBmYWxzZTtcclxuICAgIC8vIE9mZi1zY3JlZW4gZWxlbWVudCB1c2VkIGFzIHRoZSBicm93c2VyIGRyYWcgaW1hZ2Ugd2hlbiBhIHNlbGVjdGlvbiBpcyBkcmFnZ2VkLlxyXG4gICAgQFZpZXdDaGlsZCgnYnVsa0RyYWdQcmV2aWV3JykgYnVsa0RyYWdQcmV2aWV3PzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XHJcblxyXG4gICAgd29ya0Zsb3dFdGF0Tm9tTGFiZWxzOiB7IGtleTogc3RyaW5nIHwgbnVsbDsgbG9jYWxpemVkOiBzdHJpbmcgfVtdID1cclxuICAgICAgICBbXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBfd29ya2Zsb3dDb25maWd1cmF0aW9uU2VydmljZTogV29ya2Zsb3dDb25maWd1cmF0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9lbnRpdHlDb25maWc6IEVudGl0eUNvbmZpZ3VyYXRpb25TZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgX2xvY2FsaXplOiBMb2NhbGl6ZVBpcGUsXHJcbiAgICAgICAgcHJpdmF0ZSBfbm90aWZpY2F0aW9uU2VydmljZTogVHNpTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9jb25maXJtYXRpb25TZXJ2aWNlOiBUc2lDb25maXJtYXRpb25TZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgX21lc3NhZ2VTZXJ2aWNlOiBUc2lNZXNzYWdlU2VydmljZSxcclxuICAgICkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMgPSBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGtleTogbnVsbCxcclxuICAgICAgICAgICAgICAgIGxvY2FsaXplZDogdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKCdzaGFyZWRfdHNpX2NvbXBvbmVudF9ncmlkX2thbmJhbl93b3JrZmxvd0V0YXRfdmlld19zYW5zX3dvcmtmbG93JykudHJpbSgpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBdXHJcbiAgICB9XHJcblxyXG4gICAgb3ZlcnJpZGUgYXN5bmMgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgdGhpcy5wYWdlJC5zdWJzY3JpYmUoYXN5bmMgcGFnZSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChwYWdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9ICEhcGFnZS5sb2FkaW5nO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVQYWdlQ2hhbmdlKHBhZ2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQsIGNhcmQ6IFRzaUNhcmQpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmRyYWdnZWRDYXJkID0gY2FyZDtcclxuICAgICAgICAvLyBEcmFnZ2luZyBhIHNlbGVjdGVkIGNhcmQgd2hpbGUgc2V2ZXJhbCBhcmUgc2VsZWN0ZWQgZHJhZ3MgdGhlIHdob2xlIHNlbGVjdGlvbjtcclxuICAgICAgICAvLyBkcmFnZ2luZyBhbiB1bnNlbGVjdGVkIGNhcmQgKG9yIGEgc2luZ2xlIHNlbGVjdGlvbikga2VlcHMgdGhlIGV4aXN0aW5nIHNpbmdsZSBtb3ZlLlxyXG4gICAgICAgIHRoaXMuaXNCdWxrRHJhZ2dpbmcgPSB0aGlzLnNlbGVjdGVkQ291bnQgPiAxICYmIHRoaXMuaXNDYXJkU2VsZWN0ZWQoY2FyZCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzQnVsa0RyYWdnaW5nICYmIHRoaXMuYnVsa0RyYWdQcmV2aWV3ICYmIGV2ZW50LmRhdGFUcmFuc2Zlcikge1xyXG4gICAgICAgICAgICBldmVudC5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlKHRoaXMuYnVsa0RyYWdQcmV2aWV3Lm5hdGl2ZUVsZW1lbnQsIDI0LCAyNCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGRyYWdFbmQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5pc0J1bGtEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGFsbG93RHJvcChldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7IGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IH1cclxuXHJcbiAgICB0cmFja0J5V29ya2Zsb3dFdGF0KGluZGV4OiBudW1iZXIsIHN0YXR1czogeyBrZXk6IHN0cmluZyB8IG51bGw7IGxvY2FsaXplZDogc3RyaW5nIH0pIHsgcmV0dXJuIHN0YXR1cy5rZXk7IH1cclxuXHJcbiAgICB0cmFja0J5Q2FyZChpbmRleDogbnVtYmVyLCBjYXJkOiBUc2lDYXJkKSB7IHJldHVybiBjYXJkLnVpZDsgfVxyXG5cclxuICAgIGRyb3AoZXZlbnQ6IERyYWdFdmVudCwgbmV3S2V5OiBzdHJpbmcgfCBudWxsKSB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBpZiAoIXRoaXMuZHJhZ2dlZENhcmQpIHJldHVybjtcclxuICAgICAgICBpZihuZXdLZXkgPT0gbnVsbCB8fCBuZXdLZXkgPT0gdW5kZWZpbmVkKVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcihcInNoYXJlZF90c2lfY29tcG9uZW50X2dyaWRfa2FuYmFuX3dvcmtmbG93RXRhdF92aWV3X3NhbnNfd29ya2Zsb3dfZm9yYmlkZGVuXCIpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuaXNCdWxrRHJhZ2dpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5kcm9wU2VsZWN0aW9uKG5ld0tleSk7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhZ2dlZENhcmQgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLmlzQnVsa0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgY2FyZCA9IHRoaXMuZHJhZ2dlZENhcmQ7XHJcbiAgICAgICAgY29uc3QgcHJldmlvdXNXb3JrZmxvd0V0YXQgPSB0aGlzLmRyYWdnZWRDYXJkLnN0YXR1cztcclxuXHJcbiAgICAgICAgaWYocHJldmlvdXNXb3JrZmxvd0V0YXQgPT0gbnVsbClcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIHRoaXMuX25vdGlmaWNhdGlvblNlcnZpY2UuZXJyb3IoXCJzaGFyZWRfdHNpX2NvbXBvbmVudF9ncmlkX2thbmJhbl93b3JrZmxvd0V0YXRfdmlld19ub193b3JrZmxvd1wiKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJldmlvdXNXb3JrZmxvd0V0YXQgIT09IG5ld0tleSAmJiAhdGhpcy5pc0FsbG93ZWREcm9wVGFyZ2V0KG5ld0tleSkpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcignc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfd29ya2Zsb3dfZXRhdF9zdWl2YW50X2Vycm9yJyk7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhZ2dlZENhcmQgPSBudWxsO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5kcmFnZ2VkQ2FyZC5zdGF0dXMgIT09IG5ld0tleSAmJiB0aGlzLmNhcmRCdXNpbmVzc0NsYXNzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZVxyXG4gICAgICAgICAgICBsZXQgcmVxdWVzdDogV29ya2Zsb3dFdGF0S2FuYmFuUmVxdWVzdCA9IG5ldyBXb3JrZmxvd0V0YXRLYW5iYW5SZXF1ZXN0KCk7XHJcbiAgICAgICAgICAgIHJlcXVlc3Qud29ya0Zsb3dFdGF0ID0gdGhpcy5kcmFnZ2VkQ2FyZC5zdGF0dXNcclxuICAgICAgICAgICAgcmVxdWVzdC5idXNpbmVzc0NsYXNzID0gdGhpcy5jYXJkQnVzaW5lc3NDbGFzcyxcclxuICAgICAgICAgICAgcmVxdWVzdC51aWRPYmpldCA9IHRoaXMuZHJhZ2dlZENhcmQudWlkO1xyXG4gICAgICAgICAgICByZXF1ZXN0LmRpc2NyaW1pbmF0b3JDbGFzc05hbWUgPSB0aGlzLmVudGl0eUluZm8/LmRpc2NyaW1pbmF0b3JDbGFzc05hbWVcclxuICAgICAgICAgICAgcmVxdWVzdC5kaXNjcmltaW5hdG9yUHJvcGVydHlOYW1lID0gdGhpcy5lbnRpdHlJbmZvPy5kaXNjcmltaW5hdG9yUHJvcGVydHlOYW1lXHJcbiAgICAgICAgICAgIHJlcXVlc3QuZGlzY3JpbWluYXRvclZhbHVlID0gdGhpcy5kZXNjcmltaW5hdG9yVmFsdWVcclxuICAgICAgICAgICAgcmVxdWVzdC53b3JrRmxvd0V0YXRTdWl2YW50ID0gbmV3S2V5O1xyXG4gICAgICAgICAgICB0aGlzLl93b3JrZmxvd0NvbmZpZ3VyYXRpb25TZXJ2aWNlLnVwZGF0ZVdvcmtmbG93RXRhdEZyb21LYW5iYW5WaWV3KHJlcXVlc3QpLnN1YnNjcmliZSh7XHJcbiAgICAgICAgICAgICAgICBuZXh0OiAoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhcmQuc3RhdHVzID0gbmV3S2V5O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlRnJvbVNlbGVjdGlvbihjYXJkLnVpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlcnJvcjogKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkgPT5cclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub3RpZmljYXRpb25TZXJ2aWNlLmVycm9yKGVycm9yPy5lcnJvcilcclxuICAgICAgICAgICAgICAgICAgICBjYXJkLnN0YXR1cyA9IHByZXZpb3VzV29ya2Zsb3dFdGF0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2VcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDYXJkTWFwKCk7XHJcbiAgICAgICAgdGhpcy5kcmFnZ2VkQ2FyZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgb25QYWdlQ2hhbmdlKGV2ZW50OiBQYWdpbmF0b3JTdGF0ZSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcclxuICAgICAgICB0aGlzLmZpcnN0ID0gZXZlbnQuZmlyc3QgPz8gMDtcclxuICAgICAgICB0aGlzLnJvd3MgPSBldmVudC5yb3dzID8/IDEwO1xyXG4gICAgICAgIHRoaXMuY2FsbFNlYXJjaC5lbWl0KHsgc2tpcENvdW50OiB0aGlzLmZpcnN0LCBtYXhSZXN1bHRDb3VudDogdGhpcy5yb3dzIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzZWxlY3RlZENvdW50KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRDYXJkVWlkcy5zaXplO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpcnN0IHNlbGVjdGVkIGNhcmRzLCBzaG93biBhcyBhIHN0YWNrIGluIHRoZSBidWxrIGRyYWcgaW1hZ2UuXHJcbiAgICBnZXQgc2VsZWN0ZWRDYXJkc1ByZXZpZXcoKTogVHNpQ2FyZFtdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jYXJkcy5maWx0ZXIoYyA9PiB0aGlzLmlzQ2FyZFNlbGVjdGVkKGMpKS5zbGljZSgwLCAzKTtcclxuICAgIH1cclxuXHJcbiAgICBpc0NhcmRTZWxlY3RlZChjYXJkOiBUc2lDYXJkKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuICEhY2FyZC51aWQgJiYgdGhpcy5zZWxlY3RlZENhcmRVaWRzLmhhcyhjYXJkLnVpZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2VsZWN0aW5nIGEgY2FyZCBpbiBhbm90aGVyIGNvbHVtbiByZXN0YXJ0cyB0aGUgc2VsZWN0aW9uIGluIHRoYXQgY29sdW1uLlxyXG4gICAgdG9nZ2xlQ2FyZFNlbGVjdGlvbihjb2x1bW5LZXk6IHN0cmluZywgY2FyZDogVHNpQ2FyZCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghY2FyZC51aWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uQ29sdW1uS2V5ICE9PSBjb2x1bW5LZXkpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNlbGVjdGlvbihjb2x1bW5LZXkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRDYXJkVWlkcy5oYXMoY2FyZC51aWQpKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRnJvbVNlbGVjdGlvbihjYXJkLnVpZCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDYXJkVWlkcy5hZGQoY2FyZC51aWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzQ29sdW1uUGFnZUZ1bGx5U2VsZWN0ZWQoY29sdW1uS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBjb2x1bW5DYXJkcyA9IHRoaXMuY2FyZE1hcEJ5V29ya2Zsb3dFdGF0LmdldChjb2x1bW5LZXkpID8/IFtdO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbkNvbHVtbktleSA9PT0gY29sdW1uS2V5XHJcbiAgICAgICAgICAgICYmIGNvbHVtbkNhcmRzLmxlbmd0aCA+IDBcclxuICAgICAgICAgICAgJiYgY29sdW1uQ2FyZHMuZXZlcnkoYyA9PiB0aGlzLmlzQ2FyZFNlbGVjdGVkKGMpKTtcclxuICAgIH1cclxuXHJcbiAgICB0b2dnbGVTZWxlY3RBbGxDb2x1bW5QYWdlKGNvbHVtbktleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNDb2x1bW5QYWdlRnVsbHlTZWxlY3RlZChjb2x1bW5LZXkpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uQ29sdW1uS2V5ICE9PSBjb2x1bW5LZXkpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNlbGVjdGlvbihjb2x1bW5LZXkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgKHRoaXMuY2FyZE1hcEJ5V29ya2Zsb3dFdGF0LmdldChjb2x1bW5LZXkpID8/IFtdKS5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYy51aWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDYXJkVWlkcy5hZGQoYy51aWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZENhcmRVaWRzLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25Db2x1bW5LZXkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFVzZWQgd2hpbGUgZHJhZ2dpbmcgKG9uZSBjYXJkIG9yIGEgc2VsZWN0aW9uKSwgdG8gaGlnaGxpZ2h0IGFsbG93ZWQgLyBmb3JiaWRkZW4gZHJvcCBjb2x1bW5zLlxyXG4gICAgaXNBbGxvd2VkRHJvcFRhcmdldChjb2x1bW5LZXk6IHN0cmluZyB8IG51bGwpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBzb3VyY2VLZXkgPSB0aGlzLmRyYWdnZWRDYXJkPy5zdGF0dXMgPz8gbnVsbDtcclxuICAgICAgICBpZiAoY29sdW1uS2V5ID09PSBudWxsIHx8IHNvdXJjZUtleSA9PT0gbnVsbCB8fCBjb2x1bW5LZXkgPT09IHNvdXJjZUtleSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmFsbG93ZWRUYXJnZXRzQnlXb3JrZmxvd0V0YXQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLmFsbG93ZWRUYXJnZXRzQnlXb3JrZmxvd0V0YXQuZ2V0KHNvdXJjZUtleSk/Lmhhcyhjb2x1bW5LZXkpID8/IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFdvcmtmbG93RXRhdENsYXNzKGNhcmQ6IFRzaUNhcmQpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMuZmluZEluZGV4KGwgPT4gbC5rZXkgPT09IGNhcmQuc3RhdHVzKTtcclxuICAgICAgICByZXR1cm4gYHdvcmtmbG93RXRhdENvbG9yLSR7aW5kZXggPj0gMCA/IGluZGV4IDogJ2RlZmF1bHQnfWA7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TG9jYWxpemVkV29ya2Zsb3dFdGF0KGtleTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XHJcbiAgICAgICAgaWYgKCFrZXkpIHJldHVybiAnJztcclxuICAgICAgICBjb25zdCBtYXRjaCA9IHRoaXMud29ya0Zsb3dFdGF0Tm9tTGFiZWxzLmZpbmQocyA9PiBzLmtleSA9PT0ga2V5KTtcclxuICAgICAgICByZXR1cm4gbWF0Y2g/LmxvY2FsaXplZCA/PyBrZXk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVHJ1ZSBwZXItY29sdW1uIHRvdGFsOiB0aGUgZ3JvdXAncyB1bnBhZ2VkIGNvdW50IHdoZW4gZ3JvdXBlZCBzZXJ2ZXItc2lkZSxcclxuICAgIC8vIG90aGVyd2lzZSB0aGUgbnVtYmVyIG9mIGNhcmRzIG9uIHRoZSBjdXJyZW50IHBhZ2UgKGxlZ2FjeSBjbGllbnQtc2lkZSBncm91cGluZykuXHJcbiAgICBnZXRDb2x1bW5Db3VudChrZXk6IHN0cmluZyB8IG51bGwpOiBudW1iZXIge1xyXG4gICAgICAgIGlmICh0aGlzLl9pc0dyb3VwZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY291bnRCeVdvcmtmbG93RXRhdC5nZXQoa2V5KSA/PyAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5jYXJkTWFwQnlXb3JrZmxvd0V0YXQuZ2V0KGtleSk/Lmxlbmd0aCA/PyAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFdoZXRoZXIgcGVyLWNvbHVtbiBzdW1tYXJpZXMgc2hvdWxkIHJlbmRlciAoZ3JvdXBlZCBkYXRhICsgYXQgbGVhc3Qgb25lIG9wdGVkLWluIGNvbHVtbikuXHJcbiAgICBnZXQgaGFzQ29sdW1uU3VtbWFyaWVzKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pc0dyb3VwZWQgJiYgKHRoaXMuc3VtbWFyeUNvbHVtbnM/Lmxlbmd0aCA/PyAwKSA+IDA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29sdW1ucyB0byByZW5kZXI6IHRoZSBcInNhbnMgd29ya2Zsb3dcIiAobnVsbC1rZXkpIGNvbHVtbiBpcyBoaWRkZW4gd2hlbiBpdCBoYXMgbm8gY2FyZHM7XHJcbiAgICAvLyByZWFsIHdvcmtmbG93LWV0YXQgY29sdW1ucyBhbHdheXMgc2hvdyByZWdhcmRsZXNzIG9mIGNvdW50LlxyXG4gICAgZ2V0IGRpc3BsYXllZFdvcmtGbG93RXRhdExhYmVscygpOiB7IGtleTogc3RyaW5nIHwgbnVsbDsgbG9jYWxpemVkOiBzdHJpbmcgfVtdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMuZmlsdGVyKGwgPT4gbC5rZXkgIT09IG51bGwgfHwgdGhpcy5nZXRDb2x1bW5Db3VudChsLmtleSkgPiAwKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGUgU1VNIGZvciBhIHN1bW1hcml6ZWQgY29sdW1uIHdpdGhpbiBhIHdvcmtmbG93LWV0YXQgZ3JvdXAgKHVuZGVmaW5lZCB3aGVuIG5vdCBncm91cGVkIG9yIGFic2VudCkuXHJcbiAgICBnZXRDb2x1bW5TdW1tYXJ5VmFsdWUoa2V5OiBzdHJpbmcgfCBudWxsLCBmaWVsZDogc3RyaW5nKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2lzR3JvdXBlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtYXRjaCA9IHRoaXMuc3VtbWFyeUJ5V29ya2Zsb3dFdGF0LmdldChrZXkpXHJcbiAgICAgICAgICAgID8uZmluZChzID0+IHMucHJvcHJldHk/LnRvTG93ZXJDYXNlKCkgPT09IGZpZWxkPy50b0xvd2VyQ2FzZSgpKTtcclxuICAgICAgICByZXR1cm4gbWF0Y2g/LnN1bW1hcnk7XHJcbiAgICB9XHJcblxyXG4gICAgb3ZlcmZsb3dDb2x1bW5DbGlja2VkKG1lbnU6IE1lbnUsIGV2ZW50OiBFdmVudCwgcm93OiBhbnkpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRBY3Rpb25Sb3cgPSByb3c7XHJcbiAgICAgICAgbWVudS50b2dnbGUoZXZlbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uT3ZlcmZsb3dBY3Rpb25DbGlja2VkKGNhcmQ6IFRzaUNhcmQsIG1lbnVJdGVtOiBNZW51SXRlbSkge1xyXG4gICAgICAgIGlmICghY2FyZCB8fCAhbWVudUl0ZW0gfHwgIW1lbnVJdGVtLmlkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuaGFuZGxlQnV0dG9uQ2xpY2tlZChjYXJkPy5mdWxsUmVjb3JkID8/IGNhcmQsIG1lbnVJdGVtLmlkKTtcclxuICAgIH1cclxuXHJcbiAgICBoYW5kbGVCdXR0b25DbGlja2VkKGl0ZW06IGFueSwgZmllbGQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdEtleU9ubHkpIHtcclxuICAgICAgICAgICAgdGhpcy5idXR0b25DbGlja2VkLmVtaXQoeyBmaWVsZDogZmllbGQsIGtleTogaXRlbVt0aGlzLmtleV0sIHNlbGVjdEtleU9ubHk6IHRoaXMuc2VsZWN0S2V5T25seSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnV0dG9uQ2xpY2tlZC5lbWl0KHsgZmllbGQ6IGZpZWxkLCBrZXk6IGl0ZW0sIHNlbGVjdEtleU9ubHk6IHRoaXMuc2VsZWN0S2V5T25seSB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZWRpdCh1aWQ/OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodWlkKSB7XHJcbiAgICAgICAgICAgIHRoaXMub3Blbk1vZGFsQ29tcG9uZW50KHVpZCwgJ2VkaXQnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBvcGVuTW9kYWxDb21wb25lbnQodWlkOiBzdHJpbmcsIG1vZGU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuYnV0dG9uQ2xpY2tlZC5lbWl0KHsgZmllbGQ6IG1vZGUsIGtleTogdWlkLCBzZWxlY3RLZXlPbmx5OiB0cnVlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlUGFnZUNoYW5nZShwYWdlOiBJUGFnZTxhbnk+KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgLy8gQSByZWxvYWQgcmVwbGFjZXMgdGhlIGNhcmRzOiBwcmV2aW91c2x5IHNlbGVjdGVkIHVpZHMgYXJlIG5vIGxvbmdlciByZWxpYWJsZS5cclxuICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XHJcblxyXG4gICAgICAgIGlmIChwYWdlPy5ncm91cHMpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVHcm91cGVkUGFnZShwYWdlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFwYWdlPy5pdGVtcykgcmV0dXJuO1xyXG5cclxuICAgICAgICB0aGlzLl9pc0dyb3VwZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmNhcmRzID0gYXdhaXQgdGhpcy5tYXBJdGVtc1RvQ2FyZHMocGFnZS5pdGVtcyk7XHJcbiAgICAgICAgdGhpcy50b3RhbENvdW50ID0gcGFnZS50b3RhbENvdW50O1xyXG4gICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNlcnZlci1zaWRlIGdyb3VwZWQgcGFnZTogb25lIGdyb3VwIHBlciB3b3JrZmxvdyBldGF0LCBlYWNoIGNhcnJ5aW5nIGl0cyBvd24gYWNjdXJhdGVcclxuICAgIC8vICh1bnBhZ2VkKSB0b3RhbCBjb3VudCBhbmQgc3VtbWFyaWVzLiBDYXJkcyBvbiB0aGUgY3VycmVudCBwYWdlIGFyZSBtYXBwZWQgYW5kIGJ1Y2tldGVkXHJcbiAgICAvLyBleGFjdGx5IGFzIGluIHRoZSBmbGF0IHBhdGggKHZpYSB1cGRhdGVDYXJkTWFwKTsgdGhlIHRydWUgcGVyLWNvbHVtbiBjb3VudHMvc3VtbWFyaWVzXHJcbiAgICAvLyBjb21lIGZyb20gdGhlIGdyb3VwcywgYW5kIHRoZSBzaW5nbGUgYm9hcmQgcGFnaW5hdG9yIHNwYW5zIHRoZSBsYXJnZXN0IGNvbHVtbiAoc2FtZVxyXG4gICAgLy8gc2tpcC90YWtlIHdpbmRvdyBhcHBsaWVkIHRvIGV2ZXJ5IGdyb3VwIGJ5IHRoZSBiYWNrZW5kKS5cclxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlR3JvdXBlZFBhZ2UocGFnZTogSVBhZ2U8YW55Pik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwczogSUdyb3VwZWRSZXN1bHQ8YW55PltdID0gcGFnZS5ncm91cHMgPz8gW107XHJcbiAgICAgICAgY29uc3QgdmFsaWRLZXlzID0gdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHNcclxuICAgICAgICAgICAgLm1hcChsID0+IGwua2V5KVxyXG4gICAgICAgICAgICAuZmlsdGVyKChrKTogayBpcyBzdHJpbmcgPT4gayAhPT0gbnVsbCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvdW50cyA9IG5ldyBNYXA8c3RyaW5nIHwgbnVsbCwgbnVtYmVyPigpO1xyXG4gICAgICAgIGNvbnN0IHN1bW1hcmllcyA9IG5ldyBNYXA8c3RyaW5nIHwgbnVsbCwgSVN1bW1hcnlGb3JQcm9wcmV0eVtdPigpO1xyXG4gICAgICAgIGxldCBtYXhHcm91cFRvdGFsID0gMDtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBncm91cCBvZiBncm91cHMpIHtcclxuICAgICAgICAgICAgY29uc3QgcmF3S2V5ID0gZ3JvdXAua2V5Py50cmltKCkgfHwgbnVsbDtcclxuICAgICAgICAgICAgaWYgKHJhd0tleSAmJiAhdmFsaWRLZXlzLmluY2x1ZGVzKHJhd0tleSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1Y2tldEtleSA9IHJhd0tleTtcclxuXHJcbiAgICAgICAgICAgIGNvdW50cy5zZXQoYnVja2V0S2V5LCAoY291bnRzLmdldChidWNrZXRLZXkpID8/IDApICsgZ3JvdXAudG90YWxDb3VudCk7XHJcbiAgICAgICAgICAgIGlmICghc3VtbWFyaWVzLmhhcyhidWNrZXRLZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBzdW1tYXJpZXMuc2V0KGJ1Y2tldEtleSwgZ3JvdXAuc3VtbWFyaWVzID8/IFtdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBtYXhHcm91cFRvdGFsID0gTWF0aC5tYXgobWF4R3JvdXBUb3RhbCwgZ3JvdXAudG90YWxDb3VudCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEYXRhIHNocmFuayB1bmRlciBhIGxhdGVyIHBhZ2UgKGRyYWctZHJvcCwgYSBmaWx0ZXIsIG9yIGFub3RoZXIgdXNlcidzIGNoYW5nZSk6XHJcbiAgICAgICAgLy8gdGhlIGN1cnJlbnQgb2Zmc2V0IGlzIG5vdyBwYXN0IHRoZSBlbmQgb2YgZXZlcnkgY29sdW1uLCBzbyB0aGUgYmFja2VuZCByZXR1cm5lZCBhblxyXG4gICAgICAgIC8vIGVtcHR5IHdpbmRvdyBhbmQgdGhlIGJvYXJkIHdvdWxkIGxvb2sgZW1wdHkgdW50aWwgdGhlIHVzZXIgbWFudWFsbHkgcGFnZXMgYmFjay5cclxuICAgICAgICAvLyBDbGFtcCB0byB0aGUgbGFzdCB2YWxpZCBwYWdlIGFuZCByZS1mZXRjaCBvbmNlLlxyXG4gICAgICAgIGlmICh0aGlzLmZpcnN0ID4gMCAmJiB0aGlzLmZpcnN0ID49IG1heEdyb3VwVG90YWwpIHtcclxuICAgICAgICAgICAgdGhpcy5maXJzdCA9IG1heEdyb3VwVG90YWwgPiAwXHJcbiAgICAgICAgICAgICAgICA/IE1hdGguZmxvb3IoKG1heEdyb3VwVG90YWwgLSAxKSAvIHRoaXMucm93cykgKiB0aGlzLnJvd3NcclxuICAgICAgICAgICAgICAgIDogMDtcclxuICAgICAgICAgICAgdGhpcy5jYWxsU2VhcmNoLmVtaXQoeyBza2lwQ291bnQ6IHRoaXMuZmlyc3QsIG1heFJlc3VsdENvdW50OiB0aGlzLnJvd3MgfSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2lzR3JvdXBlZCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5jb3VudEJ5V29ya2Zsb3dFdGF0ID0gY291bnRzO1xyXG4gICAgICAgIHRoaXMuc3VtbWFyeUJ5V29ya2Zsb3dFdGF0ID0gc3VtbWFyaWVzO1xyXG4gICAgICAgIHRoaXMudG90YWxDb3VudCA9IG1heEdyb3VwVG90YWw7XHJcbiAgICAgICAgdGhpcy5jYXJkcyA9IGF3YWl0IHRoaXMubWFwSXRlbXNUb0NhcmRzKGdyb3Vwcy5mbGF0TWFwKGcgPT4gZy5pdGVtcyA/PyBbXSkpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQ2FyZE1hcCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRTZWxlY3Rpb24oY29sdW1uS2V5OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25Db2x1bW5LZXkgPSBjb2x1bW5LZXk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW1vdmVGcm9tU2VsZWN0aW9uKHVpZDogc3RyaW5nIHwgdW5kZWZpbmVkKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHVpZCkge1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ2FyZFVpZHMuZGVsZXRlKHVpZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkQ2FyZFVpZHMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIERyb3Agb2YgYSBkcmFnZ2VkIHNlbGVjdGlvbjogc2FtZSBndWFyZHMgYXMgdGhlIHNpbmdsZSBtb3ZlLCB0aGVuIG9uZSBjb25maXJtYXRpb24gZm9yIHRoZSBiYXRjaC5cclxuICAgIHByaXZhdGUgZHJvcFNlbGVjdGlvbih0YXJnZXRLZXk6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0YXJnZXRLZXkgPT09IHRoaXMuc2VsZWN0aW9uQ29sdW1uS2V5IHx8ICF0aGlzLmNhcmRCdXNpbmVzc0NsYXNzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5pc0FsbG93ZWREcm9wVGFyZ2V0KHRhcmdldEtleSkpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcignc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfd29ya2Zsb3dfZXRhdF9zdWl2YW50X2Vycm9yJyk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbmZpcm1NZXNzYWdlID0gdGhpcy5fbG9jYWxpemUudHJhbnNmb3JtKCdzaGFyZWRfdHNpX2NvbXBvbmVudF9ncmlkX2thbmJhbl93b3JrZmxvd0V0YXRfdmlld19idWxrX2NvbmZpcm0nKVxyXG4gICAgICAgICAgICAucmVwbGFjZSgnezB9JywgYCR7dGhpcy5zZWxlY3RlZENvdW50fWApXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKCd7MX0nLCB0aGlzLmdldExvY2FsaXplZFdvcmtmbG93RXRhdCh0aGlzLnNlbGVjdGlvbkNvbHVtbktleSkpXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKCd7Mn0nLCB0aGlzLmdldExvY2FsaXplZFdvcmtmbG93RXRhdCh0YXJnZXRLZXkpKTtcclxuXHJcbiAgICAgICAgdGhpcy5fY29uZmlybWF0aW9uU2VydmljZS5jb25maXJtKGNvbmZpcm1NZXNzYWdlLCB1bmRlZmluZWQsIChjb25maXJtZWQ6IGJvb2xlYW4pID0+IHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpcm1lZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5leGVjdXRlQnVsa01vdmUodGFyZ2V0S2V5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZXhlY3V0ZUJ1bGtNb3ZlKHRhcmdldEtleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IG5ldyBXb3JrZmxvd0V0YXRLYW5iYW5NdWx0aXBsZVJlcXVlc3QoKTtcclxuICAgICAgICByZXF1ZXN0LmJ1c2luZXNzQ2xhc3MgPSB0aGlzLmNhcmRCdXNpbmVzc0NsYXNzO1xyXG4gICAgICAgIHJlcXVlc3Qud29ya0Zsb3dFdGF0ID0gdGhpcy5zZWxlY3Rpb25Db2x1bW5LZXkgPz8gdW5kZWZpbmVkO1xyXG4gICAgICAgIHJlcXVlc3Qud29ya0Zsb3dFdGF0U3VpdmFudCA9IHRhcmdldEtleTtcclxuICAgICAgICByZXF1ZXN0LnVpZE9iamV0cyA9IFsuLi50aGlzLnNlbGVjdGVkQ2FyZFVpZHNdO1xyXG4gICAgICAgIHJlcXVlc3QuZGlzY3JpbWluYXRvckNsYXNzTmFtZSA9IHRoaXMuZW50aXR5SW5mbz8uZGlzY3JpbWluYXRvckNsYXNzTmFtZTtcclxuICAgICAgICByZXF1ZXN0LmRpc2NyaW1pbmF0b3JQcm9wZXJ0eU5hbWUgPSB0aGlzLmVudGl0eUluZm8/LmRpc2NyaW1pbmF0b3JQcm9wZXJ0eU5hbWU7XHJcbiAgICAgICAgcmVxdWVzdC5kaXNjcmltaW5hdG9yVmFsdWUgPSB0aGlzLmRlc2NyaW1pbmF0b3JWYWx1ZTtcclxuXHJcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX3dvcmtmbG93Q29uZmlndXJhdGlvblNlcnZpY2UudXBkYXRlTXVsdGlwbGVXb3JrZmxvd0V0YXRGcm9tS2FuYmFuVmlldyhyZXF1ZXN0KS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICBuZXh0OiAocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1bGtNb3ZlRmFpbHVyZXMocmVzcG9uc2UpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2FsbFNlYXJjaC5lbWl0KHsgc2tpcENvdW50OiB0aGlzLmZpcnN0LCBtYXhSZXN1bHRDb3VudDogdGhpcy5yb3dzIH0pO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlcnJvcjogKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5lcnJvcihlcnJvcj8uZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE9ubHkgZmFpbHVyZXMgYXJlIHJlcG9ydGVkOyBzdWNjZXNzZnVsbHkgbW92ZWQgY2FyZHMgbmVlZCBubyBmZWVkYmFjay5cclxuICAgIHByaXZhdGUgc2hvd0J1bGtNb3ZlRmFpbHVyZXMocmVzcG9uc2U6IFdvcmtmbG93RXRhdEthbmJhbk11bHRpcGxlUmVzcG9uc2UpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlPy5mYWlsZWQ/Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0aXRsZUJ5VWlkID0gbmV3IE1hcCh0aGlzLmNhcmRzLm1hcChjID0+IFtjLnVpZCwgYy5oZWFkZXJUaXRsZV0pKTtcclxuICAgICAgICBjb25zdCBmYWlsdXJlTGluZXMgPSByZXNwb25zZS5mYWlsZWQubWFwKGYgPT5cclxuICAgICAgICAgICAgYCR7dGl0bGVCeVVpZC5nZXQoZi51aWRPYmpldCkgfHwgZi51aWRPYmpldH0gOiAke3RoaXMuX2xvY2FsaXplLnRyYW5zZm9ybShmLmVycm9yTWVzc2FnZSl9YCk7XHJcblxyXG4gICAgICAgIHRoaXMuX21lc3NhZ2VTZXJ2aWNlLmVycm9yKFxyXG4gICAgICAgICAgICBgJHtyZXNwb25zZS5mYWlsZWRDb3VudH0gLyAke3Jlc3BvbnNlLnRvdGFsfSAke3RoaXMuX2xvY2FsaXplLnRyYW5zZm9ybSgnc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfYnVsa19mYWlsZWQnKX1gLFxyXG4gICAgICAgICAgICBmYWlsdXJlTGluZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgZ2V0RW50aXR5SW5mbygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICB0aGlzLmVudGl0eUluZm8gPSBhd2FpdCB0aGlzLl9lbnRpdHlDb25maWcuZ2V0RW50aXR5SW5mb0Zyb21DYWNoZSh0aGlzLmNhcmRCdXNpbmVzc0NsYXNzKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldCBoYXNEaXNjcmltaW5hdG9yKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAhISh0aGlzLmVudGl0eUluZm8/LmRpc2NyaW1pbmF0b3JDbGFzc05hbWUgfHwgdGhpcy5lbnRpdHlJbmZvPy5kaXNjcmltaW5hdG9yUHJvcGVydHlOYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBFbnRpdHkgaW5mbyBmaXJzdDogaXQgdGVsbHMgd2hldGhlciB0aGUgd29ya2Zsb3cgZXRhdHMgZGVwZW5kIG9uIGEgZGlzY3JpbWluYXRvciB2YWx1ZS5cclxuICAgIHByaXZhdGUgYXN5bmMgbG9hZEVudGl0eUluZm9BbmRXb3JrZmxvd0V0YXRzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghdGhpcy5fY2FyZEJ1c2luZXNzQ2xhc3MpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRFbnRpdHlJbmZvKCk7XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5oYXNEaXNjcmltaW5hdG9yKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubG9hZFdvcmtmbG93RXRhdHNBbmRTdWl2YW50cygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLl9kZXNjcmltaW5hdG9yVmFsdWUpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkV29ya2Zsb3dFdGF0c0FuZFN1aXZhbnRzKHRoaXMuX2Rlc2NyaW1pbmF0b3JWYWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgbG9hZFdvcmtmbG93RXRhdHNBbmRTdWl2YW50cyhkZXNjcmltaW5hdG9yVmFsdWU/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0V29ya2Zsb3dFdGF0KGRlc2NyaW1pbmF0b3JWYWx1ZSksXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0V29ya2Zsb3dFdGF0U3VpdmFudHMoZGVzY3JpbWluYXRvclZhbHVlKSxcclxuICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgLy8gQSBwYWdlIG1heSBoYXZlIGFycml2ZWQgYmVmb3JlIHRoZSBjb2x1bW5zIHdlcmUga25vd246IHJlLWJ1Y2tldCBpdHMgY2FyZHMgaW50byB0aGVtLlxyXG4gICAgICAgIGNvbnN0IHBhZ2UgPSB0aGlzLnBhZ2UkPy52YWx1ZSA/PyB0aGlzLl9wYWdlO1xyXG4gICAgICAgIGlmIChwYWdlKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlUGFnZUNoYW5nZShwYWdlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRDb2xLZXlzKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHBob3RvOiB0aGlzLmVudGl0eUluZm8/LmNhcmRIZWFkZXJQaG90b0NvbHVtbj8udG9Mb3dlckNhc2UoKSA/PyAnJyxcclxuICAgICAgICAgICAgY29sMTogdGhpcy5lbnRpdHlJbmZvPy5jYXJkVGl0bGVDb2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNvbDI6IHRoaXMuZW50aXR5SW5mbz8uY2FyZFN1YkhlYWRlckNvbHVtbj8udG9Mb3dlckNhc2UoKSA/PyAnJyxcclxuICAgICAgICAgICAgY29sMzogdGhpcy5lbnRpdHlJbmZvPy5jYXJkRGVzY3JpcHRpb25Db2x1bW4/LnRvTG93ZXJDYXNlKCkgPz8gJycsXHJcbiAgICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5lbnRpdHlJbmZvPy5jbGFzc05hbWU/LnRvTG93ZXJDYXNlKCkgPz8gJydcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgbWFwSXRlbXNUb0NhcmRzKGl0ZW1zOiBhbnlbXSk6IFByb21pc2U8VHNpQ2FyZFtdPiB7XHJcbiAgICAgICAgY29uc3QgeyBjb2wxLCBjb2wyLCBjb2wzLCBwaG90byB9ID0gdGhpcy5nZXRDb2xLZXlzKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcy5tYXAoKGl0ZW06IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoaXRlbSkucmVkdWNlKChhY2MsIGtleSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgYWNjW2tleS50b0xvd2VyQ2FzZSgpXSA9IGtleTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgICAgICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pO1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgd29ya2Zsb3dFdGF0VmFsdWUgPSBpdGVtLndvcmtmbG93RXRhdCA/PyBudWxsO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGlkOiBpbmRleCArIDEgKyB0aGlzLmZpcnN0LFxyXG4gICAgICAgICAgICAgICAgdWlkOiBgJHtpdGVtLnVpZH1gLFxyXG4gICAgICAgICAgICAgICAgaGVhZGVyVGl0bGU6IGAke2l0ZW1ba2V5c1tjb2wxXV0gPz8gJyd9YCxcclxuICAgICAgICAgICAgICAgIHN1YkhlYWRlclRpdGxlOiBgJHtpdGVtW2tleXNbY29sMl1dID8/ICcnfWAsXHJcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYCR7aXRlbVtrZXlzW2NvbDNdXSA/PyAnJ31gLFxyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiB3b3JrZmxvd0V0YXRWYWx1ZSxcclxuICAgICAgICAgICAgICAgIHBob3RvOiBpdGVtW2tleXNbcGhvdG9dXSB8fCBkZWZhdWx0Q2FyZEhlYWRlci5pbWFnZSxcclxuICAgICAgICAgICAgICAgIGZ1bGxSZWNvcmQ6IGl0ZW0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVDYXJkTWFwKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nIHwgbnVsbCwgVHNpQ2FyZFtdPigpO1xyXG4gICAgICAgIGZvciAoY29uc3QgbGFiZWwgb2YgdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMpIHtcclxuICAgICAgICAgICAgbWFwLnNldChsYWJlbC5rZXksIFtdKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgY2FyZCBvZiB0aGlzLmNhcmRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGNhcmQuc3RhdHVzID8/IG51bGw7XHJcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwID0gbWFwLmdldChrZXkpO1xyXG4gICAgICAgICAgICBpZiAoZ3JvdXApIHtcclxuICAgICAgICAgICAgICAgIGdyb3VwLnB1c2goY2FyZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgVW5tYXBwZWQgY2FyZCBzdGF0dXM6ICR7Y2FyZC5zdGF0dXN9YCwgY2FyZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2FyZHNdIG9mIG1hcC5lbnRyaWVzKCkpIHtcclxuICAgICAgICAgICAgY2FyZHMuc29ydCgoYSwgYikgPT4gKGEuaGVhZGVyVGl0bGUgPz8gJycpLmxvY2FsZUNvbXBhcmUoYi5oZWFkZXJUaXRsZSA/PyAnJykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5jYXJkTWFwQnlXb3JrZmxvd0V0YXQgPSBtYXA7XHJcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9XHJcbiAgICAgICAgXHJcbiAgcHJpdmF0ZSBhc3luYyBnZXRXb3JrZmxvd0V0YXQoZGVzY3JpbWluYXRvclZhbHVlPzogc3RyaW5nKSB7XHJcbiAgICAgIGlmICghdGhpcy5jYXJkQnVzaW5lc3NDbGFzcykge1xyXG4gICAgICAgIHJldHVyblxyXG4gICAgICB9XHJcblxyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5fd29ya2Zsb3dDb25maWd1cmF0aW9uU2VydmljZS5nZXRXb3JrZmxvd0V0YXRCeUNsYXNzTmFtZUFuZERlc2NyaW1pbmF0b3IodGhpcy5jYXJkQnVzaW5lc3NDbGFzcywgZGVzY3JpbWluYXRvclZhbHVlLCB0cnVlKSk7XHJcbiAgICAgICAgdGhpcy53b3JrRmxvd0V0YXROb21MYWJlbHMgPSBbXHJcbiAgICAgICAgICAgIHsga2V5OiBudWxsLCBsb2NhbGl6ZWQ6IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybSgnc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfc2Fuc193b3JrZmxvdycpLnRyaW0oKSB9LFxyXG4gICAgICAgICAgICAuLi5yZXNwb25zZS5tYXAoKHM6IGFueSkgPT4gKHtcclxuICAgICAgICAgICAgICAgIGtleTogcy5rZXksXHJcbiAgICAgICAgICAgICAgICBsb2NhbGl6ZWQ6IHRoaXMuX2xvY2FsaXplLnRyYW5zZm9ybShzLnZhbHVlKS50cmltKClcclxuICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgXTtcclxuICAgICAgfVxyXG4gICAgICBjYXRjaChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2VycmV1ciBnZXRXb3JrZmxvd0V0YXRCeUNsYXNzTmFtZUFuZERlc2NyaW1pbmF0b3IgOiAnLCBlcnJvcik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGdldFdvcmtmbG93RXRhdFN1aXZhbnRzKGRlc2NyaW1pbmF0b3JWYWx1ZT86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghdGhpcy5jYXJkQnVzaW5lc3NDbGFzcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuX3dvcmtmbG93Q29uZmlndXJhdGlvblNlcnZpY2UuZ2V0V29ya2Zsb3dFdGF0U3VpdmFudHNCeUNsYXNzTmFtZUFuZERlc2NyaW1pbmF0b3IodGhpcy5jYXJkQnVzaW5lc3NDbGFzcywgZGVzY3JpbWluYXRvclZhbHVlKSk7XHJcbiAgICAgICAgICAgIHRoaXMuYWxsb3dlZFRhcmdldHNCeVdvcmtmbG93RXRhdCA9IG5ldyBNYXAoT2JqZWN0LmVudHJpZXMocmVzcG9uc2UgPz8ge30pXHJcbiAgICAgICAgICAgICAgICAubWFwKChbd29ya2Zsb3dFdGF0LCBzdWl2YW50c10pID0+IFt3b3JrZmxvd0V0YXQsIG5ldyBTZXQoc3VpdmFudHMpXSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignZXJyZXVyIGdldFdvcmtmbG93RXRhdFN1aXZhbnRzQnlDbGFzc05hbWVBbmREZXNjcmltaW5hdG9yIDogJywgZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSIsIjxkaXYgY2xhc3M9XCJjYXJkIGZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gIDxwLXBhZ2luYXRvciBbZmlyc3RdPVwiZmlyc3RcIiBbcm93c109XCJyb3dzXCIgW3RvdGFsUmVjb3Jkc109XCJ0b3RhbENvdW50XCIgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJbMSwgMTAsIDI1LCA1MF1cIlxyXG4gICAgKG9uUGFnZUNoYW5nZSk9XCJvblBhZ2VDaGFuZ2UoJGV2ZW50KVwiIFtzaG93Q3VycmVudFBhZ2VSZXBvcnRdPVwidHJ1ZVwiXHJcbiAgICBjdXJyZW50UGFnZVJlcG9ydFRlbXBsYXRlPVwie3sgJ1Nob3dpbmcnIHwgbG9jYWxpemUgfX0ge2ZpcnN0fSB7eyd0bycgfCBsb2NhbGl6ZX19IHtsYXN0fSB7eyAnb2YnIHwgbG9jYWxpemUgfX0ge3RvdGFsUmVjb3Jkc31cIj5cclxuICA8L3AtcGFnaW5hdG9yPlxyXG48L2Rpdj5cclxuXHJcbjxkaXYgKm5nSWY9XCJzZWxlY3RlZENvdW50ID4gMFwiIGNsYXNzPVwia2FuYmFuLWJ1bGstYmFyIGZsZXggZmxleC13cmFwIGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMyBwLTIgbXgtMyBib3JkZXItcm91bmRcIj5cclxuICA8c3BhbiBjbGFzcz1cImZvbnQtc2VtaWJvbGRcIj5cclxuICAgIHt7IHNlbGVjdGVkQ291bnQgfX0ge3sgJ3NoYXJlZF90c2lfY29tcG9uZW50X2dyaWRfa2FuYmFuX3dvcmtmbG93RXRhdF92aWV3X2J1bGtfc2VsZWN0ZWQnIHwgbG9jYWxpemUgfX1cclxuICA8L3NwYW4+XHJcbiAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj5cclxuICAgIDxpIGNsYXNzPVwicGkgcGktYXJyb3dzLWggbXItMVwiPjwvaT57eyAnc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfYnVsa19kcmFnX2hpbnQnIHwgbG9jYWxpemVcclxuICAgIH19XHJcbiAgPC9zcGFuPlxyXG4gIDxwLWJ1dHRvbiBpY29uPVwicGkgcGktdGltZXNcIiBzdHlsZUNsYXNzPVwicC1idXR0b24tdGV4dFwiXHJcbiAgICBbbGFiZWxdPVwiJ3NoYXJlZF90c2lfY29tcG9uZW50X2dyaWRfa2FuYmFuX3dvcmtmbG93RXRhdF92aWV3X2J1bGtfY2xlYXJfc2VsZWN0aW9uJyB8IGxvY2FsaXplXCJcclxuICAgIFtkaXNhYmxlZF09XCJpc0xvYWRpbmdcIiAob25DbGljayk9XCJjbGVhclNlbGVjdGlvbigpXCI+XHJcbiAgPC9wLWJ1dHRvbj5cclxuPC9kaXY+XHJcblxyXG48ZGl2IGNsYXNzPVwia2FuYmFuLWJvYXJkIGZsZXggZ2FwLTQgb3ZlcmZsb3ctYXV0b1wiPlxyXG4gIDxkaXYgKm5nRm9yPVwibGV0IHdvcmtmbG93RXRhdCBvZiBkaXNwbGF5ZWRXb3JrRmxvd0V0YXRMYWJlbHM7IHRyYWNrQnk6IHRyYWNrQnlXb3JrZmxvd0V0YXRcIlxyXG4gICAgY2xhc3M9XCJrYW5iYW4tY29sdW1uIGZsZXggZmxleC1jb2x1bW4gYm9yZGVyLXJvdW5kIHN1cmZhY2UtMCBzaGFkb3ctMlwiXHJcbiAgICBbY2xhc3Mua2FuYmFuLWNvbHVtbi1kcm9wLWFsbG93ZWRdPVwiZHJhZ2dlZENhcmQgJiYgaXNBbGxvd2VkRHJvcFRhcmdldCh3b3JrZmxvd0V0YXQua2V5KVwiXHJcbiAgICBbY2xhc3Mua2FuYmFuLWNvbHVtbi1kcm9wLWZvcmJpZGRlbl09XCJkcmFnZ2VkQ2FyZCAmJiB3b3JrZmxvd0V0YXQua2V5ICE9PSBkcmFnZ2VkQ2FyZC5zdGF0dXMgJiYgIWlzQWxsb3dlZERyb3BUYXJnZXQod29ya2Zsb3dFdGF0LmtleSlcIlxyXG4gICAgKGRyYWdvdmVyKT1cImFsbG93RHJvcCgkZXZlbnQpXCIgKGRyb3ApPVwiZHJvcCgkZXZlbnQsIHdvcmtmbG93RXRhdC5rZXkpXCI+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbi1oZWFkZXIgcC0zIGJvcmRlci1ib3R0b20tMSBzdXJmYWNlLWJvcmRlciBmb250LXNlbWlib2xkXCI+XHJcbiAgICAgIHt7IHdvcmtmbG93RXRhdC5sb2NhbGl6ZWQgfX1cclxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXNtIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cclxuICAgICAgICAoe3sgZ2V0Q29sdW1uQ291bnQod29ya2Zsb3dFdGF0LmtleSkgfX0pXHJcbiAgICAgIDwvc3Bhbj5cclxuICAgICAgPGRpdiAqbmdJZj1cIndvcmtmbG93RXRhdC5rZXkgIT09IG51bGwgJiYgc2VsZWN0aW9uQ29sdW1uS2V5ID09PSB3b3JrZmxvd0V0YXQua2V5XCJcclxuICAgICAgICBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yIG10LTIgdGV4dC1zbSBmb250LW5vcm1hbFwiPlxyXG4gICAgICAgIDxwLWNoZWNrYm94IFtiaW5hcnldPVwidHJ1ZVwiIFtuZ01vZGVsXT1cImlzQ29sdW1uUGFnZUZ1bGx5U2VsZWN0ZWQod29ya2Zsb3dFdGF0LmtleSlcIlxyXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbENvbHVtblBhZ2Uod29ya2Zsb3dFdGF0LmtleSlcIiBbZGlzYWJsZWRdPVwiaXNMb2FkaW5nXCI+XHJcbiAgICAgICAgPC9wLWNoZWNrYm94PlxyXG4gICAgICAgIDxzcGFuPnt7ICdzaGFyZWRfdHNpX2NvbXBvbmVudF9ncmlkX2thbmJhbl93b3JrZmxvd0V0YXRfdmlld19idWxrX3NlbGVjdF9hbGxfcGFnZScgfCBsb2NhbGl6ZSB9fTwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIiAqbmdJZj1cImhhc0NvbHVtblN1bW1hcmllc1wiPlxyXG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHN1bUNvbCBvZiBzdW1tYXJ5Q29sdW1uc1wiIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTFcIj5cclxuICAgICAgICAgIDxzcGFuPnt7IChzdW1Db2wuaGVhZGVyID8/IHN1bUNvbC5maWVsZCkgfCBsb2NhbGl6ZSB9fTo8L3NwYW4+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJzdW1Db2wudHlwZVwiPlxyXG4gICAgICAgICAgICA8VHNpLUN1cnJlbmN5LVNvY2lldGUtRGlzcGxheSAqbmdTd2l0Y2hDYXNlPVwiZGlzcGxheVR5cGVzLkNVUlJFTkNZX1NPQ0lFVEVfRElTUExBWVwiXHJcbiAgICAgICAgICAgICAgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUod29ya2Zsb3dFdGF0LmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1DdXJyZW5jeS1Tb2NpZXRlLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxUc2ktSW50ZWdlci1EaXNwbGF5ICpuZ1N3aXRjaENhc2U9XCJkaXNwbGF5VHlwZXMuSU5URUdFUl9ESVNQTEFZXCJcclxuICAgICAgICAgICAgICBbaW5wdXREYXRhXT1cImdldENvbHVtblN1bW1hcnlWYWx1ZSh3b3JrZmxvd0V0YXQua2V5LCBzdW1Db2wuZmllbGQpXCI+XHJcbiAgICAgICAgICAgIDwvVHNpLUludGVnZXItRGlzcGxheT5cclxuICAgICAgICAgICAgPFRzaS1SYXRlLURpc3BsYXkgKm5nU3dpdGNoQ2FzZT1cImRpc3BsYXlUeXBlcy5SQVRFX0RJU1BMQVlcIiBbaXNGcmFjdGlvbl09XCJzdW1Db2wuaXNGcmFjdGlvbiA/PyBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUod29ya2Zsb3dFdGF0LmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1SYXRlLURpc3BsYXk+XHJcbiAgICAgICAgICAgIDxUc2ktRGVjaW1hbC1EaXNwbGF5ICpuZ1N3aXRjaENhc2U9XCJkaXNwbGF5VHlwZXMuREVDSU1BTF9ESVNQTEFZXCIgW2Zvcm1hdERlY2ltYWxdPVwic3VtQ29sLmZvcm1hdERlY2ltYWxcIlxyXG4gICAgICAgICAgICAgIFtudW1PZkRlY2ltYWxdPVwic3VtQ29sLm51bU9mRGVjaW1hbFwiIFtpbnB1dERhdGFdPVwiZ2V0Q29sdW1uU3VtbWFyeVZhbHVlKHdvcmtmbG93RXRhdC5rZXksIHN1bUNvbC5maWVsZClcIj5cclxuICAgICAgICAgICAgPC9Uc2ktRGVjaW1hbC1EaXNwbGF5PlxyXG4gICAgICAgICAgICA8VHNpLUN1cnJlbmN5LU90aGVyLURpc3BsYXkgKm5nU3dpdGNoQ2FzZT1cImRpc3BsYXlUeXBlcy5DVVJSRU5DWV9PVEhFUl9ESVNQTEFZXCJcclxuICAgICAgICAgICAgICBbY3VycmVuY3ldPVwic3VtQ29sLmN1cnJlbmN5T3RoZXJDb2RlXCIgW2lucHV0RGF0YV09XCJnZXRDb2x1bW5TdW1tYXJ5VmFsdWUod29ya2Zsb3dFdGF0LmtleSwgc3VtQ29sLmZpZWxkKVwiPlxyXG4gICAgICAgICAgICA8L1RzaS1DdXJyZW5jeS1PdGhlci1EaXNwbGF5PlxyXG4gICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hEZWZhdWx0Pnt7IGdldENvbHVtblN1bW1hcnlWYWx1ZSh3b3JrZmxvd0V0YXQua2V5LCBzdW1Db2wuZmllbGQpIH19PC9zcGFuPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbi1jYXJkcyBmbGV4LTEgb3ZlcmZsb3ctYXV0byBwLTNcIj5cclxuICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY2FyZCBvZiBjYXJkTWFwQnlXb3JrZmxvd0V0YXQuZ2V0KHdvcmtmbG93RXRhdC5rZXkpOyB0cmFja0J5OiB0cmFja0J5Q2FyZFwiXHJcbiAgICAgICAgY2xhc3M9XCJrYW5iYW4tY2FyZCBwLTMgYm9yZGVyLXJvdW5kIGJnLXdoaXRlIG1iLTMgc2hhZG93LTFcIiBbbmdDbGFzc109XCJnZXRXb3JrZmxvd0V0YXRDbGFzcyhjYXJkKVwiXHJcbiAgICAgICAgW2NsYXNzLmthbmJhbi1jYXJkLXNlbGVjdGVkXT1cImlzQ2FyZFNlbGVjdGVkKGNhcmQpXCJcclxuICAgICAgICBbY2xhc3Mua2FuYmFuLWNhcmQtZHJhZy1zb3VyY2VdPVwiaXNCdWxrRHJhZ2dpbmcgJiYgaXNDYXJkU2VsZWN0ZWQoY2FyZClcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcclxuICAgICAgICAoZHJhZ3N0YXJ0KT1cImRyYWdTdGFydCgkZXZlbnQsIGNhcmQpXCIgKGRyYWdlbmQpPVwiZHJhZ0VuZCgpXCI+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMiBtYi0yXCI+XHJcbiAgICAgICAgICA8cC1jaGVja2JveCAqbmdJZj1cIndvcmtmbG93RXRhdC5rZXkgIT09IG51bGxcIiBbYmluYXJ5XT1cInRydWVcIiBbbmdNb2RlbF09XCJpc0NhcmRTZWxlY3RlZChjYXJkKVwiXHJcbiAgICAgICAgICAgIChvbkNoYW5nZSk9XCJ0b2dnbGVDYXJkU2VsZWN0aW9uKHdvcmtmbG93RXRhdC5rZXksIGNhcmQpXCIgW2Rpc2FibGVkXT1cImlzTG9hZGluZ1wiPlxyXG4gICAgICAgICAgPC9wLWNoZWNrYm94PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvbnQtYm9sZFwiPnt7IGNhcmQuaGVhZGVyVGl0bGUgfX08L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1zbSB0ZXh0LWdyYXktNjAwIG1iLTNcIj57eyBjYXJkLmRlc2NyaXB0aW9uIH19PC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc20gdGV4dC1ncmF5LTYwMCBtYi0zXCI+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtc2VtaWJvbGRcIj57eyAnc2hhcmVkX3RzaV9jb21wb25lbnRfZ3JpZF9rYW5iYW5fd29ya2Zsb3dFdGF0X3ZpZXdfd29ya2Zsb3dfZXRhdCcgfCBsb2NhbGl6ZVxyXG4gICAgICAgICAgICB9fTo8L3NwYW4+XHJcbiAgICAgICAgICA8c3Bhbj57eyBnZXRMb2NhbGl6ZWRXb3JrZmxvd0V0YXQoY2FyZC5zdGF0dXMpIH19PC9zcGFuPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8cC1tZW51IGFwcGVuZFRvPVwiYm9keVwiICNtZW51TW9yZUFjdGlvbnMgW21vZGVsXT1cIm92ZXJmbG93QWN0aW9uc01lbnVcIiBbcG9wdXBdPVwidHJ1ZVwiIHN0eWxlQ2xhc3M9XCJvdmVyZmxvdy1tZW51XCJcclxuICAgICAgICAgIFtzdHlsZV09XCJ7ICd3aWR0aCc6ICdhdXRvJywgJ21pbi13aWR0aCc6ICcwcHgnIH1cIj5cclxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpdGVtXCIgbGV0LW1lbnVJdGVtPlxyXG4gICAgICAgICAgICA8YSBwUmlwcGxlIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgcC1tZW51aXRlbS1saW5rXCIgW25nQ2xhc3NdPVwibWVudUl0ZW0uc3R5bGVDbGFzc1wiXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uT3ZlcmZsb3dBY3Rpb25DbGlja2VkKGNhcmQsIG1lbnVJdGVtKVwiPlxyXG4gICAgICAgICAgICAgIDxpICpuZ0lmPVwibWVudUl0ZW0uaWQgPT09ICdub3RlcydcIiBjbGFzcz1cInt7IG1lbnVJdGVtLmljb25DbGFzcyB9fSBwLW1lbnVpdGVtLWljb24gYmFkZ2UtaWNvbiBoYXMtYmFkZ2VcIlxyXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwibWVudUl0ZW0uaWNvblN0eWxlQ2xhc3NcIiBwQmFkZ2Ugc2V2ZXJpdHk9XCJkYW5nZXJcIiBbdmFsdWVdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnRcIlxyXG4gICAgICAgICAgICAgICAgW2JhZGdlRGlzYWJsZWRdPVwiY2FyZC5mdWxsUmVjb3JkLm5vdGVzQ291bnQgPT0gbnVsbFwiIGJhZGdlUG9zaXRpb249XCJ0b3AtcmlnaHRcIj5cclxuICAgICAgICAgICAgICA8L2k+XHJcblxyXG4gICAgICAgICAgICAgIDxpICpuZ0lmPVwibWVudUl0ZW0uaWQgIT09ICdub3RlcydcIiBjbGFzcz1cInt7bWVudUl0ZW0uaWNvbkNsYXNzfX0gcC1tZW51aXRlbS1pY29uXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1lbnVJdGVtLmljb25TdHlsZUNsYXNzXCI+XHJcbiAgICAgICAgICAgICAgPC9pPlxyXG5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lbnUtbGFiZWxcIj5cclxuICAgICAgICAgICAgICAgIHt7IG1lbnVJdGVtLmxhYmVsIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC9wLW1lbnU+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1lbmQgYWxpZ24taXRlbXMtY2VudGVyIG10LTEgZ2FwLTIgcC0wXCI+XHJcbiAgICAgICAgICA8VHNpLUJ1dHRvbiBbc3R5bGVDbGFzc109XCIncC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0IHAtMC01J1wiIHR5cGU9XCJidXR0b25cIiBpY29uPVwicGkgcGktcGVuY2lsXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cImVkaXQoY2FyZC51aWQpXCI+XHJcbiAgICAgICAgICA8L1RzaS1CdXR0b24+XHJcbiAgICAgICAgICA8cC1idXR0b24gdHlwZT1cImJ1dHRvblwiIGljb249XCJwaSBwaS1lbGxpcHNpcy12XCIgc3R5bGVDbGFzcz1cIm92ZXJmbG93LWJ0blwiXHJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cIm92ZXJmbG93Q29sdW1uQ2xpY2tlZChtZW51TW9yZUFjdGlvbnMsICRldmVudCwgY2FyZClcIj5cclxuICAgICAgICAgIDwvcC1idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiAjYnVsa0RyYWdQcmV2aWV3ICpuZ0lmPVwic2VsZWN0ZWRDb3VudCA+IDFcIiBjbGFzcz1cImthbmJhbi1idWxrLWRyYWctcHJldmlld1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxyXG4gIDxkaXYgY2xhc3M9XCJrYW5iYW4tYnVsay1kcmFnLXByZXZpZXctYmFkZ2VcIj5cclxuICAgIHt7IHNlbGVjdGVkQ291bnQgfX0ge3sgJ3NoYXJlZF90c2lfY29tcG9uZW50X2dyaWRfa2FuYmFuX3dvcmtmbG93RXRhdF92aWV3X2J1bGtfc2VsZWN0ZWQnIHwgbG9jYWxpemUgfX1cclxuICA8L2Rpdj5cclxuICA8ZGl2ICpuZ0Zvcj1cImxldCBwcmV2aWV3Q2FyZCBvZiBzZWxlY3RlZENhcmRzUHJldmlld1wiIGNsYXNzPVwia2FuYmFuLWJ1bGstZHJhZy1wcmV2aWV3LWNhcmRcIlxyXG4gICAgW25nQ2xhc3NdPVwiZ2V0V29ya2Zsb3dFdGF0Q2xhc3MocHJldmlld0NhcmQpXCI+XHJcbiAgICB7eyBwcmV2aWV3Q2FyZC5oZWFkZXJUaXRsZSB9fVxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgKm5nSWY9XCJzZWxlY3RlZENvdW50ID4gc2VsZWN0ZWRDYXJkc1ByZXZpZXcubGVuZ3RoXCIgY2xhc3M9XCJrYW5iYW4tYnVsay1kcmFnLXByZXZpZXctbW9yZVwiPlxyXG4gICAgKyB7eyBzZWxlY3RlZENvdW50IC0gc2VsZWN0ZWRDYXJkc1ByZXZpZXcubGVuZ3RoIH19XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cIm92ZXJsYXlcIiAqbmdJZj1cImlzTG9hZGluZ1wiPlxyXG4gIDxkaXYgY2xhc3M9XCJzcGlubmVyLXdyYXBwZXJcIj5cclxuICAgIDxhcHAtc3Bpbm5lcj48L2FwcC1zcGlubmVyPlxyXG4gIDwvZGl2PlxyXG48L2Rpdj4iXX0=