@bnsights/bbsf-controls 1.0.145 → 1.0.147

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,14 @@ BBSF Controls package is part of BBSF 3 packages. It has all the form controls t
5
5
  For more info please visit [BBSF Controls documenation](https://bbsfadmin.bnsights.com/controls) or [BBSF documentation](https://bnsightsprojects.visualstudio.com/BBSF%203/_wiki/wikis/BBSF-3.wiki/65/BBSF-Documentation)
6
6
 
7
7
  # Change Log
8
+ ## 1.0.147 / 4-8-2024
9
+ ===================
10
+ * fixed bug in speech to text of TextAreaComponent
11
+
12
+ ## 1.0.146 / 4-8-2024
13
+ ===================
14
+ * added feature spech to text into TextAreaComponent
15
+
8
16
  ## 1.0.145 / 24-7-2024
9
17
  ===================
10
18
  * fix naming in file upload control
@@ -1,4 +1,16 @@
1
1
  import { ControlOptionsBase } from './ControlOptionsBase';
2
2
  export class TextAreaOptions extends ControlOptionsBase {
3
+ constructor() {
4
+ super(...arguments);
5
+ /**To set value to Control */
6
+ this.value = '';
7
+ //** Set flag to enable or disable speech (mic) in textarea*/
8
+ this.enableSpeechRecognition = false;
9
+ //** Set array of available languages for speech to text*/
10
+ this.speechLanguages = undefined;
11
+ this.selectedSpeechLanguage = '';
12
+ //Enable auto save speech language into local storage
13
+ this.autoSaveSpeechLanguagetoLocalStorage = true;
14
+ }
3
15
  }
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dEFyZWFPcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYmJzZi1jb250cm9scy9zcmMvbGliL1NoYXJlZC9Nb2RlbHMvVGV4dEFyZWFPcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRzFELE1BQU0sT0FBTyxlQUFnQixTQUFRLGtCQUFrQjtDQXVCdEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb3JjZURpcmVjdGlvbiB9IGZyb20gJy4uL0VudW1zL0ZvcmNlRGlyZWN0aW9uJztcclxuaW1wb3J0IHsgQ29udHJvbE9wdGlvbnNCYXNlIH0gZnJvbSAnLi9Db250cm9sT3B0aW9uc0Jhc2UnO1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBUZXh0QXJlYU9wdGlvbnMgZXh0ZW5kcyBDb250cm9sT3B0aW9uc0Jhc2Uge1xyXG4gIC8qKlRvIHNldCAgdmFsdWUgIHRvIENvbnRyb2wgKi9cclxuICB2YWx1ZTogYW55XHJcbiAgLy8qKiBTZXQgdGhlIE1heExlbmd0aCBvZiBjaGFyYWN0ZXJzIEluIFRleHRBcmVhICovXHJcbiAgbWF4TGVuZ3RoPzogbnVtYmVyXHJcbiAgLyoqU2V0IHRoZSBNaW5MZW5ndGggb2YgY2hhcmFjdGVycyBJbiBUZXh0QXJlYSAgKi9cclxuICBtaW5MZW5ndGg/OiBudW1iZXJcclxuICAvKipTZXQgTnVtYmVyIE9mIFJvd3MgICovXHJcbiAgcm93czogbnVtYmVyXHJcbiAgLyoqU2V0IE51bWJlciBPZiBjb2x1bW5zICAqL1xyXG4gIGNvbHM6IG51bWJlclxyXG4gIC8vKiogU2V0IHRoZSBNYXhXb3JkQ291bnQgb2YgY2hhcmFjdGVycyBJbiBUZXh0QXJlYSAqL1xyXG4gIG1heFdvcmRDb3VudDogbnVtYmVyO1xyXG4gIC8qKlByZXZlbnQgQXV0b0NvbXBsZXRlIG9mIFRleHRBcmVhKi9cclxuICBhdXRvQ29tcGxldGU6IGJvb2xlYW5cclxuICAvKiogIHRleHQgaW5wdXQgb24gY2hhbmdlICAqL1xyXG4gIHRyaW1UZXh0T25DaGFuZ2U6IGJvb2xlYW5cclxuICAvKiogYWRkIGJ1dHRvbiB0byBmb3IgY29waW5nIHRvIGNsaXBib2FyZCAqL1xyXG4gIGVuYWJsZUNvcHlUb0NsaXBib2FyZDogYm9vbGVhblxyXG4gIC8qKiB0byBzZXQgRGlyZWN0aW9uIG9mIFRleHRBcmVhICBpZiBUZXh0QXJlYSBpcyBBcmFiaWMgb3IgRW5nbGlzaCAgKi9cclxuICBmb3JjZURpcmVjdGlvbjogRm9yY2VEaXJlY3Rpb25cclxuICAvLyoqIFNldCB0aGUgTWF4TGVuZ3RoIExpbWl0IHRvIHNob3cgd2FybmluZyBtZXNzYWdlKi9cclxuICBtYXhMZW5ndGhXYXJuaW5nTGltaXQ6IG51bWJlcjtcclxufVxyXG4iXX0=
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dEFyZWFPcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYmJzZi1jb250cm9scy9zcmMvbGliL1NoYXJlZC9Nb2RlbHMvVGV4dEFyZWFPcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRzFELE1BQU0sT0FDTixlQUFnQixTQUFRLGtCQUFrQjtJQUQxQzs7UUFFRSwrQkFBK0I7UUFDL0IsVUFBSyxHQUFNLEVBQUUsQ0FBQTtRQXFCYiw2REFBNkQ7UUFDN0QsNEJBQXVCLEdBQVMsS0FBSyxDQUFDO1FBQ3RDLDBEQUEwRDtRQUMxRCxvQkFBZSxHQUFrQixTQUFTLENBQUM7UUFDM0MsMkJBQXNCLEdBQVMsRUFBRSxDQUFDO1FBT2xDLHFEQUFxRDtRQUNyRCx5Q0FBb0MsR0FBWSxJQUFJLENBQUM7SUFFdkQsQ0FBQztDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTGFuZ3VhZ2VEVE8gfSBmcm9tICdAYm5zaWdodHMvYmJzZi11dGlsaXRpZXMvbGliL3NoYXJlZC9tb2RlbHMnO1xyXG5pbXBvcnQgeyBGb3JjZURpcmVjdGlvbiB9IGZyb20gJy4uL0VudW1zL0ZvcmNlRGlyZWN0aW9uJztcclxuaW1wb3J0IHsgQ29udHJvbE9wdGlvbnNCYXNlIH0gZnJvbSAnLi9Db250cm9sT3B0aW9uc0Jhc2UnO1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBcclxuVGV4dEFyZWFPcHRpb25zIGV4dGVuZHMgQ29udHJvbE9wdGlvbnNCYXNlIHtcclxuICAvKipUbyBzZXQgIHZhbHVlICB0byBDb250cm9sICovXHJcbiAgdmFsdWU6IGFueT0nJ1xyXG4gIC8vKiogU2V0IHRoZSBNYXhMZW5ndGggb2YgY2hhcmFjdGVycyBJbiBUZXh0QXJlYSAqL1xyXG4gIG1heExlbmd0aD86IG51bWJlclxyXG4gIC8qKlNldCB0aGUgTWluTGVuZ3RoIG9mIGNoYXJhY3RlcnMgSW4gVGV4dEFyZWEgICovXHJcbiAgbWluTGVuZ3RoPzogbnVtYmVyXHJcbiAgLyoqU2V0IE51bWJlciBPZiBSb3dzICAqL1xyXG4gIHJvd3M6IG51bWJlclxyXG4gIC8qKlNldCBOdW1iZXIgT2YgY29sdW1ucyAgKi9cclxuICBjb2xzOiBudW1iZXJcclxuICAvLyoqIFNldCB0aGUgTWF4V29yZENvdW50IG9mIGNoYXJhY3RlcnMgSW4gVGV4dEFyZWEgKi9cclxuICBtYXhXb3JkQ291bnQ6IG51bWJlcjtcclxuICAvKipQcmV2ZW50IEF1dG9Db21wbGV0ZSBvZiBUZXh0QXJlYSovXHJcbiAgYXV0b0NvbXBsZXRlOiBib29sZWFuXHJcbiAgLyoqICB0ZXh0IGlucHV0IG9uIGNoYW5nZSAgKi9cclxuICB0cmltVGV4dE9uQ2hhbmdlOiBib29sZWFuXHJcbiAgLyoqIGFkZCBidXR0b24gdG8gZm9yIGNvcGluZyB0byBjbGlwYm9hcmQgKi9cclxuICBlbmFibGVDb3B5VG9DbGlwYm9hcmQ6IGJvb2xlYW4gIFxyXG4gIC8qKiB0byBzZXQgRGlyZWN0aW9uIG9mIFRleHRBcmVhICBpZiBUZXh0QXJlYSBpcyBBcmFiaWMgb3IgRW5nbGlzaCAgKi9cclxuICBmb3JjZURpcmVjdGlvbjogRm9yY2VEaXJlY3Rpb25cclxuICAvLyoqIFNldCB0aGUgTWF4TGVuZ3RoIExpbWl0IHRvIHNob3cgd2FybmluZyBtZXNzYWdlKi9cclxuICBtYXhMZW5ndGhXYXJuaW5nTGltaXQ6IG51bWJlcjtcclxuICAvLyoqIFNldCBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIHNwZWVjaCAobWljKSBpbiB0ZXh0YXJlYSovXHJcbiAgZW5hYmxlU3BlZWNoUmVjb2duaXRpb246Ym9vbGVhbj1mYWxzZTtcclxuICAvLyoqIFNldCBhcnJheSBvZiBhdmFpbGFibGUgbGFuZ3VhZ2VzIGZvciBzcGVlY2ggdG8gdGV4dCovXHJcbiAgc3BlZWNoTGFuZ3VhZ2VzOiBMYW5ndWFnZURUT1tdID0gdW5kZWZpbmVkO1xyXG4gIHNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2U6IHN0cmluZz0nJztcclxuICAvLyptaWMgaWNvbiAqL1xyXG4gIGljb25NaWM6IHN0cmluZztcclxuICAvLyptaWMgaWNvbiBvZmYqL1xyXG4gIGljb25NaWNPZmY6IHN0cmluZztcclxuICAvLyphZGQgZXh0cmEgY2xhc3MgZm9yIG1pYyBsYW5ndWFnZSBjb250YWluZXIqL1xyXG4gIGV4dHJhQ2xhc3NNaWNMYW5ndWFnZTogc3RyaW5nO1xyXG4gIC8vRW5hYmxlIGF1dG8gc2F2ZSBzcGVlY2ggbGFuZ3VhZ2UgaW50byBsb2NhbCBzdG9yYWdlXHJcbiAgYXV0b1NhdmVTcGVlY2hMYW5ndWFnZXRvTG9jYWxTdG9yYWdlOiBib29sZWFuID0gdHJ1ZTtcclxuICBcclxufVxyXG4iXX0=
@@ -8,15 +8,18 @@ import * as i4 from "../../Shared/services/GlobalSettings.service";
8
8
  import * as i5 from "@angular/common";
9
9
  import * as i6 from "@angular/cdk/bidi";
10
10
  import * as i7 from "ngx-intl-tel-input";
11
+ import * as i8 from "ng-inline-svg-2";
11
12
  export class TextAreaComponent {
12
13
  static { this.controlContainerstatic = null; }
13
- constructor(controlUtility, controlContainer, textAreaControlHost, utilityService, controlValidationService, globalSettings) {
14
+ constructor(controlUtility, controlContainer, textAreaControlHost, utilityService, controlValidationService, globalSettings, speechRecognitionService, languageService) {
14
15
  this.controlUtility = controlUtility;
15
16
  this.controlContainer = controlContainer;
16
17
  this.textAreaControlHost = textAreaControlHost;
17
18
  this.utilityService = utilityService;
18
19
  this.controlValidationService = controlValidationService;
19
20
  this.globalSettings = globalSettings;
21
+ this.speechRecognitionService = speechRecognitionService;
22
+ this.languageService = languageService;
20
23
  this.onChange = new EventEmitter();
21
24
  this.wordCount = 0;
22
25
  this.wordCountArray = 0;
@@ -30,6 +33,7 @@ export class TextAreaComponent {
30
33
  this.hasCharsLimitValidationError = false;
31
34
  this.minCharsLimit = -1; //To disable chars limit feature by default
32
35
  this.maxLimitWarningMsg = "";
36
+ this.isMicOn = false;
33
37
  this.resetError = () => {
34
38
  this.controlValidationService.removeGlobalError();
35
39
  };
@@ -54,6 +58,7 @@ export class TextAreaComponent {
54
58
  this.controlUtility.isValid(this.textAreaFormControl);
55
59
  };
56
60
  TextAreaComponent.controlContainerstatic = this.controlContainer;
61
+ this.currentLanguage = localStorage.getItem('language');
57
62
  }
58
63
  ngOnInit() {
59
64
  if (this.options.isReadonly && !this.options.value)
@@ -65,12 +70,27 @@ export class TextAreaComponent {
65
70
  this.controlValidationService.isCreatedBefor = false;
66
71
  this.group.addControl(this.options.name, new FormControl(''));
67
72
  this.textAreaFormControl = this.group.controls[this.options.name]; // new FormControl('',validationRules);
73
+ // Initialize language form control
74
+ const languageControlName = this.options.name + 'Language';
75
+ this.group.addControl(languageControlName, new FormControl(this.options.selectedSpeechLanguage || ''));
68
76
  if (!this.options.maxLength)
69
77
  this.options.maxLength = this.globalSettings.maxLengthTextArea;
70
78
  if (!this.options.viewType)
71
79
  this.options.viewType = this.globalSettings.viewType;
72
80
  if (this.options.labelKey != null && this.options.labelKey != "")
73
81
  this.options.labelValue = this.utilityService.getResourceValue(this.options.labelKey);
82
+ if (this.options.enableSpeechRecognition) {
83
+ //Get all languages if not set
84
+ if (!this.options.speechLanguages) {
85
+ this.languageService.getLanguages().subscribe(result => {
86
+ this.options.speechLanguages = result;
87
+ this.setSpeechLanguage();
88
+ });
89
+ }
90
+ else {
91
+ this.setSpeechLanguage();
92
+ }
93
+ }
74
94
  this.textAreaFormControl.setValue(this.options.value);
75
95
  if (this.options.customValidation.length > 0) {
76
96
  let Validations = this.options.customValidation;
@@ -180,19 +200,103 @@ export class TextAreaComponent {
180
200
  else //onFocusOut
181
201
  this.showCharsLimitMsg = false;
182
202
  }
183
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextAreaComponent, deps: [{ token: i1.ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: i4.GlobalSettings }], target: i0.ɵɵFactoryTarget.Component }); }
184
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: TextAreaComponent, selector: "BBSF-TextArea", inputs: { group: "group", options: "options" }, outputs: { onChange: "onChange" }, ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-textarea\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <div *ngIf=\"!options.isReadonly\" class=\"bbsf-input-container\"\r\n [ngClass]=\"options.enableCopyToClipboard? 'p-40px' : '' \">\r\n <!--input-->\r\n <textarea class=\"form-control {{options.extraClasses}}\" (focus)=\"onFocus(true)\" (focusout)=\"onFocus(false)\"\r\n [dir]=\"textDir\" aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{options.name}}\"\r\n [class.is-invalid]=\"textAreaFormControl.invalid && textAreaFormControl.touched\"\r\n placeholder=\"{{options.placeholder}}\" id=\"{{options.name}}\" autocomplete=\"{{options.autoComplete}}\"\r\n (change)=\"trimControlValue()\" rows=\"{{options.rows}}\" (keyup)=\"onTextChange()\" cols=\"{{options.cols}}\"\r\n maxlength=\"{{options.maxLength}}\" minlength=\"{{options.minLength}}\" [(ngModel)]=\"options.value\"\r\n (keydown)=\"wordCountArray>options.maxWordCount&&$event.keyCode !=8?$event.preventDefault():null\"\r\n #TextAreainput></textarea>\r\n <!--CopyToClipboard-->\r\n <div class=\"copy-clipboard\" *ngIf=\"options.enableCopyToClipboard\" (click)=\"copyInputMessage(TextAreainput)\">\r\n <i class=\"fas fa-copy\"></i>\r\n </div>\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly\"><span class=\"readonly-view\">{{options.value}}</span>\r\n </div>\r\n <div class=\"subtext-container\">\r\n <!--wordCount-->\r\n <div class=\"bbsf-word-count\" *ngIf=\"options.maxWordCount>0&&isShowWordCount\">\r\n {{wordCount}}/{{options.maxWordCount}} Words</div>\r\n <!-- CharsLimitMsg-->\r\n <div class=\"bbsf-character-count\" *ngIf=\"showCharsLimitMsg\"\r\n [ngClass]=\"{'badge-light-warning': charsLimitMsgClass === 'warning', 'badge-light-danger' : charsLimitMsgClass === 'danger' }\">\r\n {{maxLimitWarningMsg}}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <!-- requiredText-->\r\n <div class=\"bbsf-validation\" [dir]=\"textDir\" *ngIf=\"(textAreaFormControl.invalid && textAreaFormControl.touched)\">\r\n {{getErrorValidation(textAreaFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "directive", type: i7.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }] }); }
203
+ //region Speech Recognition
204
+ setSpeechLanguage() {
205
+ const languageControlName = this.options.name + 'Language';
206
+ if (this.options.autoSaveSpeechLanguagetoLocalStorage) {
207
+ let savedLanguage = localStorage.getItem("speechLanguage");
208
+ if (savedLanguage) {
209
+ this.options.selectedSpeechLanguage = savedLanguage;
210
+ }
211
+ else {
212
+ this.loadSelectedSpeechLanguage();
213
+ localStorage.setItem("speechLanguage", this.options.selectedSpeechLanguage);
214
+ }
215
+ }
216
+ else {
217
+ this.loadSelectedSpeechLanguage();
218
+ }
219
+ this.group.get(languageControlName).setValue(this.options.selectedSpeechLanguage);
220
+ }
221
+ loadSelectedSpeechLanguage() {
222
+ if (!this.options.selectedSpeechLanguage) {
223
+ if (this.currentLanguage == "en" && this.options.speechLanguages.some(language => language.englishName === 'English')) {
224
+ this.options.selectedSpeechLanguage = this.options.speechLanguages.find(language => language.englishName === 'English').dialect;
225
+ }
226
+ else if (this.currentLanguage == "ar" && this.options.speechLanguages.some(language => language.englishName === 'Arabic')) {
227
+ this.options.selectedSpeechLanguage = this.options.speechLanguages.find(language => language.englishName === 'Arabic').dialect;
228
+ }
229
+ else {
230
+ this.options.selectedSpeechLanguage = this.options.speechLanguages[0].dialect;
231
+ }
232
+ }
233
+ }
234
+ startSpeechRecognition() {
235
+ if (!this.speechRecognitionService.isSupported) {
236
+ this.utilityService.notifyErrorMessage(this.utilityService.getResourceValue("BrowserNotSupportSpeechRecognition"));
237
+ return;
238
+ }
239
+ this.isMicOn = true;
240
+ this.subscription = this.speechRecognitionService.startListening(this.options.selectedSpeechLanguage).subscribe({
241
+ next: (transcript) => {
242
+ if (transcript) {
243
+ if (this.options.value) {
244
+ this.options.value += ' ';
245
+ }
246
+ let charIndex = 0;
247
+ const interval = setInterval(() => {
248
+ this.options.value += transcript[charIndex];
249
+ charIndex++;
250
+ if (charIndex === transcript.length) {
251
+ clearInterval(interval);
252
+ }
253
+ }, 10);
254
+ }
255
+ },
256
+ error: (error) => {
257
+ console.error(error);
258
+ this.stopSpeechRecognition();
259
+ },
260
+ complete: () => {
261
+ this.isMicOn = false;
262
+ }
263
+ });
264
+ }
265
+ stopSpeechRecognition() {
266
+ if (!this.speechRecognitionService.isSupported) {
267
+ return;
268
+ }
269
+ this.isMicOn = false;
270
+ this.speechRecognitionService.stopListening();
271
+ if (this.subscription) {
272
+ this.subscription.unsubscribe();
273
+ }
274
+ }
275
+ ngOnDestroy() {
276
+ this.stopSpeechRecognition();
277
+ }
278
+ onSpeechLanguageChange(event) {
279
+ let selectedLang = event.target.value;
280
+ this.options.selectedSpeechLanguage = selectedLang;
281
+ const languageControlName = this.options.name + 'Language';
282
+ this.group.get(languageControlName).setValue(selectedLang);
283
+ if (this.options.autoSaveSpeechLanguagetoLocalStorage) {
284
+ localStorage.setItem("speechLanguage", selectedLang);
285
+ }
286
+ }
287
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextAreaComponent, deps: [{ token: i1.ControlUtility }, { token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: i4.GlobalSettings }, { token: i3.SpeechRecognitionService }, { token: i3.LanguageService }], target: i0.ɵɵFactoryTarget.Component }); }
288
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: TextAreaComponent, selector: "BBSF-TextArea", inputs: { group: "group", options: "options" }, outputs: { onChange: "onChange" }, ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-textarea\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <div *ngIf=\"!options.isReadonly\" class=\"bbsf-input-container\" [ngClass]=\"{\r\n 'p-120px': options.enableSpeechRecognition && options.enableCopyToClipboard,\r\n 'p-80px': options.enableSpeechRecognition && !options.enableCopyToClipboard,\r\n 'p-40px': !options.enableSpeechRecognition && options.enableCopyToClipboard\r\n }\">\r\n <!--input-->\r\n <textarea class=\"form-control {{options.extraClasses}}\" (focus)=\"onFocus(true)\" (focusout)=\"onFocus(false)\"\r\n [dir]=\"textDir\" aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{options.name}}\"\r\n [class.is-invalid]=\"textAreaFormControl.invalid && textAreaFormControl.touched\"\r\n placeholder=\"{{options.placeholder}}\" id=\"{{options.name}}\" autocomplete=\"{{options.autoComplete}}\"\r\n (change)=\"trimControlValue()\" rows=\"{{options.rows}}\" (keyup)=\"onTextChange()\" cols=\"{{options.cols}}\"\r\n maxlength=\"{{options.maxLength}}\" minlength=\"{{options.minLength}}\" [(ngModel)]=\"options.value\"\r\n (keydown)=\"wordCountArray>options.maxWordCount&&$event.keyCode !=8?$event.preventDefault():null\"\r\n #TextAreainput></textarea>\r\n <!--CopyToClipboard-->\r\n <div class=\"copy-clipboard\" *ngIf=\"options.enableCopyToClipboard\" (click)=\"copyInputMessage(TextAreainput)\">\r\n <i class=\"fas fa-copy\"></i>\r\n </div>\r\n <div [ngClass]=\"{'expanded': isFocused}\" class=\"language-container {{options.extraClassMicLanguage}}\" *ngIf=\"options.enableSpeechRecognition\">\r\n <span class=\"svg-icon svg-icon-5\" [inlineSVG]=\"options.iconMic? options.iconMic : './src/assets/images/mic.svg'\" (click)=\"startSpeechRecognition()\"\r\n *ngIf=\"!isMicOn\">\r\n </span>\r\n <span class=\"svg-icon svg-icon-5\" [inlineSVG]=\"options.iconMicOff? options.iconMicOff : './src/assets/images/mic-off.svg'\" (click)=\"stopSpeechRecognition()\"\r\n *ngIf=\"isMicOn\">\r\n </span>\r\n <select class=\"language-select\" [formControlName]=\"options.name + 'Language'\" (change)=\"onSpeechLanguageChange($event)\">\r\n <option *ngFor=\"let language of options.speechLanguages\" [value]=\"language.dialect\">{{language.displayName}}</option>\r\n </select>\r\n </div>\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly\"><span class=\"readonly-view\">{{options.value}}</span>\r\n </div>\r\n <div class=\"subtext-container\">\r\n <!--wordCount-->\r\n <div class=\"bbsf-word-count\" *ngIf=\"options.maxWordCount>0&&isShowWordCount\">\r\n {{wordCount}}/{{options.maxWordCount}} Words</div>\r\n <!-- CharsLimitMsg-->\r\n <div class=\"bbsf-character-count\" *ngIf=\"showCharsLimitMsg\"\r\n [ngClass]=\"{'badge-light-warning': charsLimitMsgClass === 'warning', 'badge-light-danger' : charsLimitMsgClass === 'danger' }\">\r\n {{maxLimitWarningMsg}}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <!-- requiredText-->\r\n <div class=\"bbsf-validation\" [dir]=\"textDir\" *ngIf=\"(textAreaFormControl.invalid && textAreaFormControl.touched)\">\r\n {{getErrorValidation(textAreaFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "directive", type: i7.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i8.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }] }); }
185
289
  }
