@sumaris-net/ngx-components 18.3.29 → 18.3.30-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,240 @@
1
+ import { FocusMonitor } from '@angular/cdk/a11y';
2
+ import { AsyncPipe, JsonPipe } from '@angular/common';
3
+ import { ChangeDetectionStrategy, Component, ElementRef, booleanAttribute, computed, effect, forwardRef, inject, input, model, signal, untracked, viewChild, } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { FormBuilder, FormControl, FormGroup, FormsModule, NgControl, ReactiveFormsModule, Validators, } from '@angular/forms';
6
+ import { MAT_FORM_FIELD, MatFormFieldControl, MatFormFieldModule } from '@angular/material/form-field';
7
+ import { MatIconModule } from '@angular/material/icon';
8
+ import { Subject } from 'rxjs';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "@angular/forms";
11
+ import * as i2 from "@angular/material/form-field";
12
+ import * as i3 from "@angular/material/icon";
13
+ /** @title Form field with custom telephone number input control. */
14
+ export class FormFieldCustomControlExample {
15
+ form = new FormGroup({
16
+ tel: new FormControl(null),
17
+ });
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: FormFieldCustomControlExample, deps: [], target: i0.ɵɵFactoryTarget.Component });
19
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.11", type: FormFieldCustomControlExample, isStandalone: true, selector: "form-field-custom-control-example", ngImport: i0, template: `
20
+ <div [formGroup]="form">
21
+ <mat-form-field>
22
+ <mat-label>Phone number</mat-label>
23
+ <example-tel-input formControlName="tel" required></example-tel-input>
24
+ <mat-icon matSuffix>phone</mat-icon>
25
+ <mat-hint>Include area code</mat-hint>
26
+ </mat-form-field>
27
+ <p>Entered value: {{ form.valueChanges | async | json }}</p>
28
+ </div>
29
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: i0.forwardRef(() => FormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i1.RequiredValidator), selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatFormFieldModule) }, { kind: "component", type: i0.forwardRef(() => i2.MatFormField), selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i0.forwardRef(() => i2.MatLabel), selector: "mat-label" }, { kind: "directive", type: i0.forwardRef(() => i2.MatHint), selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i0.forwardRef(() => i2.MatSuffix), selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i0.forwardRef(() => MyTelInput), selector: "example-tel-input", inputs: ["aria-describedby", "placeholder", "required", "disabled", "value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatIconModule) }, { kind: "component", type: i0.forwardRef(() => i3.MatIcon), selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i0.forwardRef(() => AsyncPipe), name: "async" }, { kind: "pipe", type: i0.forwardRef(() => JsonPipe), name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
30
+ }
31
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: FormFieldCustomControlExample, decorators: [{
32
+ type: Component,
33
+ args: [{
34
+ selector: 'form-field-custom-control-example',
35
+ template: `
36
+ <div [formGroup]="form">
37
+ <mat-form-field>
38
+ <mat-label>Phone number</mat-label>
39
+ <example-tel-input formControlName="tel" required></example-tel-input>
40
+ <mat-icon matSuffix>phone</mat-icon>
41
+ <mat-hint>Include area code</mat-hint>
42
+ </mat-form-field>
43
+ <p>Entered value: {{ form.valueChanges | async | json }}</p>
44
+ </div>
45
+ `,
46
+ standalone: true,
47
+ imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, forwardRef(() => MyTelInput), MatIconModule, AsyncPipe, JsonPipe],
48
+ changeDetection: ChangeDetectionStrategy.OnPush,
49
+ }]
50
+ }] });
51
+ /** Data structure for holding telephone number. */
52
+ export class MyTel {
53
+ area;
54
+ exchange;
55
+ subscriber;
56
+ constructor(area, exchange, subscriber) {
57
+ this.area = area;
58
+ this.exchange = exchange;
59
+ this.subscriber = subscriber;
60
+ }
61
+ }
62
+ /** Custom `MatFormFieldControl` for telephone number input. */
63
+ export class MyTelInput {
64
+ static nextId = 0;
65
+ areaInput = viewChild.required('area');
66
+ exchangeInput = viewChild.required('exchange');
67
+ subscriberInput = viewChild.required('subscriber');
68
+ ngControl = inject(NgControl, { optional: true, self: true });
69
+ parts;
70
+ stateChanges = new Subject();
71
+ touched = signal(false);
72
+ controlType = 'example-tel-input';
73
+ id = `example-tel-input-${MyTelInput.nextId++}`;
74
+ _userAriaDescribedBy = input('', { alias: 'aria-describedby' });
75
+ _placeholder = input('', { alias: 'placeholder' });
76
+ _required = input(false, {
77
+ alias: 'required',
78
+ transform: booleanAttribute,
79
+ });
80
+ _disabledByInput = input(false, {
81
+ alias: 'disabled',
82
+ transform: booleanAttribute,
83
+ });
84
+ _value = model(null, { alias: 'value' });
85
+ onChange = (_) => { };
86
+ onTouched = () => { };
87
+ _formField = inject(MAT_FORM_FIELD, {
88
+ optional: true,
89
+ });
90
+ _focused = signal(false);
91
+ _disabledByCva = signal(false);
92
+ _disabled = computed(() => this._disabledByInput() || this._disabledByCva());
93
+ _focusMonitor = inject(FocusMonitor);
94
+ _elementRef = inject(ElementRef);
95
+ get focused() {
96
+ return this._focused();
97
+ }
98
+ get empty() {
99
+ const { value: { area, exchange, subscriber }, } = this.parts;
100
+ return !area && !exchange && !subscriber;
101
+ }
102
+ get shouldLabelFloat() {
103
+ return this.focused || !this.empty;
104
+ }
105
+ get userAriaDescribedBy() {
106
+ return this._userAriaDescribedBy();
107
+ }
108
+ get placeholder() {
109
+ return this._placeholder();
110
+ }
111
+ get required() {
112
+ return this._required();
113
+ }
114
+ get disabled() {
115
+ return this._disabled();
116
+ }
117
+ get value() {
118
+ return this._value();
119
+ }
120
+ get errorState() {
121
+ return this.parts.invalid && this.touched();
122
+ }
123
+ constructor() {
124
+ if (this.ngControl != null) {
125
+ this.ngControl.valueAccessor = this;
126
+ }
127
+ this.parts = inject(FormBuilder).group({
128
+ area: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(3)]],
129
+ exchange: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(3)]],
130
+ subscriber: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(4)]],
131
+ });
132
+ effect(() => {
133
+ // Read signals to trigger effect.
134
+ this._placeholder();
135
+ this._required();
136
+ this._disabled();
137
+ this._focused();
138
+ // Propagate state changes.
139
+ untracked(() => this.stateChanges.next());
140
+ });
141
+ effect(() => {
142
+ if (this._disabled()) {
143
+ untracked(() => this.parts.disable());
144
+ }
145
+ else {
146
+ untracked(() => this.parts.enable());
147
+ }
148
+ });
149
+ effect(() => {
150
+ const value = this._value() || new MyTel('', '', '');
151
+ untracked(() => this.parts.setValue(value));
152
+ });
153
+ this.parts.statusChanges.pipe(takeUntilDestroyed()).subscribe(() => {
154
+ this.stateChanges.next();
155
+ });
156
+ this.parts.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => {
157
+ const tel = this.parts.valid
158
+ ? new MyTel(this.parts.value.area || '', this.parts.value.exchange || '', this.parts.value.subscriber || '')
159
+ : null;
160
+ this._updateValue(tel);
161
+ });
162
+ }
163
+ ngOnDestroy() {
164
+ this.stateChanges.complete();
165
+ this._focusMonitor.stopMonitoring(this._elementRef);
166
+ }
167
+ onFocusIn() {
168
+ if (!this._focused()) {
169
+ this._focused.set(true);
170
+ }
171
+ }
172
+ onFocusOut(event) {
173
+ if (!this._elementRef.nativeElement.contains(event.relatedTarget)) {
174
+ this.touched.set(true);
175
+ this._focused.set(false);
176
+ this.onTouched();
177
+ }
178
+ }
179
+ autoFocusNext(control, nextElement) {
180
+ if (!control.errors && nextElement) {
181
+ this._focusMonitor.focusVia(nextElement, 'program');
182
+ }
183
+ }
184
+ autoFocusPrev(control, prevElement) {
185
+ if (control.value.length < 1) {
186
+ this._focusMonitor.focusVia(prevElement, 'program');
187
+ }
188
+ }
189
+ setDescribedByIds(ids) {
190
+ const controlElement = this._elementRef.nativeElement.querySelector('.example-tel-input-container');
191
+ controlElement.setAttribute('aria-describedby', ids.join(' '));
192
+ }
193
+ onContainerClick() {
194
+ if (this.parts.controls.subscriber.valid) {
195
+ this._focusMonitor.focusVia(this.subscriberInput(), 'program');
196
+ }
197
+ else if (this.parts.controls.exchange.valid) {
198
+ this._focusMonitor.focusVia(this.subscriberInput(), 'program');
199
+ }
200
+ else if (this.parts.controls.area.valid) {
201
+ this._focusMonitor.focusVia(this.exchangeInput(), 'program');
202
+ }
203
+ else {
204
+ this._focusMonitor.focusVia(this.areaInput(), 'program');
205
+ }
206
+ }
207
+ writeValue(tel) {
208
+ this._updateValue(tel);
209
+ }
210
+ registerOnChange(fn) {
211
+ this.onChange = fn;
212
+ }
213
+ registerOnTouched(fn) {
214
+ this.onTouched = fn;
215
+ }
216
+ setDisabledState(isDisabled) {
217
+ this._disabledByCva.set(isDisabled);
218
+ }
219
+ _handleInput(control, nextElement) {
220
+ this.autoFocusNext(control, nextElement);
221
+ this.onChange(this.value);
222
+ }
223
+ _updateValue(tel) {
224
+ const current = this._value();
225
+ if (tel === current || (tel?.area === current?.area && tel?.exchange === current?.exchange && tel?.subscriber === current?.subscriber)) {
226
+ return;
227
+ }
228
+ this._value.set(tel);
229
+ }
230
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MyTelInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
231
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.11", type: MyTelInput, isStandalone: true, selector: "example-tel-input", inputs: { _userAriaDescribedBy: { classPropertyName: "_userAriaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, _placeholder: { classPropertyName: "_placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, _required: { classPropertyName: "_required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, _disabledByInput: { classPropertyName: "_disabledByInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, _value: { classPropertyName: "_value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { _value: "valueChange" }, host: { properties: { "class.example-floating": "shouldLabelFloat", "id": "id" } }, providers: [{ provide: MatFormFieldControl, useExisting: MyTelInput }], viewQueries: [{ propertyName: "areaInput", first: true, predicate: ["area"], descendants: true, isSignal: true }, { propertyName: "exchangeInput", first: true, predicate: ["exchange"], descendants: true, isSignal: true }, { propertyName: "subscriberInput", first: true, predicate: ["subscriber"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n role=\"group\"\n class=\"example-tel-input-container\"\n [formGroup]=\"parts\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut($event)\"\n>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"area\"\n size=\"3\"\n maxLength=\"3\"\n aria-label=\"Area code\"\n (input)=\"_handleInput(parts.controls.area, exchange)\"\n #area\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"exchange\"\n maxLength=\"3\"\n size=\"3\"\n aria-label=\"Exchange code\"\n (input)=\"_handleInput(parts.controls.exchange, subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.exchange, area)\"\n #exchange\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"subscriber\"\n maxLength=\"4\"\n size=\"4\"\n aria-label=\"Subscriber number\"\n (input)=\"_handleInput(parts.controls.subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.subscriber, exchange)\"\n #subscriber\n />\n</div>\n", styles: [".example-tel-input-container{display:flex}.example-tel-input-element{border:none;background:none;padding:0;outline:none;font:inherit;text-align:center;color:currentcolor}.example-tel-input-spacer{opacity:0;transition:opacity .2s}:host.example-floating .example-tel-input-spacer{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
232
+ }
233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MyTelInput, decorators: [{
234
+ type: Component,
235
+ args: [{ selector: 'example-tel-input', providers: [{ provide: MatFormFieldControl, useExisting: MyTelInput }], host: {
236
+ '[class.example-floating]': 'shouldLabelFloat',
237
+ '[id]': 'id',
238
+ }, standalone: true, imports: [FormsModule, ReactiveFormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n role=\"group\"\n class=\"example-tel-input-container\"\n [formGroup]=\"parts\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut($event)\"\n>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"area\"\n size=\"3\"\n maxLength=\"3\"\n aria-label=\"Area code\"\n (input)=\"_handleInput(parts.controls.area, exchange)\"\n #area\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"exchange\"\n maxLength=\"3\"\n size=\"3\"\n aria-label=\"Exchange code\"\n (input)=\"_handleInput(parts.controls.exchange, subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.exchange, area)\"\n #exchange\n />\n <span class=\"example-tel-input-spacer\">&ndash;</span>\n <input\n class=\"example-tel-input-element\"\n formControlName=\"subscriber\"\n maxLength=\"4\"\n size=\"4\"\n aria-label=\"Subscriber number\"\n (input)=\"_handleInput(parts.controls.subscriber)\"\n (keyup.backspace)=\"autoFocusPrev(parts.controls.subscriber, exchange)\"\n #subscriber\n />\n</div>\n", styles: [".example-tel-input-container{display:flex}.example-tel-input-element{border:none;background:none;padding:0;outline:none;font:inherit;text-align:center;color:currentcolor}.example-tel-input-spacer{opacity:0;transition:opacity .2s}:host.example-floating .example-tel-input-spacer{opacity:1}\n"] }]
239
+ }], ctorParameters: () => [] });
240
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NoYXJlZC9tYXRlcmlhbC90ZXN0L3Rlc3QtY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvbWF0ZXJpYWwvdGVzdC90ZXN0LWNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RELE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFVBQVUsRUFFVixnQkFBZ0IsRUFDaEIsUUFBUSxFQUNSLE1BQU0sRUFDTixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEUsT0FBTyxFQUdMLFdBQVcsRUFDWCxXQUFXLEVBQ1gsU0FBUyxFQUNULFdBQVcsRUFDWCxTQUFTLEVBQ1QsbUJBQW1CLEVBQ25CLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN2RyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7QUFFL0Isb0VBQW9FO0FBa0JwRSxNQUFNLE9BQU8sNkJBQTZCO0lBQy9CLElBQUksR0FBRyxJQUFJLFNBQVMsQ0FBQztRQUM1QixHQUFHLEVBQUUsSUFBSSxXQUFXLENBQUMs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cUJBQ2IsY0FDVyxJQUFJLFdBQ1AsQ0FBQyxXQUFXLEVBQUUsbUJBQW1CLENBQUMsbUJBQzFCLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb2N1c01vbml0b3IgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBBc3luY1BpcGUsIEpzb25QaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIE9uRGVzdHJveSxcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgZm9yd2FyZFJlZixcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgbW9kZWwsXG4gIHNpZ25hbCxcbiAgdW50cmFja2VkLFxuICB2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHtcbiAgQWJzdHJhY3RDb250cm9sLFxuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgRm9ybUJ1aWxkZXIsXG4gIEZvcm1Db250cm9sLFxuICBGb3JtR3JvdXAsXG4gIEZvcm1zTW9kdWxlLFxuICBOZ0NvbnRyb2wsXG4gIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gIFZhbGlkYXRvcnMsXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1BVF9GT1JNX0ZJRUxELCBNYXRGb3JtRmllbGRDb250cm9sLCBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuLyoqIEB0aXRsZSBGb3JtIGZpZWxkIHdpdGggY3VzdG9tIHRlbGVwaG9uZSBudW1iZXIgaW5wdXQgY29udHJvbC4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Zvcm0tZmllbGQtY3VzdG9tLWNvbnRyb2wtZXhhbXBsZScsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPG1hdC1sYWJlbD5QaG9uZSBudW1iZXI8L21hdC1sYWJlbD5cbiAgICAgICAgPGV4YW1wbGUtdGVsLWlucHV0IGZvcm1Db250cm9sTmFtZT1cInRlbFwiIHJlcXVpcmVkPjwvZXhhbXBsZS10ZWwtaW5wdXQ+XG4gICAgICAgIDxtYXQtaWNvbiBtYXRTdWZmaXg+cGhvbmU8L21hdC1pY29uPlxuICAgICAgICA8bWF0LWhpbnQ+SW5jbHVkZSBhcmVhIGNvZGU8L21hdC1oaW50PlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDxwPkVudGVyZWQgdmFsdWU6IHt7IGZvcm0udmFsdWVDaGFuZ2VzIHwgYXN5bmMgfCBqc29uIH19PC9wPlxuICAgIDwvZGl2PlxuICBgLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIE1hdEZvcm1GaWVsZE1vZHVsZSwgZm9yd2FyZFJlZigoKSA9PiBNeVRlbElucHV0KSwgTWF0SWNvbk1vZHVsZSwgQXN5bmNQaXBlLCBKc29uUGlwZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBGb3JtRmllbGRDdXN0b21Db250cm9sRXhhbXBsZSB7XG4gIHJlYWRvbmx5IGZvcm0gPSBuZXcgRm9ybUdyb3VwKHtcbiAgICB0ZWw6IG5ldyBGb3JtQ29udHJvbChudWxsKSxcbiAgfSk7XG59XG5cbi8qKiBEYXRhIHN0cnVjdHVyZSBmb3IgaG9sZGluZyB0ZWxlcGhvbmUgbnVtYmVyLiAqL1xuZXhwb3J0IGNsYXNzIE15VGVsIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGFyZWE6IHN0cmluZyxcbiAgICBwdWJsaWMgZXhjaGFuZ2U6IHN0cmluZyxcbiAgICBwdWJsaWMgc3Vic2NyaWJlcjogc3RyaW5nXG4gICkge31cbn1cblxuLyoqIEN1c3RvbSBgTWF0Rm9ybUZpZWxkQ29udHJvbGAgZm9yIHRlbGVwaG9uZSBudW1iZXIgaW5wdXQuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdleGFtcGxlLXRlbC1pbnB1dCcsXG4gIHRlbXBsYXRlVXJsOiAndGVzdC1jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAndGVzdC1jb21wb25lbnQuY3NzJyxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBNYXRGb3JtRmllbGRDb250cm9sLCB1c2VFeGlzdGluZzogTXlUZWxJbnB1dCB9XSxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MuZXhhbXBsZS1mbG9hdGluZ10nOiAnc2hvdWxkTGFiZWxGbG9hdCcsXG4gICAgJ1tpZF0nOiAnaWQnLFxuICB9LFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgTXlUZWxJbnB1dCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBNYXRGb3JtRmllbGRDb250cm9sPE15VGVsPiwgT25EZXN0cm95IHtcbiAgc3RhdGljIG5leHRJZCA9IDA7XG4gIHJlYWRvbmx5IGFyZWFJbnB1dCA9IHZpZXdDaGlsZC5yZXF1aXJlZDxIVE1MSW5wdXRFbGVtZW50PignYXJlYScpO1xuICByZWFkb25seSBleGNoYW5nZUlucHV0ID0gdmlld0NoaWxkLnJlcXVpcmVkPEhUTUxJbnB1dEVsZW1lbnQ+KCdleGNoYW5nZScpO1xuICByZWFkb25seSBzdWJzY3JpYmVySW5wdXQgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8SFRNTElucHV0RWxlbWVudD4oJ3N1YnNjcmliZXInKTtcbiAgbmdDb250cm9sID0gaW5qZWN0KE5nQ29udHJvbCwgeyBvcHRpb25hbDogdHJ1ZSwgc2VsZjogdHJ1ZSB9KTtcbiAgcmVhZG9ubHkgcGFydHM6IEZvcm1Hcm91cDx7XG4gICAgYXJlYTogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XG4gICAgZXhjaGFuZ2U6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+O1xuICAgIHN1YnNjcmliZXI6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+O1xuICB9PjtcbiAgcmVhZG9ubHkgc3RhdGVDaGFuZ2VzID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcmVhZG9ubHkgdG91Y2hlZCA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGNvbnRyb2xUeXBlID0gJ2V4YW1wbGUtdGVsLWlucHV0JztcbiAgcmVhZG9ubHkgaWQgPSBgZXhhbXBsZS10ZWwtaW5wdXQtJHtNeVRlbElucHV0Lm5leHRJZCsrfWA7XG4gIHJlYWRvbmx5IF91c2VyQXJpYURlc2NyaWJlZEJ5ID0gaW5wdXQ8c3RyaW5nPignJywgeyBhbGlhczogJ2FyaWEtZGVzY3JpYmVkYnknIH0pO1xuICByZWFkb25seSBfcGxhY2Vob2xkZXIgPSBpbnB1dDxzdHJpbmc+KCcnLCB7IGFsaWFzOiAncGxhY2Vob2xkZXInIH0pO1xuICByZWFkb25seSBfcmVxdWlyZWQgPSBpbnB1dDxib29sZWFuLCB1bmtub3duPihmYWxzZSwge1xuICAgIGFsaWFzOiAncmVxdWlyZWQnLFxuICAgIHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSxcbiAgfSk7XG4gIHJlYWRvbmx5IF9kaXNhYmxlZEJ5SW5wdXQgPSBpbnB1dDxib29sZWFuLCB1bmtub3duPihmYWxzZSwge1xuICAgIGFsaWFzOiAnZGlzYWJsZWQnLFxuICAgIHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSxcbiAgfSk7XG4gIHJlYWRvbmx5IF92YWx1ZSA9IG1vZGVsPE15VGVsIHwgbnVsbD4obnVsbCwgeyBhbGlhczogJ3ZhbHVlJyB9KTtcbiAgb25DaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcbiAgb25Ub3VjaGVkID0gKCkgPT4ge307XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9mb3JtRmllbGQgPSBpbmplY3QoTUFUX0ZPUk1fRklFTEQsIHtcbiAgICBvcHRpb25hbDogdHJ1ZSxcbiAgfSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZm9jdXNlZCA9IHNpZ25hbChmYWxzZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rpc2FibGVkQnlDdmEgPSBzaWduYWwoZmFsc2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kaXNhYmxlZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX2Rpc2FibGVkQnlJbnB1dCgpIHx8IHRoaXMuX2Rpc2FibGVkQnlDdmEoKSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZvY3VzTW9uaXRvciA9IGluamVjdChGb2N1c01vbml0b3IpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50UmVmID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKTtcblxuICBnZXQgZm9jdXNlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fZm9jdXNlZCgpO1xuICB9XG5cbiAgZ2V0IGVtcHR5KCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHZhbHVlOiB7IGFyZWEsIGV4Y2hhbmdlLCBzdWJzY3JpYmVyIH0sXG4gICAgfSA9IHRoaXMucGFydHM7XG5cbiAgICByZXR1cm4gIWFyZWEgJiYgIWV4Y2hhbmdlICYmICFzdWJzY3JpYmVyO1xuICB9XG5cbiAgZ2V0IHNob3VsZExhYmVsRmxvYXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9jdXNlZCB8fCAhdGhpcy5lbXB0eTtcbiAgfVxuXG4gIGdldCB1c2VyQXJpYURlc2NyaWJlZEJ5KCkge1xuICAgIHJldHVybiB0aGlzLl91c2VyQXJpYURlc2NyaWJlZEJ5KCk7XG4gIH1cblxuICBnZXQgcGxhY2Vob2xkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fcGxhY2Vob2xkZXIoKTtcbiAgfVxuXG4gIGdldCByZXF1aXJlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fcmVxdWlyZWQoKTtcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWQoKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBNeVRlbCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZSgpO1xuICB9XG5cbiAgZ2V0IGVycm9yU3RhdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucGFydHMuaW52YWxpZCAmJiB0aGlzLnRvdWNoZWQoKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGlmICh0aGlzLm5nQ29udHJvbCAhPSBudWxsKSB7XG4gICAgICB0aGlzLm5nQ29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLnBhcnRzID0gaW5qZWN0KEZvcm1CdWlsZGVyKS5ncm91cCh7XG4gICAgICBhcmVhOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbkxlbmd0aCgzKSwgVmFsaWRhdG9ycy5tYXhMZW5ndGgoMyldXSxcbiAgICAgIGV4Y2hhbmdlOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbkxlbmd0aCgzKSwgVmFsaWRhdG9ycy5tYXhMZW5ndGgoMyldXSxcbiAgICAgIHN1YnNjcmliZXI6IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWluTGVuZ3RoKDQpLCBWYWxpZGF0b3JzLm1heExlbmd0aCg0KV1dLFxuICAgIH0pO1xuXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIC8vIFJlYWQgc2lnbmFscyB0byB0cmlnZ2VyIGVmZmVjdC5cbiAgICAgIHRoaXMuX3BsYWNlaG9sZGVyKCk7XG4gICAgICB0aGlzLl9yZXF1aXJlZCgpO1xuICAgICAgdGhpcy5fZGlzYWJsZWQoKTtcbiAgICAgIHRoaXMuX2ZvY3VzZWQoKTtcbiAgICAgIC8vIFByb3BhZ2F0ZSBzdGF0ZSBjaGFuZ2VzLlxuICAgICAgdW50cmFja2VkKCgpID0+IHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKSk7XG4gICAgfSk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX2Rpc2FibGVkKCkpIHtcbiAgICAgICAgdW50cmFja2VkKCgpID0+IHRoaXMucGFydHMuZGlzYWJsZSgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLnBhcnRzLmVuYWJsZSgpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3ZhbHVlKCkgfHwgbmV3IE15VGVsKCcnLCAnJywgJycpO1xuICAgICAgdW50cmFja2VkKCgpID0+IHRoaXMucGFydHMuc2V0VmFsdWUodmFsdWUpKTtcbiAgICB9KTtcblxuICAgIHRoaXMucGFydHMuc3RhdHVzQ2hhbmdlcy5waXBlKHRha2VVbnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5wYXJ0cy52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3QgdGVsID0gdGhpcy5wYXJ0cy52YWxpZFxuICAgICAgICA/IG5ldyBNeVRlbCh0aGlzLnBhcnRzLnZhbHVlLmFyZWEgfHwgJycsIHRoaXMucGFydHMudmFsdWUuZXhjaGFuZ2UgfHwgJycsIHRoaXMucGFydHMudmFsdWUuc3Vic2NyaWJlciB8fCAnJylcbiAgICAgICAgOiBudWxsO1xuICAgICAgdGhpcy5fdXBkYXRlVmFsdWUodGVsKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VzLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5fZm9jdXNNb25pdG9yLnN0b3BNb25pdG9yaW5nKHRoaXMuX2VsZW1lbnRSZWYpO1xuICB9XG5cbiAgb25Gb2N1c0luKCkge1xuICAgIGlmICghdGhpcy5fZm9jdXNlZCgpKSB7XG4gICAgICB0aGlzLl9mb2N1c2VkLnNldCh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBvbkZvY3VzT3V0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgaWYgKCF0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCBhcyBFbGVtZW50KSkge1xuICAgICAgdGhpcy50b3VjaGVkLnNldCh0cnVlKTtcbiAgICAgIHRoaXMuX2ZvY3VzZWQuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgfVxuICB9XG5cbiAgYXV0b0ZvY3VzTmV4dChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIG5leHRFbGVtZW50PzogSFRNTElucHV0RWxlbWVudCk6IHZvaWQge1xuICAgIGlmICghY29udHJvbC5lcnJvcnMgJiYgbmV4dEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuX2ZvY3VzTW9uaXRvci5mb2N1c1ZpYShuZXh0RWxlbWVudCwgJ3Byb2dyYW0nKTtcbiAgICB9XG4gIH1cblxuICBhdXRvRm9jdXNQcmV2KGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgcHJldkVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAoY29udHJvbC52YWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aGlzLl9mb2N1c01vbml0b3IuZm9jdXNWaWEocHJldkVsZW1lbnQsICdwcm9ncmFtJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0RGVzY3JpYmVkQnlJZHMoaWRzOiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IGNvbnRyb2xFbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5leGFtcGxlLXRlbC1pbnB1dC1jb250YWluZXInKSE7XG4gICAgY29udHJvbEVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5JywgaWRzLmpvaW4oJyAnKSk7XG4gIH1cblxuICBvbkNvbnRhaW5lckNsaWNrKCkge1xuICAgIGlmICh0aGlzLnBhcnRzLmNvbnRyb2xzLnN1YnNjcmliZXIudmFsaWQpIHtcbiAgICAgIHRoaXMuX2ZvY3VzTW9uaXRvci5mb2N1c1ZpYSh0aGlzLnN1YnNjcmliZXJJbnB1dCgpLCAncHJvZ3JhbScpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5wYXJ0cy5jb250cm9scy5leGNoYW5nZS52YWxpZCkge1xuICAgICAgdGhpcy5fZm9jdXNNb25pdG9yLmZvY3VzVmlhKHRoaXMuc3Vic2NyaWJlcklucHV0KCksICdwcm9ncmFtJyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnBhcnRzLmNvbnRyb2xzLmFyZWEudmFsaWQpIHtcbiAgICAgIHRoaXMuX2ZvY3VzTW9uaXRvci5mb2N1c1ZpYSh0aGlzLmV4Y2hhbmdlSW5wdXQoKSwgJ3Byb2dyYW0nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZm9jdXNNb25pdG9yLmZvY3VzVmlhKHRoaXMuYXJlYUlucHV0KCksICdwcm9ncmFtJyk7XG4gICAgfVxuICB9XG5cbiAgd3JpdGVWYWx1ZSh0ZWw6IE15VGVsIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKHRlbCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuX2Rpc2FibGVkQnlDdmEuc2V0KGlzRGlzYWJsZWQpO1xuICB9XG5cbiAgX2hhbmRsZUlucHV0KGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgbmV4dEVsZW1lbnQ/OiBIVE1MSW5wdXRFbGVtZW50KTogdm9pZCB7XG4gICAgdGhpcy5hdXRvRm9jdXNOZXh0KGNvbnRyb2wsIG5leHRFbGVtZW50KTtcbiAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlVmFsdWUodGVsOiBNeVRlbCB8IG51bGwpIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5fdmFsdWUoKTtcbiAgICBpZiAodGVsID09PSBjdXJyZW50IHx8ICh0ZWw/LmFyZWEgPT09IGN1cnJlbnQ/LmFyZWEgJiYgdGVsPy5leGNoYW5nZSA9PT0gY3VycmVudD8uZXhjaGFuZ2UgJiYgdGVsPy5zdWJzY3JpYmVyID09PSBjdXJyZW50Py5zdWJzY3JpYmVyKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl92YWx1ZS5zZXQodGVsKTtcbiAgfVxufVxuIiwiPGRpdlxuICByb2xlPVwiZ3JvdXBcIlxuICBjbGFzcz1cImV4YW1wbGUtdGVsLWlucHV0LWNvbnRhaW5lclwiXG4gIFtmb3JtR3JvdXBdPVwicGFydHNcIlxuICBbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwiX2Zvcm1GaWVsZD8uZ2V0TGFiZWxJZCgpXCJcbiAgKGZvY3VzaW4pPVwib25Gb2N1c0luKClcIlxuICAoZm9jdXNvdXQpPVwib25Gb2N1c091dCgkZXZlbnQpXCJcbj5cbiAgPGlucHV0XG4gICAgY2xhc3M9XCJleGFtcGxlLXRlbC1pbnB1dC1lbGVtZW50XCJcbiAgICBmb3JtQ29udHJvbE5hbWU9XCJhcmVhXCJcbiAgICBzaXplPVwiM1wiXG4gICAgbWF4TGVuZ3RoPVwiM1wiXG4gICAgYXJpYS1sYWJlbD1cIkFyZWEgY29kZVwiXG4gICAgKGlucHV0KT1cIl9oYW5kbGVJbnB1dChwYXJ0cy5jb250cm9scy5hcmVhLCBleGNoYW5nZSlcIlxuICAgICNhcmVhXG4gIC8+XG4gIDxzcGFuIGNsYXNzPVwiZXhhbXBsZS10ZWwtaW5wdXQtc3BhY2VyXCI+Jm5kYXNoOzwvc3Bhbj5cbiAgPGlucHV0XG4gICAgY2xhc3M9XCJleGFtcGxlLXRlbC1pbnB1dC1lbGVtZW50XCJcbiAgICBmb3JtQ29udHJvbE5hbWU9XCJleGNoYW5nZVwiXG4gICAgbWF4TGVuZ3RoPVwiM1wiXG4gICAgc2l6ZT1cIjNcIlxuICAgIGFyaWEtbGFiZWw9XCJFeGNoYW5nZSBjb2RlXCJcbiAgICAoaW5wdXQpPVwiX2hhbmRsZUlucHV0KHBhcnRzLmNvbnRyb2xzLmV4Y2hhbmdlLCBzdWJzY3JpYmVyKVwiXG4gICAgKGtleXVwLmJhY2tzcGFjZSk9XCJhdXRvRm9jdXNQcmV2KHBhcnRzLmNvbnRyb2xzLmV4Y2hhbmdlLCBhcmVhKVwiXG4gICAgI2V4Y2hhbmdlXG4gIC8+XG4gIDxzcGFuIGNsYXNzPVwiZXhhbXBsZS10ZWwtaW5wdXQtc3BhY2VyXCI+Jm5kYXNoOzwvc3Bhbj5cbiAgPGlucHV0XG4gICAgY2xhc3M9XCJleGFtcGxlLXRlbC1pbnB1dC1lbGVtZW50XCJcbiAgICBmb3JtQ29udHJvbE5hbWU9XCJzdWJzY3JpYmVyXCJcbiAgICBtYXhMZW5ndGg9XCI0XCJcbiAgICBzaXplPVwiNFwiXG4gICAgYXJpYS1sYWJlbD1cIlN1YnNjcmliZXIgbnVtYmVyXCJcbiAgICAoaW5wdXQpPVwiX2hhbmRsZUlucHV0KHBhcnRzLmNvbnRyb2xzLnN1YnNjcmliZXIpXCJcbiAgICAoa2V5dXAuYmFja3NwYWNlKT1cImF1dG9Gb2N1c1ByZXYocGFydHMuY29udHJvbHMuc3Vic2NyaWJlciwgZXhjaGFuZ2UpXCJcbiAgICAjc3Vic2NyaWJlclxuICAvPlxuPC9kaXY+XG4iXX0=