@sumaris-net/ngx-components 18.2.26 → 18.2.27-alpha1

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.
@@ -0,0 +1,631 @@
1
+ import { booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, forwardRef, Inject, Input, numberAttribute, Optional, Output, ViewChild, } from '@angular/core';
2
+ import { FormControl, NG_VALUE_ACCESSOR, Validators, } from '@angular/forms';
3
+ import { MAT_FORM_FIELD_DEFAULT_OPTIONS, } from '@angular/material/form-field';
4
+ import { merge, Subscription } from 'rxjs';
5
+ import { filter } from 'rxjs/operators';
6
+ import { isNil, isNilOrBlank, isNotNil } from '../../functions';
7
+ import { isMobile } from '../../platforms';
8
+ import { SharedValidators } from '../../validator/validators';
9
+ import { MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING } from '../material.config';
10
+ import { computeDecimalDegrees, LAT_LONG_DEFAULT_MAX_DECIMALS, splitNumberToFieldsDD, splitNumberToFieldsDDMM, splitNumberToFieldsDDMMSS, } from './latlong.utils';
11
+ import * as i0 from "@angular/core";
12
+ import * as i1 from "@angular/forms";
13
+ import * as i2 from "@angular/common";
14
+ import * as i3 from "@ionic/angular";
15
+ import * as i4 from "../../directives/autofocus.directive";
16
+ import * as i5 from "@angular/material/form-field";
17
+ import * as i6 from "@angular/material/input";
18
+ import * as i7 from "@angular/material/button";
19
+ import * as i8 from "@angular/material/icon";
20
+ import * as i9 from "@angular/material/select";
21
+ import * as i10 from "@angular/material/core";
22
+ import * as i11 from "@ngx-translate/core";
23
+ import * as i12 from "../../pipes/latlong-format.pipe";
24
+ import * as i13 from "../../pipes/arrays.pipe";
25
+ import * as i14 from "../../pipes/maps.pipe";
26
+ import * as i15 from "../../pipes/string.pipes";
27
+ import * as i16 from "../../pipes/types.pipes";
28
+ const noop = () => { };
29
+ export class MatLatLongField2 {
30
+ cd;
31
+ formGroupDir;
32
+ _onChangeCallback = noop;
33
+ _onTouchedCallback = noop;
34
+ _subscription = new Subscription();
35
+ _disabling = false;
36
+ _writing = false;
37
+ _appearance = null;
38
+ _subscriptSizing = null;
39
+ _readonly = false;
40
+ _tabindex;
41
+ _defaultAppearance;
42
+ _defaultSubscriptSizing;
43
+ _focused = false;
44
+ _touched = false;
45
+ degreesControl;
46
+ minutesControl;
47
+ secondsControl;
48
+ signControl;
49
+ showMinutes = false;
50
+ showSeconds = false;
51
+ showSignControl;
52
+ degreesPlaceholder;
53
+ minutesPlaceholder;
54
+ secondsPlaceholder;
55
+ maxDecimals = LAT_LONG_DEFAULT_MAX_DECIMALS;
56
+ i18nErrorKeys = SharedValidators.I18N_ERROR_KEYS;
57
+ minMaxValues;
58
+ inputWidth;
59
+ formControl;
60
+ formControlName;
61
+ type;
62
+ pattern;
63
+ required = false;
64
+ floatLabel = 'auto';
65
+ placeholder;
66
+ defaultSign;
67
+ autofocus = false;
68
+ mobile;
69
+ degreesSymbolUnit = '°';
70
+ minutesSymbolUnit = "'";
71
+ secondsSymbolUnit = '"';
72
+ clearable = true;
73
+ set tabindex(value) {
74
+ if (this._tabindex !== value) {
75
+ this._tabindex = value;
76
+ setTimeout(() => this.updateTabIndex());
77
+ }
78
+ }
79
+ get tabindex() {
80
+ return this._tabindex;
81
+ }
82
+ set appearance(value) {
83
+ this._appearance = value;
84
+ }
85
+ get appearance() {
86
+ return this._appearance || this._defaultAppearance;
87
+ }
88
+ set readonly(value) {
89
+ this._readonly = value;
90
+ this.markForCheck();
91
+ }
92
+ get readonly() {
93
+ return this._readonly;
94
+ }
95
+ set subscriptSizing(value) {
96
+ this._subscriptSizing = value;
97
+ }
98
+ get subscriptSizing() {
99
+ return this._subscriptSizing || this._defaultSubscriptSizing;
100
+ }
101
+ get showFields() {
102
+ return isNotNil(this.formControl.value) || this._focused;
103
+ }
104
+ get disabled() {
105
+ return this.readonly || this.formControl.disabled;
106
+ }
107
+ // eslint-disable-next-line @angular-eslint/no-output-on-prefix,@angular-eslint/no-output-rename
108
+ keyupEnter = new EventEmitter();
109
+ // eslint-disable-next-line @angular-eslint/no-output-rename
110
+ blurred = new EventEmitter();
111
+ // eslint-disable-next-line @angular-eslint/no-output-rename
112
+ focused = new EventEmitter();
113
+ formField;
114
+ fakeInput;
115
+ inputDegrees;
116
+ inputMinutes;
117
+ inputSeconds;
118
+ inputSign;
119
+ constructor(cd, formGroupDir, defaultOptions) {
120
+ this.cd = cd;
121
+ this.formGroupDir = formGroupDir;
122
+ this._defaultSubscriptSizing = defaultOptions?.subscriptSizing || MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING;
123
+ this._defaultAppearance = defaultOptions?.appearance || MAT_FORM_FIELD_DEFAULT_APPEARANCE;
124
+ }
125
+ ngOnInit() {
126
+ this.mobile = this.mobile ?? isMobile(window);
127
+ this.type = this.type || 'latitude';
128
+ this.pattern = this.pattern || 'DDMM';
129
+ this.showSignControl = this.pattern !== 'DD';
130
+ const degreesValidators = [this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude];
131
+ const minutesValidators = [];
132
+ const secondsValidators = [];
133
+ this.minMaxValues = {};
134
+ switch (this.pattern) {
135
+ case 'DD':
136
+ this.maxDecimals = 7;
137
+ degreesValidators.push(SharedValidators.decimal({ maxDecimals: this.maxDecimals }));
138
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.DD_PLACEHOLDER' : 'COMMON.LAT_LONG.DDD_PLACEHOLDER';
139
+ this.inputWidth = {
140
+ degrees: '95%',
141
+ degreesUnit: '5%',
142
+ };
143
+ break;
144
+ case 'DDMM':
145
+ this.maxDecimals = 3;
146
+ this.showMinutes = true;
147
+ this.minMaxValues['minutes'] = {
148
+ min: 0,
149
+ max: 60 - this.computeDecimalPart(1, this.maxDecimals),
150
+ step: this.computeDecimalPart(1, this.maxDecimals),
151
+ };
152
+ degreesValidators.push(SharedValidators.integer);
153
+ minutesValidators.push(Validators.min(this.minMaxValues.minutes.min));
154
+ minutesValidators.push(Validators.max(this.minMaxValues.minutes.max));
155
+ minutesValidators.push(SharedValidators.decimal({ maxDecimals: this.maxDecimals }));
156
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
157
+ this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM_MMM';
158
+ this.inputWidth = {
159
+ degrees: '35%',
160
+ degreesUnit: '5%',
161
+ minutes: '55%',
162
+ minutesUnit: '5%',
163
+ };
164
+ break;
165
+ default: // Default is DDMMSS
166
+ this.maxDecimals = 2;
167
+ this.showMinutes = true;
168
+ this.showSeconds = true;
169
+ this.minMaxValues['minutes'] = {
170
+ min: 0,
171
+ max: 59,
172
+ step: 1,
173
+ };
174
+ this.minMaxValues['seconds'] = {
175
+ min: 0,
176
+ max: 60 - this.computeDecimalPart(1, this.maxDecimals),
177
+ step: this.computeDecimalPart(1, this.maxDecimals),
178
+ };
179
+ degreesValidators.push(SharedValidators.integer);
180
+ minutesValidators.push(SharedValidators.integer);
181
+ minutesValidators.push(Validators.min(this.minMaxValues.minutes.min));
182
+ minutesValidators.push(Validators.max(this.minMaxValues.minutes.max));
183
+ secondsValidators.push(Validators.min(this.minMaxValues.seconds.min));
184
+ secondsValidators.push(Validators.max(this.minMaxValues.seconds.max));
185
+ secondsValidators.push(SharedValidators.decimal({ maxDecimals: this.maxDecimals }));
186
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
187
+ this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
188
+ this.secondsPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.SS_SS';
189
+ this.inputWidth = {
190
+ degrees: '25%',
191
+ degreesUnit: '5%',
192
+ minutes: '25%',
193
+ minutesUnit: '5%',
194
+ seconds: '35%',
195
+ secondsUnit: '5%',
196
+ };
197
+ break;
198
+ }
199
+ // Must be done after set this.maxDecimals in switch block above
200
+ this.minMaxValues['degrees'] = {
201
+ min: this.pattern === 'DD' ? (this.type === 'latitude' ? -90 : -180) : 0,
202
+ max: this.type === 'latitude' ? 90 : 180,
203
+ step: this.pattern === 'DD' ? this.computeDecimalPart(1, this.maxDecimals) : 1,
204
+ };
205
+ this.formControl =
206
+ this.formControl || (this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName));
207
+ if (!this.formControl)
208
+ throw new Error("Missing mandatory attribute 'formControl' or 'formControlName' in <mat-latlong-field>.");
209
+ this.degreesControl = new FormControl(null, degreesValidators);
210
+ this.minutesControl = new FormControl(null, minutesValidators);
211
+ this.secondsControl = new FormControl(null, secondsValidators);
212
+ this.signControl = new FormControl(null);
213
+ this._subscription.add(merge(this.degreesControl.valueChanges, this.minutesControl.valueChanges, this.secondsControl.valueChanges, this.signControl.valueChanges).subscribe((_) => this.onFormChange()));
214
+ // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
215
+ this._subscription.add(this.formControl.statusChanges
216
+ .pipe(filter(() => !this.readonly && !this._writing && !this._disabling) // Skip
217
+ )
218
+ .subscribe(() => this.markForCheck()));
219
+ }
220
+ ngOnDestroy() {
221
+ this._subscription.unsubscribe();
222
+ }
223
+ registerOnChange(fn) {
224
+ this._onChangeCallback = fn;
225
+ }
226
+ registerOnTouched(fn) {
227
+ this._onTouchedCallback = fn;
228
+ }
229
+ writeValue(value) {
230
+ if (this._writing)
231
+ return;
232
+ this._writing = true;
233
+ if (value !== this.formControl.value) {
234
+ this.formControl.patchValue(value, { emitEvent: false });
235
+ this._onChangeCallback(value);
236
+ }
237
+ const result = this.computeLatLongFormGroupValue(value);
238
+ console.debug('[mat-latlong-field] Changing value of inputs:', value, result);
239
+ this.patchValue(result, { emitEvent: false });
240
+ this._writing = false;
241
+ this.markForCheck();
242
+ setTimeout(() => {
243
+ this.updateFakeInput();
244
+ this.updateTabIndex();
245
+ });
246
+ }
247
+ setDisabledState(isDisabled) {
248
+ if (this._disabling)
249
+ return;
250
+ this._disabling = true;
251
+ if (isDisabled) {
252
+ this.degreesControl.disable();
253
+ this.minutesControl.disable();
254
+ this.secondsControl.disable();
255
+ this.signControl.disable();
256
+ }
257
+ else {
258
+ this.degreesControl.enable();
259
+ this.minutesControl.enable();
260
+ this.secondsControl.enable();
261
+ this.signControl.enable();
262
+ }
263
+ this._disabling = false;
264
+ this.markForCheck();
265
+ }
266
+ clearValue(event) {
267
+ event?.stopPropagation();
268
+ this.writeValue(null);
269
+ }
270
+ get inputsElements() {
271
+ return (this.inputDegrees ? [this.inputDegrees.nativeElement] : [])
272
+ .concat(this.inputMinutes ? [this.inputMinutes.nativeElement] : [])
273
+ .concat(this.inputSeconds ? [this.inputSeconds.nativeElement] : [])
274
+ .concat(this.inputSign ? [this.inputSign.nativeElement] : [])
275
+ .concat(this.fakeInput ? [this.fakeInput.nativeElement] : []);
276
+ }
277
+ onFocusFakeInput(event) {
278
+ if (!this.showFields) {
279
+ event.preventDefault();
280
+ // Hide the fake input
281
+ this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
282
+ }
283
+ this._touched = this.formControl.touched;
284
+ // Focus on first input
285
+ this.focus();
286
+ }
287
+ onBlurFakeInput(event) {
288
+ const internalEvent = this.inputsElements.some((el) => el === event.relatedTarget);
289
+ if (internalEvent && !this._touched) {
290
+ // Workaround to remove touched on the fakeInput
291
+ this.formControl.markAsUntouched();
292
+ }
293
+ }
294
+ _onFocusInput(event) {
295
+ const internalEvent = this.inputsElements.some((el) => el === event.relatedTarget);
296
+ if (!internalEvent) {
297
+ this.focus(false /*focusOnDegrees*/);
298
+ }
299
+ }
300
+ _onBlurInput(event) {
301
+ const internalEvent = this.inputsElements.some((el) => el === event.relatedTarget);
302
+ if (!internalEvent) {
303
+ this._focused = false;
304
+ if (this.appearance == 'fill') {
305
+ this.formField._lineRipple.deactivate();
306
+ }
307
+ this.blurred.emit(event);
308
+ this.updateFakeInput();
309
+ this.updateTabIndex();
310
+ this._touched = true;
311
+ this.formControl.markAsTouched();
312
+ this._checkIfTouched();
313
+ }
314
+ }
315
+ _onClickInput(event) {
316
+ // Avoid mat-form-field to give focus to fake input
317
+ event.stopPropagation();
318
+ }
319
+ focus(focusOnDegrees) {
320
+ if (this._focused)
321
+ return true; // Already focused
322
+ const showFields = this.showFields;
323
+ this._focused = true;
324
+ this.markForCheck();
325
+ setTimeout(() => {
326
+ if (!showFields && focusOnDegrees !== false)
327
+ this.inputDegrees.nativeElement.focus();
328
+ if (this.appearance == 'fill') {
329
+ this.formField._lineRipple.activate();
330
+ }
331
+ // Add a blur listener on each inputs
332
+ /*const inputElements: HTMLElement[] = this.inputsElements;
333
+ inputElements.filter(isNotNil).forEach(
334
+ (el) =>
335
+ (el.onblur = (e) => {
336
+ //console.debug('onblur to element=', e.relatedTarget);
337
+
338
+ // Setup a one-time focus event handler
339
+ const focusListener = (focusEvent: FocusEvent) => {
340
+ // Remove the event listener after it has been executed once
341
+ window.removeEventListener('focus', focusListener);
342
+
343
+ //console.debug('NExt focus element=', focusEvent.target);
344
+ const internalEvent = inputElements.includes(focusEvent.target as HTMLElement);
345
+
346
+ if (!internalEvent) {
347
+ this._focused = false;
348
+ this.updateFakeInput();
349
+ this.updateTabIndex();
350
+ //this._onTouchedCallback();
351
+
352
+ this.formField._lineRipple.deactivate();
353
+ this.blurred.emit(focusEvent);
354
+
355
+ // this._touched = true;
356
+ // this.formControl.markAsUntouched();
357
+ // this._checkIfTouched();
358
+ }
359
+ };
360
+ window.addEventListener('focus', focusListener, true);
361
+ })
362
+ );*/
363
+ this.updateFakeInput();
364
+ this.updateTabIndex();
365
+ }, 250);
366
+ }
367
+ format(rawValue) {
368
+ const values = this.computeLatLongFormGroupValue(rawValue);
369
+ if (values.degrees === null)
370
+ return '';
371
+ let result = `${values.degrees}° `;
372
+ if (values.minutes !== null)
373
+ result += `${values.minutes}' `;
374
+ if (values.seconds !== null)
375
+ result += `${values.seconds}" `;
376
+ if (this.type === 'latitude') {
377
+ result += values.sign === 1 ? 'N' : 'S';
378
+ }
379
+ else {
380
+ result += values.sign === 1 ? 'E' : 'W';
381
+ }
382
+ return result;
383
+ }
384
+ computeDecimalPart(value, nbOfDecimals) {
385
+ return value * 10 ** (nbOfDecimals * -1);
386
+ }
387
+ computeLatLongFormGroupValue(rawValue) {
388
+ const isLongitude = this.type === 'longitude';
389
+ const value = typeof rawValue === 'string' ? parseFloat(rawValue.replace(/,/g, '.')) : rawValue;
390
+ const result = {
391
+ degrees: null,
392
+ minutes: null,
393
+ seconds: null,
394
+ sign: isNotNil(value)
395
+ ? value < 0
396
+ ? -1
397
+ : 1
398
+ : // Use default sign, if any
399
+ this.defaultSign && this.defaultSign === '-'
400
+ ? -1
401
+ : 1,
402
+ };
403
+ if (value === 0) {
404
+ result.degrees = 0;
405
+ }
406
+ else if (isNotNil(value)) {
407
+ if (this.pattern === 'DD') {
408
+ const splitValue = splitNumberToFieldsDD(value, {
409
+ longitude: isLongitude,
410
+ pattern: this.pattern,
411
+ maxDecimals: this.maxDecimals,
412
+ fixLatLong: true,
413
+ }).slice(1); // remove sign;
414
+ result.degrees = (splitValue[0] + this.computeDecimalPart(splitValue[1] ?? 0, this.maxDecimals)) * (result.sign || 1) || null;
415
+ }
416
+ else if (this.pattern === 'DDMM') {
417
+ const splitValue = splitNumberToFieldsDDMM(value, {
418
+ longitude: isLongitude,
419
+ pattern: this.pattern,
420
+ maxDecimals: this.maxDecimals,
421
+ fixLatLong: true,
422
+ });
423
+ result['minutes'] = Math.abs((splitValue[1] ?? 0) + this.computeDecimalPart(splitValue[2] ?? 0, this.maxDecimals)) || null;
424
+ result['degrees'] = Math.abs(!result['minutes'] && isNilOrBlank(splitValue[0]) ? null : (splitValue[0] ?? 0));
425
+ }
426
+ else {
427
+ // Default // DDMMSS
428
+ const splitValue = splitNumberToFieldsDDMMSS(value, {
429
+ longitude: isLongitude,
430
+ pattern: this.pattern,
431
+ maxDecimals: this.maxDecimals,
432
+ fixLatLong: true,
433
+ });
434
+ result['seconds'] = Math.abs((splitValue[2] ?? 0) + this.computeDecimalPart(splitValue[3] ?? 0, this.maxDecimals)) || null;
435
+ result['minutes'] = !result['seconds'] && !splitValue[1] ? null : Math.abs(splitValue[1] ?? 0);
436
+ result['degrees'] = !result['seconds'] && !result['minutes'] && isNilOrBlank(splitValue[0]) ? null : Math.abs(splitValue[0] ?? 0);
437
+ }
438
+ }
439
+ return result;
440
+ }
441
+ markAsTouched() {
442
+ this.formControl.markAsTouched();
443
+ this.degreesControl.markAsTouched();
444
+ this.minutesControl.markAsTouched();
445
+ this.secondsControl.markAsTouched();
446
+ this.signControl.markAsTouched();
447
+ this._onTouchedCallback();
448
+ }
449
+ /* -- private method -- */
450
+ patchValue(values, opts) {
451
+ this.degreesControl.patchValue(values.degrees, opts);
452
+ this.minutesControl.patchValue(values.minutes, opts);
453
+ this.secondsControl.patchValue(values.seconds, opts);
454
+ this.signControl.patchValue(values.sign, opts);
455
+ }
456
+ onFormChange() {
457
+ if (this._writing)
458
+ return; // Skip if call by self
459
+ this._writing = true;
460
+ // DEBUG
461
+ console.debug('[mat-latlong-field] onFormChange ');
462
+ const degrees = this.degreesControl.value;
463
+ const minutes = this.minutesControl.value;
464
+ const seconds = this.secondsControl.value;
465
+ const sign = this.signControl.value;
466
+ const incompleteValue = isNil(degrees) && (isNotNil(minutes) || isNotNil(seconds));
467
+ const invalid = incompleteValue || this.degreesControl.invalid || this.minutesControl.invalid || this.secondsControl.invalid || this.signControl.invalid;
468
+ if (invalid) {
469
+ // DEBUG
470
+ console.debug(`[mat-latlong-field] onFormChange() error -> incompleteValue: ${incompleteValue}`);
471
+ this.formControl.markAsPending({ onlySelf: true });
472
+ this.formControl.setErrors({
473
+ invalid: incompleteValue,
474
+ ...this.degreesControl.errors,
475
+ ...this.minutesControl.errors,
476
+ ...this.secondsControl.errors,
477
+ ...this.signControl.errors,
478
+ });
479
+ if (this.degreesControl.dirty || this.minutesControl.dirty || this.secondsControl.dirty || this.signControl.dirty) {
480
+ this.formControl.markAsDirty();
481
+ }
482
+ this._writing = false;
483
+ return;
484
+ }
485
+ // Compute decimal values
486
+ const value = isNil(degrees) || this.pattern === 'DD' ? degrees : computeDecimalDegrees(degrees, minutes, seconds, sign, this.maxDecimals);
487
+ // Set model value
488
+ this.emitChange(value);
489
+ this._writing = false;
490
+ this.markForCheck();
491
+ }
492
+ emitChange(value) {
493
+ if (this.formControl.value !== value) {
494
+ // DEBUG
495
+ console.debug('[mat-latlong-field] Emit new value: ' + value);
496
+ this.formControl.setValue(value, { emitEvent: false });
497
+ // Changes comes from inside function: use the callback
498
+ this._onChangeCallback(value);
499
+ // Check if need to update controls
500
+ this._checkIfTouched();
501
+ }
502
+ }
503
+ _checkIfTouched() {
504
+ if (this.formControl.touched) {
505
+ this._onTouchedCallback();
506
+ this.markForCheck();
507
+ this._touched = true;
508
+ }
509
+ else {
510
+ this._touched = false;
511
+ }
512
+ }
513
+ markForCheck() {
514
+ this.cd.markForCheck();
515
+ }
516
+ /**
517
+ * Show/Hide the fake input
518
+ */
519
+ updateFakeInput() {
520
+ if (this.showFields) {
521
+ this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
522
+ }
523
+ else {
524
+ this.fakeInput?.nativeElement.classList.remove('cdk-visually-hidden');
525
+ }
526
+ // TODO: check if need
527
+ this.markForCheck();
528
+ }
529
+ /**
530
+ * This is a special case, because, this component has a temporary component displayed before the first focus event
531
+ */
532
+ updateTabIndex() {
533
+ if (isNil(this._tabindex))
534
+ return;
535
+ if (this.fakeInput) {
536
+ this.fakeInput.nativeElement.tabIndex = this._tabindex;
537
+ }
538
+ this.markForCheck();
539
+ }
540
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField2, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.FormGroupDirective, optional: true }, { token: MAT_FORM_FIELD_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
541
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongField2, selector: "mat-latlong-field", inputs: { formControl: "formControl", formControlName: "formControlName", type: "type", pattern: ["latLongPattern", "pattern"], required: "required", floatLabel: "floatLabel", placeholder: "placeholder", defaultSign: "defaultSign", autofocus: "autofocus", mobile: ["mobile", "mobile", booleanAttribute], degreesSymbolUnit: "degreesSymbolUnit", minutesSymbolUnit: "minutesSymbolUnit", secondsSymbolUnit: "secondsSymbolUnit", clearable: ["clearable", "clearable", booleanAttribute], tabindex: ["tabindex", "tabindex", numberAttribute], appearance: "appearance", readonly: "readonly", subscriptSizing: "subscriptSizing" }, outputs: { keyupEnter: "keyup.enter", blurred: "blur", focused: "focus" }, providers: [
542
+ {
543
+ provide: NG_VALUE_ACCESSOR,
544
+ multi: true,
545
+ useExisting: forwardRef(() => MatLatLongField2),
546
+ },
547
+ ], viewQueries: [{ propertyName: "formField", first: true, predicate: ["formField"], descendants: true }, { propertyName: "fakeInput", first: true, predicate: ["fakeInput"], descendants: true }, { propertyName: "inputDegrees", first: true, predicate: ["inputDegrees"], descendants: true }, { propertyName: "inputMinutes", first: true, predicate: ["inputMinutes"], descendants: true }, { propertyName: "inputSeconds", first: true, predicate: ["inputSeconds"], descendants: true }, { propertyName: "inputSign", first: true, predicate: ["inputSign"], descendants: true }], ngImport: i0, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: maxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <ion-grid class=\"ion-no-padding {{ appearance }}\">\n <ion-row class=\"ion-no-padding no-wrap\">\n <!-- degrees -->\n <ion-col class=\"degrees ion-no-padding\">\n <mat-form-field\n #formField\n [floatLabel]=\"\n showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\n \"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"values\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input\n matInput\n #fakeInput\n type=\"text\"\n readonly=\"true\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [appAutofocus]=\"!showFields && autofocus\"\n [tabindex]=\"tabindex\"\n [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [style.width]=\"showFields ? inputWidth.degrees : '100%'\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [min]=\"minMaxValues.degrees.min\"\n [max]=\"minMaxValues.degrees.max\"\n [step]=\"minMaxValues.degrees.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n [class.cdk-visually-hidden]=\"!showFields\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.degreesUnit\"\n >\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [style.width]=\"this.inputWidth.minutes\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.minutes.min\"\n [max]=\"minMaxValues.minutes.max\"\n [step]=\"minMaxValues.minutes.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.minutesUnit\"\n >\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n [style.width]=\"inputWidth.seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.seconds.min\"\n [max]=\"minMaxValues.seconds.max\"\n [step]=\"minMaxValues.seconds.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n [style.width]=\"this.inputWidth.secondsUnit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n class=\"symbol-unit\"\n >\n {{ secondsSymbolUnit }}\n </span>\n }\n\n @if (!showSignControl) {\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n }\n </mat-form-field>\n </ion-col>\n\n <!-- sign -->\n @if (showSignControl) {\n <ion-col class=\"sign ion-no-padding {{ type }}\">\n @switch (type) {\n @case ('latitude') {\n <!-- sign on latitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_N' | translate }}</mat-option>\n <mat-option [value]=\"-1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_S' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n @case ('longitude') {\n <!-- sign on longitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_E' | translate }}</mat-option>\n <mat-option [value]=\"-1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_W' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n }\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative;--ion-grid-column-padding: 0}mat-form-field{width:100%}mat-form-field .datetime-md{padding:0!important}.sign mat-form-field.mat-mdc-form-field-should-float .mat-mdc-form-field-placeholder{max-width:inherit}ion-row.no-wrap{flex-wrap:nowrap}ion-grid ion-col.degrees{--min-width: 130px;min-width:var(--min-width)}ion-grid ion-col.minutes{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.seconds{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.sign{--min-width: 58px;--max-width: 65px;min-width:var(--min-width);max-width:var(--max-width)}input[type=number]{text-align:right}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}span.symbol-unit{display:inline-block;text-align:center;font-weight:700;font-size:1.3em}\n"], dependencies: [{ kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i3.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i3.IonRow, selector: "ion-row" }, { kind: "component", type: i3.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i5.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i11.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i12.LatLongFormatPipe, name: "latLongFormat" }, { kind: "pipe", type: i13.ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: i14.MapGetPipe, name: "mapGet" }, { kind: "pipe", type: i14.MapKeysPipe, name: "mapKeys" }, { kind: "pipe", type: i15.IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }, { kind: "pipe", type: i15.IsNilPipe, name: "isNil" }, { kind: "pipe", type: i16.AsFloatLabelTypePipe, name: "asFloatLabelType" }, { kind: "pipe", type: i11.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
548
+ }
549
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField2, decorators: [{
550
+ type: Component,
551
+ args: [{ selector: 'mat-latlong-field', providers: [
552
+ {
553
+ provide: NG_VALUE_ACCESSOR,
554
+ multi: true,
555
+ useExisting: forwardRef(() => MatLatLongField2),
556
+ },
557
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: maxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <ion-grid class=\"ion-no-padding {{ appearance }}\">\n <ion-row class=\"ion-no-padding no-wrap\">\n <!-- degrees -->\n <ion-col class=\"degrees ion-no-padding\">\n <mat-form-field\n #formField\n [floatLabel]=\"\n showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\n \"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"values\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input\n matInput\n #fakeInput\n type=\"text\"\n readonly=\"true\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [appAutofocus]=\"!showFields && autofocus\"\n [tabindex]=\"tabindex\"\n [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [style.width]=\"showFields ? inputWidth.degrees : '100%'\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [min]=\"minMaxValues.degrees.min\"\n [max]=\"minMaxValues.degrees.max\"\n [step]=\"minMaxValues.degrees.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n [class.cdk-visually-hidden]=\"!showFields\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.degreesUnit\"\n >\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [style.width]=\"this.inputWidth.minutes\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.minutes.min\"\n [max]=\"minMaxValues.minutes.max\"\n [step]=\"minMaxValues.minutes.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.minutesUnit\"\n >\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n [style.width]=\"inputWidth.seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.seconds.min\"\n [max]=\"minMaxValues.seconds.max\"\n [step]=\"minMaxValues.seconds.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n [style.width]=\"this.inputWidth.secondsUnit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n class=\"symbol-unit\"\n >\n {{ secondsSymbolUnit }}\n </span>\n }\n\n @if (!showSignControl) {\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n }\n </mat-form-field>\n </ion-col>\n\n <!-- sign -->\n @if (showSignControl) {\n <ion-col class=\"sign ion-no-padding {{ type }}\">\n @switch (type) {\n @case ('latitude') {\n <!-- sign on latitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_N' | translate }}</mat-option>\n <mat-option [value]=\"-1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_S' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n @case ('longitude') {\n <!-- sign on longitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_E' | translate }}</mat-option>\n <mat-option [value]=\"-1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_W' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n }\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative;--ion-grid-column-padding: 0}mat-form-field{width:100%}mat-form-field .datetime-md{padding:0!important}.sign mat-form-field.mat-mdc-form-field-should-float .mat-mdc-form-field-placeholder{max-width:inherit}ion-row.no-wrap{flex-wrap:nowrap}ion-grid ion-col.degrees{--min-width: 130px;min-width:var(--min-width)}ion-grid ion-col.minutes{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.seconds{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.sign{--min-width: 58px;--max-width: 65px;min-width:var(--min-width);max-width:var(--max-width)}input[type=number]{text-align:right}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}span.symbol-unit{display:inline-block;text-align:center;font-weight:700;font-size:1.3em}\n"] }]
558
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.FormGroupDirective, decorators: [{
559
+ type: Optional
560
+ }] }, { type: undefined, decorators: [{
561
+ type: Inject,
562
+ args: [MAT_FORM_FIELD_DEFAULT_OPTIONS]
563
+ }] }], propDecorators: { formControl: [{
564
+ type: Input
565
+ }], formControlName: [{
566
+ type: Input
567
+ }], type: [{
568
+ type: Input
569
+ }], pattern: [{
570
+ type: Input,
571
+ args: ['latLongPattern']
572
+ }], required: [{
573
+ type: Input
574
+ }], floatLabel: [{
575
+ type: Input
576
+ }], placeholder: [{
577
+ type: Input
578
+ }], defaultSign: [{
579
+ type: Input
580
+ }], autofocus: [{
581
+ type: Input
582
+ }], mobile: [{
583
+ type: Input,
584
+ args: [{ transform: booleanAttribute }]
585
+ }], degreesSymbolUnit: [{
586
+ type: Input
587
+ }], minutesSymbolUnit: [{
588
+ type: Input
589
+ }], secondsSymbolUnit: [{
590
+ type: Input
591
+ }], clearable: [{
592
+ type: Input,
593
+ args: [{ transform: booleanAttribute }]
594
+ }], tabindex: [{
595
+ type: Input,
596
+ args: [{ transform: numberAttribute }]
597
+ }], appearance: [{
598
+ type: Input
599
+ }], readonly: [{
600
+ type: Input
601
+ }], subscriptSizing: [{
602
+ type: Input
603
+ }], keyupEnter: [{
604
+ type: Output,
605
+ args: ['keyup.enter']
606
+ }], blurred: [{
607
+ type: Output,
608
+ args: ['blur']
609
+ }], focused: [{
610
+ type: Output,
611
+ args: ['focus']
612
+ }], formField: [{
613
+ type: ViewChild,
614
+ args: ['formField']
615
+ }], fakeInput: [{
616
+ type: ViewChild,
617
+ args: ['fakeInput']
618
+ }], inputDegrees: [{
619
+ type: ViewChild,
620
+ args: ['inputDegrees']
621
+ }], inputMinutes: [{
622
+ type: ViewChild,
623
+ args: ['inputMinutes']
624
+ }], inputSeconds: [{
625
+ type: ViewChild,
626
+ args: ['inputSeconds']
627
+ }], inputSign: [{
628
+ type: ViewChild,
629
+ args: ['inputSign']
630
+ }] } });
631
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwubGF0bG9uZzIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NoYXJlZC9tYXRlcmlhbC9sYXRsb25nL21hdGVyaWFsLmxhdGxvbmcyLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvbWF0ZXJpYWwvbGF0bG9uZy9tYXRlcmlhbC5sYXRsb25nMi5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsZUFBZSxFQUdmLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxXQUFXLEVBRVgsaUJBQWlCLEVBR2pCLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCw4QkFBOEIsR0FLL0IsTUFBTSw4QkFBOEIsQ0FBQztBQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSx1Q0FBdUMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hILE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsNkJBQTZCLEVBRzdCLHFCQUFxQixFQUNyQix1QkFBdUIsRUFDdkIseUJBQXlCLEdBQzFCLE1BQU0saUJBQWlC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c0JBQWhDLFNBQVM7dUJBQUMsV0FBVztnQkFDRSxTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVc7Z0JBQ0ssWUFBWTtzQkFBdEMsU0FBUzt1QkFBQyxjQUFjO2dCQUNFLFlBQVk7c0JBQXRDLFNBQVM7dUJBQUMsY0FBYztnQkFDRSxZQUFZO3NCQUF0QyxTQUFTO3VCQUFDLGNBQWM7Z0JBQ0QsU0FBUztzQkFBaEMsU0FBUzt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgbnVtYmVyQXR0cmlidXRlLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICBGb3JtQ29udHJvbCxcbiAgRm9ybUdyb3VwRGlyZWN0aXZlLFxuICBOR19WQUxVRV9BQ0NFU1NPUixcbiAgVW50eXBlZEZvcm1Db250cm9sLFxuICBWYWxpZGF0b3JGbixcbiAgVmFsaWRhdG9ycyxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9PUFRJT05TLFxuICBNYXRGb3JtRmllbGQsXG4gIE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UsXG4gIE1hdEZvcm1GaWVsZERlZmF1bHRPcHRpb25zLFxuICBTdWJzY3JpcHRTaXppbmcsXG59IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgbWVyZ2UsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQXBwRmxvYXRMYWJlbFR5cGUgfSBmcm9tICcuLi8uLi9mb3JtL2ZpZWxkLm1vZGVsJztcbmltcG9ydCB7IGlzTmlsLCBpc05pbE9yQmxhbmssIGlzTm90TmlsIH0gZnJvbSAnLi4vLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7IGlzTW9iaWxlIH0gZnJvbSAnLi4vLi4vcGxhdGZvcm1zJztcbmltcG9ydCB7IFNoYXJlZFZhbGlkYXRvcnMgfSBmcm9tICcuLi8uLi92YWxpZGF0b3IvdmFsaWRhdG9ycyc7XG5pbXBvcnQgeyBNQVRfRk9STV9GSUVMRF9ERUZBVUxUX0FQUEVBUkFOQ0UsIE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfU1VCU0NSSVBUX1NJWklORyB9IGZyb20gJy4uL21hdGVyaWFsLmNvbmZpZyc7XG5pbXBvcnQge1xuICBjb21wdXRlRGVjaW1hbERlZ3JlZXMsXG4gIExBVF9MT05HX0RFRkFVTFRfTUFYX0RFQ0lNQUxTLFxuICBMYXRMb25nUGF0dGVybixcbiAgTGF0TG9uZ1R5cGUsXG4gIHNwbGl0TnVtYmVyVG9GaWVsZHNERCxcbiAgc3BsaXROdW1iZXJUb0ZpZWxkc0RETU0sXG4gIHNwbGl0TnVtYmVyVG9GaWVsZHNERE1NU1MsXG59IGZyb20gJy4vbGF0bG9uZy51dGlscyc7XG5cbmNvbnN0IG5vb3AgPSAoKSA9PiB7fTtcblxuZGVjbGFyZSB0eXBlIExhdExvbmdTaWduID0gMSB8IC0xO1xuaW50ZXJmYWNlIElMYXRMb25nRGF0YSB7XG4gIGRlZ3JlZXM6IG51bWJlcjtcbiAgbWludXRlczogbnVtYmVyO1xuICBzZWNvbmRzOiBudW1iZXI7XG4gIHNpZ246IExhdExvbmdTaWduO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdtYXQtbGF0bG9uZy1maWVsZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tYXRlcmlhbC5sYXRsb25nMi5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbWF0ZXJpYWwubGF0bG9uZzIuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTWF0TGF0TG9uZ0ZpZWxkMiksXG4gICAgfSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE1hdExhdExvbmdGaWVsZDIgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICBwcml2YXRlIF9vbkNoYW5nZUNhbGxiYWNrOiAoXzogYW55KSA9PiB2b2lkID0gbm9vcDtcbiAgcHJpdmF0ZSBfb25Ub3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSBub29wO1xuICBwcml2YXRlIF9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgX2Rpc2FibGluZyA9IGZhbHNlO1xuICBwcml2YXRlIF93cml0aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgX2FwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0U2l6aW5nOiBTdWJzY3JpcHRTaXppbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfcmVhZG9ubHkgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfdGFiaW5kZXg6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVmYXVsdEFwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRTdWJzY3JpcHRTaXppbmc6IFN1YnNjcmlwdFNpemluZztcblxuICBwcm90ZWN0ZWQgX2ZvY3VzZWQgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIF90b3VjaGVkID0gZmFsc2U7XG4gIHByb3RlY3RlZCBkZWdyZWVzQ29udHJvbDogRm9ybUNvbnRyb2w8bnVtYmVyPjtcbiAgcHJvdGVjdGVkIG1pbnV0ZXNDb250cm9sOiBGb3JtQ29udHJvbDxudW1iZXI+O1xuICBwcm90ZWN0ZWQgc2Vjb25kc0NvbnRyb2w6IEZvcm1Db250cm9sPG51bWJlcj47XG4gIHByb3RlY3RlZCBzaWduQ29udHJvbDogRm9ybUNvbnRyb2w8TGF0TG9uZ1NpZ24+O1xuICBwcm90ZWN0ZWQgc2hvd01pbnV0ZXMgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHNob3dTZWNvbmRzID0gZmFsc2U7XG4gIHByb3RlY3RlZCBzaG93U2lnbkNvbnRyb2w6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBkZWdyZWVzUGxhY2Vob2xkZXI6IHN0cmluZztcbiAgcHJvdGVjdGVkIG1pbnV0ZXNQbGFjZWhvbGRlcjogc3RyaW5nO1xuICBwcm90ZWN0ZWQgc2Vjb25kc1BsYWNlaG9sZGVyOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBtYXhEZWNpbWFscyA9IExBVF9MT05HX0RFRkFVTFRfTUFYX0RFQ0lNQUxTO1xuICBwcm90ZWN0ZWQgaTE4bkVycm9yS2V5cyA9IFNoYXJlZFZhbGlkYXRvcnMuSTE4Tl9FUlJPUl9LRVlTO1xuICBwcm90ZWN0ZWQgbWluTWF4VmFsdWVzOiB7XG4gICAgZGVncmVlcz86IHsgbWluOiBudW1iZXI7IG1heDogbnVtYmVyOyBzdGVwOiBudW1iZXIgfTtcbiAgICBtaW51dGVzPzogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXI7IHN0ZXA6IG51bWJlciB9O1xuICAgIHNlY29uZHM/OiB7IG1pbjogbnVtYmVyOyBtYXg6IG51bWJlcjsgc3RlcDogbnVtYmVyIH07XG4gIH07XG4gIHByb3RlY3RlZCBpbnB1dFdpZHRoOiB7XG4gICAgZGVncmVlczogc3RyaW5nO1xuICAgIGRlZ3JlZXNVbml0OiBzdHJpbmc7XG4gICAgbWludXRlcz86IHN0cmluZztcbiAgICBtaW51dGVzVW5pdD86IHN0cmluZztcbiAgICBzZWNvbmRzPzogc3RyaW5nO1xuICAgIHNlY29uZHNVbml0Pzogc3RyaW5nO1xuICB9O1xuXG4gIEBJbnB1dCgpIGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gIEBJbnB1dCgpIGZvcm1Db250cm9sTmFtZTogc3RyaW5nO1xuICBASW5wdXQoKSB0eXBlOiBMYXRMb25nVHlwZTtcbiAgQElucHV0KCdsYXRMb25nUGF0dGVybicpIHBhdHRlcm46IExhdExvbmdQYXR0ZXJuO1xuICBASW5wdXQoKSByZXF1aXJlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBmbG9hdExhYmVsOiBBcHBGbG9hdExhYmVsVHlwZSA9ICdhdXRvJztcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZztcbiAgQElucHV0KCkgZGVmYXVsdFNpZ246ICctJyB8ICcrJztcbiAgQElucHV0KCkgYXV0b2ZvY3VzID0gZmFsc2U7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBtb2JpbGU6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGRlZ3JlZXNTeW1ib2xVbml0ID0gJ8KwJztcbiAgQElucHV0KCkgbWludXRlc1N5bWJvbFVuaXQgPSBcIidcIjtcbiAgQElucHV0KCkgc2Vjb25kc1N5bWJvbFVuaXQgPSAnXCInO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgY2xlYXJhYmxlID0gdHJ1ZTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZSB9KSBzZXQgdGFiaW5kZXgodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLl90YWJpbmRleCAhPT0gdmFsdWUpIHtcbiAgICAgIHRoaXMuX3RhYmluZGV4ID0gdmFsdWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMudXBkYXRlVGFiSW5kZXgoKSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHRhYmluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmluZGV4O1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IGFwcGVhcmFuY2UodmFsdWU6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UpIHtcbiAgICB0aGlzLl9hcHBlYXJhbmNlID0gdmFsdWU7XG4gIH1cbiAgZ2V0IGFwcGVhcmFuY2UoKTogTWF0Rm9ybUZpZWxkQXBwZWFyYW5jZSB7XG4gICAgcmV0dXJuIHRoaXMuX2FwcGVhcmFuY2UgfHwgdGhpcy5fZGVmYXVsdEFwcGVhcmFuY2U7XG4gIH1cblxuICBASW5wdXQoKSBzZXQgcmVhZG9ubHkodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9yZWFkb25seSA9IHZhbHVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgcmVhZG9ubHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRvbmx5O1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHN1YnNjcmlwdFNpemluZyh2YWx1ZTogU3Vic2NyaXB0U2l6aW5nKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0U2l6aW5nID0gdmFsdWU7XG4gIH1cbiAgZ2V0IHN1YnNjcmlwdFNpemluZygpOiBTdWJzY3JpcHRTaXppbmcge1xuICAgIHJldHVybiB0aGlzLl9zdWJzY3JpcHRTaXppbmcgfHwgdGhpcy5fZGVmYXVsdFN1YnNjcmlwdFNpemluZztcbiAgfVxuXG4gIGdldCBzaG93RmllbGRzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05vdE5pbCh0aGlzLmZvcm1Db250cm9sLnZhbHVlKSB8fCB0aGlzLl9mb2N1c2VkO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZG9ubHkgfHwgdGhpcy5mb3JtQ29udHJvbC5kaXNhYmxlZDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LW9uLXByZWZpeCxAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LXJlbmFtZVxuICBAT3V0cHV0KCdrZXl1cC5lbnRlcicpIGtleXVwRW50ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtcmVuYW1lXG4gIEBPdXRwdXQoJ2JsdXInKSBibHVycmVkID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1yZW5hbWVcbiAgQE91dHB1dCgnZm9jdXMnKSBmb2N1c2VkID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2Zvcm1GaWVsZCcpIGZvcm1GaWVsZDogTWF0Rm9ybUZpZWxkO1xuICBAVmlld0NoaWxkKCdmYWtlSW5wdXQnKSBmYWtlSW5wdXQ6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0RGVncmVlcycpIGlucHV0RGVncmVlczogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnaW5wdXRNaW51dGVzJykgaW5wdXRNaW51dGVzOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdpbnB1dFNlY29uZHMnKSBpbnB1dFNlY29uZHM6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0U2lnbicpIGlucHV0U2lnbjogRWxlbWVudFJlZjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGZvcm1Hcm91cERpcjogRm9ybUdyb3VwRGlyZWN0aXZlLFxuICAgIEBJbmplY3QoTUFUX0ZPUk1fRklFTERfREVGQVVMVF9PUFRJT05TKSBkZWZhdWx0T3B0aW9ucz86IE1hdEZvcm1GaWVsZERlZmF1bHRPcHRpb25zXG4gICkge1xuICAgIHRoaXMuX2RlZmF1bHRTdWJzY3JpcHRTaXppbmcgPSBkZWZhdWx0T3B0aW9ucz8uc3Vic2NyaXB0U2l6aW5nIHx8IE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfU1VCU0NSSVBUX1NJWklORztcbiAgICB0aGlzLl9kZWZhdWx0QXBwZWFyYW5jZSA9IGRlZmF1bHRPcHRpb25zPy5hcHBlYXJhbmNlIHx8IE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfQVBQRUFSQU5DRTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMubW9iaWxlID0gdGhpcy5tb2JpbGUgPz8gaXNNb2JpbGUod2luZG93KTtcbiAgICB0aGlzLnR5cGUgPSB0aGlzLnR5cGUgfHwgJ2xhdGl0dWRlJztcbiAgICB0aGlzLnBhdHRlcm4gPSB0aGlzLnBhdHRlcm4gfHwgJ0RETU0nO1xuICAgIHRoaXMuc2hvd1NpZ25Db250cm9sID0gdGhpcy5wYXR0ZXJuICE9PSAnREQnO1xuXG4gICAgY29uc3QgZGVncmVlc1ZhbGlkYXRvcnM6IFZhbGlkYXRvckZuW10gPSBbdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gU2hhcmVkVmFsaWRhdG9ycy5sYXRpdHVkZSA6IFNoYXJlZFZhbGlkYXRvcnMubG9uZ2l0dWRlXTtcbiAgICBjb25zdCBtaW51dGVzVmFsaWRhdG9yczogVmFsaWRhdG9yRm5bXSA9IFtdO1xuICAgIGNvbnN0IHNlY29uZHNWYWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gW107XG5cbiAgICB0aGlzLm1pbk1heFZhbHVlcyA9IHt9O1xuXG4gICAgc3dpdGNoICh0aGlzLnBhdHRlcm4pIHtcbiAgICAgIGNhc2UgJ0REJzpcbiAgICAgICAgdGhpcy5tYXhEZWNpbWFscyA9IDc7XG4gICAgICAgIGRlZ3JlZXNWYWxpZGF0b3JzLnB1c2goU2hhcmVkVmFsaWRhdG9ycy5kZWNpbWFsKHsgbWF4RGVjaW1hbHM6IHRoaXMubWF4RGVjaW1hbHMgfSkpO1xuICAgICAgICB0aGlzLmRlZ3JlZXNQbGFjZWhvbGRlciA9IHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/ICdDT01NT04uTEFUX0xPTkcuRERfUExBQ0VIT0xERVInIDogJ0NPTU1PTi5MQVRfTE9ORy5ERERfUExBQ0VIT0xERVInO1xuICAgICAgICB0aGlzLmlucHV0V2lkdGggPSB7XG4gICAgICAgICAgZGVncmVlczogJzk1JScsXG4gICAgICAgICAgZGVncmVlc1VuaXQ6ICc1JScsXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRERNTSc6XG4gICAgICAgIHRoaXMubWF4RGVjaW1hbHMgPSAzO1xuICAgICAgICB0aGlzLnNob3dNaW51dGVzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5taW5NYXhWYWx1ZXNbJ21pbnV0ZXMnXSA9IHtcbiAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgbWF4OiA2MCAtIHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KDEsIHRoaXMubWF4RGVjaW1hbHMpLFxuICAgICAgICAgIHN0ZXA6IHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KDEsIHRoaXMubWF4RGVjaW1hbHMpLFxuICAgICAgICB9O1xuICAgICAgICBkZWdyZWVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuaW50ZWdlcik7XG4gICAgICAgIG1pbnV0ZXNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW4odGhpcy5taW5NYXhWYWx1ZXMubWludXRlcy5taW4pKTtcbiAgICAgICAgbWludXRlc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1heCh0aGlzLm1pbk1heFZhbHVlcy5taW51dGVzLm1heCkpO1xuICAgICAgICBtaW51dGVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuZGVjaW1hbCh7IG1heERlY2ltYWxzOiB0aGlzLm1heERlY2ltYWxzIH0pKTtcbiAgICAgICAgdGhpcy5kZWdyZWVzUGxhY2Vob2xkZXIgPSB0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkREJyA6ICdDT01NT04uTEFUX0xPTkcuU0lOR0xFX0ZJRUxEX1BBVFRFUk4uREREJztcbiAgICAgICAgdGhpcy5taW51dGVzUGxhY2Vob2xkZXIgPSAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLk1NX01NTSc7XG4gICAgICAgIHRoaXMuaW5wdXRXaWR0aCA9IHtcbiAgICAgICAgICBkZWdyZWVzOiAnMzUlJyxcbiAgICAgICAgICBkZWdyZWVzVW5pdDogJzUlJyxcbiAgICAgICAgICBtaW51dGVzOiAnNTUlJyxcbiAgICAgICAgICBtaW51dGVzVW5pdDogJzUlJyxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiAvLyBEZWZhdWx0IGlzIERETU1TU1xuICAgICAgICB0aGlzLm1heERlY2ltYWxzID0gMjtcbiAgICAgICAgdGhpcy5zaG93TWludXRlcyA9IHRydWU7XG4gICAgICAgIHRoaXMuc2hvd1NlY29uZHMgPSB0cnVlO1xuICAgICAgICB0aGlzLm1pbk1heFZhbHVlc1snbWludXRlcyddID0ge1xuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBtYXg6IDU5LFxuICAgICAgICAgIHN0ZXA6IDEsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMubWluTWF4VmFsdWVzWydzZWNvbmRzJ10gPSB7XG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogNjAgLSB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydCgxLCB0aGlzLm1heERlY2ltYWxzKSxcbiAgICAgICAgICBzdGVwOiB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydCgxLCB0aGlzLm1heERlY2ltYWxzKSxcbiAgICAgICAgfTtcbiAgICAgICAgZGVncmVlc1ZhbGlkYXRvcnMucHVzaChTaGFyZWRWYWxpZGF0b3JzLmludGVnZXIpO1xuICAgICAgICBtaW51dGVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuaW50ZWdlcik7XG4gICAgICAgIG1pbnV0ZXNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW4odGhpcy5taW5NYXhWYWx1ZXMubWludXRlcy5taW4pKTtcbiAgICAgICAgbWludXRlc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1heCh0aGlzLm1pbk1heFZhbHVlcy5taW51dGVzLm1heCkpO1xuICAgICAgICBzZWNvbmRzVmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWluKHRoaXMubWluTWF4VmFsdWVzLnNlY29uZHMubWluKSk7XG4gICAgICAgIHNlY29uZHNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5tYXgodGhpcy5taW5NYXhWYWx1ZXMuc2Vjb25kcy5tYXgpKTtcbiAgICAgICAgc2Vjb25kc1ZhbGlkYXRvcnMucHVzaChTaGFyZWRWYWxpZGF0b3JzLmRlY2ltYWwoeyBtYXhEZWNpbWFsczogdGhpcy5tYXhEZWNpbWFscyB9KSk7XG4gICAgICAgIHRoaXMuZGVncmVlc1BsYWNlaG9sZGVyID0gdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5ERCcgOiAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkRERCc7XG4gICAgICAgIHRoaXMubWludXRlc1BsYWNlaG9sZGVyID0gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5NTSc7XG4gICAgICAgIHRoaXMuc2Vjb25kc1BsYWNlaG9sZGVyID0gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5TU19TUyc7XG4gICAgICAgIHRoaXMuaW5wdXRXaWR0aCA9IHtcbiAgICAgICAgICBkZWdyZWVzOiAnMjUlJyxcbiAgICAgICAgICBkZWdyZWVzVW5pdDogJzUlJyxcbiAgICAgICAgICBtaW51dGVzOiAnMjUlJyxcbiAgICAgICAgICBtaW51dGVzVW5pdDogJzUlJyxcbiAgICAgICAgICBzZWNvbmRzOiAnMzUlJyxcbiAgICAgICAgICBzZWNvbmRzVW5pdDogJzUlJyxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gTXVzdCBiZSBkb25lIGFmdGVyIHNldCB0aGlzLm1heERlY2ltYWxzIGluIHN3aXRjaCBibG9jayBhYm92ZVxuICAgIHRoaXMubWluTWF4VmFsdWVzWydkZWdyZWVzJ10gPSB7XG4gICAgICBtaW46IHRoaXMucGF0dGVybiA9PT0gJ0REJyA/ICh0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyAtOTAgOiAtMTgwKSA6IDAsXG4gICAgICBtYXg6IHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/IDkwIDogMTgwLFxuICAgICAgc3RlcDogdGhpcy5wYXR0ZXJuID09PSAnREQnID8gdGhpcy5jb21wdXRlRGVjaW1hbFBhcnQoMSwgdGhpcy5tYXhEZWNpbWFscykgOiAxLFxuICAgIH07XG5cbiAgICB0aGlzLmZvcm1Db250cm9sID1cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wgfHwgKHRoaXMuZm9ybUNvbnRyb2xOYW1lICYmIHRoaXMuZm9ybUdyb3VwRGlyICYmICh0aGlzLmZvcm1Hcm91cERpci5mb3JtLmdldCh0aGlzLmZvcm1Db250cm9sTmFtZSkgYXMgVW50eXBlZEZvcm1Db250cm9sKSk7XG4gICAgaWYgKCF0aGlzLmZvcm1Db250cm9sKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG1hbmRhdG9yeSBhdHRyaWJ1dGUgJ2Zvcm1Db250cm9sJyBvciAnZm9ybUNvbnRyb2xOYW1lJyBpbiA8bWF0LWxhdGxvbmctZmllbGQ+LlwiKTtcblxuICAgIHRoaXMuZGVncmVlc0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPihudWxsLCBkZWdyZWVzVmFsaWRhdG9ycyk7XG4gICAgdGhpcy5taW51dGVzQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxudW1iZXI+KG51bGwsIG1pbnV0ZXNWYWxpZGF0b3JzKTtcbiAgICB0aGlzLnNlY29uZHNDb250cm9sID0gbmV3IEZvcm1Db250cm9sPG51bWJlcj4obnVsbCwgc2Vjb25kc1ZhbGlkYXRvcnMpO1xuICAgIHRoaXMuc2lnbkNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2w8TGF0TG9uZ1NpZ24+KG51bGwpO1xuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIG1lcmdlKFxuICAgICAgICB0aGlzLmRlZ3JlZXNDb250cm9sLnZhbHVlQ2hhbmdlcyxcbiAgICAgICAgdGhpcy5taW51dGVzQ29udHJvbC52YWx1ZUNoYW5nZXMsXG4gICAgICAgIHRoaXMuc2Vjb25kc0NvbnRyb2wudmFsdWVDaGFuZ2VzLFxuICAgICAgICB0aGlzLnNpZ25Db250cm9sLnZhbHVlQ2hhbmdlc1xuICAgICAgKS5zdWJzY3JpYmUoKF8pID0+IHRoaXMub25Gb3JtQ2hhbmdlKCkpXG4gICAgKTtcblxuICAgIC8vIExpc3RlbiBzdGF0dXMgY2hhbmdlcyAod2hlbiBkb25lIG91dHNpZGUgdGhlIGNvbXBvbmVudCAgLSBlLmcuIHdoZW4gc2V0RXJyb3JzKCkgaXMgY2FsbGluZyBvbiB0aGUgZm9ybUNvbnRyb2wpXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc3RhdHVzQ2hhbmdlc1xuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKCkgPT4gIXRoaXMucmVhZG9ubHkgJiYgIXRoaXMuX3dyaXRpbmcgJiYgIXRoaXMuX2Rpc2FibGluZykgLy8gU2tpcFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5tYXJrRm9yQ2hlY2soKSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IG51bWJlciB8IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLl93cml0aW5nKSByZXR1cm47XG4gICAgdGhpcy5fd3JpdGluZyA9IHRydWU7XG5cbiAgICBpZiAodmFsdWUgIT09IHRoaXMuZm9ybUNvbnRyb2wudmFsdWUpIHtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgdGhpcy5fb25DaGFuZ2VDYWxsYmFjayh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb21wdXRlTGF0TG9uZ0Zvcm1Hcm91cFZhbHVlKHZhbHVlKTtcbiAgICBjb25zb2xlLmRlYnVnKCdbbWF0LWxhdGxvbmctZmllbGRdIENoYW5naW5nIHZhbHVlIG9mIGlucHV0czonLCB2YWx1ZSwgcmVzdWx0KTtcbiAgICB0aGlzLnBhdGNoVmFsdWUocmVzdWx0LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICB0aGlzLl93cml0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVGYWtlSW5wdXQoKTtcbiAgICAgIHRoaXMudXBkYXRlVGFiSW5kZXgoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLl9kaXNhYmxpbmcpIHJldHVybjtcblxuICAgIHRoaXMuX2Rpc2FibGluZyA9IHRydWU7XG4gICAgaWYgKGlzRGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuZGVncmVlc0NvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgdGhpcy5taW51dGVzQ29udHJvbC5kaXNhYmxlKCk7XG4gICAgICB0aGlzLnNlY29uZHNDb250cm9sLmRpc2FibGUoKTtcbiAgICAgIHRoaXMuc2lnbkNvbnRyb2wuZGlzYWJsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlZ3JlZXNDb250cm9sLmVuYWJsZSgpO1xuICAgICAgdGhpcy5taW51dGVzQ29udHJvbC5lbmFibGUoKTtcbiAgICAgIHRoaXMuc2Vjb25kc0NvbnRyb2wuZW5hYmxlKCk7XG4gICAgICB0aGlzLnNpZ25Db250cm9sLmVuYWJsZSgpO1xuICAgIH1cbiAgICB0aGlzLl9kaXNhYmxpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgY2xlYXJWYWx1ZShldmVudD86IEV2ZW50KSB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMud3JpdGVWYWx1ZShudWxsKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgaW5wdXRzRWxlbWVudHMoKTogSFRNTEVsZW1lbnRbXSB7XG4gICAgcmV0dXJuICh0aGlzLmlucHV0RGVncmVlcyA/IFt0aGlzLmlucHV0RGVncmVlcy5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmlucHV0TWludXRlcyA/IFt0aGlzLmlucHV0TWludXRlcy5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmlucHV0U2Vjb25kcyA/IFt0aGlzLmlucHV0U2Vjb25kcy5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmlucHV0U2lnbiA/IFt0aGlzLmlucHV0U2lnbi5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmZha2VJbnB1dCA/IFt0aGlzLmZha2VJbnB1dC5uYXRpdmVFbGVtZW50XSA6IFtdKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkZvY3VzRmFrZUlucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgaWYgKCF0aGlzLnNob3dGaWVsZHMpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIC8vIEhpZGUgdGhlIGZha2UgaW5wdXRcbiAgICAgIHRoaXMuZmFrZUlucHV0Py5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Nkay12aXN1YWxseS1oaWRkZW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl90b3VjaGVkID0gdGhpcy5mb3JtQ29udHJvbC50b3VjaGVkO1xuXG4gICAgLy8gRm9jdXMgb24gZmlyc3QgaW5wdXRcbiAgICB0aGlzLmZvY3VzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25CbHVyRmFrZUlucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW5wdXRzRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoaW50ZXJuYWxFdmVudCAmJiAhdGhpcy5fdG91Y2hlZCkge1xuICAgICAgLy8gV29ya2Fyb3VuZCB0byByZW1vdmUgdG91Y2hlZCBvbiB0aGUgZmFrZUlucHV0XG4gICAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc1VudG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfb25Gb2N1c0lucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW5wdXRzRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoIWludGVybmFsRXZlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXMoZmFsc2UgLypmb2N1c09uRGVncmVlcyovKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQmx1cklucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW5wdXRzRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoIWludGVybmFsRXZlbnQpIHtcbiAgICAgIHRoaXMuX2ZvY3VzZWQgPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLmFwcGVhcmFuY2UgPT0gJ2ZpbGwnKSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmRlYWN0aXZhdGUoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5ibHVycmVkLmVtaXQoZXZlbnQpO1xuXG4gICAgICB0aGlzLnVwZGF0ZUZha2VJbnB1dCgpO1xuICAgICAgdGhpcy51cGRhdGVUYWJJbmRleCgpO1xuXG4gICAgICB0aGlzLl90b3VjaGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgdGhpcy5fY2hlY2tJZlRvdWNoZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQ2xpY2tJbnB1dChldmVudDogRXZlbnQpIHtcbiAgICAvLyBBdm9pZCBtYXQtZm9ybS1maWVsZCB0byBnaXZlIGZvY3VzIHRvIGZha2UgaW5wdXRcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIGZvY3VzKGZvY3VzT25EZWdyZWVzPzogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLl9mb2N1c2VkKSByZXR1cm4gdHJ1ZTsgLy8gQWxyZWFkeSBmb2N1c2VkXG4gICAgY29uc3Qgc2hvd0ZpZWxkcyA9IHRoaXMuc2hvd0ZpZWxkcztcbiAgICB0aGlzLl9mb2N1c2VkID0gdHJ1ZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoIXNob3dGaWVsZHMgJiYgZm9jdXNPbkRlZ3JlZXMgIT09IGZhbHNlKSB0aGlzLmlucHV0RGVncmVlcy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG5cbiAgICAgIGlmICh0aGlzLmFwcGVhcmFuY2UgPT0gJ2ZpbGwnKSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmFjdGl2YXRlKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBhIGJsdXIgbGlzdGVuZXIgb24gZWFjaCBpbnB1dHNcbiAgICAgIC8qY29uc3QgaW5wdXRFbGVtZW50czogSFRNTEVsZW1lbnRbXSA9IHRoaXMuaW5wdXRzRWxlbWVudHM7XG4gICAgICBpbnB1dEVsZW1lbnRzLmZpbHRlcihpc05vdE5pbCkuZm9yRWFjaChcbiAgICAgICAgKGVsKSA9PlxuICAgICAgICAgIChlbC5vbmJsdXIgPSAoZSkgPT4ge1xuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdvbmJsdXIgdG8gZWxlbWVudD0nLCBlLnJlbGF0ZWRUYXJnZXQpO1xuXG4gICAgICAgICAgICAvLyBTZXR1cCBhIG9uZS10aW1lIGZvY3VzIGV2ZW50IGhhbmRsZXJcbiAgICAgICAgICAgIGNvbnN0IGZvY3VzTGlzdGVuZXIgPSAoZm9jdXNFdmVudDogRm9jdXNFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyIGFmdGVyIGl0IGhhcyBiZWVuIGV4ZWN1dGVkIG9uY2VcbiAgICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgZm9jdXNMaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdORXh0IGZvY3VzIGVsZW1lbnQ9JywgZm9jdXNFdmVudC50YXJnZXQpO1xuICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbEV2ZW50ID0gaW5wdXRFbGVtZW50cy5pbmNsdWRlcyhmb2N1c0V2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgaWYgKCFpbnRlcm5hbEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRmFrZUlucHV0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVUYWJJbmRleCgpO1xuICAgICAgICAgICAgICAgIC8vdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2soKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmRlYWN0aXZhdGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmJsdXJyZWQuZW1pdChmb2N1c0V2ZW50KTtcblxuICAgICAgICAgICAgICAgIC8vIHRoaXMuX3RvdWNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIC8vIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVW50b3VjaGVkKCk7XG4gICAgICAgICAgICAgICAgLy8gdGhpcy5fY2hlY2tJZlRvdWNoZWQoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIGZvY3VzTGlzdGVuZXIsIHRydWUpO1xuICAgICAgICAgIH0pXG4gICAgICApOyovXG5cbiAgICAgIHRoaXMudXBkYXRlRmFrZUlucHV0KCk7XG4gICAgICB0aGlzLnVwZGF0ZVRhYkluZGV4KCk7XG4gICAgfSwgMjUwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBmb3JtYXQocmF3VmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgdmFsdWVzID0gdGhpcy5jb21wdXRlTGF0TG9uZ0Zvcm1Hcm91cFZhbHVlKHJhd1ZhbHVlKTtcbiAgICBpZiAodmFsdWVzLmRlZ3JlZXMgPT09IG51bGwpIHJldHVybiAnJztcbiAgICBsZXQgcmVzdWx0ID0gYCR7dmFsdWVzLmRlZ3JlZXN9wrAgYDtcbiAgICBpZiAodmFsdWVzLm1pbnV0ZXMgIT09IG51bGwpIHJlc3VsdCArPSBgJHt2YWx1ZXMubWludXRlc30nIGA7XG4gICAgaWYgKHZhbHVlcy5zZWNvbmRzICE9PSBudWxsKSByZXN1bHQgKz0gYCR7dmFsdWVzLnNlY29uZHN9XCIgYDtcbiAgICBpZiAodGhpcy50eXBlID09PSAnbGF0aXR1ZGUnKSB7XG4gICAgICByZXN1bHQgKz0gdmFsdWVzLnNpZ24gPT09IDEgPyAnTicgOiAnUyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSB2YWx1ZXMuc2lnbiA9PT0gMSA/ICdFJyA6ICdXJztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb21wdXRlRGVjaW1hbFBhcnQodmFsdWU6IG51bWJlciwgbmJPZkRlY2ltYWxzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB2YWx1ZSAqIDEwICoqIChuYk9mRGVjaW1hbHMgKiAtMSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tcHV0ZUxhdExvbmdGb3JtR3JvdXBWYWx1ZShyYXdWYWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogSUxhdExvbmdEYXRhIHtcbiAgICBjb25zdCBpc0xvbmdpdHVkZSA9IHRoaXMudHlwZSA9PT0gJ2xvbmdpdHVkZSc7XG5cbiAgICBjb25zdCB2YWx1ZSA9IHR5cGVvZiByYXdWYWx1ZSA9PT0gJ3N0cmluZycgPyBwYXJzZUZsb2F0KHJhd1ZhbHVlLnJlcGxhY2UoLywvZywgJy4nKSkgOiByYXdWYWx1ZTtcbiAgICBjb25zdCByZXN1bHQ6IElMYXRMb25nRGF0YSA9IHtcbiAgICAgIGRlZ3JlZXM6IG51bGwsXG4gICAgICBtaW51dGVzOiBudWxsLFxuICAgICAgc2Vjb25kczogbnVsbCxcbiAgICAgIHNpZ246IGlzTm90TmlsKHZhbHVlKVxuICAgICAgICA/IHZhbHVlIDwgMFxuICAgICAgICAgID8gLTFcbiAgICAgICAgICA6IDFcbiAgICAgICAgOiAvLyBVc2UgZGVmYXVsdCBzaWduLCBpZiBhbnlcbiAgICAgICAgICB0aGlzLmRlZmF1bHRTaWduICYmIHRoaXMuZGVmYXVsdFNpZ24gPT09ICctJ1xuICAgICAgICAgID8gLTFcbiAgICAgICAgICA6IDEsXG4gICAgfTtcblxuICAgIGlmICh2YWx1ZSA9PT0gMCkge1xuICAgICAgcmVzdWx0LmRlZ3JlZXMgPSAwO1xuICAgIH0gZWxzZSBpZiAoaXNOb3ROaWwodmFsdWUpKSB7XG4gICAgICBpZiAodGhpcy5wYXR0ZXJuID09PSAnREQnKSB7XG4gICAgICAgIGNvbnN0IHNwbGl0VmFsdWUgPSBzcGxpdE51bWJlclRvRmllbGRzREQodmFsdWUsIHtcbiAgICAgICAgICBsb25naXR1ZGU6IGlzTG9uZ2l0dWRlLFxuICAgICAgICAgIHBhdHRlcm46IHRoaXMucGF0dGVybixcbiAgICAgICAgICBtYXhEZWNpbWFsczogdGhpcy5tYXhEZWNpbWFscyxcbiAgICAgICAgICBmaXhMYXRMb25nOiB0cnVlLFxuICAgICAgICB9KS5zbGljZSgxKSBhcyBudW1iZXJbXTsgLy8gcmVtb3ZlIHNpZ247XG4gICAgICAgIHJlc3VsdC5kZWdyZWVzID0gKHNwbGl0VmFsdWVbMF0gKyB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydChzcGxpdFZhbHVlWzFdID8/IDAsIHRoaXMubWF4RGVjaW1hbHMpKSAqIChyZXN1bHQuc2lnbiB8fCAxKSB8fCBudWxsO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBhdHRlcm4gPT09ICdERE1NJykge1xuICAgICAgICBjb25zdCBzcGxpdFZhbHVlID0gc3BsaXROdW1iZXJUb0ZpZWxkc0RETU0odmFsdWUsIHtcbiAgICAgICAgICBsb25naXR1ZGU6IGlzTG9uZ2l0dWRlLFxuICAgICAgICAgIHBhdHRlcm46IHRoaXMucGF0dGVybixcbiAgICAgICAgICBtYXhEZWNpbWFsczogdGhpcy5tYXhEZWNpbWFscyxcbiAgICAgICAgICBmaXhMYXRMb25nOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0WydtaW51dGVzJ10gPSBNYXRoLmFicygoc3BsaXRWYWx1ZVsxXSA/PyAwKSArIHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KHNwbGl0VmFsdWVbMl0gPz8gMCwgdGhpcy5tYXhEZWNpbWFscykpIHx8IG51bGw7XG4gICAgICAgIHJlc3VsdFsnZGVncmVlcyddID0gTWF0aC5hYnMoIXJlc3VsdFsnbWludXRlcyddICYmIGlzTmlsT3JCbGFuayhzcGxpdFZhbHVlWzBdKSA/IG51bGwgOiAoc3BsaXRWYWx1ZVswXSA/PyAwKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEZWZhdWx0IC8vIERETU1TU1xuICAgICAgICBjb25zdCBzcGxpdFZhbHVlID0gc3BsaXROdW1iZXJUb0ZpZWxkc0RETU1TUyh2YWx1ZSwge1xuICAgICAgICAgIGxvbmdpdHVkZTogaXNMb25naXR1ZGUsXG4gICAgICAgICAgcGF0dGVybjogdGhpcy5wYXR0ZXJuLFxuICAgICAgICAgIG1heERlY2ltYWxzOiB0aGlzLm1heERlY2ltYWxzLFxuICAgICAgICAgIGZpeExhdExvbmc6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHRbJ3NlY29uZHMnXSA9IE1hdGguYWJzKChzcGxpdFZhbHVlWzJdID8/IDApICsgdGhpcy5jb21wdXRlRGVjaW1hbFBhcnQoc3BsaXRWYWx1ZVszXSA/PyAwLCB0aGlzLm1heERlY2ltYWxzKSkgfHwgbnVsbDtcbiAgICAgICAgcmVzdWx0WydtaW51dGVzJ10gPSAhcmVzdWx0WydzZWNvbmRzJ10gJiYgIXNwbGl0VmFsdWVbMV0gPyBudWxsIDogTWF0aC5hYnMoc3BsaXRWYWx1ZVsxXSA/PyAwKTtcbiAgICAgICAgcmVzdWx0WydkZWdyZWVzJ10gPSAhcmVzdWx0WydzZWNvbmRzJ10gJiYgIXJlc3VsdFsnbWludXRlcyddICYmIGlzTmlsT3JCbGFuayhzcGxpdFZhbHVlWzBdKSA/IG51bGwgOiBNYXRoLmFicyhzcGxpdFZhbHVlWzBdID8/IDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0FzVG91Y2hlZCgpIHtcbiAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLmRlZ3JlZXNDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLm1pbnV0ZXNDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLnNlY29uZHNDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLnNpZ25Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLl9vblRvdWNoZWRDYWxsYmFjaygpO1xuICB9XG5cbiAgLyogLS0gcHJpdmF0ZSBtZXRob2QgLS0gKi9cblxuICBwcml2YXRlIHBhdGNoVmFsdWUodmFsdWVzOiBJTGF0TG9uZ0RhdGEsIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuZGVncmVlc0NvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZXMuZGVncmVlcywgb3B0cyk7XG4gICAgdGhpcy5taW51dGVzQ29udHJvbC5wYXRjaFZhbHVlKHZhbHVlcy5taW51dGVzLCBvcHRzKTtcbiAgICB0aGlzLnNlY29uZHNDb250cm9sLnBhdGNoVmFsdWUodmFsdWVzLnNlY29uZHMsIG9wdHMpO1xuICAgIHRoaXMuc2lnbkNvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZXMuc2lnbiwgb3B0cyk7XG4gIH1cblxuICBwcml2YXRlIG9uRm9ybUNoYW5nZSgpIHtcbiAgICBpZiAodGhpcy5fd3JpdGluZykgcmV0dXJuOyAvLyBTa2lwIGlmIGNhbGwgYnkgc2VsZlxuICAgIHRoaXMuX3dyaXRpbmcgPSB0cnVlO1xuXG4gICAgLy8gREVCVUdcbiAgICBjb25zb2xlLmRlYnVnKCdbbWF0LWxhdGxvbmctZmllbGRdIG9uRm9ybUNoYW5nZSAnKTtcblxuICAgIGNvbnN0IGRlZ3JlZXMgPSB0aGlzLmRlZ3JlZXNDb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSB0aGlzLm1pbnV0ZXNDb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnNlY29uZHNDb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IHNpZ24gPSB0aGlzLnNpZ25Db250cm9sLnZhbHVlO1xuXG4gICAgY29uc3QgaW5jb21wbGV0ZVZhbHVlID0gaXNOaWwoZGVncmVlcykgJiYgKGlzTm90TmlsKG1pbnV0ZXMpIHx8IGlzTm90TmlsKHNlY29uZHMpKTtcbiAgICBjb25zdCBpbnZhbGlkID1cbiAgICAgIGluY29tcGxldGVWYWx1ZSB8fCB0aGlzLmRlZ3JlZXNDb250cm9sLmludmFsaWQgfHwgdGhpcy5taW51dGVzQ29udHJvbC5pbnZhbGlkIHx8IHRoaXMuc2Vjb25kc0NvbnRyb2wuaW52YWxpZCB8fCB0aGlzLnNpZ25Db250cm9sLmludmFsaWQ7XG4gICAgaWYgKGludmFsaWQpIHtcbiAgICAgIC8vIERFQlVHXG4gICAgICBjb25zb2xlLmRlYnVnKGBbbWF0LWxhdGxvbmctZmllbGRdIG9uRm9ybUNoYW5nZSgpIGVycm9yIC0+IGluY29tcGxldGVWYWx1ZTogJHtpbmNvbXBsZXRlVmFsdWV9YCk7XG5cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzUGVuZGluZyh7IG9ubHlTZWxmOiB0cnVlIH0pO1xuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRFcnJvcnMoe1xuICAgICAgICBpbnZhbGlkOiBpbmNvbXBsZXRlVmFsdWUsXG4gICAgICAgIC4uLnRoaXMuZGVncmVlc0NvbnRyb2wuZXJyb3JzLFxuICAgICAgICAuLi50aGlzLm1pbnV0ZXNDb250cm9sLmVycm9ycyxcbiAgICAgICAgLi4udGhpcy5zZWNvbmRzQ29udHJvbC5lcnJvcnMsXG4gICAgICAgIC4uLnRoaXMuc2lnbkNvbnRyb2wuZXJyb3JzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0aGlzLmRlZ3JlZXNDb250cm9sLmRpcnR5IHx8IHRoaXMubWludXRlc0NvbnRyb2wuZGlydHkgfHwgdGhpcy5zZWNvbmRzQ29udHJvbC5kaXJ0eSB8fCB0aGlzLnNpZ25Db250cm9sLmRpcnR5KSB7XG4gICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENvbXB1dGUgZGVjaW1hbCB2YWx1ZXNcbiAgICBjb25zdCB2YWx1ZSA9IGlzTmlsKGRlZ3JlZXMpIHx8IHRoaXMucGF0dGVybiA9PT0gJ0REJyA/IGRlZ3JlZXMgOiBjb21wdXRlRGVjaW1hbERlZ3JlZXMoZGVncmVlcywgbWludXRlcywgc2Vjb25kcywgc2lnbiwgdGhpcy5tYXhEZWNpbWFscyk7XG5cbiAgICAvLyBTZXQgbW9kZWwgdmFsdWVcbiAgICB0aGlzLmVtaXRDaGFuZ2UodmFsdWUpO1xuXG4gICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDaGFuZ2UodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmZvcm1Db250cm9sLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgLy8gREVCVUdcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1ttYXQtbGF0bG9uZy1maWVsZF0gRW1pdCBuZXcgdmFsdWU6ICcgKyB2YWx1ZSk7XG5cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc2V0VmFsdWUodmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgICAgLy8gQ2hhbmdlcyBjb21lcyBmcm9tIGluc2lkZSBmdW5jdGlvbjogdXNlIHRoZSBjYWxsYmFja1xuICAgICAgdGhpcy5fb25DaGFuZ2VDYWxsYmFjayh2YWx1ZSk7XG5cbiAgICAgIC8vIENoZWNrIGlmIG5lZWQgdG8gdXBkYXRlIGNvbnRyb2xzXG4gICAgICB0aGlzLl9jaGVja0lmVG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NoZWNrSWZUb3VjaGVkKCkge1xuICAgIGlmICh0aGlzLmZvcm1Db250cm9sLnRvdWNoZWQpIHtcbiAgICAgIHRoaXMuX29uVG91Y2hlZENhbGxiYWNrKCk7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgdGhpcy5fdG91Y2hlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RvdWNoZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3cvSGlkZSB0aGUgZmFrZSBpbnB1dFxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVGYWtlSW5wdXQoKSB7XG4gICAgaWYgKHRoaXMuc2hvd0ZpZWxkcykge1xuICAgICAgdGhpcy5mYWtlSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnY2RrLXZpc3VhbGx5LWhpZGRlbicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZha2VJbnB1dD8ubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdjZGstdmlzdWFsbHktaGlkZGVuJyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogY2hlY2sgaWYgbmVlZFxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSwgYmVjYXVzZSwgdGhpcyBjb21wb25lbnQgaGFzIGEgdGVtcG9yYXJ5IGNvbXBvbmVudCBkaXNwbGF5ZWQgYmVmb3JlIHRoZSBmaXJzdCBmb2N1cyBldmVudFxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVUYWJJbmRleCgpIHtcbiAgICBpZiAoaXNOaWwodGhpcy5fdGFiaW5kZXgpKSByZXR1cm47XG5cbiAgICBpZiAodGhpcy5mYWtlSW5wdXQpIHtcbiAgICAgIHRoaXMuZmFrZUlucHV0Lm5hdGl2ZUVsZW1lbnQudGFiSW5kZXggPSB0aGlzLl90YWJpbmRleDtcbiAgICB9XG5cbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8IS0tIHJlYWRvbmx5IC0tPlxuQGlmIChyZWFkb25seSkge1xuICA8bWF0LWZvcm0tZmllbGRcbiAgICBbZmxvYXRMYWJlbF09XCJmbG9hdExhYmVsIHwgYXNGbG9hdExhYmVsVHlwZVwiXG4gICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgW3N1YnNjcmlwdFNpemluZ109XCJzdWJzY3JpcHRTaXppbmdcIlxuICAgIGNsYXNzPVwibWF0LWZvcm0tZmllbGQtZGlzYWJsZWRcIlxuICA+XG4gICAgPGRpdiBtYXRQcmVmaXg+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0UHJlZml4VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIEBpZiAoZmxvYXRMYWJlbCAhPT0gJ25ldmVyJyAmJiAhIXBsYWNlaG9sZGVyKSB7XG4gICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyIH19PC9tYXQtbGFiZWw+XG4gICAgfVxuXG4gICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiB0eXBlPVwidGV4dFwiIHJlYWRvbmx5IFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFwiIC8+XG4gICAgPGlvbi10ZXh0PlxuICAgICAge3tcbiAgICAgICAgZm9ybUNvbnRyb2wudmFsdWVcbiAgICAgICAgICB8IGxhdExvbmdGb3JtYXQ6IHsgcGF0dGVybjogcGF0dGVybiwgbWF4RGVjaW1hbHM6IG1heERlY2ltYWxzLCB0eXBlOiB0eXBlLCBwbGFjZWhvbGRlckNoYXI6ICcnIH1cbiAgICAgIH19XG4gICAgPC9pb24tdGV4dD5cblxuICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIGhpbnRzIC0tPlxuICAgIDxtYXQtaGludCBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCJmb3JtQ29udHJvbC5pbnZhbGlkXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0SGludFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9tYXQtaGludD5cbiAgPC9tYXQtZm9ybS1maWVsZD5cbn0gQGVsc2Uge1xuICA8IS0tIHdyaXRhYmxlIC0tPlxuICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZyB7eyBhcHBlYXJhbmNlIH19XCI+XG4gICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZyBuby13cmFwXCI+XG4gICAgICA8IS0tIGRlZ3JlZXMgLS0+XG4gICAgICA8aW9uLWNvbCBjbGFzcz1cImRlZ3JlZXMgaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgI2Zvcm1GaWVsZFxuICAgICAgICAgIFtmbG9hdExhYmVsXT1cIlxuICAgICAgICAgICAgc2hvd0ZpZWxkcyAmJiAoIWZsb2F0TGFiZWwgfHwgZmxvYXRMYWJlbCA9PT0gJ2F1dG8nKSA/ICdhbHdheXMnIDogKGZsb2F0TGFiZWwgfCBhc0Zsb2F0TGFiZWxUeXBlKVxuICAgICAgICAgIFwiXG4gICAgICAgICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgIFtjbGFzcy5tZGMtdGV4dC1maWVsZC0taW52YWxpZF09XCJmb3JtQ29udHJvbC50b3VjaGVkICYmIChzaWduQ29udHJvbC5pbnZhbGlkIHx8IGZvcm1Db250cm9sLmludmFsaWQpXCJcbiAgICAgICAgICBjbGFzcz1cInZhbHVlc1wiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IG1hdFByZWZpeD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRQcmVmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgQGlmIChmbG9hdExhYmVsICE9PSAnbmV2ZXInICYmIHBsYWNlaG9sZGVyIHwgaXNOb3ROaWxPckJsYW5rKSB7XG4gICAgICAgICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgI2Zha2VJbnB1dFxuICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgcmVhZG9ubHk9XCJ0cnVlXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFwiXG4gICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICAgW2FwcEF1dG9mb2N1c109XCIhc2hvd0ZpZWxkcyAmJiBhdXRvZm9jdXNcIlxuICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cInNob3dGaWVsZHNcIlxuICAgICAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXNGYWtlSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAoYmx1cik9XCJvbkJsdXJGYWtlSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgLz5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAjaW5wdXREZWdyZWVzXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwic2hvd0ZpZWxkcyA/IGlucHV0V2lkdGguZGVncmVlcyA6ICcxMDAlJ1wiXG4gICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZGVncmVlc1BsYWNlaG9sZGVyIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJkZWdyZWVzQ29udHJvbFwiXG4gICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgIFthcHBBdXRvZm9jdXNdPVwic2hvd0ZpZWxkcyAmJiBhdXRvZm9jdXNcIlxuICAgICAgICAgICAgW21pbl09XCJtaW5NYXhWYWx1ZXMuZGVncmVlcy5taW5cIlxuICAgICAgICAgICAgW21heF09XCJtaW5NYXhWYWx1ZXMuZGVncmVlcy5tYXhcIlxuICAgICAgICAgICAgW3N0ZXBdPVwibWluTWF4VmFsdWVzLmRlZ3JlZXMuc3RlcFwiXG4gICAgICAgICAgICAoZm9jdXMpPVwiX29uRm9jdXNJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChibHVyKT1cIl9vbkJsdXJJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChjbGljayk9XCJfb25DbGlja0lucHV0KCRldmVudClcIlxuICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIGNsYXNzPVwic3ltYm9sLXVuaXRcIlxuICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cInRoaXMuaW5wdXRXaWR0aC5kZWdyZWVzVW5pdFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgZGVncmVlc1N5bWJvbFVuaXQgfX1cbiAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICBAaWYgKHNob3dNaW51dGVzKSB7XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgI2lucHV0TWludXRlc1xuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwidGhpcy5pbnB1dFdpZHRoLm1pbnV0ZXNcIlxuICAgICAgICAgICAgICBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCIhc2hvd0ZpZWxkc1wiXG4gICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwibWludXRlc1BsYWNlaG9sZGVyIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cIm1pbnV0ZXNDb250cm9sXCJcbiAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgICAgW21pbl09XCJtaW5NYXhWYWx1ZXMubWludXRlcy5taW5cIlxuICAgICAgICAgICAgICBbbWF4XT1cIm1pbk1heFZhbHVlcy5taW51dGVzLm1heFwiXG4gICAgICAgICAgICAgIFtzdGVwXT1cIm1pbk1heFZhbHVlcy5taW51dGVzLnN0ZXBcIlxuICAgICAgICAgICAgICAoZm9jdXMpPVwiX29uRm9jdXNJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGJsdXIpPVwiX29uQmx1cklucHV0KCRldmVudClcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiX29uQ2xpY2tJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICBjbGFzcz1cInN5bWJvbC11bml0XCJcbiAgICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwidGhpcy5pbnB1dFdpZHRoLm1pbnV0ZXNVbml0XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgbWludXRlc1N5bWJvbFVuaXQgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBAaWYgKHNob3dTZWNvbmRzKSB7XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgI2lucHV0U2Vjb25kc1xuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiaW5wdXRXaWR0aC5zZWNvbmRzXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInNlY29uZHNQbGFjZWhvbGRlciB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJzZWNvbmRzQ29udHJvbFwiXG4gICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleFwiXG4gICAgICAgICAgICAgIFttaW5dPVwibWluTWF4VmFsdWVzLnNlY29uZHMubWluXCJcbiAgICAgICAgICAgICAgW21heF09XCJtaW5NYXhWYWx1ZXMuc2Vjb25kcy5tYXhcIlxuICAgICAgICAgICAgICBbc3RlcF09XCJtaW5NYXhWYWx1ZXMuc2Vjb25kcy5zdGVwXCJcbiAgICAgICAgICAgICAgKGZvY3VzKT1cIl9vbkZvY3VzSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIChibHVyKT1cIl9vbkJsdXJJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIl9vbkNsaWNrSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cInRoaXMuaW5wdXRXaWR0aC5zZWNvbmRzVW5pdFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFzaG93RmllbGRzXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzeW1ib2wtdW5pdFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IHNlY29uZHNTeW1ib2xVbml0IH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQGlmICghc2hvd1NpZ25Db250cm9sKSB7XG4gICAgICAgICAgICA8ZGl2IG1hdFN1ZmZpeD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICA8L2lvbi1jb2w+XG5cbiAgICAgIDwhLS0gc2lnbiAtLT5cbiAgICAgIEBpZiAoc2hvd1NpZ25Db250cm9sKSB7XG4gICAgICAgIDxpb24tY29sIGNsYXNzPVwic2lnbiBpb24tbm8tcGFkZGluZyB7eyB0eXBlIH19XCI+XG4gICAgICAgICAgQHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgQGNhc2UgKCdsYXRpdHVkZScpIHtcbiAgICAgICAgICAgICAgPCEtLSBzaWduIG9uIGxhdGl0dWRlIC0tPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGRcbiAgICAgICAgICAgICAgICBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCJcbiAgICAgICAgICAgICAgICBbc3Vic2NyaXB0U2l6aW5nXT1cIidkeW5hbWljJ1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLm1kYy10ZXh0LWZpZWxkLS1pbnZhbGlkXT1cImZvcm1Db250cm9sLnRvdWNoZWQgJiYgc2lnbkNvbnRyb2wuaW52YWxpZFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPjwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAjaW5wdXRTaWduXG4gICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwic2lnbkNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidDT01NT04uTEFUX0xPTkcuTEFUX1NJR05fUExBQ0VIT0xERVInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleCAhPT0gdW5kZWZpbmVkID8gdGFiaW5kZXggKyAxIDogdW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiMVwiPnt7ICdDT01NT04uTEFUX0xPTkcuTEFUX1NJR05fTicgfCB0cmFuc2xhdGUgfX08L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiLTFcIj57eyAnQ09NTU9OLkxBVF9MT05HLkxBVF9TSUdOX1MnIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cblxuICAgICAgICAgICAgICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAY2FzZSAoJ2xvbmdpdHVkZScpIHtcbiAgICAgICAgICAgICAgPCEtLSBzaWduIG9uIGxvbmdpdHVkZSAtLT5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgICAgICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgICAgICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5tZGMtdGV4dC1maWVsZC0taW52YWxpZF09XCJmb3JtQ29udHJvbC50b3VjaGVkICYmIHNpZ25Db250cm9sLmludmFsaWRcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD48L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgI2lucHV0U2lnblxuICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInNpZ25Db250cm9sXCJcbiAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9QTEFDRUhPTERFUicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4ICE9PSB1bmRlZmluZWQgPyB0YWJpbmRleCArIDEgOiB1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCIxXCIgdHJhbnNsYXRlPnt7ICdDT01NT04uTEFUX0xPTkcuTE9OR19TSUdOX0UnIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIi0xXCIgdHJhbnNsYXRlPnt7ICdDT01NT04uTEFUX0xPTkcuTE9OR19TSUdOX1cnIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cblxuICAgICAgICAgICAgICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L2lvbi1jb2w+XG4gICAgICB9XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi1ncmlkPlxuXG4gIDwhLS0gRG8gdGhlIHNhbWUgYXMgTWF0RnJvbUZpZWxkIHNpbmNlIGFuZ3VsYXIgMTUgKHNlZSBjb21wb25lbnQgc291cmNlKS0tPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJtYXQtbWRjLWZvcm0tZmllbGQtc3Vic2NyaXB0LXdyYXBwZXJcIlxuICAgIFtjbGFzcy5tYXQtbWRjLWZvcm0tZmllbGQtYm90dG9tLWFsaWduXT1cInN1YnNjcmlwdFNpemluZyA9PT0gJ2ZpeGVkJ1wiXG4gICAgW2NsYXNzLm1hdC1tZGMtZm9ybS1maWVsZC1zdWJzY3JpcHQtZHluYW1pYy1zaXplXT1cInN1YnNjcmlwdFNpemluZyA9PT0gJ2R5bmFtaWMnXCJcbiAgPlxuICAgIEBpZiAoZm9ybUNvbnRyb2wudG91Y2hlZCAmJiBmb3JtQ29udHJvbC5pbnZhbGlkKSB7XG4gICAgICA8IS0tIGVycm9ycyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLWZvcm0tZmllbGQtZXJyb3Itd3JhcHBlclwiPlxuICAgICAgICBAaWYgKGZvcm1Db250cm9sLmVycm9ycyB8IG1hcEtleXMgfCBhcnJheUZpcnN0OyBhcyBlcnJvcktleSkge1xuICAgICAgICAgIDxtYXQtZXJyb3I+XG4gICAgICAgICAgICB7eyBpMThuRXJyb3JLZXlzIHwgbWFwR2V0OiBlcnJvcktleSB8IHRyYW5zbGF0ZTogKGZvcm1Db250cm9sLmVycm9ycyB8IG1hcEdldDogZXJyb3JLZXkpIH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRFcnJvclRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH0gQGVsc2Uge1xuICAgICAgPCEtLSBoaW50cyAtLT5cbiAgICAgIDxtYXQtaGludD5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdEhpbnRUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9tYXQtaGludD5cbiAgICB9XG4gIDwvZGl2PlxufVxuXG48bmctdGVtcGxhdGUgI21hdFByZWZpeFRlbXBsYXRlPlxuICA8bmctY29udGVudCBzZWxlY3Q9XCJbbWF0UHJlZml4XVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0U3VmZml4VGVtcGxhdGU+XG4gIEBpZiAoY2xlYXJhYmxlICYmICFyZWFkb25seSkge1xuICAgIDxidXR0b25cbiAgICAgIG1hdFN1ZmZpeFxuICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgKGNsaWNrKT1cImNsZWFyVmFsdWUoJGV2ZW50KVwiXG4gICAgICBbaGlkZGVuXT1cImZvcm1Db250cm9sLnZhbHVlIHwgaXNOaWxcIlxuICAgID5cbiAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gIH1cblxuICA8bmctY29udGVudCBzZWxlY3Q9XCJbbWF0U3VmZml4XVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0RXJyb3JUZW1wbGF0ZT5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwibWF0LWVycm9yLFttYXRFcnJvcl1cIj48L25nLWNvbnRlbnQ+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI21hdEhpbnRUZW1wbGF0ZT5cbiAgPGRpdiBjbGFzcz1cIm1hdC1tZGMtZm9ybS1maWVsZC1oaW50LXdyYXBwZXJcIj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJtYXQtaGludDpub3QoW2FsaWduPSdlbmQnXSksW21hdEhpbnRdXCI+PC9uZy1jb250ZW50PlxuICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLWZvcm0tZmllbGQtaGludC1zcGFjZXJcIj48L2Rpdj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJtYXQtaGludFthbGlnbj0nZW5kJ11cIj48L25nLWNvbnRlbnQ+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==