186
290
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextAreaComponent, decorators: [{
187
291
  type: Component,
188
- args: [{ selector: 'BBSF-TextArea', template: "<div class=\"form-group bbsf-control bbsf-textarea\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <div *ngIf=\"!options.isReadonly\" class=\"bbsf-input-container\"\r\n [ngClass]=\"options.enableCopyToClipboard? 'p-40px' : '' \">\r\n <!--input-->\r\n <textarea class=\"form-control {{options.extraClasses}}\" (focus)=\"onFocus(true)\" (focusout)=\"onFocus(false)\"\r\n [dir]=\"textDir\" aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{options.name}}\"\r\n [class.is-invalid]=\"textAreaFormControl.invalid && textAreaFormControl.touched\"\r\n placeholder=\"{{options.placeholder}}\" id=\"{{options.name}}\" autocomplete=\"{{options.autoComplete}}\"\r\n (change)=\"trimControlValue()\" rows=\"{{options.rows}}\" (keyup)=\"onTextChange()\" cols=\"{{options.cols}}\"\r\n maxlength=\"{{options.maxLength}}\" minlength=\"{{options.minLength}}\" [(ngModel)]=\"options.value\"\r\n (keydown)=\"wordCountArray>options.maxWordCount&&$event.keyCode !=8?$event.preventDefault():null\"\r\n #TextAreainput></textarea>\r\n <!--CopyToClipboard-->\r\n <div class=\"copy-clipboard\" *ngIf=\"options.enableCopyToClipboard\" (click)=\"copyInputMessage(TextAreainput)\">\r\n <i class=\"fas fa-copy\"></i>\r\n </div>\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly\"><span class=\"readonly-view\">{{options.value}}</span>\r\n </div>\r\n <div class=\"subtext-container\">\r\n <!--wordCount-->\r\n <div class=\"bbsf-word-count\" *ngIf=\"options.maxWordCount>0&&isShowWordCount\">\r\n {{wordCount}}/{{options.maxWordCount}} Words</div>\r\n <!-- CharsLimitMsg-->\r\n <div class=\"bbsf-character-count\" *ngIf=\"showCharsLimitMsg\"\r\n [ngClass]=\"{'badge-light-warning': charsLimitMsgClass === 'warning', 'badge-light-danger' : charsLimitMsgClass === 'danger' }\">\r\n {{maxLimitWarningMsg}}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <!-- requiredText-->\r\n <div class=\"bbsf-validation\" [dir]=\"textDir\" *ngIf=\"(textAreaFormControl.invalid && textAreaFormControl.touched)\">\r\n {{getErrorValidation(textAreaFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>" }]
292
+ args: [{ selector: 'BBSF-TextArea', template: "<div class=\"form-group bbsf-control bbsf-textarea\" [formGroup]=\"group\">\r\n <div [ngClass]=\"(options.viewType==1)?'bbsf-vertical':'bbsf-horizontal'\">\r\n <!--label-->\r\n <label *ngIf=\"!options.hideLabel\" class=\"bbsf-label {{options.labelExtraClasses}}\">\r\n {{options.labelValue}}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk&&options.isRequired)||(options.isRequired))&&!options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <div *ngIf=\"!options.isReadonly\" class=\"bbsf-input-container\" [ngClass]=\"{\r\n 'p-120px': options.enableSpeechRecognition && options.enableCopyToClipboard,\r\n 'p-80px': options.enableSpeechRecognition && !options.enableCopyToClipboard,\r\n 'p-40px': !options.enableSpeechRecognition && options.enableCopyToClipboard\r\n }\">\r\n <!--input-->\r\n <textarea class=\"form-control {{options.extraClasses}}\" (focus)=\"onFocus(true)\" (focusout)=\"onFocus(false)\"\r\n [dir]=\"textDir\" aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{options.name}}\"\r\n [class.is-invalid]=\"textAreaFormControl.invalid && textAreaFormControl.touched\"\r\n placeholder=\"{{options.placeholder}}\" id=\"{{options.name}}\" autocomplete=\"{{options.autoComplete}}\"\r\n (change)=\"trimControlValue()\" rows=\"{{options.rows}}\" (keyup)=\"onTextChange()\" cols=\"{{options.cols}}\"\r\n maxlength=\"{{options.maxLength}}\" minlength=\"{{options.minLength}}\" [(ngModel)]=\"options.value\"\r\n (keydown)=\"wordCountArray>options.maxWordCount&&$event.keyCode !=8?$event.preventDefault():null\"\r\n #TextAreainput></textarea>\r\n <!--CopyToClipboard-->\r\n <div class=\"copy-clipboard\" *ngIf=\"options.enableCopyToClipboard\" (click)=\"copyInputMessage(TextAreainput)\">\r\n <i class=\"fas fa-copy\"></i>\r\n </div>\r\n <div [ngClass]=\"{'expanded': isFocused}\" class=\"language-container {{options.extraClassMicLanguage}}\" *ngIf=\"options.enableSpeechRecognition\">\r\n <span class=\"svg-icon svg-icon-5\" [inlineSVG]=\"options.iconMic? options.iconMic : './src/assets/images/mic.svg'\" (click)=\"startSpeechRecognition()\"\r\n *ngIf=\"!isMicOn\">\r\n </span>\r\n <span class=\"svg-icon svg-icon-5\" [inlineSVG]=\"options.iconMicOff? options.iconMicOff : './src/assets/images/mic-off.svg'\" (click)=\"stopSpeechRecognition()\"\r\n *ngIf=\"isMicOn\">\r\n </span>\r\n <select class=\"language-select\" [formControlName]=\"options.name + 'Language'\" (change)=\"onSpeechLanguageChange($event)\">\r\n <option *ngFor=\"let language of options.speechLanguages\" [value]=\"language.dialect\">{{language.displayName}}</option>\r\n </select>\r\n </div>\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly\"><span class=\"readonly-view\">{{options.value}}</span>\r\n </div>\r\n <div class=\"subtext-container\">\r\n <!--wordCount-->\r\n <div class=\"bbsf-word-count\" *ngIf=\"options.maxWordCount>0&&isShowWordCount\">\r\n {{wordCount}}/{{options.maxWordCount}} Words</div>\r\n <!-- CharsLimitMsg-->\r\n <div class=\"bbsf-character-count\" *ngIf=\"showCharsLimitMsg\"\r\n [ngClass]=\"{'badge-light-warning': charsLimitMsgClass === 'warning', 'badge-light-danger' : charsLimitMsgClass === 'danger' }\">\r\n {{maxLimitWarningMsg}}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <!-- requiredText-->\r\n <div class=\"bbsf-validation\" [dir]=\"textDir\" *ngIf=\"(textAreaFormControl.invalid && textAreaFormControl.touched)\">\r\n {{getErrorValidation(textAreaFormControl.errors|keyvalue)}}\r\n </div>\r\n </div>\r\n <div *ngIf=\"(group.valid&&group.dirty&&group.touched )||(group.untouched&&group.invalid&&group.dirty) \">\r\n {{resetError()}}</div>\r\n </div>\r\n" }]
189
293
  }], ctorParameters: () => [{ type: i1.ControlUtility }, { type: i2.ControlContainer, decorators: [{
190
294
  type: Optional
191
- }] }, { type: i2.FormGroupDirective }, { type: i3.UtilityService }, { type: i3.ControlValidationService }, { type: i4.GlobalSettings }], propDecorators: { group: [{
295
+ }] }, { type: i2.FormGroupDirective }, { type: i3.UtilityService }, { type: i3.ControlValidationService }, { type: i4.GlobalSettings }, { type: i3.SpeechRecognitionService }, { type: i3.LanguageService }], propDecorators: { group: [{
192
296
  type: Input
193
297
  }], options: [{
194
298
  type: Input
195
299
  }], onChange: [{
196
300
  type: Output
197
301
  }] } });
