@bnsights/bbsf-controls 1.0.149 → 1.0.151
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 +8 -0
- package/bnsights-bbsf-controls-1.0.151.tgz +0 -0
- package/esm2022/lib/Shared/Enums/Markdown.mjs +20 -0
- package/esm2022/lib/Shared/Models/MarkdownEditorOptions.mjs +24 -0
- package/esm2022/lib/controls/MarkdownEditor/markdown-editor.component.mjs +235 -0
- package/esm2022/lib/controls/TextArea/TextArea.component.mjs +24 -15
- package/esm2022/lib/controls/bbsf-controls.module.mjs +17 -8
- package/esm2022/public-api.mjs +4 -1
- package/fesm2022/bnsights-bbsf-controls.mjs +306 -23
- package/fesm2022/bnsights-bbsf-controls.mjs.map +1 -1
- package/lib/Shared/Enums/Markdown.d.ts +17 -0
- package/lib/Shared/Models/MarkdownEditorOptions.d.ts +29 -0
- package/lib/controls/MarkdownEditor/markdown-editor.component.d.ts +94 -0
- package/lib/controls/TextArea/TextArea.component.d.ts +2 -3
- package/lib/controls/bbsf-controls.module.d.ts +32 -30
- package/package.json +19 -17
- package/public-api.d.ts +3 -0
- package/src/lib/assets/Style-rtl.scss +18 -2
- package/src/lib/assets/Style.scss +4 -1
- package/src/lib/assets/ace-builds/ace.js +23 -0
- package/src/lib/assets/ace-builds/mode-markdown.js +8 -0
- package/src/lib/assets/ngx-markdown-editor/highlight.js/agate.min.css +17 -0
- package/src/lib/assets/ngx-markdown-editor/highlight.js/highlight.min.js +2 -0
- package/src/lib/assets/ngx-markdown-editor/marked.min.js +6 -0
- package/src/lib/assets/sass/base.scss +25 -13
- package/src/lib/assets/sass/markdown.scss +98 -0
- package/bnsights-bbsf-controls-1.0.149.tgz +0 -0
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.151 / 19-8-2024
|
|
9
|
+
======================
|
|
10
|
+
* Added MarkdownEditor Control
|
|
11
|
+
|
|
12
|
+
## 1.0.150 / 8-8-2024
|
|
13
|
+
======================
|
|
14
|
+
* Updated TextAreaComponent speech language select with UI fixes
|
|
15
|
+
|
|
8
16
|
## 1.0.149 / 6-8-2024
|
|
9
17
|
======================
|
|
10
18
|
* Updated TextAreaComponent speech language select
|
|
Binary file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export var MarkdownMode;
|
|
2
|
+
(function (MarkdownMode) {
|
|
3
|
+
MarkdownMode["editor"] = "editor";
|
|
4
|
+
MarkdownMode["preview"] = "preview";
|
|
5
|
+
})(MarkdownMode || (MarkdownMode = {}));
|
|
6
|
+
export var MarkDownIcons;
|
|
7
|
+
(function (MarkDownIcons) {
|
|
8
|
+
MarkDownIcons["Bold"] = "Bold";
|
|
9
|
+
MarkDownIcons["Italic"] = "Italic";
|
|
10
|
+
MarkDownIcons["Heading"] = "Heading";
|
|
11
|
+
MarkDownIcons["Reference"] = "Reference";
|
|
12
|
+
MarkDownIcons["Link"] = "Link";
|
|
13
|
+
MarkDownIcons["Image"] = "Image";
|
|
14
|
+
MarkDownIcons["Ul"] = "Ul";
|
|
15
|
+
MarkDownIcons["Ol"] = "Ol";
|
|
16
|
+
MarkDownIcons["Code"] = "Code";
|
|
17
|
+
MarkDownIcons["TogglePreview"] = "TogglePreview";
|
|
18
|
+
MarkDownIcons["FullScreen"] = "FullScreen";
|
|
19
|
+
})(MarkDownIcons || (MarkDownIcons = {}));
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWFya2Rvd24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9iYnNmLWNvbnRyb2xzL3NyYy9saWIvU2hhcmVkL0VudW1zL01hcmtkb3duLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLFlBR1Q7QUFISCxXQUFZLFlBQVk7SUFDcEIsaUNBQWUsQ0FBQTtJQUNmLG1DQUFpQixDQUFBO0FBQ25CLENBQUMsRUFIUyxZQUFZLEtBQVosWUFBWSxRQUdyQjtBQUNELE1BQU0sQ0FBTixJQUFZLGFBWVg7QUFaRCxXQUFZLGFBQWE7SUFDdkIsOEJBQWEsQ0FBQTtJQUNiLGtDQUFpQixDQUFBO0lBQ2pCLG9DQUFtQixDQUFBO0lBQ25CLHdDQUF1QixDQUFBO0lBQ3ZCLDhCQUFhLENBQUE7SUFDYixnQ0FBZSxDQUFBO0lBQ2YsMEJBQVMsQ0FBQTtJQUNULDBCQUFTLENBQUE7SUFDVCw4QkFBYSxDQUFBO0lBQ2IsZ0RBQStCLENBQUE7SUFDL0IsMENBQXlCLENBQUE7QUFDM0IsQ0FBQyxFQVpXLGFBQWEsS0FBYixhQUFhLFFBWXhCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gTWFya2Rvd25Nb2RlIHtcclxuICAgIGVkaXRvcj1cImVkaXRvclwiLFxyXG4gICAgcHJldmlldz1cInByZXZpZXdcIlxyXG4gIH1cclxuICBleHBvcnQgZW51bSBNYXJrRG93bkljb25zIHtcclxuICAgIEJvbGQgPSAnQm9sZCcsXHJcbiAgICBJdGFsaWMgPSAnSXRhbGljJyxcclxuICAgIEhlYWRpbmcgPSAnSGVhZGluZycsXHJcbiAgICBSZWZlcmVuY2UgPSAnUmVmZXJlbmNlJyxcclxuICAgIExpbmsgPSAnTGluaycsXHJcbiAgICBJbWFnZSA9ICdJbWFnZScsXHJcbiAgICBVbCA9ICdVbCcsXHJcbiAgICBPbCA9ICdPbCcsXHJcbiAgICBDb2RlID0gJ0NvZGUnLFxyXG4gICAgVG9nZ2xlUHJldmlldyA9ICdUb2dnbGVQcmV2aWV3JyxcclxuICAgIEZ1bGxTY3JlZW4gPSAnRnVsbFNjcmVlbidcclxuICB9XHJcbiAgXHJcbiAgIl19
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ControlOptionsBase } from "./ControlOptionsBase";
|
|
2
|
+
export class MarkdownEditorOptions extends ControlOptionsBase {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
/**To set value to MarkdownEditor */
|
|
6
|
+
this.value = '';
|
|
7
|
+
//Enable viewing preview panel
|
|
8
|
+
this.showPreviewPanelOnLoad = true;
|
|
9
|
+
/**
|
|
10
|
+
* Array of icons to be hidden from the toolbar.
|
|
11
|
+
*
|
|
12
|
+
* You can populate this array with icon names from the `MarkDownIcons` enum.
|
|
13
|
+
* This allows you to customize the toolbar by hiding specific icons based on your requirements.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Hide the Bold and Italic icons
|
|
17
|
+
* hideIcons: [MarkDownIcons.Bold, MarkDownIcons.Italic];
|
|
18
|
+
*/
|
|
19
|
+
this.hideIcons = [];
|
|
20
|
+
/** Set Height For MarkdownEditor ,default=400px */
|
|
21
|
+
this.height = '400px';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWFya2Rvd25FZGl0b3JPcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYmJzZi1jb250cm9scy9zcmMvbGliL1NoYXJlZC9Nb2RlbHMvTWFya2Rvd25FZGl0b3JPcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTFELE1BQU0sT0FBTyxxQkFBc0IsU0FBUSxrQkFBa0I7SUFBN0Q7O1FBQ0Usc0NBQXNDO1FBQ3RDLFVBQUssR0FBTyxFQUFFLENBQUE7UUFLZCw4QkFBOEI7UUFDOUIsMkJBQXNCLEdBQVUsSUFBSSxDQUFDO1FBQ3JDOzs7Ozs7Ozs7V0FTRztRQUNILGNBQVMsR0FBYyxFQUFFLENBQUM7UUFRMUIsbURBQW1EO1FBQ25ELFdBQU0sR0FBUSxPQUFPLENBQUE7SUFFdkIsQ0FBQztDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRm9yY2VEaXJlY3Rpb24gfSBmcm9tIFwiLi4vRW51bXMvRm9yY2VEaXJlY3Rpb25cIjtcclxuaW1wb3J0IHsgQ29udHJvbE9wdGlvbnNCYXNlIH0gZnJvbSBcIi4vQ29udHJvbE9wdGlvbnNCYXNlXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgTWFya2Rvd25FZGl0b3JPcHRpb25zIGV4dGVuZHMgQ29udHJvbE9wdGlvbnNCYXNlIHtcclxuICAvKipUbyBzZXQgIHZhbHVlICB0byBNYXJrZG93bkVkaXRvciAqL1xyXG4gIHZhbHVlPzogYW55PScnXHJcbiAgLy8qKiBTZXQgdGhlIE1heExlbmd0aCBvZiBjaGFyYWN0ZXJzIEluIE1hcmtkb3duRWRpdG9yICovXHJcbiAgbWF4TGVuZ3RoPzogbnVtYmVyXHJcbiAgLyoqU2V0IHRoZSBNaW5MZW5ndGggb2YgY2hhcmFjdGVycyBJbiBNYXJrZG93bkVkaXRvciAgKi9cclxuICBtaW5MZW5ndGg/Om51bWJlclxyXG4gIC8vRW5hYmxlIHZpZXdpbmcgcHJldmlldyBwYW5lbFxyXG4gIHNob3dQcmV2aWV3UGFuZWxPbkxvYWQ/OmJvb2xlYW49dHJ1ZTtcclxuICAvKipcclxuICAgKiBBcnJheSBvZiBpY29ucyB0byBiZSBoaWRkZW4gZnJvbSB0aGUgdG9vbGJhci5cclxuICAgKiBcclxuICAgKiBZb3UgY2FuIHBvcHVsYXRlIHRoaXMgYXJyYXkgd2l0aCBpY29uIG5hbWVzIGZyb20gdGhlIGBNYXJrRG93bkljb25zYCBlbnVtLlxyXG4gICAqIFRoaXMgYWxsb3dzIHlvdSB0byBjdXN0b21pemUgdGhlIHRvb2xiYXIgYnkgaGlkaW5nIHNwZWNpZmljIGljb25zIGJhc2VkIG9uIHlvdXIgcmVxdWlyZW1lbnRzLlxyXG4gICAqIFxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogLy8gSGlkZSB0aGUgQm9sZCBhbmQgSXRhbGljIGljb25zXHJcbiAgICogaGlkZUljb25zOiBbTWFya0Rvd25JY29ucy5Cb2xkLCBNYXJrRG93bkljb25zLkl0YWxpY107XHJcbiAgICovXHJcbiAgaGlkZUljb25zPzogc3RyaW5nW10gPSBbXTtcclxuICAvKipcclxuICAgKiAgQWxsb3dzIHlvdSB0byBzcGVjaWZ5IGEgY3VzdG9tIHJlbmRlcmluZyBmdW5jdGlvbiBmb3IgdGhlIE1hcmtkb3duIGNvbnRlbnQuXHJcbiAgICogVGhpcyBjYW4gYmUgdXNlZCB0byBvdmVycmlkZSBvciBleHRlbmQgdGhlIGRlZmF1bHQgcmVuZGVyaW5nIGJlaGF2aW9yIHdpdGggY3VzdG9tIEhUTUwgb3Igc3R5bGluZy5cclxuICAgKnsgaW1hZ2U6IGZ1bmN0aW9uIChocmVmOiBzdHJpbmcsIHRpdGxlOiBzdHJpbmcsIHRleHQ6IHN0cmluZyl7fSxjb2RlIGZ1bmN0aW9uKGNvZGU6IGFueSwgbGFuZ3VhZ2U6IGFueSl7fSxcclxuICAgKiB0YWJsZTpmdW5jdGlvbiAoaGVhZGVyOiBzdHJpbmcsIGJvZHk6IHN0cmluZyl7fSxsaXN0aXRlbTpmdW5jdGlvbiAodGV4dDogYW55LCB0YXNrOiBib29sZWFuLCBjaGVja2VkOiBib29sZWFuKXt9fVxyXG4gICAqL1xyXG4gIGN1c3RvbVJlbmRlcjphbnk7XHJcbiAgLyoqIFNldCBIZWlnaHQgRm9yIE1hcmtkb3duRWRpdG9yICxkZWZhdWx0PTQwMHB4ICovXHJcbiAgaGVpZ2h0OnN0cmluZz0nNDAwcHgnXHJcblxyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Optional, Output } from '@angular/core';
|
|
2
|
+
import { FormControl, Validators } from '@angular/forms';
|
|
3
|
+
import { MarkdownMode } from '../../Shared/Enums/Markdown';
|
|
4
|
+
import { switchMap } from 'rxjs';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@bnsights/bbsf-utilities";
|
|
7
|
+
import * as i2 from "../../Shared/services/GlobalSettings.service";
|
|
8
|
+
import * as i3 from "../../Shared/services/ControlUtility";
|
|
9
|
+
import * as i4 from "@angular/forms";
|
|
10
|
+
import * as i5 from "ngx-script-loader";
|
|
11
|
+
import * as i6 from "@angular/common";
|
|
12
|
+
import * as i7 from "ngx-intl-tel-input";
|
|
13
|
+
import * as i8 from "ngx-markdown-editor";
|
|
14
|
+
export class MarkdownEditorComponent {
|
|
15
|
+
static { this.controlContainerstatic = null; }
|
|
16
|
+
constructor(utilityService, globalSettings, controlValidationService, controlUtility, markdownEditorControlHost, scriptService, controlContainer) {
|
|
17
|
+
this.utilityService = utilityService;
|
|
18
|
+
this.globalSettings = globalSettings;
|
|
19
|
+
this.controlValidationService = controlValidationService;
|
|
20
|
+
this.controlUtility = controlUtility;
|
|
21
|
+
this.markdownEditorControlHost = markdownEditorControlHost;
|
|
22
|
+
this.scriptService = scriptService;
|
|
23
|
+
this.controlContainer = controlContainer;
|
|
24
|
+
this.OnChange = new EventEmitter();
|
|
25
|
+
this.hideToolbar = false;
|
|
26
|
+
this.validationRules = [];
|
|
27
|
+
this.validationRulesasync = [];
|
|
28
|
+
this.markAllAsTouched = false;
|
|
29
|
+
this.showMarkdown = false;
|
|
30
|
+
this.btnsText = {
|
|
31
|
+
Buttons: {
|
|
32
|
+
Bold: { title: this.utilityService.getResourceValue('Bold') },
|
|
33
|
+
Italic: { title: this.utilityService.getResourceValue('Italic') },
|
|
34
|
+
Heading: { title: this.utilityService.getResourceValue('Heading') },
|
|
35
|
+
Reference: { title: this.utilityService.getResourceValue('Reference') },
|
|
36
|
+
Link: { title: this.utilityService.getResourceValue('Link') },
|
|
37
|
+
Image: { title: this.utilityService.getResourceValue('Image') },
|
|
38
|
+
UnorderedList: { title: this.utilityService.getResourceValue('UnorderedList') },
|
|
39
|
+
OrderedList: { title: this.utilityService.getResourceValue('OrderedList') },
|
|
40
|
+
CodeBlock: { title: this.utilityService.getResourceValue('CodeBlock') },
|
|
41
|
+
ShowPreview: { title: this.utilityService.getResourceValue('ShowPreview') },
|
|
42
|
+
HidePreview: { title: this.utilityService.getResourceValue('HidePreview') },
|
|
43
|
+
Fullscreen: { title: this.utilityService.getResourceValue('Fullscreen') }
|
|
44
|
+
},
|
|
45
|
+
Upload: {
|
|
46
|
+
Drag: this.utilityService.getResourceValue('DragHere'),
|
|
47
|
+
Uploading: this.utilityService.getResourceValue('Uploading')
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
this.locales = {
|
|
51
|
+
en: this.btnsText,
|
|
52
|
+
ar: this.btnsText
|
|
53
|
+
};
|
|
54
|
+
this.resetError = () => {
|
|
55
|
+
this.controlValidationService.removeGlobalError();
|
|
56
|
+
};
|
|
57
|
+
//External Method
|
|
58
|
+
this.removeRequiredValidation = () => {
|
|
59
|
+
this.controlUtility.removeRequiredValidation(this.markdownEditorFormControl, this.validationRules, this.options);
|
|
60
|
+
};
|
|
61
|
+
//External Method
|
|
62
|
+
this.addRequiredValidation = () => {
|
|
63
|
+
this.controlUtility.addRequiredValidation(this.markdownEditorFormControl, this.validationRules, this.options);
|
|
64
|
+
};
|
|
65
|
+
//External Method
|
|
66
|
+
this.removeCustomValidation = (customValidation) => {
|
|
67
|
+
this.controlUtility.removeCustomValidation(this.markdownEditorFormControl, this.validationRules, customValidation);
|
|
68
|
+
};
|
|
69
|
+
//External Method
|
|
70
|
+
this.addCustomValidation = (customValidation) => {
|
|
71
|
+
this.controlUtility.addCustomValidation(this.markdownEditorFormControl, this.validationRules, customValidation);
|
|
72
|
+
};
|
|
73
|
+
//External Method
|
|
74
|
+
this.isValid = () => {
|
|
75
|
+
this.controlUtility.isValid(this.markdownEditorFormControl);
|
|
76
|
+
};
|
|
77
|
+
MarkdownEditorComponent.controlContainerstatic = this.controlContainer;
|
|
78
|
+
this.currentLocale = this.utilityService.getCurrentLanguage();
|
|
79
|
+
}
|
|
80
|
+
loadAllScripts() {
|
|
81
|
+
return this.scriptService.loadScript('assets/ace-builds/ace.js').pipe(switchMap(() => this.scriptService.loadScript('assets/ace-builds/mode-markdown.js')), switchMap(() => this.scriptService.loadScript('assets/ngx-markdown-editor/marked.min.js')), switchMap(() => this.scriptService.loadScript('assets/ngx-markdown-editor/highlight.js/highlight.min.js')));
|
|
82
|
+
}
|
|
83
|
+
ngOnInit() {
|
|
84
|
+
this.loadAllScripts()
|
|
85
|
+
.subscribe({
|
|
86
|
+
next: () => this.showMarkdown = true,
|
|
87
|
+
error: (err) => console.error('Error loading scripts', err)
|
|
88
|
+
});
|
|
89
|
+
this.mode = this.options.isReadonly ? MarkdownMode.preview : MarkdownMode.editor;
|
|
90
|
+
this.editorOptions = {
|
|
91
|
+
hideIcons: this.options.hideIcons,
|
|
92
|
+
showPreviewPanel: this.options.showPreviewPanelOnLoad,
|
|
93
|
+
resizable: false,
|
|
94
|
+
enablePreviewContentClick: this.options.isReadonly,
|
|
95
|
+
markedjsOpt: {
|
|
96
|
+
breaks: true,
|
|
97
|
+
sanitize: true,
|
|
98
|
+
smartypants: true,
|
|
99
|
+
xhtml: true,
|
|
100
|
+
},
|
|
101
|
+
customRender: this.options.customRender,
|
|
102
|
+
placeholder: this.options.placeholder,
|
|
103
|
+
locales: this.locales,
|
|
104
|
+
customIcons: {
|
|
105
|
+
CodeBlock: {
|
|
106
|
+
fontClass: 'fa fa-file-code'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
this.controlValidationService.isCreatedBefor = false;
|
|
111
|
+
this.group.addControl(this.options.name, new FormControl(''));
|
|
112
|
+
this.markdownEditorFormControl = this.group.controls[this.options.name]; // new FormControl('',validationRules);
|
|
113
|
+
this.markdownEditorFormControl.setValue(this.options.value);
|
|
114
|
+
if (!this.options.viewType)
|
|
115
|
+
this.options.viewType = this.globalSettings.viewType;
|
|
116
|
+
if (this.options.customValidation.length > 0) {
|
|
117
|
+
let validations = this.options.customValidation;
|
|
118
|
+
for (let index = 0; index < validations.length; index++) {
|
|
119
|
+
const Validation = validations[index];
|
|
120
|
+
this.validationRules.push(Validation.functionBody);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (this.options.labelKey != null && this.options.labelKey != "")
|
|
124
|
+
this.options.labelValue = this.utilityService.getResourceValue(this.options.labelKey);
|
|
125
|
+
if (this.options.minLength > 0) {
|
|
126
|
+
this.validationRules.push(Validators.minLength(this.options.minLength));
|
|
127
|
+
}
|
|
128
|
+
if (this.options.maxLength > 0) {
|
|
129
|
+
this.validationRules.push(Validators.maxLength(this.options.maxLength));
|
|
130
|
+
}
|
|
131
|
+
if (this.options.isRequired) {
|
|
132
|
+
this.validationRules.push(Validators.required);
|
|
133
|
+
}
|
|
134
|
+
this.markdownEditorFormControl.setValidators(this.validationRules);
|
|
135
|
+
this.markdownEditorFormControl.setAsyncValidators(this.validationRulesasync);
|
|
136
|
+
if (this.options.isDisabled) {
|
|
137
|
+
this.markdownEditorFormControl.disable();
|
|
138
|
+
}
|
|
139
|
+
this.markdownEditorControlHost.ngSubmit.subscribe((value) => {
|
|
140
|
+
this.group.markAllAsTouched();
|
|
141
|
+
this.markAllAsTouched = true;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
uploadImg(evt) {
|
|
145
|
+
if (!evt)
|
|
146
|
+
return;
|
|
147
|
+
const file = evt.target.files[0];
|
|
148
|
+
const reader = new FileReader();
|
|
149
|
+
reader.addEventListener('load', () => {
|
|
150
|
+
this.options.value += ``;
|
|
151
|
+
}, false);
|
|
152
|
+
if (file)
|
|
153
|
+
reader.readAsDataURL(file);
|
|
154
|
+
}
|
|
155
|
+
onPreviewDomChanged(dom) {
|
|
156
|
+
this.OnChange.emit(dom);
|
|
157
|
+
}
|
|
158
|
+
showGlobalError() {
|
|
159
|
+
this.controlUtility.showGlobalError();
|
|
160
|
+
}
|
|
161
|
+
getErrorValidation(ErrorList) {
|
|
162
|
+
if (this.markAllAsTouched && this.group.invalid) {
|
|
163
|
+
this.showGlobalError();
|
|
164
|
+
this.markAllAsTouched = false;
|
|
165
|
+
}
|
|
166
|
+
return this.controlUtility.getErrorValidationMassage(ErrorList, this.group, this.options);
|
|
167
|
+
}
|
|
168
|
+
//Fires on markdown editor has been loaded
|
|
169
|
+
onEditorLoaded(editor) {
|
|
170
|
+
if (this.options.isDisabled) {
|
|
171
|
+
const textarea = editor.renderer.textarea;
|
|
172
|
+
if (textarea && this.options.isDisabled) {
|
|
173
|
+
textarea.setAttribute('disabled', 'true');
|
|
174
|
+
}
|
|
175
|
+
this.hideToolbar = true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//The doUpload method handles file uploads when users add images or other files to the editor.
|
|
179
|
+
//This method should be implemented to manage file uploads to a server or cloud storage and return the result to the editor.
|
|
180
|
+
//fires on drag and drop or copy paste
|
|
181
|
+
//if not set will can't add files or images using this way
|
|
182
|
+
onDragFile(files) {
|
|
183
|
+
const results = [];
|
|
184
|
+
// Function to handle a single file
|
|
185
|
+
const processFile = (file) => {
|
|
186
|
+
return new Promise((resolve, reject) => {
|
|
187
|
+
const reader = new FileReader();
|
|
188
|
+
reader.onload = () => {
|
|
189
|
+
const fileUrl = reader.result;
|
|
190
|
+
const result = {
|
|
191
|
+
name: file.name,
|
|
192
|
+
url: fileUrl,
|
|
193
|
+
isImg: file.type.startsWith('image/')
|
|
194
|
+
};
|
|
195
|
+
resolve(result);
|
|
196
|
+
};
|
|
197
|
+
reader.onerror = (error) => {
|
|
198
|
+
reject(error);
|
|
199
|
+
};
|
|
200
|
+
// Read the file as a data URL
|
|
201
|
+
reader.readAsDataURL(file);
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
// // Iterate over files and process each one
|
|
205
|
+
const processAllFiles = async () => {
|
|
206
|
+
for (const file of files) {
|
|
207
|
+
try {
|
|
208
|
+
const result = await processFile(file);
|
|
209
|
+
results.push(result);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
console.error('Error processing file:', error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return results;
|
|
216
|
+
};
|
|
217
|
+
//Return the promise that resolves when all files are processed
|
|
218
|
+
return processAllFiles();
|
|
219
|
+
}
|
|
220
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: MarkdownEditorComponent, deps: [{ token: i1.UtilityService }, { token: i2.GlobalSettings }, { token: i1.ControlValidationService }, { token: i3.ControlUtility }, { token: i4.FormGroupDirective }, { token: i5.ScriptService }, { token: i4.ControlContainer, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
221
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: MarkdownEditorComponent, selector: "BBSF-MarkdownEditor", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange" }, ngImport: i0, template: "<ng-container *ngIf=\"showMarkdown\">\r\n <div class=\"form-group bbsf-control bbsf-htmleditor\" [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 class=\"bbsf-input-container {{options.extraClasses}}\">\r\n <md-editor id=\"{{options.name}}\" formControlName=\"{{options.name}}\"\r\n (onPreviewDomChanged)=\"onPreviewDomChanged($event)\"\r\n [(ngModel)]=\"options.value\" [mode]=\"mode\" [options]=\"editorOptions\" [attr.required]=\"options.isRequired ? true : null\" [upload]=\"onDragFile\" \r\n [maxlength]=\"options.maxLength\" [height]=\"options.height\" [locale]=\"currentLocale\" (onEditorLoaded)=\"onEditorLoaded($event)\" [hideToolbar]=\"hideToolbar\">\r\n <!-- [ngStyle]=\"{ 'direction': textDirection, 'text-align': textDirection === 'rtl' ? 'right' : 'left' }\" -->\r\n <div custom-btns>\r\n <input #imgInput type=\"file\" style=\"display: none\" (change)=\"uploadImg($event)\" />\r\n <button type=\"button\" class=\"btn btn-sm btn-default\" (click)=\"imgInput.click()\">\r\n {{utilityService.getResourceValue(\"UploadImg\")}}\r\n </button>\r\n </div>\r\n </md-editor>\r\n </div>\r\n\r\n <div class=\"subtext-container\">\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div class=\"bbsf-validation\" *ngIf=\"(markdownEditorFormControl.invalid && markdownEditorFormControl.touched)\">\r\n {{getErrorValidation(markdownEditorFormControl.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 </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8.MarkdownEditorComponent, selector: "md-editor", inputs: ["hideToolbar", "height", "preRender", "postRender", "upload", "locale", "maxlength", "mode", "options"], outputs: ["onEditorLoaded", "onPreviewDomChanged"] }, { kind: "pipe", type: i6.KeyValuePipe, name: "keyvalue" }] }); }
|
|
222
|
+
}
|
|
223
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: MarkdownEditorComponent, decorators: [{
|
|
224
|
+
type: Component,
|
|
225
|
+
args: [{ selector: 'BBSF-MarkdownEditor', template: "<ng-container *ngIf=\"showMarkdown\">\r\n <div class=\"form-group bbsf-control bbsf-htmleditor\" [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 class=\"bbsf-input-container {{options.extraClasses}}\">\r\n <md-editor id=\"{{options.name}}\" formControlName=\"{{options.name}}\"\r\n (onPreviewDomChanged)=\"onPreviewDomChanged($event)\"\r\n [(ngModel)]=\"options.value\" [mode]=\"mode\" [options]=\"editorOptions\" [attr.required]=\"options.isRequired ? true : null\" [upload]=\"onDragFile\" \r\n [maxlength]=\"options.maxLength\" [height]=\"options.height\" [locale]=\"currentLocale\" (onEditorLoaded)=\"onEditorLoaded($event)\" [hideToolbar]=\"hideToolbar\">\r\n <!-- [ngStyle]=\"{ 'direction': textDirection, 'text-align': textDirection === 'rtl' ? 'right' : 'left' }\" -->\r\n <div custom-btns>\r\n <input #imgInput type=\"file\" style=\"display: none\" (change)=\"uploadImg($event)\" />\r\n <button type=\"button\" class=\"btn btn-sm btn-default\" (click)=\"imgInput.click()\">\r\n {{utilityService.getResourceValue(\"UploadImg\")}}\r\n </button>\r\n </div>\r\n </md-editor>\r\n </div>\r\n\r\n <div class=\"subtext-container\">\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription!=null\">{{options.labelDescription}}</div>\r\n <div class=\"bbsf-validation\" *ngIf=\"(markdownEditorFormControl.invalid && markdownEditorFormControl.touched)\">\r\n {{getErrorValidation(markdownEditorFormControl.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 </div>\r\n</ng-container>\r\n" }]
|
|
226
|
+
}], ctorParameters: () => [{ type: i1.UtilityService }, { type: i2.GlobalSettings }, { type: i1.ControlValidationService }, { type: i3.ControlUtility }, { type: i4.FormGroupDirective }, { type: i5.ScriptService }, { type: i4.ControlContainer, decorators: [{
|
|
227
|
+
type: Optional
|
|
228
|
+
}] }], propDecorators: { group: [{
|
|
229
|
+
type: Input
|
|
230
|
+
}], options: [{
|
|
231
|
+
type: Input
|
|
232
|
+
}], OnChange: [{
|
|
233
|
+
type: Output
|
|
234
|
+
}] } });
|
|
235
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24tZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jic2YtY29udHJvbHMvc3JjL2xpYi9jb250cm9scy9NYXJrZG93bkVkaXRvci9tYXJrZG93bi1lZGl0b3IuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYmJzZi1jb250cm9scy9zcmMvbGliL2NvbnRyb2xzL01hcmtkb3duRWRpdG9yL21hcmtkb3duLWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUNoSCxPQUFPLEVBQXFDLFdBQVcsRUFBaUMsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFLM0gsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBSTNELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7Ozs7QUFNakMsTUFBTSxPQUFPLHVCQUF1QjthQUkzQiwyQkFBc0IsR0FBRyxJQUFJLEFBQVAsQ0FBUTtJQWtDckMsWUFBbUIsY0FBNkIsRUFBUyxjQUE4QixFQUM3RSx3QkFBa0QsRUFBUyxjQUE4QixFQUMxRix5QkFBNkMsRUFBUyxhQUE0QixFQUNyRSxnQkFBa0M7UUFIckMsbUJBQWMsR0FBZCxjQUFjLENBQWU7UUFBUyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDN0UsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUFTLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUMxRiw4QkFBeUIsR0FBekIseUJBQXlCLENBQW9CO1FBQVMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDckUscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQXRDOUMsYUFB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QztpQkFDdEI7Z0JBQUMsT0FBTyxLQUFLLEVBQUU7b0JBQ2QsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLENBQUMsQ0FBQztpQkFDaEQ7YUFDRjtZQUNELE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUMsQ0FBQztRQUVGLCtEQUErRDtRQUMvRCxPQUFPLGVBQWUsRUFBRSxDQUFDO0lBQzNCLENBQUM7OEdBNU9VLHVCQUF1QjtrR0FBdkIsdUJBQXVCLDhJQ2hCcEMsNnNFQW9DQTs7MkZEcEJhLHVCQUF1QjtrQkFKbkMsU0FBUzsrQkFDRSxxQkFBcUI7OzBCQTRDNUIsUUFBUTt5Q0F4Q0YsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDSSxRQUFRO3NCQUFqQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIENvbnRyb2xDb250YWluZXIsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIEZvcm1Hcm91cERpcmVjdGl2ZSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgTWRFZGl0b3JPcHRpb24gfSBmcm9tIFwibmd4LW1hcmtkb3duLWVkaXRvclwiO1xyXG5pbXBvcnQgeyBNYXJrZG93bkVkaXRvck9wdGlvbnMgfSBmcm9tICcuLi8uLi9TaGFyZWQvTW9kZWxzL01hcmtkb3duRWRpdG9yT3B0aW9ucyc7XHJcbmltcG9ydCB7IENvbnRyb2xWYWxpZGF0aW9uU2VydmljZSwgVXRpbGl0eVNlcnZpY2UgfSBmcm9tICdAYm5zaWdodHMvYmJzZi11dGlsaXRpZXMnO1xyXG5pbXBvcnQgeyBNZEVkaXRvckxvY2FsZU9wdGlvbnMgfSBmcm9tICduZ3gtbWFya2Rvd24tZWRpdG9yL2xpYi9tZC1lZGl0b3IudHlwZXMnO1xyXG5pbXBvcnQgeyBNYXJrZG93bk1vZGUgfSBmcm9tICcuLi8uLi9TaGFyZWQvRW51bXMvTWFya2Rvd24nO1xyXG5pbXBvcnQgeyBHbG9iYWxTZXR0aW5ncyB9IGZyb20gJy4uLy4uL1NoYXJlZC9zZXJ2aWNlcy9HbG9iYWxTZXR0aW5ncy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29udHJvbFV0aWxpdHkgfSBmcm9tICcuLi8uLi9TaGFyZWQvc2VydmljZXMvQ29udHJvbFV0aWxpdHknO1xyXG5pbXBvcnQgeyBTY3JpcHRTZXJ2aWNlIH0gZnJvbSAnbmd4LXNjcmlwdC1sb2FkZXInO1xyXG5pbXBvcnQgeyBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnQkJTRi1NYXJrZG93bkVkaXRvcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL21hcmtkb3duLWVkaXRvci5jb21wb25lbnQuaHRtbCdcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hcmtkb3duRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICBASW5wdXQoKSBncm91cDogRm9ybUdyb3VwO1xyXG4gIEBJbnB1dCgpIG9wdGlvbnM6IE1hcmtkb3duRWRpdG9yT3B0aW9ucztcclxuICBAT3V0cHV0KCkgT25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgc3RhdGljIGNvbnRyb2xDb250YWluZXJzdGF0aWMgPSBudWxsO1xyXG4gIG1hcmtkb3duRWRpdG9yRm9ybUNvbnRyb2w6IEFic3RyYWN0Q29udHJvbDtcclxuICBlZGl0b3JPcHRpb25zOiBNZEVkaXRvck9wdGlvbjtcclxuICBtb2RlOiBzdHJpbmc7XHJcbiAgaGlkZVRvb2xiYXI6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBjdXJyZW50TG9jYWxlOiBzdHJpbmc7XHJcbiAgdmFsaWRhdGlvblJ1bGVzID0gW107XHJcbiAgdmFsaWRhdGlvblJ1bGVzYXN5bmMgPSBbXTtcclxuICBtYXJrQWxsQXNUb3VjaGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgc2hvd01hcmtkb3duOmJvb2xlYW49ZmFsc2U7XHJcbiAgYnRuc1RleHQgPSB7XHJcbiAgICBCdXR0b25zOiB7XHJcbiAgICAgIEJvbGQ6IHsgdGl0bGU6IHRoaXMudXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnQm9sZCcpIH0sXHJcbiAgICAgIEl0YWxpYzogeyB0aXRsZTogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdJdGFsaWMnKSB9LFxyXG4gICAgICBIZWFkaW5nOiB7IHRpdGxlOiB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0hlYWRpbmcnKSB9LFxyXG4gICAgICBSZWZlcmVuY2U6IHsgdGl0bGU6IHRoaXMudXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnUmVmZXJlbmNlJykgfSxcclxuICAgICAgTGluazogeyB0aXRsZTogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdMaW5rJykgfSxcclxuICAgICAgSW1hZ2U6IHsgdGl0bGU6IHRoaXMudXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSgnSW1hZ2UnKSB9LFxyXG4gICAgICBVbm9yZGVyZWRMaXN0OiB7IHRpdGxlOiB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ1Vub3JkZXJlZExpc3QnKSB9LFxyXG4gICAgICBPcmRlcmVkTGlzdDogeyB0aXRsZTogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdPcmRlcmVkTGlzdCcpIH0sXHJcbiAgICAgIENvZGVCbG9jazogeyB0aXRsZTogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdDb2RlQmxvY2snKSB9LFxyXG4gICAgICBTaG93UHJldmlldzogeyB0aXRsZTogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdTaG93UHJldmlldycpIH0sXHJcbiAgICAgIEhpZGVQcmV2aWV3OiB7IHRpdGxlOiB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0hpZGVQcmV2aWV3JykgfSxcclxuICAgICAgRnVsbHNjcmVlbjogeyB0aXRsZTogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdGdWxsc2NyZWVuJykgfVxyXG4gICAgfSxcclxuICAgIFVwbG9hZDoge1xyXG4gICAgICBEcmFnOiB0aGlzLnV0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoJ0RyYWdIZXJlJyksXHJcbiAgICAgIFVwbG9hZGluZzogdGhpcy51dGlsaXR5U2VydmljZS5nZXRSZXNvdXJjZVZhbHVlKCdVcGxvYWRpbmcnKVxyXG4gICAgfVxyXG4gIH1cclxuICBsb2NhbGVzOiBNZEVkaXRvckxvY2FsZU9wdGlvbnMgPSB7XHJcbiAgICBlbjogdGhpcy5idG5zVGV4dCxcclxuICAgIGFyOiB0aGlzLmJ0bnNUZXh0XHJcbiAgfVxyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyB1dGlsaXR5U2VydmljZTpVdGlsaXR5U2VydmljZSxwcml2YXRlIGdsb2JhbFNldHRpbmdzOiBHbG9iYWxTZXR0aW5ncyxcclxuICAgIHByaXZhdGUgY29udHJvbFZhbGlkYXRpb25TZXJ2aWNlOiBDb250cm9sVmFsaWRhdGlvblNlcnZpY2UscHJpdmF0ZSBjb250cm9sVXRpbGl0eTogQ29udHJvbFV0aWxpdHksXHJcbiAgICBwdWJsaWMgbWFya2Rvd25FZGl0b3JDb250cm9sSG9zdDogRm9ybUdyb3VwRGlyZWN0aXZlLHByaXZhdGUgc2NyaXB0U2VydmljZTogU2NyaXB0U2VydmljZSxcclxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgY29udHJvbENvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lcil7XHJcbiAgICBNYXJrZG93bkVkaXRvckNvbXBvbmVudC5jb250cm9sQ29udGFpbmVyc3RhdGljID0gdGhpcy5jb250cm9sQ29udGFpbmVyO1xyXG4gICAgdGhpcy5jdXJyZW50TG9jYWxlID0gdGhpcy51dGlsaXR5U2VydmljZS5nZXRDdXJyZW50TGFuZ3VhZ2UoKTtcclxuICAgIH1cclxuICAgXHJcbiAgICBwcml2YXRlIGxvYWRBbGxTY3JpcHRzKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5zY3JpcHRTZXJ2aWNlLmxvYWRTY3JpcHQoJ2Fzc2V0cy9hY2UtYnVpbGRzL2FjZS5qcycpLnBpcGUoXHJcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuc2NyaXB0U2VydmljZS5sb2FkU2NyaXB0KCdhc3NldHMvYWNlLWJ1aWxkcy9tb2RlLW1hcmtkb3duLmpzJykpLFxyXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnNjcmlwdFNlcnZpY2UubG9hZFNjcmlwdCgnYXNzZXRzL25neC1tYXJrZG93bi1lZGl0b3IvbWFya2VkLm1pbi5qcycpKSxcclxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5zY3JpcHRTZXJ2aWNlLmxvYWRTY3JpcHQoJ2Fzc2V0cy9uZ3gtbWFya2Rvd24tZWRpdG9yL2hpZ2hsaWdodC5qcy9oaWdobGlnaHQubWluLmpzJykpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmxvYWRBbGxTY3JpcHRzKClcclxuICAgICAgLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6ICgpID0+IHRoaXMuc2hvd01hcmtkb3duID0gdHJ1ZSxcclxuICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGxvYWRpbmcgc2NyaXB0cycsIGVycilcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMubW9kZT10aGlzLm9wdGlvbnMuaXNSZWFkb25seT9NYXJrZG93bk1vZGUucHJldmlldzogTWFya2Rvd25Nb2RlLmVkaXRvcjtcclxuICAgIHRoaXMuZWRpdG9yT3B0aW9ucyA9IHtcclxuICAgICAgaGlkZUljb25zOiB0aGlzLm9wdGlvbnMuaGlkZUljb25zLFxyXG4gICAgICBzaG93UHJldmlld1BhbmVsOiB0aGlzLm9wdGlvbnMuc2hvd1ByZXZpZXdQYW5lbE9uTG9hZCxcclxuICAgICAgcmVzaXphYmxlOiBmYWxzZSxcclxuICAgICAgZW5hYmxlUHJldmlld0NvbnRlbnRDbGljazogdGhpcy5vcHRpb25zLmlzUmVhZG9ubHksLy8gQWxsb3cgdXNlciBmaXJlIHRoZSBjbGljayBldmVudCBvbiB0aGUgcHJldmlldyBwYW5lbCwgbGlrZSBocmVmIGV0Yy5cclxuICAgICAgbWFya2VkanNPcHQ6IHtcclxuICAgICAgICBicmVha3M6IHRydWUsXHJcbiAgICAgICAgc2FuaXRpemU6IHRydWUsXHJcbiAgICAgICAgc21hcnR5cGFudHM6IHRydWUsXHJcbiAgICAgICAgeGh0bWw6IHRydWUsXHJcbiAgICAgIH0sXHJcbiAgICAgIGN1c3RvbVJlbmRlcjogdGhpcy5vcHRpb25zLmN1c3RvbVJlbmRlcixcclxuICAgICAgcGxhY2Vob2xkZXI6IHRoaXMub3B0aW9ucy5wbGFjZWhvbGRlcixcclxuICAgICAgbG9jYWxlczogdGhpcy5sb2NhbGVzLFxyXG4gICAgICBjdXN0b21JY29uczoge1xyXG4gICAgICAgIENvZGVCbG9jazoge1xyXG4gICAgICAgICAgZm9udENsYXNzOiAnZmEgZmEtZmlsZS1jb2RlJ1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5jb250cm9sVmFsaWRhdGlvblNlcnZpY2UuaXNDcmVhdGVkQmVmb3IgPSBmYWxzZVxyXG5cclxuICAgIHRoaXMuZ3JvdXAuYWRkQ29udHJvbCh0aGlzLm9wdGlvbnMubmFtZSwgbmV3IEZvcm1Db250cm9sKCcnKSk7XHJcbiAgICB0aGlzLm1hcmtkb3duRWRpdG9yRm9ybUNvbnRyb2wgPSB0aGlzLmdyb3VwLmNvbnRyb2xzW3RoaXMub3B0aW9ucy5uYW1lXTsgLy8gIG5ldyBGb3JtQ29udHJvbCgnJyx2YWxpZGF0aW9uUnVsZXMpO1xyXG4gICAgdGhpcy5tYXJrZG93bkVkaXRvckZvcm1Db250cm9sLnNldFZhbHVlKHRoaXMub3B0aW9ucy52YWx1ZSk7XHJcblxyXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMudmlld1R5cGUpXHJcbiAgICAgIHRoaXMub3B0aW9ucy52aWV3VHlwZSA9IHRoaXMuZ2xvYmFsU2V0dGluZ3Mudmlld1R5cGU7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jdXN0b21WYWxpZGF0aW9uLmxlbmd0aCA+IDApIHtcclxuICAgICAgbGV0IHZhbGlkYXRpb25zID0gdGhpcy5vcHRpb25zLmN1c3RvbVZhbGlkYXRpb25cclxuICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHZhbGlkYXRpb25zLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgIGNvbnN0IFZhbGlkYXRpb24gPSB2YWxpZGF0aW9uc1tpbmRleF07XHJcbiAgICAgICAgdGhpcy52YWxpZGF0aW9uUnVsZXMucHVzaChWYWxpZGF0aW9uLmZ1bmN0aW9uQm9keSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5sYWJlbEtleSAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5sYWJlbEtleSAhPSBcIlwiKVxyXG4gICAgICB0aGlzLm9wdGlvbnMubGFiZWxWYWx1ZSA9IHRoaXMudXRpbGl0eVNlcnZpY2UuZ2V0UmVzb3VyY2VWYWx1ZSh0aGlzLm9wdGlvbnMubGFiZWxLZXkpO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMubWluTGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLnZhbGlkYXRpb25SdWxlcy5wdXNoKFZhbGlkYXRvcnMubWluTGVuZ3RoKHRoaXMub3B0aW9ucy5taW5MZW5ndGgpKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLm9wdGlvbnMubWF4TGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLnZhbGlkYXRpb25SdWxlcy5wdXNoKFZhbGlkYXRvcnMubWF4TGVuZ3RoKHRoaXMub3B0aW9ucy5tYXhMZW5ndGgpKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNSZXF1aXJlZCkge1xyXG4gICAgICB0aGlzLnZhbGlkYXRpb25SdWxlcy5wdXNoKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5tYXJrZG93bkVkaXRvckZvcm1Db250cm9sLnNldFZhbGlkYXRvcnModGhpcy52YWxpZGF0aW9uUnVsZXMpO1xyXG4gICAgdGhpcy5tYXJrZG93bkVkaXRvckZvcm1Db250cm9sLnNldEFzeW5jVmFsaWRhdG9ycyh0aGlzLnZhbGlkYXRpb25SdWxlc2FzeW5jKTtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNEaXNhYmxlZCkge1xyXG4gICAgICB0aGlzLm1hcmtkb3duRWRpdG9yRm9ybUNvbnRyb2wuZGlzYWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubWFya2Rvd25FZGl0b3JDb250cm9sSG9zdC5uZ1N1Ym1pdC5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XHJcbiAgICAgIHRoaXMuZ3JvdXAubWFya0FsbEFzVG91Y2hlZCgpXHJcbiAgICAgIHRoaXMubWFya0FsbEFzVG91Y2hlZCA9IHRydWVcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICB1cGxvYWRJbWcoZXZ0OiBhbnkpIHtcclxuICAgIGlmICghZXZ0KSByZXR1cm47XHJcbiAgICBjb25zdCBmaWxlID0gZXZ0LnRhcmdldC5maWxlc1swXTtcclxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICByZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgJ2xvYWQnLFxyXG4gICAgICAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zLnZhbHVlICs9IGAhW10oJHtyZWFkZXIucmVzdWx0fSlgO1xyXG4gICAgICB9LFxyXG4gICAgICBmYWxzZVxyXG4gICAgKTtcclxuICAgIGlmIChmaWxlKSByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICB9XHJcbiAgb25QcmV2aWV3RG9tQ2hhbmdlZChkb206IGFueSkge1xyXG4gICAgdGhpcy5PbkNoYW5nZS5lbWl0KGRvbSlcclxuICB9XHJcbiAgcmVzZXRFcnJvciA9ICgpID0+IHtcclxuICAgIHRoaXMuY29udHJvbFZhbGlkYXRpb25TZXJ2aWNlLnJlbW92ZUdsb2JhbEVycm9yKCk7XHJcbiAgfVxyXG4gIHNob3dHbG9iYWxFcnJvcigpIHtcclxuICAgIHRoaXMuY29udHJvbFV0aWxpdHkuc2hvd0dsb2JhbEVycm9yKClcclxuICB9XHJcbiAgZ2V0RXJyb3JWYWxpZGF0aW9uKEVycm9yTGlzdCkge1xyXG4gICAgaWYgKHRoaXMubWFya0FsbEFzVG91Y2hlZCAmJiB0aGlzLmdyb3VwLmludmFsaWQpIHtcclxuICAgICAgdGhpcy5zaG93R2xvYmFsRXJyb3IoKVxyXG4gICAgICB0aGlzLm1hcmtBbGxBc1RvdWNoZWQgPSBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmNvbnRyb2xVdGlsaXR5LmdldEVycm9yVmFsaWRhdGlvbk1hc3NhZ2UoRXJyb3JMaXN0LCB0aGlzLmdyb3VwLCB0aGlzLm9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuXHJcbiAgcmVtb3ZlUmVxdWlyZWRWYWxpZGF0aW9uID0gKCkgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5yZW1vdmVSZXF1aXJlZFZhbGlkYXRpb24odGhpcy5tYXJrZG93bkVkaXRvckZvcm1Db250cm9sLCB0aGlzLnZhbGlkYXRpb25SdWxlcywgdGhpcy5vcHRpb25zKVxyXG4gIH1cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG5cclxuICBhZGRSZXF1aXJlZFZhbGlkYXRpb24gPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmFkZFJlcXVpcmVkVmFsaWRhdGlvbih0aGlzLm1hcmtkb3duRWRpdG9yRm9ybUNvbnRyb2wsIHRoaXMudmFsaWRhdGlvblJ1bGVzLCB0aGlzLm9wdGlvbnMpXHJcbiAgfVxyXG5cclxuXHJcbiAgLy9FeHRlcm5hbCBNZXRob2RcclxuICByZW1vdmVDdXN0b21WYWxpZGF0aW9uID0gKGN1c3RvbVZhbGlkYXRpb24pID0+IHtcclxuICAgIHRoaXMuY29udHJvbFV0aWxpdHkucmVtb3ZlQ3VzdG9tVmFsaWRhdGlvbih0aGlzLm1hcmtkb3duRWRpdG9yRm9ybUNvbnRyb2wsIHRoaXMudmFsaWRhdGlvblJ1bGVzLCBjdXN0b21WYWxpZGF0aW9uKVxyXG4gIH1cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIGFkZEN1c3RvbVZhbGlkYXRpb24gPSAoY3VzdG9tVmFsaWRhdGlvbikgPT4ge1xyXG4gICAgdGhpcy5jb250cm9sVXRpbGl0eS5hZGRDdXN0b21WYWxpZGF0aW9uKHRoaXMubWFya2Rvd25FZGl0b3JGb3JtQ29udHJvbCwgdGhpcy52YWxpZGF0aW9uUnVsZXMsIGN1c3RvbVZhbGlkYXRpb24pXHJcbiAgfVxyXG5cclxuICAvL0V4dGVybmFsIE1ldGhvZFxyXG4gIGlzVmFsaWQgPSAoKSA9PiB7XHJcbiAgICB0aGlzLmNvbnRyb2xVdGlsaXR5LmlzVmFsaWQodGhpcy5tYXJrZG93bkVkaXRvckZvcm1Db250cm9sKVxyXG4gIH1cclxuICAvL0ZpcmVzIG9uIG1hcmtkb3duIGVkaXRvciBoYXMgYmVlbiBsb2FkZWRcclxuICBvbkVkaXRvckxvYWRlZChlZGl0b3I6IGFueSkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pc0Rpc2FibGVkKSB7XHJcbiAgICAgIGNvbnN0IHRleHRhcmVhID0gZWRpdG9yLnJlbmRlcmVyLnRleHRhcmVhO1xyXG4gICAgICBpZiAodGV4dGFyZWEgJiYgdGhpcy5vcHRpb25zLmlzRGlzYWJsZWQpIHtcclxuICAgICAgICB0ZXh0YXJlYS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgJ3RydWUnKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmhpZGVUb29sYmFyID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vVGhlIGRvVXBsb2FkIG1ldGhvZCBoYW5kbGVzIGZpbGUgdXBsb2FkcyB3aGVuIHVzZXJzIGFkZCBpbWFnZXMgb3Igb3RoZXIgZmlsZXMgdG8gdGhlIGVkaXRvci5cclxuICAvL1RoaXMgbWV0aG9kIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB0byBtYW5hZ2UgZmlsZSB1cGxvYWRzIHRvIGEgc2VydmVyIG9yIGNsb3VkIHN0b3JhZ2UgYW5kIHJldHVybiB0aGUgcmVzdWx0IHRvIHRoZSBlZGl0b3IuXHJcbiAgLy9maXJlcyBvbiBkcmFnIGFuZCBkcm9wIG9yIGNvcHkgcGFzdGVcclxuICAvL2lmIG5vdCBzZXQgd2lsbCBjYW4ndCBhZGQgZmlsZXMgb3IgaW1hZ2VzIHVzaW5nIHRoaXMgd2F5XHJcbiAgb25EcmFnRmlsZShmaWxlczogQXJyYXk8RmlsZT4pOiBQcm9taXNlPEFycmF5PGFueT4+IHtcclxuICAgIGNvbnN0IHJlc3VsdHM6IEFycmF5PGFueT4gPSBbXTtcclxuXHJcbiAgICAvLyBGdW5jdGlvbiB0byBoYW5kbGUgYSBzaW5nbGUgZmlsZVxyXG4gICAgY29uc3QgcHJvY2Vzc0ZpbGUgPSAoZmlsZTogRmlsZSkgPT4ge1xyXG4gICAgICByZXR1cm4gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuXHJcbiAgICAgICAgcmVhZGVyLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGZpbGVVcmwgPSByZWFkZXIucmVzdWx0IGFzIHN0cmluZztcclxuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHtcclxuICAgICAgICAgICAgbmFtZTogZmlsZS5uYW1lLFxyXG4gICAgICAgICAgICB1cmw6IGZpbGVVcmwsXHJcbiAgICAgICAgICAgIGlzSW1nOiBmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJylcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmVhZGVyLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVhZCB0aGUgZmlsZSBhcyBhIGRhdGEgVVJMXHJcbiAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyAgLy8gSXRlcmF0ZSBvdmVyIGZpbGVzIGFuZCBwcm9jZXNzIGVhY2ggb25lXHJcbiAgICBjb25zdCBwcm9jZXNzQWxsRmlsZXMgPSBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm9jZXNzRmlsZShmaWxlKTtcclxuICAgICAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBwcm9jZXNzaW5nIGZpbGU6JywgZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcmVzdWx0cztcclxuICAgIH07XHJcblxyXG4gICAgLy9SZXR1cm4gdGhlIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBmaWxlcyBhcmUgcHJvY2Vzc2VkXHJcbiAgICByZXR1cm4gcHJvY2Vzc0FsbEZpbGVzKCk7XHJcbiAgfVxyXG5cclxuXHJcbn1cclxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3dNYXJrZG93blwiPlxyXG4gIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGJic2YtY29udHJvbCBiYnNmLWh0bWxlZGl0b3JcIiBbZm9ybUdyb3VwXT1cImdyb3VwXCI+XHJcbiAgICA8ZGl2IFtuZ0NsYXNzXT1cIihvcHRpb25zLnZpZXdUeXBlPT0xKT8nYmJzZi12ZXJ0aWNhbCc6J2Jic2YtaG9yaXpvbnRhbCdcIj5cclxuICAgICAgPCEtLWxhYmVsLS0+XHJcbiAgICAgIDxsYWJlbCAqbmdJZj1cIiFvcHRpb25zLmhpZGVMYWJlbFwiIGNsYXNzPVwiYmJzZi1sYWJlbCB7e29wdGlvbnMubGFiZWxFeHRyYUNsYXNzZXN9fVwiPlxyXG4gICAgICAgIHt7b3B0aW9ucy5sYWJlbFZhbHVlfX1cclxuICAgICAgICA8IS0tQXN0ZXJpc2stLT5cclxuICAgICAgICA8c3BhbiAqbmdJZj1cIigob3B0aW9ucy5zaG93QXN0ZXJpc2smJm9wdGlvbnMuaXNSZXF1aXJlZCl8fChvcHRpb25zLmlzUmVxdWlyZWQpKSYmIW9wdGlvbnMuaXNSZWFkb25seVwiXHJcbiAgICAgICAgICBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj5cclxuICAgICAgPC9sYWJlbD5cclxuICAgICAgPGRpdiAgY2xhc3M9XCJiYnNmLWlucHV0LWNvbnRhaW5lciB7e29wdGlvbnMuZXh0cmFDbGFzc2VzfX1cIj5cclxuICAgICAgICAgIDxtZC1lZGl0b3IgICBpZD1cInt7b3B0aW9ucy5uYW1lfX1cIiBmb3JtQ29udHJvbE5hbWU9XCJ7e29wdGlvbnMubmFtZX19XCJcclxuICAgICAgICAgKG9uUHJldmlld0RvbUNoYW5nZWQpPVwib25QcmV2aWV3RG9tQ2hhbmdlZCgkZXZlbnQpXCJcclxuICAgICAgICAgWyhuZ01vZGVsKV09XCJvcHRpb25zLnZhbHVlXCIgW21vZGVdPVwibW9kZVwiIFtvcHRpb25zXT1cImVkaXRvck9wdGlvbnNcIiAgW2F0dHIucmVxdWlyZWRdPVwib3B0aW9ucy5pc1JlcXVpcmVkID8gdHJ1ZSA6IG51bGxcIiBbdXBsb2FkXT1cIm9uRHJhZ0ZpbGVcIiBcclxuICAgICAgICAgIFttYXhsZW5ndGhdPVwib3B0aW9ucy5tYXhMZW5ndGhcIiBbaGVpZ2h0XT1cIm9wdGlvbnMuaGVpZ2h0XCIgIFtsb2NhbGVdPVwiY3VycmVudExvY2FsZVwiICAob25FZGl0b3JMb2FkZWQpPVwib25FZGl0b3JMb2FkZWQoJGV2ZW50KVwiIFtoaWRlVG9vbGJhcl09XCJoaWRlVG9vbGJhclwiPlxyXG4gICAgICAgICAgIDwhLS0gW25nU3R5bGVdPVwieyAnZGlyZWN0aW9uJzogdGV4dERpcmVjdGlvbiwgJ3RleHQtYWxpZ24nOiB0ZXh0RGlyZWN0aW9uID09PSAncnRsJyA/ICdyaWdodCcgOiAnbGVmdCcgfVwiIC0tPlxyXG4gICAgICAgICAgIDxkaXYgY3VzdG9tLWJ0bnM+XHJcbiAgICAgICAgICAgIDxpbnB1dCAjaW1nSW5wdXQgdHlwZT1cImZpbGVcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIiAoY2hhbmdlKT1cInVwbG9hZEltZygkZXZlbnQpXCIgLz5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1kZWZhdWx0XCIgKGNsaWNrKT1cImltZ0lucHV0LmNsaWNrKClcIj5cclxuICAgICAgICAgICAgICB7e3V0aWxpdHlTZXJ2aWNlLmdldFJlc291cmNlVmFsdWUoXCJVcGxvYWRJbWdcIil9fVxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvbWQtZWRpdG9yPlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJzdWJ0ZXh0LWNvbnRhaW5lclwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLWNvbnRyb2wtZGVzY1wiICpuZ0lmPVwib3B0aW9ucy5sYWJlbERlc2NyaXB0aW9uIT1udWxsXCI+e3tvcHRpb25zLmxhYmVsRGVzY3JpcHRpb259fTwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJiYnNmLXZhbGlkYXRpb25cIiAqbmdJZj1cIihtYXJrZG93bkVkaXRvckZvcm1Db250cm9sLmludmFsaWQgJiYgbWFya2Rvd25FZGl0b3JGb3JtQ29udHJvbC50b3VjaGVkKVwiPlxyXG4gICAgICAgICAge3tnZXRFcnJvclZhbGlkYXRpb24obWFya2Rvd25FZGl0b3JGb3JtQ29udHJvbC5lcnJvcnN8a2V5dmFsdWUpfX1cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgKm5nSWY9XCIoZ3JvdXAudmFsaWQmJmdyb3VwLmRpcnR5JiZncm91cC50b3VjaGVkICl8fChncm91cC51bnRvdWNoZWQmJmdyb3VwLmludmFsaWQmJmdyb3VwLmRpcnR5KSBcIj5cclxuICAgICAgICB7e3Jlc2V0RXJyb3IoKX19PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9uZy1jb250YWluZXI+XHJcbiJdfQ==
|