@sumaris-net/ngx-components 18.2.28 → 18.2.29

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.
@@ -1,71 +1,91 @@
1
- import { booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, forwardRef, Inject, Input, Optional, Output, ViewChild, } from '@angular/core';
2
- import { NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
3
- import { SharedValidators } from '../../validator/validators';
4
- import { formatLatLong, LAT_LONG_PATTERN_MAX_DECIMALS, MASKS, parseLatitudeOrLongitude, } from './latlong.utils';
5
- import { SPACE_PLACEHOLDER_CHAR } from '../../constants';
6
- import { filter } from 'rxjs/operators';
7
- import { isNil, isNotNil, isNotNilOrBlank } from '../../functions';
8
- import { getInputSelectionRangesFromMask, selectInputRange } from '../../inputs';
1
+ import { booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, forwardRef, Inject, Input, numberAttribute, Optional, Output, ViewChild, } from '@angular/core';
2
+ import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
3
+ import { MAT_FORM_FIELD_DEFAULT_OPTIONS, } from '@angular/material/form-field';
9
4
  import { merge, Subscription } from 'rxjs';
10
- import { DEFAULT_MAX_DECIMALS } from '../duration/duration.utils';
11
- import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
12
- import { MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING } from '../material.config';
5
+ import { filter } from 'rxjs/operators';
6
+ import { isNil, isNilOrBlank, isNotNil } from '../../functions';
13
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_PATTERN_MAX_DECIMALS, LAT_LONG_VALUE_MAX_DECIMALS, splitNumberToFieldsDD, splitNumberToFieldsDDMM, splitNumberToFieldsDDMMSS, } from './latlong.utils';
11
+ import { MatSelect } from '@angular/material/select';
12
+ import { selectInputContent } from '../../inputs';
13
+ import { maskitoNumberOptionsGenerator } from '@maskito/kit';
14
14
  import * as i0 from "@angular/core";
15
15
  import * as i1 from "@angular/forms";
16
- import * as i2 from "@ngx-translate/core";
17
- import * as i3 from "@angular/common";
18
- import * as i4 from "@ionic/angular";
19
- import * as i5 from "../../directives/autofocus.directive";
20
- import * as i6 from "@angular/material/form-field";
21
- import * as i7 from "@angular/material/input";
16
+ import * as i2 from "@angular/common";
17
+ import * as i3 from "@ionic/angular";
18
+ import * as i4 from "../../directives/autofocus.directive";
19
+ import * as i5 from "@angular/material/form-field";
20
+ import * as i6 from "@angular/material/input";
21
+ import * as i7 from "@angular/material/button";
22
22
  import * as i8 from "@maskito/angular";
23
- import * as i9 from "@angular/material/select";
24
- import * as i10 from "@angular/material/core";
25
- import * as i11 from "../../pipes/arrays.pipe";
26
- import * as i12 from "../../pipes/maps.pipe";
27
- import * as i13 from "../../pipes/types.pipes";
28
- import * as i14 from "../../pipes/maskito.pipe";
23
+ import * as i9 from "@angular/material/icon";
24
+ import * as i10 from "@angular/material/select";
25
+ import * as i11 from "@angular/material/core";
26
+ import * as i12 from "../../pipes/latlong-format.pipe";
27
+ import * as i13 from "../../pipes/arrays.pipe";
28
+ import * as i14 from "../../pipes/maps.pipe";
29
+ import * as i15 from "../../pipes/string.pipes";
30
+ import * as i16 from "../../pipes/types.pipes";
31
+ import * as i17 from "@ngx-translate/core";
29
32
  const noop = () => { };
30
33
  export class MatLatLongField {
31
- formBuilder;
32
34
  cd;
33
- translate;
34
35
  formGroupDir;
35
36
  _onChangeCallback = noop;
36
37
  _onTouchedCallback = noop;
37
38
  _subscription = new Subscription();
38
- _formatOptions;
39
39
  _disabling = false;
40
40
  _writing = false;
41
41
  _appearance = null;
42
42
  _subscriptSizing = null;
43
+ _readonly = false;
44
+ _tabindex;
43
45
  _defaultAppearance;
44
46
  _defaultSubscriptSizing;
45
- _readonly = false;
46
- textFormControl;
47
- signFormControl;
48
- mask;
49
- inputPlaceHolderI18nKey;
47
+ _focused = false;
48
+ _touched = false;
49
+ degreesControl;
50
+ minutesControl;
51
+ secondsControl;
52
+ signControl;
53
+ showMinutes = false;
54
+ showSeconds = false;
50
55
  showSignControl;
51
- maskitoPlaceholder;
52
- hasFocus = false;
53
- get disabled() {
54
- return this.readonly || this.formControl.disabled;
55
- }
56
+ degreesPlaceholder;
57
+ minutesPlaceholder;
58
+ secondsPlaceholder;
59
+ degreesMask;
60
+ minutesMask;
61
+ secondsMask;
62
+ patternMaxDecimals = LAT_LONG_PATTERN_MAX_DECIMALS;
63
+ i18nErrorKeys = SharedValidators.I18N_ERROR_KEYS;
56
64
  formControl;
57
65
  formControlName;
58
66
  type;
59
67
  pattern;
68
+ maxDecimals = LAT_LONG_VALUE_MAX_DECIMALS;
60
69
  required = false;
61
70
  floatLabel = 'auto';
62
71
  placeholder;
63
- tabindex;
64
72
  defaultSign;
65
- maxDecimals = LAT_LONG_PATTERN_MAX_DECIMALS;
66
- placeholderChar;
67
73
  autofocus = false;
68
74
  mobile;
75
+ degreesSymbolUnit = '°';
76
+ minutesSymbolUnit = "'";
77
+ secondsSymbolUnit = '"';
78
+ clearable = false;
79
+ classList;
80
+ set tabindex(value) {
81
+ if (this._tabindex !== value) {
82
+ this._tabindex = value;
83
+ setTimeout(() => this.updateTabIndex());
84
+ }
85
+ }
86
+ get tabindex() {
87
+ return this._tabindex;
88
+ }
69
89
  set appearance(value) {
70
90
  this._appearance = value;
71
91
  }
@@ -85,285 +105,435 @@ export class MatLatLongField {
85
105
  get subscriptSizing() {
86
106
  return this._subscriptSizing || this._defaultSubscriptSizing;
87
107
  }
88
- onBlur = new EventEmitter();
89
- onFocus = new EventEmitter();
90
- inputElement;
91
- constructor(formBuilder, cd, translate, formGroupDir, defaultOptions) {
92
- this.formBuilder = formBuilder;
108
+ get showFields() {
109
+ return isNotNil(this.formControl.value) || this._focused;
110
+ }
111
+ get disabled() {
112
+ return this.readonly || this.formControl.disabled;
113
+ }
114
+ // eslint-disable-next-line @angular-eslint/no-output-on-prefix,@angular-eslint/no-output-rename
115
+ keyupEnter = new EventEmitter();
116
+ // eslint-disable-next-line @angular-eslint/no-output-rename
117
+ blurred = new EventEmitter();
118
+ // eslint-disable-next-line @angular-eslint/no-output-rename
119
+ focused = new EventEmitter();
120
+ formField;
121
+ fakeInput;
122
+ inputDegrees;
123
+ inputMinutes;
124
+ inputSeconds;
125
+ inputSign;
126
+ inputSignSelect;
127
+ constructor(cd, formGroupDir, defaultOptions) {
93
128
  this.cd = cd;
94
- this.translate = translate;
95
129
  this.formGroupDir = formGroupDir;
96
130
  this._defaultSubscriptSizing = defaultOptions?.subscriptSizing || MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING;
97
131
  this._defaultAppearance = defaultOptions?.appearance || MAT_FORM_FIELD_DEFAULT_APPEARANCE;
98
132
  }
99
133
  ngOnInit() {
100
134
  this.mobile = this.mobile ?? isMobile(window);
101
- if (isNil(this.placeholderChar)) {
102
- this.placeholderChar = this.mobile ? SPACE_PLACEHOLDER_CHAR : '';
103
- }
104
135
  this.type = this.type || 'latitude';
105
136
  this.pattern = this.pattern || 'DDMM';
106
- this.mask = MASKS[this.type]?.[this.pattern];
107
- if (!this.mask) {
108
- console.error("Invalid attribute value. Expected: type: 'latitude|longitude' and latlongPattern: 'DD|DDMM|DDMMSS'");
109
- this.type = 'latitude';
110
- this.pattern = 'DDMM';
111
- this.mask = MASKS[this.type][this.pattern];
112
- }
113
- // Ensure maxDecimals has correct value depending on pattern and it's own value
114
- if (this.pattern === 'DD') {
115
- if (this.maxDecimals != 7)
116
- console.warn(`Force 'maxDecimals' to be '7' when using the 'DD' pattern.`);
117
- this.maxDecimals = 7;
118
- }
119
- else if (this.pattern === 'DDMM') {
120
- if (this.maxDecimals != 2)
121
- console.warn(`Force 'maxDecimals' to be '3' when using the 'DDMM' pattern.`);
122
- this.maxDecimals = 3;
123
- }
124
- else if (isNil(this.maxDecimals)) {
125
- this.maxDecimals = DEFAULT_MAX_DECIMALS;
126
- }
127
- else if (this.maxDecimals < 0) {
128
- console.error("Invalid attribute 'maxDecimals'. Must a positive value.");
129
- this.maxDecimals = DEFAULT_MAX_DECIMALS;
130
- }
131
- else if (this.maxDecimals !== DEFAULT_MAX_DECIMALS) {
132
- console.warn(`Invalid attribute 'maxDecimals' - Expected value: ${DEFAULT_MAX_DECIMALS} but get: ${this.maxDecimals}. Other value not implemented.`);
133
- this.maxDecimals = DEFAULT_MAX_DECIMALS;
134
- }
135
137
  this.showSignControl = this.pattern !== 'DD';
136
- this._formatOptions = {
137
- pattern: this.pattern,
138
- maxDecimals: this.maxDecimals,
139
- hideSign: this.showSignControl,
140
- inputSelectionRanges: getInputSelectionRangesFromMask(this.mask),
141
- placeholderChar: this.placeholderChar,
142
- };
143
- this.inputPlaceHolderI18nKey = 'COMMON.LAT_LONG.' + ((this.type === 'longitude' && 'D') || '') + this.pattern + '_PLACEHOLDER';
144
- this.textFormControl = this.formBuilder.control(this.required ? [null, Validators.required] : [null]);
145
- this.signFormControl = this.formBuilder.control(this.required ? [null, Validators.required] : [null]);
138
+ // const degreesValidators: ValidatorFn[] = [this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude];
139
+ // const minutesValidators: ValidatorFn[] = [];
140
+ // const secondsValidators: ValidatorFn[] = [];
141
+ switch (this.pattern) {
142
+ case 'DD':
143
+ this.patternMaxDecimals = 7;
144
+ // degreesValidators.push(SharedValidators.decimal({ maxDecimals: this.patternMaxDecimals }));
145
+ this.degreesPlaceholder =
146
+ this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD_PLACEHOLDER' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD_PLACEHOLDER';
147
+ this.degreesMask = maskitoNumberOptionsGenerator({
148
+ precision: this.patternMaxDecimals,
149
+ min: this.type === 'latitude' ? -90 : -180,
150
+ max: this.type === 'latitude' ? 90 : 180,
151
+ minusSign: '-',
152
+ });
153
+ break;
154
+ case 'DDMM':
155
+ this.patternMaxDecimals = 3;
156
+ this.showMinutes = true;
157
+ // degreesValidators.push(SharedValidators.integer);
158
+ // minutesValidators.push(Validators.min(this.minMaxValues.minutes.min));
159
+ // minutesValidators.push(Validators.max(this.minMaxValues.minutes.max));
160
+ // minutesValidators.push(SharedValidators.decimal({ maxDecimals: this.patternMaxDecimals }));
161
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
162
+ this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
163
+ this.degreesMask = maskitoNumberOptionsGenerator({
164
+ precision: 0,
165
+ min: 0,
166
+ max: this.type === 'latitude' ? 90 : 180,
167
+ });
168
+ this.minutesMask = maskitoNumberOptionsGenerator({
169
+ precision: this.patternMaxDecimals,
170
+ min: 0,
171
+ max: 60 - this.computeDecimalPart(1, this.patternMaxDecimals),
172
+ });
173
+ break;
174
+ default: // Default is DDMMSS
175
+ this.patternMaxDecimals = 2;
176
+ this.showMinutes = true;
177
+ this.showSeconds = true;
178
+ // degreesValidators.push(SharedValidators.integer);
179
+ // minutesValidators.push(SharedValidators.integer);
180
+ // minutesValidators.push(Validators.min(this.minMaxValues.minutes.min));
181
+ // minutesValidators.push(Validators.max(this.minMaxValues.minutes.max));
182
+ // secondsValidators.push(Validators.min(this.minMaxValues.seconds.min));
183
+ // secondsValidators.push(Validators.max(this.minMaxValues.seconds.max));
184
+ // secondsValidators.push(SharedValidators.decimal({ maxDecimals: this.patternMaxDecimals }));
185
+ this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
186
+ this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
187
+ this.secondsPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.SS_SS';
188
+ this.degreesMask = maskitoNumberOptionsGenerator({
189
+ precision: 0,
190
+ min: 0,
191
+ max: this.type === 'latitude' ? 90 : 180,
192
+ });
193
+ this.minutesMask = maskitoNumberOptionsGenerator({
194
+ precision: 0,
195
+ min: 0,
196
+ max: 59,
197
+ });
198
+ this.secondsMask = maskitoNumberOptionsGenerator({
199
+ precision: this.patternMaxDecimals,
200
+ min: 0,
201
+ max: 60 - this.computeDecimalPart(1, this.patternMaxDecimals),
202
+ });
203
+ break;
204
+ }
146
205
  this.formControl =
147
206
  this.formControl || (this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName));
148
207
  if (!this.formControl)
149
208
  throw new Error("Missing mandatory attribute 'formControl' or 'formControlName' in <mat-latlong-field>.");
150
- const existingValidators = this.formControl.validator;
151
- if (existingValidators) {
152
- this.formControl.setValidators([existingValidators, this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude]);
153
- }
154
- else {
155
- this.formControl.setValidators(this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude);
156
- }
157
- this._subscription.add(merge(this.textFormControl.valueChanges, this.signFormControl.valueChanges).subscribe(() => this.onFormChange()));
209
+ this.degreesControl = new FormControl(null);
210
+ this.minutesControl = new FormControl(null);
211
+ this.secondsControl = new FormControl(null);
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()));
158
214
  // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
159
215
  this._subscription.add(this.formControl.statusChanges
160
216
  .pipe(filter(() => !this.readonly && !this._writing && !this._disabling) // Skip
161
217
  )
162
218
  .subscribe(() => this.markForCheck()));
163
- this._subscription.add(this.translate.get(this.inputPlaceHolderI18nKey).subscribe((translation) => this.updateTranslations(translation)));
164
219
  }
165
220
  ngOnDestroy() {
166
221
  this._subscription.unsubscribe();
167
222
  }
