@libs-ui/components-inputs-mention 0.2.10-6.2
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 +3 -0
- package/defines/caret-coords.define.d.ts +5 -0
- package/defines/keyboard.define.d.ts +9 -0
- package/defines/template.define.d.ts +4 -0
- package/defines/utils.define.d.ts +18 -0
- package/esm2022/defines/caret-coords.define.mjs +115 -0
- package/esm2022/defines/keyboard.define.mjs +10 -0
- package/esm2022/defines/template.define.mjs +25 -0
- package/esm2022/defines/utils.define.mjs +280 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/interfaces/mention.interface.mjs +2 -0
- package/esm2022/libs-ui-components-inputs-mention.mjs +5 -0
- package/esm2022/list/list.component.mjs +166 -0
- package/esm2022/mention.directive.mjs +504 -0
- package/fesm2022/libs-ui-components-inputs-mention.mjs +1092 -0
- package/fesm2022/libs-ui-components-inputs-mention.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/interfaces/mention.interface.d.ts +40 -0
- package/list/list.component.d.ts +36 -0
- package/mention.directive.d.ts +48 -0
- package/package.json +25 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, model, signal, viewChild, viewChildren } from "@angular/core";
|
|
2
|
+
import { LibsUiComponentsAvatarComponent } from "@libs-ui/components-avatar";
|
|
3
|
+
import { LibsUiComponentsPopoverComponent } from "@libs-ui/components-popover";
|
|
4
|
+
import { set } from "@libs-ui/utils";
|
|
5
|
+
import { fromEvent, Subject, takeUntil } from "rxjs";
|
|
6
|
+
import { getCaretCoordinates } from "../defines/caret-coords.define";
|
|
7
|
+
import { KEY_ENTER } from "../defines/keyboard.define";
|
|
8
|
+
import { getContentEditableCaretCoords, isInputOrTextAreaElement } from "../defines/utils.define";
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
export class LibsUiComponentsInputsMentionListComponent {
|
|
11
|
+
/* PROPERTY */
|
|
12
|
+
items = signal([]);
|
|
13
|
+
activeIndex = signal(0);
|
|
14
|
+
hidden = signal(false);
|
|
15
|
+
styleOff = signal(false);
|
|
16
|
+
parentHandlerKeyDown = signal(undefined);
|
|
17
|
+
dropUp = signal(false);
|
|
18
|
+
coords = signal({ top: 0, left: 0, bottom: 0 });
|
|
19
|
+
offset = signal(0);
|
|
20
|
+
nativeParentElement = signal(undefined);
|
|
21
|
+
onDestroy = new Subject();
|
|
22
|
+
/* INPUT */
|
|
23
|
+
labelKey = model('label');
|
|
24
|
+
zIndex = model(1000);
|
|
25
|
+
isIframe = model.required();
|
|
26
|
+
defaultAvatar = model();
|
|
27
|
+
/* VIEW CHILD */
|
|
28
|
+
elementEl = viewChild('element');
|
|
29
|
+
itemsEl = viewChildren('item');
|
|
30
|
+
ngOnInit() {
|
|
31
|
+
if (this.isIframe()) {
|
|
32
|
+
this.initEvent(window.parent, 'wheel');
|
|
33
|
+
this.initEvent(window.parent, 'resize');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.initEvent(window, 'wheel');
|
|
37
|
+
this.initEvent(window, 'resize');
|
|
38
|
+
}
|
|
39
|
+
/* FUNCTIONS */
|
|
40
|
+
initEvent(element, eventName) {
|
|
41
|
+
fromEvent(element, eventName).pipe(takeUntil(this.onDestroy)).subscribe((event) => {
|
|
42
|
+
if (eventName === 'resize' || !this.elementEl()?.nativeElement.contains(event.target)) {
|
|
43
|
+
this.handlerListenClose(event);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
handlerListenClose(event) {
|
|
48
|
+
if (event.target !== this.elementEl()?.nativeElement) {
|
|
49
|
+
this.hidden.set(true);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// lots of confusion here between relative coordinates and containers
|
|
53
|
+
position(nativeParentElement, iframe, leftDiv) {
|
|
54
|
+
this.nativeParentElement.set(nativeParentElement);
|
|
55
|
+
if (isInputOrTextAreaElement(nativeParentElement)) {
|
|
56
|
+
// parent elements need to have postition:relative for this to work correctly?
|
|
57
|
+
this.coords.set(getCaretCoordinates(nativeParentElement, nativeParentElement.selectionStart));
|
|
58
|
+
this.coords.update(item => ({
|
|
59
|
+
...item,
|
|
60
|
+
top: nativeParentElement.offsetTop + item.top - nativeParentElement.scrollTop,
|
|
61
|
+
left: nativeParentElement.offsetLeft + item.left - nativeParentElement.scrollLeft + nativeParentElement.getBoundingClientRect().left
|
|
62
|
+
}));
|
|
63
|
+
// getCretCoordinates() for text/input elements needs an additional offset to position the list correctly
|
|
64
|
+
this.offset.set(this.getBlockCursorDimensions(nativeParentElement).height);
|
|
65
|
+
this.positionElement();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (iframe) {
|
|
69
|
+
const context = { iframe: iframe, parent: window.parent.document.body, windowParent: true };
|
|
70
|
+
// const rect = iframe.getBoundingClientRect();
|
|
71
|
+
const caretRelativeToView = getContentEditableCaretCoords(context);
|
|
72
|
+
const doc = document.documentElement;
|
|
73
|
+
const scrollLeft = (window.scrollX || doc.scrollLeft) - (doc.clientLeft || 0);
|
|
74
|
+
this.coords.update(item => ({
|
|
75
|
+
...item,
|
|
76
|
+
left: caretRelativeToView.left - scrollLeft - (leftDiv || 0),
|
|
77
|
+
bottom: window.parent.innerHeight - caretRelativeToView.top + 18
|
|
78
|
+
}));
|
|
79
|
+
if (caretRelativeToView.bottom && caretRelativeToView.bottom !== -1) {
|
|
80
|
+
this.coords.update(item => ({
|
|
81
|
+
...item,
|
|
82
|
+
bottom: caretRelativeToView.bottom
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
this.positionElement();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const doc = document.documentElement;
|
|
89
|
+
const scrollLeft = (window.scrollX || doc.scrollLeft) - (doc.clientLeft || 0);
|
|
90
|
+
const scrollTop = (window.scrollX || doc.scrollTop) - (doc.clientTop || 0);
|
|
91
|
+
// bounding rectangles are relative to view, offsets are relative to container?
|
|
92
|
+
const caretRelativeToView = getContentEditableCaretCoords({ iframe, parent: null });
|
|
93
|
+
this.coords.update(item => ({
|
|
94
|
+
...item,
|
|
95
|
+
top: caretRelativeToView.top - scrollTop + 10,
|
|
96
|
+
left: caretRelativeToView.left - scrollLeft - (leftDiv || 0),
|
|
97
|
+
bottom: caretRelativeToView.bottom
|
|
98
|
+
}));
|
|
99
|
+
this.positionElement();
|
|
100
|
+
}
|
|
101
|
+
get ActiveItem() {
|
|
102
|
+
return this.items()[this.activeIndex()];
|
|
103
|
+
}
|
|
104
|
+
handlerClick(event, index) {
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
this.activeIndex.set(index);
|
|
107
|
+
set(event, 'keyCode', KEY_ENTER);
|
|
108
|
+
this.parentHandlerKeyDown()?.(event, this.nativeParentElement());
|
|
109
|
+
}
|
|
110
|
+
activateNextItem() {
|
|
111
|
+
this.activeIndex.set(this.items().length - 1 > this.activeIndex() ? this.activeIndex() + 1 : this.activeIndex());
|
|
112
|
+
this.scrollToActive();
|
|
113
|
+
}
|
|
114
|
+
activatePreviousItem() {
|
|
115
|
+
this.activeIndex.set(this.activeIndex() > 0 ? this.activeIndex() - 1 : this.activeIndex());
|
|
116
|
+
this.scrollToActive();
|
|
117
|
+
}
|
|
118
|
+
positionElement(left = this.coords().left, top = this.coords().top, dropUp = this.dropUp(), bottom = this.coords().bottom || 0) {
|
|
119
|
+
const el = this.elementEl()?.nativeElement;
|
|
120
|
+
top += dropUp ? 0 : this.offset(); // top of list is next line
|
|
121
|
+
el.style.position = "absolute";
|
|
122
|
+
el.style.left = left + 'px';
|
|
123
|
+
el.style.top = bottom !== -1 ? 'auto' : top + 'px';
|
|
124
|
+
el.style.bottom = bottom === -1 ? 'auto' : bottom + 'px';
|
|
125
|
+
this.nativeParentElement()?.normalize();
|
|
126
|
+
}
|
|
127
|
+
getBlockCursorDimensions(nativeParentElement) {
|
|
128
|
+
const parentStyles = window.getComputedStyle(nativeParentElement);
|
|
129
|
+
return {
|
|
130
|
+
height: parseFloat(parentStyles.lineHeight),
|
|
131
|
+
width: parseFloat(parentStyles.fontSize)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
handleActiveItem(event, index) {
|
|
135
|
+
event.stopPropagation();
|
|
136
|
+
this.activeIndex.set(index);
|
|
137
|
+
}
|
|
138
|
+
scrollToActive() {
|
|
139
|
+
if (!this.itemsEl() || (this.itemsEl().length <= this.activeIndex())) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this.itemsEl()[this.activeIndex()].nativeElement.scrollIntoView();
|
|
143
|
+
}
|
|
144
|
+
scrollContent() {
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
const element = this.elementEl();
|
|
147
|
+
if (element && element.nativeElement) {
|
|
148
|
+
element.nativeElement.scrollTop = 0;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
ngOnDestroy() {
|
|
153
|
+
this.onDestroy.next();
|
|
154
|
+
this.onDestroy.complete();
|
|
155
|
+
}
|
|
156
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsMentionListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
157
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsInputsMentionListComponent, isStandalone: true, selector: "libs_ui-components-inputs-mention-list", inputs: { labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, isIframe: { classPropertyName: "isIframe", publicName: "isIframe", isSignal: true, isRequired: true, transformFunction: null }, defaultAvatar: { classPropertyName: "defaultAvatar", publicName: "defaultAvatar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { labelKey: "labelKeyChange", zIndex: "zIndexChange", isIframe: "isIframeChange", defaultAvatar: "defaultAvatarChange" }, viewQueries: [{ propertyName: "elementEl", first: true, predicate: ["element"], descendants: true, isSignal: true }, { propertyName: "itemsEl", predicate: ["item"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #element\n class=\"libs-ui-mention-list\"\n [style.zIndex]=\"zIndex()\"\n [class.hidden]=\"hidden()\">\n @for (item of items(); track item) {\n <div #item\n class=\"libs-ui-mention-list-item\"\n [class.libs-ui-mention-list-item-active]=\"$index === activeIndex()\"\n (mousedown)=\"handlerClick($event, $index)\"\n (mouseenter)=\"handleActiveItem($event, $index)\">\n <div class=\"px-[12px] py-[6px] flex items-center\">\n <libs_ui-components-avatar [size]=\"24\"\n [linkAvatar]=\"item.avatar\"\n [linkAvatarError]=\"defaultAvatar()\"\n [textAvatar]=\"item.name\"\n [idGenColor]=\"item.id\"\n [getLastTextAfterSpace]=\"true\" />\n <libs_ui-components-popover [classInclude]=\"'libs-ui-font-h5r'\"\n [type]=\"'text'\"\n [ignoreShowPopover]=\"true\"\n [config]=\"{width: 250}\">\n <!-- // ta.m \u1EA9n show tooltip v\u00EC ch\u01B0a x\u1EED l\u00FD \u0111c v\u1ECB tr\u00ED -->\n {{ item.name + ' (' + item.username + ')' }}\n </libs_ui-components-popover>\n </div>\n </div>\n }\n</div>\n", styles: [".libs-ui-mention-list{position:absolute;top:-999px;left:-9999px;z-index:1202;float:left;width:315px;padding:4px 0;background-color:#fff;border:solid 1px #e6e8ed;border-radius:5px;max-height:190px;overflow:auto;box-shadow:0 2px 10px 1px #3333331a}.libs-ui-mention-list .libs-ui-mention-list-item{background:#fff;cursor:pointer}.libs-ui-mention-list .libs-ui-mention-list-item:hover,.libs-ui-mention-list .libs-ui-mention-list-item-active{background-color:var(--libs-ui-color-light-3, #f4f8ff)}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsAvatarComponent, selector: "libs_ui-components-avatar", inputs: ["getLastTextAfterSpace", "typeShape", "classInclude", "size", "linkAvatar", "linkAvatarError", "idGenColor", "textAvatar", "classImageInclude"], outputs: ["outAvatarError"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
158
|
+
}
|
|
159
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsMentionListComponent, decorators: [{
|
|
160
|
+
type: Component,
|
|
161
|
+
args: [{ selector: 'libs_ui-components-inputs-mention-list', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
162
|
+
LibsUiComponentsAvatarComponent,
|
|
163
|
+
LibsUiComponentsPopoverComponent
|
|
164
|
+
], template: "<div #element\n class=\"libs-ui-mention-list\"\n [style.zIndex]=\"zIndex()\"\n [class.hidden]=\"hidden()\">\n @for (item of items(); track item) {\n <div #item\n class=\"libs-ui-mention-list-item\"\n [class.libs-ui-mention-list-item-active]=\"$index === activeIndex()\"\n (mousedown)=\"handlerClick($event, $index)\"\n (mouseenter)=\"handleActiveItem($event, $index)\">\n <div class=\"px-[12px] py-[6px] flex items-center\">\n <libs_ui-components-avatar [size]=\"24\"\n [linkAvatar]=\"item.avatar\"\n [linkAvatarError]=\"defaultAvatar()\"\n [textAvatar]=\"item.name\"\n [idGenColor]=\"item.id\"\n [getLastTextAfterSpace]=\"true\" />\n <libs_ui-components-popover [classInclude]=\"'libs-ui-font-h5r'\"\n [type]=\"'text'\"\n [ignoreShowPopover]=\"true\"\n [config]=\"{width: 250}\">\n <!-- // ta.m \u1EA9n show tooltip v\u00EC ch\u01B0a x\u1EED l\u00FD \u0111c v\u1ECB tr\u00ED -->\n {{ item.name + ' (' + item.username + ')' }}\n </libs_ui-components-popover>\n </div>\n </div>\n }\n</div>\n", styles: [".libs-ui-mention-list{position:absolute;top:-999px;left:-9999px;z-index:1202;float:left;width:315px;padding:4px 0;background-color:#fff;border:solid 1px #e6e8ed;border-radius:5px;max-height:190px;overflow:auto;box-shadow:0 2px 10px 1px #3333331a}.libs-ui-mention-list .libs-ui-mention-list-item{background:#fff;cursor:pointer}.libs-ui-mention-list .libs-ui-mention-list-item:hover,.libs-ui-mention-list .libs-ui-mention-list-item-active{background-color:var(--libs-ui-color-light-3, #f4f8ff)}\n"] }]
|
|
165
|
+
}] });
|
|
166
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvaW5wdXRzL21lbnRpb24vc3JjL2xpc3QvbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvaW5wdXRzL21lbnRpb24vc3JjL2xpc3QvbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUksT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0UsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNyRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkQsT0FBTyxFQUFFLDZCQUE2QixFQUFFLHdCQUF3QixFQUFFLE1BQU0seUJBQXlCLENBQUM7O0FBY2xHLE1BQU0sT0FBTywwQ0FBMEM7SUFFckQsY0FBYztJQUNQLEtBQUssR0FBRyxNQUFNLENBQTRDLEVBQUUsQ0FBQyxDQUFDO0lBQzlELFdBQVcsR0FBRyxNQUFNLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFDaEMsTUFBTSxHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUNoQyxRQUFRLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ2xDLG9C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QUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRU8sY0FBYztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3JFLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNwRSxDQUFDO0lBRUQsYUFBYTtRQUNYLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxPQUFPLElBQUksT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUNyQyxPQUFPLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7WUFDdEMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQzt3R0F6S1UsMENBQTBDOzRGQUExQywwQ0FBMEMsdzhCQ3JCdkQsd25DQTRCQSx3aUJEWEksK0JBQStCLDZQQUMvQixnQ0FBZ0M7OzRGQUd2QiwwQ0FBMEM7a0JBWnRELFNBQVM7K0JBRUUsd0NBQXdDLGNBR3RDLElBQUksbUJBQ0MsdUJBQXVCLENBQUMsTUFBTSxXQUN0Qzt3QkFDUCwrQkFBK0I7d0JBQy9CLGdDQUFnQztxQkFDakMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBtb2RlbCwgT25EZXN0cm95LCBPbkluaXQsIHNpZ25hbCwgdmlld0NoaWxkLCB2aWV3Q2hpbGRyZW4gfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0F2YXRhckNvbXBvbmVudCB9IGZyb20gXCJAbGlicy11aS9jb21wb25lbnRzLWF2YXRhclwiO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJDb21wb25lbnQgfSBmcm9tIFwiQGxpYnMtdWkvY29tcG9uZW50cy1wb3BvdmVyXCI7XG5pbXBvcnQgeyBzZXQgfSBmcm9tIFwiQGxpYnMtdWkvdXRpbHNcIjtcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IGdldENhcmV0Q29vcmRpbmF0ZXMgfSBmcm9tIFwiLi4vZGVmaW5lcy9jYXJldC1jb29yZHMuZGVmaW5lXCI7XG5pbXBvcnQgeyBLRVlfRU5URVIgfSBmcm9tIFwiLi4vZGVmaW5lcy9rZXlib2FyZC5kZWZpbmVcIjtcbmltcG9ydCB7IGdldENvbnRlbnRFZGl0YWJsZUNhcmV0Q29vcmRzLCBpc0lucHV0T3JUZXh0QXJlYUVsZW1lbnQgfSBmcm9tIFwiLi4vZGVmaW5lcy91dGlscy5kZWZpbmVcIjtcblxuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbGlic191aS1jb21wb25lbnRzLWlucHV0cy1tZW50aW9uLWxpc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2xpc3QuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtcbiAgICBMaWJzVWlDb21wb25lbnRzQXZhdGFyQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyQ29tcG9uZW50XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c0lucHV0c01lbnRpb25MaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8qIFBST1BFUlRZICovXG4gIHB1YmxpYyBpdGVtcyA9IHNpZ25hbDxBcnJheTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+Pj4oW10pO1xuICBwdWJsaWMgYWN0aXZlSW5kZXggPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHVibGljIGhpZGRlbiA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHB1YmxpYyBzdHlsZU9mZiA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHB1YmxpYyBwYXJlbnRIYW5kbGVyS2V5RG93biA9IHNpZ25hbDwoKGU6IEV2ZW50LCBlbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50IHwgdW5kZWZpbmVkKSA9PiB1bmtub3duKSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBwcm90ZWN0ZWQgZHJvcFVwID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICBwcml2YXRlIGNvb3JkcyA9IHNpZ25hbDx7IHRvcDogbnVtYmVyLCBsZWZ0OiBudW1iZXIsIGJvdHRvbT86IG51bWJlciB9Pih7IHRvcDogMCwgbGVmdDogMCwgYm90dG9tOiAwIH0pO1xuICBwcml2YXRlIG9mZnNldCA9IHNpZ25hbDxudW1iZXI+KDApO1xuICBwcml2YXRlIG5hdGl2ZVBhcmVudEVsZW1lbnQgPSBzaWduYWw8SFRNTElucHV0RWxlbWVudCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qIElOUFVUICovXG4gIGxhYmVsS2V5ID0gbW9kZWw8c3RyaW5nPignbGFiZWwnKTtcbiAgekluZGV4ID0gbW9kZWw8bnVtYmVyPigxMDAwKTtcbiAgaXNJZnJhbWUgPSBtb2RlbC5yZXF1aXJlZDxib29sZWFuPigpO1xuICBkZWZhdWx0QXZhdGFyID0gbW9kZWw8c3RyaW5nPigpO1xuXG4gIC8qIFZJRVcgQ0hJTEQgKi9cbiAgcmVhZG9ubHkgZWxlbWVudEVsID0gdmlld0NoaWxkPEVsZW1lbnRSZWY+KCdlbGVtZW50Jyk7XG4gIHJlYWRvbmx5IGl0ZW1zRWwgPSB2aWV3Q2hpbGRyZW48RWxlbWVudFJlZj4oJ2l0ZW0nKTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAodGhpcy5pc0lmcmFtZSgpKSB7XG4gICAgICB0aGlzLmluaXRFdmVudCh3aW5kb3cucGFyZW50LCAnd2hlZWwnKTtcbiAgICAgIHRoaXMuaW5pdEV2ZW50KHdpbmRvdy5wYXJlbnQsICdyZXNpemUnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pbml0RXZlbnQod2luZG93LCAnd2hlZWwnKTtcbiAgICB0aGlzLmluaXRFdmVudCh3aW5kb3csICdyZXNpemUnKTtcbiAgfVxuXG4gIC8qIEZVTkNUSU9OUyAqL1xuICBwcml2YXRlIGluaXRFdmVudChlbGVtZW50OiBXaW5kb3csIGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgZnJvbUV2ZW50PEV2ZW50PihlbGVtZW50LCBldmVudE5hbWUpLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95KSkuc3Vic2NyaWJlKChldmVudDogRXZlbnQpID0+IHtcbiAgICAgIGlmIChldmVudE5hbWUgPT09ICdyZXNpemUnIHx8ICF0aGlzLmVsZW1lbnRFbCgpPy5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVyTGlzdGVuQ2xvc2UoZXZlbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyTGlzdGVuQ2xvc2UoZXZlbnQ6IEV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnRhcmdldCAhPT0gdGhpcy5lbGVtZW50RWwoKT8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgdGhpcy5oaWRkZW4uc2V0KHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGxvdHMgb2YgY29uZnVzaW9uIGhlcmUgYmV0d2VlbiByZWxhdGl2ZSBjb29yZGluYXRlcyBhbmQgY29udGFpbmVyc1xuICBwb3NpdGlvbihuYXRpdmVQYXJlbnRFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50LCBpZnJhbWU/OiBIVE1MSUZyYW1lRWxlbWVudCwgbGVmdERpdj86IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubmF0aXZlUGFyZW50RWxlbWVudC5zZXQobmF0aXZlUGFyZW50RWxlbWVudCk7XG4gICAgaWYgKGlzSW5wdXRPclRleHRBcmVhRWxlbWVudChuYXRpdmVQYXJlbnRFbGVtZW50KSkge1xuICAgICAgLy8gcGFyZW50IGVsZW1lbnRzIG5lZWQgdG8gaGF2ZSBwb3N0aXRpb246cmVsYXRpdmUgZm9yIHRoaXMgdG8gd29yayBjb3JyZWN0bHk/XG4gICAgICB0aGlzLmNvb3Jkcy5zZXQoZ2V0Q2FyZXRDb29yZGluYXRlcyhuYXRpdmVQYXJlbnRFbGVtZW50LCBuYXRpdmVQYXJlbnRFbGVtZW50LnNlbGVjdGlvblN0YXJ0KSk7XG4gICAgICB0aGlzLmNvb3Jkcy51cGRhdGUoaXRlbSA9PiAoe1xuICAgICAgICAuLi5pdGVtLFxuICAgICAgICB0b3A6IG5hdGl2ZVBhcmVudEVsZW1lbnQub2Zmc2V0VG9wICsgaXRlbS50b3AgLSBuYXRpdmVQYXJlbnRFbGVtZW50LnNjcm9sbFRvcCxcbiAgICAgICAgbGVmdDogbmF0aXZlUGFyZW50RWxlbWVudC5vZmZzZXRMZWZ0ICsgaXRlbS5sZWZ0IC0gbmF0aXZlUGFyZW50RWxlbWVudC5zY3JvbGxMZWZ0ICsgbmF0aXZlUGFyZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0XG4gICAgICB9KSk7XG5cbiAgICAgIC8vIGdldENyZXRDb29yZGluYXRlcygpIGZvciB0ZXh0L2lucHV0IGVsZW1lbnRzIG5lZWRzIGFuIGFkZGl0aW9uYWwgb2Zmc2V0IHRvIHBvc2l0aW9uIHRoZSBsaXN0IGNvcnJlY3RseVxuICAgICAgdGhpcy5vZmZzZXQuc2V0KHRoaXMuZ2V0QmxvY2tDdXJzb3JEaW1lbnNpb25zKG5hdGl2ZVBhcmVudEVsZW1lbnQpLmhlaWdodCk7XG4gICAgICB0aGlzLnBvc2l0aW9uRWxlbWVudCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICBjb25zdCBjb250ZXh0OiB7IGlmcmFtZTogSFRNTElGcmFtZUVsZW1lbnQsIHBhcmVudDogRWxlbWVudCB8IG51bGwsIHdpbmRvd1BhcmVudD86IGJvb2xlYW4gfSA9IHsgaWZyYW1lOiBpZnJhbWUsIHBhcmVudDogd2luZG93LnBhcmVudC5kb2N1bWVudC5ib2R5LCB3aW5kb3dQYXJlbnQ6IHRydWUgfTtcbiAgICAgIC8vIGNvbnN0IHJlY3QgPSBpZnJhbWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBjYXJldFJlbGF0aXZlVG9WaWV3ID0gZ2V0Q29udGVudEVkaXRhYmxlQ2FyZXRDb29yZHMoY29udGV4dCk7XG4gICAgICBjb25zdCBkb2MgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICBjb25zdCBzY3JvbGxMZWZ0ID0gKHdpbmRvdy5zY3JvbGxYIHx8IGRvYy5zY3JvbGxMZWZ0KSAtIChkb2MuY2xpZW50TGVmdCB8fCAwKTtcbiAgICAgIHRoaXMuY29vcmRzLnVwZGF0ZShpdGVtID0+ICh7XG4gICAgICAgIC4uLml0ZW0sXG4gICAgICAgIGxlZnQ6IGNhcmV0UmVsYXRpdmVUb1ZpZXcubGVmdCAtIHNjcm9sbExlZnQgLSAobGVmdERpdiB8fCAwKSxcbiAgICAgICAgYm90dG9tOiB3aW5kb3cucGFyZW50LmlubmVySGVpZ2h0IC0gY2FyZXRSZWxhdGl2ZVRvVmlldy50b3AgKyAxOFxuICAgICAgfSkpO1xuICAgICAgaWYgKGNhcmV0UmVsYXRpdmVUb1ZpZXcuYm90dG9tICYmIGNhcmV0UmVsYXRpdmVUb1ZpZXcuYm90dG9tICE9PSAtMSkge1xuICAgICAgICB0aGlzLmNvb3Jkcy51cGRhdGUoaXRlbSA9PiAoe1xuICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgYm90dG9tOiBjYXJldFJlbGF0aXZlVG9WaWV3LmJvdHRvbVxuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICB0aGlzLnBvc2l0aW9uRWxlbWVudCgpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGRvYyA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICBjb25zdCBzY3JvbGxMZWZ0ID0gKHdpbmRvdy5zY3JvbGxYIHx8IGRvYy5zY3JvbGxMZWZ0KSAtIChkb2MuY2xpZW50TGVmdCB8fCAwKTtcbiAgICBjb25zdCBzY3JvbGxUb3AgPSAod2luZG93LnNjcm9sbFggfHwgZG9jLnNjcm9sbFRvcCkgLSAoZG9jLmNsaWVudFRvcCB8fCAwKTtcbiAgICAvLyBib3VuZGluZyByZWN0YW5nbGVzIGFyZSByZWxhdGl2ZSB0byB2aWV3LCBvZmZzZXRzIGFyZSByZWxhdGl2ZSB0byBjb250YWluZXI/XG4gICAgY29uc3QgY2FyZXRSZWxhdGl2ZVRvVmlldyA9IGdldENvbnRlbnRFZGl0YWJsZUNhcmV0Q29vcmRzKHsgaWZyYW1lLCBwYXJlbnQ6IG51bGwgfSk7XG5cbiAgICB0aGlzLmNvb3Jkcy51cGRhdGUoaXRlbSA9PiAoe1xuICAgICAgLi4uaXRlbSxcbiAgICAgIHRvcDogY2FyZXRSZWxhdGl2ZVRvVmlldy50b3AgLSBzY3JvbGxUb3AgKyAxMCxcbiAgICAgIGxlZnQ6IGNhcmV0UmVsYXRpdmVUb1ZpZXcubGVmdCAtIHNjcm9sbExlZnQgLSAobGVmdERpdiB8fCAwKSxcbiAgICAgIGJvdHRvbTogY2FyZXRSZWxhdGl2ZVRvVmlldy5ib3R0b21cbiAgICB9KSlcbiAgICB0aGlzLnBvc2l0aW9uRWxlbWVudCgpO1xuICB9XG5cbiAgZ2V0IEFjdGl2ZUl0ZW0oKSB7XG4gICAgcmV0dXJuIHRoaXMuaXRlbXMoKVt0aGlzLmFjdGl2ZUluZGV4KCldO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJDbGljayhldmVudDogRXZlbnQsIGluZGV4OiBudW1iZXIpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmFjdGl2ZUluZGV4LnNldChpbmRleCk7XG4gICAgc2V0KGV2ZW50LCAna2V5Q29kZScsIEtFWV9FTlRFUik7XG4gICAgdGhpcy5wYXJlbnRIYW5kbGVyS2V5RG93bigpPy4oZXZlbnQsIHRoaXMubmF0aXZlUGFyZW50RWxlbWVudCgpKTtcbiAgfVxuXG4gIGFjdGl2YXRlTmV4dEl0ZW0oKSB7XG4gICAgdGhpcy5hY3RpdmVJbmRleC5zZXQodGhpcy5pdGVtcygpLmxlbmd0aCAtIDEgPiB0aGlzLmFjdGl2ZUluZGV4KCkgPyB0aGlzLmFjdGl2ZUluZGV4KCkgKyAxIDogdGhpcy5hY3RpdmVJbmRleCgpKTtcbiAgICB0aGlzLnNjcm9sbFRvQWN0aXZlKCk7XG4gIH1cblxuICBhY3RpdmF0ZVByZXZpb3VzSXRlbSgpIHtcbiAgICB0aGlzLmFjdGl2ZUluZGV4LnNldCh0aGlzLmFjdGl2ZUluZGV4KCkgPiAwID8gdGhpcy5hY3RpdmVJbmRleCgpIC0gMSA6IHRoaXMuYWN0aXZlSW5kZXgoKSk7XG4gICAgdGhpcy5zY3JvbGxUb0FjdGl2ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBwb3NpdGlvbkVsZW1lbnQobGVmdDogbnVtYmVyID0gdGhpcy5jb29yZHMoKS5sZWZ0LCB0b3A6IG51bWJlciA9IHRoaXMuY29vcmRzKCkudG9wLCBkcm9wVXA6IGJvb2xlYW4gPSB0aGlzLmRyb3BVcCgpLCBib3R0b206IG51bWJlciA9IHRoaXMuY29vcmRzKCkuYm90dG9tIHx8IDApIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuZWxlbWVudEVsKCk/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICB0b3AgKz0gZHJvcFVwID8gMCA6IHRoaXMub2Zmc2V0KCk7IC8vIHRvcCBvZiBsaXN0IGlzIG5leHQgbGluZVxuICAgIGVsLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgIGVsLnN0eWxlLmxlZnQgPSBsZWZ0ICsgJ3B4JztcbiAgICBlbC5zdHlsZS50b3AgPSBib3R0b20gIT09IC0xID8gJ2F1dG8nIDogdG9wICsgJ3B4JztcbiAgICBlbC5zdHlsZS5ib3R0b20gPSBib3R0b20gPT09IC0xID8gJ2F1dG8nIDogYm90dG9tICsgJ3B4JztcbiAgICB0aGlzLm5hdGl2ZVBhcmVudEVsZW1lbnQoKT8ubm9ybWFsaXplKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEJsb2NrQ3Vyc29yRGltZW5zaW9ucyhuYXRpdmVQYXJlbnRFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50KSB7XG4gICAgY29uc3QgcGFyZW50U3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUobmF0aXZlUGFyZW50RWxlbWVudCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaGVpZ2h0OiBwYXJzZUZsb2F0KHBhcmVudFN0eWxlcy5saW5lSGVpZ2h0KSxcbiAgICAgIHdpZHRoOiBwYXJzZUZsb2F0KHBhcmVudFN0eWxlcy5mb250U2l6ZSlcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZUFjdGl2ZUl0ZW0oZXZlbnQ6IEV2ZW50LCBpbmRleDogbnVtYmVyKSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5hY3RpdmVJbmRleC5zZXQoaW5kZXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzY3JvbGxUb0FjdGl2ZSgpIHtcbiAgICBpZiAoIXRoaXMuaXRlbXNFbCgpIHx8ICh0aGlzLml0ZW1zRWwoKS5sZW5ndGggPD0gdGhpcy5hY3RpdmVJbmRleCgpKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLml0ZW1zRWwoKVt0aGlzLmFjdGl2ZUluZGV4KCldLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgfVxuXG4gIHNjcm9sbENvbnRlbnQoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50RWwoKTtcbiAgICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xuICAgICAgICBlbGVtZW50Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub25EZXN0cm95Lm5leHQoKTtcbiAgICB0aGlzLm9uRGVzdHJveS5jb21wbGV0ZSgpO1xuICB9XG5cbn1cbiIsIjxkaXYgI2VsZW1lbnRcbiAgY2xhc3M9XCJsaWJzLXVpLW1lbnRpb24tbGlzdFwiXG4gIFtzdHlsZS56SW5kZXhdPVwiekluZGV4KClcIlxuICBbY2xhc3MuaGlkZGVuXT1cImhpZGRlbigpXCI+XG4gIEBmb3IgKGl0ZW0gb2YgaXRlbXMoKTsgdHJhY2sgaXRlbSkge1xuICAgIDxkaXYgI2l0ZW1cbiAgICAgIGNsYXNzPVwibGlicy11aS1tZW50aW9uLWxpc3QtaXRlbVwiXG4gICAgICBbY2xhc3MubGlicy11aS1tZW50aW9uLWxpc3QtaXRlbS1hY3RpdmVdPVwiJGluZGV4ID09PSBhY3RpdmVJbmRleCgpXCJcbiAgICAgIChtb3VzZWRvd24pPVwiaGFuZGxlckNsaWNrKCRldmVudCwgJGluZGV4KVwiXG4gICAgICAobW91c2VlbnRlcik9XCJoYW5kbGVBY3RpdmVJdGVtKCRldmVudCwgJGluZGV4KVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInB4LVsxMnB4XSBweS1bNnB4XSBmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWF2YXRhciBbc2l6ZV09XCIyNFwiXG4gICAgICAgICAgW2xpbmtBdmF0YXJdPVwiaXRlbS5hdmF0YXJcIlxuICAgICAgICAgIFtsaW5rQXZhdGFyRXJyb3JdPVwiZGVmYXVsdEF2YXRhcigpXCJcbiAgICAgICAgICBbdGV4dEF2YXRhcl09XCJpdGVtLm5hbWVcIlxuICAgICAgICAgIFtpZEdlbkNvbG9yXT1cIml0ZW0uaWRcIlxuICAgICAgICAgIFtnZXRMYXN0VGV4dEFmdGVyU3BhY2VdPVwidHJ1ZVwiIC8+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbY2xhc3NJbmNsdWRlXT1cIidsaWJzLXVpLWZvbnQtaDVyJ1wiXG4gICAgICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgICAgICBbaWdub3JlU2hvd1BvcG92ZXJdPVwidHJ1ZVwiXG4gICAgICAgICAgW2NvbmZpZ109XCJ7d2lkdGg6IDI1MH1cIj5cbiAgICAgICAgICA8IS0tIC8vIHRhLm0g4bqpbiBzaG93IHRvb2x0aXAgdsOsIGNoxrBhIHjhu60gbMO9IMSRYyB24buLIHRyw60gLS0+XG4gICAgICAgICAge3sgaXRlbS5uYW1lICsgJyAoJyArIGl0ZW0udXNlcm5hbWUgKyAnKScgfX1cbiAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtcG9wb3Zlcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICB9XG48L2Rpdj5cbiJdfQ==
|