@smarterplan/ngx-smarterplan-locations 0.2.21 → 0.2.22
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/esm2020/lib/components/carousel/carousel.component.mjs +27 -27
- package/esm2020/lib/components/chevron/chevron.component.mjs +17 -17
- package/esm2020/lib/components/detail-location/detail-location.component.mjs +154 -154
- package/esm2020/lib/components/form-location/form-location.component.mjs +237 -237
- package/esm2020/lib/components/images/images.component.mjs +90 -90
- package/esm2020/lib/components/locations/locations.component.mjs +141 -141
- package/esm2020/lib/components/locations/map/map-popup/map-popup.component.mjs +65 -65
- package/esm2020/lib/components/locations/map/map.component.mjs +90 -90
- package/esm2020/lib/components/plan-legend/plan-legend.component.mjs +47 -0
- package/esm2020/lib/components/plans/calibration/calibration.component.mjs +468 -468
- package/esm2020/lib/components/plans/edit-plan/edit-plan.component.mjs +324 -324
- package/esm2020/lib/components/plans/plans.component.mjs +210 -210
- package/esm2020/lib/components/tab-navigation/tab-navigation.component.mjs +41 -41
- package/esm2020/lib/components/visits/visits.component.mjs +235 -235
- package/esm2020/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +230 -230
- package/esm2020/lib/components/zones/add-zone/add-zone.component.mjs +294 -294
- package/esm2020/lib/components/zones/add-zone/selection/selection.component.mjs +76 -76
- package/esm2020/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +414 -413
- package/esm2020/lib/components/zones/zones.component.mjs +236 -232
- package/esm2020/lib/helper.service.mjs +134 -134
- package/esm2020/lib/ngx-smarterplan-location-routing.module.mjs +49 -49
- package/esm2020/lib/ngx-smarterplan-locations.module.mjs +125 -122
- package/esm2020/lib/ngx-smarterplan-locations.service.mjs +13 -13
- package/esm2020/lib/pipes/count-audio-sweeps.pipe.mjs +26 -26
- package/esm2020/lib/radio-button/radio-button.component.mjs +26 -26
- package/esm2020/public-api.mjs +8 -8
- package/esm2020/smarterplan-ngx-smarterplan-locations.mjs +4 -4
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs +3676 -3624
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs +3520 -3472
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
- package/lib/components/carousel/carousel.component.d.ts +12 -12
- package/lib/components/chevron/chevron.component.d.ts +9 -9
- package/lib/components/detail-location/detail-location.component.d.ts +51 -51
- package/lib/components/form-location/form-location.component.d.ts +45 -45
- package/lib/components/images/images.component.d.ts +28 -28
- package/lib/components/locations/locations.component.d.ts +50 -50
- package/lib/components/locations/map/map-popup/map-popup.component.d.ts +22 -22
- package/lib/components/locations/map/map.component.d.ts +22 -22
- package/lib/components/plan-legend/plan-legend.component.d.ts +14 -0
- package/lib/components/plans/calibration/calibration.component.d.ts +140 -140
- package/lib/components/plans/edit-plan/edit-plan.component.d.ts +55 -55
- package/lib/components/plans/plans.component.d.ts +59 -59
- package/lib/components/tab-navigation/tab-navigation.component.d.ts +13 -13
- package/lib/components/visits/visits.component.d.ts +51 -51
- package/lib/components/zones/add-audio-zone/add-audio-zone.component.d.ts +63 -63
- package/lib/components/zones/add-zone/add-zone.component.d.ts +67 -67
- package/lib/components/zones/add-zone/selection/selection.component.d.ts +44 -44
- package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +96 -96
- package/lib/components/zones/zones.component.d.ts +67 -67
- package/lib/helper.service.d.ts +53 -53
- package/lib/ngx-smarterplan-location-routing.module.d.ts +7 -7
- package/lib/ngx-smarterplan-locations.module.d.ts +36 -35
- package/lib/ngx-smarterplan-locations.service.d.ts +6 -6
- package/lib/pipes/count-audio-sweeps.pipe.d.ts +10 -10
- package/lib/radio-button/radio-button.component.d.ts +12 -12
- package/package.json +1 -1
- package/public-api.d.ts +4 -4
- package/smarterplan-ngx-smarterplan-locations.d.ts +5 -5
|
@@ -1,413 +1,414 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
-
import { getCoefficientsForImage, getMetaForImage, showScanPointsOnPlanInDiv } from '@smarterplan/ngx-smarterplan-core';
|
|
3
|
-
import panzoom from 'panzoom';
|
|
4
|
-
import { buttonIsInSelection, isInPolygon, rotate, setVisuallySelected, styleButton, SweepState } from '../../../../helper.service';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "@smarterplan/ngx-smarterplan-core";
|
|
7
|
-
import * as i2 from "../selection/selection.component";
|
|
8
|
-
import * as i3 from "
|
|
9
|
-
import * as i4 from "
|
|
10
|
-
import * as i5 from "@
|
|
11
|
-
import * as i6 from "@
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
draw
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
navY
|
|
142
|
-
|
|
143
|
-
this.navIDsZoneEdit.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
// let
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
// { x:
|
|
154
|
-
// element.
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
//
|
|
164
|
-
// navX
|
|
165
|
-
//
|
|
166
|
-
// navY
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
let
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
// let
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
// { x:
|
|
203
|
-
// element.
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
let
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
this.navIDsZoneEdit.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
// const
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
// element.
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
...
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
*
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
*
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
btnChanged.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
this.chosenScansOnPlan.
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
SweepPlanSelectionComponent.ɵ
|
|
393
|
-
i0.ɵɵ
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3dlZXAtcGxhbi1zZWxlY3Rpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvem9uZXMvYWRkLXpvbmUvc3dlZXAtcGxhbi1zZWxlY3Rpb24vc3dlZXAtcGxhbi1zZWxlY3Rpb24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvem9uZXMvYWRkLXpvbmUvc3dlZXAtcGxhbi1zZWxlY3Rpb24vc3dlZXAtcGxhbi1zZWxlY3Rpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsZUFBZSxFQUE2Qyx5QkFBeUIsRUFBNEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUM3TCxPQUFPLE9BQW9CLE1BQU0sU0FBUyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQWEsTUFBTSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7Ozs7QUFPL0ksTUFBTSxPQUFPLDJCQUEyQjtJQTRDcEMsWUFDWSxXQUF3QixFQUN4QixpQkFBb0MsRUFDcEMsV0FBd0I7UUFGeEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQXpDM0Isc0JBQWlCLEdBQWEsRUFBRSxDQUFDO1FBSzFDLG1CQUFjLEdBQWEsRUFBRSxDQUFDO1FBRTlCLHFDQUFxQztRQUM1QixtQkFBYyxHQUFhLEVBQUUsQ0FBQztRQUV2Qyx3Q0FBd0M7UUFDL0Isc0JBQWlCLEdBQWEsRUFBRSxDQUFDO1FBRTFDLG9DQUFvQztRQUMzQixxQkFBZ0IsR0FBWSxLQUFLLENBQUM7UUFZM0MsK0JBQStCO1FBQy9CLG1CQUFjLEdBQXdCLEVBQUUsQ0FBQztRQUV6QyxxREFBcUQ7UUFDckQsdUJBQWtCLEdBQXdCLEVBQUUsQ0FBQztRQUVuQyxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUErQyxDQUFDO1FBRTNGLHdCQUFtQixHQUFHLEtBQUssQ0FBQztJQVF4QixDQUFDO0lBRUwsUUFBUTtRQUNKLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7U0FDL0I7SUFDTCxDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqQixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDeEI7SUFDTCxDQUFDO0lBRUQsb0JBQW9CO1FBQ2hCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7SUFDbEQsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRO1FBQ1YsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsc0JBQXNCLENBQ3RELElBQUksQ0FBQyxPQUFPLENBQ2YsQ0FBQztJQUNOLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxDQUFDLElBQVU7UUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWE7UUFDZixJQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFnQixDQUFDO1FBQ2pFLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUN6QixDQUFDO1FBQ0YsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMscUJBQXFCLENBQ2xFLFVBQVUsQ0FDYixDQUFDO1FBQ0YsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0seUJBQXlCLENBQ2pELElBQUksQ0FBQyxVQUFVLEVBQ2YsSUFBSSxDQUFDLE9BQU8sRUFDWixXQUFXLENBQ2QsQ0FBQztRQUNGLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDdkUsV0FBVyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDN0M7aUJBQU07Z0JBQ0gsSUFDSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUM7b0JBQzNCLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQzt1QkFDMUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7b0JBQ2hELFdBQVcsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7d0JBQzlDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3FCQUMzQztpQkFDSjtxQkFBTSxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO29CQUN4RSxXQUFXLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztpQkFDN0M7cUJBQU07b0JBQ0gsV0FBVyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQzVDO2dCQUNELHVDQUF1QztnQkFDdkMsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxLQUFLLE9BQU8sQ0FBQyxFQUFFLEVBQUU7b0JBQzlELE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsQ0FBQztvQkFDbkMsV0FBVyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7aUJBQy9DO2dCQUNELE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUN4QyxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLE1BQXFCLENBQUMsQ0FDeEQsQ0FBQzthQUNMO1NBQ0o7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2pDLE1BQU0sRUFBRSxJQUFJO1lBQ1osYUFBYSxFQUFFLENBQUM7WUFDaEIsT0FBTyxFQUFFLEdBQUc7WUFDWixlQUFlLENBQUMsQ0FBYTtnQkFDekIsT0FBTyxDQUNILENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUNqQixDQUFDLENBQUMsdURBQXVEO1lBQzlELENBQUM7U0FDSixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELGFBQWEsQ0FBQyxXQUFrQjtRQUM1QixPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUNqQyxNQUFNLElBQUksR0FBRztnQkFDVCxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLO2dCQUM3QixNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNO2FBQ2xDLENBQUM7WUFDRixNQUFNLEdBQUcsR0FBRyxNQUFNLGVBQWUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVELE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsdUJBQXVCLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRTlELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDO1lBRXZDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE9BQVksRUFBRSxFQUFFO2dCQUM1QixRQUFRLE9BQU8sQ0FBQyxRQUFRLEVBQUU7b0JBQ3RCLEtBQUssTUFBTTt3QkFDUCxNQUFNLElBQUksQ0FBQyxhQUFhLENBQ3BCLEdBQUcsRUFDSCxNQUFNLEVBQ04sTUFBTSxFQUNOLE9BQU8sRUFDUCxXQUFXLENBQ2QsQ0FBQzt3QkFDRixNQUFNO29CQUVWLEtBQUssU0FBUzt3QkFDVixNQUFNLElBQUksQ0FBQyxlQUFlLENBQ3RCLEdBQUcsRUFDSCxNQUFNLEVBQ04sTUFBTSxFQUNOLE9BQU8sRUFDUCxXQUFXLENBQ2QsQ0FBQzt3QkFDRixNQUFNO29CQUVWLEtBQUssTUFBTTt3QkFDUCxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDdkIsR0FBRyxFQUNILE1BQU0sRUFDTixNQUFNLEVBQ04sT0FBTyxFQUNQLFdBQVcsQ0FDZCxDQUFDO3dCQUNGLE1BQU07b0JBQ1Y7d0JBQ0ksTUFBTTtpQkFDYjtZQUNMLENBQUMsQ0FBQyxDQUFDO1lBRUgsT0FBTyxFQUFFLENBQUM7UUFDZCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUFDLEdBQVEsRUFBRSxNQUFjLEVBQUUsTUFBYyxFQUN4RCxPQUF5RixFQUFFLFdBQWtCO1FBQzdHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUU7WUFDM0IsTUFBTSxlQUFlLEdBQUcsVUFBVSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUM1RCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUNwQixDQUFDO1lBQ0YsTUFBTSxjQUFjLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FDdkMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQy9DLENBQUM7WUFDRixJQUFJLGNBQWMsRUFBRTtnQkFDaEIsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7Z0JBQ3JDLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO2dCQUN2QyxNQUFNLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQztnQkFDbkUsTUFBTSxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUM7Z0JBQ2pFLElBQ0ksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDO29CQUNoQixJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsS0FBSztvQkFDaEMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDO29CQUNoQixJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTTtvQkFDakMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQzlDO29CQUNFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDM0M7YUFDSjtZQUVELG1CQUFtQjtZQUNuQixvREFBb0Q7WUFDcEQsc0VBQXNFO1lBQ3RFLHNFQUFzRTtZQUN0RSx1QkFBdUI7WUFDdkIsZ0NBQWdDO1lBQ2hDLGdDQUFnQztZQUNoQyw0Q0FBNEM7WUFDNUMseUJBQXlCO1lBQ3pCLFNBQVM7WUFDVCwwQkFBMEI7WUFDMUIsMEJBQTBCO1lBQzFCLElBQUk7WUFDSjs7ZUFFRztZQUNILE9BQU87WUFDUCwwQkFBMEI7WUFDMUIsMENBQTBDO1lBQzFDLDBCQUEwQjtZQUMxQiwyQ0FBMkM7WUFDM0MsbURBQW1EO1lBQ25ELE1BQU07WUFDTiwrQ0FBK0M7WUFDL0MsSUFBSTtRQUNSLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDLEtBQUs7SUFFUCxLQUFLLENBQUMsZUFBZSxDQUFDLEdBQVEsRUFBRSxNQUFjLEVBQUUsTUFBYyxFQUMxRCxPQUF3RSxFQUFFLFdBQXlCO1FBQ25HLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxXQUFXLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ3pCLE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDNUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FDcEIsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQ3ZDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUMvQyxDQUFDO1lBQ0YsSUFBSSxjQUFjLEVBQUU7Z0JBQ2hCLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO2dCQUNyQyxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztnQkFDdkMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUM7Z0JBQ2pFLElBQUksSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDO2dCQUMvRCxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7b0JBQ2YsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUNwQixFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUNwQixFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQ2hDLE9BQU8sQ0FBQyxLQUFLLENBQ2hCLENBQUM7b0JBQ0YsSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7b0JBQ25CLElBQUksR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO2lCQUN0QjtnQkFFRCxNQUFNLE1BQU0sR0FDUixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDN0QsTUFBTSxNQUFNLEdBQ1IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdELE1BQU0sTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUM7Z0JBQy9CLElBQUksTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRTtvQkFDN0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUMzQzthQUNKO1lBRUQsa0JBQWtCO1lBQ2xCLG9EQUFvRDtZQUNwRCxzRUFBc0U7WUFDdEUsc0VBQXNFO1lBQ3RFLHVCQUF1QjtZQUN2QixnQ0FBZ0M7WUFDaEMsZ0NBQWdDO1lBQ2hDLDRDQUE0QztZQUM1Qyx5QkFBeUI7WUFDekIsU0FBUztZQUNULDBCQUEwQjtZQUMxQiwwQkFBMEI7WUFDMUIsSUFBSTtZQUVKLGlCQUFpQjtZQUNqQixnRUFBZ0U7WUFDaEUsaUJBQWlCO1lBQ2pCLGdFQUFnRTtZQUNoRSxrQ0FBa0M7WUFDbEMscUVBQXFFO1lBQ3JFLCtDQUErQztZQUMvQyxJQUFJO1FBQ1IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsS0FBSztJQUVQLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFRLEVBQUUsTUFBYyxFQUFFLE1BQWMsRUFBRSxPQUEwQixFQUFFLFdBQWtCO1FBQzNHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxRCxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUVqQyxNQUFNLGVBQWUsR0FBRyxVQUFVLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQzVELElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQ3BCLENBQUM7WUFDRixNQUFNLGNBQWMsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUN2QyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FDL0MsQ0FBQztZQUNGLElBQUksY0FBYyxFQUFFO2dCQUNoQixNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztnQkFDckMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7Z0JBQ3ZDLElBQUksSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO2dCQUNqRSxJQUFJLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQztnQkFFL0QsTUFBTSxDQUFDLEdBQUc7b0JBQ04sQ0FBQyxFQUFFLElBQUk7b0JBQ1AsQ0FBQyxFQUFFLElBQUk7aUJBQ1YsQ0FBQztnQkFDRixJQUNJLFdBQVcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQztvQkFDL0IsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQzlDO29CQUNFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDM0M7YUFDSjtZQUVELGtCQUFrQjtZQUNsQixvREFBb0Q7WUFDcEQsY0FBYztZQUNkLGtFQUFrRTtZQUNsRSxrRUFBa0U7WUFDbEUsS0FBSztZQUNMLHVCQUF1QjtZQUN2Qix1QkFBdUI7WUFDdkIsYUFBYTtZQUNiLDRDQUE0QztZQUM1Qyx5QkFBeUI7WUFDekIsU0FBUztZQUNULElBQUk7WUFDSixPQUFPO1lBQ1AseUNBQXlDO1lBQ3pDLG1EQUFtRDtZQUNuRCxNQUFNO1lBQ04sK0NBQStDO1lBQy9DLElBQUk7UUFDUixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxZQUFZO1FBQ1IsSUFBSSxJQUFJLENBQUMsT0FBTztZQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBR0Q7Ozs7T0FJRztJQUNILGtCQUFrQixDQUFDLFNBQW9CO1FBQ25DLE1BQU0saUJBQWlCLEdBQXdCLEVBQUUsQ0FBQztRQUNsRCxNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztRQUU5QixzRkFBc0Y7UUFDdEYsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQ3RDLE1BQU0sVUFBVSxHQUFHLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMxRCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQzFDLHVGQUF1RjtnQkFDdkYsSUFBSSxDQUFDLFVBQVUsRUFBRTtvQkFDYixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQ2xDO2FBQ0o7aUJBQU0sSUFBSSxVQUFVLEVBQUU7Z0JBQ25CLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUNuQztTQUNKO1FBRUQsc0NBQXNDO1FBQ3RDLEtBQUssTUFBTSxNQUFNLElBQUksaUJBQWlCLEVBQUU7WUFDcEMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3RDO1FBRUQsb0NBQW9DO1FBQ3BDLEtBQUssTUFBTSxNQUFNLElBQUksa0JBQWtCLEVBQUU7WUFDckMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQ3JDO1FBRUQsOEJBQThCO1FBQzlCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDaEUsT0FBTyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztRQUNILCtCQUErQjtRQUMvQixJQUFJLENBQUMsa0JBQWtCLEdBQUc7WUFDdEIsR0FBRyxJQUFJLENBQUMsa0JBQWtCO1lBQzFCLEdBQUcsa0JBQWtCO1NBQ3hCLENBQUM7SUFDTixDQUFDO0lBSUQ7O09BRUc7SUFDSCxjQUFjO1FBQ1YsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUM3QyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDcEM7U0FDSjtRQUVELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7T0FFRztJQUNILGlCQUFpQjtRQUNiLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzFDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQzVDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUNwQztTQUNKO1FBQ0QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVztRQUNQLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ25ELEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztTQUNyQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSCxnQkFBZ0IsQ0FBQyxLQUFVO1FBQ3ZCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBRWxDLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN0QyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxTQUFTLE1BQU0sR0FBRyxDQUFDO1NBQy9DO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNILG1CQUFtQixDQUFDLE1BQW1CO1FBQ25DLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO1lBQzFCLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxNQUFNLENBQUMsRUFBRSxFQUFFO2dCQUNqQyxpQ0FBaUM7Z0JBQ2pDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLGlGQUFpRixDQUFDO2dCQUNqSCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDekIsT0FBTzthQUNWO1lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsOEZBQThGLENBQUM7WUFDOUgsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUM3QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUMxQztZQUNELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDbkIsOEJBQThCO2dCQUM5QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ25GLFVBQVUsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLGlGQUFpRixDQUFDO2FBQ3hIO1lBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzlCLE9BQU87U0FDVjtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUM3QyxtQkFBbUI7WUFDbkIsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsaUZBQWlGLENBQUM7WUFDakgsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDMUM7YUFBTTtZQUNILHdCQUF3QjtZQUN4QixJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDckYsa0RBQWtEO2dCQUNsRCxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxrRkFBa0YsQ0FBQzthQUNySDtpQkFBTTtnQkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyw2RkFBNkYsQ0FBQzthQUNoSTtZQUNELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQzNDO0lBQ0wsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQ3RHLENBQUM7SUFFRCxRQUFRO1FBQ0osSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQzs7d0hBL2VRLDJCQUEyQjs0R0FBM0IsMkJBQTJCLGdYQ1Z4Qyx1NUdBbUVBOzJGRHpEYSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0ksMEJBQTBCOzRKQVEzQixPQUFPO3NCQUFmLEtBQUs7Z0JBRUcsaUJBQWlCO3NCQUF6QixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBS0csY0FBYztzQkFBdEIsS0FBSztnQkFHRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBR0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBZ0JJLGNBQWM7c0JBQXZCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGdldENvZWZmaWNpZW50c0ZvckltYWdlLCBnZXRNZXRhRm9ySW1hZ2UsIE5hdmlnYXRpb24sIE5hdmlnYXRpb25TZXJ2aWNlLCBQbGFuLCBab25lLCBzaG93U2NhblBvaW50c09uUGxhbkluRGl2LCBab25lU2VydmljZSwgUGxhblNlcnZpY2UgfSBmcm9tICdAc21hcnRlcnBsYW4vbmd4LXNtYXJ0ZXJwbGFuLWNvcmUnO1xyXG5pbXBvcnQgcGFuem9vbSwgeyBQYW5ab29tIH0gZnJvbSAncGFuem9vbSc7XHJcbmltcG9ydCB7IGJ1dHRvbklzSW5TZWxlY3Rpb24sIGlzSW5Qb2x5Z29uLCBSZWN0YW5nbGUsIHJvdGF0ZSwgc2V0VmlzdWFsbHlTZWxlY3RlZCwgc3R5bGVCdXR0b24sIFN3ZWVwU3RhdGUgfSBmcm9tICcuLi8uLi8uLi8uLi9oZWxwZXIuc2VydmljZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnbGliLXN3ZWVwLXBsYW4tc2VsZWN0aW9uJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9zd2VlcC1wbGFuLXNlbGVjdGlvbi5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9zd2VlcC1wbGFuLXNlbGVjdGlvbi5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTd2VlcFBsYW5TZWxlY3Rpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG5cclxuICAgIHBsYW5zOiBQbGFuW107XHJcblxyXG4gICAgQElucHV0KCkgc3BhY2VJRDogc3RyaW5nO1xyXG5cclxuICAgIEBJbnB1dCgpIGNob3NlblNjYW5zT25QbGFuOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIC8qKiBpZiBjb21taW5nIGZyb20gRWRpdCBQbGFuIFNWRyBab25lIGNyZWF0aW9uICovXHJcbiAgICBASW5wdXQoKSBuZXdab25lRGF0YTogYW55O1xyXG5cclxuICAgIG5hdklEc1pvbmVFZGl0OiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIC8vIHN3ZWVwcyBiZWxvbmdpbmcgdG8gYW55IGF1ZGlvIHpvbmVcclxuICAgIEBJbnB1dCgpIG9jY3VwaWVkU3dlZXBzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIC8vIHN3ZWVwcyB1bmF2YWlsYWJsZSAoY2Fubm90IGJlIGNob3NlbilcclxuICAgIEBJbnB1dCgpIHVuYXZhaWxhYmxlU3dlZXBzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIC8vIGlmIGNob29zaW5nIHN3ZWVwcyBmb3IgYXVkaW8gem9uZVxyXG4gICAgQElucHV0KCkgZWRpdGluZ0F1ZGlvWm9uZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIEBJbnB1dCgpIGlucHV0Wm9uZTogWm9uZTtcclxuXHJcbiAgICBjaG9zZW5QbGFuOiBQbGFuO1xyXG5cclxuICAgIC8qKiBwYW5ab29tIGVsZW1lbnQgZm9yIGFkZGluZyBzY2FucyAqL1xyXG4gICAgcGFuWm9vbTogUGFuWm9vbTtcclxuXHJcbiAgICAvKiogZGl2UGxhbiAodXNlIEJ5IHBhblpvb20pICovXHJcbiAgICBkaXZQbGFuOiBIVE1MRWxlbWVudDtcclxuXHJcbiAgICAvKiogYWxsIHNjYW4gYnV0dG9ucyBFbGVtZW50ICovXHJcbiAgICBidXR0b25FbGVtZW50czogSFRNTEJ1dHRvbkVsZW1lbnRbXSA9IFtdO1xyXG5cclxuICAgIC8qKiBTY2FuIGJ1dHRvbnMgdGhhdCBhcmUgaW4gdGhlIGN1cnJlbnQgc2VsZWN0aW9uICovXHJcbiAgICBidXR0b25zSW5TZWxlY3Rpb246IEhUTUxCdXR0b25FbGVtZW50W10gPSBbXTtcclxuXHJcbiAgICBAT3V0cHV0KCkgc3dlZXBzU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgc3dlZXBzOiBzdHJpbmdbXTsgc3RhcnRTd2VlcElEOiBzdHJpbmc7IH0+KCk7XHJcblxyXG4gICAgaXNTZXR0aW5nU3RhcnRTd2VlcCA9IGZhbHNlO1xyXG5cclxuICAgIHN0YXJ0U3dlZXBJRDogc3RyaW5nO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgem9uZVNlcnZpY2U6IFpvbmVTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGlvblNlcnZpY2U6IE5hdmlnYXRpb25TZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgcGxhblNlcnZpY2U6IFBsYW5TZXJ2aWNlLFxyXG4gICAgKSB7IH1cclxuXHJcbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmdldFBsYW5zKCk7XHJcbiAgICAgICAgaWYgKHRoaXMuaW5wdXRab25lKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0U3dlZXBzT2ZJbnB1dFpvbmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkNoYW5nZXMoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2hvc2VuUGxhbikge1xyXG4gICAgICAgICAgICB0aGlzLnNldFN3ZWVwc09mSW5wdXRab25lKCk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4gPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5jbGVhckRpdlBsYW4oKTtcclxuICAgICAgICAgICAgdGhpcy5hZGRTY2FuUG9pbnRzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNldFN3ZWVwc09mSW5wdXRab25lKCkge1xyXG4gICAgICAgIHRoaXMubmF2SURzWm9uZUVkaXQgPSB0aGlzLmlucHV0Wm9uZS5zd2VlcElEcztcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRQbGFucygpIHtcclxuICAgICAgICB0aGlzLnBsYW5zID0gYXdhaXQgdGhpcy5wbGFuU2VydmljZS5nZXRTaW5nZWRQbGFuc0ZvclNwYWNlKFxyXG4gICAgICAgICAgICB0aGlzLnNwYWNlSUQsXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvblBsYW5DbGljayhwbGFuOiBQbGFuKSB7XHJcbiAgICAgICAgdGhpcy5jaG9zZW5QbGFuID0gcGxhbjtcclxuICAgICAgICB0aGlzLmNsZWFyRGl2UGxhbigpO1xyXG4gICAgICAgIHRoaXMuYWRkU2NhblBvaW50cygpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGFkZFNjYW5Qb2ludHMoKSB7XHJcbiAgICAgICAgdGhpcy5kaXZQbGFuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwbGFuRGl2XCIpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IHpvbmVPZlBsYW4gPSBhd2FpdCB0aGlzLnpvbmVTZXJ2aWNlLmdldFpvbmUoXHJcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuUGxhbi56b25lSUQsXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCBuYXZpZ2F0aW9ucyA9IGF3YWl0IHRoaXMubmF2aWdhdGlvblNlcnZpY2UuZ2V0TmF2aWdhdGlvbnNGb3Jab25lKFxyXG4gICAgICAgICAgICB6b25lT2ZQbGFuLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKHRoaXMubmV3Wm9uZURhdGEpIGF3YWl0IHRoaXMuc2V0U2NhbkJ5RHJhdyhuYXZpZ2F0aW9ucyk7XHJcbiAgICAgICAgdGhpcy5idXR0b25FbGVtZW50cyA9IGF3YWl0IHNob3dTY2FuUG9pbnRzT25QbGFuSW5EaXYoXHJcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuUGxhbixcclxuICAgICAgICAgICAgdGhpcy5kaXZQbGFuLFxyXG4gICAgICAgICAgICBuYXZpZ2F0aW9ucyxcclxuICAgICAgICApO1xyXG4gICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0aGlzLmJ1dHRvbkVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnVuYXZhaWxhYmxlU3dlZXBzICYmIHRoaXMudW5hdmFpbGFibGVTd2VlcHMuaW5jbHVkZXMoZWxlbWVudC5pZCkpIHtcclxuICAgICAgICAgICAgICAgIHN0eWxlQnV0dG9uKGVsZW1lbnQsIFN3ZWVwU3RhdGUuRElTQUJMRUQpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLm5hdklEc1pvbmVFZGl0Lmxlbmd0aCA+IDAgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXZJRHNab25lRWRpdC5pbmNsdWRlcyhlbGVtZW50LmlkKSlcclxuICAgICAgICAgICAgICAgICAgICB8fCB0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGVsZW1lbnQuaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3R5bGVCdXR0b24oZWxlbWVudCwgU3dlZXBTdGF0ZS5BRERFRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGVsZW1lbnQuaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4ucHVzaChlbGVtZW50LmlkKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMub2NjdXBpZWRTd2VlcHMgJiYgdGhpcy5vY2N1cGllZFN3ZWVwcy5pbmNsdWRlcyhlbGVtZW50LmlkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlQnV0dG9uKGVsZW1lbnQsIFN3ZWVwU3RhdGUuT0NDVVBJRUQpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzdHlsZUJ1dHRvbihlbGVtZW50LCBTd2VlcFN0YXRlLlJFTU9WRUQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy9zdGFydCBwb2ludCBzaG91bGQgYmUgbGFzdCBjb25kaXRpb24gXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pbnB1dFpvbmUgJiYgdGhpcy5pbnB1dFpvbmUuc3RhcnRTd2VlcElEID09PSBlbGVtZW50LmlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJzZXR0aW5nIHN0YXJ0IHBvaW50XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlQnV0dG9uKGVsZW1lbnQsIFN3ZWVwU3RhdGUuU1RBUlRQT0lOVCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZXZlbnQpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkJ1dHRvblNjYW5DbGlja2VkKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCksXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucGFuWm9vbSA9IHBhbnpvb20odGhpcy5kaXZQbGFuLCB7XHJcbiAgICAgICAgICAgIGJvdW5kczogdHJ1ZSxcclxuICAgICAgICAgICAgYm91bmRzUGFkZGluZzogMCxcclxuICAgICAgICAgICAgbWF4Wm9vbTogMy41LFxyXG4gICAgICAgICAgICBiZWZvcmVNb3VzZURvd24oZTogTW91c2VFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgICAgICBlLmJ1dHRvbiA9PT0gMlxyXG4gICAgICAgICAgICAgICAgKTsgLyoqIElnbm9yZSBldmVudCBmb3IgcmlnaHQgY2xpY2sgKHVzZSBmb3Igc2VsZWN0aW5nKSAqL1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBGdW5jdGlvbiBpZiB3ZSBhcmUgY29taW5nIGZvciBzdmcgZWRpdG9yIHdvcmtmbG93ICovXHJcbiAgICBzZXRTY2FuQnlEcmF3KG5hdmlnYXRpb25zOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCByZWN0ID0ge1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMubmV3Wm9uZURhdGEud2lkdGgsXHJcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMubmV3Wm9uZURhdGEuaGVpZ2h0LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCBpbWcgPSBhd2FpdCBnZXRNZXRhRm9ySW1hZ2UodGhpcy5jaG9zZW5QbGFuLmZpbGVwYXRoKTtcclxuICAgICAgICAgICAgY29uc3QgeyBjb2VmZlgsIGNvZWZmWSB9ID0gZ2V0Q29lZmZpY2llbnRzRm9ySW1hZ2UoaW1nLCByZWN0KTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGRyYXcgPSB0aGlzLm5ld1pvbmVEYXRhLmVsZW1lbnRzO1xyXG5cclxuICAgICAgICAgICAgZHJhdy5tYXAoYXN5bmMgKGVsZW1lbnQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChlbGVtZW50Lm5vZGVOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInJlY3RcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRTY2FuSW5SZWN0KFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29lZmZYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29lZmZZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdmlnYXRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImVsbGlwc2VcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRTY2FuSW5DaXJjbGUoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicGF0aFwiOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNldFNjYW5JblBvbHlnb24oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzZXRTY2FuSW5SZWN0KGltZzogYW55LCBjb2VmZlg6IG51bWJlciwgY29lZmZZOiBudW1iZXIsXHJcbiAgICAgICAgZWxlbWVudDogeyBhbmdsZTogYW55OyBjeDogYW55OyBjeTogYW55OyB4OiBudW1iZXI7IHdpZHRoOiBhbnk7IHk6IG51bWJlcjsgaGVpZ2h0OiBhbnk7IH0sIG5hdmlnYXRpb25zOiBhbnlbXSkge1xyXG4gICAgICAgIGNvbnN0IGNhbGlicmFnZSA9IEpTT04ucGFyc2UodGhpcy5jaG9zZW5QbGFuLmNhbGlicmF0aW9uKTtcclxuICAgICAgICBuYXZpZ2F0aW9ucy5tYXAoKG5hdmlnYXRpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25zT25QbGFuID0gbmF2aWdhdGlvbi5wb3NpdGlvbk9uUGxhbi5tYXAoKGVudHJ5KSA9PlxyXG4gICAgICAgICAgICAgICAgSlNPTi5wYXJzZShlbnRyeSksXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uT25QbGFuID0gcG9zaXRpb25zT25QbGFuLmZpbmQoXHJcbiAgICAgICAgICAgICAgICAoZGF0YSkgPT4gZGF0YS5wbGFuSUQgPT09IHRoaXMuY2hvc2VuUGxhbi5pZCxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uT25QbGFuKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsV2lkdGggPSBpbWcud2lkdGggLyBjb2VmZlg7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsSGVpZ2h0ID0gaW1nLmhlaWdodCAvIGNvZWZmWTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hdlkgPSAocG9zaXRpb25PblBsYW4ueSAqIHJlYWxIZWlnaHQpIC8gY2FsaWJyYWdlLmltZ0hlaWdodDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hdlggPSAocG9zaXRpb25PblBsYW4ueCAqIHJlYWxXaWR0aCkgLyBjYWxpYnJhZ2UuaW1nV2lkdGg7XHJcbiAgICAgICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgICAgICAgbmF2WCA+IGVsZW1lbnQueCAmJlxyXG4gICAgICAgICAgICAgICAgICAgIG5hdlggPCBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoICYmXHJcbiAgICAgICAgICAgICAgICAgICAgbmF2WSA+IGVsZW1lbnQueSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIG5hdlkgPCBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCAmJlxyXG4gICAgICAgICAgICAgICAgICAgICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdklEc1pvbmVFZGl0LnB1c2gobmF2aWdhdGlvbi5pZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIG9sZCBjYWxpYnJhdGlvbjpcclxuICAgICAgICAgICAgLy8gY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdmlnYXRpb24ucG9zaXRpb24pO1xyXG4gICAgICAgICAgICAvLyBsZXQgbmF2WCA9IChjYWxpYnJhZ2Uub2Zmc2V0WCArIHBvc2l0aW9uLnggKiBjYWxpYnJhZ2UueCkgLyBjb2VmZlg7XHJcbiAgICAgICAgICAgIC8vIGxldCBuYXZZID0gKGNhbGlicmFnZS5vZmZzZXRZICsgcG9zaXRpb24ueiAqIGNhbGlicmFnZS55KSAvIGNvZWZmWTtcclxuICAgICAgICAgICAgLy8gaWYgKGVsZW1lbnQuYW5nbGUpIHtcclxuICAgICAgICAgICAgLy8gICAgIGNvbnN0IHJvdGF0ZVBvcyA9IHJvdGF0ZShcclxuICAgICAgICAgICAgLy8gICAgICAgICB7IHg6IG5hdlgsIHk6IG5hdlkgfSxcclxuICAgICAgICAgICAgLy8gICAgICAgICB7IHg6IGVsZW1lbnQuY3gsIHk6IGVsZW1lbnQuY3kgfSxcclxuICAgICAgICAgICAgLy8gICAgICAgICBlbGVtZW50LmFuZ2xlLFxyXG4gICAgICAgICAgICAvLyAgICAgKTtcclxuICAgICAgICAgICAgLy8gICAgIG5hdlggPSByb3RhdGVQb3MueDtcclxuICAgICAgICAgICAgLy8gICAgIG5hdlkgPSByb3RhdGVQb3MueTtcclxuICAgICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVE9ETyBjYWxjdWxlciBsYSByb3RhdGlvbiBkdSByZWN0YW5nbGVcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIC8vIGlmIChcclxuICAgICAgICAgICAgLy8gICAgIG5hdlggPiBlbGVtZW50LnggJiZcclxuICAgICAgICAgICAgLy8gICAgIG5hdlggPCBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoICYmXHJcbiAgICAgICAgICAgIC8vICAgICBuYXZZID4gZWxlbWVudC55ICYmXHJcbiAgICAgICAgICAgIC8vICAgICBuYXZZIDwgZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgJiZcclxuICAgICAgICAgICAgLy8gICAgICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpXHJcbiAgICAgICAgICAgIC8vICkge1xyXG4gICAgICAgICAgICAvLyAgICAgdGhpcy5uYXZJRHNab25lRWRpdC5wdXNoKG5hdmlnYXRpb24uaWQpO1xyXG4gICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9IC8vIEVPXHJcblxyXG4gICAgYXN5bmMgc2V0U2NhbkluQ2lyY2xlKGltZzogYW55LCBjb2VmZlg6IG51bWJlciwgY29lZmZZOiBudW1iZXIsXHJcbiAgICAgICAgZWxlbWVudDogeyBhbmdsZTogYW55OyBjeDogbnVtYmVyOyBjeTogbnVtYmVyOyByeDogbnVtYmVyOyByeTogbnVtYmVyOyB9LCBuYXZpZ2F0aW9uczogTmF2aWdhdGlvbltdKSB7XHJcbiAgICAgICAgY29uc3QgY2FsaWJyYWdlID0gSlNPTi5wYXJzZSh0aGlzLmNob3NlblBsYW4uY2FsaWJyYXRpb24pO1xyXG4gICAgICAgIG5hdmlnYXRpb25zLm1hcChuYXZpZ2F0aW9uID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25zT25QbGFuID0gbmF2aWdhdGlvbi5wb3NpdGlvbk9uUGxhbi5tYXAoKGVudHJ5KSA9PlxyXG4gICAgICAgICAgICAgICAgSlNPTi5wYXJzZShlbnRyeSksXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uT25QbGFuID0gcG9zaXRpb25zT25QbGFuLmZpbmQoXHJcbiAgICAgICAgICAgICAgICAoZGF0YSkgPT4gZGF0YS5wbGFuSUQgPT09IHRoaXMuY2hvc2VuUGxhbi5pZCxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uT25QbGFuKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsV2lkdGggPSBpbWcud2lkdGggLyBjb2VmZlg7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsSGVpZ2h0ID0gaW1nLmhlaWdodCAvIGNvZWZmWTtcclxuICAgICAgICAgICAgICAgIGxldCBuYXZZID0gKHBvc2l0aW9uT25QbGFuLnkgKiByZWFsSGVpZ2h0KSAvIGNhbGlicmFnZS5pbWdIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICBsZXQgbmF2WCA9IChwb3NpdGlvbk9uUGxhbi54ICogcmVhbFdpZHRoKSAvIGNhbGlicmFnZS5pbWdXaWR0aDtcclxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmFuZ2xlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgcm90YXRlUG9zID0gcm90YXRlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7IHg6IG5hdlgsIHk6IG5hdlkgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgeyB4OiBlbGVtZW50LmN4LCB5OiBlbGVtZW50LmN5IH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYW5nbGUsXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICBuYXZYID0gcm90YXRlUG9zLng7XHJcbiAgICAgICAgICAgICAgICAgICAgbmF2WSA9IHJvdGF0ZVBvcy55O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlWCA9XHJcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5wb3cobmF2WCAtIGVsZW1lbnQuY3gsIDIpIC8gTWF0aC5wb3coZWxlbWVudC5yeCwgMik7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVkgPVxyXG4gICAgICAgICAgICAgICAgICAgIE1hdGgucG93KG5hdlkgLSBlbGVtZW50LmN5LCAyKSAvIE1hdGgucG93KGVsZW1lbnQucnksIDIpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWVYICsgdmFsdWVZO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA8PSAxICYmICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXZJRHNab25lRWRpdC5wdXNoKG5hdmlnYXRpb24uaWQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBvbGQgY2FsaWJyYXRpb25cclxuICAgICAgICAgICAgLy8gY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdmlnYXRpb24ucG9zaXRpb24pO1xyXG4gICAgICAgICAgICAvLyBsZXQgbmF2WCA9IChjYWxpYnJhZ2Uub2Zmc2V0WCArIHBvc2l0aW9uLnggKiBjYWxpYnJhZ2UueCkgLyBjb2VmZlg7XHJcbiAgICAgICAgICAgIC8vIGxldCBuYXZZID0gKGNhbGlicmFnZS5vZmZzZXRZICsgcG9zaXRpb24ueiAqIGNhbGlicmFnZS55KSAvIGNvZWZmWTtcclxuICAgICAgICAgICAgLy8gaWYgKGVsZW1lbnQuYW5nbGUpIHtcclxuICAgICAgICAgICAgLy8gICAgIGNvbnN0IHJvdGF0ZVBvcyA9IHJvdGF0ZShcclxuICAgICAgICAgICAgLy8gICAgICAgICB7IHg6IG5hdlgsIHk6IG5hdlkgfSxcclxuICAgICAgICAgICAgLy8gICAgICAgICB7IHg6IGVsZW1lbnQuY3gsIHk6IGVsZW1lbnQuY3kgfSxcclxuICAgICAgICAgICAgLy8gICAgICAgICBlbGVtZW50LmFuZ2xlLFxyXG4gICAgICAgICAgICAvLyAgICAgKTtcclxuICAgICAgICAgICAgLy8gICAgIG5hdlggPSByb3RhdGVQb3MueDtcclxuICAgICAgICAgICAgLy8gICAgIG5hdlkgPSByb3RhdGVQb3MueTtcclxuICAgICAgICAgICAgLy8gfVxyXG5cclxuICAgICAgICAgICAgLy8gY29uc3QgdmFsdWVYID1cclxuICAgICAgICAgICAgLy8gICAgIE1hdGgucG93KG5hdlggLSBlbGVtZW50LmN4LCAyKSAvIE1hdGgucG93KGVsZW1lbnQucngsIDIpO1xyXG4gICAgICAgICAgICAvLyBjb25zdCB2YWx1ZVkgPVxyXG4gICAgICAgICAgICAvLyAgICAgTWF0aC5wb3cobmF2WSAtIGVsZW1lbnQuY3ksIDIpIC8gTWF0aC5wb3coZWxlbWVudC5yeSwgMik7XHJcbiAgICAgICAgICAgIC8vIGNvbnN0IHJlc3VsdCA9IHZhbHVlWCArIHZhbHVlWTtcclxuICAgICAgICAgICAgLy8gaWYgKHJlc3VsdCA8PSAxICYmICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpKSB7XHJcbiAgICAgICAgICAgIC8vICAgICB0aGlzLm5hdklEc1pvbmVFZGl0LnB1c2gobmF2aWdhdGlvbi5pZCk7XHJcbiAgICAgICAgICAgIC8vIH1cclxuICAgICAgICB9KTtcclxuICAgIH0gLy8gRU9cclxuXHJcbiAgICBhc3luYyBzZXRTY2FuSW5Qb2x5Z29uKGltZzogYW55LCBjb2VmZlg6IG51bWJlciwgY29lZmZZOiBudW1iZXIsIGVsZW1lbnQ6IHsgc2VnTGlzdDogYW55OyB9LCBuYXZpZ2F0aW9uczogYW55W10pIHtcclxuICAgICAgICBjb25zdCBjYWxpYnJhZ2UgPSBKU09OLnBhcnNlKHRoaXMuY2hvc2VuUGxhbi5jYWxpYnJhdGlvbik7XHJcbiAgICAgICAgbmF2aWdhdGlvbnMubWFwKGFzeW5jIChuYXZpZ2F0aW9uKSA9PiB7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbnNPblBsYW4gPSBuYXZpZ2F0aW9uLnBvc2l0aW9uT25QbGFuLm1hcCgoZW50cnkpID0+XHJcbiAgICAgICAgICAgICAgICBKU09OLnBhcnNlKGVudHJ5KSxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25PblBsYW4gPSBwb3NpdGlvbnNPblBsYW4uZmluZChcclxuICAgICAgICAgICAgICAgIChkYXRhKSA9PiBkYXRhLnBsYW5JRCA9PT0gdGhpcy5jaG9zZW5QbGFuLmlkLFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBpZiAocG9zaXRpb25PblBsYW4pIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWxXaWR0aCA9IGltZy53aWR0aCAvIGNvZWZmWDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWxIZWlnaHQgPSBpbWcuaGVpZ2h0IC8gY29lZmZZO1xyXG4gICAgICAgICAgICAgICAgbGV0IG5hdlkgPSAocG9zaXRpb25PblBsYW4ueSAqIHJlYWxIZWlnaHQpIC8gY2FsaWJyYWdlLmltZ0hlaWdodDtcclxuICAgICAgICAgICAgICAgIGxldCBuYXZYID0gKHBvc2l0aW9uT25QbGFuLnggKiByZWFsV2lkdGgpIC8gY2FsaWJyYWdlLmltZ1dpZHRoO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHAgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeDogbmF2WCxcclxuICAgICAgICAgICAgICAgICAgICB5OiBuYXZZLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBpc0luUG9seWdvbihwLCBlbGVtZW50LnNlZ0xpc3QpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgIXRoaXMubmF2SURzWm9uZUVkaXQuaW5jbHVkZXMobmF2aWdhdGlvbi5pZClcclxuICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubmF2SURzWm9uZUVkaXQucHVzaChuYXZpZ2F0aW9uLmlkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gb2xkIGNhbGlicmF0aW9uXHJcbiAgICAgICAgICAgIC8vIGNvbnN0IHBvc2l0aW9uID0gSlNPTi5wYXJzZShuYXZpZ2F0aW9uLnBvc2l0aW9uKTtcclxuICAgICAgICAgICAgLy8gY29uc3QgcCA9IHtcclxuICAgICAgICAgICAgLy8gICAgIHg6IChjYWxpYnJhZ2Uub2Zmc2V0WCArIHBvc2l0aW9uLnggKiBjYWxpYnJhZ2UueCkgLyBjb2VmZlgsXHJcbiAgICAgICAgICAgIC8vICAgICB5OiAoY2FsaWJyYWdlLm9mZnNldFkgKyBwb3NpdGlvbi56ICogY2FsaWJyYWdlLnkpIC8gY29lZmZZLFxyXG4gICAgICAgICAgICAvLyB9O1xyXG4gICAgICAgICAgICAvLyBpZiAoZWxlbWVudC5hbmdsZSkge1xyXG4gICAgICAgICAgICAvLyAgICAgcCA9IHRoaXMucm90YXRlKFxyXG4gICAgICAgICAgICAvLyAgICAgICAgIHAsXHJcbiAgICAgICAgICAgIC8vICAgICAgICAgeyB4OiBlbGVtZW50LmN4LCB5OiBlbGVtZW50LmN5IH0sXHJcbiAgICAgICAgICAgIC8vICAgICAgICAgZWxlbWVudC5hbmdsZSxcclxuICAgICAgICAgICAgLy8gICAgICk7XHJcbiAgICAgICAgICAgIC8vIH1cclxuICAgICAgICAgICAgLy8gaWYgKFxyXG4gICAgICAgICAgICAvLyAgICAgaXNJblBvbHlnb24ocCwgZWxlbWVudC5zZWdMaXN0KSAmJlxyXG4gICAgICAgICAgICAvLyAgICAgIXRoaXMubmF2SURzWm9uZUVkaXQuaW5jbHVkZXMobmF2aWdhdGlvbi5pZClcclxuICAgICAgICAgICAgLy8gKSB7XHJcbiAgICAgICAgICAgIC8vICAgICB0aGlzLm5hdklEc1pvbmVFZGl0LnB1c2gobmF2aWdhdGlvbi5pZCk7XHJcbiAgICAgICAgICAgIC8vIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhckRpdlBsYW4oKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZGl2UGxhbikgdGhpcy5kaXZQbGFuLmlubmVySFRNTCA9IFwiXCI7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJpZ2dlciBlYWNoIGJ5IHRoZSBzZWxlY3Rpb25Db21wb25lbnQgd2hlbiBzZWxlY3Rpb24gY2hhbmdlXHJcbiAgICAgKiBVcGRhdGUgdGhlIGN1cnJlbnQgc2VsZWN0ZWQgc2NhbiBidXR0b25zXHJcbiAgICAgKiBAcGFyYW0gc2VsZWN0aW9uIG5ldyBzZWxlY3Rpb25cclxuICAgICAqL1xyXG4gICAgb25TZWxlY3Rpb25DaGFuZ2VkKHNlbGVjdGlvbjogUmVjdGFuZ2xlKSB7XHJcbiAgICAgICAgY29uc3QgdW5zZWxlY3RlZEJ1dHRvbnM6IEhUTUxCdXR0b25FbGVtZW50W10gPSBbXTtcclxuICAgICAgICBjb25zdCBuZXdTZWxlY3RlZEJ1dHRvbnMgPSBbXTtcclxuXHJcbiAgICAgICAgLyoqIEZvciBlYWNoIGJ1dHRvbiwgZGVjaWRlIHdoZXRoZXIgd2lsbCBiZSBhZGQgdG8gc2VsZWN0ZWQgbGlzdCBvciB1bnNlbGVjdGVkIGxpc3QgKi9cclxuICAgICAgICBmb3IgKGNvbnN0IGJ1dHRvbiBvZiB0aGlzLmJ1dHRvbkVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSBidXR0b25Jc0luU2VsZWN0aW9uKGJ1dHRvbiwgc2VsZWN0aW9uKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYnV0dG9uc0luU2VsZWN0aW9uLmluY2x1ZGVzKGJ1dHRvbikpIHtcclxuICAgICAgICAgICAgICAgIC8qKiBJZiB0aGUgYnV0dG9uIGlzIGFscmVhZHkgaW4gdGhlIHNlbGVjdGVkIGxpc3QsIHdlIGNoZWNrIGlmIGl0IHNob3VsZCBiZSB1bnNlbGVjdCAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpc1NlbGVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdW5zZWxlY3RlZEJ1dHRvbnMucHVzaChidXR0b24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzU2VsZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkQnV0dG9ucy5wdXNoKGJ1dHRvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBWaXN1YWxseSBVcGRhdGUgdW5zZWxlY3RlZCBsaXN0ICovXHJcbiAgICAgICAgZm9yIChjb25zdCBidXR0b24gb2YgdW5zZWxlY3RlZEJ1dHRvbnMpIHtcclxuICAgICAgICAgICAgc2V0VmlzdWFsbHlTZWxlY3RlZChidXR0b24sIGZhbHNlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBWaXN1YWxseSBVcGRhdGUgc2VsZWN0ZWQgbGlzdCAqL1xyXG4gICAgICAgIGZvciAoY29uc3QgYnV0dG9uIG9mIG5ld1NlbGVjdGVkQnV0dG9ucykge1xyXG4gICAgICAgICAgICBzZXRWaXN1YWxseVNlbGVjdGVkKGJ1dHRvbiwgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiogUmVtb3ZlICB1bnNlbGVjdGVkIGxpc3QgKi9cclxuICAgICAgICB0aGlzLmJ1dHRvbnNJblNlbGVjdGlvbiA9IHRoaXMuYnV0dG9uc0luU2VsZWN0aW9uLmZpbHRlcigoYnV0dG9uKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiAhdW5zZWxlY3RlZEJ1dHRvbnMuaW5jbHVkZXMoYnV0dG9uKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvKiogQWRkIG5ldyBzZWxlY3RlZCBidXR0b25zICovXHJcbiAgICAgICAgdGhpcy5idXR0b25zSW5TZWxlY3Rpb24gPSBbXHJcbiAgICAgICAgICAgIC4uLnRoaXMuYnV0dG9uc0luU2VsZWN0aW9uLFxyXG4gICAgICAgICAgICAuLi5uZXdTZWxlY3RlZEJ1dHRvbnMsXHJcbiAgICAgICAgXTtcclxuICAgIH1cclxuXHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJpZ2dlciB3aGVuIHRoZSB1c2VyIGNsaWNrIHRvIGFkZCB0aGUgc2VsZWN0ZWQgc2NhbnNcclxuICAgICAqL1xyXG4gICAgb25TZWxlY3Rpb25BZGQoKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCBidXR0b24gb2YgdGhpcy5idXR0b25zSW5TZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25CdXR0b25TY2FuQ2xpY2tlZChidXR0b24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZCh7IHRvcDogMCwgbGVmdDogMCwgd2lkdGg6IDAsIGhlaWdodDogMCB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRyaWdnZXIgd2hlbiB0aGUgdXNlciBjbGljayB0byByZW1vdmUgdGhlIHNlbGVjdGVkIHNjYW5zXHJcbiAgICAgKi9cclxuICAgIG9uU2VsZWN0aW9uUmVtb3ZlKCkge1xyXG4gICAgICAgIGZvciAoY29uc3QgYnV0dG9uIG9mIHRoaXMuYnV0dG9uc0luU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25CdXR0b25TY2FuQ2xpY2tlZChidXR0b24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKHsgdG9wOiAwLCBsZWZ0OiAwLCB3aWR0aDogMCwgaGVpZ2h0OiAwIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJpZ2dlciB3aGVuIHRoZSB1c2VyIGNsaWNrIHRvIHNlbGVjdCBhbGwgc2NhbnNcclxuICAgICAqL1xyXG4gICAgb25TZWxlY3RBbGwoKSB7XHJcbiAgICAgICAgdGhpcy5idXR0b25zSW5TZWxlY3Rpb24gPSBbLi4udGhpcy5idXR0b25FbGVtZW50c107XHJcbiAgICAgICAgZm9yIChjb25zdCBidXR0b24gb2YgdGhpcy5idXR0b25zSW5TZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgc2V0VmlzdWFsbHlTZWxlY3RlZChidXR0b24sIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRyaWdnZXIgd2hlbiB0aGUgdXNlciBjaGFuZ2UgdGhlIHNpemUgb2YgdGhlIHNjYW4gcG9pbnRzXHJcbiAgICAgKiBAcGFyYW0gZXZlbnRcclxuICAgICAqL1xyXG4gICAgb25DaGFuZ2VTY2FuU2l6ZShldmVudDogYW55KSB7XHJcbiAgICAgICAgY29uc3QgZmFjdG9yID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGJ1dHRvbiBvZiB0aGlzLmJ1dHRvbkVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS50cmFuc2Zvcm0gPSBgc2NhbGUoJHtmYWN0b3J9KWA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hlbiBhIGJ1dHRvbiByZXByZXNlbnRpbmcgYSBzY2FuIGlzIGNsaWNrZWRcclxuICAgICAqIEBwYXJhbSBidXR0b25cclxuICAgICAqL1xyXG4gICAgb25CdXR0b25TY2FuQ2xpY2tlZChidXR0b246IEhUTUxFbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNTZXR0aW5nU3RhcnRTd2VlcCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5zdGFydFN3ZWVwSUQgPT09IGJ1dHRvbi5pZCkge1xyXG4gICAgICAgICAgICAgICAgLy8gd2UgZGVzZWxlY3QgdGhlIHN0YXJ0aW5nIHBvaW50XHJcbiAgICAgICAgICAgICAgICBidXR0b24uc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybChcImh0dHBzOi8vYXBpLmljb25pZnkuZGVzaWduL21kaTphZGp1c3Quc3ZnP2NvbG9yPWdyZWVuJmhlaWdodD0xNyZ3aWR0aD0xN1wiKWA7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0U3dlZXBJRCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IGB1cmwoJ2h0dHBzOi8vYXBpLmljb25pZnkuZGVzaWduL2ljL2Jhc2VsaW5lLWZsYWctY2lyY2xlLnN2Zz9jb2xvcj13aGl0ZSZ3aWR0aD0xNyZoZWlnaHQ9MTcnKWA7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5jaG9zZW5TY2Fuc09uUGxhbi5pbmNsdWRlcyhidXR0b24uaWQpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNob3NlblNjYW5zT25QbGFuLnB1c2goYnV0dG9uLmlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGhpcy5zdGFydFN3ZWVwSUQpIHtcclxuICAgICAgICAgICAgICAgIC8vIHdlIGFyZSBjaGFuZ2luZyBzdGFydCBzd2VlcFxyXG4gICAgICAgICAgICAgICAgY29uc3QgYnRuQ2hhbmdlZCA9IHRoaXMuYnV0dG9uRWxlbWVudHMuZmluZCgoYnRuKSA9PiBidG4uaWQgPT09IHRoaXMuc3RhcnRTd2VlcElEKTtcclxuICAgICAgICAgICAgICAgIGJ0bkNoYW5nZWQuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybChcImh0dHBzOi8vYXBpLmljb25pZnkuZGVzaWduL21kaTphZGp1c3Quc3ZnP2NvbG9yPWdyZWVuJmhlaWdodD0xNyZ3aWR0aD0xN1wiKWA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5zdGFydFN3ZWVwSUQgPSBidXR0b24uaWQ7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcclxuICAgICAgICAgICAgLy8gYWRkIHRvIHNlbGVjdGlvblxyXG4gICAgICAgICAgICBidXR0b24uc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybChcImh0dHBzOi8vYXBpLmljb25pZnkuZGVzaWduL21kaTphZGp1c3Quc3ZnP2NvbG9yPWdyZWVuJmhlaWdodD0xNyZ3aWR0aD0xN1wiKWA7XHJcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4ucHVzaChidXR0b24uaWQpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIHJlbW92ZSBmcm9tIHNlbGVjdGlvblxyXG4gICAgICAgICAgICBpZiAodGhpcy5vY2N1cGllZFN3ZWVwcy5pbmNsdWRlcyhidXR0b24uaWQpICYmICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBzd2VlcCBiZWxvbmdzIHRvIGFub3RoZXIgem9uZSA9PiBzZXQgb3JhbmdlXHJcbiAgICAgICAgICAgICAgICBidXR0b24uc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybChcImh0dHBzOi8vYXBpLmljb25pZnkuZGVzaWduL21kaTphZGp1c3Quc3ZnP2NvbG9yPW9yYW5nZSZoZWlnaHQ9MTcmd2lkdGg9MTdcIilgO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IGB1cmwoXCJodHRwczovL2FwaS5pY29uaWZ5LmRlc2lnbi9tZGk6Y2xvc2UtY2lyY2xlLW91dGxpbmUuc3ZnP2NvbG9yPXJlZCZoZWlnaHQ9MTcmd2lkdGg9MTdcIilgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5jaG9zZW5TY2Fuc09uUGxhbi5pbmRleE9mKGJ1dHRvbi5pZCk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4uc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25TYXZlU2VsZWN0aW9uKCkge1xyXG4gICAgICAgIHRoaXMuc3dlZXBzU2VsZWN0ZWQuZW1pdCh7IFwic3dlZXBzXCI6IHRoaXMuY2hvc2VuU2NhbnNPblBsYW4sIFwic3RhcnRTd2VlcElEXCI6IHRoaXMuc3RhcnRTd2VlcElEIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQ2FuY2VsKCkge1xyXG4gICAgICAgIHRoaXMuc3dlZXBzU2VsZWN0ZWQuZW1pdChudWxsKTtcclxuICAgIH1cclxufVxyXG4iLCI8ZGl2IG5nYkRyb3Bkb3duIGNsYXNzPVwic3Atcm93IGQtaW5saW5lLWJsb2NrXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTNcIiAqbmdJZj1cInBsYW5zXCI+XHJcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1sYWJlbC1maWxlIHJvdW5kZWQtcGlsbFwiIGlkPVwiZHJvcGRvd25CYXNpYzFcIlxyXG4gICAgICAgICAgICAgICAgbmdiRHJvcGRvd25Ub2dnbGU+e3tjaG9zZW5QbGFuID9cclxuICAgICAgICAgICAgICAgIGNob3NlblBsYW4ubmFtZSA6ICgnQ2hvb3NlIFBsYW4nIHwgdHJhbnNsYXRlKSB9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8ZGl2IG5nYkRyb3Bkb3duTWVudSBhcmlhLWxhYmVsbGVkYnk9XCJkcm9wZG93bkJhc2ljMVwiPlxyXG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbmdiRHJvcGRvd25JdGVtICpuZ0Zvcj1cImxldCBwbGFuIG9mIHBsYW5zXCIgKGNsaWNrKT1cIm9uUGxhbkNsaWNrKHBsYW4pXCJcclxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIXBsYW4uY2FsaWJyYXRpb25cIj57eyBwbGFuLm5hbWUgfX1cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L2Rpdj5cclxuPGRpdiBjbGFzcz1cInNwLXJvd1wiPlxyXG4gICAgPGxpYi1zZWxlY3Rpb24gY2xhc3M9XCJjb2wtbWQtOFwiIChvblNlbGVjdGlvbkNoYW5nZWQpPVwib25TZWxlY3Rpb25DaGFuZ2VkKCRldmVudClcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0Wm9uZVwiIG9uY29udGV4dG1lbnU9XCJyZXR1cm4gZmFsc2U7XCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJvdmVyZmxvdzogaGlkZGVuO3dpZHRoOjEwMCU7XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImhlaWdodDogNDAwcHg7IHdpZHRoOiAxMDAlO1wiIGlkPVwicGxhbkRpdlwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9saWItc2VsZWN0aW9uPlxyXG4gICAgXHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgc2NhblRvb2xcIiAqbmdJZj1cImJ1dHRvbkVsZW1lbnRzLmxlbmd0aCA+IDBcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwic3Atcm93IGQtaW5saW5lLWJsb2NrXCI+XHJcbiAgICAgICAgICAgIDxoMj57eydzZWxlY3RUb29sLnRpdGxlJyB8IHRyYW5zbGF0ZX19PC9oMj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb3RpcFwiPnt7J3NlbGVjdFRvb2wudGlwJyB8IHRyYW5zbGF0ZX19LjwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNwLXJvd1wiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTNcIiBzdHlsZT1cInBhZGRpbmc6MHB4XCI+XHJcbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0b29sLWxhYmVsXCIgZm9yPVwic2NhblNpemVcIj57eydzZWxlY3RUb29sLnNpemUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC05XCI+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhbmdlXCIgY2xhc3M9XCJmb3JtLXJhbmdlXCIgbWluPVwiMC4wMDFcIiBtYXg9XCI1XCIgc3RlcD1cIjAuMDFcIiB2YWx1ZT1cIjFcIlxyXG4gICAgICAgICAgICAgICAgICAgIGlkPVwic2NhblNpemVcIiAoaW5wdXQpPVwib25DaGFuZ2VTY2FuU2l6ZSgkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNwLXJvd1wiPlxyXG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiIChjbGljayk9XCJvblNlbGVjdEFsbCgpXCI+e3snc2VsZWN0VG9vbC5zZWxlY3RBbGwnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIFxyXG4gICAgICAgIDxkaXYgKm5nSWY9XCJidXR0b25zSW5TZWxlY3Rpb24ubGVuZ3RoID4gMFwiIGNsYXNzPVwiZWRpdC1zZWxlY3RlZFwiPlxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2wtbGFiZWxcIj57eydzZWxlY3RUb29sLmVkaXQnIHwgdHJhbnNsYXRlfX0gOiA8L3NwYW4+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cclxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gcm91bmRlZC1waWxsIGJ0bi1wcmltYXJ5IG1zLTMgbWUtMlwiIChjbGljayk9XCJvblNlbGVjdGlvbkFkZCgpXCI+e3snc2VsZWN0VG9vbC5hZGQnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uU2VsZWN0aW9uUmVtb3ZlKClcIj57eydzZWxlY3RUb29sLnVuZG8nIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cclxuICAgICAgICAgICAge3sgY2hvc2VuU2NhbnNPblBsYW4ubGVuZ3RoIH19IHt7J3NjYW4gcG9pbnRzIGNob3NlbicgfCB0cmFuc2xhdGV9fSAgICAgICAgIFxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgKm5nSWY9XCIhZWRpdGluZ0F1ZGlvWm9uZVwiIGNsYXNzPVwic3Atcm93XCI+XHJcbiAgICAgICAgICAgIDxsaWItcmFkaW8tYnV0dG9uICBsYWJlbD1cInt7ICdzZWxlY3RUb29sLmNob29zZVN0YXJ0UG9pbnQnICB8IHRyYW5zbGF0ZSB9fVwiIChpc0NoZWNrZWRFdmVudCk9XCJpc1NldHRpbmdTdGFydFN3ZWVwPSFpc1NldHRpbmdTdGFydFN3ZWVwXCI+PC9saWItcmFkaW8tYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIFxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25TYXZlU2VsZWN0aW9uKClcIj57eydzZWxlY3RUb29sLnNhdmVTZWxlY3Rpb24nIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiIChjbGljayk9XCJvbkNhbmNlbCgpXCI+e3snc2VsZWN0VG9vbC5jYW5jZWxTZWxlY3Rpb24nIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuPC9kaXY+XHJcbiAgIFxyXG4iXX0=
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { getCoefficientsForImage, getMetaForImage, showScanPointsOnPlanInDiv } from '@smarterplan/ngx-smarterplan-core';
|
|
3
|
+
import panzoom from 'panzoom';
|
|
4
|
+
import { buttonIsInSelection, isInPolygon, rotate, setVisuallySelected, styleButton, SweepState } from '../../../../helper.service';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@smarterplan/ngx-smarterplan-core";
|
|
7
|
+
import * as i2 from "../selection/selection.component";
|
|
8
|
+
import * as i3 from "../../../plan-legend/plan-legend.component";
|
|
9
|
+
import * as i4 from "../../../../radio-button/radio-button.component";
|
|
10
|
+
import * as i5 from "@ng-bootstrap/ng-bootstrap";
|
|
11
|
+
import * as i6 from "@angular/common";
|
|
12
|
+
import * as i7 from "@ngx-translate/core";
|
|
13
|
+
export class SweepPlanSelectionComponent {
|
|
14
|
+
constructor(zoneService, navigationService, planService) {
|
|
15
|
+
this.zoneService = zoneService;
|
|
16
|
+
this.navigationService = navigationService;
|
|
17
|
+
this.planService = planService;
|
|
18
|
+
this.chosenScansOnPlan = [];
|
|
19
|
+
this.navIDsZoneEdit = [];
|
|
20
|
+
// sweeps belonging to any audio zone
|
|
21
|
+
this.occupiedSweeps = [];
|
|
22
|
+
// sweeps unavailable (cannot be chosen)
|
|
23
|
+
this.unavailableSweeps = [];
|
|
24
|
+
// if choosing sweeps for audio zone
|
|
25
|
+
this.editingAudioZone = false;
|
|
26
|
+
/** all scan buttons Element */
|
|
27
|
+
this.buttonElements = [];
|
|
28
|
+
/** Scan buttons that are in the current selection */
|
|
29
|
+
this.buttonsInSelection = [];
|
|
30
|
+
this.sweepsSelected = new EventEmitter();
|
|
31
|
+
this.isSettingStartSweep = false;
|
|
32
|
+
}
|
|
33
|
+
ngOnInit() {
|
|
34
|
+
this.getPlans();
|
|
35
|
+
if (this.inputZone) {
|
|
36
|
+
this.setSweepsOfInputZone();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
ngOnChanges() {
|
|
40
|
+
if (this.chosenPlan) {
|
|
41
|
+
this.setSweepsOfInputZone();
|
|
42
|
+
this.chosenScansOnPlan = [];
|
|
43
|
+
this.clearDivPlan();
|
|
44
|
+
this.addScanPoints();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
setSweepsOfInputZone() {
|
|
48
|
+
this.navIDsZoneEdit = this.inputZone.sweepIDs;
|
|
49
|
+
}
|
|
50
|
+
async getPlans() {
|
|
51
|
+
this.plans = await this.planService.getSingedPlansForSpace(this.spaceID);
|
|
52
|
+
}
|
|
53
|
+
async onPlanClick(plan) {
|
|
54
|
+
this.chosenPlan = plan;
|
|
55
|
+
this.clearDivPlan();
|
|
56
|
+
this.addScanPoints();
|
|
57
|
+
}
|
|
58
|
+
async addScanPoints() {
|
|
59
|
+
this.divPlan = document.querySelector("#planDiv");
|
|
60
|
+
const zoneOfPlan = await this.zoneService.getZone(this.chosenPlan.zoneID);
|
|
61
|
+
const navigations = await this.navigationService.getNavigationsForZone(zoneOfPlan);
|
|
62
|
+
if (this.newZoneData)
|
|
63
|
+
await this.setScanByDraw(navigations);
|
|
64
|
+
this.buttonElements = await showScanPointsOnPlanInDiv(this.chosenPlan, this.divPlan, navigations);
|
|
65
|
+
for (const element of this.buttonElements) {
|
|
66
|
+
if (this.unavailableSweeps && this.unavailableSweeps.includes(element.id)) {
|
|
67
|
+
styleButton(element, SweepState.DISABLED);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if ((this.navIDsZoneEdit.length > 0 &&
|
|
71
|
+
this.navIDsZoneEdit.includes(element.id))
|
|
72
|
+
|| this.chosenScansOnPlan.includes(element.id)) {
|
|
73
|
+
styleButton(element, SweepState.ADDED);
|
|
74
|
+
if (!this.chosenScansOnPlan.includes(element.id)) {
|
|
75
|
+
this.chosenScansOnPlan.push(element.id);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else if (this.occupiedSweeps && this.occupiedSweeps.includes(element.id)) {
|
|
79
|
+
styleButton(element, SweepState.OCCUPIED);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
styleButton(element, SweepState.REMOVED);
|
|
83
|
+
}
|
|
84
|
+
//start point should be last condition
|
|
85
|
+
if (this.inputZone && this.inputZone.startSweepID === element.id) {
|
|
86
|
+
console.log("setting start point");
|
|
87
|
+
styleButton(element, SweepState.STARTPOINT);
|
|
88
|
+
}
|
|
89
|
+
element.addEventListener("click", (event) => this.onButtonScanClicked(event.target));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
this.panZoom = panzoom(this.divPlan, {
|
|
93
|
+
bounds: true,
|
|
94
|
+
boundsPadding: 0,
|
|
95
|
+
maxZoom: 3.5,
|
|
96
|
+
beforeMouseDown(e) {
|
|
97
|
+
return (e.button === 2); /** Ignore event for right click (use for selecting) */
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/** Function if we are coming for svg editor workflow */
|
|
102
|
+
setScanByDraw(navigations) {
|
|
103
|
+
return new Promise(async (resolve) => {
|
|
104
|
+
const rect = {
|
|
105
|
+
width: this.newZoneData.width,
|
|
106
|
+
height: this.newZoneData.height,
|
|
107
|
+
};
|
|
108
|
+
const img = await getMetaForImage(this.chosenPlan.filepath);
|
|
109
|
+
const { coeffX, coeffY } = getCoefficientsForImage(img, rect);
|
|
110
|
+
const draw = this.newZoneData.elements;
|
|
111
|
+
draw.map(async (element) => {
|
|
112
|
+
switch (element.nodeName) {
|
|
113
|
+
case "rect":
|
|
114
|
+
await this.setScanInRect(img, coeffX, coeffY, element, navigations);
|
|
115
|
+
break;
|
|
116
|
+
case "ellipse":
|
|
117
|
+
await this.setScanInCircle(img, coeffX, coeffY, element, navigations);
|
|
118
|
+
break;
|
|
119
|
+
case "path":
|
|
120
|
+
await this.setScanInPolygon(img, coeffX, coeffY, element, navigations);
|
|
121
|
+
break;
|
|
122
|
+
default:
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
resolve();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async setScanInRect(img, coeffX, coeffY, element, navigations) {
|
|
130
|
+
const calibrage = JSON.parse(this.chosenPlan.calibration);
|
|
131
|
+
navigations.map((navigation) => {
|
|
132
|
+
const positionsOnPlan = navigation.positionOnPlan.map((entry) => JSON.parse(entry));
|
|
133
|
+
const positionOnPlan = positionsOnPlan.find((data) => data.planID === this.chosenPlan.id);
|
|
134
|
+
if (positionOnPlan) {
|
|
135
|
+
const realWidth = img.width / coeffX;
|
|
136
|
+
const realHeight = img.height / coeffY;
|
|
137
|
+
const navY = (positionOnPlan.y * realHeight) / calibrage.imgHeight;
|
|
138
|
+
const navX = (positionOnPlan.x * realWidth) / calibrage.imgWidth;
|
|
139
|
+
if (navX > element.x &&
|
|
140
|
+
navX < element.x + element.width &&
|
|
141
|
+
navY > element.y &&
|
|
142
|
+
navY < element.y + element.height &&
|
|
143
|
+
!this.navIDsZoneEdit.includes(navigation.id)) {
|
|
144
|
+
this.navIDsZoneEdit.push(navigation.id);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// old calibration:
|
|
148
|
+
// const position = JSON.parse(navigation.position);
|
|
149
|
+
// let navX = (calibrage.offsetX + position.x * calibrage.x) / coeffX;
|
|
150
|
+
// let navY = (calibrage.offsetY + position.z * calibrage.y) / coeffY;
|
|
151
|
+
// if (element.angle) {
|
|
152
|
+
// const rotatePos = rotate(
|
|
153
|
+
// { x: navX, y: navY },
|
|
154
|
+
// { x: element.cx, y: element.cy },
|
|
155
|
+
// element.angle,
|
|
156
|
+
// );
|
|
157
|
+
// navX = rotatePos.x;
|
|
158
|
+
// navY = rotatePos.y;
|
|
159
|
+
// }
|
|
160
|
+
/**
|
|
161
|
+
* TODO calculer la rotation du rectangle
|
|
162
|
+
*/
|
|
163
|
+
// if (
|
|
164
|
+
// navX > element.x &&
|
|
165
|
+
// navX < element.x + element.width &&
|
|
166
|
+
// navY > element.y &&
|
|
167
|
+
// navY < element.y + element.height &&
|
|
168
|
+
// !this.navIDsZoneEdit.includes(navigation.id)
|
|
169
|
+
// ) {
|
|
170
|
+
// this.navIDsZoneEdit.push(navigation.id);
|
|
171
|
+
// }
|
|
172
|
+
});
|
|
173
|
+
} // EO
|
|
174
|
+
async setScanInCircle(img, coeffX, coeffY, element, navigations) {
|
|
175
|
+
const calibrage = JSON.parse(this.chosenPlan.calibration);
|
|
176
|
+
navigations.map(navigation => {
|
|
177
|
+
const positionsOnPlan = navigation.positionOnPlan.map((entry) => JSON.parse(entry));
|
|
178
|
+
const positionOnPlan = positionsOnPlan.find((data) => data.planID === this.chosenPlan.id);
|
|
179
|
+
if (positionOnPlan) {
|
|
180
|
+
const realWidth = img.width / coeffX;
|
|
181
|
+
const realHeight = img.height / coeffY;
|
|
182
|
+
let navY = (positionOnPlan.y * realHeight) / calibrage.imgHeight;
|
|
183
|
+
let navX = (positionOnPlan.x * realWidth) / calibrage.imgWidth;
|
|
184
|
+
if (element.angle) {
|
|
185
|
+
const rotatePos = rotate({ x: navX, y: navY }, { x: element.cx, y: element.cy }, element.angle);
|
|
186
|
+
navX = rotatePos.x;
|
|
187
|
+
navY = rotatePos.y;
|
|
188
|
+
}
|
|
189
|
+
const valueX = Math.pow(navX - element.cx, 2) / Math.pow(element.rx, 2);
|
|
190
|
+
const valueY = Math.pow(navY - element.cy, 2) / Math.pow(element.ry, 2);
|
|
191
|
+
const result = valueX + valueY;
|
|
192
|
+
if (result <= 1 && !this.navIDsZoneEdit.includes(navigation.id)) {
|
|
193
|
+
this.navIDsZoneEdit.push(navigation.id);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// old calibration
|
|
197
|
+
// const position = JSON.parse(navigation.position);
|
|
198
|
+
// let navX = (calibrage.offsetX + position.x * calibrage.x) / coeffX;
|
|
199
|
+
// let navY = (calibrage.offsetY + position.z * calibrage.y) / coeffY;
|
|
200
|
+
// if (element.angle) {
|
|
201
|
+
// const rotatePos = rotate(
|
|
202
|
+
// { x: navX, y: navY },
|
|
203
|
+
// { x: element.cx, y: element.cy },
|
|
204
|
+
// element.angle,
|
|
205
|
+
// );
|
|
206
|
+
// navX = rotatePos.x;
|
|
207
|
+
// navY = rotatePos.y;
|
|
208
|
+
// }
|
|
209
|
+
// const valueX =
|
|
210
|
+
// Math.pow(navX - element.cx, 2) / Math.pow(element.rx, 2);
|
|
211
|
+
// const valueY =
|
|
212
|
+
// Math.pow(navY - element.cy, 2) / Math.pow(element.ry, 2);
|
|
213
|
+
// const result = valueX + valueY;
|
|
214
|
+
// if (result <= 1 && !this.navIDsZoneEdit.includes(navigation.id)) {
|
|
215
|
+
// this.navIDsZoneEdit.push(navigation.id);
|
|
216
|
+
// }
|
|
217
|
+
});
|
|
218
|
+
} // EO
|
|
219
|
+
async setScanInPolygon(img, coeffX, coeffY, element, navigations) {
|
|
220
|
+
const calibrage = JSON.parse(this.chosenPlan.calibration);
|
|
221
|
+
navigations.map(async (navigation) => {
|
|
222
|
+
const positionsOnPlan = navigation.positionOnPlan.map((entry) => JSON.parse(entry));
|
|
223
|
+
const positionOnPlan = positionsOnPlan.find((data) => data.planID === this.chosenPlan.id);
|
|
224
|
+
if (positionOnPlan) {
|
|
225
|
+
const realWidth = img.width / coeffX;
|
|
226
|
+
const realHeight = img.height / coeffY;
|
|
227
|
+
let navY = (positionOnPlan.y * realHeight) / calibrage.imgHeight;
|
|
228
|
+
let navX = (positionOnPlan.x * realWidth) / calibrage.imgWidth;
|
|
229
|
+
const p = {
|
|
230
|
+
x: navX,
|
|
231
|
+
y: navY,
|
|
232
|
+
};
|
|
233
|
+
if (isInPolygon(p, element.segList) &&
|
|
234
|
+
!this.navIDsZoneEdit.includes(navigation.id)) {
|
|
235
|
+
this.navIDsZoneEdit.push(navigation.id);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// old calibration
|
|
239
|
+
// const position = JSON.parse(navigation.position);
|
|
240
|
+
// const p = {
|
|
241
|
+
// x: (calibrage.offsetX + position.x * calibrage.x) / coeffX,
|
|
242
|
+
// y: (calibrage.offsetY + position.z * calibrage.y) / coeffY,
|
|
243
|
+
// };
|
|
244
|
+
// if (element.angle) {
|
|
245
|
+
// p = this.rotate(
|
|
246
|
+
// p,
|
|
247
|
+
// { x: element.cx, y: element.cy },
|
|
248
|
+
// element.angle,
|
|
249
|
+
// );
|
|
250
|
+
// }
|
|
251
|
+
// if (
|
|
252
|
+
// isInPolygon(p, element.segList) &&
|
|
253
|
+
// !this.navIDsZoneEdit.includes(navigation.id)
|
|
254
|
+
// ) {
|
|
255
|
+
// this.navIDsZoneEdit.push(navigation.id);
|
|
256
|
+
// }
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
clearDivPlan() {
|
|
260
|
+
if (this.divPlan)
|
|
261
|
+
this.divPlan.innerHTML = "";
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Trigger each by the selectionComponent when selection change
|
|
265
|
+
* Update the current selected scan buttons
|
|
266
|
+
* @param selection new selection
|
|
267
|
+
*/
|
|
268
|
+
onSelectionChanged(selection) {
|
|
269
|
+
const unselectedButtons = [];
|
|
270
|
+
const newSelectedButtons = [];
|
|
271
|
+
/** For each button, decide whether will be add to selected list or unselected list */
|
|
272
|
+
for (const button of this.buttonElements) {
|
|
273
|
+
const isSelected = buttonIsInSelection(button, selection);
|
|
274
|
+
if (this.buttonsInSelection.includes(button)) {
|
|
275
|
+
/** If the button is already in the selected list, we check if it should be unselect */
|
|
276
|
+
if (!isSelected) {
|
|
277
|
+
unselectedButtons.push(button);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (isSelected) {
|
|
281
|
+
newSelectedButtons.push(button);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** Visually Update unselected list */
|
|
285
|
+
for (const button of unselectedButtons) {
|
|
286
|
+
setVisuallySelected(button, false);
|
|
287
|
+
}
|
|
288
|
+
/** Visually Update selected list */
|
|
289
|
+
for (const button of newSelectedButtons) {
|
|
290
|
+
setVisuallySelected(button, true);
|
|
291
|
+
}
|
|
292
|
+
/** Remove unselected list */
|
|
293
|
+
this.buttonsInSelection = this.buttonsInSelection.filter((button) => {
|
|
294
|
+
return !unselectedButtons.includes(button);
|
|
295
|
+
});
|
|
296
|
+
/** Add new selected buttons */
|
|
297
|
+
this.buttonsInSelection = [
|
|
298
|
+
...this.buttonsInSelection,
|
|
299
|
+
...newSelectedButtons,
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Trigger when the user click to add the selected scans
|
|
304
|
+
*/
|
|
305
|
+
onSelectionAdd() {
|
|
306
|
+
for (const button of this.buttonsInSelection) {
|
|
307
|
+
if (!this.chosenScansOnPlan.includes(button.id)) {
|
|
308
|
+
this.onButtonScanClicked(button);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
this.onSelectionChanged({ top: 0, left: 0, width: 0, height: 0 });
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Trigger when the user click to remove the selected scans
|
|
315
|
+
*/
|
|
316
|
+
onSelectionRemove() {
|
|
317
|
+
for (const button of this.buttonsInSelection) {
|
|
318
|
+
if (this.chosenScansOnPlan.includes(button.id)) {
|
|
319
|
+
this.onButtonScanClicked(button);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
this.onSelectionChanged({ top: 0, left: 0, width: 0, height: 0 });
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Trigger when the user click to select all scans
|
|
326
|
+
*/
|
|
327
|
+
onSelectAll() {
|
|
328
|
+
this.buttonsInSelection = [...this.buttonElements];
|
|
329
|
+
for (const button of this.buttonsInSelection) {
|
|
330
|
+
setVisuallySelected(button, true);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Trigger when the user change the size of the scan points
|
|
335
|
+
* @param event
|
|
336
|
+
*/
|
|
337
|
+
onChangeScanSize(event) {
|
|
338
|
+
const factor = event.target.value;
|
|
339
|
+
for (const button of this.buttonElements) {
|
|
340
|
+
button.style.transform = `scale(${factor})`;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* When a button representing a scan is clicked
|
|
345
|
+
* @param button
|
|
346
|
+
*/
|
|
347
|
+
onButtonScanClicked(button) {
|
|
348
|
+
if (this.isSettingStartSweep) {
|
|
349
|
+
if (this.startSweepID === button.id) {
|
|
350
|
+
// we deselect the starting point
|
|
351
|
+
button.style.backgroundImage = `url("https://api.iconify.design/mdi:adjust.svg?color=green&height=17&width=17")`;
|
|
352
|
+
this.startSweepID = null;
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
button.style.backgroundImage = `url('https://api.iconify.design/ic/baseline-flag-circle.svg?color=white&width=17&height=17')`;
|
|
356
|
+
if (!this.chosenScansOnPlan.includes(button.id)) {
|
|
357
|
+
this.chosenScansOnPlan.push(button.id);
|
|
358
|
+
}
|
|
359
|
+
if (this.startSweepID) {
|
|
360
|
+
// we are changing start sweep
|
|
361
|
+
const btnChanged = this.buttonElements.find((btn) => btn.id === this.startSweepID);
|
|
362
|
+
btnChanged.style.backgroundImage = `url("https://api.iconify.design/mdi:adjust.svg?color=green&height=17&width=17")`;
|
|
363
|
+
}
|
|
364
|
+
this.startSweepID = button.id;
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (!this.chosenScansOnPlan.includes(button.id)) {
|
|
368
|
+
// add to selection
|
|
369
|
+
button.style.backgroundImage = `url("https://api.iconify.design/mdi:adjust.svg?color=green&height=17&width=17")`;
|
|
370
|
+
this.chosenScansOnPlan.push(button.id);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
// remove from selection
|
|
374
|
+
if (this.occupiedSweeps.includes(button.id) && !this.navIDsZoneEdit.includes(button.id)) {
|
|
375
|
+
// the sweep belongs to another zone => set orange
|
|
376
|
+
button.style.backgroundImage = `url("https://api.iconify.design/mdi:adjust.svg?color=orange&height=17&width=17")`;
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
button.style.backgroundImage = `url("https://api.iconify.design/mdi:close-circle-outline.svg?color=red&height=17&width=17")`;
|
|
380
|
+
}
|
|
381
|
+
const index = this.chosenScansOnPlan.indexOf(button.id);
|
|
382
|
+
this.chosenScansOnPlan.splice(index, 1);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
onSaveSelection() {
|
|
386
|
+
this.sweepsSelected.emit({ "sweeps": this.chosenScansOnPlan, "startSweepID": this.startSweepID });
|
|
387
|
+
}
|
|
388
|
+
onCancel() {
|
|
389
|
+
this.sweepsSelected.emit(null);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
SweepPlanSelectionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SweepPlanSelectionComponent, deps: [{ token: i1.ZoneService }, { token: i1.NavigationService }, { token: i1.PlanService }], target: i0.ɵɵFactoryTarget.Component });
|
|
393
|
+
SweepPlanSelectionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: { spaceID: "spaceID", chosenScansOnPlan: "chosenScansOnPlan", newZoneData: "newZoneData", occupiedSweeps: "occupiedSweeps", unavailableSweeps: "unavailableSweeps", editingAudioZone: "editingAudioZone", inputZone: "inputZone" }, outputs: { sweepsSelected: "sweepsSelected" }, usesOnChanges: true, ngImport: i0, template: "<div ngbDropdown class=\"sp-row d-inline-block\">\n <div class=\"col-sm-3\" *ngIf=\"plans\">\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\n ngbDropdownToggle>{{chosenPlan ?\n chosenPlan.name : ('Choose Plan' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button type=\"button\" ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\"\n [disabled]=\"!plan.calibration\">{{ plan.name }}\n </button>\n </div>\n </div>\n</div>\n<div class=\"sp-row\">\n <lib-selection class=\"col-md-8\" (onSelectionChanged)=\"onSelectionChanged($event)\">\n <lib-plan-legend [isAudioZone]=\"editingAudioZone\" *ngIf=\"buttonElements.length > 0\"></lib-plan-legend>\n <div class=\"selectZone\" oncontextmenu=\"return false;\">\n <div class=\"sp-row\">\n <div style=\"overflow: hidden;width:100%;\">\n <div style=\"height: 400px; width: 100%;\" id=\"planDiv\">\n </div>\n </div>\n </div>\n </div>\n </lib-selection>\n \n <div class=\"col-md-4 scanTool\" *ngIf=\"buttonElements.length > 0\">\n <div class=\"sp-row d-inline-block\">\n <h2>{{'selectTool.title' | translate}}</h2>\n <div class=\"protip\">{{'selectTool.tip' | translate}}.</div>\n </div>\n \n <div class=\"sp-row\">\n <div class=\"col-3\" style=\"padding:0px\">\n <label class=\"tool-label\" for=\"scanSize\">{{'selectTool.size' | translate}}</label>\n </div>\n <div class=\"col-9\">\n <input type=\"range\" class=\"form-range\" min=\"0.001\" max=\"5\" step=\"0.01\" value=\"1\"\n id=\"scanSize\" (input)=\"onChangeScanSize($event)\">\n </div>\n </div>\n \n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectAll()\">{{'selectTool.selectAll' | translate}}</button>\n </div>\n \n <div *ngIf=\"buttonsInSelection.length > 0\" class=\"edit-selected\">\n <span class=\"tool-label\">{{'selectTool.edit' | translate}} : </span>\n <div class=\"sp-row\">\n <button class=\"btn rounded-pill btn-primary ms-3 me-2\" (click)=\"onSelectionAdd()\">{{'selectTool.add' | translate}}</button>\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectionRemove()\">{{'selectTool.undo' | translate}}</button>\n </div>\n </div>\n\n <div class=\"sp-row\">\n {{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}} \n </div>\n <div *ngIf=\"!editingAudioZone\" class=\"sp-row\">\n <lib-radio-button label=\"{{ 'selectTool.chooseStartPoint' | translate }}\" (isCheckedEvent)=\"isSettingStartSweep=!isSettingStartSweep\"></lib-radio-button>\n </div>\n \n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSaveSelection()\">{{'selectTool.saveSelection' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'selectTool.cancelSelection' | translate}}</button>\n </div>\n </div>\n\n</div>\n \n", styles: [".sp-row{display:flex;margin-bottom:1rem}.selectZone{border-radius:6px;overflow:hidden;background-color:var(--smarterplan-secondary)}.scanTool{margin:0px 1rem}.protip{color:gray;padding:0}.tool-label{font-size:1rem}\n"], components: [{ type: i2.SelectionComponent, selector: "lib-selection", outputs: ["onSelectionChanged"] }, { type: i3.PlanLegendComponent, selector: "lib-plan-legend", inputs: ["isAudioZone"] }, { type: i4.RadioButtonComponent, selector: "lib-radio-button", inputs: ["label"], outputs: ["isCheckedEvent"] }], directives: [{ type: i5.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { type: i5.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }], pipes: { "translate": i7.TranslatePipe } });
|
|
394
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SweepPlanSelectionComponent, decorators: [{
|
|
395
|
+
type: Component,
|
|
396
|
+
args: [{ selector: 'lib-sweep-plan-selection', template: "<div ngbDropdown class=\"sp-row d-inline-block\">\n <div class=\"col-sm-3\" *ngIf=\"plans\">\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\n ngbDropdownToggle>{{chosenPlan ?\n chosenPlan.name : ('Choose Plan' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button type=\"button\" ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\"\n [disabled]=\"!plan.calibration\">{{ plan.name }}\n </button>\n </div>\n </div>\n</div>\n<div class=\"sp-row\">\n <lib-selection class=\"col-md-8\" (onSelectionChanged)=\"onSelectionChanged($event)\">\n <lib-plan-legend [isAudioZone]=\"editingAudioZone\" *ngIf=\"buttonElements.length > 0\"></lib-plan-legend>\n <div class=\"selectZone\" oncontextmenu=\"return false;\">\n <div class=\"sp-row\">\n <div style=\"overflow: hidden;width:100%;\">\n <div style=\"height: 400px; width: 100%;\" id=\"planDiv\">\n </div>\n </div>\n </div>\n </div>\n </lib-selection>\n \n <div class=\"col-md-4 scanTool\" *ngIf=\"buttonElements.length > 0\">\n <div class=\"sp-row d-inline-block\">\n <h2>{{'selectTool.title' | translate}}</h2>\n <div class=\"protip\">{{'selectTool.tip' | translate}}.</div>\n </div>\n \n <div class=\"sp-row\">\n <div class=\"col-3\" style=\"padding:0px\">\n <label class=\"tool-label\" for=\"scanSize\">{{'selectTool.size' | translate}}</label>\n </div>\n <div class=\"col-9\">\n <input type=\"range\" class=\"form-range\" min=\"0.001\" max=\"5\" step=\"0.01\" value=\"1\"\n id=\"scanSize\" (input)=\"onChangeScanSize($event)\">\n </div>\n </div>\n \n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectAll()\">{{'selectTool.selectAll' | translate}}</button>\n </div>\n \n <div *ngIf=\"buttonsInSelection.length > 0\" class=\"edit-selected\">\n <span class=\"tool-label\">{{'selectTool.edit' | translate}} : </span>\n <div class=\"sp-row\">\n <button class=\"btn rounded-pill btn-primary ms-3 me-2\" (click)=\"onSelectionAdd()\">{{'selectTool.add' | translate}}</button>\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectionRemove()\">{{'selectTool.undo' | translate}}</button>\n </div>\n </div>\n\n <div class=\"sp-row\">\n {{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}} \n </div>\n <div *ngIf=\"!editingAudioZone\" class=\"sp-row\">\n <lib-radio-button label=\"{{ 'selectTool.chooseStartPoint' | translate }}\" (isCheckedEvent)=\"isSettingStartSweep=!isSettingStartSweep\"></lib-radio-button>\n </div>\n \n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSaveSelection()\">{{'selectTool.saveSelection' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'selectTool.cancelSelection' | translate}}</button>\n </div>\n </div>\n\n</div>\n \n", styles: [".sp-row{display:flex;margin-bottom:1rem}.selectZone{border-radius:6px;overflow:hidden;background-color:var(--smarterplan-secondary)}.scanTool{margin:0px 1rem}.protip{color:gray;padding:0}.tool-label{font-size:1rem}\n"] }]
|
|
397
|
+
}], ctorParameters: function () { return [{ type: i1.ZoneService }, { type: i1.NavigationService }, { type: i1.PlanService }]; }, propDecorators: { spaceID: [{
|
|
398
|
+
type: Input
|
|
399
|
+
}], chosenScansOnPlan: [{
|
|
400
|
+
type: Input
|
|
401
|
+
}], newZoneData: [{
|
|
402
|
+
type: Input
|
|
403
|
+
}], occupiedSweeps: [{
|
|
404
|
+
type: Input
|
|
405
|
+
}], unavailableSweeps: [{
|
|
406
|
+
type: Input
|
|
407
|
+
}], editingAudioZone: [{
|
|
408
|
+
type: Input
|
|
409
|
+
}], inputZone: [{
|
|
410
|
+
type: Input
|
|
411
|
+
}], sweepsSelected: [{
|
|
412
|
+
type: Output
|
|
413
|
+
}] } });
|
|
414
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3dlZXAtcGxhbi1zZWxlY3Rpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvem9uZXMvYWRkLXpvbmUvc3dlZXAtcGxhbi1zZWxlY3Rpb24vc3dlZXAtcGxhbi1zZWxlY3Rpb24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvem9uZXMvYWRkLXpvbmUvc3dlZXAtcGxhbi1zZWxlY3Rpb24vc3dlZXAtcGxhbi1zZWxlY3Rpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsZUFBZSxFQUE2Qyx5QkFBeUIsRUFBNEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUM3TCxPQUFPLE9BQW9CLE1BQU0sU0FBUyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQWEsTUFBTSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7Ozs7O0FBTy9JLE1BQU0sT0FBTywyQkFBMkI7SUE0Q3BDLFlBQ1ksV0FBd0IsRUFDeEIsaUJBQW9DLEVBQ3BDLFdBQXdCO1FBRnhCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUF6QzNCLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztRQUsxQyxtQkFBYyxHQUFhLEVBQUUsQ0FBQztRQUU5Qixx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LDBCQUEwQjs0SkFRM0IsT0FBTztzQkFBZixLQUFLO2dCQUVHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHRyxXQUFXO3NCQUFuQixLQUFLO2dCQUtHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBR0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUdHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQWdCSSxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZ2V0Q29lZmZpY2llbnRzRm9ySW1hZ2UsIGdldE1ldGFGb3JJbWFnZSwgTmF2aWdhdGlvbiwgTmF2aWdhdGlvblNlcnZpY2UsIFBsYW4sIFpvbmUsIHNob3dTY2FuUG9pbnRzT25QbGFuSW5EaXYsIFpvbmVTZXJ2aWNlLCBQbGFuU2VydmljZSB9IGZyb20gJ0BzbWFydGVycGxhbi9uZ3gtc21hcnRlcnBsYW4tY29yZSc7XG5pbXBvcnQgcGFuem9vbSwgeyBQYW5ab29tIH0gZnJvbSAncGFuem9vbSc7XG5pbXBvcnQgeyBidXR0b25Jc0luU2VsZWN0aW9uLCBpc0luUG9seWdvbiwgUmVjdGFuZ2xlLCByb3RhdGUsIHNldFZpc3VhbGx5U2VsZWN0ZWQsIHN0eWxlQnV0dG9uLCBTd2VlcFN0YXRlIH0gZnJvbSAnLi4vLi4vLi4vLi4vaGVscGVyLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2xpYi1zd2VlcC1wbGFuLXNlbGVjdGlvbicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3N3ZWVwLXBsYW4tc2VsZWN0aW9uLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9zd2VlcC1wbGFuLXNlbGVjdGlvbi5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIFN3ZWVwUGxhblNlbGVjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBwbGFuczogUGxhbltdO1xuXG4gICAgQElucHV0KCkgc3BhY2VJRDogc3RyaW5nO1xuXG4gICAgQElucHV0KCkgY2hvc2VuU2NhbnNPblBsYW46IHN0cmluZ1tdID0gW107XG5cbiAgICAvKiogaWYgY29tbWluZyBmcm9tIEVkaXQgUGxhbiBTVkcgWm9uZSBjcmVhdGlvbiAqL1xuICAgIEBJbnB1dCgpIG5ld1pvbmVEYXRhOiBhbnk7XG5cbiAgICBuYXZJRHNab25lRWRpdDogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIHN3ZWVwcyBiZWxvbmdpbmcgdG8gYW55IGF1ZGlvIHpvbmVcbiAgICBASW5wdXQoKSBvY2N1cGllZFN3ZWVwczogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIHN3ZWVwcyB1bmF2YWlsYWJsZSAoY2Fubm90IGJlIGNob3NlbilcbiAgICBASW5wdXQoKSB1bmF2YWlsYWJsZVN3ZWVwczogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIGlmIGNob29zaW5nIHN3ZWVwcyBmb3IgYXVkaW8gem9uZVxuICAgIEBJbnB1dCgpIGVkaXRpbmdBdWRpb1pvbmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIEBJbnB1dCgpIGlucHV0Wm9uZTogWm9uZTtcblxuICAgIGNob3NlblBsYW46IFBsYW47XG5cbiAgICAvKiogcGFuWm9vbSBlbGVtZW50IGZvciBhZGRpbmcgc2NhbnMgKi9cbiAgICBwYW5ab29tOiBQYW5ab29tO1xuXG4gICAgLyoqIGRpdlBsYW4gKHVzZSBCeSBwYW5ab29tKSAqL1xuICAgIGRpdlBsYW46IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqIGFsbCBzY2FuIGJ1dHRvbnMgRWxlbWVudCAqL1xuICAgIGJ1dHRvbkVsZW1lbnRzOiBIVE1MQnV0dG9uRWxlbWVudFtdID0gW107XG5cbiAgICAvKiogU2NhbiBidXR0b25zIHRoYXQgYXJlIGluIHRoZSBjdXJyZW50IHNlbGVjdGlvbiAqL1xuICAgIGJ1dHRvbnNJblNlbGVjdGlvbjogSFRNTEJ1dHRvbkVsZW1lbnRbXSA9IFtdO1xuXG4gICAgQE91dHB1dCgpIHN3ZWVwc1NlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IHN3ZWVwczogc3RyaW5nW107IHN0YXJ0U3dlZXBJRDogc3RyaW5nOyB9PigpO1xuXG4gICAgaXNTZXR0aW5nU3RhcnRTd2VlcCA9IGZhbHNlO1xuXG4gICAgc3RhcnRTd2VlcElEOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSB6b25lU2VydmljZTogWm9uZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGlvblNlcnZpY2U6IE5hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHBsYW5TZXJ2aWNlOiBQbGFuU2VydmljZSxcbiAgICApIHsgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZ2V0UGxhbnMoKTtcbiAgICAgICAgaWYgKHRoaXMuaW5wdXRab25lKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN3ZWVwc09mSW5wdXRab25lKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcygpIHtcbiAgICAgICAgaWYgKHRoaXMuY2hvc2VuUGxhbikge1xuICAgICAgICAgICAgdGhpcy5zZXRTd2VlcHNPZklucHV0Wm9uZSgpO1xuICAgICAgICAgICAgdGhpcy5jaG9zZW5TY2Fuc09uUGxhbiA9IFtdO1xuICAgICAgICAgICAgdGhpcy5jbGVhckRpdlBsYW4oKTtcbiAgICAgICAgICAgIHRoaXMuYWRkU2NhblBvaW50cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0U3dlZXBzT2ZJbnB1dFpvbmUoKSB7XG4gICAgICAgIHRoaXMubmF2SURzWm9uZUVkaXQgPSB0aGlzLmlucHV0Wm9uZS5zd2VlcElEcztcbiAgICB9XG5cbiAgICBhc3luYyBnZXRQbGFucygpIHtcbiAgICAgICAgdGhpcy5wbGFucyA9IGF3YWl0IHRoaXMucGxhblNlcnZpY2UuZ2V0U2luZ2VkUGxhbnNGb3JTcGFjZShcbiAgICAgICAgICAgIHRoaXMuc3BhY2VJRCxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBhc3luYyBvblBsYW5DbGljayhwbGFuOiBQbGFuKSB7XG4gICAgICAgIHRoaXMuY2hvc2VuUGxhbiA9IHBsYW47XG4gICAgICAgIHRoaXMuY2xlYXJEaXZQbGFuKCk7XG4gICAgICAgIHRoaXMuYWRkU2NhblBvaW50cygpO1xuICAgIH1cblxuICAgIGFzeW5jIGFkZFNjYW5Qb2ludHMoKSB7XG4gICAgICAgIHRoaXMuZGl2UGxhbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjcGxhbkRpdlwiKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgY29uc3Qgem9uZU9mUGxhbiA9IGF3YWl0IHRoaXMuem9uZVNlcnZpY2UuZ2V0Wm9uZShcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuUGxhbi56b25lSUQsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG5hdmlnYXRpb25zID0gYXdhaXQgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXROYXZpZ2F0aW9uc0ZvclpvbmUoXG4gICAgICAgICAgICB6b25lT2ZQbGFuLFxuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5uZXdab25lRGF0YSkgYXdhaXQgdGhpcy5zZXRTY2FuQnlEcmF3KG5hdmlnYXRpb25zKTtcbiAgICAgICAgdGhpcy5idXR0b25FbGVtZW50cyA9IGF3YWl0IHNob3dTY2FuUG9pbnRzT25QbGFuSW5EaXYoXG4gICAgICAgICAgICB0aGlzLmNob3NlblBsYW4sXG4gICAgICAgICAgICB0aGlzLmRpdlBsYW4sXG4gICAgICAgICAgICBuYXZpZ2F0aW9ucyxcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuYnV0dG9uRWxlbWVudHMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnVuYXZhaWxhYmxlU3dlZXBzICYmIHRoaXMudW5hdmFpbGFibGVTd2VlcHMuaW5jbHVkZXMoZWxlbWVudC5pZCkpIHtcbiAgICAgICAgICAgICAgICBzdHlsZUJ1dHRvbihlbGVtZW50LCBTd2VlcFN0YXRlLkRJU0FCTEVEKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAodGhpcy5uYXZJRHNab25lRWRpdC5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKGVsZW1lbnQuaWQpKVxuICAgICAgICAgICAgICAgICAgICB8fCB0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGVsZW1lbnQuaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlQnV0dG9uKGVsZW1lbnQsIFN3ZWVwU3RhdGUuQURERUQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY2hvc2VuU2NhbnNPblBsYW4uaW5jbHVkZXMoZWxlbWVudC5pZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4ucHVzaChlbGVtZW50LmlkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5vY2N1cGllZFN3ZWVwcyAmJiB0aGlzLm9jY3VwaWVkU3dlZXBzLmluY2x1ZGVzKGVsZW1lbnQuaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlQnV0dG9uKGVsZW1lbnQsIFN3ZWVwU3RhdGUuT0NDVVBJRUQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlQnV0dG9uKGVsZW1lbnQsIFN3ZWVwU3RhdGUuUkVNT1ZFRCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vc3RhcnQgcG9pbnQgc2hvdWxkIGJlIGxhc3QgY29uZGl0aW9uIFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlucHV0Wm9uZSAmJiB0aGlzLmlucHV0Wm9uZS5zdGFydFN3ZWVwSUQgPT09IGVsZW1lbnQuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJzZXR0aW5nIHN0YXJ0IHBvaW50XCIpO1xuICAgICAgICAgICAgICAgICAgICBzdHlsZUJ1dHRvbihlbGVtZW50LCBTd2VlcFN0YXRlLlNUQVJUUE9JTlQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZXZlbnQpID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25CdXR0b25TY2FuQ2xpY2tlZChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYW5ab29tID0gcGFuem9vbSh0aGlzLmRpdlBsYW4sIHtcbiAgICAgICAgICAgIGJvdW5kczogdHJ1ZSxcbiAgICAgICAgICAgIGJvdW5kc1BhZGRpbmc6IDAsXG4gICAgICAgICAgICBtYXhab29tOiAzLjUsXG4gICAgICAgICAgICBiZWZvcmVNb3VzZURvd24oZTogTW91c2VFdmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIGUuYnV0dG9uID09PSAyXG4gICAgICAgICAgICAgICAgKTsgLyoqIElnbm9yZSBldmVudCBmb3IgcmlnaHQgY2xpY2sgKHVzZSBmb3Igc2VsZWN0aW5nKSAqL1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqIEZ1bmN0aW9uIGlmIHdlIGFyZSBjb21pbmcgZm9yIHN2ZyBlZGl0b3Igd29ya2Zsb3cgKi9cbiAgICBzZXRTY2FuQnlEcmF3KG5hdmlnYXRpb25zOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMubmV3Wm9uZURhdGEud2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLm5ld1pvbmVEYXRhLmhlaWdodCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBpbWcgPSBhd2FpdCBnZXRNZXRhRm9ySW1hZ2UodGhpcy5jaG9zZW5QbGFuLmZpbGVwYXRoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgY29lZmZYLCBjb2VmZlkgfSA9IGdldENvZWZmaWNpZW50c0ZvckltYWdlKGltZywgcmVjdCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGRyYXcgPSB0aGlzLm5ld1pvbmVEYXRhLmVsZW1lbnRzO1xuXG4gICAgICAgICAgICBkcmF3Lm1hcChhc3luYyAoZWxlbWVudDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlbGVtZW50Lm5vZGVOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZWN0XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNldFNjYW5JblJlY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZWZmWCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZWxsaXBzZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRTY2FuSW5DaXJjbGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZWZmWCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicGF0aFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRTY2FuSW5Qb2x5Z29uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZlgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29lZmZZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBzZXRTY2FuSW5SZWN0KGltZzogYW55LCBjb2VmZlg6IG51bWJlciwgY29lZmZZOiBudW1iZXIsXG4gICAgICAgIGVsZW1lbnQ6IHsgYW5nbGU6IGFueTsgY3g6IGFueTsgY3k6IGFueTsgeDogbnVtYmVyOyB3aWR0aDogYW55OyB5OiBudW1iZXI7IGhlaWdodDogYW55OyB9LCBuYXZpZ2F0aW9uczogYW55W10pIHtcbiAgICAgICAgY29uc3QgY2FsaWJyYWdlID0gSlNPTi5wYXJzZSh0aGlzLmNob3NlblBsYW4uY2FsaWJyYXRpb24pO1xuICAgICAgICBuYXZpZ2F0aW9ucy5tYXAoKG5hdmlnYXRpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uc09uUGxhbiA9IG5hdmlnYXRpb24ucG9zaXRpb25PblBsYW4ubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICAgICAgICBKU09OLnBhcnNlKGVudHJ5KSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbk9uUGxhbiA9IHBvc2l0aW9uc09uUGxhbi5maW5kKFxuICAgICAgICAgICAgICAgIChkYXRhKSA9PiBkYXRhLnBsYW5JRCA9PT0gdGhpcy5jaG9zZW5QbGFuLmlkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbk9uUGxhbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWxXaWR0aCA9IGltZy53aWR0aCAvIGNvZWZmWDtcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsSGVpZ2h0ID0gaW1nLmhlaWdodCAvIGNvZWZmWTtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXZZID0gKHBvc2l0aW9uT25QbGFuLnkgKiByZWFsSGVpZ2h0KSAvIGNhbGlicmFnZS5pbWdIZWlnaHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF2WCA9IChwb3NpdGlvbk9uUGxhbi54ICogcmVhbFdpZHRoKSAvIGNhbGlicmFnZS5pbWdXaWR0aDtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIG5hdlggPiBlbGVtZW50LnggJiZcbiAgICAgICAgICAgICAgICAgICAgbmF2WCA8IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggJiZcbiAgICAgICAgICAgICAgICAgICAgbmF2WSA+IGVsZW1lbnQueSAmJlxuICAgICAgICAgICAgICAgICAgICBuYXZZIDwgZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgJiZcbiAgICAgICAgICAgICAgICAgICAgIXRoaXMubmF2SURzWm9uZUVkaXQuaW5jbHVkZXMobmF2aWdhdGlvbi5pZClcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXZJRHNab25lRWRpdC5wdXNoKG5hdmlnYXRpb24uaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gb2xkIGNhbGlicmF0aW9uOlxuICAgICAgICAgICAgLy8gY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdmlnYXRpb24ucG9zaXRpb24pO1xuICAgICAgICAgICAgLy8gbGV0IG5hdlggPSAoY2FsaWJyYWdlLm9mZnNldFggKyBwb3NpdGlvbi54ICogY2FsaWJyYWdlLngpIC8gY29lZmZYO1xuICAgICAgICAgICAgLy8gbGV0IG5hdlkgPSAoY2FsaWJyYWdlLm9mZnNldFkgKyBwb3NpdGlvbi56ICogY2FsaWJyYWdlLnkpIC8gY29lZmZZO1xuICAgICAgICAgICAgLy8gaWYgKGVsZW1lbnQuYW5nbGUpIHtcbiAgICAgICAgICAgIC8vICAgICBjb25zdCByb3RhdGVQb3MgPSByb3RhdGUoXG4gICAgICAgICAgICAvLyAgICAgICAgIHsgeDogbmF2WCwgeTogbmF2WSB9LFxuICAgICAgICAgICAgLy8gICAgICAgICB7IHg6IGVsZW1lbnQuY3gsIHk6IGVsZW1lbnQuY3kgfSxcbiAgICAgICAgICAgIC8vICAgICAgICAgZWxlbWVudC5hbmdsZSxcbiAgICAgICAgICAgIC8vICAgICApO1xuICAgICAgICAgICAgLy8gICAgIG5hdlggPSByb3RhdGVQb3MueDtcbiAgICAgICAgICAgIC8vICAgICBuYXZZID0gcm90YXRlUG9zLnk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFRPRE8gY2FsY3VsZXIgbGEgcm90YXRpb24gZHUgcmVjdGFuZ2xlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIC8vIGlmIChcbiAgICAgICAgICAgIC8vICAgICBuYXZYID4gZWxlbWVudC54ICYmXG4gICAgICAgICAgICAvLyAgICAgbmF2WCA8IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggJiZcbiAgICAgICAgICAgIC8vICAgICBuYXZZID4gZWxlbWVudC55ICYmXG4gICAgICAgICAgICAvLyAgICAgbmF2WSA8IGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0ICYmXG4gICAgICAgICAgICAvLyAgICAgIXRoaXMubmF2SURzWm9uZUVkaXQuaW5jbHVkZXMobmF2aWdhdGlvbi5pZClcbiAgICAgICAgICAgIC8vICkge1xuICAgICAgICAgICAgLy8gICAgIHRoaXMubmF2SURzWm9uZUVkaXQucHVzaChuYXZpZ2F0aW9uLmlkKTtcbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgfSk7XG4gICAgfSAvLyBFT1xuXG4gICAgYXN5bmMgc2V0U2NhbkluQ2lyY2xlKGltZzogYW55LCBjb2VmZlg6IG51bWJlciwgY29lZmZZOiBudW1iZXIsXG4gICAgICAgIGVsZW1lbnQ6IHsgYW5nbGU6IGFueTsgY3g6IG51bWJlcjsgY3k6IG51bWJlcjsgcng6IG51bWJlcjsgcnk6IG51bWJlcjsgfSwgbmF2aWdhdGlvbnM6IE5hdmlnYXRpb25bXSkge1xuICAgICAgICBjb25zdCBjYWxpYnJhZ2UgPSBKU09OLnBhcnNlKHRoaXMuY2hvc2VuUGxhbi5jYWxpYnJhdGlvbik7XG4gICAgICAgIG5hdmlnYXRpb25zLm1hcChuYXZpZ2F0aW9uID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uc09uUGxhbiA9IG5hdmlnYXRpb24ucG9zaXRpb25PblBsYW4ubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICAgICAgICBKU09OLnBhcnNlKGVudHJ5KSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbk9uUGxhbiA9IHBvc2l0aW9uc09uUGxhbi5maW5kKFxuICAgICAgICAgICAgICAgIChkYXRhKSA9PiBkYXRhLnBsYW5JRCA9PT0gdGhpcy5jaG9zZW5QbGFuLmlkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbk9uUGxhbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWxXaWR0aCA9IGltZy53aWR0aCAvIGNvZWZmWDtcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsSGVpZ2h0ID0gaW1nLmhlaWdodCAvIGNvZWZmWTtcbiAgICAgICAgICAgICAgICBsZXQgbmF2WSA9IChwb3NpdGlvbk9uUGxhbi55ICogcmVhbEhlaWdodCkgLyBjYWxpYnJhZ2UuaW1nSGVpZ2h0O1xuICAgICAgICAgICAgICAgIGxldCBuYXZYID0gKHBvc2l0aW9uT25QbGFuLnggKiByZWFsV2lkdGgpIC8gY2FsaWJyYWdlLmltZ1dpZHRoO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJvdGF0ZVBvcyA9IHJvdGF0ZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgeDogbmF2WCwgeTogbmF2WSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyB4OiBlbGVtZW50LmN4LCB5OiBlbGVtZW50LmN5IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFuZ2xlLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBuYXZYID0gcm90YXRlUG9zLng7XG4gICAgICAgICAgICAgICAgICAgIG5hdlkgPSByb3RhdGVQb3MueTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVggPVxuICAgICAgICAgICAgICAgICAgICBNYXRoLnBvdyhuYXZYIC0gZWxlbWVudC5jeCwgMikgLyBNYXRoLnBvdyhlbGVtZW50LnJ4LCAyKTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVkgPVxuICAgICAgICAgICAgICAgICAgICBNYXRoLnBvdyhuYXZZIC0gZWxlbWVudC5jeSwgMikgLyBNYXRoLnBvdyhlbGVtZW50LnJ5LCAyKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB2YWx1ZVggKyB2YWx1ZVk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA8PSAxICYmICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubmF2SURzWm9uZUVkaXQucHVzaChuYXZpZ2F0aW9uLmlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG9sZCBjYWxpYnJhdGlvblxuICAgICAgICAgICAgLy8gY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdmlnYXRpb24ucG9zaXRpb24pO1xuICAgICAgICAgICAgLy8gbGV0IG5hdlggPSAoY2FsaWJyYWdlLm9mZnNldFggKyBwb3NpdGlvbi54ICogY2FsaWJyYWdlLngpIC8gY29lZmZYO1xuICAgICAgICAgICAgLy8gbGV0IG5hdlkgPSAoY2FsaWJyYWdlLm9mZnNldFkgKyBwb3NpdGlvbi56ICogY2FsaWJyYWdlLnkpIC8gY29lZmZZO1xuICAgICAgICAgICAgLy8gaWYgKGVsZW1lbnQuYW5nbGUpIHtcbiAgICAgICAgICAgIC8vICAgICBjb25zdCByb3RhdGVQb3MgPSByb3RhdGUoXG4gICAgICAgICAgICAvLyAgICAgICAgIHsgeDogbmF2WCwgeTogbmF2WSB9LFxuICAgICAgICAgICAgLy8gICAgICAgICB7IHg6IGVsZW1lbnQuY3gsIHk6IGVsZW1lbnQuY3kgfSxcbiAgICAgICAgICAgIC8vICAgICAgICAgZWxlbWVudC5hbmdsZSxcbiAgICAgICAgICAgIC8vICAgICApO1xuICAgICAgICAgICAgLy8gICAgIG5hdlggPSByb3RhdGVQb3MueDtcbiAgICAgICAgICAgIC8vICAgICBuYXZZID0gcm90YXRlUG9zLnk7XG4gICAgICAgICAgICAvLyB9XG5cbiAgICAgICAgICAgIC8vIGNvbnN0IHZhbHVlWCA9XG4gICAgICAgICAgICAvLyAgICAgTWF0aC5wb3cobmF2WCAtIGVsZW1lbnQuY3gsIDIpIC8gTWF0aC5wb3coZWxlbWVudC5yeCwgMik7XG4gICAgICAgICAgICAvLyBjb25zdCB2YWx1ZVkgPVxuICAgICAgICAgICAgLy8gICAgIE1hdGgucG93KG5hdlkgLSBlbGVtZW50LmN5LCAyKSAvIE1hdGgucG93KGVsZW1lbnQucnksIDIpO1xuICAgICAgICAgICAgLy8gY29uc3QgcmVzdWx0ID0gdmFsdWVYICsgdmFsdWVZO1xuICAgICAgICAgICAgLy8gaWYgKHJlc3VsdCA8PSAxICYmICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpKSB7XG4gICAgICAgICAgICAvLyAgICAgdGhpcy5uYXZJRHNab25lRWRpdC5wdXNoKG5hdmlnYXRpb24uaWQpO1xuICAgICAgICAgICAgLy8gfVxuICAgICAgICB9KTtcbiAgICB9IC8vIEVPXG5cbiAgICBhc3luYyBzZXRTY2FuSW5Qb2x5Z29uKGltZzogYW55LCBjb2VmZlg6IG51bWJlciwgY29lZmZZOiBudW1iZXIsIGVsZW1lbnQ6IHsgc2VnTGlzdDogYW55OyB9LCBuYXZpZ2F0aW9uczogYW55W10pIHtcbiAgICAgICAgY29uc3QgY2FsaWJyYWdlID0gSlNPTi5wYXJzZSh0aGlzLmNob3NlblBsYW4uY2FsaWJyYXRpb24pO1xuICAgICAgICBuYXZpZ2F0aW9ucy5tYXAoYXN5bmMgKG5hdmlnYXRpb24pID0+IHtcblxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25zT25QbGFuID0gbmF2aWdhdGlvbi5wb3NpdGlvbk9uUGxhbi5tYXAoKGVudHJ5KSA9PlxuICAgICAgICAgICAgICAgIEpTT04ucGFyc2UoZW50cnkpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uT25QbGFuID0gcG9zaXRpb25zT25QbGFuLmZpbmQoXG4gICAgICAgICAgICAgICAgKGRhdGEpID0+IGRhdGEucGxhbklEID09PSB0aGlzLmNob3NlblBsYW4uaWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHBvc2l0aW9uT25QbGFuKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVhbFdpZHRoID0gaW1nLndpZHRoIC8gY29lZmZYO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWxIZWlnaHQgPSBpbWcuaGVpZ2h0IC8gY29lZmZZO1xuICAgICAgICAgICAgICAgIGxldCBuYXZZID0gKHBvc2l0aW9uT25QbGFuLnkgKiByZWFsSGVpZ2h0KSAvIGNhbGlicmFnZS5pbWdIZWlnaHQ7XG4gICAgICAgICAgICAgICAgbGV0IG5hdlggPSAocG9zaXRpb25PblBsYW4ueCAqIHJlYWxXaWR0aCkgLyBjYWxpYnJhZ2UuaW1nV2lkdGg7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiBuYXZYLFxuICAgICAgICAgICAgICAgICAgICB5OiBuYXZZLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBpc0luUG9seWdvbihwLCBlbGVtZW50LnNlZ0xpc3QpICYmXG4gICAgICAgICAgICAgICAgICAgICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubmF2SURzWm9uZUVkaXQucHVzaChuYXZpZ2F0aW9uLmlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG9sZCBjYWxpYnJhdGlvblxuICAgICAgICAgICAgLy8gY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdmlnYXRpb24ucG9zaXRpb24pO1xuICAgICAgICAgICAgLy8gY29uc3QgcCA9IHtcbiAgICAgICAgICAgIC8vICAgICB4OiAoY2FsaWJyYWdlLm9mZnNldFggKyBwb3NpdGlvbi54ICogY2FsaWJyYWdlLngpIC8gY29lZmZYLFxuICAgICAgICAgICAgLy8gICAgIHk6IChjYWxpYnJhZ2Uub2Zmc2V0WSArIHBvc2l0aW9uLnogKiBjYWxpYnJhZ2UueSkgLyBjb2VmZlksXG4gICAgICAgICAgICAvLyB9O1xuICAgICAgICAgICAgLy8gaWYgKGVsZW1lbnQuYW5nbGUpIHtcbiAgICAgICAgICAgIC8vICAgICBwID0gdGhpcy5yb3RhdGUoXG4gICAgICAgICAgICAvLyAgICAgICAgIHAsXG4gICAgICAgICAgICAvLyAgICAgICAgIHsgeDogZWxlbWVudC5jeCwgeTogZWxlbWVudC5jeSB9LFxuICAgICAgICAgICAgLy8gICAgICAgICBlbGVtZW50LmFuZ2xlLFxuICAgICAgICAgICAgLy8gICAgICk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAvLyBpZiAoXG4gICAgICAgICAgICAvLyAgICAgaXNJblBvbHlnb24ocCwgZWxlbWVudC5zZWdMaXN0KSAmJlxuICAgICAgICAgICAgLy8gICAgICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKG5hdmlnYXRpb24uaWQpXG4gICAgICAgICAgICAvLyApIHtcbiAgICAgICAgICAgIC8vICAgICB0aGlzLm5hdklEc1pvbmVFZGl0LnB1c2gobmF2aWdhdGlvbi5pZCk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNsZWFyRGl2UGxhbigpIHtcbiAgICAgICAgaWYgKHRoaXMuZGl2UGxhbikgdGhpcy5kaXZQbGFuLmlubmVySFRNTCA9IFwiXCI7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGVhY2ggYnkgdGhlIHNlbGVjdGlvbkNvbXBvbmVudCB3aGVuIHNlbGVjdGlvbiBjaGFuZ2VcbiAgICAgKiBVcGRhdGUgdGhlIGN1cnJlbnQgc2VsZWN0ZWQgc2NhbiBidXR0b25zXG4gICAgICogQHBhcmFtIHNlbGVjdGlvbiBuZXcgc2VsZWN0aW9uXG4gICAgICovXG4gICAgb25TZWxlY3Rpb25DaGFuZ2VkKHNlbGVjdGlvbjogUmVjdGFuZ2xlKSB7XG4gICAgICAgIGNvbnN0IHVuc2VsZWN0ZWRCdXR0b25zOiBIVE1MQnV0dG9uRWxlbWVudFtdID0gW107XG4gICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkQnV0dG9ucyA9IFtdO1xuXG4gICAgICAgIC8qKiBGb3IgZWFjaCBidXR0b24sIGRlY2lkZSB3aGV0aGVyIHdpbGwgYmUgYWRkIHRvIHNlbGVjdGVkIGxpc3Qgb3IgdW5zZWxlY3RlZCBsaXN0ICovXG4gICAgICAgIGZvciAoY29uc3QgYnV0dG9uIG9mIHRoaXMuYnV0dG9uRWxlbWVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSBidXR0b25Jc0luU2VsZWN0aW9uKGJ1dHRvbiwgc2VsZWN0aW9uKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1dHRvbnNJblNlbGVjdGlvbi5pbmNsdWRlcyhidXR0b24pKSB7XG4gICAgICAgICAgICAgICAgLyoqIElmIHRoZSBidXR0b24gaXMgYWxyZWFkeSBpbiB0aGUgc2VsZWN0ZWQgbGlzdCwgd2UgY2hlY2sgaWYgaXQgc2hvdWxkIGJlIHVuc2VsZWN0ICovXG4gICAgICAgICAgICAgICAgaWYgKCFpc1NlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuc2VsZWN0ZWRCdXR0b25zLnB1c2goYnV0dG9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBuZXdTZWxlY3RlZEJ1dHRvbnMucHVzaChidXR0b24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqIFZpc3VhbGx5IFVwZGF0ZSB1bnNlbGVjdGVkIGxpc3QgKi9cbiAgICAgICAgZm9yIChjb25zdCBidXR0b24gb2YgdW5zZWxlY3RlZEJ1dHRvbnMpIHtcbiAgICAgICAgICAgIHNldFZpc3VhbGx5U2VsZWN0ZWQoYnV0dG9uLCBmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogVmlzdWFsbHkgVXBkYXRlIHNlbGVjdGVkIGxpc3QgKi9cbiAgICAgICAgZm9yIChjb25zdCBidXR0b24gb2YgbmV3U2VsZWN0ZWRCdXR0b25zKSB7XG4gICAgICAgICAgICBzZXRWaXN1YWxseVNlbGVjdGVkKGJ1dHRvbiwgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogUmVtb3ZlICB1bnNlbGVjdGVkIGxpc3QgKi9cbiAgICAgICAgdGhpcy5idXR0b25zSW5TZWxlY3Rpb24gPSB0aGlzLmJ1dHRvbnNJblNlbGVjdGlvbi5maWx0ZXIoKGJ1dHRvbikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICF1bnNlbGVjdGVkQnV0dG9ucy5pbmNsdWRlcyhidXR0b24pO1xuICAgICAgICB9KTtcbiAgICAgICAgLyoqIEFkZCBuZXcgc2VsZWN0ZWQgYnV0dG9ucyAqL1xuICAgICAgICB0aGlzLmJ1dHRvbnNJblNlbGVjdGlvbiA9IFtcbiAgICAgICAgICAgIC4uLnRoaXMuYnV0dG9uc0luU2VsZWN0aW9uLFxuICAgICAgICAgICAgLi4ubmV3U2VsZWN0ZWRCdXR0b25zLFxuICAgICAgICBdO1xuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHdoZW4gdGhlIHVzZXIgY2xpY2sgdG8gYWRkIHRoZSBzZWxlY3RlZCBzY2Fuc1xuICAgICAqL1xuICAgIG9uU2VsZWN0aW9uQWRkKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGJ1dHRvbiBvZiB0aGlzLmJ1dHRvbnNJblNlbGVjdGlvbikge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uQnV0dG9uU2NhbkNsaWNrZWQoYnV0dG9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkKHsgdG9wOiAwLCBsZWZ0OiAwLCB3aWR0aDogMCwgaGVpZ2h0OiAwIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgd2hlbiB0aGUgdXNlciBjbGljayB0byByZW1vdmUgdGhlIHNlbGVjdGVkIHNjYW5zXG4gICAgICovXG4gICAgb25TZWxlY3Rpb25SZW1vdmUoKSB7XG4gICAgICAgIGZvciAoY29uc3QgYnV0dG9uIG9mIHRoaXMuYnV0dG9uc0luU2VsZWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jaG9zZW5TY2Fuc09uUGxhbi5pbmNsdWRlcyhidXR0b24uaWQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkJ1dHRvblNjYW5DbGlja2VkKGJ1dHRvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQoeyB0b3A6IDAsIGxlZnQ6IDAsIHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB3aGVuIHRoZSB1c2VyIGNsaWNrIHRvIHNlbGVjdCBhbGwgc2NhbnNcbiAgICAgKi9cbiAgICBvblNlbGVjdEFsbCgpIHtcbiAgICAgICAgdGhpcy5idXR0b25zSW5TZWxlY3Rpb24gPSBbLi4udGhpcy5idXR0b25FbGVtZW50c107XG4gICAgICAgIGZvciAoY29uc3QgYnV0dG9uIG9mIHRoaXMuYnV0dG9uc0luU2VsZWN0aW9uKSB7XG4gICAgICAgICAgICBzZXRWaXN1YWxseVNlbGVjdGVkKGJ1dHRvbiwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHdoZW4gdGhlIHVzZXIgY2hhbmdlIHRoZSBzaXplIG9mIHRoZSBzY2FuIHBvaW50c1xuICAgICAqIEBwYXJhbSBldmVudFxuICAgICAqL1xuICAgIG9uQ2hhbmdlU2NhblNpemUoZXZlbnQ6IGFueSkge1xuICAgICAgICBjb25zdCBmYWN0b3IgPSBldmVudC50YXJnZXQudmFsdWU7XG5cbiAgICAgICAgZm9yIChjb25zdCBidXR0b24gb2YgdGhpcy5idXR0b25FbGVtZW50cykge1xuICAgICAgICAgICAgYnV0dG9uLnN0eWxlLnRyYW5zZm9ybSA9IGBzY2FsZSgke2ZhY3Rvcn0pYDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZW4gYSBidXR0b24gcmVwcmVzZW50aW5nIGEgc2NhbiBpcyBjbGlja2VkXG4gICAgICogQHBhcmFtIGJ1dHRvblxuICAgICAqL1xuICAgIG9uQnV0dG9uU2NhbkNsaWNrZWQoYnV0dG9uOiBIVE1MRWxlbWVudCkge1xuICAgICAgICBpZiAodGhpcy5pc1NldHRpbmdTdGFydFN3ZWVwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGFydFN3ZWVwSUQgPT09IGJ1dHRvbi5pZCkge1xuICAgICAgICAgICAgICAgIC8vIHdlIGRlc2VsZWN0IHRoZSBzdGFydGluZyBwb2ludFxuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKFwiaHR0cHM6Ly9hcGkuaWNvbmlmeS5kZXNpZ24vbWRpOmFkanVzdC5zdmc/Y29sb3I9Z3JlZW4maGVpZ2h0PTE3JndpZHRoPTE3XCIpYDtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0U3dlZXBJRCA9IG51bGw7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IGB1cmwoJ2h0dHBzOi8vYXBpLmljb25pZnkuZGVzaWduL2ljL2Jhc2VsaW5lLWZsYWctY2lyY2xlLnN2Zz9jb2xvcj13aGl0ZSZ3aWR0aD0xNyZoZWlnaHQ9MTcnKWA7XG4gICAgICAgICAgICBpZiAoIXRoaXMuY2hvc2VuU2NhbnNPblBsYW4uaW5jbHVkZXMoYnV0dG9uLmlkKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4ucHVzaChidXR0b24uaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhcnRTd2VlcElEKSB7XG4gICAgICAgICAgICAgICAgLy8gd2UgYXJlIGNoYW5naW5nIHN0YXJ0IHN3ZWVwXG4gICAgICAgICAgICAgICAgY29uc3QgYnRuQ2hhbmdlZCA9IHRoaXMuYnV0dG9uRWxlbWVudHMuZmluZCgoYnRuKSA9PiBidG4uaWQgPT09IHRoaXMuc3RhcnRTd2VlcElEKTtcbiAgICAgICAgICAgICAgICBidG5DaGFuZ2VkLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IGB1cmwoXCJodHRwczovL2FwaS5pY29uaWZ5LmRlc2lnbi9tZGk6YWRqdXN0LnN2Zz9jb2xvcj1ncmVlbiZoZWlnaHQ9MTcmd2lkdGg9MTdcIilgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdGFydFN3ZWVwSUQgPSBidXR0b24uaWQ7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmNob3NlblNjYW5zT25QbGFuLmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcbiAgICAgICAgICAgIC8vIGFkZCB0byBzZWxlY3Rpb25cbiAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKFwiaHR0cHM6Ly9hcGkuaWNvbmlmeS5kZXNpZ24vbWRpOmFkanVzdC5zdmc/Y29sb3I9Z3JlZW4maGVpZ2h0PTE3JndpZHRoPTE3XCIpYDtcbiAgICAgICAgICAgIHRoaXMuY2hvc2VuU2NhbnNPblBsYW4ucHVzaChidXR0b24uaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGZyb20gc2VsZWN0aW9uXG4gICAgICAgICAgICBpZiAodGhpcy5vY2N1cGllZFN3ZWVwcy5pbmNsdWRlcyhidXR0b24uaWQpICYmICF0aGlzLm5hdklEc1pvbmVFZGl0LmluY2x1ZGVzKGJ1dHRvbi5pZCkpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGUgc3dlZXAgYmVsb25ncyB0byBhbm90aGVyIHpvbmUgPT4gc2V0IG9yYW5nZVxuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKFwiaHR0cHM6Ly9hcGkuaWNvbmlmeS5kZXNpZ24vbWRpOmFkanVzdC5zdmc/Y29sb3I9b3JhbmdlJmhlaWdodD0xNyZ3aWR0aD0xN1wiKWA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKFwiaHR0cHM6Ly9hcGkuaWNvbmlmeS5kZXNpZ24vbWRpOmNsb3NlLWNpcmNsZS1vdXRsaW5lLnN2Zz9jb2xvcj1yZWQmaGVpZ2h0PTE3JndpZHRoPTE3XCIpYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5jaG9zZW5TY2Fuc09uUGxhbi5pbmRleE9mKGJ1dHRvbi5pZCk7XG4gICAgICAgICAgICB0aGlzLmNob3NlblNjYW5zT25QbGFuLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblNhdmVTZWxlY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc3dlZXBzU2VsZWN0ZWQuZW1pdCh7IFwic3dlZXBzXCI6IHRoaXMuY2hvc2VuU2NhbnNPblBsYW4sIFwic3RhcnRTd2VlcElEXCI6IHRoaXMuc3RhcnRTd2VlcElEIH0pO1xuICAgIH1cblxuICAgIG9uQ2FuY2VsKCkge1xuICAgICAgICB0aGlzLnN3ZWVwc1NlbGVjdGVkLmVtaXQobnVsbCk7XG4gICAgfVxufVxuIiwiPGRpdiBuZ2JEcm9wZG93biBjbGFzcz1cInNwLXJvdyBkLWlubGluZS1ibG9ja1wiPlxuICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tM1wiICpuZ0lmPVwicGxhbnNcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1sYWJlbC1maWxlIHJvdW5kZWQtcGlsbFwiIGlkPVwiZHJvcGRvd25CYXNpYzFcIlxuICAgICAgICAgICAgICAgIG5nYkRyb3Bkb3duVG9nZ2xlPnt7Y2hvc2VuUGxhbiA/XG4gICAgICAgICAgICAgICAgY2hvc2VuUGxhbi5uYW1lIDogKCdDaG9vc2UgUGxhbicgfCB0cmFuc2xhdGUpIH19PC9idXR0b24+XG4gICAgICAgICAgICA8ZGl2IG5nYkRyb3Bkb3duTWVudSBhcmlhLWxhYmVsbGVkYnk9XCJkcm9wZG93bkJhc2ljMVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG5nYkRyb3Bkb3duSXRlbSAqbmdGb3I9XCJsZXQgcGxhbiBvZiBwbGFuc1wiIChjbGljayk9XCJvblBsYW5DbGljayhwbGFuKVwiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhcGxhbi5jYWxpYnJhdGlvblwiPnt7IHBsYW4ubmFtZSB9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cbjxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cbiAgICA8bGliLXNlbGVjdGlvbiBjbGFzcz1cImNvbC1tZC04XCIgKG9uU2VsZWN0aW9uQ2hhbmdlZCk9XCJvblNlbGVjdGlvbkNoYW5nZWQoJGV2ZW50KVwiPlxuICAgICAgICA8bGliLXBsYW4tbGVnZW5kIFtpc0F1ZGlvWm9uZV09XCJlZGl0aW5nQXVkaW9ab25lXCIgKm5nSWY9XCJidXR0b25FbGVtZW50cy5sZW5ndGggPiAwXCI+PC9saWItcGxhbi1sZWdlbmQ+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3Rab25lXCIgb25jb250ZXh0bWVudT1cInJldHVybiBmYWxzZTtcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwib3ZlcmZsb3c6IGhpZGRlbjt3aWR0aDoxMDAlO1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiaGVpZ2h0OiA0MDBweDsgd2lkdGg6IDEwMCU7XCIgaWQ9XCJwbGFuRGl2XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvbGliLXNlbGVjdGlvbj5cbiAgICBcbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgc2NhblRvb2xcIiAqbmdJZj1cImJ1dHRvbkVsZW1lbnRzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNwLXJvdyBkLWlubGluZS1ibG9ja1wiPlxuICAgICAgICAgICAgPGgyPnt7J3NlbGVjdFRvb2wudGl0bGUnIHwgdHJhbnNsYXRlfX08L2gyPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb3RpcFwiPnt7J3NlbGVjdFRvb2wudGlwJyB8IHRyYW5zbGF0ZX19LjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICBcbiAgICAgICAgPGRpdiBjbGFzcz1cInNwLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC0zXCIgc3R5bGU9XCJwYWRkaW5nOjBweFwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvb2wtbGFiZWxcIiBmb3I9XCJzY2FuU2l6ZVwiPnt7J3NlbGVjdFRvb2wuc2l6ZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtOVwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFuZ2VcIiBjbGFzcz1cImZvcm0tcmFuZ2VcIiBtaW49XCIwLjAwMVwiIG1heD1cIjVcIiBzdGVwPVwiMC4wMVwiIHZhbHVlPVwiMVwiXG4gICAgICAgICAgICAgICAgICAgIGlkPVwic2NhblNpemVcIiAoaW5wdXQpPVwib25DaGFuZ2VTY2FuU2l6ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcC1yb3dcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uU2VsZWN0QWxsKClcIj57eydzZWxlY3RUb29sLnNlbGVjdEFsbCcgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICBcbiAgICAgICAgPGRpdiAqbmdJZj1cImJ1dHRvbnNJblNlbGVjdGlvbi5sZW5ndGggPiAwXCIgY2xhc3M9XCJlZGl0LXNlbGVjdGVkXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2wtbGFiZWxcIj57eydzZWxlY3RUb29sLmVkaXQnIHwgdHJhbnNsYXRlfX0gOiA8L3NwYW4+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Atcm93XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biByb3VuZGVkLXBpbGwgYnRuLXByaW1hcnkgbXMtMyBtZS0yXCIgKGNsaWNrKT1cIm9uU2VsZWN0aW9uQWRkKClcIj57eydzZWxlY3RUb29sLmFkZCcgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uU2VsZWN0aW9uUmVtb3ZlKClcIj57eydzZWxlY3RUb29sLnVuZG8nIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwic3Atcm93XCI+XG4gICAgICAgICAgICB7eyBjaG9zZW5TY2Fuc09uUGxhbi5sZW5ndGggfX0ge3snc2NhbiBwb2ludHMgY2hvc2VuJyB8IHRyYW5zbGF0ZX19ICAgICAgICAgXG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWVkaXRpbmdBdWRpb1pvbmVcIiBjbGFzcz1cInNwLXJvd1wiPlxuICAgICAgICAgICAgPGxpYi1yYWRpby1idXR0b24gIGxhYmVsPVwie3sgJ3NlbGVjdFRvb2wuY2hvb3NlU3RhcnRQb2ludCcgIHwgdHJhbnNsYXRlIH19XCIgKGlzQ2hlY2tlZEV2ZW50KT1cImlzU2V0dGluZ1N0YXJ0U3dlZXA9IWlzU2V0dGluZ1N0YXJ0U3dlZXBcIj48L2xpYi1yYWRpby1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgICAgPGRpdiBjbGFzcz1cInNwLXJvd1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25TYXZlU2VsZWN0aW9uKClcIj57eydzZWxlY3RUb29sLnNhdmVTZWxlY3Rpb24nIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25DYW5jZWwoKVwiPnt7J3NlbGVjdFRvb2wuY2FuY2VsU2VsZWN0aW9uJyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L2Rpdj5cbiAgIFxuIl19
|