@angular/forms 19.0.0-next.1 → 19.0.0-next.11
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/LICENSE +21 -0
- package/fesm2022/forms.mjs +186 -132
- package/fesm2022/forms.mjs.map +1 -1
- package/index.d.ts +6 -5
- package/package.json +4 -6
- package/esm2022/forms.mjs +0 -5
- package/esm2022/index.mjs +0 -13
- package/esm2022/public_api.mjs +0 -15
- package/esm2022/src/directives/abstract_control_directive.mjs +0 -279
- package/esm2022/src/directives/abstract_form_group_directive.mjs +0 -61
- package/esm2022/src/directives/checkbox_value_accessor.mjs +0 -58
- package/esm2022/src/directives/control_container.mjs +0 -32
- package/esm2022/src/directives/control_value_accessor.mjs +0 -92
- package/esm2022/src/directives/default_value_accessor.mjs +0 -124
- package/esm2022/src/directives/error_examples.mjs +0 -57
- package/esm2022/src/directives/form_interface.mjs +0 -9
- package/esm2022/src/directives/ng_control.mjs +0 -38
- package/esm2022/src/directives/ng_control_status.mjs +0 -139
- package/esm2022/src/directives/ng_form.mjs +0 -313
- package/esm2022/src/directives/ng_model.mjs +0 -331
- package/esm2022/src/directives/ng_model_group.mjs +0 -95
- package/esm2022/src/directives/ng_no_validate_directive.mjs +0 -39
- package/esm2022/src/directives/number_value_accessor.mjs +0 -70
- package/esm2022/src/directives/radio_control_value_accessor.mjs +0 -201
- package/esm2022/src/directives/range_value_accessor.mjs +0 -72
- package/esm2022/src/directives/reactive_directives/form_control_directive.mjs +0 -183
- package/esm2022/src/directives/reactive_directives/form_control_name.mjs +0 -216
- package/esm2022/src/directives/reactive_directives/form_group_directive.mjs +0 -359
- package/esm2022/src/directives/reactive_directives/form_group_name.mjs +0 -246
- package/esm2022/src/directives/reactive_errors.mjs +0 -119
- package/esm2022/src/directives/select_control_value_accessor.mjs +0 -220
- package/esm2022/src/directives/select_multiple_control_value_accessor.mjs +0 -252
- package/esm2022/src/directives/shared.mjs +0 -350
- package/esm2022/src/directives/template_driven_errors.mjs +0 -54
- package/esm2022/src/directives/validators.mjs +0 -505
- package/esm2022/src/directives.mjs +0 -128
- package/esm2022/src/errors.mjs +0 -9
- package/esm2022/src/form_builder.mjs +0 -258
- package/esm2022/src/form_providers.mjs +0 -105
- package/esm2022/src/forms.mjs +0 -49
- package/esm2022/src/model/abstract_model.mjs +0 -992
- package/esm2022/src/model/form_array.mjs +0 -461
- package/esm2022/src/model/form_control.mjs +0 -126
- package/esm2022/src/model/form_group.mjs +0 -490
- package/esm2022/src/util.mjs +0 -13
- package/esm2022/src/validators.mjs +0 -680
- package/esm2022/src/version.mjs +0 -18
|
@@ -1,992 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { EventEmitter, signal, ɵRuntimeError as RuntimeError, untracked, computed, } from '@angular/core';
|
|
9
|
-
import { Subject } from 'rxjs';
|
|
10
|
-
import { asyncValidatorsDroppedWithOptsWarning, missingControlError, missingControlValueError, noControlsError, } from '../directives/reactive_errors';
|
|
11
|
-
import { addValidators, composeAsyncValidators, composeValidators, hasValidator, removeValidators, toObservable, } from '../validators';
|
|
12
|
-
/**
|
|
13
|
-
* Reports that a control is valid, meaning that no errors exist in the input value.
|
|
14
|
-
*
|
|
15
|
-
* @see {@link status}
|
|
16
|
-
*/
|
|
17
|
-
export const VALID = 'VALID';
|
|
18
|
-
/**
|
|
19
|
-
* Reports that a control is invalid, meaning that an error exists in the input value.
|
|
20
|
-
*
|
|
21
|
-
* @see {@link status}
|
|
22
|
-
*/
|
|
23
|
-
export const INVALID = 'INVALID';
|
|
24
|
-
/**
|
|
25
|
-
* Reports that a control is pending, meaning that async validation is occurring and
|
|
26
|
-
* errors are not yet available for the input value.
|
|
27
|
-
*
|
|
28
|
-
* @see {@link markAsPending}
|
|
29
|
-
* @see {@link status}
|
|
30
|
-
*/
|
|
31
|
-
export const PENDING = 'PENDING';
|
|
32
|
-
/**
|
|
33
|
-
* Reports that a control is disabled, meaning that the control is exempt from ancestor
|
|
34
|
-
* calculations of validity or value.
|
|
35
|
-
*
|
|
36
|
-
* @see {@link markAsDisabled}
|
|
37
|
-
* @see {@link status}
|
|
38
|
-
*/
|
|
39
|
-
export const DISABLED = 'DISABLED';
|
|
40
|
-
/**
|
|
41
|
-
* Base class for every event sent by `AbstractControl.events()`
|
|
42
|
-
*
|
|
43
|
-
* @publicApi
|
|
44
|
-
*/
|
|
45
|
-
export class ControlEvent {
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Event fired when the value of a control changes.
|
|
49
|
-
*
|
|
50
|
-
* @publicApi
|
|
51
|
-
*/
|
|
52
|
-
export class ValueChangeEvent extends ControlEvent {
|
|
53
|
-
constructor(value, source) {
|
|
54
|
-
super();
|
|
55
|
-
this.value = value;
|
|
56
|
-
this.source = source;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Event fired when the control's pristine state changes (pristine <=> dirty).
|
|
61
|
-
*
|
|
62
|
-
* @publicApi */
|
|
63
|
-
export class PristineChangeEvent extends ControlEvent {
|
|
64
|
-
constructor(pristine, source) {
|
|
65
|
-
super();
|
|
66
|
-
this.pristine = pristine;
|
|
67
|
-
this.source = source;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Event fired when the control's touched status changes (touched <=> untouched).
|
|
72
|
-
*
|
|
73
|
-
* @publicApi
|
|
74
|
-
*/
|
|
75
|
-
export class TouchedChangeEvent extends ControlEvent {
|
|
76
|
-
constructor(touched, source) {
|
|
77
|
-
super();
|
|
78
|
-
this.touched = touched;
|
|
79
|
-
this.source = source;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Event fired when the control's status changes.
|
|
84
|
-
*
|
|
85
|
-
* @publicApi
|
|
86
|
-
*/
|
|
87
|
-
export class StatusChangeEvent extends ControlEvent {
|
|
88
|
-
constructor(status, source) {
|
|
89
|
-
super();
|
|
90
|
-
this.status = status;
|
|
91
|
-
this.source = source;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Event fired when a form is submitted
|
|
96
|
-
*
|
|
97
|
-
* @publicApi
|
|
98
|
-
*/
|
|
99
|
-
export class FormSubmittedEvent extends ControlEvent {
|
|
100
|
-
constructor(source) {
|
|
101
|
-
super();
|
|
102
|
-
this.source = source;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Event fired when a form is reset.
|
|
107
|
-
*
|
|
108
|
-
* @publicApi
|
|
109
|
-
*/
|
|
110
|
-
export class FormResetEvent extends ControlEvent {
|
|
111
|
-
constructor(source) {
|
|
112
|
-
super();
|
|
113
|
-
this.source = source;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Gets validators from either an options object or given validators.
|
|
118
|
-
*/
|
|
119
|
-
export function pickValidators(validatorOrOpts) {
|
|
120
|
-
return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.validators : validatorOrOpts) || null;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Creates validator function by combining provided validators.
|
|
124
|
-
*/
|
|
125
|
-
function coerceToValidator(validator) {
|
|
126
|
-
return Array.isArray(validator) ? composeValidators(validator) : validator || null;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Gets async validators from either an options object or given validators.
|
|
130
|
-
*/
|
|
131
|
-
export function pickAsyncValidators(asyncValidator, validatorOrOpts) {
|
|
132
|
-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
133
|
-
if (isOptionsObj(validatorOrOpts) && asyncValidator) {
|
|
134
|
-
console.warn(asyncValidatorsDroppedWithOptsWarning);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.asyncValidators : asyncValidator) || null;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Creates async validator function by combining provided async validators.
|
|
141
|
-
*/
|
|
142
|
-
function coerceToAsyncValidator(asyncValidator) {
|
|
143
|
-
return Array.isArray(asyncValidator)
|
|
144
|
-
? composeAsyncValidators(asyncValidator)
|
|
145
|
-
: asyncValidator || null;
|
|
146
|
-
}
|
|
147
|
-
export function isOptionsObj(validatorOrOpts) {
|
|
148
|
-
return (validatorOrOpts != null &&
|
|
149
|
-
!Array.isArray(validatorOrOpts) &&
|
|
150
|
-
typeof validatorOrOpts === 'object');
|
|
151
|
-
}
|
|
152
|
-
export function assertControlPresent(parent, isGroup, key) {
|
|
153
|
-
const controls = parent.controls;
|
|
154
|
-
const collection = isGroup ? Object.keys(controls) : controls;
|
|
155
|
-
if (!collection.length) {
|
|
156
|
-
throw new RuntimeError(1000 /* RuntimeErrorCode.NO_CONTROLS */, typeof ngDevMode === 'undefined' || ngDevMode ? noControlsError(isGroup) : '');
|
|
157
|
-
}
|
|
158
|
-
if (!controls[key]) {
|
|
159
|
-
throw new RuntimeError(1001 /* RuntimeErrorCode.MISSING_CONTROL */, typeof ngDevMode === 'undefined' || ngDevMode ? missingControlError(isGroup, key) : '');
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
export function assertAllValuesPresent(control, isGroup, value) {
|
|
163
|
-
control._forEachChild((_, key) => {
|
|
164
|
-
if (value[key] === undefined) {
|
|
165
|
-
throw new RuntimeError(1002 /* RuntimeErrorCode.MISSING_CONTROL_VALUE */, typeof ngDevMode === 'undefined' || ngDevMode ? missingControlValueError(isGroup, key) : '');
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* This is the base class for `FormControl`, `FormGroup`, and `FormArray`.
|
|
171
|
-
*
|
|
172
|
-
* It provides some of the shared behavior that all controls and groups of controls have, like
|
|
173
|
-
* running validators, calculating status, and resetting state. It also defines the properties
|
|
174
|
-
* that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
|
|
175
|
-
* instantiated directly.
|
|
176
|
-
*
|
|
177
|
-
* The first type parameter TValue represents the value type of the control (`control.value`).
|
|
178
|
-
* The optional type parameter TRawValue represents the raw value type (`control.getRawValue()`).
|
|
179
|
-
*
|
|
180
|
-
* @see [Forms Guide](guide/forms)
|
|
181
|
-
* @see [Reactive Forms Guide](guide/forms/reactive-forms)
|
|
182
|
-
* @see [Dynamic Forms Guide](guide/forms/dynamic-forms)
|
|
183
|
-
*
|
|
184
|
-
* @publicApi
|
|
185
|
-
*/
|
|
186
|
-
export class AbstractControl {
|
|
187
|
-
/**
|
|
188
|
-
* Initialize the AbstractControl instance.
|
|
189
|
-
*
|
|
190
|
-
* @param validators The function or array of functions that is used to determine the validity of
|
|
191
|
-
* this control synchronously.
|
|
192
|
-
* @param asyncValidators The function or array of functions that is used to determine validity of
|
|
193
|
-
* this control asynchronously.
|
|
194
|
-
*/
|
|
195
|
-
constructor(validators, asyncValidators) {
|
|
196
|
-
/** @internal */
|
|
197
|
-
this._pendingDirty = false;
|
|
198
|
-
/**
|
|
199
|
-
* Indicates that a control has its own pending asynchronous validation in progress.
|
|
200
|
-
* It also stores if the control should emit events when the validation status changes.
|
|
201
|
-
*
|
|
202
|
-
* @internal
|
|
203
|
-
*/
|
|
204
|
-
this._hasOwnPendingAsyncValidator = null;
|
|
205
|
-
/** @internal */
|
|
206
|
-
this._pendingTouched = false;
|
|
207
|
-
/** @internal */
|
|
208
|
-
this._onCollectionChange = () => { };
|
|
209
|
-
this._parent = null;
|
|
210
|
-
/** @internal */
|
|
211
|
-
this._status = computed(() => this.statusReactive());
|
|
212
|
-
this.statusReactive = signal(undefined);
|
|
213
|
-
/** @internal */
|
|
214
|
-
this._pristine = computed(() => this.pristineReactive());
|
|
215
|
-
this.pristineReactive = signal(true);
|
|
216
|
-
/** @internal */
|
|
217
|
-
this._touched = computed(() => this.touchedReactive());
|
|
218
|
-
this.touchedReactive = signal(false);
|
|
219
|
-
/**
|
|
220
|
-
* Exposed as observable, see below.
|
|
221
|
-
*
|
|
222
|
-
* @internal
|
|
223
|
-
*/
|
|
224
|
-
this._events = new Subject();
|
|
225
|
-
/**
|
|
226
|
-
* A multicasting observable that emits an event every time the state of the control changes.
|
|
227
|
-
* It emits for value, status, pristine or touched changes.
|
|
228
|
-
*
|
|
229
|
-
* **Note**: On value change, the emit happens right after a value of this control is updated. The
|
|
230
|
-
* value of a parent control (for example if this FormControl is a part of a FormGroup) is updated
|
|
231
|
-
* later, so accessing a value of a parent control (using the `value` property) from the callback
|
|
232
|
-
* of this event might result in getting a value that has not been updated yet. Subscribe to the
|
|
233
|
-
* `events` of the parent control instead.
|
|
234
|
-
* For other event types, the events are emitted after the parent control has been updated.
|
|
235
|
-
*
|
|
236
|
-
*/
|
|
237
|
-
this.events = this._events.asObservable();
|
|
238
|
-
/** @internal */
|
|
239
|
-
this._onDisabledChange = [];
|
|
240
|
-
this._assignValidators(validators);
|
|
241
|
-
this._assignAsyncValidators(asyncValidators);
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Returns the function that is used to determine the validity of this control synchronously.
|
|
245
|
-
* If multiple validators have been added, this will be a single composed function.
|
|
246
|
-
* See `Validators.compose()` for additional information.
|
|
247
|
-
*/
|
|
248
|
-
get validator() {
|
|
249
|
-
return this._composedValidatorFn;
|
|
250
|
-
}
|
|
251
|
-
set validator(validatorFn) {
|
|
252
|
-
this._rawValidators = this._composedValidatorFn = validatorFn;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Returns the function that is used to determine the validity of this control asynchronously.
|
|
256
|
-
* If multiple validators have been added, this will be a single composed function.
|
|
257
|
-
* See `Validators.compose()` for additional information.
|
|
258
|
-
*/
|
|
259
|
-
get asyncValidator() {
|
|
260
|
-
return this._composedAsyncValidatorFn;
|
|
261
|
-
}
|
|
262
|
-
set asyncValidator(asyncValidatorFn) {
|
|
263
|
-
this._rawAsyncValidators = this._composedAsyncValidatorFn = asyncValidatorFn;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* The parent control.
|
|
267
|
-
*/
|
|
268
|
-
get parent() {
|
|
269
|
-
return this._parent;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* The validation status of the control.
|
|
273
|
-
*
|
|
274
|
-
* @see {@link FormControlStatus}
|
|
275
|
-
*
|
|
276
|
-
* These status values are mutually exclusive, so a control cannot be
|
|
277
|
-
* both valid AND invalid or invalid AND disabled.
|
|
278
|
-
*/
|
|
279
|
-
get status() {
|
|
280
|
-
return untracked(this.statusReactive);
|
|
281
|
-
}
|
|
282
|
-
set status(v) {
|
|
283
|
-
untracked(() => this.statusReactive.set(v));
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* A control is `valid` when its `status` is `VALID`.
|
|
287
|
-
*
|
|
288
|
-
* @see {@link AbstractControl.status}
|
|
289
|
-
*
|
|
290
|
-
* @returns True if the control has passed all of its validation tests,
|
|
291
|
-
* false otherwise.
|
|
292
|
-
*/
|
|
293
|
-
get valid() {
|
|
294
|
-
return this.status === VALID;
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* A control is `invalid` when its `status` is `INVALID`.
|
|
298
|
-
*
|
|
299
|
-
* @see {@link AbstractControl.status}
|
|
300
|
-
*
|
|
301
|
-
* @returns True if this control has failed one or more of its validation checks,
|
|
302
|
-
* false otherwise.
|
|
303
|
-
*/
|
|
304
|
-
get invalid() {
|
|
305
|
-
return this.status === INVALID;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* A control is `pending` when its `status` is `PENDING`.
|
|
309
|
-
*
|
|
310
|
-
* @see {@link AbstractControl.status}
|
|
311
|
-
*
|
|
312
|
-
* @returns True if this control is in the process of conducting a validation check,
|
|
313
|
-
* false otherwise.
|
|
314
|
-
*/
|
|
315
|
-
get pending() {
|
|
316
|
-
return this.status == PENDING;
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* A control is `disabled` when its `status` is `DISABLED`.
|
|
320
|
-
*
|
|
321
|
-
* Disabled controls are exempt from validation checks and
|
|
322
|
-
* are not included in the aggregate value of their ancestor
|
|
323
|
-
* controls.
|
|
324
|
-
*
|
|
325
|
-
* @see {@link AbstractControl.status}
|
|
326
|
-
*
|
|
327
|
-
* @returns True if the control is disabled, false otherwise.
|
|
328
|
-
*/
|
|
329
|
-
get disabled() {
|
|
330
|
-
return this.status === DISABLED;
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* A control is `enabled` as long as its `status` is not `DISABLED`.
|
|
334
|
-
*
|
|
335
|
-
* @returns True if the control has any status other than 'DISABLED',
|
|
336
|
-
* false if the status is 'DISABLED'.
|
|
337
|
-
*
|
|
338
|
-
* @see {@link AbstractControl.status}
|
|
339
|
-
*
|
|
340
|
-
*/
|
|
341
|
-
get enabled() {
|
|
342
|
-
return this.status !== DISABLED;
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* A control is `pristine` if the user has not yet changed
|
|
346
|
-
* the value in the UI.
|
|
347
|
-
*
|
|
348
|
-
* @returns True if the user has not yet changed the value in the UI; compare `dirty`.
|
|
349
|
-
* Programmatic changes to a control's value do not mark it dirty.
|
|
350
|
-
*/
|
|
351
|
-
get pristine() {
|
|
352
|
-
return untracked(this.pristineReactive);
|
|
353
|
-
}
|
|
354
|
-
set pristine(v) {
|
|
355
|
-
untracked(() => this.pristineReactive.set(v));
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* A control is `dirty` if the user has changed the value
|
|
359
|
-
* in the UI.
|
|
360
|
-
*
|
|
361
|
-
* @returns True if the user has changed the value of this control in the UI; compare `pristine`.
|
|
362
|
-
* Programmatic changes to a control's value do not mark it dirty.
|
|
363
|
-
*/
|
|
364
|
-
get dirty() {
|
|
365
|
-
return !this.pristine;
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* True if the control is marked as `touched`.
|
|
369
|
-
*
|
|
370
|
-
* A control is marked `touched` once the user has triggered
|
|
371
|
-
* a `blur` event on it.
|
|
372
|
-
*/
|
|
373
|
-
get touched() {
|
|
374
|
-
return untracked(this.touchedReactive);
|
|
375
|
-
}
|
|
376
|
-
set touched(v) {
|
|
377
|
-
untracked(() => this.touchedReactive.set(v));
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* True if the control has not been marked as touched
|
|
381
|
-
*
|
|
382
|
-
* A control is `untouched` if the user has not yet triggered
|
|
383
|
-
* a `blur` event on it.
|
|
384
|
-
*/
|
|
385
|
-
get untouched() {
|
|
386
|
-
return !this.touched;
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Reports the update strategy of the `AbstractControl` (meaning
|
|
390
|
-
* the event on which the control updates itself).
|
|
391
|
-
* Possible values: `'change'` | `'blur'` | `'submit'`
|
|
392
|
-
* Default value: `'change'`
|
|
393
|
-
*/
|
|
394
|
-
get updateOn() {
|
|
395
|
-
return this._updateOn ? this._updateOn : this.parent ? this.parent.updateOn : 'change';
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Sets the synchronous validators that are active on this control. Calling
|
|
399
|
-
* this overwrites any existing synchronous validators.
|
|
400
|
-
*
|
|
401
|
-
* When you add or remove a validator at run time, you must call
|
|
402
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
403
|
-
*
|
|
404
|
-
* If you want to add a new validator without affecting existing ones, consider
|
|
405
|
-
* using `addValidators()` method instead.
|
|
406
|
-
*/
|
|
407
|
-
setValidators(validators) {
|
|
408
|
-
this._assignValidators(validators);
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Sets the asynchronous validators that are active on this control. Calling this
|
|
412
|
-
* overwrites any existing asynchronous validators.
|
|
413
|
-
*
|
|
414
|
-
* When you add or remove a validator at run time, you must call
|
|
415
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
416
|
-
*
|
|
417
|
-
* If you want to add a new validator without affecting existing ones, consider
|
|
418
|
-
* using `addAsyncValidators()` method instead.
|
|
419
|
-
*/
|
|
420
|
-
setAsyncValidators(validators) {
|
|
421
|
-
this._assignAsyncValidators(validators);
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Add a synchronous validator or validators to this control, without affecting other validators.
|
|
425
|
-
*
|
|
426
|
-
* When you add or remove a validator at run time, you must call
|
|
427
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
428
|
-
*
|
|
429
|
-
* Adding a validator that already exists will have no effect. If duplicate validator functions
|
|
430
|
-
* are present in the `validators` array, only the first instance would be added to a form
|
|
431
|
-
* control.
|
|
432
|
-
*
|
|
433
|
-
* @param validators The new validator function or functions to add to this control.
|
|
434
|
-
*/
|
|
435
|
-
addValidators(validators) {
|
|
436
|
-
this.setValidators(addValidators(validators, this._rawValidators));
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Add an asynchronous validator or validators to this control, without affecting other
|
|
440
|
-
* validators.
|
|
441
|
-
*
|
|
442
|
-
* When you add or remove a validator at run time, you must call
|
|
443
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
444
|
-
*
|
|
445
|
-
* Adding a validator that already exists will have no effect.
|
|
446
|
-
*
|
|
447
|
-
* @param validators The new asynchronous validator function or functions to add to this control.
|
|
448
|
-
*/
|
|
449
|
-
addAsyncValidators(validators) {
|
|
450
|
-
this.setAsyncValidators(addValidators(validators, this._rawAsyncValidators));
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Remove a synchronous validator from this control, without affecting other validators.
|
|
454
|
-
* Validators are compared by function reference; you must pass a reference to the exact same
|
|
455
|
-
* validator function as the one that was originally set. If a provided validator is not found,
|
|
456
|
-
* it is ignored.
|
|
457
|
-
*
|
|
458
|
-
* @usageNotes
|
|
459
|
-
*
|
|
460
|
-
* ### Reference to a ValidatorFn
|
|
461
|
-
*
|
|
462
|
-
* ```
|
|
463
|
-
* // Reference to the RequiredValidator
|
|
464
|
-
* const ctrl = new FormControl<string | null>('', Validators.required);
|
|
465
|
-
* ctrl.removeValidators(Validators.required);
|
|
466
|
-
*
|
|
467
|
-
* // Reference to anonymous function inside MinValidator
|
|
468
|
-
* const minValidator = Validators.min(3);
|
|
469
|
-
* const ctrl = new FormControl<string | null>('', minValidator);
|
|
470
|
-
* expect(ctrl.hasValidator(minValidator)).toEqual(true)
|
|
471
|
-
* expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)
|
|
472
|
-
*
|
|
473
|
-
* ctrl.removeValidators(minValidator);
|
|
474
|
-
* ```
|
|
475
|
-
*
|
|
476
|
-
* When you add or remove a validator at run time, you must call
|
|
477
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
478
|
-
*
|
|
479
|
-
* @param validators The validator or validators to remove.
|
|
480
|
-
*/
|
|
481
|
-
removeValidators(validators) {
|
|
482
|
-
this.setValidators(removeValidators(validators, this._rawValidators));
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Remove an asynchronous validator from this control, without affecting other validators.
|
|
486
|
-
* Validators are compared by function reference; you must pass a reference to the exact same
|
|
487
|
-
* validator function as the one that was originally set. If a provided validator is not found, it
|
|
488
|
-
* is ignored.
|
|
489
|
-
*
|
|
490
|
-
* When you add or remove a validator at run time, you must call
|
|
491
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
492
|
-
*
|
|
493
|
-
* @param validators The asynchronous validator or validators to remove.
|
|
494
|
-
*/
|
|
495
|
-
removeAsyncValidators(validators) {
|
|
496
|
-
this.setAsyncValidators(removeValidators(validators, this._rawAsyncValidators));
|
|
497
|
-
}
|
|
498
|
-
/**
|
|
499
|
-
* Check whether a synchronous validator function is present on this control. The provided
|
|
500
|
-
* validator must be a reference to the exact same function that was provided.
|
|
501
|
-
*
|
|
502
|
-
* @usageNotes
|
|
503
|
-
*
|
|
504
|
-
* ### Reference to a ValidatorFn
|
|
505
|
-
*
|
|
506
|
-
* ```
|
|
507
|
-
* // Reference to the RequiredValidator
|
|
508
|
-
* const ctrl = new FormControl<number | null>(0, Validators.required);
|
|
509
|
-
* expect(ctrl.hasValidator(Validators.required)).toEqual(true)
|
|
510
|
-
*
|
|
511
|
-
* // Reference to anonymous function inside MinValidator
|
|
512
|
-
* const minValidator = Validators.min(3);
|
|
513
|
-
* const ctrl = new FormControl<number | null>(0, minValidator);
|
|
514
|
-
* expect(ctrl.hasValidator(minValidator)).toEqual(true)
|
|
515
|
-
* expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)
|
|
516
|
-
* ```
|
|
517
|
-
*
|
|
518
|
-
* @param validator The validator to check for presence. Compared by function reference.
|
|
519
|
-
* @returns Whether the provided validator was found on this control.
|
|
520
|
-
*/
|
|
521
|
-
hasValidator(validator) {
|
|
522
|
-
return hasValidator(this._rawValidators, validator);
|
|
523
|
-
}
|
|
524
|
-
/**
|
|
525
|
-
* Check whether an asynchronous validator function is present on this control. The provided
|
|
526
|
-
* validator must be a reference to the exact same function that was provided.
|
|
527
|
-
*
|
|
528
|
-
* @param validator The asynchronous validator to check for presence. Compared by function
|
|
529
|
-
* reference.
|
|
530
|
-
* @returns Whether the provided asynchronous validator was found on this control.
|
|
531
|
-
*/
|
|
532
|
-
hasAsyncValidator(validator) {
|
|
533
|
-
return hasValidator(this._rawAsyncValidators, validator);
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Empties out the synchronous validator list.
|
|
537
|
-
*
|
|
538
|
-
* When you add or remove a validator at run time, you must call
|
|
539
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
540
|
-
*
|
|
541
|
-
*/
|
|
542
|
-
clearValidators() {
|
|
543
|
-
this.validator = null;
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Empties out the async validator list.
|
|
547
|
-
*
|
|
548
|
-
* When you add or remove a validator at run time, you must call
|
|
549
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
550
|
-
*
|
|
551
|
-
*/
|
|
552
|
-
clearAsyncValidators() {
|
|
553
|
-
this.asyncValidator = null;
|
|
554
|
-
}
|
|
555
|
-
markAsTouched(opts = {}) {
|
|
556
|
-
const changed = this.touched === false;
|
|
557
|
-
this.touched = true;
|
|
558
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
559
|
-
if (this._parent && !opts.onlySelf) {
|
|
560
|
-
this._parent.markAsTouched({ ...opts, sourceControl });
|
|
561
|
-
}
|
|
562
|
-
if (changed && opts.emitEvent !== false) {
|
|
563
|
-
this._events.next(new TouchedChangeEvent(true, sourceControl));
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Marks the control and all its descendant controls as `touched`.
|
|
568
|
-
* @see {@link markAsTouched()}
|
|
569
|
-
*
|
|
570
|
-
* @param opts Configuration options that determine how the control propagates changes
|
|
571
|
-
* and emits events after marking is applied.
|
|
572
|
-
* * `emitEvent`: When true or not supplied (the default), the `events`
|
|
573
|
-
* observable emits a `TouchedChangeEvent` with the `touched` property being `true`.
|
|
574
|
-
* When false, no events are emitted.
|
|
575
|
-
*/
|
|
576
|
-
markAllAsTouched(opts = {}) {
|
|
577
|
-
this.markAsTouched({ onlySelf: true, emitEvent: opts.emitEvent, sourceControl: this });
|
|
578
|
-
this._forEachChild((control) => control.markAllAsTouched(opts));
|
|
579
|
-
}
|
|
580
|
-
markAsUntouched(opts = {}) {
|
|
581
|
-
const changed = this.touched === true;
|
|
582
|
-
this.touched = false;
|
|
583
|
-
this._pendingTouched = false;
|
|
584
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
585
|
-
this._forEachChild((control) => {
|
|
586
|
-
control.markAsUntouched({ onlySelf: true, emitEvent: opts.emitEvent, sourceControl });
|
|
587
|
-
});
|
|
588
|
-
if (this._parent && !opts.onlySelf) {
|
|
589
|
-
this._parent._updateTouched(opts, sourceControl);
|
|
590
|
-
}
|
|
591
|
-
if (changed && opts.emitEvent !== false) {
|
|
592
|
-
this._events.next(new TouchedChangeEvent(false, sourceControl));
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
markAsDirty(opts = {}) {
|
|
596
|
-
const changed = this.pristine === true;
|
|
597
|
-
this.pristine = false;
|
|
598
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
599
|
-
if (this._parent && !opts.onlySelf) {
|
|
600
|
-
this._parent.markAsDirty({ ...opts, sourceControl });
|
|
601
|
-
}
|
|
602
|
-
if (changed && opts.emitEvent !== false) {
|
|
603
|
-
this._events.next(new PristineChangeEvent(false, sourceControl));
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
markAsPristine(opts = {}) {
|
|
607
|
-
const changed = this.pristine === false;
|
|
608
|
-
this.pristine = true;
|
|
609
|
-
this._pendingDirty = false;
|
|
610
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
611
|
-
this._forEachChild((control) => {
|
|
612
|
-
/** We don't propagate the source control downwards */
|
|
613
|
-
control.markAsPristine({ onlySelf: true, emitEvent: opts.emitEvent });
|
|
614
|
-
});
|
|
615
|
-
if (this._parent && !opts.onlySelf) {
|
|
616
|
-
this._parent._updatePristine(opts, sourceControl);
|
|
617
|
-
}
|
|
618
|
-
if (changed && opts.emitEvent !== false) {
|
|
619
|
-
this._events.next(new PristineChangeEvent(true, sourceControl));
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
markAsPending(opts = {}) {
|
|
623
|
-
this.status = PENDING;
|
|
624
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
625
|
-
if (opts.emitEvent !== false) {
|
|
626
|
-
this._events.next(new StatusChangeEvent(this.status, sourceControl));
|
|
627
|
-
this.statusChanges.emit(this.status);
|
|
628
|
-
}
|
|
629
|
-
if (this._parent && !opts.onlySelf) {
|
|
630
|
-
this._parent.markAsPending({ ...opts, sourceControl });
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
disable(opts = {}) {
|
|
634
|
-
// If parent has been marked artificially dirty we don't want to re-calculate the
|
|
635
|
-
// parent's dirtiness based on the children.
|
|
636
|
-
const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
|
|
637
|
-
this.status = DISABLED;
|
|
638
|
-
this.errors = null;
|
|
639
|
-
this._forEachChild((control) => {
|
|
640
|
-
/** We don't propagate the source control downwards */
|
|
641
|
-
control.disable({ ...opts, onlySelf: true });
|
|
642
|
-
});
|
|
643
|
-
this._updateValue();
|
|
644
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
645
|
-
if (opts.emitEvent !== false) {
|
|
646
|
-
this._events.next(new ValueChangeEvent(this.value, sourceControl));
|
|
647
|
-
this._events.next(new StatusChangeEvent(this.status, sourceControl));
|
|
648
|
-
this.valueChanges.emit(this.value);
|
|
649
|
-
this.statusChanges.emit(this.status);
|
|
650
|
-
}
|
|
651
|
-
this._updateAncestors({ ...opts, skipPristineCheck }, this);
|
|
652
|
-
this._onDisabledChange.forEach((changeFn) => changeFn(true));
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* Enables the control. This means the control is included in validation checks and
|
|
656
|
-
* the aggregate value of its parent. Its status recalculates based on its value and
|
|
657
|
-
* its validators.
|
|
658
|
-
*
|
|
659
|
-
* By default, if the control has children, all children are enabled.
|
|
660
|
-
*
|
|
661
|
-
* @see {@link AbstractControl.status}
|
|
662
|
-
*
|
|
663
|
-
* @param opts Configure options that control how the control propagates changes and
|
|
664
|
-
* emits events when marked as untouched
|
|
665
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
666
|
-
* marks all direct ancestors. Default is false.
|
|
667
|
-
* * `emitEvent`: When true or not supplied (the default), the `statusChanges`,
|
|
668
|
-
* `valueChanges` and `events`
|
|
669
|
-
* observables emit events with the latest status and value when the control is enabled.
|
|
670
|
-
* When false, no events are emitted.
|
|
671
|
-
*/
|
|
672
|
-
enable(opts = {}) {
|
|
673
|
-
// If parent has been marked artificially dirty we don't want to re-calculate the
|
|
674
|
-
// parent's dirtiness based on the children.
|
|
675
|
-
const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
|
|
676
|
-
this.status = VALID;
|
|
677
|
-
this._forEachChild((control) => {
|
|
678
|
-
control.enable({ ...opts, onlySelf: true });
|
|
679
|
-
});
|
|
680
|
-
this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
|
|
681
|
-
this._updateAncestors({ ...opts, skipPristineCheck }, this);
|
|
682
|
-
this._onDisabledChange.forEach((changeFn) => changeFn(false));
|
|
683
|
-
}
|
|
684
|
-
_updateAncestors(opts, sourceControl) {
|
|
685
|
-
if (this._parent && !opts.onlySelf) {
|
|
686
|
-
this._parent.updateValueAndValidity(opts);
|
|
687
|
-
if (!opts.skipPristineCheck) {
|
|
688
|
-
this._parent._updatePristine({}, sourceControl);
|
|
689
|
-
}
|
|
690
|
-
this._parent._updateTouched({}, sourceControl);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Sets the parent of the control
|
|
695
|
-
*
|
|
696
|
-
* @param parent The new parent.
|
|
697
|
-
*/
|
|
698
|
-
setParent(parent) {
|
|
699
|
-
this._parent = parent;
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* The raw value of this control. For most control implementations, the raw value will include
|
|
703
|
-
* disabled children.
|
|
704
|
-
*/
|
|
705
|
-
getRawValue() {
|
|
706
|
-
return this.value;
|
|
707
|
-
}
|
|
708
|
-
updateValueAndValidity(opts = {}) {
|
|
709
|
-
this._setInitialStatus();
|
|
710
|
-
this._updateValue();
|
|
711
|
-
if (this.enabled) {
|
|
712
|
-
const shouldHaveEmitted = this._cancelExistingSubscription();
|
|
713
|
-
this.errors = this._runValidator();
|
|
714
|
-
this.status = this._calculateStatus();
|
|
715
|
-
if (this.status === VALID || this.status === PENDING) {
|
|
716
|
-
// If the canceled subscription should have emitted
|
|
717
|
-
// we make sure the async validator emits the status change on completion
|
|
718
|
-
this._runAsyncValidator(shouldHaveEmitted, opts.emitEvent);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
const sourceControl = opts.sourceControl ?? this;
|
|
722
|
-
if (opts.emitEvent !== false) {
|
|
723
|
-
this._events.next(new ValueChangeEvent(this.value, sourceControl));
|
|
724
|
-
this._events.next(new StatusChangeEvent(this.status, sourceControl));
|
|
725
|
-
this.valueChanges.emit(this.value);
|
|
726
|
-
this.statusChanges.emit(this.status);
|
|
727
|
-
}
|
|
728
|
-
if (this._parent && !opts.onlySelf) {
|
|
729
|
-
this._parent.updateValueAndValidity({ ...opts, sourceControl });
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
/** @internal */
|
|
733
|
-
_updateTreeValidity(opts = { emitEvent: true }) {
|
|
734
|
-
this._forEachChild((ctrl) => ctrl._updateTreeValidity(opts));
|
|
735
|
-
this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
|
|
736
|
-
}
|
|
737
|
-
_setInitialStatus() {
|
|
738
|
-
this.status = this._allControlsDisabled() ? DISABLED : VALID;
|
|
739
|
-
}
|
|
740
|
-
_runValidator() {
|
|
741
|
-
return this.validator ? this.validator(this) : null;
|
|
742
|
-
}
|
|
743
|
-
_runAsyncValidator(shouldHaveEmitted, emitEvent) {
|
|
744
|
-
if (this.asyncValidator) {
|
|
745
|
-
this.status = PENDING;
|
|
746
|
-
this._hasOwnPendingAsyncValidator = { emitEvent: emitEvent !== false };
|
|
747
|
-
const obs = toObservable(this.asyncValidator(this));
|
|
748
|
-
this._asyncValidationSubscription = obs.subscribe((errors) => {
|
|
749
|
-
this._hasOwnPendingAsyncValidator = null;
|
|
750
|
-
// This will trigger the recalculation of the validation status, which depends on
|
|
751
|
-
// the state of the asynchronous validation (whether it is in progress or not). So, it is
|
|
752
|
-
// necessary that we have updated the `_hasOwnPendingAsyncValidator` boolean flag first.
|
|
753
|
-
this.setErrors(errors, { emitEvent, shouldHaveEmitted });
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
_cancelExistingSubscription() {
|
|
758
|
-
if (this._asyncValidationSubscription) {
|
|
759
|
-
this._asyncValidationSubscription.unsubscribe();
|
|
760
|
-
// we're cancelling the validator subscribtion, we keep if it should have emitted
|
|
761
|
-
// because we want to emit eventually if it was required at least once.
|
|
762
|
-
const shouldHaveEmitted = this._hasOwnPendingAsyncValidator?.emitEvent ?? false;
|
|
763
|
-
this._hasOwnPendingAsyncValidator = null;
|
|
764
|
-
return shouldHaveEmitted;
|
|
765
|
-
}
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
setErrors(errors, opts = {}) {
|
|
769
|
-
this.errors = errors;
|
|
770
|
-
this._updateControlsErrors(opts.emitEvent !== false, this, opts.shouldHaveEmitted);
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Retrieves a child control given the control's name or path.
|
|
774
|
-
*
|
|
775
|
-
* @param path A dot-delimited string or array of string/number values that define the path to the
|
|
776
|
-
* control. If a string is provided, passing it as a string literal will result in improved type
|
|
777
|
-
* information. Likewise, if an array is provided, passing it `as const` will cause improved type
|
|
778
|
-
* information to be available.
|
|
779
|
-
*
|
|
780
|
-
* @usageNotes
|
|
781
|
-
* ### Retrieve a nested control
|
|
782
|
-
*
|
|
783
|
-
* For example, to get a `name` control nested within a `person` sub-group:
|
|
784
|
-
*
|
|
785
|
-
* * `this.form.get('person.name');`
|
|
786
|
-
*
|
|
787
|
-
* -OR-
|
|
788
|
-
*
|
|
789
|
-
* * `this.form.get(['person', 'name'] as const);` // `as const` gives improved typings
|
|
790
|
-
*
|
|
791
|
-
* ### Retrieve a control in a FormArray
|
|
792
|
-
*
|
|
793
|
-
* When accessing an element inside a FormArray, you can use an element index.
|
|
794
|
-
* For example, to get a `price` control from the first element in an `items` array you can use:
|
|
795
|
-
*
|
|
796
|
-
* * `this.form.get('items.0.price');`
|
|
797
|
-
*
|
|
798
|
-
* -OR-
|
|
799
|
-
*
|
|
800
|
-
* * `this.form.get(['items', 0, 'price']);`
|
|
801
|
-
*/
|
|
802
|
-
get(path) {
|
|
803
|
-
let currPath = path;
|
|
804
|
-
if (currPath == null)
|
|
805
|
-
return null;
|
|
806
|
-
if (!Array.isArray(currPath))
|
|
807
|
-
currPath = currPath.split('.');
|
|
808
|
-
if (currPath.length === 0)
|
|
809
|
-
return null;
|
|
810
|
-
return currPath.reduce((control, name) => control && control._find(name), this);
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* @description
|
|
814
|
-
* Reports error data for the control with the given path.
|
|
815
|
-
*
|
|
816
|
-
* @param errorCode The code of the error to check
|
|
817
|
-
* @param path A list of control names that designates how to move from the current control
|
|
818
|
-
* to the control that should be queried for errors.
|
|
819
|
-
*
|
|
820
|
-
* @usageNotes
|
|
821
|
-
* For example, for the following `FormGroup`:
|
|
822
|
-
*
|
|
823
|
-
* ```
|
|
824
|
-
* form = new FormGroup({
|
|
825
|
-
* address: new FormGroup({ street: new FormControl() })
|
|
826
|
-
* });
|
|
827
|
-
* ```
|
|
828
|
-
*
|
|
829
|
-
* The path to the 'street' control from the root form would be 'address' -> 'street'.
|
|
830
|
-
*
|
|
831
|
-
* It can be provided to this method in one of two formats:
|
|
832
|
-
*
|
|
833
|
-
* 1. An array of string control names, e.g. `['address', 'street']`
|
|
834
|
-
* 1. A period-delimited list of control names in one string, e.g. `'address.street'`
|
|
835
|
-
*
|
|
836
|
-
* @returns error data for that particular error. If the control or error is not present,
|
|
837
|
-
* null is returned.
|
|
838
|
-
*/
|
|
839
|
-
getError(errorCode, path) {
|
|
840
|
-
const control = path ? this.get(path) : this;
|
|
841
|
-
return control && control.errors ? control.errors[errorCode] : null;
|
|
842
|
-
}
|
|
843
|
-
/**
|
|
844
|
-
* @description
|
|
845
|
-
* Reports whether the control with the given path has the error specified.
|
|
846
|
-
*
|
|
847
|
-
* @param errorCode The code of the error to check
|
|
848
|
-
* @param path A list of control names that designates how to move from the current control
|
|
849
|
-
* to the control that should be queried for errors.
|
|
850
|
-
*
|
|
851
|
-
* @usageNotes
|
|
852
|
-
* For example, for the following `FormGroup`:
|
|
853
|
-
*
|
|
854
|
-
* ```
|
|
855
|
-
* form = new FormGroup({
|
|
856
|
-
* address: new FormGroup({ street: new FormControl() })
|
|
857
|
-
* });
|
|
858
|
-
* ```
|
|
859
|
-
*
|
|
860
|
-
* The path to the 'street' control from the root form would be 'address' -> 'street'.
|
|
861
|
-
*
|
|
862
|
-
* It can be provided to this method in one of two formats:
|
|
863
|
-
*
|
|
864
|
-
* 1. An array of string control names, e.g. `['address', 'street']`
|
|
865
|
-
* 1. A period-delimited list of control names in one string, e.g. `'address.street'`
|
|
866
|
-
*
|
|
867
|
-
* If no path is given, this method checks for the error on the current control.
|
|
868
|
-
*
|
|
869
|
-
* @returns whether the given error is present in the control at the given path.
|
|
870
|
-
*
|
|
871
|
-
* If the control is not present, false is returned.
|
|
872
|
-
*/
|
|
873
|
-
hasError(errorCode, path) {
|
|
874
|
-
return !!this.getError(errorCode, path);
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Retrieves the top-level ancestor of this control.
|
|
878
|
-
*/
|
|
879
|
-
get root() {
|
|
880
|
-
let x = this;
|
|
881
|
-
while (x._parent) {
|
|
882
|
-
x = x._parent;
|
|
883
|
-
}
|
|
884
|
-
return x;
|
|
885
|
-
}
|
|
886
|
-
/** @internal */
|
|
887
|
-
_updateControlsErrors(emitEvent, changedControl, shouldHaveEmitted) {
|
|
888
|
-
this.status = this._calculateStatus();
|
|
889
|
-
if (emitEvent) {
|
|
890
|
-
this.statusChanges.emit(this.status);
|
|
891
|
-
}
|
|
892
|
-
// The Events Observable expose a slight different bevahior than the statusChanges obs
|
|
893
|
-
// An async validator will still emit a StatusChangeEvent is a previously cancelled
|
|
894
|
-
// async validator has emitEvent set to true
|
|
895
|
-
if (emitEvent || shouldHaveEmitted) {
|
|
896
|
-
this._events.next(new StatusChangeEvent(this.status, changedControl));
|
|
897
|
-
}
|
|
898
|
-
if (this._parent) {
|
|
899
|
-
this._parent._updateControlsErrors(emitEvent, changedControl, shouldHaveEmitted);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
/** @internal */
|
|
903
|
-
_initObservables() {
|
|
904
|
-
this.valueChanges = new EventEmitter();
|
|
905
|
-
this.statusChanges = new EventEmitter();
|
|
906
|
-
}
|
|
907
|
-
_calculateStatus() {
|
|
908
|
-
if (this._allControlsDisabled())
|
|
909
|
-
return DISABLED;
|
|
910
|
-
if (this.errors)
|
|
911
|
-
return INVALID;
|
|
912
|
-
if (this._hasOwnPendingAsyncValidator || this._anyControlsHaveStatus(PENDING))
|
|
913
|
-
return PENDING;
|
|
914
|
-
if (this._anyControlsHaveStatus(INVALID))
|
|
915
|
-
return INVALID;
|
|
916
|
-
return VALID;
|
|
917
|
-
}
|
|
918
|
-
/** @internal */
|
|
919
|
-
_anyControlsHaveStatus(status) {
|
|
920
|
-
return this._anyControls((control) => control.status === status);
|
|
921
|
-
}
|
|
922
|
-
/** @internal */
|
|
923
|
-
_anyControlsDirty() {
|
|
924
|
-
return this._anyControls((control) => control.dirty);
|
|
925
|
-
}
|
|
926
|
-
/** @internal */
|
|
927
|
-
_anyControlsTouched() {
|
|
928
|
-
return this._anyControls((control) => control.touched);
|
|
929
|
-
}
|
|
930
|
-
/** @internal */
|
|
931
|
-
_updatePristine(opts, changedControl) {
|
|
932
|
-
const newPristine = !this._anyControlsDirty();
|
|
933
|
-
const changed = this.pristine !== newPristine;
|
|
934
|
-
this.pristine = newPristine;
|
|
935
|
-
if (this._parent && !opts.onlySelf) {
|
|
936
|
-
this._parent._updatePristine(opts, changedControl);
|
|
937
|
-
}
|
|
938
|
-
if (changed) {
|
|
939
|
-
this._events.next(new PristineChangeEvent(this.pristine, changedControl));
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
/** @internal */
|
|
943
|
-
_updateTouched(opts = {}, changedControl) {
|
|
944
|
-
this.touched = this._anyControlsTouched();
|
|
945
|
-
this._events.next(new TouchedChangeEvent(this.touched, changedControl));
|
|
946
|
-
if (this._parent && !opts.onlySelf) {
|
|
947
|
-
this._parent._updateTouched(opts, changedControl);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
/** @internal */
|
|
951
|
-
_registerOnCollectionChange(fn) {
|
|
952
|
-
this._onCollectionChange = fn;
|
|
953
|
-
}
|
|
954
|
-
/** @internal */
|
|
955
|
-
_setUpdateStrategy(opts) {
|
|
956
|
-
if (isOptionsObj(opts) && opts.updateOn != null) {
|
|
957
|
-
this._updateOn = opts.updateOn;
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Check to see if parent has been marked artificially dirty.
|
|
962
|
-
*
|
|
963
|
-
* @internal
|
|
964
|
-
*/
|
|
965
|
-
_parentMarkedDirty(onlySelf) {
|
|
966
|
-
const parentDirty = this._parent && this._parent.dirty;
|
|
967
|
-
return !onlySelf && !!parentDirty && !this._parent._anyControlsDirty();
|
|
968
|
-
}
|
|
969
|
-
/** @internal */
|
|
970
|
-
_find(name) {
|
|
971
|
-
return null;
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Internal implementation of the `setValidators` method. Needs to be separated out into a
|
|
975
|
-
* different method, because it is called in the constructor and it can break cases where
|
|
976
|
-
* a control is extended.
|
|
977
|
-
*/
|
|
978
|
-
_assignValidators(validators) {
|
|
979
|
-
this._rawValidators = Array.isArray(validators) ? validators.slice() : validators;
|
|
980
|
-
this._composedValidatorFn = coerceToValidator(this._rawValidators);
|
|
981
|
-
}
|
|
982
|
-
/**
|
|
983
|
-
* Internal implementation of the `setAsyncValidators` method. Needs to be separated out into a
|
|
984
|
-
* different method, because it is called in the constructor and it can break cases where
|
|
985
|
-
* a control is extended.
|
|
986
|
-
*/
|
|
987
|
-
_assignAsyncValidators(validators) {
|
|
988
|
-
this._rawAsyncValidators = Array.isArray(validators) ? validators.slice() : validators;
|
|
989
|
-
this._composedAsyncValidatorFn = coerceToAsyncValidator(this._rawAsyncValidators);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RfbW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9mb3Jtcy9zcmMvbW9kZWwvYWJzdHJhY3RfbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUNMLFlBQVksRUFDWixNQUFNLEVBQ04sYUFBYSxJQUFJLFlBQVksRUFFN0IsU0FBUyxFQUNULFFBQVEsR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQWEsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRXpDLE9BQU8sRUFDTCxxQ0FBcUMsRUFDckMsbUJBQW1CLEVBQ25CLHdCQUF3QixFQUN4QixlQUFlLEdBQ2hCLE1BQU0sK0JBQStCLENBQUM7QUFJdkMsT0FBTyxFQUNMLGFBQWEsRUFDYixzQkFBc0IsRUFDdEIsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBRXZCOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDO0FBRTdCOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDO0FBRWpDOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUM7QUFFakM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQztBQW1CbkM7Ozs7R0FJRztBQUNILE1BQU0sT0FBZ0IsWUFBWTtDQUtqQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sZ0JBQW9CLFNBQVEsWUFBZTtJQUN0RCxZQUNrQixLQUFRLEVBQ1IsTUFBdUI7UUFFdkMsS0FBSyxFQUFFLENBQUM7UUFIUSxVQUFLLEdBQUwsS0FBSyxDQUFHO1FBQ1IsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7SUFHekMs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QUNLLHNCQUFzQixDQUFDLFVBQXdEO1FBQ3JGLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztRQUN2RixJQUFJLENBQUMseUJBQXlCLEdBQUcsc0JBQXNCLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDcEYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7XG4gIEV2ZW50RW1pdHRlcixcbiAgc2lnbmFsLFxuICDJtVJ1bnRpbWVFcnJvciBhcyBSdW50aW1lRXJyb3IsXG4gIMm1V3JpdGFibGUgYXMgV3JpdGFibGUsXG4gIHVudHJhY2tlZCxcbiAgY29tcHV0ZWQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtcbiAgYXN5bmNWYWxpZGF0b3JzRHJvcHBlZFdpdGhPcHRzV2FybmluZyxcbiAgbWlzc2luZ0NvbnRyb2xFcnJvcixcbiAgbWlzc2luZ0NvbnRyb2xWYWx1ZUVycm9yLFxuICBub0NvbnRyb2xzRXJyb3IsXG59IGZyb20gJy4uL2RpcmVjdGl2ZXMvcmVhY3RpdmVfZXJyb3JzJztcbmltcG9ydCB7QXN5bmNWYWxpZGF0b3JGbiwgVmFsaWRhdGlvbkVycm9ycywgVmFsaWRhdG9yRm59IGZyb20gJy4uL2RpcmVjdGl2ZXMvdmFsaWRhdG9ycyc7XG5pbXBvcnQge1J1bnRpbWVFcnJvckNvZGV9IGZyb20gJy4uL2Vycm9ycyc7XG5pbXBvcnQge0Zvcm1BcnJheSwgRm9ybUdyb3VwfSBmcm9tICcuLi9mb3Jtcyc7XG5pbXBvcnQge1xuICBhZGRWYWxpZGF0b3JzLFxuICBjb21wb3NlQXN5bmNWYWxpZGF0b3JzLFxuICBjb21wb3NlVmFsaWRhdG9ycyxcbiAgaGFzVmFsaWRhdG9yLFxuICByZW1vdmVWYWxpZGF0b3JzLFxuICB0b09ic2VydmFibGUsXG59IGZyb20gJy4uL3ZhbGlkYXRvcnMnO1xuXG4vKipcbiAqIFJlcG9ydHMgdGhhdCBhIGNvbnRyb2wgaXMgdmFsaWQsIG1lYW5pbmcgdGhhdCBubyBlcnJvcnMgZXhpc3QgaW4gdGhlIGlucHV0IHZhbHVlLlxuICpcbiAqIEBzZWUge0BsaW5rIHN0YXR1c31cbiAqL1xuZXhwb3J0IGNvbnN0IFZBTElEID0gJ1ZBTElEJztcblxuLyoqXG4gKiBSZXBvcnRzIHRoYXQgYSBjb250cm9sIGlzIGludmFsaWQsIG1lYW5pbmcgdGhhdCBhbiBlcnJvciBleGlzdHMgaW4gdGhlIGlucHV0IHZhbHVlLlxuICpcbiAqIEBzZWUge0BsaW5rIHN0YXR1c31cbiAqL1xuZXhwb3J0IGNvbnN0IElOVkFMSUQgPSAnSU5WQUxJRCc7XG5cbi8qKlxuICogUmVwb3J0cyB0aGF0IGEgY29udHJvbCBpcyBwZW5kaW5nLCBtZWFuaW5nIHRoYXQgYXN5bmMgdmFsaWRhdGlvbiBpcyBvY2N1cnJpbmcgYW5kXG4gKiBlcnJvcnMgYXJlIG5vdCB5ZXQgYXZhaWxhYmxlIGZvciB0aGUgaW5wdXQgdmFsdWUuXG4gKlxuICogQHNlZSB7QGxpbmsgbWFya0FzUGVuZGluZ31cbiAqIEBzZWUge0BsaW5rIHN0YXR1c31cbiAqL1xuZXhwb3J0IGNvbnN0IFBFTkRJTkcgPSAnUEVORElORyc7XG5cbi8qKlxuICogUmVwb3J0cyB0aGF0IGEgY29udHJvbCBpcyBkaXNhYmxlZCwgbWVhbmluZyB0aGF0IHRoZSBjb250cm9sIGlzIGV4ZW1wdCBmcm9tIGFuY2VzdG9yXG4gKiBjYWxjdWxhdGlvbnMgb2YgdmFsaWRpdHkgb3IgdmFsdWUuXG4gKlxuICogQHNlZSB7QGxpbmsgbWFya0FzRGlzYWJsZWR9XG4gKiBAc2VlIHtAbGluayBzdGF0dXN9XG4gKi9cbmV4cG9ydCBjb25zdCBESVNBQkxFRCA9ICdESVNBQkxFRCc7XG5cbi8qKlxuICogQSBmb3JtIGNhbiBoYXZlIHNldmVyYWwgZGlmZmVyZW50IHN0YXR1c2VzLiBFYWNoXG4gKiBwb3NzaWJsZSBzdGF0dXMgaXMgcmV0dXJuZWQgYXMgYSBzdHJpbmcgbGl0ZXJhbC5cbiAqXG4gKiAqICoqVkFMSUQqKjogUmVwb3J0cyB0aGF0IGEgY29udHJvbCBpcyB2YWxpZCwgbWVhbmluZyB0aGF0IG5vIGVycm9ycyBleGlzdCBpbiB0aGUgaW5wdXRcbiAqIHZhbHVlLlxuICogKiAqKklOVkFMSUQqKjogUmVwb3J0cyB0aGF0IGEgY29udHJvbCBpcyBpbnZhbGlkLCBtZWFuaW5nIHRoYXQgYW4gZXJyb3IgZXhpc3RzIGluIHRoZSBpbnB1dFxuICogdmFsdWUuXG4gKiAqICoqUEVORElORyoqOiBSZXBvcnRzIHRoYXQgYSBjb250cm9sIGlzIHBlbmRpbmcsIG1lYW5pbmcgdGhhdCBhc3luYyB2YWxpZGF0aW9uIGlzXG4gKiBvY2N1cnJpbmcgYW5kIGVycm9ycyBhcmUgbm90IHlldCBhdmFpbGFibGUgZm9yIHRoZSBpbnB1dCB2YWx1ZS5cbiAqICogKipESVNBQkxFRCoqOiBSZXBvcnRzIHRoYXQgYSBjb250cm9sIGlzXG4gKiBkaXNhYmxlZCwgbWVhbmluZyB0aGF0IHRoZSBjb250cm9sIGlzIGV4ZW1wdCBmcm9tIGFuY2VzdG9yIGNhbGN1bGF0aW9ucyBvZiB2YWxpZGl0eSBvciB2YWx1ZS5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCB0eXBlIEZvcm1Db250cm9sU3RhdHVzID0gJ1ZBTElEJyB8ICdJTlZBTElEJyB8ICdQRU5ESU5HJyB8ICdESVNBQkxFRCc7XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZXZlcnkgZXZlbnQgc2VudCBieSBgQWJzdHJhY3RDb250cm9sLmV2ZW50cygpYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENvbnRyb2xFdmVudDxUID0gYW55PiB7XG4gIC8qKlxuICAgKiBGb3JtIGNvbnRyb2wgZnJvbSB3aGljaCB0aGlzIGV2ZW50IGlzIG9yaWdpbmF0ZWQuXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgc291cmNlOiBBYnN0cmFjdENvbnRyb2w8dW5rbm93bj47XG59XG5cbi8qKlxuICogRXZlbnQgZmlyZWQgd2hlbiB0aGUgdmFsdWUgb2YgYSBjb250cm9sIGNoYW5nZXMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgVmFsdWVDaGFuZ2VFdmVudDxUPiBleHRlbmRzIENvbnRyb2xFdmVudDxUPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSB2YWx1ZTogVCxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc291cmNlOiBBYnN0cmFjdENvbnRyb2wsXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBFdmVudCBmaXJlZCB3aGVuIHRoZSBjb250cm9sJ3MgcHJpc3RpbmUgc3RhdGUgY2hhbmdlcyAocHJpc3RpbmUgPD0+IGRpcnR5KS5cbiAqXG4gKiBAcHVibGljQXBpICovXG5leHBvcnQgY2xhc3MgUHJpc3RpbmVDaGFuZ2VFdmVudCBleHRlbmRzIENvbnRyb2xFdmVudCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBwcmlzdGluZTogYm9vbGVhbixcbiAgICBwdWJsaWMgcmVhZG9ubHkgc291cmNlOiBBYnN0cmFjdENvbnRyb2wsXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBFdmVudCBmaXJlZCB3aGVuIHRoZSBjb250cm9sJ3MgdG91Y2hlZCBzdGF0dXMgY2hhbmdlcyAodG91Y2hlZCA8PT4gdW50b3VjaGVkKS5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBjbGFzcyBUb3VjaGVkQ2hhbmdlRXZlbnQgZXh0ZW5kcyBDb250cm9sRXZlbnQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgdG91Y2hlZDogYm9vbGVhbixcbiAgICBwdWJsaWMgcmVhZG9ubHkgc291cmNlOiBBYnN0cmFjdENvbnRyb2wsXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBFdmVudCBmaXJlZCB3aGVuIHRoZSBjb250cm9sJ3Mgc3RhdHVzIGNoYW5nZXMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgU3RhdHVzQ2hhbmdlRXZlbnQgZXh0ZW5kcyBDb250cm9sRXZlbnQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzOiBGb3JtQ29udHJvbFN0YXR1cyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc291cmNlOiBBYnN0cmFjdENvbnRyb2wsXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBFdmVudCBmaXJlZCB3aGVuIGEgZm9ybSBpcyBzdWJtaXR0ZWRcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBjbGFzcyBGb3JtU3VibWl0dGVkRXZlbnQgZXh0ZW5kcyBDb250cm9sRXZlbnQge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgc291cmNlOiBBYnN0cmFjdENvbnRyb2wpIHtcbiAgICBzdXBlcigpO1xuICB9XG59XG4vKipcbiAqIEV2ZW50IGZpcmVkIHdoZW4gYSBmb3JtIGlzIHJlc2V0LlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGNsYXNzIEZvcm1SZXNldEV2ZW50IGV4dGVuZHMgQ29udHJvbEV2ZW50IHtcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHNvdXJjZTogQWJzdHJhY3RDb250cm9sKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldHMgdmFsaWRhdG9ycyBmcm9tIGVpdGhlciBhbiBvcHRpb25zIG9iamVjdCBvciBnaXZlbiB2YWxpZGF0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGlja1ZhbGlkYXRvcnMoXG4gIHZhbGlkYXRvck9yT3B0cz86IFZhbGlkYXRvckZuIHwgVmFsaWRhdG9yRm5bXSB8IEFic3RyYWN0Q29udHJvbE9wdGlvbnMgfCBudWxsLFxuKTogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdIHwgbnVsbCB7XG4gIHJldHVybiAoaXNPcHRpb25zT2JqKHZhbGlkYXRvck9yT3B0cykgPyB2YWxpZGF0b3JPck9wdHMudmFsaWRhdG9ycyA6IHZhbGlkYXRvck9yT3B0cykgfHwgbnVsbDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHZhbGlkYXRvciBmdW5jdGlvbiBieSBjb21iaW5pbmcgcHJvdmlkZWQgdmFsaWRhdG9ycy5cbiAqL1xuZnVuY3Rpb24gY29lcmNlVG9WYWxpZGF0b3IodmFsaWRhdG9yOiBWYWxpZGF0b3JGbiB8IFZhbGlkYXRvckZuW10gfCBudWxsKTogVmFsaWRhdG9yRm4gfCBudWxsIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsaWRhdG9yKSA/IGNvbXBvc2VWYWxpZGF0b3JzKHZhbGlkYXRvcikgOiB2YWxpZGF0b3IgfHwgbnVsbDtcbn1cblxuLyoqXG4gKiBHZXRzIGFzeW5jIHZhbGlkYXRvcnMgZnJvbSBlaXRoZXIgYW4gb3B0aW9ucyBvYmplY3Qgb3IgZ2l2ZW4gdmFsaWRhdG9ycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBpY2tBc3luY1ZhbGlkYXRvcnMoXG4gIGFzeW5jVmFsaWRhdG9yPzogQXN5bmNWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm5bXSB8IG51bGwsXG4gIHZhbGlkYXRvck9yT3B0cz86IFZhbGlkYXRvckZuIHwgVmFsaWRhdG9yRm5bXSB8IEFic3RyYWN0Q29udHJvbE9wdGlvbnMgfCBudWxsLFxuKTogQXN5bmNWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm5bXSB8IG51bGwge1xuICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSB7XG4gICAgaWYgKGlzT3B0aW9uc09iaih2YWxpZGF0b3JPck9wdHMpICYmIGFzeW5jVmFsaWRhdG9yKSB7XG4gICAgICBjb25zb2xlLndhcm4oYXN5bmNWYWxpZGF0b3JzRHJvcHBlZFdpdGhPcHRzV2FybmluZyk7XG4gICAgfVxuICB9XG4gIHJldHVybiAoaXNPcHRpb25zT2JqKHZhbGlkYXRvck9yT3B0cykgPyB2YWxpZGF0b3JPck9wdHMuYXN5bmNWYWxpZGF0b3JzIDogYXN5bmNWYWxpZGF0b3IpIHx8IG51bGw7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhc3luYyB2YWxpZGF0b3IgZnVuY3Rpb24gYnkgY29tYmluaW5nIHByb3ZpZGVkIGFzeW5jIHZhbGlkYXRvcnMuXG4gKi9cbmZ1bmN0aW9uIGNvZXJjZVRvQXN5bmNWYWxpZGF0b3IoXG4gIGFzeW5jVmFsaWRhdG9yPzogQXN5bmNWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm5bXSB8IG51bGwsXG4pOiBBc3luY1ZhbGlkYXRvckZuIHwgbnVsbCB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFzeW5jVmFsaWRhdG9yKVxuICAgID8gY29tcG9zZUFzeW5jVmFsaWRhdG9ycyhhc3luY1ZhbGlkYXRvcilcbiAgICA6IGFzeW5jVmFsaWRhdG9yIHx8IG51bGw7XG59XG5cbmV4cG9ydCB0eXBlIEZvcm1Ib29rcyA9ICdjaGFuZ2UnIHwgJ2JsdXInIHwgJ3N1Ym1pdCc7XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBvcHRpb25zIHByb3ZpZGVkIHRvIGFuIGBBYnN0cmFjdENvbnRyb2xgLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBYnN0cmFjdENvbnRyb2xPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUaGUgbGlzdCBvZiB2YWxpZGF0b3JzIGFwcGxpZWQgdG8gYSBjb250cm9sLlxuICAgKi9cbiAgdmFsaWRhdG9ycz86IFZhbGlkYXRvckZuIHwgVmFsaWRhdG9yRm5bXSB8IG51bGw7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogVGhlIGxpc3Qgb2YgYXN5bmMgdmFsaWRhdG9ycyBhcHBsaWVkIHRvIGNvbnRyb2wuXG4gICAqL1xuICBhc3luY1ZhbGlkYXRvcnM/OiBBc3luY1ZhbGlkYXRvckZuIHwgQXN5bmNWYWxpZGF0b3JGbltdIHwgbnVsbDtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUaGUgZXZlbnQgbmFtZSBmb3IgY29udHJvbCB0byB1cGRhdGUgdXBvbi5cbiAgICovXG4gIHVwZGF0ZU9uPzogJ2NoYW5nZScgfCAnYmx1cicgfCAnc3VibWl0Jztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzT3B0aW9uc09iaihcbiAgdmFsaWRhdG9yT3JPcHRzPzogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdIHwgQWJzdHJhY3RDb250cm9sT3B0aW9ucyB8IG51bGwsXG4pOiB2YWxpZGF0b3JPck9wdHMgaXMgQWJzdHJhY3RDb250cm9sT3B0aW9ucyB7XG4gIHJldHVybiAoXG4gICAgdmFsaWRhdG9yT3JPcHRzICE9IG51bGwgJiZcbiAgICAhQXJyYXkuaXNBcnJheSh2YWxpZGF0b3JPck9wdHMpICYmXG4gICAgdHlwZW9mIHZhbGlkYXRvck9yT3B0cyA9PT0gJ29iamVjdCdcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydENvbnRyb2xQcmVzZW50KHBhcmVudDogYW55LCBpc0dyb3VwOiBib29sZWFuLCBrZXk6IHN0cmluZyB8IG51bWJlcik6IHZvaWQge1xuICBjb25zdCBjb250cm9scyA9IHBhcmVudC5jb250cm9scyBhcyB7W2tleTogc3RyaW5nIHwgbnVtYmVyXTogdW5rbm93bn07XG4gIGNvbnN0IGNvbGxlY3Rpb24gPSBpc0dyb3VwID8gT2JqZWN0LmtleXMoY29udHJvbHMpIDogY29udHJvbHM7XG4gIGlmICghY29sbGVjdGlvbi5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKFxuICAgICAgUnVudGltZUVycm9yQ29kZS5OT19DT05UUk9MUyxcbiAgICAgIHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSA/IG5vQ29udHJvbHNFcnJvcihpc0dyb3VwKSA6ICcnLFxuICAgICk7XG4gIH1cbiAgaWYgKCFjb250cm9sc1trZXldKSB7XG4gICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihcbiAgICAgIFJ1bnRpbWVFcnJvckNvZGUuTUlTU0lOR19DT05UUk9MLFxuICAgICAgdHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlID8gbWlzc2luZ0NvbnRyb2xFcnJvcihpc0dyb3VwLCBrZXkpIDogJycsXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0QWxsVmFsdWVzUHJlc2VudChjb250cm9sOiBhbnksIGlzR3JvdXA6IGJvb2xlYW4sIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgY29udHJvbC5fZm9yRWFjaENoaWxkKChfOiB1bmtub3duLCBrZXk6IHN0cmluZyB8IG51bWJlcikgPT4ge1xuICAgIGlmICh2YWx1ZVtrZXldID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuTUlTU0lOR19DT05UUk9MX1ZBTFVFLFxuICAgICAgICB0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUgPyBtaXNzaW5nQ29udHJvbFZhbHVlRXJyb3IoaXNHcm91cCwga2V5KSA6ICcnLFxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xufVxuXG4vLyBJc0FueSBjaGVja3MgaWYgVCBpcyBgYW55YCwgYnkgY2hlY2tpbmcgYSBjb25kaXRpb24gdGhhdCBjb3VsZG4ndCBwb3NzaWJseSBiZSB0cnVlIG90aGVyd2lzZS5cbmV4cG9ydCB0eXBlIMm1SXNBbnk8VCwgWSwgTj4gPSAwIGV4dGVuZHMgMSAmIFQgPyBZIDogTjtcblxuLyoqXG4gKiBgVHlwZWRPclVudHlwZWRgIGFsbG93cyBvbmUgb2YgdHdvIGRpZmZlcmVudCB0eXBlcyB0byBiZSBzZWxlY3RlZCwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIEZvcm1zXG4gKiBjbGFzcyBpdCdzIGFwcGxpZWQgdG8gaXMgdHlwZWQgb3Igbm90LlxuICpcbiAqIFRoaXMgaXMgZm9yIGludGVybmFsIEFuZ3VsYXIgdXNhZ2UgdG8gc3VwcG9ydCB0eXBlZCBmb3JtczsgZG8gbm90IGRpcmVjdGx5IHVzZSBpdC5cbiAqL1xuZXhwb3J0IHR5cGUgybVUeXBlZE9yVW50eXBlZDxULCBUeXBlZCwgVW50eXBlZD4gPSDJtUlzQW55PFQsIFVudHlwZWQsIFR5cGVkPjtcblxuLyoqXG4gKiBWYWx1ZSBnaXZlcyB0aGUgdmFsdWUgdHlwZSBjb3JyZXNwb25kaW5nIHRvIGEgY29udHJvbCB0eXBlLlxuICpcbiAqIE5vdGUgdGhhdCB0aGUgcmVzdWx0aW5nIHR5cGUgd2lsbCBmb2xsb3cgdGhlIHNhbWUgcnVsZXMgYXMgYC52YWx1ZWAgb24geW91ciBjb250cm9sLCBncm91cCwgb3JcbiAqIGFycmF5LCBpbmNsdWRpbmcgYHVuZGVmaW5lZGAgZm9yIGVhY2ggZ3JvdXAgZWxlbWVudCB3aGljaCBtaWdodCBiZSBkaXNhYmxlZC5cbiAqXG4gKiBJZiB5b3UgYXJlIHRyeWluZyB0byBleHRyYWN0IGEgdmFsdWUgdHlwZSBmb3IgYSBkYXRhIG1vZGVsLCB5b3UgcHJvYmFibHkgd2FudCB7QGxpbmsgUmF3VmFsdWV9LFxuICogd2hpY2ggd2lsbCBub3QgaGF2ZSBgdW5kZWZpbmVkYCBpbiBncm91cCBrZXlzLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogIyMjIGBGb3JtQ29udHJvbGAgdmFsdWUgdHlwZVxuICpcbiAqIFlvdSBjYW4gZXh0cmFjdCB0aGUgdmFsdWUgdHlwZSBvZiBhIHNpbmdsZSBjb250cm9sOlxuICpcbiAqIGBgYHRzXG4gKiB0eXBlIE5hbWVDb250cm9sID0gRm9ybUNvbnRyb2w8c3RyaW5nPjtcbiAqIHR5cGUgTmFtZVZhbHVlID0gVmFsdWU8TmFtZUNvbnRyb2w+O1xuICogYGBgXG4gKlxuICogVGhlIHJlc3VsdGluZyB0eXBlIGlzIGBzdHJpbmdgLlxuICpcbiAqICMjIyBgRm9ybUdyb3VwYCB2YWx1ZSB0eXBlXG4gKlxuICogSW1hZ2luZSB5b3UgaGF2ZSBhbiBpbnRlcmZhY2UgZGVmaW5pbmcgdGhlIGNvbnRyb2xzIGluIHlvdXIgZ3JvdXAuIFlvdSBjYW4gZXh0cmFjdCB0aGUgc2hhcGUgb2ZcbiAqIHRoZSB2YWx1ZXMgYXMgZm9sbG93czpcbiAqXG4gKiBgYGB0c1xuICogaW50ZXJmYWNlIFBhcnR5Rm9ybUNvbnRyb2xzIHtcbiAqICAgYWRkcmVzczogRm9ybUNvbnRyb2w8c3RyaW5nPjtcbiAqIH1cbiAqXG4gKiAvLyBWYWx1ZSBvcGVyYXRlcyBvbiBjb250cm9sczsgdGhlIG9iamVjdCBtdXN0IGJlIHdyYXBwZWQgaW4gYSBGb3JtR3JvdXAuXG4gKiB0eXBlIFBhcnR5Rm9ybVZhbHVlcyA9IFZhbHVlPEZvcm1Hcm91cDxQYXJ0eUZvcm1Db250cm9scz4+O1xuICogYGBgXG4gKlxuICogVGhlIHJlc3VsdGluZyB0eXBlIGlzIGB7YWRkcmVzczogc3RyaW5nfHVuZGVmaW5lZH1gLlxuICpcbiAqICMjIyBgRm9ybUFycmF5YCB2YWx1ZSB0eXBlXG4gKlxuICogWW91IGNhbiBleHRyYWN0IHZhbHVlcyBmcm9tIEZvcm1BcnJheXMgYXMgd2VsbDpcbiAqXG4gKiBgYGB0c1xuICogdHlwZSBHdWVzdE5hbWVzQ29udHJvbHMgPSBGb3JtQXJyYXk8Rm9ybUNvbnRyb2w8c3RyaW5nPj47XG4gKlxuICogdHlwZSBOYW1lc1ZhbHVlcyA9IFZhbHVlPEd1ZXN0TmFtZXNDb250cm9scz47XG4gKiBgYGBcbiAqXG4gKiBUaGUgcmVzdWx0aW5nIHR5cGUgaXMgYHN0cmluZ1tdYC5cbiAqXG4gKiAqKkludGVybmFsOiBub3QgZm9yIHB1YmxpYyB1c2UuKipcbiAqL1xuZXhwb3J0IHR5cGUgybVWYWx1ZTxUIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sIHwgdW5kZWZpbmVkPiA9XG4gIFQgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2w8YW55LCBhbnk+ID8gVFsndmFsdWUnXSA6IG5ldmVyO1xuXG4vKipcbiAqIFJhd1ZhbHVlIGdpdmVzIHRoZSByYXcgdmFsdWUgdHlwZSBjb3JyZXNwb25kaW5nIHRvIGEgY29udHJvbCB0eXBlLlxuICpcbiAqIE5vdGUgdGhhdCB0aGUgcmVzdWx0aW5nIHR5cGUgd2lsbCBmb2xsb3cgdGhlIHNhbWUgcnVsZXMgYXMgYC5nZXRSYXdWYWx1ZSgpYCBvbiB5b3VyIGNvbnRyb2wsXG4gKiBncm91cCwgb3IgYXJyYXkuIFRoaXMgbWVhbnMgdGhhdCBhbGwgY29udHJvbHMgaW5zaWRlIGEgZ3JvdXAgd2lsbCBiZSByZXF1aXJlZCwgbm90IG9wdGlvbmFsLFxuICogcmVnYXJkbGVzcyBvZiB0aGVpciBkaXNhYmxlZCBzdGF0ZS5cbiAqXG4gKiBZb3UgbWF5IGFsc28gd2lzaCB0byB1c2Uge0BsaW5rIMm1VmFsdWV9LCB3aGljaCB3aWxsIGhhdmUgYHVuZGVmaW5lZGAgaW4gZ3JvdXAga2V5cyAod2hpY2ggY2FuIGJlXG4gKiBkaXNhYmxlZCkuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgYEZvcm1Hcm91cGAgcmF3IHZhbHVlIHR5cGVcbiAqXG4gKiBJbWFnaW5lIHlvdSBoYXZlIGFuIGludGVyZmFjZSBkZWZpbmluZyB0aGUgY29udHJvbHMgaW4geW91ciBncm91cC4gWW91IGNhbiBleHRyYWN0IHRoZSBzaGFwZSBvZlxuICogdGhlIHJhdyB2YWx1ZXMgYXMgZm9sbG93czpcbiAqXG4gKiBgYGB0c1xuICogaW50ZXJmYWNlIFBhcnR5Rm9ybUNvbnRyb2xzIHtcbiAqICAgYWRkcmVzczogRm9ybUNvbnRyb2w8c3RyaW5nPjtcbiAqIH1cbiAqXG4gKiAvLyBSYXdWYWx1ZSBvcGVyYXRlcyBvbiBjb250cm9sczsgdGhlIG9iamVjdCBtdXN0IGJlIHdyYXBwZWQgaW4gYSBGb3JtR3JvdXAuXG4gKiB0eXBlIFBhcnR5Rm9ybVZhbHVlcyA9IFJhd1ZhbHVlPEZvcm1Hcm91cDxQYXJ0eUZvcm1Db250cm9scz4+O1xuICogYGBgXG4gKlxuICogVGhlIHJlc3VsdGluZyB0eXBlIGlzIGB7YWRkcmVzczogc3RyaW5nfWAuIChOb3RlIHRoZSBhYnNlbmNlIG9mIGB1bmRlZmluZWRgLilcbiAqXG4gKiAgKipJbnRlcm5hbDogbm90IGZvciBwdWJsaWMgdXNlLioqXG4gKi9cbmV4cG9ydCB0eXBlIMm1UmF3VmFsdWU8VCBleHRlbmRzIEFic3RyYWN0Q29udHJvbCB8IHVuZGVmaW5lZD4gPVxuICBUIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sPGFueSwgYW55PlxuICAgID8gVFsnc2V0VmFsdWUnXSBleHRlbmRzICh2OiBpbmZlciBSKSA9PiB2b2lkXG4gICAgICA/IFJcbiAgICAgIDogbmV2ZXJcbiAgICA6IG5ldmVyO1xuXG4vKipcbiAqIFRva2VuaXplIHNwbGl0cyBhIHN0cmluZyBsaXRlcmFsIFMgYnkgYSBkZWxpbWl0ZXIgRC5cbiAqL1xuZXhwb3J0IHR5cGUgybVUb2tlbml6ZTxTIGV4dGVuZHMgc3RyaW5nLCBEIGV4dGVuZHMgc3RyaW5nPiA9IHN0cmluZyBleHRlbmRzIFNcbiAgPyBzdHJpbmdbXSAvKiBTIG11c3QgYmUgYSBsaXRlcmFsICovXG4gIDogUyBleHRlbmRzIGAke2luZmVyIFR9JHtEfSR7aW5mZXIgVX1gXG4gICAgPyBbVCwgLi4uybVUb2tlbml6ZTxVLCBEPl1cbiAgICA6IFtTXSAvKiBCYXNlIGNhc2UgKi87XG5cbi8qKlxuICogQ29lcmNlU3RyQXJyVG9OdW1BcnIgYWNjZXB0cyBhbiBhcnJheSBvZiBzdHJpbmdzLCBhbmQgY29udmVydHMgYW55IG51bWVyaWMgc3RyaW5nIHRvIGEgbnVtYmVyLlxuICovXG5leHBvcnQgdHlwZSDJtUNvZXJjZVN0ckFyclRvTnVtQXJyPFM+ID1cbiAgLy8gRXh0cmFjdCB0aGUgaGVhZCBvZiB0aGUgYXJyYXkuXG4gIFMgZXh0ZW5kcyBbaW5mZXIgSGVhZCwgLi4uaW5mZXIgVGFpbF1cbiAgICA/IC8vIFVzaW5nIGEgdGVtcGxhdGUgbGl0ZXJhbCB0eXBlLCBjb2VyY2UgdGhlIGhlYWQgdG8gYG51bWJlcmAgaWYgcG9zc2libGUuXG4gICAgICAvLyBUaGVuLCByZWN1cnNlIG9uIHRoZSB0YWlsLlxuICAgICAgSGVhZCBleHRlbmRzIGAke251bWJlcn1gXG4gICAgICA/IFtudW1iZXIsIC4uLsm1Q29lcmNlU3RyQXJyVG9OdW1BcnI8VGFpbD5dXG4gICAgICA6IFtIZWFkLCAuLi7JtUNvZXJjZVN0ckFyclRvTnVtQXJyPFRhaWw+XVxuICAgIDogW107XG5cbi8qKlxuICogTmF2aWdhdGUgdGFrZXMgYSB0eXBlIFQgYW5kIGFuIGFycmF5IEssIGFuZCByZXR1cm5zIHRoZSB0eXBlIG9mIFRbS1swXV1bS1sxXV1bS1syXV0uLi5cbiAqL1xuZXhwb3J0IHR5cGUgybVOYXZpZ2F0ZTxcbiAgVCxcbiAgSyBleHRlbmRzIEFycmF5PHN0cmluZyB8IG51bWJlcj4sXG4+ID0gVCBleHRlbmRzIG9iamVjdCAvKiBUIG11c3QgYmUgaW5kZXhhYmxlIChvYmplY3Qgb3IgYXJyYXkpICovXG4gID8gSyBleHRlbmRzIFtpbmZlciBIZWFkLCAuLi5pbmZlciBUYWlsXSAvKiBTcGxpdCBLIGludG8gaGVhZCBhbmQgdGFpbCAqL1xuICAgID8gSGVhZCBleHRlbmRzIGtleW9mIFQgLyogaGVhZChLKSBtdXN0IGluZGV4IFQgKi9cbiAgICAgID8gVGFpbCBleHRlbmRzIChzdHJpbmcgfCBudW1iZXIpW10gLyogdGFpbChLKSBtdXN0IGJlIGFuIGFycmF5ICovXG4gICAgICAgID8gW10gZXh0ZW5kcyBUYWlsXG4gICAgICAgICAgPyBUW0hlYWRdIC8qIGJhc2UgY2FzZTogSyBjYW4gYmUgc3BsaXQsIGJ1dCBUYWlsIGlzIGVtcHR5ICovXG4gICAgICAgICAgOiDJtU5hdmlnYXRlPFRbSGVhZF0sIFRhaWw+IC8qIGV4cGxvcmUgVFtoZWFkKEspXSBieSB0YWlsKEspICovXG4gICAgICAgIDogYW55IC8qIHRhaWwoSykgd2FzIG5vdCBhbiBhcnJheSwgZ2l2ZSB1cCAqL1xuICAgICAgOiBuZXZlciAvKiBoZWFkKEspIGRvZXMgbm90IGluZGV4IFQsIGdpdmUgdXAgKi9cbiAgICA6IGFueSAvKiBLIGNhbm5vdCBiZSBzcGxpdCwgZ2l2ZSB1cCAqL1xuICA6IGFueSAvKiBUIGlzIG5vdCBpbmRleGFibGUsIGdpdmUgdXAgKi87XG5cbi8qKlxuICogybVXcml0ZWFibGUgcmVtb3ZlcyByZWFkb25seSBmcm9tIGFsbCBrZXlzLlxuICovXG5leHBvcnQgdHlwZSDJtVdyaXRlYWJsZTxUPiA9IHtcbiAgLXJlYWRvbmx5IFtQIGluIGtleW9mIFRdOiBUW1BdO1xufTtcblxuLyoqXG4gKiBHZXRQcm9wZXJ0eSB0YWtlcyBhIHR5cGUgVCBhbmQgc29tZSBwcm9wZXJ0eSBuYW1lcyBvciBpbmRpY2VzIEsuXG4gKiBJZiBLIGlzIGEgZG90LXNlcGFyYXRlZCBzdHJpbmcsIGl0IGlzIHRva2VuaXplZCBpbnRvIGFuIGFycmF5IGJlZm9yZSBwcm9jZWVkaW5nLlxuICogVGhlbiwgdGhlIHR5cGUgb2YgdGhlIG5lc3RlZCBwcm9wZXJ0eSBhdCBLIGlzIGNvbXB1dGVkOiBUW0tbMF1dW0tbMV1dW0tbMl1dLi4uXG4gKiBUaGlzIHdvcmtzIHdpdGggYm90aCBvYmplY3RzLCB3aGljaCBhcmUgaW5kZXhlZCBieSBwcm9wZXJ0eSBuYW1lLCBhbmQgYXJyYXlzLCB3aGljaCBhcmUgaW5kZXhlZFxuICogbnVtZXJpY2FsbHkuXG4gKlxuICogRm9yIGludGVybmFsIHVzZSBvbmx5LlxuICovXG5leHBvcnQgdHlwZSDJtUdldFByb3BlcnR5PFQsIEs+ID1cbiAgLy8gSyBpcyBhIHN0cmluZ1xuICBLIGV4dGVuZHMgc3RyaW5nXG4gICAgPyDJtUdldFByb3BlcnR5PFQsIMm1Q29lcmNlU3RyQXJyVG9OdW1BcnI8ybVUb2tlbml6ZTxLLCAnLic+Pj5cbiAgICA6IC8vIElzIGl0IGFuIGFycmF5XG4gICAgICDJtVdyaXRlYWJsZTxLPiBleHRlbmRzIEFycmF5PHN0cmluZyB8IG51bWJlcj5cbiAgICAgID8gybVOYXZpZ2F0ZTxULCDJtVdyaXRlYWJsZTxLPj5cbiAgICAgIDogLy8gRmFsbCB0aHJvdWdoIHBlcm1pc3NpdmVseSBpZiB3ZSBjYW4ndCBjYWxjdWxhdGUgdGhlIHR5cGUgb2YgSy5cbiAgICAgICAgYW55O1xuXG4vKipcbiAqIFRoaXMgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGBGb3JtQ29udHJvbGAsIGBGb3JtR3JvdXBgLCBhbmQgYEZvcm1BcnJheWAuXG4gKlxuICogSXQgcHJvdmlkZXMgc29tZSBvZiB0aGUgc2hhcmVkIGJlaGF2aW9yIHRoYXQgYWxsIGNvbnRyb2xzIGFuZCBncm91cHMgb2YgY29udHJvbHMgaGF2ZSwgbGlrZVxuICogcnVubmluZyB2YWxpZGF0b3JzLCBjYWxjdWxhdGluZyBzdGF0dXMsIGFuZCByZXNldHRpbmcgc3RhdGUuIEl0IGFsc28gZGVmaW5lcyB0aGUgcHJvcGVydGllc1xuICogdGhhdCBhcmUgc2hhcmVkIGJldHdlZW4gYWxsIHN1Yi1jbGFzc2VzLCBsaWtlIGB2YWx1ZWAsIGB2YWxpZGAsIGFuZCBgZGlydHlgLiBJdCBzaG91bGRuJ3QgYmVcbiAqIGluc3RhbnRpYXRlZCBkaXJlY3RseS5cbiAqXG4gKiBUaGUgZmlyc3QgdHlwZSBwYXJhbWV0ZXIgVFZhbHVlIHJlcHJlc2VudHMgdGhlIHZhbHVlIHR5cGUgb2YgdGhlIGNvbnRyb2wgKGBjb250cm9sLnZhbHVlYCkuXG4gKiBUaGUgb3B0aW9uYWwgdHlwZSBwYXJhbWV0ZXIgVFJhd1ZhbHVlICByZXByZXNlbnRzIHRoZSByYXcgdmFsdWUgdHlwZSAoYGNvbnRyb2wuZ2V0UmF3VmFsdWUoKWApLlxuICpcbiAqIEBzZWUgW0Zvcm1zIEd1aWRlXShndWlkZS9mb3JtcylcbiAqIEBzZWUgW1JlYWN0aXZlIEZvcm1zIEd1aWRlXShndWlkZS9mb3Jtcy9yZWFjdGl2ZS1mb3JtcylcbiAqIEBzZWUgW0R5bmFtaWMgRm9ybXMgR3VpZGVdKGd1aWRlL2Zvcm1zL2R5bmFtaWMtZm9ybXMpXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RDb250cm9sPFRWYWx1ZSA9IGFueSwgVFJhd1ZhbHVlIGV4dGVuZHMgVFZhbHVlID0gVFZhbHVlPiB7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3BlbmRpbmdEaXJ0eSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCBhIGNvbnRyb2wgaGFzIGl0cyBvd24gcGVuZGluZyBhc3luY2hyb25vdXMgdmFsaWRhdGlvbiBpbiBwcm9ncmVzcy5cbiAgICogSXQgYWxzbyBzdG9yZXMgaWYgdGhlIGNvbnRyb2wgc2hvdWxkIGVtaXQgZXZlbnRzIHdoZW4gdGhlIHZhbGlkYXRpb24gc3RhdHVzIGNoYW5nZXMuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgX2hhc093blBlbmRpbmdBc3luY1ZhbGlkYXRvcjogbnVsbCB8IHtlbWl0RXZlbnQ6IGJvb2xlYW59ID0gbnVsbDtcblxuICAvKiogQGludGVybmFsICovXG4gIF9wZW5kaW5nVG91Y2hlZCA9IGZhbHNlO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX29uQ29sbGVjdGlvbkNoYW5nZSA9ICgpID0+IHt9O1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3VwZGF0ZU9uPzogRm9ybUhvb2tzO1xuXG4gIHByaXZhdGUgX3BhcmVudDogRm9ybUdyb3VwIHwgRm9ybUFycmF5IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2FzeW5jVmFsaWRhdGlvblN1YnNjcmlwdGlvbjogYW55O1xuXG4gIC8qKlxuICAgKiBDb250YWlucyB0aGUgcmVzdWx0IG9mIG1lcmdpbmcgc3luY2hyb25vdXMgdmFsaWRhdG9ycyBpbnRvIGEgc2luZ2xlIHZhbGlkYXRvciBmdW5jdGlvblxuICAgKiAoY29tYmluZWQgdXNpbmcgYFZhbGlkYXRvcnMuY29tcG9zZWApLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX2NvbXBvc2VkVmFsaWRhdG9yRm4hOiBWYWxpZGF0b3JGbiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIENvbnRhaW5zIHRoZSByZXN1bHQgb2YgbWVyZ2luZyBhc3luY2hyb25vdXMgdmFsaWRhdG9ycyBpbnRvIGEgc2luZ2xlIHZhbGlkYXRvciBmdW5jdGlvblxuICAgKiAoY29tYmluZWQgdXNpbmcgYFZhbGlkYXRvcnMuY29tcG9zZUFzeW5jYCkuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJpdmF0ZSBfY29tcG9zZWRBc3luY1ZhbGlkYXRvckZuITogQXN5bmNWYWxpZGF0b3JGbiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIFN5bmNocm9ub3VzIHZhbGlkYXRvcnMgYXMgdGhleSB3ZXJlIHByb3ZpZGVkOlxuICAgKiAgLSBpbiBgQWJzdHJhY3RDb250cm9sYCBjb25zdHJ1Y3RvclxuICAgKiAgLSBhcyBhbiBhcmd1bWVudCB3aGlsZSBjYWxsaW5nIGBzZXRWYWxpZGF0b3JzYCBmdW5jdGlvblxuICAgKiAgLSB3aGlsZSBjYWxsaW5nIHRoZSBzZXR0ZXIgb24gdGhlIGB2YWxpZGF0b3JgIGZpZWxkIChlLmcuIGBjb250cm9sLnZhbGlkYXRvciA9IHZhbGlkYXRvckZuYClcbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcml2YXRlIF9yYXdWYWxpZGF0b3JzITogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdIHwgbnVsbDtcblxuICAvKipcbiAgICogQXN5bmNocm9ub3VzIHZhbGlkYXRvcnMgYXMgdGhleSB3ZXJlIHByb3ZpZGVkOlxuICAgKiAgLSBpbiBgQWJzdHJhY3RDb250cm9sYCBjb25zdHJ1Y3RvclxuICAgKiAgLSBhcyBhbiBhcmd1bWVudCB3aGlsZSBjYWxsaW5nIGBzZXRBc3luY1ZhbGlkYXRvcnNgIGZ1bmN0aW9uXG4gICAqICAtIHdoaWxlIGNhbGxpbmcgdGhlIHNldHRlciBvbiB0aGUgYGFzeW5jVmFsaWRhdG9yYCBmaWVsZCAoZS5nLiBgY29udHJvbC5hc3luY1ZhbGlkYXRvciA9XG4gICAqIGFzeW5jVmFsaWRhdG9yRm5gKVxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX3Jhd0FzeW5jVmFsaWRhdG9ycyE6IEFzeW5jVmFsaWRhdG9yRm4gfCBBc3luY1ZhbGlkYXRvckZuW10gfCBudWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgY29udHJvbC5cbiAgICpcbiAgICogKiBGb3IgYSBgRm9ybUNvbnRyb2xgLCB0aGUgY3VycmVudCB2YWx1ZS5cbiAgICogKiBGb3IgYW4gZW5hYmxlZCBgRm9ybUdyb3VwYCwgdGhlIHZhbHVlcyBvZiBlbmFibGVkIGNvbnRyb2xzIGFzIGFuIG9iamVjdFxuICAgKiB3aXRoIGEga2V5LXZhbHVlIHBhaXIgZm9yIGVhY2ggbWVtYmVyIG9mIHRoZSBncm91cC5cbiAgICogKiBGb3IgYSBkaXNhYmxlZCBgRm9ybUdyb3VwYCwgdGhlIHZhbHVlcyBvZiBhbGwgY29udHJvbHMgYXMgYW4gb2JqZWN0XG4gICAqIHdpdGggYSBrZXktdmFsdWUgcGFpciBmb3IgZWFjaCBtZW1iZXIgb2YgdGhlIGdyb3VwLlxuICAgKiAqIEZvciBhIGBGb3JtQXJyYXlgLCB0aGUgdmFsdWVzIG9mIGVuYWJsZWQgY29udHJvbHMgYXMgYW4gYXJyYXkuXG4gICAqXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdmFsdWUhOiBUVmFsdWU7XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIEFic3RyYWN0Q29udHJvbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHZhbGlkYXRvcnMgVGhlIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGZ1bmN0aW9ucyB0aGF0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSB2YWxpZGl0eSBvZlxuICAgKiAgICAgdGhpcyBjb250cm9sIHN5bmNocm9ub3VzbHkuXG4gICAqIEBwYXJhbSBhc3luY1ZhbGlkYXRvcnMgVGhlIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGZ1bmN0aW9ucyB0aGF0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHZhbGlkaXR5IG9mXG4gICAqICAgICB0aGlzIGNvbnRyb2wgYXN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICB2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbiB8IFZhbGlkYXRvckZuW10gfCBudWxsLFxuICAgIGFzeW5jVmFsaWRhdG9yczogQXN5bmNWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm5bXSB8IG51bGwsXG4gICkge1xuICAgIHRoaXMuX2Fzc2lnblZhbGlkYXRvcnModmFsaWRhdG9ycyk7XG4gICAgdGhpcy5fYXNzaWduQXN5bmNWYWxpZGF0b3JzKGFzeW5jVmFsaWRhdG9ycyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgdmFsaWRpdHkgb2YgdGhpcyBjb250cm9sIHN5bmNocm9ub3VzbHkuXG4gICAqIElmIG11bHRpcGxlIHZhbGlkYXRvcnMgaGF2ZSBiZWVuIGFkZGVkLCB0aGlzIHdpbGwgYmUgYSBzaW5nbGUgY29tcG9zZWQgZnVuY3Rpb24uXG4gICAqIFNlZSBgVmFsaWRhdG9ycy5jb21wb3NlKClgIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZ2V0IHZhbGlkYXRvcigpOiBWYWxpZGF0b3JGbiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9jb21wb3NlZFZhbGlkYXRvckZuO1xuICB9XG4gIHNldCB2YWxpZGF0b3IodmFsaWRhdG9yRm46IFZhbGlkYXRvckZuIHwgbnVsbCkge1xuICAgIHRoaXMuX3Jhd1ZhbGlkYXRvcnMgPSB0aGlzLl9jb21wb3NlZFZhbGlkYXRvckZuID0gdmFsaWRhdG9yRm47XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgdmFsaWRpdHkgb2YgdGhpcyBjb250cm9sIGFzeW5jaHJvbm91c2x5LlxuICAgKiBJZiBtdWx0aXBsZSB2YWxpZGF0b3JzIGhhdmUgYmVlbiBhZGRlZCwgdGhpcyB3aWxsIGJlIGEgc2luZ2xlIGNvbXBvc2VkIGZ1bmN0aW9uLlxuICAgKiBTZWUgYFZhbGlkYXRvcnMuY29tcG9zZSgpYCBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi5cbiAgICovXG4gIGdldCBhc3luY1ZhbGlkYXRvcigpOiBBc3luY1ZhbGlkYXRvckZuIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbXBvc2VkQXN5bmNWYWxpZGF0b3JGbjtcbiAgfVxuICBzZXQgYXN5bmNWYWxpZGF0b3IoYXN5bmNWYWxpZGF0b3JGbjogQXN5bmNWYWxpZGF0b3JGbiB8IG51bGwpIHtcbiAgICB0aGlzLl9yYXdBc3luY1ZhbGlkYXRvcnMgPSB0aGlzLl9jb21wb3NlZEFzeW5jVmFsaWRhdG9yRm4gPSBhc3luY1ZhbGlkYXRvckZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwYXJlbnQgY29udHJvbC5cbiAgICovXG4gIGdldCBwYXJlbnQoKTogRm9ybUdyb3VwIHwgRm9ybUFycmF5IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdmFsaWRhdGlvbiBzdGF0dXMgb2YgdGhlIGNvbnRyb2wuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIEZvcm1Db250cm9sU3RhdHVzfVxuICAgKlxuICAgKiBUaGVzZSBzdGF0dXMgdmFsdWVzIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIHNvIGEgY29udHJvbCBjYW5ub3QgYmVcbiAgICogYm90aCB2YWxpZCBBTkQgaW52YWxpZCBvciBpbnZhbGlkIEFORCBkaXNhYmxlZC5cbiAgICovXG4gIGdldCBzdGF0dXMoKTogRm9ybUNvbnRyb2xTdGF0dXMge1xuICAgIHJldHVybiB1bnRyYWNrZWQodGhpcy5zdGF0dXNSZWFjdGl2ZSkhO1xuICB9XG4gIHByaXZhdGUgc2V0IHN0YXR1cyh2OiBGb3JtQ29udHJvbFN0YXR1cykge1xuICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLnN0YXR1c1JlYWN0aXZlLnNldCh2KSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICByZWFkb25seSBfc3RhdHVzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5zdGF0dXNSZWFjdGl2ZSgpKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGF0dXNSZWFjdGl2ZSA9IHNpZ25hbDxGb3JtQ29udHJvbFN0YXR1cyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGB2YWxpZGAgd2hlbiBpdHMgYHN0YXR1c2AgaXMgYFZBTElEYC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29udHJvbCBoYXMgcGFzc2VkIGFsbCBvZiBpdHMgdmFsaWRhdGlvbiB0ZXN0cyxcbiAgICogZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgZ2V0IHZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gVkFMSUQ7XG4gIH1cblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBpbnZhbGlkYCB3aGVuIGl0cyBgc3RhdHVzYCBpcyBgSU5WQUxJRGAuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIEFic3RyYWN0Q29udHJvbC5zdGF0dXN9XG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhpcyBjb250cm9sIGhhcyBmYWlsZWQgb25lIG9yIG1vcmUgb2YgaXRzIHZhbGlkYXRpb24gY2hlY2tzLFxuICAgKiBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBnZXQgaW52YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXMgPT09IElOVkFMSUQ7XG4gIH1cblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBwZW5kaW5nYCB3aGVuIGl0cyBgc3RhdHVzYCBpcyBgUEVORElOR2AuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIEFic3RyYWN0Q29udHJvbC5zdGF0dXN9XG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhpcyBjb250cm9sIGlzIGluIHRoZSBwcm9jZXNzIG9mIGNvbmR1Y3RpbmcgYSB2YWxpZGF0aW9uIGNoZWNrLFxuICAgKiBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBnZXQgcGVuZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXMgPT0gUEVORElORztcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGNvbnRyb2wgaXMgYGRpc2FibGVkYCB3aGVuIGl0cyBgc3RhdHVzYCBpcyBgRElTQUJMRURgLlxuICAgKlxuICAgKiBEaXNhYmxlZCBjb250cm9scyBhcmUgZXhlbXB0IGZyb20gdmFsaWRhdGlvbiBjaGVja3MgYW5kXG4gICAqIGFyZSBub3QgaW5jbHVkZWQgaW4gdGhlIGFnZ3JlZ2F0ZSB2YWx1ZSBvZiB0aGVpciBhbmNlc3RvclxuICAgKiBjb250cm9scy5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29udHJvbCBpcyBkaXNhYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gRElTQUJMRUQ7XG4gIH1cblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBlbmFibGVkYCBhcyBsb25nIGFzIGl0cyBgc3RhdHVzYCBpcyBub3QgYERJU0FCTEVEYC5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29udHJvbCBoYXMgYW55IHN0YXR1cyBvdGhlciB0aGFuICdESVNBQkxFRCcsXG4gICAqIGZhbHNlIGlmIHRoZSBzdGF0dXMgaXMgJ0RJU0FCTEVEJy5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICovXG4gIGdldCBlbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyAhPT0gRElTQUJMRUQ7XG4gIH1cblxuICAvKipcbiAgICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgYW55IGVycm9ycyBnZW5lcmF0ZWQgYnkgZmFpbGluZyB2YWxpZGF0aW9uLFxuICAgKiBvciBudWxsIGlmIHRoZXJlIGFyZSBubyBlcnJvcnMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZXJyb3JzITogVmFsaWRhdGlvbkVycm9ycyB8IG51bGw7XG5cbiAgLyoqXG4gICAqIEEgY29udHJvbCBpcyBgcHJpc3RpbmVgIGlmIHRoZSB1c2VyIGhhcyBub3QgeWV0IGNoYW5nZWRcbiAgICogdGhlIHZhbHVlIGluIHRoZSBVSS5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdXNlciBoYXMgbm90IHlldCBjaGFuZ2VkIHRoZSB2YWx1ZSBpbiB0aGUgVUk7IGNvbXBhcmUgYGRpcnR5YC5cbiAgICogUHJvZ3JhbW1hdGljIGNoYW5nZXMgdG8gYSBjb250cm9sJ3MgdmFsdWUgZG8gbm90IG1hcmsgaXQgZGlydHkuXG4gICAqL1xuICBnZXQgcHJpc3RpbmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHVudHJhY2tlZCh0aGlzLnByaXN0aW5lUmVhY3RpdmUpO1xuICB9XG4gIHByaXZhdGUgc2V0IHByaXN0aW5lKHY6IGJvb2xlYW4pIHtcbiAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy5wcmlzdGluZVJlYWN0aXZlLnNldCh2KSk7XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICByZWFkb25seSBfcHJpc3RpbmUgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnByaXN0aW5lUmVhY3RpdmUoKSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJpc3RpbmVSZWFjdGl2ZSA9IHNpZ25hbCh0cnVlKTtcblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBkaXJ0eWAgaWYgdGhlIHVzZXIgaGFzIGNoYW5nZWQgdGhlIHZhbHVlXG4gICAqIGluIHRoZSBVSS5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdXNlciBoYXMgY2hhbmdlZCB0aGUgdmFsdWUgb2YgdGhpcyBjb250cm9sIGluIHRoZSBVSTsgY29tcGFyZSBgcHJpc3RpbmVgLlxuICAgKiBQcm9ncmFtbWF0aWMgY2hhbmdlcyB0byBhIGNvbnRyb2wncyB2YWx1ZSBkbyBub3QgbWFyayBpdCBkaXJ0eS5cbiAgICovXG4gIGdldCBkaXJ0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMucHJpc3RpbmU7XG4gIH1cblxuICAvKipcbiAgICogVHJ1ZSBpZiB0aGUgY29udHJvbCBpcyBtYXJrZWQgYXMgYHRvdWNoZWRgLlxuICAgKlxuICAgKiBBIGNvbnRyb2wgaXMgbWFya2VkIGB0b3VjaGVkYCBvbmNlIHRoZSB1c2VyIGhhcyB0cmlnZ2VyZWRcbiAgICogYSBgYmx1cmAgZXZlbnQgb24gaXQuXG4gICAqL1xuICBnZXQgdG91Y2hlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdW50cmFja2VkKHRoaXMudG91Y2hlZFJlYWN0aXZlKTtcbiAgfVxuICBwcml2YXRlIHNldCB0b3VjaGVkKHY6IGJvb2xlYW4pIHtcbiAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy50b3VjaGVkUmVhY3RpdmUuc2V0KHYpKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIHJlYWRvbmx5IF90b3VjaGVkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy50b3VjaGVkUmVhY3RpdmUoKSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdG91Y2hlZFJlYWN0aXZlID0gc2lnbmFsKGZhbHNlKTtcblxuICAvKipcbiAgICogVHJ1ZSBpZiB0aGUgY29udHJvbCBoYXMgbm90IGJlZW4gbWFya2VkIGFzIHRvdWNoZWRcbiAgICpcbiAgICogQSBjb250cm9sIGlzIGB1bnRvdWNoZWRgIGlmIHRoZSB1c2VyIGhhcyBub3QgeWV0IHRyaWdnZXJlZFxuICAgKiBhIGBibHVyYCBldmVudCBvbiBpdC5cbiAgICovXG4gIGdldCB1bnRvdWNoZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLnRvdWNoZWQ7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3NlZCBhcyBvYnNlcnZhYmxlLCBzZWUgYmVsb3cuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcmVhZG9ubHkgX2V2ZW50cyA9IG5ldyBTdWJqZWN0PENvbnRyb2xFdmVudDxUVmFsdWU+PigpO1xuXG4gIC8qKlxuICAgKiBBIG11bHRpY2FzdGluZyBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gZXZlbnQgZXZlcnkgdGltZSB0aGUgc3RhdGUgb2YgdGhlIGNvbnRyb2wgY2hhbmdlcy5cbiAgICogSXQgZW1pdHMgZm9yIHZhbHVlLCBzdGF0dXMsIHByaXN0aW5lIG9yIHRvdWNoZWQgY2hhbmdlcy5cbiAgICpcbiAgICogKipOb3RlKio6IE9uIHZhbHVlIGNoYW5nZSwgdGhlIGVtaXQgaGFwcGVucyByaWdodCBhZnRlciBhIHZhbHVlIG9mIHRoaXMgY29udHJvbCBpcyB1cGRhdGVkLiBUaGVcbiAgICogdmFsdWUgb2YgYSBwYXJlbnQgY29udHJvbCAoZm9yIGV4YW1wbGUgaWYgdGhpcyBGb3JtQ29udHJvbCBpcyBhIHBhcnQgb2YgYSBGb3JtR3JvdXApIGlzIHVwZGF0ZWRcbiAgICogbGF0ZXIsIHNvIGFjY2Vzc2luZyBhIHZhbHVlIG9mIGEgcGFyZW50IGNvbnRyb2wgKHVzaW5nIHRoZSBgdmFsdWVgIHByb3BlcnR5KSBmcm9tIHRoZSBjYWxsYmFja1xuICAgKiBvZiB0aGlzIGV2ZW50IG1pZ2h0IHJlc3VsdCBpbiBnZXR0aW5nIGEgdmFsdWUgdGhhdCBoYXMgbm90IGJlZW4gdXBkYXRlZCB5ZXQuIFN1YnNjcmliZSB0byB0aGVcbiAgICogYGV2ZW50c2Agb2YgdGhlIHBhcmVudCBjb250cm9sIGluc3RlYWQuXG4gICAqIEZvciBvdGhlciBldmVudCB0eXBlcywgdGhlIGV2ZW50cyBhcmUgZW1pdHRlZCBhZnRlciB0aGUgcGFyZW50IGNvbnRyb2wgaGFzIGJlZW4gdXBkYXRlZC5cbiAgICpcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBldmVudHMgPSB0aGlzLl9ldmVudHMuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqXG4gICAqIEEgbXVsdGljYXN0aW5nIG9ic2VydmFibGUgdGhhdCBlbWl0cyBhbiBldmVudCBldmVyeSB0aW1lIHRoZSB2YWx1ZSBvZiB0aGUgY29udHJvbCBjaGFuZ2VzLCBpblxuICAgKiB0aGUgVUkgb3IgcHJvZ3JhbW1hdGljYWxseS4gSXQgYWxzbyBlbWl0cyBhbiBldmVudCBlYWNoIHRpbWUgeW91IGNhbGwgZW5hYmxlKCkgb3IgZGlzYWJsZSgpXG4gICAqIHdpdGhvdXQgcGFzc2luZyBhbG9uZyB7ZW1pdEV2ZW50OiBmYWxzZX0gYXMgYSBmdW5jdGlvbiBhcmd1bWVudC5cbiAgICpcbiAgICogKipOb3RlKio6IHRoZSBlbWl0IGhhcHBlbnMgcmlnaHQgYWZ0ZXIgYSB2YWx1ZSBvZiB0aGlzIGNvbnRyb2wgaXMgdXBkYXRlZC4gVGhlIHZhbHVlIG9mIGFcbiAgICogcGFyZW50IGNvbnRyb2wgKGZvciBleGFtcGxlIGlmIHRoaXMgRm9ybUNvbnRyb2wgaXMgYSBwYXJ0IG9mIGEgRm9ybUdyb3VwKSBpcyB1cGRhdGVkIGxhdGVyLCBzb1xuICAgKiBhY2Nlc3NpbmcgYSB2YWx1ZSBvZiBhIHBhcmVudCBjb250cm9sICh1c2luZyB0aGUgYHZhbHVlYCBwcm9wZXJ0eSkgZnJvbSB0aGUgY2FsbGJhY2sgb2YgdGhpc1xuICAgKiBldmVudCBtaWdodCByZXN1bHQgaW4gZ2V0dGluZyBhIHZhbHVlIHRoYXQgaGFzIG5vdCBiZWVuIHVwZGF0ZWQgeWV0LiBTdWJzY3JpYmUgdG8gdGhlXG4gICAqIGB2YWx1ZUNoYW5nZXNgIGV2ZW50IG9mIHRoZSBwYXJlbnQgY29udHJvbCBpbnN0ZWFkLlxuICAgKlxuICAgKiBUT0RPOiB0aGlzIHNob3VsZCBiZSBwaXBlZCBmcm9tIGV2ZW50cygpIGJ1dCBpcyBicmVha2luZyBpbiBHM1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlQ2hhbmdlcyE6IE9ic2VydmFibGU8VFZhbHVlPjtcblxuICAvKipcbiAgICogQSBtdWx0aWNhc3Rpbmcgb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIGFuIGV2ZW50IGV2ZXJ5IHRpbWUgdGhlIHZhbGlkYXRpb24gYHN0YXR1c2Agb2YgdGhlIGNvbnRyb2xcbiAgICogcmVjYWxjdWxhdGVzLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBGb3JtQ29udHJvbFN0YXR1c31cbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogVE9ETzogdGhpcyBzaG91bGQgYmUgcGlwZWQgZnJvbSBldmVudHMoKSBidXQgaXMgYnJlYWtpbmcgaW4gRzNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzdGF0dXNDaGFuZ2VzITogT2JzZXJ2YWJsZTxGb3JtQ29udHJvbFN0YXR1cz47XG5cbiAgLyoqXG4gICAqIFJlcG9ydHMgdGhlIHVwZGF0ZSBzdHJhdGVneSBvZiB0aGUgYEFic3RyYWN0Q29udHJvbGAgKG1lYW5pbmdcbiAgICogdGhlIGV2ZW50IG9uIHdoaWNoIHRoZSBjb250cm9sIHVwZGF0ZXMgaXRzZWxmKS5cbiAgICogUG9zc2libGUgdmFsdWVzOiBgJ2NoYW5nZSdgIHwgYCdibHVyJ2AgfCBgJ3N1Ym1pdCdgXG4gICAqIERlZmF1bHQgdmFsdWU6IGAnY2hhbmdlJ2BcbiAgICovXG4gIGdldCB1cGRhdGVPbigpOiBGb3JtSG9va3Mge1xuICAgIHJldHVybiB0aGlzLl91cGRhdGVPbiA/IHRoaXMuX3VwZGF0ZU9uIDogdGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC51cGRhdGVPbiA6ICdjaGFuZ2UnO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHN5bmNocm9ub3VzIHZhbGlkYXRvcnMgdGhhdCBhcmUgYWN0aXZlIG9uIHRoaXMgY29udHJvbC4gIENhbGxpbmdcbiAgICogdGhpcyBvdmVyd3JpdGVzIGFueSBleGlzdGluZyBzeW5jaHJvbm91cyB2YWxpZGF0b3JzLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIElmIHlvdSB3YW50IHRvIGFkZCBhIG5ldyB2YWxpZGF0b3Igd2l0aG91dCBhZmZlY3RpbmcgZXhpc3Rpbmcgb25lcywgY29uc2lkZXJcbiAgICogdXNpbmcgYGFkZFZhbGlkYXRvcnMoKWAgbWV0aG9kIGluc3RlYWQuXG4gICAqL1xuICBzZXRWYWxpZGF0b3JzKHZhbGlkYXRvcnM6IFZhbGlkYXRvckZuIHwgVmFsaWRhdG9yRm5bXSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9hc3NpZ25WYWxpZGF0b3JzKHZhbGlkYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGFzeW5jaHJvbm91cyB2YWxpZGF0b3JzIHRoYXQgYXJlIGFjdGl2ZSBvbiB0aGlzIGNvbnRyb2wuIENhbGxpbmcgdGhpc1xuICAgKiBvdmVyd3JpdGVzIGFueSBleGlzdGluZyBhc3luY2hyb25vdXMgdmFsaWRhdG9ycy5cbiAgICpcbiAgICogV2hlbiB5b3UgYWRkIG9yIHJlbW92ZSBhIHZhbGlkYXRvciBhdCBydW4gdGltZSwgeW91IG11c3QgY2FsbFxuICAgKiBgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpYCBmb3IgdGhlIG5ldyB2YWxpZGF0aW9uIHRvIHRha2UgZWZmZWN0LlxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byBhZGQgYSBuZXcgdmFsaWRhdG9yIHdpdGhvdXQgYWZmZWN0aW5nIGV4aXN0aW5nIG9uZXMsIGNvbnNpZGVyXG4gICAqIHVzaW5nIGBhZGRBc3luY1ZhbGlkYXRvcnMoKWAgbWV0aG9kIGluc3RlYWQuXG4gICAqL1xuICBzZXRBc3luY1ZhbGlkYXRvcnModmFsaWRhdG9yczogQXN5bmNWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm5bXSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9hc3NpZ25Bc3luY1ZhbGlkYXRvcnModmFsaWRhdG9ycyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgc3luY2hyb25vdXMgdmFsaWRhdG9yIG9yIHZhbGlkYXRvcnMgdG8gdGhpcyBjb250cm9sLCB3aXRob3V0IGFmZmVjdGluZyBvdGhlciB2YWxpZGF0b3JzLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEFkZGluZyBhIHZhbGlkYXRvciB0aGF0IGFscmVhZHkgZXhpc3RzIHdpbGwgaGF2ZSBubyBlZmZlY3QuIElmIGR1cGxpY2F0ZSB2YWxpZGF0b3IgZnVuY3Rpb25zXG4gICAqIGFyZSBwcmVzZW50IGluIHRoZSBgdmFsaWRhdG9yc2AgYXJyYXksIG9ubHkgdGhlIGZpcnN0IGluc3RhbmNlIHdvdWxkIGJlIGFkZGVkIHRvIGEgZm9ybVxuICAgKiBjb250cm9sLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsaWRhdG9ycyBUaGUgbmV3IHZhbGlkYXRvciBmdW5jdGlvbiBvciBmdW5jdGlvbnMgdG8gYWRkIHRvIHRoaXMgY29udHJvbC5cbiAgICovXG4gIGFkZFZhbGlkYXRvcnModmFsaWRhdG9yczogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdKTogdm9pZCB7XG4gICAgdGhpcy5zZXRWYWxpZGF0b3JzKGFkZFZhbGlkYXRvcnModmFsaWRhdG9ycywgdGhpcy5fcmF3VmFsaWRhdG9ycykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBhc3luY2hyb25vdXMgdmFsaWRhdG9yIG9yIHZhbGlkYXRvcnMgdG8gdGhpcyBjb250cm9sLCB3aXRob3V0IGFmZmVjdGluZyBvdGhlclxuICAgKiB2YWxpZGF0b3JzLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEFkZGluZyBhIHZhbGlkYXRvciB0aGF0IGFscmVhZHkgZXhpc3RzIHdpbGwgaGF2ZSBubyBlZmZlY3QuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3JzIFRoZSBuZXcgYXN5bmNocm9ub3VzIHZhbGlkYXRvciBmdW5jdGlvbiBvciBmdW5jdGlvbnMgdG8gYWRkIHRvIHRoaXMgY29udHJvbC5cbiAgICovXG4gIGFkZEFzeW5jVmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBBc3luY1ZhbGlkYXRvckZuIHwgQXN5bmNWYWxpZGF0b3JGbltdKTogdm9pZCB7XG4gICAgdGhpcy5zZXRBc3luY1ZhbGlkYXRvcnMoYWRkVmFsaWRhdG9ycyh2YWxpZGF0b3JzLCB0aGlzLl9yYXdBc3luY1ZhbGlkYXRvcnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBzeW5jaHJvbm91cyB2YWxpZGF0b3IgZnJvbSB0aGlzIGNvbnRyb2wsIHdpdGhvdXQgYWZmZWN0aW5nIG90aGVyIHZhbGlkYXRvcnMuXG4gICAqIFZhbGlkYXRvcnMgYXJlIGNvbXBhcmVkIGJ5IGZ1bmN0aW9uIHJlZmVyZW5jZTsgeW91IG11c3QgcGFzcyBhIHJlZmVyZW5jZSB0byB0aGUgZXhhY3Qgc2FtZVxuICAgKiB2YWxpZGF0b3IgZnVuY3Rpb24gYXMgdGhlIG9uZSB0aGF0IHdhcyBvcmlnaW5hbGx5IHNldC4gSWYgYSBwcm92aWRlZCB2YWxpZGF0b3IgaXMgbm90IGZvdW5kLFxuICAgKiBpdCBpcyBpZ25vcmVkLlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKlxuICAgKiAjIyMgUmVmZXJlbmNlIHRvIGEgVmFsaWRhdG9yRm5cbiAgICpcbiAgICogYGBgXG4gICAqIC8vIFJlZmVyZW5jZSB0byB0aGUgUmVxdWlyZWRWYWxpZGF0b3JcbiAgICogY29uc3QgY3RybCA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPignJywgVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG4gICAqIGN0cmwucmVtb3ZlVmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcbiAgICpcbiAgICogLy8gUmVmZXJlbmNlIHRvIGFub255bW91cyBmdW5jdGlvbiBpbnNpZGUgTWluVmFsaWRhdG9yXG4gICAqIGNvbnN0IG1pblZhbGlkYXRvciA9IFZhbGlkYXRvcnMubWluKDMpO1xuICAgKiBjb25zdCBjdHJsID0gbmV3IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+KCcnLCBtaW5WYWxpZGF0b3IpO1xuICAgKiBleHBlY3QoY3RybC5oYXNWYWxpZGF0b3IobWluVmFsaWRhdG9yKSkudG9FcXVhbCh0cnVlKVxuICAgKiBleHBlY3QoY3RybC5oYXNWYWxpZGF0b3IoVmFsaWRhdG9ycy5taW4oMykpKS50b0VxdWFsKGZhbHNlKVxuICAgKlxuICAgKiBjdHJsLnJlbW92ZVZhbGlkYXRvcnMobWluVmFsaWRhdG9yKTtcbiAgICogYGBgXG4gICAqXG4gICAqIFdoZW4geW91IGFkZCBvciByZW1vdmUgYSB2YWxpZGF0b3IgYXQgcnVuIHRpbWUsIHlvdSBtdXN0IGNhbGxcbiAgICogYHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKWAgZm9yIHRoZSBuZXcgdmFsaWRhdGlvbiB0byB0YWtlIGVmZmVjdC5cbiAgICpcbiAgICogQHBhcmFtIHZhbGlkYXRvcnMgVGhlIHZhbGlkYXRvciBvciB2YWxpZGF0b3JzIHRvIHJlbW92ZS5cbiAgICovXG4gIHJlbW92ZVZhbGlkYXRvcnModmFsaWRhdG9yczogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdKTogdm9pZCB7XG4gICAgdGhpcy5zZXRWYWxpZGF0b3JzKHJlbW92ZVZhbGlkYXRvcnModmFsaWRhdG9ycywgdGhpcy5fcmF3VmFsaWRhdG9ycykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBhc3luY2hyb25vdXMgdmFsaWRhdG9yIGZyb20gdGhpcyBjb250cm9sLCB3aXRob3V0IGFmZmVjdGluZyBvdGhlciB2YWxpZGF0b3JzLlxuICAgKiBWYWxpZGF0b3JzIGFyZSBjb21wYXJlZCBieSBmdW5jdGlvbiByZWZlcmVuY2U7IHlvdSBtdXN0IHBhc3MgYSByZWZlcmVuY2UgdG8gdGhlIGV4YWN0IHNhbWVcbiAgICogdmFsaWRhdG9yIGZ1bmN0aW9uIGFzIHRoZSBvbmUgdGhhdCB3YXMgb3JpZ2luYWxseSBzZXQuIElmIGEgcHJvdmlkZWQgdmFsaWRhdG9yIGlzIG5vdCBmb3VuZCwgaXRcbiAgICogaXMgaWdub3JlZC5cbiAgICpcbiAgICogV2hlbiB5b3UgYWRkIG9yIHJlbW92ZSBhIHZhbGlkYXRvciBhdCBydW4gdGltZSwgeW91IG11c3QgY2FsbFxuICAgKiBgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpYCBmb3IgdGhlIG5ldyB2YWxpZGF0aW9uIHRvIHRha2UgZWZmZWN0LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsaWRhdG9ycyBUaGUgYXN5bmNocm9ub3VzIHZhbGlkYXRvciBvciB2YWxpZGF0b3JzIHRvIHJlbW92ZS5cbiAgICovXG4gIHJlbW92ZUFzeW5jVmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBBc3luY1ZhbGlkYXRvckZuIHwgQXN5bmNWYWxpZGF0b3JGbltdKTogdm9pZCB7XG4gICAgdGhpcy5zZXRBc3luY1ZhbGlkYXRvcnMocmVtb3ZlVmFsaWRhdG9ycyh2YWxpZGF0b3JzLCB0aGlzLl9yYXdBc3luY1ZhbGlkYXRvcnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB3aGV0aGVyIGEgc3luY2hyb25vdXMgdmFsaWRhdG9yIGZ1bmN0aW9uIGlzIHByZXNlbnQgb24gdGhpcyBjb250cm9sLiBUaGUgcHJvdmlkZWRcbiAgICogdmFsaWRhdG9yIG11c3QgYmUgYSByZWZlcmVuY2UgdG8gdGhlIGV4YWN0IHNhbWUgZnVuY3Rpb24gdGhhdCB3YXMgcHJvdmlkZWQuXG4gICAqXG4gICAqIEB1c2FnZU5vdGVzXG4gICAqXG4gICAqICMjIyBSZWZlcmVuY2UgdG8gYSBWYWxpZGF0b3JGblxuICAgKlxuICAgKiBgYGBcbiAgICogLy8gUmVmZXJlbmNlIHRvIHRoZSBSZXF1aXJlZFZhbGlkYXRvclxuICAgKiBjb25zdCBjdHJsID0gbmV3IEZvcm1Db250cm9sPG51bWJlciB8IG51bGw+KDAsIFZhbGlkYXRvcnMucmVxdWlyZWQpO1xuICAgKiBleHBlY3QoY3RybC5oYXNWYWxpZGF0b3IoVmFsaWRhdG9ycy5yZXF1aXJlZCkpLnRvRXF1YWwodHJ1ZSlcbiAgICpcbiAgICogLy8gUmVmZXJlbmNlIHRvIGFub255bW91cyBmdW5jdGlvbiBpbnNpZGUgTWluVmFsaWRhdG9yXG4gICAqIGNvbnN0IG1pblZhbGlkYXRvciA9IFZhbGlkYXRvcnMubWluKDMpO1xuICAgKiBjb25zdCBjdHJsID0gbmV3IEZvcm1Db250cm9sPG51bWJlciB8IG51bGw+KDAsIG1pblZhbGlkYXRvcik7XG4gICAqIGV4cGVjdChjdHJsLmhhc1ZhbGlkYXRvcihtaW5WYWxpZGF0b3IpKS50b0VxdWFsKHRydWUpXG4gICAqIGV4cGVjdChjdHJsLmhhc1ZhbGlkYXRvcihWYWxpZGF0b3JzLm1pbigzKSkpLnRvRXF1YWwoZmFsc2UpXG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gdmFsaWRhdG9yIFRoZSB2YWxpZGF0b3IgdG8gY2hlY2sgZm9yIHByZXNlbmNlLiBDb21wYXJlZCBieSBmdW5jdGlvbiByZWZlcmVuY2UuXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHByb3ZpZGVkIHZhbGlkYXRvciB3YXMgZm91bmQgb24gdGhpcyBjb250cm9sLlxuICAgKi9cbiAgaGFzVmFsaWRhdG9yKHZhbGlkYXRvcjogVmFsaWRhdG9yRm4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGFzVmFsaWRhdG9yKHRoaXMuX3Jhd1ZhbGlkYXRvcnMsIHZhbGlkYXRvcik7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciBhbiBhc3luY2hyb25vdXMgdmFsaWRhdG9yIGZ1bmN0aW9uIGlzIHByZXNlbnQgb24gdGhpcyBjb250cm9sLiBUaGUgcHJvdmlkZWRcbiAgICogdmFsaWRhdG9yIG11c3QgYmUgYSByZWZlcmVuY2UgdG8gdGhlIGV4YWN0IHNhbWUgZnVuY3Rpb24gdGhhdCB3YXMgcHJvdmlkZWQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3IgVGhlIGFzeW5jaHJvbm91cyB2YWxpZGF0b3IgdG8gY2hlY2sgZm9yIHByZXNlbmNlLiBDb21wYXJlZCBieSBmdW5jdGlvblxuICAgKiAgICAgcmVmZXJlbmNlLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBwcm92aWRlZCBhc3luY2hyb25vdXMgdmFsaWRhdG9yIHdhcyBmb3VuZCBvbiB0aGlzIGNvbnRyb2wuXG4gICAqL1xuICBoYXNBc3luY1ZhbGlkYXRvcih2YWxpZGF0b3I6IEFzeW5jVmFsaWRhdG9yRm4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGFzVmFsaWRhdG9yKHRoaXMuX3Jhd0FzeW5jVmFsaWRhdG9ycywgdmFsaWRhdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbXB0aWVzIG91dCB0aGUgc3luY2hyb25vdXMgdmFsaWRhdG9yIGxpc3QuXG4gICAqXG4gICAqIFdoZW4geW91IGFkZCBvciByZW1vdmUgYSB2YWxpZGF0b3IgYXQgcnVuIHRpbWUsIHlvdSBtdXN0IGNhbGxcbiAgICogYHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKWAgZm9yIHRoZSBuZXcgdmFsaWRhdGlvbiB0byB0YWtlIGVmZmVjdC5cbiAgICpcbiAgICovXG4gIGNsZWFyVmFsaWRhdG9ycygpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRvciA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRW1wdGllcyBvdXQgdGhlIGFzeW5jIHZhbGlkYXRvciBsaXN0LlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqL1xuICBjbGVhckFzeW5jVmFsaWRhdG9ycygpOiB2b2lkIHtcbiAgICB0aGlzLmFzeW5jVmFsaWRhdG9yID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY29udHJvbCBhcyBgdG91Y2hlZGAuIEEgY29udHJvbCBpcyB0b3VjaGVkIGJ5IGZvY3VzIGFuZFxuICAgKiBibHVyIGV2ZW50cyB0aGF0IGRvIG5vdCBjaGFuZ2UgdGhlIHZhbHVlLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBtYXJrQXNVbnRvdWNoZWQoKX1cbiAgICogQHNlZSB7QGxpbmsgbWFya0FzRGlydHkoKX1cbiAgICogQHNlZSB7QGxpbmsgbWFya0FzUHJpc3RpbmUoKX1cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzIGNoYW5nZXNcbiAgICogYW5kIGVtaXRzIGV2ZW50cyBhZnRlciBtYXJraW5nIGlzIGFwcGxpZWQuXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBtYXJrIG9ubHkgdGhpcyBjb250cm9sLiBXaGVuIGZhbHNlIG9yIG5vdCBzdXBwbGllZCxcbiAgICogbWFya3MgYWxsIGRpcmVjdCBhbmNlc3RvcnMuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqICogYGVtaXRFdmVudGA6IFdoZW4gdHJ1ZSBvciBub3Qgc3VwcGxpZWQgKHRoZSBkZWZhdWx0KSwgdGhlIGBldmVudHNgXG4gICAqIG9ic2VydmFibGUgZW1pdHMgYSBgVG91Y2hlZENoYW5nZUV2ZW50YCB3aXRoIHRoZSBgdG91Y2hlZGAgcHJvcGVydHkgYmVpbmcgYHRydWVgLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqL1xuICBtYXJrQXNUb3VjaGVkKG9wdHM/OiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFufSk6IHZvaWQ7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgVXNlZCB0byBwcm9wYWdhdGUgdGhlIHNvdXJjZSBjb250cm9sIGRvd253YXJkc1xuICAgKi9cbiAgbWFya0FzVG91Y2hlZChvcHRzPzoge1xuICAgIG9ubHlTZWxmPzogYm9vbGVhbjtcbiAgICBlbWl0RXZlbnQ/OiBib29sZWFuO1xuICAgIHNvdXJjZUNvbnRyb2w/OiBBYnN0cmFjdENvbnRyb2w7XG4gIH0pOiB2b2lkO1xuICBtYXJrQXNUb3VjaGVkKFxuICAgIG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW47IHNvdXJjZUNvbnRyb2w/OiBBYnN0cmFjdENvbnRyb2x9ID0ge30sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGNoYW5nZWQgPSB0aGlzLnRvdWNoZWQgPT09IGZhbHNlO1xuICAgIHRoaXMudG91Y2hlZCA9IHRydWU7XG5cbiAgICBjb25zdCBzb3VyY2VDb250cm9sID0gb3B0cy5zb3VyY2VDb250cm9sID8/IHRoaXM7XG4gICAgaWYgKHRoaXMuX3BhcmVudCAmJiAhb3B0cy5vbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50Lm1hcmtBc1RvdWNoZWQoey4uLm9wdHMsIHNvdXJjZUNvbnRyb2x9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlZCAmJiBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuX2V2ZW50cy5uZXh0KG5ldyBUb3VjaGVkQ2hhbmdlRXZlbnQodHJ1ZSwgc291cmNlQ29udHJvbCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY29udHJvbCBhbmQgYWxsIGl0cyBkZXNjZW5kYW50IGNvbnRyb2xzIGFzIGB0b3VjaGVkYC5cbiAgICogQHNlZSB7QGxpbmsgbWFya0FzVG91Y2hlZCgpfVxuICAgKlxuICAgKiBAcGFyYW0gb3B0cyBDb25maWd1cmF0aW9uIG9wdGlvbnMgdGhhdCBkZXRlcm1pbmUgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlc1xuICAgKiBhbmQgZW1pdHMgZXZlbnRzIGFmdGVyIG1hcmtpbmcgaXMgYXBwbGllZC5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYGV2ZW50c2BcbiAgICogb2JzZXJ2YWJsZSBlbWl0cyBhIGBUb3VjaGVkQ2hhbmdlRXZlbnRgIHdpdGggdGhlIGB0b3VjaGVkYCBwcm9wZXJ0eSBiZWluZyBgdHJ1ZWAuXG4gICAqIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICovXG4gIG1hcmtBbGxBc1RvdWNoZWQob3B0czoge2VtaXRFdmVudD86IGJvb2xlYW59ID0ge30pOiB2b2lkIHtcbiAgICB0aGlzLm1hcmtBc1RvdWNoZWQoe29ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IG9wdHMuZW1pdEV2ZW50LCBzb3VyY2VDb250cm9sOiB0aGlzfSk7XG5cbiAgICB0aGlzLl9mb3JFYWNoQ2hpbGQoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gY29udHJvbC5tYXJrQWxsQXNUb3VjaGVkKG9wdHMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY29udHJvbCBhcyBgdW50b3VjaGVkYC5cbiAgICpcbiAgICogSWYgdGhlIGNvbnRyb2wgaGFzIGFueSBjaGlsZHJlbiwgYWxzbyBtYXJrcyBhbGwgY2hpbGRyZW4gYXMgYHVudG91Y2hlZGBcbiAgICogYW5kIHJlY2FsY3VsYXRlcyB0aGUgYHRvdWNoZWRgIHN0YXR1cyBvZiBhbGwgcGFyZW50IGNvbnRyb2xzLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBtYXJrQXNUb3VjaGVkKCl9XG4gICAqIEBzZWUge0BsaW5rIG1hcmtBc0RpcnR5KCl9XG4gICAqIEBzZWUge0BsaW5rIG1hcmtBc1ByaXN0aW5lKCl9XG4gICAqXG4gICAqIEBwYXJhbSBvcHRzIENvbmZpZ3VyYXRpb24gb3B0aW9ucyB0aGF0IGRldGVybWluZSBob3cgdGhlIGNvbnRyb2wgcHJvcGFnYXRlcyBjaGFuZ2VzXG4gICAqIGFuZCBlbWl0cyBldmVudHMgYWZ0ZXIgdGhlIG1hcmtpbmcgaXMgYXBwbGllZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG1hcmsgb25seSB0aGlzIGNvbnRyb2wuIFdoZW4gZmFsc2Ugb3Igbm90IHN1cHBsaWVkLFxuICAgKiBtYXJrcyBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYGV2ZW50c2BcbiAgICogb2JzZXJ2YWJsZSBlbWl0cyBhIGBUb3VjaGVkQ2hhbmdlRXZlbnRgIHdpdGggdGhlIGB0b3VjaGVkYCBwcm9wZXJ0eSBiZWluZyBgZmFsc2VgLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqL1xuICBtYXJrQXNVbnRvdWNoZWQob3B0cz86IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW59KTogdm9pZDtcbiAgLyoqXG4gICAqXG4gICAqIEBpbnRlcm5hbCBVc2VkIHRvIHByb3BhZ2F0ZSB0aGUgc291cmNlIGNvbnRyb2wgZG93bndhcmRzXG4gICAqL1xuICBtYXJrQXNVbnRvdWNoZWQob3B0czoge1xuICAgIG9ubHlTZWxmPzogYm9vbGVhbjtcbiAgICBlbWl0RXZlbnQ/OiBib29sZWFuO1xuICAgIHNvdXJjZUNvbnRyb2w/OiBBYnN0cmFjdENvbnRyb2w7XG4gIH0pOiB2b2lkO1xuICBtYXJrQXNVbnRvdWNoZWQoXG4gICAgb3B0czoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbjsgc291cmNlQ29udHJvbD86IEFic3RyYWN0Q29udHJvbH0gPSB7fSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgY2hhbmdlZCA9IHRoaXMudG91Y2hlZCA9PT0gdHJ1ZTtcbiAgICB0aGlzLnRvdWNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9wZW5kaW5nVG91Y2hlZCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc291cmNlQ29udHJvbCA9IG9wdHMuc291cmNlQ29udHJvbCA/PyB0aGlzO1xuICAgIHRoaXMuX2ZvckVhY2hDaGlsZCgoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XG4gICAgICBjb250cm9sLm1hcmtBc1VudG91Y2hlZCh7b25seVNlbGY6IHRydWUsIGVtaXRFdmVudDogb3B0cy5lbWl0RXZlbnQsIHNvdXJjZUNvbnRyb2x9KTtcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlVG91Y2hlZChvcHRzLCBzb3VyY2VDb250cm9sKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlZCAmJiBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuX2V2ZW50cy5uZXh0KG5ldyBUb3VjaGVkQ2hhbmdlRXZlbnQoZmFsc2UsIHNvdXJjZUNvbnRyb2wpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFya3MgdGhlIGNvbnRyb2wgYXMgYGRpcnR5YC4gQSBjb250cm9sIGJlY29tZXMgZGlydHkgd2hlblxuICAgKiB0aGUgY29udHJvbCdzIHZhbHVlIGlzIGNoYW5nZWQgdGhyb3VnaCB0aGUgVUk7IGNvbXBhcmUgYG1hcmtBc1RvdWNoZWRgLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBtYXJrQXNUb3VjaGVkKCl9XG4gICAqIEBzZWUge0BsaW5rIG1hcmtBc1VudG91Y2hlZCgpfVxuICAgKiBAc2VlIHtAbGluayBtYXJrQXNQcmlzdGluZSgpfVxuICAgKlxuICAgKiBAcGFyYW0gb3B0cyBDb25maWd1cmF0aW9uIG9wdGlvbnMgdGhhdCBkZXRlcm1pbmUgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlc1xuICAgKiBhbmQgZW1pdHMgZXZlbnRzIGFmdGVyIG1hcmtpbmcgaXMgYXBwbGllZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG1hcmsgb25seSB0aGlzIGNvbnRyb2wuIFdoZW4gZmFsc2Ugb3Igbm90IHN1cHBsaWVkLFxuICAgKiBtYXJrcyBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYGV2ZW50c2BcbiAgICogb2JzZXJ2YWJsZSBlbWl0cyBhIGBQcmlzdGluZUNoYW5nZUV2ZW50YCB3aXRoIHRoZSBgcHJpc3RpbmVgIHByb3BlcnR5IGJlaW5nIGBmYWxzZWAuXG4gICAqIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICovXG4gIG1hcmtBc0RpcnR5KG9wdHM/OiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFufSk6IHZvaWQ7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgVXNlZCB0byBwcm9wYWdhdGUgdGhlIHNvdXJjZSBjb250cm9sIGRvd253YXJkc1xuICAgKi9cbiAgbWFya0FzRGlydHkob3B0czoge1xuICAgIG9ubHlTZWxmPzogYm9vbGVhbjtcbiAgICBlbWl0RXZlbnQ/OiBib29sZWFuO1xuICAgIHNvdXJjZUNvbnRyb2w/OiBBYnN0cmFjdENvbnRyb2w7XG4gIH0pOiB2b2lkO1xuICBtYXJrQXNEaXJ0eShcbiAgICBvcHRzOiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuOyBzb3VyY2VDb250cm9sPzogQWJzdHJhY3RDb250cm9sfSA9IHt9LFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBjaGFuZ2VkID0gdGhpcy5wcmlzdGluZSA9PT0gdHJ1ZTtcbiAgICB0aGlzLnByaXN0aW5lID0gZmFsc2U7XG5cbiAgICBjb25zdCBzb3VyY2VDb250cm9sID0gb3B0cy5zb3VyY2VDb250cm9sID8/IHRoaXM7XG4gICAgaWYgKHRoaXMuX3BhcmVudCAmJiAhb3B0cy5vbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50Lm1hcmtBc0RpcnR5KHsuLi5vcHRzLCBzb3VyY2VDb250cm9sfSk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWQgJiYgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLl9ldmVudHMubmV4dChuZXcgUHJpc3RpbmVDaGFuZ2VFdmVudChmYWxzZSwgc291cmNlQ29udHJvbCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY29udHJvbCBhcyBgcHJpc3RpbmVgLlxuICAgKlxuICAgKiBJZiB0aGUgY29udHJvbCBoYXMgYW55IGNoaWxkcmVuLCBtYXJrcyBhbGwgY2hpbGRyZW4gYXMgYHByaXN0aW5lYCxcbiAgICogYW5kIHJlY2FsY3VsYXRlcyB0aGUgYHByaXN0aW5lYCBzdGF0dXMgb2YgYWxsIHBhcmVudFxuICAgKiBjb250cm9scy5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgbWFya0FzVG91Y2hlZCgpfVxuICAgKiBAc2VlIHtAbGluayBtYXJrQXNVbnRvdWNoZWQoKX1cbiAgICogQHNlZSB7QGxpbmsgbWFya0FzRGlydHkoKX1cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBlbWl0cyBldmVudHMgYWZ0ZXJcbiAgICogbWFya2luZyBpcyBhcHBsaWVkLlxuICAgKiAqIGBvbmx5U2VsZmA6IFdoZW4gdHJ1ZSwgbWFyayBvbmx5IHRoaXMgY29udHJvbC4gV2hlbiBmYWxzZSBvciBub3Qgc3VwcGxpZWQsXG4gICAqIG1hcmtzIGFsbCBkaXJlY3QgYW5jZXN0b3JzLiBEZWZhdWx0IGlzIGZhbHNlLlxuICAgKiAqIGBlbWl0RXZlbnRgOiBXaGVuIHRydWUgb3Igbm90IHN1cHBsaWVkICh0aGUgZGVmYXVsdCksIHRoZSBgZXZlbnRzYFxuICAgKiBvYnNlcnZhYmxlIGVtaXRzIGEgYFByaXN0aW5lQ2hhbmdlRXZlbnRgIHdpdGggdGhlIGBwcmlzdGluZWAgcHJvcGVydHkgYmVpbmcgYHRydWVgLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqL1xuICBtYXJrQXNQcmlzdGluZShvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbn0pOiB2b2lkO1xuICAvKipcbiAgICogQGludGVybmFsIFVzZWQgdG8gcHJvcGFnYXRlIHRoZSBzb3VyY2UgY29udHJvbCBkb3dud2FyZHNcbiAgICovXG4gIG1hcmtBc1ByaXN0aW5lKG9wdHM6IHtcbiAgICBvbmx5U2VsZj86IGJvb2xlYW47XG4gICAgZW1pdEV2ZW50PzogYm9vbGVhbjtcbiAgICBzb3VyY2VDb250cm9sPzogQWJzdHJhY3RDb250cm9sO1xuICB9KTogdm9pZDtcbiAgbWFya0FzUHJpc3RpbmUoXG4gICAgb3B0czoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbjsgc291cmNlQ29udHJvbD86IEFic3RyYWN0Q29udHJvbH0gPSB7fSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgY2hhbmdlZCA9IHRoaXMucHJpc3RpbmUgPT09IGZhbHNlO1xuICAgIHRoaXMucHJpc3RpbmUgPSB0cnVlO1xuICAgIHRoaXMuX3BlbmRpbmdEaXJ0eSA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc291cmNlQ29udHJvbCA9IG9wdHMuc291cmNlQ29udHJvbCA/PyB0aGlzO1xuICAgIHRoaXMuX2ZvckVhY2hDaGlsZCgoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XG4gICAgICAvKiogV2UgZG9uJ3QgcHJvcGFnYXRlIHRoZSBzb3VyY2UgY29udHJvbCBkb3dud2FyZHMgKi9cbiAgICAgIGNvbnRyb2wubWFya0FzUHJpc3RpbmUoe29ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IG9wdHMuZW1pdEV2ZW50fSk7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5fcGFyZW50ICYmICFvcHRzLm9ubHlTZWxmKSB7XG4gICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZVByaXN0aW5lKG9wdHMsIHNvdXJjZUNvbnRyb2wpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VkICYmIG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5fZXZlbnRzLm5leHQobmV3IFByaXN0aW5lQ2hhbmdlRXZlbnQodHJ1ZSwgc291cmNlQ29udHJvbCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY29udHJvbCBhcyBgcGVuZGluZ2AuXG4gICAqXG4gICAqIEEgY29udHJvbCBpcyBwZW5kaW5nIHdoaWxlIHRoZSBjb250cm9sIHBlcmZvcm1zIGFzeW5jIHZhbGlkYXRpb24uXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIEFic3RyYWN0Q29udHJvbC5zdGF0dXN9XG4gICAqXG4gICAqIEBwYXJhbSBvcHRzIENvbmZpZ3VyYXRpb24gb3B0aW9ucyB0aGF0IGRldGVybWluZSBob3cgdGhlIGNvbnRyb2wgcHJvcGFnYXRlcyBjaGFuZ2VzIGFuZFxuICAgKiBlbWl0cyBldmVudHMgYWZ0ZXIgbWFya2luZyBpcyBhcHBsaWVkLlxuICAgKiAqIGBvbmx5U2VsZmA6IFdoZW4gdHJ1ZSwgbWFyayBvbmx5IHRoaXMgY29udHJvbC4gV2hlbiBmYWxzZSBvciBub3Qgc3VwcGxpZWQsXG4gICAqIG1hcmtzIGFsbCBkaXJlY3QgYW5jZXN0b3JzLiBEZWZhdWx0IGlzIGZhbHNlLlxuICAgKiAqIGBlbWl0RXZlbnRgOiBXaGVuIHRydWUgb3Igbm90IHN1cHBsaWVkICh0aGUgZGVmYXVsdCksIHRoZSBgc3RhdHVzQ2hhbmdlc2BcbiAgICogb2JzZXJ2YWJsZSBlbWl0cyBhbiBldmVudCB3aXRoIHRoZSBsYXRlc3Qgc3RhdHVzIHRoZSBjb250cm9sIGlzIG1hcmtlZCBwZW5kaW5nXG4gICAqIGFuZCB0aGUgYGV2ZW50c2Agb2JzZXJ2YWJsZSBlbWl0cyBhIGBTdGF0dXNDaGFuZ2VFdmVudGAgd2l0aCB0aGUgYHN0YXR1c2AgcHJvcGVydHkgYmVpbmdcbiAgICogYFBFTkRJTkdgIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICpcbiAgICovXG4gIG1hcmtBc1BlbmRpbmcob3B0cz86IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW59KTogdm9pZDtcbiAgLyoqXG4gICAqIEBpbnRlcm5hbCBVc2VkIHRvIHByb3BhZ2F0ZSB0aGUgc291cmNlIGNvbnRyb2wgZG93bndhcmRzXG4gICAqL1xuICBtYXJrQXNQZW5kaW5nKG9wdHM6IHtcbiAgICBvbmx5U2VsZj86IGJvb2xlYW47XG4gICAgZW1pdEV2ZW50PzogYm9vbGVhbjtcbiAgICBzb3VyY2VDb250cm9sPzogQWJzdHJhY3RDb250cm9sO1xuICB9KTogdm9pZDtcbiAgbWFya0FzUGVuZGluZyhcbiAgICBvcHRzOiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuOyBzb3VyY2VDb250cm9sPzogQWJzdHJhY3RDb250cm9sfSA9IHt9LFxuICApOiB2b2lkIHtcbiAgICB0aGlzLnN0YXR1cyA9IFBFTkRJTkc7XG5cbiAgICBjb25zdCBzb3VyY2VDb250cm9sID0gb3B0cy5zb3VyY2VDb250cm9sID8/IHRoaXM7XG4gICAgaWYgKG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5fZXZlbnRzLm5leHQobmV3IFN0YXR1c0NoYW5nZUV2ZW50KHRoaXMuc3RhdHVzLCBzb3VyY2VDb250cm9sKSk7XG4gICAgICAodGhpcy5zdGF0dXNDaGFuZ2VzIGFzIEV2ZW50RW1pdHRlcjxGb3JtQ29udHJvbFN0YXR1cz4pLmVtaXQodGhpcy5zdGF0dXMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5tYXJrQXNQZW5kaW5nKHsuLi5vcHRzLCBzb3VyY2VDb250cm9sfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERpc2FibGVzIHRoZSBjb250cm9sLiBUaGlzIG1lYW5zIHRoZSBjb250cm9sIGlzIGV4ZW1wdCBmcm9tIHZhbGlkYXRpb24gY2hlY2tzIGFuZFxuICAgKiBleGNsdWRlZCBmcm9tIHRoZSBhZ2dyZWdhdGUgdmFsdWUgb2YgYW55IHBhcmVudC4gSXRzIHN0YXR1cyBpcyBgRElTQUJMRURgLlxuICAgKlxuICAgKiBJZiB0aGUgY29udHJvbCBoYXMgY2hpbGRyZW4sIGFsbCBjaGlsZHJlbiBhcmUgYWxzbyBkaXNhYmxlZC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzXG4gICAqIGNoYW5nZXMgYW5kIGVtaXRzIGV2ZW50cyBhZnRlciB0aGUgY29udHJvbCBpcyBkaXNhYmxlZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG1hcmsgb25seSB0aGlzIGNvbnRyb2wuIFdoZW4gZmFsc2Ugb3Igbm90IHN1cHBsaWVkLFxuICAgKiBtYXJrcyBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYHN0YXR1c0NoYW5nZXNgLFxuICAgKiBgdmFsdWVDaGFuZ2VzYCBhbmQgYGV2ZW50c2BcbiAgICogb2JzZXJ2YWJsZXMgZW1pdCBldmVudHMgd2l0aCB0aGUgbGF0ZXN0IHN0YXR1cyBhbmQgdmFsdWUgd2hlbiB0aGUgY29udHJvbCBpcyBkaXNhYmxlZC5cbiAgICogV2hlbiBmYWxzZSwgbm8gZXZlbnRzIGFyZSBlbWl0dGVkLlxuICAgKi9cbiAgZGlzYWJsZShvcHRzPzoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbn0pOiB2b2lkO1xuICAvKipcbiAgICogQGludGVybmFsIFVzZWQgdG8gcHJvcGFnYXRlIHRoZSBzb3VyY2UgY29udHJvbCBkb3dud2FyZHNcbiAgICovXG4gIGRpc2FibGUob3B0czoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbjsgc291cmNlQ29udHJvbD86IEFic3RyYWN0Q29udHJvbH0pOiB2b2lkO1xuICBkaXNhYmxlKFxuICAgIG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW47IHNvdXJjZUNvbnRyb2w/OiBBYnN0cmFjdENvbnRyb2x9ID0ge30sXG4gICk6IHZvaWQge1xuICAgIC8vIElmIHBhcmVudCBoYXMgYmVlbiBtYXJrZWQgYXJ0aWZpY2lhbGx5IGRpcnR5IHdlIGRvbid0IHdhbnQgdG8gcmUtY2FsY3VsYXRlIHRoZVxuICAgIC8vIHBhcmVudCdzIGRpcnRpbmVzcyBiYXNlZCBvbiB0aGUgY2hpbGRyZW4uXG4gICAgY29uc3Qgc2tpcFByaXN0aW5lQ2hlY2sgPSB0aGlzLl9wYXJlbnRNYXJrZWREaXJ0eShvcHRzLm9ubHlTZWxmKTtcblxuICAgIHRoaXMuc3RhdHVzID0gRElTQUJMRUQ7XG4gICAgKHRoaXMgYXMgV3JpdGFibGU8dGhpcz4pLmVycm9ycyA9IG51bGw7XG4gICAgdGhpcy5fZm9yRWFjaENoaWxkKChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IHtcbiAgICAgIC8qKiBXZSBkb24ndCBwcm9wYWdhdGUgdGhlIHNvdXJjZSBjb250cm9sIGRvd253YXJkcyAqL1xuICAgICAgY29udHJvbC5kaXNhYmxlKHsuLi5vcHRzLCBvbmx5U2VsZjogdHJ1ZX0pO1xuICAgIH0pO1xuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG5cbiAgICBjb25zdCBzb3VyY2VDb250cm9sID0gb3B0cy5zb3VyY2VDb250cm9sID8/IHRoaXM7XG4gICAgaWYgKG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5fZXZlbnRzLm5leHQobmV3IFZhbHVlQ2hhbmdlRXZlbnQodGhpcy52YWx1ZSwgc291cmNlQ29udHJvbCkpO1xuICAgICAgdGhpcy5fZXZlbnRzLm5leHQobmV3IFN0YXR1c0NoYW5nZUV2ZW50KHRoaXMuc3RhdHVzLCBzb3VyY2VDb250cm9sKSk7XG4gICAgICAodGhpcy52YWx1ZUNoYW5nZXMgYXMgRXZlbnRFbWl0dGVyPFRWYWx1ZT4pLmVtaXQodGhpcy52YWx1ZSk7XG4gICAgICAodGhpcy5zdGF0dXNDaGFuZ2VzIGFzIEV2ZW50RW1pdHRlcjxGb3JtQ29udHJvbFN0YXR1cz4pLmVtaXQodGhpcy5zdGF0dXMpO1xuICAgIH1cblxuICAgIHRoaXMuX3VwZGF0ZUFuY2VzdG9ycyh7Li4ub3B0cywgc2tpcFByaXN0aW5lQ2hlY2t9LCB0aGlzKTtcbiAgICB0aGlzLl9vbkRpc2FibGVkQ2hhbmdlLmZvckVhY2goKGNoYW5nZUZuKSA9PiBjaGFuZ2VGbih0cnVlKSk7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyB0aGUgY29udHJvbC4gVGhpcyBtZWFucyB0aGUgY29udHJvbCBpcyBpbmNsdWRlZCBpbiB2YWxpZGF0aW9uIGNoZWNrcyBhbmRcbiAgICogdGhlIGFnZ3JlZ2F0ZSB2YWx1ZSBvZiBpdHMgcGFyZW50LiBJdHMgc3RhdHVzIHJlY2FsY3VsYXRlcyBiYXNlZCBvbiBpdHMgdmFsdWUgYW5kXG4gICAqIGl0cyB2YWxpZGF0b3JzLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBpZiB0aGUgY29udHJvbCBoYXMgY2hpbGRyZW4sIGFsbCBjaGlsZHJlbiBhcmUgZW5hYmxlZC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJlIG9wdGlvbnMgdGhhdCBjb250cm9sIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzIGNoYW5nZXMgYW5kXG4gICAqIGVtaXRzIGV2ZW50cyB3aGVuIG1hcmtlZCBhcyB1bnRvdWNoZWRcbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG1hcmsgb25seSB0aGlzIGNvbnRyb2wuIFdoZW4gZmFsc2Ugb3Igbm90IHN1cHBsaWVkLFxuICAgKiBtYXJrcyBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYHN0YXR1c0NoYW5nZXNgLFxuICAgKiBgdmFsdWVDaGFuZ2VzYCBhbmQgYGV2ZW50c2BcbiAgICogb2JzZXJ2YWJsZXMgZW1pdCBldmVudHMgd2l0aCB0aGUgbGF0ZXN0IHN0YXR1cyBhbmQgdmFsdWUgd2hlbiB0aGUgY29udHJvbCBpcyBlbmFibGVkLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqL1xuICBlbmFibGUob3B0czoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgIC8vIElmIHBhcmVudCBoYXMgYmVlbiBtYXJrZWQgYXJ0aWZpY2lhbGx5IGRpcnR5IHdlIGRvbid0IHdhbnQgdG8gcmUtY2FsY3VsYXRlIHRoZVxuICAgIC8vIHBhcmVudCdzIGRpcnRpbmVzcyBiYXNlZCBvbiB0aGUgY2hpbGRyZW4uXG4gICAgY29uc3Qgc2tpcFByaXN0aW5lQ2hlY2sgPSB0aGlzLl9wYXJlbnRNYXJrZWREaXJ0eShvcHRzLm9ubHlTZWxmKTtcblxuICAgIHRoaXMuc3RhdHVzID0gVkFMSUQ7XG4gICAgdGhpcy5fZm9yRWFjaENoaWxkKChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IHtcbiAgICAgIGNvbnRyb2wuZW5hYmxlKHsuLi5vcHRzLCBvbmx5U2VsZjogdHJ1ZX0pO1xuICAgIH0pO1xuICAgIHRoaXMudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7b25seVNlbGY6IHRydWUsIGVtaXRFdmVudDogb3B0cy5lbWl0RXZlbnR9KTtcblxuICAgIHRoaXMuX3VwZGF0ZUFuY2VzdG9ycyh7Li4ub3B0cywgc2tpcFByaXN0aW5lQ2hlY2t9LCB0aGlzKTtcbiAgICB0aGlzLl9vbkRpc2FibGVkQ2hhbmdlLmZvckVhY2goKGNoYW5nZUZuKSA9PiBjaGFuZ2VGbihmYWxzZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlQW5jZXN0b3JzKFxuICAgIG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW47IGVtaXRFdmVudD86IGJvb2xlYW47IHNraXBQcmlzdGluZUNoZWNrPzogYm9vbGVhbn0sXG4gICAgc291cmNlQ29udHJvbDogQWJzdHJhY3RDb250cm9sLFxuICApOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcGFyZW50ICYmICFvcHRzLm9ubHlTZWxmKSB7XG4gICAgICB0aGlzLl9wYXJlbnQudXBkYXRlVmFsdWVBbmRWYWxpZGl0eShvcHRzKTtcbiAgICAgIGlmICghb3B0cy5za2lwUHJpc3RpbmVDaGVjaykge1xuICAgICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZVByaXN0aW5lKHt9LCBzb3VyY2VDb250cm9sKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlVG91Y2hlZCh7fSwgc291cmNlQ29udHJvbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHBhcmVudCBvZiB0aGUgY29udHJvbFxuICAgKlxuICAgKiBAcGFyYW0gcGFyZW50IFRoZSBuZXcgcGFyZW50LlxuICAgKi9cbiAgc2V0UGFyZW50KHBhcmVudDogRm9ybUdyb3VwIHwgRm9ybUFycmF5IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgY29udHJvbC4gQWJzdHJhY3QgbWV0aG9kIChpbXBsZW1lbnRlZCBpbiBzdWItY2xhc3NlcykuXG4gICAqL1xuICBhYnN0cmFjdCBzZXRWYWx1ZSh2YWx1ZTogVFJhd1ZhbHVlLCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogUGF0Y2hlcyB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wuIEFic3RyYWN0IG1ldGhvZCAoaW1wbGVtZW50ZWQgaW4gc3ViLWNsYXNzZXMpLlxuICAgKi9cbiAgYWJzdHJhY3QgcGF0Y2hWYWx1ZSh2YWx1ZTogVFZhbHVlLCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBjb250cm9sLiBBYnN0cmFjdCBtZXRob2QgKGltcGxlbWVudGVkIGluIHN1Yi1jbGFzc2VzKS5cbiAgICovXG4gIGFic3RyYWN0IHJlc2V0KHZhbHVlPzogVFZhbHVlLCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogVGhlIHJhdyB2YWx1ZSBvZiB0aGlzIGNvbnRyb2wuIEZvciBtb3N0IGNvbnRyb2wgaW1wbGVtZW50YXRpb25zLCB0aGUgcmF3IHZhbHVlIHdpbGwgaW5jbHVkZVxuICAgKiBkaXNhYmxlZCBjaGlsZHJlbi5cbiAgICovXG4gIGdldFJhd1ZhbHVlKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogUmVjYWxjdWxhdGVzIHRoZSB2YWx1ZSBhbmQgdmFsaWRhdGlvbiBzdGF0dXMgb2YgdGhlIGNvbnRyb2wuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGl0IGFsc28gdXBkYXRlcyB0aGUgdmFsdWUgYW5kIHZhbGlkaXR5IG9mIGl0cyBhbmNlc3RvcnMuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRzIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBkZXRlcm1pbmUgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlcyBhbmQgZW1pdHMgZXZlbnRzXG4gICAqIGFmdGVyIHVwZGF0ZXMgYW5kIHZhbGlkaXR5IGNoZWNrcyBhcmUgYXBwbGllZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG9ubHkgdXBkYXRlIHRoaXMgY29udHJvbC4gV2hlbiBmYWxzZSBvciBub3Qgc3VwcGxpZWQsXG4gICAqIHVwZGF0ZSBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYHN0YXR1c0NoYW5nZXNgLFxuICAgKiBgdmFsdWVDaGFuZ2VzYCBhbmQgYGV2ZW50c2BcbiAgICogb2JzZXJ2YWJsZXMgZW1pdCBldmVudHMgd2l0aCB0aGUgbGF0ZXN0IHN0YXR1cyBhbmQgdmFsdWUgd2hlbiB0aGUgY29udHJvbCBpcyB1cGRhdGVkLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqL1xuICB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KG9wdHM/OiB7b25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFufSk6IHZvaWQ7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgVXNlZCB0byBwcm9wYWdhdGUgdGhlIHNvdXJjZSBjb250cm9sIGRvd253YXJkc1xuICAgKi9cbiAgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eShvcHRzOiB7XG4gICAgb25seVNlbGY/OiBib29sZWFuO1xuICAgIGVtaXRFdmVudD86IGJvb2xlYW47XG4gICAgc291cmNlQ29udHJvbD86IEFic3RyYWN0Q29udHJvbDtcbiAgfSk6IHZvaWQ7XG4gIHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoXG4gICAgb3B0czoge29ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbjsgc291cmNlQ29udHJvbD86IEFic3RyYWN0Q29udHJvbH0gPSB7fSxcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5fc2V0SW5pdGlhbFN0YXR1cygpO1xuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG5cbiAgICBpZiAodGhpcy5lbmFibGVkKSB7XG4gICAgICBjb25zdCBzaG91bGRIYXZlRW1pdHRlZCA9IHRoaXMuX2NhbmNlbEV4aXN0aW5nU3Vic2NyaXB0aW9uKCk7XG5cbiAgICAgICh0aGlzIGFzIFdyaXRhYmxlPHRoaXM+KS5lcnJvcnMgPSB0aGlzLl9ydW5WYWxpZGF0b3IoKTtcbiAgICAgIHRoaXMuc3RhdHVzID0gdGhpcy5fY2FsY3VsYXRlU3RhdHVzKCk7XG5cbiAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gVkFMSUQgfHwgdGhpcy5zdGF0dXMgPT09IFBFTkRJTkcpIHtcbiAgICAgICAgLy8gSWYgdGhlIGNhbmNlbGVkIHN1YnNjcmlwdGlvbiBzaG91bGQgaGF2ZSBlbWl0dGVkXG4gICAgICAgIC8vIHdlIG1ha2Ugc3VyZSB0aGUgYXN5bmMgdmFsaWRhdG9yIGVtaXRzIHRoZSBzdGF0dXMgY2hhbmdlIG9uIGNvbXBsZXRpb25cbiAgICAgICAgdGhpcy5fcnVuQXN5bmNWYWxpZGF0b3Ioc2hvdWxkSGF2ZUVtaXR0ZWQsIG9wdHMuZW1pdEV2ZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VDb250cm9sID0gb3B0cy5zb3VyY2VDb250cm9sID8/IHRoaXM7XG4gICAgaWYgKG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5fZXZlbnRzLm5leHQobmV3IFZhbHVlQ2hhbmdlRXZlbnQ8VFZhbHVlPih0aGlzLnZhbHVlLCBzb3VyY2VDb250cm9sKSk7XG4gICAgICB0aGlzLl9ldmVudHMubmV4dChuZXcgU3RhdHVzQ2hhbmdlRXZlbnQodGhpcy5zdGF0dXMsIHNvdXJjZUNvbnRyb2wpKTtcbiAgICAgICh0aGlzLnZhbHVlQ2hhbmdlcyBhcyBFdmVudEVtaXR0ZXI8VFZhbHVlPikuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICh0aGlzLnN0YXR1c0NoYW5nZXMgYXMgRXZlbnRFbWl0dGVyPEZvcm1Db250cm9sU3RhdHVzPikuZW1pdCh0aGlzLnN0YXR1cyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3BhcmVudCAmJiAhb3B0cy5vbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoey4uLm9wdHMsIHNvdXJjZUNvbnRyb2x9KTtcbiAgICB9XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF91cGRhdGVUcmVlVmFsaWRpdHkob3B0czoge2VtaXRFdmVudD86IGJvb2xlYW59ID0ge2VtaXRFdmVudDogdHJ1ZX0pOiB2b2lkIHtcbiAgICB0aGlzLl9mb3JFYWNoQ2hpbGQoKGN0cmw6IEFic3RyYWN0Q29udHJvbCkgPT4gY3RybC5fdXBkYXRlVHJlZVZhbGlkaXR5KG9wdHMpKTtcbiAgICB0aGlzLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoe29ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IG9wdHMuZW1pdEV2ZW50fSk7XG4gIH1cblxuICBwcml2YXRlIF9zZXRJbml0aWFsU3RhdHVzKCkge1xuICAgIHRoaXMuc3RhdHVzID0gdGhpcy5fYWxsQ29udHJvbHNEaXNhYmxlZCgpID8gRElTQUJMRUQgOiBWQUxJRDtcbiAgfVxuXG4gIHByaXZhdGUgX3J1blZhbGlkYXRvcigpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdG9yID8gdGhpcy52YWxpZGF0b3IodGhpcykgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBfcnVuQXN5bmNWYWxpZGF0b3Ioc2hvdWxkSGF2ZUVtaXR0ZWQ6IGJvb2xlYW4sIGVtaXRFdmVudD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hc3luY1ZhbGlkYXRvcikge1xuICAgICAgdGhpcy5zdGF0dXMgPSBQRU5ESU5HO1xuICAgICAgdGhpcy5faGFzT3duUGVuZGluZ0FzeW5jVmFsaWRhdG9yID0ge2VtaXRFdmVudDogZW1pdEV2ZW50ICE9PSBmYWxzZX07XG4gICAgICBjb25zdCBvYnMgPSB0b09ic2VydmFibGUodGhpcy5hc3luY1ZhbGlkYXRvcih0aGlzKSk7XG4gICAgICB0aGlzLl9hc3luY1ZhbGlkYXRpb25TdWJzY3JpcHRpb24gPSBvYnMuc3Vic2NyaWJlKChlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsKSA9PiB7XG4gICAgICAgIHRoaXMuX2hhc093blBlbmRpbmdBc3luY1ZhbGlkYXRvciA9IG51bGw7XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0cmlnZ2VyIHRoZSByZWNhbGN1bGF0aW9uIG9mIHRoZSB2YWxpZGF0aW9uIHN0YXR1cywgd2hpY2ggZGVwZW5kcyBvblxuICAgICAgICAvLyB0aGUgc3RhdGUgb2YgdGhlIGFzeW5jaHJvbm91cyB2YWxpZGF0aW9uICh3aGV0aGVyIGl0IGlzIGluIHByb2dyZXNzIG9yIG5vdCkuIFNvLCBpdCBpc1xuICAgICAgICAvLyBuZWNlc3NhcnkgdGhhdCB3ZSBoYXZlIHVwZGF0ZWQgdGhlIGBfaGFzT3duUGVuZGluZ0FzeW5jVmFsaWRhdG9yYCBib29sZWFuIGZsYWcgZmlyc3QuXG4gICAgICAgIHRoaXMuc2V0RXJyb3JzKGVycm9ycywge2VtaXRFdmVudCwgc2hvdWxkSGF2ZUVtaXR0ZWR9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NhbmNlbEV4aXN0aW5nU3Vic2NyaXB0aW9uKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9hc3luY1ZhbGlkYXRpb25TdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX2FzeW5jVmFsaWRhdGlvblN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuXG4gICAgICAvLyB3ZSdyZSBjYW5jZWxsaW5nIHRoZSB2YWxpZGF0b3Igc3Vic2NyaWJ0aW9uLCB3ZSBrZWVwIGlmIGl0IHNob3VsZCBoYXZlIGVtaXR0ZWRcbiAgICAgIC8vIGJlY2F1c2Ugd2Ugd2FudCB0byBlbWl0IGV2ZW50dWFsbHkgaWYgaXQgd2FzIHJlcXVpcmVkIGF0IGxlYXN0IG9uY2UuXG4gICAgICBjb25zdCBzaG91bGRIYXZlRW1pdHRlZCA9IHRoaXMuX2hhc093blBlbmRpbmdBc3luY1ZhbGlkYXRvcj8uZW1pdEV2ZW50ID8/IGZhbHNlO1xuICAgICAgdGhpcy5faGFzT3duUGVuZGluZ0FzeW5jVmFsaWRhdG9yID0gbnVsbDtcbiAgICAgIHJldHVybiBzaG91bGRIYXZlRW1pdHRlZDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgZXJyb3JzIG9uIGEgZm9ybSBjb250cm9sIHdoZW4gcnVubmluZyB2YWxpZGF0aW9ucyBtYW51YWxseSwgcmF0aGVyIHRoYW4gYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogQ2FsbGluZyBgc2V0RXJyb3JzYCBhbHNvIHVwZGF0ZXMgdGhlIHZhbGlkaXR5IG9mIHRoZSBwYXJlbnQgY29udHJvbC5cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzXG4gICAqIGNoYW5nZXMgYW5kIGVtaXRzIGV2ZW50cyBhZnRlciB0aGUgY29udHJvbCBlcnJvcnMgYXJlIHNldC5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCB0aGUgYHN0YXR1c0NoYW5nZXNgXG4gICAqIG9ic2VydmFibGUgZW1pdHMgYW4gZXZlbnQgYWZ0ZXIgdGhlIGVycm9ycyBhcmUgc2V0LlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKlxuICAgKiAjIyMgTWFudWFsbHkgc2V0IHRoZSBlcnJvcnMgZm9yIGEgY29udHJvbFxuICAgKlxuICAgKiBgYGBcbiAgICogY29uc3QgbG9naW4gPSBuZXcgRm9ybUNvbnRyb2woJ3NvbWVMb2dpbicpO1xuICAgKiBsb2dpbi5zZXRFcnJvcnMoe1xuICAgKiAgIG5vdFVuaXF1ZTogdHJ1ZVxuICAgKiB9KTtcbiAgICpcbiAgICogZXhwZWN0KGxvZ2luLnZhbGlkKS50b0VxdWFsKGZhbHNlKTtcbiAgICogZXhwZWN0KGxvZ2luLmVycm9ycykudG9FcXVhbCh7IG5vdFVuaXF1ZTogdHJ1ZSB9KTtcbiAgICpcbiAgICogbG9naW4uc2V0VmFsdWUoJ3NvbWVPdGhlckxvZ2luJyk7XG4gICAqXG4gICAqIGV4cGVjdChsb2dpbi52YWxpZCkudG9FcXVhbCh0cnVlKTtcbiAgICogYGBgXG4gICAqL1xuICBzZXRFcnJvcnMoZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCwgb3B0cz86IHtlbWl0RXZlbnQ/OiBib29sZWFufSk6IHZvaWQ7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBzZXRFcnJvcnMoXG4gICAgZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCxcbiAgICBvcHRzPzoge2VtaXRFdmVudD86IGJvb2xlYW47IHNob3VsZEhhdmVFbWl0dGVkPzogYm9vbGVhbn0sXG4gICk6IHZvaWQ7XG4gIHNldEVycm9ycyhcbiAgICBlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsLFxuICAgIG9wdHM6IHtlbWl0RXZlbnQ/OiBib29sZWFuOyBzaG91bGRIYXZlRW1pdHRlZD86IGJvb2xlYW59ID0ge30sXG4gICk6IHZvaWQge1xuICAgICh0aGlzIGFzIFdyaXRhYmxlPHRoaXM+KS5lcnJvcnMgPSBlcnJvcnM7XG4gICAgdGhpcy5fdXBkYXRlQ29udHJvbHNFcnJvcnMob3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlLCB0aGlzLCBvcHRzLnNob3VsZEhhdmVFbWl0dGVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSBjaGlsZCBjb250cm9sIGdpdmVuIHRoZSBjb250cm9sJ3MgbmFtZSBvciBwYXRoLlxuICAgKlxuICAgKiBUaGlzIHNpZ25hdHVyZSBmb3IgZ2V0IHN1cHBvcnRzIHN0cmluZ3MgYW5kIGBjb25zdGAgYXJyYXlzIChgLmdldChbJ2ZvbycsICdiYXInXSBhcyBjb25zdClgKS5cbiAgICovXG4gIGdldDxQIGV4dGVuZHMgc3RyaW5nIHwgcmVhZG9ubHkgKHN0cmluZyB8IG51bWJlcilbXT4oXG4gICAgcGF0aDogUCxcbiAgKTogQWJzdHJhY3RDb250cm9sPMm1R2V0UHJvcGVydHk8VFJhd1ZhbHVlLCBQPj4gfCBudWxsO1xuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSBjaGlsZCBjb250cm9sIGdpdmVuIHRoZSBjb250cm9sJ3MgbmFtZSBvciBwYXRoLlxuICAgKlxuICAgKiBUaGlzIHNpZ25hdHVyZSBmb3IgYGdldGAgc3VwcG9ydHMgbm9uLWNvbnN0IChtdXRhYmxlKSBhcnJheXMuIEluZmVycmVkIHR5cGVcbiAgICogaW5mb3JtYXRpb24gd2lsbCBub3QgYmUgYXMgcm9idXN0LCBzbyBwcmVmZXIgdG8gcGFzcyBhIGByZWFkb25seWAgYXJyYXkgaWYgcG9zc2libGUuXG4gICAqL1xuICBnZXQ8UCBleHRlbmRzIHN0cmluZyB8IEFycmF5PHN0cmluZyB8IG51bWJlcj4+KFxuICAgIHBhdGg6IFAsXG4gICk6IEFic3RyYWN0Q29udHJvbDzJtUdldFByb3BlcnR5PFRSYXdWYWx1ZSwgUD4+IHwgbnVsbDtcblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgY2hpbGQgY29udHJvbCBnaXZlbiB0aGUgY29udHJvbCdzIG5hbWUgb3IgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggQSBkb3QtZGVsaW1pdGVkIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmcvbnVtYmVyIHZhbHVlcyB0aGF0IGRlZmluZSB0aGUgcGF0aCB0byB0aGVcbiAgICogY29udHJvbC4gSWYgYSBzdHJpbmcgaXMgcHJvdmlkZWQsIHBhc3NpbmcgaXQgYXMgYSBzdHJpbmcgbGl0ZXJhbCB3aWxsIHJlc3VsdCBpbiBpbXByb3ZlZCB0eXBlXG4gICAqIGluZm9ybWF0aW9uLiBMaWtld2lzZSwgaWYgYW4gYXJyYXkgaXMgcHJvdmlkZWQsIHBhc3NpbmcgaXQgYGFzIGNvbnN0YCB3aWxsIGNhdXNlIGltcHJvdmVkIHR5cGVcbiAgICogaW5mb3JtYXRpb24gdG8gYmUgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKiAjIyMgUmV0cmlldmUgYSBuZXN0ZWQgY29udHJvbFxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYG5hbWVgIGNvbnRyb2wgbmVzdGVkIHdpdGhpbiBhIGBwZXJzb25gIHN1Yi1ncm91cDpcbiAgICpcbiAgICogKiBgdGhpcy5mb3JtLmdldCgncGVyc29uLm5hbWUnKTtgXG4gICAqXG4gICAqIC1PUi1cbiAgICpcbiAgICogKiBgdGhpcy5mb3JtLmdldChbJ3BlcnNvbicsICduYW1lJ10gYXMgY29uc3QpO2AgLy8gYGFzIGNvbnN0YCBnaXZlcyBpbXByb3ZlZCB0eXBpbmdzXG4gICAqXG4gICAqICMjIyBSZXRyaWV2ZSBhIGNvbnRyb2wgaW4gYSBGb3JtQXJyYXlcbiAgICpcbiAgICogV2hlbiBhY2Nlc3NpbmcgYW4gZWxlbWVudCBpbnNpZGUgYSBGb3JtQXJyYXksIHlvdSBjYW4gdXNlIGFuIGVsZW1lbnQgaW5kZXguXG4gICAqIEZvciBleGFtcGxlLCB0byBnZXQgYSBgcHJpY2VgIGNvbnRyb2wgZnJvbSB0aGUgZmlyc3QgZWxlbWVudCBpbiBhbiBgaXRlbXNgIGFycmF5IHlvdSBjYW4gdXNlOlxuICAgKlxuICAgKiAqIGB0aGlzLmZvcm0uZ2V0KCdpdGVtcy4wLnByaWNlJyk7YFxuICAgKlxuICAgKiAtT1ItXG4gICAqXG4gICAqICogYHRoaXMuZm9ybS5nZXQoWydpdGVtcycsIDAsICdwcmljZSddKTtgXG4gICAqL1xuICBnZXQ8UCBleHRlbmRzIHN0cmluZyB8IChzdHJpbmcgfCBudW1iZXIpW10+KFxuICAgIHBhdGg6IFAsXG4gICk6IEFic3RyYWN0Q29udHJvbDzJtUdldFByb3BlcnR5PFRSYXdWYWx1ZSwgUD4+IHwgbnVsbCB7XG4gICAgbGV0IGN1cnJQYXRoOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+IHwgc3RyaW5nID0gcGF0aDtcbiAgICBpZiAoY3VyclBhdGggPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGN1cnJQYXRoKSkgY3VyclBhdGggPSBjdXJyUGF0aC5zcGxpdCgnLicpO1xuICAgIGlmIChjdXJyUGF0aC5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgIHJldHVybiBjdXJyUGF0aC5yZWR1Y2UoXG4gICAgICAoY29udHJvbDogQWJzdHJhY3RDb250cm9sIHwgbnVsbCwgbmFtZSkgPT4gY29udHJvbCAmJiBjb250cm9sLl9maW5kKG5hbWUpLFxuICAgICAgdGhpcyxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBSZXBvcnRzIGVycm9yIGRhdGEgZm9yIHRoZSBjb250cm9sIHdpdGggdGhlIGdpdmVuIHBhdGguXG4gICAqXG4gICAqIEBwYXJhbSBlcnJvckNvZGUgVGhlIGNvZGUgb2YgdGhlIGVycm9yIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBwYXRoIEEgbGlzdCBvZiBjb250cm9sIG5hbWVzIHRoYXQgZGVzaWduYXRlcyBob3cgdG8gbW92ZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRyb2xcbiAgICogdG8gdGhlIGNvbnRyb2wgdGhhdCBzaG91bGQgYmUgcXVlcmllZCBmb3IgZXJyb3JzLlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKiBGb3IgZXhhbXBsZSwgZm9yIHRoZSBmb2xsb3dpbmcgYEZvcm1Hcm91cGA6XG4gICAqXG4gICAqIGBgYFxuICAgKiBmb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gICAqICAgYWRkcmVzczogbmV3IEZvcm1Hcm91cCh7IHN0cmVldDogbmV3IEZvcm1Db250cm9sKCkgfSlcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgJ3N0cmVldCcgY29udHJvbCBmcm9tIHRoZSByb290IGZvcm0gd291bGQgYmUgJ2FkZHJlc3MnIC0+ICdzdHJlZXQnLlxuICAgKlxuICAgKiBJdCBjYW4gYmUgcHJvdmlkZWQgdG8gdGhpcyBtZXRob2QgaW4gb25lIG9mIHR3byBmb3JtYXRzOlxuICAgKlxuICAgKiAxLiBBbiBhcnJheSBvZiBzdHJpbmcgY29udHJvbCBuYW1lcywgZS5nLiBgWydhZGRyZXNzJywgJ3N0cmVldCddYFxuICAgKiAxLiBBIHBlcmlvZC1kZWxpbWl0ZWQgbGlzdCBvZiBjb250cm9sIG5hbWVzIGluIG9uZSBzdHJpbmcsIGUuZy4gYCdhZGRyZXNzLnN0cmVldCdgXG4gICAqXG4gICAqIEByZXR1cm5zIGVycm9yIGRhdGEgZm9yIHRoYXQgcGFydGljdWxhciBlcnJvci4gSWYgdGhlIGNvbnRyb2wgb3IgZXJyb3IgaXMgbm90IHByZXNlbnQsXG4gICAqIG51bGwgaXMgcmV0dXJuZWQuXG4gICAqL1xuICBnZXRFcnJvcihlcnJvckNvZGU6IHN0cmluZywgcGF0aD86IEFycmF5PHN0cmluZyB8IG51bWJlcj4gfCBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnN0IGNvbnRyb2wgPSBwYXRoID8gdGhpcy5nZXQocGF0aCkgOiB0aGlzO1xuICAgIHJldHVybiBjb250cm9sICYmIGNvbnRyb2wuZXJyb3JzID8gY29udHJvbC5lcnJvcnNbZXJyb3JDb2RlXSA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFJlcG9ydHMgd2hldGhlciB0aGUgY29udHJvbCB3aXRoIHRoZSBnaXZlbiBwYXRoIGhhcyB0aGUgZXJyb3Igc3BlY2lmaWVkLlxuICAgKlxuICAgKiBAcGFyYW0gZXJyb3JDb2RlIFRoZSBjb2RlIG9mIHRoZSBlcnJvciB0byBjaGVja1xuICAgKiBAcGFyYW0gcGF0aCBBIGxpc3Qgb2YgY29udHJvbCBuYW1lcyB0aGF0IGRlc2lnbmF0ZXMgaG93IHRvIG1vdmUgZnJvbSB0aGUgY3VycmVudCBjb250cm9sXG4gICAqIHRvIHRoZSBjb250cm9sIHRoYXQgc2hvdWxkIGJlIHF1ZXJpZWQgZm9yIGVycm9ycy5cbiAgICpcbiAgICogQHVzYWdlTm90ZXNcbiAgICogRm9yIGV4YW1wbGUsIGZvciB0aGUgZm9sbG93aW5nIGBGb3JtR3JvdXBgOlxuICAgKlxuICAgKiBgYGBcbiAgICogZm9ybSA9IG5ldyBGb3JtR3JvdXAoe1xuICAgKiAgIGFkZHJlc3M6IG5ldyBGb3JtR3JvdXAoeyBzdHJlZXQ6IG5ldyBGb3JtQ29udHJvbCgpIH0pXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICpcbiAgICogVGhlIHBhdGggdG8gdGhlICdzdHJlZXQnIGNvbnRyb2wgZnJvbSB0aGUgcm9vdCBmb3JtIHdvdWxkIGJlICdhZGRyZXNzJyAtPiAnc3RyZWV0Jy5cbiAgICpcbiAgICogSXQgY2FuIGJlIHByb3ZpZGVkIHRvIHRoaXMgbWV0aG9kIGluIG9uZSBvZiB0d28gZm9ybWF0czpcbiAgICpcbiAgICogMS4gQW4gYXJyYXkgb2Ygc3RyaW5nIGNvbnRyb2wgbmFtZXMsIGUuZy4gYFsnYWRkcmVzcycsICdzdHJlZXQnXWBcbiAgICogMS4gQSBwZXJpb2QtZGVsaW1pdGVkIGxpc3Qgb2YgY29udHJvbCBuYW1lcyBpbiBvbmUgc3RyaW5nLCBlLmcuIGAnYWRkcmVzcy5zdHJlZXQnYFxuICAgKlxuICAgKiBJZiBubyBwYXRoIGlzIGdpdmVuLCB0aGlzIG1ldGhvZCBjaGVja3MgZm9yIHRoZSBlcnJvciBvbiB0aGUgY3VycmVudCBjb250cm9sLlxuICAgKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBlcnJvciBpcyBwcmVzZW50IGluIHRoZSBjb250cm9sIGF0IHRoZSBnaXZlbiBwYXRoLlxuICAgKlxuICAgKiBJZiB0aGUgY29udHJvbCBpcyBub3QgcHJlc2VudCwgZmFsc2UgaXMgcmV0dXJuZWQuXG4gICAqL1xuICBoYXNFcnJvcihlcnJvckNvZGU6IHN0cmluZywgcGF0aD86IEFycmF5PHN0cmluZyB8IG51bWJlcj4gfCBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmdldEVycm9yKGVycm9yQ29kZSwgcGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB0b3AtbGV2ZWwgYW5jZXN0b3Igb2YgdGhpcyBjb250cm9sLlxuICAgKi9cbiAgZ2V0IHJvb3QoKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICBsZXQgeDogQWJzdHJhY3RDb250cm9sID0gdGhpcztcblxuICAgIHdoaWxlICh4Ll9wYXJlbnQpIHtcbiAgICAgIHggPSB4Ll9wYXJlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHg7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF91cGRhdGVDb250cm9sc0Vycm9ycyhcbiAgICBlbWl0RXZlbnQ6IGJvb2xlYW4sXG4gICAgY2hhbmdlZENvbnRyb2w6IEFic3RyYWN0Q29udHJvbCxcbiAgICBzaG91bGRIYXZlRW1pdHRlZD86IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIHRoaXMuc3RhdHVzID0gdGhpcy5fY2FsY3VsYXRlU3RhdHVzKCk7XG5cbiAgICBpZiAoZW1pdEV2ZW50KSB7XG4gICAgICAodGhpcy5zdGF0dXNDaGFuZ2VzIGFzIEV2ZW50RW1pdHRlcjxGb3JtQ29udHJvbFN0YXR1cz4pLmVtaXQodGhpcy5zdGF0dXMpO1xuICAgIH1cblxuICAgIC8vIFRoZSBFdmVudHMgT2JzZXJ2YWJsZSBleHBvc2UgYSBzbGlnaHQgZGlmZmVyZW50IGJldmFoaW9yIHRoYW4gdGhlIHN0YXR1c0NoYW5nZXMgb2JzXG4gICAgLy8gQW4gYXN5bmMgdmFsaWRhdG9yIHdpbGwgc3RpbGwgZW1pdCBhIFN0YXR1c0NoYW5nZUV2ZW50IGlzIGEgcHJldmlvdXNseSBjYW5jZWxsZWRcbiAgICAvLyBhc3luYyB2YWxpZGF0b3IgaGFzIGVtaXRFdmVudCBzZXQgdG8gdHJ1ZVxuICAgIGlmIChlbWl0RXZlbnQgfHwgc2hvdWxkSGF2ZUVtaXR0ZWQpIHtcbiAgICAgIHRoaXMuX2V2ZW50cy5uZXh0KG5ldyBTdGF0dXNDaGFuZ2VFdmVudCh0aGlzLnN0YXR1cywgY2hhbmdlZENvbnRyb2wpKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcGFyZW50KSB7XG4gICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZUNvbnRyb2xzRXJyb3JzKGVtaXRFdmVudCwgY2hhbmdlZENvbnRyb2wsIHNob3VsZEhhdmVFbWl0dGVkKTtcbiAgICB9XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF9pbml0T2JzZXJ2YWJsZXMoKSB7XG4gICAgKHRoaXMgYXMgV3JpdGFibGU8dGhpcz4pLnZhbHVlQ2hhbmdlcyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAodGhpcyBhcyBXcml0YWJsZTx0aGlzPikuc3RhdHVzQ2hhbmdlcyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhbGN1bGF0ZVN0YXR1cygpOiBGb3JtQ29udHJvbFN0YXR1cyB7XG4gICAgaWYgKHRoaXMuX2FsbENvbnRyb2xzRGlzYWJsZWQoKSkgcmV0dXJuIERJU0FCTEVEO1xuICAgIGlmICh0aGlzLmVycm9ycykgcmV0dXJuIElOVkFMSUQ7XG4gICAgaWYgKHRoaXMuX2hhc093blBlbmRpbmdBc3luY1ZhbGlkYXRvciB8fCB0aGlzLl9hbnlDb250cm9sc0hhdmVTdGF0dXMoUEVORElORykpIHJldHVybiBQRU5ESU5HO1xuICAgIGlmICh0aGlzLl9hbnlDb250cm9sc0hhdmVTdGF0dXMoSU5WQUxJRCkpIHJldHVybiBJTlZBTElEO1xuICAgIHJldHVybiBWQUxJRDtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYWJzdHJhY3QgX3VwZGF0ZVZhbHVlKCk6IHZvaWQ7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBhYnN0cmFjdCBfZm9yRWFjaENoaWxkKGNiOiAoYzogQWJzdHJhY3RDb250cm9sKSA9PiB2b2lkKTogdm9pZDtcblxuICAvKiogQGludGVybmFsICovXG4gIGFic3RyYWN0IF9hbnlDb250cm9scyhjb25kaXRpb246IChjOiBBYnN0cmFjdENvbnRyb2wpID0+IGJvb2xlYW4pOiBib29sZWFuO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYWJzdHJhY3QgX2FsbENvbnRyb2xzRGlzYWJsZWQoKTogYm9vbGVhbjtcblxuICAvKiogQGludGVybmFsICovXG4gIGFic3RyYWN0IF9zeW5jUGVuZGluZ0NvbnRyb2xzKCk6IGJvb2xlYW47XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfYW55Q29udHJvbHNIYXZlU3RhdHVzKHN0YXR1czogRm9ybUNvbnRyb2xTdGF0dXMpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fYW55Q29udHJvbHMoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gY29udHJvbC5zdGF0dXMgPT09IHN0YXR1cyk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF9hbnlDb250cm9sc0RpcnR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9hbnlDb250cm9scygoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBjb250cm9sLmRpcnR5KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2FueUNvbnRyb2xzVG91Y2hlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fYW55Q29udHJvbHMoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gY29udHJvbC50b3VjaGVkKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3VwZGF0ZVByaXN0aW5lKG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW59LCBjaGFuZ2VkQ29udHJvbDogQWJzdHJhY3RDb250cm9sKTogdm9pZCB7XG4gICAgY29uc3QgbmV3UHJpc3RpbmUgPSAhdGhpcy5fYW55Q29udHJvbHNEaXJ0eSgpO1xuICAgIGNvbnN0IGNoYW5nZWQgPSB0aGlzLnByaXN0aW5lICE9PSBuZXdQcmlzdGluZTtcbiAgICB0aGlzLnByaXN0aW5lID0gbmV3UHJpc3RpbmU7XG5cbiAgICBpZiAodGhpcy5fcGFyZW50ICYmICFvcHRzLm9ubHlTZWxmKSB7XG4gICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZVByaXN0aW5lKG9wdHMsIGNoYW5nZWRDb250cm9sKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgdGhpcy5fZXZlbnRzLm5leHQobmV3IFByaXN0aW5lQ2hhbmdlRXZlbnQodGhpcy5wcmlzdGluZSwgY2hhbmdlZENvbnRyb2wpKTtcbiAgICB9XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF91cGRhdGVUb3VjaGVkKG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW59ID0ge30sIGNoYW5nZWRDb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiB2b2lkIHtcbiAgICB0aGlzLnRvdWNoZWQgPSB0aGlzLl9hbnlDb250cm9sc1RvdWNoZWQoKTtcbiAgICB0aGlzLl9ldmVudHMubmV4dChuZXcgVG91Y2hlZENoYW5nZUV2ZW50KHRoaXMudG91Y2hlZCwgY2hhbmdlZENvbnRyb2wpKTtcblxuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlVG91Y2hlZChvcHRzLCBjaGFuZ2VkQ29udHJvbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfb25EaXNhYmxlZENoYW5nZTogQXJyYXk8KGlzRGlzYWJsZWQ6IGJvb2xlYW4pID0+IHZvaWQ+ID0gW107XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfcmVnaXN0ZXJPbkNvbGxlY3Rpb25DaGFuZ2UoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLl9vbkNvbGxlY3Rpb25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3NldFVwZGF0ZVN0cmF0ZWd5KG9wdHM/OiBWYWxpZGF0b3JGbiB8IFZhbGlkYXRvckZuW10gfCBBYnN0cmFjdENvbnRyb2xPcHRpb25zIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmIChpc09wdGlvbnNPYmoob3B0cykgJiYgb3B0cy51cGRhdGVPbiAhPSBudWxsKSB7XG4gICAgICB0aGlzLl91cGRhdGVPbiA9IG9wdHMudXBkYXRlT24hO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogQ2hlY2sgdG8gc2VlIGlmIHBhcmVudCBoYXMgYmVlbiBtYXJrZWQgYXJ0aWZpY2lhbGx5IGRpcnR5LlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX3BhcmVudE1hcmtlZERpcnR5KG9ubHlTZWxmPzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhcmVudERpcnR5ID0gdGhpcy5fcGFyZW50ICYmIHRoaXMuX3BhcmVudC5kaXJ0eTtcbiAgICByZXR1cm4gIW9ubHlTZWxmICYmICEhcGFyZW50RGlydHkgJiYgIXRoaXMuX3BhcmVudCEuX2FueUNvbnRyb2xzRGlydHkoKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2ZpbmQobmFtZTogc3RyaW5nIHwgbnVtYmVyKTogQWJzdHJhY3RDb250cm9sIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIGBzZXRWYWxpZGF0b3JzYCBtZXRob2QuIE5lZWRzIHRvIGJlIHNlcGFyYXRlZCBvdXQgaW50byBhXG4gICAqIGRpZmZlcmVudCBtZXRob2QsIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGluIHRoZSBjb25zdHJ1Y3RvciBhbmQgaXQgY2FuIGJyZWFrIGNhc2VzIHdoZXJlXG4gICAqIGEgY29udHJvbCBpcyBleHRlbmRlZC5cbiAgICovXG4gIHByaXZhdGUgX2Fzc2lnblZhbGlkYXRvcnModmFsaWRhdG9yczogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX3Jhd1ZhbGlkYXRvcnMgPSBBcnJheS5pc0FycmF5KHZhbGlkYXRvcnMpID8gdmFsaWRhdG9ycy5zbGljZSgpIDogdmFsaWRhdG9ycztcbiAgICB0aGlzLl9jb21wb3NlZFZhbGlkYXRvckZuID0gY29lcmNlVG9WYWxpZGF0b3IodGhpcy5fcmF3VmFsaWRhdG9ycyk7XG4gIH1cblxuICAvKipcbiAgICogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIGBzZXRBc3luY1ZhbGlkYXRvcnNgIG1ldGhvZC4gTmVlZHMgdG8gYmUgc2VwYXJhdGVkIG91dCBpbnRvIGFcbiAgICogZGlmZmVyZW50IG1ldGhvZCwgYmVjYXVzZSBpdCBpcyBjYWxsZWQgaW4gdGhlIGNvbnN0cnVjdG9yIGFuZCBpdCBjYW4gYnJlYWsgY2FzZXMgd2hlcmVcbiAgICogYSBjb250cm9sIGlzIGV4dGVuZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfYXNzaWduQXN5bmNWYWxpZGF0b3JzKHZhbGlkYXRvcnM6IEFzeW5jVmFsaWRhdG9yRm4gfCBBc3luY1ZhbGlkYXRvckZuW10gfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5fcmF3QXN5bmNWYWxpZGF0b3JzID0gQXJyYXkuaXNBcnJheSh2YWxpZGF0b3JzKSA/IHZhbGlkYXRvcnMuc2xpY2UoKSA6IHZhbGlkYXRvcnM7XG4gICAgdGhpcy5fY29tcG9zZWRBc3luY1ZhbGlkYXRvckZuID0gY29lcmNlVG9Bc3luY1ZhbGlkYXRvcih0aGlzLl9yYXdBc3luY1ZhbGlkYXRvcnMpO1xuICB9XG59XG4iXX0=
|