@jax-data-science/sci-image-visualizer 0.9.0 → 0.11.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.
- package/esm2022/index.mjs +10 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +18 -2
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/osd/osd-tile-loading.mjs +71 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
- package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +670 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +44 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-import/label-classes.mjs +149 -0
- package/esm2022/lib/region-import/label-volume.mjs +194 -0
- package/esm2022/lib/region-import/region-import.mjs +71 -0
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/routing-visualizer.service.mjs +510 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +186 -0
- package/esm2022/lib/store/region-store.service.mjs +774 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +155 -7
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs} +9851 -2904
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +12 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +24 -0
- package/lib/contracts/region-editor-api.contract.d.ts +102 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +2 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/osd/osd-tile-loading.d.ts +43 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
- package/lib/implementations/osd/slice-cache.d.ts +13 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
- package/lib/region-editor/region-editor.component.d.ts +159 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +17 -5
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-import/label-classes.d.ts +39 -0
- package/lib/region-import/label-volume.d.ts +31 -0
- package/lib/region-import/region-import.d.ts +46 -0
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/routing-visualizer.service.d.ts +168 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +74 -0
- package/lib/store/region-store.service.d.ts +216 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +40 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, Inject, ViewChild, inject, NgZone, } from '@angular/core';
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, Inject, Input, ViewChild, inject, NgZone, } from '@angular/core';
|
|
2
2
|
import { markForCheckInZone } from '../util/mark-for-check';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
@@ -12,17 +12,24 @@ import { ToolbarModule } from 'primeng/toolbar';
|
|
|
12
12
|
import { TooltipModule } from 'primeng/tooltip';
|
|
13
13
|
import { saveAs } from 'file-saver';
|
|
14
14
|
import { Subject } from 'rxjs';
|
|
15
|
-
import { Rectangle } from '../models/region';
|
|
15
|
+
import { Rectangle, Region } from '../models/region';
|
|
16
16
|
import { withRegionPatch } from '../models/region-clone';
|
|
17
17
|
import { defaultPresetSet, parsePresetSet } from '../models/class-preset';
|
|
18
18
|
import { colorForLabel, presetKey } from '../store/class-color.util';
|
|
19
19
|
import { ConfirmationService, MessageService, SharedModule } from 'primeng/api';
|
|
20
20
|
import { REGION_EDITOR_API } from '../contracts/region-editor-api.contract';
|
|
21
21
|
import { VIZ_TOAST_KEY } from '../toast-outlets';
|
|
22
|
+
import { HttpClient } from '@angular/common/http';
|
|
23
|
+
import { openGeoJsonRegionSource } from '../region-source/worker-region-source';
|
|
24
|
+
import { openHttpRegionSource } from '../region-source/http-region-source';
|
|
25
|
+
import { readLabelVolume } from '../region-import/label-volume';
|
|
26
|
+
import { labelClasses, labelSliceGeoJson } from '../region-import/label-classes';
|
|
27
|
+
import { folderSliceGeoJson, importFile, planRegionImport, } from '../region-import/region-import';
|
|
22
28
|
import { RegionPersistenceService } from './region-persistence.service';
|
|
23
29
|
import { RegionColorDialogComponent } from './region-color-dialog/region-color-dialog.component';
|
|
24
30
|
import { ClassesPanelComponent } from './classes-panel/classes-panel.component';
|
|
25
31
|
import { RegionTableComponent } from './region-table/region-table.component';
|
|
32
|
+
import { ClassTreeComponent } from './class-tree/class-tree.component';
|
|
26
33
|
import { SaveRegionsDialogComponent } from './save-regions-dialog/save-regions-dialog.component';
|
|
27
34
|
import { SaveMaskDialogComponent } from './save-mask-dialog/save-mask-dialog.component';
|
|
28
35
|
import { ManageClassesDialogComponent } from './manage-classes-dialog/manage-classes-dialog.component';
|
|
@@ -33,14 +40,15 @@ import * as i0 from "@angular/core";
|
|
|
33
40
|
import * as i1 from "primeng/api";
|
|
34
41
|
import * as i2 from "./region-persistence.service";
|
|
35
42
|
import * as i3 from "./mask-export.service";
|
|
36
|
-
import * as i4 from "@angular/
|
|
37
|
-
import * as i5 from "
|
|
38
|
-
import * as i6 from "primeng/
|
|
39
|
-
import * as i7 from "primeng/
|
|
40
|
-
import * as i8 from "primeng/
|
|
41
|
-
import * as i9 from "primeng/
|
|
42
|
-
import * as i10 from "primeng/
|
|
43
|
-
import * as i11 from "primeng/
|
|
43
|
+
import * as i4 from "@angular/common";
|
|
44
|
+
import * as i5 from "@angular/forms";
|
|
45
|
+
import * as i6 from "primeng/button";
|
|
46
|
+
import * as i7 from "primeng/confirmdialog";
|
|
47
|
+
import * as i8 from "primeng/dropdown";
|
|
48
|
+
import * as i9 from "primeng/inputtext";
|
|
49
|
+
import * as i10 from "primeng/overlaypanel";
|
|
50
|
+
import * as i11 from "primeng/toolbar";
|
|
51
|
+
import * as i12 from "primeng/tooltip";
|
|
44
52
|
/**
|
|
45
53
|
* The Region Editor (`<region-editor>`): the table of the active image's
|
|
46
54
|
* annotation regions with class presets, colours, labels, GeoJSON import /
|
|
@@ -52,7 +60,25 @@ import * as i11 from "primeng/tooltip";
|
|
|
52
60
|
* API's region / selection / preset / image-meta streams, save and mask-export
|
|
53
61
|
* progress, file reads) marks it for check.
|
|
54
62
|
*/
|
|
63
|
+
/** The opacity the fill toggle fills regions at. */
|
|
64
|
+
const REGION_FILL_OPACITY = 0.6;
|
|
65
|
+
/** "Select all" takes at most this many region-source features into the regions. */
|
|
66
|
+
const SELECT_ALL_SOURCE_LIMIT = 5000;
|
|
55
67
|
export class RegionEditorComponent {
|
|
68
|
+
/**
|
|
69
|
+
* Whether the editor is on screen (its dialog open). Closed, it asks the region source nothing:
|
|
70
|
+
* its page of features, its class counts and, in a volume view, its classes' volumes are each a
|
|
71
|
+
* request over the whole set (a stack's every slice), and they competed with the volume's own
|
|
72
|
+
* slice loading for nothing anyone could see. Opened, it reads them again.
|
|
73
|
+
*/
|
|
74
|
+
set active(value) {
|
|
75
|
+
const was = this.isActive;
|
|
76
|
+
this.isActive = value;
|
|
77
|
+
if (value && !was) {
|
|
78
|
+
void this.refreshSource();
|
|
79
|
+
this.resetVolumes();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
56
82
|
/** Re-render this OnPush view, re-entering the zone when the change came from outside it. */
|
|
57
83
|
changed() {
|
|
58
84
|
markForCheckInZone(this.cdr, this.zone);
|
|
@@ -63,6 +89,9 @@ export class RegionEditorComponent {
|
|
|
63
89
|
this.confirmationService = confirmationService;
|
|
64
90
|
this.persistence = persistence;
|
|
65
91
|
this.maskExport = maskExport;
|
|
92
|
+
this.isActive = true;
|
|
93
|
+
/** The host's HttpClient: a served region set's requests go through it (its auth). */
|
|
94
|
+
this.http = inject(HttpClient, { optional: true });
|
|
66
95
|
this.regions = [];
|
|
67
96
|
this.selectedRegions = [];
|
|
68
97
|
this.displayHelpDialog = false;
|
|
@@ -97,6 +126,56 @@ export class RegionEditorComponent {
|
|
|
97
126
|
* avoids needing a unique id field. */
|
|
98
127
|
this.editingLabelRegions = new Map();
|
|
99
128
|
this.showSaveAsDialog = false;
|
|
129
|
+
/**
|
|
130
|
+
* The slice's region source (a large region set drawn by level of detail), or null. Its
|
|
131
|
+
* features are rows of the table after the regions — stand-ins until one is selected or edited,
|
|
132
|
+
* which takes it into the regions — and its classes count in the classes panel.
|
|
133
|
+
*/
|
|
134
|
+
this.sourceView = null;
|
|
135
|
+
/** Features still in the source (the table's rows after the regions). */
|
|
136
|
+
this.sourceTotal = 0;
|
|
137
|
+
/** Stand-in rows for the source features on the current page. */
|
|
138
|
+
this.sourceRows = [];
|
|
139
|
+
/** Features per class still in the source. */
|
|
140
|
+
this.sourceClassCounts = {};
|
|
141
|
+
/** The stand-in rows (rows of a source feature, not of a region). */
|
|
142
|
+
this.standIns = new WeakSet();
|
|
143
|
+
this.standInSeq = 0;
|
|
144
|
+
/** Bumped per source refresh, so a late answer is dropped. */
|
|
145
|
+
this.sourceRequest = 0;
|
|
146
|
+
/** The classes the table's Class column offers: the presets and the region source's classes
|
|
147
|
+
* (a dropdown can only show a value that is one of its options). */
|
|
148
|
+
this.tablePresetSet = defaultPresetSet();
|
|
149
|
+
/** Whether regions are drawn filled (the atlas look) rather than outlined. */
|
|
150
|
+
this.regionsFilled = false;
|
|
151
|
+
/** Whether a volume view is on screen (classes can then be shown in 3D). */
|
|
152
|
+
this.volumeView = false;
|
|
153
|
+
/** Whether the volume view's slice pane is wanted (one slice edited beside the 3D view). */
|
|
154
|
+
this.slicePane = false;
|
|
155
|
+
/** Whether the volume view draws the regions through the volume (see toggleThroughVolume). */
|
|
156
|
+
this.regionsThroughVolume = false;
|
|
157
|
+
/** Classes shown in 3D in the volume view, each with the classes its surface covers. */
|
|
158
|
+
this.shown3d = new Map();
|
|
159
|
+
/** The classes of the class tree's pick (it and its subtree), as long as the pick holds. */
|
|
160
|
+
this.pickedClasses = [];
|
|
161
|
+
/** The selected rows' classes, marked in the class lists. */
|
|
162
|
+
this.markedClasses = new Set();
|
|
163
|
+
/** The surfaces highlighted in the volume view (their keys, joined). */
|
|
164
|
+
this.highlighted3d = '';
|
|
165
|
+
/** The colour each shown surface was last drawn in. */
|
|
166
|
+
this.colors3d = new Map();
|
|
167
|
+
/** Their names, for the class lists' toggles (a new set per change, for OnPush). */
|
|
168
|
+
this.shown3dNames = new Set();
|
|
169
|
+
/** The classes hidden from view (their regions, source features and surfaces). */
|
|
170
|
+
this.hiddenClasses = new Set();
|
|
171
|
+
/** Whether a region set's class hierarchy is shown as a tree (rather than the class list). */
|
|
172
|
+
this.classTreeView = true;
|
|
173
|
+
/** The class picked last in the class tree. */
|
|
174
|
+
this.pickedClass = null;
|
|
175
|
+
/** Regions per class (the regions' and the source's), for the class tree. */
|
|
176
|
+
this.treeCounts = new Map();
|
|
177
|
+
/** A class's colour, for the class tree: a new function per colour change, so the tree repaints. */
|
|
178
|
+
this.treeColor = (name) => colorForLabel(name, this.presetSet);
|
|
100
179
|
this.saveAsFilename = '';
|
|
101
180
|
this.saveAsFileExists = false;
|
|
102
181
|
/** True while a GeoJSON persist is serializing/uploading — drives the dialog's
|
|
@@ -132,8 +211,14 @@ export class RegionEditorComponent {
|
|
|
132
211
|
/** Physical pixel size (µm/pixel) of the active image, for region areas in
|
|
133
212
|
* µm²; empty when the format reports no physical size. */
|
|
134
213
|
this.mpp = {};
|
|
214
|
+
/** In a volume view, each class's volume over the whole stack, for the table (null: areas). */
|
|
215
|
+
this.tableVolumes = null;
|
|
216
|
+
/** Bumped when the regions change, so a volume computed before is dropped. */
|
|
217
|
+
this.volumeRequest = 0;
|
|
135
218
|
this._pageKey = {};
|
|
136
219
|
this._page = [];
|
|
220
|
+
/** An import from the server is in flight. */
|
|
221
|
+
this.importing = false;
|
|
137
222
|
}
|
|
138
223
|
ngOnInit() {
|
|
139
224
|
this.showShapeLabel = this.regionApi.getShowShapeLabel();
|
|
@@ -150,7 +235,9 @@ export class RegionEditorComponent {
|
|
|
150
235
|
presets$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((set) => {
|
|
151
236
|
if (set)
|
|
152
237
|
this.presetSet = set;
|
|
238
|
+
this.treeColor = (name) => colorForLabel(name, this.presetSet);
|
|
153
239
|
this.updateDisplayClasses();
|
|
240
|
+
this.recolor3d();
|
|
154
241
|
this.changed();
|
|
155
242
|
});
|
|
156
243
|
}
|
|
@@ -179,8 +266,77 @@ export class RegionEditorComponent {
|
|
|
179
266
|
this.clampPaginatorFirst();
|
|
180
267
|
this.syncClassesFromRegions(updated);
|
|
181
268
|
this.recomputeClassCounts();
|
|
269
|
+
if (this.volumeView)
|
|
270
|
+
this.resetVolumes();
|
|
271
|
+
this.changed();
|
|
272
|
+
void this.refreshSource();
|
|
273
|
+
});
|
|
274
|
+
this.regionApi
|
|
275
|
+
.getRegionSourceView$?.()
|
|
276
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
277
|
+
.subscribe((view) => {
|
|
278
|
+
if (view?.source !== this.sourceView?.source)
|
|
279
|
+
this.pickedClass = null;
|
|
280
|
+
this.sourceView = view;
|
|
281
|
+
void this.refreshSource();
|
|
282
|
+
});
|
|
283
|
+
this.regionApi
|
|
284
|
+
.getRegionStyle$?.()
|
|
285
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
286
|
+
.subscribe((style) => {
|
|
287
|
+
this.regionsFilled = style.fillOpacity > 0;
|
|
182
288
|
this.changed();
|
|
183
289
|
});
|
|
290
|
+
this.regionApi
|
|
291
|
+
.getVolumeView$?.()
|
|
292
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
293
|
+
.subscribe((volume) => {
|
|
294
|
+
const counting = this.stackCounts;
|
|
295
|
+
this.volumeView = volume;
|
|
296
|
+
this.resetVolumes();
|
|
297
|
+
this.changed();
|
|
298
|
+
if (this.stackCounts !== counting)
|
|
299
|
+
void this.refreshSource();
|
|
300
|
+
});
|
|
301
|
+
this.regionApi
|
|
302
|
+
.getRegionsThroughVolume$?.()
|
|
303
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
304
|
+
.subscribe((through) => {
|
|
305
|
+
this.regionsThroughVolume = through;
|
|
306
|
+
this.changed();
|
|
307
|
+
});
|
|
308
|
+
this.regionApi
|
|
309
|
+
.getSliceEditor$?.()
|
|
310
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
311
|
+
.subscribe((pane) => {
|
|
312
|
+
const counting = this.stackCounts;
|
|
313
|
+
this.slicePane = pane;
|
|
314
|
+
if (this.stackCounts !== counting)
|
|
315
|
+
void this.refreshSource();
|
|
316
|
+
});
|
|
317
|
+
// What is shown in 3D: the router clears it when another image is plotted.
|
|
318
|
+
this.regionApi
|
|
319
|
+
.getRegionClasses3d$?.()
|
|
320
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
321
|
+
.subscribe((groups) => {
|
|
322
|
+
this.shown3d = new Map(groups.map((g) => [g.key, [...g.classes]]));
|
|
323
|
+
this.shown3dNames = new Set(this.shown3d.keys());
|
|
324
|
+
this.highlighted3d = '';
|
|
325
|
+
this.updateSelectionHighlight();
|
|
326
|
+
this.changed();
|
|
327
|
+
});
|
|
328
|
+
this.regionApi
|
|
329
|
+
.getHiddenClasses$?.()
|
|
330
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
331
|
+
.subscribe((hidden) => {
|
|
332
|
+
this.hiddenClasses = hidden;
|
|
333
|
+
this.changed();
|
|
334
|
+
});
|
|
335
|
+
// A surface clicked in the volume view (with the selection tool) picks its class.
|
|
336
|
+
this.regionApi
|
|
337
|
+
.getRegionPicked3d$?.()
|
|
338
|
+
?.pipe(takeUntilDestroyed(this.destroyRef))
|
|
339
|
+
.subscribe(({ key, additive }) => this.onPicked3d(key, additive));
|
|
184
340
|
this.persistence
|
|
185
341
|
.fileExists(this.saveAsCheck$)
|
|
186
342
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
@@ -208,6 +364,7 @@ export class RegionEditorComponent {
|
|
|
208
364
|
next.every((r, i) => r.id === this.selectedRegions[i]?.id);
|
|
209
365
|
if (!same)
|
|
210
366
|
this.selectedRegions = next;
|
|
367
|
+
this.updateSelectionHighlight();
|
|
211
368
|
// Scroll the paginator so the most-recently-selected row is visible.
|
|
212
369
|
if (next.length > 0) {
|
|
213
370
|
const lastIdx = this.regions.findIndex((r) => r.id === next[next.length - 1].id);
|
|
@@ -233,13 +390,195 @@ export class RegionEditorComponent {
|
|
|
233
390
|
* intensity-profile lines the editor never sees).
|
|
234
391
|
*/
|
|
235
392
|
onSelectionChanged() {
|
|
393
|
+
const selected = this.selectedRegions ?? [];
|
|
394
|
+
// Rows picked in the table replace the class tree's pick.
|
|
395
|
+
this.pickedClasses = [];
|
|
396
|
+
this.updateSelectionHighlight();
|
|
397
|
+
const fromSource = selected.filter((r) => this.standIns.has(r));
|
|
236
398
|
this._suppressSelectionSyncToPlot = true;
|
|
237
399
|
try {
|
|
238
|
-
this.regionApi.setSelectedRegions(
|
|
400
|
+
this.regionApi.setSelectedRegions(selected.filter((r) => !this.standIns.has(r)));
|
|
239
401
|
}
|
|
240
402
|
finally {
|
|
241
403
|
this._suppressSelectionSyncToPlot = false;
|
|
242
404
|
}
|
|
405
|
+
// A selected source row is taken into the regions (and so selected on the image too).
|
|
406
|
+
if (fromSource.length)
|
|
407
|
+
void this.regionApi.selectSourceFeatures?.(this.sourceIds(fromSource), true);
|
|
408
|
+
}
|
|
409
|
+
// ── The region source's features as table rows ───────────────────────
|
|
410
|
+
/** Whether the slice has a region source: it then has regions to save even with an empty table. */
|
|
411
|
+
get hasRegionSource() {
|
|
412
|
+
return !!this.sourceView;
|
|
413
|
+
}
|
|
414
|
+
/** Rows in the table: the regions, then the features still in the region source. */
|
|
415
|
+
get tableTotal() {
|
|
416
|
+
return this.regions.length + this.sourceTotal;
|
|
417
|
+
}
|
|
418
|
+
/** The class hierarchy of the slice's region source, when it has one (the classes as a tree). */
|
|
419
|
+
get classHierarchy() {
|
|
420
|
+
return this.sourceView?.source.info.hierarchy ?? null;
|
|
421
|
+
}
|
|
422
|
+
/** Whether `row` is a region-source feature's stand-in rather than a region. */
|
|
423
|
+
isSourceRow(row) {
|
|
424
|
+
return this.standIns.has(row);
|
|
425
|
+
}
|
|
426
|
+
sourceIds(rows) {
|
|
427
|
+
return rows.map((r) => r.sourceId).filter((id) => !!id);
|
|
428
|
+
}
|
|
429
|
+
/** A table row for a source feature: no geometry until it is taken. */
|
|
430
|
+
standIn(row) {
|
|
431
|
+
const r = Object.assign(new Region(), {
|
|
432
|
+
id: -++this.standInSeq,
|
|
433
|
+
name: row.label ?? row.id,
|
|
434
|
+
label: row.label ?? undefined,
|
|
435
|
+
color: this.sourceView?.colorOf(row) ?? row.color ?? this.shapeColor,
|
|
436
|
+
sourceId: row.id,
|
|
437
|
+
sourceArea: row.area,
|
|
438
|
+
bounds: null,
|
|
439
|
+
});
|
|
440
|
+
this.standIns.add(r);
|
|
441
|
+
return r;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Re-read the source part of the table (the stand-ins on the current page, the count) and the
|
|
445
|
+
* source's class counts. The page holds regions first, so its source rows start at
|
|
446
|
+
* `max(first, regions)` − regions.
|
|
447
|
+
*/
|
|
448
|
+
async refreshSource() {
|
|
449
|
+
if (!this.isActive)
|
|
450
|
+
return;
|
|
451
|
+
const request = ++this.sourceRequest;
|
|
452
|
+
const view = this.sourceView;
|
|
453
|
+
let rows = [];
|
|
454
|
+
let total = 0;
|
|
455
|
+
let counts = {};
|
|
456
|
+
if (view && this.regionApi.getRegionSourceIndex) {
|
|
457
|
+
const own = this.regions.length;
|
|
458
|
+
const start = Math.max(this.paginatorFirst, own);
|
|
459
|
+
const limit = Math.max(0, this.paginatorFirst + this.paginatorRows - start);
|
|
460
|
+
try {
|
|
461
|
+
const [page, perClass] = await Promise.all([
|
|
462
|
+
this.regionApi.getRegionSourceIndex({ offset: start - own, limit }),
|
|
463
|
+
this.regionApi.getRegionSourceClassCounts?.(this.stackCounts),
|
|
464
|
+
]);
|
|
465
|
+
rows = page?.rows ?? [];
|
|
466
|
+
total = page?.total ?? 0;
|
|
467
|
+
counts = perClass ?? {};
|
|
468
|
+
}
|
|
469
|
+
catch (err) {
|
|
470
|
+
console.warn('[regions] could not list the region source', err);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (request !== this.sourceRequest)
|
|
474
|
+
return;
|
|
475
|
+
this.sourceTotal = total;
|
|
476
|
+
this.sourceRows = rows.map((r) => this.standIn(r));
|
|
477
|
+
this.sourceClassCounts = counts;
|
|
478
|
+
this.recomputeClassCounts();
|
|
479
|
+
this.changed();
|
|
480
|
+
}
|
|
481
|
+
/** Take a source row's feature into the regions, then run `then` on the region it became. */
|
|
482
|
+
async takeThen(row, then) {
|
|
483
|
+
const [id] = (await this.regionApi.selectSourceFeatures?.(this.sourceIds([row]))) ?? [];
|
|
484
|
+
const region = this.regions.find((r) => r.id === id);
|
|
485
|
+
if (region)
|
|
486
|
+
then(region);
|
|
487
|
+
}
|
|
488
|
+
/** Toggle the filled (atlas) look: each region filled in its colour, labels inside. */
|
|
489
|
+
/** In a volume view: the regions drawn through the volume, or hidden behind what it shows. */
|
|
490
|
+
toggleThroughVolume() {
|
|
491
|
+
this.regionApi.setRegionsThroughVolume?.(!this.regionsThroughVolume);
|
|
492
|
+
}
|
|
493
|
+
toggleFill() {
|
|
494
|
+
this.regionApi.setRegionStyle?.({ fillOpacity: this.regionsFilled ? 0 : REGION_FILL_OPACITY });
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Show or hide a class in the volume view as a 3D reconstruction — a tree node with every class
|
|
498
|
+
* under it, as one surface in its colour.
|
|
499
|
+
*/
|
|
500
|
+
toggleClass3d(name, classes = [name]) {
|
|
501
|
+
const next = new Map(this.shown3d);
|
|
502
|
+
if (next.has(name))
|
|
503
|
+
next.delete(name);
|
|
504
|
+
else
|
|
505
|
+
next.set(name, classes);
|
|
506
|
+
this.shown3d = next;
|
|
507
|
+
this.shown3dNames = new Set(next.keys());
|
|
508
|
+
this.changed();
|
|
509
|
+
this.show3d(this.groups3d());
|
|
510
|
+
this.updateSelectionHighlight();
|
|
511
|
+
}
|
|
512
|
+
/** Hide (or show again) these classes' regions, wherever they are drawn. */
|
|
513
|
+
setClassesHidden(classes, hidden) {
|
|
514
|
+
this.regionApi.setClassesHidden?.(classes, hidden);
|
|
515
|
+
}
|
|
516
|
+
/** The surfaces shown in 3D, in their classes' colours now. */
|
|
517
|
+
groups3d() {
|
|
518
|
+
const titles = new Map((this.classHierarchy ?? []).map((n) => [n.name, n.title]));
|
|
519
|
+
return [...this.shown3d].map(([key, classes]) => {
|
|
520
|
+
const title = titles.get(key);
|
|
521
|
+
return { key, classes, color: this.treeColor(key), label: title ? `${key} · ${title}` : key };
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
/** The classes selected now: the class tree's pick (with its subtree) and the selected rows'. */
|
|
525
|
+
selectedClassNames() {
|
|
526
|
+
const names = new Set(this.pickedClasses);
|
|
527
|
+
for (const r of this.selectedRegions ?? [])
|
|
528
|
+
if (r.label)
|
|
529
|
+
names.add(r.label);
|
|
530
|
+
return names;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Highlight, in the volume view, the surfaces holding a selected class (focus + context: they
|
|
534
|
+
* turn near opaque, the others fade), and mark the selected rows' classes in the class lists.
|
|
535
|
+
*/
|
|
536
|
+
updateSelectionHighlight() {
|
|
537
|
+
const names = this.selectedClassNames();
|
|
538
|
+
const marked = new Set((this.selectedRegions ?? []).map((r) => r.label).filter((l) => !!l));
|
|
539
|
+
if ([...marked].join('\n') !== [...this.markedClasses].join('\n'))
|
|
540
|
+
this.markedClasses = marked;
|
|
541
|
+
const keys = [...this.shown3d].filter(([, classes]) => classes.some((c) => names.has(c))).map(([k]) => k);
|
|
542
|
+
const id = keys.join('\n');
|
|
543
|
+
if (id === this.highlighted3d)
|
|
544
|
+
return;
|
|
545
|
+
this.highlighted3d = id;
|
|
546
|
+
this.regionApi.highlightRegionClasses3d?.(keys);
|
|
547
|
+
}
|
|
548
|
+
/** A surface clicked in the volume view: pick its class as the tree would; beside them, clear. */
|
|
549
|
+
onPicked3d(key, additive) {
|
|
550
|
+
if (key === null) {
|
|
551
|
+
if (additive)
|
|
552
|
+
return;
|
|
553
|
+
this.pickedClass = null;
|
|
554
|
+
this.pickedClasses = [];
|
|
555
|
+
this.selectedRegions = [];
|
|
556
|
+
this.onSelectionChanged();
|
|
557
|
+
this.changed();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
void this.pickClasses({ name: key, classes: this.shown3d.get(key) ?? [key], additive });
|
|
561
|
+
}
|
|
562
|
+
/** A class colour changed (its swatch, or Manage): repaint the surfaces shown in 3D whose colour it changed. */
|
|
563
|
+
recolor3d() {
|
|
564
|
+
const groups = this.groups3d();
|
|
565
|
+
if (!groups.some((g) => g.color !== this.colors3d.get(g.key)))
|
|
566
|
+
return;
|
|
567
|
+
this.show3d(groups);
|
|
568
|
+
}
|
|
569
|
+
show3d(groups) {
|
|
570
|
+
this.colors3d = new Map(groups.map((g) => [g.key, g.color]));
|
|
571
|
+
this.regionApi.showRegionClasses3d?.(groups).catch((err) => {
|
|
572
|
+
this.toast('error', 'Could not show the region in 3D', `${err?.message ?? err}`);
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
/** Pick a class in the class tree: select its regions and its subclasses', the source's taken. */
|
|
576
|
+
async pickClasses(pick) {
|
|
577
|
+
this.pickedClass = pick.name;
|
|
578
|
+
this.pickedClasses = pick.additive ? [...new Set([...this.pickedClasses, ...pick.classes])] : pick.classes;
|
|
579
|
+
this.updateSelectionHighlight();
|
|
580
|
+
this.changed();
|
|
581
|
+
await this.regionApi.selectRegionClasses?.(pick.classes, pick.additive);
|
|
243
582
|
}
|
|
244
583
|
/**
|
|
245
584
|
* Rows for regions coming from the visualizer: neutral `Region`s with bounds,
|
|
@@ -327,23 +666,94 @@ export class RegionEditorComponent {
|
|
|
327
666
|
* change detection doesn't hand p-table a new array every tick (RT-20). */
|
|
328
667
|
get pagedRegions() {
|
|
329
668
|
const key = this._pageKey;
|
|
330
|
-
if (key.regions !== this.regions ||
|
|
331
|
-
|
|
332
|
-
|
|
669
|
+
if (key.regions !== this.regions ||
|
|
670
|
+
key.source !== this.sourceRows ||
|
|
671
|
+
key.first !== this.paginatorFirst ||
|
|
672
|
+
key.rows !== this.paginatorRows) {
|
|
673
|
+
this._pageKey = {
|
|
674
|
+
regions: this.regions,
|
|
675
|
+
source: this.sourceRows,
|
|
676
|
+
first: this.paginatorFirst,
|
|
677
|
+
rows: this.paginatorRows,
|
|
678
|
+
};
|
|
679
|
+
const own = this.regions.slice(this.paginatorFirst, this.paginatorFirst + this.paginatorRows);
|
|
680
|
+
this._page =
|
|
681
|
+
own.length >= this.paginatorRows
|
|
682
|
+
? own
|
|
683
|
+
: [...own, ...this.sourceRows.slice(0, this.paginatorRows - own.length)];
|
|
684
|
+
// A new page may show classes whose volume is not known yet (after this check).
|
|
685
|
+
if (this.volumeView)
|
|
686
|
+
queueMicrotask(() => this.requestVolumes());
|
|
333
687
|
}
|
|
334
688
|
return this._page;
|
|
335
689
|
}
|
|
690
|
+
/** Compute the volumes of the classes on the table's page that are not known yet. */
|
|
691
|
+
requestVolumes() {
|
|
692
|
+
const api = this.regionApi.getClassVolumes?.bind(this.regionApi);
|
|
693
|
+
// Closed: asked for again when it opens (see active).
|
|
694
|
+
if (!this.isActive)
|
|
695
|
+
return;
|
|
696
|
+
if (!this.volumeView || !api) {
|
|
697
|
+
if (this.tableVolumes) {
|
|
698
|
+
this.tableVolumes = null;
|
|
699
|
+
this.changed();
|
|
700
|
+
}
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
const known = this.tableVolumes ?? new Map();
|
|
704
|
+
const labels = new Set(this.pagedRegions.map((r) => r.label).filter((l) => !!l));
|
|
705
|
+
const missing = [...labels].filter((l) => !known.has(l));
|
|
706
|
+
if (!missing.length && this.tableVolumes)
|
|
707
|
+
return;
|
|
708
|
+
this.tableVolumes = new Map([...known, ...missing.map((l) => [l, null])]);
|
|
709
|
+
this.changed();
|
|
710
|
+
if (!missing.length)
|
|
711
|
+
return;
|
|
712
|
+
const request = this.volumeRequest;
|
|
713
|
+
api(missing).then((volumes) => {
|
|
714
|
+
if (request !== this.volumeRequest || !this.tableVolumes)
|
|
715
|
+
return;
|
|
716
|
+
this.tableVolumes = new Map([...this.tableVolumes, ...Object.entries(volumes)]);
|
|
717
|
+
this.changed();
|
|
718
|
+
}, (err) => {
|
|
719
|
+
if (request !== this.volumeRequest || !this.tableVolumes)
|
|
720
|
+
return;
|
|
721
|
+
// Leave them unknown ('—') rather than computing forever.
|
|
722
|
+
const next = new Map(this.tableVolumes);
|
|
723
|
+
for (const l of missing)
|
|
724
|
+
next.delete(l);
|
|
725
|
+
this.tableVolumes = next;
|
|
726
|
+
this.changed();
|
|
727
|
+
console.warn('[regions] could not compute class volumes', err);
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
/** The regions changed (or the view did): forget the volumes and compute the page's again. */
|
|
731
|
+
resetVolumes() {
|
|
732
|
+
this.volumeRequest++;
|
|
733
|
+
this.tableVolumes = null;
|
|
734
|
+
this.requestVolumes();
|
|
735
|
+
}
|
|
336
736
|
onPageChange(event) {
|
|
337
737
|
this.paginatorFirst = event.first ?? 0;
|
|
338
738
|
this.paginatorRows = event.rows ?? this.paginatorRows;
|
|
739
|
+
void this.refreshSource();
|
|
339
740
|
}
|
|
340
|
-
/** Select every region in the table (and highlight them on the diagram). */
|
|
341
|
-
selectAllRegions() {
|
|
741
|
+
/** Select every region in the table (and highlight them on the diagram), the source's taken. */
|
|
742
|
+
async selectAllRegions() {
|
|
342
743
|
this.selectedRegions = [...this.regions];
|
|
343
744
|
this.onSelectionChanged();
|
|
745
|
+
if (!this.sourceTotal || !this.regionApi.getRegionSourceIndex)
|
|
746
|
+
return;
|
|
747
|
+
const page = await this.regionApi.getRegionSourceIndex({ offset: 0, limit: SELECT_ALL_SOURCE_LIMIT });
|
|
748
|
+
const ids = (page?.rows ?? []).map((r) => r.id);
|
|
749
|
+
if (ids.length)
|
|
750
|
+
await this.regionApi.selectSourceFeatures?.(ids, true);
|
|
344
751
|
}
|
|
345
752
|
deleteSelectedRegions() {
|
|
346
753
|
if (this.selectedRegions && this.selectedRegions.length > 0) {
|
|
754
|
+
const fromSource = this.selectedRegions.filter((r) => this.standIns.has(r));
|
|
755
|
+
if (fromSource.length)
|
|
756
|
+
this.regionApi.deleteSourceFeatures?.(this.sourceIds(fromSource));
|
|
347
757
|
// Filter by id — object identity isn't reliable across re-parses,
|
|
348
758
|
// and name is a user-editable label that may collide.
|
|
349
759
|
const removed = new Set(this.selectedRegions.map((r) => r.id));
|
|
@@ -363,10 +773,28 @@ export class RegionEditorComponent {
|
|
|
363
773
|
this.paginatorFirst = 0;
|
|
364
774
|
this.commit([]);
|
|
365
775
|
this.onSelectionChanged();
|
|
776
|
+
if (this.hasRegionSource)
|
|
777
|
+
void this.deleteAllSourceFeatures();
|
|
366
778
|
},
|
|
367
779
|
});
|
|
368
780
|
}
|
|
781
|
+
/** Delete every feature still in the slice's region source (with "Delete all regions"). */
|
|
782
|
+
async deleteAllSourceFeatures() {
|
|
783
|
+
const index = this.regionApi.getRegionSourceIndex;
|
|
784
|
+
if (!index || !this.regionApi.deleteSourceFeatures)
|
|
785
|
+
return;
|
|
786
|
+
const page = await index.call(this.regionApi, { offset: 0, limit: Number.MAX_SAFE_INTEGER });
|
|
787
|
+
if (page?.rows.length)
|
|
788
|
+
this.regionApi.deleteSourceFeatures(page.rows.map((r) => r.id));
|
|
789
|
+
}
|
|
369
790
|
deleteRegion(shapeIdx) {
|
|
791
|
+
// A row past the regions is a source feature: delete it from the source.
|
|
792
|
+
if (shapeIdx >= this.regions.length) {
|
|
793
|
+
const row = this.sourceRows[shapeIdx - Math.max(this.paginatorFirst, this.regions.length)];
|
|
794
|
+
if (row)
|
|
795
|
+
this.regionApi.deleteSourceFeatures?.(this.sourceIds([row]));
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
370
798
|
const removed = this.regions[shapeIdx];
|
|
371
799
|
if (removed) {
|
|
372
800
|
this.selectedRegions = this.selectedRegions.filter((r) => r.id !== removed.id);
|
|
@@ -378,7 +806,7 @@ export class RegionEditorComponent {
|
|
|
378
806
|
this.onSelectionChanged();
|
|
379
807
|
}
|
|
380
808
|
clampPaginatorFirst() {
|
|
381
|
-
const maxFirst = Math.max(0, Math.floor((this.
|
|
809
|
+
const maxFirst = Math.max(0, Math.floor((this.tableTotal - 1) / this.paginatorRows) * this.paginatorRows);
|
|
382
810
|
if (this.paginatorFirst > maxFirst) {
|
|
383
811
|
this.paginatorFirst = maxFirst;
|
|
384
812
|
}
|
|
@@ -391,6 +819,10 @@ export class RegionEditorComponent {
|
|
|
391
819
|
}
|
|
392
820
|
startEditLabel(region, event) {
|
|
393
821
|
event?.stopPropagation(); // don't toggle row selection
|
|
822
|
+
if (this.standIns.has(region)) {
|
|
823
|
+
void this.takeThen(region, (r) => this.startEditLabel(r));
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
394
826
|
// A new map per start/stop, so the OnPush table sees the change.
|
|
395
827
|
this.editingLabelRegions = new Map(this.editingLabelRegions).set(region, region.label ?? '');
|
|
396
828
|
}
|
|
@@ -507,21 +939,49 @@ export class RegionEditorComponent {
|
|
|
507
939
|
}
|
|
508
940
|
}
|
|
509
941
|
// ── Docked Classes panel (jit-ui#70) ─────────────────────────────────
|
|
510
|
-
/**
|
|
942
|
+
/**
|
|
943
|
+
* Whether the classes count every slice of the stack: in a volume view (the whole stack on
|
|
944
|
+
* screen), unless its slice pane shows one slice. The table lists the slice's regions anyway.
|
|
945
|
+
*/
|
|
946
|
+
get stackCounts() {
|
|
947
|
+
return this.volumeView && !this.slicePane;
|
|
948
|
+
}
|
|
949
|
+
/** Rebuild the per-class region counts shown in the panel (the stack's, see stackCounts). */
|
|
511
950
|
recomputeClassCounts() {
|
|
512
951
|
const counts = new Map();
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
952
|
+
const tree = new Map();
|
|
953
|
+
const add = (label, n) => {
|
|
954
|
+
const k = presetKey(this.presetSet, label);
|
|
955
|
+
counts.set(k, (counts.get(k) ?? 0) + n);
|
|
956
|
+
tree.set(label, (tree.get(label) ?? 0) + n);
|
|
957
|
+
};
|
|
958
|
+
const regions = this.stackCounts ? this.regionApi.getSliceAnnotationRegions() : this.regions;
|
|
959
|
+
for (const r of regions)
|
|
960
|
+
if (r.label)
|
|
961
|
+
add(r.label, 1);
|
|
962
|
+
// The region source's classes count too (its features are rows of the table).
|
|
963
|
+
for (const [label, n] of Object.entries(this.sourceClassCounts))
|
|
964
|
+
add(label, n);
|
|
519
965
|
this.classCounts = counts;
|
|
966
|
+
this.treeCounts = tree;
|
|
520
967
|
this.updateDisplayClasses();
|
|
521
968
|
}
|
|
522
|
-
/** Rebuild the panel's display order — most-used classes first, then by name.
|
|
969
|
+
/** Rebuild the panel's display order — most-used classes first, then by name. A class only
|
|
970
|
+
* the region source has is listed too, in its colour. */
|
|
523
971
|
updateDisplayClasses() {
|
|
524
|
-
|
|
972
|
+
const known = new Set(this.presetSet.classes.map((c) => presetKey(this.presetSet, c.name)));
|
|
973
|
+
const fromSource = [];
|
|
974
|
+
for (const label of Object.keys(this.sourceClassCounts)) {
|
|
975
|
+
const k = presetKey(this.presetSet, label);
|
|
976
|
+
if (known.has(k))
|
|
977
|
+
continue;
|
|
978
|
+
known.add(k);
|
|
979
|
+
fromSource.push({ name: label, color: colorForLabel(label, this.presetSet) });
|
|
980
|
+
}
|
|
981
|
+
this.tablePresetSet = fromSource.length
|
|
982
|
+
? { ...this.presetSet, classes: [...this.presetSet.classes, ...fromSource] }
|
|
983
|
+
: this.presetSet;
|
|
984
|
+
this.displayClasses = [...this.presetSet.classes, ...fromSource].sort((a, b) => {
|
|
525
985
|
const d = this.classCount(b.name) - this.classCount(a.name);
|
|
526
986
|
return d !== 0 ? d : a.name.localeCompare(b.name);
|
|
527
987
|
});
|
|
@@ -564,6 +1024,10 @@ export class RegionEditorComponent {
|
|
|
564
1024
|
/** Stamp a class (and its preset/fallback colour) onto one region from the Class
|
|
565
1025
|
* dropdown; choosing a class opts the region back into the preset colour. */
|
|
566
1026
|
applyPresetToRegion(region, className) {
|
|
1027
|
+
if (this.standIns.has(region)) {
|
|
1028
|
+
void this.takeThen(region, (r) => this.applyPresetToRegion(r, className));
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
567
1031
|
const name = (className ?? '').trim();
|
|
568
1032
|
const patch = { label: name, colorOverridden: false };
|
|
569
1033
|
if (name)
|
|
@@ -657,7 +1121,7 @@ export class RegionEditorComponent {
|
|
|
657
1121
|
this.commit();
|
|
658
1122
|
}
|
|
659
1123
|
exportPresets() {
|
|
660
|
-
const json = JSON.stringify(this.regionApi.getPresetSet(), null, 2);
|
|
1124
|
+
const json = JSON.stringify(this.clonePresetSet(this.regionApi.getPresetSet()), null, 2);
|
|
661
1125
|
saveAs(new Blob([json], { type: 'application/json' }), 'annotation-classes.json');
|
|
662
1126
|
}
|
|
663
1127
|
importPresets(event) {
|
|
@@ -689,13 +1153,160 @@ export class RegionEditorComponent {
|
|
|
689
1153
|
}
|
|
690
1154
|
this.changed();
|
|
691
1155
|
}
|
|
1156
|
+
/** The files chosen in the import inputs: one GeoJSON, a label volume with its ontology, or a
|
|
1157
|
+
* folder of per-slice GeoJSON files. */
|
|
692
1158
|
importRois(event) {
|
|
693
|
-
|
|
1159
|
+
const files = Array.from(event.target.files ?? []);
|
|
1160
|
+
if (files.length)
|
|
1161
|
+
void this.importRegionFiles(files.map((f) => importFile(f, f.webkitRelativePath || f.name)));
|
|
694
1162
|
}
|
|
695
|
-
/**
|
|
696
|
-
|
|
1163
|
+
/** Whether the host can pick regions on its server ("Import regions from server"). */
|
|
1164
|
+
get canImportFromServer() {
|
|
1165
|
+
return this.persistence.canPickServerRegions();
|
|
1166
|
+
}
|
|
1167
|
+
/** "Import regions from server": the host picks files or a served region set; they import as chosen files do. */
|
|
1168
|
+
importFromServer() {
|
|
1169
|
+
this.importing = true;
|
|
1170
|
+
this.changed();
|
|
1171
|
+
this.persistence.pickServerRegions().subscribe({
|
|
1172
|
+
next: (pick) => {
|
|
1173
|
+
if (!pick)
|
|
1174
|
+
return;
|
|
1175
|
+
if (pick.kind === 'files') {
|
|
1176
|
+
void this.importRegionFiles(pick.files.map((f) => importFile(f.data, f.name)));
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
void this.importServedRegionSet(pick.url, pick.name);
|
|
1180
|
+
},
|
|
1181
|
+
error: (err) => this.importFailed(err),
|
|
1182
|
+
complete: () => {
|
|
1183
|
+
this.importing = false;
|
|
1184
|
+
this.changed();
|
|
1185
|
+
},
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* Import `files` (see planRegionImport): one GeoJSON file as before; a label volume as one
|
|
1190
|
+
* region source per slice, traced from it the first time the slice is shown, its classes named
|
|
1191
|
+
* (and treed) by the ontology chosen with it; a folder as one source per slice file. Either
|
|
1192
|
+
* replaces the regions and sources of every slice.
|
|
1193
|
+
*/
|
|
1194
|
+
async importRegionFiles(files) {
|
|
1195
|
+
const plan = planRegionImport(files);
|
|
1196
|
+
if (!plan) {
|
|
1197
|
+
this.importFailed(new Error('Choose a GeoJSON file, a folder of GeoJSON files, or a .nii, .nii.gz or .nrrd label volume.'));
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
if (plan.kind === 'single') {
|
|
1201
|
+
await this.applyImportedRois(await plan.file.text());
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
const attach = this.regionApi.importSliceRegionSources?.bind(this.regionApi);
|
|
1205
|
+
if (!attach) {
|
|
1206
|
+
this.importFailed(new Error('This viewer cannot hold region sources.'));
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
// Taken before the files are read: decoding a volume takes a while, and the import must land
|
|
1210
|
+
// on the image it was started for, not on one shown meanwhile.
|
|
1211
|
+
const ticket = this.regionApi.regionImportTicket?.();
|
|
697
1212
|
try {
|
|
698
|
-
|
|
1213
|
+
const openers = new Map();
|
|
1214
|
+
let summary;
|
|
1215
|
+
if (plan.kind === 'volume') {
|
|
1216
|
+
const volume = await readLabelVolume(plan.volume.name, await plan.volume.bytes());
|
|
1217
|
+
const classes = labelClasses(plan.ontology ? JSON.parse(await plan.ontology.text()) : undefined);
|
|
1218
|
+
for (let z = 0; z < volume.slices; z++) {
|
|
1219
|
+
openers.set(z, () => openGeoJsonRegionSource(labelSliceGeoJson(volume, z, classes)));
|
|
1220
|
+
}
|
|
1221
|
+
summary = `${volume.slices} slices of ${volume.width} × ${volume.height}`;
|
|
1222
|
+
this.warnIfSizeDiffers(volume.width, volume.height);
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
const regionSet = plan.regionSet ? JSON.parse(await plan.regionSet.text()) : null;
|
|
1226
|
+
plan.slices.forEach((file, z) => openers.set(z, async () => openGeoJsonRegionSource(await folderSliceGeoJson(file, regionSet))));
|
|
1227
|
+
summary = `${plan.slices.length} slice files`;
|
|
1228
|
+
}
|
|
1229
|
+
const attached = attach(openers, ticket);
|
|
1230
|
+
if (attached === null) {
|
|
1231
|
+
this.importStale();
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
this.afterSourceImport();
|
|
1235
|
+
this.toast('success', 'Regions imported', `${summary}; ${attached} slice${attached === 1 ? '' : 's'} annotated.`);
|
|
1236
|
+
}
|
|
1237
|
+
catch (err) {
|
|
1238
|
+
this.importFailed(err);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
/** A region set the host's server serves (jit-service's /regions/{id}/), read through its HttpClient. */
|
|
1242
|
+
async importServedRegionSet(url, name) {
|
|
1243
|
+
const importSource = this.regionApi.importRegionSourceOpener?.bind(this.regionApi);
|
|
1244
|
+
if (!importSource) {
|
|
1245
|
+
this.importFailed(new Error('This viewer cannot hold region sources.'));
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
const ticket = this.regionApi.regionImportTicket?.();
|
|
1249
|
+
try {
|
|
1250
|
+
const applied = await importSource(() => openHttpRegionSource(url, { http: this.http ?? undefined }), ticket);
|
|
1251
|
+
if (applied === false) {
|
|
1252
|
+
this.importStale();
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
this.afterSourceImport();
|
|
1256
|
+
this.toast('success', 'Regions imported', name ?? url);
|
|
1257
|
+
}
|
|
1258
|
+
catch (err) {
|
|
1259
|
+
this.importFailed(err);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
/** An import that finished after another image was shown (or another import began): dropped. */
|
|
1263
|
+
importStale() {
|
|
1264
|
+
this.toast('info', 'Import discarded', 'The image changed while the regions were being read.');
|
|
1265
|
+
this.changed();
|
|
1266
|
+
}
|
|
1267
|
+
/** The table and selection after the regions were replaced by imported sources. */
|
|
1268
|
+
afterSourceImport() {
|
|
1269
|
+
this.selectedRegions = [];
|
|
1270
|
+
this.paginatorFirst = 0;
|
|
1271
|
+
this.commit([]);
|
|
1272
|
+
this.onSelectionChanged();
|
|
1273
|
+
}
|
|
1274
|
+
/** Warn when an imported volume's slices are not the image's size: its outlines would not fit. */
|
|
1275
|
+
warnIfSizeDiffers(width, height) {
|
|
1276
|
+
const meta = this.regionApi.getMaskImageSize();
|
|
1277
|
+
if (meta && (meta.width !== width || meta.height !== height)) {
|
|
1278
|
+
this.toast('info', 'Different size', `The volume's slices are ${width} × ${height}; the image is ${meta.width} × ${meta.height}.`);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
importFailed(err) {
|
|
1282
|
+
this.importing = false;
|
|
1283
|
+
this.messageService.add({
|
|
1284
|
+
key: VIZ_TOAST_KEY,
|
|
1285
|
+
severity: 'error',
|
|
1286
|
+
summary: 'Error importing regions',
|
|
1287
|
+
detail: `${err?.message ?? err}`,
|
|
1288
|
+
});
|
|
1289
|
+
console.error('Error importing regions:', err);
|
|
1290
|
+
this.changed();
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Replace the regions with an imported GeoJSON file's, and the slice's region source with them.
|
|
1294
|
+
* A large file becomes the slice's region source instead (drawn by level of detail; listed above
|
|
1295
|
+
* the table), the table emptied.
|
|
1296
|
+
*/
|
|
1297
|
+
async applyImportedRois(text) {
|
|
1298
|
+
try {
|
|
1299
|
+
if (await this.regionApi.importRegionSource?.(text)) {
|
|
1300
|
+
this.selectedRegions = [];
|
|
1301
|
+
this.paginatorFirst = 0;
|
|
1302
|
+
this.commit([]);
|
|
1303
|
+
this.onSelectionChanged();
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
// Parsed first: a file that is not GeoJSON leaves the source alone.
|
|
1307
|
+
const regions = this.regionApi.importRegions(text);
|
|
1308
|
+
await this.regionApi.dropRegionSource?.();
|
|
1309
|
+
this.regions = regions;
|
|
699
1310
|
this.fillClassColors();
|
|
700
1311
|
this.commit();
|
|
701
1312
|
}
|
|
@@ -714,7 +1325,7 @@ export class RegionEditorComponent {
|
|
|
714
1325
|
return this.persistence.regionsForSave(this.regions);
|
|
715
1326
|
}
|
|
716
1327
|
exportRois() {
|
|
717
|
-
if (!this.regionsForSave().length)
|
|
1328
|
+
if (!this.regionsForSave().length && !this.hasRegionSource)
|
|
718
1329
|
return;
|
|
719
1330
|
this.exportFilename = this.persistence.defaultExportName();
|
|
720
1331
|
this.showExportDialog = true;
|
|
@@ -722,10 +1333,12 @@ export class RegionEditorComponent {
|
|
|
722
1333
|
confirmExport() {
|
|
723
1334
|
const filename = this.exportFilename.trim();
|
|
724
1335
|
const regions = this.regionsForSave();
|
|
725
|
-
if (!filename || !regions.length)
|
|
1336
|
+
if (!filename || (!regions.length && !this.hasRegionSource))
|
|
726
1337
|
return;
|
|
727
1338
|
this.showExportDialog = false;
|
|
728
|
-
this.persistence
|
|
1339
|
+
this.persistence
|
|
1340
|
+
.download(regions, filename)
|
|
1341
|
+
.catch((err) => this.toast('error', 'Error exporting regions', `${err?.message ?? err}`));
|
|
729
1342
|
}
|
|
730
1343
|
/** Open the "Save mask" dialog, seeded with `<image-stem>_mask.png`. */
|
|
731
1344
|
openSaveMaskDialog() {
|
|
@@ -825,7 +1438,7 @@ export class RegionEditorComponent {
|
|
|
825
1438
|
return;
|
|
826
1439
|
}
|
|
827
1440
|
const filename = this.persistence.defaultSaveName();
|
|
828
|
-
if (!filename || !this.regionsForSave().length)
|
|
1441
|
+
if (!filename || (!this.regionsForSave().length && !this.hasRegionSource))
|
|
829
1442
|
return;
|
|
830
1443
|
this.saveAsFilename = filename;
|
|
831
1444
|
this.saveAsFileExists = false;
|
|
@@ -835,13 +1448,25 @@ export class RegionEditorComponent {
|
|
|
835
1448
|
/** Save a folder stack's regions as one geojson per slice-file (jit-ui#93).
|
|
836
1449
|
* No dialog covers the toolbar meanwhile, so a Save while one is uploading
|
|
837
1450
|
* is ignored rather than starting a second write (and orphaning the first). */
|
|
838
|
-
saveStackSlices() {
|
|
1451
|
+
async saveStackSlices() {
|
|
839
1452
|
if (this.saveAsBusy)
|
|
840
1453
|
return;
|
|
841
|
-
const slices = this.persistence.sliceGeoJsons();
|
|
842
|
-
if (!slices.length)
|
|
843
|
-
return;
|
|
844
1454
|
this.saveAsBusy = true;
|
|
1455
|
+
let slices;
|
|
1456
|
+
try {
|
|
1457
|
+
slices = await this.persistence.sliceGeoJsons();
|
|
1458
|
+
}
|
|
1459
|
+
catch (err) {
|
|
1460
|
+
this.saveAsBusy = false;
|
|
1461
|
+
this.changed();
|
|
1462
|
+
this.toast('error', 'Error saving regions', `${err?.message ?? err}`);
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
// Cancelled while the slices serialized, or nothing to write.
|
|
1466
|
+
if (!this.saveAsBusy || !slices.length) {
|
|
1467
|
+
this.saveAsBusy = false;
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
845
1470
|
this._saveAsSub = this.persistence.saveSlices(slices).subscribe({
|
|
846
1471
|
next: () => {
|
|
847
1472
|
this.saveAsBusy = false;
|
|
@@ -909,7 +1534,7 @@ export class RegionEditorComponent {
|
|
|
909
1534
|
this.messageService.add({ key: VIZ_TOAST_KEY, severity, summary, detail });
|
|
910
1535
|
}
|
|
911
1536
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: RegionEditorComponent, deps: [{ token: REGION_EDITOR_API }, { token: i1.MessageService }, { token: i1.ConfirmationService }, { token: i2.RegionPersistenceService }, { token: i3.MaskExportService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
912
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: RegionEditorComponent, isStandalone: true, selector: "region-editor", providers: [RegionPersistenceService], viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: ["op"], descendants: true }], ngImport: i0, template: "<p-toolbar styleClass=\"region-toolbar\">\n <div class=\"p-toolbar-group-start align-items-center flex-wrap gap-1\">\n <p-button\n icon=\"pi pi-tag\"\n size=\"small\"\n [text]=\"!showShapeLabel\"\n pTooltip=\"Show region labels.\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showShapeLabel = !showShapeLabel; changeShowShapeLabel(showShapeLabel)\"\n >\n </p-button>\n <span class=\"toolbar-separator\"></span>\n <!-- New regions are now created from the diagram toolbar\n (rectangle, polyline, freeform, wand). -->\n <p-button\n icon=\"pi pi-upload\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Upload and display regions from geojson file.\"\n tooltipPosition=\"bottom\"\n (click)=\"roiFileInput.click()\"\n >\n </p-button>\n <input\n #roiFileInput\n type=\"file\"\n accept=\".geojson,.json\"\n hidden\n (change)=\"importRois($event); roiFileInput.value = ''\"\n />\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download regions as geojson file.\"\n tooltipPosition=\"bottom\"\n icon=\"pi pi-download\"\n (click)=\"exportRois()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-save\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Save regions to server.\"\n tooltipPosition=\"bottom\"\n (click)=\"persistRegions()\"\n [disabled]=\"!regions || !regions.length\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download mask of the regions as PNG\"\n tooltipPosition=\"bottom\"\n (click)=\"openSaveMaskDialog()\"\n [disabled]=\"!regions || !regions.length\"\n >\n <!-- References the file so Inkscape edits to mask.svg show up directly\n (the lib's assets/** are served at assets/plotting/). The\n toolbar-icon-dark filter recolours the black SVG to the theme blue,\n same as region-editor.svg and the other SVG toolbar icons. -->\n <img\n src=\"assets/plotting/mask.svg\"\n class=\"toolbar-icon-dark\"\n style=\"width: 1rem; height: 1rem; vertical-align: middle\"\n alt=\"Download mask\"\n />\n </p-button>\n <p-button\n label=\"x512\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Round all rectangle regions\n to width and height that are multiple of 512\"\n tooltipPosition=\"bottom\"\n (click)=\"roundRectangleLengths()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-check-square\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Select all regions\"\n tooltipPosition=\"bottom\"\n (click)=\"selectAllRegions()\"\n [disabled]=\"!regions || !regions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-tags\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit class on selected rows\"\n tooltipPosition=\"bottom\"\n (click)=\"!selectedRegions || !selectedRegions.length ? op.hide() : op.toggle($event)\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-palette\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit colour of selected regions\"\n tooltipPosition=\"bottom\"\n (click)=\"openColorDialog()\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-overlayPanel #op (onHide)=\"bulkClass = ''; newBulkClass = ''\">\n <div class=\"flex flex-column gap-2\" style=\"width: 18rem\">\n <span class=\"font-medium text-900\"\n >Set class on {{ selectedRegions?.length || 0 }} selected region(s)</span\n >\n <!-- Selecting a class applies it immediately (choosing an option closes the\n overlay, so there's no separate Apply button). -->\n <p-dropdown\n styleClass=\"w-full\"\n appendTo=\"body\"\n [options]=\"presetSet.classes\"\n optionLabel=\"name\"\n optionValue=\"name\"\n [(ngModel)]=\"bulkClass\"\n placeholder=\"Choose a class\u2026\"\n [filter]=\"presetSet.classes.length > 8\"\n filterBy=\"name\"\n (onChange)=\"applyBulkClass()\"\n >\n <ng-template let-c pTemplate=\"item\">\n <span class=\"dd-value\"\n ><span class=\"chip-swatch\" [style.background]=\"c.color\"></span>{{ c.name }}</span\n >\n </ng-template>\n </p-dropdown>\n <div class=\"p-inputgroup\">\n <input\n type=\"text\"\n pInputText\n placeholder=\"\u2026or a new class\"\n [(ngModel)]=\"newBulkClass\"\n (keydown.enter)=\"addAndApplyBulkClass()\"\n />\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n pTooltip=\"Add class & set it\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!newBulkClass.trim()\"\n (click)=\"addAndApplyBulkClass()\"\n ></button>\n </div>\n </div>\n </p-overlayPanel>\n <p-button\n icon=\"pi pi-trash\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"deleteSelectedRegions()\"\n pTooltip=\"Delete selected regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n ></p-button>\n <p-button\n icon=\"pi pi-times-circle\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"clearAllRegions()\"\n pTooltip=\"Delete all regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!regions || !regions.length\"\n ></p-button>\n <p-button\n icon=\"pi pi-question\"\n size=\"small\"\n [text]=\"true\"\n (click)=\"showHelp()\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n ></p-button>\n </div>\n</p-toolbar>\n\n<region-classes-panel\n [classes]=\"displayClasses\"\n [counts]=\"classCounts\"\n [matchMode]=\"presetSet.matchMode\"\n [activeClass]=\"activeClass\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n [defaultClassName]=\"defaultClassName\"\n (pick)=\"selectActiveClass($event)\"\n (recolor)=\"setClassColor($event.name, $event.color)\"\n (remove)=\"deleteClass($event)\"\n (manage)=\"openManageDialog()\"\n>\n</region-classes-panel>\n\n<region-table\n [page]=\"pagedRegions\"\n [total]=\"regions.length\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [rowsPerPageOptions]=\"rowsPerPageOptions\"\n [metaKey]=\"metaKey\"\n [selection]=\"selectedRegions\"\n (selectionChange)=\"selectedRegions = $event\"\n (rowSelect)=\"onSelectionChanged()\"\n [presetSet]=\"presetSet\"\n [defaultColor]=\"shapeColor\"\n [mpp]=\"mpp\"\n [labelDrafts]=\"editingLabelRegions\"\n (labelEditStart)=\"startEditLabel($event)\"\n (labelDraftChange)=\"setLabelDraft($event.region, $event.value)\"\n (labelEditStop)=\"stopEditLabel($event.region, $event.commit)\"\n (classPick)=\"applyPresetToRegion($event.region, $event.name)\"\n (deleteRow)=\"deleteRegion($event)\"\n (pageChange)=\"onPageChange($event)\"\n>\n</region-table>\n\n<!-- Live-edit mode: no Save/Cancel \u2014 every edit commits immediately to the\n active image's region cache. -->\n\n<p-confirmDialog\n #cd\n [style]=\"{ width: '24rem', height: '14rem' }\"\n key=\"positionDialog\"\n [baseZIndex]=\"10000\"\n rejectButtonStyleClass=\"p-button-outlined\"\n>\n <ng-template pTemplate=\"footer\">\n <button type=\"button\" pButton icon=\"pi pi-check\" label=\"Yes\" (click)=\"cd.accept()\"></button>\n <button\n type=\"button\"\n class=\"p-button-outlined\"\n pButton\n icon=\"pi pi-times\"\n label=\"No\"\n (click)=\"cd.reject()\"\n ></button>\n </ng-template>\n</p-confirmDialog>\n\n<region-save-regions-dialog\n [(visible)]=\"showSaveAsDialog\"\n [filename]=\"saveAsFilename\"\n (filenameChange)=\"saveAsFilename = $event; checkSaveAsFileExists()\"\n [fileExists]=\"saveAsFileExists\"\n [busy]=\"saveAsBusy\"\n (confirm)=\"confirmSaveAs()\"\n (cancelSave)=\"cancelSaveAs()\"\n>\n</region-save-regions-dialog>\n\n<region-save-regions-dialog\n header=\"Export Regions\"\n confirmLabel=\"Export\"\n confirmIcon=\"pi pi-download\"\n inputId=\"export-filename\"\n [(visible)]=\"showExportDialog\"\n [(filename)]=\"exportFilename\"\n (confirm)=\"confirmExport()\"\n>\n</region-save-regions-dialog>\n\n<region-save-mask-dialog\n [(visible)]=\"showSaveMaskDialog\"\n [(filename)]=\"saveMaskFilename\"\n [(mode)]=\"maskMode\"\n [busy]=\"maskBusy\"\n [progress]=\"maskProgress\"\n [encoding]=\"maskEncoding\"\n (confirm)=\"confirmSaveMask()\"\n (cancelExport)=\"cancelSaveMask()\"\n>\n</region-save-mask-dialog>\n\n<region-color-dialog\n [(visible)]=\"showColorDialog\"\n [edits]=\"classColorEdits\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n (apply)=\"applyColorToSelected($event)\"\n>\n</region-color-dialog>\n\n<!-- Manage annotation classes (jit-ui#70): edits a working copy, committed on Apply. -->\n<region-manage-classes-dialog\n [(visible)]=\"showManageDialog\"\n [(draft)]=\"presetDraft\"\n (apply)=\"applyManageDialog(true)\"\n (resetDefaults)=\"resetPresetsToDefaults()\"\n (importFile)=\"importPresets($event)\"\n (export)=\"exportPresets()\"\n>\n</region-manage-classes-dialog>\n\n<region-editor-help [(visible)]=\"displayHelpDialog\"></region-editor-help>\n", styles: ["@charset \"UTF-8\";.chip-swatch{display:inline-block;width:.75rem;height:.75rem;border-radius:50%;border:1px solid rgba(0,0,0,.2);flex:0 0 auto}.dd-value{display:inline-flex;align-items:center;gap:.4rem;min-width:0}.dd-value .class-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}::ng-deep region-editor .p-toolbar.region-toolbar{padding:.25rem .5rem;border-radius:0;border-left:none;border-right:none;border-top:none}::ng-deep region-editor .p-toolbar.region-toolbar .p-button.p-button-icon-only{width:auto;padding:.25rem .5rem}::ng-deep region-editor .p-toolbar.region-toolbar .p-button{padding:.25rem .5rem}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i5.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: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i6.ConfirmDialog, selector: "p-confirmDialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i7.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: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: i9.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i10.Toolbar, selector: "p-toolbar", inputs: ["style", "styleClass", "ariaLabelledBy"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i11.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: ClassesPanelComponent, selector: "region-classes-panel", inputs: ["classes", "counts", "matchMode", "activeClass", "selectedCount", "defaultClassName"], outputs: ["pick", "recolor", "remove", "manage"] }, { kind: "component", type: RegionTableComponent, selector: "region-table", inputs: ["page", "total", "first", "rows", "rowsPerPageOptions", "metaKey", "selection", "presetSet", "defaultColor", "mpp", "labelDrafts"], outputs: ["selectionChange", "rowSelect", "labelEditStart", "labelDraftChange", "labelEditStop", "classPick", "deleteRow", "pageChange"] }, { kind: "component", type: SaveRegionsDialogComponent, selector: "region-save-regions-dialog", inputs: ["header", "confirmLabel", "confirmIcon", "inputId", "visible", "filename", "fileExists", "busy"], outputs: ["visibleChange", "filenameChange", "confirm", "cancelSave"] }, { kind: "component", type: SaveMaskDialogComponent, selector: "region-save-mask-dialog", inputs: ["visible", "filename", "mode", "busy", "progress", "encoding"], outputs: ["visibleChange", "filenameChange", "modeChange", "confirm", "cancelExport"] }, { kind: "component", type: RegionColorDialogComponent, selector: "region-color-dialog", inputs: ["visible", "selectedCount", "edits"], outputs: ["visibleChange", "apply"] }, { kind: "component", type: ManageClassesDialogComponent, selector: "region-manage-classes-dialog", inputs: ["visible", "draft"], outputs: ["visibleChange", "draftChange", "apply", "resetDefaults", "importFile", "export"] }, { kind: "component", type: RegionEditorHelpComponent, selector: "region-editor-help", inputs: ["visible"], outputs: ["visibleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1537
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: RegionEditorComponent, isStandalone: true, selector: "region-editor", inputs: { active: "active" }, providers: [RegionPersistenceService], viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: ["op"], descendants: true }], ngImport: i0, template: "<p-toolbar styleClass=\"region-toolbar\">\n <div class=\"p-toolbar-group-start align-items-center flex-wrap gap-1\">\n <p-button\n icon=\"pi pi-tag\"\n size=\"small\"\n [text]=\"!showShapeLabel\"\n pTooltip=\"Show region labels.\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showShapeLabel = !showShapeLabel; changeShowShapeLabel(showShapeLabel)\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-stop-circle\"\n size=\"small\"\n [text]=\"!regionsFilled\"\n pTooltip=\"Fill regions in their colour (an atlas's look); labels sit inside.\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Fill regions\"\n (onClick)=\"toggleFill()\"\n >\n </p-button>\n <p-button\n *ngIf=\"volumeView\"\n icon=\"pi pi-eye\"\n size=\"small\"\n [text]=\"!regionsThroughVolume\"\n [attr.aria-pressed]=\"regionsThroughVolume\"\n pTooltip=\"See the regions through the volume. Off, the volume hides the parts of them behind what it shows; on, none (layers traced inside bright structures, such as an OCT's).\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Regions through volume\"\n (onClick)=\"toggleThroughVolume()\"\n >\n </p-button>\n <span class=\"toolbar-separator\"></span>\n <!-- New regions are now created from the diagram toolbar\n (rectangle, polyline, freeform, wand). -->\n <p-button\n icon=\"pi pi-upload\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Import regions: a GeoJSON file, or a label volume (.nii, .nii.gz, .nrrd) chosen with its ontology JSON for the class tree.\"\n tooltipPosition=\"bottom\"\n (click)=\"roiFileInput.click()\"\n >\n </p-button>\n <input\n #roiFileInput\n type=\"file\"\n accept=\".geojson,.json,.nii,.gz,.nrrd\"\n multiple\n hidden\n (change)=\"importRois($event); roiFileInput.value = ''\"\n />\n <p-button\n icon=\"pi pi-folder-open\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Import a folder of per-slice GeoJSON files (one per slice, in name order, with its regionset.json class tree).\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Import a folder of regions\"\n (click)=\"roiFolderInput.click()\"\n >\n </p-button>\n <input\n #roiFolderInput\n type=\"file\"\n webkitdirectory\n multiple\n hidden\n (change)=\"importRois($event); roiFolderInput.value = ''\"\n />\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download regions as geojson file.\"\n tooltipPosition=\"bottom\"\n icon=\"pi pi-download\"\n (click)=\"exportRois()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-save\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Save regions to server.\"\n tooltipPosition=\"bottom\"\n (click)=\"persistRegions()\"\n [disabled]=\"(!regions || !regions.length) && !hasRegionSource\"\n >\n </p-button>\n <p-button\n *ngIf=\"canImportFromServer\"\n icon=\"pi pi-cloud-download\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Import regions from server: a GeoJSON file, a folder of per-slice GeoJSON files or a label volume (.nii, .nii.gz, .nrrd).\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Import regions from server\"\n [loading]=\"importing\"\n (click)=\"importFromServer()\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download mask of the regions as PNG\"\n tooltipPosition=\"bottom\"\n (click)=\"openSaveMaskDialog()\"\n [disabled]=\"!regions || !regions.length\"\n >\n <!-- References the file so Inkscape edits to mask.svg show up directly\n (the lib's assets/** are served at assets/plotting/). The\n toolbar-icon-dark filter recolours the black SVG to the theme blue,\n same as region-editor.svg and the other SVG toolbar icons. -->\n <img\n src=\"assets/plotting/mask.svg\"\n class=\"toolbar-icon-dark\"\n style=\"width: 1rem; height: 1rem; vertical-align: middle\"\n alt=\"Download mask\"\n />\n </p-button>\n <p-button\n label=\"x512\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Round all rectangle regions\n to width and height that are multiple of 512\"\n tooltipPosition=\"bottom\"\n (click)=\"roundRectangleLengths()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-check-square\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Select all regions\"\n tooltipPosition=\"bottom\"\n (click)=\"selectAllRegions()\"\n [disabled]=\"!regions || !regions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-tags\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit class on selected rows\"\n tooltipPosition=\"bottom\"\n (click)=\"!selectedRegions || !selectedRegions.length ? op.hide() : op.toggle($event)\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-palette\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit colour of selected regions\"\n tooltipPosition=\"bottom\"\n (click)=\"openColorDialog()\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-overlayPanel #op (onHide)=\"bulkClass = ''; newBulkClass = ''\">\n <div class=\"flex flex-column gap-2\" style=\"width: 18rem\">\n <span class=\"font-medium text-900\"\n >Set class on {{ selectedRegions?.length || 0 }} selected region(s)</span\n >\n <!-- Selecting a class applies it immediately (choosing an option closes the\n overlay, so there's no separate Apply button). -->\n <p-dropdown\n styleClass=\"w-full\"\n appendTo=\"body\"\n [options]=\"presetSet.classes\"\n optionLabel=\"name\"\n optionValue=\"name\"\n [(ngModel)]=\"bulkClass\"\n placeholder=\"Choose a class\u2026\"\n [filter]=\"presetSet.classes.length > 8\"\n filterBy=\"name\"\n (onChange)=\"applyBulkClass()\"\n >\n <ng-template let-c pTemplate=\"item\">\n <span class=\"dd-value\"\n ><span class=\"chip-swatch\" [style.background]=\"c.color\"></span>{{ c.name }}</span\n >\n </ng-template>\n </p-dropdown>\n <div class=\"p-inputgroup\">\n <input\n type=\"text\"\n pInputText\n placeholder=\"\u2026or a new class\"\n [(ngModel)]=\"newBulkClass\"\n (keydown.enter)=\"addAndApplyBulkClass()\"\n />\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n pTooltip=\"Add class & set it\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!newBulkClass.trim()\"\n (click)=\"addAndApplyBulkClass()\"\n ></button>\n </div>\n </div>\n </p-overlayPanel>\n <p-button\n icon=\"pi pi-trash\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"deleteSelectedRegions()\"\n pTooltip=\"Delete selected regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n ></p-button>\n <p-button\n icon=\"pi pi-times-circle\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"clearAllRegions()\"\n pTooltip=\"Delete all regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"(!regions || !regions.length) && !hasRegionSource\"\n ></p-button>\n <p-button\n icon=\"pi pi-question\"\n size=\"small\"\n [text]=\"true\"\n (click)=\"showHelp()\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n ></p-button>\n </div>\n</p-toolbar>\n\n<region-classes-panel\n [classes]=\"displayClasses\"\n [counts]=\"classCounts\"\n [matchMode]=\"presetSet.matchMode\"\n [activeClass]=\"activeClass\"\n [picked]=\"pickedClass\"\n [marked]=\"markedClasses\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n [defaultClassName]=\"defaultClassName\"\n (pick)=\"selectActiveClass($event)\"\n (recolor)=\"setClassColor($event.name, $event.color)\"\n (remove)=\"deleteClass($event)\"\n (manage)=\"openManageDialog()\"\n [volume]=\"volumeView\"\n [shown3d]=\"shown3dNames\"\n (toggle3d)=\"toggleClass3d($event)\"\n [hidden]=\"hiddenClasses\"\n (toggleHidden)=\"setClassesHidden([$event], !hiddenClasses.has($event))\"\n [treeView]=\"classHierarchy ? classTreeView : null\"\n (treeViewChange)=\"classTreeView = $event\"\n>\n <!-- A region set with a class hierarchy (an atlas ontology) can show its classes as a tree. -->\n <region-class-tree\n *ngIf=\"classHierarchy as hierarchy\"\n [nodes]=\"hierarchy\"\n [counts]=\"treeCounts\"\n [colorOf]=\"treeColor\"\n [picked]=\"pickedClass\"\n [marked]=\"markedClasses\"\n [volume]=\"volumeView\"\n [shown3d]=\"shown3dNames\"\n (pick)=\"pickClasses($event)\"\n (recolor)=\"setClassColor($event.name, $event.color)\"\n (toggle3d)=\"toggleClass3d($event.name, $event.classes)\"\n [hidden]=\"hiddenClasses\"\n (toggleHidden)=\"setClassesHidden($event.classes, $event.hidden)\"\n >\n </region-class-tree>\n</region-classes-panel>\n\n<region-table\n [page]=\"pagedRegions\"\n [total]=\"tableTotal\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [rowsPerPageOptions]=\"rowsPerPageOptions\"\n [metaKey]=\"metaKey\"\n [selection]=\"selectedRegions\"\n (selectionChange)=\"selectedRegions = $event\"\n (rowSelect)=\"onSelectionChanged()\"\n [presetSet]=\"tablePresetSet\"\n [defaultColor]=\"shapeColor\"\n [mpp]=\"mpp\"\n [volumes]=\"tableVolumes\"\n [labelDrafts]=\"editingLabelRegions\"\n (labelEditStart)=\"startEditLabel($event)\"\n (labelDraftChange)=\"setLabelDraft($event.region, $event.value)\"\n (labelEditStop)=\"stopEditLabel($event.region, $event.commit)\"\n (classPick)=\"applyPresetToRegion($event.region, $event.name)\"\n (deleteRow)=\"deleteRegion($event)\"\n (pageChange)=\"onPageChange($event)\"\n>\n</region-table>\n\n<!-- Live-edit mode: no Save/Cancel \u2014 every edit commits immediately to the\n active image's region cache. -->\n\n<p-confirmDialog\n #cd\n [style]=\"{ width: '24rem', height: '14rem' }\"\n key=\"positionDialog\"\n [baseZIndex]=\"10000\"\n rejectButtonStyleClass=\"p-button-outlined\"\n>\n <ng-template pTemplate=\"footer\">\n <button type=\"button\" pButton icon=\"pi pi-check\" label=\"Yes\" (click)=\"cd.accept()\"></button>\n <button\n type=\"button\"\n class=\"p-button-outlined\"\n pButton\n icon=\"pi pi-times\"\n label=\"No\"\n (click)=\"cd.reject()\"\n ></button>\n </ng-template>\n</p-confirmDialog>\n\n<region-save-regions-dialog\n [(visible)]=\"showSaveAsDialog\"\n [filename]=\"saveAsFilename\"\n (filenameChange)=\"saveAsFilename = $event; checkSaveAsFileExists()\"\n [fileExists]=\"saveAsFileExists\"\n [busy]=\"saveAsBusy\"\n (confirm)=\"confirmSaveAs()\"\n (cancelSave)=\"cancelSaveAs()\"\n>\n</region-save-regions-dialog>\n\n<region-save-regions-dialog\n header=\"Export Regions\"\n confirmLabel=\"Export\"\n confirmIcon=\"pi pi-download\"\n inputId=\"export-filename\"\n [(visible)]=\"showExportDialog\"\n [(filename)]=\"exportFilename\"\n (confirm)=\"confirmExport()\"\n>\n</region-save-regions-dialog>\n\n<region-save-mask-dialog\n [(visible)]=\"showSaveMaskDialog\"\n [(filename)]=\"saveMaskFilename\"\n [(mode)]=\"maskMode\"\n [busy]=\"maskBusy\"\n [progress]=\"maskProgress\"\n [encoding]=\"maskEncoding\"\n (confirm)=\"confirmSaveMask()\"\n (cancelExport)=\"cancelSaveMask()\"\n>\n</region-save-mask-dialog>\n\n<region-color-dialog\n [(visible)]=\"showColorDialog\"\n [edits]=\"classColorEdits\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n (apply)=\"applyColorToSelected($event)\"\n>\n</region-color-dialog>\n\n<!-- Manage annotation classes (jit-ui#70): edits a working copy, committed on Apply. -->\n<region-manage-classes-dialog\n [(visible)]=\"showManageDialog\"\n [(draft)]=\"presetDraft\"\n (apply)=\"applyManageDialog(true)\"\n (resetDefaults)=\"resetPresetsToDefaults()\"\n (importFile)=\"importPresets($event)\"\n (export)=\"exportPresets()\"\n>\n</region-manage-classes-dialog>\n\n<region-editor-help [(visible)]=\"displayHelpDialog\"></region-editor-help>\n", styles: ["@charset \"UTF-8\";.chip-swatch{display:inline-block;width:.75rem;height:.75rem;border-radius:50%;border:1px solid rgba(0,0,0,.2);flex:0 0 auto}.dd-value{display:inline-flex;align-items:center;gap:.4rem;min-width:0}.dd-value .class-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}::ng-deep region-editor .p-toolbar.region-toolbar{padding:.25rem .5rem;border-radius:0;border-left:none;border-right:none;border-top:none}::ng-deep region-editor .p-toolbar.region-toolbar .p-button.p-button-icon-only{width:auto;padding:.25rem .5rem}::ng-deep region-editor .p-toolbar.region-toolbar .p-button{padding:.25rem .5rem}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i7.ConfirmDialog, selector: "p-confirmDialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i8.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: "ngmodule", type: InputTextModule }, { kind: "directive", type: i9.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: i10.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i11.Toolbar, selector: "p-toolbar", inputs: ["style", "styleClass", "ariaLabelledBy"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i12.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: ClassesPanelComponent, selector: "region-classes-panel", inputs: ["classes", "counts", "matchMode", "activeClass", "picked", "marked", "selectedCount", "defaultClassName", "volume", "shown3d", "hidden", "treeView"], outputs: ["toggleHidden", "toggle3d", "treeViewChange", "pick", "recolor", "remove", "manage"] }, { kind: "component", type: RegionTableComponent, selector: "region-table", inputs: ["page", "total", "first", "rows", "rowsPerPageOptions", "metaKey", "selection", "presetSet", "defaultColor", "mpp", "volumes", "labelDrafts"], outputs: ["selectionChange", "rowSelect", "labelEditStart", "labelDraftChange", "labelEditStop", "classPick", "deleteRow", "pageChange"] }, { kind: "component", type: ClassTreeComponent, selector: "region-class-tree", inputs: ["nodes", "counts", "colorOf", "picked", "marked", "volume", "shown3d", "hidden"], outputs: ["pick", "recolor", "toggle3d", "toggleHidden"] }, { kind: "component", type: SaveRegionsDialogComponent, selector: "region-save-regions-dialog", inputs: ["header", "confirmLabel", "confirmIcon", "inputId", "visible", "filename", "fileExists", "busy"], outputs: ["visibleChange", "filenameChange", "confirm", "cancelSave"] }, { kind: "component", type: SaveMaskDialogComponent, selector: "region-save-mask-dialog", inputs: ["visible", "filename", "mode", "busy", "progress", "encoding"], outputs: ["visibleChange", "filenameChange", "modeChange", "confirm", "cancelExport"] }, { kind: "component", type: RegionColorDialogComponent, selector: "region-color-dialog", inputs: ["visible", "selectedCount", "edits"], outputs: ["visibleChange", "apply"] }, { kind: "component", type: ManageClassesDialogComponent, selector: "region-manage-classes-dialog", inputs: ["visible", "draft"], outputs: ["visibleChange", "draftChange", "apply", "resetDefaults", "importFile", "export"] }, { kind: "component", type: RegionEditorHelpComponent, selector: "region-editor-help", inputs: ["visible"], outputs: ["visibleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
913
1538
|
}
|
|
914
1539
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: RegionEditorComponent, decorators: [{
|
|
915
1540
|
type: Component,
|
|
@@ -926,17 +1551,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
926
1551
|
TooltipModule,
|
|
927
1552
|
ClassesPanelComponent,
|
|
928
1553
|
RegionTableComponent,
|
|
1554
|
+
ClassTreeComponent,
|
|
929
1555
|
SaveRegionsDialogComponent,
|
|
930
1556
|
SaveMaskDialogComponent,
|
|
931
1557
|
RegionColorDialogComponent,
|
|
932
1558
|
ManageClassesDialogComponent,
|
|
933
1559
|
RegionEditorHelpComponent,
|
|
934
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [RegionPersistenceService], template: "<p-toolbar styleClass=\"region-toolbar\">\n <div class=\"p-toolbar-group-start align-items-center flex-wrap gap-1\">\n <p-button\n icon=\"pi pi-tag\"\n size=\"small\"\n [text]=\"!showShapeLabel\"\n pTooltip=\"Show region labels.\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showShapeLabel = !showShapeLabel; changeShowShapeLabel(showShapeLabel)\"\n >\n </p-button>\n <span class=\"toolbar-separator\"></span>\n <!-- New regions are now created from the diagram toolbar\n (rectangle, polyline, freeform, wand). -->\n <p-button\n icon=\"pi pi-upload\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Upload and display regions from geojson file.\"\n tooltipPosition=\"bottom\"\n (click)=\"roiFileInput.click()\"\n >\n </p-button>\n <input\n #roiFileInput\n type=\"file\"\n accept=\".geojson,.json\"\n hidden\n (change)=\"importRois($event); roiFileInput.value = ''\"\n />\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download regions as geojson file.\"\n tooltipPosition=\"bottom\"\n icon=\"pi pi-download\"\n (click)=\"exportRois()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-save\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Save regions to server.\"\n tooltipPosition=\"bottom\"\n (click)=\"persistRegions()\"\n [disabled]=\"!regions || !regions.length\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download mask of the regions as PNG\"\n tooltipPosition=\"bottom\"\n (click)=\"openSaveMaskDialog()\"\n [disabled]=\"!regions || !regions.length\"\n >\n <!-- References the file so Inkscape edits to mask.svg show up directly\n (the lib's assets/** are served at assets/plotting/). The\n toolbar-icon-dark filter recolours the black SVG to the theme blue,\n same as region-editor.svg and the other SVG toolbar icons. -->\n <img\n src=\"assets/plotting/mask.svg\"\n class=\"toolbar-icon-dark\"\n style=\"width: 1rem; height: 1rem; vertical-align: middle\"\n alt=\"Download mask\"\n />\n </p-button>\n <p-button\n label=\"x512\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Round all rectangle regions\n to width and height that are multiple of 512\"\n tooltipPosition=\"bottom\"\n (click)=\"roundRectangleLengths()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-check-square\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Select all regions\"\n tooltipPosition=\"bottom\"\n (click)=\"selectAllRegions()\"\n [disabled]=\"!regions || !regions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-tags\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit class on selected rows\"\n tooltipPosition=\"bottom\"\n (click)=\"!selectedRegions || !selectedRegions.length ? op.hide() : op.toggle($event)\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-palette\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit colour of selected regions\"\n tooltipPosition=\"bottom\"\n (click)=\"openColorDialog()\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-overlayPanel #op (onHide)=\"bulkClass = ''; newBulkClass = ''\">\n <div class=\"flex flex-column gap-2\" style=\"width: 18rem\">\n <span class=\"font-medium text-900\"\n >Set class on {{ selectedRegions?.length || 0 }} selected region(s)</span\n >\n <!-- Selecting a class applies it immediately (choosing an option closes the\n overlay, so there's no separate Apply button). -->\n <p-dropdown\n styleClass=\"w-full\"\n appendTo=\"body\"\n [options]=\"presetSet.classes\"\n optionLabel=\"name\"\n optionValue=\"name\"\n [(ngModel)]=\"bulkClass\"\n placeholder=\"Choose a class\u2026\"\n [filter]=\"presetSet.classes.length > 8\"\n filterBy=\"name\"\n (onChange)=\"applyBulkClass()\"\n >\n <ng-template let-c pTemplate=\"item\">\n <span class=\"dd-value\"\n ><span class=\"chip-swatch\" [style.background]=\"c.color\"></span>{{ c.name }}</span\n >\n </ng-template>\n </p-dropdown>\n <div class=\"p-inputgroup\">\n <input\n type=\"text\"\n pInputText\n placeholder=\"\u2026or a new class\"\n [(ngModel)]=\"newBulkClass\"\n (keydown.enter)=\"addAndApplyBulkClass()\"\n />\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n pTooltip=\"Add class & set it\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!newBulkClass.trim()\"\n (click)=\"addAndApplyBulkClass()\"\n ></button>\n </div>\n </div>\n </p-overlayPanel>\n <p-button\n icon=\"pi pi-trash\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"deleteSelectedRegions()\"\n pTooltip=\"Delete selected regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n ></p-button>\n <p-button\n icon=\"pi pi-times-circle\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"clearAllRegions()\"\n pTooltip=\"Delete all regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!regions || !regions.length\"\n ></p-button>\n <p-button\n icon=\"pi pi-question\"\n size=\"small\"\n [text]=\"true\"\n (click)=\"showHelp()\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n ></p-button>\n </div>\n</p-toolbar>\n\n<region-classes-panel\n [classes]=\"displayClasses\"\n [counts]=\"classCounts\"\n [matchMode]=\"presetSet.matchMode\"\n [activeClass]=\"activeClass\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n [defaultClassName]=\"defaultClassName\"\n (pick)=\"selectActiveClass($event)\"\n (recolor)=\"setClassColor($event.name, $event.color)\"\n (remove)=\"deleteClass($event)\"\n (manage)=\"openManageDialog()\"\n>\n</region-classes-panel>\n\n<region-table\n [page]=\"pagedRegions\"\n [total]=\"regions.length\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [rowsPerPageOptions]=\"rowsPerPageOptions\"\n [metaKey]=\"metaKey\"\n [selection]=\"selectedRegions\"\n (selectionChange)=\"selectedRegions = $event\"\n (rowSelect)=\"onSelectionChanged()\"\n [presetSet]=\"presetSet\"\n [defaultColor]=\"shapeColor\"\n [mpp]=\"mpp\"\n [labelDrafts]=\"editingLabelRegions\"\n (labelEditStart)=\"startEditLabel($event)\"\n (labelDraftChange)=\"setLabelDraft($event.region, $event.value)\"\n (labelEditStop)=\"stopEditLabel($event.region, $event.commit)\"\n (classPick)=\"applyPresetToRegion($event.region, $event.name)\"\n (deleteRow)=\"deleteRegion($event)\"\n (pageChange)=\"onPageChange($event)\"\n>\n</region-table>\n\n<!-- Live-edit mode: no Save/Cancel \u2014 every edit commits immediately to the\n active image's region cache. -->\n\n<p-confirmDialog\n #cd\n [style]=\"{ width: '24rem', height: '14rem' }\"\n key=\"positionDialog\"\n [baseZIndex]=\"10000\"\n rejectButtonStyleClass=\"p-button-outlined\"\n>\n <ng-template pTemplate=\"footer\">\n <button type=\"button\" pButton icon=\"pi pi-check\" label=\"Yes\" (click)=\"cd.accept()\"></button>\n <button\n type=\"button\"\n class=\"p-button-outlined\"\n pButton\n icon=\"pi pi-times\"\n label=\"No\"\n (click)=\"cd.reject()\"\n ></button>\n </ng-template>\n</p-confirmDialog>\n\n<region-save-regions-dialog\n [(visible)]=\"showSaveAsDialog\"\n [filename]=\"saveAsFilename\"\n (filenameChange)=\"saveAsFilename = $event; checkSaveAsFileExists()\"\n [fileExists]=\"saveAsFileExists\"\n [busy]=\"saveAsBusy\"\n (confirm)=\"confirmSaveAs()\"\n (cancelSave)=\"cancelSaveAs()\"\n>\n</region-save-regions-dialog>\n\n<region-save-regions-dialog\n header=\"Export Regions\"\n confirmLabel=\"Export\"\n confirmIcon=\"pi pi-download\"\n inputId=\"export-filename\"\n [(visible)]=\"showExportDialog\"\n [(filename)]=\"exportFilename\"\n (confirm)=\"confirmExport()\"\n>\n</region-save-regions-dialog>\n\n<region-save-mask-dialog\n [(visible)]=\"showSaveMaskDialog\"\n [(filename)]=\"saveMaskFilename\"\n [(mode)]=\"maskMode\"\n [busy]=\"maskBusy\"\n [progress]=\"maskProgress\"\n [encoding]=\"maskEncoding\"\n (confirm)=\"confirmSaveMask()\"\n (cancelExport)=\"cancelSaveMask()\"\n>\n</region-save-mask-dialog>\n\n<region-color-dialog\n [(visible)]=\"showColorDialog\"\n [edits]=\"classColorEdits\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n (apply)=\"applyColorToSelected($event)\"\n>\n</region-color-dialog>\n\n<!-- Manage annotation classes (jit-ui#70): edits a working copy, committed on Apply. -->\n<region-manage-classes-dialog\n [(visible)]=\"showManageDialog\"\n [(draft)]=\"presetDraft\"\n (apply)=\"applyManageDialog(true)\"\n (resetDefaults)=\"resetPresetsToDefaults()\"\n (importFile)=\"importPresets($event)\"\n (export)=\"exportPresets()\"\n>\n</region-manage-classes-dialog>\n\n<region-editor-help [(visible)]=\"displayHelpDialog\"></region-editor-help>\n", styles: ["@charset \"UTF-8\";.chip-swatch{display:inline-block;width:.75rem;height:.75rem;border-radius:50%;border:1px solid rgba(0,0,0,.2);flex:0 0 auto}.dd-value{display:inline-flex;align-items:center;gap:.4rem;min-width:0}.dd-value .class-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}::ng-deep region-editor .p-toolbar.region-toolbar{padding:.25rem .5rem;border-radius:0;border-left:none;border-right:none;border-top:none}::ng-deep region-editor .p-toolbar.region-toolbar .p-button.p-button-icon-only{width:auto;padding:.25rem .5rem}::ng-deep region-editor .p-toolbar.region-toolbar .p-button{padding:.25rem .5rem}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}\n"] }]
|
|
1560
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [RegionPersistenceService], template: "<p-toolbar styleClass=\"region-toolbar\">\n <div class=\"p-toolbar-group-start align-items-center flex-wrap gap-1\">\n <p-button\n icon=\"pi pi-tag\"\n size=\"small\"\n [text]=\"!showShapeLabel\"\n pTooltip=\"Show region labels.\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showShapeLabel = !showShapeLabel; changeShowShapeLabel(showShapeLabel)\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-stop-circle\"\n size=\"small\"\n [text]=\"!regionsFilled\"\n pTooltip=\"Fill regions in their colour (an atlas's look); labels sit inside.\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Fill regions\"\n (onClick)=\"toggleFill()\"\n >\n </p-button>\n <p-button\n *ngIf=\"volumeView\"\n icon=\"pi pi-eye\"\n size=\"small\"\n [text]=\"!regionsThroughVolume\"\n [attr.aria-pressed]=\"regionsThroughVolume\"\n pTooltip=\"See the regions through the volume. Off, the volume hides the parts of them behind what it shows; on, none (layers traced inside bright structures, such as an OCT's).\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Regions through volume\"\n (onClick)=\"toggleThroughVolume()\"\n >\n </p-button>\n <span class=\"toolbar-separator\"></span>\n <!-- New regions are now created from the diagram toolbar\n (rectangle, polyline, freeform, wand). -->\n <p-button\n icon=\"pi pi-upload\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Import regions: a GeoJSON file, or a label volume (.nii, .nii.gz, .nrrd) chosen with its ontology JSON for the class tree.\"\n tooltipPosition=\"bottom\"\n (click)=\"roiFileInput.click()\"\n >\n </p-button>\n <input\n #roiFileInput\n type=\"file\"\n accept=\".geojson,.json,.nii,.gz,.nrrd\"\n multiple\n hidden\n (change)=\"importRois($event); roiFileInput.value = ''\"\n />\n <p-button\n icon=\"pi pi-folder-open\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Import a folder of per-slice GeoJSON files (one per slice, in name order, with its regionset.json class tree).\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Import a folder of regions\"\n (click)=\"roiFolderInput.click()\"\n >\n </p-button>\n <input\n #roiFolderInput\n type=\"file\"\n webkitdirectory\n multiple\n hidden\n (change)=\"importRois($event); roiFolderInput.value = ''\"\n />\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download regions as geojson file.\"\n tooltipPosition=\"bottom\"\n icon=\"pi pi-download\"\n (click)=\"exportRois()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-save\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Save regions to server.\"\n tooltipPosition=\"bottom\"\n (click)=\"persistRegions()\"\n [disabled]=\"(!regions || !regions.length) && !hasRegionSource\"\n >\n </p-button>\n <p-button\n *ngIf=\"canImportFromServer\"\n icon=\"pi pi-cloud-download\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Import regions from server: a GeoJSON file, a folder of per-slice GeoJSON files or a label volume (.nii, .nii.gz, .nrrd).\"\n tooltipPosition=\"bottom\"\n ariaLabel=\"Import regions from server\"\n [loading]=\"importing\"\n (click)=\"importFromServer()\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Download mask of the regions as PNG\"\n tooltipPosition=\"bottom\"\n (click)=\"openSaveMaskDialog()\"\n [disabled]=\"!regions || !regions.length\"\n >\n <!-- References the file so Inkscape edits to mask.svg show up directly\n (the lib's assets/** are served at assets/plotting/). The\n toolbar-icon-dark filter recolours the black SVG to the theme blue,\n same as region-editor.svg and the other SVG toolbar icons. -->\n <img\n src=\"assets/plotting/mask.svg\"\n class=\"toolbar-icon-dark\"\n style=\"width: 1rem; height: 1rem; vertical-align: middle\"\n alt=\"Download mask\"\n />\n </p-button>\n <p-button\n label=\"x512\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Round all rectangle regions\n to width and height that are multiple of 512\"\n tooltipPosition=\"bottom\"\n (click)=\"roundRectangleLengths()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-check-square\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Select all regions\"\n tooltipPosition=\"bottom\"\n (click)=\"selectAllRegions()\"\n [disabled]=\"!regions || !regions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-tags\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit class on selected rows\"\n tooltipPosition=\"bottom\"\n (click)=\"!selectedRegions || !selectedRegions.length ? op.hide() : op.toggle($event)\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-palette\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n pTooltip=\"Edit colour of selected regions\"\n tooltipPosition=\"bottom\"\n (click)=\"openColorDialog()\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n >\n </p-button>\n <p-overlayPanel #op (onHide)=\"bulkClass = ''; newBulkClass = ''\">\n <div class=\"flex flex-column gap-2\" style=\"width: 18rem\">\n <span class=\"font-medium text-900\"\n >Set class on {{ selectedRegions?.length || 0 }} selected region(s)</span\n >\n <!-- Selecting a class applies it immediately (choosing an option closes the\n overlay, so there's no separate Apply button). -->\n <p-dropdown\n styleClass=\"w-full\"\n appendTo=\"body\"\n [options]=\"presetSet.classes\"\n optionLabel=\"name\"\n optionValue=\"name\"\n [(ngModel)]=\"bulkClass\"\n placeholder=\"Choose a class\u2026\"\n [filter]=\"presetSet.classes.length > 8\"\n filterBy=\"name\"\n (onChange)=\"applyBulkClass()\"\n >\n <ng-template let-c pTemplate=\"item\">\n <span class=\"dd-value\"\n ><span class=\"chip-swatch\" [style.background]=\"c.color\"></span>{{ c.name }}</span\n >\n </ng-template>\n </p-dropdown>\n <div class=\"p-inputgroup\">\n <input\n type=\"text\"\n pInputText\n placeholder=\"\u2026or a new class\"\n [(ngModel)]=\"newBulkClass\"\n (keydown.enter)=\"addAndApplyBulkClass()\"\n />\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n pTooltip=\"Add class & set it\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!newBulkClass.trim()\"\n (click)=\"addAndApplyBulkClass()\"\n ></button>\n </div>\n </div>\n </p-overlayPanel>\n <p-button\n icon=\"pi pi-trash\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"deleteSelectedRegions()\"\n pTooltip=\"Delete selected regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"!selectedRegions || !selectedRegions.length\"\n ></p-button>\n <p-button\n icon=\"pi pi-times-circle\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"mr-2\"\n (click)=\"clearAllRegions()\"\n pTooltip=\"Delete all regions\"\n tooltipPosition=\"bottom\"\n [disabled]=\"(!regions || !regions.length) && !hasRegionSource\"\n ></p-button>\n <p-button\n icon=\"pi pi-question\"\n size=\"small\"\n [text]=\"true\"\n (click)=\"showHelp()\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n ></p-button>\n </div>\n</p-toolbar>\n\n<region-classes-panel\n [classes]=\"displayClasses\"\n [counts]=\"classCounts\"\n [matchMode]=\"presetSet.matchMode\"\n [activeClass]=\"activeClass\"\n [picked]=\"pickedClass\"\n [marked]=\"markedClasses\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n [defaultClassName]=\"defaultClassName\"\n (pick)=\"selectActiveClass($event)\"\n (recolor)=\"setClassColor($event.name, $event.color)\"\n (remove)=\"deleteClass($event)\"\n (manage)=\"openManageDialog()\"\n [volume]=\"volumeView\"\n [shown3d]=\"shown3dNames\"\n (toggle3d)=\"toggleClass3d($event)\"\n [hidden]=\"hiddenClasses\"\n (toggleHidden)=\"setClassesHidden([$event], !hiddenClasses.has($event))\"\n [treeView]=\"classHierarchy ? classTreeView : null\"\n (treeViewChange)=\"classTreeView = $event\"\n>\n <!-- A region set with a class hierarchy (an atlas ontology) can show its classes as a tree. -->\n <region-class-tree\n *ngIf=\"classHierarchy as hierarchy\"\n [nodes]=\"hierarchy\"\n [counts]=\"treeCounts\"\n [colorOf]=\"treeColor\"\n [picked]=\"pickedClass\"\n [marked]=\"markedClasses\"\n [volume]=\"volumeView\"\n [shown3d]=\"shown3dNames\"\n (pick)=\"pickClasses($event)\"\n (recolor)=\"setClassColor($event.name, $event.color)\"\n (toggle3d)=\"toggleClass3d($event.name, $event.classes)\"\n [hidden]=\"hiddenClasses\"\n (toggleHidden)=\"setClassesHidden($event.classes, $event.hidden)\"\n >\n </region-class-tree>\n</region-classes-panel>\n\n<region-table\n [page]=\"pagedRegions\"\n [total]=\"tableTotal\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [rowsPerPageOptions]=\"rowsPerPageOptions\"\n [metaKey]=\"metaKey\"\n [selection]=\"selectedRegions\"\n (selectionChange)=\"selectedRegions = $event\"\n (rowSelect)=\"onSelectionChanged()\"\n [presetSet]=\"tablePresetSet\"\n [defaultColor]=\"shapeColor\"\n [mpp]=\"mpp\"\n [volumes]=\"tableVolumes\"\n [labelDrafts]=\"editingLabelRegions\"\n (labelEditStart)=\"startEditLabel($event)\"\n (labelDraftChange)=\"setLabelDraft($event.region, $event.value)\"\n (labelEditStop)=\"stopEditLabel($event.region, $event.commit)\"\n (classPick)=\"applyPresetToRegion($event.region, $event.name)\"\n (deleteRow)=\"deleteRegion($event)\"\n (pageChange)=\"onPageChange($event)\"\n>\n</region-table>\n\n<!-- Live-edit mode: no Save/Cancel \u2014 every edit commits immediately to the\n active image's region cache. -->\n\n<p-confirmDialog\n #cd\n [style]=\"{ width: '24rem', height: '14rem' }\"\n key=\"positionDialog\"\n [baseZIndex]=\"10000\"\n rejectButtonStyleClass=\"p-button-outlined\"\n>\n <ng-template pTemplate=\"footer\">\n <button type=\"button\" pButton icon=\"pi pi-check\" label=\"Yes\" (click)=\"cd.accept()\"></button>\n <button\n type=\"button\"\n class=\"p-button-outlined\"\n pButton\n icon=\"pi pi-times\"\n label=\"No\"\n (click)=\"cd.reject()\"\n ></button>\n </ng-template>\n</p-confirmDialog>\n\n<region-save-regions-dialog\n [(visible)]=\"showSaveAsDialog\"\n [filename]=\"saveAsFilename\"\n (filenameChange)=\"saveAsFilename = $event; checkSaveAsFileExists()\"\n [fileExists]=\"saveAsFileExists\"\n [busy]=\"saveAsBusy\"\n (confirm)=\"confirmSaveAs()\"\n (cancelSave)=\"cancelSaveAs()\"\n>\n</region-save-regions-dialog>\n\n<region-save-regions-dialog\n header=\"Export Regions\"\n confirmLabel=\"Export\"\n confirmIcon=\"pi pi-download\"\n inputId=\"export-filename\"\n [(visible)]=\"showExportDialog\"\n [(filename)]=\"exportFilename\"\n (confirm)=\"confirmExport()\"\n>\n</region-save-regions-dialog>\n\n<region-save-mask-dialog\n [(visible)]=\"showSaveMaskDialog\"\n [(filename)]=\"saveMaskFilename\"\n [(mode)]=\"maskMode\"\n [busy]=\"maskBusy\"\n [progress]=\"maskProgress\"\n [encoding]=\"maskEncoding\"\n (confirm)=\"confirmSaveMask()\"\n (cancelExport)=\"cancelSaveMask()\"\n>\n</region-save-mask-dialog>\n\n<region-color-dialog\n [(visible)]=\"showColorDialog\"\n [edits]=\"classColorEdits\"\n [selectedCount]=\"selectedRegions?.length || 0\"\n (apply)=\"applyColorToSelected($event)\"\n>\n</region-color-dialog>\n\n<!-- Manage annotation classes (jit-ui#70): edits a working copy, committed on Apply. -->\n<region-manage-classes-dialog\n [(visible)]=\"showManageDialog\"\n [(draft)]=\"presetDraft\"\n (apply)=\"applyManageDialog(true)\"\n (resetDefaults)=\"resetPresetsToDefaults()\"\n (importFile)=\"importPresets($event)\"\n (export)=\"exportPresets()\"\n>\n</region-manage-classes-dialog>\n\n<region-editor-help [(visible)]=\"displayHelpDialog\"></region-editor-help>\n", styles: ["@charset \"UTF-8\";.chip-swatch{display:inline-block;width:.75rem;height:.75rem;border-radius:50%;border:1px solid rgba(0,0,0,.2);flex:0 0 auto}.dd-value{display:inline-flex;align-items:center;gap:.4rem;min-width:0}.dd-value .class-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}::ng-deep region-editor .p-toolbar.region-toolbar{padding:.25rem .5rem;border-radius:0;border-left:none;border-right:none;border-top:none}::ng-deep region-editor .p-toolbar.region-toolbar .p-button.p-button-icon-only{width:auto;padding:.25rem .5rem}::ng-deep region-editor .p-toolbar.region-toolbar .p-button{padding:.25rem .5rem}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}\n"] }]
|
|
935
1561
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
936
1562
|
type: Inject,
|
|
937
1563
|
args: [REGION_EDITOR_API]
|
|
938
1564
|
}] }, { type: i1.MessageService }, { type: i1.ConfirmationService }, { type: i2.RegionPersistenceService }, { type: i3.MaskExportService }], propDecorators: { overlayPanel: [{
|
|
939
1565
|
type: ViewChild,
|
|
940
1566
|
args: ['op']
|
|
1567
|
+
}], active: [{
|
|
1568
|
+
type: Input
|
|
941
1569
|
}] } });
|
|
942
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLE1BQU0sRUFHTixTQUFTLEVBQ1QsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFFLE9BQU8sRUFB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LGtCQUFrQixrV0FDbEIsYUFBYSxrSkFDYixhQUFhLHVYQUNiLHFCQUFxQixtTkFDckIsb0JBQW9CLGdWQUNwQiwwQkFBMEIseVBBQzFCLHVCQUF1QixvT0FDdkIsMEJBQTBCLG9KQUMxQiw0QkFBNEIsb01BQzVCLHlCQUF5Qjs7MkZBT2hCLHFCQUFxQjtrQkEzQmpDLFNBQVM7K0JBQ0UsZUFBZSxjQUNiLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsY0FBYzt3QkFDZCxlQUFlO3dCQUNmLGtCQUFrQjt3QkFDbEIsYUFBYTt3QkFDYixhQUFhO3dCQUNiLHFCQUFxQjt3QkFDckIsb0JBQW9CO3dCQUNwQiwwQkFBMEI7d0JBQzFCLHVCQUF1Qjt3QkFDdkIsMEJBQTBCO3dCQUMxQiw0QkFBNEI7d0JBQzVCLHlCQUF5QjtxQkFDMUIsbUJBR2dCLHVCQUF1QixDQUFDLE1BQU0sYUFDcEMsQ0FBQyx3QkFBd0IsQ0FBQzs7MEJBZ0dsQyxNQUFNOzJCQUFDLGlCQUFpQjsrS0E3RkYsWUFBWTtzQkFBcEMsU0FBUzt1QkFBQyxJQUFJIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEluamVjdCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIFZpZXdDaGlsZCxcbiAgaW5qZWN0LFxuICBOZ1pvbmUsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbWFya0ZvckNoZWNrSW5ab25lIH0gZnJvbSAnLi4vdXRpbC9tYXJrLWZvci1jaGVjayc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBDb25maXJtRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jb25maXJtZGlhbG9nJztcbmltcG9ydCB7IERyb3Bkb3duTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kcm9wZG93bic7XG5pbXBvcnQgeyBJbnB1dFRleHRNb2R1bGUgfSBmcm9tICdwcmltZW5nL2lucHV0dGV4dCc7XG5pbXBvcnQgeyBPdmVybGF5UGFuZWwsIE92ZXJsYXlQYW5lbE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvb3ZlcmxheXBhbmVsJztcbmltcG9ydCB7IFRvb2xiYXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2xiYXInO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5pbXBvcnQgeyBzYXZlQXMgfSBmcm9tICdmaWxlLXNhdmVyJztcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBSZWN0YW5nbGUsIFJlZ2lvbiB9IGZyb20gJy4uL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgd2l0aFJlZ2lvblBhdGNoIH0gZnJvbSAnLi4vbW9kZWxzL3JlZ2lvbi1jbG9uZSc7XG5pbXBvcnQgeyBQcmVzZXRTZXQsIENsYXNzUHJlc2V0LCBkZWZhdWx0UHJlc2V0U2V0LCBwYXJzZVByZXNldFNldCB9IGZyb20gJy4uL21vZGVscy9jbGFzcy1wcmVzZXQnO1xuaW1wb3J0IHsgY29sb3JGb3JMYWJlbCwgcHJlc2V0S2V5IH0gZnJvbSAnLi4vc3RvcmUvY2xhc3MtY29sb3IudXRpbCc7XG5pbXBvcnQgeyBDb25maXJtYXRpb25TZXJ2aWNlLCBNZXNzYWdlU2VydmljZSwgU2hhcmVkTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgSVJlZ2lvbkVkaXRvckFwaSwgUkVHSU9OX0VESVRPUl9BUEkgfSBmcm9tICcuLi9jb250cmFjdHMvcmVnaW9uLWVkaXRvci1hcGkuY29udHJhY3QnO1xuaW1wb3J0IHsgVklaX1RPQVNUX0tFWSB9IGZyb20gJy4uL3RvYXN0LW91dGxldHMnO1xuaW1wb3J0IHsgUmVnaW9uUGVyc2lzdGVuY2VTZXJ2aWNlIH0gZnJvbSAnLi9yZWdpb24tcGVyc2lzdGVuY2Uuc2VydmljZSc7XG5pbXBvcnQgeyBDbGFzc0NvbG9yRWRpdCwgUmVnaW9uQ29sb3JEaWFsb2dDb21wb25lbnQgfSBmcm9tICcuL3JlZ2lvbi1jb2xvci1kaWFsb2cvcmVnaW9uLWNvbG9yLWRpYWxvZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2xhc3Nlc1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9jbGFzc2VzLXBhbmVsL2NsYXNzZXMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFJlZ2lvblRhYmxlQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tdGFibGUvcmVnaW9uLXRhYmxlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTYXZlUmVnaW9uc0RpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4vc2F2ZS1yZWdpb25zLWRpYWxvZy9zYXZlLXJlZ2lvbnMtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTYXZlTWFza0RpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4vc2F2ZS1tYXNrLWRpYWxvZy9zYXZlLW1hc2stZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYW5hZ2VDbGFzc2VzRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi9tYW5hZ2UtY2xhc3Nlcy1kaWFsb2cvbWFuYWdlLWNsYXNzZXMtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWdpb25FZGl0b3JIZWxwQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tZWRpdG9yLWhlbHAvcmVnaW9uLWVkaXRvci1oZWxwLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYXNrRXhwb3J0U2VydmljZSwgTWFza01vZGUgfSBmcm9tICcuL21hc2stZXhwb3J0LnNlcnZpY2UnO1xuaW1wb3J0IHsgUGl4ZWxTaXplLCBmb3JtYXRBcmVhLCBwaWNrTXBwLCByZWdpb25BcmVhUHggfSBmcm9tICcuL3JlZ2lvbi1tZXRyaWNzJztcblxuLyoqXG4gKiBUaGUgUmVnaW9uIEVkaXRvciAoYDxyZWdpb24tZWRpdG9yPmApOiB0aGUgdGFibGUgb2YgdGhlIGFjdGl2ZSBpbWFnZSdzXG4gKiBhbm5vdGF0aW9uIHJlZ2lvbnMgd2l0aCBjbGFzcyBwcmVzZXRzLCBjb2xvdXJzLCBsYWJlbHMsIEdlb0pTT04gaW1wb3J0IC9cbiAqIGV4cG9ydCAvIHNlcnZlciBzYXZlIGFuZCBtYXNrIGV4cG9ydC4gU2VsZi1jb250YWluZWQ6IGl0IHRhbGtzIHRvIHRoZSB2aWV3ZXJcbiAqIG9ubHkgdGhyb3VnaCB7QGxpbmsgUkVHSU9OX0VESVRPUl9BUEl9IChhbmQgdGhlIGhvc3QncyBSRUdJT05fSU9fUE9SVCksIHNvIGl0XG4gKiBoYXMgbm8gaW5wdXRzIG9yIG91dHB1dHMuXG4gKlxuICogT25QdXNoOiB0ZW1wbGF0ZSBldmVudHMgcmUtcmVuZGVyIGl0OyBzdGF0ZSB0aGF0IGxhbmRzIGFzeW5jaHJvbm91c2x5ICh0aGVcbiAqIEFQSSdzIHJlZ2lvbiAvIHNlbGVjdGlvbiAvIHByZXNldCAvIGltYWdlLW1ldGEgc3RyZWFtcywgc2F2ZSBhbmQgbWFzay1leHBvcnRcbiAqIHByb2dyZXNzLCBmaWxlIHJlYWRzKSBtYXJrcyBpdCBmb3IgY2hlY2suXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JlZ2lvbi1lZGl0b3InLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFNoYXJlZE1vZHVsZSxcbiAgICBCdXR0b25Nb2R1bGUsXG4gICAgQ29uZmlybURpYWxvZ01vZHVsZSxcbiAgICBEcm9wZG93bk1vZHVsZSxcbiAgICBJbnB1dFRleHRNb2R1bGUsXG4gICAgT3ZlcmxheVBhbmVsTW9kdWxlLFxuICAgIFRvb2xiYXJNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBDbGFzc2VzUGFuZWxDb21wb25lbnQsXG4gICAgUmVnaW9uVGFibGVDb21wb25lbnQsXG4gICAgU2F2ZVJlZ2lvbnNEaWFsb2dDb21wb25lbnQsXG4gICAgU2F2ZU1hc2tEaWFsb2dDb21wb25lbnQsXG4gICAgUmVnaW9uQ29sb3JEaWFsb2dDb21wb25lbnQsXG4gICAgTWFuYWdlQ2xhc3Nlc0RpYWxvZ0NvbXBvbmVudCxcbiAgICBSZWdpb25FZGl0b3JIZWxwQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vcmVnaW9uLWVkaXRvci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3JlZ2lvbi1lZGl0b3IuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW1JlZ2lvblBlcnNpc3RlbmNlU2VydmljZV0sXG59KVxuZXhwb3J0IGNsYXNzIFJlZ2lvbkVkaXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQFZpZXdDaGlsZCgnb3AnKSBwcml2YXRlIG92ZXJsYXlQYW5lbCE6IE92ZXJsYXlQYW5lbDtcblxuICBwcm90ZWN0ZWQgcmVnaW9uczogUmVnaW9uW10gPSBbXTtcbiAgcHJvdGVjdGVkIHNlbGVjdGVkUmVnaW9uczogUmVnaW9uW10gPSBbXTtcbiAgcHJvdGVjdGVkIHNob3dTaGFwZUxhYmVsITogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIHNoYXBlQ29sb3IhOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBmaWxsQ29sb3IhOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBkaXNwbGF5SGVscERpYWxvZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgc2hvd0NvbG9yRGlhbG9nID0gZmFsc2U7XG4gIC8qKiBPbmUgY29sb3VyIGVkaXRvciBwZXIgdW5pcXVlIGNsYXNzIGFtb25nIHRoZSBzZWxlY3RlZCByZWdpb25zLCBzaG93biBpbiB0aGVcbiAgICogIFwiZWRpdCBjb2xvdXIgb2Ygc2VsZWN0ZWQgcmVnaW9uc1wiIGRpYWxvZy4gVW5jbGFzc2lmaWVkIHJlZ2lvbnMgKG5vIGxhYmVsKVxuICAgKiAgYXJlIGdyb3VwZWQgdW5kZXIgYSBzaW5nbGUgZW50cnkgd2l0aCBhbiBlbXB0eSBgbGFiZWxgLiAqL1xuICBwcm90ZWN0ZWQgY2xhc3NDb2xvckVkaXRzOiBDbGFzc0NvbG9yRWRpdFtdID0gW107XG4gIC8qKiBcIkVkaXQgY2xhc3Mgb24gc2VsZWN0ZWQgcm93c1wiIHBvcHVwOiBjaG9zZW4gZXhpc3RpbmcgY2xhc3MsIGFuZCBhIG5ldy1jbGFzcyBuYW1lLiAqL1xuICBwcm90ZWN0ZWQgYnVsa0NsYXNzID0gJyc7XG4gIHByb3RlY3RlZCBuZXdCdWxrQ2xhc3MgPSAnJztcblxuICAvLyDilIDilIAgYW5ub3RhdGlvbi1jbGFzcyBwcmVzZXRzIChqaXQtdWkjNzApIOKUgOKUgFxuICAvKiogTG9jYWwgbWlycm9yIG9mIHRoZSBwZXItdXNlciBwcmVzZXQgc2V0IChjaGlwIHN0cmlwLCBDbGFzcyBkcm9wZG93biwgZGlhbG9nKS4gKi9cbiAgcHJvdGVjdGVkIHByZXNldFNldDogUHJlc2V0U2V0ID0gZGVmYXVsdFByZXNldFNldCgpO1xuICAvKiogVGhlIGNsYXNzIGxhc3QgcGlja2VkIGluIHRoZSBwYW5lbDsgYSBjaGlwLWNsaWNrIGFwcGxpZXMgaXQgdG8gdGhlIHNlbGVjdGVkIHJvd3MuICovXG4gIHByb3RlY3RlZCBhY3RpdmVDbGFzczogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCBzaG93TWFuYWdlRGlhbG9nID0gZmFsc2U7XG4gIC8qKiBXb3JraW5nIGNvcHkgZWRpdGVkIGluc2lkZSB0aGUgTWFuYWdlLWNsYXNzZXMgZGlhbG9nOyBjb21taXR0ZWQgb24gQXBwbHkvRG9uZS4gKi9cbiAgcHJvdGVjdGVkIHByZXNldERyYWZ0OiBQcmVzZXRTZXQgfCBudWxsID0gbnVsbDtcbiAgLyoqIGNsYXNzIG5hbWUgKG1hdGNoLW1vZGUga2V5ZWQpIOKGkiBudW1iZXIgb2YgcmVnaW9ucyBjdXJyZW50bHkgdXNpbmcgaXQuICovXG4gIHByb3RlY3RlZCBjbGFzc0NvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBGYWxsYmFjayBjbGFzcyB0aGF0IGEgcmVnaW9uIHJldmVydHMgdG8gd2hlbiBpdHMgY2xhc3MgaXMgZGVsZXRlZCAoaml0LXVpIzcwKS4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlZmF1bHRDbGFzc05hbWUgPSAnUmVnaW9uJztcbiAgLyoqIENsYXNzZXMgYXMgc2hvd24gaW4gdGhlIHBhbmVsOiBzb3J0ZWQgYnkgcmVnaW9uIGNvdW50IChkZXNjKSwgdGhlbiBuYW1lLiAqL1xuICBwcm90ZWN0ZWQgZGlzcGxheUNsYXNzZXM6IENsYXNzUHJlc2V0W10gPSBbXTtcblxuICBwcm90ZWN0ZWQgcGFnaW5hdG9yRmlyc3QgPSAwO1xuICBwcm90ZWN0ZWQgcGFnaW5hdG9yUm93cyA9IDEwO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcm93c1BlclBhZ2VPcHRpb25zID0gWzEwLCAyNSwgNTBdO1xuICAvKiogUmVnaW9ucyB3aG9zZSBDbGFzcyBjZWxsIGlzIGN1cnJlbnRseSBpbiBlZGl0IG1vZGUg4oaSIHRoZSBsYWJlbCBiZWluZyB0eXBlZC5cbiAgICogIFRoZSBkcmFmdCBpcyBjb21taXR0ZWQgb24gRW50ZXIgYW5kIGRpc2NhcmRlZCBvbiBFc2NhcGUv4pyVLCBzbyB0eXBpbmcgbmV2ZXJcbiAgICogIHdyaXRlcyBpbnRvIHRoZSBzdG9yZSdzIHJlZ2lvbiAoUlQtMTgpLiBLZXllZCBieSBvYmplY3QgaWRlbnRpdHksIHdoaWNoXG4gICAqICBhdm9pZHMgbmVlZGluZyBhIHVuaXF1ZSBpZCBmaWVsZC4gKi9cbiAgcHJvdGVjdGVkIGVkaXRpbmdMYWJlbFJlZ2lvbnMgPSBuZXcgTWFwPFJlZ2lvbiwgc3RyaW5nPigpO1xuXG4gIHByb3RlY3RlZCBzaG93U2F2ZUFzRGlhbG9nID0gZmFsc2U7XG4gIHByb3RlY3RlZCBzYXZlQXNGaWxlbmFtZSA9ICcnO1xuICBwcm90ZWN0ZWQgc2F2ZUFzRmlsZUV4aXN0cyA9IGZhbHNlO1xuICAvKiogVHJ1ZSB3aGlsZSBhIEdlb0pTT04gcGVyc2lzdCBpcyBzZXJpYWxpemluZy91cGxvYWRpbmcg4oCUIGRyaXZlcyB0aGUgZGlhbG9nJ3NcbiAgICogIHByb2dyZXNzIGJhciBhbmQgQ2FuY2VsIGJ1dHRvbiAocGFyaXR5IHdpdGggdGhlIFNhdmUtbWFzayBkaWFsb2cpLiAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFzQnVzeSA9IGZhbHNlO1xuICAvKiogVGhlIHJ1bm5pbmcgR2VvSlNPTiBzYXZlOyB1bnN1YnNjcmliaW5nIGNhbmNlbHMgaXQgKENhbmNlbCAvIGRlc3Ryb3kpLiAqL1xuICBwcml2YXRlIF9zYXZlQXNTdWI/OiBTdWJzY3JpcHRpb247XG4gIC8qKiBTYXZlLWFzIGZpbGUgbmFtZXMgdG8gY2hlY2sgZm9yIGFuIGV4aXN0aW5nIGZpbGUgKGRlYm91bmNlZCkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgc2F2ZUFzQ2hlY2skID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuXG4gIHByb3RlY3RlZCBzaG93RXhwb3J0RGlhbG9nID0gZmFsc2U7XG4gIHByb3RlY3RlZCBleHBvcnRGaWxlbmFtZSA9ICcnO1xuXG4gIHByb3RlY3RlZCBzaG93U2F2ZU1hc2tEaWFsb2cgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHNhdmVNYXNrRmlsZW5hbWUgPSAnJztcbiAgLyoqIE1hc2sgdHlwZSBjaG9zZW4gaW4gdGhlIFNhdmUtbWFzayBkaWFsb2c6IGEgYmluYXJ5IGZvcmVncm91bmQvYmFja2dyb3VuZFxuICAgKiAgbWFzaywgb3IgYSBtdWx0aS1jbGFzcyBtYXNrIHdpdGggYSBkaXN0aW5jdCBpZCBwZXIgcmVnaW9uLiAqL1xuICBwcm90ZWN0ZWQgbWFza01vZGU6IE1hc2tNb2RlID0gJ2JpbmFyeSc7XG4gIC8qKiBUcnVlIHdoaWxlIHRoZSBtYXNrIHdvcmtlciBpcyByYXN0ZXJpemluZy9lbmNvZGluZyDigJQgZHJpdmVzIHRoZSBwcm9ncmVzc1xuICAgKiAgYmFyIGFuZCB0aGUgQ2FuY2VsIGJ1dHRvbiBpbiB0aGUgZGlhbG9nLiAqL1xuICBwcm90ZWN0ZWQgbWFza0J1c3kgPSBmYWxzZTtcbiAgLyoqIDDigJMxMDAgcmFzdGVyaXphdGlvbiBwcm9ncmVzczsgc3dpdGNoZXMgdG8gaW5kZXRlcm1pbmF0ZSBkdXJpbmcgZW5jb2RpbmcuICovXG4gIHByb3RlY3RlZCBtYXNrUHJvZ3Jlc3MgPSAwO1xuICBwcm90ZWN0ZWQgbWFza0VuY29kaW5nID0gZmFsc2U7XG4gIC8qKiBUaGUgcnVubmluZyBtYXNrIGV4cG9ydDsgdW5zdWJzY3JpYmluZyBjYW5jZWxzIGl0ICh0ZXJtaW5hdGVzIGl0cyB3b3JrZXIpLiAqL1xuICBwcml2YXRlIG1hc2tKb2I/OiBTdWJzY3JpcHRpb247XG5cbiAgLyoqXG4gICAqIFByaW1lTkcgcC10YWJsZSBtdWx0aS1zZWxlY3Rpb24gbW9kZSB0b2dnbGUuIFdoZW4gdHJ1ZSwgc2luZ2xlLWNsaWNrXG4gICAqIHNlbGVjdHMgb25lIHJvdyAocmVwbGFjaW5nIHByaW9yKTsgbWV0YS9jdHJsLWNsaWNrIHRvZ2dsZXMgYSByb3cgaW4vb3V0XG4gICAqIG9mIHRoZSBzZWxlY3Rpb24uIFdoZW4gZmFsc2UsIGV2ZXJ5IGNsaWNrIHRvZ2dsZXMuIERlZmF1bHQgdHJ1ZSB0b1xuICAgKiBtYXRjaCB0aGUgbW9zdCBjb21tb24gc3ByZWFkc2hlZXQtbGlrZSBVWC5cbiAgICovXG4gIHByb3RlY3RlZCBtZXRhS2V5ID0gdHJ1ZTtcblxuICBwcml2YXRlIF91cGRhdGluZ0Zyb21FZGl0b3IgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfc3VwcHJlc3NTZWxlY3Rpb25TeW5jVG9QbG90ID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IHpvbmUgPSBpbmplY3QoTmdab25lKTtcblxuICAvKiogUmUtcmVuZGVyIHRoaXMgT25QdXNoIHZpZXcsIHJlLWVudGVyaW5nIHRoZSB6b25lIHdoZW4gdGhlIGNoYW5nZSBjYW1lIGZyb20gb3V0c2lkZSBpdC4gKi9cbiAgcHJpdmF0ZSBjaGFuZ2VkKCk6IHZvaWQge1xuICAgIG1hcmtGb3JDaGVja0luWm9uZSh0aGlzLmNkciwgdGhpcy56b25lKTtcbiAgfVxuXG4gIC8qKiBQaHlzaWNhbCBwaXhlbCBzaXplICjCtW0vcGl4ZWwpIG9mIHRoZSBhY3RpdmUgaW1hZ2UsIGZvciByZWdpb24gYXJlYXMgaW5cbiAgICogIMK1bcKyOyBlbXB0eSB3aGVuIHRoZSBmb3JtYXQgcmVwb3J0cyBubyBwaHlzaWNhbCBzaXplLiAqL1xuICBwcm90ZWN0ZWQgbXBwOiBQaXhlbFNpemUgPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFJFR0lPTl9FRElUT1JfQVBJKSBwcml2YXRlIHJlZ2lvbkFwaTogSVJlZ2lvbkVkaXRvckFwaSxcbiAgICBwcml2YXRlIG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIGNvbmZpcm1hdGlvblNlcnZpY2U6IENvbmZpcm1hdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwZXJzaXN0ZW5jZTogUmVnaW9uUGVyc2lzdGVuY2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgbWFza0V4cG9ydDogTWFza0V4cG9ydFNlcnZpY2UsXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnNob3dTaGFwZUxhYmVsID0gdGhpcy5yZWdpb25BcGkuZ2V0U2hvd1NoYXBlTGFiZWwoKTtcbiAgICB0aGlzLnNoYXBlQ29sb3IgPSB0aGlzLnJlZ2lvbkFwaS5nZXRTaGFwZUNvbG9yKCk7XG4gICAgdGhpcy5maWxsQ29sb3IgPSB0aGlzLnJlZ2lvbkFwaS5nZXRGaWxsQ29sb3IoKTtcblxuICAgIC8vIEFubm90YXRpb24tY2xhc3MgcHJlc2V0cyAoaml0LXVpIzcwKTogbWlycm9yIHRoZSBzZXQgZm9yIHRoZSBjaGlwIHN0cmlwLFxuICAgIC8vIHRoZSBDbGFzcyBkcm9wZG93biBhbmQgdGhlIG1hbmFnZSBkaWFsb2cuIEd1YXJkZWQgd2l0aCBvcHRpb25hbCBjYWxscyBzb1xuICAgIC8vIHBhcnRpYWwgQVBJIG1vY2tzIGluIHRlc3RzICh3aGljaCBvbWl0IHRoZSBwcmVzZXQgbWV0aG9kcykgZG9uJ3QgdGhyb3cuXG4gICAgY29uc3QgaW5pdGlhbFByZXNldHMgPSB0aGlzLnJlZ2lvbkFwaS5nZXRQcmVzZXRTZXQ/LigpO1xuICAgIGlmIChpbml0aWFsUHJlc2V0cykgdGhpcy5wcmVzZXRTZXQgPSBpbml0aWFsUHJlc2V0cztcbiAgICBjb25zdCBwcmVzZXRzJCA9IHRoaXMucmVnaW9uQXBpLmdldFByZXNldFNldCQ/LigpO1xuICAgIGlmIChwcmVzZXRzJCkge1xuICAgICAgcHJlc2V0cyQucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChzZXQpID0+IHtcbiAgICAgICAgaWYgKHNldCkgdGhpcy5wcmVzZXRTZXQgPSBzZXQ7XG4gICAgICAgIHRoaXMudXBkYXRlRGlzcGxheUNsYXNzZXMoKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gU2VlZCBmcm9tIHRoZSB2aXN1YWxpemVyJ3MgY3VycmVudCByZWdpb25zIOKAlCBhbHJlYWR5IHNjb3BlZCB0byB0aGVcbiAgICAvLyBhY3RpdmUgaW1hZ2UgYnkgdGhlIHBlci1pbWFnZSBjYWNoZSwgYW5kIGhhbmRlZCBiYWNrIGFzIG5ldXRyYWwgUmVnaW9uXG4gICAgLy8gb2JqZWN0cyAobm8gYmFja2VuZCBzaGFwZSBmb3JtYXQgaW52b2x2ZWQpLlxuICAgIC8vIEFubm90YXRpb24gcmVnaW9ucyBvbmx5IOKAlCBpbnRlbnNpdHktcHJvZmlsZSBsaW5lcyBhcmUgb3duZWQgYnkgdGhlXG4gICAgLy8gaW50ZW5zaXR5IHRvb2wgYW5kIGV4Y2x1ZGVkIGJ5IHRoZSBjb250cmFjdCwgc28gdGhlIGVkaXRvciBuZXZlciBzZWVzIHRoZW0uXG4gICAgdGhpcy5yZWdpb25zID0gdGhpcy5hcHBseVJlZ2lvbkNvbG9ycyh0aGlzLnJlZ2lvbkFwaS5nZXRBbm5vdGF0aW9uUmVnaW9ucygpKTtcbiAgICB0aGlzLnN5bmNDbGFzc2VzRnJvbVJlZ2lvbnModGhpcy5yZWdpb25zKTtcbiAgICB0aGlzLnJlY29tcHV0ZUNsYXNzQ291bnRzKCk7XG5cbiAgICAvLyBUaGUgdXBkYXRlIGV2ZW50IGlzIGp1c3QgYSBjaGFuZ2Ugc2lnbmFsOyByZS1yZWFkIHRoZSByZWdpb25zIGZyb20gdGhlXG4gICAgLy8gdmlzdWFsaXplciByYXRoZXIgdGhhbiBwYXJzaW5nIHdoYXRldmVyIHBheWxvYWQgaXQgY2Fycmllcy5cbiAgICB0aGlzLnJlZ2lvbkFwaVxuICAgICAgLmdldFJlZ2lvblVwZGF0ZUV2ZW50KClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLl91cGRhdGluZ0Zyb21FZGl0b3IpIHJldHVybjtcbiAgICAgICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuYXBwbHlSZWdpb25Db2xvcnModGhpcy5yZWdpb25BcGkuZ2V0QW5ub3RhdGlvblJlZ2lvbnMoKSk7XG4gICAgICAgIC8vIHByZXNlcnZlIHNlbGVjdGlvbiBmb3IgcmVnaW9ucyB0aGF0IHN0aWxsIGV4aXN0IChieSBpZCwgc2luY2UgbmFtZVxuICAgICAgICAvLyBpcyBhIHVzZXItZWRpdGFibGUgZGlzcGxheSBsYWJlbCBhbmQgbWF5IGNvbGxpZGUpXG4gICAgICAgIGNvbnN0IHNlbGVjdGVkSWRzID0gbmV3IFNldCh0aGlzLnNlbGVjdGVkUmVnaW9ucy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICAgICAgdGhpcy5yZWdpb25zID0gdXBkYXRlZDtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFJlZ2lvbnMgPSB1cGRhdGVkLmZpbHRlcigocikgPT4gc2VsZWN0ZWRJZHMuaGFzKHIuaWQpKTtcbiAgICAgICAgdGhpcy5jbGFtcFBhZ2luYXRvckZpcnN0KCk7XG4gICAgICAgIHRoaXMuc3luY0NsYXNzZXNGcm9tUmVnaW9ucyh1cGRhdGVkKTtcbiAgICAgICAgdGhpcy5yZWNvbXB1dGVDbGFzc0NvdW50cygpO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5wZXJzaXN0ZW5jZVxuICAgICAgLmZpbGVFeGlzdHModGhpcy5zYXZlQXNDaGVjayQpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKGV4aXN0cykgPT4ge1xuICAgICAgICB0aGlzLnNhdmVBc0ZpbGVFeGlzdHMgPSBleGlzdHM7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG5cbiAgICAvLyBQaHlzaWNhbCBwaXhlbCBzaXplIG9mIHRoZSBhY3RpdmUgaW1hZ2UgKGZvciByZWdpb24gYXJlYXMgaW4gwrVtwrIvbW3CsikuXG4gICAgdGhpcy5yZWdpb25BcGlcbiAgICAgIC5nZXRJbWFnZU1ldGEoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChtZXRhKSA9PiB7XG4gICAgICAgIHRoaXMubXBwID0gcGlja01wcChtZXRhKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVnaW9uQXBpXG4gICAgICAuZ2V0U2VsZWN0ZWRSZWdpb25zJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNlbGVjdGVkKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLl9zdXBwcmVzc1NlbGVjdGlvblN5bmNUb1Bsb3QpIHJldHVybjtcbiAgICAgICAgLy8gTWFwIHRoZSBjb250cmFjdCdzIHNlbGVjdGVkIHJlZ2lvbnMgdG8gdGhlIGVkaXRvcidzIG93biBpbnN0YW5jZXMgYnkgaWQuXG4gICAgICAgIGNvbnN0IG5leHQgPSBzZWxlY3RlZC5tYXAoKHMpID0+IHRoaXMucmVnaW9ucy5maW5kKChyKSA9PiByLmlkID09PSBzLmlkKSkuZmlsdGVyKChyKTogciBpcyBSZWdpb24gPT4gISFyKTtcbiAgICAgICAgY29uc3Qgc2FtZSA9XG4gICAgICAgICAgbmV4dC5sZW5ndGggPT09IHRoaXMuc2VsZWN0ZWRSZWdpb25zLmxlbmd0aCAmJlxuICAgICAgICAgIG5leHQuZXZlcnkoKHIsIGkpID0+IHIuaWQgPT09IHRoaXMuc2VsZWN0ZWRSZWdpb25zW2ldPy5pZCk7XG4gICAgICAgIGlmICghc2FtZSkgdGhpcy5zZWxlY3RlZFJlZ2lvbnMgPSBuZXh0O1xuICAgICAgICAvLyBTY3JvbGwgdGhlIHBhZ2luYXRvciBzbyB0aGUgbW9zdC1yZWNlbnRseS1zZWxlY3RlZCByb3cgaXMgdmlzaWJsZS5cbiAgICAgICAgaWYgKG5leHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IGxhc3RJZHggPSB0aGlzLnJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSBuZXh0W25leHQubGVuZ3RoIC0gMV0uaWQpO1xuICAgICAgICAgIGlmIChsYXN0SWR4ID49IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHBhZ2VTdGFydCA9IE1hdGguZmxvb3IobGFzdElkeCAvIHRoaXMucGFnaW5hdG9yUm93cykgKiB0aGlzLnBhZ2luYXRvclJvd3M7XG4gICAgICAgICAgICBpZiAocGFnZVN0YXJ0ICE9PSB0aGlzLnBhZ2luYXRvckZpcnN0KSB0aGlzLnBhZ2luYXRvckZpcnN0ID0gcGFnZVN0YXJ0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqIENhbmNlbHMgYSBydW5uaW5nIEdlb0pTT04gc2F2ZSAoYWJvcnRzIGl0cyB1cGxvYWQpIGFuZCBtYXNrIGV4cG9ydCAodGVybWluYXRlc1xuICAgKiAgaXRzIHdvcmtlcik7IHRoZSBBUEkgc3Vic2NyaXB0aW9ucyBlbmQgdGhyb3VnaCBgdGFrZVVudGlsRGVzdHJveWVkYC4gKi9cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fc2F2ZUFzU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMubWFza0pvYj8udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUYWJsZSDihpIgUGxvdDogUHJpbWVORyBmaXJlcyBvblJvd1NlbGVjdC9vblJvd1Vuc2VsZWN0IGFmdGVyIHVwZGF0aW5nXG4gICAqIGBzZWxlY3RlZFJlZ2lvbnNgLiBQdXNoIHRoZSBzZWxlY3RlZCByZWdpb25zIHRvIHRoZSBjb250cmFjdCBieSBpZGVudGl0eSDigJRcbiAgICogdGhlIHBhY2thZ2UgbWFwcyB0aGVtIHRvIGl0cyBpbnRlcm5hbCBpbmRleCBzcGFjZSAod2hpY2ggaW5jbHVkZXMgdGhlXG4gICAqIGludGVuc2l0eS1wcm9maWxlIGxpbmVzIHRoZSBlZGl0b3IgbmV2ZXIgc2VlcykuXG4gICAqL1xuICBwcm90ZWN0ZWQgb25TZWxlY3Rpb25DaGFuZ2VkKCkge1xuICAgIHRoaXMuX3N1cHByZXNzU2VsZWN0aW9uU3luY1RvUGxvdCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVnaW9uQXBpLnNldFNlbGVjdGVkUmVnaW9ucyh0aGlzLnNlbGVjdGVkUmVnaW9ucyA/PyBbXSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX3N1cHByZXNzU2VsZWN0aW9uU3luY1RvUGxvdCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSb3dzIGZvciByZWdpb25zIGNvbWluZyBmcm9tIHRoZSB2aXN1YWxpemVyOiBuZXV0cmFsIGBSZWdpb25gcyB3aXRoIGJvdW5kcyxcbiAgICogY29sb3VyIGFuZCBsYWJlbCBhbHJlYWR5IHBvcHVsYXRlZC4gQSByZWdpb24gd2l0aG91dCBhIGNvbG91ciBpcyBzaG93biB3aXRoXG4gICAqIGl0cyBjbGFzc2lmaWNhdGlvbiBjb2xvdXIgKG9yIHRoZSBkZWZhdWx0IHNoYXBlIGNvbG91cikg4oCUIGFzIGEgY29weTogdGhlXG4gICAqIHN0b3JlJ3MgaW5zdGFuY2VzIGFyZSBzaGFyZWQgd2l0aCBpdHMgdW5kbyBoaXN0b3J5IGFuZCBtdXN0IG5vdCBiZSBjaGFuZ2VkXG4gICAqIGluIHBsYWNlIChSVC0xKS5cbiAgICovXG4gIHByaXZhdGUgYXBwbHlSZWdpb25Db2xvcnMocmVnaW9uczogUmVnaW9uW10pOiBSZWdpb25bXSB7XG4gICAgY29uc3QgY2xhc3NDb2xvcnMgPSB0aGlzLnJlZ2lvbkFwaS5nZXRDbGFzc2lmaWNhdGlvbkNvbG9ycygpO1xuICAgIHJldHVybiByZWdpb25zLm1hcCgocmVnaW9uKSA9PlxuICAgICAgcmVnaW9uLmNvbG9yXG4gICAgICAgID8gcmVnaW9uXG4gICAgICAgIDogd2l0aFJlZ2lvblBhdGNoKHJlZ2lvbiwgeyBjb2xvcjogY2xhc3NDb2xvcnMuZ2V0KHJlZ2lvbi5sYWJlbCA/PyAnJykgfHwgdGhpcy5zaGFwZUNvbG9yIH0pLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGVkaXRvcidzIG9uZSB3cml0ZSBwYXRoIChSVC0xKTogbWFrZSBgbmV4dGAgdGhlIHRhYmxlJ3Mgcm93cyBhbmQgY29tbWl0XG4gICAqIHRoZW0gdG8gdGhlIHN0b3JlIOKAlCBsaXZlLCBhcyBvbmUgdW5kb2FibGUgc3RlcCAoaXNSZWdpb25TYXZlT249dHJ1ZTsgdGhlXG4gICAqIHJvdXRlciBrZWVwcyB0aGUgaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMpLiBSb3dzIGFyZSB0aGUgc3RvcmUncyBpbnN0YW5jZXMsXG4gICAqIHNvIGFuIGVkaXQgcGFzc2VzIGNvcGllcyAoe0BsaW5rIHBhdGNoUmVnaW9uc30pLCBuZXZlciBjaGFuZ2VkIHJvd3MuIFRoZVxuICAgKiByZXN1bHRpbmcgcmVnaW9uLXVwZGF0ZSBldmVudCBpcyBpZ25vcmVkIChgX3VwZGF0aW5nRnJvbUVkaXRvcmApLCBzbyB0aGVcbiAgICogY2xhc3MgbGlzdCBhbmQgY291bnRzIGFyZSByZWZyZXNoZWQgaGVyZSAoYSB0eXBlZCBjbGFzcyBpcyBhZGRlZDsgaml0LXVpIzcwKS5cbiAgICovXG4gIHByaXZhdGUgY29tbWl0KG5leHQ6IFJlZ2lvbltdID0gdGhpcy5yZWdpb25zKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpb25zID0gbmV4dDtcbiAgICB0aGlzLl91cGRhdGluZ0Zyb21FZGl0b3IgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnJlZ2lvbkFwaS5zZXRBbm5vdGF0aW9uUmVnaW9ucyhuZXh0LCB0aGlzLnNob3dTaGFwZUxhYmVsLCB0cnVlLCB0aGlzLmZpbGxDb2xvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX3VwZGF0aW5nRnJvbUVkaXRvciA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnN5bmNDbGFzc2VzRnJvbVJlZ2lvbnMobmV4dCk7XG4gICAgdGhpcy5yZWNvbXB1dGVDbGFzc0NvdW50cygpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcHktb24td3JpdGUgZWRpdCAocmV2aWV3IFJULTEpLiBUaGUgZWRpdG9yJ3Mgcm93cyBhcmUgdGhlIHJlZ2lvbiBzdG9yZSdzXG4gICAqIGxpdmUgaW5zdGFuY2VzLCBhbmQgdGhlIHN0b3JlIHRha2VzIGl0cyB1bmRvIHNuYXBzaG90IG9ubHkgd2hlbiB0aGUgZWRpdCBpc1xuICAgKiBjb21taXR0ZWQg4oCUIHNvIGFuIGVkaXQgbXVzdCByZXBsYWNlIGEgcmVnaW9uIHdpdGggYSBwYXRjaGVkIGNvcHkgKGFuZCBhbnlcbiAgICogYm91bmRzIGl0IGNoYW5nZXMgd2l0aCBuZXcgYm91bmRzKSwgbmV2ZXIgbXV0YXRlIHRoZSBpbnN0YW5jZSB0aGUgc3RvcmVcbiAgICogaG9sZHMuIFJldHVybnMgdGhlIGNvcGllcyBieSBvcmlnaW5hbDsgdGhlIHNlbGVjdGlvbiBhbmQgYW4gb3BlbiBsYWJlbCBlZGl0XG4gICAqIGZvbGxvdyB0aGVtLlxuICAgKi9cbiAgcHJpdmF0ZSBwYXRjaFJlZ2lvbnMocGF0Y2hGb3I6IChyOiBSZWdpb24pID0+IFBhcnRpYWw8UmVnaW9uPiB8IG51bGwpOiBNYXA8UmVnaW9uLCBSZWdpb24+IHtcbiAgICBjb25zdCBjb3BpZXMgPSBuZXcgTWFwPFJlZ2lvbiwgUmVnaW9uPigpO1xuICAgIHRoaXMucmVnaW9ucyA9IHRoaXMucmVnaW9ucy5tYXAoKHIpID0+IHtcbiAgICAgIGNvbnN0IHBhdGNoID0gcGF0Y2hGb3Iocik7XG4gICAgICBpZiAoIXBhdGNoKSByZXR1cm4gcjtcbiAgICAgIGNvbnN0IGNvcHkgPSB3aXRoUmVnaW9uUGF0Y2gociwgcGF0Y2gpO1xuICAgICAgY29waWVzLnNldChyLCBjb3B5KTtcbiAgICAgIHJldHVybiBjb3B5O1xuICAgIH0pO1xuICAgIGlmIChjb3BpZXMuc2l6ZSkge1xuICAgICAgdGhpcy5zZWxlY3RlZFJlZ2lvbnMgPSAodGhpcy5zZWxlY3RlZFJlZ2lvbnMgPz8gW10pLm1hcCgocikgPT4gY29waWVzLmdldChyKSA/PyByKTtcbiAgICAgIGlmIChbLi4uY29waWVzLmtleXMoKV0uc29tZSgocikgPT4gdGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zLmhhcyhyKSkpIHtcbiAgICAgICAgdGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zID0gbmV3IE1hcChbLi4udGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zXS5tYXAoKFtyLCBkXSkgPT4gW2NvcGllcy5nZXQocikgPz8gciwgZF0pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvcGllcztcbiAgfVxuXG4gIC8qKiBTZXQgb25lIHJlZ2lvbidzIG91dGxpbmUgY29sb3VyIChhbiBleHBsaWNpdCBvdmVycmlkZSkgYW5kIGNvbW1pdCBsaXZlLiAqL1xuICBwcm90ZWN0ZWQgY2hhbmdlUmVnaW9uQ29sb3IocmVnaW9uOiBSZWdpb24sIGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIWNvbG9yIHx8IHJlZ2lvbi5jb2xvciA9PT0gY29sb3IpIHJldHVybjtcbiAgICAvLyBjb2xvck92ZXJyaWRkZW46IGV4cGxpY2l0IHBlci1yZWdpb24gY29sb3VyIOKAlCBwcmVzZXJ2ZSBpdCBhZ2FpbnN0IHByZXNldCAocmUpYXBwbHkgKGppdC11aSM3MClcbiAgICB0aGlzLnBhdGNoUmVnaW9ucygocikgPT4gKHIgPT09IHJlZ2lvbiA/IHsgY29sb3IsIGNvbG9yT3ZlcnJpZGRlbjogdHJ1ZSB9IDogbnVsbCkpO1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogQWZ0ZXIgYSBsYWJlbCBlZGl0IG9uIGByZWdpb25gOiBnaXZlIGV2ZXJ5IGxhYmVsbGVkIHJvdyB3aXRob3V0IGEgY29sb3VyIGl0c1xuICAgKiBjbGFzcyBjb2xvdXIgKHByZXNldCBvciBmYWxsYmFjaywgYXMgdGhlIHN0b3JlIHdpbGwpLCBhbmQgY29tbWl0IHdoZW5cbiAgICogYGNvbW1pdGAgaXMgc2V0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGxhYmVsUmVnaW9uVXBkYXRlKHJlZ2lvbjogUmVnaW9uLCBjb21taXQgPSBmYWxzZSkge1xuICAgIHRoaXMuZmlsbENsYXNzQ29sb3JzKCk7XG4gICAgaWYgKGNvbW1pdCkgdGhpcy5jb21taXQoKTtcbiAgfVxuXG4gIC8qKiBMYWJlbGxlZCByb3dzIHdpdGhvdXQgYSBjb2xvdXIgZ2V0IHRoZWlyIGNsYXNzIGNvbG91ciAoY29waWVzKS4gKi9cbiAgcHJpdmF0ZSBmaWxsQ2xhc3NDb2xvcnMoKTogdm9pZCB7XG4gICAgdGhpcy5wYXRjaFJlZ2lvbnMoKHIpID0+ICghci5jb2xvciAmJiByLmxhYmVsID8geyBjb2xvcjogdGhpcy5jb2xvckZvck5hbWUoci5sYWJlbCkgfSA6IG51bGwpKTtcbiAgfVxuXG4gIC8qKiBUaGUgY3VycmVudCBwYWdlIG9mIHRoZSB0YWJsZS4gTWVtb2l6ZWQgb24gKHJlZ2lvbnMsIGZpcnN0LCByb3dzKSwgc29cbiAgICogIGNoYW5nZSBkZXRlY3Rpb24gZG9lc24ndCBoYW5kIHAtdGFibGUgYSBuZXcgYXJyYXkgZXZlcnkgdGljayAoUlQtMjApLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBhZ2VkUmVnaW9ucygpOiBSZWdpb25bXSB7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5fcGFnZUtleTtcbiAgICBpZiAoa2V5LnJlZ2lvbnMgIT09IHRoaXMucmVnaW9ucyB8fCBrZXkuZmlyc3QgIT09IHRoaXMucGFnaW5hdG9yRmlyc3QgfHwga2V5LnJvd3MgIT09IHRoaXMucGFnaW5hdG9yUm93cykge1xuICAgICAgdGhpcy5fcGFnZUtleSA9IHsgcmVnaW9uczogdGhpcy5yZWdpb25zLCBmaXJzdDogdGhpcy5wYWdpbmF0b3JGaXJzdCwgcm93czogdGhpcy5wYWdpbmF0b3JSb3dzIH07XG4gICAgICB0aGlzLl9wYWdlID0gdGhpcy5yZWdpb25zLnNsaWNlKHRoaXMucGFnaW5hdG9yRmlyc3QsIHRoaXMucGFnaW5hdG9yRmlyc3QgKyB0aGlzLnBhZ2luYXRvclJvd3MpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcGFnZTtcbiAgfVxuICBwcml2YXRlIF9wYWdlS2V5OiB7IHJlZ2lvbnM/OiBSZWdpb25bXTsgZmlyc3Q/OiBudW1iZXI7IHJvd3M/OiBudW1iZXIgfSA9IHt9O1xuICBwcml2YXRlIF9wYWdlOiBSZWdpb25bXSA9IFtdO1xuXG4gIHByb3RlY3RlZCBvblBhZ2VDaGFuZ2UoZXZlbnQ6IHsgZmlyc3Q/OiBudW1iZXI7IHJvd3M/OiBudW1iZXIgfSkge1xuICAgIHRoaXMucGFnaW5hdG9yRmlyc3QgPSBldmVudC5maXJzdCA/PyAwO1xuICAgIHRoaXMucGFnaW5hdG9yUm93cyA9IGV2ZW50LnJvd3MgPz8gdGhpcy5wYWdpbmF0b3JSb3dzO1xuICB9XG5cbiAgLyoqIFNlbGVjdCBldmVyeSByZWdpb24gaW4gdGhlIHRhYmxlIChhbmQgaGlnaGxpZ2h0IHRoZW0gb24gdGhlIGRpYWdyYW0pLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0QWxsUmVnaW9ucygpIHtcbiAgICB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IFsuLi50aGlzLnJlZ2lvbnNdO1xuICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZGVsZXRlU2VsZWN0ZWRSZWdpb25zKCkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkUmVnaW9ucyAmJiB0aGlzLnNlbGVjdGVkUmVnaW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBGaWx0ZXIgYnkgaWQg4oCUIG9iamVjdCBpZGVudGl0eSBpc24ndCByZWxpYWJsZSBhY3Jvc3MgcmUtcGFyc2VzLFxuICAgICAgLy8gYW5kIG5hbWUgaXMgYSB1c2VyLWVkaXRhYmxlIGxhYmVsIHRoYXQgbWF5IGNvbGxpZGUuXG4gICAgICBjb25zdCByZW1vdmVkID0gbmV3IFNldCh0aGlzLnNlbGVjdGVkUmVnaW9ucy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRSZWdpb25zID0gW107XG4gICAgICB0aGlzLmNvbW1pdCh0aGlzLnJlZ2lvbnMuZmlsdGVyKChyKSA9PiAhcmVtb3ZlZC5oYXMoci5pZCkpKTtcbiAgICAgIHRoaXMuY2xhbXBQYWdpbmF0b3JGaXJzdCgpO1xuICAgICAgLy8gU3luYyB0aGUgY2xlYXJlZCBzZWxlY3Rpb24gd2l0aCB0aGUgcGxvdCdzIGhpZ2hsaWdodCBzdGF0ZS5cbiAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNsZWFyQWxsUmVnaW9ucygpIHtcbiAgICB0aGlzLmNvbmZpcm1hdGlvblNlcnZpY2UuY29uZmlybSh7XG4gICAgICBrZXk6ICdwb3NpdGlvbkRpYWxvZycsXG4gICAgICBtZXNzYWdlOiAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSBhbGwgcmVnaW9ucz8nLFxuICAgICAgYWNjZXB0OiAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRSZWdpb25zID0gW107XG4gICAgICAgIHRoaXMucGFnaW5hdG9yRmlyc3QgPSAwO1xuICAgICAgICB0aGlzLmNvbW1pdChbXSk7XG4gICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGRlbGV0ZVJlZ2lvbihzaGFwZUlkeDogbnVtYmVyKSB7XG4gICAgY29uc3QgcmVtb3ZlZCA9IHRoaXMucmVnaW9uc1tzaGFwZUlkeF07XG4gICAgaWYgKHJlbW92ZWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRSZWdpb25zID0gdGhpcy5zZWxlY3RlZFJlZ2lvbnMuZmlsdGVyKChyKSA9PiByLmlkICE9PSByZW1vdmVkLmlkKTtcbiAgICB9XG4gICAgdGhpcy5jb21taXQodGhpcy5yZWdpb25zLmZpbHRlcigoXywgaSkgPT4gaSAhPT0gc2hhcGVJZHgpKTtcbiAgICB0aGlzLmNsYW1wUGFnaW5hdG9yRmlyc3QoKTtcbiAgICAvLyBSZS1lbWl0IHRoZSAocG9zc2libHkgdHJpbW1lZCkgc2VsZWN0aW9uIHNvIHRoZSBwbG90J3MgaGlnaGxpZ2h0IHN0YXlzXG4gICAgLy8gaW4gc3luYyB3aXRoIHdoYXQncyBzdGlsbCBpbiB0aGUgdGFibGUuXG4gICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xhbXBQYWdpbmF0b3JGaXJzdCgpIHtcbiAgICBjb25zdCBtYXhGaXJzdCA9IE1hdGgubWF4KDAsIE1hdGguZmxvb3IoKHRoaXMucmVnaW9ucy5sZW5ndGggLSAxKSAvIHRoaXMucGFnaW5hdG9yUm93cykgKiB0aGlzLnBhZ2luYXRvclJvd3MpO1xuICAgIGlmICh0aGlzLnBhZ2luYXRvckZpcnN0ID4gbWF4Rmlyc3QpIHtcbiAgICAgIHRoaXMucGFnaW5hdG9yRmlyc3QgPSBtYXhGaXJzdDtcbiAgICB9XG4gIH1cbiAgcHJvdGVjdGVkIGNoYW5nZVNob3dTaGFwZUxhYmVsKHNob3dMYWJlbDogYm9vbGVhbikge1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNFZGl0aW5nTGFiZWwocmVnaW9uOiBSZWdpb24pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zLmhhcyhyZWdpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHN0YXJ0RWRpdExhYmVsKHJlZ2lvbjogUmVnaW9uLCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpOyAvLyBkb24ndCB0b2dnbGUgcm93IHNlbGVjdGlvblxuICAgIC8vIEEgbmV3IG1hcCBwZXIgc3RhcnQvc3RvcCwgc28gdGhlIE9uUHVzaCB0YWJsZSBzZWVzIHRoZSBjaGFuZ2UuXG4gICAgdGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zID0gbmV3IE1hcCh0aGlzLmVkaXRpbmdMYWJlbFJlZ2lvbnMpLnNldChyZWdpb24sIHJlZ2lvbi5sYWJlbCA/PyAnJyk7XG4gIH1cblxuICAvKiogVGhlIGxhYmVsIHR5cGVkIHNvIGZhciBmb3IgYSByb3cgaW4gZWRpdCBtb2RlIChubyByZS1yZW5kZXIgbmVlZGVkKS4gKi9cbiAgcHJvdGVjdGVkIHNldExhYmVsRHJhZnQocmVnaW9uOiBSZWdpb24sIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zLmhhcyhyZWdpb24pKSB0aGlzLmVkaXRpbmdMYWJlbFJlZ2lvbnMuc2V0KHJlZ2lvbiwgdmFsdWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHN0b3BFZGl0TGFiZWwocmVnaW9uOiBSZWdpb24sIGNvbW1pdDogYm9vbGVhbiwgZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50Py5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBkcmFmdCA9IHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucy5nZXQocmVnaW9uKTtcbiAgICBpZiAodGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zLmhhcyhyZWdpb24pKSB7XG4gICAgICBjb25zdCBuZXh0ID0gbmV3IE1hcCh0aGlzLmVkaXRpbmdMYWJlbFJlZ2lvbnMpO1xuICAgICAgbmV4dC5kZWxldGUocmVnaW9uKTtcbiAgICAgIHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucyA9IG5leHQ7XG4gICAgfVxuICAgIGlmIChjb21taXQpIHtcbiAgICAgIC8vIEEgY2hhbmdlZCBsYWJlbCBjb21taXRzIGFzIGEgcmVwbGFjZW1lbnQgcmVnaW9uLCBzbyBpdCBpcyB1bmRvYWJsZSAoUlQtMSkuXG4gICAgICBjb25zdCBlZGl0ZWQgPVxuICAgICAgICBkcmFmdCAhPT0gdW5kZWZpbmVkICYmIGRyYWZ0ICE9PSByZWdpb24ubGFiZWxcbiAgICAgICAgICA/ICh0aGlzLnBhdGNoUmVnaW9ucygocikgPT4gKHIgPT09IHJlZ2lvbiA/IHsgbGFiZWw6IGRyYWZ0IH0gOiBudWxsKSkuZ2V0KHJlZ2lvbikgPz8gcmVnaW9uKVxuICAgICAgICAgIDogcmVnaW9uO1xuICAgICAgdGhpcy5sYWJlbFJlZ2lvblVwZGF0ZShlZGl0ZWQsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZWdpb24gYXJlYSBmb3IgZGlzcGxheSAowrVtwrIvbW3CsiB3aGVuIHRoZSBpbWFnZSBpcyBzY2FsZWQsIGVsc2UgcHjCsik7XG4gICAqICBlbXB0eSBmb3IgYSBkZWdlbmVyYXRlIHJlZ2lvbi4gU2VlIGByZWdpb24tbWV0cmljc2AuICovXG4gIHByb3RlY3RlZCByZWdpb25BcmVhKHJlZ2lvbjogUmVnaW9uKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZm9ybWF0QXJlYShyZWdpb25BcmVhUHgocmVnaW9uKSwgdGhpcy5tcHApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHJvdW5kcyBhbGwgdGhlIHJlY3RhbmdsZSByZWdpb25zIGxlbmd0aHMgdG8gbXVsdGlwbGUgb2YgNTEyXG4gICAqL1xuICBwcm90ZWN0ZWQgcm91bmRSZWN0YW5nbGVMZW5ndGhzKCkge1xuICAgIHRoaXMucGF0Y2hSZWdpb25zKChyZWdpb24pID0+IHtcbiAgICAgIGNvbnN0IHJlY3QgPSByZWdpb24uYm91bmRzO1xuICAgICAgaWYgKCEocmVjdCBpbnN0YW5jZW9mIFJlY3RhbmdsZSkpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYm91bmRzOiBPYmplY3QuYXNzaWduKG5ldyBSZWN0YW5nbGUoKSwgcmVjdCwge1xuICAgICAgICAgIGhlaWdodDogTWF0aC5yb3VuZChyZWN0LmhlaWdodCAvIDUxMikgKiA1MTIsXG4gICAgICAgICAgd2lkdGg6IE1hdGgucm91bmQocmVjdC53aWR0aCAvIDUxMikgKiA1MTIsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dIZWxwKCkge1xuICAgIHRoaXMuZGlzcGxheUhlbHBEaWFsb2cgPSB0cnVlO1xuICB9XG5cbiAgLyoqIE9wZW4gdGhlIGNvbG91ciBkaWFsb2cgZm9yIHRoZSBjdXJyZW50bHktc2VsZWN0ZWQgcmVnaW9uKHMpLCBidWlsZGluZyBvbmVcbiAgICogIGNvbG91ciBwaWNrZXIgcGVyIHVuaXF1ZSBjbGFzcyBpbiB0aGUgc2VsZWN0aW9uLiBFYWNoIHBpY2tlciBpcyBzZWVkZWQgd2l0aFxuICAgKiAgdGhlIGZpcnN0IHNlbGVjdGVkIHJlZ2lvbiBvZiB0aGF0IGNsYXNzJ3MgY29sb3VyIChlbHNlIHRoZSBjbGFzcyBjb2xvdXIpLiAqL1xuICBwcm90ZWN0ZWQgb3BlbkNvbG9yRGlhbG9nKCkge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZFJlZ2lvbnM/Lmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IHNlZWRCeUxhYmVsID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHJlZ2lvbiBvZiB0aGlzLnNlbGVjdGVkUmVnaW9ucykge1xuICAgICAgY29uc3QgbGFiZWwgPSByZWdpb24ubGFiZWw/LnRyaW0oKSA/PyAnJztcbiAgICAgIGlmIChzZWVkQnlMYWJlbC5oYXMobGFiZWwpKSBjb250aW51ZTtcbiAgICAgIHNlZWRCeUxhYmVsLnNldChsYWJlbCwgcmVnaW9uLmNvbG9yID8/IChsYWJlbCA/IHRoaXMuY29sb3JGb3JOYW1lKGxhYmVsKSA6IHRoaXMuc2hhcGVDb2xvcikpO1xuICAgIH1cbiAgICB0aGlzLmNsYXNzQ29sb3JFZGl0cyA9IFsuLi5zZWVkQnlMYWJlbF0ubWFwKChbbGFiZWwsIGNvbG9yXSkgPT4gKHsgbGFiZWwsIGNvbG9yIH0pKTtcbiAgICB0aGlzLnNob3dDb2xvckRpYWxvZyA9IHRydWU7XG4gIH1cblxuICAvKiogQXBwbHkgZWFjaCBjbGFzcydzIGNob3NlbiBjb2xvdXIgdG8gdGhlIHNlbGVjdGVkIHJlZ2lvbnMgb2YgdGhhdCBjbGFzcyAoYW5cbiAgICogIGV4cGxpY2l0IG92ZXJyaWRlKSBhbmQgY29tbWl0IGxpdmUuICovXG4gIHByb3RlY3RlZCBhcHBseUNvbG9yVG9TZWxlY3RlZChlZGl0czogQ2xhc3NDb2xvckVkaXRbXSA9IHRoaXMuY2xhc3NDb2xvckVkaXRzKSB7XG4gICAgY29uc3QgY29sb3JCeUxhYmVsID0gbmV3IE1hcChlZGl0cy5tYXAoKGUpID0+IFtlLmxhYmVsLCBlLmNvbG9yXSkpO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gbmV3IFNldCh0aGlzLnNlbGVjdGVkUmVnaW9ucyA/PyBbXSk7XG4gICAgdGhpcy5wYXRjaFJlZ2lvbnMoKHJlZ2lvbikgPT4ge1xuICAgICAgaWYgKCFzZWxlY3RlZC5oYXMocmVnaW9uKSkgcmV0dXJuIG51bGw7XG4gICAgICBjb25zdCBsYWJlbCA9IHJlZ2lvbi5sYWJlbD8udHJpbSgpID8/ICcnO1xuICAgICAgY29uc3QgY29sb3IgPSBjb2xvckJ5TGFiZWwuZ2V0KGxhYmVsKTtcbiAgICAgIGlmICghY29sb3IpIHJldHVybiBudWxsO1xuICAgICAgLy8gZXhwbGljaXQgY29sb3VyIOKAlCBwcmVzZXJ2ZSBhZ2FpbnN0IHByZXNldCAocmUpYXBwbHkgKGppdC11aSM3MClcbiAgICAgIHJldHVybiB7IGNvbG9yLCBjb2xvck92ZXJyaWRkZW46IHRydWUgfTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICAgIHRoaXMuc2hvd0NvbG9yRGlhbG9nID0gZmFsc2U7XG4gIH1cblxuICAvLyDilIDilIAgYW5ub3RhdGlvbi1jbGFzcyBwcmVzZXRzIChqaXQtdWkjNzApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBSZXNvbHZlIHRoZSBkaXNwbGF5IGNvbG91ciBmb3IgYSBjbGFzcyBuYW1lIChwcmVzZXQgY29sb3VyIG9yIGRldGVybWluaXN0aWMgZmFsbGJhY2spLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JGb3JOYW1lKG5hbWU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBuYW1lID8gY29sb3JGb3JMYWJlbChuYW1lLCB0aGlzLnByZXNldFNldCkgOiB0aGlzLnNoYXBlQ29sb3I7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlIGV2ZXJ5IGNsYXNzIGxhYmVsIHByZXNlbnQgaW4gdGhlIGxvYWRlZCByZWdpb25zIGV4aXN0cyBpbiB0aGUgcHJlc2V0XG4gICAqIGxpc3QsIGF1dG8tYWRkaW5nIGFueSB0aGF0IGFyZSBtaXNzaW5nICh1c2luZyB0aGUgcmVnaW9uJ3MgYWxyZWFkeS1yZXNvbHZlZFxuICAgKiBjb2xvdXIpLiBUaGlzIG1ha2VzIGNsYXNzZXMgY2FycmllZCBpbiBhIGxvYWRlZC9pbXBvcnRlZCBHZW9KU09OIHNob3cgdXAgYXNcbiAgICogY2hpcHMgKyBDbGFzcy1kcm9wZG93biBvcHRpb25zIChhIHAtZHJvcGRvd24gY2FuJ3QgZGlzcGxheSBhIHZhbHVlIHRoYXQgaXNuJ3RcbiAgICogYW4gb3B0aW9uKSBhbmQgbGV0cyB0aGUgdXNlciBtYW5hZ2UgdGhlbS4gVGhlIHBsYWNlaG9sZGVyICdsZWdlbmQnIGFuZCBlbXB0eVxuICAgKiBsYWJlbHMgYXJlIGlnbm9yZWQuIChqaXQtdWkjNzApXG4gICAqL1xuICBwcml2YXRlIHN5bmNDbGFzc2VzRnJvbVJlZ2lvbnMocmVnaW9uczogUmVnaW9uW10pOiB2b2lkIHtcbiAgICBjb25zdCBrZXlPZiA9IChsOiBzdHJpbmcpID0+IHByZXNldEtleSh0aGlzLnByZXNldFNldCwgbCk7XG4gICAgY29uc3Qga25vd24gPSBuZXcgU2V0KHRoaXMucHJlc2V0U2V0LmNsYXNzZXMubWFwKChjKSA9PiBrZXlPZihjLm5hbWUpKSk7XG4gICAgY29uc3QgYWRkZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHIgb2YgcmVnaW9ucykge1xuICAgICAgY29uc3QgbGFiZWwgPSByLmxhYmVsPy50cmltKCk7XG4gICAgICBpZiAoIWxhYmVsIHx8IGxhYmVsID09PSAnbGVnZW5kJykgY29udGludWU7XG4gICAgICBjb25zdCBrID0ga2V5T2YobGFiZWwpO1xuICAgICAgaWYgKGtub3duLmhhcyhrKSB8fCBhZGRlZC5oYXMoaykpIGNvbnRpbnVlO1xuICAgICAgYWRkZWQuYWRkKGspO1xuICAgICAgdGhpcy5yZWdpb25BcGkudXBzZXJ0Q2xhc3Moe1xuICAgICAgICBuYW1lOiBsYWJlbCxcbiAgICAgICAgY29sb3I6IHIuY29sb3IgfHwgY29sb3JGb3JMYWJlbChsYWJlbCwgdGhpcy5wcmVzZXRTZXQpLFxuICAgICAgICBzb3VyY2U6ICdhdXRvJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBEb2NrZWQgQ2xhc3NlcyBwYW5lbCAoaml0LXVpIzcwKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgcGVyLWNsYXNzIHJlZ2lvbiBjb3VudHMgc2hvd24gaW4gdGhlIHBhbmVsLiAqL1xuICBwcml2YXRlIHJlY29tcHV0ZUNsYXNzQ291bnRzKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgZm9yIChjb25zdCByIG9mIHRoaXMucmVnaW9ucykge1xuICAgICAgaWYgKCFyLmxhYmVsKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IGsgPSBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIHIubGFiZWwpO1xuICAgICAgY291bnRzLnNldChrLCAoY291bnRzLmdldChrKSA/PyAwKSArIDEpO1xuICAgIH1cbiAgICB0aGlzLmNsYXNzQ291bnRzID0gY291bnRzO1xuICAgIHRoaXMudXBkYXRlRGlzcGxheUNsYXNzZXMoKTtcbiAgfVxuXG4gIC8qKiBSZWJ1aWxkIHRoZSBwYW5lbCdzIGRpc3BsYXkgb3JkZXIg4oCUIG1vc3QtdXNlZCBjbGFzc2VzIGZpcnN0LCB0aGVuIGJ5IG5hbWUuICovXG4gIHByaXZhdGUgdXBkYXRlRGlzcGxheUNsYXNzZXMoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNwbGF5Q2xhc3NlcyA9IFsuLi50aGlzLnByZXNldFNldC5jbGFzc2VzXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICBjb25zdCBkID0gdGhpcy5jbGFzc0NvdW50KGIubmFtZSkgLSB0aGlzLmNsYXNzQ291bnQoYS5uYW1lKTtcbiAgICAgIHJldHVybiBkICE9PSAwID8gZCA6IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiogTnVtYmVyIG9mIHJlZ2lvbnMgY3VycmVudGx5IHVzaW5nIGEgY2xhc3MgKGtleWVkIGJ5IHRoZSBhY3RpdmUgbWF0Y2ggbW9kZSkuICovXG4gIHByb3RlY3RlZCBjbGFzc0NvdW50KG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY2xhc3NDb3VudHMuZ2V0KHByZXNldEtleSh0aGlzLnByZXNldFNldCwgbmFtZSkpID8/IDA7XG4gIH1cblxuICAvKiogUmVjb2xvdXIgYSBjbGFzcyBmcm9tIGl0cyBwYW5lbCBzd2F0Y2ggYW5kIHJlcGFpbnQgaXRzIChub24tb3ZlcnJpZGRlbikgcmVnaW9ucy4gKi9cbiAgcHJvdGVjdGVkIHNldENsYXNzQ29sb3IobmFtZTogc3RyaW5nLCBjb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFjb2xvcikgcmV0dXJuO1xuICAgIHRoaXMucmVnaW9uQXBpLnNldENsYXNzaWZpY2F0aW9uQ29sb3IobmFtZSwgY29sb3IpO1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICAvKiogUmVtb3ZlIGEgY2xhc3MuIEFueSByZWdpb25zIHN0aWxsIHVzaW5nIGl0IGZhbGwgYmFjayB0byB0aGUgZGVmYXVsdFxuICAgKiAgXCJSZWdpb25cIiBjbGFzcywgc28gdGhleSBhcmVuJ3Qgb3JwaGFuZWQgKGFuZCB0aGUgY2xhc3MgaXNuJ3QgaW1tZWRpYXRlbHlcbiAgICogIHJlLWFkZGVkIGZyb20gaXRzIHJlZ2lvbnMgYnkgc3luY0NsYXNzZXNGcm9tUmVnaW9ucykuICovXG4gIHByb3RlY3RlZCBkZWxldGVDbGFzcyhuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnJlYXNzaWduUmVnaW9uc1RvRGVmYXVsdENsYXNzKFtuYW1lXSk7XG4gICAgdGhpcy5yZWdpb25BcGkucmVtb3ZlQ2xhc3MobmFtZSk7XG4gICAgaWYgKHRoaXMuYWN0aXZlQ2xhc3MgPT09IG5hbWUpIHRoaXMuYWN0aXZlQ2xhc3MgPSBudWxsO1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICAvKiogUmVnaW9ucyBsYWJlbGxlZCB3aXRoIGFueSBvZiBgcmVtb3ZlZE5hbWVzYCByZXZlcnQgdG8gdGhlIGRlZmF1bHRcbiAgICogIHtAbGluayBkZWZhdWx0Q2xhc3NOYW1lfSAoXCJSZWdpb25cIik6IGl0cyBjbGFzcyBjb2xvdXIsIG92ZXJyaWRlIGNsZWFyZWQuXG4gICAqICBTa2lwcyB0aGUgZGVmYXVsdCBpdHNlbGYgc28gZGVsZXRpbmcgXCJSZWdpb25cIiBjYW4ndCBzZWxmLXJlYXNzaWduLiAoaml0LXVpIzcwKSAqL1xuICBwcml2YXRlIHJlYXNzaWduUmVnaW9uc1RvRGVmYXVsdENsYXNzKHJlbW92ZWROYW1lczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBjb25zdCBrZXlPZiA9IChzOiBzdHJpbmcpID0+IHByZXNldEtleSh0aGlzLnByZXNldFNldCwgcyk7XG4gICAgY29uc3QgcmVtb3ZlZCA9IG5ldyBTZXQocmVtb3ZlZE5hbWVzLm1hcChrZXlPZikpO1xuICAgIHJlbW92ZWQuZGVsZXRlKGtleU9mKHRoaXMuZGVmYXVsdENsYXNzTmFtZSkpO1xuICAgIGlmICghcmVtb3ZlZC5zaXplKSByZXR1cm47XG4gICAgY29uc3QgY29sb3IgPSBjb2xvckZvckxhYmVsKHRoaXMuZGVmYXVsdENsYXNzTmFtZSwgdGhpcy5wcmVzZXRTZXQpO1xuICAgIHRoaXMucGF0Y2hSZWdpb25zKChyKSA9PlxuICAgICAgci5sYWJlbCAmJiByZW1vdmVkLmhhcyhrZXlPZihyLmxhYmVsKSlcbiAgICAgICAgPyB7IGxhYmVsOiB0aGlzLmRlZmF1bHRDbGFzc05hbWUsIGNvbG9yT3ZlcnJpZGRlbjogZmFsc2UsIGNvbG9yIH1cbiAgICAgICAgOiBudWxsLFxuICAgICk7XG4gIH1cblxuICAvKiogU3RhbXAgYSBjbGFzcyAoYW5kIGl0cyBwcmVzZXQvZmFsbGJhY2sgY29sb3VyKSBvbnRvIG9uZSByZWdpb24gZnJvbSB0aGUgQ2xhc3NcbiAgICogIGRyb3Bkb3duOyBjaG9vc2luZyBhIGNsYXNzIG9wdHMgdGhlIHJlZ2lvbiBiYWNrIGludG8gdGhlIHByZXNldCBjb2xvdXIuICovXG4gIHByb3RlY3RlZCBhcHBseVByZXNldFRvUmVnaW9uKHJlZ2lvbjogUmVnaW9uLCBjbGFzc05hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG5hbWUgPSAoY2xhc3NOYW1lID8/ICcnKS50cmltKCk7XG4gICAgY29uc3QgcGF0Y2g6IFBhcnRpYWw8UmVnaW9uPiA9IHsgbGFiZWw6IG5hbWUsIGNvbG9yT3ZlcnJpZGRlbjogZmFsc2UgfTtcbiAgICBpZiAobmFtZSkgcGF0Y2guY29sb3IgPSBjb2xvckZvckxhYmVsKG5hbWUsIHRoaXMucHJlc2V0U2V0KTtcbiAgICB0aGlzLnBhdGNoUmVnaW9ucygocikgPT4gKHIgPT09IHJlZ2lvbiA/IHBhdGNoIDogbnVsbCkpO1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICAvKiogTWFrZSBhIGNsYXNzIGFjdGl2ZSAodXNlZCBmb3IgbmV3IHJlZ2lvbnMpIGFuZCwgaWYgcm93cyBhcmUgc2VsZWN0ZWQsIGFwcGx5XG4gICAqICBpdCB0byB0aGVtIGluIG9uZSBjb21taXQuICovXG4gIHByb3RlY3RlZCBzZWxlY3RBY3RpdmVDbGFzcyhuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUNsYXNzID0gbmFtZTtcbiAgICB0aGlzLmFwcGx5Q2xhc3NUb1NlbGVjdGVkKG5hbWUpO1xuICB9XG5cbiAgLyoqIEFwcGx5IGEgY2xhc3MgKGxhYmVsICsgcHJlc2V0L2ZhbGxiYWNrIGNvbG91cikgdG8gdGhlIGN1cnJlbnQgc2VsZWN0aW9uIGFuZCBjb21taXQuICovXG4gIHByaXZhdGUgYXBwbHlDbGFzc1RvU2VsZWN0ZWQobmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBuZXcgU2V0KHRoaXMuc2VsZWN0ZWRSZWdpb25zID8/IFtdKTtcbiAgICBpZiAoIXNlbGVjdGVkLnNpemUpIHJldHVybjtcbiAgICBjb25zdCBjb2xvciA9IGNvbG9yRm9yTGFiZWwobmFtZSwgdGhpcy5wcmVzZXRTZXQpO1xuICAgIHRoaXMucGF0Y2hSZWdpb25zKChyKSA9PiAoc2VsZWN0ZWQuaGFzKHIpID8geyBsYWJlbDogbmFtZSwgY29sb3JPdmVycmlkZGVuOiBmYWxzZSwgY29sb3IgfSA6IG51bGwpKTtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICB9XG5cbiAgLyoqIFwiRWRpdCBjbGFzcyBvbiBzZWxlY3RlZCByb3dzXCIgcG9wdXAg4oCUIGFwcGx5IHRoZSBjaG9zZW4gZXhpc3RpbmcgY2xhc3MuICovXG4gIHByb3RlY3RlZCBhcHBseUJ1bGtDbGFzcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYnVsa0NsYXNzKSByZXR1cm47XG4gICAgdGhpcy5hcHBseUNsYXNzVG9TZWxlY3RlZCh0aGlzLmJ1bGtDbGFzcyk7XG4gICAgdGhpcy5vdmVybGF5UGFuZWw/LmhpZGUoKTtcbiAgfVxuXG4gIC8qKiBcIkVkaXQgY2xhc3Mgb24gc2VsZWN0ZWQgcm93c1wiIHBvcHVwIOKAlCBhZGQgYSBuZXcgY2xhc3MgYW5kIHNldCBpdCBvbiB0aGUgc2VsZWN0aW9uLiAqL1xuICBwcm90ZWN0ZWQgYWRkQW5kQXBwbHlCdWxrQ2xhc3MoKTogdm9pZCB7XG4gICAgY29uc3QgbmFtZSA9IHRoaXMubmV3QnVsa0NsYXNzLnRyaW0oKTtcbiAgICBpZiAoIW5hbWUpIHJldHVybjtcbiAgICBjb25zdCBrZXkgPSBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIG5hbWUpO1xuICAgIGNvbnN0IGV4aXN0cyA9IHRoaXMucHJlc2V0U2V0LmNsYXNzZXMuc29tZSgoYykgPT4gcHJlc2V0S2V5KHRoaXMucHJlc2V0U2V0LCBjLm5hbWUpID09PSBrZXkpO1xuICAgIGlmICghZXhpc3RzKSB7XG4gICAgICB0aGlzLnJlZ2lvbkFwaS51cHNlcnRDbGFzcyh7IG5hbWUsIGNvbG9yOiBjb2xvckZvckxhYmVsKG5hbWUsIHRoaXMucHJlc2V0U2V0KSwgc291cmNlOiAndXNlcicgfSk7XG4gICAgfVxuICAgIHRoaXMuYXBwbHlDbGFzc1RvU2VsZWN0ZWQobmFtZSk7XG4gICAgdGhpcy5idWxrQ2xhc3MgPSBuYW1lO1xuICAgIHRoaXMubmV3QnVsa0NsYXNzID0gJyc7XG4gICAgdGhpcy5vdmVybGF5UGFuZWw/LmhpZGUoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBNYW5hZ2UtY2xhc3NlcyBkaWFsb2cg4pSA4pSAXG4gIHByb3RlY3RlZCBvcGVuTWFuYWdlRGlhbG9nKCk6IHZvaWQge1xuICAgIHRoaXMucHJlc2V0RHJhZnQgPSB0aGlzLmNsb25lUHJlc2V0U2V0KHRoaXMucHJlc2V0U2V0KTtcbiAgICB0aGlzLnNob3dNYW5hZ2VEaWFsb2cgPSB0cnVlO1xuICB9XG4gIHByaXZhdGUgY2xvbmVQcmVzZXRTZXQoczogUHJlc2V0U2V0KTogUHJlc2V0U2V0IHtcbiAgICByZXR1cm4ge1xuICAgICAgY2xhc3NlczogKHMuY2xhc3NlcyA/PyBbXSkubWFwKChjKSA9PiAoeyAuLi5jIH0pKSxcbiAgICAgIGZhbGxiYWNrUGFsZXR0ZTogWy4uLihzLmZhbGxiYWNrUGFsZXR0ZSA/PyBbXSldLFxuICAgICAgYXV0b1Byb21vdGU6ICEhcy5hdXRvUHJvbW90ZSxcbiAgICAgIG1hdGNoTW9kZTogcy5tYXRjaE1vZGUgPT09ICdub3JtYWxpemVkJyA/ICdub3JtYWxpemVkJyA6ICdleGFjdCcsXG4gICAgfTtcbiAgfVxuICAvKiogQ29tbWl0IHRoZSBkcmFmdDogZHJvcCBibGFuay9kdXBsaWNhdGUgbmFtZXMsIHBlcnNpc3QsIGFuZCByZWNvbG91clxuICAgKiAgbm9uLW92ZXJyaWRkZW4gcmVnaW9ucyB3aXRoIHRoZSB1cGRhdGVkIHByZXNldHMuICovXG4gIHByb3RlY3RlZCBhcHBseU1hbmFnZURpYWxvZyhjbG9zZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmVzZXREcmFmdCkgcmV0dXJuO1xuICAgIC8vIERlLWR1cGxpY2F0ZSB1c2luZyB0aGUgYWN0aXZlIG1hdGNoIG1vZGUncyBrZXkgc28gbm9ybWFsaXplZCBtb2RlIGNhbid0IGtlZXBcbiAgICAvLyBib3RoIFwiVHVtb3JcIiBhbmQgXCJ0dW1vclwiICh3aGljaCB3b3VsZCBjb2xsaWRlIGF0IHJ1bnRpbWUgaW4gZmluZFByZXNldCgpKS5cbiAgICBjb25zdCBkcmFmdCA9IHRoaXMucHJlc2V0RHJhZnQ7XG4gICAgY29uc3Qga2V5T2YgPSAoczogc3RyaW5nKSA9PiBwcmVzZXRLZXkoZHJhZnQsIHMpO1xuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBjbGFzc2VzOiBDbGFzc1ByZXNldFtdID0gW107XG4gICAgZm9yIChjb25zdCBjIG9mIGRyYWZ0LmNsYXNzZXMpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSAoYy5uYW1lID8/ICcnKS50cmltKCk7XG4gICAgICBjb25zdCBrZXkgPSBrZXlPZihuYW1lKTtcbiAgICAgIGlmICghbmFtZSB8fCBzZWVuLmhhcyhrZXkpKSBjb250aW51ZTtcbiAgICAgIHNlZW4uYWRkKGtleSk7XG4gICAgICBjbGFzc2VzLnB1c2goeyAuLi5jLCBuYW1lIH0pO1xuICAgIH1cbiAgICB0aGlzLnByZXNldERyYWZ0ID0geyAuLi5kcmFmdCwgY2xhc3NlcyB9O1xuICAgIC8vIENsYXNzZXMgZHJvcHBlZCBpbiB0aGUgZGlhbG9nOiB0aGVpciByZWdpb25zIHJldmVydCB0byB0aGUgZGVmYXVsdCBcIlJlZ2lvblwiXG4gICAgLy8gY2xhc3MgKGVsc2Ugc3luY0NsYXNzZXNGcm9tUmVnaW9ucyB3b3VsZCBqdXN0IHJlLWFkZCB0aGVtKSAoaml0LXVpIzcwKS5cbiAgICBjb25zdCBrZXB0ID0gbmV3IFNldChjbGFzc2VzLm1hcCgoYykgPT4ga2V5T2YoYy5uYW1lKSkpO1xuICAgIGNvbnN0IHJlbW92ZWQgPSB0aGlzLnByZXNldFNldC5jbGFzc2VzLm1hcCgoYykgPT4gYy5uYW1lKS5maWx0ZXIoKG4pID0+ICFrZXB0LmhhcyhrZXlPZihuKSkpO1xuICAgIHRoaXMucmVhc3NpZ25SZWdpb25zVG9EZWZhdWx0Q2xhc3MocmVtb3ZlZCk7XG4gICAgdGhpcy5yZWdpb25BcGkuc2V0UHJlc2V0U2V0KHRoaXMucHJlc2V0RHJhZnQpO1xuICAgIHRoaXMuY29tbWl0KCk7IC8vIHJlY29sb3VyIGV4aXN0aW5nIChub24tb3ZlcnJpZGRlbikgcmVnaW9ucyBmcm9tIHRoZSBuZXcgcHJlc2V0c1xuICAgIGlmIChjbG9zZSkgdGhpcy5zaG93TWFuYWdlRGlhbG9nID0gZmFsc2U7XG4gIH1cbiAgcHJvdGVjdGVkIHJlc2V0UHJlc2V0c1RvRGVmYXVsdHMoKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpb25BcGkucmVzZXRQcmVzZXRzKCk7XG4gICAgdGhpcy5wcmVzZXREcmFmdCA9IHRoaXMuY2xvbmVQcmVzZXRTZXQodGhpcy5yZWdpb25BcGkuZ2V0UHJlc2V0U2V0KCkpO1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cbiAgcHJvdGVjdGVkIGV4cG9ydFByZXNldHMoKTogdm9pZCB7XG4gICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KHRoaXMucmVnaW9uQXBpLmdldFByZXNldFNldCgpLCBudWxsLCAyKTtcbiAgICBzYXZlQXMobmV3IEJsb2IoW2pzb25dLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSwgJ2Fubm90YXRpb24tY2xhc3Nlcy5qc29uJyk7XG4gIH1cbiAgcHJvdGVjdGVkIGltcG9ydFByZXNldHMoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5wZXJzaXN0ZW5jZS5yZWFkQ2hvc2VuRmlsZShldmVudCwgKHRleHQpID0+IHRoaXMuYXBwbHlJbXBvcnRlZFByZXNldHModGV4dCkpO1xuICB9XG5cbiAgLyoqIFZhbGlkYXRlIGFuZCBhcHBseSBhbiBpbXBvcnRlZCBhbm5vdGF0aW9uLWNsYXNzZXMgSlNPTiBmaWxlLiAqL1xuICBwcml2YXRlIGFwcGx5SW1wb3J0ZWRQcmVzZXRzKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXQgPSBwYXJzZVByZXNldFNldChKU09OLnBhcnNlKHRleHQpKTtcbiAgICAgIGlmICghc2V0KSB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBmaWxlIGlzIG5vdCBhbiBhbm5vdGF0aW9uLWNsYXNzIGxpc3QgKG5vIHZhbGlkIGNsYXNzZXMpLicpO1xuICAgICAgdGhpcy5yZWdpb25BcGkuc2V0UHJlc2V0U2V0KHNldCk7XG4gICAgICB0aGlzLnByZXNldERyYWZ0ID0gdGhpcy5jbG9uZVByZXNldFNldCh0aGlzLnJlZ2lvbkFwaS5nZXRQcmVzZXRTZXQoKSk7XG4gICAgICB0aGlzLmNvbW1pdCgpO1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IFZJWl9UT0FTVF9LRVksXG4gICAgICAgIHNldmVyaXR5OiAnc3VjY2VzcycsXG4gICAgICAgIHN1bW1hcnk6ICdDbGFzc2VzIGltcG9ydGVkJyxcbiAgICAgICAgZGV0YWlsOiAnQW5ub3RhdGlvbiBjbGFzc2VzIGxvYWRlZC4nLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgIGtleTogVklaX1RPQVNUX0tFWSxcbiAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgIHN1bW1hcnk6ICdJbXBvcnQgZmFpbGVkJyxcbiAgICAgICAgZGV0YWlsOiBgJHsoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSA/PyBlcnJ9YCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBpbXBvcnRSb2lzKGV2ZW50OiBFdmVudCkge1xuICAgIHRoaXMucGVyc2lzdGVuY2UucmVhZENob3NlbkZpbGUoZXZlbnQsICh0ZXh0KSA9PiB0aGlzLmFwcGx5SW1wb3J0ZWRSb2lzKHRleHQpKTtcbiAgfVxuXG4gIC8qKiBSZXBsYWNlIHRoZSByZWdpb25zIHdpdGggYW4gaW1wb3J0ZWQgR2VvSlNPTiBmaWxlJ3MuICovXG4gIHByaXZhdGUgYXBwbHlJbXBvcnRlZFJvaXModGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVnaW9ucyA9IHRoaXMucmVnaW9uQXBpLmltcG9ydFJlZ2lvbnModGV4dCk7XG4gICAgICB0aGlzLmZpbGxDbGFzc0NvbG9ycygpO1xuICAgICAgdGhpcy5jb21taXQoKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAga2V5OiBWSVpfVE9BU1RfS0VZLFxuICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgc3VtbWFyeTogJ0Vycm9yIGltcG9ydGluZyB0aGUgZmlsZScsXG4gICAgICAgIGRldGFpbDogYCR7KGVyciBhcyBFcnJvcik/Lm1lc3NhZ2UgPz8gZXJyfWAsXG4gICAgICB9KTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlYWRpbmcgdGhlIGZpbGU6JywgZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVnaW9ucyB0byBzZXJpYWxpemUgb24gc2F2ZS9leHBvcnQgKGV2ZXJ5IHNsaWNlIGZvciBhIGNvbWJpbmVkIHotc3RhY2spLiAqL1xuICBwcml2YXRlIHJlZ2lvbnNGb3JTYXZlKCk6IFJlZ2lvbltdIHtcbiAgICByZXR1cm4gdGhpcy5wZXJzaXN0ZW5jZS5yZWdpb25zRm9yU2F2ZSh0aGlzLnJlZ2lvbnMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGV4cG9ydFJvaXMoKSB7XG4gICAgaWYgKCF0aGlzLnJlZ2lvbnNGb3JTYXZlKCkubGVuZ3RoKSByZXR1cm47XG4gICAgdGhpcy5leHBvcnRGaWxlbmFtZSA9IHRoaXMucGVyc2lzdGVuY2UuZGVmYXVsdEV4cG9ydE5hbWUoKTtcbiAgICB0aGlzLnNob3dFeHBvcnREaWFsb2cgPSB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbmZpcm1FeHBvcnQoKSB7XG4gICAgY29uc3QgZmlsZW5hbWUgPSB0aGlzLmV4cG9ydEZpbGVuYW1lLnRyaW0oKTtcbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5yZWdpb25zRm9yU2F2ZSgpO1xuICAgIGlmICghZmlsZW5hbWUgfHwgIXJlZ2lvbnMubGVuZ3RoKSByZXR1cm47XG4gICAgdGhpcy5zaG93RXhwb3J0RGlhbG9nID0gZmFsc2U7XG4gICAgdGhpcy5wZXJzaXN0ZW5jZS5kb3dubG9hZChyZWdpb25zLCBmaWxlbmFtZSk7XG4gIH1cblxuICAvKiogT3BlbiB0aGUgXCJTYXZlIG1hc2tcIiBkaWFsb2csIHNlZWRlZCB3aXRoIGA8aW1hZ2Utc3RlbT5fbWFzay5wbmdgLiAqL1xuICBwcm90ZWN0ZWQgb3BlblNhdmVNYXNrRGlhbG9nKCkge1xuICAgIGlmICghdGhpcy5yZWdpb25zLmxlbmd0aCkgcmV0dXJuO1xuICAgIHRoaXMuc2F2ZU1hc2tGaWxlbmFtZSA9IHRoaXMucGVyc2lzdGVuY2UuZGVmYXVsdE1hc2tOYW1lKCk7XG4gICAgdGhpcy5tYXNrTW9kZSA9ICdiaW5hcnknO1xuICAgIHRoaXMuc2hvd1NhdmVNYXNrRGlhbG9nID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSYXN0ZXJpemUgdGhlIHJlZ2lvbnMgdG8gdGhlIGNob3NlbiBtYXNrIHR5cGUgYW5kIGRvd25sb2FkIGFzIGEgUE5HLiBUaGVcbiAgICogaGVhdnkgd29yayBydW5zIGluIGEgV2ViIFdvcmtlciAoe0BsaW5rIE1hc2tFeHBvcnRTZXJ2aWNlfSkgc28gdGhlIFVJIG5ldmVyXG4gICAqIGZyZWV6ZXMgb24gd2hvbGUtc2xpZGUgaW1hZ2VzIGFuZCB0aGUgam9iIGNhbiBiZSBjYW5jZWxsZWQgKGppdC11aSM5NSk7XG4gICAqIHRoZSBkaWFsb2cgc3RheXMgb3BlbiB3aXRoIGEgcHJvZ3Jlc3MgYmFyIHVudGlsIGRvbmUuXG4gICAqL1xuICBwcm90ZWN0ZWQgY29uZmlybVNhdmVNYXNrKCkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gdGhpcy5zYXZlTWFza0ZpbGVuYW1lLnRyaW0oKTtcbiAgICBpZiAoIWZpbGVuYW1lIHx8ICF0aGlzLnJlZ2lvbnMubGVuZ3RoIHx8IHRoaXMubWFza0J1c3kpIHJldHVybjtcblxuICAgIGNvbnN0IHNpemUgPSB0aGlzLnJlZ2lvbkFwaS5nZXRNYXNrSW1hZ2VTaXplKCk7XG4gICAgaWYgKCFzaXplKSB7XG4gICAgICB0aGlzLm1hc2tFcnJvcignTm8gaW1hZ2Ugc2l6ZSBpcyBhdmFpbGFibGUsIHNvIHRoZSBtYXNrIGNhbm5vdCBiZSBzaXplZC4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tYXNrQnVzeSA9IHRydWU7XG4gICAgdGhpcy5tYXNrRW5jb2RpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hc2tQcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5tYXNrSm9iID0gdGhpcy5tYXNrRXhwb3J0XG4gICAgICAuZXhwb3J0KHtcbiAgICAgICAgcmVnaW9uczogdGhpcy5yZWdpb25zLFxuICAgICAgICBpbWFnZVNpemU6IHNpemUsXG4gICAgICAgIG1vZGU6IHRoaXMubWFza01vZGUsXG4gICAgICAgIHNvdXJjZU5hbWU6IHRoaXMucGVyc2lzdGVuY2Uuc2VsZWN0ZWRGaWxlTmFtZSgpLFxuICAgICAgfSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoZSkgPT4ge1xuICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgICAgIHN3aXRjaCAoZS50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdwbGFubmVkJzpcbiAgICAgICAgICAgICAgaWYgKGUuc2NhbGUgPCAxKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICAgICAgICAgICAga2V5OiBWSVpfVE9BU1RfS0VZLFxuICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6ICdpbmZvJyxcbiAgICAgICAgICAgICAgICAgIHN1bW1hcnk6ICdNYXNrIGRvd25zY2FsZWQnLFxuICAgICAgICAgICAgICAgICAgZGV0YWlsOiBgSW1hZ2UgdG9vIGxhcmdlIGZvciBhIGZ1bGwtcmVzb2x1dGlvbiBtYXNrOyBzYXZpbmcgYXQgJHtlLndpZHRofcOXJHtlLmhlaWdodH0uYCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3Byb2dyZXNzJzpcbiAgICAgICAgICAgICAgdGhpcy5tYXNrUHJvZ3Jlc3MgPSBlLnBlcmNlbnQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZW5jb2RpbmcnOlxuICAgICAgICAgICAgICB0aGlzLm1hc2tFbmNvZGluZyA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZG9uZSc6XG4gICAgICAgICAgICAgIHRoaXMuZmluaXNoTWFzayhlLmJsb2IsIGZpbGVuYW1lKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgICB0aGlzLm1hc2tFcnJvcihlcnIubWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKiBDYW5jZWwgYW4gaW4tcHJvZ3Jlc3MgbWFzayBleHBvcnQgKHRlcm1pbmF0ZXMgaXRzIHdvcmtlcikgYW5kIHJlc2V0IHN0YXRlLiAqL1xuICBwcm90ZWN0ZWQgY2FuY2VsU2F2ZU1hc2soKSB7XG4gICAgdGhpcy5tYXNrSm9iPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMubWFza0pvYiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1hc2tCdXN5ID0gZmFsc2U7XG4gICAgdGhpcy5tYXNrRW5jb2RpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hc2tQcm9ncmVzcyA9IDA7XG4gIH1cblxuICBwcml2YXRlIGZpbmlzaE1hc2soYmxvYjogQmxvYiwgZmlsZW5hbWU6IHN0cmluZykge1xuICAgIHRoaXMubWFza0pvYiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1hc2tCdXN5ID0gZmFsc2U7XG4gICAgdGhpcy5tYXNrRW5jb2RpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnNob3dTYXZlTWFza0RpYWxvZyA9IGZhbHNlO1xuICAgIHNhdmVBcyhibG9iLCBmaWxlbmFtZSk7XG4gIH1cblxuICBwcml2YXRlIG1hc2tFcnJvcihkZXRhaWw6IHN0cmluZykge1xuICAgIHRoaXMubWFza0pvYiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1hc2tCdXN5ID0gZmFsc2U7XG4gICAgdGhpcy5tYXNrRW5jb2RpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICBrZXk6IFZJWl9UT0FTVF9LRVksXG4gICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgIHN1bW1hcnk6ICdDb3VsZCBub3QgY3JlYXRlIG1hc2snLFxuICAgICAgZGV0YWlsLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBlcnNpc3RSZWdpb25zKCkge1xuICAgIC8vIEZvbGRlciBzdGFjazogd3JpdGUgZWFjaCBzbGljZSdzIHJlZ2lvbnMgYmFjayB0byBpdHMgb3duIHNsaWNlLWZpbGUnc1xuICAgIC8vIHNpYmxpbmcgZ2VvanNvbiDigJQgbm8gc2luZ2xlLWZpbGVuYW1lIHByb21wdCAoaml0LXVpIzkzKS5cbiAgICBpZiAodGhpcy5wZXJzaXN0ZW5jZS5zYXZlc1BlclNsaWNlKCkpIHtcbiAgICAgIHRoaXMuc2F2ZVN0YWNrU2xpY2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGZpbGVuYW1lID0gdGhpcy5wZXJzaXN0ZW5jZS5kZWZhdWx0U2F2ZU5hbWUoKTtcbiAgICBpZiAoIWZpbGVuYW1lIHx8ICF0aGlzLnJlZ2lvbnNGb3JTYXZlKCkubGVuZ3RoKSByZXR1cm47XG5cbiAgICB0aGlzLnNhdmVBc0ZpbGVuYW1lID0gZmlsZW5hbWU7XG4gICAgdGhpcy5zYXZlQXNGaWxlRXhpc3RzID0gZmFsc2U7XG4gICAgdGhpcy5zaG93U2F2ZUFzRGlhbG9nID0gdHJ1ZTtcbiAgICB0aGlzLnNhdmVBc0NoZWNrJC5uZXh0KHRoaXMuc2F2ZUFzRmlsZW5hbWUpO1xuICB9XG5cbiAgLyoqIFNhdmUgYSBmb2xkZXIgc3RhY2sncyByZWdpb25zIGFzIG9uZSBnZW9qc29uIHBlciBzbGljZS1maWxlIChqaXQtdWkjOTMpLlxuICAgKiAgTm8gZGlhbG9nIGNvdmVycyB0aGUgdG9vbGJhciBtZWFud2hpbGUsIHNvIGEgU2F2ZSB3aGlsZSBvbmUgaXMgdXBsb2FkaW5nXG4gICAqICBpcyBpZ25vcmVkIHJhdGhlciB0aGFuIHN0YXJ0aW5nIGEgc2Vjb25kIHdyaXRlIChhbmQgb3JwaGFuaW5nIHRoZSBmaXJzdCkuICovXG4gIHByaXZhdGUgc2F2ZVN0YWNrU2xpY2VzKCkge1xuICAgIGlmICh0aGlzLnNhdmVBc0J1c3kpIHJldHVybjtcbiAgICBjb25zdCBzbGljZXMgPSB0aGlzLnBlcnNpc3RlbmNlLnNsaWNlR2VvSnNvbnMoKTtcbiAgICBpZiAoIXNsaWNlcy5sZW5ndGgpIHJldHVybjtcbiAgICB0aGlzLnNhdmVBc0J1c3kgPSB0cnVlO1xuICAgIHRoaXMuX3NhdmVBc1N1YiA9IHRoaXMucGVyc2lzdGVuY2Uuc2F2ZVNsaWNlcyhzbGljZXMpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2F2ZUFzQnVzeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgdGhpcy50b2FzdChcbiAgICAgICAgICAnc3VjY2VzcycsXG4gICAgICAgICAgJ1JlZ2lvbnMgc2F2ZWQnLFxuICAgICAgICAgIGBTYXZlZCBST0lzIGZvciAke3NsaWNlcy5sZW5ndGh9IHNsaWNlJHtzbGljZXMubGVuZ3RoID09PSAxID8gJycgOiAncyd9YCxcbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICB0aGlzLnNhdmVBc0J1c3kgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgIHRoaXMudG9hc3QoJ2Vycm9yJywgJ0Vycm9yIHNhdmluZyByZWdpb25zJywgYCR7KGVyciBhcyBFcnJvcik/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjaGVja1NhdmVBc0ZpbGVFeGlzdHMoKSB7XG4gICAgdGhpcy5zYXZlQXNDaGVjayQubmV4dCh0aGlzLnNhdmVBc0ZpbGVuYW1lKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb25maXJtU2F2ZUFzKCkge1xuICAgIGlmICghdGhpcy5wZXJzaXN0ZW5jZS5zZWxlY3RlZEZpbGVOYW1lKCkpIHJldHVybjtcblxuICAgIGNvbnN0IGZpbGVuYW1lID0gdGhpcy5zYXZlQXNGaWxlbmFtZS50cmltKCk7XG4gICAgaWYgKCFmaWxlbmFtZSkgcmV0dXJuO1xuXG4gICAgLy8gS2VlcCB0aGUgZGlhbG9nIG9wZW4gc2hvd2luZyBhbiAoaW5kZXRlcm1pbmF0ZSkgcHJvZ3Jlc3MgYmFyIHdoaWxlIHRoZVxuICAgIC8vIHJlZ2lvbnMgc2VyaWFsaXplIGFuZCB1cGxvYWQsIHRoZW4gY2xvc2Ugb24gc3VjY2Vzcy5cbiAgICBjb25zdCBkb1NhdmUgPSAoKSA9PiB7XG4gICAgICB0aGlzLnNhdmVBc0J1c3kgPSB0cnVlO1xuICAgICAgLy8gQWxzbyBydW4gZnJvbSB0aGUgb3ZlcndyaXRlIGNvbmZpcm1hdGlvbiwgd2hpY2ggdGhlIGhvc3QncyBkaWFsb2cgbWF5IGFuc3dlci5cbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgdGhpcy5fc2F2ZUFzU3ViID0gdGhpcy5wZXJzaXN0ZW5jZVxuICAgICAgICAuc2F2ZSgoKSA9PiB0aGlzLnJlZ2lvbnNGb3JTYXZlKCksIGZpbGVuYW1lKVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNhdmVBc0J1c3kgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2hvd1NhdmVBc0RpYWxvZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgICAgICB0aGlzLnRvYXN0KCdzdWNjZXNzJywgJ1JlZ2lvbnMgc2F2ZWQnLCBgU2F2ZWQgYXMgJHtmaWxlbmFtZX1gKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNhdmVBc0J1c3kgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgICAgICAgdGhpcy50b2FzdCgnZXJyb3InLCAnRXJyb3Igc2F2aW5nIHJlZ2lvbnMnLCBgJHsoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSB8fCBlcnJ9YCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGlmICh0aGlzLnNhdmVBc0ZpbGVFeGlzdHMpIHtcbiAgICAgIHRoaXMuY29uZmlybWF0aW9uU2VydmljZS5jb25maXJtKHtcbiAgICAgICAgbWVzc2FnZTogYFwiJHtmaWxlbmFtZX1cIiBhbHJlYWR5IGV4aXN0cy4gRG8geW91IHdhbnQgdG8gb3ZlcndyaXRlIGl0P2AsXG4gICAgICAgIGhlYWRlcjogJ0NvbmZpcm0gT3ZlcndyaXRlJyxcbiAgICAgICAgaWNvbjogJ3BpIHBpLWV4Y2xhbWF0aW9uLXRyaWFuZ2xlJyxcbiAgICAgICAgYWNjZXB0OiBkb1NhdmUsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9TYXZlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENhbmNlbCBhbiBpbi1wcm9ncmVzcyBHZW9KU09OIHBlcnNpc3Q6IGFib3J0IHRoZSBkZWZlcnJlZCBzZXJpYWxpemUgYW5kL29yXG4gICAqICB0aGUgaW4tZmxpZ2h0IHVwbG9hZCwgYW5kIHJlc2V0IHN0YXRlLiAqL1xuICBwcm90ZWN0ZWQgY2FuY2VsU2F2ZUFzKCkge1xuICAgIHRoaXMuX3NhdmVBc1N1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9zYXZlQXNTdWIgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5zYXZlQXNCdXN5ID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIHRvYXN0KHNldmVyaXR5OiAnc3VjY2VzcycgfCAnZXJyb3InIHwgJ2luZm8nLCBzdW1tYXJ5OiBzdHJpbmcsIGRldGFpbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IFZJWl9UT0FTVF9LRVksIHNldmVyaXR5LCBzdW1tYXJ5LCBkZXRhaWwgfSk7XG4gIH1cbn1cbiIsIjxwLXRvb2xiYXIgc3R5bGVDbGFzcz1cInJlZ2lvbi10b29sYmFyXCI+XG4gIDxkaXYgY2xhc3M9XCJwLXRvb2xiYXItZ3JvdXAtc3RhcnQgYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtd3JhcCBnYXAtMVwiPlxuICAgIDxwLWJ1dHRvblxuICAgICAgaWNvbj1cInBpIHBpLXRhZ1wiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwiIXNob3dTaGFwZUxhYmVsXCJcbiAgICAgIHBUb29sdGlwPVwiU2hvdyByZWdpb24gbGFiZWxzLlwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKG9uQ2xpY2spPVwic2hvd1NoYXBlTGFiZWwgPSAhc2hvd1NoYXBlTGFiZWw7IGNoYW5nZVNob3dTaGFwZUxhYmVsKHNob3dTaGFwZUxhYmVsKVwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICA8IS0tIE5ldyByZWdpb25zIGFyZSBub3cgY3JlYXRlZCBmcm9tIHRoZSBkaWFncmFtIHRvb2xiYXJcbiAgICAgICAgIChyZWN0YW5nbGUsIHBvbHlsaW5lLCBmcmVlZm9ybSwgd2FuZCkuIC0tPlxuICAgIDxwLWJ1dHRvblxuICAgICAgaWNvbj1cInBpIHBpLXVwbG9hZFwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIlVwbG9hZCBhbmQgZGlzcGxheSByZWdpb25zIGZyb20gZ2VvanNvbiBmaWxlLlwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cInJvaUZpbGVJbnB1dC5jbGljaygpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8aW5wdXRcbiAgICAgICNyb2lGaWxlSW5wdXRcbiAgICAgIHR5cGU9XCJmaWxlXCJcbiAgICAgIGFjY2VwdD1cIi5nZW9qc29uLC5qc29uXCJcbiAgICAgIGhpZGRlblxuICAgICAgKGNoYW5nZSk9XCJpbXBvcnRSb2lzKCRldmVudCk7IHJvaUZpbGVJbnB1dC52YWx1ZSA9ICcnXCJcbiAgICAvPlxuICAgIDxwLWJ1dHRvblxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgcFRvb2x0aXA9XCJEb3dubG9hZCByZWdpb25zIGFzIGdlb2pzb24gZmlsZS5cIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIGljb249XCJwaSBwaS1kb3dubG9hZFwiXG4gICAgICAoY2xpY2spPVwiZXhwb3J0Um9pcygpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS1zYXZlXCJcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIHN0eWxlQ2xhc3M9XCJtci0yXCJcbiAgICAgIHBUb29sdGlwPVwiU2F2ZSByZWdpb25zIHRvIHNlcnZlci5cIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChjbGljayk9XCJwZXJzaXN0UmVnaW9ucygpXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhcmVnaW9ucyB8fCAhcmVnaW9ucy5sZW5ndGhcIlxuICAgID5cbiAgICA8L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvblxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgcFRvb2x0aXA9XCJEb3dubG9hZCBtYXNrIG9mIHRoZSByZWdpb25zIGFzIFBOR1wiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cIm9wZW5TYXZlTWFza0RpYWxvZygpXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhcmVnaW9ucyB8fCAhcmVnaW9ucy5sZW5ndGhcIlxuICAgID5cbiAgICAgIDwhLS0gUmVmZXJlbmNlcyB0aGUgZmlsZSBzbyBJbmtzY2FwZSBlZGl0cyB0byBtYXNrLnN2ZyBzaG93IHVwIGRpcmVjdGx5XG4gICAgICAgICAgICh0aGUgbGliJ3MgYXNzZXRzLyoqIGFyZSBzZXJ2ZWQgYXQgYXNzZXRzL3Bsb3R0aW5nLykuIFRoZVxuICAgICAgICAgICB0b29sYmFyLWljb24tZGFyayBmaWx0ZXIgcmVjb2xvdXJzIHRoZSBibGFjayBTVkcgdG8gdGhlIHRoZW1lIGJsdWUsXG4gICAgICAgICAgIHNhbWUgYXMgcmVnaW9uLWVkaXRvci5zdmcgYW5kIHRoZSBvdGhlciBTVkcgdG9vbGJhciBpY29ucy4gLS0+XG4gICAgICA8aW1nXG4gICAgICAgIHNyYz1cImFzc2V0cy9wbG90dGluZy9tYXNrLnN2Z1wiXG4gICAgICAgIGNsYXNzPVwidG9vbGJhci1pY29uLWRhcmtcIlxuICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtOyBoZWlnaHQ6IDFyZW07IHZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIlxuICAgICAgICBhbHQ9XCJEb3dubG9hZCBtYXNrXCJcbiAgICAgIC8+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGxhYmVsPVwieDUxMlwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIlJvdW5kIGFsbCByZWN0YW5nbGUgcmVnaW9uc1xuICAgICAgICAgICAgICAgICAgICB0byB3aWR0aCBhbmQgaGVpZ2h0IHRoYXQgYXJlIG11bHRpcGxlIG9mIDUxMlwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cInJvdW5kUmVjdGFuZ2xlTGVuZ3RocygpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS1jaGVjay1zcXVhcmVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgcFRvb2x0aXA9XCJTZWxlY3QgYWxsIHJlZ2lvbnNcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChjbGljayk9XCJzZWxlY3RBbGxSZWdpb25zKClcIlxuICAgICAgW2Rpc2FibGVkXT1cIiFyZWdpb25zIHx8ICFyZWdpb25zLmxlbmd0aFwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdGFnc1wiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIkVkaXQgY2xhc3Mgb24gc2VsZWN0ZWQgcm93c1wiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cIiFzZWxlY3RlZFJlZ2lvbnMgfHwgIXNlbGVjdGVkUmVnaW9ucy5sZW5ndGggPyBvcC5oaWRlKCkgOiBvcC50b2dnbGUoJGV2ZW50KVwiXG4gICAgICBbZGlzYWJsZWRdPVwiIXNlbGVjdGVkUmVnaW9ucyB8fCAhc2VsZWN0ZWRSZWdpb25zLmxlbmd0aFwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktcGFsZXR0ZVwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIkVkaXQgY29sb3VyIG9mIHNlbGVjdGVkIHJlZ2lvbnNcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChjbGljayk9XCJvcGVuQ29sb3JEaWFsb2coKVwiXG4gICAgICBbZGlzYWJsZWRdPVwiIXNlbGVjdGVkUmVnaW9ucyB8fCAhc2VsZWN0ZWRSZWdpb25zLmxlbmd0aFwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtb3ZlcmxheVBhbmVsICNvcCAob25IaWRlKT1cImJ1bGtDbGFzcyA9ICcnOyBuZXdCdWxrQ2xhc3MgPSAnJ1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2x1bW4gZ2FwLTJcIiBzdHlsZT1cIndpZHRoOiAxOHJlbVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtbWVkaXVtIHRleHQtOTAwXCJcbiAgICAgICAgICA+U2V0IGNsYXNzIG9uIHt7IHNlbGVjdGVkUmVnaW9ucz8ubGVuZ3RoIHx8IDAgfX0gc2VsZWN0ZWQgcmVnaW9uKHMpPC9zcGFuXG4gICAgICAgID5cbiAgICAgICAgPCEtLSBTZWxlY3RpbmcgYSBjbGFzcyBhcHBsaWVzIGl0IGltbWVkaWF0ZWx5IChjaG9vc2luZyBhbiBvcHRpb24gY2xvc2VzIHRoZVxuICAgICAgICAgICAgIG92ZXJsYXksIHNvIHRoZXJlJ3Mgbm8gc2VwYXJhdGUgQXBwbHkgYnV0dG9uKS4gLS0+XG4gICAgICAgIDxwLWRyb3Bkb3duXG4gICAgICAgICAgc3R5bGVDbGFzcz1cInctZnVsbFwiXG4gICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICBbb3B0aW9uc109XCJwcmVzZXRTZXQuY2xhc3Nlc1wiXG4gICAgICAgICAgb3B0aW9uTGFiZWw9XCJuYW1lXCJcbiAgICAgICAgICBvcHRpb25WYWx1ZT1cIm5hbWVcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwiYnVsa0NsYXNzXCJcbiAgICAgICAgICBwbGFjZWhvbGRlcj1cIkNob29zZSBhIGNsYXNz4oCmXCJcbiAgICAgICAgICBbZmlsdGVyXT1cInByZXNldFNldC5jbGFzc2VzLmxlbmd0aCA+IDhcIlxuICAgICAgICAgIGZpbHRlckJ5PVwibmFtZVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cImFwcGx5QnVsa0NsYXNzKClcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIGxldC1jIHBUZW1wbGF0ZT1cIml0ZW1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGQtdmFsdWVcIlxuICAgICAgICAgICAgICA+PHNwYW4gY2xhc3M9XCJjaGlwLXN3YXRjaFwiIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImMuY29sb3JcIj48L3NwYW4+e3sgYy5uYW1lIH19PC9zcGFuXG4gICAgICAgICAgICA+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9wLWRyb3Bkb3duPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicC1pbnB1dGdyb3VwXCI+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIuKApm9yIGEgbmV3IGNsYXNzXCJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwibmV3QnVsa0NsYXNzXCJcbiAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cImFkZEFuZEFwcGx5QnVsa0NsYXNzKClcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBpY29uPVwicGkgcGktcGx1c1wiXG4gICAgICAgICAgICBwVG9vbHRpcD1cIkFkZCBjbGFzcyAmYW1wOyBzZXQgaXRcIlxuICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhbmV3QnVsa0NsYXNzLnRyaW0oKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiYWRkQW5kQXBwbHlCdWxrQ2xhc3MoKVwiXG4gICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvcC1vdmVybGF5UGFuZWw+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdHJhc2hcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgKGNsaWNrKT1cImRlbGV0ZVNlbGVjdGVkUmVnaW9ucygpXCJcbiAgICAgIHBUb29sdGlwPVwiRGVsZXRlIHNlbGVjdGVkIHJlZ2lvbnNcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhc2VsZWN0ZWRSZWdpb25zIHx8ICFzZWxlY3RlZFJlZ2lvbnMubGVuZ3RoXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS10aW1lcy1jaXJjbGVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgKGNsaWNrKT1cImNsZWFyQWxsUmVnaW9ucygpXCJcbiAgICAgIHBUb29sdGlwPVwiRGVsZXRlIGFsbCByZWdpb25zXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICBbZGlzYWJsZWRdPVwiIXJlZ2lvbnMgfHwgIXJlZ2lvbnMubGVuZ3RoXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS1xdWVzdGlvblwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAoY2xpY2spPVwic2hvd0hlbHAoKVwiXG4gICAgICBwVG9vbHRpcD1cIkhlbHBcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgPC9kaXY+XG48L3AtdG9vbGJhcj5cblxuPHJlZ2lvbi1jbGFzc2VzLXBhbmVsXG4gIFtjbGFzc2VzXT1cImRpc3BsYXlDbGFzc2VzXCJcbiAgW2NvdW50c109XCJjbGFzc0NvdW50c1wiXG4gIFttYXRjaE1vZGVdPVwicHJlc2V0U2V0Lm1hdGNoTW9kZVwiXG4gIFthY3RpdmVDbGFzc109XCJhY3RpdmVDbGFzc1wiXG4gIFtzZWxlY3RlZENvdW50XT1cInNlbGVjdGVkUmVnaW9ucz8ubGVuZ3RoIHx8IDBcIlxuICBbZGVmYXVsdENsYXNzTmFtZV09XCJkZWZhdWx0Q2xhc3NOYW1lXCJcbiAgKHBpY2spPVwic2VsZWN0QWN0aXZlQ2xhc3MoJGV2ZW50KVwiXG4gIChyZWNvbG9yKT1cInNldENsYXNzQ29sb3IoJGV2ZW50Lm5hbWUsICRldmVudC5jb2xvcilcIlxuICAocmVtb3ZlKT1cImRlbGV0ZUNsYXNzKCRldmVudClcIlxuICAobWFuYWdlKT1cIm9wZW5NYW5hZ2VEaWFsb2coKVwiXG4+XG48L3JlZ2lvbi1jbGFzc2VzLXBhbmVsPlxuXG48cmVnaW9uLXRhYmxlXG4gIFtwYWdlXT1cInBhZ2VkUmVnaW9uc1wiXG4gIFt0b3RhbF09XCJyZWdpb25zLmxlbmd0aFwiXG4gIFtmaXJzdF09XCJwYWdpbmF0b3JGaXJzdFwiXG4gIFtyb3dzXT1cInBhZ2luYXRvclJvd3NcIlxuICBbcm93c1BlclBhZ2VPcHRpb25zXT1cInJvd3NQZXJQYWdlT3B0aW9uc1wiXG4gIFttZXRhS2V5XT1cIm1ldGFLZXlcIlxuICBbc2VsZWN0aW9uXT1cInNlbGVjdGVkUmVnaW9uc1wiXG4gIChzZWxlY3Rpb25DaGFuZ2UpPVwic2VsZWN0ZWRSZWdpb25zID0gJGV2ZW50XCJcbiAgKHJvd1NlbGVjdCk9XCJvblNlbGVjdGlvbkNoYW5nZWQoKVwiXG4gIFtwcmVzZXRTZXRdPVwicHJlc2V0U2V0XCJcbiAgW2RlZmF1bHRDb2xvcl09XCJzaGFwZUNvbG9yXCJcbiAgW21wcF09XCJtcHBcIlxuICBbbGFiZWxEcmFmdHNdPVwiZWRpdGluZ0xhYmVsUmVnaW9uc1wiXG4gIChsYWJlbEVkaXRTdGFydCk9XCJzdGFydEVkaXRMYWJlbCgkZXZlbnQpXCJcbiAgKGxhYmVsRHJhZnRDaGFuZ2UpPVwic2V0TGFiZWxEcmFmdCgkZXZlbnQucmVnaW9uLCAkZXZlbnQudmFsdWUpXCJcbiAgKGxhYmVsRWRpdFN0b3ApPVwic3RvcEVkaXRMYWJlbCgkZXZlbnQucmVnaW9uLCAkZXZlbnQuY29tbWl0KVwiXG4gIChjbGFzc1BpY2spPVwiYXBwbHlQcmVzZXRUb1JlZ2lvbigkZXZlbnQucmVnaW9uLCAkZXZlbnQubmFtZSlcIlxuICAoZGVsZXRlUm93KT1cImRlbGV0ZVJlZ2lvbigkZXZlbnQpXCJcbiAgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxuPlxuPC9yZWdpb24tdGFibGU+XG5cbjwhLS0gTGl2ZS1lZGl0IG1vZGU6IG5vIFNhdmUvQ2FuY2VsIOKAlCBldmVyeSBlZGl0IGNvbW1pdHMgaW1tZWRpYXRlbHkgdG8gdGhlXG4gICAgIGFjdGl2ZSBpbWFnZSdzIHJlZ2lvbiBjYWNoZS4gLS0+XG5cbjxwLWNvbmZpcm1EaWFsb2dcbiAgI2NkXG4gIFtzdHlsZV09XCJ7IHdpZHRoOiAnMjRyZW0nLCBoZWlnaHQ6ICcxNHJlbScgfVwiXG4gIGtleT1cInBvc2l0aW9uRGlhbG9nXCJcbiAgW2Jhc2VaSW5kZXhdPVwiMTAwMDBcIlxuICByZWplY3RCdXR0b25TdHlsZUNsYXNzPVwicC1idXR0b24tb3V0bGluZWRcIlxuPlxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgcEJ1dHRvbiBpY29uPVwicGkgcGktY2hlY2tcIiBsYWJlbD1cIlllc1wiIChjbGljayk9XCJjZC5hY2NlcHQoKVwiPjwvYnV0dG9uPlxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1vdXRsaW5lZFwiXG4gICAgICBwQnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdGltZXNcIlxuICAgICAgbGFiZWw9XCJOb1wiXG4gICAgICAoY2xpY2spPVwiY2QucmVqZWN0KClcIlxuICAgID48L2J1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1jb25maXJtRGlhbG9nPlxuXG48cmVnaW9uLXNhdmUtcmVnaW9ucy1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJzaG93U2F2ZUFzRGlhbG9nXCJcbiAgW2ZpbGVuYW1lXT1cInNhdmVBc0ZpbGVuYW1lXCJcbiAgKGZpbGVuYW1lQ2hhbmdlKT1cInNhdmVBc0ZpbGVuYW1lID0gJGV2ZW50OyBjaGVja1NhdmVBc0ZpbGVFeGlzdHMoKVwiXG4gIFtmaWxlRXhpc3RzXT1cInNhdmVBc0ZpbGVFeGlzdHNcIlxuICBbYnVzeV09XCJzYXZlQXNCdXN5XCJcbiAgKGNvbmZpcm0pPVwiY29uZmlybVNhdmVBcygpXCJcbiAgKGNhbmNlbFNhdmUpPVwiY2FuY2VsU2F2ZUFzKClcIlxuPlxuPC9yZWdpb24tc2F2ZS1yZWdpb25zLWRpYWxvZz5cblxuPHJlZ2lvbi1zYXZlLXJlZ2lvbnMtZGlhbG9nXG4gIGhlYWRlcj1cIkV4cG9ydCBSZWdpb25zXCJcbiAgY29uZmlybUxhYmVsPVwiRXhwb3J0XCJcbiAgY29uZmlybUljb249XCJwaSBwaS1kb3dubG9hZFwiXG4gIGlucHV0SWQ9XCJleHBvcnQtZmlsZW5hbWVcIlxuICBbKHZpc2libGUpXT1cInNob3dFeHBvcnREaWFsb2dcIlxuICBbKGZpbGVuYW1lKV09XCJleHBvcnRGaWxlbmFtZVwiXG4gIChjb25maXJtKT1cImNvbmZpcm1FeHBvcnQoKVwiXG4+XG48L3JlZ2lvbi1zYXZlLXJlZ2lvbnMtZGlhbG9nPlxuXG48cmVnaW9uLXNhdmUtbWFzay1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJzaG93U2F2ZU1hc2tEaWFsb2dcIlxuICBbKGZpbGVuYW1lKV09XCJzYXZlTWFza0ZpbGVuYW1lXCJcbiAgWyhtb2RlKV09XCJtYXNrTW9kZVwiXG4gIFtidXN5XT1cIm1hc2tCdXN5XCJcbiAgW3Byb2dyZXNzXT1cIm1hc2tQcm9ncmVzc1wiXG4gIFtlbmNvZGluZ109XCJtYXNrRW5jb2RpbmdcIlxuICAoY29uZmlybSk9XCJjb25maXJtU2F2ZU1hc2soKVwiXG4gIChjYW5jZWxFeHBvcnQpPVwiY2FuY2VsU2F2ZU1hc2soKVwiXG4+XG48L3JlZ2lvbi1zYXZlLW1hc2stZGlhbG9nPlxuXG48cmVnaW9uLWNvbG9yLWRpYWxvZ1xuICBbKHZpc2libGUpXT1cInNob3dDb2xvckRpYWxvZ1wiXG4gIFtlZGl0c109XCJjbGFzc0NvbG9yRWRpdHNcIlxuICBbc2VsZWN0ZWRDb3VudF09XCJzZWxlY3RlZFJlZ2lvbnM/Lmxlbmd0aCB8fCAwXCJcbiAgKGFwcGx5KT1cImFwcGx5Q29sb3JUb1NlbGVjdGVkKCRldmVudClcIlxuPlxuPC9yZWdpb24tY29sb3ItZGlhbG9nPlxuXG48IS0tIE1hbmFnZSBhbm5vdGF0aW9uIGNsYXNzZXMgKGppdC11aSM3MCk6IGVkaXRzIGEgd29ya2luZyBjb3B5LCBjb21taXR0ZWQgb24gQXBwbHkuIC0tPlxuPHJlZ2lvbi1tYW5hZ2UtY2xhc3Nlcy1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJzaG93TWFuYWdlRGlhbG9nXCJcbiAgWyhkcmFmdCldPVwicHJlc2V0RHJhZnRcIlxuICAoYXBwbHkpPVwiYXBwbHlNYW5hZ2VEaWFsb2codHJ1ZSlcIlxuICAocmVzZXREZWZhdWx0cyk9XCJyZXNldFByZXNldHNUb0RlZmF1bHRzKClcIlxuICAoaW1wb3J0RmlsZSk9XCJpbXBvcnRQcmVzZXRzKCRldmVudClcIlxuICAoZXhwb3J0KT1cImV4cG9ydFByZXNldHMoKVwiXG4+XG48L3JlZ2lvbi1tYW5hZ2UtY2xhc3Nlcy1kaWFsb2c+XG5cbjxyZWdpb24tZWRpdG9yLWhlbHAgWyh2aXNpYmxlKV09XCJkaXNwbGF5SGVscERpYWxvZ1wiPjwvcmVnaW9uLWVkaXRvci1oZWxwPlxuIl19
|
|
1570
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBR0wsU0FBUyxFQUNULE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBRTdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBMEIsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbEcsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNoRixPQUFPLEVBQW9CLGlCQUFpQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDOUYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNoRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pGLE9BQU8sRUFFTCxrQkFBa0IsRUFDbEIsVUFBVSxFQUNWLGdCQUFnQixHQUNqQixNQUFNLGdDQUFnQyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSx3QkFBd0IsRUFBZ0IsTUFBTSw4QkFBOEIsQ0FBQztBQUN0RixPQUFPLEVBQWtCLDBCQUEwQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDakgsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDaEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFpQixNQUFNLG1DQUFtQyxDQUFDO0FBR3RGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ2pHLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ3hGLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQzlGLE9BQU8sRUFBRSxpQkFBaUIsRUFBWSxNQUFNLHVCQUF1QixDQUFDO0FBQ3BFLE9BQU8sRUFBYSxVQUFVLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDOzs7Ozs7Ozs7Ozs7OztBQUVoRjs7Ozs7Ozs7OztHQVVHO0FBQ0gsb0RBQW9EO0FBQ3BELE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUFDO0FBRWhDLG9GQUFvRjtBQUNwRixNQUFNLHVCQUF1QixHQUFHLElBQUksQ0FBQztBQThCckMsTUFBTSxPQUFPLHFCQUFxQjtJQUdoQzs7Ozs7T0FLRztJQUNILElBQWEsTUFBTSxDQUFDLEtBQWM7UUFDaEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2xCLEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQXdJRCw2RkFBNkY7SUFDckYsT0FBTztRQUNiLGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFNRCxZQUNxQyxTQUEyQixFQUN0RCxjQUE4QixFQUM5QixtQkFBd0MsRUFDeEMsV0FBcUMsRUFDckMsVUFBNkI7UUFKRixjQUFTLEdBQVQsU0FBUyxDQUFrQjtRQUN0RCxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxnQkFBVyxHQUFYLFdBQVcsQ0FBMEI7UUFDckMsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7UUFySi9CLGFBQVEsR0FBRyxJQUFJLENBQUM7UUFDeEIsc0ZBQXNGO1FBQ3JFLFNBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFckQsWUFBTyxHQUFhLEVBQUUsQ0FBQztRQUN2QixvQkFBZSxHQUFhLEVBQUUsQ0FBQztRQUkvQixzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFDMUIsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFDbEM7O3NFQUU4RDtRQUNwRCxvQkFBZSxHQUFxQixFQUFFLENBQUM7UUFDakQsd0ZBQXdGO1FBQzlFLGNBQVMsR0FBRyxFQUFFLENBQUM7UUFDZixpQkFBWSxHQUFHLEVBQUUsQ0FBQztRQUU1Qiw2Q0FBNkM7UUFDN0Msb0ZBQW9GO1FBQzFFLGNBQVMsR0FBYyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3BELHdGQUF3RjtRQUM5RSxnQkFBVyxHQUFrQixJQUFJLENBQUM7UUFDbEMscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ25DLHFGQUFxRjtRQUMzRSxnQkFBVyxHQUFxQixJQUFJLENBQUM7UUFDL0MsNEVBQTRFO1FBQ2xFLGdCQUFXLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDbEQscUZBQXFGO1FBQ2xFLHFCQUFnQixHQUFHLFFBQVEsQ0FBQztRQUMvQywrRUFBK0U7UUFDckUsbUJBQWMsR0FBa0IsRUFBRSxDQUFDO1FBRW5DLG1CQUFjLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ1YsdUJBQWtCLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3JEOzs7Z0RBR3dDO1FBQzlCLHdCQUFtQixHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBRWhELHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUNuQzs7OztXQUlHO1FBQ08sZUFBVSxHQUE0QixJQUFJLENBQUM7UUFDckQseUVBQXlFO1FBQ2pFLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLGlFQUFpRTtRQUN6RCxlQUFVLEdBQWEsRUFBRSxDQUFDO1FBQ2xDLDhDQUE4QztRQUN0QyxzQkFBaUIsR0FBMkIsRUFBRSxDQUFDO1FBQ3ZELHFFQUFxRTtRQUNwRCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztRQUMxQyxlQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZCLDhEQUE4RDtRQUN0RCxrQkFBYSxHQUFHLENBQUMsQ0FBQztRQUMxQjs2RUFDcUU7UUFDM0QsbUJBQWMsR0FBYyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3pELDhFQUE4RTtRQUNwRSxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUNoQyw0RUFBNEU7UUFDbEUsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUM3Qiw0RkFBNEY7UUFDcEYsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUMxQiw4RkFBOEY7UUFDcEYseUJBQW9CLEdBQUcsS0FBSyxDQUFDO1FBQ3ZDLHdGQUF3RjtRQUM5RSxZQUFPLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7UUFDaEQsNEZBQTRGO1FBQ3BGLGtCQUFhLEdBQXNCLEVBQUUsQ0FBQztRQUM5Qyw2REFBNkQ7UUFDbkQsa0JBQWEsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN6RCx3RUFBd0U7UUFDaEUsa0JBQWEsR0FBRyxFQUFFLENBQUM7UUFDM0IsdURBQXVEO1FBQy9DLGFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUM3QyxvRkFBb0Y7UUFDMUUsaUJBQVksR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN4RCxrRkFBa0Y7UUFDeEUsa0JBQWEsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN6RCw4RkFBOEY7UUFDcEYsa0JBQWEsR0FBRyxJQUFJLENBQUM7UUFDL0IsK0NBQStDO1FBQ3JDLGdCQUFXLEdBQWtCLElBQUksQ0FBQztRQUM1Qyw2RUFBNkU7UUFDbkUsZUFBVSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBQ2pELG9HQUFvRztRQUMxRixjQUFTLEdBQUcsQ0FBQyxJQUFZLEVBQVUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFFLG1CQUFjLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUNuQztpRkFDeUU7UUFDL0QsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUc3QixvRUFBb0U7UUFDbkQsaUJBQVksR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO1FBRTVDLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUN6QixtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUVwQix1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDM0IscUJBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQ2hDO3lFQUNpRTtRQUN2RCxhQUFRLEdBQWEsUUFBUSxDQUFDO1FBQ3hDO3VEQUMrQztRQUNyQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzNCLCtFQUErRTtRQUNyRSxpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUkvQjs7Ozs7V0FLRztRQUNPLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFFakIsd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQzVCLGlDQUE0QixHQUFHLEtBQUssQ0FBQztRQUM1QixlQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hDLFFBQUcsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNoQyxTQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBT3ZDO21FQUMyRDtRQUNqRCxRQUFHLEdBQWMsRUFBRSxDQUFDO1FBZ2Y5QiwrRkFBK0Y7UUFDckYsaUJBQVksR0FBOEMsSUFBSSxDQUFDO1FBQ3pFLDhFQUE4RTtRQUN0RSxrQkFBYSxHQUFHLENBQUMsQ0FBQztRQThDbEIsYUFBUSxHQUE2RSxFQUFFLENBQUM7UUFDeEYsVUFBSyxHQUFhLEVBQUUsQ0FBQztRQXViN0IsOENBQThDO1FBQ3BDLGNBQVMsR0FBRyxLQUFLLENBQUM7SUFsOUJ6QixDQUFDO0lBRUosUUFBUTtRQUNOLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNqRCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFL0MsMkVBQTJFO1FBQzNFLDJFQUEyRTtRQUMzRSwwRUFBMEU7UUFDMUUsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDO1FBQ3ZELElBQUksY0FBYztZQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDO1FBQ3BELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQztRQUNsRCxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDbkUsSUFBSSxHQUFHO29CQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDO2dCQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBWSxFQUFVLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDL0UsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7Z0JBQzVCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDakIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELHFFQUFxRTtRQUNyRSx5RUFBeUU7UUFDekUsOENBQThDO1FBQzlDLHFFQUFxRTtRQUNyRSw4RUFBOEU7UUFDOUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUU1Qix5RUFBeUU7UUFDekUsOERBQThEO1FBQzlELElBQUksQ0FBQyxTQUFTO2FBQ1gsb0JBQW9CLEVBQUU7YUFDdEIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUN6QyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxJQUFJLENBQUMsbUJBQW1CO2dCQUFFLE9BQU87WUFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1lBQzlFLHFFQUFxRTtZQUNyRSxvREFBb0Q7WUFDcEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNwRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFDNUIsSUFBSSxJQUFJLENBQUMsVUFBVTtnQkFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2YsS0FBSyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsU0FBUzthQUNYLG9CQUFvQixFQUFFLEVBQUU7WUFDekIsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xCLElBQUksSUFBSSxFQUFFLE1BQU0sS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU07Z0JBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7WUFDdEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFDdkIsS0FBSyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsU0FBUzthQUNYLGVBQWUsRUFBRSxFQUFFO1lBQ3BCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUMxQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNuQixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxTQUFTO2FBQ1gsY0FBYyxFQUFFLEVBQUU7WUFDbkIsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3BCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDbEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxRQUFRO2dCQUFFLEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUwsSUFBSSxDQUFDLFNBQVM7YUFDWCx3QkFBd0IsRUFBRSxFQUFFO1lBQzdCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUMxQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsT0FBTyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxTQUFTO2FBQ1gsZUFBZSxFQUFFLEVBQUU7WUFDcEIsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDbEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDdEIsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFFBQVE7Z0JBQUUsS0FBSyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDL0QsQ0FBQyxDQUFDLENBQUM7UUFFTCwyRUFBMkU7UUFDM0UsSUFBSSxDQUFDLFNBQVM7YUFDWCxtQkFBbUIsRUFBRSxFQUFFO1lBQ3hCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUMxQyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNwQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxTQUFTO2FBQ1gsaUJBQWlCLEVBQUUsRUFBRTtZQUN0QixFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDMUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDcEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUM7WUFDNUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBRUwsa0ZBQWtGO1FBQ2xGLElBQUksQ0FBQyxTQUFTO2FBQ1gsa0JBQWtCLEVBQUUsRUFBRTtZQUN2QixFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDMUMsU0FBUyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLFdBQVc7YUFDYixVQUFVLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQzthQUM3QixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ3pDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUM7WUFDL0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBRUwseUVBQXlFO1FBQ3pFLElBQUksQ0FBQyxTQUFTO2FBQ1gsWUFBWSxFQUFFO2FBQ2QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUN6QyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNsQixJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsU0FBUzthQUNYLG1CQUFtQixFQUFFO2FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDekMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDdEIsSUFBSSxJQUFJLENBQUMsNEJBQTRCO2dCQUFFLE9BQU87WUFDOUMsMkVBQTJFO1lBQzNFLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFHLE1BQU0sSUFBSSxHQUNSLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNO2dCQUMzQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJO2dCQUFFLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2hDLHFFQUFxRTtZQUNyRSxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRixJQUFJLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDakIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7b0JBQ2hGLElBQUksU0FBUyxLQUFLLElBQUksQ0FBQyxjQUFjO3dCQUFFLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO2dCQUN6RSxDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDsrRUFDMkU7SUFDM0UsV0FBVztRQUNULElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxrQkFBa0I7UUFDMUIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUM7UUFDNUMsMERBQTBEO1FBQzFELElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLDRCQUE0QixHQUFHLElBQUksQ0FBQztRQUN6QyxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25GLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksQ0FBQyw0QkFBNEIsR0FBRyxLQUFLLENBQUM7UUFDNUMsQ0FBQztRQUNELHNGQUFzRjtRQUN0RixJQUFJLFVBQVUsQ0FBQyxNQUFNO1lBQUUsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN0RyxDQUFDO0lBRUQsd0VBQXdFO0lBRXhFLG1HQUFtRztJQUNuRyxJQUFjLGVBQWU7UUFDM0IsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUMzQixDQUFDO0lBRUQsb0ZBQW9GO0lBQ3BGLElBQWMsVUFBVTtRQUN0QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDaEQsQ0FBQztJQUVELGlHQUFpRztJQUNqRyxJQUFjLGNBQWM7UUFDMUIsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQztJQUN4RCxDQUFDO0lBRUQsZ0ZBQWdGO0lBQ3RFLFdBQVcsQ0FBQyxHQUFXO1FBQy9CLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVPLFNBQVMsQ0FBQyxJQUFjO1FBQzlCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsdUVBQXVFO0lBQy9ELE9BQU8sQ0FBQyxHQUFtQjtRQUNqQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxFQUFFLEVBQUU7WUFDcEMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVTtZQUN0QixJQUFJLEVBQUUsR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsRUFBRTtZQUN6QixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssSUFBSSxTQUFTO1lBQzdCLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxVQUFVO1lBQ3BFLFFBQVEsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNoQixVQUFVLEVBQUUsR0FBRyxDQUFDLElBQUk7WUFDcEIsTUFBTSxFQUFFLElBQUk7U0FDYixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssS0FBSyxDQUFDLGFBQWE7UUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUMzQixNQUFNLE9BQU8sR0FBRyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDckMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUM3QixJQUFJLElBQUksR0FBcUIsRUFBRSxDQUFDO1FBQ2hDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLElBQUksTUFBTSxHQUEyQixFQUFFLENBQUM7UUFDeEMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQ2hELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQ2hDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNqRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDO2dCQUNILE1BQU0sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO29CQUN6QyxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssR0FBRyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUM7b0JBQ25FLElBQUksQ0FBQyxTQUFTLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO2lCQUM5RCxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxHQUFHLElBQUksRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUN4QixLQUFLLEdBQUcsSUFBSSxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7Z0JBQ3pCLE1BQU0sR0FBRyxRQUFRLElBQUksRUFBRSxDQUFDO1lBQzFCLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE9BQU8sQ0FBQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbEUsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDM0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztRQUNoQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVELDZGQUE2RjtJQUNyRixLQUFLLENBQUMsUUFBUSxDQUFDLEdBQVcsRUFBRSxJQUE4QjtRQUNoRSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQsdUZBQXVGO0lBQ3ZGLDhGQUE4RjtJQUNwRixtQkFBbUI7UUFDM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVTLFVBQVU7UUFDbEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQztJQUNqRyxDQUFDO0lBRUQ7OztPQUdHO0lBQ08sYUFBYSxDQUFDLElBQVksRUFBRSxVQUFvQixDQUFDLElBQUksQ0FBQztRQUM5RCxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztZQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7O1lBQ2pDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsNEVBQTRFO0lBQ2xFLGdCQUFnQixDQUFDLE9BQTBCLEVBQUUsTUFBZTtRQUNwRSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRCwrREFBK0Q7SUFDdkQsUUFBUTtRQUNkLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFO1lBQzlDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDOUIsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLE1BQU0sS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hHLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGlHQUFpRztJQUN6RixrQkFBa0I7UUFDeEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFDLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxFQUFFO1lBQUUsSUFBSSxDQUFDLENBQUMsS0FBSztnQkFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1RSxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7O09BR0c7SUFDSyx3QkFBd0I7UUFDOUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDeEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekcsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUFFLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDO1FBQy9GLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxRyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLElBQUksRUFBRSxLQUFLLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUN0QyxJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsU0FBUyxDQUFDLHdCQUF3QixFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELGtHQUFrRztJQUMxRixVQUFVLENBQUMsR0FBa0IsRUFBRSxRQUFpQjtRQUN0RCxJQUFJLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNqQixJQUFJLFFBQVE7Z0JBQUUsT0FBTztZQUNyQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztZQUN4QixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixPQUFPO1FBQ1QsQ0FBQztRQUNELEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQsZ0hBQWdIO0lBQ3hHLFNBQVM7UUFDZixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQUUsT0FBTztRQUN0RSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFTyxNQUFNLENBQUMsTUFBZ0U7UUFDN0UsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDekQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsR0FBSSxHQUFhLEVBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDOUYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0dBQWtHO0lBQ3hGLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBbUI7UUFDN0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUMzRyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssaUJBQWlCLENBQUMsT0FBaUI7UUFDekMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzdELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQzVCLE1BQU0sQ0FBQyxLQUFLO1lBQ1YsQ0FBQyxDQUFDLE1BQU07WUFDUixDQUFDLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQy9GLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNLLE1BQU0sQ0FBQyxPQUFpQixJQUFJLENBQUMsT0FBTztRQUMxQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2hDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2RixDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQ25DLENBQUM7UUFDRCxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ssWUFBWSxDQUFDLFFBQStDO1FBQ2xFLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBQ3pDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNwQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxDQUFDLENBQUM7WUFDckIsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2QyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNwQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25GLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdHLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELDhFQUE4RTtJQUNwRSxpQkFBaUIsQ0FBQyxNQUFjLEVBQUUsS0FBYTtRQUN2RCxJQUFJLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssS0FBSztZQUFFLE9BQU87UUFDN0MsaUdBQWlHO1FBQ2pHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ25GLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNPLGlCQUFpQixDQUFDLE1BQWMsRUFBRSxNQUFNLEdBQUcsS0FBSztRQUN4RCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxNQUFNO1lBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxzRUFBc0U7SUFDOUQsZUFBZTtRQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2pHLENBQUM7SUFFRDtnRkFDNEU7SUFDNUUsSUFBYyxZQUFZO1FBQ3hCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDMUIsSUFDRSxHQUFHLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxPQUFPO1lBQzVCLEdBQUcsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLFVBQVU7WUFDOUIsR0FBRyxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsY0FBYztZQUNqQyxHQUFHLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxhQUFhLEVBQy9CLENBQUM7WUFDRCxJQUFJLENBQUMsUUFBUSxHQUFHO2dCQUNkLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztnQkFDckIsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUN2QixLQUFLLEVBQUUsSUFBSSxDQUFDLGNBQWM7Z0JBQzFCLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYTthQUN6QixDQUFDO1lBQ0YsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM5RixJQUFJLENBQUMsS0FBSztnQkFDUixHQUFHLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxhQUFhO29CQUM5QixDQUFDLENBQUMsR0FBRztvQkFDTCxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsYUFBYSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzdFLGdGQUFnRjtZQUNoRixJQUFJLElBQUksQ0FBQyxVQUFVO2dCQUFFLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUNuRSxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFPRCxxRkFBcUY7SUFDN0UsY0FBYztRQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pFLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDN0IsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2dCQUN6QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsQ0FBQztZQUNELE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLEdBQUcsRUFBeUIsQ0FBQztRQUNwRSxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUYsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFlBQVk7WUFBRSxPQUFPO1FBQ2pELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQWtCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxRixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07WUFBRSxPQUFPO1FBQzVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDbkMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FDZixDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ1YsSUFBSSxPQUFPLEtBQUssSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZO2dCQUFFLE9BQU87WUFDakUsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hGLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDLEVBQ0QsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNOLElBQUksT0FBTyxLQUFLLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWTtnQkFBRSxPQUFPO1lBQ2pFLDBEQUEwRDtZQUMxRCxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDeEMsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPO2dCQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQywyQ0FBMkMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNqRSxDQUFDLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCw4RkFBOEY7SUFDdEYsWUFBWTtRQUNsQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFJUyxZQUFZLENBQUMsS0FBd0M7UUFDN0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUN0RCxLQUFLLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQsZ0dBQWdHO0lBQ3RGLEtBQUssQ0FBQyxnQkFBZ0I7UUFDOUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0I7WUFBRSxPQUFPO1FBQ3RFLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQztRQUN0RyxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEQsSUFBSSxHQUFHLENBQUMsTUFBTTtZQUFFLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRVMscUJBQXFCO1FBQzdCLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1RSxJQUFJLFVBQVUsQ0FBQyxNQUFNO2dCQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDekYsa0VBQWtFO1lBQ2xFLHNEQUFzRDtZQUN0RCxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDM0IsOERBQThEO1lBQzlELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0lBRVMsZUFBZTtRQUN2QixJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDO1lBQy9CLEdBQUcsRUFBRSxnQkFBZ0I7WUFDckIsT0FBTyxFQUFFLDhDQUE4QztZQUN2RCxNQUFNLEVBQUUsR0FBRyxFQUFFO2dCQUNYLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO2dCQUMxQixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQzFCLElBQUksSUFBSSxDQUFDLGVBQWU7b0JBQUUsS0FBSyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztZQUNoRSxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDJGQUEyRjtJQUNuRixLQUFLLENBQUMsdUJBQXVCO1FBQ25DLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUM7UUFDbEQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CO1lBQUUsT0FBTztRQUMzRCxNQUFNLElBQUksR0FBRyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7UUFDN0YsSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6RixDQUFDO0lBRVMsWUFBWSxDQUFDLFFBQWdCO1FBQ3JDLHlFQUF5RTtRQUN6RSxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3BDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDM0YsSUFBSSxHQUFHO2dCQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RFLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2QyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakYsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQix5RUFBeUU7UUFDekUsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFTyxtQkFBbUI7UUFDekIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMxRyxJQUFJLElBQUksQ0FBQyxjQUFjLEdBQUcsUUFBUSxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFDUyxvQkFBb0IsQ0FBQyxTQUFrQjtRQUMvQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVTLGNBQWMsQ0FBQyxNQUFjO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRVMsY0FBYyxDQUFDLE1BQWMsRUFBRSxLQUFhO1FBQ3BELEtBQUssRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDLDZCQUE2QjtRQUN2RCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDOUIsS0FBSyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFELE9BQU87UUFDVCxDQUFDO1FBQ0QsaUVBQWlFO1FBQ2pFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUVELDJFQUEyRTtJQUNqRSxhQUFhLENBQUMsTUFBYyxFQUFFLEtBQWE7UUFDbkQsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFUyxhQUFhLENBQUMsTUFBYyxFQUFFLE1BQWUsRUFBRSxLQUFhO1FBQ3BFLEtBQUssRUFBRSxlQUFlLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztRQUNsQyxDQUFDO1FBQ0QsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNYLDZFQUE2RTtZQUM3RSxNQUFNLE1BQU0sR0FDVixLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxNQUFNLENBQUMsS0FBSztnQkFDM0MsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDO2dCQUM1RixDQUFDLENBQUMsTUFBTSxDQUFDO1lBQ2IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN2QyxDQUFDO0lBQ0gsQ0FBQztJQUVEOytEQUMyRDtJQUNqRCxVQUFVLENBQUMsTUFBYztRQUNqQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRDs7T0FFRztJQUNPLHFCQUFxQjtRQUM3QixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDM0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUMzQixJQUFJLENBQUMsQ0FBQyxJQUFJLFlBQVksU0FBUyxDQUFDO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQzlDLE9BQU87Z0JBQ0wsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUU7b0JBQzNDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRztvQkFDM0MsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHO2lCQUMxQyxDQUFDO2FBQ0gsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFUyxRQUFRO1FBQ2hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVEOztvRkFFZ0Y7SUFDdEUsZUFBZTtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxNQUFNO1lBQUUsT0FBTztRQUMxQyxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUM5QyxLQUFLLE1BQU0sTUFBTSxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMxQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUN6QyxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO2dCQUFFLFNBQVM7WUFDckMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDL0YsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztJQUM5QixDQUFDO0lBRUQ7OENBQzBDO0lBQ2hDLG9CQUFvQixDQUFDLFFBQTBCLElBQUksQ0FBQyxlQUFlO1FBQzNFLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25FLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksRUFBRSxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUN2QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUN6QyxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxLQUFLO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQ3hCLGtFQUFrRTtZQUNsRSxPQUFPLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQy9CLENBQUM7SUFFRCx3RUFBd0U7SUFFeEUsNkZBQTZGO0lBQ25GLFlBQVksQ0FBQyxJQUFhO1FBQ2xDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN0RSxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNLLHNCQUFzQixDQUFDLE9BQWlCO1FBQzlDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxRCxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDaEMsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUN4QixNQUFNLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxLQUFLLFFBQVE7Z0JBQUUsU0FBUztZQUMzQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUFFLFNBQVM7WUFDM0MsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNiLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO2dCQUN6QixJQUFJLEVBQUUsS0FBSztnQkFDWCxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxhQUFhLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQ3RELE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFRCx3RUFBd0U7SUFFeEU7OztPQUdHO0lBQ0gsSUFBWSxXQUFXO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDNUMsQ0FBQztJQUVELDZGQUE2RjtJQUNyRixvQkFBb0I7UUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDdkMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFhLEVBQUUsQ0FBUyxFQUFFLEVBQUU7WUFDdkMsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUM7UUFDRixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDN0YsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPO1lBQUUsSUFBSSxDQUFDLENBQUMsS0FBSztnQkFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN0RCw4RUFBOEU7UUFDOUUsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDO1lBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQ7OERBQzBEO0lBQ2xELG9CQUFvQjtRQUMxQixNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUYsTUFBTSxVQUFVLEdBQWtCLEVBQUUsQ0FBQztRQUNyQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztZQUN4RCxNQUFNLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUFFLFNBQVM7WUFDM0IsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNiLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEYsQ0FBQztRQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsVUFBVSxDQUFDLE1BQU07WUFDckMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxVQUFVLENBQUMsRUFBRTtZQUM1RSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM3RSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1RCxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtGQUFrRjtJQUN4RSxVQUFVLENBQUMsSUFBWTtRQUMvQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRCx1RkFBdUY7SUFDN0UsYUFBYSxDQUFDLElBQVksRUFBRSxLQUFhO1FBQ2pELElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLHNCQUFzQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVEOztnRUFFNEQ7SUFDbEQsV0FBVyxDQUFDLElBQVk7UUFDaEMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssSUFBSTtZQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQ7O3lGQUVxRjtJQUM3RSw2QkFBNkIsQ0FBQyxZQUFzQjtRQUMxRCxNQUFNLEtBQUssR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUMxQixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDdEIsQ0FBQyxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtZQUNqRSxDQUFDLENBQUMsSUFBSSxDQUNULENBQUM7SUFDSixDQUFDO0lBRUQ7a0ZBQzhFO0lBQ3BFLG1CQUFtQixDQUFDLE1BQWMsRUFBRSxTQUFpQjtRQUM3RCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDOUIsS0FBSyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQzFFLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEMsTUFBTSxLQUFLLEdBQW9CLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDdkUsSUFBSSxJQUFJO1lBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVEO29DQUNnQztJQUN0QixpQkFBaUIsQ0FBQyxJQUFZO1FBQ3RDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsMEZBQTBGO0lBQ2xGLG9CQUFvQixDQUFDLElBQVk7UUFDdkMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBQzNCLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDcEcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRCw2RUFBNkU7SUFDbkUsY0FBYztRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPO1FBQzVCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQseUZBQXlGO0lBQy9FLG9CQUFvQjtRQUM1QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUM3RixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkcsQ0FBQztRQUNELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCw4QkFBOEI7SUFDcEIsZ0JBQWdCO1FBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztJQUMvQixDQUFDO0lBQ08sY0FBYyxDQUFDLENBQVk7UUFDakMsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELGVBQWUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsZUFBZSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQy9DLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVc7WUFDNUIsU0FBUyxFQUFFLENBQUMsQ0FBQyxTQUFTLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLE9BQU87U0FDakUsQ0FBQztJQUNKLENBQUM7SUFDRDsyREFDdUQ7SUFDN0MsaUJBQWlCLENBQUMsS0FBYztRQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPO1FBQzlCLCtFQUErRTtRQUMvRSw2RUFBNkU7UUFDN0UsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUMvQixNQUFNLEtBQUssR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQy9CLE1BQU0sT0FBTyxHQUFrQixFQUFFLENBQUM7UUFDbEMsS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ25DLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QixJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO2dCQUFFLFNBQVM7WUFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNkLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsR0FBRyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDekMsOEVBQThFO1FBQzlFLDBFQUEwRTtRQUMxRSxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdGLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsa0VBQWtFO1FBQ2pGLElBQUksS0FBSztZQUFFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7SUFDM0MsQ0FBQztJQUNTLHNCQUFzQjtRQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFDUyxhQUFhO1FBQ3JCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pGLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLENBQUMsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFDUyxhQUFhLENBQUMsS0FBWTtRQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFFRCxtRUFBbUU7SUFDM0Qsb0JBQW9CLENBQUMsSUFBWTtRQUN2QyxJQUFJLENBQUM7WUFDSCxNQUFNLEdBQUcsR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxHQUFHO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztZQUMxRixJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ3RFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO2dCQUN0QixHQUFHLEVBQUUsYUFBYTtnQkFDbEIsUUFBUSxFQUFFLFNBQVM7Z0JBQ25CLE9BQU8sRUFBRSxrQkFBa0I7Z0JBQzNCLE1BQU0sRUFBRSw0QkFBNEI7YUFDckMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztnQkFDdEIsR0FBRyxFQUFFLGFBQWE7Z0JBQ2xCLFFBQVEsRUFBRSxPQUFPO2dCQUNqQixPQUFPLEVBQUUsZUFBZTtnQkFDeEIsTUFBTSxFQUFFLEdBQUksR0FBYSxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUU7YUFDNUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQ7NkNBQ3lDO0lBQy9CLFVBQVUsQ0FBQyxLQUFZO1FBQy9CLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUUsS0FBSyxDQUFDLE1BQTJCLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLElBQUksS0FBSyxDQUFDLE1BQU07WUFBRSxLQUFLLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxrQkFBa0IsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pILENBQUM7SUFFRCxzRkFBc0Y7SUFDdEYsSUFBYyxtQkFBbUI7UUFDL0IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLENBQUM7SUFDakQsQ0FBQztJQUlELGlIQUFpSDtJQUN2RyxnQkFBZ0I7UUFDeEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLFNBQVMsQ0FBQztZQUM3QyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDYixJQUFJLENBQUMsSUFBSTtvQkFBRSxPQUFPO2dCQUNsQixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7b0JBQzFCLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUMvRSxPQUFPO2dCQUNULENBQUM7Z0JBQ0QsS0FBSyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkQsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUM7WUFDdEMsUUFBUSxFQUFFLEdBQUcsRUFBRTtnQkFDYixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDdkIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxLQUFLLENBQUMsaUJBQWlCLENBQUMsS0FBeUI7UUFDdkQsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLFlBQVksQ0FDZixJQUFJLEtBQUssQ0FBQyw2RkFBNkYsQ0FBQyxDQUN6RyxDQUFDO1lBQ0YsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDckQsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLHdCQUF3QixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDLENBQUM7WUFDeEUsT0FBTztRQUNULENBQUM7UUFDRCw2RkFBNkY7UUFDN0YsK0RBQStEO1FBQy9ELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO1FBQ3JELElBQUksQ0FBQztZQUNILE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUE4QixDQUFDO1lBQ3RELElBQUksT0FBZSxDQUFDO1lBQ3BCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDM0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7Z0JBQ2xGLE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDakcsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDdkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsdUJBQXVCLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZGLENBQUM7Z0JBQ0QsT0FBTyxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sY0FBYyxNQUFNLENBQUMsS0FBSyxNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDMUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQ2xGLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsdUJBQXVCLENBQUMsTUFBTSxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUMvRixDQUFDO2dCQUNGLE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxjQUFjLENBQUM7WUFDaEQsQ0FBQztZQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDekMsSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbkIsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsS0FBSyxDQUNSLFNBQVMsRUFDVCxrQkFBa0IsRUFDbEIsR0FBRyxPQUFPLEtBQUssUUFBUSxTQUFTLFFBQVEsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxhQUFhLENBQ3ZFLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekIsQ0FBQztJQUNILENBQUM7SUFFRCx5R0FBeUc7SUFDakcsS0FBSyxDQUFDLHFCQUFxQixDQUFDLEdBQVcsRUFBRSxJQUFhO1FBQzVELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuRixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDLENBQUM7WUFDeEUsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztRQUNyRCxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLFlBQVksQ0FDaEMsR0FBRyxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUyxFQUFFLENBQUMsRUFDakUsTUFBTSxDQUNQLENBQUM7WUFDRixJQUFJLE9BQU8sS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDdEIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNuQixPQUFPO1lBQ1QsQ0FBQztZQUNELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGtCQUFrQixFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekIsQ0FBQztJQUNILENBQUM7SUFFRCxnR0FBZ0c7SUFDeEYsV0FBVztRQUNqQixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxzREFBc0QsQ0FBQyxDQUFDO1FBQy9GLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQsbUZBQW1GO0lBQzNFLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxrR0FBa0c7SUFDMUYsaUJBQWlCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDckQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQy9DLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzdELElBQUksQ0FBQyxLQUFLLENBQ1IsTUFBTSxFQUNOLGdCQUFnQixFQUNoQiwyQkFBMkIsS0FBSyxNQUFNLE1BQU0sa0JBQWtCLElBQUksQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUM3RixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTyxZQUFZLENBQUMsR0FBWTtRQUMvQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztZQUN0QixHQUFHLEVBQUUsYUFBYTtZQUNsQixRQUFRLEVBQUUsT0FBTztZQUNqQixPQUFPLEVBQUUseUJBQXlCO1lBQ2xDLE1BQU0sRUFBRSxHQUFJLEdBQWEsRUFBRSxPQUFPLElBQUksR0FBRyxFQUFFO1NBQzVDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQVk7UUFDMUMsSUFBSSxDQUFDO1lBQ0gsSUFBSSxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNwRCxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztnQkFDMUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2hCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUMxQixPQUFPO1lBQ1QsQ0FBQztZQUNELG9FQUFvRTtZQUNwRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuRCxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztnQkFDdEIsR0FBRyxFQUFFLGFBQWE7Z0JBQ2xCLFFBQVEsRUFBRSxPQUFPO2dCQUNqQixPQUFPLEVBQUUsMEJBQTBCO2dCQUNuQyxNQUFNLEVBQUUsR0FBSSxHQUFhLEVBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRTthQUM1QyxDQUFDLENBQUM7WUFDSCxPQUFPLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDO0lBRUQsZ0ZBQWdGO0lBQ3hFLGNBQWM7UUFDcEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVTLFVBQVU7UUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZTtZQUFFLE9BQU87UUFDbkUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDM0QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRVMsYUFBYTtRQUNyQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzVDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUFFLE9BQU87UUFDcEUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztRQUM5QixJQUFJLENBQUMsV0FBVzthQUNiLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDO2FBQzNCLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsR0FBSSxHQUFhLEVBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6RyxDQUFDO0lBRUQsd0VBQXdFO0lBQzlELGtCQUFrQjtRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUNqQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUMzRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNPLGVBQWU7UUFDdkIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFFL0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxTQUFTLENBQUMsMERBQTBELENBQUMsQ0FBQztZQUMzRSxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVU7YUFDM0IsTUFBTSxDQUFDO1lBQ04sT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLFNBQVMsRUFBRSxJQUFJO1lBQ2YsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFO1NBQ2hELENBQUM7YUFDRCxTQUFTLENBQUM7WUFDVCxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDVixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2YsUUFBUSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ2YsS0FBSyxTQUFTO3dCQUNaLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQzs0QkFDaEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUM7Z0NBQ3RCLEdBQUcsRUFBRSxhQUFhO2dDQUNsQixRQUFRLEVBQUUsTUFBTTtnQ0FDaEIsT0FBTyxFQUFFLGlCQUFpQjtnQ0FDMUIsTUFBTSxFQUFFLHlEQUF5RCxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxNQUFNLEdBQUc7NkJBQ3hGLENBQUMsQ0FBQzt3QkFDTCxDQUFDO3dCQUNELE1BQU07b0JBQ1IsS0FBSyxVQUFVO3dCQUNiLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQzt3QkFDOUIsTUFBTTtvQkFDUixLQUFLLFVBQVU7d0JBQ2IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7d0JBQ3pCLE1BQU07b0JBQ1IsS0FBSyxNQUFNO3dCQUNULElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQzt3QkFDbEMsTUFBTTtnQkFDVixDQUFDO1lBQ0gsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEdBQVUsRUFBRSxFQUFFO2dCQUNwQixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLENBQUM7U0FDRixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsaUZBQWlGO0lBQ3ZFLGNBQWM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBRU8sVUFBVSxDQUFDLElBQVUsRUFBRSxRQUFnQjtRQUM3QyxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVPLFNBQVMsQ0FBQyxNQUFjO1FBQzlCLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO1lBQ3RCLEdBQUcsRUFBRSxhQUFhO1lBQ2xCLFFBQVEsRUFBRSxPQUFPO1lBQ2pCLE9BQU8sRUFBRSx1QkFBdUI7WUFDaEMsTUFBTTtTQUNQLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxjQUFjO1FBQ3RCLHdFQUF3RTtRQUN4RSwyREFBMkQ7UUFDM0QsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNwRCxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUFFLE9BQU87UUFFbEYsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7UUFDL0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztRQUM5QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7O29GQUVnRjtJQUN4RSxLQUFLLENBQUMsZUFBZTtRQUMzQixJQUFJLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUM1QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLE1BQXNCLENBQUM7UUFDM0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNsRCxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLEdBQUksR0FBYSxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLE9BQU87UUFDVCxDQUFDO1FBQ0QsOERBQThEO1FBQzlELElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ3hCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDOUQsSUFBSSxFQUFFLEdBQUcsRUFBRTtnQkFDVCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxLQUFLLENBQ1IsU0FBUyxFQUNULGVBQWUsRUFDZixrQkFBa0IsTUFBTSxDQUFDLE1BQU0sU0FBUyxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FDekUsQ0FBQztZQUNKLENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDYixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLEdBQUksR0FBYSxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ25GLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMscUJBQXFCO1FBQzdCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRVMsYUFBYTtRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRTtZQUFFLE9BQU87UUFFakQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM1QyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFFdEIseUVBQXlFO1FBQ3pFLHVEQUF1RDtRQUN2RCxNQUFNLE1BQU0sR0FBRyxHQUFHLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFDdkIsZ0ZBQWdGO1lBQ2hGLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVc7aUJBQy9CLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxDQUFDO2lCQUMzQyxTQUFTLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLEdBQUcsRUFBRTtvQkFDVCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztvQkFDeEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztvQkFDOUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGVBQWUsRUFBRSxZQUFZLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ2pFLENBQUM7Z0JBQ0QsS0FBSyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ2IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7b0JBQ3hCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDZixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxHQUFJLEdBQWEsRUFBRSxPQUFPLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDbkYsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQztRQUVGLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQztnQkFDL0IsT0FBTyxFQUFFLElBQUksUUFBUSxnREFBZ0Q7Z0JBQ3JFLE1BQU0sRUFBRSxtQkFBbUI7Z0JBQzNCLElBQUksRUFBRSw0QkFBNEI7Z0JBQ2xDLE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLEVBQUUsQ0FBQztRQUNYLENBQUM7SUFDSCxDQUFDO0lBRUQ7aURBQzZDO0lBQ25DLFlBQVk7UUFDcEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztRQUM1QixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztJQUMxQixDQUFDO0lBRU8sS0FBSyxDQUFDLFFBQXNDLEVBQUUsT0FBZSxFQUFFLE1BQWM7UUFDbkYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUM3RSxDQUFDOzhHQXpnRFUscUJBQXFCLGtCQWtLdEIsaUJBQWlCO2tHQWxLaEIscUJBQXFCLDBGQUZyQixDQUFDLHdCQUF3QixDQUFDLDhIQ3ZHdkMsZ3BaQW9ZQSw2K0JEblRJLFlBQVksa0lBQ1osV0FBVyw4bUJBQ1gsWUFBWSxxSUFDWixZQUFZLDJrQkFDWixtQkFBbUIsb21CQUNuQixjQUFjLHV0Q0FDZCxlQUFlLHdIQUNmLGtCQUFrQixtV0FDbEIsYUFBYSxrSkFDYixhQUFhLHVYQUNiLHFCQUFxQixnVUFDckIsb0JBQW9CLDJWQUNwQixrQkFBa0IsbU5BQ2xCLDBCQUEwQix5UEFDMUIsdUJBQXVCLG9PQUN2QiwwQkFBMEIsb0pBQzFCLDRCQUE0QixvTUFDNUIseUJBQXlCOzsyRkFPaEIscUJBQXFCO2tCQTVCakMsU0FBUzsrQkFDRSxlQUFlLGNBQ2IsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxZQUFZO3dCQUNaLFlBQVk7d0JBQ1osbUJBQW1CO3dCQUNuQixjQUFjO3dCQUNkLGVBQWU7d0JBQ2Ysa0JBQWtCO3dCQUNsQixhQUFhO3dCQUNiLGFBQWE7d0JBQ2IscUJBQXFCO3dCQUNyQixvQkFBb0I7d0JBQ3BCLGtCQUFrQjt3QkFDbEIsMEJBQTBCO3dCQUMxQix1QkFBdUI7d0JBQ3ZCLDBCQUEwQjt3QkFDMUIsNEJBQTRCO3dCQUM1Qix5QkFBeUI7cUJBQzFCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNLGFBQ3BDLENBQUMsd0JBQXdCLENBQUM7OzBCQW9LbEMsTUFBTTsyQkFBQyxpQkFBaUI7K0tBaktGLFlBQVk7c0JBQXBDLFNBQVM7dUJBQUMsSUFBSTtnQkFRRixNQUFNO3NCQUFsQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBWaWV3Q2hpbGQsXG4gIGluamVjdCxcbiAgTmdab25lLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IG1hcmtGb3JDaGVja0luWm9uZSB9IGZyb20gJy4uL3V0aWwvbWFyay1mb3ItY2hlY2snO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgQ29uZmlybURpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY29uZmlybWRpYWxvZyc7XG5pbXBvcnQgeyBEcm9wZG93bk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZHJvcGRvd24nO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuaW1wb3J0IHsgT3ZlcmxheVBhbmVsLCBPdmVybGF5UGFuZWxNb2R1bGUgfSBmcm9tICdwcmltZW5nL292ZXJsYXlwYW5lbCc7XG5pbXBvcnQgeyBUb29sYmFyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sYmFyJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuaW1wb3J0IHsgc2F2ZUFzIH0gZnJvbSAnZmlsZS1zYXZlcic7XG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUmVjdGFuZ2xlLCBSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IHdpdGhSZWdpb25QYXRjaCB9IGZyb20gJy4uL21vZGVscy9yZWdpb24tY2xvbmUnO1xuaW1wb3J0IHsgUHJlc2V0U2V0LCBDbGFzc1ByZXNldCwgZGVmYXVsdFByZXNldFNldCwgcGFyc2VQcmVzZXRTZXQgfSBmcm9tICcuLi9tb2RlbHMvY2xhc3MtcHJlc2V0JztcbmltcG9ydCB7IGNvbG9yRm9yTGFiZWwsIHByZXNldEtleSB9IGZyb20gJy4uL3N0b3JlL2NsYXNzLWNvbG9yLnV0aWwnO1xuaW1wb3J0IHsgQ29uZmlybWF0aW9uU2VydmljZSwgTWVzc2FnZVNlcnZpY2UsIFNoYXJlZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IElSZWdpb25FZGl0b3JBcGksIFJFR0lPTl9FRElUT1JfQVBJIH0gZnJvbSAnLi4vY29udHJhY3RzL3JlZ2lvbi1lZGl0b3ItYXBpLmNvbnRyYWN0JztcbmltcG9ydCB7IFZJWl9UT0FTVF9LRVkgfSBmcm9tICcuLi90b2FzdC1vdXRsZXRzJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgdHlwZSB7IFJlZ2lvblNvdXJjZU9wZW5lciB9IGZyb20gJy4uL3N0b3JlL3JlZ2lvbi1zb3VyY2Utc2NvcGUnO1xuaW1wb3J0IHsgb3Blbkdlb0pzb25SZWdpb25Tb3VyY2UgfSBmcm9tICcuLi9yZWdpb24tc291cmNlL3dvcmtlci1yZWdpb24tc291cmNlJztcbmltcG9ydCB7IG9wZW5IdHRwUmVnaW9uU291cmNlIH0gZnJvbSAnLi4vcmVnaW9uLXNvdXJjZS9odHRwLXJlZ2lvbi1zb3VyY2UnO1xuaW1wb3J0IHsgcmVhZExhYmVsVm9sdW1lIH0gZnJvbSAnLi4vcmVnaW9uLWltcG9ydC9sYWJlbC12b2x1bWUnO1xuaW1wb3J0IHsgbGFiZWxDbGFzc2VzLCBsYWJlbFNsaWNlR2VvSnNvbiB9IGZyb20gJy4uL3JlZ2lvbi1pbXBvcnQvbGFiZWwtY2xhc3Nlcyc7XG5pbXBvcnQge1xuICBSZWdpb25JbXBvcnRGaWxlLFxuICBmb2xkZXJTbGljZUdlb0pzb24sXG4gIGltcG9ydEZpbGUsXG4gIHBsYW5SZWdpb25JbXBvcnQsXG59IGZyb20gJy4uL3JlZ2lvbi1pbXBvcnQvcmVnaW9uLWltcG9ydCc7XG5pbXBvcnQgeyBSZWdpb25QZXJzaXN0ZW5jZVNlcnZpY2UsIFNsaWNlR2VvSnNvbiB9IGZyb20gJy4vcmVnaW9uLXBlcnNpc3RlbmNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2xhc3NDb2xvckVkaXQsIFJlZ2lvbkNvbG9yRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tY29sb3ItZGlhbG9nL3JlZ2lvbi1jb2xvci1kaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7IENsYXNzZXNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vY2xhc3Nlcy1wYW5lbC9jbGFzc2VzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWdpb25UYWJsZUNvbXBvbmVudCB9IGZyb20gJy4vcmVnaW9uLXRhYmxlL3JlZ2lvbi10YWJsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2xhc3NUcmVlQ29tcG9uZW50LCBDbGFzc1RyZWVQaWNrIH0gZnJvbSAnLi9jbGFzcy10cmVlL2NsYXNzLXRyZWUuY29tcG9uZW50JztcbmltcG9ydCB0eXBlIHsgUmVnaW9uU291cmNlVmlldyB9IGZyb20gJy4uL3JlZ2lvbi1zb3VyY2UvcmVnaW9uLXNvdXJjZSc7XG5pbXBvcnQgdHlwZSB7IFJlZ2lvbkNsYXNzTm9kZSwgUmVnaW9uSW5kZXhSb3cgfSBmcm9tICcuLi9yZWdpb24tc291cmNlL3JlZ2lvbi10aWxlcyc7XG5pbXBvcnQgeyBTYXZlUmVnaW9uc0RpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4vc2F2ZS1yZWdpb25zLWRpYWxvZy9zYXZlLXJlZ2lvbnMtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTYXZlTWFza0RpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4vc2F2ZS1tYXNrLWRpYWxvZy9zYXZlLW1hc2stZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYW5hZ2VDbGFzc2VzRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi9tYW5hZ2UtY2xhc3Nlcy1kaWFsb2cvbWFuYWdlLWNsYXNzZXMtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWdpb25FZGl0b3JIZWxwQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tZWRpdG9yLWhlbHAvcmVnaW9uLWVkaXRvci1oZWxwLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYXNrRXhwb3J0U2VydmljZSwgTWFza01vZGUgfSBmcm9tICcuL21hc2stZXhwb3J0LnNlcnZpY2UnO1xuaW1wb3J0IHsgUGl4ZWxTaXplLCBmb3JtYXRBcmVhLCBwaWNrTXBwLCByZWdpb25BcmVhUHggfSBmcm9tICcuL3JlZ2lvbi1tZXRyaWNzJztcblxuLyoqXG4gKiBUaGUgUmVnaW9uIEVkaXRvciAoYDxyZWdpb24tZWRpdG9yPmApOiB0aGUgdGFibGUgb2YgdGhlIGFjdGl2ZSBpbWFnZSdzXG4gKiBhbm5vdGF0aW9uIHJlZ2lvbnMgd2l0aCBjbGFzcyBwcmVzZXRzLCBjb2xvdXJzLCBsYWJlbHMsIEdlb0pTT04gaW1wb3J0IC9cbiAqIGV4cG9ydCAvIHNlcnZlciBzYXZlIGFuZCBtYXNrIGV4cG9ydC4gU2VsZi1jb250YWluZWQ6IGl0IHRhbGtzIHRvIHRoZSB2aWV3ZXJcbiAqIG9ubHkgdGhyb3VnaCB7QGxpbmsgUkVHSU9OX0VESVRPUl9BUEl9IChhbmQgdGhlIGhvc3QncyBSRUdJT05fSU9fUE9SVCksIHNvIGl0XG4gKiBoYXMgbm8gaW5wdXRzIG9yIG91dHB1dHMuXG4gKlxuICogT25QdXNoOiB0ZW1wbGF0ZSBldmVudHMgcmUtcmVuZGVyIGl0OyBzdGF0ZSB0aGF0IGxhbmRzIGFzeW5jaHJvbm91c2x5ICh0aGVcbiAqIEFQSSdzIHJlZ2lvbiAvIHNlbGVjdGlvbiAvIHByZXNldCAvIGltYWdlLW1ldGEgc3RyZWFtcywgc2F2ZSBhbmQgbWFzay1leHBvcnRcbiAqIHByb2dyZXNzLCBmaWxlIHJlYWRzKSBtYXJrcyBpdCBmb3IgY2hlY2suXG4gKi9cbi8qKiBUaGUgb3BhY2l0eSB0aGUgZmlsbCB0b2dnbGUgZmlsbHMgcmVnaW9ucyBhdC4gKi9cbmNvbnN0IFJFR0lPTl9GSUxMX09QQUNJVFkgPSAwLjY7XG5cbi8qKiBcIlNlbGVjdCBhbGxcIiB0YWtlcyBhdCBtb3N0IHRoaXMgbWFueSByZWdpb24tc291cmNlIGZlYXR1cmVzIGludG8gdGhlIHJlZ2lvbnMuICovXG5jb25zdCBTRUxFQ1RfQUxMX1NPVVJDRV9MSU1JVCA9IDUwMDA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JlZ2lvbi1lZGl0b3InLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFNoYXJlZE1vZHVsZSxcbiAgICBCdXR0b25Nb2R1bGUsXG4gICAgQ29uZmlybURpYWxvZ01vZHVsZSxcbiAgICBEcm9wZG93bk1vZHVsZSxcbiAgICBJbnB1dFRleHRNb2R1bGUsXG4gICAgT3ZlcmxheVBhbmVsTW9kdWxlLFxuICAgIFRvb2xiYXJNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBDbGFzc2VzUGFuZWxDb21wb25lbnQsXG4gICAgUmVnaW9uVGFibGVDb21wb25lbnQsXG4gICAgQ2xhc3NUcmVlQ29tcG9uZW50LFxuICAgIFNhdmVSZWdpb25zRGlhbG9nQ29tcG9uZW50LFxuICAgIFNhdmVNYXNrRGlhbG9nQ29tcG9uZW50LFxuICAgIFJlZ2lvbkNvbG9yRGlhbG9nQ29tcG9uZW50LFxuICAgIE1hbmFnZUNsYXNzZXNEaWFsb2dDb21wb25lbnQsXG4gICAgUmVnaW9uRWRpdG9ySGVscENvbXBvbmVudCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3JlZ2lvbi1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9yZWdpb24tZWRpdG9yLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtSZWdpb25QZXJzaXN0ZW5jZVNlcnZpY2VdLFxufSlcbmV4cG9ydCBjbGFzcyBSZWdpb25FZGl0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBWaWV3Q2hpbGQoJ29wJykgcHJpdmF0ZSBvdmVybGF5UGFuZWwhOiBPdmVybGF5UGFuZWw7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGVkaXRvciBpcyBvbiBzY3JlZW4gKGl0cyBkaWFsb2cgb3BlbikuIENsb3NlZCwgaXQgYXNrcyB0aGUgcmVnaW9uIHNvdXJjZSBub3RoaW5nOlxuICAgKiBpdHMgcGFnZSBvZiBmZWF0dXJlcywgaXRzIGNsYXNzIGNvdW50cyBhbmQsIGluIGEgdm9sdW1lIHZpZXcsIGl0cyBjbGFzc2VzJyB2b2x1bWVzIGFyZSBlYWNoIGFcbiAgICogcmVxdWVzdCBvdmVyIHRoZSB3aG9sZSBzZXQgKGEgc3RhY2sncyBldmVyeSBzbGljZSksIGFuZCB0aGV5IGNvbXBldGVkIHdpdGggdGhlIHZvbHVtZSdzIG93blxuICAgKiBzbGljZSBsb2FkaW5nIGZvciBub3RoaW5nIGFueW9uZSBjb3VsZCBzZWUuIE9wZW5lZCwgaXQgcmVhZHMgdGhlbSBhZ2Fpbi5cbiAgICovXG4gIEBJbnB1dCgpIHNldCBhY3RpdmUodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBjb25zdCB3YXMgPSB0aGlzLmlzQWN0aXZlO1xuICAgIHRoaXMuaXNBY3RpdmUgPSB2YWx1ZTtcbiAgICBpZiAodmFsdWUgJiYgIXdhcykge1xuICAgICAgdm9pZCB0aGlzLnJlZnJlc2hTb3VyY2UoKTtcbiAgICAgIHRoaXMucmVzZXRWb2x1bWVzKCk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgaXNBY3RpdmUgPSB0cnVlO1xuICAvKiogVGhlIGhvc3QncyBIdHRwQ2xpZW50OiBhIHNlcnZlZCByZWdpb24gc2V0J3MgcmVxdWVzdHMgZ28gdGhyb3VnaCBpdCAoaXRzIGF1dGgpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICBwcm90ZWN0ZWQgcmVnaW9uczogUmVnaW9uW10gPSBbXTtcbiAgcHJvdGVjdGVkIHNlbGVjdGVkUmVnaW9uczogUmVnaW9uW10gPSBbXTtcbiAgcHJvdGVjdGVkIHNob3dTaGFwZUxhYmVsITogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIHNoYXBlQ29sb3IhOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBmaWxsQ29sb3IhOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBkaXNwbGF5SGVscERpYWxvZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgc2hvd0NvbG9yRGlhbG9nID0gZmFsc2U7XG4gIC8qKiBPbmUgY29sb3VyIGVkaXRvciBwZXIgdW5pcXVlIGNsYXNzIGFtb25nIHRoZSBzZWxlY3RlZCByZWdpb25zLCBzaG93biBpbiB0aGVcbiAgICogIFwiZWRpdCBjb2xvdXIgb2Ygc2VsZWN0ZWQgcmVnaW9uc1wiIGRpYWxvZy4gVW5jbGFzc2lmaWVkIHJlZ2lvbnMgKG5vIGxhYmVsKVxuICAgKiAgYXJlIGdyb3VwZWQgdW5kZXIgYSBzaW5nbGUgZW50cnkgd2l0aCBhbiBlbXB0eSBgbGFiZWxgLiAqL1xuICBwcm90ZWN0ZWQgY2xhc3NDb2xvckVkaXRzOiBDbGFzc0NvbG9yRWRpdFtdID0gW107XG4gIC8qKiBcIkVkaXQgY2xhc3Mgb24gc2VsZWN0ZWQgcm93c1wiIHBvcHVwOiBjaG9zZW4gZXhpc3RpbmcgY2xhc3MsIGFuZCBhIG5ldy1jbGFzcyBuYW1lLiAqL1xuICBwcm90ZWN0ZWQgYnVsa0NsYXNzID0gJyc7XG4gIHByb3RlY3RlZCBuZXdCdWxrQ2xhc3MgPSAnJztcblxuICAvLyDilIDilIAgYW5ub3RhdGlvbi1jbGFzcyBwcmVzZXRzIChqaXQtdWkjNzApIOKUgOKUgFxuICAvKiogTG9jYWwgbWlycm9yIG9mIHRoZSBwZXItdXNlciBwcmVzZXQgc2V0IChjaGlwIHN0cmlwLCBDbGFzcyBkcm9wZG93biwgZGlhbG9nKS4gKi9cbiAgcHJvdGVjdGVkIHByZXNldFNldDogUHJlc2V0U2V0ID0gZGVmYXVsdFByZXNldFNldCgpO1xuICAvKiogVGhlIGNsYXNzIGxhc3QgcGlja2VkIGluIHRoZSBwYW5lbDsgYSBjaGlwLWNsaWNrIGFwcGxpZXMgaXQgdG8gdGhlIHNlbGVjdGVkIHJvd3MuICovXG4gIHByb3RlY3RlZCBhY3RpdmVDbGFzczogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCBzaG93TWFuYWdlRGlhbG9nID0gZmFsc2U7XG4gIC8qKiBXb3JraW5nIGNvcHkgZWRpdGVkIGluc2lkZSB0aGUgTWFuYWdlLWNsYXNzZXMgZGlhbG9nOyBjb21taXR0ZWQgb24gQXBwbHkvRG9uZS4gKi9cbiAgcHJvdGVjdGVkIHByZXNldERyYWZ0OiBQcmVzZXRTZXQgfCBudWxsID0gbnVsbDtcbiAgLyoqIGNsYXNzIG5hbWUgKG1hdGNoLW1vZGUga2V5ZWQpIOKGkiBudW1iZXIgb2YgcmVnaW9ucyBjdXJyZW50bHkgdXNpbmcgaXQuICovXG4gIHByb3RlY3RlZCBjbGFzc0NvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBGYWxsYmFjayBjbGFzcyB0aGF0IGEgcmVnaW9uIHJldmVydHMgdG8gd2hlbiBpdHMgY2xhc3MgaXMgZGVsZXRlZCAoaml0LXVpIzcwKS4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlZmF1bHRDbGFzc05hbWUgPSAnUmVnaW9uJztcbiAgLyoqIENsYXNzZXMgYXMgc2hvd24gaW4gdGhlIHBhbmVsOiBzb3J0ZWQgYnkgcmVnaW9uIGNvdW50IChkZXNjKSwgdGhlbiBuYW1lLiAqL1xuICBwcm90ZWN0ZWQgZGlzcGxheUNsYXNzZXM6IENsYXNzUHJlc2V0W10gPSBbXTtcblxuICBwcm90ZWN0ZWQgcGFnaW5hdG9yRmlyc3QgPSAwO1xuICBwcm90ZWN0ZWQgcGFnaW5hdG9yUm93cyA9IDEwO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcm93c1BlclBhZ2VPcHRpb25zID0gWzEwLCAyNSwgNTBdO1xuICAvKiogUmVnaW9ucyB3aG9zZSBDbGFzcyBjZWxsIGlzIGN1cnJlbnRseSBpbiBlZGl0IG1vZGUg4oaSIHRoZSBsYWJlbCBiZWluZyB0eXBlZC5cbiAgICogIFRoZSBkcmFmdCBpcyBjb21taXR0ZWQgb24gRW50ZXIgYW5kIGRpc2NhcmRlZCBvbiBFc2NhcGUv4pyVLCBzbyB0eXBpbmcgbmV2ZXJcbiAgICogIHdyaXRlcyBpbnRvIHRoZSBzdG9yZSdzIHJlZ2lvbiAoUlQtMTgpLiBLZXllZCBieSBvYmplY3QgaWRlbnRpdHksIHdoaWNoXG4gICAqICBhdm9pZHMgbmVlZGluZyBhIHVuaXF1ZSBpZCBmaWVsZC4gKi9cbiAgcHJvdGVjdGVkIGVkaXRpbmdMYWJlbFJlZ2lvbnMgPSBuZXcgTWFwPFJlZ2lvbiwgc3RyaW5nPigpO1xuXG4gIHByb3RlY3RlZCBzaG93U2F2ZUFzRGlhbG9nID0gZmFsc2U7XG4gIC8qKlxuICAgKiBUaGUgc2xpY2UncyByZWdpb24gc291cmNlIChhIGxhcmdlIHJlZ2lvbiBzZXQgZHJhd24gYnkgbGV2ZWwgb2YgZGV0YWlsKSwgb3IgbnVsbC4gSXRzXG4gICAqIGZlYXR1cmVzIGFyZSByb3dzIG9mIHRoZSB0YWJsZSBhZnRlciB0aGUgcmVnaW9ucyDigJQgc3RhbmQtaW5zIHVudGlsIG9uZSBpcyBzZWxlY3RlZCBvciBlZGl0ZWQsXG4gICAqIHdoaWNoIHRha2VzIGl0IGludG8gdGhlIHJlZ2lvbnMg4oCUIGFuZCBpdHMgY2xhc3NlcyBjb3VudCBpbiB0aGUgY2xhc3NlcyBwYW5lbC5cbiAgICovXG4gIHByb3RlY3RlZCBzb3VyY2VWaWV3OiBSZWdpb25Tb3VyY2VWaWV3IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBGZWF0dXJlcyBzdGlsbCBpbiB0aGUgc291cmNlICh0aGUgdGFibGUncyByb3dzIGFmdGVyIHRoZSByZWdpb25zKS4gKi9cbiAgcHJpdmF0ZSBzb3VyY2VUb3RhbCA9IDA7XG4gIC8qKiBTdGFuZC1pbiByb3dzIGZvciB0aGUgc291cmNlIGZlYXR1cmVzIG9uIHRoZSBjdXJyZW50IHBhZ2UuICovXG4gIHByaXZhdGUgc291cmNlUm93czogUmVnaW9uW10gPSBbXTtcbiAgLyoqIEZlYXR1cmVzIHBlciBjbGFzcyBzdGlsbCBpbiB0aGUgc291cmNlLiAqL1xuICBwcml2YXRlIHNvdXJjZUNsYXNzQ291bnRzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge307XG4gIC8qKiBUaGUgc3RhbmQtaW4gcm93cyAocm93cyBvZiBhIHNvdXJjZSBmZWF0dXJlLCBub3Qgb2YgYSByZWdpb24pLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YW5kSW5zID0gbmV3IFdlYWtTZXQ8UmVnaW9uPigpO1xuICBwcml2YXRlIHN0YW5kSW5TZXEgPSAwO1xuICAvKiogQnVtcGVkIHBlciBzb3VyY2UgcmVmcmVzaCwgc28gYSBsYXRlIGFuc3dlciBpcyBkcm9wcGVkLiAqL1xuICBwcml2YXRlIHNvdXJjZVJlcXVlc3QgPSAwO1xuICAvKiogVGhlIGNsYXNzZXMgdGhlIHRhYmxlJ3MgQ2xhc3MgY29sdW1uIG9mZmVyczogdGhlIHByZXNldHMgYW5kIHRoZSByZWdpb24gc291cmNlJ3MgY2xhc3Nlc1xuICAgKiAgKGEgZHJvcGRvd24gY2FuIG9ubHkgc2hvdyBhIHZhbHVlIHRoYXQgaXMgb25lIG9mIGl0cyBvcHRpb25zKS4gKi9cbiAgcHJvdGVjdGVkIHRhYmxlUHJlc2V0U2V0OiBQcmVzZXRTZXQgPSBkZWZhdWx0UHJlc2V0U2V0KCk7XG4gIC8qKiBXaGV0aGVyIHJlZ2lvbnMgYXJlIGRyYXduIGZpbGxlZCAodGhlIGF0bGFzIGxvb2spIHJhdGhlciB0aGFuIG91dGxpbmVkLiAqL1xuICBwcm90ZWN0ZWQgcmVnaW9uc0ZpbGxlZCA9IGZhbHNlO1xuICAvKiogV2hldGhlciBhIHZvbHVtZSB2aWV3IGlzIG9uIHNjcmVlbiAoY2xhc3NlcyBjYW4gdGhlbiBiZSBzaG93biBpbiAzRCkuICovXG4gIHByb3RlY3RlZCB2b2x1bWVWaWV3ID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoZSB2b2x1bWUgdmlldydzIHNsaWNlIHBhbmUgaXMgd2FudGVkIChvbmUgc2xpY2UgZWRpdGVkIGJlc2lkZSB0aGUgM0QgdmlldykuICovXG4gIHByaXZhdGUgc2xpY2VQYW5lID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoZSB2b2x1bWUgdmlldyBkcmF3cyB0aGUgcmVnaW9ucyB0aHJvdWdoIHRoZSB2b2x1bWUgKHNlZSB0b2dnbGVUaHJvdWdoVm9sdW1lKS4gKi9cbiAgcHJvdGVjdGVkIHJlZ2lvbnNUaHJvdWdoVm9sdW1lID0gZmFsc2U7XG4gIC8qKiBDbGFzc2VzIHNob3duIGluIDNEIGluIHRoZSB2b2x1bWUgdmlldywgZWFjaCB3aXRoIHRoZSBjbGFzc2VzIGl0cyBzdXJmYWNlIGNvdmVycy4gKi9cbiAgcHJvdGVjdGVkIHNob3duM2QgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG4gIC8qKiBUaGUgY2xhc3NlcyBvZiB0aGUgY2xhc3MgdHJlZSdzIHBpY2sgKGl0IGFuZCBpdHMgc3VidHJlZSksIGFzIGxvbmcgYXMgdGhlIHBpY2sgaG9sZHMuICovXG4gIHByaXZhdGUgcGlja2VkQ2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXTtcbiAgLyoqIFRoZSBzZWxlY3RlZCByb3dzJyBjbGFzc2VzLCBtYXJrZWQgaW4gdGhlIGNsYXNzIGxpc3RzLiAqL1xuICBwcm90ZWN0ZWQgbWFya2VkQ2xhc3NlczogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFRoZSBzdXJmYWNlcyBoaWdobGlnaHRlZCBpbiB0aGUgdm9sdW1lIHZpZXcgKHRoZWlyIGtleXMsIGpvaW5lZCkuICovXG4gIHByaXZhdGUgaGlnaGxpZ2h0ZWQzZCA9ICcnO1xuICAvKiogVGhlIGNvbG91ciBlYWNoIHNob3duIHN1cmZhY2Ugd2FzIGxhc3QgZHJhd24gaW4uICovXG4gIHByaXZhdGUgY29sb3JzM2QgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAvKiogVGhlaXIgbmFtZXMsIGZvciB0aGUgY2xhc3MgbGlzdHMnIHRvZ2dsZXMgKGEgbmV3IHNldCBwZXIgY2hhbmdlLCBmb3IgT25QdXNoKS4gKi9cbiAgcHJvdGVjdGVkIHNob3duM2ROYW1lczogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFRoZSBjbGFzc2VzIGhpZGRlbiBmcm9tIHZpZXcgKHRoZWlyIHJlZ2lvbnMsIHNvdXJjZSBmZWF0dXJlcyBhbmQgc3VyZmFjZXMpLiAqL1xuICBwcm90ZWN0ZWQgaGlkZGVuQ2xhc3NlczogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFdoZXRoZXIgYSByZWdpb24gc2V0J3MgY2xhc3MgaGllcmFyY2h5IGlzIHNob3duIGFzIGEgdHJlZSAocmF0aGVyIHRoYW4gdGhlIGNsYXNzIGxpc3QpLiAqL1xuICBwcm90ZWN0ZWQgY2xhc3NUcmVlVmlldyA9IHRydWU7XG4gIC8qKiBUaGUgY2xhc3MgcGlja2VkIGxhc3QgaW4gdGhlIGNsYXNzIHRyZWUuICovXG4gIHByb3RlY3RlZCBwaWNrZWRDbGFzczogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBSZWdpb25zIHBlciBjbGFzcyAodGhlIHJlZ2lvbnMnIGFuZCB0aGUgc291cmNlJ3MpLCBmb3IgdGhlIGNsYXNzIHRyZWUuICovXG4gIHByb3RlY3RlZCB0cmVlQ291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIEEgY2xhc3MncyBjb2xvdXIsIGZvciB0aGUgY2xhc3MgdHJlZTogYSBuZXcgZnVuY3Rpb24gcGVyIGNvbG91ciBjaGFuZ2UsIHNvIHRoZSB0cmVlIHJlcGFpbnRzLiAqL1xuICBwcm90ZWN0ZWQgdHJlZUNvbG9yID0gKG5hbWU6IHN0cmluZyk6IHN0cmluZyA9PiBjb2xvckZvckxhYmVsKG5hbWUsIHRoaXMucHJlc2V0U2V0KTtcbiAgcHJvdGVjdGVkIHNhdmVBc0ZpbGVuYW1lID0gJyc7XG4gIHByb3RlY3RlZCBzYXZlQXNGaWxlRXhpc3RzID0gZmFsc2U7XG4gIC8qKiBUcnVlIHdoaWxlIGEgR2VvSlNPTiBwZXJzaXN0IGlzIHNlcmlhbGl6aW5nL3VwbG9hZGluZyDigJQgZHJpdmVzIHRoZSBkaWFsb2cnc1xuICAgKiAgcHJvZ3Jlc3MgYmFyIGFuZCBDYW5jZWwgYnV0dG9uIChwYXJpdHkgd2l0aCB0aGUgU2F2ZS1tYXNrIGRpYWxvZykuICovXG4gIHByb3RlY3RlZCBzYXZlQXNCdXN5ID0gZmFsc2U7XG4gIC8qKiBUaGUgcnVubmluZyBHZW9KU09OIHNhdmU7IHVuc3Vic2NyaWJpbmcgY2FuY2VscyBpdCAoQ2FuY2VsIC8gZGVzdHJveSkuICovXG4gIHByaXZhdGUgX3NhdmVBc1N1Yj86IFN1YnNjcmlwdGlvbjtcbiAgLyoqIFNhdmUtYXMgZmlsZSBuYW1lcyB0byBjaGVjayBmb3IgYW4gZXhpc3RpbmcgZmlsZSAoZGVib3VuY2VkKS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBzYXZlQXNDaGVjayQgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG5cbiAgcHJvdGVjdGVkIHNob3dFeHBvcnREaWFsb2cgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGV4cG9ydEZpbGVuYW1lID0gJyc7XG5cbiAgcHJvdGVjdGVkIHNob3dTYXZlTWFza0RpYWxvZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgc2F2ZU1hc2tGaWxlbmFtZSA9ICcnO1xuICAvKiogTWFzayB0eXBlIGNob3NlbiBpbiB0aGUgU2F2ZS1tYXNrIGRpYWxvZzogYSBiaW5hcnkgZm9yZWdyb3VuZC9iYWNrZ3JvdW5kXG4gICAqICBtYXNrLCBvciBhIG11bHRpLWNsYXNzIG1hc2sgd2l0aCBhIGRpc3RpbmN0IGlkIHBlciByZWdpb24uICovXG4gIHByb3RlY3RlZCBtYXNrTW9kZTogTWFza01vZGUgPSAnYmluYXJ5JztcbiAgLyoqIFRydWUgd2hpbGUgdGhlIG1hc2sgd29ya2VyIGlzIHJhc3Rlcml6aW5nL2VuY29kaW5nIOKAlCBkcml2ZXMgdGhlIHByb2dyZXNzXG4gICAqICBiYXIgYW5kIHRoZSBDYW5jZWwgYnV0dG9uIGluIHRoZSBkaWFsb2cuICovXG4gIHByb3RlY3RlZCBtYXNrQnVzeSA9IGZhbHNlO1xuICAvKiogMOKAkzEwMCByYXN0ZXJpemF0aW9uIHByb2dyZXNzOyBzd2l0Y2hlcyB0byBpbmRldGVybWluYXRlIGR1cmluZyBlbmNvZGluZy4gKi9cbiAgcHJvdGVjdGVkIG1hc2tQcm9ncmVzcyA9IDA7XG4gIHByb3RlY3RlZCBtYXNrRW5jb2RpbmcgPSBmYWxzZTtcbiAgLyoqIFRoZSBydW5uaW5nIG1hc2sgZXhwb3J0OyB1bnN1YnNjcmliaW5nIGNhbmNlbHMgaXQgKHRlcm1pbmF0ZXMgaXRzIHdvcmtlcikuICovXG4gIHByaXZhdGUgbWFza0pvYj86IFN1YnNjcmlwdGlvbjtcblxuICAvKipcbiAgICogUHJpbWVORyBwLXRhYmxlIG11bHRpLXNlbGVjdGlvbiBtb2RlIHRvZ2dsZS4gV2hlbiB0cnVlLCBzaW5nbGUtY2xpY2tcbiAgICogc2VsZWN0cyBvbmUgcm93IChyZXBsYWNpbmcgcHJpb3IpOyBtZXRhL2N0cmwtY2xpY2sgdG9nZ2xlcyBhIHJvdyBpbi9vdXRcbiAgICogb2YgdGhlIHNlbGVjdGlvbi4gV2hlbiBmYWxzZSwgZXZlcnkgY2xpY2sgdG9nZ2xlcy4gRGVmYXVsdCB0cnVlIHRvXG4gICAqIG1hdGNoIHRoZSBtb3N0IGNvbW1vbiBzcHJlYWRzaGVldC1saWtlIFVYLlxuICAgKi9cbiAgcHJvdGVjdGVkIG1ldGFLZXkgPSB0cnVlO1xuXG4gIHByaXZhdGUgX3VwZGF0aW5nRnJvbUVkaXRvciA9IGZhbHNlO1xuICBwcml2YXRlIF9zdXBwcmVzc1NlbGVjdGlvblN5bmNUb1Bsb3QgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gIC8qKiBSZS1yZW5kZXIgdGhpcyBPblB1c2ggdmlldywgcmUtZW50ZXJpbmcgdGhlIHpvbmUgd2hlbiB0aGUgY2hhbmdlIGNhbWUgZnJvbSBvdXRzaWRlIGl0LiAqL1xuICBwcml2YXRlIGNoYW5nZWQoKTogdm9pZCB7XG4gICAgbWFya0ZvckNoZWNrSW5ab25lKHRoaXMuY2RyLCB0aGlzLnpvbmUpO1xuICB9XG5cbiAgLyoqIFBoeXNpY2FsIHBpeGVsIHNpemUgKMK1bS9waXhlbCkgb2YgdGhlIGFjdGl2ZSBpbWFnZSwgZm9yIHJlZ2lvbiBhcmVhcyBpblxuICAgKiAgwrVtwrI7IGVtcHR5IHdoZW4gdGhlIGZvcm1hdCByZXBvcnRzIG5vIHBoeXNpY2FsIHNpemUuICovXG4gIHByb3RlY3RlZCBtcHA6IFBpeGVsU2l6ZSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoUkVHSU9OX0VESVRPUl9BUEkpIHByaXZhdGUgcmVnaW9uQXBpOiBJUmVnaW9uRWRpdG9yQXBpLFxuICAgIHByaXZhdGUgbWVzc2FnZVNlcnZpY2U6IE1lc3NhZ2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgY29uZmlybWF0aW9uU2VydmljZTogQ29uZmlybWF0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIHBlcnNpc3RlbmNlOiBSZWdpb25QZXJzaXN0ZW5jZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtYXNrRXhwb3J0OiBNYXNrRXhwb3J0U2VydmljZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuc2hvd1NoYXBlTGFiZWwgPSB0aGlzLnJlZ2lvbkFwaS5nZXRTaG93U2hhcGVMYWJlbCgpO1xuICAgIHRoaXMuc2hhcGVDb2xvciA9IHRoaXMucmVnaW9uQXBpLmdldFNoYXBlQ29sb3IoKTtcbiAgICB0aGlzLmZpbGxDb2xvciA9IHRoaXMucmVnaW9uQXBpLmdldEZpbGxDb2xvcigpO1xuXG4gICAgLy8gQW5ub3RhdGlvbi1jbGFzcyBwcmVzZXRzIChqaXQtdWkjNzApOiBtaXJyb3IgdGhlIHNldCBmb3IgdGhlIGNoaXAgc3RyaXAsXG4gICAgLy8gdGhlIENsYXNzIGRyb3Bkb3duIGFuZCB0aGUgbWFuYWdlIGRpYWxvZy4gR3VhcmRlZCB3aXRoIG9wdGlvbmFsIGNhbGxzIHNvXG4gICAgLy8gcGFydGlhbCBBUEkgbW9ja3MgaW4gdGVzdHMgKHdoaWNoIG9taXQgdGhlIHByZXNldCBtZXRob2RzKSBkb24ndCB0aHJvdy5cbiAgICBjb25zdCBpbml0aWFsUHJlc2V0cyA9IHRoaXMucmVnaW9uQXBpLmdldFByZXNldFNldD8uKCk7XG4gICAgaWYgKGluaXRpYWxQcmVzZXRzKSB0aGlzLnByZXNldFNldCA9IGluaXRpYWxQcmVzZXRzO1xuICAgIGNvbnN0IHByZXNldHMkID0gdGhpcy5yZWdpb25BcGkuZ2V0UHJlc2V0U2V0JD8uKCk7XG4gICAgaWYgKHByZXNldHMkKSB7XG4gICAgICBwcmVzZXRzJC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoKHNldCkgPT4ge1xuICAgICAgICBpZiAoc2V0KSB0aGlzLnByZXNldFNldCA9IHNldDtcbiAgICAgICAgdGhpcy50cmVlQ29sb3IgPSAobmFtZTogc3RyaW5nKTogc3RyaW5nID0+IGNvbG9yRm9yTGFiZWwobmFtZSwgdGhpcy5wcmVzZXRTZXQpO1xuICAgICAgICB0aGlzLnVwZGF0ZURpc3BsYXlDbGFzc2VzKCk7XG4gICAgICAgIHRoaXMucmVjb2xvcjNkKCk7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFNlZWQgZnJvbSB0aGUgdmlzdWFsaXplcidzIGN1cnJlbnQgcmVnaW9ucyDigJQgYWxyZWFkeSBzY29wZWQgdG8gdGhlXG4gICAgLy8gYWN0aXZlIGltYWdlIGJ5IHRoZSBwZXItaW1hZ2UgY2FjaGUsIGFuZCBoYW5kZWQgYmFjayBhcyBuZXV0cmFsIFJlZ2lvblxuICAgIC8vIG9iamVjdHMgKG5vIGJhY2tlbmQgc2hhcGUgZm9ybWF0IGludm9sdmVkKS5cbiAgICAvLyBBbm5vdGF0aW9uIHJlZ2lvbnMgb25seSDigJQgaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMgYXJlIG93bmVkIGJ5IHRoZVxuICAgIC8vIGludGVuc2l0eSB0b29sIGFuZCBleGNsdWRlZCBieSB0aGUgY29udHJhY3QsIHNvIHRoZSBlZGl0b3IgbmV2ZXIgc2VlcyB0aGVtLlxuICAgIHRoaXMucmVnaW9ucyA9IHRoaXMuYXBwbHlSZWdpb25Db2xvcnModGhpcy5yZWdpb25BcGkuZ2V0QW5ub3RhdGlvblJlZ2lvbnMoKSk7XG4gICAgdGhpcy5zeW5jQ2xhc3Nlc0Zyb21SZWdpb25zKHRoaXMucmVnaW9ucyk7XG4gICAgdGhpcy5yZWNvbXB1dGVDbGFzc0NvdW50cygpO1xuXG4gICAgLy8gVGhlIHVwZGF0ZSBldmVudCBpcyBqdXN0IGEgY2hhbmdlIHNpZ25hbDsgcmUtcmVhZCB0aGUgcmVnaW9ucyBmcm9tIHRoZVxuICAgIC8vIHZpc3VhbGl6ZXIgcmF0aGVyIHRoYW4gcGFyc2luZyB3aGF0ZXZlciBwYXlsb2FkIGl0IGNhcnJpZXMuXG4gICAgdGhpcy5yZWdpb25BcGlcbiAgICAgIC5nZXRSZWdpb25VcGRhdGVFdmVudCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fdXBkYXRpbmdGcm9tRWRpdG9yKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHVwZGF0ZWQgPSB0aGlzLmFwcGx5UmVnaW9uQ29sb3JzKHRoaXMucmVnaW9uQXBpLmdldEFubm90YXRpb25SZWdpb25zKCkpO1xuICAgICAgICAvLyBwcmVzZXJ2ZSBzZWxlY3Rpb24gZm9yIHJlZ2lvbnMgdGhhdCBzdGlsbCBleGlzdCAoYnkgaWQsIHNpbmNlIG5hbWVcbiAgICAgICAgLy8gaXMgYSB1c2VyLWVkaXRhYmxlIGRpc3BsYXkgbGFiZWwgYW5kIG1heSBjb2xsaWRlKVxuICAgICAgICBjb25zdCBzZWxlY3RlZElkcyA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZFJlZ2lvbnMubWFwKChyKSA9PiByLmlkKSk7XG4gICAgICAgIHRoaXMucmVnaW9ucyA9IHVwZGF0ZWQ7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRSZWdpb25zID0gdXBkYXRlZC5maWx0ZXIoKHIpID0+IHNlbGVjdGVkSWRzLmhhcyhyLmlkKSk7XG4gICAgICAgIHRoaXMuY2xhbXBQYWdpbmF0b3JGaXJzdCgpO1xuICAgICAgICB0aGlzLnN5bmNDbGFzc2VzRnJvbVJlZ2lvbnModXBkYXRlZCk7XG4gICAgICAgIHRoaXMucmVjb21wdXRlQ2xhc3NDb3VudHMoKTtcbiAgICAgICAgaWYgKHRoaXMudm9sdW1lVmlldykgdGhpcy5yZXNldFZvbHVtZXMoKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoU291cmNlKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVnaW9uQXBpXG4gICAgICAuZ2V0UmVnaW9uU291cmNlVmlldyQ/LigpXG4gICAgICA/LnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKCh2aWV3KSA9PiB7XG4gICAgICAgIGlmICh2aWV3Py5zb3VyY2UgIT09IHRoaXMuc291cmNlVmlldz8uc291cmNlKSB0aGlzLnBpY2tlZENsYXNzID0gbnVsbDtcbiAgICAgICAgdGhpcy5zb3VyY2VWaWV3ID0gdmlldztcbiAgICAgICAgdm9pZCB0aGlzLnJlZnJlc2hTb3VyY2UoKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpb25BcGlcbiAgICAgIC5nZXRSZWdpb25TdHlsZSQ/LigpXG4gICAgICA/LnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChzdHlsZSkgPT4ge1xuICAgICAgICB0aGlzLnJlZ2lvbnNGaWxsZWQgPSBzdHlsZS5maWxsT3BhY2l0eSA+IDA7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnJlZ2lvbkFwaVxuICAgICAgLmdldFZvbHVtZVZpZXckPy4oKVxuICAgICAgPy5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgodm9sdW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvdW50aW5nID0gdGhpcy5zdGFja0NvdW50cztcbiAgICAgICAgdGhpcy52b2x1bWVWaWV3ID0gdm9sdW1lO1xuICAgICAgICB0aGlzLnJlc2V0Vm9sdW1lcygpO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhY2tDb3VudHMgIT09IGNvdW50aW5nKSB2b2lkIHRoaXMucmVmcmVzaFNvdXJjZSgpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnJlZ2lvbkFwaVxuICAgICAgLmdldFJlZ2lvbnNUaHJvdWdoVm9sdW1lJD8uKClcbiAgICAgID8ucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHRocm91Z2gpID0+IHtcbiAgICAgICAgdGhpcy5yZWdpb25zVGhyb3VnaFZvbHVtZSA9IHRocm91Z2g7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnJlZ2lvbkFwaVxuICAgICAgLmdldFNsaWNlRWRpdG9yJD8uKClcbiAgICAgID8ucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHBhbmUpID0+IHtcbiAgICAgICAgY29uc3QgY291bnRpbmcgPSB0aGlzLnN0YWNrQ291bnRzO1xuICAgICAgICB0aGlzLnNsaWNlUGFuZSA9IHBhbmU7XG4gICAgICAgIGlmICh0aGlzLnN0YWNrQ291bnRzICE9PSBjb3VudGluZykgdm9pZCB0aGlzLnJlZnJlc2hTb3VyY2UoKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gV2hhdCBpcyBzaG93biBpbiAzRDogdGhlIHJvdXRlciBjbGVhcnMgaXQgd2hlbiBhbm90aGVyIGltYWdlIGlzIHBsb3R0ZWQuXG4gICAgdGhpcy5yZWdpb25BcGlcbiAgICAgIC5nZXRSZWdpb25DbGFzc2VzM2QkPy4oKVxuICAgICAgPy5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoZ3JvdXBzKSA9PiB7XG4gICAgICAgIHRoaXMuc2hvd24zZCA9IG5ldyBNYXAoZ3JvdXBzLm1hcCgoZykgPT4gW2cua2V5LCBbLi4uZy5jbGFzc2VzXV0pKTtcbiAgICAgICAgdGhpcy5zaG93bjNkTmFtZXMgPSBuZXcgU2V0KHRoaXMuc2hvd24zZC5rZXlzKCkpO1xuICAgICAgICB0aGlzLmhpZ2hsaWdodGVkM2QgPSAnJztcbiAgICAgICAgdGhpcy51cGRhdGVTZWxlY3Rpb25IaWdobGlnaHQoKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVnaW9uQXBpXG4gICAgICAuZ2V0SGlkZGVuQ2xhc3NlcyQ/LigpXG4gICAgICA/LnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChoaWRkZW4pID0+IHtcbiAgICAgICAgdGhpcy5oaWRkZW5DbGFzc2VzID0gaGlkZGVuO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gQSBzdXJmYWNlIGNsaWNrZWQgaW4gdGhlIHZvbHVtZSB2aWV3ICh3aXRoIHRoZSBzZWxlY3Rpb24gdG9vbCkgcGlja3MgaXRzIGNsYXNzLlxuICAgIHRoaXMucmVnaW9uQXBpXG4gICAgICAuZ2V0UmVnaW9uUGlja2VkM2QkPy4oKVxuICAgICAgPy5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoeyBrZXksIGFkZGl0aXZlIH0pID0+IHRoaXMub25QaWNrZWQzZChrZXksIGFkZGl0aXZlKSk7XG5cbiAgICB0aGlzLnBlcnNpc3RlbmNlXG4gICAgICAuZmlsZUV4aXN0cyh0aGlzLnNhdmVBc0NoZWNrJClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoZXhpc3RzKSA9PiB7XG4gICAgICAgIHRoaXMuc2F2ZUFzRmlsZUV4aXN0cyA9IGV4aXN0cztcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB9KTtcblxuICAgIC8vIFBoeXNpY2FsIHBpeGVsIHNpemUgb2YgdGhlIGFjdGl2ZSBpbWFnZSAoZm9yIHJlZ2lvbiBhcmVhcyBpbiDCtW3Csi9tbcKyKS5cbiAgICB0aGlzLnJlZ2lvbkFwaVxuICAgICAgLmdldEltYWdlTWV0YSgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKG1ldGEpID0+IHtcbiAgICAgICAgdGhpcy5tcHAgPSBwaWNrTXBwKG1ldGEpO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpb25BcGlcbiAgICAgIC5nZXRTZWxlY3RlZFJlZ2lvbnMkKClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoc2VsZWN0ZWQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX3N1cHByZXNzU2VsZWN0aW9uU3luY1RvUGxvdCkgcmV0dXJuO1xuICAgICAgICAvLyBNYXAgdGhlIGNvbnRyYWN0J3Mgc2VsZWN0ZWQgcmVnaW9ucyB0byB0aGUgZWRpdG9yJ3Mgb3duIGluc3RhbmNlcyBieSBpZC5cbiAgICAgICAgY29uc3QgbmV4dCA9IHNlbGVjdGVkLm1hcCgocykgPT4gdGhpcy5yZWdpb25zLmZpbmQoKHIpID0+IHIuaWQgPT09IHMuaWQpKS5maWx0ZXIoKHIpOiByIGlzIFJlZ2lvbiA9PiAhIXIpO1xuICAgICAgICBjb25zdCBzYW1lID1cbiAgICAgICAgICBuZXh0Lmxlbmd0aCA9PT0gdGhpcy5zZWxlY3RlZFJlZ2lvbnMubGVuZ3RoICYmXG4gICAgICAgICAgbmV4dC5ldmVyeSgociwgaSkgPT4gci5pZCA9PT0gdGhpcy5zZWxlY3RlZFJlZ2lvbnNbaV0/LmlkKTtcbiAgICAgICAgaWYgKCFzYW1lKSB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IG5leHQ7XG4gICAgICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uSGlnaGxpZ2h0KCk7XG4gICAgICAgIC8vIFNjcm9sbCB0aGUgcGFnaW5hdG9yIHNvIHRoZSBtb3N0LXJlY2VudGx5LXNlbGVjdGVkIHJvdyBpcyB2aXNpYmxlLlxuICAgICAgICBpZiAobmV4dC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgbGFzdElkeCA9IHRoaXMucmVnaW9ucy5maW5kSW5kZXgoKHIpID0+IHIuaWQgPT09IG5leHRbbmV4dC5sZW5ndGggLSAxXS5pZCk7XG4gICAgICAgICAgaWYgKGxhc3RJZHggPj0gMCkge1xuICAgICAgICAgICAgY29uc3QgcGFnZVN0YXJ0ID0gTWF0aC5mbG9vcihsYXN0SWR4IC8gdGhpcy5wYWdpbmF0b3JSb3dzKSAqIHRoaXMucGFnaW5hdG9yUm93cztcbiAgICAgICAgICAgIGlmIChwYWdlU3RhcnQgIT09IHRoaXMucGFnaW5hdG9yRmlyc3QpIHRoaXMucGFnaW5hdG9yRmlyc3QgPSBwYWdlU3RhcnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKiogQ2FuY2VscyBhIHJ1bm5pbmcgR2VvSlNPTiBzYXZlIChhYm9ydHMgaXRzIHVwbG9hZCkgYW5kIG1hc2sgZXhwb3J0ICh0ZXJtaW5hdGVzXG4gICAqICBpdHMgd29ya2VyKTsgdGhlIEFQSSBzdWJzY3JpcHRpb25zIGVuZCB0aHJvdWdoIGB0YWtlVW50aWxEZXN0cm95ZWRgLiAqL1xuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zYXZlQXNTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5tYXNrSm9iPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRhYmxlIOKGkiBQbG90OiBQcmltZU5HIGZpcmVzIG9uUm93U2VsZWN0L29uUm93VW5zZWxlY3QgYWZ0ZXIgdXBkYXRpbmdcbiAgICogYHNlbGVjdGVkUmVnaW9uc2AuIFB1c2ggdGhlIHNlbGVjdGVkIHJlZ2lvbnMgdG8gdGhlIGNvbnRyYWN0IGJ5IGlkZW50aXR5IOKAlFxuICAgKiB0aGUgcGFja2FnZSBtYXBzIHRoZW0gdG8gaXRzIGludGVybmFsIGluZGV4IHNwYWNlICh3aGljaCBpbmNsdWRlcyB0aGVcbiAgICogaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMgdGhlIGVkaXRvciBuZXZlciBzZWVzKS5cbiAgICovXG4gIHByb3RlY3RlZCBvblNlbGVjdGlvbkNoYW5nZWQoKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkUmVnaW9ucyA/PyBbXTtcbiAgICAvLyBSb3dzIHBpY2tlZCBpbiB0aGUgdGFibGUgcmVwbGFjZSB0aGUgY2xhc3MgdHJlZSdzIHBpY2suXG4gICAgdGhpcy5waWNrZWRDbGFzc2VzID0gW107XG4gICAgdGhpcy51cGRhdGVTZWxlY3Rpb25IaWdobGlnaHQoKTtcbiAgICBjb25zdCBmcm9tU291cmNlID0gc2VsZWN0ZWQuZmlsdGVyKChyKSA9PiB0aGlzLnN0YW5kSW5zLmhhcyhyKSk7XG4gICAgdGhpcy5fc3VwcHJlc3NTZWxlY3Rpb25TeW5jVG9QbG90ID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZWdpb25BcGkuc2V0U2VsZWN0ZWRSZWdpb25zKHNlbGVjdGVkLmZpbHRlcigocikgPT4gIXRoaXMuc3RhbmRJbnMuaGFzKHIpKSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX3N1cHByZXNzU2VsZWN0aW9uU3luY1RvUGxvdCA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBBIHNlbGVjdGVkIHNvdXJjZSByb3cgaXMgdGFrZW4gaW50byB0aGUgcmVnaW9ucyAoYW5kIHNvIHNlbGVjdGVkIG9uIHRoZSBpbWFnZSB0b28pLlxuICAgIGlmIChmcm9tU291cmNlLmxlbmd0aCkgdm9pZCB0aGlzLnJlZ2lvbkFwaS5zZWxlY3RTb3VyY2VGZWF0dXJlcz8uKHRoaXMuc291cmNlSWRzKGZyb21Tb3VyY2UpLCB0cnVlKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBUaGUgcmVnaW9uIHNvdXJjZSdzIGZlYXR1cmVzIGFzIHRhYmxlIHJvd3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFdoZXRoZXIgdGhlIHNsaWNlIGhhcyBhIHJlZ2lvbiBzb3VyY2U6IGl0IHRoZW4gaGFzIHJlZ2lvbnMgdG8gc2F2ZSBldmVuIHdpdGggYW4gZW1wdHkgdGFibGUuICovXG4gIHByb3RlY3RlZCBnZXQgaGFzUmVnaW9uU291cmNlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuc291cmNlVmlldztcbiAgfVxuXG4gIC8qKiBSb3dzIGluIHRoZSB0YWJsZTogdGhlIHJlZ2lvbnMsIHRoZW4gdGhlIGZlYXR1cmVzIHN0aWxsIGluIHRoZSByZWdpb24gc291cmNlLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHRhYmxlVG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25zLmxlbmd0aCArIHRoaXMuc291cmNlVG90YWw7XG4gIH1cblxuICAvKiogVGhlIGNsYXNzIGhpZXJhcmNoeSBvZiB0aGUgc2xpY2UncyByZWdpb24gc291cmNlLCB3aGVuIGl0IGhhcyBvbmUgKHRoZSBjbGFzc2VzIGFzIGEgdHJlZSkuICovXG4gIHByb3RlY3RlZCBnZXQgY2xhc3NIaWVyYXJjaHkoKTogUmVnaW9uQ2xhc3NOb2RlW10gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5zb3VyY2VWaWV3Py5zb3VyY2UuaW5mby5oaWVyYXJjaHkgPz8gbnVsbDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGByb3dgIGlzIGEgcmVnaW9uLXNvdXJjZSBmZWF0dXJlJ3Mgc3RhbmQtaW4gcmF0aGVyIHRoYW4gYSByZWdpb24uICovXG4gIHByb3RlY3RlZCBpc1NvdXJjZVJvdyhyb3c6IFJlZ2lvbik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YW5kSW5zLmhhcyhyb3cpO1xuICB9XG5cbiAgcHJpdmF0ZSBzb3VyY2VJZHMocm93czogUmVnaW9uW10pOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHJvd3MubWFwKChyKSA9PiByLnNvdXJjZUlkKS5maWx0ZXIoKGlkKTogaWQgaXMgc3RyaW5nID0+ICEhaWQpO1xuICB9XG5cbiAgLyoqIEEgdGFibGUgcm93IGZvciBhIHNvdXJjZSBmZWF0dXJlOiBubyBnZW9tZXRyeSB1bnRpbCBpdCBpcyB0YWtlbi4gKi9cbiAgcHJpdmF0ZSBzdGFuZEluKHJvdzogUmVnaW9uSW5kZXhSb3cpOiBSZWdpb24ge1xuICAgIGNvbnN0IHIgPSBPYmplY3QuYXNzaWduKG5ldyBSZWdpb24oKSwge1xuICAgICAgaWQ6IC0rK3RoaXMuc3RhbmRJblNlcSxcbiAgICAgIG5hbWU6IHJvdy5sYWJlbCA/PyByb3cuaWQsXG4gICAgICBsYWJlbDogcm93LmxhYmVsID8/IHVuZGVmaW5lZCxcbiAgICAgIGNvbG9yOiB0aGlzLnNvdXJjZVZpZXc/LmNvbG9yT2Yocm93KSA/PyByb3cuY29sb3IgPz8gdGhpcy5zaGFwZUNvbG9yLFxuICAgICAgc291cmNlSWQ6IHJvdy5pZCxcbiAgICAgIHNvdXJjZUFyZWE6IHJvdy5hcmVhLFxuICAgICAgYm91bmRzOiBudWxsLFxuICAgIH0pO1xuICAgIHRoaXMuc3RhbmRJbnMuYWRkKHIpO1xuICAgIHJldHVybiByO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlLXJlYWQgdGhlIHNvdXJjZSBwYXJ0IG9mIHRoZSB0YWJsZSAodGhlIHN0YW5kLWlucyBvbiB0aGUgY3VycmVudCBwYWdlLCB0aGUgY291bnQpIGFuZCB0aGVcbiAgICogc291cmNlJ3MgY2xhc3MgY291bnRzLiBUaGUgcGFnZSBob2xkcyByZWdpb25zIGZpcnN0LCBzbyBpdHMgc291cmNlIHJvd3Mgc3RhcnQgYXRcbiAgICogYG1heChmaXJzdCwgcmVnaW9ucylgIOKIkiByZWdpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWZyZXNoU291cmNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5pc0FjdGl2ZSkgcmV0dXJuO1xuICAgIGNvbnN0IHJlcXVlc3QgPSArK3RoaXMuc291cmNlUmVxdWVzdDtcbiAgICBjb25zdCB2aWV3ID0gdGhpcy5zb3VyY2VWaWV3O1xuICAgIGxldCByb3dzOiBSZWdpb25JbmRleFJvd1tdID0gW107XG4gICAgbGV0IHRvdGFsID0gMDtcbiAgICBsZXQgY291bnRzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge307XG4gICAgaWYgKHZpZXcgJiYgdGhpcy5yZWdpb25BcGkuZ2V0UmVnaW9uU291cmNlSW5kZXgpIHtcbiAgICAgIGNvbnN0IG93biA9IHRoaXMucmVnaW9ucy5sZW5ndGg7XG4gICAgICBjb25zdCBzdGFydCA9IE1hdGgubWF4KHRoaXMucGFnaW5hdG9yRmlyc3QsIG93bik7XG4gICAgICBjb25zdCBsaW1pdCA9IE1hdGgubWF4KDAsIHRoaXMucGFnaW5hdG9yRmlyc3QgKyB0aGlzLnBhZ2luYXRvclJvd3MgLSBzdGFydCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBbcGFnZSwgcGVyQ2xhc3NdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgIHRoaXMucmVnaW9uQXBpLmdldFJlZ2lvblNvdXJjZUluZGV4KHsgb2Zmc2V0OiBzdGFydCAtIG93biwgbGltaXQgfSksXG4gICAgICAgICAgdGhpcy5yZWdpb25BcGkuZ2V0UmVnaW9uU291cmNlQ2xhc3NDb3VudHM/Lih0aGlzLnN0YWNrQ291bnRzKSxcbiAgICAgICAgXSk7XG4gICAgICAgIHJvd3MgPSBwYWdlPy5yb3dzID8/IFtdO1xuICAgICAgICB0b3RhbCA9IHBhZ2U/LnRvdGFsID8/IDA7XG4gICAgICAgIGNvdW50cyA9IHBlckNsYXNzID8/IHt9O1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignW3JlZ2lvbnNdIGNvdWxkIG5vdCBsaXN0IHRoZSByZWdpb24gc291cmNlJywgZXJyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJlcXVlc3QgIT09IHRoaXMuc291cmNlUmVxdWVzdCkgcmV0dXJuO1xuICAgIHRoaXMuc291cmNlVG90YWwgPSB0b3RhbDtcbiAgICB0aGlzLnNvdXJjZVJvd3MgPSByb3dzLm1hcCgocikgPT4gdGhpcy5zdGFuZEluKHIpKTtcbiAgICB0aGlzLnNvdXJjZUNsYXNzQ291bnRzID0gY291bnRzO1xuICAgIHRoaXMucmVjb21wdXRlQ2xhc3NDb3VudHMoKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfVxuXG4gIC8qKiBUYWtlIGEgc291cmNlIHJvdydzIGZlYXR1cmUgaW50byB0aGUgcmVnaW9ucywgdGhlbiBydW4gYHRoZW5gIG9uIHRoZSByZWdpb24gaXQgYmVjYW1lLiAqL1xuICBwcml2YXRlIGFzeW5jIHRha2VUaGVuKHJvdzogUmVnaW9uLCB0aGVuOiAocmVnaW9uOiBSZWdpb24pID0+IHZvaWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBbaWRdID0gKGF3YWl0IHRoaXMucmVnaW9uQXBpLnNlbGVjdFNvdXJjZUZlYXR1cmVzPy4odGhpcy5zb3VyY2VJZHMoW3Jvd10pKSkgPz8gW107XG4gICAgY29uc3QgcmVnaW9uID0gdGhpcy5yZWdpb25zLmZpbmQoKHIpID0+IHIuaWQgPT09IGlkKTtcbiAgICBpZiAocmVnaW9uKSB0aGVuKHJlZ2lvbik7XG4gIH1cblxuICAvKiogVG9nZ2xlIHRoZSBmaWxsZWQgKGF0bGFzKSBsb29rOiBlYWNoIHJlZ2lvbiBmaWxsZWQgaW4gaXRzIGNvbG91ciwgbGFiZWxzIGluc2lkZS4gKi9cbiAgLyoqIEluIGEgdm9sdW1lIHZpZXc6IHRoZSByZWdpb25zIGRyYXduIHRocm91Z2ggdGhlIHZvbHVtZSwgb3IgaGlkZGVuIGJlaGluZCB3aGF0IGl0IHNob3dzLiAqL1xuICBwcm90ZWN0ZWQgdG9nZ2xlVGhyb3VnaFZvbHVtZSgpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFwaS5zZXRSZWdpb25zVGhyb3VnaFZvbHVtZT8uKCF0aGlzLnJlZ2lvbnNUaHJvdWdoVm9sdW1lKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0b2dnbGVGaWxsKCk6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQXBpLnNldFJlZ2lvblN0eWxlPy4oeyBmaWxsT3BhY2l0eTogdGhpcy5yZWdpb25zRmlsbGVkID8gMCA6IFJFR0lPTl9GSUxMX09QQUNJVFkgfSk7XG4gIH1cblxuICAvKipcbiAgICogU2hvdyBvciBoaWRlIGEgY2xhc3MgaW4gdGhlIHZvbHVtZSB2aWV3IGFzIGEgM0QgcmVjb25zdHJ1Y3Rpb24g4oCUIGEgdHJlZSBub2RlIHdpdGggZXZlcnkgY2xhc3NcbiAgICogdW5kZXIgaXQsIGFzIG9uZSBzdXJmYWNlIGluIGl0cyBjb2xvdXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9nZ2xlQ2xhc3MzZChuYW1lOiBzdHJpbmcsIGNsYXNzZXM6IHN0cmluZ1tdID0gW25hbWVdKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IG5ldyBNYXAodGhpcy5zaG93bjNkKTtcbiAgICBpZiAobmV4dC5oYXMobmFtZSkpIG5leHQuZGVsZXRlKG5hbWUpO1xuICAgIGVsc2UgbmV4dC5zZXQobmFtZSwgY2xhc3Nlcyk7XG4gICAgdGhpcy5zaG93bjNkID0gbmV4dDtcbiAgICB0aGlzLnNob3duM2ROYW1lcyA9IG5ldyBTZXQobmV4dC5rZXlzKCkpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIHRoaXMuc2hvdzNkKHRoaXMuZ3JvdXBzM2QoKSk7XG4gICAgdGhpcy51cGRhdGVTZWxlY3Rpb25IaWdobGlnaHQoKTtcbiAgfVxuXG4gIC8qKiBIaWRlIChvciBzaG93IGFnYWluKSB0aGVzZSBjbGFzc2VzJyByZWdpb25zLCB3aGVyZXZlciB0aGV5IGFyZSBkcmF3bi4gKi9cbiAgcHJvdGVjdGVkIHNldENsYXNzZXNIaWRkZW4oY2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10sIGhpZGRlbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQXBpLnNldENsYXNzZXNIaWRkZW4/LihjbGFzc2VzLCBoaWRkZW4pO1xuICB9XG5cbiAgLyoqIFRoZSBzdXJmYWNlcyBzaG93biBpbiAzRCwgaW4gdGhlaXIgY2xhc3NlcycgY29sb3VycyBub3cuICovXG4gIHByaXZhdGUgZ3JvdXBzM2QoKTogQXJyYXk8eyBrZXk6IHN0cmluZzsgY2xhc3Nlczogc3RyaW5nW107IGNvbG9yOiBzdHJpbmc7IGxhYmVsOiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IHRpdGxlcyA9IG5ldyBNYXAoKHRoaXMuY2xhc3NIaWVyYXJjaHkgPz8gW10pLm1hcCgobikgPT4gW24ubmFtZSwgbi50aXRsZV0pKTtcbiAgICByZXR1cm4gWy4uLnRoaXMuc2hvd24zZF0ubWFwKChba2V5LCBjbGFzc2VzXSkgPT4ge1xuICAgICAgY29uc3QgdGl0bGUgPSB0aXRsZXMuZ2V0KGtleSk7XG4gICAgICByZXR1cm4geyBrZXksIGNsYXNzZXMsIGNvbG9yOiB0aGlzLnRyZWVDb2xvcihrZXkpLCBsYWJlbDogdGl0bGUgPyBgJHtrZXl9IMK3ICR7dGl0bGV9YCA6IGtleSB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIFRoZSBjbGFzc2VzIHNlbGVjdGVkIG5vdzogdGhlIGNsYXNzIHRyZWUncyBwaWNrICh3aXRoIGl0cyBzdWJ0cmVlKSBhbmQgdGhlIHNlbGVjdGVkIHJvd3MnLiAqL1xuICBwcml2YXRlIHNlbGVjdGVkQ2xhc3NOYW1lcygpOiBTZXQ8c3RyaW5nPiB7XG4gICAgY29uc3QgbmFtZXMgPSBuZXcgU2V0KHRoaXMucGlja2VkQ2xhc3Nlcyk7XG4gICAgZm9yIChjb25zdCByIG9mIHRoaXMuc2VsZWN0ZWRSZWdpb25zID8/IFtdKSBpZiAoci5sYWJlbCkgbmFtZXMuYWRkKHIubGFiZWwpO1xuICAgIHJldHVybiBuYW1lcztcbiAgfVxuXG4gIC8qKlxuICAgKiBIaWdobGlnaHQsIGluIHRoZSB2b2x1bWUgdmlldywgdGhlIHN1cmZhY2VzIGhvbGRpbmcgYSBzZWxlY3RlZCBjbGFzcyAoZm9jdXMgKyBjb250ZXh0OiB0aGV5XG4gICAqIHR1cm4gbmVhciBvcGFxdWUsIHRoZSBvdGhlcnMgZmFkZSksIGFuZCBtYXJrIHRoZSBzZWxlY3RlZCByb3dzJyBjbGFzc2VzIGluIHRoZSBjbGFzcyBsaXN0cy5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlU2VsZWN0aW9uSGlnaGxpZ2h0KCk6IHZvaWQge1xuICAgIGNvbnN0IG5hbWVzID0gdGhpcy5zZWxlY3RlZENsYXNzTmFtZXMoKTtcbiAgICBjb25zdCBtYXJrZWQgPSBuZXcgU2V0KCh0aGlzLnNlbGVjdGVkUmVnaW9ucyA/PyBbXSkubWFwKChyKSA9PiByLmxhYmVsKS5maWx0ZXIoKGwpOiBsIGlzIHN0cmluZyA9PiAhIWwpKTtcbiAgICBpZiAoWy4uLm1hcmtlZF0uam9pbignXFxuJykgIT09IFsuLi50aGlzLm1hcmtlZENsYXNzZXNdLmpvaW4oJ1xcbicpKSB0aGlzLm1hcmtlZENsYXNzZXMgPSBtYXJrZWQ7XG4gICAgY29uc3Qga2V5cyA9IFsuLi50aGlzLnNob3duM2RdLmZpbHRlcigoWywgY2xhc3Nlc10pID0+IGNsYXNzZXMuc29tZSgoYykgPT4gbmFtZXMuaGFzKGMpKSkubWFwKChba10pID0+IGspO1xuICAgIGNvbnN0IGlkID0ga2V5cy5qb2luKCdcXG4nKTtcbiAgICBpZiAoaWQgPT09IHRoaXMuaGlnaGxpZ2h0ZWQzZCkgcmV0dXJuO1xuICAgIHRoaXMuaGlnaGxpZ2h0ZWQzZCA9IGlkO1xuICAgIHRoaXMucmVnaW9uQXBpLmhpZ2hsaWdodFJlZ2lvbkNsYXNzZXMzZD8uKGtleXMpO1xuICB9XG5cbiAgLyoqIEEgc3VyZmFjZSBjbGlja2VkIGluIHRoZSB2b2x1bWUgdmlldzogcGljayBpdHMgY2xhc3MgYXMgdGhlIHRyZWUgd291bGQ7IGJlc2lkZSB0aGVtLCBjbGVhci4gKi9cbiAgcHJpdmF0ZSBvblBpY2tlZDNkKGtleTogc3RyaW5nIHwgbnVsbCwgYWRkaXRpdmU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoa2V5ID09PSBudWxsKSB7XG4gICAgICBpZiAoYWRkaXRpdmUpIHJldHVybjtcbiAgICAgIHRoaXMucGlja2VkQ2xhc3MgPSBudWxsO1xuICAgICAgdGhpcy5waWNrZWRDbGFzc2VzID0gW107XG4gICAgICB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IFtdO1xuICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQoKTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2b2lkIHRoaXMucGlja0NsYXNzZXMoeyBuYW1lOiBrZXksIGNsYXNzZXM6IHRoaXMuc2hvd24zZC5nZXQoa2V5KSA/PyBba2V5XSwgYWRkaXRpdmUgfSk7XG4gIH1cblxuICAvKiogQSBjbGFzcyBjb2xvdXIgY2hhbmdlZCAoaXRzIHN3YXRjaCwgb3IgTWFuYWdlKTogcmVwYWludCB0aGUgc3VyZmFjZXMgc2hvd24gaW4gM0Qgd2hvc2UgY29sb3VyIGl0IGNoYW5nZWQuICovXG4gIHByaXZhdGUgcmVjb2xvcjNkKCk6IHZvaWQge1xuICAgIGNvbnN0IGdyb3VwcyA9IHRoaXMuZ3JvdXBzM2QoKTtcbiAgICBpZiAoIWdyb3Vwcy5zb21lKChnKSA9PiBnLmNvbG9yICE9PSB0aGlzLmNvbG9yczNkLmdldChnLmtleSkpKSByZXR1cm47XG4gICAgdGhpcy5zaG93M2QoZ3JvdXBzKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvdzNkKGdyb3VwczogQXJyYXk8eyBrZXk6IHN0cmluZzsgY2xhc3Nlczogc3RyaW5nW107IGNvbG9yOiBzdHJpbmcgfT4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbG9yczNkID0gbmV3IE1hcChncm91cHMubWFwKChnKSA9PiBbZy5rZXksIGcuY29sb3JdKSk7XG4gICAgdGhpcy5yZWdpb25BcGkuc2hvd1JlZ2lvbkNsYXNzZXMzZD8uKGdyb3VwcykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgdGhpcy50b2FzdCgnZXJyb3InLCAnQ291bGQgbm90IHNob3cgdGhlIHJlZ2lvbiBpbiAzRCcsIGAkeyhlcnIgYXMgRXJyb3IpPy5tZXNzYWdlID8/IGVycn1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBQaWNrIGEgY2xhc3MgaW4gdGhlIGNsYXNzIHRyZWU6IHNlbGVjdCBpdHMgcmVnaW9ucyBhbmQgaXRzIHN1YmNsYXNzZXMnLCB0aGUgc291cmNlJ3MgdGFrZW4uICovXG4gIHByb3RlY3RlZCBhc3luYyBwaWNrQ2xhc3NlcyhwaWNrOiBDbGFzc1RyZWVQaWNrKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5waWNrZWRDbGFzcyA9IHBpY2submFtZTtcbiAgICB0aGlzLnBpY2tlZENsYXNzZXMgPSBwaWNrLmFkZGl0aXZlID8gWy4uLm5ldyBTZXQoWy4uLnRoaXMucGlja2VkQ2xhc3NlcywgLi4ucGljay5jbGFzc2VzXSldIDogcGljay5jbGFzc2VzO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uSGlnaGxpZ2h0KCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgYXdhaXQgdGhpcy5yZWdpb25BcGkuc2VsZWN0UmVnaW9uQ2xhc3Nlcz8uKHBpY2suY2xhc3NlcywgcGljay5hZGRpdGl2ZSk7XG4gIH1cblxuICAvKipcbiAgICogUm93cyBmb3IgcmVnaW9ucyBjb21pbmcgZnJvbSB0aGUgdmlzdWFsaXplcjogbmV1dHJhbCBgUmVnaW9uYHMgd2l0aCBib3VuZHMsXG4gICAqIGNvbG91ciBhbmQgbGFiZWwgYWxyZWFkeSBwb3B1bGF0ZWQuIEEgcmVnaW9uIHdpdGhvdXQgYSBjb2xvdXIgaXMgc2hvd24gd2l0aFxuICAgKiBpdHMgY2xhc3NpZmljYXRpb24gY29sb3VyIChvciB0aGUgZGVmYXVsdCBzaGFwZSBjb2xvdXIpIOKAlCBhcyBhIGNvcHk6IHRoZVxuICAgKiBzdG9yZSdzIGluc3RhbmNlcyBhcmUgc2hhcmVkIHdpdGggaXRzIHVuZG8gaGlzdG9yeSBhbmQgbXVzdCBub3QgYmUgY2hhbmdlZFxuICAgKiBpbiBwbGFjZSAoUlQtMSkuXG4gICAqL1xuICBwcml2YXRlIGFwcGx5UmVnaW9uQ29sb3JzKHJlZ2lvbnM6IFJlZ2lvbltdKTogUmVnaW9uW10ge1xuICAgIGNvbnN0IGNsYXNzQ29sb3JzID0gdGhpcy5yZWdpb25BcGkuZ2V0Q2xhc3NpZmljYXRpb25Db2xvcnMoKTtcbiAgICByZXR1cm4gcmVnaW9ucy5tYXAoKHJlZ2lvbikgPT5cbiAgICAgIHJlZ2lvbi5jb2xvclxuICAgICAgICA/IHJlZ2lvblxuICAgICAgICA6IHdpdGhSZWdpb25QYXRjaChyZWdpb24sIHsgY29sb3I6IGNsYXNzQ29sb3JzLmdldChyZWdpb24ubGFiZWwgPz8gJycpIHx8IHRoaXMuc2hhcGVDb2xvciB9KSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBlZGl0b3IncyBvbmUgd3JpdGUgcGF0aCAoUlQtMSk6IG1ha2UgYG5leHRgIHRoZSB0YWJsZSdzIHJvd3MgYW5kIGNvbW1pdFxuICAgKiB0aGVtIHRvIHRoZSBzdG9yZSDigJQgbGl2ZSwgYXMgb25lIHVuZG9hYmxlIHN0ZXAgKGlzUmVnaW9uU2F2ZU9uPXRydWU7IHRoZVxuICAgKiByb3V0ZXIga2VlcHMgdGhlIGludGVuc2l0eS1wcm9maWxlIGxpbmVzKS4gUm93cyBhcmUgdGhlIHN0b3JlJ3MgaW5zdGFuY2VzLFxuICAgKiBzbyBhbiBlZGl0IHBhc3NlcyBjb3BpZXMgKHtAbGluayBwYXRjaFJlZ2lvbnN9KSwgbmV2ZXIgY2hhbmdlZCByb3dzLiBUaGVcbiAgICogcmVzdWx0aW5nIHJlZ2lvbi11cGRhdGUgZXZlbnQgaXMgaWdub3JlZCAoYF91cGRhdGluZ0Zyb21FZGl0b3JgKSwgc28gdGhlXG4gICAqIGNsYXNzIGxpc3QgYW5kIGNvdW50cyBhcmUgcmVmcmVzaGVkIGhlcmUgKGEgdHlwZWQgY2xhc3MgaXMgYWRkZWQ7IGppdC11aSM3MCkuXG4gICAqL1xuICBwcml2YXRlIGNvbW1pdChuZXh0OiBSZWdpb25bXSA9IHRoaXMucmVnaW9ucyk6IHZvaWQge1xuICAgIHRoaXMucmVnaW9ucyA9IG5leHQ7XG4gICAgdGhpcy5fdXBkYXRpbmdGcm9tRWRpdG9yID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZWdpb25BcGkuc2V0QW5ub3RhdGlvblJlZ2lvbnMobmV4dCwgdGhpcy5zaG93U2hhcGVMYWJlbCwgdHJ1ZSwgdGhpcy5maWxsQ29sb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLl91cGRhdGluZ0Zyb21FZGl0b3IgPSBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5zeW5jQ2xhc3Nlc0Zyb21SZWdpb25zKG5leHQpO1xuICAgIHRoaXMucmVjb21wdXRlQ2xhc3NDb3VudHMoKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3B5LW9uLXdyaXRlIGVkaXQgKHJldmlldyBSVC0xKS4gVGhlIGVkaXRvcidzIHJvd3MgYXJlIHRoZSByZWdpb24gc3RvcmUnc1xuICAgKiBsaXZlIGluc3RhbmNlcywgYW5kIHRoZSBzdG9yZSB0YWtlcyBpdHMgdW5kbyBzbmFwc2hvdCBvbmx5IHdoZW4gdGhlIGVkaXQgaXNcbiAgICogY29tbWl0dGVkIOKAlCBzbyBhbiBlZGl0IG11c3QgcmVwbGFjZSBhIHJlZ2lvbiB3aXRoIGEgcGF0Y2hlZCBjb3B5IChhbmQgYW55XG4gICAqIGJvdW5kcyBpdCBjaGFuZ2VzIHdpdGggbmV3IGJvdW5kcyksIG5ldmVyIG11dGF0ZSB0aGUgaW5zdGFuY2UgdGhlIHN0b3JlXG4gICAqIGhvbGRzLiBSZXR1cm5zIHRoZSBjb3BpZXMgYnkgb3JpZ2luYWw7IHRoZSBzZWxlY3Rpb24gYW5kIGFuIG9wZW4gbGFiZWwgZWRpdFxuICAgKiBmb2xsb3cgdGhlbS5cbiAgICovXG4gIHByaXZhdGUgcGF0Y2hSZWdpb25zKHBhdGNoRm9yOiAocjogUmVnaW9uKSA9PiBQYXJ0aWFsPFJlZ2lvbj4gfCBudWxsKTogTWFwPFJlZ2lvbiwgUmVnaW9uPiB7XG4gICAgY29uc3QgY29waWVzID0gbmV3IE1hcDxSZWdpb24sIFJlZ2lvbj4oKTtcbiAgICB0aGlzLnJlZ2lvbnMgPSB0aGlzLnJlZ2lvbnMubWFwKChyKSA9PiB7XG4gICAgICBjb25zdCBwYXRjaCA9IHBhdGNoRm9yKHIpO1xuICAgICAgaWYgKCFwYXRjaCkgcmV0dXJuIHI7XG4gICAgICBjb25zdCBjb3B5ID0gd2l0aFJlZ2lvblBhdGNoKHIsIHBhdGNoKTtcbiAgICAgIGNvcGllcy5zZXQociwgY29weSk7XG4gICAgICByZXR1cm4gY29weTtcbiAgICB9KTtcbiAgICBpZiAoY29waWVzLnNpemUpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRSZWdpb25zID0gKHRoaXMuc2VsZWN0ZWRSZWdpb25zID8/IFtdKS5tYXAoKHIpID0+IGNvcGllcy5nZXQocikgPz8gcik7XG4gICAgICBpZiAoWy4uLmNvcGllcy5rZXlzKCldLnNvbWUoKHIpID0+IHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucy5oYXMocikpKSB7XG4gICAgICAgIHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucyA9IG5ldyBNYXAoWy4uLnRoaXMuZWRpdGluZ0xhYmVsUmVnaW9uc10ubWFwKChbciwgZF0pID0+IFtjb3BpZXMuZ2V0KHIpID8/IHIsIGRdKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb3BpZXM7XG4gIH1cblxuICAvKiogU2V0IG9uZSByZWdpb24ncyBvdXRsaW5lIGNvbG91ciAoYW4gZXhwbGljaXQgb3ZlcnJpZGUpIGFuZCBjb21taXQgbGl2ZS4gKi9cbiAgcHJvdGVjdGVkIGNoYW5nZVJlZ2lvbkNvbG9yKHJlZ2lvbjogUmVnaW9uLCBjb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFjb2xvciB8fCByZWdpb24uY29sb3IgPT09IGNvbG9yKSByZXR1cm47XG4gICAgLy8gY29sb3JPdmVycmlkZGVuOiBleHBsaWNpdCBwZXItcmVnaW9uIGNvbG91ciDigJQgcHJlc2VydmUgaXQgYWdhaW5zdCBwcmVzZXQgKHJlKWFwcGx5IChqaXQtdWkjNzApXG4gICAgdGhpcy5wYXRjaFJlZ2lvbnMoKHIpID0+IChyID09PSByZWdpb24gPyB7IGNvbG9yLCBjb2xvck92ZXJyaWRkZW46IHRydWUgfSA6IG51bGwpKTtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFmdGVyIGEgbGFiZWwgZWRpdCBvbiBgcmVnaW9uYDogZ2l2ZSBldmVyeSBsYWJlbGxlZCByb3cgd2l0aG91dCBhIGNvbG91ciBpdHNcbiAgICogY2xhc3MgY29sb3VyIChwcmVzZXQgb3IgZmFsbGJhY2ssIGFzIHRoZSBzdG9yZSB3aWxsKSwgYW5kIGNvbW1pdCB3aGVuXG4gICAqIGBjb21taXRgIGlzIHNldC5cbiAgICovXG4gIHByb3RlY3RlZCBsYWJlbFJlZ2lvblVwZGF0ZShyZWdpb246IFJlZ2lvbiwgY29tbWl0ID0gZmFsc2UpIHtcbiAgICB0aGlzLmZpbGxDbGFzc0NvbG9ycygpO1xuICAgIGlmIChjb21taXQpIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICAvKiogTGFiZWxsZWQgcm93cyB3aXRob3V0IGEgY29sb3VyIGdldCB0aGVpciBjbGFzcyBjb2xvdXIgKGNvcGllcykuICovXG4gIHByaXZhdGUgZmlsbENsYXNzQ29sb3JzKCk6IHZvaWQge1xuICAgIHRoaXMucGF0Y2hSZWdpb25zKChyKSA9PiAoIXIuY29sb3IgJiYgci5sYWJlbCA/IHsgY29sb3I6IHRoaXMuY29sb3JGb3JOYW1lKHIubGFiZWwpIH0gOiBudWxsKSk7XG4gIH1cblxuICAvKiogVGhlIGN1cnJlbnQgcGFnZSBvZiB0aGUgdGFibGUuIE1lbW9pemVkIG9uIChyZWdpb25zLCBmaXJzdCwgcm93cyksIHNvXG4gICAqICBjaGFuZ2UgZGV0ZWN0aW9uIGRvZXNuJ3QgaGFuZCBwLXRhYmxlIGEgbmV3IGFycmF5IGV2ZXJ5IHRpY2sgKFJULTIwKS4gKi9cbiAgcHJvdGVjdGVkIGdldCBwYWdlZFJlZ2lvbnMoKTogUmVnaW9uW10ge1xuICAgIGNvbnN0IGtleSA9IHRoaXMuX3BhZ2VLZXk7XG4gICAgaWYgKFxuICAgICAga2V5LnJlZ2lvbnMgIT09IHRoaXMucmVnaW9ucyB8fFxuICAgICAga2V5LnNvdXJjZSAhPT0gdGhpcy5zb3VyY2VSb3dzIHx8XG4gICAgICBrZXkuZmlyc3QgIT09IHRoaXMucGFnaW5hdG9yRmlyc3QgfHxcbiAgICAgIGtleS5yb3dzICE9PSB0aGlzLnBhZ2luYXRvclJvd3NcbiAgICApIHtcbiAgICAgIHRoaXMuX3BhZ2VLZXkgPSB7XG4gICAgICAgIHJlZ2lvbnM6IHRoaXMucmVnaW9ucyxcbiAgICAgICAgc291cmNlOiB0aGlzLnNvdXJjZVJvd3MsXG4gICAgICAgIGZpcnN0OiB0aGlzLnBhZ2luYXRvckZpcnN0LFxuICAgICAgICByb3dzOiB0aGlzLnBhZ2luYXRvclJvd3MsXG4gICAgICB9O1xuICAgICAgY29uc3Qgb3duID0gdGhpcy5yZWdpb25zLnNsaWNlKHRoaXMucGFnaW5hdG9yRmlyc3QsIHRoaXMucGFnaW5hdG9yRmlyc3QgKyB0aGlzLnBhZ2luYXRvclJvd3MpO1xuICAgICAgdGhpcy5fcGFnZSA9XG4gICAgICAgIG93bi5sZW5ndGggPj0gdGhpcy5wYWdpbmF0b3JSb3dzXG4gICAgICAgICAgPyBvd25cbiAgICAgICAgICA6IFsuLi5vd24sIC4uLnRoaXMuc291cmNlUm93cy5zbGljZSgwLCB0aGlzLnBhZ2luYXRvclJvd3MgLSBvd24ubGVuZ3RoKV07XG4gICAgICAvLyBBIG5ldyBwYWdlIG1heSBzaG93IGNsYXNzZXMgd2hvc2Ugdm9sdW1lIGlzIG5vdCBrbm93biB5ZXQgKGFmdGVyIHRoaXMgY2hlY2spLlxuICAgICAgaWYgKHRoaXMudm9sdW1lVmlldykgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZXF1ZXN0Vm9sdW1lcygpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gIH1cblxuICAvKiogSW4gYSB2b2x1bWUgdmlldywgZWFjaCBjbGFzcydzIHZvbHVtZSBvdmVyIHRoZSB3aG9sZSBzdGFjaywgZm9yIHRoZSB0YWJsZSAobnVsbDogYXJlYXMpLiAqL1xuICBwcm90ZWN0ZWQgdGFibGVWb2x1bWVzOiBSZWFkb25seU1hcDxzdHJpbmcsIG51bWJlciB8IG51bGw+IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBCdW1wZWQgd2hlbiB0aGUgcmVnaW9ucyBjaGFuZ2UsIHNvIGEgdm9sdW1lIGNvbXB1dGVkIGJlZm9yZSBpcyBkcm9wcGVkLiAqL1xuICBwcml2YXRlIHZvbHVtZVJlcXVlc3QgPSAwO1xuXG4gIC8qKiBDb21wdXRlIHRoZSB2b2x1bWVzIG9mIHRoZSBjbGFzc2VzIG9uIHRoZSB0YWJsZSdzIHBhZ2UgdGhhdCBhcmUgbm90IGtub3duIHlldC4gKi9cbiAgcHJpdmF0ZSByZXF1ZXN0Vm9sdW1lcygpOiB2b2lkIHtcbiAgICBjb25zdCBhcGkgPSB0aGlzLnJlZ2lvbkFwaS5nZXRDbGFzc1ZvbHVtZXM/LmJpbmQodGhpcy5yZWdpb25BcGkpO1xuICAgIC8vIENsb3NlZDogYXNrZWQgZm9yIGFnYWluIHdoZW4gaXQgb3BlbnMgKHNlZSBhY3RpdmUpLlxuICAgIGlmICghdGhpcy5pc0FjdGl2ZSkgcmV0dXJuO1xuICAgIGlmICghdGhpcy52b2x1bWVWaWV3IHx8ICFhcGkpIHtcbiAgICAgIGlmICh0aGlzLnRhYmxlVm9sdW1lcykge1xuICAgICAgICB0aGlzLnRhYmxlVm9sdW1lcyA9IG51bGw7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBrbm93biA9IHRoaXMudGFibGVWb2x1bWVzID8/IG5ldyBNYXA8c3RyaW5nLCBudW1iZXIgfCBudWxsPigpO1xuICAgIGNvbnN0IGxhYmVscyA9IG5ldyBTZXQodGhpcy5wYWdlZFJlZ2lvbnMubWFwKChyKSA9PiByLmxhYmVsKS5maWx0ZXIoKGwpOiBsIGlzIHN0cmluZyA9PiAhIWwpKTtcbiAgICBjb25zdCBtaXNzaW5nID0gWy4uLmxhYmVsc10uZmlsdGVyKChsKSA9PiAha25vd24uaGFzKGwpKTtcbiAgICBpZiAoIW1pc3NpbmcubGVuZ3RoICYmIHRoaXMudGFibGVWb2x1bWVzKSByZXR1cm47XG4gICAgdGhpcy50YWJsZVZvbHVtZXMgPSBuZXcgTWFwKFsuLi5rbm93biwgLi4ubWlzc2luZy5tYXAoKGwpOiBbc3RyaW5nLCBudWxsXSA9PiBbbCwgbnVsbF0pXSk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgaWYgKCFtaXNzaW5nLmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLnZvbHVtZVJlcXVlc3Q7XG4gICAgYXBpKG1pc3NpbmcpLnRoZW4oXG4gICAgICAodm9sdW1lcykgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdCAhPT0gdGhpcy52b2x1bWVSZXF1ZXN0IHx8ICF0aGlzLnRhYmxlVm9sdW1lcykgcmV0dXJuO1xuICAgICAgICB0aGlzLnRhYmxlVm9sdW1lcyA9IG5ldyBNYXAoWy4uLnRoaXMudGFibGVWb2x1bWVzLCAuLi5PYmplY3QuZW50cmllcyh2b2x1bWVzKV0pO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0sXG4gICAgICAoZXJyKSA9PiB7XG4gICAgICAgIGlmIChyZXF1ZXN0ICE9PSB0aGlzLnZvbHVtZVJlcXVlc3QgfHwgIXRoaXMudGFibGVWb2x1bWVzKSByZXR1cm47XG4gICAgICAgIC8vIExlYXZlIHRoZW0gdW5rbm93biAoJ+KAlCcpIHJhdGhlciB0aGFuIGNvbXB1dGluZyBmb3JldmVyLlxuICAgICAgICBjb25zdCBuZXh0ID0gbmV3IE1hcCh0aGlzLnRhYmxlVm9sdW1lcyk7XG4gICAgICAgIGZvciAoY29uc3QgbCBvZiBtaXNzaW5nKSBuZXh0LmRlbGV0ZShsKTtcbiAgICAgICAgdGhpcy50YWJsZVZvbHVtZXMgPSBuZXh0O1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgY29uc29sZS53YXJuKCdbcmVnaW9uc10gY291bGQgbm90IGNvbXB1dGUgY2xhc3Mgdm9sdW1lcycsIGVycik7XG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICAvKiogVGhlIHJlZ2lvbnMgY2hhbmdlZCAob3IgdGhlIHZpZXcgZGlkKTogZm9yZ2V0IHRoZSB2b2x1bWVzIGFuZCBjb21wdXRlIHRoZSBwYWdlJ3MgYWdhaW4uICovXG4gIHByaXZhdGUgcmVzZXRWb2x1bWVzKCk6IHZvaWQge1xuICAgIHRoaXMudm9sdW1lUmVxdWVzdCsrO1xuICAgIHRoaXMudGFibGVWb2x1bWVzID0gbnVsbDtcbiAgICB0aGlzLnJlcXVlc3RWb2x1bWVzKCk7XG4gIH1cbiAgcHJpdmF0ZSBfcGFnZUtleTogeyByZWdpb25zPzogUmVnaW9uW107IHNvdXJjZT86IFJlZ2lvbltdOyBmaXJzdD86IG51bWJlcjsgcm93cz86IG51bWJlciB9ID0ge307XG4gIHByaXZhdGUgX3BhZ2U6IFJlZ2lvbltdID0gW107XG5cbiAgcHJvdGVjdGVkIG9uUGFnZUNoYW5nZShldmVudDogeyBmaXJzdD86IG51bWJlcjsgcm93cz86IG51bWJlciB9KSB7XG4gICAgdGhpcy5wYWdpbmF0b3JGaXJzdCA9IGV2ZW50LmZpcnN0ID8/IDA7XG4gICAgdGhpcy5wYWdpbmF0b3JSb3dzID0gZXZlbnQucm93cyA/PyB0aGlzLnBhZ2luYXRvclJvd3M7XG4gICAgdm9pZCB0aGlzLnJlZnJlc2hTb3VyY2UoKTtcbiAgfVxuXG4gIC8qKiBTZWxlY3QgZXZlcnkgcmVnaW9uIGluIHRoZSB0YWJsZSAoYW5kIGhpZ2hsaWdodCB0aGVtIG9uIHRoZSBkaWFncmFtKSwgdGhlIHNvdXJjZSdzIHRha2VuLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0QWxsUmVnaW9ucygpIHtcbiAgICB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IFsuLi50aGlzLnJlZ2lvbnNdO1xuICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKCk7XG4gICAgaWYgKCF0aGlzLnNvdXJjZVRvdGFsIHx8ICF0aGlzLnJlZ2lvbkFwaS5nZXRSZWdpb25Tb3VyY2VJbmRleCkgcmV0dXJuO1xuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLnJlZ2lvbkFwaS5nZXRSZWdpb25Tb3VyY2VJbmRleCh7IG9mZnNldDogMCwgbGltaXQ6IFNFTEVDVF9BTExfU09VUkNFX0xJTUlUIH0pO1xuICAgIGNvbnN0IGlkcyA9IChwYWdlPy5yb3dzID8/IFtdKS5tYXAoKHIpID0+IHIuaWQpO1xuICAgIGlmIChpZHMubGVuZ3RoKSBhd2FpdCB0aGlzLnJlZ2lvbkFwaS5zZWxlY3RTb3VyY2VGZWF0dXJlcz8uKGlkcywgdHJ1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZGVsZXRlU2VsZWN0ZWRSZWdpb25zKCkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkUmVnaW9ucyAmJiB0aGlzLnNlbGVjdGVkUmVnaW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBmcm9tU291cmNlID0gdGhpcy5zZWxlY3RlZFJlZ2lvbnMuZmlsdGVyKChyKSA9PiB0aGlzLnN0YW5kSW5zLmhhcyhyKSk7XG4gICAgICBpZiAoZnJvbVNvdXJjZS5sZW5ndGgpIHRoaXMucmVnaW9uQXBpLmRlbGV0ZVNvdXJjZUZlYXR1cmVzPy4odGhpcy5zb3VyY2VJZHMoZnJvbVNvdXJjZSkpO1xuICAgICAgLy8gRmlsdGVyIGJ5IGlkIOKAlCBvYmplY3QgaWRlbnRpdHkgaXNuJ3QgcmVsaWFibGUgYWNyb3NzIHJlLXBhcnNlcyxcbiAgICAgIC8vIGFuZCBuYW1lIGlzIGEgdXNlci1lZGl0YWJsZSBsYWJlbCB0aGF0IG1heSBjb2xsaWRlLlxuICAgICAgY29uc3QgcmVtb3ZlZCA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZFJlZ2lvbnMubWFwKChyKSA9PiByLmlkKSk7XG4gICAgICB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IFtdO1xuICAgICAgdGhpcy5jb21taXQodGhpcy5yZWdpb25zLmZpbHRlcigocikgPT4gIXJlbW92ZWQuaGFzKHIuaWQpKSk7XG4gICAgICB0aGlzLmNsYW1wUGFnaW5hdG9yRmlyc3QoKTtcbiAgICAgIC8vIFN5bmMgdGhlIGNsZWFyZWQgc2VsZWN0aW9uIHdpdGggdGhlIHBsb3QncyBoaWdobGlnaHQgc3RhdGUuXG4gICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBjbGVhckFsbFJlZ2lvbnMoKSB7XG4gICAgdGhpcy5jb25maXJtYXRpb25TZXJ2aWNlLmNvbmZpcm0oe1xuICAgICAga2V5OiAncG9zaXRpb25EaWFsb2cnLFxuICAgICAgbWVzc2FnZTogJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgYWxsIHJlZ2lvbnM/JyxcbiAgICAgIGFjY2VwdDogKCkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IFtdO1xuICAgICAgICB0aGlzLnBhZ2luYXRvckZpcnN0ID0gMDtcbiAgICAgICAgdGhpcy5jb21taXQoW10pO1xuICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZCgpO1xuICAgICAgICBpZiAodGhpcy5oYXNSZWdpb25Tb3VyY2UpIHZvaWQgdGhpcy5kZWxldGVBbGxTb3VyY2VGZWF0dXJlcygpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBEZWxldGUgZXZlcnkgZmVhdHVyZSBzdGlsbCBpbiB0aGUgc2xpY2UncyByZWdpb24gc291cmNlICh3aXRoIFwiRGVsZXRlIGFsbCByZWdpb25zXCIpLiAqL1xuICBwcml2YXRlIGFzeW5jIGRlbGV0ZUFsbFNvdXJjZUZlYXR1cmVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5yZWdpb25BcGkuZ2V0UmVnaW9uU291cmNlSW5kZXg7XG4gICAgaWYgKCFpbmRleCB8fCAhdGhpcy5yZWdpb25BcGkuZGVsZXRlU291cmNlRmVhdHVyZXMpIHJldHVybjtcbiAgICBjb25zdCBwYWdlID0gYXdhaXQgaW5kZXguY2FsbCh0aGlzLnJlZ2lvbkFwaSwgeyBvZmZzZXQ6IDAsIGxpbWl0OiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiB9KTtcbiAgICBpZiAocGFnZT8ucm93cy5sZW5ndGgpIHRoaXMucmVnaW9uQXBpLmRlbGV0ZVNvdXJjZUZlYXR1cmVzKHBhZ2Uucm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkZWxldGVSZWdpb24oc2hhcGVJZHg6IG51bWJlcikge1xuICAgIC8vIEEgcm93IHBhc3QgdGhlIHJlZ2lvbnMgaXMgYSBzb3VyY2UgZmVhdHVyZTogZGVsZXRlIGl0IGZyb20gdGhlIHNvdXJjZS5cbiAgICBpZiAoc2hhcGVJZHggPj0gdGhpcy5yZWdpb25zLmxlbmd0aCkge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy5zb3VyY2VSb3dzW3NoYXBlSWR4IC0gTWF0aC5tYXgodGhpcy5wYWdpbmF0b3JGaXJzdCwgdGhpcy5yZWdpb25zLmxlbmd0aCldO1xuICAgICAgaWYgKHJvdykgdGhpcy5yZWdpb25BcGkuZGVsZXRlU291cmNlRmVhdHVyZXM/Lih0aGlzLnNvdXJjZUlkcyhbcm93XSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZW1vdmVkID0gdGhpcy5yZWdpb25zW3NoYXBlSWR4XTtcbiAgICBpZiAocmVtb3ZlZCkge1xuICAgICAgdGhpcy5zZWxlY3RlZFJlZ2lvbnMgPSB0aGlzLnNlbGVjdGVkUmVnaW9ucy5maWx0ZXIoKHIpID0+IHIuaWQgIT09IHJlbW92ZWQuaWQpO1xuICAgIH1cbiAgICB0aGlzLmNvbW1pdCh0aGlzLnJlZ2lvbnMuZmlsdGVyKChfLCBpKSA9PiBpICE9PSBzaGFwZUlkeCkpO1xuICAgIHRoaXMuY2xhbXBQYWdpbmF0b3JGaXJzdCgpO1xuICAgIC8vIFJlLWVtaXQgdGhlIChwb3NzaWJseSB0cmltbWVkKSBzZWxlY3Rpb24gc28gdGhlIHBsb3QncyBoaWdobGlnaHQgc3RheXNcbiAgICAvLyBpbiBzeW5jIHdpdGggd2hhdCdzIHN0aWxsIGluIHRoZSB0YWJsZS5cbiAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGFtcFBhZ2luYXRvckZpcnN0KCkge1xuICAgIGNvbnN0IG1heEZpcnN0ID0gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcigodGhpcy50YWJsZVRvdGFsIC0gMSkgLyB0aGlzLnBhZ2luYXRvclJvd3MpICogdGhpcy5wYWdpbmF0b3JSb3dzKTtcbiAgICBpZiAodGhpcy5wYWdpbmF0b3JGaXJzdCA+IG1heEZpcnN0KSB7XG4gICAgICB0aGlzLnBhZ2luYXRvckZpcnN0ID0gbWF4Rmlyc3Q7XG4gICAgfVxuICB9XG4gIHByb3RlY3RlZCBjaGFuZ2VTaG93U2hhcGVMYWJlbChzaG93TGFiZWw6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGlzRWRpdGluZ0xhYmVsKHJlZ2lvbjogUmVnaW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucy5oYXMocmVnaW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdGFydEVkaXRMYWJlbChyZWdpb246IFJlZ2lvbiwgZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50Py5zdG9wUHJvcGFnYXRpb24oKTsgLy8gZG9uJ3QgdG9nZ2xlIHJvdyBzZWxlY3Rpb25cbiAgICBpZiAodGhpcy5zdGFuZElucy5oYXMocmVnaW9uKSkge1xuICAgICAgdm9pZCB0aGlzLnRha2VUaGVuKHJlZ2lvbiwgKHIpID0+IHRoaXMuc3RhcnRFZGl0TGFiZWwocikpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBBIG5ldyBtYXAgcGVyIHN0YXJ0L3N0b3AsIHNvIHRoZSBPblB1c2ggdGFibGUgc2VlcyB0aGUgY2hhbmdlLlxuICAgIHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucyA9IG5ldyBNYXAodGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zKS5zZXQocmVnaW9uLCByZWdpb24ubGFiZWwgPz8gJycpO1xuICB9XG5cbiAgLyoqIFRoZSBsYWJlbCB0eXBlZCBzbyBmYXIgZm9yIGEgcm93IGluIGVkaXQgbW9kZSAobm8gcmUtcmVuZGVyIG5lZWRlZCkuICovXG4gIHByb3RlY3RlZCBzZXRMYWJlbERyYWZ0KHJlZ2lvbjogUmVnaW9uLCB2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucy5oYXMocmVnaW9uKSkgdGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zLnNldChyZWdpb24sIHZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdG9wRWRpdExhYmVsKHJlZ2lvbjogUmVnaW9uLCBjb21taXQ6IGJvb2xlYW4sIGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgZHJhZnQgPSB0aGlzLmVkaXRpbmdMYWJlbFJlZ2lvbnMuZ2V0KHJlZ2lvbik7XG4gICAgaWYgKHRoaXMuZWRpdGluZ0xhYmVsUmVnaW9ucy5oYXMocmVnaW9uKSkge1xuICAgICAgY29uc3QgbmV4dCA9IG5ldyBNYXAodGhpcy5lZGl0aW5nTGFiZWxSZWdpb25zKTtcbiAgICAgIG5leHQuZGVsZXRlKHJlZ2lvbik7XG4gICAgICB0aGlzLmVkaXRpbmdMYWJlbFJlZ2lvbnMgPSBuZXh0O1xuICAgIH1cbiAgICBpZiAoY29tbWl0KSB7XG4gICAgICAvLyBBIGNoYW5nZWQgbGFiZWwgY29tbWl0cyBhcyBhIHJlcGxhY2VtZW50IHJlZ2lvbiwgc28gaXQgaXMgdW5kb2FibGUgKFJULTEpLlxuICAgICAgY29uc3QgZWRpdGVkID1cbiAgICAgICAgZHJhZnQgIT09IHVuZGVmaW5lZCAmJiBkcmFmdCAhPT0gcmVnaW9uLmxhYmVsXG4gICAgICAgICAgPyAodGhpcy5wYXRjaFJlZ2lvbnMoKHIpID0+IChyID09PSByZWdpb24gPyB7IGxhYmVsOiBkcmFmdCB9IDogbnVsbCkpLmdldChyZWdpb24pID8/IHJlZ2lvbilcbiAgICAgICAgICA6IHJlZ2lvbjtcbiAgICAgIHRoaXMubGFiZWxSZWdpb25VcGRhdGUoZWRpdGVkLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVnaW9uIGFyZWEgZm9yIGRpc3BsYXkgKMK1bcKyL21twrIgd2hlbiB0aGUgaW1hZ2UgaXMgc2NhbGVkLCBlbHNlIHB4wrIpO1xuICAgKiAgZW1wdHkgZm9yIGEgZGVnZW5lcmF0ZSByZWdpb24uIFNlZSBgcmVnaW9uLW1ldHJpY3NgLiAqL1xuICBwcm90ZWN0ZWQgcmVnaW9uQXJlYShyZWdpb246IFJlZ2lvbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGZvcm1hdEFyZWEocmVnaW9uQXJlYVB4KHJlZ2lvbiksIHRoaXMubXBwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCByb3VuZHMgYWxsIHRoZSByZWN0YW5nbGUgcmVnaW9ucyBsZW5ndGhzIHRvIG11bHRpcGxlIG9mIDUxMlxuICAgKi9cbiAgcHJvdGVjdGVkIHJvdW5kUmVjdGFuZ2xlTGVuZ3RocygpIHtcbiAgICB0aGlzLnBhdGNoUmVnaW9ucygocmVnaW9uKSA9PiB7XG4gICAgICBjb25zdCByZWN0ID0gcmVnaW9uLmJvdW5kcztcbiAgICAgIGlmICghKHJlY3QgaW5zdGFuY2VvZiBSZWN0YW5nbGUpKSByZXR1cm4gbnVsbDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJvdW5kczogT2JqZWN0LmFzc2lnbihuZXcgUmVjdGFuZ2xlKCksIHJlY3QsIHtcbiAgICAgICAgICBoZWlnaHQ6IE1hdGgucm91bmQocmVjdC5oZWlnaHQgLyA1MTIpICogNTEyLFxuICAgICAgICAgIHdpZHRoOiBNYXRoLnJvdW5kKHJlY3Qud2lkdGggLyA1MTIpICogNTEyLFxuICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgdGhpcy5jb21taXQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93SGVscCgpIHtcbiAgICB0aGlzLmRpc3BsYXlIZWxwRGlhbG9nID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBPcGVuIHRoZSBjb2xvdXIgZGlhbG9nIGZvciB0aGUgY3VycmVudGx5LXNlbGVjdGVkIHJlZ2lvbihzKSwgYnVpbGRpbmcgb25lXG4gICAqICBjb2xvdXIgcGlja2VyIHBlciB1bmlxdWUgY2xhc3MgaW4gdGhlIHNlbGVjdGlvbi4gRWFjaCBwaWNrZXIgaXMgc2VlZGVkIHdpdGhcbiAgICogIHRoZSBmaXJzdCBzZWxlY3RlZCByZWdpb24gb2YgdGhhdCBjbGFzcydzIGNvbG91ciAoZWxzZSB0aGUgY2xhc3MgY29sb3VyKS4gKi9cbiAgcHJvdGVjdGVkIG9wZW5Db2xvckRpYWxvZygpIHtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRSZWdpb25zPy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBzZWVkQnlMYWJlbCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCByZWdpb24gb2YgdGhpcy5zZWxlY3RlZFJlZ2lvbnMpIHtcbiAgICAgIGNvbnN0IGxhYmVsID0gcmVnaW9uLmxhYmVsPy50cmltKCkgPz8gJyc7XG4gICAgICBpZiAoc2VlZEJ5TGFiZWwuaGFzKGxhYmVsKSkgY29udGludWU7XG4gICAgICBzZWVkQnlMYWJlbC5zZXQobGFiZWwsIHJlZ2lvbi5jb2xvciA/PyAobGFiZWwgPyB0aGlzLmNvbG9yRm9yTmFtZShsYWJlbCkgOiB0aGlzLnNoYXBlQ29sb3IpKTtcbiAgICB9XG4gICAgdGhpcy5jbGFzc0NvbG9yRWRpdHMgPSBbLi4uc2VlZEJ5TGFiZWxdLm1hcCgoW2xhYmVsLCBjb2xvcl0pID0+ICh7IGxhYmVsLCBjb2xvciB9KSk7XG4gICAgdGhpcy5zaG93Q29sb3JEaWFsb2cgPSB0cnVlO1xuICB9XG5cbiAgLyoqIEFwcGx5IGVhY2ggY2xhc3MncyBjaG9zZW4gY29sb3VyIHRvIHRoZSBzZWxlY3RlZCByZWdpb25zIG9mIHRoYXQgY2xhc3MgKGFuXG4gICAqICBleHBsaWNpdCBvdmVycmlkZSkgYW5kIGNvbW1pdCBsaXZlLiAqL1xuICBwcm90ZWN0ZWQgYXBwbHlDb2xvclRvU2VsZWN0ZWQoZWRpdHM6IENsYXNzQ29sb3JFZGl0W10gPSB0aGlzLmNsYXNzQ29sb3JFZGl0cykge1xuICAgIGNvbnN0IGNvbG9yQnlMYWJlbCA9IG5ldyBNYXAoZWRpdHMubWFwKChlKSA9PiBbZS5sYWJlbCwgZS5jb2xvcl0pKTtcbiAgICBjb25zdCBzZWxlY3RlZCA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZFJlZ2lvbnMgPz8gW10pO1xuICAgIHRoaXMucGF0Y2hSZWdpb25zKChyZWdpb24pID0+IHtcbiAgICAgIGlmICghc2VsZWN0ZWQuaGFzKHJlZ2lvbikpIHJldHVybiBudWxsO1xuICAgICAgY29uc3QgbGFiZWwgPSByZWdpb24ubGFiZWw/LnRyaW0oKSA/PyAnJztcbiAgICAgIGNvbnN0IGNvbG9yID0gY29sb3JCeUxhYmVsLmdldChsYWJlbCk7XG4gICAgICBpZiAoIWNvbG9yKSByZXR1cm4gbnVsbDtcbiAgICAgIC8vIGV4cGxpY2l0IGNvbG91ciDigJQgcHJlc2VydmUgYWdhaW5zdCBwcmVzZXQgKHJlKWFwcGx5IChqaXQtdWkjNzApXG4gICAgICByZXR1cm4geyBjb2xvciwgY29sb3JPdmVycmlkZGVuOiB0cnVlIH07XG4gICAgfSk7XG4gICAgdGhpcy5jb21taXQoKTtcbiAgICB0aGlzLnNob3dDb2xvckRpYWxvZyA9IGZhbHNlO1xuICB9XG5cbiAgLy8g4pSA4pSAIGFubm90YXRpb24tY2xhc3MgcHJlc2V0cyAoaml0LXVpIzcwKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVzb2x2ZSB0aGUgZGlzcGxheSBjb2xvdXIgZm9yIGEgY2xhc3MgbmFtZSAocHJlc2V0IGNvbG91ciBvciBkZXRlcm1pbmlzdGljIGZhbGxiYWNrKS4gKi9cbiAgcHJvdGVjdGVkIGNvbG9yRm9yTmFtZShuYW1lPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmFtZSA/IGNvbG9yRm9yTGFiZWwobmFtZSwgdGhpcy5wcmVzZXRTZXQpIDogdGhpcy5zaGFwZUNvbG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZSBldmVyeSBjbGFzcyBsYWJlbCBwcmVzZW50IGluIHRoZSBsb2FkZWQgcmVnaW9ucyBleGlzdHMgaW4gdGhlIHByZXNldFxuICAgKiBsaXN0LCBhdXRvLWFkZGluZyBhbnkgdGhhdCBhcmUgbWlzc2luZyAodXNpbmcgdGhlIHJlZ2lvbidzIGFscmVhZHktcmVzb2x2ZWRcbiAgICogY29sb3VyKS4gVGhpcyBtYWtlcyBjbGFzc2VzIGNhcnJpZWQgaW4gYSBsb2FkZWQvaW1wb3J0ZWQgR2VvSlNPTiBzaG93IHVwIGFzXG4gICAqIGNoaXBzICsgQ2xhc3MtZHJvcGRvd24gb3B0aW9ucyAoYSBwLWRyb3Bkb3duIGNhbid0IGRpc3BsYXkgYSB2YWx1ZSB0aGF0IGlzbid0XG4gICAqIGFuIG9wdGlvbikgYW5kIGxldHMgdGhlIHVzZXIgbWFuYWdlIHRoZW0uIFRoZSBwbGFjZWhvbGRlciAnbGVnZW5kJyBhbmQgZW1wdHlcbiAgICogbGFiZWxzIGFyZSBpZ25vcmVkLiAoaml0LXVpIzcwKVxuICAgKi9cbiAgcHJpdmF0ZSBzeW5jQ2xhc3Nlc0Zyb21SZWdpb25zKHJlZ2lvbnM6IFJlZ2lvbltdKTogdm9pZCB7XG4gICAgY29uc3Qga2V5T2YgPSAobDogc3RyaW5nKSA9PiBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIGwpO1xuICAgIGNvbnN0IGtub3duID0gbmV3IFNldCh0aGlzLnByZXNldFNldC5jbGFzc2VzLm1hcCgoYykgPT4ga2V5T2YoYy5uYW1lKSkpO1xuICAgIGNvbnN0IGFkZGVkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICAgIGNvbnN0IGxhYmVsID0gci5sYWJlbD8udHJpbSgpO1xuICAgICAgaWYgKCFsYWJlbCB8fCBsYWJlbCA9PT0gJ2xlZ2VuZCcpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgayA9IGtleU9mKGxhYmVsKTtcbiAgICAgIGlmIChrbm93bi5oYXMoaykgfHwgYWRkZWQuaGFzKGspKSBjb250aW51ZTtcbiAgICAgIGFkZGVkLmFkZChrKTtcbiAgICAgIHRoaXMucmVnaW9uQXBpLnVwc2VydENsYXNzKHtcbiAgICAgICAgbmFtZTogbGFiZWwsXG4gICAgICAgIGNvbG9yOiByLmNvbG9yIHx8IGNvbG9yRm9yTGFiZWwobGFiZWwsIHRoaXMucHJlc2V0U2V0KSxcbiAgICAgICAgc291cmNlOiAnYXV0bycsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgRG9ja2VkIENsYXNzZXMgcGFuZWwgKGppdC11aSM3MCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGNsYXNzZXMgY291bnQgZXZlcnkgc2xpY2Ugb2YgdGhlIHN0YWNrOiBpbiBhIHZvbHVtZSB2aWV3ICh0aGUgd2hvbGUgc3RhY2sgb25cbiAgICogc2NyZWVuKSwgdW5sZXNzIGl0cyBzbGljZSBwYW5lIHNob3dzIG9uZSBzbGljZS4gVGhlIHRhYmxlIGxpc3RzIHRoZSBzbGljZSdzIHJlZ2lvbnMgYW55d2F5LlxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgc3RhY2tDb3VudHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudm9sdW1lVmlldyAmJiAhdGhpcy5zbGljZVBhbmU7XG4gIH1cblxuICAvKiogUmVidWlsZCB0aGUgcGVyLWNsYXNzIHJlZ2lvbiBjb3VudHMgc2hvd24gaW4gdGhlIHBhbmVsICh0aGUgc3RhY2sncywgc2VlIHN0YWNrQ291bnRzKS4gKi9cbiAgcHJpdmF0ZSByZWNvbXB1dGVDbGFzc0NvdW50cygpOiB2b2lkIHtcbiAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGNvbnN0IHRyZWUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGNvbnN0IGFkZCA9IChsYWJlbDogc3RyaW5nLCBuOiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IGsgPSBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIGxhYmVsKTtcbiAgICAgIGNvdW50cy5zZXQoaywgKGNvdW50cy5nZXQoaykgPz8gMCkgKyBuKTtcbiAgICAgIHRyZWUuc2V0KGxhYmVsLCAodHJlZS5nZXQobGFiZWwpID8/IDApICsgbik7XG4gICAgfTtcbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5zdGFja0NvdW50cyA/IHRoaXMucmVnaW9uQXBpLmdldFNsaWNlQW5ub3RhdGlvblJlZ2lvbnMoKSA6IHRoaXMucmVnaW9ucztcbiAgICBmb3IgKGNvbnN0IHIgb2YgcmVnaW9ucykgaWYgKHIubGFiZWwpIGFkZChyLmxhYmVsLCAxKTtcbiAgICAvLyBUaGUgcmVnaW9uIHNvdXJjZSdzIGNsYXNzZXMgY291bnQgdG9vIChpdHMgZmVhdHVyZXMgYXJlIHJvd3Mgb2YgdGhlIHRhYmxlKS5cbiAgICBmb3IgKGNvbnN0IFtsYWJlbCwgbl0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5zb3VyY2VDbGFzc0NvdW50cykpIGFkZChsYWJlbCwgbik7XG4gICAgdGhpcy5jbGFzc0NvdW50cyA9IGNvdW50cztcbiAgICB0aGlzLnRyZWVDb3VudHMgPSB0cmVlO1xuICAgIHRoaXMudXBkYXRlRGlzcGxheUNsYXNzZXMoKTtcbiAgfVxuXG4gIC8qKiBSZWJ1aWxkIHRoZSBwYW5lbCdzIGRpc3BsYXkgb3JkZXIg4oCUIG1vc3QtdXNlZCBjbGFzc2VzIGZpcnN0LCB0aGVuIGJ5IG5hbWUuIEEgY2xhc3Mgb25seVxuICAgKiAgdGhlIHJlZ2lvbiBzb3VyY2UgaGFzIGlzIGxpc3RlZCB0b28sIGluIGl0cyBjb2xvdXIuICovXG4gIHByaXZhdGUgdXBkYXRlRGlzcGxheUNsYXNzZXMoKTogdm9pZCB7XG4gICAgY29uc3Qga25vd24gPSBuZXcgU2V0KHRoaXMucHJlc2V0U2V0LmNsYXNzZXMubWFwKChjKSA9PiBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIGMubmFtZSkpKTtcbiAgICBjb25zdCBmcm9tU291cmNlOiBDbGFzc1ByZXNldFtdID0gW107XG4gICAgZm9yIChjb25zdCBsYWJlbCBvZiBPYmplY3Qua2V5cyh0aGlzLnNvdXJjZUNsYXNzQ291bnRzKSkge1xuICAgICAgY29uc3QgayA9IHByZXNldEtleSh0aGlzLnByZXNldFNldCwgbGFiZWwpO1xuICAgICAgaWYgKGtub3duLmhhcyhrKSkgY29udGludWU7XG4gICAgICBrbm93bi5hZGQoayk7XG4gICAgICBmcm9tU291cmNlLnB1c2goeyBuYW1lOiBsYWJlbCwgY29sb3I6IGNvbG9yRm9yTGFiZWwobGFiZWwsIHRoaXMucHJlc2V0U2V0KSB9KTtcbiAgICB9XG4gICAgdGhpcy50YWJsZVByZXNldFNldCA9IGZyb21Tb3VyY2UubGVuZ3RoXG4gICAgICA/IHsgLi4udGhpcy5wcmVzZXRTZXQsIGNsYXNzZXM6IFsuLi50aGlzLnByZXNldFNldC5jbGFzc2VzLCAuLi5mcm9tU291cmNlXSB9XG4gICAgICA6IHRoaXMucHJlc2V0U2V0O1xuICAgIHRoaXMuZGlzcGxheUNsYXNzZXMgPSBbLi4udGhpcy5wcmVzZXRTZXQuY2xhc3NlcywgLi4uZnJvbVNvdXJjZV0uc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3QgZCA9IHRoaXMuY2xhc3NDb3VudChiLm5hbWUpIC0gdGhpcy5jbGFzc0NvdW50KGEubmFtZSk7XG4gICAgICByZXR1cm4gZCAhPT0gMCA/IGQgOiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIE51bWJlciBvZiByZWdpb25zIGN1cnJlbnRseSB1c2luZyBhIGNsYXNzIChrZXllZCBieSB0aGUgYWN0aXZlIG1hdGNoIG1vZGUpLiAqL1xuICBwcm90ZWN0ZWQgY2xhc3NDb3VudChuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNsYXNzQ291bnRzLmdldChwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIG5hbWUpKSA/PyAwO1xuICB9XG5cbiAgLyoqIFJlY29sb3VyIGEgY2xhc3MgZnJvbSBpdHMgcGFuZWwgc3dhdGNoIGFuZCByZXBhaW50IGl0cyAobm9uLW92ZXJyaWRkZW4pIHJlZ2lvbnMuICovXG4gIHByb3RlY3RlZCBzZXRDbGFzc0NvbG9yKG5hbWU6IHN0cmluZywgY29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghY29sb3IpIHJldHVybjtcbiAgICB0aGlzLnJlZ2lvbkFwaS5zZXRDbGFzc2lmaWNhdGlvbkNvbG9yKG5hbWUsIGNvbG9yKTtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICB9XG5cbiAgLyoqIFJlbW92ZSBhIGNsYXNzLiBBbnkgcmVnaW9ucyBzdGlsbCB1c2luZyBpdCBmYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHRcbiAgICogIFwiUmVnaW9uXCIgY2xhc3MsIHNvIHRoZXkgYXJlbid0IG9ycGhhbmVkIChhbmQgdGhlIGNsYXNzIGlzbid0IGltbWVkaWF0ZWx5XG4gICAqICByZS1hZGRlZCBmcm9tIGl0cyByZWdpb25zIGJ5IHN5bmNDbGFzc2VzRnJvbVJlZ2lvbnMpLiAqL1xuICBwcm90ZWN0ZWQgZGVsZXRlQ2xhc3MobmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5yZWFzc2lnblJlZ2lvbnNUb0RlZmF1bHRDbGFzcyhbbmFtZV0pO1xuICAgIHRoaXMucmVnaW9uQXBpLnJlbW92ZUNsYXNzKG5hbWUpO1xuICAgIGlmICh0aGlzLmFjdGl2ZUNsYXNzID09PSBuYW1lKSB0aGlzLmFjdGl2ZUNsYXNzID0gbnVsbDtcbiAgICB0aGlzLmNvbW1pdCgpO1xuICB9XG5cbiAgLyoqIFJlZ2lvbnMgbGFiZWxsZWQgd2l0aCBhbnkgb2YgYHJlbW92ZWROYW1lc2AgcmV2ZXJ0IHRvIHRoZSBkZWZhdWx0XG4gICAqICB7QGxpbmsgZGVmYXVsdENsYXNzTmFtZX0gKFwiUmVnaW9uXCIpOiBpdHMgY2xhc3MgY29sb3VyLCBvdmVycmlkZSBjbGVhcmVkLlxuICAgKiAgU2tpcHMgdGhlIGRlZmF1bHQgaXRzZWxmIHNvIGRlbGV0aW5nIFwiUmVnaW9uXCIgY2FuJ3Qgc2VsZi1yZWFzc2lnbi4gKGppdC11aSM3MCkgKi9cbiAgcHJpdmF0ZSByZWFzc2lnblJlZ2lvbnNUb0RlZmF1bHRDbGFzcyhyZW1vdmVkTmFtZXM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3Qga2V5T2YgPSAoczogc3RyaW5nKSA9PiBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIHMpO1xuICAgIGNvbnN0IHJlbW92ZWQgPSBuZXcgU2V0KHJlbW92ZWROYW1lcy5tYXAoa2V5T2YpKTtcbiAgICByZW1vdmVkLmRlbGV0ZShrZXlPZih0aGlzLmRlZmF1bHRDbGFzc05hbWUpKTtcbiAgICBpZiAoIXJlbW92ZWQuc2l6ZSkgcmV0dXJuO1xuICAgIGNvbnN0IGNvbG9yID0gY29sb3JGb3JMYWJlbCh0aGlzLmRlZmF1bHRDbGFzc05hbWUsIHRoaXMucHJlc2V0U2V0KTtcbiAgICB0aGlzLnBhdGNoUmVnaW9ucygocikgPT5cbiAgICAgIHIubGFiZWwgJiYgcmVtb3ZlZC5oYXMoa2V5T2Yoci5sYWJlbCkpXG4gICAgICAgID8geyBsYWJlbDogdGhpcy5kZWZhdWx0Q2xhc3NOYW1lLCBjb2xvck92ZXJyaWRkZW46IGZhbHNlLCBjb2xvciB9XG4gICAgICAgIDogbnVsbCxcbiAgICApO1xuICB9XG5cbiAgLyoqIFN0YW1wIGEgY2xhc3MgKGFuZCBpdHMgcHJlc2V0L2ZhbGxiYWNrIGNvbG91cikgb250byBvbmUgcmVnaW9uIGZyb20gdGhlIENsYXNzXG4gICAqICBkcm9wZG93bjsgY2hvb3NpbmcgYSBjbGFzcyBvcHRzIHRoZSByZWdpb24gYmFjayBpbnRvIHRoZSBwcmVzZXQgY29sb3VyLiAqL1xuICBwcm90ZWN0ZWQgYXBwbHlQcmVzZXRUb1JlZ2lvbihyZWdpb246IFJlZ2lvbiwgY2xhc3NOYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdGFuZElucy5oYXMocmVnaW9uKSkge1xuICAgICAgdm9pZCB0aGlzLnRha2VUaGVuKHJlZ2lvbiwgKHIpID0+IHRoaXMuYXBwbHlQcmVzZXRUb1JlZ2lvbihyLCBjbGFzc05hbWUpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbmFtZSA9IChjbGFzc05hbWUgPz8gJycpLnRyaW0oKTtcbiAgICBjb25zdCBwYXRjaDogUGFydGlhbDxSZWdpb24+ID0geyBsYWJlbDogbmFtZSwgY29sb3JPdmVycmlkZGVuOiBmYWxzZSB9O1xuICAgIGlmIChuYW1lKSBwYXRjaC5jb2xvciA9IGNvbG9yRm9yTGFiZWwobmFtZSwgdGhpcy5wcmVzZXRTZXQpO1xuICAgIHRoaXMucGF0Y2hSZWdpb25zKChyKSA9PiAociA9PT0gcmVnaW9uID8gcGF0Y2ggOiBudWxsKSk7XG4gICAgdGhpcy5jb21taXQoKTtcbiAgfVxuXG4gIC8qKiBNYWtlIGEgY2xhc3MgYWN0aXZlICh1c2VkIGZvciBuZXcgcmVnaW9ucykgYW5kLCBpZiByb3dzIGFyZSBzZWxlY3RlZCwgYXBwbHlcbiAgICogIGl0IHRvIHRoZW0gaW4gb25lIGNvbW1pdC4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdEFjdGl2ZUNsYXNzKG5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlQ2xhc3MgPSBuYW1lO1xuICAgIHRoaXMuYXBwbHlDbGFzc1RvU2VsZWN0ZWQobmFtZSk7XG4gIH1cblxuICAvKiogQXBwbHkgYSBjbGFzcyAobGFiZWwgKyBwcmVzZXQvZmFsbGJhY2sgY29sb3VyKSB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24gYW5kIGNvbW1pdC4gKi9cbiAgcHJpdmF0ZSBhcHBseUNsYXNzVG9TZWxlY3RlZChuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3RlZCA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZFJlZ2lvbnMgPz8gW10pO1xuICAgIGlmICghc2VsZWN0ZWQuc2l6ZSkgcmV0dXJuO1xuICAgIGNvbnN0IGNvbG9yID0gY29sb3JGb3JMYWJlbChuYW1lLCB0aGlzLnByZXNldFNldCk7XG4gICAgdGhpcy5wYXRjaFJlZ2lvbnMoKHIpID0+IChzZWxlY3RlZC5oYXMocikgPyB7IGxhYmVsOiBuYW1lLCBjb2xvck92ZXJyaWRkZW46IGZhbHNlLCBjb2xvciB9IDogbnVsbCkpO1xuICAgIHRoaXMuY29tbWl0KCk7XG4gIH1cblxuICAvKiogXCJFZGl0IGNsYXNzIG9uIHNlbGVjdGVkIHJvd3NcIiBwb3B1cCDigJQgYXBwbHkgdGhlIGNob3NlbiBleGlzdGluZyBjbGFzcy4gKi9cbiAgcHJvdGVjdGVkIGFwcGx5QnVsa0NsYXNzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5idWxrQ2xhc3MpIHJldHVybjtcbiAgICB0aGlzLmFwcGx5Q2xhc3NUb1NlbGVjdGVkKHRoaXMuYnVsa0NsYXNzKTtcbiAgICB0aGlzLm92ZXJsYXlQYW5lbD8uaGlkZSgpO1xuICB9XG5cbiAgLyoqIFwiRWRpdCBjbGFzcyBvbiBzZWxlY3RlZCByb3dzXCIgcG9wdXAg4oCUIGFkZCBhIG5ldyBjbGFzcyBhbmQgc2V0IGl0IG9uIHRoZSBzZWxlY3Rpb24uICovXG4gIHByb3RlY3RlZCBhZGRBbmRBcHBseUJ1bGtDbGFzcygpOiB2b2lkIHtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5uZXdCdWxrQ2xhc3MudHJpbSgpO1xuICAgIGlmICghbmFtZSkgcmV0dXJuO1xuICAgIGNvbnN0IGtleSA9IHByZXNldEtleSh0aGlzLnByZXNldFNldCwgbmFtZSk7XG4gICAgY29uc3QgZXhpc3RzID0gdGhpcy5wcmVzZXRTZXQuY2xhc3Nlcy5zb21lKChjKSA9PiBwcmVzZXRLZXkodGhpcy5wcmVzZXRTZXQsIGMubmFtZSkgPT09IGtleSk7XG4gICAgaWYgKCFleGlzdHMpIHtcbiAgICAgIHRoaXMucmVnaW9uQXBpLnVwc2VydENsYXNzKHsgbmFtZSwgY29sb3I6IGNvbG9yRm9yTGFiZWwobmFtZSwgdGhpcy5wcmVzZXRTZXQpLCBzb3VyY2U6ICd1c2VyJyB9KTtcbiAgICB9XG4gICAgdGhpcy5hcHBseUNsYXNzVG9TZWxlY3RlZChuYW1lKTtcbiAgICB0aGlzLmJ1bGtDbGFzcyA9IG5hbWU7XG4gICAgdGhpcy5uZXdCdWxrQ2xhc3MgPSAnJztcbiAgICB0aGlzLm92ZXJsYXlQYW5lbD8uaGlkZSgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIE1hbmFnZS1jbGFzc2VzIGRpYWxvZyDilIDilIBcbiAgcHJvdGVjdGVkIG9wZW5NYW5hZ2VEaWFsb2coKTogdm9pZCB7XG4gICAgdGhpcy5wcmVzZXREcmFmdCA9IHRoaXMuY2xvbmVQcmVzZXRTZXQodGhpcy5wcmVzZXRTZXQpO1xuICAgIHRoaXMuc2hvd01hbmFnZURpYWxvZyA9IHRydWU7XG4gIH1cbiAgcHJpdmF0ZSBjbG9uZVByZXNldFNldChzOiBQcmVzZXRTZXQpOiBQcmVzZXRTZXQge1xuICAgIHJldHVybiB7XG4gICAgICBjbGFzc2VzOiAocy5jbGFzc2VzID8/IFtdKS5tYXAoKGMpID0+ICh7IC4uLmMgfSkpLFxuICAgICAgZmFsbGJhY2tQYWxldHRlOiBbLi4uKHMuZmFsbGJhY2tQYWxldHRlID8/IFtdKV0sXG4gICAgICBhdXRvUHJvbW90ZTogISFzLmF1dG9Qcm9tb3RlLFxuICAgICAgbWF0Y2hNb2RlOiBzLm1hdGNoTW9kZSA9PT0gJ25vcm1hbGl6ZWQnID8gJ25vcm1hbGl6ZWQnIDogJ2V4YWN0JyxcbiAgICB9O1xuICB9XG4gIC8qKiBDb21taXQgdGhlIGRyYWZ0OiBkcm9wIGJsYW5rL2R1cGxpY2F0ZSBuYW1lcywgcGVyc2lzdCwgYW5kIHJlY29sb3VyXG4gICAqICBub24tb3ZlcnJpZGRlbiByZWdpb25zIHdpdGggdGhlIHVwZGF0ZWQgcHJlc2V0cy4gKi9cbiAgcHJvdGVjdGVkIGFwcGx5TWFuYWdlRGlhbG9nKGNsb3NlOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnByZXNldERyYWZ0KSByZXR1cm47XG4gICAgLy8gRGUtZHVwbGljYXRlIHVzaW5nIHRoZSBhY3RpdmUgbWF0Y2ggbW9kZSdzIGtleSBzbyBub3JtYWxpemVkIG1vZGUgY2FuJ3Qga2VlcFxuICAgIC8vIGJvdGggXCJUdW1vclwiIGFuZCBcInR1bW9yXCIgKHdoaWNoIHdvdWxkIGNvbGxpZGUgYXQgcnVudGltZSBpbiBmaW5kUHJlc2V0KCkpLlxuICAgIGNvbnN0IGRyYWZ0ID0gdGhpcy5wcmVzZXREcmFmdDtcbiAgICBjb25zdCBrZXlPZiA9IChzOiBzdHJpbmcpID0+IHByZXNldEtleShkcmFmdCwgcyk7XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNsYXNzZXM6IENsYXNzUHJlc2V0W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGMgb2YgZHJhZnQuY2xhc3Nlcykge1xuICAgICAgY29uc3QgbmFtZSA9IChjLm5hbWUgPz8gJycpLnRyaW0oKTtcbiAgICAgIGNvbnN0IGtleSA9IGtleU9mKG5hbWUpO1xuICAgICAgaWYgKCFuYW1lIHx8IHNlZW4uaGFzKGtleSkpIGNvbnRpbnVlO1xuICAgICAgc2Vlbi5hZGQoa2V5KTtcbiAgICAgIGNsYXNzZXMucHVzaCh7IC4uLmMsIG5hbWUgfSk7XG4gICAgfVxuICAgIHRoaXMucHJlc2V0RHJhZnQgPSB7IC4uLmRyYWZ0LCBjbGFzc2VzIH07XG4gICAgLy8gQ2xhc3NlcyBkcm9wcGVkIGluIHRoZSBkaWFsb2c6IHRoZWlyIHJlZ2lvbnMgcmV2ZXJ0IHRvIHRoZSBkZWZhdWx0IFwiUmVnaW9uXCJcbiAgICAvLyBjbGFzcyAoZWxzZSBzeW5jQ2xhc3Nlc0Zyb21SZWdpb25zIHdvdWxkIGp1c3QgcmUtYWRkIHRoZW0pIChqaXQtdWkjNzApLlxuICAgIGNvbnN0IGtlcHQgPSBuZXcgU2V0KGNsYXNzZXMubWFwKChjKSA9PiBrZXlPZihjLm5hbWUpKSk7XG4gICAgY29uc3QgcmVtb3ZlZCA9IHRoaXMucHJlc2V0U2V0LmNsYXNzZXMubWFwKChjKSA9PiBjLm5hbWUpLmZpbHRlcigobikgPT4gIWtlcHQuaGFzKGtleU9mKG4pKSk7XG4gICAgdGhpcy5yZWFzc2lnblJlZ2lvbnNUb0RlZmF1bHRDbGFzcyhyZW1vdmVkKTtcbiAgICB0aGlzLnJlZ2lvbkFwaS5zZXRQcmVzZXRTZXQodGhpcy5wcmVzZXREcmFmdCk7XG4gICAgdGhpcy5jb21taXQoKTsgLy8gcmVjb2xvdXIgZXhpc3RpbmcgKG5vbi1vdmVycmlkZGVuKSByZWdpb25zIGZyb20gdGhlIG5ldyBwcmVzZXRzXG4gICAgaWYgKGNsb3NlKSB0aGlzLnNob3dNYW5hZ2VEaWFsb2cgPSBmYWxzZTtcbiAgfVxuICBwcm90ZWN0ZWQgcmVzZXRQcmVzZXRzVG9EZWZhdWx0cygpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFwaS5yZXNldFByZXNldHMoKTtcbiAgICB0aGlzLnByZXNldERyYWZ0ID0gdGhpcy5jbG9uZVByZXNldFNldCh0aGlzLnJlZ2lvbkFwaS5nZXRQcmVzZXRTZXQoKSk7XG4gICAgdGhpcy5jb21taXQoKTtcbiAgfVxuICBwcm90ZWN0ZWQgZXhwb3J0UHJlc2V0cygpOiB2b2lkIHtcbiAgICBjb25zdCBqc29uID0gSlNPTi5zdHJpbmdpZnkodGhpcy5jbG9uZVByZXNldFNldCh0aGlzLnJlZ2lvbkFwaS5nZXRQcmVzZXRTZXQoKSksIG51bGwsIDIpO1xuICAgIHNhdmVBcyhuZXcgQmxvYihbanNvbl0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nIH0pLCAnYW5ub3RhdGlvbi1jbGFzc2VzLmpzb24nKTtcbiAgfVxuICBwcm90ZWN0ZWQgaW1wb3J0UHJlc2V0cyhldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnBlcnNpc3RlbmNlLnJlYWRDaG9zZW5GaWxlKGV2ZW50LCAodGV4dCkgPT4gdGhpcy5hcHBseUltcG9ydGVkUHJlc2V0cyh0ZXh0KSk7XG4gIH1cblxuICAvKiogVmFsaWRhdGUgYW5kIGFwcGx5IGFuIGltcG9ydGVkIGFubm90YXRpb24tY2xhc3NlcyBKU09OIGZpbGUuICovXG4gIHByaXZhdGUgYXBwbHlJbXBvcnRlZFByZXNldHModGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNldCA9IHBhcnNlUHJlc2V0U2V0KEpTT04ucGFyc2UodGV4dCkpO1xuICAgICAgaWYgKCFzZXQpIHRocm93IG5ldyBFcnJvcignVGhlIGZpbGUgaXMgbm90IGFuIGFubm90YXRpb24tY2xhc3MgbGlzdCAobm8gdmFsaWQgY2xhc3NlcykuJyk7XG4gICAgICB0aGlzLnJlZ2lvbkFwaS5zZXRQcmVzZXRTZXQoc2V0KTtcbiAgICAgIHRoaXMucHJlc2V0RHJhZnQgPSB0aGlzLmNsb25lUHJlc2V0U2V0KHRoaXMucmVnaW9uQXBpLmdldFByZXNldFNldCgpKTtcbiAgICAgIHRoaXMuY29tbWl0KCk7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgIGtleTogVklaX1RPQVNUX0tFWSxcbiAgICAgICAgc2V2ZXJpdHk6ICdzdWNjZXNzJyxcbiAgICAgICAgc3VtbWFyeTogJ0NsYXNzZXMgaW1wb3J0ZWQnLFxuICAgICAgICBkZXRhaWw6ICdBbm5vdGF0aW9uIGNsYXNzZXMgbG9hZGVkLicsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAga2V5OiBWSVpfVE9BU1RfS0VZLFxuICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgc3VtbWFyeTogJ0ltcG9ydCBmYWlsZWQnLFxuICAgICAgICBkZXRhaWw6IGAkeyhlcnIgYXMgRXJyb3IpPy5tZXNzYWdlID8/IGVycn1gLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIFRoZSBmaWxlcyBjaG9zZW4gaW4gdGhlIGltcG9ydCBpbnB1dHM6IG9uZSBHZW9KU09OLCBhIGxhYmVsIHZvbHVtZSB3aXRoIGl0cyBvbnRvbG9neSwgb3IgYVxuICAgKiAgZm9sZGVyIG9mIHBlci1zbGljZSBHZW9KU09OIGZpbGVzLiAqL1xuICBwcm90ZWN0ZWQgaW1wb3J0Um9pcyhldmVudDogRXZlbnQpIHtcbiAgICBjb25zdCBmaWxlcyA9IEFycmF5LmZyb20oKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS5maWxlcyA/PyBbXSk7XG4gICAgaWYgKGZpbGVzLmxlbmd0aCkgdm9pZCB0aGlzLmltcG9ydFJlZ2lvbkZpbGVzKGZpbGVzLm1hcCgoZikgPT4gaW1wb3J0RmlsZShmLCBmLndlYmtpdFJlbGF0aXZlUGF0aCB8fCBmLm5hbWUpKSk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgaG9zdCBjYW4gcGljayByZWdpb25zIG9uIGl0cyBzZXJ2ZXIgKFwiSW1wb3J0IHJlZ2lvbnMgZnJvbSBzZXJ2ZXJcIikuICovXG4gIHByb3RlY3RlZCBnZXQgY2FuSW1wb3J0RnJvbVNlcnZlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5wZXJzaXN0ZW5jZS5jYW5QaWNrU2VydmVyUmVnaW9ucygpO1xuICB9XG4gIC8qKiBBbiBpbXBvcnQgZnJvbSB0aGUgc2VydmVyIGlzIGluIGZsaWdodC4gKi9cbiAgcHJvdGVjdGVkIGltcG9ydGluZyA9IGZhbHNlO1xuXG4gIC8qKiBcIkltcG9ydCByZWdpb25zIGZyb20gc2VydmVyXCI6IHRoZSBob3N0IHBpY2tzIGZpbGVzIG9yIGEgc2VydmVkIHJlZ2lvbiBzZXQ7IHRoZXkgaW1wb3J0IGFzIGNob3NlbiBmaWxlcyBkby4gKi9cbiAgcHJvdGVjdGVkIGltcG9ydEZyb21TZXJ2ZXIoKTogdm9pZCB7XG4gICAgdGhpcy5pbXBvcnRpbmcgPSB0cnVlO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIHRoaXMucGVyc2lzdGVuY2UucGlja1NlcnZlclJlZ2lvbnMoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHBpY2spID0+IHtcbiAgICAgICAgaWYgKCFwaWNrKSByZXR1cm47XG4gICAgICAgIGlmIChwaWNrLmtpbmQgPT09ICdmaWxlcycpIHtcbiAgICAgICAgICB2b2lkIHRoaXMuaW1wb3J0UmVnaW9uRmlsZXMocGljay5maWxlcy5tYXAoKGYpID0+IGltcG9ydEZpbGUoZi5kYXRhLCBmLm5hbWUpKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZvaWQgdGhpcy5pbXBvcnRTZXJ2ZWRSZWdpb25TZXQocGljay51cmwsIHBpY2submFtZSk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnIpID0+IHRoaXMuaW1wb3J0RmFpbGVkKGVyciksXG4gICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICB0aGlzLmltcG9ydGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGBmaWxlc2AgKHNlZSBwbGFuUmVnaW9uSW1wb3J0KTogb25lIEdlb0pTT04gZmlsZSBhcyBiZWZvcmU7IGEgbGFiZWwgdm9sdW1lIGFzIG9uZVxuICAgKiByZWdpb24gc291cmNlIHBlciBzbGljZSwgdHJhY2VkIGZyb20gaXQgdGhlIGZpcnN0IHRpbWUgdGhlIHNsaWNlIGlzIHNob3duLCBpdHMgY2xhc3NlcyBuYW1lZFxuICAgKiAoYW5kIHRyZWVkKSBieSB0aGUgb250b2xvZ3kgY2hvc2VuIHdpdGggaXQ7IGEgZm9sZGVyIGFzIG9uZSBzb3VyY2UgcGVyIHNsaWNlIGZpbGUuIEVpdGhlclxuICAgKiByZXBsYWNlcyB0aGUgcmVnaW9ucyBhbmQgc291cmNlcyBvZiBldmVyeSBzbGljZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaW1wb3J0UmVnaW9uRmlsZXMoZmlsZXM6IFJlZ2lvbkltcG9ydEZpbGVbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBsYW4gPSBwbGFuUmVnaW9uSW1wb3J0KGZpbGVzKTtcbiAgICBpZiAoIXBsYW4pIHtcbiAgICAgIHRoaXMuaW1wb3J0RmFpbGVkKFxuICAgICAgICBuZXcgRXJyb3IoJ0Nob29zZSBhIEdlb0pTT04gZmlsZSwgYSBmb2xkZXIgb2YgR2VvSlNPTiBmaWxlcywgb3IgYSAubmlpLCAubmlpLmd6IG9yIC5ucnJkIGxhYmVsIHZvbHVtZS4nKSxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwbGFuLmtpbmQgPT09ICdzaW5nbGUnKSB7XG4gICAgICBhd2FpdCB0aGlzLmFwcGx5SW1wb3J0ZWRSb2lzKGF3YWl0IHBsYW4uZmlsZS50ZXh0KCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhdHRhY2ggPSB0aGlzLnJlZ2lvbkFwaS5pbXBvcnRTbGljZVJlZ2lvblNvdXJjZXM/LmJpbmQodGhpcy5yZWdpb25BcGkpO1xuICAgIGlmICghYXR0YWNoKSB7XG4gICAgICB0aGlzLmltcG9ydEZhaWxlZChuZXcgRXJyb3IoJ1RoaXMgdmlld2VyIGNhbm5vdCBob2xkIHJlZ2lvbiBzb3VyY2VzLicpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gVGFrZW4gYmVmb3JlIHRoZSBmaWxlcyBhcmUgcmVhZDogZGVjb2RpbmcgYSB2b2x1bWUgdGFrZXMgYSB3aGlsZSwgYW5kIHRoZSBpbXBvcnQgbXVzdCBsYW5kXG4gICAgLy8gb24gdGhlIGltYWdlIGl0IHdhcyBzdGFydGVkIGZvciwgbm90IG9uIG9uZSBzaG93biBtZWFud2hpbGUuXG4gICAgY29uc3QgdGlja2V0ID0gdGhpcy5yZWdpb25BcGkucmVnaW9uSW1wb3J0VGlja2V0Py4oKTtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgb3BlbmVycyA9IG5ldyBNYXA8bnVtYmVyLCBSZWdpb25Tb3VyY2VPcGVuZXI+KCk7XG4gICAgICBsZXQgc3VtbWFyeTogc3RyaW5nO1xuICAgICAgaWYgKHBsYW4ua2luZCA9PT0gJ3ZvbHVtZScpIHtcbiAgICAgICAgY29uc3Qgdm9sdW1lID0gYXdhaXQgcmVhZExhYmVsVm9sdW1lKHBsYW4udm9sdW1lLm5hbWUsIGF3YWl0IHBsYW4udm9sdW1lLmJ5dGVzKCkpO1xuICAgICAgICBjb25zdCBjbGFzc2VzID0gbGFiZWxDbGFzc2VzKHBsYW4ub250b2xvZ3kgPyBKU09OLnBhcnNlKGF3YWl0IHBsYW4ub250b2xvZ3kudGV4dCgpKSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIGZvciAobGV0IHogPSAwOyB6IDwgdm9sdW1lLnNsaWNlczsgeisrKSB7XG4gICAgICAgICAgb3BlbmVycy5zZXQoeiwgKCkgPT4gb3Blbkdlb0pzb25SZWdpb25Tb3VyY2UobGFiZWxTbGljZUdlb0pzb24odm9sdW1lLCB6LCBjbGFzc2VzKSkpO1xuICAgICAgICB9XG4gICAgICAgIHN1bW1hcnkgPSBgJHt2b2x1bWUuc2xpY2VzfSBzbGljZXMgb2YgJHt2b2x1bWUud2lkdGh9IMOXICR7dm9sdW1lLmhlaWdodH1gO1xuICAgICAgICB0aGlzLndhcm5JZlNpemVEaWZmZXJzKHZvbHVtZS53aWR0aCwgdm9sdW1lLmhlaWdodCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZWdpb25TZXQgPSBwbGFuLnJlZ2lvblNldCA/IEpTT04ucGFyc2UoYXdhaXQgcGxhbi5yZWdpb25TZXQudGV4dCgpKSA6IG51bGw7XG4gICAgICAgIHBsYW4uc2xpY2VzLmZvckVhY2goKGZpbGUsIHopID0+XG4gICAgICAgICAgb3BlbmVycy5zZXQoeiwgYXN5bmMgKCkgPT4gb3Blbkdlb0pzb25SZWdpb25Tb3VyY2UoYXdhaXQgZm9sZGVyU2xpY2VHZW9Kc29uKGZpbGUsIHJlZ2lvblNldCkpKSxcbiAgICAgICAgKTtcbiAgICAgICAgc3VtbWFyeSA9IGAke3BsYW4uc2xpY2VzLmxlbmd0aH0gc2xpY2UgZmlsZXNgO1xuICAgICAgfVxuICAgICAgY29uc3QgYXR0YWNoZWQgPSBhdHRhY2gob3BlbmVycywgdGlja2V0KTtcbiAgICAgIGlmIChhdHRhY2hlZCA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLmltcG9ydFN0YWxlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWZ0ZXJTb3VyY2VJbXBvcnQoKTtcbiAgICAgIHRoaXMudG9hc3QoXG4gICAgICAgICdzdWNjZXNzJyxcbiAgICAgICAgJ1JlZ2lvbnMgaW1wb3J0ZWQnLFxuICAgICAgICBgJHtzdW1tYXJ5fTsgJHthdHRhY2hlZH0gc2xpY2Uke2F0dGFjaGVkID09PSAxID8gJycgOiAncyd9IGFubm90YXRlZC5gLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuaW1wb3J0RmFpbGVkKGVycik7XG4gICAgfVxuICB9XG5cbiAgLyoqIEEgcmVnaW9uIHNldCB0aGUgaG9zdCdzIHNlcnZlciBzZXJ2ZXMgKGppdC1zZXJ2aWNlJ3MgL3JlZ2lvbnMve2lkfS8pLCByZWFkIHRocm91Z2ggaXRzIEh0dHBDbGllbnQuICovXG4gIHByaXZhdGUgYXN5bmMgaW1wb3J0U2VydmVkUmVnaW9uU2V0KHVybDogc3RyaW5nLCBuYW1lPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW1wb3J0U291cmNlID0gdGhpcy5yZWdpb25BcGkuaW1wb3J0UmVnaW9uU291cmNlT3BlbmVyPy5iaW5kKHRoaXMucmVnaW9uQXBpKTtcbiAgICBpZiAoIWltcG9ydFNvdXJjZSkge1xuICAgICAgdGhpcy5pbXBvcnRGYWlsZWQobmV3IEVycm9yKCdUaGlzIHZpZXdlciBjYW5ub3QgaG9sZCByZWdpb24gc291cmNlcy4nKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRpY2tldCA9IHRoaXMucmVnaW9uQXBpLnJlZ2lvbkltcG9ydFRpY2tldD8uKCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGFwcGxpZWQgPSBhd2FpdCBpbXBvcnRTb3VyY2UoXG4gICAgICAgICgpID0+IG9wZW5IdHRwUmVnaW9uU291cmNlKHVybCwgeyBodHRwOiB0aGlzLmh0dHAgPz8gdW5kZWZpbmVkIH0pLFxuICAgICAgICB0aWNrZXQsXG4gICAgICApO1xuICAgICAgaWYgKGFwcGxpZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuaW1wb3J0U3RhbGUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5hZnRlclNvdXJjZUltcG9ydCgpO1xuICAgICAgdGhpcy50b2FzdCgnc3VjY2VzcycsICdSZWdpb25zIGltcG9ydGVkJywgbmFtZSA/PyB1cmwpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5pbXBvcnRGYWlsZWQoZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKiogQW4gaW1wb3J0IHRoYXQgZmluaXNoZWQgYWZ0ZXIgYW5vdGhlciBpbWFnZSB3YXMgc2hvd24gKG9yIGFub3RoZXIgaW1wb3J0IGJlZ2FuKTogZHJvcHBlZC4gKi9cbiAgcHJpdmF0ZSBpbXBvcnRTdGFsZSgpOiB2b2lkIHtcbiAgICB0aGlzLnRvYXN0KCdpbmZvJywgJ0ltcG9ydCBkaXNjYXJkZWQnLCAnVGhlIGltYWdlIGNoYW5nZWQgd2hpbGUgdGhlIHJlZ2lvbnMgd2VyZSBiZWluZyByZWFkLicpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIFRoZSB0YWJsZSBhbmQgc2VsZWN0aW9uIGFmdGVyIHRoZSByZWdpb25zIHdlcmUgcmVwbGFjZWQgYnkgaW1wb3J0ZWQgc291cmNlcy4gKi9cbiAgcHJpdmF0ZSBhZnRlclNvdXJjZUltcG9ydCgpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkUmVnaW9ucyA9IFtdO1xuICAgIHRoaXMucGFnaW5hdG9yRmlyc3QgPSAwO1xuICAgIHRoaXMuY29tbWl0KFtdKTtcbiAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIFdhcm4gd2hlbiBhbiBpbXBvcnRlZCB2b2x1bWUncyBzbGljZXMgYXJlIG5vdCB0aGUgaW1hZ2UncyBzaXplOiBpdHMgb3V0bGluZXMgd291bGQgbm90IGZpdC4gKi9cbiAgcHJpdmF0ZSB3YXJuSWZTaXplRGlmZmVycyh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLnJlZ2lvbkFwaS5nZXRNYXNrSW1hZ2VTaXplKCk7XG4gICAgaWYgKG1ldGEgJiYgKG1ldGEud2lkdGggIT09IHdpZHRoIHx8IG1ldGEuaGVpZ2h0ICE9PSBoZWlnaHQpKSB7XG4gICAgICB0aGlzLnRvYXN0KFxuICAgICAgICAnaW5mbycsXG4gICAgICAgICdEaWZmZXJlbnQgc2l6ZScsXG4gICAgICAgIGBUaGUgdm9sdW1lJ3Mgc2xpY2VzIGFyZSAke3dpZHRofSDDlyAke2hlaWdodH07IHRoZSBpbWFnZSBpcyAke21ldGEud2lkdGh9IMOXICR7bWV0YS5oZWlnaHR9LmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW1wb3J0RmFpbGVkKGVycjogdW5rbm93bik6IHZvaWQge1xuICAgIHRoaXMuaW1wb3J0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAga2V5OiBWSVpfVE9BU1RfS0VZLFxuICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICBzdW1tYXJ5OiAnRXJyb3IgaW1wb3J0aW5nIHJlZ2lvbnMnLFxuICAgICAgZGV0YWlsOiBgJHsoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSA/PyBlcnJ9YCxcbiAgICB9KTtcbiAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbXBvcnRpbmcgcmVnaW9uczonLCBlcnIpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIHJlZ2lvbnMgd2l0aCBhbiBpbXBvcnRlZCBHZW9KU09OIGZpbGUncywgYW5kIHRoZSBzbGljZSdzIHJlZ2lvbiBzb3VyY2Ugd2l0aCB0aGVtLlxuICAgKiBBIGxhcmdlIGZpbGUgYmVjb21lcyB0aGUgc2xpY2UncyByZWdpb24gc291cmNlIGluc3RlYWQgKGRyYXduIGJ5IGxldmVsIG9mIGRldGFpbDsgbGlzdGVkIGFib3ZlXG4gICAqIHRoZSB0YWJsZSksIHRoZSB0YWJsZSBlbXB0aWVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhcHBseUltcG9ydGVkUm9pcyh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgaWYgKGF3YWl0IHRoaXMucmVnaW9uQXBpLmltcG9ydFJlZ2lvblNvdXJjZT8uKHRleHQpKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRSZWdpb25zID0gW107XG4gICAgICAgIHRoaXMucGFnaW5hdG9yRmlyc3QgPSAwO1xuICAgICAgICB0aGlzLmNvbW1pdChbXSk7XG4gICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIFBhcnNlZCBmaXJzdDogYSBmaWxlIHRoYXQgaXMgbm90IEdlb0pTT04gbGVhdmVzIHRoZSBzb3VyY2UgYWxvbmUuXG4gICAgICBjb25zdCByZWdpb25zID0gdGhpcy5yZWdpb25BcGkuaW1wb3J0UmVnaW9ucyh0ZXh0KTtcbiAgICAgIGF3YWl0IHRoaXMucmVnaW9uQXBpLmRyb3BSZWdpb25Tb3VyY2U/LigpO1xuICAgICAgdGhpcy5yZWdpb25zID0gcmVnaW9ucztcbiAgICAgIHRoaXMuZmlsbENsYXNzQ29sb3JzKCk7XG4gICAgICB0aGlzLmNvbW1pdCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoe1xuICAgICAgICBrZXk6IFZJWl9UT0FTVF9LRVksXG4gICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICBzdW1tYXJ5OiAnRXJyb3IgaW1wb3J0aW5nIHRoZSBmaWxlJyxcbiAgICAgICAgZGV0YWlsOiBgJHsoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSA/PyBlcnJ9YCxcbiAgICAgIH0pO1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcmVhZGluZyB0aGUgZmlsZTonLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZWdpb25zIHRvIHNlcmlhbGl6ZSBvbiBzYXZlL2V4cG9ydCAoZXZlcnkgc2xpY2UgZm9yIGEgY29tYmluZWQgei1zdGFjaykuICovXG4gIHByaXZhdGUgcmVnaW9uc0ZvclNhdmUoKTogUmVnaW9uW10ge1xuICAgIHJldHVybiB0aGlzLnBlcnNpc3RlbmNlLnJlZ2lvbnNGb3JTYXZlKHRoaXMucmVnaW9ucyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZXhwb3J0Um9pcygpIHtcbiAgICBpZiAoIXRoaXMucmVnaW9uc0ZvclNhdmUoKS5sZW5ndGggJiYgIXRoaXMuaGFzUmVnaW9uU291cmNlKSByZXR1cm47XG4gICAgdGhpcy5leHBvcnRGaWxlbmFtZSA9IHRoaXMucGVyc2lzdGVuY2UuZGVmYXVsdEV4cG9ydE5hbWUoKTtcbiAgICB0aGlzLnNob3dFeHBvcnREaWFsb2cgPSB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbmZpcm1FeHBvcnQoKSB7XG4gICAgY29uc3QgZmlsZW5hbWUgPSB0aGlzLmV4cG9ydEZpbGVuYW1lLnRyaW0oKTtcbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5yZWdpb25zRm9yU2F2ZSgpO1xuICAgIGlmICghZmlsZW5hbWUgfHwgKCFyZWdpb25zLmxlbmd0aCAmJiAhdGhpcy5oYXNSZWdpb25Tb3VyY2UpKSByZXR1cm47XG4gICAgdGhpcy5zaG93RXhwb3J0RGlhbG9nID0gZmFsc2U7XG4gICAgdGhpcy5wZXJzaXN0ZW5jZVxuICAgICAgLmRvd25sb2FkKHJlZ2lvbnMsIGZpbGVuYW1lKVxuICAgICAgLmNhdGNoKChlcnIpID0+IHRoaXMudG9hc3QoJ2Vycm9yJywgJ0Vycm9yIGV4cG9ydGluZyByZWdpb25zJywgYCR7KGVyciBhcyBFcnJvcik/Lm1lc3NhZ2UgPz8gZXJyfWApKTtcbiAgfVxuXG4gIC8qKiBPcGVuIHRoZSBcIlNhdmUgbWFza1wiIGRpYWxvZywgc2VlZGVkIHdpdGggYDxpbWFnZS1zdGVtPl9tYXNrLnBuZ2AuICovXG4gIHByb3RlY3RlZCBvcGVuU2F2ZU1hc2tEaWFsb2coKSB7XG4gICAgaWYgKCF0aGlzLnJlZ2lvbnMubGVuZ3RoKSByZXR1cm47XG4gICAgdGhpcy5zYXZlTWFza0ZpbGVuYW1lID0gdGhpcy5wZXJzaXN0ZW5jZS5kZWZhdWx0TWFza05hbWUoKTtcbiAgICB0aGlzLm1hc2tNb2RlID0gJ2JpbmFyeSc7XG4gICAgdGhpcy5zaG93U2F2ZU1hc2tEaWFsb2cgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJhc3Rlcml6ZSB0aGUgcmVnaW9ucyB0byB0aGUgY2hvc2VuIG1hc2sgdHlwZSBhbmQgZG93bmxvYWQgYXMgYSBQTkcuIFRoZVxuICAgKiBoZWF2eSB3b3JrIHJ1bnMgaW4gYSBXZWIgV29ya2VyICh7QGxpbmsgTWFza0V4cG9ydFNlcnZpY2V9KSBzbyB0aGUgVUkgbmV2ZXJcbiAgICogZnJlZXplcyBvbiB3aG9sZS1zbGlkZSBpbWFnZXMgYW5kIHRoZSBqb2IgY2FuIGJlIGNhbmNlbGxlZCAoaml0LXVpIzk1KTtcbiAgICogdGhlIGRpYWxvZyBzdGF5cyBvcGVuIHdpdGggYSBwcm9ncmVzcyBiYXIgdW50aWwgZG9uZS5cbiAgICovXG4gIHByb3RlY3RlZCBjb25maXJtU2F2ZU1hc2soKSB7XG4gICAgY29uc3QgZmlsZW5hbWUgPSB0aGlzLnNhdmVNYXNrRmlsZW5hbWUudHJpbSgpO1xuICAgIGlmICghZmlsZW5hbWUgfHwgIXRoaXMucmVnaW9ucy5sZW5ndGggfHwgdGhpcy5tYXNrQnVzeSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgc2l6ZSA9IHRoaXMucmVnaW9uQXBpLmdldE1hc2tJbWFnZVNpemUoKTtcbiAgICBpZiAoIXNpemUpIHtcbiAgICAgIHRoaXMubWFza0Vycm9yKCdObyBpbWFnZSBzaXplIGlzIGF2YWlsYWJsZSwgc28gdGhlIG1hc2sgY2Fubm90IGJlIHNpemVkLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm1hc2tCdXN5ID0gdHJ1ZTtcbiAgICB0aGlzLm1hc2tFbmNvZGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFza1Byb2dyZXNzID0gMDtcbiAgICB0aGlzLm1hc2tKb2IgPSB0aGlzLm1hc2tFeHBvcnRcbiAgICAgIC5leHBvcnQoe1xuICAgICAgICByZWdpb25zOiB0aGlzLnJlZ2lvbnMsXG4gICAgICAgIGltYWdlU2l6ZTogc2l6ZSxcbiAgICAgICAgbW9kZTogdGhpcy5tYXNrTW9kZSxcbiAgICAgICAgc291cmNlTmFtZTogdGhpcy5wZXJzaXN0ZW5jZS5zZWxlY3RlZEZpbGVOYW1lKCksXG4gICAgICB9KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChlKSA9PiB7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3BsYW5uZWQnOlxuICAgICAgICAgICAgICBpZiAoZS5zY2FsZSA8IDEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgICAgICAgICAgICBrZXk6IFZJWl9UT0FTVF9LRVksXG4gICAgICAgICAgICAgICAgICBzZXZlcml0eTogJ2luZm8nLFxuICAgICAgICAgICAgICAgICAgc3VtbWFyeTogJ01hc2sgZG93bnNjYWxlZCcsXG4gICAgICAgICAgICAgICAgICBkZXRhaWw6IGBJbWFnZSB0b28gbGFyZ2UgZm9yIGEgZnVsbC1yZXNvbHV0aW9uIG1hc2s7IHNhdmluZyBhdCAke2Uud2lkdGh9w5cke2UuaGVpZ2h0fS5gLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncHJvZ3Jlc3MnOlxuICAgICAgICAgICAgICB0aGlzLm1hc2tQcm9ncmVzcyA9IGUucGVyY2VudDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdlbmNvZGluZyc6XG4gICAgICAgICAgICAgIHRoaXMubWFza0VuY29kaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkb25lJzpcbiAgICAgICAgICAgICAgdGhpcy5maW5pc2hNYXNrKGUuYmxvYiwgZmlsZW5hbWUpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgICAgIHRoaXMubWFza0Vycm9yKGVyci5tZXNzYWdlKTtcbiAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqIENhbmNlbCBhbiBpbi1wcm9ncmVzcyBtYXNrIGV4cG9ydCAodGVybWluYXRlcyBpdHMgd29ya2VyKSBhbmQgcmVzZXQgc3RhdGUuICovXG4gIHByb3RlY3RlZCBjYW5jZWxTYXZlTWFzaygpIHtcbiAgICB0aGlzLm1hc2tKb2I/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5tYXNrSm9iID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWFza0J1c3kgPSBmYWxzZTtcbiAgICB0aGlzLm1hc2tFbmNvZGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFza1Byb2dyZXNzID0gMDtcbiAgfVxuXG4gIHByaXZhdGUgZmluaXNoTWFzayhibG9iOiBCbG9iLCBmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5tYXNrSm9iID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWFza0J1c3kgPSBmYWxzZTtcbiAgICB0aGlzLm1hc2tFbmNvZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuc2hvd1NhdmVNYXNrRGlhbG9nID0gZmFsc2U7XG4gICAgc2F2ZUFzKGJsb2IsIGZpbGVuYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFza0Vycm9yKGRldGFpbDogc3RyaW5nKSB7XG4gICAgdGhpcy5tYXNrSm9iID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWFza0J1c3kgPSBmYWxzZTtcbiAgICB0aGlzLm1hc2tFbmNvZGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgIGtleTogVklaX1RPQVNUX0tFWSxcbiAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgc3VtbWFyeTogJ0NvdWxkIG5vdCBjcmVhdGUgbWFzaycsXG4gICAgICBkZXRhaWwsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcGVyc2lzdFJlZ2lvbnMoKSB7XG4gICAgLy8gRm9sZGVyIHN0YWNrOiB3cml0ZSBlYWNoIHNsaWNlJ3MgcmVnaW9ucyBiYWNrIHRvIGl0cyBvd24gc2xpY2UtZmlsZSdzXG4gICAgLy8gc2libGluZyBnZW9qc29uIOKAlCBubyBzaW5nbGUtZmlsZW5hbWUgcHJvbXB0IChqaXQtdWkjOTMpLlxuICAgIGlmICh0aGlzLnBlcnNpc3RlbmNlLnNhdmVzUGVyU2xpY2UoKSkge1xuICAgICAgdGhpcy5zYXZlU3RhY2tTbGljZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZmlsZW5hbWUgPSB0aGlzLnBlcnNpc3RlbmNlLmRlZmF1bHRTYXZlTmFtZSgpO1xuICAgIGlmICghZmlsZW5hbWUgfHwgKCF0aGlzLnJlZ2lvbnNGb3JTYXZlKCkubGVuZ3RoICYmICF0aGlzLmhhc1JlZ2lvblNvdXJjZSkpIHJldHVybjtcblxuICAgIHRoaXMuc2F2ZUFzRmlsZW5hbWUgPSBmaWxlbmFtZTtcbiAgICB0aGlzLnNhdmVBc0ZpbGVFeGlzdHMgPSBmYWxzZTtcbiAgICB0aGlzLnNob3dTYXZlQXNEaWFsb2cgPSB0cnVlO1xuICAgIHRoaXMuc2F2ZUFzQ2hlY2skLm5leHQodGhpcy5zYXZlQXNGaWxlbmFtZSk7XG4gIH1cblxuICAvKiogU2F2ZSBhIGZvbGRlciBzdGFjaydzIHJlZ2lvbnMgYXMgb25lIGdlb2pzb24gcGVyIHNsaWNlLWZpbGUgKGppdC11aSM5MykuXG4gICAqICBObyBkaWFsb2cgY292ZXJzIHRoZSB0b29sYmFyIG1lYW53aGlsZSwgc28gYSBTYXZlIHdoaWxlIG9uZSBpcyB1cGxvYWRpbmdcbiAgICogIGlzIGlnbm9yZWQgcmF0aGVyIHRoYW4gc3RhcnRpbmcgYSBzZWNvbmQgd3JpdGUgKGFuZCBvcnBoYW5pbmcgdGhlIGZpcnN0KS4gKi9cbiAgcHJpdmF0ZSBhc3luYyBzYXZlU3RhY2tTbGljZXMoKSB7XG4gICAgaWYgKHRoaXMuc2F2ZUFzQnVzeSkgcmV0dXJuO1xuICAgIHRoaXMuc2F2ZUFzQnVzeSA9IHRydWU7XG4gICAgbGV0IHNsaWNlczogU2xpY2VHZW9Kc29uW107XG4gICAgdHJ5IHtcbiAgICAgIHNsaWNlcyA9IGF3YWl0IHRoaXMucGVyc2lzdGVuY2Uuc2xpY2VHZW9Kc29ucygpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5zYXZlQXNCdXN5ID0gZmFsc2U7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIHRoaXMudG9hc3QoJ2Vycm9yJywgJ0Vycm9yIHNhdmluZyByZWdpb25zJywgYCR7KGVyciBhcyBFcnJvcik/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBDYW5jZWxsZWQgd2hpbGUgdGhlIHNsaWNlcyBzZXJpYWxpemVkLCBvciBub3RoaW5nIHRvIHdyaXRlLlxuICAgIGlmICghdGhpcy5zYXZlQXNCdXN5IHx8ICFzbGljZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLnNhdmVBc0J1c3kgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fc2F2ZUFzU3ViID0gdGhpcy5wZXJzaXN0ZW5jZS5zYXZlU2xpY2VzKHNsaWNlcykuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgdGhpcy5zYXZlQXNCdXN5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgICB0aGlzLnRvYXN0KFxuICAgICAgICAgICdzdWNjZXNzJyxcbiAgICAgICAgICAnUmVnaW9ucyBzYXZlZCcsXG4gICAgICAgICAgYFNhdmVkIFJPSXMgZm9yICR7c2xpY2VzLmxlbmd0aH0gc2xpY2Uke3NsaWNlcy5sZW5ndGggPT09IDEgPyAnJyA6ICdzJ31gLFxuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgIHRoaXMuc2F2ZUFzQnVzeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgdGhpcy50b2FzdCgnZXJyb3InLCAnRXJyb3Igc2F2aW5nIHJlZ2lvbnMnLCBgJHsoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSA/PyBlcnJ9YCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNoZWNrU2F2ZUFzRmlsZUV4aXN0cygpIHtcbiAgICB0aGlzLnNhdmVBc0NoZWNrJC5uZXh0KHRoaXMuc2F2ZUFzRmlsZW5hbWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbmZpcm1TYXZlQXMoKSB7XG4gICAgaWYgKCF0aGlzLnBlcnNpc3RlbmNlLnNlbGVjdGVkRmlsZU5hbWUoKSkgcmV0dXJuO1xuXG4gICAgY29uc3QgZmlsZW5hbWUgPSB0aGlzLnNhdmVBc0ZpbGVuYW1lLnRyaW0oKTtcbiAgICBpZiAoIWZpbGVuYW1lKSByZXR1cm47XG5cbiAgICAvLyBLZWVwIHRoZSBkaWFsb2cgb3BlbiBzaG93aW5nIGFuIChpbmRldGVybWluYXRlKSBwcm9ncmVzcyBiYXIgd2hpbGUgdGhlXG4gICAgLy8gcmVnaW9ucyBzZXJpYWxpemUgYW5kIHVwbG9hZCwgdGhlbiBjbG9zZSBvbiBzdWNjZXNzLlxuICAgIGNvbnN0IGRvU2F2ZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuc2F2ZUFzQnVzeSA9IHRydWU7XG4gICAgICAvLyBBbHNvIHJ1biBmcm9tIHRoZSBvdmVyd3JpdGUgY29uZmlybWF0aW9uLCB3aGljaCB0aGUgaG9zdCdzIGRpYWxvZyBtYXkgYW5zd2VyLlxuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB0aGlzLl9zYXZlQXNTdWIgPSB0aGlzLnBlcnNpc3RlbmNlXG4gICAgICAgIC5zYXZlKCgpID0+IHRoaXMucmVnaW9uc0ZvclNhdmUoKSwgZmlsZW5hbWUpXG4gICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2F2ZUFzQnVzeSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5zaG93U2F2ZUFzRGlhbG9nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgICAgIHRoaXMudG9hc3QoJ3N1Y2Nlc3MnLCAnUmVnaW9ucyBzYXZlZCcsIGBTYXZlZCBhcyAke2ZpbGVuYW1lfWApO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2F2ZUFzQnVzeSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgICAgICB0aGlzLnRvYXN0KCdlcnJvcicsICdFcnJvciBzYXZpbmcgcmVnaW9ucycsIGAkeyhlcnIgYXMgRXJyb3IpPy5tZXNzYWdlIHx8IGVycn1gKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuc2F2ZUFzRmlsZUV4aXN0cykge1xuICAgICAgdGhpcy5jb25maXJtYXRpb25TZXJ2aWNlLmNvbmZpcm0oe1xuICAgICAgICBtZXNzYWdlOiBgXCIke2ZpbGVuYW1lfVwiIGFscmVhZHkgZXhpc3RzLiBEbyB5b3Ugd2FudCB0byBvdmVyd3JpdGUgaXQ/YCxcbiAgICAgICAgaGVhZGVyOiAnQ29uZmlybSBPdmVyd3JpdGUnLFxuICAgICAgICBpY29uOiAncGkgcGktZXhjbGFtYXRpb24tdHJpYW5nbGUnLFxuICAgICAgICBhY2NlcHQ6IGRvU2F2ZSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb1NhdmUoKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2FuY2VsIGFuIGluLXByb2dyZXNzIEdlb0pTT04gcGVyc2lzdDogYWJvcnQgdGhlIGRlZmVycmVkIHNlcmlhbGl6ZSBhbmQvb3JcbiAgICogIHRoZSBpbi1mbGlnaHQgdXBsb2FkLCBhbmQgcmVzZXQgc3RhdGUuICovXG4gIHByb3RlY3RlZCBjYW5jZWxTYXZlQXMoKSB7XG4gICAgdGhpcy5fc2F2ZUFzU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX3NhdmVBc1N1YiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNhdmVBc0J1c3kgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgdG9hc3Qoc2V2ZXJpdHk6ICdzdWNjZXNzJyB8ICdlcnJvcicgfCAnaW5mbycsIHN1bW1hcnk6IHN0cmluZywgZGV0YWlsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IGtleTogVklaX1RPQVNUX0tFWSwgc2V2ZXJpdHksIHN1bW1hcnksIGRldGFpbCB9KTtcbiAgfVxufVxuIiwiPHAtdG9vbGJhciBzdHlsZUNsYXNzPVwicmVnaW9uLXRvb2xiYXJcIj5cbiAgPGRpdiBjbGFzcz1cInAtdG9vbGJhci1ncm91cC1zdGFydCBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC13cmFwIGdhcC0xXCI+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdGFnXCJcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCIhc2hvd1NoYXBlTGFiZWxcIlxuICAgICAgcFRvb2x0aXA9XCJTaG93IHJlZ2lvbiBsYWJlbHMuXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAob25DbGljayk9XCJzaG93U2hhcGVMYWJlbCA9ICFzaG93U2hhcGVMYWJlbDsgY2hhbmdlU2hvd1NoYXBlTGFiZWwoc2hvd1NoYXBlTGFiZWwpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS1zdG9wLWNpcmNsZVwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwiIXJlZ2lvbnNGaWxsZWRcIlxuICAgICAgcFRvb2x0aXA9XCJGaWxsIHJlZ2lvbnMgaW4gdGhlaXIgY29sb3VyIChhbiBhdGxhcydzIGxvb2spOyBsYWJlbHMgc2l0IGluc2lkZS5cIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIGFyaWFMYWJlbD1cIkZpbGwgcmVnaW9uc1wiXG4gICAgICAob25DbGljayk9XCJ0b2dnbGVGaWxsKClcIlxuICAgID5cbiAgICA8L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvblxuICAgICAgKm5nSWY9XCJ2b2x1bWVWaWV3XCJcbiAgICAgIGljb249XCJwaSBwaS1leWVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cIiFyZWdpb25zVGhyb3VnaFZvbHVtZVwiXG4gICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwicmVnaW9uc1Rocm91Z2hWb2x1bWVcIlxuICAgICAgcFRvb2x0aXA9XCJTZWUgdGhlIHJlZ2lvbnMgdGhyb3VnaCB0aGUgdm9sdW1lLiBPZmYsIHRoZSB2b2x1bWUgaGlkZXMgdGhlIHBhcnRzIG9mIHRoZW0gYmVoaW5kIHdoYXQgaXQgc2hvd3M7IG9uLCBub25lIChsYXllcnMgdHJhY2VkIGluc2lkZSBicmlnaHQgc3RydWN0dXJlcywgc3VjaCBhcyBhbiBPQ1QncykuXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICBhcmlhTGFiZWw9XCJSZWdpb25zIHRocm91Z2ggdm9sdW1lXCJcbiAgICAgIChvbkNsaWNrKT1cInRvZ2dsZVRocm91Z2hWb2x1bWUoKVwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICA8IS0tIE5ldyByZWdpb25zIGFyZSBub3cgY3JlYXRlZCBmcm9tIHRoZSBkaWFncmFtIHRvb2xiYXJcbiAgICAgICAgIChyZWN0YW5nbGUsIHBvbHlsaW5lLCBmcmVlZm9ybSwgd2FuZCkuIC0tPlxuICAgIDxwLWJ1dHRvblxuICAgICAgaWNvbj1cInBpIHBpLXVwbG9hZFwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIkltcG9ydCByZWdpb25zOiBhIEdlb0pTT04gZmlsZSwgb3IgYSBsYWJlbCB2b2x1bWUgKC5uaWksIC5uaWkuZ3osIC5ucnJkKSBjaG9zZW4gd2l0aCBpdHMgb250b2xvZ3kgSlNPTiBmb3IgdGhlIGNsYXNzIHRyZWUuXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAoY2xpY2spPVwicm9pRmlsZUlucHV0LmNsaWNrKClcIlxuICAgID5cbiAgICA8L3AtYnV0dG9uPlxuICAgIDxpbnB1dFxuICAgICAgI3JvaUZpbGVJbnB1dFxuICAgICAgdHlwZT1cImZpbGVcIlxuICAgICAgYWNjZXB0PVwiLmdlb2pzb24sLmpzb24sLm5paSwuZ3osLm5ycmRcIlxuICAgICAgbXVsdGlwbGVcbiAgICAgIGhpZGRlblxuICAgICAgKGNoYW5nZSk9XCJpbXBvcnRSb2lzKCRldmVudCk7IHJvaUZpbGVJbnB1dC52YWx1ZSA9ICcnXCJcbiAgICAvPlxuICAgIDxwLWJ1dHRvblxuICAgICAgaWNvbj1cInBpIHBpLWZvbGRlci1vcGVuXCJcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIHN0eWxlQ2xhc3M9XCJtci0yXCJcbiAgICAgIHBUb29sdGlwPVwiSW1wb3J0IGEgZm9sZGVyIG9mIHBlci1zbGljZSBHZW9KU09OIGZpbGVzIChvbmUgcGVyIHNsaWNlLCBpbiBuYW1lIG9yZGVyLCB3aXRoIGl0cyByZWdpb25zZXQuanNvbiBjbGFzcyB0cmVlKS5cIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIGFyaWFMYWJlbD1cIkltcG9ydCBhIGZvbGRlciBvZiByZWdpb25zXCJcbiAgICAgIChjbGljayk9XCJyb2lGb2xkZXJJbnB1dC5jbGljaygpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8aW5wdXRcbiAgICAgICNyb2lGb2xkZXJJbnB1dFxuICAgICAgdHlwZT1cImZpbGVcIlxuICAgICAgd2Via2l0ZGlyZWN0b3J5XG4gICAgICBtdWx0aXBsZVxuICAgICAgaGlkZGVuXG4gICAgICAoY2hhbmdlKT1cImltcG9ydFJvaXMoJGV2ZW50KTsgcm9pRm9sZGVySW5wdXQudmFsdWUgPSAnJ1wiXG4gICAgLz5cbiAgICA8cC1idXR0b25cbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIHN0eWxlQ2xhc3M9XCJtci0yXCJcbiAgICAgIHBUb29sdGlwPVwiRG93bmxvYWQgcmVnaW9ucyBhcyBnZW9qc29uIGZpbGUuXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICBpY29uPVwicGkgcGktZG93bmxvYWRcIlxuICAgICAgKGNsaWNrKT1cImV4cG9ydFJvaXMoKVwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktc2F2ZVwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIlNhdmUgcmVnaW9ucyB0byBzZXJ2ZXIuXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAoY2xpY2spPVwicGVyc2lzdFJlZ2lvbnMoKVwiXG4gICAgICBbZGlzYWJsZWRdPVwiKCFyZWdpb25zIHx8ICFyZWdpb25zLmxlbmd0aCkgJiYgIWhhc1JlZ2lvblNvdXJjZVwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICAqbmdJZj1cImNhbkltcG9ydEZyb21TZXJ2ZXJcIlxuICAgICAgaWNvbj1cInBpIHBpLWNsb3VkLWRvd25sb2FkXCJcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIHN0eWxlQ2xhc3M9XCJtci0yXCJcbiAgICAgIHBUb29sdGlwPVwiSW1wb3J0IHJlZ2lvbnMgZnJvbSBzZXJ2ZXI6IGEgR2VvSlNPTiBmaWxlLCBhIGZvbGRlciBvZiBwZXItc2xpY2UgR2VvSlNPTiBmaWxlcyBvciBhIGxhYmVsIHZvbHVtZSAoLm5paSwgLm5paS5neiwgLm5ycmQpLlwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgYXJpYUxhYmVsPVwiSW1wb3J0IHJlZ2lvbnMgZnJvbSBzZXJ2ZXJcIlxuICAgICAgW2xvYWRpbmddPVwiaW1wb3J0aW5nXCJcbiAgICAgIChjbGljayk9XCJpbXBvcnRGcm9tU2VydmVyKClcIlxuICAgID5cbiAgICA8L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvblxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgcFRvb2x0aXA9XCJEb3dubG9hZCBtYXNrIG9mIHRoZSByZWdpb25zIGFzIFBOR1wiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cIm9wZW5TYXZlTWFza0RpYWxvZygpXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhcmVnaW9ucyB8fCAhcmVnaW9ucy5sZW5ndGhcIlxuICAgID5cbiAgICAgIDwhLS0gUmVmZXJlbmNlcyB0aGUgZmlsZSBzbyBJbmtzY2FwZSBlZGl0cyB0byBtYXNrLnN2ZyBzaG93IHVwIGRpcmVjdGx5XG4gICAgICAgICAgICh0aGUgbGliJ3MgYXNzZXRzLyoqIGFyZSBzZXJ2ZWQgYXQgYXNzZXRzL3Bsb3R0aW5nLykuIFRoZVxuICAgICAgICAgICB0b29sYmFyLWljb24tZGFyayBmaWx0ZXIgcmVjb2xvdXJzIHRoZSBibGFjayBTVkcgdG8gdGhlIHRoZW1lIGJsdWUsXG4gICAgICAgICAgIHNhbWUgYXMgcmVnaW9uLWVkaXRvci5zdmcgYW5kIHRoZSBvdGhlciBTVkcgdG9vbGJhciBpY29ucy4gLS0+XG4gICAgICA8aW1nXG4gICAgICAgIHNyYz1cImFzc2V0cy9wbG90dGluZy9tYXNrLnN2Z1wiXG4gICAgICAgIGNsYXNzPVwidG9vbGJhci1pY29uLWRhcmtcIlxuICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtOyBoZWlnaHQ6IDFyZW07IHZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIlxuICAgICAgICBhbHQ9XCJEb3dubG9hZCBtYXNrXCJcbiAgICAgIC8+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGxhYmVsPVwieDUxMlwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIlJvdW5kIGFsbCByZWN0YW5nbGUgcmVnaW9uc1xuICAgICAgICAgICAgICAgICAgICB0byB3aWR0aCBhbmQgaGVpZ2h0IHRoYXQgYXJlIG11bHRpcGxlIG9mIDUxMlwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cInJvdW5kUmVjdGFuZ2xlTGVuZ3RocygpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS1jaGVjay1zcXVhcmVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgcFRvb2x0aXA9XCJTZWxlY3QgYWxsIHJlZ2lvbnNcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChjbGljayk9XCJzZWxlY3RBbGxSZWdpb25zKClcIlxuICAgICAgW2Rpc2FibGVkXT1cIiFyZWdpb25zIHx8ICFyZWdpb25zLmxlbmd0aFwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdGFnc1wiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIkVkaXQgY2xhc3Mgb24gc2VsZWN0ZWQgcm93c1wiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKGNsaWNrKT1cIiFzZWxlY3RlZFJlZ2lvbnMgfHwgIXNlbGVjdGVkUmVnaW9ucy5sZW5ndGggPyBvcC5oaWRlKCkgOiBvcC50b2dnbGUoJGV2ZW50KVwiXG4gICAgICBbZGlzYWJsZWRdPVwiIXNlbGVjdGVkUmVnaW9ucyB8fCAhc2VsZWN0ZWRSZWdpb25zLmxlbmd0aFwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktcGFsZXR0ZVwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwibXItMlwiXG4gICAgICBwVG9vbHRpcD1cIkVkaXQgY29sb3VyIG9mIHNlbGVjdGVkIHJlZ2lvbnNcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChjbGljayk9XCJvcGVuQ29sb3JEaWFsb2coKVwiXG4gICAgICBbZGlzYWJsZWRdPVwiIXNlbGVjdGVkUmVnaW9ucyB8fCAhc2VsZWN0ZWRSZWdpb25zLmxlbmd0aFwiXG4gICAgPlxuICAgIDwvcC1idXR0b24+XG4gICAgPHAtb3ZlcmxheVBhbmVsICNvcCAob25IaWRlKT1cImJ1bGtDbGFzcyA9ICcnOyBuZXdCdWxrQ2xhc3MgPSAnJ1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2x1bW4gZ2FwLTJcIiBzdHlsZT1cIndpZHRoOiAxOHJlbVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtbWVkaXVtIHRleHQtOTAwXCJcbiAgICAgICAgICA+U2V0IGNsYXNzIG9uIHt7IHNlbGVjdGVkUmVnaW9ucz8ubGVuZ3RoIHx8IDAgfX0gc2VsZWN0ZWQgcmVnaW9uKHMpPC9zcGFuXG4gICAgICAgID5cbiAgICAgICAgPCEtLSBTZWxlY3RpbmcgYSBjbGFzcyBhcHBsaWVzIGl0IGltbWVkaWF0ZWx5IChjaG9vc2luZyBhbiBvcHRpb24gY2xvc2VzIHRoZVxuICAgICAgICAgICAgIG92ZXJsYXksIHNvIHRoZXJlJ3Mgbm8gc2VwYXJhdGUgQXBwbHkgYnV0dG9uKS4gLS0+XG4gICAgICAgIDxwLWRyb3Bkb3duXG4gICAgICAgICAgc3R5bGVDbGFzcz1cInctZnVsbFwiXG4gICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICBbb3B0aW9uc109XCJwcmVzZXRTZXQuY2xhc3Nlc1wiXG4gICAgICAgICAgb3B0aW9uTGFiZWw9XCJuYW1lXCJcbiAgICAgICAgICBvcHRpb25WYWx1ZT1cIm5hbWVcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwiYnVsa0NsYXNzXCJcbiAgICAgICAgICBwbGFjZWhvbGRlcj1cIkNob29zZSBhIGNsYXNz4oCmXCJcbiAgICAgICAgICBbZmlsdGVyXT1cInByZXNldFNldC5jbGFzc2VzLmxlbmd0aCA+IDhcIlxuICAgICAgICAgIGZpbHRlckJ5PVwibmFtZVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cImFwcGx5QnVsa0NsYXNzKClcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIGxldC1jIHBUZW1wbGF0ZT1cIml0ZW1cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGQtdmFsdWVcIlxuICAgICAgICAgICAgICA+PHNwYW4gY2xhc3M9XCJjaGlwLXN3YXRjaFwiIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImMuY29sb3JcIj48L3NwYW4+e3sgYy5uYW1lIH19PC9zcGFuXG4gICAgICAgICAgICA+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9wLWRyb3Bkb3duPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicC1pbnB1dGdyb3VwXCI+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIuKApm9yIGEgbmV3IGNsYXNzXCJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwibmV3QnVsa0NsYXNzXCJcbiAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cImFkZEFuZEFwcGx5QnVsa0NsYXNzKClcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBpY29uPVwicGkgcGktcGx1c1wiXG4gICAgICAgICAgICBwVG9vbHRpcD1cIkFkZCBjbGFzcyAmYW1wOyBzZXQgaXRcIlxuICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhbmV3QnVsa0NsYXNzLnRyaW0oKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiYWRkQW5kQXBwbHlCdWxrQ2xhc3MoKVwiXG4gICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvcC1vdmVybGF5UGFuZWw+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdHJhc2hcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgKGNsaWNrKT1cImRlbGV0ZVNlbGVjdGVkUmVnaW9ucygpXCJcbiAgICAgIHBUb29sdGlwPVwiRGVsZXRlIHNlbGVjdGVkIHJlZ2lvbnNcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhc2VsZWN0ZWRSZWdpb25zIHx8ICFzZWxlY3RlZFJlZ2lvbnMubGVuZ3RoXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGljb249XCJwaSBwaS10aW1lcy1jaXJjbGVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc3R5bGVDbGFzcz1cIm1yLTJcIlxuICAgICAgKGNsaWNrKT1cImNsZWFyQWxsUmVnaW9ucygpXCJcbiAgICAgIHBUb29sdGlwPVwiRGVsZXRlIGFsbCByZWdpb25zXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICBbZGlzYWJsZWRdPVwiKCFyZWdpb25zIHx8ICFyZWdpb25zLmxlbmd0aCkgJiYgIWhhc1JlZ2lvblNvdXJjZVwiXG4gICAgPjwvcC1idXR0b24+XG4gICAgPHAtYnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktcXVlc3Rpb25cIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgKGNsaWNrKT1cInNob3dIZWxwKClcIlxuICAgICAgcFRvb2x0aXA9XCJIZWxwXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgPjwvcC1idXR0b24+XG4gIDwvZGl2PlxuPC9wLXRvb2xiYXI+XG5cbjxyZWdpb24tY2xhc3Nlcy1wYW5lbFxuICBbY2xhc3Nlc109XCJkaXNwbGF5Q2xhc3Nlc1wiXG4gIFtjb3VudHNdPVwiY2xhc3NDb3VudHNcIlxuICBbbWF0Y2hNb2RlXT1cInByZXNldFNldC5tYXRjaE1vZGVcIlxuICBbYWN0aXZlQ2xhc3NdPVwiYWN0aXZlQ2xhc3NcIlxuICBbcGlja2VkXT1cInBpY2tlZENsYXNzXCJcbiAgW21hcmtlZF09XCJtYXJrZWRDbGFzc2VzXCJcbiAgW3NlbGVjdGVkQ291bnRdPVwic2VsZWN0ZWRSZWdpb25zPy5sZW5ndGggfHwgMFwiXG4gIFtkZWZhdWx0Q2xhc3NOYW1lXT1cImRlZmF1bHRDbGFzc05hbWVcIlxuICAocGljayk9XCJzZWxlY3RBY3RpdmVDbGFzcygkZXZlbnQpXCJcbiAgKHJlY29sb3IpPVwic2V0Q2xhc3NDb2xvcigkZXZlbnQubmFtZSwgJGV2ZW50LmNvbG9yKVwiXG4gIChyZW1vdmUpPVwiZGVsZXRlQ2xhc3MoJGV2ZW50KVwiXG4gIChtYW5hZ2UpPVwib3Blbk1hbmFnZURpYWxvZygpXCJcbiAgW3ZvbHVtZV09XCJ2b2x1bWVWaWV3XCJcbiAgW3Nob3duM2RdPVwic2hvd24zZE5hbWVzXCJcbiAgKHRvZ2dsZTNkKT1cInRvZ2dsZUNsYXNzM2QoJGV2ZW50KVwiXG4gIFtoaWRkZW5dPVwiaGlkZGVuQ2xhc3Nlc1wiXG4gICh0b2dnbGVIaWRkZW4pPVwic2V0Q2xhc3Nlc0hpZGRlbihbJGV2ZW50XSwgIWhpZGRlbkNsYXNzZXMuaGFzKCRldmVudCkpXCJcbiAgW3RyZWVWaWV3XT1cImNsYXNzSGllcmFyY2h5ID8gY2xhc3NUcmVlVmlldyA6IG51bGxcIlxuICAodHJlZVZpZXdDaGFuZ2UpPVwiY2xhc3NUcmVlVmlldyA9ICRldmVudFwiXG4+XG4gIDwhLS0gQSByZWdpb24gc2V0IHdpdGggYSBjbGFzcyBoaWVyYXJjaHkgKGFuIGF0bGFzIG9udG9sb2d5KSBjYW4gc2hvdyBpdHMgY2xhc3NlcyBhcyBhIHRyZWUuIC0tPlxuICA8cmVnaW9uLWNsYXNzLXRyZWVcbiAgICAqbmdJZj1cImNsYXNzSGllcmFyY2h5IGFzIGhpZXJhcmNoeVwiXG4gICAgW25vZGVzXT1cImhpZXJhcmNoeVwiXG4gICAgW2NvdW50c109XCJ0cmVlQ291bnRzXCJcbiAgICBbY29sb3JPZl09XCJ0cmVlQ29sb3JcIlxuICAgIFtwaWNrZWRdPVwicGlja2VkQ2xhc3NcIlxuICAgIFttYXJrZWRdPVwibWFya2VkQ2xhc3Nlc1wiXG4gICAgW3ZvbHVtZV09XCJ2b2x1bWVWaWV3XCJcbiAgICBbc2hvd24zZF09XCJzaG93bjNkTmFtZXNcIlxuICAgIChwaWNrKT1cInBpY2tDbGFzc2VzKCRldmVudClcIlxuICAgIChyZWNvbG9yKT1cInNldENsYXNzQ29sb3IoJGV2ZW50Lm5hbWUsICRldmVudC5jb2xvcilcIlxuICAgICh0b2dnbGUzZCk9XCJ0b2dnbGVDbGFzczNkKCRldmVudC5uYW1lLCAkZXZlbnQuY2xhc3NlcylcIlxuICAgIFtoaWRkZW5dPVwiaGlkZGVuQ2xhc3Nlc1wiXG4gICAgKHRvZ2dsZUhpZGRlbik9XCJzZXRDbGFzc2VzSGlkZGVuKCRldmVudC5jbGFzc2VzLCAkZXZlbnQuaGlkZGVuKVwiXG4gID5cbiAgPC9yZWdpb24tY2xhc3MtdHJlZT5cbjwvcmVnaW9uLWNsYXNzZXMtcGFuZWw+XG5cbjxyZWdpb24tdGFibGVcbiAgW3BhZ2VdPVwicGFnZWRSZWdpb25zXCJcbiAgW3RvdGFsXT1cInRhYmxlVG90YWxcIlxuICBbZmlyc3RdPVwicGFnaW5hdG9yRmlyc3RcIlxuICBbcm93c109XCJwYWdpbmF0b3JSb3dzXCJcbiAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJyb3dzUGVyUGFnZU9wdGlvbnNcIlxuICBbbWV0YUtleV09XCJtZXRhS2V5XCJcbiAgW3NlbGVjdGlvbl09XCJzZWxlY3RlZFJlZ2lvbnNcIlxuICAoc2VsZWN0aW9uQ2hhbmdlKT1cInNlbGVjdGVkUmVnaW9ucyA9ICRldmVudFwiXG4gIChyb3dTZWxlY3QpPVwib25TZWxlY3Rpb25DaGFuZ2VkKClcIlxuICBbcHJlc2V0U2V0XT1cInRhYmxlUHJlc2V0U2V0XCJcbiAgW2RlZmF1bHRDb2xvcl09XCJzaGFwZUNvbG9yXCJcbiAgW21wcF09XCJtcHBcIlxuICBbdm9sdW1lc109XCJ0YWJsZVZvbHVtZXNcIlxuICBbbGFiZWxEcmFmdHNdPVwiZWRpdGluZ0xhYmVsUmVnaW9uc1wiXG4gIChsYWJlbEVkaXRTdGFydCk9XCJzdGFydEVkaXRMYWJlbCgkZXZlbnQpXCJcbiAgKGxhYmVsRHJhZnRDaGFuZ2UpPVwic2V0TGFiZWxEcmFmdCgkZXZlbnQucmVnaW9uLCAkZXZlbnQudmFsdWUpXCJcbiAgKGxhYmVsRWRpdFN0b3ApPVwic3RvcEVkaXRMYWJlbCgkZXZlbnQucmVnaW9uLCAkZXZlbnQuY29tbWl0KVwiXG4gIChjbGFzc1BpY2spPVwiYXBwbHlQcmVzZXRUb1JlZ2lvbigkZXZlbnQucmVnaW9uLCAkZXZlbnQubmFtZSlcIlxuICAoZGVsZXRlUm93KT1cImRlbGV0ZVJlZ2lvbigkZXZlbnQpXCJcbiAgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxuPlxuPC9yZWdpb24tdGFibGU+XG5cbjwhLS0gTGl2ZS1lZGl0IG1vZGU6IG5vIFNhdmUvQ2FuY2VsIOKAlCBldmVyeSBlZGl0IGNvbW1pdHMgaW1tZWRpYXRlbHkgdG8gdGhlXG4gICAgIGFjdGl2ZSBpbWFnZSdzIHJlZ2lvbiBjYWNoZS4gLS0+XG5cbjxwLWNvbmZpcm1EaWFsb2dcbiAgI2NkXG4gIFtzdHlsZV09XCJ7IHdpZHRoOiAnMjRyZW0nLCBoZWlnaHQ6ICcxNHJlbScgfVwiXG4gIGtleT1cInBvc2l0aW9uRGlhbG9nXCJcbiAgW2Jhc2VaSW5kZXhdPVwiMTAwMDBcIlxuICByZWplY3RCdXR0b25TdHlsZUNsYXNzPVwicC1idXR0b24tb3V0bGluZWRcIlxuPlxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgcEJ1dHRvbiBpY29uPVwicGkgcGktY2hlY2tcIiBsYWJlbD1cIlllc1wiIChjbGljayk9XCJjZC5hY2NlcHQoKVwiPjwvYnV0dG9uPlxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1vdXRsaW5lZFwiXG4gICAgICBwQnV0dG9uXG4gICAgICBpY29uPVwicGkgcGktdGltZXNcIlxuICAgICAgbGFiZWw9XCJOb1wiXG4gICAgICAoY2xpY2spPVwiY2QucmVqZWN0KClcIlxuICAgID48L2J1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1jb25maXJtRGlhbG9nPlxuXG48cmVnaW9uLXNhdmUtcmVnaW9ucy1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJzaG93U2F2ZUFzRGlhbG9nXCJcbiAgW2ZpbGVuYW1lXT1cInNhdmVBc0ZpbGVuYW1lXCJcbiAgKGZpbGVuYW1lQ2hhbmdlKT1cInNhdmVBc0ZpbGVuYW1lID0gJGV2ZW50OyBjaGVja1NhdmVBc0ZpbGVFeGlzdHMoKVwiXG4gIFtmaWxlRXhpc3RzXT1cInNhdmVBc0ZpbGVFeGlzdHNcIlxuICBbYnVzeV09XCJzYXZlQXNCdXN5XCJcbiAgKGNvbmZpcm0pPVwiY29uZmlybVNhdmVBcygpXCJcbiAgKGNhbmNlbFNhdmUpPVwiY2FuY2VsU2F2ZUFzKClcIlxuPlxuPC9yZWdpb24tc2F2ZS1yZWdpb25zLWRpYWxvZz5cblxuPHJlZ2lvbi1zYXZlLXJlZ2lvbnMtZGlhbG9nXG4gIGhlYWRlcj1cIkV4cG9ydCBSZWdpb25zXCJcbiAgY29uZmlybUxhYmVsPVwiRXhwb3J0XCJcbiAgY29uZmlybUljb249XCJwaSBwaS1kb3dubG9hZFwiXG4gIGlucHV0SWQ9XCJleHBvcnQtZmlsZW5hbWVcIlxuICBbKHZpc2libGUpXT1cInNob3dFeHBvcnREaWFsb2dcIlxuICBbKGZpbGVuYW1lKV09XCJleHBvcnRGaWxlbmFtZVwiXG4gIChjb25maXJtKT1cImNvbmZpcm1FeHBvcnQoKVwiXG4+XG48L3JlZ2lvbi1zYXZlLXJlZ2lvbnMtZGlhbG9nPlxuXG48cmVnaW9uLXNhdmUtbWFzay1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJzaG93U2F2ZU1hc2tEaWFsb2dcIlxuICBbKGZpbGVuYW1lKV09XCJzYXZlTWFza0ZpbGVuYW1lXCJcbiAgWyhtb2RlKV09XCJtYXNrTW9kZVwiXG4gIFtidXN5XT1cIm1hc2tCdXN5XCJcbiAgW3Byb2dyZXNzXT1cIm1hc2tQcm9ncmVzc1wiXG4gIFtlbmNvZGluZ109XCJtYXNrRW5jb2RpbmdcIlxuICAoY29uZmlybSk9XCJjb25maXJtU2F2ZU1hc2soKVwiXG4gIChjYW5jZWxFeHBvcnQpPVwiY2FuY2VsU2F2ZU1hc2soKVwiXG4+XG48L3JlZ2lvbi1zYXZlLW1hc2stZGlhbG9nPlxuXG48cmVnaW9uLWNvbG9yLWRpYWxvZ1xuICBbKHZpc2libGUpXT1cInNob3dDb2xvckRpYWxvZ1wiXG4gIFtlZGl0c109XCJjbGFzc0NvbG9yRWRpdHNcIlxuICBbc2VsZWN0ZWRDb3VudF09XCJzZWxlY3RlZFJlZ2lvbnM/Lmxlbmd0aCB8fCAwXCJcbiAgKGFwcGx5KT1cImFwcGx5Q29sb3JUb1NlbGVjdGVkKCRldmVudClcIlxuPlxuPC9yZWdpb24tY29sb3ItZGlhbG9nPlxuXG48IS0tIE1hbmFnZSBhbm5vdGF0aW9uIGNsYXNzZXMgKGppdC11aSM3MCk6IGVkaXRzIGEgd29ya2luZyBjb3B5LCBjb21taXR0ZWQgb24gQXBwbHkuIC0tPlxuPHJlZ2lvbi1tYW5hZ2UtY2xhc3Nlcy1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJzaG93TWFuYWdlRGlhbG9nXCJcbiAgWyhkcmFmdCldPVwicHJlc2V0RHJhZnRcIlxuICAoYXBwbHkpPVwiYXBwbHlNYW5hZ2VEaWFsb2codHJ1ZSlcIlxuICAocmVzZXREZWZhdWx0cyk9XCJyZXNldFByZXNldHNUb0RlZmF1bHRzKClcIlxuICAoaW1wb3J0RmlsZSk9XCJpbXBvcnRQcmVzZXRzKCRldmVudClcIlxuICAoZXhwb3J0KT1cImV4cG9ydFByZXNldHMoKVwiXG4+XG48L3JlZ2lvbi1tYW5hZ2UtY2xhc3Nlcy1kaWFsb2c+XG5cbjxyZWdpb24tZWRpdG9yLWhlbHAgWyh2aXNpYmxlKV09XCJkaXNwbGF5SGVscERpYWxvZ1wiPjwvcmVnaW9uLWVkaXRvci1oZWxwPlxuIl19
|