@covalent/guided-tour 4.0.0-alpha.0 → 4.0.0-beta.1
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/_guided-tour-theme.scss +4 -3
- package/_guided-tour.scss +17 -2
- package/covalent-guided-tour.d.ts +1 -0
- package/esm2020/covalent-guided-tour.mjs +5 -0
- package/esm2020/guided-tour.module.mjs +20 -0
- package/esm2020/guided-tour.service.mjs +155 -0
- package/esm2020/guided.tour.mjs +414 -0
- package/esm2020/index.mjs +2 -0
- package/esm2020/public-api.mjs +4 -0
- package/fesm2015/{covalent-guided-tour.js → covalent-guided-tour.mjs} +123 -590
- package/fesm2015/covalent-guided-tour.mjs.map +1 -0
- package/fesm2020/covalent-guided-tour.mjs +588 -0
- package/fesm2020/covalent-guided-tour.mjs.map +1 -0
- package/guided-tour.module.d.ts +5 -0
- package/guided-tour.service.d.ts +3 -0
- package/package.json +32 -17
- package/bundles/covalent-guided-tour.umd.js +0 -1369
- package/bundles/covalent-guided-tour.umd.js.map +0 -1
- package/bundles/covalent-guided-tour.umd.min.js +0 -16
- package/bundles/covalent-guided-tour.umd.min.js.map +0 -1
- package/covalent-guided-tour.metadata.json +0 -1
- package/esm2015/covalent-guided-tour.js +0 -10
- package/esm2015/guided-tour.module.js +0 -19
- package/esm2015/guided-tour.service.js +0 -312
- package/esm2015/guided.tour.js +0 -722
- package/esm2015/index.js +0 -7
- package/esm2015/public-api.js +0 -9
- package/fesm2015/covalent-guided-tour.js.map +0 -1
package/esm2015/guided.tour.js
DELETED
|
@@ -1,722 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview added by tsickle
|
|
3
|
-
* Generated from: guided.tour.ts
|
|
4
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
5
|
-
*/
|
|
6
|
-
import Shepherd from 'shepherd.js';
|
|
7
|
-
import { timer, Subject, BehaviorSubject, merge, fromEvent, forkJoin } from 'rxjs';
|
|
8
|
-
import { takeUntil, skipWhile, filter, skip, first } from 'rxjs/operators';
|
|
9
|
-
/** @enum {string} */
|
|
10
|
-
const ITourEvent = {
|
|
11
|
-
'click': "click",
|
|
12
|
-
'pointerover': "pointerover",
|
|
13
|
-
'keyup': "keyup",
|
|
14
|
-
'added': "added",
|
|
15
|
-
'removed': "removed",
|
|
16
|
-
};
|
|
17
|
-
export { ITourEvent };
|
|
18
|
-
/**
|
|
19
|
-
* @record
|
|
20
|
-
*/
|
|
21
|
-
export function ITourEventOn() { }
|
|
22
|
-
if (false) {
|
|
23
|
-
/** @type {?|undefined} */
|
|
24
|
-
ITourEventOn.prototype.selector;
|
|
25
|
-
/** @type {?|undefined} */
|
|
26
|
-
ITourEventOn.prototype.event;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* @record
|
|
30
|
-
*/
|
|
31
|
-
export function ITourEventOnOptions() { }
|
|
32
|
-
if (false) {
|
|
33
|
-
/** @type {?|undefined} */
|
|
34
|
-
ITourEventOnOptions.prototype.timeBeforeShow;
|
|
35
|
-
/** @type {?|undefined} */
|
|
36
|
-
ITourEventOnOptions.prototype.interval;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* @record
|
|
40
|
-
*/
|
|
41
|
-
export function ITourAbortOn() { }
|
|
42
|
-
/**
|
|
43
|
-
* @record
|
|
44
|
-
*/
|
|
45
|
-
export function ITourOptions() { }
|
|
46
|
-
if (false) {
|
|
47
|
-
/** @type {?|undefined} */
|
|
48
|
-
ITourOptions.prototype.abortOn;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* @record
|
|
52
|
-
*/
|
|
53
|
-
export function ITourStepAttachToOptions() { }
|
|
54
|
-
if (false) {
|
|
55
|
-
/** @type {?|undefined} */
|
|
56
|
-
ITourStepAttachToOptions.prototype.highlight;
|
|
57
|
-
/** @type {?|undefined} */
|
|
58
|
-
ITourStepAttachToOptions.prototype.retries;
|
|
59
|
-
/** @type {?|undefined} */
|
|
60
|
-
ITourStepAttachToOptions.prototype.skipIfNotFound;
|
|
61
|
-
/** @type {?|undefined} */
|
|
62
|
-
ITourStepAttachToOptions.prototype.else;
|
|
63
|
-
/** @type {?|undefined} */
|
|
64
|
-
ITourStepAttachToOptions.prototype.goBackTo;
|
|
65
|
-
/** @type {?|undefined} */
|
|
66
|
-
ITourStepAttachToOptions.prototype.skipFromStepCount;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* @record
|
|
70
|
-
*/
|
|
71
|
-
export function ITourStepAdvanceOn() { }
|
|
72
|
-
/**
|
|
73
|
-
* @record
|
|
74
|
-
*/
|
|
75
|
-
export function ITourStepAdvanceOnOptions() { }
|
|
76
|
-
if (false) {
|
|
77
|
-
/** @type {?|undefined} */
|
|
78
|
-
ITourStepAdvanceOnOptions.prototype.jumpTo;
|
|
79
|
-
/** @type {?|undefined} */
|
|
80
|
-
ITourStepAdvanceOnOptions.prototype.allowGoBack;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* @record
|
|
84
|
-
*/
|
|
85
|
-
export function ITourStep() { }
|
|
86
|
-
if (false) {
|
|
87
|
-
/** @type {?|undefined} */
|
|
88
|
-
ITourStep.prototype.attachToOptions;
|
|
89
|
-
/** @type {?|undefined} */
|
|
90
|
-
ITourStep.prototype.advanceOnOptions;
|
|
91
|
-
/** @type {?|undefined} */
|
|
92
|
-
ITourStep.prototype.advanceOn;
|
|
93
|
-
/** @type {?|undefined} */
|
|
94
|
-
ITourStep.prototype.abortOn;
|
|
95
|
-
/** @type {?|undefined} */
|
|
96
|
-
ITourStep.prototype.count;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* @abstract
|
|
100
|
-
*/
|
|
101
|
-
class TourButtonsActions {
|
|
102
|
-
}
|
|
103
|
-
if (false) {
|
|
104
|
-
/**
|
|
105
|
-
* @abstract
|
|
106
|
-
* @return {?}
|
|
107
|
-
*/
|
|
108
|
-
TourButtonsActions.prototype.next = function () { };
|
|
109
|
-
/**
|
|
110
|
-
* @abstract
|
|
111
|
-
* @return {?}
|
|
112
|
-
*/
|
|
113
|
-
TourButtonsActions.prototype.back = function () { };
|
|
114
|
-
/**
|
|
115
|
-
* @abstract
|
|
116
|
-
* @return {?}
|
|
117
|
-
*/
|
|
118
|
-
TourButtonsActions.prototype.cancel = function () { };
|
|
119
|
-
/**
|
|
120
|
-
* @abstract
|
|
121
|
-
* @return {?}
|
|
122
|
-
*/
|
|
123
|
-
TourButtonsActions.prototype.finish = function () { };
|
|
124
|
-
}
|
|
125
|
-
/** @type {?} */
|
|
126
|
-
const SHEPHERD_DEFAULT_FIND_TIME_BEFORE_SHOW = 100;
|
|
127
|
-
/** @type {?} */
|
|
128
|
-
const SHEPHERD_DEFAULT_FIND_INTERVAL = 500;
|
|
129
|
-
/** @type {?} */
|
|
130
|
-
const SHEPHERD_DEFAULT_FIND_ATTEMPTS = 20;
|
|
131
|
-
/** @type {?} */
|
|
132
|
-
const overriddenEvents = [
|
|
133
|
-
ITourEvent.click,
|
|
134
|
-
ITourEvent.pointerover,
|
|
135
|
-
ITourEvent.removed,
|
|
136
|
-
ITourEvent.added,
|
|
137
|
-
ITourEvent.keyup,
|
|
138
|
-
];
|
|
139
|
-
/** @type {?} */
|
|
140
|
-
const keyEvents = new Map([
|
|
141
|
-
[13, 'enter'],
|
|
142
|
-
[27, 'esc'],
|
|
143
|
-
]);
|
|
144
|
-
/** @type {?} */
|
|
145
|
-
const defaultStepOptions = {
|
|
146
|
-
scrollTo: { behavior: 'smooth', block: 'center' },
|
|
147
|
-
cancelIcon: {
|
|
148
|
-
enabled: true,
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
/** @type {?} */
|
|
152
|
-
const MAT_ICON_BUTTON = 'mat-icon-button material-icons mat-button-base';
|
|
153
|
-
/** @type {?} */
|
|
154
|
-
const MAT_BUTTON = 'mat-button-base mat-button';
|
|
155
|
-
/** @type {?} */
|
|
156
|
-
const MAT_BUTTON_INVISIBLE = 'shepherd-void-button';
|
|
157
|
-
export class CovalentGuidedTour extends TourButtonsActions {
|
|
158
|
-
/**
|
|
159
|
-
* @param {?=} stepOptions
|
|
160
|
-
*/
|
|
161
|
-
constructor(stepOptions = defaultStepOptions) {
|
|
162
|
-
super();
|
|
163
|
-
this.stepOptions = stepOptions;
|
|
164
|
-
this.newTour();
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* @param {?=} opts
|
|
168
|
-
* @return {?}
|
|
169
|
-
*/
|
|
170
|
-
newTour(opts) {
|
|
171
|
-
this.shepherdTour = new Shepherd.Tour(Object.assign({
|
|
172
|
-
defaultStepOptions: this.stepOptions,
|
|
173
|
-
}, opts));
|
|
174
|
-
this._destroyedEvent$ = new Subject();
|
|
175
|
-
// listen to cancel and complete to clean up abortOn events
|
|
176
|
-
merge(fromEvent(this.shepherdTour, 'cancel'), fromEvent(this.shepherdTour, 'complete'))
|
|
177
|
-
.pipe(first())
|
|
178
|
-
.subscribe((/**
|
|
179
|
-
* @return {?}
|
|
180
|
-
*/
|
|
181
|
-
() => {
|
|
182
|
-
this._destroyedEvent$.next();
|
|
183
|
-
this._destroyedEvent$.complete();
|
|
184
|
-
}));
|
|
185
|
-
// if abortOn was passed, we bind the event and execute complete
|
|
186
|
-
if (opts && opts.abortOn) {
|
|
187
|
-
/** @type {?} */
|
|
188
|
-
const abortArr$ = [];
|
|
189
|
-
opts.abortOn.forEach((/**
|
|
190
|
-
* @param {?} abortOn
|
|
191
|
-
* @return {?}
|
|
192
|
-
*/
|
|
193
|
-
(abortOn) => {
|
|
194
|
-
/** @type {?} */
|
|
195
|
-
const abortEvent$ = new Subject();
|
|
196
|
-
abortArr$.push(abortEvent$);
|
|
197
|
-
this._bindEvent(abortOn, undefined, abortEvent$, this._destroyedEvent$);
|
|
198
|
-
}));
|
|
199
|
-
/** @type {?} */
|
|
200
|
-
const abortSubs = merge(...abortArr$)
|
|
201
|
-
.pipe(takeUntil(this._destroyedEvent$))
|
|
202
|
-
.subscribe((/**
|
|
203
|
-
* @return {?}
|
|
204
|
-
*/
|
|
205
|
-
() => {
|
|
206
|
-
this.shepherdTour.complete();
|
|
207
|
-
abortSubs.unsubscribe();
|
|
208
|
-
}));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* @return {?}
|
|
213
|
-
*/
|
|
214
|
-
back() {
|
|
215
|
-
this.shepherdTour.back();
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* @return {?}
|
|
219
|
-
*/
|
|
220
|
-
cancel() {
|
|
221
|
-
this.shepherdTour.cancel();
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* @return {?}
|
|
225
|
-
*/
|
|
226
|
-
next() {
|
|
227
|
-
this.shepherdTour.next();
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* @return {?}
|
|
231
|
-
*/
|
|
232
|
-
finish() {
|
|
233
|
-
this.shepherdTour.complete();
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* @param {?} steps
|
|
237
|
-
* @return {?}
|
|
238
|
-
*/
|
|
239
|
-
addSteps(steps) {
|
|
240
|
-
this.shepherdTour.addSteps(this._prepareTour(steps));
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* @return {?}
|
|
244
|
-
*/
|
|
245
|
-
start() {
|
|
246
|
-
this.shepherdTour.start();
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* @protected
|
|
250
|
-
* @param {?} originalSteps
|
|
251
|
-
* @param {?=} finishLabel
|
|
252
|
-
* @return {?}
|
|
253
|
-
*/
|
|
254
|
-
_prepareTour(originalSteps, finishLabel = 'finish') {
|
|
255
|
-
// create Subjects for back and forward events
|
|
256
|
-
/** @type {?} */
|
|
257
|
-
const backEvent$ = new Subject();
|
|
258
|
-
/** @type {?} */
|
|
259
|
-
const forwardEvent$ = new Subject();
|
|
260
|
-
/** @type {?} */
|
|
261
|
-
let _backFlow = false;
|
|
262
|
-
// create Subject for your end
|
|
263
|
-
/** @type {?} */
|
|
264
|
-
const destroyedEvent$ = new Subject();
|
|
265
|
-
/**
|
|
266
|
-
* This function adds the step progress in the footer of the shepherd tooltip
|
|
267
|
-
* @type {?}
|
|
268
|
-
*/
|
|
269
|
-
const appendProgressFunc = (/**
|
|
270
|
-
* @return {?}
|
|
271
|
-
*/
|
|
272
|
-
function () {
|
|
273
|
-
// get all the footers that are available in the DOM
|
|
274
|
-
/** @type {?} */
|
|
275
|
-
const footers = Array.from(document.querySelectorAll('.shepherd-footer'));
|
|
276
|
-
// get the last footer since Shepherd always puts the active one at the end
|
|
277
|
-
/** @type {?} */
|
|
278
|
-
const footer = footers[footers.length - 1];
|
|
279
|
-
// generate steps html element
|
|
280
|
-
/** @type {?} */
|
|
281
|
-
const progress = document.createElement('span');
|
|
282
|
-
progress.className = 'shepherd-progress';
|
|
283
|
-
progress.innerText = `${this.shepherdTour.currentStep.options.count}/${stepTotal}`;
|
|
284
|
-
// insert into the footer before the first button
|
|
285
|
-
footer.insertBefore(progress, footer.querySelector('.shepherd-button'));
|
|
286
|
-
});
|
|
287
|
-
/** @type {?} */
|
|
288
|
-
let stepTotal = 0;
|
|
289
|
-
/** @type {?} */
|
|
290
|
-
const steps = originalSteps.map((/**
|
|
291
|
-
* @param {?} step
|
|
292
|
-
* @return {?}
|
|
293
|
-
*/
|
|
294
|
-
(step) => {
|
|
295
|
-
var _a, _b, _c;
|
|
296
|
-
/** @type {?} */
|
|
297
|
-
let showProgress;
|
|
298
|
-
if (((_a = step.attachToOptions) === null || _a === void 0 ? void 0 : _a.skipFromStepCount) === true) {
|
|
299
|
-
showProgress = (/**
|
|
300
|
-
* @return {?}
|
|
301
|
-
*/
|
|
302
|
-
function () {
|
|
303
|
-
return;
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
else if (((_b = step.attachToOptions) === null || _b === void 0 ? void 0 : _b.skipFromStepCount) === undefined ||
|
|
307
|
-
((_c = step.attachToOptions) === null || _c === void 0 ? void 0 : _c.skipFromStepCount) === false) {
|
|
308
|
-
step.count = ++stepTotal;
|
|
309
|
-
showProgress = appendProgressFunc.bind(this);
|
|
310
|
-
}
|
|
311
|
-
return Object.assign({}, step, {
|
|
312
|
-
when: {
|
|
313
|
-
show: showProgress,
|
|
314
|
-
},
|
|
315
|
-
});
|
|
316
|
-
}));
|
|
317
|
-
/** @type {?} */
|
|
318
|
-
const finishButton = {
|
|
319
|
-
text: finishLabel,
|
|
320
|
-
action: this['finish'].bind(this),
|
|
321
|
-
classes: MAT_BUTTON,
|
|
322
|
-
};
|
|
323
|
-
/** @type {?} */
|
|
324
|
-
const voidButton = {
|
|
325
|
-
text: '',
|
|
326
|
-
/**
|
|
327
|
-
* @return {?}
|
|
328
|
-
*/
|
|
329
|
-
action() {
|
|
330
|
-
return;
|
|
331
|
-
},
|
|
332
|
-
classes: MAT_BUTTON_INVISIBLE,
|
|
333
|
-
};
|
|
334
|
-
// listen to the destroyed event to clean up all the streams
|
|
335
|
-
this._destroyedEvent$.pipe(first()).subscribe((/**
|
|
336
|
-
* @return {?}
|
|
337
|
-
*/
|
|
338
|
-
() => {
|
|
339
|
-
backEvent$.complete();
|
|
340
|
-
forwardEvent$.complete();
|
|
341
|
-
destroyedEvent$.next();
|
|
342
|
-
destroyedEvent$.complete();
|
|
343
|
-
}));
|
|
344
|
-
/** @type {?} */
|
|
345
|
-
const totalSteps = steps.length;
|
|
346
|
-
steps.forEach((/**
|
|
347
|
-
* @param {?} step
|
|
348
|
-
* @param {?} index
|
|
349
|
-
* @return {?}
|
|
350
|
-
*/
|
|
351
|
-
(step, index) => {
|
|
352
|
-
var _a;
|
|
353
|
-
// create buttons specific for the step
|
|
354
|
-
// this is done to create more control on events
|
|
355
|
-
/** @type {?} */
|
|
356
|
-
const nextButton = {
|
|
357
|
-
text: 'chevron_right',
|
|
358
|
-
action: (/**
|
|
359
|
-
* @return {?}
|
|
360
|
-
*/
|
|
361
|
-
() => {
|
|
362
|
-
// intercept the next action and trigger event
|
|
363
|
-
forwardEvent$.next();
|
|
364
|
-
this.shepherdTour.next();
|
|
365
|
-
}),
|
|
366
|
-
classes: MAT_ICON_BUTTON,
|
|
367
|
-
};
|
|
368
|
-
/** @type {?} */
|
|
369
|
-
const backButton = {
|
|
370
|
-
text: 'chevron_left',
|
|
371
|
-
action: (/**
|
|
372
|
-
* @return {?}
|
|
373
|
-
*/
|
|
374
|
-
() => {
|
|
375
|
-
// intercept the back action and trigger event
|
|
376
|
-
backEvent$.next();
|
|
377
|
-
_backFlow = true;
|
|
378
|
-
// check if 'goBackTo' is set to jump to a particular step, else just go back
|
|
379
|
-
if (step.attachToOptions && step.attachToOptions.goBackTo) {
|
|
380
|
-
this.shepherdTour.show(step.attachToOptions.goBackTo, false);
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
this.shepherdTour.back();
|
|
384
|
-
}
|
|
385
|
-
}),
|
|
386
|
-
classes: ((_a = step.advanceOnOptions) === null || _a === void 0 ? void 0 : _a.allowGoBack) === false ? MAT_BUTTON_INVISIBLE : MAT_ICON_BUTTON,
|
|
387
|
-
};
|
|
388
|
-
// check if highlight was provided for the step, else fallback into shepherds usage
|
|
389
|
-
step.highlightClass =
|
|
390
|
-
step.attachToOptions && step.attachToOptions.highlight ? 'shepherd-highlight' : step.highlightClass;
|
|
391
|
-
// Adding buttons in the steps if no buttons are defined
|
|
392
|
-
if (!step.buttons || step.buttons.length === 0) {
|
|
393
|
-
if (index === 0) {
|
|
394
|
-
// first step
|
|
395
|
-
step.buttons = [nextButton];
|
|
396
|
-
}
|
|
397
|
-
else if (index === totalSteps - 1) {
|
|
398
|
-
// last step
|
|
399
|
-
step.buttons = [backButton, finishButton];
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
step.buttons = [backButton, nextButton];
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
// checks "advanceOn" to override listeners
|
|
406
|
-
/** @type {?} */
|
|
407
|
-
let advanceOn = step.advanceOn;
|
|
408
|
-
// remove the shepherd "advanceOn" infavor of ours if the event is part of our list
|
|
409
|
-
if ((typeof advanceOn === 'object' &&
|
|
410
|
-
!Array.isArray(advanceOn) &&
|
|
411
|
-
overriddenEvents.indexOf(advanceOn.event.split('.')[0]) > -1) ||
|
|
412
|
-
advanceOn instanceof Array) {
|
|
413
|
-
step.advanceOn = undefined;
|
|
414
|
-
step.buttons =
|
|
415
|
-
step.advanceOnOptions && step.advanceOnOptions.allowGoBack ? [backButton, voidButton] : [voidButton];
|
|
416
|
-
}
|
|
417
|
-
// adds a default beforeShowPromise function
|
|
418
|
-
step.beforeShowPromise = (/**
|
|
419
|
-
* @return {?}
|
|
420
|
-
*/
|
|
421
|
-
() => {
|
|
422
|
-
return new Promise((/**
|
|
423
|
-
* @param {?} resolve
|
|
424
|
-
* @return {?}
|
|
425
|
-
*/
|
|
426
|
-
(resolve) => {
|
|
427
|
-
/** @type {?} */
|
|
428
|
-
const additionalCapabilitiesSetup = (/**
|
|
429
|
-
* @return {?}
|
|
430
|
-
*/
|
|
431
|
-
() => {
|
|
432
|
-
if (advanceOn && !step.advanceOn) {
|
|
433
|
-
if (!Array.isArray(advanceOn)) {
|
|
434
|
-
advanceOn = [advanceOn];
|
|
435
|
-
}
|
|
436
|
-
/** @type {?} */
|
|
437
|
-
const advanceArr$ = [];
|
|
438
|
-
advanceOn.forEach((/**
|
|
439
|
-
* @param {?} _
|
|
440
|
-
* @param {?} i
|
|
441
|
-
* @return {?}
|
|
442
|
-
*/
|
|
443
|
-
(_, i) => {
|
|
444
|
-
/** @type {?} */
|
|
445
|
-
const advanceEvent$ = new Subject();
|
|
446
|
-
advanceArr$.push(advanceEvent$);
|
|
447
|
-
// we start a timer of attempts to find an element in the dom
|
|
448
|
-
this._bindEvent(advanceOn[i], step.advanceOnOptions, advanceEvent$, destroyedEvent$);
|
|
449
|
-
}));
|
|
450
|
-
/** @type {?} */
|
|
451
|
-
const advanceSubs = forkJoin(...advanceArr$)
|
|
452
|
-
.pipe(takeUntil(merge(destroyedEvent$, backEvent$)))
|
|
453
|
-
.subscribe((/**
|
|
454
|
-
* @return {?}
|
|
455
|
-
*/
|
|
456
|
-
() => {
|
|
457
|
-
// check if we need to advance to a specific step, else advance to next step
|
|
458
|
-
if (step.advanceOnOptions && step.advanceOnOptions.jumpTo) {
|
|
459
|
-
this.shepherdTour.show(step.advanceOnOptions.jumpTo);
|
|
460
|
-
}
|
|
461
|
-
else {
|
|
462
|
-
this.shepherdTour.next();
|
|
463
|
-
}
|
|
464
|
-
forwardEvent$.next();
|
|
465
|
-
advanceSubs.unsubscribe();
|
|
466
|
-
}));
|
|
467
|
-
}
|
|
468
|
-
// if abortOn was passed on the step, we bind the event and execute complete
|
|
469
|
-
if (step.abortOn) {
|
|
470
|
-
/** @type {?} */
|
|
471
|
-
const abortArr$ = [];
|
|
472
|
-
step.abortOn.forEach((/**
|
|
473
|
-
* @param {?} abortOn
|
|
474
|
-
* @return {?}
|
|
475
|
-
*/
|
|
476
|
-
(abortOn) => {
|
|
477
|
-
/** @type {?} */
|
|
478
|
-
const abortEvent$ = new Subject();
|
|
479
|
-
abortArr$.push(abortEvent$);
|
|
480
|
-
this._bindEvent(abortOn, undefined, abortEvent$, destroyedEvent$);
|
|
481
|
-
}));
|
|
482
|
-
/** @type {?} */
|
|
483
|
-
const abortSubs = merge(...abortArr$)
|
|
484
|
-
.pipe(takeUntil(merge(destroyedEvent$, backEvent$, forwardEvent$)))
|
|
485
|
-
.subscribe((/**
|
|
486
|
-
* @return {?}
|
|
487
|
-
*/
|
|
488
|
-
() => {
|
|
489
|
-
this.shepherdTour.complete();
|
|
490
|
-
abortSubs.unsubscribe();
|
|
491
|
-
}));
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
/** @type {?} */
|
|
495
|
-
const _stopTimer$ = new Subject();
|
|
496
|
-
/** @type {?} */
|
|
497
|
-
const _retriesReached$ = new Subject();
|
|
498
|
-
/** @type {?} */
|
|
499
|
-
const _retryAttempts$ = new BehaviorSubject(-1);
|
|
500
|
-
/** @type {?} */
|
|
501
|
-
let id;
|
|
502
|
-
// checks if "attachTo" is a string or an object to get the id of an element
|
|
503
|
-
if (typeof step.attachTo === 'string') {
|
|
504
|
-
id = step.attachTo;
|
|
505
|
-
}
|
|
506
|
-
else if (typeof step.attachTo === 'object' && typeof step.attachTo.element === 'string') {
|
|
507
|
-
id = step.attachTo.element;
|
|
508
|
-
}
|
|
509
|
-
// if we have an id as a string in either case, we use it (we ignore it if its HTMLElement)
|
|
510
|
-
if (id) {
|
|
511
|
-
// if current step is the first step of the tour, we set the buttons to be only "next"
|
|
512
|
-
// we had to use `any` since the tour doesnt expose the steps in any fashion nor a way to check if we have modified them at all
|
|
513
|
-
if (this.shepherdTour.getCurrentStep() === ((/** @type {?} */ (this.shepherdTour))).steps[0]) {
|
|
514
|
-
this.shepherdTour.getCurrentStep().updateStepOptions({
|
|
515
|
-
buttons: originalSteps[index].advanceOn ? [voidButton] : [nextButton],
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
// register to the attempts observable to notify deeveloper when number has been reached
|
|
519
|
-
_retryAttempts$
|
|
520
|
-
.pipe(skip(1), takeUntil(merge(_stopTimer$.asObservable(), destroyedEvent$)), skipWhile((/**
|
|
521
|
-
* @param {?} val
|
|
522
|
-
* @return {?}
|
|
523
|
-
*/
|
|
524
|
-
(val) => {
|
|
525
|
-
if (step.attachToOptions && step.attachToOptions.retries !== undefined) {
|
|
526
|
-
return val < step.attachToOptions.retries;
|
|
527
|
-
}
|
|
528
|
-
return val < SHEPHERD_DEFAULT_FIND_ATTEMPTS;
|
|
529
|
-
})))
|
|
530
|
-
.subscribe((/**
|
|
531
|
-
* @param {?} attempts
|
|
532
|
-
* @return {?}
|
|
533
|
-
*/
|
|
534
|
-
(attempts) => {
|
|
535
|
-
_retriesReached$.next();
|
|
536
|
-
_retriesReached$.complete();
|
|
537
|
-
// if attempts have been reached, we check "skipIfNotFound" to move on to the next step
|
|
538
|
-
if (step.attachToOptions && step.attachToOptions.skipIfNotFound) {
|
|
539
|
-
// if we get to this step coming back from a step and it wasnt found
|
|
540
|
-
// then we either check if its the first step and try going forward
|
|
541
|
-
// or we keep going back until we find a step that actually exists
|
|
542
|
-
if (_backFlow) {
|
|
543
|
-
if (((/** @type {?} */ (this.shepherdTour))).steps.indexOf(this.shepherdTour.getCurrentStep()) === 0) {
|
|
544
|
-
this.shepherdTour.next();
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
this.shepherdTour.back();
|
|
548
|
-
}
|
|
549
|
-
_backFlow = false;
|
|
550
|
-
}
|
|
551
|
-
else {
|
|
552
|
-
// destroys current step if we need to skip it to remove it from the tour
|
|
553
|
-
/** @type {?} */
|
|
554
|
-
const currentStep = this.shepherdTour.getCurrentStep();
|
|
555
|
-
currentStep.destroy();
|
|
556
|
-
this.shepherdTour.next();
|
|
557
|
-
this.shepherdTour.removeStep(((/** @type {?} */ (currentStep))).id);
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
else if (step.attachToOptions && step.attachToOptions.else) {
|
|
561
|
-
// if "skipIfNotFound" is not true, then we check if "else" has been set to jump to a specific step
|
|
562
|
-
this.shepherdTour.show(step.attachToOptions.else);
|
|
563
|
-
}
|
|
564
|
-
else {
|
|
565
|
-
// tslint:disable-next-line:no-console
|
|
566
|
-
console.warn(`Retries reached trying to find ${id}. Retried ${attempts} times.`);
|
|
567
|
-
// else we show the step regardless
|
|
568
|
-
resolve();
|
|
569
|
-
}
|
|
570
|
-
}));
|
|
571
|
-
// we start a timer of attempts to find an element in the dom
|
|
572
|
-
timer((step.attachToOptions && step.attachToOptions.timeBeforeShow) || SHEPHERD_DEFAULT_FIND_TIME_BEFORE_SHOW, (step.attachToOptions && step.attachToOptions.interval) || SHEPHERD_DEFAULT_FIND_INTERVAL)
|
|
573
|
-
.pipe(
|
|
574
|
-
// the timer will continue either until we find the element or the number of attempts has been reached
|
|
575
|
-
takeUntil(merge(_stopTimer$, _retriesReached$, destroyedEvent$)))
|
|
576
|
-
.subscribe((/**
|
|
577
|
-
* @return {?}
|
|
578
|
-
*/
|
|
579
|
-
() => {
|
|
580
|
-
/** @type {?} */
|
|
581
|
-
const element = document.querySelector(id);
|
|
582
|
-
// if the element has been found, we stop the timer and resolve the promise
|
|
583
|
-
if (element) {
|
|
584
|
-
_stopTimer$.next();
|
|
585
|
-
_stopTimer$.complete();
|
|
586
|
-
additionalCapabilitiesSetup();
|
|
587
|
-
resolve();
|
|
588
|
-
}
|
|
589
|
-
else {
|
|
590
|
-
_retryAttempts$.next(_retryAttempts$.value + 1);
|
|
591
|
-
}
|
|
592
|
-
}));
|
|
593
|
-
// stop find interval if user stops the tour
|
|
594
|
-
destroyedEvent$.subscribe((/**
|
|
595
|
-
* @return {?}
|
|
596
|
-
*/
|
|
597
|
-
() => {
|
|
598
|
-
_stopTimer$.next();
|
|
599
|
-
_stopTimer$.complete();
|
|
600
|
-
_retriesReached$.next();
|
|
601
|
-
_retriesReached$.complete();
|
|
602
|
-
}));
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
// resolve observable until the timeBeforeShow has passsed or use default
|
|
606
|
-
timer((step.attachToOptions && step.attachToOptions.timeBeforeShow) || SHEPHERD_DEFAULT_FIND_TIME_BEFORE_SHOW)
|
|
607
|
-
.pipe(takeUntil(merge(destroyedEvent$)))
|
|
608
|
-
.subscribe((/**
|
|
609
|
-
* @return {?}
|
|
610
|
-
*/
|
|
611
|
-
() => {
|
|
612
|
-
resolve();
|
|
613
|
-
}));
|
|
614
|
-
}
|
|
615
|
-
}));
|
|
616
|
-
});
|
|
617
|
-
}));
|
|
618
|
-
return steps;
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* @private
|
|
622
|
-
* @param {?} eventOn
|
|
623
|
-
* @param {?} eventOnOptions
|
|
624
|
-
* @param {?} event$
|
|
625
|
-
* @param {?} destroyedEvent$
|
|
626
|
-
* @return {?}
|
|
627
|
-
*/
|
|
628
|
-
_bindEvent(eventOn, eventOnOptions, event$, destroyedEvent$) {
|
|
629
|
-
/** @type {?} */
|
|
630
|
-
const selector = eventOn.selector;
|
|
631
|
-
/** @type {?} */
|
|
632
|
-
const event = eventOn.event;
|
|
633
|
-
// we start a timer of attempts to find an element in the dom
|
|
634
|
-
/** @type {?} */
|
|
635
|
-
const timerSubs = timer((eventOnOptions && eventOnOptions.timeBeforeShow) || SHEPHERD_DEFAULT_FIND_TIME_BEFORE_SHOW, (eventOnOptions && eventOnOptions.interval) || SHEPHERD_DEFAULT_FIND_INTERVAL)
|
|
636
|
-
.pipe(takeUntil(destroyedEvent$))
|
|
637
|
-
.subscribe((/**
|
|
638
|
-
* @return {?}
|
|
639
|
-
*/
|
|
640
|
-
() => {
|
|
641
|
-
/** @type {?} */
|
|
642
|
-
const element = document.querySelector(selector);
|
|
643
|
-
// if the element has been found, we stop the timer and resolve the promise
|
|
644
|
-
if (element) {
|
|
645
|
-
timerSubs.unsubscribe();
|
|
646
|
-
if (event === ITourEvent.added) {
|
|
647
|
-
// if event is "Added" trigger a soon as this is attached.
|
|
648
|
-
event$.next();
|
|
649
|
-
event$.complete();
|
|
650
|
-
}
|
|
651
|
-
else if (event === ITourEvent.click ||
|
|
652
|
-
event === ITourEvent.pointerover ||
|
|
653
|
-
event.indexOf(ITourEvent.keyup) > -1) {
|
|
654
|
-
// we use normal listeners for mouseevents
|
|
655
|
-
/** @type {?} */
|
|
656
|
-
const mainEvent = event.split('.')[0];
|
|
657
|
-
/** @type {?} */
|
|
658
|
-
const subEvent = event.split('.')[1];
|
|
659
|
-
fromEvent(element, mainEvent)
|
|
660
|
-
.pipe(takeUntil(merge(event$.asObservable(), destroyedEvent$)), filter((/**
|
|
661
|
-
* @param {?} $event
|
|
662
|
-
* @return {?}
|
|
663
|
-
*/
|
|
664
|
-
($event) => {
|
|
665
|
-
// only trigger if the event is a keyboard event and part of out list
|
|
666
|
-
if ($event instanceof KeyboardEvent) {
|
|
667
|
-
if (keyEvents.get($event.keyCode) === subEvent) {
|
|
668
|
-
return true;
|
|
669
|
-
}
|
|
670
|
-
return false;
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
return true;
|
|
674
|
-
}
|
|
675
|
-
})))
|
|
676
|
-
.subscribe((/**
|
|
677
|
-
* @return {?}
|
|
678
|
-
*/
|
|
679
|
-
() => {
|
|
680
|
-
event$.next();
|
|
681
|
-
event$.complete();
|
|
682
|
-
}));
|
|
683
|
-
}
|
|
684
|
-
else if (event === ITourEvent.removed) {
|
|
685
|
-
// and we will use MutationObserver for DOM events
|
|
686
|
-
/** @type {?} */
|
|
687
|
-
const observer = new MutationObserver((/**
|
|
688
|
-
* @return {?}
|
|
689
|
-
*/
|
|
690
|
-
() => {
|
|
691
|
-
if (!document.body.contains(element)) {
|
|
692
|
-
event$.next();
|
|
693
|
-
event$.complete();
|
|
694
|
-
observer.disconnect();
|
|
695
|
-
}
|
|
696
|
-
}));
|
|
697
|
-
// stop listenining if tour is closed
|
|
698
|
-
destroyedEvent$.subscribe((/**
|
|
699
|
-
* @return {?}
|
|
700
|
-
*/
|
|
701
|
-
() => {
|
|
702
|
-
observer.disconnect();
|
|
703
|
-
}));
|
|
704
|
-
// observe for any DOM interaction in the element
|
|
705
|
-
observer.observe(element, { childList: true, subtree: true, attributes: true });
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
}));
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
if (false) {
|
|
712
|
-
/**
|
|
713
|
-
* @type {?}
|
|
714
|
-
* @private
|
|
715
|
-
*/
|
|
716
|
-
CovalentGuidedTour.prototype._destroyedEvent$;
|
|
717
|
-
/** @type {?} */
|
|
718
|
-
CovalentGuidedTour.prototype.shepherdTour;
|
|
719
|
-
/** @type {?} */
|
|
720
|
-
CovalentGuidedTour.prototype.stepOptions;
|
|
721
|
-
}
|
|
722
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VpZGVkLnRvdXIuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vc3JjL3BsYXRmb3JtL2d1aWRlZC10b3VyLyIsInNvdXJjZXMiOlsiZ3VpZGVkLnRvdXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLFFBQVEsTUFBTSxhQUFhLENBQUM7QUFDbkMsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBZ0IsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRyxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQUszRSxNQUFZLFVBQVU7SUFDcEIsT0FBTyxTQUFVO0lBQ2pCLGFBQWEsZUFBZ0I7SUFDN0IsT0FBTyxTQUFVO0lBQ2pCLE9BQU8sU0FBVTtJQUNqQixTQUFTLFdBQVk7RUFDdEI7Ozs7O0FBRUQsa0NBR0M7OztJQUZDLGdDQUFrQjs7SUFDbEIsNkJBQWdDOzs7OztBQUdsQyx5Q0FHQzs7O0lBRkMsNkNBQXdCOztJQUN4Qix1Q0FBa0I7Ozs7O0FBR3BCLGtDQUFxRDs7OztBQUVyRCxrQ0FFQzs7O0lBREMsK0JBQXlCOzs7OztBQUczQiw4Q0FPQzs7O0lBTkMsNkNBQW9COztJQUNwQiwyQ0FBaUI7O0lBQ2pCLGtEQUF5Qjs7SUFDekIsd0NBQWM7O0lBQ2QsNENBQWtCOztJQUNsQixxREFBNEI7Ozs7O0FBRzlCLHdDQUEyRDs7OztBQUUzRCwrQ0FHQzs7O0lBRkMsMkNBQWdCOztJQUNoQixnREFBc0I7Ozs7O0FBR3hCLCtCQU1DOzs7SUFMQyxvQ0FBMkM7O0lBQzNDLHFDQUE2Qzs7SUFDN0MsOEJBQTREOztJQUM1RCw0QkFBeUI7O0lBQ3pCLDBCQUFlOzs7OztBQUdqQixNQUFlLGtCQUFrQjtDQVFoQzs7Ozs7O0lBUEMsb0RBQXNCOzs7OztJQUV0QixvREFBc0I7Ozs7O0lB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QyxFQUFDLENBQUM7aUJBQ047cUJBQU0sSUFBSSxLQUFLLEtBQUssVUFBVSxDQUFDLE9BQU8sRUFBRTs7OzBCQUVqQyxRQUFRLEdBQXFCLElBQUksZ0JBQWdCOzs7b0JBQUMsR0FBRyxFQUFFO3dCQUMzRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7NEJBQ3BDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQzs0QkFDZCxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7NEJBQ2xCLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQzt5QkFDdkI7b0JBQ0gsQ0FBQyxFQUFDO29CQUVGLHFDQUFxQztvQkFDckMsZUFBZSxDQUFDLFNBQVM7OztvQkFBQyxHQUFHLEVBQUU7d0JBQzdCLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDeEIsQ0FBQyxFQUFDLENBQUM7b0JBQ0gsaURBQWlEO29CQUNqRCxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztpQkFDakY7YUFDRjtRQUNILENBQUMsRUFBQztJQUNOLENBQUM7Q0FDRjs7Ozs7O0lBM2FDLDhDQUF3Qzs7SUFFeEMsMENBQTRCOztJQUM1Qix5Q0FBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgU2hlcGhlcmQgZnJvbSAnc2hlcGhlcmQuanMnO1xuaW1wb3J0IHsgdGltZXIsIFN1YmplY3QsIEJlaGF2aW9yU3ViamVjdCwgbWVyZ2UsIFN1YnNjcmlwdGlvbiwgZnJvbUV2ZW50LCBmb3JrSm9pbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsLCBza2lwV2hpbGUsIGZpbHRlciwgc2tpcCwgZmlyc3QgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmV4cG9ydCB0eXBlIFRvdXJTdGVwID0gU2hlcGhlcmQuU3RlcC5TdGVwT3B0aW9ucztcbmV4cG9ydCB0eXBlIFRvdXJTdGVwQnV0dG9uID0gU2hlcGhlcmQuU3RlcC5TdGVwT3B0aW9uc0J1dHRvbjtcblxuZXhwb3J0IGVudW0gSVRvdXJFdmVudCB7XG4gICdjbGljaycgPSAnY2xpY2snLFxuICAncG9pbnRlcm92ZXInID0gJ3BvaW50ZXJvdmVyJyxcbiAgJ2tleXVwJyA9ICdrZXl1cCcsXG4gICdhZGRlZCcgPSAnYWRkZWQnLCAvLyBhZGRlZCB0byBET01cbiAgJ3JlbW92ZWQnID0gJ3JlbW92ZWQnLCAvLyByZW1vdmVkIGZyb20gRE9NXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVRvdXJFdmVudE9uIHtcbiAgc2VsZWN0b3I/OiBzdHJpbmc7IC8vIGNzcyBzZWxlY3RvclxuICBldmVudD86IGtleW9mIHR5cGVvZiBJVG91ckV2ZW50OyAvLyBjbGljaywgcG9pbnRlcm92ZXIsIGtleXVwLCBhZGRlZCwgcmVtb3ZlZFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElUb3VyRXZlbnRPbk9wdGlvbnMge1xuICB0aW1lQmVmb3JlU2hvdz86IG51bWJlcjsgLy8gZGVsYXkgYmVmb3JlIHN0ZXAgaXMgZGlzcGxheWVkXG4gIGludGVydmFsPzogbnVtYmVyOyAvLyB0aW1lIGJldHdlZW4gc2VhcmNoZXMgZm9yIGVsZW1lbnQsIGRlZmF1bHRzIHRvIDUwMG1zXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVRvdXJBYm9ydE9uIGV4dGVuZHMgSVRvdXJFdmVudE9uIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVRvdXJPcHRpb25zIGV4dGVuZHMgU2hlcGhlcmQuVG91ci5Ub3VyT3B0aW9ucyB7XG4gIGFib3J0T24/OiBJVG91ckFib3J0T25bXTsgLy8gZXZlbnRzIHRvIGFib3J0IG9uXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVRvdXJTdGVwQXR0YWNoVG9PcHRpb25zIGV4dGVuZHMgSVRvdXJFdmVudE9uT3B0aW9ucyB7XG4gIGhpZ2hsaWdodD86IGJvb2xlYW47XG4gIHJldHJpZXM/OiBudW1iZXI7IC8vICMgbnVtIG9mIGF0dGVtcHRzIHRvIGZpbmQgZWxlbWVudFxuICBza2lwSWZOb3RGb3VuZD86IGJvb2xlYW47IC8vIGlmIGVsZW1lbnQgaXMgbm90IGZvdW5kIGFmdGVyIG4gcmV0cmllcywgbW92ZSBvbiB0byBuZXh0IHN0ZXBcbiAgZWxzZT86IHN0cmluZzsgLy8gaWYgZWxlbWVudCBpcyBub3QgZm91bmQsIGdvIHRvIHN0ZXAgd2l0aCB0aGlzIGlkXG4gIGdvQmFja1RvPzogc3RyaW5nOyAvLyBiYWNrIGJ1dHRvbiBnb2VzIGJhY2sgdG8gc3RlcCB3aXRoIHRoaXMgaWRcbiAgc2tpcEZyb21TdGVwQ291bnQ/OiBib29sZWFuOyAvLyBzaG93L2hpZGUgcHJvZ3Jlc3Mgb24gc3RlcFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElUb3VyU3RlcEFkdmFuY2VPbiBleHRlbmRzIElUb3VyRXZlbnRPbiB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIElUb3VyU3RlcEFkdmFuY2VPbk9wdGlvbnMgZXh0ZW5kcyBJVG91ckV2ZW50T25PcHRpb25zIHtcbiAganVtcFRvPzogc3RyaW5nOyAvLyBuZXh0IGJ1dHRvbiB3aWxsIGp1bXAgdG8gc3RlcCB3aXRoIHRoaXMgaWRcbiAgYWxsb3dHb0JhY2s/OiBib29sZWFuOyAvLyBhbGxvdyBiYWNrIHdpdGhpbiB0aGlzIHN0ZXBcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVG91clN0ZXAgZXh0ZW5kcyBUb3VyU3RlcCB7XG4gIGF0dGFjaFRvT3B0aW9ucz86IElUb3VyU3RlcEF0dGFjaFRvT3B0aW9ucztcbiAgYWR2YW5jZU9uT3B0aW9ucz86IElUb3VyU3RlcEFkdmFuY2VPbk9wdGlvbnM7XG4gIGFkdmFuY2VPbj86IElUb3VyU3RlcEFkdmFuY2VPbltdIHwgSVRvdXJTdGVwQWR2YW5jZU9uIHwgYW55O1xuICBhYm9ydE9uPzogSVRvdXJBYm9ydE9uW107XG4gIGNvdW50PzogbnVtYmVyO1xufVxuXG5hYnN0cmFjdCBjbGFzcyBUb3VyQnV0dG9uc0FjdGlvbnMge1xuICBhYnN0cmFjdCBuZXh0KCk6IHZvaWQ7XG5cbiAgYWJzdHJhY3QgYmFjaygpOiB2b2lkO1xuXG4gIGFic3RyYWN0IGNhbmNlbCgpOiB2b2lkO1xuXG4gIGFic3RyYWN0IGZpbmlzaCgpOiB2b2lkO1xufVxuXG5jb25zdCBTSEVQSEVSRF9ERUZBVUxUX0ZJTkRfVElNRV9CRUZPUkVfU0hPVzogbnVtYmVyID0gMTAwO1xuY29uc3QgU0hFUEhFUkRfREVGQVVMVF9GSU5EX0lOVEVSVkFMOiBudW1iZXIgPSA1MDA7XG5jb25zdCBTSEVQSEVSRF9ERUZBVUxUX0ZJTkRfQVRURU1QVFM6IG51bWJlciA9IDIwO1xuXG5jb25zdCBvdmVycmlkZGVuRXZlbnRzOiBzdHJpbmdbXSA9IFtcbiAgSVRvdXJFdmVudC5jbGljayxcbiAgSVRvdXJFdmVudC5wb2ludGVyb3ZlcixcbiAgSVRvdXJFdmVudC5yZW1vdmVkLFxuICBJVG91ckV2ZW50LmFkZGVkLFxuICBJVG91ckV2ZW50LmtleXVwLFxuXTtcblxuY29uc3Qga2V5RXZlbnRzOiBNYXA8bnVtYmVyLCBzdHJpbmc+ID0gbmV3IE1hcDxudW1iZXIsIHN0cmluZz4oW1xuICBbMTMsICdlbnRlciddLFxuICBbMjcsICdlc2MnXSxcbl0pO1xuXG5jb25zdCBkZWZhdWx0U3RlcE9wdGlvbnM6IFRvdXJTdGVwID0ge1xuICBzY3JvbGxUbzogeyBiZWhhdmlvcjogJ3Ntb290aCcsIGJsb2NrOiAnY2VudGVyJyB9LFxuICBjYW5jZWxJY29uOiB7XG4gICAgZW5hYmxlZDogdHJ1ZSxcbiAgfSxcbn07XG5cbmNvbnN0IE1BVF9JQ09OX0JVVFRPTjogc3RyaW5nID0gJ21hdC1pY29uLWJ1dHRvbiBtYXRlcmlhbC1pY29ucyBtYXQtYnV0dG9uLWJhc2UnO1xuY29uc3QgTUFUX0JVVFRPTjogc3RyaW5nID0gJ21hdC1idXR0b24tYmFzZSBtYXQtYnV0dG9uJztcbmNvbnN0IE1BVF9CVVRUT05fSU5WSVNJQkxFOiBzdHJpbmcgPSAnc2hlcGhlcmQtdm9pZC1idXR0b24nO1xuXG5leHBvcnQgY2xhc3MgQ292YWxlbnRHdWlkZWRUb3VyIGV4dGVuZHMgVG91ckJ1dHRvbnNBY3Rpb25zIHtcbiAgcHJpdmF0ZSBfZGVzdHJveWVkRXZlbnQkOiBTdWJqZWN0PHZvaWQ+O1xuXG4gIHNoZXBoZXJkVG91cjogU2hlcGhlcmQuVG91cjtcbiAgc3RlcE9wdGlvbnM6IElUb3VyU3RlcDtcblxuICBjb25zdHJ1Y3RvcihzdGVwT3B0aW9uczogSVRvdXJTdGVwID0gZGVmYXVsdFN0ZXBPcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuc3RlcE9wdGlvbnMgPSBzdGVwT3B0aW9ucztcbiAgICB0aGlzLm5ld1RvdXIoKTtcbiAgfVxuXG4gIG5ld1RvdXIob3B0cz86IElUb3VyT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMuc2hlcGhlcmRUb3VyID0gbmV3IFNoZXBoZXJkLlRvdXIoXG4gICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICB7XG4gICAgICAgICAgZGVmYXVsdFN0ZXBPcHRpb25zOiB0aGlzLnN0ZXBPcHRpb25zLFxuICAgICAgICB9LFxuICAgICAgICBvcHRzLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgdGhpcy5fZGVzdHJveWVkRXZlbnQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgICAvLyBsaXN0ZW4gdG8gY2FuY2VsIGFuZCBjb21wbGV0ZSB0byBjbGVhbiB1cCBhYm9ydE9uIGV2ZW50c1xuICAgIG1lcmdlKGZyb21FdmVudCh0aGlzLnNoZXBoZXJkVG91ciwgJ2NhbmNlbCcpLCBmcm9tRXZlbnQodGhpcy5zaGVwaGVyZFRvdXIsICdjb21wbGV0ZScpKVxuICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWRFdmVudCQubmV4dCgpO1xuICAgICAgICB0aGlzLl9kZXN0cm95ZWRFdmVudCQuY29tcGxldGUoKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gaWYgYWJvcnRPbiB3YXMgcGFzc2VkLCB3ZSBiaW5kIHRoZSBldmVudCBhbmQgZXhlY3V0ZSBjb21wbGV0ZVxuICAgIGlmIChvcHRzICYmIG9wdHMuYWJvcnRPbikge1xuICAgICAgY29uc3QgYWJvcnRBcnIkOiBTdWJqZWN0PHZvaWQ+W10gPSBbXTtcbiAgICAgIG9wdHMuYWJvcnRPbi5mb3JFYWNoKChhYm9ydE9uOiBJVG91ckFib3J0T24pID0+IHtcbiAgICAgICAgY29uc3QgYWJvcnRFdmVudCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgICAgICBhYm9ydEFyciQucHVzaChhYm9ydEV2ZW50JCk7XG4gICAgICAgIHRoaXMuX2JpbmRFdmVudChhYm9ydE9uLCB1bmRlZmluZWQsIGFib3J0RXZlbnQkLCB0aGlzLl9kZXN0cm95ZWRFdmVudCQpO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGFib3J0U3ViczogU3Vic2NyaXB0aW9uID0gbWVyZ2UoLi4uYWJvcnRBcnIkKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkRXZlbnQkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zaGVwaGVyZFRvdXIuY29tcGxldGUoKTtcbiAgICAgICAgICBhYm9ydFN1YnMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYmFjaygpOiB2b2lkIHtcbiAgICB0aGlzLnNoZXBoZXJkVG91ci5iYWNrKCk7XG4gIH1cblxuICBjYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5zaGVwaGVyZFRvdXIuY2FuY2VsKCk7XG4gIH1cblxuICBuZXh0KCk6IHZvaWQge1xuICAgIHRoaXMuc2hlcGhlcmRUb3VyLm5leHQoKTtcbiAgfVxuXG4gIGZpbmlzaCgpOiB2b2lkIHtcbiAgICB0aGlzLnNoZXBoZXJkVG91ci5jb21wbGV0ZSgpO1xuICB9XG5cbiAgYWRkU3RlcHMoc3RlcHM6IElUb3VyU3RlcFtdKTogdm9pZCB7XG4gICAgdGhpcy5zaGVwaGVyZFRvdXIuYWRkU3RlcHModGhpcy5fcHJlcGFyZVRvdXIoc3RlcHMpKTtcbiAgfVxuXG4gIHN0YXJ0KCk6IHZvaWQge1xuICAgIHRoaXMuc2hlcGhlcmRUb3VyLnN0YXJ0KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3ByZXBhcmVUb3VyKG9yaWdpbmFsU3RlcHM6IElUb3VyU3RlcFtdLCBmaW5pc2hMYWJlbDogc3RyaW5nID0gJ2ZpbmlzaCcpOiBJVG91clN0ZXBbXSB7XG4gICAgLy8gY3JlYXRlIFN1YmplY3RzIGZvciBiYWNrIGFuZCBmb3J3YXJkIGV2ZW50c1xuICAgIGNvbnN0IGJhY2tFdmVudCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgIGNvbnN0IGZvcndhcmRFdmVudCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgIGxldCBfYmFja0Zsb3c6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvLyBjcmVhdGUgU3ViamVjdCBmb3IgeW91ciBlbmRcbiAgICBjb25zdCBkZXN0cm95ZWRFdmVudCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyB0aGUgc3RlcCBwcm9ncmVzcyBpbiB0aGUgZm9vdGVyIG9mIHRoZSBzaGVwaGVyZCB0b29sdGlwXG4gICAgICovXG4gICAgY29uc3QgYXBwZW5kUHJvZ3Jlc3NGdW5jOiBGdW5jdGlvbiA9IGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgIC8vIGdldCBhbGwgdGhlIGZvb3RlcnMgdGhhdCBhcmUgYXZhaWxhYmxlIGluIHRoZSBET01cbiAgICAgIGNvbnN0IGZvb3RlcnM6IEVsZW1lbnRbXSA9IEFycmF5LmZyb208RWxlbWVudD4oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnNoZXBoZXJkLWZvb3RlcicpKTtcbiAgICAgIC8vIGdldCB0aGUgbGFzdCBmb290ZXIgc2luY2UgU2hlcGhlcmQgYWx3YXlzIHB1dHMgdGhlIGFjdGl2ZSBvbmUgYXQgdGhlIGVuZFxuICAgICAgY29uc3QgZm9vdGVyOiBFbGVtZW50ID0gZm9vdGVyc1tmb290ZXJzLmxlbmd0aCAtIDFdO1xuICAgICAgLy8gZ2VuZXJhdGUgc3RlcHMgaHRtbCBlbGVtZW50XG4gICAgICBjb25zdCBwcm9ncmVzczogSFRNTFNwYW5FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgcHJvZ3Jlc3MuY2xhc3NOYW1lID0gJ3NoZXBoZXJkLXByb2dyZXNzJztcbiAgICAgIHByb2dyZXNzLmlubmVyVGV4dCA9IGAke3RoaXMuc2hlcGhlcmRUb3VyLmN1cnJlbnRTdGVwLm9wdGlvbnMuY291bnR9LyR7c3RlcFRvdGFsfWA7XG4gICAgICAvLyBpbnNlcnQgaW50byB0aGUgZm9vdGVyIGJlZm9yZSB0aGUgZmlyc3QgYnV0dG9uXG4gICAgICBmb290ZXIuaW5zZXJ0QmVmb3JlKHByb2dyZXNzLCBmb290ZXIucXVlcnlTZWxlY3RvcignLnNoZXBoZXJkLWJ1dHRvbicpKTtcbiAgICB9O1xuXG4gICAgbGV0IHN0ZXBUb3RhbDogbnVtYmVyID0gMDtcbiAgICBjb25zdCBzdGVwczogSVRvdXJTdGVwW10gPSBvcmlnaW5hbFN0ZXBzLm1hcCgoc3RlcDogSVRvdXJTdGVwKSA9PiB7XG4gICAgICBsZXQgc2hvd1Byb2dyZXNzOiBGdW5jdGlvbjtcbiAgICAgIGlmIChzdGVwLmF0dGFjaFRvT3B0aW9ucz8uc2tpcEZyb21TdGVwQ291bnQgPT09IHRydWUpIHtcbiAgICAgICAgc2hvd1Byb2dyZXNzID0gZnVuY3Rpb24gKCk6IHZvaWQge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHN0ZXAuYXR0YWNoVG9PcHRpb25zPy5za2lwRnJvbVN0ZXBDb3VudCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHN0ZXAuYXR0YWNoVG9PcHRpb25zPy5za2lwRnJvbVN0ZXBDb3VudCA9PT0gZmFsc2VcbiAgICAgICkge1xuICAgICAgICBzdGVwLmNvdW50ID0gKytzdGVwVG90YWw7XG4gICAgICAgIHNob3dQcm9ncmVzcyA9IGFwcGVuZFByb2dyZXNzRnVuYy5iaW5kKHRoaXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0ZXAsIHtcbiAgICAgICAgd2hlbjoge1xuICAgICAgICAgIHNob3c6IHNob3dQcm9ncmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgZmluaXNoQnV0dG9uOiBUb3VyU3RlcEJ1dHRvbiA9IHtcbiAgICAgIHRleHQ6IGZpbmlzaExhYmVsLFxuICAgICAgYWN0aW9uOiB0aGlzWydmaW5pc2gnXS5iaW5kKHRoaXMpLFxuICAgICAgY2xhc3NlczogTUFUX0JVVFRPTixcbiAgICB9O1xuXG4gICAgY29uc3Qgdm9pZEJ1dHRvbjogVG91clN0ZXBCdXR0b24gPSB7XG4gICAgICB0ZXh0OiAnJyxcbiAgICAgIGFjdGlvbigpOiB2b2lkIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSxcbiAgICAgIGNsYXNzZXM6IE1BVF9CVVRUT05fSU5WSVNJQkxFLFxuICAgIH07XG5cbiAgICAvLyBsaXN0ZW4gdG8gdGhlIGRlc3Ryb3llZCBldmVudCB0byBjbGVhbiB1cCBhbGwgdGhlIHN0cmVhbXNcbiAgICB0aGlzLl9kZXN0cm95ZWRFdmVudCQucGlwZShmaXJzdCgpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgYmFja0V2ZW50JC5jb21wbGV0ZSgpO1xuICAgICAgZm9yd2FyZEV2ZW50JC5jb21wbGV0ZSgpO1xuICAgICAgZGVzdHJveWVkRXZlbnQkLm5leHQoKTtcbiAgICAgIGRlc3Ryb3llZEV2ZW50JC5jb21wbGV0ZSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgdG90YWxTdGVwczogbnVtYmVyID0gc3RlcHMubGVuZ3RoO1xuICAgIHN0ZXBzLmZvckVhY2goKHN0ZXA6IElUb3VyU3RlcCwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgLy8gY3JlYXRlIGJ1dHRvbnMgc3BlY2lmaWMgZm9yIHRoZSBzdGVwXG4gICAgICAvLyB0aGlzIGlzIGRvbmUgdG8gY3JlYXRlIG1vcmUgY29udHJvbCBvbiBldmVudHNcbiAgICAgIGNvbnN0IG5leHRCdXR0b246IFRvdXJTdGVwQnV0dG9uID0ge1xuICAgICAgICB0ZXh0OiAnY2hldnJvbl9yaWdodCcsXG4gICAgICAgIGFjdGlvbjogKCkgPT4ge1xuICAgICAgICAgIC8vIGludGVyY2VwdCB0aGUgbmV4dCBhY3Rpb24gYW5kIHRyaWdnZXIgZXZlbnRcbiAgICAgICAgICBmb3J3YXJkRXZlbnQkLm5leHQoKTtcbiAgICAgICAgICB0aGlzLnNoZXBoZXJkVG91ci5uZXh0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIGNsYXNzZXM6IE1BVF9JQ09OX0JVVFRPTixcbiAgICAgIH07XG4gICAgICBjb25zdCBiYWNrQnV0dG9uOiBUb3VyU3RlcEJ1dHRvbiA9IHtcbiAgICAgICAgdGV4dDogJ2NoZXZyb25fbGVmdCcsXG4gICAgICAgIGFjdGlvbjogKCkgPT4ge1xuICAgICAgICAgIC8vIGludGVyY2VwdCB0aGUgYmFjayBhY3Rpb24gYW5kIHRyaWdnZXIgZXZlbnRcbiAgICAgICAgICBiYWNrRXZlbnQkLm5leHQoKTtcbiAgICAgICAgICBfYmFja0Zsb3cgPSB0cnVlO1xuICAgICAgICAgIC8vIGNoZWNrIGlmICdnb0JhY2tUbycgaXMgc2V0IHRvIGp1bXAgdG8gYSBwYXJ0aWN1bGFyIHN0ZXAsIGVsc2UganVzdCBnbyBiYWNrXG4gICAgICAgICAgaWYgKHN0ZXAuYXR0YWNoVG9PcHRpb25zICYmIHN0ZXAuYXR0YWNoVG9PcHRpb25zLmdvQmFja1RvKSB7XG4gICAgICAgICAgICB0aGlzLnNoZXBoZXJkVG91ci5zaG93KHN0ZXAuYXR0YWNoVG9PcHRpb25zLmdvQmFja1RvLCBmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2hlcGhlcmRUb3VyLmJhY2soKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNsYXNzZXM6IHN0ZXAuYWR2YW5jZU9uT3B0aW9ucz8uYWxsb3dHb0JhY2sgPT09IGZhbHNlID8gTUFUX0JVVFRPTl9JTlZJU0lCTEUgOiBNQVRfSUNPTl9CVVRUT04sXG4gICAgICB9O1xuXG4gICAgICAvLyBjaGVjayBpZiBoaWdobGlnaHQgd2FzIHByb3ZpZGVkIGZvciB0aGUgc3RlcCwgZWxzZSBmYWxsYmFjayBpbnRvIHNoZXBoZXJkcyB1c2FnZVxuICAgICAgc3RlcC5oaWdobGlnaHRDbGFzcyA9XG4gICAgICAgIHN0ZXAuYXR0YWNoVG9PcHRpb25zICYmIHN0ZXAuYXR0YWNoVG9PcHRpb25zLmhpZ2hsaWdodCA/ICdzaGVwaGVyZC1oaWdobGlnaHQnIDogc3RlcC5oaWdobGlnaHRDbGFzcztcblxuICAgICAgLy8gQWRkaW5nIGJ1dHRvbnMgaW4gdGhlIHN0ZXBzIGlmIG5vIGJ1dHRvbnMgYXJlIGRlZmluZWRcbiAgICAgIGlmICghc3RlcC5idXR0b25zIHx8IHN0ZXAuYnV0dG9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgLy8gZmlyc3Qgc3RlcFxuICAgICAgICAgIHN0ZXAuYnV0dG9ucyA9IFtuZXh0QnV0dG9uXTtcbiAgICAgICAgfSBlbHNlIGlmIChpbmRleCA9PT0gdG90YWxTdGVwcyAtIDEpIHtcbiAgICAgICAgICAvLyBsYXN0IHN0ZXBcbiAgICAgICAgICBzdGVwLmJ1dHRvbnMgPSBbYmFja0J1dHRvbiwgZmluaXNoQnV0dG9uXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdGVwLmJ1dHRvbnMgPSBbYmFja0J1dHRvbiwgbmV4dEJ1dHRvbl07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gY2hlY2tzIFwiYWR2YW5jZU9uXCIgdG8gb3ZlcnJpZGUgbGlzdGVuZXJzXG4gICAgICBsZXQgYWR2YW5jZU9uOiBJVG91clN0ZXBBZHZhbmNlT25bXSB8IElUb3VyU3RlcEFkdmFuY2VPbiA9IHN0ZXAuYWR2YW5jZU9uO1xuICAgICAgLy8gcmVtb3ZlIHRoZSBzaGVwaGVyZCBcImFkdmFuY2VPblwiIGluZmF2b3Igb2Ygb3VycyBpZiB0aGUgZXZlbnQgaXMgcGFydCBvZiBvdXIgbGlzdFxuICAgICAgaWYgKFxuICAgICAgICAodHlwZW9mIGFkdmFuY2VPbiA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAhQXJyYXkuaXNBcnJheShhZHZhbmNlT24pICYmXG4gICAgICAgICAgb3ZlcnJpZGRlbkV2ZW50cy5pbmRleE9mKGFkdmFuY2VPbi5ldmVudC5zcGxpdCgnLicpWzBdKSA+IC0xKSB8fFxuICAgICAgICBhZHZhbmNlT24gaW5zdGFuY2VvZiBBcnJheVxuICAgICAgKSB7XG4gICAgICAgIHN0ZXAuYWR2YW5jZU9uID0gdW5kZWZpbmVkO1xuICAgICAgICBzdGVwLmJ1dHRvbnMgPVxuICAgICAgICAgIHN0ZXAuYWR2YW5jZU9uT3B0aW9ucyAmJiBzdGVwLmFkdmFuY2VPbk9wdGlvbnMuYWxsb3dHb0JhY2sgPyBbYmFja0J1dHRvbiwgdm9pZEJ1dHRvbl0gOiBbdm9pZEJ1dHRvbl07XG4gICAgICB9XG4gICAgICAvLyBhZGRzIGEgZGVmYXVsdCBiZWZvcmVTaG93UHJvbWlzZSBmdW5jdGlvblxuICAgICAgc3RlcC5iZWZvcmVTaG93UHJvbWlzZSA9ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlOiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgICAgICAgY29uc3QgYWRkaXRpb25hbENhcGFiaWxpdGllc1NldHVwOiBGdW5jdGlvbiA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChhZHZhbmNlT24gJiYgIXN0ZXAuYWR2YW5jZU9uKSB7XG4gICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhZHZhbmNlT24pKSB7XG4gICAgICAgICAgICAgICAgYWR2YW5jZU9uID0gW2FkdmFuY2VPbl07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBhZHZhbmNlQXJyJDogU3ViamVjdDx2b2lkPltdID0gW107XG4gICAgICAgICAgICAgIGFkdmFuY2VPbi5mb3JFYWNoKChfOiBhbnksIGk6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFkdmFuY2VFdmVudCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgICAgICAgICAgICAgIGFkdmFuY2VBcnIkLnB1c2goYWR2YW5jZUV2ZW50JCk7XG4gICAgICAgICAgICAgICAgLy8gd2Ugc3RhcnQgYSB0aW1lciBvZiBhdHRlbXB0cyB0byBmaW5kIGFuIGVsZW1lbnQgaW4gdGhlIGRvbVxuICAgICAgICAgICAgICAgIHRoaXMuX2JpbmRFdmVudChhZHZhbmNlT25baV0sIHN0ZXAuYWR2YW5jZU9uT3B0aW9ucywgYWR2YW5jZUV2ZW50JCwgZGVzdHJveWVkRXZlbnQkKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGNvbnN0IGFkdmFuY2VTdWJzOiBTdWJzY3JpcHRpb24gPSBmb3JrSm9pbiguLi5hZHZhbmNlQXJyJClcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwobWVyZ2UoZGVzdHJveWVkRXZlbnQkLCBiYWNrRXZlbnQkKSkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBuZWVkIHRvIGFkdmFuY2UgdG8gYSBzcGVjaWZpYyBzdGVwLCBlbHNlIGFkdmFuY2UgdG8gbmV4dCBzdGVwXG4gICAgICAgICAgICAgICAgICBpZiAoc3RlcC5hZHZhbmNlT25PcHRpb25zICYmIHN0ZXAuYWR2YW5jZU9uT3B0aW9ucy5qdW1wVG8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaGVwaGVyZFRvdXIuc2hvdyhzdGVwLmFkdmFuY2VPbk9wdGlvbnMuanVtcFRvKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hlcGhlcmRUb3VyLm5leHQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGZvcndhcmRFdmVudCQubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgYWR2YW5jZVN1YnMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaWYgYWJvcnRPbiB3YXMgcGFzc2VkIG9uIHRoZSBzdGVwLCB3ZSBiaW5kIHRoZSBldmVudCBhbmQgZXhlY3V0ZSBjb21wbGV0ZVxuICAgICAgICAgICAgaWYgKHN0ZXAuYWJvcnRPbikge1xuICAgICAgICAgICAgICBjb25zdCBhYm9ydEFyciQ6IFN1YmplY3Q8dm9pZD5bXSA9IFtdO1xuICAgICAgICAgICAgICBzdGVwLmFib3J0T24uZm9yRWFjaCgoYWJvcnRPbjogSVRvdXJBYm9ydE9uKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYWJvcnRFdmVudCQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgICAgICAgICAgICAgIGFib3J0QXJyJC5wdXNoKGFib3J0RXZlbnQkKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9iaW5kRXZlbnQoYWJvcnRPbiwgdW5kZWZpbmVkLCBhYm9ydEV2ZW50JCwgZGVzdHJveWVkRXZlbnQkKTtcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY29uc3QgYWJvcnRTdWJzOiBTdWJzY3JpcHRpb24gPSBtZXJnZSguLi5hYm9ydEFyciQpXG4gICAgICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKG1lcmdlKGRlc3Ryb3llZEV2ZW50JCwgYmFja0V2ZW50JCwgZm9yd2FyZEV2ZW50JCkpKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5zaGVwaGVyZFRvdXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgIGFib3J0U3Vicy51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCBfc3RvcFRpbWVyJDogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gICAgICAgICAgY29uc3QgX3JldHJpZXNSZWFjaGVkJDogU3ViamVjdDxudW1iZXI+ID0gbmV3IFN1YmplY3Q8bnVtYmVyPigpO1xuICAgICAgICAgIGNvbnN0IF9yZXRyeUF0dGVtcHRzJDogQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oLTEpO1xuXG4gICAgICAgICAgbGV0IGlkOiBzdHJpbmc7XG4gICAgICAgICAgLy8gY2hlY2tzIGlmIFwiYXR0YWNoVG9cIiBpcyBhIHN0cmluZyBvciBhbiBvYmplY3QgdG8gZ2V0IHRoZSBpZCBvZiBhbiBlbGVtZW50XG4gICAgICAgICAgaWYgKHR5cGVvZiBzdGVwLmF0dGFjaFRvID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgaWQgPSBzdGVwLmF0dGFjaFRvO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0ZXAuYXR0YWNoVG8gPT09ICdvYmplY3QnICYmIHR5cGVvZiBzdGVwLmF0dGFjaFRvLmVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZCA9IHN0ZXAuYXR0YWNoVG8uZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gaWYgd2UgaGF2ZSBhbiBpZCBhcyBhIHN0cmluZyBpbiBlaXRoZXIgY2FzZSwgd2UgdXNlIGl0ICh3ZSBpZ25vcmUgaXQgaWYgaXRzIEhUTUxFbGVtZW50KVxuICAgICAgICAgIGlmIChpZCkge1xuICAgICAgICAgICAgLy8gaWYgY3VycmVudCBzdGVwIGlzIHRoZSBmaXJzdCBzdGVwIG9mIHRoZSB0b3VyLCB3ZSBzZXQgdGhlIGJ1dHRvbnMgdG8gYmUgb25seSBcIm5leHRcIlxuICAgICAgICAgICAgLy8gd2UgaGFkIHRvIHVzZSBgYW55YCBzaW5jZSB0aGUgdG91ciBkb2VzbnQgZXhwb3NlIHRoZSBzdGVwcyBpbiBhbnkgZmFzaGlvbiBub3IgYSB3YXkgdG8gY2hlY2sgaWYgd2UgaGF2ZSBtb2RpZmllZCB0aGVtIGF0IGFsbFxuICAgICAgICAgICAgaWYgKHRoaXMuc2hlcGhlcmRUb3VyLmdldEN1cnJlbnRTdGVwKCkgPT09ICg8YW55PnRoaXMuc2hlcGhlcmRUb3VyKS5zdGVwc1swXSkge1xuICAgICAgICAgICAgICB0aGlzLnNoZXBoZXJkVG91ci5nZXRDdXJyZW50U3RlcCgpLnVwZGF0ZVN0ZXBPcHRpb25zKHtcbiAgICAgICAgICAgICAgICBidXR0b25zOiBvcmlnaW5hbFN0ZXBzW2luZGV4XS5hZHZhbmNlT24gPyBbdm9pZEJ1dHRvbl0gOiBbbmV4dEJ1dHRvbl0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcmVnaXN0ZXIgdG8gdGhlIGF0dGVtcHRzIG9ic2VydmFibGUgdG8gbm90aWZ5IGRlZXZlbG9wZXIgd2hlbiBudW1iZXIgaGFzIGJlZW4gcmVhY2hlZFxuICAgICAgICAgICAgX3JldHJ5QXR0ZW1wdHMkXG4gICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHNraXAoMSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKG1lcmdlKF9zdG9wVGltZXIkLmFzT2JzZXJ2YWJsZSgpLCBkZXN0cm95ZWRFdmVudCQpKSxcbiAgICAgICAgICAgICAgICBza2lwV2hpbGUoKHZhbDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoc3RlcC5hdHRhY2hUb09wdGlvbnMgJiYgc3RlcC5hdHRhY2hUb09wdGlvbnMucmV0cmllcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWwgPCBzdGVwLmF0dGFjaFRvT3B0aW9ucy5yZXRyaWVzO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbCA8IFNIRVBIRVJEX0RFRkFVTFRfRklORF9BVFRFTVBUUztcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAuc3Vic2NyaWJlKChhdHRlbXB0czogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgX3JldHJpZXNSZWFjaGVkJC5uZXh0KCk7XG4gICAgICAgICAgICAgICAgX3JldHJpZXNSZWFjaGVkJC5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgIC8vIGlmIGF0dGVtcHRzIGhhdmUgYmVlbiByZWFjaGVkLCB3ZSBjaGVjayBcInNraXBJZk5vdEZvdW5kXCIgdG8gbW92ZSBvbiB0byB0aGUgbmV4dCBzdGVwXG4gICAgICAgICAgICAgICAgaWYgKHN0ZXAuYXR0YWNoVG9PcHRpb25zICYmIHN0ZXAuYXR0YWNoVG9PcHRpb25zLnNraXBJZk5vdEZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBnZXQgdG8gdGhpcyBzdGVwIGNvbWluZyBiYWNrIGZyb20gYSBzdGVwIGFuZCBpdCB3YXNudCBmb3VuZFxuICAgICAgICAgICAgICAgICAgLy8gdGhlbiB3ZSBlaXRoZXIgY2hlY2sgaWYgaXRzIHRoZSBmaXJzdCBzdGVwIGFuZCB0cnkgZ29pbmcgZm9yd2FyZFxuICAgICAgICAgICAgICAgICAgLy8gb3Igd2Uga2VlcCBnb2luZyBiYWNrIHVudGlsIHdlIGZpbmQgYSBzdGVwIHRoYXQgYWN0dWFsbHkgZXhpc3RzXG4gICAgICAgICAgICAgICAgICBpZiAoX2JhY2tGbG93KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoPGFueT50aGlzLnNoZXBoZXJkVG91cikuc3RlcHMuaW5kZXhPZih0aGlzLnNoZXBoZXJkVG91ci5nZXRDdXJyZW50U3RlcCgpKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2hlcGhlcmRUb3VyLm5leHQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNoZXBoZXJkVG91ci5iYWNrKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgX2JhY2tGbG93ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBkZXN0cm95cyBjdXJyZW50IHN0ZXAgaWYgd2UgbmVlZCB0byBza2lwIGl0IHRvIHJlbW92ZSBpdCBmcm9tIHRoZSB0b3VyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwOiBTaGVwaGVyZC5TdGVwID0gdGhpcy5zaGVwaGVyZFRvdXIuZ2V0Q3VycmVudFN0ZXAoKTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFN0ZXAuZGVzdHJveSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNoZXBoZXJkVG91ci5uZXh0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hlcGhlcmRUb3VyLnJlbW92ZVN0ZXAoKDxTaGVwaGVyZC5TdGVwLlN0ZXBPcHRpb25zPmN1cnJlbnRTdGVwKS5pZCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGVwLmF0dGFjaFRvT3B0aW9ucyAmJiBzdGVwLmF0dGFjaFRvT3B0aW9ucy5lbHNlKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpZiBcInNraXBJZk5vdEZvdW5kXCIgaXMgbm90IHRydWUsIHRoZW4gd2UgY2hlY2sgaWYgXCJlbHNlXCIgaGFzIGJlZW4gc2V0IHRvIGp1bXAgdG8gYSBzcGVjaWZpYyBzdGVwXG4gICAgICAgICAgICAgICAgICB0aGlzLnNoZXBoZXJkVG91ci5zaG93KHN0ZXAuYXR0YWNoVG9PcHRpb25zLmVsc2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tY29uc29sZVxuICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBSZXRyaWVzIHJlYWNoZWQgdHJ5aW5nIHRvIGZpbmQgJHtpZH0uIFJldHJpZWQgICR7YXR0ZW1wdHN9IHRpbWVzLmApO1xuICAgICAgICAgICAgICAgICAgLy8gZWxzZSB3ZSBzaG93IHRoZSBzdGVwIHJlZ2FyZGxlc3NcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyB3ZSBzdGFydCBhIHRpbWVyIG9mIGF0dGVtcHRzIHRvIGZpbmQgYW4gZWxlbWVudCBpbiB0aGUgZG9tXG4gICAgICAgICAgICB0aW1lcihcbiAgICAgICAgICAgICAgKHN0ZXAuYXR0YWNoVG9PcHRpb25zICYmIHN0ZXAuYXR0YWNoVG9PcHRpb25zLnRpbWVCZWZvcmVTaG93KSB8fCBTSEVQSEVSRF9ERUZBVUxUX0ZJTkRfVElNRV9CRUZPUkVfU0hPVyxcbiAgICAgICAgICAgICAgKHN0ZXAuYXR0YWNoVG9PcHRpb25zICYmIHN0ZXAuYXR0YWNoVG9PcHRpb25zLmludGVydmFsKSB8fCBTSEVQSEVSRF9ERUZBVUxUX0ZJTkRfSU5URVJWQUwsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIC8vIHRoZSB0aW1lciB3aWxsIGNvbnRpbnVlIGVpdGhlciB1bnRpbCB3ZSBmaW5kIHRoZSBlbGVtZW50IG9yIHRoZSBudW1iZXIgb2YgYXR0ZW1wdHMgaGFzIGJlZW4gcmVhY2hlZFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbChtZXJnZShfc3RvcFRpbWVyJCwgX3JldHJpZXNSZWFjaGVkJCwgZGVzdHJveWVkRXZlbnQkKSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudDogSFRNTEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGlkKTtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgZWxlbWVudCBoYXMgYmVlbiBmb3VuZCwgd2Ugc3RvcCB0aGUgdGltZXIgYW5kIHJlc29sdmUgdGhlIHByb21pc2VcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgX3N0b3BUaW1lciQubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgX3N0b3BUaW1lciQuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxDYXBhYmlsaXRpZXNTZXR1cCgpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBfcmV0cnlBdHRlbXB0cyQubmV4dChfcmV0cnlBdHRlbXB0cyQudmFsdWUgKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBzdG9wIGZpbmQgaW50ZXJ2YWwgaWYgdXNlciBzdG9wcyB0aGUgdG91clxuICAgICAgICAgICAgZGVzdHJveWVkRXZlbnQkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIF9zdG9wVGltZXIkLm5leHQoKTtcbiAgICAgICAgICAgICAgX3N0b3BUaW1lciQuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgX3JldHJpZXNSZWFjaGVkJC5uZXh0KCk7XG4gICAgICAgICAgICAgIF9yZXRyaWVzUmVhY2hlZCQuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyByZXNvbHZlIG9ic2VydmFibGUgdW50aWwgdGhlIHRpbWVCZWZvcmVTaG93IGhhcyBwYXNzc2VkIG9yIHVzZSBkZWZhdWx0XG4gICAgICAgICAgICB0aW1lcihcbiAgICAgICAgICAgICAgKHN0ZXAuYXR0YWNoVG9PcHRpb25zICYmIHN0ZXAuYXR0YWNoVG9PcHRpb25zLnRpbWVCZWZvcmVTaG93KSB8fCBTSEVQSEVSRF9ERUZBVUxUX0ZJTkRfVElNRV9CRUZPUkVfU0hPVyxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKG1lcmdlKGRlc3Ryb3llZEV2ZW50JCkpKVxuICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH0pO1xuICAgIHJldHVybiBzdGVwcztcbiAgfVxuXG4gIHByaXZhdGUgX2JpbmRFdmVudChcbiAgICBldmVudE9uOiBJVG91ckV2ZW50T24sXG4gICAgZXZlbnRPbk9wdGlvbnM6IElUb3VyRXZlbnRPbk9wdGlvbnMsXG4gICAgZXZlbnQkOiBTdWJqZWN0PHZvaWQ+LFxuICAgIGRlc3Ryb3llZEV2ZW50JDogU3ViamVjdDx2b2lkPixcbiAgKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0b3I6IHN0cmluZyA9IGV2ZW50T24uc2VsZWN0b3I7XG4gICAgY29uc3QgZXZlbnQ6IHN0cmluZyA9IGV2ZW50T24uZXZlbnQ7XG4gICAgLy8gd2Ugc3RhcnQgYSB0aW1lciBvZiBhdHRlbXB0cyB0byBmaW5kIGFuIGVsZW1lbnQgaW4gdGhlIGRvbVxuICAgIGNvbnN0IHRpbWVyU3ViczogU3Vic2NyaXB0aW9uID0gdGltZXIoXG4gICAgICAoZXZlbnRPbk9wdGlvbnMgJiYgZXZlbnRPbk9wdGlvbnMudGltZUJlZm9yZVNob3cpIHx8IFNIRVBIRVJEX0RFRkFVTFRfRklORF9USU1FX0JFRk9SRV9TSE9XLFxuICAgICAgKGV2ZW50T25PcHRpb25zICYmIGV2ZW50T25PcHRpb25zLmludGVydmFsKSB8fCBTSEVQSEVSRF9ERUZBVUxUX0ZJTkRfSU5URVJWQUwsXG4gICAgKVxuICAgICAgLnBpcGUodGFrZVVudGlsKGRlc3Ryb3llZEV2ZW50JCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudDogSFRNTEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgLy8gaWYgdGhlIGVsZW1lbnQgaGFzIGJlZW4gZm91bmQsIHdlIHN0b3AgdGhlIHRpbWVyIGFuZCByZXNvbHZlIHRoZSBwcm9taXNlXG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgdGltZXJTdWJzLnVuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgICBpZiAoZXZlbnQgPT09IElUb3VyRXZlbnQuYWRkZWQpIHtcbiAgICAgICAgICAgIC8vIGlmIGV2ZW50IGlzIFwiQWRkZWRcIiB0cmlnZ2VyIGEgc29vbiBhcyB0aGlzIGlzIGF0dGFjaGVkLlxuICAgICAgICAgICAgZXZlbnQkLm5leHQoKTtcbiAgICAgICAgICAgIGV2ZW50JC5jb21wbGV0ZSgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICBldmVudCA9PT0gSVRvdXJFdmVudC5jbGljayB8fFxuICAgICAgICAgICAgZXZlbnQgPT09IElUb3VyRXZlbnQucG9pbnRlcm92ZXIgfHxcbiAgICAgICAgICAgIGV2ZW50LmluZGV4T2YoSVRvdXJFdmVudC5rZXl1cCkgPiAtMVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gd2UgdXNlIG5vcm1hbCBsaXN0ZW5lcnMgZm9yIG1vdXNlZXZlbnRzXG4gICAgICAgICAgICBjb25zdCBtYWluRXZlbnQ6IHN0cmluZyA9IGV2ZW50LnNwbGl0KCcuJylbMF07XG4gICAgICAgICAgICBjb25zdCBzdWJFdmVudDogc3RyaW5nID0gZXZlbnQuc3BsaXQoJy4nKVsxXTtcbiAgICAgICAgICAgIGZyb21FdmVudChlbGVtZW50LCBtYWluRXZlbnQpXG4gICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbChtZXJnZShldmVudCQuYXNPYnNlcnZhYmxlKCksIGRlc3Ryb3llZEV2ZW50JCkpLFxuICAgICAgICAgICAgICAgIGZpbHRlcigoJGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgLy8gb25seSB0cmlnZ2VyIGlmIHRoZSBldmVudCBpcyBhIGtleWJvYXJkIGV2ZW50IGFuZCBwYXJ0IG9mIG91dCBsaXN0XG4gICAgICAgICAgICAgICAgICBpZiAoJGV2ZW50IGluc3RhbmNlb2YgS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5RXZlbnRzLmdldCgkZXZlbnQua2V5Q29kZSkgPT09IHN1YkV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQkLm5leHQoKTtcbiAgICAgICAgICAgICAgICBldmVudCQuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChldmVudCA9PT0gSVRvdXJFdmVudC5yZW1vdmVkKSB7XG4gICAgICAgICAgICAvLyBhbmQgd2Ugd2lsbCB1c2UgTXV0YXRpb25PYnNlcnZlciBmb3IgRE9NIGV2ZW50c1xuICAgICAgICAgICAgY29uc3Qgb2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghZG9jdW1lbnQuYm9keS5jb250YWlucyhlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIGV2ZW50JC5uZXh0KCk7XG4gICAgICAgICAgICAgICAgZXZlbnQkLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gc3RvcCBsaXN0ZW5pbmluZyBpZiB0b3VyIGlzIGNsb3NlZFxuICAgICAgICAgICAgZGVzdHJveWVkRXZlbnQkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gb2JzZXJ2ZSBmb3IgYW55IERPTSBpbnRlcmFjdGlvbiBpbiB0aGUgZWxlbWVudFxuICAgICAgICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZShlbGVtZW50LCB7IGNoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZSwgYXR0cmlidXRlczogdHJ1ZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG4iXX0=
|