198
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dEFyZWEuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYmJzZi1jb250cm9scy9zcmMvbGliL2NvbnRyb2xzL1RleHRBcmVhL1RleHRBcmVhLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jic2YtY29udHJvbHMvc3JjL2xpYi9jb250cm9scy9UZXh0QXJlYS9UZXh0QXJlYS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RixPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBb0UsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7O0FBVzNILE1BQU0sT0FBTyxpQkFBaUI7YUFHckIsMkJBQXNCLEdBQUcsSUFBSSxBQUFQLENBQVE7SUFDckMsWUFBb0IsY0FBOEIsRUFBc0IsZ0JBQWtDLEVBQ2pHLG1CQUF1QyxFQUFVLGNBQThCLEVBQzlFLHdCQUFrRCxFQUFVLGNBQThCO1FBRmhGLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUFzQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2pHLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBb0I7UUFBVSxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUUsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUFVLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUsxRixhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUd4QyxjQUFTLEdBQVcsQ0FBQyxDQUFDO1FBQ3RCLG1CQUFjLEdBQVcsQ0FBQyxDQUFDO1FBQzNCLG9CQUFlLEdBQVksS0FBSyxDQUFDO1FBQ2pDLHFCQUFnQixHQUFZLEtBQUssQ0FBQztRQUNsQyxvQkFBZSxHQUFHLEVBQUUs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SUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztTQUNqQzthQUNJLFlBQVk7WUFDZixJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO0lBQ25DLENBQUM7OEdBMUxVLGlCQUFpQjtrR0FBakIsaUJBQWlCLHdJQ1o5Qix1NEZBOENROzsyRkRsQ0ssaUJBQWlCO2tCQUo3QixTQUFTOytCQUNFLGVBQWU7OzBCQU80QixRQUFROzJLQUtwRCxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNJLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE9wdGlvbmFsLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtQ29udHJvbCwgVmFsaWRhdG9ycywgRm9ybUdyb3VwLCBBYnN0cmFjdENvbnRyb2wsIENvbnRyb2xDb250YWluZXIsIEZvcm1Hcm91cERpcmVjdGl2ZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbGlkYXRpb25TZXJ2aWNlLCBVdGlsaXR5U2VydmljZSB9IGZyb20gJ0BibnNpZ2h0cy9iYnNmLXV0aWxpdGllcyc7XHJcbmltcG9ydCB7IENvbnRyb2xVdGlsaXR5IH0gZnJvbSAnLi4vLi4vU2hhcmVkL3NlcnZpY2VzL0NvbnRyb2xVdGlsaXR5JztcclxuaW1wb3J0IHsgVGV4dEFyZWFPcHRpb25zIH0gZnJvbSAnLi4vLi4vU2hhcmVkL01vZGVscy9UZXh0QXJlYU9wdGlvbnMnO1xyXG5pbXBvcnQgeyBHbG9iYWxTZXR0aW5ncyB9IGZyb20gJy4uLy4uL1NoYXJlZC9zZXJ2aWNlcy9HbG9iYWxTZXR0aW5ncy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdCQlNGLVRleHRBcmVhJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vVGV4dEFyZWEuY29tcG9uZW50Lmh0bWwnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUZXh0QXJlYUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG5cclxuICBzdGF0aWMgY29udHJvbENvbnRhaW5lcnN0YXRpYyA9IG51bGw7XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjb250cm9sVXRpbGl0eTogQ29udHJvbFV0aWxpdHksIEBPcHRpb25hbCgpIHByaXZhdGUgY29udHJvbENvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lcixcclxuICAgIHB1YmxpYyB0ZXh0QXJlYUNvbnRyb2xIb3N0OiBGb3JtR3JvdXBEaXJlY3RpdmUsIHByaXZhdGUgdXRpbGl0eVNlcnZpY2U6IFV0aWxpdHlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBjb250cm9sVmFsaWRhdGlvblNlcnZpY2U6IENvbnRyb2xWYWxpZGF0aW9uU2VydmljZSwgcHJpdmF0ZSBnbG9iYWxTZXR0aW5nczogR2xvYmFsU2V0dGluZ3MpIHtcclxuICAgIFRleHRBcmVhQ29tcG9uZW50LmNvbnRyb2xDb250YWluZXJzdGF0aWMgPSB0aGlzLmNvbnRyb2xDb250YWluZXI7XHJcbiAgfVxyXG4gIEBJbnB1dCgpIGdyb3VwOiBGb3JtR3JvdXA7XHJcbiAgQElucHV0KCkgb3B0aW9uczogVGV4dEFyZWFPcHRpb25zO1xyXG4gIEBPdXRwdXQoKSBvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgdGV4dEFyZWFGb3JtQ29udHJvbDogQWJzdHJhY3RDb250cm9sO1xyXG4gIHdvcmRDb3VudDogbnVtYmVyID0gMDtcclxuICB3b3JkQ291bnRBcnJheTogbnVtYmVyID0gMDtcclxuICBpc1Nob3dXb3JkQ291bnQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBtYXJrQWxsQXNUb3VjaGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgdmFsaWRhdGlvblJ1bGVzID0gW107XHJcbiAgdmFsaWRhdGlvblJ1bGVzYXN5bmMgPSBbXTtcclxuICAvL0ZvciBTaG93IHdhcm5pbmcgbWVzc2FnZSBvZiBtYXggbGVuZ3RoIGxpbWl0XHJcbiAgY3VycmVudENoYXJzQ291bnQ6IG51bWJlciA9IDA7XHJcbiAgc2hvd0NoYXJzTGltaXRNc2c6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBoYXNDaGFyc0xpbWl0VmFsaWRhdGlvbkVycm9yOiBib29sZWFuID0gZmFsc2U7XHJcbiAgY2hhcnNMaW1pdE1zZ0NsYXNzOiBzdHJpbmc7XHJcbiAgbWluQ2hhcnNMaW1pdDogbnVtYmVyID0gLTE7IC8vVG8gZGlzYWJsZSBjaGFycyBsaW1pdCBmZWF0dXJlIGJ5IGRlZmF1bHRcclxuICBtYXhMaW1pdFdhcm5pbmdNc2c6IHN0cmluZyA9IFwiXCI7XHJcbiAgcHVibGljIHRleHREaXI7XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc1JlYWRvbmx5ICYmICF0aGlzLm9wdGlvbnMudmFsdWUpXHJcbiAgICAgIHRoaXMub3B0aW9ucy52YWx1ZSA9IHRoaXMudXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnTkEnKTtcclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmZvcmNlRGlyZWN0aW9uKVxyXG4gICAgICB0aGlzLnRleHREaXIgPSB0aGlzLm9wdGlvbnMuZm9yY2VEaXJlY3Rpb24gPT0gMiA/ICdydGwnIDogJ2x0cic7XHJcbiAgICBlbHNlXHJcbiAgICAgIHRoaXMudGV4dERpciA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdsYW5ndWFnZScpID09ICdhcicgPyAncnRsJyA6ICdsdHInO1xyXG5cclxuICAgIHRoaXMuY29udHJvbFZhbGlkYXRpb25TZXJ2aWNlLmlzQ3JlYXRlZEJlZm9yID0gZmFsc2VcclxuXHJcbiAgICB0aGlzLmdyb3VwLmFkZENvbnRyb2wodGhpcy5vcHRpb25zLm5hbWUsIG5ldyBGb3JtQ29udHJvbCgnJykpO1xyXG4gICAgdGhpcy50ZXh0QXJlYUZvcm1Db250cm9sID0gdGhpcy5ncm91cC5jb250cm9sc1t0aGlzLm9wdGlvbnMubmFtZV07IC8vICBuZXcgRm9ybUNvbnRyb2woJycsdmFsaWRhdGlvblJ1bGVzKTtcclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5tYXhMZW5ndGgpXHJcbiAgICAgIHRoaXMub3B0aW9ucy5tYXhMZW5ndGggPSB0aGlzLmdsb2JhbFNldHRpbmdzLm1heExlbmd0aFRleHRBcmVhO1xyXG5cclxuICAgIGlmICghdGhpcy5vcHRpb25zLnZpZXdUeXBlKVxyXG4gICAgICB0aGlzLm9wdGlvbnMudmlld1R5cGUgPSB0aGlzLmdsb2JhbFNldHRpbmdzLnZpZXdUeXBlO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMubGFiZWxLZXkgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMubGFiZWxLZXkgIT0gXCJcIilcclxuICAgICAgdGhpcy5vcHRpb25zLmxhYmVsVmFsdWUgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUodGhpcy5vcHRpb25zLmxhYmVsS2V5KTtcclxuXHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuc2V0VmFsdWUodGhpcy5vcHRpb25zLnZhbHVlKTtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuY3VzdG9tVmFsaWRhdGlvbi5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGxldCBWYWxpZGF0aW9ucyA9IHRoaXMub3B0aW9ucy5jdXN0b21WYWxpZGF0aW9uXHJcbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBWYWxpZGF0aW9ucy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBjb25zdCBWYWxpZGF0aW9uID0gVmFsaWRhdGlvbnNbaW5kZXhdO1xyXG4gICAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdGlvbi5mdW5jdGlvbkJvZHkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5taW5MZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdG9ycy5taW5MZW5ndGgodGhpcy5vcHRpb25zLm1pbkxlbmd0aCkpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5tYXhMZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdG9ycy5tYXhMZW5ndGgodGhpcy5vcHRpb25zLm1heExlbmd0aCkpO1xyXG5cclxuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubWF4TGVuZ3RoV2FybmluZ0xpbWl0KVxyXG4gICAgICAgIHRoaXMub3B0aW9ucy5tYXhMZW5ndGhXYXJuaW5nTGltaXQgPSB0aGlzLmdsb2JhbFNldHRpbmdzLm1heExlbmd0aFdhcm5pbmdMaW1pdDtcclxuXHJcbiAgICAgIHRoaXMubWluQ2hhcnNMaW1pdCA9IHRoaXMub3B0aW9ucy5tYXhMZW5ndGggLSB0aGlzLm9wdGlvbnMubWF4TGVuZ3RoV2FybmluZ0xpbWl0O1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc1JlcXVpcmVkKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyh0aGlzLnZhbGlkYXRpb25SdWxlcyk7XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuc2V0QXN5bmNWYWxpZGF0b3JzKHRoaXMudmFsaWRhdGlvblJ1bGVzYXN5bmMpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc0Rpc2FibGVkKSB7XHJcbiAgICAgIHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC5kaXNhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50ZXh0QXJlYUNvbnRyb2xIb3N0Lm5nU3VibWl0LnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAgICAgdGhpcy5ncm91cC5tYXJrQWxsQXNUb3VjaGVkKClcclxuICAgICAgdGhpcy5tYXJrQWxsQXNUb3VjaGVkID0gdHJ1ZVxyXG4gICAgfSlcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5zZXRBdHRyaWJ1dGVGb3JDb250cm9sKHRoaXMub3B0aW9ucylcclxuICB9XHJcblxyXG4gIHJlc2V0RXJyb3IgPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xWYWxpZGF0aW9uU2VydmljZS5yZW1vdmVHbG9iYWxFcnJvcigpO1xyXG4gIH1cclxuXHJcbiAgc2hvd0dsb2JhbEVycm9yKCkge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5zaG93R2xvYmFsRXJyb3IoKVxyXG4gIH1cclxuXHJcbiAgZ2V0RXJyb3JWYWxpZGF0aW9uKEVycm9yTGlzdCkge1xyXG4gICAgaWYgKHRoaXMubWFya0FsbEFzVG91Y2hlZCAmJiB0aGlzLmdyb3VwLmludmFsaWQpIHtcclxuICAgICAgdGhpcy5zaG93R2xvYmFsRXJyb3IoKVxyXG4gICAgICB0aGlzLm1hcmtBbGxBc1RvdWNoZWQgPSBmYWxzZVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29udHJvbFV0aWxpdHkuZ2V0RXJyb3JWYWxpZGF0aW9uTWFzc2FnZShFcnJvckxpc3QsIHRoaXMuZ3JvdXAsIHRoaXMub3B0aW9ucyk7XHJcbiAgfVxyXG4gIGdldElucHV0VHlwZSh0eXBlOiBudW1iZXIpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbnRyb2xVdGlsaXR5LmdldElucHV0VHlwZSh0eXBlKVxyXG4gIH1cclxuXHJcbiAgdHJpbUNvbnRyb2xWYWx1ZSgpIHtcclxuICAgIGxldCBvcmlnaW5hbFZhbHVlID0gdGhpcy5jb250cm9sVXRpbGl0eS50cmltQ29udHJvbFZhbHVlKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC52YWx1ZSk7XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wucGF0Y2hWYWx1ZShvcmlnaW5hbFZhbHVlKVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wYXRjaEZ1bmN0aW9uICYmIHRoaXMub3B0aW9ucy5wYXRjaFBhdGggJiYgdGhpcy50ZXh0QXJlYUZvcm1Db250cm9sLnZhbGlkKSB7XHJcbiAgICAgIHRoaXMuY29udHJvbFV0aWxpdHkucGF0Y2hDb250cm9sVmFsdWUob3JpZ2luYWxWYWx1ZSwgdGhpcy5vcHRpb25zLnBhdGNoRnVuY3Rpb24sIHRoaXMub3B0aW9ucy5wYXRjaFBhdGgpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb3B5SW5wdXRNZXNzYWdlKGlucHV0RWxlbWVudCkge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5Db3B5SW5wdXRNZXNzYWdlKGlucHV0RWxlbWVudClcclxuICB9XHJcblxyXG4gIG9uVGV4dENoYW5nZSgpIHtcclxuXHJcbiAgICBpZiAodGhpcy50ZXh0QXJlYUZvcm1Db250cm9sLnZhbHVlID09IFwiXCIpIHtcclxuICAgICAgdGhpcy53b3JkQ291bnRBcnJheSA9IDA7XHJcbiAgICAgIHRoaXMud29yZENvdW50ID0gMDtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgdGhpcy53b3JkQ291bnRBcnJheSA9IHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC52YWx1ZS5zcGxpdChcIiBcIikubGVuZ3RoO1xyXG4gICAgICBpZiAodGhpcy53b3JkQ291bnRBcnJheSA+IDApIHtcclxuICAgICAgICBpZiAodGhpcy53b3JkQ291bnRBcnJheSA+IHRoaXMub3B0aW9ucy5tYXhXb3JkQ291bnQpIHtcclxuICAgICAgICAgIHRoaXMud29yZENvdW50ID0gdGhpcy5vcHRpb25zLm1heFdvcmRDb3VudDtcclxuICAgICAgICAgIHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC5zZXRFcnJvcnMoeyBcImVycm9yTWFzc2FnZVwiOiBgICBXb3JkIGNvdW50IG11c3QgYmUgbGVzcyB0aGVuIG9yIGVxdWFsICAke3RoaXMub3B0aW9ucy5tYXhXb3JkQ291bnR9YCB9KTtcclxuICAgICAgICAgIHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XHJcbiAgICAgICAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuaW52YWxpZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLndvcmRDb3VudCA9IHRoaXMud29yZENvdW50QXJyYXk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vQ2hlY2sgZm9yIG1heGxlbmd0aCBsaW1pdCBjb3VudFxyXG4gICAgLy9NYXhMZW5ndGggc2hvdWxkIGJlIGdyZXRhZXIgdGhhbiBvciBlcXVhbHMgY2hhcnMgbGltaXQgc28gdGhhdCBtaW5DaGFyc0xpbWl0IHdvdWxkIGJlID49IDBcclxuICAgIGlmICh0aGlzLm9wdGlvbnMubWF4TGVuZ3RoICYmIHRoaXMubWluQ2hhcnNMaW1pdCA+PSAwKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudENoYXJzQ291bnQgPSB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wudmFsdWUubGVuZ3RoO1xyXG4gICAgICBpZiAodGhpcy5jdXJyZW50Q2hhcnNDb3VudCA+IHRoaXMubWluQ2hhcnNMaW1pdCkge1xyXG4gICAgICAgIHRoaXMuc2hvd0NoYXJzTGltaXRNc2cgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuaGFzQ2hhcnNMaW1pdFZhbGlkYXRpb25FcnJvciA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRDaGFyc0NvdW50ID09IHRoaXMub3B0aW9ucy5tYXhMZW5ndGgpXHJcbiAgICAgICAgICB0aGlzLmNoYXJzTGltaXRNc2dDbGFzcyA9IFwiZGFuZ2VyXCI7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgdGhpcy5jaGFyc0xpbWl0TXNnQ2xhc3MgPSBcIndhcm5pbmdcIjtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLnNob3dDaGFyc0xpbWl0TXNnID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5oYXNDaGFyc0xpbWl0VmFsaWRhdGlvbkVycm9yID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBtYXg6IG51bWJlciA9IHRoaXMub3B0aW9ucy5tYXhMZW5ndGg7XHJcbiAgICAgIGxldCBjdXJyZW50OiBudW1iZXIgPSB0aGlzLmN1cnJlbnRDaGFyc0NvdW50O1xyXG4gICAgICBsZXQgbXNnOiBzdHJpbmcgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJNYXhMZW5ndGhMaW1pdFdhcm5pbmdcIik7XHJcblxyXG4gICAgICAvLyBSZXBsYWNlIHBsYWNlaG9sZGVycyB3aXRoIGFjdHVhbCB2YWx1ZXNcclxuICAgICAgdGhpcy5tYXhMaW1pdFdhcm5pbmdNc2cgPSBtc2cucmVwbGFjZShcIiR7bWF4fVwiLCBtYXgudG9TdHJpbmcoKSkucmVwbGFjZShcIiR7Y3VycmVudH1cIiwgY3VycmVudC50b1N0cmluZygpKTtcclxuICAgIH1cclxuICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wudmFsdWUpXHJcblxyXG4gIH1cclxuXHJcbiAgb25Gb2N1cyhpc0ZvY3VzOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmlzU2hvd1dvcmRDb3VudCA9IGlzRm9jdXM7XHJcblxyXG4gICAgLy9vbkZvY3VzXHJcbiAgICBpZiAoaXNGb2N1cykge1xyXG4gICAgICBpZiAodGhpcy5oYXNDaGFyc0xpbWl0VmFsaWRhdGlvbkVycm9yKSAvL2NoZWNrIGlmIHRoZXJlIHdhcyBwcmV2aW91cyB2YWxpZGF0aW9uIGVycm9yXHJcbiAgICAgICAgdGhpcy5zaG93Q2hhcnNMaW1pdE1zZyA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBlbHNlIC8vb25Gb2N1c091dFxyXG4gICAgICB0aGlzLnNob3dDaGFyc0xpbWl0TXNnID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIHJlbW92ZVJlcXVpcmVkVmFsaWRhdGlvbiA9ICgpID0+IHtcclxuICAgIHRoaXMuY29udHJvbFV0aWxpdHkucmVtb3ZlUmVxdWlyZWRWYWxpZGF0aW9uKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbCwgdGhpcy52YWxpZGF0aW9uUnVsZXMsIHRoaXMub3B0aW9ucylcclxuICB9XHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICBhZGRSZXF1aXJlZFZhbGlkYXRpb24gPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZFJlcXVpcmVkVmFsaWRhdGlvbih0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wsIHRoaXMudmFsaWRhdGlvblJ1bGVzLCB0aGlzLm9wdGlvbnMpXHJcbiAgfVxyXG5cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIHJlbW92ZUN1c3RvbVZhbGlkYXRpb24gPSAoY3VzdG9tVmFsaWRhdGlvbikgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5yZW1vdmVDdXN0b21WYWxpZGF0aW9uKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbCwgdGhpcy52YWxpZGF0aW9uUnVsZXMsIGN1c3RvbVZhbGlkYXRpb24pXHJcbiAgfVxyXG4gIC8vRXh0ZXJuYWwgTWV0aG9kXHJcbiAgYWRkQ3VzdG9tVmFsaWRhdGlvbiA9IChjdXN0b21WYWxpZGF0aW9uKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZEN1c3RvbVZhbGlkYXRpb24odGhpcy50ZXh0QXJlYUZvcm1Db250cm9sLCB0aGlzLnZhbGlkYXRpb25SdWxlcywgY3VzdG9tVmFsaWRhdGlvbilcclxuICB9XHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICBpc1ZhbGlkID0gKCkgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5pc1ZhbGlkKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbClcclxuICB9XHJcbn1cclxuXHJcblxyXG4iLCI8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBiYnNmLWNvbnRyb2wgYmJzZi10ZXh0YXJlYVwiIFtmb3JtR3JvdXBdPVwiZ3JvdXBcIj5cclxuICA8ZGl2IFtuZ0NsYXNzXT1cIihvcHRpb25zLnZpZXdUeXBlPT0xKT8nYmJzZi12ZXJ0aWNhbCc6J2Jic2YtaG9yaXpvbnRhbCdcIj5cclxuICAgIDwhLS1sYWJlbC0tPlxyXG4gICAgPGxhYmVsICpuZ0lmPVwiIW9wdGlvbnMuaGlkZUxhYmVsXCIgY2xhc3M9XCJiYnNmLWxhYmVsIHt7b3B0aW9ucy5sYWJlbEV4dHJhQ2xhc3Nlc319XCI+XHJcbiAgICAgIHt7b3B0aW9ucy5sYWJlbFZhbHVlfX1cclxuICAgICAgPCEtLUFzdGVyaXNrLS0+XHJcbiAgICAgIDxzcGFuICpuZ0lmPVwiKChvcHRpb25zLnNob3dBc3RlcmlzayYmb3B0aW9ucy5pc1JlcXVpcmVkKXx8KG9wdGlvbnMuaXNSZXF1aXJlZCkpJiYhb3B0aW9ucy5pc1JlYWRvbmx5XCJcclxuICAgICAgICBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj5cclxuICAgIDwvbGFiZWw+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiIW9wdGlvbnMuaXNSZWFkb25seVwiIGNsYXNzPVwiYmJzZi1pbnB1dC1jb250YWluZXJcIlxyXG4gICAgICBbbmdDbGFzc109XCJvcHRpb25zLmVuYWJsZUNvcHlUb0NsaXBib2FyZD8gJ3AtNDBweCcgOiAnJyBcIj5cclxuICAgICAgPCEtLWlucHV0LS0+XHJcbiAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbCB7e29wdGlvbnMuZXh0cmFDbGFzc2VzfX1cIiAoZm9jdXMpPVwib25Gb2N1cyh0cnVlKVwiIChmb2N1c291dCk9XCJvbkZvY3VzKGZhbHNlKVwiXHJcbiAgICAgICAgW2Rpcl09XCJ0ZXh0RGlyXCIgYXJpYS1kZXNjcmliZWRieT1cImVtYWlsLWVycm9yXCIgYXJpYS1pbnZhbGlkPVwidHJ1ZVwiIGZvcm1Db250cm9sTmFtZT1cInt7b3B0aW9ucy5uYW1lfX1cIlxyXG4gICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cInRleHRBcmVhRm9ybUNvbnRyb2wuaW52YWxpZCAmJiB0ZXh0QXJlYUZvcm1Db250cm9sLnRvdWNoZWRcIlxyXG4gICAgICAgIHBsYWNlaG9sZGVyPVwie3tvcHRpb25zLnBsYWNlaG9sZGVyfX1cIiBpZD1cInt7b3B0aW9ucy5uYW1lfX1cIiBhdXRvY29tcGxldGU9XCJ7e29wdGlvbnMuYXV0b0NvbXBsZXRlfX1cIlxyXG4gICAgICAgIChjaGFuZ2UpPVwidHJpbUNvbnRyb2xWYWx1ZSgpXCIgcm93cz1cInt7b3B0aW9ucy5yb3dzfX1cIiAoa2V5dXApPVwib25UZXh0Q2hhbmdlKClcIiBjb2xzPVwie3tvcHRpb25zLmNvbHN9fVwiXHJcbiAgICAgICAgbWF4bGVuZ3RoPVwie3tvcHRpb25zLm1heExlbmd0aH19XCIgbWlubGVuZ3RoPVwie3tvcHRpb25zLm1pbkxlbmd0aH19XCIgWyhuZ01vZGVsKV09XCJvcHRpb25zLnZhbHVlXCJcclxuICAgICAgICAoa2V5ZG93bik9XCJ3b3JkQ291bnRBcnJheT5vcHRpb25zLm1heFdvcmRDb3VudCYmJGV2ZW50LmtleUNvZGUgIT04PyRldmVudC5wcmV2ZW50RGVmYXVsdCgpOm51bGxcIlxyXG4gICAgICAgICNUZXh0QXJlYWlucHV0PjwvdGV4dGFyZWE+XHJcbiAgICAgIDwhLS1Db3B5VG9DbGlwYm9hcmQtLT5cclxuICAgICAgPGRpdiBjbGFzcz1cImNvcHktY2xpcGJvYXJkXCIgKm5nSWY9XCJvcHRpb25zLmVuYWJsZUNvcHlUb0NsaXBib2FyZFwiIChjbGljayk9XCJjb3B5SW5wdXRNZXNzYWdlKFRleHRBcmVhaW5wdXQpXCI+XHJcbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtY29weVwiPjwvaT5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDwhLS0gcmVhZG9ubHkgLS0+XHJcbiAgICA8ZGl2ICpuZ0lmPVwib3B0aW9ucy5pc1JlYWRvbmx5XCI+PHNwYW4gY2xhc3M9XCJyZWFkb25seS12aWV3XCI+e3tvcHRpb25zLnZhbHVlfX08L3NwYW4+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJzdWJ0ZXh0LWNvbnRhaW5lclwiPlxyXG4gICAgICA8IS0td29yZENvdW50LS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLXdvcmQtY291bnRcIiAqbmdJZj1cIm9wdGlvbnMubWF4V29yZENvdW50PjAmJmlzU2hvd1dvcmRDb3VudFwiPlxyXG4gICAgICAgIHt7d29yZENvdW50fX0ve3tvcHRpb25zLm1heFdvcmRDb3VudH19IFdvcmRzPC9kaXY+XHJcbiAgICAgIDwhLS0gQ2hhcnNMaW1pdE1zZy0tPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiYmJzZi1jaGFyYWN0ZXItY291bnRcIiAqbmdJZj1cInNob3dDaGFyc0xpbWl0TXNnXCJcclxuICAgICAgICBbbmdDbGFzc109XCJ7J2JhZGdlLWxpZ2h0LXdhcm5pbmcnOiBjaGFyc0xpbWl0TXNnQ2xhc3MgPT09ICd3YXJuaW5nJywgJ2JhZGdlLWxpZ2h0LWRhbmdlcicgOiBjaGFyc0xpbWl0TXNnQ2xhc3MgPT09ICdkYW5nZXInIH1cIj5cclxuICAgICAgICB7e21heExpbWl0V2FybmluZ01zZ319XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8IS0tIExhYmVsRGVzY3JpcHRpb24tLT5cclxuICAgICAgPGRpdiBjbGFzcz1cImJic2YtY29udHJvbC1kZXNjXCIgKm5nSWY9XCJvcHRpb25zLmxhYmVsRGVzY3JpcHRpb24hPW51bGxcIj57e29wdGlvbnMubGFiZWxEZXNjcmlwdGlvbn19PC9kaXY+XHJcbiAgICAgIDwhLS0gcmVxdWlyZWRUZXh0LS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLXZhbGlkYXRpb25cIiBbZGlyXT1cInRleHREaXJcIiAqbmdJZj1cIih0ZXh0QXJlYUZvcm1Db250cm9sLmludmFsaWQgJiYgdGV4dEFyZWFGb3JtQ29udHJvbC50b3VjaGVkKVwiPlxyXG4gICAgICAgIHt7Z2V0RXJyb3JWYWxpZGF0aW9uKHRleHRBcmVhRm9ybUNvbnRyb2wuZXJyb3JzfGtleXZhbHVlKX19XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiKGdyb3VwLnZhbGlkJiZncm91cC5kaXJ0eSYmZ3JvdXAudG91Y2hlZCApfHwoZ3JvdXAudW50b3VjaGVkJiZncm91cC5pbnZhbGlkJiZncm91cC5kaXJ0eSkgXCI+XHJcbiAgICAgIHt7cmVzZXRFcnJvcigpfX08L2Rpdj5cclxuICA8L2Rpdj4iXX0=
302
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dEFyZWEuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYmJzZi1jb250cm9scy9zcmMvbGliL2NvbnRyb2xzL1RleHRBcmVhL1RleHRBcmVhLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jic2YtY29udHJvbHMvc3JjL2xpYi9jb250cm9scy9UZXh0QXJlYS9UZXh0QXJlYS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDNUcsT0FBTyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQW9FLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7QUFXM0gsTUFBTSxPQUFPLGlCQUFpQjthQUdyQiwyQkFBc0IsR0FBRyxJQUFJLEFBQVAsQ0FBUTtJQUNyQyxZQUFvQixjQUE4QixFQUFzQixnQkFBa0MsRUFDakcsbUJBQXVDLEVBQVUsY0FBOEIsRUFDOUUsd0JBQWtELEVBQVUsY0FBOEIsRUFDMUYsd0JBQWtELEVBQVUsZUFBK0I7UUFIakYsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQXNCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDakcsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFvQjtRQUFVLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5RSw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQVUsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzFGLDZCQUF3QixHQUF4Qix3QkFBd0IsQ0FBMEI7UUFBVSxvQkFBZSxHQUFmLGVBQWUsQ0FBZ0I7UUFNM0YsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFHeEMsY0FBUyxHQUFXLENBQUMsQ0FBQztRQUN0QixtQkFBYyxHQUFXLENB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QztRQUUzRCxJQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsb0NBQW9DLEVBQUM7WUFDbkQsWUFBWSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBQyxZQUFZLENBQUMsQ0FBQTtTQUNwRDtJQUNILENBQUM7OEdBblVVLGlCQUFpQjtrR0FBakIsaUJBQWlCLHdJQ1o5QixpL0hBNkRBOzsyRkRqRGEsaUJBQWlCO2tCQUo3QixTQUFTOytCQUNFLGVBQWU7OzBCQU80QixRQUFRO2dQQU9wRCxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNJLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE9wdGlvbmFsLCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgQ2hhbmdlRGV0ZWN0b3JSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIFZhbGlkYXRvcnMsIEZvcm1Hcm91cCwgQWJzdHJhY3RDb250cm9sLCBDb250cm9sQ29udGFpbmVyLCBGb3JtR3JvdXBEaXJlY3RpdmUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IENvbnRyb2xWYWxpZGF0aW9uU2VydmljZSwgTGFuZ3VhZ2VTZXJ2aWNlLCBVdGlsaXR5U2VydmljZSxTcGVlY2hSZWNvZ25pdGlvblNlcnZpY2UgfSBmcm9tICdAYm5zaWdodHMvYmJzZi11dGlsaXRpZXMnO1xyXG5pbXBvcnQgeyBDb250cm9sVXRpbGl0eSB9IGZyb20gJy4uLy4uL1NoYXJlZC9zZXJ2aWNlcy9Db250cm9sVXRpbGl0eSc7XHJcbmltcG9ydCB7IFRleHRBcmVhT3B0aW9ucyB9IGZyb20gJy4uLy4uL1NoYXJlZC9Nb2RlbHMvVGV4dEFyZWFPcHRpb25zJztcclxuaW1wb3J0IHsgR2xvYmFsU2V0dGluZ3MgfSBmcm9tICcuLi8uLi9TaGFyZWQvc2VydmljZXMvR2xvYmFsU2V0dGluZ3Muc2VydmljZSc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdCQlNGLVRleHRBcmVhJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vVGV4dEFyZWEuY29tcG9uZW50Lmh0bWwnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUZXh0QXJlYUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG5cclxuICBzdGF0aWMgY29udHJvbENvbnRhaW5lcnN0YXRpYyA9IG51bGw7XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjb250cm9sVXRpbGl0eTogQ29udHJvbFV0aWxpdHksIEBPcHRpb25hbCgpIHByaXZhdGUgY29udHJvbENvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lcixcclxuICAgIHB1YmxpYyB0ZXh0QXJlYUNvbnRyb2xIb3N0OiBGb3JtR3JvdXBEaXJlY3RpdmUsIHByaXZhdGUgdXRpbGl0eVNlcnZpY2U6IFV0aWxpdHlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBjb250cm9sVmFsaWRhdGlvblNlcnZpY2U6IENvbnRyb2xWYWxpZGF0aW9uU2VydmljZSwgcHJpdmF0ZSBnbG9iYWxTZXR0aW5nczogR2xvYmFsU2V0dGluZ3MsXHJcbiAgICBwcml2YXRlIHNwZWVjaFJlY29nbml0aW9uU2VydmljZTogU3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlLCBwcml2YXRlIGxhbmd1YWdlU2VydmljZTpMYW5ndWFnZVNlcnZpY2UpIHtcclxuICAgIFRleHRBcmVhQ29tcG9uZW50LmNvbnRyb2xDb250YWluZXJzdGF0aWMgPSB0aGlzLmNvbnRyb2xDb250YWluZXI7XHJcbiAgICB0aGlzLmN1cnJlbnRMYW5ndWFnZT1sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbGFuZ3VhZ2UnKTtcclxuICB9XHJcbiAgQElucHV0KCkgZ3JvdXA6IEZvcm1Hcm91cDtcclxuICBASW5wdXQoKSBvcHRpb25zOiBUZXh0QXJlYU9wdGlvbnM7XHJcbiAgQE91dHB1dCgpIG9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICB0ZXh0QXJlYUZvcm1Db250cm9sOiBBYnN0cmFjdENvbnRyb2w7XHJcbiAgd29yZENvdW50OiBudW1iZXIgPSAwO1xyXG4gIHdvcmRDb3VudEFycmF5OiBudW1iZXIgPSAwO1xyXG4gIGlzU2hvd1dvcmRDb3VudDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIG1hcmtBbGxBc1RvdWNoZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICB2YWxpZGF0aW9uUnVsZXMgPSBbXTtcclxuICB2YWxpZGF0aW9uUnVsZXNhc3luYyA9IFtdO1xyXG4gIC8vRm9yIFNob3cgd2FybmluZyBtZXNzYWdlIG9mIG1heCBsZW5ndGggbGltaXRcclxuICBjdXJyZW50Q2hhcnNDb3VudDogbnVtYmVyID0gMDtcclxuICBzaG93Q2hhcnNMaW1pdE1zZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGhhc0NoYXJzTGltaXRWYWxpZGF0aW9uRXJyb3I6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBjaGFyc0xpbWl0TXNnQ2xhc3M6IHN0cmluZztcclxuICBtaW5DaGFyc0xpbWl0OiBudW1iZXIgPSAtMTsgLy9UbyBkaXNhYmxlIGNoYXJzIGxpbWl0IGZlYXR1cmUgYnkgZGVmYXVsdFxyXG4gIG1heExpbWl0V2FybmluZ01zZzogc3RyaW5nID0gXCJcIjtcclxuICBpc01pY09uOiBib29sZWFuID0gZmFsc2U7XHJcbiAgcHVibGljIHRleHREaXI7XHJcbiAgaXNGb2N1c2VkOiBib29sZWFuO1xyXG5jdXJyZW50TGFuZ3VhZ2U6U3RyaW5nO1xyXG5zdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmlzUmVhZG9ubHkgJiYgIXRoaXMub3B0aW9ucy52YWx1ZSlcclxuICAgICAgdGhpcy5vcHRpb25zLnZhbHVlID0gdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdOQScpO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZm9yY2VEaXJlY3Rpb24pXHJcbiAgICAgIHRoaXMudGV4dERpciA9IHRoaXMub3B0aW9ucy5mb3JjZURpcmVjdGlvbiA9PSAyID8gJ3J0bCcgOiAnbHRyJztcclxuICAgIGVsc2VcclxuICAgICAgdGhpcy50ZXh0RGlyID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2xhbmd1YWdlJykgPT0gJ2FyJyA/ICdydGwnIDogJ2x0cic7XHJcblxyXG4gICAgdGhpcy5jb250cm9sVmFsaWRhdGlvblNlcnZpY2UuaXNDcmVhdGVkQmVmb3IgPSBmYWxzZVxyXG5cclxuICAgIHRoaXMuZ3JvdXAuYWRkQ29udHJvbCh0aGlzLm9wdGlvbnMubmFtZSwgbmV3IEZvcm1Db250cm9sKCcnKSk7XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wgPSB0aGlzLmdyb3VwLmNvbnRyb2xzW3RoaXMub3B0aW9ucy5uYW1lXTsgLy8gIG5ldyBGb3JtQ29udHJvbCgnJyx2YWxpZGF0aW9uUnVsZXMpO1xyXG5cclxuICAgICAgLy8gSW5pdGlhbGl6ZSBsYW5ndWFnZSBmb3JtIGNvbnRyb2xcclxuICBjb25zdCBsYW5ndWFnZUNvbnRyb2xOYW1lID0gdGhpcy5vcHRpb25zLm5hbWUgKyAnTGFuZ3VhZ2UnO1xyXG4gIHRoaXMuZ3JvdXAuYWRkQ29udHJvbChsYW5ndWFnZUNvbnRyb2xOYW1lLCBuZXcgRm9ybUNvbnRyb2wodGhpcy5vcHRpb25zLnNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2UgfHwgJycpKTtcclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5tYXhMZW5ndGgpXHJcbiAgICAgIHRoaXMub3B0aW9ucy5tYXhMZW5ndGggPSB0aGlzLmdsb2JhbFNldHRpbmdzLm1heExlbmd0aFRleHRBcmVhO1xyXG5cclxuICAgIGlmICghdGhpcy5vcHRpb25zLnZpZXdUeXBlKVxyXG4gICAgICB0aGlzLm9wdGlvbnMudmlld1R5cGUgPSB0aGlzLmdsb2JhbFNldHRpbmdzLnZpZXdUeXBlO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMubGFiZWxLZXkgIT0gbnVsbCAmJiB0aGlzLm9wdGlvbnMubGFiZWxLZXkgIT0gXCJcIilcclxuICAgICAgdGhpcy5vcHRpb25zLmxhYmVsVmFsdWUgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUodGhpcy5vcHRpb25zLmxhYmVsS2V5KTtcclxuXHJcbiAgICBpZih0aGlzLm9wdGlvbnMuZW5hYmxlU3BlZWNoUmVjb2duaXRpb24pXHJcbiAgICB7XHJcbiAgICAgIC8vR2V0IGFsbCBsYW5ndWFnZXMgaWYgbm90IHNldFxyXG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5zcGVlY2hMYW5ndWFnZXMpIHtcclxuICAgICAgICB0aGlzLmxhbmd1YWdlU2VydmljZS5nZXRMYW5ndWFnZXMoKS5zdWJzY3JpYmUocmVzdWx0ID0+IHtcclxuICAgICAgICAgIHRoaXMub3B0aW9ucy5zcGVlY2hMYW5ndWFnZXMgPSByZXN1bHQ7XHJcbiAgICAgICAgICB0aGlzLnNldFNwZWVjaExhbmd1YWdlKCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgICBlbHNle1xyXG4gICAgICAgIHRoaXMuc2V0U3BlZWNoTGFuZ3VhZ2UoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgXHJcbiAgICB9XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuc2V0VmFsdWUodGhpcy5vcHRpb25zLnZhbHVlKTtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuY3VzdG9tVmFsaWRhdGlvbi5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGxldCBWYWxpZGF0aW9ucyA9IHRoaXMub3B0aW9ucy5jdXN0b21WYWxpZGF0aW9uXHJcbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBWYWxpZGF0aW9ucy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBjb25zdCBWYWxpZGF0aW9uID0gVmFsaWRhdGlvbnNbaW5kZXhdO1xyXG4gICAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdGlvbi5mdW5jdGlvbkJvZHkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5taW5MZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdG9ycy5taW5MZW5ndGgodGhpcy5vcHRpb25zLm1pbkxlbmd0aCkpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5tYXhMZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdG9ycy5tYXhMZW5ndGgodGhpcy5vcHRpb25zLm1heExlbmd0aCkpO1xyXG5cclxuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubWF4TGVuZ3RoV2FybmluZ0xpbWl0KVxyXG4gICAgICAgIHRoaXMub3B0aW9ucy5tYXhMZW5ndGhXYXJuaW5nTGltaXQgPSB0aGlzLmdsb2JhbFNldHRpbmdzLm1heExlbmd0aFdhcm5pbmdMaW1pdDtcclxuXHJcbiAgICAgIHRoaXMubWluQ2hhcnNMaW1pdCA9IHRoaXMub3B0aW9ucy5tYXhMZW5ndGggLSB0aGlzLm9wdGlvbnMubWF4TGVuZ3RoV2FybmluZ0xpbWl0O1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc1JlcXVpcmVkKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvblJ1bGVzLnB1c2goVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyh0aGlzLnZhbGlkYXRpb25SdWxlcyk7XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuc2V0QXN5bmNWYWxpZGF0b3JzKHRoaXMudmFsaWRhdGlvblJ1bGVzYXN5bmMpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc0Rpc2FibGVkKSB7XHJcbiAgICAgIHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC5kaXNhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50ZXh0QXJlYUNvbnRyb2xIb3N0Lm5nU3VibWl0LnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAgICAgdGhpcy5ncm91cC5tYXJrQWxsQXNUb3VjaGVkKClcclxuICAgICAgdGhpcy5tYXJrQWxsQXNUb3VjaGVkID0gdHJ1ZVxyXG4gICAgfSlcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5zZXRBdHRyaWJ1dGVGb3JDb250cm9sKHRoaXMub3B0aW9ucylcclxuICB9XHJcblxyXG4gIHJlc2V0RXJyb3IgPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xWYWxpZGF0aW9uU2VydmljZS5yZW1vdmVHbG9iYWxFcnJvcigpO1xyXG4gIH1cclxuXHJcbiAgc2hvd0dsb2JhbEVycm9yKCkge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5zaG93R2xvYmFsRXJyb3IoKVxyXG4gIH1cclxuXHJcbiAgZ2V0RXJyb3JWYWxpZGF0aW9uKEVycm9yTGlzdCkge1xyXG4gICAgaWYgKHRoaXMubWFya0FsbEFzVG91Y2hlZCAmJiB0aGlzLmdyb3VwLmludmFsaWQpIHtcclxuICAgICAgdGhpcy5zaG93R2xvYmFsRXJyb3IoKVxyXG4gICAgICB0aGlzLm1hcmtBbGxBc1RvdWNoZWQgPSBmYWxzZVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29udHJvbFV0aWxpdHkuZ2V0RXJyb3JWYWxpZGF0aW9uTWFzc2FnZShFcnJvckxpc3QsIHRoaXMuZ3JvdXAsIHRoaXMub3B0aW9ucyk7XHJcbiAgfVxyXG4gIGdldElucHV0VHlwZSh0eXBlOiBudW1iZXIpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbnRyb2xVdGlsaXR5LmdldElucHV0VHlwZSh0eXBlKVxyXG4gIH1cclxuXHJcbiAgdHJpbUNvbnRyb2xWYWx1ZSgpIHtcclxuICAgIGxldCBvcmlnaW5hbFZhbHVlID0gdGhpcy5jb250cm9sVXRpbGl0eS50cmltQ29udHJvbFZhbHVlKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC52YWx1ZSk7XHJcbiAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wucGF0Y2hWYWx1ZShvcmlnaW5hbFZhbHVlKVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wYXRjaEZ1bmN0aW9uICYmIHRoaXMub3B0aW9ucy5wYXRjaFBhdGggJiYgdGhpcy50ZXh0QXJlYUZvcm1Db250cm9sLnZhbGlkKSB7XHJcbiAgICAgIHRoaXMuY29udHJvbFV0aWxpdHkucGF0Y2hDb250cm9sVmFsdWUob3JpZ2luYWxWYWx1ZSwgdGhpcy5vcHRpb25zLnBhdGNoRnVuY3Rpb24sIHRoaXMub3B0aW9ucy5wYXRjaFBhdGgpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb3B5SW5wdXRNZXNzYWdlKGlucHV0RWxlbWVudCkge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5Db3B5SW5wdXRNZXNzYWdlKGlucHV0RWxlbWVudClcclxuICB9XHJcblxyXG4gIG9uVGV4dENoYW5nZSgpIHtcclxuXHJcbiAgICBpZiAodGhpcy50ZXh0QXJlYUZvcm1Db250cm9sLnZhbHVlID09IFwiXCIpIHtcclxuICAgICAgdGhpcy53b3JkQ291bnRBcnJheSA9IDA7XHJcbiAgICAgIHRoaXMud29yZENvdW50ID0gMDtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgdGhpcy53b3JkQ291bnRBcnJheSA9IHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC52YWx1ZS5zcGxpdChcIiBcIikubGVuZ3RoO1xyXG4gICAgICBpZiAodGhpcy53b3JkQ291bnRBcnJheSA+IDApIHtcclxuICAgICAgICBpZiAodGhpcy53b3JkQ291bnRBcnJheSA+IHRoaXMub3B0aW9ucy5tYXhXb3JkQ291bnQpIHtcclxuICAgICAgICAgIHRoaXMud29yZENvdW50ID0gdGhpcy5vcHRpb25zLm1heFdvcmRDb3VudDtcclxuICAgICAgICAgIHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC5zZXRFcnJvcnMoeyBcImVycm9yTWFzc2FnZVwiOiBgICBXb3JkIGNvdW50IG11c3QgYmUgbGVzcyB0aGVuIG9yIGVxdWFsICAke3RoaXMub3B0aW9ucy5tYXhXb3JkQ291bnR9YCB9KTtcclxuICAgICAgICAgIHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XHJcbiAgICAgICAgICB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wuaW52YWxpZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLndvcmRDb3VudCA9IHRoaXMud29yZENvdW50QXJyYXk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vQ2hlY2sgZm9yIG1heGxlbmd0aCBsaW1pdCBjb3VudFxyXG4gICAgLy9NYXhMZW5ndGggc2hvdWxkIGJlIGdyZXRhZXIgdGhhbiBvciBlcXVhbHMgY2hhcnMgbGltaXQgc28gdGhhdCBtaW5DaGFyc0xpbWl0IHdvdWxkIGJlID49IDBcclxuICAgIGlmICh0aGlzLm9wdGlvbnMubWF4TGVuZ3RoICYmIHRoaXMubWluQ2hhcnNMaW1pdCA+PSAwKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudENoYXJzQ291bnQgPSB0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wudmFsdWUubGVuZ3RoO1xyXG4gICAgICBpZiAodGhpcy5jdXJyZW50Q2hhcnNDb3VudCA+IHRoaXMubWluQ2hhcnNMaW1pdCkge1xyXG4gICAgICAgIHRoaXMuc2hvd0NoYXJzTGltaXRNc2cgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuaGFzQ2hhcnNMaW1pdFZhbGlkYXRpb25FcnJvciA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRDaGFyc0NvdW50ID09IHRoaXMub3B0aW9ucy5tYXhMZW5ndGgpXHJcbiAgICAgICAgICB0aGlzLmNoYXJzTGltaXRNc2dDbGFzcyA9IFwiZGFuZ2VyXCI7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgdGhpcy5jaGFyc0xpbWl0TXNnQ2xhc3MgPSBcIndhcm5pbmdcIjtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLnNob3dDaGFyc0xpbWl0TXNnID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5oYXNDaGFyc0xpbWl0VmFsaWRhdGlvbkVycm9yID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBtYXg6IG51bWJlciA9IHRoaXMub3B0aW9ucy5tYXhMZW5ndGg7XHJcbiAgICAgIGxldCBjdXJyZW50OiBudW1iZXIgPSB0aGlzLmN1cnJlbnRDaGFyc0NvdW50O1xyXG4gICAgICBsZXQgbXNnOiBzdHJpbmcgPSB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJNYXhMZW5ndGhMaW1pdFdhcm5pbmdcIik7XHJcblxyXG4gICAgICAvLyBSZXBsYWNlIHBsYWNlaG9sZGVycyB3aXRoIGFjdHVhbCB2YWx1ZXNcclxuICAgICAgdGhpcy5tYXhMaW1pdFdhcm5pbmdNc2cgPSBtc2cucmVwbGFjZShcIiR7bWF4fVwiLCBtYXgudG9TdHJpbmcoKSkucmVwbGFjZShcIiR7Y3VycmVudH1cIiwgY3VycmVudC50b1N0cmluZygpKTtcclxuICAgIH1cclxuICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wudmFsdWUpXHJcblxyXG4gIH1cclxuXHJcbiAgb25Gb2N1cyhpc0ZvY3VzOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmlzU2hvd1dvcmRDb3VudCA9IGlzRm9jdXM7XHJcblxyXG4gICAgLy9vbkZvY3VzXHJcbiAgICBpZiAoaXNGb2N1cykge1xyXG4gICAgICBpZiAodGhpcy5oYXNDaGFyc0xpbWl0VmFsaWRhdGlvbkVycm9yKSAvL2NoZWNrIGlmIHRoZXJlIHdhcyBwcmV2aW91cyB2YWxpZGF0aW9uIGVycm9yXHJcbiAgICAgICAgdGhpcy5zaG93Q2hhcnNMaW1pdE1zZyA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBlbHNlIC8vb25Gb2N1c091dFxyXG4gICAgICB0aGlzLnNob3dDaGFyc0xpbWl0TXNnID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIHJlbW92ZVJlcXVpcmVkVmFsaWRhdGlvbiA9ICgpID0+IHtcclxuICAgIHRoaXMuY29udHJvbFV0aWxpdHkucmVtb3ZlUmVxdWlyZWRWYWxpZGF0aW9uKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbCwgdGhpcy52YWxpZGF0aW9uUnVsZXMsIHRoaXMub3B0aW9ucylcclxuICB9XHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICBhZGRSZXF1aXJlZFZhbGlkYXRpb24gPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZFJlcXVpcmVkVmFsaWRhdGlvbih0aGlzLnRleHRBcmVhRm9ybUNvbnRyb2wsIHRoaXMudmFsaWRhdGlvblJ1bGVzLCB0aGlzLm9wdGlvbnMpXHJcbiAgfVxyXG5cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIHJlbW92ZUN1c3RvbVZhbGlkYXRpb24gPSAoY3VzdG9tVmFsaWRhdGlvbikgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5yZW1vdmVDdXN0b21WYWxpZGF0aW9uKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbCwgdGhpcy52YWxpZGF0aW9uUnVsZXMsIGN1c3RvbVZhbGlkYXRpb24pXHJcbiAgfVxyXG4gIC8vRXh0ZXJuYWwgTWV0aG9kXHJcbiAgYWRkQ3VzdG9tVmFsaWRhdGlvbiA9IChjdXN0b21WYWxpZGF0aW9uKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZEN1c3RvbVZhbGlkYXRpb24odGhpcy50ZXh0QXJlYUZvcm1Db250cm9sLCB0aGlzLnZhbGlkYXRpb25SdWxlcywgY3VzdG9tVmFsaWRhdGlvbilcclxuICB9XHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICBpc1ZhbGlkID0gKCkgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5pc1ZhbGlkKHRoaXMudGV4dEFyZWFGb3JtQ29udHJvbClcclxuICB9XHJcbiAgLy9yZWdpb24gU3BlZWNoIFJlY29nbml0aW9uXHJcbiAgc2V0U3BlZWNoTGFuZ3VhZ2UoKXtcclxuICAgIGNvbnN0IGxhbmd1YWdlQ29udHJvbE5hbWUgPSB0aGlzLm9wdGlvbnMubmFtZSArICdMYW5ndWFnZSc7XHJcblxyXG4gICAgaWYodGhpcy5vcHRpb25zLmF1dG9TYXZlU3BlZWNoTGFuZ3VhZ2V0b0xvY2FsU3RvcmFnZSl7XHJcbiAgICAgIGxldCBzYXZlZExhbmd1YWdlPWxvY2FsU3RvcmFnZS5nZXRJdGVtKFwic3BlZWNoTGFuZ3VhZ2VcIik7XHJcbiAgICAgIGlmKHNhdmVkTGFuZ3VhZ2Upe1xyXG4gICAgICAgIHRoaXMub3B0aW9ucy5zZWxlY3RlZFNwZWVjaExhbmd1YWdlPXNhdmVkTGFuZ3VhZ2U7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZXtcclxuICAgICAgICB0aGlzLmxvYWRTZWxlY3RlZFNwZWVjaExhbmd1YWdlKCk7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oXCJzcGVlY2hMYW5ndWFnZVwiLHRoaXMub3B0aW9ucy5zZWxlY3RlZFNwZWVjaExhbmd1YWdlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZXtcclxuICAgICAgdGhpcy5sb2FkU2VsZWN0ZWRTcGVlY2hMYW5ndWFnZSgpOyBcclxuICAgIH1cclxuICAgIHRoaXMuZ3JvdXAuZ2V0KGxhbmd1YWdlQ29udHJvbE5hbWUpLnNldFZhbHVlKHRoaXMub3B0aW9ucy5zZWxlY3RlZFNwZWVjaExhbmd1YWdlKTtcclxuICB9XHJcbiAgbG9hZFNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2UoKXtcclxuICAgIGlmICghdGhpcy5vcHRpb25zLnNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2Upe1xyXG4gICAgICBpZih0aGlzLmN1cnJlbnRMYW5ndWFnZT09XCJlblwiICYmIHRoaXMub3B0aW9ucy5zcGVlY2hMYW5ndWFnZXMuc29tZShsYW5ndWFnZSA9PiBsYW5ndWFnZS5lbmdsaXNoTmFtZSA9PT0gJ0VuZ2xpc2gnKSl7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zLnNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2U9dGhpcy5vcHRpb25zLnNwZWVjaExhbmd1YWdlcy5maW5kKGxhbmd1YWdlID0+IGxhbmd1YWdlLmVuZ2xpc2hOYW1lID09PSAnRW5nbGlzaCcpLmRpYWxlY3Q7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZih0aGlzLmN1cnJlbnRMYW5ndWFnZT09XCJhclwiICYmIHRoaXMub3B0aW9ucy5zcGVlY2hMYW5ndWFnZXMuc29tZShsYW5ndWFnZSA9PiBsYW5ndWFnZS5lbmdsaXNoTmFtZSA9PT0gJ0FyYWJpYycpKXtcclxuICAgICAgICB0aGlzLm9wdGlvbnMuc2VsZWN0ZWRTcGVlY2hMYW5ndWFnZT10aGlzLm9wdGlvbnMuc3BlZWNoTGFuZ3VhZ2VzLmZpbmQobGFuZ3VhZ2UgPT4gbGFuZ3VhZ2UuZW5nbGlzaE5hbWUgPT09ICdBcmFiaWMnKS5kaWFsZWN0O1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2V7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zLnNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2UgPSB0aGlzLm9wdGlvbnMuc3BlZWNoTGFuZ3VhZ2VzWzBdLmRpYWxlY3Q7XHJcbiAgICAgIH1cclxuICB9XHJcbn1cclxuICBzdGFydFNwZWVjaFJlY29nbml0aW9uKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNwZWVjaFJlY29nbml0aW9uU2VydmljZS5pc1N1cHBvcnRlZCkge1xyXG4gICAgICB0aGlzLnV0aWxpdHlTZXJ2aWNlLm5vdGlmeUVycm9yTWVzc2FnZSh0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJCcm93c2VyTm90U3VwcG9ydFNwZWVjaFJlY29nbml0aW9uXCIpKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5pc01pY09uID0gdHJ1ZTtcclxuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5zcGVlY2hSZWNvZ25pdGlvblNlcnZpY2Uuc3RhcnRMaXN0ZW5pbmcodGhpcy5vcHRpb25zLnNlbGVjdGVkU3BlZWNoTGFuZ3VhZ2UpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6ICh0cmFuc2NyaXB0OiBzdHJpbmcpID0+IHtcclxuICAgICAgICBpZih0cmFuc2NyaXB0KXtcclxuICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy52YWx1ZSl7XHJcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy52YWx1ZSs9JyAnO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbGV0IGNoYXJJbmRleCA9IDA7XHJcbiAgICAgICAgICBjb25zdCBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnZhbHVlICs9IHRyYW5zY3JpcHRbY2hhckluZGV4XTtcclxuICAgICAgICAgICAgY2hhckluZGV4Kys7XHJcbiAgICAgICAgICAgIGlmIChjaGFySW5kZXggPT09IHRyYW5zY3JpcHQubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sIDEwKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIHRoaXMuc3RvcFNwZWVjaFJlY29nbml0aW9uKCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5pc01pY09uID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc3RvcFNwZWVjaFJlY29nbml0aW9uKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNwZWVjaFJlY29nbml0aW9uU2VydmljZS5pc1N1cHBvcnRlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLmlzTWljT24gPSBmYWxzZTtcclxuICAgIHRoaXMuc3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlLnN0b3BMaXN0ZW5pbmcoKTtcclxuICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbikge1xyXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLnN0b3BTcGVlY2hSZWNvZ25pdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgb25TcGVlY2hMYW5ndWFnZUNoYW5nZShldmVudCkge1xyXG4gICAgbGV0IHNlbGVjdGVkTGFuZz1ldmVudC50YXJnZXQudmFsdWU7XHJcbiAgICB0aGlzLm9wdGlvbnMuc2VsZWN0ZWRTcGVlY2hMYW5ndWFnZSA9IHNlbGVjdGVkTGFuZztcclxuXHJcbiAgICBjb25zdCBsYW5ndWFnZUNvbnRyb2xOYW1lID0gdGhpcy5vcHRpb25zLm5hbWUgKyAnTGFuZ3VhZ2UnO1xyXG4gICAgdGhpcy5ncm91cC5nZXQobGFuZ3VhZ2VDb250cm9sTmFtZSkuc2V0VmFsdWUoc2VsZWN0ZWRMYW5nKTtcclxuICAgIFxyXG4gICAgaWYodGhpcy5vcHRpb25zLmF1dG9TYXZlU3BlZWNoTGFuZ3VhZ2V0b0xvY2FsU3RvcmFnZSl7XHJcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwic3BlZWNoTGFuZ3VhZ2VcIixzZWxlY3RlZExhbmcpXHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vI2VuZFJlZ2lvblxyXG59XHJcblxyXG5cclxuIiwiPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgYmJzZi1jb250cm9sIGJic2YtdGV4dGFyZWFcIiBbZm9ybUdyb3VwXT1cImdyb3VwXCI+XHJcbiAgPGRpdiBbbmdDbGFzc109XCIob3B0aW9ucy52aWV3VHlwZT09MSk/J2Jic2YtdmVydGljYWwnOidiYnNmLWhvcml6b250YWwnXCI+XHJcbiAgICA8IS0tbGFiZWwtLT5cclxuICAgIDxsYWJlbCAqbmdJZj1cIiFvcHRpb25zLmhpZGVMYWJlbFwiIGNsYXNzPVwiYmJzZi1sYWJlbCB7e29wdGlvbnMubGFiZWxFeHRyYUNsYXNzZXN9fVwiPlxyXG4gICAgICB7e29wdGlvbnMubGFiZWxWYWx1ZX19XHJcbiAgICAgIDwhLS1Bc3Rlcmlzay0tPlxyXG4gICAgICA8c3BhbiAqbmdJZj1cIigob3B0aW9ucy5zaG93QXN0ZXJpc2smJm9wdGlvbnMuaXNSZXF1aXJlZCl8fChvcHRpb25zLmlzUmVxdWlyZWQpKSYmIW9wdGlvbnMuaXNSZWFkb25seVwiXHJcbiAgICAgICAgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+XHJcbiAgICA8L2xhYmVsPlxyXG4gICAgPGRpdiAqbmdJZj1cIiFvcHRpb25zLmlzUmVhZG9ubHlcIiBjbGFzcz1cImJic2YtaW5wdXQtY29udGFpbmVyXCIgW25nQ2xhc3NdPVwie1xyXG4gICAgICAncC0xMjBweCc6IG9wdGlvbnMuZW5hYmxlU3BlZWNoUmVjb2duaXRpb24gJiYgb3B0aW9ucy5lbmFibGVDb3B5VG9DbGlwYm9hcmQsXHJcbiAgICAgICdwLTgwcHgnOiBvcHRpb25zLmVuYWJsZVNwZWVjaFJlY29nbml0aW9uICYmICFvcHRpb25zLmVuYWJsZUNvcHlUb0NsaXBib2FyZCxcclxuICAgICAgJ3AtNDBweCc6ICFvcHRpb25zLmVuYWJsZVNwZWVjaFJlY29nbml0aW9uICYmIG9wdGlvbnMuZW5hYmxlQ29weVRvQ2xpcGJvYXJkXHJcbiAgICB9XCI+XHJcbiAgICAgIDwhLS1pbnB1dC0tPlxyXG4gICAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2wge3tvcHRpb25zLmV4dHJhQ2xhc3Nlc319XCIgKGZvY3VzKT1cIm9uRm9jdXModHJ1ZSlcIiAoZm9jdXNvdXQpPVwib25Gb2N1cyhmYWxzZSlcIlxyXG4gICAgICAgIFtkaXJdPVwidGV4dERpclwiIGFyaWEtZGVzY3JpYmVkYnk9XCJlbWFpbC1lcnJvclwiIGFyaWEtaW52YWxpZD1cInRydWVcIiBmb3JtQ29udHJvbE5hbWU9XCJ7e29wdGlvbnMubmFtZX19XCJcclxuICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJ0ZXh0QXJlYUZvcm1Db250cm9sLmludmFsaWQgJiYgdGV4dEFyZWFGb3JtQ29udHJvbC50b3VjaGVkXCJcclxuICAgICAgICBwbGFjZWhvbGRlcj1cInt7b3B0aW9ucy5wbGFjZWhvbGRlcn19XCIgaWQ9XCJ7e29wdGlvbnMubmFtZX19XCIgYXV0b2NvbXBsZXRlPVwie3tvcHRpb25zLmF1dG9Db21wbGV0ZX19XCJcclxuICAgICAgICAoY2hhbmdlKT1cInRyaW1Db250cm9sVmFsdWUoKVwiIHJvd3M9XCJ7e29wdGlvbnMucm93c319XCIgKGtleXVwKT1cIm9uVGV4dENoYW5nZSgpXCIgY29scz1cInt7b3B0aW9ucy5jb2xzfX1cIlxyXG4gICAgICAgIG1heGxlbmd0aD1cInt7b3B0aW9ucy5tYXhMZW5ndGh9fVwiIG1pbmxlbmd0aD1cInt7b3B0aW9ucy5taW5MZW5ndGh9fVwiIFsobmdNb2RlbCldPVwib3B0aW9ucy52YWx1ZVwiXHJcbiAgICAgICAgKGtleWRvd24pPVwid29yZENvdW50QXJyYXk+b3B0aW9ucy5tYXhXb3JkQ291bnQmJiRldmVudC5rZXlDb2RlICE9OD8kZXZlbnQucHJldmVudERlZmF1bHQoKTpudWxsXCJcclxuICAgICAgICAjVGV4dEFyZWFpbnB1dD48L3RleHRhcmVhPlxyXG4gICAgICA8IS0tQ29weVRvQ2xpcGJvYXJkLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJjb3B5LWNsaXBib2FyZFwiICpuZ0lmPVwib3B0aW9ucy5lbmFibGVDb3B5VG9DbGlwYm9hcmRcIiAoY2xpY2spPVwiY29weUlucHV0TWVzc2FnZShUZXh0QXJlYWlucHV0KVwiPlxyXG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNvcHlcIj48L2k+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsnZXhwYW5kZWQnOiBpc0ZvY3VzZWR9XCIgY2xhc3M9XCJsYW5ndWFnZS1jb250YWluZXIge3tvcHRpb25zLmV4dHJhQ2xhc3NNaWNMYW5ndWFnZX19XCIgKm5nSWY9XCJvcHRpb25zLmVuYWJsZVNwZWVjaFJlY29nbml0aW9uXCI+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzdmctaWNvbiBzdmctaWNvbi01XCIgW2lubGluZVNWR109XCJvcHRpb25zLmljb25NaWM/IG9wdGlvbnMuaWNvbk1pYyA6ICcuL3NyYy9hc3NldHMvaW1hZ2VzL21pYy5zdmcnXCIgKGNsaWNrKT1cInN0YXJ0U3BlZWNoUmVjb2duaXRpb24oKVwiXHJcbiAgICAgICAgICAgICpuZ0lmPVwiIWlzTWljT25cIj5cclxuICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzdmctaWNvbiBzdmctaWNvbi01XCIgIFtpbmxpbmVTVkddPVwib3B0aW9ucy5pY29uTWljT2ZmPyBvcHRpb25zLmljb25NaWNPZmYgOiAnLi9zcmMvYXNzZXRzL2ltYWdlcy9taWMtb2ZmLnN2ZydcIiAoY2xpY2spPVwic3RvcFNwZWVjaFJlY29nbml0aW9uKClcIlxyXG4gICAgICAgICAgICAqbmdJZj1cImlzTWljT25cIj5cclxuICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgPHNlbGVjdCBjbGFzcz1cImxhbmd1YWdlLXNlbGVjdFwiIFtmb3JtQ29udHJvbE5hbWVdPVwib3B0aW9ucy5uYW1lICsgJ0xhbmd1YWdlJ1wiIChjaGFuZ2UpPVwib25TcGVlY2hMYW5ndWFnZUNoYW5nZSgkZXZlbnQpXCI+XHJcbiAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBsYW5ndWFnZSBvZiBvcHRpb25zLnNwZWVjaExhbmd1YWdlc1wiIFt2YWx1ZV09XCJsYW5ndWFnZS5kaWFsZWN0XCI+e3tsYW5ndWFnZS5kaXNwbGF5TmFtZX19PC9vcHRpb24+XHJcbiAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPCEtLSByZWFkb25seSAtLT5cclxuICAgIDxkaXYgKm5nSWY9XCJvcHRpb25zLmlzUmVhZG9ubHlcIj48c3BhbiBjbGFzcz1cInJlYWRvbmx5LXZpZXdcIj57e29wdGlvbnMudmFsdWV9fTwvc3Bhbj5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cInN1YnRleHQtY29udGFpbmVyXCI+XHJcbiAgICAgIDwhLS13b3JkQ291bnQtLT5cclxuICAgICAgPGRpdiBjbGFzcz1cImJic2Ytd29yZC1jb3VudFwiICpuZ0lmPVwib3B0aW9ucy5tYXhXb3JkQ291bnQ+MCYmaXNTaG93V29yZENvdW50XCI+XHJcbiAgICAgICAge3t3b3JkQ291bnR9fS97e29wdGlvbnMubWF4V29yZENvdW50fX0gV29yZHM8L2Rpdj5cclxuICAgICAgPCEtLSBDaGFyc0xpbWl0TXNnLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLWNoYXJhY3Rlci1jb3VudFwiICpuZ0lmPVwic2hvd0NoYXJzTGltaXRNc2dcIlxyXG4gICAgICAgIFtuZ0NsYXNzXT1cInsnYmFkZ2UtbGlnaHQtd2FybmluZyc6IGNoYXJzTGltaXRNc2dDbGFzcyA9PT0gJ3dhcm5pbmcnLCAnYmFkZ2UtbGlnaHQtZGFuZ2VyJyA6IGNoYXJzTGltaXRNc2dDbGFzcyA9PT0gJ2RhbmdlcicgfVwiPlxyXG4gICAgICAgIHt7bWF4TGltaXRXYXJuaW5nTXNnfX1cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDwhLS0gTGFiZWxEZXNjcmlwdGlvbi0tPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiYmJzZi1jb250cm9sLWRlc2NcIiAqbmdJZj1cIm9wdGlvbnMubGFiZWxEZXNjcmlwdGlvbiE9bnVsbFwiPnt7b3B0aW9ucy5sYWJlbERlc2NyaXB0aW9ufX08L2Rpdj5cclxuICAgICAgPCEtLSByZXF1aXJlZFRleHQtLT5cclxuICAgICAgPGRpdiBjbGFzcz1cImJic2YtdmFsaWRhdGlvblwiIFtkaXJdPVwidGV4dERpclwiICpuZ0lmPVwiKHRleHRBcmVhRm9ybUNvbnRyb2wuaW52YWxpZCAmJiB0ZXh0QXJlYUZvcm1Db250cm9sLnRvdWNoZWQpXCI+XHJcbiAgICAgICAge3tnZXRFcnJvclZhbGlkYXRpb24odGV4dEFyZWFGb3JtQ29udHJvbC5lcnJvcnN8a2V5dmFsdWUpfX1cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgKm5nSWY9XCIoZ3JvdXAudmFsaWQmJmdyb3VwLmRpcnR5JiZncm91cC50b3VjaGVkICl8fChncm91cC51bnRvdWNoZWQmJmdyb3VwLmludmFsaWQmJmdyb3VwLmRpcnR5KSBcIj5cclxuICAgICAge3tyZXNldEVycm9yKCl9fTwvZGl2PlxyXG4gIDwvZGl2PlxyXG4iXX0=