@jax-data-science/sci-image-visualizer 0.4.0 → 0.6.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.
Files changed (32) hide show
  1. package/README.md +109 -0
  2. package/esm2022/index.mjs +2 -1
  3. package/esm2022/lib/contracts/display-types.mjs +1 -1
  4. package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +66 -0
  5. package/esm2022/lib/contracts/plot-type.mjs +6 -1
  6. package/esm2022/lib/contracts/toolbar-tool.contract.mjs +46 -4
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2 -3
  9. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +70 -7
  10. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +8 -1
  11. package/esm2022/lib/implementations/plotly/plotly.service.mjs +2 -3
  12. package/esm2022/lib/plot-mode/plot-mode-controller.mjs +329 -0
  13. package/esm2022/lib/routing-visualizer.service.mjs +6 -1
  14. package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +44 -3
  15. package/esm2022/lib/toolbar/toolbar.component.mjs +50 -21
  16. package/esm2022/lib/visualizer.component.mjs +479 -43
  17. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1092 -75
  18. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  19. package/index.d.ts +1 -0
  20. package/lib/contracts/display-types.d.ts +10 -0
  21. package/lib/contracts/plot-type-contribution.contract.d.ts +199 -0
  22. package/lib/contracts/plot-type.d.ts +10 -0
  23. package/lib/contracts/toolbar-tool.contract.d.ts +84 -5
  24. package/lib/contracts/visualizer.contract.d.ts +5 -0
  25. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +21 -0
  26. package/lib/implementations/osd/osd-coordinate-transform.d.ts +6 -0
  27. package/lib/plot-mode/plot-mode-controller.d.ts +130 -0
  28. package/lib/routing-visualizer.service.d.ts +4 -0
  29. package/lib/toolbar/brush/brush-tool.service.d.ts +21 -0
  30. package/lib/toolbar/toolbar.component.d.ts +28 -8
  31. package/lib/visualizer.component.d.ts +121 -8
  32. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { ChangeDetectorRef, Component, EventEmitter, HostListener, Inject, Input, NgZone, Optional, Output, ViewChild } from '@angular/core';
1
+ import { ChangeDetectorRef, Component, EventEmitter, HostListener, Inject, Injector, Input, NgZone, Optional, Output, ViewChild } from '@angular/core';
2
2
  import { Subject, Subscription } from 'rxjs';
3
3
  import { takeUntil } from 'rxjs/operators';
4
4
  import { MessageService } from 'primeng/api';
@@ -9,14 +9,16 @@ import { RegionOpsService } from './region-ops.service';
9
9
  import { VIZ_TOAST_KEY, VIZ_ALERT_TOAST_KEY } from './toast-outlets';
10
10
  import { VisualizerStore } from './store/visualizer-store.service';
11
11
  import { RenderOrchestrator, SliceScrubber } from './render-orchestrator';
12
- import { PlotType, isNapari3d, isSpatialOmics3d, rendererOwnsWheel, NAPARI_DEFAULT_DECIMATE, } from './contracts/plot-type';
12
+ import { PlotType, getPlotTypeDescriptor, isBuiltinPlotType, isNapari3d, isSpatialOmics3d, rendererOwnsWheel, NAPARI_DEFAULT_DECIMATE, } from './contracts/plot-type';
13
+ import { PLOT_MODE_CONTEXT, PLOT_MODE_SESSION, PLOT_TYPE_CONTRIBUTIONS, contributedPlotTypeOption, } from './contracts/plot-type-contribution.contract';
14
+ import { PlotModeController } from './plot-mode/plot-mode-controller';
13
15
  import { ViewerFeature } from './contracts/capabilities.contract';
14
16
  import { VISUALIZER } from './contracts/visualizer.contract';
15
17
  import { SAM_MODELS, getDefaultSamModelId, isSamModelReady } from './toolbar/segmentation/sam-model-registry';
16
18
  import { SamToolService } from './toolbar/segmentation/sam-tool.service';
17
19
  import { SamPointToolService } from './toolbar/segmentation/sam-point-tool.service';
18
20
  import { CellSegmentToolService } from './toolbar/segmentation/cell-segment-tool.service';
19
- import { TOOLBAR_TOOLS, visibleToolContributions, } from './contracts/toolbar-tool.contract';
21
+ import { TOOLBAR_TOOLS, dialogToolContributions, visibleToolContributions, } from './contracts/toolbar-tool.contract';
20
22
  import { ALL_TOOLBAR_TOOLS } from './contracts/toolbar-config';
21
23
  import { VIZ_CONFIG } from './contracts/viz-config';
22
24
  import { SPATIAL_DATA_PORT } from './contracts/ports/spatial-data.port';
@@ -95,21 +97,44 @@ export class VisualizerComponent {
95
97
  get isCaching() {
96
98
  return this.cacheProgress !== null && this.cacheProgress < 100;
97
99
  }
100
+ /**
101
+ * The built-in plot type being rendered. With no contributed mode active this
102
+ * is the selection itself; during one it is the mode's `baseType`. Kept with its
103
+ * original `PlotType` type for existing readers — use {@link selectedPlotTypeId}
104
+ * for the selector's id. Assigning selects that built-in type.
105
+ */
106
+ get selectedPlotType() {
107
+ return this.basePlotType;
108
+ }
109
+ set selectedPlotType(type) {
110
+ this.selectedPlotTypeId = type;
111
+ }
112
+ /** Where a `mount` panel's host element is attached once the dialog renders. */
113
+ set plotModePanelSlot(ref) {
114
+ const host = this.plotModePanel?.host;
115
+ if (ref && host && host.parentElement !== ref.nativeElement)
116
+ ref.nativeElement.appendChild(host);
117
+ }
118
+ /** The built-in type actually rendered for {@link selectedPlotTypeId}: itself
119
+ * for a built-in type, `baseType` for a contributed mode. */
120
+ get basePlotType() {
121
+ return this.plotModes.baseTypeOf(this.selectedPlotTypeId);
122
+ }
98
123
  /** True while the 3D spatial cloud is the active mode. The controls drop the ROI
99
124
  * selection there: region tools are screen-space, and against an orbiting
100
125
  * camera a drawn rectangle has no fixed meaning in the data. */
101
126
  get isSpatial3dMode() {
102
- return isSpatialOmics3d(this.selectedPlotType);
127
+ return isSpatialOmics3d(this.basePlotType);
103
128
  }
104
129
  /** LINE plot type shows the image + draggable line ROI + intensity inset. */
105
130
  get isProfileMode() {
106
- return this.selectedPlotType === PlotType.LINE;
131
+ return this.basePlotType === PlotType.LINE;
107
132
  }
108
133
  /** True for the Image plot type, which renders as a natively pan/zoom-able
109
134
  * raster — so the backend-agnostic zoom/pan toolbar tools are hidden. The
110
135
  * component drives this off the plot type, not the active backend. */
111
136
  get isImageView() {
112
- return this.selectedPlotType === PlotType.IMAGE;
137
+ return this.basePlotType === PlotType.IMAGE;
113
138
  }
114
139
  constructor(state, plotService, messageService, ngZone, cdr, session, samTool, cellSegmentTool, samPointTool, regionOps, vizConfig,
115
140
  // A constructor parameter rather than a field `inject()`: this component is
@@ -118,7 +143,13 @@ export class VisualizerComponent {
118
143
  toolContributions,
119
144
  // Optional like the rest: a host that shows only images never provides it,
120
145
  // and the spatial plot types simply stay hidden.
121
- spatialData) {
146
+ spatialData,
147
+ // Contributed plot modes. Like TOOLBAR_TOOLS the token has no factory, so a
148
+ // host that provides none gets null here and the selector is unchanged.
149
+ plotTypeContributions,
150
+ // Parent of a contributed panel component's injector. Optional only so the
151
+ // specs can construct this component with `new`.
152
+ injector) {
122
153
  this.state = state;
123
154
  this.plotService = plotService;
124
155
  this.messageService = messageService;
@@ -131,6 +162,7 @@ export class VisualizerComponent {
131
162
  this.regionOps = regionOps;
132
163
  this.vizConfig = vizConfig;
133
164
  this.spatialData = spatialData;
165
+ this.injector = injector;
134
166
  this.vizToastKey = VIZ_TOAST_KEY;
135
167
  this.vizAlertToastKey = VIZ_ALERT_TOAST_KEY;
136
168
  this.isStackEvent = new EventEmitter(false);
@@ -186,6 +218,8 @@ export class VisualizerComponent {
186
218
  this.wandSensitivity = 2.0;
187
219
  /** Brush diameter in image-pixel coordinates (drives the painted disc size). */
188
220
  this.brushSize = 40;
221
+ /** Class the brush paints while a plot mode armed it (PlotModeTools.armBrush); null = plain brush. */
222
+ this.brushClass = null;
189
223
  /** SAM model picker options + current selection (jit-ui#90 P1). Only models
190
224
  * with a hosted ONNX pair (configured via setSamModelUrls at app init) are
191
225
  * offered, so the picker can't select a model that can't run. */
@@ -198,6 +232,16 @@ export class VisualizerComponent {
198
232
  * and help dialog simply omit that group.
199
233
  */
200
234
  this.contributedTools = [];
235
+ /**
236
+ * Dialog tools registered through {@link TOOLBAR_TOOLS} (`kind: 'dialog'`),
237
+ * sorted. Their buttons sit with the host's own actions and show in the Image
238
+ * view only; each opens a floating dialog the tool fills.
239
+ */
240
+ this.dialogTools = [];
241
+ /** The dialog tool the user has open (its session may be between renders). */
242
+ this.openDialogToolId = null;
243
+ /** The open dialog tool's live dialog, as the template renders it. */
244
+ this.toolDialog = null;
201
245
  /** Active checkpoint per contributed tool. */
202
246
  this.toolModelIds = {};
203
247
  /**
@@ -264,9 +308,28 @@ export class VisualizerComponent {
264
308
  this.wireframeActive = false;
265
309
  /** napari 3D decimate factor (1 = Full … 8 = ⅛; default ½); changing it re-plots. */
266
310
  this.resolutionScale = NAPARI_DEFAULT_DECIMATE;
267
- /** Plot types the active backend advertises (3D gated by capability). */
311
+ /** The selector's entries: the built-in plot types the active backend
312
+ * advertises (3D gated by capability), then any contributed modes
313
+ * ({@link PLOT_TYPE_CONTRIBUTIONS}). */
314
+ this.plotTypeMenu = [];
315
+ /**
316
+ * The built-in plot types on offer — {@link plotTypeMenu} without contributed
317
+ * modes. Kept with its original type so existing readers are unaffected.
318
+ */
268
319
  this.plotTypeOptions = [];
269
- this.selectedPlotType = PlotType.IMAGE;
320
+ /**
321
+ * What the selector shows: a built-in type or a contributed mode's id. Every
322
+ * rendering and tool decision goes through {@link basePlotType} instead, so a
323
+ * contributed mode behaves exactly like the built-in type it rides on.
324
+ */
325
+ this.selectedPlotTypeId = PlotType.IMAGE;
326
+ /**
327
+ * The live contributed mode's side panel, as the template renders it: an
328
+ * Angular component with its own injector, or a plain host element a `mount`
329
+ * panel rendered into. Null while no contributed session is live.
330
+ */
331
+ this.plotModePanel = null;
332
+ this.destroying = false;
270
333
  /** Floating intensity-profile inset (LINE mode). */
271
334
  this.intensityInsetDiv = 'intensity-inset-plot';
272
335
  this.profilePanelPos = { x: 20, y: 70 };
@@ -317,7 +380,49 @@ export class VisualizerComponent {
317
380
  /** Whether the live spatial dataset brings pixels of its own — a tissue image it
318
381
  * registers onto, or a volume that is published as a z-stack image. */
319
382
  this.spatialDatasetHasPixels = false;
383
+ /** The live dialog body's teardown, and a pending wait for its host to connect. */
384
+ this.toolDialogTeardown = null;
385
+ this.toolDialogFrame = null;
386
+ /** Toolbar tools for contributed modes. Calls can come from outside Angular, hence the zone. */
387
+ this.plotModeTools = {
388
+ armBrush: (brushClass) => this.ngZone.run(() => {
389
+ this.brushClass = { label: brushClass?.label, color: brushClass?.color };
390
+ if (this.activeDragMode === 'brush') {
391
+ this.plotService.setBrushOptions({ size: this.brushSize, ...this.brushClass });
392
+ }
393
+ else {
394
+ this.applyDragMode('brush');
395
+ }
396
+ this.cdr.markForCheck();
397
+ }),
398
+ disarm: () => this.ngZone.run(() => {
399
+ this.brushClass = null;
400
+ if (this.activeDragMode !== null)
401
+ this.applyDragMode(null);
402
+ this.cdr.markForCheck();
403
+ }),
404
+ activeTool$: this.session.getActiveTool$(),
405
+ };
406
+ this.plotModes = new PlotModeController(plotTypeContributions, {
407
+ onActivated: (active) => this.showPlotModePanel(active),
408
+ onDeactivating: () => this.hidePlotModePanel(),
409
+ onFailed: (contribution) => this.fallBackFromPlotMode(contribution),
410
+ });
320
411
  this.contributedTools = visibleToolContributions(toolContributions);
412
+ this.dialogTools = dialogToolContributions(toolContributions);
413
+ // A dialog tool's session is run by the plot-mode lifecycle, adapted: its "base
414
+ // type" is the Image view it draws over. Its body is NOT a controller panel: the
415
+ // controller would mount into a detached host, and a body must be able to measure
416
+ // itself. The dialog is rendered first and the body mounted once its host is in the
417
+ // document (showToolDialog).
418
+ this.toolDialogs = new PlotModeController(this.dialogTools.map((t) => ({
419
+ descriptor: { type: t.id, label: t.label, dimensions: '2d', baseType: PlotType.IMAGE },
420
+ activate: (ctx) => t.activate(ctx),
421
+ })), {
422
+ onActivated: (active) => this.showToolDialog(active),
423
+ onDeactivating: () => this.hideToolDialog(),
424
+ onFailed: (contribution) => this.dialogToolFailed(contribution.descriptor.type),
425
+ });
321
426
  this.colormapsOptions = plotService.getColormapOptions();
322
427
  this.computePlotTypeOptions();
323
428
  }
@@ -407,7 +512,7 @@ export class VisualizerComponent {
407
512
  // with an image-less 2D dataset, which is why it went unhandled — before
408
513
  // it, image-less meant 3D.
409
514
  const target = has3d ? PlotType.SPATIAL_OMICS_3D : PlotType.SPATIAL_OMICS;
410
- if (this.selectedPlotType !== target)
515
+ if (this.selectedPlotTypeId !== target)
411
516
  this.onSelectPlotType(target);
412
517
  }
413
518
  }
@@ -455,7 +560,7 @@ export class VisualizerComponent {
455
560
  }
456
561
  // Pick the mode first so the image lands in the view that will show it,
457
562
  // instead of rendering once into whatever mode the last dataset left active.
458
- if (this.selectedPlotType !== PlotType.IMAGE)
563
+ if (this.selectedPlotTypeId !== PlotType.IMAGE)
459
564
  this.onSelectPlotType(PlotType.IMAGE);
460
565
  this.revokeVolumeImageUrls();
461
566
  this.volumeImageUrls = built.urls;
@@ -466,7 +571,7 @@ export class VisualizerComponent {
466
571
  // it rather than leaving the host on an Image view with nothing in it.
467
572
  console.warn('[visualizer] reference volume unavailable — falling back to the 3D cloud', err);
468
573
  this.volumeImageKey = null;
469
- if (this.hasSpatial3dDataset && !isSpatialOmics3d(this.selectedPlotType)) {
574
+ if (this.hasSpatial3dDataset && !isSpatialOmics3d(this.basePlotType)) {
470
575
  this.onSelectPlotType(PlotType.SPATIAL_OMICS_3D);
471
576
  }
472
577
  }
@@ -495,12 +600,7 @@ export class VisualizerComponent {
495
600
  // though the RGB composite isn't grayscale — don't gate them out.
496
601
  const m0 = this.imageInfo?.imageMeta?.[0];
497
602
  const isMultichannel = (m0?.channelCount ?? 1) > 1 && (m0?.rgbChannels ?? 1) < 3;
498
- this.plotTypeOptions = this.plotService.getPlotTypeDescriptors()
499
- .filter((d) => {
500
- // Outside test mode, only the curated set (those with a productionLabel)
501
- // is offered; test mode exposes every backend's type.
502
- if (!this.testMode && !d.productionLabel)
503
- return false;
603
+ const passesGates = (d) => {
504
604
  if (d.dimensions === '3d' && !caps.has(ViewerFeature.Surface3D))
505
605
  return false;
506
606
  // Volume and Isosurface raymarch the IMAGE STACK, and nothing else: these
@@ -528,10 +628,37 @@ export class VisualizerComponent {
528
628
  && !this.spatialDatasetHasPixels)
529
629
  return false;
530
630
  return true;
531
- })
532
- // Default selector shows the suffix-free productionLabel; test mode keeps
533
- // the full backend-suffixed label so same-named modes stay distinguishable.
534
- .map((d) => (this.testMode ? d : { ...d, label: d.productionLabel }));
631
+ };
632
+ // Outside test mode, only the curated set (those with a productionLabel)
633
+ // is offered; test mode exposes every backend's type.
634
+ const curated = (d) => this.testMode || !!d.productionLabel;
635
+ const builtIn = this.plotService.getPlotTypeDescriptors()
636
+ .filter((d) => curated(d) && passesGates(d));
637
+ // Contributed modes come after every built-in one, under the same label rule
638
+ // and their own stack/grayscale/spatial gates. A mode also needs whatever its base
639
+ // view needs (pixels, a 3D-capable backend), so the base type's gates apply
640
+ // too — a contributed Image-based mode goes wherever Image goes.
641
+ const contributed = [];
642
+ for (const d of this.plotModes.descriptors()) {
643
+ if (!curated(d))
644
+ continue;
645
+ if (d.requiresStack && !isStack)
646
+ continue;
647
+ if (d.requiresGrayscale && !isGrayscale && !isMultichannel)
648
+ continue;
649
+ if (d.requiresSpatialData && !this.hasSpatialDataset)
650
+ continue;
651
+ if (d.requiresSpatial3d && !this.hasSpatial3dDataset)
652
+ continue;
653
+ const base = getPlotTypeDescriptor(d.baseType);
654
+ if (base && passesGates(base))
655
+ contributed.push(contributedPlotTypeOption(d, base));
656
+ }
657
+ // Default selector shows the suffix-free productionLabel; test mode keeps
658
+ // the full backend-suffixed label so same-named modes stay distinguishable.
659
+ const labelled = (d) => (this.testMode ? d : { ...d, label: d.productionLabel });
660
+ this.plotTypeOptions = builtIn.map(labelled);
661
+ this.plotTypeMenu = [...this.plotTypeOptions, ...contributed.map(labelled)];
535
662
  }
536
663
  ngOnChanges(changes) {
537
664
  // The constructor computes the options with testMode still at its default;
@@ -552,6 +679,10 @@ export class VisualizerComponent {
552
679
  * `isStack`/`isGrayscale` decision is made against a file that is no longer loaded.
553
680
  */
554
681
  onImageCleared() {
682
+ // The image a contributed mode was drawing over is gone. An open dialog
683
+ // tool stays open and restarts once the next image has plotted.
684
+ this.plotModes.deactivate();
685
+ this.toolDialogs.deactivate();
555
686
  this.imageInfo = undefined;
556
687
  this.loadedFileName = undefined;
557
688
  this.computePlotTypeOptions();
@@ -567,20 +698,26 @@ export class VisualizerComponent {
567
698
  this.cdr.detectChanges();
568
699
  }
569
700
  reconcileSelectedPlotType() {
570
- if (this.plotTypeOptions.some((d) => d.type === this.selectedPlotType))
701
+ if (this.plotTypeMenu.some((d) => d.type === this.selectedPlotTypeId))
571
702
  return;
572
703
  // Image is the usual fallback, but it is not always ON OFFER: with no image loaded
573
704
  // the pixel modes are gone, and falling back to one would select a mode the selector
574
705
  // does not list and nothing can draw. Take the first type still offered instead.
575
- const fallback = this.plotTypeOptions.some((d) => d.type === PlotType.IMAGE)
706
+ const fallback = this.plotTypeMenu.some((d) => d.type === PlotType.IMAGE)
576
707
  ? PlotType.IMAGE
577
- : this.plotTypeOptions[0]?.type;
708
+ : this.plotTypeMenu[0]?.type;
578
709
  if (!fallback)
579
710
  return;
580
- this.selectedPlotType = fallback;
581
- this.plotType = fallback;
582
- this.isHeatmap = fallback === PlotType.IMAGE;
583
- this.plotService.setPlotType(fallback);
711
+ // Leaving a contributed mode (its gates stopped passing, or its provider is
712
+ // gone): its session ends before anything else draws.
713
+ this.plotModes.deactivate();
714
+ const base = this.plotModes.baseTypeOf(fallback);
715
+ if (base !== PlotType.IMAGE)
716
+ this.closeDialogTool();
717
+ this.selectedPlotTypeId = fallback;
718
+ this.plotType = base;
719
+ this.isHeatmap = base === PlotType.IMAGE;
720
+ this.plotService.setPlotType(base);
584
721
  }
585
722
  ngOnInit() {
586
723
  // Join the live set; the oldest member renders the shared notice outlets.
@@ -734,7 +871,7 @@ export class VisualizerComponent {
734
871
  if (!this.isHeatmap && imgInfo.fileName !== this.loadedFileName) {
735
872
  this.isHeatmap = true;
736
873
  this.plotType = PlotType.IMAGE;
737
- this.selectedPlotType = PlotType.IMAGE;
874
+ this.selectedPlotTypeId = PlotType.IMAGE;
738
875
  this.plotService.setPlotType(this.plotType);
739
876
  this.activeSurface3dMode = 'turntable';
740
877
  }
@@ -762,6 +899,12 @@ export class VisualizerComponent {
762
899
  // image size — measure the plot div directly so the toolbar height is excluded
763
900
  const plotDiv = document.getElementById(this.plotDivName);
764
901
  const screenHeight = plotDiv?.offsetHeight || 500;
902
+ // A contributed mode's session is bound to the base view about to be
903
+ // torn down, so it ends here — before reset(), before anything new
904
+ // draws. If the mode is still selected once this render lands, a
905
+ // fresh session starts for it (see activateSelectedPlotMode).
906
+ this.plotModes.deactivate();
907
+ this.toolDialogs.deactivate();
765
908
  this.plotService.reset();
766
909
  this.stackLoading = imgInfo.isStack && imgInfo.showStack;
767
910
  // set max index of stack — computed before updateZIndex so a
@@ -915,6 +1058,8 @@ export class VisualizerComponent {
915
1058
  releaseOverlay();
916
1059
  this.running = false;
917
1060
  applyRoi();
1061
+ this.activateSelectedPlotMode();
1062
+ this.activateOpenDialogTool();
918
1063
  console.log(logTag);
919
1064
  },
920
1065
  sharpenFailed: (err) => {
@@ -931,6 +1076,8 @@ export class VisualizerComponent {
931
1076
  });
932
1077
  this.running = false;
933
1078
  applyRoi();
1079
+ this.activateSelectedPlotMode();
1080
+ this.activateOpenDialogTool();
934
1081
  },
935
1082
  }).render(imgInfo, smallImgInfo);
936
1083
  }
@@ -1040,7 +1187,7 @@ export class VisualizerComponent {
1040
1187
  // Intercepting here fires a FIXED zoom step per wheel event, which is far
1041
1188
  // too sensitive for a renderer that reads the scroll delta — so anything
1042
1189
  // drawn by such a renderer keeps its own wheel. See `rendererOwnsWheel`.
1043
- if (rendererOwnsWheel(this.selectedPlotType))
1190
+ if (rendererOwnsWheel(this.basePlotType))
1044
1191
  return;
1045
1192
  // 3D plot types (surface, scatter3d, isosurface) render in a Plotly scene
1046
1193
  // that orbits/zooms natively on scroll. The 2D step-zoom doesn't apply and
@@ -1159,6 +1306,11 @@ export class VisualizerComponent {
1159
1306
  }
1160
1307
  }
1161
1308
  ngOnDestroy() {
1309
+ // A contributed mode's session ends first, while the viewer it drew over
1310
+ // still exists. The panel goes with this view, so no change detection.
1311
+ this.destroying = true;
1312
+ this.plotModes.deactivate();
1313
+ this.toolDialogs.deactivate();
1162
1314
  // Leave the live set so the next-oldest visualizer picks up the outlets.
1163
1315
  VisualizerComponent.liveInstances.delete(this);
1164
1316
  this.revokeVolumeImageUrls();
@@ -1282,7 +1434,7 @@ export class VisualizerComponent {
1282
1434
  if (!this.isHeatmap) {
1283
1435
  this.isHeatmap = true;
1284
1436
  this.plotType = PlotType.HEATMAP;
1285
- this.selectedPlotType = PlotType.HEATMAP;
1437
+ this.selectedPlotTypeId = PlotType.HEATMAP;
1286
1438
  this.plotService.setPlotType(this.plotType);
1287
1439
  }
1288
1440
  this.plotService.setShowStack(showstack);
@@ -1398,8 +1550,15 @@ export class VisualizerComponent {
1398
1550
  this.plotService.resetAxes();
1399
1551
  }
1400
1552
  toggleDragMode(mode) {
1553
+ // A tool picked by the user is always the plain tool, never a plot mode's
1554
+ // brush class.
1555
+ this.brushClass = null;
1401
1556
  // Toggle off if the same mode is re-selected.
1402
- this.activeDragMode = this.activeDragMode === mode ? null : mode;
1557
+ this.applyDragMode(this.activeDragMode === mode ? null : mode);
1558
+ }
1559
+ /** Arm `mode` (or nothing) across every tool, keeping the toolbar in step. */
1560
+ applyDragMode(mode) {
1561
+ this.activeDragMode = mode;
1403
1562
  const active = this.activeDragMode;
1404
1563
  // Record the armed tool in the shared session store.
1405
1564
  this.session.setActiveTool(active);
@@ -1416,7 +1575,7 @@ export class VisualizerComponent {
1416
1575
  // On-canvas tool overlays.
1417
1576
  this.plotService.setZoomToBoxMode(active === 'zoomToBox');
1418
1577
  this.plotService.setWandMode(active === 'wand', { sensitivity: this.wandSensitivity });
1419
- this.plotService.setBrushMode(active === 'brush', { size: this.brushSize });
1578
+ this.plotService.setBrushMode(active === 'brush', { size: this.brushSize, ...this.brushClass });
1420
1579
  this.plotService.setSamPointMode(active === 'samPoint');
1421
1580
  // Leaving point mode dismisses any lingering status toast.
1422
1581
  if (active !== 'samPoint')
@@ -1815,7 +1974,7 @@ export class VisualizerComponent {
1815
1974
  }
1816
1975
  // Bézier conversions are vertex-level edits — Image (OpenSeadragon) view
1817
1976
  // only — gated on the selection's current form.
1818
- if (this.selectedPlotType === PlotType.IMAGE) {
1977
+ if (this.basePlotType === PlotType.IMAGE) {
1819
1978
  const hasStraight = selAll.some((r) => (r.bounds instanceof Polygon && !r.bounds.bezier) || r.bounds instanceof Rectangle);
1820
1979
  const hasBezier = selAll.some((r) => r.bounds instanceof Polygon && r.bounds.bezier);
1821
1980
  if (hasStraight) {
@@ -1929,7 +2088,7 @@ export class VisualizerComponent {
1929
2088
  // Vertex editing runs on the OpenSeadragon overlay, which
1930
2089
  // backs the Image plot type. Hidden for other 2D types (Plotly), where
1931
2090
  // these modes are no-ops.
1932
- if (this.selectedPlotType === PlotType.IMAGE) {
2091
+ if (this.basePlotType === PlotType.IMAGE) {
1933
2092
  items.push({
1934
2093
  label: 'Polygon (click vertices)',
1935
2094
  icon: 'polygon-vertices-icon',
@@ -1985,10 +2144,34 @@ export class VisualizerComponent {
1985
2144
  * the toolbar/context-menu logic relies on, deactivates 2D-only tools when
1986
2145
  * moving to a 3D type, then re-plots.
1987
2146
  */
1988
- onSelectPlotType(type) {
2147
+ onSelectPlotType(selected) {
2148
+ // A contributed id whose provider is gone (e.g. restored from a previous
2149
+ // session) has nothing to activate — take the default Image view instead.
2150
+ if (!isBuiltinPlotType(selected) && !this.plotModes.find(selected)) {
2151
+ console.warn(`[visualizer] unknown plot type '${selected}' — showing '${PlotType.IMAGE}' instead.`);
2152
+ selected = PlotType.IMAGE;
2153
+ }
2154
+ // An explicit choice retries a mode whose earlier cleanup failed; only
2155
+ // automatic re-activations (re-render, image switch) fall back for that.
2156
+ this.plotModes.clearCleanupFailures();
2157
+ // Whatever was selected before, a contributed session ends before the next
2158
+ // mode draws. (Re-selecting the same contributed mode re-plots, so it gets a
2159
+ // fresh session too.)
2160
+ this.plotModes.deactivate();
2161
+ // Everything below decides how to RENDER, so it works on the built-in type
2162
+ // that draws `selected`: a contributed mode behaves exactly like its base.
2163
+ const type = this.plotModes.baseTypeOf(selected);
2164
+ // A dialog tool draws over the Image view: leaving it closes the dialog. Staying
2165
+ // on it, the session ends here and restarts once the re-plot lands.
2166
+ if (type === PlotType.IMAGE)
2167
+ this.toolDialogs.deactivate();
2168
+ else
2169
+ this.closeDialogTool();
1989
2170
  this.plotType = type;
1990
- this.selectedPlotType = type;
1991
- const descriptor = this.plotTypeOptions.find((d) => d.type === type);
2171
+ this.selectedPlotTypeId = selected;
2172
+ const descriptor = isBuiltinPlotType(selected)
2173
+ ? this.plotTypeMenu.find((d) => d.type === type)
2174
+ : getPlotTypeDescriptor(type);
1992
2175
  const is3d = descriptor?.dimensions === '3d';
1993
2176
  this.isHeatmap = !is3d;
1994
2177
  this.plotService.setPlotType(type);
@@ -2023,8 +2206,248 @@ export class VisualizerComponent {
2023
2206
  }
2024
2207
  this.reloadAndPlot();
2025
2208
  }
2209
+ // ── contributed plot modes ─────────────────────────────────────────────
2210
+ /**
2211
+ * Start the selected contributed mode's session, once its base view has
2212
+ * plotted. No-op for a built-in type, or when the base on screen is not the
2213
+ * one the mode rides on. A backend that cannot provide a viewport for it
2214
+ * (e.g. OSD fell back to Plotly) counts as a failed activation.
2215
+ */
2216
+ activateSelectedPlotMode() {
2217
+ const contribution = this.plotModes.find(this.selectedPlotTypeId);
2218
+ if (!contribution || this.plotType !== contribution.descriptor.baseType)
2219
+ return;
2220
+ const viewport = this.plotService.getPlotModeViewport?.() ?? null;
2221
+ if (!viewport) {
2222
+ console.error(`[visualizer] plot-type contribution '${contribution.descriptor.type}': the backend `
2223
+ + 'on screen provides no viewport to draw over — falling back.');
2224
+ this.fallBackFromPlotMode(contribution);
2225
+ return;
2226
+ }
2227
+ const ctx = {
2228
+ visualizer: this.plotService,
2229
+ viewport,
2230
+ imageInfo$: this.state.getImageInfo$(),
2231
+ tools: this.plotModeTools,
2232
+ };
2233
+ void this.plotModes.activate(contribution, ctx);
2234
+ }
2235
+ /** Render the live mode's panel. Activation can resolve outside Angular (an
2236
+ * OSD callback, a contribution's own promise), hence the zone re-entry. */
2237
+ showPlotModePanel(active) {
2238
+ const panel = active.contribution.panel;
2239
+ if (!panel)
2240
+ return;
2241
+ this.ngZone.run(() => {
2242
+ if ('component' in panel && panel.component) {
2243
+ this.plotModePanel = {
2244
+ title: panel.title,
2245
+ component: panel.component,
2246
+ injector: Injector.create({
2247
+ providers: [
2248
+ { provide: PLOT_MODE_CONTEXT, useValue: active.ctx },
2249
+ { provide: PLOT_MODE_SESSION, useValue: active.session },
2250
+ ],
2251
+ parent: this.injector,
2252
+ }),
2253
+ host: null,
2254
+ };
2255
+ }
2256
+ else if (active.panelHost) {
2257
+ this.plotModePanel = { title: panel.title, component: null, injector: null, host: active.panelHost };
2258
+ }
2259
+ else {
2260
+ return;
2261
+ }
2262
+ // A component panel is created and first rendered right here; if that throws,
2263
+ // the mode is not usable — end it and fall back rather than leave it selected.
2264
+ const err = this.detectChangesSafely();
2265
+ if (err !== null)
2266
+ this.plotModes.failActive(err);
2267
+ });
2268
+ }
2269
+ /** Drop the panel (destroying a component panel) before the session ends. */
2270
+ hidePlotModePanel() {
2271
+ if (!this.plotModePanel)
2272
+ return;
2273
+ this.plotModePanel = null;
2274
+ this.detectChangesSafely();
2275
+ }
2276
+ /**
2277
+ * A contributed mode could not start. Its base type is already on screen —
2278
+ * the base plotted first — so just select it: nothing needs to re-plot.
2279
+ */
2280
+ fallBackFromPlotMode(contribution) {
2281
+ if (this.destroying || this.selectedPlotTypeId !== contribution.descriptor.type)
2282
+ return;
2283
+ this.ngZone.run(() => {
2284
+ const base = contribution.descriptor.baseType;
2285
+ this.selectedPlotTypeId = base;
2286
+ this.plotType = base;
2287
+ this.messageService.add({
2288
+ key: this.resultToastKey,
2289
+ severity: 'warn',
2290
+ summary: `${contribution.descriptor.productionLabel ?? contribution.descriptor.label} is unavailable`,
2291
+ detail: 'The plot mode could not start, so the plain image is shown instead. See the browser console for details.',
2292
+ });
2293
+ this.detectChangesSafely();
2294
+ });
2295
+ }
2296
+ /** Run change detection; returns what it threw (logged), or null. */
2297
+ detectChangesSafely() {
2298
+ if (this.destroying)
2299
+ return null;
2300
+ try {
2301
+ this.cdr.detectChanges();
2302
+ return null;
2303
+ }
2304
+ catch (err) {
2305
+ console.error('[visualizer] change detection failed while updating a contributed plot mode panel.', err);
2306
+ return err ?? new Error('change detection failed');
2307
+ }
2308
+ }
2309
+ // ── dialog tools (TOOLBAR_TOOLS, kind: 'dialog') ─────────────────────────
2310
+ /** The toolbar button: open the tool's dialog, or close it if it is open. */
2311
+ toggleDialogTool(id) {
2312
+ if (this.openDialogToolId === id) {
2313
+ this.closeDialogTool();
2314
+ return;
2315
+ }
2316
+ this.closeDialogTool();
2317
+ if (!this.dialogTools.some((t) => t.id === id))
2318
+ return;
2319
+ this.openDialogToolId = id;
2320
+ this.toolDialogs.clearCleanupFailures(); // an explicit open gets a fresh attempt
2321
+ this.activateOpenDialogTool();
2322
+ }
2323
+ /** Close the open dialog tool: its body is torn down, then its session ends. */
2324
+ closeDialogTool() {
2325
+ this.openDialogToolId = null;
2326
+ this.toolDialogs.deactivate();
2327
+ }
2328
+ /** Start (or restart, after a re-render) the open dialog tool's session. */
2329
+ activateOpenDialogTool() {
2330
+ const id = this.openDialogToolId;
2331
+ const contribution = id ? this.toolDialogs.find(id) : undefined;
2332
+ if (!contribution || this.plotType !== PlotType.IMAGE)
2333
+ return;
2334
+ if (this.toolDialogs.current?.contribution === contribution || this.toolDialogs.pending)
2335
+ return;
2336
+ const viewport = this.plotService.getPlotModeViewport?.() ?? null;
2337
+ if (!viewport) {
2338
+ console.error(`[visualizer] dialog tool '${id}': the backend on screen provides no viewport to draw over.`);
2339
+ this.dialogToolFailed(id);
2340
+ return;
2341
+ }
2342
+ const ctx = {
2343
+ visualizer: this.plotService,
2344
+ viewport,
2345
+ imageInfo$: this.state.getImageInfo$(),
2346
+ tools: this.plotModeTools,
2347
+ };
2348
+ void this.toolDialogs.activate(contribution, ctx);
2349
+ }
2350
+ /**
2351
+ * The session is live: render the dialog, then mount the tool's body once the host
2352
+ * element is in the document, so `mount()` can measure it and start widgets that need
2353
+ * a connected element.
2354
+ */
2355
+ showToolDialog(active) {
2356
+ const tool = this.dialogTools.find((t) => t.id === active.contribution.descriptor.type);
2357
+ if (!tool)
2358
+ return;
2359
+ const host = document.createElement('div');
2360
+ host.className = 'tool-dialog-body';
2361
+ this.ngZone.run(() => {
2362
+ this.toolDialog = {
2363
+ title: tool.dialog?.title ?? tool.label,
2364
+ width: tool.dialog?.width ?? '22rem',
2365
+ host,
2366
+ };
2367
+ const err = this.detectChangesSafely();
2368
+ if (err !== null) {
2369
+ this.toolDialogs.failActive(err);
2370
+ return;
2371
+ }
2372
+ this.mountToolDialogBody(tool, active, host, 0);
2373
+ });
2374
+ }
2375
+ /** How many animation frames to wait for the dialog to attach the body's host. */
2376
+ static { this.TOOL_DIALOG_ATTACH_FRAMES = 60; }
2377
+ /**
2378
+ * Mount `tool`'s body into `host` once it is connected (the dialog may attach it a
2379
+ * frame later, when it moves itself to `<body>`). If it never connects within
2380
+ * {@link TOOL_DIALOG_ATTACH_FRAMES} it is mounted anyway, with a warning, rather than
2381
+ * leaving an empty dialog. A throwing `mount()` fails the session like a failed start.
2382
+ */
2383
+ mountToolDialogBody(tool, active, host, frames) {
2384
+ this.toolDialogFrame = null;
2385
+ // The session ended (or was replaced) while waiting: nothing to mount into.
2386
+ if (this.toolDialogs.current !== active || this.toolDialog?.host !== host)
2387
+ return;
2388
+ if (!host.isConnected) {
2389
+ if (frames < VisualizerComponent.TOOL_DIALOG_ATTACH_FRAMES) {
2390
+ this.toolDialogFrame = requestAnimationFrame(() => this.mountToolDialogBody(tool, active, host, frames + 1));
2391
+ return;
2392
+ }
2393
+ console.warn(`[visualizer] dialog tool '${tool.id}': the dialog body never attached; mounting it detached.`);
2394
+ }
2395
+ try {
2396
+ const teardown = tool.mount(host, active.ctx, active.session);
2397
+ this.toolDialogTeardown = typeof teardown === 'function' ? teardown : null;
2398
+ }
2399
+ catch (err) {
2400
+ console.error(`[visualizer] dialog tool '${tool.id}' mount() threw.`, err);
2401
+ this.toolDialogs.failActive(err);
2402
+ }
2403
+ }
2404
+ /** The session is about to end: tear the body down first, then drop the dialog. */
2405
+ hideToolDialog() {
2406
+ if (this.toolDialogFrame !== null)
2407
+ cancelAnimationFrame(this.toolDialogFrame);
2408
+ this.toolDialogFrame = null;
2409
+ const teardown = this.toolDialogTeardown;
2410
+ this.toolDialogTeardown = null;
2411
+ if (teardown) {
2412
+ try {
2413
+ teardown();
2414
+ }
2415
+ catch (err) {
2416
+ console.error('[visualizer] dialog tool body teardown threw.', err);
2417
+ }
2418
+ }
2419
+ if (!this.toolDialog)
2420
+ return;
2421
+ this.toolDialog.host.remove();
2422
+ this.toolDialog = null;
2423
+ if (!this.destroying)
2424
+ this.detectChangesSafely();
2425
+ }
2426
+ /** A dialog tool could not start: close it and say so. */
2427
+ dialogToolFailed(id) {
2428
+ if (this.destroying || this.openDialogToolId !== id)
2429
+ return;
2430
+ this.ngZone.run(() => {
2431
+ this.openDialogToolId = null;
2432
+ const tool = this.dialogTools.find((t) => t.id === id);
2433
+ this.messageService.add({
2434
+ key: this.resultToastKey,
2435
+ severity: 'warn',
2436
+ summary: `${tool?.label ?? id} is unavailable`,
2437
+ detail: 'The tool could not start. See the browser console for details.',
2438
+ });
2439
+ this.detectChangesSafely();
2440
+ });
2441
+ }
2442
+ /** Where the open dialog tool's host element is attached once its dialog renders. */
2443
+ set toolDialogSlot(ref) {
2444
+ const host = this.toolDialog?.host;
2445
+ if (ref && host && host.parentElement !== ref.nativeElement)
2446
+ ref.nativeElement.appendChild(host);
2447
+ }
2026
2448
  /** Deactivate whatever tool is armed and clear every tool mode. */
2027
2449
  deactivateActiveTool() {
2450
+ this.brushClass = null;
2028
2451
  this.activeDragMode = null;
2029
2452
  this.session.setActiveTool(null);
2030
2453
  this.plotService.getRegionOverlay()?.setMode('none');
@@ -2035,12 +2458,12 @@ export class VisualizerComponent {
2035
2458
  this.plotService.setSamPointMode(false);
2036
2459
  this.plotService.setVertexEraserMode(false);
2037
2460
  }
2038
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: VisualizerComponent, deps: [{ token: IMAGE_STATE_PORT }, { token: VISUALIZER }, { token: i1.MessageService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i2.VisualizerStore }, { token: i3.SamToolService }, { token: i4.CellSegmentToolService }, { token: i5.SamPointToolService }, { token: i6.RegionOpsService }, { token: VIZ_CONFIG, optional: true }, { token: TOOLBAR_TOOLS, optional: true }, { token: SPATIAL_DATA_PORT, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
2039
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: VisualizerComponent, selector: "visualizer", inputs: { toolbarTools: "toolbarTools", testMode: "testMode" }, outputs: { isStackEvent: "isStackEvent", isGrayscaleEvent: "isGrayscaleEvent" }, host: { listeners: { "window:keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["cm"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ samStatus || message.detail }}</div>\n <p-progressBar *ngIf=\"samDownloading\" [value]=\"samProgress\" styleClass=\"mt-2 sam-progress\"></p-progressBar>\n <p-progressBar *ngIf=\"samBusy && !samDownloading\" mode=\"indeterminate\" styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div class=\"toolbar-dock\" [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\">\n <div class=\"toolbar-drag-handle\" (mousedown)=\"onToolbarDragStart($event)\"\n pTooltip=\"Drag to float the toolbar\" tooltipPosition=\"bottom\">\n <i class=\"pi pi-bars\"></i>\n </div>\n<plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [plotTypeOptions]=\"plotTypeOptions\"\n [selectedPlotType]=\"selectedPlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [toolModelIds]=\"toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndoRegion\"\n [canRedo]=\"canRedoRegion\"\n [stackOptions]=\"stackOptions\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\">\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n</plotting-toolbar>\n <p-button *ngIf=\"toolbarFloating\" class=\"toolbar-dock-btn\" icon=\"pi pi-thumbtack\" size=\"small\" [text]=\"true\"\n pTooltip=\"Dock to top\" tooltipPosition=\"bottom\" (onClick)=\"dockToolbar()\">\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading || stackLoading || isCaching\" id=\"overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading; else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching; else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress\"></p-progressBar>\n <span class=\"text-loading\">{{loadingMessage}}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading && !zoom\" class=\"text-loading\">{{loadingMessage}}</span>\n <span *ngIf=\"imgLoading && zoom\" class=\"zoom-text-loading\">{{loadingMessage}}</span>\n </ng-template>\n </ng-template>\n <p-button *ngIf=\"stackLoading || imgLoading\" class=\"cancel-loading \" label=\"Cancel\"\n (onClick)=\"cancelLoading()\">\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"sharpening && !imgLoading && !stackLoading && !isCaching\" id=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n\n</div>\n\n<!-- Floating, draggable intensity-profile inset. Shown in LINE mode; the chart\n updates live as the line ROI on the image is moved. Kept OUTSIDE #plot and\n positioned fixed so it floats over the whole page (not clipped to the\n diagram/canvas area). -->\n<div *ngIf=\"hasProfiles\" class=\"intensity-panel\"\n [style.left.px]=\"profilePanelPos.x\" [style.top.px]=\"profilePanelPos.y\">\n <div class=\"intensity-panel-header\" (mousedown)=\"onProfilePanelDragStart($event)\">\n <span>Intensity profile</span>\n <i class=\"pi pi-arrows-alt\"></i>\n </div>\n <div [id]=\"intensityInsetDiv\" class=\"intensity-panel-plot\"></div>\n</div>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\" ></spatial-controls>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog header=\"Region Editor\" [(visible)]=\"showRegionEditor\"\n [modal]=\"false\" [resizable]=\"true\" [draggable]=\"true\"\n [maximizable]=\"true\" appendTo=\"body\" position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <region-editor></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog header=\"Simplify region(s)\" [(visible)]=\"displaySimplifyDialog\" [modal]=\"true\"\n [style]=\"{width: '22rem'}\" [draggable]=\"false\" [resizable]=\"false\">\n <div class=\"flex flex-column gap-2\">\n <span>Altitude threshold: <b>{{ simplifyThreshold }} px</b></span>\n <p-slider [(ngModel)]=\"simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button label=\"Apply\" icon=\"pi pi-check\" (onClick)=\"simplifyRegions(simplifyThreshold)\"></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog *ngIf=\"openParamsTool as tool\"\n [header]=\"tool.label + ' parameters'\"\n [visible]=\"true\" (visibleChange)=\"openParamsToolId = null\"\n [modal]=\"true\"\n [style]=\"{width: '30rem'}\" [draggable]=\"false\" [resizable]=\"false\" appendTo=\"body\">\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let p of tool.params\">\n <div class=\"field\" [ngClass]=\"p.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container [ngSwitch]=\"p.type\">\n\n <ng-container *ngSwitchCase=\"'number'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-inputNumber [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [min]=\"numberParam(p).min\" [max]=\"numberParam(p).max\"\n [step]=\"numberParam(p).step\"\n [minFractionDigits]=\"numberParam(p).fractionDigits\"\n [showButtons]=\"true\"></p-inputNumber>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'select'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-dropdown [options]=\"selectParam(p).options\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n appendTo=\"body\"></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngSwitchCase=\"'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [binary]=\"true\" [inputId]=\"tool.id + '-' + p.id\"></p-checkbox>\n <label [for]=\"tool.id + '-' + p.id\" class=\"text-sm mb-0\"\n [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n </div>\n\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Reset to model defaults\" [text]=\"true\" size=\"small\"\n (onClick)=\"resetToolParams(tool.id)\"></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"openParamsToolId = null\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-plot{flex:1;min-height:0;height:auto!important}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}#overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}#sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}#sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}#sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.intensity-panel{position:fixed;z-index:1100;width:280px;height:180px;background:#191919e6;border:1px solid var(--primary-color, #3399ff);border-radius:6px;box-shadow:0 4px 14px #00000073;display:flex;flex-direction:column;overflow:hidden}.intensity-panel-header{display:flex;align-items:center;justify-content:space-between;padding:.25rem .5rem;cursor:move;-webkit-user-select:none;user-select:none;background:#ffffff14;color:#eee;font-size:.75rem;font-weight:600}.intensity-panel-header i{opacity:.6;font-size:.7rem}.intensity-panel-plot{flex:1 1 auto;width:100%}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i7.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i9.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i11.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i12.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "component", type: i13.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: i14.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i15.ContextMenu, selector: "p-contextMenu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "id", "ariaLabel", "ariaLabelledBy", "pressDelay"], outputs: ["onShow", "onHide"] }, { kind: "component", type: i16.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i17.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "component", type: i18.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i19.ToolbarComponent, selector: "plotting-toolbar", inputs: ["imageInfo", "plotTypeOptions", "selectedPlotType", "isoRange", "maxIndex", "zIndex", "isHeatmap", "is3dRegions", "activeDragMode", "activeSurface3dMode", "axesVisible", "wireframeActive", "resolutionScale", "wandSensitivity", "brushSize", "vertexEraserRadius", "canUndo", "canRedo", "stackOptions", "tools", "imageSmoothingEnabled", "samModels", "samModelId", "contributedTools", "toolModelIds"], outputs: ["selectPlotType", "addProfileLine", "toggleImageSmoothing", "isoRangeChange", "openChannelHistogram", "openSpatialControls", "openRegionEditor", "selectStackOption", "zScrub", "zSlide", "zIndexInput", "reloadAndPlot", "downloadImage", "autoscaleImage", "toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution", "deleteRegion", "undoRegion", "redoRegion", "segmentRegions", "segmentCellpose", "runTool", "toolModelChange", "openToolParams", "samModelChange", "wandSensitivityChange", "brushSizeChange", "vertexEraserRadiusChange"] }, { kind: "component", type: i20.RegionEditorComponent, selector: "region-editor" }, { kind: "component", type: i21.ChannelHistogramComponent, selector: "channel-histogram", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "component", type: i22.SpatialControlsComponent, selector: "spatial-controls", inputs: ["visible", "is3d"], outputs: ["visibleChange"] }] }); }
2461
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: VisualizerComponent, deps: [{ token: IMAGE_STATE_PORT }, { token: VISUALIZER }, { token: i1.MessageService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i2.VisualizerStore }, { token: i3.SamToolService }, { token: i4.CellSegmentToolService }, { token: i5.SamPointToolService }, { token: i6.RegionOpsService }, { token: VIZ_CONFIG, optional: true }, { token: TOOLBAR_TOOLS, optional: true }, { token: SPATIAL_DATA_PORT, optional: true }, { token: PLOT_TYPE_CONTRIBUTIONS, optional: true }, { token: i0.Injector, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
2462
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: VisualizerComponent, selector: "visualizer", inputs: { toolbarTools: "toolbarTools", testMode: "testMode" }, outputs: { isStackEvent: "isStackEvent", isGrayscaleEvent: "isGrayscaleEvent" }, host: { listeners: { "window:keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["cm"], descendants: true }, { propertyName: "plotModePanelSlot", first: true, predicate: ["plotModePanelSlot"], descendants: true }, { propertyName: "toolDialogSlot", first: true, predicate: ["toolDialogSlot"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ samStatus || message.detail }}</div>\n <p-progressBar *ngIf=\"samDownloading\" [value]=\"samProgress\" styleClass=\"mt-2 sam-progress\"></p-progressBar>\n <p-progressBar *ngIf=\"samBusy && !samDownloading\" mode=\"indeterminate\" styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div class=\"toolbar-dock\" [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\">\n <div class=\"toolbar-drag-handle\" (mousedown)=\"onToolbarDragStart($event)\"\n pTooltip=\"Drag to float the toolbar\" tooltipPosition=\"bottom\">\n <i class=\"pi pi-bars\"></i>\n </div>\n<plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [plotTypeOptions]=\"plotTypeMenu\"\n [selectedPlotType]=\"selectedPlotTypeId\"\n [basePlotType]=\"basePlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n [openDialogToolId]=\"openDialogToolId\"\n (toggleDialogTool)=\"toggleDialogTool($event)\"\n [toolModelIds]=\"toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndoRegion\"\n [canRedo]=\"canRedoRegion\"\n [stackOptions]=\"stackOptions\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\">\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n</plotting-toolbar>\n <p-button *ngIf=\"toolbarFloating\" class=\"toolbar-dock-btn\" icon=\"pi pi-thumbtack\" size=\"small\" [text]=\"true\"\n pTooltip=\"Dock to top\" tooltipPosition=\"bottom\" (onClick)=\"dockToolbar()\">\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading || stackLoading || isCaching\" id=\"overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading; else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching; else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress\"></p-progressBar>\n <span class=\"text-loading\">{{loadingMessage}}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading && !zoom\" class=\"text-loading\">{{loadingMessage}}</span>\n <span *ngIf=\"imgLoading && zoom\" class=\"zoom-text-loading\">{{loadingMessage}}</span>\n </ng-template>\n </ng-template>\n <p-button *ngIf=\"stackLoading || imgLoading\" class=\"cancel-loading \" label=\"Cancel\"\n (onClick)=\"cancelLoading()\">\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"sharpening && !imgLoading && !stackLoading && !isCaching\" id=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n\n</div>\n\n<!-- Floating, draggable intensity-profile inset. Shown in LINE mode; the chart\n updates live as the line ROI on the image is moved. Kept OUTSIDE #plot and\n positioned fixed so it floats over the whole page (not clipped to the\n diagram/canvas area). -->\n<div *ngIf=\"hasProfiles\" class=\"intensity-panel\"\n [style.left.px]=\"profilePanelPos.x\" [style.top.px]=\"profilePanelPos.y\">\n <div class=\"intensity-panel-header\" (mousedown)=\"onProfilePanelDragStart($event)\">\n <span>Intensity profile</span>\n <i class=\"pi pi-arrows-alt\"></i>\n </div>\n <div [id]=\"intensityInsetDiv\" class=\"intensity-panel-plot\"></div>\n</div>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\" ></spatial-controls>\n\n<!-- Side panel of the active contributed plot mode (PLOT_TYPE_CONTRIBUTIONS),\n in the same right-hand area as the spatial controls and the Region Editor.\n Exists only while the mode's session is live; there is no close button,\n because leaving the mode is what ends it. A component panel gets\n PLOT_MODE_CONTEXT / PLOT_MODE_SESSION from its injector; a `mount` panel's\n host element is attached to the slot below (see plotModePanelSlot). -->\n<p-dialog *ngIf=\"plotModePanel as panel\" [header]=\"panel.title\" [visible]=\"true\"\n [modal]=\"false\" [closable]=\"false\" [resizable]=\"true\" [draggable]=\"true\"\n appendTo=\"body\" position=\"right\" styleClass=\"plot-mode-panel\"\n [style]=\"{ width: '22rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <ng-container *ngIf=\"panel.component\">\n <ng-container *ngComponentOutlet=\"panel.component; injector: panel.injector ?? undefined\"></ng-container>\n </ng-container>\n <div *ngIf=\"panel.host\" #plotModePanelSlot class=\"plot-mode-panel-slot\"></div>\n</p-dialog>\n\n<!-- An open dialog tool (TOOLBAR_TOOLS, kind: 'dialog'). Non-modal so the user can\n keep working on the image, e.g. painting with the brush the tool armed. The\n tool renders its body into a host element attached to the slot below (see\n toolDialogSlot); closing the dialog ends the tool's session. -->\n<p-dialog *ngIf=\"toolDialog as dlg\" [header]=\"dlg.title\" [visible]=\"true\"\n (visibleChange)=\"$event || closeDialogTool()\"\n [modal]=\"false\" [closable]=\"true\" [resizable]=\"true\" [draggable]=\"true\"\n appendTo=\"body\" position=\"right\" styleClass=\"tool-dialog\"\n [style]=\"{ width: dlg.width, maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <div #toolDialogSlot class=\"tool-dialog-slot\"></div>\n</p-dialog>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog header=\"Region Editor\" [(visible)]=\"showRegionEditor\"\n [modal]=\"false\" [resizable]=\"true\" [draggable]=\"true\"\n [maximizable]=\"true\" appendTo=\"body\" position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <region-editor></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog header=\"Simplify region(s)\" [(visible)]=\"displaySimplifyDialog\" [modal]=\"true\"\n [style]=\"{width: '22rem'}\" [draggable]=\"false\" [resizable]=\"false\">\n <div class=\"flex flex-column gap-2\">\n <span>Altitude threshold: <b>{{ simplifyThreshold }} px</b></span>\n <p-slider [(ngModel)]=\"simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button label=\"Apply\" icon=\"pi pi-check\" (onClick)=\"simplifyRegions(simplifyThreshold)\"></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog *ngIf=\"openParamsTool as tool\"\n [header]=\"tool.label + ' parameters'\"\n [visible]=\"true\" (visibleChange)=\"openParamsToolId = null\"\n [modal]=\"true\"\n [style]=\"{width: '30rem'}\" [draggable]=\"false\" [resizable]=\"false\" appendTo=\"body\">\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let p of tool.params\">\n <div class=\"field\" [ngClass]=\"p.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container [ngSwitch]=\"p.type\">\n\n <ng-container *ngSwitchCase=\"'number'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-inputNumber [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [min]=\"numberParam(p).min\" [max]=\"numberParam(p).max\"\n [step]=\"numberParam(p).step\"\n [minFractionDigits]=\"numberParam(p).fractionDigits\"\n [showButtons]=\"true\"></p-inputNumber>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'select'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-dropdown [options]=\"selectParam(p).options\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n appendTo=\"body\"></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngSwitchCase=\"'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [binary]=\"true\" [inputId]=\"tool.id + '-' + p.id\"></p-checkbox>\n <label [for]=\"tool.id + '-' + p.id\" class=\"text-sm mb-0\"\n [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n </div>\n\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Reset to model defaults\" [text]=\"true\" size=\"small\"\n (onClick)=\"resetToolParams(tool.id)\"></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"openParamsToolId = null\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-plot{flex:1;min-height:0;height:auto!important}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}#overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}#sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}#sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}#sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.intensity-panel{position:fixed;z-index:1100;width:280px;height:180px;background:#191919e6;border:1px solid var(--primary-color, #3399ff);border-radius:6px;box-shadow:0 4px 14px #00000073;display:flex;flex-direction:column;overflow:hidden}.intensity-panel-header{display:flex;align-items:center;justify-content:space-between;padding:.25rem .5rem;cursor:move;-webkit-user-select:none;user-select:none;background:#ffffff14;color:#eee;font-size:.75rem;font-weight:600}.intensity-panel-header i{opacity:.6;font-size:.7rem}.intensity-panel-plot{flex:1 1 auto;width:100%}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i7.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i9.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i11.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i12.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "component", type: i13.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: i14.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i15.ContextMenu, selector: "p-contextMenu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "id", "ariaLabel", "ariaLabelledBy", "pressDelay"], outputs: ["onShow", "onHide"] }, { kind: "component", type: i16.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i17.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "component", type: i18.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i19.ToolbarComponent, selector: "plotting-toolbar", inputs: ["imageInfo", "plotTypeOptions", "selectedPlotType", "basePlotType", "isoRange", "maxIndex", "zIndex", "isHeatmap", "is3dRegions", "activeDragMode", "activeSurface3dMode", "axesVisible", "wireframeActive", "resolutionScale", "wandSensitivity", "brushSize", "vertexEraserRadius", "canUndo", "canRedo", "stackOptions", "tools", "imageSmoothingEnabled", "samModels", "samModelId", "contributedTools", "dialogTools", "openDialogToolId", "toolModelIds"], outputs: ["selectPlotType", "addProfileLine", "toggleImageSmoothing", "isoRangeChange", "openChannelHistogram", "openSpatialControls", "openRegionEditor", "selectStackOption", "zScrub", "zSlide", "zIndexInput", "reloadAndPlot", "downloadImage", "autoscaleImage", "toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution", "deleteRegion", "undoRegion", "redoRegion", "segmentRegions", "segmentCellpose", "runTool", "toggleDialogTool", "toolModelChange", "openToolParams", "samModelChange", "wandSensitivityChange", "brushSizeChange", "vertexEraserRadiusChange"] }, { kind: "component", type: i20.RegionEditorComponent, selector: "region-editor" }, { kind: "component", type: i21.ChannelHistogramComponent, selector: "channel-histogram", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "component", type: i22.SpatialControlsComponent, selector: "spatial-controls", inputs: ["visible", "is3d"], outputs: ["visibleChange"] }] }); }
2040
2463
  }
2041
2464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: VisualizerComponent, decorators: [{
2042
2465
  type: Component,
2043
- args: [{ selector: 'visualizer', template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ samStatus || message.detail }}</div>\n <p-progressBar *ngIf=\"samDownloading\" [value]=\"samProgress\" styleClass=\"mt-2 sam-progress\"></p-progressBar>\n <p-progressBar *ngIf=\"samBusy && !samDownloading\" mode=\"indeterminate\" styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div class=\"toolbar-dock\" [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\">\n <div class=\"toolbar-drag-handle\" (mousedown)=\"onToolbarDragStart($event)\"\n pTooltip=\"Drag to float the toolbar\" tooltipPosition=\"bottom\">\n <i class=\"pi pi-bars\"></i>\n </div>\n<plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [plotTypeOptions]=\"plotTypeOptions\"\n [selectedPlotType]=\"selectedPlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [toolModelIds]=\"toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndoRegion\"\n [canRedo]=\"canRedoRegion\"\n [stackOptions]=\"stackOptions\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\">\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n</plotting-toolbar>\n <p-button *ngIf=\"toolbarFloating\" class=\"toolbar-dock-btn\" icon=\"pi pi-thumbtack\" size=\"small\" [text]=\"true\"\n pTooltip=\"Dock to top\" tooltipPosition=\"bottom\" (onClick)=\"dockToolbar()\">\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading || stackLoading || isCaching\" id=\"overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading; else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching; else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress\"></p-progressBar>\n <span class=\"text-loading\">{{loadingMessage}}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading && !zoom\" class=\"text-loading\">{{loadingMessage}}</span>\n <span *ngIf=\"imgLoading && zoom\" class=\"zoom-text-loading\">{{loadingMessage}}</span>\n </ng-template>\n </ng-template>\n <p-button *ngIf=\"stackLoading || imgLoading\" class=\"cancel-loading \" label=\"Cancel\"\n (onClick)=\"cancelLoading()\">\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"sharpening && !imgLoading && !stackLoading && !isCaching\" id=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n\n</div>\n\n<!-- Floating, draggable intensity-profile inset. Shown in LINE mode; the chart\n updates live as the line ROI on the image is moved. Kept OUTSIDE #plot and\n positioned fixed so it floats over the whole page (not clipped to the\n diagram/canvas area). -->\n<div *ngIf=\"hasProfiles\" class=\"intensity-panel\"\n [style.left.px]=\"profilePanelPos.x\" [style.top.px]=\"profilePanelPos.y\">\n <div class=\"intensity-panel-header\" (mousedown)=\"onProfilePanelDragStart($event)\">\n <span>Intensity profile</span>\n <i class=\"pi pi-arrows-alt\"></i>\n </div>\n <div [id]=\"intensityInsetDiv\" class=\"intensity-panel-plot\"></div>\n</div>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\" ></spatial-controls>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog header=\"Region Editor\" [(visible)]=\"showRegionEditor\"\n [modal]=\"false\" [resizable]=\"true\" [draggable]=\"true\"\n [maximizable]=\"true\" appendTo=\"body\" position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <region-editor></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog header=\"Simplify region(s)\" [(visible)]=\"displaySimplifyDialog\" [modal]=\"true\"\n [style]=\"{width: '22rem'}\" [draggable]=\"false\" [resizable]=\"false\">\n <div class=\"flex flex-column gap-2\">\n <span>Altitude threshold: <b>{{ simplifyThreshold }} px</b></span>\n <p-slider [(ngModel)]=\"simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button label=\"Apply\" icon=\"pi pi-check\" (onClick)=\"simplifyRegions(simplifyThreshold)\"></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog *ngIf=\"openParamsTool as tool\"\n [header]=\"tool.label + ' parameters'\"\n [visible]=\"true\" (visibleChange)=\"openParamsToolId = null\"\n [modal]=\"true\"\n [style]=\"{width: '30rem'}\" [draggable]=\"false\" [resizable]=\"false\" appendTo=\"body\">\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let p of tool.params\">\n <div class=\"field\" [ngClass]=\"p.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container [ngSwitch]=\"p.type\">\n\n <ng-container *ngSwitchCase=\"'number'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-inputNumber [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [min]=\"numberParam(p).min\" [max]=\"numberParam(p).max\"\n [step]=\"numberParam(p).step\"\n [minFractionDigits]=\"numberParam(p).fractionDigits\"\n [showButtons]=\"true\"></p-inputNumber>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'select'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-dropdown [options]=\"selectParam(p).options\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n appendTo=\"body\"></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngSwitchCase=\"'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [binary]=\"true\" [inputId]=\"tool.id + '-' + p.id\"></p-checkbox>\n <label [for]=\"tool.id + '-' + p.id\" class=\"text-sm mb-0\"\n [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n </div>\n\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Reset to model defaults\" [text]=\"true\" size=\"small\"\n (onClick)=\"resetToolParams(tool.id)\"></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"openParamsToolId = null\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-plot{flex:1;min-height:0;height:auto!important}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}#overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}#sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}#sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}#sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.intensity-panel{position:fixed;z-index:1100;width:280px;height:180px;background:#191919e6;border:1px solid var(--primary-color, #3399ff);border-radius:6px;box-shadow:0 4px 14px #00000073;display:flex;flex-direction:column;overflow:hidden}.intensity-panel-header{display:flex;align-items:center;justify-content:space-between;padding:.25rem .5rem;cursor:move;-webkit-user-select:none;user-select:none;background:#ffffff14;color:#eee;font-size:.75rem;font-weight:600}.intensity-panel-header i{opacity:.6;font-size:.7rem}.intensity-panel-plot{flex:1 1 auto;width:100%}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"] }]
2466
+ args: [{ selector: 'visualizer', template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ samStatus || message.detail }}</div>\n <p-progressBar *ngIf=\"samDownloading\" [value]=\"samProgress\" styleClass=\"mt-2 sam-progress\"></p-progressBar>\n <p-progressBar *ngIf=\"samBusy && !samDownloading\" mode=\"indeterminate\" styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div class=\"toolbar-dock\" [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\">\n <div class=\"toolbar-drag-handle\" (mousedown)=\"onToolbarDragStart($event)\"\n pTooltip=\"Drag to float the toolbar\" tooltipPosition=\"bottom\">\n <i class=\"pi pi-bars\"></i>\n </div>\n<plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [plotTypeOptions]=\"plotTypeMenu\"\n [selectedPlotType]=\"selectedPlotTypeId\"\n [basePlotType]=\"basePlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n [openDialogToolId]=\"openDialogToolId\"\n (toggleDialogTool)=\"toggleDialogTool($event)\"\n [toolModelIds]=\"toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndoRegion\"\n [canRedo]=\"canRedoRegion\"\n [stackOptions]=\"stackOptions\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\">\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n</plotting-toolbar>\n <p-button *ngIf=\"toolbarFloating\" class=\"toolbar-dock-btn\" icon=\"pi pi-thumbtack\" size=\"small\" [text]=\"true\"\n pTooltip=\"Dock to top\" tooltipPosition=\"bottom\" (onClick)=\"dockToolbar()\">\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading || stackLoading || isCaching\" id=\"overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading; else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching; else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress\"></p-progressBar>\n <span class=\"text-loading\">{{loadingMessage}}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading && !zoom\" class=\"text-loading\">{{loadingMessage}}</span>\n <span *ngIf=\"imgLoading && zoom\" class=\"zoom-text-loading\">{{loadingMessage}}</span>\n </ng-template>\n </ng-template>\n <p-button *ngIf=\"stackLoading || imgLoading\" class=\"cancel-loading \" label=\"Cancel\"\n (onClick)=\"cancelLoading()\">\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"sharpening && !imgLoading && !stackLoading && !isCaching\" id=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n\n</div>\n\n<!-- Floating, draggable intensity-profile inset. Shown in LINE mode; the chart\n updates live as the line ROI on the image is moved. Kept OUTSIDE #plot and\n positioned fixed so it floats over the whole page (not clipped to the\n diagram/canvas area). -->\n<div *ngIf=\"hasProfiles\" class=\"intensity-panel\"\n [style.left.px]=\"profilePanelPos.x\" [style.top.px]=\"profilePanelPos.y\">\n <div class=\"intensity-panel-header\" (mousedown)=\"onProfilePanelDragStart($event)\">\n <span>Intensity profile</span>\n <i class=\"pi pi-arrows-alt\"></i>\n </div>\n <div [id]=\"intensityInsetDiv\" class=\"intensity-panel-plot\"></div>\n</div>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\" ></spatial-controls>\n\n<!-- Side panel of the active contributed plot mode (PLOT_TYPE_CONTRIBUTIONS),\n in the same right-hand area as the spatial controls and the Region Editor.\n Exists only while the mode's session is live; there is no close button,\n because leaving the mode is what ends it. A component panel gets\n PLOT_MODE_CONTEXT / PLOT_MODE_SESSION from its injector; a `mount` panel's\n host element is attached to the slot below (see plotModePanelSlot). -->\n<p-dialog *ngIf=\"plotModePanel as panel\" [header]=\"panel.title\" [visible]=\"true\"\n [modal]=\"false\" [closable]=\"false\" [resizable]=\"true\" [draggable]=\"true\"\n appendTo=\"body\" position=\"right\" styleClass=\"plot-mode-panel\"\n [style]=\"{ width: '22rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <ng-container *ngIf=\"panel.component\">\n <ng-container *ngComponentOutlet=\"panel.component; injector: panel.injector ?? undefined\"></ng-container>\n </ng-container>\n <div *ngIf=\"panel.host\" #plotModePanelSlot class=\"plot-mode-panel-slot\"></div>\n</p-dialog>\n\n<!-- An open dialog tool (TOOLBAR_TOOLS, kind: 'dialog'). Non-modal so the user can\n keep working on the image, e.g. painting with the brush the tool armed. The\n tool renders its body into a host element attached to the slot below (see\n toolDialogSlot); closing the dialog ends the tool's session. -->\n<p-dialog *ngIf=\"toolDialog as dlg\" [header]=\"dlg.title\" [visible]=\"true\"\n (visibleChange)=\"$event || closeDialogTool()\"\n [modal]=\"false\" [closable]=\"true\" [resizable]=\"true\" [draggable]=\"true\"\n appendTo=\"body\" position=\"right\" styleClass=\"tool-dialog\"\n [style]=\"{ width: dlg.width, maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <div #toolDialogSlot class=\"tool-dialog-slot\"></div>\n</p-dialog>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog header=\"Region Editor\" [(visible)]=\"showRegionEditor\"\n [modal]=\"false\" [resizable]=\"true\" [draggable]=\"true\"\n [maximizable]=\"true\" appendTo=\"body\" position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <region-editor></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog header=\"Simplify region(s)\" [(visible)]=\"displaySimplifyDialog\" [modal]=\"true\"\n [style]=\"{width: '22rem'}\" [draggable]=\"false\" [resizable]=\"false\">\n <div class=\"flex flex-column gap-2\">\n <span>Altitude threshold: <b>{{ simplifyThreshold }} px</b></span>\n <p-slider [(ngModel)]=\"simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button label=\"Apply\" icon=\"pi pi-check\" (onClick)=\"simplifyRegions(simplifyThreshold)\"></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog *ngIf=\"openParamsTool as tool\"\n [header]=\"tool.label + ' parameters'\"\n [visible]=\"true\" (visibleChange)=\"openParamsToolId = null\"\n [modal]=\"true\"\n [style]=\"{width: '30rem'}\" [draggable]=\"false\" [resizable]=\"false\" appendTo=\"body\">\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let p of tool.params\">\n <div class=\"field\" [ngClass]=\"p.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container [ngSwitch]=\"p.type\">\n\n <ng-container *ngSwitchCase=\"'number'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-inputNumber [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [min]=\"numberParam(p).min\" [max]=\"numberParam(p).max\"\n [step]=\"numberParam(p).step\"\n [minFractionDigits]=\"numberParam(p).fractionDigits\"\n [showButtons]=\"true\"></p-inputNumber>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'select'\">\n <label class=\"text-sm\" [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n <p-dropdown [options]=\"selectParam(p).options\" optionLabel=\"label\" optionValue=\"value\"\n [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n appendTo=\"body\"></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngSwitchCase=\"'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox [ngModel]=\"paramsFor(tool.id)[p.id]\"\n (ngModelChange)=\"paramsFor(tool.id)[p.id] = $event\"\n [binary]=\"true\" [inputId]=\"tool.id + '-' + p.id\"></p-checkbox>\n <label [for]=\"tool.id + '-' + p.id\" class=\"text-sm mb-0\"\n [pTooltip]=\"p.tooltip || ''\">{{ p.label }}</label>\n </div>\n\n </ng-container>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Reset to model defaults\" [text]=\"true\" size=\"small\"\n (onClick)=\"resetToolParams(tool.id)\"></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"openParamsToolId = null\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-plot{flex:1;min-height:0;height:auto!important}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}#overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}#sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}#sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}#sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.intensity-panel{position:fixed;z-index:1100;width:280px;height:180px;background:#191919e6;border:1px solid var(--primary-color, #3399ff);border-radius:6px;box-shadow:0 4px 14px #00000073;display:flex;flex-direction:column;overflow:hidden}.intensity-panel-header{display:flex;align-items:center;justify-content:space-between;padding:.25rem .5rem;cursor:move;-webkit-user-select:none;user-select:none;background:#ffffff14;color:#eee;font-size:.75rem;font-weight:600}.intensity-panel-header i{opacity:.6;font-size:.7rem}.intensity-panel-plot{flex:1 1 auto;width:100%}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"] }]
2044
2467
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2045
2468
  type: Inject,
2046
2469
  args: [IMAGE_STATE_PORT]
@@ -2062,6 +2485,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
2062
2485
  }, {
2063
2486
  type: Inject,
2064
2487
  args: [SPATIAL_DATA_PORT]
2488
+ }] }, { type: undefined, decorators: [{
2489
+ type: Optional
2490
+ }, {
2491
+ type: Inject,
2492
+ args: [PLOT_TYPE_CONTRIBUTIONS]
2493
+ }] }, { type: i0.Injector, decorators: [{
2494
+ type: Optional
2065
2495
  }] }], propDecorators: { isStackEvent: [{
2066
2496
  type: Output
2067
2497
  }], isGrayscaleEvent: [{
@@ -2073,8 +2503,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
2073
2503
  }], contextMenu: [{
2074
2504
  type: ViewChild,
2075
2505
  args: ['cm']
2506
+ }], plotModePanelSlot: [{
2507
+ type: ViewChild,
2508
+ args: ['plotModePanelSlot']
2076
2509
  }], onKeydown: [{
2077
2510
  type: HostListener,
2078
2511
  args: ['window:keydown', ['$event']]
2512
+ }], toolDialogSlot: [{
2513
+ type: ViewChild,
2514
+ args: ['toolDialogSlot']
2079
2515
  }] } });
2080
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQWlCLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQWdDLFFBQVEsRUFBRSxNQUFNLEVBQWlCLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6TSxPQUFPLEVBQStCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBWSxjQUFjLEVBQVksTUFBTSxhQUFhLENBQUM7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWxELE9BQU8sRUFBa0IsZ0JBQWdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN0RixPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQVUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsYUFBYSxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDckUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRSxPQUFPLEVBQ0wsUUFBUSxFQUVSLFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLHVCQUF1QixHQUN4QixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRSxPQUFPLEVBQWlDLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxVQUFVLEVBQUUsb0JBQW9CLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDOUcsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQzFGLE9BQU8sRUFDTCxhQUFhLEVBS2Isd0JBQXdCLEdBQ3pCLE1BQU0sbUNBQW1DLENBQUM7QUFFM0MsT0FBTyxFQUF5QixpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSx3QkFBd0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsaUJBQWlCLEVBQW1CLE1BQU0scUNBQXFDLENBQUM7QUFFekYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV2RTs7O2lFQUdpRTtBQUNqRSxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUM7QUFTeEIsTUFBTSxPQUFPLG1CQUFtQjtJQUM5Qjs7OzZFQUd5RTthQUMxRCxnQkFBVyxHQUFHLENBQUMsQUFBSixDQUFLO0lBRS9COzs7Ozs7Ozs7OztPQVdHO2FBQ3FCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQXVCLEFBQWpDLENBQWtDO0lBR3ZFOzs7Ozs7OztPQVFHO0lBQ0gsSUFBSSxnQkFBZ0I7UUFDbEIsTUFBTSxNQUFNLEdBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2pFLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDO0lBQy9DLENBQUM7SUFPRDtzRkFDa0Y7SUFDbEYsSUFDSSxZQUFZLENBQUMsQ0FBb0M7UUFDbkQsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLEdBQUcsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlELENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztJQWlDRDs7MEZBRXNGO0lBQ3RGLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLGFBQWEsR0FBRyxHQUFHLENBQUM7SUFDakUsQ0FBQztJQWtKRDs7cUVBRWlFO0lBQ2pFLElBQUksZUFBZTtRQUNqQixPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCw2RUFBNkU7SUFDN0UsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssUUFBUSxDQUFDLElBQUksQ0FBQztJQUNqRCxDQUFDO0lBRUQ7OzJFQUV1RTtJQUN2RSxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQ2xELENBQUM7SUE2Q0QsWUFDb0MsS0FBcUIsRUFDNUIsV0FBd0IsRUFDNUMsY0FBOEIsRUFDN0IsTUFBYyxFQUNkLEdBQXNCLEVBQ3RCLE9BQXdCLEVBQ3hCLE9BQXVCLEVBQ3ZCLGVBQXVDLEVBQ3ZDLFlBQWlDLEVBQ2pDLFNBQTJCLEVBQ0ssU0FBcUI7SUFDN0QsNEVBQTRFO0lBQzVFLDBFQUEwRTtJQUMxRSxzRUFBc0U7SUFDbkMsaUJBQXNEO0lBQ3pGLDJFQUEyRTtJQUMzRSxpREFBaUQ7SUFDRixXQUE2QjtRQWpCMUMsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDNUMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzdCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixZQUFPLEdBQVAsT0FBTyxDQUFpQjtRQUN4QixZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN2QixvQkFBZSxHQUFmLGVBQWUsQ0FBd0I7UUFDdkMsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBQ2pDLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQ0ssY0FBUyxHQUFULFNBQVMsQ0FBWTtRQU9kLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQXRTckUsZ0JBQVcsR0FBRyxhQUFhLENBQUM7UUFDNUIscUJBQWdCLEdBQUcsbUJBQW1CLENBQUM7UUFnQmhELGlCQUFZLEdBQUcsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdkMscUJBQWdCLEdBQUcsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFZbkMsa0JBQWEsR0FBb0MsaUJBQWlCLENBQUM7UUFFM0U7OzBFQUVrRTtRQUVsRSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRWpCOytFQUN1RTtRQUN2RSwwQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDOUIsbUJBQWMsR0FBRyxrQkFBa0IsQ0FBQztRQUNwQyxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBS0wsVUFBSyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDNUIsd0JBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUUxQyxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUM3QiwwRUFBMEU7UUFDMUUsMEVBQTBFO1FBQzFFLHlFQUF5RTtRQUNsRSxrQkFBYSxHQUFrQixJQUFJLENBQUM7UUFDM0MsdUVBQXVFO1FBQ3ZFLHNFQUFzRTtRQUN0RSx5RUFBeUU7UUFDekUscURBQXFEO1FBQzlDLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFPbEIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUV4Qjs7Ozs7V0FLRztRQUNLLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLFdBQU0sR0FBRyxDQUFDLENBQUM7UUFDWCxhQUFRLEdBQUcsQ0FBQyxDQUFDO1FBR3BCLHFCQUFnQixHQUFlLEVBQUUsQ0FBQztRQUVsQyxtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFFckM7a0ZBQzBFO1FBQzFFLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLHdFQUF3RTtRQUN4RSxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUV0QixvREFBb0Q7UUFDcEQsMEJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQzlCLHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUN0QjtpRkFDeUU7UUFDakUsb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFFdkMsd0ZBQXdGO1FBQ3hGLG9CQUFlLEdBQUcsR0FBRyxDQUFDO1FBQ3RCLGdGQUFnRjtRQUNoRixjQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ2Y7OzBFQUVrRTtRQUNsRSxjQUFTLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxRixlQUFVLEdBQUcsb0JBQW9CLEVBQUUsQ0FBQztRQUVwQzs7Ozs7V0FLRztRQUNILHFCQUFnQixHQUE4QixFQUFFLENBQUM7UUFDakQsOENBQThDO1FBQzlDLGlCQUFZLEdBQTJCLEVBQUUsQ0FBQztRQUMxQzs7O1dBR0c7UUFDSCxlQUFVLEdBQTRDLEVBQUUsQ0FBQztRQUN6RCxzREFBc0Q7UUFDdEQscUJBQWdCLEdBQWtCLElBQUksQ0FBQztRQUN2Qyw4RUFBOEU7UUFDOUUsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNmLGdCQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsMkJBQTJCO1FBQzVDLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLFlBQU8sR0FBRyxLQUFLLENBQUMsQ0FBQyw0REFBNEQ7UUFDN0U7MkRBQ21EO1FBQzNDLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBRXJCLGdCQUFXLEdBQUcsT0FBTyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO1FBQ2xFOzs7Ozs7Ozs7Ozs7Ozs7OztXQWlCRztRQUNNLG1CQUFjLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxTQUFTLENBQUM7UUFDdkQsMkVBQTJFO1FBQ25FLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN6Qyx1REFBdUQ7UUFDdkQsdUJBQWtCLEdBQUcsRUFBRSxDQUFDO1FBR3hCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRXJCLHdFQUF3RTtRQUN4RSx5QkFBb0IsR0FBRyxLQUFLLENBQUM7UUFDN0IsaUVBQWlFO1FBQ2pFLHdCQUFtQixHQUFHLEtBQUssQ0FBQztRQUM1QixpRUFBaUU7UUFDakUscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ3pCOzs2RUFFcUU7UUFDckUsc0JBQWlCLEdBQUcsTUFBTSxDQUFDO1FBQzNCLGlCQUFZLEdBQUc7WUFDYixFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRTtZQUN0QyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRTtTQUMvQixDQUFDO1FBQ0Ysd0JBQW1CLEdBQThDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0UsZ0JBQVcsR0FBRyxZQUFZLGVBQWUsRUFBRSxFQUFFLENBQUM7UUFDdkQsYUFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDMUIsY0FBUyxHQUFHLElBQUksQ0FBQztRQUNqQix3QkFBbUIsR0FBRyxXQUFXLENBQUM7UUFDbEMsd0ZBQXdGO1FBQ3hGLGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ25CLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLHFGQUFxRjtRQUNyRixvQkFBZSxHQUFHLHVCQUF1QixDQUFDO1FBRTFDLHlFQUF5RTtRQUN6RSxvQkFBZSxHQUF5QixFQUFFLENBQUM7UUFDM0MscUJBQWdCLEdBQWEsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUU1QyxvREFBb0Q7UUFDM0Msc0JBQWlCLEdBQUcsc0JBQXNCLENBQUM7UUFDcEQsb0JBQWUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQzNCLHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQUM3QixzQkFBaUIsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUV6RDs7OEJBRXNCO1FBQ3RCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGVBQVUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ3BCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGlCQUFZLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDNUMsbUJBQWMsR0FBdUIsRUFBRSxDQUFDO1FBQ2hEO29GQUM0RTtRQUM1RSxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQTBCcEI7MkVBQ21FO1FBQ25FLGFBQVEsR0FBYSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUU5QjtrRkFDMEU7UUFDbEUsc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLGlGQUFpRjtRQUN6RSx3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFDcEM7OytDQUV1QztRQUMvQixxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDakM7MEZBQ2tGO1FBQzFFLHNCQUFpQixHQUFrQixJQUFJLENBQUM7UUFDaEQ7dUZBQytFO1FBQ3ZFLG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQUM3QyxxREFBcUQ7UUFDN0Msb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFjdkMsaUZBQWlGO1FBQ2hFLGFBQVEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ2xELElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLDZFQUE2RTtZQUM3RSw2RUFBNkU7WUFDN0UsOEVBQThFO1lBQzlFLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBaVBIOztxRUFFNkQ7UUFDN0Q7Z0ZBQ3dFO1FBQ2hFLDRCQUF1QixHQUFHLEtBQUssQ0FBQztRQWhPdEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLHdCQUF3QixDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQ3pELElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSDs7Ozs7OztPQU9HO0lBQ0ssbUJBQW1CO1FBQ3pCLElBQUksQ0FBQywwQkFBMEIsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3RGLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDdEIsMEVBQTBFO1lBQzFFLHlFQUF5RTtZQUN6RSw4Q0FBOEM7WUFDOUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO1lBQ3BDLDJFQUEyRTtZQUMzRSx5RUFBeUU7WUFDekUsMEVBQTBFO1lBQzFFLDJFQUEyRTtZQUMzRSwyRUFBMkU7WUFDM0Usc0JBQXNCO1lBQ3RCLE1BQU0sR0FBRyxHQUFHLE9BQU87Z0JBQ2pCLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLElBQUksS0FBSyxJQUFJLFNBQVMsSUFBSSxPQUFPLENBQUMsTUFBTTtvQkFDckQsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO2dCQUNyRixDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ1QsSUFBSSxHQUFHLEtBQUssSUFBSSxDQUFDLGlCQUFpQjtnQkFBRSxPQUFPO1lBQzNDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxHQUFHLENBQUM7WUFDN0IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztZQUM3QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1lBQ2pDLDhFQUE4RTtZQUM5RSxnRkFBZ0Y7WUFDaEYseUVBQXlFO1lBQ3pFLG9GQUFvRjtZQUNwRixtRkFBbUY7WUFDbkYsa0ZBQWtGO1lBQ2xGLDhCQUE4QjtZQUM5QixJQUFJLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLElBQUksU0FBUyxDQUFDO1lBQ2hFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7WUFDbEMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDOUIsMkVBQTJFO1lBQzNFLHlFQUF5RTtZQUN6RSwyRUFBMkU7WUFDM0UsNEVBQTRFO1lBQzVFLDBFQUEwRTtZQUMxRSw0RUFBNEU7WUFDNUUscUNBQXFDO1lBQ3JDLElBQUksT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDOUMsS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdkMsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLHNFQUFzRTtnQkFDdEUsMkVBQTJFO2dCQUMzRSxzRUFBc0U7Z0JBQ3RFLDBFQUEwRTtnQkFDMUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixJQUFJLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDakMsMkVBQTJFO29CQUMzRSxrRUFBa0U7b0JBQ2xFLDJFQUEyRTtvQkFDM0UseUVBQXlFO29CQUN6RSxzRUFBc0U7b0JBQ3RFLDJCQUEyQjtvQkFDM0IsRUFBRTtvQkFDRixrRUFBa0U7b0JBQ2xFLDJFQUEyRTtvQkFDM0UseUVBQXlFO29CQUN6RSwyQkFBMkI7b0JBQzNCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO29CQUMxRSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxNQUFNO3dCQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDdEUsQ0FBQztZQUNILENBQUM7WUFDRCw0RUFBNEU7WUFDNUUseUVBQXlFO1lBQ3pFLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ssS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQXVCO1FBQ3JELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDNUIsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsU0FBUztZQUFFLE9BQU87UUFDbEQsTUFBTSxHQUFHLEdBQUcsR0FBRyxPQUFPLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkUsSUFBSSxHQUFHLEtBQUssSUFBSSxDQUFDLGNBQWM7WUFBRSxPQUFPO1FBQ3hDLDRFQUE0RTtRQUM1RSwwRUFBMEU7UUFDMUUsSUFBSSxDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUM7UUFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDdkYsNkVBQTZFO1lBQzdFLDBEQUEwRDtZQUMxRCxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQ2hDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25ELE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUMzQixPQUFPO1lBQ1QsQ0FBQztZQUNELHdFQUF3RTtZQUN4RSw2RUFBNkU7WUFDN0UsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssUUFBUSxDQUFDLEtBQUs7Z0JBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwRixJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsNkVBQTZFO1lBQzdFLHVFQUF1RTtZQUN2RSxPQUFPLENBQUMsSUFBSSxDQUFDLDBFQUEwRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzlGLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1lBQzNCLElBQUksSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztnQkFDekUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ25ELENBQUM7UUFDSCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozt1RUFHbUU7SUFDM0QsZUFBZTtRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztJQUM3QixDQUFDO0lBRU8scUJBQXFCO1FBQzNCLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVPLHNCQUFzQjtRQUM1QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQztRQUMzQyxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUM7UUFDMUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDO1FBQ2xELDRFQUE0RTtRQUM1RSw4RUFBOEU7UUFDOUUsa0VBQWtFO1FBQ2xFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxFQUFFLEVBQUUsWUFBWSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxXQUFXLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxzQkFBc0IsRUFBRTthQUM3RCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNaLHlFQUF5RTtZQUN6RSxzREFBc0Q7WUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLENBQUMsZUFBZTtnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUN2RCxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQzlFLDBFQUEwRTtZQUMxRSxzRUFBc0U7WUFDdEUseUVBQXlFO1lBQ3pFLHNFQUFzRTtZQUN0RSx1Q0FBdUM7WUFDdkMsSUFBSSxDQUFDLENBQUMsYUFBYSxJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUM5QyxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLGNBQWM7Z0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDekUsSUFBSSxDQUFDLENBQUMsbUJBQW1CLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQ25FLElBQUksQ0FBQyxDQUFDLGlCQUFpQixJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQjtnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUNuRSw4RUFBOEU7WUFDOUUsaUZBQWlGO1lBQ2pGLGlGQUFpRjtZQUNqRiwyRUFBMkU7WUFDM0UsRUFBRTtZQUNGLCtFQUErRTtZQUMvRSxnRkFBZ0Y7WUFDaEYsa0VBQWtFO1lBQ2xFLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLGlCQUFpQjttQkFDN0MsQ0FBQyxJQUFJLENBQUMsdUJBQXVCO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQ2pELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDO1lBQ0YsMEVBQTBFO1lBQzFFLDRFQUE0RTthQUMzRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsZUFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLDJFQUEyRTtRQUMzRSw2RUFBNkU7UUFDN0UsNEVBQTRFO1FBQzVFLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDOUIsMkVBQTJFO1lBQzNFLCtEQUErRDtZQUMvRCxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztJQVNEOzs7Ozs7T0FNRztJQUNLLGNBQWM7UUFDcEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7UUFDaEMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDOUIseUVBQXlFO1FBQ3pFLCtFQUErRTtRQUMvRSw4REFBOEQ7UUFDOUQsZ0ZBQWdGO1FBQ2hGLDBFQUEwRTtRQUMxRSxFQUFFO1FBQ0YsK0VBQStFO1FBQy9FLCtFQUErRTtRQUMvRSwrQ0FBK0M7UUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8seUJBQXlCO1FBQy9CLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLGdCQUFnQixDQUFDO1lBQUUsT0FBTztRQUMvRSxtRkFBbUY7UUFDbkYscUZBQXFGO1FBQ3JGLGlGQUFpRjtRQUNqRixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQzFFLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSztZQUNoQixDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQ3RCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxRQUFRLENBQUM7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLEtBQUssUUFBUSxDQUFDLEtBQUssQ0FBQztRQUM3QyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsUUFBUTtRQUNOLDBFQUEwRTtRQUMxRSxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0I7WUFDbkIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssV0FBVyxDQUFDO2dCQUMzRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUc7WUFDbEIsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUU7WUFDdEMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUU7U0FDL0IsQ0FBQztRQUNGLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUMvRSx1Q0FBdUM7WUFDdkMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDbEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRTtZQUN4RixJQUFJLENBQUMsVUFBVSxHQUFHLGNBQWMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztRQUNILDJFQUEyRTtRQUMzRSx3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLFdBQVc7YUFDYixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMzQixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztZQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsSUFBSSxDQUFDLFdBQVc7YUFDYixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMzQixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztZQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsMEVBQTBFO1FBQzFFLG9EQUFvRDtRQUNwRCxJQUFJLENBQUMsV0FBVzthQUNiLHdCQUF3QixFQUFFO2FBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzNCLFNBQVMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUNMLHlFQUF5RTtRQUN6RSx5RUFBeUU7UUFDekUseUVBQXlFO1FBQ3pFLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUNsQixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMxQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FDbEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7WUFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQ2xCLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3pDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksSUFBSTtnQkFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxFQUFFO1lBQ3ZFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxlQUFlLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFO1lBQzNELElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN0RSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVCLDZFQUE2RTtZQUM3RSwwRUFBMEU7WUFDMUUscUVBQXFFO1lBQ3JFLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLDZCQUE2QixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM5RixJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLO2FBQ1AsaUJBQWlCLEVBQUU7YUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDM0IsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDdEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNoRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzNFLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxZQUFZLEVBQUUsRUFBRTtZQUM1RCxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDeEYsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7WUFDL0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUN2Qyw0RUFBNEU7WUFDNUUsNEVBQTRFO1lBQzVFLDZFQUE2RTtZQUM3RSw0RUFBNEU7WUFDNUUsNEVBQTRFO1lBQzVFLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pCLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7UUFDSCw2RUFBNkU7UUFDN0UseUVBQXlFO1FBQ3pFLDZFQUE2RTtRQUM3RSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQy9FLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxXQUFXLENBQUMsOEJBQThCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEcsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMsU0FBUyxDQUFDO1lBQzlELElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUNoQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN0QixPQUFPO2dCQUNULENBQUM7Z0JBQ0QsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztvQkFDekIsdUVBQXVFO29CQUN2RSxvREFBb0Q7b0JBQ3BELElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO29CQUM5QixvRUFBb0U7b0JBQ3BFLHVFQUF1RTtvQkFDdkUsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7b0JBQ2pDLGdDQUFnQztvQkFDaEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBRTNGLDZFQUE2RTtvQkFDN0UsNEVBQTRFO29CQUM1RSwyRUFBMkU7b0JBQzNFLDJFQUEyRTtvQkFDM0UsOEVBQThFO29CQUM5RSxpREFBaUQ7b0JBQ2pELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUNoRCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3hDLCtEQUErRDtvQkFDL0Qsc0NBQXNDO29CQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzt3QkFDaEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7d0JBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQzt3QkFDL0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7d0JBQ3ZDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDNUMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFdBQVcsQ0FBQztvQkFDekMsQ0FBQztvQkFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7b0JBQ3ZDLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDakQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDMUIsOERBQThEO29CQUM5RCxzRUFBc0U7b0JBQ3RFLHVFQUF1RTtvQkFDdkUsd0VBQXdFO29CQUN4RSx1RUFBdUU7b0JBQ3ZFLHFFQUFxRTtvQkFDckUsd0RBQXdEO29CQUN4RCxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUNULE1BQU0sS0FBSyxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQzt3QkFDakMsTUFBTSxTQUFTLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLENBQUM7d0JBQ25ELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDOzRCQUNqQixvRUFBb0U7NEJBQ3BFLG9FQUFvRTs0QkFDcEUscUVBQXFFOzRCQUNyRSxnREFBZ0Q7NEJBQ2hELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQzs0QkFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7d0JBQzFCLENBQUM7d0JBQ0QsK0VBQStFO3dCQUMvRSxNQUFNLE9BQU8sR0FBdUIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7d0JBQzlFLE1BQU0sWUFBWSxHQUFHLE9BQU8sRUFBRSxZQUFZLElBQUksR0FBRyxDQUFDO3dCQUNsRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUN6QixJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQzt3QkFDekQsNkRBQTZEO3dCQUM3RCw4REFBOEQ7d0JBQzlELHlEQUF5RDt3QkFDekQsZ0VBQWdFO3dCQUNoRSx5REFBeUQ7d0JBQ3pELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3RELDZEQUE2RDt3QkFDN0QsNERBQTREO3dCQUM1RCxnRUFBZ0U7d0JBQ2hFLCtEQUErRDt3QkFDL0QscUNBQXFDO3dCQUNyQyxJQUFJLE9BQU8sQ0FBQyxhQUFhLEtBQUssU0FBUyxFQUFFLENBQUM7NEJBQ3hDLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQzs0QkFDcEMsT0FBTyxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUM7d0JBQ3BDLENBQUM7d0JBQ0Qsd0NBQXdDO3dCQUN4QyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQzt3QkFDcEIsaUVBQWlFO3dCQUNqRSxrRUFBa0U7d0JBQ2xFLGlFQUFpRTt3QkFDakUsb0VBQW9FO3dCQUNwRSxtRUFBbUU7d0JBQ25FLE1BQU0sWUFBWSxHQUNoQixJQUFJLENBQUMsU0FBUzs0QkFDZCxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxNQUFNOzRCQUNoRCxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFDdkMsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsU0FBcUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7d0JBRS9GLGtFQUFrRTt3QkFDbEUscUVBQXFFO3dCQUNyRSx5REFBeUQ7d0JBQ3pELE1BQU0sVUFBVSxHQUFHLENBQ2pCLE1BQTZCLEVBQzdCLE1BQXFDLEVBQ3JDLEVBQUU7NEJBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7NEJBQzdELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXO2lDQUM1QixVQUFVLEVBQUU7aUNBQ1osR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7NEJBQzFFLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7d0JBQzdDLENBQUMsQ0FBQzt3QkFFRixNQUFNLFFBQVEsR0FBRyxHQUFHLEVBQUU7NEJBQ3BCLDBEQUEwRDs0QkFDMUQsZ0VBQWdFOzRCQUNoRSxpRUFBaUU7NEJBQ2pFLGdFQUFnRTs0QkFDaEUsNERBQTREOzRCQUM1RCxpRUFBaUU7NEJBQ2pFLGtFQUFrRTs0QkFDbEUsNkNBQTZDOzRCQUM3QyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUUsQ0FBQztnQ0FDL0MsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQztnQ0FDckMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLElBQUksUUFBUSxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUM7Z0NBQ2pFLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO2dDQUMzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0NBQ3BDLE1BQU0sSUFBSSxHQUFHLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQztvQ0FDbkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7Z0NBQ2xFLENBQUM7Z0NBQ0QsVUFBVSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO2dDQUNyQyxPQUFPOzRCQUNULENBQUM7NEJBQ0QsaUVBQWlFOzRCQUNqRSxnRUFBZ0U7NEJBQ2hFLDZEQUE2RDs0QkFDN0Qsa0VBQWtFOzRCQUNsRSxtRUFBbUU7NEJBQ25FLDJEQUEyRDs0QkFDM0QsZ0VBQWdFOzRCQUNoRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDOzRCQUNuQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQ0FDcEIsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dDQUN2RSxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0NBQzNELElBQUksQ0FBQyxPQUFPLElBQUksWUFBWSxFQUFFLENBQUM7b0NBQzdCLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO29DQUMzQyxLQUFLLE1BQU0sQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDO3dDQUN4QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQzt3Q0FDbkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3Q0FDN0IsSUFBSSxNQUFNOzRDQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7OzRDQUN0QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0NBQzFCLENBQUM7b0NBQ0QsVUFBVSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztvQ0FDL0IsT0FBTztnQ0FDVCxDQUFDOzRCQUNILENBQUM7NEJBQ0QsK0RBQStEOzRCQUMvRCxrQ0FBa0M7NEJBQ2xDLElBQUksT0FBTyxFQUFFLENBQUM7Z0NBQ1osTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7Z0NBQ3hELElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dDQUNyQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FDcEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FDdEQsQ0FBQztnQ0FDRixJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDOzRCQUM3QyxDQUFDOzRCQUNELCtEQUErRDs0QkFDL0Qsb0VBQW9FOzRCQUNwRSxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFLENBQUM7d0JBQ3RDLENBQUMsQ0FBQzt3QkFDRixJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUM7d0JBQzVCLE1BQU0sY0FBYyxHQUFHLEdBQUcsRUFBRTs0QkFDMUIsSUFBSSxlQUFlO2dDQUFFLE9BQU87NEJBQzVCLGVBQWUsR0FBRyxJQUFJLENBQUM7NEJBQ3ZCLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsU0FBUztnQ0FBRSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQzs0QkFDcEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ3BDLENBQUMsQ0FBQzt3QkFFRixJQUFJLGtCQUFrQixDQUFDOzRCQUNyQixpRUFBaUU7NEJBQ2pFLCtEQUErRDs0QkFDL0QsV0FBVyxFQUFFLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxFQUFFO2dDQUNsQyxvRUFBb0U7Z0NBQ3BFLHFFQUFxRTtnQ0FDckUsb0VBQW9FO2dDQUNwRSxpRUFBaUU7Z0NBQ2pFLDhCQUE4QjtnQ0FDOUIsSUFBSSxDQUFDLFNBQVMsRUFBRTtvQ0FBRSxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7Z0NBQy9DLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtvQ0FDeEUsaUVBQWlFO29DQUNqRSxJQUFJLENBQUMsU0FBUyxFQUFFO3dDQUFFLE9BQU8sSUFBSSxDQUFDO29DQUM5QixzREFBc0Q7b0NBQ3RELElBQUksU0FBUyxDQUFDLFFBQVEsS0FBSyxXQUFXLENBQUMsUUFBUTt3Q0FBRSxPQUFPLElBQUksQ0FBQztvQ0FDN0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FDMUIsSUFBSSxDQUFDLFdBQVcsRUFDaEIsV0FBVyxFQUNYLFNBQVMsRUFDVCxZQUFZLEVBQ1osSUFBSSxDQUFDLFFBQVEsRUFDYixPQUFPLENBQ1IsQ0FBQztnQ0FDSixDQUFDLENBQUMsQ0FBQzs0QkFDTCxDQUFDOzRCQUNELFVBQVUsRUFBRSxHQUFHLEVBQUU7Z0NBQ2YsSUFBSSxDQUFDLFNBQVMsRUFBRTtvQ0FBRSxPQUFPLENBQUMsOEJBQThCO2dDQUN4RCx3RUFBd0U7Z0NBQ3hFLCtFQUErRTtnQ0FDL0UsOEVBQThFO2dDQUM5RSw4RUFBOEU7Z0NBQzlFLHlCQUF5QjtnQ0FDekIsSUFBSSxJQUFJLENBQUMsU0FBUztvQ0FBRSxPQUFPO2dDQUMzQixpRkFBaUY7Z0NBQ2pGLHdEQUF3RDtnQ0FDeEQsY0FBYyxFQUFFLENBQUM7Z0NBQ2pCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDOzRCQUN6QixDQUFDOzRCQUNELGNBQWMsRUFBRSxHQUFHLEVBQUU7Z0NBQ25CLElBQUksQ0FBQyxTQUFTLEVBQUU7b0NBQUUsT0FBTyxDQUFDLDhCQUE4QjtnQ0FDeEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7NEJBQzFCLENBQUM7NEJBQ0QsUUFBUSxFQUFFLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dDQUM5QixJQUFJLENBQUMsU0FBUyxFQUFFO29DQUFFLE9BQU8sQ0FBQyw4QkFBOEI7Z0NBQ3hELGdGQUFnRjtnQ0FDaEYsY0FBYyxFQUFFLENBQUM7Z0NBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO2dDQUNyQixRQUFRLEVBQUUsQ0FBQztnQ0FDWCxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDOzRCQUN0QixDQUFDOzRCQUNELGFBQWEsRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dDQUMxQixJQUFJLENBQUMsU0FBUyxFQUFFO29DQUFFLE9BQU8sQ0FBQyw4QkFBOEI7Z0NBQ3hELDREQUE0RDtnQ0FDNUQseUNBQXlDO2dDQUN6QyxNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRSxVQUFVLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dDQUNsRixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztvQ0FDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0NBQzFCLFFBQVEsRUFBRSxNQUFNO29DQUNoQixPQUFPLEVBQUUsdUJBQXVCO29DQUNoQyxNQUFNLEVBQUUsNkNBQTZDLEdBQUcsNkVBQTZFO2lDQUN0SSxDQUFDLENBQUM7Z0NBQ0gsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0NBQ3JCLFFBQVEsRUFBRSxDQUFDOzRCQUNiLENBQUM7eUJBQ0YsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7b0JBQ25DLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDYixNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRSxVQUFVLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNsRixPQUFPLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM1RCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztvQkFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0JBQzFCLE1BQU0sRUFBRSxJQUFJO29CQUNaLFFBQVEsRUFBRSxPQUFPO29CQUNqQixPQUFPLEVBQUUsa0JBQWtCO29CQUMzQixNQUFNLEVBQUUseURBQXlELEdBQUc7a0ZBQ0k7aUJBQ3pFLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRTtZQUNuRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBYyxDQUFDO2dCQUFFLE9BQU87WUFDcEQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2dCQUNyRCxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTNFLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxLQUFvQixFQUFFLEVBQUU7WUFDOUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7WUFDM0MsSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsaUJBQWlCO2dCQUFFLE9BQU87WUFDcEcsbUVBQW1FO1lBQ25FLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQzVGLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLE9BQU87d0JBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQzs7d0JBQ3pELElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3ZDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLDZDQUE2QztnQkFDcEUsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsT0FBTztZQUNULENBQUM7WUFDRCxxRUFBcUU7WUFDckUscUJBQXFCO1lBQ3JCLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ25DLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDakMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztvQkFDekMsT0FBTztnQkFDVCxDQUFDO2dCQUNELElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7b0JBQy9DLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7b0JBQ3pDLE9BQU87Z0JBQ1QsQ0FBQztZQUNILENBQUM7WUFDRCxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssV0FBVyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQ2xHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN2QyxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDeEMsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNwRCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzFELENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDekQsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1lBQy9ELENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDckQsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUM1RCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXpELElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDekMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQWMsQ0FBQztnQkFBRSxPQUFPO1lBQ3BELDBFQUEwRTtZQUMxRSx5RUFBeUU7WUFDekUseUVBQXlFO1lBQ3pFLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO2dCQUFFLE9BQU87WUFDckQsMEVBQTBFO1lBQzFFLDJFQUEyRTtZQUMzRSxxRUFBcUU7WUFDckUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO2dCQUFFLE9BQU87WUFDNUIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2pDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDdkMsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ3hDLENBQUM7UUFDSCxDQUFDLENBQUM7UUFDRixNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBRXhGLDBEQUEwRDtRQUMxRCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxDQUFhLEVBQUUsRUFBRTtZQUMvQyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2dCQUM5QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ25CLElBQUksQ0FBQyxlQUFlLEdBQUc7d0JBQ3JCLENBQUMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO3dCQUNyRSxDQUFDLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztxQkFDdEUsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRzt3QkFDaEIsQ0FBQyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQzt3QkFDM0QsQ0FBQyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztxQkFDNUQsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQUM7UUFDRixJQUFJLENBQUMscUJBQXFCLEdBQUcsR0FBRyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFDbEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDL0IsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUNuRSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBRS9ELDZFQUE2RTtRQUM3RSw0RUFBNEU7UUFDNUUscUVBQXFFO1FBQ3JFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxHQUFHLEVBQUU7WUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXO2dCQUFFLE9BQU87WUFDOUIscUJBQXFCLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQztRQUMzRCxDQUFDLENBQUM7UUFDRixNQUFNLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCx1QkFBdUIsQ0FBQyxDQUFhO1FBQ25DLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDakMsSUFBSSxDQUFDLGlCQUFpQixHQUFHO1lBQ3ZCLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTztZQUNiLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTztZQUNiLENBQUMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDekIsQ0FBQyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztTQUMxQixDQUFDO1FBQ0YsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRDs4QkFDMEI7SUFDMUIsa0JBQWtCLENBQUMsQ0FBYTtRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBQzVCLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRztZQUNsQixFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU87WUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU87WUFDYixDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BCLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDckIsQ0FBQztRQUNGLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLFdBQVc7UUFDVCxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUMvQixDQUFDO0lBRUQ7O2lEQUU2QztJQUNyQyxvQkFBb0I7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUM5QixJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSxLQUFLLENBQUMsY0FBYztRQUNsQiwyRUFBMkU7UUFDM0UsMEVBQTBFO1FBQzFFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUscUJBQXFCLEVBQUUsQ0FBQztZQUNoRixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUk7Z0JBQ3pCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUUsRUFBRTtnQkFDekQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUNELDhFQUE4RTtRQUM5RSx1RUFBdUU7UUFDdkUsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN2QyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxjQUFjLEVBQUUsQ0FBQztRQUN6RSx1RUFBdUU7UUFDdkUsMERBQTBEO1FBQzFELElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QywyRUFBMkU7WUFDM0UseUVBQXlFO1lBQ3pFLDhEQUE4RDtZQUM5RCxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QseUVBQXlFO1FBQ3pFLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQy9CLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEYsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixNQUFNLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMvQixNQUFNLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNoRCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMscUJBQXFCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDM0MsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzlDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMxQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRU0sVUFBVTtRQUNmLG9FQUFvRTtRQUNwRSwyRUFBMkU7UUFDM0UsaUVBQWlFO1FBQ2pFLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7T0FFRztJQUNJLGlCQUFpQjtRQUN0QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsY0FBYyxDQUFDLFlBQXNCO1FBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDN0MsQ0FBQztJQUNILENBQUM7SUFFRCw2REFBNkQ7SUFDN0Qsb0JBQW9CO1FBQ2xCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7SUFDbkMsQ0FBQztJQUVELGlEQUFpRDtJQUNqRCxtQkFBbUI7UUFDakIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztJQUNsQyxDQUFDO0lBRUQ7OzBEQUVzRDtJQUN0RCxnQkFBZ0I7UUFDZCx5RUFBeUU7UUFDekUsdUVBQXVFO1FBQ3ZFLHlFQUF5RTtRQUN6RSwrREFBK0Q7UUFDL0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSx5QkFBeUIsQ0FBQztRQUMzRCxNQUFNLEtBQUssR0FBRyxRQUFRO1lBQ3BCLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFjLFFBQVEsQ0FBQyxFQUFFLHFCQUFxQixFQUFFLENBQUMsS0FBSztZQUM5RSxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ2QsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ2hGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILGlCQUFpQixDQUFDLG1CQUF3QjtRQUN4QyxNQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLEtBQUssTUFBTSxDQUFDO1FBQ3JELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQztRQUMvQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztRQUNoRixJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUM5QixJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLG1FQUFtRTtRQUNuRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQztZQUNqQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQztZQUN6QyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxZQUFZLENBQUMsSUFBZTtRQUMxQixJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUM5QixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLENBQUM7UUFDRCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDbEMsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxRQUFRLENBQUMsQ0FBcUI7UUFDNUIsSUFBSSxDQUFDLEtBQUssU0FBUztZQUFFLE9BQU87UUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDaEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsNkVBQTZFO1FBQzdFLG9FQUFvRTtRQUNwRSxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDM0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlELENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFFBQVEsQ0FBQyxDQUFxQjtRQUM1QixJQUFJLENBQUMsS0FBSyxTQUFTO1lBQUUsT0FBTztRQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFFSCxTQUFTLENBQUMsQ0FBZ0I7UUFDeEIsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLFdBQVcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVk7WUFBRSxPQUFPO1FBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUMxRCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBNEIsQ0FBQztRQUN6QyxJQUFJLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLGlCQUFpQixDQUFDO1lBQUUsT0FBTztRQUN0RiwyRUFBMkU7UUFDM0Usd0NBQXdDO1FBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUFFLE9BQU87UUFDakYsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsd0VBQXdFO0lBQ3hFLFNBQVMsQ0FBQyxLQUFhO1FBQ3JCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDdkUsSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPO1FBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEIsQ0FBQztJQUVELGFBQWE7UUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQywwRUFBMEU7UUFDMUUsMEVBQTBFO1FBQzFFLDBFQUEwRTtRQUMxRSxzRUFBc0U7UUFDdEUsb0VBQW9FO1FBQ3BFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDbkMsQ0FBQztJQUNILENBQUM7SUFDRCxhQUFhO1FBQ1gsMkZBQTJGO1FBQzNGLDJGQUEyRjtRQUMzRixJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDaEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxhQUFhO1FBQ1gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRUQsY0FBYztRQUNaLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELG1GQUFtRjtJQUNuRixzQkFBc0I7UUFDcEIsSUFBSSxDQUFDLHFCQUFxQixHQUFHLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDO1FBQ3pELElBQUksQ0FBQyxXQUFXLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxjQUFjLENBQUMsSUFBWTtRQUN6Qiw4Q0FBOEM7UUFDOUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDakUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUNuQyxxREFBcUQ7UUFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkMsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxXQUFXO2FBQ2IsZ0JBQWdCLEVBQUU7WUFDbkIsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUUsTUFBeUIsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFN0UseUVBQXlFO1FBQ3pFLDJDQUEyQztRQUMzQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sWUFBWSxHQUFHLE1BQU0sS0FBSyxLQUFLLElBQUksTUFBTSxLQUFLLE1BQU0sQ0FBQztZQUMzRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUVELDJCQUEyQjtRQUMzQixJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxXQUFXLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEtBQUssTUFBTSxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZGLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsTUFBTSxLQUFLLFVBQVUsQ0FBQyxDQUFDO1FBQ3hELDJEQUEyRDtRQUMzRCxJQUFJLE1BQU0sS0FBSyxVQUFVO1lBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsTUFBTSxLQUFLLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELElBQUksTUFBTSxLQUFLLGFBQWEsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDbEUsQ0FBQztJQUNILENBQUM7SUFFRDs7cUZBRWlGO0lBQ3pFLFlBQVksQ0FBQyxJQUFtQjtRQUN0QyxPQUFPLENBQ0wsSUFBSSxLQUFLLFVBQVU7WUFDbkIsSUFBSSxLQUFLLGdCQUFnQjtZQUN6QixJQUFJLEtBQUssY0FBYztZQUN2QixJQUFJLEtBQUssUUFBUTtZQUNqQixJQUFJLEtBQUssYUFBYTtZQUN0QixJQUFJLEtBQUssVUFBVTtZQUNuQixJQUFJLEtBQUssYUFBYTtZQUN0QixJQUFJLEtBQUssTUFBTSxDQUNoQixDQUFDO0lBQ0osQ0FBQztJQUVEO21GQUMrRTtJQUMvRSxnQkFBZ0IsQ0FBQyxNQUE0QjtRQUMzQyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUFFLE9BQU87UUFDekMsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVELHVCQUF1QixDQUFDLEtBQXlCO1FBQy9DLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTztRQUMzRCxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxLQUF5QjtRQUN6QyxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsMEJBQTBCLENBQUMsS0FBeUI7UUFDbEQsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPO1FBQzNELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCwyRUFBMkU7SUFDM0UsVUFBVTtRQUNSLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELCtEQUErRDtJQUMvRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsMkVBQTJFO0lBRTNFLDZEQUE2RDtJQUM3RCxJQUFZLGVBQWU7UUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxQyxPQUFPLElBQUksQ0FBQyxlQUFlO2FBQ3hCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs2REFDeUQ7SUFDakQsVUFBVSxDQUFDLE9BQWlCO1FBQ2xDLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FDbkQsQ0FBQyxDQUFDLE1BQU0sWUFBWSxTQUFTO1lBQzdCLENBQUMsQ0FBQyxNQUFNLFlBQVksWUFBWTtZQUNoQyxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksT0FBTyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUMzRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7d0VBQ29FO0lBQzVELFdBQVcsQ0FBQyxPQUFpQjtRQUNuQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUM7WUFDdkIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxFQUFZLEVBQUUsRUFBWSxFQUFFLEVBQUU7Z0JBQzFDLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRTtvQkFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRTtvQkFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDO1lBQ0YsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFlBQVksU0FBUztvQkFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7cUJBQy9ELElBQUksQ0FBQyxZQUFZLE9BQU87b0JBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUNyRCxJQUFJLENBQUMsWUFBWSxZQUFZO29CQUFFLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVE7d0JBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdGLENBQUM7WUFDRCxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNyQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLElBQUksZUFBZSxLQUFjLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUYsdUVBQXVFO0lBQ3ZFLElBQUksaUJBQWlCLEtBQWMsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0csK0VBQStFO0lBQy9FLElBQUksb0JBQW9CLEtBQWMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVqRywyRUFBMkU7SUFDM0UsZ0JBQWdCO1FBQ2QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxQyxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7UUFDN0IsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTO1lBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxXQUFXLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSxZQUFZO1FBQ1YsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbEQsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUM7WUFBRSxPQUFPO1FBQzNCLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQy9DLElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsc0VBQXNFO0lBQ3RFLGNBQWM7UUFDWixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDN0IsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO1FBQzdCLEtBQUssTUFBTSxDQUFDLElBQUksR0FBRztZQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCx5RUFBeUU7SUFDekUsY0FBYztRQUNaLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTztRQUM3QixNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztnQkFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxjQUFjO2dCQUN4QixRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTO2dCQUNwQyxNQUFNLEVBQUUsOERBQThEO2FBQ3ZFLENBQUMsQ0FBQztZQUNILE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxzRUFBc0U7SUFDdEUsZUFBZSxDQUFDLFdBQW1CO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTztRQUM3QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUVELGlEQUFpRDtJQUNqRCxrQkFBa0IsS0FBVyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUVqRTs7OztPQUlHO0lBQ0ssY0FBYyxDQUFDLE1BQWdCLEVBQUUsR0FBYTtRQUNwRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDN0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsbUNBQW1DO1FBQ25GLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDN0MsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxXQUFXLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzttRkFFK0U7SUFDL0UsS0FBSyxDQUFDLGNBQWM7UUFDbEIsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7SUFDbEcsQ0FBQztJQUVEOzttRkFFK0U7SUFDL0UsS0FBSyxDQUFDLGVBQWU7UUFDbkIsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFLENBQ3BFLElBQUksQ0FBQyxXQUFXLENBQUMseUJBQXlCLEVBQUUsQ0FDN0MsQ0FBQztJQUNKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsU0FBUyxDQUFDLE1BQWM7UUFDdEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDN0IsaUVBQWlFO1lBQ2pFLHdFQUF3RTtZQUN4RSx5RUFBeUU7WUFDekUsc0VBQXNFO1lBQ3RFLGdFQUFnRTtZQUNoRSx5RUFBeUU7WUFDekUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLFVBQVUsQ0FBQyxJQUE2QjtRQUN0QyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUM3RCxDQUFDO0lBRUQ7NkNBQ3lDO0lBQ3pDLGlCQUFpQixDQUFDLENBQXNDO1FBQ3RELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQix5RUFBeUU7UUFDekUsMkVBQTJFO1FBQzNFLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BFLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRDtrRUFDOEQ7SUFDdEQsVUFBVSxDQUFDLElBQTZCLEVBQUUsT0FBZTtRQUMvRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLE9BQU8sQ0FBQyxDQUFDO1FBQzFELE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxRQUFRLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsV0FBVyxDQUFDLENBQWdCO1FBQzFCLE9BQU8sQ0FBb0IsQ0FBQztJQUM5QixDQUFDO0lBRUQsV0FBVyxDQUFDLENBQWdCO1FBQzFCLE9BQU8sQ0FBb0IsQ0FBQztJQUM5QixDQUFDO0lBRUQsY0FBYyxDQUFDLE1BQWM7UUFDM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLHFDQUFxQztRQUM3RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDO0lBQ2pDLENBQUM7SUFFRDswQkFDc0I7SUFDdEIsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsZUFBZSxDQUFDLE1BQWM7UUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLElBQUk7WUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRUQ7O21GQUUrRTtJQUMvRSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQWM7UUFDMUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDbEIsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3RSxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQzdELElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FDbkMsQ0FBQztJQUNKLENBQUM7SUFFRDs7b0ZBRWdGO0lBQ3hFLEtBQUssQ0FBQyxtQkFBbUIsQ0FDL0IsS0FBYTtJQUNiLDBFQUEwRTtJQUMxRSwwRUFBMEU7SUFDMUUsb0RBQW9EO0lBQ3BELElBQW9FLEVBQ3BFLEVBQXlCO1FBRXpCLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDMUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUNILDJFQUEyRTtRQUMzRSx5RUFBeUU7UUFDekUsdUVBQXVFO1FBQ3ZFLElBQUksVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3hDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ04sVUFBVSxHQUFHLENBQUMsQ0FBQztnQkFDZixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILE1BQU0sQ0FBQyxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUM7Z0JBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDeEIsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTTtnQkFDcEMsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsTUFBTSxFQUFFLFVBQVUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDO2FBQzlFLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUM7Z0JBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDeEIsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQzthQUNqRSxDQUFDLENBQUM7UUFDTCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzZDQUN5QztJQUNqQyxZQUFZLENBQUMsT0FBZTtRQUNsQyxJQUFJLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFRCwyRUFBMkU7SUFDbkUsWUFBWTtRQUNsQixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELGdCQUFnQixDQUFDLEVBQVU7UUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELDREQUE0RDtJQUM1RCxjQUFjO1FBQ1osSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRCxvRUFBb0U7SUFDcEUsZUFBZTtRQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssc0JBQXNCO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQztRQUMzRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxHQUFlLEVBQUUsQ0FBQztRQUU3QiwyRUFBMkU7UUFDM0UscUJBQXFCO1FBQ3JCLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDVCxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLG9CQUFvQjtZQUN2RCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1NBQ3ZDLENBQUMsQ0FBQztRQUVILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDcEMsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpDLElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN6QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7UUFDRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNyRCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2hHLENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDekIsS0FBSyxDQUFDLElBQUksQ0FDUixFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLEVBQy9FO2dCQUNFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLGtCQUFrQjtnQkFDM0MsS0FBSyxFQUFFO29CQUNMLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDakUsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUNsRSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2xFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRTtvQkFDbkIsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtpQkFDL0Q7YUFDRixDQUNGLENBQUM7UUFDSixDQUFDO1FBQ0QseUVBQXlFO1FBQ3pFLGdEQUFnRDtRQUNoRCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDN0MsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ3BDLENBQUMsQ0FBQyxDQUFDLE1BQU0sWUFBWSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLFlBQVksU0FBUyxDQUFDLENBQUM7WUFDdEYsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sWUFBWSxPQUFPLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRixJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNoQixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMzRyxDQUFDO1lBQ0QsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLG9CQUFvQixFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5RyxDQUFDO1FBQ0gsQ0FBQztRQUNELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDaEcsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8scUJBQXFCO1FBQzNCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDbkMsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUM7UUFDMUMsTUFBTSxLQUFLLEdBQWUsRUFBRSxDQUFDO1FBQzdCLDJFQUEyRTtRQUMzRSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUM5QyxJQUFJLE9BQU8sQ0FBQyxNQUFNO2dCQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsS0FBSyxDQUFDLElBQUksQ0FDUixFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsRUFDM0YsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQ3BCLENBQUM7WUFDRix5RUFBeUU7WUFDekUscUVBQXFFO1lBQ3JFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3RCLEtBQUssQ0FBQyxJQUFJLENBQUM7b0JBQ1QsS0FBSyxFQUFFLGdCQUFnQjtvQkFDdkIsSUFBSSxFQUFFLGNBQWM7b0JBQ3BCLFVBQVUsRUFBRSxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2hELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQztpQkFDM0MsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLGFBQWE7Z0JBQ3BCLElBQUksRUFBRSxtQkFBbUI7Z0JBQ3pCLFVBQVUsRUFBRSxNQUFNLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQzthQUNoRCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDVCxLQUFLLEVBQUUsS0FBSztnQkFDWixJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixVQUFVLEVBQUUsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUMvQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUM7YUFDMUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUM7WUFDckMsS0FBSyxDQUFDLElBQUksQ0FDUjtnQkFDRSxLQUFLLEVBQUUsTUFBTTtnQkFDYixJQUFJLEVBQUUsY0FBYztnQkFDcEIsVUFBVSxFQUFFLEdBQUcsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDN0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUM7YUFDaEQsRUFDRDtnQkFDRSxLQUFLLEVBQUUsS0FBSztnQkFDWixJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixVQUFVLEVBQUUsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUM1QyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQzthQUMvQyxFQUNEO2dCQUNFLEtBQUssRUFBRSxrQkFBa0I7Z0JBQ3pCLElBQUksRUFBRSxhQUFhO2dCQUNuQixVQUFVLEVBQUUsR0FBRyxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUM5QyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQzthQUNqRCxFQUNEO2dCQUNFLEtBQUssRUFBRSxvQkFBb0I7Z0JBQzNCLElBQUksRUFBRSxZQUFZO2dCQUNsQixVQUFVLEVBQUUsR0FBRyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNsRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQzthQUNyRCxFQUNELEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUNuQixFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FDeEYsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixLQUFLLENBQUMsSUFBSSxDQUNSLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUM3RSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFDaEYsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQ25CO2dCQUNFLEtBQUssRUFBRSxRQUFRO2dCQUNmLElBQUksRUFBRSxzQkFBc0I7Z0JBQzVCLFVBQVUsRUFBRSxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2xELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQzthQUM3QyxFQUNEO2dCQUNFLEtBQUssRUFBRSxVQUFVO2dCQUNqQixJQUFJLEVBQUUsY0FBYztnQkFDcEIsVUFBVSxFQUFFLE1BQU0sS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUMxRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQzthQUNyRCxFQUNEO2dCQUNFLEtBQUssRUFBRSxPQUFPO2dCQUNkLElBQUksRUFBRSxZQUFZO2dCQUNsQixVQUFVLEVBQUUsTUFBTSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNqRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUM7YUFDNUMsRUFDRDtnQkFDRSxLQUFLLEVBQUUsVUFBVTtnQkFDakIsSUFBSSxFQUFFLGVBQWU7Z0JBQ3JCLFVBQVUsRUFBRSxNQUFNLEtBQUssY0FBYyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3hELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQzthQUNuRCxFQUNEO2dCQUNFLEtBQUssRUFBRSxXQUFXO2dCQUNsQixJQUFJLEVBQUUsWUFBWTtnQkFDbEIsVUFBVSxFQUFFLE1BQU0sS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDcEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDO2FBQy9DLEVBQ0Q7Z0JBQ0UsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLFVBQVUsRUFBRSxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2hELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQzthQUMzQyxFQUNEO2dCQUNFLEtBQUssRUFBRSxlQUFlO2dCQUN0QixJQUFJLEVBQUUsY0FBYztnQkFDcEIsVUFBVSxFQUFFLE1BQU0sS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDdkQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDO2FBQ2xELENBQ0YsQ0FBQztZQUNGLDBEQUEwRDtZQUMxRCx1RUFBdUU7WUFDdkUsMEJBQTBCO1lBQzFCLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0MsS0FBSyxDQUFDLElBQUksQ0FDUjtvQkFDRSxLQUFLLEVBQUUsMEJBQTBCO29CQUNqQyxJQUFJLEVBQUUsdUJBQXVCO29CQUM3QixVQUFVLEVBQUUsTUFBTSxLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUN2RCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUM7aUJBQ2xELEVBQ0Q7b0JBQ0UsS0FBSyxFQUFFLFlBQVk7b0JBQ25CLElBQUksRUFBRSxpQkFBaUI7b0JBQ3ZCLFVBQVUsRUFBRSxNQUFNLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3BELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztpQkFDL0MsRUFDRDtvQkFDRSxLQUFLLEVBQUUsZUFBZTtvQkFDdEIsSUFBSSxFQUFFLG9CQUFvQjtvQkFDMUIsVUFBVSxFQUFFLE1BQU0sS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDdkQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDO2lCQUNsRCxDQUNGLENBQUM7WUFDSixDQUFDO1lBQ0QsNEVBQTRFO1lBQzVFLHNFQUFzRTtRQUN4RSxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsbUJBQW1CLENBQUMsSUFBWTtRQUM5QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELGtCQUFrQjtRQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUVEO2tFQUM4RDtJQUM5RCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLGNBQWMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRUQsa0dBQWtHO0lBQ2xHLGVBQWU7UUFDYixJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUM3QyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2hGLENBQUM7SUFFRDtzR0FDa0c7SUFDbEcsZ0JBQWdCLENBQUMsS0FBYTtRQUM1QixJQUFJLEtBQUssS0FBSyxJQUFJLENBQUMsZUFBZTtZQUFFLE9BQU87UUFDM0MsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxnQkFBZ0IsQ0FBQyxJQUFjO1FBQzdCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDckUsTUFBTSxJQUFJLEdBQUcsVUFBVSxFQUFFLFVBQVUsS0FBSyxJQUFJLENBQUM7UUFDN0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyw0RUFBNEU7UUFDNUUsMkVBQTJFO1FBQzNFLHFFQUFxRTtRQUNyRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFdBQVcsQ0FBQztRQUN6QyxDQUFDO1FBQ0Qsd0ZBQXdGO1FBQ3hGLHNGQUFzRjtRQUN0RiwwRkFBMEY7UUFDMUYsTUFBTSxRQUFRLEdBQUcsSUFBSSxLQUFLLFFBQVEsQ0FBQyxZQUFZLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BFLElBQUksVUFBVSxFQUFFLGFBQWEsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzNDLDBFQUEwRTtZQUMxRSxxRUFBcUU7WUFDckUsMkVBQTJFO1lBQzNFLDJFQUEyRTtZQUMzRSx5RUFBeUU7WUFDekUscUVBQXFFO1lBQ3JFLHNFQUFzRTtZQUN0RSxvREFBb0Q7WUFDcEQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztnQkFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzFDLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsbUVBQW1FO0lBQzNELG9CQUFvQjtRQUMxQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDOzhHQTFqRVUsbUJBQW1CLGtCQXlTcEIsZ0JBQWdCLGFBQ2hCLFVBQVUsd1FBU0UsVUFBVSw2QkFJVixhQUFhLDZCQUdiLGlCQUFpQjtrR0ExVDVCLG1CQUFtQiwyWEN4RGhDLGtnYkE4UEE7OzJGRHRNYSxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBR0UsWUFBWTs7MEJBNlNuQixNQUFNOzJCQUFDLGdCQUFnQjs7MEJBQ3ZCLE1BQU07MkJBQUMsVUFBVTs7MEJBU2pCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsVUFBVTs7MEJBSTdCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsYUFBYTs7MEJBR2hDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsaUJBQWlCO3lDQXJSdkMsWUFBWTtzQkFEWCxNQUFNO2dCQUdQLGdCQUFnQjtzQkFEZixNQUFNO2dCQU1ILFlBQVk7c0JBRGYsS0FBSztnQkFjTixRQUFRO3NCQURQLEtBQUs7Z0JBNkNXLFdBQVc7c0JBQTNCLFNBQVM7dUJBQUMsSUFBSTtnQkEwdENmLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEFmdGVyVmlld0luaXQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbmplY3QsIElucHV0LCBOZ1pvbmUsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBNZW51SXRlbSwgTWVzc2FnZVNlcnZpY2UsIFRyZWVOb2RlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgQ29udGV4dE1lbnUgfSBmcm9tICdwcmltZW5nL2NvbnRleHRtZW51JztcbmltcG9ydCB7IElJbWFnZUluZm8gfSBmcm9tICcuL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQgeyBJbWFnZVN0YXRlUG9ydCwgSU1BR0VfU1RBVEVfUE9SVCB9IGZyb20gJy4vY29udHJhY3RzL3BvcnRzL2ltYWdlLXN0YXRlLnBvcnQnO1xuaW1wb3J0IHsgUG9seWdvbiwgUmVjdGFuZ2xlLCBNdWx0aVBvbHlnb24sIFJlZ2lvbiB9IGZyb20gJy4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBSZWdpb25PcHNTZXJ2aWNlIH0gZnJvbSAnLi9yZWdpb24tb3BzLnNlcnZpY2UnO1xuaW1wb3J0IHsgVklaX1RPQVNUX0tFWSwgVklaX0FMRVJUX1RPQVNUX0tFWSB9IGZyb20gJy4vdG9hc3Qtb3V0bGV0cyc7XG5pbXBvcnQgeyBWaXN1YWxpemVyU3RvcmUgfSBmcm9tICcuL3N0b3JlL3Zpc3VhbGl6ZXItc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBSZW5kZXJPcmNoZXN0cmF0b3IsIFNsaWNlU2NydWJiZXIgfSBmcm9tICcuL3JlbmRlci1vcmNoZXN0cmF0b3InO1xuaW1wb3J0IHtcbiAgUGxvdFR5cGUsXG4gIFBsb3RUeXBlRGVzY3JpcHRvcixcbiAgaXNOYXBhcmkzZCxcbiAgaXNTcGF0aWFsT21pY3MzZCxcbiAgcmVuZGVyZXJPd25zV2hlZWwsXG4gIE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFLFxufSBmcm9tICcuL2NvbnRyYWN0cy9wbG90LXR5cGUnO1xuaW1wb3J0IHsgVmlld2VyRmVhdHVyZSB9IGZyb20gJy4vY29udHJhY3RzL2NhcGFiaWxpdGllcy5jb250cmFjdCc7XG5pbXBvcnQgeyBJbnRlbnNpdHlQcm9maWxlLCBJVmlzdWFsaXplciwgVklTVUFMSVpFUiB9IGZyb20gJy4vY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuaW1wb3J0IHsgU0FNX01PREVMUywgZ2V0RGVmYXVsdFNhbU1vZGVsSWQsIGlzU2FtTW9kZWxSZWFkeSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLW1vZGVsLXJlZ2lzdHJ5JztcbmltcG9ydCB7IFNhbVRvb2xTZXJ2aWNlIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zYW0tdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IFNhbVBvaW50VG9vbFNlcnZpY2UgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NhbS1wb2ludC10b29sLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2VsbFNlZ21lbnRUb29sU2VydmljZSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vY2VsbC1zZWdtZW50LXRvb2wuc2VydmljZSc7XG5pbXBvcnQge1xuICBUT09MQkFSX1RPT0xTLFxuICBOdW1iZXJQYXJhbVNwZWMsXG4gIFNlbGVjdFBhcmFtU3BlYyxcbiAgVG9vbFBhcmFtU3BlYyxcbiAgVG9vbGJhclRvb2xDb250cmlidXRpb24sXG4gIHZpc2libGVUb29sQ29udHJpYnV0aW9ucyxcbn0gZnJvbSAnLi9jb250cmFjdHMvdG9vbGJhci10b29sLmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvblRvb2xNb2RlIH0gZnJvbSAnLi9jb250cmFjdHMvcmVnaW9uLW92ZXJsYXkuY29udHJhY3QnO1xuaW1wb3J0IHsgVG9vbGJhclRvb2xWaXNpYmlsaXR5LCBBTExfVE9PTEJBUl9UT09MUyB9IGZyb20gJy4vY29udHJhY3RzL3Rvb2xiYXItY29uZmlnJztcbmltcG9ydCB7IFZJWl9DT05GSUcsIFZpekNvbmZpZyB9IGZyb20gJy4vY29udHJhY3RzL3Zpei1jb25maWcnO1xuaW1wb3J0IHsgU1BBVElBTF9EQVRBX1BPUlQsIFNwYXRpYWxEYXRhUG9ydCB9IGZyb20gJy4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB7IFNwYXRpYWxEYXRhc2V0IH0gZnJvbSAnLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IGJ1aWxkVm9sdW1lU3RhY2tJbWFnZSB9IGZyb20gJy4vc3BhdGlhbC9zcGF0aWFsLXZvbHVtZS1pbWFnZSc7XG5cbi8qKiBQZXItaW5zdGFuY2UgcGxvdC1kaXYgaWQgc291cmNlLiBUaGUgbW91bnQgZWxlbWVudCdzIGlkIG11c3QgYmUgdW5pcXVlIHNvIHR3b1xuICogIGxpdmUgdmlld2VycyAoZS5nLiB0aGUgbWFpbiBkaWFncmFtICsgYSBtb2RhbCBwcmV2aWV3KSBkb24ndCBjb2xsaWRlIG9uIHRoZVxuICogIHNhbWUgRE9NIGlkIOKAlCBgZ2V0RWxlbWVudEJ5SWRgIHdvdWxkIG90aGVyd2lzZSByZXR1cm4gd2hpY2hldmVyIGNhbWUgZmlyc3QuXG4gKiAgU3R5bGluZyBoYW5ncyBvZmYgdGhlIGAudml6LXBsb3RgIGNsYXNzIGluc3RlYWQgb2YgdGhlIGlkLiAqL1xubGV0IHBsb3RJbnN0YW5jZVNlcSA9IDA7XG5cbkBDb21wb25lbnQoe1xuICAvLyBDYW5vbmljYWwgcHJlZml4ZWQgc2VsZWN0b3IgZmlyc3Q7IHRoZSB1bnByZWZpeGVkIG9yaWdpbmFsIGlzIGtlcHQgYXMgYW5cbiAgLy8gYWxpYXMgZm9yIG9uZSByZWxlYXNlIChwcmUtcHVibGljYXRpb24gYmFjay1jb21wYXQpLlxuICBzZWxlY3RvcjogJ3Zpc3VhbGl6ZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vdmlzdWFsaXplci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgVmlzdWFsaXplckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAvKiogUGVyLWluc3RhbmNlIHRvYXN0IGtleS4gTWVzc2FnZVNlcnZpY2UgaXMgYSBnbG9iYWwgc2luZ2xldG9uLCBzbyB0d28gbGl2ZVxuICAgKiAgYDx2aXN1YWxpemVyPmAgaW5zdGFuY2VzIChtYWluIHZpZXdlciArIHBpcGVsaW5lLWRpYWxvZyBwcmV2aWV3KSBzaGFyaW5nXG4gICAqICBvbmUga2V5IHdvdWxkIGVhY2ggcmVuZGVyIHRoZSBzYW1lIG1lc3NhZ2Ug4oCUIGEgZHVwbGljYXRlIHRvYXN0LiBBIHVuaXF1ZVxuICAgKiAga2V5IHBlciBpbnN0YW5jZSBzY29wZXMgdGhlIHRvYXN0IHRvIHRoZSBjb21wb25lbnQgdGhhdCByYWlzZWQgaXQuICovXG4gIHByaXZhdGUgc3RhdGljIG5leHRUb2FzdElkID0gMDtcblxuICAvKipcbiAgICogVGhlIGxpYnJhcnkgYWxzbyByYWlzZXMgbm90aWNlcyBmcm9tIHBsYWNlcyB0aGF0IGhhdmUgbm8gaW5zdGFuY2Ugb2YgdGhlaXJcbiAgICogb3duIHRvIGtleSBhZ2FpbnN0OiB7QGxpbmsgUGxvdGx5U2VydmljZX0gaXMgYHByb3ZpZGVkSW46ICdyb290J2AsIGFuZCB0aGVcbiAgICogcmVnaW9uIGVkaXRvciBpcyBhIGNoaWxkIGRpYWxvZy4gVGhvc2UgdXNlIHRoZSBmaXhlZFxuICAgKiB7QGxpbmsgVklaX1RPQVNUX0tFWX0gLyB7QGxpbmsgVklaX0FMRVJUX1RPQVNUX0tFWX0gb3V0bGV0cy5cbiAgICpcbiAgICogRm9yIHRoZSBzYW1lIHJlYXNvbiB0aGUgcGVyLWluc3RhbmNlIGtleSBhYm92ZSBleGlzdHMsIGV4YWN0bHkgT05FIG1vdW50ZWRcbiAgICogdmlzdWFsaXplciBtYXkgcmVuZGVyIHRob3NlIHNoYXJlZCBvdXRsZXRzIOKAlCBvdGhlcndpc2UgYSBtZXNzYWdlIGZyb20gdGhlXG4gICAqIHJvb3Qgc2VydmljZSB3b3VsZCBiZSBzaG93biBvbmNlIHBlciBsaXZlIHZpZXdlciAoaml0LXVpIHJ1bnMgYSBtYWluIHZpZXdcbiAgICogYW5kIGEgcGlwZWxpbmUtcHJldmlldyBhdCB0aGUgc2FtZSB0aW1lKS4gVGhlIGZpcnN0IHRvIGluaXQgY2xhaW1zIHRoZW0gYW5kXG4gICAqIHJlbGVhc2VzIG9uIGRlc3Ryb3ksIHNvIHRoZSBzdXJ2aXZpbmcgdmlld2VyIHBpY2tzIHRoZW0gdXAuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBsaXZlSW5zdGFuY2VzID0gbmV3IFNldDxWaXN1YWxpemVyQ29tcG9uZW50PigpO1xuICByZWFkb25seSB2aXpUb2FzdEtleSA9IFZJWl9UT0FTVF9LRVk7XG4gIHJlYWRvbmx5IHZpekFsZXJ0VG9hc3RLZXkgPSBWSVpfQUxFUlRfVE9BU1RfS0VZO1xuICAvKipcbiAgICogV2hldGhlciB0aGlzIGluc3RhbmNlIHJlbmRlcnMgdGhlIHNoYXJlZCBvdXRsZXRzLiBUaGUgb3duZXIgaXMgc2ltcGx5IHRoZVxuICAgKiBvbGRlc3QgbGl2ZSB2aXN1YWxpemVyIOKAlCBhIGBTZXRgIGl0ZXJhdGVzIGluIGluc2VydGlvbiBvcmRlciwgc28gd2hlbiB0aGVcbiAgICogb3duZXIgaXMgZGVzdHJveWVkIHRoZSBuZXh0IG9uZSB0YWtlcyBvdmVyIG9uIGl0cyBmb2xsb3dpbmcgY2hhbmdlLWRldGVjdGlvblxuICAgKiBwYXNzLiBUcmFja2luZyBhIHNldCByYXRoZXIgdGhhbiBhIHNpbmdsZSBvd25lciBtYXR0ZXJzOiB3aXRoIGEgbG9uZVxuICAgKiBgb3duZXJgIHJlZmVyZW5jZSwgdGVhcmluZyBkb3duIHRoZSBvd25lciB3aGlsZSBhIHNpYmxpbmcgd2FzIGFscmVhZHlcbiAgICogaW5pdGlhbGlzZWQgd291bGQgbGVhdmUgbm9ib2R5IHJlbmRlcmluZyB0aGUgb3V0bGV0cywgYW5kIGV2ZXJ5IG5vdGljZSBmcm9tXG4gICAqIHRoZSByb290IHNlcnZpY2Ugd291bGQgc2lsZW50bHkgdmFuaXNoIGFnYWluLlxuICAgKi9cbiAgZ2V0IG93bnNTaGFyZWRUb2FzdHMoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgb2xkZXN0ID0gVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLnZhbHVlcygpLm5leHQoKTtcbiAgICByZXR1cm4gIW9sZGVzdC5kb25lICYmIG9sZGVzdC52YWx1ZSA9PT0gdGhpcztcbiAgfVxuXG4gIEBPdXRwdXQoKVxuICBpc1N0YWNrRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKTtcbiAgQE91dHB1dCgpXG4gIGlzR3JheXNjYWxlRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKTtcblxuICAvKiogV2hpY2ggdG9vbGJhciBncm91cHMgdG8gc2hvdy4gQSBwYXJ0aWFsIG92ZXJyaWRlIG1lcmdlcyBvdmVyIHRoZSBmdWxsIHNldCxcbiAgICogIHNvIGB7IHNwZWNpYWxUb29sczogZmFsc2UgfWAgaGlkZXMgb25seSB0aGF0IGdyb3VwLiBEZWZhdWx0cyB0byBldmVyeXRoaW5nLiAqL1xuICBASW5wdXQoKVxuICBzZXQgdG9vbGJhclRvb2xzKHY6IFRvb2xiYXJUb29sVmlzaWJpbGl0eSB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX3Rvb2xiYXJUb29scyA9IHsgLi4uQUxMX1RPT0xCQVJfVE9PTFMsIC4uLih2ID8/IHt9KSB9O1xuICB9XG5cbiAgZ2V0IHRvb2xiYXJUb29scygpOiBSZXF1aXJlZDxUb29sYmFyVG9vbFZpc2liaWxpdHk+IHtcbiAgICByZXR1cm4gdGhpcy5fdG9vbGJhclRvb2xzO1xuICB9XG4gIHByaXZhdGUgX3Rvb2xiYXJUb29sczogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiA9IEFMTF9UT09MQkFSX1RPT0xTO1xuXG4gIC8qKiBFeHBvc2UgdGVzdC1vbmx5IHBsb3QgbW9kZXMgaW4gdGhlIHNlbGVjdG9yIChlLmcuIHRoZSBuYXBhcmkgYEltYWdlYFxuICAgKiAgbW9kZSwgb3RoZXJ3aXNlIGhpZGRlbikuIFRoZSBob3N0IGFwcCBzZXRzIHRoaXMgZnJvbSBhIGA/dGVzdD0xYCBVUkxcbiAgICogIHRvZ2dsZS4gT2ZmIGJ5IGRlZmF1bHQsIHNvIHByb2R1Y3Rpb24gdXNlcnMgbmV2ZXIgc2VlIHRoZW0uICovXG4gIEBJbnB1dCgpXG4gIHRlc3RNb2RlID0gZmFsc2U7XG5cbiAgLyoqIEltYWdlLXNtb290aGluZyBzdGF0ZSBmb3IgdGhlIHRvb2xiYXIncyBTbW9vdGhlbiB0b2dnbGUgKE9TRCBvbmx5KS5cbiAgICogIERlZmF1bHRzIHRvIGBmYWxzZWAgc28gT1NEIHNob3dzIHJhdyBwaXhlbHMgKG5lYXJlc3QtbmVpZ2hib3VyKS4gKi9cbiAgaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZmFsc2U7XG4gIGxvYWRpbmdNZXNzYWdlID0gJ0xvYWRpbmcgaW1hZ2UuLi4nO1xuICB6b29tID0gZmFsc2U7XG4gIGZpbGVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbG9hZGVkRmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaW1hZ2VJbmZvOiBJSW1hZ2VJbmZvIHwgdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgdW5zdWIgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHByZXZpZXdTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgcHVibGljIHN0YWNrTG9hZGluZyA9IGZhbHNlO1xuICBwdWJsaWMgaW1nTG9hZGluZyA9IGZhbHNlO1xuICBwdWJsaWMgbG9hZGluZ1BlcmNlbnRhZ2UgPSAwO1xuICAvLyBOb24tbnVsbCAoMC4uMTAwKSB3aGlsZSBqaXQtc2VydmljZSBpcyBjb3B5aW5nIHRoZSBzb3VyY2UgZmlsZSBpbnRvIHRoZVxuICAvLyBsb2NhbCBjYWNoZSBQVkMgb24gZmlyc3QgY2xpY2suIFdoZW4gc2V0LCB0aGUgbG9hZGluZyBvdmVybGF5IHN3YXBzIHRoZVxuICAvLyBzcGlubmVyIGZvciBhIGRldGVybWluYXRlIHByb2dyZXNzIGJhciB3aXRoIGEgXCJDYWNoaW5nIGltYWdlXCIgbWVzc2FnZS5cbiAgcHVibGljIGNhY2hlUHJvZ3Jlc3M6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAvLyBUcnVlIGJldHdlZW4gdGhlIHNtYWxsLXRpZXIgcmVuZGVyIGxhbmRpbmcgYW5kIHRoZSBsYXJnZS10aWVyIHJlbmRlclxuICAvLyBsYW5kaW5nIGluIHRoZSBtdWx0aS10aWVyIHJlbmRlcmluZyBwYXRoLiBUaGUgdGVtcGxhdGUgdXNlcyB0aGlzIHRvXG4gIC8vIG92ZXJsYXkgYSB0cmFuc2x1Y2VudCBzcGlubmVyIG9uIHRvcCBvZiB0aGUgYmx1cnJ5IHNtYWxsLXRpZXIgaW1hZ2Ugc29cbiAgLy8gdGhlIHVzZXIgZG9lc24ndCBtaXN0YWtlIGl0IGZvciB0aGUgZmluYWwgcHJldmlldy5cbiAgcHVibGljIHNoYXJwZW5pbmcgPSBmYWxzZTtcbiAgLyoqIEEgaml0LXNlcnZpY2UgY2FjaGUgY29weSBpcyBhY3RpdmVseSBpbiBwcm9ncmVzcyAoZGV0ZXJtaW5hdGUgMC4uOTkpLiBEcml2ZXMgdGhlIGNhY2hlXG4gICAqICBwcm9ncmVzcyBiYXIgaW5kZXBlbmRlbnRseSBvZiBgaW1nTG9hZGluZ2Agc28gdGhlIGJhciBjYW4ndCBiZSBkcm9wcGVkIOKAlCBvciBtYXNrZWQgYnkgdGhlXG4gICAqICBcIlNoYXJwZW5pbmcgcHJldmlldy4uLlwiIG92ZXJsYXkg4oCUIG1pZC1kb3dubG9hZCBpZiB0aGUgbG9hZGluZyBmbGFnIGZsaXBzIGVhcmx5LiAqL1xuICBnZXQgaXNDYWNoaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNhY2hlUHJvZ3Jlc3MgIT09IG51bGwgJiYgdGhpcy5jYWNoZVByb2dyZXNzIDwgMTAwO1xuICB9XG4gIHByaXZhdGUgcnVubmluZyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBNb25vdG9uaWMgcmVuZGVyIGdlbmVyYXRpb24uIEJ1bXBlZCB3aGVuIGEgcmVuZGVyIHN0YXJ0cywgc28gYSByZW5kZXIgdGhhdFxuICAgKiBoYXMgYmVlbiBzdXBlcnNlZGVkIGJ5IGEgbmV3ZXIgaW1hZ2UgY2FuIGJlIHJlY29nbmlzZWQgYW5kIG1hZGUgaW5lcnQ6IGl0c1xuICAgKiBjYWxsYmFja3MgcmV0dXJuIGVhcmx5IGluc3RlYWQgb2YgcGFpbnRpbmcsIGNsZWFyaW5nIGBydW5uaW5nYCwgcmVsZWFzaW5nXG4gICAqIHRoZSBuZXdlciByZW5kZXIncyBvdmVybGF5LCBvciBhcHBseWluZyBpdHMgUk9Jcy5cbiAgICovXG4gIHByaXZhdGUgcmVuZGVyVG9rZW4gPSAwO1xuICBwdWJsaWMgekluZGV4ID0gMDtcbiAgcHVibGljIG1heEluZGV4ID0gMDtcblxuICBAVmlld0NoaWxkKCdjbScpIGNvbnRleHRNZW51ITogQ29udGV4dE1lbnU7XG4gIGNvbnRleHRNZW51SXRlbXM6IE1lbnVJdGVtW10gPSBbXTtcblxuICBhY3RpdmVEcmFnTW9kZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFdoZXRoZXIgYSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byB1bmRvIChqaXQtdWkjODUpLiBNaXJyb3JzIHRoZVxuICAgKiAgc2hhcmVkIFJlZ2lvblN0b3JlJ3MgaGlzdG9yeSBkZXB0aDsgZHJpdmVzIHRoZSB0b29sYmFyIFVuZG8gYnV0dG9uLiAqL1xuICBjYW5VbmRvUmVnaW9uID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIGFuIHVuZG9uZSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byByZWRvIChqaXQtdWkjODUpLiAqL1xuICBjYW5SZWRvUmVnaW9uID0gZmFsc2U7XG5cbiAgLyoqIEN1c3RvbS10aHJlc2hvbGQgU2ltcGxpZnkgZGlhbG9nIChqaXQtdWkjODUpLiAqL1xuICBkaXNwbGF5U2ltcGxpZnlEaWFsb2cgPSBmYWxzZTtcbiAgc2ltcGxpZnlUaHJlc2hvbGQgPSAzO1xuICAvKiogQ3VycmVudCByZWdpb24gc2VsZWN0aW9uIChhcnJheSBpbmRpY2VzKSDigJQgbWlycm9yZWQgZnJvbSB0aGUgc3RvcmUgc28gdGhlXG4gICAqICBjb250ZXh0LW1lbnUgcmVnaW9uIGFjdGlvbnMgY2FuIHJlYWQgaXQgc3luY2hyb25vdXNseSAoaml0LXVpIzg1KS4gKi9cbiAgcHJpdmF0ZSBzZWxlY3RlZEluZGljZXM6IG51bWJlcltdID0gW107XG5cbiAgLyoqIFdhbmQgc2Vuc2l0aXZpdHkg4oCUIGhpZ2hlciA9IHN0cmljdGVyIChzbWFsbGVyIHNlbGVjdGlvbikuIE1hdGNoZXMgUXVQYXRoIGRlZmF1bHQuICovXG4gIHdhbmRTZW5zaXRpdml0eSA9IDIuMDtcbiAgLyoqIEJydXNoIGRpYW1ldGVyIGluIGltYWdlLXBpeGVsIGNvb3JkaW5hdGVzIChkcml2ZXMgdGhlIHBhaW50ZWQgZGlzYyBzaXplKS4gKi9cbiAgYnJ1c2hTaXplID0gNDA7XG4gIC8qKiBTQU0gbW9kZWwgcGlja2VyIG9wdGlvbnMgKyBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzkwIFAxKS4gT25seSBtb2RlbHNcbiAgICogIHdpdGggYSBob3N0ZWQgT05OWCBwYWlyIChjb25maWd1cmVkIHZpYSBzZXRTYW1Nb2RlbFVybHMgYXQgYXBwIGluaXQpIGFyZVxuICAgKiAgb2ZmZXJlZCwgc28gdGhlIHBpY2tlciBjYW4ndCBzZWxlY3QgYSBtb2RlbCB0aGF0IGNhbid0IHJ1bi4gKi9cbiAgc2FtTW9kZWxzID0gU0FNX01PREVMUy5maWx0ZXIoaXNTYW1Nb2RlbFJlYWR5KS5tYXAoKG0pID0+ICh7IGlkOiBtLmlkLCBsYWJlbDogbS5sYWJlbCB9KSk7XG4gIHNhbU1vZGVsSWQgPSBnZXREZWZhdWx0U2FtTW9kZWxJZCgpO1xuXG4gIC8qKlxuICAgKiBOby1wcm9tcHQgdG9vbHMgcmVnaXN0ZXJlZCB0aHJvdWdoIHtAbGluayBUT09MQkFSX1RPT0xTfSwgZmlsdGVyZWQgdG8gdGhvc2VcbiAgICogd2l0aCBjb25maWd1cmVkIG1vZGVscyBhbmQgc29ydGVkLiBUaGlzIGxpYnJhcnkgcmVnaXN0ZXJzIG5vbmUg4oCUIGEgaG9zdFxuICAgKiBzdXBwbGllcyB0aGVtIOKAlCBzbyBhbiBvcGVuIGJ1aWxkIGhhcyBhbiBlbXB0eSBhcnJheSBoZXJlIGFuZCB0aGUgdG9vbGJhclxuICAgKiBhbmQgaGVscCBkaWFsb2cgc2ltcGx5IG9taXQgdGhhdCBncm91cC5cbiAgICovXG4gIGNvbnRyaWJ1dGVkVG9vbHM6IFRvb2xiYXJUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIEFjdGl2ZSBjaGVja3BvaW50IHBlciBjb250cmlidXRlZCB0b29sLiAqL1xuICB0b29sTW9kZWxJZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgLyoqXG4gICAqIFBhcmFtZXRlciB2YWx1ZXMgcGVyIGNvbnRyaWJ1dGVkIHRvb2wsIHNlZWRlZCBmcm9tIGVhY2ggdG9vbCdzIG93biBkZWZhdWx0c1xuICAgKiDigJQgd2hpY2ggZW5jb2RlIHRoZSBzY2FsZSBhbmQgY3Jvd2RpbmcgaXRzIGNoZWNrcG9pbnQgd2FzIHRyYWluZWQgZm9yLlxuICAgKi9cbiAgdG9vbFBhcmFtczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0ge307XG4gIC8qKiBXaGljaCB0b29sJ3MgcGFyYW1ldGVyIGRpYWxvZyBpcyBvcGVuLCBvciBudWxsLiAqL1xuICBvcGVuUGFyYW1zVG9vbElkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFNBTSBkb3dubG9hZC9zZWdtZW50IHRvYXN0IHN0YXRlIChib3VuZCBieSB0aGUgYHNhbWAgcC10b2FzdCB0ZW1wbGF0ZSkuICovXG4gIHNhbVN0YXR1cyA9ICcnO1xuICBzYW1Qcm9ncmVzcyA9IDA7IC8vIDAuLjEwMCwgZW5jb2RlciBkb3dubG9hZFxuICBzYW1Eb3dubG9hZGluZyA9IGZhbHNlO1xuICBzYW1CdXN5ID0gZmFsc2U7IC8vIGFueSBTQU0gd29yayBpbiBmbGlnaHQgKGRyaXZlcyB0aGUgaW5kZXRlcm1pbmF0ZSBzcGlubmVyKVxuICAvKiogV2hldGhlciB0aGUgc2hhcmVkIGBzYW1gIHRvYXN0IGlzIGN1cnJlbnRseSBzaG93biAoYXZvaWRzIHN0YWNraW5nIGl0IG9uXG4gICAqICBldmVyeSBwb2ludCBjbGljaywgd2hpY2ggcmUtcnVucyBpbmZlcmVuY2UpLiAqL1xuICBwcml2YXRlIHNhbVRvYXN0U2hvd24gPSBmYWxzZTtcblxuICByZWFkb25seSBzYW1Ub2FzdEtleSA9IGBzYW0tJHtWaXN1YWxpemVyQ29tcG9uZW50Lm5leHRUb2FzdElkKyt9YDtcbiAgLyoqXG4gICAqIE91dGxldCBmb3IgdGhlIGxpYnJhcnkncyBvd24gcmVzdWx0L2Vycm9yIG5vdGljZXMuXG4gICAqXG4gICAqIFByaW1lTkcgcm91dGVzIGEgbWVzc2FnZSB0byBhIGA8cC10b2FzdD5gIG9ubHkgd2hlbiB0aGUga2V5cyBtYXRjaCDigJQgYVxuICAgKiBrZXlsZXNzIG1lc3NhZ2UgcmVhY2hlcyBhIGtleWxlc3MgdG9hc3QgYW5kIG5vdGhpbmcgZWxzZS4gVGhlc2Ugbm90aWNlcyB1c2VkXG4gICAqIHRvIGJlIGVtaXR0ZWQgd2l0aCBubyBrZXksIHNvIHRoZXkgcmVuZGVyZWQgb25seSBpbiBob3N0cyB0aGF0IGhhcHBlbiB0b1xuICAgKiBtb3VudCBhIGJhcmUgYDxwLXRvYXN0PmAgKGppdC11aSBkb2VzLCBpbiBpdHMgZmlsZS10cmVlIGNvbXBvbmVudCkuIEV2ZXJ5XG4gICAqIG90aGVyIGhvc3Qg4oCUIGluY2x1ZGluZyB0aGlzIHJlcG8ncyBvd24gYnJvd3NlciBleGFtcGxlIOKAlCBkcm9wcGVkIHRoZW1cbiAgICogc2lsZW50bHksIHdoaWNoIG1hZGUgYSBmYWlsZWQgb3Igbm8tb3Agc2VnbWVudGF0aW9uIGxvb2sgbGlrZSBhIGRlYWQgYnV0dG9uOlxuICAgKiB0aGUgc3RpY2t5IHByb2dyZXNzIHRvYXN0IGlzIGNsZWFyZWQgaW4gdGhlIHNhbWUgdGljayBieSBoaWRlU2FtVG9hc3QsIGFuZFxuICAgKiB0aGUgbWVzc2FnZSBleHBsYWluaW5nIHdoeSBuZXZlciBhcHBlYXJlZCBhbnl3aGVyZS5cbiAgICpcbiAgICogS2V5ZWQgdG8gdGhpcyBjb21wb25lbnQgaW5zdGFuY2Ugc28gdGhlIGxpYnJhcnkgcmVuZGVycyBpdHMgb3duIG91dGxldCBhbmRcbiAgICogaXMgbm90IGRlcGVuZGVudCBvbiBob3N0IG1hcmt1cC4gRGVsaWJlcmF0ZWx5IE5PVCB0aGUgc3RpY2t5IHRvYXN0J3Mga2V5OlxuICAgKiB7QGxpbmsgaGlkZVNhbVRvYXN0fSBjbGVhcnMgdGhhdCBrZXkgaW4gdGhlIGBmaW5hbGx5YCwgd2hpY2ggd291bGQgd2lwZSB0aGVcbiAgICogcmVzdWx0IHRoZSBtb21lbnQgaXQgd2FzIHBvc3RlZCwgYW5kIHRoZSBzdGlja3kgdG9hc3QncyBjdXN0b20gdGVtcGxhdGUgaXNcbiAgICogYnVpbHQgZm9yIHRoZSBsaXZlIHN0YXR1cyArIHByb2dyZXNzIGJhci5cbiAgICovXG4gIHJlYWRvbmx5IHJlc3VsdFRvYXN0S2V5ID0gYCR7dGhpcy5zYW1Ub2FzdEtleX0tcmVzdWx0YDtcbiAgLyoqIFN1YnNjcmlwdGlvbnMgdG8gdGhlIHBvaW50IHRvb2wncyBsaXZlIGZlZWRzIChzdGF0dXMvYnVzeS9kb3dubG9hZCkuICovXG4gIHByaXZhdGUgc2FtUG9pbnRTdWIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIC8qKiBWZXJ0ZXggZXJhc2VyIHJhZGl1cyBpbiBpbWFnZS1waXhlbCBjb29yZGluYXRlcy4gKi9cbiAgdmVydGV4RXJhc2VyUmFkaXVzID0gMjA7XG5cbiAgY29sb3JtYXBzT3B0aW9ucyE6IGFueTtcbiAgcmV2ZXJzZXNjYWxlID0gZmFsc2U7XG4gIHNlbGVjdGVkQ29sb3JtYXAhOiBhbnk7XG4gIC8qKiBDaGFubmVscyAmIEhpc3RvZ3JhbSBkaWFsb2cgdmlzaWJpbGl0eSAob3BlbmVkIGZyb20gdGhlIHRvb2xiYXIpLiAqL1xuICBzaG93Q2hhbm5lbEhpc3RvZ3JhbSA9IGZhbHNlO1xuICAvKiogU3BhdGlhbC1vbWljcyBjb250cm9scyBkaWFsb2cgdmlzaWJpbGl0eSAodG9vbGJhciBidXR0b24pLiAqL1xuICBzaG93U3BhdGlhbENvbnRyb2xzID0gZmFsc2U7XG4gIC8qKiBSZWdpb24gRWRpdG9yIGRpYWxvZyB2aXNpYmlsaXR5IChvcGVuZWQgZnJvbSB0aGUgdG9vbGJhcikuICovXG4gIHNob3dSZWdpb25FZGl0b3IgPSBmYWxzZTtcbiAgLyoqIFJlZ2lvbiBFZGl0b3IgZGlhbG9nIHdpZHRoLiBPbiBvcGVuIGl0IGlzIHNldCB0byB0aGUgY29uZmlndXJlZCBob3N0XG4gICAqICBlbGVtZW50J3MgY3VycmVudCB3aWR0aCwgb3Ig4oCUIHdoZW4gbm8gc2VsZWN0b3IgaXMgY29uZmlndXJlZCAvIHRoZSBlbGVtZW50XG4gICAqICBpc24ndCBmb3VuZCDigJQgdG8gYSBxdWFydGVyIG9mIHRoZSBwYWdlIChzZWUgb3BlblJlZ2lvbkVkaXRvcikuICovXG4gIHJlZ2lvbkVkaXRvcldpZHRoID0gJzI1dncnO1xuICBzdGFja09wdGlvbnMgPSBbXG4gICAgeyBuYW1lOiAnU2luZ2xlIGltYWdlJywgdmFsOiAnZmFsc2UnIH0sXG4gICAgeyBuYW1lOiAnU3RhY2snLCB2YWw6ICd0cnVlJyB9LFxuICBdO1xuICBzZWxlY3RlZFN0YWNrT3B0aW9uOiB7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfSB8IHVuZGVmaW5lZCA9IHRoaXMuc3RhY2tPcHRpb25zWzBdO1xuICByZWFkb25seSBwbG90RGl2TmFtZSA9IGB2aXotcGxvdC0ke3Bsb3RJbnN0YW5jZVNlcSsrfWA7XG4gIHBsb3RUeXBlID0gUGxvdFR5cGUuSU1BR0U7XG4gIGlzSGVhdG1hcCA9IHRydWU7XG4gIGFjdGl2ZVN1cmZhY2UzZE1vZGUgPSAndHVybnRhYmxlJztcbiAgLyoqIFdoZXRoZXIgdGhlIG5hcGFyaSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyBpcyBzaG93biAodm9sdW1lL2lzb3N1cmZhY2UpLiAqL1xuICBheGVzVmlzaWJsZSA9IHRydWU7XG4gIHdpcmVmcmFtZUFjdGl2ZSA9IGZhbHNlO1xuICAvKiogbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciAoMSA9IEZ1bGwg4oCmIDggPSDihZs7IGRlZmF1bHQgwr0pOyBjaGFuZ2luZyBpdCByZS1wbG90cy4gKi9cbiAgcmVzb2x1dGlvblNjYWxlID0gTkFQQVJJX0RFRkFVTFRfREVDSU1BVEU7XG5cbiAgLyoqIFBsb3QgdHlwZXMgdGhlIGFjdGl2ZSBiYWNrZW5kIGFkdmVydGlzZXMgKDNEIGdhdGVkIGJ5IGNhcGFiaWxpdHkpLiAqL1xuICBwbG90VHlwZU9wdGlvbnM6IFBsb3RUeXBlRGVzY3JpcHRvcltdID0gW107XG4gIHNlbGVjdGVkUGxvdFR5cGU6IFBsb3RUeXBlID0gUGxvdFR5cGUuSU1BR0U7XG5cbiAgLyoqIEZsb2F0aW5nIGludGVuc2l0eS1wcm9maWxlIGluc2V0IChMSU5FIG1vZGUpLiAqL1xuICByZWFkb25seSBpbnRlbnNpdHlJbnNldERpdiA9ICdpbnRlbnNpdHktaW5zZXQtcGxvdCc7XG4gIHByb2ZpbGVQYW5lbFBvcyA9IHsgeDogMjAsIHk6IDcwIH07XG4gIHByaXZhdGUgcHJvZmlsZVBhbmVsRHJhZ2dpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBwcm9maWxlUGFuZWxTdGFydCA9IHsgbXg6IDAsIG15OiAwLCB4OiAwLCB5OiAwIH07XG5cbiAgLyoqIFRvb2xiYXIgZG9ja2luZzogZG9ja2VkIGFjcm9zcyB0aGUgdG9wIGJ5IGRlZmF1bHQ7IGRyYWdnaW5nIGl0cyBoYW5kbGVcbiAgICogIGRldGFjaGVzIGl0IGludG8gYSBmbG9hdGluZywgbW92YWJsZSB3aW5kb3cgKGZyZWVzIHRoZSB0b3Agcm93IGZvciB0aGVcbiAgICogIHZpc3VhbGl6YXRpb24pLiAqL1xuICB0b29sYmFyRmxvYXRpbmcgPSBmYWxzZTtcbiAgdG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICBwcml2YXRlIHRvb2xiYXJEcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIHRvb2xiYXJTdGFydCA9IHsgbXg6IDAsIG15OiAwLCB4OiAwLCB5OiAwIH07XG4gIHByaXZhdGUgbGF0ZXN0UHJvZmlsZXM6IEludGVuc2l0eVByb2ZpbGVbXSA9IFtdO1xuICAvKiogRHJpdmVzIHRoZSBpbnRlbnNpdHkgaW5zZXQgcGFuZWwncyB2aXNpYmlsaXR5IOKAlCB0cnVlIHdoZW5ldmVyIGFueVxuICAgKiAgaW50ZW5zaXR5LXByb2ZpbGUgbGluZSBleGlzdHMgKGluZGVwZW5kZW50IG9mIHRoZSBjdXJyZW50IHBsb3QgdHlwZSkuICovXG4gIGhhc1Byb2ZpbGVzID0gZmFsc2U7XG4gIHByaXZhdGUgaW50ZW5zaXR5UHJvZmlsZVN1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSB2aWV3cG9ydENoYW5nZVN1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBwcm9maWxlRHJhZ01vdmVMaXN0ZW5lcj86IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIHByb2ZpbGVEcmFnVXBMaXN0ZW5lcj86ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgcHJvZmlsZVJlc2l6ZUxpc3RlbmVyPzogKCkgPT4gdm9pZDtcblxuICAvKiogVHJ1ZSB3aGlsZSB0aGUgM0Qgc3BhdGlhbCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIFRoZSBjb250cm9scyBkcm9wIHRoZSBST0lcbiAgICogIHNlbGVjdGlvbiB0aGVyZTogcmVnaW9uIHRvb2xzIGFyZSBzY3JlZW4tc3BhY2UsIGFuZCBhZ2FpbnN0IGFuIG9yYml0aW5nXG4gICAqICBjYW1lcmEgYSBkcmF3biByZWN0YW5nbGUgaGFzIG5vIGZpeGVkIG1lYW5pbmcgaW4gdGhlIGRhdGEuICovXG4gIGdldCBpc1NwYXRpYWwzZE1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzU3BhdGlhbE9taWNzM2QodGhpcy5zZWxlY3RlZFBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBMSU5FIHBsb3QgdHlwZSBzaG93cyB0aGUgaW1hZ2UgKyBkcmFnZ2FibGUgbGluZSBST0kgKyBpbnRlbnNpdHkgaW5zZXQuICovXG4gIGdldCBpc1Byb2ZpbGVNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkUGxvdFR5cGUgPT09IFBsb3RUeXBlLkxJTkU7XG4gIH1cblxuICAvKiogVHJ1ZSBmb3IgdGhlIEltYWdlIHBsb3QgdHlwZSwgd2hpY2ggcmVuZGVycyBhcyBhIG5hdGl2ZWx5IHBhbi96b29tLWFibGVcbiAgICogIHJhc3RlciDigJQgc28gdGhlIGJhY2tlbmQtYWdub3N0aWMgem9vbS9wYW4gdG9vbGJhciB0b29scyBhcmUgaGlkZGVuLiBUaGVcbiAgICogIGNvbXBvbmVudCBkcml2ZXMgdGhpcyBvZmYgdGhlIHBsb3QgdHlwZSwgbm90IHRoZSBhY3RpdmUgYmFja2VuZC4gKi9cbiAgZ2V0IGlzSW1hZ2VWaWV3KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFO1xuICB9XG5cbiAgLyoqIElzb3N1cmZhY2UgYmFuZCBhcyBhIDDigJMyNTUgc2xpZGVyIHBvc2l0aW9uLCBtYXBwZWQgb250byB0aGUgdm9sdW1lJ3MgcmVhbFxuICAgKiAgaW50ZW5zaXR5IHJhbmdlIGJ5IHRoZSByZW5kZXJlci4gRGVmYXVsdHMgdG8gdGhlIGZ1bGwgcmFuZ2UuICovXG4gIGlzb1JhbmdlOiBudW1iZXJbXSA9IFswLCAyNTVdO1xuXG4gIC8qKiBXaGV0aGVyIGEgc3BhdGlhbC1vbWljcyBkYXRhc2V0IGlzIGN1cnJlbnRseSBwdWJsaXNoZWQgb25cbiAgICogIGBTUEFUSUFMX0RBVEFfUE9SVGAg4oCUIGdhdGVzIHRoZSBzcGF0aWFsIHBsb3QgdHlwZXMgaW4gdGhlIHNlbGVjdG9yLiAqL1xuICBwcml2YXRlIGhhc1NwYXRpYWxEYXRhc2V0ID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoYXQgZGF0YXNldCdzIG9ic2VydmF0aW9ucyBjYXJyeSBhIHosIGdhdGluZyB0aGUgM0Qgc3BhdGlhbCBtb2RlLiAqL1xuICBwcml2YXRlIGhhc1NwYXRpYWwzZERhdGFzZXQgPSBmYWxzZTtcbiAgLyoqIFdoZXRoZXIgaXQgY2FycmllcyBhIHJlZ2lzdGVyZWQgdm9sdW1lLiBDaGFuZ2UgZGV0ZWN0aW9uIG9ubHk6IGEgdm9sdW1lXG4gICAqICBhcHBlYXJpbmcgaXMgd2hhdCBwdWJsaXNoZXMgaXQgYXMgdGhlIGltYWdlLCBhbmQgdGhlIHBsb3QtdHlwZSBnYXRlcyB0aGVuXG4gICAqICBzZWUgYW4gb3JkaW5hcnkgZ3JheXNjYWxlIHN0YWNrLiAqL1xuICBwcml2YXRlIGhhc1NwYXRpYWxWb2x1bWUgPSBmYWxzZTtcbiAgLyoqIERhdGFzZXQgaWRlbnRpdHkgKyBjYXBhYmlsaXR5IHNoYXBlIHRoZSBsYXN0IGVtaXNzaW9uIHdhcyBoYW5kbGVkIGF0LCBzbyBhXG4gICAqICBzd2l0Y2ggYmV0d2VlbiB0d28gZGF0YXNldHMgb2YgdGhlIHNhbWUgc2hhcGUgaXMgbm90IG1pc3Rha2VuIGZvciBhIHJlcGVhdC4gKi9cbiAgcHJpdmF0ZSBzcGF0aWFsRGF0YXNldEtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBEYXRhc2V0ICsgZ2VvbWV0cnkgdGhlIGN1cnJlbnRseSBwdWJsaXNoZWQgdm9sdW1lIGltYWdlIHdhcyBidWlsdCBmcm9tLCBzbyBhXG4gICAqICByZS1lbWl0dGVkIGRhdGFzZXQgZG9lc24ndCByZS1mZXRjaCBtZWdhYnl0ZXMgb3IgcmVzZXQgdGhlIHVzZXIncyBzY3J1Yi4gKi9cbiAgcHJpdmF0ZSB2b2x1bWVJbWFnZUtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBCbG9iIFVSTHMgYmFja2luZyB0aGF0IGltYWdlIOKAlCBvdXJzIHRvIHJldm9rZS4gKi9cbiAgcHJpdmF0ZSB2b2x1bWVJbWFnZVVybHM6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgc3BhdGlhbERhdGFzZXRTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgcGxvdFdpZHRoU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBpbWFnZUxvYWRpbmdTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gIGltZ0xvYWRpbmdNZXNzYWdlU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBpc1pvb21TdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gIGZpbGVuYW1lU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBhdXRvc2NhbGVTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgcHJpdmF0ZSBwbG90Q29udGV4dE1lbnVMaXN0ZW5lcj86IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIGtleWRvd25MaXN0ZW5lcj86IChlOiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIHdoZWVsTGlzdGVuZXI/OiAoZTogV2hlZWxFdmVudCkgPT4gdm9pZDtcblxuICAvKiogRGVib3VuY2VkIHotc2xpY2Ugc2NydWJiaW5nIChzZWUgU2xpY2VTY3J1YmJlciDigJQgcmVmYWN0b3JpbmcgcGxhbiBTdGVwIDcpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNjcnViYmVyID0gbmV3IFNsaWNlU2NydWJiZXIoKHopID0+IHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpJbmRleCh6KTtcbiAgICAvLyBJbiBhIHBlci1zbGljZSB6LXN0YWNrIHNlc3Npb24gdGhlIHN0b3JlIHN3YXBzIHRoZSBsaXZlIHJlZ2lvbiBzZXQgdG8gdGhpc1xuICAgIC8vIHNsaWNlIChwcmVzZXJ2aW5nIGVkaXRzIG1hZGUgb24gdGhlIHByZXZpb3VzIG9uZSk7IG91dHNpZGUgc3RhY2sgbW9kZSB0aGlzXG4gICAgLy8ganVzdCByZWNvcmRzIHRoZSBzbGljZSwgbGVhdmluZyBzaW5nbGUtcGxhbmUgcmVnaW9ucyB1bnRvdWNoZWQgKGppdC11aSM5MykuXG4gICAgdGhpcy5wbG90U2VydmljZS5zZXREaXNwbGF5U2xpY2Uoeik7XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoSU1BR0VfU1RBVEVfUE9SVCkgcHJpdmF0ZSBzdGF0ZTogSW1hZ2VTdGF0ZVBvcnQsXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwdWJsaWMgcGxvdFNlcnZpY2U6IElWaXN1YWxpemVyLFxuICAgIHB1YmxpYyBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBzZXNzaW9uOiBWaXN1YWxpemVyU3RvcmUsXG4gICAgcHJpdmF0ZSBzYW1Ub29sOiBTYW1Ub29sU2VydmljZSxcbiAgICBwcml2YXRlIGNlbGxTZWdtZW50VG9vbDogQ2VsbFNlZ21lbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHNhbVBvaW50VG9vbDogU2FtUG9pbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHJlZ2lvbk9wczogUmVnaW9uT3BzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFZJWl9DT05GSUcpIHByaXZhdGUgdml6Q29uZmlnPzogVml6Q29uZmlnLFxuICAgIC8vIEEgY29uc3RydWN0b3IgcGFyYW1ldGVyIHJhdGhlciB0aGFuIGEgZmllbGQgYGluamVjdCgpYDogdGhpcyBjb21wb25lbnQgaXNcbiAgICAvLyBhbHNvIGNvbnN0cnVjdGVkIGRpcmVjdGx5IHdpdGggYG5ld2AgaW4gaXRzIG93biBzcGVjcywgd2hpY2ggaXMgb3V0c2lkZVxuICAgIC8vIGFuIGluamVjdGlvbiBjb250ZXh0IGFuZCB3b3VsZCB0aHJvdyBORzAyMDMgb24gYSBmaWVsZCBpbml0aWFsaXplci5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRPT0xCQVJfVE9PTFMpIHRvb2xDb250cmlidXRpb25zPzogcmVhZG9ubHkgVG9vbGJhclRvb2xDb250cmlidXRpb25bXSxcbiAgICAvLyBPcHRpb25hbCBsaWtlIHRoZSByZXN0OiBhIGhvc3QgdGhhdCBzaG93cyBvbmx5IGltYWdlcyBuZXZlciBwcm92aWRlcyBpdCxcbiAgICAvLyBhbmQgdGhlIHNwYXRpYWwgcGxvdCB0eXBlcyBzaW1wbHkgc3RheSBoaWRkZW4uXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChTUEFUSUFMX0RBVEFfUE9SVCkgcHJpdmF0ZSBzcGF0aWFsRGF0YT86IFNwYXRpYWxEYXRhUG9ydCxcbiAgKSB7XG4gICAgdGhpcy5jb250cmlidXRlZFRvb2xzID0gdmlzaWJsZVRvb2xDb250cmlidXRpb25zKHRvb2xDb250cmlidXRpb25zKTtcbiAgICB0aGlzLmNvbG9ybWFwc09wdGlvbnMgPSBwbG90U2VydmljZS5nZXRDb2xvcm1hcE9wdGlvbnMoKTtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQbG90IHR5cGVzIG9mZmVyZWQgaW4gdGhlIHNlbGVjdG9yIGZvciB0aGUgY3VycmVudCBpbWFnZTpcbiAgICogIC0gT3V0c2lkZSAqKnRlc3QgbW9kZSoqLCBvbmx5IHRoZSBjdXJhdGVkIGRlZmF1bHQgc2V0IChkZXNjcmlwdG9ycyB3aXRoIGFcbiAgICogICAgYHByb2R1Y3Rpb25MYWJlbGApIGlzIG9mZmVyZWQsIHNob3duIHVuZGVyIHN1ZmZpeC1mcmVlIG5hbWVzIOKAlCBJbWFnZSxcbiAgICogICAgSGVhdG1hcCwgQ29udG91ciBhbmQgdGhlIG5hcGFyaSBTdXJmYWNlIC8gVm9sdW1lIC8gSXNvc3VyZmFjZS4gVGVzdCBtb2RlXG4gICAqICAgIGV4cG9zZXMgZXZlcnkgYmFja2VuZCdzIHR5cGUgdW5kZXIgaXRzIGZ1bGwgKGJhY2tlbmQtc3VmZml4ZWQpIGxhYmVsLlxuICAgKiAgLSAzRCB0eXBlcyBoaWRkZW4gd2hlbiB0aGUgYmFja2VuZCBjYW4ndCByZW5kZXIgYSAzRCBzY2VuZS5cbiAgICogIC0gc3RhY2stb25seSB0eXBlcyAodm9sdW1lLCBpc29zdXJmYWNlKSBoaWRkZW4gdW5sZXNzIHRoZSBmaWxlIGlzIGEgc3RhY2sg4oCUXG4gICAqICAgIGEgdm9sdW1lIG5lZWRzIG11bHRpcGxlIHotc2xpY2VzLlxuICAgKiAgLSBzY2FsYXItaW50ZW5zaXR5IHR5cGVzIChjb250b3VyLCBzdXJmYWNlLCBpc29zdXJmYWNlKSBoaWRkZW4gZm9yIFJHQlxuICAgKiAgICBpbWFnZXMg4oCUIHRoZXkgbWFwIGEgc2luZ2xlIGludGVuc2l0eSBwZXIgcGl4ZWwuIEltYWdlIGFuZCBIZWF0bWFwIHJlbmRlclxuICAgKiAgICBhbnkgaW1hZ2UuXG4gICAqICAtIHNwYXRpYWwtb21pY3MgdHlwZXMgaGlkZGVuIHVudGlsIGEgYFNwYXRpYWxEYXRhc2V0YCBpcyBwdWJsaXNoZWQgb25cbiAgICogICAgYFNQQVRJQUxfREFUQV9QT1JUYCDigJQgdGhlIG1vZGUgaGFzIG5vdGhpbmcgdG8gZHJhdyB3aXRob3V0IG9ic2VydmF0aW9ucyxcbiAgICogICAgZXhhY3RseSBhcyBhIHZvbHVtZSBoYXMgbm90aGluZyB0byBkcmF3IHdpdGhvdXQgYSBzdGFjay5cbiAgICovXG4gIC8qKlxuICAgKiBUcmFjayB3aGV0aGVyIGEgc3BhdGlhbC1vbWljcyBkYXRhc2V0IGlzIGF2YWlsYWJsZS4gQSBkYXRhc2V0IGFwcGVhcmluZyAob3JcbiAgICogYmVpbmcgY2xlYXJlZCkgY2hhbmdlcyB3aGljaCBwbG90IHR5cGVzIG1ha2Ugc2Vuc2UsIHNvIGl0IGRyaXZlcyB0aGUgc2FtZVxuICAgKiByZWNvbXB1dGUgKyByZWNvbmNpbGUgdGhhdCB0aGUgaW1hZ2Ugc3RyZWFtIGFuZCB0aGUgdGVzdC1tb2RlIHRvZ2dsZSBkby5cbiAgICpcbiAgICogTm8tb3Agd2hlbiB0aGUgaG9zdCBwcm92aWRlcyBubyBgU1BBVElBTF9EQVRBX1BPUlRgIOKAlCB0aGUgc3BhdGlhbCB0eXBlcyB0aGVuXG4gICAqIHN0YXkgaGlkZGVuIGZvciB0aGUgbGlmZSBvZiB0aGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJpdmF0ZSB3YXRjaFNwYXRpYWxEYXRhc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuc3BhdGlhbERhdGFzZXRTdWJzY3JpcHRpb24gPSB0aGlzLnNwYXRpYWxEYXRhPy5nZXREYXRhc2V0JCgpLnN1YnNjcmliZSgoZGF0YXNldCkgPT4ge1xuICAgICAgY29uc3QgaGFzID0gISFkYXRhc2V0O1xuICAgICAgLy8gT25seSBhIGRhdGFzZXQgd2hvc2Ugb2JzZXJ2YXRpb25zIGNhcnJ5IGEgeiBjYW4gYmUgZHJhd24gYXMgYSBjbG91ZCwgc29cbiAgICAgIC8vIHRoZSAzRCBtb2RlIGlzIGdhdGVkIG9uIHRoZSBjb29yZGluYXRlcywgbm90IG1lcmVseSBvbiBhIGRhdGFzZXQgYmVpbmdcbiAgICAgIC8vIHByZXNlbnQuIE1vc3Qgc3BhdGlhbCBhc3NheXMgYXJlIG9uZSBwbGFuZS5cbiAgICAgIGNvbnN0IGhhczNkID0gISFkYXRhc2V0Py5vYnNlcnZhdGlvbnMuejtcbiAgICAgIGNvbnN0IGhhc1ZvbHVtZSA9ICEhZGF0YXNldD8udm9sdW1lO1xuICAgICAgLy8gVGhlIHBvcnQgcHVibGlzaGVzIGl0cyBjdXJyZW50IHZhbHVlIG9uIHN1YnNjcmliZSwgc28gdGhlIGluaXRpYWwgYG51bGxgXG4gICAgICAvLyB3b3VsZCBvdGhlcndpc2UgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBmb3Igbm8gY2hhbmdlLiBLZXllZCBieSBkYXRhc2V0XG4gICAgICAvLyBJREVOVElUWSBhcyB3ZWxsIGFzIGNhcGFiaWxpdHkgc2hhcGU6IHR3byAzRCBkYXRhc2V0cyB0aGF0IGJvdGggY2FycnkgYVxuICAgICAgLy8gdm9sdW1lIGhhdmUgdGhlIHNhbWUgc2hhcGUsIGFuZCBjb21wYXJpbmcgb25seSB0aGF0IHNraXBwZWQgdGhlIHN3aXRjaCDigJRcbiAgICAgIC8vIGxlYXZpbmcgdGhlIHByZXZpb3VzIGRhdGFzZXQncyB2b2x1bWUgaW1hZ2Ugb24gc2NyZWVuIHVuZGVybmVhdGggdGhlIG5ld1xuICAgICAgLy8gb25lJ3Mgb2JzZXJ2YXRpb25zLlxuICAgICAgY29uc3Qga2V5ID0gZGF0YXNldFxuICAgICAgICA/IGAke2RhdGFzZXQuaWR9fCR7aGFzM2R9fCR7aGFzVm9sdW1lfXwke2RhdGFzZXQudm9sdW1lXG4gICAgICAgICAgPyBgJHtkYXRhc2V0LnZvbHVtZS53aWR0aH14JHtkYXRhc2V0LnZvbHVtZS5oZWlnaHR9eCR7ZGF0YXNldC52b2x1bWUuZGVwdGh9YCA6ICcnfWBcbiAgICAgICAgOiBudWxsO1xuICAgICAgaWYgKGtleSA9PT0gdGhpcy5zcGF0aWFsRGF0YXNldEtleSkgcmV0dXJuO1xuICAgICAgdGhpcy5zcGF0aWFsRGF0YXNldEtleSA9IGtleTtcbiAgICAgIHRoaXMuaGFzU3BhdGlhbERhdGFzZXQgPSBoYXM7XG4gICAgICB0aGlzLmhhc1NwYXRpYWwzZERhdGFzZXQgPSBoYXMzZDtcbiAgICAgIC8vIFdoZXRoZXIgdGhlIGRhdGFzZXQgc2F5cyBpdCByZWdpc3RlcnMgb250byBhIHRpc3N1ZSBpbWFnZS4gRGlzdGluY3QgZnJvbSBhblxuICAgICAgLy8gaW1hZ2UgYmVpbmcgTE9BREVEOiBhIHJlZ2lzdGVyZWQgZGF0YXNldCdzIGltYWdlIG1heSBzdGlsbCBiZSBvbiBpdHMgd2F5LCBhbmRcbiAgICAgIC8vIHRoZSBwaXhlbCBtb2RlcyBtdXN0IG5vdCBmbGlja2VyIG91dCBvZiB0aGUgc2VsZWN0b3Igd2hpbGUgaXQgYXJyaXZlcy5cbiAgICAgIC8vIEEgcmVnaXN0ZXJlZCBkYXRhc2V0IGRyYXdzIG92ZXIgYSB0aXNzdWUgaW1hZ2U7IGEgdm9sdW1lLWJhY2tlZCBvbmUgcHVibGlzaGVzIGl0c1xuICAgICAgLy8gdm9sdW1lIEFTIGEgZ3JheXNjYWxlIHotc3RhY2sgaW1hZ2UgKGBidWlsZFZvbHVtZVN0YWNrSW1hZ2VgKS4gRWl0aGVyIHdheSBwaXhlbHNcbiAgICAgIC8vIGV4aXN0LCBzbyB0aGUgcGl4ZWwgbW9kZXMgc3RheSBvbiBvZmZlciDigJQgVm9sdW1lIGFuZCBJc29zdXJmYWNlIGFyZSBleGFjdGx5IGhvd1xuICAgICAgLy8gYSAzRCBvbWljcyBkYXRhc2V0IGlzIHJlYWQuXG4gICAgICB0aGlzLnNwYXRpYWxEYXRhc2V0SGFzUGl4ZWxzID0gISFkYXRhc2V0Py5pbWFnZVJlZiB8fCBoYXNWb2x1bWU7XG4gICAgICB0aGlzLmhhc1NwYXRpYWxWb2x1bWUgPSBoYXNWb2x1bWU7XG4gICAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAgIC8vIEEgZGF0YXNldCB3aXRoIG5vIHJlZmVyZW5jZSBpbWFnZSBoYXMgbm90aGluZyB0byBkcmF3IG9ic2VydmF0aW9ucyBPVkVSOlxuICAgICAgLy8gYSBjbG91ZCByZWdpc3RlcmVkIGludG8gYSBjb21tb24gZnJhbWUgKHRoZSBBbGxlbiBDQ0YpIGhhcyBjb29yZGluYXRlc1xuICAgICAgLy8gYnV0IG5vIG9uZSBzZWN0aW9uLiBXaGF0IGl0IGRvZXMgaGF2ZSBpcyBpdHMgcmVnaXN0ZXJlZCBWT0xVTUUsIHdoaWNoIGlzXG4gICAgICAvLyBhIDNEIGltYWdlIGluIG9uZSBmaWxlIOKAlCBzbyBtYWtlIHRoYXQgdGhlIGltYWdlIGFuZCBvcGVuIG9uIGl0LCBzbGljZSBiYXJcbiAgICAgIC8vIGFuZCBhbGwsIHJhdGhlciB0aGFuIGxlYXZpbmcgdGhlIGhvc3Qgb24gYW4gSW1hZ2UgdmlldyBzaG93aW5nIHdoYXRldmVyXG4gICAgICAvLyBzbGlkZSB3YXMgbG9hZGVkIGJlZm9yZS4gT3JkZXJlZCBhZnRlciBjb21wdXRlUGxvdFR5cGVPcHRpb25zIHNvIHRoZSB0eXBlXG4gICAgICAvLyBpcyBvbiBvZmZlciBiZWZvcmUgaXQgaXMgc2VsZWN0ZWQuXG4gICAgICBpZiAoZGF0YXNldCAmJiAhZGF0YXNldC5pbWFnZVJlZiAmJiBoYXNWb2x1bWUpIHtcbiAgICAgICAgdm9pZCB0aGlzLnNob3dWb2x1bWVBc0ltYWdlKGRhdGFzZXQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQW55dGhpbmcgZWxzZSDigJQgYSBkYXRhc2V0IHdpdGggaXRzIG93biBzZWN0aW9uIGltYWdlLCBhIHZvbHVtZS1sZXNzXG4gICAgICAgIC8vIGNsb3VkLCBvciBub25lIGF0IGFsbCDigJQgbWVhbnMgYSBwdWJsaXNoZWQgdm9sdW1lIGltYWdlIGlzIG5vIGxvbmdlciB3aGF0XG4gICAgICAgIC8vIGlzIG9uIHNjcmVlbi4gRm9yZ2V0IGl0LCBvciBjb21pbmcgQkFDSyB0byB0aGUgdm9sdW1lIGRhdGFzZXQgd291bGRcbiAgICAgICAgLy8gc2hvcnQtY2lyY3VpdCBvbiBhIG1hdGNoaW5nIGtleSBhbmQgbGVhdmUgdGhlIG90aGVyIGRhdGFzZXQncyBzbGlkZSB1cC5cbiAgICAgICAgdGhpcy5kcm9wVm9sdW1lSW1hZ2UoKTtcbiAgICAgICAgaWYgKGRhdGFzZXQgJiYgIWRhdGFzZXQuaW1hZ2VSZWYpIHtcbiAgICAgICAgICAvLyBObyByZWZlcmVuY2UgaW1hZ2UgYW5kIG5vIHZvbHVtZSB0byBzbGljZTogdGhlIG9ic2VydmF0aW9ucyBhcmUgdGhlIG9ubHlcbiAgICAgICAgICAvLyB0aGluZyB0aGVyZSBpcyB0byBkcmF3LCBzbyBvcGVuIG9uIHdoaWNoZXZlciBzcGF0aWFsIG1vZGUgdGhlaXJcbiAgICAgICAgICAvLyBjb29yZGluYXRlcyBzdXBwb3J0LiBMZWF2aW5nIHRoZSB0eXBlIGFsb25lIHN0cmFuZHMgdGhlIGhvc3Qgb24gYW4gSW1hZ2VcbiAgICAgICAgICAvLyB2aWV3IHNob3dpbmcgd2hhdGV2ZXIgc2xpZGUgd2FzIGxvYWRlZCBCRUZPUkUg4oCUIHRoZSBvYnNlcnZhdGlvbnMgbmV2ZXJcbiAgICAgICAgICAvLyBhcHBlYXIsIGFuZCB0aGUgcHJldmlvdXMgZGF0YXNldCdzIHRpc3N1ZSBkb2VzLCB3aGljaCByZWFkcyBhcyB0aGlzXG4gICAgICAgICAgLy8gZGF0YXNldCBmYWlsaW5nIHRvIGxvYWQuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBHYXRlZCBvbiB0aGUgY29vcmRpbmF0ZXMsIG5vdCBvbiB0aGUgZGF0YXNldCBtZXJlbHkgZXhpc3Rpbmc6IGFcbiAgICAgICAgICAvLyBvbmUtcGxhbmUgYXNzYXkgaGFzIG5vIHogYW5kIGNhbm5vdCBiZSBhIGNsb3VkLiBUaGF0IGNhc2Ugb25seSB0dXJuZWQgdXBcbiAgICAgICAgICAvLyB3aXRoIGFuIGltYWdlLWxlc3MgMkQgZGF0YXNldCwgd2hpY2ggaXMgd2h5IGl0IHdlbnQgdW5oYW5kbGVkIOKAlCBiZWZvcmVcbiAgICAgICAgICAvLyBpdCwgaW1hZ2UtbGVzcyBtZWFudCAzRC5cbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBoYXMzZCA/IFBsb3RUeXBlLlNQQVRJQUxfT01JQ1NfM0QgOiBQbG90VHlwZS5TUEFUSUFMX09NSUNTO1xuICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkUGxvdFR5cGUgIT09IHRhcmdldCkgdGhpcy5vblNlbGVjdFBsb3RUeXBlKHRhcmdldCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIENsZWFyaW5nIHRoZSBkYXRhc2V0IHdoaWxlIGEgc3BhdGlhbCBtb2RlIGlzIGFjdGl2ZSBsZWF2ZXMgYSB0eXBlIHRoYXQgaXNcbiAgICAgIC8vIG5vIGxvbmdlciBvZmZlcmVkIOKAlCBmYWxsIGJhY2sgdG8gSW1hZ2UsIGFzIHR1cm5pbmcgdGVzdCBtb2RlIG9mZiBkb2VzLlxuICAgICAgdGhpcy5yZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlKCk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaCBhIGRhdGFzZXQncyByZWZlcmVuY2Ugdm9sdW1lIEFTIHRoZSBpbWFnZSwgYW5kIG9wZW4gdGhlIDJEIEltYWdlIHZpZXdcbiAgICogb24gaXQuXG4gICAqXG4gICAqIFRoZSB2b2x1bWUgaXMgYSAzRCBpbWFnZSBkZWxpdmVyZWQgaW4gb25lIGZpbGUsIHNvIGZvciBhIGRhdGFzZXQgdGhhdCBoYXMgbm9cbiAgICogc2VjdGlvbiBpbWFnZSBpdCBpcyB0aGUgaG9uZXN0IHRoaW5nIHRvIHB1dCBvbiBzY3JlZW46IHRoZSBzbGljZSBiYXIgc2NydWJzIHosXG4gICAqIGFuZCB0aGUgY29udHJhc3Qgd2luZG93LCBjb2xvcm1hcHMgYW5kIHJlZ2lvbiB0b29scyBhbGwgd29yayBiZWNhdXNlIHRoZVxuICAgKiB2b2x1bWUgZ2VudWluZWx5IGlzIHRoZSBpbWFnZSBub3cuIFRoZSAzRCBjbG91ZCBzdGF5cyBvbmUgbWVudSBwaWNrIGF3YXkuXG4gICAqXG4gICAqIEtleWVkIGJ5IGRhdGFzZXQgKyBnZW9tZXRyeTogdGhlIGRhdGFzZXQgc3RyZWFtIHJlLWVtaXRzIG9uIHRoaW5ncyBsaWtlIGFcbiAgICogY29sb3VyLWNvbHVtbiBjaGFuZ2UsIGFuZCByZWJ1aWxkaW5nIHRoZW4gd291bGQgcmUtZmV0Y2ggdGhlIHZveGVscyBhbmQgdGhyb3dcbiAgICogdGhlIHVzZXIgYmFjayB0byB0aGUgbWlkZGxlIHNsaWNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzaG93Vm9sdW1lQXNJbWFnZShkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1ldGEgPSBkYXRhc2V0LnZvbHVtZTtcbiAgICBpZiAoIW1ldGEgfHwgIXRoaXMuc3BhdGlhbERhdGE/LmdldFZvbHVtZSkgcmV0dXJuO1xuICAgIGNvbnN0IGtleSA9IGAke2RhdGFzZXQuaWR9OiR7bWV0YS53aWR0aH14JHttZXRhLmhlaWdodH14JHttZXRhLmRlcHRofWA7XG4gICAgaWYgKGtleSA9PT0gdGhpcy52b2x1bWVJbWFnZUtleSkgcmV0dXJuO1xuICAgIC8vIENsYWltIHRoZSBrZXkgQkVGT1JFIGF3YWl0aW5nOiB0aGUgc3RyZWFtIGNhbiBlbWl0IGFnYWluIHdoaWxlIHRoZSB2b3hlbHNcbiAgICAvLyBhcmUgaW4gZmxpZ2h0LCBhbmQgdHdvIGJ1aWxkcyBvZiB0aGUgc2FtZSB2b2x1bWUgd291bGQgcmFjZSB0byBwdWJsaXNoLlxuICAgIHRoaXMudm9sdW1lSW1hZ2VLZXkgPSBrZXk7XG4gICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcodHJ1ZSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJ1aWx0ID0gYXdhaXQgYnVpbGRWb2x1bWVTdGFja0ltYWdlKGRhdGFzZXQsIGF3YWl0IHRoaXMuc3BhdGlhbERhdGEuZ2V0Vm9sdW1lKCkpO1xuICAgICAgLy8gQSBkaWZmZXJlbnQgZGF0YXNldCB3YXMgc2VsZWN0ZWQgd2hpbGUgdGhpcyBvbmUgZW5jb2RlZCDigJQgaXRzIGltYWdlIGlzIHRoZVxuICAgICAgLy8gb25lIHRoYXQgYmVsb25ncyBvbiBzY3JlZW4sIHNvIGRyb3Agd2hhdCB3ZSBqdXN0IGJ1aWx0LlxuICAgICAgaWYgKHRoaXMudm9sdW1lSW1hZ2VLZXkgIT09IGtleSkge1xuICAgICAgICBidWlsdD8udXJscy5mb3JFYWNoKCh1KSA9PiBVUkwucmV2b2tlT2JqZWN0VVJMKHUpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFidWlsdCkge1xuICAgICAgICB0aGlzLnZvbHVtZUltYWdlS2V5ID0gbnVsbDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gUGljayB0aGUgbW9kZSBmaXJzdCBzbyB0aGUgaW1hZ2UgbGFuZHMgaW4gdGhlIHZpZXcgdGhhdCB3aWxsIHNob3cgaXQsXG4gICAgICAvLyBpbnN0ZWFkIG9mIHJlbmRlcmluZyBvbmNlIGludG8gd2hhdGV2ZXIgbW9kZSB0aGUgbGFzdCBkYXRhc2V0IGxlZnQgYWN0aXZlLlxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRQbG90VHlwZSAhPT0gUGxvdFR5cGUuSU1BR0UpIHRoaXMub25TZWxlY3RQbG90VHlwZShQbG90VHlwZS5JTUFHRSk7XG4gICAgICB0aGlzLnJldm9rZVZvbHVtZUltYWdlVXJscygpO1xuICAgICAgdGhpcy52b2x1bWVJbWFnZVVybHMgPSBidWlsdC51cmxzO1xuICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUluZm8oYnVpbHQuaW5mbyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBObyB2b2x1bWUgc2VydmVkIGFmdGVyIGFsbDogdGhlIGNsb3VkIGlzIHN0aWxsIHJlbmRlcmFibGUsIHNvIGZhbGwgYmFjayB0b1xuICAgICAgLy8gaXQgcmF0aGVyIHRoYW4gbGVhdmluZyB0aGUgaG9zdCBvbiBhbiBJbWFnZSB2aWV3IHdpdGggbm90aGluZyBpbiBpdC5cbiAgICAgIGNvbnNvbGUud2FybignW3Zpc3VhbGl6ZXJdIHJlZmVyZW5jZSB2b2x1bWUgdW5hdmFpbGFibGUg4oCUIGZhbGxpbmcgYmFjayB0byB0aGUgM0QgY2xvdWQnLCBlcnIpO1xuICAgICAgdGhpcy52b2x1bWVJbWFnZUtleSA9IG51bGw7XG4gICAgICBpZiAodGhpcy5oYXNTcGF0aWFsM2REYXRhc2V0ICYmICFpc1NwYXRpYWxPbWljczNkKHRoaXMuc2VsZWN0ZWRQbG90VHlwZSkpIHtcbiAgICAgICAgdGhpcy5vblNlbGVjdFBsb3RUeXBlKFBsb3RUeXBlLlNQQVRJQUxfT01JQ1NfM0QpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhmYWxzZSk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEZvcmdldCB0aGUgcHVibGlzaGVkIHZvbHVtZSBpbWFnZSBzbyByZS1zZWxlY3RpbmcgdGhlIGRhdGFzZXQgcmVidWlsZHMgaXQuXG4gICAqICBUaGUgVVJMcyBkZWxpYmVyYXRlbHkgc3RheSBhbGl2ZTogdGhlIGhvc3QgbWF5IHN0aWxsIGJlIGRpc3BsYXlpbmcgdGhhdCBpbWFnZVxuICAgKiAgYXQgdGhpcyBpbnN0YW50LCBhbmQgcmV2b2tpbmcgdW5kZXIgaXQgd291bGQgYnJlYWsgZXZlcnkgbGF0ZXIgdGlsZSByZWFkLiBUaGV5XG4gICAqICBhcmUgZnJlZWQgd2hlbiB0aGUgbmV4dCB2b2x1bWUgcmVwbGFjZXMgdGhlbSwgb3Igb24gZGVzdHJveS4gKi9cbiAgcHJpdmF0ZSBkcm9wVm9sdW1lSW1hZ2UoKTogdm9pZCB7XG4gICAgdGhpcy52b2x1bWVJbWFnZUtleSA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIHJldm9rZVZvbHVtZUltYWdlVXJscygpOiB2b2lkIHtcbiAgICB0aGlzLnZvbHVtZUltYWdlVXJscy5mb3JFYWNoKCh1KSA9PiBVUkwucmV2b2tlT2JqZWN0VVJMKHUpKTtcbiAgICB0aGlzLnZvbHVtZUltYWdlVXJscyA9IFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlUGxvdFR5cGVPcHRpb25zKCkge1xuICAgIGNvbnN0IGNhcHMgPSB0aGlzLnBsb3RTZXJ2aWNlLmNhcGFiaWxpdGllcztcbiAgICBjb25zdCBpc1N0YWNrID0gISF0aGlzLmltYWdlSW5mbz8uaXNTdGFjaztcbiAgICBjb25zdCBpc0dyYXlzY2FsZSA9ICEhdGhpcy5pbWFnZUluZm8/LmlzR3JheXNjYWxlO1xuICAgIC8vIEEgbXVsdGljaGFubmVsIGltYWdlJ3MgYmFuZHMgYXJlIGVhY2ggc2luZ2xlLWJhbmQgKHNjYWxhciksIHNvIHRoZSBzY2FsYXJcbiAgICAvLyBwbG90IG1vZGVzIChIZWF0bWFwIC8gU3VyZmFjZSAvIFZvbHVtZSAvIElzb3N1cmZhY2UpIGFwcGx5IHBlciBjaGFubmVsIGV2ZW5cbiAgICAvLyB0aG91Z2ggdGhlIFJHQiBjb21wb3NpdGUgaXNuJ3QgZ3JheXNjYWxlIOKAlCBkb24ndCBnYXRlIHRoZW0gb3V0LlxuICAgIGNvbnN0IG0wID0gdGhpcy5pbWFnZUluZm8/LmltYWdlTWV0YT8uWzBdO1xuICAgIGNvbnN0IGlzTXVsdGljaGFubmVsID0gKG0wPy5jaGFubmVsQ291bnQgPz8gMSkgPiAxICYmIChtMD8ucmdiQ2hhbm5lbHMgPz8gMSkgPCAzO1xuICAgIHRoaXMucGxvdFR5cGVPcHRpb25zID0gdGhpcy5wbG90U2VydmljZS5nZXRQbG90VHlwZURlc2NyaXB0b3JzKClcbiAgICAgIC5maWx0ZXIoKGQpID0+IHtcbiAgICAgICAgLy8gT3V0c2lkZSB0ZXN0IG1vZGUsIG9ubHkgdGhlIGN1cmF0ZWQgc2V0ICh0aG9zZSB3aXRoIGEgcHJvZHVjdGlvbkxhYmVsKVxuICAgICAgICAvLyBpcyBvZmZlcmVkOyB0ZXN0IG1vZGUgZXhwb3NlcyBldmVyeSBiYWNrZW5kJ3MgdHlwZS5cbiAgICAgICAgaWYgKCF0aGlzLnRlc3RNb2RlICYmICFkLnByb2R1Y3Rpb25MYWJlbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZC5kaW1lbnNpb25zID09PSAnM2QnICYmICFjYXBzLmhhcyhWaWV3ZXJGZWF0dXJlLlN1cmZhY2UzRCkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gVm9sdW1lIGFuZCBJc29zdXJmYWNlIHJheW1hcmNoIHRoZSBJTUFHRSBTVEFDSywgYW5kIG5vdGhpbmcgZWxzZTogdGhlc2VcbiAgICAgICAgLy8gdHdvIGdhdGVzIGFyZSBhYm91dCB0aGUgbG9hZGVkIGltYWdlLCBmdWxsIHN0b3AuIEEgM0Qgb21pY3MgZGF0YXNldFxuICAgICAgICAvLyByZWFjaGVzIHRoZW0gYmVjYXVzZSBpdHMgcmVnaXN0ZXJlZCB2b2x1bWUgaXMgcHVibGlzaGVkIEFTIGEgZ3JheXNjYWxlXG4gICAgICAgIC8vIHotc3RhY2sgaW1hZ2UgKGBidWlsZFZvbHVtZVN0YWNrSW1hZ2VgKSwgbm90IHRocm91Z2ggYSBzZWNvbmQgdm94ZWxcbiAgICAgICAgLy8gc291cmNlIGhpZGluZyBiZWhpbmQgdGhlIHNhbWUgbW9kZXMuXG4gICAgICAgIGlmIChkLnJlcXVpcmVzU3RhY2sgJiYgIWlzU3RhY2spIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGQucmVxdWlyZXNHcmF5c2NhbGUgJiYgIWlzR3JheXNjYWxlICYmICFpc011bHRpY2hhbm5lbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZC5yZXF1aXJlc1NwYXRpYWxEYXRhICYmICF0aGlzLmhhc1NwYXRpYWxEYXRhc2V0KSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkLnJlcXVpcmVzU3BhdGlhbDNkICYmICF0aGlzLmhhc1NwYXRpYWwzZERhdGFzZXQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gQW4gaW1hZ2Utc291cmNlZCBtb2RlIHJlYWRzIFBJWEVMUy4gQSBzcGF0aWFsIGRhdGFzZXQgdGhhdCBicmluZ3Mgbm8gdGlzc3VlXG4gICAgICAgIC8vIGltYWdlIChzZXFGSVNIIHJlY29yZHMgdW5pdGxlc3MgY29vcmRpbmF0ZXMsIG5vdCBhIHNlY3Rpb24pIGxlYXZlcyBub3RoaW5nIGZvclxuICAgICAgICAvLyBvbmUgdG8gZHJhdywgc28gb2ZmZXJpbmcgSW1hZ2UgLyBIZWF0bWFwIC8gU3VyZmFjZSB0aGVyZSBvZmZlcnMgbW9kZXMgdGhhdCBjYW5cbiAgICAgICAgLy8gb25seSBjb21lIHVwIGJsYW5rIOKAlCBvciB3b3JzZSwgc2hvd2luZyB3aGF0ZXZlciBzbGlkZSB3YXMgbG9hZGVkIGJlZm9yZS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gTmFycm93ZWQgdG8gXCJhIGRhdGFzZXQgaXMgdXAgQU5EIHRoZXJlIGlzIG5vIGltYWdlXCI6IHdpdGggbm8gZGF0YXNldCBhdCBhbGwsXG4gICAgICAgIC8vIEltYWdlIHN0YXlzIG9uIG9mZmVyLCBiZWNhdXNlIGEgaG9zdCB0aGF0IGhhcyBub3QgbG9hZGVkIGFueXRoaW5nIHlldCBuZWVkcyBhXG4gICAgICAgIC8vIGRlZmF1bHQgYW5kIGFuIGVtcHR5IHNlbGVjdG9yIHdvdWxkIGJlIHdvcnNlIHRoYW4gYSBibGFuayB2aWV3LlxuICAgICAgICBpZiAoZC5zb3VyY2UgPT09ICdpbWFnZScgJiYgdGhpcy5oYXNTcGF0aWFsRGF0YXNldFxuICAgICAgICAgICYmICF0aGlzLnNwYXRpYWxEYXRhc2V0SGFzUGl4ZWxzKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSlcbiAgICAgIC8vIERlZmF1bHQgc2VsZWN0b3Igc2hvd3MgdGhlIHN1ZmZpeC1mcmVlIHByb2R1Y3Rpb25MYWJlbDsgdGVzdCBtb2RlIGtlZXBzXG4gICAgICAvLyB0aGUgZnVsbCBiYWNrZW5kLXN1ZmZpeGVkIGxhYmVsIHNvIHNhbWUtbmFtZWQgbW9kZXMgc3RheSBkaXN0aW5ndWlzaGFibGUuXG4gICAgICAubWFwKChkKSA9PiAodGhpcy50ZXN0TW9kZSA/IGQgOiB7IC4uLmQsIGxhYmVsOiBkLnByb2R1Y3Rpb25MYWJlbCEgfSkpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBjb21wdXRlcyB0aGUgb3B0aW9ucyB3aXRoIHRlc3RNb2RlIHN0aWxsIGF0IGl0cyBkZWZhdWx0O1xuICAgIC8vIHJlY29tcHV0ZSBvbmNlIHRoZSBob3N0IGJpbmRzIGl0IChhbmQgb24gYW55IGxhdGVyIGNoYW5nZSkgc28gdGhlIHNlbGVjdG9yXG4gICAgLy8gcmVmbGVjdHMgdGVzdCBtb2RlIGltbWVkaWF0ZWx5LCB3aXRob3V0IHdhaXRpbmcgZm9yIGFuIGltYWdlIHRvIChyZSlsb2FkLlxuICAgIGlmIChjaGFuZ2VzWyd0ZXN0TW9kZSddKSB7XG4gICAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAgIC8vIElmIHRlc3QgbW9kZSBpcyB0dXJuZWQgb2ZmIHdoaWxlIGEgdGVzdC1vbmx5IHR5cGUgKGUuZy4gTkFQQVJJX0lNQUdFKSBpc1xuICAgICAgLy8gYWN0aXZlLCB0aGF0IHR5cGUgaXMgbm8gbG9uZ2VyIG9mZmVyZWQg4oCUIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBJZiB0aGUgYWN0aXZlIHBsb3QgdHlwZSBpcyBubyBsb25nZXIgaW4gdGhlIG9mZmVyZWQgb3B0aW9ucyAoZS5nLiB0ZXN0IG1vZGVcbiAgICogIHR1cm5lZCBvZmYgd2hpbGUgYSB0ZXN0LW9ubHkgdHlwZSB3YXMgYWN0aXZlLCBvciBhIHNjYWxhciB0eXBlIGNhcnJpZWQgb250b1xuICAgKiAgYW4gUkdCIGltYWdlKSwgZmFsbCBiYWNrIHRvIHRoZSBkZWZhdWx0IDJEIEltYWdlIHZpZXcuICovXG4gIC8qKiBXaGV0aGVyIHRoZSBsaXZlIHNwYXRpYWwgZGF0YXNldCBicmluZ3MgcGl4ZWxzIG9mIGl0cyBvd24g4oCUIGEgdGlzc3VlIGltYWdlIGl0XG4gICAqICByZWdpc3RlcnMgb250bywgb3IgYSB2b2x1bWUgdGhhdCBpcyBwdWJsaXNoZWQgYXMgYSB6LXN0YWNrIGltYWdlLiAqL1xuICBwcml2YXRlIHNwYXRpYWxEYXRhc2V0SGFzUGl4ZWxzID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFRoZSBob3N0IHB1Ymxpc2hlZCBOTyBpbWFnZSDigJQgYSBzcGF0aWFsIGRhdGFzZXQgdGhhdCBicmluZ3Mgbm9uZSBkb2VzIHRoaXMuXG4gICAqXG4gICAqIFdpdGhvdXQgaGFuZGxpbmcgdGhlIGVtcHR5IGVtaXNzaW9uLCBgaW1hZ2VJbmZvYCBrZWVwcyB0aGUgTEFTVCBpbWFnZSdzIG1ldGFkYXRhOiB0aGVcbiAgICogc2VsZWN0b3IgZ29lcyBvbiBvZmZlcmluZyBwaXhlbCBtb2RlcyBmb3IgcGl4ZWxzIHRoYXQgYXJlIGdvbmUsIGFuZCBldmVyeVxuICAgKiBgaXNTdGFja2AvYGlzR3JheXNjYWxlYCBkZWNpc2lvbiBpcyBtYWRlIGFnYWluc3QgYSBmaWxlIHRoYXQgaXMgbm8gbG9uZ2VyIGxvYWRlZC5cbiAgICovXG4gIHByaXZhdGUgb25JbWFnZUNsZWFyZWQoKTogdm9pZCB7XG4gICAgdGhpcy5pbWFnZUluZm8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2FkZWRGaWxlTmFtZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAvLyBEZWxpYmVyYXRlbHkgTk9UIHJlY29uY2lsaW5nIHRoZSBzZWxlY3RlZCB0eXBlIGhlcmUuIFJlY29uY2lsaW5nIGNhbGxzXG4gICAgLy8gYHNldFBsb3RUeXBlYCwgd2hpY2ggZHJpdmVzIGEgcmUtcGxvdCDigJQgYW5kIHRoZXJlIGlzIG5vdGhpbmcgdG8gcGxvdCwgc28gdGhlXG4gICAgLy8gUGxvdGx5IGJhY2tlbmQgcmVhZCBpdHMgb3duIG5vdy11bnNldCBgaW1hZ2VJbmZvYCBhbmQgdGhyZXdcbiAgICAvLyAoXCJjYW4ndCBhY2Nlc3MgcHJvcGVydHkgaXNHcmF5c2NhbGVcIiksIGFib3J0aW5nIHRoZSBsb2FkIHdpdGggbm8gb2JzZXJ2YXRpb25zXG4gICAgLy8gZHJhd24uIElnbm9yaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiBlbnRpcmVseSBpcyB3aGF0IHVzZWQgdG8gYXZvaWQgdGhhdC5cbiAgICAvL1xuICAgIC8vIE5vdGhpbmcgaXMgbGVmdCBzdHJhbmRlZDogYW4gaW1hZ2UgaXMgY2xlYXJlZCBiZWNhdXNlIGEgc3BhdGlhbCBkYXRhc2V0IHRoYXRcbiAgICAvLyBicmluZ3Mgbm9uZSBpcyBiZWluZyBvcGVuZWQsIGFuZCB0aGF0IGRhdGFzZXQncyBvd24gc3Vic2NyaXB0aW9uIHNlbGVjdHMgdGhlXG4gICAgLy8gbW9kZSBpdHMgY29vcmRpbmF0ZXMgc3VwcG9ydCBhIG1vbWVudCBsYXRlci5cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIHJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucGxvdFR5cGVPcHRpb25zLnNvbWUoKGQpID0+IGQudHlwZSA9PT0gdGhpcy5zZWxlY3RlZFBsb3RUeXBlKSkgcmV0dXJuO1xuICAgIC8vIEltYWdlIGlzIHRoZSB1c3VhbCBmYWxsYmFjaywgYnV0IGl0IGlzIG5vdCBhbHdheXMgT04gT0ZGRVI6IHdpdGggbm8gaW1hZ2UgbG9hZGVkXG4gICAgLy8gdGhlIHBpeGVsIG1vZGVzIGFyZSBnb25lLCBhbmQgZmFsbGluZyBiYWNrIHRvIG9uZSB3b3VsZCBzZWxlY3QgYSBtb2RlIHRoZSBzZWxlY3RvclxuICAgIC8vIGRvZXMgbm90IGxpc3QgYW5kIG5vdGhpbmcgY2FuIGRyYXcuIFRha2UgdGhlIGZpcnN0IHR5cGUgc3RpbGwgb2ZmZXJlZCBpbnN0ZWFkLlxuICAgIGNvbnN0IGZhbGxiYWNrID0gdGhpcy5wbG90VHlwZU9wdGlvbnMuc29tZSgoZCkgPT4gZC50eXBlID09PSBQbG90VHlwZS5JTUFHRSlcbiAgICAgID8gUGxvdFR5cGUuSU1BR0VcbiAgICAgIDogdGhpcy5wbG90VHlwZU9wdGlvbnNbMF0/LnR5cGU7XG4gICAgaWYgKCFmYWxsYmFjaykgcmV0dXJuO1xuICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZSA9IGZhbGxiYWNrO1xuICAgIHRoaXMucGxvdFR5cGUgPSBmYWxsYmFjaztcbiAgICB0aGlzLmlzSGVhdG1hcCA9IGZhbGxiYWNrID09PSBQbG90VHlwZS5JTUFHRTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKGZhbGxiYWNrKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEpvaW4gdGhlIGxpdmUgc2V0OyB0aGUgb2xkZXN0IG1lbWJlciByZW5kZXJzIHRoZSBzaGFyZWQgbm90aWNlIG91dGxldHMuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmFkZCh0aGlzKTtcbiAgICB0aGlzLnN0YXRlLnNldERpYWdyYW0odGhpcyk7XG4gICAgdGhpcy5zZWxlY3RlZENvbG9ybWFwID1cbiAgICAgIHRoaXMuY29sb3JtYXBzT3B0aW9uc1swXS5jaGlsZHJlbi5maW5kKChjOiBhbnkpID0+IGMubGFiZWwgPT09ICdHcmV5cyBJbnYnKSA/P1xuICAgICAgdGhpcy5jb2xvcm1hcHNPcHRpb25zWzBdLmNoaWxkcmVuWzBdO1xuICAgIHRoaXMuc3RhY2tPcHRpb25zID0gW1xuICAgICAgeyBuYW1lOiAnU2luZ2xlIGltYWdlJywgdmFsOiAnZmFsc2UnIH0sXG4gICAgICB7IG5hbWU6ICdTdGFjaycsIHZhbDogJ3RydWUnIH0sXG4gICAgXTtcbiAgICB0aGlzLnNlbGVjdGVkU3RhY2tPcHRpb24gPSB0aGlzLnN0YWNrT3B0aW9uc1swXTtcbiAgICB0aGlzLndhdGNoU3BhdGlhbERhdGFzZXQoKTtcbiAgICB0aGlzLmF1dG9zY2FsZVN1YnNjcmlwdGlvbiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0QXV0b3NjYWxlRXZlbnQoKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgLy8gcmVzZXQgdGhlIGltYWdlIG1vZGUgdG8gc2luZ2xlIGltYWdlXG4gICAgICB0aGlzLnNlbGVjdGVkU3RhY2tPcHRpb24gPSB7IG5hbWU6ICdTaW5nbGUgaW1hZ2UnLCB2YWw6ICdmYWxzZScgfTtcbiAgICAgIHRoaXMuYWN0aXZlRHJhZ01vZGUgPSBudWxsO1xuICAgICAgdGhpcy5zZXNzaW9uLnNldEFjdGl2ZVRvb2wobnVsbCk7XG4gICAgfSk7XG4gICAgdGhpcy5pbWFnZUxvYWRpbmdTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmlzSW1hZ2VMb2FkaW5nJCgpLnN1YnNjcmliZSgoaXNJbWFnZUxvYWRpbmcpID0+IHtcbiAgICAgIHRoaXMuaW1nTG9hZGluZyA9IGlzSW1hZ2VMb2FkaW5nO1xuICAgIH0pO1xuICAgIC8vIFVuZG8gYXZhaWxhYmlsaXR5IChqaXQtdWkjODUpOiB0aGUgc2hhcmVkIFJlZ2lvblN0b3JlIGVtaXRzIHdoZW5ldmVyIGl0c1xuICAgIC8vIGhpc3RvcnkgZGVwdGggY2hhbmdlczsgZ3JleXMgb3V0IHRoZSB0b29sYmFyIFVuZG8gYnV0dG9uIGFjY29yZGluZ2x5LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRDYW5VbmRvJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YikpXG4gICAgICAuc3Vic2NyaWJlKChjYW5VbmRvKSA9PiB7XG4gICAgICAgIHRoaXMuY2FuVW5kb1JlZ2lvbiA9IGNhblVuZG87XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRDYW5SZWRvJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YikpXG4gICAgICAuc3Vic2NyaWJlKChjYW5SZWRvKSA9PiB7XG4gICAgICAgIHRoaXMuY2FuUmVkb1JlZ2lvbiA9IGNhblJlZG87XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pO1xuICAgIC8vIE1pcnJvciB0aGUgcmVnaW9uIHNlbGVjdGlvbiBzbyB0aGUgcmlnaHQtY2xpY2sgYWN0aW9uIGdyb3VwIChqaXQtdWkjODUpXG4gICAgLy8gY2FuIHJlYWQgaXQgc3luY2hyb25vdXNseSB3aGVuIHRoZSBtZW51IGlzIGJ1aWx0LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMudW5zdWIpKVxuICAgICAgLnN1YnNjcmliZSgoaW5kaWNlcykgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkSW5kaWNlcyA9IGluZGljZXMgfHwgW107XG4gICAgICB9KTtcbiAgICAvLyBJbnRlcmFjdGl2ZSBwb2ludC1wcm9tcHQgc2VnbWVudGF0aW9uIHJ1bnMgaW5zaWRlIHRoZSByZW5kZXJlciBvbiBlYWNoXG4gICAgLy8gY2xpY2s7IHN1cmZhY2UgaXRzIGxpdmUgc3RhdHVzICsgZG93bmxvYWQgcHJvZ3Jlc3MgaW4gdGhlIHNoYXJlZCBgc2FtYFxuICAgIC8vIHRvYXN0IHNvIHRoZSB1c2VyIHNlZXMgaXQgd29ya2luZyAodGhlIGZpcnN0IGNsaWNrIHB1bGxzIHRoZSBlbmNvZGVyKS5cbiAgICB0aGlzLnNhbVBvaW50U3ViLmFkZChcbiAgICAgIHRoaXMuc2FtUG9pbnRUb29sLnByb2dyZXNzJC5zdWJzY3JpYmUoKGYpID0+IHtcbiAgICAgICAgdGhpcy5zYW1Eb3dubG9hZGluZyA9IGYgPj0gMCAmJiBmIDwgMTtcbiAgICAgICAgaWYgKGYgPj0gMCkgdGhpcy5zYW1Qcm9ncmVzcyA9IE1hdGgubWluKDEwMCwgTWF0aC5yb3VuZChmICogMTAwKSk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zYW1Qb2ludFN1Yi5hZGQoXG4gICAgICB0aGlzLnNhbVBvaW50VG9vbC5zdGF0dXMkLnN1YnNjcmliZSgobSkgPT4ge1xuICAgICAgICB0aGlzLnNhbVN0YXR1cyA9IG07XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zYW1Qb2ludFN1Yi5hZGQoXG4gICAgICB0aGlzLnNhbVBvaW50VG9vbC5idXN5JC5zdWJzY3JpYmUoKGJ1c3kpID0+IHtcbiAgICAgICAgdGhpcy5zYW1CdXN5ID0gYnVzeTtcbiAgICAgICAgaWYgKGJ1c3kpIHRoaXMuc2hvd1NhbVRvYXN0KCdTQU0gcG9pbnQgc2VnbWVudGF0aW9uJyk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdGFja0xvYWRpbmdQcm9ncmVzcygpLnN1YnNjcmliZSgobG9hZGluZ1Byb2dyZXNzKSA9PiB7XG4gICAgICB0aGlzLmxvYWRpbmdQZXJjZW50YWdlID0gbG9hZGluZ1Byb2dyZXNzO1xuICAgIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuaXNTdGFja0xvYWRpbmcoKS5zdWJzY3JpYmUoKHN0YWNrTG9hZGluZykgPT4ge1xuICAgICAgdGhpcy5zdGFja0xvYWRpbmcgPSBzdGFja0xvYWRpbmc7XG4gICAgfSk7XG4gICAgdGhpcy5wbG90V2lkdGhTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmdldFBhbmVsV2lkdGgkKCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVsYXlvdXQoKTtcbiAgICAgIC8vIFRoZSBpbnRlbnNpdHkgaW5zZXQgaXMgYSBzZXBhcmF0ZSBQbG90bHkgY2hhcnQgaW4gYSBmbG9hdGluZyBwYW5lbDsgcmVmbG93XG4gICAgICAvLyBpdCB0byBpdHMgY3VycmVudCBzaXplIHdoZW4gdGhlIGNhbnZhcyByZXNpemVzLCBlbHNlIGl0IGtlZXBzIHRoZSBzdGFsZVxuICAgICAgLy8gc2l6ZSBhbmQgYmxhbmtzIG91dC4gRGVmZXIgYSB0aWNrIHNvIHRoZSBwYW5lbCBsYXlvdXQgaGFzIHNldHRsZWQuXG4gICAgICBpZiAodGhpcy5oYXNQcm9maWxlcykge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVuZGVySW50ZW5zaXR5SW5zZXQoKSwgMCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5pbWdMb2FkaW5nTWVzc2FnZVN1YnNjcmlwdGlvbiA9IHRoaXMuc3RhdGUuZ2V0SW1hZ2VMb2FkaW5nTWVzc2FnZSQoKS5zdWJzY3JpYmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgIHRoaXMubG9hZGluZ01lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH0pO1xuICAgIHRoaXMuc3RhdGVcbiAgICAgIC5nZXRDYWNoZVByb2dyZXNzJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YikpXG4gICAgICAuc3Vic2NyaWJlKChwcm9ncmVzcykgPT4ge1xuICAgICAgICB0aGlzLmNhY2hlUHJvZ3Jlc3MgPSBwcm9ncmVzcztcbiAgICAgIH0pO1xuICAgIHRoaXMuaXNab29tU3Vic2NyaXB0aW9uID0gdGhpcy5zdGF0ZS5pc1pvb20kKCkuc3Vic2NyaWJlKCh6b29tKSA9PiB7XG4gICAgICB0aGlzLnpvb20gPSB6b29tO1xuICAgIH0pO1xuICAgIHRoaXMuZmlsZW5hbWVTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmdldEZpbGVuYW1lJCgpLnN1YnNjcmliZSgoZmlsZW5hbWUpID0+IHtcbiAgICAgIGlmIChmaWxlbmFtZSkge1xuICAgICAgICB0aGlzLmZpbGVOYW1lID0gZmlsZW5hbWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRDb2xvcm1hcCgpLnN1YnNjcmliZSgoY29sb3JtYXApID0+IHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDb2xvcm1hcCA9IGNvbG9ybWFwO1xuICAgIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmV2ZXJzZVNjYWxlKCkuc3Vic2NyaWJlKChyZXZlcnNlc2NhbGUpID0+IHtcbiAgICAgIHRoaXMucmV2ZXJzZXNjYWxlID0gcmV2ZXJzZXNjYWxlO1xuICAgIH0pO1xuICAgIHRoaXMuaW50ZW5zaXR5UHJvZmlsZVN1YiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0SW50ZW5zaXR5UHJvZmlsZSQoKS5zdWJzY3JpYmUoKHByb2ZpbGVzKSA9PiB7XG4gICAgICB0aGlzLmxhdGVzdFByb2ZpbGVzID0gcHJvZmlsZXM7XG4gICAgICB0aGlzLmhhc1Byb2ZpbGVzID0gcHJvZmlsZXMubGVuZ3RoID4gMDtcbiAgICAgIC8vIFRoZSBwYW5lbCBkaXYgaXMgYmVoaW5kICpuZ0lmPVwiaGFzUHJvZmlsZXNcIi4gZGV0ZWN0Q2hhbmdlcygpIG1hdGVyaWFsaXplc1xuICAgICAgLy8gaXQgc3luY2hyb25vdXNseSAodGhlIHN1YnNjcmlwdGlvbiBtYXkgZmlyZSBvdXRzaWRlIEFuZ3VsYXIncyB6b25lIOKAlCBlLmcuXG4gICAgICAvLyBmcm9tIGFuIE9TRCBkcmFnIOKAlCBzbyBDRCB3b3VsZG4ndCBydW4gb24gaXRzIG93bikuIFRoZW4gcmVuZGVyIG9uIHRoZSBuZXh0XG4gICAgICAvLyBhbmltYXRpb24gZnJhbWUsIEFGVEVSIHRoZSBicm93c2VyIGxheXMgdGhlIHBhbmVsIG91dDogYSBzeW5jaHJvbm91cyBkcmF3XG4gICAgICAvLyBoaXRzIGEgemVyby1zaXplIGNvbnRhaW5lciBvbiBmaXJzdCBjcmVhdGUgYW5kIFBsb3RseSBrZWVwcyB0aGF0IHNpemUsIHNvXG4gICAgICAvLyB0aGUgaW5zZXQgc3RheXMgYmxhbmsgYW5kIGxpdmUgdXBkYXRlcyByZWRyYXcgaW50byB0aGUgc2FtZSB6ZXJvIGJveC5cbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLnJlbmRlckludGVuc2l0eUluc2V0KCkpO1xuICAgIH0pO1xuICAgIC8vIFdoZW4gdGhlIE9TRCB2aWV3IHNldHRsZXMgYXQgYSBuZXcgem9vbS9wYW4sIHJlLXNhbXBsZSB0aGUgaW50ZW5zaXR5IGxpbmVzXG4gICAgLy8gZnJvbSBhIGNyb3Agb2YgdGhlIHZpc2libGUgcmVnaW9uIHNvIHRoZSBpbnNldCByZWZsZWN0cyB0aGUgem9vbS1sZXZlbFxuICAgIC8vIHJlc29sdXRpb24gKFBsb3RseSdzIG93biBoaWdoLWRlZiB6b29tIHVwZGF0ZXMgdGhlIHNhbXBsaW5nIGNhY2hlIGlubGluZSkuXG4gICAgdGhpcy52aWV3cG9ydENoYW5nZVN1YiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0Vmlld3BvcnRDaGFuZ2UkKCkuc3Vic2NyaWJlKChyb2kpID0+IHtcbiAgICAgIGlmICh0aGlzLmhhc1Byb2ZpbGVzICYmIHRoaXMuaXNJbWFnZVZpZXcpIHtcbiAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZWZyZXNoSW50ZW5zaXR5U2FtcGxpbmdGb3JSb2kocm9pLngsIHJvaS55LCByb2kud2lkdGgsIHJvaS5oZWlnaHQsIHRoaXMuekluZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnByZXZpZXdTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmdldEltYWdlSW5mbyQoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGltZ0luZm8pID0+IHtcbiAgICAgICAgaWYgKCFpbWdJbmZvKSB7XG4gICAgICAgICAgdGhpcy5vbkltYWdlQ2xlYXJlZCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW1nSW5mbykge1xuICAgICAgICAgIHRoaXMuaW1hZ2VJbmZvID0gaW1nSW5mbztcbiAgICAgICAgICAvLyBTdGFjay1vbmx5IHBsb3QgdHlwZXMgKGlzb3N1cmZhY2UsIHNjYXR0ZXIzZCkgZGVwZW5kIG9uIHdoZXRoZXIgdGhpc1xuICAgICAgICAgIC8vIGZpbGUgaXMgYSBzdGFjayDigJQgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBvcHRpb25zLlxuICAgICAgICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgICAgICAgIC8vIElmIHRoZSBhY3RpdmUgcGxvdCB0eXBlIGlzbid0IHZhbGlkIGZvciB0aGlzIGltYWdlIChlLmcuIGEgc2NhbGFyXG4gICAgICAgICAgLy8gdHlwZSBsaWtlIENvbnRvdXIgY2FycmllZCBvdmVyIHRvIGFuIFJHQiBpbWFnZSksIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICAgICAgICAvLyByZXNldCBzdGFjayBvcHRpb25zIHNlbGVjdGlvblxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRTdGFja09wdGlvbiA9IGltZ0luZm8uc2hvd1N0YWNrID8gdGhpcy5zdGFja09wdGlvbnNbMV0gOiB0aGlzLnN0YWNrT3B0aW9uc1swXTtcblxuICAgICAgICAgIC8vIFJlYWQgZnJvbSBgaW1nSW5mb2AsIHRoZSB2YWx1ZSB0aGlzIGVtaXNzaW9uIGNhcnJpZWQsIHJhdGhlciB0aGFuIGZyb20gdGhlXG4gICAgICAgICAgLy8gZmllbGQuIEhhbmRsaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiBtZWFucyB0aGUgZmllbGQgQ0FOIGJlIG51bGxlZCBwYXJ0LXdheVxuICAgICAgICAgIC8vIHRocm91Z2ggdGhpcyBicmFuY2g6IGByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlYCBtYXkgY2FsbCBgc2V0UGxvdFR5cGVgLFxuICAgICAgICAgIC8vIHdoaWNoIGNhbiBtYWtlIHRoZSBob3N0IHB1Ymxpc2ggYSBuZXcgaW1hZ2Ugc3RhdGUsIHJlLWVudGVyaW5nIHRoaXMgdmVyeVxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbi4gUmVhZGluZyB0aGUgZmllbGQgdGhlbiB0aHJldyBvbiBgaXNHcmF5c2NhbGVgIGFuZCBhYm9ydGVkIHRoZVxuICAgICAgICAgIC8vIGhhbmRsZXIsIHNvIHRoZSBvYnNlcnZhdGlvbnMgd2VyZSBuZXZlciBkcmF3bi5cbiAgICAgICAgICB0aGlzLmlzR3JheXNjYWxlRXZlbnQuZW1pdChpbWdJbmZvLmlzR3JheXNjYWxlKTtcbiAgICAgICAgICB0aGlzLmlzU3RhY2tFdmVudC5lbWl0KGltZ0luZm8uaXNTdGFjayk7XG4gICAgICAgICAgLy8gUmVzZXQgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2UgdmlldyB3aGVuIGEgZGlmZmVyZW50IGltYWdlIGlzXG4gICAgICAgICAgLy8gc2VsZWN0ZWQgd2hpbGUgYSAzRCB0eXBlIGlzIGFjdGl2ZS5cbiAgICAgICAgICBpZiAoIXRoaXMuaXNIZWF0bWFwICYmIGltZ0luZm8uZmlsZU5hbWUgIT09IHRoaXMubG9hZGVkRmlsZU5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMuaXNIZWF0bWFwID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucGxvdFR5cGUgPSBQbG90VHlwZS5JTUFHRTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZSA9IFBsb3RUeXBlLklNQUdFO1xuICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0aGlzLnBsb3RUeXBlKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmxvYWRlZEZpbGVOYW1lID0gaW1nSW5mby5maWxlTmFtZTtcbiAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldEltYWdlTWV0YShpbWdJbmZvLmltYWdlTWV0YSk7XG4gICAgICAgICAgY29uc3QgdXJscyA9IGltZ0luZm8udXJscztcbiAgICAgICAgICAvLyBBIG5ld2VyIGltYWdlIEFMV0FZUyBwcmVlbXB0cyBhbiBpbi1mbGlnaHQgcmVuZGVyLiBUaGlzIHdhc1xuICAgICAgICAgIC8vIGBpZiAoIXRoaXMucnVubmluZylgLCB3aGljaCBEUk9QUEVEIHRoZSBuZXcgaW1hZ2Ugd2hpbGUgdGhlIG9sZCBvbmVcbiAgICAgICAgICAvLyBmaW5pc2hlZDogaWRlbnRpdHkgYWJvdmUgaGFkIGFscmVhZHkgZmxpcHBlZCB0byB0aGUgbmV3IGZpbGUsIHNvIHRoZVxuICAgICAgICAgIC8vIGFwcCByZXBvcnRlZCBpbWFnZSBCIGFzIGxvYWRlZCB3aGlsZSBpbWFnZSBBIHN0YXllZCBvbiBzY3JlZW4uIFdvcnNlLFxuICAgICAgICAgIC8vIGEgY29sZCBpbWFnZSBob2xkcyB0aGUgc2xvdCBmb3IgaXRzIHdob2xlIHNlcnZlci1zaWRlIGNhY2hlIGZpbGwsIHNvXG4gICAgICAgICAgLy8gZXZlcnkgY2xpY2sgZm9yIDEtMiBtaW51dGVzIHdhcyBkaXNjYXJkZWQgYWdhaW5zdCBhIGJsYW5rIHZpZXdwb3J0XG4gICAgICAgICAgLy8gYW5kIGEgXCJMb2FkaW5nIGltYWdlLi4uXCIgb3ZlcmxheSB0aGF0IG5ldmVyIHJlc29sdmVkLlxuICAgICAgICAgIGlmICh1cmxzKSB7XG4gICAgICAgICAgICBjb25zdCB0b2tlbiA9ICsrdGhpcy5yZW5kZXJUb2tlbjtcbiAgICAgICAgICAgIGNvbnN0IGlzQ3VycmVudCA9ICgpID0+IHRoaXMucmVuZGVyVG9rZW4gPT09IHRva2VuO1xuICAgICAgICAgICAgaWYgKHRoaXMucnVubmluZykge1xuICAgICAgICAgICAgICAvLyBTdG9wIHRoZSBwcmV2aW91cyByZW5kZXIncyBmcmFtZSBzdHJlYW1pbmcgKG5hcGFyaSB2b2x1bWUvc3VyZmFjZVxuICAgICAgICAgICAgICAvLyBwcmVsb2FkIGtlZXBzIGZldGNoaW5nIG90aGVyd2lzZSkgYW5kIGNsZWFyIGl0cyBzaGFycGVuIGZsYWcuIEl0c1xuICAgICAgICAgICAgICAvLyBjYWxsYmFja3MgYXJlIGFscmVhZHkgaW5lcnQgdmlhIHRoZSB0b2tlbiwgc28gaXQgY2FuIG5laXRoZXIgcGFpbnRcbiAgICAgICAgICAgICAgLy8gbm9yIHJlbGVhc2UgdGhlIG92ZXJsYXkgdGhpcyByZW5kZXIgbm93IG93bnMuXG4gICAgICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2UuY2FuY2VsTG9hZGluZz8uKCk7XG4gICAgICAgICAgICAgIHRoaXMuc2hhcnBlbmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaW1hZ2Ugc2l6ZSDigJQgbWVhc3VyZSB0aGUgcGxvdCBkaXYgZGlyZWN0bHkgc28gdGhlIHRvb2xiYXIgaGVpZ2h0IGlzIGV4Y2x1ZGVkXG4gICAgICAgICAgICBjb25zdCBwbG90RGl2OiBIVE1MRWxlbWVudCB8IG51bGwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnBsb3REaXZOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHNjcmVlbkhlaWdodCA9IHBsb3REaXY/Lm9mZnNldEhlaWdodCB8fCA1MDA7XG4gICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlc2V0KCk7XG4gICAgICAgICAgICB0aGlzLnN0YWNrTG9hZGluZyA9IGltZ0luZm8uaXNTdGFjayAmJiBpbWdJbmZvLnNob3dTdGFjaztcbiAgICAgICAgICAgIC8vIHNldCBtYXggaW5kZXggb2Ygc3RhY2sg4oCUIGNvbXB1dGVkIGJlZm9yZSB1cGRhdGVaSW5kZXggc28gYVxuICAgICAgICAgICAgLy8gZnJlc2ggc3RhY2sgKHNob3J0ZXIgb3IgbG9uZ2VyIHRoYW4gd2hhdGV2ZXIgd2FzIHByZXZpb3VzbHlcbiAgICAgICAgICAgIC8vIGxvYWRlZCkgY2xhbXBzIGFnYWluc3QgSVRTIGJvdW5kcywgbm90IHRoZSBzdGFsZSBvbmVzLlxuICAgICAgICAgICAgLy8gT25lIFVSTCBwZXIgc2xpY2UgKDAtaW5kZXhlZCksIHNvIHRoZSBsYXN0IHJlYWNoYWJsZSBpbmRleCBpc1xuICAgICAgICAgICAgLy8gbGVuZ3RoLTEg4oCUIGVhcmxpZXIgYGxlbmd0aC0yYCBkcm9wcGVkIHRoZSBmaW5hbCBzbGljZS5cbiAgICAgICAgICAgIHRoaXMubWF4SW5kZXggPSB1cmxzLmxlbmd0aCA+IDEgPyB1cmxzLmxlbmd0aCAtIDEgOiAwO1xuICAgICAgICAgICAgLy8gT25lLXNob3QgaGludDoganVtcCBzdHJhaWdodCB0byBhIHNwZWNpZmljIHNsaWNlIChlLmcuIHRoZVxuICAgICAgICAgICAgLy8gZmlsZSB0aGUgdXNlciBhY3R1YWxseSBjbGlja2VkIHdpdGhpbiBhIG51bWJlcmVkIHNlcmllcykuXG4gICAgICAgICAgICAvLyBDb25zdW1lZCBpbW1lZGlhdGVseSBzbyByZWRlbGl2ZXJpbmcgdGhlIHNhbWUgSW1hZ2VJbmZvIGxhdGVyXG4gICAgICAgICAgICAvLyAoYSBwbG90LXR5cGUgc3dpdGNoLCByZWxvYWRBbmRQbG90KSBkb2Vzbid0IHJlc2V0IHRoZSB1c2VyJ3NcbiAgICAgICAgICAgIC8vIGN1cnJlbnQgc2NydWIgcG9zaXRpb24gYmFjayB0byBpdC5cbiAgICAgICAgICAgIGlmIChpbWdJbmZvLmluaXRpYWxaSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICB0aGlzLnpJbmRleCA9IGltZ0luZm8uaW5pdGlhbFpJbmRleDtcbiAgICAgICAgICAgICAgaW1nSW5mby5pbml0aWFsWkluZGV4ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSB6aW5kZXggaXMgd2l0aGluIGJvdW5kc1xuICAgICAgICAgICAgdGhpcy51cGRhdGVaSW5kZXgodXJscyk7XG4gICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xuICAgICAgICAgICAgLy8gTXVsdGktdGllciByZW5kZXJpbmcgKHNtYWxsIGJsdXJyeSB0aWVyIGZpcnN0LCB0aGVuIHNoYXJwZW4gaW5cbiAgICAgICAgICAgIC8vIHBsYWNlKSDigJQgc2VxdWVuY2luZyBsaXZlcyBpbiBSZW5kZXJPcmNoZXN0cmF0b3I7IHRoaXMgY29tcG9uZW50XG4gICAgICAgICAgICAvLyBzdXBwbGllcyB0aGUgcGhhc2UgcmVuZGVyIGFuZCBvd25zIHRoZSBVSSBmbGFncyB2aWEgY2FsbGJhY2tzLlxuICAgICAgICAgICAgLy8gM0QgcGxvdCB0eXBlcyByZW5kZXIgc2luZ2xlLXBhc3M6IHRoZSBpbi1wbGFjZSBsYXJnZSBwYXNzIGRvZXNuJ3RcbiAgICAgICAgICAgIC8vIHJlYnVpbGQgYSAzRCBnbC1tZXNoIGlzb3N1cmZhY2UsIHNvIHRoZSBzaGFycGVuIHN0ZXAgYmxhbmtlZCBpdC5cbiAgICAgICAgICAgIGNvbnN0IGhhc1NtYWxsVGllciA9XG4gICAgICAgICAgICAgIHRoaXMuaXNIZWF0bWFwICYmXG4gICAgICAgICAgICAgIChpbWdJbmZvLnNtYWxsVXJscz8ubGVuZ3RoID8/IDApID09PSB1cmxzLmxlbmd0aCAmJlxuICAgICAgICAgICAgICAoaW1nSW5mby5zbWFsbFVybHM/Lmxlbmd0aCA/PyAwKSA+IDA7XG4gICAgICAgICAgICBjb25zdCBzbWFsbEltZ0luZm8gPSBoYXNTbWFsbFRpZXIgPyB7IC4uLmltZ0luZm8sIHVybHM6IGltZ0luZm8uc21hbGxVcmxzIGFzIHN0cmluZ1tdIH0gOiBudWxsO1xuXG4gICAgICAgICAgICAvLyBFbnRlciBwZXItc2xpY2Ugc3RhY2sgbW9kZSB3aXRoIHRoZSBnaXZlbiBzbGljZeKGknJlZ2lvbnMgbWFwIGFuZFxuICAgICAgICAgICAgLy8gc2VlZCB0aGUgXCJwcmV2aW91cyBzaGFwZXNcIiBmcm9tIHRoZSBub3ctbGl2ZSBzbGljZS4gZW50ZXJTdGFja01vZGVcbiAgICAgICAgICAgIC8vIG1ha2VzIHpJbmRleCdzIHNsaWNlIGxpdmUgYW5kIHJlc2V0cyB1bmRvIChqaXQtdWkjOTMpLlxuICAgICAgICAgICAgY29uc3QgZW50ZXJTdGFjayA9IChcbiAgICAgICAgICAgICAgc2xpY2VzOiBNYXA8bnVtYmVyLCBSZWdpb25bXT4sXG4gICAgICAgICAgICAgIGxheW91dDogJ2NvbWJpbmVkJyB8ICdwZXItc2xpY2UtZmlsZScsXG4gICAgICAgICAgICApID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5lbnRlclN0YWNrTW9kZShzbGljZXMsIHRoaXMuekluZGV4LCBsYXlvdXQpO1xuICAgICAgICAgICAgICBjb25zdCBzaGFwZXMgPSB0aGlzLnBsb3RTZXJ2aWNlXG4gICAgICAgICAgICAgICAgLmdldFJlZ2lvbnMoKVxuICAgICAgICAgICAgICAgIC5tYXAoKHJlZ2lvbikgPT4gcmVnaW9uLmdldFNoYXBlKHRoaXMucGxvdFNlcnZpY2UuZ2V0U2hvd1NoYXBlTGFiZWwoKSkpO1xuICAgICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFByZXZpb3VzU2hhcGVzKHNoYXBlcyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBhcHBseVJvaSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgLy8gRm9sZGVyIHN0YWNrOiBhIHN0YWNrIG9mIHNlbGYtY29udGFpbmVkIHBlci1zbGljZSBmaWxlc1xuICAgICAgICAgICAgICAvLyAodGlsZWQgPT09IGZhbHNlOyBzZWUgbG9hZFNlcmllc0FzU3RhY2spLiBFYWNoIHNsaWNlLWZpbGUgbWF5XG4gICAgICAgICAgICAgIC8vIGNhcnJ5IGl0cyBvd24gc2libGluZyBcIjxzdGVtPi5nZW9qc29uXCIgKHJvaUpzb25TdHJzW3pdKSwgYnV0IGFcbiAgICAgICAgICAgICAgLy8gZnJlc2ggZm9sZGVyIHdpdGggbm9uZSB5ZXQgbGVhdmVzIHJvaUpzb25TdHJzIHVuZGVmaW5lZCDigJQga2V5XG4gICAgICAgICAgICAgIC8vIG9mZiBgdGlsZWQgPT09IGZhbHNlYCwgTk9UIHJvaUpzb25TdHJzLCBzbyBhbiB1bmFubm90YXRlZFxuICAgICAgICAgICAgICAvLyBmb2xkZXIgc3RhY2sgc3RpbGwgZW50ZXJzIHRoZSBwZXItc2xpY2UtZmlsZSBsYXlvdXQgKGFuZCBzYXZlc1xuICAgICAgICAgICAgICAvLyBiYWNrIG9uZSBnZW9qc29uIHBlciBzbGljZS1maWxlKSByYXRoZXIgdGhhbiBmYWxsaW5nIHRocm91Z2ggdG9cbiAgICAgICAgICAgICAgLy8gdGhlIHNpbmdsZS1maWxlIGNvbWJpbmVkIHBhdGggKGppdC11aSM5MykuXG4gICAgICAgICAgICAgIGlmIChpbWdJbmZvLmlzU3RhY2sgJiYgaW1nSW5mby50aWxlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwZXJTbGljZSA9IGltZ0luZm8ucm9pSnNvblN0cnM7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2xpY2VDb3VudCA9IGltZ0luZm8udXJscz8ubGVuZ3RoID8/IHBlclNsaWNlPy5sZW5ndGggPz8gMDtcbiAgICAgICAgICAgICAgICBjb25zdCBzbGljZXMgPSBuZXcgTWFwPG51bWJlciwgUmVnaW9uW10+KCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBzbGljZUNvdW50OyB6KyspIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBwZXJTbGljZT8uW3pdID8/IG51bGw7XG4gICAgICAgICAgICAgICAgICBzbGljZXMuc2V0KHosIGpzb24gPyB0aGlzLnBsb3RTZXJ2aWNlLmltcG9ydFJlZ2lvbnMoanNvbikgOiBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVudGVyU3RhY2soc2xpY2VzLCAncGVyLXNsaWNlLWZpbGUnKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gU2luZ2xlLWZpbGUgei1zdGFjazogb25lIHNpYmxpbmcgZ2VvanNvbiBob2xkaW5nIGV2ZXJ5IHNsaWNlJ3NcbiAgICAgICAgICAgICAgLy8gcmVnaW9ucyBpbmRleGVkIGJ5IFF1UGF0aCdzIGdlb21ldHJ5LnBsYW5lLnouIEVudGVyIHBlci1zbGljZVxuICAgICAgICAgICAgICAvLyBtb2RlIChzYXZpbmcgYmFjayBvbmUgY29tYmluZWQgei1pbmRleGVkIGdlb2pzb24pIHdoZW4gdGhlXG4gICAgICAgICAgICAgIC8vIGdlb2pzb24gYWN0dWFsbHkgY2FycmllcyBzbGljZSBpbmRpY2VzLCBvciB3aGVuIHRoZXJlJ3Mgbm90aGluZ1xuICAgICAgICAgICAgICAvLyB5ZXQgdG8gYXV0aG9yIGFnYWluc3QuIEEgbGVnYWN5IGdlb2pzb24gd2hvc2UgcmVnaW9ucyBhcmUgYWxsIG9uXG4gICAgICAgICAgICAgIC8vIHRoZSBkZWZhdWx0IHBsYW5lIHN0YXlzIGdsb2JhbCAoc2hvd24gb24gZXZlcnkgc2xpY2UpIHNvXG4gICAgICAgICAgICAgIC8vIGV4aXN0aW5nIHNpbmdsZS1wbGFuZSBhbm5vdGF0aW9ucyBhcmVuJ3QgY29uZmluZWQgdG8gc2xpY2UgMC5cbiAgICAgICAgICAgICAgY29uc3Qgcm9pSnNvbiA9IGltZ0luZm8ucm9pSnNvblN0cjtcbiAgICAgICAgICAgICAgaWYgKGltZ0luZm8uaXNTdGFjaykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2lvbnMgPSByb2lKc29uID8gdGhpcy5wbG90U2VydmljZS5pbXBvcnRSZWdpb25zKHJvaUpzb24pIDogW107XG4gICAgICAgICAgICAgICAgY29uc3QgaGFzU2xpY2VJbmZvID0gcmVnaW9ucy5zb21lKChyKSA9PiAoci56ID8/IDApICE9PSAwKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJvaUpzb24gfHwgaGFzU2xpY2VJbmZvKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzbGljZXMgPSBuZXcgTWFwPG51bWJlciwgUmVnaW9uW10+KCk7XG4gICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHIgb2YgcmVnaW9ucykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB6ID0gci56ID8/IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ1Y2tldCA9IHNsaWNlcy5nZXQoeik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChidWNrZXQpIGJ1Y2tldC5wdXNoKHIpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHNsaWNlcy5zZXQoeiwgW3JdKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGVudGVyU3RhY2soc2xpY2VzLCAnY29tYmluZWQnKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gU2luZ2xlLXBsYW5lIGltYWdlIChvciBhIGxlZ2FjeSBnbG9iYWwgei1zdGFjayBnZW9qc29uKTogb25lXG4gICAgICAgICAgICAgIC8vIHJlZ2lvbiBzZXQgZm9yIHRoZSB3aG9sZSBpbWFnZS5cbiAgICAgICAgICAgICAgaWYgKHJvaUpzb24pIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWdpb25zID0gdGhpcy5wbG90U2VydmljZS5pbXBvcnRSZWdpb25zKHJvaUpzb24pO1xuICAgICAgICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0UmVnaW9ucyhyZWdpb25zKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzaGFwZXMgPSByZWdpb25zLm1hcCgocmVnaW9uKSA9PlxuICAgICAgICAgICAgICAgICAgcmVnaW9uLmdldFNoYXBlKHRoaXMucGxvdFNlcnZpY2UuZ2V0U2hvd1NoYXBlTGFiZWwoKSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFByZXZpb3VzU2hhcGVzKHNoYXBlcyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gTG9hZGluZyBhbiBpbWFnZSdzIHNhdmVkIFJPSXMgaXMgbm90IGEgdXNlciBlZGl0IOKAlCBzdGFydCB0aGVcbiAgICAgICAgICAgICAgLy8gdW5kbyBoaXN0b3J5IGZyZXNoIHNvIHRoZSBmaXJzdCB1bmRvIGNhbid0IHdpcGUgdGhlbSAoaml0LXVpIzg1KS5cbiAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZXNldFVuZG9IaXN0b3J5KCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbGV0IG92ZXJsYXlSZWxlYXNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgcmVsZWFzZU92ZXJsYXkgPSAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChvdmVybGF5UmVsZWFzZWQpIHJldHVybjtcbiAgICAgICAgICAgICAgb3ZlcmxheVJlbGVhc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgaWYgKGltZ0luZm8uaXNTdGFjayAmJiBpbWdJbmZvLnNob3dTdGFjaykgdGhpcy5zdGFja0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoZmFsc2UpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgbmV3IFJlbmRlck9yY2hlc3RyYXRvcih7XG4gICAgICAgICAgICAgIC8vIGluUGxhY2U9dHJ1ZSB1cGRhdGVzIHRoZSBleGlzdGluZyByZW5kZXIgaW5zdGVhZCBvZiByZWJ1aWxkaW5nXG4gICAgICAgICAgICAgIC8vIGl0LCBzbyB0aGUgY2FudmFzIGRvZXNuJ3QgYmxhbmsgZHVyaW5nIHRoZSBzbWFsbOKGkmxhcmdlIHN3YXAuXG4gICAgICAgICAgICAgIHJlbmRlclBoYXNlOiAocGhhc2VJbmZvLCBpblBsYWNlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gU3VwZXJzZWRlZCBCRUZPUkUgdGhpcyBwaGFzZSBzdGFydGVkIOKAlCBkb24ndCBldmVuIGlzc3VlIHRoZSBsb2FkLlxuICAgICAgICAgICAgICAgIC8vIFJlbmRlck9yY2hlc3RyYXRvciBjYWxscyByZW5kZXJQaGFzZSBvbmNlIHBlciB0aWVyIGFuZCByZXRyaWVzIHRoZVxuICAgICAgICAgICAgICAgIC8vIHNoYXJwZW4gcGFzcyBvbiBmYWlsdXJlLCBzbyBjaGVja2luZyBvbmx5IGFmdGVyIHRoZSBsb2FkIHJlc29sdmVzXG4gICAgICAgICAgICAgICAgLy8gd291bGQgbGV0IGEgcHJlZW1wdGVkIHJlbmRlciBrZWVwIGZldGNoaW5nIHNsaWNlcy90aWxlcyBmb3IgYW5cbiAgICAgICAgICAgICAgICAvLyBpbWFnZSBub2JvZHkgaXMgbG9va2luZyBhdC5cbiAgICAgICAgICAgICAgICBpZiAoIWlzQ3VycmVudCgpKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBsb3RTZXJ2aWNlLmxvYWQocGhhc2VJbmZvLCB0aGlzLnpJbmRleCkudGhlbigobG9hZGVkSW1hZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vIFByZWVtcHRlZCB3aGlsZSB0aGlzIHBoYXNlIHdhcyBsb2FkaW5nIOKAlCBkcm9wIGl0IG9uIHRoZSBmbG9vci5cbiAgICAgICAgICAgICAgICAgIGlmICghaXNDdXJyZW50KCkpIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgLy8gR3VhcmQgYWdhaW5zdCBhIG5ld2VyIGNsaWNrIHJlYWNoaW5nIHVzIG1pZC1yZW5kZXIuXG4gICAgICAgICAgICAgICAgICBpZiAocGhhc2VJbmZvLmZpbGVOYW1lICE9PSBsb2FkZWRJbWFnZS5maWxlbmFtZSkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wbG90U2VydmljZS5wbG90KFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsb3REaXZOYW1lLFxuICAgICAgICAgICAgICAgICAgICBsb2FkZWRJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgcGhhc2VJbmZvLFxuICAgICAgICAgICAgICAgICAgICBzY3JlZW5IZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxvdFR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGluUGxhY2UsXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBzbWFsbFNob3duOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnQoKSkgcmV0dXJuOyAvLyBzdXBlcnNlZGVkIGJ5IGEgbmV3ZXIgaW1hZ2VcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgZmlsZSBpcyBzdGlsbCBiZWluZyBjYWNoZWQvcHJlcGFyZWQgc2VydmVyLXNpZGUsIGtlZXAgdGhlIGZ1bGxcbiAgICAgICAgICAgICAgICAvLyBjYWNoZS1wcm9ncmVzcyBvdmVybGF5IHVwIGluc3RlYWQgb2YgZHJvcHBpbmcgdG8gdGhlIHRyYW5zbHVjZW50IFwiU2hhcnBlbmluZ1xuICAgICAgICAgICAgICAgIC8vIHByZXZpZXcuLi5cIiBzcGlubmVyIG92ZXIgYSBibGFuayBjYW52YXMgKGEgbGFyZ2UgdW5jYWNoZWQgaW1hZ2UgcmVuZGVycyBpdHNcbiAgICAgICAgICAgICAgICAvLyBzbWFsbCBwcmV2aWV3IGJlZm9yZSBpdHMgdGlsZXMgZXhpc3QpLiBmaW5pc2hlZCgpIHJlbGVhc2VzIHRoZSBvdmVybGF5IG9uY2VcbiAgICAgICAgICAgICAgICAvLyB0aGUgcmVhbCByZW5kZXIgbGFuZHMuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNDYWNoaW5nKSByZXR1cm47XG4gICAgICAgICAgICAgICAgLy8gU21hbGwgdGllciBvbiBzY3JlZW4g4oCUIGRyb3AgdGhlIGZ1bGwgb3ZlcmxheSBidXQga2VlcCBhIHRyYW5zbHVjZW50IHNwaW5uZXIgc29cbiAgICAgICAgICAgICAgICAvLyB0aGUgYmx1cnJ5IHJlbmRlciBpc24ndCBtaXN0YWtlbiBmb3IgdGhlIGZpbmFsIGltYWdlLlxuICAgICAgICAgICAgICAgIHJlbGVhc2VPdmVybGF5KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zaGFycGVuaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc2hhcnBlblNldHRsZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzQ3VycmVudCgpKSByZXR1cm47IC8vIHN1cGVyc2VkZWQgYnkgYSBuZXdlciBpbWFnZVxuICAgICAgICAgICAgICAgIHRoaXMuc2hhcnBlbmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBmaW5pc2hlZDogKF92aWFTbWFsbCwgbG9nVGFnKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnQoKSkgcmV0dXJuOyAvLyBzdXBlcnNlZGVkIGJ5IGEgbmV3ZXIgaW1hZ2VcbiAgICAgICAgICAgICAgICAvLyBJZGVtcG90ZW50IOKAlCByZWxlYXNlcyBub3cgaWYgc21hbGxTaG93biBkZWZlcnJlZCBpdCAoY2FjaGluZykgb3Igd2FzIHNraXBwZWQuXG4gICAgICAgICAgICAgICAgcmVsZWFzZU92ZXJsYXkoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBhcHBseVJvaSgpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGxvZ1RhZyk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHNoYXJwZW5GYWlsZWQ6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNDdXJyZW50KCkpIHJldHVybjsgLy8gc3VwZXJzZWRlZCBieSBhIG5ld2VyIGltYWdlXG4gICAgICAgICAgICAgICAgLy8gVGhlIHNtYWxsIHRpZXIgc3RheXMgb24gc2NyZWVuIGFzIHRoZSBmYWxsYmFjayDigJQgdGVsbCB0aGVcbiAgICAgICAgICAgICAgICAvLyB1c2VyIHRoZSBzaGFycGVyIHZlcnNpb24gaXNuJ3QgY29taW5nLlxuICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9IGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgZXJyPy5tZXNzYWdlIHx8IGVycj8uc3RhdHVzVGV4dCB8fCBTdHJpbmcoZXJyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgICAgICAgICAgICBrZXk6IHRoaXMudml6QWxlcnRUb2FzdEtleSxcbiAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnd2FybicsXG4gICAgICAgICAgICAgICAgICBzdW1tYXJ5OiAnUHJldmlldyBub3Qgc2hhcnBlbmVkJyxcbiAgICAgICAgICAgICAgICAgIGRldGFpbDogYFRoZSBmdWxsLXJlc29sdXRpb24gcHJldmlldyBkaWQgbm90IGxvYWQgKCR7bXNnfSkuIFRoZSBsb3ctcmVzb2x1dGlvbiBwcmV2aWV3IGlzIHN0aWxsIHNob3duLiBUcnkgY2xpY2tpbmcgdGhlIGltYWdlIGFnYWluLmAsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYXBwbHlSb2koKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLnJlbmRlcihpbWdJbmZvLCBzbWFsbEltZ0luZm8pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgIGNvbnN0IG1zZyA9IGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgZXJyPy5tZXNzYWdlIHx8IGVycj8uc3RhdHVzVGV4dCB8fCBTdHJpbmcoZXJyKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igb2NjdXJlZCB3aGVuIGdldHRpbmcgaW1hZ2UgaW5mbycsIGVycik7XG4gICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAgICBrZXk6IHRoaXMudml6QWxlcnRUb2FzdEtleSxcbiAgICAgICAgICBzdGlja3k6IHRydWUsXG4gICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgICAgc3VtbWFyeTogJ0FuIGVycm9yIG9jY3VyZWQnLFxuICAgICAgICAgIGRldGFpbDogYFRoZSBmb2xsb3dpbmcgZXJyb3Igb2NjdXJlZCB3aGlsZSBnZXR0aW5nIGltYWdlIGluZm86ICR7bXNnfS5cbiAgICAgICAgICAgICAgICAgICBQbGVhc2UgdHJ5IHRvIG9wZW4gdGhlIGltYWdlIGFnYWluIHRocm91Z2ggdGhlIGZpbGUgbmF2aWdhdG9yLmAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnN0YWNrTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhmYWxzZSk7XG4gICAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlc2V0KCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMucGxvdENvbnRleHRNZW51TGlzdGVuZXIgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHBsb3RFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMucGxvdERpdk5hbWUpO1xuICAgICAgaWYgKCFwbG90RWw/LmNvbnRhaW5zKGV2ZW50LnRhcmdldCBhcyBOb2RlKSkgcmV0dXJuO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5jb250ZXh0TWVudUl0ZW1zID0gdGhpcy5idWlsZENvbnRleHRNZW51SXRlbXMoKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB0aGlzLmNvbnRleHRNZW51LnNob3coZXZlbnQpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCB0aGlzLnBsb3RDb250ZXh0TWVudUxpc3RlbmVyLCB0cnVlKTtcblxuICAgIHRoaXMua2V5ZG93bkxpc3RlbmVyID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBpZiAodGFyZ2V0LnRhZ05hbWUgPT09ICdJTlBVVCcgfHwgdGFyZ2V0LnRhZ05hbWUgPT09ICdURVhUQVJFQScgfHwgdGFyZ2V0LmlzQ29udGVudEVkaXRhYmxlKSByZXR1cm47XG4gICAgICAvLyBTQU0gcG9pbnQgbW9kZTogRW50ZXIgY29tbWl0cyB0aGUgb2JqZWN0LCBFc2MgY2xlYXJzIHRoZSBwcm9tcHQuXG4gICAgICBpZiAodGhpcy5hY3RpdmVEcmFnTW9kZSA9PT0gJ3NhbVBvaW50JyAmJiAoZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleSA9PT0gJ0VzY2FwZScpKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJykgdGhpcy5wbG90U2VydmljZS5jb21taXRTYW1Qb2ludHMoKTtcbiAgICAgICAgICBlbHNlIHRoaXMucGxvdFNlcnZpY2UuY2xlYXJTYW1Qb2ludHMoKTtcbiAgICAgICAgICB0aGlzLmhpZGVTYW1Ub2FzdCgpOyAvLyBwcm9tcHQgcmVzb2x2ZWQg4oaSIGRpc21pc3MgdGhlIHN0YXR1cyB0b2FzdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gUmVnaW9uIGhpc3RvcnkgKGppdC11aSM4NSk6IEN0cmwvQ21kK1ogdW5kb2VzOyBDdHJsL0NtZCtTaGlmdCtaIG9yXG4gICAgICAvLyBDdHJsL0NtZCtZIHJlZG9lcy5cbiAgICAgIGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcbiAgICAgICAgY29uc3QgayA9IGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoayA9PT0gJ3onICYmICFldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMudW5kb1JlZ2lvbigpKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChrID09PSAneicgJiYgZXZlbnQuc2hpZnRLZXkpIHx8IGsgPT09ICd5Jykge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMucmVkb1JlZ2lvbigpKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICdEZWxldGUnIHx8IGV2ZW50LmtleSA9PT0gJ0JhY2tzcGFjZScgfHwgZXZlbnQua2V5ID09PSAnZCcgfHwgZXZlbnQua2V5ID09PSAnRCcpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuZGVsZXRlUmVnaW9uKCkpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICcrJyB8fCBldmVudC5rZXkgPT09ICc9Jykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy56b29tSW4oKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJy0nIHx8IGV2ZW50LmtleSA9PT0gJ18nKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnpvb21PdXQoKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ3AnKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdwYW4nKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ2InKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCd6b29tVG9Cb3gnKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ3InKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdkcmF3cmVjdCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSAnZicpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2RyYXdjbG9zZWRwYXRoJykpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICd3Jykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnd2FuZCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSAnZScpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2VyYXNlVmVydGV4JykpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdzJykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnc2VsZWN0JykpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdsJykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZHJhd29wZW5wYXRoJykpO1xuICAgICAgfVxuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmtleWRvd25MaXN0ZW5lcik7XG5cbiAgICB0aGlzLndoZWVsTGlzdGVuZXIgPSAoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHBsb3RFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMucGxvdERpdk5hbWUpO1xuICAgICAgaWYgKCFwbG90RWw/LmNvbnRhaW5zKGV2ZW50LnRhcmdldCBhcyBOb2RlKSkgcmV0dXJuO1xuICAgICAgLy8gSW50ZXJjZXB0aW5nIGhlcmUgZmlyZXMgYSBGSVhFRCB6b29tIHN0ZXAgcGVyIHdoZWVsIGV2ZW50LCB3aGljaCBpcyBmYXJcbiAgICAgIC8vIHRvbyBzZW5zaXRpdmUgZm9yIGEgcmVuZGVyZXIgdGhhdCByZWFkcyB0aGUgc2Nyb2xsIGRlbHRhIOKAlCBzbyBhbnl0aGluZ1xuICAgICAgLy8gZHJhd24gYnkgc3VjaCBhIHJlbmRlcmVyIGtlZXBzIGl0cyBvd24gd2hlZWwuIFNlZSBgcmVuZGVyZXJPd25zV2hlZWxgLlxuICAgICAgaWYgKHJlbmRlcmVyT3duc1doZWVsKHRoaXMuc2VsZWN0ZWRQbG90VHlwZSkpIHJldHVybjtcbiAgICAgIC8vIDNEIHBsb3QgdHlwZXMgKHN1cmZhY2UsIHNjYXR0ZXIzZCwgaXNvc3VyZmFjZSkgcmVuZGVyIGluIGEgUGxvdGx5IHNjZW5lXG4gICAgICAvLyB0aGF0IG9yYml0cy96b29tcyBuYXRpdmVseSBvbiBzY3JvbGwuIFRoZSAyRCBzdGVwLXpvb20gZG9lc24ndCBhcHBseSBhbmRcbiAgICAgIC8vIHdvdWxkIHRocm93IChubyB4YXhpcyBvbiBhIHNjZW5lKSwgc28gbGV0IFBsb3RseSBoYW5kbGUgdGhlIHdoZWVsLlxuICAgICAgaWYgKCF0aGlzLmlzSGVhdG1hcCkgcmV0dXJuO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgaWYgKGV2ZW50LmRlbHRhWSA8IDApIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuem9vbUluKCkpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5kZWx0YVkgPiAwKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnpvb21PdXQoKSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignd2hlZWwnLCB0aGlzLndoZWVsTGlzdGVuZXIsIHsgY2FwdHVyZTogdHJ1ZSwgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbiAgICAvLyBEcmFnIGhhbmRsaW5nIGZvciB0aGUgZmxvYXRpbmcgaW50ZW5zaXR5LXByb2ZpbGUgcGFuZWwuXG4gICAgdGhpcy5wcm9maWxlRHJhZ01vdmVMaXN0ZW5lciA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5wcm9maWxlUGFuZWxEcmFnZ2luZykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMucHJvZmlsZVBhbmVsUG9zID0ge1xuICAgICAgICAgICAgeDogdGhpcy5wcm9maWxlUGFuZWxTdGFydC54ICsgKGUuY2xpZW50WCAtIHRoaXMucHJvZmlsZVBhbmVsU3RhcnQubXgpLFxuICAgICAgICAgICAgeTogdGhpcy5wcm9maWxlUGFuZWxTdGFydC55ICsgKGUuY2xpZW50WSAtIHRoaXMucHJvZmlsZVBhbmVsU3RhcnQubXkpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnRvb2xiYXJEcmFnZ2luZykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMudG9vbGJhclBvcyA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMudG9vbGJhclN0YXJ0LnggKyAoZS5jbGllbnRYIC0gdGhpcy50b29sYmFyU3RhcnQubXgpLFxuICAgICAgICAgICAgeTogdGhpcy50b29sYmFyU3RhcnQueSArIChlLmNsaWVudFkgLSB0aGlzLnRvb2xiYXJTdGFydC5teSksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aGlzLnByb2ZpbGVEcmFnVXBMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgIHRoaXMucHJvZmlsZVBhbmVsRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMudG9vbGJhckRyYWdnaW5nID0gZmFsc2U7XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5wcm9maWxlRHJhZ01vdmVMaXN0ZW5lcik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLnByb2ZpbGVEcmFnVXBMaXN0ZW5lcik7XG5cbiAgICAvLyBPbiBhbnkgd2luZG93IHJlc2l6ZSwgcmVmbG93IHRoZSBpbnRlbnNpdHkgaW5zZXQgdG8gaXRzIChmaXhlZCkgcGFuZWwgc2l6ZVxuICAgIC8vIG9uIHRoZSBuZXh0IGZyYW1lLCBvbmNlIGxheW91dCBoYXMgc2V0dGxlZC4gV2l0aG91dCB0aGlzIHRoZSBpbnNldCBjYW4gYmVcbiAgICAvLyBsZWZ0IGF0IGEgc3RhbGUvemVybyBzaXplIGJ5IGEgbWlkLXJlZmxvdyByZXNpemUgYW5kIHN0b3Agc2hvd2luZy5cbiAgICB0aGlzLnByb2ZpbGVSZXNpemVMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgIGlmICghdGhpcy5oYXNQcm9maWxlcykgcmV0dXJuO1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHRoaXMucmVuZGVySW50ZW5zaXR5SW5zZXQoKSk7XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5wcm9maWxlUmVzaXplTGlzdGVuZXIpO1xuICB9XG5cbiAgb25Qcm9maWxlUGFuZWxEcmFnU3RhcnQoZTogTW91c2VFdmVudCkge1xuICAgIHRoaXMucHJvZmlsZVBhbmVsRHJhZ2dpbmcgPSB0cnVlO1xuICAgIHRoaXMucHJvZmlsZVBhbmVsU3RhcnQgPSB7XG4gICAgICBteDogZS5jbGllbnRYLFxuICAgICAgbXk6IGUuY2xpZW50WSxcbiAgICAgIHg6IHRoaXMucHJvZmlsZVBhbmVsUG9zLngsXG4gICAgICB5OiB0aGlzLnByb2ZpbGVQYW5lbFBvcy55LFxuICAgIH07XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgLyoqIEdyYWIgdGhlIHRvb2xiYXIgaGFuZGxlOiBkZXRhY2ggaXQgaW50byBhIGZsb2F0aW5nIHdpbmRvdyAoaWYgc3RpbGwgZG9ja2VkKVxuICAgKiAgYW5kIHN0YXJ0IGRyYWdnaW5nLiAqL1xuICBvblRvb2xiYXJEcmFnU3RhcnQoZTogTW91c2VFdmVudCkge1xuICAgIGlmICghdGhpcy50b29sYmFyRmxvYXRpbmcpIHtcbiAgICAgIHRoaXMudG9vbGJhckZsb2F0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMudG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICAgIH1cbiAgICB0aGlzLnRvb2xiYXJEcmFnZ2luZyA9IHRydWU7XG4gICAgdGhpcy50b29sYmFyU3RhcnQgPSB7XG4gICAgICBteDogZS5jbGllbnRYLFxuICAgICAgbXk6IGUuY2xpZW50WSxcbiAgICAgIHg6IHRoaXMudG9vbGJhclBvcy54LFxuICAgICAgeTogdGhpcy50b29sYmFyUG9zLnksXG4gICAgfTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvKiogU25hcCB0aGUgZmxvYXRpbmcgdG9vbGJhciBiYWNrIHRvIGl0cyBkb2NrZWQgcG9zaXRpb24gYWNyb3NzIHRoZSB0b3AuICovXG4gIGRvY2tUb29sYmFyKCkge1xuICAgIHRoaXMudG9vbGJhckZsb2F0aW5nID0gZmFsc2U7XG4gIH1cblxuICAvKiogUmVuZGVyIHRoZSBpbnRlbnNpdHkgaW5zZXQgY2hhcnQgZnJvbSB0aGUgbGF0ZXN0IHByb2ZpbGUgZGF0YS4gVGhlIGFjdHVhbFxuICAgKiAgY2hhcnRpbmcgaXMgb3duZWQgYnkgdGhlIHZpc3VhbGl6ZXIgc2VydmljZSDigJQgdGhlIGNvbXBvbmVudCBqdXN0IGRlY2lkZXNcbiAgICogIHdoZW4gKHByb2ZpbGUgbW9kZSArIGEgZnJlc2ggcHJvZmlsZSkuICovXG4gIHByaXZhdGUgcmVuZGVySW50ZW5zaXR5SW5zZXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhhc1Byb2ZpbGVzKSByZXR1cm47XG4gICAgdGhpcy5wbG90U2VydmljZS5yZW5kZXJJbnRlbnNpdHlJbnNldCh0aGlzLmludGVuc2l0eUluc2V0RGl2LCB0aGlzLmxhdGVzdFByb2ZpbGVzKTtcbiAgfVxuXG4gIC8qKiBUb29sYmFyIFwiSW50ZW5zaXR5XCIgZ3JvdXA6IGFkZCBhbm90aGVyIGxpbmUgUk9JIChuZXh0IGJyaWdodCBjb2xvdXIpLiAqL1xuICBhc3luYyBhZGRQcm9maWxlTGluZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBQYXJrIHRoZSBmbG9hdGluZyBpbnNldCBuZWFyIHRoZSBwbG90J3MgdG9wLXJpZ2h0IHdoZW4gdGhlIGZpcnN0IGxpbmUgaXNcbiAgICAvLyBhZGRlZCAoaXQncyBwb3NpdGlvbjpmaXhlZCwgc28gdXNlIHZpZXdwb3J0IGNvb3JkcyBmcm9tIHRoZSBwbG90IHJlY3QpLlxuICAgIGlmICghdGhpcy5oYXNQcm9maWxlcykge1xuICAgICAgY29uc3QgcmVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMucGxvdERpdk5hbWUpPy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHRoaXMucHJvZmlsZVBhbmVsUG9zID0gcmVjdFxuICAgICAgICA/IHsgeDogTWF0aC5tYXgoMTAsIHJlY3QucmlnaHQgLSAzMDApLCB5OiByZWN0LnRvcCArIDEwIH1cbiAgICAgICAgOiB7IHg6IDIwLCB5OiA3MCB9O1xuICAgIH1cbiAgICAvLyBJbWFnZSAoT1NEKSBtb2RlOiBQbG90bHkgbmV2ZXIgcmVuZGVyZWQsIHNvIGl0IGhhcyBubyBwaXhlbCBjYWNoZSAvIGV4dGVudC5cbiAgICAvLyBMb2FkIHRoZSBjdXJyZW50IHNsaWNlJ3MgZnJhbWVzIGZvciBzYW1wbGluZyArIGxpbmUgcGxhY2VtZW50IGZpcnN0LlxuICAgIGlmICh0aGlzLmlzSW1hZ2VWaWV3ICYmIHRoaXMuaW1hZ2VJbmZvKSB7XG4gICAgICBhd2FpdCB0aGlzLnBsb3RTZXJ2aWNlLmVuc3VyZUludGVuc2l0eVNhbXBsaW5nKHRoaXMuaW1hZ2VJbmZvLCB0aGlzLnpJbmRleCk7XG4gICAgfVxuICAgIGNvbnN0IHJlZ2lvbiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0SW50ZW5zaXR5Q29udHJvbHMoKT8uYWRkUHJvZmlsZUxpbmUoKTtcbiAgICAvLyBBdXRvLXNlbGVjdCB0aGUgbmV3IGxpbmUgb24gdGhlIGFjdGl2ZSBiYWNrZW5kIChQbG90bHkgaGFuZGxlcyAvIE9TRFxuICAgIC8vIGhpZ2hsaWdodCkgc28gaXQncyByZWFkeSB0byBtb3ZlIG9yIGRlbGV0ZSBpbW1lZGlhdGVseS5cbiAgICBpZiAocmVnaW9uKSB7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNlbGVjdFJlZ2lvbihyZWdpb24pO1xuICAgICAgLy8gT1NEIG9ubHkgZHJhd3MgYSBzZWxlY3RlZCByZWdpb24ncyBoYW5kbGVzIGluIGFuIGVkaXQgbW9kZSwgc28gYSBsaW5lIGluXG4gICAgICAvLyAnbm9uZScgbW9kZSBsb29rcyB1bnNlbGVjdGVkLiBTd2l0Y2ggdG8gJ3NlbGVjdCcgc28gdGhlIG5ldyBsaW5lIHNob3dzXG4gICAgICAvLyBpdHMgZW5kcG9pbnQgaGFuZGxlcyBhbmQgY2FuIGJlIGRyYWdnZWQvZGVsZXRlZCByaWdodCBhd2F5LlxuICAgICAgaWYgKHRoaXMuaXNJbWFnZVZpZXcgJiYgdGhpcy5hY3RpdmVEcmFnTW9kZSAhPT0gJ3NlbGVjdCcpIHtcbiAgICAgICAgdGhpcy50b2dnbGVEcmFnTW9kZSgnc2VsZWN0Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgLy8gTGVhdmUgdGhlIGxpdmUgc2V0IHNvIHRoZSBuZXh0LW9sZGVzdCB2aXN1YWxpemVyIHBpY2tzIHVwIHRoZSBvdXRsZXRzLlxuICAgIFZpc3VhbGl6ZXJDb21wb25lbnQubGl2ZUluc3RhbmNlcy5kZWxldGUodGhpcyk7XG4gICAgdGhpcy5yZXZva2VWb2x1bWVJbWFnZVVybHMoKTtcbiAgICB0aGlzLnNjcnViYmVyLmNhbmNlbCgpO1xuICAgIHRoaXMuc2FtUG9pbnRTdWIudW5zdWJzY3JpYmUoKTtcbiAgICBpZiAodGhpcy5wbG90Q29udGV4dE1lbnVMaXN0ZW5lcikge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgdGhpcy5wbG90Q29udGV4dE1lbnVMaXN0ZW5lciwgdHJ1ZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmtleWRvd25MaXN0ZW5lcikge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmtleWRvd25MaXN0ZW5lcik7XG4gICAgfVxuICAgIGlmICh0aGlzLndoZWVsTGlzdGVuZXIpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCd3aGVlbCcsIHRoaXMud2hlZWxMaXN0ZW5lciwgdHJ1ZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLnByb2ZpbGVEcmFnTW92ZUxpc3RlbmVyKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5wcm9maWxlRHJhZ01vdmVMaXN0ZW5lcik7XG4gICAgfVxuICAgIGlmICh0aGlzLnByb2ZpbGVEcmFnVXBMaXN0ZW5lcikge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLnByb2ZpbGVEcmFnVXBMaXN0ZW5lcik7XG4gICAgfVxuICAgIGlmICh0aGlzLnByb2ZpbGVSZXNpemVMaXN0ZW5lcikge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMucHJvZmlsZVJlc2l6ZUxpc3RlbmVyKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaW50ZW5zaXR5UHJvZmlsZVN1Yikge1xuICAgICAgdGhpcy5pbnRlbnNpdHlQcm9maWxlU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnZpZXdwb3J0Q2hhbmdlU3ViKSB7XG4gICAgICB0aGlzLnZpZXdwb3J0Q2hhbmdlU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIHRoaXMudW5zdWIubmV4dCgpO1xuICAgIHRoaXMudW5zdWIuY29tcGxldGUoKTtcbiAgICBpZiAodGhpcy5wcmV2aWV3U3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnByZXZpZXdTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3BhdGlhbERhdGFzZXRTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuc3BhdGlhbERhdGFzZXRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGxvdFdpZHRoU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnBsb3RXaWR0aFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pbWFnZUxvYWRpbmdTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuaW1hZ2VMb2FkaW5nU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmltZ0xvYWRpbmdNZXNzYWdlU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmltZ0xvYWRpbmdNZXNzYWdlU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzWm9vbVN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5pc1pvb21TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuYXV0b3NjYWxlU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmF1dG9zY2FsZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5maWxlbmFtZVN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5maWxlbmFtZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwdWJsaWMgaGFzUmVnaW9ucygpOiBib29sZWFuIHtcbiAgICAvLyBVc2UgdGhlIGNvbnRyYWN0J3MgZnJhbWV3b3JrLW5ldXRyYWwgcmVnaW9uIGFjY2Vzc29yLCBub3QgdGhlIHJhd1xuICAgIC8vIFBsb3RseS1zaGFwZWQgZ2V0U2hhcGVzKCkg4oCUIHRoZSBjb21wb25lbnQgb25seSBuZWVkcyB0byBrbm93IHdoZXRoZXIgYW55XG4gICAgLy8gcmVnaW9uIGV4aXN0cywgYW5kIG11c3Qgbm90IGRlcGVuZCBvbiBhIGJhY2tlbmQncyB3aXJlIGZvcm1hdC5cbiAgICByZXR1cm4gdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25zKCkubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgaW4gbWFpbkZhY2FkZS5jb25maWdSZXF1ZXN0KCkgLSBETyBOT1QgREVMRVRFXG4gICAqL1xuICBwdWJsaWMgZ2V0UmVnaW9uUG9seWdvbnMoKTogUG9seWdvbltdIHtcbiAgICByZXR1cm4gdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25Qb2x5Z29ucygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgY29sb3Igc2NhbGUgdHlwZTogY2FsbGVkIGJ5IHRoZSBjb2xvciBzY2FsZSBzZWxlY3QgYnV0dG9uXG4gICAqIEBwYXJhbSBldmVudFxuICAgKi9cbiAgdG9nZ2xlUmV2ZXJzZVNjYWxlKCkge1xuICAgIHRoaXMucmV2ZXJzZXNjYWxlID0gIXRoaXMucmV2ZXJzZXNjYWxlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0UmV2ZXJzZVNjYWxlKHRoaXMucmV2ZXJzZXNjYWxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgYSBjb2xvciBtYXA6IGNhbGxlZCBieSB0aGUgY29sb3IgbWFwIGRyb3Bkb3duIGJ1dHRvblxuICAgKiBAcGFyYW0gY29sb3JtYXBOb2RlXG4gICAqL1xuICBzZWxlY3RDb2xvcm1hcChjb2xvcm1hcE5vZGU6IFRyZWVOb2RlKSB7XG4gICAgaWYgKCFjb2xvcm1hcE5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0Q29sb3JtYXAoY29sb3JtYXBOb2RlKTtcbiAgICB9XG4gIH1cblxuICAvKiogT3BlbiB0aGUgQ2hhbm5lbHMgJiBIaXN0b2dyYW0gZGlhbG9nICh0b29sYmFyIGJ1dHRvbikuICovXG4gIG9wZW5DaGFubmVsSGlzdG9ncmFtKCkge1xuICAgIHRoaXMuc2hvd0NoYW5uZWxIaXN0b2dyYW0gPSB0cnVlO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIg4oaSIG9wZW4gdGhlIHNwYXRpYWwtb21pY3MgY29udHJvbHMuICovXG4gIG9wZW5TcGF0aWFsQ29udHJvbHMoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93U3BhdGlhbENvbnRyb2xzID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBPcGVuIHRoZSBSZWdpb24gRWRpdG9yIGRpYWxvZyAodG9vbGJhciBidXR0b24pLiBUaGUgZWRpdG9yIHN0YXlzIGxpbmtlZCB0b1xuICAgKiAgdGhpcyBwbG90dGluZyBpbnN0YW5jZSB0aHJvdWdoIHRoZSByb290IFJlZ2lvblN0b3JlIHNpbmdsZXRvbiwgc28gaXQgd29ya3NcbiAgICogIHRoZSBzYW1lIGFzIHRoZSBmb3JtZXIgcmlnaHQtcGFuZWwgUmVnaW9ucyB0YWIuICovXG4gIG9wZW5SZWdpb25FZGl0b3IoKSB7XG4gICAgLy8gU2l6ZSB0aGUgZGlhbG9nIHRvIG1hdGNoIHRoZSBob3N0J3MgY29uZmlndXJlZCBlbGVtZW50IChlLmcuIHRoZSBhcHAnc1xuICAgIC8vIHJpZ2h0IHBhbmVsKSBhdCBvcGVuIHRpbWUuIE1lYXN1cmVkIG9uY2Ug4oCUIGl0IGludGVudGlvbmFsbHkgZG9lcyBub3RcbiAgICAvLyB0cmFjayBsYXRlciBicm93c2VyL3NwbGl0IHJlc2l6ZXMuIEZhbGxzIGJhY2sgdG8gYSBxdWFydGVyIG9mIHRoZSBwYWdlXG4gICAgLy8gd2hlbiBubyBzZWxlY3RvciBpcyBjb25maWd1cmVkIG9yIHRoZSBlbGVtZW50IGlzbid0IHByZXNlbnQuXG4gICAgY29uc3Qgc2VsZWN0b3IgPSB0aGlzLnZpekNvbmZpZz8ucmVnaW9uRWRpdG9yV2lkdGhTZWxlY3RvcjtcbiAgICBjb25zdCB3aWR0aCA9IHNlbGVjdG9yXG4gICAgICA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KHNlbGVjdG9yKT8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGhcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMucmVnaW9uRWRpdG9yV2lkdGggPSB3aWR0aCAmJiB3aWR0aCA+IDAgPyBgJHtNYXRoLnJvdW5kKHdpZHRoKX1weGAgOiAnMjV2dyc7XG4gICAgdGhpcy5zaG93UmVnaW9uRWRpdG9yID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgYnkgdGhlIHN0YWNrL3NpbmdsZSBpbWFnZSBkcm9wZG93biBidXR0b25cbiAgICogQHBhcmFtIHNob3dzdGFja1xuICAgKi9cbiAgc2VsZWN0U3RhY2tPcHRpb24oc2VsZWN0ZWRTdGFja09wdGlvbjogYW55KSB7XG4gICAgY29uc3Qgc2hvd3N0YWNrID0gc2VsZWN0ZWRTdGFja09wdGlvbi52YWwgPT09ICd0cnVlJztcbiAgICB0aGlzLnNlbGVjdGVkU3RhY2tPcHRpb24gPSBzZWxlY3RlZFN0YWNrT3B0aW9uO1xuICAgIGNvbnNvbGUubG9nKCdzZWxlY3RlZCBzdGFjayBvcHRpb24nICsgSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZFN0YWNrT3B0aW9uKSk7XG4gICAgdGhpcy5zdGFja0xvYWRpbmcgPSBzaG93c3RhY2s7XG4gICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoIXNob3dzdGFjayk7XG4gICAgLy8gU3RhY2sgbW9kZSBpcyBhbHdheXMgYSAyRCBoZWF0bWFwIOKAlCByZXNldCBzdXJmYWNlIG1vZGUgaWYgYWN0aXZlXG4gICAgaWYgKCF0aGlzLmlzSGVhdG1hcCkge1xuICAgICAgdGhpcy5pc0hlYXRtYXAgPSB0cnVlO1xuICAgICAgdGhpcy5wbG90VHlwZSA9IFBsb3RUeXBlLkhFQVRNQVA7XG4gICAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGUgPSBQbG90VHlwZS5IRUFUTUFQO1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0aGlzLnBsb3RUeXBlKTtcbiAgICB9XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTaG93U3RhY2soc2hvd3N0YWNrKTtcbiAgfVxuXG4gIHVwZGF0ZVpJbmRleCh1cmxzPzogc3RyaW5nW10pIHtcbiAgICBpZiAodGhpcy56SW5kZXggPiB0aGlzLm1heEluZGV4KSB7XG4gICAgICB0aGlzLnpJbmRleCA9IHRoaXMubWF4SW5kZXg7XG4gICAgfVxuICAgIGlmICh0aGlzLnpJbmRleCA8IDApIHtcbiAgICAgIHRoaXMuekluZGV4ID0gMDtcbiAgICB9XG4gICAgaWYgKHVybHMpIHtcbiAgICAgIGlmICh0aGlzLnpJbmRleCA+IHVybHM/Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLnpJbmRleCA9IDA7XG4gICAgICAgIHRoaXMubWF4SW5kZXggPSB1cmxzLmxlbmd0aCAtIDE7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0WkluZGV4KHRoaXMuekluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXZlIHotc2xpY2Ugc2NydWIgZm9yIHRoZSBJbWFnZSB2aWV3OiB0aGUgcmVuZGVyZXIgc3dhcHMgdGhlIGRpc3BsYXllZFxuICAgKiBzbGljZSBpbiBwbGFjZSAobm8gcmUtbW91bnQpLCBzbyBkcmFnZ2luZyB0aGUgc2xpZGVyIHN0ZXBzIHRocm91Z2ggdGhlXG4gICAqIHN0YWNrIHRoZSBzYW1lIHdheSB0aGUgaGVhdG1hcCBmcmFtZSBzbGlkZXIgZG9lcy5cbiAgICovXG4gIG9uWlNsaWRlKHo6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIGlmICh6ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICB0aGlzLnpJbmRleCA9IHo7XG4gICAgdGhpcy5zY3J1YmJlci5jb21taXQoeik7XG4gICAgLy8gS2VlcCB0aGUgaW50ZW5zaXR5IGluc2V0IGluIHN5bmMgd2l0aCB0aGUgZGlzcGxheWVkIHNsaWNlIChJbWFnZS9PU0QgbW9kZSxcbiAgICAvLyB3aGVyZSB0aGUgcHJvZmlsZSBzYW1wbGVyIGlzIGZlZCBmcm9tIHRoZSBsb2FkZWQgcHJldmlldyBmcmFtZXMpLlxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGVzICYmIHRoaXMuaXNJbWFnZVZpZXcgJiYgdGhpcy5pbWFnZUluZm8pIHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UuZW5zdXJlSW50ZW5zaXR5U2FtcGxpbmcodGhpcy5pbWFnZUluZm8sIHopO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXZlIChkZWJvdW5jZWQpIHNjcnViIHdoaWxlIGRyYWdnaW5nIHRoZSBJbWFnZS12aWV3IHotc2xpZGVyOiB1cGRhdGUgdGhlXG4gICAqIHNsaWNlIGFzIHRoZSB1c2VyIGRyYWdzLCBidXQgY29hbGVzY2UgcmFwaWQgY2hhbmdlcyBzbyB3ZSBkb24ndCBmaXJlIGFcbiAgICogc2xpY2Ugc3dhcCBvbiBldmVyeSBwaXhlbC4gVGhlIGZpbmFsIHZhbHVlIGFsc28gbGFuZHMgdmlhIG9uWlNsaWRlIChvblNsaWRlRW5kKS5cbiAgICovXG4gIG9uWlNjcnViKHo6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIGlmICh6ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICB0aGlzLnpJbmRleCA9IHo7XG4gICAgdGhpcy5zY3J1YmJlci5zY3J1Yih6KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBLZXlib2FyZCBzdGFjayBuYXZpZ2F0aW9uOiDihpAv4oaSIHN0ZXAgdGhlIHotc2xpY2UgaW4gdGhlIEltYWdlIHZpZXcsIHRoZSBzYW1lXG4gICAqIHdheSB0aGUgc2xpZGVyIGRvZXMuIE9ubHkgYWN0aXZlIGZvciBhIGxvYWRlZCBzdGFjayBpbiBJbWFnZSB2aWV3LCBhbmRcbiAgICogaWdub3JlZCB3aGlsZSBhIGZvcm0gZmllbGQgaXMgZm9jdXNlZCBzbyB0eXBpbmcgaXNuJ3QgaGlqYWNrZWQuIFVwL0Rvd24gYXJlXG4gICAqIGxlZnQgdG8gT3BlblNlYWRyYWdvbiAocGFubmluZykuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bicsIFsnJGV2ZW50J10pXG4gIG9uS2V5ZG93bihlOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGUua2V5ICE9PSAnQXJyb3dMZWZ0JyAmJiBlLmtleSAhPT0gJ0Fycm93UmlnaHQnKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmltYWdlSW5mbz8uaXNTdGFjayB8fCAhdGhpcy5pc0ltYWdlVmlldykgcmV0dXJuO1xuICAgIGNvbnN0IHQgPSBlLnRhcmdldCBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKHQgJiYgKC9eKElOUFVUfFRFWFRBUkVBfFNFTEVDVCkkLy50ZXN0KHQudGFnTmFtZSkgfHwgdC5pc0NvbnRlbnRFZGl0YWJsZSkpIHJldHVybjtcbiAgICAvLyBUaGUgc2xpY2Ugc2xpZGVyIGhhbmRsZXMgYXJyb3dzIG5hdGl2ZWx5IHdoZW4gZm9jdXNlZCAoYWxzbyBhICsxIHN0ZXApIOKAlFxuICAgIC8vIHNraXAgaGVyZSBzbyB3ZSBkb24ndCBkb3VibGUtc3RlcCBpdC5cbiAgICBpZiAodCAmJiAodC5nZXRBdHRyaWJ1dGUoJ3JvbGUnKSA9PT0gJ3NsaWRlcicgfHwgdC5jbG9zZXN0KCcucC1zbGlkZXInKSkpIHJldHVybjtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zdGVwU2xpY2UoZS5rZXkgPT09ICdBcnJvd1JpZ2h0JyA/IDEgOiAtMSk7XG4gIH1cblxuICAvKiogTW92ZSB0aGUgZGlzcGxheWVkIHNsaWNlIGJ5IGBkZWx0YWAsIGNsYW1wZWQgdG8gdGhlIHN0YWNrIGJvdW5kcy4gKi9cbiAgc3RlcFNsaWNlKGRlbHRhOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gTWF0aC5taW4odGhpcy5tYXhJbmRleCwgTWF0aC5tYXgoMCwgdGhpcy56SW5kZXggKyBkZWx0YSkpO1xuICAgIGlmIChuZXh0ID09PSB0aGlzLnpJbmRleCkgcmV0dXJuO1xuICAgIHRoaXMub25aU2xpZGUobmV4dCk7XG4gIH1cblxuICByZWxvYWRBbmRQbG90KCkge1xuICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKHRydWUpO1xuICAgIC8vIFJlLWRyaXZlIHRoZSByZW5kZXIgcGlwZWxpbmUgZnJvbSB0aGUgY3VycmVudCBpbWFnZSBpbmZvICh0aGUgc291cmNlIG9mXG4gICAgLy8gdHJ1dGgsIHdpdGggcmVhbCB1cmxzL2ZpbGVOYW1lKS4gRG9uJ3QgdXNlIHBsb3RTZXJ2aWNlLnJlbG9hZEFuZFBsb3QoKTpcbiAgICAvLyB0aGF0IHJlYnVpbGRzIHRoZSBpbmZvIGZyb20gdGhlIHJlbmRlcmVyJ3MgaW50ZXJuYWwgc3RhdGUsIHdoaWNoIGNhbiBiZVxuICAgIC8vIHN0YWxlIChlLmcuIGFmdGVyIHN3aXRjaGluZyBwbG90IHR5cGUgSW1hZ2UgLT4gSGVhdG1hcCkgYW5kIHJlLWVtaXRcbiAgICAvLyBlbXB0eS9vbGQgdXJscywgZmFpbGluZyB0byBoYW5kIHRoZSBkaXYgb3ZlciB0byB0aGUgbmV3IHJlbmRlcmVyLlxuICAgIGlmICh0aGlzLmltYWdlSW5mbykge1xuICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUluZm8odGhpcy5pbWFnZUluZm8pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlbG9hZEFuZFBsb3QoKTtcbiAgICB9XG4gIH1cbiAgY2FuY2VsTG9hZGluZygpIHtcbiAgICAvLyBTdG9wIGFueSBpbi1mbGlnaHQgZnJhbWUgc3RyZWFtaW5nIChuYXBhcmktanMgdm9sdW1lL3N1cmZhY2UgcHJlbG9hZCkgc28gdGhlIGZldGNoIGxvb3BzXG4gICAgLy8gYWN0dWFsbHkgYWJvcnQg4oCUIGNsZWFyaW5nIHRoZSBmbGFnIGFsb25lIG9ubHkgcm91dGVkIHRvIFBsb3RseSBhbmQgbGVmdCBuYXBhcmkgZmV0Y2hpbmcuXG4gICAgdGhpcy5wbG90U2VydmljZS5jYW5jZWxMb2FkaW5nPy4oKTtcbiAgICB0aGlzLnN0YWNrTG9hZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuaW1nTG9hZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICB0aGlzLnpJbmRleCA9IDA7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRaSW5kZXgodGhpcy56SW5kZXgpO1xuICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U3RhY2tMb2FkaW5nKGZhbHNlKTtcbiAgfVxuXG4gIGRvd25sb2FkSW1hZ2UoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5kb3dubG9hZEltYWdlKCk7XG4gIH1cblxuICBhdXRvc2NhbGVJbWFnZSgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmF1dG9zY2FsZSgpO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIgcGl4ZWwvc21vb3RoIHRvZ2dsZTogZmxpcCBzbW9vdGhpbmcgYW5kIGFwcGx5IHRvIHRoZSBhY3RpdmUgYmFja2VuZC4gKi9cbiAgb25Ub2dnbGVJbWFnZVNtb290aGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZCA9ICF0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZDtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldEltYWdlU21vb3RoaW5nRW5hYmxlZCh0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZCk7XG4gIH1cblxuICByZXNldEF4ZXMoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5yZXNldEF4ZXMoKTtcbiAgfVxuXG4gIHRvZ2dsZURyYWdNb2RlKG1vZGU6IHN0cmluZykge1xuICAgIC8vIFRvZ2dsZSBvZmYgaWYgdGhlIHNhbWUgbW9kZSBpcyByZS1zZWxlY3RlZC5cbiAgICB0aGlzLmFjdGl2ZURyYWdNb2RlID0gdGhpcy5hY3RpdmVEcmFnTW9kZSA9PT0gbW9kZSA/IG51bGwgOiBtb2RlO1xuICAgIGNvbnN0IGFjdGl2ZSA9IHRoaXMuYWN0aXZlRHJhZ01vZGU7XG4gICAgLy8gUmVjb3JkIHRoZSBhcm1lZCB0b29sIGluIHRoZSBzaGFyZWQgc2Vzc2lvbiBzdG9yZS5cbiAgICB0aGlzLnNlc3Npb24uc2V0QWN0aXZlVG9vbChhY3RpdmUpO1xuXG4gICAgLy8gUmVnaW9uIGRyYXcvc2VsZWN0IHJ1biB0aHJvdWdoIHRoZSByZW5kZXJlcidzIHJlZ2lvbiBvdmVybGF5LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRSZWdpb25PdmVybGF5KClcbiAgICAgID8uc2V0TW9kZSh0aGlzLmlzUmVnaW9uTW9kZShhY3RpdmUpID8gKGFjdGl2ZSBhcyBSZWdpb25Ub29sTW9kZSkgOiAnbm9uZScpO1xuXG4gICAgLy8gVmlld3BvcnQgZHJhZyBtb2RlcyAocGFuL2JveC16b29tKS4gUmVnaW9uIG1vZGVzIG93biB0aGUgZHJhZyBtb2RlIHZpYVxuICAgIC8vIHRoZSBvdmVybGF5LCBzbyBkb24ndCBhbHNvIHNldCBvbmUgaGVyZS5cbiAgICBpZiAoIXRoaXMuaXNSZWdpb25Nb2RlKGFjdGl2ZSkpIHtcbiAgICAgIGNvbnN0IHZpZXdwb3J0RHJhZyA9IGFjdGl2ZSA9PT0gJ3BhbicgfHwgYWN0aXZlID09PSAnem9vbSc7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldERyYWdNb2RlKHZpZXdwb3J0RHJhZyA/IGFjdGl2ZSA6IGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyBPbi1jYW52YXMgdG9vbCBvdmVybGF5cy5cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpvb21Ub0JveE1vZGUoYWN0aXZlID09PSAnem9vbVRvQm94Jyk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRXYW5kTW9kZShhY3RpdmUgPT09ICd3YW5kJywgeyBzZW5zaXRpdml0eTogdGhpcy53YW5kU2Vuc2l0aXZpdHkgfSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRCcnVzaE1vZGUoYWN0aXZlID09PSAnYnJ1c2gnLCB7IHNpemU6IHRoaXMuYnJ1c2hTaXplIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2FtUG9pbnRNb2RlKGFjdGl2ZSA9PT0gJ3NhbVBvaW50Jyk7XG4gICAgLy8gTGVhdmluZyBwb2ludCBtb2RlIGRpc21pc3NlcyBhbnkgbGluZ2VyaW5nIHN0YXR1cyB0b2FzdC5cbiAgICBpZiAoYWN0aXZlICE9PSAnc2FtUG9pbnQnKSB0aGlzLmhpZGVTYW1Ub2FzdCgpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0VmVydGV4RXJhc2VyTW9kZShhY3RpdmUgPT09ICdlcmFzZVZlcnRleCcpO1xuICAgIGlmIChhY3RpdmUgPT09ICdlcmFzZVZlcnRleCcpIHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0VmVydGV4RXJhc2VyUmFkaXVzKHRoaXMudmVydGV4RXJhc2VyUmFkaXVzKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVnaW9uIGRyYXcvc2VsZWN0L2VkaXQgbW9kZXMgcm91dGVkIHRocm91Z2ggdGhlIHJlZ2lvbiBvdmVybGF5LiBUaGVcbiAgICogIFRoZSB2ZXJ0ZXggdG9vbHMgKGRyYXdwb2x5Z29uL2FkZHBvaW50L2RlbGV0ZXBvaW50L21vdmUpIGFyZVxuICAgKiAgaGFuZGxlZCBieSB0aGUgT3BlblNlYWRyYWdvbiBvdmVybGF5OyBQbG90bHkncyBvdmVybGF5IG1hcHMgdGhlbSB0byBuby1vcC4gKi9cbiAgcHJpdmF0ZSBpc1JlZ2lvbk1vZGUobW9kZTogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBtb2RlID09PSAnZHJhd3JlY3QnIHx8XG4gICAgICBtb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnIHx8XG4gICAgICBtb2RlID09PSAnZHJhd29wZW5wYXRoJyB8fFxuICAgICAgbW9kZSA9PT0gJ3NlbGVjdCcgfHxcbiAgICAgIG1vZGUgPT09ICdkcmF3cG9seWdvbicgfHxcbiAgICAgIG1vZGUgPT09ICdhZGRwb2ludCcgfHxcbiAgICAgIG1vZGUgPT09ICdkZWxldGVwb2ludCcgfHxcbiAgICAgIG1vZGUgPT09ICdtb3ZlJ1xuICAgICk7XG4gIH1cblxuICAvKiogTGl2ZS11cGRhdGUgdGhlIGlzb3N1cmZhY2UgYXMgdGhlIHJhbmdlIHNsaWRlciBtb3Zlcy4gVGhlIGNvbnRyb2wgaXMgb25seVxuICAgKiAgYXZhaWxhYmxlIHdoZW4gdGhlIGFjdGl2ZSBiYWNrZW5kIHJlbmRlcnMgaXNvc3VyZmFjZXMgKElTT1NVUkZBQ0UgbW9kZSkuICovXG4gIG9uSXNvUmFuZ2VDaGFuZ2UodmFsdWVzOiBudW1iZXJbXSB8IHVuZGVmaW5lZCkge1xuICAgIGlmICghdmFsdWVzIHx8IHZhbHVlcy5sZW5ndGggPCAyKSByZXR1cm47XG4gICAgdGhpcy5pc29SYW5nZSA9IHZhbHVlcztcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldElzb3N1cmZhY2VDb250cm9scygpPy5zZXRJc29SYW5nZSh2YWx1ZXNbMF0sIHZhbHVlc1sxXSk7XG4gIH1cblxuICBvbldhbmRTZW5zaXRpdml0eUNoYW5nZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLndhbmRTZW5zaXRpdml0eSA9IHZhbHVlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0V2FuZE9wdGlvbnMoeyBzZW5zaXRpdml0eTogdmFsdWUgfSk7XG4gIH1cblxuICBvbkJydXNoU2l6ZUNoYW5nZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLmJydXNoU2l6ZSA9IHZhbHVlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0QnJ1c2hPcHRpb25zKHsgc2l6ZTogdmFsdWUgfSk7XG4gIH1cblxuICBvblZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLnZlcnRleEVyYXNlclJhZGl1cyA9IHZhbHVlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0VmVydGV4RXJhc2VyUmFkaXVzKHZhbHVlKTtcbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnpvb21JbigpO1xuICB9XG5cbiAgem9vbU91dCgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnpvb21PdXQoKTtcbiAgfVxuXG4gIGRlbGV0ZVJlZ2lvbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmRlbGV0ZUFjdGl2ZVNoYXBlKCk7XG4gIH1cblxuICAvKiogVW5kbyB0aGUgbW9zdCByZWNlbnQgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gVXAgdG8gMTAgc3RlcHMgYmFjay4gKi9cbiAgdW5kb1JlZ2lvbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnVuZG8oKTtcbiAgfVxuXG4gIC8qKiBSZWRvIHRoZSBtb3N0IHJlY2VudGx5IHVuZG9uZSByZWdpb24gYWN0aW9uIChqaXQtdWkjODUpLiAqL1xuICByZWRvUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UucmVkbygpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFJlZ2lvbiBzZXQtb3BlcmF0aW9ucyBvbiB0aGUgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM4NSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRoZSBjdXJyZW50bHktc2VsZWN0ZWQgcmVnaW9ucyAobGl2ZSBzdG9yZSBpbnN0YW5jZXMpLiAqL1xuICBwcml2YXRlIGdldCBzZWxlY3RlZFJlZ2lvbnMoKTogUmVnaW9uW10ge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpO1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkSW5kaWNlc1xuICAgICAgLm1hcCgoaSkgPT4gYWxsW2ldKVxuICAgICAgLmZpbHRlcigocik6IHIgaXMgUmVnaW9uID0+ICEhcik7XG4gIH1cblxuICAvKiogUmVnaW9ucyBlbGlnaWJsZSBmb3Igc2V0LW9wczogY2xvc2VkIGFyZWFzIChyZWN0IC8gY2xvc2VkIHBvbHlnb24gL1xuICAgKiAgbXVsdGktcG9seWdvbiksIGV4Y2x1ZGluZyBpbnRlbnNpdHktcHJvZmlsZSBsaW5lcy4gKi9cbiAgcHJpdmF0ZSBvcEVsaWdpYmxlKHJlZ2lvbnM6IFJlZ2lvbltdKTogUmVnaW9uW10ge1xuICAgIHJldHVybiByZWdpb25zLmZpbHRlcigocikgPT4gci5raW5kICE9PSAncHJvZmlsZScgJiYgKFxuICAgICAgci5ib3VuZHMgaW5zdGFuY2VvZiBSZWN0YW5nbGUgfHxcbiAgICAgIHIuYm91bmRzIGluc3RhbmNlb2YgTXVsdGlQb2x5Z29uIHx8XG4gICAgICAoci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uICYmIHIuYm91bmRzLmNsb3NlZCAhPT0gZmFsc2UpXG4gICAgKSk7XG4gIH1cblxuICAvKiogSW1hZ2UgcGl4ZWwgZGltZW5zaW9ucyBmb3IgdGhlIHJhc3RlciBvcHM7IGZhbGxzIGJhY2sgdG8gdGhlIHNlbGVjdGlvbidzXG4gICAqICBleHRlbnQgd2hlbiB0aGUgaW1hZ2Ugc2l6ZSBpc24ndCBrbm93biAoa2VlcHMgY2xhbXBpbmcgc2FuZSkuICovXG4gIHByaXZhdGUgb3BJbWFnZURpbXMocmVnaW9uczogUmVnaW9uW10pOiB7IHc6IG51bWJlcjsgaDogbnVtYmVyIH0ge1xuICAgIGxldCBbdywgaF0gPSB0aGlzLmltYWdlSW5mbz8udHJ1ZUltYWdlU2l6ZSA/PyBbMCwgMF07XG4gICAgaWYgKCEodyA+IDApIHx8ICEoaCA+IDApKSB7XG4gICAgICBsZXQgbWF4WCA9IDAsIG1heFkgPSAwO1xuICAgICAgY29uc3Qgc2NhbiA9ICh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHggb2YgeHMpIG1heFggPSBNYXRoLm1heChtYXhYLCB4KTtcbiAgICAgICAgZm9yIChjb25zdCB5IG9mIHlzKSBtYXhZID0gTWF0aC5tYXgobWF4WSwgeSk7XG4gICAgICB9O1xuICAgICAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICAgICAgY29uc3QgYiA9IHIuYm91bmRzO1xuICAgICAgICBpZiAoYiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkgc2NhbihbYi54ICsgYi53aWR0aF0sIFtiLnkgKyBiLmhlaWdodF0pO1xuICAgICAgICBlbHNlIGlmIChiIGluc3RhbmNlb2YgUG9seWdvbikgc2NhbihiLnhwb2ludHMsIGIueXBvaW50cyk7XG4gICAgICAgIGVsc2UgaWYgKGIgaW5zdGFuY2VvZiBNdWx0aVBvbHlnb24pIGZvciAoY29uc3QgcCBvZiBiLnBvbHlnb25zKSBzY2FuKHAueHBvaW50cywgcC55cG9pbnRzKTtcbiAgICAgIH1cbiAgICAgIHcgPSBNYXRoLm1heCh3LCBNYXRoLmNlaWwobWF4WCkgKyAyKTtcbiAgICAgIGggPSBNYXRoLm1heChoLCBNYXRoLmNlaWwobWF4WSkgKyAyKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgdywgaCB9O1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiDiiaUyIGVsaWdpYmxlIHJlZ2lvbnMgYXJlIHNlbGVjdGVkIChNZXJnZSBhdmFpbGFibGUpLiAqL1xuICBnZXQgY2FuTWVyZ2VSZWdpb25zKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKS5sZW5ndGggPj0gMjsgfVxuICAvKiogVHJ1ZSB3aGVuIGFueSBzZWxlY3RlZCByZWdpb24gaXMgbXVsdGktcGFydCAoVW5ncm91cCBhdmFpbGFibGUpLiAqL1xuICBnZXQgY2FuVW5ncm91cFJlZ2lvbnMoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNlbGVjdGVkUmVnaW9ucy5zb21lKChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5jYW5Vbmdyb3VwKHIpKTsgfVxuICAvKiogVHJ1ZSB3aGVuIOKJpTEgZWxpZ2libGUgcmVnaW9uIGlzIHNlbGVjdGVkIChJbnZlcnNlIC8gU2ltcGxpZnkgYXZhaWxhYmxlKS4gKi9cbiAgZ2V0IGhhc0VsaWdpYmxlU2VsZWN0aW9uKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKS5sZW5ndGggPj0gMTsgfVxuXG4gIC8qKiBTZWxlY3QgZXZlcnkgcmVnaW9uIG9uIHRoZSBpbWFnZSAoZXhjbHVkZXMgaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMpLiAqL1xuICBzZWxlY3RBbGxSZWdpb25zKCk6IHZvaWQge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gW107XG4gICAgYWxsLmZvckVhY2goKHIsIGkpID0+IHsgaWYgKHIua2luZCAhPT0gJ3Byb2ZpbGUnKSBpbmRpY2VzLnB1c2goaSk7IH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoaW5kaWNlcyk7XG4gIH1cblxuICAvKiogTWVyZ2UgdGhlIHNlbGVjdGVkIHJlZ2lvbnMgaW50byBhIHNpbmdsZSAocG9zc2libHkgbXVsdGktcGFydCkgcmVnaW9uLiAqL1xuICBtZXJnZVJlZ2lvbnMoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKTtcbiAgICBpZiAoc2VsLmxlbmd0aCA8IDIpIHJldHVybjtcbiAgICBjb25zdCB7IHcsIGggfSA9IHRoaXMub3BJbWFnZURpbXMoc2VsKTtcbiAgICBjb25zdCBtZXJnZWQgPSB0aGlzLnJlZ2lvbk9wcy5tZXJnZShzZWwsIHcsIGgpO1xuICAgIGlmIChtZXJnZWQpIHRoaXMucmVwbGFjZVJlZ2lvbnMoc2VsLCBbbWVyZ2VkXSk7XG4gIH1cblxuICAvKiogU3BsaXQgZWFjaCBzZWxlY3RlZCBtdWx0aS1wYXJ0IHJlZ2lvbiBpbnRvIG9uZSByZWdpb24gcGVyIHBhcnQuICovXG4gIHVuZ3JvdXBSZWdpb25zKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb25zLmZpbHRlcigocikgPT4gdGhpcy5yZWdpb25PcHMuY2FuVW5ncm91cChyKSk7XG4gICAgaWYgKHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCByZXN1bHRzOiBSZWdpb25bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgciBvZiBzZWwpIHJlc3VsdHMucHVzaCguLi50aGlzLnJlZ2lvbk9wcy51bmdyb3VwKHIpKTtcbiAgICB0aGlzLnJlcGxhY2VSZWdpb25zKHNlbCwgcmVzdWx0cyk7XG4gIH1cblxuICAvKiogUmVwbGFjZSB0aGUgc2VsZWN0aW9uIHdpdGggaXRzIGludmVyc2UgaW5zaWRlIHRoZSBpbWFnZSByZWN0YW5nbGUuICovXG4gIGludmVyc2VSZWdpb25zKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMub3BFbGlnaWJsZSh0aGlzLnNlbGVjdGVkUmVnaW9ucyk7XG4gICAgaWYgKHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCB7IHcsIGggfSA9IHRoaXMub3BJbWFnZURpbXMoc2VsKTtcbiAgICBjb25zdCBpbnYgPSB0aGlzLnJlZ2lvbk9wcy5pbnZlcnNlKHNlbCwgdywgaCk7XG4gICAgaWYgKCFpbnYpIHtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAga2V5OiB0aGlzLnJlc3VsdFRvYXN0S2V5LFxuICAgICAgICBzZXZlcml0eTogJ3dhcm4nLCBzdW1tYXJ5OiAnSW52ZXJzZScsXG4gICAgICAgIGRldGFpbDogJ05vdGhpbmcgdG8gaW52ZXJ0IOKAlCBzZWxlY3Qgb25lIG9yIG1vcmUgY2xvc2VkIHJlZ2lvbnMgZmlyc3QuJyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlcGxhY2VSZWdpb25zKHNlbCwgW2ludl0pO1xuICB9XG5cbiAgLyoqIERvdWdsYXPigJNQZXVja2VyIHNpbXBsaWZ5IGVhY2ggc2VsZWN0ZWQgcmVnaW9uIGJ5IGB0aHJlc2hvbGRQeGAuICovXG4gIHNpbXBsaWZ5UmVnaW9ucyh0aHJlc2hvbGRQeDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKTtcbiAgICBpZiAoc2VsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIHRoaXMucmVwbGFjZVJlZ2lvbnMoc2VsLCBzZWwubWFwKChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5zaW1wbGlmeShyLCB0aHJlc2hvbGRQeCkpKTtcbiAgICB0aGlzLmRpc3BsYXlTaW1wbGlmeURpYWxvZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIE9wZW4gdGhlIGN1c3RvbS10aHJlc2hvbGQgc2ltcGxpZnkgZGlhbG9nLiAqL1xuICBvcGVuU2ltcGxpZnlEaWFsb2coKTogdm9pZCB7IHRoaXMuZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gdHJ1ZTsgfVxuXG4gIC8qKlxuICAgKiBDb21taXQgYSBzZXQtb3A6IGRyb3AgdGhlIGByZW1vdmVgIHJlZ2lvbnMsIGFwcGVuZCBgYWRkYCwgYW5kIHNlbGVjdCB0aGVcbiAgICogcmVzdWx0cy4gR29lcyB0aHJvdWdoIHNldFJlZ2lvbnMgc28gaXQncyB1bmRvLXRyYWNrZWQgYW5kIHJlLXJlbmRlcmVkO1xuICAgKiBwcm9maWxlIGxpbmVzIGFuZCB1bnNlbGVjdGVkIHJlZ2lvbnMgYXJlIHByZXNlcnZlZC5cbiAgICovXG4gIHByaXZhdGUgcmVwbGFjZVJlZ2lvbnMocmVtb3ZlOiBSZWdpb25bXSwgYWRkOiBSZWdpb25bXSk6IHZvaWQge1xuICAgIGlmIChhZGQubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgY29uc3QgcmVtb3ZlU2V0ID0gbmV3IFNldChyZW1vdmUpO1xuICAgIGNvbnN0IGtlcHQgPSB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvbnMoKS5maWx0ZXIoKHIpID0+ICFyZW1vdmVTZXQuaGFzKHIpKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFJlZ2lvbnMoWy4uLmtlcHQsIC4uLmFkZF0pOyAvLyBtaW50cyBpZHMgb24gYGFkZGAsIHJlY29yZHMgdW5kb1xuICAgIGNvbnN0IHN0b3JlZCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IHNlbCA9IGFkZC5tYXAoKHIpID0+IHN0b3JlZC5pbmRleE9mKHIpKS5maWx0ZXIoKGkpID0+IGkgPj0gMCk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyhzZWwpO1xuICB9XG5cbiAgLyoqIEJveC1wcm9tcHRlZCBTQU0gc2VnbWVudGF0aW9uIG9mIHRoZSBkcmF3biByZWN0YW5nbGVzIChqaXQtdWkjOTApLiBBIHN0aWNreVxuICAgKiAgYHNhbWAgdG9hc3Qgc2hvd3MgbGl2ZSBzdGF0dXMgKyBhIGRvd25sb2FkIHByb2dyZXNzIGJhciAoZmlyc3QgcnVuIHB1bGxzIHRoZVxuICAgKiAgZW5jb2RlciwgfjE3MCBNQik7IGl0IHN0YXlzIG9wZW4gdW50aWwgdGhlIHJ1biBmaW5pc2hlcyAoYmFyIGhpdHMgMTAwJSkuICovXG4gIGFzeW5jIHNlZ21lbnRSZWdpb25zKCkge1xuICAgIGF3YWl0IHRoaXMucnVuU2VnbWVudFdpdGhUb2FzdCgnU0FNJywgdGhpcy5zYW1Ub29sLCAoKSA9PiB0aGlzLnBsb3RTZXJ2aWNlLnNlZ21lbnRSZWN0YW5nbGVzKCkpO1xuICB9XG5cbiAgLyoqIEF1dG8tc2VnbWVudCBjZWxscyBpbnNpZGUgZWFjaCBkcmF3biByZWN0YW5nbGUgd2l0aCBjZWxscG9zZS1TQU0sIGNsaWVudC1zaWRlXG4gICAqICAoaml0LXVpIzkwKS4gRWFjaCBib3ggaXMgY3JvcHBlZCAoYnJvd3NlciBzbGlkZS1jcm9wKSB0aGVuIHJ1biB0aHJvdWdoIHRoZVxuICAgKiAgY2VsbHBvc2UtanMgbW9kZWw7IHRoZSBzYW1lIHN0aWNreSBgc2FtYCB0b2FzdCArIHByb2dyZXNzIGJhciBpcyByZXVzZWQuICovXG4gIGFzeW5jIHNlZ21lbnRDZWxscG9zZSgpIHtcbiAgICBhd2FpdCB0aGlzLnJ1blNlZ21lbnRXaXRoVG9hc3QoJ0NlbGxwb3NlJywgdGhpcy5jZWxsU2VnbWVudFRvb2wsICgpID0+XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNlZ21lbnRSZWN0YW5nbGVzQ2VsbHBvc2UoKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcmFtZXRlcnMgY3VycmVudGx5IGJvdW5kIGJ5IHRoZSBnZW5lcmljIHBhcmFtZXRlciBkaWFsb2csIGZvciB3aGljaGV2ZXJcbiAgICogdG9vbCBpcyBvcGVuLiBTZWVkZWQgbGF6aWx5OiBhIHRvb2wncyBkZWZhdWx0cyBhcmUgb25seSBhc2tlZCBmb3Igd2hlbiB0aGVcbiAgICogdXNlciBmaXJzdCB0b3VjaGVzIGl0LCBzbyByZWdpc3RlcmluZyBhIHRvb2wgY29zdHMgbm90aGluZyB1bnRpbCB1c2VkLlxuICAgKi9cbiAgcGFyYW1zRm9yKHRvb2xJZDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybiB7fTtcbiAgICBpZiAoIXRoaXMudG9vbFBhcmFtc1t0b29sSWRdKSB7XG4gICAgICAvLyBUaHJvdWdoIGBzZWVkUGFyYW1zYCwgbm90IGBkZWZhdWx0UGFyYW1zYCBkaXJlY3RseTogdGhlIGFjdGl2ZVxuICAgICAgLy8gY2hlY2twb2ludCdzIG93biBgVG9vbE1vZGVsT3B0aW9uLmRlZmF1bHRzYCBoYXZlIHRvIGJlIG1lcmdlZCBvbiB0b3AuXG4gICAgICAvLyBDYWxsaW5nIGBkZWZhdWx0UGFyYW1zYCBoZXJlIGJ5cGFzc2VkIHRoZW0sIHNvIHRoZSB2ZXJ5IGZpcnN0IHJ1biBvZiBhXG4gICAgICAvLyB0b29sIHVzZWQgdGhlIHRvb2wncyBiYXNlbGluZSB0aHJlc2hvbGRzIGFuZCB0aWxpbmcgcmF0aGVyIHRoYW4gdGhlXG4gICAgICAvLyBtb2RlbCdzIOKAlCBhbmQgaXQgb25seSBjb3JyZWN0ZWQgaXRzZWxmIG9uY2UgdGhlIHVzZXIgc3dpdGNoZWRcbiAgICAgIC8vIGNoZWNrcG9pbnRzIG9yIGhpdCBSZXNldC4gRXZlcnkgZW50cnkgcG9pbnQgbm93IGdvZXMgdGhyb3VnaCBvbmUgcGF0aC5cbiAgICAgIHRoaXMudG9vbFBhcmFtc1t0b29sSWRdID0gdGhpcy5zZWVkUGFyYW1zKHRvb2wsIHRoaXMubW9kZWxJZEZvcih0b29sKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRvb2xQYXJhbXNbdG9vbElkXSE7XG4gIH1cblxuICAvKiogQWN0aXZlIGNoZWNrcG9pbnQgZm9yIGEgdG9vbCwgZmFsbGluZyBiYWNrIHRvIHRoZSB0b29sJ3Mgb3duIGRlZmF1bHQuICovXG4gIG1vZGVsSWRGb3IodG9vbDogVG9vbGJhclRvb2xDb250cmlidXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnRvb2xNb2RlbElkc1t0b29sLmlkXSA/PyB0b29sLmRlZmF1bHRNb2RlbElkKCk7XG4gIH1cblxuICAvKiogU3dpdGNoaW5nIGNoZWNrcG9pbnQgcmUtc2VlZHMgdGhlIHBhcmFtZXRlcnMsIHNpbmNlIHRoZSBkZWZhdWx0cyBiZWxvbmcgdG9cbiAgICogIHRoZSBtb2RlbCByYXRoZXIgdGhhbiB0byB0aGUgdG9vbC4gKi9cbiAgb25Ub29sTW9kZWxDaGFuZ2UoZTogeyB0b29sSWQ6IHN0cmluZzsgbW9kZWxJZDogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICBjb25zdCB0b29sID0gdGhpcy5jb250cmlidXRlZFRvb2xzLmZpbmQoKHQpID0+IHQuaWQgPT09IGUudG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybjtcbiAgICAvLyBSZWFzc2lnbmVkIHJhdGhlciB0aGFuIG11dGF0ZWQgc28gdGhlIHRvb2xiYXIncyBuZ09uQ2hhbmdlcyBzZWVzIGEgbmV3XG4gICAgLy8gcmVmZXJlbmNlIGFuZCByZWJ1aWxkcyB0aGF0IHRvb2wncyBtb2RlbCBtZW51IHdpdGggdGhlIGNoZWNrIG1hcmsgbW92ZWQuXG4gICAgdGhpcy50b29sTW9kZWxJZHMgPSB7IC4uLnRoaXMudG9vbE1vZGVsSWRzLCBbZS50b29sSWRdOiBlLm1vZGVsSWQgfTtcbiAgICB0b29sLm9uTW9kZWxDaGFuZ2U/LihlLm1vZGVsSWQpO1xuICAgIHRoaXMudG9vbFBhcmFtc1tlLnRvb2xJZF0gPSB0aGlzLnNlZWRQYXJhbXModG9vbCwgZS5tb2RlbElkKTtcbiAgfVxuXG4gIC8qKiBBIHRvb2wncyBkZWZhdWx0cyBmb3IgYSBjaGVja3BvaW50LCB3aXRoIHRoYXQgY2hlY2twb2ludCdzIG93biBvdmVycmlkZXNcbiAgICogIGFwcGxpZWQgb24gdG9wIOKAlCBwZXItbW9kZWwgZGVmYXVsdHMgYmVhdCBwZXItdG9vbCBvbmVzLiAqL1xuICBwcml2YXRlIHNlZWRQYXJhbXModG9vbDogVG9vbGJhclRvb2xDb250cmlidXRpb24sIG1vZGVsSWQ6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBtb2RlbCA9IHRvb2wubW9kZWxzKCkuZmluZCgobSkgPT4gbS5pZCA9PT0gbW9kZWxJZCk7XG4gICAgcmV0dXJuIHsgLi4udG9vbC5kZWZhdWx0UGFyYW1zKG1vZGVsSWQpLCAuLi4obW9kZWw/LmRlZmF1bHRzID8/IHt9KSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIE5hcnJvdyBhIHBhcmFtIHNwZWMgZm9yIHRoZSB0ZW1wbGF0ZS5cbiAgICpcbiAgICogYCpuZ1N3aXRjaENhc2VgIGRvZXMgbm90IG5hcnJvdyBhIGRpc2NyaW1pbmF0ZWQgdW5pb24gaW4gQW5ndWxhcidzIHRlbXBsYXRlXG4gICAqIHR5cGUgY2hlY2tlciB0aGUgd2F5IGEgYHN3aXRjaGAgZG9lcyBpbiBUeXBlU2NyaXB0LCBzbyB0aGUgdGVtcGxhdGUgYXNrcyBmb3JcbiAgICogdGhlIHZhcmlhbnQgaXQgaGFzIGFscmVhZHkgbWF0Y2hlZCBvbi5cbiAgICovXG4gIG51bWJlclBhcmFtKHA6IFRvb2xQYXJhbVNwZWMpOiBOdW1iZXJQYXJhbVNwZWMge1xuICAgIHJldHVybiBwIGFzIE51bWJlclBhcmFtU3BlYztcbiAgfVxuXG4gIHNlbGVjdFBhcmFtKHA6IFRvb2xQYXJhbVNwZWMpOiBTZWxlY3RQYXJhbVNwZWMge1xuICAgIHJldHVybiBwIGFzIFNlbGVjdFBhcmFtU3BlYztcbiAgfVxuXG4gIG9wZW5Ub29sUGFyYW1zKHRvb2xJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5wYXJhbXNGb3IodG9vbElkKTsgLy8gc2VlZCBiZWZvcmUgdGhlIGRpYWxvZyBiaW5kcyB0byBpdFxuICAgIHRoaXMub3BlblBhcmFtc1Rvb2xJZCA9IHRvb2xJZDtcbiAgfVxuXG4gIC8qKiBUaGUgdG9vbCB3aG9zZSBwYXJhbWV0ZXIgZGlhbG9nIGlzIG9wZW4sIGZvciB0aGUgZ2VuZXJpYyBkaWFsb2cncyBoZWFkZXJcbiAgICogIGFuZCBmaWVsZCBsaXN0LiAqL1xuICBnZXQgb3BlblBhcmFtc1Rvb2woKTogVG9vbGJhclRvb2xDb250cmlidXRpb24gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdGhpcy5vcGVuUGFyYW1zVG9vbElkKTtcbiAgfVxuXG4gIHJlc2V0VG9vbFBhcmFtcyh0b29sSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdG9vbElkKTtcbiAgICBpZiAodG9vbCkgdGhpcy50b29sUGFyYW1zW3Rvb2xJZF0gPSB0aGlzLnNlZWRQYXJhbXModG9vbCwgdGhpcy5tb2RlbElkRm9yKHRvb2wpKTtcbiAgfVxuXG4gIC8qKiBSdW4gYSBjb250cmlidXRlZCB0b29sIG92ZXIgdGhlIGN1cnJlbnQgdmlldy4gTm8gcHJvbXB0OiB0aGVzZSBzd2VlcCB0aGVcbiAgICogIHdob2xlIHZpZXcgcmF0aGVyIHRoYW4gYmVpbmcgcG9pbnRlZCBhdCBzb21ldGhpbmcuIFJldXNlcyB0aGUgc2hhcmVkXG4gICAqICBzZWdtZW50YXRpb24gdG9hc3Qgc28gcHJvZ3Jlc3MgcmVhZHMgdGhlIHNhbWUgYXMgdGhlIFNBTS9jZWxscG9zZSB0b29scy4gKi9cbiAgYXN5bmMgcnVuVG9vbCh0b29sSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybjtcbiAgICBjb25zdCBwYXJhbXMgPSB7IC4uLnRoaXMucGFyYW1zRm9yKHRvb2xJZCksIG1vZGVsSWQ6IHRoaXMubW9kZWxJZEZvcih0b29sKSB9O1xuICAgIGF3YWl0IHRoaXMucnVuU2VnbWVudFdpdGhUb2FzdCh0b29sLmxhYmVsLCB0b29sLnByb2dyZXNzLCAoKSA9PlxuICAgICAgdG9vbC5ydW4odGhpcy5wbG90U2VydmljZSwgcGFyYW1zKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFNoYXJlZCBkcml2ZXIgZm9yIHRoZSBib3gtcHJvbXB0IHNlZ21lbnQgdG9vbHM6IHdpcmVzIHRoZSB0b29sJ3Mgc3RhdHVzICtcbiAgICogIGRvd25sb2FkIHByb2dyZXNzIGludG8gdGhlIHN0aWNreSBgc2FtYCB0b2FzdCwgcnVucyBgb3BgLCBhbmQgcmVwb3J0cyB0aGVcbiAgICogIHJlZ2lvbiBjb3VudC4gS2VlcHMgdGhlIHRvYXN0IG9wZW4gdW50aWwgdGhlIHJ1biBzZXR0bGVzIChiYXIgaGl0cyAxMDAlKS4gKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5TZWdtZW50V2l0aFRvYXN0KFxuICAgIGxhYmVsOiBzdHJpbmcsXG4gICAgLy8gT2JzZXJ2YWJsZXMgcmF0aGVyIHRoYW4gQmVoYXZpb3JTdWJqZWN0czogYSBjb250cmlidXRlZCB0b29sIGltcGxlbWVudHNcbiAgICAvLyBUb29sUHJvZ3Jlc3MsIGFuZCByZXF1aXJpbmcgYSBjb25jcmV0ZSBzdWJqZWN0IHdvdWxkIGZvcmNlIGV2ZXJ5IHBsdWdpblxuICAgIC8vIHRvIGV4cG9zZSBpdHMgaW50ZXJuYWxzIGp1c3QgdG8gZHJpdmUgdGhpcyB0b2FzdC5cbiAgICB0b29sOiB7IHN0YXR1cyQ6IE9ic2VydmFibGU8c3RyaW5nPjsgcHJvZ3Jlc3MkOiBPYnNlcnZhYmxlPG51bWJlcj4gfSxcbiAgICBvcDogKCkgPT4gUHJvbWlzZTxudW1iZXI+LFxuICApIHtcbiAgICB0aGlzLnNhbVN0YXR1cyA9ICdTdGFydGluZ+KApic7XG4gICAgdGhpcy5zYW1Qcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5zYW1Eb3dubG9hZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuc2FtQnVzeSA9IHRydWU7XG4gICAgY29uc3QgcHN1YiA9IHRvb2wucHJvZ3Jlc3MkLnN1YnNjcmliZSgoZikgPT4ge1xuICAgICAgdGhpcy5zYW1Eb3dubG9hZGluZyA9IGYgPj0gMCAmJiBmIDwgMTtcbiAgICAgIGlmIChmID49IDApIHRoaXMuc2FtUHJvZ3Jlc3MgPSBNYXRoLm1pbigxMDAsIE1hdGgucm91bmQoZiAqIDEwMCkpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuICAgIC8vIFRyYWNrZWQgaGVyZSByYXRoZXIgdGhhbiByZWFkIG9mZiB0aGUgc3ViamVjdCBhdCB0aGUgZW5kOiBgdG9vbGAgaXMgb25seVxuICAgIC8vIGFuIE9ic2VydmFibGUgcGFpciBub3csIHNvIHRoZXJlIGlzIG5vIGAudmFsdWVgIHRvIHNhbXBsZSBvbmNlIHRoZSBydW5cbiAgICAvLyBzZXR0bGVzLiBUaGUgbGFzdCBub24tZW1wdHkgc3RhdHVzIGlzIHdoYXQgdGhlIHJlc3VsdCB0b2FzdCByZXBvcnRzLlxuICAgIGxldCBsYXN0U3RhdHVzID0gJyc7XG4gICAgY29uc3Qgc3N1YiA9IHRvb2wuc3RhdHVzJC5zdWJzY3JpYmUoKG0pID0+IHtcbiAgICAgIGlmIChtKSB7XG4gICAgICAgIGxhc3RTdGF0dXMgPSBtO1xuICAgICAgICB0aGlzLnNhbVN0YXR1cyA9IG07XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnNob3dTYW1Ub2FzdChsYWJlbCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG4gPSBhd2FpdCBvcCgpO1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgICAgIHNldmVyaXR5OiBuID4gMCA/ICdzdWNjZXNzJyA6ICd3YXJuJyxcbiAgICAgICAgc3VtbWFyeTogbGFiZWwsXG4gICAgICAgIGRldGFpbDogbGFzdFN0YXR1cyB8fCAobiA+IDAgPyBgQWRkZWQgJHtufSByZWdpb24ocykuYCA6ICdObyByZWdpb25zIGFkZGVkLicpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgICAgIHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiBgJHtsYWJlbH0gZmFpbGVkYCwgZGV0YWlsOiBTdHJpbmcoZSksXG4gICAgICB9KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgc3N1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5oaWRlU2FtVG9hc3QoKTtcbiAgICB9XG4gIH1cblxuICAvKiogU2hvdyB0aGUgc2hhcmVkIHN0aWNreSBgc2FtYCB0b2FzdCBvbmNlIChpZGVtcG90ZW50IOKAlCByZS1hZGRpbmcgd291bGQgc3RhY2tcbiAgICogIGEgbmV3IHRvYXN0IG9uIGV2ZXJ5IHBvaW50IGNsaWNrKS4gKi9cbiAgcHJpdmF0ZSBzaG93U2FtVG9hc3Qoc3VtbWFyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2FtVG9hc3RTaG93bikgcmV0dXJuO1xuICAgIHRoaXMuc2FtVG9hc3RTaG93biA9IHRydWU7XG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IHRoaXMuc2FtVG9hc3RLZXksIHN0aWNreTogdHJ1ZSwgc2V2ZXJpdHk6ICdpbmZvJywgc3VtbWFyeSB9KTtcbiAgfVxuXG4gIC8qKiBEaXNtaXNzIHRoZSBzaGFyZWQgYHNhbWAgdG9hc3QgYW5kIHJlc2V0IGl0cyBwcm9ncmVzcy9zcGlubmVyIHN0YXRlLiAqL1xuICBwcml2YXRlIGhpZGVTYW1Ub2FzdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNhbVRvYXN0U2hvd24gPSBmYWxzZTtcbiAgICB0aGlzLnNhbUJ1c3kgPSBmYWxzZTtcbiAgICB0aGlzLnNhbURvd25sb2FkaW5nID0gZmFsc2U7XG4gICAgdGhpcy5zYW1Qcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5jbGVhcih0aGlzLnNhbVRvYXN0S2V5KTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKiogUGljayB0aGUgU0FNIG1vZGVsIHRoZSBzZWdtZW50IHRvb2xzIHVzZSAoaml0LXVpIzkwIFAxKS4gKi9cbiAgb25TYW1Nb2RlbENoYW5nZShpZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zYW1Nb2RlbElkID0gaWQ7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTYW1Nb2RlbChpZCk7XG4gIH1cblxuICAvKiogQ29udmVydCB0aGUgc2VsZWN0ZWQgcmVnaW9uIHRvIGEgc21vb3RoIGJlemllciBjdXJ2ZS4gKi9cbiAgdG9CZXppZXJSZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25PdmVybGF5KCk/LnNldFNlbGVjdGVkQmV6aWVyKHRydWUpO1xuICB9XG5cbiAgLyoqIENvbnZlcnQgdGhlIHNlbGVjdGVkIHJlZ2lvbiBiYWNrIHRvIGEgc3RyYWlnaHQtZWRnZWQgcG9seWdvbi4gKi9cbiAgdG9Qb2x5Z29uUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9uT3ZlcmxheSgpPy5zZXRTZWxlY3RlZEJlemllcihmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogSW1tZWRpYXRlIHJlZ2lvbiBhY3Rpb25zIG9uIHRoZSBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzg1KTogbWVyZ2UsXG4gICAqIHVuZ3JvdXAsIGludmVyc2UsIHNpbXBsaWZ5LCB0aGUgQsOpemllciBjb252ZXJzaW9ucywgYW5kIGRlbGV0ZSDigJQgdGhlXG4gICAqIG9uZS1zaG90IGdlb21ldHJ5IHRyYW5zZm9ybXMsIGdyb3VwZWQgYXBhcnQgZnJvbSB0aGUgdG9vbC9tb2RlIHRvZ2dsZXMgYW5kXG4gICAqIHNob3duIG9ubHkgd2hlbiBzb21ldGhpbmcgaXMgc2VsZWN0ZWQuIEVhY2ggaXRlbSBpcyBnYXRlZCBvbiB3aGF0IHRoZVxuICAgKiBzZWxlY3Rpb24gc3VwcG9ydHMuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkUmVnaW9uQWN0aW9uSXRlbXMoKTogTWVudUl0ZW1bXSB7XG4gICAgY29uc3QgYWxsID0gdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25zKCk7XG4gICAgY29uc3Qgc2VsZWN0YWJsZSA9IGFsbC5maWx0ZXIoKHIpID0+IHIua2luZCAhPT0gJ3Byb2ZpbGUnKTtcbiAgICBpZiAoc2VsZWN0YWJsZS5sZW5ndGggPT09IDApIHJldHVybiBbXTtcbiAgICBjb25zdCBpdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgLy8gU2VsZWN0IGFsbCDigJQgYXZhaWxhYmxlIHdoZW5ldmVyIHRoZSBpbWFnZSBoYXMgcmVnaW9ucywgcmVnYXJkbGVzcyBvZiB0aGVcbiAgICAvLyBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICBpdGVtcy5wdXNoKHtcbiAgICAgIGxhYmVsOiAnU2VsZWN0IGFsbCByZWdpb25zJywgaWNvbjogJ3BpIHBpLWNoZWNrLXNxdWFyZScsXG4gICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnNlbGVjdEFsbFJlZ2lvbnMoKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlbEFsbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb25zO1xuICAgIGlmIChzZWxBbGwubGVuZ3RoID09PSAwKSByZXR1cm4gaXRlbXM7XG4gICAgY29uc3QgZWxpZ2libGUgPSB0aGlzLm9wRWxpZ2libGUoc2VsQWxsKTtcblxuICAgIGlmIChlbGlnaWJsZS5sZW5ndGggPj0gMikge1xuICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnTWVyZ2UgLyBncm91cCcsIGljb246ICdwaSBwaS1saW5rJywgY29tbWFuZDogKCkgPT4gdGhpcy5tZXJnZVJlZ2lvbnMoKSB9KTtcbiAgICB9XG4gICAgaWYgKHNlbEFsbC5zb21lKChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5jYW5Vbmdyb3VwKHIpKSkge1xuICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnVW5ncm91cCcsIGljb246ICdwaSBwaS1zaXRlbWFwJywgY29tbWFuZDogKCkgPT4gdGhpcy51bmdyb3VwUmVnaW9ucygpIH0pO1xuICAgIH1cbiAgICBpZiAoZWxpZ2libGUubGVuZ3RoID49IDEpIHtcbiAgICAgIGl0ZW1zLnB1c2goXG4gICAgICAgIHsgbGFiZWw6ICdJbnZlcnNlJywgaWNvbjogJ3BpIHBpLWNsb25lJywgY29tbWFuZDogKCkgPT4gdGhpcy5pbnZlcnNlUmVnaW9ucygpIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ1NpbXBsaWZ5JywgaWNvbjogJ3BpIHBpLWNoYXJ0LWxpbmUnLFxuICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICB7IGxhYmVsOiAnTGlnaHQgKDEgcHgpJywgY29tbWFuZDogKCkgPT4gdGhpcy5zaW1wbGlmeVJlZ2lvbnMoMSkgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6ICdNZWRpdW0gKDMgcHgpJywgY29tbWFuZDogKCkgPT4gdGhpcy5zaW1wbGlmeVJlZ2lvbnMoMykgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6ICdTdHJvbmcgKDggcHgpJywgY29tbWFuZDogKCkgPT4gdGhpcy5zaW1wbGlmeVJlZ2lvbnMoOCkgfSxcbiAgICAgICAgICAgIHsgc2VwYXJhdG9yOiB0cnVlIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiAnQ3VzdG9t4oCmJywgY29tbWFuZDogKCkgPT4gdGhpcy5vcGVuU2ltcGxpZnlEaWFsb2coKSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBCw6l6aWVyIGNvbnZlcnNpb25zIGFyZSB2ZXJ0ZXgtbGV2ZWwgZWRpdHMg4oCUIEltYWdlIChPcGVuU2VhZHJhZ29uKSB2aWV3XG4gICAgLy8gb25seSDigJQgZ2F0ZWQgb24gdGhlIHNlbGVjdGlvbidzIGN1cnJlbnQgZm9ybS5cbiAgICBpZiAodGhpcy5zZWxlY3RlZFBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRSkge1xuICAgICAgY29uc3QgaGFzU3RyYWlnaHQgPSBzZWxBbGwuc29tZSgocikgPT5cbiAgICAgICAgKHIuYm91bmRzIGluc3RhbmNlb2YgUG9seWdvbiAmJiAhci5ib3VuZHMuYmV6aWVyKSB8fCByLmJvdW5kcyBpbnN0YW5jZW9mIFJlY3RhbmdsZSk7XG4gICAgICBjb25zdCBoYXNCZXppZXIgPSBzZWxBbGwuc29tZSgocikgPT4gci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uICYmIHIuYm91bmRzLmJlemllcik7XG4gICAgICBpZiAoaGFzU3RyYWlnaHQpIHtcbiAgICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnQ29udmVydCB0byBCw6l6aWVyJywgaWNvbjogJ3RvLWJlemllci1pY29uJywgY29tbWFuZDogKCkgPT4gdGhpcy50b0JlemllclJlZ2lvbigpIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGhhc0Jlemllcikge1xuICAgICAgICBpdGVtcy5wdXNoKHsgbGFiZWw6ICdDb252ZXJ0IHRvIHBvbHlnb24nLCBpY29uOiAndG8tcG9seWdvbi1pY29uJywgY29tbWFuZDogKCkgPT4gdGhpcy50b1BvbHlnb25SZWdpb24oKSB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnRGVsZXRlIHJlZ2lvbicsIGljb246ICdwaSBwaS10cmFzaCcsIGNvbW1hbmQ6ICgpID0+IHRoaXMuZGVsZXRlUmVnaW9uKCkgfSk7XG4gICAgcmV0dXJuIGl0ZW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZENvbnRleHRNZW51SXRlbXMoKTogTWVudUl0ZW1bXSB7XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5hY3RpdmVEcmFnTW9kZTtcbiAgICBjb25zdCBhY3RpdmVDbGFzcyA9ICdjb250ZXh0LW1lbnUtYWN0aXZlJztcbiAgICBjb25zdCBpdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuICAgIC8vIFNlbGVjdGVkLXJlZ2lvbiBhY3Rpb25zIGxlYWQgdGhlIG1lbnUgKHNlcGFyYXRlZCBmcm9tIHRoZSB0b29sIHRvZ2dsZXMpLlxuICAgIGlmICh0aGlzLmlzSGVhdG1hcCkge1xuICAgICAgY29uc3QgYWN0aW9ucyA9IHRoaXMuYnVpbGRSZWdpb25BY3Rpb25JdGVtcygpO1xuICAgICAgaWYgKGFjdGlvbnMubGVuZ3RoKSBpdGVtcy5wdXNoKC4uLmFjdGlvbnMsIHsgc2VwYXJhdG9yOiB0cnVlIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0hlYXRtYXApIHtcbiAgICAgIGl0ZW1zLnB1c2goXG4gICAgICAgIHsgbGFiZWw6ICdBdXRvc2NhbGUnLCBpY29uOiAncGkgcGktd2luZG93LW1heGltaXplJywgY29tbWFuZDogKCkgPT4gdGhpcy5hdXRvc2NhbGVJbWFnZSgpIH0sXG4gICAgICAgIHsgc2VwYXJhdG9yOiB0cnVlIH0sXG4gICAgICApO1xuICAgICAgLy8gJ1pvb20gc2VsZWN0aW9uJyBpcyBQbG90bHkncyBydWJiZXItYmFuZCB6b29tOyBpdCBkb2Vzbid0IGFwcGx5IHRvIHRoZVxuICAgICAgLy8gT3BlblNlYWRyYWdvbi1iYWNrZWQgSW1hZ2UgdmlldyAodXNlICdab29tIHRvIGJveCcgdGhlcmUgaW5zdGVhZCkuXG4gICAgICBpZiAoIXRoaXMuaXNJbWFnZVZpZXcpIHtcbiAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgbGFiZWw6ICdab29tIHNlbGVjdGlvbicsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLXNlYXJjaCcsXG4gICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnem9vbScgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3pvb20nKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgbGFiZWw6ICdab29tIHRvIGJveCcsXG4gICAgICAgIGljb246ICd6b29tLWJveC1vZmYtaWNvbicsXG4gICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ3pvb21Ub0JveCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCd6b29tVG9Cb3gnKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0hlYXRtYXApIHtcbiAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICBsYWJlbDogJ1BhbicsXG4gICAgICAgIGljb246ICdwaSBwaS1hcnJvd3MtYWx0JyxcbiAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAncGFuJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3BhbicpLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHMzZCA9IHRoaXMuYWN0aXZlU3VyZmFjZTNkTW9kZTtcbiAgICAgIGl0ZW1zLnB1c2goXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ1pvb20nLFxuICAgICAgICAgIGljb246ICdwaSBwaS1zZWFyY2gnLFxuICAgICAgICAgIHN0eWxlQ2xhc3M6IHMzZCA9PT0gJ3pvb20nID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZVN1cmZhY2UzZE1vZGUoJ3pvb20nKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnUGFuJyxcbiAgICAgICAgICBpY29uOiAncGkgcGktYXJyb3dzLWFsdCcsXG4gICAgICAgICAgc3R5bGVDbGFzczogczNkID09PSAncGFuJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVTdXJmYWNlM2RNb2RlKCdwYW4nKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnT3JiaXRhbCByb3RhdGlvbicsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLWdsb2JlJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBzM2QgPT09ICdvcmJpdCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlU3VyZmFjZTNkTW9kZSgnb3JiaXQnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnVHVybnRhYmxlIHJvdGF0aW9uJyxcbiAgICAgICAgICBpY29uOiAncGkgcGktc3luYycsXG4gICAgICAgICAgc3R5bGVDbGFzczogczNkID09PSAndHVybnRhYmxlJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVTdXJmYWNlM2RNb2RlKCd0dXJudGFibGUnKSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBzZXBhcmF0b3I6IHRydWUgfSxcbiAgICAgICAgeyBsYWJlbDogJ1Jlc2V0IGNhbWVyYScsIGljb246ICdwaSBwaS1ob21lJywgY29tbWFuZDogKCkgPT4gdGhpcy5yZXNldFN1cmZhY2VDYW1lcmEoKSB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNIZWF0bWFwKSB7XG4gICAgICBpdGVtcy5wdXNoKFxuICAgICAgICB7IGxhYmVsOiAnWm9vbSBpbicsIGljb246ICdwaSBwaS1zZWFyY2gtcGx1cycsIGNvbW1hbmQ6ICgpID0+IHRoaXMuem9vbUluKCkgfSxcbiAgICAgICAgeyBsYWJlbDogJ1pvb20gb3V0JywgaWNvbjogJ3BpIHBpLXNlYXJjaC1taW51cycsIGNvbW1hbmQ6ICgpID0+IHRoaXMuem9vbU91dCgpIH0sXG4gICAgICAgIHsgc2VwYXJhdG9yOiB0cnVlIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ1NlbGVjdCcsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLWFycm93LXVwLXJpZ2h0JyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdzZWxlY3QnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdzZWxlY3QnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnRnJlZWZvcm0nLFxuICAgICAgICAgIGljb246ICdwaSBwaS1wZW5jaWwnLFxuICAgICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ2RyYXdjbG9zZWRwYXRoJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZHJhd2Nsb3NlZHBhdGgnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnQnJ1c2gnLFxuICAgICAgICAgIGljb246ICdicnVzaC1pY29uJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdicnVzaCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2JydXNoJyksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ1BvbHlsaW5lJyxcbiAgICAgICAgICBpY29uOiAncG9seWxpbmUtaWNvbicsXG4gICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnZHJhd29wZW5wYXRoJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZHJhd29wZW5wYXRoJyksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ1JlY3RhbmdsZScsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLXN0b3AnLFxuICAgICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ2RyYXdyZWN0JyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZHJhd3JlY3QnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnV2FuZCcsXG4gICAgICAgICAgaWNvbjogJ3dhbmQtaWNvbicsXG4gICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnd2FuZCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3dhbmQnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnVmVydGV4IGVyYXNlcicsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLWVyYXNlcicsXG4gICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnZXJhc2VWZXJ0ZXgnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdlcmFzZVZlcnRleCcpLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICAgIC8vIFZlcnRleCBlZGl0aW5nIHJ1bnMgb24gdGhlIE9wZW5TZWFkcmFnb24gb3ZlcmxheSwgd2hpY2hcbiAgICAgIC8vIGJhY2tzIHRoZSBJbWFnZSBwbG90IHR5cGUuIEhpZGRlbiBmb3Igb3RoZXIgMkQgdHlwZXMgKFBsb3RseSksIHdoZXJlXG4gICAgICAvLyB0aGVzZSBtb2RlcyBhcmUgbm8tb3BzLlxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0UpIHtcbiAgICAgICAgaXRlbXMucHVzaChcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogJ1BvbHlnb24gKGNsaWNrIHZlcnRpY2VzKScsXG4gICAgICAgICAgICBpY29uOiAncG9seWdvbi12ZXJ0aWNlcy1pY29uJyxcbiAgICAgICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ2RyYXdwb2x5Z29uJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdkcmF3cG9seWdvbicpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdBZGQgdmVydGV4JyxcbiAgICAgICAgICAgIGljb246ICd2ZXJ0ZXgtYWRkLWljb24nLFxuICAgICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnYWRkcG9pbnQnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2FkZHBvaW50JyksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogJ0RlbGV0ZSB2ZXJ0ZXgnLFxuICAgICAgICAgICAgaWNvbjogJ3ZlcnRleC1kZWxldGUtaWNvbicsXG4gICAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdkZWxldGVwb2ludCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZGVsZXRlcG9pbnQnKSxcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gQsOpemllciBjb252ZXJzaW9ucyArIERlbGV0ZSBhcmUgaW1tZWRpYXRlIHNlbGVjdGlvbiAqYWN0aW9ucyosIG5vdyBpbiB0aGVcbiAgICAgIC8vIFwiU2VsZWN0ZWQgcmVnaW9uKHMpXCIgZ3JvdXAgYXQgdGhlIHRvcCAoc2VlIGJ1aWxkUmVnaW9uQWN0aW9uSXRlbXMpLlxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICB0b2dnbGVTdXJmYWNlM2RNb2RlKG1vZGU6IHN0cmluZykge1xuICAgIHRoaXMuYWN0aXZlU3VyZmFjZTNkTW9kZSA9IG1vZGU7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTdXJmYWNlRHJhZ01vZGUobW9kZSk7XG4gIH1cblxuICByZXNldFN1cmZhY2VDYW1lcmEoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5yZXNldFN1cmZhY2VDYW1lcmEoKTtcbiAgfVxuXG4gIC8qKiBUb2dnbGUgdGhlIG5hcGFyaSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyAodm9sdW1lL2lzb3N1cmZhY2UpLiBOby1vcCBvbiBiYWNrZW5kc1xuICAgKiAgdGhhdCBkb24ndCByZW5kZXIgb25lICh0aGUgY29udHJvbCBtZXRob2QgaXMgb3B0aW9uYWwpLiAqL1xuICB0b2dnbGVBeGVzKCkge1xuICAgIHRoaXMuYXhlc1Zpc2libGUgPSAhdGhpcy5heGVzVmlzaWJsZTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFN1cmZhY2UzZENvbnRyb2xzKCk/LnNldEF4ZXNWaXNpYmxlPy4odGhpcy5heGVzVmlzaWJsZSk7XG4gIH1cblxuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgc3VyZmFjZSB3aXJlZnJhbWUgKGVkZ2VzIHZzIGZpbGxlZCkuIE5vLW9wIG9uIGJhY2tlbmRzIHdpdGhvdXQgYSBzdXJmYWNlLiAqL1xuICB0b2dnbGVXaXJlZnJhbWUoKSB7XG4gICAgdGhpcy53aXJlZnJhbWVBY3RpdmUgPSAhdGhpcy53aXJlZnJhbWVBY3RpdmU7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdXJmYWNlM2RDb250cm9scygpPy5zZXRXaXJlZnJhbWU/Lih0aGlzLndpcmVmcmFtZUFjdGl2ZSk7XG4gIH1cblxuICAvKiogQ2hhbmdlIHRoZSBuYXBhcmkgM0QgZGVjaW1hdGUgZmFjdG9yLiBEZWNpbWF0aW9uIGNoYW5nZXMgdGhlIGZldGNoZWQvYXNzZW1ibGVkIGRhdGEsIHNvIHRoaXNcbiAgICogIHJlLXBsb3RzIHRoZSBjdXJyZW50IDNEIHR5cGUgYXQgdGhlIG5ldyByZXNvbHV0aW9uICh1bmxpa2UgYXhlcy93aXJlZnJhbWUsIHdoaWNoIGFyZSBsaXZlKS4gKi9cbiAgc2VsZWN0UmVzb2x1dGlvbihzY2FsZTogbnVtYmVyKSB7XG4gICAgaWYgKHNjYWxlID09PSB0aGlzLnJlc29sdXRpb25TY2FsZSkgcmV0dXJuO1xuICAgIHRoaXMucmVzb2x1dGlvblNjYWxlID0gc2NhbGU7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRSZXNvbHV0aW9uU2NhbGU/LihzY2FsZSk7XG4gICAgdGhpcy5yZWxvYWRBbmRQbG90KCk7XG4gIH1cblxuICAvKipcbiAgICogU3dpdGNoIHRoZSBhY3RpdmUgcGxvdCB0eXBlIChoZWF0bWFwLCBzdXJmYWNlLCBjb250b3VyLCBzY2F0dGVyLCBsaW5lLFxuICAgKiBzY2F0dGVyM2QsIGlzb3N1cmZhY2UpLiBLZWVwcyBgaXNIZWF0bWFwYCBhcyB0aGUgMkQtdnMtM0QgZmxhZyB0aGUgcmVzdCBvZlxuICAgKiB0aGUgdG9vbGJhci9jb250ZXh0LW1lbnUgbG9naWMgcmVsaWVzIG9uLCBkZWFjdGl2YXRlcyAyRC1vbmx5IHRvb2xzIHdoZW5cbiAgICogbW92aW5nIHRvIGEgM0QgdHlwZSwgdGhlbiByZS1wbG90cy5cbiAgICovXG4gIG9uU2VsZWN0UGxvdFR5cGUodHlwZTogUGxvdFR5cGUpIHtcbiAgICB0aGlzLnBsb3RUeXBlID0gdHlwZTtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGUgPSB0eXBlO1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLnBsb3RUeXBlT3B0aW9ucy5maW5kKChkKSA9PiBkLnR5cGUgPT09IHR5cGUpO1xuICAgIGNvbnN0IGlzM2QgPSBkZXNjcmlwdG9yPy5kaW1lbnNpb25zID09PSAnM2QnO1xuICAgIHRoaXMuaXNIZWF0bWFwID0gIWlzM2Q7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0eXBlKTtcbiAgICAvLyBTd2l0Y2hpbmcgcGxvdCB0eXBlIGNhbmNlbHMgdGhlIGFjdGl2ZSB0b29sIOKAlCBub3QgZXZlcnkgdHlwZSBzdXBwb3J0cyB0aGVcbiAgICAvLyBzYW1lIHRvb2xzIChsaW5lL3NjYXR0ZXIgY2hhcnRzIGFuZCAzRCBzY2VuZXMgaGF2ZSBubyBib3ggem9vbSBvciByZWdpb25cbiAgICAvLyBkcmF3aW5nKSwgc28gbGVhdmluZyBhIHRvb2wgYXJtZWQgd291bGQgbWlzYmVoYXZlIG9uIHRoZSBuZXcgcGxvdC5cbiAgICB0aGlzLmRlYWN0aXZhdGVBY3RpdmVUb29sKCk7XG4gICAgaWYgKGlzM2QpIHtcbiAgICAgIHRoaXMuYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAgIH1cbiAgICAvLyBuYXBhcmktanMgdm9sdW1lL2lzb3N1cmZhY2UgYXNzZW1ibGUgdGhlaXIgb3duIDNEIHRleHR1cmUgZnJvbSB0aGUgc2xpY2UgZW5kcG9pbnQsIHNvXG4gICAgLy8gdGhleSB0YWtlIHRoZSBub3JtYWwgcmUtcGxvdCBwYXRoIOKAlCBOT1QgUGxvdGx5J3Mgc3RhY2stZnJhbWUgbG9hZGVyICh3aG9zZSBcIkxvYWRpbmdcbiAgICAvLyBmcmFtZXNcIiBvdmVybGF5IHdvdWxkIG5ldmVyIGNsZWFyLCBzaW5jZSBQbG90bHkgaXNuJ3QgdGhlIGFjdGl2ZSBiYWNrZW5kKSAoaml0LXVpIzEwMikuXG4gICAgY29uc3QgaXNOYXBhcmkgPSB0eXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0UgfHwgaXNOYXBhcmkzZCh0eXBlKTtcbiAgICBpZiAoZGVzY3JpcHRvcj8ucmVxdWlyZXNTdGFjayAmJiAhaXNOYXBhcmkpIHtcbiAgICAgIC8vIFZvbHVtZSB0eXBlcyAoaXNvc3VyZmFjZSwgc2NhdHRlcjNkKSBuZWVkIHRoZSB3aG9sZSB6LXN0YWNrIGxvYWRlZCBhcyBhXG4gICAgICAvLyAzRCBhcnJheSwgYW5kIHRoZXkgYWx3YXlzIHJlbmRlciBvbiBQbG90bHkuIERyaXZlIHRoZSBzdGFjayByZWxvYWRcbiAgICAgIC8vIGRpcmVjdGx5IHRocm91Z2ggdGhlIGltYWdlLWluZm8gc3RyZWFtIHJhdGhlciB0aGFuIHRoZSBhY3RpdmUgcmVuZGVyZXInc1xuICAgICAgLy8gc2V0U2hvd1N0YWNrOiB3aGVuIE9wZW5TZWFkcmFnb24gb3ducyB0aGUgSW1hZ2UgdmlldyBpdHMgc2V0U2hvd1N0YWNrIGlzXG4gICAgICAvLyBhIG5vLW9wLCBzbyB0aGUgcmVsb2FkIG5ldmVyIGZpcmVkIGFuZCB0aGUgbG9hZGVyIHNwdW4gZm9yZXZlci4gV2UgYXJtXG4gICAgICAvLyBQbG90bHkncyBzdGFjay1sb2FkaW5nIGZsYWcgKGtlZXBzIGl0cyBmcmFtZS1mZXRjaCBsb29wIGFsaXZlKSBhbmRcbiAgICAgIC8vIHJlLWVtaXQgdGhlIGltYWdlIGluZm8gd2l0aCBzaG93U3RhY2sgb24gc28gdGhlIHBpcGVsaW5lIHJlbG9hZHMgb25cbiAgICAgIC8vIFBsb3RseSByZWdhcmRsZXNzIG9mIHdoaWNoIGJhY2tlbmQgd2FzIG9uIHNjcmVlbi5cbiAgICAgIHRoaXMuc2VsZWN0ZWRTdGFja09wdGlvbiA9IHRoaXMuc3RhY2tPcHRpb25zWzFdO1xuICAgICAgdGhpcy5zdGFja0xvYWRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRTdGFja0xvYWRpbmcodHJ1ZSk7XG4gICAgICBpZiAodGhpcy5pbWFnZUluZm8pIHtcbiAgICAgICAgdGhpcy5pbWFnZUluZm8uc2hvd1N0YWNrID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUluZm8odGhpcy5pbWFnZUluZm8pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlbG9hZEFuZFBsb3QoKTtcbiAgfVxuXG4gIC8qKiBEZWFjdGl2YXRlIHdoYXRldmVyIHRvb2wgaXMgYXJtZWQgYW5kIGNsZWFyIGV2ZXJ5IHRvb2wgbW9kZS4gKi9cbiAgcHJpdmF0ZSBkZWFjdGl2YXRlQWN0aXZlVG9vbCgpIHtcbiAgICB0aGlzLmFjdGl2ZURyYWdNb2RlID0gbnVsbDtcbiAgICB0aGlzLnNlc3Npb24uc2V0QWN0aXZlVG9vbChudWxsKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvbk92ZXJsYXkoKT8uc2V0TW9kZSgnbm9uZScpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0RHJhZ01vZGUoZmFsc2UpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0Wm9vbVRvQm94TW9kZShmYWxzZSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRXYW5kTW9kZShmYWxzZSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRCcnVzaE1vZGUoZmFsc2UpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2FtUG9pbnRNb2RlKGZhbHNlKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFZlcnRleEVyYXNlck1vZGUoZmFsc2UpO1xuICB9XG59XG5cbiIsIjwhLS0gU0FNIHRvYXN0OiBsaXZlIHN0YXR1cyArIGVuY29kZXItZG93bmxvYWQgcHJvZ3Jlc3MgYmFyIChqaXQtdWkjOTApLiBTdGlja3lcbiAgICAgd2hpbGUgYSBzZWdtZW50IHJ1bnM7IHN0YXlzIG9wZW4gdW50aWwgdGhlIGJhciByZWFjaGVzIDEwMCUgYW5kIHRoZSBydW4gZW5kcy4gLS0+XG48cC10b2FzdCBba2V5XT1cInNhbVRvYXN0S2V5XCIgcG9zaXRpb249XCJib3R0b20tcmlnaHRcIj5cbiAgPG5nLXRlbXBsYXRlIGxldC1tZXNzYWdlIHBUZW1wbGF0ZT1cIm1lc3NhZ2VcIj5cbiAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgbWluLXdpZHRoOiAxNnJlbVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvbnQtYm9sZCBtYi0xXCI+e3sgbWVzc2FnZS5zdW1tYXJ5IH19PC9kaXY+XG4gICAgICA8ZGl2Pnt7IHNhbVN0YXR1cyB8fCBtZXNzYWdlLmRldGFpbCB9fTwvZGl2PlxuICAgICAgPHAtcHJvZ3Jlc3NCYXIgKm5nSWY9XCJzYW1Eb3dubG9hZGluZ1wiIFt2YWx1ZV09XCJzYW1Qcm9ncmVzc1wiIHN0eWxlQ2xhc3M9XCJtdC0yIHNhbS1wcm9ncmVzc1wiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgIDxwLXByb2dyZXNzQmFyICpuZ0lmPVwic2FtQnVzeSAmJiAhc2FtRG93bmxvYWRpbmdcIiBtb2RlPVwiaW5kZXRlcm1pbmF0ZVwiIHN0eWxlQ2xhc3M9XCJtdC0yXCJcbiAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7IGhlaWdodDogJzRweCcgfVwiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC10b2FzdD5cblxuPCEtLSBSZXN1bHQvZXJyb3Igbm90aWNlcyBmcm9tIHRoZSBsaWJyYXJ5IGl0c2VsZiAoc2VnbWVudGF0aW9uIG91dGNvbWUsIHJlZ2lvblxuICAgICB2YWxpZGF0aW9uKS4gUmVuZGVyZWQgaGVyZSBzbyB0aGV5IGRvIG5vdCBkZXBlbmQgb24gdGhlIGhvc3QgbW91bnRpbmcgYVxuICAgICBrZXlsZXNzIDxwLXRvYXN0PiDigJQgd2l0aG91dCB0aGlzIHRoZSBtZXNzYWdlcyB3ZW50IG5vd2hlcmUgaW4gYW55IGhvc3QgYnV0XG4gICAgIGppdC11aSwgYW5kIGEgZmFpbGVkIHJ1biBsb29rZWQgbGlrZSBhIGJ1dHRvbiB0aGF0IGRpZCBub3RoaW5nLiAtLT5cbjxwLXRvYXN0IFtrZXldPVwicmVzdWx0VG9hc3RLZXlcIiBwb3NpdGlvbj1cImJvdHRvbS1yaWdodFwiPjwvcC10b2FzdD5cblxuPCEtLSBTaGFyZWQgb3V0bGV0cyBmb3Igbm90aWNlcyByYWlzZWQgd2hlcmUgdGhlcmUgaXMgbm8gcGVyLWluc3RhbmNlIGtleSB0byB1c2U6XG4gICAgIHRoZSByb290LXByb3ZpZGVkIFBsb3RseVNlcnZpY2UgYW5kIHRoZSByZWdpb24tZWRpdG9yIGRpYWxvZy4gUmVuZGVyZWQgYnkgYVxuICAgICBzaW5nbGUgdmlzdWFsaXplciAob3duc1NoYXJlZFRvYXN0cykgc28gYSBtZXNzYWdlIGZyb20gdGhlIHJvb3Qgc2VydmljZSBpc1xuICAgICBub3Qgc2hvd24gb25jZSBwZXIgbGl2ZSB2aWV3ZXIuIC0tPlxuPHAtdG9hc3QgKm5nSWY9XCJvd25zU2hhcmVkVG9hc3RzXCIgW2tleV09XCJ2aXpUb2FzdEtleVwiPjwvcC10b2FzdD5cbjxwLXRvYXN0ICpuZ0lmPVwib3duc1NoYXJlZFRvYXN0c1wiIFtrZXldPVwidml6QWxlcnRUb2FzdEtleVwiIHBvc2l0aW9uPVwiY2VudGVyXCI+PC9wLXRvYXN0PlxuXG48IS0tIFRvb2xiYXIgZG9jazogZG9ja2VkIGFjcm9zcyB0aGUgdG9wIGJ5IGRlZmF1bHQ7IGRyYWcgdGhlIGhhbmRsZSB0byBkZXRhY2hcbiAgICAgaXQgaW50byBhIGZsb2F0aW5nLCBtb3ZhYmxlIHdpbmRvdyAoZnJlZXMgdGhlIHRvcCByb3cgZm9yIHRoZSBpbWFnZSkuIC0tPlxuPGRpdiBjbGFzcz1cInRvb2xiYXItZG9ja1wiIFtjbGFzcy5mbG9hdGluZ109XCJ0b29sYmFyRmxvYXRpbmdcIlxuICAgICBbc3R5bGUubGVmdC5weF09XCJ0b29sYmFyRmxvYXRpbmcgPyB0b29sYmFyUG9zLnggOiBudWxsXCJcbiAgICAgW3N0eWxlLnRvcC5weF09XCJ0b29sYmFyRmxvYXRpbmcgPyB0b29sYmFyUG9zLnkgOiBudWxsXCI+XG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLWRyYWctaGFuZGxlXCIgKG1vdXNlZG93bik9XCJvblRvb2xiYXJEcmFnU3RhcnQoJGV2ZW50KVwiXG4gICAgICAgcFRvb2x0aXA9XCJEcmFnIHRvIGZsb2F0IHRoZSB0b29sYmFyXCIgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCI+XG4gICAgPGkgY2xhc3M9XCJwaSBwaS1iYXJzXCI+PC9pPlxuICA8L2Rpdj5cbjxwbG90dGluZy10b29sYmFyXG4gIFtpbWFnZUluZm9dPVwiaW1hZ2VJbmZvXCJcbiAgW3Bsb3RUeXBlT3B0aW9uc109XCJwbG90VHlwZU9wdGlvbnNcIlxuICBbc2VsZWN0ZWRQbG90VHlwZV09XCJzZWxlY3RlZFBsb3RUeXBlXCJcbiAgW2lzb1JhbmdlXT1cImlzb1JhbmdlXCJcbiAgW21heEluZGV4XT1cIm1heEluZGV4XCJcbiAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICBbaXNIZWF0bWFwXT1cImlzSGVhdG1hcFwiXG4gIFtpczNkUmVnaW9uc109XCJpc1NwYXRpYWwzZE1vZGVcIlxuICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICBbYWN0aXZlU3VyZmFjZTNkTW9kZV09XCJhY3RpdmVTdXJmYWNlM2RNb2RlXCJcbiAgW2F4ZXNWaXNpYmxlXT1cImF4ZXNWaXNpYmxlXCJcbiAgW3dpcmVmcmFtZUFjdGl2ZV09XCJ3aXJlZnJhbWVBY3RpdmVcIlxuICBbcmVzb2x1dGlvblNjYWxlXT1cInJlc29sdXRpb25TY2FsZVwiXG4gIFt3YW5kU2Vuc2l0aXZpdHldPVwid2FuZFNlbnNpdGl2aXR5XCJcbiAgW2JydXNoU2l6ZV09XCJicnVzaFNpemVcIlxuICBbc2FtTW9kZWxzXT1cInNhbU1vZGVsc1wiXG4gIFtzYW1Nb2RlbElkXT1cInNhbU1vZGVsSWRcIlxuICBbY29udHJpYnV0ZWRUb29sc109XCJjb250cmlidXRlZFRvb2xzXCJcbiAgW3Rvb2xNb2RlbElkc109XCJ0b29sTW9kZWxJZHNcIlxuICBbdmVydGV4RXJhc2VyUmFkaXVzXT1cInZlcnRleEVyYXNlclJhZGl1c1wiXG4gIFtjYW5VbmRvXT1cImNhblVuZG9SZWdpb25cIlxuICBbY2FuUmVkb109XCJjYW5SZWRvUmVnaW9uXCJcbiAgW3N0YWNrT3B0aW9uc109XCJzdGFja09wdGlvbnNcIlxuICBbdG9vbHNdPVwidG9vbGJhclRvb2xzXCJcbiAgW2ltYWdlU21vb3RoaW5nRW5hYmxlZF09XCJpbWFnZVNtb290aGluZ0VuYWJsZWRcIlxuICAoc2VsZWN0UGxvdFR5cGUpPVwib25TZWxlY3RQbG90VHlwZSgkZXZlbnQpXCJcbiAgKHRvZ2dsZUltYWdlU21vb3RoaW5nKT1cIm9uVG9nZ2xlSW1hZ2VTbW9vdGhpbmcoKVwiXG4gIChhZGRQcm9maWxlTGluZSk9XCJhZGRQcm9maWxlTGluZSgpXCJcbiAgKGlzb1JhbmdlQ2hhbmdlKT1cIm9uSXNvUmFuZ2VDaGFuZ2UoJGV2ZW50KVwiXG4gIChvcGVuQ2hhbm5lbEhpc3RvZ3JhbSk9XCJvcGVuQ2hhbm5lbEhpc3RvZ3JhbSgpXCJcbiAgKG9wZW5TcGF0aWFsQ29udHJvbHMpPVwib3BlblNwYXRpYWxDb250cm9scygpXCJcbiAgKG9wZW5SZWdpb25FZGl0b3IpPVwib3BlblJlZ2lvbkVkaXRvcigpXCJcbiAgKHNlbGVjdFN0YWNrT3B0aW9uKT1cInNlbGVjdFN0YWNrT3B0aW9uKCRldmVudClcIlxuICAoelNjcnViKT1cIm9uWlNjcnViKCRldmVudClcIlxuICAoelNsaWRlKT1cIm9uWlNsaWRlKCRldmVudClcIlxuICAoekluZGV4SW5wdXQpPVwiekluZGV4ID0gJGV2ZW50OyB1cGRhdGVaSW5kZXgoKVwiXG4gIChyZWxvYWRBbmRQbG90KT1cInJlbG9hZEFuZFBsb3QoKVwiXG4gIChkb3dubG9hZEltYWdlKT1cImRvd25sb2FkSW1hZ2UoKVwiXG4gIChhdXRvc2NhbGVJbWFnZSk9XCJhdXRvc2NhbGVJbWFnZSgpXCJcbiAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlKCRldmVudClcIlxuICAoem9vbUluKT1cInpvb21JbigpXCJcbiAgKHpvb21PdXQpPVwiem9vbU91dCgpXCJcbiAgKHRvZ2dsZVN1cmZhY2UzZE1vZGUpPVwidG9nZ2xlU3VyZmFjZTNkTW9kZSgkZXZlbnQpXCJcbiAgKHJlc2V0U3VyZmFjZUNhbWVyYSk9XCJyZXNldFN1cmZhY2VDYW1lcmEoKVwiXG4gICh0b2dnbGVBeGVzKT1cInRvZ2dsZUF4ZXMoKVwiXG4gICh0b2dnbGVXaXJlZnJhbWUpPVwidG9nZ2xlV2lyZWZyYW1lKClcIlxuICAoc2VsZWN0UmVzb2x1dGlvbik9XCJzZWxlY3RSZXNvbHV0aW9uKCRldmVudClcIlxuICAoZGVsZXRlUmVnaW9uKT1cImRlbGV0ZVJlZ2lvbigpXCJcbiAgKHVuZG9SZWdpb24pPVwidW5kb1JlZ2lvbigpXCJcbiAgKHJlZG9SZWdpb24pPVwicmVkb1JlZ2lvbigpXCJcbiAgKHNlZ21lbnRSZWdpb25zKT1cInNlZ21lbnRSZWdpb25zKClcIlxuICAoc2VnbWVudENlbGxwb3NlKT1cInNlZ21lbnRDZWxscG9zZSgpXCJcbiAgKHNhbU1vZGVsQ2hhbmdlKT1cIm9uU2FtTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gIChydW5Ub29sKT1cInJ1blRvb2woJGV2ZW50KVwiXG4gICh0b29sTW9kZWxDaGFuZ2UpPVwib25Ub29sTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gIChvcGVuVG9vbFBhcmFtcyk9XCJvcGVuVG9vbFBhcmFtcygkZXZlbnQpXCJcbiAgKHdhbmRTZW5zaXRpdml0eUNoYW5nZSk9XCJvbldhbmRTZW5zaXRpdml0eUNoYW5nZSgkZXZlbnQpXCJcbiAgKGJydXNoU2l6ZUNoYW5nZSk9XCJvbkJydXNoU2l6ZUNoYW5nZSgkZXZlbnQpXCJcbiAgKHZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSk9XCJvblZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSgkZXZlbnQpXCI+XG4gIDwhLS0gSG9zdC1wcm9qZWN0ZWQgY3VzdG9tIHRvb2xiYXIgYnV0dG9ucywgZm9yd2FyZGVkIGludG8gdGhlIHRvb2xiYXIuIC0tPlxuICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG48L3Bsb3R0aW5nLXRvb2xiYXI+XG4gIDxwLWJ1dHRvbiAqbmdJZj1cInRvb2xiYXJGbG9hdGluZ1wiIGNsYXNzPVwidG9vbGJhci1kb2NrLWJ0blwiIGljb249XCJwaSBwaS10aHVtYnRhY2tcIiBzaXplPVwic21hbGxcIiBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgICAgIHBUb29sdGlwPVwiRG9jayB0byB0b3BcIiB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIiAob25DbGljayk9XCJkb2NrVG9vbGJhcigpXCI+XG4gIDwvcC1idXR0b24+XG48L2Rpdj5cblxuPHAtY29udGV4dE1lbnUgI2NtIFttb2RlbF09XCJjb250ZXh0TWVudUl0ZW1zXCIgYXBwZW5kVG89XCJib2R5XCI+PC9wLWNvbnRleHRNZW51PlxuPCEtLSBObyBgaC1mdWxsYCBoZXJlOiBQcmltZUZsZXgncyBoZWlnaHQ6MTAwJSAhaW1wb3J0YW50IG1hZGUgI3Bsb3QgYXMgdGFsbCBhc1xuICAgICB0aGUgd2hvbGUgaG9zdCwgc28gdW5kZXIgdGhlIGRvY2tlZCB0b29sYmFyIGl0cyBib3R0b20gdG9vbGJhci1oZWlnaHQgc3RyaXBcbiAgICAgKGluY2wuIHRoZSBPU0Qgc2NhbGUgYmFyIGF0IGJvdHRvbS1sZWZ0KSB3YXMgY2xpcHBlZCBieSB0aGUgaG9zdCdzXG4gICAgIG92ZXJmbG93OmhpZGRlbi4gVGhlIGNvbXBvbmVudCBzdHlsZXNoZWV0IHNpemVzIGl0ICgudml6LXBsb3QgeyBmbGV4OiAxIH0pLiAtLT5cbjxkaXYgY2xhc3M9XCJ3LWZ1bGwgcmVsYXRpdmUgdml6LXBsb3RcIiBbaWRdPVwicGxvdERpdk5hbWVcIj5cbiAgPGRpdiAqbmdJZj1cImltZ0xvYWRpbmcgfHwgc3RhY2tMb2FkaW5nIHx8IGlzQ2FjaGluZ1wiIGlkPVwib3ZlcmxheVwiPlxuICAgIDwhLS0gRGV0ZXJtaW5hdGUgc3RhY2svdm9sdW1lIHByb2dyZXNzIHRha2VzIHByZWNlZGVuY2U6IHdoaWxlIGl0J3MgYWN0aXZlIHNob3cgT05MWSB0aGVcbiAgICAgICAgIHByb2dyZXNzIGJhciArIFwiTG9hZGluZyBmcmFtZXMuLi5cIiwgbm90IHRoZSBnZW5lcmljIHNwaW5uZXIvXCJMb2FkaW5nIGltYWdlLi4uXCIgb24gdG9wIG9mXG4gICAgICAgICBpdCAoYm90aCB3ZXJlIHJlbmRlcmluZyBhdCBvbmNlIGZvciBuYXBhcmkgdm9sdW1lL2lzb3N1cmZhY2UgbG9hZHMpLiAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RhY2tMb2FkaW5nOyBlbHNlIGltZ0xvYWRpbmdUcGxcIj5cbiAgICAgIDxwLXByb2dyZXNzQmFyIGNsYXNzPVwicHJvZ3Jlc3NcIiBbdmFsdWVdPVwibG9hZGluZ1BlcmNlbnRhZ2VcIj48L3AtcHJvZ3Jlc3NCYXI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPkxvYWRpbmcgZnJhbWVzLi4uPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy10ZW1wbGF0ZSAjaW1nTG9hZGluZ1RwbD5cbiAgICAgIDwhLS0gQ2FjaGUtY29weSBwcm9ncmVzcyBpcyBzaG93biB3aGVuZXZlciBhIGNhY2hlIGRvd25sb2FkIGlzIGFjdGl2ZSAoaXNDYWNoaW5nKSwgaW5kZXBlbmRlbnRcbiAgICAgICAgICAgb2YgYGltZ0xvYWRpbmdgLCBzbyBpdCdzIG5ldmVyIGRyb3BwZWQvbWFza2VkIG1pZC1kb3dubG9hZC4gLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDYWNoaW5nOyBlbHNlIHNwaW5uZXJMb2FkaW5nXCI+XG4gICAgICAgIDwhLS0gU3RhZ2UtYXdhcmUgbWVzc2FnZSBjb21lcyBmcm9tIENhY2hlUHJvZ3Jlc3NTZXJ2aWNlIHVwZGF0aW5nXG4gICAgICAgICAgICAgaW1hZ2VMb2FkaW5nTWVzc2FnZSQgKFwiQ2FjaGluZyBpbWFnZS4uLlwiIGR1cmluZyB0aGUgR0NTIGRvd25sb2FkLFxuICAgICAgICAgICAgIHRoZW4gXCJHZW5lcmF0aW5nIHByZXZpZXcuLi5cIiBkdXJpbmcgcGVyLXNsaWNlIHRodW1ibmFpbCBnZW4pLiBPbmNlIHRoZVxuICAgICAgICAgICAgIGRvd25sb2FkIGhpdHMgMTAwJSB0aGUgcmVtYWluaW5nIHdvcmsgKHNlcnZlciBwcmV2aWV3L3RpbGUgZ2VuZXJhdGlvbilcbiAgICAgICAgICAgICBoYXMgbm8gZGV0ZXJtaW5hdGUgcHJvZ3Jlc3MsIHNvIGZhbGwgdGhyb3VnaCB0byB0aGUgc3Bpbm5lciB0ZW1wbGF0ZVxuICAgICAgICAgICAgIHJhdGhlciB0aGFuIHBhcmtpbmcgYSBmdWxsIGJhciB1bmRlciBcIkxvYWRpbmcgaW1hZ2UuLi5cIi4gLS0+XG4gICAgICAgIDxwLXByb2dyZXNzQmFyIGNsYXNzPVwicHJvZ3Jlc3NcIiBbdmFsdWVdPVwiY2FjaGVQcm9ncmVzc1wiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj57e2xvYWRpbmdNZXNzYWdlfX08L3NwYW4+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjc3Bpbm5lckxvYWRpbmc+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJpbWdMb2FkaW5nXCIgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaW1nTG9hZGluZyAmJiAhem9vbVwiIGNsYXNzPVwidGV4dC1sb2FkaW5nXCI+e3tsb2FkaW5nTWVzc2FnZX19PC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cImltZ0xvYWRpbmcgJiYgem9vbVwiIGNsYXNzPVwiem9vbS10ZXh0LWxvYWRpbmdcIj57e2xvYWRpbmdNZXNzYWdlfX08L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPHAtYnV0dG9uICpuZ0lmPVwic3RhY2tMb2FkaW5nIHx8IGltZ0xvYWRpbmdcIiBjbGFzcz1cImNhbmNlbC1sb2FkaW5nIFwiIGxhYmVsPVwiQ2FuY2VsXCJcbiAgICAgICAgICAgICAgKG9uQ2xpY2spPVwiY2FuY2VsTG9hZGluZygpXCI+XG4gICAgPC9wLWJ1dHRvbj5cbiAgPC9kaXY+XG4gIDwhLS0gVHJhbnNsdWNlbnQgXCJzaGFycGVuaW5nXCIgb3ZlcmxheSBzaG93biBhZnRlciB0aGUgc21hbGwtdGllciBwcmV2aWV3IGlzXG4gICAgICAgb24gc2NyZWVuIHdoaWxlIHRoZSBsYXJnZS10aWVyIHJlbmRlciBpcyBzdGlsbCBsb2FkaW5nIGluIHRoZVxuICAgICAgIGJhY2tncm91bmQuIExldHMgdGhlIHVzZXIgc2VlIHRoZSBibHVycnkgaW1hZ2UgdW5kZXJuZWF0aCBidXQgbWFrZXNcbiAgICAgICBpdCBjbGVhciBzb21ldGhpbmcgaXMgc3RpbGwgbG9hZGluZyBzbyB0aGV5IGRvbid0IG1pc3Rha2UgdGhlXG4gICAgICAgbG93LXJlcyByZW5kZXIgZm9yIHRoZSBmaW5hbCBpbWFnZS4gLS0+XG4gIDxkaXYgKm5nSWY9XCJzaGFycGVuaW5nICYmICFpbWdMb2FkaW5nICYmICFzdGFja0xvYWRpbmcgJiYgIWlzQ2FjaGluZ1wiIGlkPVwic2hhcnBlbmluZy1vdmVybGF5XCI+XG4gICAgPGRpdiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cbiAgICA8c3BhbiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPlNoYXJwZW5pbmcgcHJldmlldy4uLjwvc3Bhbj5cbiAgPC9kaXY+XG5cbjwvZGl2PlxuXG48IS0tIEZsb2F0aW5nLCBkcmFnZ2FibGUgaW50ZW5zaXR5LXByb2ZpbGUgaW5zZXQuIFNob3duIGluIExJTkUgbW9kZTsgdGhlIGNoYXJ0XG4gICAgIHVwZGF0ZXMgbGl2ZSBhcyB0aGUgbGluZSBST0kgb24gdGhlIGltYWdlIGlzIG1vdmVkLiBLZXB0IE9VVFNJREUgI3Bsb3QgYW5kXG4gICAgIHBvc2l0aW9uZWQgZml4ZWQgc28gaXQgZmxvYXRzIG92ZXIgdGhlIHdob2xlIHBhZ2UgKG5vdCBjbGlwcGVkIHRvIHRoZVxuICAgICBkaWFncmFtL2NhbnZhcyBhcmVhKS4gLS0+XG48ZGl2ICpuZ0lmPVwiaGFzUHJvZmlsZXNcIiBjbGFzcz1cImludGVuc2l0eS1wYW5lbFwiXG4gICAgIFtzdHlsZS5sZWZ0LnB4XT1cInByb2ZpbGVQYW5lbFBvcy54XCIgW3N0eWxlLnRvcC5weF09XCJwcm9maWxlUGFuZWxQb3MueVwiPlxuICA8ZGl2IGNsYXNzPVwiaW50ZW5zaXR5LXBhbmVsLWhlYWRlclwiIChtb3VzZWRvd24pPVwib25Qcm9maWxlUGFuZWxEcmFnU3RhcnQoJGV2ZW50KVwiPlxuICAgIDxzcGFuPkludGVuc2l0eSBwcm9maWxlPC9zcGFuPlxuICAgIDxpIGNsYXNzPVwicGkgcGktYXJyb3dzLWFsdFwiPjwvaT5cbiAgPC9kaXY+XG4gIDxkaXYgW2lkXT1cImludGVuc2l0eUluc2V0RGl2XCIgY2xhc3M9XCJpbnRlbnNpdHktcGFuZWwtcGxvdFwiPjwvZGl2PlxuPC9kaXY+XG5cbjwhLS0gQ2hhbm5lbHMgJiBIaXN0b2dyYW06IG5vbi1tb2RhbCBmbG9hdGluZyBkaWFsb2cgb3BlbmVkIGZyb20gdGhlIHRvb2xiYXIuIC0tPlxuPGNoYW5uZWwtaGlzdG9ncmFtIFsodmlzaWJsZSldPVwic2hvd0NoYW5uZWxIaXN0b2dyYW1cIj48L2NoYW5uZWwtaGlzdG9ncmFtPlxuXG48IS0tIFNwYXRpYWwtb21pY3MgY29udHJvbHMuIFJlbmRlcnMgaXRzIG93biBlbXB0eSBzdGF0ZSB3aGVuIG5vIGRhdGFzZXQgKG9yIG5vXG4gICAgIFNQQVRJQUxfREFUQV9QT1JUKSBpcyBwcmVzZW50LCBzbyBpdCBpcyBhbHdheXMgc2FmZSB0byBob3N0LiAtLT5cbjxzcGF0aWFsLWNvbnRyb2xzIFsodmlzaWJsZSldPVwic2hvd1NwYXRpYWxDb250cm9sc1wiIFtpczNkXT1cImlzU3BhdGlhbDNkTW9kZVwiID48L3NwYXRpYWwtY29udHJvbHM+XG5cbjwhLS0gUmVnaW9uIEVkaXRvcjogbm9uLW1vZGFsLCBkcmFnZ2FibGUsIHJlc2l6YWJsZSBmbG9hdGluZyBkaWFsb2cgb3BlbmVkIGZyb21cbiAgICAgdGhlIHRvb2xiYXIgKGZvcm1lcmx5IHRoZSByaWdodC1wYW5lbCBSZWdpb25zIHRhYikuIE1vZGVsZXNzIHNvIHJlZ2lvbnMgY2FuXG4gICAgIHN0aWxsIGJlIGRyYXduL3NlbGVjdGVkIG9uIHRoZSBwbG90IHdoaWxlIGl0J3Mgb3Blbjsgc3RheXMgbGlua2VkIHRvIHRoaXNcbiAgICAgcGxvdHRpbmcgaW5zdGFuY2UgdmlhIHRoZSByb290IFJlZ2lvblN0b3JlIHNpbmdsZXRvbi4gT3BlbnMgb3ZlciB0aGUgcmlnaHRcbiAgICAgc2lkZSBvZiB0aGUgdmlldy4gLS0+XG48cC1kaWFsb2cgaGVhZGVyPVwiUmVnaW9uIEVkaXRvclwiIFsodmlzaWJsZSldPVwic2hvd1JlZ2lvbkVkaXRvclwiXG4gICAgICAgICAgW21vZGFsXT1cImZhbHNlXCIgW3Jlc2l6YWJsZV09XCJ0cnVlXCIgW2RyYWdnYWJsZV09XCJ0cnVlXCJcbiAgICAgICAgICBbbWF4aW1pemFibGVdPVwidHJ1ZVwiIGFwcGVuZFRvPVwiYm9keVwiIHBvc2l0aW9uPVwicmlnaHRcIlxuICAgICAgICAgIFtzdHlsZV09XCJ7IHdpZHRoOiByZWdpb25FZGl0b3JXaWR0aCwgaGVpZ2h0OiAnODV2aCcgfVwiXG4gICAgICAgICAgW2NvbnRlbnRTdHlsZV09XCJ7IG92ZXJmbG93OiAnYXV0bycgfVwiPlxuICA8cmVnaW9uLWVkaXRvcj48L3JlZ2lvbi1lZGl0b3I+XG48L3AtZGlhbG9nPlxuXG48IS0tIFNpbXBsaWZ5IChEb3VnbGFz4oCTUGV1Y2tlcik6IGN1c3RvbSBweC10aHJlc2hvbGQgcGlja2VyIGZvciB0aGUgc2VsZWN0ZWRcbiAgICAgcmVnaW9uKHMpLCBvcGVuZWQgZnJvbSB0aGUgcmlnaHQtY2xpY2sgXCJTaW1wbGlmeSDilrggQ3VzdG9t4oCmXCIgYWN0aW9uLiAtLT5cbjxwLWRpYWxvZyBoZWFkZXI9XCJTaW1wbGlmeSByZWdpb24ocylcIiBbKHZpc2libGUpXT1cImRpc3BsYXlTaW1wbGlmeURpYWxvZ1wiIFttb2RhbF09XCJ0cnVlXCJcbiAgICAgICAgICBbc3R5bGVdPVwie3dpZHRoOiAnMjJyZW0nfVwiIFtkcmFnZ2FibGVdPVwiZmFsc2VcIiBbcmVzaXphYmxlXT1cImZhbHNlXCI+XG4gIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sdW1uIGdhcC0yXCI+XG4gICAgPHNwYW4+QWx0aXR1ZGUgdGhyZXNob2xkOiA8Yj57eyBzaW1wbGlmeVRocmVzaG9sZCB9fSBweDwvYj48L3NwYW4+XG4gICAgPHAtc2xpZGVyIFsobmdNb2RlbCldPVwic2ltcGxpZnlUaHJlc2hvbGRcIiBbbWluXT1cIjFcIiBbbWF4XT1cIjIwXCIgW3N0ZXBdPVwiMVwiPjwvcC1zbGlkZXI+XG4gICAgPHNtYWxsPlZlcnRpY2VzIHdpdGhpbiB0aGlzIGRpc3RhbmNlIG9mIHRoZSBsaW5lIGJldHdlZW4gdGhlaXIgbmVpZ2hib3VycyBhcmUgcmVtb3ZlZC48L3NtYWxsPlxuICA8L2Rpdj5cbiAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImZvb3RlclwiPlxuICAgIDxwLWJ1dHRvbiBsYWJlbD1cIkNhbmNlbFwiIFt0ZXh0XT1cInRydWVcIiAob25DbGljayk9XCJkaXNwbGF5U2ltcGxpZnlEaWFsb2cgPSBmYWxzZVwiPjwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uIGxhYmVsPVwiQXBwbHlcIiBpY29uPVwicGkgcGktY2hlY2tcIiAob25DbGljayk9XCJzaW1wbGlmeVJlZ2lvbnMoc2ltcGxpZnlUaHJlc2hvbGQpXCI+PC9wLWJ1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gUGFyYW1ldGVycyBmb3Igd2hpY2hldmVyIGNvbnRyaWJ1dGVkIHRvb2wgaXMgb3Blbi4gT25lIGRpYWxvZyBmb3IgYWxsIG9mXG4gICAgIHRoZW06IGEgdG9vbCBkZWNsYXJlcyBpdHMgZmllbGRzIChUb29sUGFyYW1TcGVjKSBhbmQgdGhpcyByZW5kZXJzIHRoZW0sIHNvXG4gICAgIHRoZSB0b29sYmFyIGNhbiBsYXkgZXZlcnkgdG9vbCBvdXQgdGhlIHNhbWUgd2F5IGFuZCBhIHBsdWdpbiBuZWVkcyBub1xuICAgICBQcmltZU5HIG9mIGl0cyBvd24uIERlZmF1bHRzIGNvbWUgZnJvbSB0aGUgYWN0aXZlIGNoZWNrcG9pbnQsIHNpbmNlIHRoZXlcbiAgICAgZW5jb2RlIHdoYXQgaXQgd2FzIHRyYWluZWQgZm9yLiAtLT5cbjxwLWRpYWxvZyAqbmdJZj1cIm9wZW5QYXJhbXNUb29sIGFzIHRvb2xcIlxuICAgICAgICAgIFtoZWFkZXJdPVwidG9vbC5sYWJlbCArICcgcGFyYW1ldGVycydcIlxuICAgICAgICAgIFt2aXNpYmxlXT1cInRydWVcIiAodmlzaWJsZUNoYW5nZSk9XCJvcGVuUGFyYW1zVG9vbElkID0gbnVsbFwiXG4gICAgICAgICAgW21vZGFsXT1cInRydWVcIlxuICAgICAgICAgIFtzdHlsZV09XCJ7d2lkdGg6ICczMHJlbSd9XCIgW2RyYWdnYWJsZV09XCJmYWxzZVwiIFtyZXNpemFibGVdPVwiZmFsc2VcIiBhcHBlbmRUbz1cImJvZHlcIj5cbiAgPGRpdiBjbGFzcz1cImdyaWQgZm9ybWdyaWQgcC1mbHVpZFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHAgb2YgdG9vbC5wYXJhbXNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiIFtuZ0NsYXNzXT1cInAudHlwZSA9PT0gJ2Jvb2xlYW4nID8gJ2NvbC0xMicgOiAnY29sLTYnXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInAudHlwZVwiPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ251bWJlcidcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtc21cIiBbcFRvb2x0aXBdPVwicC50b29sdGlwIHx8ICcnXCI+e3sgcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8cC1pbnB1dE51bWJlciBbbmdNb2RlbF09XCJwYXJhbXNGb3IodG9vbC5pZClbcC5pZF1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGFyYW1zRm9yKHRvb2wuaWQpW3AuaWRdID0gJGV2ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwibnVtYmVyUGFyYW0ocCkubWluXCIgW21heF09XCJudW1iZXJQYXJhbShwKS5tYXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwibnVtYmVyUGFyYW0ocCkuc3RlcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluRnJhY3Rpb25EaWdpdHNdPVwibnVtYmVyUGFyYW0ocCkuZnJhY3Rpb25EaWdpdHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCdXR0b25zXT1cInRydWVcIj48L3AtaW5wdXROdW1iZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc2VsZWN0J1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiIFtwVG9vbHRpcF09XCJwLnRvb2x0aXAgfHwgJydcIj57eyBwLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgIDxwLWRyb3Bkb3duIFtvcHRpb25zXT1cInNlbGVjdFBhcmFtKHApLm9wdGlvbnNcIiBvcHRpb25MYWJlbD1cImxhYmVsXCIgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJwYXJhbXNGb3IodG9vbC5pZClbcC5pZF1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGFyYW1zRm9yKHRvb2wuaWQpW3AuaWRdID0gJGV2ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvPVwiYm9keVwiPjwvcC1kcm9wZG93bj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDwhLS0gQ2hlY2tib3ggbGFiZWwgc2l0cyBiZXNpZGUgdGhlIGJveCBhbmQgbWF5IHJ1biB0byBhIHNlbnRlbmNlLCBzb1xuICAgICAgICAgICAgICAgaXQgZG9lcyBub3QgZ2V0IHRoZSBzdGFja2VkIGxhYmVsIHRoZSBvdGhlciB0eXBlcyB1c2UuIC0tPlxuICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIidib29sZWFuJ1wiIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgICAgICAgIDxwLWNoZWNrYm94IFtuZ01vZGVsXT1cInBhcmFtc0Zvcih0b29sLmlkKVtwLmlkXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJwYXJhbXNGb3IodG9vbC5pZClbcC5pZF0gPSAkZXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2JpbmFyeV09XCJ0cnVlXCIgW2lucHV0SWRdPVwidG9vbC5pZCArICctJyArIHAuaWRcIj48L3AtY2hlY2tib3g+XG4gICAgICAgICAgICA8bGFiZWwgW2Zvcl09XCJ0b29sLmlkICsgJy0nICsgcC5pZFwiIGNsYXNzPVwidGV4dC1zbSBtYi0wXCJcbiAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicC50b29sdGlwIHx8ICcnXCI+e3sgcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG4gIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJmb290ZXJcIj5cbiAgICA8cC1idXR0b24gbGFiZWw9XCJSZXNldCB0byBtb2RlbCBkZWZhdWx0c1wiIFt0ZXh0XT1cInRydWVcIiBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICAob25DbGljayk9XCJyZXNldFRvb2xQYXJhbXModG9vbC5pZClcIj48L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvbiBsYWJlbD1cIkNsb3NlXCIgc2l6ZT1cInNtYWxsXCIgKG9uQ2xpY2spPVwib3BlblBhcmFtc1Rvb2xJZCA9IG51bGxcIj48L3AtYnV0dG9uPlxuICA8L25nLXRlbXBsYXRlPlxuPC9wLWRpYWxvZz5cbiJdfQ==
2516
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQTZCLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFnQyxRQUFRLEVBQUUsTUFBTSxFQUF1QixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFck8sT0FBTyxFQUErQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQVksY0FBYyxFQUFZLE1BQU0sYUFBYSxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVsRCxPQUFPLEVBQWtCLGdCQUFnQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDdEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFVLE1BQU0saUJBQWlCLENBQUM7QUFDM0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUUsT0FBTyxFQUNMLFFBQVEsRUFHUixxQkFBcUIsRUFDckIsaUJBQWlCLEVBQ2pCLFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLHVCQUF1QixHQUN4QixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLHVCQUF1QixFQU12Qix5QkFBeUIsR0FDMUIsTUFBTSw2Q0FBNkMsQ0FBQztBQUNyRCxPQUFPLEVBQWtCLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2xFLE9BQU8sRUFBaUMsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUM5RyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDekUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDcEYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sa0RBQWtELENBQUM7QUFDMUYsT0FBTyxFQUNMLGFBQWEsRUFRYix1QkFBdUIsRUFDdkIsd0JBQXdCLEdBQ3pCLE1BQU0sbUNBQW1DLENBQUM7QUFFM0MsT0FBTyxFQUF5QixpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSx3QkFBd0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsaUJBQWlCLEVBQW1CLE1BQU0scUNBQXFDLENBQUM7QUFFekYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV2RTs7O2lFQUdpRTtBQUNqRSxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUM7QUFTeEIsTUFBTSxPQUFPLG1CQUFtQjtJQUM5Qjs7OzZFQUd5RTthQUMxRCxnQkFBVyxHQUFHLENBQUMsQUFBSixDQUFLO0lBRS9COzs7Ozs7Ozs7OztPQVdHO2FBQ3FCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQXVCLEFBQWpDLENBQWtDO0lBR3ZFOzs7Ozs7OztPQVFHO0lBQ0gsSUFBSSxnQkFBZ0I7UUFDbEIsTUFBTSxNQUFNLEdBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2pFLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDO0lBQy9DLENBQUM7SUFPRDtzRkFDa0Y7SUFDbEYsSUFDSSxZQUFZLENBQUMsQ0FBb0M7UUFDbkQsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLEdBQUcsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlELENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztJQWlDRDs7MEZBRXNGO0lBQ3RGLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLGFBQWEsR0FBRyxHQUFHLENBQUM7SUFDakUsQ0FBQztJQXFKRDs7Ozs7T0FLRztJQUNILElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFjO1FBQ2pDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7SUFDakMsQ0FBQztJQWlCRCxnRkFBZ0Y7SUFDaEYsSUFDSSxpQkFBaUIsQ0FBQyxHQUF3QztRQUM1RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQztRQUN0QyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxHQUFHLENBQUMsYUFBYTtZQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25HLENBQUM7SUFFRDtrRUFDOEQ7SUFDOUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBeUJEOztxRUFFaUU7SUFDakUsSUFBSSxlQUFlO1FBQ2pCLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCw2RUFBNkU7SUFDN0UsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsWUFBWSxLQUFLLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFDN0MsQ0FBQztJQUVEOzsyRUFFdUU7SUFDdkUsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsWUFBWSxLQUFLLFFBQVEsQ0FBQyxLQUFLLENBQUM7SUFDOUMsQ0FBQztJQTZDRCxZQUNvQyxLQUFxQixFQUM1QixXQUF3QixFQUM1QyxjQUE4QixFQUM3QixNQUFjLEVBQ2QsR0FBc0IsRUFDdEIsT0FBd0IsRUFDeEIsT0FBdUIsRUFDdkIsZUFBdUMsRUFDdkMsWUFBaUMsRUFDakMsU0FBMkIsRUFDSyxTQUFxQjtJQUM3RCw0RUFBNEU7SUFDNUUsMEVBQTBFO0lBQzFFLHNFQUFzRTtJQUNuQyxpQkFBa0Q7SUFDckYsMkVBQTJFO0lBQzNFLGlEQUFpRDtJQUNGLFdBQTZCO0lBQzVFLDRFQUE0RTtJQUM1RSx3RUFBd0U7SUFDM0IscUJBQXVEO0lBQ3BHLDJFQUEyRTtJQUMzRSxpREFBaUQ7SUFDN0IsUUFBbUI7UUF2QkwsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDNUMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzdCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixZQUFPLEdBQVAsT0FBTyxDQUFpQjtRQUN4QixZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN2QixvQkFBZSxHQUFmLGVBQWUsQ0FBd0I7UUFDdkMsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBQ2pDLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQ0ssY0FBUyxHQUFULFNBQVMsQ0FBWTtRQU9kLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQU14RCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBL1doQyxnQkFBVyxHQUFHLGFBQWEsQ0FBQztRQUM1QixxQkFBZ0IsR0FBRyxtQkFBbUIsQ0FBQztRQWdCaEQsaUJBQVksR0FBRyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV2QyxxQkFBZ0IsR0FBRyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQVluQyxrQkFBYSxHQUFvQyxpQkFBaUIsQ0FBQztRQUUzRTs7MEVBRWtFO1FBRWxFLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFakI7K0VBQ3VFO1FBQ3ZFLDBCQUFxQixHQUFHLEtBQUssQ0FBQztRQUM5QixtQkFBYyxHQUFHLGtCQUFrQixDQUFDO1FBQ3BDLFNBQUksR0FBRyxLQUFLLENBQUM7UUFLTCxVQUFLLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUM1Qix3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBRTFDLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsc0JBQWlCLEdBQUcsQ0FBQyxDQUFDO1FBQzdCLDBFQUEwRTtRQUMxRSwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ2xFLGtCQUFhLEdBQWtCLElBQUksQ0FBQztRQUMzQyx1RUFBdUU7UUFDdkUsc0VBQXNFO1FBQ3RFLHlFQUF5RTtRQUN6RSxxREFBcUQ7UUFDOUMsZUFBVSxHQUFHLEtBQUssQ0FBQztRQU9sQixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBRXhCOzs7OztXQUtHO1FBQ0ssZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFDakIsV0FBTSxHQUFHLENBQUMsQ0FBQztRQUNYLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFHcEIscUJBQWdCLEdBQWUsRUFBRSxDQUFDO1FBRWxDLG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQUVyQztrRkFDMEU7UUFDMUUsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDdEIsd0VBQXdFO1FBQ3hFLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBRXRCLG9EQUFvRDtRQUNwRCwwQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDOUIsc0JBQWlCLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCO2lGQUN5RTtRQUNqRSxvQkFBZSxHQUFhLEVBQUUsQ0FBQztRQUV2Qyx3RkFBd0Y7UUFDeEYsb0JBQWUsR0FBRyxHQUFHLENBQUM7UUFDdEIsZ0ZBQWdGO1FBQ2hGLGNBQVMsR0FBRyxFQUFFLENBQUM7UUFDZixzR0FBc0c7UUFDOUYsZUFBVSxHQUE4QixJQUFJLENBQUM7UUFDckQ7OzBFQUVrRTtRQUNsRSxjQUFTLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxRixlQUFVLEdBQUcsb0JBQW9CLEVBQUUsQ0FBQztRQUVwQzs7Ozs7V0FLRztRQUNILHFCQUFnQixHQUE4QixFQUFFLENBQUM7UUFDakQ7Ozs7V0FJRztRQUNILGdCQUFXLEdBQW9DLEVBQUUsQ0FBQztRQUNsRCw4RUFBOEU7UUFDOUUscUJBQWdCLEdBQWtCLElBQUksQ0FBQztRQUN2QyxzRUFBc0U7UUFDdEUsZUFBVSxHQUErRCxJQUFJLENBQUM7UUFHOUUsOENBQThDO1FBQzlDLGlCQUFZLEdBQTJCLEVBQUUsQ0FBQztRQUMxQzs7O1dBR0c7UUFDSCxlQUFVLEdBQTRDLEVBQUUsQ0FBQztRQUN6RCxzREFBc0Q7UUFDdEQscUJBQWdCLEdBQWtCLElBQUksQ0FBQztRQUN2Qyw4RUFBOEU7UUFDOUUsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNmLGdCQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsMkJBQTJCO1FBQzVDLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLFlBQU8sR0FBRyxLQUFLLENBQUMsQ0FBQyw0REFBNEQ7UUFDN0U7MkRBQ21EO1FBQzNDLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBRXJCLGdCQUFXLEdBQUcsT0FBTyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO1FBQ2xFOzs7Ozs7Ozs7Ozs7Ozs7OztXQWlCRztRQUNNLG1CQUFjLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxTQUFTLENBQUM7UUFDdkQsMkVBQTJFO1FBQ25FLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN6Qyx1REFBdUQ7UUFDdkQsdUJBQWtCLEdBQUcsRUFBRSxDQUFDO1FBR3hCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRXJCLHdFQUF3RTtRQUN4RSx5QkFBb0IsR0FBRyxLQUFLLENBQUM7UUFDN0IsaUVBQWlFO1FBQ2pFLHdCQUFtQixHQUFHLEtBQUssQ0FBQztRQUM1QixpRUFBaUU7UUFDakUscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ3pCOzs2RUFFcUU7UUFDckUsc0JBQWlCLEdBQUcsTUFBTSxDQUFDO1FBQzNCLGlCQUFZLEdBQUc7WUFDYixFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRTtZQUN0QyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRTtTQUMvQixDQUFDO1FBQ0Ysd0JBQW1CLEdBQThDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0UsZ0JBQVcsR0FBRyxZQUFZLGVBQWUsRUFBRSxFQUFFLENBQUM7UUFDdkQsYUFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDMUIsY0FBUyxHQUFHLElBQUksQ0FBQztRQUNqQix3QkFBbUIsR0FBRyxXQUFXLENBQUM7UUFDbEMsd0ZBQXdGO1FBQ3hGLGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ25CLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLHFGQUFxRjtRQUNyRixvQkFBZSxHQUFHLHVCQUF1QixDQUFDO1FBRTFDOztpREFFeUM7UUFDekMsaUJBQVksR0FBcUIsRUFBRSxDQUFDO1FBQ3BDOzs7V0FHRztRQUNILG9CQUFlLEdBQXlCLEVBQUUsQ0FBQztRQUMzQzs7OztXQUlHO1FBQ0gsdUJBQWtCLEdBQWUsUUFBUSxDQUFDLEtBQUssQ0FBQztRQWlCaEQ7Ozs7V0FJRztRQUNILGtCQUFhLEdBS0YsSUFBSSxDQUFDO1FBQ1IsZUFBVSxHQUFHLEtBQUssQ0FBQztRQWUzQixvREFBb0Q7UUFDM0Msc0JBQWlCLEdBQUcsc0JBQXNCLENBQUM7UUFDcEQsb0JBQWUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQzNCLHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQUM3QixzQkFBaUIsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUV6RDs7OEJBRXNCO1FBQ3RCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGVBQVUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ3BCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGlCQUFZLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDNUMsbUJBQWMsR0FBdUIsRUFBRSxDQUFDO1FBQ2hEO29GQUM0RTtRQUM1RSxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQTBCcEI7MkVBQ21FO1FBQ25FLGFBQVEsR0FBYSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUU5QjtrRkFDMEU7UUFDbEUsc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLGlGQUFpRjtRQUN6RSx3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFDcEM7OytDQUV1QztRQUMvQixxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDakM7MEZBQ2tGO1FBQzFFLHNCQUFpQixHQUFrQixJQUFJLENBQUM7UUFDaEQ7dUZBQytFO1FBQ3ZFLG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQUM3QyxxREFBcUQ7UUFDN0Msb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFjdkMsaUZBQWlGO1FBQ2hFLGFBQVEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ2xELElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLDZFQUE2RTtZQUM3RSw2RUFBNkU7WUFDN0UsOEVBQThFO1lBQzlFLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBK1JIOztxRUFFNkQ7UUFDN0Q7Z0ZBQ3dFO1FBQ2hFLDRCQUF1QixHQUFHLEtBQUssQ0FBQztRQW90RHhDLG1GQUFtRjtRQUMzRSx1QkFBa0IsR0FBd0IsSUFBSSxDQUFDO1FBQy9DLG9CQUFlLEdBQWtCLElBQUksQ0FBQztRQW9HOUMsZ0dBQWdHO1FBQy9FLGtCQUFhLEdBQWtCO1lBQzlDLFFBQVEsRUFBRSxDQUFDLFVBQStCLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDbEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLENBQUM7Z0JBQ3pFLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxPQUFPLEVBQUUsQ0FBQztvQkFDcEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRixDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDOUIsQ0FBQztnQkFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzFCLENBQUMsQ0FBQztZQUNGLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO2dCQUN2QixJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssSUFBSTtvQkFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMzRCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzFCLENBQUMsQ0FBQztZQUNGLFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRTtTQUMzQyxDQUFDO1FBbmxFQSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksa0JBQWtCLENBQUMscUJBQXFCLEVBQUU7WUFDN0QsV0FBVyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDO1lBQ3ZELGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDOUMsUUFBUSxFQUFFLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDO1NBQ3BFLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxnQkFBZ0IsR0FBRyx3QkFBd0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxXQUFXLEdBQUcsdUJBQXVCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM5RCxnRkFBZ0Y7UUFDaEYsaUZBQWlGO1FBQ2pGLGtGQUFrRjtRQUNsRixvRkFBb0Y7UUFDcEYsNkJBQTZCO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxrQkFBa0IsQ0FDdkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQXdCLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxLQUFLLEVBQUU7WUFDdEYsUUFBUSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQXdCLENBQUM7U0FDeEQsQ0FBQyxDQUFDLEVBQ0g7WUFDRSxXQUFXLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDO1lBQ3BELGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQzNDLFFBQVEsRUFBRSxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1NBQ2hGLENBQ0YsQ0FBQztRQUNGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUN6RCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0g7Ozs7Ozs7T0FPRztJQUNLLG1CQUFtQjtRQUN6QixJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUN0RixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ3RCLDBFQUEwRTtZQUMxRSx5RUFBeUU7WUFDekUsOENBQThDO1lBQzlDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztZQUN4QyxNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQztZQUNwQywyRUFBMkU7WUFDM0UseUVBQXlFO1lBQ3pFLDBFQUEwRTtZQUMxRSwyRUFBMkU7WUFDM0UsMkVBQTJFO1lBQzNFLHNCQUFzQjtZQUN0QixNQUFNLEdBQUcsR0FBRyxPQUFPO2dCQUNqQixDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxJQUFJLEtBQUssSUFBSSxTQUFTLElBQUksT0FBTyxDQUFDLE1BQU07b0JBQ3JELENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDckYsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNULElBQUksR0FBRyxLQUFLLElBQUksQ0FBQyxpQkFBaUI7Z0JBQUUsT0FBTztZQUMzQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsR0FBRyxDQUFDO1lBQzdCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxHQUFHLENBQUM7WUFDN0IsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztZQUNqQyw4RUFBOEU7WUFDOUUsZ0ZBQWdGO1lBQ2hGLHlFQUF5RTtZQUN6RSxvRkFBb0Y7WUFDcEYsbUZBQW1GO1lBQ25GLGtGQUFrRjtZQUNsRiw4QkFBOEI7WUFDOUIsSUFBSSxDQUFDLHVCQUF1QixHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxJQUFJLFNBQVMsQ0FBQztZQUNoRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQzlCLDJFQUEyRTtZQUMzRSx5RUFBeUU7WUFDekUsMkVBQTJFO1lBQzNFLDRFQUE0RTtZQUM1RSwwRUFBMEU7WUFDMUUsNEVBQTRFO1lBQzVFLHFDQUFxQztZQUNyQyxJQUFJLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQzlDLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixzRUFBc0U7Z0JBQ3RFLDJFQUEyRTtnQkFDM0Usc0VBQXNFO2dCQUN0RSwwRUFBMEU7Z0JBQzFFLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ2pDLDJFQUEyRTtvQkFDM0Usa0VBQWtFO29CQUNsRSwyRUFBMkU7b0JBQzNFLHlFQUF5RTtvQkFDekUsc0VBQXNFO29CQUN0RSwyQkFBMkI7b0JBQzNCLEVBQUU7b0JBQ0Ysa0VBQWtFO29CQUNsRSwyRUFBMkU7b0JBQzNFLHlFQUF5RTtvQkFDekUsMkJBQTJCO29CQUMzQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQztvQkFDMUUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEtBQUssTUFBTTt3QkFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3hFLENBQUM7WUFDSCxDQUFDO1lBQ0QsNEVBQTRFO1lBQzVFLHlFQUF5RTtZQUN6RSxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNLLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUF1QjtRQUNyRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQzVCLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFNBQVM7WUFBRSxPQUFPO1FBQ2xELE1BQU0sR0FBRyxHQUFHLEdBQUcsT0FBTyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZFLElBQUksR0FBRyxLQUFLLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTztRQUN4Qyw0RUFBNEU7UUFDNUUsMEVBQTBFO1FBQzFFLElBQUksQ0FBQyxjQUFjLEdBQUcsR0FBRyxDQUFDO1FBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQztZQUNILE1BQU0sS0FBSyxHQUFHLE1BQU0scUJBQXFCLENBQUMsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZGLDZFQUE2RTtZQUM3RSwwREFBMEQ7WUFDMUQsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUNoQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuRCxPQUFPO1lBQ1QsQ0FBQztZQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztnQkFDM0IsT0FBTztZQUNULENBQUM7WUFDRCx3RUFBd0U7WUFDeEUsNkVBQTZFO1lBQzdFLElBQUksSUFBSSxDQUFDLGtCQUFrQixLQUFLLFFBQVEsQ0FBQyxLQUFLO2dCQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEYsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLDZFQUE2RTtZQUM3RSx1RUFBdUU7WUFDdkUsT0FBTyxDQUFDLElBQUksQ0FBQywwRUFBMEUsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM5RixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztZQUMzQixJQUFJLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUNyRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbkQsQ0FBQztRQUNILENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFRDs7O3VFQUdtRTtJQUMzRCxlQUFlO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO0lBQzdCLENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU8sc0JBQXNCO1FBQzVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDO1FBQzNDLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQztRQUMxQyxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUM7UUFDbEQsNEVBQTRFO1FBQzVFLDhFQUE4RTtRQUM5RSxrRUFBa0U7UUFDbEUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLGNBQWMsR0FBRyxDQUFDLEVBQUUsRUFBRSxZQUFZLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFdBQVcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakYsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFxQixFQUFXLEVBQUU7WUFDckQsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUM5RSwwRUFBMEU7WUFDMUUsc0VBQXNFO1lBQ3RFLHlFQUF5RTtZQUN6RSxzRUFBc0U7WUFDdEUsdUNBQXVDO1lBQ3ZDLElBQUksQ0FBQyxDQUFDLGFBQWEsSUFBSSxDQUFDLE9BQU87Z0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDOUMsSUFBSSxDQUFDLENBQUMsaUJBQWlCLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxjQUFjO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQ3pFLElBQUksQ0FBQyxDQUFDLG1CQUFtQixJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUNuRSxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUI7Z0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDbkUsOEVBQThFO1lBQzlFLGlGQUFpRjtZQUNqRixpRkFBaUY7WUFDakYsMkVBQTJFO1lBQzNFLEVBQUU7WUFDRiwrRUFBK0U7WUFDL0UsZ0ZBQWdGO1lBQ2hGLGtFQUFrRTtZQUNsRSxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxpQkFBaUI7bUJBQzdDLENBQUMsSUFBSSxDQUFDLHVCQUF1QjtnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUNqRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQztRQUNGLHlFQUF5RTtRQUN6RSxzREFBc0Q7UUFDdEQsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUErQixFQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO1FBQ25HLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsc0JBQXNCLEVBQUU7YUFDdEQsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0MsNkVBQTZFO1FBQzdFLG1GQUFtRjtRQUNuRiw0RUFBNEU7UUFDNUUsaUVBQWlFO1FBQ2pFLE1BQU0sV0FBVyxHQUFxQixFQUFFLENBQUM7UUFDekMsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQUUsU0FBUztZQUMxQixJQUFJLENBQUMsQ0FBQyxhQUFhLElBQUksQ0FBQyxPQUFPO2dCQUFFLFNBQVM7WUFDMUMsSUFBSSxDQUFDLENBQUMsaUJBQWlCLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxjQUFjO2dCQUFFLFNBQVM7WUFDckUsSUFBSSxDQUFDLENBQUMsbUJBQW1CLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCO2dCQUFFLFNBQVM7WUFDL0QsSUFBSSxDQUFDLENBQUMsaUJBQWlCLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CO2dCQUFFLFNBQVM7WUFDL0QsTUFBTSxJQUFJLEdBQUcscUJBQXFCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQy9DLElBQUksSUFBSSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUM7Z0JBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0RixDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLDRFQUE0RTtRQUM1RSxNQUFNLFFBQVEsR0FBRyxDQUF3RCxDQUFJLEVBQUssRUFBRSxDQUNsRixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLGVBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsMkVBQTJFO1FBQzNFLDZFQUE2RTtRQUM3RSw0RUFBNEU7UUFDNUUsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUM5QiwyRUFBMkU7WUFDM0UsK0RBQStEO1lBQy9ELElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBU0Q7Ozs7OztPQU1HO0lBQ0ssY0FBYztRQUNwQix3RUFBd0U7UUFDeEUsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQztRQUNoQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM5Qix5RUFBeUU7UUFDekUsK0VBQStFO1FBQy9FLDhEQUE4RDtRQUM5RCxnRkFBZ0Y7UUFDaEYsMEVBQTBFO1FBQzFFLEVBQUU7UUFDRiwrRUFBK0U7UUFDL0UsK0VBQStFO1FBQy9FLCtDQUErQztRQUMvQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFTyx5QkFBeUI7UUFDL0IsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFBRSxPQUFPO1FBQzlFLG1GQUFtRjtRQUNuRixxRkFBcUY7UUFDckYsaUZBQWlGO1FBQ2pGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDdkUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLO1lBQ2hCLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQztRQUMvQixJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDdEIsNEVBQTRFO1FBQzVFLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELElBQUksSUFBSSxLQUFLLFFBQVEsQ0FBQyxLQUFLO1lBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3BELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxRQUFRLENBQUM7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEtBQUssUUFBUSxDQUFDLEtBQUssQ0FBQztRQUN6QyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsUUFBUTtRQUNOLDBFQUEwRTtRQUMxRSxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0I7WUFDbkIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssV0FBVyxDQUFDO2dCQUMzRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUc7WUFDbEIsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUU7WUFDdEMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUU7U0FDL0IsQ0FBQztRQUNGLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUMvRSx1Q0FBdUM7WUFDdkMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDbEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRTtZQUN4RixJQUFJLENBQUMsVUFBVSxHQUFHLGNBQWMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztRQUNILDJFQUEyRTtRQUMzRSx3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLFdBQVc7YUFDYixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMzQixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztZQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsSUFBSSxDQUFDLFdBQVc7YUFDYixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMzQixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztZQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsMEVBQTBFO1FBQzFFLG9EQUFvRDtRQUNwRCxJQUFJLENBQUMsV0FBVzthQUNiLHdCQUF3QixFQUFFO2FBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzNCLFNBQVMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUNMLHlFQUF5RTtRQUN6RSx5RUFBeUU7UUFDekUseUVBQXlFO1FBQ3pFLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUNsQixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMxQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FDbEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7WUFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQ2xCLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3pDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksSUFBSTtnQkFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxFQUFFO1lBQ3ZFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxlQUFlLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFO1lBQzNELElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN0RSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVCLDZFQUE2RTtZQUM3RSwwRUFBMEU7WUFDMUUscUVBQXFFO1lBQ3JFLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLDZCQUE2QixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM5RixJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLO2FBQ1AsaUJBQWlCLEVBQUU7YUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDM0IsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDdEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNoRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzNFLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxZQUFZLEVBQUUsRUFBRTtZQUM1RCxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDeEYsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7WUFDL0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUN2Qyw0RUFBNEU7WUFDNUUsNEVBQTRFO1lBQzVFLDZFQUE2RTtZQUM3RSw0RUFBNEU7WUFDNUUsNEVBQTRFO1lBQzVFLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pCLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7UUFDSCw2RUFBNkU7UUFDN0UseUVBQXlFO1FBQ3pFLDZFQUE2RTtRQUM3RSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQy9FLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxXQUFXLENBQUMsOEJBQThCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEcsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMsU0FBUyxDQUFDO1lBQzlELElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUNoQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN0QixPQUFPO2dCQUNULENBQUM7Z0JBQ0QsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztvQkFDekIsdUVBQXVFO29CQUN2RSxvREFBb0Q7b0JBQ3BELElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO29CQUM5QixvRUFBb0U7b0JBQ3BFLHVFQUF1RTtvQkFDdkUsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7b0JBQ2pDLGdDQUFnQztvQkFDaEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBRTNGLDZFQUE2RTtvQkFDN0UsNEVBQTRFO29CQUM1RSwyRUFBMkU7b0JBQzNFLDJFQUEyRTtvQkFDM0UsOEVBQThFO29CQUM5RSxpREFBaUQ7b0JBQ2pELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUNoRCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3hDLCtEQUErRDtvQkFDL0Qsc0NBQXNDO29CQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzt3QkFDaEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7d0JBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQzt3QkFDL0IsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7d0JBQ3pDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDNUMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFdBQVcsQ0FBQztvQkFDekMsQ0FBQztvQkFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7b0JBQ3ZDLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDakQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDMUIsOERBQThEO29CQUM5RCxzRUFBc0U7b0JBQ3RFLHVFQUF1RTtvQkFDdkUsd0VBQXdFO29CQUN4RSx1RUFBdUU7b0JBQ3ZFLHFFQUFxRTtvQkFDckUsd0RBQXdEO29CQUN4RCxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUNULE1BQU0sS0FBSyxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQzt3QkFDakMsTUFBTSxTQUFTLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLENBQUM7d0JBQ25ELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDOzRCQUNqQixvRUFBb0U7NEJBQ3BFLG9FQUFvRTs0QkFDcEUscUVBQXFFOzRCQUNyRSxnREFBZ0Q7NEJBQ2hELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQzs0QkFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7d0JBQzFCLENBQUM7d0JBQ0QsK0VBQStFO3dCQUMvRSxNQUFNLE9BQU8sR0FBdUIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7d0JBQzlFLE1BQU0sWUFBWSxHQUFHLE9BQU8sRUFBRSxZQUFZLElBQUksR0FBRyxDQUFDO3dCQUNsRCxxRUFBcUU7d0JBQ3JFLG1FQUFtRTt3QkFDbkUsaUVBQWlFO3dCQUNqRSw4REFBOEQ7d0JBQzlELElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQzVCLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQzlCLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7d0JBQ3pCLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDO3dCQUN6RCw2REFBNkQ7d0JBQzdELDhEQUE4RDt3QkFDOUQseURBQXlEO3dCQUN6RCxnRUFBZ0U7d0JBQ2hFLHlEQUF5RDt3QkFDekQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDdEQsNkRBQTZEO3dCQUM3RCw0REFBNEQ7d0JBQzVELGdFQUFnRTt3QkFDaEUsK0RBQStEO3dCQUMvRCxxQ0FBcUM7d0JBQ3JDLElBQUksT0FBTyxDQUFDLGFBQWEsS0FBSyxTQUFTLEVBQUUsQ0FBQzs0QkFDeEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDOzRCQUNwQyxPQUFPLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQzt3QkFDcEMsQ0FBQzt3QkFDRCx3Q0FBd0M7d0JBQ3hDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3hCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO3dCQUNwQixpRUFBaUU7d0JBQ2pFLGtFQUFrRTt3QkFDbEUsaUVBQWlFO3dCQUNqRSxvRUFBb0U7d0JBQ3BFLG1FQUFtRTt3QkFDbkUsTUFBTSxZQUFZLEdBQ2hCLElBQUksQ0FBQyxTQUFTOzRCQUNkLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU07NEJBQ2hELENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO3dCQUN2QyxNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxTQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQzt3QkFFL0Ysa0VBQWtFO3dCQUNsRSxxRUFBcUU7d0JBQ3JFLHlEQUF5RDt3QkFDekQsTUFBTSxVQUFVLEdBQUcsQ0FDakIsTUFBNkIsRUFDN0IsTUFBcUMsRUFDckMsRUFBRTs0QkFDRixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQzs0QkFDN0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVc7aUNBQzVCLFVBQVUsRUFBRTtpQ0FDWixHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQzs0QkFDMUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDN0MsQ0FBQyxDQUFDO3dCQUVGLE1BQU0sUUFBUSxHQUFHLEdBQUcsRUFBRTs0QkFDcEIsMERBQTBEOzRCQUMxRCxnRUFBZ0U7NEJBQ2hFLGlFQUFpRTs0QkFDakUsZ0VBQWdFOzRCQUNoRSw0REFBNEQ7NEJBQzVELGlFQUFpRTs0QkFDakUsa0VBQWtFOzRCQUNsRSw2Q0FBNkM7NEJBQzdDLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLEtBQUssRUFBRSxDQUFDO2dDQUMvQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO2dDQUNyQyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sSUFBSSxRQUFRLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQztnQ0FDakUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7Z0NBQzNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQ0FDcEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO29DQUNuQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQ0FDbEUsQ0FBQztnQ0FDRCxVQUFVLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0NBQ3JDLE9BQU87NEJBQ1QsQ0FBQzs0QkFDRCxpRUFBaUU7NEJBQ2pFLGdFQUFnRTs0QkFDaEUsNkRBQTZEOzRCQUM3RCxrRUFBa0U7NEJBQ2xFLG1FQUFtRTs0QkFDbkUsMkRBQTJEOzRCQUMzRCxnRUFBZ0U7NEJBQ2hFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7NEJBQ25DLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dDQUNwQixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0NBQ3ZFLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztnQ0FDM0QsSUFBSSxDQUFDLE9BQU8sSUFBSSxZQUFZLEVBQUUsQ0FBQztvQ0FDN0IsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7b0NBQzNDLEtBQUssTUFBTSxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7d0NBQ3hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO3dDQUNuQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dDQUM3QixJQUFJLE1BQU07NENBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7NENBQ3RCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQ0FDMUIsQ0FBQztvQ0FDRCxVQUFVLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO29DQUMvQixPQUFPO2dDQUNULENBQUM7NEJBQ0gsQ0FBQzs0QkFDRCwrREFBK0Q7NEJBQy9ELGtDQUFrQzs0QkFDbEMsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQ0FDWixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQ0FDeEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7Z0NBQ3JDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUN0RCxDQUFDO2dDQUNGLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7NEJBQzdDLENBQUM7NEJBQ0QsK0RBQStEOzRCQUMvRCxvRUFBb0U7NEJBQ3BFLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzt3QkFDdEMsQ0FBQyxDQUFDO3dCQUNGLElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQzt3QkFDNUIsTUFBTSxjQUFjLEdBQUcsR0FBRyxFQUFFOzRCQUMxQixJQUFJLGVBQWU7Z0NBQUUsT0FBTzs0QkFDNUIsZUFBZSxHQUFHLElBQUksQ0FBQzs0QkFDdkIsSUFBSSxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxTQUFTO2dDQUFFLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDOzRCQUNwRSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDcEMsQ0FBQyxDQUFDO3dCQUVGLElBQUksa0JBQWtCLENBQUM7NEJBQ3JCLGlFQUFpRTs0QkFDakUsK0RBQStEOzRCQUMvRCxXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLEVBQUU7Z0NBQ2xDLG9FQUFvRTtnQ0FDcEUscUVBQXFFO2dDQUNyRSxvRUFBb0U7Z0NBQ3BFLGlFQUFpRTtnQ0FDakUsOEJBQThCO2dDQUM5QixJQUFJLENBQUMsU0FBUyxFQUFFO29DQUFFLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQ0FDL0MsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO29DQUN4RSxpRUFBaUU7b0NBQ2pFLElBQUksQ0FBQyxTQUFTLEVBQUU7d0NBQUUsT0FBTyxJQUFJLENBQUM7b0NBQzlCLHNEQUFzRDtvQ0FDdEQsSUFBSSxTQUFTLENBQUMsUUFBUSxLQUFLLFdBQVcsQ0FBQyxRQUFRO3dDQUFFLE9BQU8sSUFBSSxDQUFDO29DQUM3RCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUMxQixJQUFJLENBQUMsV0FBVyxFQUNoQixXQUFXLEVBQ1gsU0FBUyxFQUNULFlBQVksRUFDWixJQUFJLENBQUMsUUFBUSxFQUNiLE9BQU8sQ0FDUixDQUFDO2dDQUNKLENBQUMsQ0FBQyxDQUFDOzRCQUNMLENBQUM7NEJBQ0QsVUFBVSxFQUFFLEdBQUcsRUFBRTtnQ0FDZixJQUFJLENBQUMsU0FBUyxFQUFFO29DQUFFLE9BQU8sQ0FBQyw4QkFBOEI7Z0NBQ3hELHdFQUF3RTtnQ0FDeEUsK0VBQStFO2dDQUMvRSw4RUFBOEU7Z0NBQzlFLDhFQUE4RTtnQ0FDOUUseUJBQXlCO2dDQUN6QixJQUFJLElBQUksQ0FBQyxTQUFTO29DQUFFLE9BQU87Z0NBQzNCLGlGQUFpRjtnQ0FDakYsd0RBQXdEO2dDQUN4RCxjQUFjLEVBQUUsQ0FBQztnQ0FDakIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7NEJBQ3pCLENBQUM7NEJBQ0QsY0FBYyxFQUFFLEdBQUcsRUFBRTtnQ0FDbkIsSUFBSSxDQUFDLFNBQVMsRUFBRTtvQ0FBRSxPQUFPLENBQUMsOEJBQThCO2dDQUN4RCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQzs0QkFDMUIsQ0FBQzs0QkFDRCxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0NBQzlCLElBQUksQ0FBQyxTQUFTLEVBQUU7b0NBQUUsT0FBTyxDQUFDLDhCQUE4QjtnQ0FDeEQsZ0ZBQWdGO2dDQUNoRixjQUFjLEVBQUUsQ0FBQztnQ0FDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0NBQ3JCLFFBQVEsRUFBRSxDQUFDO2dDQUNYLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2dDQUNoQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQ0FDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQzs0QkFDdEIsQ0FBQzs0QkFDRCxhQUFhLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQ0FDMUIsSUFBSSxDQUFDLFNBQVMsRUFBRTtvQ0FBRSxPQUFPLENBQUMsOEJBQThCO2dDQUN4RCw0REFBNEQ7Z0NBQzVELHlDQUF5QztnQ0FDekMsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLElBQUksR0FBRyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsVUFBVSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQ0FDbEYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUM7b0NBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO29DQUMxQixRQUFRLEVBQUUsTUFBTTtvQ0FDaEIsT0FBTyxFQUFFLHVCQUF1QjtvQ0FDaEMsTUFBTSxFQUFFLDZDQUE2QyxHQUFHLDZFQUE2RTtpQ0FDdEksQ0FBQyxDQUFDO2dDQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO2dDQUNyQixRQUFRLEVBQUUsQ0FBQztnQ0FDWCxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztnQ0FDaEMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7NEJBQ2hDLENBQUM7eUJBQ0YsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7b0JBQ25DLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDYixNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRSxVQUFVLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNsRixPQUFPLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM1RCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztvQkFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0JBQzFCLE1BQU0sRUFBRSxJQUFJO29CQUNaLFFBQVEsRUFBRSxPQUFPO29CQUNqQixPQUFPLEVBQUUsa0JBQWtCO29CQUMzQixNQUFNLEVBQUUseURBQXlELEdBQUc7a0ZBQ0k7aUJBQ3pFLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRTtZQUNuRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBYyxDQUFDO2dCQUFFLE9BQU87WUFDcEQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2dCQUNyRCxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTNFLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxLQUFvQixFQUFFLEVBQUU7WUFDOUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7WUFDM0MsSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsaUJBQWlCO2dCQUFFLE9BQU87WUFDcEcsbUVBQW1FO1lBQ25FLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQzVGLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLE9BQU87d0JBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQzs7d0JBQ3pELElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3ZDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLDZDQUE2QztnQkFDcEUsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsT0FBTztZQUNULENBQUM7WUFDRCxxRUFBcUU7WUFDckUscUJBQXFCO1lBQ3JCLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ25DLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDakMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztvQkFDekMsT0FBTztnQkFDVCxDQUFDO2dCQUNELElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7b0JBQy9DLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7b0JBQ3pDLE9BQU87Z0JBQ1QsQ0FBQztZQUNILENBQUM7WUFDRCxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssV0FBVyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQ2xHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN2QyxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDeEMsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNwRCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzFELENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDekQsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1lBQy9ELENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDckQsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUM1RCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXpELElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDekMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQWMsQ0FBQztnQkFBRSxPQUFPO1lBQ3BELDBFQUEwRTtZQUMxRSx5RUFBeUU7WUFDekUseUVBQXlFO1lBQ3pFLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztnQkFBRSxPQUFPO1lBQ2pELDBFQUEwRTtZQUMxRSwyRUFBMkU7WUFDM0UscUVBQXFFO1lBQ3JFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztnQkFBRSxPQUFPO1lBQzVCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZDLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN4QyxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUV4RiwwREFBMEQ7UUFDMUQsSUFBSSxDQUFDLHVCQUF1QixHQUFHLENBQUMsQ0FBYSxFQUFFLEVBQUU7WUFDL0MsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO29CQUNuQixJQUFJLENBQUMsZUFBZSxHQUFHO3dCQUNyQixDQUFDLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQzt3QkFDckUsQ0FBQyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7cUJBQ3RFLENBQUM7Z0JBQ0osQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO2lCQUFNLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUc7d0JBQ2hCLENBQUMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7d0JBQzNELENBQUMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7cUJBQzVELENBQUM7Z0JBQ0osQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEdBQUcsRUFBRTtZQUNoQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDbkUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUUvRCw2RUFBNkU7UUFDN0UsNEVBQTRFO1FBQzVFLHFFQUFxRTtRQUNyRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsR0FBRyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVztnQkFBRSxPQUFPO1lBQzlCLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsdUJBQXVCLENBQUMsQ0FBYTtRQUNuQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxpQkFBaUIsR0FBRztZQUN2QixFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU87WUFDYixFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU87WUFDYixDQUFDLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3pCLENBQUMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDMUIsQ0FBQztRQUNGLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQ7OEJBQzBCO0lBQzFCLGtCQUFrQixDQUFDLENBQWE7UUFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUM1QixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQzVCLElBQUksQ0FBQyxZQUFZLEdBQUc7WUFDbEIsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPO1lBQ2IsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPO1lBQ2IsQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwQixDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQ3JCLENBQUM7UUFDRixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSxXQUFXO1FBQ1QsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDL0IsQ0FBQztJQUVEOztpREFFNkM7SUFDckMsb0JBQW9CO1FBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU87UUFDOUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFRCw0RUFBNEU7SUFDNUUsS0FBSyxDQUFDLGNBQWM7UUFDbEIsMkVBQTJFO1FBQzNFLDBFQUEwRTtRQUMxRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLHFCQUFxQixFQUFFLENBQUM7WUFDaEYsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJO2dCQUN6QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUU7Z0JBQ3pELENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ3ZCLENBQUM7UUFDRCw4RUFBOEU7UUFDOUUsdUVBQXVFO1FBQ3ZFLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdkMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsY0FBYyxFQUFFLENBQUM7UUFDekUsdUVBQXVFO1FBQ3ZFLDBEQUEwRDtRQUMxRCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsMkVBQTJFO1lBQzNFLHlFQUF5RTtZQUN6RSw4REFBOEQ7WUFDOUQsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDaEMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULHlFQUF5RTtRQUN6RSx1RUFBdUU7UUFDdkUsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzlCLHlFQUF5RTtRQUN6RSxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMvQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6QixNQUFNLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hFLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDL0IsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNwRSxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMvQixNQUFNLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdkMsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN0QixJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDaEQsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM5QyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsNkJBQTZCLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMsNkJBQTZCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkQsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3hDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMzQyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDMUMsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVNLFVBQVU7UUFDZixvRUFBb0U7UUFDcEUsMkVBQTJFO1FBQzNFLGlFQUFpRTtRQUNqRSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxpQkFBaUI7UUFDdEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7T0FHRztJQUNILGtCQUFrQjtRQUNoQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUN2QyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVEOzs7T0FHRztJQUNILGNBQWMsQ0FBQyxZQUFzQjtRQUNuQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdDLENBQUM7SUFDSCxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELG9CQUFvQjtRQUNsQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO0lBQ25DLENBQUM7SUFFRCxpREFBaUQ7SUFDakQsbUJBQW1CO1FBQ2pCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7SUFDbEMsQ0FBQztJQUVEOzswREFFc0Q7SUFDdEQsZ0JBQWdCO1FBQ2QseUVBQXlFO1FBQ3pFLHVFQUF1RTtRQUN2RSx5RUFBeUU7UUFDekUsK0RBQStEO1FBQy9ELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUseUJBQXlCLENBQUM7UUFDM0QsTUFBTSxLQUFLLEdBQUcsUUFBUTtZQUNwQixDQUFDLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBYyxRQUFRLENBQUMsRUFBRSxxQkFBcUIsRUFBRSxDQUFDLEtBQUs7WUFDOUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNkLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNoRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDSCxpQkFBaUIsQ0FBQyxtQkFBd0I7UUFDeEMsTUFBTSxTQUFTLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxLQUFLLE1BQU0sQ0FBQztRQUNyRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7UUFDL0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7UUFDaEYsSUFBSSxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUM7UUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2QyxtRUFBbUU7UUFDbkUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUN0QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7WUFDakMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7WUFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsWUFBWSxDQUFDLElBQWU7UUFDMUIsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNsQixDQUFDO1FBQ0QsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsUUFBUSxDQUFDLENBQXFCO1FBQzVCLElBQUksQ0FBQyxLQUFLLFNBQVM7WUFBRSxPQUFPO1FBQzVCLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLDZFQUE2RTtRQUM3RSxvRUFBb0U7UUFDcEUsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzNELElBQUksQ0FBQyxXQUFXLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxRQUFRLENBQUMsQ0FBcUI7UUFDNUIsSUFBSSxDQUFDLEtBQUssU0FBUztZQUFFLE9BQU87UUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDaEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7OztPQUtHO0lBRUgsU0FBUyxDQUFDLENBQWdCO1FBQ3hCLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxXQUFXLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZO1lBQUUsT0FBTztRQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU87UUFDMUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQTRCLENBQUM7UUFDekMsSUFBSSxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQztZQUFFLE9BQU87UUFDdEYsMkVBQTJFO1FBQzNFLHdDQUF3QztRQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7WUFBRSxPQUFPO1FBQ2pGLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxTQUFTLENBQUMsS0FBYTtRQUNyQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUNqQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxhQUFhO1FBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsMEVBQTBFO1FBQzFFLDBFQUEwRTtRQUMxRSwwRUFBMEU7UUFDMUUsc0VBQXNFO1FBQ3RFLG9FQUFvRTtRQUNwRSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUMsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBQ0QsYUFBYTtRQUNYLDJGQUEyRjtRQUMzRiwyRkFBMkY7UUFDM0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVELGNBQWM7UUFDWixJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxtRkFBbUY7SUFDbkYsc0JBQXNCO1FBQ3BCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztRQUN6RCxJQUFJLENBQUMsV0FBVyxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQsY0FBYyxDQUFDLElBQVk7UUFDekIsMEVBQTBFO1FBQzFFLGVBQWU7UUFDZixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2Qiw4Q0FBOEM7UUFDOUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQsOEVBQThFO0lBQ3RFLGFBQWEsQ0FBQyxJQUFtQjtRQUN2QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ25DLHFEQUFxRDtRQUNyRCxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVuQyxnRUFBZ0U7UUFDaEUsSUFBSSxDQUFDLFdBQVc7YUFDYixnQkFBZ0IsRUFBRTtZQUNuQixFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBRSxNQUF5QixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU3RSx5RUFBeUU7UUFDekUsMkNBQTJDO1FBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDL0IsTUFBTSxZQUFZLEdBQUcsTUFBTSxLQUFLLEtBQUssSUFBSSxNQUFNLEtBQUssTUFBTSxDQUFDO1lBQzNELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBRUQsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sS0FBSyxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDdkYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsTUFBTSxLQUFLLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDaEcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsTUFBTSxLQUFLLFVBQVUsQ0FBQyxDQUFDO1FBQ3hELDJEQUEyRDtRQUMzRCxJQUFJLE1BQU0sS0FBSyxVQUFVO1lBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsTUFBTSxLQUFLLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELElBQUksTUFBTSxLQUFLLGFBQWEsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDbEUsQ0FBQztJQUNILENBQUM7SUFFRDs7cUZBRWlGO0lBQ3pFLFlBQVksQ0FBQyxJQUFtQjtRQUN0QyxPQUFPLENBQ0wsSUFBSSxLQUFLLFVBQVU7WUFDbkIsSUFBSSxLQUFLLGdCQUFnQjtZQUN6QixJQUFJLEtBQUssY0FBYztZQUN2QixJQUFJLEtBQUssUUFBUTtZQUNqQixJQUFJLEtBQUssYUFBYTtZQUN0QixJQUFJLEtBQUssVUFBVTtZQUNuQixJQUFJLEtBQUssYUFBYTtZQUN0QixJQUFJLEtBQUssTUFBTSxDQUNoQixDQUFDO0lBQ0osQ0FBQztJQUVEO21GQUMrRTtJQUMvRSxnQkFBZ0IsQ0FBQyxNQUE0QjtRQUMzQyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUFFLE9BQU87UUFDekMsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVELHVCQUF1QixDQUFDLEtBQXlCO1FBQy9DLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTztRQUMzRCxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxLQUF5QjtRQUN6QyxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsMEJBQTBCLENBQUMsS0FBeUI7UUFDbEQsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPO1FBQzNELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCwyRUFBMkU7SUFDM0UsVUFBVTtRQUNSLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELCtEQUErRDtJQUMvRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsMkVBQTJFO0lBRTNFLDZEQUE2RDtJQUM3RCxJQUFZLGVBQWU7UUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxQyxPQUFPLElBQUksQ0FBQyxlQUFlO2FBQ3hCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs2REFDeUQ7SUFDakQsVUFBVSxDQUFDLE9BQWlCO1FBQ2xDLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FDbkQsQ0FBQyxDQUFDLE1BQU0sWUFBWSxTQUFTO1lBQzdCLENBQUMsQ0FBQyxNQUFNLFlBQVksWUFBWTtZQUNoQyxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksT0FBTyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUMzRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7d0VBQ29FO0lBQzVELFdBQVcsQ0FBQyxPQUFpQjtRQUNuQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUM7WUFDdkIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxFQUFZLEVBQUUsRUFBWSxFQUFFLEVBQUU7Z0JBQzFDLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRTtvQkFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRTtvQkFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDO1lBQ0YsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFlBQVksU0FBUztvQkFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7cUJBQy9ELElBQUksQ0FBQyxZQUFZLE9BQU87b0JBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUNyRCxJQUFJLENBQUMsWUFBWSxZQUFZO29CQUFFLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVE7d0JBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdGLENBQUM7WUFDRCxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNyQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLElBQUksZUFBZSxLQUFjLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUYsdUVBQXVFO0lBQ3ZFLElBQUksaUJBQWlCLEtBQWMsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0csK0VBQStFO0lBQy9FLElBQUksb0JBQW9CLEtBQWMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVqRywyRUFBMkU7SUFDM0UsZ0JBQWdCO1FBQ2QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxQyxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7UUFDN0IsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTO1lBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxXQUFXLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSxZQUFZO1FBQ1YsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbEQsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUM7WUFBRSxPQUFPO1FBQzNCLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQy9DLElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsc0VBQXNFO0lBQ3RFLGNBQWM7UUFDWixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDN0IsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO1FBQzdCLEtBQUssTUFBTSxDQUFDLElBQUksR0FBRztZQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCx5RUFBeUU7SUFDekUsY0FBYztRQUNaLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTztRQUM3QixNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztnQkFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxjQUFjO2dCQUN4QixRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTO2dCQUNwQyxNQUFNLEVBQUUsOERBQThEO2FBQ3ZFLENBQUMsQ0FBQztZQUNILE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxzRUFBc0U7SUFDdEUsZUFBZSxDQUFDLFdBQW1CO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTztRQUM3QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUVELGlEQUFpRDtJQUNqRCxrQkFBa0IsS0FBVyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUVqRTs7OztPQUlHO0lBQ0ssY0FBYyxDQUFDLE1BQWdCLEVBQUUsR0FBYTtRQUNwRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDN0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsbUNBQW1DO1FBQ25GLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDN0MsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxXQUFXLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzttRkFFK0U7SUFDL0UsS0FBSyxDQUFDLGNBQWM7UUFDbEIsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7SUFDbEcsQ0FBQztJQUVEOzttRkFFK0U7SUFDL0UsS0FBSyxDQUFDLGVBQWU7UUFDbkIsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFLENBQ3BFLElBQUksQ0FBQyxXQUFXLENBQUMseUJBQXlCLEVBQUUsQ0FDN0MsQ0FBQztJQUNKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsU0FBUyxDQUFDLE1BQWM7UUFDdEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDN0IsaUVBQWlFO1lBQ2pFLHdFQUF3RTtZQUN4RSx5RUFBeUU7WUFDekUsc0VBQXNFO1lBQ3RFLGdFQUFnRTtZQUNoRSx5RUFBeUU7WUFDekUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLFVBQVUsQ0FBQyxJQUE2QjtRQUN0QyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUM3RCxDQUFDO0lBRUQ7NkNBQ3lDO0lBQ3pDLGlCQUFpQixDQUFDLENBQXNDO1FBQ3RELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQix5RUFBeUU7UUFDekUsMkVBQTJFO1FBQzNFLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BFLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRDtrRUFDOEQ7SUFDdEQsVUFBVSxDQUFDLElBQTZCLEVBQUUsT0FBZTtRQUMvRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLE9BQU8sQ0FBQyxDQUFDO1FBQzFELE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxRQUFRLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsV0FBVyxDQUFDLENBQWdCO1FBQzFCLE9BQU8sQ0FBb0IsQ0FBQztJQUM5QixDQUFDO0lBRUQsV0FBVyxDQUFDLENBQWdCO1FBQzFCLE9BQU8sQ0FBb0IsQ0FBQztJQUM5QixDQUFDO0lBRUQsY0FBYyxDQUFDLE1BQWM7UUFDM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLHFDQUFxQztRQUM3RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDO0lBQ2pDLENBQUM7SUFFRDswQkFDc0I7SUFDdEIsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsZUFBZSxDQUFDLE1BQWM7UUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLElBQUk7WUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRUQ7O21GQUUrRTtJQUMvRSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQWM7UUFDMUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDbEIsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3RSxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQzdELElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FDbkMsQ0FBQztJQUNKLENBQUM7SUFFRDs7b0ZBRWdGO0lBQ3hFLEtBQUssQ0FBQyxtQkFBbUIsQ0FDL0IsS0FBYTtJQUNiLDBFQUEwRTtJQUMxRSwwRUFBMEU7SUFDMUUsb0RBQW9EO0lBQ3BELElBQW9FLEVBQ3BFLEVBQXlCO1FBRXpCLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDMUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUNILDJFQUEyRTtRQUMzRSx5RUFBeUU7UUFDekUsdUVBQXVFO1FBQ3ZFLElBQUksVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3hDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ04sVUFBVSxHQUFHLENBQUMsQ0FBQztnQkFDZixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILE1BQU0sQ0FBQyxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUM7Z0JBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDeEIsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTTtnQkFDcEMsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsTUFBTSxFQUFFLFVBQVUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDO2FBQzlFLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUM7Z0JBQ3RCLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDeEIsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQzthQUNqRSxDQUFDLENBQUM7UUFDTCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzZDQUN5QztJQUNqQyxZQUFZLENBQUMsT0FBZTtRQUNsQyxJQUFJLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFRCwyRUFBMkU7SUFDbkUsWUFBWTtRQUNsQixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELGdCQUFnQixDQUFDLEVBQVU7UUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELDREQUE0RDtJQUM1RCxjQUFjO1FBQ1osSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRCxvRUFBb0U7SUFDcEUsZUFBZTtRQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssc0JBQXNCO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQztRQUMzRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxHQUFlLEVBQUUsQ0FBQztRQUU3QiwyRUFBMkU7UUFDM0UscUJBQXFCO1FBQ3JCLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDVCxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLG9CQUFvQjtZQUN2RCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1NBQ3ZDLENBQUMsQ0FBQztRQUVILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDcEMsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpDLElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN6QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7UUFDRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNyRCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2hHLENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDekIsS0FBSyxDQUFDLElBQUksQ0FDUixFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLEVBQy9FO2dCQUNFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLGtCQUFrQjtnQkFDM0MsS0FBSyxFQUFFO29CQUNMLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDakUsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUNsRSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2xFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRTtvQkFDbkIsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtpQkFDL0Q7YUFDRixDQUNGLENBQUM7UUFDSixDQUFDO1FBQ0QseUVBQXlFO1FBQ3pFLGdEQUFnRDtRQUNoRCxJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3pDLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNwQyxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxZQUFZLFNBQVMsQ0FBQyxDQUFDO1lBQ3RGLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksT0FBTyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDckYsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0csQ0FBQztZQUNELElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDOUcsQ0FBQztRQUNILENBQUM7UUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2hHLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVPLHFCQUFxQjtRQUMzQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ25DLE1BQU0sV0FBVyxHQUFHLHFCQUFxQixDQUFDO1FBQzFDLE1BQU0sS0FBSyxHQUFlLEVBQUUsQ0FBQztRQUM3QiwyRUFBMkU7UUFDM0UsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDOUMsSUFBSSxPQUFPLENBQUMsTUFBTTtnQkFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLEtBQUssQ0FBQyxJQUFJLENBQ1IsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLEVBQzNGLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUNwQixDQUFDO1lBQ0YseUVBQXlFO1lBQ3pFLHFFQUFxRTtZQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUN0QixLQUFLLENBQUMsSUFBSSxDQUFDO29CQUNULEtBQUssRUFBRSxnQkFBZ0I7b0JBQ3ZCLElBQUksRUFBRSxjQUFjO29CQUNwQixVQUFVLEVBQUUsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUNoRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7aUJBQzNDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUNULEtBQUssRUFBRSxhQUFhO2dCQUNwQixJQUFJLEVBQUUsbUJBQW1CO2dCQUN6QixVQUFVLEVBQUUsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNyRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUM7YUFDaEQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osSUFBSSxFQUFFLGtCQUFrQjtnQkFDeEIsVUFBVSxFQUFFLE1BQU0sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDO2FBQzFDLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1lBQ3JDLEtBQUssQ0FBQyxJQUFJLENBQ1I7Z0JBQ0UsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLFVBQVUsRUFBRSxHQUFHLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQzdDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDO2FBQ2hELEVBQ0Q7Z0JBQ0UsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osSUFBSSxFQUFFLGtCQUFrQjtnQkFDeEIsVUFBVSxFQUFFLEdBQUcsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDNUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUM7YUFDL0MsRUFDRDtnQkFDRSxLQUFLLEVBQUUsa0JBQWtCO2dCQUN6QixJQUFJLEVBQUUsYUFBYTtnQkFDbkIsVUFBVSxFQUFFLEdBQUcsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7YUFDakQsRUFDRDtnQkFDRSxLQUFLLEVBQUUsb0JBQW9CO2dCQUMzQixJQUFJLEVBQUUsWUFBWTtnQkFDbEIsVUFBVSxFQUFFLEdBQUcsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDbEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUM7YUFDckQsRUFDRCxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFDbkIsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQ3hGLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsS0FBSyxDQUFDLElBQUksQ0FDUixFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFDN0UsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxvQkFBb0IsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQ2hGLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUNuQjtnQkFDRSxLQUFLLEVBQUUsUUFBUTtnQkFDZixJQUFJLEVBQUUsc0JBQXNCO2dCQUM1QixVQUFVLEVBQUUsTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNsRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUM7YUFDN0MsRUFDRDtnQkFDRSxLQUFLLEVBQUUsVUFBVTtnQkFDakIsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLFVBQVUsRUFBRSxNQUFNLEtBQUssZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDMUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUM7YUFDckQsRUFDRDtnQkFDRSxLQUFLLEVBQUUsT0FBTztnQkFDZCxJQUFJLEVBQUUsWUFBWTtnQkFDbEIsVUFBVSxFQUFFLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDakQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO2FBQzVDLEVBQ0Q7Z0JBQ0UsS0FBSyxFQUFFLFVBQVU7Z0JBQ2pCLElBQUksRUFBRSxlQUFlO2dCQUNyQixVQUFVLEVBQUUsTUFBTSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUN4RCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUM7YUFDbkQsRUFDRDtnQkFDRSxLQUFLLEVBQUUsV0FBVztnQkFDbEIsSUFBSSxFQUFFLFlBQVk7Z0JBQ2xCLFVBQVUsRUFBRSxNQUFNLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQzthQUMvQyxFQUNEO2dCQUNFLEtBQUssRUFBRSxNQUFNO2dCQUNiLElBQUksRUFBRSxXQUFXO2dCQUNqQixVQUFVLEVBQUUsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNoRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7YUFDM0MsRUFDRDtnQkFDRSxLQUFLLEVBQUUsZUFBZTtnQkFDdEIsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLFVBQVUsRUFBRSxNQUFNLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3ZELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQzthQUNsRCxDQUNGLENBQUM7WUFDRiwwREFBMEQ7WUFDMUQsdUVBQXVFO1lBQ3ZFLDBCQUEwQjtZQUMxQixJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN6QyxLQUFLLENBQUMsSUFBSSxDQUNSO29CQUNFLEtBQUssRUFBRSwwQkFBMEI7b0JBQ2pDLElBQUksRUFBRSx1QkFBdUI7b0JBQzdCLFVBQVUsRUFBRSxNQUFNLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3ZELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQztpQkFDbEQsRUFDRDtvQkFDRSxLQUFLLEVBQUUsWUFBWTtvQkFDbkIsSUFBSSxFQUFFLGlCQUFpQjtvQkFDdkIsVUFBVSxFQUFFLE1BQU0sS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDcEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDO2lCQUMvQyxFQUNEO29CQUNFLEtBQUssRUFBRSxlQUFlO29CQUN0QixJQUFJLEVBQUUsb0JBQW9CO29CQUMxQixVQUFVLEVBQUUsTUFBTSxLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUN2RCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUM7aUJBQ2xELENBQ0YsQ0FBQztZQUNKLENBQUM7WUFDRCw0RUFBNEU7WUFDNUUsc0VBQXNFO1FBQ3hFLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxJQUFZO1FBQzlCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7UUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7a0VBQzhEO0lBQzlELFVBQVU7UUFDUixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNyQyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsY0FBYyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRCxrR0FBa0c7SUFDbEcsZUFBZTtRQUNiLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQzdDLElBQUksQ0FBQyxXQUFXLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxZQUFZLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUVEO3NHQUNrRztJQUNsRyxnQkFBZ0IsQ0FBQyxLQUFhO1FBQzVCLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxlQUFlO1lBQUUsT0FBTztRQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGdCQUFnQixDQUFDLFFBQW9CO1FBQ25DLHlFQUF5RTtRQUN6RSwwRUFBMEU7UUFDMUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNuRSxPQUFPLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxRQUFRLGdCQUFnQixRQUFRLENBQUMsS0FBSyxZQUFZLENBQUMsQ0FBQztZQUNwRyxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUM1QixDQUFDO1FBQ0QsdUVBQXVFO1FBQ3ZFLHlFQUF5RTtRQUN6RSxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDdEMsMkVBQTJFO1FBQzNFLDZFQUE2RTtRQUM3RSxzQkFBc0I7UUFDdEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM1QiwyRUFBMkU7UUFDM0UsMkVBQTJFO1FBQzNFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELGlGQUFpRjtRQUNqRixvRUFBb0U7UUFDcEUsSUFBSSxJQUFJLEtBQUssUUFBUSxDQUFDLEtBQUs7WUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxDQUFDOztZQUN0RCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFFBQVEsQ0FBQztRQUNuQyxNQUFNLFVBQVUsR0FBRyxpQkFBaUIsQ0FBQyxRQUFRLENBQUM7WUFDNUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQztZQUNoRCxDQUFDLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsTUFBTSxJQUFJLEdBQUcsVUFBVSxFQUFFLFVBQVUsS0FBSyxJQUFJLENBQUM7UUFDN0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyw0RUFBNEU7UUFDNUUsMkVBQTJFO1FBQzNFLHFFQUFxRTtRQUNyRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFdBQVcsQ0FBQztRQUN6QyxDQUFDO1FBQ0Qsd0ZBQXdGO1FBQ3hGLHNGQUFzRjtRQUN0RiwwRkFBMEY7UUFDMUYsTUFBTSxRQUFRLEdBQUcsSUFBSSxLQUFLLFFBQVEsQ0FBQyxZQUFZLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BFLElBQUksVUFBVSxFQUFFLGFBQWEsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzNDLDBFQUEwRTtZQUMxRSxxRUFBcUU7WUFDckUsMkVBQTJFO1lBQzNFLDJFQUEyRTtZQUMzRSx5RUFBeUU7WUFDekUscUVBQXFFO1lBQ3JFLHNFQUFzRTtZQUN0RSxvREFBb0Q7WUFDcEQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztnQkFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzFDLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsMEVBQTBFO0lBRTFFOzs7OztPQUtHO0lBQ0ssd0JBQXdCO1FBQzlCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUMsVUFBVSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQ2hGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxJQUFJLElBQUksQ0FBQztRQUNsRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksaUJBQWlCO2tCQUMvRiw2REFBNkQsQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN4QyxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFvQjtZQUMzQixVQUFVLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDNUIsUUFBUTtZQUNSLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTtZQUN0QyxLQUFLLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDMUIsQ0FBQztRQUNGLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDtnRkFDNEU7SUFDcEUsaUJBQWlCLENBQUMsTUFBc0I7UUFDOUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUM7UUFDeEMsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPO1FBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLFdBQVcsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUM1QyxJQUFJLENBQUMsYUFBYSxHQUFHO29CQUNuQixLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7b0JBQ2xCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztvQkFDMUIsUUFBUSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUM7d0JBQ3hCLFNBQVMsRUFBRTs0QkFDVCxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRTs0QkFDcEQsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUU7eUJBQ3pEO3dCQUNELE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUTtxQkFDdEIsQ0FBQztvQkFDRixJQUFJLEVBQUUsSUFBSTtpQkFDWCxDQUFDO1lBQ0osQ0FBQztpQkFBTSxJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3ZHLENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPO1lBQ1QsQ0FBQztZQUNELDhFQUE4RTtZQUM5RSwrRUFBK0U7WUFDL0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDdkMsSUFBSSxHQUFHLEtBQUssSUFBSTtnQkFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCw2RUFBNkU7SUFDckUsaUJBQWlCO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDMUIsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7T0FHRztJQUNLLG9CQUFvQixDQUFDLFlBQWtDO1FBQzdELElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEtBQUssWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUN4RixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDOUMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztZQUMvQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztnQkFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxjQUFjO2dCQUN4QixRQUFRLEVBQUUsTUFBTTtnQkFDaEIsT0FBTyxFQUFFLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxlQUFlLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxLQUFLLGlCQUFpQjtnQkFDckcsTUFBTSxFQUFFLDBHQUEwRzthQUNuSCxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxxRUFBcUU7SUFDN0QsbUJBQW1CO1FBQ3pCLElBQUksSUFBSSxDQUFDLFVBQVU7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNqQyxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLG9GQUFvRixFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3pHLE9BQU8sR0FBRyxJQUFJLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDckQsQ0FBQztJQUNILENBQUM7SUFFRCw0RUFBNEU7SUFFNUUsNkVBQTZFO0lBQzdFLGdCQUFnQixDQUFDLEVBQVU7UUFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFBRSxPQUFPO1FBQ3ZELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDM0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUMsd0NBQXdDO1FBQ2pGLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxnRkFBZ0Y7SUFDaEYsZUFBZTtRQUNiLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsNEVBQTRFO0lBQ3BFLHNCQUFzQjtRQUM1QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDakMsTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsS0FBSztZQUFFLE9BQU87UUFDOUQsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxZQUFZLEtBQUssWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTztZQUFFLE9BQU87UUFDaEcsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDO1FBQ2xFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsNkRBQTZELENBQUMsQ0FBQztZQUM1RyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRyxDQUFDLENBQUM7WUFDM0IsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBc0I7WUFDN0IsVUFBVSxFQUFFLElBQUksQ0FBQyxXQUFXO1lBQzVCLFFBQVE7WUFDUixVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUU7WUFDdEMsS0FBSyxFQUFFLElBQUksQ0FBQyxhQUFhO1NBQzFCLENBQUM7UUFDRixLQUFLLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBTUQ7Ozs7T0FJRztJQUNLLGNBQWMsQ0FBQyxNQUFzQjtRQUMzQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4RixJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDbEIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsU0FBUyxHQUFHLGtCQUFrQixDQUFDO1FBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsVUFBVSxHQUFHO2dCQUNoQixLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUs7Z0JBQ3ZDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxPQUFPO2dCQUNwQyxJQUFJO2FBQ0wsQ0FBQztZQUNGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ3ZDLElBQUksR0FBRyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNqQixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDakMsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0ZBQWtGO2FBQzFELDhCQUF5QixHQUFHLEVBQUUsQUFBTCxDQUFNO0lBRXZEOzs7OztPQUtHO0lBQ0ssbUJBQW1CLENBQUMsSUFBbUMsRUFBRSxNQUFzQixFQUMzRCxJQUFpQixFQUFFLE1BQWM7UUFDM0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDNUIsNEVBQTRFO1FBQzVFLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxLQUFLLElBQUk7WUFBRSxPQUFPO1FBQ2xGLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsSUFBSSxNQUFNLEdBQUcsbUJBQW1CLENBQUMseUJBQXlCLEVBQUUsQ0FBQztnQkFDM0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxxQkFBcUIsQ0FDMUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxPQUFPO1lBQ1QsQ0FBQztZQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLElBQUksQ0FBQyxFQUFFLDBEQUEwRCxDQUFDLENBQUM7UUFDL0csQ0FBQztRQUNELElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxHQUF3QixFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNuRixJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxRQUFRLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM3RSxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLElBQUksQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzNFLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBRUQsbUZBQW1GO0lBQzNFLGNBQWM7UUFDcEIsSUFBSSxJQUFJLENBQUMsZUFBZSxLQUFLLElBQUk7WUFBRSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDNUIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBQ3pDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7UUFDL0IsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQztnQkFDSCxRQUFRLEVBQUUsQ0FBQztZQUNiLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsK0NBQStDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDdEUsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVU7WUFBRSxPQUFPO1FBQzdCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVTtZQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQ25ELENBQUM7SUFFRCwwREFBMEQ7SUFDbEQsZ0JBQWdCLENBQUMsRUFBVTtRQUNqQyxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLEVBQUU7WUFBRSxPQUFPO1FBQzVELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO2dCQUN0QixHQUFHLEVBQUUsSUFBSSxDQUFDLGNBQWM7Z0JBQ3hCLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsS0FBSyxJQUFJLEVBQUUsaUJBQWlCO2dCQUM5QyxNQUFNLEVBQUUsZ0VBQWdFO2FBQ3pFLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHFGQUFxRjtJQUNyRixJQUNJLGNBQWMsQ0FBQyxHQUF3QztRQUN6RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztRQUNuQyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxHQUFHLENBQUMsYUFBYTtZQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25HLENBQUM7SUFxQkQsbUVBQW1FO0lBQzNELG9CQUFvQjtRQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDOzhHQXQrRVUsbUJBQW1CLGtCQTRXcEIsZ0JBQWdCLGFBQ2hCLFVBQVUsd1FBU0UsVUFBVSw2QkFJVixhQUFhLDZCQUdiLGlCQUFpQiw2QkFHakIsdUJBQXVCO2tHQWhZbEMsbUJBQW1CLHVrQkMzRWhDLDZpZkFnU0E7OzJGRHJOYSxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBR0UsWUFBWTs7MEJBZ1huQixNQUFNOzJCQUFDLGdCQUFnQjs7MEJBQ3ZCLE1BQU07MkJBQUMsVUFBVTs7MEJBU2pCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsVUFBVTs7MEJBSTdCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsYUFBYTs7MEJBR2hDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsaUJBQWlCOzswQkFHcEMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyx1QkFBdUI7OzBCQUcxQyxRQUFRO3lDQTlWWCxZQUFZO3NCQURYLE1BQU07Z0JBR1AsZ0JBQWdCO3NCQURmLE1BQU07Z0JBTUgsWUFBWTtzQkFEZixLQUFLO2dCQWNOLFFBQVE7c0JBRFAsS0FBSztnQkE2Q1csV0FBVztzQkFBM0IsU0FBUzt1QkFBQyxJQUFJO2dCQXNLWCxpQkFBaUI7c0JBRHBCLFNBQVM7dUJBQUMsbUJBQW1CO2dCQThyQzlCLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkEyL0J0QyxjQUFjO3NCQURqQixTQUFTO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEFmdGVyVmlld0luaXQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbmplY3QsIEluamVjdG9yLCBJbnB1dCwgTmdab25lLCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBPcHRpb25hbCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBUeXBlLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTWVudUl0ZW0sIE1lc3NhZ2VTZXJ2aWNlLCBUcmVlTm9kZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IENvbnRleHRNZW51IH0gZnJvbSAncHJpbWVuZy9jb250ZXh0bWVudSc7XG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi9jb250cmFjdHMvaW1hZ2UuY29udHJhY3QnO1xuaW1wb3J0IHsgSW1hZ2VTdGF0ZVBvcnQsIElNQUdFX1NUQVRFX1BPUlQgfSBmcm9tICcuL2NvbnRyYWN0cy9wb3J0cy9pbWFnZS1zdGF0ZS5wb3J0JztcbmltcG9ydCB7IFBvbHlnb24sIFJlY3RhbmdsZSwgTXVsdGlQb2x5Z29uLCBSZWdpb24gfSBmcm9tICcuL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgUmVnaW9uT3BzU2VydmljZSB9IGZyb20gJy4vcmVnaW9uLW9wcy5zZXJ2aWNlJztcbmltcG9ydCB7IFZJWl9UT0FTVF9LRVksIFZJWl9BTEVSVF9UT0FTVF9LRVkgfSBmcm9tICcuL3RvYXN0LW91dGxldHMnO1xuaW1wb3J0IHsgVmlzdWFsaXplclN0b3JlIH0gZnJvbSAnLi9zdG9yZS92aXN1YWxpemVyLXN0b3JlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVuZGVyT3JjaGVzdHJhdG9yLCBTbGljZVNjcnViYmVyIH0gZnJvbSAnLi9yZW5kZXItb3JjaGVzdHJhdG9yJztcbmltcG9ydCB7XG4gIFBsb3RUeXBlLFxuICBQbG90VHlwZURlc2NyaXB0b3IsXG4gIFBsb3RUeXBlSWQsXG4gIGdldFBsb3RUeXBlRGVzY3JpcHRvcixcbiAgaXNCdWlsdGluUGxvdFR5cGUsXG4gIGlzTmFwYXJpM2QsXG4gIGlzU3BhdGlhbE9taWNzM2QsXG4gIHJlbmRlcmVyT3duc1doZWVsLFxuICBOQVBBUklfREVGQVVMVF9ERUNJTUFURSxcbn0gZnJvbSAnLi9jb250cmFjdHMvcGxvdC10eXBlJztcbmltcG9ydCB7XG4gIFBMT1RfTU9ERV9DT05URVhULFxuICBQTE9UX01PREVfU0VTU0lPTixcbiAgUExPVF9UWVBFX0NPTlRSSUJVVElPTlMsXG4gIFBsb3RNb2RlQnJ1c2hDbGFzcyxcbiAgUGxvdE1vZGVDb250ZXh0LFxuICBQbG90TW9kZVRvb2xzLFxuICBQbG90VHlwZUNvbnRyaWJ1dGlvbixcbiAgUGxvdFR5cGVPcHRpb24sXG4gIGNvbnRyaWJ1dGVkUGxvdFR5cGVPcHRpb24sXG59IGZyb20gJy4vY29udHJhY3RzL3Bsb3QtdHlwZS1jb250cmlidXRpb24uY29udHJhY3QnO1xuaW1wb3J0IHsgQWN0aXZlUGxvdE1vZGUsIFBsb3RNb2RlQ29udHJvbGxlciB9IGZyb20gJy4vcGxvdC1tb2RlL3Bsb3QtbW9kZS1jb250cm9sbGVyJztcbmltcG9ydCB7IFZpZXdlckZlYXR1cmUgfSBmcm9tICcuL2NvbnRyYWN0cy9jYXBhYmlsaXRpZXMuY29udHJhY3QnO1xuaW1wb3J0IHsgSW50ZW5zaXR5UHJvZmlsZSwgSVZpc3VhbGl6ZXIsIFZJU1VBTElaRVIgfSBmcm9tICcuL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IFNBTV9NT0RFTFMsIGdldERlZmF1bHRTYW1Nb2RlbElkLCBpc1NhbU1vZGVsUmVhZHkgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NhbS1tb2RlbC1yZWdpc3RyeSc7XG5pbXBvcnQgeyBTYW1Ub29sU2VydmljZSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLXRvb2wuc2VydmljZSc7XG5pbXBvcnQgeyBTYW1Qb2ludFRvb2xTZXJ2aWNlIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zYW0tcG9pbnQtdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IENlbGxTZWdtZW50VG9vbFNlcnZpY2UgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL2NlbGwtc2VnbWVudC10b29sLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgVE9PTEJBUl9UT09MUyxcbiAgTnVtYmVyUGFyYW1TcGVjLFxuICBTZWxlY3RQYXJhbVNwZWMsXG4gIFRvb2xQYXJhbVNwZWMsXG4gIFRvb2xiYXJDb250cmlidXRpb24sXG4gIFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uLFxuICBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbixcbiAgVG9vbERpYWxvZ0NvbnRleHQsXG4gIGRpYWxvZ1Rvb2xDb250cmlidXRpb25zLFxuICB2aXNpYmxlVG9vbENvbnRyaWJ1dGlvbnMsXG59IGZyb20gJy4vY29udHJhY3RzL3Rvb2xiYXItdG9vbC5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb25Ub29sTW9kZSB9IGZyb20gJy4vY29udHJhY3RzL3JlZ2lvbi1vdmVybGF5LmNvbnRyYWN0JztcbmltcG9ydCB7IFRvb2xiYXJUb29sVmlzaWJpbGl0eSwgQUxMX1RPT0xCQVJfVE9PTFMgfSBmcm9tICcuL2NvbnRyYWN0cy90b29sYmFyLWNvbmZpZyc7XG5pbXBvcnQgeyBWSVpfQ09ORklHLCBWaXpDb25maWcgfSBmcm9tICcuL2NvbnRyYWN0cy92aXotY29uZmlnJztcbmltcG9ydCB7IFNQQVRJQUxfREFUQV9QT1JULCBTcGF0aWFsRGF0YVBvcnQgfSBmcm9tICcuL2NvbnRyYWN0cy9wb3J0cy9zcGF0aWFsLWRhdGEucG9ydCc7XG5pbXBvcnQgeyBTcGF0aWFsRGF0YXNldCB9IGZyb20gJy4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBidWlsZFZvbHVtZVN0YWNrSW1hZ2UgfSBmcm9tICcuL3NwYXRpYWwvc3BhdGlhbC12b2x1bWUtaW1hZ2UnO1xuXG4vKiogUGVyLWluc3RhbmNlIHBsb3QtZGl2IGlkIHNvdXJjZS4gVGhlIG1vdW50IGVsZW1lbnQncyBpZCBtdXN0IGJlIHVuaXF1ZSBzbyB0d29cbiAqICBsaXZlIHZpZXdlcnMgKGUuZy4gdGhlIG1haW4gZGlhZ3JhbSArIGEgbW9kYWwgcHJldmlldykgZG9uJ3QgY29sbGlkZSBvbiB0aGVcbiAqICBzYW1lIERPTSBpZCDigJQgYGdldEVsZW1lbnRCeUlkYCB3b3VsZCBvdGhlcndpc2UgcmV0dXJuIHdoaWNoZXZlciBjYW1lIGZpcnN0LlxuICogIFN0eWxpbmcgaGFuZ3Mgb2ZmIHRoZSBgLnZpei1wbG90YCBjbGFzcyBpbnN0ZWFkIG9mIHRoZSBpZC4gKi9cbmxldCBwbG90SW5zdGFuY2VTZXEgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgLy8gQ2Fub25pY2FsIHByZWZpeGVkIHNlbGVjdG9yIGZpcnN0OyB0aGUgdW5wcmVmaXhlZCBvcmlnaW5hbCBpcyBrZXB0IGFzIGFuXG4gIC8vIGFsaWFzIGZvciBvbmUgcmVsZWFzZSAocHJlLXB1YmxpY2F0aW9uIGJhY2stY29tcGF0KS5cbiAgc2VsZWN0b3I6ICd2aXN1YWxpemVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Zpc3VhbGl6ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi92aXN1YWxpemVyLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFZpc3VhbGl6ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIFBlci1pbnN0YW5jZSB0b2FzdCBrZXkuIE1lc3NhZ2VTZXJ2aWNlIGlzIGEgZ2xvYmFsIHNpbmdsZXRvbiwgc28gdHdvIGxpdmVcbiAgICogIGA8dmlzdWFsaXplcj5gIGluc3RhbmNlcyAobWFpbiB2aWV3ZXIgKyBwaXBlbGluZS1kaWFsb2cgcHJldmlldykgc2hhcmluZ1xuICAgKiAgb25lIGtleSB3b3VsZCBlYWNoIHJlbmRlciB0aGUgc2FtZSBtZXNzYWdlIOKAlCBhIGR1cGxpY2F0ZSB0b2FzdC4gQSB1bmlxdWVcbiAgICogIGtleSBwZXIgaW5zdGFuY2Ugc2NvcGVzIHRoZSB0b2FzdCB0byB0aGUgY29tcG9uZW50IHRoYXQgcmFpc2VkIGl0LiAqL1xuICBwcml2YXRlIHN0YXRpYyBuZXh0VG9hc3RJZCA9IDA7XG5cbiAgLyoqXG4gICAqIFRoZSBsaWJyYXJ5IGFsc28gcmFpc2VzIG5vdGljZXMgZnJvbSBwbGFjZXMgdGhhdCBoYXZlIG5vIGluc3RhbmNlIG9mIHRoZWlyXG4gICAqIG93biB0byBrZXkgYWdhaW5zdDoge0BsaW5rIFBsb3RseVNlcnZpY2V9IGlzIGBwcm92aWRlZEluOiAncm9vdCdgLCBhbmQgdGhlXG4gICAqIHJlZ2lvbiBlZGl0b3IgaXMgYSBjaGlsZCBkaWFsb2cuIFRob3NlIHVzZSB0aGUgZml4ZWRcbiAgICoge0BsaW5rIFZJWl9UT0FTVF9LRVl9IC8ge0BsaW5rIFZJWl9BTEVSVF9UT0FTVF9LRVl9IG91dGxldHMuXG4gICAqXG4gICAqIEZvciB0aGUgc2FtZSByZWFzb24gdGhlIHBlci1pbnN0YW5jZSBrZXkgYWJvdmUgZXhpc3RzLCBleGFjdGx5IE9ORSBtb3VudGVkXG4gICAqIHZpc3VhbGl6ZXIgbWF5IHJlbmRlciB0aG9zZSBzaGFyZWQgb3V0bGV0cyDigJQgb3RoZXJ3aXNlIGEgbWVzc2FnZSBmcm9tIHRoZVxuICAgKiByb290IHNlcnZpY2Ugd291bGQgYmUgc2hvd24gb25jZSBwZXIgbGl2ZSB2aWV3ZXIgKGppdC11aSBydW5zIGEgbWFpbiB2aWV3XG4gICAqIGFuZCBhIHBpcGVsaW5lLXByZXZpZXcgYXQgdGhlIHNhbWUgdGltZSkuIFRoZSBmaXJzdCB0byBpbml0IGNsYWltcyB0aGVtIGFuZFxuICAgKiByZWxlYXNlcyBvbiBkZXN0cm95LCBzbyB0aGUgc3Vydml2aW5nIHZpZXdlciBwaWNrcyB0aGVtIHVwLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgbGl2ZUluc3RhbmNlcyA9IG5ldyBTZXQ8VmlzdWFsaXplckNvbXBvbmVudD4oKTtcbiAgcmVhZG9ubHkgdml6VG9hc3RLZXkgPSBWSVpfVE9BU1RfS0VZO1xuICByZWFkb25seSB2aXpBbGVydFRvYXN0S2V5ID0gVklaX0FMRVJUX1RPQVNUX0tFWTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBpbnN0YW5jZSByZW5kZXJzIHRoZSBzaGFyZWQgb3V0bGV0cy4gVGhlIG93bmVyIGlzIHNpbXBseSB0aGVcbiAgICogb2xkZXN0IGxpdmUgdmlzdWFsaXplciDigJQgYSBgU2V0YCBpdGVyYXRlcyBpbiBpbnNlcnRpb24gb3JkZXIsIHNvIHdoZW4gdGhlXG4gICAqIG93bmVyIGlzIGRlc3Ryb3llZCB0aGUgbmV4dCBvbmUgdGFrZXMgb3ZlciBvbiBpdHMgZm9sbG93aW5nIGNoYW5nZS1kZXRlY3Rpb25cbiAgICogcGFzcy4gVHJhY2tpbmcgYSBzZXQgcmF0aGVyIHRoYW4gYSBzaW5nbGUgb3duZXIgbWF0dGVyczogd2l0aCBhIGxvbmVcbiAgICogYG93bmVyYCByZWZlcmVuY2UsIHRlYXJpbmcgZG93biB0aGUgb3duZXIgd2hpbGUgYSBzaWJsaW5nIHdhcyBhbHJlYWR5XG4gICAqIGluaXRpYWxpc2VkIHdvdWxkIGxlYXZlIG5vYm9keSByZW5kZXJpbmcgdGhlIG91dGxldHMsIGFuZCBldmVyeSBub3RpY2UgZnJvbVxuICAgKiB0aGUgcm9vdCBzZXJ2aWNlIHdvdWxkIHNpbGVudGx5IHZhbmlzaCBhZ2Fpbi5cbiAgICovXG4gIGdldCBvd25zU2hhcmVkVG9hc3RzKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG9sZGVzdCA9IFZpc3VhbGl6ZXJDb21wb25lbnQubGl2ZUluc3RhbmNlcy52YWx1ZXMoKS5uZXh0KCk7XG4gICAgcmV0dXJuICFvbGRlc3QuZG9uZSAmJiBvbGRlc3QudmFsdWUgPT09IHRoaXM7XG4gIH1cblxuICBAT3V0cHV0KClcbiAgaXNTdGFja0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSk7XG4gIEBPdXRwdXQoKVxuICBpc0dyYXlzY2FsZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSk7XG5cbiAgLyoqIFdoaWNoIHRvb2xiYXIgZ3JvdXBzIHRvIHNob3cuIEEgcGFydGlhbCBvdmVycmlkZSBtZXJnZXMgb3ZlciB0aGUgZnVsbCBzZXQsXG4gICAqICBzbyBgeyBzcGVjaWFsVG9vbHM6IGZhbHNlIH1gIGhpZGVzIG9ubHkgdGhhdCBncm91cC4gRGVmYXVsdHMgdG8gZXZlcnl0aGluZy4gKi9cbiAgQElucHV0KClcbiAgc2V0IHRvb2xiYXJUb29scyh2OiBUb29sYmFyVG9vbFZpc2liaWxpdHkgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl90b29sYmFyVG9vbHMgPSB7IC4uLkFMTF9UT09MQkFSX1RPT0xTLCAuLi4odiA/PyB7fSkgfTtcbiAgfVxuXG4gIGdldCB0b29sYmFyVG9vbHMoKTogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiB7XG4gICAgcmV0dXJuIHRoaXMuX3Rvb2xiYXJUb29scztcbiAgfVxuICBwcml2YXRlIF90b29sYmFyVG9vbHM6IFJlcXVpcmVkPFRvb2xiYXJUb29sVmlzaWJpbGl0eT4gPSBBTExfVE9PTEJBUl9UT09MUztcblxuICAvKiogRXhwb3NlIHRlc3Qtb25seSBwbG90IG1vZGVzIGluIHRoZSBzZWxlY3RvciAoZS5nLiB0aGUgbmFwYXJpIGBJbWFnZWBcbiAgICogIG1vZGUsIG90aGVyd2lzZSBoaWRkZW4pLiBUaGUgaG9zdCBhcHAgc2V0cyB0aGlzIGZyb20gYSBgP3Rlc3Q9MWAgVVJMXG4gICAqICB0b2dnbGUuIE9mZiBieSBkZWZhdWx0LCBzbyBwcm9kdWN0aW9uIHVzZXJzIG5ldmVyIHNlZSB0aGVtLiAqL1xuICBASW5wdXQoKVxuICB0ZXN0TW9kZSA9IGZhbHNlO1xuXG4gIC8qKiBJbWFnZS1zbW9vdGhpbmcgc3RhdGUgZm9yIHRoZSB0b29sYmFyJ3MgU21vb3RoZW4gdG9nZ2xlIChPU0Qgb25seSkuXG4gICAqICBEZWZhdWx0cyB0byBgZmFsc2VgIHNvIE9TRCBzaG93cyByYXcgcGl4ZWxzIChuZWFyZXN0LW5laWdoYm91cikuICovXG4gIGltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGZhbHNlO1xuICBsb2FkaW5nTWVzc2FnZSA9ICdMb2FkaW5nIGltYWdlLi4uJztcbiAgem9vbSA9IGZhbHNlO1xuICBmaWxlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGxvYWRlZEZpbGVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGltYWdlSW5mbzogSUltYWdlSW5mbyB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIHVuc3ViID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBwcmV2aWV3U3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIHB1YmxpYyBzdGFja0xvYWRpbmcgPSBmYWxzZTtcbiAgcHVibGljIGltZ0xvYWRpbmcgPSBmYWxzZTtcbiAgcHVibGljIGxvYWRpbmdQZXJjZW50YWdlID0gMDtcbiAgLy8gTm9uLW51bGwgKDAuLjEwMCkgd2hpbGUgaml0LXNlcnZpY2UgaXMgY29weWluZyB0aGUgc291cmNlIGZpbGUgaW50byB0aGVcbiAgLy8gbG9jYWwgY2FjaGUgUFZDIG9uIGZpcnN0IGNsaWNrLiBXaGVuIHNldCwgdGhlIGxvYWRpbmcgb3ZlcmxheSBzd2FwcyB0aGVcbiAgLy8gc3Bpbm5lciBmb3IgYSBkZXRlcm1pbmF0ZSBwcm9ncmVzcyBiYXIgd2l0aCBhIFwiQ2FjaGluZyBpbWFnZVwiIG1lc3NhZ2UuXG4gIHB1YmxpYyBjYWNoZVByb2dyZXNzOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLy8gVHJ1ZSBiZXR3ZWVuIHRoZSBzbWFsbC10aWVyIHJlbmRlciBsYW5kaW5nIGFuZCB0aGUgbGFyZ2UtdGllciByZW5kZXJcbiAgLy8gbGFuZGluZyBpbiB0aGUgbXVsdGktdGllciByZW5kZXJpbmcgcGF0aC4gVGhlIHRlbXBsYXRlIHVzZXMgdGhpcyB0b1xuICAvLyBvdmVybGF5IGEgdHJhbnNsdWNlbnQgc3Bpbm5lciBvbiB0b3Agb2YgdGhlIGJsdXJyeSBzbWFsbC10aWVyIGltYWdlIHNvXG4gIC8vIHRoZSB1c2VyIGRvZXNuJ3QgbWlzdGFrZSBpdCBmb3IgdGhlIGZpbmFsIHByZXZpZXcuXG4gIHB1YmxpYyBzaGFycGVuaW5nID0gZmFsc2U7XG4gIC8qKiBBIGppdC1zZXJ2aWNlIGNhY2hlIGNvcHkgaXMgYWN0aXZlbHkgaW4gcHJvZ3Jlc3MgKGRldGVybWluYXRlIDAuLjk5KS4gRHJpdmVzIHRoZSBjYWNoZVxuICAgKiAgcHJvZ3Jlc3MgYmFyIGluZGVwZW5kZW50bHkgb2YgYGltZ0xvYWRpbmdgIHNvIHRoZSBiYXIgY2FuJ3QgYmUgZHJvcHBlZCDigJQgb3IgbWFza2VkIGJ5IHRoZVxuICAgKiAgXCJTaGFycGVuaW5nIHByZXZpZXcuLi5cIiBvdmVybGF5IOKAlCBtaWQtZG93bmxvYWQgaWYgdGhlIGxvYWRpbmcgZmxhZyBmbGlwcyBlYXJseS4gKi9cbiAgZ2V0IGlzQ2FjaGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZVByb2dyZXNzICE9PSBudWxsICYmIHRoaXMuY2FjaGVQcm9ncmVzcyA8IDEwMDtcbiAgfVxuICBwcml2YXRlIHJ1bm5pbmcgPSBmYWxzZTtcblxuICAvKipcbiAgICogTW9ub3RvbmljIHJlbmRlciBnZW5lcmF0aW9uLiBCdW1wZWQgd2hlbiBhIHJlbmRlciBzdGFydHMsIHNvIGEgcmVuZGVyIHRoYXRcbiAgICogaGFzIGJlZW4gc3VwZXJzZWRlZCBieSBhIG5ld2VyIGltYWdlIGNhbiBiZSByZWNvZ25pc2VkIGFuZCBtYWRlIGluZXJ0OiBpdHNcbiAgICogY2FsbGJhY2tzIHJldHVybiBlYXJseSBpbnN0ZWFkIG9mIHBhaW50aW5nLCBjbGVhcmluZyBgcnVubmluZ2AsIHJlbGVhc2luZ1xuICAgKiB0aGUgbmV3ZXIgcmVuZGVyJ3Mgb3ZlcmxheSwgb3IgYXBwbHlpbmcgaXRzIFJPSXMuXG4gICAqL1xuICBwcml2YXRlIHJlbmRlclRva2VuID0gMDtcbiAgcHVibGljIHpJbmRleCA9IDA7XG4gIHB1YmxpYyBtYXhJbmRleCA9IDA7XG5cbiAgQFZpZXdDaGlsZCgnY20nKSBjb250ZXh0TWVudSE6IENvbnRleHRNZW51O1xuICBjb250ZXh0TWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XG5cbiAgYWN0aXZlRHJhZ01vZGU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBXaGV0aGVyIGEgcmVnaW9uIGFjdGlvbiBpcyBhdmFpbGFibGUgdG8gdW5kbyAoaml0LXVpIzg1KS4gTWlycm9ycyB0aGVcbiAgICogIHNoYXJlZCBSZWdpb25TdG9yZSdzIGhpc3RvcnkgZGVwdGg7IGRyaXZlcyB0aGUgdG9vbGJhciBVbmRvIGJ1dHRvbi4gKi9cbiAgY2FuVW5kb1JlZ2lvbiA9IGZhbHNlO1xuICAvKiogV2hldGhlciBhbiB1bmRvbmUgcmVnaW9uIGFjdGlvbiBpcyBhdmFpbGFibGUgdG8gcmVkbyAoaml0LXVpIzg1KS4gKi9cbiAgY2FuUmVkb1JlZ2lvbiA9IGZhbHNlO1xuXG4gIC8qKiBDdXN0b20tdGhyZXNob2xkIFNpbXBsaWZ5IGRpYWxvZyAoaml0LXVpIzg1KS4gKi9cbiAgZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gZmFsc2U7XG4gIHNpbXBsaWZ5VGhyZXNob2xkID0gMztcbiAgLyoqIEN1cnJlbnQgcmVnaW9uIHNlbGVjdGlvbiAoYXJyYXkgaW5kaWNlcykg4oCUIG1pcnJvcmVkIGZyb20gdGhlIHN0b3JlIHNvIHRoZVxuICAgKiAgY29udGV4dC1tZW51IHJlZ2lvbiBhY3Rpb25zIGNhbiByZWFkIGl0IHN5bmNocm9ub3VzbHkgKGppdC11aSM4NSkuICovXG4gIHByaXZhdGUgc2VsZWN0ZWRJbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuXG4gIC8qKiBXYW5kIHNlbnNpdGl2aXR5IOKAlCBoaWdoZXIgPSBzdHJpY3RlciAoc21hbGxlciBzZWxlY3Rpb24pLiBNYXRjaGVzIFF1UGF0aCBkZWZhdWx0LiAqL1xuICB3YW5kU2Vuc2l0aXZpdHkgPSAyLjA7XG4gIC8qKiBCcnVzaCBkaWFtZXRlciBpbiBpbWFnZS1waXhlbCBjb29yZGluYXRlcyAoZHJpdmVzIHRoZSBwYWludGVkIGRpc2Mgc2l6ZSkuICovXG4gIGJydXNoU2l6ZSA9IDQwO1xuICAvKiogQ2xhc3MgdGhlIGJydXNoIHBhaW50cyB3aGlsZSBhIHBsb3QgbW9kZSBhcm1lZCBpdCAoUGxvdE1vZGVUb29scy5hcm1CcnVzaCk7IG51bGwgPSBwbGFpbiBicnVzaC4gKi9cbiAgcHJpdmF0ZSBicnVzaENsYXNzOiBQbG90TW9kZUJydXNoQ2xhc3MgfCBudWxsID0gbnVsbDtcbiAgLyoqIFNBTSBtb2RlbCBwaWNrZXIgb3B0aW9ucyArIGN1cnJlbnQgc2VsZWN0aW9uIChqaXQtdWkjOTAgUDEpLiBPbmx5IG1vZGVsc1xuICAgKiAgd2l0aCBhIGhvc3RlZCBPTk5YIHBhaXIgKGNvbmZpZ3VyZWQgdmlhIHNldFNhbU1vZGVsVXJscyBhdCBhcHAgaW5pdCkgYXJlXG4gICAqICBvZmZlcmVkLCBzbyB0aGUgcGlja2VyIGNhbid0IHNlbGVjdCBhIG1vZGVsIHRoYXQgY2FuJ3QgcnVuLiAqL1xuICBzYW1Nb2RlbHMgPSBTQU1fTU9ERUxTLmZpbHRlcihpc1NhbU1vZGVsUmVhZHkpLm1hcCgobSkgPT4gKHsgaWQ6IG0uaWQsIGxhYmVsOiBtLmxhYmVsIH0pKTtcbiAgc2FtTW9kZWxJZCA9IGdldERlZmF1bHRTYW1Nb2RlbElkKCk7XG5cbiAgLyoqXG4gICAqIE5vLXByb21wdCB0b29scyByZWdpc3RlcmVkIHRocm91Z2gge0BsaW5rIFRPT0xCQVJfVE9PTFN9LCBmaWx0ZXJlZCB0byB0aG9zZVxuICAgKiB3aXRoIGNvbmZpZ3VyZWQgbW9kZWxzIGFuZCBzb3J0ZWQuIFRoaXMgbGlicmFyeSByZWdpc3RlcnMgbm9uZSDigJQgYSBob3N0XG4gICAqIHN1cHBsaWVzIHRoZW0g4oCUIHNvIGFuIG9wZW4gYnVpbGQgaGFzIGFuIGVtcHR5IGFycmF5IGhlcmUgYW5kIHRoZSB0b29sYmFyXG4gICAqIGFuZCBoZWxwIGRpYWxvZyBzaW1wbHkgb21pdCB0aGF0IGdyb3VwLlxuICAgKi9cbiAgY29udHJpYnV0ZWRUb29sczogVG9vbGJhclRvb2xDb250cmlidXRpb25bXSA9IFtdO1xuICAvKipcbiAgICogRGlhbG9nIHRvb2xzIHJlZ2lzdGVyZWQgdGhyb3VnaCB7QGxpbmsgVE9PTEJBUl9UT09MU30gKGBraW5kOiAnZGlhbG9nJ2ApLFxuICAgKiBzb3J0ZWQuIFRoZWlyIGJ1dHRvbnMgc2l0IHdpdGggdGhlIGhvc3QncyBvd24gYWN0aW9ucyBhbmQgc2hvdyBpbiB0aGUgSW1hZ2VcbiAgICogdmlldyBvbmx5OyBlYWNoIG9wZW5zIGEgZmxvYXRpbmcgZGlhbG9nIHRoZSB0b29sIGZpbGxzLlxuICAgKi9cbiAgZGlhbG9nVG9vbHM6IFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIFRoZSBkaWFsb2cgdG9vbCB0aGUgdXNlciBoYXMgb3BlbiAoaXRzIHNlc3Npb24gbWF5IGJlIGJldHdlZW4gcmVuZGVycykuICovXG4gIG9wZW5EaWFsb2dUb29sSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIG9wZW4gZGlhbG9nIHRvb2wncyBsaXZlIGRpYWxvZywgYXMgdGhlIHRlbXBsYXRlIHJlbmRlcnMgaXQuICovXG4gIHRvb2xEaWFsb2c6IHsgdGl0bGU6IHN0cmluZzsgd2lkdGg6IHN0cmluZzsgaG9zdDogSFRNTEVsZW1lbnQgfSB8IG51bGwgPSBudWxsO1xuICAvKiogRGlhbG9nLXRvb2wgc2Vzc2lvbnM6IHRoZSBzYW1lIGxpZmVjeWNsZSBhbmQgaXNvbGF0aW9uIGFzIGNvbnRyaWJ1dGVkIHBsb3QgbW9kZXMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdG9vbERpYWxvZ3M6IFBsb3RNb2RlQ29udHJvbGxlcjtcbiAgLyoqIEFjdGl2ZSBjaGVja3BvaW50IHBlciBjb250cmlidXRlZCB0b29sLiAqL1xuICB0b29sTW9kZWxJZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgLyoqXG4gICAqIFBhcmFtZXRlciB2YWx1ZXMgcGVyIGNvbnRyaWJ1dGVkIHRvb2wsIHNlZWRlZCBmcm9tIGVhY2ggdG9vbCdzIG93biBkZWZhdWx0c1xuICAgKiDigJQgd2hpY2ggZW5jb2RlIHRoZSBzY2FsZSBhbmQgY3Jvd2RpbmcgaXRzIGNoZWNrcG9pbnQgd2FzIHRyYWluZWQgZm9yLlxuICAgKi9cbiAgdG9vbFBhcmFtczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0ge307XG4gIC8qKiBXaGljaCB0b29sJ3MgcGFyYW1ldGVyIGRpYWxvZyBpcyBvcGVuLCBvciBudWxsLiAqL1xuICBvcGVuUGFyYW1zVG9vbElkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFNBTSBkb3dubG9hZC9zZWdtZW50IHRvYXN0IHN0YXRlIChib3VuZCBieSB0aGUgYHNhbWAgcC10b2FzdCB0ZW1wbGF0ZSkuICovXG4gIHNhbVN0YXR1cyA9ICcnO1xuICBzYW1Qcm9ncmVzcyA9IDA7IC8vIDAuLjEwMCwgZW5jb2RlciBkb3dubG9hZFxuICBzYW1Eb3dubG9hZGluZyA9IGZhbHNlO1xuICBzYW1CdXN5ID0gZmFsc2U7IC8vIGFueSBTQU0gd29yayBpbiBmbGlnaHQgKGRyaXZlcyB0aGUgaW5kZXRlcm1pbmF0ZSBzcGlubmVyKVxuICAvKiogV2hldGhlciB0aGUgc2hhcmVkIGBzYW1gIHRvYXN0IGlzIGN1cnJlbnRseSBzaG93biAoYXZvaWRzIHN0YWNraW5nIGl0IG9uXG4gICAqICBldmVyeSBwb2ludCBjbGljaywgd2hpY2ggcmUtcnVucyBpbmZlcmVuY2UpLiAqL1xuICBwcml2YXRlIHNhbVRvYXN0U2hvd24gPSBmYWxzZTtcblxuICByZWFkb25seSBzYW1Ub2FzdEtleSA9IGBzYW0tJHtWaXN1YWxpemVyQ29tcG9uZW50Lm5leHRUb2FzdElkKyt9YDtcbiAgLyoqXG4gICAqIE91dGxldCBmb3IgdGhlIGxpYnJhcnkncyBvd24gcmVzdWx0L2Vycm9yIG5vdGljZXMuXG4gICAqXG4gICAqIFByaW1lTkcgcm91dGVzIGEgbWVzc2FnZSB0byBhIGA8cC10b2FzdD5gIG9ubHkgd2hlbiB0aGUga2V5cyBtYXRjaCDigJQgYVxuICAgKiBrZXlsZXNzIG1lc3NhZ2UgcmVhY2hlcyBhIGtleWxlc3MgdG9hc3QgYW5kIG5vdGhpbmcgZWxzZS4gVGhlc2Ugbm90aWNlcyB1c2VkXG4gICAqIHRvIGJlIGVtaXR0ZWQgd2l0aCBubyBrZXksIHNvIHRoZXkgcmVuZGVyZWQgb25seSBpbiBob3N0cyB0aGF0IGhhcHBlbiB0b1xuICAgKiBtb3VudCBhIGJhcmUgYDxwLXRvYXN0PmAgKGppdC11aSBkb2VzLCBpbiBpdHMgZmlsZS10cmVlIGNvbXBvbmVudCkuIEV2ZXJ5XG4gICAqIG90aGVyIGhvc3Qg4oCUIGluY2x1ZGluZyB0aGlzIHJlcG8ncyBvd24gYnJvd3NlciBleGFtcGxlIOKAlCBkcm9wcGVkIHRoZW1cbiAgICogc2lsZW50bHksIHdoaWNoIG1hZGUgYSBmYWlsZWQgb3Igbm8tb3Agc2VnbWVudGF0aW9uIGxvb2sgbGlrZSBhIGRlYWQgYnV0dG9uOlxuICAgKiB0aGUgc3RpY2t5IHByb2dyZXNzIHRvYXN0IGlzIGNsZWFyZWQgaW4gdGhlIHNhbWUgdGljayBieSBoaWRlU2FtVG9hc3QsIGFuZFxuICAgKiB0aGUgbWVzc2FnZSBleHBsYWluaW5nIHdoeSBuZXZlciBhcHBlYXJlZCBhbnl3aGVyZS5cbiAgICpcbiAgICogS2V5ZWQgdG8gdGhpcyBjb21wb25lbnQgaW5zdGFuY2Ugc28gdGhlIGxpYnJhcnkgcmVuZGVycyBpdHMgb3duIG91dGxldCBhbmRcbiAgICogaXMgbm90IGRlcGVuZGVudCBvbiBob3N0IG1hcmt1cC4gRGVsaWJlcmF0ZWx5IE5PVCB0aGUgc3RpY2t5IHRvYXN0J3Mga2V5OlxuICAgKiB7QGxpbmsgaGlkZVNhbVRvYXN0fSBjbGVhcnMgdGhhdCBrZXkgaW4gdGhlIGBmaW5hbGx5YCwgd2hpY2ggd291bGQgd2lwZSB0aGVcbiAgICogcmVzdWx0IHRoZSBtb21lbnQgaXQgd2FzIHBvc3RlZCwgYW5kIHRoZSBzdGlja3kgdG9hc3QncyBjdXN0b20gdGVtcGxhdGUgaXNcbiAgICogYnVpbHQgZm9yIHRoZSBsaXZlIHN0YXR1cyArIHByb2dyZXNzIGJhci5cbiAgICovXG4gIHJlYWRvbmx5IHJlc3VsdFRvYXN0S2V5ID0gYCR7dGhpcy5zYW1Ub2FzdEtleX0tcmVzdWx0YDtcbiAgLyoqIFN1YnNjcmlwdGlvbnMgdG8gdGhlIHBvaW50IHRvb2wncyBsaXZlIGZlZWRzIChzdGF0dXMvYnVzeS9kb3dubG9hZCkuICovXG4gIHByaXZhdGUgc2FtUG9pbnRTdWIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIC8qKiBWZXJ0ZXggZXJhc2VyIHJhZGl1cyBpbiBpbWFnZS1waXhlbCBjb29yZGluYXRlcy4gKi9cbiAgdmVydGV4RXJhc2VyUmFkaXVzID0gMjA7XG5cbiAgY29sb3JtYXBzT3B0aW9ucyE6IGFueTtcbiAgcmV2ZXJzZXNjYWxlID0gZmFsc2U7XG4gIHNlbGVjdGVkQ29sb3JtYXAhOiBhbnk7XG4gIC8qKiBDaGFubmVscyAmIEhpc3RvZ3JhbSBkaWFsb2cgdmlzaWJpbGl0eSAob3BlbmVkIGZyb20gdGhlIHRvb2xiYXIpLiAqL1xuICBzaG93Q2hhbm5lbEhpc3RvZ3JhbSA9IGZhbHNlO1xuICAvKiogU3BhdGlhbC1vbWljcyBjb250cm9scyBkaWFsb2cgdmlzaWJpbGl0eSAodG9vbGJhciBidXR0b24pLiAqL1xuICBzaG93U3BhdGlhbENvbnRyb2xzID0gZmFsc2U7XG4gIC8qKiBSZWdpb24gRWRpdG9yIGRpYWxvZyB2aXNpYmlsaXR5IChvcGVuZWQgZnJvbSB0aGUgdG9vbGJhcikuICovXG4gIHNob3dSZWdpb25FZGl0b3IgPSBmYWxzZTtcbiAgLyoqIFJlZ2lvbiBFZGl0b3IgZGlhbG9nIHdpZHRoLiBPbiBvcGVuIGl0IGlzIHNldCB0byB0aGUgY29uZmlndXJlZCBob3N0XG4gICAqICBlbGVtZW50J3MgY3VycmVudCB3aWR0aCwgb3Ig4oCUIHdoZW4gbm8gc2VsZWN0b3IgaXMgY29uZmlndXJlZCAvIHRoZSBlbGVtZW50XG4gICAqICBpc24ndCBmb3VuZCDigJQgdG8gYSBxdWFydGVyIG9mIHRoZSBwYWdlIChzZWUgb3BlblJlZ2lvbkVkaXRvcikuICovXG4gIHJlZ2lvbkVkaXRvcldpZHRoID0gJzI1dncnO1xuICBzdGFja09wdGlvbnMgPSBbXG4gICAgeyBuYW1lOiAnU2luZ2xlIGltYWdlJywgdmFsOiAnZmFsc2UnIH0sXG4gICAgeyBuYW1lOiAnU3RhY2snLCB2YWw6ICd0cnVlJyB9LFxuICBdO1xuICBzZWxlY3RlZFN0YWNrT3B0aW9uOiB7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfSB8IHVuZGVmaW5lZCA9IHRoaXMuc3RhY2tPcHRpb25zWzBdO1xuICByZWFkb25seSBwbG90RGl2TmFtZSA9IGB2aXotcGxvdC0ke3Bsb3RJbnN0YW5jZVNlcSsrfWA7XG4gIHBsb3RUeXBlID0gUGxvdFR5cGUuSU1BR0U7XG4gIGlzSGVhdG1hcCA9IHRydWU7XG4gIGFjdGl2ZVN1cmZhY2UzZE1vZGUgPSAndHVybnRhYmxlJztcbiAgLyoqIFdoZXRoZXIgdGhlIG5hcGFyaSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyBpcyBzaG93biAodm9sdW1lL2lzb3N1cmZhY2UpLiAqL1xuICBheGVzVmlzaWJsZSA9IHRydWU7XG4gIHdpcmVmcmFtZUFjdGl2ZSA9IGZhbHNlO1xuICAvKiogbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciAoMSA9IEZ1bGwg4oCmIDggPSDihZs7IGRlZmF1bHQgwr0pOyBjaGFuZ2luZyBpdCByZS1wbG90cy4gKi9cbiAgcmVzb2x1dGlvblNjYWxlID0gTkFQQVJJX0RFRkFVTFRfREVDSU1BVEU7XG5cbiAgLyoqIFRoZSBzZWxlY3RvcidzIGVudHJpZXM6IHRoZSBidWlsdC1pbiBwbG90IHR5cGVzIHRoZSBhY3RpdmUgYmFja2VuZFxuICAgKiAgYWR2ZXJ0aXNlcyAoM0QgZ2F0ZWQgYnkgY2FwYWJpbGl0eSksIHRoZW4gYW55IGNvbnRyaWJ1dGVkIG1vZGVzXG4gICAqICAoe0BsaW5rIFBMT1RfVFlQRV9DT05UUklCVVRJT05TfSkuICovXG4gIHBsb3RUeXBlTWVudTogUGxvdFR5cGVPcHRpb25bXSA9IFtdO1xuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHBsb3QgdHlwZXMgb24gb2ZmZXIg4oCUIHtAbGluayBwbG90VHlwZU1lbnV9IHdpdGhvdXQgY29udHJpYnV0ZWRcbiAgICogbW9kZXMuIEtlcHQgd2l0aCBpdHMgb3JpZ2luYWwgdHlwZSBzbyBleGlzdGluZyByZWFkZXJzIGFyZSB1bmFmZmVjdGVkLlxuICAgKi9cbiAgcGxvdFR5cGVPcHRpb25zOiBQbG90VHlwZURlc2NyaXB0b3JbXSA9IFtdO1xuICAvKipcbiAgICogV2hhdCB0aGUgc2VsZWN0b3Igc2hvd3M6IGEgYnVpbHQtaW4gdHlwZSBvciBhIGNvbnRyaWJ1dGVkIG1vZGUncyBpZC4gRXZlcnlcbiAgICogcmVuZGVyaW5nIGFuZCB0b29sIGRlY2lzaW9uIGdvZXMgdGhyb3VnaCB7QGxpbmsgYmFzZVBsb3RUeXBlfSBpbnN0ZWFkLCBzbyBhXG4gICAqIGNvbnRyaWJ1dGVkIG1vZGUgYmVoYXZlcyBleGFjdGx5IGxpa2UgdGhlIGJ1aWx0LWluIHR5cGUgaXQgcmlkZXMgb24uXG4gICAqL1xuICBzZWxlY3RlZFBsb3RUeXBlSWQ6IFBsb3RUeXBlSWQgPSBQbG90VHlwZS5JTUFHRTtcblxuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHBsb3QgdHlwZSBiZWluZyByZW5kZXJlZC4gV2l0aCBubyBjb250cmlidXRlZCBtb2RlIGFjdGl2ZSB0aGlzXG4gICAqIGlzIHRoZSBzZWxlY3Rpb24gaXRzZWxmOyBkdXJpbmcgb25lIGl0IGlzIHRoZSBtb2RlJ3MgYGJhc2VUeXBlYC4gS2VwdCB3aXRoIGl0c1xuICAgKiBvcmlnaW5hbCBgUGxvdFR5cGVgIHR5cGUgZm9yIGV4aXN0aW5nIHJlYWRlcnMg4oCUIHVzZSB7QGxpbmsgc2VsZWN0ZWRQbG90VHlwZUlkfVxuICAgKiBmb3IgdGhlIHNlbGVjdG9yJ3MgaWQuIEFzc2lnbmluZyBzZWxlY3RzIHRoYXQgYnVpbHQtaW4gdHlwZS5cbiAgICovXG4gIGdldCBzZWxlY3RlZFBsb3RUeXBlKCk6IFBsb3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5iYXNlUGxvdFR5cGU7XG4gIH1cbiAgc2V0IHNlbGVjdGVkUGxvdFR5cGUodHlwZTogUGxvdFR5cGUpIHtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IHR5cGU7XG4gIH1cblxuICAvKiogQ29udHJpYnV0ZWQgcGxvdCBtb2RlcyBhbmQgdGhlaXIgc2luZ2xlIGxpdmUgc2Vzc2lvbi4gKi9cbiAgcmVhZG9ubHkgcGxvdE1vZGVzOiBQbG90TW9kZUNvbnRyb2xsZXI7XG4gIC8qKlxuICAgKiBUaGUgbGl2ZSBjb250cmlidXRlZCBtb2RlJ3Mgc2lkZSBwYW5lbCwgYXMgdGhlIHRlbXBsYXRlIHJlbmRlcnMgaXQ6IGFuXG4gICAqIEFuZ3VsYXIgY29tcG9uZW50IHdpdGggaXRzIG93biBpbmplY3Rvciwgb3IgYSBwbGFpbiBob3N0IGVsZW1lbnQgYSBgbW91bnRgXG4gICAqIHBhbmVsIHJlbmRlcmVkIGludG8uIE51bGwgd2hpbGUgbm8gY29udHJpYnV0ZWQgc2Vzc2lvbiBpcyBsaXZlLlxuICAgKi9cbiAgcGxvdE1vZGVQYW5lbDoge1xuICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgY29tcG9uZW50OiBUeXBlPHVua25vd24+IHwgbnVsbDtcbiAgICBpbmplY3RvcjogSW5qZWN0b3IgfCBudWxsO1xuICAgIGhvc3Q6IEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgfSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRlc3Ryb3lpbmcgPSBmYWxzZTtcblxuICAvKiogV2hlcmUgYSBgbW91bnRgIHBhbmVsJ3MgaG9zdCBlbGVtZW50IGlzIGF0dGFjaGVkIG9uY2UgdGhlIGRpYWxvZyByZW5kZXJzLiAqL1xuICBAVmlld0NoaWxkKCdwbG90TW9kZVBhbmVsU2xvdCcpXG4gIHNldCBwbG90TW9kZVBhbmVsU2xvdChyZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgaG9zdCA9IHRoaXMucGxvdE1vZGVQYW5lbD8uaG9zdDtcbiAgICBpZiAocmVmICYmIGhvc3QgJiYgaG9zdC5wYXJlbnRFbGVtZW50ICE9PSByZWYubmF0aXZlRWxlbWVudCkgcmVmLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQoaG9zdCk7XG4gIH1cblxuICAvKiogVGhlIGJ1aWx0LWluIHR5cGUgYWN0dWFsbHkgcmVuZGVyZWQgZm9yIHtAbGluayBzZWxlY3RlZFBsb3RUeXBlSWR9OiBpdHNlbGZcbiAgICogIGZvciBhIGJ1aWx0LWluIHR5cGUsIGBiYXNlVHlwZWAgZm9yIGEgY29udHJpYnV0ZWQgbW9kZS4gKi9cbiAgZ2V0IGJhc2VQbG90VHlwZSgpOiBQbG90VHlwZSB7XG4gICAgcmV0dXJuIHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2YodGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQpO1xuICB9XG5cbiAgLyoqIEZsb2F0aW5nIGludGVuc2l0eS1wcm9maWxlIGluc2V0IChMSU5FIG1vZGUpLiAqL1xuICByZWFkb25seSBpbnRlbnNpdHlJbnNldERpdiA9ICdpbnRlbnNpdHktaW5zZXQtcGxvdCc7XG4gIHByb2ZpbGVQYW5lbFBvcyA9IHsgeDogMjAsIHk6IDcwIH07XG4gIHByaXZhdGUgcHJvZmlsZVBhbmVsRHJhZ2dpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBwcm9maWxlUGFuZWxTdGFydCA9IHsgbXg6IDAsIG15OiAwLCB4OiAwLCB5OiAwIH07XG5cbiAgLyoqIFRvb2xiYXIgZG9ja2luZzogZG9ja2VkIGFjcm9zcyB0aGUgdG9wIGJ5IGRlZmF1bHQ7IGRyYWdnaW5nIGl0cyBoYW5kbGVcbiAgICogIGRldGFjaGVzIGl0IGludG8gYSBmbG9hdGluZywgbW92YWJsZSB3aW5kb3cgKGZyZWVzIHRoZSB0b3Agcm93IGZvciB0aGVcbiAgICogIHZpc3VhbGl6YXRpb24pLiAqL1xuICB0b29sYmFyRmxvYXRpbmcgPSBmYWxzZTtcbiAgdG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICBwcml2YXRlIHRvb2xiYXJEcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIHRvb2xiYXJTdGFydCA9IHsgbXg6IDAsIG15OiAwLCB4OiAwLCB5OiAwIH07XG4gIHByaXZhdGUgbGF0ZXN0UHJvZmlsZXM6IEludGVuc2l0eVByb2ZpbGVbXSA9IFtdO1xuICAvKiogRHJpdmVzIHRoZSBpbnRlbnNpdHkgaW5zZXQgcGFuZWwncyB2aXNpYmlsaXR5IOKAlCB0cnVlIHdoZW5ldmVyIGFueVxuICAgKiAgaW50ZW5zaXR5LXByb2ZpbGUgbGluZSBleGlzdHMgKGluZGVwZW5kZW50IG9mIHRoZSBjdXJyZW50IHBsb3QgdHlwZSkuICovXG4gIGhhc1Byb2ZpbGVzID0gZmFsc2U7XG4gIHByaXZhdGUgaW50ZW5zaXR5UHJvZmlsZVN1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSB2aWV3cG9ydENoYW5nZVN1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBwcm9maWxlRHJhZ01vdmVMaXN0ZW5lcj86IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIHByb2ZpbGVEcmFnVXBMaXN0ZW5lcj86ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgcHJvZmlsZVJlc2l6ZUxpc3RlbmVyPzogKCkgPT4gdm9pZDtcblxuICAvKiogVHJ1ZSB3aGlsZSB0aGUgM0Qgc3BhdGlhbCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIFRoZSBjb250cm9scyBkcm9wIHRoZSBST0lcbiAgICogIHNlbGVjdGlvbiB0aGVyZTogcmVnaW9uIHRvb2xzIGFyZSBzY3JlZW4tc3BhY2UsIGFuZCBhZ2FpbnN0IGFuIG9yYml0aW5nXG4gICAqICBjYW1lcmEgYSBkcmF3biByZWN0YW5nbGUgaGFzIG5vIGZpeGVkIG1lYW5pbmcgaW4gdGhlIGRhdGEuICovXG4gIGdldCBpc1NwYXRpYWwzZE1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzU3BhdGlhbE9taWNzM2QodGhpcy5iYXNlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqIExJTkUgcGxvdCB0eXBlIHNob3dzIHRoZSBpbWFnZSArIGRyYWdnYWJsZSBsaW5lIFJPSSArIGludGVuc2l0eSBpbnNldC4gKi9cbiAgZ2V0IGlzUHJvZmlsZU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZVBsb3RUeXBlID09PSBQbG90VHlwZS5MSU5FO1xuICB9XG5cbiAgLyoqIFRydWUgZm9yIHRoZSBJbWFnZSBwbG90IHR5cGUsIHdoaWNoIHJlbmRlcnMgYXMgYSBuYXRpdmVseSBwYW4vem9vbS1hYmxlXG4gICAqICByYXN0ZXIg4oCUIHNvIHRoZSBiYWNrZW5kLWFnbm9zdGljIHpvb20vcGFuIHRvb2xiYXIgdG9vbHMgYXJlIGhpZGRlbi4gVGhlXG4gICAqICBjb21wb25lbnQgZHJpdmVzIHRoaXMgb2ZmIHRoZSBwbG90IHR5cGUsIG5vdCB0aGUgYWN0aXZlIGJhY2tlbmQuICovXG4gIGdldCBpc0ltYWdlVmlldygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5iYXNlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFO1xuICB9XG5cbiAgLyoqIElzb3N1cmZhY2UgYmFuZCBhcyBhIDDigJMyNTUgc2xpZGVyIHBvc2l0aW9uLCBtYXBwZWQgb250byB0aGUgdm9sdW1lJ3MgcmVhbFxuICAgKiAgaW50ZW5zaXR5IHJhbmdlIGJ5IHRoZSByZW5kZXJlci4gRGVmYXVsdHMgdG8gdGhlIGZ1bGwgcmFuZ2UuICovXG4gIGlzb1JhbmdlOiBudW1iZXJbXSA9IFswLCAyNTVdO1xuXG4gIC8qKiBXaGV0aGVyIGEgc3BhdGlhbC1vbWljcyBkYXRhc2V0IGlzIGN1cnJlbnRseSBwdWJsaXNoZWQgb25cbiAgICogIGBTUEFUSUFMX0RBVEFfUE9SVGAg4oCUIGdhdGVzIHRoZSBzcGF0aWFsIHBsb3QgdHlwZXMgaW4gdGhlIHNlbGVjdG9yLiAqL1xuICBwcml2YXRlIGhhc1NwYXRpYWxEYXRhc2V0ID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoYXQgZGF0YXNldCdzIG9ic2VydmF0aW9ucyBjYXJyeSBhIHosIGdhdGluZyB0aGUgM0Qgc3BhdGlhbCBtb2RlLiAqL1xuICBwcml2YXRlIGhhc1NwYXRpYWwzZERhdGFzZXQgPSBmYWxzZTtcbiAgLyoqIFdoZXRoZXIgaXQgY2FycmllcyBhIHJlZ2lzdGVyZWQgdm9sdW1lLiBDaGFuZ2UgZGV0ZWN0aW9uIG9ubHk6IGEgdm9sdW1lXG4gICAqICBhcHBlYXJpbmcgaXMgd2hhdCBwdWJsaXNoZXMgaXQgYXMgdGhlIGltYWdlLCBhbmQgdGhlIHBsb3QtdHlwZSBnYXRlcyB0aGVuXG4gICAqICBzZWUgYW4gb3JkaW5hcnkgZ3JheXNjYWxlIHN0YWNrLiAqL1xuICBwcml2YXRlIGhhc1NwYXRpYWxWb2x1bWUgPSBmYWxzZTtcbiAgLyoqIERhdGFzZXQgaWRlbnRpdHkgKyBjYXBhYmlsaXR5IHNoYXBlIHRoZSBsYXN0IGVtaXNzaW9uIHdhcyBoYW5kbGVkIGF0LCBzbyBhXG4gICAqICBzd2l0Y2ggYmV0d2VlbiB0d28gZGF0YXNldHMgb2YgdGhlIHNhbWUgc2hhcGUgaXMgbm90IG1pc3Rha2VuIGZvciBhIHJlcGVhdC4gKi9cbiAgcHJpdmF0ZSBzcGF0aWFsRGF0YXNldEtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBEYXRhc2V0ICsgZ2VvbWV0cnkgdGhlIGN1cnJlbnRseSBwdWJsaXNoZWQgdm9sdW1lIGltYWdlIHdhcyBidWlsdCBmcm9tLCBzbyBhXG4gICAqICByZS1lbWl0dGVkIGRhdGFzZXQgZG9lc24ndCByZS1mZXRjaCBtZWdhYnl0ZXMgb3IgcmVzZXQgdGhlIHVzZXIncyBzY3J1Yi4gKi9cbiAgcHJpdmF0ZSB2b2x1bWVJbWFnZUtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBCbG9iIFVSTHMgYmFja2luZyB0aGF0IGltYWdlIOKAlCBvdXJzIHRvIHJldm9rZS4gKi9cbiAgcHJpdmF0ZSB2b2x1bWVJbWFnZVVybHM6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgc3BhdGlhbERhdGFzZXRTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgcGxvdFdpZHRoU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBpbWFnZUxvYWRpbmdTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gIGltZ0xvYWRpbmdNZXNzYWdlU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBpc1pvb21TdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG4gIGZpbGVuYW1lU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBhdXRvc2NhbGVTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgcHJpdmF0ZSBwbG90Q29udGV4dE1lbnVMaXN0ZW5lcj86IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIGtleWRvd25MaXN0ZW5lcj86IChlOiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIHdoZWVsTGlzdGVuZXI/OiAoZTogV2hlZWxFdmVudCkgPT4gdm9pZDtcblxuICAvKiogRGVib3VuY2VkIHotc2xpY2Ugc2NydWJiaW5nIChzZWUgU2xpY2VTY3J1YmJlciDigJQgcmVmYWN0b3JpbmcgcGxhbiBTdGVwIDcpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNjcnViYmVyID0gbmV3IFNsaWNlU2NydWJiZXIoKHopID0+IHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpJbmRleCh6KTtcbiAgICAvLyBJbiBhIHBlci1zbGljZSB6LXN0YWNrIHNlc3Npb24gdGhlIHN0b3JlIHN3YXBzIHRoZSBsaXZlIHJlZ2lvbiBzZXQgdG8gdGhpc1xuICAgIC8vIHNsaWNlIChwcmVzZXJ2aW5nIGVkaXRzIG1hZGUgb24gdGhlIHByZXZpb3VzIG9uZSk7IG91dHNpZGUgc3RhY2sgbW9kZSB0aGlzXG4gICAgLy8ganVzdCByZWNvcmRzIHRoZSBzbGljZSwgbGVhdmluZyBzaW5nbGUtcGxhbmUgcmVnaW9ucyB1bnRvdWNoZWQgKGppdC11aSM5MykuXG4gICAgdGhpcy5wbG90U2VydmljZS5zZXREaXNwbGF5U2xpY2Uoeik7XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoSU1BR0VfU1RBVEVfUE9SVCkgcHJpdmF0ZSBzdGF0ZTogSW1hZ2VTdGF0ZVBvcnQsXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwdWJsaWMgcGxvdFNlcnZpY2U6IElWaXN1YWxpemVyLFxuICAgIHB1YmxpYyBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBzZXNzaW9uOiBWaXN1YWxpemVyU3RvcmUsXG4gICAgcHJpdmF0ZSBzYW1Ub29sOiBTYW1Ub29sU2VydmljZSxcbiAgICBwcml2YXRlIGNlbGxTZWdtZW50VG9vbDogQ2VsbFNlZ21lbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHNhbVBvaW50VG9vbDogU2FtUG9pbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHJlZ2lvbk9wczogUmVnaW9uT3BzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFZJWl9DT05GSUcpIHByaXZhdGUgdml6Q29uZmlnPzogVml6Q29uZmlnLFxuICAgIC8vIEEgY29uc3RydWN0b3IgcGFyYW1ldGVyIHJhdGhlciB0aGFuIGEgZmllbGQgYGluamVjdCgpYDogdGhpcyBjb21wb25lbnQgaXNcbiAgICAvLyBhbHNvIGNvbnN0cnVjdGVkIGRpcmVjdGx5IHdpdGggYG5ld2AgaW4gaXRzIG93biBzcGVjcywgd2hpY2ggaXMgb3V0c2lkZVxuICAgIC8vIGFuIGluamVjdGlvbiBjb250ZXh0IGFuZCB3b3VsZCB0aHJvdyBORzAyMDMgb24gYSBmaWVsZCBpbml0aWFsaXplci5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRPT0xCQVJfVE9PTFMpIHRvb2xDb250cmlidXRpb25zPzogcmVhZG9ubHkgVG9vbGJhckNvbnRyaWJ1dGlvbltdLFxuICAgIC8vIE9wdGlvbmFsIGxpa2UgdGhlIHJlc3Q6IGEgaG9zdCB0aGF0IHNob3dzIG9ubHkgaW1hZ2VzIG5ldmVyIHByb3ZpZGVzIGl0LFxuICAgIC8vIGFuZCB0aGUgc3BhdGlhbCBwbG90IHR5cGVzIHNpbXBseSBzdGF5IGhpZGRlbi5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNQQVRJQUxfREFUQV9QT1JUKSBwcml2YXRlIHNwYXRpYWxEYXRhPzogU3BhdGlhbERhdGFQb3J0LFxuICAgIC8vIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMuIExpa2UgVE9PTEJBUl9UT09MUyB0aGUgdG9rZW4gaGFzIG5vIGZhY3RvcnksIHNvIGFcbiAgICAvLyBob3N0IHRoYXQgcHJvdmlkZXMgbm9uZSBnZXRzIG51bGwgaGVyZSBhbmQgdGhlIHNlbGVjdG9yIGlzIHVuY2hhbmdlZC5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFBMT1RfVFlQRV9DT05UUklCVVRJT05TKSBwbG90VHlwZUNvbnRyaWJ1dGlvbnM/OiByZWFkb25seSBQbG90VHlwZUNvbnRyaWJ1dGlvbltdLFxuICAgIC8vIFBhcmVudCBvZiBhIGNvbnRyaWJ1dGVkIHBhbmVsIGNvbXBvbmVudCdzIGluamVjdG9yLiBPcHRpb25hbCBvbmx5IHNvIHRoZVxuICAgIC8vIHNwZWNzIGNhbiBjb25zdHJ1Y3QgdGhpcyBjb21wb25lbnQgd2l0aCBgbmV3YC5cbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGluamVjdG9yPzogSW5qZWN0b3IsXG4gICkge1xuICAgIHRoaXMucGxvdE1vZGVzID0gbmV3IFBsb3RNb2RlQ29udHJvbGxlcihwbG90VHlwZUNvbnRyaWJ1dGlvbnMsIHtcbiAgICAgIG9uQWN0aXZhdGVkOiAoYWN0aXZlKSA9PiB0aGlzLnNob3dQbG90TW9kZVBhbmVsKGFjdGl2ZSksXG4gICAgICBvbkRlYWN0aXZhdGluZzogKCkgPT4gdGhpcy5oaWRlUGxvdE1vZGVQYW5lbCgpLFxuICAgICAgb25GYWlsZWQ6IChjb250cmlidXRpb24pID0+IHRoaXMuZmFsbEJhY2tGcm9tUGxvdE1vZGUoY29udHJpYnV0aW9uKSxcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMgPSB2aXNpYmxlVG9vbENvbnRyaWJ1dGlvbnModG9vbENvbnRyaWJ1dGlvbnMpO1xuICAgIHRoaXMuZGlhbG9nVG9vbHMgPSBkaWFsb2dUb29sQ29udHJpYnV0aW9ucyh0b29sQ29udHJpYnV0aW9ucyk7XG4gICAgLy8gQSBkaWFsb2cgdG9vbCdzIHNlc3Npb24gaXMgcnVuIGJ5IHRoZSBwbG90LW1vZGUgbGlmZWN5Y2xlLCBhZGFwdGVkOiBpdHMgXCJiYXNlXG4gICAgLy8gdHlwZVwiIGlzIHRoZSBJbWFnZSB2aWV3IGl0IGRyYXdzIG92ZXIuIEl0cyBib2R5IGlzIE5PVCBhIGNvbnRyb2xsZXIgcGFuZWw6IHRoZVxuICAgIC8vIGNvbnRyb2xsZXIgd291bGQgbW91bnQgaW50byBhIGRldGFjaGVkIGhvc3QsIGFuZCBhIGJvZHkgbXVzdCBiZSBhYmxlIHRvIG1lYXN1cmVcbiAgICAvLyBpdHNlbGYuIFRoZSBkaWFsb2cgaXMgcmVuZGVyZWQgZmlyc3QgYW5kIHRoZSBib2R5IG1vdW50ZWQgb25jZSBpdHMgaG9zdCBpcyBpbiB0aGVcbiAgICAvLyBkb2N1bWVudCAoc2hvd1Rvb2xEaWFsb2cpLlxuICAgIHRoaXMudG9vbERpYWxvZ3MgPSBuZXcgUGxvdE1vZGVDb250cm9sbGVyKFxuICAgICAgdGhpcy5kaWFsb2dUb29scy5tYXAoKHQpOiBQbG90VHlwZUNvbnRyaWJ1dGlvbiA9PiAoe1xuICAgICAgICBkZXNjcmlwdG9yOiB7IHR5cGU6IHQuaWQsIGxhYmVsOiB0LmxhYmVsLCBkaW1lbnNpb25zOiAnMmQnLCBiYXNlVHlwZTogUGxvdFR5cGUuSU1BR0UgfSxcbiAgICAgICAgYWN0aXZhdGU6IChjdHgpID0+IHQuYWN0aXZhdGUoY3R4IGFzIFRvb2xEaWFsb2dDb250ZXh0KSxcbiAgICAgIH0pKSxcbiAgICAgIHtcbiAgICAgICAgb25BY3RpdmF0ZWQ6IChhY3RpdmUpID0+IHRoaXMuc2hvd1Rvb2xEaWFsb2coYWN0aXZlKSxcbiAgICAgICAgb25EZWFjdGl2YXRpbmc6ICgpID0+IHRoaXMuaGlkZVRvb2xEaWFsb2coKSxcbiAgICAgICAgb25GYWlsZWQ6IChjb250cmlidXRpb24pID0+IHRoaXMuZGlhbG9nVG9vbEZhaWxlZChjb250cmlidXRpb24uZGVzY3JpcHRvci50eXBlKSxcbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLmNvbG9ybWFwc09wdGlvbnMgPSBwbG90U2VydmljZS5nZXRDb2xvcm1hcE9wdGlvbnMoKTtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQbG90IHR5cGVzIG9mZmVyZWQgaW4gdGhlIHNlbGVjdG9yIGZvciB0aGUgY3VycmVudCBpbWFnZTpcbiAgICogIC0gT3V0c2lkZSAqKnRlc3QgbW9kZSoqLCBvbmx5IHRoZSBjdXJhdGVkIGRlZmF1bHQgc2V0IChkZXNjcmlwdG9ycyB3aXRoIGFcbiAgICogICAgYHByb2R1Y3Rpb25MYWJlbGApIGlzIG9mZmVyZWQsIHNob3duIHVuZGVyIHN1ZmZpeC1mcmVlIG5hbWVzIOKAlCBJbWFnZSxcbiAgICogICAgSGVhdG1hcCwgQ29udG91ciBhbmQgdGhlIG5hcGFyaSBTdXJmYWNlIC8gVm9sdW1lIC8gSXNvc3VyZmFjZS4gVGVzdCBtb2RlXG4gICAqICAgIGV4cG9zZXMgZXZlcnkgYmFja2VuZCdzIHR5cGUgdW5kZXIgaXRzIGZ1bGwgKGJhY2tlbmQtc3VmZml4ZWQpIGxhYmVsLlxuICAgKiAgLSAzRCB0eXBlcyBoaWRkZW4gd2hlbiB0aGUgYmFja2VuZCBjYW4ndCByZW5kZXIgYSAzRCBzY2VuZS5cbiAgICogIC0gc3RhY2stb25seSB0eXBlcyAodm9sdW1lLCBpc29zdXJmYWNlKSBoaWRkZW4gdW5sZXNzIHRoZSBmaWxlIGlzIGEgc3RhY2sg4oCUXG4gICAqICAgIGEgdm9sdW1lIG5lZWRzIG11bHRpcGxlIHotc2xpY2VzLlxuICAgKiAgLSBzY2FsYXItaW50ZW5zaXR5IHR5cGVzIChjb250b3VyLCBzdXJmYWNlLCBpc29zdXJmYWNlKSBoaWRkZW4gZm9yIFJHQlxuICAgKiAgICBpbWFnZXMg4oCUIHRoZXkgbWFwIGEgc2luZ2xlIGludGVuc2l0eSBwZXIgcGl4ZWwuIEltYWdlIGFuZCBIZWF0bWFwIHJlbmRlclxuICAgKiAgICBhbnkgaW1hZ2UuXG4gICAqICAtIHNwYXRpYWwtb21pY3MgdHlwZXMgaGlkZGVuIHVudGlsIGEgYFNwYXRpYWxEYXRhc2V0YCBpcyBwdWJsaXNoZWQgb25cbiAgICogICAgYFNQQVRJQUxfREFUQV9QT1JUYCDigJQgdGhlIG1vZGUgaGFzIG5vdGhpbmcgdG8gZHJhdyB3aXRob3V0IG9ic2VydmF0aW9ucyxcbiAgICogICAgZXhhY3RseSBhcyBhIHZvbHVtZSBoYXMgbm90aGluZyB0byBkcmF3IHdpdGhvdXQgYSBzdGFjay5cbiAgICovXG4gIC8qKlxuICAgKiBUcmFjayB3aGV0aGVyIGEgc3BhdGlhbC1vbWljcyBkYXRhc2V0IGlzIGF2YWlsYWJsZS4gQSBkYXRhc2V0IGFwcGVhcmluZyAob3JcbiAgICogYmVpbmcgY2xlYXJlZCkgY2hhbmdlcyB3aGljaCBwbG90IHR5cGVzIG1ha2Ugc2Vuc2UsIHNvIGl0IGRyaXZlcyB0aGUgc2FtZVxuICAgKiByZWNvbXB1dGUgKyByZWNvbmNpbGUgdGhhdCB0aGUgaW1hZ2Ugc3RyZWFtIGFuZCB0aGUgdGVzdC1tb2RlIHRvZ2dsZSBkby5cbiAgICpcbiAgICogTm8tb3Agd2hlbiB0aGUgaG9zdCBwcm92aWRlcyBubyBgU1BBVElBTF9EQVRBX1BPUlRgIOKAlCB0aGUgc3BhdGlhbCB0eXBlcyB0aGVuXG4gICAqIHN0YXkgaGlkZGVuIGZvciB0aGUgbGlmZSBvZiB0aGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJpdmF0ZSB3YXRjaFNwYXRpYWxEYXRhc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuc3BhdGlhbERhdGFzZXRTdWJzY3JpcHRpb24gPSB0aGlzLnNwYXRpYWxEYXRhPy5nZXREYXRhc2V0JCgpLnN1YnNjcmliZSgoZGF0YXNldCkgPT4ge1xuICAgICAgY29uc3QgaGFzID0gISFkYXRhc2V0O1xuICAgICAgLy8gT25seSBhIGRhdGFzZXQgd2hvc2Ugb2JzZXJ2YXRpb25zIGNhcnJ5IGEgeiBjYW4gYmUgZHJhd24gYXMgYSBjbG91ZCwgc29cbiAgICAgIC8vIHRoZSAzRCBtb2RlIGlzIGdhdGVkIG9uIHRoZSBjb29yZGluYXRlcywgbm90IG1lcmVseSBvbiBhIGRhdGFzZXQgYmVpbmdcbiAgICAgIC8vIHByZXNlbnQuIE1vc3Qgc3BhdGlhbCBhc3NheXMgYXJlIG9uZSBwbGFuZS5cbiAgICAgIGNvbnN0IGhhczNkID0gISFkYXRhc2V0Py5vYnNlcnZhdGlvbnMuejtcbiAgICAgIGNvbnN0IGhhc1ZvbHVtZSA9ICEhZGF0YXNldD8udm9sdW1lO1xuICAgICAgLy8gVGhlIHBvcnQgcHVibGlzaGVzIGl0cyBjdXJyZW50IHZhbHVlIG9uIHN1YnNjcmliZSwgc28gdGhlIGluaXRpYWwgYG51bGxgXG4gICAgICAvLyB3b3VsZCBvdGhlcndpc2UgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBmb3Igbm8gY2hhbmdlLiBLZXllZCBieSBkYXRhc2V0XG4gICAgICAvLyBJREVOVElUWSBhcyB3ZWxsIGFzIGNhcGFiaWxpdHkgc2hhcGU6IHR3byAzRCBkYXRhc2V0cyB0aGF0IGJvdGggY2FycnkgYVxuICAgICAgLy8gdm9sdW1lIGhhdmUgdGhlIHNhbWUgc2hhcGUsIGFuZCBjb21wYXJpbmcgb25seSB0aGF0IHNraXBwZWQgdGhlIHN3aXRjaCDigJRcbiAgICAgIC8vIGxlYXZpbmcgdGhlIHByZXZpb3VzIGRhdGFzZXQncyB2b2x1bWUgaW1hZ2Ugb24gc2NyZWVuIHVuZGVybmVhdGggdGhlIG5ld1xuICAgICAgLy8gb25lJ3Mgb2JzZXJ2YXRpb25zLlxuICAgICAgY29uc3Qga2V5ID0gZGF0YXNldFxuICAgICAgICA/IGAke2RhdGFzZXQuaWR9fCR7aGFzM2R9fCR7aGFzVm9sdW1lfXwke2RhdGFzZXQudm9sdW1lXG4gICAgICAgICAgPyBgJHtkYXRhc2V0LnZvbHVtZS53aWR0aH14JHtkYXRhc2V0LnZvbHVtZS5oZWlnaHR9eCR7ZGF0YXNldC52b2x1bWUuZGVwdGh9YCA6ICcnfWBcbiAgICAgICAgOiBudWxsO1xuICAgICAgaWYgKGtleSA9PT0gdGhpcy5zcGF0aWFsRGF0YXNldEtleSkgcmV0dXJuO1xuICAgICAgdGhpcy5zcGF0aWFsRGF0YXNldEtleSA9IGtleTtcbiAgICAgIHRoaXMuaGFzU3BhdGlhbERhdGFzZXQgPSBoYXM7XG4gICAgICB0aGlzLmhhc1NwYXRpYWwzZERhdGFzZXQgPSBoYXMzZDtcbiAgICAgIC8vIFdoZXRoZXIgdGhlIGRhdGFzZXQgc2F5cyBpdCByZWdpc3RlcnMgb250byBhIHRpc3N1ZSBpbWFnZS4gRGlzdGluY3QgZnJvbSBhblxuICAgICAgLy8gaW1hZ2UgYmVpbmcgTE9BREVEOiBhIHJlZ2lzdGVyZWQgZGF0YXNldCdzIGltYWdlIG1heSBzdGlsbCBiZSBvbiBpdHMgd2F5LCBhbmRcbiAgICAgIC8vIHRoZSBwaXhlbCBtb2RlcyBtdXN0IG5vdCBmbGlja2VyIG91dCBvZiB0aGUgc2VsZWN0b3Igd2hpbGUgaXQgYXJyaXZlcy5cbiAgICAgIC8vIEEgcmVnaXN0ZXJlZCBkYXRhc2V0IGRyYXdzIG92ZXIgYSB0aXNzdWUgaW1hZ2U7IGEgdm9sdW1lLWJhY2tlZCBvbmUgcHVibGlzaGVzIGl0c1xuICAgICAgLy8gdm9sdW1lIEFTIGEgZ3JheXNjYWxlIHotc3RhY2sgaW1hZ2UgKGBidWlsZFZvbHVtZVN0YWNrSW1hZ2VgKS4gRWl0aGVyIHdheSBwaXhlbHNcbiAgICAgIC8vIGV4aXN0LCBzbyB0aGUgcGl4ZWwgbW9kZXMgc3RheSBvbiBvZmZlciDigJQgVm9sdW1lIGFuZCBJc29zdXJmYWNlIGFyZSBleGFjdGx5IGhvd1xuICAgICAgLy8gYSAzRCBvbWljcyBkYXRhc2V0IGlzIHJlYWQuXG4gICAgICB0aGlzLnNwYXRpYWxEYXRhc2V0SGFzUGl4ZWxzID0gISFkYXRhc2V0Py5pbWFnZVJlZiB8fCBoYXNWb2x1bWU7XG4gICAgICB0aGlzLmhhc1NwYXRpYWxWb2x1bWUgPSBoYXNWb2x1bWU7XG4gICAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAgIC8vIEEgZGF0YXNldCB3aXRoIG5vIHJlZmVyZW5jZSBpbWFnZSBoYXMgbm90aGluZyB0byBkcmF3IG9ic2VydmF0aW9ucyBPVkVSOlxuICAgICAgLy8gYSBjbG91ZCByZWdpc3RlcmVkIGludG8gYSBjb21tb24gZnJhbWUgKHRoZSBBbGxlbiBDQ0YpIGhhcyBjb29yZGluYXRlc1xuICAgICAgLy8gYnV0IG5vIG9uZSBzZWN0aW9uLiBXaGF0IGl0IGRvZXMgaGF2ZSBpcyBpdHMgcmVnaXN0ZXJlZCBWT0xVTUUsIHdoaWNoIGlzXG4gICAgICAvLyBhIDNEIGltYWdlIGluIG9uZSBmaWxlIOKAlCBzbyBtYWtlIHRoYXQgdGhlIGltYWdlIGFuZCBvcGVuIG9uIGl0LCBzbGljZSBiYXJcbiAgICAgIC8vIGFuZCBhbGwsIHJhdGhlciB0aGFuIGxlYXZpbmcgdGhlIGhvc3Qgb24gYW4gSW1hZ2UgdmlldyBzaG93aW5nIHdoYXRldmVyXG4gICAgICAvLyBzbGlkZSB3YXMgbG9hZGVkIGJlZm9yZS4gT3JkZXJlZCBhZnRlciBjb21wdXRlUGxvdFR5cGVPcHRpb25zIHNvIHRoZSB0eXBlXG4gICAgICAvLyBpcyBvbiBvZmZlciBiZWZvcmUgaXQgaXMgc2VsZWN0ZWQuXG4gICAgICBpZiAoZGF0YXNldCAmJiAhZGF0YXNldC5pbWFnZVJlZiAmJiBoYXNWb2x1bWUpIHtcbiAgICAgICAgdm9pZCB0aGlzLnNob3dWb2x1bWVBc0ltYWdlKGRhdGFzZXQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQW55dGhpbmcgZWxzZSDigJQgYSBkYXRhc2V0IHdpdGggaXRzIG93biBzZWN0aW9uIGltYWdlLCBhIHZvbHVtZS1sZXNzXG4gICAgICAgIC8vIGNsb3VkLCBvciBub25lIGF0IGFsbCDigJQgbWVhbnMgYSBwdWJsaXNoZWQgdm9sdW1lIGltYWdlIGlzIG5vIGxvbmdlciB3aGF0XG4gICAgICAgIC8vIGlzIG9uIHNjcmVlbi4gRm9yZ2V0IGl0LCBvciBjb21pbmcgQkFDSyB0byB0aGUgdm9sdW1lIGRhdGFzZXQgd291bGRcbiAgICAgICAgLy8gc2hvcnQtY2lyY3VpdCBvbiBhIG1hdGNoaW5nIGtleSBhbmQgbGVhdmUgdGhlIG90aGVyIGRhdGFzZXQncyBzbGlkZSB1cC5cbiAgICAgICAgdGhpcy5kcm9wVm9sdW1lSW1hZ2UoKTtcbiAgICAgICAgaWYgKGRhdGFzZXQgJiYgIWRhdGFzZXQuaW1hZ2VSZWYpIHtcbiAgICAgICAgICAvLyBObyByZWZlcmVuY2UgaW1hZ2UgYW5kIG5vIHZvbHVtZSB0byBzbGljZTogdGhlIG9ic2VydmF0aW9ucyBhcmUgdGhlIG9ubHlcbiAgICAgICAgICAvLyB0aGluZyB0aGVyZSBpcyB0byBkcmF3LCBzbyBvcGVuIG9uIHdoaWNoZXZlciBzcGF0aWFsIG1vZGUgdGhlaXJcbiAgICAgICAgICAvLyBjb29yZGluYXRlcyBzdXBwb3J0LiBMZWF2aW5nIHRoZSB0eXBlIGFsb25lIHN0cmFuZHMgdGhlIGhvc3Qgb24gYW4gSW1hZ2VcbiAgICAgICAgICAvLyB2aWV3IHNob3dpbmcgd2hhdGV2ZXIgc2xpZGUgd2FzIGxvYWRlZCBCRUZPUkUg4oCUIHRoZSBvYnNlcnZhdGlvbnMgbmV2ZXJcbiAgICAgICAgICAvLyBhcHBlYXIsIGFuZCB0aGUgcHJldmlvdXMgZGF0YXNldCdzIHRpc3N1ZSBkb2VzLCB3aGljaCByZWFkcyBhcyB0aGlzXG4gICAgICAgICAgLy8gZGF0YXNldCBmYWlsaW5nIHRvIGxvYWQuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBHYXRlZCBvbiB0aGUgY29vcmRpbmF0ZXMsIG5vdCBvbiB0aGUgZGF0YXNldCBtZXJlbHkgZXhpc3Rpbmc6IGFcbiAgICAgICAgICAvLyBvbmUtcGxhbmUgYXNzYXkgaGFzIG5vIHogYW5kIGNhbm5vdCBiZSBhIGNsb3VkLiBUaGF0IGNhc2Ugb25seSB0dXJuZWQgdXBcbiAgICAgICAgICAvLyB3aXRoIGFuIGltYWdlLWxlc3MgMkQgZGF0YXNldCwgd2hpY2ggaXMgd2h5IGl0IHdlbnQgdW5oYW5kbGVkIOKAlCBiZWZvcmVcbiAgICAgICAgICAvLyBpdCwgaW1hZ2UtbGVzcyBtZWFudCAzRC5cbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBoYXMzZCA/IFBsb3RUeXBlLlNQQVRJQUxfT01JQ1NfM0QgOiBQbG90VHlwZS5TUEFUSUFMX09NSUNTO1xuICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCAhPT0gdGFyZ2V0KSB0aGlzLm9uU2VsZWN0UGxvdFR5cGUodGFyZ2V0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQ2xlYXJpbmcgdGhlIGRhdGFzZXQgd2hpbGUgYSBzcGF0aWFsIG1vZGUgaXMgYWN0aXZlIGxlYXZlcyBhIHR5cGUgdGhhdCBpc1xuICAgICAgLy8gbm8gbG9uZ2VyIG9mZmVyZWQg4oCUIGZhbGwgYmFjayB0byBJbWFnZSwgYXMgdHVybmluZyB0ZXN0IG1vZGUgb2ZmIGRvZXMuXG4gICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIGEgZGF0YXNldCdzIHJlZmVyZW5jZSB2b2x1bWUgQVMgdGhlIGltYWdlLCBhbmQgb3BlbiB0aGUgMkQgSW1hZ2Ugdmlld1xuICAgKiBvbiBpdC5cbiAgICpcbiAgICogVGhlIHZvbHVtZSBpcyBhIDNEIGltYWdlIGRlbGl2ZXJlZCBpbiBvbmUgZmlsZSwgc28gZm9yIGEgZGF0YXNldCB0aGF0IGhhcyBub1xuICAgKiBzZWN0aW9uIGltYWdlIGl0IGlzIHRoZSBob25lc3QgdGhpbmcgdG8gcHV0IG9uIHNjcmVlbjogdGhlIHNsaWNlIGJhciBzY3J1YnMgeixcbiAgICogYW5kIHRoZSBjb250cmFzdCB3aW5kb3csIGNvbG9ybWFwcyBhbmQgcmVnaW9uIHRvb2xzIGFsbCB3b3JrIGJlY2F1c2UgdGhlXG4gICAqIHZvbHVtZSBnZW51aW5lbHkgaXMgdGhlIGltYWdlIG5vdy4gVGhlIDNEIGNsb3VkIHN0YXlzIG9uZSBtZW51IHBpY2sgYXdheS5cbiAgICpcbiAgICogS2V5ZWQgYnkgZGF0YXNldCArIGdlb21ldHJ5OiB0aGUgZGF0YXNldCBzdHJlYW0gcmUtZW1pdHMgb24gdGhpbmdzIGxpa2UgYVxuICAgKiBjb2xvdXItY29sdW1uIGNoYW5nZSwgYW5kIHJlYnVpbGRpbmcgdGhlbiB3b3VsZCByZS1mZXRjaCB0aGUgdm94ZWxzIGFuZCB0aHJvd1xuICAgKiB0aGUgdXNlciBiYWNrIHRvIHRoZSBtaWRkbGUgc2xpY2UuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNob3dWb2x1bWVBc0ltYWdlKGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbWV0YSA9IGRhdGFzZXQudm9sdW1lO1xuICAgIGlmICghbWV0YSB8fCAhdGhpcy5zcGF0aWFsRGF0YT8uZ2V0Vm9sdW1lKSByZXR1cm47XG4gICAgY29uc3Qga2V5ID0gYCR7ZGF0YXNldC5pZH06JHttZXRhLndpZHRofXgke21ldGEuaGVpZ2h0fXgke21ldGEuZGVwdGh9YDtcbiAgICBpZiAoa2V5ID09PSB0aGlzLnZvbHVtZUltYWdlS2V5KSByZXR1cm47XG4gICAgLy8gQ2xhaW0gdGhlIGtleSBCRUZPUkUgYXdhaXRpbmc6IHRoZSBzdHJlYW0gY2FuIGVtaXQgYWdhaW4gd2hpbGUgdGhlIHZveGVsc1xuICAgIC8vIGFyZSBpbiBmbGlnaHQsIGFuZCB0d28gYnVpbGRzIG9mIHRoZSBzYW1lIHZvbHVtZSB3b3VsZCByYWNlIHRvIHB1Ymxpc2guXG4gICAgdGhpcy52b2x1bWVJbWFnZUtleSA9IGtleTtcbiAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyh0cnVlKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYnVpbHQgPSBhd2FpdCBidWlsZFZvbHVtZVN0YWNrSW1hZ2UoZGF0YXNldCwgYXdhaXQgdGhpcy5zcGF0aWFsRGF0YS5nZXRWb2x1bWUoKSk7XG4gICAgICAvLyBBIGRpZmZlcmVudCBkYXRhc2V0IHdhcyBzZWxlY3RlZCB3aGlsZSB0aGlzIG9uZSBlbmNvZGVkIOKAlCBpdHMgaW1hZ2UgaXMgdGhlXG4gICAgICAvLyBvbmUgdGhhdCBiZWxvbmdzIG9uIHNjcmVlbiwgc28gZHJvcCB3aGF0IHdlIGp1c3QgYnVpbHQuXG4gICAgICBpZiAodGhpcy52b2x1bWVJbWFnZUtleSAhPT0ga2V5KSB7XG4gICAgICAgIGJ1aWx0Py51cmxzLmZvckVhY2goKHUpID0+IFVSTC5yZXZva2VPYmplY3RVUkwodSkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWJ1aWx0KSB7XG4gICAgICAgIHRoaXMudm9sdW1lSW1hZ2VLZXkgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBQaWNrIHRoZSBtb2RlIGZpcnN0IHNvIHRoZSBpbWFnZSBsYW5kcyBpbiB0aGUgdmlldyB0aGF0IHdpbGwgc2hvdyBpdCxcbiAgICAgIC8vIGluc3RlYWQgb2YgcmVuZGVyaW5nIG9uY2UgaW50byB3aGF0ZXZlciBtb2RlIHRoZSBsYXN0IGRhdGFzZXQgbGVmdCBhY3RpdmUuXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgIT09IFBsb3RUeXBlLklNQUdFKSB0aGlzLm9uU2VsZWN0UGxvdFR5cGUoUGxvdFR5cGUuSU1BR0UpO1xuICAgICAgdGhpcy5yZXZva2VWb2x1bWVJbWFnZVVybHMoKTtcbiAgICAgIHRoaXMudm9sdW1lSW1hZ2VVcmxzID0gYnVpbHQudXJscztcbiAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VJbmZvKGJ1aWx0LmluZm8pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gTm8gdm9sdW1lIHNlcnZlZCBhZnRlciBhbGw6IHRoZSBjbG91ZCBpcyBzdGlsbCByZW5kZXJhYmxlLCBzbyBmYWxsIGJhY2sgdG9cbiAgICAgIC8vIGl0IHJhdGhlciB0aGFuIGxlYXZpbmcgdGhlIGhvc3Qgb24gYW4gSW1hZ2UgdmlldyB3aXRoIG5vdGhpbmcgaW4gaXQuXG4gICAgICBjb25zb2xlLndhcm4oJ1t2aXN1YWxpemVyXSByZWZlcmVuY2Ugdm9sdW1lIHVuYXZhaWxhYmxlIOKAlCBmYWxsaW5nIGJhY2sgdG8gdGhlIDNEIGNsb3VkJywgZXJyKTtcbiAgICAgIHRoaXMudm9sdW1lSW1hZ2VLZXkgPSBudWxsO1xuICAgICAgaWYgKHRoaXMuaGFzU3BhdGlhbDNkRGF0YXNldCAmJiAhaXNTcGF0aWFsT21pY3MzZCh0aGlzLmJhc2VQbG90VHlwZSkpIHtcbiAgICAgICAgdGhpcy5vblNlbGVjdFBsb3RUeXBlKFBsb3RUeXBlLlNQQVRJQUxfT01JQ1NfM0QpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhmYWxzZSk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEZvcmdldCB0aGUgcHVibGlzaGVkIHZvbHVtZSBpbWFnZSBzbyByZS1zZWxlY3RpbmcgdGhlIGRhdGFzZXQgcmVidWlsZHMgaXQuXG4gICAqICBUaGUgVVJMcyBkZWxpYmVyYXRlbHkgc3RheSBhbGl2ZTogdGhlIGhvc3QgbWF5IHN0aWxsIGJlIGRpc3BsYXlpbmcgdGhhdCBpbWFnZVxuICAgKiAgYXQgdGhpcyBpbnN0YW50LCBhbmQgcmV2b2tpbmcgdW5kZXIgaXQgd291bGQgYnJlYWsgZXZlcnkgbGF0ZXIgdGlsZSByZWFkLiBUaGV5XG4gICAqICBhcmUgZnJlZWQgd2hlbiB0aGUgbmV4dCB2b2x1bWUgcmVwbGFjZXMgdGhlbSwgb3Igb24gZGVzdHJveS4gKi9cbiAgcHJpdmF0ZSBkcm9wVm9sdW1lSW1hZ2UoKTogdm9pZCB7XG4gICAgdGhpcy52b2x1bWVJbWFnZUtleSA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIHJldm9rZVZvbHVtZUltYWdlVXJscygpOiB2b2lkIHtcbiAgICB0aGlzLnZvbHVtZUltYWdlVXJscy5mb3JFYWNoKCh1KSA9PiBVUkwucmV2b2tlT2JqZWN0VVJMKHUpKTtcbiAgICB0aGlzLnZvbHVtZUltYWdlVXJscyA9IFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlUGxvdFR5cGVPcHRpb25zKCkge1xuICAgIGNvbnN0IGNhcHMgPSB0aGlzLnBsb3RTZXJ2aWNlLmNhcGFiaWxpdGllcztcbiAgICBjb25zdCBpc1N0YWNrID0gISF0aGlzLmltYWdlSW5mbz8uaXNTdGFjaztcbiAgICBjb25zdCBpc0dyYXlzY2FsZSA9ICEhdGhpcy5pbWFnZUluZm8/LmlzR3JheXNjYWxlO1xuICAgIC8vIEEgbXVsdGljaGFubmVsIGltYWdlJ3MgYmFuZHMgYXJlIGVhY2ggc2luZ2xlLWJhbmQgKHNjYWxhciksIHNvIHRoZSBzY2FsYXJcbiAgICAvLyBwbG90IG1vZGVzIChIZWF0bWFwIC8gU3VyZmFjZSAvIFZvbHVtZSAvIElzb3N1cmZhY2UpIGFwcGx5IHBlciBjaGFubmVsIGV2ZW5cbiAgICAvLyB0aG91Z2ggdGhlIFJHQiBjb21wb3NpdGUgaXNuJ3QgZ3JheXNjYWxlIOKAlCBkb24ndCBnYXRlIHRoZW0gb3V0LlxuICAgIGNvbnN0IG0wID0gdGhpcy5pbWFnZUluZm8/LmltYWdlTWV0YT8uWzBdO1xuICAgIGNvbnN0IGlzTXVsdGljaGFubmVsID0gKG0wPy5jaGFubmVsQ291bnQgPz8gMSkgPiAxICYmIChtMD8ucmdiQ2hhbm5lbHMgPz8gMSkgPCAzO1xuICAgIGNvbnN0IHBhc3Nlc0dhdGVzID0gKGQ6IFBsb3RUeXBlRGVzY3JpcHRvcik6IGJvb2xlYW4gPT4ge1xuICAgICAgaWYgKGQuZGltZW5zaW9ucyA9PT0gJzNkJyAmJiAhY2Fwcy5oYXMoVmlld2VyRmVhdHVyZS5TdXJmYWNlM0QpKSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyBWb2x1bWUgYW5kIElzb3N1cmZhY2UgcmF5bWFyY2ggdGhlIElNQUdFIFNUQUNLLCBhbmQgbm90aGluZyBlbHNlOiB0aGVzZVxuICAgICAgLy8gdHdvIGdhdGVzIGFyZSBhYm91dCB0aGUgbG9hZGVkIGltYWdlLCBmdWxsIHN0b3AuIEEgM0Qgb21pY3MgZGF0YXNldFxuICAgICAgLy8gcmVhY2hlcyB0aGVtIGJlY2F1c2UgaXRzIHJlZ2lzdGVyZWQgdm9sdW1lIGlzIHB1Ymxpc2hlZCBBUyBhIGdyYXlzY2FsZVxuICAgICAgLy8gei1zdGFjayBpbWFnZSAoYGJ1aWxkVm9sdW1lU3RhY2tJbWFnZWApLCBub3QgdGhyb3VnaCBhIHNlY29uZCB2b3hlbFxuICAgICAgLy8gc291cmNlIGhpZGluZyBiZWhpbmQgdGhlIHNhbWUgbW9kZXMuXG4gICAgICBpZiAoZC5yZXF1aXJlc1N0YWNrICYmICFpc1N0YWNrKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoZC5yZXF1aXJlc0dyYXlzY2FsZSAmJiAhaXNHcmF5c2NhbGUgJiYgIWlzTXVsdGljaGFubmVsKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoZC5yZXF1aXJlc1NwYXRpYWxEYXRhICYmICF0aGlzLmhhc1NwYXRpYWxEYXRhc2V0KSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoZC5yZXF1aXJlc1NwYXRpYWwzZCAmJiAhdGhpcy5oYXNTcGF0aWFsM2REYXRhc2V0KSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyBBbiBpbWFnZS1zb3VyY2VkIG1vZGUgcmVhZHMgUElYRUxTLiBBIHNwYXRpYWwgZGF0YXNldCB0aGF0IGJyaW5ncyBubyB0aXNzdWVcbiAgICAgIC8vIGltYWdlIChzZXFGSVNIIHJlY29yZHMgdW5pdGxlc3MgY29vcmRpbmF0ZXMsIG5vdCBhIHNlY3Rpb24pIGxlYXZlcyBub3RoaW5nIGZvclxuICAgICAgLy8gb25lIHRvIGRyYXcsIHNvIG9mZmVyaW5nIEltYWdlIC8gSGVhdG1hcCAvIFN1cmZhY2UgdGhlcmUgb2ZmZXJzIG1vZGVzIHRoYXQgY2FuXG4gICAgICAvLyBvbmx5IGNvbWUgdXAgYmxhbmsg4oCUIG9yIHdvcnNlLCBzaG93aW5nIHdoYXRldmVyIHNsaWRlIHdhcyBsb2FkZWQgYmVmb3JlLlxuICAgICAgLy9cbiAgICAgIC8vIE5hcnJvd2VkIHRvIFwiYSBkYXRhc2V0IGlzIHVwIEFORCB0aGVyZSBpcyBubyBpbWFnZVwiOiB3aXRoIG5vIGRhdGFzZXQgYXQgYWxsLFxuICAgICAgLy8gSW1hZ2Ugc3RheXMgb24gb2ZmZXIsIGJlY2F1c2UgYSBob3N0IHRoYXQgaGFzIG5vdCBsb2FkZWQgYW55dGhpbmcgeWV0IG5lZWRzIGFcbiAgICAgIC8vIGRlZmF1bHQgYW5kIGFuIGVtcHR5IHNlbGVjdG9yIHdvdWxkIGJlIHdvcnNlIHRoYW4gYSBibGFuayB2aWV3LlxuICAgICAgaWYgKGQuc291cmNlID09PSAnaW1hZ2UnICYmIHRoaXMuaGFzU3BhdGlhbERhdGFzZXRcbiAgICAgICAgJiYgIXRoaXMuc3BhdGlhbERhdGFzZXRIYXNQaXhlbHMpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgLy8gT3V0c2lkZSB0ZXN0IG1vZGUsIG9ubHkgdGhlIGN1cmF0ZWQgc2V0ICh0aG9zZSB3aXRoIGEgcHJvZHVjdGlvbkxhYmVsKVxuICAgIC8vIGlzIG9mZmVyZWQ7IHRlc3QgbW9kZSBleHBvc2VzIGV2ZXJ5IGJhY2tlbmQncyB0eXBlLlxuICAgIGNvbnN0IGN1cmF0ZWQgPSAoZDogeyBwcm9kdWN0aW9uTGFiZWw/OiBzdHJpbmcgfSk6IGJvb2xlYW4gPT4gdGhpcy50ZXN0TW9kZSB8fCAhIWQucHJvZHVjdGlvbkxhYmVsO1xuICAgIGNvbnN0IGJ1aWx0SW4gPSB0aGlzLnBsb3RTZXJ2aWNlLmdldFBsb3RUeXBlRGVzY3JpcHRvcnMoKVxuICAgICAgLmZpbHRlcigoZCkgPT4gY3VyYXRlZChkKSAmJiBwYXNzZXNHYXRlcyhkKSk7XG4gICAgLy8gQ29udHJpYnV0ZWQgbW9kZXMgY29tZSBhZnRlciBldmVyeSBidWlsdC1pbiBvbmUsIHVuZGVyIHRoZSBzYW1lIGxhYmVsIHJ1bGVcbiAgICAvLyBhbmQgdGhlaXIgb3duIHN0YWNrL2dyYXlzY2FsZS9zcGF0aWFsIGdhdGVzLiBBIG1vZGUgYWxzbyBuZWVkcyB3aGF0ZXZlciBpdHMgYmFzZVxuICAgIC8vIHZpZXcgbmVlZHMgKHBpeGVscywgYSAzRC1jYXBhYmxlIGJhY2tlbmQpLCBzbyB0aGUgYmFzZSB0eXBlJ3MgZ2F0ZXMgYXBwbHlcbiAgICAvLyB0b28g4oCUIGEgY29udHJpYnV0ZWQgSW1hZ2UtYmFzZWQgbW9kZSBnb2VzIHdoZXJldmVyIEltYWdlIGdvZXMuXG4gICAgY29uc3QgY29udHJpYnV0ZWQ6IFBsb3RUeXBlT3B0aW9uW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGQgb2YgdGhpcy5wbG90TW9kZXMuZGVzY3JpcHRvcnMoKSkge1xuICAgICAgaWYgKCFjdXJhdGVkKGQpKSBjb250aW51ZTtcbiAgICAgIGlmIChkLnJlcXVpcmVzU3RhY2sgJiYgIWlzU3RhY2spIGNvbnRpbnVlO1xuICAgICAgaWYgKGQucmVxdWlyZXNHcmF5c2NhbGUgJiYgIWlzR3JheXNjYWxlICYmICFpc011bHRpY2hhbm5lbCkgY29udGludWU7XG4gICAgICBpZiAoZC5yZXF1aXJlc1NwYXRpYWxEYXRhICYmICF0aGlzLmhhc1NwYXRpYWxEYXRhc2V0KSBjb250aW51ZTtcbiAgICAgIGlmIChkLnJlcXVpcmVzU3BhdGlhbDNkICYmICF0aGlzLmhhc1NwYXRpYWwzZERhdGFzZXQpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgYmFzZSA9IGdldFBsb3RUeXBlRGVzY3JpcHRvcihkLmJhc2VUeXBlKTtcbiAgICAgIGlmIChiYXNlICYmIHBhc3Nlc0dhdGVzKGJhc2UpKSBjb250cmlidXRlZC5wdXNoKGNvbnRyaWJ1dGVkUGxvdFR5cGVPcHRpb24oZCwgYmFzZSkpO1xuICAgIH1cbiAgICAvLyBEZWZhdWx0IHNlbGVjdG9yIHNob3dzIHRoZSBzdWZmaXgtZnJlZSBwcm9kdWN0aW9uTGFiZWw7IHRlc3QgbW9kZSBrZWVwc1xuICAgIC8vIHRoZSBmdWxsIGJhY2tlbmQtc3VmZml4ZWQgbGFiZWwgc28gc2FtZS1uYW1lZCBtb2RlcyBzdGF5IGRpc3Rpbmd1aXNoYWJsZS5cbiAgICBjb25zdCBsYWJlbGxlZCA9IDxUIGV4dGVuZHMgeyBsYWJlbDogc3RyaW5nOyBwcm9kdWN0aW9uTGFiZWw/OiBzdHJpbmcgfT4oZDogVCk6IFQgPT5cbiAgICAgICh0aGlzLnRlc3RNb2RlID8gZCA6IHsgLi4uZCwgbGFiZWw6IGQucHJvZHVjdGlvbkxhYmVsISB9KTtcbiAgICB0aGlzLnBsb3RUeXBlT3B0aW9ucyA9IGJ1aWx0SW4ubWFwKGxhYmVsbGVkKTtcbiAgICB0aGlzLnBsb3RUeXBlTWVudSA9IFsuLi50aGlzLnBsb3RUeXBlT3B0aW9ucywgLi4uY29udHJpYnV0ZWQubWFwKGxhYmVsbGVkKV07XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgLy8gVGhlIGNvbnN0cnVjdG9yIGNvbXB1dGVzIHRoZSBvcHRpb25zIHdpdGggdGVzdE1vZGUgc3RpbGwgYXQgaXRzIGRlZmF1bHQ7XG4gICAgLy8gcmVjb21wdXRlIG9uY2UgdGhlIGhvc3QgYmluZHMgaXQgKGFuZCBvbiBhbnkgbGF0ZXIgY2hhbmdlKSBzbyB0aGUgc2VsZWN0b3JcbiAgICAvLyByZWZsZWN0cyB0ZXN0IG1vZGUgaW1tZWRpYXRlbHksIHdpdGhvdXQgd2FpdGluZyBmb3IgYW4gaW1hZ2UgdG8gKHJlKWxvYWQuXG4gICAgaWYgKGNoYW5nZXNbJ3Rlc3RNb2RlJ10pIHtcbiAgICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgICAgLy8gSWYgdGVzdCBtb2RlIGlzIHR1cm5lZCBvZmYgd2hpbGUgYSB0ZXN0LW9ubHkgdHlwZSAoZS5nLiBOQVBBUklfSU1BR0UpIGlzXG4gICAgICAvLyBhY3RpdmUsIHRoYXQgdHlwZSBpcyBubyBsb25nZXIgb2ZmZXJlZCDigJQgZmFsbCBiYWNrIHRvIEltYWdlLlxuICAgICAgdGhpcy5yZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIElmIHRoZSBhY3RpdmUgcGxvdCB0eXBlIGlzIG5vIGxvbmdlciBpbiB0aGUgb2ZmZXJlZCBvcHRpb25zIChlLmcuIHRlc3QgbW9kZVxuICAgKiAgdHVybmVkIG9mZiB3aGlsZSBhIHRlc3Qtb25seSB0eXBlIHdhcyBhY3RpdmUsIG9yIGEgc2NhbGFyIHR5cGUgY2FycmllZCBvbnRvXG4gICAqICBhbiBSR0IgaW1hZ2UpLCBmYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2Ugdmlldy4gKi9cbiAgLyoqIFdoZXRoZXIgdGhlIGxpdmUgc3BhdGlhbCBkYXRhc2V0IGJyaW5ncyBwaXhlbHMgb2YgaXRzIG93biDigJQgYSB0aXNzdWUgaW1hZ2UgaXRcbiAgICogIHJlZ2lzdGVycyBvbnRvLCBvciBhIHZvbHVtZSB0aGF0IGlzIHB1Ymxpc2hlZCBhcyBhIHotc3RhY2sgaW1hZ2UuICovXG4gIHByaXZhdGUgc3BhdGlhbERhdGFzZXRIYXNQaXhlbHMgPSBmYWxzZTtcblxuICAvKipcbiAgICogVGhlIGhvc3QgcHVibGlzaGVkIE5PIGltYWdlIOKAlCBhIHNwYXRpYWwgZGF0YXNldCB0aGF0IGJyaW5ncyBub25lIGRvZXMgdGhpcy5cbiAgICpcbiAgICogV2l0aG91dCBoYW5kbGluZyB0aGUgZW1wdHkgZW1pc3Npb24sIGBpbWFnZUluZm9gIGtlZXBzIHRoZSBMQVNUIGltYWdlJ3MgbWV0YWRhdGE6IHRoZVxuICAgKiBzZWxlY3RvciBnb2VzIG9uIG9mZmVyaW5nIHBpeGVsIG1vZGVzIGZvciBwaXhlbHMgdGhhdCBhcmUgZ29uZSwgYW5kIGV2ZXJ5XG4gICAqIGBpc1N0YWNrYC9gaXNHcmF5c2NhbGVgIGRlY2lzaW9uIGlzIG1hZGUgYWdhaW5zdCBhIGZpbGUgdGhhdCBpcyBubyBsb25nZXIgbG9hZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBvbkltYWdlQ2xlYXJlZCgpOiB2b2lkIHtcbiAgICAvLyBUaGUgaW1hZ2UgYSBjb250cmlidXRlZCBtb2RlIHdhcyBkcmF3aW5nIG92ZXIgaXMgZ29uZS4gQW4gb3BlbiBkaWFsb2dcbiAgICAvLyB0b29sIHN0YXlzIG9wZW4gYW5kIHJlc3RhcnRzIG9uY2UgdGhlIG5leHQgaW1hZ2UgaGFzIHBsb3R0ZWQuXG4gICAgdGhpcy5wbG90TW9kZXMuZGVhY3RpdmF0ZSgpO1xuICAgIHRoaXMudG9vbERpYWxvZ3MuZGVhY3RpdmF0ZSgpO1xuICAgIHRoaXMuaW1hZ2VJbmZvID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubG9hZGVkRmlsZU5hbWUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCk7XG4gICAgLy8gRGVsaWJlcmF0ZWx5IE5PVCByZWNvbmNpbGluZyB0aGUgc2VsZWN0ZWQgdHlwZSBoZXJlLiBSZWNvbmNpbGluZyBjYWxsc1xuICAgIC8vIGBzZXRQbG90VHlwZWAsIHdoaWNoIGRyaXZlcyBhIHJlLXBsb3Qg4oCUIGFuZCB0aGVyZSBpcyBub3RoaW5nIHRvIHBsb3QsIHNvIHRoZVxuICAgIC8vIFBsb3RseSBiYWNrZW5kIHJlYWQgaXRzIG93biBub3ctdW5zZXQgYGltYWdlSW5mb2AgYW5kIHRocmV3XG4gICAgLy8gKFwiY2FuJ3QgYWNjZXNzIHByb3BlcnR5IGlzR3JheXNjYWxlXCIpLCBhYm9ydGluZyB0aGUgbG9hZCB3aXRoIG5vIG9ic2VydmF0aW9uc1xuICAgIC8vIGRyYXduLiBJZ25vcmluZyB0aGUgZW1wdHkgZW1pc3Npb24gZW50aXJlbHkgaXMgd2hhdCB1c2VkIHRvIGF2b2lkIHRoYXQuXG4gICAgLy9cbiAgICAvLyBOb3RoaW5nIGlzIGxlZnQgc3RyYW5kZWQ6IGFuIGltYWdlIGlzIGNsZWFyZWQgYmVjYXVzZSBhIHNwYXRpYWwgZGF0YXNldCB0aGF0XG4gICAgLy8gYnJpbmdzIG5vbmUgaXMgYmVpbmcgb3BlbmVkLCBhbmQgdGhhdCBkYXRhc2V0J3Mgb3duIHN1YnNjcmlwdGlvbiBzZWxlY3RzIHRoZVxuICAgIC8vIG1vZGUgaXRzIGNvb3JkaW5hdGVzIHN1cHBvcnQgYSBtb21lbnQgbGF0ZXIuXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnBsb3RUeXBlTWVudS5zb21lKChkKSA9PiBkLnR5cGUgPT09IHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkKSkgcmV0dXJuO1xuICAgIC8vIEltYWdlIGlzIHRoZSB1c3VhbCBmYWxsYmFjaywgYnV0IGl0IGlzIG5vdCBhbHdheXMgT04gT0ZGRVI6IHdpdGggbm8gaW1hZ2UgbG9hZGVkXG4gICAgLy8gdGhlIHBpeGVsIG1vZGVzIGFyZSBnb25lLCBhbmQgZmFsbGluZyBiYWNrIHRvIG9uZSB3b3VsZCBzZWxlY3QgYSBtb2RlIHRoZSBzZWxlY3RvclxuICAgIC8vIGRvZXMgbm90IGxpc3QgYW5kIG5vdGhpbmcgY2FuIGRyYXcuIFRha2UgdGhlIGZpcnN0IHR5cGUgc3RpbGwgb2ZmZXJlZCBpbnN0ZWFkLlxuICAgIGNvbnN0IGZhbGxiYWNrID0gdGhpcy5wbG90VHlwZU1lbnUuc29tZSgoZCkgPT4gZC50eXBlID09PSBQbG90VHlwZS5JTUFHRSlcbiAgICAgID8gUGxvdFR5cGUuSU1BR0VcbiAgICAgIDogdGhpcy5wbG90VHlwZU1lbnVbMF0/LnR5cGU7XG4gICAgaWYgKCFmYWxsYmFjaykgcmV0dXJuO1xuICAgIC8vIExlYXZpbmcgYSBjb250cmlidXRlZCBtb2RlIChpdHMgZ2F0ZXMgc3RvcHBlZCBwYXNzaW5nLCBvciBpdHMgcHJvdmlkZXIgaXNcbiAgICAvLyBnb25lKTogaXRzIHNlc3Npb24gZW5kcyBiZWZvcmUgYW55dGhpbmcgZWxzZSBkcmF3cy5cbiAgICB0aGlzLnBsb3RNb2Rlcy5kZWFjdGl2YXRlKCk7XG4gICAgY29uc3QgYmFzZSA9IHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2YoZmFsbGJhY2spO1xuICAgIGlmIChiYXNlICE9PSBQbG90VHlwZS5JTUFHRSkgdGhpcy5jbG9zZURpYWxvZ1Rvb2woKTtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IGZhbGxiYWNrO1xuICAgIHRoaXMucGxvdFR5cGUgPSBiYXNlO1xuICAgIHRoaXMuaXNIZWF0bWFwID0gYmFzZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZShiYXNlKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEpvaW4gdGhlIGxpdmUgc2V0OyB0aGUgb2xkZXN0IG1lbWJlciByZW5kZXJzIHRoZSBzaGFyZWQgbm90aWNlIG91dGxldHMuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmFkZCh0aGlzKTtcbiAgICB0aGlzLnN0YXRlLnNldERpYWdyYW0odGhpcyk7XG4gICAgdGhpcy5zZWxlY3RlZENvbG9ybWFwID1cbiAgICAgIHRoaXMuY29sb3JtYXBzT3B0aW9uc1swXS5jaGlsZHJlbi5maW5kKChjOiBhbnkpID0+IGMubGFiZWwgPT09ICdHcmV5cyBJbnYnKSA/P1xuICAgICAgdGhpcy5jb2xvcm1hcHNPcHRpb25zWzBdLmNoaWxkcmVuWzBdO1xuICAgIHRoaXMuc3RhY2tPcHRpb25zID0gW1xuICAgICAgeyBuYW1lOiAnU2luZ2xlIGltYWdlJywgdmFsOiAnZmFsc2UnIH0sXG4gICAgICB7IG5hbWU6ICdTdGFjaycsIHZhbDogJ3RydWUnIH0sXG4gICAgXTtcbiAgICB0aGlzLnNlbGVjdGVkU3RhY2tPcHRpb24gPSB0aGlzLnN0YWNrT3B0aW9uc1swXTtcbiAgICB0aGlzLndhdGNoU3BhdGlhbERhdGFzZXQoKTtcbiAgICB0aGlzLmF1dG9zY2FsZVN1YnNjcmlwdGlvbiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0QXV0b3NjYWxlRXZlbnQoKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgLy8gcmVzZXQgdGhlIGltYWdlIG1vZGUgdG8gc2luZ2xlIGltYWdlXG4gICAgICB0aGlzLnNlbGVjdGVkU3RhY2tPcHRpb24gPSB7IG5hbWU6ICdTaW5nbGUgaW1hZ2UnLCB2YWw6ICdmYWxzZScgfTtcbiAgICAgIHRoaXMuYWN0aXZlRHJhZ01vZGUgPSBudWxsO1xuICAgICAgdGhpcy5zZXNzaW9uLnNldEFjdGl2ZVRvb2wobnVsbCk7XG4gICAgfSk7XG4gICAgdGhpcy5pbWFnZUxvYWRpbmdTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmlzSW1hZ2VMb2FkaW5nJCgpLnN1YnNjcmliZSgoaXNJbWFnZUxvYWRpbmcpID0+IHtcbiAgICAgIHRoaXMuaW1nTG9hZGluZyA9IGlzSW1hZ2VMb2FkaW5nO1xuICAgIH0pO1xuICAgIC8vIFVuZG8gYXZhaWxhYmlsaXR5IChqaXQtdWkjODUpOiB0aGUgc2hhcmVkIFJlZ2lvblN0b3JlIGVtaXRzIHdoZW5ldmVyIGl0c1xuICAgIC8vIGhpc3RvcnkgZGVwdGggY2hhbmdlczsgZ3JleXMgb3V0IHRoZSB0b29sYmFyIFVuZG8gYnV0dG9uIGFjY29yZGluZ2x5LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRDYW5VbmRvJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YikpXG4gICAgICAuc3Vic2NyaWJlKChjYW5VbmRvKSA9PiB7XG4gICAgICAgIHRoaXMuY2FuVW5kb1JlZ2lvbiA9IGNhblVuZG87XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRDYW5SZWRvJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YikpXG4gICAgICAuc3Vic2NyaWJlKChjYW5SZWRvKSA9PiB7XG4gICAgICAgIHRoaXMuY2FuUmVkb1JlZ2lvbiA9IGNhblJlZG87XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pO1xuICAgIC8vIE1pcnJvciB0aGUgcmVnaW9uIHNlbGVjdGlvbiBzbyB0aGUgcmlnaHQtY2xpY2sgYWN0aW9uIGdyb3VwIChqaXQtdWkjODUpXG4gICAgLy8gY2FuIHJlYWQgaXQgc3luY2hyb25vdXNseSB3aGVuIHRoZSBtZW51IGlzIGJ1aWx0LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMudW5zdWIpKVxuICAgICAgLnN1YnNjcmliZSgoaW5kaWNlcykgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkSW5kaWNlcyA9IGluZGljZXMgfHwgW107XG4gICAgICB9KTtcbiAgICAvLyBJbnRlcmFjdGl2ZSBwb2ludC1wcm9tcHQgc2VnbWVudGF0aW9uIHJ1bnMgaW5zaWRlIHRoZSByZW5kZXJlciBvbiBlYWNoXG4gICAgLy8gY2xpY2s7IHN1cmZhY2UgaXRzIGxpdmUgc3RhdHVzICsgZG93bmxvYWQgcHJvZ3Jlc3MgaW4gdGhlIHNoYXJlZCBgc2FtYFxuICAgIC8vIHRvYXN0IHNvIHRoZSB1c2VyIHNlZXMgaXQgd29ya2luZyAodGhlIGZpcnN0IGNsaWNrIHB1bGxzIHRoZSBlbmNvZGVyKS5cbiAgICB0aGlzLnNhbVBvaW50U3ViLmFkZChcbiAgICAgIHRoaXMuc2FtUG9pbnRUb29sLnByb2dyZXNzJC5zdWJzY3JpYmUoKGYpID0+IHtcbiAgICAgICAgdGhpcy5zYW1Eb3dubG9hZGluZyA9IGYgPj0gMCAmJiBmIDwgMTtcbiAgICAgICAgaWYgKGYgPj0gMCkgdGhpcy5zYW1Qcm9ncmVzcyA9IE1hdGgubWluKDEwMCwgTWF0aC5yb3VuZChmICogMTAwKSk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zYW1Qb2ludFN1Yi5hZGQoXG4gICAgICB0aGlzLnNhbVBvaW50VG9vbC5zdGF0dXMkLnN1YnNjcmliZSgobSkgPT4ge1xuICAgICAgICB0aGlzLnNhbVN0YXR1cyA9IG07XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zYW1Qb2ludFN1Yi5hZGQoXG4gICAgICB0aGlzLnNhbVBvaW50VG9vbC5idXN5JC5zdWJzY3JpYmUoKGJ1c3kpID0+IHtcbiAgICAgICAgdGhpcy5zYW1CdXN5ID0gYnVzeTtcbiAgICAgICAgaWYgKGJ1c3kpIHRoaXMuc2hvd1NhbVRvYXN0KCdTQU0gcG9pbnQgc2VnbWVudGF0aW9uJyk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdGFja0xvYWRpbmdQcm9ncmVzcygpLnN1YnNjcmliZSgobG9hZGluZ1Byb2dyZXNzKSA9PiB7XG4gICAgICB0aGlzLmxvYWRpbmdQZXJjZW50YWdlID0gbG9hZGluZ1Byb2dyZXNzO1xuICAgIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuaXNTdGFja0xvYWRpbmcoKS5zdWJzY3JpYmUoKHN0YWNrTG9hZGluZykgPT4ge1xuICAgICAgdGhpcy5zdGFja0xvYWRpbmcgPSBzdGFja0xvYWRpbmc7XG4gICAgfSk7XG4gICAgdGhpcy5wbG90V2lkdGhTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmdldFBhbmVsV2lkdGgkKCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVsYXlvdXQoKTtcbiAgICAgIC8vIFRoZSBpbnRlbnNpdHkgaW5zZXQgaXMgYSBzZXBhcmF0ZSBQbG90bHkgY2hhcnQgaW4gYSBmbG9hdGluZyBwYW5lbDsgcmVmbG93XG4gICAgICAvLyBpdCB0byBpdHMgY3VycmVudCBzaXplIHdoZW4gdGhlIGNhbnZhcyByZXNpemVzLCBlbHNlIGl0IGtlZXBzIHRoZSBzdGFsZVxuICAgICAgLy8gc2l6ZSBhbmQgYmxhbmtzIG91dC4gRGVmZXIgYSB0aWNrIHNvIHRoZSBwYW5lbCBsYXlvdXQgaGFzIHNldHRsZWQuXG4gICAgICBpZiAodGhpcy5oYXNQcm9maWxlcykge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVuZGVySW50ZW5zaXR5SW5zZXQoKSwgMCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5pbWdMb2FkaW5nTWVzc2FnZVN1YnNjcmlwdGlvbiA9IHRoaXMuc3RhdGUuZ2V0SW1hZ2VMb2FkaW5nTWVzc2FnZSQoKS5zdWJzY3JpYmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgIHRoaXMubG9hZGluZ01lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH0pO1xuICAgIHRoaXMuc3RhdGVcbiAgICAgIC5nZXRDYWNoZVByb2dyZXNzJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YikpXG4gICAgICAuc3Vic2NyaWJlKChwcm9ncmVzcykgPT4ge1xuICAgICAgICB0aGlzLmNhY2hlUHJvZ3Jlc3MgPSBwcm9ncmVzcztcbiAgICAgIH0pO1xuICAgIHRoaXMuaXNab29tU3Vic2NyaXB0aW9uID0gdGhpcy5zdGF0ZS5pc1pvb20kKCkuc3Vic2NyaWJlKCh6b29tKSA9PiB7XG4gICAgICB0aGlzLnpvb20gPSB6b29tO1xuICAgIH0pO1xuICAgIHRoaXMuZmlsZW5hbWVTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmdldEZpbGVuYW1lJCgpLnN1YnNjcmliZSgoZmlsZW5hbWUpID0+IHtcbiAgICAgIGlmIChmaWxlbmFtZSkge1xuICAgICAgICB0aGlzLmZpbGVOYW1lID0gZmlsZW5hbWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRDb2xvcm1hcCgpLnN1YnNjcmliZSgoY29sb3JtYXApID0+IHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDb2xvcm1hcCA9IGNvbG9ybWFwO1xuICAgIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmV2ZXJzZVNjYWxlKCkuc3Vic2NyaWJlKChyZXZlcnNlc2NhbGUpID0+IHtcbiAgICAgIHRoaXMucmV2ZXJzZXNjYWxlID0gcmV2ZXJzZXNjYWxlO1xuICAgIH0pO1xuICAgIHRoaXMuaW50ZW5zaXR5UHJvZmlsZVN1YiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0SW50ZW5zaXR5UHJvZmlsZSQoKS5zdWJzY3JpYmUoKHByb2ZpbGVzKSA9PiB7XG4gICAgICB0aGlzLmxhdGVzdFByb2ZpbGVzID0gcHJvZmlsZXM7XG4gICAgICB0aGlzLmhhc1Byb2ZpbGVzID0gcHJvZmlsZXMubGVuZ3RoID4gMDtcbiAgICAgIC8vIFRoZSBwYW5lbCBkaXYgaXMgYmVoaW5kICpuZ0lmPVwiaGFzUHJvZmlsZXNcIi4gZGV0ZWN0Q2hhbmdlcygpIG1hdGVyaWFsaXplc1xuICAgICAgLy8gaXQgc3luY2hyb25vdXNseSAodGhlIHN1YnNjcmlwdGlvbiBtYXkgZmlyZSBvdXRzaWRlIEFuZ3VsYXIncyB6b25lIOKAlCBlLmcuXG4gICAgICAvLyBmcm9tIGFuIE9TRCBkcmFnIOKAlCBzbyBDRCB3b3VsZG4ndCBydW4gb24gaXRzIG93bikuIFRoZW4gcmVuZGVyIG9uIHRoZSBuZXh0XG4gICAgICAvLyBhbmltYXRpb24gZnJhbWUsIEFGVEVSIHRoZSBicm93c2VyIGxheXMgdGhlIHBhbmVsIG91dDogYSBzeW5jaHJvbm91cyBkcmF3XG4gICAgICAvLyBoaXRzIGEgemVyby1zaXplIGNvbnRhaW5lciBvbiBmaXJzdCBjcmVhdGUgYW5kIFBsb3RseSBrZWVwcyB0aGF0IHNpemUsIHNvXG4gICAgICAvLyB0aGUgaW5zZXQgc3RheXMgYmxhbmsgYW5kIGxpdmUgdXBkYXRlcyByZWRyYXcgaW50byB0aGUgc2FtZSB6ZXJvIGJveC5cbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLnJlbmRlckludGVuc2l0eUluc2V0KCkpO1xuICAgIH0pO1xuICAgIC8vIFdoZW4gdGhlIE9TRCB2aWV3IHNldHRsZXMgYXQgYSBuZXcgem9vbS9wYW4sIHJlLXNhbXBsZSB0aGUgaW50ZW5zaXR5IGxpbmVzXG4gICAgLy8gZnJvbSBhIGNyb3Agb2YgdGhlIHZpc2libGUgcmVnaW9uIHNvIHRoZSBpbnNldCByZWZsZWN0cyB0aGUgem9vbS1sZXZlbFxuICAgIC8vIHJlc29sdXRpb24gKFBsb3RseSdzIG93biBoaWdoLWRlZiB6b29tIHVwZGF0ZXMgdGhlIHNhbXBsaW5nIGNhY2hlIGlubGluZSkuXG4gICAgdGhpcy52aWV3cG9ydENoYW5nZVN1YiA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0Vmlld3BvcnRDaGFuZ2UkKCkuc3Vic2NyaWJlKChyb2kpID0+IHtcbiAgICAgIGlmICh0aGlzLmhhc1Byb2ZpbGVzICYmIHRoaXMuaXNJbWFnZVZpZXcpIHtcbiAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZWZyZXNoSW50ZW5zaXR5U2FtcGxpbmdGb3JSb2kocm9pLngsIHJvaS55LCByb2kud2lkdGgsIHJvaS5oZWlnaHQsIHRoaXMuekluZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnByZXZpZXdTdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlLmdldEltYWdlSW5mbyQoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGltZ0luZm8pID0+IHtcbiAgICAgICAgaWYgKCFpbWdJbmZvKSB7XG4gICAgICAgICAgdGhpcy5vbkltYWdlQ2xlYXJlZCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW1nSW5mbykge1xuICAgICAgICAgIHRoaXMuaW1hZ2VJbmZvID0gaW1nSW5mbztcbiAgICAgICAgICAvLyBTdGFjay1vbmx5IHBsb3QgdHlwZXMgKGlzb3N1cmZhY2UsIHNjYXR0ZXIzZCkgZGVwZW5kIG9uIHdoZXRoZXIgdGhpc1xuICAgICAgICAgIC8vIGZpbGUgaXMgYSBzdGFjayDigJQgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBvcHRpb25zLlxuICAgICAgICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgICAgICAgIC8vIElmIHRoZSBhY3RpdmUgcGxvdCB0eXBlIGlzbid0IHZhbGlkIGZvciB0aGlzIGltYWdlIChlLmcuIGEgc2NhbGFyXG4gICAgICAgICAgLy8gdHlwZSBsaWtlIENvbnRvdXIgY2FycmllZCBvdmVyIHRvIGFuIFJHQiBpbWFnZSksIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICAgICAgICAvLyByZXNldCBzdGFjayBvcHRpb25zIHNlbGVjdGlvblxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRTdGFja09wdGlvbiA9IGltZ0luZm8uc2hvd1N0YWNrID8gdGhpcy5zdGFja09wdGlvbnNbMV0gOiB0aGlzLnN0YWNrT3B0aW9uc1swXTtcblxuICAgICAgICAgIC8vIFJlYWQgZnJvbSBgaW1nSW5mb2AsIHRoZSB2YWx1ZSB0aGlzIGVtaXNzaW9uIGNhcnJpZWQsIHJhdGhlciB0aGFuIGZyb20gdGhlXG4gICAgICAgICAgLy8gZmllbGQuIEhhbmRsaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiBtZWFucyB0aGUgZmllbGQgQ0FOIGJlIG51bGxlZCBwYXJ0LXdheVxuICAgICAgICAgIC8vIHRocm91Z2ggdGhpcyBicmFuY2g6IGByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlYCBtYXkgY2FsbCBgc2V0UGxvdFR5cGVgLFxuICAgICAgICAgIC8vIHdoaWNoIGNhbiBtYWtlIHRoZSBob3N0IHB1Ymxpc2ggYSBuZXcgaW1hZ2Ugc3RhdGUsIHJlLWVudGVyaW5nIHRoaXMgdmVyeVxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbi4gUmVhZGluZyB0aGUgZmllbGQgdGhlbiB0aHJldyBvbiBgaXNHcmF5c2NhbGVgIGFuZCBhYm9ydGVkIHRoZVxuICAgICAgICAgIC8vIGhhbmRsZXIsIHNvIHRoZSBvYnNlcnZhdGlvbnMgd2VyZSBuZXZlciBkcmF3bi5cbiAgICAgICAgICB0aGlzLmlzR3JheXNjYWxlRXZlbnQuZW1pdChpbWdJbmZvLmlzR3JheXNjYWxlKTtcbiAgICAgICAgICB0aGlzLmlzU3RhY2tFdmVudC5lbWl0KGltZ0luZm8uaXNTdGFjayk7XG4gICAgICAgICAgLy8gUmVzZXQgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2UgdmlldyB3aGVuIGEgZGlmZmVyZW50IGltYWdlIGlzXG4gICAgICAgICAgLy8gc2VsZWN0ZWQgd2hpbGUgYSAzRCB0eXBlIGlzIGFjdGl2ZS5cbiAgICAgICAgICBpZiAoIXRoaXMuaXNIZWF0bWFwICYmIGltZ0luZm8uZmlsZU5hbWUgIT09IHRoaXMubG9hZGVkRmlsZU5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMuaXNIZWF0bWFwID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucGxvdFR5cGUgPSBQbG90VHlwZS5JTUFHRTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gUGxvdFR5cGUuSU1BR0U7XG4gICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKHRoaXMucGxvdFR5cGUpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubG9hZGVkRmlsZU5hbWUgPSBpbWdJbmZvLmZpbGVOYW1lO1xuICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0SW1hZ2VNZXRhKGltZ0luZm8uaW1hZ2VNZXRhKTtcbiAgICAgICAgICBjb25zdCB1cmxzID0gaW1nSW5mby51cmxzO1xuICAgICAgICAgIC8vIEEgbmV3ZXIgaW1hZ2UgQUxXQVlTIHByZWVtcHRzIGFuIGluLWZsaWdodCByZW5kZXIuIFRoaXMgd2FzXG4gICAgICAgICAgLy8gYGlmICghdGhpcy5ydW5uaW5nKWAsIHdoaWNoIERST1BQRUQgdGhlIG5ldyBpbWFnZSB3aGlsZSB0aGUgb2xkIG9uZVxuICAgICAgICAgIC8vIGZpbmlzaGVkOiBpZGVudGl0eSBhYm92ZSBoYWQgYWxyZWFkeSBmbGlwcGVkIHRvIHRoZSBuZXcgZmlsZSwgc28gdGhlXG4gICAgICAgICAgLy8gYXBwIHJlcG9ydGVkIGltYWdlIEIgYXMgbG9hZGVkIHdoaWxlIGltYWdlIEEgc3RheWVkIG9uIHNjcmVlbi4gV29yc2UsXG4gICAgICAgICAgLy8gYSBjb2xkIGltYWdlIGhvbGRzIHRoZSBzbG90IGZvciBpdHMgd2hvbGUgc2VydmVyLXNpZGUgY2FjaGUgZmlsbCwgc29cbiAgICAgICAgICAvLyBldmVyeSBjbGljayBmb3IgMS0yIG1pbnV0ZXMgd2FzIGRpc2NhcmRlZCBhZ2FpbnN0IGEgYmxhbmsgdmlld3BvcnRcbiAgICAgICAgICAvLyBhbmQgYSBcIkxvYWRpbmcgaW1hZ2UuLi5cIiBvdmVybGF5IHRoYXQgbmV2ZXIgcmVzb2x2ZWQuXG4gICAgICAgICAgaWYgKHVybHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRva2VuID0gKyt0aGlzLnJlbmRlclRva2VuO1xuICAgICAgICAgICAgY29uc3QgaXNDdXJyZW50ID0gKCkgPT4gdGhpcy5yZW5kZXJUb2tlbiA9PT0gdG9rZW47XG4gICAgICAgICAgICBpZiAodGhpcy5ydW5uaW5nKSB7XG4gICAgICAgICAgICAgIC8vIFN0b3AgdGhlIHByZXZpb3VzIHJlbmRlcidzIGZyYW1lIHN0cmVhbWluZyAobmFwYXJpIHZvbHVtZS9zdXJmYWNlXG4gICAgICAgICAgICAgIC8vIHByZWxvYWQga2VlcHMgZmV0Y2hpbmcgb3RoZXJ3aXNlKSBhbmQgY2xlYXIgaXRzIHNoYXJwZW4gZmxhZy4gSXRzXG4gICAgICAgICAgICAgIC8vIGNhbGxiYWNrcyBhcmUgYWxyZWFkeSBpbmVydCB2aWEgdGhlIHRva2VuLCBzbyBpdCBjYW4gbmVpdGhlciBwYWludFxuICAgICAgICAgICAgICAvLyBub3IgcmVsZWFzZSB0aGUgb3ZlcmxheSB0aGlzIHJlbmRlciBub3cgb3ducy5cbiAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5jYW5jZWxMb2FkaW5nPy4oKTtcbiAgICAgICAgICAgICAgdGhpcy5zaGFycGVuaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpbWFnZSBzaXplIOKAlCBtZWFzdXJlIHRoZSBwbG90IGRpdiBkaXJlY3RseSBzbyB0aGUgdG9vbGJhciBoZWlnaHQgaXMgZXhjbHVkZWRcbiAgICAgICAgICAgIGNvbnN0IHBsb3REaXY6IEhUTUxFbGVtZW50IHwgbnVsbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMucGxvdERpdk5hbWUpO1xuICAgICAgICAgICAgY29uc3Qgc2NyZWVuSGVpZ2h0ID0gcGxvdERpdj8ub2Zmc2V0SGVpZ2h0IHx8IDUwMDtcbiAgICAgICAgICAgIC8vIEEgY29udHJpYnV0ZWQgbW9kZSdzIHNlc3Npb24gaXMgYm91bmQgdG8gdGhlIGJhc2UgdmlldyBhYm91dCB0byBiZVxuICAgICAgICAgICAgLy8gdG9ybiBkb3duLCBzbyBpdCBlbmRzIGhlcmUg4oCUIGJlZm9yZSByZXNldCgpLCBiZWZvcmUgYW55dGhpbmcgbmV3XG4gICAgICAgICAgICAvLyBkcmF3cy4gSWYgdGhlIG1vZGUgaXMgc3RpbGwgc2VsZWN0ZWQgb25jZSB0aGlzIHJlbmRlciBsYW5kcywgYVxuICAgICAgICAgICAgLy8gZnJlc2ggc2Vzc2lvbiBzdGFydHMgZm9yIGl0IChzZWUgYWN0aXZhdGVTZWxlY3RlZFBsb3RNb2RlKS5cbiAgICAgICAgICAgIHRoaXMucGxvdE1vZGVzLmRlYWN0aXZhdGUoKTtcbiAgICAgICAgICAgIHRoaXMudG9vbERpYWxvZ3MuZGVhY3RpdmF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5zdGFja0xvYWRpbmcgPSBpbWdJbmZvLmlzU3RhY2sgJiYgaW1nSW5mby5zaG93U3RhY2s7XG4gICAgICAgICAgICAvLyBzZXQgbWF4IGluZGV4IG9mIHN0YWNrIOKAlCBjb21wdXRlZCBiZWZvcmUgdXBkYXRlWkluZGV4IHNvIGFcbiAgICAgICAgICAgIC8vIGZyZXNoIHN0YWNrIChzaG9ydGVyIG9yIGxvbmdlciB0aGFuIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5XG4gICAgICAgICAgICAvLyBsb2FkZWQpIGNsYW1wcyBhZ2FpbnN0IElUUyBib3VuZHMsIG5vdCB0aGUgc3RhbGUgb25lcy5cbiAgICAgICAgICAgIC8vIE9uZSBVUkwgcGVyIHNsaWNlICgwLWluZGV4ZWQpLCBzbyB0aGUgbGFzdCByZWFjaGFibGUgaW5kZXggaXNcbiAgICAgICAgICAgIC8vIGxlbmd0aC0xIOKAlCBlYXJsaWVyIGBsZW5ndGgtMmAgZHJvcHBlZCB0aGUgZmluYWwgc2xpY2UuXG4gICAgICAgICAgICB0aGlzLm1heEluZGV4ID0gdXJscy5sZW5ndGggPiAxID8gdXJscy5sZW5ndGggLSAxIDogMDtcbiAgICAgICAgICAgIC8vIE9uZS1zaG90IGhpbnQ6IGp1bXAgc3RyYWlnaHQgdG8gYSBzcGVjaWZpYyBzbGljZSAoZS5nLiB0aGVcbiAgICAgICAgICAgIC8vIGZpbGUgdGhlIHVzZXIgYWN0dWFsbHkgY2xpY2tlZCB3aXRoaW4gYSBudW1iZXJlZCBzZXJpZXMpLlxuICAgICAgICAgICAgLy8gQ29uc3VtZWQgaW1tZWRpYXRlbHkgc28gcmVkZWxpdmVyaW5nIHRoZSBzYW1lIEltYWdlSW5mbyBsYXRlclxuICAgICAgICAgICAgLy8gKGEgcGxvdC10eXBlIHN3aXRjaCwgcmVsb2FkQW5kUGxvdCkgZG9lc24ndCByZXNldCB0aGUgdXNlcidzXG4gICAgICAgICAgICAvLyBjdXJyZW50IHNjcnViIHBvc2l0aW9uIGJhY2sgdG8gaXQuXG4gICAgICAgICAgICBpZiAoaW1nSW5mby5pbml0aWFsWkluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgdGhpcy56SW5kZXggPSBpbWdJbmZvLmluaXRpYWxaSW5kZXg7XG4gICAgICAgICAgICAgIGltZ0luZm8uaW5pdGlhbFpJbmRleCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgemluZGV4IGlzIHdpdGhpbiBib3VuZHNcbiAgICAgICAgICAgIHRoaXMudXBkYXRlWkluZGV4KHVybHMpO1xuICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIE11bHRpLXRpZXIgcmVuZGVyaW5nIChzbWFsbCBibHVycnkgdGllciBmaXJzdCwgdGhlbiBzaGFycGVuIGluXG4gICAgICAgICAgICAvLyBwbGFjZSkg4oCUIHNlcXVlbmNpbmcgbGl2ZXMgaW4gUmVuZGVyT3JjaGVzdHJhdG9yOyB0aGlzIGNvbXBvbmVudFxuICAgICAgICAgICAgLy8gc3VwcGxpZXMgdGhlIHBoYXNlIHJlbmRlciBhbmQgb3ducyB0aGUgVUkgZmxhZ3MgdmlhIGNhbGxiYWNrcy5cbiAgICAgICAgICAgIC8vIDNEIHBsb3QgdHlwZXMgcmVuZGVyIHNpbmdsZS1wYXNzOiB0aGUgaW4tcGxhY2UgbGFyZ2UgcGFzcyBkb2Vzbid0XG4gICAgICAgICAgICAvLyByZWJ1aWxkIGEgM0QgZ2wtbWVzaCBpc29zdXJmYWNlLCBzbyB0aGUgc2hhcnBlbiBzdGVwIGJsYW5rZWQgaXQuXG4gICAgICAgICAgICBjb25zdCBoYXNTbWFsbFRpZXIgPVxuICAgICAgICAgICAgICB0aGlzLmlzSGVhdG1hcCAmJlxuICAgICAgICAgICAgICAoaW1nSW5mby5zbWFsbFVybHM/Lmxlbmd0aCA/PyAwKSA9PT0gdXJscy5sZW5ndGggJiZcbiAgICAgICAgICAgICAgKGltZ0luZm8uc21hbGxVcmxzPy5sZW5ndGggPz8gMCkgPiAwO1xuICAgICAgICAgICAgY29uc3Qgc21hbGxJbWdJbmZvID0gaGFzU21hbGxUaWVyID8geyAuLi5pbWdJbmZvLCB1cmxzOiBpbWdJbmZvLnNtYWxsVXJscyBhcyBzdHJpbmdbXSB9IDogbnVsbDtcblxuICAgICAgICAgICAgLy8gRW50ZXIgcGVyLXNsaWNlIHN0YWNrIG1vZGUgd2l0aCB0aGUgZ2l2ZW4gc2xpY2XihpJyZWdpb25zIG1hcCBhbmRcbiAgICAgICAgICAgIC8vIHNlZWQgdGhlIFwicHJldmlvdXMgc2hhcGVzXCIgZnJvbSB0aGUgbm93LWxpdmUgc2xpY2UuIGVudGVyU3RhY2tNb2RlXG4gICAgICAgICAgICAvLyBtYWtlcyB6SW5kZXgncyBzbGljZSBsaXZlIGFuZCByZXNldHMgdW5kbyAoaml0LXVpIzkzKS5cbiAgICAgICAgICAgIGNvbnN0IGVudGVyU3RhY2sgPSAoXG4gICAgICAgICAgICAgIHNsaWNlczogTWFwPG51bWJlciwgUmVnaW9uW10+LFxuICAgICAgICAgICAgICBsYXlvdXQ6ICdjb21iaW5lZCcgfCAncGVyLXNsaWNlLWZpbGUnLFxuICAgICAgICAgICAgKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2UuZW50ZXJTdGFja01vZGUoc2xpY2VzLCB0aGlzLnpJbmRleCwgbGF5b3V0KTtcbiAgICAgICAgICAgICAgY29uc3Qgc2hhcGVzID0gdGhpcy5wbG90U2VydmljZVxuICAgICAgICAgICAgICAgIC5nZXRSZWdpb25zKClcbiAgICAgICAgICAgICAgICAubWFwKChyZWdpb24pID0+IHJlZ2lvbi5nZXRTaGFwZSh0aGlzLnBsb3RTZXJ2aWNlLmdldFNob3dTaGFwZUxhYmVsKCkpKTtcbiAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQcmV2aW91c1NoYXBlcyhzaGFwZXMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgYXBwbHlSb2kgPSAoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIEZvbGRlciBzdGFjazogYSBzdGFjayBvZiBzZWxmLWNvbnRhaW5lZCBwZXItc2xpY2UgZmlsZXNcbiAgICAgICAgICAgICAgLy8gKHRpbGVkID09PSBmYWxzZTsgc2VlIGxvYWRTZXJpZXNBc1N0YWNrKS4gRWFjaCBzbGljZS1maWxlIG1heVxuICAgICAgICAgICAgICAvLyBjYXJyeSBpdHMgb3duIHNpYmxpbmcgXCI8c3RlbT4uZ2VvanNvblwiIChyb2lKc29uU3Ryc1t6XSksIGJ1dCBhXG4gICAgICAgICAgICAgIC8vIGZyZXNoIGZvbGRlciB3aXRoIG5vbmUgeWV0IGxlYXZlcyByb2lKc29uU3RycyB1bmRlZmluZWQg4oCUIGtleVxuICAgICAgICAgICAgICAvLyBvZmYgYHRpbGVkID09PSBmYWxzZWAsIE5PVCByb2lKc29uU3Rycywgc28gYW4gdW5hbm5vdGF0ZWRcbiAgICAgICAgICAgICAgLy8gZm9sZGVyIHN0YWNrIHN0aWxsIGVudGVycyB0aGUgcGVyLXNsaWNlLWZpbGUgbGF5b3V0IChhbmQgc2F2ZXNcbiAgICAgICAgICAgICAgLy8gYmFjayBvbmUgZ2VvanNvbiBwZXIgc2xpY2UtZmlsZSkgcmF0aGVyIHRoYW4gZmFsbGluZyB0aHJvdWdoIHRvXG4gICAgICAgICAgICAgIC8vIHRoZSBzaW5nbGUtZmlsZSBjb21iaW5lZCBwYXRoIChqaXQtdWkjOTMpLlxuICAgICAgICAgICAgICBpZiAoaW1nSW5mby5pc1N0YWNrICYmIGltZ0luZm8udGlsZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGVyU2xpY2UgPSBpbWdJbmZvLnJvaUpzb25TdHJzO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNsaWNlQ291bnQgPSBpbWdJbmZvLnVybHM/Lmxlbmd0aCA/PyBwZXJTbGljZT8ubGVuZ3RoID8/IDA7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2xpY2VzID0gbmV3IE1hcDxudW1iZXIsIFJlZ2lvbltdPigpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgc2xpY2VDb3VudDsgeisrKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gcGVyU2xpY2U/Llt6XSA/PyBudWxsO1xuICAgICAgICAgICAgICAgICAgc2xpY2VzLnNldCh6LCBqc29uID8gdGhpcy5wbG90U2VydmljZS5pbXBvcnRSZWdpb25zKGpzb24pIDogW10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbnRlclN0YWNrKHNsaWNlcywgJ3Blci1zbGljZS1maWxlJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFNpbmdsZS1maWxlIHotc3RhY2s6IG9uZSBzaWJsaW5nIGdlb2pzb24gaG9sZGluZyBldmVyeSBzbGljZSdzXG4gICAgICAgICAgICAgIC8vIHJlZ2lvbnMgaW5kZXhlZCBieSBRdVBhdGgncyBnZW9tZXRyeS5wbGFuZS56LiBFbnRlciBwZXItc2xpY2VcbiAgICAgICAgICAgICAgLy8gbW9kZSAoc2F2aW5nIGJhY2sgb25lIGNvbWJpbmVkIHotaW5kZXhlZCBnZW9qc29uKSB3aGVuIHRoZVxuICAgICAgICAgICAgICAvLyBnZW9qc29uIGFjdHVhbGx5IGNhcnJpZXMgc2xpY2UgaW5kaWNlcywgb3Igd2hlbiB0aGVyZSdzIG5vdGhpbmdcbiAgICAgICAgICAgICAgLy8geWV0IHRvIGF1dGhvciBhZ2FpbnN0LiBBIGxlZ2FjeSBnZW9qc29uIHdob3NlIHJlZ2lvbnMgYXJlIGFsbCBvblxuICAgICAgICAgICAgICAvLyB0aGUgZGVmYXVsdCBwbGFuZSBzdGF5cyBnbG9iYWwgKHNob3duIG9uIGV2ZXJ5IHNsaWNlKSBzb1xuICAgICAgICAgICAgICAvLyBleGlzdGluZyBzaW5nbGUtcGxhbmUgYW5ub3RhdGlvbnMgYXJlbid0IGNvbmZpbmVkIHRvIHNsaWNlIDAuXG4gICAgICAgICAgICAgIGNvbnN0IHJvaUpzb24gPSBpbWdJbmZvLnJvaUpzb25TdHI7XG4gICAgICAgICAgICAgIGlmIChpbWdJbmZvLmlzU3RhY2spIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWdpb25zID0gcm9pSnNvbiA/IHRoaXMucGxvdFNlcnZpY2UuaW1wb3J0UmVnaW9ucyhyb2lKc29uKSA6IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhc1NsaWNlSW5mbyA9IHJlZ2lvbnMuc29tZSgocikgPT4gKHIueiA/PyAwKSAhPT0gMCk7XG4gICAgICAgICAgICAgICAgaWYgKCFyb2lKc29uIHx8IGhhc1NsaWNlSW5mbykge1xuICAgICAgICAgICAgICAgICAgY29uc3Qgc2xpY2VzID0gbmV3IE1hcDxudW1iZXIsIFJlZ2lvbltdPigpO1xuICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeiA9IHIueiA/PyAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBidWNrZXQgPSBzbGljZXMuZ2V0KHopO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYnVja2V0KSBidWNrZXQucHVzaChyKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBzbGljZXMuc2V0KHosIFtyXSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBlbnRlclN0YWNrKHNsaWNlcywgJ2NvbWJpbmVkJyk7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFNpbmdsZS1wbGFuZSBpbWFnZSAob3IgYSBsZWdhY3kgZ2xvYmFsIHotc3RhY2sgZ2VvanNvbik6IG9uZVxuICAgICAgICAgICAgICAvLyByZWdpb24gc2V0IGZvciB0aGUgd2hvbGUgaW1hZ2UuXG4gICAgICAgICAgICAgIGlmIChyb2lKc29uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVnaW9ucyA9IHRoaXMucGxvdFNlcnZpY2UuaW1wb3J0UmVnaW9ucyhyb2lKc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFJlZ2lvbnMocmVnaW9ucyk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhcGVzID0gcmVnaW9ucy5tYXAoKHJlZ2lvbikgPT5cbiAgICAgICAgICAgICAgICAgIHJlZ2lvbi5nZXRTaGFwZSh0aGlzLnBsb3RTZXJ2aWNlLmdldFNob3dTaGFwZUxhYmVsKCkpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQcmV2aW91c1NoYXBlcyhzaGFwZXMpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIExvYWRpbmcgYW4gaW1hZ2UncyBzYXZlZCBST0lzIGlzIG5vdCBhIHVzZXIgZWRpdCDigJQgc3RhcnQgdGhlXG4gICAgICAgICAgICAgIC8vIHVuZG8gaGlzdG9yeSBmcmVzaCBzbyB0aGUgZmlyc3QgdW5kbyBjYW4ndCB3aXBlIHRoZW0gKGppdC11aSM4NSkuXG4gICAgICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVzZXRVbmRvSGlzdG9yeSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGxldCBvdmVybGF5UmVsZWFzZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHJlbGVhc2VPdmVybGF5ID0gKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAob3ZlcmxheVJlbGVhc2VkKSByZXR1cm47XG4gICAgICAgICAgICAgIG92ZXJsYXlSZWxlYXNlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGlmIChpbWdJbmZvLmlzU3RhY2sgJiYgaW1nSW5mby5zaG93U3RhY2spIHRoaXMuc3RhY2tMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIG5ldyBSZW5kZXJPcmNoZXN0cmF0b3Ioe1xuICAgICAgICAgICAgICAvLyBpblBsYWNlPXRydWUgdXBkYXRlcyB0aGUgZXhpc3RpbmcgcmVuZGVyIGluc3RlYWQgb2YgcmVidWlsZGluZ1xuICAgICAgICAgICAgICAvLyBpdCwgc28gdGhlIGNhbnZhcyBkb2Vzbid0IGJsYW5rIGR1cmluZyB0aGUgc21hbGzihpJsYXJnZSBzd2FwLlxuICAgICAgICAgICAgICByZW5kZXJQaGFzZTogKHBoYXNlSW5mbywgaW5QbGFjZSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFN1cGVyc2VkZWQgQkVGT1JFIHRoaXMgcGhhc2Ugc3RhcnRlZCDigJQgZG9uJ3QgZXZlbiBpc3N1ZSB0aGUgbG9hZC5cbiAgICAgICAgICAgICAgICAvLyBSZW5kZXJPcmNoZXN0cmF0b3IgY2FsbHMgcmVuZGVyUGhhc2Ugb25jZSBwZXIgdGllciBhbmQgcmV0cmllcyB0aGVcbiAgICAgICAgICAgICAgICAvLyBzaGFycGVuIHBhc3Mgb24gZmFpbHVyZSwgc28gY2hlY2tpbmcgb25seSBhZnRlciB0aGUgbG9hZCByZXNvbHZlc1xuICAgICAgICAgICAgICAgIC8vIHdvdWxkIGxldCBhIHByZWVtcHRlZCByZW5kZXIga2VlcCBmZXRjaGluZyBzbGljZXMvdGlsZXMgZm9yIGFuXG4gICAgICAgICAgICAgICAgLy8gaW1hZ2Ugbm9ib2R5IGlzIGxvb2tpbmcgYXQuXG4gICAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnQoKSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wbG90U2VydmljZS5sb2FkKHBoYXNlSW5mbywgdGhpcy56SW5kZXgpLnRoZW4oKGxvYWRlZEltYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAvLyBQcmVlbXB0ZWQgd2hpbGUgdGhpcyBwaGFzZSB3YXMgbG9hZGluZyDigJQgZHJvcCBpdCBvbiB0aGUgZmxvb3IuXG4gICAgICAgICAgICAgICAgICBpZiAoIWlzQ3VycmVudCgpKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgIC8vIEd1YXJkIGFnYWluc3QgYSBuZXdlciBjbGljayByZWFjaGluZyB1cyBtaWQtcmVuZGVyLlxuICAgICAgICAgICAgICAgICAgaWYgKHBoYXNlSW5mby5maWxlTmFtZSAhPT0gbG9hZGVkSW1hZ2UuZmlsZW5hbWUpIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGxvdFNlcnZpY2UucGxvdChcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbG90RGl2TmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbG9hZGVkSW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgIHBoYXNlSW5mbyxcbiAgICAgICAgICAgICAgICAgICAgc2NyZWVuSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsb3RUeXBlLFxuICAgICAgICAgICAgICAgICAgICBpblBsYWNlLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc21hbGxTaG93bjogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNDdXJyZW50KCkpIHJldHVybjsgLy8gc3VwZXJzZWRlZCBieSBhIG5ld2VyIGltYWdlXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZpbGUgaXMgc3RpbGwgYmVpbmcgY2FjaGVkL3ByZXBhcmVkIHNlcnZlci1zaWRlLCBrZWVwIHRoZSBmdWxsXG4gICAgICAgICAgICAgICAgLy8gY2FjaGUtcHJvZ3Jlc3Mgb3ZlcmxheSB1cCBpbnN0ZWFkIG9mIGRyb3BwaW5nIHRvIHRoZSB0cmFuc2x1Y2VudCBcIlNoYXJwZW5pbmdcbiAgICAgICAgICAgICAgICAvLyBwcmV2aWV3Li4uXCIgc3Bpbm5lciBvdmVyIGEgYmxhbmsgY2FudmFzIChhIGxhcmdlIHVuY2FjaGVkIGltYWdlIHJlbmRlcnMgaXRzXG4gICAgICAgICAgICAgICAgLy8gc21hbGwgcHJldmlldyBiZWZvcmUgaXRzIHRpbGVzIGV4aXN0KS4gZmluaXNoZWQoKSByZWxlYXNlcyB0aGUgb3ZlcmxheSBvbmNlXG4gICAgICAgICAgICAgICAgLy8gdGhlIHJlYWwgcmVuZGVyIGxhbmRzLlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQ2FjaGluZykgcmV0dXJuO1xuICAgICAgICAgICAgICAgIC8vIFNtYWxsIHRpZXIgb24gc2NyZWVuIOKAlCBkcm9wIHRoZSBmdWxsIG92ZXJsYXkgYnV0IGtlZXAgYSB0cmFuc2x1Y2VudCBzcGlubmVyIHNvXG4gICAgICAgICAgICAgICAgLy8gdGhlIGJsdXJyeSByZW5kZXIgaXNuJ3QgbWlzdGFrZW4gZm9yIHRoZSBmaW5hbCBpbWFnZS5cbiAgICAgICAgICAgICAgICByZWxlYXNlT3ZlcmxheSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2hhcnBlbmluZyA9IHRydWU7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHNoYXJwZW5TZXR0bGVkOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnQoKSkgcmV0dXJuOyAvLyBzdXBlcnNlZGVkIGJ5IGEgbmV3ZXIgaW1hZ2VcbiAgICAgICAgICAgICAgICB0aGlzLnNoYXJwZW5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZmluaXNoZWQ6IChfdmlhU21hbGwsIGxvZ1RhZykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNDdXJyZW50KCkpIHJldHVybjsgLy8gc3VwZXJzZWRlZCBieSBhIG5ld2VyIGltYWdlXG4gICAgICAgICAgICAgICAgLy8gSWRlbXBvdGVudCDigJQgcmVsZWFzZXMgbm93IGlmIHNtYWxsU2hvd24gZGVmZXJyZWQgaXQgKGNhY2hpbmcpIG9yIHdhcyBza2lwcGVkLlxuICAgICAgICAgICAgICAgIHJlbGVhc2VPdmVybGF5KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYXBwbHlSb2koKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2YXRlU2VsZWN0ZWRQbG90TW9kZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVPcGVuRGlhbG9nVG9vbCgpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGxvZ1RhZyk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHNoYXJwZW5GYWlsZWQ6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNDdXJyZW50KCkpIHJldHVybjsgLy8gc3VwZXJzZWRlZCBieSBhIG5ld2VyIGltYWdlXG4gICAgICAgICAgICAgICAgLy8gVGhlIHNtYWxsIHRpZXIgc3RheXMgb24gc2NyZWVuIGFzIHRoZSBmYWxsYmFjayDigJQgdGVsbCB0aGVcbiAgICAgICAgICAgICAgICAvLyB1c2VyIHRoZSBzaGFycGVyIHZlcnNpb24gaXNuJ3QgY29taW5nLlxuICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9IGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgZXJyPy5tZXNzYWdlIHx8IGVycj8uc3RhdHVzVGV4dCB8fCBTdHJpbmcoZXJyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgICAgICAgICAgICBrZXk6IHRoaXMudml6QWxlcnRUb2FzdEtleSxcbiAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnd2FybicsXG4gICAgICAgICAgICAgICAgICBzdW1tYXJ5OiAnUHJldmlldyBub3Qgc2hhcnBlbmVkJyxcbiAgICAgICAgICAgICAgICAgIGRldGFpbDogYFRoZSBmdWxsLXJlc29sdXRpb24gcHJldmlldyBkaWQgbm90IGxvYWQgKCR7bXNnfSkuIFRoZSBsb3ctcmVzb2x1dGlvbiBwcmV2aWV3IGlzIHN0aWxsIHNob3duLiBUcnkgY2xpY2tpbmcgdGhlIGltYWdlIGFnYWluLmAsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYXBwbHlSb2koKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2YXRlU2VsZWN0ZWRQbG90TW9kZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVPcGVuRGlhbG9nVG9vbCgpO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkucmVuZGVyKGltZ0luZm8sIHNtYWxsSW1nSW5mbyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgY29uc3QgbXNnID0gZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCBlcnI/Lm1lc3NhZ2UgfHwgZXJyPy5zdGF0dXNUZXh0IHx8IFN0cmluZyhlcnIpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cmVkIHdoZW4gZ2V0dGluZyBpbWFnZSBpbmZvJywgZXJyKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICAgIGtleTogdGhpcy52aXpBbGVydFRvYXN0S2V5LFxuICAgICAgICAgIHN0aWNreTogdHJ1ZSxcbiAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICBzdW1tYXJ5OiAnQW4gZXJyb3Igb2NjdXJlZCcsXG4gICAgICAgICAgZGV0YWlsOiBgVGhlIGZvbGxvd2luZyBlcnJvciBvY2N1cmVkIHdoaWxlIGdldHRpbmcgaW1hZ2UgaW5mbzogJHttc2d9LlxuICAgICAgICAgICAgICAgICAgIFBsZWFzZSB0cnkgdG8gb3BlbiB0aGUgaW1hZ2UgYWdhaW4gdGhyb3VnaCB0aGUgZmlsZSBuYXZpZ2F0b3IuYCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3RhY2tMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgdGhpcy5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVzZXQoKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5wbG90Q29udGV4dE1lbnVMaXN0ZW5lciA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgY29uc3QgcGxvdEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5wbG90RGl2TmFtZSk7XG4gICAgICBpZiAoIXBsb3RFbD8uY29udGFpbnMoZXZlbnQudGFyZ2V0IGFzIE5vZGUpKSByZXR1cm47XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLmNvbnRleHRNZW51SXRlbXMgPSB0aGlzLmJ1aWxkQ29udGV4dE1lbnVJdGVtcygpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHRoaXMuY29udGV4dE1lbnUuc2hvdyhldmVudCk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjb250ZXh0bWVudScsIHRoaXMucGxvdENvbnRleHRNZW51TGlzdGVuZXIsIHRydWUpO1xuXG4gICAgdGhpcy5rZXlkb3duTGlzdGVuZXIgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGlmICh0YXJnZXQudGFnTmFtZSA9PT0gJ0lOUFVUJyB8fCB0YXJnZXQudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyB8fCB0YXJnZXQuaXNDb250ZW50RWRpdGFibGUpIHJldHVybjtcbiAgICAgIC8vIFNBTSBwb2ludCBtb2RlOiBFbnRlciBjb21taXRzIHRoZSBvYmplY3QsIEVzYyBjbGVhcnMgdGhlIHByb21wdC5cbiAgICAgIGlmICh0aGlzLmFjdGl2ZURyYWdNb2RlID09PSAnc2FtUG9pbnQnICYmIChldmVudC5rZXkgPT09ICdFbnRlcicgfHwgZXZlbnQua2V5ID09PSAnRXNjYXBlJykpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInKSB0aGlzLnBsb3RTZXJ2aWNlLmNvbW1pdFNhbVBvaW50cygpO1xuICAgICAgICAgIGVsc2UgdGhpcy5wbG90U2VydmljZS5jbGVhclNhbVBvaW50cygpO1xuICAgICAgICAgIHRoaXMuaGlkZVNhbVRvYXN0KCk7IC8vIHByb21wdCByZXNvbHZlZCDihpIgZGlzbWlzcyB0aGUgc3RhdHVzIHRvYXN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBSZWdpb24gaGlzdG9yeSAoaml0LXVpIzg1KTogQ3RybC9DbWQrWiB1bmRvZXM7IEN0cmwvQ21kK1NoaWZ0K1ogb3JcbiAgICAgIC8vIEN0cmwvQ21kK1kgcmVkb2VzLlxuICAgICAgaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkge1xuICAgICAgICBjb25zdCBrID0gZXZlbnQua2V5LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChrID09PSAneicgJiYgIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy51bmRvUmVnaW9uKCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKGsgPT09ICd6JyAmJiBldmVudC5zaGlmdEtleSkgfHwgayA9PT0gJ3knKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5yZWRvUmVnaW9uKCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0RlbGV0ZScgfHwgZXZlbnQua2V5ID09PSAnQmFja3NwYWNlJyB8fCBldmVudC5rZXkgPT09ICdkJyB8fCBldmVudC5rZXkgPT09ICdEJykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5kZWxldGVSZWdpb24oKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJysnIHx8IGV2ZW50LmtleSA9PT0gJz0nKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnpvb21JbigpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSAnLScgfHwgZXZlbnQua2V5ID09PSAnXycpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuem9vbU91dCgpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSAncCcpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3BhbicpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSAnYicpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3pvb21Ub0JveCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSAncicpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2RyYXdyZWN0JykpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdmJykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZHJhd2Nsb3NlZHBhdGgnKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ3cnKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCd3YW5kJykpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdlJykge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZXJhc2VWZXJ0ZXgnKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ3MnKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdzZWxlY3QnKSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ2wnKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdkcmF3b3BlbnBhdGgnKSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMua2V5ZG93bkxpc3RlbmVyKTtcblxuICAgIHRoaXMud2hlZWxMaXN0ZW5lciA9IChldmVudDogV2hlZWxFdmVudCkgPT4ge1xuICAgICAgY29uc3QgcGxvdEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5wbG90RGl2TmFtZSk7XG4gICAgICBpZiAoIXBsb3RFbD8uY29udGFpbnMoZXZlbnQudGFyZ2V0IGFzIE5vZGUpKSByZXR1cm47XG4gICAgICAvLyBJbnRlcmNlcHRpbmcgaGVyZSBmaXJlcyBhIEZJWEVEIHpvb20gc3RlcCBwZXIgd2hlZWwgZXZlbnQsIHdoaWNoIGlzIGZhclxuICAgICAgLy8gdG9vIHNlbnNpdGl2ZSBmb3IgYSByZW5kZXJlciB0aGF0IHJlYWRzIHRoZSBzY3JvbGwgZGVsdGEg4oCUIHNvIGFueXRoaW5nXG4gICAgICAvLyBkcmF3biBieSBzdWNoIGEgcmVuZGVyZXIga2VlcHMgaXRzIG93biB3aGVlbC4gU2VlIGByZW5kZXJlck93bnNXaGVlbGAuXG4gICAgICBpZiAocmVuZGVyZXJPd25zV2hlZWwodGhpcy5iYXNlUGxvdFR5cGUpKSByZXR1cm47XG4gICAgICAvLyAzRCBwbG90IHR5cGVzIChzdXJmYWNlLCBzY2F0dGVyM2QsIGlzb3N1cmZhY2UpIHJlbmRlciBpbiBhIFBsb3RseSBzY2VuZVxuICAgICAgLy8gdGhhdCBvcmJpdHMvem9vbXMgbmF0aXZlbHkgb24gc2Nyb2xsLiBUaGUgMkQgc3RlcC16b29tIGRvZXNuJ3QgYXBwbHkgYW5kXG4gICAgICAvLyB3b3VsZCB0aHJvdyAobm8geGF4aXMgb24gYSBzY2VuZSksIHNvIGxldCBQbG90bHkgaGFuZGxlIHRoZSB3aGVlbC5cbiAgICAgIGlmICghdGhpcy5pc0hlYXRtYXApIHJldHVybjtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgIGlmIChldmVudC5kZWx0YVkgPCAwKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnpvb21JbigpKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQuZGVsdGFZID4gMCkge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy56b29tT3V0KCkpO1xuICAgICAgfVxuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3doZWVsJywgdGhpcy53aGVlbExpc3RlbmVyLCB7IGNhcHR1cmU6IHRydWUsIHBhc3NpdmU6IGZhbHNlIH0pO1xuXG4gICAgLy8gRHJhZyBoYW5kbGluZyBmb3IgdGhlIGZsb2F0aW5nIGludGVuc2l0eS1wcm9maWxlIHBhbmVsLlxuICAgIHRoaXMucHJvZmlsZURyYWdNb3ZlTGlzdGVuZXIgPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgaWYgKHRoaXMucHJvZmlsZVBhbmVsRHJhZ2dpbmcpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnByb2ZpbGVQYW5lbFBvcyA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMucHJvZmlsZVBhbmVsU3RhcnQueCArIChlLmNsaWVudFggLSB0aGlzLnByb2ZpbGVQYW5lbFN0YXJ0Lm14KSxcbiAgICAgICAgICAgIHk6IHRoaXMucHJvZmlsZVBhbmVsU3RhcnQueSArIChlLmNsaWVudFkgLSB0aGlzLnByb2ZpbGVQYW5lbFN0YXJ0Lm15KSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy50b29sYmFyRHJhZ2dpbmcpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnRvb2xiYXJQb3MgPSB7XG4gICAgICAgICAgICB4OiB0aGlzLnRvb2xiYXJTdGFydC54ICsgKGUuY2xpZW50WCAtIHRoaXMudG9vbGJhclN0YXJ0Lm14KSxcbiAgICAgICAgICAgIHk6IHRoaXMudG9vbGJhclN0YXJ0LnkgKyAoZS5jbGllbnRZIC0gdGhpcy50b29sYmFyU3RhcnQubXkpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5wcm9maWxlRHJhZ1VwTGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICB0aGlzLnByb2ZpbGVQYW5lbERyYWdnaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLnRvb2xiYXJEcmFnZ2luZyA9IGZhbHNlO1xuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMucHJvZmlsZURyYWdNb3ZlTGlzdGVuZXIpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5wcm9maWxlRHJhZ1VwTGlzdGVuZXIpO1xuXG4gICAgLy8gT24gYW55IHdpbmRvdyByZXNpemUsIHJlZmxvdyB0aGUgaW50ZW5zaXR5IGluc2V0IHRvIGl0cyAoZml4ZWQpIHBhbmVsIHNpemVcbiAgICAvLyBvbiB0aGUgbmV4dCBmcmFtZSwgb25jZSBsYXlvdXQgaGFzIHNldHRsZWQuIFdpdGhvdXQgdGhpcyB0aGUgaW5zZXQgY2FuIGJlXG4gICAgLy8gbGVmdCBhdCBhIHN0YWxlL3plcm8gc2l6ZSBieSBhIG1pZC1yZWZsb3cgcmVzaXplIGFuZCBzdG9wIHNob3dpbmcuXG4gICAgdGhpcy5wcm9maWxlUmVzaXplTGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuaGFzUHJvZmlsZXMpIHJldHVybjtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLnJlbmRlckludGVuc2l0eUluc2V0KCkpO1xuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMucHJvZmlsZVJlc2l6ZUxpc3RlbmVyKTtcbiAgfVxuXG4gIG9uUHJvZmlsZVBhbmVsRHJhZ1N0YXJ0KGU6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLnByb2ZpbGVQYW5lbERyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLnByb2ZpbGVQYW5lbFN0YXJ0ID0ge1xuICAgICAgbXg6IGUuY2xpZW50WCxcbiAgICAgIG15OiBlLmNsaWVudFksXG4gICAgICB4OiB0aGlzLnByb2ZpbGVQYW5lbFBvcy54LFxuICAgICAgeTogdGhpcy5wcm9maWxlUGFuZWxQb3MueSxcbiAgICB9O1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIC8qKiBHcmFiIHRoZSB0b29sYmFyIGhhbmRsZTogZGV0YWNoIGl0IGludG8gYSBmbG9hdGluZyB3aW5kb3cgKGlmIHN0aWxsIGRvY2tlZClcbiAgICogIGFuZCBzdGFydCBkcmFnZ2luZy4gKi9cbiAgb25Ub29sYmFyRHJhZ1N0YXJ0KGU6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMudG9vbGJhckZsb2F0aW5nKSB7XG4gICAgICB0aGlzLnRvb2xiYXJGbG9hdGluZyA9IHRydWU7XG4gICAgICB0aGlzLnRvb2xiYXJQb3MgPSB7IHg6IDgsIHk6IDggfTtcbiAgICB9XG4gICAgdGhpcy50b29sYmFyRHJhZ2dpbmcgPSB0cnVlO1xuICAgIHRoaXMudG9vbGJhclN0YXJ0ID0ge1xuICAgICAgbXg6IGUuY2xpZW50WCxcbiAgICAgIG15OiBlLmNsaWVudFksXG4gICAgICB4OiB0aGlzLnRvb2xiYXJQb3MueCxcbiAgICAgIHk6IHRoaXMudG9vbGJhclBvcy55LFxuICAgIH07XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgLyoqIFNuYXAgdGhlIGZsb2F0aW5nIHRvb2xiYXIgYmFjayB0byBpdHMgZG9ja2VkIHBvc2l0aW9uIGFjcm9zcyB0aGUgdG9wLiAqL1xuICBkb2NrVG9vbGJhcigpIHtcbiAgICB0aGlzLnRvb2xiYXJGbG9hdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIFJlbmRlciB0aGUgaW50ZW5zaXR5IGluc2V0IGNoYXJ0IGZyb20gdGhlIGxhdGVzdCBwcm9maWxlIGRhdGEuIFRoZSBhY3R1YWxcbiAgICogIGNoYXJ0aW5nIGlzIG93bmVkIGJ5IHRoZSB2aXN1YWxpemVyIHNlcnZpY2Ug4oCUIHRoZSBjb21wb25lbnQganVzdCBkZWNpZGVzXG4gICAqICB3aGVuIChwcm9maWxlIG1vZGUgKyBhIGZyZXNoIHByb2ZpbGUpLiAqL1xuICBwcml2YXRlIHJlbmRlckludGVuc2l0eUluc2V0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5oYXNQcm9maWxlcykgcmV0dXJuO1xuICAgIHRoaXMucGxvdFNlcnZpY2UucmVuZGVySW50ZW5zaXR5SW5zZXQodGhpcy5pbnRlbnNpdHlJbnNldERpdiwgdGhpcy5sYXRlc3RQcm9maWxlcyk7XG4gIH1cblxuICAvKiogVG9vbGJhciBcIkludGVuc2l0eVwiIGdyb3VwOiBhZGQgYW5vdGhlciBsaW5lIFJPSSAobmV4dCBicmlnaHQgY29sb3VyKS4gKi9cbiAgYXN5bmMgYWRkUHJvZmlsZUxpbmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gUGFyayB0aGUgZmxvYXRpbmcgaW5zZXQgbmVhciB0aGUgcGxvdCdzIHRvcC1yaWdodCB3aGVuIHRoZSBmaXJzdCBsaW5lIGlzXG4gICAgLy8gYWRkZWQgKGl0J3MgcG9zaXRpb246Zml4ZWQsIHNvIHVzZSB2aWV3cG9ydCBjb29yZHMgZnJvbSB0aGUgcGxvdCByZWN0KS5cbiAgICBpZiAoIXRoaXMuaGFzUHJvZmlsZXMpIHtcbiAgICAgIGNvbnN0IHJlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnBsb3REaXZOYW1lKT8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB0aGlzLnByb2ZpbGVQYW5lbFBvcyA9IHJlY3RcbiAgICAgICAgPyB7IHg6IE1hdGgubWF4KDEwLCByZWN0LnJpZ2h0IC0gMzAwKSwgeTogcmVjdC50b3AgKyAxMCB9XG4gICAgICAgIDogeyB4OiAyMCwgeTogNzAgfTtcbiAgICB9XG4gICAgLy8gSW1hZ2UgKE9TRCkgbW9kZTogUGxvdGx5IG5ldmVyIHJlbmRlcmVkLCBzbyBpdCBoYXMgbm8gcGl4ZWwgY2FjaGUgLyBleHRlbnQuXG4gICAgLy8gTG9hZCB0aGUgY3VycmVudCBzbGljZSdzIGZyYW1lcyBmb3Igc2FtcGxpbmcgKyBsaW5lIHBsYWNlbWVudCBmaXJzdC5cbiAgICBpZiAodGhpcy5pc0ltYWdlVmlldyAmJiB0aGlzLmltYWdlSW5mbykge1xuICAgICAgYXdhaXQgdGhpcy5wbG90U2VydmljZS5lbnN1cmVJbnRlbnNpdHlTYW1wbGluZyh0aGlzLmltYWdlSW5mbywgdGhpcy56SW5kZXgpO1xuICAgIH1cbiAgICBjb25zdCByZWdpb24gPSB0aGlzLnBsb3RTZXJ2aWNlLmdldEludGVuc2l0eUNvbnRyb2xzKCk/LmFkZFByb2ZpbGVMaW5lKCk7XG4gICAgLy8gQXV0by1zZWxlY3QgdGhlIG5ldyBsaW5lIG9uIHRoZSBhY3RpdmUgYmFja2VuZCAoUGxvdGx5IGhhbmRsZXMgLyBPU0RcbiAgICAvLyBoaWdobGlnaHQpIHNvIGl0J3MgcmVhZHkgdG8gbW92ZSBvciBkZWxldGUgaW1tZWRpYXRlbHkuXG4gICAgaWYgKHJlZ2lvbikge1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZWxlY3RSZWdpb24ocmVnaW9uKTtcbiAgICAgIC8vIE9TRCBvbmx5IGRyYXdzIGEgc2VsZWN0ZWQgcmVnaW9uJ3MgaGFuZGxlcyBpbiBhbiBlZGl0IG1vZGUsIHNvIGEgbGluZSBpblxuICAgICAgLy8gJ25vbmUnIG1vZGUgbG9va3MgdW5zZWxlY3RlZC4gU3dpdGNoIHRvICdzZWxlY3QnIHNvIHRoZSBuZXcgbGluZSBzaG93c1xuICAgICAgLy8gaXRzIGVuZHBvaW50IGhhbmRsZXMgYW5kIGNhbiBiZSBkcmFnZ2VkL2RlbGV0ZWQgcmlnaHQgYXdheS5cbiAgICAgIGlmICh0aGlzLmlzSW1hZ2VWaWV3ICYmIHRoaXMuYWN0aXZlRHJhZ01vZGUgIT09ICdzZWxlY3QnKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3NlbGVjdCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vIEEgY29udHJpYnV0ZWQgbW9kZSdzIHNlc3Npb24gZW5kcyBmaXJzdCwgd2hpbGUgdGhlIHZpZXdlciBpdCBkcmV3IG92ZXJcbiAgICAvLyBzdGlsbCBleGlzdHMuIFRoZSBwYW5lbCBnb2VzIHdpdGggdGhpcyB2aWV3LCBzbyBubyBjaGFuZ2UgZGV0ZWN0aW9uLlxuICAgIHRoaXMuZGVzdHJveWluZyA9IHRydWU7XG4gICAgdGhpcy5wbG90TW9kZXMuZGVhY3RpdmF0ZSgpO1xuICAgIHRoaXMudG9vbERpYWxvZ3MuZGVhY3RpdmF0ZSgpO1xuICAgIC8vIExlYXZlIHRoZSBsaXZlIHNldCBzbyB0aGUgbmV4dC1vbGRlc3QgdmlzdWFsaXplciBwaWNrcyB1cCB0aGUgb3V0bGV0cy5cbiAgICBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMuZGVsZXRlKHRoaXMpO1xuICAgIHRoaXMucmV2b2tlVm9sdW1lSW1hZ2VVcmxzKCk7XG4gICAgdGhpcy5zY3J1YmJlci5jYW5jZWwoKTtcbiAgICB0aGlzLnNhbVBvaW50U3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMucGxvdENvbnRleHRNZW51TGlzdGVuZXIpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdjb250ZXh0bWVudScsIHRoaXMucGxvdENvbnRleHRNZW51TGlzdGVuZXIsIHRydWUpO1xuICAgIH1cbiAgICBpZiAodGhpcy5rZXlkb3duTGlzdGVuZXIpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5rZXlkb3duTGlzdGVuZXIpO1xuICAgIH1cbiAgICBpZiAodGhpcy53aGVlbExpc3RlbmVyKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2hlZWwnLCB0aGlzLndoZWVsTGlzdGVuZXIsIHRydWUpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcm9maWxlRHJhZ01vdmVMaXN0ZW5lcikge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMucHJvZmlsZURyYWdNb3ZlTGlzdGVuZXIpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcm9maWxlRHJhZ1VwTGlzdGVuZXIpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5wcm9maWxlRHJhZ1VwTGlzdGVuZXIpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcm9maWxlUmVzaXplTGlzdGVuZXIpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLnByb2ZpbGVSZXNpemVMaXN0ZW5lcik7XG4gICAgfVxuICAgIGlmICh0aGlzLmludGVuc2l0eVByb2ZpbGVTdWIpIHtcbiAgICAgIHRoaXMuaW50ZW5zaXR5UHJvZmlsZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy52aWV3cG9ydENoYW5nZVN1Yikge1xuICAgICAgdGhpcy52aWV3cG9ydENoYW5nZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLnVuc3ViLm5leHQoKTtcbiAgICB0aGlzLnVuc3ViLmNvbXBsZXRlKCk7XG4gICAgaWYgKHRoaXMucHJldmlld1N1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5wcmV2aWV3U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNwYXRpYWxEYXRhc2V0U3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnNwYXRpYWxEYXRhc2V0U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnBsb3RXaWR0aFN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5wbG90V2lkdGhTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaW1hZ2VMb2FkaW5nU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmltYWdlTG9hZGluZ1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pbWdMb2FkaW5nTWVzc2FnZVN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5pbWdMb2FkaW5nTWVzc2FnZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc1pvb21TdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuaXNab29tU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmF1dG9zY2FsZVN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5hdXRvc2NhbGVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZmlsZW5hbWVTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuZmlsZW5hbWVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5wbG90U2VydmljZS51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHVibGljIGhhc1JlZ2lvbnMoKTogYm9vbGVhbiB7XG4gICAgLy8gVXNlIHRoZSBjb250cmFjdCdzIGZyYW1ld29yay1uZXV0cmFsIHJlZ2lvbiBhY2Nlc3Nvciwgbm90IHRoZSByYXdcbiAgICAvLyBQbG90bHktc2hhcGVkIGdldFNoYXBlcygpIOKAlCB0aGUgY29tcG9uZW50IG9ubHkgbmVlZHMgdG8ga25vdyB3aGV0aGVyIGFueVxuICAgIC8vIHJlZ2lvbiBleGlzdHMsIGFuZCBtdXN0IG5vdCBkZXBlbmQgb24gYSBiYWNrZW5kJ3Mgd2lyZSBmb3JtYXQuXG4gICAgcmV0dXJuIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGluIG1haW5GYWNhZGUuY29uZmlnUmVxdWVzdCgpIC0gRE8gTk9UIERFTEVURVxuICAgKi9cbiAgcHVibGljIGdldFJlZ2lvblBvbHlnb25zKCk6IFBvbHlnb25bXSB7XG4gICAgcmV0dXJuIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9uUG9seWdvbnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgdGhlIGNvbG9yIHNjYWxlIHR5cGU6IGNhbGxlZCBieSB0aGUgY29sb3Igc2NhbGUgc2VsZWN0IGJ1dHRvblxuICAgKiBAcGFyYW0gZXZlbnRcbiAgICovXG4gIHRvZ2dsZVJldmVyc2VTY2FsZSgpIHtcbiAgICB0aGlzLnJldmVyc2VzY2FsZSA9ICF0aGlzLnJldmVyc2VzY2FsZTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFJldmVyc2VTY2FsZSh0aGlzLnJldmVyc2VzY2FsZSk7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IGEgY29sb3IgbWFwOiBjYWxsZWQgYnkgdGhlIGNvbG9yIG1hcCBkcm9wZG93biBidXR0b25cbiAgICogQHBhcmFtIGNvbG9ybWFwTm9kZVxuICAgKi9cbiAgc2VsZWN0Q29sb3JtYXAoY29sb3JtYXBOb2RlOiBUcmVlTm9kZSkge1xuICAgIGlmICghY29sb3JtYXBOb2RlLmNoaWxkcmVuKSB7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldENvbG9ybWFwKGNvbG9ybWFwTm9kZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIE9wZW4gdGhlIENoYW5uZWxzICYgSGlzdG9ncmFtIGRpYWxvZyAodG9vbGJhciBidXR0b24pLiAqL1xuICBvcGVuQ2hhbm5lbEhpc3RvZ3JhbSgpIHtcbiAgICB0aGlzLnNob3dDaGFubmVsSGlzdG9ncmFtID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBUb29sYmFyIOKGkiBvcGVuIHRoZSBzcGF0aWFsLW9taWNzIGNvbnRyb2xzLiAqL1xuICBvcGVuU3BhdGlhbENvbnRyb2xzKCk6IHZvaWQge1xuICAgIHRoaXMuc2hvd1NwYXRpYWxDb250cm9scyA9IHRydWU7XG4gIH1cblxuICAvKiogT3BlbiB0aGUgUmVnaW9uIEVkaXRvciBkaWFsb2cgKHRvb2xiYXIgYnV0dG9uKS4gVGhlIGVkaXRvciBzdGF5cyBsaW5rZWQgdG9cbiAgICogIHRoaXMgcGxvdHRpbmcgaW5zdGFuY2UgdGhyb3VnaCB0aGUgcm9vdCBSZWdpb25TdG9yZSBzaW5nbGV0b24sIHNvIGl0IHdvcmtzXG4gICAqICB0aGUgc2FtZSBhcyB0aGUgZm9ybWVyIHJpZ2h0LXBhbmVsIFJlZ2lvbnMgdGFiLiAqL1xuICBvcGVuUmVnaW9uRWRpdG9yKCkge1xuICAgIC8vIFNpemUgdGhlIGRpYWxvZyB0byBtYXRjaCB0aGUgaG9zdCdzIGNvbmZpZ3VyZWQgZWxlbWVudCAoZS5nLiB0aGUgYXBwJ3NcbiAgICAvLyByaWdodCBwYW5lbCkgYXQgb3BlbiB0aW1lLiBNZWFzdXJlZCBvbmNlIOKAlCBpdCBpbnRlbnRpb25hbGx5IGRvZXMgbm90XG4gICAgLy8gdHJhY2sgbGF0ZXIgYnJvd3Nlci9zcGxpdCByZXNpemVzLiBGYWxscyBiYWNrIHRvIGEgcXVhcnRlciBvZiB0aGUgcGFnZVxuICAgIC8vIHdoZW4gbm8gc2VsZWN0b3IgaXMgY29uZmlndXJlZCBvciB0aGUgZWxlbWVudCBpc24ndCBwcmVzZW50LlxuICAgIGNvbnN0IHNlbGVjdG9yID0gdGhpcy52aXpDb25maWc/LnJlZ2lvbkVkaXRvcldpZHRoU2VsZWN0b3I7XG4gICAgY29uc3Qgd2lkdGggPSBzZWxlY3RvclxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihzZWxlY3Rvcik/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJlZ2lvbkVkaXRvcldpZHRoID0gd2lkdGggJiYgd2lkdGggPiAwID8gYCR7TWF0aC5yb3VuZCh3aWR0aCl9cHhgIDogJzI1dncnO1xuICAgIHRoaXMuc2hvd1JlZ2lvbkVkaXRvciA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIGJ5IHRoZSBzdGFjay9zaW5nbGUgaW1hZ2UgZHJvcGRvd24gYnV0dG9uXG4gICAqIEBwYXJhbSBzaG93c3RhY2tcbiAgICovXG4gIHNlbGVjdFN0YWNrT3B0aW9uKHNlbGVjdGVkU3RhY2tPcHRpb246IGFueSkge1xuICAgIGNvbnN0IHNob3dzdGFjayA9IHNlbGVjdGVkU3RhY2tPcHRpb24udmFsID09PSAndHJ1ZSc7XG4gICAgdGhpcy5zZWxlY3RlZFN0YWNrT3B0aW9uID0gc2VsZWN0ZWRTdGFja09wdGlvbjtcbiAgICBjb25zb2xlLmxvZygnc2VsZWN0ZWQgc3RhY2sgb3B0aW9uJyArIEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRTdGFja09wdGlvbikpO1xuICAgIHRoaXMuc3RhY2tMb2FkaW5nID0gc2hvd3N0YWNrO1xuICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKCFzaG93c3RhY2spO1xuICAgIC8vIFN0YWNrIG1vZGUgaXMgYWx3YXlzIGEgMkQgaGVhdG1hcCDigJQgcmVzZXQgc3VyZmFjZSBtb2RlIGlmIGFjdGl2ZVxuICAgIGlmICghdGhpcy5pc0hlYXRtYXApIHtcbiAgICAgIHRoaXMuaXNIZWF0bWFwID0gdHJ1ZTtcbiAgICAgIHRoaXMucGxvdFR5cGUgPSBQbG90VHlwZS5IRUFUTUFQO1xuICAgICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSBQbG90VHlwZS5IRUFUTUFQO1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0aGlzLnBsb3RUeXBlKTtcbiAgICB9XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTaG93U3RhY2soc2hvd3N0YWNrKTtcbiAgfVxuXG4gIHVwZGF0ZVpJbmRleCh1cmxzPzogc3RyaW5nW10pIHtcbiAgICBpZiAodGhpcy56SW5kZXggPiB0aGlzLm1heEluZGV4KSB7XG4gICAgICB0aGlzLnpJbmRleCA9IHRoaXMubWF4SW5kZXg7XG4gICAgfVxuICAgIGlmICh0aGlzLnpJbmRleCA8IDApIHtcbiAgICAgIHRoaXMuekluZGV4ID0gMDtcbiAgICB9XG4gICAgaWYgKHVybHMpIHtcbiAgICAgIGlmICh0aGlzLnpJbmRleCA+IHVybHM/Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLnpJbmRleCA9IDA7XG4gICAgICAgIHRoaXMubWF4SW5kZXggPSB1cmxzLmxlbmd0aCAtIDE7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0WkluZGV4KHRoaXMuekluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXZlIHotc2xpY2Ugc2NydWIgZm9yIHRoZSBJbWFnZSB2aWV3OiB0aGUgcmVuZGVyZXIgc3dhcHMgdGhlIGRpc3BsYXllZFxuICAgKiBzbGljZSBpbiBwbGFjZSAobm8gcmUtbW91bnQpLCBzbyBkcmFnZ2luZyB0aGUgc2xpZGVyIHN0ZXBzIHRocm91Z2ggdGhlXG4gICAqIHN0YWNrIHRoZSBzYW1lIHdheSB0aGUgaGVhdG1hcCBmcmFtZSBzbGlkZXIgZG9lcy5cbiAgICovXG4gIG9uWlNsaWRlKHo6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIGlmICh6ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICB0aGlzLnpJbmRleCA9IHo7XG4gICAgdGhpcy5zY3J1YmJlci5jb21taXQoeik7XG4gICAgLy8gS2VlcCB0aGUgaW50ZW5zaXR5IGluc2V0IGluIHN5bmMgd2l0aCB0aGUgZGlzcGxheWVkIHNsaWNlIChJbWFnZS9PU0QgbW9kZSxcbiAgICAvLyB3aGVyZSB0aGUgcHJvZmlsZSBzYW1wbGVyIGlzIGZlZCBmcm9tIHRoZSBsb2FkZWQgcHJldmlldyBmcmFtZXMpLlxuICAgIGlmICh0aGlzLmhhc1Byb2ZpbGVzICYmIHRoaXMuaXNJbWFnZVZpZXcgJiYgdGhpcy5pbWFnZUluZm8pIHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UuZW5zdXJlSW50ZW5zaXR5U2FtcGxpbmcodGhpcy5pbWFnZUluZm8sIHopO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXZlIChkZWJvdW5jZWQpIHNjcnViIHdoaWxlIGRyYWdnaW5nIHRoZSBJbWFnZS12aWV3IHotc2xpZGVyOiB1cGRhdGUgdGhlXG4gICAqIHNsaWNlIGFzIHRoZSB1c2VyIGRyYWdzLCBidXQgY29hbGVzY2UgcmFwaWQgY2hhbmdlcyBzbyB3ZSBkb24ndCBmaXJlIGFcbiAgICogc2xpY2Ugc3dhcCBvbiBldmVyeSBwaXhlbC4gVGhlIGZpbmFsIHZhbHVlIGFsc28gbGFuZHMgdmlhIG9uWlNsaWRlIChvblNsaWRlRW5kKS5cbiAgICovXG4gIG9uWlNjcnViKHo6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIGlmICh6ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICB0aGlzLnpJbmRleCA9IHo7XG4gICAgdGhpcy5zY3J1YmJlci5zY3J1Yih6KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBLZXlib2FyZCBzdGFjayBuYXZpZ2F0aW9uOiDihpAv4oaSIHN0ZXAgdGhlIHotc2xpY2UgaW4gdGhlIEltYWdlIHZpZXcsIHRoZSBzYW1lXG4gICAqIHdheSB0aGUgc2xpZGVyIGRvZXMuIE9ubHkgYWN0aXZlIGZvciBhIGxvYWRlZCBzdGFjayBpbiBJbWFnZSB2aWV3LCBhbmRcbiAgICogaWdub3JlZCB3aGlsZSBhIGZvcm0gZmllbGQgaXMgZm9jdXNlZCBzbyB0eXBpbmcgaXNuJ3QgaGlqYWNrZWQuIFVwL0Rvd24gYXJlXG4gICAqIGxlZnQgdG8gT3BlblNlYWRyYWdvbiAocGFubmluZykuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bicsIFsnJGV2ZW50J10pXG4gIG9uS2V5ZG93bihlOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGUua2V5ICE9PSAnQXJyb3dMZWZ0JyAmJiBlLmtleSAhPT0gJ0Fycm93UmlnaHQnKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmltYWdlSW5mbz8uaXNTdGFjayB8fCAhdGhpcy5pc0ltYWdlVmlldykgcmV0dXJuO1xuICAgIGNvbnN0IHQgPSBlLnRhcmdldCBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKHQgJiYgKC9eKElOUFVUfFRFWFRBUkVBfFNFTEVDVCkkLy50ZXN0KHQudGFnTmFtZSkgfHwgdC5pc0NvbnRlbnRFZGl0YWJsZSkpIHJldHVybjtcbiAgICAvLyBUaGUgc2xpY2Ugc2xpZGVyIGhhbmRsZXMgYXJyb3dzIG5hdGl2ZWx5IHdoZW4gZm9jdXNlZCAoYWxzbyBhICsxIHN0ZXApIOKAlFxuICAgIC8vIHNraXAgaGVyZSBzbyB3ZSBkb24ndCBkb3VibGUtc3RlcCBpdC5cbiAgICBpZiAodCAmJiAodC5nZXRBdHRyaWJ1dGUoJ3JvbGUnKSA9PT0gJ3NsaWRlcicgfHwgdC5jbG9zZXN0KCcucC1zbGlkZXInKSkpIHJldHVybjtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zdGVwU2xpY2UoZS5rZXkgPT09ICdBcnJvd1JpZ2h0JyA/IDEgOiAtMSk7XG4gIH1cblxuICAvKiogTW92ZSB0aGUgZGlzcGxheWVkIHNsaWNlIGJ5IGBkZWx0YWAsIGNsYW1wZWQgdG8gdGhlIHN0YWNrIGJvdW5kcy4gKi9cbiAgc3RlcFNsaWNlKGRlbHRhOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gTWF0aC5taW4odGhpcy5tYXhJbmRleCwgTWF0aC5tYXgoMCwgdGhpcy56SW5kZXggKyBkZWx0YSkpO1xuICAgIGlmIChuZXh0ID09PSB0aGlzLnpJbmRleCkgcmV0dXJuO1xuICAgIHRoaXMub25aU2xpZGUobmV4dCk7XG4gIH1cblxuICByZWxvYWRBbmRQbG90KCkge1xuICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKHRydWUpO1xuICAgIC8vIFJlLWRyaXZlIHRoZSByZW5kZXIgcGlwZWxpbmUgZnJvbSB0aGUgY3VycmVudCBpbWFnZSBpbmZvICh0aGUgc291cmNlIG9mXG4gICAgLy8gdHJ1dGgsIHdpdGggcmVhbCB1cmxzL2ZpbGVOYW1lKS4gRG9uJ3QgdXNlIHBsb3RTZXJ2aWNlLnJlbG9hZEFuZFBsb3QoKTpcbiAgICAvLyB0aGF0IHJlYnVpbGRzIHRoZSBpbmZvIGZyb20gdGhlIHJlbmRlcmVyJ3MgaW50ZXJuYWwgc3RhdGUsIHdoaWNoIGNhbiBiZVxuICAgIC8vIHN0YWxlIChlLmcuIGFmdGVyIHN3aXRjaGluZyBwbG90IHR5cGUgSW1hZ2UgLT4gSGVhdG1hcCkgYW5kIHJlLWVtaXRcbiAgICAvLyBlbXB0eS9vbGQgdXJscywgZmFpbGluZyB0byBoYW5kIHRoZSBkaXYgb3ZlciB0byB0aGUgbmV3IHJlbmRlcmVyLlxuICAgIGlmICh0aGlzLmltYWdlSW5mbykge1xuICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUluZm8odGhpcy5pbWFnZUluZm8pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlbG9hZEFuZFBsb3QoKTtcbiAgICB9XG4gIH1cbiAgY2FuY2VsTG9hZGluZygpIHtcbiAgICAvLyBTdG9wIGFueSBpbi1mbGlnaHQgZnJhbWUgc3RyZWFtaW5nIChuYXBhcmktanMgdm9sdW1lL3N1cmZhY2UgcHJlbG9hZCkgc28gdGhlIGZldGNoIGxvb3BzXG4gICAgLy8gYWN0dWFsbHkgYWJvcnQg4oCUIGNsZWFyaW5nIHRoZSBmbGFnIGFsb25lIG9ubHkgcm91dGVkIHRvIFBsb3RseSBhbmQgbGVmdCBuYXBhcmkgZmV0Y2hpbmcuXG4gICAgdGhpcy5wbG90U2VydmljZS5jYW5jZWxMb2FkaW5nPy4oKTtcbiAgICB0aGlzLnN0YWNrTG9hZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuaW1nTG9hZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICB0aGlzLnpJbmRleCA9IDA7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRaSW5kZXgodGhpcy56SW5kZXgpO1xuICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U3RhY2tMb2FkaW5nKGZhbHNlKTtcbiAgfVxuXG4gIGRvd25sb2FkSW1hZ2UoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5kb3dubG9hZEltYWdlKCk7XG4gIH1cblxuICBhdXRvc2NhbGVJbWFnZSgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmF1dG9zY2FsZSgpO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIgcGl4ZWwvc21vb3RoIHRvZ2dsZTogZmxpcCBzbW9vdGhpbmcgYW5kIGFwcGx5IHRvIHRoZSBhY3RpdmUgYmFja2VuZC4gKi9cbiAgb25Ub2dnbGVJbWFnZVNtb290aGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZCA9ICF0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZDtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldEltYWdlU21vb3RoaW5nRW5hYmxlZCh0aGlzLmltYWdlU21vb3RoaW5nRW5hYmxlZCk7XG4gIH1cblxuICByZXNldEF4ZXMoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5yZXNldEF4ZXMoKTtcbiAgfVxuXG4gIHRvZ2dsZURyYWdNb2RlKG1vZGU6IHN0cmluZykge1xuICAgIC8vIEEgdG9vbCBwaWNrZWQgYnkgdGhlIHVzZXIgaXMgYWx3YXlzIHRoZSBwbGFpbiB0b29sLCBuZXZlciBhIHBsb3QgbW9kZSdzXG4gICAgLy8gYnJ1c2ggY2xhc3MuXG4gICAgdGhpcy5icnVzaENsYXNzID0gbnVsbDtcbiAgICAvLyBUb2dnbGUgb2ZmIGlmIHRoZSBzYW1lIG1vZGUgaXMgcmUtc2VsZWN0ZWQuXG4gICAgdGhpcy5hcHBseURyYWdNb2RlKHRoaXMuYWN0aXZlRHJhZ01vZGUgPT09IG1vZGUgPyBudWxsIDogbW9kZSk7XG4gIH1cblxuICAvKiogQXJtIGBtb2RlYCAob3Igbm90aGluZykgYWNyb3NzIGV2ZXJ5IHRvb2wsIGtlZXBpbmcgdGhlIHRvb2xiYXIgaW4gc3RlcC4gKi9cbiAgcHJpdmF0ZSBhcHBseURyYWdNb2RlKG1vZGU6IHN0cmluZyB8IG51bGwpIHtcbiAgICB0aGlzLmFjdGl2ZURyYWdNb2RlID0gbW9kZTtcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLmFjdGl2ZURyYWdNb2RlO1xuICAgIC8vIFJlY29yZCB0aGUgYXJtZWQgdG9vbCBpbiB0aGUgc2hhcmVkIHNlc3Npb24gc3RvcmUuXG4gICAgdGhpcy5zZXNzaW9uLnNldEFjdGl2ZVRvb2woYWN0aXZlKTtcblxuICAgIC8vIFJlZ2lvbiBkcmF3L3NlbGVjdCBydW4gdGhyb3VnaCB0aGUgcmVuZGVyZXIncyByZWdpb24gb3ZlcmxheS5cbiAgICB0aGlzLnBsb3RTZXJ2aWNlXG4gICAgICAuZ2V0UmVnaW9uT3ZlcmxheSgpXG4gICAgICA/LnNldE1vZGUodGhpcy5pc1JlZ2lvbk1vZGUoYWN0aXZlKSA/IChhY3RpdmUgYXMgUmVnaW9uVG9vbE1vZGUpIDogJ25vbmUnKTtcblxuICAgIC8vIFZpZXdwb3J0IGRyYWcgbW9kZXMgKHBhbi9ib3gtem9vbSkuIFJlZ2lvbiBtb2RlcyBvd24gdGhlIGRyYWcgbW9kZSB2aWFcbiAgICAvLyB0aGUgb3ZlcmxheSwgc28gZG9uJ3QgYWxzbyBzZXQgb25lIGhlcmUuXG4gICAgaWYgKCF0aGlzLmlzUmVnaW9uTW9kZShhY3RpdmUpKSB7XG4gICAgICBjb25zdCB2aWV3cG9ydERyYWcgPSBhY3RpdmUgPT09ICdwYW4nIHx8IGFjdGl2ZSA9PT0gJ3pvb20nO1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZXREcmFnTW9kZSh2aWV3cG9ydERyYWcgPyBhY3RpdmUgOiBmYWxzZSk7XG4gICAgfVxuXG4gICAgLy8gT24tY2FudmFzIHRvb2wgb3ZlcmxheXMuXG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRab29tVG9Cb3hNb2RlKGFjdGl2ZSA9PT0gJ3pvb21Ub0JveCcpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0V2FuZE1vZGUoYWN0aXZlID09PSAnd2FuZCcsIHsgc2Vuc2l0aXZpdHk6IHRoaXMud2FuZFNlbnNpdGl2aXR5IH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0QnJ1c2hNb2RlKGFjdGl2ZSA9PT0gJ2JydXNoJywgeyBzaXplOiB0aGlzLmJydXNoU2l6ZSwgLi4udGhpcy5icnVzaENsYXNzIH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2FtUG9pbnRNb2RlKGFjdGl2ZSA9PT0gJ3NhbVBvaW50Jyk7XG4gICAgLy8gTGVhdmluZyBwb2ludCBtb2RlIGRpc21pc3NlcyBhbnkgbGluZ2VyaW5nIHN0YXR1cyB0b2FzdC5cbiAgICBpZiAoYWN0aXZlICE9PSAnc2FtUG9pbnQnKSB0aGlzLmhpZGVTYW1Ub2FzdCgpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0VmVydGV4RXJhc2VyTW9kZShhY3RpdmUgPT09ICdlcmFzZVZlcnRleCcpO1xuICAgIGlmIChhY3RpdmUgPT09ICdlcmFzZVZlcnRleCcpIHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0VmVydGV4RXJhc2VyUmFkaXVzKHRoaXMudmVydGV4RXJhc2VyUmFkaXVzKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVnaW9uIGRyYXcvc2VsZWN0L2VkaXQgbW9kZXMgcm91dGVkIHRocm91Z2ggdGhlIHJlZ2lvbiBvdmVybGF5LiBUaGVcbiAgICogIFRoZSB2ZXJ0ZXggdG9vbHMgKGRyYXdwb2x5Z29uL2FkZHBvaW50L2RlbGV0ZXBvaW50L21vdmUpIGFyZVxuICAgKiAgaGFuZGxlZCBieSB0aGUgT3BlblNlYWRyYWdvbiBvdmVybGF5OyBQbG90bHkncyBvdmVybGF5IG1hcHMgdGhlbSB0byBuby1vcC4gKi9cbiAgcHJpdmF0ZSBpc1JlZ2lvbk1vZGUobW9kZTogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBtb2RlID09PSAnZHJhd3JlY3QnIHx8XG4gICAgICBtb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnIHx8XG4gICAgICBtb2RlID09PSAnZHJhd29wZW5wYXRoJyB8fFxuICAgICAgbW9kZSA9PT0gJ3NlbGVjdCcgfHxcbiAgICAgIG1vZGUgPT09ICdkcmF3cG9seWdvbicgfHxcbiAgICAgIG1vZGUgPT09ICdhZGRwb2ludCcgfHxcbiAgICAgIG1vZGUgPT09ICdkZWxldGVwb2ludCcgfHxcbiAgICAgIG1vZGUgPT09ICdtb3ZlJ1xuICAgICk7XG4gIH1cblxuICAvKiogTGl2ZS11cGRhdGUgdGhlIGlzb3N1cmZhY2UgYXMgdGhlIHJhbmdlIHNsaWRlciBtb3Zlcy4gVGhlIGNvbnRyb2wgaXMgb25seVxuICAgKiAgYXZhaWxhYmxlIHdoZW4gdGhlIGFjdGl2ZSBiYWNrZW5kIHJlbmRlcnMgaXNvc3VyZmFjZXMgKElTT1NVUkZBQ0UgbW9kZSkuICovXG4gIG9uSXNvUmFuZ2VDaGFuZ2UodmFsdWVzOiBudW1iZXJbXSB8IHVuZGVmaW5lZCkge1xuICAgIGlmICghdmFsdWVzIHx8IHZhbHVlcy5sZW5ndGggPCAyKSByZXR1cm47XG4gICAgdGhpcy5pc29SYW5nZSA9IHZhbHVlcztcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldElzb3N1cmZhY2VDb250cm9scygpPy5zZXRJc29SYW5nZSh2YWx1ZXNbMF0sIHZhbHVlc1sxXSk7XG4gIH1cblxuICBvbldhbmRTZW5zaXRpdml0eUNoYW5nZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLndhbmRTZW5zaXRpdml0eSA9IHZhbHVlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0V2FuZE9wdGlvbnMoeyBzZW5zaXRpdml0eTogdmFsdWUgfSk7XG4gIH1cblxuICBvbkJydXNoU2l6ZUNoYW5nZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLmJydXNoU2l6ZSA9IHZhbHVlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0QnJ1c2hPcHRpb25zKHsgc2l6ZTogdmFsdWUgfSk7XG4gIH1cblxuICBvblZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLnZlcnRleEVyYXNlclJhZGl1cyA9IHZhbHVlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0VmVydGV4RXJhc2VyUmFkaXVzKHZhbHVlKTtcbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnpvb21JbigpO1xuICB9XG5cbiAgem9vbU91dCgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnpvb21PdXQoKTtcbiAgfVxuXG4gIGRlbGV0ZVJlZ2lvbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmRlbGV0ZUFjdGl2ZVNoYXBlKCk7XG4gIH1cblxuICAvKiogVW5kbyB0aGUgbW9zdCByZWNlbnQgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gVXAgdG8gMTAgc3RlcHMgYmFjay4gKi9cbiAgdW5kb1JlZ2lvbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnVuZG8oKTtcbiAgfVxuXG4gIC8qKiBSZWRvIHRoZSBtb3N0IHJlY2VudGx5IHVuZG9uZSByZWdpb24gYWN0aW9uIChqaXQtdWkjODUpLiAqL1xuICByZWRvUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UucmVkbygpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFJlZ2lvbiBzZXQtb3BlcmF0aW9ucyBvbiB0aGUgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM4NSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRoZSBjdXJyZW50bHktc2VsZWN0ZWQgcmVnaW9ucyAobGl2ZSBzdG9yZSBpbnN0YW5jZXMpLiAqL1xuICBwcml2YXRlIGdldCBzZWxlY3RlZFJlZ2lvbnMoKTogUmVnaW9uW10ge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpO1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkSW5kaWNlc1xuICAgICAgLm1hcCgoaSkgPT4gYWxsW2ldKVxuICAgICAgLmZpbHRlcigocik6IHIgaXMgUmVnaW9uID0+ICEhcik7XG4gIH1cblxuICAvKiogUmVnaW9ucyBlbGlnaWJsZSBmb3Igc2V0LW9wczogY2xvc2VkIGFyZWFzIChyZWN0IC8gY2xvc2VkIHBvbHlnb24gL1xuICAgKiAgbXVsdGktcG9seWdvbiksIGV4Y2x1ZGluZyBpbnRlbnNpdHktcHJvZmlsZSBsaW5lcy4gKi9cbiAgcHJpdmF0ZSBvcEVsaWdpYmxlKHJlZ2lvbnM6IFJlZ2lvbltdKTogUmVnaW9uW10ge1xuICAgIHJldHVybiByZWdpb25zLmZpbHRlcigocikgPT4gci5raW5kICE9PSAncHJvZmlsZScgJiYgKFxuICAgICAgci5ib3VuZHMgaW5zdGFuY2VvZiBSZWN0YW5nbGUgfHxcbiAgICAgIHIuYm91bmRzIGluc3RhbmNlb2YgTXVsdGlQb2x5Z29uIHx8XG4gICAgICAoci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uICYmIHIuYm91bmRzLmNsb3NlZCAhPT0gZmFsc2UpXG4gICAgKSk7XG4gIH1cblxuICAvKiogSW1hZ2UgcGl4ZWwgZGltZW5zaW9ucyBmb3IgdGhlIHJhc3RlciBvcHM7IGZhbGxzIGJhY2sgdG8gdGhlIHNlbGVjdGlvbidzXG4gICAqICBleHRlbnQgd2hlbiB0aGUgaW1hZ2Ugc2l6ZSBpc24ndCBrbm93biAoa2VlcHMgY2xhbXBpbmcgc2FuZSkuICovXG4gIHByaXZhdGUgb3BJbWFnZURpbXMocmVnaW9uczogUmVnaW9uW10pOiB7IHc6IG51bWJlcjsgaDogbnVtYmVyIH0ge1xuICAgIGxldCBbdywgaF0gPSB0aGlzLmltYWdlSW5mbz8udHJ1ZUltYWdlU2l6ZSA/PyBbMCwgMF07XG4gICAgaWYgKCEodyA+IDApIHx8ICEoaCA+IDApKSB7XG4gICAgICBsZXQgbWF4WCA9IDAsIG1heFkgPSAwO1xuICAgICAgY29uc3Qgc2NhbiA9ICh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHggb2YgeHMpIG1heFggPSBNYXRoLm1heChtYXhYLCB4KTtcbiAgICAgICAgZm9yIChjb25zdCB5IG9mIHlzKSBtYXhZID0gTWF0aC5tYXgobWF4WSwgeSk7XG4gICAgICB9O1xuICAgICAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICAgICAgY29uc3QgYiA9IHIuYm91bmRzO1xuICAgICAgICBpZiAoYiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkgc2NhbihbYi54ICsgYi53aWR0aF0sIFtiLnkgKyBiLmhlaWdodF0pO1xuICAgICAgICBlbHNlIGlmIChiIGluc3RhbmNlb2YgUG9seWdvbikgc2NhbihiLnhwb2ludHMsIGIueXBvaW50cyk7XG4gICAgICAgIGVsc2UgaWYgKGIgaW5zdGFuY2VvZiBNdWx0aVBvbHlnb24pIGZvciAoY29uc3QgcCBvZiBiLnBvbHlnb25zKSBzY2FuKHAueHBvaW50cywgcC55cG9pbnRzKTtcbiAgICAgIH1cbiAgICAgIHcgPSBNYXRoLm1heCh3LCBNYXRoLmNlaWwobWF4WCkgKyAyKTtcbiAgICAgIGggPSBNYXRoLm1heChoLCBNYXRoLmNlaWwobWF4WSkgKyAyKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgdywgaCB9O1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiDiiaUyIGVsaWdpYmxlIHJlZ2lvbnMgYXJlIHNlbGVjdGVkIChNZXJnZSBhdmFpbGFibGUpLiAqL1xuICBnZXQgY2FuTWVyZ2VSZWdpb25zKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKS5sZW5ndGggPj0gMjsgfVxuICAvKiogVHJ1ZSB3aGVuIGFueSBzZWxlY3RlZCByZWdpb24gaXMgbXVsdGktcGFydCAoVW5ncm91cCBhdmFpbGFibGUpLiAqL1xuICBnZXQgY2FuVW5ncm91cFJlZ2lvbnMoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNlbGVjdGVkUmVnaW9ucy5zb21lKChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5jYW5Vbmdyb3VwKHIpKTsgfVxuICAvKiogVHJ1ZSB3aGVuIOKJpTEgZWxpZ2libGUgcmVnaW9uIGlzIHNlbGVjdGVkIChJbnZlcnNlIC8gU2ltcGxpZnkgYXZhaWxhYmxlKS4gKi9cbiAgZ2V0IGhhc0VsaWdpYmxlU2VsZWN0aW9uKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKS5sZW5ndGggPj0gMTsgfVxuXG4gIC8qKiBTZWxlY3QgZXZlcnkgcmVnaW9uIG9uIHRoZSBpbWFnZSAoZXhjbHVkZXMgaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMpLiAqL1xuICBzZWxlY3RBbGxSZWdpb25zKCk6IHZvaWQge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gW107XG4gICAgYWxsLmZvckVhY2goKHIsIGkpID0+IHsgaWYgKHIua2luZCAhPT0gJ3Byb2ZpbGUnKSBpbmRpY2VzLnB1c2goaSk7IH0pO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoaW5kaWNlcyk7XG4gIH1cblxuICAvKiogTWVyZ2UgdGhlIHNlbGVjdGVkIHJlZ2lvbnMgaW50byBhIHNpbmdsZSAocG9zc2libHkgbXVsdGktcGFydCkgcmVnaW9uLiAqL1xuICBtZXJnZVJlZ2lvbnMoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKTtcbiAgICBpZiAoc2VsLmxlbmd0aCA8IDIpIHJldHVybjtcbiAgICBjb25zdCB7IHcsIGggfSA9IHRoaXMub3BJbWFnZURpbXMoc2VsKTtcbiAgICBjb25zdCBtZXJnZWQgPSB0aGlzLnJlZ2lvbk9wcy5tZXJnZShzZWwsIHcsIGgpO1xuICAgIGlmIChtZXJnZWQpIHRoaXMucmVwbGFjZVJlZ2lvbnMoc2VsLCBbbWVyZ2VkXSk7XG4gIH1cblxuICAvKiogU3BsaXQgZWFjaCBzZWxlY3RlZCBtdWx0aS1wYXJ0IHJlZ2lvbiBpbnRvIG9uZSByZWdpb24gcGVyIHBhcnQuICovXG4gIHVuZ3JvdXBSZWdpb25zKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb25zLmZpbHRlcigocikgPT4gdGhpcy5yZWdpb25PcHMuY2FuVW5ncm91cChyKSk7XG4gICAgaWYgKHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCByZXN1bHRzOiBSZWdpb25bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgciBvZiBzZWwpIHJlc3VsdHMucHVzaCguLi50aGlzLnJlZ2lvbk9wcy51bmdyb3VwKHIpKTtcbiAgICB0aGlzLnJlcGxhY2VSZWdpb25zKHNlbCwgcmVzdWx0cyk7XG4gIH1cblxuICAvKiogUmVwbGFjZSB0aGUgc2VsZWN0aW9uIHdpdGggaXRzIGludmVyc2UgaW5zaWRlIHRoZSBpbWFnZSByZWN0YW5nbGUuICovXG4gIGludmVyc2VSZWdpb25zKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMub3BFbGlnaWJsZSh0aGlzLnNlbGVjdGVkUmVnaW9ucyk7XG4gICAgaWYgKHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCB7IHcsIGggfSA9IHRoaXMub3BJbWFnZURpbXMoc2VsKTtcbiAgICBjb25zdCBpbnYgPSB0aGlzLnJlZ2lvbk9wcy5pbnZlcnNlKHNlbCwgdywgaCk7XG4gICAgaWYgKCFpbnYpIHtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAga2V5OiB0aGlzLnJlc3VsdFRvYXN0S2V5LFxuICAgICAgICBzZXZlcml0eTogJ3dhcm4nLCBzdW1tYXJ5OiAnSW52ZXJzZScsXG4gICAgICAgIGRldGFpbDogJ05vdGhpbmcgdG8gaW52ZXJ0IOKAlCBzZWxlY3Qgb25lIG9yIG1vcmUgY2xvc2VkIHJlZ2lvbnMgZmlyc3QuJyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlcGxhY2VSZWdpb25zKHNlbCwgW2ludl0pO1xuICB9XG5cbiAgLyoqIERvdWdsYXPigJNQZXVja2VyIHNpbXBsaWZ5IGVhY2ggc2VsZWN0ZWQgcmVnaW9uIGJ5IGB0aHJlc2hvbGRQeGAuICovXG4gIHNpbXBsaWZ5UmVnaW9ucyh0aHJlc2hvbGRQeDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5vcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWRSZWdpb25zKTtcbiAgICBpZiAoc2VsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIHRoaXMucmVwbGFjZVJlZ2lvbnMoc2VsLCBzZWwubWFwKChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5zaW1wbGlmeShyLCB0aHJlc2hvbGRQeCkpKTtcbiAgICB0aGlzLmRpc3BsYXlTaW1wbGlmeURpYWxvZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIE9wZW4gdGhlIGN1c3RvbS10aHJlc2hvbGQgc2ltcGxpZnkgZGlhbG9nLiAqL1xuICBvcGVuU2ltcGxpZnlEaWFsb2coKTogdm9pZCB7IHRoaXMuZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gdHJ1ZTsgfVxuXG4gIC8qKlxuICAgKiBDb21taXQgYSBzZXQtb3A6IGRyb3AgdGhlIGByZW1vdmVgIHJlZ2lvbnMsIGFwcGVuZCBgYWRkYCwgYW5kIHNlbGVjdCB0aGVcbiAgICogcmVzdWx0cy4gR29lcyB0aHJvdWdoIHNldFJlZ2lvbnMgc28gaXQncyB1bmRvLXRyYWNrZWQgYW5kIHJlLXJlbmRlcmVkO1xuICAgKiBwcm9maWxlIGxpbmVzIGFuZCB1bnNlbGVjdGVkIHJlZ2lvbnMgYXJlIHByZXNlcnZlZC5cbiAgICovXG4gIHByaXZhdGUgcmVwbGFjZVJlZ2lvbnMocmVtb3ZlOiBSZWdpb25bXSwgYWRkOiBSZWdpb25bXSk6IHZvaWQge1xuICAgIGlmIChhZGQubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgY29uc3QgcmVtb3ZlU2V0ID0gbmV3IFNldChyZW1vdmUpO1xuICAgIGNvbnN0IGtlcHQgPSB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvbnMoKS5maWx0ZXIoKHIpID0+ICFyZW1vdmVTZXQuaGFzKHIpKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFJlZ2lvbnMoWy4uLmtlcHQsIC4uLmFkZF0pOyAvLyBtaW50cyBpZHMgb24gYGFkZGAsIHJlY29yZHMgdW5kb1xuICAgIGNvbnN0IHN0b3JlZCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IHNlbCA9IGFkZC5tYXAoKHIpID0+IHN0b3JlZC5pbmRleE9mKHIpKS5maWx0ZXIoKGkpID0+IGkgPj0gMCk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyhzZWwpO1xuICB9XG5cbiAgLyoqIEJveC1wcm9tcHRlZCBTQU0gc2VnbWVudGF0aW9uIG9mIHRoZSBkcmF3biByZWN0YW5nbGVzIChqaXQtdWkjOTApLiBBIHN0aWNreVxuICAgKiAgYHNhbWAgdG9hc3Qgc2hvd3MgbGl2ZSBzdGF0dXMgKyBhIGRvd25sb2FkIHByb2dyZXNzIGJhciAoZmlyc3QgcnVuIHB1bGxzIHRoZVxuICAgKiAgZW5jb2RlciwgfjE3MCBNQik7IGl0IHN0YXlzIG9wZW4gdW50aWwgdGhlIHJ1biBmaW5pc2hlcyAoYmFyIGhpdHMgMTAwJSkuICovXG4gIGFzeW5jIHNlZ21lbnRSZWdpb25zKCkge1xuICAgIGF3YWl0IHRoaXMucnVuU2VnbWVudFdpdGhUb2FzdCgnU0FNJywgdGhpcy5zYW1Ub29sLCAoKSA9PiB0aGlzLnBsb3RTZXJ2aWNlLnNlZ21lbnRSZWN0YW5nbGVzKCkpO1xuICB9XG5cbiAgLyoqIEF1dG8tc2VnbWVudCBjZWxscyBpbnNpZGUgZWFjaCBkcmF3biByZWN0YW5nbGUgd2l0aCBjZWxscG9zZS1TQU0sIGNsaWVudC1zaWRlXG4gICAqICAoaml0LXVpIzkwKS4gRWFjaCBib3ggaXMgY3JvcHBlZCAoYnJvd3NlciBzbGlkZS1jcm9wKSB0aGVuIHJ1biB0aHJvdWdoIHRoZVxuICAgKiAgY2VsbHBvc2UtanMgbW9kZWw7IHRoZSBzYW1lIHN0aWNreSBgc2FtYCB0b2FzdCArIHByb2dyZXNzIGJhciBpcyByZXVzZWQuICovXG4gIGFzeW5jIHNlZ21lbnRDZWxscG9zZSgpIHtcbiAgICBhd2FpdCB0aGlzLnJ1blNlZ21lbnRXaXRoVG9hc3QoJ0NlbGxwb3NlJywgdGhpcy5jZWxsU2VnbWVudFRvb2wsICgpID0+XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNlZ21lbnRSZWN0YW5nbGVzQ2VsbHBvc2UoKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcmFtZXRlcnMgY3VycmVudGx5IGJvdW5kIGJ5IHRoZSBnZW5lcmljIHBhcmFtZXRlciBkaWFsb2csIGZvciB3aGljaGV2ZXJcbiAgICogdG9vbCBpcyBvcGVuLiBTZWVkZWQgbGF6aWx5OiBhIHRvb2wncyBkZWZhdWx0cyBhcmUgb25seSBhc2tlZCBmb3Igd2hlbiB0aGVcbiAgICogdXNlciBmaXJzdCB0b3VjaGVzIGl0LCBzbyByZWdpc3RlcmluZyBhIHRvb2wgY29zdHMgbm90aGluZyB1bnRpbCB1c2VkLlxuICAgKi9cbiAgcGFyYW1zRm9yKHRvb2xJZDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybiB7fTtcbiAgICBpZiAoIXRoaXMudG9vbFBhcmFtc1t0b29sSWRdKSB7XG4gICAgICAvLyBUaHJvdWdoIGBzZWVkUGFyYW1zYCwgbm90IGBkZWZhdWx0UGFyYW1zYCBkaXJlY3RseTogdGhlIGFjdGl2ZVxuICAgICAgLy8gY2hlY2twb2ludCdzIG93biBgVG9vbE1vZGVsT3B0aW9uLmRlZmF1bHRzYCBoYXZlIHRvIGJlIG1lcmdlZCBvbiB0b3AuXG4gICAgICAvLyBDYWxsaW5nIGBkZWZhdWx0UGFyYW1zYCBoZXJlIGJ5cGFzc2VkIHRoZW0sIHNvIHRoZSB2ZXJ5IGZpcnN0IHJ1biBvZiBhXG4gICAgICAvLyB0b29sIHVzZWQgdGhlIHRvb2wncyBiYXNlbGluZSB0aHJlc2hvbGRzIGFuZCB0aWxpbmcgcmF0aGVyIHRoYW4gdGhlXG4gICAgICAvLyBtb2RlbCdzIOKAlCBhbmQgaXQgb25seSBjb3JyZWN0ZWQgaXRzZWxmIG9uY2UgdGhlIHVzZXIgc3dpdGNoZWRcbiAgICAgIC8vIGNoZWNrcG9pbnRzIG9yIGhpdCBSZXNldC4gRXZlcnkgZW50cnkgcG9pbnQgbm93IGdvZXMgdGhyb3VnaCBvbmUgcGF0aC5cbiAgICAgIHRoaXMudG9vbFBhcmFtc1t0b29sSWRdID0gdGhpcy5zZWVkUGFyYW1zKHRvb2wsIHRoaXMubW9kZWxJZEZvcih0b29sKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRvb2xQYXJhbXNbdG9vbElkXSE7XG4gIH1cblxuICAvKiogQWN0aXZlIGNoZWNrcG9pbnQgZm9yIGEgdG9vbCwgZmFsbGluZyBiYWNrIHRvIHRoZSB0b29sJ3Mgb3duIGRlZmF1bHQuICovXG4gIG1vZGVsSWRGb3IodG9vbDogVG9vbGJhclRvb2xDb250cmlidXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnRvb2xNb2RlbElkc1t0b29sLmlkXSA/PyB0b29sLmRlZmF1bHRNb2RlbElkKCk7XG4gIH1cblxuICAvKiogU3dpdGNoaW5nIGNoZWNrcG9pbnQgcmUtc2VlZHMgdGhlIHBhcmFtZXRlcnMsIHNpbmNlIHRoZSBkZWZhdWx0cyBiZWxvbmcgdG9cbiAgICogIHRoZSBtb2RlbCByYXRoZXIgdGhhbiB0byB0aGUgdG9vbC4gKi9cbiAgb25Ub29sTW9kZWxDaGFuZ2UoZTogeyB0b29sSWQ6IHN0cmluZzsgbW9kZWxJZDogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICBjb25zdCB0b29sID0gdGhpcy5jb250cmlidXRlZFRvb2xzLmZpbmQoKHQpID0+IHQuaWQgPT09IGUudG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybjtcbiAgICAvLyBSZWFzc2lnbmVkIHJhdGhlciB0aGFuIG11dGF0ZWQgc28gdGhlIHRvb2xiYXIncyBuZ09uQ2hhbmdlcyBzZWVzIGEgbmV3XG4gICAgLy8gcmVmZXJlbmNlIGFuZCByZWJ1aWxkcyB0aGF0IHRvb2wncyBtb2RlbCBtZW51IHdpdGggdGhlIGNoZWNrIG1hcmsgbW92ZWQuXG4gICAgdGhpcy50b29sTW9kZWxJZHMgPSB7IC4uLnRoaXMudG9vbE1vZGVsSWRzLCBbZS50b29sSWRdOiBlLm1vZGVsSWQgfTtcbiAgICB0b29sLm9uTW9kZWxDaGFuZ2U/LihlLm1vZGVsSWQpO1xuICAgIHRoaXMudG9vbFBhcmFtc1tlLnRvb2xJZF0gPSB0aGlzLnNlZWRQYXJhbXModG9vbCwgZS5tb2RlbElkKTtcbiAgfVxuXG4gIC8qKiBBIHRvb2wncyBkZWZhdWx0cyBmb3IgYSBjaGVja3BvaW50LCB3aXRoIHRoYXQgY2hlY2twb2ludCdzIG93biBvdmVycmlkZXNcbiAgICogIGFwcGxpZWQgb24gdG9wIOKAlCBwZXItbW9kZWwgZGVmYXVsdHMgYmVhdCBwZXItdG9vbCBvbmVzLiAqL1xuICBwcml2YXRlIHNlZWRQYXJhbXModG9vbDogVG9vbGJhclRvb2xDb250cmlidXRpb24sIG1vZGVsSWQ6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBtb2RlbCA9IHRvb2wubW9kZWxzKCkuZmluZCgobSkgPT4gbS5pZCA9PT0gbW9kZWxJZCk7XG4gICAgcmV0dXJuIHsgLi4udG9vbC5kZWZhdWx0UGFyYW1zKG1vZGVsSWQpLCAuLi4obW9kZWw/LmRlZmF1bHRzID8/IHt9KSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIE5hcnJvdyBhIHBhcmFtIHNwZWMgZm9yIHRoZSB0ZW1wbGF0ZS5cbiAgICpcbiAgICogYCpuZ1N3aXRjaENhc2VgIGRvZXMgbm90IG5hcnJvdyBhIGRpc2NyaW1pbmF0ZWQgdW5pb24gaW4gQW5ndWxhcidzIHRlbXBsYXRlXG4gICAqIHR5cGUgY2hlY2tlciB0aGUgd2F5IGEgYHN3aXRjaGAgZG9lcyBpbiBUeXBlU2NyaXB0LCBzbyB0aGUgdGVtcGxhdGUgYXNrcyBmb3JcbiAgICogdGhlIHZhcmlhbnQgaXQgaGFzIGFscmVhZHkgbWF0Y2hlZCBvbi5cbiAgICovXG4gIG51bWJlclBhcmFtKHA6IFRvb2xQYXJhbVNwZWMpOiBOdW1iZXJQYXJhbVNwZWMge1xuICAgIHJldHVybiBwIGFzIE51bWJlclBhcmFtU3BlYztcbiAgfVxuXG4gIHNlbGVjdFBhcmFtKHA6IFRvb2xQYXJhbVNwZWMpOiBTZWxlY3RQYXJhbVNwZWMge1xuICAgIHJldHVybiBwIGFzIFNlbGVjdFBhcmFtU3BlYztcbiAgfVxuXG4gIG9wZW5Ub29sUGFyYW1zKHRvb2xJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5wYXJhbXNGb3IodG9vbElkKTsgLy8gc2VlZCBiZWZvcmUgdGhlIGRpYWxvZyBiaW5kcyB0byBpdFxuICAgIHRoaXMub3BlblBhcmFtc1Rvb2xJZCA9IHRvb2xJZDtcbiAgfVxuXG4gIC8qKiBUaGUgdG9vbCB3aG9zZSBwYXJhbWV0ZXIgZGlhbG9nIGlzIG9wZW4sIGZvciB0aGUgZ2VuZXJpYyBkaWFsb2cncyBoZWFkZXJcbiAgICogIGFuZCBmaWVsZCBsaXN0LiAqL1xuICBnZXQgb3BlblBhcmFtc1Rvb2woKTogVG9vbGJhclRvb2xDb250cmlidXRpb24gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdGhpcy5vcGVuUGFyYW1zVG9vbElkKTtcbiAgfVxuXG4gIHJlc2V0VG9vbFBhcmFtcyh0b29sSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdG9vbElkKTtcbiAgICBpZiAodG9vbCkgdGhpcy50b29sUGFyYW1zW3Rvb2xJZF0gPSB0aGlzLnNlZWRQYXJhbXModG9vbCwgdGhpcy5tb2RlbElkRm9yKHRvb2wpKTtcbiAgfVxuXG4gIC8qKiBSdW4gYSBjb250cmlidXRlZCB0b29sIG92ZXIgdGhlIGN1cnJlbnQgdmlldy4gTm8gcHJvbXB0OiB0aGVzZSBzd2VlcCB0aGVcbiAgICogIHdob2xlIHZpZXcgcmF0aGVyIHRoYW4gYmVpbmcgcG9pbnRlZCBhdCBzb21ldGhpbmcuIFJldXNlcyB0aGUgc2hhcmVkXG4gICAqICBzZWdtZW50YXRpb24gdG9hc3Qgc28gcHJvZ3Jlc3MgcmVhZHMgdGhlIHNhbWUgYXMgdGhlIFNBTS9jZWxscG9zZSB0b29scy4gKi9cbiAgYXN5bmMgcnVuVG9vbCh0b29sSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmNvbnRyaWJ1dGVkVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gdG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybjtcbiAgICBjb25zdCBwYXJhbXMgPSB7IC4uLnRoaXMucGFyYW1zRm9yKHRvb2xJZCksIG1vZGVsSWQ6IHRoaXMubW9kZWxJZEZvcih0b29sKSB9O1xuICAgIGF3YWl0IHRoaXMucnVuU2VnbWVudFdpdGhUb2FzdCh0b29sLmxhYmVsLCB0b29sLnByb2dyZXNzLCAoKSA9PlxuICAgICAgdG9vbC5ydW4odGhpcy5wbG90U2VydmljZSwgcGFyYW1zKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFNoYXJlZCBkcml2ZXIgZm9yIHRoZSBib3gtcHJvbXB0IHNlZ21lbnQgdG9vbHM6IHdpcmVzIHRoZSB0b29sJ3Mgc3RhdHVzICtcbiAgICogIGRvd25sb2FkIHByb2dyZXNzIGludG8gdGhlIHN0aWNreSBgc2FtYCB0b2FzdCwgcnVucyBgb3BgLCBhbmQgcmVwb3J0cyB0aGVcbiAgICogIHJlZ2lvbiBjb3VudC4gS2VlcHMgdGhlIHRvYXN0IG9wZW4gdW50aWwgdGhlIHJ1biBzZXR0bGVzIChiYXIgaGl0cyAxMDAlKS4gKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5TZWdtZW50V2l0aFRvYXN0KFxuICAgIGxhYmVsOiBzdHJpbmcsXG4gICAgLy8gT2JzZXJ2YWJsZXMgcmF0aGVyIHRoYW4gQmVoYXZpb3JTdWJqZWN0czogYSBjb250cmlidXRlZCB0b29sIGltcGxlbWVudHNcbiAgICAvLyBUb29sUHJvZ3Jlc3MsIGFuZCByZXF1aXJpbmcgYSBjb25jcmV0ZSBzdWJqZWN0IHdvdWxkIGZvcmNlIGV2ZXJ5IHBsdWdpblxuICAgIC8vIHRvIGV4cG9zZSBpdHMgaW50ZXJuYWxzIGp1c3QgdG8gZHJpdmUgdGhpcyB0b2FzdC5cbiAgICB0b29sOiB7IHN0YXR1cyQ6IE9ic2VydmFibGU8c3RyaW5nPjsgcHJvZ3Jlc3MkOiBPYnNlcnZhYmxlPG51bWJlcj4gfSxcbiAgICBvcDogKCkgPT4gUHJvbWlzZTxudW1iZXI+LFxuICApIHtcbiAgICB0aGlzLnNhbVN0YXR1cyA9ICdTdGFydGluZ+KApic7XG4gICAgdGhpcy5zYW1Qcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5zYW1Eb3dubG9hZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuc2FtQnVzeSA9IHRydWU7XG4gICAgY29uc3QgcHN1YiA9IHRvb2wucHJvZ3Jlc3MkLnN1YnNjcmliZSgoZikgPT4ge1xuICAgICAgdGhpcy5zYW1Eb3dubG9hZGluZyA9IGYgPj0gMCAmJiBmIDwgMTtcbiAgICAgIGlmIChmID49IDApIHRoaXMuc2FtUHJvZ3Jlc3MgPSBNYXRoLm1pbigxMDAsIE1hdGgucm91bmQoZiAqIDEwMCkpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuICAgIC8vIFRyYWNrZWQgaGVyZSByYXRoZXIgdGhhbiByZWFkIG9mZiB0aGUgc3ViamVjdCBhdCB0aGUgZW5kOiBgdG9vbGAgaXMgb25seVxuICAgIC8vIGFuIE9ic2VydmFibGUgcGFpciBub3csIHNvIHRoZXJlIGlzIG5vIGAudmFsdWVgIHRvIHNhbXBsZSBvbmNlIHRoZSBydW5cbiAgICAvLyBzZXR0bGVzLiBUaGUgbGFzdCBub24tZW1wdHkgc3RhdHVzIGlzIHdoYXQgdGhlIHJlc3VsdCB0b2FzdCByZXBvcnRzLlxuICAgIGxldCBsYXN0U3RhdHVzID0gJyc7XG4gICAgY29uc3Qgc3N1YiA9IHRvb2wuc3RhdHVzJC5zdWJzY3JpYmUoKG0pID0+IHtcbiAgICAgIGlmIChtKSB7XG4gICAgICAgIGxhc3RTdGF0dXMgPSBtO1xuICAgICAgICB0aGlzLnNhbVN0YXR1cyA9IG07XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnNob3dTYW1Ub2FzdChsYWJlbCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG4gPSBhd2FpdCBvcCgpO1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgICAgIHNldmVyaXR5OiBuID4gMCA/ICdzdWNjZXNzJyA6ICd3YXJuJyxcbiAgICAgICAgc3VtbWFyeTogbGFiZWwsXG4gICAgICAgIGRldGFpbDogbGFzdFN0YXR1cyB8fCAobiA+IDAgPyBgQWRkZWQgJHtufSByZWdpb24ocykuYCA6ICdObyByZWdpb25zIGFkZGVkLicpLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgICAgIHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiBgJHtsYWJlbH0gZmFpbGVkYCwgZGV0YWlsOiBTdHJpbmcoZSksXG4gICAgICB9KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgc3N1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5oaWRlU2FtVG9hc3QoKTtcbiAgICB9XG4gIH1cblxuICAvKiogU2hvdyB0aGUgc2hhcmVkIHN0aWNreSBgc2FtYCB0b2FzdCBvbmNlIChpZGVtcG90ZW50IOKAlCByZS1hZGRpbmcgd291bGQgc3RhY2tcbiAgICogIGEgbmV3IHRvYXN0IG9uIGV2ZXJ5IHBvaW50IGNsaWNrKS4gKi9cbiAgcHJpdmF0ZSBzaG93U2FtVG9hc3Qoc3VtbWFyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2FtVG9hc3RTaG93bikgcmV0dXJuO1xuICAgIHRoaXMuc2FtVG9hc3RTaG93biA9IHRydWU7XG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IHRoaXMuc2FtVG9hc3RLZXksIHN0aWNreTogdHJ1ZSwgc2V2ZXJpdHk6ICdpbmZvJywgc3VtbWFyeSB9KTtcbiAgfVxuXG4gIC8qKiBEaXNtaXNzIHRoZSBzaGFyZWQgYHNhbWAgdG9hc3QgYW5kIHJlc2V0IGl0cyBwcm9ncmVzcy9zcGlubmVyIHN0YXRlLiAqL1xuICBwcml2YXRlIGhpZGVTYW1Ub2FzdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNhbVRvYXN0U2hvd24gPSBmYWxzZTtcbiAgICB0aGlzLnNhbUJ1c3kgPSBmYWxzZTtcbiAgICB0aGlzLnNhbURvd25sb2FkaW5nID0gZmFsc2U7XG4gICAgdGhpcy5zYW1Qcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5jbGVhcih0aGlzLnNhbVRvYXN0S2V5KTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKiogUGljayB0aGUgU0FNIG1vZGVsIHRoZSBzZWdtZW50IHRvb2xzIHVzZSAoaml0LXVpIzkwIFAxKS4gKi9cbiAgb25TYW1Nb2RlbENoYW5nZShpZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zYW1Nb2RlbElkID0gaWQ7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTYW1Nb2RlbChpZCk7XG4gIH1cblxuICAvKiogQ29udmVydCB0aGUgc2VsZWN0ZWQgcmVnaW9uIHRvIGEgc21vb3RoIGJlemllciBjdXJ2ZS4gKi9cbiAgdG9CZXppZXJSZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25PdmVybGF5KCk/LnNldFNlbGVjdGVkQmV6aWVyKHRydWUpO1xuICB9XG5cbiAgLyoqIENvbnZlcnQgdGhlIHNlbGVjdGVkIHJlZ2lvbiBiYWNrIHRvIGEgc3RyYWlnaHQtZWRnZWQgcG9seWdvbi4gKi9cbiAgdG9Qb2x5Z29uUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9uT3ZlcmxheSgpPy5zZXRTZWxlY3RlZEJlemllcihmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogSW1tZWRpYXRlIHJlZ2lvbiBhY3Rpb25zIG9uIHRoZSBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzg1KTogbWVyZ2UsXG4gICAqIHVuZ3JvdXAsIGludmVyc2UsIHNpbXBsaWZ5LCB0aGUgQsOpemllciBjb252ZXJzaW9ucywgYW5kIGRlbGV0ZSDigJQgdGhlXG4gICAqIG9uZS1zaG90IGdlb21ldHJ5IHRyYW5zZm9ybXMsIGdyb3VwZWQgYXBhcnQgZnJvbSB0aGUgdG9vbC9tb2RlIHRvZ2dsZXMgYW5kXG4gICAqIHNob3duIG9ubHkgd2hlbiBzb21ldGhpbmcgaXMgc2VsZWN0ZWQuIEVhY2ggaXRlbSBpcyBnYXRlZCBvbiB3aGF0IHRoZVxuICAgKiBzZWxlY3Rpb24gc3VwcG9ydHMuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkUmVnaW9uQWN0aW9uSXRlbXMoKTogTWVudUl0ZW1bXSB7XG4gICAgY29uc3QgYWxsID0gdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25zKCk7XG4gICAgY29uc3Qgc2VsZWN0YWJsZSA9IGFsbC5maWx0ZXIoKHIpID0+IHIua2luZCAhPT0gJ3Byb2ZpbGUnKTtcbiAgICBpZiAoc2VsZWN0YWJsZS5sZW5ndGggPT09IDApIHJldHVybiBbXTtcbiAgICBjb25zdCBpdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgLy8gU2VsZWN0IGFsbCDigJQgYXZhaWxhYmxlIHdoZW5ldmVyIHRoZSBpbWFnZSBoYXMgcmVnaW9ucywgcmVnYXJkbGVzcyBvZiB0aGVcbiAgICAvLyBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICBpdGVtcy5wdXNoKHtcbiAgICAgIGxhYmVsOiAnU2VsZWN0IGFsbCByZWdpb25zJywgaWNvbjogJ3BpIHBpLWNoZWNrLXNxdWFyZScsXG4gICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnNlbGVjdEFsbFJlZ2lvbnMoKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlbEFsbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb25zO1xuICAgIGlmIChzZWxBbGwubGVuZ3RoID09PSAwKSByZXR1cm4gaXRlbXM7XG4gICAgY29uc3QgZWxpZ2libGUgPSB0aGlzLm9wRWxpZ2libGUoc2VsQWxsKTtcblxuICAgIGlmIChlbGlnaWJsZS5sZW5ndGggPj0gMikge1xuICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnTWVyZ2UgLyBncm91cCcsIGljb246ICdwaSBwaS1saW5rJywgY29tbWFuZDogKCkgPT4gdGhpcy5tZXJnZVJlZ2lvbnMoKSB9KTtcbiAgICB9XG4gICAgaWYgKHNlbEFsbC5zb21lKChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5jYW5Vbmdyb3VwKHIpKSkge1xuICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnVW5ncm91cCcsIGljb246ICdwaSBwaS1zaXRlbWFwJywgY29tbWFuZDogKCkgPT4gdGhpcy51bmdyb3VwUmVnaW9ucygpIH0pO1xuICAgIH1cbiAgICBpZiAoZWxpZ2libGUubGVuZ3RoID49IDEpIHtcbiAgICAgIGl0ZW1zLnB1c2goXG4gICAgICAgIHsgbGFiZWw6ICdJbnZlcnNlJywgaWNvbjogJ3BpIHBpLWNsb25lJywgY29tbWFuZDogKCkgPT4gdGhpcy5pbnZlcnNlUmVnaW9ucygpIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ1NpbXBsaWZ5JywgaWNvbjogJ3BpIHBpLWNoYXJ0LWxpbmUnLFxuICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICB7IGxhYmVsOiAnTGlnaHQgKDEgcHgpJywgY29tbWFuZDogKCkgPT4gdGhpcy5zaW1wbGlmeVJlZ2lvbnMoMSkgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6ICdNZWRpdW0gKDMgcHgpJywgY29tbWFuZDogKCkgPT4gdGhpcy5zaW1wbGlmeVJlZ2lvbnMoMykgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6ICdTdHJvbmcgKDggcHgpJywgY29tbWFuZDogKCkgPT4gdGhpcy5zaW1wbGlmeVJlZ2lvbnMoOCkgfSxcbiAgICAgICAgICAgIHsgc2VwYXJhdG9yOiB0cnVlIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiAnQ3VzdG9t4oCmJywgY29tbWFuZDogKCkgPT4gdGhpcy5vcGVuU2ltcGxpZnlEaWFsb2coKSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBCw6l6aWVyIGNvbnZlcnNpb25zIGFyZSB2ZXJ0ZXgtbGV2ZWwgZWRpdHMg4oCUIEltYWdlIChPcGVuU2VhZHJhZ29uKSB2aWV3XG4gICAgLy8gb25seSDigJQgZ2F0ZWQgb24gdGhlIHNlbGVjdGlvbidzIGN1cnJlbnQgZm9ybS5cbiAgICBpZiAodGhpcy5iYXNlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFKSB7XG4gICAgICBjb25zdCBoYXNTdHJhaWdodCA9IHNlbEFsbC5zb21lKChyKSA9PlxuICAgICAgICAoci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uICYmICFyLmJvdW5kcy5iZXppZXIpIHx8IHIuYm91bmRzIGluc3RhbmNlb2YgUmVjdGFuZ2xlKTtcbiAgICAgIGNvbnN0IGhhc0JlemllciA9IHNlbEFsbC5zb21lKChyKSA9PiByLmJvdW5kcyBpbnN0YW5jZW9mIFBvbHlnb24gJiYgci5ib3VuZHMuYmV6aWVyKTtcbiAgICAgIGlmIChoYXNTdHJhaWdodCkge1xuICAgICAgICBpdGVtcy5wdXNoKHsgbGFiZWw6ICdDb252ZXJ0IHRvIELDqXppZXInLCBpY29uOiAndG8tYmV6aWVyLWljb24nLCBjb21tYW5kOiAoKSA9PiB0aGlzLnRvQmV6aWVyUmVnaW9uKCkgfSk7XG4gICAgICB9XG4gICAgICBpZiAoaGFzQmV6aWVyKSB7XG4gICAgICAgIGl0ZW1zLnB1c2goeyBsYWJlbDogJ0NvbnZlcnQgdG8gcG9seWdvbicsIGljb246ICd0by1wb2x5Z29uLWljb24nLCBjb21tYW5kOiAoKSA9PiB0aGlzLnRvUG9seWdvblJlZ2lvbigpIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpdGVtcy5wdXNoKHsgbGFiZWw6ICdEZWxldGUgcmVnaW9uJywgaWNvbjogJ3BpIHBpLXRyYXNoJywgY29tbWFuZDogKCkgPT4gdGhpcy5kZWxldGVSZWdpb24oKSB9KTtcbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkQ29udGV4dE1lbnVJdGVtcygpOiBNZW51SXRlbVtdIHtcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLmFjdGl2ZURyYWdNb2RlO1xuICAgIGNvbnN0IGFjdGl2ZUNsYXNzID0gJ2NvbnRleHQtbWVudS1hY3RpdmUnO1xuICAgIGNvbnN0IGl0ZW1zOiBNZW51SXRlbVtdID0gW107XG4gICAgLy8gU2VsZWN0ZWQtcmVnaW9uIGFjdGlvbnMgbGVhZCB0aGUgbWVudSAoc2VwYXJhdGVkIGZyb20gdGhlIHRvb2wgdG9nZ2xlcykuXG4gICAgaWYgKHRoaXMuaXNIZWF0bWFwKSB7XG4gICAgICBjb25zdCBhY3Rpb25zID0gdGhpcy5idWlsZFJlZ2lvbkFjdGlvbkl0ZW1zKCk7XG4gICAgICBpZiAoYWN0aW9ucy5sZW5ndGgpIGl0ZW1zLnB1c2goLi4uYWN0aW9ucywgeyBzZXBhcmF0b3I6IHRydWUgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzSGVhdG1hcCkge1xuICAgICAgaXRlbXMucHVzaChcbiAgICAgICAgeyBsYWJlbDogJ0F1dG9zY2FsZScsIGljb246ICdwaSBwaS13aW5kb3ctbWF4aW1pemUnLCBjb21tYW5kOiAoKSA9PiB0aGlzLmF1dG9zY2FsZUltYWdlKCkgfSxcbiAgICAgICAgeyBzZXBhcmF0b3I6IHRydWUgfSxcbiAgICAgICk7XG4gICAgICAvLyAnWm9vbSBzZWxlY3Rpb24nIGlzIFBsb3RseSdzIHJ1YmJlci1iYW5kIHpvb207IGl0IGRvZXNuJ3QgYXBwbHkgdG8gdGhlXG4gICAgICAvLyBPcGVuU2VhZHJhZ29uLWJhY2tlZCBJbWFnZSB2aWV3ICh1c2UgJ1pvb20gdG8gYm94JyB0aGVyZSBpbnN0ZWFkKS5cbiAgICAgIGlmICghdGhpcy5pc0ltYWdlVmlldykge1xuICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICBsYWJlbDogJ1pvb20gc2VsZWN0aW9uJyxcbiAgICAgICAgICBpY29uOiAncGkgcGktc2VhcmNoJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICd6b29tJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnem9vbScpLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICBsYWJlbDogJ1pvb20gdG8gYm94JyxcbiAgICAgICAgaWNvbjogJ3pvb20tYm94LW9mZi1pY29uJyxcbiAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnem9vbVRvQm94JyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3pvb21Ub0JveCcpLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzSGVhdG1hcCkge1xuICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgIGxhYmVsOiAnUGFuJyxcbiAgICAgICAgaWNvbjogJ3BpIHBpLWFycm93cy1hbHQnLFxuICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdwYW4nID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgncGFuJyksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgczNkID0gdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlO1xuICAgICAgaXRlbXMucHVzaChcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnWm9vbScsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLXNlYXJjaCcsXG4gICAgICAgICAgc3R5bGVDbGFzczogczNkID09PSAnem9vbScgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlU3VyZmFjZTNkTW9kZSgnem9vbScpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdQYW4nLFxuICAgICAgICAgIGljb246ICdwaSBwaS1hcnJvd3MtYWx0JyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBzM2QgPT09ICdwYW4nID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZVN1cmZhY2UzZE1vZGUoJ3BhbicpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdPcmJpdGFsIHJvdGF0aW9uJyxcbiAgICAgICAgICBpY29uOiAncGkgcGktZ2xvYmUnLFxuICAgICAgICAgIHN0eWxlQ2xhc3M6IHMzZCA9PT0gJ29yYml0JyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVTdXJmYWNlM2RNb2RlKCdvcmJpdCcpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdUdXJudGFibGUgcm90YXRpb24nLFxuICAgICAgICAgIGljb246ICdwaSBwaS1zeW5jJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBzM2QgPT09ICd0dXJudGFibGUnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZVN1cmZhY2UzZE1vZGUoJ3R1cm50YWJsZScpLFxuICAgICAgICB9LFxuICAgICAgICB7IHNlcGFyYXRvcjogdHJ1ZSB9LFxuICAgICAgICB7IGxhYmVsOiAnUmVzZXQgY2FtZXJhJywgaWNvbjogJ3BpIHBpLWhvbWUnLCBjb21tYW5kOiAoKSA9PiB0aGlzLnJlc2V0U3VyZmFjZUNhbWVyYSgpIH0sXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0hlYXRtYXApIHtcbiAgICAgIGl0ZW1zLnB1c2goXG4gICAgICAgIHsgbGFiZWw6ICdab29tIGluJywgaWNvbjogJ3BpIHBpLXNlYXJjaC1wbHVzJywgY29tbWFuZDogKCkgPT4gdGhpcy56b29tSW4oKSB9LFxuICAgICAgICB7IGxhYmVsOiAnWm9vbSBvdXQnLCBpY29uOiAncGkgcGktc2VhcmNoLW1pbnVzJywgY29tbWFuZDogKCkgPT4gdGhpcy56b29tT3V0KCkgfSxcbiAgICAgICAgeyBzZXBhcmF0b3I6IHRydWUgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnU2VsZWN0JyxcbiAgICAgICAgICBpY29uOiAncGkgcGktYXJyb3ctdXAtcmlnaHQnLFxuICAgICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ3NlbGVjdCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3NlbGVjdCcpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdGcmVlZm9ybScsXG4gICAgICAgICAgaWNvbjogJ3BpIHBpLXBlbmNpbCcsXG4gICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnZHJhd2Nsb3NlZHBhdGgnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdkcmF3Y2xvc2VkcGF0aCcpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdCcnVzaCcsXG4gICAgICAgICAgaWNvbjogJ2JydXNoLWljb24nLFxuICAgICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ2JydXNoJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnYnJ1c2gnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnUG9seWxpbmUnLFxuICAgICAgICAgIGljb246ICdwb2x5bGluZS1pY29uJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdkcmF3b3BlbnBhdGgnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdkcmF3b3BlbnBhdGgnKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnUmVjdGFuZ2xlJyxcbiAgICAgICAgICBpY29uOiAncGkgcGktc3RvcCcsXG4gICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnZHJhd3JlY3QnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdkcmF3cmVjdCcpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdXYW5kJyxcbiAgICAgICAgICBpY29uOiAnd2FuZC1pY29uJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICd3YW5kJyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnd2FuZCcpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdWZXJ0ZXggZXJhc2VyJyxcbiAgICAgICAgICBpY29uOiAncGkgcGktZXJhc2VyJyxcbiAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdlcmFzZVZlcnRleCcgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2VyYXNlVmVydGV4JyksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgLy8gVmVydGV4IGVkaXRpbmcgcnVucyBvbiB0aGUgT3BlblNlYWRyYWdvbiBvdmVybGF5LCB3aGljaFxuICAgICAgLy8gYmFja3MgdGhlIEltYWdlIHBsb3QgdHlwZS4gSGlkZGVuIGZvciBvdGhlciAyRCB0eXBlcyAoUGxvdGx5KSwgd2hlcmVcbiAgICAgIC8vIHRoZXNlIG1vZGVzIGFyZSBuby1vcHMuXG4gICAgICBpZiAodGhpcy5iYXNlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFKSB7XG4gICAgICAgIGl0ZW1zLnB1c2goXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdQb2x5Z29uIChjbGljayB2ZXJ0aWNlcyknLFxuICAgICAgICAgICAgaWNvbjogJ3BvbHlnb24tdmVydGljZXMtaWNvbicsXG4gICAgICAgICAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09ICdkcmF3cG9seWdvbicgPyBhY3RpdmVDbGFzcyA6ICcnLFxuICAgICAgICAgICAgY29tbWFuZDogKCkgPT4gdGhpcy50b2dnbGVEcmFnTW9kZSgnZHJhd3BvbHlnb24nKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxhYmVsOiAnQWRkIHZlcnRleCcsXG4gICAgICAgICAgICBpY29uOiAndmVydGV4LWFkZC1pY29uJyxcbiAgICAgICAgICAgIHN0eWxlQ2xhc3M6IGFjdGl2ZSA9PT0gJ2FkZHBvaW50JyA/IGFjdGl2ZUNsYXNzIDogJycsXG4gICAgICAgICAgICBjb21tYW5kOiAoKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKCdhZGRwb2ludCcpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdEZWxldGUgdmVydGV4JyxcbiAgICAgICAgICAgIGljb246ICd2ZXJ0ZXgtZGVsZXRlLWljb24nLFxuICAgICAgICAgICAgc3R5bGVDbGFzczogYWN0aXZlID09PSAnZGVsZXRlcG9pbnQnID8gYWN0aXZlQ2xhc3MgOiAnJyxcbiAgICAgICAgICAgIGNvbW1hbmQ6ICgpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUoJ2RlbGV0ZXBvaW50JyksXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIELDqXppZXIgY29udmVyc2lvbnMgKyBEZWxldGUgYXJlIGltbWVkaWF0ZSBzZWxlY3Rpb24gKmFjdGlvbnMqLCBub3cgaW4gdGhlXG4gICAgICAvLyBcIlNlbGVjdGVkIHJlZ2lvbihzKVwiIGdyb3VwIGF0IHRoZSB0b3AgKHNlZSBidWlsZFJlZ2lvbkFjdGlvbkl0ZW1zKS5cbiAgICB9XG4gICAgcmV0dXJuIGl0ZW1zO1xuICB9XG5cbiAgdG9nZ2xlU3VyZmFjZTNkTW9kZShtb2RlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVN1cmZhY2UzZE1vZGUgPSBtb2RlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U3VyZmFjZURyYWdNb2RlKG1vZGUpO1xuICB9XG5cbiAgcmVzZXRTdXJmYWNlQ2FtZXJhKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UucmVzZXRTdXJmYWNlQ2FtZXJhKCk7XG4gIH1cblxuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgM0QgY29vcmRpbmF0ZS1heGVzIC8gc2NhbGUgZ2l6bW8gKHZvbHVtZS9pc29zdXJmYWNlKS4gTm8tb3Agb24gYmFja2VuZHNcbiAgICogIHRoYXQgZG9uJ3QgcmVuZGVyIG9uZSAodGhlIGNvbnRyb2wgbWV0aG9kIGlzIG9wdGlvbmFsKS4gKi9cbiAgdG9nZ2xlQXhlcygpIHtcbiAgICB0aGlzLmF4ZXNWaXNpYmxlID0gIXRoaXMuYXhlc1Zpc2libGU7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdXJmYWNlM2RDb250cm9scygpPy5zZXRBeGVzVmlzaWJsZT8uKHRoaXMuYXhlc1Zpc2libGUpO1xuICB9XG5cbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIHN1cmZhY2Ugd2lyZWZyYW1lIChlZGdlcyB2cyBmaWxsZWQpLiBOby1vcCBvbiBiYWNrZW5kcyB3aXRob3V0IGEgc3VyZmFjZS4gKi9cbiAgdG9nZ2xlV2lyZWZyYW1lKCkge1xuICAgIHRoaXMud2lyZWZyYW1lQWN0aXZlID0gIXRoaXMud2lyZWZyYW1lQWN0aXZlO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0U3VyZmFjZTNkQ29udHJvbHMoKT8uc2V0V2lyZWZyYW1lPy4odGhpcy53aXJlZnJhbWVBY3RpdmUpO1xuICB9XG5cbiAgLyoqIENoYW5nZSB0aGUgbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3Rvci4gRGVjaW1hdGlvbiBjaGFuZ2VzIHRoZSBmZXRjaGVkL2Fzc2VtYmxlZCBkYXRhLCBzbyB0aGlzXG4gICAqICByZS1wbG90cyB0aGUgY3VycmVudCAzRCB0eXBlIGF0IHRoZSBuZXcgcmVzb2x1dGlvbiAodW5saWtlIGF4ZXMvd2lyZWZyYW1lLCB3aGljaCBhcmUgbGl2ZSkuICovXG4gIHNlbGVjdFJlc29sdXRpb24oc2NhbGU6IG51bWJlcikge1xuICAgIGlmIChzY2FsZSA9PT0gdGhpcy5yZXNvbHV0aW9uU2NhbGUpIHJldHVybjtcbiAgICB0aGlzLnJlc29sdXRpb25TY2FsZSA9IHNjYWxlO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0UmVzb2x1dGlvblNjYWxlPy4oc2NhbGUpO1xuICAgIHRoaXMucmVsb2FkQW5kUGxvdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN3aXRjaCB0aGUgYWN0aXZlIHBsb3QgdHlwZSAoaGVhdG1hcCwgc3VyZmFjZSwgY29udG91ciwgc2NhdHRlciwgbGluZSxcbiAgICogc2NhdHRlcjNkLCBpc29zdXJmYWNlKS4gS2VlcHMgYGlzSGVhdG1hcGAgYXMgdGhlIDJELXZzLTNEIGZsYWcgdGhlIHJlc3Qgb2ZcbiAgICogdGhlIHRvb2xiYXIvY29udGV4dC1tZW51IGxvZ2ljIHJlbGllcyBvbiwgZGVhY3RpdmF0ZXMgMkQtb25seSB0b29scyB3aGVuXG4gICAqIG1vdmluZyB0byBhIDNEIHR5cGUsIHRoZW4gcmUtcGxvdHMuXG4gICAqL1xuICBvblNlbGVjdFBsb3RUeXBlKHNlbGVjdGVkOiBQbG90VHlwZUlkKSB7XG4gICAgLy8gQSBjb250cmlidXRlZCBpZCB3aG9zZSBwcm92aWRlciBpcyBnb25lIChlLmcuIHJlc3RvcmVkIGZyb20gYSBwcmV2aW91c1xuICAgIC8vIHNlc3Npb24pIGhhcyBub3RoaW5nIHRvIGFjdGl2YXRlIOKAlCB0YWtlIHRoZSBkZWZhdWx0IEltYWdlIHZpZXcgaW5zdGVhZC5cbiAgICBpZiAoIWlzQnVpbHRpblBsb3RUeXBlKHNlbGVjdGVkKSAmJiAhdGhpcy5wbG90TW9kZXMuZmluZChzZWxlY3RlZCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3Zpc3VhbGl6ZXJdIHVua25vd24gcGxvdCB0eXBlICcke3NlbGVjdGVkfScg4oCUIHNob3dpbmcgJyR7UGxvdFR5cGUuSU1BR0V9JyBpbnN0ZWFkLmApO1xuICAgICAgc2VsZWN0ZWQgPSBQbG90VHlwZS5JTUFHRTtcbiAgICB9XG4gICAgLy8gQW4gZXhwbGljaXQgY2hvaWNlIHJldHJpZXMgYSBtb2RlIHdob3NlIGVhcmxpZXIgY2xlYW51cCBmYWlsZWQ7IG9ubHlcbiAgICAvLyBhdXRvbWF0aWMgcmUtYWN0aXZhdGlvbnMgKHJlLXJlbmRlciwgaW1hZ2Ugc3dpdGNoKSBmYWxsIGJhY2sgZm9yIHRoYXQuXG4gICAgdGhpcy5wbG90TW9kZXMuY2xlYXJDbGVhbnVwRmFpbHVyZXMoKTtcbiAgICAvLyBXaGF0ZXZlciB3YXMgc2VsZWN0ZWQgYmVmb3JlLCBhIGNvbnRyaWJ1dGVkIHNlc3Npb24gZW5kcyBiZWZvcmUgdGhlIG5leHRcbiAgICAvLyBtb2RlIGRyYXdzLiAoUmUtc2VsZWN0aW5nIHRoZSBzYW1lIGNvbnRyaWJ1dGVkIG1vZGUgcmUtcGxvdHMsIHNvIGl0IGdldHMgYVxuICAgIC8vIGZyZXNoIHNlc3Npb24gdG9vLilcbiAgICB0aGlzLnBsb3RNb2Rlcy5kZWFjdGl2YXRlKCk7XG4gICAgLy8gRXZlcnl0aGluZyBiZWxvdyBkZWNpZGVzIGhvdyB0byBSRU5ERVIsIHNvIGl0IHdvcmtzIG9uIHRoZSBidWlsdC1pbiB0eXBlXG4gICAgLy8gdGhhdCBkcmF3cyBgc2VsZWN0ZWRgOiBhIGNvbnRyaWJ1dGVkIG1vZGUgYmVoYXZlcyBleGFjdGx5IGxpa2UgaXRzIGJhc2UuXG4gICAgY29uc3QgdHlwZSA9IHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2Yoc2VsZWN0ZWQpO1xuICAgIC8vIEEgZGlhbG9nIHRvb2wgZHJhd3Mgb3ZlciB0aGUgSW1hZ2UgdmlldzogbGVhdmluZyBpdCBjbG9zZXMgdGhlIGRpYWxvZy4gU3RheWluZ1xuICAgIC8vIG9uIGl0LCB0aGUgc2Vzc2lvbiBlbmRzIGhlcmUgYW5kIHJlc3RhcnRzIG9uY2UgdGhlIHJlLXBsb3QgbGFuZHMuXG4gICAgaWYgKHR5cGUgPT09IFBsb3RUeXBlLklNQUdFKSB0aGlzLnRvb2xEaWFsb2dzLmRlYWN0aXZhdGUoKTtcbiAgICBlbHNlIHRoaXMuY2xvc2VEaWFsb2dUb29sKCk7XG4gICAgdGhpcy5wbG90VHlwZSA9IHR5cGU7XG4gICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSBzZWxlY3RlZDtcbiAgICBjb25zdCBkZXNjcmlwdG9yID0gaXNCdWlsdGluUGxvdFR5cGUoc2VsZWN0ZWQpXG4gICAgICA/IHRoaXMucGxvdFR5cGVNZW51LmZpbmQoKGQpID0+IGQudHlwZSA9PT0gdHlwZSlcbiAgICAgIDogZ2V0UGxvdFR5cGVEZXNjcmlwdG9yKHR5cGUpO1xuICAgIGNvbnN0IGlzM2QgPSBkZXNjcmlwdG9yPy5kaW1lbnNpb25zID09PSAnM2QnO1xuICAgIHRoaXMuaXNIZWF0bWFwID0gIWlzM2Q7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0eXBlKTtcbiAgICAvLyBTd2l0Y2hpbmcgcGxvdCB0eXBlIGNhbmNlbHMgdGhlIGFjdGl2ZSB0b29sIOKAlCBub3QgZXZlcnkgdHlwZSBzdXBwb3J0cyB0aGVcbiAgICAvLyBzYW1lIHRvb2xzIChsaW5lL3NjYXR0ZXIgY2hhcnRzIGFuZCAzRCBzY2VuZXMgaGF2ZSBubyBib3ggem9vbSBvciByZWdpb25cbiAgICAvLyBkcmF3aW5nKSwgc28gbGVhdmluZyBhIHRvb2wgYXJtZWQgd291bGQgbWlzYmVoYXZlIG9uIHRoZSBuZXcgcGxvdC5cbiAgICB0aGlzLmRlYWN0aXZhdGVBY3RpdmVUb29sKCk7XG4gICAgaWYgKGlzM2QpIHtcbiAgICAgIHRoaXMuYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAgIH1cbiAgICAvLyBuYXBhcmktanMgdm9sdW1lL2lzb3N1cmZhY2UgYXNzZW1ibGUgdGhlaXIgb3duIDNEIHRleHR1cmUgZnJvbSB0aGUgc2xpY2UgZW5kcG9pbnQsIHNvXG4gICAgLy8gdGhleSB0YWtlIHRoZSBub3JtYWwgcmUtcGxvdCBwYXRoIOKAlCBOT1QgUGxvdGx5J3Mgc3RhY2stZnJhbWUgbG9hZGVyICh3aG9zZSBcIkxvYWRpbmdcbiAgICAvLyBmcmFtZXNcIiBvdmVybGF5IHdvdWxkIG5ldmVyIGNsZWFyLCBzaW5jZSBQbG90bHkgaXNuJ3QgdGhlIGFjdGl2ZSBiYWNrZW5kKSAoaml0LXVpIzEwMikuXG4gICAgY29uc3QgaXNOYXBhcmkgPSB0eXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0UgfHwgaXNOYXBhcmkzZCh0eXBlKTtcbiAgICBpZiAoZGVzY3JpcHRvcj8ucmVxdWlyZXNTdGFjayAmJiAhaXNOYXBhcmkpIHtcbiAgICAgIC8vIFZvbHVtZSB0eXBlcyAoaXNvc3VyZmFjZSwgc2NhdHRlcjNkKSBuZWVkIHRoZSB3aG9sZSB6LXN0YWNrIGxvYWRlZCBhcyBhXG4gICAgICAvLyAzRCBhcnJheSwgYW5kIHRoZXkgYWx3YXlzIHJlbmRlciBvbiBQbG90bHkuIERyaXZlIHRoZSBzdGFjayByZWxvYWRcbiAgICAgIC8vIGRpcmVjdGx5IHRocm91Z2ggdGhlIGltYWdlLWluZm8gc3RyZWFtIHJhdGhlciB0aGFuIHRoZSBhY3RpdmUgcmVuZGVyZXInc1xuICAgICAgLy8gc2V0U2hvd1N0YWNrOiB3aGVuIE9wZW5TZWFkcmFnb24gb3ducyB0aGUgSW1hZ2UgdmlldyBpdHMgc2V0U2hvd1N0YWNrIGlzXG4gICAgICAvLyBhIG5vLW9wLCBzbyB0aGUgcmVsb2FkIG5ldmVyIGZpcmVkIGFuZCB0aGUgbG9hZGVyIHNwdW4gZm9yZXZlci4gV2UgYXJtXG4gICAgICAvLyBQbG90bHkncyBzdGFjay1sb2FkaW5nIGZsYWcgKGtlZXBzIGl0cyBmcmFtZS1mZXRjaCBsb29wIGFsaXZlKSBhbmRcbiAgICAgIC8vIHJlLWVtaXQgdGhlIGltYWdlIGluZm8gd2l0aCBzaG93U3RhY2sgb24gc28gdGhlIHBpcGVsaW5lIHJlbG9hZHMgb25cbiAgICAgIC8vIFBsb3RseSByZWdhcmRsZXNzIG9mIHdoaWNoIGJhY2tlbmQgd2FzIG9uIHNjcmVlbi5cbiAgICAgIHRoaXMuc2VsZWN0ZWRTdGFja09wdGlvbiA9IHRoaXMuc3RhY2tPcHRpb25zWzFdO1xuICAgICAgdGhpcy5zdGFja0xvYWRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRTdGFja0xvYWRpbmcodHJ1ZSk7XG4gICAgICBpZiAodGhpcy5pbWFnZUluZm8pIHtcbiAgICAgICAgdGhpcy5pbWFnZUluZm8uc2hvd1N0YWNrID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUluZm8odGhpcy5pbWFnZUluZm8pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlbG9hZEFuZFBsb3QoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBjb250cmlidXRlZCBwbG90IG1vZGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKlxuICAgKiBTdGFydCB0aGUgc2VsZWN0ZWQgY29udHJpYnV0ZWQgbW9kZSdzIHNlc3Npb24sIG9uY2UgaXRzIGJhc2UgdmlldyBoYXNcbiAgICogcGxvdHRlZC4gTm8tb3AgZm9yIGEgYnVpbHQtaW4gdHlwZSwgb3Igd2hlbiB0aGUgYmFzZSBvbiBzY3JlZW4gaXMgbm90IHRoZVxuICAgKiBvbmUgdGhlIG1vZGUgcmlkZXMgb24uIEEgYmFja2VuZCB0aGF0IGNhbm5vdCBwcm92aWRlIGEgdmlld3BvcnQgZm9yIGl0XG4gICAqIChlLmcuIE9TRCBmZWxsIGJhY2sgdG8gUGxvdGx5KSBjb3VudHMgYXMgYSBmYWlsZWQgYWN0aXZhdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYWN0aXZhdGVTZWxlY3RlZFBsb3RNb2RlKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbnRyaWJ1dGlvbiA9IHRoaXMucGxvdE1vZGVzLmZpbmQodGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQpO1xuICAgIGlmICghY29udHJpYnV0aW9uIHx8IHRoaXMucGxvdFR5cGUgIT09IGNvbnRyaWJ1dGlvbi5kZXNjcmlwdG9yLmJhc2VUeXBlKSByZXR1cm47XG4gICAgY29uc3Qgdmlld3BvcnQgPSB0aGlzLnBsb3RTZXJ2aWNlLmdldFBsb3RNb2RlVmlld3BvcnQ/LigpID8/IG51bGw7XG4gICAgaWYgKCF2aWV3cG9ydCkge1xuICAgICAgY29uc29sZS5lcnJvcihgW3Zpc3VhbGl6ZXJdIHBsb3QtdHlwZSBjb250cmlidXRpb24gJyR7Y29udHJpYnV0aW9uLmRlc2NyaXB0b3IudHlwZX0nOiB0aGUgYmFja2VuZCBgXG4gICAgICAgICsgJ29uIHNjcmVlbiBwcm92aWRlcyBubyB2aWV3cG9ydCB0byBkcmF3IG92ZXIg4oCUIGZhbGxpbmcgYmFjay4nKTtcbiAgICAgIHRoaXMuZmFsbEJhY2tGcm9tUGxvdE1vZGUoY29udHJpYnV0aW9uKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY3R4OiBQbG90TW9kZUNvbnRleHQgPSB7XG4gICAgICB2aXN1YWxpemVyOiB0aGlzLnBsb3RTZXJ2aWNlLFxuICAgICAgdmlld3BvcnQsXG4gICAgICBpbWFnZUluZm8kOiB0aGlzLnN0YXRlLmdldEltYWdlSW5mbyQoKSxcbiAgICAgIHRvb2xzOiB0aGlzLnBsb3RNb2RlVG9vbHMsXG4gICAgfTtcbiAgICB2b2lkIHRoaXMucGxvdE1vZGVzLmFjdGl2YXRlKGNvbnRyaWJ1dGlvbiwgY3R4KTtcbiAgfVxuXG4gIC8qKiBSZW5kZXIgdGhlIGxpdmUgbW9kZSdzIHBhbmVsLiBBY3RpdmF0aW9uIGNhbiByZXNvbHZlIG91dHNpZGUgQW5ndWxhciAoYW5cbiAgICogIE9TRCBjYWxsYmFjaywgYSBjb250cmlidXRpb24ncyBvd24gcHJvbWlzZSksIGhlbmNlIHRoZSB6b25lIHJlLWVudHJ5LiAqL1xuICBwcml2YXRlIHNob3dQbG90TW9kZVBhbmVsKGFjdGl2ZTogQWN0aXZlUGxvdE1vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBwYW5lbCA9IGFjdGl2ZS5jb250cmlidXRpb24ucGFuZWw7XG4gICAgaWYgKCFwYW5lbCkgcmV0dXJuO1xuICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBpZiAoJ2NvbXBvbmVudCcgaW4gcGFuZWwgJiYgcGFuZWwuY29tcG9uZW50KSB7XG4gICAgICAgIHRoaXMucGxvdE1vZGVQYW5lbCA9IHtcbiAgICAgICAgICB0aXRsZTogcGFuZWwudGl0bGUsXG4gICAgICAgICAgY29tcG9uZW50OiBwYW5lbC5jb21wb25lbnQsXG4gICAgICAgICAgaW5qZWN0b3I6IEluamVjdG9yLmNyZWF0ZSh7XG4gICAgICAgICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgICAgICAgeyBwcm92aWRlOiBQTE9UX01PREVfQ09OVEVYVCwgdXNlVmFsdWU6IGFjdGl2ZS5jdHggfSxcbiAgICAgICAgICAgICAgeyBwcm92aWRlOiBQTE9UX01PREVfU0VTU0lPTiwgdXNlVmFsdWU6IGFjdGl2ZS5zZXNzaW9uIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcGFyZW50OiB0aGlzLmluamVjdG9yLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGhvc3Q6IG51bGwsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKGFjdGl2ZS5wYW5lbEhvc3QpIHtcbiAgICAgICAgdGhpcy5wbG90TW9kZVBhbmVsID0geyB0aXRsZTogcGFuZWwudGl0bGUsIGNvbXBvbmVudDogbnVsbCwgaW5qZWN0b3I6IG51bGwsIGhvc3Q6IGFjdGl2ZS5wYW5lbEhvc3QgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIEEgY29tcG9uZW50IHBhbmVsIGlzIGNyZWF0ZWQgYW5kIGZpcnN0IHJlbmRlcmVkIHJpZ2h0IGhlcmU7IGlmIHRoYXQgdGhyb3dzLFxuICAgICAgLy8gdGhlIG1vZGUgaXMgbm90IHVzYWJsZSDigJQgZW5kIGl0IGFuZCBmYWxsIGJhY2sgcmF0aGVyIHRoYW4gbGVhdmUgaXQgc2VsZWN0ZWQuXG4gICAgICBjb25zdCBlcnIgPSB0aGlzLmRldGVjdENoYW5nZXNTYWZlbHkoKTtcbiAgICAgIGlmIChlcnIgIT09IG51bGwpIHRoaXMucGxvdE1vZGVzLmZhaWxBY3RpdmUoZXJyKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBEcm9wIHRoZSBwYW5lbCAoZGVzdHJveWluZyBhIGNvbXBvbmVudCBwYW5lbCkgYmVmb3JlIHRoZSBzZXNzaW9uIGVuZHMuICovXG4gIHByaXZhdGUgaGlkZVBsb3RNb2RlUGFuZWwoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBsb3RNb2RlUGFuZWwpIHJldHVybjtcbiAgICB0aGlzLnBsb3RNb2RlUGFuZWwgPSBudWxsO1xuICAgIHRoaXMuZGV0ZWN0Q2hhbmdlc1NhZmVseSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgY29udHJpYnV0ZWQgbW9kZSBjb3VsZCBub3Qgc3RhcnQuIEl0cyBiYXNlIHR5cGUgaXMgYWxyZWFkeSBvbiBzY3JlZW4g4oCUXG4gICAqIHRoZSBiYXNlIHBsb3R0ZWQgZmlyc3Qg4oCUIHNvIGp1c3Qgc2VsZWN0IGl0OiBub3RoaW5nIG5lZWRzIHRvIHJlLXBsb3QuXG4gICAqL1xuICBwcml2YXRlIGZhbGxCYWNrRnJvbVBsb3RNb2RlKGNvbnRyaWJ1dGlvbjogUGxvdFR5cGVDb250cmlidXRpb24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kZXN0cm95aW5nIHx8IHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkICE9PSBjb250cmlidXRpb24uZGVzY3JpcHRvci50eXBlKSByZXR1cm47XG4gICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgIGNvbnN0IGJhc2UgPSBjb250cmlidXRpb24uZGVzY3JpcHRvci5iYXNlVHlwZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gYmFzZTtcbiAgICAgIHRoaXMucGxvdFR5cGUgPSBiYXNlO1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgICAgIHNldmVyaXR5OiAnd2FybicsXG4gICAgICAgIHN1bW1hcnk6IGAke2NvbnRyaWJ1dGlvbi5kZXNjcmlwdG9yLnByb2R1Y3Rpb25MYWJlbCA/PyBjb250cmlidXRpb24uZGVzY3JpcHRvci5sYWJlbH0gaXMgdW5hdmFpbGFibGVgLFxuICAgICAgICBkZXRhaWw6ICdUaGUgcGxvdCBtb2RlIGNvdWxkIG5vdCBzdGFydCwgc28gdGhlIHBsYWluIGltYWdlIGlzIHNob3duIGluc3RlYWQuIFNlZSB0aGUgYnJvd3NlciBjb25zb2xlIGZvciBkZXRhaWxzLicsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdlc1NhZmVseSgpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIFJ1biBjaGFuZ2UgZGV0ZWN0aW9uOyByZXR1cm5zIHdoYXQgaXQgdGhyZXcgKGxvZ2dlZCksIG9yIG51bGwuICovXG4gIHByaXZhdGUgZGV0ZWN0Q2hhbmdlc1NhZmVseSgpOiB1bmtub3duIHwgbnVsbCB7XG4gICAgaWYgKHRoaXMuZGVzdHJveWluZykgcmV0dXJuIG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignW3Zpc3VhbGl6ZXJdIGNoYW5nZSBkZXRlY3Rpb24gZmFpbGVkIHdoaWxlIHVwZGF0aW5nIGEgY29udHJpYnV0ZWQgcGxvdCBtb2RlIHBhbmVsLicsIGVycik7XG4gICAgICByZXR1cm4gZXJyID8/IG5ldyBFcnJvcignY2hhbmdlIGRldGVjdGlvbiBmYWlsZWQnKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgZGlhbG9nIHRvb2xzIChUT09MQkFSX1RPT0xTLCBraW5kOiAnZGlhbG9nJykg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRoZSB0b29sYmFyIGJ1dHRvbjogb3BlbiB0aGUgdG9vbCdzIGRpYWxvZywgb3IgY2xvc2UgaXQgaWYgaXQgaXMgb3Blbi4gKi9cbiAgdG9nZ2xlRGlhbG9nVG9vbChpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3BlbkRpYWxvZ1Rvb2xJZCA9PT0gaWQpIHtcbiAgICAgIHRoaXMuY2xvc2VEaWFsb2dUb29sKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY2xvc2VEaWFsb2dUb29sKCk7XG4gICAgaWYgKCF0aGlzLmRpYWxvZ1Rvb2xzLnNvbWUoKHQpID0+IHQuaWQgPT09IGlkKSkgcmV0dXJuO1xuICAgIHRoaXMub3BlbkRpYWxvZ1Rvb2xJZCA9IGlkO1xuICAgIHRoaXMudG9vbERpYWxvZ3MuY2xlYXJDbGVhbnVwRmFpbHVyZXMoKTsgLy8gYW4gZXhwbGljaXQgb3BlbiBnZXRzIGEgZnJlc2ggYXR0ZW1wdFxuICAgIHRoaXMuYWN0aXZhdGVPcGVuRGlhbG9nVG9vbCgpO1xuICB9XG5cbiAgLyoqIENsb3NlIHRoZSBvcGVuIGRpYWxvZyB0b29sOiBpdHMgYm9keSBpcyB0b3JuIGRvd24sIHRoZW4gaXRzIHNlc3Npb24gZW5kcy4gKi9cbiAgY2xvc2VEaWFsb2dUb29sKCk6IHZvaWQge1xuICAgIHRoaXMub3BlbkRpYWxvZ1Rvb2xJZCA9IG51bGw7XG4gICAgdGhpcy50b29sRGlhbG9ncy5kZWFjdGl2YXRlKCk7XG4gIH1cblxuICAvKiogU3RhcnQgKG9yIHJlc3RhcnQsIGFmdGVyIGEgcmUtcmVuZGVyKSB0aGUgb3BlbiBkaWFsb2cgdG9vbCdzIHNlc3Npb24uICovXG4gIHByaXZhdGUgYWN0aXZhdGVPcGVuRGlhbG9nVG9vbCgpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHRoaXMub3BlbkRpYWxvZ1Rvb2xJZDtcbiAgICBjb25zdCBjb250cmlidXRpb24gPSBpZCA/IHRoaXMudG9vbERpYWxvZ3MuZmluZChpZCkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKCFjb250cmlidXRpb24gfHwgdGhpcy5wbG90VHlwZSAhPT0gUGxvdFR5cGUuSU1BR0UpIHJldHVybjtcbiAgICBpZiAodGhpcy50b29sRGlhbG9ncy5jdXJyZW50Py5jb250cmlidXRpb24gPT09IGNvbnRyaWJ1dGlvbiB8fCB0aGlzLnRvb2xEaWFsb2dzLnBlbmRpbmcpIHJldHVybjtcbiAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0UGxvdE1vZGVWaWV3cG9ydD8uKCkgPz8gbnVsbDtcbiAgICBpZiAoIXZpZXdwb3J0KSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBbdmlzdWFsaXplcl0gZGlhbG9nIHRvb2wgJyR7aWR9JzogdGhlIGJhY2tlbmQgb24gc2NyZWVuIHByb3ZpZGVzIG5vIHZpZXdwb3J0IHRvIGRyYXcgb3Zlci5gKTtcbiAgICAgIHRoaXMuZGlhbG9nVG9vbEZhaWxlZChpZCEpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjdHg6IFRvb2xEaWFsb2dDb250ZXh0ID0ge1xuICAgICAgdmlzdWFsaXplcjogdGhpcy5wbG90U2VydmljZSxcbiAgICAgIHZpZXdwb3J0LFxuICAgICAgaW1hZ2VJbmZvJDogdGhpcy5zdGF0ZS5nZXRJbWFnZUluZm8kKCksXG4gICAgICB0b29sczogdGhpcy5wbG90TW9kZVRvb2xzLFxuICAgIH07XG4gICAgdm9pZCB0aGlzLnRvb2xEaWFsb2dzLmFjdGl2YXRlKGNvbnRyaWJ1dGlvbiwgY3R4KTtcbiAgfVxuXG4gIC8qKiBUaGUgbGl2ZSBkaWFsb2cgYm9keSdzIHRlYXJkb3duLCBhbmQgYSBwZW5kaW5nIHdhaXQgZm9yIGl0cyBob3N0IHRvIGNvbm5lY3QuICovXG4gIHByaXZhdGUgdG9vbERpYWxvZ1RlYXJkb3duOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB0b29sRGlhbG9nRnJhbWU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgc2Vzc2lvbiBpcyBsaXZlOiByZW5kZXIgdGhlIGRpYWxvZywgdGhlbiBtb3VudCB0aGUgdG9vbCdzIGJvZHkgb25jZSB0aGUgaG9zdFxuICAgKiBlbGVtZW50IGlzIGluIHRoZSBkb2N1bWVudCwgc28gYG1vdW50KClgIGNhbiBtZWFzdXJlIGl0IGFuZCBzdGFydCB3aWRnZXRzIHRoYXQgbmVlZFxuICAgKiBhIGNvbm5lY3RlZCBlbGVtZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBzaG93VG9vbERpYWxvZyhhY3RpdmU6IEFjdGl2ZVBsb3RNb2RlKTogdm9pZCB7XG4gICAgY29uc3QgdG9vbCA9IHRoaXMuZGlhbG9nVG9vbHMuZmluZCgodCkgPT4gdC5pZCA9PT0gYWN0aXZlLmNvbnRyaWJ1dGlvbi5kZXNjcmlwdG9yLnR5cGUpO1xuICAgIGlmICghdG9vbCkgcmV0dXJuO1xuICAgIGNvbnN0IGhvc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBob3N0LmNsYXNzTmFtZSA9ICd0b29sLWRpYWxvZy1ib2R5JztcbiAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgdGhpcy50b29sRGlhbG9nID0ge1xuICAgICAgICB0aXRsZTogdG9vbC5kaWFsb2c/LnRpdGxlID8/IHRvb2wubGFiZWwsXG4gICAgICAgIHdpZHRoOiB0b29sLmRpYWxvZz8ud2lkdGggPz8gJzIycmVtJyxcbiAgICAgICAgaG9zdCxcbiAgICAgIH07XG4gICAgICBjb25zdCBlcnIgPSB0aGlzLmRldGVjdENoYW5nZXNTYWZlbHkoKTtcbiAgICAgIGlmIChlcnIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy50b29sRGlhbG9ncy5mYWlsQWN0aXZlKGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubW91bnRUb29sRGlhbG9nQm9keSh0b29sLCBhY3RpdmUsIGhvc3QsIDApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIEhvdyBtYW55IGFuaW1hdGlvbiBmcmFtZXMgdG8gd2FpdCBmb3IgdGhlIGRpYWxvZyB0byBhdHRhY2ggdGhlIGJvZHkncyBob3N0LiAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBUT09MX0RJQUxPR19BVFRBQ0hfRlJBTUVTID0gNjA7XG5cbiAgLyoqXG4gICAqIE1vdW50IGB0b29sYCdzIGJvZHkgaW50byBgaG9zdGAgb25jZSBpdCBpcyBjb25uZWN0ZWQgKHRoZSBkaWFsb2cgbWF5IGF0dGFjaCBpdCBhXG4gICAqIGZyYW1lIGxhdGVyLCB3aGVuIGl0IG1vdmVzIGl0c2VsZiB0byBgPGJvZHk+YCkuIElmIGl0IG5ldmVyIGNvbm5lY3RzIHdpdGhpblxuICAgKiB7QGxpbmsgVE9PTF9ESUFMT0dfQVRUQUNIX0ZSQU1FU30gaXQgaXMgbW91bnRlZCBhbnl3YXksIHdpdGggYSB3YXJuaW5nLCByYXRoZXIgdGhhblxuICAgKiBsZWF2aW5nIGFuIGVtcHR5IGRpYWxvZy4gQSB0aHJvd2luZyBgbW91bnQoKWAgZmFpbHMgdGhlIHNlc3Npb24gbGlrZSBhIGZhaWxlZCBzdGFydC5cbiAgICovXG4gIHByaXZhdGUgbW91bnRUb29sRGlhbG9nQm9keSh0b29sOiBUb29sYmFyRGlhbG9nVG9vbENvbnRyaWJ1dGlvbiwgYWN0aXZlOiBBY3RpdmVQbG90TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3Q6IEhUTUxFbGVtZW50LCBmcmFtZXM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudG9vbERpYWxvZ0ZyYW1lID0gbnVsbDtcbiAgICAvLyBUaGUgc2Vzc2lvbiBlbmRlZCAob3Igd2FzIHJlcGxhY2VkKSB3aGlsZSB3YWl0aW5nOiBub3RoaW5nIHRvIG1vdW50IGludG8uXG4gICAgaWYgKHRoaXMudG9vbERpYWxvZ3MuY3VycmVudCAhPT0gYWN0aXZlIHx8IHRoaXMudG9vbERpYWxvZz8uaG9zdCAhPT0gaG9zdCkgcmV0dXJuO1xuICAgIGlmICghaG9zdC5pc0Nvbm5lY3RlZCkge1xuICAgICAgaWYgKGZyYW1lcyA8IFZpc3VhbGl6ZXJDb21wb25lbnQuVE9PTF9ESUFMT0dfQVRUQUNIX0ZSQU1FUykge1xuICAgICAgICB0aGlzLnRvb2xEaWFsb2dGcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShcbiAgICAgICAgICAoKSA9PiB0aGlzLm1vdW50VG9vbERpYWxvZ0JvZHkodG9vbCwgYWN0aXZlLCBob3N0LCBmcmFtZXMgKyAxKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUud2FybihgW3Zpc3VhbGl6ZXJdIGRpYWxvZyB0b29sICcke3Rvb2wuaWR9JzogdGhlIGRpYWxvZyBib2R5IG5ldmVyIGF0dGFjaGVkOyBtb3VudGluZyBpdCBkZXRhY2hlZC5gKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRlYXJkb3duID0gdG9vbC5tb3VudChob3N0LCBhY3RpdmUuY3R4IGFzIFRvb2xEaWFsb2dDb250ZXh0LCBhY3RpdmUuc2Vzc2lvbik7XG4gICAgICB0aGlzLnRvb2xEaWFsb2dUZWFyZG93biA9IHR5cGVvZiB0ZWFyZG93biA9PT0gJ2Z1bmN0aW9uJyA/IHRlYXJkb3duIDogbnVsbDtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFt2aXN1YWxpemVyXSBkaWFsb2cgdG9vbCAnJHt0b29sLmlkfScgbW91bnQoKSB0aHJldy5gLCBlcnIpO1xuICAgICAgdGhpcy50b29sRGlhbG9ncy5mYWlsQWN0aXZlKGVycik7XG4gICAgfVxuICB9XG5cbiAgLyoqIFRoZSBzZXNzaW9uIGlzIGFib3V0IHRvIGVuZDogdGVhciB0aGUgYm9keSBkb3duIGZpcnN0LCB0aGVuIGRyb3AgdGhlIGRpYWxvZy4gKi9cbiAgcHJpdmF0ZSBoaWRlVG9vbERpYWxvZygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50b29sRGlhbG9nRnJhbWUgIT09IG51bGwpIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMudG9vbERpYWxvZ0ZyYW1lKTtcbiAgICB0aGlzLnRvb2xEaWFsb2dGcmFtZSA9IG51bGw7XG4gICAgY29uc3QgdGVhcmRvd24gPSB0aGlzLnRvb2xEaWFsb2dUZWFyZG93bjtcbiAgICB0aGlzLnRvb2xEaWFsb2dUZWFyZG93biA9IG51bGw7XG4gICAgaWYgKHRlYXJkb3duKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0ZWFyZG93bigpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1t2aXN1YWxpemVyXSBkaWFsb2cgdG9vbCBib2R5IHRlYXJkb3duIHRocmV3LicsIGVycik7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghdGhpcy50b29sRGlhbG9nKSByZXR1cm47XG4gICAgdGhpcy50b29sRGlhbG9nLmhvc3QucmVtb3ZlKCk7XG4gICAgdGhpcy50b29sRGlhbG9nID0gbnVsbDtcbiAgICBpZiAoIXRoaXMuZGVzdHJveWluZykgdGhpcy5kZXRlY3RDaGFuZ2VzU2FmZWx5KCk7XG4gIH1cblxuICAvKiogQSBkaWFsb2cgdG9vbCBjb3VsZCBub3Qgc3RhcnQ6IGNsb3NlIGl0IGFuZCBzYXkgc28uICovXG4gIHByaXZhdGUgZGlhbG9nVG9vbEZhaWxlZChpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGVzdHJveWluZyB8fCB0aGlzLm9wZW5EaWFsb2dUb29sSWQgIT09IGlkKSByZXR1cm47XG4gICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgIHRoaXMub3BlbkRpYWxvZ1Rvb2xJZCA9IG51bGw7XG4gICAgICBjb25zdCB0b29sID0gdGhpcy5kaWFsb2dUb29scy5maW5kKCh0KSA9PiB0LmlkID09PSBpZCk7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgIGtleTogdGhpcy5yZXN1bHRUb2FzdEtleSxcbiAgICAgICAgc2V2ZXJpdHk6ICd3YXJuJyxcbiAgICAgICAgc3VtbWFyeTogYCR7dG9vbD8ubGFiZWwgPz8gaWR9IGlzIHVuYXZhaWxhYmxlYCxcbiAgICAgICAgZGV0YWlsOiAnVGhlIHRvb2wgY291bGQgbm90IHN0YXJ0LiBTZWUgdGhlIGJyb3dzZXIgY29uc29sZSBmb3IgZGV0YWlscy4nLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmRldGVjdENoYW5nZXNTYWZlbHkoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBXaGVyZSB0aGUgb3BlbiBkaWFsb2cgdG9vbCdzIGhvc3QgZWxlbWVudCBpcyBhdHRhY2hlZCBvbmNlIGl0cyBkaWFsb2cgcmVuZGVycy4gKi9cbiAgQFZpZXdDaGlsZCgndG9vbERpYWxvZ1Nsb3QnKVxuICBzZXQgdG9vbERpYWxvZ1Nsb3QocmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiB8IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGhvc3QgPSB0aGlzLnRvb2xEaWFsb2c/Lmhvc3Q7XG4gICAgaWYgKHJlZiAmJiBob3N0ICYmIGhvc3QucGFyZW50RWxlbWVudCAhPT0gcmVmLm5hdGl2ZUVsZW1lbnQpIHJlZi5uYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKGhvc3QpO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIgdG9vbHMgZm9yIGNvbnRyaWJ1dGVkIG1vZGVzLiBDYWxscyBjYW4gY29tZSBmcm9tIG91dHNpZGUgQW5ndWxhciwgaGVuY2UgdGhlIHpvbmUuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcGxvdE1vZGVUb29sczogUGxvdE1vZGVUb29scyA9IHtcbiAgICBhcm1CcnVzaDogKGJydXNoQ2xhc3M/OiBQbG90TW9kZUJydXNoQ2xhc3MpID0+IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICB0aGlzLmJydXNoQ2xhc3MgPSB7IGxhYmVsOiBicnVzaENsYXNzPy5sYWJlbCwgY29sb3I6IGJydXNoQ2xhc3M/LmNvbG9yIH07XG4gICAgICBpZiAodGhpcy5hY3RpdmVEcmFnTW9kZSA9PT0gJ2JydXNoJykge1xuICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldEJydXNoT3B0aW9ucyh7IHNpemU6IHRoaXMuYnJ1c2hTaXplLCAuLi50aGlzLmJydXNoQ2xhc3MgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFwcGx5RHJhZ01vZGUoJ2JydXNoJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KSxcbiAgICBkaXNhcm06ICgpID0+IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICB0aGlzLmJydXNoQ2xhc3MgPSBudWxsO1xuICAgICAgaWYgKHRoaXMuYWN0aXZlRHJhZ01vZGUgIT09IG51bGwpIHRoaXMuYXBwbHlEcmFnTW9kZShudWxsKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pLFxuICAgIGFjdGl2ZVRvb2wkOiB0aGlzLnNlc3Npb24uZ2V0QWN0aXZlVG9vbCQoKSxcbiAgfTtcblxuICAvKiogRGVhY3RpdmF0ZSB3aGF0ZXZlciB0b29sIGlzIGFybWVkIGFuZCBjbGVhciBldmVyeSB0b29sIG1vZGUuICovXG4gIHByaXZhdGUgZGVhY3RpdmF0ZUFjdGl2ZVRvb2woKSB7XG4gICAgdGhpcy5icnVzaENsYXNzID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZURyYWdNb2RlID0gbnVsbDtcbiAgICB0aGlzLnNlc3Npb24uc2V0QWN0aXZlVG9vbChudWxsKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvbk92ZXJsYXkoKT8uc2V0TW9kZSgnbm9uZScpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0RHJhZ01vZGUoZmFsc2UpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0Wm9vbVRvQm94TW9kZShmYWxzZSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRXYW5kTW9kZShmYWxzZSk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRCcnVzaE1vZGUoZmFsc2UpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2FtUG9pbnRNb2RlKGZhbHNlKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFZlcnRleEVyYXNlck1vZGUoZmFsc2UpO1xuICB9XG59XG5cbiIsIjwhLS0gU0FNIHRvYXN0OiBsaXZlIHN0YXR1cyArIGVuY29kZXItZG93bmxvYWQgcHJvZ3Jlc3MgYmFyIChqaXQtdWkjOTApLiBTdGlja3lcbiAgICAgd2hpbGUgYSBzZWdtZW50IHJ1bnM7IHN0YXlzIG9wZW4gdW50aWwgdGhlIGJhciByZWFjaGVzIDEwMCUgYW5kIHRoZSBydW4gZW5kcy4gLS0+XG48cC10b2FzdCBba2V5XT1cInNhbVRvYXN0S2V5XCIgcG9zaXRpb249XCJib3R0b20tcmlnaHRcIj5cbiAgPG5nLXRlbXBsYXRlIGxldC1tZXNzYWdlIHBUZW1wbGF0ZT1cIm1lc3NhZ2VcIj5cbiAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgbWluLXdpZHRoOiAxNnJlbVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvbnQtYm9sZCBtYi0xXCI+e3sgbWVzc2FnZS5zdW1tYXJ5IH19PC9kaXY+XG4gICAgICA8ZGl2Pnt7IHNhbVN0YXR1cyB8fCBtZXNzYWdlLmRldGFpbCB9fTwvZGl2PlxuICAgICAgPHAtcHJvZ3Jlc3NCYXIgKm5nSWY9XCJzYW1Eb3dubG9hZGluZ1wiIFt2YWx1ZV09XCJzYW1Qcm9ncmVzc1wiIHN0eWxlQ2xhc3M9XCJtdC0yIHNhbS1wcm9ncmVzc1wiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgIDxwLXByb2dyZXNzQmFyICpuZ0lmPVwic2FtQnVzeSAmJiAhc2FtRG93bmxvYWRpbmdcIiBtb2RlPVwiaW5kZXRlcm1pbmF0ZVwiIHN0eWxlQ2xhc3M9XCJtdC0yXCJcbiAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7IGhlaWdodDogJzRweCcgfVwiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC10b2FzdD5cblxuPCEtLSBSZXN1bHQvZXJyb3Igbm90aWNlcyBmcm9tIHRoZSBsaWJyYXJ5IGl0c2VsZiAoc2VnbWVudGF0aW9uIG91dGNvbWUsIHJlZ2lvblxuICAgICB2YWxpZGF0aW9uKS4gUmVuZGVyZWQgaGVyZSBzbyB0aGV5IGRvIG5vdCBkZXBlbmQgb24gdGhlIGhvc3QgbW91bnRpbmcgYVxuICAgICBrZXlsZXNzIDxwLXRvYXN0PiDigJQgd2l0aG91dCB0aGlzIHRoZSBtZXNzYWdlcyB3ZW50IG5vd2hlcmUgaW4gYW55IGhvc3QgYnV0XG4gICAgIGppdC11aSwgYW5kIGEgZmFpbGVkIHJ1biBsb29rZWQgbGlrZSBhIGJ1dHRvbiB0aGF0IGRpZCBub3RoaW5nLiAtLT5cbjxwLXRvYXN0IFtrZXldPVwicmVzdWx0VG9hc3RLZXlcIiBwb3NpdGlvbj1cImJvdHRvbS1yaWdodFwiPjwvcC10b2FzdD5cblxuPCEtLSBTaGFyZWQgb3V0bGV0cyBmb3Igbm90aWNlcyByYWlzZWQgd2hlcmUgdGhlcmUgaXMgbm8gcGVyLWluc3RhbmNlIGtleSB0byB1c2U6XG4gICAgIHRoZSByb290LXByb3ZpZGVkIFBsb3RseVNlcnZpY2UgYW5kIHRoZSByZWdpb24tZWRpdG9yIGRpYWxvZy4gUmVuZGVyZWQgYnkgYVxuICAgICBzaW5nbGUgdmlzdWFsaXplciAob3duc1NoYXJlZFRvYXN0cykgc28gYSBtZXNzYWdlIGZyb20gdGhlIHJvb3Qgc2VydmljZSBpc1xuICAgICBub3Qgc2hvd24gb25jZSBwZXIgbGl2ZSB2aWV3ZXIuIC0tPlxuPHAtdG9hc3QgKm5nSWY9XCJvd25zU2hhcmVkVG9hc3RzXCIgW2tleV09XCJ2aXpUb2FzdEtleVwiPjwvcC10b2FzdD5cbjxwLXRvYXN0ICpuZ0lmPVwib3duc1NoYXJlZFRvYXN0c1wiIFtrZXldPVwidml6QWxlcnRUb2FzdEtleVwiIHBvc2l0aW9uPVwiY2VudGVyXCI+PC9wLXRvYXN0PlxuXG48IS0tIFRvb2xiYXIgZG9jazogZG9ja2VkIGFjcm9zcyB0aGUgdG9wIGJ5IGRlZmF1bHQ7IGRyYWcgdGhlIGhhbmRsZSB0byBkZXRhY2hcbiAgICAgaXQgaW50byBhIGZsb2F0aW5nLCBtb3ZhYmxlIHdpbmRvdyAoZnJlZXMgdGhlIHRvcCByb3cgZm9yIHRoZSBpbWFnZSkuIC0tPlxuPGRpdiBjbGFzcz1cInRvb2xiYXItZG9ja1wiIFtjbGFzcy5mbG9hdGluZ109XCJ0b29sYmFyRmxvYXRpbmdcIlxuICAgICBbc3R5bGUubGVmdC5weF09XCJ0b29sYmFyRmxvYXRpbmcgPyB0b29sYmFyUG9zLnggOiBudWxsXCJcbiAgICAgW3N0eWxlLnRvcC5weF09XCJ0b29sYmFyRmxvYXRpbmcgPyB0b29sYmFyUG9zLnkgOiBudWxsXCI+XG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLWRyYWctaGFuZGxlXCIgKG1vdXNlZG93bik9XCJvblRvb2xiYXJEcmFnU3RhcnQoJGV2ZW50KVwiXG4gICAgICAgcFRvb2x0aXA9XCJEcmFnIHRvIGZsb2F0IHRoZSB0b29sYmFyXCIgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCI+XG4gICAgPGkgY2xhc3M9XCJwaSBwaS1iYXJzXCI+PC9pPlxuICA8L2Rpdj5cbjxwbG90dGluZy10b29sYmFyXG4gIFtpbWFnZUluZm9dPVwiaW1hZ2VJbmZvXCJcbiAgW3Bsb3RUeXBlT3B0aW9uc109XCJwbG90VHlwZU1lbnVcIlxuICBbc2VsZWN0ZWRQbG90VHlwZV09XCJzZWxlY3RlZFBsb3RUeXBlSWRcIlxuICBbYmFzZVBsb3RUeXBlXT1cImJhc2VQbG90VHlwZVwiXG4gIFtpc29SYW5nZV09XCJpc29SYW5nZVwiXG4gIFttYXhJbmRleF09XCJtYXhJbmRleFwiXG4gIFt6SW5kZXhdPVwiekluZGV4XCJcbiAgW2lzSGVhdG1hcF09XCJpc0hlYXRtYXBcIlxuICBbaXMzZFJlZ2lvbnNdPVwiaXNTcGF0aWFsM2RNb2RlXCJcbiAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgW2FjdGl2ZVN1cmZhY2UzZE1vZGVdPVwiYWN0aXZlU3VyZmFjZTNkTW9kZVwiXG4gIFtheGVzVmlzaWJsZV09XCJheGVzVmlzaWJsZVwiXG4gIFt3aXJlZnJhbWVBY3RpdmVdPVwid2lyZWZyYW1lQWN0aXZlXCJcbiAgW3Jlc29sdXRpb25TY2FsZV09XCJyZXNvbHV0aW9uU2NhbGVcIlxuICBbd2FuZFNlbnNpdGl2aXR5XT1cIndhbmRTZW5zaXRpdml0eVwiXG4gIFticnVzaFNpemVdPVwiYnJ1c2hTaXplXCJcbiAgW3NhbU1vZGVsc109XCJzYW1Nb2RlbHNcIlxuICBbc2FtTW9kZWxJZF09XCJzYW1Nb2RlbElkXCJcbiAgW2NvbnRyaWJ1dGVkVG9vbHNdPVwiY29udHJpYnV0ZWRUb29sc1wiXG4gIFtkaWFsb2dUb29sc109XCJkaWFsb2dUb29sc1wiXG4gIFtvcGVuRGlhbG9nVG9vbElkXT1cIm9wZW5EaWFsb2dUb29sSWRcIlxuICAodG9nZ2xlRGlhbG9nVG9vbCk9XCJ0b2dnbGVEaWFsb2dUb29sKCRldmVudClcIlxuICBbdG9vbE1vZGVsSWRzXT1cInRvb2xNb2RlbElkc1wiXG4gIFt2ZXJ0ZXhFcmFzZXJSYWRpdXNdPVwidmVydGV4RXJhc2VyUmFkaXVzXCJcbiAgW2NhblVuZG9dPVwiY2FuVW5kb1JlZ2lvblwiXG4gIFtjYW5SZWRvXT1cImNhblJlZG9SZWdpb25cIlxuICBbc3RhY2tPcHRpb25zXT1cInN0YWNrT3B0aW9uc1wiXG4gIFt0b29sc109XCJ0b29sYmFyVG9vbHNcIlxuICBbaW1hZ2VTbW9vdGhpbmdFbmFibGVkXT1cImltYWdlU21vb3RoaW5nRW5hYmxlZFwiXG4gIChzZWxlY3RQbG90VHlwZSk9XCJvblNlbGVjdFBsb3RUeXBlKCRldmVudClcIlxuICAodG9nZ2xlSW1hZ2VTbW9vdGhpbmcpPVwib25Ub2dnbGVJbWFnZVNtb290aGluZygpXCJcbiAgKGFkZFByb2ZpbGVMaW5lKT1cImFkZFByb2ZpbGVMaW5lKClcIlxuICAoaXNvUmFuZ2VDaGFuZ2UpPVwib25Jc29SYW5nZUNoYW5nZSgkZXZlbnQpXCJcbiAgKG9wZW5DaGFubmVsSGlzdG9ncmFtKT1cIm9wZW5DaGFubmVsSGlzdG9ncmFtKClcIlxuICAob3BlblNwYXRpYWxDb250cm9scyk9XCJvcGVuU3BhdGlhbENvbnRyb2xzKClcIlxuICAob3BlblJlZ2lvbkVkaXRvcik9XCJvcGVuUmVnaW9uRWRpdG9yKClcIlxuICAoc2VsZWN0U3RhY2tPcHRpb24pPVwic2VsZWN0U3RhY2tPcHRpb24oJGV2ZW50KVwiXG4gICh6U2NydWIpPVwib25aU2NydWIoJGV2ZW50KVwiXG4gICh6U2xpZGUpPVwib25aU2xpZGUoJGV2ZW50KVwiXG4gICh6SW5kZXhJbnB1dCk9XCJ6SW5kZXggPSAkZXZlbnQ7IHVwZGF0ZVpJbmRleCgpXCJcbiAgKHJlbG9hZEFuZFBsb3QpPVwicmVsb2FkQW5kUGxvdCgpXCJcbiAgKGRvd25sb2FkSW1hZ2UpPVwiZG93bmxvYWRJbWFnZSgpXCJcbiAgKGF1dG9zY2FsZUltYWdlKT1cImF1dG9zY2FsZUltYWdlKClcIlxuICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUoJGV2ZW50KVwiXG4gICh6b29tSW4pPVwiem9vbUluKClcIlxuICAoem9vbU91dCk9XCJ6b29tT3V0KClcIlxuICAodG9nZ2xlU3VyZmFjZTNkTW9kZSk9XCJ0b2dnbGVTdXJmYWNlM2RNb2RlKCRldmVudClcIlxuICAocmVzZXRTdXJmYWNlQ2FtZXJhKT1cInJlc2V0U3VyZmFjZUNhbWVyYSgpXCJcbiAgKHRvZ2dsZUF4ZXMpPVwidG9nZ2xlQXhlcygpXCJcbiAgKHRvZ2dsZVdpcmVmcmFtZSk9XCJ0b2dnbGVXaXJlZnJhbWUoKVwiXG4gIChzZWxlY3RSZXNvbHV0aW9uKT1cInNlbGVjdFJlc29sdXRpb24oJGV2ZW50KVwiXG4gIChkZWxldGVSZWdpb24pPVwiZGVsZXRlUmVnaW9uKClcIlxuICAodW5kb1JlZ2lvbik9XCJ1bmRvUmVnaW9uKClcIlxuICAocmVkb1JlZ2lvbik9XCJyZWRvUmVnaW9uKClcIlxuICAoc2VnbWVudFJlZ2lvbnMpPVwic2VnbWVudFJlZ2lvbnMoKVwiXG4gIChzZWdtZW50Q2VsbHBvc2UpPVwic2VnbWVudENlbGxwb3NlKClcIlxuICAoc2FtTW9kZWxDaGFuZ2UpPVwib25TYW1Nb2RlbENoYW5nZSgkZXZlbnQpXCJcbiAgKHJ1blRvb2wpPVwicnVuVG9vbCgkZXZlbnQpXCJcbiAgKHRvb2xNb2RlbENoYW5nZSk9XCJvblRvb2xNb2RlbENoYW5nZSgkZXZlbnQpXCJcbiAgKG9wZW5Ub29sUGFyYW1zKT1cIm9wZW5Ub29sUGFyYW1zKCRldmVudClcIlxuICAod2FuZFNlbnNpdGl2aXR5Q2hhbmdlKT1cIm9uV2FuZFNlbnNpdGl2aXR5Q2hhbmdlKCRldmVudClcIlxuICAoYnJ1c2hTaXplQ2hhbmdlKT1cIm9uQnJ1c2hTaXplQ2hhbmdlKCRldmVudClcIlxuICAodmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlKT1cIm9uVmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlKCRldmVudClcIj5cbiAgPCEtLSBIb3N0LXByb2plY3RlZCBjdXN0b20gdG9vbGJhciBidXR0b25zLCBmb3J3YXJkZWQgaW50byB0aGUgdG9vbGJhci4gLS0+XG4gIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvcGxvdHRpbmctdG9vbGJhcj5cbiAgPHAtYnV0dG9uICpuZ0lmPVwidG9vbGJhckZsb2F0aW5nXCIgY2xhc3M9XCJ0b29sYmFyLWRvY2stYnRuXCIgaWNvbj1cInBpIHBpLXRodW1idGFja1wiIHNpemU9XCJzbWFsbFwiIFt0ZXh0XT1cInRydWVcIlxuICAgICAgICAgICAgcFRvb2x0aXA9XCJEb2NrIHRvIHRvcFwiIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiIChvbkNsaWNrKT1cImRvY2tUb29sYmFyKClcIj5cbiAgPC9wLWJ1dHRvbj5cbjwvZGl2PlxuXG48cC1jb250ZXh0TWVudSAjY20gW21vZGVsXT1cImNvbnRleHRNZW51SXRlbXNcIiBhcHBlbmRUbz1cImJvZHlcIj48L3AtY29udGV4dE1lbnU+XG48IS0tIE5vIGBoLWZ1bGxgIGhlcmU6IFByaW1lRmxleCdzIGhlaWdodDoxMDAlICFpbXBvcnRhbnQgbWFkZSAjcGxvdCBhcyB0YWxsIGFzXG4gICAgIHRoZSB3aG9sZSBob3N0LCBzbyB1bmRlciB0aGUgZG9ja2VkIHRvb2xiYXIgaXRzIGJvdHRvbSB0b29sYmFyLWhlaWdodCBzdHJpcFxuICAgICAoaW5jbC4gdGhlIE9TRCBzY2FsZSBiYXIgYXQgYm90dG9tLWxlZnQpIHdhcyBjbGlwcGVkIGJ5IHRoZSBob3N0J3NcbiAgICAgb3ZlcmZsb3c6aGlkZGVuLiBUaGUgY29tcG9uZW50IHN0eWxlc2hlZXQgc2l6ZXMgaXQgKC52aXotcGxvdCB7IGZsZXg6IDEgfSkuIC0tPlxuPGRpdiBjbGFzcz1cInctZnVsbCByZWxhdGl2ZSB2aXotcGxvdFwiIFtpZF09XCJwbG90RGl2TmFtZVwiPlxuICA8ZGl2ICpuZ0lmPVwiaW1nTG9hZGluZyB8fCBzdGFja0xvYWRpbmcgfHwgaXNDYWNoaW5nXCIgaWQ9XCJvdmVybGF5XCI+XG4gICAgPCEtLSBEZXRlcm1pbmF0ZSBzdGFjay92b2x1bWUgcHJvZ3Jlc3MgdGFrZXMgcHJlY2VkZW5jZTogd2hpbGUgaXQncyBhY3RpdmUgc2hvdyBPTkxZIHRoZVxuICAgICAgICAgcHJvZ3Jlc3MgYmFyICsgXCJMb2FkaW5nIGZyYW1lcy4uLlwiLCBub3QgdGhlIGdlbmVyaWMgc3Bpbm5lci9cIkxvYWRpbmcgaW1hZ2UuLi5cIiBvbiB0b3Agb2ZcbiAgICAgICAgIGl0IChib3RoIHdlcmUgcmVuZGVyaW5nIGF0IG9uY2UgZm9yIG5hcGFyaSB2b2x1bWUvaXNvc3VyZmFjZSBsb2FkcykuIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzdGFja0xvYWRpbmc7IGVsc2UgaW1nTG9hZGluZ1RwbFwiPlxuICAgICAgPHAtcHJvZ3Jlc3NCYXIgY2xhc3M9XCJwcm9ncmVzc1wiIFt2YWx1ZV09XCJsb2FkaW5nUGVyY2VudGFnZVwiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sb2FkaW5nXCI+TG9hZGluZyBmcmFtZXMuLi48L3NwYW4+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLXRlbXBsYXRlICNpbWdMb2FkaW5nVHBsPlxuICAgICAgPCEtLSBDYWNoZS1jb3B5IHByb2dyZXNzIGlzIHNob3duIHdoZW5ldmVyIGEgY2FjaGUgZG93bmxvYWQgaXMgYWN0aXZlIChpc0NhY2hpbmcpLCBpbmRlcGVuZGVudFxuICAgICAgICAgICBvZiBgaW1nTG9hZGluZ2AsIHNvIGl0J3MgbmV2ZXIgZHJvcHBlZC9tYXNrZWQgbWlkLWRvd25sb2FkLiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NhY2hpbmc7IGVsc2Ugc3Bpbm5lckxvYWRpbmdcIj5cbiAgICAgICAgPCEtLSBTdGFnZS1hd2FyZSBtZXNzYWdlIGNvbWVzIGZyb20gQ2FjaGVQcm9ncmVzc1NlcnZpY2UgdXBkYXRpbmdcbiAgICAgICAgICAgICBpbWFnZUxvYWRpbmdNZXNzYWdlJCAoXCJDYWNoaW5nIGltYWdlLi4uXCIgZHVyaW5nIHRoZSBHQ1MgZG93bmxvYWQsXG4gICAgICAgICAgICAgdGhlbiBcIkdlbmVyYXRpbmcgcHJldmlldy4uLlwiIGR1cmluZyBwZXItc2xpY2UgdGh1bWJuYWlsIGdlbikuIE9uY2UgdGhlXG4gICAgICAgICAgICAgZG93bmxvYWQgaGl0cyAxMDAlIHRoZSByZW1haW5pbmcgd29yayAoc2VydmVyIHByZXZpZXcvdGlsZSBnZW5lcmF0aW9uKVxuICAgICAgICAgICAgIGhhcyBubyBkZXRlcm1pbmF0ZSBwcm9ncmVzcywgc28gZmFsbCB0aHJvdWdoIHRvIHRoZSBzcGlubmVyIHRlbXBsYXRlXG4gICAgICAgICAgICAgcmF0aGVyIHRoYW4gcGFya2luZyBhIGZ1bGwgYmFyIHVuZGVyIFwiTG9hZGluZyBpbWFnZS4uLlwiLiAtLT5cbiAgICAgICAgPHAtcHJvZ3Jlc3NCYXIgY2xhc3M9XCJwcm9ncmVzc1wiIFt2YWx1ZV09XCJjYWNoZVByb2dyZXNzXCI+PC9wLXByb2dyZXNzQmFyPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPnt7bG9hZGluZ01lc3NhZ2V9fTwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLXRlbXBsYXRlICNzcGlubmVyTG9hZGluZz5cbiAgICAgICAgPGRpdiAqbmdJZj1cImltZ0xvYWRpbmdcIiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCJpbWdMb2FkaW5nICYmICF6b29tXCIgY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj57e2xvYWRpbmdNZXNzYWdlfX08L3NwYW4+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaW1nTG9hZGluZyAmJiB6b29tXCIgY2xhc3M9XCJ6b29tLXRleHQtbG9hZGluZ1wiPnt7bG9hZGluZ01lc3NhZ2V9fTwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8cC1idXR0b24gKm5nSWY9XCJzdGFja0xvYWRpbmcgfHwgaW1nTG9hZGluZ1wiIGNsYXNzPVwiY2FuY2VsLWxvYWRpbmcgXCIgbGFiZWw9XCJDYW5jZWxcIlxuICAgICAgICAgICAgICAob25DbGljayk9XCJjYW5jZWxMb2FkaW5nKClcIj5cbiAgICA8L3AtYnV0dG9uPlxuICA8L2Rpdj5cbiAgPCEtLSBUcmFuc2x1Y2VudCBcInNoYXJwZW5pbmdcIiBvdmVybGF5IHNob3duIGFmdGVyIHRoZSBzbWFsbC10aWVyIHByZXZpZXcgaXNcbiAgICAgICBvbiBzY3JlZW4gd2hpbGUgdGhlIGxhcmdlLXRpZXIgcmVuZGVyIGlzIHN0aWxsIGxvYWRpbmcgaW4gdGhlXG4gICAgICAgYmFja2dyb3VuZC4gTGV0cyB0aGUgdXNlciBzZWUgdGhlIGJsdXJyeSBpbWFnZSB1bmRlcm5lYXRoIGJ1dCBtYWtlc1xuICAgICAgIGl0IGNsZWFyIHNvbWV0aGluZyBpcyBzdGlsbCBsb2FkaW5nIHNvIHRoZXkgZG9uJ3QgbWlzdGFrZSB0aGVcbiAgICAgICBsb3ctcmVzIHJlbmRlciBmb3IgdGhlIGZpbmFsIGltYWdlLiAtLT5cbiAgPGRpdiAqbmdJZj1cInNoYXJwZW5pbmcgJiYgIWltZ0xvYWRpbmcgJiYgIXN0YWNrTG9hZGluZyAmJiAhaXNDYWNoaW5nXCIgaWQ9XCJzaGFycGVuaW5nLW92ZXJsYXlcIj5cbiAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lclwiPjwvZGl2PlxuICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sb2FkaW5nXCI+U2hhcnBlbmluZyBwcmV2aWV3Li4uPC9zcGFuPlxuICA8L2Rpdj5cblxuPC9kaXY+XG5cbjwhLS0gRmxvYXRpbmcsIGRyYWdnYWJsZSBpbnRlbnNpdHktcHJvZmlsZSBpbnNldC4gU2hvd24gaW4gTElORSBtb2RlOyB0aGUgY2hhcnRcbiAgICAgdXBkYXRlcyBsaXZlIGFzIHRoZSBsaW5lIFJPSSBvbiB0aGUgaW1hZ2UgaXMgbW92ZWQuIEtlcHQgT1VUU0lERSAjcGxvdCBhbmRcbiAgICAgcG9zaXRpb25lZCBmaXhlZCBzbyBpdCBmbG9hdHMgb3ZlciB0aGUgd2hvbGUgcGFnZSAobm90IGNsaXBwZWQgdG8gdGhlXG4gICAgIGRpYWdyYW0vY2FudmFzIGFyZWEpLiAtLT5cbjxkaXYgKm5nSWY9XCJoYXNQcm9maWxlc1wiIGNsYXNzPVwiaW50ZW5zaXR5LXBhbmVsXCJcbiAgICAgW3N0eWxlLmxlZnQucHhdPVwicHJvZmlsZVBhbmVsUG9zLnhcIiBbc3R5bGUudG9wLnB4XT1cInByb2ZpbGVQYW5lbFBvcy55XCI+XG4gIDxkaXYgY2xhc3M9XCJpbnRlbnNpdHktcGFuZWwtaGVhZGVyXCIgKG1vdXNlZG93bik9XCJvblByb2ZpbGVQYW5lbERyYWdTdGFydCgkZXZlbnQpXCI+XG4gICAgPHNwYW4+SW50ZW5zaXR5IHByb2ZpbGU8L3NwYW4+XG4gICAgPGkgY2xhc3M9XCJwaSBwaS1hcnJvd3MtYWx0XCI+PC9pPlxuICA8L2Rpdj5cbiAgPGRpdiBbaWRdPVwiaW50ZW5zaXR5SW5zZXREaXZcIiBjbGFzcz1cImludGVuc2l0eS1wYW5lbC1wbG90XCI+PC9kaXY+XG48L2Rpdj5cblxuPCEtLSBDaGFubmVscyAmIEhpc3RvZ3JhbTogbm9uLW1vZGFsIGZsb2F0aW5nIGRpYWxvZyBvcGVuZWQgZnJvbSB0aGUgdG9vbGJhci4gLS0+XG48Y2hhbm5lbC1oaXN0b2dyYW0gWyh2aXNpYmxlKV09XCJzaG93Q2hhbm5lbEhpc3RvZ3JhbVwiPjwvY2hhbm5lbC1oaXN0b2dyYW0+XG5cbjwhLS0gU3BhdGlhbC1vbWljcyBjb250cm9scy4gUmVuZGVycyBpdHMgb3duIGVtcHR5IHN0YXRlIHdoZW4gbm8gZGF0YXNldCAob3Igbm9cbiAgICAgU1BBVElBTF9EQVRBX1BPUlQpIGlzIHByZXNlbnQsIHNvIGl0IGlzIGFsd2F5cyBzYWZlIHRvIGhvc3QuIC0tPlxuPHNwYXRpYWwtY29udHJvbHMgWyh2aXNpYmxlKV09XCJzaG93U3BhdGlhbENvbnRyb2xzXCIgW2lzM2RdPVwiaXNTcGF0aWFsM2RNb2RlXCIgPjwvc3BhdGlhbC1jb250cm9scz5cblxuPCEtLSBTaWRlIHBhbmVsIG9mIHRoZSBhY3RpdmUgY29udHJpYnV0ZWQgcGxvdCBtb2RlIChQTE9UX1RZUEVfQ09OVFJJQlVUSU9OUyksXG4gICAgIGluIHRoZSBzYW1lIHJpZ2h0LWhhbmQgYXJlYSBhcyB0aGUgc3BhdGlhbCBjb250cm9scyBhbmQgdGhlIFJlZ2lvbiBFZGl0b3IuXG4gICAgIEV4aXN0cyBvbmx5IHdoaWxlIHRoZSBtb2RlJ3Mgc2Vzc2lvbiBpcyBsaXZlOyB0aGVyZSBpcyBubyBjbG9zZSBidXR0b24sXG4gICAgIGJlY2F1c2UgbGVhdmluZyB0aGUgbW9kZSBpcyB3aGF0IGVuZHMgaXQuIEEgY29tcG9uZW50IHBhbmVsIGdldHNcbiAgICAgUExPVF9NT0RFX0NPTlRFWFQgLyBQTE9UX01PREVfU0VTU0lPTiBmcm9tIGl0cyBpbmplY3RvcjsgYSBgbW91bnRgIHBhbmVsJ3NcbiAgICAgaG9zdCBlbGVtZW50IGlzIGF0dGFjaGVkIHRvIHRoZSBzbG90IGJlbG93IChzZWUgcGxvdE1vZGVQYW5lbFNsb3QpLiAtLT5cbjxwLWRpYWxvZyAqbmdJZj1cInBsb3RNb2RlUGFuZWwgYXMgcGFuZWxcIiBbaGVhZGVyXT1cInBhbmVsLnRpdGxlXCIgW3Zpc2libGVdPVwidHJ1ZVwiXG4gICAgICAgICAgW21vZGFsXT1cImZhbHNlXCIgW2Nsb3NhYmxlXT1cImZhbHNlXCIgW3Jlc2l6YWJsZV09XCJ0cnVlXCIgW2RyYWdnYWJsZV09XCJ0cnVlXCJcbiAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIiBwb3NpdGlvbj1cInJpZ2h0XCIgc3R5bGVDbGFzcz1cInBsb3QtbW9kZS1wYW5lbFwiXG4gICAgICAgICAgW3N0eWxlXT1cInsgd2lkdGg6ICcyMnJlbScsIG1heEhlaWdodDogJzg1dmgnIH1cIlxuICAgICAgICAgIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhbmVsLmNvbXBvbmVudFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nQ29tcG9uZW50T3V0bGV0PVwicGFuZWwuY29tcG9uZW50OyBpbmplY3RvcjogcGFuZWwuaW5qZWN0b3IgPz8gdW5kZWZpbmVkXCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuICA8ZGl2ICpuZ0lmPVwicGFuZWwuaG9zdFwiICNwbG90TW9kZVBhbmVsU2xvdCBjbGFzcz1cInBsb3QtbW9kZS1wYW5lbC1zbG90XCI+PC9kaXY+XG48L3AtZGlhbG9nPlxuXG48IS0tIEFuIG9wZW4gZGlhbG9nIHRvb2wgKFRPT0xCQVJfVE9PTFMsIGtpbmQ6ICdkaWFsb2cnKS4gTm9uLW1vZGFsIHNvIHRoZSB1c2VyIGNhblxuICAgICBrZWVwIHdvcmtpbmcgb24gdGhlIGltYWdlLCBlLmcuIHBhaW50aW5nIHdpdGggdGhlIGJydXNoIHRoZSB0b29sIGFybWVkLiBUaGVcbiAgICAgdG9vbCByZW5kZXJzIGl0cyBib2R5IGludG8gYSBob3N0IGVsZW1lbnQgYXR0YWNoZWQgdG8gdGhlIHNsb3QgYmVsb3cgKHNlZVxuICAgICB0b29sRGlhbG9nU2xvdCk7IGNsb3NpbmcgdGhlIGRpYWxvZyBlbmRzIHRoZSB0b29sJ3Mgc2Vzc2lvbi4gLS0+XG48cC1kaWFsb2cgKm5nSWY9XCJ0b29sRGlhbG9nIGFzIGRsZ1wiIFtoZWFkZXJdPVwiZGxnLnRpdGxlXCIgW3Zpc2libGVdPVwidHJ1ZVwiXG4gICAgICAgICAgKHZpc2libGVDaGFuZ2UpPVwiJGV2ZW50IHx8IGNsb3NlRGlhbG9nVG9vbCgpXCJcbiAgICAgICAgICBbbW9kYWxdPVwiZmFsc2VcIiBbY2xvc2FibGVdPVwidHJ1ZVwiIFtyZXNpemFibGVdPVwidHJ1ZVwiIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gICAgICAgICAgYXBwZW5kVG89XCJib2R5XCIgcG9zaXRpb249XCJyaWdodFwiIHN0eWxlQ2xhc3M9XCJ0b29sLWRpYWxvZ1wiXG4gICAgICAgICAgW3N0eWxlXT1cInsgd2lkdGg6IGRsZy53aWR0aCwgbWF4SGVpZ2h0OiAnODV2aCcgfVwiXG4gICAgICAgICAgW2NvbnRlbnRTdHlsZV09XCJ7IG92ZXJmbG93OiAnYXV0bycgfVwiPlxuICA8ZGl2ICN0b29sRGlhbG9nU2xvdCBjbGFzcz1cInRvb2wtZGlhbG9nLXNsb3RcIj48L2Rpdj5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gUmVnaW9uIEVkaXRvcjogbm9uLW1vZGFsLCBkcmFnZ2FibGUsIHJlc2l6YWJsZSBmbG9hdGluZyBkaWFsb2cgb3BlbmVkIGZyb21cbiAgICAgdGhlIHRvb2xiYXIgKGZvcm1lcmx5IHRoZSByaWdodC1wYW5lbCBSZWdpb25zIHRhYikuIE1vZGVsZXNzIHNvIHJlZ2lvbnMgY2FuXG4gICAgIHN0aWxsIGJlIGRyYXduL3NlbGVjdGVkIG9uIHRoZSBwbG90IHdoaWxlIGl0J3Mgb3Blbjsgc3RheXMgbGlua2VkIHRvIHRoaXNcbiAgICAgcGxvdHRpbmcgaW5zdGFuY2UgdmlhIHRoZSByb290IFJlZ2lvblN0b3JlIHNpbmdsZXRvbi4gT3BlbnMgb3ZlciB0aGUgcmlnaHRcbiAgICAgc2lkZSBvZiB0aGUgdmlldy4gLS0+XG48cC1kaWFsb2cgaGVhZGVyPVwiUmVnaW9uIEVkaXRvclwiIFsodmlzaWJsZSldPVwic2hvd1JlZ2lvbkVkaXRvclwiXG4gICAgICAgICAgW21vZGFsXT1cImZhbHNlXCIgW3Jlc2l6YWJsZV09XCJ0cnVlXCIgW2RyYWdnYWJsZV09XCJ0cnVlXCJcbiAgICAgICAgICBbbWF4aW1pemFibGVdPVwidHJ1ZVwiIGFwcGVuZFRvPVwiYm9keVwiIHBvc2l0aW9uPVwicmlnaHRcIlxuICAgICAgICAgIFtzdHlsZV09XCJ7IHdpZHRoOiByZWdpb25FZGl0b3JXaWR0aCwgaGVpZ2h0OiAnODV2aCcgfVwiXG4gICAgICAgICAgW2NvbnRlbnRTdHlsZV09XCJ7IG92ZXJmbG93OiAnYXV0bycgfVwiPlxuICA8cmVnaW9uLWVkaXRvcj48L3JlZ2lvbi1lZGl0b3I+XG48L3AtZGlhbG9nPlxuXG48IS0tIFNpbXBsaWZ5IChEb3VnbGFz4oCTUGV1Y2tlcik6IGN1c3RvbSBweC10aHJlc2hvbGQgcGlja2VyIGZvciB0aGUgc2VsZWN0ZWRcbiAgICAgcmVnaW9uKHMpLCBvcGVuZWQgZnJvbSB0aGUgcmlnaHQtY2xpY2sgXCJTaW1wbGlmeSDilrggQ3VzdG9t4oCmXCIgYWN0aW9uLiAtLT5cbjxwLWRpYWxvZyBoZWFkZXI9XCJTaW1wbGlmeSByZWdpb24ocylcIiBbKHZpc2libGUpXT1cImRpc3BsYXlTaW1wbGlmeURpYWxvZ1wiIFttb2RhbF09XCJ0cnVlXCJcbiAgICAgICAgICBbc3R5bGVdPVwie3dpZHRoOiAnMjJyZW0nfVwiIFtkcmFnZ2FibGVdPVwiZmFsc2VcIiBbcmVzaXphYmxlXT1cImZhbHNlXCI+XG4gIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sdW1uIGdhcC0yXCI+XG4gICAgPHNwYW4+QWx0aXR1ZGUgdGhyZXNob2xkOiA8Yj57eyBzaW1wbGlmeVRocmVzaG9sZCB9fSBweDwvYj48L3NwYW4+XG4gICAgPHAtc2xpZGVyIFsobmdNb2RlbCldPVwic2ltcGxpZnlUaHJlc2hvbGRcIiBbbWluXT1cIjFcIiBbbWF4XT1cIjIwXCIgW3N0ZXBdPVwiMVwiPjwvcC1zbGlkZXI+XG4gICAgPHNtYWxsPlZlcnRpY2VzIHdpdGhpbiB0aGlzIGRpc3RhbmNlIG9mIHRoZSBsaW5lIGJldHdlZW4gdGhlaXIgbmVpZ2hib3VycyBhcmUgcmVtb3ZlZC48L3NtYWxsPlxuICA8L2Rpdj5cbiAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImZvb3RlclwiPlxuICAgIDxwLWJ1dHRvbiBsYWJlbD1cIkNhbmNlbFwiIFt0ZXh0XT1cInRydWVcIiAob25DbGljayk9XCJkaXNwbGF5U2ltcGxpZnlEaWFsb2cgPSBmYWxzZVwiPjwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uIGxhYmVsPVwiQXBwbHlcIiBpY29uPVwicGkgcGktY2hlY2tcIiAob25DbGljayk9XCJzaW1wbGlmeVJlZ2lvbnMoc2ltcGxpZnlUaHJlc2hvbGQpXCI+PC9wLWJ1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gUGFyYW1ldGVycyBmb3Igd2hpY2hldmVyIGNvbnRyaWJ1dGVkIHRvb2wgaXMgb3Blbi4gT25lIGRpYWxvZyBmb3IgYWxsIG9mXG4gICAgIHRoZW06IGEgdG9vbCBkZWNsYXJlcyBpdHMgZmllbGRzIChUb29sUGFyYW1TcGVjKSBhbmQgdGhpcyByZW5kZXJzIHRoZW0sIHNvXG4gICAgIHRoZSB0b29sYmFyIGNhbiBsYXkgZXZlcnkgdG9vbCBvdXQgdGhlIHNhbWUgd2F5IGFuZCBhIHBsdWdpbiBuZWVkcyBub1xuICAgICBQcmltZU5HIG9mIGl0cyBvd24uIERlZmF1bHRzIGNvbWUgZnJvbSB0aGUgYWN0aXZlIGNoZWNrcG9pbnQsIHNpbmNlIHRoZXlcbiAgICAgZW5jb2RlIHdoYXQgaXQgd2FzIHRyYWluZWQgZm9yLiAtLT5cbjxwLWRpYWxvZyAqbmdJZj1cIm9wZW5QYXJhbXNUb29sIGFzIHRvb2xcIlxuICAgICAgICAgIFtoZWFkZXJdPVwidG9vbC5sYWJlbCArICcgcGFyYW1ldGVycydcIlxuICAgICAgICAgIFt2aXNpYmxlXT1cInRydWVcIiAodmlzaWJsZUNoYW5nZSk9XCJvcGVuUGFyYW1zVG9vbElkID0gbnVsbFwiXG4gICAgICAgICAgW21vZGFsXT1cInRydWVcIlxuICAgICAgICAgIFtzdHlsZV09XCJ7d2lkdGg6ICczMHJlbSd9XCIgW2RyYWdnYWJsZV09XCJmYWxzZVwiIFtyZXNpemFibGVdPVwiZmFsc2VcIiBhcHBlbmRUbz1cImJvZHlcIj5cbiAgPGRpdiBjbGFzcz1cImdyaWQgZm9ybWdyaWQgcC1mbHVpZFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHAgb2YgdG9vbC5wYXJhbXNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiIFtuZ0NsYXNzXT1cInAudHlwZSA9PT0gJ2Jvb2xlYW4nID8gJ2NvbC0xMicgOiAnY29sLTYnXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInAudHlwZVwiPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ251bWJlcidcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtc21cIiBbcFRvb2x0aXBdPVwicC50b29sdGlwIHx8ICcnXCI+e3sgcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8cC1pbnB1dE51bWJlciBbbmdNb2RlbF09XCJwYXJhbXNGb3IodG9vbC5pZClbcC5pZF1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGFyYW1zRm9yKHRvb2wuaWQpW3AuaWRdID0gJGV2ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwibnVtYmVyUGFyYW0ocCkubWluXCIgW21heF09XCJudW1iZXJQYXJhbShwKS5tYXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwibnVtYmVyUGFyYW0ocCkuc3RlcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluRnJhY3Rpb25EaWdpdHNdPVwibnVtYmVyUGFyYW0ocCkuZnJhY3Rpb25EaWdpdHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCdXR0b25zXT1cInRydWVcIj48L3AtaW5wdXROdW1iZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc2VsZWN0J1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiIFtwVG9vbHRpcF09XCJwLnRvb2x0aXAgfHwgJydcIj57eyBwLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgIDxwLWRyb3Bkb3duIFtvcHRpb25zXT1cInNlbGVjdFBhcmFtKHApLm9wdGlvbnNcIiBvcHRpb25MYWJlbD1cImxhYmVsXCIgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJwYXJhbXNGb3IodG9vbC5pZClbcC5pZF1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGFyYW1zRm9yKHRvb2wuaWQpW3AuaWRdID0gJGV2ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvPVwiYm9keVwiPjwvcC1kcm9wZG93bj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDwhLS0gQ2hlY2tib3ggbGFiZWwgc2l0cyBiZXNpZGUgdGhlIGJveCBhbmQgbWF5IHJ1biB0byBhIHNlbnRlbmNlLCBzb1xuICAgICAgICAgICAgICAgaXQgZG9lcyBub3QgZ2V0IHRoZSBzdGFja2VkIGxhYmVsIHRoZSBvdGhlciB0eXBlcyB1c2UuIC0tPlxuICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIidib29sZWFuJ1wiIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgICAgICAgIDxwLWNoZWNrYm94IFtuZ01vZGVsXT1cInBhcmFtc0Zvcih0b29sLmlkKVtwLmlkXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJwYXJhbXNGb3IodG9vbC5pZClbcC5pZF0gPSAkZXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2JpbmFyeV09XCJ0cnVlXCIgW2lucHV0SWRdPVwidG9vbC5pZCArICctJyArIHAuaWRcIj48L3AtY2hlY2tib3g+XG4gICAgICAgICAgICA8bGFiZWwgW2Zvcl09XCJ0b29sLmlkICsgJy0nICsgcC5pZFwiIGNsYXNzPVwidGV4dC1zbSBtYi0wXCJcbiAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicC50b29sdGlwIHx8ICcnXCI+e3sgcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG4gIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJmb290ZXJcIj5cbiAgICA8cC1idXR0b24gbGFiZWw9XCJSZXNldCB0byBtb2RlbCBkZWZhdWx0c1wiIFt0ZXh0XT1cInRydWVcIiBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICAob25DbGljayk9XCJyZXNldFRvb2xQYXJhbXModG9vbC5pZClcIj48L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvbiBsYWJlbD1cIkNsb3NlXCIgc2l6ZT1cInNtYWxsXCIgKG9uQ2xpY2spPVwib3BlblBhcmFtc1Rvb2xJZCA9IG51bGxcIj48L3AtYnV0dG9uPlxuICA8L25nLXRlbXBsYXRlPlxuPC9wLWRpYWxvZz5cbiJdfQ==