168
- writeValue(obj) {
223
+ registerOnChange(fn) {
224
+ this._onChangeCallback = fn;
225
+ }
226
+ registerOnTouched(fn) {
227
+ this._onTouchedCallback = fn;
228
+ }
229
+ writeValue(value) {
169
230
  if (this._writing)
170
231
  return;
171
232
  this._writing = true;
172
- const value = typeof obj === 'string' ? parseFloat(obj.replace(/,/g, '.')) : obj;
173
- const fixLatLong = this.formControl.valid;
174
- const strValue = this._format(value, { fixLatLong });
175
- const sign = isNotNil(value)
176
- ? value < 0
177
- ? -1
178
- : 1
179
- : // Use default sign, if any
180
- this.defaultSign
181
- ? this.defaultSign === '-'
182
- ? -1
183
- : 1
184
- : null;
185
- this.signFormControl.patchValue(sign, { emitEvent: false });
186
- if (value === null) {
187
- // Reset the field
188
- this.textFormControl.patchValue(null, { emitEvent: false });
189
- }
190
- else {
191
- this.textFormControl.patchValue(strValue, { emitEvent: false });
233
+ if (value !== this.formControl.value) {
234
+ this.formControl.patchValue(value, { emitEvent: false });
235
+ this._onChangeCallback(value);
192
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 });
193
240
  this._writing = false;
194
241
  this.markForCheck();
195
- }
196
- registerOnChange(fn) {
197
- this._onChangeCallback = fn;
198
- }
199
- registerOnTouched(fn) {
200
- this._onTouchedCallback = fn;
242
+ setTimeout(() => {
243
+ this.updateFakeInput();
244
+ this.updateTabIndex();
245
+ });
201
246
  }
202
247
  setDisabledState(isDisabled) {
203
248
  if (this._disabling)
204
249
  return;
205
250
  this._disabling = true;
206
251
  if (isDisabled) {
207
- this.textFormControl.disable({ onlySelf: true, emitEvent: false });
208
- this.signFormControl.disable({ onlySelf: true, emitEvent: false });
252
+ this.degreesControl.disable();
253
+ this.minutesControl.disable();
254
+ this.secondsControl.disable();
255
+ this.signControl.disable();
209
256
  }
210
257
  else {
211
- this.textFormControl.enable({ onlySelf: true, emitEvent: false });
212
- this.signFormControl.enable({ onlySelf: true, emitEvent: false });
258
+ this.degreesControl.enable();
259
+ this.minutesControl.enable();
260
+ this.secondsControl.enable();
261
+ this.signControl.enable();
213
262
  }
214
263
  this._disabling = false;
215
264
  this.markForCheck();
216
265
  }
217
- _onFocus(event) {
218
- this.hasFocus = true;
219
- const fromTabKey = isNotNil(event.relatedTarget);
220
- const fixLatLong = this.formControl.valid;
221
- let strValue = formatLatLong(this.formControl.value, this.type, { ...this._formatOptions, placeholderChar: '0', fixLatLong }) ?? this.maskitoPlaceholder;
222
- if (strValue.startsWith('±')) {
223
- strValue = strValue.replace('±', this.defaultSign);
224
- if (this.type === 'latitude') {
225
- this.textFormControl.setValue(strValue + ' ');
266
+ clearValue(event) {
267
+ event?.stopPropagation();
268
+ this.writeValue(null);
269
+ }
270
+ get internalElements() {
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.internalElements.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.internalElements.some((el) => el === event.target);
296
+ if (internalEvent) {
297
+ if (event.target === this.inputSign?.nativeElement) {
298
+ this.inputSignSelect?.open();
226
299
  }
227
300
  else {
228
- this.textFormControl.setValue(strValue);
301
+ selectInputContent(event.target);
229
302
  }
230
303
  }
231
- this.textFormControl.setValue(strValue);
232
- // If focus came form push tab key and the input has value, select all the value
233
- if (fromTabKey && strValue.replace(/^[±+-]/, '') !== this.maskitoPlaceholder.replace(/^[±+-]/, '')) {
234
- const strValueWithoutSign = strValue.replace(/^[±+-]/, '');
235
- if (strValueWithoutSign !== this.maskitoPlaceholder.replace(/^[±+-]/, '')) {
236
- // has value
237
- selectInputRange(event.target, strValue.length - strValueWithoutSign.length, strValueWithoutSign.length);
304
+ this.focus(event.target);
305
+ }
306
+ _onBlurInput(event) {
307
+ const internalEvent = this.internalElements.some((el) => el === event.relatedTarget);
308
+ if (!internalEvent) {
309
+ this._focused = false;
310
+ if (this.appearance == 'fill') {
311
+ this.formField._lineRipple.deactivate();
238
312
  }
313
+ this.blurred.emit(event);
314
+ this.updateFakeInput();
315
+ this.updateTabIndex();
316
+ this._touched = true;
317
+ this.formControl.markAsTouched();
318
+ this._checkIfTouched();
239
319
  }
240
- this.onFocus.emit(event);
241
- return true;
242
- }
243
- _onBlur(event) {
244
- this.hasFocus = false;
245
- let strValue = this.textFormControl.value;
246
- // Reset mask if value is empty
247
- if (!/\d/.test(strValue)) {
248
- strValue = null;
320
+ }
321
+ _onClickInput(event) {
322
+ const internalEvent = this.internalElements.some((el) => el === event.target);
323
+ if (internalEvent) {
324
+ selectInputContent(event.target);
249
325
  }
250
- const parsedValue = this.parseValue(strValue);
251
- this.formControl.markAsTouched();
252
- this.formControl.patchValue(parsedValue, { emitEvent: false });
253
- this.onBlur.emit(event);
326
+ // Avoid mat-form-field to give focus to fake input
327
+ event.stopPropagation();
254
328
  }
255
- _format(value, opts = {}) {
256
- return formatLatLong(value, this.type, { ...this._formatOptions, ...opts }) ?? this.maskitoPlaceholder;
329
+ focus(target) {
330
+ if (this._focused)
331
+ return true; // Already focused
332
+ const showFields = this.showFields;
333
+ this._focused = true;
334
+ this.markForCheck();
335
+ setTimeout(() => {
336
+ if (!showFields) {
337
+ this.inputDegrees.nativeElement.focus();
338
+ selectInputContent(this.inputDegrees.nativeElement);
339
+ }
340
+ else if (target) {
341
+ target.focus();
342
+ selectInputContent(target);
343
+ }
344
+ if (this.appearance == 'fill') {
345
+ this.formField._lineRipple.activate();
346
+ }
347
+ this.updateFakeInput();
348
+ this.updateTabIndex();
349
+ }, 50);
257
350
  }
258
- _checkIfTouched() {
259
- if (this.textFormControl.touched) {
260
- this._onTouchedCallback();
261
- this.markForCheck();
351
+ format(rawValue) {
352
+ const values = this.computeLatLongFormGroupValue(rawValue);
353
+ if (values.degrees === null)
354
+ return '';
355
+ let result = `${values.degrees}° `;
356
+ if (values.minutes !== null)
357
+ result += `${values.minutes}' `;
358
+ if (values.seconds !== null)
359
+ result += `${values.seconds}" `;
360
+ if (this.type === 'latitude') {
361
+ result += values.sign === 1 ? 'N' : 'S';
262
362
  }
363
+ else {
364
+ result += values.sign === 1 ? 'E' : 'W';
365
+ }
366
+ return result;
367
+ }
368
+ computeDecimalPart(value, nbOfDecimals) {
369
+ return value * 10 ** (nbOfDecimals * -1);
370
+ }
371
+ computeLatLongFormGroupValue(rawValue) {
372
+ const isLongitude = this.type === 'longitude';
373
+ const value = typeof rawValue === 'string' ? parseFloat(rawValue.replace(/,/g, '.')) : rawValue;
374
+ const result = {
375
+ degrees: null,
376
+ minutes: null,
377
+ seconds: null,
378
+ sign: isNotNil(value)
379
+ ? value < 0
380
+ ? -1
381
+ : 1
382
+ : // Use default sign, if any
383
+ this.defaultSign && this.defaultSign === '-'
384
+ ? -1
385
+ : 1,
386
+ };
387
+ if (value === 0) {
388
+ result.degrees = 0;
389
+ }
390
+ else if (isNotNil(value)) {
391
+ if (this.pattern === 'DD') {
392
+ const splitValue = splitNumberToFieldsDD(value, {
393
+ longitude: isLongitude,
394
+ pattern: this.pattern,
395
+ maxDecimals: this.patternMaxDecimals,
396
+ fixLatLong: true,
397
+ }).slice(1); // remove sign;
398
+ result.degrees = (splitValue[0] + this.computeDecimalPart(splitValue[1] ?? 0, this.patternMaxDecimals)) * (result.sign || 1) || null;
399
+ }
400
+ else if (this.pattern === 'DDMM') {
401
+ const splitValue = splitNumberToFieldsDDMM(value, {
402
+ longitude: isLongitude,
403
+ pattern: this.pattern,
404
+ maxDecimals: this.patternMaxDecimals,
405
+ fixLatLong: true,
406
+ });
407
+ result['minutes'] = Math.abs((splitValue[1] ?? 0) + this.computeDecimalPart(splitValue[2] ?? 0, this.patternMaxDecimals)) || null;
408
+ result['degrees'] = Math.abs(!result['minutes'] && isNilOrBlank(splitValue[0]) ? null : (splitValue[0] ?? 0));
409
+ }
410
+ else {
411
+ // Default // DDMMSS
412
+ const splitValue = splitNumberToFieldsDDMMSS(value, {
413
+ longitude: isLongitude,
414
+ pattern: this.pattern,
415
+ maxDecimals: this.patternMaxDecimals,
416
+ fixLatLong: true,
417
+ });
418
+ result['seconds'] = Math.abs((splitValue[2] ?? 0) + this.computeDecimalPart(splitValue[3] ?? 0, this.patternMaxDecimals)) || null;
419
+ result['minutes'] = !result['seconds'] && !splitValue[1] ? null : Math.abs(splitValue[1] ?? 0);
420
+ result['degrees'] = !result['seconds'] && !result['minutes'] && isNilOrBlank(splitValue[0]) ? null : Math.abs(splitValue[0] ?? 0);
421
+ }
422
+ }
423
+ return result;
424
+ }
425
+ markAsTouched() {
426
+ this.formControl.markAsTouched();
427
+ this.degreesControl.markAsTouched();
428
+ this.minutesControl.markAsTouched();
429
+ this.secondsControl.markAsTouched();
430
+ this.signControl.markAsTouched();
431
+ this._onTouchedCallback();
263
432
  }
264
433
  /* -- private method -- */
434
+ patchValue(values, opts) {
435
+ this.degreesControl.patchValue(values.degrees?.toString(), opts);
436
+ this.minutesControl.patchValue(values.minutes?.toString(), opts);
437
+ this.secondsControl.patchValue(values.seconds?.toString(), opts);
438
+ this.signControl.patchValue(values.sign, opts);
439
+ }
265
440
  onFormChange() {
266
441
  if (this._writing)
267
442
  return; // Skip if call by self
268
443
  this._writing = true;
269
- let strValue = this.textFormControl.value;
270
- // Reset mask if value is empty
271
- if (!/\d/.test(strValue)) {
272
- strValue = null;
444
+ const degrees = parseFloat(this.degreesControl.value);
445
+ const minutes = parseFloat(this.minutesControl.value);
446
+ const seconds = parseFloat(this.secondsControl.value);
447
+ const sign = this.signControl.value;
448
+ const incompleteValue = isNil(degrees) && (isNotNil(minutes) || isNotNil(seconds));
449
+ const invalid = incompleteValue || this.degreesControl.invalid || this.minutesControl.invalid || this.secondsControl.invalid || this.signControl.invalid;
450
+ if (invalid) {
451
+ this.formControl.markAsPending({ onlySelf: true });
452
+ this.formControl.setErrors({
453
+ invalid: incompleteValue,
454
+ ...this.degreesControl.errors,
455
+ ...this.minutesControl.errors,
456
+ ...this.secondsControl.errors,
457
+ ...this.signControl.errors,
458
+ });
459
+ if (this.degreesControl.dirty || this.minutesControl.dirty || this.secondsControl.dirty || this.signControl.dirty) {
460
+ this.formControl.markAsDirty();
461
+ }
462
+ this._writing = false;
463
+ return;
273
464
  }
274
- const parsedValue = this.parseValue(strValue);
275
- this.emitChange(parsedValue);
465
+ // Compute decimal values
466
+ const value = isNil(degrees) || this.pattern === 'DD' ? degrees : computeDecimalDegrees(degrees, minutes, seconds, sign, this.maxDecimals);
467
+ // Set model value
468
+ this.emitChange(value);
276
469
  this._writing = false;
277
470
  this.markForCheck();
278
471
  }
279
472
  emitChange(value) {
280
- const formControlValue = this.formControl.value;
281
- if (formControlValue !== value) {
282
- if (this.textFormControl.valid) {
283
- this.formControl.setValue(value, { emitEvent: false });
284
- this._onChangeCallback(value);
285
- this._checkIfTouched();
286
- }
287
- }
288
- }
289
- updateTranslations(translation) {
290
- // No change
291
- if (this.maskitoPlaceholder === translation)
292
- return;
293
- // Translation fallback
294
- if (this.inputPlaceHolderI18nKey === translation) {
295
- switch (this.pattern) {
296
- case 'DD':
297
- if (this.type === 'longitude') {
298
- this.maskitoPlaceholder = '±DDD.DDDDDDD°';
299
- }
300
- else {
301
- this.maskitoPlaceholder = '± DD.DDDDDDD°';
302
- }
303
- break;
304
- case 'DDMM':
305
- if (this.type === 'longitude') {
306
- this.maskitoPlaceholder = "DDD° MM.MMM'";
307
- }
308
- else {
309
- this.maskitoPlaceholder = "DD° MM.MMM'";
310
- }
311
- break;
312
- case 'DDMMSS':
313
- if (this.type === 'longitude') {
314
- this.maskitoPlaceholder = 'DDD° MM\' SS.SS"';
315
- }
316
- else {
317
- this.maskitoPlaceholder = 'DD° MM\' SS.SS"';
318
- }
319
- break;
320
- }
321
- return;
473
+ if (this.formControl.value !== value) {
474
+ this.formControl.setValue(value, { emitEvent: false });
475
+ // Changes comes from inside function: use the callback
476
+ this._onChangeCallback(value);
477
+ // Check if need to update controls
478
+ this._checkIfTouched();
322
479
  }
323
- this.maskitoPlaceholder = translation;
324
480
  }
325
- parseValue(strValue) {
326
- let parsedValue;
327
- if (isNotNilOrBlank(strValue)) {
328
- if (this.pattern === 'DD') {
329
- parsedValue = parseLatitudeOrLongitude(strValue, this.pattern, 7);
330
- }
331
- else {
332
- const sign = this.signFormControl.value || this.defaultSign === '-' ? -1 : 1;
333
- parsedValue = sign * parseLatitudeOrLongitude(strValue, this.pattern, 7);
334
- }
481
+ _checkIfTouched() {
482
+ if (this.formControl.touched) {
483
+ this._onTouchedCallback();
484
+ this.markForCheck();
485
+ this._touched = true;
335
486
  }
336
487
  else {
337
- parsedValue = null;
338
- }
339
- if (this.pattern !== 'DD' && parsedValue !== null) {
340
- const sign = this.signFormControl.value;
341
- parsedValue = sign * Math.abs(parsedValue);
488
+ this._touched = false;
342
489
  }
343
- return parsedValue;
344
490
  }
345
491
  markForCheck() {
346
492
  this.cd.markForCheck();
347
493
  }
348
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, deps: [{ token: i1.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }, { token: i2.TranslateService }, { token: i1.FormGroupDirective, optional: true }, { token: MAT_FORM_FIELD_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
349
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongField, selector: "mat-latlong-field-old", inputs: { formControl: "formControl", formControlName: "formControlName", type: "type", pattern: ["latLongPattern", "pattern"], required: "required", floatLabel: "floatLabel", placeholder: "placeholder", tabindex: "tabindex", defaultSign: "defaultSign", maxDecimals: "maxDecimals", placeholderChar: "placeholderChar", autofocus: "autofocus", mobile: ["mobile", "mobile", booleanAttribute], appearance: "appearance", readonly: "readonly", subscriptSizing: "subscriptSizing" }, outputs: { onBlur: "onBlur", onFocus: "onFocus" }, providers: [
494
+ /**
495
+ * Show/Hide the fake input
496
+ */
497
+ updateFakeInput() {
498
+ if (this.showFields) {
499
+ this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
500
+ }
501
+ else {
502
+ this.fakeInput?.nativeElement.classList.remove('cdk-visually-hidden');
503
+ }
504
+ // TODO: check if need
505
+ this.markForCheck();
506
+ }
507
+ /**
508
+ * This is a special case, because, this component has a temporary component displayed before the first focus event
509
+ */
510
+ updateTabIndex() {
511
+ if (isNil(this._tabindex))
512
+ return;
513
+ if (this.fakeInput) {
514
+ this.fakeInput.nativeElement.tabIndex = this._tabindex;
515
+ }
516
+ this.markForCheck();
517
+ }
518
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.FormGroupDirective, optional: true }, { token: MAT_FORM_FIELD_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
519
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongField, selector: "mat-latlong-field", inputs: { formControl: "formControl", formControlName: "formControlName", type: "type", pattern: ["latLongPattern", "pattern"], maxDecimals: "maxDecimals", required: "required", floatLabel: "floatLabel", placeholder: "placeholder", defaultSign: "defaultSign", autofocus: "autofocus", mobile: ["mobile", "mobile", booleanAttribute], degreesSymbolUnit: "degreesSymbolUnit", minutesSymbolUnit: "minutesSymbolUnit", secondsSymbolUnit: "secondsSymbolUnit", clearable: ["clearable", "clearable", booleanAttribute], classList: ["class", "classList"], tabindex: ["tabindex", "tabindex", numberAttribute], appearance: "appearance", readonly: "readonly", subscriptSizing: "subscriptSizing" }, outputs: { keyupEnter: "keyup.enter", blurred: "blur", focused: "focus" }, providers: [
350
520
  {
351
521
  provide: NG_VALUE_ACCESSOR,
352
522
  multi: true,
353
523
  useExisting: forwardRef(() => MatLatLongField),
354
524
  },
355
- ], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], ngImport: i0, template: "<!-- readonly -->\n<mat-form-field\n *ngIf=\"readonly; else writable\"\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>{{ _format(formControl.value) }}</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\n<!-- writable -->\n<ng-template #writable>\n <ion-grid class=\"ion-no-padding {{ appearance }}\">\n <ion-row class=\"ion-no-padding no-wrap\">\n <ion-col class=\"text ion-no-padding\">\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signFormControl.invalid || formControl.invalid)\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <mat-label *ngIf=\"floatLabel !== 'never' && !!placeholder\">{{ placeholder }}</mat-label>\n\n <input\n matInput\n #inputElement\n [maskito]=\"maskitoPlaceholder | maskitoPlaceholder: mask\"\n type=\"text\"\n autocomplete=\"off\"\n [placeholder]=\"placeholder\"\n (blur)=\"_onBlur($event)\"\n (focus)=\"_onFocus($event)\"\n [formControl]=\"textFormControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"autofocus\"\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 && signFormControl.invalid\"\n >\n <mat-select\n [formControl]=\"signFormControl\"\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 && signFormControl.invalid\"\n >\n <mat-select\n [formControl]=\"signFormControl\"\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 @switch (errorKey) {\n @case ('required') {\n <mat-error translate>ERROR.FIELD_REQUIRED</mat-error>\n }\n @case ('latitude') {\n <mat-error translate>ERROR.FIELD_NOT_VALID_LATITUDE</mat-error>\n }\n @case ('longitude') {\n <mat-error translate>ERROR.FIELD_NOT_VALID_LONGITUDE</mat-error>\n }\n @case ('min') {\n <mat-error>\n {{ 'ERROR.FIELD_MIN_COMPACT' | translate: { min: _format(formControl.errors.min.min) } }}\n </mat-error>\n }\n @case ('max') {\n <mat-error>\n {{ 'ERROR.FIELD_MAX_COMPACT' | translate: { max: _format(formControl.errors.max.max) } }}\n </mat-error>\n }\n @case ('msg') {\n <mat-error>\n {{ formControl.errors.msg?.key || formControl.errors.msg | translate: formControl.errors.msg?.params }}\n </mat-error>\n }\n @default {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n }\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</ng-template>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\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.text{--min-width: 100px;min-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)}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.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: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.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.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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7.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: "directive", type: i8.MaskitoDirective, selector: "[maskito]", inputs: ["maskito", "maskitoElement"] }, { 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: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i11.ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: i12.MapKeysPipe, name: "mapKeys" }, { kind: "pipe", type: i13.AsFloatLabelTypePipe, name: "asFloatLabelType" }, { kind: "pipe", type: i14.MaskitoPlaceholderPipe, name: "maskitoPlaceholder" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
525
+ ], 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, read: ElementRef }, { propertyName: "inputSignSelect", first: true, predicate: ["inputSign"], descendants: true, read: MatSelect }], 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 {{ classList }}\"\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: patternMaxDecimals, 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 <mat-form-field\n #formField\n [floatLabel]=\"showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"mat-latlong-field mat-latlong-field-{{ type }} {{ classList }}\"\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 [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [class.degrees]=\"pattern !== 'DD'\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [maskito]=\"degreesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [class.minutes]=\"showSeconds\"\n [class.minutes-seconds]=\"!showSeconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"minutesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n class=\"seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"secondsMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span [class.cdk-visually-hidden]=\"!showFields\" class=\"symbol-unit\">\n {{ secondsSymbolUnit }}\n </span>\n }\n\n <!-- sign -->\n @if (showSignControl) {\n <span class=\"flex-spacer\"></span>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"\n (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' : 'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER')\n | translate\n \"\n [tabindex]=\"tabindex\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n class=\"sign\"\n >\n <mat-option [value]=\"1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_N' : 'COMMON.LAT_LONG.LONG_SIGN_E') | translate }}\n </mat-option>\n <mat-option [value]=\"-1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_S' : 'COMMON.LAT_LONG.LONG_SIGN_W') | translate }}\n </mat-option>\n </mat-select>\n }\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\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-latlong-field-latitude input.degrees{width:1.3em!important}input{text-align:right}input::placeholder{letter-spacing:-.05em}input.degrees{width:2em}input.minutes{width:1.5em}input.minutes-seconds{width:3.5em}input.seconds{width:3em}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}span.symbol-unit{max-height:24px;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.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.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.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: "directive", type: i8.MaskitoDirective, selector: "[maskito]", inputs: ["maskito", "maskitoElement"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.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: i11.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { 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: i17.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
356
526
  }
357
527
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField, decorators: [{
358
528
  type: Component,
359
- args: [{ selector: 'mat-latlong-field-old', providers: [
529
+ args: [{ selector: 'mat-latlong-field', providers: [
360
530
  {
361
531
  provide: NG_VALUE_ACCESSOR,
362
532
  multi: true,
363
533
  useExisting: forwardRef(() => MatLatLongField),
364
534
  },
365
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- readonly -->\n<mat-form-field\n *ngIf=\"readonly; else writable\"\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>{{ _format(formControl.value) }}</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\n<!-- writable -->\n<ng-template #writable>\n <ion-grid class=\"ion-no-padding {{ appearance }}\">\n <ion-row class=\"ion-no-padding no-wrap\">\n <ion-col class=\"text ion-no-padding\">\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signFormControl.invalid || formControl.invalid)\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <mat-label *ngIf=\"floatLabel !== 'never' && !!placeholder\">{{ placeholder }}</mat-label>\n\n <input\n matInput\n #inputElement\n [maskito]=\"maskitoPlaceholder | maskitoPlaceholder: mask\"\n type=\"text\"\n autocomplete=\"off\"\n [placeholder]=\"placeholder\"\n (blur)=\"_onBlur($event)\"\n (focus)=\"_onFocus($event)\"\n [formControl]=\"textFormControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"autofocus\"\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 && signFormControl.invalid\"\n >\n <mat-select\n [formControl]=\"signFormControl\"\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 && signFormControl.invalid\"\n >\n <mat-select\n [formControl]=\"signFormControl\"\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 @switch (errorKey) {\n @case ('required') {\n <mat-error translate>ERROR.FIELD_REQUIRED</mat-error>\n }\n @case ('latitude') {\n <mat-error translate>ERROR.FIELD_NOT_VALID_LATITUDE</mat-error>\n }\n @case ('longitude') {\n <mat-error translate>ERROR.FIELD_NOT_VALID_LONGITUDE</mat-error>\n }\n @case ('min') {\n <mat-error>\n {{ 'ERROR.FIELD_MIN_COMPACT' | translate: { min: _format(formControl.errors.min.min) } }}\n </mat-error>\n }\n @case ('max') {\n <mat-error>\n {{ 'ERROR.FIELD_MAX_COMPACT' | translate: { max: _format(formControl.errors.max.max) } }}\n </mat-error>\n }\n @case ('msg') {\n <mat-error>\n {{ formControl.errors.msg?.key || formControl.errors.msg | translate: formControl.errors.msg?.params }}\n </mat-error>\n }\n @default {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n }\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</ng-template>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\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.text{--min-width: 100px;min-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)}\n"] }]
366
- }], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }, { type: i2.TranslateService }, { type: i1.FormGroupDirective, decorators: [{
535
+ ], 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 {{ classList }}\"\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: patternMaxDecimals, 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 <mat-form-field\n #formField\n [floatLabel]=\"showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"mat-latlong-field mat-latlong-field-{{ type }} {{ classList }}\"\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 [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [class.degrees]=\"pattern !== 'DD'\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [maskito]=\"degreesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [class.minutes]=\"showSeconds\"\n [class.minutes-seconds]=\"!showSeconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"minutesMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span class=\"symbol-unit\" [class.cdk-visually-hidden]=\"!showFields\">\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n class=\"seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n inputmode=\"decimal\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [maskito]=\"secondsMask\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span [class.cdk-visually-hidden]=\"!showFields\" class=\"symbol-unit\">\n {{ secondsSymbolUnit }}\n </span>\n }\n\n <!-- sign -->\n @if (showSignControl) {\n <span class=\"flex-spacer\"></span>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"\n (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' : 'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER')\n | translate\n \"\n [tabindex]=\"tabindex\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n class=\"sign\"\n >\n <mat-option [value]=\"1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_N' : 'COMMON.LAT_LONG.LONG_SIGN_E') | translate }}\n </mat-option>\n <mat-option [value]=\"-1\" (click)=\"inputSign.close()\">\n {{ (type === 'latitude' ? 'COMMON.LAT_LONG.LAT_SIGN_S' : 'COMMON.LAT_LONG.LONG_SIGN_W') | translate }}\n </mat-option>\n </mat-select>\n }\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\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-latlong-field-latitude input.degrees{width:1.3em!important}input{text-align:right}input::placeholder{letter-spacing:-.05em}input.degrees{width:2em}input.minutes{width:1.5em}input.minutes-seconds{width:3.5em}input.seconds{width:3em}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}span.symbol-unit{max-height:24px;display:inline-block;text-align:center;font-weight:700;font-size:1.3em}\n"] }]
536
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.FormGroupDirective, decorators: [{
367
537
  type: Optional
368
538
  }] }, { type: undefined, decorators: [{
369
539
  type: Inject,
@@ -377,37 +547,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImpo
377
547
  }], pattern: [{
378
548
  type: Input,
379
549
  args: ['latLongPattern']
550
+ }], maxDecimals: [{
551
+ type: Input
380
552
  }], required: [{
381
553
  type: Input
382
554
  }], floatLabel: [{
383
555
  type: Input
384
556
  }], placeholder: [{
385
557
  type: Input
386
- }], tabindex: [{
387
- type: Input
388
558
  }], defaultSign: [{
389
559
  type: Input
390
- }], maxDecimals: [{
391
- type: Input
392
- }], placeholderChar: [{
393
- type: Input
394
560
  }], autofocus: [{
395
561
  type: Input
396
562
  }], mobile: [{
397
563
  type: Input,
398
564
  args: [{ transform: booleanAttribute }]
565
+ }], degreesSymbolUnit: [{
566
+ type: Input
567
+ }], minutesSymbolUnit: [{
568
+ type: Input
569
+ }], secondsSymbolUnit: [{
570
+ type: Input
571
+ }], clearable: [{
572
+ type: Input,
573
+ args: [{ transform: booleanAttribute }]
574
+ }], classList: [{
575
+ type: Input,
576
+ args: ['class']
577
+ }], tabindex: [{
578
+ type: Input,
579
+ args: [{ transform: numberAttribute }]
399
580
  }], appearance: [{
400
581
  type: Input
401
582
  }], readonly: [{
402
583
  type: Input
403
584
  }], subscriptSizing: [{
404
585
  type: Input
405
- }], onBlur: [{
406
- type: Output
407
- }], onFocus: [{
408
- type: Output
409
- }], inputElement: [{
586
+ }], keyupEnter: [{
587
+ type: Output,
588
+ args: ['keyup.enter']
589
+ }], blurred: [{
590
+ type: Output,
591
+ args: ['blur']
592
+ }], focused: [{
593
+ type: Output,
594
+ args: ['focus']
595
+ }], formField: [{
596
+ type: ViewChild,
597
+ args: ['formField']
598
+ }], fakeInput: [{
599
+ type: ViewChild,
600
+ args: ['fakeInput']
601
+ }], inputDegrees: [{
602
+ type: ViewChild,
603
+ args: ['inputDegrees']
604
+ }], inputMinutes: [{
605
+ type: ViewChild,
606
+ args: ['inputMinutes']
607
+ }], inputSeconds: [{
608
+ type: ViewChild,
609
+ args: ['inputSeconds']
610
+ }], inputSign: [{
611
+ type: ViewChild,
612
+ args: ['inputSign', { read: ElementRef }]
613
+ }], inputSignSelect: [{
410
614
  type: ViewChild,
411
- args: ['inputElement']
615
+ args: ['inputSign', { read: MatSelect }]
412
616
  }] } });
413
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwubGF0bG9uZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL21hdGVyaWFsL2xhdGxvbmcvbWF0ZXJpYWwubGF0bG9uZy50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL21hdGVyaWFsL2xhdGxvbmcvbWF0ZXJpYWwubGF0bG9uZy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUE0QyxpQkFBaUIsRUFBMEMsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakosT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUNMLGFBQWEsRUFDYiw2QkFBNkIsRUFJN0IsS0FBSyxFQUNMLHdCQUF3QixHQUN6QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDakYsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbEUsT0FBTyxFQUFFLDhCQUE4QixFQUF1RSxNQUFNLDhC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Qjt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixLQUFLLEVBQUUsSUFBSTs0QkFDWCxXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsQ0FBQzt5QkFDL0M7cUJBQ0YsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU07OzBCQTJFNUMsUUFBUTs7MEJBQ1IsTUFBTTsyQkFBQyw4QkFBOEI7eUNBakQvQixXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNtQixPQUFPO3NCQUEvQixLQUFLO3VCQUFDLGdCQUFnQjtnQkFDZCxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ2tDLE1BQU07c0JBQTdDLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBR2xDLFVBQVU7c0JBRGIsS0FBSztnQkFRTyxRQUFRO3NCQUFwQixLQUFLO2dCQVVGLGVBQWU7c0JBRGxCLEtBQUs7Z0JBUUksTUFBTTtzQkFBZixNQUFNO2dCQUNHLE9BQU87c0JBQWhCLE1BQU07Z0JBRW9CLFlBQVk7c0JBQXRDLFNBQVM7dUJBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Hcm91cERpcmVjdGl2ZSwgTkdfVkFMVUVfQUNDRVNTT1IsIFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU2hhcmVkVmFsaWRhdG9ycyB9IGZyb20gJy4uLy4uL3ZhbGlkYXRvci92YWxpZGF0b3JzJztcbmltcG9ydCB7XG4gIGZvcm1hdExhdExvbmcsXG4gIExBVF9MT05HX1BBVFRFUk5fTUFYX0RFQ0lNQUxTLFxuICBMYXRMb25nRm9ybWF0T3B0aW9ucyxcbiAgTGF0TG9uZ1BhdHRlcm4sXG4gIExhdExvbmdUeXBlLFxuICBNQVNLUyxcbiAgcGFyc2VMYXRpdHVkZU9yTG9uZ2l0dWRlLFxufSBmcm9tICcuL2xhdGxvbmcudXRpbHMnO1xuaW1wb3J0IHsgU1BBQ0VfUExBQ0VIT0xERVJfQ0hBUiB9IGZyb20gJy4uLy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBpc05pbCwgaXNOb3ROaWwsIGlzTm90TmlsT3JCbGFuayB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBnZXRJbnB1dFNlbGVjdGlvblJhbmdlc0Zyb21NYXNrLCBzZWxlY3RJbnB1dFJhbmdlIH0gZnJvbSAnLi4vLi4vaW5wdXRzJztcbmltcG9ydCB7IG1lcmdlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERFRkFVTFRfTUFYX0RFQ0lNQUxTIH0gZnJvbSAnLi4vZHVyYXRpb24vZHVyYXRpb24udXRpbHMnO1xuaW1wb3J0IHsgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9PUFRJT05TLCBNYXRGb3JtRmllbGRBcHBlYXJhbmNlLCBNYXRGb3JtRmllbGREZWZhdWx0T3B0aW9ucywgU3Vic2NyaXB0U2l6aW5nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBBcHBGbG9hdExhYmVsVHlwZSB9IGZyb20gJy4uLy4uL2Zvcm0vZmllbGQubW9kZWwnO1xuaW1wb3J0IHsgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9BUFBFQVJBTkNFLCBNQVRfRk9STV9GSUVMRF9ERUZBVUxUX1NVQlNDUklQVF9TSVpJTkcgfSBmcm9tICcuLi9tYXRlcmlhbC5jb25maWcnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgaXNNb2JpbGUgfSBmcm9tICcuLi8uLi9wbGF0Zm9ybXMnO1xuXG5jb25zdCBub29wID0gKCkgPT4ge307XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21hdC1sYXRsb25nLWZpZWxkLW9sZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tYXRlcmlhbC5sYXRsb25nLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tYXRlcmlhbC5sYXRsb25nLnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdExhdExvbmdGaWVsZCksXG4gICAgfSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE1hdExhdExvbmdGaWVsZCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gIHByaXZhdGUgX29uQ2hhbmdlQ2FsbGJhY2s6IChfOiBhbnkpID0+IHZvaWQgPSBub29wO1xuICBwcml2YXRlIF9vblRvdWNoZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IG5vb3A7XG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSBfZm9ybWF0T3B0aW9uczogTGF0TG9uZ0Zvcm1hdE9wdGlvbnM7XG4gIHByaXZhdGUgX2Rpc2FibGluZyA9IGZhbHNlO1xuICBwcml2YXRlIF93cml0aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgX2FwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0U2l6aW5nOiBTdWJzY3JpcHRTaXppbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVmYXVsdEFwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRTdWJzY3JpcHRTaXppbmc6IFN1YnNjcmlwdFNpemluZztcblxuICBwcm90ZWN0ZWQgX3JlYWRvbmx5ID0gZmFsc2U7XG4gIHByb3RlY3RlZCB0ZXh0Rm9ybUNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbDtcbiAgcHJvdGVjdGVkIHNpZ25Gb3JtQ29udHJvbDogVW50eXBlZEZvcm1Db250cm9sO1xuICBwcm90ZWN0ZWQgbWFzazogKHN0cmluZyB8IFJlZ0V4cClbXTtcbiAgcHJvdGVjdGVkIGlucHV0UGxhY2VIb2xkZXJJMThuS2V5OiBzdHJpbmc7XG4gIHByb3RlY3RlZCBzaG93U2lnbkNvbnRyb2w6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBtYXNraXRvUGxhY2Vob2xkZXI6IHN0cmluZztcbiAgcHJvdGVjdGVkIGhhc0ZvY3VzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgZ2V0IGRpc2FibGVkKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZG9ubHkgfHwgdGhpcy5mb3JtQ29udHJvbC5kaXNhYmxlZDtcbiAgfVxuXG4gIEBJbnB1dCgpIGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gIEBJbnB1dCgpIGZvcm1Db250cm9sTmFtZTogc3RyaW5nO1xuICBASW5wdXQoKSB0eXBlOiBMYXRMb25nVHlwZTtcbiAgQElucHV0KCdsYXRMb25nUGF0dGVybicpIHBhdHRlcm46IExhdExvbmdQYXR0ZXJuO1xuICBASW5wdXQoKSByZXF1aXJlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBmbG9hdExhYmVsOiBBcHBGbG9hdExhYmVsVHlwZSA9ICdhdXRvJztcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZztcbiAgQElucHV0KCkgdGFiaW5kZXg6IG51bWJlcjtcbiAgQElucHV0KCkgZGVmYXVsdFNpZ246ICctJyB8ICcrJztcbiAgQElucHV0KCkgbWF4RGVjaW1hbHM6IG51bWJlciA9IExBVF9MT05HX1BBVFRFUk5fTUFYX0RFQ0lNQUxTO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlckNoYXI6IHN0cmluZztcbiAgQElucHV0KCkgYXV0b2ZvY3VzID0gZmFsc2U7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBtb2JpbGU6IGJvb2xlYW47XG5cbiAgQElucHV0KClcbiAgc2V0IGFwcGVhcmFuY2UodmFsdWU6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UpIHtcbiAgICB0aGlzLl9hcHBlYXJhbmNlID0gdmFsdWU7XG4gIH1cbiAgZ2V0IGFwcGVhcmFuY2UoKTogTWF0Rm9ybUZpZWxkQXBwZWFyYW5jZSB7XG4gICAgcmV0dXJuIHRoaXMuX2FwcGVhcmFuY2UgfHwgdGhpcy5fZGVmYXVsdEFwcGVhcmFuY2U7XG4gIH1cblxuICBASW5wdXQoKSBzZXQgcmVhZG9ubHkodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9yZWFkb25seSA9IHZhbHVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgcmVhZG9ubHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRvbmx5O1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHN1YnNjcmlwdFNpemluZyh2YWx1ZTogU3Vic2NyaXB0U2l6aW5nKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0U2l6aW5nID0gdmFsdWU7XG4gIH1cbiAgZ2V0IHN1YnNjcmlwdFNpemluZygpOiBTdWJzY3JpcHRTaXppbmcge1xuICAgIHJldHVybiB0aGlzLl9zdWJzY3JpcHRTaXppbmcgfHwgdGhpcy5fZGVmYXVsdFN1YnNjcmlwdFNpemluZztcbiAgfVxuXG4gIEBPdXRwdXQoKSBvbkJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyPEZvY3VzRXZlbnQ+KCk7XG4gIEBPdXRwdXQoKSBvbkZvY3VzID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2lucHV0RWxlbWVudCcpIGlucHV0RWxlbWVudDogRWxlbWVudFJlZjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGZvcm1CdWlsZGVyOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBmb3JtR3JvdXBEaXI6IEZvcm1Hcm91cERpcmVjdGl2ZSxcbiAgICBASW5qZWN0KE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfT1BUSU9OUykgZGVmYXVsdE9wdGlvbnM/OiBNYXRGb3JtRmllbGREZWZhdWx0T3B0aW9uc1xuICApIHtcbiAgICB0aGlzLl9kZWZhdWx0U3Vic2NyaXB0U2l6aW5nID0gZGVmYXVsdE9wdGlvbnM/LnN1YnNjcmlwdFNpemluZyB8fCBNQVRfRk9STV9GSUVMRF9ERUZBVUxUX1NVQlNDUklQVF9TSVpJTkc7XG4gICAgdGhpcy5fZGVmYXVsdEFwcGVhcmFuY2UgPSBkZWZhdWx0T3B0aW9ucz8uYXBwZWFyYW5jZSB8fCBNQVRfRk9STV9GSUVMRF9ERUZBVUxUX0FQUEVBUkFOQ0U7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLm1vYmlsZSA9IHRoaXMubW9iaWxlID8/IGlzTW9iaWxlKHdpbmRvdyk7XG5cbiAgICBpZiAoaXNOaWwodGhpcy5wbGFjZWhvbGRlckNoYXIpKSB7XG4gICAgICB0aGlzLnBsYWNlaG9sZGVyQ2hhciA9IHRoaXMubW9iaWxlID8gU1BBQ0VfUExBQ0VIT0xERVJfQ0hBUiA6ICcnO1xuICAgIH1cblxuICAgIHRoaXMudHlwZSA9IHRoaXMudHlwZSB8fCAnbGF0aXR1ZGUnO1xuICAgIHRoaXMucGF0dGVybiA9IHRoaXMucGF0dGVybiB8fCAnRERNTSc7XG4gICAgdGhpcy5tYXNrID0gTUFTS1NbdGhpcy50eXBlXT8uW3RoaXMucGF0dGVybl07XG4gICAgaWYgKCF0aGlzLm1hc2spIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJJbnZhbGlkIGF0dHJpYnV0ZSB2YWx1ZS4gRXhwZWN0ZWQ6IHR5cGU6ICdsYXRpdHVkZXxsb25naXR1ZGUnIGFuZCBsYXRsb25nUGF0dGVybjogJ0REfERETU18RERNTVNTJ1wiKTtcbiAgICAgIHRoaXMudHlwZSA9ICdsYXRpdHVkZSc7XG4gICAgICB0aGlzLnBhdHRlcm4gPSAnRERNTSc7XG4gICAgICB0aGlzLm1hc2sgPSBNQVNLU1t0aGlzLnR5cGVdW3RoaXMucGF0dGVybl07XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIG1heERlY2ltYWxzIGhhcyBjb3JyZWN0IHZhbHVlIGRlcGVuZGluZyBvbiBwYXR0ZXJuIGFuZCBpdCdzIG93biB2YWx1ZVxuICAgIGlmICh0aGlzLnBhdHRlcm4gPT09ICdERCcpIHtcbiAgICAgIGlmICh0aGlzLm1heERlY2ltYWxzICE9IDcpIGNvbnNvbGUud2FybihgRm9yY2UgJ21heERlY2ltYWxzJyB0byBiZSAnNycgd2hlbiB1c2luZyB0aGUgJ0REJyBwYXR0ZXJuLmApO1xuICAgICAgdGhpcy5tYXhEZWNpbWFscyA9IDc7XG4gICAgfSBlbHNlIGlmICh0aGlzLnBhdHRlcm4gPT09ICdERE1NJykge1xuICAgICAgaWYgKHRoaXMubWF4RGVjaW1hbHMgIT0gMikgY29uc29sZS53YXJuKGBGb3JjZSAnbWF4RGVjaW1hbHMnIHRvIGJlICczJyB3aGVuIHVzaW5nIHRoZSAnRERNTScgcGF0dGVybi5gKTtcbiAgICAgIHRoaXMubWF4RGVjaW1hbHMgPSAzO1xuICAgIH0gZWxzZSBpZiAoaXNOaWwodGhpcy5tYXhEZWNpbWFscykpIHtcbiAgICAgIHRoaXMubWF4RGVjaW1hbHMgPSBERUZBVUxUX01BWF9ERUNJTUFMUztcbiAgICB9IGVsc2UgaWYgKHRoaXMubWF4RGVjaW1hbHMgPCAwKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiSW52YWxpZCBhdHRyaWJ1dGUgJ21heERlY2ltYWxzJy4gTXVzdCBhIHBvc2l0aXZlIHZhbHVlLlwiKTtcbiAgICAgIHRoaXMubWF4RGVjaW1hbHMgPSBERUZBVUxUX01BWF9ERUNJTUFMUztcbiAgICB9IGVsc2UgaWYgKHRoaXMubWF4RGVjaW1hbHMgIT09IERFRkFVTFRfTUFYX0RFQ0lNQUxTKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBJbnZhbGlkIGF0dHJpYnV0ZSAnbWF4RGVjaW1hbHMnIC0gRXhwZWN0ZWQgdmFsdWU6ICR7REVGQVVMVF9NQVhfREVDSU1BTFN9IGJ1dCBnZXQ6ICR7dGhpcy5tYXhEZWNpbWFsc30uIE90aGVyIHZhbHVlIG5vdCBpbXBsZW1lbnRlZC5gXG4gICAgICApO1xuICAgICAgdGhpcy5tYXhEZWNpbWFscyA9IERFRkFVTFRfTUFYX0RFQ0lNQUxTO1xuICAgIH1cblxuICAgIHRoaXMuc2hvd1NpZ25Db250cm9sID0gdGhpcy5wYXR0ZXJuICE9PSAnREQnO1xuXG4gICAgdGhpcy5fZm9ybWF0T3B0aW9ucyA9IHtcbiAgICAgIHBhdHRlcm46IHRoaXMucGF0dGVybixcbiAgICAgIG1heERlY2ltYWxzOiB0aGlzLm1heERlY2ltYWxzLFxuICAgICAgaGlkZVNpZ246IHRoaXMuc2hvd1NpZ25Db250cm9sLFxuICAgICAgaW5wdXRTZWxlY3Rpb25SYW5nZXM6IGdldElucHV0U2VsZWN0aW9uUmFuZ2VzRnJvbU1hc2sodGhpcy5tYXNrKSxcbiAgICAgIHBsYWNlaG9sZGVyQ2hhcjogdGhpcy5wbGFjZWhvbGRlckNoYXIsXG4gICAgfTtcblxuICAgIHRoaXMuaW5wdXRQbGFjZUhvbGRlckkxOG5LZXkgPSAnQ09NTU9OLkxBVF9MT05HLicgKyAoKHRoaXMudHlwZSA9PT0gJ2xvbmdpdHVkZScgJiYgJ0QnKSB8fCAnJykgKyB0aGlzLnBhdHRlcm4gKyAnX1BMQUNFSE9MREVSJztcblxuICAgIHRoaXMudGV4dEZvcm1Db250cm9sID0gdGhpcy5mb3JtQnVpbGRlci5jb250cm9sKHRoaXMucmVxdWlyZWQgPyBbbnVsbCwgVmFsaWRhdG9ycy5yZXF1aXJlZF0gOiBbbnVsbF0pO1xuXG4gICAgdGhpcy5zaWduRm9ybUNvbnRyb2wgPSB0aGlzLmZvcm1CdWlsZGVyLmNvbnRyb2wodGhpcy5yZXF1aXJlZCA/IFtudWxsLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSA6IFtudWxsXSk7XG5cbiAgICB0aGlzLmZvcm1Db250cm9sID1cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wgfHwgKHRoaXMuZm9ybUNvbnRyb2xOYW1lICYmIHRoaXMuZm9ybUdyb3VwRGlyICYmICh0aGlzLmZvcm1Hcm91cERpci5mb3JtLmdldCh0aGlzLmZvcm1Db250cm9sTmFtZSkgYXMgVW50eXBlZEZvcm1Db250cm9sKSk7XG4gICAgaWYgKCF0aGlzLmZvcm1Db250cm9sKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG1hbmRhdG9yeSBhdHRyaWJ1dGUgJ2Zvcm1Db250cm9sJyBvciAnZm9ybUNvbnRyb2xOYW1lJyBpbiA8bWF0LWxhdGxvbmctZmllbGQ+LlwiKTtcblxuICAgIGNvbnN0IGV4aXN0aW5nVmFsaWRhdG9ycyA9IHRoaXMuZm9ybUNvbnRyb2wudmFsaWRhdG9yO1xuICAgIGlmIChleGlzdGluZ1ZhbGlkYXRvcnMpIHtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyhbZXhpc3RpbmdWYWxpZGF0b3JzLCB0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyBTaGFyZWRWYWxpZGF0b3JzLmxhdGl0dWRlIDogU2hhcmVkVmFsaWRhdG9ycy5sb25naXR1ZGVdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWxpZGF0b3JzKHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/IFNoYXJlZFZhbGlkYXRvcnMubGF0aXR1ZGUgOiBTaGFyZWRWYWxpZGF0b3JzLmxvbmdpdHVkZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChtZXJnZSh0aGlzLnRleHRGb3JtQ29udHJvbC52YWx1ZUNoYW5nZXMsIHRoaXMuc2lnbkZvcm1Db250cm9sLnZhbHVlQ2hhbmdlcykuc3Vic2NyaWJlKCgpID0+IHRoaXMub25Gb3JtQ2hhbmdlKCkpKTtcblxuICAgIC8vIExpc3RlbiBzdGF0dXMgY2hhbmdlcyAod2hlbiBkb25lIG91dHNpZGUgdGhlIGNvbXBvbmVudCAgLSBlLmcuIHdoZW4gc2V0RXJyb3JzKCkgaXMgY2FsbGluZyBvbiB0aGUgZm9ybUNvbnRyb2wpXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc3RhdHVzQ2hhbmdlc1xuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKCkgPT4gIXRoaXMucmVhZG9ubHkgJiYgIXRoaXMuX3dyaXRpbmcgJiYgIXRoaXMuX2Rpc2FibGluZykgLy8gU2tpcFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5tYXJrRm9yQ2hlY2soKSlcbiAgICApO1xuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZCh0aGlzLnRyYW5zbGF0ZS5nZXQodGhpcy5pbnB1dFBsYWNlSG9sZGVySTE4bktleSkuc3Vic2NyaWJlKCh0cmFuc2xhdGlvbikgPT4gdGhpcy51cGRhdGVUcmFuc2xhdGlvbnModHJhbnNsYXRpb24pKSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHdyaXRlVmFsdWUob2JqOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fd3JpdGluZykgcmV0dXJuO1xuICAgIHRoaXMuX3dyaXRpbmcgPSB0cnVlO1xuXG4gICAgY29uc3QgdmFsdWUgPSB0eXBlb2Ygb2JqID09PSAnc3RyaW5nJyA/IHBhcnNlRmxvYXQob2JqLnJlcGxhY2UoLywvZywgJy4nKSkgOiBvYmo7XG4gICAgY29uc3QgZml4TGF0TG9uZyA9IHRoaXMuZm9ybUNvbnRyb2wudmFsaWQ7XG4gICAgY29uc3Qgc3RyVmFsdWUgPSB0aGlzLl9mb3JtYXQodmFsdWUsIHsgZml4TGF0TG9uZyB9KTtcblxuICAgIGNvbnN0IHNpZ24gPSBpc05vdE5pbCh2YWx1ZSlcbiAgICAgID8gdmFsdWUgPCAwXG4gICAgICAgID8gLTFcbiAgICAgICAgOiAxXG4gICAgICA6IC8vIFVzZSBkZWZhdWx0IHNpZ24sIGlmIGFueVxuICAgICAgICB0aGlzLmRlZmF1bHRTaWduXG4gICAgICAgID8gdGhpcy5kZWZhdWx0U2lnbiA9PT0gJy0nXG4gICAgICAgICAgPyAtMVxuICAgICAgICAgIDogMVxuICAgICAgICA6IG51bGw7XG5cbiAgICB0aGlzLnNpZ25Gb3JtQ29udHJvbC5wYXRjaFZhbHVlKHNpZ24sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgIC8vIFJlc2V0IHRoZSBmaWVsZFxuICAgICAgdGhpcy50ZXh0Rm9ybUNvbnRyb2wucGF0Y2hWYWx1ZShudWxsLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGV4dEZvcm1Db250cm9sLnBhdGNoVmFsdWUoc3RyVmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl93cml0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9vblRvdWNoZWRDYWxsYmFjayA9IGZuO1xuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2Rpc2FibGluZykgcmV0dXJuO1xuXG4gICAgdGhpcy5fZGlzYWJsaW5nID0gdHJ1ZTtcbiAgICBpZiAoaXNEaXNhYmxlZCkge1xuICAgICAgdGhpcy50ZXh0Rm9ybUNvbnRyb2wuZGlzYWJsZSh7IG9ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgdGhpcy5zaWduRm9ybUNvbnRyb2wuZGlzYWJsZSh7IG9ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRleHRGb3JtQ29udHJvbC5lbmFibGUoeyBvbmx5U2VsZjogdHJ1ZSwgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgIHRoaXMuc2lnbkZvcm1Db250cm9sLmVuYWJsZSh7IG9ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cbiAgICB0aGlzLl9kaXNhYmxpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgX29uRm9jdXMoZXZlbnQ6IEZvY3VzRXZlbnQpIHtcbiAgICB0aGlzLmhhc0ZvY3VzID0gdHJ1ZTtcbiAgICBjb25zdCBmcm9tVGFiS2V5ID0gaXNOb3ROaWwoZXZlbnQucmVsYXRlZFRhcmdldCk7XG4gICAgY29uc3QgZml4TGF0TG9uZyA9IHRoaXMuZm9ybUNvbnRyb2wudmFsaWQ7XG5cbiAgICBsZXQgc3RyVmFsdWUgPVxuICAgICAgZm9ybWF0TGF0TG9uZyh0aGlzLmZvcm1Db250cm9sLnZhbHVlLCB0aGlzLnR5cGUsIHsgLi4udGhpcy5fZm9ybWF0T3B0aW9ucywgcGxhY2Vob2xkZXJDaGFyOiAnMCcsIGZpeExhdExvbmcgfSkgPz8gdGhpcy5tYXNraXRvUGxhY2Vob2xkZXI7XG5cbiAgICBpZiAoc3RyVmFsdWUuc3RhcnRzV2l0aCgnwrEnKSkge1xuICAgICAgc3RyVmFsdWUgPSBzdHJWYWx1ZS5yZXBsYWNlKCfCsScsIHRoaXMuZGVmYXVsdFNpZ24pO1xuICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJykge1xuICAgICAgICB0aGlzLnRleHRGb3JtQ29udHJvbC5zZXRWYWx1ZShzdHJWYWx1ZSArICcgJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRleHRGb3JtQ29udHJvbC5zZXRWYWx1ZShzdHJWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy50ZXh0Rm9ybUNvbnRyb2wuc2V0VmFsdWUoc3RyVmFsdWUpO1xuICAgIC8vIElmIGZvY3VzIGNhbWUgZm9ybSBwdXNoIHRhYiBrZXkgYW5kIHRoZSBpbnB1dCBoYXMgdmFsdWUsIHNlbGVjdCBhbGwgdGhlIHZhbHVlXG4gICAgaWYgKGZyb21UYWJLZXkgJiYgc3RyVmFsdWUucmVwbGFjZSgvXlvCsSstXS8sICcnKSAhPT0gdGhpcy5tYXNraXRvUGxhY2Vob2xkZXIucmVwbGFjZSgvXlvCsSstXS8sICcnKSkge1xuICAgICAgY29uc3Qgc3RyVmFsdWVXaXRob3V0U2lnbiA9IHN0clZhbHVlLnJlcGxhY2UoL15bwrErLV0vLCAnJyk7XG4gICAgICBpZiAoc3RyVmFsdWVXaXRob3V0U2lnbiAhPT0gdGhpcy5tYXNraXRvUGxhY2Vob2xkZXIucmVwbGFjZSgvXlvCsSstXS8sICcnKSkge1xuICAgICAgICAvLyBoYXMgdmFsdWVcbiAgICAgICAgc2VsZWN0SW5wdXRSYW5nZShldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCwgc3RyVmFsdWUubGVuZ3RoIC0gc3RyVmFsdWVXaXRob3V0U2lnbi5sZW5ndGgsIHN0clZhbHVlV2l0aG91dFNpZ24ubGVuZ3RoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm9uRm9jdXMuZW1pdChldmVudCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBfb25CbHVyKGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgdGhpcy5oYXNGb2N1cyA9IGZhbHNlO1xuICAgIGxldCBzdHJWYWx1ZSA9IHRoaXMudGV4dEZvcm1Db250cm9sLnZhbHVlO1xuXG4gICAgLy8gUmVzZXQgbWFzayBpZiB2YWx1ZSBpcyBlbXB0eVxuICAgIGlmICghL1xcZC8udGVzdChzdHJWYWx1ZSkpIHtcbiAgICAgIHN0clZhbHVlID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJzZWRWYWx1ZSA9IHRoaXMucGFyc2VWYWx1ZShzdHJWYWx1ZSk7XG4gICAgdGhpcy5mb3JtQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5mb3JtQ29udHJvbC5wYXRjaFZhbHVlKHBhcnNlZFZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICB0aGlzLm9uQmx1ci5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZm9ybWF0KHZhbHVlOiBudW1iZXIsIG9wdHM6IFBhcnRpYWw8TGF0TG9uZ0Zvcm1hdE9wdGlvbnM+ID0ge30pOiBzdHJpbmcge1xuICAgIHJldHVybiBmb3JtYXRMYXRMb25nKHZhbHVlLCB0aGlzLnR5cGUsIHsgLi4udGhpcy5fZm9ybWF0T3B0aW9ucywgLi4ub3B0cyB9KSA/PyB0aGlzLm1hc2tpdG9QbGFjZWhvbGRlcjtcbiAgfVxuXG4gIHByb3RlY3RlZCBfY2hlY2tJZlRvdWNoZWQoKSB7XG4gICAgaWYgKHRoaXMudGV4dEZvcm1Db250cm9sLnRvdWNoZWQpIHtcbiAgICAgIHRoaXMuX29uVG91Y2hlZENhbGxiYWNrKCk7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIC8qIC0tIHByaXZhdGUgbWV0aG9kIC0tICovXG5cbiAgcHJpdmF0ZSBvbkZvcm1DaGFuZ2UoKSB7XG4gICAgaWYgKHRoaXMuX3dyaXRpbmcpIHJldHVybjsgLy8gU2tpcCBpZiBjYWxsIGJ5IHNlbGZcbiAgICB0aGlzLl93cml0aW5nID0gdHJ1ZTtcblxuICAgIGxldCBzdHJWYWx1ZSA9IHRoaXMudGV4dEZvcm1Db250cm9sLnZhbHVlO1xuXG4gICAgLy8gUmVzZXQgbWFzayBpZiB2YWx1ZSBpcyBlbXB0eVxuICAgIGlmICghL1xcZC8udGVzdChzdHJWYWx1ZSkpIHtcbiAgICAgIHN0clZhbHVlID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJzZWRWYWx1ZSA9IHRoaXMucGFyc2VWYWx1ZShzdHJWYWx1ZSk7XG5cbiAgICB0aGlzLmVtaXRDaGFuZ2UocGFyc2VkVmFsdWUpO1xuXG4gICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDaGFuZ2UodmFsdWU6IG51bWJlcikge1xuICAgIGNvbnN0IGZvcm1Db250cm9sVmFsdWUgPSB0aGlzLmZvcm1Db250cm9sLnZhbHVlO1xuXG4gICAgaWYgKGZvcm1Db250cm9sVmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICBpZiAodGhpcy50ZXh0Rm9ybUNvbnRyb2wudmFsaWQpIHtcbiAgICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWx1ZSh2YWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKHZhbHVlKTtcbiAgICAgICAgdGhpcy5fY2hlY2tJZlRvdWNoZWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVRyYW5zbGF0aW9ucyh0cmFuc2xhdGlvbjogc3RyaW5nKSB7XG4gICAgLy8gTm8gY2hhbmdlXG4gICAgaWYgKHRoaXMubWFza2l0b1BsYWNlaG9sZGVyID09PSB0cmFuc2xhdGlvbikgcmV0dXJuO1xuICAgIC8vIFRyYW5zbGF0aW9uIGZhbGxiYWNrXG4gICAgaWYgKHRoaXMuaW5wdXRQbGFjZUhvbGRlckkxOG5LZXkgPT09IHRyYW5zbGF0aW9uKSB7XG4gICAgICBzd2l0Y2ggKHRoaXMucGF0dGVybikge1xuICAgICAgICBjYXNlICdERCc6XG4gICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ2xvbmdpdHVkZScpIHtcbiAgICAgICAgICAgIHRoaXMubWFza2l0b1BsYWNlaG9sZGVyID0gJ8KxRERELkRERERERETCsCc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubWFza2l0b1BsYWNlaG9sZGVyID0gJ8KxIERELkRERERERETCsCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdERE1NJzpcbiAgICAgICAgICBpZiAodGhpcy50eXBlID09PSAnbG9uZ2l0dWRlJykge1xuICAgICAgICAgICAgdGhpcy5tYXNraXRvUGxhY2Vob2xkZXIgPSBcIkRERMKwIE1NLk1NTSdcIjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tYXNraXRvUGxhY2Vob2xkZXIgPSBcIkREwrAgTU0uTU1NJ1wiO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRERNTVNTJzpcbiAgICAgICAgICBpZiAodGhpcy50eXBlID09PSAnbG9uZ2l0dWRlJykge1xuICAgICAgICAgICAgdGhpcy5tYXNraXRvUGxhY2Vob2xkZXIgPSAnREREwrAgTU1cXCcgU1MuU1NcIic7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubWFza2l0b1BsYWNlaG9sZGVyID0gJ0REwrAgTU1cXCcgU1MuU1NcIic7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm1hc2tpdG9QbGFjZWhvbGRlciA9IHRyYW5zbGF0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVZhbHVlKHN0clZhbHVlOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGxldCBwYXJzZWRWYWx1ZTogbnVtYmVyO1xuICAgIGlmIChpc05vdE5pbE9yQmxhbmsoc3RyVmFsdWUpKSB7XG4gICAgICBpZiAodGhpcy5wYXR0ZXJuID09PSAnREQnKSB7XG4gICAgICAgIHBhcnNlZFZhbHVlID0gcGFyc2VMYXRpdHVkZU9yTG9uZ2l0dWRlKHN0clZhbHVlLCB0aGlzLnBhdHRlcm4sIDcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc2lnbiA9IHRoaXMuc2lnbkZvcm1Db250cm9sLnZhbHVlIHx8IHRoaXMuZGVmYXVsdFNpZ24gPT09ICctJyA/IC0xIDogMTtcbiAgICAgICAgcGFyc2VkVmFsdWUgPSBzaWduICogcGFyc2VMYXRpdHVkZU9yTG9uZ2l0dWRlKHN0clZhbHVlLCB0aGlzLnBhdHRlcm4sIDcpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJzZWRWYWx1ZSA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGF0dGVybiAhPT0gJ0REJyAmJiBwYXJzZWRWYWx1ZSAhPT0gbnVsbCkge1xuICAgICAgY29uc3Qgc2lnbiA9IHRoaXMuc2lnbkZvcm1Db250cm9sLnZhbHVlO1xuICAgICAgcGFyc2VkVmFsdWUgPSBzaWduICogTWF0aC5hYnMocGFyc2VkVmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWRWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiIsIjwhLS0gcmVhZG9ubHkgLS0+XG48bWF0LWZvcm0tZmllbGRcbiAgKm5nSWY9XCJyZWFkb25seTsgZWxzZSB3cml0YWJsZVwiXG4gIFtmbG9hdExhYmVsXT1cImZsb2F0TGFiZWwgfCBhc0Zsb2F0TGFiZWxUeXBlXCJcbiAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gIFtzdWJzY3JpcHRTaXppbmddPVwic3Vic2NyaXB0U2l6aW5nXCJcbiAgY2xhc3M9XCJtYXQtZm9ybS1maWVsZC1kaXNhYmxlZFwiXG4+XG4gIDxkaXYgbWF0UHJlZml4PlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRQcmVmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cblxuICBAaWYgKGZsb2F0TGFiZWwgIT09ICduZXZlcicgJiYgISFwbGFjZWhvbGRlcikge1xuICAgIDxtYXQtbGFiZWw+e3sgcGxhY2Vob2xkZXIgfX08L21hdC1sYWJlbD5cbiAgfVxuXG4gIDxpbnB1dCBtYXRJbnB1dCBoaWRkZW4gdHlwZT1cInRleHRcIiByZWFkb25seSBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xcIiAvPlxuICA8aW9uLXRleHQ+e3sgX2Zvcm1hdChmb3JtQ29udHJvbC52YWx1ZSkgfX08L2lvbi10ZXh0PlxuXG4gIDxkaXYgbWF0U3VmZml4PlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRTdWZmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cblxuICA8IS0tIGhpbnRzIC0tPlxuICA8bWF0LWhpbnQgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiZm9ybUNvbnRyb2wuaW52YWxpZFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRIaW50VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9tYXQtaGludD5cbjwvbWF0LWZvcm0tZmllbGQ+XG5cbjwhLS0gd3JpdGFibGUgLS0+XG48bmctdGVtcGxhdGUgI3dyaXRhYmxlPlxuICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZyB7eyBhcHBlYXJhbmNlIH19XCI+XG4gICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZyBuby13cmFwXCI+XG4gICAgICA8aW9uLWNvbCBjbGFzcz1cInRleHQgaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgW2Zsb2F0TGFiZWxdPVwiZmxvYXRMYWJlbCB8IGFzRmxvYXRMYWJlbFR5cGVcIlxuICAgICAgICAgIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIlxuICAgICAgICAgIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCJcbiAgICAgICAgICBbY2xhc3MubWRjLXRleHQtZmllbGQtLWludmFsaWRdPVwiZm9ybUNvbnRyb2wudG91Y2hlZCAmJiAoc2lnbkZvcm1Db250cm9sLmludmFsaWQgfHwgZm9ybUNvbnRyb2wuaW52YWxpZClcIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiBtYXRQcmVmaXg+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0UHJlZml4VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxtYXQtbGFiZWwgKm5nSWY9XCJmbG9hdExhYmVsICE9PSAnbmV2ZXInICYmICEhcGxhY2Vob2xkZXJcIj57eyBwbGFjZWhvbGRlciB9fTwvbWF0LWxhYmVsPlxuXG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgI2lucHV0RWxlbWVudFxuICAgICAgICAgICAgW21hc2tpdG9dPVwibWFza2l0b1BsYWNlaG9sZGVyIHwgbWFza2l0b1BsYWNlaG9sZGVyOiBtYXNrXCJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgKGJsdXIpPVwiX29uQmx1cigkZXZlbnQpXCJcbiAgICAgICAgICAgIChmb2N1cyk9XCJfb25Gb2N1cygkZXZlbnQpXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJ0ZXh0Rm9ybUNvbnRyb2xcIlxuICAgICAgICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcbiAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleFwiXG4gICAgICAgICAgICBbYXBwQXV0b2ZvY3VzXT1cImF1dG9mb2N1c1wiXG4gICAgICAgICAgLz5cblxuICAgICAgICAgIEBpZiAoIXNob3dTaWduQ29udHJvbCkge1xuICAgICAgICAgICAgPGRpdiBtYXRTdWZmaXg+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRTdWZmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgPC9pb24tY29sPlxuXG4gICAgICA8IS0tIHNpZ24gLS0+XG4gICAgICBAaWYgKHNob3dTaWduQ29udHJvbCkge1xuICAgICAgICA8aW9uLWNvbCBjbGFzcz1cInNpZ24gaW9uLW5vLXBhZGRpbmcge3sgdHlwZSB9fVwiPlxuICAgICAgICAgIEBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIEBjYXNlICgnbGF0aXR1ZGUnKSB7XG4gICAgICAgICAgICAgIDwhLS0gc2lnbiBvbiBsYXRpdHVkZSAtLT5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgICAgICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgICAgICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5tZGMtdGV4dC1maWVsZC0taW52YWxpZF09XCJmb3JtQ29udHJvbC50b3VjaGVkICYmIHNpZ25Gb3JtQ29udHJvbC5pbnZhbGlkXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwic2lnbkZvcm1Db250cm9sXCJcbiAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInQ09NTU9OLkxBVF9MT05HLkxBVF9TSUdOX1BMQUNFSE9MREVSJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXggIT09IHVuZGVmaW5lZCA/IHRhYmluZGV4ICsgMSA6IHVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIjFcIj57eyAnQ09NTU9OLkxBVF9MT05HLkxBVF9TSUdOX04nIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIi0xXCI+e3sgJ0NPTU1PTi5MQVRfTE9ORy5MQVRfU0lHTl9TJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IG1hdFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRTdWZmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdsb25naXR1ZGUnKSB7XG4gICAgICAgICAgICAgIDwhLS0gc2lnbiBvbiBsb25naXR1ZGUgLS0+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZFxuICAgICAgICAgICAgICAgIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIlxuICAgICAgICAgICAgICAgIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MubWRjLXRleHQtZmllbGQtLWludmFsaWRdPVwiZm9ybUNvbnRyb2wudG91Y2hlZCAmJiBzaWduRm9ybUNvbnRyb2wuaW52YWxpZFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInNpZ25Gb3JtQ29udHJvbFwiXG4gICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0NPTU1PTi5MQVRfTE9ORy5MT05HX1NJR05fUExBQ0VIT0xERVInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleCAhPT0gdW5kZWZpbmVkID8gdGFiaW5kZXggKyAxIDogdW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiMVwiIHRyYW5zbGF0ZT57eyAnQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9FJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCItMVwiIHRyYW5zbGF0ZT57eyAnQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9XJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IG1hdFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRTdWZmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgPC9pb24tY29sPlxuICAgICAgfVxuICAgIDwvaW9uLXJvdz5cbiAgPC9pb24tZ3JpZD5cblxuICA8IS0tIERvIHRoZSBzYW1lIGFzIE1hdEZyb21GaWVsZCBzaW5jZSBhbmd1bGFyIDE1IChzZWUgY29tcG9uZW50IHNvdXJjZSktLT5cbiAgPGRpdlxuICAgIGNsYXNzPVwibWF0LW1kYy1mb3JtLWZpZWxkLXN1YnNjcmlwdC13cmFwcGVyXCJcbiAgICBbY2xhc3MubWF0LW1kYy1mb3JtLWZpZWxkLWJvdHRvbS1hbGlnbl09XCJzdWJzY3JpcHRTaXppbmcgPT09ICdmaXhlZCdcIlxuICAgIFtjbGFzcy5tYXQtbWRjLWZvcm0tZmllbGQtc3Vic2NyaXB0LWR5bmFtaWMtc2l6ZV09XCJzdWJzY3JpcHRTaXppbmcgPT09ICdkeW5hbWljJ1wiXG4gID5cbiAgICBAaWYgKGZvcm1Db250cm9sLnRvdWNoZWQgJiYgZm9ybUNvbnRyb2wuaW52YWxpZCkge1xuICAgICAgPCEtLSBlcnJvcnMgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwibWF0LW1kYy1mb3JtLWZpZWxkLWVycm9yLXdyYXBwZXJcIj5cbiAgICAgICAgQGlmIChmb3JtQ29udHJvbC5lcnJvcnMgfCBtYXBLZXlzIHwgYXJyYXlGaXJzdDsgYXMgZXJyb3JLZXkpIHtcbiAgICAgICAgICBAc3dpdGNoIChlcnJvcktleSkge1xuICAgICAgICAgICAgQGNhc2UgKCdyZXF1aXJlZCcpIHtcbiAgICAgICAgICAgICAgPG1hdC1lcnJvciB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRUQ8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnbGF0aXR1ZGUnKSB7XG4gICAgICAgICAgICAgIDxtYXQtZXJyb3IgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX05PVF9WQUxJRF9MQVRJVFVERTwvbWF0LWVycm9yPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdsb25naXR1ZGUnKSB7XG4gICAgICAgICAgICAgIDxtYXQtZXJyb3IgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX05PVF9WQUxJRF9MT05HSVRVREU8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnbWluJykge1xuICAgICAgICAgICAgICA8bWF0LWVycm9yPlxuICAgICAgICAgICAgICAgIHt7ICdFUlJPUi5GSUVMRF9NSU5fQ09NUEFDVCcgfCB0cmFuc2xhdGU6IHsgbWluOiBfZm9ybWF0KGZvcm1Db250cm9sLmVycm9ycy5taW4ubWluKSB9IH19XG4gICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdtYXgnKSB7XG4gICAgICAgICAgICAgIDxtYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAge3sgJ0VSUk9SLkZJRUxEX01BWF9DT01QQUNUJyB8IHRyYW5zbGF0ZTogeyBtYXg6IF9mb3JtYXQoZm9ybUNvbnRyb2wuZXJyb3JzLm1heC5tYXgpIH0gfX1cbiAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAY2FzZSAoJ21zZycpIHtcbiAgICAgICAgICAgICAgPG1hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICB7eyBmb3JtQ29udHJvbC5lcnJvcnMubXNnPy5rZXkgfHwgZm9ybUNvbnRyb2wuZXJyb3JzLm1zZyB8IHRyYW5zbGF0ZTogZm9ybUNvbnRyb2wuZXJyb3JzLm1zZz8ucGFyYW1zIH19XG4gICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0RXJyb3JUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdEVycm9yVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSB7XG4gICAgICA8IS0tIGhpbnRzIC0tPlxuICAgICAgPG1hdC1oaW50PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0SGludFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L21hdC1oaW50PlxuICAgIH1cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI21hdFByZWZpeFRlbXBsYXRlPlxuICA8bmctY29udGVudCBzZWxlY3Q9XCJbbWF0UHJlZml4XVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0U3VmZml4VGVtcGxhdGU+XG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIlttYXRTdWZmaXhdXCI+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNtYXRFcnJvclRlbXBsYXRlPlxuICA8bmctY29udGVudCBzZWxlY3Q9XCJtYXQtZXJyb3IsW21hdEVycm9yXVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0SGludFRlbXBsYXRlPlxuICA8ZGl2IGNsYXNzPVwibWF0LW1kYy1mb3JtLWZpZWxkLWhpbnQtd3JhcHBlclwiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm1hdC1oaW50Om5vdChbYWxpZ249J2VuZCddKSxbbWF0SGludF1cIj48L25nLWNvbnRlbnQ+XG4gICAgPGRpdiBjbGFzcz1cIm1hdC1tZGMtZm9ybS1maWVsZC1oaW50LXNwYWNlclwiPjwvZGl2PlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm1hdC1oaW50W2FsaWduPSdlbmQnXVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
617
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwubGF0bG9uZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL21hdGVyaWFsL2xhdGxvbmcvbWF0ZXJpYWwubGF0bG9uZy50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL21hdGVyaWFsL2xhdGxvbmcvbWF0ZXJpYWwubGF0bG9uZy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLGVBQWUsRUFHZixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLFdBQVcsRUFBc0IsaUJBQWlCLEVBQXNCLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUgsT0FBTyxFQUNMLDhCQUE4QixHQUsvQixNQUFNLDhCQUE4QixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QyxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLHVDQUF1QyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDaEgsT0FBTyxFQUNMLHFCQUFxQixFQUNyQiw2QkFBNkIsRUFDN0IsMkJBQTJCLEVBRzNCLHFCQUFxQixFQUNyQix1QkFBdUIsRUFDdkIseUJBQXlCLEdBQzFC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LE9BQU87Z0JBRTZCLFFBQVE7c0JBQWxELEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFO2dCQVlqQyxVQUFVO3NCQURiLEtBQUs7Z0JBU08sUUFBUTtzQkFBcEIsS0FBSztnQkFVRixlQUFlO3NCQURsQixLQUFLO2dCQWtCaUIsVUFBVTtzQkFBaEMsTUFBTTt1QkFBQyxhQUFhO2dCQUVMLE9BQU87c0JBQXRCLE1BQU07dUJBQUMsTUFBTTtnQkFFRyxPQUFPO3NCQUF2QixNQUFNO3VCQUFDLE9BQU87Z0JBRVMsU0FBUztzQkFBaEMsU0FBUzt1QkFBQyxXQUFXO2dCQUNFLFNBQVM7c0JBQWhDLFNBQVM7dUJBQUMsV0FBVztnQkFDSyxZQUFZO3NCQUF0QyxTQUFTO3VCQUFDLGNBQWM7Z0JBQ0UsWUFBWTtzQkFBdEMsU0FBUzt1QkFBQyxjQUFjO2dCQUNFLFlBQVk7c0JBQXRDLFNBQVM7dUJBQUMsY0FBYztnQkFDcUIsU0FBUztzQkFBdEQsU0FBUzt1QkFBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUNDLGVBQWU7c0JBQTNELFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIG51bWJlckF0dHJpYnV0ZSxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cERpcmVjdGl2ZSwgTkdfVkFMVUVfQUNDRVNTT1IsIFVudHlwZWRGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfT1BUSU9OUyxcbiAgTWF0Rm9ybUZpZWxkLFxuICBNYXRGb3JtRmllbGRBcHBlYXJhbmNlLFxuICBNYXRGb3JtRmllbGREZWZhdWx0T3B0aW9ucyxcbiAgU3Vic2NyaXB0U2l6aW5nLFxufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IG1lcmdlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFwcEZsb2F0TGFiZWxUeXBlIH0gZnJvbSAnLi4vLi4vZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBpc05pbCwgaXNOaWxPckJsYW5rLCBpc05vdE5pbCB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBpc01vYmlsZSB9IGZyb20gJy4uLy4uL3BsYXRmb3Jtcyc7XG5pbXBvcnQgeyBTaGFyZWRWYWxpZGF0b3JzIH0gZnJvbSAnLi4vLi4vdmFsaWRhdG9yL3ZhbGlkYXRvcnMnO1xuaW1wb3J0IHsgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9BUFBFQVJBTkNFLCBNQVRfRk9STV9GSUVMRF9ERUZBVUxUX1NVQlNDUklQVF9TSVpJTkcgfSBmcm9tICcuLi9tYXRlcmlhbC5jb25maWcnO1xuaW1wb3J0IHtcbiAgY29tcHV0ZURlY2ltYWxEZWdyZWVzLFxuICBMQVRfTE9OR19QQVRURVJOX01BWF9ERUNJTUFMUyxcbiAgTEFUX0xPTkdfVkFMVUVfTUFYX0RFQ0lNQUxTLFxuICBMYXRMb25nUGF0dGVybixcbiAgTGF0TG9uZ1R5cGUsXG4gIHNwbGl0TnVtYmVyVG9GaWVsZHNERCxcbiAgc3BsaXROdW1iZXJUb0ZpZWxkc0RETU0sXG4gIHNwbGl0TnVtYmVyVG9GaWVsZHNERE1NU1MsXG59IGZyb20gJy4vbGF0bG9uZy51dGlscyc7XG5pbXBvcnQgeyBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgc2VsZWN0SW5wdXRDb250ZW50IH0gZnJvbSAnLi4vLi4vaW5wdXRzJztcbmltcG9ydCB7IG1hc2tpdG9OdW1iZXJPcHRpb25zR2VuZXJhdG9yIH0gZnJvbSAnQG1hc2tpdG8va2l0JztcbmltcG9ydCB7IE1hc2tpdG9PcHRpb25zIH0gZnJvbSAnQG1hc2tpdG8vY29yZSc7XG5cbmNvbnN0IG5vb3AgPSAoKSA9PiB7fTtcblxuZGVjbGFyZSB0eXBlIExhdExvbmdTaWduID0gMSB8IC0xO1xuXG5pbnRlcmZhY2UgSUxhdExvbmdEYXRhIHtcbiAgZGVncmVlczogbnVtYmVyO1xuICBtaW51dGVzOiBudW1iZXI7XG4gIHNlY29uZHM6IG51bWJlcjtcbiAgc2lnbjogTGF0TG9uZ1NpZ247XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21hdC1sYXRsb25nLWZpZWxkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL21hdGVyaWFsLmxhdGxvbmcuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL21hdGVyaWFsLmxhdGxvbmcuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTWF0TGF0TG9uZ0ZpZWxkKSxcbiAgICB9LFxuICBdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgTWF0TGF0TG9uZ0ZpZWxkIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgcHJpdmF0ZSBfb25DaGFuZ2VDYWxsYmFjazogKF86IGFueSkgPT4gdm9pZCA9IG5vb3A7XG4gIHByaXZhdGUgX29uVG91Y2hlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gbm9vcDtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIF9kaXNhYmxpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfd3JpdGluZyA9IGZhbHNlO1xuICBwcml2YXRlIF9hcHBlYXJhbmNlOiBNYXRGb3JtRmllbGRBcHBlYXJhbmNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX3N1YnNjcmlwdFNpemluZzogU3Vic2NyaXB0U2l6aW5nIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX3JlYWRvbmx5ID0gZmFsc2U7XG4gIHByaXZhdGUgX3RhYmluZGV4OiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRBcHBlYXJhbmNlOiBNYXRGb3JtRmllbGRBcHBlYXJhbmNlO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0U3Vic2NyaXB0U2l6aW5nOiBTdWJzY3JpcHRTaXppbmc7XG5cbiAgcHJvdGVjdGVkIF9mb2N1c2VkID0gZmFsc2U7XG4gIHByb3RlY3RlZCBfdG91Y2hlZCA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgZGVncmVlc0NvbnRyb2w6IEZvcm1Db250cm9sPHN0cmluZz47XG4gIHByb3RlY3RlZCBtaW51dGVzQ29udHJvbDogRm9ybUNvbnRyb2w8c3RyaW5nPjtcbiAgcHJvdGVjdGVkIHNlY29uZHNDb250cm9sOiBGb3JtQ29udHJvbDxzdHJpbmc+O1xuICBwcm90ZWN0ZWQgc2lnbkNvbnRyb2w6IEZvcm1Db250cm9sPExhdExvbmdTaWduPjtcbiAgcHJvdGVjdGVkIHNob3dNaW51dGVzID0gZmFsc2U7XG4gIHByb3RlY3RlZCBzaG93U2Vjb25kcyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgc2hvd1NpZ25Db250cm9sOiBib29sZWFuO1xuICBwcm90ZWN0ZWQgZGVncmVlc1BsYWNlaG9sZGVyOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBtaW51dGVzUGxhY2Vob2xkZXI6IHN0cmluZztcbiAgcHJvdGVjdGVkIHNlY29uZHNQbGFjZWhvbGRlcjogc3RyaW5nO1xuICBwcm90ZWN0ZWQgZGVncmVlc01hc2s6IE1hc2tpdG9PcHRpb25zO1xuICBwcm90ZWN0ZWQgbWludXRlc01hc2s6IE1hc2tpdG9PcHRpb25zO1xuICBwcm90ZWN0ZWQgc2Vjb25kc01hc2s6IE1hc2tpdG9PcHRpb25zO1xuICBwcm90ZWN0ZWQgcGF0dGVybk1heERlY2ltYWxzID0gTEFUX0xPTkdfUEFUVEVSTl9NQVhfREVDSU1BTFM7XG4gIHByb3RlY3RlZCBpMThuRXJyb3JLZXlzID0gU2hhcmVkVmFsaWRhdG9ycy5JMThOX0VSUk9SX0tFWVM7XG5cbiAgQElucHV0KCkgZm9ybUNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbDtcbiAgQElucHV0KCkgZm9ybUNvbnRyb2xOYW1lOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHR5cGU6IExhdExvbmdUeXBlO1xuICBASW5wdXQoJ2xhdExvbmdQYXR0ZXJuJykgcGF0dGVybjogTGF0TG9uZ1BhdHRlcm47XG4gIEBJbnB1dCgpIG1heERlY2ltYWxzOiBudW1iZXIgPSBMQVRfTE9OR19WQUxVRV9NQVhfREVDSU1BTFM7XG4gIEBJbnB1dCgpIHJlcXVpcmVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIGZsb2F0TGFiZWw6IEFwcEZsb2F0TGFiZWxUeXBlID0gJ2F1dG8nO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nO1xuICBASW5wdXQoKSBkZWZhdWx0U2lnbjogJy0nIHwgJysnO1xuICBASW5wdXQoKSBhdXRvZm9jdXMgPSBmYWxzZTtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIG1vYmlsZTogYm9vbGVhbjtcbiAgQElucHV0KCkgZGVncmVlc1N5bWJvbFVuaXQgPSAnwrAnO1xuICBASW5wdXQoKSBtaW51dGVzU3ltYm9sVW5pdCA9IFwiJ1wiO1xuICBASW5wdXQoKSBzZWNvbmRzU3ltYm9sVW5pdCA9ICdcIic7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBjbGVhcmFibGUgPSBmYWxzZTtcbiAgQElucHV0KCdjbGFzcycpIGNsYXNzTGlzdDogc3RyaW5nO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlIH0pIHNldCB0YWJpbmRleCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuX3RhYmluZGV4ICE9PSB2YWx1ZSkge1xuICAgICAgdGhpcy5fdGFiaW5kZXggPSB2YWx1ZTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy51cGRhdGVUYWJJbmRleCgpKTtcbiAgICB9XG4gIH1cblxuICBnZXQgdGFiaW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdGFiaW5kZXg7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgYXBwZWFyYW5jZSh2YWx1ZTogTWF0Rm9ybUZpZWxkQXBwZWFyYW5jZSkge1xuICAgIHRoaXMuX2FwcGVhcmFuY2UgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBhcHBlYXJhbmNlKCk6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2Uge1xuICAgIHJldHVybiB0aGlzLl9hcHBlYXJhbmNlIHx8IHRoaXMuX2RlZmF1bHRBcHBlYXJhbmNlO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IHJlYWRvbmx5KHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fcmVhZG9ubHkgPSB2YWx1ZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZ2V0IHJlYWRvbmx5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9yZWFkb25seTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCBzdWJzY3JpcHRTaXppbmcodmFsdWU6IFN1YnNjcmlwdFNpemluZykge1xuICAgIHRoaXMuX3N1YnNjcmlwdFNpemluZyA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHN1YnNjcmlwdFNpemluZygpOiBTdWJzY3JpcHRTaXppbmcge1xuICAgIHJldHVybiB0aGlzLl9zdWJzY3JpcHRTaXppbmcgfHwgdGhpcy5fZGVmYXVsdFN1YnNjcmlwdFNpemluZztcbiAgfVxuXG4gIGdldCBzaG93RmllbGRzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05vdE5pbCh0aGlzLmZvcm1Db250cm9sLnZhbHVlKSB8fCB0aGlzLl9mb2N1c2VkO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZG9ubHkgfHwgdGhpcy5mb3JtQ29udHJvbC5kaXNhYmxlZDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LW9uLXByZWZpeCxAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LXJlbmFtZVxuICBAT3V0cHV0KCdrZXl1cC5lbnRlcicpIGtleXVwRW50ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtcmVuYW1lXG4gIEBPdXRwdXQoJ2JsdXInKSBibHVycmVkID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1yZW5hbWVcbiAgQE91dHB1dCgnZm9jdXMnKSBmb2N1c2VkID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2Zvcm1GaWVsZCcpIGZvcm1GaWVsZDogTWF0Rm9ybUZpZWxkO1xuICBAVmlld0NoaWxkKCdmYWtlSW5wdXQnKSBmYWtlSW5wdXQ6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0RGVncmVlcycpIGlucHV0RGVncmVlczogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnaW5wdXRNaW51dGVzJykgaW5wdXRNaW51dGVzOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdpbnB1dFNlY29uZHMnKSBpbnB1dFNlY29uZHM6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0U2lnbicsIHsgcmVhZDogRWxlbWVudFJlZiB9KSBpbnB1dFNpZ246IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0U2lnbicsIHsgcmVhZDogTWF0U2VsZWN0IH0pIGlucHV0U2lnblNlbGVjdDogTWF0U2VsZWN0O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZm9ybUdyb3VwRGlyOiBGb3JtR3JvdXBEaXJlY3RpdmUsXG4gICAgQEluamVjdChNQVRfRk9STV9GSUVMRF9ERUZBVUxUX09QVElPTlMpIGRlZmF1bHRPcHRpb25zPzogTWF0Rm9ybUZpZWxkRGVmYXVsdE9wdGlvbnNcbiAgKSB7XG4gICAgdGhpcy5fZGVmYXVsdFN1YnNjcmlwdFNpemluZyA9IGRlZmF1bHRPcHRpb25zPy5zdWJzY3JpcHRTaXppbmcgfHwgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9TVUJTQ1JJUFRfU0laSU5HO1xuICAgIHRoaXMuX2RlZmF1bHRBcHBlYXJhbmNlID0gZGVmYXVsdE9wdGlvbnM/LmFwcGVhcmFuY2UgfHwgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9BUFBFQVJBTkNFO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5tb2JpbGUgPSB0aGlzLm1vYmlsZSA/PyBpc01vYmlsZSh3aW5kb3cpO1xuICAgIHRoaXMudHlwZSA9IHRoaXMudHlwZSB8fCAnbGF0aXR1ZGUnO1xuICAgIHRoaXMucGF0dGVybiA9IHRoaXMucGF0dGVybiB8fCAnRERNTSc7XG4gICAgdGhpcy5zaG93U2lnbkNvbnRyb2wgPSB0aGlzLnBhdHRlcm4gIT09ICdERCc7XG5cbiAgICAvLyBjb25zdCBkZWdyZWVzVmFsaWRhdG9yczogVmFsaWRhdG9yRm5bXSA9IFt0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyBTaGFyZWRWYWxpZGF0b3JzLmxhdGl0dWRlIDogU2hhcmVkVmFsaWRhdG9ycy5sb25naXR1ZGVdO1xuICAgIC8vIGNvbnN0IG1pbnV0ZXNWYWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gW107XG4gICAgLy8gY29uc3Qgc2Vjb25kc1ZhbGlkYXRvcnM6IFZhbGlkYXRvckZuW10gPSBbXTtcblxuICAgIHN3aXRjaCAodGhpcy5wYXR0ZXJuKSB7XG4gICAgICBjYXNlICdERCc6XG4gICAgICAgIHRoaXMucGF0dGVybk1heERlY2ltYWxzID0gNztcbiAgICAgICAgLy8gZGVncmVlc1ZhbGlkYXRvcnMucHVzaChTaGFyZWRWYWxpZGF0b3JzLmRlY2ltYWwoeyBtYXhEZWNpbWFsczogdGhpcy5wYXR0ZXJuTWF4RGVjaW1hbHMgfSkpO1xuICAgICAgICB0aGlzLmRlZ3JlZXNQbGFjZWhvbGRlciA9XG4gICAgICAgICAgdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5ERF9QTEFDRUhPTERFUicgOiAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkRERF9QTEFDRUhPTERFUic7XG4gICAgICAgIHRoaXMuZGVncmVlc01hc2sgPSBtYXNraXRvTnVtYmVyT3B0aW9uc0dlbmVyYXRvcih7XG4gICAgICAgICAgcHJlY2lzaW9uOiB0aGlzLnBhdHRlcm5NYXhEZWNpbWFscyxcbiAgICAgICAgICBtaW46IHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/IC05MCA6IC0xODAsXG4gICAgICAgICAgbWF4OiB0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyA5MCA6IDE4MCxcbiAgICAgICAgICBtaW51c1NpZ246ICctJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRERNTSc6XG4gICAgICAgIHRoaXMucGF0dGVybk1heERlY2ltYWxzID0gMztcbiAgICAgICAgdGhpcy5zaG93TWludXRlcyA9IHRydWU7XG4gICAgICAgIC8vIGRlZ3JlZXNWYWxpZGF0b3JzLnB1c2goU2hhcmVkVmFsaWRhdG9ycy5pbnRlZ2VyKTtcbiAgICAgICAgLy8gbWludXRlc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1pbih0aGlzLm1pbk1heFZhbHVlcy5taW51dGVzLm1pbikpO1xuICAgICAgICAvLyBtaW51dGVzVmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWF4KHRoaXMubWluTWF4VmFsdWVzLm1pbnV0ZXMubWF4KSk7XG4gICAgICAgIC8vIG1pbnV0ZXNWYWxpZGF0b3JzLnB1c2goU2hhcmVkVmFsaWRhdG9ycy5kZWNpbWFsKHsgbWF4RGVjaW1hbHM6IHRoaXMucGF0dGVybk1heERlY2ltYWxzIH0pKTtcbiAgICAgICAgdGhpcy5kZWdyZWVzUGxhY2Vob2xkZXIgPSB0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkREJyA6ICdDT01NT04uTEFUX0xPTkcuU0lOR0xFX0ZJRUxEX1BBVFRFUk4uREREJztcbiAgICAgICAgdGhpcy5taW51dGVzUGxhY2Vob2xkZXIgPSAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLk1NJztcbiAgICAgICAgdGhpcy5kZWdyZWVzTWFzayA9IG1hc2tpdG9OdW1iZXJPcHRpb25zR2VuZXJhdG9yKHtcbiAgICAgICAgICBwcmVjaXNpb246IDAsXG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gOTAgOiAxODAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1pbnV0ZXNNYXNrID0gbWFza2l0b051bWJlck9wdGlvbnNHZW5lcmF0b3Ioe1xuICAgICAgICAgIHByZWNpc2lvbjogdGhpcy5wYXR0ZXJuTWF4RGVjaW1hbHMsXG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogNjAgLSB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydCgxLCB0aGlzLnBhdHRlcm5NYXhEZWNpbWFscyksXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6IC8vIERlZmF1bHQgaXMgRERNTVNTXG4gICAgICAgIHRoaXMucGF0dGVybk1heERlY2ltYWxzID0gMjtcbiAgICAgICAgdGhpcy5zaG93TWludXRlcyA9IHRydWU7XG4gICAgICAgIHRoaXMuc2hvd1NlY29uZHMgPSB0cnVlO1xuICAgICAgICAvLyBkZWdyZWVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuaW50ZWdlcik7XG4gICAgICAgIC8vIG1pbnV0ZXNWYWxpZGF0b3JzLnB1c2goU2hhcmVkVmFsaWRhdG9ycy5pbnRlZ2VyKTtcbiAgICAgICAgLy8gbWludXRlc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1pbih0aGlzLm1pbk1heFZhbHVlcy5taW51dGVzLm1pbikpO1xuICAgICAgICAvLyBtaW51dGVzVmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWF4KHRoaXMubWluTWF4VmFsdWVzLm1pbnV0ZXMubWF4KSk7XG4gICAgICAgIC8vIHNlY29uZHNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW4odGhpcy5taW5NYXhWYWx1ZXMuc2Vjb25kcy5taW4pKTtcbiAgICAgICAgLy8gc2Vjb25kc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1heCh0aGlzLm1pbk1heFZhbHVlcy5zZWNvbmRzLm1heCkpO1xuICAgICAgICAvLyBzZWNvbmRzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuZGVjaW1hbCh7IG1heERlY2ltYWxzOiB0aGlzLnBhdHRlcm5NYXhEZWNpbWFscyB9KSk7XG4gICAgICAgIHRoaXMuZGVncmVlc1BsYWNlaG9sZGVyID0gdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5ERCcgOiAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkRERCc7XG4gICAgICAgIHRoaXMubWludXRlc1BsYWNlaG9sZGVyID0gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5NTSc7XG4gICAgICAgIHRoaXMuc2Vjb25kc1BsYWNlaG9sZGVyID0gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5TU19TUyc7XG4gICAgICAgIHRoaXMuZGVncmVlc01hc2sgPSBtYXNraXRvTnVtYmVyT3B0aW9uc0dlbmVyYXRvcih7XG4gICAgICAgICAgcHJlY2lzaW9uOiAwLFxuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBtYXg6IHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/IDkwIDogMTgwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5taW51dGVzTWFzayA9IG1hc2tpdG9OdW1iZXJPcHRpb25zR2VuZXJhdG9yKHtcbiAgICAgICAgICBwcmVjaXNpb246IDAsXG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogNTksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNlY29uZHNNYXNrID0gbWFza2l0b051bWJlck9wdGlvbnNHZW5lcmF0b3Ioe1xuICAgICAgICAgIHByZWNpc2lvbjogdGhpcy5wYXR0ZXJuTWF4RGVjaW1hbHMsXG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogNjAgLSB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydCgxLCB0aGlzLnBhdHRlcm5NYXhEZWNpbWFscyksXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLmZvcm1Db250cm9sID1cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wgfHwgKHRoaXMuZm9ybUNvbnRyb2xOYW1lICYmIHRoaXMuZm9ybUdyb3VwRGlyICYmICh0aGlzLmZvcm1Hcm91cERpci5mb3JtLmdldCh0aGlzLmZvcm1Db250cm9sTmFtZSkgYXMgVW50eXBlZEZvcm1Db250cm9sKSk7XG4gICAgaWYgKCF0aGlzLmZvcm1Db250cm9sKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG1hbmRhdG9yeSBhdHRyaWJ1dGUgJ2Zvcm1Db250cm9sJyBvciAnZm9ybUNvbnRyb2xOYW1lJyBpbiA8bWF0LWxhdGxvbmctZmllbGQ+LlwiKTtcblxuICAgIHRoaXMuZGVncmVlc0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nPihudWxsKTtcbiAgICB0aGlzLm1pbnV0ZXNDb250cm9sID0gbmV3IEZvcm1Db250cm9sPHN0cmluZz4obnVsbCk7XG4gICAgdGhpcy5zZWNvbmRzQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmc+KG51bGwpO1xuICAgIHRoaXMuc2lnbkNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2w8TGF0TG9uZ1NpZ24+KG51bGwpO1xuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIG1lcmdlKFxuICAgICAgICB0aGlzLmRlZ3JlZXNDb250cm9sLnZhbHVlQ2hhbmdlcyxcbiAgICAgICAgdGhpcy5taW51dGVzQ29udHJvbC52YWx1ZUNoYW5nZXMsXG4gICAgICAgIHRoaXMuc2Vjb25kc0NvbnRyb2wudmFsdWVDaGFuZ2VzLFxuICAgICAgICB0aGlzLnNpZ25Db250cm9sLnZhbHVlQ2hhbmdlc1xuICAgICAgKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbkZvcm1DaGFuZ2UoKSlcbiAgICApO1xuXG4gICAgLy8gTGlzdGVuIHN0YXR1cyBjaGFuZ2VzICh3aGVuIGRvbmUgb3V0c2lkZSB0aGUgY29tcG9uZW50ICAtIGUuZy4gd2hlbiBzZXRFcnJvcnMoKSBpcyBjYWxsaW5nIG9uIHRoZSBmb3JtQ29udHJvbClcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zdGF0dXNDaGFuZ2VzXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIGZpbHRlcigoKSA9PiAhdGhpcy5yZWFkb25seSAmJiAhdGhpcy5fd3JpdGluZyAmJiAhdGhpcy5fZGlzYWJsaW5nKSAvLyBTa2lwXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLm1hcmtGb3JDaGVjaygpKVxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9vblRvdWNoZWRDYWxsYmFjayA9IGZuO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3dyaXRpbmcpIHJldHVybjtcbiAgICB0aGlzLl93cml0aW5nID0gdHJ1ZTtcblxuICAgIGlmICh2YWx1ZSAhPT0gdGhpcy5mb3JtQ29udHJvbC52YWx1ZSkge1xuICAgICAgdGhpcy5mb3JtQ29udHJvbC5wYXRjaFZhbHVlKHZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKHZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbXB1dGVMYXRMb25nRm9ybUdyb3VwVmFsdWUodmFsdWUpO1xuICAgIGNvbnNvbGUuZGVidWcoJ1ttYXQtbGF0bG9uZy1maWVsZF0gQ2hhbmdpbmcgdmFsdWUgb2YgaW5wdXRzOicsIHZhbHVlLCByZXN1bHQpO1xuICAgIHRoaXMucGF0Y2hWYWx1ZShyZXN1bHQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgIHRoaXMuX3dyaXRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZUZha2VJbnB1dCgpO1xuICAgICAgdGhpcy51cGRhdGVUYWJJbmRleCgpO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2Rpc2FibGluZykgcmV0dXJuO1xuXG4gICAgdGhpcy5fZGlzYWJsaW5nID0gdHJ1ZTtcbiAgICBpZiAoaXNEaXNhYmxlZCkge1xuICAgICAgdGhpcy5kZWdyZWVzQ29udHJvbC5kaXNhYmxlKCk7XG4gICAgICB0aGlzLm1pbnV0ZXNDb250cm9sLmRpc2FibGUoKTtcbiAgICAgIHRoaXMuc2Vjb25kc0NvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgdGhpcy5zaWduQ29udHJvbC5kaXNhYmxlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVncmVlc0NvbnRyb2wuZW5hYmxlKCk7XG4gICAgICB0aGlzLm1pbnV0ZXNDb250cm9sLmVuYWJsZSgpO1xuICAgICAgdGhpcy5zZWNvbmRzQ29udHJvbC5lbmFibGUoKTtcbiAgICAgIHRoaXMuc2lnbkNvbnRyb2wuZW5hYmxlKCk7XG4gICAgfVxuICAgIHRoaXMuX2Rpc2FibGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBjbGVhclZhbHVlKGV2ZW50PzogRXZlbnQpIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy53cml0ZVZhbHVlKG51bGwpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBpbnRlcm5hbEVsZW1lbnRzKCk6IEhUTUxFbGVtZW50W10ge1xuICAgIHJldHVybiAodGhpcy5pbnB1dERlZ3JlZXMgPyBbdGhpcy5pbnB1dERlZ3JlZXMubmF0aXZlRWxlbWVudF0gOiBbXSlcbiAgICAgIC5jb25jYXQodGhpcy5pbnB1dE1pbnV0ZXMgPyBbdGhpcy5pbnB1dE1pbnV0ZXMubmF0aXZlRWxlbWVudF0gOiBbXSlcbiAgICAgIC5jb25jYXQodGhpcy5pbnB1dFNlY29uZHMgPyBbdGhpcy5pbnB1dFNlY29uZHMubmF0aXZlRWxlbWVudF0gOiBbXSlcbiAgICAgIC5jb25jYXQodGhpcy5pbnB1dFNpZ24gPyBbdGhpcy5pbnB1dFNpZ24ubmF0aXZlRWxlbWVudF0gOiBbXSlcbiAgICAgIC5jb25jYXQodGhpcy5mYWtlSW5wdXQgPyBbdGhpcy5mYWtlSW5wdXQubmF0aXZlRWxlbWVudF0gOiBbXSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25Gb2N1c0Zha2VJbnB1dChldmVudDogRm9jdXNFdmVudCkge1xuICAgIGlmICghdGhpcy5zaG93RmllbGRzKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAvLyBIaWRlIHRoZSBmYWtlIGlucHV0XG4gICAgICB0aGlzLmZha2VJbnB1dD8ubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdjZGstdmlzdWFsbHktaGlkZGVuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdG91Y2hlZCA9IHRoaXMuZm9ybUNvbnRyb2wudG91Y2hlZDtcblxuICAgIC8vIEZvY3VzIG9uIGZpcnN0IGlucHV0XG4gICAgdGhpcy5mb2N1cygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uQmx1ckZha2VJbnB1dChldmVudDogRm9jdXNFdmVudCkge1xuICAgIGNvbnN0IGludGVybmFsRXZlbnQgPSB0aGlzLmludGVybmFsRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoaW50ZXJuYWxFdmVudCAmJiAhdGhpcy5fdG91Y2hlZCkge1xuICAgICAgLy8gV29ya2Fyb3VuZCB0byByZW1vdmUgdG91Y2hlZCBvbiB0aGUgZmFrZUlucHV0XG4gICAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc1VudG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfb25Gb2N1c0lucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW50ZXJuYWxFbGVtZW50cy5zb21lKChlbCkgPT4gZWwgPT09IGV2ZW50LnRhcmdldCk7XG4gICAgaWYgKGludGVybmFsRXZlbnQpIHtcbiAgICAgIGlmIChldmVudC50YXJnZXQgPT09IHRoaXMuaW5wdXRTaWduPy5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaW5wdXRTaWduU2VsZWN0Py5vcGVuKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxlY3RJbnB1dENvbnRlbnQoZXZlbnQudGFyZ2V0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5mb2N1cyhldmVudC50YXJnZXQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkJsdXJJbnB1dChldmVudDogRm9jdXNFdmVudCkge1xuICAgIGNvbnN0IGludGVybmFsRXZlbnQgPSB0aGlzLmludGVybmFsRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoIWludGVybmFsRXZlbnQpIHtcbiAgICAgIHRoaXMuX2ZvY3VzZWQgPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLmFwcGVhcmFuY2UgPT0gJ2ZpbGwnKSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmRlYWN0aXZhdGUoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5ibHVycmVkLmVtaXQoZXZlbnQpO1xuXG4gICAgICB0aGlzLnVwZGF0ZUZha2VJbnB1dCgpO1xuICAgICAgdGhpcy51cGRhdGVUYWJJbmRleCgpO1xuXG4gICAgICB0aGlzLl90b3VjaGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgdGhpcy5fY2hlY2tJZlRvdWNoZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQ2xpY2tJbnB1dChldmVudDogVUlFdmVudCkge1xuICAgIGNvbnN0IGludGVybmFsRXZlbnQgPSB0aGlzLmludGVybmFsRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC50YXJnZXQpO1xuICAgIGlmIChpbnRlcm5hbEV2ZW50KSB7XG4gICAgICBzZWxlY3RJbnB1dENvbnRlbnQoZXZlbnQudGFyZ2V0KTtcbiAgICB9XG4gICAgLy8gQXZvaWQgbWF0LWZvcm0tZmllbGQgdG8gZ2l2ZSBmb2N1cyB0byBmYWtlIGlucHV0XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZm9jdXModGFyZ2V0PzogYW55KSB7XG4gICAgaWYgKHRoaXMuX2ZvY3VzZWQpIHJldHVybiB0cnVlOyAvLyBBbHJlYWR5IGZvY3VzZWRcbiAgICBjb25zdCBzaG93RmllbGRzID0gdGhpcy5zaG93RmllbGRzO1xuICAgIHRoaXMuX2ZvY3VzZWQgPSB0cnVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghc2hvd0ZpZWxkcykge1xuICAgICAgICB0aGlzLmlucHV0RGVncmVlcy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgIHNlbGVjdElucHV0Q29udGVudCh0aGlzLmlucHV0RGVncmVlcy5uYXRpdmVFbGVtZW50KTtcbiAgICAgIH0gZWxzZSBpZiAodGFyZ2V0KSB7XG4gICAgICAgIHRhcmdldC5mb2N1cygpO1xuICAgICAgICBzZWxlY3RJbnB1dENvbnRlbnQodGFyZ2V0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYXBwZWFyYW5jZSA9PSAnZmlsbCcpIHtcbiAgICAgICAgdGhpcy5mb3JtRmllbGQuX2xpbmVSaXBwbGUuYWN0aXZhdGUoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy51cGRhdGVGYWtlSW5wdXQoKTtcbiAgICAgIHRoaXMudXBkYXRlVGFiSW5kZXgoKTtcbiAgICB9LCA1MCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZm9ybWF0KHJhd1ZhbHVlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuY29tcHV0ZUxhdExvbmdGb3JtR3JvdXBWYWx1ZShyYXdWYWx1ZSk7XG4gICAgaWYgKHZhbHVlcy5kZWdyZWVzID09PSBudWxsKSByZXR1cm4gJyc7XG4gICAgbGV0IHJlc3VsdCA9IGAke3ZhbHVlcy5kZWdyZWVzfcKwIGA7XG4gICAgaWYgKHZhbHVlcy5taW51dGVzICE9PSBudWxsKSByZXN1bHQgKz0gYCR7dmFsdWVzLm1pbnV0ZXN9JyBgO1xuICAgIGlmICh2YWx1ZXMuc2Vjb25kcyAhPT0gbnVsbCkgcmVzdWx0ICs9IGAke3ZhbHVlcy5zZWNvbmRzfVwiIGA7XG4gICAgaWYgKHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJykge1xuICAgICAgcmVzdWx0ICs9IHZhbHVlcy5zaWduID09PSAxID8gJ04nIDogJ1MnO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgKz0gdmFsdWVzLnNpZ24gPT09IDEgPyAnRScgOiAnVyc7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tcHV0ZURlY2ltYWxQYXJ0KHZhbHVlOiBudW1iZXIsIG5iT2ZEZWNpbWFsczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdmFsdWUgKiAxMCAqKiAobmJPZkRlY2ltYWxzICogLTEpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbXB1dGVMYXRMb25nRm9ybUdyb3VwVmFsdWUocmF3VmFsdWU6IG51bWJlciB8IHN0cmluZyk6IElMYXRMb25nRGF0YSB7XG4gICAgY29uc3QgaXNMb25naXR1ZGUgPSB0aGlzLnR5cGUgPT09ICdsb25naXR1ZGUnO1xuXG4gICAgY29uc3QgdmFsdWUgPSB0eXBlb2YgcmF3VmFsdWUgPT09ICdzdHJpbmcnID8gcGFyc2VGbG9hdChyYXdWYWx1ZS5yZXBsYWNlKC8sL2csICcuJykpIDogcmF3VmFsdWU7XG4gICAgY29uc3QgcmVzdWx0OiBJTGF0TG9uZ0RhdGEgPSB7XG4gICAgICBkZWdyZWVzOiBudWxsLFxuICAgICAgbWludXRlczogbnVsbCxcbiAgICAgIHNlY29uZHM6IG51bGwsXG4gICAgICBzaWduOiBpc05vdE5pbCh2YWx1ZSlcbiAgICAgICAgPyB2YWx1ZSA8IDBcbiAgICAgICAgICA/IC0xXG4gICAgICAgICAgOiAxXG4gICAgICAgIDogLy8gVXNlIGRlZmF1bHQgc2lnbiwgaWYgYW55XG4gICAgICAgICAgdGhpcy5kZWZhdWx0U2lnbiAmJiB0aGlzLmRlZmF1bHRTaWduID09PSAnLSdcbiAgICAgICAgICA/IC0xXG4gICAgICAgICAgOiAxLFxuICAgIH07XG5cbiAgICBpZiAodmFsdWUgPT09IDApIHtcbiAgICAgIHJlc3VsdC5kZWdyZWVzID0gMDtcbiAgICB9IGVsc2UgaWYgKGlzTm90TmlsKHZhbHVlKSkge1xuICAgICAgaWYgKHRoaXMucGF0dGVybiA9PT0gJ0REJykge1xuICAgICAgICBjb25zdCBzcGxpdFZhbHVlID0gc3BsaXROdW1iZXJUb0ZpZWxkc0REKHZhbHVlLCB7XG4gICAgICAgICAgbG9uZ2l0dWRlOiBpc0xvbmdpdHVkZSxcbiAgICAgICAgICBwYXR0ZXJuOiB0aGlzLnBhdHRlcm4sXG4gICAgICAgICAgbWF4RGVjaW1hbHM6IHRoaXMucGF0dGVybk1heERlY2ltYWxzLFxuICAgICAgICAgIGZpeExhdExvbmc6IHRydWUsXG4gICAgICAgIH0pLnNsaWNlKDEpIGFzIG51bWJlcltdOyAvLyByZW1vdmUgc2lnbjtcbiAgICAgICAgcmVzdWx0LmRlZ3JlZXMgPSAoc3BsaXRWYWx1ZVswXSArIHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KHNwbGl0VmFsdWVbMV0gPz8gMCwgdGhpcy5wYXR0ZXJuTWF4RGVjaW1hbHMpKSAqIChyZXN1bHQuc2lnbiB8fCAxKSB8fCBudWxsO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBhdHRlcm4gPT09ICdERE1NJykge1xuICAgICAgICBjb25zdCBzcGxpdFZhbHVlID0gc3BsaXROdW1iZXJUb0ZpZWxkc0RETU0odmFsdWUsIHtcbiAgICAgICAgICBsb25naXR1ZGU6IGlzTG9uZ2l0dWRlLFxuICAgICAgICAgIHBhdHRlcm46IHRoaXMucGF0dGVybixcbiAgICAgICAgICBtYXhEZWNpbWFsczogdGhpcy5wYXR0ZXJuTWF4RGVjaW1hbHMsXG4gICAgICAgICAgZml4TGF0TG9uZzogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdFsnbWludXRlcyddID0gTWF0aC5hYnMoKHNwbGl0VmFsdWVbMV0gPz8gMCkgKyB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydChzcGxpdFZhbHVlWzJdID8/IDAsIHRoaXMucGF0dGVybk1heERlY2ltYWxzKSkgfHwgbnVsbDtcbiAgICAgICAgcmVzdWx0WydkZWdyZWVzJ10gPSBNYXRoLmFicyghcmVzdWx0WydtaW51dGVzJ10gJiYgaXNOaWxPckJsYW5rKHNwbGl0VmFsdWVbMF0pID8gbnVsbCA6IChzcGxpdFZhbHVlWzBdID8/IDApKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIERlZmF1bHQgLy8gRERNTVNTXG4gICAgICAgIGNvbnN0IHNwbGl0VmFsdWUgPSBzcGxpdE51bWJlclRvRmllbGRzRERNTVNTKHZhbHVlLCB7XG4gICAgICAgICAgbG9uZ2l0dWRlOiBpc0xvbmdpdHVkZSxcbiAgICAgICAgICBwYXR0ZXJuOiB0aGlzLnBhdHRlcm4sXG4gICAgICAgICAgbWF4RGVjaW1hbHM6IHRoaXMucGF0dGVybk1heERlY2ltYWxzLFxuICAgICAgICAgIGZpeExhdExvbmc6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHRbJ3NlY29uZHMnXSA9IE1hdGguYWJzKChzcGxpdFZhbHVlWzJdID8/IDApICsgdGhpcy5jb21wdXRlRGVjaW1hbFBhcnQoc3BsaXRWYWx1ZVszXSA/PyAwLCB0aGlzLnBhdHRlcm5NYXhEZWNpbWFscykpIHx8IG51bGw7XG4gICAgICAgIHJlc3VsdFsnbWludXRlcyddID0gIXJlc3VsdFsnc2Vjb25kcyddICYmICFzcGxpdFZhbHVlWzFdID8gbnVsbCA6IE1hdGguYWJzKHNwbGl0VmFsdWVbMV0gPz8gMCk7XG4gICAgICAgIHJlc3VsdFsnZGVncmVlcyddID0gIXJlc3VsdFsnc2Vjb25kcyddICYmICFyZXN1bHRbJ21pbnV0ZXMnXSAmJiBpc05pbE9yQmxhbmsoc3BsaXRWYWx1ZVswXSkgPyBudWxsIDogTWF0aC5hYnMoc3BsaXRWYWx1ZVswXSA/PyAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIG1hcmtBc1RvdWNoZWQoKSB7XG4gICAgdGhpcy5mb3JtQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5kZWdyZWVzQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5taW51dGVzQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5zZWNvbmRzQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5zaWduQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2soKTtcbiAgfVxuXG4gIC8qIC0tIHByaXZhdGUgbWV0aG9kIC0tICovXG5cbiAgcHJpdmF0ZSBwYXRjaFZhbHVlKHZhbHVlczogSUxhdExvbmdEYXRhLCBvcHRzPzogeyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICB0aGlzLmRlZ3JlZXNDb250cm9sLnBhdGNoVmFsdWUodmFsdWVzLmRlZ3JlZXM/LnRvU3RyaW5nKCksIG9wdHMpO1xuICAgIHRoaXMubWludXRlc0NvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZXMubWludXRlcz8udG9TdHJpbmcoKSwgb3B0cyk7XG4gICAgdGhpcy5zZWNvbmRzQ29udHJvbC5wYXRjaFZhbHVlKHZhbHVlcy5zZWNvbmRzPy50b1N0cmluZygpLCBvcHRzKTtcbiAgICB0aGlzLnNpZ25Db250cm9sLnBhdGNoVmFsdWUodmFsdWVzLnNpZ24sIG9wdHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkZvcm1DaGFuZ2UoKSB7XG4gICAgaWYgKHRoaXMuX3dyaXRpbmcpIHJldHVybjsgLy8gU2tpcCBpZiBjYWxsIGJ5IHNlbGZcbiAgICB0aGlzLl93cml0aW5nID0gdHJ1ZTtcblxuICAgIGNvbnN0IGRlZ3JlZXMgPSBwYXJzZUZsb2F0KHRoaXMuZGVncmVlc0NvbnRyb2wudmFsdWUpO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSBwYXJzZUZsb2F0KHRoaXMubWludXRlc0NvbnRyb2wudmFsdWUpO1xuICAgIGNvbnN0IHNlY29uZHMgPSBwYXJzZUZsb2F0KHRoaXMuc2Vjb25kc0NvbnRyb2wudmFsdWUpO1xuICAgIGNvbnN0IHNpZ24gPSB0aGlzLnNpZ25Db250cm9sLnZhbHVlO1xuXG4gICAgY29uc3QgaW5jb21wbGV0ZVZhbHVlID0gaXNOaWwoZGVncmVlcykgJiYgKGlzTm90TmlsKG1pbnV0ZXMpIHx8IGlzTm90TmlsKHNlY29uZHMpKTtcbiAgICBjb25zdCBpbnZhbGlkID1cbiAgICAgIGluY29tcGxldGVWYWx1ZSB8fCB0aGlzLmRlZ3JlZXNDb250cm9sLmludmFsaWQgfHwgdGhpcy5taW51dGVzQ29udHJvbC5pbnZhbGlkIHx8IHRoaXMuc2Vjb25kc0NvbnRyb2wuaW52YWxpZCB8fCB0aGlzLnNpZ25Db250cm9sLmludmFsaWQ7XG4gICAgaWYgKGludmFsaWQpIHtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzUGVuZGluZyh7IG9ubHlTZWxmOiB0cnVlIH0pO1xuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRFcnJvcnMoe1xuICAgICAgICBpbnZhbGlkOiBpbmNvbXBsZXRlVmFsdWUsXG4gICAgICAgIC4uLnRoaXMuZGVncmVlc0NvbnRyb2wuZXJyb3JzLFxuICAgICAgICAuLi50aGlzLm1pbnV0ZXNDb250cm9sLmVycm9ycyxcbiAgICAgICAgLi4udGhpcy5zZWNvbmRzQ29udHJvbC5lcnJvcnMsXG4gICAgICAgIC4uLnRoaXMuc2lnbkNvbnRyb2wuZXJyb3JzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0aGlzLmRlZ3JlZXNDb250cm9sLmRpcnR5IHx8IHRoaXMubWludXRlc0NvbnRyb2wuZGlydHkgfHwgdGhpcy5zZWNvbmRzQ29udHJvbC5kaXJ0eSB8fCB0aGlzLnNpZ25Db250cm9sLmRpcnR5KSB7XG4gICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENvbXB1dGUgZGVjaW1hbCB2YWx1ZXNcbiAgICBjb25zdCB2YWx1ZSA9IGlzTmlsKGRlZ3JlZXMpIHx8IHRoaXMucGF0dGVybiA9PT0gJ0REJyA/IGRlZ3JlZXMgOiBjb21wdXRlRGVjaW1hbERlZ3JlZXMoZGVncmVlcywgbWludXRlcywgc2Vjb25kcywgc2lnbiwgdGhpcy5tYXhEZWNpbWFscyk7XG5cbiAgICAvLyBTZXQgbW9kZWwgdmFsdWVcbiAgICB0aGlzLmVtaXRDaGFuZ2UodmFsdWUpO1xuXG4gICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDaGFuZ2UodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmZvcm1Db250cm9sLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWx1ZSh2YWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgICAvLyBDaGFuZ2VzIGNvbWVzIGZyb20gaW5zaWRlIGZ1bmN0aW9uOiB1c2UgdGhlIGNhbGxiYWNrXG4gICAgICB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrKHZhbHVlKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgbmVlZCB0byB1cGRhdGUgY29udHJvbHNcbiAgICAgIHRoaXMuX2NoZWNrSWZUb3VjaGVkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfY2hlY2tJZlRvdWNoZWQoKSB7XG4gICAgaWYgKHRoaXMuZm9ybUNvbnRyb2wudG91Y2hlZCkge1xuICAgICAgdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2soKTtcbiAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgICB0aGlzLl90b3VjaGVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdG91Y2hlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogU2hvdy9IaWRlIHRoZSBmYWtlIGlucHV0XG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUZha2VJbnB1dCgpIHtcbiAgICBpZiAodGhpcy5zaG93RmllbGRzKSB7XG4gICAgICB0aGlzLmZha2VJbnB1dD8ubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdjZGstdmlzdWFsbHktaGlkZGVuJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZmFrZUlucHV0Py5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Nkay12aXN1YWxseS1oaWRkZW4nKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBjaGVjayBpZiBuZWVkXG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlLCBiZWNhdXNlLCB0aGlzIGNvbXBvbmVudCBoYXMgYSB0ZW1wb3JhcnkgY29tcG9uZW50IGRpc3BsYXllZCBiZWZvcmUgdGhlIGZpcnN0IGZvY3VzIGV2ZW50XG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZVRhYkluZGV4KCkge1xuICAgIGlmIChpc05pbCh0aGlzLl90YWJpbmRleCkpIHJldHVybjtcblxuICAgIGlmICh0aGlzLmZha2VJbnB1dCkge1xuICAgICAgdGhpcy5mYWtlSW5wdXQubmF0aXZlRWxlbWVudC50YWJJbmRleCA9IHRoaXMuX3RhYmluZGV4O1xuICAgIH1cblxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiIsIjwhLS0gcmVhZG9ubHkgLS0+XG5AaWYgKHJlYWRvbmx5KSB7XG4gIDxtYXQtZm9ybS1maWVsZFxuICAgIFtmbG9hdExhYmVsXT1cImZsb2F0TGFiZWwgfCBhc0Zsb2F0TGFiZWxUeXBlXCJcbiAgICBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCJcbiAgICBbc3Vic2NyaXB0U2l6aW5nXT1cInN1YnNjcmlwdFNpemluZ1wiXG4gICAgY2xhc3M9XCJtYXQtZm9ybS1maWVsZC1kaXNhYmxlZCB7eyBjbGFzc0xpc3QgfX1cIlxuICA+XG4gICAgPGRpdiBtYXRQcmVmaXg+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0UHJlZml4VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIEBpZiAoZmxvYXRMYWJlbCAhPT0gJ25ldmVyJyAmJiAhIXBsYWNlaG9sZGVyKSB7XG4gICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyIH19PC9tYXQtbGFiZWw+XG4gICAgfVxuXG4gICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiB0eXBlPVwidGV4dFwiIHJlYWRvbmx5IFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFwiIC8+XG4gICAgPGlvbi10ZXh0PlxuICAgICAge3tcbiAgICAgICAgZm9ybUNvbnRyb2wudmFsdWVcbiAgICAgICAgICB8IGxhdExvbmdGb3JtYXQ6IHsgcGF0dGVybjogcGF0dGVybiwgbWF4RGVjaW1hbHM6IHBhdHRlcm5NYXhEZWNpbWFscywgdHlwZTogdHlwZSwgcGxhY2Vob2xkZXJDaGFyOiAnJyB9XG4gICAgICB9fVxuICAgIDwvaW9uLXRleHQ+XG5cbiAgICA8ZGl2IG1hdFN1ZmZpeD5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRTdWZmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBoaW50cyAtLT5cbiAgICA8bWF0LWhpbnQgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiZm9ybUNvbnRyb2wuaW52YWxpZFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdEhpbnRUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvbWF0LWhpbnQ+XG4gIDwvbWF0LWZvcm0tZmllbGQ+XG59IEBlbHNlIHtcbiAgPCEtLSB3cml0YWJsZSAtLT5cbiAgPG1hdC1mb3JtLWZpZWxkXG4gICAgI2Zvcm1GaWVsZFxuICAgIFtmbG9hdExhYmVsXT1cInNob3dGaWVsZHMgJiYgKCFmbG9hdExhYmVsIHx8IGZsb2F0TGFiZWwgPT09ICdhdXRvJykgPyAnYWx3YXlzJyA6IChmbG9hdExhYmVsIHwgYXNGbG9hdExhYmVsVHlwZSlcIlxuICAgIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIlxuICAgIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCJcbiAgICBbY2xhc3MubWRjLXRleHQtZmllbGQtLWludmFsaWRdPVwiZm9ybUNvbnRyb2wudG91Y2hlZCAmJiAoc2lnbkNvbnRyb2wuaW52YWxpZCB8fCBmb3JtQ29udHJvbC5pbnZhbGlkKVwiXG4gICAgY2xhc3M9XCJtYXQtbGF0bG9uZy1maWVsZCBtYXQtbGF0bG9uZy1maWVsZC17eyB0eXBlIH19IHt7IGNsYXNzTGlzdCB9fVwiXG4gID5cbiAgICA8ZGl2IG1hdFByZWZpeD5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRQcmVmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgQGlmIChmbG9hdExhYmVsICE9PSAnbmV2ZXInICYmIHBsYWNlaG9sZGVyIHwgaXNOb3ROaWxPckJsYW5rKSB7XG4gICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyIH19PC9tYXQtbGFiZWw+XG4gICAgfVxuXG4gICAgPGlucHV0XG4gICAgICBtYXRJbnB1dFxuICAgICAgI2Zha2VJbnB1dFxuICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgcmVhZG9ubHk9XCJ0cnVlXCJcbiAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFwiXG4gICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgW2FwcEF1dG9mb2N1c109XCIhc2hvd0ZpZWxkcyAmJiBhdXRvZm9jdXNcIlxuICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwic2hvd0ZpZWxkc1wiXG4gICAgICAoZm9jdXMpPVwib25Gb2N1c0Zha2VJbnB1dCgkZXZlbnQpXCJcbiAgICAgIChibHVyKT1cIm9uQmx1ckZha2VJbnB1dCgkZXZlbnQpXCJcbiAgICAvPlxuICAgIDxpbnB1dFxuICAgICAgbWF0SW5wdXRcbiAgICAgICNpbnB1dERlZ3JlZXNcbiAgICAgIFtjbGFzcy5kZWdyZWVzXT1cInBhdHRlcm4gIT09ICdERCdcIlxuICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgaW5wdXRtb2RlPVwiZGVjaW1hbFwiXG4gICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgW3BsYWNlaG9sZGVyXT1cImRlZ3JlZXNQbGFjZWhvbGRlciB8IHRyYW5zbGF0ZVwiXG4gICAgICBbZm9ybUNvbnRyb2xdPVwiZGVncmVlc0NvbnRyb2xcIlxuICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcbiAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleFwiXG4gICAgICBbYXBwQXV0b2ZvY3VzXT1cInNob3dGaWVsZHMgJiYgYXV0b2ZvY3VzXCJcbiAgICAgIFttYXNraXRvXT1cImRlZ3JlZXNNYXNrXCJcbiAgICAgIChmb2N1cyk9XCJfb25Gb2N1c0lucHV0KCRldmVudClcIlxuICAgICAgKGJsdXIpPVwiX29uQmx1cklucHV0KCRldmVudClcIlxuICAgICAgKGNsaWNrKT1cIl9vbkNsaWNrSW5wdXQoJGV2ZW50KVwiXG4gICAgLz5cbiAgICA8c3BhbiBjbGFzcz1cInN5bWJvbC11bml0XCIgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIj5cbiAgICAgIHt7IGRlZ3JlZXNTeW1ib2xVbml0IH19XG4gICAgPC9zcGFuPlxuXG4gICAgQGlmIChzaG93TWludXRlcykge1xuICAgICAgPGlucHV0XG4gICAgICAgIG1hdElucHV0XG4gICAgICAgICNpbnB1dE1pbnV0ZXNcbiAgICAgICAgW2NsYXNzLm1pbnV0ZXNdPVwic2hvd1NlY29uZHNcIlxuICAgICAgICBbY2xhc3MubWludXRlcy1zZWNvbmRzXT1cIiFzaG93U2Vjb25kc1wiXG4gICAgICAgIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFzaG93RmllbGRzXCJcbiAgICAgICAgaW5wdXRtb2RlPVwiZGVjaW1hbFwiXG4gICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJtaW51dGVzUGxhY2Vob2xkZXIgfCB0cmFuc2xhdGVcIlxuICAgICAgICBbZm9ybUNvbnRyb2xdPVwibWludXRlc0NvbnRyb2xcIlxuICAgICAgICBbcmVxdWlyZWRdPVwiZmFsc2VcIlxuICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXhcIlxuICAgICAgICBbbWFza2l0b109XCJtaW51dGVzTWFza1wiXG4gICAgICAgIChmb2N1cyk9XCJfb25Gb2N1c0lucHV0KCRldmVudClcIlxuICAgICAgICAoYmx1cik9XCJfb25CbHVySW5wdXQoJGV2ZW50KVwiXG4gICAgICAgIChjbGljayk9XCJfb25DbGlja0lucHV0KCRldmVudClcIlxuICAgICAgLz5cbiAgICAgIDxzcGFuIGNsYXNzPVwic3ltYm9sLXVuaXRcIiBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCIhc2hvd0ZpZWxkc1wiPlxuICAgICAgICB7eyBtaW51dGVzU3ltYm9sVW5pdCB9fVxuICAgICAgPC9zcGFuPlxuICAgIH1cblxuICAgIEBpZiAoc2hvd1NlY29uZHMpIHtcbiAgICAgIDxpbnB1dFxuICAgICAgICBtYXRJbnB1dFxuICAgICAgICAjaW5wdXRTZWNvbmRzXG4gICAgICAgIGNsYXNzPVwic2Vjb25kc1wiXG4gICAgICAgIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFzaG93RmllbGRzXCJcbiAgICAgICAgaW5wdXRtb2RlPVwiZGVjaW1hbFwiXG4gICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJzZWNvbmRzUGxhY2Vob2xkZXIgfCB0cmFuc2xhdGVcIlxuICAgICAgICBbZm9ybUNvbnRyb2xdPVwic2Vjb25kc0NvbnRyb2xcIlxuICAgICAgICBbcmVxdWlyZWRdPVwiZmFsc2VcIlxuICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXhcIlxuICAgICAgICBbbWFza2l0b109XCJzZWNvbmRzTWFza1wiXG4gICAgICAgIChmb2N1cyk9XCJfb25Gb2N1c0lucHV0KCRldmVudClcIlxuICAgICAgICAoYmx1cik9XCJfb25CbHVySW5wdXQoJGV2ZW50KVwiXG4gICAgICAgIChjbGljayk9XCJfb25DbGlja0lucHV0KCRldmVudClcIlxuICAgICAgLz5cbiAgICAgIDxzcGFuIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFzaG93RmllbGRzXCIgY2xhc3M9XCJzeW1ib2wtdW5pdFwiPlxuICAgICAgICB7eyBzZWNvbmRzU3ltYm9sVW5pdCB9fVxuICAgICAgPC9zcGFuPlxuICAgIH1cblxuICAgIDwhLS0gc2lnbiAtLT5cbiAgICBAaWYgKHNob3dTaWduQ29udHJvbCkge1xuICAgICAgPHNwYW4gY2xhc3M9XCJmbGV4LXNwYWNlclwiPjwvc3Bhbj5cbiAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICNpbnB1dFNpZ25cbiAgICAgICAgW2Zvcm1Db250cm9sXT1cInNpZ25Db250cm9sXCJcbiAgICAgICAgW3BsYWNlaG9sZGVyXT1cIlxuICAgICAgICAgICh0eXBlID09PSAnbGF0aXR1ZGUnID8gJ0NPTU1PTi5MQVRfTE9ORy5MQVRfU0lHTl9QTEFDRUhPTERFUicgOiAnQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9QTEFDRUhPTERFUicpXG4gICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICBcIlxuICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXhcIlxuICAgICAgICAoZm9jdXMpPVwiX29uRm9jdXNJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgKGJsdXIpPVwiX29uQmx1cklucHV0KCRldmVudClcIlxuICAgICAgICAoY2xpY2spPVwiX29uQ2xpY2tJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgY2xhc3M9XCJzaWduXCJcbiAgICAgID5cbiAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIjFcIiAoY2xpY2spPVwiaW5wdXRTaWduLmNsb3NlKClcIj5cbiAgICAgICAgICB7eyAodHlwZSA9PT0gJ2xhdGl0dWRlJyA/ICdDT01NT04uTEFUX0xPTkcuTEFUX1NJR05fTicgOiAnQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9FJykgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiLTFcIiAoY2xpY2spPVwiaW5wdXRTaWduLmNsb3NlKClcIj5cbiAgICAgICAgICB7eyAodHlwZSA9PT0gJ2xhdGl0dWRlJyA/ICdDT01NT04uTEFUX0xPTkcuTEFUX1NJR05fUycgOiAnQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9XJykgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgPC9tYXQtc2VsZWN0PlxuICAgIH1cblxuICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgPCEtLSBEbyB0aGUgc2FtZSBhcyBNYXRGcm9tRmllbGQgc2luY2UgYW5ndWxhciAxNSAoc2VlIGNvbXBvbmVudCBzb3VyY2UpLS0+XG4gIDxkaXZcbiAgICBjbGFzcz1cIm1hdC1tZGMtZm9ybS1maWVsZC1zdWJzY3JpcHQtd3JhcHBlclwiXG4gICAgW2NsYXNzLm1hdC1tZGMtZm9ybS1maWVsZC1ib3R0b20tYWxpZ25dPVwic3Vic2NyaXB0U2l6aW5nID09PSAnZml4ZWQnXCJcbiAgICBbY2xhc3MubWF0LW1kYy1mb3JtLWZpZWxkLXN1YnNjcmlwdC1keW5hbWljLXNpemVdPVwic3Vic2NyaXB0U2l6aW5nID09PSAnZHluYW1pYydcIlxuICA+XG4gICAgQGlmIChmb3JtQ29udHJvbC50b3VjaGVkICYmIGZvcm1Db250cm9sLmludmFsaWQpIHtcbiAgICAgIDwhLS0gZXJyb3JzIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cIm1hdC1tZGMtZm9ybS1maWVsZC1lcnJvci13cmFwcGVyXCI+XG4gICAgICAgIEBpZiAoZm9ybUNvbnRyb2wuZXJyb3JzIHwgbWFwS2V5cyB8IGFycmF5Rmlyc3Q7IGFzIGVycm9yS2V5KSB7XG4gICAgICAgICAgPG1hdC1lcnJvcj5cbiAgICAgICAgICAgIHt7IGkxOG5FcnJvcktleXMgfCBtYXBHZXQ6IGVycm9yS2V5IHwgdHJhbnNsYXRlOiAoZm9ybUNvbnRyb2wuZXJyb3JzIHwgbWFwR2V0OiBlcnJvcktleSkgfX1cbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdEVycm9yVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSB7XG4gICAgICA8IS0tIGhpbnRzIC0tPlxuICAgICAgPG1hdC1oaW50PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0SGludFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L21hdC1oaW50PlxuICAgIH1cbiAgPC9kaXY+XG59XG5cbjxuZy10ZW1wbGF0ZSAjbWF0UHJlZml4VGVtcGxhdGU+XG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIlttYXRQcmVmaXhdXCI+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNtYXRTdWZmaXhUZW1wbGF0ZT5cbiAgQGlmIChjbGVhcmFibGUgJiYgIXJlYWRvbmx5KSB7XG4gICAgPGJ1dHRvblxuICAgICAgbWF0U3VmZml4XG4gICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAoY2xpY2spPVwiY2xlYXJWYWx1ZSgkZXZlbnQpXCJcbiAgICAgIFtoaWRkZW5dPVwiZm9ybUNvbnRyb2wudmFsdWUgfCBpc05pbFwiXG4gICAgPlxuICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cbiAgfVxuXG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIlttYXRTdWZmaXhdXCI+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNtYXRFcnJvclRlbXBsYXRlPlxuICA8bmctY29udGVudCBzZWxlY3Q9XCJtYXQtZXJyb3IsW21hdEVycm9yXVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0SGludFRlbXBsYXRlPlxuICA8ZGl2IGNsYXNzPVwibWF0LW1kYy1mb3JtLWZpZWxkLWhpbnQtd3JhcHBlclwiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm1hdC1oaW50Om5vdChbYWxpZ249J2VuZCddKSxbbWF0SGludF1cIj48L25nLWNvbnRlbnQ+XG4gICAgPGRpdiBjbGFzcz1cIm1hdC1tZGMtZm9ybS1maWVsZC1oaW50LXNwYWNlclwiPjwvZGl2PlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm1hdC1oaW50W2FsaWduPSdlbmQnXVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19