@eqproject/eqp-attachments 3.0.3 → 3.1.0

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,12 +1,10 @@
1
1
  import { Component, EventEmitter, Input, Output, ViewChild } from "@angular/core";
2
2
  import { Validators } from "@angular/forms";
3
- import { TooltipPositionType, TypeColumn } from "@eqproject/eqp-common";
4
3
  import imageCompression from "browser-image-compression";
5
4
  import { base64ToFile, ImageCropperComponent } from "ngx-image-cropper";
6
5
  import { AttachmentHelperService } from "./helpers/attachment.helper";
7
6
  import { AttachmentType } from "./interfaces/IAttachment";
8
7
  import { EqpAttachmentDialogService } from "./services/eqp-attachment-dialog.service";
9
- import { concatMap, from, Observable } from "rxjs";
10
8
  import * as i0 from "@angular/core";
11
9
  import * as i1 from "@angular/material/dialog";
12
10
  import * as i2 from "@angular/forms";
@@ -17,13 +15,11 @@ import * as i6 from "@angular/material/button";
17
15
  import * as i7 from "@angular/material/input";
18
16
  import * as i8 from "@angular/material/form-field";
19
17
  import * as i9 from "@angular/material/menu";
20
- import * as i10 from "@angular/material/card";
18
+ import * as i10 from "@angular/material/button-toggle";
21
19
  import * as i11 from "@angular/material/icon";
22
20
  import * as i12 from "@angular/material/tooltip";
23
21
  import * as i13 from "@angular/common";
24
22
  import * as i14 from "ngx-image-cropper";
25
- import * as i15 from "@eqproject/eqp-table";
26
- import * as i16 from "ngx-file-drop";
27
23
  const toBase64 = (file) => new Promise((resolve, reject) => {
28
24
  const reader = new FileReader();
29
25
  reader.readAsDataURL(file);
@@ -54,6 +50,10 @@ export class EqpAttachmentsComponent {
54
50
  * Sorgente dati da visualizzare. Nel caso si vuole gestire un singolo allegato va passato in ogni caso come Array.
55
51
  */
56
52
  attachmentsList = null;
53
+ /**
54
+ * Nel caso si vuole gestire un solo elemento senza passarlo come array, lo passo come singolo allegato e gestisco nella libreria l'array.
55
+ */
56
+ singleAttachment = null;
57
57
  /**
58
58
  * Se TRUE non mostra la MatCard (nel caso in cui "multipleAttachment" è TRUE).
59
59
  */
@@ -68,10 +68,6 @@ export class EqpAttachmentsComponent {
68
68
  * SOLO se si gestiscono allegati multipli, quindi se l'input 'multipleAttachment' assume il valore TRUE, altrimenti è sempre disabilitata.
69
69
  */
70
70
  loadMultipleFiles = false;
71
- /**
72
- * Configurazione delle colonne della eqp-table per la visualizzazione degli allegati (caso "multipleAttachment" è TRUE).
73
- */
74
- attachmentsColumns = null;
75
71
  /**
76
72
  * Imposta il messaggio da visualizzare nel caso in cui la tabella degli allegati (nel caso in cui "multipleAttachment" è TRUE) è vuota.
77
73
  */
@@ -164,10 +160,13 @@ export class EqpAttachmentsComponent {
164
160
  * Classe custom da assegnare al dialog del crop immagini
165
161
  */
166
162
  cropDialogClass;
163
+ maxFileSizeMB = 100; // Default max size of 100 MB
164
+ cardSize = 'small'; // Default
165
+ customCardWidthPx = 200; // Larghezza custom in px
166
+ customCardHeightPx = 180; // Altezza custom in px
167
167
  /**
168
168
  * Input per definire le label da usare nel componente
169
169
  */
170
- downloadTooltipPosition = TooltipPositionType.Below;
171
170
  openLinkLabel = "Apri link";
172
171
  addButtonLabel = "Aggiungi";
173
172
  downloadLabel = "Download";
@@ -181,7 +180,6 @@ export class EqpAttachmentsComponent {
181
180
  exitLabel = "Esci";
182
181
  uploadWithDropboxLabel = "Carica con Dropbox";
183
182
  cropLabel = "Scegli le dimensioni dell'immagine";
184
- eqpTableSearchText = "Cerca";
185
183
  deleteDialogTitle = null;
186
184
  deleteDialogMessage = "Sei sicuro di voler cancellare quest'allegato?";
187
185
  noImageSelectedErrorMessage = "Non è possibile selezionare un file che non sia un'immagine.";
@@ -192,6 +190,21 @@ export class EqpAttachmentsComponent {
192
190
  flipVerticalLabel = "Capovolgi verticalmente";
193
191
  rotateRightLabel = "Ruota a destra";
194
192
  rotateLeftLabel = "Ruota a sinistra";
193
+ uploadTitle = 'Upload file';
194
+ uploadSubtitle = 'Drag & drop files o click';
195
+ dropHereLabel = 'Rilascia i file qui';
196
+ supportedFormatsLabel = 'Formati supportati: JPEG, PNG, PDF (Max 100MB)';
197
+ browseFilesLabel = 'Cerca i file';
198
+ uploadSummaryLabel = 'Lista allegati';
199
+ filesLabel = 'Files';
200
+ totalSizeLabel = 'Dimensione totale';
201
+ emptyStateLabel = 'Non sono presenti file caricati';
202
+ addedSuccessfullyLabel = 'file(s) caricati con successo.';
203
+ removedLabel = 'File rimosso';
204
+ // @Input() removeLabel = 'Rimuovi file';
205
+ chooseView = true;
206
+ showSummary = false;
207
+ viewMode = 'table';
195
208
  //#endregion
196
209
  //#region @Output del componente
197
210
  /**
@@ -225,6 +238,7 @@ export class EqpAttachmentsComponent {
225
238
  dialogAddMultipleAttachment;
226
239
  dialogRefCropImage;
227
240
  dialogCropImage;
241
+ addingLinkTemplate;
228
242
  //#endregion
229
243
  //#region Proprietà per gestione ridimensionamento file di tipo image
230
244
  imageChangedEvent = "";
@@ -240,11 +254,51 @@ export class EqpAttachmentsComponent {
240
254
  originalHeight;
241
255
  customWidth;
242
256
  customHeight;
243
- attachmentTable;
244
257
  inlinePreviewTemplate;
245
258
  dialogPreview;
246
259
  imageFile;
247
260
  addingLinkMode = false;
261
+ //#region Sezione nuova refactoring
262
+ // Stato drag & drop e toast
263
+ dragOver = false;
264
+ toast = {
265
+ visible: false,
266
+ type: 'success',
267
+ text: '',
268
+ timeoutId: 0
269
+ };
270
+ progressPercent = 0;
271
+ totalSizeBytes = 0;
272
+ get totalSizeFormatted() { return this.formatFileSize(this.totalSizeBytes); }
273
+ // Utility per formattare bytes (2 decimali)
274
+ formatFileSize(bytes) {
275
+ if (!bytes || bytes <= 0)
276
+ return '0 Bytes';
277
+ const k = 1024;
278
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
279
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
280
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
281
+ }
282
+ // Mostra toast con auto‑hide e reset progress bar CSS
283
+ showToast(message, type = 'success', durationMs = 3000) {
284
+ if (this.toast.visible && this.toast.text === message) {
285
+ return;
286
+ }
287
+ // Cancella il timeout precedente se esiste
288
+ if (this.toast.timeoutId) {
289
+ clearTimeout(this.toast.timeoutId);
290
+ }
291
+ // Calcola una durata dinamica
292
+ const duration = durationMs || Math.max(4000, message.length * 100);
293
+ this.toast.text = message;
294
+ this.toast.type = type;
295
+ this.toast.visible = true;
296
+ // Imposta il nuovo timeout per nascondere automaticamente il toast
297
+ this.toast.timeoutId = setTimeout(() => {
298
+ this.toast.visible = false;
299
+ }, duration);
300
+ }
301
+ #endregion;
248
302
  constructor(dialog, formBuilder, sanitizer, http, cd, eqpAttachmentService) {
249
303
  this.dialog = dialog;
250
304
  this.formBuilder = formBuilder;
@@ -253,7 +307,9 @@ export class EqpAttachmentsComponent {
253
307
  this.cd = cd;
254
308
  this.eqpAttachmentService = eqpAttachmentService;
255
309
  }
256
- async ngOnInit() {
310
+ ngOnInit() {
311
+ // Inizializza metriche e progress in base allo stato iniziale
312
+ this.recomputeTotalsAndProgress();
257
313
  //Se è stata richiesta la gestione delle sole immagini allora imposta il filtro per le estensioni possibili da caricare
258
314
  if (!this.acceptedFileTypes)
259
315
  if (this.allowOnlyImages == true)
@@ -267,20 +323,48 @@ export class EqpAttachmentsComponent {
267
323
  EqpAttachmentDialogService.Warning('Almeno uno degli AttachmentType selezionati nel parametro "allowedTypes" non esiste.');
268
324
  this.allowedTypes = [AttachmentType.FILE, AttachmentType.LINK, AttachmentType.DROPBOX];
269
325
  }
270
- //Se è stata richiesta la gestione multipla degli allegati allora configura l'eqp-table
271
- if (this.multipleAttachment == true && (!this.attachmentsColumns || this.attachmentsColumns.length == 0)) {
272
- this.configureColumns();
273
- }
274
326
  if (this.attachmentsList == null)
275
327
  this.attachmentsList = new Array();
328
+ // Se è stato passato un singolo allegato lo aggiungo alla lista
329
+ if (this.singleAttachment != null && this.attachmentsList.length == 0) {
330
+ this.attachmentsList.push(this.singleAttachment);
331
+ }
276
332
  this.checkAttachmentImage();
277
333
  if (this.allowedTypes.includes(3)) {
278
334
  this.eqpAttachmentService.loadDropboxScript();
279
335
  }
280
336
  }
281
- reloadData() {
282
- if (this.attachmentTable)
283
- this.attachmentTable.reloadDatatable();
337
+ setViewMode(mode) {
338
+ this.viewMode = mode;
339
+ }
340
+ // Ricalcola la somma pesata sugli allegati presenti
341
+ recomputeTotalsAndProgress() {
342
+ this.totalSizeBytes = (this.attachmentsList || [])
343
+ .filter(a => !!a)
344
+ .reduce((sum, a) => sum + this.bytesFromBase64(a.FileDataBase64 || a.FileThumbnailBase64 || ''), 0);
345
+ // Progress fittizio: 100% se presenti file, 0 se vuoto
346
+ this.progressPercent = (this.attachmentsList && this.attachmentsList.length > 0) ? 100 : 0;
347
+ }
348
+ ngOnDestroy() {
349
+ if (this.toast.timeoutId)
350
+ clearTimeout(this.toast.timeoutId);
351
+ }
352
+ // Calcola i byte da una stringa Base64 pura (senza prefisso data:...)
353
+ bytesFromBase64(base64) {
354
+ if (!base64)
355
+ return 0;
356
+ // Rimuovi eventuale prefisso data URL
357
+ const commaIdx = base64.indexOf(',');
358
+ const b64 = commaIdx >= 0 ? base64.substring(commaIdx + 1) : base64;
359
+ // Conta padding
360
+ let padding = 0;
361
+ if (b64.endsWith('=='))
362
+ padding = 2;
363
+ else if (b64.endsWith('='))
364
+ padding = 1;
365
+ // Formula esatta: (3 * (len / 4)) - padding
366
+ const len = b64.length;
367
+ return Math.max(0, (3 * Math.floor(len / 4)) - padding);
284
368
  }
285
369
  checkAttachmentImage() {
286
370
  this.attachmentsList.forEach((a) => {
@@ -288,67 +372,6 @@ export class EqpAttachmentsComponent {
288
372
  });
289
373
  }
290
374
  //#region Gestione elenco allegati
291
- /**
292
- * Configura le colonne per l'eqp-table nel caso in cui il parametro "multipleAttachments" è TRUE.
293
- */
294
- configureColumns() {
295
- this.attachmentsColumns = [];
296
- if (this.disableAction != true) {
297
- this.attachmentsColumns.push({
298
- key: "action",
299
- display: "",
300
- type: TypeColumn.MenuAction,
301
- buttonMenuIcon: "more_vert",
302
- styles: { flex: "0 0 6%" },
303
- actions: [
304
- { name: this.deleteLabel, icon: "delete", fn: (element, index, col) => this.deleteAttachment(element) }
305
- ]
306
- });
307
- }
308
- let downloadColumn = {
309
- key: "attachment",
310
- display: "",
311
- type: TypeColumn.SimpleAction,
312
- styles: { flex: "0 0 6%" },
313
- actions: [
314
- {
315
- name: "",
316
- fontawesome: true,
317
- icon: (element) => {
318
- return this.showInlinePreview
319
- ? element.AttachmentType == AttachmentType.FILE
320
- ? "fas fa-cloud-download-alt"
321
- : "fas fa-external-link-alt"
322
- : this.getAttachmentIcon(element);
323
- },
324
- fn: (element, col, elementIndex) => this.viewAttachment(element),
325
- tooltip: {
326
- tooltipText: (element) => {
327
- return element.AttachmentType == AttachmentType.FILE ? this.downloadLabel : this.openLinkLabel;
328
- },
329
- tooltipPosition: this.downloadTooltipPosition
330
- }
331
- }
332
- ]
333
- };
334
- let inlinePreviewColumn = {
335
- key: "InlinePreview",
336
- display: this.previewLabel,
337
- type: TypeColumn.ExternalTemplate,
338
- externalTemplate: this.inlinePreviewTemplate,
339
- styles: { flex: "0 0 10%" }
340
- };
341
- let fileNameColumn = { key: "FileName", display: this.fileNameLabel };
342
- if (this.showInlinePreview) {
343
- this.attachmentsColumns.push(inlinePreviewColumn);
344
- this.attachmentsColumns.push(fileNameColumn);
345
- this.attachmentsColumns.push(downloadColumn);
346
- }
347
- else {
348
- this.attachmentsColumns.push(downloadColumn);
349
- this.attachmentsColumns.push(fileNameColumn);
350
- }
351
- }
352
375
  /**
353
376
  * Elimina un allegato eliminando anche il file presente nello storage di archiviazione utilizzato (AWS o cartella progetto)
354
377
  * @param element IAttachmentDTO da cancellare
@@ -365,9 +388,21 @@ export class EqpAttachmentsComponent {
365
388
  removeAttachmentFromList(attachmentIndex) {
366
389
  this.onDeleteAttachment.emit(this.attachmentsList[attachmentIndex]);
367
390
  this.attachmentsList.splice(attachmentIndex, 1);
368
- if (this.attachmentTable)
369
- this.attachmentTable.reloadDatatable();
370
391
  this.localEditedAttachments.emit(this.attachmentsList);
392
+ this.recomputeTotalsAndProgress();
393
+ this.showToast(this.removedLabel || 'File removed', 'success');
394
+ }
395
+ simulateProgress() {
396
+ this.progressPercent = 0;
397
+ setTimeout(() => {
398
+ this.progressPercent = 30;
399
+ setTimeout(() => {
400
+ this.progressPercent = 60;
401
+ setTimeout(() => {
402
+ this.progressPercent = 100;
403
+ }, 200);
404
+ }, 200);
405
+ }, 100);
371
406
  }
372
407
  /**
373
408
  * Scarica l'allegato o apre il link
@@ -456,7 +491,7 @@ export class EqpAttachmentsComponent {
456
491
  }
457
492
  }
458
493
  confirmAddAttachment() {
459
- if (this.newAttachment.IsImage) {
494
+ if (this.newAttachment.IsImage && this.imageCropper) {
460
495
  this.newAttachment.FileDataBase64 = this.imageCropper.crop().base64.split(";base64,")[1];
461
496
  }
462
497
  if (this.loadMultipleFiles != true) {
@@ -473,13 +508,17 @@ export class EqpAttachmentsComponent {
473
508
  this.attachmentsList = new Array();
474
509
  this.attachmentsList = this.attachmentsList.concat(this.newMultipleAttachments);
475
510
  }
476
- if (this.attachmentTable)
477
- this.attachmentTable.reloadDatatable();
511
+ // if (this.attachmentTable) this.attachmentTable.reloadDatatable();
478
512
  this.localEditedAttachments.emit(this.attachmentsList);
479
513
  if (this.newAttachment.IsImage) {
480
514
  this.dialogRefCropImage.close();
481
515
  this.restoreOriginalDimensions();
482
516
  }
517
+ if (this.newAttachment.AttachmentType === AttachmentType.LINK) {
518
+ this.newAttachment = {};
519
+ if (this.newAttachmentForm)
520
+ this.newAttachmentForm.reset();
521
+ }
483
522
  }
484
523
  /**
485
524
  * Apre il dialog per l'anteprima dell'allegato selezionato.
@@ -548,12 +587,16 @@ export class EqpAttachmentsComponent {
548
587
  */
549
588
  async onFileAdded(event, isFileDropped = false) {
550
589
  this.showCropImage = false;
551
- let filesOnInput = isFileDropped ? event : event.target.files;
590
+ // let filesOnInput = isFileDropped ? event : event.target.files;
591
+ const filesOnInput = isFileDropped
592
+ ? event
593
+ : Array.from(event.target?.files || []);
594
+ const { validFiles, oversizedFiles } = this.validationFile(filesOnInput, isFileDropped);
552
595
  //Se è stato richiesto il caricamento SINGOLO oppure se il caricamento è MULTIPLO ma è stato selezionato un solo file
553
596
  //allora verifica se il file è un immagine (per mostrare il CROPPIE)
554
- if ([...filesOnInput].length == 1 || this.loadMultipleFiles != true) {
555
- this.selectedFile = filesOnInput[0];
556
- this.selectedFiles = filesOnInput;
597
+ if ([...validFiles].length == 1 || this.loadMultipleFiles != true) {
598
+ this.selectedFile = validFiles[0];
599
+ this.selectedFiles = validFiles;
557
600
  if (!this.selectedFile)
558
601
  return;
559
602
  //Memorizza i dati per l'allegato
@@ -568,7 +611,7 @@ export class EqpAttachmentsComponent {
568
611
  //Verifica se il file caricato è un'immagine oppure no. Se è un immagine, prima di caricarla mostra il croppie per il resize.
569
612
  //Se non è un immagine allora genera il Base64
570
613
  if (this.newAttachment.IsImage == true) {
571
- this.getImageDimensions(filesOnInput[0]);
614
+ this.getImageDimensions(validFiles[0]);
572
615
  //Mostra il croppie e disabilita la form finchè non termina la modifica dell'immagine
573
616
  this.newAttachmentForm.disable();
574
617
  this.newAttachmentForm.controls["customWidth"].enable();
@@ -592,10 +635,11 @@ export class EqpAttachmentsComponent {
592
635
  }
593
636
  }
594
637
  else {
595
- this.selectedFiles = filesOnInput;
638
+ this.selectedFiles = validFiles;
596
639
  if (!this.selectedFiles || this.selectedFiles.length == 0)
597
640
  return;
598
- this.newMultipleAttachments = new Array();
641
+ if (!this.newMultipleAttachments)
642
+ this.newMultipleAttachments = [];
599
643
  for (let i = 0; i < this.selectedFiles.length; i++) {
600
644
  let newAttachment = await this.createAttachmentFromUploadedFile(this.selectedFiles[i], true, true);
601
645
  //Se è stata richiesta la gestione delle sole immagini ma per errore è stato selezionato un file che non è un immagine
@@ -606,10 +650,50 @@ export class EqpAttachmentsComponent {
606
650
  }
607
651
  this.confirmAddAttachment();
608
652
  }
653
+ this.recomputeTotalsAndProgress();
654
+ this.simulateProgress();
655
+ // Caso 1: Successo Parziale (alcuni file validi, altri no)
656
+ if (oversizedFiles.length > 0 && validFiles.length > 0) {
657
+ const fileNames = oversizedFiles.join(', ');
658
+ this.showToast(`${validFiles.length} file aggiunti. ${oversizedFiles.length} non caricati perché troppo grandi (${fileNames}).`, 'error');
659
+ }
660
+ // Caso 2: Nessun file valido
661
+ else if (oversizedFiles.length > 0 && validFiles.length === 0) {
662
+ }
663
+ // Caso 3: Tutti i file validi
664
+ else if (oversizedFiles.length === 0 && validFiles.length > 0) {
665
+ this.showToast(`${validFiles.length} ${this.addedSuccessfullyLabel || 'file(s) aggiunti con successo.'}`, 'success');
666
+ }
609
667
  //Resetto il valore del file input in modo da scatenare il change anche se si dovesse caricare lo stesso file
610
668
  if (!isFileDropped)
611
669
  event.target.value = "";
612
670
  }
671
+ validationFile(filesOnInput, isFileDropped) {
672
+ const validFiles = [];
673
+ const oversizedFiles = [];
674
+ for (const file of filesOnInput) {
675
+ const fileSizeMB = file.size / 1024 / 1024;
676
+ if (fileSizeMB > this.maxFileSizeMB) {
677
+ oversizedFiles.push(file.name);
678
+ }
679
+ else {
680
+ validFiles.push(file);
681
+ }
682
+ }
683
+ // Show a single error message for all oversized files
684
+ if (oversizedFiles.length > 0) {
685
+ const fileNames = oversizedFiles.join(', ');
686
+ this.showToast(`File(s) troppo grandi: ${fileNames}. Limite: ${this.maxFileSizeMB}MB`, 'error');
687
+ }
688
+ // Abort if no files are valid
689
+ if (validFiles.length === 0) {
690
+ if (!isFileDropped) {
691
+ event.target.value = '';
692
+ }
693
+ return;
694
+ }
695
+ return { validFiles, oversizedFiles };
696
+ }
613
697
  /**
614
698
  * A partire dal FILE ricevuto in input ricostruisce l'oggetto IAttachmentDTO e lo restituisce.
615
699
  * Se il parametro getBase64 viene passato a TRUE allora, sempre a partire dal file,genera il base64 e
@@ -827,35 +911,14 @@ export class EqpAttachmentsComponent {
827
911
  this.restoreOriginalDimensions();
828
912
  }
829
913
  //#endregion
830
- // Viene creato un'array observables per memorizzare tutti gli observable creati dalle chiamate a fileEntry.file().
831
- // Dopo che tutti gli observables sono stati completati, viene utilizzato il metodo subscribe() per eseguire la funzione onFileAdded().
832
- fileDropped(files) {
833
- let filesDropped = [];
834
- const observables = [];
835
- for (let i = 0; i < files.length; i++) {
836
- if (files[i].fileEntry.isFile) {
837
- const fileEntry = files[i].fileEntry;
838
- const observable = new Observable((observer) => {
839
- fileEntry.file((file) => {
840
- filesDropped.push(file);
841
- observer.next(file);
842
- observer.complete();
843
- });
844
- });
845
- observables.push(observable);
846
- }
847
- else {
848
- const fileEntry = files[i].fileEntry;
849
- console.log(files[i].relativePath, fileEntry);
850
- }
914
+ fileDropped(event) {
915
+ event.preventDefault();
916
+ event.stopPropagation();
917
+ this.dragOver = false;
918
+ const files = event.dataTransfer?.files;
919
+ if (files && files.length > 0) {
920
+ this.onFileAdded({ target: { files: files } });
851
921
  }
852
- from(observables)
853
- .pipe(concatMap((observable) => observable))
854
- .subscribe({
855
- complete: () => {
856
- this.onFileAdded(filesDropped, true);
857
- }
858
- });
859
922
  }
860
923
  // Se il caricamento del file dropbox va a buon fine, la funzione di callback restituisce un array di oggetti.
861
924
  // Viene poi fatta una XMLHttpRequest con responseType 'blob' per convertire il primo elemento della response in un Blob.
@@ -890,21 +953,78 @@ export class EqpAttachmentsComponent {
890
953
  fileInput.click();
891
954
  }
892
955
  // Metodo per visualizzare la form di aggiunta di un link
956
+ // switchToAddingLinkMode() {
957
+ // this.addingLinkMode = true;
958
+ // this.newAttachment = {} as IAttachmentDTO;
959
+ // this.newAttachment.IsImage = false;
960
+ // this.newAttachment.AttachmentType = this.attachmentType.LINK;
961
+ // this.newMultipleAttachments = new Array<IAttachmentDTO>();
962
+ // this.newMultipleAttachments.push(this.newAttachment);
963
+ // this.createAttachmentForm();
964
+ // }
965
+ /**
966
+ * Apre il dialogo per l'inserimento del link.
967
+ */
893
968
  switchToAddingLinkMode() {
894
- this.addingLinkMode = true;
895
- this.newAttachment = {};
896
- this.newAttachment.IsImage = false;
897
- this.newAttachment.AttachmentType = this.attachmentType.LINK;
898
- this.newMultipleAttachments = new Array();
899
- this.newMultipleAttachments.push(this.newAttachment);
900
- this.createAttachmentForm();
969
+ // 1. Crea il form per il dialogo
970
+ this.newAttachmentForm = this.formBuilder.group({
971
+ fileName: [''],
972
+ filePath: ['', [Validators.required, Validators.pattern('https?://.+')]]
973
+ });
974
+ // 2. Apri il dialogo
975
+ const dialogRef = this.dialog.open(this.addingLinkTemplate, {
976
+ width: '500px',
977
+ });
978
+ // 3. Gestisci il risultato alla chiusura
979
+ dialogRef.afterClosed().subscribe(result => {
980
+ if (result) {
981
+ // A. Crea l'oggetto per il nuovo link dai dati del form
982
+ const newLinkObject = {
983
+ ID: 0,
984
+ AttachmentType: AttachmentType.LINK,
985
+ FileName: result.fileName,
986
+ FilePath: result.filePath,
987
+ IsImage: false
988
+ };
989
+ // B. Prepara l'oggetto `newAttachment` che `confirmAddAttachment` si aspetta
990
+ this.newAttachment = newLinkObject;
991
+ this.newMultipleAttachments = [newLinkObject];
992
+ // C. Chiama la tua funzione di conferma centrale!
993
+ this.confirmAddAttachment();
994
+ }
995
+ });
996
+ }
997
+ // Metodo per ottenere le classi CSS dinamiche
998
+ getCardClass(att) {
999
+ return {
1000
+ 'file-preview': true,
1001
+ 'uploading': !!att.isUploading,
1002
+ 'card-small': this.cardSize === 'small',
1003
+ 'card-medium': this.cardSize === 'medium',
1004
+ 'card-large': this.cardSize === 'large',
1005
+ // Nessuna classe specifica per 'custom', useremo style.cssText
1006
+ };
1007
+ }
1008
+ // Questa funzione ora si applica al contenitore, non alla singola card.
1009
+ getPreviewsContainerStyle() {
1010
+ let minWidth = '200px'; // Dimensione di default per 'medium'
1011
+ if (this.cardSize === 'small') {
1012
+ minWidth = '140px';
1013
+ }
1014
+ else if (this.cardSize === 'large') {
1015
+ minWidth = '280px';
1016
+ }
1017
+ else if (this.cardSize === 'custom') {
1018
+ minWidth = `${this.customCardWidthPx}px`;
1019
+ }
1020
+ return { '--card-min-width': minWidth };
901
1021
  }
902
1022
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EqpAttachmentsComponent, deps: [{ token: i1.MatDialog }, { token: i2.FormBuilder }, { token: i3.DomSanitizer }, { token: i4.HttpClient }, { token: i0.ChangeDetectorRef }, { token: i5.EqpAttachmentService }], target: i0.ɵɵFactoryTarget.Component });
903
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EqpAttachmentsComponent, selector: "eqp-attachments", inputs: { disableAction: "disableAction", showHeader: "showHeader", headerTitle: "headerTitle", attachmentsList: "attachmentsList", showMatCard: "showMatCard", multipleAttachment: "multipleAttachment", loadMultipleFiles: "loadMultipleFiles", attachmentsColumns: "attachmentsColumns", emptyTableMessage: "emptyTableMessage", allowOnlyImages: "allowOnlyImages", acceptedFileTypes: "acceptedFileTypes", isDisabled: "isDisabled", showInlinePreview: "showInlinePreview", getAttachmentEndpoint: "getAttachmentEndpoint", productionBaseUrl: "productionBaseUrl", compressionOptions: "compressionOptions", allowedTypes: "allowedTypes", isEqpTableMultiLanguage: "isEqpTableMultiLanguage", tablePaginatorVisible: "tablePaginatorVisible", isTableSearcheable: "isTableSearcheable", tablePaginatorSize: "tablePaginatorSize", separatedUploadButtons: "separatedUploadButtons", showPreview: "showPreview", singleAttachmentDragAndDrop: "singleAttachmentDragAndDrop", cropOptions: "cropOptions", cropDialogClass: "cropDialogClass", downloadTooltipPosition: "downloadTooltipPosition", openLinkLabel: "openLinkLabel", addButtonLabel: "addButtonLabel", downloadLabel: "downloadLabel", deleteLabel: "deleteLabel", fileNameLabel: "fileNameLabel", previewLabel: "previewLabel", uploadFileLabel: "uploadFileLabel", confirmLabel: "confirmLabel", abortLabel: "abortLabel", saveLabel: "saveLabel", exitLabel: "exitLabel", uploadWithDropboxLabel: "uploadWithDropboxLabel", cropLabel: "cropLabel", eqpTableSearchText: "eqpTableSearchText", deleteDialogTitle: "deleteDialogTitle", deleteDialogMessage: "deleteDialogMessage", noImageSelectedErrorMessage: "noImageSelectedErrorMessage", wrongTypeSelectedErrorMessage: "wrongTypeSelectedErrorMessage", videoPreviewErrorMessage: "videoPreviewErrorMessage", audioPreviewErrorMessage: ["videoPreviewErrorMessage", "audioPreviewErrorMessage"], flipHorinzontalLabel: "flipHorinzontalLabel", flipVerticalLabel: "flipVerticalLabel", rotateRightLabel: "rotateRightLabel", rotateLeftLabel: "rotateLeftLabel" }, outputs: { localEditedAttachments: "localEditedAttachments", abortAddAttachment: "abortAddAttachment", downloadAttachment: "downloadAttachment", onDeleteAttachment: "onDeleteAttachment" }, viewQueries: [{ propertyName: "dialogAddAttachment", first: true, predicate: ["dialogAddAttachment"], descendants: true, static: true }, { propertyName: "dialogAddMultipleAttachment", first: true, predicate: ["dialogAddMultipleAttachment"], descendants: true, static: true }, { propertyName: "dialogCropImage", first: true, predicate: ["dialogCropImage"], descendants: true, static: true }, { propertyName: "imageCropper", first: true, predicate: ImageCropperComponent, descendants: true }, { propertyName: "imageInput", first: true, predicate: ["imageInput"], descendants: true }, { propertyName: "attachmentTable", first: true, predicate: ["attachmentTable"], descendants: true }, { propertyName: "inlinePreviewTemplate", first: true, predicate: ["inlinePreviewTemplate"], descendants: true, static: true }, { propertyName: "dialogPreview", first: true, predicate: ["dialogPreview"], descendants: true, static: true }], ngImport: i0, template: "<!-- Se richiesta la gestione singola mostra il pulsante di caricamento di un singolo file -->\r\n<div *ngIf=\"multipleAttachment != true\">\r\n <div *ngIf=\"!singleAttachmentDragAndDrop\">\r\n <!-- Template del button per l'aggiunta di un allegato -->\r\n <div *ngIf=\"!addingLinkMode\" class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"addAttachmentButton\"></ng-container>\r\n </div>\r\n <!-- Template della form per l'aggiunta di un link -->\r\n <div *ngIf=\"addingLinkMode\" class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"addingLinkTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n <div *ngIf=\"singleAttachmentDragAndDrop\">\r\n <input\r\n #fileInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <ngx-file-drop\r\n (onFileDrop)=\"fileDropped($event)\"\r\n (click)=\"onSelectFile($event, fileInput)\"\r\n *ngIf=\"\r\n allowedTypes &&\r\n allowedTypes.includes(1) &&\r\n (!attachmentsList || attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \">\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"!addingLinkMode\">\r\n <i class=\"fa-solid fa-cloud-upload-alt fa-3x mt-3\"></i>\r\n Trascina i file qui\r\n <div class=\"btn-group mt-1\" role=\"group\">\r\n <button type=\"button\" class=\"btn btn-light border-end\" (click)=\"fileInput.click()\">Scegli un file</button>\r\n <div class=\"btn-group\" role=\"group\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-light border-start dropdown-toggle\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\"></button>\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n mat-menu-item\r\n (click)=\"fileInput.click()\"\r\n class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n mat-menu-item\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n mat-menu-item\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"addingLinkMode\">\r\n <ng-container *ngTemplateOutlet=\"addingLinkTemplate\"></ng-container>\r\n </ng-template>\r\n </ngx-file-drop>\r\n </div>\r\n <div class=\"text-center\">\r\n <button\r\n class=\"mb-2 me-2 eqp-attachments-download-btn\"\r\n (click)=\"viewAttachment(attachmentsList[0])\"\r\n type=\"button\"\r\n mat-raised-button\r\n *ngIf=\"attachmentsList && attachmentsList.length > 0 && attachmentsList[0]\"\r\n color=\"primary\">\r\n <mat-icon *ngIf=\"attachmentsList[0].AttachmentType == AttachmentType.FILE\">download</mat-icon>\r\n <mat-icon *ngIf=\"attachmentsList[0].AttachmentType != AttachmentType.FILE\">open_in_new</mat-icon>\r\n {{ attachmentsList[0].AttachmentType == AttachmentType.FILE ? downloadLabel : openLinkLabel }}\r\n </button>\r\n <button\r\n class=\"mb-2 me-2 eqp-attachments-preview-btn\"\r\n (click)=\"openPreviewDialog(attachmentsList[0])\"\r\n type=\"button\"\r\n mat-raised-button\r\n color=\"primary\"\r\n *ngIf=\"\r\n showPreview &&\r\n attachmentsList &&\r\n attachmentsList.length > 0 &&\r\n attachmentsList[0] &&\r\n (!attachmentsList[0].FileContentType ||\r\n (!attachmentsList[0].FileContentType.startsWith('video') &&\r\n !attachmentsList[0].FileContentType.startsWith('audio'))) &&\r\n attachmentsList[0].IsImage == true\r\n \">\r\n <mat-icon>visibility</mat-icon> {{ previewLabel }}\r\n </button>\r\n <button\r\n class=\"mb-2 eqp-attachments-delete-btn\"\r\n (click)=\"deleteAttachment(attachmentsList[0])\"\r\n type=\"button\"\r\n mat-raised-button\r\n *ngIf=\"attachmentsList && attachmentsList.length > 0 && attachmentsList[0]\"\r\n [disabled]=\"isDisabled\">\r\n <mat-icon>delete</mat-icon> {{ deleteLabel }}\r\n </button>\r\n </div>\r\n <div\r\n class=\"row\"\r\n style=\"margin-top: 10px\"\r\n *ngIf=\"\r\n attachmentsList.length > 0 &&\r\n attachmentsList[0] &&\r\n attachmentsList[0].FileDataBase64 &&\r\n attachmentsList[0].IsImage == true\r\n \">\r\n <div class=\"col-sm-12 d-flex justify-content-center\">\r\n <div class=\"single-attachment-inline-preview-container\">\r\n <img src=\"data:image/png;base64,{{ attachmentsList[0].FileDataBase64 }}\" />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\" *ngIf=\"attachmentsList.length > 0 && attachmentsList[0] && attachmentsList[0].IsImage != true\">\r\n <div class=\"col-sm-12\">\r\n <mat-form-field>\r\n <mat-label>{{ fileNameLabel }}</mat-label>\r\n <input readonly matInput [(ngModel)]=\"attachmentsList[0].FileName\" />\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"multipleAttachment == true\">\r\n <input\r\n #fileInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <ngx-file-drop (onFileDrop)=\"fileDropped($event)\" (click)=\"onSelectFile($event, fileInput)\">\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"!addingLinkMode\">\r\n <i class=\"fa-solid fa-cloud-upload-alt fa-3x mt-3\"></i>\r\n Trascina i file qui\r\n <div class=\"btn-group mt-1\" role=\"group\">\r\n <button type=\"button\" class=\"btn btn-light border-end\" (click)=\"fileInput.click()\">Scegli un file</button>\r\n <div class=\"btn-group\" role=\"group\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-light border-start dropdown-toggle\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\"></button>\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n mat-menu-item\r\n (click)=\"fileInput.click()\"\r\n class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n mat-menu-item\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n mat-menu-item\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"addingLinkMode\">\r\n <ng-container *ngTemplateOutlet=\"addingLinkTemplate\"></ng-container>\r\n </ng-template>\r\n </ngx-file-drop>\r\n <div class=\"mt-2\">\r\n <eqp-table\r\n #attachmentTable\r\n [createMatCard]=\"false\"\r\n #table\r\n [columns]=\"attachmentsColumns\"\r\n [isMultiLanguage]=\"isEqpTableMultiLanguage\"\r\n [data]=\"attachmentsList\"\r\n [paginatorVisible]=\"tablePaginatorVisible\"\r\n [matPaginatorSize]=\"tablePaginatorSize\"\r\n [emptyTableMessage]=\"emptyTableMessage\"\r\n [searchText]=\"eqpTableSearchText\"\r\n [isTableSearcheable]=\"isTableSearcheable\">\r\n </eqp-table>\r\n </div>\r\n</div>\r\n\r\n<ng-template #dialogCropImage>\r\n <!-- Richiama il template per le funzionalit\u00E0 del CROPPIE -->\r\n <div style=\"overflow-x: hidden\" [ngClass]=\"cropDialogClass\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"croppieTemplate\"\r\n [ngTemplateOutletContext]=\"{ form: newAttachmentForm }\"\r\n *ngIf=\"showCropImage == true\"></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #inlinePreviewTemplate let-row=\"row\">\r\n <div\r\n class=\"inline-preview-container\"\r\n *ngIf=\"row.AttachmentType != AttachmentType.LINK && row.IsImage\"\r\n (click)=\"openPreviewDialog(row)\">\r\n <img src=\"data:image/png;base64,{{ row.FileThumbnailBase64 ? row.FileThumbnailBase64 : row.FileDataBase64 }}\" />\r\n </div>\r\n <div\r\n class=\"inline-preview-container\"\r\n *ngIf=\"row.AttachmentType != AttachmentType.LINK && !row.IsImage\"\r\n (click)=\"openPreviewDialog(row)\">\r\n <i [ngClass]=\"getAttachmentIcon(row)\"></i>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogPreview>\r\n <mat-card class=\"example-card\" *ngIf=\"selectedAttachment\">\r\n <mat-card-content>\r\n <div class=\"row\">\r\n <div class=\"header-title-standard\">\r\n {{ previewLabel }} {{ selectedAttachment?.AttachmentType == attachmentType.FILE ? \"File\" : \"Link\" }}\r\n <button\r\n type=\"button\"\r\n class=\"btn-close closeButton\"\r\n mat-dialog-close\r\n (click)=\"selectedAttachment = null\"></button>\r\n </div>\r\n </div>\r\n <div class=\"row mt-2\">\r\n <!-- ANTEPRIMA IMMAGINE -->\r\n <div class=\"col-12 text-center preview-container\" *ngIf=\"selectedAttachment.IsImage\">\r\n <img\r\n class=\"image-preview\"\r\n src=\"data:image/png;base64,{{\r\n selectedAttachment.FileDataBase64\r\n ? selectedAttachment.FileDataBase64\r\n : selectedAttachment.FileThumbnailBase64\r\n }}\" />\r\n </div>\r\n\r\n <!-- ANTEPRIMA LINK -->\r\n <div class=\"col-12 preview-container\" *ngIf=\"!selectedAttachment.IsImage\">\r\n <iframe\r\n class=\"link-preview\"\r\n [src]=\"selectedAttachment.TrustedUrl\"\r\n [title]=\"selectedAttachment.FileName\"></iframe>\r\n </div>\r\n </div>\r\n <div class=\"row mt-3\">\r\n <div class=\"col-sm-12 text-center\">\r\n <button\r\n mat-mini-fab\r\n color=\"primary\"\r\n matTooltip=\"Download\"\r\n (click)=\"viewAttachment(selectedAttachment)\"\r\n *ngIf=\"selectedAttachment.AttachmentType != AttachmentType.LINK\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n</ng-template>\r\n\r\n<!-- TEMPLATE PER IL PULSANTE DI AGGIUNTA NUOVO ALLEGATO -->\r\n<ng-template #addAttachmentButton>\r\n <!--\r\n Pulsanti per l'aggiunta di un file o un link. Ne viene visualizzato uno se:\r\n - gli allowedTypes sono stati specificati, nell'array ne \u00E8 presente uno solo, quello inserito \u00E8 AttachmentType.FILE (o AttachmentType.LINK)\r\n e sono nella gestione di pi\u00F9 allegati (multipleAttachment == true)\r\n OPPURE\r\n - gli allowedTypes sono stati specificati, nell'array ne \u00E8 presente uno solo, quello inserito \u00E8 AttachmentType.FILE (o AttachmentType.LINK)\r\n e sono nella gestione di un singolo allegato (multipleAttachment == true) e non ne \u00E8 ancora stato selezionato uno (ovvero attachmentsList non esiste o non ha elementi)\r\n -->\r\n <input\r\n #fileInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <button\r\n class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n *ngIf=\"\r\n allowedTypes &&\r\n allowedTypes.length == 1 &&\r\n (multipleAttachment == true ||\r\n !attachmentsList ||\r\n attachmentsList.length == 0 ||\r\n (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \"\r\n (click)=\"addFile(allowedTypes[0], fileInput)\"\r\n [disabled]=\"isDisabled\">\r\n <!-- Per l'aggiunta dei file mostro un'icona diversa dall'aggiunta dei link -->\r\n <mat-icon *ngIf=\"allowedTypes[0] == 1\">cloud_upload</mat-icon>\r\n <i class=\"fas fa-link\" *ngIf=\"allowedTypes[0] == 2\"></i>\r\n <i class=\"fa-brands fa-dropbox\" *ngIf=\"allowedTypes[0] == 3\"></i>\r\n <span style=\"margin-left: 10px\">\r\n {{\r\n allowedTypes[0] == 1\r\n ? addButtonLabel + \" file\"\r\n : allowedTypes[0] == 2\r\n ? addButtonLabel + \" link\"\r\n : uploadWithDropboxLabel\r\n }}</span\r\n >\r\n </button>\r\n\r\n <!-- Pulsante per aprire il menu per la scelta del tipo di Attachment da creare -->\r\n <button\r\n class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\"\r\n [disabled]=\"isDisabled\"\r\n *ngIf=\"\r\n !separatedUploadButtons &&\r\n allowedTypes &&\r\n allowedTypes.length > 1 &&\r\n (multipleAttachment == true ||\r\n !attachmentsList ||\r\n attachmentsList.length == 0 ||\r\n (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \">\r\n <mat-icon *ngIf=\"multipleAttachment != true\">cloud_upload</mat-icon>\r\n <mat-icon *ngIf=\"multipleAttachment == true\">add</mat-icon>\r\n <span style=\"margin-left: 0px\"> {{ addButtonLabel }} </span>\r\n </button>\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <input\r\n #imageInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n mat-menu-item\r\n (click)=\"imageInput.click()\"\r\n class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n mat-menu-item\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n mat-menu-item\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n\r\n <div\r\n *ngIf=\"\r\n separatedUploadButtons &&\r\n allowedTypes &&\r\n allowedTypes.length > 1 &&\r\n (multipleAttachment == true ||\r\n !attachmentsList ||\r\n attachmentsList.length == 0 ||\r\n (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \">\r\n <div class=\"btn-group\">\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n (click)=\"imageInput.click()\"\r\n class=\"btn btn-secondary eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"secondary\"\r\n type=\"button\">\r\n <i class=\"fa-solid fa-cloud-upload\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <input\r\n #imageInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"btn btn-secondary eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"secondary\"\r\n type=\"button\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"btn btn-secondary eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"secondary\"\r\n type=\"button\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #croppieTemplate>\r\n <div class=\"row m-3\">\r\n <h4>{{ cropLabel }}</h4>\r\n </div>\r\n <div class=\"row m-2 crop-large\">\r\n <div class=\"col-md-12 d-flex align-items-center justify-content-center\">\r\n <button\r\n [matTooltip]=\"rotateLeftLabel\"\r\n *ngIf=\"cropOptions.includes(1)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"rotateLeft()\">\r\n <mat-icon style=\"vertical-align: middle\">rotate_left</mat-icon>\r\n </button>\r\n <button\r\n [matTooltip]=\"rotateRightLabel\"\r\n *ngIf=\"cropOptions.includes(1)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"rotateRight()\">\r\n <mat-icon style=\"vertical-align: middle\">rotate_right</mat-icon>\r\n </button>\r\n <button\r\n [matTooltip]=\"flipHorinzontalLabel\"\r\n *ngIf=\"cropOptions.includes(2)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"flipHorizontal()\">\r\n <mat-icon style=\"vertical-align: middle\">flip_horizontal</mat-icon>\r\n </button>\r\n <button\r\n [matTooltip]=\"flipVerticalLabel\"\r\n *ngIf=\"cropOptions.includes(2)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"flipVertical()\">\r\n <div style=\"transform: rotate(90deg)\"><mat-icon style=\"vertical-align: middle\">flip_vertical</mat-icon></div>\r\n </button>\r\n <button\r\n [matTooltip]=\"'Reset'\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"restoreOriginalDimensions()\">\r\n <mat-icon style=\"vertical-align: middle\">replay</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"row m-2 crop-small\">\r\n <div class=\"col-md-12 d-flex align-items-center justify-content-center\">\r\n <mat-icon *ngIf=\"cropOptions.includes(1)\" style=\"font-size: 27px; vertical-align: middle\" (click)=\"rotateLeft()\"\r\n >rotate_left</mat-icon\r\n >\r\n <mat-icon\r\n class=\"ms-3\"\r\n *ngIf=\"cropOptions.includes(1)\"\r\n style=\"font-size: 27px; vertical-align: middle\"\r\n (click)=\"rotateRight()\"\r\n >rotate_right</mat-icon\r\n >\r\n <mat-icon\r\n class=\"ms-3\"\r\n *ngIf=\"cropOptions.includes(2)\"\r\n style=\"font-size: 27px; vertical-align: middle\"\r\n (click)=\"flipHorizontal()\"\r\n >flip_horizontal</mat-icon\r\n >\r\n <div class=\"ms-3\" style=\"transform: rotate(90deg)\">\r\n <mat-icon\r\n *ngIf=\"cropOptions.includes(2)\"\r\n style=\"font-size: 27px; vertical-align: middle\"\r\n (click)=\"flipVertical()\"\r\n >flip_vertical</mat-icon\r\n >\r\n </div>\r\n <mat-icon class=\"ms-3\" (click)=\"restoreOriginalDimensions()\" style=\"font-size: 27px; vertical-align: middle\"\r\n >replay</mat-icon\r\n >\r\n </div>\r\n </div>\r\n <div class=\"row justify-content-center\">\r\n <div class=\"col-12 d-flex align-items-center justify-content-center\">\r\n <div class=\"crop-container\">\r\n <image-cropper\r\n [imageFile]=\"selectedFile\"\r\n [maintainAspectRatio]=\"false\"\r\n [autoCrop]=\"false\"\r\n [containWithinAspectRatio]=\"false\"\r\n [aspectRatio]=\"4 / 3\"\r\n [cropperMinWidth]=\"128\"\r\n [onlyScaleDown]=\"true\"\r\n [roundCropper]=\"false\"\r\n [canvasRotation]=\"0\"\r\n [transform]=\"transform\"\r\n [alignImage]=\"'left'\"\r\n format=\"png\"\r\n (imageCropped)=\"imageCropped($event)\"\r\n [resizeToWidth]=\"customWidth\"\r\n [resizeToHeight]=\"customHeight\"\r\n [canvasRotation]=\"canvasRotation\">\r\n </image-cropper>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row justify-content-center mt-2 mb-2 crop-large\">\r\n <div class=\"col-12 d-flex align-items-center justify-content-center\">\r\n <button\r\n class=\"btn btn-primary mat-raised-button eqp-attachments-confirm-btn me-2\"\r\n type=\"button\"\r\n (click)=\"confirmAddAttachment()\">\r\n {{ confirmLabel }}\r\n </button>\r\n <button class=\"btn mat-raised-button eqp-attachments-abort-btn\" type=\"button\" (click)=\"abortFile()\">\r\n {{ abortLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"row justify-content-center mt-2 mb-2 crop-small\">\r\n <div class=\"col-6 d-flex align-items-center justify-content-center\" style=\"font-size: 20px\">\r\n <i class=\"fa fa-times\" (click)=\"abortFile()\"></i>\r\n </div>\r\n <div class=\"col-6 d-flex align-items-center justify-content-center\" style=\"font-size: 20px\">\r\n <i class=\"fa fa-check\" (click)=\"confirmAddAttachment()\"></i>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- TEMPLATE PER FORM DI AGGIUNTA DI UN LINK -->\r\n<ng-template #addingLinkTemplate>\r\n <span class=\"mb-1\" style=\"font-size: 20px\"><i class=\"fa fa-link\"></i>Inserisci l'URL</span>\r\n <form [formGroup]=\"newAttachmentForm\" *ngIf=\"newAttachmentForm\">\r\n <div class=\"row mb-2\" style=\"height: 80px\">\r\n <div class=\"col-6 d-grid gap-2 mx-auto\">\r\n <div class=\"input-group mb-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"{{ fileNameLabel }}\"\r\n formControlName=\"name\"\r\n [(ngModel)]=\"newAttachment.FileName\" />\r\n </div>\r\n </div>\r\n <div class=\"col-12 d-grid gap-2\">\r\n <div class=\"input-group\">\r\n <input\r\n required\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Link\"\r\n formControlName=\"path\"\r\n [(ngModel)]=\"newAttachment.FilePath\" />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-6 d-grid gap-2\">\r\n <button\r\n class=\"btn btn-secondary mat-raised-button\"\r\n (click)=\"selectedAttachment = null; addingLinkMode = false\"\r\n type=\"button\">\r\n {{ exitLabel }}\r\n </button>\r\n </div>\r\n <div class=\"col-6 d-grid gap-2\">\r\n <button\r\n class=\"btn btn-primary mat-raised-button\"\r\n type=\"submit\"\r\n (click)=\"confirmAddAttachment(); selectedAttachment = null; addingLinkMode = false\">\r\n {{ saveLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n </form>\r\n</ng-template>\r\n", styles: ["ngx-file-drop ::ng-deep .ngx-file-drop__drop-zone{min-height:30vh;border-radius:5px!important;background-color:#e4e6ea!important;cursor:pointer;font-size:17px!important;border:dotted!important;padding-top:7vh}ngx-file-drop ::ng-deep .ngx-file-drop__drop-zone .ngx-file-drop__content{display:flex;flex-direction:column;align-items:center;justify-content:center;color:#73777a!important;margin:auto}.custom-height .mat-form-field-wrapper{height:20px}.eqp-attachments-header-title{font-weight:700;font-size:19px;line-height:24px;margin-bottom:auto}.single-attachment-inline-preview-container{max-height:400px;max-width:400px;display:flex;align-items:center}.single-attachment-inline-preview-container img{max-width:100%;max-height:120px}.inline-preview-container{max-height:100px;max-width:100px;display:flex;align-items:center;justify-content:center;width:100%;cursor:pointer}.inline-preview-container img{max-width:100%;max-height:100px}.inline-preview-container i{font-size:25px;margin:auto}.preview-container{max-height:60vh;max-width:100%}.preview-container .image-preview{max-width:100%;max-height:100%}.preview-container .link-preview{width:70vw;height:55vh}.closeButton{float:right}@media (max-width: 768px){.crop-large{display:none}}@media (min-width: 768px){.crop-small{display:none}}@media (max-width: 768px){.crop-container{max-width:55%}}@media (min-width: 768px){.crop-container{max-width:35%}}\n"], dependencies: [{ kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i10.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i13.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i13.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i13.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i14.ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "cropperFrameAriaLabel", "output", "format", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "autoCrop", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "cropper", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange"] }, { kind: "component", type: i15.EqpTableComponent, selector: "eqp-table" }, { kind: "component", type: i16.NgxFileDropComponent, selector: "ngx-file-drop", inputs: ["accept", "directory", "multiple", "dropZoneLabel", "dropZoneClassName", "useDragEnter", "contentClassName", "showBrowseBtn", "browseBtnClassName", "browseBtnLabel", "disabled"], outputs: ["onFileDrop", "onFileOver", "onFileLeave"] }, { kind: "directive", type: i16.NgxFileDropContentTemplateDirective, selector: "[ngx-file-drop-content-tmp]" }] });
1023
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EqpAttachmentsComponent, selector: "eqp-attachments", inputs: { disableAction: "disableAction", showHeader: "showHeader", headerTitle: "headerTitle", attachmentsList: "attachmentsList", singleAttachment: "singleAttachment", showMatCard: "showMatCard", multipleAttachment: "multipleAttachment", loadMultipleFiles: "loadMultipleFiles", emptyTableMessage: "emptyTableMessage", allowOnlyImages: "allowOnlyImages", acceptedFileTypes: "acceptedFileTypes", isDisabled: "isDisabled", showInlinePreview: "showInlinePreview", getAttachmentEndpoint: "getAttachmentEndpoint", productionBaseUrl: "productionBaseUrl", compressionOptions: "compressionOptions", allowedTypes: "allowedTypes", isEqpTableMultiLanguage: "isEqpTableMultiLanguage", tablePaginatorVisible: "tablePaginatorVisible", isTableSearcheable: "isTableSearcheable", tablePaginatorSize: "tablePaginatorSize", separatedUploadButtons: "separatedUploadButtons", showPreview: "showPreview", singleAttachmentDragAndDrop: "singleAttachmentDragAndDrop", cropOptions: "cropOptions", cropDialogClass: "cropDialogClass", maxFileSizeMB: "maxFileSizeMB", cardSize: "cardSize", customCardWidthPx: "customCardWidthPx", customCardHeightPx: "customCardHeightPx", openLinkLabel: "openLinkLabel", addButtonLabel: "addButtonLabel", downloadLabel: "downloadLabel", deleteLabel: "deleteLabel", fileNameLabel: "fileNameLabel", previewLabel: "previewLabel", uploadFileLabel: "uploadFileLabel", confirmLabel: "confirmLabel", abortLabel: "abortLabel", saveLabel: "saveLabel", exitLabel: "exitLabel", uploadWithDropboxLabel: "uploadWithDropboxLabel", cropLabel: "cropLabel", deleteDialogTitle: "deleteDialogTitle", deleteDialogMessage: "deleteDialogMessage", noImageSelectedErrorMessage: "noImageSelectedErrorMessage", wrongTypeSelectedErrorMessage: "wrongTypeSelectedErrorMessage", videoPreviewErrorMessage: "videoPreviewErrorMessage", audioPreviewErrorMessage: ["videoPreviewErrorMessage", "audioPreviewErrorMessage"], flipHorinzontalLabel: "flipHorinzontalLabel", flipVerticalLabel: "flipVerticalLabel", rotateRightLabel: "rotateRightLabel", rotateLeftLabel: "rotateLeftLabel", uploadTitle: "uploadTitle", uploadSubtitle: "uploadSubtitle", dropHereLabel: "dropHereLabel", supportedFormatsLabel: "supportedFormatsLabel", browseFilesLabel: "browseFilesLabel", uploadSummaryLabel: "uploadSummaryLabel", filesLabel: "filesLabel", totalSizeLabel: "totalSizeLabel", emptyStateLabel: "emptyStateLabel", addedSuccessfullyLabel: "addedSuccessfullyLabel", removedLabel: "removedLabel", chooseView: "chooseView", showSummary: "showSummary", viewMode: "viewMode" }, outputs: { localEditedAttachments: "localEditedAttachments", abortAddAttachment: "abortAddAttachment", downloadAttachment: "downloadAttachment", onDeleteAttachment: "onDeleteAttachment" }, viewQueries: [{ propertyName: "dialogAddAttachment", first: true, predicate: ["dialogAddAttachment"], descendants: true, static: true }, { propertyName: "dialogAddMultipleAttachment", first: true, predicate: ["dialogAddMultipleAttachment"], descendants: true, static: true }, { propertyName: "dialogCropImage", first: true, predicate: ["dialogCropImage"], descendants: true, static: true }, { propertyName: "addingLinkTemplate", first: true, predicate: ["addingLinkTemplate"], descendants: true }, { propertyName: "imageCropper", first: true, predicate: ImageCropperComponent, descendants: true }, { propertyName: "imageInput", first: true, predicate: ["imageInput"], descendants: true }, { propertyName: "inlinePreviewTemplate", first: true, predicate: ["inlinePreviewTemplate"], descendants: true, static: true }, { propertyName: "dialogPreview", first: true, predicate: ["dialogPreview"], descendants: true, static: true }], ngImport: i0, template: "<!-- Se richiesta la gestione singola mostra il pulsante di caricamento di un singolo file -->\r\n<div class=\"header\">\r\n <h1>{{ uploadTitle }}</h1>\r\n @if(chooseView == true){\r\n <mat-button-toggle-group [value]=\"viewMode\" (change)=\"setViewMode($event.value)\"\r\n aria-label=\"Modalit\u00E0 di visualizzazione\">\r\n <mat-button-toggle value=\"card\"><mat-icon>grid_view</mat-icon></mat-button-toggle>\r\n <mat-button-toggle value=\"table\"><mat-icon>view_list</mat-icon></mat-button-toggle>\r\n </mat-button-toggle-group>\r\n }\r\n</div>\r\n\r\n<!-- Gestione singolo -->\r\n@if (multipleAttachment != true) {\r\n@if (!singleAttachmentDragAndDrop) {\r\n@if (!addingLinkMode) {\r\n<div class=\"text-center\">\r\n <ng-container [ngTemplateOutlet]=\"addAttachmentButton\"></ng-container>\r\n</div>\r\n} @else {\r\n<div class=\"text-center\">\r\n <ng-container [ngTemplateOutlet]=\"addingLinkTemplate\"></ng-container>\r\n</div>\r\n}\r\n} @else {\r\n<input #fileInput id=\"file_attachment\" name=\"file_attachment\" type=\"file\" hidden (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n\r\n@if (allowedTypes && allowedTypes.includes(1) && (!attachmentsList || attachmentsList.length == 0 ||\r\n(attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n<div class=\"dropbox\" [class.dragover]=\"dragOver\" (dragover)=\"dragOver = true; $event.preventDefault()\"\r\n (dragleave)=\"dragOver = false\" (drop)=\"dragOver = false; fileDropped($event)\"\r\n (click)=\"onSelectFile($event, fileInput)\" role=\"button\" tabindex=\"0\" (keydown.enter)=\"fileInput.click()\"\r\n (keydown.space)=\"fileInput.click()\">\r\n <div class=\"dropbox-icon\">\uD83D\uDCC1</div>\r\n <div class=\"dropbox-text\">{{ dropHereLabel }}</div>\r\n <div class=\"dropbox-subtext\">\r\n {{ supportedFormatsLabel }}\r\n </div>\r\n <button class=\"browse-btn\" type=\"button\" (click)=\"$event.stopPropagation(); fileInput.click()\">\r\n {{ browseFilesLabel }}\r\n </button>\r\n <div class=\"secondary-action\">\r\n @if (allowedTypes.includes(2) || allowedTypes.includes(3)) {\r\n @if (allowedTypes.includes(2) && allowedTypes.includes(3)) {\r\n <a class=\"secondary-action-link\" [matMenuTriggerFor]=\"linkMenu\" (click)=\"$event.stopPropagation()\">\r\n o aggiungi da web\r\n </a>\r\n <mat-menu #linkMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"switchToAddingLinkMode()\">\r\n <mat-icon>link</mat-icon>\r\n <span>Aggiungi da link</span>\r\n </button>\r\n <button mat-menu-item (click)=\"chooseDropboxFile()\">\r\n <mat-icon>cloud_queue</mat-icon>\r\n <span>Carica da Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n }\r\n\r\n @else if (allowedTypes.includes(2)) {\r\n <a class=\"secondary-action-link\" (click)=\"$event.stopPropagation(); switchToAddingLinkMode()\">\r\n aggiungi un link\r\n </a>\r\n }\r\n\r\n @else if (allowedTypes.includes(3)) {\r\n <a class=\"secondary-action-link\" (click)=\"$event.stopPropagation(); chooseDropboxFile()\">\r\n carica da Dropbox\r\n </a>\r\n }\r\n }\r\n </div>\r\n</div>\r\n}\r\n}\r\n\r\n<!-- Azioni singolo elemento (come prima) -->\r\n<div class=\"text-center\">\r\n @if (attachmentsList && attachmentsList.length > 0 && attachmentsList[0]) {\r\n <button class=\"mb-2 me-2 eqp-attachments-download-btn\" (click)=\"viewAttachment(attachmentsList[0])\" type=\"button\"\r\n mat-raised-button color=\"primary\">\r\n @if (attachmentsList[0].AttachmentType == AttachmentType.FILE) {\r\n <mat-icon>download</mat-icon>\r\n } @else {\r\n <mat-icon>open_in_new</mat-icon>\r\n }\r\n {{ attachmentsList[0].AttachmentType == AttachmentType.FILE ? downloadLabel : openLinkLabel }}\r\n </button>\r\n\r\n @if (showPreview && (!attachmentsList[0].FileContentType || (!attachmentsList[0].FileContentType.startsWith('video')\r\n && !attachmentsList[0].FileContentType.startsWith('audio'))) && attachmentsList[0].IsImage == true) {\r\n <button class=\"mb-2 me-2 eqp-attachments-preview-btn\" (click)=\"openPreviewDialog(attachmentsList[0])\" type=\"button\"\r\n mat-raised-button color=\"primary\">\r\n <mat-icon>visibility</mat-icon> {{ previewLabel }}\r\n </button>\r\n }\r\n\r\n <button [disabled]=\"disableAction\" class=\"mb-2 eqp-attachments-delete-btn\"\r\n (click)=\"deleteAttachment(attachmentsList[0])\" type=\"button\" mat-raised-button [disabled]=\"isDisabled\">\r\n <mat-icon>delete</mat-icon> {{ deleteLabel }}\r\n </button>\r\n }\r\n</div>\r\n}\r\n\r\n<!-- Gestione multipla -->\r\n@if (multipleAttachment == true) {\r\n<input #fileInput id=\"file_attachment_multi\" name=\"file_attachment_multi\" type=\"file\" hidden\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n\r\n<div class=\"dropbox\" [class.dragover]=\"dragOver\" (dragover)=\"dragOver = true; $event.preventDefault()\"\r\n (dragleave)=\"dragOver = false\" (drop)=\"dragOver = false; fileDropped($event)\"\r\n (click)=\"onSelectFile($event, fileInput)\" role=\"button\" tabindex=\"0\" (keydown.enter)=\"fileInput.click()\"\r\n (keydown.space)=\"fileInput.click()\">\r\n <div class=\"dropbox-icon\">\uD83D\uDCC1</div>\r\n <div class=\"dropbox-text\">{{ dropHereLabel }}</div>\r\n <div class=\"dropbox-subtext\">\r\n {{ supportedFormatsLabel }}\r\n </div>\r\n <button class=\"browse-btn\" type=\"button\" (click)=\"$event.stopPropagation(); fileInput.click()\">\r\n {{ browseFilesLabel }}\r\n </button>\r\n <div class=\"secondary-action-link\">\r\n o <a (click)=\"$event.stopPropagation(); switchToAddingLinkMode()\">aggiungi un link</a>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if (attachmentsList?.length > 0 && showSummary) {\r\n<div class=\"upload-stats\">\r\n\r\n <div class=\"stats-info\">\r\n <div class=\"stat-item\">\r\n <div class=\"stat-value\">{{ attachmentsList?.length }}</div>\r\n <div class=\"stat-label\">{{ filesLabel }}</div>\r\n </div>\r\n <div class=\"stat-item\">\r\n <div class=\"stat-value\">{{ totalSizeFormatted }}</div>\r\n <div class=\"stat-label\">{{ totalSizeLabel }}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"progress-bar\">\r\n <div class=\"progress-fill\" [style.width.%]=\"progressPercent\"></div>\r\n </div>\r\n\r\n</div>\r\n} @else if(attachmentsList?.length == 0){\r\n<div class=\"empty-state\">{{ emptyStateLabel }}</div>\r\n}\r\n\r\n<!-- Griglia anteprime card (vale per singolo e multiplo) -->\r\n@if (viewMode === 'card') {\r\n\r\n<div class=\"file-previews\" [ngStyle]=\"getPreviewsContainerStyle()\">\r\n @for (att of attachmentsList; track att.ID) {\r\n <div [ngClass]=\"getCardClass(att)\">\r\n\r\n <div class=\"preview-img-container\" (click)=\"!att.isUploading && openPreviewDialog(att)\">\r\n @if (att.IsImage) {\r\n <img class=\"preview-img\" [src]=\"'data:image/png;base64,' + (att.FileThumbnailBase64 || att.FileDataBase64)\"\r\n [alt]=\"att.FileName\" />\r\n } @else {\r\n <div class=\"file-icon\">\r\n <i [ngClass]=\"getAttachmentIcon(att)\"></i>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"file-info\">\r\n <div class=\"file-name\" [title]=\"att.FileName\">{{ att.FileName }}</div>\r\n </div>\r\n\r\n @if(!disableAction){\r\n <button mat-icon-button class=\"remove-btn\" type=\"button\" aria-label=\"Rimuovi allegato\"\r\n (click)=\"deleteAttachment(att)\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n\r\n @if (att.isUploading) {\r\n <div class=\"upload-spinner\"></div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n} @else {\r\n\r\n<div class=\"table-view-container\">\r\n <div class=\"table-header\">\r\n <div class=\"table-cell name-col\">File</div>\r\n <div class=\"table-cell actions-col\">Azioni</div>\r\n </div>\r\n\r\n @for (att of attachmentsList; track att.ID) {\r\n <div class=\"table-row\">\r\n <div class=\"table-cell name-col\">\r\n <i class=\"file-icon-small\" [ngClass]=\"getAttachmentIcon(att)\"></i>\r\n <div class=\"file-info-text\">\r\n <span class=\"file-name-table\">{{ att.FileName }}</span>\r\n <span class=\"file-type-table\">{{ att.FileExtension || 'Link' }}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"table-cell actions-col\">\r\n <button mat-icon-button (click)=\"viewAttachment(att)\" matTooltip=\"Visualizza/Scarica\">\r\n <mat-icon>{{ att.AttachmentType === attachmentType.FILE ? 'download' : 'open_in_new' }}</mat-icon>\r\n </button>\r\n <button mat-icon-button [matMenuTriggerFor]=\"actionsMenu\" matTooltip=\"Altre opzioni\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #actionsMenu=\"matMenu\">\r\n <button mat-menu-item\r\n (click)=\"openPreviewDialog(att)\"><mat-icon>visibility</mat-icon><span>Anteprima</span></button>\r\n <button [disabled]=\"disableAction\" mat-menu-item (click)=\"deleteAttachment(att)\" matTooltip=\"Elimina\">\r\n <mat-icon color=\"warn\">delete</mat-icon>\r\n <span>Elimina</span>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n}\r\n\r\n<!-- Notifica toast -->\r\n<div class=\"upload-notification\" [class.show]=\"toast?.visible\" [class.success]=\"toast?.type === 'success'\"\r\n [class.error]=\"toast?.type === 'error'\">\r\n <span>{{ toast?.text }}</span>\r\n <div class=\"notification-progress\"></div>\r\n</div>\r\n\r\n\r\n<ng-template #dialogCropImage>\r\n <div style=\"overflow-x: hidden\" [ngClass]=\"cropDialogClass\">\r\n @if (showCropImage == true) {\r\n <ng-container [ngTemplateOutlet]=\"croppieTemplate\" [ngTemplateOutletContext]=\"{ form: newAttachmentForm }\">\r\n </ng-container>\r\n }\r\n </div>\r\n</ng-template>\r\n\r\n\r\n<ng-template #inlinePreviewTemplate let-row=\"row\">\r\n @if (row.AttachmentType != AttachmentType.LINK && row.IsImage) {\r\n <div class=\"inline-preview-container\" (click)=\"openPreviewDialog(row)\">\r\n <img [src]=\"'data:image/png;base64,' + (row.FileThumbnailBase64 ? row.FileThumbnailBase64 : row.FileDataBase64)\" />\r\n </div>\r\n } @else if (row.AttachmentType != AttachmentType.LINK && !row.IsImage) {\r\n <div class=\"inline-preview-container\" (click)=\"openPreviewDialog(row)\">\r\n <i [ngClass]=\"getAttachmentIcon(row)\"></i>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n\r\n<ng-template #dialogPreview>\r\n @if (selectedAttachment) {\r\n <h2 mat-dialog-title class=\"dialog-header\">\r\n <span>\r\n {{ previewLabel }} {{ selectedAttachment!.AttachmentType === attachmentType.FILE ? \"File\" : \"Link\" }}\r\n </span>\r\n <button mat-icon-button mat-dialog-close aria-label=\"Chiudi anteprima\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </h2>\r\n\r\n <mat-dialog-content class=\"dialog-content\">\r\n @if (selectedAttachment!.IsImage) {\r\n <img class=\"preview-image\"\r\n [src]=\"'data:image/png;base64,' + (selectedAttachment!.FileDataBase64 || selectedAttachment!.FileThumbnailBase64)\"\r\n alt=\"Anteprima allegato\" />\r\n } @else {\r\n <iframe class=\"preview-iframe\" [src]=\"selectedAttachment!.TrustedUrl\" [title]=\"selectedAttachment!.FileName\">\r\n </iframe>\r\n }\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions [align]=\"'center'\">\r\n @if (selectedAttachment!.AttachmentType !== AttachmentType.LINK) {\r\n <button mat-raised-button color=\"primary\" (click)=\"viewAttachment(selectedAttachment!)\">\r\n <mat-icon>download</mat-icon>\r\n <span>{{ downloadLabel }}</span>\r\n </button>\r\n }\r\n </mat-dialog-actions>\r\n }\r\n</ng-template>\r\n\r\n\r\n<!-- TEMPLATE PER IL PULSANTE DI AGGIUNTA NUOVO ALLEGATO -->\r\n<ng-template #addAttachmentButton>\r\n <input #fileInput style=\"display: none\" id=\"file_attachment\" name=\"file_attachment\" type=\"file\"\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n\r\n @if (allowedTypes && allowedTypes.length == 1 && (multipleAttachment == true || !attachmentsList ||\r\n attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n <button class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\" mat-raised-button color=\"primary\" type=\"button\"\r\n (click)=\"addFile(allowedTypes[0], fileInput)\" [disabled]=\"isDisabled\">\r\n @if (allowedTypes[0] == 1) { <mat-icon>cloud_upload</mat-icon> }\r\n @if (allowedTypes[0] == 2) { <i class=\"fas fa-link\"></i> }\r\n @if (allowedTypes[0] == 3) { <i class=\"fa-brands fa-dropbox\"></i> }\r\n <span style=\"margin-left: 10px\">\r\n {{ allowedTypes[0] == 1 ? (addButtonLabel + \" file\") : allowedTypes[0] == 2 ? (addButtonLabel + \" link\") :\r\n uploadWithDropboxLabel }}\r\n </span>\r\n </button>\r\n }\r\n\r\n @if (!separatedUploadButtons && allowedTypes && allowedTypes.length > 1 && (multipleAttachment == true ||\r\n !attachmentsList || attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n <button class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\" mat-raised-button color=\"primary\" type=\"button\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\" [disabled]=\"isDisabled\">\r\n @if (multipleAttachment != true) { <mat-icon>cloud_upload</mat-icon> } @else { <mat-icon>add</mat-icon> }\r\n <span style=\"margin-left: 0px\">{{ addButtonLabel }}</span>\r\n </button>\r\n\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <input #imageInput style=\"display: none\" id=\"file_attachment\" name=\"file_attachment\" type=\"file\"\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n @if (allowedTypes.includes(1)) {\r\n <button mat-menu-item (click)=\"imageInput.click()\" class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n }\r\n @if (allowedTypes.includes(2)) {\r\n <button mat-menu-item (click)=\"switchToAddingLinkMode()\" class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n }\r\n @if (allowedTypes.includes(3)) {\r\n <button mat-menu-item (click)=\"chooseDropboxFile()\" class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n }\r\n </mat-menu>\r\n }\r\n\r\n @if (separatedUploadButtons && allowedTypes && allowedTypes.length > 1 && (multipleAttachment == true ||\r\n !attachmentsList || attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n <div class=\"btn-group\">\r\n @if (allowedTypes.includes(1)) {\r\n <button (click)=\"imageInput.click()\" class=\"btn btn-secondary eqp-attachments-add-btn\" mat-raised-button\r\n color=\"secondary\" type=\"button\">\r\n <i class=\"fa-solid fa-cloud-upload\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n }\r\n <input #imageInput style=\"display: none\" id=\"file_attachment\" name=\"file_attachment\" type=\"file\"\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n @if (allowedTypes.includes(2)) {\r\n <button (click)=\"switchToAddingLinkMode()\" class=\"btn btn-secondary eqp-attachments-add-btn\" mat-raised-button\r\n color=\"secondary\" type=\"button\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n }\r\n @if (allowedTypes.includes(3)) {\r\n <button (click)=\"chooseDropboxFile()\" class=\"btn btn-secondary eqp-attachments-add-btn\" mat-raised-button\r\n color=\"secondary\" type=\"button\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n\r\n<ng-template #croppieTemplate>\r\n <!-- Header compatto -->\r\n <h2 class=\"dialog-header m-3\">\r\n <span>{{ cropLabel }}</span>\r\n <button mat-icon-button type=\"button\" aria-label=\"Chiudi\" (click)=\"abortFile()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </h2>\r\n\r\n <!-- Contenuto scrollabile con griglia responsive -->\r\n <div class=\"dialog-content\">\r\n <!-- Toolbar controlli (large) -->\r\n <div class=\"controls-row crop-large\">\r\n @if (cropOptions.includes(1)) {\r\n <button [matTooltip]=\"rotateLeftLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"rotateLeft()\">\r\n <mat-icon>rotate_left</mat-icon>\r\n </button>\r\n <button [matTooltip]=\"rotateRightLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"rotateRight()\">\r\n <mat-icon>rotate_right</mat-icon>\r\n </button>\r\n }\r\n @if (cropOptions.includes(2)) {\r\n <button [matTooltip]=\"flipHorinzontalLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"flipHorizontal()\">\r\n <mat-icon>flip_horizontal</mat-icon>\r\n </button>\r\n <button [matTooltip]=\"flipVerticalLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"flipVertical()\">\r\n <mat-icon>flip_vertical</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Reset'\" class=\"btn btn-primary mat-raised-button\" (click)=\"restoreOriginalDimensions()\">\r\n <mat-icon>replay</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Toolbar controlli (small) -->\r\n <div class=\"controls-row crop-small\">\r\n @if (cropOptions.includes(1)) {\r\n <mat-icon class=\"control-icon\" (click)=\"rotateLeft()\">rotate_left</mat-icon>\r\n <mat-icon class=\"control-icon\" (click)=\"rotateRight()\">rotate_right</mat-icon>\r\n }\r\n @if (cropOptions.includes(2)) {\r\n <mat-icon class=\"control-icon\" (click)=\"flipHorizontal()\">flip_horizontal</mat-icon>\r\n <mat-icon class=\"control-icon\" (click)=\"flipVertical()\">flip_vertical</mat-icon>\r\n }\r\n <mat-icon class=\"control-icon\" (click)=\"restoreOriginalDimensions()\">replay</mat-icon>\r\n </div>\r\n\r\n <!-- Area crop con contenimento -->\r\n <div class=\"crop-area\">\r\n <div class=\"crop-container\">\r\n <image-cropper [imageFile]=\"selectedFile\" [maintainAspectRatio]=\"false\" [autoCrop]=\"false\"\r\n [containWithinAspectRatio]=\"false\" [aspectRatio]=\"4 / 3\" [cropperMinWidth]=\"128\" [onlyScaleDown]=\"true\"\r\n [roundCropper]=\"false\" [canvasRotation]=\"0\" [transform]=\"transform\" [alignImage]=\"'left'\" format=\"png\"\r\n (imageCropped)=\"imageCropped($event)\" [resizeToWidth]=\"customWidth\" [resizeToHeight]=\"customHeight\"\r\n [canvasRotation]=\"canvasRotation\" [output]=\"'base64'\">\r\n </image-cropper>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Azioni -->\r\n <div class=\"dialog-actions crop-large\">\r\n <button class=\"btn btn-primary mat-raised-button eqp-attachments-confirm-btn\" type=\"button\"\r\n (click)=\"confirmAddAttachment()\">\r\n {{ confirmLabel }}\r\n </button>\r\n <button class=\"btn mat-raised-button eqp-attachments-abort-btn\" type=\"button\" (click)=\"abortFile()\">\r\n {{ abortLabel }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"dialog-actions crop-small\">\r\n <button class=\"icon-action\" type=\"button\" (click)=\"abortFile()\" aria-label=\"Abort\">\r\n <i class=\"fa fa-times\"></i>\r\n </button>\r\n <button class=\"icon-action\" type=\"button\" (click)=\"confirmAddAttachment()\" aria-label=\"Confirm\">\r\n <i class=\"fa fa-check\"></i>\r\n </button>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- TEMPLATE PER FORM DI AGGIUNTA DI UN LINK -->\r\n<ng-template #addingLinkTemplate>\r\n <h2 mat-dialog-title>Aggiungi un link</h2>\r\n <mat-dialog-content class=\"add-link-dialog-content\">\r\n <form [formGroup]=\"newAttachmentForm\" class=\"add-link-form\">\r\n <mat-form-field appearance=\"outline\">\r\n <mat-label>URL *</mat-label>\r\n <input matInput formControlName=\"filePath\" placeholder=\"https://...\" required>\r\n @if (newAttachmentForm.get('filePath')?.hasError('pattern')) {\r\n <mat-error>L'URL non sembra valido.</mat-error>\r\n }\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\">\r\n <mat-label>Nome (opzionale)</mat-label>\r\n <input matInput formControlName=\"fileName\" placeholder=\"Es. Documento Progetto\">\r\n </mat-form-field>\r\n </form>\r\n </mat-dialog-content>\r\n <mat-dialog-actions align=\"end\">\r\n <button mat-button mat-dialog-close>Annulla</button>\r\n <button mat-raised-button color=\"primary\" [mat-dialog-close]=\"newAttachmentForm.value\"\r\n [disabled]=\"newAttachmentForm.invalid\">\r\n Aggiungi\r\n </button>\r\n </mat-dialog-actions>\r\n</ng-template>", styles: [":host{--primary-color: #6a5af9;--primary-color-dark: #5441f8;--success-color: #1ce593;--error-color: #ff5b5b;--background-light: #f7f9fc;--background-card: rgba(255, 255, 255, .7);--text-color: #1e293b;--text-color-light: #64748b;--border-color: rgba(203, 213, 225, .5);--shadow-color: rgba(99, 102, 241, .2);--border-radius: 16px;--transition-speed: .3s}@keyframes fadeIn{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--primary-color)}70%{box-shadow:0 0 0 10px #6a5af900}to{box-shadow:0 0 #6a5af900}}.container{width:100%;max-width:700px;margin:2rem auto;font-family:Inter,sans-serif}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:2rem;padding-bottom:1.5rem;border-bottom:1px solid var(--border-color)}.header h1{color:var(--text-color);font-size:1.8rem;font-weight:700;margin:0}.dropbox{width:100%;border:2px dashed var(--border-color);border-radius:var(--border-radius);padding:2.5rem;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;cursor:pointer;background-color:var(--background-card);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:all var(--transition-speed) ease}.dropbox:hover{transform:translateY(-5px);box-shadow:0 10px 25px var(--shadow-color);border-color:var(--primary-color)}.dropbox.dragover{border-style:solid;border-color:var(--primary-color);transform:scale(1.02);box-shadow:0 0 25px var(--shadow-color);animation:pulse 1.5s infinite}.dropbox .dropbox-icon{font-size:3.5rem;color:var(--primary-color)}.dropbox .dropbox-text{font-size:1.1rem;font-weight:600;color:var(--text-color);margin-top:1rem}.dropbox .dropbox-subtext{color:var(--text-color-light);margin-top:.5rem}.dropbox .browse-btn{margin-top:1.5rem;padding:.75rem 1.5rem;background-color:var(--primary-color);color:#fff;border:none;border-radius:10px;font-weight:600;transition:all var(--transition-speed) ease}.dropbox .browse-btn:hover{background-color:var(--primary-color-dark);transform:translateY(-2px)}.file-previews{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:1.5rem;margin-top:2rem}.file-previews{display:grid;gap:16px;padding:16px;grid-template-columns:repeat(auto-fill,minmax(var(--card-min-width, 200px),1fr))}.file-preview{background-color:var(--background-card);border-radius:var(--border-radius);box-shadow:0 4px 15px #0000000d;border:1px solid var(--border-color);overflow:hidden;display:flex;flex-direction:column;position:relative;opacity:0;animation:fadeIn .5s ease-out forwards;transition:transform var(--transition-speed) ease,box-shadow var(--transition-speed) ease}.file-preview.uploading{cursor:wait}.file-preview.uploading .preview-img-container:after{content:\"\";position:absolute;inset:0;background:#ffffffb3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);pointer-events:none}.file-preview .remove-btn{position:absolute;top:8px;right:8px;z-index:2;background-color:#0000004d;color:#fff;width:32px;height:32px;display:flex;align-items:center;justify-content:center;padding:0;transition:all var(--transition-speed) ease}.file-preview .remove-btn:hover{background-color:#ff5b5b}.file-preview .remove-btn .mat-icon{font-size:18px}@media (hover: hover) and (min-width: 769px){.file-preview .remove-btn{opacity:0;transform:scale(.8)}.file-preview:hover{transform:translateY(-5px);box-shadow:0 10px 25px var(--shadow-color)}.file-preview:hover .remove-btn{opacity:1;transform:scale(1)}}.file-preview .preview-img-container{aspect-ratio:4/3;display:flex;align-items:center;justify-content:center;position:relative;cursor:pointer;background-color:#f0f2f5}.file-preview .preview-img{width:100%;height:100%;object-fit:cover}.file-preview .file-icon{font-size:4rem;color:var(--primary-color)}.file-preview .file-info{padding:12px;border-top:1px solid var(--border-color);flex-grow:1;display:flex;align-items:center}.file-preview .file-name{font-weight:600;font-size:.9rem;color:var(--text-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-preview .upload-spinner{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:40px;height:40px;border:4px solid rgba(0,0,0,.1);border-left-color:var(--primary-color);border-radius:50%;animation:spin 1s linear infinite;pointer-events:none}.file-preview.card-small{width:140px}.file-preview.card-small .preview-img-container{height:80px}.file-preview.card-small .file-info{padding:8px}.file-preview.card-small .file-name{font-size:.8rem}.file-preview.card-small .file-icon{font-size:3rem}.file-preview.card-small .remove-btn{width:28px;height:28px}.file-preview.card-small .remove-btn .mat-icon{font-size:16px}.file-preview.card-large{width:280px}.file-preview.card-large .preview-img-container{height:180px}.file-preview.card-large .file-info{padding:16px}.file-preview.card-large .file-name{font-size:1rem}.file-preview.card-large .file-icon{font-size:5rem}.file-preview.card-large .remove-btn{width:36px;height:36px}.file-preview.card-large .remove-btn .mat-icon{font-size:20px}.file-preview[style*=--eqp-card-width]{width:var(--eqp-card-width)}.file-preview[style*=--eqp-card-width] .preview-img-container{height:calc(var(--eqp-card-width) * .65)}@keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}}.upload-stats{background-color:var(--background-card);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid var(--border-color);border-radius:var(--border-radius);padding:1.5rem;margin-top:2rem;animation:fadeIn .5s ease-out}.upload-stats .stats-info{display:flex;justify-content:space-around}.upload-stats .progress-bar{height:10px;background-color:var(--border-color);border-radius:5px;overflow:hidden;margin-top:1rem}.upload-stats .progress-fill{height:100%;background:linear-gradient(90deg,var(--primary-color),var(--success-color));transition:width var(--transition-speed) ease-out;border-radius:5px}.upload-notification{position:fixed;bottom:20px;left:50%;transform:translate(-50%,100px);padding:1rem 1.5rem;border-radius:var(--border-radius);color:#fff;font-weight:600;box-shadow:0 10px 30px #0003;transition:transform var(--transition-speed) cubic-bezier(.175,.885,.32,1.275)}.upload-notification.show{transform:translate(-50%)}.upload-notification.success{background-color:var(--success-color)}.upload-notification.error{background-color:var(--error-color)}.dialog-header{display:flex;justify-content:space-between;align-items:center;width:100%}.dialog-content{display:flex;justify-content:center;align-items:center;padding:16px 24px;overflow:auto}.preview-image{max-width:100%;max-height:70vh;height:auto;object-fit:contain}.preview-iframe{width:80vw;height:75vh;border:none;max-width:1200px}.dialog-header{display:flex;align-items:center;justify-content:space-between}.dialog-content{display:flex;flex-direction:column;gap:12px;max-height:60vh;overflow:auto;padding:0 16px 8px}.controls-row{display:flex;align-items:center;justify-content:center;gap:8px}.control-icon{font-size:28px;cursor:pointer}.crop-area{display:flex;justify-content:center}.crop-container{width:100%;max-width:720px;aspect-ratio:4/3;border-radius:8px;background:#f9f9f9;overflow:hidden}image-cropper,image-cropper canvas,image-cropper img{max-width:100%!important;max-height:100%!important}.dialog-actions{display:flex;justify-content:center;gap:12px;padding:12px 16px}.crop-large{display:flex}.crop-small{display:none}@media (max-width: 600px){.dialog-content{max-height:55vh}.crop-container{max-width:100%;aspect-ratio:auto}.crop-large{display:none}.crop-small{display:flex;justify-content:center;gap:14px}.control-icon{font-size:24px}}.stats-header{display:flex;justify-content:space-between;align-items:center;width:100%}.table-view-container{margin-top:1.5rem;background-color:var(--background-card);border-radius:var(--border-radius);border:1px solid var(--border-color);overflow:hidden;animation:fadeIn .5s ease-out}.table-header,.table-row{display:flex;align-items:center;padding:0 1rem;transition:background-color var(--transition-speed) ease}.table-header{background-color:#f8f9fa;font-weight:600;color:var(--text-color-light);font-size:.8rem;text-transform:uppercase;border-bottom:2px solid var(--border-color)}.table-row{border-bottom:1px solid var(--border-color)}.table-row:last-child{border-bottom:none}.table-row:hover{background-color:#00000005}.table-cell{padding:1rem .5rem;display:flex;align-items:center;gap:1rem}.name-col{flex:4}.size-col,.date-col{flex:2}.actions-col{flex:1;justify-content:flex-end;min-width:150px}.file-icon-small{font-size:1.5rem;color:var(--primary-color)}.file-info-text{display:flex;flex-direction:column}.file-name-table{font-weight:600;color:var(--text-color)}.file-type-table{font-size:.8rem;color:var(--text-color-light)}@media (max-width: 768px){.date-col{display:none}.name-col{flex:3}.size-col{flex:2}.actions-col{flex:2;min-width:120px}}.secondary-action-link{color:var(--primary-color);text-decoration:none;border-bottom:1px solid var(--primary-color);cursor:pointer;font-weight:500}.secondary-action-link:hover{color:var(--primary-color-dark);border-bottom-color:var(--primary-color-dark)}h2[mat-dialog-title]+mat-dialog-content.add-link-dialog-content{padding-top:20px}mat-dialog-content.add-link-dialog-content{padding-left:24px;padding-right:24px;padding-bottom:20px}.add-link-form{display:flex;flex-direction:column;gap:16px}\n"], dependencies: [{ kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i10.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i10.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i12.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i13.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i13.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i13.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i14.ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }] });
904
1024
  }
905
1025
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EqpAttachmentsComponent, decorators: [{
906
1026
  type: Component,
907
- args: [{ selector: "eqp-attachments", template: "<!-- Se richiesta la gestione singola mostra il pulsante di caricamento di un singolo file -->\r\n<div *ngIf=\"multipleAttachment != true\">\r\n <div *ngIf=\"!singleAttachmentDragAndDrop\">\r\n <!-- Template del button per l'aggiunta di un allegato -->\r\n <div *ngIf=\"!addingLinkMode\" class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"addAttachmentButton\"></ng-container>\r\n </div>\r\n <!-- Template della form per l'aggiunta di un link -->\r\n <div *ngIf=\"addingLinkMode\" class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"addingLinkTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n <div *ngIf=\"singleAttachmentDragAndDrop\">\r\n <input\r\n #fileInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <ngx-file-drop\r\n (onFileDrop)=\"fileDropped($event)\"\r\n (click)=\"onSelectFile($event, fileInput)\"\r\n *ngIf=\"\r\n allowedTypes &&\r\n allowedTypes.includes(1) &&\r\n (!attachmentsList || attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \">\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"!addingLinkMode\">\r\n <i class=\"fa-solid fa-cloud-upload-alt fa-3x mt-3\"></i>\r\n Trascina i file qui\r\n <div class=\"btn-group mt-1\" role=\"group\">\r\n <button type=\"button\" class=\"btn btn-light border-end\" (click)=\"fileInput.click()\">Scegli un file</button>\r\n <div class=\"btn-group\" role=\"group\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-light border-start dropdown-toggle\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\"></button>\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n mat-menu-item\r\n (click)=\"fileInput.click()\"\r\n class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n mat-menu-item\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n mat-menu-item\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"addingLinkMode\">\r\n <ng-container *ngTemplateOutlet=\"addingLinkTemplate\"></ng-container>\r\n </ng-template>\r\n </ngx-file-drop>\r\n </div>\r\n <div class=\"text-center\">\r\n <button\r\n class=\"mb-2 me-2 eqp-attachments-download-btn\"\r\n (click)=\"viewAttachment(attachmentsList[0])\"\r\n type=\"button\"\r\n mat-raised-button\r\n *ngIf=\"attachmentsList && attachmentsList.length > 0 && attachmentsList[0]\"\r\n color=\"primary\">\r\n <mat-icon *ngIf=\"attachmentsList[0].AttachmentType == AttachmentType.FILE\">download</mat-icon>\r\n <mat-icon *ngIf=\"attachmentsList[0].AttachmentType != AttachmentType.FILE\">open_in_new</mat-icon>\r\n {{ attachmentsList[0].AttachmentType == AttachmentType.FILE ? downloadLabel : openLinkLabel }}\r\n </button>\r\n <button\r\n class=\"mb-2 me-2 eqp-attachments-preview-btn\"\r\n (click)=\"openPreviewDialog(attachmentsList[0])\"\r\n type=\"button\"\r\n mat-raised-button\r\n color=\"primary\"\r\n *ngIf=\"\r\n showPreview &&\r\n attachmentsList &&\r\n attachmentsList.length > 0 &&\r\n attachmentsList[0] &&\r\n (!attachmentsList[0].FileContentType ||\r\n (!attachmentsList[0].FileContentType.startsWith('video') &&\r\n !attachmentsList[0].FileContentType.startsWith('audio'))) &&\r\n attachmentsList[0].IsImage == true\r\n \">\r\n <mat-icon>visibility</mat-icon> {{ previewLabel }}\r\n </button>\r\n <button\r\n class=\"mb-2 eqp-attachments-delete-btn\"\r\n (click)=\"deleteAttachment(attachmentsList[0])\"\r\n type=\"button\"\r\n mat-raised-button\r\n *ngIf=\"attachmentsList && attachmentsList.length > 0 && attachmentsList[0]\"\r\n [disabled]=\"isDisabled\">\r\n <mat-icon>delete</mat-icon> {{ deleteLabel }}\r\n </button>\r\n </div>\r\n <div\r\n class=\"row\"\r\n style=\"margin-top: 10px\"\r\n *ngIf=\"\r\n attachmentsList.length > 0 &&\r\n attachmentsList[0] &&\r\n attachmentsList[0].FileDataBase64 &&\r\n attachmentsList[0].IsImage == true\r\n \">\r\n <div class=\"col-sm-12 d-flex justify-content-center\">\r\n <div class=\"single-attachment-inline-preview-container\">\r\n <img src=\"data:image/png;base64,{{ attachmentsList[0].FileDataBase64 }}\" />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\" *ngIf=\"attachmentsList.length > 0 && attachmentsList[0] && attachmentsList[0].IsImage != true\">\r\n <div class=\"col-sm-12\">\r\n <mat-form-field>\r\n <mat-label>{{ fileNameLabel }}</mat-label>\r\n <input readonly matInput [(ngModel)]=\"attachmentsList[0].FileName\" />\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"multipleAttachment == true\">\r\n <input\r\n #fileInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <ngx-file-drop (onFileDrop)=\"fileDropped($event)\" (click)=\"onSelectFile($event, fileInput)\">\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"!addingLinkMode\">\r\n <i class=\"fa-solid fa-cloud-upload-alt fa-3x mt-3\"></i>\r\n Trascina i file qui\r\n <div class=\"btn-group mt-1\" role=\"group\">\r\n <button type=\"button\" class=\"btn btn-light border-end\" (click)=\"fileInput.click()\">Scegli un file</button>\r\n <div class=\"btn-group\" role=\"group\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-light border-start dropdown-toggle\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\"></button>\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n mat-menu-item\r\n (click)=\"fileInput.click()\"\r\n class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n mat-menu-item\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n mat-menu-item\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template ngx-file-drop-content-tmp *ngIf=\"addingLinkMode\">\r\n <ng-container *ngTemplateOutlet=\"addingLinkTemplate\"></ng-container>\r\n </ng-template>\r\n </ngx-file-drop>\r\n <div class=\"mt-2\">\r\n <eqp-table\r\n #attachmentTable\r\n [createMatCard]=\"false\"\r\n #table\r\n [columns]=\"attachmentsColumns\"\r\n [isMultiLanguage]=\"isEqpTableMultiLanguage\"\r\n [data]=\"attachmentsList\"\r\n [paginatorVisible]=\"tablePaginatorVisible\"\r\n [matPaginatorSize]=\"tablePaginatorSize\"\r\n [emptyTableMessage]=\"emptyTableMessage\"\r\n [searchText]=\"eqpTableSearchText\"\r\n [isTableSearcheable]=\"isTableSearcheable\">\r\n </eqp-table>\r\n </div>\r\n</div>\r\n\r\n<ng-template #dialogCropImage>\r\n <!-- Richiama il template per le funzionalit\u00E0 del CROPPIE -->\r\n <div style=\"overflow-x: hidden\" [ngClass]=\"cropDialogClass\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"croppieTemplate\"\r\n [ngTemplateOutletContext]=\"{ form: newAttachmentForm }\"\r\n *ngIf=\"showCropImage == true\"></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #inlinePreviewTemplate let-row=\"row\">\r\n <div\r\n class=\"inline-preview-container\"\r\n *ngIf=\"row.AttachmentType != AttachmentType.LINK && row.IsImage\"\r\n (click)=\"openPreviewDialog(row)\">\r\n <img src=\"data:image/png;base64,{{ row.FileThumbnailBase64 ? row.FileThumbnailBase64 : row.FileDataBase64 }}\" />\r\n </div>\r\n <div\r\n class=\"inline-preview-container\"\r\n *ngIf=\"row.AttachmentType != AttachmentType.LINK && !row.IsImage\"\r\n (click)=\"openPreviewDialog(row)\">\r\n <i [ngClass]=\"getAttachmentIcon(row)\"></i>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dialogPreview>\r\n <mat-card class=\"example-card\" *ngIf=\"selectedAttachment\">\r\n <mat-card-content>\r\n <div class=\"row\">\r\n <div class=\"header-title-standard\">\r\n {{ previewLabel }} {{ selectedAttachment?.AttachmentType == attachmentType.FILE ? \"File\" : \"Link\" }}\r\n <button\r\n type=\"button\"\r\n class=\"btn-close closeButton\"\r\n mat-dialog-close\r\n (click)=\"selectedAttachment = null\"></button>\r\n </div>\r\n </div>\r\n <div class=\"row mt-2\">\r\n <!-- ANTEPRIMA IMMAGINE -->\r\n <div class=\"col-12 text-center preview-container\" *ngIf=\"selectedAttachment.IsImage\">\r\n <img\r\n class=\"image-preview\"\r\n src=\"data:image/png;base64,{{\r\n selectedAttachment.FileDataBase64\r\n ? selectedAttachment.FileDataBase64\r\n : selectedAttachment.FileThumbnailBase64\r\n }}\" />\r\n </div>\r\n\r\n <!-- ANTEPRIMA LINK -->\r\n <div class=\"col-12 preview-container\" *ngIf=\"!selectedAttachment.IsImage\">\r\n <iframe\r\n class=\"link-preview\"\r\n [src]=\"selectedAttachment.TrustedUrl\"\r\n [title]=\"selectedAttachment.FileName\"></iframe>\r\n </div>\r\n </div>\r\n <div class=\"row mt-3\">\r\n <div class=\"col-sm-12 text-center\">\r\n <button\r\n mat-mini-fab\r\n color=\"primary\"\r\n matTooltip=\"Download\"\r\n (click)=\"viewAttachment(selectedAttachment)\"\r\n *ngIf=\"selectedAttachment.AttachmentType != AttachmentType.LINK\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n</ng-template>\r\n\r\n<!-- TEMPLATE PER IL PULSANTE DI AGGIUNTA NUOVO ALLEGATO -->\r\n<ng-template #addAttachmentButton>\r\n <!--\r\n Pulsanti per l'aggiunta di un file o un link. Ne viene visualizzato uno se:\r\n - gli allowedTypes sono stati specificati, nell'array ne \u00E8 presente uno solo, quello inserito \u00E8 AttachmentType.FILE (o AttachmentType.LINK)\r\n e sono nella gestione di pi\u00F9 allegati (multipleAttachment == true)\r\n OPPURE\r\n - gli allowedTypes sono stati specificati, nell'array ne \u00E8 presente uno solo, quello inserito \u00E8 AttachmentType.FILE (o AttachmentType.LINK)\r\n e sono nella gestione di un singolo allegato (multipleAttachment == true) e non ne \u00E8 ancora stato selezionato uno (ovvero attachmentsList non esiste o non ha elementi)\r\n -->\r\n <input\r\n #fileInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <button\r\n class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n *ngIf=\"\r\n allowedTypes &&\r\n allowedTypes.length == 1 &&\r\n (multipleAttachment == true ||\r\n !attachmentsList ||\r\n attachmentsList.length == 0 ||\r\n (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \"\r\n (click)=\"addFile(allowedTypes[0], fileInput)\"\r\n [disabled]=\"isDisabled\">\r\n <!-- Per l'aggiunta dei file mostro un'icona diversa dall'aggiunta dei link -->\r\n <mat-icon *ngIf=\"allowedTypes[0] == 1\">cloud_upload</mat-icon>\r\n <i class=\"fas fa-link\" *ngIf=\"allowedTypes[0] == 2\"></i>\r\n <i class=\"fa-brands fa-dropbox\" *ngIf=\"allowedTypes[0] == 3\"></i>\r\n <span style=\"margin-left: 10px\">\r\n {{\r\n allowedTypes[0] == 1\r\n ? addButtonLabel + \" file\"\r\n : allowedTypes[0] == 2\r\n ? addButtonLabel + \" link\"\r\n : uploadWithDropboxLabel\r\n }}</span\r\n >\r\n </button>\r\n\r\n <!-- Pulsante per aprire il menu per la scelta del tipo di Attachment da creare -->\r\n <button\r\n class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\"\r\n [disabled]=\"isDisabled\"\r\n *ngIf=\"\r\n !separatedUploadButtons &&\r\n allowedTypes &&\r\n allowedTypes.length > 1 &&\r\n (multipleAttachment == true ||\r\n !attachmentsList ||\r\n attachmentsList.length == 0 ||\r\n (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \">\r\n <mat-icon *ngIf=\"multipleAttachment != true\">cloud_upload</mat-icon>\r\n <mat-icon *ngIf=\"multipleAttachment == true\">add</mat-icon>\r\n <span style=\"margin-left: 0px\"> {{ addButtonLabel }} </span>\r\n </button>\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <input\r\n #imageInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n mat-menu-item\r\n (click)=\"imageInput.click()\"\r\n class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n mat-menu-item\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n mat-menu-item\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n\r\n <div\r\n *ngIf=\"\r\n separatedUploadButtons &&\r\n allowedTypes &&\r\n allowedTypes.length > 1 &&\r\n (multipleAttachment == true ||\r\n !attachmentsList ||\r\n attachmentsList.length == 0 ||\r\n (attachmentsList.length > 0 && !attachmentsList[0]))\r\n \">\r\n <div class=\"btn-group\">\r\n <button\r\n *ngIf=\"allowedTypes.includes(1)\"\r\n (click)=\"imageInput.click()\"\r\n class=\"btn btn-secondary eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"secondary\"\r\n type=\"button\">\r\n <i class=\"fa-solid fa-cloud-upload\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n <input\r\n #imageInput\r\n style=\"display: none\"\r\n id=\"file_attachment\"\r\n name=\"file_attachment\"\r\n type=\"file\"\r\n (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\"\r\n [multiple]=\"loadMultipleFiles\" />\r\n <button\r\n *ngIf=\"allowedTypes.includes(2)\"\r\n (click)=\"switchToAddingLinkMode()\"\r\n class=\"btn btn-secondary eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"secondary\"\r\n type=\"button\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n <button\r\n *ngIf=\"allowedTypes.includes(3)\"\r\n (click)=\"chooseDropboxFile()\"\r\n class=\"btn btn-secondary eqp-attachments-add-btn\"\r\n mat-raised-button\r\n color=\"secondary\"\r\n type=\"button\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #croppieTemplate>\r\n <div class=\"row m-3\">\r\n <h4>{{ cropLabel }}</h4>\r\n </div>\r\n <div class=\"row m-2 crop-large\">\r\n <div class=\"col-md-12 d-flex align-items-center justify-content-center\">\r\n <button\r\n [matTooltip]=\"rotateLeftLabel\"\r\n *ngIf=\"cropOptions.includes(1)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"rotateLeft()\">\r\n <mat-icon style=\"vertical-align: middle\">rotate_left</mat-icon>\r\n </button>\r\n <button\r\n [matTooltip]=\"rotateRightLabel\"\r\n *ngIf=\"cropOptions.includes(1)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"rotateRight()\">\r\n <mat-icon style=\"vertical-align: middle\">rotate_right</mat-icon>\r\n </button>\r\n <button\r\n [matTooltip]=\"flipHorinzontalLabel\"\r\n *ngIf=\"cropOptions.includes(2)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"flipHorizontal()\">\r\n <mat-icon style=\"vertical-align: middle\">flip_horizontal</mat-icon>\r\n </button>\r\n <button\r\n [matTooltip]=\"flipVerticalLabel\"\r\n *ngIf=\"cropOptions.includes(2)\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"flipVertical()\">\r\n <div style=\"transform: rotate(90deg)\"><mat-icon style=\"vertical-align: middle\">flip_vertical</mat-icon></div>\r\n </button>\r\n <button\r\n [matTooltip]=\"'Reset'\"\r\n class=\"btn btn-primary mat-raised-button ms-2\"\r\n (click)=\"restoreOriginalDimensions()\">\r\n <mat-icon style=\"vertical-align: middle\">replay</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"row m-2 crop-small\">\r\n <div class=\"col-md-12 d-flex align-items-center justify-content-center\">\r\n <mat-icon *ngIf=\"cropOptions.includes(1)\" style=\"font-size: 27px; vertical-align: middle\" (click)=\"rotateLeft()\"\r\n >rotate_left</mat-icon\r\n >\r\n <mat-icon\r\n class=\"ms-3\"\r\n *ngIf=\"cropOptions.includes(1)\"\r\n style=\"font-size: 27px; vertical-align: middle\"\r\n (click)=\"rotateRight()\"\r\n >rotate_right</mat-icon\r\n >\r\n <mat-icon\r\n class=\"ms-3\"\r\n *ngIf=\"cropOptions.includes(2)\"\r\n style=\"font-size: 27px; vertical-align: middle\"\r\n (click)=\"flipHorizontal()\"\r\n >flip_horizontal</mat-icon\r\n >\r\n <div class=\"ms-3\" style=\"transform: rotate(90deg)\">\r\n <mat-icon\r\n *ngIf=\"cropOptions.includes(2)\"\r\n style=\"font-size: 27px; vertical-align: middle\"\r\n (click)=\"flipVertical()\"\r\n >flip_vertical</mat-icon\r\n >\r\n </div>\r\n <mat-icon class=\"ms-3\" (click)=\"restoreOriginalDimensions()\" style=\"font-size: 27px; vertical-align: middle\"\r\n >replay</mat-icon\r\n >\r\n </div>\r\n </div>\r\n <div class=\"row justify-content-center\">\r\n <div class=\"col-12 d-flex align-items-center justify-content-center\">\r\n <div class=\"crop-container\">\r\n <image-cropper\r\n [imageFile]=\"selectedFile\"\r\n [maintainAspectRatio]=\"false\"\r\n [autoCrop]=\"false\"\r\n [containWithinAspectRatio]=\"false\"\r\n [aspectRatio]=\"4 / 3\"\r\n [cropperMinWidth]=\"128\"\r\n [onlyScaleDown]=\"true\"\r\n [roundCropper]=\"false\"\r\n [canvasRotation]=\"0\"\r\n [transform]=\"transform\"\r\n [alignImage]=\"'left'\"\r\n format=\"png\"\r\n (imageCropped)=\"imageCropped($event)\"\r\n [resizeToWidth]=\"customWidth\"\r\n [resizeToHeight]=\"customHeight\"\r\n [canvasRotation]=\"canvasRotation\">\r\n </image-cropper>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row justify-content-center mt-2 mb-2 crop-large\">\r\n <div class=\"col-12 d-flex align-items-center justify-content-center\">\r\n <button\r\n class=\"btn btn-primary mat-raised-button eqp-attachments-confirm-btn me-2\"\r\n type=\"button\"\r\n (click)=\"confirmAddAttachment()\">\r\n {{ confirmLabel }}\r\n </button>\r\n <button class=\"btn mat-raised-button eqp-attachments-abort-btn\" type=\"button\" (click)=\"abortFile()\">\r\n {{ abortLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"row justify-content-center mt-2 mb-2 crop-small\">\r\n <div class=\"col-6 d-flex align-items-center justify-content-center\" style=\"font-size: 20px\">\r\n <i class=\"fa fa-times\" (click)=\"abortFile()\"></i>\r\n </div>\r\n <div class=\"col-6 d-flex align-items-center justify-content-center\" style=\"font-size: 20px\">\r\n <i class=\"fa fa-check\" (click)=\"confirmAddAttachment()\"></i>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- TEMPLATE PER FORM DI AGGIUNTA DI UN LINK -->\r\n<ng-template #addingLinkTemplate>\r\n <span class=\"mb-1\" style=\"font-size: 20px\"><i class=\"fa fa-link\"></i>Inserisci l'URL</span>\r\n <form [formGroup]=\"newAttachmentForm\" *ngIf=\"newAttachmentForm\">\r\n <div class=\"row mb-2\" style=\"height: 80px\">\r\n <div class=\"col-6 d-grid gap-2 mx-auto\">\r\n <div class=\"input-group mb-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"{{ fileNameLabel }}\"\r\n formControlName=\"name\"\r\n [(ngModel)]=\"newAttachment.FileName\" />\r\n </div>\r\n </div>\r\n <div class=\"col-12 d-grid gap-2\">\r\n <div class=\"input-group\">\r\n <input\r\n required\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Link\"\r\n formControlName=\"path\"\r\n [(ngModel)]=\"newAttachment.FilePath\" />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-6 d-grid gap-2\">\r\n <button\r\n class=\"btn btn-secondary mat-raised-button\"\r\n (click)=\"selectedAttachment = null; addingLinkMode = false\"\r\n type=\"button\">\r\n {{ exitLabel }}\r\n </button>\r\n </div>\r\n <div class=\"col-6 d-grid gap-2\">\r\n <button\r\n class=\"btn btn-primary mat-raised-button\"\r\n type=\"submit\"\r\n (click)=\"confirmAddAttachment(); selectedAttachment = null; addingLinkMode = false\">\r\n {{ saveLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n </form>\r\n</ng-template>\r\n", styles: ["ngx-file-drop ::ng-deep .ngx-file-drop__drop-zone{min-height:30vh;border-radius:5px!important;background-color:#e4e6ea!important;cursor:pointer;font-size:17px!important;border:dotted!important;padding-top:7vh}ngx-file-drop ::ng-deep .ngx-file-drop__drop-zone .ngx-file-drop__content{display:flex;flex-direction:column;align-items:center;justify-content:center;color:#73777a!important;margin:auto}.custom-height .mat-form-field-wrapper{height:20px}.eqp-attachments-header-title{font-weight:700;font-size:19px;line-height:24px;margin-bottom:auto}.single-attachment-inline-preview-container{max-height:400px;max-width:400px;display:flex;align-items:center}.single-attachment-inline-preview-container img{max-width:100%;max-height:120px}.inline-preview-container{max-height:100px;max-width:100px;display:flex;align-items:center;justify-content:center;width:100%;cursor:pointer}.inline-preview-container img{max-width:100%;max-height:100px}.inline-preview-container i{font-size:25px;margin:auto}.preview-container{max-height:60vh;max-width:100%}.preview-container .image-preview{max-width:100%;max-height:100%}.preview-container .link-preview{width:70vw;height:55vh}.closeButton{float:right}@media (max-width: 768px){.crop-large{display:none}}@media (min-width: 768px){.crop-small{display:none}}@media (max-width: 768px){.crop-container{max-width:55%}}@media (min-width: 768px){.crop-container{max-width:35%}}\n"] }]
1027
+ args: [{ selector: "eqp-attachments", template: "<!-- Se richiesta la gestione singola mostra il pulsante di caricamento di un singolo file -->\r\n<div class=\"header\">\r\n <h1>{{ uploadTitle }}</h1>\r\n @if(chooseView == true){\r\n <mat-button-toggle-group [value]=\"viewMode\" (change)=\"setViewMode($event.value)\"\r\n aria-label=\"Modalit\u00E0 di visualizzazione\">\r\n <mat-button-toggle value=\"card\"><mat-icon>grid_view</mat-icon></mat-button-toggle>\r\n <mat-button-toggle value=\"table\"><mat-icon>view_list</mat-icon></mat-button-toggle>\r\n </mat-button-toggle-group>\r\n }\r\n</div>\r\n\r\n<!-- Gestione singolo -->\r\n@if (multipleAttachment != true) {\r\n@if (!singleAttachmentDragAndDrop) {\r\n@if (!addingLinkMode) {\r\n<div class=\"text-center\">\r\n <ng-container [ngTemplateOutlet]=\"addAttachmentButton\"></ng-container>\r\n</div>\r\n} @else {\r\n<div class=\"text-center\">\r\n <ng-container [ngTemplateOutlet]=\"addingLinkTemplate\"></ng-container>\r\n</div>\r\n}\r\n} @else {\r\n<input #fileInput id=\"file_attachment\" name=\"file_attachment\" type=\"file\" hidden (change)=\"onFileAdded($event)\"\r\n [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n\r\n@if (allowedTypes && allowedTypes.includes(1) && (!attachmentsList || attachmentsList.length == 0 ||\r\n(attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n<div class=\"dropbox\" [class.dragover]=\"dragOver\" (dragover)=\"dragOver = true; $event.preventDefault()\"\r\n (dragleave)=\"dragOver = false\" (drop)=\"dragOver = false; fileDropped($event)\"\r\n (click)=\"onSelectFile($event, fileInput)\" role=\"button\" tabindex=\"0\" (keydown.enter)=\"fileInput.click()\"\r\n (keydown.space)=\"fileInput.click()\">\r\n <div class=\"dropbox-icon\">\uD83D\uDCC1</div>\r\n <div class=\"dropbox-text\">{{ dropHereLabel }}</div>\r\n <div class=\"dropbox-subtext\">\r\n {{ supportedFormatsLabel }}\r\n </div>\r\n <button class=\"browse-btn\" type=\"button\" (click)=\"$event.stopPropagation(); fileInput.click()\">\r\n {{ browseFilesLabel }}\r\n </button>\r\n <div class=\"secondary-action\">\r\n @if (allowedTypes.includes(2) || allowedTypes.includes(3)) {\r\n @if (allowedTypes.includes(2) && allowedTypes.includes(3)) {\r\n <a class=\"secondary-action-link\" [matMenuTriggerFor]=\"linkMenu\" (click)=\"$event.stopPropagation()\">\r\n o aggiungi da web\r\n </a>\r\n <mat-menu #linkMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"switchToAddingLinkMode()\">\r\n <mat-icon>link</mat-icon>\r\n <span>Aggiungi da link</span>\r\n </button>\r\n <button mat-menu-item (click)=\"chooseDropboxFile()\">\r\n <mat-icon>cloud_queue</mat-icon>\r\n <span>Carica da Dropbox</span>\r\n </button>\r\n </mat-menu>\r\n }\r\n\r\n @else if (allowedTypes.includes(2)) {\r\n <a class=\"secondary-action-link\" (click)=\"$event.stopPropagation(); switchToAddingLinkMode()\">\r\n aggiungi un link\r\n </a>\r\n }\r\n\r\n @else if (allowedTypes.includes(3)) {\r\n <a class=\"secondary-action-link\" (click)=\"$event.stopPropagation(); chooseDropboxFile()\">\r\n carica da Dropbox\r\n </a>\r\n }\r\n }\r\n </div>\r\n</div>\r\n}\r\n}\r\n\r\n<!-- Azioni singolo elemento (come prima) -->\r\n<div class=\"text-center\">\r\n @if (attachmentsList && attachmentsList.length > 0 && attachmentsList[0]) {\r\n <button class=\"mb-2 me-2 eqp-attachments-download-btn\" (click)=\"viewAttachment(attachmentsList[0])\" type=\"button\"\r\n mat-raised-button color=\"primary\">\r\n @if (attachmentsList[0].AttachmentType == AttachmentType.FILE) {\r\n <mat-icon>download</mat-icon>\r\n } @else {\r\n <mat-icon>open_in_new</mat-icon>\r\n }\r\n {{ attachmentsList[0].AttachmentType == AttachmentType.FILE ? downloadLabel : openLinkLabel }}\r\n </button>\r\n\r\n @if (showPreview && (!attachmentsList[0].FileContentType || (!attachmentsList[0].FileContentType.startsWith('video')\r\n && !attachmentsList[0].FileContentType.startsWith('audio'))) && attachmentsList[0].IsImage == true) {\r\n <button class=\"mb-2 me-2 eqp-attachments-preview-btn\" (click)=\"openPreviewDialog(attachmentsList[0])\" type=\"button\"\r\n mat-raised-button color=\"primary\">\r\n <mat-icon>visibility</mat-icon> {{ previewLabel }}\r\n </button>\r\n }\r\n\r\n <button [disabled]=\"disableAction\" class=\"mb-2 eqp-attachments-delete-btn\"\r\n (click)=\"deleteAttachment(attachmentsList[0])\" type=\"button\" mat-raised-button [disabled]=\"isDisabled\">\r\n <mat-icon>delete</mat-icon> {{ deleteLabel }}\r\n </button>\r\n }\r\n</div>\r\n}\r\n\r\n<!-- Gestione multipla -->\r\n@if (multipleAttachment == true) {\r\n<input #fileInput id=\"file_attachment_multi\" name=\"file_attachment_multi\" type=\"file\" hidden\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n\r\n<div class=\"dropbox\" [class.dragover]=\"dragOver\" (dragover)=\"dragOver = true; $event.preventDefault()\"\r\n (dragleave)=\"dragOver = false\" (drop)=\"dragOver = false; fileDropped($event)\"\r\n (click)=\"onSelectFile($event, fileInput)\" role=\"button\" tabindex=\"0\" (keydown.enter)=\"fileInput.click()\"\r\n (keydown.space)=\"fileInput.click()\">\r\n <div class=\"dropbox-icon\">\uD83D\uDCC1</div>\r\n <div class=\"dropbox-text\">{{ dropHereLabel }}</div>\r\n <div class=\"dropbox-subtext\">\r\n {{ supportedFormatsLabel }}\r\n </div>\r\n <button class=\"browse-btn\" type=\"button\" (click)=\"$event.stopPropagation(); fileInput.click()\">\r\n {{ browseFilesLabel }}\r\n </button>\r\n <div class=\"secondary-action-link\">\r\n o <a (click)=\"$event.stopPropagation(); switchToAddingLinkMode()\">aggiungi un link</a>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if (attachmentsList?.length > 0 && showSummary) {\r\n<div class=\"upload-stats\">\r\n\r\n <div class=\"stats-info\">\r\n <div class=\"stat-item\">\r\n <div class=\"stat-value\">{{ attachmentsList?.length }}</div>\r\n <div class=\"stat-label\">{{ filesLabel }}</div>\r\n </div>\r\n <div class=\"stat-item\">\r\n <div class=\"stat-value\">{{ totalSizeFormatted }}</div>\r\n <div class=\"stat-label\">{{ totalSizeLabel }}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"progress-bar\">\r\n <div class=\"progress-fill\" [style.width.%]=\"progressPercent\"></div>\r\n </div>\r\n\r\n</div>\r\n} @else if(attachmentsList?.length == 0){\r\n<div class=\"empty-state\">{{ emptyStateLabel }}</div>\r\n}\r\n\r\n<!-- Griglia anteprime card (vale per singolo e multiplo) -->\r\n@if (viewMode === 'card') {\r\n\r\n<div class=\"file-previews\" [ngStyle]=\"getPreviewsContainerStyle()\">\r\n @for (att of attachmentsList; track att.ID) {\r\n <div [ngClass]=\"getCardClass(att)\">\r\n\r\n <div class=\"preview-img-container\" (click)=\"!att.isUploading && openPreviewDialog(att)\">\r\n @if (att.IsImage) {\r\n <img class=\"preview-img\" [src]=\"'data:image/png;base64,' + (att.FileThumbnailBase64 || att.FileDataBase64)\"\r\n [alt]=\"att.FileName\" />\r\n } @else {\r\n <div class=\"file-icon\">\r\n <i [ngClass]=\"getAttachmentIcon(att)\"></i>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"file-info\">\r\n <div class=\"file-name\" [title]=\"att.FileName\">{{ att.FileName }}</div>\r\n </div>\r\n\r\n @if(!disableAction){\r\n <button mat-icon-button class=\"remove-btn\" type=\"button\" aria-label=\"Rimuovi allegato\"\r\n (click)=\"deleteAttachment(att)\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n\r\n @if (att.isUploading) {\r\n <div class=\"upload-spinner\"></div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n} @else {\r\n\r\n<div class=\"table-view-container\">\r\n <div class=\"table-header\">\r\n <div class=\"table-cell name-col\">File</div>\r\n <div class=\"table-cell actions-col\">Azioni</div>\r\n </div>\r\n\r\n @for (att of attachmentsList; track att.ID) {\r\n <div class=\"table-row\">\r\n <div class=\"table-cell name-col\">\r\n <i class=\"file-icon-small\" [ngClass]=\"getAttachmentIcon(att)\"></i>\r\n <div class=\"file-info-text\">\r\n <span class=\"file-name-table\">{{ att.FileName }}</span>\r\n <span class=\"file-type-table\">{{ att.FileExtension || 'Link' }}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"table-cell actions-col\">\r\n <button mat-icon-button (click)=\"viewAttachment(att)\" matTooltip=\"Visualizza/Scarica\">\r\n <mat-icon>{{ att.AttachmentType === attachmentType.FILE ? 'download' : 'open_in_new' }}</mat-icon>\r\n </button>\r\n <button mat-icon-button [matMenuTriggerFor]=\"actionsMenu\" matTooltip=\"Altre opzioni\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #actionsMenu=\"matMenu\">\r\n <button mat-menu-item\r\n (click)=\"openPreviewDialog(att)\"><mat-icon>visibility</mat-icon><span>Anteprima</span></button>\r\n <button [disabled]=\"disableAction\" mat-menu-item (click)=\"deleteAttachment(att)\" matTooltip=\"Elimina\">\r\n <mat-icon color=\"warn\">delete</mat-icon>\r\n <span>Elimina</span>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n}\r\n\r\n<!-- Notifica toast -->\r\n<div class=\"upload-notification\" [class.show]=\"toast?.visible\" [class.success]=\"toast?.type === 'success'\"\r\n [class.error]=\"toast?.type === 'error'\">\r\n <span>{{ toast?.text }}</span>\r\n <div class=\"notification-progress\"></div>\r\n</div>\r\n\r\n\r\n<ng-template #dialogCropImage>\r\n <div style=\"overflow-x: hidden\" [ngClass]=\"cropDialogClass\">\r\n @if (showCropImage == true) {\r\n <ng-container [ngTemplateOutlet]=\"croppieTemplate\" [ngTemplateOutletContext]=\"{ form: newAttachmentForm }\">\r\n </ng-container>\r\n }\r\n </div>\r\n</ng-template>\r\n\r\n\r\n<ng-template #inlinePreviewTemplate let-row=\"row\">\r\n @if (row.AttachmentType != AttachmentType.LINK && row.IsImage) {\r\n <div class=\"inline-preview-container\" (click)=\"openPreviewDialog(row)\">\r\n <img [src]=\"'data:image/png;base64,' + (row.FileThumbnailBase64 ? row.FileThumbnailBase64 : row.FileDataBase64)\" />\r\n </div>\r\n } @else if (row.AttachmentType != AttachmentType.LINK && !row.IsImage) {\r\n <div class=\"inline-preview-container\" (click)=\"openPreviewDialog(row)\">\r\n <i [ngClass]=\"getAttachmentIcon(row)\"></i>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n\r\n<ng-template #dialogPreview>\r\n @if (selectedAttachment) {\r\n <h2 mat-dialog-title class=\"dialog-header\">\r\n <span>\r\n {{ previewLabel }} {{ selectedAttachment!.AttachmentType === attachmentType.FILE ? \"File\" : \"Link\" }}\r\n </span>\r\n <button mat-icon-button mat-dialog-close aria-label=\"Chiudi anteprima\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </h2>\r\n\r\n <mat-dialog-content class=\"dialog-content\">\r\n @if (selectedAttachment!.IsImage) {\r\n <img class=\"preview-image\"\r\n [src]=\"'data:image/png;base64,' + (selectedAttachment!.FileDataBase64 || selectedAttachment!.FileThumbnailBase64)\"\r\n alt=\"Anteprima allegato\" />\r\n } @else {\r\n <iframe class=\"preview-iframe\" [src]=\"selectedAttachment!.TrustedUrl\" [title]=\"selectedAttachment!.FileName\">\r\n </iframe>\r\n }\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions [align]=\"'center'\">\r\n @if (selectedAttachment!.AttachmentType !== AttachmentType.LINK) {\r\n <button mat-raised-button color=\"primary\" (click)=\"viewAttachment(selectedAttachment!)\">\r\n <mat-icon>download</mat-icon>\r\n <span>{{ downloadLabel }}</span>\r\n </button>\r\n }\r\n </mat-dialog-actions>\r\n }\r\n</ng-template>\r\n\r\n\r\n<!-- TEMPLATE PER IL PULSANTE DI AGGIUNTA NUOVO ALLEGATO -->\r\n<ng-template #addAttachmentButton>\r\n <input #fileInput style=\"display: none\" id=\"file_attachment\" name=\"file_attachment\" type=\"file\"\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n\r\n @if (allowedTypes && allowedTypes.length == 1 && (multipleAttachment == true || !attachmentsList ||\r\n attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n <button class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\" mat-raised-button color=\"primary\" type=\"button\"\r\n (click)=\"addFile(allowedTypes[0], fileInput)\" [disabled]=\"isDisabled\">\r\n @if (allowedTypes[0] == 1) { <mat-icon>cloud_upload</mat-icon> }\r\n @if (allowedTypes[0] == 2) { <i class=\"fas fa-link\"></i> }\r\n @if (allowedTypes[0] == 3) { <i class=\"fa-brands fa-dropbox\"></i> }\r\n <span style=\"margin-left: 10px\">\r\n {{ allowedTypes[0] == 1 ? (addButtonLabel + \" file\") : allowedTypes[0] == 2 ? (addButtonLabel + \" link\") :\r\n uploadWithDropboxLabel }}\r\n </span>\r\n </button>\r\n }\r\n\r\n @if (!separatedUploadButtons && allowedTypes && allowedTypes.length > 1 && (multipleAttachment == true ||\r\n !attachmentsList || attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n <button class=\"btn btn-primary mb-4 me-5 eqp-attachments-add-btn\" mat-raised-button color=\"primary\" type=\"button\"\r\n [matMenuTriggerFor]=\"attachmentTypeMenu\" [disabled]=\"isDisabled\">\r\n @if (multipleAttachment != true) { <mat-icon>cloud_upload</mat-icon> } @else { <mat-icon>add</mat-icon> }\r\n <span style=\"margin-left: 0px\">{{ addButtonLabel }}</span>\r\n </button>\r\n\r\n <mat-menu #attachmentTypeMenu=\"matMenu\">\r\n <input #imageInput style=\"display: none\" id=\"file_attachment\" name=\"file_attachment\" type=\"file\"\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n @if (allowedTypes.includes(1)) {\r\n <button mat-menu-item (click)=\"imageInput.click()\" class=\"eqp-attachments-file-btn\">\r\n <i class=\"fas fa-file\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n }\r\n @if (allowedTypes.includes(2)) {\r\n <button mat-menu-item (click)=\"switchToAddingLinkMode()\" class=\"eqp-attachments-link-btn\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n }\r\n @if (allowedTypes.includes(3)) {\r\n <button mat-menu-item (click)=\"chooseDropboxFile()\" class=\"eqp-attachments-link-btn\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n }\r\n </mat-menu>\r\n }\r\n\r\n @if (separatedUploadButtons && allowedTypes && allowedTypes.length > 1 && (multipleAttachment == true ||\r\n !attachmentsList || attachmentsList.length == 0 || (attachmentsList.length > 0 && !attachmentsList[0]))) {\r\n <div class=\"btn-group\">\r\n @if (allowedTypes.includes(1)) {\r\n <button (click)=\"imageInput.click()\" class=\"btn btn-secondary eqp-attachments-add-btn\" mat-raised-button\r\n color=\"secondary\" type=\"button\">\r\n <i class=\"fa-solid fa-cloud-upload\"></i>\r\n <span style=\"margin-left: 10px\">File</span>\r\n </button>\r\n }\r\n <input #imageInput style=\"display: none\" id=\"file_attachment\" name=\"file_attachment\" type=\"file\"\r\n (change)=\"onFileAdded($event)\" [accept]=\"acceptedFileTypes\" [multiple]=\"loadMultipleFiles\" />\r\n @if (allowedTypes.includes(2)) {\r\n <button (click)=\"switchToAddingLinkMode()\" class=\"btn btn-secondary eqp-attachments-add-btn\" mat-raised-button\r\n color=\"secondary\" type=\"button\">\r\n <i class=\"fas fa-link\"></i>\r\n <span style=\"margin-left: 10px\">Link</span>\r\n </button>\r\n }\r\n @if (allowedTypes.includes(3)) {\r\n <button (click)=\"chooseDropboxFile()\" class=\"btn btn-secondary eqp-attachments-add-btn\" mat-raised-button\r\n color=\"secondary\" type=\"button\">\r\n <i class=\"fa-brands fa-dropbox\"></i>\r\n <span style=\"margin-left: 10px\">Dropbox</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n\r\n<ng-template #croppieTemplate>\r\n <!-- Header compatto -->\r\n <h2 class=\"dialog-header m-3\">\r\n <span>{{ cropLabel }}</span>\r\n <button mat-icon-button type=\"button\" aria-label=\"Chiudi\" (click)=\"abortFile()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </h2>\r\n\r\n <!-- Contenuto scrollabile con griglia responsive -->\r\n <div class=\"dialog-content\">\r\n <!-- Toolbar controlli (large) -->\r\n <div class=\"controls-row crop-large\">\r\n @if (cropOptions.includes(1)) {\r\n <button [matTooltip]=\"rotateLeftLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"rotateLeft()\">\r\n <mat-icon>rotate_left</mat-icon>\r\n </button>\r\n <button [matTooltip]=\"rotateRightLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"rotateRight()\">\r\n <mat-icon>rotate_right</mat-icon>\r\n </button>\r\n }\r\n @if (cropOptions.includes(2)) {\r\n <button [matTooltip]=\"flipHorinzontalLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"flipHorizontal()\">\r\n <mat-icon>flip_horizontal</mat-icon>\r\n </button>\r\n <button [matTooltip]=\"flipVerticalLabel\" class=\"btn btn-primary mat-raised-button\" (click)=\"flipVertical()\">\r\n <mat-icon>flip_vertical</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Reset'\" class=\"btn btn-primary mat-raised-button\" (click)=\"restoreOriginalDimensions()\">\r\n <mat-icon>replay</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Toolbar controlli (small) -->\r\n <div class=\"controls-row crop-small\">\r\n @if (cropOptions.includes(1)) {\r\n <mat-icon class=\"control-icon\" (click)=\"rotateLeft()\">rotate_left</mat-icon>\r\n <mat-icon class=\"control-icon\" (click)=\"rotateRight()\">rotate_right</mat-icon>\r\n }\r\n @if (cropOptions.includes(2)) {\r\n <mat-icon class=\"control-icon\" (click)=\"flipHorizontal()\">flip_horizontal</mat-icon>\r\n <mat-icon class=\"control-icon\" (click)=\"flipVertical()\">flip_vertical</mat-icon>\r\n }\r\n <mat-icon class=\"control-icon\" (click)=\"restoreOriginalDimensions()\">replay</mat-icon>\r\n </div>\r\n\r\n <!-- Area crop con contenimento -->\r\n <div class=\"crop-area\">\r\n <div class=\"crop-container\">\r\n <image-cropper [imageFile]=\"selectedFile\" [maintainAspectRatio]=\"false\" [autoCrop]=\"false\"\r\n [containWithinAspectRatio]=\"false\" [aspectRatio]=\"4 / 3\" [cropperMinWidth]=\"128\" [onlyScaleDown]=\"true\"\r\n [roundCropper]=\"false\" [canvasRotation]=\"0\" [transform]=\"transform\" [alignImage]=\"'left'\" format=\"png\"\r\n (imageCropped)=\"imageCropped($event)\" [resizeToWidth]=\"customWidth\" [resizeToHeight]=\"customHeight\"\r\n [canvasRotation]=\"canvasRotation\" [output]=\"'base64'\">\r\n </image-cropper>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Azioni -->\r\n <div class=\"dialog-actions crop-large\">\r\n <button class=\"btn btn-primary mat-raised-button eqp-attachments-confirm-btn\" type=\"button\"\r\n (click)=\"confirmAddAttachment()\">\r\n {{ confirmLabel }}\r\n </button>\r\n <button class=\"btn mat-raised-button eqp-attachments-abort-btn\" type=\"button\" (click)=\"abortFile()\">\r\n {{ abortLabel }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"dialog-actions crop-small\">\r\n <button class=\"icon-action\" type=\"button\" (click)=\"abortFile()\" aria-label=\"Abort\">\r\n <i class=\"fa fa-times\"></i>\r\n </button>\r\n <button class=\"icon-action\" type=\"button\" (click)=\"confirmAddAttachment()\" aria-label=\"Confirm\">\r\n <i class=\"fa fa-check\"></i>\r\n </button>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- TEMPLATE PER FORM DI AGGIUNTA DI UN LINK -->\r\n<ng-template #addingLinkTemplate>\r\n <h2 mat-dialog-title>Aggiungi un link</h2>\r\n <mat-dialog-content class=\"add-link-dialog-content\">\r\n <form [formGroup]=\"newAttachmentForm\" class=\"add-link-form\">\r\n <mat-form-field appearance=\"outline\">\r\n <mat-label>URL *</mat-label>\r\n <input matInput formControlName=\"filePath\" placeholder=\"https://...\" required>\r\n @if (newAttachmentForm.get('filePath')?.hasError('pattern')) {\r\n <mat-error>L'URL non sembra valido.</mat-error>\r\n }\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\">\r\n <mat-label>Nome (opzionale)</mat-label>\r\n <input matInput formControlName=\"fileName\" placeholder=\"Es. Documento Progetto\">\r\n </mat-form-field>\r\n </form>\r\n </mat-dialog-content>\r\n <mat-dialog-actions align=\"end\">\r\n <button mat-button mat-dialog-close>Annulla</button>\r\n <button mat-raised-button color=\"primary\" [mat-dialog-close]=\"newAttachmentForm.value\"\r\n [disabled]=\"newAttachmentForm.invalid\">\r\n Aggiungi\r\n </button>\r\n </mat-dialog-actions>\r\n</ng-template>", styles: [":host{--primary-color: #6a5af9;--primary-color-dark: #5441f8;--success-color: #1ce593;--error-color: #ff5b5b;--background-light: #f7f9fc;--background-card: rgba(255, 255, 255, .7);--text-color: #1e293b;--text-color-light: #64748b;--border-color: rgba(203, 213, 225, .5);--shadow-color: rgba(99, 102, 241, .2);--border-radius: 16px;--transition-speed: .3s}@keyframes fadeIn{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--primary-color)}70%{box-shadow:0 0 0 10px #6a5af900}to{box-shadow:0 0 #6a5af900}}.container{width:100%;max-width:700px;margin:2rem auto;font-family:Inter,sans-serif}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:2rem;padding-bottom:1.5rem;border-bottom:1px solid var(--border-color)}.header h1{color:var(--text-color);font-size:1.8rem;font-weight:700;margin:0}.dropbox{width:100%;border:2px dashed var(--border-color);border-radius:var(--border-radius);padding:2.5rem;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;cursor:pointer;background-color:var(--background-card);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:all var(--transition-speed) ease}.dropbox:hover{transform:translateY(-5px);box-shadow:0 10px 25px var(--shadow-color);border-color:var(--primary-color)}.dropbox.dragover{border-style:solid;border-color:var(--primary-color);transform:scale(1.02);box-shadow:0 0 25px var(--shadow-color);animation:pulse 1.5s infinite}.dropbox .dropbox-icon{font-size:3.5rem;color:var(--primary-color)}.dropbox .dropbox-text{font-size:1.1rem;font-weight:600;color:var(--text-color);margin-top:1rem}.dropbox .dropbox-subtext{color:var(--text-color-light);margin-top:.5rem}.dropbox .browse-btn{margin-top:1.5rem;padding:.75rem 1.5rem;background-color:var(--primary-color);color:#fff;border:none;border-radius:10px;font-weight:600;transition:all var(--transition-speed) ease}.dropbox .browse-btn:hover{background-color:var(--primary-color-dark);transform:translateY(-2px)}.file-previews{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:1.5rem;margin-top:2rem}.file-previews{display:grid;gap:16px;padding:16px;grid-template-columns:repeat(auto-fill,minmax(var(--card-min-width, 200px),1fr))}.file-preview{background-color:var(--background-card);border-radius:var(--border-radius);box-shadow:0 4px 15px #0000000d;border:1px solid var(--border-color);overflow:hidden;display:flex;flex-direction:column;position:relative;opacity:0;animation:fadeIn .5s ease-out forwards;transition:transform var(--transition-speed) ease,box-shadow var(--transition-speed) ease}.file-preview.uploading{cursor:wait}.file-preview.uploading .preview-img-container:after{content:\"\";position:absolute;inset:0;background:#ffffffb3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);pointer-events:none}.file-preview .remove-btn{position:absolute;top:8px;right:8px;z-index:2;background-color:#0000004d;color:#fff;width:32px;height:32px;display:flex;align-items:center;justify-content:center;padding:0;transition:all var(--transition-speed) ease}.file-preview .remove-btn:hover{background-color:#ff5b5b}.file-preview .remove-btn .mat-icon{font-size:18px}@media (hover: hover) and (min-width: 769px){.file-preview .remove-btn{opacity:0;transform:scale(.8)}.file-preview:hover{transform:translateY(-5px);box-shadow:0 10px 25px var(--shadow-color)}.file-preview:hover .remove-btn{opacity:1;transform:scale(1)}}.file-preview .preview-img-container{aspect-ratio:4/3;display:flex;align-items:center;justify-content:center;position:relative;cursor:pointer;background-color:#f0f2f5}.file-preview .preview-img{width:100%;height:100%;object-fit:cover}.file-preview .file-icon{font-size:4rem;color:var(--primary-color)}.file-preview .file-info{padding:12px;border-top:1px solid var(--border-color);flex-grow:1;display:flex;align-items:center}.file-preview .file-name{font-weight:600;font-size:.9rem;color:var(--text-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-preview .upload-spinner{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:40px;height:40px;border:4px solid rgba(0,0,0,.1);border-left-color:var(--primary-color);border-radius:50%;animation:spin 1s linear infinite;pointer-events:none}.file-preview.card-small{width:140px}.file-preview.card-small .preview-img-container{height:80px}.file-preview.card-small .file-info{padding:8px}.file-preview.card-small .file-name{font-size:.8rem}.file-preview.card-small .file-icon{font-size:3rem}.file-preview.card-small .remove-btn{width:28px;height:28px}.file-preview.card-small .remove-btn .mat-icon{font-size:16px}.file-preview.card-large{width:280px}.file-preview.card-large .preview-img-container{height:180px}.file-preview.card-large .file-info{padding:16px}.file-preview.card-large .file-name{font-size:1rem}.file-preview.card-large .file-icon{font-size:5rem}.file-preview.card-large .remove-btn{width:36px;height:36px}.file-preview.card-large .remove-btn .mat-icon{font-size:20px}.file-preview[style*=--eqp-card-width]{width:var(--eqp-card-width)}.file-preview[style*=--eqp-card-width] .preview-img-container{height:calc(var(--eqp-card-width) * .65)}@keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}}.upload-stats{background-color:var(--background-card);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid var(--border-color);border-radius:var(--border-radius);padding:1.5rem;margin-top:2rem;animation:fadeIn .5s ease-out}.upload-stats .stats-info{display:flex;justify-content:space-around}.upload-stats .progress-bar{height:10px;background-color:var(--border-color);border-radius:5px;overflow:hidden;margin-top:1rem}.upload-stats .progress-fill{height:100%;background:linear-gradient(90deg,var(--primary-color),var(--success-color));transition:width var(--transition-speed) ease-out;border-radius:5px}.upload-notification{position:fixed;bottom:20px;left:50%;transform:translate(-50%,100px);padding:1rem 1.5rem;border-radius:var(--border-radius);color:#fff;font-weight:600;box-shadow:0 10px 30px #0003;transition:transform var(--transition-speed) cubic-bezier(.175,.885,.32,1.275)}.upload-notification.show{transform:translate(-50%)}.upload-notification.success{background-color:var(--success-color)}.upload-notification.error{background-color:var(--error-color)}.dialog-header{display:flex;justify-content:space-between;align-items:center;width:100%}.dialog-content{display:flex;justify-content:center;align-items:center;padding:16px 24px;overflow:auto}.preview-image{max-width:100%;max-height:70vh;height:auto;object-fit:contain}.preview-iframe{width:80vw;height:75vh;border:none;max-width:1200px}.dialog-header{display:flex;align-items:center;justify-content:space-between}.dialog-content{display:flex;flex-direction:column;gap:12px;max-height:60vh;overflow:auto;padding:0 16px 8px}.controls-row{display:flex;align-items:center;justify-content:center;gap:8px}.control-icon{font-size:28px;cursor:pointer}.crop-area{display:flex;justify-content:center}.crop-container{width:100%;max-width:720px;aspect-ratio:4/3;border-radius:8px;background:#f9f9f9;overflow:hidden}image-cropper,image-cropper canvas,image-cropper img{max-width:100%!important;max-height:100%!important}.dialog-actions{display:flex;justify-content:center;gap:12px;padding:12px 16px}.crop-large{display:flex}.crop-small{display:none}@media (max-width: 600px){.dialog-content{max-height:55vh}.crop-container{max-width:100%;aspect-ratio:auto}.crop-large{display:none}.crop-small{display:flex;justify-content:center;gap:14px}.control-icon{font-size:24px}}.stats-header{display:flex;justify-content:space-between;align-items:center;width:100%}.table-view-container{margin-top:1.5rem;background-color:var(--background-card);border-radius:var(--border-radius);border:1px solid var(--border-color);overflow:hidden;animation:fadeIn .5s ease-out}.table-header,.table-row{display:flex;align-items:center;padding:0 1rem;transition:background-color var(--transition-speed) ease}.table-header{background-color:#f8f9fa;font-weight:600;color:var(--text-color-light);font-size:.8rem;text-transform:uppercase;border-bottom:2px solid var(--border-color)}.table-row{border-bottom:1px solid var(--border-color)}.table-row:last-child{border-bottom:none}.table-row:hover{background-color:#00000005}.table-cell{padding:1rem .5rem;display:flex;align-items:center;gap:1rem}.name-col{flex:4}.size-col,.date-col{flex:2}.actions-col{flex:1;justify-content:flex-end;min-width:150px}.file-icon-small{font-size:1.5rem;color:var(--primary-color)}.file-info-text{display:flex;flex-direction:column}.file-name-table{font-weight:600;color:var(--text-color)}.file-type-table{font-size:.8rem;color:var(--text-color-light)}@media (max-width: 768px){.date-col{display:none}.name-col{flex:3}.size-col{flex:2}.actions-col{flex:2;min-width:120px}}.secondary-action-link{color:var(--primary-color);text-decoration:none;border-bottom:1px solid var(--primary-color);cursor:pointer;font-weight:500}.secondary-action-link:hover{color:var(--primary-color-dark);border-bottom-color:var(--primary-color-dark)}h2[mat-dialog-title]+mat-dialog-content.add-link-dialog-content{padding-top:20px}mat-dialog-content.add-link-dialog-content{padding-left:24px;padding-right:24px;padding-bottom:20px}.add-link-form{display:flex;flex-direction:column;gap:16px}\n"] }]
908
1028
  }], ctorParameters: () => [{ type: i1.MatDialog }, { type: i2.FormBuilder }, { type: i3.DomSanitizer }, { type: i4.HttpClient }, { type: i0.ChangeDetectorRef }, { type: i5.EqpAttachmentService }], propDecorators: { disableAction: [{
909
1029
  type: Input,
910
1030
  args: ["disableAction"]
@@ -917,6 +1037,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
917
1037
  }], attachmentsList: [{
918
1038
  type: Input,
919
1039
  args: ["attachmentsList"]
1040
+ }], singleAttachment: [{
1041
+ type: Input,
1042
+ args: ["singleAttachment"]
920
1043
  }], showMatCard: [{
921
1044
  type: Input,
922
1045
  args: ["showMatCard"]
@@ -926,9 +1049,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
926
1049
  }], loadMultipleFiles: [{
927
1050
  type: Input,
928
1051
  args: ["loadMultipleFiles"]
929
- }], attachmentsColumns: [{
930
- type: Input,
931
- args: ["attachmentsColumns"]
932
1052
  }], emptyTableMessage: [{
933
1053
  type: Input,
934
1054
  args: ["emptyTableMessage"]
@@ -983,9 +1103,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
983
1103
  }], cropDialogClass: [{
984
1104
  type: Input,
985
1105
  args: ["cropDialogClass"]
986
- }], downloadTooltipPosition: [{
987
- type: Input,
988
- args: ["downloadTooltipPosition"]
1106
+ }], maxFileSizeMB: [{
1107
+ type: Input
1108
+ }], cardSize: [{
1109
+ type: Input
1110
+ }], customCardWidthPx: [{
1111
+ type: Input
1112
+ }], customCardHeightPx: [{
1113
+ type: Input
989
1114
  }], openLinkLabel: [{
990
1115
  type: Input,
991
1116
  args: ["openLinkLabel"]
@@ -1025,9 +1150,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1025
1150
  }], cropLabel: [{
1026
1151
  type: Input,
1027
1152
  args: ["cropLabel"]
1028
- }], eqpTableSearchText: [{
1029
- type: Input,
1030
- args: ["eqpTableSearchText"]
1031
1153
  }], deleteDialogTitle: [{
1032
1154
  type: Input,
1033
1155
  args: ["deleteDialogTitle"]
@@ -1058,6 +1180,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1058
1180
  }], rotateLeftLabel: [{
1059
1181
  type: Input,
1060
1182
  args: ["rotateLeftLabel"]
1183
+ }], uploadTitle: [{
1184
+ type: Input
1185
+ }], uploadSubtitle: [{
1186
+ type: Input
1187
+ }], dropHereLabel: [{
1188
+ type: Input
1189
+ }], supportedFormatsLabel: [{
1190
+ type: Input
1191
+ }], browseFilesLabel: [{
1192
+ type: Input
1193
+ }], uploadSummaryLabel: [{
1194
+ type: Input
1195
+ }], filesLabel: [{
1196
+ type: Input
1197
+ }], totalSizeLabel: [{
1198
+ type: Input
1199
+ }], emptyStateLabel: [{
1200
+ type: Input
1201
+ }], addedSuccessfullyLabel: [{
1202
+ type: Input
1203
+ }], removedLabel: [{
1204
+ type: Input
1205
+ }], chooseView: [{
1206
+ type: Input
1207
+ }], showSummary: [{
1208
+ type: Input
1209
+ }], viewMode: [{
1210
+ type: Input,
1211
+ args: ["viewMode"]
1061
1212
  }], localEditedAttachments: [{
1062
1213
  type: Output
1063
1214
  }], abortAddAttachment: [{
@@ -1077,15 +1228,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1077
1228
  }], dialogCropImage: [{
1078
1229
  type: ViewChild,
1079
1230
  args: ["dialogCropImage", { static: true }]
1231
+ }], addingLinkTemplate: [{
1232
+ type: ViewChild,
1233
+ args: ['addingLinkTemplate']
1080
1234
  }], imageCropper: [{
1081
1235
  type: ViewChild,
1082
1236
  args: [ImageCropperComponent]
1083
1237
  }], imageInput: [{
1084
1238
  type: ViewChild,
1085
1239
  args: ["imageInput"]
1086
- }], attachmentTable: [{
1087
- type: ViewChild,
1088
- args: ["attachmentTable", { static: false }]
1089
1240
  }], inlinePreviewTemplate: [{
1090
1241
  type: ViewChild,
1091
1242
  args: ["inlinePreviewTemplate", { static: true }]
@@ -1093,4 +1244,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1093
1244
  type: ViewChild,
1094
1245
  args: ["dialogPreview", { static: true }]
1095
1246
  }] } });
1096
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXFwLWF0dGFjaG1lbnRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2VxcC1hdHRhY2htZW50cy9zcmMvbGliL2VxcC1hdHRhY2htZW50cy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9lcXAtYXR0YWNobWVudHMvc3JjL2xpYi9lcXAtYXR0YWNobWVudHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFFTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUEwQixVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdwRSxPQUFPLEVBQWdCLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RGLE9BQU8sZ0JBQWdCLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBcUIscUJBQXFCLEVBQWtCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0csT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGNBQWMsRUFBa0MsTUFBTSwwQkFBMEIsQ0FBQztBQUUxRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUl0RixPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUluRCxNQUFNLFFBQVEsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQ3hCLElBQUksT0FBTyxDQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO0lBQ3RDLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7SUFDaEMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJ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O3NCQUExRSxTQUFTO3VCQUFDLHVCQUF1QixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFDTixhQUFhO3NCQUExRCxTQUFTO3VCQUFDLGVBQWUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XHJcbmltcG9ydCB7XHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFRlbXBsYXRlUmVmLFxyXG4gIFZpZXdDaGlsZFxyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcclxuaW1wb3J0IHsgTWF0RGlhbG9nLCBNYXREaWFsb2dSZWYgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nXCI7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gXCJAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyXCI7XHJcbmltcG9ydCB7IENvbmZpZ0NvbHVtbiwgVG9vbHRpcFBvc2l0aW9uVHlwZSwgVHlwZUNvbHVtbiB9IGZyb20gXCJAZXFwcm9qZWN0L2VxcC1jb21tb25cIjtcclxuaW1wb3J0IGltYWdlQ29tcHJlc3Npb24gZnJvbSBcImJyb3dzZXItaW1hZ2UtY29tcHJlc3Npb25cIjtcclxuaW1wb3J0IHsgYmFzZTY0VG9GaWxlLCBJbWFnZUNyb3BwZWRFdmVudCwgSW1hZ2VDcm9wcGVyQ29tcG9uZW50LCBJbWFnZVRyYW5zZm9ybSB9IGZyb20gXCJuZ3gtaW1hZ2UtY3JvcHBlclwiO1xyXG5pbXBvcnQgeyBBdHRhY2htZW50SGVscGVyU2VydmljZSB9IGZyb20gXCIuL2hlbHBlcnMvYXR0YWNobWVudC5oZWxwZXJcIjtcclxuaW1wb3J0IHsgQXR0YWNobWVudFR5cGUsIENyb3BPcHRpb25FbnVtLCBJQXR0YWNobWVudERUTyB9IGZyb20gXCIuL2ludGVyZmFjZXMvSUF0dGFjaG1lbnRcIjtcclxuaW1wb3J0IHsgSU9wdGlvbnMgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL0lPcHRpb25zXCI7XHJcbmltcG9ydCB7IEVxcEF0dGFjaG1lbnREaWFsb2dTZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvZXFwLWF0dGFjaG1lbnQtZGlhbG9nLnNlcnZpY2VcIjtcclxuXHJcbmRlY2xhcmUgdmFyIERyb3Bib3g6IGFueTtcclxuXHJcbmltcG9ydCB7IGNvbmNhdE1hcCwgZnJvbSwgT2JzZXJ2YWJsZSB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IEVxcEF0dGFjaG1lbnRTZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvZXFwLWF0dGFjaG1lbnQuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBFcXBUYWJsZUNvbXBvbmVudCB9IGZyb20gXCJAZXFwcm9qZWN0L2VxcC10YWJsZVwiO1xyXG5cclxuY29uc3QgdG9CYXNlNjQgPSAoZmlsZSkgPT5cclxuICBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiByZXNvbHZlKHJlYWRlci5yZXN1bHQudG9TdHJpbmcoKSk7XHJcbiAgICByZWFkZXIub25lcnJvciA9IChlcnJvcikgPT4gcmVqZWN0KGVycm9yKTtcclxuICB9KTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcImVxcC1hdHRhY2htZW50c1wiLFxyXG4gIHRlbXBsYXRlVXJsOiBcIi4vZXFwLWF0dGFjaG1lbnRzLmNvbXBvbmVudC5odG1sXCIsXHJcbiAgc3R5bGVVcmxzOiBbXCIuL2VxcC1hdHRhY2htZW50cy5jb21wb25lbnQuc2Nzc1wiXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRXFwQXR0YWNobWVudHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIC8vI3JlZ2lvbiBASW5wdXQgZGVsIGNvbXBvbmVudGVcclxuXHJcbiAgLyoqXHJcbiAgICogU2UgVFJVRSBhbGxvcmEgbmFzY29uZGUgbGEgY29sb25uYSBwZXIgbGUgYXppb25pIHN1bGwnYWxsZWdhdG8gKG5lbCBjYXNvIFwibXVsdGlwbGVBdHRhY2htZW50XCIgw6ggVFJVRSkuXHJcbiAgICovXHJcbiAgQElucHV0KFwiZGlzYWJsZUFjdGlvblwiKSBkaXNhYmxlQWN0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlIFRSVUUgbW9zdHJhIGlsIHRpdG9sbyBuZWxsJ2hlYWRlciBuZWwgY2FzbyBpbiBjdWkgXCJtdWx0aXBsZUF0dGFjaG1lbnRcIiDDqCBUUlVFIChcIkVsZW5jbyBhbGxlZ2F0aVwiIGRpIGRlZmF1bHQpLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNob3dIZWFkZXJcIikgc2hvd0hlYWRlcjogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRpdG9sbyBkYSB2aXN1YWxpenphcmUgc2UgaWwgcGFyYW1ldHJvIFwic2hvd0hlYWRlclwiIMOoIFRSVUUuIERpIGRldmF1bHQgdmllbmUgdmlzdWFsaXp6YXRvIFwiRWxlbmNvIGFsbGVnYXRpXCIuXHJcbiAgICovXHJcbiAgQElucHV0KFwiaGVhZGVyVGl0bGVcIikgaGVhZGVyVGl0bGU6IHN0cmluZyA9IFwiRWxlbmNvIGFsbGVnYXRpXCI7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNvcmdlbnRlIGRhdGkgZGEgdmlzdWFsaXp6YXJlLiBOZWwgY2FzbyBzaSB2dW9sZSBnZXN0aXJlIHVuIHNpbmdvbG8gYWxsZWdhdG8gdmEgcGFzc2F0byBpbiBvZ25pIGNhc28gY29tZSBBcnJheS5cclxuICAgKi9cclxuICBASW5wdXQoXCJhdHRhY2htZW50c0xpc3RcIikgYXR0YWNobWVudHNMaXN0OiBBcnJheTxJQXR0YWNobWVudERUTz4gPSBudWxsO1xyXG5cclxuICAvKipcclxuICAgKiBTZSBUUlVFIG5vbiBtb3N0cmEgbGEgTWF0Q2FyZCAobmVsIGNhc28gaW4gY3VpIFwibXVsdGlwbGVBdHRhY2htZW50XCIgw6ggVFJVRSkuXHJcbiAgICovXHJcbiAgQElucHV0KFwic2hvd01hdENhcmRcIikgc2hvd01hdENhcmQ6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBTZSBGQUxTRSBhbGxvcmEgaWwgY29tcG9uZW50ZSBtb3N0cmEgc29sbyBpbCBwdWxzYW50ZSBkaSBjYXJpY2FtZW50byBkaSB1biBzaW5nb2xvIGZpbGUsIHVuYSB2b2x0YSBjYXJpY2F0byBpbCBmaWxlIGludm9jYSBsJ2V2ZW50byBkaSBvdXRwdXQgXCJsb2NhbEVkaXRlZEF0dGFjaG1lbnRzXCIuXHJcbiAgICogU2UgVFJVRSBhbGxvcmEgaWwgY29tcG9uZW50ZSBtb3N0cmEgbCdlbGVuY28gZGkgdHV0dGkgZ2xpIGFsbGVnYXRpIHJpY2V2dXRvIG5lbCBwYXJhbWV0cm8gXCJhdHRhY2htZW50c0xpc3RcIi5cclxuICAgKi9cclxuICBASW5wdXQoXCJtdWx0aXBsZUF0dGFjaG1lbnRcIikgbXVsdGlwbGVBdHRhY2htZW50OiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogU2UgYXNzdW1lIGlsIHZhbG9yZSBUUlVFIGFsbG9yYSBzYXLDoCBwb3NzaWJpbGUgY2FyaWNhcmUgcGnDuSBmaWxlIHBlciB2b2x0YS4gUXVlc3RhIGZ1bnppb25hbGl0w6Agw6ggYXR0aXZhXHJcbiAgICogU09MTyBzZSBzaSBnZXN0aXNjb25vIGFsbGVnYXRpIG11bHRpcGxpLCBxdWluZGkgc2UgbCdpbnB1dCAnbXVsdGlwbGVBdHRhY2htZW50JyBhc3N1bWUgaWwgdmFsb3JlIFRSVUUsIGFsdHJpbWVudGkgw6ggc2VtcHJlIGRpc2FiaWxpdGF0YS5cclxuICAgKi9cclxuICBASW5wdXQoXCJsb2FkTXVsdGlwbGVGaWxlc1wiKSBsb2FkTXVsdGlwbGVGaWxlczogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBDb25maWd1cmF6aW9uZSBkZWxsZSBjb2xvbm5lIGRlbGxhIGVxcC10YWJsZSBwZXIgbGEgdmlzdWFsaXp6YXppb25lIGRlZ2xpIGFsbGVnYXRpIChjYXNvIFwibXVsdGlwbGVBdHRhY2htZW50XCIgw6ggVFJVRSkuXHJcbiAgICovXHJcbiAgQElucHV0KFwiYXR0YWNobWVudHNDb2x1bW5zXCIpIGF0dGFjaG1lbnRzQ29sdW1uczogQXJyYXk8Q29uZmlnQ29sdW1uPiA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEltcG9zdGEgaWwgbWVzc2FnZ2lvIGRhIHZpc3VhbGl6emFyZSBuZWwgY2FzbyBpbiBjdWkgbGEgdGFiZWxsYSBkZWdsaSBhbGxlZ2F0aSAobmVsIGNhc28gaW4gY3VpIFwibXVsdGlwbGVBdHRhY2htZW50XCIgw6ggVFJVRSkgw6ggdnVvdGEuXHJcbiAgICovXHJcbiAgQElucHV0KFwiZW1wdHlUYWJsZU1lc3NhZ2VcIikgZW1wdHlUYWJsZU1lc3NhZ2U6IHN0cmluZyA9IFwiTmVzc3VuIGRhdG8gdHJvdmF0b1wiO1xyXG5cclxuICAvKipcclxuICAgKiBTZSBUUlVFIGFsbG9yYSBwZXJtZXR0ZSBkaSBzZWxlemlvbmFyZSBzb2x0YW50byBmaWxlIGRpIHRpcG8gaW1tYWdpbmUsIGF2ZW50ZSB1bm8gZGVpIG1pbWV0eXBlXHJcbiAgICogc3BlY2lmaWNhdGkgZGVudHJvIEF0dGFjaG1lbnRIZWxwZXJTZXJ2aWNlLlxyXG4gICAqIFNlIEZBTFNFIHBlcm1ldHRlIGRpIHNlbGV6aW9uYXJlIHF1YWxzaWFzaSB0aXBvIGRpIGZpbGVcclxuICAgKi9cclxuICBASW5wdXQoXCJhbGxvd09ubHlJbWFnZXNcIikgYWxsb3dPbmx5SW1hZ2VzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNwZWNpZmljYSBpIHRpcGkgZGkgZmlsZSBjaGUgw6ggcG9zc2liaWxlIGNhcmljYXJlXHJcbiAgICovXHJcbiAgQElucHV0KFwiYWNjZXB0ZWRGaWxlVHlwZXNcIikgYWNjZXB0ZWRGaWxlVHlwZXM6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogU2UgVFJVRSBkaXNhYmlsaXRhIGlsIHB1bHNhbnRlIGRpIEFnZ2l1bnRhIGFsbGVnYXRvIChhIHByZXNjaW5kZXJlIGRhbCB2YWxvcmUgZGVsIHBhcmFtZXRybyBcIm11bHRpcGxlQXR0YWNobWVudFwiKS5cclxuICAgKi9cclxuICBASW5wdXQoXCJpc0Rpc2FibGVkXCIpIGlzRGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogTW9zdHJhL25hc2NvbmRlIGxhIGNvbG9ubmEgcGVyIHZpc3VhbGl6emFyZSBsJ2FudGVwcmltYSBkZWkgZmlsZSBuZWxsYSB0YWJlbGxhIChjYXNvIG11bHRpcGxlQXRhdGNobWVudHMgPSB0cnVlKS5cclxuICAgKi9cclxuICBASW5wdXQoXCJzaG93SW5saW5lUHJldmlld1wiKSBzaG93SW5saW5lUHJldmlldzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBFbmRwb2ludCBkYSBjaGlhbWFyZSBwZXIgcmVjdWVwcmFyZSBsJ0lBdHRhY2htZW50RFRPIGNvbXBsZXRvIGRhIHZlZGVyZSBuZWxsJ2FudGVwcmltYS4gTGEgY2hpYW1hdGEgc2Fyw6AgaW4gUE9TVCBlIG5lbCBib2R5XHJcbiAgICogY29udGVycsOgIGwnSUF0dGFjaG1lbnREVE8gc2VsZXppb25hdG8gZGFsbCd1dGVudGUuXHJcbiAgICogTGEgY2hpYW1hdGEgdmllbmUgZXNlZ3VpdGEgc29sbyBwZXIgbCdhbnRlcHJpbWEgZGVsbGUgaW1tYWdpbmkgZXNzZW5kbyBuZWNlc3NhcmlvIGlsIGJhc2U2NCBjb21wbGV0byBkZWxsJ2ltbWFnaW5lIGEgZGltZW5zaW9uZSByZWFsZS5cclxuICAgKiBQZXIgZG9jdW1lbnRpL2xpbmsgYmFzdGEgY2hlIHNpYSBwb3BvbGF0YSBsYSBwcm9wcmlldMOgIEZpbGVQYXRoIGRpIElBdHRhY2htZW50RFRPLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcImdldEF0dGFjaG1lbnRFbmRwb2ludFwiKSBnZXRBdHRhY2htZW50RW5kcG9pbnQ6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIEhvc3RuYW1lIGRlbGwnYW1iaWVudGUgZGkgcHJvZHV6aW9uZSBkZWxsJ2FwcGxpY2F0aXZvLiBOZWNlc3NhcmlvIHBlciB2aXN1YWxpenphcmUgbCdhbnRlcHJpbWEgZGVpIGRvY3VtZW50aVxyXG4gICAqIHRyYW1pdGUgaWwgdmlld2VyIGRpIGdvb2dsZS5cclxuICAgKiBOT1RBOiBQZXIgdmlzdWFsaXp6YXJlIGwnYW50ZXByaW1hIMOoIG5lY2Vzc2FyaW8gY2hlIGxhIHByb3JpZXTDoCBGaWxlUGF0aCBkZWxsJ0lBdHRhY2htZW50RFRPIHNpYSBwb3BvbGF0YSBlIGNoZVxyXG4gICAqIHNpYSBhYmlsaXRhdG8gbCdhY2Nlc3NvIGFsbGEgY2FydGVsbGEgc3VsIHNlcnZlciB0cmFtaXRlIGhvc3RuYW1lLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcInByb2R1Y3Rpb25CYXNlVXJsXCIpIHByb2R1Y3Rpb25CYXNlVXJsOiBzdHJpbmcgPSBudWxsO1xyXG5cclxuICAvKipcclxuICAgKiBPcHppb25pIHBlciBsYSBjb21wcmVzc2lvbmUgZGVsbGUgaW1tYWdpbmkgY2FyaWNhdGUuXHJcbiAgICovXHJcbiAgQElucHV0KFwiY29tcHJlc3Npb25PcHRpb25zXCIpIGNvbXByZXNzaW9uT3B0aW9uczogSU9wdGlvbnMgPSB7XHJcbiAgICBtYXhTaXplTUI6IDAuNSxcclxuICAgIG1heFdpZHRoT3JIZWlnaHQ6IDE5MjAsXHJcbiAgICB1c2VXZWJXb3JrZXI6IHRydWVcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBBcnJheSBkaSBBdHRhY2htZW50VHlwZSBjaGUgc2kgcG9zc29ubyBhZ2dpdW5nZXJlXHJcbiAgICovXHJcbiAgQElucHV0KFwiYWxsb3dlZFR5cGVzXCIpIGFsbG93ZWRUeXBlczogQXJyYXk8QXR0YWNobWVudFR5cGU+ID0gW0F0dGFjaG1lbnRUeXBlLkZJTEUsIEF0dGFjaG1lbnRUeXBlLkxJTktdO1xyXG5cclxuICAvKipcclxuICAgKiBQZXJtZXR0ZSBkaSBzdGFiaWxpcmUgc2UgbGEgZXFwLXRhYmxlIGNvbnRlbmVudGUgbCdlbGVuY28gZGVnbGkgYWxsZWdhdGkgdXRpbGl6emFcclxuICAgKiBpbCBtdWx0aWxpbmd1YSBvcHB1cmUgbm9cclxuICAgKi9cclxuICBASW5wdXQoXCJpc0VxcFRhYmxlTXVsdGlMYW5ndWFnZVwiKSBpc0VxcFRhYmxlTXVsdGlMYW5ndWFnZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBQZXJtZXR0ZSBkaSBzdGFiaWxpcmUsIGluIGNhc28gZGkgZ2VzdGlvbmUgYWxsZWdhdGkgbXVsdGlwbGksIHNlIGxhIHRhYmVsbGEgY29udGVuZW50ZSBsJ2VsZW5jb1xyXG4gICAqIGRlZ2xpIGFsbGVnYXRpIGRldmUgZXNzZXJlIHBhZ2luYXRhIG9wcHVyZSBub1xyXG4gICAqL1xyXG4gIEBJbnB1dChcInRhYmxlUGFnaW5hdG9yVmlzaWJsZVwiKSB0YWJsZVBhZ2luYXRvclZpc2libGU6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBQZXJtZXR0ZSBkaSBzdGFiaWxpcmUsIGluIGNhc28gZGkgZ2VzdGlvbmUgYWxsZWdhdGkgbXVsdGlwbGksIHNlIGxhIHRhYmVsbGEgY29udGVuZW50ZSBsJ2VsZW5jb1xyXG4gICAqIGRlZ2xpIGFsbGVnYXRpIGRldmUgY29udGVuZXJlIGlsIGNhbXBvIGRpIHJpY2VyY2Egb3BwdXJlIG5vXHJcbiAgICovXHJcbiAgQElucHV0KFwiaXNUYWJsZVNlYXJjaGVhYmxlXCIpIGlzVGFibGVTZWFyY2hlYWJsZTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIEluIGNhc28gZGkgZ2VzdGlvbmUgYWxsZWdhdGkgbXVsdGlwbGksIHBlcm1ldHRlIGRpIHN0YWJpbGlyZSBsYSBkaW1lbnNpb25lIHBhZ2luYSBkaSBkZWZhdWx0XHJcbiAgICogcGVyIGxhIHRhYmVsbGEgY29udGVuZW50ZSBsJ2VsZW5jbyBkZWdsaSBhbGxlZ2F0aVxyXG4gICAqL1xyXG4gIEBJbnB1dChcInRhYmxlUGFnaW5hdG9yU2l6ZVwiKSB0YWJsZVBhZ2luYXRvclNpemU6IG51bWJlciA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcm1ldHRlIGRpIHNjZWdsaWVyZSBpbCBtb2RvIGluIGN1aSBpIGZpbGUgZGV2b25vIGVzc2VyZSBjYXJpY2F0aVxyXG4gICAqL1xyXG4gIC8vIEBJbnB1dChcInVwbG9hZFR5cGVcIikgdXBsb2FkVHlwZTogVXBsb2FkVHlwZUVudW0gPSBVcGxvYWRUeXBlRW51bS5GSUxFX0FORF9MSU5LO1xyXG5cclxuICAvKipcclxuICAgKiBQZXJtZXR0ZSBkaSBzdGFiaWxpcmUgc2UgaSBwdWxzYW50aSBwZXIgaWwgY2FyaWNhbWVudG8gZGVpIGZpbGUgc29ubyBzZXBhcmF0aSBvIGluIHVuIG1lbsO5IGEgdGVuZGluYVxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNlcGFyYXRlZFVwbG9hZEJ1dHRvbnNcIikgc2VwYXJhdGVkVXBsb2FkQnV0dG9uczogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBQZXJtZXR0ZSBkaSBzY2VnbGllcmUgc2UgZGFyZSBsYSBwb3NzaWJpbGl0w6AgZGkgdmVkZXJlIG8gbm8gbCdhbnRlcHJpbWFcclxuICAgKi9cclxuICBASW5wdXQoXCJzaG93UHJldmlld1wiKSBzaG93UHJldmlldzogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIEluIGNhc28gZGkgYWxsZWdhdG8gc2luZ29sbywgcGVybWV0dGUgZGkgc2NlZ2xpZXJlIHNlIGFnZ2l1bmdlcmUgZmlsZSB0cmFtaXRlIGRyYWcgYW5kIGRyb3BcclxuICAgKi9cclxuICBASW5wdXQoXCJzaW5nbGVBdHRhY2htZW50RHJhZ0FuZERyb3BcIikgc2luZ2xlQXR0YWNobWVudERyYWdBbmREcm9wOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEFycmF5IGRpIG9wemlvbmkgY2hlIHNpIHBvc3Nvbm8gdXRpbGl6emFyZSBwZXIgaWwgY3JvcFxyXG4gICAqL1xyXG4gIEBJbnB1dChcImNyb3BPcHRpb25zXCIpIGNyb3BPcHRpb25zOiBBcnJheTxDcm9wT3B0aW9uRW51bT4gPSBbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ2xhc3NlIGN1c3RvbSBkYSBhc3NlZ25hcmUgYWwgZGlhbG9nIGRlbCBjcm9wIGltbWFnaW5pXHJcbiAgICovXHJcbiAgQElucHV0KFwiY3JvcERpYWxvZ0NsYXNzXCIpIGNyb3BEaWFsb2dDbGFzczogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBJbnB1dCBwZXIgZGVmaW5pcmUgbGUgbGFiZWwgZGEgdXNhcmUgbmVsIGNvbXBvbmVudGVcclxuICAgKi9cclxuICBASW5wdXQoXCJkb3dubG9hZFRvb2x0aXBQb3NpdGlvblwiKSBkb3dubG9hZFRvb2x0aXBQb3NpdGlvbjogVG9vbHRpcFBvc2l0aW9uVHlwZSA9IFRvb2x0aXBQb3NpdGlvblR5cGUuQmVsb3c7XHJcbiAgQElucHV0KFwib3BlbkxpbmtMYWJlbFwiKSBvcGVuTGlua0xhYmVsOiBzdHJpbmcgPSBcIkFwcmkgbGlua1wiO1xyXG4gIEBJbnB1dChcImFkZEJ1dHRvbkxhYmVsXCIpIGFkZEJ1dHRvbkxhYmVsOiBzdHJpbmcgPSBcIkFnZ2l1bmdpXCI7XHJcbiAgQElucHV0KFwiZG93bmxvYWRMYWJlbFwiKSBkb3dubG9hZExhYmVsOiBzdHJpbmcgPSBcIkRvd25sb2FkXCI7XHJcbiAgQElucHV0KFwiZGVsZXRlTGFiZWxcIikgZGVsZXRlTGFiZWw6IHN0cmluZyA9IFwiRWxpbWluYVwiO1xyXG4gIEBJbnB1dChcImZpbGVOYW1lTGFiZWxcIikgZmlsZU5hbWVMYWJlbDogc3RyaW5nID0gXCJOb21lIGZpbGVcIjtcclxuICBASW5wdXQoXCJwcmV2aWV3TGFiZWxcIikgcHJldmlld0xhYmVsOiBzdHJpbmcgPSBcIkFudGVwcmltYVwiO1xyXG4gIEBJbnB1dChcInVwbG9hZEZpbGVMYWJlbFwiKSB1cGxvYWRGaWxlTGFiZWw6IHN0cmluZyA9IFwiQ2FyaWNhIGZpbGVcIjtcclxuICBASW5wdXQoXCJjb25maXJtTGFiZWxcIikgY29uZmlybUxhYmVsOiBzdHJpbmcgPSBcIkNvbmZlcm1hXCI7XHJcbiAgQElucHV0KFwiYWJvcnRMYWJlbFwiKSBhYm9ydExhYmVsOiBzdHJpbmcgPSBcIkFubnVsbGFcIjtcclxuICBASW5wdXQoXCJzYXZlTGFiZWxcIikgc2F2ZUxhYmVsOiBzdHJpbmcgPSBcIlNhbHZhXCI7XHJcbiAgQElucHV0KFwiZXhpdExhYmVsXCIpIGV4aXRMYWJlbDogc3RyaW5nID0gXCJFc2NpXCI7XHJcbiAgQElucHV0KFwidXBsb2FkV2l0aERyb3Bib3hMYWJlbFwiKSB1cGxvYWRXaXRoRHJvcGJveExhYmVsOiBzdHJpbmcgPSBcIkNhcmljYSBjb24gRHJvcGJveFwiO1xyXG4gIEBJbnB1dChcImNyb3BMYWJlbFwiKSBjcm9wTGFiZWw6IHN0cmluZyA9IFwiU2NlZ2xpIGxlIGRpbWVuc2lvbmkgZGVsbCdpbW1hZ2luZVwiO1xyXG4gIEBJbnB1dChcImVxcFRhYmxlU2VhcmNoVGV4dFwiKSBlcXBUYWJsZVNlYXJjaFRleHQ6IHN0cmluZyA9IFwiQ2VyY2FcIjtcclxuICBASW5wdXQoXCJkZWxldGVEaWFsb2dUaXRsZVwiKSBkZWxldGVEaWFsb2dUaXRsZTogc3RyaW5nID0gbnVsbDtcclxuICBASW5wdXQoXCJkZWxldGVEaWFsb2dNZXNzYWdlXCIpIGRlbGV0ZURpYWxvZ01lc3NhZ2U6IHN0cmluZyA9IFwiU2VpIHNpY3VybyBkaSB2b2xlciBjYW5jZWxsYXJlIHF1ZXN0J2FsbGVnYXRvP1wiO1xyXG4gIEBJbnB1dChcIm5vSW1hZ2VTZWxlY3RlZEVycm9yTWVzc2FnZVwiKSBub0ltYWdlU2VsZWN0ZWRFcnJvck1lc3NhZ2U6IHN0cmluZyA9XHJcbiAgICBcIk5vbiDDqCBwb3NzaWJpbGUgc2VsZXppb25hcmUgdW4gZmlsZSBjaGUgbm9uIHNpYSB1bidpbW1hZ2luZS5cIjtcclxuICBASW5wdXQoXCJ3cm9uZ1R5cGVTZWxlY3RlZEVycm9yTWVzc2FnZVwiKSB3cm9uZ1R5cGVTZWxlY3RlZEVycm9yTWVzc2FnZTogc3RyaW5nID1cclxuICAgIFwiTm9uIMOoIHBvc3NpYmlsZSBjYXJpY2FyZSBpbCBmaWxlIHNlbGV6aW9uYXRvLlwiO1xyXG4gIEBJbnB1dChcInZpZGVvUHJldmlld0Vycm9yTWVzc2FnZVwiKSB2aWRlb1ByZXZpZXdFcnJvck1lc3NhZ2U6IHN0cmluZyA9XHJcbiAgICBcIkltcG9zc2liaWxlIGFwcmlyZSBsJ2FudGVwcmltYSBkaSB1biBmaWxlIHZpZGVvLlwiO1xyXG4gIEBJbnB1dChcInZpZGVvUHJldmlld0Vycm9yTWVzc2FnZVwiKSBhdWRpb1ByZXZpZXdFcnJvck1lc3NhZ2U6IHN0cmluZyA9XHJcbiAgICBcIkltcG9zc2liaWxlIGFwcmlyZSBsJ2FudGVwcmltYSBkaSB1biBmaWxlIGF1ZGlvLlwiO1xyXG4gIEBJbnB1dChcImZsaXBIb3JpbnpvbnRhbExhYmVsXCIpIGZsaXBIb3JpbnpvbnRhbExhYmVsOiBzdHJpbmcgPSBcIkNhcG92b2xnaSBvcml6em9udGFsbWVudGVcIjtcclxuICBASW5wdXQoXCJmbGlwVmVydGljYWxMYWJlbFwiKSBmbGlwVmVydGljYWxMYWJlbDogc3RyaW5nID0gXCJDYXBvdm9sZ2kgdmVydGljYWxtZW50ZVwiO1xyXG4gIEBJbnB1dChcInJvdGF0ZVJpZ2h0TGFiZWxcIikgcm90YXRlUmlnaHRMYWJlbDogc3RyaW5nID0gXCJSdW90YSBhIGRlc3RyYVwiO1xyXG4gIEBJbnB1dChcInJvdGF0ZUxlZnRMYWJlbFwiKSByb3RhdGVMZWZ0TGFiZWw6IHN0cmluZyA9IFwiUnVvdGEgYSBzaW5pc3RyYVwiO1xyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICAvLyNyZWdpb24gQE91dHB1dCBkZWwgY29tcG9uZW50ZVxyXG5cclxuICAvKipcclxuICAgKiBSZXN0aXR1aXNjZSBsYSBsaXN0YSBhZ2dpb3JuYXRhIGRlZ2xpIGFsbGVnYXRpLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSBsb2NhbEVkaXRlZEF0dGFjaG1lbnRzOiBFdmVudEVtaXR0ZXI8QXJyYXk8SUF0dGFjaG1lbnREVE8+PiA9IG5ldyBFdmVudEVtaXR0ZXI8QXJyYXk8SUF0dGFjaG1lbnREVE8+PigpO1xyXG5cclxuICAvKipcclxuICAgKiBFdmVudG8gc2NhdGVuYXRvIGFsbGEgcHJlc3Npb25lIGRlbCBwdWxzYW50ZSBFU0NJIGRlbGxhIG1vZGFsZSBkaSBjYXJpY2FtZW50byBmaWxlLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSBhYm9ydEFkZEF0dGFjaG1lbnQ6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBkaSBvdXRwdXQgY2hlIHJlc3RpdHVpc2NlIGwnSUF0dGFjaG1lbnREVE8gc2VsZXppb25hdG8gcGVyIGlsIGRvd25sb2FkIG5lbCBjYXNvIEZpbGVEYXRhQmFzZTY0LCBGaWxlQ29udGVudFR5cGUgbyBGaWxlTmFtZSBub24gZm9zc2VybyBzcGVjaWZpY2F0aS5cclxuICAgKi9cclxuICBAT3V0cHV0KFwiZG93bmxvYWRBdHRhY2htZW50XCIpIGRvd25sb2FkQXR0YWNobWVudDogRXZlbnRFbWl0dGVyPElBdHRhY2htZW50RFRPPiA9IG5ldyBFdmVudEVtaXR0ZXI8SUF0dGFjaG1lbnREVE8+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBkaSBvdXRwdXQgY2hlIHJlc3RpdHVpc2NlIGwnZWxlbWVudG8gZWxpbWluYXRvIHByaW1hIGNoZSBxdWVzdG8gdmVuZ2EgZWZmZXR0aXZhbWVudGUgcmlzbW9zc28gZGFsbGEgbGlzdGEuXHJcbiAgICovXHJcbiAgQE91dHB1dChcIm9uRGVsZXRlQXR0YWNobWVudFwiKSBvbkRlbGV0ZUF0dGFjaG1lbnQ6IEV2ZW50RW1pdHRlcjxJQXR0YWNobWVudERUTz4gPSBuZXcgRXZlbnRFbWl0dGVyPElBdHRhY2htZW50RFRPPigpO1xyXG5cclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgLy8jcmVnaW9uIFByb3ByaWV0w6AgcGVyIGdlc3Rpb25lIGNhcmljYW1lbnRvIG51b3ZvIGFsbGVnYXRvXHJcbiAgbmV3QXR0YWNobWVudDogSUF0dGFjaG1lbnREVE8gPSB7fSBhcyBJQXR0YWNobWVudERUTztcclxuICBuZXdNdWx0aXBsZUF0dGFjaG1lbnRzOiBBcnJheTxJQXR0YWNobWVudERUTz4gPSBbXTtcclxuICBhdHRhY2htZW50VHlwZSA9IEF0dGFjaG1lbnRUeXBlO1xyXG4gIC8vIHVwbG9hZFR5cGVFbnVtID0gVXBsb2FkVHlwZUVudW07XHJcbiAgbmV3QXR0YWNobWVudEZvcm06IEZvcm1Hcm91cDtcclxuICBzZWxlY3RlZEZpbGU6IEZpbGUgPSBudWxsO1xyXG4gIHNlbGVjdGVkRmlsZXM6IEFycmF5PEZpbGU+ID0gbnVsbDtcclxuICBzaG93Q3JvcEltYWdlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQFZpZXdDaGlsZChcImRpYWxvZ0FkZEF0dGFjaG1lbnRcIiwgeyBzdGF0aWM6IHRydWUgfSkgZGlhbG9nQWRkQXR0YWNobWVudDogVGVtcGxhdGVSZWY8YW55PjtcclxuICBkaWFsb2dSZWZBZGRBdHRhY2htZW50OiBNYXREaWFsb2dSZWY8VGVtcGxhdGVSZWY8YW55Pj47XHJcbiAgQFZpZXdDaGlsZChcImRpYWxvZ0FkZE11bHRpcGxlQXR0YWNobWVudFwiLCB7IHN0YXRpYzogdHJ1ZSB9KSBkaWFsb2dBZGRNdWx0aXBsZUF0dGFjaG1lbnQ6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgZGlhbG9nUmVmQ3JvcEltYWdlOiBNYXREaWFsb2dSZWY8VGVtcGxhdGVSZWY8YW55Pj47XHJcbiAgQFZpZXdDaGlsZChcImRpYWxvZ0Nyb3BJbWFnZVwiLCB7IHN0YXRpYzogdHJ1ZSB9KSBkaWFsb2dDcm9wSW1hZ2U6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8vI3JlZ2lvbiBQcm9wcmlldMOgIHBlciBnZXN0aW9uZSByaWRpbWVuc2lvbmFtZW50byBmaWxlIGRpIHRpcG8gaW1hZ2VcclxuICBpbWFnZUNoYW5nZWRFdmVudDogYW55ID0gXCJcIjtcclxuICBjcm9wcGVkSW1hZ2U6IGFueSA9IFwiXCI7XHJcbiAgdHJhbnNmb3JtOiBJbWFnZVRyYW5zZm9ybSA9IHt9O1xyXG4gIGNhbnZhc1JvdGF0aW9uID0gMDtcclxuICBAVmlld0NoaWxkKEltYWdlQ3JvcHBlckNvbXBvbmVudCkgaW1hZ2VDcm9wcGVyOiBJbWFnZUNyb3BwZXJDb21wb25lbnQ7XHJcbiAgQFZpZXdDaGlsZChcImltYWdlSW5wdXRcIikgaW1hZ2VJbnB1dDogYW55O1xyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICBBdHRhY2htZW50VHlwZSA9IEF0dGFjaG1lbnRUeXBlO1xyXG4gIHNlbGVjdGVkQXR0YWNobWVudDogSUF0dGFjaG1lbnREVE87XHJcblxyXG4gIG9yaWdpbmFsV2lkdGg6IG51bWJlcjtcclxuICBvcmlnaW5hbEhlaWdodDogbnVtYmVyO1xyXG4gIGN1c3RvbVdpZHRoOiBudW1iZXI7XHJcbiAgY3VzdG9tSGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gIEBWaWV3Q2hpbGQoXCJhdHRhY2htZW50VGFibGVcIiwgeyBzdGF0aWM6IGZhbHNlIH0pIGF0dGFjaG1lbnRUYWJsZTogRXFwVGFibGVDb21wb25lbnQ7XHJcbiAgQFZpZXdDaGlsZChcImlubGluZVByZXZpZXdUZW1wbGF0ZVwiLCB7IHN0YXRpYzogdHJ1ZSB9KSBpbmxpbmVQcmV2aWV3VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQFZpZXdDaGlsZChcImRpYWxvZ1ByZXZpZXdcIiwgeyBzdGF0aWM6IHRydWUgfSkgZGlhbG9nUHJldmlldzogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgaW1hZ2VGaWxlOiBGaWxlO1xyXG5cclxuICBhZGRpbmdMaW5rTW9kZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXHJcbiAgICBwcml2YXRlIGZvcm1CdWlsZGVyOiBGb3JtQnVpbGRlcixcclxuICAgIHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIsXHJcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXHJcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIHByaXZhdGUgZXFwQXR0YWNobWVudFNlcnZpY2U6IEVxcEF0dGFjaG1lbnRTZXJ2aWNlXHJcbiAgKSB7fVxyXG5cclxuICBhc3luYyBuZ09uSW5pdCgpIHtcclxuICAgIC8vU2Ugw6ggc3RhdGEgcmljaGllc3RhIGxhIGdlc3Rpb25lIGRlbGxlIHNvbGUgaW1tYWdpbmkgYWxsb3JhIGltcG9zdGEgaWwgZmlsdHJvIHBlciBsZSBlc3RlbnNpb25pIHBvc3NpYmlsaSBkYSBjYXJpY2FyZVxyXG4gICAgaWYgKCF0aGlzLmFjY2VwdGVkRmlsZVR5cGVzKVxyXG4gICAgICBpZiAodGhpcy5hbGxvd09ubHlJbWFnZXMgPT0gdHJ1ZSkgdGhpcy5hY2NlcHRlZEZpbGVUeXBlcyA9IFwiaW1hZ2UvKlwiO1xyXG4gICAgICBlbHNlIHRoaXMuYWNjZXB0ZWRGaWxlVHlwZXMgPSBcIipcIjtcclxuXHJcbiAgICAvLyBTZSBub24gc29ubyBzdGF0aSBzcGVjaWZpY2F0aSBpIHRpcGkgZGEgZ2VzdGlyZSBtYSDDqCBzdGF0byBwYXNzYXRvIG51bGwgbyB1biBhcnJheSB2dW90byBpbXBvc3RvIGkgdGlwaSBkaSBkZWZhdWx0LlxyXG4gICAgaWYgKCF0aGlzLmFsbG93ZWRUeXBlcyB8fCB0aGlzLmFsbG93ZWRUeXBlcy5sZW5ndGggPT0gMClcclxuICAgICAgdGhpcy5hbGxvd2VkVHlwZXMgPSBbQXR0YWNobWVudFR5cGUuRklMRSwgQXR0YWNobWVudFR5cGUuTElOSywgQXR0YWNobWVudFR5cGUuRFJPUEJPWF07XHJcbiAgICBlbHNlIGlmIChcclxuICAgICAgdGhpcy5hbGxvd2VkVHlwZXMuZmluZCgodCkgPT4gdCAhPSBBdHRhY2htZW50VHlwZS5GSUxFICYmIHQgIT0gQXR0YWNobWVudFR5cGUuTElOSyAmJiB0ICE9IEF0dGFjaG1lbnRUeXBlLkRST1BCT1gpXHJcbiAgICApIHtcclxuICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuV2FybmluZyhcclxuICAgICAgICAnQWxtZW5vIHVubyBkZWdsaSBBdHRhY2htZW50VHlwZSBzZWxlemlvbmF0aSBuZWwgcGFyYW1ldHJvIFwiYWxsb3dlZFR5cGVzXCIgbm9uIGVzaXN0ZS4nXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuYWxsb3dlZFR5cGVzID0gW0F0dGFjaG1lbnRUeXBlLkZJTEUsIEF0dGFjaG1lbnRUeXBlLkxJTkssIEF0dGFjaG1lbnRUeXBlLkRST1BCT1hdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vU2Ugw6ggc3RhdGEgcmljaGllc3RhIGxhIGdlc3Rpb25lIG11bHRpcGxhIGRlZ2xpIGFsbGVnYXRpIGFsbG9yYSBjb25maWd1cmEgbCdlcXAtdGFibGVcclxuICAgIGlmICh0aGlzLm11bHRpcGxlQXR0YWNobWVudCA9PSB0cnVlICYmICghdGhpcy5hdHRhY2htZW50c0NvbHVtbnMgfHwgdGhpcy5hdHRhY2htZW50c0NvbHVtbnMubGVuZ3RoID09IDApKSB7XHJcbiAgICAgIHRoaXMuY29uZmlndXJlQ29sdW1ucygpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmF0dGFjaG1lbnRzTGlzdCA9PSBudWxsKSB0aGlzLmF0dGFjaG1lbnRzTGlzdCA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuXHJcbiAgICB0aGlzLmNoZWNrQXR0YWNobWVudEltYWdlKCk7XHJcblxyXG4gICAgaWYgKHRoaXMuYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDMpKSB7XHJcbiAgICAgIHRoaXMuZXFwQXR0YWNobWVudFNlcnZpY2UubG9hZERyb3Bib3hTY3JpcHQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyByZWxvYWREYXRhKCkge1xyXG4gICAgaWYgKHRoaXMuYXR0YWNobWVudFRhYmxlKSB0aGlzLmF0dGFjaG1lbnRUYWJsZS5yZWxvYWREYXRhdGFibGUoKTtcclxuICB9XHJcblxyXG4gIGNoZWNrQXR0YWNobWVudEltYWdlKCkge1xyXG4gICAgdGhpcy5hdHRhY2htZW50c0xpc3QuZm9yRWFjaCgoYSkgPT4ge1xyXG4gICAgICBhLklzSW1hZ2UgPSBBdHRhY2htZW50SGVscGVyU2VydmljZS5jaGVja0ltYWdlRnJvbU1pbWVUeXBlKGEuRmlsZUNvbnRlbnRUeXBlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8jcmVnaW9uIEdlc3Rpb25lIGVsZW5jbyBhbGxlZ2F0aVxyXG5cclxuICAvKipcclxuICAgKiBDb25maWd1cmEgbGUgY29sb25uZSBwZXIgbCdlcXAtdGFibGUgbmVsIGNhc28gaW4gY3VpIGlsIHBhcmFtZXRybyBcIm11bHRpcGxlQXR0YWNobWVudHNcIiDDqCBUUlVFLlxyXG4gICAqL1xyXG4gIGNvbmZpZ3VyZUNvbHVtbnMoKSB7XHJcbiAgICB0aGlzLmF0dGFjaG1lbnRzQ29sdW1ucyA9IFtdO1xyXG4gICAgaWYgKHRoaXMuZGlzYWJsZUFjdGlvbiAhPSB0cnVlKSB7XHJcbiAgICAgIHRoaXMuYXR0YWNobWVudHNDb2x1bW5zLnB1c2goe1xyXG4gICAgICAgIGtleTogXCJhY3Rpb25cIixcclxuICAgICAgICBkaXNwbGF5OiBcIlwiLFxyXG4gICAgICAgIHR5cGU6IFR5cGVDb2x1bW4uTWVudUFjdGlvbixcclxuICAgICAgICBidXR0b25NZW51SWNvbjogXCJtb3JlX3ZlcnRcIixcclxuICAgICAgICBzdHlsZXM6IHsgZmxleDogXCIwIDAgNiVcIiB9LFxyXG4gICAgICAgIGFjdGlvbnM6IFtcclxuICAgICAgICAgIHsgbmFtZTogdGhpcy5kZWxldGVMYWJlbCwgaWNvbjogXCJkZWxldGVcIiwgZm46IChlbGVtZW50LCBpbmRleCwgY29sKSA9PiB0aGlzLmRlbGV0ZUF0dGFjaG1lbnQoZWxlbWVudCkgfVxyXG4gICAgICAgIF1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGRvd25sb2FkQ29sdW1uID0ge1xyXG4gICAgICBrZXk6IFwiYXR0YWNobWVudFwiLFxyXG4gICAgICBkaXNwbGF5OiBcIlwiLFxyXG4gICAgICB0eXBlOiBUeXBlQ29sdW1uLlNpbXBsZUFjdGlvbixcclxuICAgICAgc3R5bGVzOiB7IGZsZXg6IFwiMCAwIDYlXCIgfSxcclxuICAgICAgYWN0aW9uczogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG5hbWU6IFwiXCIsXHJcbiAgICAgICAgICBmb250YXdlc29tZTogdHJ1ZSxcclxuICAgICAgICAgIGljb246IChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNob3dJbmxpbmVQcmV2aWV3XHJcbiAgICAgICAgICAgICAgPyBlbGVtZW50LkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkZJTEVcclxuICAgICAgICAgICAgICAgID8gXCJmYXMgZmEtY2xvdWQtZG93bmxvYWQtYWx0XCJcclxuICAgICAgICAgICAgICAgIDogXCJmYXMgZmEtZXh0ZXJuYWwtbGluay1hbHRcIlxyXG4gICAgICAgICAgICAgIDogdGhpcy5nZXRBdHRhY2htZW50SWNvbihlbGVtZW50KTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBmbjogKGVsZW1lbnQsIGNvbCwgZWxlbWVudEluZGV4KSA9PiB0aGlzLnZpZXdBdHRhY2htZW50KGVsZW1lbnQpLFxyXG4gICAgICAgICAgdG9vbHRpcDoge1xyXG4gICAgICAgICAgICB0b29sdGlwVGV4dDogKGVsZW1lbnQpID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudC5BdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5GSUxFID8gdGhpcy5kb3dubG9hZExhYmVsIDogdGhpcy5vcGVuTGlua0xhYmVsO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB0b29sdGlwUG9zaXRpb246IHRoaXMuZG93bmxvYWRUb29sdGlwUG9zaXRpb25cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH07XHJcblxyXG4gICAgbGV0IGlubGluZVByZXZpZXdDb2x1bW4gPSB7XHJcbiAgICAgIGtleTogXCJJbmxpbmVQcmV2aWV3XCIsXHJcbiAgICAgIGRpc3BsYXk6IHRoaXMucHJldmlld0xhYmVsLFxyXG4gICAgICB0eXBlOiBUeXBlQ29sdW1uLkV4dGVybmFsVGVtcGxhdGUsXHJcbiAgICAgIGV4dGVybmFsVGVtcGxhdGU6IHRoaXMuaW5saW5lUHJldmlld1RlbXBsYXRlLFxyXG4gICAgICBzdHlsZXM6IHsgZmxleDogXCIwIDAgMTAlXCIgfVxyXG4gICAgfTtcclxuXHJcbiAgICBsZXQgZmlsZU5hbWVDb2x1bW4gPSB7IGtleTogXCJGaWxlTmFtZVwiLCBkaXNwbGF5OiB0aGlzLmZpbGVOYW1lTGFiZWwgfTtcclxuXHJcbiAgICBpZiAodGhpcy5zaG93SW5saW5lUHJldmlldykge1xyXG4gICAgICB0aGlzLmF0dGFjaG1lbnRzQ29sdW1ucy5wdXNoKGlubGluZVByZXZpZXdDb2x1bW4pO1xyXG4gICAgICB0aGlzLmF0dGFjaG1lbnRzQ29sdW1ucy5wdXNoKGZpbGVOYW1lQ29sdW1uKTtcclxuICAgICAgdGhpcy5hdHRhY2htZW50c0NvbHVtbnMucHVzaChkb3dubG9hZENvbHVtbik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmF0dGFjaG1lbnRzQ29sdW1ucy5wdXNoKGRvd25sb2FkQ29sdW1uKTtcclxuICAgICAgdGhpcy5hdHRhY2htZW50c0NvbHVtbnMucHVzaChmaWxlTmFtZUNvbHVtbik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFbGltaW5hIHVuIGFsbGVnYXRvIGVsaW1pbmFuZG8gYW5jaGUgaWwgZmlsZSBwcmVzZW50ZSBuZWxsbyBzdG9yYWdlIGRpIGFyY2hpdmlhemlvbmUgdXRpbGl6emF0byAoQVdTIG8gY2FydGVsbGEgcHJvZ2V0dG8pXHJcbiAgICogQHBhcmFtIGVsZW1lbnQgSUF0dGFjaG1lbnREVE8gZGEgY2FuY2VsbGFyZVxyXG4gICAqL1xyXG4gIGRlbGV0ZUF0dGFjaG1lbnQoZWxlbWVudDogSUF0dGFjaG1lbnREVE8pIHtcclxuICAgIEVxcEF0dGFjaG1lbnREaWFsb2dTZXJ2aWNlLkNvbmZpcm0oXHJcbiAgICAgIHRoaXMuZGVsZXRlRGlhbG9nTWVzc2FnZSxcclxuICAgICAgKCkgPT4ge1xyXG4gICAgICAgIHRoaXMucmVtb3ZlQXR0YWNobWVudEZyb21MaXN0KHRoaXMuYXR0YWNobWVudHNMaXN0LmluZGV4T2YoZWxlbWVudCkpO1xyXG4gICAgICB9LFxyXG4gICAgICB0cnVlLFxyXG4gICAgICB0aGlzLmRlbGV0ZURpYWxvZ1RpdGxlXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmltdW92ZSBsJ2FsbGVnYXRvIHNlbGV6aW9uYXRvIGRhbGxhIGxpc3RhIFwiYXR0YWNobWVudHNMaXN0XCIgZSBpbnZvY2EgbCdldmVudG8gZGkgb3V0cHV0IGNoZSByZXN0aXR1aXNjZSBsYSBsaXN0YSBhZ2dpb3JuYXRhLlxyXG4gICAqIEBwYXJhbSBhdHRhY2htZW50SW5kZXggSW5kaWNlIGRlbGwnYXR0YWNobWVudCBkYSByaW11b3ZlcmVcclxuICAgKi9cclxuICByZW1vdmVBdHRhY2htZW50RnJvbUxpc3QoYXR0YWNobWVudEluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMub25EZWxldGVBdHRhY2htZW50LmVtaXQodGhpcy5hdHRhY2htZW50c0xpc3RbYXR0YWNobWVudEluZGV4XSk7XHJcblxyXG4gICAgdGhpcy5hdHRhY2htZW50c0xpc3Quc3BsaWNlKGF0dGFjaG1lbnRJbmRleCwgMSk7XHJcbiAgICBpZiAodGhpcy5hdHRhY2htZW50VGFibGUpIHRoaXMuYXR0YWNobWVudFRhYmxlLnJlbG9hZERhdGF0YWJsZSgpO1xyXG4gICAgdGhpcy5sb2NhbEVkaXRlZEF0dGFjaG1lbnRzLmVtaXQodGhpcy5hdHRhY2htZW50c0xpc3QpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2NhcmljYSBsJ2FsbGVnYXRvIG8gYXByZSBpbCBsaW5rXHJcbiAgICogQHBhcmFtIGVsZW1lbnQgQWxsZWdhdG8gZGEgbW9zdHJhcmVcclxuICAgKi9cclxuICB2aWV3QXR0YWNobWVudChhdHRhY2htZW50OiBJQXR0YWNobWVudERUTykge1xyXG4gICAgaWYgKGF0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSykge1xyXG4gICAgICB3aW5kb3cub3BlbihhdHRhY2htZW50LkZpbGVQYXRoLCBcIl9ibGFua1wiKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChhdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0ICYmIGF0dGFjaG1lbnQuRmlsZUNvbnRlbnRUeXBlICYmIGF0dGFjaG1lbnQuRmlsZU5hbWUpIHtcclxuICAgICAgbGV0IHNvdXJjZSA9IGBkYXRhOiR7YXR0YWNobWVudC5GaWxlQ29udGVudFR5cGV9O2Jhc2U2NCwke2F0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjR9YDtcclxuICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xyXG4gICAgICBsaW5rLmhyZWYgPSBzb3VyY2U7XHJcbiAgICAgIGxpbmsuZG93bmxvYWQgPSBgJHthdHRhY2htZW50LkZpbGVOYW1lfWA7XHJcbiAgICAgIGxpbmsuY2xpY2soKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZG93bmxvYWRBdHRhY2htZW50LmVtaXQoYXR0YWNobWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSaWRlZmluaXNjZSBsJ2ljb25hIGRhIG1vc3RyYXJlIG5lbGxhIGNvbG9ubmEgZGVsbCdlcXAtdGFibGUgcGVyIG9nbmkgZmlsZS5cclxuICAgKiBMJ2ljb25hIHZhcmlhIGluIGJhc2UgYWxsJ2VzdGVuc2lvbmUgZGVsIGZpbGVcclxuICAgKiBAcGFyYW0gYXR0YWNobWVudFxyXG4gICAqL1xyXG4gIGdldEF0dGFjaG1lbnRJY29uKGF0dGFjaG1lbnQ6IElBdHRhY2htZW50RFRPKSB7XHJcbiAgICBpZiAoYXR0YWNobWVudC5BdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5MSU5LKSByZXR1cm4gXCJmYXMgZmEtbGlua1wiO1xyXG4gICAgZWxzZSByZXR1cm4gQXR0YWNobWVudEhlbHBlclNlcnZpY2UuZ2V0SWNvbkZyb21GaWxlRXh0ZW5zaW9uZShhdHRhY2htZW50LkZpbGVFeHRlbnNpb24pO1xyXG4gIH1cclxuXHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8qKlxyXG4gICAqIEluIGNhc28gZGkgYWxsZWdhdG8gc2luZ29sbywgc2NlZ2xpZSBxdWFsZSBtZXRvZG8gcmljaGlhbWFyZSBpbiBiYXNlIGFsIHRpcG8gZGkgYWxsZWdhdG9cclxuICAgKi9cclxuICBhZGRGaWxlKGF0dGFjaG1lbnRUeXBlOiBBdHRhY2htZW50VHlwZSwgaW1hZ2VJbnB1dCA9IG51bGwpIHtcclxuICAgIGlmIChhdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5MSU5LKSB7XHJcbiAgICAgIHRoaXMuc3dpdGNoVG9BZGRpbmdMaW5rTW9kZSgpO1xyXG4gICAgfSBlbHNlIGlmIChhdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5GSUxFKSB7XHJcbiAgICAgIGltYWdlSW5wdXQuY2xpY2soKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuY2hvb3NlRHJvcGJveEZpbGUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNyZWF0ZUF0dGFjaG1lbnRGb3JtKCkge1xyXG4gICAgLy9DcmVhIGxhIGZvcm0gcGVyIGxhIHZhbGlkYXppb25lIGRlaSBjYW1waVxyXG4gICAgdGhpcy5uZXdBdHRhY2htZW50Rm9ybSA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xyXG4gICAgICB0eXBlOiBbdGhpcy5uZXdBdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcclxuICAgICAgbmFtZTogW3RoaXMubmV3QXR0YWNobWVudC5GaWxlTmFtZV0sXHJcbiAgICAgIHBhdGg6IFt0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZVBhdGhdLFxyXG4gICAgICBjdXN0b21IZWlnaHQ6IFt0aGlzLmN1c3RvbUhlaWdodF0sXHJcbiAgICAgIGN1c3RvbVdpZHRoOiBbdGhpcy5jdXN0b21XaWR0aF1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgY2xvc2UoZW1pdENsb3NlRXZlbnQgPSB0cnVlKSB7XHJcbiAgICB0aGlzLm5ld0F0dGFjaG1lbnQgPSB7fSBhcyBJQXR0YWNobWVudERUTztcclxuICAgIHRoaXMubmV3TXVsdGlwbGVBdHRhY2htZW50cyA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuICAgIHRoaXMuYWJvcnRGaWxlKCk7XHJcbiAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50Rm9ybSkgdGhpcy5uZXdBdHRhY2htZW50Rm9ybS5yZXNldCgpO1xyXG5cclxuICAgIHRoaXMuZGlhbG9nUmVmQ3JvcEltYWdlLmNsb3NlKCk7XHJcbiAgICB0aGlzLnJlc3RvcmVPcmlnaW5hbERpbWVuc2lvbnMoKTtcclxuXHJcbiAgICBpZiAoZW1pdENsb3NlRXZlbnQgPT0gdHJ1ZSAmJiB0aGlzLmFib3J0QWRkQXR0YWNobWVudCkgdGhpcy5hYm9ydEFkZEF0dGFjaG1lbnQuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW4gYmFzZSBhbCB0aXBvIGRpIGFsbGVnYXRvIGNvbnRyb2xsYSBzZSBkaXNhYmlsaXRhcmUgbyBtZW5vIGlsIHB1bHNhbnRlIHBlciBzYWx2YXJlLlxyXG4gICAqIEZ1bnppb25lIHVzYXRhIG5lbCBbZGlzYWJsZV0gZGVsIHB1bHNhbnRlIFwiU2FsdmFcIiBkZWwgZGlhbG9nIHBlciBsJ2FnZ2l1bnRhIGRpIHVuIGFsbGVnYXRvLlxyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgZGlzYWJsZVNhdmUoKSB7XHJcbiAgICBpZiAodGhpcy5sb2FkTXVsdGlwbGVGaWxlcyAhPSB0cnVlKSB7XHJcbiAgICAgIGlmICh0aGlzLm5ld0F0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuRklMRSkge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5uZXdBdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5uZXdBdHRhY2htZW50LkZpbGVQYXRoO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIHRoaXMubmV3TXVsdGlwbGVBdHRhY2htZW50cy5maWx0ZXIoXHJcbiAgICAgICAgICAocCkgPT5cclxuICAgICAgICAgICAgKHAuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuRklMRSAmJiAhcC5GaWxlRGF0YUJhc2U2NCkgfHxcclxuICAgICAgICAgICAgKHAuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSyAmJiAhcC5GaWxlUGF0aClcclxuICAgICAgICApLmxlbmd0aCA+IDBcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbmZpcm1BZGRBdHRhY2htZW50KCkge1xyXG4gICAgaWYgKHRoaXMubmV3QXR0YWNobWVudC5Jc0ltYWdlKSB7XHJcbiAgICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCA9IHRoaXMuaW1hZ2VDcm9wcGVyLmNyb3AoKS5iYXNlNjQuc3BsaXQoXCI7YmFzZTY0LFwiKVsxXTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5sb2FkTXVsdGlwbGVGaWxlcyAhPSB0cnVlKSB7XHJcbiAgICAgIGlmICh0aGlzLm5ld0F0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSyAmJiAhdGhpcy5uZXdBdHRhY2htZW50LkZpbGVOYW1lKVxyXG4gICAgICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlTmFtZSA9IHRoaXMubmV3QXR0YWNobWVudC5GaWxlUGF0aDtcclxuXHJcbiAgICAgIGlmICh0aGlzLmF0dGFjaG1lbnRzTGlzdCA9PSBudWxsKSB0aGlzLmF0dGFjaG1lbnRzTGlzdCA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuXHJcbiAgICAgIHRoaXMuYXR0YWNobWVudHNMaXN0LnB1c2godGhpcy5uZXdBdHRhY2htZW50KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICh0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPT0gbnVsbCB8fCB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMubGVuZ3RoID09IDApIHJldHVybjtcclxuXHJcbiAgICAgIGlmICh0aGlzLmF0dGFjaG1lbnRzTGlzdCA9PSBudWxsKSB0aGlzLmF0dGFjaG1lbnRzTGlzdCA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuXHJcbiAgICAgIHRoaXMuYXR0YWNobWVudHNMaXN0ID0gdGhpcy5hdHRhY2htZW50c0xpc3QuY29uY2F0KHRoaXMubmV3TXVsdGlwbGVBdHRhY2htZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuYXR0YWNobWVudFRhYmxlKSB0aGlzLmF0dGFjaG1lbnRUYWJsZS5yZWxvYWREYXRhdGFibGUoKTtcclxuXHJcbiAgICB0aGlzLmxvY2FsRWRpdGVkQXR0YWNobWVudHMuZW1pdCh0aGlzLmF0dGFjaG1lbnRzTGlzdCk7XHJcblxyXG4gICAgaWYgKHRoaXMubmV3QXR0YWNobWVudC5Jc0ltYWdlKSB7XHJcbiAgICAgIHRoaXMuZGlhbG9nUmVmQ3JvcEltYWdlLmNsb3NlKCk7XHJcbiAgICAgIHRoaXMucmVzdG9yZU9yaWdpbmFsRGltZW5zaW9ucygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQXByZSBpbCBkaWFsb2cgcGVyIGwnYW50ZXByaW1hIGRlbGwnYWxsZWdhdG8gc2VsZXppb25hdG8uXHJcbiAgICogQHBhcmFtIHJvd1xyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgYXN5bmMgb3BlblByZXZpZXdEaWFsb2cocm93OiBJQXR0YWNobWVudERUTykge1xyXG4gICAgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJvdykpO1xyXG5cclxuICAgIGlmICh0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5BdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5GSUxFKSB7XHJcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5GaWxlQ29udGVudFR5cGUuc3RhcnRzV2l0aChcInZpZGVvXCIpKSB7XHJcbiAgICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuV2FybmluZyh0aGlzLnZpZGVvUHJldmlld0Vycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVDb250ZW50VHlwZS5zdGFydHNXaXRoKFwiYXVkaW9cIikpIHtcclxuICAgICAgICBFcXBBdHRhY2htZW50RGlhbG9nU2VydmljZS5XYXJuaW5nKHRoaXMuYXVkaW9QcmV2aWV3RXJyb3JNZXNzYWdlKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5nZXRBdHRhY2htZW50RW5kcG9pbnQgJiYgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuSXNJbWFnZSAmJiAhdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjQpIHtcclxuICAgICAgYXdhaXQgdGhpcy5nZXRBdHRhY2htZW50QnlJRCgpXHJcbiAgICAgICAgLnRoZW4oKHJlcykgPT4ge1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjQgPSByZXMuRmlsZURhdGFCYXNlNjQ7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAuY2F0Y2goKGVycikgPT4ge1xyXG4gICAgICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuRXJyb3IoZXJyKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSykge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5UcnVzdGVkVXJsID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKFxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVQYXRoXHJcbiAgICAgICk7XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5Jc0ltYWdlICYmXHJcbiAgICAgICF0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCAmJlxyXG4gICAgICAhdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuRmlsZVRodW1ibmFpbEJhc2U2NFxyXG4gICAgKSB7XHJcbiAgICAgIEVxcEF0dGFjaG1lbnREaWFsb2dTZXJ2aWNlLkluZm8oXCJJbXBvc3NpYmlsZSBhcHJpcmUgbCdhbnRlcHJpbWEgZGVsbCdhbGxlZ2F0bywgZmlsZSBtYW5jYW50ZS5cIik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSBpZiAoIXRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LklzSW1hZ2UpIHtcclxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVQYXRoICYmIHRoaXMucHJvZHVjdGlvbkJhc2VVcmwpIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5UcnVzdGVkVXJsID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKFxyXG4gICAgICAgICAgXCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9ndmlldz91cmw9XCIgK1xyXG4gICAgICAgICAgICB0aGlzLnByb2R1Y3Rpb25CYXNlVXJsICtcclxuICAgICAgICAgICAgXCIvXCIgK1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5GaWxlUGF0aCArXHJcbiAgICAgICAgICAgIFwiJmVtYmVkZGVkPXRydWVcIlxyXG4gICAgICAgICk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuSW5mbyhcIkltcG9zc2liaWxlIGFwcmlyZSBsJ2FudGVwcmltYSBkZWwgZG9jdW1lbnRvIVwiKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmRpYWxvZy5vcGVuKHRoaXMuZGlhbG9nUHJldmlldywge1xyXG4gICAgICBkaXNhYmxlQ2xvc2U6IHRydWUsXHJcbiAgICAgIGhhc0JhY2tkcm9wOiB0cnVlXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGdldEF0dGFjaG1lbnRCeUlEKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PElBdHRhY2htZW50RFRPPih0aGlzLmdldEF0dGFjaG1lbnRFbmRwb2ludCwgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQpLnRvUHJvbWlzZSgpO1xyXG4gIH1cclxuXHJcbiAgLy8jcmVnaW9uIEdlc3Rpb25lIGNhcmljYW1lbnRvIGZpbGVcclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnRvIHNjYXRlbmF0byBhbGxhIHNlbGV6aW9uZSBkZWwgZmlsZSAobyBkZWkgZmlsZSkuXHJcbiAgICogU2UgaWwgY2FyaWNhbWVudG8gw6ggU0lOR09MTyBvIHNlIGNvbXVucXVlIMOoIHN0YXRvIHNlbGV6aW9uYXRvIHVuIHNvbG8gZmlsZSBhbGxvcmEgc2kgb2NjdXBhIGRpIGNvbnRyb2xsYXJlIHNlIHNpIHRyYXR0YSBkaSB1biBpbW1hZ2luZSBpbiBtb2RvIGRhXHJcbiAgICogbW9zdHJhcmUgbGUgZnVuemlvbmFsaXTDoCBkZWwgY3JvcHBpZSAocGVyIHJpdGFnbGlhcmUgbCdpbW1hZ2luZSkgb3BwdXJlIG5vLlxyXG4gICAqIFNlIGlsIGZpbGUgY2FyaWNhdG8gbm9uIMOoIHVuIGltbWFnaW5lIGFsbG9yYSBnZW5lcmEgZGlyZXR0YW1lbnRlIGlsIGJhc2U2NCBlIGxvIGFzc29jaWEgYWxsJ2FsbGVnYXRvIGRhIHNhbHZhcmUuXHJcbiAgICogU2UgaW52ZWNlIGlsIGNhcmljYW1lbnRvIGRlaSBmaWxlIMOoIE1VTFRJUExPIGUgc29ubyBwcmVzZW50aSBwacO5IGZpbGUgYWxsb3JhIGVzZWd1ZSBsZSBzdGVzc2Ugb3BlcmF6aW9uaSBpZ25vcmFuZG8gcGVyw7IgaWwgY29udHJsbG9cclxuICAgKiBpbW1hZ2luZSBwZXIgaWwgY3JvcHBpZSAoaW4gY2FzbyBkaSBjYXJpY2FtZW50byBtdWx0aXBsbyBsZSBmdW56aW9uYWxpdMOgIGRlbCBjcm9wcGllIHNvbm8gZGlzYWJpbGl0YXRlKS5cclxuICAgKi9cclxuICBhc3luYyBvbkZpbGVBZGRlZChldmVudCwgaXNGaWxlRHJvcHBlZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICB0aGlzLnNob3dDcm9wSW1hZ2UgPSBmYWxzZTtcclxuICAgIGxldCBmaWxlc09uSW5wdXQgPSBpc0ZpbGVEcm9wcGVkID8gZXZlbnQgOiBldmVudC50YXJnZXQuZmlsZXM7XHJcblxyXG4gICAgLy9TZSDDqCBzdGF0byByaWNoaWVzdG8gaWwgY2FyaWNhbWVudG8gU0lOR09MTyBvcHB1cmUgc2UgaWwgY2FyaWNhbWVudG8gw6ggTVVMVElQTE8gbWEgw6ggc3RhdG8gc2VsZXppb25hdG8gdW4gc29sbyBmaWxlXHJcbiAgICAvL2FsbG9yYSB2ZXJpZmljYSBzZSBpbCBmaWxlIMOoIHVuIGltbWFnaW5lIChwZXIgbW9zdHJhcmUgaWwgQ1JPUFBJRSlcclxuICAgIGlmIChbLi4uZmlsZXNPbklucHV0XS5sZW5ndGggPT0gMSB8fCB0aGlzLmxvYWRNdWx0aXBsZUZpbGVzICE9IHRydWUpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpbGUgPSBmaWxlc09uSW5wdXRbMF07XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlcyA9IGZpbGVzT25JbnB1dDtcclxuICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkRmlsZSkgcmV0dXJuO1xyXG5cclxuICAgICAgLy9NZW1vcml6emEgaSBkYXRpIHBlciBsJ2FsbGVnYXRvXHJcbiAgICAgIHRoaXMubmV3QXR0YWNobWVudCA9IGF3YWl0IHRoaXMuY3JlYXRlQXR0YWNobWVudEZyb21VcGxvYWRlZEZpbGUodGhpcy5zZWxlY3RlZEZpbGUsIGZhbHNlKTtcclxuICAgICAgdGhpcy5uZXdNdWx0aXBsZUF0dGFjaG1lbnRzID0gbmV3IEFycmF5PElBdHRhY2htZW50RFRPPigpO1xyXG4gICAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMucHVzaCh0aGlzLm5ld0F0dGFjaG1lbnQpO1xyXG5cclxuICAgICAgLy9TZSDDqCBzdGF0YSByaWNoaWVzdGEgbGEgZ2VzdGlvbmUgZGVsbGUgc29sZSBpbW1hZ2luaSBtYSBwZXIgZXJyb3JlIMOoIHN0YXRvIHNlbGV6aW9uYXRvIHVuIGZpbGUgY2hlIG5vbiDDqCB1biBpbW1hZ2luZVxyXG4gICAgICBsZXQgY2hlY2tPbmx5SW1hZ2UgPSB0aGlzLmNoZWNrQWxsb3dPbmx5SW1hZ2VGaWxlKHRoaXMubmV3QXR0YWNobWVudCk7XHJcbiAgICAgIGlmIChjaGVja09ubHlJbWFnZSA9PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgdGhpcy5jcmVhdGVBdHRhY2htZW50Rm9ybSgpO1xyXG5cclxuICAgICAgLy9WZXJpZmljYSBzZSBpbCBmaWxlIGNhcmljYXRvIMOoIHVuJ2ltbWFnaW5lIG9wcHVyZSBuby4gU2Ugw6ggdW4gaW1tYWdpbmUsIHByaW1hIGRpIGNhcmljYXJsYSBtb3N0cmEgaWwgY3JvcHBpZSBwZXIgaWwgcmVzaXplLlxyXG4gICAgICAvL1NlIG5vbiDDqCB1biBpbW1hZ2luZSBhbGxvcmEgZ2VuZXJhIGlsIEJhc2U2NFxyXG4gICAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50LklzSW1hZ2UgPT0gdHJ1ZSkge1xyXG4gICAgICAgIHRoaXMuZ2V0SW1hZ2VEaW1lbnNpb25zKGZpbGVzT25JbnB1dFswXSk7XHJcblxyXG4gICAgICAgIC8vTW9zdHJhIGlsIGNyb3BwaWUgZSBkaXNhYmlsaXRhIGxhIGZvcm0gZmluY2jDqCBub24gdGVybWluYSBsYSBtb2RpZmljYSBkZWxsJ2ltbWFnaW5lXHJcbiAgICAgICAgdGhpcy5uZXdBdHRhY2htZW50Rm9ybS5kaXNhYmxlKCk7XHJcbiAgICAgICAgdGhpcy5uZXdBdHRhY2htZW50Rm9ybS5jb250cm9sc1tcImN1c3RvbVdpZHRoXCJdLmVuYWJsZSgpO1xyXG4gICAgICAgIHRoaXMubmV3QXR0YWNobWVudEZvcm0uY29udHJvbHNbXCJjdXN0b21IZWlnaHRcIl0uZW5hYmxlKCk7XHJcbiAgICAgICAgdGhpcy5zaG93Q3JvcEltYWdlID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmltYWdlRmlsZSA9IGV2ZW50O1xyXG5cclxuICAgICAgICB0aGlzLmRpYWxvZ1JlZkNyb3BJbWFnZSA9IHRoaXMuZGlhbG9nLm9wZW4odGhpcy5kaWFsb2dDcm9wSW1hZ2UsIHtcclxuICAgICAgICAgIGRpc2FibGVDbG9zZTogdHJ1ZSxcclxuICAgICAgICAgIGhhc0JhY2tkcm9wOiB0cnVlLFxyXG4gICAgICAgICAgd2lkdGg6IFwiNjAlXCIsXHJcbiAgICAgICAgICBtYXhIZWlnaHQ6IFwiODAlXCIsXHJcbiAgICAgICAgICBtYXhXaWR0aDogXCI3MHZoXCJcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnNob3dDcm9wSW1hZ2UgPSBmYWxzZTtcclxuICAgICAgICBsZXQgYmFzZTY0UmVzdWx0ID0gYXdhaXQgdGhpcy5nZXRCYXNlNjRGcm9tRmlsZSh0aGlzLnNlbGVjdGVkRmlsZSk7XHJcbiAgICAgICAgdGhpcy5uZXdBdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0ID0gYmFzZTY0UmVzdWx0LkJhc2U2NEZpbGU7XHJcbiAgICAgICAgdGhpcy5uZXdBdHRhY2htZW50LkZpbGVDb250ZW50VHlwZSA9IGJhc2U2NFJlc3VsdC5Db250ZW50VHlwZTtcclxuICAgICAgICB0aGlzLmNvbmZpcm1BZGRBdHRhY2htZW50KCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlcyA9IGZpbGVzT25JbnB1dDtcclxuICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkRmlsZXMgfHwgdGhpcy5zZWxlY3RlZEZpbGVzLmxlbmd0aCA9PSAwKSByZXR1cm47XHJcblxyXG4gICAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPSBuZXcgQXJyYXk8SUF0dGFjaG1lbnREVE8+KCk7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWxlY3RlZEZpbGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IG5ld0F0dGFjaG1lbnQ6IElBdHRhY2htZW50RFRPID0gYXdhaXQgdGhpcy5jcmVhdGVBdHRhY2htZW50RnJvbVVwbG9hZGVkRmlsZShcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlc1tpXSxcclxuICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICB0cnVlXHJcbiAgICAgICAgKTtcclxuICAgICAgICAvL1NlIMOoIHN0YXRhIHJpY2hpZXN0YSBsYSBnZXN0aW9uZSBkZWxsZSBzb2xlIGltbWFnaW5pIG1hIHBlciBlcnJvcmUgw6ggc3RhdG8gc2VsZXppb25hdG8gdW4gZmlsZSBjaGUgbm9uIMOoIHVuIGltbWFnaW5lXHJcbiAgICAgICAgbGV0IGNoZWNrT25seUltYWdlID0gdGhpcy5jaGVja0FsbG93T25seUltYWdlRmlsZShuZXdBdHRhY2htZW50KTtcclxuICAgICAgICBpZiAoY2hlY2tPbmx5SW1hZ2UgPT0gZmFsc2UpIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5uZXdNdWx0aXBsZUF0dGFjaG1lbnRzLnB1c2gobmV3QXR0YWNobWVudCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jb25maXJtQWRkQXR0YWNobWVudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vUmVzZXR0byBpbCB2YWxvcmUgZGVsIGZpbGUgaW5wdXQgaW4gbW9kbyBkYSBzY2F0ZW5hcmUgaWwgY2hhbmdlIGFuY2hlIHNlIHNpIGRvdmVzc2UgY2FyaWNhcmUgbG8gc3Rlc3NvIGZpbGVcclxuICAgIGlmICghaXNGaWxlRHJvcHBlZCkgZXZlbnQudGFyZ2V0LnZhbHVlID0gXCJcIjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgcGFydGlyZSBkYWwgRklMRSByaWNldnV0byBpbiBpbnB1dCByaWNvc3RydWlzY2UgbCdvZ2dldHRvIElBdHRhY2htZW50RFRPIGUgbG8gcmVzdGl0dWlzY2UuXHJcbiAgICogU2UgaWwgcGFyYW1ldHJvIGdldEJhc2U2NCB2aWVuZSBwYXNzYXRvIGEgVFJVRSBhbGxvcmEsIHNlbXByZSBhIHBhcnRpcmUgZGFsIGZpbGUsZ2VuZXJhIGlsIGJhc2U2NCBlXHJcbiAgICogcmljYXZhIGlsIENvbnRlbnRUeXBlIGRhIGFzc29jaWFyZSBhbGwnb2dnZXR0byBJQXR0YWNobWVudERUTyBkYSByZXN0aXR1aXJlXHJcbiAgICogQHBhcmFtIGN1cnJlbnRGaWxlIE9nZ2V0dG8gRklMRSBkYSBwcm9jZXNzYXJlXHJcbiAgICogQHBhcmFtIGdldEJhc2U2NCBTZSBUUlVFIGFsbG9yYSBjYWxjb2xhIGJhc2U2NCBlIENvbnRlbnRUeXBlIGRlbCBmaWxlIHBhc3NhdG8gaW4gaW5wdXRcclxuICAgKiBAcmV0dXJucyBSZXN0aXR1aXNjZSB1biBvZ2dldHRvIGRpIHRpcG8gSUF0dGFjaG1lbnREVE9cclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZUF0dGFjaG1lbnRGcm9tVXBsb2FkZWRGaWxlKFxyXG4gICAgY3VycmVudEZpbGU6IEZpbGUsXHJcbiAgICBnZXRCYXNlNjQ6IGJvb2xlYW4gPSB0cnVlLFxyXG4gICAgY3JvcEZpbGU6IGJvb2xlYW4gPSBmYWxzZVxyXG4gICk6IFByb21pc2U8SUF0dGFjaG1lbnREVE8+IHtcclxuICAgIGxldCBuZXdBdHRhY2htZW50OiBJQXR0YWNobWVudERUTyA9IHt9IGFzIElBdHRhY2htZW50RFRPO1xyXG4gICAgLy9NZW1vcml6emEgaSBkYXRpIHBlciBsJ2FsbGVnYXRvXHJcbiAgICBuZXdBdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlID0gQXR0YWNobWVudFR5cGUuRklMRTtcclxuICAgIG5ld0F0dGFjaG1lbnQuRmlsZUNvbnRlbnRUeXBlID0gY3VycmVudEZpbGUudHlwZTtcclxuICAgIG5ld0F0dGFjaG1lbnQuRmlsZU5hbWUgPSBjdXJyZW50RmlsZS5uYW1lO1xyXG4gICAgbmV3QXR0YWNobWVudC5GaWxlRXh0ZW5zaW9uID0gY3VycmVudEZpbGUubmFtZS5zdWJzdHIoY3VycmVudEZpbGUubmFtZS5sYXN0SW5kZXhPZihcIi5cIikgKyAxKTtcclxuICAgIG5ld0F0dGFjaG1lbnQuSXNJbWFnZSA9IEF0dGFjaG1lbnRIZWxwZXJTZXJ2aWNlLmNoZWNrSW1hZ2VGcm9tTWltZVR5cGUoY3VycmVudEZpbGUudHlwZSk7XHJcblxyXG4gICAgaWYgKGdldEJhc2U2NCA9PSB0cnVlKSB7XHJcbiAgICAgIGxldCBiYXNlNjRSZXN1bHQgPSBhd2FpdCB0aGlzLmdldEJhc2U2NEZyb21GaWxlKGN1cnJlbnRGaWxlKTtcclxuICAgICAgbmV3QXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCA9IGJhc2U2NFJlc3VsdC5CYXNlNjRGaWxlO1xyXG4gICAgICBuZXdBdHRhY2htZW50LkZpbGVDb250ZW50VHlwZSA9IGJhc2U2NFJlc3VsdC5Db250ZW50VHlwZTtcclxuXHJcbiAgICAgIGlmIChuZXdBdHRhY2htZW50LklzSW1hZ2UgJiYgbmV3QXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCAmJiBjcm9wRmlsZSkge1xyXG4gICAgICAgIHRoaXMuZ2V0Q3JvcHBlZEFuZFVwbG9hZChgZGF0YToke2Jhc2U2NFJlc3VsdC5Db250ZW50VHlwZX07YmFzZTY0LCR7YmFzZTY0UmVzdWx0LkJhc2U2NEZpbGV9YCwgbmV3QXR0YWNobWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbmV3QXR0YWNobWVudDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgcGFydGlyZSBkYWwgZmlsZSBwYXNzYXRvIGluIGlucHV0IHJlc3RpdHVpc2NlIHVuIG9nZ2V0dG9cclxuICAgKiBjb250ZW5lbnRlIGlsIGJhc2U2NCBkZWwgZmlsZSBlIGlsIHN1byBjb250ZW50VHlwZVxyXG4gICAqIEBwYXJhbSBjdXJyZW50RmlsZSBPZ2dldHRvIEZpbGUgZGEgY3VpIGVzdHJhcG9sYXJlIGJhc2U2NCBlIGNvbnRlbnRUeXBlXHJcbiAgICogQHJldHVybnMgUmVzdGl0dWlzY2UgdW4gb2dnZXR0byBhdmVudGUgbGUgcHJvcHJpZXTDoCBCYXNlNjRGaWxlIGUgQ29udGVudFR5cGVcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGdldEJhc2U2NEZyb21GaWxlKGN1cnJlbnRGaWxlOiBGaWxlKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGxldCBiYXNlNjRGaWxlID0gYXdhaXQgdG9CYXNlNjQoY3VycmVudEZpbGUpO1xyXG4gICAgbGV0IGNvbnRlbnRUeXBlOiBzdHJpbmcgPSBudWxsO1xyXG4gICAgaWYgKGJhc2U2NEZpbGUpIHtcclxuICAgICAgLy8gTG9yaXMgMjAvMDEvMjAyMjogUFJPQkxFTUEgLSBRdWFuZG8gZXNlZ3VvIGwndXBsb2FkIGRpIHVuIGZpbGUgLnNxbCBub24gdmllbmUgc2FsdmF0by9zY2FyaWNhdG8gY29ycmV0dGFtZW50ZS5cclxuICAgICAgLy8gICAgICAgICAgICAgICAgICAgUXVlc3RvIHN1Y2NlZGUgcGVyY2jDqCBub24gdmllbmUgcG9wb2xhdG8gaWwgRmlsZUNvbnRlbnRUeXBlLiBQZXIgcmlzb2x2ZXJlIGlsIHByb2JsZW1hXHJcbiAgICAgIC8vICAgICAgICAgICAgICAgICAgIGZhY2NpbyB1biBjb250cm9sbG8gZSBzZSBub24gZXNpc3RlIGlsIEZpbGVDb250ZW50VHlwZSBhbGxvcmEgbG8gcmVjdXBlcm8gZGFsIGJhc2U2NCBvdHRlbnV0by5cclxuICAgICAgY29udGVudFR5cGUgPSBiYXNlNjRGaWxlLnNwbGl0KFwiLFwiKVswXS5zcGxpdChcIjpcIilbMV0uc3BsaXQoXCI7XCIpWzBdO1xyXG4gICAgICAvLyBVbiBhbHRybyBtZXRvZG8gcGVyIGxlZ2dlcmUgaWwgY2NvbnRlbnQgdHlwZSBkZWwgZmlsZSDDqCB0cmFtaXRlIHVuYSByZWd1bGFyIGV4cHJlc3Npb246XHJcbiAgICAgIGJhc2U2NEZpbGUgPSBiYXNlNjRGaWxlLnNwbGl0KFwiLFwiKVsxXTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcmVzdWx0ID0ge1xyXG4gICAgICBCYXNlNjRGaWxlOiBiYXNlNjRGaWxlLFxyXG4gICAgICBDb250ZW50VHlwZTogY29udGVudFR5cGVcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnRyb2xsYSBzZSBpbCBmaWxlIGNoZSBzaSBzdGEgY2FyaWNhbmRvIMOoIHN1cHBvcnRhdG8gZGFsIHNpc3RlbWEuXHJcbiAgICogQHJldHVybnNcclxuICAgKi9cclxuICBwcml2YXRlIGNoZWNrQWNjZXB0ZWRGaWxlcygpOiBib29sZWFuIHtcclxuICAgIGlmIChcclxuICAgICAgKHRoaXMubG9hZE11bHRpcGxlRmlsZXMgIT0gdHJ1ZSAmJiB0aGlzLnNlbGVjdGVkRmlsZS50eXBlLnN0YXJ0c1dpdGgoXCJ2aWRlb1wiKSkgfHxcclxuICAgICAgKHRoaXMubG9hZE11bHRpcGxlRmlsZXMgPT0gdHJ1ZSAmJiBbLi4udGhpcy5zZWxlY3RlZEZpbGVzXS5maWx0ZXIoKHApID0+IHAudHlwZS5zdGFydHNXaXRoKFwidmlkZW9cIikpLmxlbmd0aCA+IDApXHJcbiAgICApXHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICBpZiAodGhpcy5hY2NlcHRlZEZpbGVUeXBlcyA9PSBcIipcIikgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgLy9WZXJpZmljYSBjaGUgaSB0aXBpIGRlbCBmaWxlIChvIGRlaSBmaWxlKSBjYXJpY2F0aSBzaWFubyBjb2VyZW50aSBjb24gcXVlbGxpIGFjY2V0dGF0aSBkYWxsYSBkaXJldHRpdmFcclxuICAgIGxldCBhY2NlcHRlZDogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBpZiAodGhpcy5sb2FkTXVsdGlwbGVGaWxlcyAhPSB0cnVlKSBhY2NlcHRlZCA9IHRoaXMuYWNjZXB0ZWRGaWxlVHlwZXMuaW5jbHVkZXModGhpcy5zZWxlY3RlZEZpbGUudHlwZSk7XHJcbiAgICBlbHNlIHtcclxuICAgICAgbGV0IHVwbG9hZGVkRmlsZVR5cGVzOiBzdHJpbmdbXSA9IFsuLi50aGlzLnNlbGVjdGVkRmlsZXNdLm1hcCgocCkgPT4gcC50eXBlKTtcclxuICAgICAgdXBsb2FkZWRGaWxlVHlwZXMuZm9yRWFjaCgodHlwZSkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy5hY2NlcHRlZEZpbGVUeXBlcy5pbmNsdWRlcyh0eXBlKSkgYWNjZXB0ZWQgPSBmYWxzZTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy9RdWVzdG8gY29udHJvbGxvIHBlcm1ldHRlIGRpIGdlc3RpcmUgbGUgY2FzaXN0aWNoZSBwZXIgY3VpIHZlbmdvbm8gaW5kaWNhdGkgY29tZSB0aXBpIHZhbGlkaSwgYWQgZXNlbXBpbywgJ2ltYWdlLyonXHJcbiAgICBpZiAoIWFjY2VwdGVkICYmIHRoaXMubG9hZE11bHRpcGxlRmlsZXMgIT0gdHJ1ZSkge1xyXG4gICAgICBmb3IgKGxldCB0IG9mIHRoaXMuYWNjZXB0ZWRGaWxlVHlwZXMuc3BsaXQoXCIsXCIpLmZpbHRlcigodCkgPT4gdC5pbmNsdWRlcyhcIipcIikpKSB7XHJcbiAgICAgICAgYWNjZXB0ZWQgPSB0aGlzLnNlbGVjdGVkRmlsZS50eXBlLnN0YXJ0c1dpdGgodC5zcGxpdChcIipcIilbMF0pO1xyXG4gICAgICAgIGlmIChhY2NlcHRlZCkgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBhY2NlcHRlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlIGVxcC1hdHRhY2htZW50cyDDqCBzdGF0YSBjb25maWd1cmF0YSBwZXIgaWwgY2FyaWNhbWVudG8gZGVsbGUgc29sZSBpbW1hZ2luaSBhbGxvcmEgdmVyaWZpY2EgY2hlIGlsIGZpbGUgcGFzc2F0byBpblxyXG4gICAqIGlucHV0IHNpYSBlZmZldHRpdmFtZW50ZSB1biBpbW1hZ2luZSBvIG5vLlxyXG4gICAqIFNlIGlsIGNvbnRyb2xsbyB2YSBhIGJ1b24gZmluZSByZXN0aXR1aXNjZSBUUlVFIGFsdHJpbWVudGkgbW9zdHJhIHVuIG1lc3NhZ2dpbyBkJ2Vycm9yZSBlIHJlc3RpdHVpc2NlIEZBTFNFXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjaGVja0FsbG93T25seUltYWdlRmlsZShuZXdBdHRhY2htZW50KTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5hbGxvd09ubHlJbWFnZXMgPT0gdHJ1ZSAmJiBuZXdBdHRhY2htZW50LklzSW1hZ2UgIT0gdHJ1ZSkge1xyXG4gICAgICBFcXBBdHRhY2htZW50RGlhbG9nU2VydmljZS5FcnJvcih0aGlzLm5vSW1hZ2VTZWxlY3RlZEVycm9yTWVzc2FnZSk7XHJcbiAgICAgIHRoaXMuYWJvcnRGaWxlKCk7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0gZWxzZSBpZiAoIXRoaXMuY2hlY2tBY2NlcHRlZEZpbGVzKCkpIHtcclxuICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuRXJyb3IodGhpcy53cm9uZ1R5cGVTZWxlY3RlZEVycm9yTWVzc2FnZSk7XHJcbiAgICAgIHRoaXMuYWJvcnRGaWxlKCk7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8vI3JlZ2lvbiBHZXN0aW9uZSBjcm9wIGZpbGVcclxuXHJcbiAgZ2V0SW1hZ2VEaW1lbnNpb25zKGltZzogYW55KSB7XHJcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG4gICAgcmVhZGVyLm9ubG9hZCA9IChlOiBhbnkpID0+IHtcclxuICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcclxuICAgICAgaW1hZ2Uuc3JjID0gZS50YXJnZXQucmVzdWx0O1xyXG4gICAgICBpbWFnZS5vbmxvYWQgPSAocnMpID0+IHtcclxuICAgICAgICB0aGlzLm9yaWdpbmFsSGVpZ2h0ID0gcnMuY3VycmVudFRhcmdldFtcImhlaWdodFwiXTtcclxuICAgICAgICB0aGlzLm9yaWdpbmFsV2lkdGggPSBycy5jdXJyZW50VGFyZ2V0W1wid2lkdGhcIl07XHJcblxyXG4gICAgICAgIGlmICh0aGlzLm9yaWdpbmFsV2lkdGggPiAxMjgwKSB7XHJcbiAgICAgICAgICB0aGlzLmN1c3RvbVdpZHRoID0gMTI4MDtcclxuICAgICAgICAgIHRoaXMuY3VzdG9tSGVpZ2h0ID0gTWF0aC5yb3VuZCgoMTI4MCAqIHRoaXMub3JpZ2luYWxIZWlnaHQpIC8gdGhpcy5vcmlnaW5hbFdpZHRoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5jdXN0b21IZWlnaHQgPSBycy5jdXJyZW50VGFyZ2V0W1wiaGVpZ2h0XCJdO1xyXG4gICAgICAgICAgdGhpcy5jdXN0b21XaWR0aCA9IHJzLmN1cnJlbnRUYXJnZXRbXCJ3aWR0aFwiXTtcclxuICAgICAgICB9XHJcbiAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoaW1nKTtcclxuICB9XHJcblxyXG4gIHJlc3RvcmVPcmlnaW5hbERpbWVuc2lvbnMoKSB7XHJcbiAgICB0aGlzLmN1c3RvbVdpZHRoID0gdGhpcy5vcmlnaW5hbFdpZHRoO1xyXG4gICAgdGhpcy5jdXN0b21IZWlnaHQgPSB0aGlzLm9yaWdpbmFsSGVpZ2h0O1xyXG4gICAgdGhpcy5jYW52YXNSb3RhdGlvbiA9IDA7XHJcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHt9O1xyXG4gIH1cclxuXHJcbiAgb25EaW1lbnNpb25zQ2hhbmdlKGRpbWVuc2lvbjogc3RyaW5nKSB7XHJcbiAgICBpZiAoZGltZW5zaW9uID09IFwiSFwiKSB7XHJcbiAgICAgIHRoaXMuY3VzdG9tV2lkdGggPSBNYXRoLnJvdW5kKCh0aGlzLmN1c3RvbUhlaWdodCAqIHRoaXMub3JpZ2luYWxXaWR0aCkgLyB0aGlzLm9yaWdpbmFsSGVpZ2h0KTtcclxuICAgIH0gZWxzZSBpZiAoZGltZW5zaW9uID09IFwiV1wiKSB7XHJcbiAgICAgIHRoaXMuY3VzdG9tSGVpZ2h0ID0gTWF0aC5yb3VuZCgodGhpcy5jdXN0b21XaWR0aCAqIHRoaXMub3JpZ2luYWxIZWlnaHQpIC8gdGhpcy5vcmlnaW5hbFdpZHRoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGltYWdlQ3JvcHBlZChldmVudDogSW1hZ2VDcm9wcGVkRXZlbnQpIHtcclxuICAgIHRoaXMuY3JvcHBlZEltYWdlID0gZXZlbnQuYmFzZTY0O1xyXG4gICAgdGhpcy5nZXRDcm9wcGVkQW5kVXBsb2FkKHRoaXMuY3JvcHBlZEltYWdlLCB0aGlzLm5ld0F0dGFjaG1lbnQpO1xyXG4gIH1cclxuXHJcbiAgZ2V0Q3JvcHBlZEFuZFVwbG9hZChmaWxlLCBuZXdBdHRhY2htZW50OiBJQXR0YWNobWVudERUTykge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIHZhciBmaWxlOiBhbnkgPSBiYXNlNjRUb0ZpbGUoZmlsZSk7XHJcblxyXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY29tcHJlc3Npb25PcHRpb25zO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcHJpbWUgbCdpbW1hZ2luZSBwYXNzYW5kbyBjb21lIHBhcmFtZXRyaSBsZSBvcHRpb25zIGNyZWF0ZSBuZWxsJ29nZ2V0dG8gc29wcmEsIGUgaWwgZmlsZSBkYWwgcmVhZGVyIHByaW5jaXBhbGVcclxuICAgICAqL1xyXG4gICAgaW1hZ2VDb21wcmVzc2lvbihmaWxlLCBvcHRpb25zKS50aGVuKChmaWxlQ29tcHJlc3NlZCkgPT4ge1xyXG4gICAgICBsZXQgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcblxyXG4gICAgICAvL0ZhY2NpbyBsYSBwdXNoIGRpIG9nbmkgZmlsZSBhbGwnaW50ZXJubyBkZWxsJ2FycmF5IGRpIGZpbGUgZGVsbCdpdGVtIGRhIG1hbmRhcmUgYWwgc2VydmVyXHJcbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGxldCByZXN1bHRSZWFkZXIgPSA8c3RyaW5nPmZpbGVSZWFkZXIucmVzdWx0O1xyXG4gICAgICAgIHZhciBtYXJrZXIgPSBcIjtiYXNlNjQsXCI7XHJcbiAgICAgICAgbmV3QXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCA9IHJlc3VsdFJlYWRlci5zdWJzdHJpbmcocmVzdWx0UmVhZGVyLmluZGV4T2YobWFya2VyKSArIG1hcmtlci5sZW5ndGgpO1xyXG4gICAgICAgIHNlbGYuc2hvd0Nyb3BJbWFnZSA9IGZhbHNlO1xyXG4gICAgICAgIGlmIChzZWxmLm5ld0F0dGFjaG1lbnRGb3JtKSB7XHJcbiAgICAgICAgICBzZWxmLm5ld0F0dGFjaG1lbnRGb3JtLmVuYWJsZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIGZpbGVSZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlQ29tcHJlc3NlZCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIGNvbmZpcm1Dcm9wKCkge1xyXG4gIC8vICAgdGhpcy5pbWFnZUNyb3BwZXIuY3JvcCgpO1xyXG4gIC8vICAgdGhpcy5kaWFsb2dSZWZDcm9wSW1hZ2UuY2xvc2UoKTtcclxuICAvLyAgIHRoaXMucmVzdG9yZU9yaWdpbmFsRGltZW5zaW9ucygpO1xyXG4gIC8vIH1cclxuXHJcbiAgcm90YXRlTGVmdCgpIHtcclxuICAgIHRoaXMuY2FudmFzUm90YXRpb24tLTtcclxuICAgIHRoaXMuZmxpcEFmdGVyUm90YXRlKCk7XHJcbiAgfVxyXG5cclxuICByb3RhdGVSaWdodCgpIHtcclxuICAgIHRoaXMuY2FudmFzUm90YXRpb24rKztcclxuICAgIHRoaXMuZmxpcEFmdGVyUm90YXRlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZsaXBBZnRlclJvdGF0ZSgpIHtcclxuICAgIGNvbnN0IGZsaXBwZWRIID0gdGhpcy50cmFuc2Zvcm0uZmxpcEg7XHJcbiAgICBjb25zdCBmbGlwcGVkViA9IHRoaXMudHJhbnNmb3JtLmZsaXBWO1xyXG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XHJcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxyXG4gICAgICBmbGlwSDogZmxpcHBlZFYsXHJcbiAgICAgIGZsaXBWOiBmbGlwcGVkSFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIGZsaXBIb3Jpem9udGFsKCkge1xyXG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XHJcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxyXG4gICAgICBmbGlwSDogIXRoaXMudHJhbnNmb3JtLmZsaXBIXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgZmxpcFZlcnRpY2FsKCkge1xyXG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XHJcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxyXG4gICAgICBmbGlwVjogIXRoaXMudHJhbnNmb3JtLmZsaXBWXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8qKlxyXG4gICAqIEFubnVsbGEgbGEgc2VsZXppb25lIGRlbCBmaWxlLCBzdnVvdGFuZG8gbCdpbnB1dCBlIHJlc2V0dGFuZG8gdHV0dGUgbGUgcHJvcHJpZXTDoCBkZWxsJ0lBdHRhY2htZW50RFRPXHJcbiAgICovXHJcbiAgYWJvcnRGaWxlKCkge1xyXG4gICAgaWYgKHRoaXMuaW1hZ2VJbnB1dCkgdGhpcy5pbWFnZUlucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSBcIlwiO1xyXG5cclxuICAgIHRoaXMuc2VsZWN0ZWRGaWxlID0gbnVsbDtcclxuICAgIHRoaXMuc2VsZWN0ZWRGaWxlcyA9IG51bGw7XHJcbiAgICB0aGlzLnNob3dDcm9wSW1hZ2UgPSBmYWxzZTtcclxuXHJcbiAgICB0aGlzLm5ld0F0dGFjaG1lbnQuSXNJbWFnZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5uZXdBdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0ID0gbnVsbDtcclxuICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlTmFtZSA9IG51bGw7XHJcbiAgICB0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZUV4dGVuc2lvbiA9IG51bGw7XHJcbiAgICB0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZUNvbnRlbnRUeXBlID0gbnVsbDtcclxuXHJcbiAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPSBuZXcgQXJyYXk8SUF0dGFjaG1lbnREVE8+KCk7XHJcblxyXG4gICAgdGhpcy5jdXN0b21IZWlnaHQgPSBudWxsO1xyXG4gICAgdGhpcy5jdXN0b21XaWR0aCA9IG51bGw7XHJcbiAgICB0aGlzLm9yaWdpbmFsSGVpZ2h0ID0gbnVsbDtcclxuICAgIHRoaXMub3JpZ2luYWxXaWR0aCA9IG51bGw7XHJcblxyXG4gICAgdGhpcy5kaWFsb2dSZWZDcm9wSW1hZ2UuY2xvc2UoKTtcclxuICAgIHRoaXMucmVzdG9yZU9yaWdpbmFsRGltZW5zaW9ucygpO1xyXG4gIH1cclxuXHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8vIFZpZW5lIGNyZWF0byB1bidhcnJheSBvYnNlcnZhYmxlcyBwZXIgbWVtb3JpenphcmUgdHV0dGkgZ2xpIG9ic2VydmFibGUgY3JlYXRpIGRhbGxlIGNoaWFtYXRlIGEgZmlsZUVudHJ5LmZpbGUoKS5cclxuICAvLyBEb3BvIGNoZSB0dXR0aSBnbGkgb2JzZXJ2YWJsZXMgc29ubyBzdGF0aSBjb21wbGV0YXRpLCB2aWVuZSB1dGlsaXp6YXRvIGlsIG1ldG9kbyBzdWJzY3JpYmUoKSBwZXIgZXNlZ3VpcmUgbGEgZnVuemlvbmUgb25GaWxlQWRkZWQoKS5cclxuICBmaWxlRHJvcHBlZChmaWxlcykge1xyXG4gICAgbGV0IGZpbGVzRHJvcHBlZCA9IFtdO1xyXG5cclxuICAgIGNvbnN0IG9ic2VydmFibGVzOiBPYnNlcnZhYmxlPGFueT5bXSA9IFtdO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBpZiAoZmlsZXNbaV0uZmlsZUVudHJ5LmlzRmlsZSkge1xyXG4gICAgICAgIGNvbnN0IGZpbGVFbnRyeSA9IGZpbGVzW2ldLmZpbGVFbnRyeSBhcyBGaWxlU3lzdGVtRmlsZUVudHJ5O1xyXG4gICAgICAgIGNvbnN0IG9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXIpID0+IHtcclxuICAgICAgICAgIGZpbGVFbnRyeS5maWxlKChmaWxlOiBGaWxlKSA9PiB7XHJcbiAgICAgICAgICAgIGZpbGVzRHJvcHBlZC5wdXNoKGZpbGUpO1xyXG5cclxuICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChmaWxlKTtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIG9ic2VydmFibGVzLnB1c2gob2JzZXJ2YWJsZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZmlsZUVudHJ5ID0gZmlsZXNbaV0uZmlsZUVudHJ5IGFzIEZpbGVTeXN0ZW1EaXJlY3RvcnlFbnRyeTtcclxuICAgICAgICBjb25zb2xlLmxvZyhmaWxlc1tpXS5yZWxhdGl2ZVBhdGgsIGZpbGVFbnRyeSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmcm9tKG9ic2VydmFibGVzKVxyXG4gICAgICAucGlwZShjb25jYXRNYXAoKG9ic2VydmFibGUpID0+IG9ic2VydmFibGUpKVxyXG4gICAgICAuc3Vic2NyaWJlKHtcclxuICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5vbkZpbGVBZGRlZChmaWxlc0Ryb3BwZWQsIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBTZSBpbCBjYXJpY2FtZW50byBkZWwgZmlsZSBkcm9wYm94IHZhIGEgYnVvbiBmaW5lLCBsYSBmdW56aW9uZSBkaSBjYWxsYmFjayByZXN0aXR1aXNjZSB1biBhcnJheSBkaSBvZ2dldHRpLlxyXG4gIC8vIFZpZW5lIHBvaSBmYXR0YSB1bmEgWE1MSHR0cFJlcXVlc3QgY29uIHJlc3BvbnNlVHlwZSAnYmxvYicgcGVyIGNvbnZlcnRpcmUgaWwgcHJpbW8gZWxlbWVudG8gZGVsbGEgcmVzcG9uc2UgaW4gdW4gQmxvYi5cclxuICBjaG9vc2VEcm9wYm94RmlsZSgpIHtcclxuICAgIHZhciBvcHRpb25zID0ge1xyXG4gICAgICBzdWNjZXNzOiAoZmlsZXM6IGFueVtdKSA9PiB7XHJcbiAgICAgICAgY29uc3QgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgeGhyLm9wZW4oXCJHRVRcIiwgZmlsZXNbMF0ubGluayk7XHJcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJBdXRob3JpemF0aW9uXCIsIGBCZWFyZXIgJHtBdHRhY2htZW50SGVscGVyU2VydmljZS5kcm9wYm94Q3JlZGVudGlhbHMuYWNjZXNzVG9rZW59YCk7XHJcbiAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9IFwiYmxvYlwiO1xyXG5cclxuICAgICAgICB4aHIub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgYmxvYiA9IHhoci5yZXNwb25zZTtcclxuICAgICAgICAgIGNvbnN0IGZpbGUgPSBuZXcgRmlsZShbYmxvYl0sIGZpbGVzWzBdLm5hbWUsIHsgdHlwZTogYmxvYi50eXBlIH0pO1xyXG4gICAgICAgICAgbGV0IGZpbGVzQWRkZWQgPSBbZmlsZV07XHJcbiAgICAgICAgICB0aGlzLm9uRmlsZUFkZGVkKGZpbGVzQWRkZWQsIHRydWUpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHhoci5zZW5kKCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGxpbmtUeXBlOiBcImRpcmVjdFwiLFxyXG4gICAgICBtdWx0aXNlbGVjdDogZmFsc2UsXHJcbiAgICAgIGV4dGVuc2lvbnM6IFtcIi5qcGdcIiwgXCIucG5nXCIsIFwiLnBkZlwiLCBcIi5kb2NcIiwgXCIuZG9jeFwiLCBcIi50eHRcIl1cclxuICAgIH07XHJcbiAgICBEcm9wYm94LmNob29zZShvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIC8vIFdvcmthcm91bmQgZHJvcHpvbmU6IGRpc2FiaWxpdG8gaWwgY2xpY2sgZGVnbGkgZWxlbWVudGkgaW5jbHVzaSBuZWxsYSBkcm9wem9uZSBwZXIgZXZpdGFyZSBkaSBjbGljY2FyZSBkdWUgdm9sdGVcclxuICBvblNlbGVjdEZpbGUoZXZlbnQsIGZpbGVJbnB1dCkge1xyXG4gICAgaWYgKFxyXG4gICAgICAoZXZlbnQudGFyZ2V0IGFzIEhUTUxCdXR0b25FbGVtZW50KS50YWdOYW1lID09PSBcIkJVVFRPTlwiIHx8XHJcbiAgICAgIChldmVudC50YXJnZXQgYXMgSFRNTEJ1dHRvbkVsZW1lbnQpLnRhZ05hbWUgPT09IFwiSU5QVVRcIiB8fFxyXG4gICAgICB0aGlzLmFkZGluZ0xpbmtNb2RlID09IHRydWVcclxuICAgICkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBmaWxlSW5wdXQuY2xpY2soKTtcclxuICB9XHJcblxyXG4gIC8vIE1ldG9kbyBwZXIgdmlzdWFsaXp6YXJlIGxhIGZvcm0gZGkgYWdnaXVudGEgZGkgdW4gbGlua1xyXG4gIHN3aXRjaFRvQWRkaW5nTGlua01vZGUoKSB7XHJcbiAgICB0aGlzLmFkZGluZ0xpbmtNb2RlID0gdHJ1ZTtcclxuICAgIHRoaXMubmV3QXR0YWNobWVudCA9IHt9IGFzIElBdHRhY2htZW50RFRPO1xyXG4gICAgdGhpcy5uZXdBdHRhY2htZW50LklzSW1hZ2UgPSBmYWxzZTtcclxuICAgIHRoaXMubmV3QXR0YWNobWVudC5BdHRhY2htZW50VHlwZSA9IHRoaXMuYXR0YWNobWVudFR5cGUuTElOSztcclxuICAgIHRoaXMubmV3TXVsdGlwbGVBdHRhY2htZW50cyA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuICAgIHRoaXMubmV3TXVsdGlwbGVBdHRhY2htZW50cy5wdXNoKHRoaXMubmV3QXR0YWNobWVudCk7XHJcblxyXG4gICAgdGhpcy5jcmVhdGVBdHRhY2htZW50Rm9ybSgpO1xyXG4gIH1cclxufVxyXG4iLCI8IS0tIFNlIHJpY2hpZXN0YSBsYSBnZXN0aW9uZSBzaW5nb2xhIG1vc3RyYSBpbCBwdWxzYW50ZSBkaSBjYXJpY2FtZW50byBkaSB1biBzaW5nb2xvIGZpbGUgLS0+XHJcbjxkaXYgKm5nSWY9XCJtdWx0aXBsZUF0dGFjaG1lbnQgIT0gdHJ1ZVwiPlxyXG4gIDxkaXYgKm5nSWY9XCIhc2luZ2xlQXR0YWNobWVudERyYWdBbmREcm9wXCI+XHJcbiAgICA8IS0tIFRlbXBsYXRlIGRlbCBidXR0b24gcGVyIGwnYWdnaXVudGEgZGkgdW4gYWxsZWdhdG8gLS0+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiIWFkZGluZ0xpbmtNb2RlXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYWRkQXR0YWNobWVudEJ1dHRvblwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8IS0tIFRlbXBsYXRlIGRlbGxhIGZvcm0gcGVyIGwnYWdnaXVudGEgZGkgdW4gbGluayAtLT5cclxuICAgIDxkaXYgKm5nSWY9XCJhZGRpbmdMaW5rTW9kZVwiIGNsYXNzPVwidGV4dC1jZW50ZXJcIj5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImFkZGluZ0xpbmtUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgPGRpdiAqbmdJZj1cInNpbmdsZUF0dGFjaG1lbnREcmFnQW5kRHJvcFwiPlxyXG4gICAgPGlucHV0XHJcbiAgICAgICNmaWxlSW5wdXRcclxuICAgICAgc3R5bGU9XCJkaXNwbGF5OiBub25lXCJcclxuICAgICAgaWQ9XCJmaWxlX2F0dGFjaG1lbnRcIlxyXG4gICAgICBuYW1lPVwiZmlsZV9hdHRhY2htZW50XCJcclxuICAgICAgdHlwZT1cImZpbGVcIlxyXG4gICAgICAoY2hhbmdlKT1cIm9uRmlsZUFkZGVkKCRldmVudClcIlxyXG4gICAgICBbYWNjZXB0XT1cImFjY2VwdGVkRmlsZVR5cGVzXCJcclxuICAgICAgW211bHRpcGxlXT1cImxvYWRNdWx0aXBsZUZpbGVzXCIgLz5cclxuICAgIDxuZ3gtZmlsZS1kcm9wXHJcbiAgICAgIChvbkZpbGVEcm9wKT1cImZpbGVEcm9wcGVkKCRldmVudClcIlxyXG4gICAgICAoY2xpY2spPVwib25TZWxlY3RGaWxlKCRldmVudCwgZmlsZUlucHV0KVwiXHJcbiAgICAgICpuZ0lmPVwiXHJcbiAgICAgICAgYWxsb3dlZFR5cGVzICYmXHJcbiAgICAgICAgYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDEpICYmXHJcbiAgICAgICAgKCFhdHRhY2htZW50c0xpc3QgfHwgYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA9PSAwIHx8IChhdHRhY2htZW50c0xpc3QubGVuZ3RoID4gMCAmJiAhYXR0YWNobWVudHNMaXN0WzBdKSlcclxuICAgICAgXCI+XHJcbiAgICAgIDxuZy10ZW1wbGF0ZSBuZ3gtZmlsZS1kcm9wLWNvbnRlbnQtdG1wICpuZ0lmPVwiIWFkZGluZ0xpbmtNb2RlXCI+XHJcbiAgICAgICAgPGkgY2xhc3M9XCJmYS1zb2xpZCBmYS1jbG91ZC11cGxvYWQtYWx0IGZhLTN4IG10LTNcIj48L2k+XHJcbiAgICAgICAgVHJhc2NpbmEgaSBmaWxlIHF1aVxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgbXQtMVwiIHJvbGU9XCJncm91cFwiPlxyXG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWxpZ2h0IGJvcmRlci1lbmRcIiAoY2xpY2spPVwiZmlsZUlucHV0LmNsaWNrKClcIj5TY2VnbGkgdW4gZmlsZTwvYnV0dG9uPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cFwiIHJvbGU9XCJncm91cFwiPlxyXG4gICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWxpZ2h0IGJvcmRlci1zdGFydCBkcm9wZG93bi10b2dnbGVcIlxyXG4gICAgICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJhdHRhY2htZW50VHlwZU1lbnVcIj48L2J1dHRvbj5cclxuICAgICAgICAgICAgPG1hdC1tZW51ICNhdHRhY2htZW50VHlwZU1lbnU9XCJtYXRNZW51XCI+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMSlcIlxyXG4gICAgICAgICAgICAgICAgbWF0LW1lbnUtaXRlbVxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZXFwLWF0dGFjaG1lbnRzLWZpbGUtYnRuXCI+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1maWxlXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPkZpbGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMilcIlxyXG4gICAgICAgICAgICAgICAgbWF0LW1lbnUtaXRlbVxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInN3aXRjaFRvQWRkaW5nTGlua01vZGUoKVwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImVxcC1hdHRhY2htZW50cy1saW5rLWJ0blwiPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtbGlua1wiPjwvaT5cclxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDEwcHhcIj5MaW5rPC9zcGFuPlxyXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICpuZ0lmPVwiYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDMpXCJcclxuICAgICAgICAgICAgICAgIG1hdC1tZW51LWl0ZW1cclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJjaG9vc2VEcm9wYm94RmlsZSgpXCJcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZXFwLWF0dGFjaG1lbnRzLWxpbmstYnRuXCI+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhLWJyYW5kcyBmYS1kcm9wYm94XCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPkRyb3Bib3g8L3NwYW4+XHJcbiAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDwvbWF0LW1lbnU+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgPG5nLXRlbXBsYXRlIG5neC1maWxlLWRyb3AtY29udGVudC10bXAgKm5nSWY9XCJhZGRpbmdMaW5rTW9kZVwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJhZGRpbmdMaW5rVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDwvbmd4LWZpbGUtZHJvcD5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXJcIj5cclxuICAgIDxidXR0b25cclxuICAgICAgY2xhc3M9XCJtYi0yIG1lLTIgZXFwLWF0dGFjaG1lbnRzLWRvd25sb2FkLWJ0blwiXHJcbiAgICAgIChjbGljayk9XCJ2aWV3QXR0YWNobWVudChhdHRhY2htZW50c0xpc3RbMF0pXCJcclxuICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgIG1hdC1yYWlzZWQtYnV0dG9uXHJcbiAgICAgICpuZ0lmPVwiYXR0YWNobWVudHNMaXN0ICYmIGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPiAwICYmIGF0dGFjaG1lbnRzTGlzdFswXVwiXHJcbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiPlxyXG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJhdHRhY2htZW50c0xpc3RbMF0uQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuRklMRVwiPmRvd25sb2FkPC9tYXQtaWNvbj5cclxuICAgICAgPG1hdC1pY29uICpuZ0lmPVwiYXR0YWNobWVudHNMaXN0WzBdLkF0dGFjaG1lbnRUeXBlICE9IEF0dGFjaG1lbnRUeXBlLkZJTEVcIj5vcGVuX2luX25ldzwvbWF0LWljb24+XHJcbiAgICAgIHt7IGF0dGFjaG1lbnRzTGlzdFswXS5BdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5GSUxFID8gZG93bmxvYWRMYWJlbCA6IG9wZW5MaW5rTGFiZWwgfX1cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvblxyXG4gICAgICBjbGFzcz1cIm1iLTIgbWUtMiBlcXAtYXR0YWNobWVudHMtcHJldmlldy1idG5cIlxyXG4gICAgICAoY2xpY2spPVwib3BlblByZXZpZXdEaWFsb2coYXR0YWNobWVudHNMaXN0WzBdKVwiXHJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICBtYXQtcmFpc2VkLWJ1dHRvblxyXG4gICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAqbmdJZj1cIlxyXG4gICAgICAgIHNob3dQcmV2aWV3ICYmXHJcbiAgICAgICAgYXR0YWNobWVudHNMaXN0ICYmXHJcbiAgICAgICAgYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA+IDAgJiZcclxuICAgICAgICBhdHRhY2htZW50c0xpc3RbMF0gJiZcclxuICAgICAgICAoIWF0dGFjaG1lbnRzTGlzdFswXS5GaWxlQ29udGVudFR5cGUgfHxcclxuICAgICAgICAgICghYXR0YWNobWVudHNMaXN0WzBdLkZpbGVDb250ZW50VHlwZS5zdGFydHNXaXRoKCd2aWRlbycpICYmXHJcbiAgICAgICAgICAgICFhdHRhY2htZW50c0xpc3RbMF0uRmlsZUNvbnRlbnRUeXBlLnN0YXJ0c1dpdGgoJ2F1ZGlvJykpKSAmJlxyXG4gICAgICAgIGF0dGFjaG1lbnRzTGlzdFswXS5Jc0ltYWdlID09IHRydWVcclxuICAgICAgXCI+XHJcbiAgICAgIDxtYXQtaWNvbj52aXNpYmlsaXR5PC9tYXQtaWNvbj4ge3sgcHJldmlld0xhYmVsIH19XHJcbiAgICA8L2J1dHRvbj5cclxuICAgIDxidXR0b25cclxuICAgICAgY2xhc3M9XCJtYi0yIGVxcC1hdHRhY2htZW50cy1kZWxldGUtYnRuXCJcclxuICAgICAgKGNsaWNrKT1cImRlbGV0ZUF0dGFjaG1lbnQoYXR0YWNobWVudHNMaXN0WzBdKVwiXHJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICBtYXQtcmFpc2VkLWJ1dHRvblxyXG4gICAgICAqbmdJZj1cImF0dGFjaG1lbnRzTGlzdCAmJiBhdHRhY2htZW50c0xpc3QubGVuZ3RoID4gMCAmJiBhdHRhY2htZW50c0xpc3RbMF1cIlxyXG4gICAgICBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiPlxyXG4gICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj4ge3sgZGVsZXRlTGFiZWwgfX1cclxuICAgIDwvYnV0dG9uPlxyXG4gIDwvZGl2PlxyXG4gIDxkaXZcclxuICAgIGNsYXNzPVwicm93XCJcclxuICAgIHN0eWxlPVwibWFyZ2luLXRvcDogMTBweFwiXHJcbiAgICAqbmdJZj1cIlxyXG4gICAgICBhdHRhY2htZW50c0xpc3QubGVuZ3RoID4gMCAmJlxyXG4gICAgICBhdHRhY2htZW50c0xpc3RbMF0gJiZcclxuICAgICAgYXR0YWNobWVudHNMaXN0WzBdLkZpbGVEYXRhQmFzZTY0ICYmXHJcbiAgICAgIGF0dGFjaG1lbnRzTGlzdFswXS5Jc0ltYWdlID09IHRydWVcclxuICAgIFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMiBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic2luZ2xlLWF0dGFjaG1lbnQtaW5saW5lLXByZXZpZXctY29udGFpbmVyXCI+XHJcbiAgICAgICAgPGltZyBzcmM9XCJkYXRhOmltYWdlL3BuZztiYXNlNjQse3sgYXR0YWNobWVudHNMaXN0WzBdLkZpbGVEYXRhQmFzZTY0IH19XCIgLz5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nSWY9XCJhdHRhY2htZW50c0xpc3QubGVuZ3RoID4gMCAmJiBhdHRhY2htZW50c0xpc3RbMF0gJiYgYXR0YWNobWVudHNMaXN0WzBdLklzSW1hZ2UgIT0gdHJ1ZVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMlwiPlxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgPG1hdC1sYWJlbD57eyBmaWxlTmFtZUxhYmVsIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0IHJlYWRvbmx5IG1hdElucHV0IFsobmdNb2RlbCldPVwiYXR0YWNobWVudHNMaXN0WzBdLkZpbGVOYW1lXCIgLz5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxuXHJcbjxkaXYgKm5nSWY9XCJtdWx0aXBsZUF0dGFjaG1lbnQgPT0gdHJ1ZVwiPlxyXG4gIDxpbnB1dFxyXG4gICAgI2ZpbGVJbnB1dFxyXG4gICAgc3R5bGU9XCJkaXNwbGF5OiBub25lXCJcclxuICAgIGlkPVwiZmlsZV9hdHRhY2htZW50XCJcclxuICAgIG5hbWU9XCJmaWxlX2F0dGFjaG1lbnRcIlxyXG4gICAgdHlwZT1cImZpbGVcIlxyXG4gICAgKGNoYW5nZSk9XCJvbkZpbGVBZGRlZCgkZXZlbnQpXCJcclxuICAgIFthY2NlcHRdPVwiYWNjZXB0ZWRGaWxlVHlwZXNcIlxyXG4gICAgW211bHRpcGxlXT1cImxvYWRNdWx0aXBsZUZpbGVzXCIgLz5cclxuICA8bmd4LWZpbGUtZHJvcCAob25GaWxlRHJvcCk9XCJmaWxlRHJvcHBlZCgkZXZlbnQpXCIgKGNsaWNrKT1cIm9uU2VsZWN0RmlsZSgkZXZlbnQsIGZpbGVJbnB1dClcIj5cclxuICAgIDxuZy10ZW1wbGF0ZSBuZ3gtZmlsZS1kcm9wLWNvbnRlbnQtdG1wICpuZ0lmPVwiIWFkZGluZ0xpbmtNb2RlXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiZmEtc29saWQgZmEtY2xvdWQtdXBsb2FkLWFsdCBmYS0zeCBtdC0zXCI+PC9pPlxyXG4gICAgICBUcmFzY2luYSBpIGZpbGUgcXVpXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgbXQtMVwiIHJvbGU9XCJncm91cFwiPlxyXG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1saWdodCBib3JkZXItZW5kXCIgKGNsaWNrKT1cImZpbGVJbnB1dC5jbGljaygpXCI+U2NlZ2xpIHVuIGZpbGU8L2J1dHRvbj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwXCIgcm9sZT1cImdyb3VwXCI+XHJcbiAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tbGlnaHQgYm9yZGVyLXN0YXJ0IGRyb3Bkb3duLXRvZ2dsZVwiXHJcbiAgICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJhdHRhY2htZW50VHlwZU1lbnVcIj48L2J1dHRvbj5cclxuICAgICAgICAgIDxtYXQtbWVudSAjYXR0YWNobWVudFR5cGVNZW51PVwibWF0TWVudVwiPlxyXG4gICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgKm5nSWY9XCJhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMSlcIlxyXG4gICAgICAgICAgICAgIG1hdC1tZW51LWl0ZW1cclxuICAgICAgICAgICAgICAoY2xpY2spPVwiZmlsZUlucHV0LmNsaWNrKClcIlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiZXFwLWF0dGFjaG1lbnRzLWZpbGUtYnRuXCI+XHJcbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZmlsZVwiPjwvaT5cclxuICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+RmlsZTwvc3Bhbj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAqbmdJZj1cImFsbG93ZWRUeXBlcy5pbmNsdWRlcygyKVwiXHJcbiAgICAgICAgICAgICAgbWF0LW1lbnUtaXRlbVxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJzd2l0Y2hUb0FkZGluZ0xpbmtNb2RlKClcIlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiZXFwLWF0dGFjaG1lbnRzLWxpbmstYnRuXCI+XHJcbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtbGlua1wiPjwvaT5cclxuICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+TGluazwvc3Bhbj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAqbmdJZj1cImFsbG93ZWRUeXBlcy5pbmNsdWRlcygzKVwiXHJcbiAgICAgICAgICAgICAgbWF0LW1lbnUtaXRlbVxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJjaG9vc2VEcm9wYm94RmlsZSgpXCJcclxuICAgICAgICAgICAgICBjbGFzcz1cImVxcC1hdHRhY2htZW50cy1saW5rLWJ0blwiPlxyXG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEtYnJhbmRzIGZhLWRyb3Bib3hcIj48L2k+XHJcbiAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPkRyb3Bib3g8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPC9tYXQtbWVudT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgPG5nLXRlbXBsYXRlIG5neC1maWxlLWRyb3AtY29udGVudC10bXAgKm5nSWY9XCJhZGRpbmdMaW5rTW9kZVwiPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYWRkaW5nTGlua1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gIDwvbmd4LWZpbGUtZHJvcD5cclxuICA8ZGl2IGNsYXNzPVwibXQtMlwiPlxyXG4gICAgPGVxcC10YWJsZVxyXG4gICAgICAjYXR0YWNobWVudFRhYmxlXHJcbiAgICAgIFtjcmVhdGVNYXRDYXJkXT1cImZhbHNlXCJcclxuICAgICAgI3RhYmxlXHJcbiAgICAgIFtjb2x1bW5zXT1cImF0dGFjaG1lbnRzQ29sdW1uc1wiXHJcbiAgICAgIFtpc011bHRpTGFuZ3VhZ2VdPVwiaXNFcXBUYWJsZU11bHRpTGFuZ3VhZ2VcIlxyXG4gICAgICBbZGF0YV09XCJhdHRhY2htZW50c0xpc3RcIlxyXG4gICAgICBbcGFnaW5hdG9yVmlzaWJsZV09XCJ0YWJsZVBhZ2luYXRvclZpc2libGVcIlxyXG4gICAgICBbbWF0UGFnaW5hdG9yU2l6ZV09XCJ0YWJsZVBhZ2luYXRvclNpemVcIlxyXG4gICAgICBbZW1wdHlUYWJsZU1lc3NhZ2VdPVwiZW1wdHlUYWJsZU1lc3NhZ2VcIlxyXG4gICAgICBbc2VhcmNoVGV4dF09XCJlcXBUYWJsZVNlYXJjaFRleHRcIlxyXG4gICAgICBbaXNUYWJsZVNlYXJjaGVhYmxlXT1cImlzVGFibGVTZWFyY2hlYWJsZVwiPlxyXG4gICAgPC9lcXAtdGFibGU+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPG5nLXRlbXBsYXRlICNkaWFsb2dDcm9wSW1hZ2U+XHJcbiAgPCEtLSBSaWNoaWFtYSBpbCB0ZW1wbGF0ZSBwZXIgbGUgZnVuemlvbmFsaXTDoCBkZWwgQ1JPUFBJRSAtLT5cclxuICA8ZGl2IHN0eWxlPVwib3ZlcmZsb3cteDogaGlkZGVuXCIgW25nQ2xhc3NdPVwiY3JvcERpYWxvZ0NsYXNzXCI+XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNyb3BwaWVUZW1wbGF0ZVwiXHJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGZvcm06IG5ld0F0dGFjaG1lbnRGb3JtIH1cIlxyXG4gICAgICAqbmdJZj1cInNob3dDcm9wSW1hZ2UgPT0gdHJ1ZVwiPjwvbmctY29udGFpbmVyPlxyXG4gIDwvZGl2PlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNpbmxpbmVQcmV2aWV3VGVtcGxhdGUgbGV0LXJvdz1cInJvd1wiPlxyXG4gIDxkaXZcclxuICAgIGNsYXNzPVwiaW5saW5lLXByZXZpZXctY29udGFpbmVyXCJcclxuICAgICpuZ0lmPVwicm93LkF0dGFjaG1lbnRUeXBlICE9IEF0dGFjaG1lbnRUeXBlLkxJTksgJiYgcm93LklzSW1hZ2VcIlxyXG4gICAgKGNsaWNrKT1cIm9wZW5QcmV2aWV3RGlhbG9nKHJvdylcIj5cclxuICAgIDxpbWcgc3JjPVwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LHt7IHJvdy5GaWxlVGh1bWJuYWlsQmFzZTY0ID8gcm93LkZpbGVUaHVtYm5haWxCYXNlNjQgOiByb3cuRmlsZURhdGFCYXNlNjQgfX1cIiAvPlxyXG4gIDwvZGl2PlxyXG4gIDxkaXZcclxuICAgIGNsYXNzPVwiaW5saW5lLXByZXZpZXctY29udGFpbmVyXCJcclxuICAgICpuZ0lmPVwicm93LkF0dGFjaG1lbnRUeXBlICE9IEF0dGFjaG1lbnRUeXBlLkxJTksgJiYgIXJvdy5Jc0ltYWdlXCJcclxuICAgIChjbGljayk9XCJvcGVuUHJldmlld0RpYWxvZyhyb3cpXCI+XHJcbiAgICA8aSBbbmdDbGFzc109XCJnZXRBdHRhY2htZW50SWNvbihyb3cpXCI+PC9pPlxyXG4gIDwvZGl2PlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNkaWFsb2dQcmV2aWV3PlxyXG4gIDxtYXQtY2FyZCBjbGFzcz1cImV4YW1wbGUtY2FyZFwiICpuZ0lmPVwic2VsZWN0ZWRBdHRhY2htZW50XCI+XHJcbiAgICA8bWF0LWNhcmQtY29udGVudD5cclxuICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItdGl0bGUtc3RhbmRhcmRcIj5cclxuICAgICAgICAgIHt7IHByZXZpZXdMYWJlbCB9fSB7eyBzZWxlY3RlZEF0dGFjaG1lbnQ/LkF0dGFjaG1lbnRUeXBlID09IGF0dGFjaG1lbnRUeXBlLkZJTEUgPyBcIkZpbGVcIiA6IFwiTGlua1wiIH19XHJcbiAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICBjbGFzcz1cImJ0bi1jbG9zZSBjbG9zZUJ1dHRvblwiXHJcbiAgICAgICAgICAgIG1hdC1kaWFsb2ctY2xvc2VcclxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdGVkQXR0YWNobWVudCA9IG51bGxcIj48L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJyb3cgbXQtMlwiPlxyXG4gICAgICAgIDwhLS0gQU5URVBSSU1BIElNTUFHSU5FIC0tPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTIgdGV4dC1jZW50ZXIgcHJldmlldy1jb250YWluZXJcIiAqbmdJZj1cInNlbGVjdGVkQXR0YWNobWVudC5Jc0ltYWdlXCI+XHJcbiAgICAgICAgICA8aW1nXHJcbiAgICAgICAgICAgIGNsYXNzPVwiaW1hZ2UtcHJldmlld1wiXHJcbiAgICAgICAgICAgIHNyYz1cImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCx7e1xyXG4gICAgICAgICAgICAgIHNlbGVjdGVkQXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NFxyXG4gICAgICAgICAgICAgICAgPyBzZWxlY3RlZEF0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjRcclxuICAgICAgICAgICAgICAgIDogc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVUaHVtYm5haWxCYXNlNjRcclxuICAgICAgICAgICAgfX1cIiAvPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tIEFOVEVQUklNQSBMSU5LIC0tPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTIgcHJldmlldy1jb250YWluZXJcIiAqbmdJZj1cIiFzZWxlY3RlZEF0dGFjaG1lbnQuSXNJbWFnZVwiPlxyXG4gICAgICAgICAgPGlmcmFtZVxyXG4gICAgICAgICAgICBjbGFzcz1cImxpbmstcHJldmlld1wiXHJcbiAgICAgICAgICAgIFtzcmNdPVwic2VsZWN0ZWRBdHRhY2htZW50LlRydXN0ZWRVcmxcIlxyXG4gICAgICAgICAgICBbdGl0bGVdPVwic2VsZWN0ZWRBdHRhY2htZW50LkZpbGVOYW1lXCI+PC9pZnJhbWU+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwicm93IG10LTNcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEyIHRleHQtY2VudGVyXCI+XHJcbiAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgIG1hdC1taW5pLWZhYlxyXG4gICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICBtYXRUb29sdGlwPVwiRG93bmxvYWRcIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwidmlld0F0dGFjaG1lbnQoc2VsZWN0ZWRBdHRhY2htZW50KVwiXHJcbiAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRBdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlICE9IEF0dGFjaG1lbnRUeXBlLkxJTktcIj5cclxuICAgICAgICAgICAgPG1hdC1pY29uPmRvd25sb2FkPC9tYXQtaWNvbj5cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvbWF0LWNhcmQtY29udGVudD5cclxuICA8L21hdC1jYXJkPlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPCEtLSBURU1QTEFURSBQRVIgSUwgUFVMU0FOVEUgREkgQUdHSVVOVEEgTlVPVk8gQUxMRUdBVE8gLS0+XHJcbjxuZy10ZW1wbGF0ZSAjYWRkQXR0YWNobWVudEJ1dHRvbj5cclxuICA8IS0tXHJcbiAgICAgICAgUHVsc2FudGkgcGVyIGwnYWdnaXVudGEgZGkgdW4gZmlsZSBvIHVuIGxpbmsuIE5lIHZpZW5lIHZpc3VhbGl6emF0byB1bm8gc2U6XHJcbiAgICAgICAgLSBnbGkgYWxsb3dlZFR5cGVzIHNvbm8gc3RhdGkgc3BlY2lmaWNhdGksIG5lbGwnYXJyYXkgbmUgw6ggcHJlc2VudGUgdW5vIHNvbG8sIHF1ZWxsbyBpbnNlcml0byDDqCBBdHRhY2htZW50VHlwZS5GSUxFIChvIEF0dGFjaG1lbnRUeXBlLkxJTkspXHJcbiAgICAgICAgZSBzb25vIG5lbGxhIGdlc3Rpb25lIGRpIHBpw7kgYWxsZWdhdGkgKG11bHRpcGxlQXR0YWNobWVudCA9PSB0cnVlKVxyXG4gICAgICAgIE9QUFVSRVxyXG4gICAgICAgIC0gZ2xpIGFsbG93ZWRUeXBlcyBzb25vIHN0YXRpIHNwZWNpZmljYXRpLCBuZWxsJ2FycmF5IG5lIMOoIHByZXNlbnRlIHVubyBzb2xvLCBxdWVsbG8gaW5zZXJpdG8gw6ggQXR0YWNobWVudFR5cGUuRklMRSAobyBBdHRhY2htZW50VHlwZS5MSU5LKVxyXG4gICAgICAgIGUgc29ubyBuZWxsYSBnZXN0aW9uZSBkaSB1biBzaW5nb2xvIGFsbGVnYXRvIChtdWx0aXBsZUF0dGFjaG1lbnQgPT0gdHJ1ZSkgZSBub24gbmUgw6ggYW5jb3JhIHN0YXRvIHNlbGV6aW9uYXRvIHVubyAob3Z2ZXJvIGF0dGFjaG1lbnRzTGlzdCBub24gZXNpc3RlIG8gbm9uIGhhIGVsZW1lbnRpKVxyXG4gICAgLS0+XHJcbiAgPGlucHV0XHJcbiAgICAjZmlsZUlucHV0XHJcbiAgICBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIlxyXG4gICAgaWQ9XCJmaWxlX2F0dGFjaG1lbnRcIlxyXG4gICAgbmFtZT1cImZpbGVfYXR0YWNobWVudFwiXHJcbiAgICB0eXBlPVwiZmlsZVwiXHJcbiAgICAoY2hhbmdlKT1cIm9uRmlsZUFkZGVkKCRldmVudClcIlxyXG4gICAgW2FjY2VwdF09XCJhY2NlcHRlZEZpbGVUeXBlc1wiXHJcbiAgICBbbXVsdGlwbGVdPVwibG9hZE11bHRpcGxlRmlsZXNcIiAvPlxyXG4gIDxidXR0b25cclxuICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG1iLTQgbWUtNSBlcXAtYXR0YWNobWVudHMtYWRkLWJ0blwiXHJcbiAgICBtYXQtcmFpc2VkLWJ1dHRvblxyXG4gICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgKm5nSWY9XCJcclxuICAgICAgYWxsb3dlZFR5cGVzICYmXHJcbiAgICAgIGFsbG93ZWRUeXBlcy5sZW5ndGggPT0gMSAmJlxyXG4gICAgICAobXVsdGlwbGVBdHRhY2htZW50ID09IHRydWUgfHxcclxuICAgICAgICAhYXR0YWNobWVudHNMaXN0IHx8XHJcbiAgICAgICAgYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA9PSAwIHx8XHJcbiAgICAgICAgKGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPiAwICYmICFhdHRhY2htZW50c0xpc3RbMF0pKVxyXG4gICAgXCJcclxuICAgIChjbGljayk9XCJhZGRGaWxlKGFsbG93ZWRUeXBlc1swXSwgZmlsZUlucHV0KVwiXHJcbiAgICBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiPlxyXG4gICAgPCEtLSBQZXIgbCdhZ2dpdW50YSBkZWkgZmlsZSBtb3N0cm8gdW4naWNvbmEgZGl2ZXJzYSBkYWxsJ2FnZ2l1bnRhIGRlaSBsaW5rIC0tPlxyXG4gICAgPG1hdC1pY29uICpuZ0lmPVwiYWxsb3dlZFR5cGVzWzBdID09IDFcIj5jbG91ZF91cGxvYWQ8L21hdC1pY29uPlxyXG4gICAgPGkgY2xhc3M9XCJmYXMgZmEtbGlua1wiICpuZ0lmPVwiYWxsb3dlZFR5cGVzWzBdID09IDJcIj48L2k+XHJcbiAgICA8aSBjbGFzcz1cImZhLWJyYW5kcyBmYS1kcm9wYm94XCIgKm5nSWY9XCJhbGxvd2VkVHlwZXNbMF0gPT0gM1wiPjwvaT5cclxuICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDEwcHhcIj5cclxuICAgICAge3tcclxuICAgICAgICBhbGxvd2VkVHlwZXNbMF0gPT0gMVxyXG4gICAgICAgICAgPyBhZGRCdXR0b25MYWJlbCArIFwiIGZpbGVcIlxyXG4gICAgICAgICAgOiBhbGxvd2VkVHlwZXNbMF0gPT0gMlxyXG4gICAgICAgICAgPyBhZGRCdXR0b25MYWJlbCArIFwiIGxpbmtcIlxyXG4gICAgICAgICAgOiB1cGxvYWRXaXRoRHJvcGJveExhYmVsXHJcbiAgICAgIH19PC9zcGFuXHJcbiAgICA+XHJcbiAgPC9idXR0b24+XHJcblxyXG4gIDwhLS0gUHVsc2FudGUgcGVyIGFwcmlyZSBpbCBtZW51IHBlciBsYSBzY2VsdGEgZGVsIHRpcG8gZGkgQXR0YWNobWVudCBkYSBjcmVhcmUgLS0+XHJcbiAgPGJ1dHRvblxyXG4gICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgbWItNCBtZS01IGVxcC1hdHRhY2htZW50cy1hZGQtYnRuXCJcclxuICAgIG1hdC1yYWlzZWQtYnV0dG9uXHJcbiAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICBbbWF0TWVudVRyaWdnZXJGb3JdPVwiYXR0YWNobWVudFR5cGVNZW51XCJcclxuICAgIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkXCJcclxuICAgICpuZ0lmPVwiXHJcbiAgICAgICFzZXBhcmF0ZWRVcGxvYWRCdXR0b25zICYmXHJcbiAgICAgIGFsbG93ZWRUeXBlcyAmJlxyXG4gICAgICBhbGxvd2VkVHlwZXMubGVuZ3RoID4gMSAmJlxyXG4gICAgICAobXVsdGlwbGVBdHRhY2htZW50ID09IHRydWUgfHxcclxuICAgICAgICAhYXR0YWNobWVudHNMaXN0IHx8XHJcbiAgICAgICAgYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA9PSAwIHx8XHJcbiAgICAgICAgKGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPiAwICYmICFhdHRhY2htZW50c0xpc3RbMF0pKVxyXG4gICAgXCI+XHJcbiAgICA8bWF0LWljb24gKm5nSWY9XCJtdWx0aXBsZUF0dGFjaG1lbnQgIT0gdHJ1ZVwiPmNsb3VkX3VwbG9hZDwvbWF0LWljb24+XHJcbiAgICA8bWF0LWljb24gKm5nSWY9XCJtdWx0aXBsZUF0dGFjaG1lbnQgPT0gdHJ1ZVwiPmFkZDwvbWF0LWljb24+XHJcbiAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAwcHhcIj4ge3sgYWRkQnV0dG9uTGFiZWwgfX0gPC9zcGFuPlxyXG4gIDwvYnV0dG9uPlxyXG4gIDxtYXQtbWVudSAjYXR0YWNobWVudFR5cGVNZW51PVwibWF0TWVudVwiPlxyXG4gICAgPGlucHV0XHJcbiAgICAgICNpbWFnZUlucHV0XHJcbiAgICAgIHN0eWxlPVwiZGlzcGxheTogbm9uZVwiXHJcbiAgICAgIGlkPVwiZmlsZV9hdHRhY2htZW50XCJcclxuICAgICAgbmFtZT1cImZpbGVfYXR0YWNobWVudFwiXHJcbiAgICAgIHR5cGU9XCJmaWxlXCJcclxuICAgICAgKGNoYW5nZSk9XCJvbkZpbGVBZGRlZCgkZXZlbnQpXCJcclxuICAgICAgW2FjY2VwdF09XCJhY2NlcHRlZEZpbGVUeXBlc1wiXHJcbiAgICAgIFttdWx0aXBsZV09XCJsb2FkTXVsdGlwbGVGaWxlc1wiIC8+XHJcbiAgICA8YnV0dG9uXHJcbiAgICAgICpuZ0lmPVwiYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDEpXCJcclxuICAgICAgbWF0LW1lbnUtaXRlbVxyXG4gICAgICAoY2xpY2spPVwiaW1hZ2VJbnB1dC5jbGljaygpXCJcclxuICAgICAgY2xhc3M9XCJlcXAtYXR0YWNobWVudHMtZmlsZS1idG5cIj5cclxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZmlsZVwiPjwvaT5cclxuICAgICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPkZpbGU8L3NwYW4+XHJcbiAgICA8L2J1dHRvbj5cclxuICAgIDxidXR0b25cclxuICAgICAgKm5nSWY9XCJhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMilcIlxyXG4gICAgICBtYXQtbWVudS1pdGVtXHJcbiAgICAgIChjbGljayk9XCJzd2l0Y2hUb0FkZGluZ0xpbmtNb2RlKClcIlxyXG4gICAgICBjbGFzcz1cImVxcC1hdHRhY2htZW50cy1saW5rLWJ0blwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1saW5rXCI+PC9pPlxyXG4gICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+TGluazwvc3Bhbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvblxyXG4gICAgICAqbmdJZj1cImFsbG93ZWRUeXBlcy5pbmNsdWRlcygzKVwiXHJcbiAgICAgIG1hdC1tZW51LWl0ZW1cclxuICAgICAgKGNsaWNrKT1cImNob29zZURyb3Bib3hGaWxlKClcIlxyXG4gICAgICBjbGFzcz1cImVxcC1hdHRhY2htZW50cy1saW5rLWJ0blwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhLWJyYW5kcyBmYS1kcm9wYm94XCI+PC9pPlxyXG4gICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+RHJvcGJveDwvc3Bhbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gIDwvbWF0LW1lbnU+XHJcblxyXG4gIDxkaXZcclxuICAgICpuZ0lmPVwiXHJcbiAgICAgIHNlcGFyYXRlZFVwbG9hZEJ1dHRvbnMgJiZcclxuICAgICAgYWxsb3dlZFR5cGVzICYmXHJcbiAgICAgIGFsbG93ZWRUeXBlcy5sZW5ndGggPiAxICYmXHJcbiAgICAgIChtdWx0aXBsZUF0dGFjaG1lbnQgPT0gdHJ1ZSB8fFxyXG4gICAgICAgICFhdHRhY2htZW50c0xpc3QgfHxcclxuICAgICAgICBhdHRhY2htZW50c0xpc3QubGVuZ3RoID09IDAgfHxcclxuICAgICAgICAoYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA+IDAgJiYgIWF0dGFjaG1lbnRzTGlzdFswXSkpXHJcbiAgICBcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgICpuZ0lmPVwiYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDEpXCJcclxuICAgICAgICAoY2xpY2spPVwiaW1hZ2VJbnB1dC5jbGljaygpXCJcclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGVxcC1hdHRhY2htZW50cy1hZGQtYnRuXCJcclxuICAgICAgICBtYXQtcmFpc2VkLWJ1dHRvblxyXG4gICAgICAgIGNvbG9yPVwic2Vjb25kYXJ5XCJcclxuICAgICAgICB0eXBlPVwiYnV0dG9uXCI+XHJcbiAgICAgICAgPGkgY2xhc3M9XCJmYS1zb2xpZCBmYS1jbG91ZC11cGxvYWRcIj48L2k+XHJcbiAgICAgICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPkZpbGU8L3NwYW4+XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8aW5wdXRcclxuICAgICAgICAjaW1hZ2VJbnB1dFxyXG4gICAgICAgIHN0eWxlPVwiZGlzcGxheTogbm9uZVwiXHJcbiAgICAgICAgaWQ9XCJmaWxlX2F0dGFjaG1lbnRcIlxyXG4gICAgICAgIG5hbWU9XCJmaWxlX2F0dGFjaG1lbnRcIlxyXG4gICAgICAgIHR5cGU9XCJmaWxlXCJcclxuICAgICAgICAoY2hhbmdlKT1cIm9uRmlsZUFkZGVkKCRldmVudClcIlxyXG4gICAgICAgIFthY2NlcHRdPVwiYWNjZXB0ZWRGaWxlVHlwZXNcIlxyXG4gICAgICAgIFttdWx0aXBsZV09XCJsb2FkTXVsdGlwbGVGaWxlc1wiIC8+XHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICAqbmdJZj1cImFsbG93ZWRUeXBlcy5pbmNsdWRlcygyKVwiXHJcbiAgICAgICAgKGNsaWNrKT1cInN3aXRjaFRvQWRkaW5nTGlua01vZGUoKVwiXHJcbiAgICAgICAgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeSBlcXAtYXR0YWNobWVudHMtYWRkLWJ0blwiXHJcbiAgICAgICAgbWF0LXJhaXNlZC1idXR0b25cclxuICAgICAgICBjb2xvcj1cInNlY29uZGFyeVwiXHJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiPlxyXG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWxpbmtcIj48L2k+XHJcbiAgICAgICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPkxpbms8L3NwYW4+XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8YnV0dG9uXHJcbiAgICAgICAgKm5nSWY9XCJhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMylcIlxyXG4gICAgICAgIChjbGljayk9XCJjaG9vc2VEcm9wYm94RmlsZSgpXCJcclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGVxcC1hdHRhY2htZW50cy1hZGQtYnRuXCJcclxuICAgICAgICBtYXQtcmFpc2VkLWJ1dHRvblxyXG4gICAgICAgIGNvbG9yPVwic2Vjb25kYXJ5XCJcclxuICAgICAgICB0eXBlPVwiYnV0dG9uXCI+XHJcbiAgICAgICAgPGkgY2xhc3M9XCJmYS1icmFuZHMgZmEtZHJvcGJveFwiPjwvaT5cclxuICAgICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+RHJvcGJveDwvc3Bhbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9uZy10ZW1wbGF0ZT5cclxuXHJcbjxuZy10ZW1wbGF0ZSAjY3JvcHBpZVRlbXBsYXRlPlxyXG4gIDxkaXYgY2xhc3M9XCJyb3cgbS0zXCI+XHJcbiAgICA8aDQ+e3sgY3JvcExhYmVsIH19PC9oND5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwicm93IG0tMiBjcm9wLWxhcmdlXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gICAgICA8YnV0dG9uXHJcbiAgICAgICAgW21hdFRvb2x0aXBdPVwicm90YXRlTGVmdExhYmVsXCJcclxuICAgICAgICAqbmdJZj1cImNyb3BPcHRpb25zLmluY2x1ZGVzKDEpXCJcclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYXQtcmFpc2VkLWJ1dHRvbiBtcy0yXCJcclxuICAgICAgICAoY2xpY2spPVwicm90YXRlTGVmdCgpXCI+XHJcbiAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwidmVydGljYWwtYWxpZ246IG1pZGRsZVwiPnJvdGF0ZV9sZWZ0PC9tYXQtaWNvbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICBbbWF0VG9vbHRpcF09XCJyb3RhdGVSaWdodExhYmVsXCJcclxuICAgICAgICAqbmdJZj1cImNyb3BPcHRpb25zLmluY2x1ZGVzKDEpXCJcclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYXQtcmFpc2VkLWJ1dHRvbiBtcy0yXCJcclxuICAgICAgICAoY2xpY2spPVwicm90YXRlUmlnaHQoKVwiPlxyXG4gICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIj5yb3RhdGVfcmlnaHQ8L21hdC1pY29uPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIFttYXRUb29sdGlwXT1cImZsaXBIb3JpbnpvbnRhbExhYmVsXCJcclxuICAgICAgICAqbmdJZj1cImNyb3BPcHRpb25zLmluY2x1ZGVzKDIpXCJcclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYXQtcmFpc2VkLWJ1dHRvbiBtcy0yXCJcclxuICAgICAgICAoY2xpY2spPVwiZmxpcEhvcml6b250YWwoKVwiPlxyXG4gICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIj5mbGlwX2hvcml6b250YWw8L21hdC1pY29uPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIFttYXRUb29sdGlwXT1cImZsaXBWZXJ0aWNhbExhYmVsXCJcclxuICAgICAgICAqbmdJZj1cImNyb3BPcHRpb25zLmluY2x1ZGVzKDIpXCJcclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYXQtcmFpc2VkLWJ1dHRvbiBtcy0yXCJcclxuICAgICAgICAoY2xpY2spPVwiZmxpcFZlcnRpY2FsKClcIj5cclxuICAgICAgICA8ZGl2IHN0eWxlPVwidHJhbnNmb3JtOiByb3RhdGUoOTBkZWcpXCI+PG1hdC1pY29uIHN0eWxlPVwidmVydGljYWwtYWxpZ246IG1pZGRsZVwiPmZsaXBfdmVydGljYWw8L21hdC1pY29uPjwvZGl2PlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIFttYXRUb29sdGlwXT1cIidSZXNldCdcIlxyXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG1hdC1yYWlzZWQtYnV0dG9uIG1zLTJcIlxyXG4gICAgICAgIChjbGljayk9XCJyZXN0b3JlT3JpZ2luYWxEaW1lbnNpb25zKClcIj5cclxuICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlXCI+cmVwbGF5PC9tYXQtaWNvbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwicm93IG0tMiBjcm9wLXNtYWxsXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJjcm9wT3B0aW9ucy5pbmNsdWRlcygxKVwiIHN0eWxlPVwiZm9udC1zaXplOiAyN3B4OyB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlXCIgKGNsaWNrKT1cInJvdGF0ZUxlZnQoKVwiXHJcbiAgICAgICAgPnJvdGF0ZV9sZWZ0PC9tYXQtaWNvblxyXG4gICAgICA+XHJcbiAgICAgIDxtYXQtaWNvblxyXG4gICAgICAgIGNsYXNzPVwibXMtM1wiXHJcbiAgICAgICAgKm5nSWY9XCJjcm9wT3B0aW9ucy5pbmNsdWRlcygxKVwiXHJcbiAgICAgICAgc3R5bGU9XCJmb250LXNpemU6IDI3cHg7IHZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIlxyXG4gICAgICAgIChjbGljayk9XCJyb3RhdGVSaWdodCgpXCJcclxuICAgICAgICA+cm90YXRlX3JpZ2h0PC9tYXQtaWNvblxyXG4gICAgICA+XHJcbiAgICAgIDxtYXQtaWNvblxyXG4gICAgICAgIGNsYXNzPVwibXMtM1wiXHJcbiAgICAgICAgKm5nSWY9XCJjcm9wT3B0aW9ucy5pbmNsdWRlcygyKVwiXHJcbiAgICAgICAgc3R5bGU9XCJmb250LXNpemU6IDI3cHg7IHZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIlxyXG4gICAgICAgIChjbGljayk9XCJmbGlwSG9yaXpvbnRhbCgpXCJcclxuICAgICAgICA+ZmxpcF9ob3Jpem9udGFsPC9tYXQtaWNvblxyXG4gICAgICA+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJtcy0zXCIgc3R5bGU9XCJ0cmFuc2Zvcm06IHJvdGF0ZSg5MGRlZylcIj5cclxuICAgICAgICA8bWF0LWljb25cclxuICAgICAgICAgICpuZ0lmPVwiY3JvcE9wdGlvbnMuaW5jbHVkZXMoMilcIlxyXG4gICAgICAgICAgc3R5bGU9XCJmb250LXNpemU6IDI3cHg7IHZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cImZsaXBWZXJ0aWNhbCgpXCJcclxuICAgICAgICAgID5mbGlwX3ZlcnRpY2FsPC9tYXQtaWNvblxyXG4gICAgICAgID5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1zLTNcIiAoY2xpY2spPVwicmVzdG9yZU9yaWdpbmFsRGltZW5zaW9ucygpXCIgc3R5bGU9XCJmb250LXNpemU6IDI3cHg7IHZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIlxyXG4gICAgICAgID5yZXBsYXk8L21hdC1pY29uXHJcbiAgICAgID5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgY2xhc3M9XCJyb3cganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbC0xMiBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNyb3AtY29udGFpbmVyXCI+XHJcbiAgICAgICAgPGltYWdlLWNyb3BwZXJcclxuICAgICAgICAgIFtpbWFnZUZpbGVdPVwic2VsZWN0ZWRGaWxlXCJcclxuICAgICAgICAgIFttYWludGFpbkFzcGVjdFJhdGlvXT1cImZhbHNlXCJcclxuICAgICAgICAgIFthdXRvQ3JvcF09XCJmYWxzZVwiXHJcbiAgICAgICAgICBbY29udGFpbldpdGhpbkFzcGVjdFJhdGlvXT1cImZhbHNlXCJcclxuICAgICAgICAgIFthc3BlY3RSYXRpb109XCI0IC8gM1wiXHJcbiAgICAgICAgICBbY3JvcHBlck1pbldpZHRoXT1cIjEyOFwiXHJcbiAgICAgICAgICBbb25seVNjYWxlRG93bl09XCJ0cnVlXCJcclxuICAgICAgICAgIFtyb3VuZENyb3BwZXJdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgW2NhbnZhc1JvdGF0aW9uXT1cIjBcIlxyXG4gICAgICAgICAgW3RyYW5zZm9ybV09XCJ0cmFuc2Zvcm1cIlxyXG4gICAgICAgICAgW2FsaWduSW1hZ2VdPVwiJ2xlZnQnXCJcclxuICAgICAgICAgIGZvcm1hdD1cInBuZ1wiXHJcbiAgICAgICAgICAoaW1hZ2VDcm9wcGVkKT1cImltYWdlQ3JvcHBlZCgkZXZlbnQpXCJcclxuICAgICAgICAgIFtyZXNpemVUb1dpZHRoXT1cImN1c3RvbVdpZHRoXCJcclxuICAgICAgICAgIFtyZXNpemVUb0hlaWdodF09XCJjdXN0b21IZWlnaHRcIlxyXG4gICAgICAgICAgW2NhbnZhc1JvdGF0aW9uXT1cImNhbnZhc1JvdGF0aW9uXCI+XHJcbiAgICAgICAgPC9pbWFnZS1jcm9wcGVyPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgY2xhc3M9XCJyb3cganVzdGlmeS1jb250ZW50LWNlbnRlciBtdC0yIG1iLTIgY3JvcC1sYXJnZVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbC0xMiBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG1hdC1yYWlzZWQtYnV0dG9uIGVxcC1hdHRhY2htZW50cy1jb25maXJtLWJ0biBtZS0yXCJcclxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAoY2xpY2spPVwiY29uZmlybUFkZEF0dGFjaG1lbnQoKVwiPlxyXG4gICAgICAgIHt7IGNvbmZpcm1MYWJlbCB9fVxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBtYXQtcmFpc2VkLWJ1dHRvbiBlcXAtYXR0YWNobWVudHMtYWJvcnQtYnRuXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhYm9ydEZpbGUoKVwiPlxyXG4gICAgICAgIHt7IGFib3J0TGFiZWwgfX1cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwicm93IGp1c3RpZnktY29udGVudC1jZW50ZXIgbXQtMiBtYi0yIGNyb3Atc21hbGxcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjb2wtNiBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIiBzdHlsZT1cImZvbnQtc2l6ZTogMjBweFwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhIGZhLXRpbWVzXCIgKGNsaWNrKT1cImFib3J0RmlsZSgpXCI+PC9pPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLTYgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCIgc3R5bGU9XCJmb250LXNpemU6IDIwcHhcIj5cclxuICAgICAgPGkgY2xhc3M9XCJmYSBmYS1jaGVja1wiIChjbGljayk9XCJjb25maXJtQWRkQXR0YWNobWVudCgpXCI+PC9pPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG48IS0tIFRFTVBMQVRFIFBFUiBGT1JNIERJIEFHR0lVTlRBIERJIFVOIExJTksgLS0+XHJcbjxuZy10ZW1wbGF0ZSAjYWRkaW5nTGlua1RlbXBsYXRlPlxyXG4gIDxzcGFuIGNsYXNzPVwibWItMVwiIHN0eWxlPVwiZm9udC1zaXplOiAyMHB4XCI+PGkgY2xhc3M9XCJmYSBmYS1saW5rXCI+PC9pPkluc2VyaXNjaSBsJ1VSTDwvc3Bhbj5cclxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cIm5ld0F0dGFjaG1lbnRGb3JtXCIgKm5nSWY9XCJuZXdBdHRhY2htZW50Rm9ybVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cInJvdyBtYi0yXCIgc3R5bGU9XCJoZWlnaHQ6IDgwcHhcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNvbC02IGQtZ3JpZCBnYXAtMiBteC1hdXRvXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwIG1iLTFcIj5cclxuICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcclxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7eyBmaWxlTmFtZUxhYmVsIH19XCJcclxuICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibmFtZVwiXHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwibmV3QXR0YWNobWVudC5GaWxlTmFtZVwiIC8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyIGQtZ3JpZCBnYXAtMlwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxyXG4gICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgIHJlcXVpcmVkXHJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxyXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkxpbmtcIlxyXG4gICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJwYXRoXCJcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJuZXdBdHRhY2htZW50LkZpbGVQYXRoXCIgLz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNvbC02IGQtZ3JpZCBnYXAtMlwiPlxyXG4gICAgICAgIDxidXR0b25cclxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnkgbWF0LXJhaXNlZC1idXR0b25cIlxyXG4gICAgICAgICAgKGNsaWNrKT1cInNlbGVjdGVkQXR0YWNobWVudCA9IG51bGw7IGFkZGluZ0xpbmtNb2RlID0gZmFsc2VcIlxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiPlxyXG4gICAgICAgICAge3sgZXhpdExhYmVsIH19XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLTYgZC1ncmlkIGdhcC0yXCI+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgbWF0LXJhaXNlZC1idXR0b25cIlxyXG4gICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiY29uZmlybUFkZEF0dGFjaG1lbnQoKTsgc2VsZWN0ZWRBdHRhY2htZW50ID0gbnVsbDsgYWRkaW5nTGlua01vZGUgPSBmYWxzZVwiPlxyXG4gICAgICAgICAge3sgc2F2ZUxhYmVsIH19XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9mb3JtPlxyXG48L25nLXRlbXBsYXRlPlxyXG4iXX0=
1247
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXFwLWF0dGFjaG1lbnRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2VxcC1hdHRhY2htZW50cy9zcmMvbGliL2VxcC1hdHRhY2htZW50cy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9lcXAtYXR0YWNobWVudHMvc3JjL2xpYi9lcXAtYXR0YWNobWVudHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFFTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUEwQixVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdwRSxPQUFPLGdCQUFnQixNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQXFCLHFCQUFxQixFQUFrQixNQUFNLG1CQUFtQixDQUFDO0FBQzNHLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3RFLE9BQU8sRUFBc0IsY0FBYyxFQUFrQyxNQUFNLDBCQUEwQixDQUFDO0FBRTlHLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O0FBS3RGLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDeEIsSUFBSSxPQUFPLENBQVMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7SUFDdEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztJQUNoQyxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUN4RCxNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUMsQ0FBQyxDQUFDLENBQUM7QUFPTCxNQUFNLE9BQU8sdUJBQXVCO0lBb1V4QjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUF4VVYsK0JBQStCO0lBRS9COztPQUVHO0lBQ3FCLGFBQWEsR0FBWSxLQUFLLENBQUM7SUFFdkQ7O09BRUc7SUFDa0IsVUFBVSxHQUFZLElBQUksQ0FBQztJQUVoRDs7T0FFRztJQUNtQixXQUFXLEdBQVcsaUJBQWlCLENBQUM7SUFFOUQ7O09BRUc7SUFDdUIsZUFBZSxHQUEwQixJQUFJLENBQUM7SUFFeEU7O09BRUc7SUFDd0IsZ0JBQWdCLEdBQW1CLElBQUksQ0FBQztJQUVuRTs7T0FFRztJQUNtQixXQUFXLEdBQVksSUFBSSxDQUFDO0lBRWxEOzs7T0FHRztJQUMwQixrQkFBa0IsR0FBWSxJQUFJLENBQUM7SUFFaEU7OztPQUdHO0lBQ3lCLGlCQUFpQixHQUFZLEtBQUssQ0FBQztJQUUvRDs7T0FFRztJQUN5QixpQkFBaUIsR0FBVyxxQkFBcUIsQ0FBQztJQUU5RTs7OztPQUlHO0lBQ3VCLGVBQWUsR0FBWSxLQUFLLENBQUM7SUFFM0Q7O09BRUc7SUFDeUIsaUJBQWlCLENBQVM7SUFFdEQ7O09BRUc7SUFDa0IsVUFBVSxHQUFZLEtBQUssQ0FBQztJQUVqRDs7T0FFRztJQUN5QixpQkFBaUIsR0FBWSxLQUFLLENBQUM7SUFFL0Q7Ozs7O09BS0c7SUFDNkIscUJBQXFCLEdBQVcsSUFBSSxDQUFDO0lBRXJFOzs7OztPQUtHO0lBQ3lCLGlCQUFpQixHQUFXLElBQUksQ0FBQztJQUU3RDs7T0FFRztJQUMwQixrQkFBa0IsR0FBYTtRQUMxRCxTQUFTLEVBQUUsR0FBRztRQUNkLGdCQUFnQixFQUFFLElBQUk7UUFDdEIsWUFBWSxFQUFFLElBQUk7S0FDbkIsQ0FBQztJQUVGOztPQUVHO0lBQ29CLFlBQVksR0FBMEIsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUV4Rzs7O09BR0c7SUFDK0IsdUJBQXVCLEdBQVksS0FBSyxDQUFDO0lBRTNFOzs7T0FHRztJQUM2QixxQkFBcUIsR0FBWSxJQUFJLENBQUM7SUFFdEU7OztPQUdHO0lBQzBCLGtCQUFrQixHQUFZLElBQUksQ0FBQztJQUVoRTs7O09BR0c7SUFDMEIsa0JBQWtCLEdBQVcsSUFBSSxDQUFDO0lBRS9EOztPQUVHO0lBQ0gsa0ZBQWtGO0lBRWxGOztPQUVHO0lBQzhCLHNCQUFzQixHQUFZLEtBQUssQ0FBQztJQUV6RTs7T0FFRztJQUNtQixXQUFXLEdBQVksSUFBSSxDQUFDO0lBRWxEOztPQUVHO0lBQ21DLDJCQUEyQixHQUFZLEtBQUssQ0FBQztJQUVuRjs7T0FFRztJQUNtQixXQUFXLEdBQTBCLEVBQUUsQ0FBQztJQUU5RDs7T0FFRztJQUN1QixlQUFlLENBQVM7SUFFekMsYUFBYSxHQUFXLEdBQUcsQ0FBQyxDQUFDLDZCQUE2QjtJQUMxRCxRQUFRLEdBQXVCLE9BQU8sQ0FBQyxDQUFDLFVBQVU7SUFDbEQsaUJBQWlCLEdBQVcsR0FBRyxDQUFDLENBQUMseUJBQXlCO0lBQzFELGtCQUFrQixHQUFXLEdBQUcsQ0FBQyxDQUFDLHVCQUF1QjtJQUVsRTs7T0FFRztJQUNxQixhQUFhLEdBQVcsV0FBVyxDQUFDO0lBQ25DLGNBQWMsR0FBVyxVQUFVLENBQUM7SUFDckMsYUFBYSxHQUFXLFVBQVUsQ0FBQztJQUNyQyxXQUFXLEdBQVcsU0FBUyxDQUFDO0lBQzlCLGFBQWEsR0FBVyxXQUFXLENBQUM7SUFDckMsWUFBWSxHQUFXLFdBQVcsQ0FBQztJQUNoQyxlQUFlLEdBQVcsYUFBYSxDQUFDO0lBQzNDLFlBQVksR0FBVyxVQUFVLENBQUM7SUFDcEMsVUFBVSxHQUFXLFNBQVMsQ0FBQztJQUNoQyxTQUFTLEdBQVcsT0FBTyxDQUFDO0lBQzVCLFNBQVMsR0FBVyxNQUFNLENBQUM7SUFDZCxzQkFBc0IsR0FBVyxvQkFBb0IsQ0FBQztJQUNuRSxTQUFTLEdBQVcsb0NBQW9DLENBQUM7SUFDakQsaUJBQWlCLEdBQVcsSUFBSSxDQUFDO0lBQy9CLG1CQUFtQixHQUFXLGdEQUFnRCxDQUFDO0lBQ3ZFLDJCQUEyQixHQUMvRCw4REFBOEQsQ0FBQztJQUN6Qiw2QkFBNkIsR0FDbkUsK0NBQStDLENBQUM7SUFDZix3QkFBd0IsR0FDekQsa0RBQWtELENBQUM7SUFDbEIsd0JBQXdCLEdBQ3pELGtEQUFrRCxDQUFDO0lBQ3RCLG9CQUFvQixHQUFXLDJCQUEyQixDQUFDO0lBQzlELGlCQUFpQixHQUFXLHlCQUF5QixDQUFDO0lBQ3ZELGdCQUFnQixHQUFXLGdCQUFnQixDQUFDO0lBQzdDLGVBQWUsR0FBVyxrQkFBa0IsQ0FBQztJQUM5RCxXQUFXLEdBQUcsYUFBYSxDQUFDO0lBQzVCLGNBQWMsR0FBRywyQkFBMkIsQ0FBQztJQUM3QyxhQUFhLEdBQUcscUJBQXFCLENBQUM7SUFDdEMscUJBQXFCLEdBQUcsZ0RBQWdELENBQUM7SUFDekUsZ0JBQWdCLEdBQUcsY0FBYyxDQUFDO0lBQ2xDLGtCQUFrQixHQUFHLGdCQUFnQixDQUFDO0lBQ3RDLFVBQVUsR0FBRyxPQUFPLENBQUM7SUFDckIsY0FBYyxHQUFHLG1CQUFtQixDQUFDO0lBQ3JDLGVBQWUsR0FBRyxpQ0FBaUMsQ0FBQztJQUNwRCxzQkFBc0IsR0FBRyxnQ0FBZ0MsQ0FBQztJQUMxRCxZQUFZLEdBQUcsY0FBYyxDQUFDO0lBQ3ZDLHlDQUF5QztJQUNoQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDVixRQUFRLEdBQXFCLE9BQU8sQ0FBQztJQUN4RCxZQUFZO0lBRVosZ0NBQWdDO0lBRWhDOztPQUVHO0lBQ08sc0JBQXNCLEdBQXdDLElBQUksWUFBWSxFQUF5QixDQUFDO0lBRWxIOztPQUVHO0lBQ08sa0JBQWtCLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7SUFFMUU7O09BRUc7SUFDMkIsa0JBQWtCLEdBQWlDLElBQUksWUFBWSxFQUFrQixDQUFDO0lBRXBIOztPQUVHO0lBQzJCLGtCQUFrQixHQUFpQyxJQUFJLFlBQVksRUFBa0IsQ0FBQztJQUVwSCxZQUFZO0lBRVosMkRBQTJEO0lBQzNELGFBQWEsR0FBbUIsRUFBb0IsQ0FBQztJQUNyRCxzQkFBc0IsR0FBMEIsRUFBRSxDQUFDO0lBQ25ELGNBQWMsR0FBRyxjQUFjLENBQUM7SUFDaEMsbUNBQW1DO0lBQ25DLGlCQUFpQixDQUFZO0lBQzdCLFlBQVksR0FBUyxJQUFJLENBQUM7SUFDMUIsYUFBYSxHQUFnQixJQUFJLENBQUM7SUFDbEMsYUFBYSxHQUFZLEtBQUssQ0FBQztJQUNxQixtQkFBbUIsQ0FBbUI7SUFDMUYsc0JBQXNCLENBQWlDO0lBQ0ssMkJBQTJCLENBQW1CO0lBQzFHLGtCQUFrQixDQUFpQztJQUNILGVBQWUsQ0FBbUI7SUFFakQsa0JBQWtCLENBQW1CO0lBQ3RFLFlBQVk7SUFFWixxRUFBcUU7SUFDckUsaUJBQWlCLEdBQVEsRUFBRSxDQUFDO0lBQzVCLFlBQVksR0FBUSxFQUFFLENBQUM7SUFDdkIsU0FBUyxHQUFtQixFQUFFLENBQUM7SUFDL0IsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNlLFlBQVksQ0FBd0I7SUFDN0MsVUFBVSxDQUFNO0lBQ3pDLFlBQVk7SUFFWixjQUFjLEdBQUcsY0FBYyxDQUFDO0lBQ2hDLGtCQUFrQixDQUFpQjtJQUVuQyxhQUFhLENBQVM7SUFDdEIsY0FBYyxDQUFTO0lBQ3ZCLFdBQVcsQ0FBUztJQUNwQixZQUFZLENBQVM7SUFFaUMscUJBQXFCLENBQW1CO0lBQ2hELGFBQWEsQ0FBbUI7SUFFOUUsU0FBUyxDQUFPO0lBRWhCLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFFaEMsbUNBQW1DO0lBQ25DLDRCQUE0QjtJQUM1QixRQUFRLEdBQUcsS0FBSyxDQUFDO0lBQ2pCLEtBQUssR0FBRztRQUNOLE9BQU8sRUFBRSxLQUFnQjtRQUN6QixJQUFJLEVBQUUsU0FBZ0M7UUFDdEMsSUFBSSxFQUFFLEVBQVk7UUFDbEIsU0FBUyxFQUFFLENBQVE7S0FDcEIsQ0FBQztJQUVGLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFDcEIsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNuQixJQUFJLGtCQUFrQixLQUFhLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXJGLDRDQUE0QztJQUM1QyxjQUFjLENBQUMsS0FBYTtRQUMxQixJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssSUFBSSxDQUFDO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDM0MsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2YsTUFBTSxLQUFLLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRCxPQUFPLEdBQUcsVUFBVSxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDMUUsQ0FBQztJQUVELHNEQUFzRDtJQUN0RCxTQUFTLENBQUMsT0FBZSxFQUFFLE9BQTRCLFNBQVMsRUFBRSxVQUFVLEdBQUcsSUFBSTtRQUNqRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTtZQUNyRCxPQUFPO1NBQ1I7UUFFRCwyQ0FBMkM7UUFDM0MsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTtZQUN4QixZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNwQztRQUVELDhCQUE4QjtRQUM5QixNQUFNLFFBQVEsR0FBRyxVQUFVLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQztRQUVwRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7UUFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUUxQixtRUFBbUU7UUFDbkUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDN0IsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2YsQ0FBQztJQUVELFVBQVUsQ0FBQTtJQUVWLFlBQ1UsTUFBaUIsRUFDakIsV0FBd0IsRUFDeEIsU0FBdUIsRUFDdkIsSUFBZ0IsRUFDaEIsRUFBcUIsRUFDckIsb0JBQTBDO1FBTDFDLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsY0FBUyxHQUFULFNBQVMsQ0FBYztRQUN2QixTQUFJLEdBQUosSUFBSSxDQUFZO1FBQ2hCLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBQ3JCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7SUFDaEQsQ0FBQztJQUVMLFFBQVE7UUFFTiw4REFBOEQ7UUFDOUQsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFFbEMsdUhBQXVIO1FBQ3ZILElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCO1lBQ3pCLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJO2dCQUFFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxTQUFTLENBQUM7O2dCQUNoRSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsR0FBRyxDQUFDO1FBRXBDLHNIQUFzSDtRQUN0SCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sSUFBSSxDQUFDO1lBQ3JELElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3BGLElBQ0gsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxjQUFjLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxjQUFjLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQ2xIO1lBQ0EsMEJBQTBCLENBQUMsT0FBTyxDQUNoQyxzRkFBc0YsQ0FDdkYsQ0FBQztZQUNGLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3hGO1FBRUQsSUFBSSxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUk7WUFBRSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksS0FBSyxFQUFrQixDQUFDO1FBRXJGLGdFQUFnRTtRQUNoRSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO1lBQ3JFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1NBQ2xEO1FBRUQsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFNUIsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNqQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztTQUMvQztJQUNILENBQUM7SUFFRCxXQUFXLENBQUMsSUFBc0I7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVELG9EQUFvRDtJQUM1QywwQkFBMEI7UUFDaEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksRUFBRSxDQUFDO2FBQy9DLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDaEIsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUMsbUJBQW1CLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFdEcsdURBQXVEO1FBQ3ZELElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTO1lBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVELHNFQUFzRTtJQUMvRCxlQUFlLENBQUMsTUFBYztRQUNuQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RCLHNDQUFzQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sR0FBRyxHQUFHLFFBQVEsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDcEUsZ0JBQWdCO1FBQ2hCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztRQUNoQixJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTyxHQUFHLENBQUMsQ0FBQzthQUMvQixJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO1lBQUUsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUN4Qyw0Q0FBNEM7UUFDNUMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELG9CQUFvQjtRQUNsQixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ2pDLENBQUMsQ0FBQyxPQUFPLEdBQUcsdUJBQXVCLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2hGLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtDQUFrQztJQUVsQzs7O09BR0c7SUFDSCxnQkFBZ0IsQ0FBQyxPQUF1QjtRQUN0QywwQkFBMEIsQ0FBQyxPQUFPLENBQ2hDLElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsR0FBRyxFQUFFO1lBQ0gsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdkUsQ0FBQyxFQUNELElBQUksRUFDSixJQUFJLENBQUMsaUJBQWlCLENBQ3ZCLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsd0JBQXdCLENBQUMsZUFBdUI7UUFDOUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXZELElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFFakUsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQztRQUN6QixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7WUFDMUIsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztnQkFDMUIsVUFBVSxDQUFDLEdBQUcsRUFBRTtvQkFDZCxJQUFJLENBQUMsZUFBZSxHQUFHLEdBQUcsQ0FBQztnQkFDN0IsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ1YsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUdEOzs7T0FHRztJQUNILGNBQWMsQ0FBQyxVQUEwQjtRQUN2QyxJQUFJLFVBQVUsQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLElBQUksRUFBRTtZQUNwRCxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDM0MsT0FBTztTQUNSO1FBRUQsSUFBSSxVQUFVLENBQUMsY0FBYyxJQUFJLFVBQVUsQ0FBQyxlQUFlLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRTtZQUNsRixJQUFJLE1BQU0sR0FBRyxRQUFRLFVBQVUsQ0FBQyxlQUFlLFdBQVcsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3RGLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7WUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDZDthQUFNO1lBQ0wsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUMxQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsaUJBQWlCLENBQUMsVUFBMEI7UUFDMUMsSUFBSSxVQUFVLENBQUMsY0FBYyxJQUFJLGNBQWMsQ0FBQyxJQUFJO1lBQUUsT0FBTyxhQUFhLENBQUM7O1lBQ3RFLE9BQU8sdUJBQXVCLENBQUMseUJBQXlCLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFRCxZQUFZO0lBRVo7O09BRUc7SUFDSCxPQUFPLENBQUMsY0FBOEIsRUFBRSxVQUFVLEdBQUcsSUFBSTtRQUN2RCxJQUFJLGNBQWMsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQ3pDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1NBQy9CO2FBQU0sSUFBSSxjQUFjLElBQUksY0FBYyxDQUFDLElBQUksRUFBRTtZQUNoRCxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDcEI7YUFBTTtZQUNMLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1NBQzFCO0lBQ0gsQ0FBQztJQUVELG9CQUFvQjtRQUNsQiwyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO1lBQzlDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDOUQsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7WUFDbkMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7WUFDbkMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztZQUNqQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQ2hDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsY0FBYyxHQUFHLElBQUk7UUFDekIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFvQixDQUFDO1FBQzFDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLEtBQUssRUFBa0IsQ0FBQztRQUMxRCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsSUFBSSxJQUFJLENBQUMsaUJBQWlCO1lBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBRTNELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUVqQyxJQUFJLGNBQWMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLGtCQUFrQjtZQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN4RixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLEVBQUU7WUFDbEMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFO2dCQUM1RCxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUM7YUFDM0M7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDO2FBQ3JDO1NBQ0Y7YUFBTTtZQUNMLE9BQU8sQ0FDTCxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUNoQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ0osQ0FBQyxDQUFDLENBQUMsY0FBYyxJQUFJLGNBQWMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDO2dCQUM5RCxDQUFDLENBQUMsQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FDM0QsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUNiLENBQUM7U0FDSDtJQUNILENBQUM7SUFFRCxvQkFBb0I7UUFDbEIsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ25ELElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMxRjtRQUVELElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksRUFBRTtZQUNsQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxJQUFJLGNBQWMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVE7Z0JBQzFGLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDO1lBRTVELElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJO2dCQUFFLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxLQUFLLEVBQWtCLENBQUM7WUFFckYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQy9DO2FBQU07WUFDTCxJQUFJLElBQUksQ0FBQyxzQkFBc0IsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sSUFBSSxDQUFDO2dCQUFFLE9BQU87WUFFM0YsSUFBSSxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUk7Z0JBQUUsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLEtBQUssRUFBa0IsQ0FBQztZQUVyRixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1NBQ2pGO1FBRUQsb0VBQW9FO1FBRXBFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXZELElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUU7WUFDOUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1NBQ2xDO1FBRUQsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsS0FBSyxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQzdELElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBb0IsQ0FBQztZQUMxQyxJQUFJLElBQUksQ0FBQyxpQkFBaUI7Z0JBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxDQUFDO1NBQzVEO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQUMsR0FBbUI7UUFDekMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRTFELElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQ2pFLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQy9ELDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztnQkFDbEUsT0FBTzthQUNSO2lCQUFNLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ3RFLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztnQkFDbEUsT0FBTzthQUNSO1NBQ0Y7UUFFRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsRUFBRTtZQUM1RyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtpQkFDM0IsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ1osSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDO1lBQzlELENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDYiwwQkFBMEIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEMsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQ2pFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsQ0FDaEYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FDakMsQ0FBQztTQUNIO2FBQU0sSUFDTCxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTztZQUMvQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjO1lBQ3ZDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixFQUM1QztZQUNBLDBCQUEwQixDQUFDLElBQUksQ0FBQyw4REFBOEQsQ0FBQyxDQUFDO1lBQ2hHLE9BQU87U0FDUjthQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFO1lBQzNDLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQzlELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsQ0FDaEYsb0NBQW9DO29CQUNwQyxJQUFJLENBQUMsaUJBQWlCO29CQUN0QixHQUFHO29CQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRO29CQUNoQyxnQkFBZ0IsQ0FDakIsQ0FBQzthQUNIO2lCQUFNO2dCQUNMLDBCQUEwQixDQUFDLElBQUksQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO2dCQUNqRixPQUFPO2FBQ1I7U0FDRjtRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDbkMsWUFBWSxFQUFFLElBQUk7WUFDbEIsV0FBVyxFQUFFLElBQUk7U0FDbEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUI7UUFDckIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBaUIsSUFBSSxDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3pHLENBQUM7SUFFRCxtQ0FBbUM7SUFFbkM7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLGdCQUF5QixLQUFLO1FBQ3JELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzNCLGlFQUFpRTtRQUNqRSxNQUFNLFlBQVksR0FBVyxhQUFhO1lBQ3hDLENBQUMsQ0FBRSxLQUFnQjtZQUNuQixDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBRSxLQUFLLENBQUMsTUFBMkIsRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7UUFFaEUsTUFBTSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztRQUV4RixxSEFBcUg7UUFDckgsb0VBQW9FO1FBQ3BFLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksRUFBRTtZQUNqRSxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQztZQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVk7Z0JBQUUsT0FBTztZQUUvQixpQ0FBaUM7WUFDakMsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNGLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLEtBQUssRUFBa0IsQ0FBQztZQUMxRCxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUVyRCxzSEFBc0g7WUFDdEgsSUFBSSxjQUFjLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN0RSxJQUFJLGNBQWMsSUFBSSxLQUFLO2dCQUFFLE9BQU87WUFFcEMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFFNUIsNkhBQTZIO1lBQzdILDhDQUE4QztZQUM5QyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxJQUFJLElBQUksRUFBRTtnQkFDdEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUV2QyxxRkFBcUY7Z0JBQ3JGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUV2QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtvQkFDL0QsWUFBWSxFQUFFLElBQUk7b0JBQ2xCLFdBQVcsRUFBRSxJQUFJO29CQUNqQixLQUFLLEVBQUUsS0FBSztvQkFDWixTQUFTLEVBQUUsS0FBSztvQkFDaEIsUUFBUSxFQUFFLE1BQU07aUJBQ2pCLENBQUMsQ0FBQzthQUNKO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO2dCQUMzQixJQUFJLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ25FLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUM7Z0JBQzVELElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxHQUFHLFlBQVksQ0FBQyxXQUFXLENBQUM7Z0JBQzlELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2FBQzdCO1NBQ0Y7YUFBTTtZQUNMLElBQUksQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxJQUFJLENBQUM7Z0JBQUUsT0FBTztZQUVsRSxJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQjtnQkFBRSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsRUFBRSxDQUFDO1lBQ25FLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDbEQsSUFBSSxhQUFhLEdBQW1CLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxDQUM3RSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUNyQixJQUFJLEVBQ0osSUFBSSxDQUNMLENBQUM7Z0JBQ0Ysc0hBQXNIO2dCQUN0SCxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksY0FBYyxJQUFJLEtBQUs7b0JBQUUsT0FBTztnQkFFcEMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUNqRDtZQUNELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1NBQzdCO1FBRUQsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDeEIsMkRBQTJEO1FBQzNELElBQUksY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDdEQsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsU0FBUyxDQUNaLEdBQUcsVUFBVSxDQUFDLE1BQU0sbUJBQW1CLGNBQWMsQ0FBQyxNQUFNLHVDQUF1QyxTQUFTLElBQUksRUFDaEgsT0FBTyxDQUNSLENBQUM7U0FDSDtRQUNELDZCQUE2QjthQUN4QixJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1NBQzlEO1FBQ0QsOEJBQThCO2FBQ3pCLElBQUksY0FBYyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDN0QsSUFBSSxDQUFDLFNBQVMsQ0FDWixHQUFHLFVBQVUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLHNCQUFzQixJQUFJLGdDQUFnQyxFQUFFLEVBQ3pGLFNBQVMsQ0FDVixDQUFDO1NBQ0g7UUFFRCw2R0FBNkc7UUFDN0csSUFBSSxDQUFDLGFBQWE7WUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVPLGNBQWMsQ0FBQyxZQUFvQixFQUFFLGFBQXNCO1FBQ2pFLE1BQU0sVUFBVSxHQUFXLEVBQUUsQ0FBQztRQUM5QixNQUFNLGNBQWMsR0FBYSxFQUFFLENBQUM7UUFFcEMsS0FBSyxNQUFNLElBQUksSUFBSSxZQUFZLEVBQUU7WUFDL0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQzNDLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQ25DLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2hDO2lCQUFNO2dCQUNMLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDdkI7U0FDRjtRQUVELHNEQUFzRDtRQUN0RCxJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLFNBQVMsQ0FBQywwQkFBMEIsU0FBUyxhQUFhLElBQUksQ0FBQyxhQUFhLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztTQUNqRztRQUVELDhCQUE4QjtRQUM5QixJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQzNCLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQUcsS0FBSyxDQUFDLE1BQTJCLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQzthQUFFO1lBQ3RFLE9BQU87U0FDUjtRQUVELE9BQU8sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxLQUFLLENBQUMsZ0NBQWdDLENBQzVDLFdBQWlCLEVBQ2pCLFlBQXFCLElBQUksRUFDekIsV0FBb0IsS0FBSztRQUV6QixJQUFJLGFBQWEsR0FBbUIsRUFBb0IsQ0FBQztRQUN6RCxpQ0FBaUM7UUFDakMsYUFBYSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDO1FBQ25ELGFBQWEsQ0FBQyxlQUFlLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNqRCxhQUFhLENBQUMsUUFBUSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUM7UUFDMUMsYUFBYSxDQUFDLGFBQWEsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM3RixhQUFhLENBQUMsT0FBTyxHQUFHLHVCQUF1QixDQUFDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV6RixJQUFJLFNBQVMsSUFBSSxJQUFJLEVBQUU7WUFDckIsSUFBSSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDN0QsYUFBYSxDQUFDLGNBQWMsR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDO1lBQ3ZELGFBQWEsQ0FBQyxlQUFlLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQztZQUV6RCxJQUFJLGFBQWEsQ0FBQyxPQUFPLElBQUksYUFBYSxDQUFDLGNBQWMsSUFBSSxRQUFRLEVBQUU7Z0JBQ3JFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLFlBQVksQ0FBQyxXQUFXLFdBQVcsWUFBWSxDQUFDLFVBQVUsRUFBRSxFQUFFLGFBQWEsQ0FBQyxDQUFDO2FBQy9HO1NBQ0Y7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxLQUFLLENBQUMsaUJBQWlCLENBQUMsV0FBaUI7UUFDL0MsSUFBSSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0MsSUFBSSxXQUFXLEdBQVcsSUFBSSxDQUFDO1FBQy9CLElBQUksVUFBVSxFQUFFO1lBQ2QsaUhBQWlIO1lBQ2pILDJHQUEyRztZQUMzRyxtSEFBbUg7WUFDbkgsV0FBVyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRSwwRkFBMEY7WUFDMUYsVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDdkM7UUFFRCxJQUFJLE1BQU0sR0FBRztZQUNYLFVBQVUsRUFBRSxVQUFVO1lBQ3RCLFdBQVcsRUFBRSxXQUFXO1NBQ3pCLENBQUM7UUFFRixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssa0JBQWtCO1FBQ3hCLElBQ0UsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM5RSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUVoSCxPQUFPLEtBQUssQ0FBQztRQUVmLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLEdBQUc7WUFBRSxPQUFPLElBQUksQ0FBQztRQUUvQyx3R0FBd0c7UUFDeEcsSUFBSSxRQUFRLEdBQVksSUFBSSxDQUFDO1FBQzdCLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUk7WUFBRSxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2xHO1lBQ0gsSUFBSSxpQkFBaUIsR0FBYSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdFLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7b0JBQUUsUUFBUSxHQUFHLEtBQUssQ0FBQztZQUMvRCxDQUFDLENBQUMsQ0FBQztTQUNKO1FBRUQscUhBQXFIO1FBQ3JILElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksRUFBRTtZQUMvQyxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQzlFLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM5RCxJQUFJLFFBQVE7b0JBQUUsTUFBTTthQUNyQjtTQUNGO1FBQ0QsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyx1QkFBdUIsQ0FBQyxhQUFhO1FBQzNDLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLElBQUksYUFBYSxDQUFDLE9BQU8sSUFBSSxJQUFJLEVBQUU7WUFDakUsMEJBQTBCLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNqQixPQUFPLEtBQUssQ0FBQztTQUNkO2FBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFO1lBQ3JDLDBCQUEwQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQztZQUNyRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDakIsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELDRCQUE0QjtJQUU1QixrQkFBa0IsQ0FBQyxHQUFRO1FBQ3pCLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7UUFDaEMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFO1lBQ3pCLE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7WUFDMUIsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUM1QixLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUU7Z0JBQ3BCLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDakQsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUUvQyxJQUFJLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxFQUFFO29CQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztvQkFDeEIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7aUJBQ25GO3FCQUFNO29CQUNMLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDL0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUM5QztZQUNILENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELHlCQUF5QjtRQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxTQUFpQjtRQUNsQyxJQUFJLFNBQVMsSUFBSSxHQUFHLEVBQUU7WUFDcEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQy9GO2FBQU0sSUFBSSxTQUFTLElBQUksR0FBRyxFQUFFO1lBQzNCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUMvRjtJQUNILENBQUM7SUFFRCxZQUFZLENBQUMsS0FBd0I7UUFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsbUJBQW1CLENBQUMsSUFBSSxFQUFFLGFBQTZCO1FBQ3JELElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztRQUVoQixJQUFJLElBQUksR0FBUSxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbkMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBRXhDOztXQUVHO1FBQ0gsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLGNBQWMsRUFBRSxFQUFFO1lBQ3RELElBQUksVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7WUFFbEMsMkZBQTJGO1lBQzNGLFVBQVUsQ0FBQyxNQUFNLEdBQUc7Z0JBQ2xCLElBQUksWUFBWSxHQUFXLFVBQVUsQ0FBQyxNQUFNLENBQUM7Z0JBQzdDLElBQUksTUFBTSxHQUFHLFVBQVUsQ0FBQztnQkFDeEIsYUFBYSxDQUFDLGNBQWMsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNwRyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztnQkFDM0IsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7b0JBQzFCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztpQkFDakM7WUFDSCxDQUFDLENBQUM7WUFFRixVQUFVLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtCQUFrQjtJQUNsQiw4QkFBOEI7SUFDOUIscUNBQXFDO0lBQ3JDLHNDQUFzQztJQUN0QyxJQUFJO0lBRUosVUFBVTtRQUNSLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFTyxlQUFlO1FBQ3JCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ3RDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDZixHQUFHLElBQUksQ0FBQyxTQUFTO1lBQ2pCLEtBQUssRUFBRSxRQUFRO1lBQ2YsS0FBSyxFQUFFLFFBQVE7U0FDaEIsQ0FBQztJQUNKLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNmLEdBQUcsSUFBSSxDQUFDLFNBQVM7WUFDakIsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLO1NBQzdCLENBQUM7SUFDSixDQUFDO0lBRUQsWUFBWTtRQUNWLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDZixHQUFHLElBQUksQ0FBQyxTQUFTO1lBQ2pCLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSztTQUM3QixDQUFDO0lBQ0osQ0FBQztJQUVELFlBQVk7SUFFWjs7T0FFRztJQUNILFNBQVM7UUFDUCxJQUFJLElBQUksQ0FBQyxVQUFVO1lBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUU5RCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztRQUUzQixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDeEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBRTFDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLEtBQUssRUFBa0IsQ0FBQztRQUUxRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUN4QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUUxQixJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVELFlBQVk7SUFFWixXQUFXLENBQUMsS0FBZ0I7UUFDMUIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUV0QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQztRQUV4QyxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFRCw4R0FBOEc7SUFDOUcseUhBQXlIO0lBQ3pILGlCQUFpQjtRQUNmLElBQUksT0FBTyxHQUFHO1lBQ1osT0FBTyxFQUFFLENBQUMsS0FBWSxFQUFFLEVBQUU7Z0JBQ3hCLE1BQU0sR0FBRyxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ2pDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDL0IsR0FBRyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxVQUFVLHVCQUF1QixDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBQzFHLEdBQUcsQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDO2dCQUUxQixHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtvQkFDaEIsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQztvQkFDMUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUNsRSxJQUFJLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUN4QixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDckMsQ0FBQyxDQUFDO2dCQUVGLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNiLENBQUM7WUFDRCxRQUFRLEVBQUUsUUFBUTtZQUNsQixXQUFXLEVBQUUsS0FBSztZQUNsQixVQUFVLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQztTQUM5RCxDQUFDO1FBQ0YsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQsbUhBQW1IO0lBQ25ILFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBUztRQUMzQixJQUNHLEtBQUssQ0FBQyxNQUE0QixDQUFDLE9BQU8sS0FBSyxRQUFRO1lBQ3ZELEtBQUssQ0FBQyxNQUE0QixDQUFDLE9BQU8sS0FBSyxPQUFPO1lBQ3ZELElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxFQUMzQjtZQUNBLE9BQU87U0FDUjtRQUNELFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQseURBQXlEO0lBQ3pELDZCQUE2QjtJQUM3QixnQ0FBZ0M7SUFDaEMsK0NBQStDO0lBQy9DLHdDQUF3QztJQUN4QyxrRUFBa0U7SUFDbEUsK0RBQStEO0lBQy9ELDBEQUEwRDtJQUUxRCxpQ0FBaUM7SUFDakMsSUFBSTtJQUVKOztPQUVHO0lBQ0gsc0JBQXNCO1FBQ3BCLGlDQUFpQztRQUNqQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7WUFDOUMsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2QsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7U0FDekUsQ0FBQyxDQUFDO1FBRUgscUJBQXFCO1FBQ3JCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUMxRCxLQUFLLEVBQUUsT0FBTztTQUNmLENBQUMsQ0FBQztRQUVILHlDQUF5QztRQUN6QyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3pDLElBQUksTUFBTSxFQUFFO2dCQUNWLHdEQUF3RDtnQkFDeEQsTUFBTSxhQUFhLEdBQW1CO29CQUNwQyxFQUFFLEVBQUUsQ0FBQztvQkFDTCxjQUFjLEVBQUUsY0FBYyxDQUFDLElBQUk7b0JBQ25DLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtvQkFDekIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO29CQUN6QixPQUFPLEVBQUUsS0FBSztpQkFDZixDQUFDO2dCQUVGLDZFQUE2RTtnQkFDN0UsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUc5QyxrREFBa0Q7Z0JBQ2xELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2FBQzdCO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBSUQsOENBQThDO0lBQzlDLFlBQVksQ0FBQyxHQUFtQjtRQUM5QixPQUFPO1lBQ0wsY0FBYyxFQUFFLElBQUk7WUFDcEIsV0FBVyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVztZQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsS0FBSyxPQUFPO1lBQ3ZDLGFBQWEsRUFBRSxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVE7WUFDekMsWUFBWSxFQUFFLElBQUksQ0FBQyxRQUFRLEtBQUssT0FBTztZQUN2QywrREFBK0Q7U0FDaEUsQ0FBQztJQUNKLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUseUJBQXlCO1FBQ3ZCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLHFDQUFxQztRQUU3RCxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFO1lBQzdCLFFBQVEsR0FBRyxPQUFPLENBQUM7U0FDcEI7YUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFO1lBQ3BDLFFBQVEsR0FBRyxPQUFPLENBQUM7U0FDcEI7YUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFO1lBQ3JDLFFBQVEsR0FBRyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxDQUFDO1NBQzFDO1FBRUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQzFDLENBQUM7d0dBem9DVSx1QkFBdUI7NEZBQXZCLHVCQUF1QixzdUdBK1B2QixxQkFBcUIseVhDcFNsQyx1d3BCQWtlYzs7NEZEN2JELHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDRSxpQkFBaUI7K05BVUgsYUFBYTtzQkFBcEMsS0FBSzt1QkFBQyxlQUFlO2dCQUtELFVBQVU7c0JBQTlCLEtBQUs7dUJBQUMsWUFBWTtnQkFLRyxXQUFXO3NCQUFoQyxLQUFLO3VCQUFDLGFBQWE7Z0JBS00sZUFBZTtzQkFBeEMsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBS0csZ0JBQWdCO3NCQUExQyxLQUFLO3VCQUFDLGtCQUFrQjtnQkFLSCxXQUFXO3NCQUFoQyxLQUFLO3VCQUFDLGFBQWE7Z0JBTVMsa0JBQWtCO3NCQUE5QyxLQUFLO3VCQUFDLG9CQUFvQjtnQkFNQyxpQkFBaUI7c0JBQTVDLEtBQUs7dUJBQUMsbUJBQW1CO2dCQUtFLGlCQUFpQjtzQkFBNUMsS0FBSzt1QkFBQyxtQkFBbUI7Z0JBT0EsZUFBZTtzQkFBeEMsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBS0ksaUJBQWlCO3NCQUE1QyxLQUFLO3VCQUFDLG1CQUFtQjtnQkFLTCxVQUFVO3NCQUE5QixLQUFLO3VCQUFDLFlBQVk7Z0JBS1MsaUJBQWlCO3NCQUE1QyxLQUFLO3VCQUFDLG1CQUFtQjtnQkFRTSxxQkFBcUI7c0JBQXBELEtBQUs7dUJBQUMsdUJBQXVCO2dCQVFGLGlCQUFpQjtzQkFBNUMsS0FBSzt1QkFBQyxtQkFBbUI7Z0JBS0csa0JBQWtCO3NCQUE5QyxLQUFLO3VCQUFDLG9CQUFvQjtnQkFTSixZQUFZO3NCQUFsQyxLQUFLO3VCQUFDLGNBQWM7Z0JBTWEsdUJBQXVCO3NCQUF4RCxLQUFLO3VCQUFDLHlCQUF5QjtnQkFNQSxxQkFBcUI7c0JBQXBELEtBQUs7dUJBQUMsdUJBQXVCO2dCQU1ELGtCQUFrQjtzQkFBOUMsS0FBSzt1QkFBQyxvQkFBb0I7Z0JBTUUsa0JBQWtCO3NCQUE5QyxLQUFLO3VCQUFDLG9CQUFvQjtnQkFVTSxzQkFBc0I7c0JBQXRELEtBQUs7dUJBQUMsd0JBQXdCO2dCQUtULFdBQVc7c0JBQWhDLEtBQUs7dUJBQUMsYUFBYTtnQkFLa0IsMkJBQTJCO3NCQUFoRSxLQUFLO3VCQUFDLDZCQUE2QjtnQkFLZCxXQUFXO3NCQUFoQyxLQUFLO3VCQUFDLGFBQWE7Z0JBS00sZUFBZTtzQkFBeEMsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBRWYsYUFBYTtzQkFBckIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBS2tCLGFBQWE7c0JBQXBDLEtBQUs7dUJBQUMsZUFBZTtnQkFDRyxjQUFjO3NCQUF0QyxLQUFLO3VCQUFDLGdCQUFnQjtnQkFDQyxhQUFhO3NCQUFwQyxLQUFLO3VCQUFDLGVBQWU7Z0JBQ0EsV0FBVztzQkFBaEMsS0FBSzt1QkFBQyxhQUFhO2dCQUNJLGFBQWE7c0JBQXBDLEtBQUs7dUJBQUMsZUFBZTtnQkFDQyxZQUFZO3NCQUFsQyxLQUFLO3VCQUFDLGNBQWM7Z0JBQ0ssZUFBZTtzQkFBeEMsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBQ0QsWUFBWTtzQkFBbEMsS0FBSzt1QkFBQyxjQUFjO2dCQUNBLFVBQVU7c0JBQTlCLEtBQUs7dUJBQUMsWUFBWTtnQkFDQyxTQUFTO3NCQUE1QixLQUFLO3VCQUFDLFdBQVc7Z0JBQ0UsU0FBUztzQkFBNUIsS0FBSzt1QkFBQyxXQUFXO2dCQUNlLHNCQUFzQjtzQkFBdEQsS0FBSzt1QkFBQyx3QkFBd0I7Z0JBQ1gsU0FBUztzQkFBNUIsS0FBSzt1QkFBQyxXQUFXO2dCQUNVLGlCQUFpQjtzQkFBNUMsS0FBSzt1QkFBQyxtQkFBbUI7Z0JBQ0ksbUJBQW1CO3NCQUFoRCxLQUFLO3VCQUFDLHFCQUFxQjtnQkFDVSwyQkFBMkI7c0JBQWhFLEtBQUs7dUJBQUMsNkJBQTZCO2dCQUVJLDZCQUE2QjtzQkFBcEUsS0FBSzt1QkFBQywrQkFBK0I7Z0JBRUgsd0JBQXdCO3NCQUExRCxLQUFLO3VCQUFDLDBCQUEwQjtnQkFFRSx3QkFBd0I7c0JBQTFELEtBQUs7dUJBQUMsMEJBQTBCO2dCQUVGLG9CQUFvQjtzQkFBbEQsS0FBSzt1QkFBQyxzQkFBc0I7Z0JBQ0QsaUJBQWlCO3NCQUE1QyxLQUFLO3VCQUFDLG1CQUFtQjtnQkFDQyxnQkFBZ0I7c0JBQTFDLEtBQUs7dUJBQUMsa0JBQWtCO2dCQUNDLGVBQWU7c0JBQXhDLEtBQUs7dUJBQUMsaUJBQWlCO2dCQUNmLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDYSxRQUFRO3NCQUExQixLQUFLO3VCQUFDLFVBQVU7Z0JBUVAsc0JBQXNCO3NCQUEvQixNQUFNO2dCQUtHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFLdUIsa0JBQWtCO3NCQUEvQyxNQUFNO3VCQUFDLG9CQUFvQjtnQkFLRSxrQkFBa0I7c0JBQS9DLE1BQU07dUJBQUMsb0JBQW9CO2dCQWF3QixtQkFBbUI7c0JBQXRFLFNBQVM7dUJBQUMscUJBQXFCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUVVLDJCQUEyQjtzQkFBdEYsU0FBUzt1QkFBQyw2QkFBNkIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBRVYsZUFBZTtzQkFBOUQsU0FBUzt1QkFBQyxpQkFBaUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBRWIsa0JBQWtCO3NCQUFsRCxTQUFTO3VCQUFDLG9CQUFvQjtnQkFRRyxZQUFZO3NCQUE3QyxTQUFTO3VCQUFDLHFCQUFxQjtnQkFDUCxVQUFVO3NCQUFsQyxTQUFTO3VCQUFDLFlBQVk7Z0JBVytCLHFCQUFxQjtzQkFBMUUsU0FBUzt1QkFBQyx1QkFBdUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ04sYUFBYTtzQkFBMUQsU0FBUzt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5pbXBvcnQge1xyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBUZW1wbGF0ZVJlZixcclxuICBWaWV3Q2hpbGRcclxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgRm9ybUdyb3VwLCBWYWxpZGF0b3JzIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XHJcbmltcG9ydCB7IE1hdERpYWxvZywgTWF0RGlhbG9nUmVmIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2RpYWxvZ1wiO1xyXG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tIFwiQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3NlclwiO1xyXG5pbXBvcnQgaW1hZ2VDb21wcmVzc2lvbiBmcm9tIFwiYnJvd3Nlci1pbWFnZS1jb21wcmVzc2lvblwiO1xyXG5pbXBvcnQgeyBiYXNlNjRUb0ZpbGUsIEltYWdlQ3JvcHBlZEV2ZW50LCBJbWFnZUNyb3BwZXJDb21wb25lbnQsIEltYWdlVHJhbnNmb3JtIH0gZnJvbSBcIm5neC1pbWFnZS1jcm9wcGVyXCI7XHJcbmltcG9ydCB7IEF0dGFjaG1lbnRIZWxwZXJTZXJ2aWNlIH0gZnJvbSBcIi4vaGVscGVycy9hdHRhY2htZW50LmhlbHBlclwiO1xyXG5pbXBvcnQgeyBBdHRhY2htZW50Q2FyZFNpemUsIEF0dGFjaG1lbnRUeXBlLCBDcm9wT3B0aW9uRW51bSwgSUF0dGFjaG1lbnREVE8gfSBmcm9tIFwiLi9pbnRlcmZhY2VzL0lBdHRhY2htZW50XCI7XHJcbmltcG9ydCB7IElPcHRpb25zIH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9JT3B0aW9uc1wiO1xyXG5pbXBvcnQgeyBFcXBBdHRhY2htZW50RGlhbG9nU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL2VxcC1hdHRhY2htZW50LWRpYWxvZy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IEVxcEF0dGFjaG1lbnRTZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvZXFwLWF0dGFjaG1lbnQuc2VydmljZVwiO1xyXG5cclxuZGVjbGFyZSB2YXIgRHJvcGJveDogYW55O1xyXG5cclxuY29uc3QgdG9CYXNlNjQgPSAoZmlsZSkgPT5cclxuICBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiByZXNvbHZlKHJlYWRlci5yZXN1bHQudG9TdHJpbmcoKSk7XHJcbiAgICByZWFkZXIub25lcnJvciA9IChlcnJvcikgPT4gcmVqZWN0KGVycm9yKTtcclxuICB9KTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcImVxcC1hdHRhY2htZW50c1wiLFxyXG4gIHRlbXBsYXRlVXJsOiBcIi4vZXFwLWF0dGFjaG1lbnRzLmNvbXBvbmVudC5odG1sXCIsXHJcbiAgc3R5bGVVcmxzOiBbXCIuL2VxcC1hdHRhY2htZW50cy5jb21wb25lbnQuc2Nzc1wiXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRXFwQXR0YWNobWVudHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIC8vI3JlZ2lvbiBASW5wdXQgZGVsIGNvbXBvbmVudGVcclxuXHJcbiAgLyoqXHJcbiAgICogU2UgVFJVRSBhbGxvcmEgbmFzY29uZGUgbGEgY29sb25uYSBwZXIgbGUgYXppb25pIHN1bGwnYWxsZWdhdG8gKG5lbCBjYXNvIFwibXVsdGlwbGVBdHRhY2htZW50XCIgw6ggVFJVRSkuXHJcbiAgICovXHJcbiAgQElucHV0KFwiZGlzYWJsZUFjdGlvblwiKSBkaXNhYmxlQWN0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlIFRSVUUgbW9zdHJhIGlsIHRpdG9sbyBuZWxsJ2hlYWRlciBuZWwgY2FzbyBpbiBjdWkgXCJtdWx0aXBsZUF0dGFjaG1lbnRcIiDDqCBUUlVFIChcIkVsZW5jbyBhbGxlZ2F0aVwiIGRpIGRlZmF1bHQpLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNob3dIZWFkZXJcIikgc2hvd0hlYWRlcjogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRpdG9sbyBkYSB2aXN1YWxpenphcmUgc2UgaWwgcGFyYW1ldHJvIFwic2hvd0hlYWRlclwiIMOoIFRSVUUuIERpIGRldmF1bHQgdmllbmUgdmlzdWFsaXp6YXRvIFwiRWxlbmNvIGFsbGVnYXRpXCIuXHJcbiAgICovXHJcbiAgQElucHV0KFwiaGVhZGVyVGl0bGVcIikgaGVhZGVyVGl0bGU6IHN0cmluZyA9IFwiRWxlbmNvIGFsbGVnYXRpXCI7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNvcmdlbnRlIGRhdGkgZGEgdmlzdWFsaXp6YXJlLiBOZWwgY2FzbyBzaSB2dW9sZSBnZXN0aXJlIHVuIHNpbmdvbG8gYWxsZWdhdG8gdmEgcGFzc2F0byBpbiBvZ25pIGNhc28gY29tZSBBcnJheS5cclxuICAgKi9cclxuICBASW5wdXQoXCJhdHRhY2htZW50c0xpc3RcIikgYXR0YWNobWVudHNMaXN0OiBBcnJheTxJQXR0YWNobWVudERUTz4gPSBudWxsO1xyXG5cclxuICAvKipcclxuICAgKiBOZWwgY2FzbyBzaSB2dW9sZSBnZXN0aXJlIHVuIHNvbG8gZWxlbWVudG8gc2VuemEgcGFzc2FybG8gY29tZSBhcnJheSwgbG8gcGFzc28gY29tZSBzaW5nb2xvIGFsbGVnYXRvIGUgZ2VzdGlzY28gbmVsbGEgbGlicmVyaWEgbCdhcnJheS5cclxuICAgKi9cclxuICBASW5wdXQoXCJzaW5nbGVBdHRhY2htZW50XCIpIHNpbmdsZUF0dGFjaG1lbnQ6IElBdHRhY2htZW50RFRPID0gbnVsbDtcclxuXHJcbiAgLyoqXHJcbiAgICogU2UgVFJVRSBub24gbW9zdHJhIGxhIE1hdENhcmQgKG5lbCBjYXNvIGluIGN1aSBcIm11bHRpcGxlQXR0YWNobWVudFwiIMOoIFRSVUUpLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNob3dNYXRDYXJkXCIpIHNob3dNYXRDYXJkOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogU2UgRkFMU0UgYWxsb3JhIGlsIGNvbXBvbmVudGUgbW9zdHJhIHNvbG8gaWwgcHVsc2FudGUgZGkgY2FyaWNhbWVudG8gZGkgdW4gc2luZ29sbyBmaWxlLCB1bmEgdm9sdGEgY2FyaWNhdG8gaWwgZmlsZSBpbnZvY2EgbCdldmVudG8gZGkgb3V0cHV0IFwibG9jYWxFZGl0ZWRBdHRhY2htZW50c1wiLlxyXG4gICAqIFNlIFRSVUUgYWxsb3JhIGlsIGNvbXBvbmVudGUgbW9zdHJhIGwnZWxlbmNvIGRpIHR1dHRpIGdsaSBhbGxlZ2F0aSByaWNldnV0byBuZWwgcGFyYW1ldHJvIFwiYXR0YWNobWVudHNMaXN0XCIuXHJcbiAgICovXHJcbiAgQElucHV0KFwibXVsdGlwbGVBdHRhY2htZW50XCIpIG11bHRpcGxlQXR0YWNobWVudDogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlIGFzc3VtZSBpbCB2YWxvcmUgVFJVRSBhbGxvcmEgc2Fyw6AgcG9zc2liaWxlIGNhcmljYXJlIHBpw7kgZmlsZSBwZXIgdm9sdGEuIFF1ZXN0YSBmdW56aW9uYWxpdMOgIMOoIGF0dGl2YVxyXG4gICAqIFNPTE8gc2Ugc2kgZ2VzdGlzY29ubyBhbGxlZ2F0aSBtdWx0aXBsaSwgcXVpbmRpIHNlIGwnaW5wdXQgJ211bHRpcGxlQXR0YWNobWVudCcgYXNzdW1lIGlsIHZhbG9yZSBUUlVFLCBhbHRyaW1lbnRpIMOoIHNlbXByZSBkaXNhYmlsaXRhdGEuXHJcbiAgICovXHJcbiAgQElucHV0KFwibG9hZE11bHRpcGxlRmlsZXNcIikgbG9hZE11bHRpcGxlRmlsZXM6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW1wb3N0YSBpbCBtZXNzYWdnaW8gZGEgdmlzdWFsaXp6YXJlIG5lbCBjYXNvIGluIGN1aSBsYSB0YWJlbGxhIGRlZ2xpIGFsbGVnYXRpIChuZWwgY2FzbyBpbiBjdWkgXCJtdWx0aXBsZUF0dGFjaG1lbnRcIiDDqCBUUlVFKSDDqCB2dW90YS5cclxuICAgKi9cclxuICBASW5wdXQoXCJlbXB0eVRhYmxlTWVzc2FnZVwiKSBlbXB0eVRhYmxlTWVzc2FnZTogc3RyaW5nID0gXCJOZXNzdW4gZGF0byB0cm92YXRvXCI7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlIFRSVUUgYWxsb3JhIHBlcm1ldHRlIGRpIHNlbGV6aW9uYXJlIHNvbHRhbnRvIGZpbGUgZGkgdGlwbyBpbW1hZ2luZSwgYXZlbnRlIHVubyBkZWkgbWltZXR5cGVcclxuICAgKiBzcGVjaWZpY2F0aSBkZW50cm8gQXR0YWNobWVudEhlbHBlclNlcnZpY2UuXHJcbiAgICogU2UgRkFMU0UgcGVybWV0dGUgZGkgc2VsZXppb25hcmUgcXVhbHNpYXNpIHRpcG8gZGkgZmlsZVxyXG4gICAqL1xyXG4gIEBJbnB1dChcImFsbG93T25seUltYWdlc1wiKSBhbGxvd09ubHlJbWFnZXM6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogU3BlY2lmaWNhIGkgdGlwaSBkaSBmaWxlIGNoZSDDqCBwb3NzaWJpbGUgY2FyaWNhcmVcclxuICAgKi9cclxuICBASW5wdXQoXCJhY2NlcHRlZEZpbGVUeXBlc1wiKSBhY2NlcHRlZEZpbGVUeXBlczogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBTZSBUUlVFIGRpc2FiaWxpdGEgaWwgcHVsc2FudGUgZGkgQWdnaXVudGEgYWxsZWdhdG8gKGEgcHJlc2NpbmRlcmUgZGFsIHZhbG9yZSBkZWwgcGFyYW1ldHJvIFwibXVsdGlwbGVBdHRhY2htZW50XCIpLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcImlzRGlzYWJsZWRcIikgaXNEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKipcclxuICAgKiBNb3N0cmEvbmFzY29uZGUgbGEgY29sb25uYSBwZXIgdmlzdWFsaXp6YXJlIGwnYW50ZXByaW1hIGRlaSBmaWxlIG5lbGxhIHRhYmVsbGEgKGNhc28gbXVsdGlwbGVBdGF0Y2htZW50cyA9IHRydWUpLlxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNob3dJbmxpbmVQcmV2aWV3XCIpIHNob3dJbmxpbmVQcmV2aWV3OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEVuZHBvaW50IGRhIGNoaWFtYXJlIHBlciByZWN1ZXByYXJlIGwnSUF0dGFjaG1lbnREVE8gY29tcGxldG8gZGEgdmVkZXJlIG5lbGwnYW50ZXByaW1hLiBMYSBjaGlhbWF0YSBzYXLDoCBpbiBQT1NUIGUgbmVsIGJvZHlcclxuICAgKiBjb250ZXJyw6AgbCdJQXR0YWNobWVudERUTyBzZWxlemlvbmF0byBkYWxsJ3V0ZW50ZS5cclxuICAgKiBMYSBjaGlhbWF0YSB2aWVuZSBlc2VndWl0YSBzb2xvIHBlciBsJ2FudGVwcmltYSBkZWxsZSBpbW1hZ2luaSBlc3NlbmRvIG5lY2Vzc2FyaW8gaWwgYmFzZTY0IGNvbXBsZXRvIGRlbGwnaW1tYWdpbmUgYSBkaW1lbnNpb25lIHJlYWxlLlxyXG4gICAqIFBlciBkb2N1bWVudGkvbGluayBiYXN0YSBjaGUgc2lhIHBvcG9sYXRhIGxhIHByb3ByaWV0w6AgRmlsZVBhdGggZGkgSUF0dGFjaG1lbnREVE8uXHJcbiAgICovXHJcbiAgQElucHV0KFwiZ2V0QXR0YWNobWVudEVuZHBvaW50XCIpIGdldEF0dGFjaG1lbnRFbmRwb2ludDogc3RyaW5nID0gbnVsbDtcclxuXHJcbiAgLyoqXHJcbiAgICogSG9zdG5hbWUgZGVsbCdhbWJpZW50ZSBkaSBwcm9kdXppb25lIGRlbGwnYXBwbGljYXRpdm8uIE5lY2Vzc2FyaW8gcGVyIHZpc3VhbGl6emFyZSBsJ2FudGVwcmltYSBkZWkgZG9jdW1lbnRpXHJcbiAgICogdHJhbWl0ZSBpbCB2aWV3ZXIgZGkgZ29vZ2xlLlxyXG4gICAqIE5PVEE6IFBlciB2aXN1YWxpenphcmUgbCdhbnRlcHJpbWEgw6ggbmVjZXNzYXJpbyBjaGUgbGEgcHJvcmlldMOgIEZpbGVQYXRoIGRlbGwnSUF0dGFjaG1lbnREVE8gc2lhIHBvcG9sYXRhIGUgY2hlXHJcbiAgICogc2lhIGFiaWxpdGF0byBsJ2FjY2Vzc28gYWxsYSBjYXJ0ZWxsYSBzdWwgc2VydmVyIHRyYW1pdGUgaG9zdG5hbWUuXHJcbiAgICovXHJcbiAgQElucHV0KFwicHJvZHVjdGlvbkJhc2VVcmxcIikgcHJvZHVjdGlvbkJhc2VVcmw6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wemlvbmkgcGVyIGxhIGNvbXByZXNzaW9uZSBkZWxsZSBpbW1hZ2luaSBjYXJpY2F0ZS5cclxuICAgKi9cclxuICBASW5wdXQoXCJjb21wcmVzc2lvbk9wdGlvbnNcIikgY29tcHJlc3Npb25PcHRpb25zOiBJT3B0aW9ucyA9IHtcclxuICAgIG1heFNpemVNQjogMC41LFxyXG4gICAgbWF4V2lkdGhPckhlaWdodDogMTkyMCxcclxuICAgIHVzZVdlYldvcmtlcjogdHJ1ZVxyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEFycmF5IGRpIEF0dGFjaG1lbnRUeXBlIGNoZSBzaSBwb3Nzb25vIGFnZ2l1bmdlcmVcclxuICAgKi9cclxuICBASW5wdXQoXCJhbGxvd2VkVHlwZXNcIikgYWxsb3dlZFR5cGVzOiBBcnJheTxBdHRhY2htZW50VHlwZT4gPSBbQXR0YWNobWVudFR5cGUuRklMRSwgQXR0YWNobWVudFR5cGUuTElOS107XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcm1ldHRlIGRpIHN0YWJpbGlyZSBzZSBsYSBlcXAtdGFibGUgY29udGVuZW50ZSBsJ2VsZW5jbyBkZWdsaSBhbGxlZ2F0aSB1dGlsaXp6YVxyXG4gICAqIGlsIG11bHRpbGluZ3VhIG9wcHVyZSBub1xyXG4gICAqL1xyXG4gIEBJbnB1dChcImlzRXFwVGFibGVNdWx0aUxhbmd1YWdlXCIpIGlzRXFwVGFibGVNdWx0aUxhbmd1YWdlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcm1ldHRlIGRpIHN0YWJpbGlyZSwgaW4gY2FzbyBkaSBnZXN0aW9uZSBhbGxlZ2F0aSBtdWx0aXBsaSwgc2UgbGEgdGFiZWxsYSBjb250ZW5lbnRlIGwnZWxlbmNvXHJcbiAgICogZGVnbGkgYWxsZWdhdGkgZGV2ZSBlc3NlcmUgcGFnaW5hdGEgb3BwdXJlIG5vXHJcbiAgICovXHJcbiAgQElucHV0KFwidGFibGVQYWdpbmF0b3JWaXNpYmxlXCIpIHRhYmxlUGFnaW5hdG9yVmlzaWJsZTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcm1ldHRlIGRpIHN0YWJpbGlyZSwgaW4gY2FzbyBkaSBnZXN0aW9uZSBhbGxlZ2F0aSBtdWx0aXBsaSwgc2UgbGEgdGFiZWxsYSBjb250ZW5lbnRlIGwnZWxlbmNvXHJcbiAgICogZGVnbGkgYWxsZWdhdGkgZGV2ZSBjb250ZW5lcmUgaWwgY2FtcG8gZGkgcmljZXJjYSBvcHB1cmUgbm9cclxuICAgKi9cclxuICBASW5wdXQoXCJpc1RhYmxlU2VhcmNoZWFibGVcIikgaXNUYWJsZVNlYXJjaGVhYmxlOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW4gY2FzbyBkaSBnZXN0aW9uZSBhbGxlZ2F0aSBtdWx0aXBsaSwgcGVybWV0dGUgZGkgc3RhYmlsaXJlIGxhIGRpbWVuc2lvbmUgcGFnaW5hIGRpIGRlZmF1bHRcclxuICAgKiBwZXIgbGEgdGFiZWxsYSBjb250ZW5lbnRlIGwnZWxlbmNvIGRlZ2xpIGFsbGVnYXRpXHJcbiAgICovXHJcbiAgQElucHV0KFwidGFibGVQYWdpbmF0b3JTaXplXCIpIHRhYmxlUGFnaW5hdG9yU2l6ZTogbnVtYmVyID0gbnVsbDtcclxuXHJcbiAgLyoqXHJcbiAgICogUGVybWV0dGUgZGkgc2NlZ2xpZXJlIGlsIG1vZG8gaW4gY3VpIGkgZmlsZSBkZXZvbm8gZXNzZXJlIGNhcmljYXRpXHJcbiAgICovXHJcbiAgLy8gQElucHV0KFwidXBsb2FkVHlwZVwiKSB1cGxvYWRUeXBlOiBVcGxvYWRUeXBlRW51bSA9IFVwbG9hZFR5cGVFbnVtLkZJTEVfQU5EX0xJTks7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcm1ldHRlIGRpIHN0YWJpbGlyZSBzZSBpIHB1bHNhbnRpIHBlciBpbCBjYXJpY2FtZW50byBkZWkgZmlsZSBzb25vIHNlcGFyYXRpIG8gaW4gdW4gbWVuw7kgYSB0ZW5kaW5hXHJcbiAgICovXHJcbiAgQElucHV0KFwic2VwYXJhdGVkVXBsb2FkQnV0dG9uc1wiKSBzZXBhcmF0ZWRVcGxvYWRCdXR0b25zOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBlcm1ldHRlIGRpIHNjZWdsaWVyZSBzZSBkYXJlIGxhIHBvc3NpYmlsaXTDoCBkaSB2ZWRlcmUgbyBubyBsJ2FudGVwcmltYVxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNob3dQcmV2aWV3XCIpIHNob3dQcmV2aWV3OiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW4gY2FzbyBkaSBhbGxlZ2F0byBzaW5nb2xvLCBwZXJtZXR0ZSBkaSBzY2VnbGllcmUgc2UgYWdnaXVuZ2VyZSBmaWxlIHRyYW1pdGUgZHJhZyBhbmQgZHJvcFxyXG4gICAqL1xyXG4gIEBJbnB1dChcInNpbmdsZUF0dGFjaG1lbnREcmFnQW5kRHJvcFwiKSBzaW5nbGVBdHRhY2htZW50RHJhZ0FuZERyb3A6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogQXJyYXkgZGkgb3B6aW9uaSBjaGUgc2kgcG9zc29ubyB1dGlsaXp6YXJlIHBlciBpbCBjcm9wXHJcbiAgICovXHJcbiAgQElucHV0KFwiY3JvcE9wdGlvbnNcIikgY3JvcE9wdGlvbnM6IEFycmF5PENyb3BPcHRpb25FbnVtPiA9IFtdO1xyXG5cclxuICAvKipcclxuICAgKiBDbGFzc2UgY3VzdG9tIGRhIGFzc2VnbmFyZSBhbCBkaWFsb2cgZGVsIGNyb3AgaW1tYWdpbmlcclxuICAgKi9cclxuICBASW5wdXQoXCJjcm9wRGlhbG9nQ2xhc3NcIikgY3JvcERpYWxvZ0NsYXNzOiBzdHJpbmc7XHJcblxyXG4gIEBJbnB1dCgpIG1heEZpbGVTaXplTUI6IG51bWJlciA9IDEwMDsgLy8gRGVmYXVsdCBtYXggc2l6ZSBvZiAxMDAgTUJcclxuICBASW5wdXQoKSBjYXJkU2l6ZTogQXR0YWNobWVudENhcmRTaXplID0gJ3NtYWxsJzsgLy8gRGVmYXVsdFxyXG4gIEBJbnB1dCgpIGN1c3RvbUNhcmRXaWR0aFB4OiBudW1iZXIgPSAyMDA7IC8vIExhcmdoZXp6YSBjdXN0b20gaW4gcHhcclxuICBASW5wdXQoKSBjdXN0b21DYXJkSGVpZ2h0UHg6IG51bWJlciA9IDE4MDsgLy8gQWx0ZXp6YSBjdXN0b20gaW4gcHhcclxuXHJcbiAgLyoqXHJcbiAgICogSW5wdXQgcGVyIGRlZmluaXJlIGxlIGxhYmVsIGRhIHVzYXJlIG5lbCBjb21wb25lbnRlXHJcbiAgICovXHJcbiAgQElucHV0KFwib3BlbkxpbmtMYWJlbFwiKSBvcGVuTGlua0xhYmVsOiBzdHJpbmcgPSBcIkFwcmkgbGlua1wiO1xyXG4gIEBJbnB1dChcImFkZEJ1dHRvbkxhYmVsXCIpIGFkZEJ1dHRvbkxhYmVsOiBzdHJpbmcgPSBcIkFnZ2l1bmdpXCI7XHJcbiAgQElucHV0KFwiZG93bmxvYWRMYWJlbFwiKSBkb3dubG9hZExhYmVsOiBzdHJpbmcgPSBcIkRvd25sb2FkXCI7XHJcbiAgQElucHV0KFwiZGVsZXRlTGFiZWxcIikgZGVsZXRlTGFiZWw6IHN0cmluZyA9IFwiRWxpbWluYVwiO1xyXG4gIEBJbnB1dChcImZpbGVOYW1lTGFiZWxcIikgZmlsZU5hbWVMYWJlbDogc3RyaW5nID0gXCJOb21lIGZpbGVcIjtcclxuICBASW5wdXQoXCJwcmV2aWV3TGFiZWxcIikgcHJldmlld0xhYmVsOiBzdHJpbmcgPSBcIkFudGVwcmltYVwiO1xyXG4gIEBJbnB1dChcInVwbG9hZEZpbGVMYWJlbFwiKSB1cGxvYWRGaWxlTGFiZWw6IHN0cmluZyA9IFwiQ2FyaWNhIGZpbGVcIjtcclxuICBASW5wdXQoXCJjb25maXJtTGFiZWxcIikgY29uZmlybUxhYmVsOiBzdHJpbmcgPSBcIkNvbmZlcm1hXCI7XHJcbiAgQElucHV0KFwiYWJvcnRMYWJlbFwiKSBhYm9ydExhYmVsOiBzdHJpbmcgPSBcIkFubnVsbGFcIjtcclxuICBASW5wdXQoXCJzYXZlTGFiZWxcIikgc2F2ZUxhYmVsOiBzdHJpbmcgPSBcIlNhbHZhXCI7XHJcbiAgQElucHV0KFwiZXhpdExhYmVsXCIpIGV4aXRMYWJlbDogc3RyaW5nID0gXCJFc2NpXCI7XHJcbiAgQElucHV0KFwidXBsb2FkV2l0aERyb3Bib3hMYWJlbFwiKSB1cGxvYWRXaXRoRHJvcGJveExhYmVsOiBzdHJpbmcgPSBcIkNhcmljYSBjb24gRHJvcGJveFwiO1xyXG4gIEBJbnB1dChcImNyb3BMYWJlbFwiKSBjcm9wTGFiZWw6IHN0cmluZyA9IFwiU2NlZ2xpIGxlIGRpbWVuc2lvbmkgZGVsbCdpbW1hZ2luZVwiO1xyXG4gIEBJbnB1dChcImRlbGV0ZURpYWxvZ1RpdGxlXCIpIGRlbGV0ZURpYWxvZ1RpdGxlOiBzdHJpbmcgPSBudWxsO1xyXG4gIEBJbnB1dChcImRlbGV0ZURpYWxvZ01lc3NhZ2VcIikgZGVsZXRlRGlhbG9nTWVzc2FnZTogc3RyaW5nID0gXCJTZWkgc2ljdXJvIGRpIHZvbGVyIGNhbmNlbGxhcmUgcXVlc3QnYWxsZWdhdG8/XCI7XHJcbiAgQElucHV0KFwibm9JbWFnZVNlbGVjdGVkRXJyb3JNZXNzYWdlXCIpIG5vSW1hZ2VTZWxlY3RlZEVycm9yTWVzc2FnZTogc3RyaW5nID1cclxuICAgIFwiTm9uIMOoIHBvc3NpYmlsZSBzZWxlemlvbmFyZSB1biBmaWxlIGNoZSBub24gc2lhIHVuJ2ltbWFnaW5lLlwiO1xyXG4gIEBJbnB1dChcIndyb25nVHlwZVNlbGVjdGVkRXJyb3JNZXNzYWdlXCIpIHdyb25nVHlwZVNlbGVjdGVkRXJyb3JNZXNzYWdlOiBzdHJpbmcgPVxyXG4gICAgXCJOb24gw6ggcG9zc2liaWxlIGNhcmljYXJlIGlsIGZpbGUgc2VsZXppb25hdG8uXCI7XHJcbiAgQElucHV0KFwidmlkZW9QcmV2aWV3RXJyb3JNZXNzYWdlXCIpIHZpZGVvUHJldmlld0Vycm9yTWVzc2FnZTogc3RyaW5nID1cclxuICAgIFwiSW1wb3NzaWJpbGUgYXByaXJlIGwnYW50ZXByaW1hIGRpIHVuIGZpbGUgdmlkZW8uXCI7XHJcbiAgQElucHV0KFwidmlkZW9QcmV2aWV3RXJyb3JNZXNzYWdlXCIpIGF1ZGlvUHJldmlld0Vycm9yTWVzc2FnZTogc3RyaW5nID1cclxuICAgIFwiSW1wb3NzaWJpbGUgYXByaXJlIGwnYW50ZXByaW1hIGRpIHVuIGZpbGUgYXVkaW8uXCI7XHJcbiAgQElucHV0KFwiZmxpcEhvcmluem9udGFsTGFiZWxcIikgZmxpcEhvcmluem9udGFsTGFiZWw6IHN0cmluZyA9IFwiQ2Fwb3ZvbGdpIG9yaXp6b250YWxtZW50ZVwiO1xyXG4gIEBJbnB1dChcImZsaXBWZXJ0aWNhbExhYmVsXCIpIGZsaXBWZXJ0aWNhbExhYmVsOiBzdHJpbmcgPSBcIkNhcG92b2xnaSB2ZXJ0aWNhbG1lbnRlXCI7XHJcbiAgQElucHV0KFwicm90YXRlUmlnaHRMYWJlbFwiKSByb3RhdGVSaWdodExhYmVsOiBzdHJpbmcgPSBcIlJ1b3RhIGEgZGVzdHJhXCI7XHJcbiAgQElucHV0KFwicm90YXRlTGVmdExhYmVsXCIpIHJvdGF0ZUxlZnRMYWJlbDogc3RyaW5nID0gXCJSdW90YSBhIHNpbmlzdHJhXCI7XHJcbiAgQElucHV0KCkgdXBsb2FkVGl0bGUgPSAnVXBsb2FkIGZpbGUnO1xyXG4gIEBJbnB1dCgpIHVwbG9hZFN1YnRpdGxlID0gJ0RyYWcgJiBkcm9wIGZpbGVzIG8gY2xpY2snO1xyXG4gIEBJbnB1dCgpIGRyb3BIZXJlTGFiZWwgPSAnUmlsYXNjaWEgaSBmaWxlIHF1aSc7XHJcbiAgQElucHV0KCkgc3VwcG9ydGVkRm9ybWF0c0xhYmVsID0gJ0Zvcm1hdGkgc3VwcG9ydGF0aTogSlBFRywgUE5HLCBQREYgKE1heCAxMDBNQiknO1xyXG4gIEBJbnB1dCgpIGJyb3dzZUZpbGVzTGFiZWwgPSAnQ2VyY2EgaSBmaWxlJztcclxuICBASW5wdXQoKSB1cGxvYWRTdW1tYXJ5TGFiZWwgPSAnTGlzdGEgYWxsZWdhdGknO1xyXG4gIEBJbnB1dCgpIGZpbGVzTGFiZWwgPSAnRmlsZXMnO1xyXG4gIEBJbnB1dCgpIHRvdGFsU2l6ZUxhYmVsID0gJ0RpbWVuc2lvbmUgdG90YWxlJztcclxuICBASW5wdXQoKSBlbXB0eVN0YXRlTGFiZWwgPSAnTm9uIHNvbm8gcHJlc2VudGkgZmlsZSBjYXJpY2F0aSc7XHJcbiAgQElucHV0KCkgYWRkZWRTdWNjZXNzZnVsbHlMYWJlbCA9ICdmaWxlKHMpIGNhcmljYXRpIGNvbiBzdWNjZXNzby4nO1xyXG4gIEBJbnB1dCgpIHJlbW92ZWRMYWJlbCA9ICdGaWxlIHJpbW9zc28nO1xyXG4gIC8vIEBJbnB1dCgpIHJlbW92ZUxhYmVsID0gJ1JpbXVvdmkgZmlsZSc7XHJcbiAgQElucHV0KCkgY2hvb3NlVmlldyA9IHRydWU7XHJcbiAgQElucHV0KCkgc2hvd1N1bW1hcnkgPSBmYWxzZTtcclxuICBASW5wdXQoXCJ2aWV3TW9kZVwiKSB2aWV3TW9kZTogJ2NhcmQnIHwgJ3RhYmxlJyA9ICd0YWJsZSc7XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8vI3JlZ2lvbiBAT3V0cHV0IGRlbCBjb21wb25lbnRlXHJcblxyXG4gIC8qKlxyXG4gICAqIFJlc3RpdHVpc2NlIGxhIGxpc3RhIGFnZ2lvcm5hdGEgZGVnbGkgYWxsZWdhdGkuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIGxvY2FsRWRpdGVkQXR0YWNobWVudHM6IEV2ZW50RW1pdHRlcjxBcnJheTxJQXR0YWNobWVudERUTz4+ID0gbmV3IEV2ZW50RW1pdHRlcjxBcnJheTxJQXR0YWNobWVudERUTz4+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBzY2F0ZW5hdG8gYWxsYSBwcmVzc2lvbmUgZGVsIHB1bHNhbnRlIEVTQ0kgZGVsbGEgbW9kYWxlIGRpIGNhcmljYW1lbnRvIGZpbGUuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIGFib3J0QWRkQXR0YWNobWVudDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnRvIGRpIG91dHB1dCBjaGUgcmVzdGl0dWlzY2UgbCdJQXR0YWNobWVudERUTyBzZWxlemlvbmF0byBwZXIgaWwgZG93bmxvYWQgbmVsIGNhc28gRmlsZURhdGFCYXNlNjQsIEZpbGVDb250ZW50VHlwZSBvIEZpbGVOYW1lIG5vbiBmb3NzZXJvIHNwZWNpZmljYXRpLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoXCJkb3dubG9hZEF0dGFjaG1lbnRcIikgZG93bmxvYWRBdHRhY2htZW50OiBFdmVudEVtaXR0ZXI8SUF0dGFjaG1lbnREVE8+ID0gbmV3IEV2ZW50RW1pdHRlcjxJQXR0YWNobWVudERUTz4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnRvIGRpIG91dHB1dCBjaGUgcmVzdGl0dWlzY2UgbCdlbGVtZW50byBlbGltaW5hdG8gcHJpbWEgY2hlIHF1ZXN0byB2ZW5nYSBlZmZldHRpdmFtZW50ZSByaXNtb3NzbyBkYWxsYSBsaXN0YS5cclxuICAgKi9cclxuICBAT3V0cHV0KFwib25EZWxldGVBdHRhY2htZW50XCIpIG9uRGVsZXRlQXR0YWNobWVudDogRXZlbnRFbWl0dGVyPElBdHRhY2htZW50RFRPPiA9IG5ldyBFdmVudEVtaXR0ZXI8SUF0dGFjaG1lbnREVE8+KCk7XHJcblxyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICAvLyNyZWdpb24gUHJvcHJpZXTDoCBwZXIgZ2VzdGlvbmUgY2FyaWNhbWVudG8gbnVvdm8gYWxsZWdhdG9cclxuICBuZXdBdHRhY2htZW50OiBJQXR0YWNobWVudERUTyA9IHt9IGFzIElBdHRhY2htZW50RFRPO1xyXG4gIG5ld011bHRpcGxlQXR0YWNobWVudHM6IEFycmF5PElBdHRhY2htZW50RFRPPiA9IFtdO1xyXG4gIGF0dGFjaG1lbnRUeXBlID0gQXR0YWNobWVudFR5cGU7XHJcbiAgLy8gdXBsb2FkVHlwZUVudW0gPSBVcGxvYWRUeXBlRW51bTtcclxuICBuZXdBdHRhY2htZW50Rm9ybTogRm9ybUdyb3VwO1xyXG4gIHNlbGVjdGVkRmlsZTogRmlsZSA9IG51bGw7XHJcbiAgc2VsZWN0ZWRGaWxlczogQXJyYXk8RmlsZT4gPSBudWxsO1xyXG4gIHNob3dDcm9wSW1hZ2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBAVmlld0NoaWxkKFwiZGlhbG9nQWRkQXR0YWNobWVudFwiLCB7IHN0YXRpYzogdHJ1ZSB9KSBkaWFsb2dBZGRBdHRhY2htZW50OiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIGRpYWxvZ1JlZkFkZEF0dGFjaG1lbnQ6IE1hdERpYWxvZ1JlZjxUZW1wbGF0ZVJlZjxhbnk+PjtcclxuICBAVmlld0NoaWxkKFwiZGlhbG9nQWRkTXVsdGlwbGVBdHRhY2htZW50XCIsIHsgc3RhdGljOiB0cnVlIH0pIGRpYWxvZ0FkZE11bHRpcGxlQXR0YWNobWVudDogVGVtcGxhdGVSZWY8YW55PjtcclxuICBkaWFsb2dSZWZDcm9wSW1hZ2U6IE1hdERpYWxvZ1JlZjxUZW1wbGF0ZVJlZjxhbnk+PjtcclxuICBAVmlld0NoaWxkKFwiZGlhbG9nQ3JvcEltYWdlXCIsIHsgc3RhdGljOiB0cnVlIH0pIGRpYWxvZ0Nyb3BJbWFnZTogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgQFZpZXdDaGlsZCgnYWRkaW5nTGlua1RlbXBsYXRlJykgYWRkaW5nTGlua1RlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICAvLyNyZWdpb24gUHJvcHJpZXTDoCBwZXIgZ2VzdGlvbmUgcmlkaW1lbnNpb25hbWVudG8gZmlsZSBkaSB0aXBvIGltYWdlXHJcbiAgaW1hZ2VDaGFuZ2VkRXZlbnQ6IGFueSA9IFwiXCI7XHJcbiAgY3JvcHBlZEltYWdlOiBhbnkgPSBcIlwiO1xyXG4gIHRyYW5zZm9ybTogSW1hZ2VUcmFuc2Zvcm0gPSB7fTtcclxuICBjYW52YXNSb3RhdGlvbiA9IDA7XHJcbiAgQFZpZXdDaGlsZChJbWFnZUNyb3BwZXJDb21wb25lbnQpIGltYWdlQ3JvcHBlcjogSW1hZ2VDcm9wcGVyQ29tcG9uZW50O1xyXG4gIEBWaWV3Q2hpbGQoXCJpbWFnZUlucHV0XCIpIGltYWdlSW5wdXQ6IGFueTtcclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgQXR0YWNobWVudFR5cGUgPSBBdHRhY2htZW50VHlwZTtcclxuICBzZWxlY3RlZEF0dGFjaG1lbnQ6IElBdHRhY2htZW50RFRPO1xyXG5cclxuICBvcmlnaW5hbFdpZHRoOiBudW1iZXI7XHJcbiAgb3JpZ2luYWxIZWlnaHQ6IG51bWJlcjtcclxuICBjdXN0b21XaWR0aDogbnVtYmVyO1xyXG4gIGN1c3RvbUhlaWdodDogbnVtYmVyO1xyXG5cclxuICBAVmlld0NoaWxkKFwiaW5saW5lUHJldmlld1RlbXBsYXRlXCIsIHsgc3RhdGljOiB0cnVlIH0pIGlubGluZVByZXZpZXdUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBAVmlld0NoaWxkKFwiZGlhbG9nUHJldmlld1wiLCB7IHN0YXRpYzogdHJ1ZSB9KSBkaWFsb2dQcmV2aWV3OiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG5cclxuICBpbWFnZUZpbGU6IEZpbGU7XHJcblxyXG4gIGFkZGluZ0xpbmtNb2RlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8vI3JlZ2lvbiBTZXppb25lIG51b3ZhIHJlZmFjdG9yaW5nXHJcbiAgLy8gU3RhdG8gZHJhZyAmIGRyb3AgZSB0b2FzdFxyXG4gIGRyYWdPdmVyID0gZmFsc2U7XHJcbiAgdG9hc3QgPSB7XHJcbiAgICB2aXNpYmxlOiBmYWxzZSBhcyBib29sZWFuLFxyXG4gICAgdHlwZTogJ3N1Y2Nlc3MnIGFzICdzdWNjZXNzJyB8ICdlcnJvcicsXHJcbiAgICB0ZXh0OiAnJyBhcyBzdHJpbmcsXHJcbiAgICB0aW1lb3V0SWQ6IDAgYXMgYW55XHJcbiAgfTtcclxuXHJcbiAgcHJvZ3Jlc3NQZXJjZW50ID0gMDtcclxuICB0b3RhbFNpemVCeXRlcyA9IDA7XHJcbiAgZ2V0IHRvdGFsU2l6ZUZvcm1hdHRlZCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5mb3JtYXRGaWxlU2l6ZSh0aGlzLnRvdGFsU2l6ZUJ5dGVzKTsgfVxyXG5cclxuICAvLyBVdGlsaXR5IHBlciBmb3JtYXR0YXJlIGJ5dGVzICgyIGRlY2ltYWxpKVxyXG4gIGZvcm1hdEZpbGVTaXplKGJ5dGVzOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKCFieXRlcyB8fCBieXRlcyA8PSAwKSByZXR1cm4gJzAgQnl0ZXMnO1xyXG4gICAgY29uc3QgayA9IDEwMjQ7XHJcbiAgICBjb25zdCBzaXplcyA9IFsnQnl0ZXMnLCAnS0InLCAnTUInLCAnR0InLCAnVEInXTtcclxuICAgIGNvbnN0IGkgPSBNYXRoLmZsb29yKE1hdGgubG9nKGJ5dGVzKSAvIE1hdGgubG9nKGspKTtcclxuICAgIHJldHVybiBgJHtwYXJzZUZsb2F0KChieXRlcyAvIE1hdGgucG93KGssIGkpKS50b0ZpeGVkKDIpKX0gJHtzaXplc1tpXX1gO1xyXG4gIH1cclxuXHJcbiAgLy8gTW9zdHJhIHRvYXN0IGNvbiBhdXRv4oCRaGlkZSBlIHJlc2V0IHByb2dyZXNzIGJhciBDU1NcclxuICBzaG93VG9hc3QobWVzc2FnZTogc3RyaW5nLCB0eXBlOiAnc3VjY2VzcycgfCAnZXJyb3InID0gJ3N1Y2Nlc3MnLCBkdXJhdGlvbk1zID0gMzAwMCkge1xyXG4gICAgaWYgKHRoaXMudG9hc3QudmlzaWJsZSAmJiB0aGlzLnRvYXN0LnRleHQgPT09IG1lc3NhZ2UpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbmNlbGxhIGlsIHRpbWVvdXQgcHJlY2VkZW50ZSBzZSBlc2lzdGVcclxuICAgIGlmICh0aGlzLnRvYXN0LnRpbWVvdXRJZCkge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy50b2FzdC50aW1lb3V0SWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbGNvbGEgdW5hIGR1cmF0YSBkaW5hbWljYVxyXG4gICAgY29uc3QgZHVyYXRpb24gPSBkdXJhdGlvbk1zIHx8IE1hdGgubWF4KDQwMDAsIG1lc3NhZ2UubGVuZ3RoICogMTAwKTtcclxuXHJcbiAgICB0aGlzLnRvYXN0LnRleHQgPSBtZXNzYWdlO1xyXG4gICAgdGhpcy50b2FzdC50eXBlID0gdHlwZTtcclxuICAgIHRoaXMudG9hc3QudmlzaWJsZSA9IHRydWU7XHJcblxyXG4gICAgLy8gSW1wb3N0YSBpbCBudW92byB0aW1lb3V0IHBlciBuYXNjb25kZXJlIGF1dG9tYXRpY2FtZW50ZSBpbCB0b2FzdFxyXG4gICAgdGhpcy50b2FzdC50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy50b2FzdC52aXNpYmxlID0gZmFsc2U7XHJcbiAgICB9LCBkdXJhdGlvbik7XHJcbiAgfVxyXG5cclxuICAjZW5kcmVnaW9uXHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZyxcclxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcclxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgcHJpdmF0ZSBlcXBBdHRhY2htZW50U2VydmljZTogRXFwQXR0YWNobWVudFNlcnZpY2VcclxuICApIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuXHJcbiAgICAvLyBJbml6aWFsaXp6YSBtZXRyaWNoZSBlIHByb2dyZXNzIGluIGJhc2UgYWxsbyBzdGF0byBpbml6aWFsZVxyXG4gICAgdGhpcy5yZWNvbXB1dGVUb3RhbHNBbmRQcm9ncmVzcygpO1xyXG5cclxuICAgIC8vU2Ugw6ggc3RhdGEgcmljaGllc3RhIGxhIGdlc3Rpb25lIGRlbGxlIHNvbGUgaW1tYWdpbmkgYWxsb3JhIGltcG9zdGEgaWwgZmlsdHJvIHBlciBsZSBlc3RlbnNpb25pIHBvc3NpYmlsaSBkYSBjYXJpY2FyZVxyXG4gICAgaWYgKCF0aGlzLmFjY2VwdGVkRmlsZVR5cGVzKVxyXG4gICAgICBpZiAodGhpcy5hbGxvd09ubHlJbWFnZXMgPT0gdHJ1ZSkgdGhpcy5hY2NlcHRlZEZpbGVUeXBlcyA9IFwiaW1hZ2UvKlwiO1xyXG4gICAgICBlbHNlIHRoaXMuYWNjZXB0ZWRGaWxlVHlwZXMgPSBcIipcIjtcclxuXHJcbiAgICAvLyBTZSBub24gc29ubyBzdGF0aSBzcGVjaWZpY2F0aSBpIHRpcGkgZGEgZ2VzdGlyZSBtYSDDqCBzdGF0byBwYXNzYXRvIG51bGwgbyB1biBhcnJheSB2dW90byBpbXBvc3RvIGkgdGlwaSBkaSBkZWZhdWx0LlxyXG4gICAgaWYgKCF0aGlzLmFsbG93ZWRUeXBlcyB8fCB0aGlzLmFsbG93ZWRUeXBlcy5sZW5ndGggPT0gMClcclxuICAgICAgdGhpcy5hbGxvd2VkVHlwZXMgPSBbQXR0YWNobWVudFR5cGUuRklMRSwgQXR0YWNobWVudFR5cGUuTElOSywgQXR0YWNobWVudFR5cGUuRFJPUEJPWF07XHJcbiAgICBlbHNlIGlmIChcclxuICAgICAgdGhpcy5hbGxvd2VkVHlwZXMuZmluZCgodCkgPT4gdCAhPSBBdHRhY2htZW50VHlwZS5GSUxFICYmIHQgIT0gQXR0YWNobWVudFR5cGUuTElOSyAmJiB0ICE9IEF0dGFjaG1lbnRUeXBlLkRST1BCT1gpXHJcbiAgICApIHtcclxuICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuV2FybmluZyhcclxuICAgICAgICAnQWxtZW5vIHVubyBkZWdsaSBBdHRhY2htZW50VHlwZSBzZWxlemlvbmF0aSBuZWwgcGFyYW1ldHJvIFwiYWxsb3dlZFR5cGVzXCIgbm9uIGVzaXN0ZS4nXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuYWxsb3dlZFR5cGVzID0gW0F0dGFjaG1lbnRUeXBlLkZJTEUsIEF0dGFjaG1lbnRUeXBlLkxJTkssIEF0dGFjaG1lbnRUeXBlLkRST1BCT1hdO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmF0dGFjaG1lbnRzTGlzdCA9PSBudWxsKSB0aGlzLmF0dGFjaG1lbnRzTGlzdCA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuXHJcbiAgICAvLyBTZSDDqCBzdGF0byBwYXNzYXRvIHVuIHNpbmdvbG8gYWxsZWdhdG8gbG8gYWdnaXVuZ28gYWxsYSBsaXN0YVxyXG4gICAgaWYgKHRoaXMuc2luZ2xlQXR0YWNobWVudCAhPSBudWxsICYmIHRoaXMuYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgIHRoaXMuYXR0YWNobWVudHNMaXN0LnB1c2godGhpcy5zaW5nbGVBdHRhY2htZW50KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmNoZWNrQXR0YWNobWVudEltYWdlKCk7XHJcblxyXG4gICAgaWYgKHRoaXMuYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDMpKSB7XHJcbiAgICAgIHRoaXMuZXFwQXR0YWNobWVudFNlcnZpY2UubG9hZERyb3Bib3hTY3JpcHQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHNldFZpZXdNb2RlKG1vZGU6ICdjYXJkJyB8ICd0YWJsZScpOiB2b2lkIHtcclxuICAgIHRoaXMudmlld01vZGUgPSBtb2RlO1xyXG4gIH1cclxuXHJcbiAgLy8gUmljYWxjb2xhIGxhIHNvbW1hIHBlc2F0YSBzdWdsaSBhbGxlZ2F0aSBwcmVzZW50aVxyXG4gIHByaXZhdGUgcmVjb21wdXRlVG90YWxzQW5kUHJvZ3Jlc3MoKSB7XHJcbiAgICB0aGlzLnRvdGFsU2l6ZUJ5dGVzID0gKHRoaXMuYXR0YWNobWVudHNMaXN0IHx8IFtdKVxyXG4gICAgICAuZmlsdGVyKGEgPT4gISFhKVxyXG4gICAgICAucmVkdWNlKChzdW0sIGEpID0+IHN1bSArIHRoaXMuYnl0ZXNGcm9tQmFzZTY0KGEuRmlsZURhdGFCYXNlNjQgfHwgYS5GaWxlVGh1bWJuYWlsQmFzZTY0IHx8ICcnKSwgMCk7XHJcblxyXG4gICAgLy8gUHJvZ3Jlc3MgZml0dGl6aW86IDEwMCUgc2UgcHJlc2VudGkgZmlsZSwgMCBzZSB2dW90b1xyXG4gICAgdGhpcy5wcm9ncmVzc1BlcmNlbnQgPSAodGhpcy5hdHRhY2htZW50c0xpc3QgJiYgdGhpcy5hdHRhY2htZW50c0xpc3QubGVuZ3RoID4gMCkgPyAxMDAgOiAwO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy50b2FzdC50aW1lb3V0SWQpIGNsZWFyVGltZW91dCh0aGlzLnRvYXN0LnRpbWVvdXRJZCk7XHJcbiAgfVxyXG5cclxuICAvLyBDYWxjb2xhIGkgYnl0ZSBkYSB1bmEgc3RyaW5nYSBCYXNlNjQgcHVyYSAoc2VuemEgcHJlZmlzc28gZGF0YTouLi4pXHJcbiAgcHVibGljIGJ5dGVzRnJvbUJhc2U2NChiYXNlNjQ6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBpZiAoIWJhc2U2NCkgcmV0dXJuIDA7XHJcbiAgICAvLyBSaW11b3ZpIGV2ZW50dWFsZSBwcmVmaXNzbyBkYXRhIFVSTFxyXG4gICAgY29uc3QgY29tbWFJZHggPSBiYXNlNjQuaW5kZXhPZignLCcpO1xyXG4gICAgY29uc3QgYjY0ID0gY29tbWFJZHggPj0gMCA/IGJhc2U2NC5zdWJzdHJpbmcoY29tbWFJZHggKyAxKSA6IGJhc2U2NDtcclxuICAgIC8vIENvbnRhIHBhZGRpbmdcclxuICAgIGxldCBwYWRkaW5nID0gMDtcclxuICAgIGlmIChiNjQuZW5kc1dpdGgoJz09JykpIHBhZGRpbmcgPSAyO1xyXG4gICAgZWxzZSBpZiAoYjY0LmVuZHNXaXRoKCc9JykpIHBhZGRpbmcgPSAxO1xyXG4gICAgLy8gRm9ybXVsYSBlc2F0dGE6ICgzICogKGxlbiAvIDQpKSAtIHBhZGRpbmdcclxuICAgIGNvbnN0IGxlbiA9IGI2NC5sZW5ndGg7XHJcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgKDMgKiBNYXRoLmZsb29yKGxlbiAvIDQpKSAtIHBhZGRpbmcpO1xyXG4gIH1cclxuXHJcbiAgY2hlY2tBdHRhY2htZW50SW1hZ2UoKSB7XHJcbiAgICB0aGlzLmF0dGFjaG1lbnRzTGlzdC5mb3JFYWNoKChhKSA9PiB7XHJcbiAgICAgIGEuSXNJbWFnZSA9IEF0dGFjaG1lbnRIZWxwZXJTZXJ2aWNlLmNoZWNrSW1hZ2VGcm9tTWltZVR5cGUoYS5GaWxlQ29udGVudFR5cGUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyNyZWdpb24gR2VzdGlvbmUgZWxlbmNvIGFsbGVnYXRpXHJcblxyXG4gIC8qKlxyXG4gICAqIEVsaW1pbmEgdW4gYWxsZWdhdG8gZWxpbWluYW5kbyBhbmNoZSBpbCBmaWxlIHByZXNlbnRlIG5lbGxvIHN0b3JhZ2UgZGkgYXJjaGl2aWF6aW9uZSB1dGlsaXp6YXRvIChBV1MgbyBjYXJ0ZWxsYSBwcm9nZXR0bylcclxuICAgKiBAcGFyYW0gZWxlbWVudCBJQXR0YWNobWVudERUTyBkYSBjYW5jZWxsYXJlXHJcbiAgICovXHJcbiAgZGVsZXRlQXR0YWNobWVudChlbGVtZW50OiBJQXR0YWNobWVudERUTykge1xyXG4gICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuQ29uZmlybShcclxuICAgICAgdGhpcy5kZWxldGVEaWFsb2dNZXNzYWdlLFxyXG4gICAgICAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVBdHRhY2htZW50RnJvbUxpc3QodGhpcy5hdHRhY2htZW50c0xpc3QuaW5kZXhPZihlbGVtZW50KSk7XHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIHRoaXMuZGVsZXRlRGlhbG9nVGl0bGVcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSaW11b3ZlIGwnYWxsZWdhdG8gc2VsZXppb25hdG8gZGFsbGEgbGlzdGEgXCJhdHRhY2htZW50c0xpc3RcIiBlIGludm9jYSBsJ2V2ZW50byBkaSBvdXRwdXQgY2hlIHJlc3RpdHVpc2NlIGxhIGxpc3RhIGFnZ2lvcm5hdGEuXHJcbiAgICogQHBhcmFtIGF0dGFjaG1lbnRJbmRleCBJbmRpY2UgZGVsbCdhdHRhY2htZW50IGRhIHJpbXVvdmVyZVxyXG4gICAqL1xyXG4gIHJlbW92ZUF0dGFjaG1lbnRGcm9tTGlzdChhdHRhY2htZW50SW5kZXg6IG51bWJlcikge1xyXG4gICAgdGhpcy5vbkRlbGV0ZUF0dGFjaG1lbnQuZW1pdCh0aGlzLmF0dGFjaG1lbnRzTGlzdFthdHRhY2htZW50SW5kZXhdKTtcclxuXHJcbiAgICB0aGlzLmF0dGFjaG1lbnRzTGlzdC5zcGxpY2UoYXR0YWNobWVudEluZGV4LCAxKTtcclxuICAgIHRoaXMubG9jYWxFZGl0ZWRBdHRhY2htZW50cy5lbWl0KHRoaXMuYXR0YWNobWVudHNMaXN0KTtcclxuXHJcbiAgICB0aGlzLnJlY29tcHV0ZVRvdGFsc0FuZFByb2dyZXNzKCk7XHJcbiAgICB0aGlzLnNob3dUb2FzdCh0aGlzLnJlbW92ZWRMYWJlbCB8fCAnRmlsZSByZW1vdmVkJywgJ3N1Y2Nlc3MnKTtcclxuXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNpbXVsYXRlUHJvZ3Jlc3MoKSB7XHJcbiAgICB0aGlzLnByb2dyZXNzUGVyY2VudCA9IDA7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy5wcm9ncmVzc1BlcmNlbnQgPSAzMDtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5wcm9ncmVzc1BlcmNlbnQgPSA2MDtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgIHRoaXMucHJvZ3Jlc3NQZXJjZW50ID0gMTAwO1xyXG4gICAgICAgIH0sIDIwMCk7XHJcbiAgICAgIH0sIDIwMCk7XHJcbiAgICB9LCAxMDApO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIFNjYXJpY2EgbCdhbGxlZ2F0byBvIGFwcmUgaWwgbGlua1xyXG4gICAqIEBwYXJhbSBlbGVtZW50IEFsbGVnYXRvIGRhIG1vc3RyYXJlXHJcbiAgICovXHJcbiAgdmlld0F0dGFjaG1lbnQoYXR0YWNobWVudDogSUF0dGFjaG1lbnREVE8pIHtcclxuICAgIGlmIChhdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkxJTkspIHtcclxuICAgICAgd2luZG93Lm9wZW4oYXR0YWNobWVudC5GaWxlUGF0aCwgXCJfYmxhbmtcIik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCAmJiBhdHRhY2htZW50LkZpbGVDb250ZW50VHlwZSAmJiBhdHRhY2htZW50LkZpbGVOYW1lKSB7XHJcbiAgICAgIGxldCBzb3VyY2UgPSBgZGF0YToke2F0dGFjaG1lbnQuRmlsZUNvbnRlbnRUeXBlfTtiYXNlNjQsJHthdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0fWA7XHJcbiAgICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcclxuICAgICAgbGluay5ocmVmID0gc291cmNlO1xyXG4gICAgICBsaW5rLmRvd25sb2FkID0gYCR7YXR0YWNobWVudC5GaWxlTmFtZX1gO1xyXG4gICAgICBsaW5rLmNsaWNrKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmRvd25sb2FkQXR0YWNobWVudC5lbWl0KGF0dGFjaG1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmlkZWZpbmlzY2UgbCdpY29uYSBkYSBtb3N0cmFyZSBuZWxsYSBjb2xvbm5hIGRlbGwnZXFwLXRhYmxlIHBlciBvZ25pIGZpbGUuXHJcbiAgICogTCdpY29uYSB2YXJpYSBpbiBiYXNlIGFsbCdlc3RlbnNpb25lIGRlbCBmaWxlXHJcbiAgICogQHBhcmFtIGF0dGFjaG1lbnRcclxuICAgKi9cclxuICBnZXRBdHRhY2htZW50SWNvbihhdHRhY2htZW50OiBJQXR0YWNobWVudERUTykge1xyXG4gICAgaWYgKGF0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSykgcmV0dXJuIFwiZmFzIGZhLWxpbmtcIjtcclxuICAgIGVsc2UgcmV0dXJuIEF0dGFjaG1lbnRIZWxwZXJTZXJ2aWNlLmdldEljb25Gcm9tRmlsZUV4dGVuc2lvbmUoYXR0YWNobWVudC5GaWxlRXh0ZW5zaW9uKTtcclxuICB9XHJcblxyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICAvKipcclxuICAgKiBJbiBjYXNvIGRpIGFsbGVnYXRvIHNpbmdvbG8sIHNjZWdsaWUgcXVhbGUgbWV0b2RvIHJpY2hpYW1hcmUgaW4gYmFzZSBhbCB0aXBvIGRpIGFsbGVnYXRvXHJcbiAgICovXHJcbiAgYWRkRmlsZShhdHRhY2htZW50VHlwZTogQXR0YWNobWVudFR5cGUsIGltYWdlSW5wdXQgPSBudWxsKSB7XHJcbiAgICBpZiAoYXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSykge1xyXG4gICAgICB0aGlzLnN3aXRjaFRvQWRkaW5nTGlua01vZGUoKTtcclxuICAgIH0gZWxzZSBpZiAoYXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuRklMRSkge1xyXG4gICAgICBpbWFnZUlucHV0LmNsaWNrKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmNob29zZURyb3Bib3hGaWxlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjcmVhdGVBdHRhY2htZW50Rm9ybSgpIHtcclxuICAgIC8vQ3JlYSBsYSBmb3JtIHBlciBsYSB2YWxpZGF6aW9uZSBkZWkgY2FtcGlcclxuICAgIHRoaXMubmV3QXR0YWNobWVudEZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcclxuICAgICAgdHlwZTogW3RoaXMubmV3QXR0YWNobWVudC5BdHRhY2htZW50VHlwZSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXHJcbiAgICAgIG5hbWU6IFt0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZU5hbWVdLFxyXG4gICAgICBwYXRoOiBbdGhpcy5uZXdBdHRhY2htZW50LkZpbGVQYXRoXSxcclxuICAgICAgY3VzdG9tSGVpZ2h0OiBbdGhpcy5jdXN0b21IZWlnaHRdLFxyXG4gICAgICBjdXN0b21XaWR0aDogW3RoaXMuY3VzdG9tV2lkdGhdXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGNsb3NlKGVtaXRDbG9zZUV2ZW50ID0gdHJ1ZSkge1xyXG4gICAgdGhpcy5uZXdBdHRhY2htZW50ID0ge30gYXMgSUF0dGFjaG1lbnREVE87XHJcbiAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPSBuZXcgQXJyYXk8SUF0dGFjaG1lbnREVE8+KCk7XHJcbiAgICB0aGlzLmFib3J0RmlsZSgpO1xyXG4gICAgaWYgKHRoaXMubmV3QXR0YWNobWVudEZvcm0pIHRoaXMubmV3QXR0YWNobWVudEZvcm0ucmVzZXQoKTtcclxuXHJcbiAgICB0aGlzLmRpYWxvZ1JlZkNyb3BJbWFnZS5jbG9zZSgpO1xyXG4gICAgdGhpcy5yZXN0b3JlT3JpZ2luYWxEaW1lbnNpb25zKCk7XHJcblxyXG4gICAgaWYgKGVtaXRDbG9zZUV2ZW50ID09IHRydWUgJiYgdGhpcy5hYm9ydEFkZEF0dGFjaG1lbnQpIHRoaXMuYWJvcnRBZGRBdHRhY2htZW50LmVtaXQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluIGJhc2UgYWwgdGlwbyBkaSBhbGxlZ2F0byBjb250cm9sbGEgc2UgZGlzYWJpbGl0YXJlIG8gbWVubyBpbCBwdWxzYW50ZSBwZXIgc2FsdmFyZS5cclxuICAgKiBGdW56aW9uZSB1c2F0YSBuZWwgW2Rpc2FibGVdIGRlbCBwdWxzYW50ZSBcIlNhbHZhXCIgZGVsIGRpYWxvZyBwZXIgbCdhZ2dpdW50YSBkaSB1biBhbGxlZ2F0by5cclxuICAgKiBAcmV0dXJuc1xyXG4gICAqL1xyXG4gIGRpc2FibGVTYXZlKCkge1xyXG4gICAgaWYgKHRoaXMubG9hZE11bHRpcGxlRmlsZXMgIT0gdHJ1ZSkge1xyXG4gICAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkZJTEUpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMubmV3QXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMubmV3QXR0YWNobWVudC5GaWxlUGF0aDtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIChcclxuICAgICAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMuZmlsdGVyKFxyXG4gICAgICAgICAgKHApID0+XHJcbiAgICAgICAgICAgIChwLkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkZJTEUgJiYgIXAuRmlsZURhdGFCYXNlNjQpIHx8XHJcbiAgICAgICAgICAgIChwLkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkxJTksgJiYgIXAuRmlsZVBhdGgpXHJcbiAgICAgICAgKS5sZW5ndGggPiAwXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb25maXJtQWRkQXR0YWNobWVudCgpIHtcclxuICAgIGlmICh0aGlzLm5ld0F0dGFjaG1lbnQuSXNJbWFnZSAmJiB0aGlzLmltYWdlQ3JvcHBlcikge1xyXG4gICAgICB0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjQgPSB0aGlzLmltYWdlQ3JvcHBlci5jcm9wKCkuYmFzZTY0LnNwbGl0KFwiO2Jhc2U2NCxcIilbMV07XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMubG9hZE11bHRpcGxlRmlsZXMgIT0gdHJ1ZSkge1xyXG4gICAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkxJTksgJiYgIXRoaXMubmV3QXR0YWNobWVudC5GaWxlTmFtZSlcclxuICAgICAgICB0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZU5hbWUgPSB0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZVBhdGg7XHJcblxyXG4gICAgICBpZiAodGhpcy5hdHRhY2htZW50c0xpc3QgPT0gbnVsbCkgdGhpcy5hdHRhY2htZW50c0xpc3QgPSBuZXcgQXJyYXk8SUF0dGFjaG1lbnREVE8+KCk7XHJcblxyXG4gICAgICB0aGlzLmF0dGFjaG1lbnRzTGlzdC5wdXNoKHRoaXMubmV3QXR0YWNobWVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy5uZXdNdWx0aXBsZUF0dGFjaG1lbnRzID09IG51bGwgfHwgdGhpcy5uZXdNdWx0aXBsZUF0dGFjaG1lbnRzLmxlbmd0aCA9PSAwKSByZXR1cm47XHJcblxyXG4gICAgICBpZiAodGhpcy5hdHRhY2htZW50c0xpc3QgPT0gbnVsbCkgdGhpcy5hdHRhY2htZW50c0xpc3QgPSBuZXcgQXJyYXk8SUF0dGFjaG1lbnREVE8+KCk7XHJcblxyXG4gICAgICB0aGlzLmF0dGFjaG1lbnRzTGlzdCA9IHRoaXMuYXR0YWNobWVudHNMaXN0LmNvbmNhdCh0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGlmICh0aGlzLmF0dGFjaG1lbnRUYWJsZSkgdGhpcy5hdHRhY2htZW50VGFibGUucmVsb2FkRGF0YXRhYmxlKCk7XHJcblxyXG4gICAgdGhpcy5sb2NhbEVkaXRlZEF0dGFjaG1lbnRzLmVtaXQodGhpcy5hdHRhY2htZW50c0xpc3QpO1xyXG5cclxuICAgIGlmICh0aGlzLm5ld0F0dGFjaG1lbnQuSXNJbWFnZSkge1xyXG4gICAgICB0aGlzLmRpYWxvZ1JlZkNyb3BJbWFnZS5jbG9zZSgpO1xyXG4gICAgICB0aGlzLnJlc3RvcmVPcmlnaW5hbERpbWVuc2lvbnMoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50LkF0dGFjaG1lbnRUeXBlID09PSBBdHRhY2htZW50VHlwZS5MSU5LKSB7XHJcbiAgICAgIHRoaXMubmV3QXR0YWNobWVudCA9IHt9IGFzIElBdHRhY2htZW50RFRPO1xyXG4gICAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50Rm9ybSkgdGhpcy5uZXdBdHRhY2htZW50Rm9ybS5yZXNldCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQXByZSBpbCBkaWFsb2cgcGVyIGwnYW50ZXByaW1hIGRlbGwnYWxsZWdhdG8gc2VsZXppb25hdG8uXHJcbiAgICogQHBhcmFtIHJvd1xyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgYXN5bmMgb3BlblByZXZpZXdEaWFsb2cocm93OiBJQXR0YWNobWVudERUTykge1xyXG4gICAgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJvdykpO1xyXG5cclxuICAgIGlmICh0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5BdHRhY2htZW50VHlwZSA9PSBBdHRhY2htZW50VHlwZS5GSUxFKSB7XHJcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5GaWxlQ29udGVudFR5cGUuc3RhcnRzV2l0aChcInZpZGVvXCIpKSB7XHJcbiAgICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuV2FybmluZyh0aGlzLnZpZGVvUHJldmlld0Vycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVDb250ZW50VHlwZS5zdGFydHNXaXRoKFwiYXVkaW9cIikpIHtcclxuICAgICAgICBFcXBBdHRhY2htZW50RGlhbG9nU2VydmljZS5XYXJuaW5nKHRoaXMuYXVkaW9QcmV2aWV3RXJyb3JNZXNzYWdlKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5nZXRBdHRhY2htZW50RW5kcG9pbnQgJiYgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuSXNJbWFnZSAmJiAhdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjQpIHtcclxuICAgICAgYXdhaXQgdGhpcy5nZXRBdHRhY2htZW50QnlJRCgpXHJcbiAgICAgICAgLnRoZW4oKHJlcykgPT4ge1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjQgPSByZXMuRmlsZURhdGFCYXNlNjQ7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAuY2F0Y2goKGVycikgPT4ge1xyXG4gICAgICAgICAgRXFwQXR0YWNobWVudERpYWxvZ1NlcnZpY2UuRXJyb3IoZXJyKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuTElOSykge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5UcnVzdGVkVXJsID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKFxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVQYXRoXHJcbiAgICAgICk7XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5Jc0ltYWdlICYmXHJcbiAgICAgICF0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCAmJlxyXG4gICAgICAhdGhpcy5zZWxlY3RlZEF0dGFjaG1lbnQuRmlsZVRodW1ibmFpbEJhc2U2NFxyXG4gICAgKSB7XHJcbiAgICAgIEVxcEF0dGFjaG1lbnREaWFsb2dTZXJ2aWNlLkluZm8oXCJJbXBvc3NpYmlsZSBhcHJpcmUgbCdhbnRlcHJpbWEgZGVsbCdhbGxlZ2F0bywgZmlsZSBtYW5jYW50ZS5cIik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSBpZiAoIXRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LklzSW1hZ2UpIHtcclxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50LkZpbGVQYXRoICYmIHRoaXMucHJvZHVjdGlvbkJhc2VVcmwpIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5UcnVzdGVkVXJsID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKFxyXG4gICAgICAgICAgXCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9ndmlldz91cmw9XCIgK1xyXG4gICAgICAgICAgdGhpcy5wcm9kdWN0aW9uQmFzZVVybCArXHJcbiAgICAgICAgICBcIi9cIiArXHJcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkQXR0YWNobWVudC5GaWxlUGF0aCArXHJcbiAgICAgICAgICBcIiZlbWJlZGRlZD10cnVlXCJcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIEVxcEF0dGFjaG1lbnREaWFsb2dTZXJ2aWNlLkluZm8oXCJJbXBvc3NpYmlsZSBhcHJpcmUgbCdhbnRlcHJpbWEgZGVsIGRvY3VtZW50byFcIik7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5kaWFsb2cub3Blbih0aGlzLmRpYWxvZ1ByZXZpZXcsIHtcclxuICAgICAgZGlzYWJsZUNsb3NlOiB0cnVlLFxyXG4gICAgICBoYXNCYWNrZHJvcDogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBnZXRBdHRhY2htZW50QnlJRCgpIHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxJQXR0YWNobWVudERUTz4odGhpcy5nZXRBdHRhY2htZW50RW5kcG9pbnQsIHRoaXMuc2VsZWN0ZWRBdHRhY2htZW50KS50b1Byb21pc2UoKTtcclxuICB9XHJcblxyXG4gIC8vI3JlZ2lvbiBHZXN0aW9uZSBjYXJpY2FtZW50byBmaWxlXHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50byBzY2F0ZW5hdG8gYWxsYSBzZWxlemlvbmUgZGVsIGZpbGUgKG8gZGVpIGZpbGUpLlxyXG4gICAqIFNlIGlsIGNhcmljYW1lbnRvIMOoIFNJTkdPTE8gbyBzZSBjb211bnF1ZSDDqCBzdGF0byBzZWxlemlvbmF0byB1biBzb2xvIGZpbGUgYWxsb3JhIHNpIG9jY3VwYSBkaSBjb250cm9sbGFyZSBzZSBzaSB0cmF0dGEgZGkgdW4gaW1tYWdpbmUgaW4gbW9kbyBkYVxyXG4gICAqIG1vc3RyYXJlIGxlIGZ1bnppb25hbGl0w6AgZGVsIGNyb3BwaWUgKHBlciByaXRhZ2xpYXJlIGwnaW1tYWdpbmUpIG9wcHVyZSBuby5cclxuICAgKiBTZSBpbCBmaWxlIGNhcmljYXRvIG5vbiDDqCB1biBpbW1hZ2luZSBhbGxvcmEgZ2VuZXJhIGRpcmV0dGFtZW50ZSBpbCBiYXNlNjQgZSBsbyBhc3NvY2lhIGFsbCdhbGxlZ2F0byBkYSBzYWx2YXJlLlxyXG4gICAqIFNlIGludmVjZSBpbCBjYXJpY2FtZW50byBkZWkgZmlsZSDDqCBNVUxUSVBMTyBlIHNvbm8gcHJlc2VudGkgcGnDuSBmaWxlIGFsbG9yYSBlc2VndWUgbGUgc3Rlc3NlIG9wZXJhemlvbmkgaWdub3JhbmRvIHBlcsOyIGlsIGNvbnRybGxvXHJcbiAgICogaW1tYWdpbmUgcGVyIGlsIGNyb3BwaWUgKGluIGNhc28gZGkgY2FyaWNhbWVudG8gbXVsdGlwbG8gbGUgZnVuemlvbmFsaXTDoCBkZWwgY3JvcHBpZSBzb25vIGRpc2FiaWxpdGF0ZSkuXHJcbiAgICovXHJcbiAgYXN5bmMgb25GaWxlQWRkZWQoZXZlbnQsIGlzRmlsZURyb3BwZWQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgdGhpcy5zaG93Q3JvcEltYWdlID0gZmFsc2U7XHJcbiAgICAvLyBsZXQgZmlsZXNPbklucHV0ID0gaXNGaWxlRHJvcHBlZCA/IGV2ZW50IDogZXZlbnQudGFyZ2V0LmZpbGVzO1xyXG4gICAgY29uc3QgZmlsZXNPbklucHV0OiBGaWxlW10gPSBpc0ZpbGVEcm9wcGVkXHJcbiAgICAgID8gKGV2ZW50IGFzIEZpbGVbXSlcclxuICAgICAgOiBBcnJheS5mcm9tKChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCk/LmZpbGVzIHx8IFtdKTtcclxuXHJcbiAgICBjb25zdCB7IHZhbGlkRmlsZXMsIG92ZXJzaXplZEZpbGVzIH0gPSB0aGlzLnZhbGlkYXRpb25GaWxlKGZpbGVzT25JbnB1dCwgaXNGaWxlRHJvcHBlZCk7XHJcblxyXG4gICAgLy9TZSDDqCBzdGF0byByaWNoaWVzdG8gaWwgY2FyaWNhbWVudG8gU0lOR09MTyBvcHB1cmUgc2UgaWwgY2FyaWNhbWVudG8gw6ggTVVMVElQTE8gbWEgw6ggc3RhdG8gc2VsZXppb25hdG8gdW4gc29sbyBmaWxlXHJcbiAgICAvL2FsbG9yYSB2ZXJpZmljYSBzZSBpbCBmaWxlIMOoIHVuIGltbWFnaW5lIChwZXIgbW9zdHJhcmUgaWwgQ1JPUFBJRSlcclxuICAgIGlmIChbLi4udmFsaWRGaWxlc10ubGVuZ3RoID09IDEgfHwgdGhpcy5sb2FkTXVsdGlwbGVGaWxlcyAhPSB0cnVlKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlID0gdmFsaWRGaWxlc1swXTtcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpbGVzID0gdmFsaWRGaWxlcztcclxuICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkRmlsZSkgcmV0dXJuO1xyXG5cclxuICAgICAgLy9NZW1vcml6emEgaSBkYXRpIHBlciBsJ2FsbGVnYXRvXHJcbiAgICAgIHRoaXMubmV3QXR0YWNobWVudCA9IGF3YWl0IHRoaXMuY3JlYXRlQXR0YWNobWVudEZyb21VcGxvYWRlZEZpbGUodGhpcy5zZWxlY3RlZEZpbGUsIGZhbHNlKTtcclxuICAgICAgdGhpcy5uZXdNdWx0aXBsZUF0dGFjaG1lbnRzID0gbmV3IEFycmF5PElBdHRhY2htZW50RFRPPigpO1xyXG4gICAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMucHVzaCh0aGlzLm5ld0F0dGFjaG1lbnQpO1xyXG5cclxuICAgICAgLy9TZSDDqCBzdGF0YSByaWNoaWVzdGEgbGEgZ2VzdGlvbmUgZGVsbGUgc29sZSBpbW1hZ2luaSBtYSBwZXIgZXJyb3JlIMOoIHN0YXRvIHNlbGV6aW9uYXRvIHVuIGZpbGUgY2hlIG5vbiDDqCB1biBpbW1hZ2luZVxyXG4gICAgICBsZXQgY2hlY2tPbmx5SW1hZ2UgPSB0aGlzLmNoZWNrQWxsb3dPbmx5SW1hZ2VGaWxlKHRoaXMubmV3QXR0YWNobWVudCk7XHJcbiAgICAgIGlmIChjaGVja09ubHlJbWFnZSA9PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgdGhpcy5jcmVhdGVBdHRhY2htZW50Rm9ybSgpO1xyXG5cclxuICAgICAgLy9WZXJpZmljYSBzZSBpbCBmaWxlIGNhcmljYXRvIMOoIHVuJ2ltbWFnaW5lIG9wcHVyZSBuby4gU2Ugw6ggdW4gaW1tYWdpbmUsIHByaW1hIGRpIGNhcmljYXJsYSBtb3N0cmEgaWwgY3JvcHBpZSBwZXIgaWwgcmVzaXplLlxyXG4gICAgICAvL1NlIG5vbiDDqCB1biBpbW1hZ2luZSBhbGxvcmEgZ2VuZXJhIGlsIEJhc2U2NFxyXG4gICAgICBpZiAodGhpcy5uZXdBdHRhY2htZW50LklzSW1hZ2UgPT0gdHJ1ZSkge1xyXG4gICAgICAgIHRoaXMuZ2V0SW1hZ2VEaW1lbnNpb25zKHZhbGlkRmlsZXNbMF0pO1xyXG5cclxuICAgICAgICAvL01vc3RyYSBpbCBjcm9wcGllIGUgZGlzYWJpbGl0YSBsYSBmb3JtIGZpbmNow6ggbm9uIHRlcm1pbmEgbGEgbW9kaWZpY2EgZGVsbCdpbW1hZ2luZVxyXG4gICAgICAgIHRoaXMubmV3QXR0YWNobWVudEZvcm0uZGlzYWJsZSgpO1xyXG4gICAgICAgIHRoaXMubmV3QXR0YWNobWVudEZvcm0uY29udHJvbHNbXCJjdXN0b21XaWR0aFwiXS5lbmFibGUoKTtcclxuICAgICAgICB0aGlzLm5ld0F0dGFjaG1lbnRGb3JtLmNvbnRyb2xzW1wiY3VzdG9tSGVpZ2h0XCJdLmVuYWJsZSgpO1xyXG4gICAgICAgIHRoaXMuc2hvd0Nyb3BJbWFnZSA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5pbWFnZUZpbGUgPSBldmVudDtcclxuXHJcbiAgICAgICAgdGhpcy5kaWFsb2dSZWZDcm9wSW1hZ2UgPSB0aGlzLmRpYWxvZy5vcGVuKHRoaXMuZGlhbG9nQ3JvcEltYWdlLCB7XHJcbiAgICAgICAgICBkaXNhYmxlQ2xvc2U6IHRydWUsXHJcbiAgICAgICAgICBoYXNCYWNrZHJvcDogdHJ1ZSxcclxuICAgICAgICAgIHdpZHRoOiBcIjYwJVwiLFxyXG4gICAgICAgICAgbWF4SGVpZ2h0OiBcIjgwJVwiLFxyXG4gICAgICAgICAgbWF4V2lkdGg6IFwiNzB2aFwiXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zaG93Q3JvcEltYWdlID0gZmFsc2U7XHJcbiAgICAgICAgbGV0IGJhc2U2NFJlc3VsdCA9IGF3YWl0IHRoaXMuZ2V0QmFzZTY0RnJvbUZpbGUodGhpcy5zZWxlY3RlZEZpbGUpO1xyXG4gICAgICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlRGF0YUJhc2U2NCA9IGJhc2U2NFJlc3VsdC5CYXNlNjRGaWxlO1xyXG4gICAgICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlQ29udGVudFR5cGUgPSBiYXNlNjRSZXN1bHQuQ29udGVudFR5cGU7XHJcbiAgICAgICAgdGhpcy5jb25maXJtQWRkQXR0YWNobWVudCgpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsZXMgPSB2YWxpZEZpbGVzO1xyXG4gICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRGaWxlcyB8fCB0aGlzLnNlbGVjdGVkRmlsZXMubGVuZ3RoID09IDApIHJldHVybjtcclxuXHJcbiAgICAgIGlmICghdGhpcy5uZXdNdWx0aXBsZUF0dGFjaG1lbnRzKSB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPSBbXTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNlbGVjdGVkRmlsZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBsZXQgbmV3QXR0YWNobWVudDogSUF0dGFjaG1lbnREVE8gPSBhd2FpdCB0aGlzLmNyZWF0ZUF0dGFjaG1lbnRGcm9tVXBsb2FkZWRGaWxlKFxyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZpbGVzW2ldLFxyXG4gICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgIHRydWVcclxuICAgICAgICApO1xyXG4gICAgICAgIC8vU2Ugw6ggc3RhdGEgcmljaGllc3RhIGxhIGdlc3Rpb25lIGRlbGxlIHNvbGUgaW1tYWdpbmkgbWEgcGVyIGVycm9yZSDDqCBzdGF0byBzZWxlemlvbmF0byB1biBmaWxlIGNoZSBub24gw6ggdW4gaW1tYWdpbmVcclxuICAgICAgICBsZXQgY2hlY2tPbmx5SW1hZ2UgPSB0aGlzLmNoZWNrQWxsb3dPbmx5SW1hZ2VGaWxlKG5ld0F0dGFjaG1lbnQpO1xyXG4gICAgICAgIGlmIChjaGVja09ubHlJbWFnZSA9PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMucHVzaChuZXdBdHRhY2htZW50KTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmNvbmZpcm1BZGRBdHRhY2htZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5yZWNvbXB1dGVUb3RhbHNBbmRQcm9ncmVzcygpO1xyXG4gICAgdGhpcy5zaW11bGF0ZVByb2dyZXNzKCk7XHJcbiAgICAvLyBDYXNvIDE6IFN1Y2Nlc3NvIFBhcnppYWxlIChhbGN1bmkgZmlsZSB2YWxpZGksIGFsdHJpIG5vKVxyXG4gICAgaWYgKG92ZXJzaXplZEZpbGVzLmxlbmd0aCA+IDAgJiYgdmFsaWRGaWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGNvbnN0IGZpbGVOYW1lcyA9IG92ZXJzaXplZEZpbGVzLmpvaW4oJywgJyk7XHJcbiAgICAgIHRoaXMuc2hvd1RvYXN0KFxyXG4gICAgICAgIGAke3ZhbGlkRmlsZXMubGVuZ3RofSBmaWxlIGFnZ2l1bnRpLiAke292ZXJzaXplZEZpbGVzLmxlbmd0aH0gbm9uIGNhcmljYXRpIHBlcmNow6kgdHJvcHBvIGdyYW5kaSAoJHtmaWxlTmFtZXN9KS5gLFxyXG4gICAgICAgICdlcnJvcidcclxuICAgICAgKTtcclxuICAgIH1cclxuICAgIC8vIENhc28gMjogTmVzc3VuIGZpbGUgdmFsaWRvXHJcbiAgICBlbHNlIGlmIChvdmVyc2l6ZWRGaWxlcy5sZW5ndGggPiAwICYmIHZhbGlkRmlsZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICB9XHJcbiAgICAvLyBDYXNvIDM6IFR1dHRpIGkgZmlsZSB2YWxpZGlcclxuICAgIGVsc2UgaWYgKG92ZXJzaXplZEZpbGVzLmxlbmd0aCA9PT0gMCAmJiB2YWxpZEZpbGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5zaG93VG9hc3QoXHJcbiAgICAgICAgYCR7dmFsaWRGaWxlcy5sZW5ndGh9ICR7dGhpcy5hZGRlZFN1Y2Nlc3NmdWxseUxhYmVsIHx8ICdmaWxlKHMpIGFnZ2l1bnRpIGNvbiBzdWNjZXNzby4nfWAsXHJcbiAgICAgICAgJ3N1Y2Nlc3MnXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy9SZXNldHRvIGlsIHZhbG9yZSBkZWwgZmlsZSBpbnB1dCBpbiBtb2RvIGRhIHNjYXRlbmFyZSBpbCBjaGFuZ2UgYW5jaGUgc2Ugc2kgZG92ZXNzZSBjYXJpY2FyZSBsbyBzdGVzc28gZmlsZVxyXG4gICAgaWYgKCFpc0ZpbGVEcm9wcGVkKSBldmVudC50YXJnZXQudmFsdWUgPSBcIlwiO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB2YWxpZGF0aW9uRmlsZShmaWxlc09uSW5wdXQ6IEZpbGVbXSwgaXNGaWxlRHJvcHBlZDogYm9vbGVhbikge1xyXG4gICAgY29uc3QgdmFsaWRGaWxlczogRmlsZVtdID0gW107XHJcbiAgICBjb25zdCBvdmVyc2l6ZWRGaWxlczogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXNPbklucHV0KSB7XHJcbiAgICAgIGNvbnN0IGZpbGVTaXplTUIgPSBmaWxlLnNpemUgLyAxMDI0IC8gMTAyNDtcclxuICAgICAgaWYgKGZpbGVTaXplTUIgPiB0aGlzLm1heEZpbGVTaXplTUIpIHtcclxuICAgICAgICBvdmVyc2l6ZWRGaWxlcy5wdXNoKGZpbGUubmFtZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFsaWRGaWxlcy5wdXNoKGZpbGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2hvdyBhIHNpbmdsZSBlcnJvciBtZXNzYWdlIGZvciBhbGwgb3ZlcnNpemVkIGZpbGVzXHJcbiAgICBpZiAob3ZlcnNpemVkRmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb25zdCBmaWxlTmFtZXMgPSBvdmVyc2l6ZWRGaWxlcy5qb2luKCcsICcpO1xyXG4gICAgICB0aGlzLnNob3dUb2FzdChgRmlsZShzKSB0cm9wcG8gZ3JhbmRpOiAke2ZpbGVOYW1lc30uIExpbWl0ZTogJHt0aGlzLm1heEZpbGVTaXplTUJ9TUJgLCAnZXJyb3InKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBYm9ydCBpZiBubyBmaWxlcyBhcmUgdmFsaWRcclxuICAgIGlmICh2YWxpZEZpbGVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICBpZiAoIWlzRmlsZURyb3BwZWQpIHsgKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZSA9ICcnOyB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyB2YWxpZEZpbGVzLCBvdmVyc2l6ZWRGaWxlcyB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQSBwYXJ0aXJlIGRhbCBGSUxFIHJpY2V2dXRvIGluIGlucHV0IHJpY29zdHJ1aXNjZSBsJ29nZ2V0dG8gSUF0dGFjaG1lbnREVE8gZSBsbyByZXN0aXR1aXNjZS5cclxuICAgKiBTZSBpbCBwYXJhbWV0cm8gZ2V0QmFzZTY0IHZpZW5lIHBhc3NhdG8gYSBUUlVFIGFsbG9yYSwgc2VtcHJlIGEgcGFydGlyZSBkYWwgZmlsZSxnZW5lcmEgaWwgYmFzZTY0IGVcclxuICAgKiByaWNhdmEgaWwgQ29udGVudFR5cGUgZGEgYXNzb2NpYXJlIGFsbCdvZ2dldHRvIElBdHRhY2htZW50RFRPIGRhIHJlc3RpdHVpcmVcclxuICAgKiBAcGFyYW0gY3VycmVudEZpbGUgT2dnZXR0byBGSUxFIGRhIHByb2Nlc3NhcmVcclxuICAgKiBAcGFyYW0gZ2V0QmFzZTY0IFNlIFRSVUUgYWxsb3JhIGNhbGNvbGEgYmFzZTY0IGUgQ29udGVudFR5cGUgZGVsIGZpbGUgcGFzc2F0byBpbiBpbnB1dFxyXG4gICAqIEByZXR1cm5zIFJlc3RpdHVpc2NlIHVuIG9nZ2V0dG8gZGkgdGlwbyBJQXR0YWNobWVudERUT1xyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlQXR0YWNobWVudEZyb21VcGxvYWRlZEZpbGUoXHJcbiAgICBjdXJyZW50RmlsZTogRmlsZSxcclxuICAgIGdldEJhc2U2NDogYm9vbGVhbiA9IHRydWUsXHJcbiAgICBjcm9wRmlsZTogYm9vbGVhbiA9IGZhbHNlXHJcbiAgKTogUHJvbWlzZTxJQXR0YWNobWVudERUTz4ge1xyXG4gICAgbGV0IG5ld0F0dGFjaG1lbnQ6IElBdHRhY2htZW50RFRPID0ge30gYXMgSUF0dGFjaG1lbnREVE87XHJcbiAgICAvL01lbW9yaXp6YSBpIGRhdGkgcGVyIGwnYWxsZWdhdG9cclxuICAgIG5ld0F0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPSBBdHRhY2htZW50VHlwZS5GSUxFO1xyXG4gICAgbmV3QXR0YWNobWVudC5GaWxlQ29udGVudFR5cGUgPSBjdXJyZW50RmlsZS50eXBlO1xyXG4gICAgbmV3QXR0YWNobWVudC5GaWxlTmFtZSA9IGN1cnJlbnRGaWxlLm5hbWU7XHJcbiAgICBuZXdBdHRhY2htZW50LkZpbGVFeHRlbnNpb24gPSBjdXJyZW50RmlsZS5uYW1lLnN1YnN0cihjdXJyZW50RmlsZS5uYW1lLmxhc3RJbmRleE9mKFwiLlwiKSArIDEpO1xyXG4gICAgbmV3QXR0YWNobWVudC5Jc0ltYWdlID0gQXR0YWNobWVudEhlbHBlclNlcnZpY2UuY2hlY2tJbWFnZUZyb21NaW1lVHlwZShjdXJyZW50RmlsZS50eXBlKTtcclxuXHJcbiAgICBpZiAoZ2V0QmFzZTY0ID09IHRydWUpIHtcclxuICAgICAgbGV0IGJhc2U2NFJlc3VsdCA9IGF3YWl0IHRoaXMuZ2V0QmFzZTY0RnJvbUZpbGUoY3VycmVudEZpbGUpO1xyXG4gICAgICBuZXdBdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0ID0gYmFzZTY0UmVzdWx0LkJhc2U2NEZpbGU7XHJcbiAgICAgIG5ld0F0dGFjaG1lbnQuRmlsZUNvbnRlbnRUeXBlID0gYmFzZTY0UmVzdWx0LkNvbnRlbnRUeXBlO1xyXG5cclxuICAgICAgaWYgKG5ld0F0dGFjaG1lbnQuSXNJbWFnZSAmJiBuZXdBdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0ICYmIGNyb3BGaWxlKSB7XHJcbiAgICAgICAgdGhpcy5nZXRDcm9wcGVkQW5kVXBsb2FkKGBkYXRhOiR7YmFzZTY0UmVzdWx0LkNvbnRlbnRUeXBlfTtiYXNlNjQsJHtiYXNlNjRSZXN1bHQuQmFzZTY0RmlsZX1gLCBuZXdBdHRhY2htZW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBuZXdBdHRhY2htZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQSBwYXJ0aXJlIGRhbCBmaWxlIHBhc3NhdG8gaW4gaW5wdXQgcmVzdGl0dWlzY2UgdW4gb2dnZXR0b1xyXG4gICAqIGNvbnRlbmVudGUgaWwgYmFzZTY0IGRlbCBmaWxlIGUgaWwgc3VvIGNvbnRlbnRUeXBlXHJcbiAgICogQHBhcmFtIGN1cnJlbnRGaWxlIE9nZ2V0dG8gRmlsZSBkYSBjdWkgZXN0cmFwb2xhcmUgYmFzZTY0IGUgY29udGVudFR5cGVcclxuICAgKiBAcmV0dXJucyBSZXN0aXR1aXNjZSB1biBvZ2dldHRvIGF2ZW50ZSBsZSBwcm9wcmlldMOgIEJhc2U2NEZpbGUgZSBDb250ZW50VHlwZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgZ2V0QmFzZTY0RnJvbUZpbGUoY3VycmVudEZpbGU6IEZpbGUpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgbGV0IGJhc2U2NEZpbGUgPSBhd2FpdCB0b0Jhc2U2NChjdXJyZW50RmlsZSk7XHJcbiAgICBsZXQgY29udGVudFR5cGU6IHN0cmluZyA9IG51bGw7XHJcbiAgICBpZiAoYmFzZTY0RmlsZSkge1xyXG4gICAgICAvLyBMb3JpcyAyMC8wMS8yMDIyOiBQUk9CTEVNQSAtIFF1YW5kbyBlc2VndW8gbCd1cGxvYWQgZGkgdW4gZmlsZSAuc3FsIG5vbiB2aWVuZSBzYWx2YXRvL3NjYXJpY2F0byBjb3JyZXR0YW1lbnRlLlxyXG4gICAgICAvLyAgICAgICAgICAgICAgICAgICBRdWVzdG8gc3VjY2VkZSBwZXJjaMOoIG5vbiB2aWVuZSBwb3BvbGF0byBpbCBGaWxlQ29udGVudFR5cGUuIFBlciByaXNvbHZlcmUgaWwgcHJvYmxlbWFcclxuICAgICAgLy8gICAgICAgICAgICAgICAgICAgZmFjY2lvIHVuIGNvbnRyb2xsbyBlIHNlIG5vbiBlc2lzdGUgaWwgRmlsZUNvbnRlbnRUeXBlIGFsbG9yYSBsbyByZWN1cGVybyBkYWwgYmFzZTY0IG90dGVudXRvLlxyXG4gICAgICBjb250ZW50VHlwZSA9IGJhc2U2NEZpbGUuc3BsaXQoXCIsXCIpWzBdLnNwbGl0KFwiOlwiKVsxXS5zcGxpdChcIjtcIilbMF07XHJcbiAgICAgIC8vIFVuIGFsdHJvIG1ldG9kbyBwZXIgbGVnZ2VyZSBpbCBjY29udGVudCB0eXBlIGRlbCBmaWxlIMOoIHRyYW1pdGUgdW5hIHJlZ3VsYXIgZXhwcmVzc2lvbjpcclxuICAgICAgYmFzZTY0RmlsZSA9IGJhc2U2NEZpbGUuc3BsaXQoXCIsXCIpWzFdO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZXN1bHQgPSB7XHJcbiAgICAgIEJhc2U2NEZpbGU6IGJhc2U2NEZpbGUsXHJcbiAgICAgIENvbnRlbnRUeXBlOiBjb250ZW50VHlwZVxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29udHJvbGxhIHNlIGlsIGZpbGUgY2hlIHNpIHN0YSBjYXJpY2FuZG8gw6ggc3VwcG9ydGF0byBkYWwgc2lzdGVtYS5cclxuICAgKiBAcmV0dXJuc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tBY2NlcHRlZEZpbGVzKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKFxyXG4gICAgICAodGhpcy5sb2FkTXVsdGlwbGVGaWxlcyAhPSB0cnVlICYmIHRoaXMuc2VsZWN0ZWRGaWxlLnR5cGUuc3RhcnRzV2l0aChcInZpZGVvXCIpKSB8fFxyXG4gICAgICAodGhpcy5sb2FkTXVsdGlwbGVGaWxlcyA9PSB0cnVlICYmIFsuLi50aGlzLnNlbGVjdGVkRmlsZXNdLmZpbHRlcigocCkgPT4gcC50eXBlLnN0YXJ0c1dpdGgoXCJ2aWRlb1wiKSkubGVuZ3RoID4gMClcclxuICAgIClcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgIGlmICh0aGlzLmFjY2VwdGVkRmlsZVR5cGVzID09IFwiKlwiKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAvL1ZlcmlmaWNhIGNoZSBpIHRpcGkgZGVsIGZpbGUgKG8gZGVpIGZpbGUpIGNhcmljYXRpIHNpYW5vIGNvZXJlbnRpIGNvbiBxdWVsbGkgYWNjZXR0YXRpIGRhbGxhIGRpcmV0dGl2YVxyXG4gICAgbGV0IGFjY2VwdGVkOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIGlmICh0aGlzLmxvYWRNdWx0aXBsZUZpbGVzICE9IHRydWUpIGFjY2VwdGVkID0gdGhpcy5hY2NlcHRlZEZpbGVUeXBlcy5pbmNsdWRlcyh0aGlzLnNlbGVjdGVkRmlsZS50eXBlKTtcclxuICAgIGVsc2Uge1xyXG4gICAgICBsZXQgdXBsb2FkZWRGaWxlVHlwZXM6IHN0cmluZ1tdID0gWy4uLnRoaXMuc2VsZWN0ZWRGaWxlc10ubWFwKChwKSA9PiBwLnR5cGUpO1xyXG4gICAgICB1cGxvYWRlZEZpbGVUeXBlcy5mb3JFYWNoKCh0eXBlKSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmFjY2VwdGVkRmlsZVR5cGVzLmluY2x1ZGVzKHR5cGUpKSBhY2NlcHRlZCA9IGZhbHNlO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvL1F1ZXN0byBjb250cm9sbG8gcGVybWV0dGUgZGkgZ2VzdGlyZSBsZSBjYXNpc3RpY2hlIHBlciBjdWkgdmVuZ29ubyBpbmRpY2F0aSBjb21lIHRpcGkgdmFsaWRpLCBhZCBlc2VtcGlvLCAnaW1hZ2UvKidcclxuICAgIGlmICghYWNjZXB0ZWQgJiYgdGhpcy5sb2FkTXVsdGlwbGVGaWxlcyAhPSB0cnVlKSB7XHJcbiAgICAgIGZvciAobGV0IHQgb2YgdGhpcy5hY2NlcHRlZEZpbGVUeXBlcy5zcGxpdChcIixcIikuZmlsdGVyKCh0KSA9PiB0LmluY2x1ZGVzKFwiKlwiKSkpIHtcclxuICAgICAgICBhY2NlcHRlZCA9IHRoaXMuc2VsZWN0ZWRGaWxlLnR5cGUuc3RhcnRzV2l0aCh0LnNwbGl0KFwiKlwiKVswXSk7XHJcbiAgICAgICAgaWYgKGFjY2VwdGVkKSBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFjY2VwdGVkO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2UgZXFwLWF0dGFjaG1lbnRzIMOoIHN0YXRhIGNvbmZpZ3VyYXRhIHBlciBpbCBjYXJpY2FtZW50byBkZWxsZSBzb2xlIGltbWFnaW5pIGFsbG9yYSB2ZXJpZmljYSBjaGUgaWwgZmlsZSBwYXNzYXRvIGluXHJcbiAgICogaW5wdXQgc2lhIGVmZmV0dGl2YW1lbnRlIHVuIGltbWFnaW5lIG8gbm8uXHJcbiAgICogU2UgaWwgY29udHJvbGxvIHZhIGEgYnVvbiBmaW5lIHJlc3RpdHVpc2NlIFRSVUUgYWx0cmltZW50aSBtb3N0cmEgdW4gbWVzc2FnZ2lvIGQnZXJyb3JlIGUgcmVzdGl0dWlzY2UgRkFMU0VcclxuICAgKi9cclxuICBwcml2YXRlIGNoZWNrQWxsb3dPbmx5SW1hZ2VGaWxlKG5ld0F0dGFjaG1lbnQpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLmFsbG93T25seUltYWdlcyA9PSB0cnVlICYmIG5ld0F0dGFjaG1lbnQuSXNJbWFnZSAhPSB0cnVlKSB7XHJcbiAgICAgIEVxcEF0dGFjaG1lbnREaWFsb2dTZXJ2aWNlLkVycm9yKHRoaXMubm9JbWFnZVNlbGVjdGVkRXJyb3JNZXNzYWdlKTtcclxuICAgICAgdGhpcy5hYm9ydEZpbGUoKTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSBlbHNlIGlmICghdGhpcy5jaGVja0FjY2VwdGVkRmlsZXMoKSkge1xyXG4gICAgICBFcXBBdHRhY2htZW50RGlhbG9nU2VydmljZS5FcnJvcih0aGlzLndyb25nVHlwZVNlbGVjdGVkRXJyb3JNZXNzYWdlKTtcclxuICAgICAgdGhpcy5hYm9ydEZpbGUoKTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLy8jcmVnaW9uIEdlc3Rpb25lIGNyb3AgZmlsZVxyXG5cclxuICBnZXRJbWFnZURpbWVuc2lvbnMoaW1nOiBhbnkpIHtcclxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICByZWFkZXIub25sb2FkID0gKGU6IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xyXG4gICAgICBpbWFnZS5zcmMgPSBlLnRhcmdldC5yZXN1bHQ7XHJcbiAgICAgIGltYWdlLm9ubG9hZCA9IChycykgPT4ge1xyXG4gICAgICAgIHRoaXMub3JpZ2luYWxIZWlnaHQgPSBycy5jdXJyZW50VGFyZ2V0W1wiaGVpZ2h0XCJdO1xyXG4gICAgICAgIHRoaXMub3JpZ2luYWxXaWR0aCA9IHJzLmN1cnJlbnRUYXJnZXRbXCJ3aWR0aFwiXTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMub3JpZ2luYWxXaWR0aCA+IDEyODApIHtcclxuICAgICAgICAgIHRoaXMuY3VzdG9tV2lkdGggPSAxMjgwO1xyXG4gICAgICAgICAgdGhpcy5jdXN0b21IZWlnaHQgPSBNYXRoLnJvdW5kKCgxMjgwICogdGhpcy5vcmlnaW5hbEhlaWdodCkgLyB0aGlzLm9yaWdpbmFsV2lkdGgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLmN1c3RvbUhlaWdodCA9IHJzLmN1cnJlbnRUYXJnZXRbXCJoZWlnaHRcIl07XHJcbiAgICAgICAgICB0aGlzLmN1c3RvbVdpZHRoID0gcnMuY3VycmVudFRhcmdldFtcIndpZHRoXCJdO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuICAgIH07XHJcbiAgICByZWFkZXIucmVhZEFzRGF0YVVSTChpbWcpO1xyXG4gIH1cclxuXHJcbiAgcmVzdG9yZU9yaWdpbmFsRGltZW5zaW9ucygpIHtcclxuICAgIHRoaXMuY3VzdG9tV2lkdGggPSB0aGlzLm9yaWdpbmFsV2lkdGg7XHJcbiAgICB0aGlzLmN1c3RvbUhlaWdodCA9IHRoaXMub3JpZ2luYWxIZWlnaHQ7XHJcbiAgICB0aGlzLmNhbnZhc1JvdGF0aW9uID0gMDtcclxuICAgIHRoaXMudHJhbnNmb3JtID0ge307XHJcbiAgfVxyXG5cclxuICBvbkRpbWVuc2lvbnNDaGFuZ2UoZGltZW5zaW9uOiBzdHJpbmcpIHtcclxuICAgIGlmIChkaW1lbnNpb24gPT0gXCJIXCIpIHtcclxuICAgICAgdGhpcy5jdXN0b21XaWR0aCA9IE1hdGgucm91bmQoKHRoaXMuY3VzdG9tSGVpZ2h0ICogdGhpcy5vcmlnaW5hbFdpZHRoKSAvIHRoaXMub3JpZ2luYWxIZWlnaHQpO1xyXG4gICAgfSBlbHNlIGlmIChkaW1lbnNpb24gPT0gXCJXXCIpIHtcclxuICAgICAgdGhpcy5jdXN0b21IZWlnaHQgPSBNYXRoLnJvdW5kKCh0aGlzLmN1c3RvbVdpZHRoICogdGhpcy5vcmlnaW5hbEhlaWdodCkgLyB0aGlzLm9yaWdpbmFsV2lkdGgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaW1hZ2VDcm9wcGVkKGV2ZW50OiBJbWFnZUNyb3BwZWRFdmVudCkge1xyXG4gICAgdGhpcy5jcm9wcGVkSW1hZ2UgPSBldmVudC5iYXNlNjQ7XHJcbiAgICB0aGlzLmdldENyb3BwZWRBbmRVcGxvYWQodGhpcy5jcm9wcGVkSW1hZ2UsIHRoaXMubmV3QXR0YWNobWVudCk7XHJcbiAgfVxyXG5cclxuICBnZXRDcm9wcGVkQW5kVXBsb2FkKGZpbGUsIG5ld0F0dGFjaG1lbnQ6IElBdHRhY2htZW50RFRPKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdmFyIGZpbGU6IGFueSA9IGJhc2U2NFRvRmlsZShmaWxlKTtcclxuXHJcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5jb21wcmVzc2lvbk9wdGlvbnM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb21wcmltZSBsJ2ltbWFnaW5lIHBhc3NhbmRvIGNvbWUgcGFyYW1ldHJpIGxlIG9wdGlvbnMgY3JlYXRlIG5lbGwnb2dnZXR0byBzb3ByYSwgZSBpbCBmaWxlIGRhbCByZWFkZXIgcHJpbmNpcGFsZVxyXG4gICAgICovXHJcbiAgICBpbWFnZUNvbXByZXNzaW9uKGZpbGUsIG9wdGlvbnMpLnRoZW4oKGZpbGVDb21wcmVzc2VkKSA9PiB7XHJcbiAgICAgIGxldCBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuXHJcbiAgICAgIC8vRmFjY2lvIGxhIHB1c2ggZGkgb2duaSBmaWxlIGFsbCdpbnRlcm5vIGRlbGwnYXJyYXkgZGkgZmlsZSBkZWxsJ2l0ZW0gZGEgbWFuZGFyZSBhbCBzZXJ2ZXJcclxuICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdFJlYWRlciA9IDxzdHJpbmc+ZmlsZVJlYWRlci5yZXN1bHQ7XHJcbiAgICAgICAgdmFyIG1hcmtlciA9IFwiO2Jhc2U2NCxcIjtcclxuICAgICAgICBuZXdBdHRhY2htZW50LkZpbGVEYXRhQmFzZTY0ID0gcmVzdWx0UmVhZGVyLnN1YnN0cmluZyhyZXN1bHRSZWFkZXIuaW5kZXhPZihtYXJrZXIpICsgbWFya2VyLmxlbmd0aCk7XHJcbiAgICAgICAgc2VsZi5zaG93Q3JvcEltYWdlID0gZmFsc2U7XHJcbiAgICAgICAgaWYgKHNlbGYubmV3QXR0YWNobWVudEZvcm0pIHtcclxuICAgICAgICAgIHNlbGYubmV3QXR0YWNobWVudEZvcm0uZW5hYmxlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgZmlsZVJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGVDb21wcmVzc2VkKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gY29uZmlybUNyb3AoKSB7XHJcbiAgLy8gICB0aGlzLmltYWdlQ3JvcHBlci5jcm9wKCk7XHJcbiAgLy8gICB0aGlzLmRpYWxvZ1JlZkNyb3BJbWFnZS5jbG9zZSgpO1xyXG4gIC8vICAgdGhpcy5yZXN0b3JlT3JpZ2luYWxEaW1lbnNpb25zKCk7XHJcbiAgLy8gfVxyXG5cclxuICByb3RhdGVMZWZ0KCkge1xyXG4gICAgdGhpcy5jYW52YXNSb3RhdGlvbi0tO1xyXG4gICAgdGhpcy5mbGlwQWZ0ZXJSb3RhdGUoKTtcclxuICB9XHJcblxyXG4gIHJvdGF0ZVJpZ2h0KCkge1xyXG4gICAgdGhpcy5jYW52YXNSb3RhdGlvbisrO1xyXG4gICAgdGhpcy5mbGlwQWZ0ZXJSb3RhdGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZmxpcEFmdGVyUm90YXRlKCkge1xyXG4gICAgY29uc3QgZmxpcHBlZEggPSB0aGlzLnRyYW5zZm9ybS5mbGlwSDtcclxuICAgIGNvbnN0IGZsaXBwZWRWID0gdGhpcy50cmFuc2Zvcm0uZmxpcFY7XHJcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcclxuICAgICAgLi4udGhpcy50cmFuc2Zvcm0sXHJcbiAgICAgIGZsaXBIOiBmbGlwcGVkVixcclxuICAgICAgZmxpcFY6IGZsaXBwZWRIXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgZmxpcEhvcml6b250YWwoKSB7XHJcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcclxuICAgICAgLi4udGhpcy50cmFuc2Zvcm0sXHJcbiAgICAgIGZsaXBIOiAhdGhpcy50cmFuc2Zvcm0uZmxpcEhcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBmbGlwVmVydGljYWwoKSB7XHJcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcclxuICAgICAgLi4udGhpcy50cmFuc2Zvcm0sXHJcbiAgICAgIGZsaXBWOiAhdGhpcy50cmFuc2Zvcm0uZmxpcFZcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgLyoqXHJcbiAgICogQW5udWxsYSBsYSBzZWxlemlvbmUgZGVsIGZpbGUsIHN2dW90YW5kbyBsJ2lucHV0IGUgcmVzZXR0YW5kbyB0dXR0ZSBsZSBwcm9wcmlldMOgIGRlbGwnSUF0dGFjaG1lbnREVE9cclxuICAgKi9cclxuICBhYm9ydEZpbGUoKSB7XHJcbiAgICBpZiAodGhpcy5pbWFnZUlucHV0KSB0aGlzLmltYWdlSW5wdXQubmF0aXZlRWxlbWVudC52YWx1ZSA9IFwiXCI7XHJcblxyXG4gICAgdGhpcy5zZWxlY3RlZEZpbGUgPSBudWxsO1xyXG4gICAgdGhpcy5zZWxlY3RlZEZpbGVzID0gbnVsbDtcclxuICAgIHRoaXMuc2hvd0Nyb3BJbWFnZSA9IGZhbHNlO1xyXG5cclxuICAgIHRoaXMubmV3QXR0YWNobWVudC5Jc0ltYWdlID0gZmFsc2U7XHJcbiAgICB0aGlzLm5ld0F0dGFjaG1lbnQuRmlsZURhdGFCYXNlNjQgPSBudWxsO1xyXG4gICAgdGhpcy5uZXdBdHRhY2htZW50LkZpbGVOYW1lID0gbnVsbDtcclxuICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlRXh0ZW5zaW9uID0gbnVsbDtcclxuICAgIHRoaXMubmV3QXR0YWNobWVudC5GaWxlQ29udGVudFR5cGUgPSBudWxsO1xyXG5cclxuICAgIHRoaXMubmV3TXVsdGlwbGVBdHRhY2htZW50cyA9IG5ldyBBcnJheTxJQXR0YWNobWVudERUTz4oKTtcclxuXHJcbiAgICB0aGlzLmN1c3RvbUhlaWdodCA9IG51bGw7XHJcbiAgICB0aGlzLmN1c3RvbVdpZHRoID0gbnVsbDtcclxuICAgIHRoaXMub3JpZ2luYWxIZWlnaHQgPSBudWxsO1xyXG4gICAgdGhpcy5vcmlnaW5hbFdpZHRoID0gbnVsbDtcclxuXHJcbiAgICB0aGlzLmRpYWxvZ1JlZkNyb3BJbWFnZS5jbG9zZSgpO1xyXG4gICAgdGhpcy5yZXN0b3JlT3JpZ2luYWxEaW1lbnNpb25zKCk7XHJcbiAgfVxyXG5cclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgZmlsZURyb3BwZWQoZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgdGhpcy5kcmFnT3ZlciA9IGZhbHNlO1xyXG5cclxuICAgIGNvbnN0IGZpbGVzID0gZXZlbnQuZGF0YVRyYW5zZmVyPy5maWxlcztcclxuXHJcbiAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLm9uRmlsZUFkZGVkKHsgdGFyZ2V0OiB7IGZpbGVzOiBmaWxlcyB9IH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gU2UgaWwgY2FyaWNhbWVudG8gZGVsIGZpbGUgZHJvcGJveCB2YSBhIGJ1b24gZmluZSwgbGEgZnVuemlvbmUgZGkgY2FsbGJhY2sgcmVzdGl0dWlzY2UgdW4gYXJyYXkgZGkgb2dnZXR0aS5cclxuICAvLyBWaWVuZSBwb2kgZmF0dGEgdW5hIFhNTEh0dHBSZXF1ZXN0IGNvbiByZXNwb25zZVR5cGUgJ2Jsb2InIHBlciBjb252ZXJ0aXJlIGlsIHByaW1vIGVsZW1lbnRvIGRlbGxhIHJlc3BvbnNlIGluIHVuIEJsb2IuXHJcbiAgY2hvb3NlRHJvcGJveEZpbGUoKSB7XHJcbiAgICB2YXIgb3B0aW9ucyA9IHtcclxuICAgICAgc3VjY2VzczogKGZpbGVzOiBhbnlbXSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgICAgIHhoci5vcGVuKFwiR0VUXCIsIGZpbGVzWzBdLmxpbmspO1xyXG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiQXV0aG9yaXphdGlvblwiLCBgQmVhcmVyICR7QXR0YWNobWVudEhlbHBlclNlcnZpY2UuZHJvcGJveENyZWRlbnRpYWxzLmFjY2Vzc1Rva2VufWApO1xyXG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSBcImJsb2JcIjtcclxuXHJcbiAgICAgICAgeGhyLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGJsb2IgPSB4aHIucmVzcG9uc2U7XHJcbiAgICAgICAgICBjb25zdCBmaWxlID0gbmV3IEZpbGUoW2Jsb2JdLCBmaWxlc1swXS5uYW1lLCB7IHR5cGU6IGJsb2IudHlwZSB9KTtcclxuICAgICAgICAgIGxldCBmaWxlc0FkZGVkID0gW2ZpbGVdO1xyXG4gICAgICAgICAgdGhpcy5vbkZpbGVBZGRlZChmaWxlc0FkZGVkLCB0cnVlKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB4aHIuc2VuZCgpO1xyXG4gICAgICB9LFxyXG4gICAgICBsaW5rVHlwZTogXCJkaXJlY3RcIixcclxuICAgICAgbXVsdGlzZWxlY3Q6IGZhbHNlLFxyXG4gICAgICBleHRlbnNpb25zOiBbXCIuanBnXCIsIFwiLnBuZ1wiLCBcIi5wZGZcIiwgXCIuZG9jXCIsIFwiLmRvY3hcIiwgXCIudHh0XCJdXHJcbiAgICB9O1xyXG4gICAgRHJvcGJveC5jaG9vc2Uob3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuICAvLyBXb3JrYXJvdW5kIGRyb3B6b25lOiBkaXNhYmlsaXRvIGlsIGNsaWNrIGRlZ2xpIGVsZW1lbnRpIGluY2x1c2kgbmVsbGEgZHJvcHpvbmUgcGVyIGV2aXRhcmUgZGkgY2xpY2NhcmUgZHVlIHZvbHRlXHJcbiAgb25TZWxlY3RGaWxlKGV2ZW50LCBmaWxlSW5wdXQpIHtcclxuICAgIGlmIChcclxuICAgICAgKGV2ZW50LnRhcmdldCBhcyBIVE1MQnV0dG9uRWxlbWVudCkudGFnTmFtZSA9PT0gXCJCVVRUT05cIiB8fFxyXG4gICAgICAoZXZlbnQudGFyZ2V0IGFzIEhUTUxCdXR0b25FbGVtZW50KS50YWdOYW1lID09PSBcIklOUFVUXCIgfHxcclxuICAgICAgdGhpcy5hZGRpbmdMaW5rTW9kZSA9PSB0cnVlXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgZmlsZUlucHV0LmNsaWNrKCk7XHJcbiAgfVxyXG5cclxuICAvLyBNZXRvZG8gcGVyIHZpc3VhbGl6emFyZSBsYSBmb3JtIGRpIGFnZ2l1bnRhIGRpIHVuIGxpbmtcclxuICAvLyBzd2l0Y2hUb0FkZGluZ0xpbmtNb2RlKCkge1xyXG4gIC8vICAgdGhpcy5hZGRpbmdMaW5rTW9kZSA9IHRydWU7XHJcbiAgLy8gICB0aGlzLm5ld0F0dGFjaG1lbnQgPSB7fSBhcyBJQXR0YWNobWVudERUTztcclxuICAvLyAgIHRoaXMubmV3QXR0YWNobWVudC5Jc0ltYWdlID0gZmFsc2U7XHJcbiAgLy8gICB0aGlzLm5ld0F0dGFjaG1lbnQuQXR0YWNobWVudFR5cGUgPSB0aGlzLmF0dGFjaG1lbnRUeXBlLkxJTks7XHJcbiAgLy8gICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPSBuZXcgQXJyYXk8SUF0dGFjaG1lbnREVE8+KCk7XHJcbiAgLy8gICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMucHVzaCh0aGlzLm5ld0F0dGFjaG1lbnQpO1xyXG5cclxuICAvLyAgIHRoaXMuY3JlYXRlQXR0YWNobWVudEZvcm0oKTtcclxuICAvLyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFwcmUgaWwgZGlhbG9nbyBwZXIgbCdpbnNlcmltZW50byBkZWwgbGluay5cclxuICAgKi9cclxuICBzd2l0Y2hUb0FkZGluZ0xpbmtNb2RlKCk6IHZvaWQge1xyXG4gICAgLy8gMS4gQ3JlYSBpbCBmb3JtIHBlciBpbCBkaWFsb2dvXHJcbiAgICB0aGlzLm5ld0F0dGFjaG1lbnRGb3JtID0gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7XHJcbiAgICAgIGZpbGVOYW1lOiBbJyddLFxyXG4gICAgICBmaWxlUGF0aDogWycnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5wYXR0ZXJuKCdodHRwcz86Ly8uKycpXV1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIDIuIEFwcmkgaWwgZGlhbG9nb1xyXG4gICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3Blbih0aGlzLmFkZGluZ0xpbmtUZW1wbGF0ZSwge1xyXG4gICAgICB3aWR0aDogJzUwMHB4JyxcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIDMuIEdlc3Rpc2NpIGlsIHJpc3VsdGF0byBhbGxhIGNoaXVzdXJhXHJcbiAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUocmVzdWx0ID0+IHtcclxuICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgIC8vIEEuIENyZWEgbCdvZ2dldHRvIHBlciBpbCBudW92byBsaW5rIGRhaSBkYXRpIGRlbCBmb3JtXHJcbiAgICAgICAgY29uc3QgbmV3TGlua09iamVjdDogSUF0dGFjaG1lbnREVE8gPSB7XHJcbiAgICAgICAgICBJRDogMCxcclxuICAgICAgICAgIEF0dGFjaG1lbnRUeXBlOiBBdHRhY2htZW50VHlwZS5MSU5LLFxyXG4gICAgICAgICAgRmlsZU5hbWU6IHJlc3VsdC5maWxlTmFtZSxcclxuICAgICAgICAgIEZpbGVQYXRoOiByZXN1bHQuZmlsZVBhdGgsXHJcbiAgICAgICAgICBJc0ltYWdlOiBmYWxzZVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIEIuIFByZXBhcmEgbCdvZ2dldHRvIGBuZXdBdHRhY2htZW50YCBjaGUgYGNvbmZpcm1BZGRBdHRhY2htZW50YCBzaSBhc3BldHRhXHJcbiAgICAgICAgdGhpcy5uZXdBdHRhY2htZW50ID0gbmV3TGlua09iamVjdDtcclxuICAgICAgICB0aGlzLm5ld011bHRpcGxlQXR0YWNobWVudHMgPSBbbmV3TGlua09iamVjdF07XHJcblxyXG5cclxuICAgICAgICAvLyBDLiBDaGlhbWEgbGEgdHVhIGZ1bnppb25lIGRpIGNvbmZlcm1hIGNlbnRyYWxlIVxyXG4gICAgICAgIHRoaXMuY29uZmlybUFkZEF0dGFjaG1lbnQoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIC8vIE1ldG9kbyBwZXIgb3R0ZW5lcmUgbGUgY2xhc3NpIENTUyBkaW5hbWljaGVcclxuICBnZXRDYXJkQ2xhc3MoYXR0OiBJQXR0YWNobWVudERUTyk6IHsgW2tleTogc3RyaW5nXTogYm9vbGVhbiB9IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICdmaWxlLXByZXZpZXcnOiB0cnVlLFxyXG4gICAgICAndXBsb2FkaW5nJzogISFhdHQuaXNVcGxvYWRpbmcsXHJcbiAgICAgICdjYXJkLXNtYWxsJzogdGhpcy5jYXJkU2l6ZSA9PT0gJ3NtYWxsJyxcclxuICAgICAgJ2NhcmQtbWVkaXVtJzogdGhpcy5jYXJkU2l6ZSA9PT0gJ21lZGl1bScsXHJcbiAgICAgICdjYXJkLWxhcmdlJzogdGhpcy5jYXJkU2l6ZSA9PT0gJ2xhcmdlJyxcclxuICAgICAgLy8gTmVzc3VuYSBjbGFzc2Ugc3BlY2lmaWNhIHBlciAnY3VzdG9tJywgdXNlcmVtbyBzdHlsZS5jc3NUZXh0XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8gUXVlc3RhIGZ1bnppb25lIG9yYSBzaSBhcHBsaWNhIGFsIGNvbnRlbml0b3JlLCBub24gYWxsYSBzaW5nb2xhIGNhcmQuXHJcbiAgZ2V0UHJldmlld3NDb250YWluZXJTdHlsZSgpOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IHtcclxuICAgIGxldCBtaW5XaWR0aCA9ICcyMDBweCc7IC8vIERpbWVuc2lvbmUgZGkgZGVmYXVsdCBwZXIgJ21lZGl1bSdcclxuXHJcbiAgICBpZiAodGhpcy5jYXJkU2l6ZSA9PT0gJ3NtYWxsJykge1xyXG4gICAgICBtaW5XaWR0aCA9ICcxNDBweCc7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuY2FyZFNpemUgPT09ICdsYXJnZScpIHtcclxuICAgICAgbWluV2lkdGggPSAnMjgwcHgnO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLmNhcmRTaXplID09PSAnY3VzdG9tJykge1xyXG4gICAgICBtaW5XaWR0aCA9IGAke3RoaXMuY3VzdG9tQ2FyZFdpZHRoUHh9cHhgO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7ICctLWNhcmQtbWluLXdpZHRoJzogbWluV2lkdGggfTtcclxuICB9XHJcbn1cclxuIiwiPCEtLSBTZSByaWNoaWVzdGEgbGEgZ2VzdGlvbmUgc2luZ29sYSBtb3N0cmEgaWwgcHVsc2FudGUgZGkgY2FyaWNhbWVudG8gZGkgdW4gc2luZ29sbyBmaWxlIC0tPlxyXG48ZGl2IGNsYXNzPVwiaGVhZGVyXCI+XHJcbiAgPGgxPnt7IHVwbG9hZFRpdGxlIH19PC9oMT5cclxuICBAaWYoY2hvb3NlVmlldyA9PSB0cnVlKXtcclxuICA8bWF0LWJ1dHRvbi10b2dnbGUtZ3JvdXAgW3ZhbHVlXT1cInZpZXdNb2RlXCIgKGNoYW5nZSk9XCJzZXRWaWV3TW9kZSgkZXZlbnQudmFsdWUpXCJcclxuICAgIGFyaWEtbGFiZWw9XCJNb2RhbGl0w6AgZGkgdmlzdWFsaXp6YXppb25lXCI+XHJcbiAgICA8bWF0LWJ1dHRvbi10b2dnbGUgdmFsdWU9XCJjYXJkXCI+PG1hdC1pY29uPmdyaWRfdmlldzwvbWF0LWljb24+PC9tYXQtYnV0dG9uLXRvZ2dsZT5cclxuICAgIDxtYXQtYnV0dG9uLXRvZ2dsZSB2YWx1ZT1cInRhYmxlXCI+PG1hdC1pY29uPnZpZXdfbGlzdDwvbWF0LWljb24+PC9tYXQtYnV0dG9uLXRvZ2dsZT5cclxuICA8L21hdC1idXR0b24tdG9nZ2xlLWdyb3VwPlxyXG4gIH1cclxuPC9kaXY+XHJcblxyXG48IS0tIEdlc3Rpb25lIHNpbmdvbG8gLS0+XHJcbkBpZiAobXVsdGlwbGVBdHRhY2htZW50ICE9IHRydWUpIHtcclxuQGlmICghc2luZ2xlQXR0YWNobWVudERyYWdBbmREcm9wKSB7XHJcbkBpZiAoIWFkZGluZ0xpbmtNb2RlKSB7XHJcbjxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxyXG4gIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiYWRkQXR0YWNobWVudEJ1dHRvblwiPjwvbmctY29udGFpbmVyPlxyXG48L2Rpdj5cclxufSBAZWxzZSB7XHJcbjxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxyXG4gIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiYWRkaW5nTGlua1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XHJcbjwvZGl2PlxyXG59XHJcbn0gQGVsc2Uge1xyXG48aW5wdXQgI2ZpbGVJbnB1dCBpZD1cImZpbGVfYXR0YWNobWVudFwiIG5hbWU9XCJmaWxlX2F0dGFjaG1lbnRcIiB0eXBlPVwiZmlsZVwiIGhpZGRlbiAoY2hhbmdlKT1cIm9uRmlsZUFkZGVkKCRldmVudClcIlxyXG4gIFthY2NlcHRdPVwiYWNjZXB0ZWRGaWxlVHlwZXNcIiBbbXVsdGlwbGVdPVwibG9hZE11bHRpcGxlRmlsZXNcIiAvPlxyXG5cclxuQGlmIChhbGxvd2VkVHlwZXMgJiYgYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDEpICYmICghYXR0YWNobWVudHNMaXN0IHx8IGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPT0gMCB8fFxyXG4oYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA+IDAgJiYgIWF0dGFjaG1lbnRzTGlzdFswXSkpKSB7XHJcbjxkaXYgY2xhc3M9XCJkcm9wYm94XCIgW2NsYXNzLmRyYWdvdmVyXT1cImRyYWdPdmVyXCIgKGRyYWdvdmVyKT1cImRyYWdPdmVyID0gdHJ1ZTsgJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIlxyXG4gIChkcmFnbGVhdmUpPVwiZHJhZ092ZXIgPSBmYWxzZVwiIChkcm9wKT1cImRyYWdPdmVyID0gZmFsc2U7IGZpbGVEcm9wcGVkKCRldmVudClcIlxyXG4gIChjbGljayk9XCJvblNlbGVjdEZpbGUoJGV2ZW50LCBmaWxlSW5wdXQpXCIgcm9sZT1cImJ1dHRvblwiIHRhYmluZGV4PVwiMFwiIChrZXlkb3duLmVudGVyKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAoa2V5ZG93bi5zcGFjZSk9XCJmaWxlSW5wdXQuY2xpY2soKVwiPlxyXG4gIDxkaXYgY2xhc3M9XCJkcm9wYm94LWljb25cIj7wn5OBPC9kaXY+XHJcbiAgPGRpdiBjbGFzcz1cImRyb3Bib3gtdGV4dFwiPnt7IGRyb3BIZXJlTGFiZWwgfX08L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwiZHJvcGJveC1zdWJ0ZXh0XCI+XHJcbiAgICB7eyBzdXBwb3J0ZWRGb3JtYXRzTGFiZWwgfX1cclxuICA8L2Rpdj5cclxuICA8YnV0dG9uIGNsYXNzPVwiYnJvd3NlLWJ0blwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBmaWxlSW5wdXQuY2xpY2soKVwiPlxyXG4gICAge3sgYnJvd3NlRmlsZXNMYWJlbCB9fVxyXG4gIDwvYnV0dG9uPlxyXG4gIDxkaXYgY2xhc3M9XCJzZWNvbmRhcnktYWN0aW9uXCI+XHJcbiAgICBAaWYgKGFsbG93ZWRUeXBlcy5pbmNsdWRlcygyKSB8fCBhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMykpIHtcclxuICAgIEBpZiAoYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDIpICYmIGFsbG93ZWRUeXBlcy5pbmNsdWRlcygzKSkge1xyXG4gICAgPGEgY2xhc3M9XCJzZWNvbmRhcnktYWN0aW9uLWxpbmtcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwibGlua01lbnVcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgIG8gYWdnaXVuZ2kgZGEgd2ViXHJcbiAgICA8L2E+XHJcbiAgICA8bWF0LW1lbnUgI2xpbmtNZW51PVwibWF0TWVudVwiPlxyXG4gICAgICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cInN3aXRjaFRvQWRkaW5nTGlua01vZGUoKVwiPlxyXG4gICAgICAgIDxtYXQtaWNvbj5saW5rPC9tYXQtaWNvbj5cclxuICAgICAgICA8c3Bhbj5BZ2dpdW5naSBkYSBsaW5rPC9zcGFuPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJjaG9vc2VEcm9wYm94RmlsZSgpXCI+XHJcbiAgICAgICAgPG1hdC1pY29uPmNsb3VkX3F1ZXVlPC9tYXQtaWNvbj5cclxuICAgICAgICA8c3Bhbj5DYXJpY2EgZGEgRHJvcGJveDwvc3Bhbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L21hdC1tZW51PlxyXG4gICAgfVxyXG5cclxuICAgIEBlbHNlIGlmIChhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMikpIHtcclxuICAgIDxhIGNsYXNzPVwic2Vjb25kYXJ5LWFjdGlvbi1saW5rXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgc3dpdGNoVG9BZGRpbmdMaW5rTW9kZSgpXCI+XHJcbiAgICAgIGFnZ2l1bmdpIHVuIGxpbmtcclxuICAgIDwvYT5cclxuICAgIH1cclxuXHJcbiAgICBAZWxzZSBpZiAoYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDMpKSB7XHJcbiAgICA8YSBjbGFzcz1cInNlY29uZGFyeS1hY3Rpb24tbGlua1wiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IGNob29zZURyb3Bib3hGaWxlKClcIj5cclxuICAgICAgY2FyaWNhIGRhIERyb3Bib3hcclxuICAgIDwvYT5cclxuICAgIH1cclxuICAgIH1cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcbn1cclxufVxyXG5cclxuPCEtLSBBemlvbmkgc2luZ29sbyBlbGVtZW50byAoY29tZSBwcmltYSkgLS0+XHJcbjxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxyXG4gIEBpZiAoYXR0YWNobWVudHNMaXN0ICYmIGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPiAwICYmIGF0dGFjaG1lbnRzTGlzdFswXSkge1xyXG4gIDxidXR0b24gY2xhc3M9XCJtYi0yIG1lLTIgZXFwLWF0dGFjaG1lbnRzLWRvd25sb2FkLWJ0blwiIChjbGljayk9XCJ2aWV3QXR0YWNobWVudChhdHRhY2htZW50c0xpc3RbMF0pXCIgdHlwZT1cImJ1dHRvblwiXHJcbiAgICBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIj5cclxuICAgIEBpZiAoYXR0YWNobWVudHNMaXN0WzBdLkF0dGFjaG1lbnRUeXBlID09IEF0dGFjaG1lbnRUeXBlLkZJTEUpIHtcclxuICAgIDxtYXQtaWNvbj5kb3dubG9hZDwvbWF0LWljb24+XHJcbiAgICB9IEBlbHNlIHtcclxuICAgIDxtYXQtaWNvbj5vcGVuX2luX25ldzwvbWF0LWljb24+XHJcbiAgICB9XHJcbiAgICB7eyBhdHRhY2htZW50c0xpc3RbMF0uQXR0YWNobWVudFR5cGUgPT0gQXR0YWNobWVudFR5cGUuRklMRSA/IGRvd25sb2FkTGFiZWwgOiBvcGVuTGlua0xhYmVsIH19XHJcbiAgPC9idXR0b24+XHJcblxyXG4gIEBpZiAoc2hvd1ByZXZpZXcgJiYgKCFhdHRhY2htZW50c0xpc3RbMF0uRmlsZUNvbnRlbnRUeXBlIHx8ICghYXR0YWNobWVudHNMaXN0WzBdLkZpbGVDb250ZW50VHlwZS5zdGFydHNXaXRoKCd2aWRlbycpXHJcbiAgJiYgIWF0dGFjaG1lbnRzTGlzdFswXS5GaWxlQ29udGVudFR5cGUuc3RhcnRzV2l0aCgnYXVkaW8nKSkpICYmIGF0dGFjaG1lbnRzTGlzdFswXS5Jc0ltYWdlID09IHRydWUpIHtcclxuICA8YnV0dG9uIGNsYXNzPVwibWItMiBtZS0yIGVxcC1hdHRhY2htZW50cy1wcmV2aWV3LWJ0blwiIChjbGljayk9XCJvcGVuUHJldmlld0RpYWxvZyhhdHRhY2htZW50c0xpc3RbMF0pXCIgdHlwZT1cImJ1dHRvblwiXHJcbiAgICBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIj5cclxuICAgIDxtYXQtaWNvbj52aXNpYmlsaXR5PC9tYXQtaWNvbj4ge3sgcHJldmlld0xhYmVsIH19XHJcbiAgPC9idXR0b24+XHJcbiAgfVxyXG5cclxuICA8YnV0dG9uIFtkaXNhYmxlZF09XCJkaXNhYmxlQWN0aW9uXCIgY2xhc3M9XCJtYi0yIGVxcC1hdHRhY2htZW50cy1kZWxldGUtYnRuXCJcclxuICAgIChjbGljayk9XCJkZWxldGVBdHRhY2htZW50KGF0dGFjaG1lbnRzTGlzdFswXSlcIiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gW2Rpc2FibGVkXT1cImlzRGlzYWJsZWRcIj5cclxuICAgIDxtYXQtaWNvbj5kZWxldGU8L21hdC1pY29uPiB7eyBkZWxldGVMYWJlbCB9fVxyXG4gIDwvYnV0dG9uPlxyXG4gIH1cclxuPC9kaXY+XHJcbn1cclxuXHJcbjwhLS0gR2VzdGlvbmUgbXVsdGlwbGEgLS0+XHJcbkBpZiAobXVsdGlwbGVBdHRhY2htZW50ID09IHRydWUpIHtcclxuPGlucHV0ICNmaWxlSW5wdXQgaWQ9XCJmaWxlX2F0dGFjaG1lbnRfbXVsdGlcIiBuYW1lPVwiZmlsZV9hdHRhY2htZW50X211bHRpXCIgdHlwZT1cImZpbGVcIiBoaWRkZW5cclxuICAoY2hhbmdlKT1cIm9uRmlsZUFkZGVkKCRldmVudClcIiBbYWNjZXB0XT1cImFjY2VwdGVkRmlsZVR5cGVzXCIgW211bHRpcGxlXT1cImxvYWRNdWx0aXBsZUZpbGVzXCIgLz5cclxuXHJcbjxkaXYgY2xhc3M9XCJkcm9wYm94XCIgW2NsYXNzLmRyYWdvdmVyXT1cImRyYWdPdmVyXCIgKGRyYWdvdmVyKT1cImRyYWdPdmVyID0gdHJ1ZTsgJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIlxyXG4gIChkcmFnbGVhdmUpPVwiZHJhZ092ZXIgPSBmYWxzZVwiIChkcm9wKT1cImRyYWdPdmVyID0gZmFsc2U7IGZpbGVEcm9wcGVkKCRldmVudClcIlxyXG4gIChjbGljayk9XCJvblNlbGVjdEZpbGUoJGV2ZW50LCBmaWxlSW5wdXQpXCIgcm9sZT1cImJ1dHRvblwiIHRhYmluZGV4PVwiMFwiIChrZXlkb3duLmVudGVyKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAoa2V5ZG93bi5zcGFjZSk9XCJmaWxlSW5wdXQuY2xpY2soKVwiPlxyXG4gIDxkaXYgY2xhc3M9XCJkcm9wYm94LWljb25cIj7wn5OBPC9kaXY+XHJcbiAgPGRpdiBjbGFzcz1cImRyb3Bib3gtdGV4dFwiPnt7IGRyb3BIZXJlTGFiZWwgfX08L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwiZHJvcGJveC1zdWJ0ZXh0XCI+XHJcbiAgICB7eyBzdXBwb3J0ZWRGb3JtYXRzTGFiZWwgfX1cclxuICA8L2Rpdj5cclxuICA8YnV0dG9uIGNsYXNzPVwiYnJvd3NlLWJ0blwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBmaWxlSW5wdXQuY2xpY2soKVwiPlxyXG4gICAge3sgYnJvd3NlRmlsZXNMYWJlbCB9fVxyXG4gIDwvYnV0dG9uPlxyXG4gIDxkaXYgY2xhc3M9XCJzZWNvbmRhcnktYWN0aW9uLWxpbmtcIj5cclxuICAgIG8gPGEgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgc3dpdGNoVG9BZGRpbmdMaW5rTW9kZSgpXCI+YWdnaXVuZ2kgdW4gbGluazwvYT5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcbn1cclxuXHJcbkBpZiAoYXR0YWNobWVudHNMaXN0Py5sZW5ndGggPiAwICYmIHNob3dTdW1tYXJ5KSB7XHJcbjxkaXYgY2xhc3M9XCJ1cGxvYWQtc3RhdHNcIj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cInN0YXRzLWluZm9cIj5cclxuICAgIDxkaXYgY2xhc3M9XCJzdGF0LWl0ZW1cIj5cclxuICAgICAgPGRpdiBjbGFzcz1cInN0YXQtdmFsdWVcIj57eyBhdHRhY2htZW50c0xpc3Q/Lmxlbmd0aCB9fTwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdC1sYWJlbFwiPnt7IGZpbGVzTGFiZWwgfX08L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cInN0YXQtaXRlbVwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdC12YWx1ZVwiPnt7IHRvdGFsU2l6ZUZvcm1hdHRlZCB9fTwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdC1sYWJlbFwiPnt7IHRvdGFsU2l6ZUxhYmVsIH19PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhclwiPlxyXG4gICAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWZpbGxcIiBbc3R5bGUud2lkdGguJV09XCJwcm9ncmVzc1BlcmNlbnRcIj48L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbjwvZGl2PlxyXG59IEBlbHNlIGlmKGF0dGFjaG1lbnRzTGlzdD8ubGVuZ3RoID09IDApe1xyXG48ZGl2IGNsYXNzPVwiZW1wdHktc3RhdGVcIj57eyBlbXB0eVN0YXRlTGFiZWwgfX08L2Rpdj5cclxufVxyXG5cclxuPCEtLSBHcmlnbGlhIGFudGVwcmltZSBjYXJkICh2YWxlIHBlciBzaW5nb2xvIGUgbXVsdGlwbG8pIC0tPlxyXG5AaWYgKHZpZXdNb2RlID09PSAnY2FyZCcpIHtcclxuXHJcbjxkaXYgY2xhc3M9XCJmaWxlLXByZXZpZXdzXCIgW25nU3R5bGVdPVwiZ2V0UHJldmlld3NDb250YWluZXJTdHlsZSgpXCI+XHJcbiAgQGZvciAoYXR0IG9mIGF0dGFjaG1lbnRzTGlzdDsgdHJhY2sgYXR0LklEKSB7XHJcbiAgPGRpdiBbbmdDbGFzc109XCJnZXRDYXJkQ2xhc3MoYXR0KVwiPlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJwcmV2aWV3LWltZy1jb250YWluZXJcIiAoY2xpY2spPVwiIWF0dC5pc1VwbG9hZGluZyAmJiBvcGVuUHJldmlld0RpYWxvZyhhdHQpXCI+XHJcbiAgICAgIEBpZiAoYXR0LklzSW1hZ2UpIHtcclxuICAgICAgPGltZyBjbGFzcz1cInByZXZpZXctaW1nXCIgW3NyY109XCInZGF0YTppbWFnZS9wbmc7YmFzZTY0LCcgKyAoYXR0LkZpbGVUaHVtYm5haWxCYXNlNjQgfHwgYXR0LkZpbGVEYXRhQmFzZTY0KVwiXHJcbiAgICAgICAgW2FsdF09XCJhdHQuRmlsZU5hbWVcIiAvPlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgPGRpdiBjbGFzcz1cImZpbGUtaWNvblwiPlxyXG4gICAgICAgIDxpIFtuZ0NsYXNzXT1cImdldEF0dGFjaG1lbnRJY29uKGF0dClcIj48L2k+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiZmlsZS1pbmZvXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJmaWxlLW5hbWVcIiBbdGl0bGVdPVwiYXR0LkZpbGVOYW1lXCI+e3sgYXR0LkZpbGVOYW1lIH19PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICBAaWYoIWRpc2FibGVBY3Rpb24pe1xyXG4gICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJyZW1vdmUtYnRuXCIgdHlwZT1cImJ1dHRvblwiIGFyaWEtbGFiZWw9XCJSaW11b3ZpIGFsbGVnYXRvXCJcclxuICAgICAgKGNsaWNrKT1cImRlbGV0ZUF0dGFjaG1lbnQoYXR0KVwiPlxyXG4gICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgfVxyXG5cclxuICAgIEBpZiAoYXR0LmlzVXBsb2FkaW5nKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwidXBsb2FkLXNwaW5uZXJcIj48L2Rpdj5cclxuICAgIH1cclxuICA8L2Rpdj5cclxuICB9XHJcbjwvZGl2PlxyXG5cclxufSBAZWxzZSB7XHJcblxyXG48ZGl2IGNsYXNzPVwidGFibGUtdmlldy1jb250YWluZXJcIj5cclxuICA8ZGl2IGNsYXNzPVwidGFibGUtaGVhZGVyXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwidGFibGUtY2VsbCBuYW1lLWNvbFwiPkZpbGU8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jZWxsIGFjdGlvbnMtY29sXCI+QXppb25pPC9kaXY+XHJcbiAgPC9kaXY+XHJcblxyXG4gIEBmb3IgKGF0dCBvZiBhdHRhY2htZW50c0xpc3Q7IHRyYWNrIGF0dC5JRCkge1xyXG4gIDxkaXYgY2xhc3M9XCJ0YWJsZS1yb3dcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jZWxsIG5hbWUtY29sXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiZmlsZS1pY29uLXNtYWxsXCIgW25nQ2xhc3NdPVwiZ2V0QXR0YWNobWVudEljb24oYXR0KVwiPjwvaT5cclxuICAgICAgPGRpdiBjbGFzcz1cImZpbGUtaW5mby10ZXh0XCI+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLW5hbWUtdGFibGVcIj57eyBhdHQuRmlsZU5hbWUgfX08L3NwYW4+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlLXR5cGUtdGFibGVcIj57eyBhdHQuRmlsZUV4dGVuc2lvbiB8fCAnTGluaycgfX08L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cInRhYmxlLWNlbGwgYWN0aW9ucy1jb2xcIj5cclxuICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cInZpZXdBdHRhY2htZW50KGF0dClcIiBtYXRUb29sdGlwPVwiVmlzdWFsaXp6YS9TY2FyaWNhXCI+XHJcbiAgICAgICAgPG1hdC1pY29uPnt7IGF0dC5BdHRhY2htZW50VHlwZSA9PT0gYXR0YWNobWVudFR5cGUuRklMRSA/ICdkb3dubG9hZCcgOiAnb3Blbl9pbl9uZXcnIH19PC9tYXQtaWNvbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIFttYXRNZW51VHJpZ2dlckZvcl09XCJhY3Rpb25zTWVudVwiIG1hdFRvb2x0aXA9XCJBbHRyZSBvcHppb25pXCI+XHJcbiAgICAgICAgPG1hdC1pY29uPm1vcmVfdmVydDwvbWF0LWljb24+XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8bWF0LW1lbnUgI2FjdGlvbnNNZW51PVwibWF0TWVudVwiPlxyXG4gICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbVxyXG4gICAgICAgICAgKGNsaWNrKT1cIm9wZW5QcmV2aWV3RGlhbG9nKGF0dClcIj48bWF0LWljb24+dmlzaWJpbGl0eTwvbWF0LWljb24+PHNwYW4+QW50ZXByaW1hPC9zcGFuPjwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cImRpc2FibGVBY3Rpb25cIiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJkZWxldGVBdHRhY2htZW50KGF0dClcIiBtYXRUb29sdGlwPVwiRWxpbWluYVwiPlxyXG4gICAgICAgICAgPG1hdC1pY29uIGNvbG9yPVwid2FyblwiPmRlbGV0ZTwvbWF0LWljb24+XHJcbiAgICAgICAgICA8c3Bhbj5FbGltaW5hPC9zcGFuPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L21hdC1tZW51PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgfVxyXG48L2Rpdj5cclxufVxyXG5cclxuPCEtLSBOb3RpZmljYSB0b2FzdCAtLT5cclxuPGRpdiBjbGFzcz1cInVwbG9hZC1ub3RpZmljYXRpb25cIiBbY2xhc3Muc2hvd109XCJ0b2FzdD8udmlzaWJsZVwiIFtjbGFzcy5zdWNjZXNzXT1cInRvYXN0Py50eXBlID09PSAnc3VjY2VzcydcIlxyXG4gIFtjbGFzcy5lcnJvcl09XCJ0b2FzdD8udHlwZSA9PT0gJ2Vycm9yJ1wiPlxyXG4gIDxzcGFuPnt7IHRvYXN0Py50ZXh0IH19PC9zcGFuPlxyXG4gIDxkaXYgY2xhc3M9XCJub3RpZmljYXRpb24tcHJvZ3Jlc3NcIj48L2Rpdj5cclxuPC9kaXY+XHJcblxyXG5cclxuPG5nLXRlbXBsYXRlICNkaWFsb2dDcm9wSW1hZ2U+XHJcbiAgPGRpdiBzdHlsZT1cIm92ZXJmbG93LXg6IGhpZGRlblwiIFtuZ0NsYXNzXT1cImNyb3BEaWFsb2dDbGFzc1wiPlxyXG4gICAgQGlmIChzaG93Q3JvcEltYWdlID09IHRydWUpIHtcclxuICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3JvcHBpZVRlbXBsYXRlXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgZm9ybTogbmV3QXR0YWNobWVudEZvcm0gfVwiPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbiAgICB9XHJcbiAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG5cclxuPG5nLXRlbXBsYXRlICNpbmxpbmVQcmV2aWV3VGVtcGxhdGUgbGV0LXJvdz1cInJvd1wiPlxyXG4gIEBpZiAocm93LkF0dGFjaG1lbnRUeXBlICE9IEF0dGFjaG1lbnRUeXBlLkxJTksgJiYgcm93LklzSW1hZ2UpIHtcclxuICA8ZGl2IGNsYXNzPVwiaW5saW5lLXByZXZpZXctY29udGFpbmVyXCIgKGNsaWNrKT1cIm9wZW5QcmV2aWV3RGlhbG9nKHJvdylcIj5cclxuICAgIDxpbWcgW3NyY109XCInZGF0YTppbWFnZS9wbmc7YmFzZTY0LCcgKyAocm93LkZpbGVUaHVtYm5haWxCYXNlNjQgPyByb3cuRmlsZVRodW1ibmFpbEJhc2U2NCA6IHJvdy5GaWxlRGF0YUJhc2U2NClcIiAvPlxyXG4gIDwvZGl2PlxyXG4gIH0gQGVsc2UgaWYgKHJvdy5BdHRhY2htZW50VHlwZSAhPSBBdHRhY2htZW50VHlwZS5MSU5LICYmICFyb3cuSXNJbWFnZSkge1xyXG4gIDxkaXYgY2xhc3M9XCJpbmxpbmUtcHJldmlldy1jb250YWluZXJcIiAoY2xpY2spPVwib3BlblByZXZpZXdEaWFsb2cocm93KVwiPlxyXG4gICAgPGkgW25nQ2xhc3NdPVwiZ2V0QXR0YWNobWVudEljb24ocm93KVwiPjwvaT5cclxuICA8L2Rpdj5cclxuICB9XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG5cclxuPG5nLXRlbXBsYXRlICNkaWFsb2dQcmV2aWV3PlxyXG4gIEBpZiAoc2VsZWN0ZWRBdHRhY2htZW50KSB7XHJcbiAgPGgyIG1hdC1kaWFsb2ctdGl0bGUgY2xhc3M9XCJkaWFsb2ctaGVhZGVyXCI+XHJcbiAgICA8c3Bhbj5cclxuICAgICAge3sgcHJldmlld0xhYmVsIH19IHt7IHNlbGVjdGVkQXR0YWNobWVudCEuQXR0YWNobWVudFR5cGUgPT09IGF0dGFjaG1lbnRUeXBlLkZJTEUgPyBcIkZpbGVcIiA6IFwiTGlua1wiIH19XHJcbiAgICA8L3NwYW4+XHJcbiAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBtYXQtZGlhbG9nLWNsb3NlIGFyaWEtbGFiZWw9XCJDaGl1ZGkgYW50ZXByaW1hXCI+XHJcbiAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XHJcbiAgICA8L2J1dHRvbj5cclxuICA8L2gyPlxyXG5cclxuICA8bWF0LWRpYWxvZy1jb250ZW50IGNsYXNzPVwiZGlhbG9nLWNvbnRlbnRcIj5cclxuICAgIEBpZiAoc2VsZWN0ZWRBdHRhY2htZW50IS5Jc0ltYWdlKSB7XHJcbiAgICA8aW1nIGNsYXNzPVwicHJldmlldy1pbWFnZVwiXHJcbiAgICAgIFtzcmNdPVwiJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwnICsgKHNlbGVjdGVkQXR0YWNobWVudCEuRmlsZURhdGFCYXNlNjQgfHwgc2VsZWN0ZWRBdHRhY2htZW50IS5GaWxlVGh1bWJuYWlsQmFzZTY0KVwiXHJcbiAgICAgIGFsdD1cIkFudGVwcmltYSBhbGxlZ2F0b1wiIC8+XHJcbiAgICB9IEBlbHNlIHtcclxuICAgIDxpZnJhbWUgY2xhc3M9XCJwcmV2aWV3LWlmcmFtZVwiIFtzcmNdPVwic2VsZWN0ZWRBdHRhY2htZW50IS5UcnVzdGVkVXJsXCIgW3RpdGxlXT1cInNlbGVjdGVkQXR0YWNobWVudCEuRmlsZU5hbWVcIj5cclxuICAgIDwvaWZyYW1lPlxyXG4gICAgfVxyXG4gIDwvbWF0LWRpYWxvZy1jb250ZW50PlxyXG5cclxuICA8bWF0LWRpYWxvZy1hY3Rpb25zIFthbGlnbl09XCInY2VudGVyJ1wiPlxyXG4gICAgQGlmIChzZWxlY3RlZEF0dGFjaG1lbnQhLkF0dGFjaG1lbnRUeXBlICE9PSBBdHRhY2htZW50VHlwZS5MSU5LKSB7XHJcbiAgICA8YnV0dG9uIG1hdC1yYWlzZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJ2aWV3QXR0YWNobWVudChzZWxlY3RlZEF0dGFjaG1lbnQhKVwiPlxyXG4gICAgICA8bWF0LWljb24+ZG93bmxvYWQ8L21hdC1pY29uPlxyXG4gICAgICA8c3Bhbj57eyBkb3dubG9hZExhYmVsIH19PC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICB9XHJcbiAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XHJcbiAgfVxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuXHJcbjwhLS0gVEVNUExBVEUgUEVSIElMIFBVTFNBTlRFIERJIEFHR0lVTlRBIE5VT1ZPIEFMTEVHQVRPIC0tPlxyXG48bmctdGVtcGxhdGUgI2FkZEF0dGFjaG1lbnRCdXR0b24+XHJcbiAgPGlucHV0ICNmaWxlSW5wdXQgc3R5bGU9XCJkaXNwbGF5OiBub25lXCIgaWQ9XCJmaWxlX2F0dGFjaG1lbnRcIiBuYW1lPVwiZmlsZV9hdHRhY2htZW50XCIgdHlwZT1cImZpbGVcIlxyXG4gICAgKGNoYW5nZSk9XCJvbkZpbGVBZGRlZCgkZXZlbnQpXCIgW2FjY2VwdF09XCJhY2NlcHRlZEZpbGVUeXBlc1wiIFttdWx0aXBsZV09XCJsb2FkTXVsdGlwbGVGaWxlc1wiIC8+XHJcblxyXG4gIEBpZiAoYWxsb3dlZFR5cGVzICYmIGFsbG93ZWRUeXBlcy5sZW5ndGggPT0gMSAmJiAobXVsdGlwbGVBdHRhY2htZW50ID09IHRydWUgfHwgIWF0dGFjaG1lbnRzTGlzdCB8fFxyXG4gIGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPT0gMCB8fCAoYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA+IDAgJiYgIWF0dGFjaG1lbnRzTGlzdFswXSkpKSB7XHJcbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYi00IG1lLTUgZXFwLWF0dGFjaG1lbnRzLWFkZC1idG5cIiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCJcclxuICAgIChjbGljayk9XCJhZGRGaWxlKGFsbG93ZWRUeXBlc1swXSwgZmlsZUlucHV0KVwiIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkXCI+XHJcbiAgICBAaWYgKGFsbG93ZWRUeXBlc1swXSA9PSAxKSB7IDxtYXQtaWNvbj5jbG91ZF91cGxvYWQ8L21hdC1pY29uPiB9XHJcbiAgICBAaWYgKGFsbG93ZWRUeXBlc1swXSA9PSAyKSB7IDxpIGNsYXNzPVwiZmFzIGZhLWxpbmtcIj48L2k+IH1cclxuICAgIEBpZiAoYWxsb3dlZFR5cGVzWzBdID09IDMpIHsgPGkgY2xhc3M9XCJmYS1icmFuZHMgZmEtZHJvcGJveFwiPjwvaT4gfVxyXG4gICAgPHNwYW4gc3R5bGU9XCJtYXJnaW4tbGVmdDogMTBweFwiPlxyXG4gICAgICB7eyBhbGxvd2VkVHlwZXNbMF0gPT0gMSA/IChhZGRCdXR0b25MYWJlbCArIFwiIGZpbGVcIikgOiBhbGxvd2VkVHlwZXNbMF0gPT0gMiA/IChhZGRCdXR0b25MYWJlbCArIFwiIGxpbmtcIikgOlxyXG4gICAgICB1cGxvYWRXaXRoRHJvcGJveExhYmVsIH19XHJcbiAgICA8L3NwYW4+XHJcbiAgPC9idXR0b24+XHJcbiAgfVxyXG5cclxuICBAaWYgKCFzZXBhcmF0ZWRVcGxvYWRCdXR0b25zICYmIGFsbG93ZWRUeXBlcyAmJiBhbGxvd2VkVHlwZXMubGVuZ3RoID4gMSAmJiAobXVsdGlwbGVBdHRhY2htZW50ID09IHRydWUgfHxcclxuICAhYXR0YWNobWVudHNMaXN0IHx8IGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPT0gMCB8fCAoYXR0YWNobWVudHNMaXN0Lmxlbmd0aCA+IDAgJiYgIWF0dGFjaG1lbnRzTGlzdFswXSkpKSB7XHJcbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYi00IG1lLTUgZXFwLWF0dGFjaG1lbnRzLWFkZC1idG5cIiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCJcclxuICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJhdHRhY2htZW50VHlwZU1lbnVcIiBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiPlxyXG4gICAgQGlmIChtdWx0aXBsZUF0dGFjaG1lbnQgIT0gdHJ1ZSkgeyA8bWF0LWljb24+Y2xvdWRfdXBsb2FkPC9tYXQtaWNvbj4gfSBAZWxzZSB7IDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPiB9XHJcbiAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAwcHhcIj57eyBhZGRCdXR0b25MYWJlbCB9fTwvc3Bhbj5cclxuICA8L2J1dHRvbj5cclxuXHJcbiAgPG1hdC1tZW51ICNhdHRhY2htZW50VHlwZU1lbnU9XCJtYXRNZW51XCI+XHJcbiAgICA8aW5wdXQgI2ltYWdlSW5wdXQgc3R5bGU9XCJkaXNwbGF5OiBub25lXCIgaWQ9XCJmaWxlX2F0dGFjaG1lbnRcIiBuYW1lPVwiZmlsZV9hdHRhY2htZW50XCIgdHlwZT1cImZpbGVcIlxyXG4gICAgICAoY2hhbmdlKT1cIm9uRmlsZUFkZGVkKCRldmVudClcIiBbYWNjZXB0XT1cImFjY2VwdGVkRmlsZVR5cGVzXCIgW211bHRpcGxlXT1cImxvYWRNdWx0aXBsZUZpbGVzXCIgLz5cclxuICAgIEBpZiAoYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDEpKSB7XHJcbiAgICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImltYWdlSW5wdXQuY2xpY2soKVwiIGNsYXNzPVwiZXFwLWF0dGFjaG1lbnRzLWZpbGUtYnRuXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWZpbGVcIj48L2k+XHJcbiAgICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDEwcHhcIj5GaWxlPC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICB9XHJcbiAgICBAaWYgKGFsbG93ZWRUeXBlcy5pbmNsdWRlcygyKSkge1xyXG4gICAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJzd2l0Y2hUb0FkZGluZ0xpbmtNb2RlKClcIiBjbGFzcz1cImVxcC1hdHRhY2htZW50cy1saW5rLWJ0blwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1saW5rXCI+PC9pPlxyXG4gICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+TGluazwvc3Bhbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgfVxyXG4gICAgQGlmIChhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMykpIHtcclxuICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiY2hvb3NlRHJvcGJveEZpbGUoKVwiIGNsYXNzPVwiZXFwLWF0dGFjaG1lbnRzLWxpbmstYnRuXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiZmEtYnJhbmRzIGZhLWRyb3Bib3hcIj48L2k+XHJcbiAgICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDEwcHhcIj5Ecm9wYm94PC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICB9XHJcbiAgPC9tYXQtbWVudT5cclxuICB9XHJcblxyXG4gIEBpZiAoc2VwYXJhdGVkVXBsb2FkQnV0dG9ucyAmJiBhbGxvd2VkVHlwZXMgJiYgYWxsb3dlZFR5cGVzLmxlbmd0aCA+IDEgJiYgKG11bHRpcGxlQXR0YWNobWVudCA9PSB0cnVlIHx8XHJcbiAgIWF0dGFjaG1lbnRzTGlzdCB8fCBhdHRhY2htZW50c0xpc3QubGVuZ3RoID09IDAgfHwgKGF0dGFjaG1lbnRzTGlzdC5sZW5ndGggPiAwICYmICFhdHRhY2htZW50c0xpc3RbMF0pKSkge1xyXG4gIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj5cclxuICAgIEBpZiAoYWxsb3dlZFR5cGVzLmluY2x1ZGVzKDEpKSB7XHJcbiAgICA8YnV0dG9uIChjbGljayk9XCJpbWFnZUlucHV0LmNsaWNrKClcIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGVxcC1hdHRhY2htZW50cy1hZGQtYnRuXCIgbWF0LXJhaXNlZC1idXR0b25cclxuICAgICAgY29sb3I9XCJzZWNvbmRhcnlcIiB0eXBlPVwiYnV0dG9uXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiZmEtc29saWQgZmEtY2xvdWQtdXBsb2FkXCI+PC9pPlxyXG4gICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+RmlsZTwvc3Bhbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgfVxyXG4gICAgPGlucHV0ICNpbWFnZUlucHV0IHN0eWxlPVwiZGlzcGxheTogbm9uZVwiIGlkPVwiZmlsZV9hdHRhY2htZW50XCIgbmFtZT1cImZpbGVfYXR0YWNobWVudFwiIHR5cGU9XCJmaWxlXCJcclxuICAgICAgKGNoYW5nZSk9XCJvbkZpbGVBZGRlZCgkZXZlbnQpXCIgW2FjY2VwdF09XCJhY2NlcHRlZEZpbGVUeXBlc1wiIFttdWx0aXBsZV09XCJsb2FkTXVsdGlwbGVGaWxlc1wiIC8+XHJcbiAgICBAaWYgKGFsbG93ZWRUeXBlcy5pbmNsdWRlcygyKSkge1xyXG4gICAgPGJ1dHRvbiAoY2xpY2spPVwic3dpdGNoVG9BZGRpbmdMaW5rTW9kZSgpXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeSBlcXAtYXR0YWNobWVudHMtYWRkLWJ0blwiIG1hdC1yYWlzZWQtYnV0dG9uXHJcbiAgICAgIGNvbG9yPVwic2Vjb25kYXJ5XCIgdHlwZT1cImJ1dHRvblwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1saW5rXCI+PC9pPlxyXG4gICAgICA8c3BhbiBzdHlsZT1cIm1hcmdpbi1sZWZ0OiAxMHB4XCI+TGluazwvc3Bhbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgfVxyXG4gICAgQGlmIChhbGxvd2VkVHlwZXMuaW5jbHVkZXMoMykpIHtcclxuICAgIDxidXR0b24gKGNsaWNrKT1cImNob29zZURyb3Bib3hGaWxlKClcIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGVxcC1hdHRhY2htZW50cy1hZGQtYnRuXCIgbWF0LXJhaXNlZC1idXR0b25cclxuICAgICAgY29sb3I9XCJzZWNvbmRhcnlcIiB0eXBlPVwiYnV0dG9uXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiZmEtYnJhbmRzIGZhLWRyb3Bib3hcIj48L2k+XHJcbiAgICAgIDxzcGFuIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDEwcHhcIj5Ecm9wYm94PC9zcGFuPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICB9XHJcbiAgPC9kaXY+XHJcbiAgfVxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuXHJcbjxuZy10ZW1wbGF0ZSAjY3JvcHBpZVRlbXBsYXRlPlxyXG4gIDwhLS0gSGVhZGVyIGNvbXBhdHRvIC0tPlxyXG4gIDxoMiBjbGFzcz1cImRpYWxvZy1oZWFkZXIgbS0zXCI+XHJcbiAgICA8c3Bhbj57eyBjcm9wTGFiZWwgfX08L3NwYW4+XHJcbiAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgYXJpYS1sYWJlbD1cIkNoaXVkaVwiIChjbGljayk9XCJhYm9ydEZpbGUoKVwiPlxyXG4gICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9oMj5cclxuXHJcbiAgPCEtLSBDb250ZW51dG8gc2Nyb2xsYWJpbGUgY29uIGdyaWdsaWEgcmVzcG9uc2l2ZSAtLT5cclxuICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWNvbnRlbnRcIj5cclxuICAgIDwhLS0gVG9vbGJhciBjb250cm9sbGkgKGxhcmdlKSAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJjb250cm9scy1yb3cgY3JvcC1sYXJnZVwiPlxyXG4gICAgICBAaWYgKGNyb3BPcHRpb25zLmluY2x1ZGVzKDEpKSB7XHJcbiAgICAgIDxidXR0b24gW21hdFRvb2x0aXBdPVwicm90YXRlTGVmdExhYmVsXCIgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgbWF0LXJhaXNlZC1idXR0b25cIiAoY2xpY2spPVwicm90YXRlTGVmdCgpXCI+XHJcbiAgICAgICAgPG1hdC1pY29uPnJvdGF0ZV9sZWZ0PC9tYXQtaWNvbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b24gW21hdFRvb2x0aXBdPVwicm90YXRlUmlnaHRMYWJlbFwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG1hdC1yYWlzZWQtYnV0dG9uXCIgKGNsaWNrKT1cInJvdGF0ZVJpZ2h0KClcIj5cclxuICAgICAgICA8bWF0LWljb24+cm90YXRlX3JpZ2h0PC9tYXQtaWNvbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIH1cclxuICAgICAgQGlmIChjcm9wT3B0aW9ucy5pbmNsdWRlcygyKSkge1xyXG4gICAgICA8YnV0dG9uIFttYXRUb29sdGlwXT1cImZsaXBIb3JpbnpvbnRhbExhYmVsXCIgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgbWF0LXJhaXNlZC1idXR0b25cIiAoY2xpY2spPVwiZmxpcEhvcml6b250YWwoKVwiPlxyXG4gICAgICAgIDxtYXQtaWNvbj5mbGlwX2hvcml6b250YWw8L21hdC1pY29uPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvbiBbbWF0VG9vbHRpcF09XCJmbGlwVmVydGljYWxMYWJlbFwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG1hdC1yYWlzZWQtYnV0dG9uXCIgKGNsaWNrKT1cImZsaXBWZXJ0aWNhbCgpXCI+XHJcbiAgICAgICAgPG1hdC1pY29uPmZsaXBfdmVydGljYWw8L21hdC1pY29uPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgfVxyXG4gICAgICA8YnV0dG9uIFttYXRUb29sdGlwXT1cIidSZXNldCdcIiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtYXQtcmFpc2VkLWJ1dHRvblwiIChjbGljayk9XCJyZXN0b3JlT3JpZ2luYWxEaW1lbnNpb25zKClcIj5cclxuICAgICAgICA8bWF0LWljb24+cmVwbGF5PC9tYXQtaWNvbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIFRvb2xiYXIgY29udHJvbGxpIChzbWFsbCkgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29udHJvbHMtcm93IGNyb3Atc21hbGxcIj5cclxuICAgICAgQGlmIChjcm9wT3B0aW9ucy5pbmNsdWRlcygxKSkge1xyXG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJjb250cm9sLWljb25cIiAoY2xpY2spPVwicm90YXRlTGVmdCgpXCI+cm90YXRlX2xlZnQ8L21hdC1pY29uPlxyXG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJjb250cm9sLWljb25cIiAoY2xpY2spPVwicm90YXRlUmlnaHQoKVwiPnJvdGF0ZV9yaWdodDwvbWF0LWljb24+XHJcbiAgICAgIH1cclxuICAgICAgQGlmIChjcm9wT3B0aW9ucy5pbmNsdWRlcygyKSkge1xyXG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJjb250cm9sLWljb25cIiAoY2xpY2spPVwiZmxpcEhvcml6b250YWwoKVwiPmZsaXBfaG9yaXpvbnRhbDwvbWF0LWljb24+XHJcbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbnRyb2wtaWNvblwiIChjbGljayk9XCJmbGlwVmVydGljYWwoKVwiPmZsaXBfdmVydGljYWw8L21hdC1pY29uPlxyXG4gICAgICB9XHJcbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbnRyb2wtaWNvblwiIChjbGljayk9XCJyZXN0b3JlT3JpZ2luYWxEaW1lbnNpb25zKClcIj5yZXBsYXk8L21hdC1pY29uPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBBcmVhIGNyb3AgY29uIGNvbnRlbmltZW50byAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJjcm9wLWFyZWFcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNyb3AtY29udGFpbmVyXCI+XHJcbiAgICAgICAgPGltYWdlLWNyb3BwZXIgW2ltYWdlRmlsZV09XCJzZWxlY3RlZEZpbGVcIiBbbWFpbnRhaW5Bc3BlY3RSYXRpb109XCJmYWxzZVwiIFthdXRvQ3JvcF09XCJmYWxzZVwiXHJcbiAgICAgICAgICBbY29udGFpbldpdGhpbkFzcGVjdFJhdGlvXT1cImZhbHNlXCIgW2FzcGVjdFJhdGlvXT1cIjQgLyAzXCIgW2Nyb3BwZXJNaW5XaWR0aF09XCIxMjhcIiBbb25seVNjYWxlRG93bl09XCJ0cnVlXCJcclxuICAgICAgICAgIFtyb3VuZENyb3BwZXJdPVwiZmFsc2VcIiBbY2FudmFzUm90YXRpb25dPVwiMFwiIFt0cmFuc2Zvcm1dPVwidHJhbnNmb3JtXCIgW2FsaWduSW1hZ2VdPVwiJ2xlZnQnXCIgZm9ybWF0PVwicG5nXCJcclxuICAgICAgICAgIChpbWFnZUNyb3BwZWQpPVwiaW1hZ2VDcm9wcGVkKCRldmVudClcIiBbcmVzaXplVG9XaWR0aF09XCJjdXN0b21XaWR0aFwiIFtyZXNpemVUb0hlaWdodF09XCJjdXN0b21IZWlnaHRcIlxyXG4gICAgICAgICAgW2NhbnZhc1JvdGF0aW9uXT1cImNhbnZhc1JvdGF0aW9uXCIgW291dHB1dF09XCInYmFzZTY0J1wiPlxyXG4gICAgICAgIDwvaW1hZ2UtY3JvcHBlcj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPCEtLSBBemlvbmkgLS0+XHJcbiAgPGRpdiBjbGFzcz1cImRpYWxvZy1hY3Rpb25zIGNyb3AtbGFyZ2VcIj5cclxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgbWF0LXJhaXNlZC1idXR0b24gZXFwLWF0dGFjaG1lbnRzLWNvbmZpcm0tYnRuXCIgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgIChjbGljayk9XCJjb25maXJtQWRkQXR0YWNobWVudCgpXCI+XHJcbiAgICAgIHt7IGNvbmZpcm1MYWJlbCB9fVxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIG1hdC1yYWlzZWQtYnV0dG9uIGVxcC1hdHRhY2htZW50cy1hYm9ydC1idG5cIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFib3J0RmlsZSgpXCI+XHJcbiAgICAgIHt7IGFib3J0TGFiZWwgfX1cclxuICAgIDwvYnV0dG9uPlxyXG4gIDwvZGl2PlxyXG5cclxuICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWFjdGlvbnMgY3JvcC1zbWFsbFwiPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cImljb24tYWN0aW9uXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhYm9ydEZpbGUoKVwiIGFyaWEtbGFiZWw9XCJBYm9ydFwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhIGZhLXRpbWVzXCI+PC9pPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwiaWNvbi1hY3Rpb25cIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNvbmZpcm1BZGRBdHRhY2htZW50KClcIiBhcmlhLWxhYmVsPVwiQ29uZmlybVwiPlxyXG4gICAgICA8aSBjbGFzcz1cImZhIGZhLWNoZWNrXCI+PC9pPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG5cclxuXHJcbjwhLS0gVEVNUExBVEUgUEVSIEZPUk0gREkgQUdHSVVOVEEgREkgVU4gTElOSyAtLT5cclxuPG5nLXRlbXBsYXRlICNhZGRpbmdMaW5rVGVtcGxhdGU+XHJcbiAgPGgyIG1hdC1kaWFsb2ctdGl0bGU+QWdnaXVuZ2kgdW4gbGluazwvaDI+XHJcbiAgPG1hdC1kaWFsb2ctY29udGVudCBjbGFzcz1cImFkZC1saW5rLWRpYWxvZy1jb250ZW50XCI+XHJcbiAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cIm5ld0F0dGFjaG1lbnRGb3JtXCIgY2xhc3M9XCJhZGQtbGluay1mb3JtXCI+XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiPlxyXG4gICAgICAgIDxtYXQtbGFiZWw+VVJMICo8L21hdC1sYWJlbD5cclxuICAgICAgICA8aW5wdXQgbWF0SW5wdXQgZm9ybUNvbnRyb2xOYW1lPVwiZmlsZVBhdGhcIiBwbGFjZWhvbGRlcj1cImh0dHBzOi8vLi4uXCIgcmVxdWlyZWQ+XHJcbiAgICAgICAgQGlmIChuZXdBdHRhY2htZW50Rm9ybS5nZXQoJ2ZpbGVQYXRoJyk/Lmhhc0Vycm9yKCdwYXR0ZXJuJykpIHtcclxuICAgICAgICA8bWF0LWVycm9yPkwnVVJMIG5vbiBzZW1icmEgdmFsaWRvLjwvbWF0LWVycm9yPlxyXG4gICAgICAgIH1cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCI+XHJcbiAgICAgICAgPG1hdC1sYWJlbD5Ob21lIChvcHppb25hbGUpPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0IG1hdElucHV0IGZvcm1Db250cm9sTmFtZT1cImZpbGVOYW1lXCIgcGxhY2Vob2xkZXI9XCJFcy4gRG9jdW1lbnRvIFByb2dldHRvXCI+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICA8L2Zvcm0+XHJcbiAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XHJcbiAgPG1hdC1kaWFsb2ctYWN0aW9ucyBhbGlnbj1cImVuZFwiPlxyXG4gICAgPGJ1dHRvbiBtYXQtYnV0dG9uIG1hdC1kaWFsb2ctY2xvc2U+QW5udWxsYTwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiBbbWF0LWRpYWxvZy1jbG9zZV09XCJuZXdBdHRhY2htZW50Rm9ybS52YWx1ZVwiXHJcbiAgICAgIFtkaXNhYmxlZF09XCJuZXdBdHRhY2htZW50Rm9ybS5pbnZhbGlkXCI+XHJcbiAgICAgIEFnZ2l1bmdpXHJcbiAgICA8L2J1dHRvbj5cclxuICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cclxuPC9uZy10ZW1wbGF0ZT4iXX0=