@libs-ui/components-inputs-quill2x 0.2.351-0
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/blots-custom/image2x.component.d.ts +6 -0
- package/blots-custom/index.d.ts +2 -0
- package/blots-custom/mention2x.component.d.ts +19 -0
- package/esm2022/blots-custom/image2x.component.mjs +13 -0
- package/esm2022/blots-custom/index.mjs +3 -0
- package/esm2022/blots-custom/mention2x.component.mjs +35 -0
- package/esm2022/index.mjs +4 -0
- package/esm2022/interfaces/quill2x.interface.mjs +2 -0
- package/esm2022/libs-ui-components-inputs-quill2x.mjs +5 -0
- package/esm2022/link/link.component.mjs +52 -0
- package/esm2022/quill2x.component.mjs +921 -0
- package/esm2022/upload-image/upload-image.component.mjs +67 -0
- package/esm2022/utils/data.define.mjs +476 -0
- package/esm2022/utils/functions.define.mjs +590 -0
- package/fesm2022/libs-ui-components-inputs-quill2x.mjs +2141 -0
- package/fesm2022/libs-ui-components-inputs-quill2x.mjs.map +1 -0
- package/index.d.ts +3 -0
- package/interfaces/quill2x.interface.d.ts +79 -0
- package/link/link.component.d.ts +27 -0
- package/package.json +27 -0
- package/quill2x.component.d.ts +162 -0
- package/upload-image/upload-image.component.d.ts +15 -0
- package/utils/data.define.d.ts +25 -0
- package/utils/functions.define.d.ts +30 -0
|
@@ -0,0 +1,921 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { NgStyle, NgTemplateOutlet } from '@angular/common';
|
|
3
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, DestroyRef, effect, inject, input, model, output, signal, untracked, viewChild } from '@angular/core';
|
|
4
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
6
|
+
import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
|
|
7
|
+
import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
|
|
8
|
+
import { LibsUiComponentsEmojiComponent } from '@libs-ui/components-inputs-emoji';
|
|
9
|
+
import { LibsUiComponentsInputsMentionDirective } from '@libs-ui/components-inputs-mention';
|
|
10
|
+
import { LibsUiComponentsInputsValidComponent } from '@libs-ui/components-inputs-valid';
|
|
11
|
+
import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
|
|
12
|
+
import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
|
|
13
|
+
import { LibsUiComponentsScrollOverlayDirective } from '@libs-ui/components-scroll-overlay';
|
|
14
|
+
import { LibsUiComponentsSkeletonComponent } from '@libs-ui/components-skeleton';
|
|
15
|
+
import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
|
|
16
|
+
import { LibsUiNotificationService } from '@libs-ui/services-notification';
|
|
17
|
+
import { ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MAX_LENGTH, ERROR_MESSAGE_MIN_LENGTH, get, getLabelBySizeFile, isNearWhite, isNil, patternUrl, patterProtocolUrl, set, UtilsKeyCodeConstant, xssFilter } from '@libs-ui/utils';
|
|
18
|
+
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
19
|
+
import Quill2x, { Delta } from 'quill2x';
|
|
20
|
+
import { fromEvent, lastValueFrom, merge, timer } from 'rxjs';
|
|
21
|
+
import { LibsUiComponentsInputsQuillLinkComponent } from './link/link.component';
|
|
22
|
+
import { LibsUiComponentsInputsQuillUploadImageComponent } from './upload-image/upload-image.component';
|
|
23
|
+
import { linkDefault, listConfigAlign, listConfigFont, listConfigHeader, listFont, toolBarOptions, uploadImageConfigDefault } from './utils/data.define';
|
|
24
|
+
import { createContextMenuOptionTable, createTableSelector, enableTableSelection, getAllTablesWithSpan, isEmptyQuill2x, getHTMLFromDeltaOfQuill2x, registerQuill2x } from './utils/functions.define';
|
|
25
|
+
import * as i0 from "@angular/core";
|
|
26
|
+
import * as i1 from "@ngx-translate/core";
|
|
27
|
+
export class LibsUiComponentsInputsQuill2xComponent {
|
|
28
|
+
//region Private
|
|
29
|
+
displayEditor = signal(false);
|
|
30
|
+
isPaste = signal(false);
|
|
31
|
+
quill = null;
|
|
32
|
+
addEditLinkComponentRef = signal(undefined);
|
|
33
|
+
uploadImageComponentRef = signal(undefined);
|
|
34
|
+
handlers = signal({
|
|
35
|
+
link: this.handleShowUploadLink.bind(this),
|
|
36
|
+
undo: this.handleUndo.bind(this),
|
|
37
|
+
redo: this.handleRedo.bind(this),
|
|
38
|
+
table: this.handleTable.bind(this),
|
|
39
|
+
image: this.handlerShowUploadImage.bind(this),
|
|
40
|
+
});
|
|
41
|
+
timerSetFontSize = signal(undefined);
|
|
42
|
+
timerCalculatorToolbar = signal(undefined);
|
|
43
|
+
totalRecallCalculatorToolbar = signal(0);
|
|
44
|
+
isCalculatorToolbarSuccess = signal(false);
|
|
45
|
+
showMention = signal(false);
|
|
46
|
+
handlerTextChangeBind = this.handlerTextChange.bind(this);
|
|
47
|
+
handlerSelectionChangeBind = this.handlerSelectionChange.bind(this);
|
|
48
|
+
//endregion
|
|
49
|
+
//region Protected
|
|
50
|
+
borderColor = computed(() => (this.messageError() && this.showErrorBorder() ? ' !border-[var(--libs-ui-color-border-error,#ee2d41)] ' : '!border-[#e5e7eb] '));
|
|
51
|
+
containerClass = computed(() => `quill-container flex flex-col h-full w-full ${get(this.quillCustomConfig(), 'classContainer') || ''}`);
|
|
52
|
+
containerToolbarClass = computed(() => `h-full border-t border-l border-r ${this.ignoreShowBorderErrorToolbar() ? '!border-[#e5e7eb] ' : this.borderColor()}rounded-t-[4px] ${this.readonly() ? ' libs-ui-readonly-background cursor-default pointer-events-none ' : ' '} ${get(this.quillCustomConfig(), 'toolbar.classCustomContainerToolbar') || ''} ${get(this.quillCustomConfig(), 'toolbar.positionFixed') ? ' fixed ' : ' '}`);
|
|
53
|
+
containerEditorClass = computed(() => `${this.displayEditor() ? 'h-full' : 'hidden'} !border ${this.borderColor()} !rounded-b-[4px] ${this.readonly() ? ' libs-ui-readonly-background ' : ' '} ${get(this.quillCustomConfig(), 'editor.classCustomContainerEditor') || ''} ${get(this.quillCustomConfig(), 'toolbar.positionFixed') ? ' rounded-t-[4px] ' : ' '}`);
|
|
54
|
+
showButtonMoreToolbar = computed(() => this.toolbarOptionsConfig().some((item) => item.display === false));
|
|
55
|
+
displaySkeletonToolbar = computed(() => this.toolbarOptionsConfig().every((item) => item.display === undefined));
|
|
56
|
+
labelFontSelectedComputed = computed(() => get(this.fontSelected(), 'item.label') || 'Sans Serif');
|
|
57
|
+
fontSelected = signal(undefined);
|
|
58
|
+
listConfigFont = signal(listConfigFont());
|
|
59
|
+
listConfigHeader = signal(listConfigHeader());
|
|
60
|
+
headerSelected = signal(undefined);
|
|
61
|
+
labelHeaderSelectedComputed = computed(() => get(this.headerSelected(), 'item.label') || 'Normal');
|
|
62
|
+
listConfigAlign = signal(listConfigAlign());
|
|
63
|
+
alignSelected = signal(undefined);
|
|
64
|
+
iconAlignSelectedComputed = computed(() => get(this.alignSelected(), 'item.icon'));
|
|
65
|
+
colorSelected = signal(undefined);
|
|
66
|
+
backgroundSelected = signal(undefined);
|
|
67
|
+
listCheckboxSelected = signal(false);
|
|
68
|
+
adjustSelected = signal(undefined);
|
|
69
|
+
messageError = signal('');
|
|
70
|
+
fontSize = signal({ value: 14 });
|
|
71
|
+
link = signal(linkDefault());
|
|
72
|
+
showMoreAction = signal(false);
|
|
73
|
+
toolbarOptionsConfig = signal([]);
|
|
74
|
+
loadingUploadImage = signal(false);
|
|
75
|
+
uploadImageConfig = input(uploadImageConfigDefault(), { transform: (value) => value || uploadImageConfigDefault() });
|
|
76
|
+
//region Inputs
|
|
77
|
+
displayToolbar = input(true, { transform: (value) => value ?? true });
|
|
78
|
+
placeholder = input('i18n_import_content', { transform: (value) => value || 'i18n_import_content' });
|
|
79
|
+
blotsRegister = input();
|
|
80
|
+
readonly = input(false, { transform: (value) => value ?? false });
|
|
81
|
+
quillCustomConfig = input();
|
|
82
|
+
label = input();
|
|
83
|
+
item = model.required();
|
|
84
|
+
fieldBind = input.required();
|
|
85
|
+
autoUpdateValueWhenTextChange = input(true, { transform: (value) => value ?? true });
|
|
86
|
+
dataConfigMention = input();
|
|
87
|
+
templateToolBarPersonalize = input();
|
|
88
|
+
zIndex = input(1250, { transform: (value) => value ?? 1250 });
|
|
89
|
+
ignoreShowPopupEditLink = input();
|
|
90
|
+
ignoreCommunicateMicroEventPopup = input();
|
|
91
|
+
handlersExpand = input();
|
|
92
|
+
resizeImagePlugin = input();
|
|
93
|
+
fontSizeDefault = input(14, { transform: (value) => value ?? 14 });
|
|
94
|
+
heightEditorContentDefault = input();
|
|
95
|
+
minHeightEditorContentDefault = input();
|
|
96
|
+
maxHeightEditorContentDefault = input();
|
|
97
|
+
removeNearWhiteColorsOnPaste = input(true);
|
|
98
|
+
resize = input('none', { transform: (value) => value ?? 'none' });
|
|
99
|
+
autoFocus = input();
|
|
100
|
+
focusTimerOnInit = input(750, { transform: (value) => value ?? 750 });
|
|
101
|
+
focusBottom = input();
|
|
102
|
+
validRequired = input();
|
|
103
|
+
validMinLength = input();
|
|
104
|
+
validMaxLength = input();
|
|
105
|
+
showErrorLabel = input(true, { transform: (val) => val ?? true });
|
|
106
|
+
showErrorBorder = input(true);
|
|
107
|
+
ignoreShowBorderErrorToolbar = input();
|
|
108
|
+
//endregion
|
|
109
|
+
//region Outputs
|
|
110
|
+
outShowPopupEditLink = output();
|
|
111
|
+
outMessageError = output();
|
|
112
|
+
outBlur = output();
|
|
113
|
+
outFocus = output();
|
|
114
|
+
outChange = output();
|
|
115
|
+
outSelectionChange = output();
|
|
116
|
+
outTextChange = output();
|
|
117
|
+
outContextMenu = output();
|
|
118
|
+
outFunctionsControl = output();
|
|
119
|
+
//endregion
|
|
120
|
+
//region ViewChild
|
|
121
|
+
htmlContainer = viewChild.required('htmlContainer');
|
|
122
|
+
quillBodyContainer = viewChild.required('snowContainer');
|
|
123
|
+
toolbarContainer = viewChild.required('toolbarContainer');
|
|
124
|
+
inputLinkRef = viewChild.required('inputLinkRef');
|
|
125
|
+
//endregion
|
|
126
|
+
//region Inject
|
|
127
|
+
destroyRef = inject(DestroyRef);
|
|
128
|
+
notificationService = inject(LibsUiNotificationService);
|
|
129
|
+
translate = inject(TranslateService);
|
|
130
|
+
cdr = inject(ChangeDetectorRef);
|
|
131
|
+
dynamicComponentService = inject(LibsUiDynamicComponentService);
|
|
132
|
+
//endregion
|
|
133
|
+
constructor() {
|
|
134
|
+
effect(() => {
|
|
135
|
+
if (this.fontSizeDefault()) {
|
|
136
|
+
untracked(() => {
|
|
137
|
+
this.fontSize.set({ value: this.fontSizeDefault() });
|
|
138
|
+
this.handlerValueChangeFontSize();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
effect(() => {
|
|
143
|
+
const elementEditor = this.quillBodyContainer().nativeElement.getElementsByClassName('ql-editor')?.[0];
|
|
144
|
+
if (this.heightEditorContentDefault()) {
|
|
145
|
+
untracked(() => {
|
|
146
|
+
if (elementEditor) {
|
|
147
|
+
elementEditor.style.height = `${this.heightEditorContentDefault()}px`;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (this.minHeightEditorContentDefault()) {
|
|
152
|
+
untracked(() => {
|
|
153
|
+
if (elementEditor) {
|
|
154
|
+
elementEditor.style.minHeight = `${this.minHeightEditorContentDefault()}px`;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (this.maxHeightEditorContentDefault()) {
|
|
159
|
+
untracked(() => {
|
|
160
|
+
if (elementEditor) {
|
|
161
|
+
elementEditor.style.maxHeight = `${this.maxHeightEditorContentDefault()}px`;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async ngOnInit() {
|
|
168
|
+
const type = get(this.quillCustomConfig(), 'toolbar.type', 'default');
|
|
169
|
+
const hasIconImage = this.uploadImageConfig().showIcon ?? false;
|
|
170
|
+
const hasIconPersonalize = !!this.templateToolBarPersonalize();
|
|
171
|
+
this.toolbarOptionsConfig.set(get(this.quillCustomConfig(), 'toolbar.options', toolBarOptions(type, hasIconImage, hasIconPersonalize)));
|
|
172
|
+
this.calculatorToolbar();
|
|
173
|
+
registerQuill2x();
|
|
174
|
+
this.blotsRegister()?.forEach((item) => {
|
|
175
|
+
Quill2x.register(item.component, true);
|
|
176
|
+
});
|
|
177
|
+
this.updateHandlerFunction();
|
|
178
|
+
const options = {
|
|
179
|
+
theme: 'snow',
|
|
180
|
+
placeholder: this.translate.instant(this.placeholder()),
|
|
181
|
+
readOnly: this.readonly(),
|
|
182
|
+
modules: {
|
|
183
|
+
toolbar: {
|
|
184
|
+
container: this.toolbarContainer().nativeElement,
|
|
185
|
+
handlers: this.handlers(),
|
|
186
|
+
},
|
|
187
|
+
resize: this.resizeImagePlugin()
|
|
188
|
+
? {
|
|
189
|
+
locale: {
|
|
190
|
+
altTip: this.translate.instant('i18n_keep_alt_key_to_change_the_ratio_when_changing_the_size'),
|
|
191
|
+
inputTip: this.translate.instant('i18n_press_enter_to_confirm'),
|
|
192
|
+
floatLeft: this.translate.instant('i18n_left_align'),
|
|
193
|
+
floatRight: this.translate.instant('i18n_right_align'),
|
|
194
|
+
center: this.translate.instant('i18n_center_align'),
|
|
195
|
+
restore: this.translate.instant('i18n_restore_to_default'),
|
|
196
|
+
},
|
|
197
|
+
}
|
|
198
|
+
: undefined,
|
|
199
|
+
table: true,
|
|
200
|
+
clipboard: {
|
|
201
|
+
matchers: [
|
|
202
|
+
[Node.TEXT_NODE, (node) => new Delta().insert(node.data)],
|
|
203
|
+
this.removeNearWhiteColorsOnPaste()
|
|
204
|
+
? [
|
|
205
|
+
Node.ELEMENT_NODE,
|
|
206
|
+
(node, delta) => {
|
|
207
|
+
const style = node.getAttribute('style');
|
|
208
|
+
if (style && this.isPaste()) {
|
|
209
|
+
const newOps = delta.ops.map((op) => {
|
|
210
|
+
if (op.attributes) {
|
|
211
|
+
const newAttrs = { ...op.attributes };
|
|
212
|
+
const color = newAttrs.color;
|
|
213
|
+
const background = newAttrs.background;
|
|
214
|
+
if (color && isNearWhite(color)) {
|
|
215
|
+
delete newAttrs.color;
|
|
216
|
+
}
|
|
217
|
+
if (background && isNearWhite(background)) {
|
|
218
|
+
delete newAttrs.background;
|
|
219
|
+
}
|
|
220
|
+
return { ...op, attributes: Object.keys(newAttrs).length ? newAttrs : undefined };
|
|
221
|
+
}
|
|
222
|
+
return op;
|
|
223
|
+
});
|
|
224
|
+
return new Delta(newOps);
|
|
225
|
+
}
|
|
226
|
+
return delta;
|
|
227
|
+
},
|
|
228
|
+
]
|
|
229
|
+
: [],
|
|
230
|
+
],
|
|
231
|
+
},
|
|
232
|
+
keyboard: {
|
|
233
|
+
bindings: {
|
|
234
|
+
backspace: {
|
|
235
|
+
key: UtilsKeyCodeConstant.BACKSPACE,
|
|
236
|
+
handler: (range) => this.noPreventEmbedDeletion(range),
|
|
237
|
+
},
|
|
238
|
+
delete: {
|
|
239
|
+
key: UtilsKeyCodeConstant.DELETE,
|
|
240
|
+
handler: (range) => this.noPreventEmbedDeletion(range),
|
|
241
|
+
},
|
|
242
|
+
enter: {
|
|
243
|
+
key: 13,
|
|
244
|
+
handler: () => (this.showMention() ? false : true),
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
history: {
|
|
249
|
+
delay: 2000,
|
|
250
|
+
maxStack: 500,
|
|
251
|
+
userOnly: true,
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
this.quill = new Quill2x(this.quillBodyContainer().nativeElement, options);
|
|
256
|
+
this.quill?.on('text-change', this.handlerTextChangeBind);
|
|
257
|
+
this.quill?.on('selection-change', this.handlerSelectionChangeBind);
|
|
258
|
+
fromEvent(this.quill?.root, 'copy').pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.handlerCopy.bind(this));
|
|
259
|
+
fromEvent(this.quill?.root, 'paste', { capture: true }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.handlerPaste.bind(this));
|
|
260
|
+
fromEvent(this.quillBodyContainer()?.nativeElement, 'contextmenu')
|
|
261
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
262
|
+
.subscribe((e) => this.outContextMenu.emit(e));
|
|
263
|
+
fromEvent(window, 'resize')
|
|
264
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
265
|
+
.subscribe(() => this.calculatorToolbar(true));
|
|
266
|
+
this.outFunctionsControl.emit(this.FunctionsControl);
|
|
267
|
+
await this.setContent(this.item()[this.fieldBind()]);
|
|
268
|
+
timer(this.autoFocus() ? 0 : 250)
|
|
269
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
270
|
+
.subscribe(() => this.displayEditor.set(true));
|
|
271
|
+
this.setStyleForContent();
|
|
272
|
+
if (this.autoFocus()) {
|
|
273
|
+
timer(this.focusTimerOnInit() + 250)
|
|
274
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
275
|
+
.subscribe(() => this.focus());
|
|
276
|
+
}
|
|
277
|
+
createContextMenuOptionTable(this.quill, this.translate);
|
|
278
|
+
enableTableSelection(this.quill.root);
|
|
279
|
+
getAllTablesWithSpan(this.quill);
|
|
280
|
+
const rootElement = this.quill?.root;
|
|
281
|
+
if (!rootElement) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
merge(fromEvent(rootElement, 'compositionstart'), fromEvent(rootElement, 'compositionend'))
|
|
285
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
286
|
+
.subscribe((e) => {
|
|
287
|
+
if (e.type === 'compositionstart') {
|
|
288
|
+
rootElement.classList.remove('ql-blank');
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (isEmptyQuill2x(this.quill)) {
|
|
292
|
+
rootElement.classList.add('ql-blank');
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
rootElement.classList.remove('ql-blank');
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
get FunctionsControl() {
|
|
299
|
+
return {
|
|
300
|
+
quill: () => this.quill,
|
|
301
|
+
checkIsValid: this.validate.bind(this),
|
|
302
|
+
refreshItemValue: this.updateValueByRootQuillHtml.bind(this),
|
|
303
|
+
setContent: this.setContent.bind(this),
|
|
304
|
+
insertText: this.insertText.bind(this),
|
|
305
|
+
insertLink: this.insertLink.bind(this),
|
|
306
|
+
insertImage: this.insertImage.bind(this),
|
|
307
|
+
setFontSize: async (size) => this.quill?.format('size', `${size}px`),
|
|
308
|
+
setColor: async (color) => this.quill?.format('color', color),
|
|
309
|
+
setBackground: async (color) => this.quill?.format('background', color),
|
|
310
|
+
setMessageError: async (message) => this.messageError.set(message),
|
|
311
|
+
reCalculatorToolbar: async () => this.calculatorToolbar(true),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
//region handler Event HTML
|
|
315
|
+
handlerChangeShowMoreAction(event) {
|
|
316
|
+
event.stopPropagation();
|
|
317
|
+
this.showMoreAction.update((showMoreAction) => !showMoreAction);
|
|
318
|
+
}
|
|
319
|
+
handleSelectFont(event) {
|
|
320
|
+
this.fontSelected.set(event);
|
|
321
|
+
this.quill?.format('font', event?.key);
|
|
322
|
+
}
|
|
323
|
+
handleSelectHeader(event) {
|
|
324
|
+
this.headerSelected.set(event);
|
|
325
|
+
this.quill?.format('header', event?.key);
|
|
326
|
+
}
|
|
327
|
+
handlerValueChangeFontSize(event) {
|
|
328
|
+
if (!event || event?.name === 'blur') {
|
|
329
|
+
this.quill?.format('size', `${this.fontSize().value}px`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
handleSelectAlign(event) {
|
|
333
|
+
this.alignSelected.set(event);
|
|
334
|
+
this.quill?.format('align', event?.key);
|
|
335
|
+
}
|
|
336
|
+
handlerSetFormat(type, data) {
|
|
337
|
+
if (!data.alpha) {
|
|
338
|
+
this.quill?.format(type, undefined);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
this.quill?.format(type, data.hex);
|
|
342
|
+
}
|
|
343
|
+
handlerInsertEmoji(emoji) {
|
|
344
|
+
this.insertText(emoji, undefined, true);
|
|
345
|
+
}
|
|
346
|
+
handlerUnlink(event) {
|
|
347
|
+
event.stopPropagation();
|
|
348
|
+
const link = this.link();
|
|
349
|
+
this.quill?.formatText(link.range.index, link.range.length, { link: false });
|
|
350
|
+
this.inputLinkRef().FunctionsControl?.removePopoverOverlay();
|
|
351
|
+
}
|
|
352
|
+
handlerEditLink(event) {
|
|
353
|
+
event.stopPropagation();
|
|
354
|
+
const link = this.link();
|
|
355
|
+
if (this.ignoreShowPopupEditLink()) {
|
|
356
|
+
this.outShowPopupEditLink.emit({
|
|
357
|
+
dataLink: link,
|
|
358
|
+
callback: async (linkEdit) => {
|
|
359
|
+
if (link instanceof Object && link.url) {
|
|
360
|
+
this.quill?.deleteText(link.range.index, link.range.length, Quill2x.sources.USER);
|
|
361
|
+
this.quill?.insertText(link.range.index, linkEdit.title, 'link', linkEdit.link);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
this.insertLink(linkEdit.title, linkEdit.link);
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
this.handleShowUploadLink(link);
|
|
370
|
+
this.inputLinkRef().FunctionsControl?.removePopoverOverlay();
|
|
371
|
+
}
|
|
372
|
+
handleToggleMention(show) {
|
|
373
|
+
this.showMention.set(show);
|
|
374
|
+
}
|
|
375
|
+
handlerInsertMention(data) {
|
|
376
|
+
this.insertMention(data);
|
|
377
|
+
}
|
|
378
|
+
//endregion
|
|
379
|
+
//region Private Method
|
|
380
|
+
//region Quill Methods
|
|
381
|
+
handleTable() {
|
|
382
|
+
const button = this.htmlContainer().nativeElement.querySelector?.('button.ql-table');
|
|
383
|
+
createTableSelector(this.quill, button, this.translate);
|
|
384
|
+
}
|
|
385
|
+
handleUndo() {
|
|
386
|
+
this.quill?.history?.undo();
|
|
387
|
+
}
|
|
388
|
+
handleRedo() {
|
|
389
|
+
this.quill?.history?.redo();
|
|
390
|
+
}
|
|
391
|
+
handlerShowUploadImage() {
|
|
392
|
+
if (this.uploadImageConfig().modeCustom) {
|
|
393
|
+
this.uploadImageComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillUploadImageComponent));
|
|
394
|
+
const instance = this.uploadImageComponentRef()?.instance;
|
|
395
|
+
this.uploadImageComponentRef()?.setInput('uploadImageConfig', this.uploadImageConfig());
|
|
396
|
+
this.uploadImageComponentRef()?.setInput('ignoreCommunicateMicroEvent', this.ignoreCommunicateMicroEventPopup());
|
|
397
|
+
instance?.outClose.subscribe((link) => {
|
|
398
|
+
this.dynamicComponentService.remove(this.uploadImageComponentRef());
|
|
399
|
+
if (link) {
|
|
400
|
+
this.insertImage(link);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
this.dynamicComponentService.addToBody(this.uploadImageComponentRef());
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const input = document.createElement('input');
|
|
407
|
+
input.setAttribute('type', 'file');
|
|
408
|
+
input.setAttribute('accept', 'image/*');
|
|
409
|
+
input.click();
|
|
410
|
+
input.onchange = async () => {
|
|
411
|
+
await this.uploadImagesAndInsert(input?.files);
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
async insertText(content, index, focusLastValueInsert) {
|
|
415
|
+
index = index ?? this.quill?.getSelection(true).index;
|
|
416
|
+
if (!isNil(index)) {
|
|
417
|
+
this.quill?.insertText(index, content, Quill2x.sources.USER);
|
|
418
|
+
if (focusLastValueInsert) {
|
|
419
|
+
await lastValueFrom(timer(0));
|
|
420
|
+
this.quill?.setSelection(index + content.length, 0, Quill2x.sources.USER);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
handlerSelectionChange(range, oldRange, source) {
|
|
425
|
+
if (this.readonly()) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if (range === null && oldRange !== null) {
|
|
429
|
+
this.outBlur.emit();
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (range !== null && oldRange === null) {
|
|
433
|
+
this.outFocus.emit();
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const format = this.updateStateToolbarByFormatInCursor();
|
|
437
|
+
this.outSelectionChange.emit({
|
|
438
|
+
quill: this.quill,
|
|
439
|
+
range,
|
|
440
|
+
oldRange,
|
|
441
|
+
source,
|
|
442
|
+
});
|
|
443
|
+
if (range.length !== 0 || !format?.link || source !== 'user') {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const selection = document.getSelection();
|
|
447
|
+
const anchorNode = selection?.anchorNode;
|
|
448
|
+
let linkNode = anchorNode;
|
|
449
|
+
while (linkNode && linkNode.tagName !== 'A') {
|
|
450
|
+
linkNode = linkNode.parentNode;
|
|
451
|
+
}
|
|
452
|
+
if (!linkNode || linkNode.tagName !== 'A') {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const linkText = linkNode.innerText;
|
|
456
|
+
const linksIndices = [];
|
|
457
|
+
let indexReturn = -1;
|
|
458
|
+
while (!isNil(indexReturn) && indexReturn < range.index) {
|
|
459
|
+
const textContent = this.quill?.getText();
|
|
460
|
+
const linkIndex = textContent?.indexOf(linkText, linksIndices.length > 0 ? linksIndices[linksIndices.length - 1] + linkText.length : 0);
|
|
461
|
+
if (!isNil(linkIndex)) {
|
|
462
|
+
if (linkIndex !== -1) {
|
|
463
|
+
linksIndices.push(linkIndex);
|
|
464
|
+
indexReturn = linkIndex + linkText.length;
|
|
465
|
+
}
|
|
466
|
+
if (linkIndex === -1) {
|
|
467
|
+
indexReturn = undefined;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (linksIndices && linksIndices.length) {
|
|
472
|
+
const rangeIndex = linksIndices[linksIndices.length - 1];
|
|
473
|
+
const countImage = this.adjustIndexForImages(rangeIndex);
|
|
474
|
+
setTimeout(() => {
|
|
475
|
+
this.link.set({
|
|
476
|
+
title: linkText,
|
|
477
|
+
url: linkNode.href,
|
|
478
|
+
range: {
|
|
479
|
+
index: rangeIndex + countImage,
|
|
480
|
+
length: linkText.length,
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
this.inputLinkRef().FunctionsControl?.showPopover(linkNode);
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
handlerCopy(e) {
|
|
488
|
+
if (!this.quill)
|
|
489
|
+
return;
|
|
490
|
+
const sel = this.quill.getSelection();
|
|
491
|
+
if (!sel || sel.length === 0)
|
|
492
|
+
return;
|
|
493
|
+
e.preventDefault();
|
|
494
|
+
const delta = this.quill.getContents(sel.index, sel.length);
|
|
495
|
+
const html2x = getHTMLFromDeltaOfQuill2x(delta);
|
|
496
|
+
if (e.clipboardData) {
|
|
497
|
+
e.clipboardData.setData('text/html', html2x);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
async handlerPaste(event) {
|
|
501
|
+
this.isPaste.set(true);
|
|
502
|
+
setTimeout(() => this.isPaste.set(false), 0);
|
|
503
|
+
if (!event || !event.clipboardData) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const files = event.clipboardData.files;
|
|
507
|
+
if (!files.length) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
event.preventDefault();
|
|
511
|
+
await this.uploadImagesAndInsert(files);
|
|
512
|
+
}
|
|
513
|
+
handlerTextChange(event, _, source) {
|
|
514
|
+
this.outTextChange.emit({
|
|
515
|
+
quill: this.quill,
|
|
516
|
+
delta: event,
|
|
517
|
+
});
|
|
518
|
+
setTimeout(() => {
|
|
519
|
+
this.detectLink(source);
|
|
520
|
+
this.updateStateToolbarByFormatInCursor();
|
|
521
|
+
if (event?.ops[1]?.insert === '\n') {
|
|
522
|
+
const range = { index: event?.ops[0].retain };
|
|
523
|
+
const currentLeaf = this.quill?.getLeaf(range.index)[0];
|
|
524
|
+
const nextLeaf = this.quill?.getLeaf(range.index + 1)[0];
|
|
525
|
+
this.quill?.insertEmbed(range.index, 'break', true, 'user');
|
|
526
|
+
if (nextLeaf === null || currentLeaf.parent !== nextLeaf.parent) {
|
|
527
|
+
this.quill?.insertEmbed(range.index, 'break', true, 'user');
|
|
528
|
+
}
|
|
529
|
+
this.quill?.setSelection((range.index || 0) + 1, 0, Quill2x.sources.SILENT);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
if (!this.autoUpdateValueWhenTextChange()) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
this.updateValueByRootQuillHtml();
|
|
536
|
+
}
|
|
537
|
+
//endregion
|
|
538
|
+
updateStateToolbarByFormatInCursor() {
|
|
539
|
+
try {
|
|
540
|
+
const format = this.quill?.getFormat();
|
|
541
|
+
if (format) {
|
|
542
|
+
this.setFontSizeSelected(format);
|
|
543
|
+
this.setFontSelected(format);
|
|
544
|
+
this.setColorSelected(format);
|
|
545
|
+
this.listCheckboxSelected.set(format?.list === 'unchecked' || format?.list === 'checked');
|
|
546
|
+
this.adjustSelected.set(format?.align);
|
|
547
|
+
}
|
|
548
|
+
return format;
|
|
549
|
+
}
|
|
550
|
+
catch (error) {
|
|
551
|
+
console.log(error);
|
|
552
|
+
return undefined;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
async validate() {
|
|
556
|
+
this.messageError.set('');
|
|
557
|
+
const validRequired = this.validRequired();
|
|
558
|
+
const item = this.item();
|
|
559
|
+
const fieldNameBind = this.fieldBind();
|
|
560
|
+
const value = get(item, fieldNameBind);
|
|
561
|
+
if (validRequired && validRequired.isRequired && !this.readonly() && isEmptyQuill2x(this.quill)) {
|
|
562
|
+
this.messageError.set(validRequired.message || ERROR_MESSAGE_EMPTY_VALID);
|
|
563
|
+
this.outMessageError.emit(this.messageError());
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
566
|
+
const validMinLength = this.validMinLength();
|
|
567
|
+
if (validMinLength && fieldNameBind && value && value.trim().length < validMinLength.length) {
|
|
568
|
+
this.messageError.set(validMinLength.message || ERROR_MESSAGE_MIN_LENGTH);
|
|
569
|
+
this.outMessageError.emit(this.messageError());
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
const validMaxLength = this.validMaxLength();
|
|
573
|
+
if (validMaxLength && fieldNameBind && value && value.trim().length > this.validMaxLength.length) {
|
|
574
|
+
this.messageError.set(validMaxLength.message || ERROR_MESSAGE_MAX_LENGTH);
|
|
575
|
+
this.outMessageError.emit(this.messageError());
|
|
576
|
+
return false;
|
|
577
|
+
}
|
|
578
|
+
this.outMessageError.emit(this.messageError());
|
|
579
|
+
return true;
|
|
580
|
+
}
|
|
581
|
+
updateHandlerFunction() {
|
|
582
|
+
const handlersExpand = this.handlersExpand();
|
|
583
|
+
if (handlersExpand && handlersExpand.length) {
|
|
584
|
+
handlersExpand.forEach((element) => {
|
|
585
|
+
if (element.title && element.action) {
|
|
586
|
+
this.handlers.update((item) => ({ ...item, [element.title]: element.action }));
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
noPreventEmbedDeletion(range) {
|
|
592
|
+
if (!this.quill)
|
|
593
|
+
return false;
|
|
594
|
+
const delta = this.quill?.getContents(range.index, 1);
|
|
595
|
+
if (delta?.ops.some((option) => this.blotsRegister()?.find((item) => get(option.insert, item.component['blotName']) && item.ignoreDelete))) {
|
|
596
|
+
return false; // Ngăn không cho Quill xử lý xóa
|
|
597
|
+
}
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
setFontSizeSelected(format) {
|
|
601
|
+
const fontSize = format?.size?.toString()?.replace('px', '');
|
|
602
|
+
if (isNaN(parseFloat(fontSize))) {
|
|
603
|
+
this.fontSize.set({ value: this.fontSizeDefault() });
|
|
604
|
+
// this.handlerValueChangeFontSize();
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
this.fontSize.set({ value: parseFloat(fontSize) });
|
|
608
|
+
}
|
|
609
|
+
setFontSelected(format) {
|
|
610
|
+
const font = listFont().find((item) => item.key === format.font);
|
|
611
|
+
if (!font) {
|
|
612
|
+
this.fontSelected.set({ key: '', item: listFont().find((item) => item.key === '') });
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
this.fontSelected.set({ key: format.font, item: font });
|
|
616
|
+
}
|
|
617
|
+
setColorSelected(format) {
|
|
618
|
+
this.colorSelected.set(format?.color);
|
|
619
|
+
this.backgroundSelected.set(format?.background);
|
|
620
|
+
}
|
|
621
|
+
async calculatorToolbar(resetTotalRecall) {
|
|
622
|
+
clearTimeout(this.timerCalculatorToolbar());
|
|
623
|
+
if (resetTotalRecall) {
|
|
624
|
+
this.totalRecallCalculatorToolbar.set(0);
|
|
625
|
+
}
|
|
626
|
+
this.cdr.detectChanges();
|
|
627
|
+
const toolbarWidth = this.toolbarContainer().nativeElement.offsetWidth || 0;
|
|
628
|
+
let totalWidth = 84;
|
|
629
|
+
if (!this.isCalculatorToolbarSuccess() && this.totalRecallCalculatorToolbar() < 10 && toolbarWidth < get(this.quillCustomConfig(), 'toolbar.lessWidthToolbarRecallCalculator', totalWidth)) {
|
|
630
|
+
this.totalRecallCalculatorToolbar.update((val) => val + 1);
|
|
631
|
+
this.timerCalculatorToolbar.set(setTimeout(() => {
|
|
632
|
+
this.calculatorToolbar();
|
|
633
|
+
}, 250));
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
this.isCalculatorToolbarSuccess.set(true);
|
|
637
|
+
this.toolbarOptionsConfig.update((configs) => {
|
|
638
|
+
configs.forEach((item, index) => {
|
|
639
|
+
item.display = true;
|
|
640
|
+
totalWidth += item.width;
|
|
641
|
+
if (item.type === 'line') {
|
|
642
|
+
const nextItemWidth = totalWidth + this.toolbarOptionsConfig()[+index + 1].width;
|
|
643
|
+
const preItem = this.toolbarOptionsConfig()[+index - 1];
|
|
644
|
+
if (nextItemWidth > toolbarWidth && preItem.display === true) {
|
|
645
|
+
item.display = undefined;
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
if (totalWidth > toolbarWidth) {
|
|
650
|
+
item.display = false;
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
return [...configs];
|
|
655
|
+
});
|
|
656
|
+
this.cdr.detectChanges();
|
|
657
|
+
}
|
|
658
|
+
setStyleForContent() {
|
|
659
|
+
const styleArray = [
|
|
660
|
+
{ selector: '.ql-font-Arial', style: 'font-family: Arial' },
|
|
661
|
+
{ selector: '.ql-font-sans-serif', style: 'font-family: sans-serif' },
|
|
662
|
+
{ selector: '.ql-font-serif', style: 'font-family: serif' },
|
|
663
|
+
{ selector: '.ql-font-monospace', style: 'font-family: monospace' },
|
|
664
|
+
{ selector: '.ql-font-Helvetica', style: 'font-family: Helvetica' },
|
|
665
|
+
{ selector: '.libs-ui-quill-format-image', style: 'max-width: 100%; height: auto', overrideStyle: true },
|
|
666
|
+
{ selector: '.libs-ui-quill-mention', style: 'font-weight: 600;-moz-osx-font-smoothing: grayscale;-webkit-font-smoothing: antialiased; color: #7239EA', overrideStyle: true },
|
|
667
|
+
{ selector: 'blockquote', style: 'border-left: 4px solid #ccc; margin-bottom: 5px; margin-top: 5px; padding-left: 16px', overrideStyle: true },
|
|
668
|
+
];
|
|
669
|
+
this.blotsRegister()?.forEach((item) => {
|
|
670
|
+
styleArray.push({ selector: `.${item.className}`, style: item.style, overrideStyle: true });
|
|
671
|
+
});
|
|
672
|
+
styleArray.forEach((item) => {
|
|
673
|
+
const elements = this.quill?.root.querySelectorAll(item.selector);
|
|
674
|
+
elements?.forEach((element) => {
|
|
675
|
+
if (item.overrideStyle) {
|
|
676
|
+
element.setAttribute('style', item.style);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
// Fixbug issue: https://admin-cv.mobio.vn/issues/49092
|
|
680
|
+
let styleExist = element.getAttribute('style');
|
|
681
|
+
if (styleExist) {
|
|
682
|
+
['font-family: Arial', 'font-family: sans-serif', 'font-family: serif', 'font-family: monospace', 'font-family: Helvetica'].forEach((font) => {
|
|
683
|
+
styleExist = (styleExist?.includes(`${font};`) ? styleExist?.replace(`${font};`, '') : styleExist?.replace(font, ''));
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
element.setAttribute('style', styleExist ? `${styleExist}${styleExist[styleExist.length - 1] === ';' ? '' : ';'}${item.style};` : item.style);
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
async setContent(content) {
|
|
691
|
+
if (!this.quill) {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
const contentXssFilter = await xssFilter(this.removeUnwantedPart(content || ''));
|
|
695
|
+
this.quill.clipboard.dangerouslyPasteHTML(contentXssFilter, Quill2x.sources.SILENT);
|
|
696
|
+
this.quill.blur();
|
|
697
|
+
}
|
|
698
|
+
adjustIndexForImages(index) {
|
|
699
|
+
const content = this.quill?.root;
|
|
700
|
+
let imageCount = 0;
|
|
701
|
+
let adjustedIndex = 0;
|
|
702
|
+
const adjustTextIndex = (node) => {
|
|
703
|
+
if (adjustedIndex > index) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
707
|
+
adjustedIndex += node.textContent?.length || 0;
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'IMG') {
|
|
711
|
+
if (adjustedIndex <= index) {
|
|
712
|
+
imageCount++;
|
|
713
|
+
}
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
717
|
+
Array.from(node.childNodes).forEach(adjustTextIndex);
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
adjustTextIndex(content);
|
|
721
|
+
return imageCount;
|
|
722
|
+
}
|
|
723
|
+
async uploadImagesAndInsert(files) {
|
|
724
|
+
if (!files) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
const maxImageSize = this.uploadImageConfig()?.maxImageSize || 5 * 1024 * 1024;
|
|
728
|
+
const images = Array.from(files).filter((file) => file && file.type.split('/')[0] === 'image' && (!this.uploadImageConfig().maxImageSize || file.size <= maxImageSize));
|
|
729
|
+
if (!images.length) {
|
|
730
|
+
this.notificationService.showCompTypeTextWarning(this.translate.instant('i18n_note_upload_image_volume', { value: getLabelBySizeFile(maxImageSize) }), { timeRemove: 8000 });
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
try {
|
|
734
|
+
this.loadingUploadImage.set(true);
|
|
735
|
+
const indexInsert = this.quill?.getSelection(true).index;
|
|
736
|
+
const links = await this.uploadImageConfig().functionUploadImage?.(images);
|
|
737
|
+
if (!links?.length) {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
links.forEach((link) => {
|
|
741
|
+
if (!link || (this.uploadImageConfig().onlyAcceptImageHttpsLink && (link instanceof ArrayBuffer || !new RegExp(patternUrl()).test(link)))) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
this.insertImage(link, indexInsert);
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
catch (error) {
|
|
748
|
+
console.error(error);
|
|
749
|
+
}
|
|
750
|
+
finally {
|
|
751
|
+
this.loadingUploadImage.set(false);
|
|
752
|
+
}
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
async insertImage(content, index) {
|
|
756
|
+
const selection = index ?? this.quill?.getSelection(true).index;
|
|
757
|
+
if (!isNil(selection)) {
|
|
758
|
+
this.quill?.insertEmbed(selection, 'image', content);
|
|
759
|
+
this.quill?.setSelection(selection + 1, 0);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
handlerPopoverEvent(event) {
|
|
763
|
+
setTimeout(() => {
|
|
764
|
+
if (event === 'remove') {
|
|
765
|
+
this.link.set(linkDefault());
|
|
766
|
+
}
|
|
767
|
+
}, 100);
|
|
768
|
+
}
|
|
769
|
+
async insertLink(text, url, index) {
|
|
770
|
+
const selection = this.quill?.getSelection(true);
|
|
771
|
+
const indexInsert = index ?? selection?.index;
|
|
772
|
+
if (selection?.length) {
|
|
773
|
+
this.quill?.deleteText(selection.index, selection.length, Quill2x.sources.USER);
|
|
774
|
+
}
|
|
775
|
+
if (!isNil(indexInsert)) {
|
|
776
|
+
this.quill?.insertText(indexInsert, text, {
|
|
777
|
+
link: url,
|
|
778
|
+
color: false,
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
handleShowUploadLink(event) {
|
|
783
|
+
this.addEditLinkComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillLinkComponent));
|
|
784
|
+
const instance = this.addEditLinkComponentRef()?.instance;
|
|
785
|
+
const selection = this.quill?.getSelection();
|
|
786
|
+
const textSelected = selection?.length ? this.quill?.getText(selection?.index, selection?.length) : '';
|
|
787
|
+
const data = event;
|
|
788
|
+
this.addEditLinkComponentRef()?.setInput('zIndex', this.zIndex());
|
|
789
|
+
this.addEditLinkComponentRef()?.setInput('title', data?.title || textSelected);
|
|
790
|
+
this.addEditLinkComponentRef()?.setInput('link', data?.url || '');
|
|
791
|
+
this.addEditLinkComponentRef()?.setInput('ignoreCommunicateMicroEvent', this.ignoreCommunicateMicroEventPopup());
|
|
792
|
+
instance?.outSaveLink.subscribe((item) => {
|
|
793
|
+
if (data instanceof Object && data.url) {
|
|
794
|
+
this.quill?.deleteText(data.range.index, data.range.length, Quill2x.sources.USER);
|
|
795
|
+
this.quill?.insertText(data.range.index, item.title, 'link', item.link);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
this.insertLink(item.title, item.link);
|
|
799
|
+
});
|
|
800
|
+
instance?.outClose.subscribe(() => this.dynamicComponentService.remove(this.addEditLinkComponentRef()));
|
|
801
|
+
this.dynamicComponentService.addToBody(this.addEditLinkComponentRef());
|
|
802
|
+
}
|
|
803
|
+
insertMention(event) {
|
|
804
|
+
const range = this.quill?.getSelection();
|
|
805
|
+
if (!range) {
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
const indexSubtract = this.quill?.getText(range.index - 1, 1)?.includes('@') ? 0 : 1;
|
|
809
|
+
const cursorPos = range.index - indexSubtract;
|
|
810
|
+
const startPosInsert = cursorPos - event.lengthKey;
|
|
811
|
+
this.quill?.deleteText(startPosInsert, event.lengthKey, Quill2x.sources.SILENT);
|
|
812
|
+
this.quill?.insertEmbed(startPosInsert, 'mention', event.data, Quill2x.sources.SILENT);
|
|
813
|
+
this.insertText(' ', startPosInsert + 1);
|
|
814
|
+
if (indexSubtract) {
|
|
815
|
+
this.quill?.deleteText(startPosInsert + 3, 1, Quill2x.sources.SILENT);
|
|
816
|
+
}
|
|
817
|
+
this.quill?.setSelection(startPosInsert + 2, 0, Quill2x.sources.SILENT);
|
|
818
|
+
}
|
|
819
|
+
updateValueByRootQuillHtml() {
|
|
820
|
+
if (!this.quill?.root.getElementsByTagName('img').length && !this.quill?.getText()) {
|
|
821
|
+
set(this.item(), this.fieldBind(), '');
|
|
822
|
+
this.validate();
|
|
823
|
+
this.outChange.emit(get(this.item, this.fieldBind()));
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
this.convertInnerHTMLAndSetValue();
|
|
827
|
+
this.validate();
|
|
828
|
+
this.outChange.emit(get(this.item, this.fieldBind()));
|
|
829
|
+
}
|
|
830
|
+
convertInnerHTMLAndSetValue() {
|
|
831
|
+
this.setStyleForContent();
|
|
832
|
+
set(this.item(), this.fieldBind(), this.removeUnwantedPart(this.quill?.root.innerHTML || ''));
|
|
833
|
+
}
|
|
834
|
+
removeUnwantedPart(html) {
|
|
835
|
+
if (!html) {
|
|
836
|
+
return '';
|
|
837
|
+
}
|
|
838
|
+
return html
|
|
839
|
+
.replace(/^\s*<p><br><\/p>/, '')
|
|
840
|
+
.replace(/<div><br><\/div>/gi, '')
|
|
841
|
+
.replace(/[\u200B-\u200D\uFEFF]/g, '');
|
|
842
|
+
}
|
|
843
|
+
detectLink(source) {
|
|
844
|
+
if (source !== 'user') {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
const fullText = this.quill?.getText();
|
|
848
|
+
const indexes = this.getIndexUrlMatch(fullText || '');
|
|
849
|
+
if (isNil(fullText) || !indexes.length) {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
indexes.forEach((item) => {
|
|
853
|
+
const textSelection = this.quill?.getText(item.start, item.end - item.start);
|
|
854
|
+
if (!textSelection) {
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
const indexof = textSelection.search(patterProtocolUrl());
|
|
858
|
+
if (indexof < 0) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
this.quill?.formatText(item.start + indexof, item.text.length, { link: item.text, color: false }, Quill2x.sources.SILENT);
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
getIndexUrlMatch(fullText) {
|
|
865
|
+
const textMatch = fullText.match(new RegExp(patternUrl().toString().replace('/^', '').replace('$/', ''), 'ig'));
|
|
866
|
+
const indexes = [];
|
|
867
|
+
let index = 0;
|
|
868
|
+
textMatch?.forEach((text) => {
|
|
869
|
+
const indexOfTextMatch = fullText.indexOf(text, index);
|
|
870
|
+
const indexPreCharacter = indexOfTextMatch - 1;
|
|
871
|
+
index = indexOfTextMatch + text.length;
|
|
872
|
+
if (indexOfTextMatch < 0 || !new RegExp(/^[\s]|^[\t]|^[\n]/).test(fullText[indexPreCharacter] || '')) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
indexes.push({ start: indexOfTextMatch, end: indexOfTextMatch + text.length, text, preCharacter: fullText[indexPreCharacter] });
|
|
876
|
+
});
|
|
877
|
+
return indexes;
|
|
878
|
+
}
|
|
879
|
+
focus() {
|
|
880
|
+
if (this.focusBottom()) {
|
|
881
|
+
this.quill?.setSelection(this.quill.root.innerHTML.length, 0, Quill2x.sources.SILENT);
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
this.quill?.setSelection(0, 0, Quill2x.sources.SILENT);
|
|
885
|
+
}
|
|
886
|
+
//endregion
|
|
887
|
+
ngOnDestroy() {
|
|
888
|
+
clearTimeout(this.timerSetFontSize());
|
|
889
|
+
clearTimeout(this.timerCalculatorToolbar());
|
|
890
|
+
this.dynamicComponentService.delete(this.addEditLinkComponentRef());
|
|
891
|
+
this.dynamicComponentService.delete(this.uploadImageComponentRef());
|
|
892
|
+
this.quill?.off('text-change', this.handlerTextChangeBind);
|
|
893
|
+
this.quill?.off('selection-change', this.handlerSelectionChangeBind);
|
|
894
|
+
const editorDom = this.quill?.root.parentElement;
|
|
895
|
+
if (editorDom && editorDom.parentElement) {
|
|
896
|
+
editorDom.parentElement.removeChild(editorDom);
|
|
897
|
+
}
|
|
898
|
+
this.quill = null;
|
|
899
|
+
}
|
|
900
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuill2xComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
901
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsInputsQuill2xComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill2x", inputs: { uploadImageConfig: { classPropertyName: "uploadImageConfig", publicName: "uploadImageConfig", isSignal: true, isRequired: false, transformFunction: null }, displayToolbar: { classPropertyName: "displayToolbar", publicName: "displayToolbar", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, blotsRegister: { classPropertyName: "blotsRegister", publicName: "blotsRegister", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, quillCustomConfig: { classPropertyName: "quillCustomConfig", publicName: "quillCustomConfig", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, fieldBind: { classPropertyName: "fieldBind", publicName: "fieldBind", isSignal: true, isRequired: true, transformFunction: null }, autoUpdateValueWhenTextChange: { classPropertyName: "autoUpdateValueWhenTextChange", publicName: "autoUpdateValueWhenTextChange", isSignal: true, isRequired: false, transformFunction: null }, dataConfigMention: { classPropertyName: "dataConfigMention", publicName: "dataConfigMention", isSignal: true, isRequired: false, transformFunction: null }, templateToolBarPersonalize: { classPropertyName: "templateToolBarPersonalize", publicName: "templateToolBarPersonalize", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowPopupEditLink: { classPropertyName: "ignoreShowPopupEditLink", publicName: "ignoreShowPopupEditLink", isSignal: true, isRequired: false, transformFunction: null }, ignoreCommunicateMicroEventPopup: { classPropertyName: "ignoreCommunicateMicroEventPopup", publicName: "ignoreCommunicateMicroEventPopup", isSignal: true, isRequired: false, transformFunction: null }, handlersExpand: { classPropertyName: "handlersExpand", publicName: "handlersExpand", isSignal: true, isRequired: false, transformFunction: null }, resizeImagePlugin: { classPropertyName: "resizeImagePlugin", publicName: "resizeImagePlugin", isSignal: true, isRequired: false, transformFunction: null }, fontSizeDefault: { classPropertyName: "fontSizeDefault", publicName: "fontSizeDefault", isSignal: true, isRequired: false, transformFunction: null }, heightEditorContentDefault: { classPropertyName: "heightEditorContentDefault", publicName: "heightEditorContentDefault", isSignal: true, isRequired: false, transformFunction: null }, minHeightEditorContentDefault: { classPropertyName: "minHeightEditorContentDefault", publicName: "minHeightEditorContentDefault", isSignal: true, isRequired: false, transformFunction: null }, maxHeightEditorContentDefault: { classPropertyName: "maxHeightEditorContentDefault", publicName: "maxHeightEditorContentDefault", isSignal: true, isRequired: false, transformFunction: null }, removeNearWhiteColorsOnPaste: { classPropertyName: "removeNearWhiteColorsOnPaste", publicName: "removeNearWhiteColorsOnPaste", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, focusTimerOnInit: { classPropertyName: "focusTimerOnInit", publicName: "focusTimerOnInit", isSignal: true, isRequired: false, transformFunction: null }, focusBottom: { classPropertyName: "focusBottom", publicName: "focusBottom", isSignal: true, isRequired: false, transformFunction: null }, validRequired: { classPropertyName: "validRequired", publicName: "validRequired", isSignal: true, isRequired: false, transformFunction: null }, validMinLength: { classPropertyName: "validMinLength", publicName: "validMinLength", isSignal: true, isRequired: false, transformFunction: null }, validMaxLength: { classPropertyName: "validMaxLength", publicName: "validMaxLength", isSignal: true, isRequired: false, transformFunction: null }, showErrorLabel: { classPropertyName: "showErrorLabel", publicName: "showErrorLabel", isSignal: true, isRequired: false, transformFunction: null }, showErrorBorder: { classPropertyName: "showErrorBorder", publicName: "showErrorBorder", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowBorderErrorToolbar: { classPropertyName: "ignoreShowBorderErrorToolbar", publicName: "ignoreShowBorderErrorToolbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { item: "itemChange", outShowPopupEditLink: "outShowPopupEditLink", outMessageError: "outMessageError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outSelectionChange: "outSelectionChange", outTextChange: "outTextChange", outContextMenu: "outContextMenu", outFunctionsControl: "outFunctionsControl" }, viewQueries: [{ propertyName: "htmlContainer", first: true, predicate: ["htmlContainer"], descendants: true, isSignal: true }, { propertyName: "quillBodyContainer", first: true, predicate: ["snowContainer"], descendants: true, isSignal: true }, { propertyName: "toolbarContainer", first: true, predicate: ["toolbarContainer"], descendants: true, isSignal: true }, { propertyName: "inputLinkRef", first: true, predicate: ["inputLinkRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #htmlContainer\n [class]=\"containerClass()\"\n [style.--resize]=\"resize()\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #toolbarContainer\n class=\"relative h-[44px]\"\n [class.hidden]=\"!displayToolbar()\"\n [ngStyle]=\"quillCustomConfig()?.toolbar?.()?.styles?.() || {}\">\n <ng-container *ngTemplateOutlet=\"toolbarTemplate\" />\n </div>\n <div\n #snowContainer\n LibsUiComponentsScrollOverlayDirective\n LibsUiComponentsInputsMentionDirective\n [options]=\"{ ignoreTransparentScrollBarColorDefault: resize() !== 'none' }\"\n [mentionConfig]=\"dataConfigMention()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"\n [class]=\"containerEditorClass()\"></div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbarTemplate>\n <div\n [class]=\"containerToolbarClass()\"\n #toolbarItems>\n @if (displaySkeletonToolbar()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px] !flex\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n <div class=\"relative\">\n @if (showButtonMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemToolbarTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [readonly]=\"readonly()\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [popoverCustomConfig]=\"{ widthByParent: false, width: 200, classInclude: 'h-[254px]', classIncludeOverlayBody: 'h-full', position: { mode: 'start', distance: -8 } }\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [readonly]=\"readonly()\"\n [listMaxItemShow]=\"-1\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\" {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n #inputSizeRef\n [dataType]=\"'int'\"\n [(item)]=\"fontSize\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outChangeValueByButtonUpDown)=\"handlerValueChangeFontSize()\"\n (outFocusAndBlur)=\"handlerValueChangeFontSize($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChangeMultipleType)=\"handlerSetFormat('color', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.libs-ui-icon-editor-color-text-active]=\"!!colorSelected()\"\n [style.--color-selected]=\"colorSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChangeMultipleType)=\"handlerSetFormat('background', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.libs-ui-icon-editor-color-background-active]=\"!!backgroundSelected()\"\n [style.--background-selected]=\"backgroundSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold !flex\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic !flex\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline !flex\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike !flex\"></button>\n </div>\n }\n @if (option.type === 'script.sub') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_sub', zIndex: zIndex() }\"\n class=\"ql-script flex\"\n value=\"sub\"></button>\n </div>\n }\n @if (option.type === 'script.super') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_super', zIndex: zIndex() }\"\n class=\"ql-script flex\"\n value=\"super\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [zIndex]=\"zIndex() + 1\"\n [listKeySelected]=\"adjustSelected()\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i\n [class]=\"iconAlignSelectedComputed()\"\n [class.text-[var(--libs-ui-color-light-1)]]=\"adjustSelected() !== undefined\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'listChecked') {\n <div\n [class]=\"option.classInclude || 'mx-[8px]'\"\n [class.ql-active]=\"listCheckboxSelected()\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-check\"\n value=\"check\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"\n (click)=\"handlerUnlink($event)\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'video') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_video', zIndex: zIndex() }\"\n class=\"ql-video\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerInsertEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'table') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_table', zIndex: zIndex() }\"\n class=\"ql-table\"></button>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n #inputLinkRef\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEditLink($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host ::ng-deep .quill-container .ql-container{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400}:host ::ng-deep .quill-container .ql-container .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400;height:auto;min-height:100%;resize:var(--resize)}:host ::ng-deep .quill-container .ql-container .ql-editor ol,:host ::ng-deep .quill-container .ql-container .ql-editor ul{list-style:none!important;padding-left:0!important;margin-left:0!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li,:host ::ng-deep .quill-container .ql-container .ql-editor ul li{list-style-type:none!important}:host ::ng-deep .quill-container .ql-container .ql-editor li,:host ::ng-deep .quill-container .ql-container .ql-editor ol li,:host ::ng-deep .quill-container .ql-container .ql-editor ul li,:host ::ng-deep .quill-container .ql-container .ql-editor li[data-list]{counter-reset:none!important;counter-increment:none!important;counter-set:none!important}@supports (counter-set: none){:host ::ng-deep .quill-container .ql-container .ql-editor li[data-list]{counter-set:none!important}}:host ::ng-deep .quill-container .ql-container .ql-editor ol li:not(.ql-direction-rtl){counter-increment:none!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol{counter-reset:my-counter 0!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol>li[data-list=ordered]{counter-increment:my-counter 1!important;position:relative;padding-left:8px}:host ::ng-deep .quill-container .ql-container .ql-editor ol>li[data-list=ordered]:before{content:counter(my-counter) \". \"}:host ::ng-deep .quill-container .ql-container .ql-editor ol li span:before{content:\"\"!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li[data-list=bullet]:before{content:\"\\2022 \"!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li[data-list=unchecked]:before{content:\"\\2610 \"!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li[data-list=checked]:before{content:\"\\2611 \"!important}:host ::ng-deep .quill-container .ql-container .ql-blank:before{font-style:normal!important;font-size:12px!important;color:#9ca2ad!important;font-family:var(--libs-ui-font-family-name),arial!important}:host ::ng-deep .quill-container .ql-active span:before{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-active .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-script :hover .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-toolbar{padding:0!important;border:none!important}:host ::ng-deep .quill-container .ql-toolbar button{padding:0!important;height:16px!important;width:16px!important}:host ::ng-deep .quill-container .ql-tooltip{display:none!important}:host ::ng-deep .quill-container #editor-resizer .toolbar{top:0!important;left:0!important;transform:none!important;font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400;font-size:12px}:host ::ng-deep .quill-container .libs-ui-icon-editor-color-text-active{color:var(--color-selected)!important}:host ::ng-deep .quill-container .libs-ui-icon-editor-color-background-active{color:var(--background-selected)!important}:host ::ng-deep .quill-container .ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}:host ::ng-deep .selected-cell{background-color:#0096ff4d}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldLabel", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "disableLabel", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsSkeletonComponent, selector: "libs_ui-components-skeleton", inputs: ["config"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }, { kind: "component", type: LibsUiComponentsEmojiComponent, selector: "libs_ui-components-emoji", inputs: ["configPopover", "isNgContent", "zIndex", "modePopoverPosition", "classPopup", "classInclude", "classIconInclude"], outputs: ["outEventEmoji", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "initEventInElementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "typeInput", "modeInput", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "ignoreWidthInput100", "classIncludeInput", "classContainerInput", "readonly", "disable", "noBorder", "backgroundNone", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "classContainerBottomInput", "autoRemoveEmoji", "defaultHeight", "maxHeightTextArea", "minHeightTextArea", "ignoreShowError", "borderError", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "zIndexPopoverContent", "unitsLeft", "configUnitLeft", "keySelectedUnitLeft", "unitsRight", "configUnitRight", "keySelectedUnitRight", "maxValueNumber", "minValueNumber", "ignoreContentLeft", "ignoreContentRight", "isBaselineStyle", "valuePatternShowError", "validPattern", "validRequired", "validMinLength", "validMinValue", "validMaxValue", "validMaxLength", "functionValid", "maxLength", "positionMessageErrorStartInput", "classInclude", "resize", "templateLeftBottomInput", "templateRightBottomInput", "onlyAcceptNegativeValue", "autoAddZeroLessThan10InTypeInt", "maxLengthNumberCount", "classMessageErrorInclude", "ignoreStopPropagationEvent", "ignoreUnitRightClassReadOnly", "paddingRightCustomSpecific", "focusTimeOut", "debounceTimeValidate"], outputs: ["itemChange", "outValueChange", "outSelect", "outIconLeft", "outIconRight", "outClickButtonLabel", "outSwitchEventLabel", "outLabelRightClick", "outEnterInputEvent", "outHeightAreaChange", "outFunctionsControl", "outFocusAndBlur", "outChangeValueByButtonUpDown"] }, { kind: "component", type: LibsUiComponentsButtonsSelectColorComponent, selector: "libs_ui-components-buttons-select_color", inputs: ["zIndex", "customOptions", "externalContent", "direction", "button", "applyNow"], outputs: ["zIndexChange", "outColorChange", "outColorChangeMultipleType"] }, { kind: "component", type: LibsUiComponentsLabelComponent, selector: "libs_ui-components-label", inputs: ["iconPopoverClass", "classInclude", "labelLeft", "labelLeftClass", "labelLeftBehindToggleButton", "popover", "required", "buttonsLeft", "disableButtonsLeft", "buttonsRight", "disableButtonsRight", "labelRight", "labelRightClass", "labelRightRequired", "hasToggle", "toggleSize", "toggleActive", "toggleDisable", "description", "descriptionClass", "buttonsDescription", "disableButtonsDescription", "buttonsDescriptionContainerClass", "onlyShowCount", "zIndexPopover", "timerDestroyPopover", "count", "limitLength"], outputs: ["outClickButton", "outSwitchEvent", "outLabelRightClick", "outLabelLeftClick"] }, { kind: "directive", type: LibsUiComponentsInputsMentionDirective, selector: "[LibsUiComponentsInputsMentionDirective]", inputs: ["timeDelayInit", "mentionConfig", "mentionListTemplate"], outputs: ["outSearchTerm", "outItemSelected", "outToggle", "outInsertMention", "outFunctionControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
902
|
+
}
|
|
903
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuill2xComponent, decorators: [{
|
|
904
|
+
type: Component,
|
|
905
|
+
args: [{ selector: 'libs_ui-components-inputs-quill2x', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
906
|
+
NgStyle,
|
|
907
|
+
TranslateModule,
|
|
908
|
+
NgTemplateOutlet,
|
|
909
|
+
LibsUiComponentsDropdownComponent,
|
|
910
|
+
LibsUiComponentsButtonsButtonComponent,
|
|
911
|
+
LibsUiComponentsSkeletonComponent,
|
|
912
|
+
LibsUiComponentsScrollOverlayDirective,
|
|
913
|
+
LibsUiComponentsEmojiComponent,
|
|
914
|
+
LibsUiComponentsPopoverComponent,
|
|
915
|
+
LibsUiComponentsInputsValidComponent,
|
|
916
|
+
LibsUiComponentsButtonsSelectColorComponent,
|
|
917
|
+
LibsUiComponentsLabelComponent,
|
|
918
|
+
LibsUiComponentsInputsMentionDirective,
|
|
919
|
+
], template: "<div\n #htmlContainer\n [class]=\"containerClass()\"\n [style.--resize]=\"resize()\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #toolbarContainer\n class=\"relative h-[44px]\"\n [class.hidden]=\"!displayToolbar()\"\n [ngStyle]=\"quillCustomConfig()?.toolbar?.()?.styles?.() || {}\">\n <ng-container *ngTemplateOutlet=\"toolbarTemplate\" />\n </div>\n <div\n #snowContainer\n LibsUiComponentsScrollOverlayDirective\n LibsUiComponentsInputsMentionDirective\n [options]=\"{ ignoreTransparentScrollBarColorDefault: resize() !== 'none' }\"\n [mentionConfig]=\"dataConfigMention()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"\n [class]=\"containerEditorClass()\"></div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbarTemplate>\n <div\n [class]=\"containerToolbarClass()\"\n #toolbarItems>\n @if (displaySkeletonToolbar()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px] !flex\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n <div class=\"relative\">\n @if (showButtonMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemToolbarTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [readonly]=\"readonly()\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [popoverCustomConfig]=\"{ widthByParent: false, width: 200, classInclude: 'h-[254px]', classIncludeOverlayBody: 'h-full', position: { mode: 'start', distance: -8 } }\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [readonly]=\"readonly()\"\n [listMaxItemShow]=\"-1\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\" {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n #inputSizeRef\n [dataType]=\"'int'\"\n [(item)]=\"fontSize\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outChangeValueByButtonUpDown)=\"handlerValueChangeFontSize()\"\n (outFocusAndBlur)=\"handlerValueChangeFontSize($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChangeMultipleType)=\"handlerSetFormat('color', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.libs-ui-icon-editor-color-text-active]=\"!!colorSelected()\"\n [style.--color-selected]=\"colorSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChangeMultipleType)=\"handlerSetFormat('background', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.libs-ui-icon-editor-color-background-active]=\"!!backgroundSelected()\"\n [style.--background-selected]=\"backgroundSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold !flex\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic !flex\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline !flex\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike !flex\"></button>\n </div>\n }\n @if (option.type === 'script.sub') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_sub', zIndex: zIndex() }\"\n class=\"ql-script flex\"\n value=\"sub\"></button>\n </div>\n }\n @if (option.type === 'script.super') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_super', zIndex: zIndex() }\"\n class=\"ql-script flex\"\n value=\"super\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [zIndex]=\"zIndex() + 1\"\n [listKeySelected]=\"adjustSelected()\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i\n [class]=\"iconAlignSelectedComputed()\"\n [class.text-[var(--libs-ui-color-light-1)]]=\"adjustSelected() !== undefined\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'listChecked') {\n <div\n [class]=\"option.classInclude || 'mx-[8px]'\"\n [class.ql-active]=\"listCheckboxSelected()\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-check\"\n value=\"check\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"\n (click)=\"handlerUnlink($event)\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'video') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_video', zIndex: zIndex() }\"\n class=\"ql-video\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerInsertEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'table') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_table', zIndex: zIndex() }\"\n class=\"ql-table\"></button>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n #inputLinkRef\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEditLink($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host ::ng-deep .quill-container .ql-container{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400}:host ::ng-deep .quill-container .ql-container .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400;height:auto;min-height:100%;resize:var(--resize)}:host ::ng-deep .quill-container .ql-container .ql-editor ol,:host ::ng-deep .quill-container .ql-container .ql-editor ul{list-style:none!important;padding-left:0!important;margin-left:0!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li,:host ::ng-deep .quill-container .ql-container .ql-editor ul li{list-style-type:none!important}:host ::ng-deep .quill-container .ql-container .ql-editor li,:host ::ng-deep .quill-container .ql-container .ql-editor ol li,:host ::ng-deep .quill-container .ql-container .ql-editor ul li,:host ::ng-deep .quill-container .ql-container .ql-editor li[data-list]{counter-reset:none!important;counter-increment:none!important;counter-set:none!important}@supports (counter-set: none){:host ::ng-deep .quill-container .ql-container .ql-editor li[data-list]{counter-set:none!important}}:host ::ng-deep .quill-container .ql-container .ql-editor ol li:not(.ql-direction-rtl){counter-increment:none!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol{counter-reset:my-counter 0!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol>li[data-list=ordered]{counter-increment:my-counter 1!important;position:relative;padding-left:8px}:host ::ng-deep .quill-container .ql-container .ql-editor ol>li[data-list=ordered]:before{content:counter(my-counter) \". \"}:host ::ng-deep .quill-container .ql-container .ql-editor ol li span:before{content:\"\"!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li[data-list=bullet]:before{content:\"\\2022 \"!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li[data-list=unchecked]:before{content:\"\\2610 \"!important}:host ::ng-deep .quill-container .ql-container .ql-editor ol li[data-list=checked]:before{content:\"\\2611 \"!important}:host ::ng-deep .quill-container .ql-container .ql-blank:before{font-style:normal!important;font-size:12px!important;color:#9ca2ad!important;font-family:var(--libs-ui-font-family-name),arial!important}:host ::ng-deep .quill-container .ql-active span:before{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-active .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-script :hover .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-toolbar{padding:0!important;border:none!important}:host ::ng-deep .quill-container .ql-toolbar button{padding:0!important;height:16px!important;width:16px!important}:host ::ng-deep .quill-container .ql-tooltip{display:none!important}:host ::ng-deep .quill-container #editor-resizer .toolbar{top:0!important;left:0!important;transform:none!important;font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400;font-size:12px}:host ::ng-deep .quill-container .libs-ui-icon-editor-color-text-active{color:var(--color-selected)!important}:host ::ng-deep .quill-container .libs-ui-icon-editor-color-background-active{color:var(--background-selected)!important}:host ::ng-deep .quill-container .ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}:host ::ng-deep .selected-cell{background-color:#0096ff4d}\n"] }]
|
|
920
|
+
}], ctorParameters: () => [] });
|
|
921
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpbGwyeC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvaW5wdXRzL3F1aWxsMngvc3JjL3F1aWxsMnguY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2lucHV0cy9xdWlsbDJ4L3NyYy9xdWlsbDJ4LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBZ0IsUUFBUSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQWMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBRSxNQUFNLEVBQWUsU0FBUyxFQUFFLFNBQVMsRUFBa0IsTUFBTSxlQUFlLENBQUM7QUFDMVAsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEUsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDNUYsT0FBTyxFQUFFLDJDQUEyQyxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDdkcsT0FBTyxFQUFrQixpQ0FBaUMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2pHLE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRWxGLE9BQU8sRUFBa0Msc0NBQXNDLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUM1SCxPQUFPLEVBQWdDLG9DQUFvQyxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEgsT0FBTyxFQUFVLDhCQUE4QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFbkYsT0FBTyxFQUFFLGdDQUFnQyxFQUFzQixNQUFNLDZCQUE2QixDQUFDO0FB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O3FCQUN2QyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IE5nU3R5bGUsIE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIENvbXBvbmVudFJlZiwgY29tcHV0ZWQsIERlc3Ryb3lSZWYsIGVmZmVjdCwgRWxlbWVudFJlZiwgaW5qZWN0LCBpbnB1dCwgbW9kZWwsIE9uRGVzdHJveSwgT25Jbml0LCBvdXRwdXQsIHNpZ25hbCwgVGVtcGxhdGVSZWYsIHVudHJhY2tlZCwgdmlld0NoaWxkLCBXcml0YWJsZVNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNCdXR0b25Db21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNCdXR0b25zU2VsZWN0Q29sb3JDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWJ1dHRvbnMtc2VsZWN0LWNvbG9yJztcbmltcG9ydCB7IElFbWl0U2VsZWN0S2V5LCBMaWJzVWlDb21wb25lbnRzRHJvcGRvd25Db21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWRyb3Bkb3duJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNFbW9qaUNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtaW5wdXRzLWVtb2ppJztcbmltcG9ydCB7IElGb2N1c0FuZEJsdXJFdmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtaW5wdXRzLWlucHV0JztcbmltcG9ydCB7IElNZW50aW9uQ29uZmlnLCBJTWVudGlvbkluc2VydCwgTGlic1VpQ29tcG9uZW50c0lucHV0c01lbnRpb25EaXJlY3RpdmUgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWlucHV0cy1tZW50aW9uJztcbmltcG9ydCB7IElWYWxpZExlbmd0aCwgSVZhbGlkUmVxdWlyZWQsIExpYnNVaUNvbXBvbmVudHNJbnB1dHNWYWxpZENvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtaW5wdXRzLXZhbGlkJztcbmltcG9ydCB7IElMYWJlbCwgTGlic1VpQ29tcG9uZW50c0xhYmVsQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1sYWJlbCc7XG5pbXBvcnQgeyBJTGlzdENvbmZpZ0l0ZW0gfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWxpc3QnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJDb21wb25lbnQsIFRZUEVfUE9QT1ZFUl9FVkVOVCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtcG9wb3Zlcic7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZSB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtc2Nyb2xsLW92ZXJsYXknO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c1NrZWxldG9uQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1za2VsZXRvbic7XG5pbXBvcnQgeyBUWVBFX09CSkVDVCwgVFlQRV9URU1QTEFURV9SRUYgfSBmcm9tICdAbGlicy11aS9pbnRlcmZhY2VzLXR5cGVzJztcbmltcG9ydCB7IExpYnNVaUR5bmFtaWNDb21wb25lbnRTZXJ2aWNlIH0gZnJvbSAnQGxpYnMtdWkvc2VydmljZXMtZHluYW1pYy1jb21wb25lbnQnO1xuaW1wb3J0IHsgTGlic1VpTm90aWZpY2F0aW9uU2VydmljZSB9IGZyb20gJ0BsaWJzLXVpL3NlcnZpY2VzLW5vdGlmaWNhdGlvbic7XG5pbXBvcnQgeyBFUlJPUl9NRVNTQUdFX0VNUFRZX1ZBTElELCBFUlJPUl9NRVNTQUdFX01BWF9MRU5HVEgsIEVSUk9SX01FU1NBR0VfTUlOX0xFTkdUSCwgZ2V0LCBnZXRMYWJlbEJ5U2l6ZUZpbGUsIGlzTmVhcldoaXRlLCBpc05pbCwgcGF0dGVyblVybCwgcGF0dGVyUHJvdG9jb2xVcmwsIHNldCwgVXRpbHNLZXlDb2RlQ29uc3RhbnQsIHhzc0ZpbHRlciB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSwgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuXG5pbXBvcnQgeyBJT3V0cHV0Q29sb3JDaGFuZ2VNdWx0aXBsZVR5cGUgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWNvbG9yLXBpY2tlcic7XG5pbXBvcnQgUXVpbGwyeCwgeyBEZWx0YSwgRW1pdHRlclNvdXJjZSwgUmFuZ2UgfSBmcm9tICdxdWlsbDJ4JztcbmltcG9ydCB7IGZyb21FdmVudCwgbGFzdFZhbHVlRnJvbSwgbWVyZ2UsIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBRVUlMTDJYX1RZUEVfTU9ERV9CQVJfQ09ORklHX09QVElPTiB9IGZyb20gJy4vaW50ZXJmYWNlcy9xdWlsbDJ4LmludGVyZmFjZSc7XG5pbXBvcnQgeyBJUXVpbGwyeEJsb3RSZWdpc3RlciwgSVF1aWxsMnhDdXN0b21Db25maWcsIElRdWlsbDJ4RnVuY3Rpb25Db250cm9sRXZlbnQsIElRdWlsbDJ4TGluaywgSVF1aWxsMnhTZWxlY3Rpb25DaGFuZ2UsIElRdWlsbDJ4VGV4dENoYW5nZSwgSVF1aWxsMnhUb29sYmFyQ29uZmlnLCBJUXVpbGwyeFVwbG9hZEltYWdlQ29uZmlnIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3F1aWxsMnguaW50ZXJmYWNlJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbExpbmtDb21wb25lbnQgfSBmcm9tICcuL2xpbmsvbGluay5jb21wb25lbnQnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0lucHV0c1F1aWxsVXBsb2FkSW1hZ2VDb21wb25lbnQgfSBmcm9tICcuL3VwbG9hZC1pbWFnZS91cGxvYWQtaW1hZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IGxpbmtEZWZhdWx0LCBsaXN0Q29uZmlnQWxpZ24sIGxpc3RDb25maWdGb250LCBsaXN0Q29uZmlnSGVhZGVyLCBsaXN0Rm9udCwgdG9vbEJhck9wdGlvbnMsIHVwbG9hZEltYWdlQ29uZmlnRGVmYXVsdCB9IGZyb20gJy4vdXRpbHMvZGF0YS5kZWZpbmUnO1xuaW1wb3J0IHsgY3JlYXRlQ29udGV4dE1lbnVPcHRpb25UYWJsZSwgY3JlYXRlVGFibGVTZWxlY3RvciwgZW5hYmxlVGFibGVTZWxlY3Rpb24sIGdldEFsbFRhYmxlc1dpdGhTcGFuLCBpc0VtcHR5UXVpbGwyeCwgZ2V0SFRNTEZyb21EZWx0YU9mUXVpbGwyeCwgcmVnaXN0ZXJRdWlsbDJ4IH0gZnJvbSAnLi91dGlscy9mdW5jdGlvbnMuZGVmaW5lJztcbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2xpYnNfdWktY29tcG9uZW50cy1pbnB1dHMtcXVpbGwyeCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZVVybDogJy4vcXVpbGwyeC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9xdWlsbDJ4LmNvbXBvbmVudC5zY3NzJyxcbiAgaW1wb3J0czogW1xuICAgIE5nU3R5bGUsXG4gICAgVHJhbnNsYXRlTW9kdWxlLFxuICAgIE5nVGVtcGxhdGVPdXRsZXQsXG4gICAgTGlic1VpQ29tcG9uZW50c0Ryb3Bkb3duQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNCdXR0b25zQnV0dG9uQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNTa2VsZXRvbkNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZSxcbiAgICBMaWJzVWlDb21wb25lbnRzRW1vamlDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c0lucHV0c1ZhbGlkQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNCdXR0b25zU2VsZWN0Q29sb3JDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c0xhYmVsQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uRGlyZWN0aXZlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzSW5wdXRzUXVpbGwyeENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLy9yZWdpb24gUHJpdmF0ZVxuICBwcml2YXRlIGRpc3BsYXlFZGl0b3IgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGlzUGFzdGUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIHF1aWxsOiBRdWlsbDJ4IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYWRkRWRpdExpbmtDb21wb25lbnRSZWYgPSBzaWduYWw8Q29tcG9uZW50UmVmPExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbExpbmtDb21wb25lbnQ+IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIHVwbG9hZEltYWdlQ29tcG9uZW50UmVmID0gc2lnbmFsPENvbXBvbmVudFJlZjxMaWJzVWlDb21wb25lbnRzSW5wdXRzUXVpbGxVcGxvYWRJbWFnZUNvbXBvbmVudD4gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgaGFuZGxlcnMgPSBzaWduYWw8UmVjb3JkPHN0cmluZywgKC4uLnBhcmFtczogQXJyYXk8dW5rbm93bj4pID0+IHZvaWQ+Pih7XG4gICAgbGluazogdGhpcy5oYW5kbGVTaG93VXBsb2FkTGluay5iaW5kKHRoaXMpLFxuICAgIHVuZG86IHRoaXMuaGFuZGxlVW5kby5iaW5kKHRoaXMpLFxuICAgIHJlZG86IHRoaXMuaGFuZGxlUmVkby5iaW5kKHRoaXMpLFxuICAgIHRhYmxlOiB0aGlzLmhhbmRsZVRhYmxlLmJpbmQodGhpcyksXG4gICAgaW1hZ2U6IHRoaXMuaGFuZGxlclNob3dVcGxvYWRJbWFnZS5iaW5kKHRoaXMpLFxuICB9KTtcbiAgcHJpdmF0ZSB0aW1lclNldEZvbnRTaXplID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSB0aW1lckNhbGN1bGF0b3JUb29sYmFyID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSB0b3RhbFJlY2FsbENhbGN1bGF0b3JUb29sYmFyID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIHByaXZhdGUgaXNDYWxjdWxhdG9yVG9vbGJhclN1Y2Nlc3MgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIHNob3dNZW50aW9uID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBoYW5kbGVyVGV4dENoYW5nZUJpbmQgPSB0aGlzLmhhbmRsZXJUZXh0Q2hhbmdlLmJpbmQodGhpcyk7XG4gIHByaXZhdGUgaGFuZGxlclNlbGVjdGlvbkNoYW5nZUJpbmQgPSB0aGlzLmhhbmRsZXJTZWxlY3Rpb25DaGFuZ2UuYmluZCh0aGlzKTtcbiAgLy9lbmRyZWdpb25cblxuICAvL3JlZ2lvbiBQcm90ZWN0ZWRcbiAgcHJvdGVjdGVkIGJvcmRlckNvbG9yID0gY29tcHV0ZWQ8c3RyaW5nPigoKSA9PiAodGhpcy5tZXNzYWdlRXJyb3IoKSAmJiB0aGlzLnNob3dFcnJvckJvcmRlcigpID8gJyAhYm9yZGVyLVt2YXIoLS1saWJzLXVpLWNvbG9yLWJvcmRlci1lcnJvciwjZWUyZDQxKV0gJyA6ICchYm9yZGVyLVsjZTVlN2ViXSAnKSk7XG4gIHByb3RlY3RlZCBjb250YWluZXJDbGFzcyA9IGNvbXB1dGVkKCgpID0+IGBxdWlsbC1jb250YWluZXIgZmxleCBmbGV4LWNvbCBoLWZ1bGwgdy1mdWxsICR7Z2V0KHRoaXMucXVpbGxDdXN0b21Db25maWcoKSBhcyBJUXVpbGwyeEN1c3RvbUNvbmZpZywgJ2NsYXNzQ29udGFpbmVyJykgfHwgJyd9YCk7XG4gIHByb3RlY3RlZCBjb250YWluZXJUb29sYmFyQ2xhc3MgPSBjb21wdXRlZChcbiAgICAoKSA9PlxuICAgICAgYGgtZnVsbCBib3JkZXItdCBib3JkZXItbCBib3JkZXItciAke3RoaXMuaWdub3JlU2hvd0JvcmRlckVycm9yVG9vbGJhcigpID8gJyFib3JkZXItWyNlNWU3ZWJdICcgOiB0aGlzLmJvcmRlckNvbG9yKCl9cm91bmRlZC10LVs0cHhdICR7dGhpcy5yZWFkb25seSgpID8gJyBsaWJzLXVpLXJlYWRvbmx5LWJhY2tncm91bmQgY3Vyc29yLWRlZmF1bHQgcG9pbnRlci1ldmVudHMtbm9uZSAgJyA6ICcgJ30gJHtnZXQodGhpcy5xdWlsbEN1c3RvbUNvbmZpZygpIGFzIElRdWlsbDJ4Q3VzdG9tQ29uZmlnLCAndG9vbGJhci5jbGFzc0N1c3RvbUNvbnRhaW5lclRvb2xiYXInKSB8fCAnJ30gJHtnZXQodGhpcy5xdWlsbEN1c3RvbUNvbmZpZygpIGFzIElRdWlsbDJ4Q3VzdG9tQ29uZmlnLCAndG9vbGJhci5wb3NpdGlvbkZpeGVkJykgPyAnIGZpeGVkICcgOiAnICd9YFxuICApO1xuICBwcm90ZWN0ZWQgY29udGFpbmVyRWRpdG9yQ2xhc3MgPSBjb21wdXRlZChcbiAgICAoKSA9PlxuICAgICAgYCR7dGhpcy5kaXNwbGF5RWRpdG9yKCkgPyAnaC1mdWxsJyA6ICdoaWRkZW4nfSAhYm9yZGVyICR7dGhpcy5ib3JkZXJDb2xvcigpfSAhcm91bmRlZC1iLVs0cHhdICR7dGhpcy5yZWFkb25seSgpID8gJyBsaWJzLXVpLXJlYWRvbmx5LWJhY2tncm91bmQgJyA6ICcgJ30gJHtnZXQodGhpcy5xdWlsbEN1c3RvbUNvbmZpZygpIGFzIElRdWlsbDJ4Q3VzdG9tQ29uZmlnLCAnZWRpdG9yLmNsYXNzQ3VzdG9tQ29udGFpbmVyRWRpdG9yJykgfHwgJyd9ICR7Z2V0KHRoaXMucXVpbGxDdXN0b21Db25maWcoKSBhcyBJUXVpbGwyeEN1c3RvbUNvbmZpZywgJ3Rvb2xiYXIucG9zaXRpb25GaXhlZCcpID8gJyByb3VuZGVkLXQtWzRweF0gJyA6ICcgJ31gXG4gICk7XG5cbiAgcHJvdGVjdGVkIHNob3dCdXR0b25Nb3JlVG9vbGJhciA9IGNvbXB1dGVkKCgpID0+IHRoaXMudG9vbGJhck9wdGlvbnNDb25maWcoKS5zb21lKChpdGVtKSA9PiBpdGVtLmRpc3BsYXkgPT09IGZhbHNlKSk7XG4gIHByb3RlY3RlZCBkaXNwbGF5U2tlbGV0b25Ub29sYmFyID0gY29tcHV0ZWQoKCkgPT4gdGhpcy50b29sYmFyT3B0aW9uc0NvbmZpZygpLmV2ZXJ5KChpdGVtKSA9PiBpdGVtLmRpc3BsYXkgPT09IHVuZGVmaW5lZCkpO1xuXG4gIHByb3RlY3RlZCBsYWJlbEZvbnRTZWxlY3RlZENvbXB1dGVkID0gY29tcHV0ZWQoKCkgPT4gZ2V0PHVua25vd24+KHRoaXMuZm9udFNlbGVjdGVkKCksICdpdGVtLmxhYmVsJykgfHwgJ1NhbnMgU2VyaWYnKTtcbiAgcHJvdGVjdGVkIGZvbnRTZWxlY3RlZCA9IHNpZ25hbDxJRW1pdFNlbGVjdEtleSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJvdGVjdGVkIGxpc3RDb25maWdGb250ID0gc2lnbmFsPElMaXN0Q29uZmlnSXRlbT4obGlzdENvbmZpZ0ZvbnQoKSk7XG5cbiAgcHJvdGVjdGVkIGxpc3RDb25maWdIZWFkZXIgPSBzaWduYWw8SUxpc3RDb25maWdJdGVtPihsaXN0Q29uZmlnSGVhZGVyKCkpO1xuICBwcm90ZWN0ZWQgaGVhZGVyU2VsZWN0ZWQgPSBzaWduYWw8SUVtaXRTZWxlY3RLZXkgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByb3RlY3RlZCBsYWJlbEhlYWRlclNlbGVjdGVkQ29tcHV0ZWQgPSBjb21wdXRlZCgoKSA9PiBnZXQ8dW5rbm93bj4odGhpcy5oZWFkZXJTZWxlY3RlZCgpLCAnaXRlbS5sYWJlbCcpIHx8ICdOb3JtYWwnKTtcblxuICBwcm90ZWN0ZWQgbGlzdENvbmZpZ0FsaWduID0gc2lnbmFsPElMaXN0Q29uZmlnSXRlbT4obGlzdENvbmZpZ0FsaWduKCkpO1xuICBwcm90ZWN0ZWQgYWxpZ25TZWxlY3RlZCA9IHNpZ25hbDxJRW1pdFNlbGVjdEtleSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJvdGVjdGVkIGljb25BbGlnblNlbGVjdGVkQ29tcHV0ZWQgPSBjb21wdXRlZCgoKSA9PiBnZXQodGhpcy5hbGlnblNlbGVjdGVkKCkgYXMgdW5rbm93biwgJ2l0ZW0uaWNvbicpKTtcblxuICBwcm90ZWN0ZWQgY29sb3JTZWxlY3RlZCA9IHNpZ25hbDxzdHJpbmcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByb3RlY3RlZCBiYWNrZ3JvdW5kU2VsZWN0ZWQgPSBzaWduYWw8c3RyaW5nIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcm90ZWN0ZWQgbGlzdENoZWNrYm94U2VsZWN0ZWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgYWRqdXN0U2VsZWN0ZWQgPSBzaWduYWw8c3RyaW5nIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG4gIHByb3RlY3RlZCBtZXNzYWdlRXJyb3IgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHByb3RlY3RlZCBmb250U2l6ZSA9IHNpZ25hbDx7IHZhbHVlOiBudW1iZXIgfT4oeyB2YWx1ZTogMTQgfSk7XG4gIHByb3RlY3RlZCBsaW5rID0gc2lnbmFsPElRdWlsbDJ4TGluaz4obGlua0RlZmF1bHQoKSk7XG5cbiAgcHJvdGVjdGVkIHNob3dNb3JlQWN0aW9uID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIHRvb2xiYXJPcHRpb25zQ29uZmlnOiBXcml0YWJsZVNpZ25hbDxBcnJheTxJUXVpbGwyeFRvb2xiYXJDb25maWc+PiA9IHNpZ25hbChbXSk7XG5cbiAgcHJvdGVjdGVkIGxvYWRpbmdVcGxvYWRJbWFnZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IHVwbG9hZEltYWdlQ29uZmlnID0gaW5wdXQ8SVF1aWxsMnhVcGxvYWRJbWFnZUNvbmZpZywgSVF1aWxsMnhVcGxvYWRJbWFnZUNvbmZpZyB8IHVuZGVmaW5lZD4odXBsb2FkSW1hZ2VDb25maWdEZWZhdWx0KCksIHsgdHJhbnNmb3JtOiAodmFsdWUpID0+IHZhbHVlIHx8IHVwbG9hZEltYWdlQ29uZmlnRGVmYXVsdCgpIH0pO1xuXG4gIC8vcmVnaW9uIElucHV0c1xuICByZWFkb25seSBkaXNwbGF5VG9vbGJhciA9IGlucHV0PGJvb2xlYW4sIGJvb2xlYW4gfCB1bmRlZmluZWQ+KHRydWUsIHsgdHJhbnNmb3JtOiAodmFsdWUpID0+IHZhbHVlID8/IHRydWUgfSk7XG5cbiAgcmVhZG9ubHkgcGxhY2Vob2xkZXIgPSBpbnB1dDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4oJ2kxOG5faW1wb3J0X2NvbnRlbnQnLCB7IHRyYW5zZm9ybTogKHZhbHVlKSA9PiB2YWx1ZSB8fCAnaTE4bl9pbXBvcnRfY29udGVudCcgfSk7XG4gIHJlYWRvbmx5IGJsb3RzUmVnaXN0ZXIgPSBpbnB1dDxBcnJheTxJUXVpbGwyeEJsb3RSZWdpc3Rlcj4+KCk7XG4gIHJlYWRvbmx5IHJlYWRvbmx5ID0gaW5wdXQ8Ym9vbGVhbiwgYm9vbGVhbiB8IHVuZGVmaW5lZD4oZmFsc2UsIHsgdHJhbnNmb3JtOiAodmFsdWUpID0+IHZhbHVlID8/IGZhbHNlIH0pO1xuICByZWFkb25seSBxdWlsbEN1c3RvbUNvbmZpZyA9IGlucHV0PElRdWlsbDJ4Q3VzdG9tQ29uZmlnPigpO1xuXG4gIHJlYWRvbmx5IGxhYmVsID0gaW5wdXQ8SUxhYmVsIHwgdW5kZWZpbmVkPigpO1xuICByZWFkb25seSBpdGVtID0gbW9kZWwucmVxdWlyZWQ8VFlQRV9PQkpFQ1Q+KCk7XG4gIHJlYWRvbmx5IGZpZWxkQmluZCA9IGlucHV0LnJlcXVpcmVkPHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgYXV0b1VwZGF0ZVZhbHVlV2hlblRleHRDaGFuZ2UgPSBpbnB1dDxib29sZWFuLCBib29sZWFuIHwgdW5kZWZpbmVkPih0cnVlLCB7IHRyYW5zZm9ybTogKHZhbHVlKSA9PiB2YWx1ZSA/PyB0cnVlIH0pO1xuXG4gIHJlYWRvbmx5IGRhdGFDb25maWdNZW50aW9uID0gaW5wdXQ8SU1lbnRpb25Db25maWc+KCk7XG4gIHJlYWRvbmx5IHRlbXBsYXRlVG9vbEJhclBlcnNvbmFsaXplID0gaW5wdXQ8VGVtcGxhdGVSZWY8VFlQRV9URU1QTEFURV9SRUY+PigpO1xuXG4gIHJlYWRvbmx5IHpJbmRleCA9IGlucHV0PG51bWJlciwgbnVtYmVyIHwgdW5kZWZpbmVkPigxMjUwLCB7IHRyYW5zZm9ybTogKHZhbHVlKSA9PiB2YWx1ZSA/PyAxMjUwIH0pO1xuICByZWFkb25seSBpZ25vcmVTaG93UG9wdXBFZGl0TGluayA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGlnbm9yZUNvbW11bmljYXRlTWljcm9FdmVudFBvcHVwID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgaGFuZGxlcnNFeHBhbmQgPSBpbnB1dDxBcnJheTx7IHRpdGxlOiBzdHJpbmc7IGFjdGlvbjogKCkgPT4gdm9pZCB9Pj4oKTtcbiAgcmVhZG9ubHkgcmVzaXplSW1hZ2VQbHVnaW4gPSBpbnB1dDxib29sZWFuPigpO1xuXG4gIHJlYWRvbmx5IGZvbnRTaXplRGVmYXVsdCA9IGlucHV0PG51bWJlciwgbnVtYmVyIHwgdW5kZWZpbmVkPigxNCwgeyB0cmFuc2Zvcm06ICh2YWx1ZSkgPT4gdmFsdWUgPz8gMTQgfSk7XG4gIHJlYWRvbmx5IGhlaWdodEVkaXRvckNvbnRlbnREZWZhdWx0ID0gaW5wdXQ8bnVtYmVyPigpO1xuICByZWFkb25seSBtaW5IZWlnaHRFZGl0b3JDb250ZW50RGVmYXVsdCA9IGlucHV0PG51bWJlcj4oKTtcbiAgcmVhZG9ubHkgbWF4SGVpZ2h0RWRpdG9yQ29udGVudERlZmF1bHQgPSBpbnB1dDxudW1iZXI+KCk7XG5cbiAgcmVhZG9ubHkgcmVtb3ZlTmVhcldoaXRlQ29sb3JzT25QYXN0ZSA9IGlucHV0PGJvb2xlYW4+KHRydWUpO1xuXG4gIHJlYWRvbmx5IHJlc2l6ZSA9IGlucHV0PCd2ZXJ0aWNhbCcgfCAnbm9uZScsICd2ZXJ0aWNhbCcgfCAnbm9uZScgfCB1bmRlZmluZWQ+KCdub25lJywgeyB0cmFuc2Zvcm06ICh2YWx1ZSkgPT4gdmFsdWUgPz8gJ25vbmUnIH0pO1xuICByZWFkb25seSBhdXRvRm9jdXMgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBmb2N1c1RpbWVyT25Jbml0ID0gaW5wdXQ8bnVtYmVyLCBudW1iZXIgfCB1bmRlZmluZWQ+KDc1MCwgeyB0cmFuc2Zvcm06ICh2YWx1ZSkgPT4gdmFsdWUgPz8gNzUwIH0pO1xuICByZWFkb25seSBmb2N1c0JvdHRvbSA9IGlucHV0PGJvb2xlYW4+KCk7XG5cbiAgcmVhZG9ubHkgdmFsaWRSZXF1aXJlZCA9IGlucHV0PElWYWxpZFJlcXVpcmVkPigpO1xuICByZWFkb25seSB2YWxpZE1pbkxlbmd0aCA9IGlucHV0PElWYWxpZExlbmd0aD4oKTtcbiAgcmVhZG9ubHkgdmFsaWRNYXhMZW5ndGggPSBpbnB1dDxJVmFsaWRMZW5ndGg+KCk7XG4gIHJlYWRvbmx5IHNob3dFcnJvckxhYmVsID0gaW5wdXQ8Ym9vbGVhbiwgYm9vbGVhbiB8IHVuZGVmaW5lZD4odHJ1ZSwgeyB0cmFuc2Zvcm06ICh2YWwpID0+IHZhbCA/PyB0cnVlIH0pO1xuICByZWFkb25seSBzaG93RXJyb3JCb3JkZXIgPSBpbnB1dDxib29sZWFuIHwgdW5kZWZpbmVkPih0cnVlKTtcbiAgcmVhZG9ubHkgaWdub3JlU2hvd0JvcmRlckVycm9yVG9vbGJhciA9IGlucHV0PGJvb2xlYW4+KCk7XG5cbiAgLy9lbmRyZWdpb25cblxuICAvL3JlZ2lvbiBPdXRwdXRzXG4gIHJlYWRvbmx5IG91dFNob3dQb3B1cEVkaXRMaW5rID0gb3V0cHV0PHtcbiAgICBkYXRhTGluazogSVF1aWxsMnhMaW5rO1xuICAgIGNhbGxiYWNrOiAobGlua0VkaXQ6IHsgdGl0bGU6IHN0cmluZzsgbGluazogc3RyaW5nIH0pID0+IFByb21pc2U8dm9pZD47XG4gIH0+KCk7XG4gIHJlYWRvbmx5IG91dE1lc3NhZ2VFcnJvciA9IG91dHB1dDxzdHJpbmc+KCk7XG4gIHJlYWRvbmx5IG91dEJsdXIgPSBvdXRwdXQ8dm9pZD4oKTtcbiAgcmVhZG9ubHkgb3V0Rm9jdXMgPSBvdXRwdXQ8dm9pZD4oKTtcbiAgcmVhZG9ubHkgb3V0Q2hhbmdlID0gb3V0cHV0PHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgb3V0U2VsZWN0aW9uQ2hhbmdlID0gb3V0cHV0PElRdWlsbDJ4U2VsZWN0aW9uQ2hhbmdlPigpO1xuICByZWFkb25seSBvdXRUZXh0Q2hhbmdlID0gb3V0cHV0PElRdWlsbDJ4VGV4dENoYW5nZT4oKTtcbiAgcmVhZG9ubHkgb3V0Q29udGV4dE1lbnUgPSBvdXRwdXQ8TW91c2VFdmVudD4oKTtcbiAgcmVhZG9ubHkgb3V0RnVuY3Rpb25zQ29udHJvbCA9IG91dHB1dDxJUXVpbGwyeEZ1bmN0aW9uQ29udHJvbEV2ZW50PigpO1xuICAvL2VuZHJlZ2lvblxuXG4gIC8vcmVnaW9uIFZpZXdDaGlsZFxuICBwcml2YXRlIHJlYWRvbmx5IGh0bWxDb250YWluZXIgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD4+KCdodG1sQ29udGFpbmVyJyk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVpbGxCb2R5Q29udGFpbmVyID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+Pignc25vd0NvbnRhaW5lcicpO1xuICBwcml2YXRlIHJlYWRvbmx5IHRvb2xiYXJDb250YWluZXIgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD4+KCd0b29sYmFyQ29udGFpbmVyJyk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5wdXRMaW5rUmVmID0gdmlld0NoaWxkLnJlcXVpcmVkPExpYnNVaUNvbXBvbmVudHNQb3BvdmVyQ29tcG9uZW50PignaW5wdXRMaW5rUmVmJyk7XG4gIC8vZW5kcmVnaW9uXG5cbiAgLy9yZWdpb24gSW5qZWN0XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBub3RpZmljYXRpb25TZXJ2aWNlID0gaW5qZWN0KExpYnNVaU5vdGlmaWNhdGlvblNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0ZSA9IGluamVjdChUcmFuc2xhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGR5bmFtaWNDb21wb25lbnRTZXJ2aWNlID0gaW5qZWN0KExpYnNVaUR5bmFtaWNDb21wb25lbnRTZXJ2aWNlKTtcbiAgLy9lbmRyZWdpb25cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuZm9udFNpemVEZWZhdWx0KCkpIHtcbiAgICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmZvbnRTaXplLnNldCh7IHZhbHVlOiB0aGlzLmZvbnRTaXplRGVmYXVsdCgpIH0pO1xuICAgICAgICAgIHRoaXMuaGFuZGxlclZhbHVlQ2hhbmdlRm9udFNpemUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgZWxlbWVudEVkaXRvciA9IHRoaXMucXVpbGxCb2R5Q29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdxbC1lZGl0b3InKT8uWzBdIGFzIEhUTUxFbGVtZW50O1xuICAgICAgaWYgKHRoaXMuaGVpZ2h0RWRpdG9yQ29udGVudERlZmF1bHQoKSkge1xuICAgICAgICB1bnRyYWNrZWQoKCkgPT4ge1xuICAgICAgICAgIGlmIChlbGVtZW50RWRpdG9yKSB7XG4gICAgICAgICAgICBlbGVtZW50RWRpdG9yLnN0eWxlLmhlaWdodCA9IGAke3RoaXMuaGVpZ2h0RWRpdG9yQ29udGVudERlZmF1bHQoKX1weGA7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm1pbkhlaWdodEVkaXRvckNvbnRlbnREZWZhdWx0KCkpIHtcbiAgICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgICBpZiAoZWxlbWVudEVkaXRvcikge1xuICAgICAgICAgICAgZWxlbWVudEVkaXRvci5zdHlsZS5taW5IZWlnaHQgPSBgJHt0aGlzLm1pbkhlaWdodEVkaXRvckNvbnRlbnREZWZhdWx0KCl9cHhgO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5tYXhIZWlnaHRFZGl0b3JDb250ZW50RGVmYXVsdCgpKSB7XG4gICAgICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICAgICAgaWYgKGVsZW1lbnRFZGl0b3IpIHtcbiAgICAgICAgICAgIGVsZW1lbnRFZGl0b3Iuc3R5bGUubWF4SGVpZ2h0ID0gYCR7dGhpcy5tYXhIZWlnaHRFZGl0b3JDb250ZW50RGVmYXVsdCgpfXB4YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgbmdPbkluaXQoKSB7XG4gICAgY29uc3QgdHlwZSA9IGdldCh0aGlzLnF1aWxsQ3VzdG9tQ29uZmlnKCkgYXMgSVF1aWxsMnhDdXN0b21Db25maWcsICd0b29sYmFyLnR5cGUnLCAnZGVmYXVsdCcpIGFzIFFVSUxMMlhfVFlQRV9NT0RFX0JBUl9DT05GSUdfT1BUSU9OO1xuICAgIGNvbnN0IGhhc0ljb25JbWFnZSA9IHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKS5zaG93SWNvbiA/PyBmYWxzZTtcbiAgICBjb25zdCBoYXNJY29uUGVyc29uYWxpemUgPSAhIXRoaXMudGVtcGxhdGVUb29sQmFyUGVyc29uYWxpemUoKTtcbiAgICB0aGlzLnRvb2xiYXJPcHRpb25zQ29uZmlnLnNldChnZXQodGhpcy5xdWlsbEN1c3RvbUNvbmZpZygpIGFzIElRdWlsbDJ4Q3VzdG9tQ29uZmlnLCAndG9vbGJhci5vcHRpb25zJywgdG9vbEJhck9wdGlvbnModHlwZSwgaGFzSWNvbkltYWdlLCBoYXNJY29uUGVyc29uYWxpemUpKSk7XG5cbiAgICB0aGlzLmNhbGN1bGF0b3JUb29sYmFyKCk7XG4gICAgcmVnaXN0ZXJRdWlsbDJ4KCk7XG4gICAgdGhpcy5ibG90c1JlZ2lzdGVyKCk/LmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIFF1aWxsMngucmVnaXN0ZXIoaXRlbS5jb21wb25lbnQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGVIYW5kbGVyRnVuY3Rpb24oKTtcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICB0aGVtZTogJ3Nub3cnLFxuICAgICAgcGxhY2Vob2xkZXI6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQodGhpcy5wbGFjZWhvbGRlcigpKSxcbiAgICAgIHJlYWRPbmx5OiB0aGlzLnJlYWRvbmx5KCksXG4gICAgICBtb2R1bGVzOiB7XG4gICAgICAgIHRvb2xiYXI6IHtcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMudG9vbGJhckNvbnRhaW5lcigpLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgaGFuZGxlcnM6IHRoaXMuaGFuZGxlcnMoKSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzaXplOiB0aGlzLnJlc2l6ZUltYWdlUGx1Z2luKClcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgbG9jYWxlOiB7XG4gICAgICAgICAgICAgICAgYWx0VGlwOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdpMThuX2tlZXBfYWx0X2tleV90b19jaGFuZ2VfdGhlX3JhdGlvX3doZW5fY2hhbmdpbmdfdGhlX3NpemUnKSxcbiAgICAgICAgICAgICAgICBpbnB1dFRpcDogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnaTE4bl9wcmVzc19lbnRlcl90b19jb25maXJtJyksXG4gICAgICAgICAgICAgICAgZmxvYXRMZWZ0OiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdpMThuX2xlZnRfYWxpZ24nKSxcbiAgICAgICAgICAgICAgICBmbG9hdFJpZ2h0OiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdpMThuX3JpZ2h0X2FsaWduJyksXG4gICAgICAgICAgICAgICAgY2VudGVyOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdpMThuX2NlbnRlcl9hbGlnbicpLFxuICAgICAgICAgICAgICAgIHJlc3RvcmU6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ2kxOG5fcmVzdG9yZV90b19kZWZhdWx0JyksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgIHRhYmxlOiB0cnVlLFxuICAgICAgICBjbGlwYm9hcmQ6IHtcbiAgICAgICAgICBtYXRjaGVyczogW1xuICAgICAgICAgICAgW05vZGUuVEVYVF9OT0RFLCAobm9kZTogeyBkYXRhOiBzdHJpbmcgfSkgPT4gbmV3IERlbHRhKCkuaW5zZXJ0KG5vZGUuZGF0YSldLFxuICAgICAgICAgICAgdGhpcy5yZW1vdmVOZWFyV2hpdGVDb2xvcnNPblBhc3RlKClcbiAgICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgICBOb2RlLkVMRU1FTlRfTk9ERSxcbiAgICAgICAgICAgICAgICAgIChub2RlOiBIVE1MRWxlbWVudCwgZGVsdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHlsZSA9IG5vZGUuZ2V0QXR0cmlidXRlKCdzdHlsZScpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUgJiYgdGhpcy5pc1Bhc3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdPcHMgPSBkZWx0YS5vcHMubWFwKChvcDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3AuYXR0cmlidXRlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdBdHRycyA9IHsgLi4ub3AuYXR0cmlidXRlcyB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2xvciA9IG5ld0F0dHJzLmNvbG9yIGFzIHN0cmluZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmFja2dyb3VuZCA9IG5ld0F0dHJzLmJhY2tncm91bmQgYXMgc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xvciAmJiBpc05lYXJXaGl0ZShjb2xvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgbmV3QXR0cnMuY29sb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFja2dyb3VuZCAmJiBpc05lYXJXaGl0ZShiYWNrZ3JvdW5kKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBuZXdBdHRycy5iYWNrZ3JvdW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4ub3AsIGF0dHJpYnV0ZXM6IE9iamVjdC5rZXlzKG5ld0F0dHJzKS5sZW5ndGggPyBuZXdBdHRycyA6IHVuZGVmaW5lZCB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wO1xuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEZWx0YShuZXdPcHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWx0YTtcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICA6IFtdLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIGtleWJvYXJkOiB7XG4gICAgICAgICAgYmluZGluZ3M6IHtcbiAgICAgICAgICAgIGJhY2tzcGFjZToge1xuICAgICAgICAgICAgICBrZXk6IFV0aWxzS2V5Q29kZUNvbnN0YW50LkJBQ0tTUEFDRSxcbiAgICAgICAgICAgICAgaGFuZGxlcjogKHJhbmdlOiBSYW5nZSkgPT4gdGhpcy5ub1ByZXZlbnRFbWJlZERlbGV0aW9uKHJhbmdlKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZWxldGU6IHtcbiAgICAgICAgICAgICAga2V5OiBVdGlsc0tleUNvZGVDb25zdGFudC5ERUxFVEUsXG4gICAgICAgICAgICAgIGhhbmRsZXI6IChyYW5nZTogUmFuZ2UpID0+IHRoaXMubm9QcmV2ZW50RW1iZWREZWxldGlvbihyYW5nZSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZW50ZXI6IHtcbiAgICAgICAgICAgICAga2V5OiAxMyxcbiAgICAgICAgICAgICAgaGFuZGxlcjogKCkgPT4gKHRoaXMuc2hvd01lbnRpb24oKSA/IGZhbHNlIDogdHJ1ZSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBkZWxheTogMjAwMCxcbiAgICAgICAgICBtYXhTdGFjazogNTAwLFxuICAgICAgICAgIHVzZXJPbmx5OiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9IGFzIGNvbnN0O1xuXG4gICAgdGhpcy5xdWlsbCA9IG5ldyBRdWlsbDJ4KHRoaXMucXVpbGxCb2R5Q29udGFpbmVyKCkubmF0aXZlRWxlbWVudCwgb3B0aW9ucyk7XG4gICAgdGhpcy5xdWlsbD8ub24oJ3RleHQtY2hhbmdlJywgdGhpcy5oYW5kbGVyVGV4dENoYW5nZUJpbmQpO1xuICAgIHRoaXMucXVpbGw/Lm9uKCdzZWxlY3Rpb24tY2hhbmdlJywgdGhpcy5oYW5kbGVyU2VsZWN0aW9uQ2hhbmdlQmluZCk7XG5cbiAgICBmcm9tRXZlbnQ8Q2xpcGJvYXJkRXZlbnQ+KHRoaXMucXVpbGw/LnJvb3QsICdjb3B5JykucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKHRoaXMuaGFuZGxlckNvcHkuYmluZCh0aGlzKSk7XG4gICAgZnJvbUV2ZW50PENsaXBib2FyZEV2ZW50Pih0aGlzLnF1aWxsPy5yb290LCAncGFzdGUnLCB7IGNhcHR1cmU6IHRydWUgfSkucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKHRoaXMuaGFuZGxlclBhc3RlLmJpbmQodGhpcykpO1xuICAgIGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLnF1aWxsQm9keUNvbnRhaW5lcigpPy5uYXRpdmVFbGVtZW50LCAnY29udGV4dG1lbnUnKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChlKSA9PiB0aGlzLm91dENvbnRleHRNZW51LmVtaXQoZSkpO1xuICAgIGZyb21FdmVudDxNb3VzZUV2ZW50Pih3aW5kb3csICdyZXNpemUnKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuY2FsY3VsYXRvclRvb2xiYXIodHJ1ZSkpO1xuXG4gICAgdGhpcy5vdXRGdW5jdGlvbnNDb250cm9sLmVtaXQodGhpcy5GdW5jdGlvbnNDb250cm9sKTtcbiAgICBhd2FpdCB0aGlzLnNldENvbnRlbnQodGhpcy5pdGVtKClbdGhpcy5maWVsZEJpbmQoKV0gYXMgc3RyaW5nKTtcblxuICAgIHRpbWVyKHRoaXMuYXV0b0ZvY3VzKCkgPyAwIDogMjUwKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuZGlzcGxheUVkaXRvci5zZXQodHJ1ZSkpO1xuXG4gICAgdGhpcy5zZXRTdHlsZUZvckNvbnRlbnQoKTtcblxuICAgIGlmICh0aGlzLmF1dG9Gb2N1cygpKSB7XG4gICAgICB0aW1lcih0aGlzLmZvY3VzVGltZXJPbkluaXQoKSArIDI1MClcbiAgICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5mb2N1cygpKTtcbiAgICB9XG4gICAgY3JlYXRlQ29udGV4dE1lbnVPcHRpb25UYWJsZSh0aGlzLnF1aWxsIGFzIFF1aWxsMngsIHRoaXMudHJhbnNsYXRlKTtcbiAgICBlbmFibGVUYWJsZVNlbGVjdGlvbih0aGlzLnF1aWxsLnJvb3QpO1xuICAgIGdldEFsbFRhYmxlc1dpdGhTcGFuKHRoaXMucXVpbGwpO1xuXG4gICAgY29uc3Qgcm9vdEVsZW1lbnQgPSB0aGlzLnF1aWxsPy5yb290O1xuICAgIGlmICghcm9vdEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBtZXJnZShmcm9tRXZlbnQocm9vdEVsZW1lbnQsICdjb21wb3NpdGlvbnN0YXJ0JyksIGZyb21FdmVudChyb290RWxlbWVudCwgJ2NvbXBvc2l0aW9uZW5kJykpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgICAgaWYgKGUudHlwZSA9PT0gJ2NvbXBvc2l0aW9uc3RhcnQnKSB7XG4gICAgICAgICAgcm9vdEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgncWwtYmxhbmsnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRW1wdHlRdWlsbDJ4KHRoaXMucXVpbGwpKSB7XG4gICAgICAgICAgcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgncWwtYmxhbmsnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcm9vdEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgncWwtYmxhbmsnKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldCBGdW5jdGlvbnNDb250cm9sKCk6IElRdWlsbDJ4RnVuY3Rpb25Db250cm9sRXZlbnQge1xuICAgIHJldHVybiB7XG4gICAgICBxdWlsbDogKCkgPT4gdGhpcy5xdWlsbCBhcyBRdWlsbDJ4LFxuICAgICAgY2hlY2tJc1ZhbGlkOiB0aGlzLnZhbGlkYXRlLmJpbmQodGhpcyksXG4gICAgICByZWZyZXNoSXRlbVZhbHVlOiB0aGlzLnVwZGF0ZVZhbHVlQnlSb290UXVpbGxIdG1sLmJpbmQodGhpcyksXG4gICAgICBzZXRDb250ZW50OiB0aGlzLnNldENvbnRlbnQuYmluZCh0aGlzKSxcbiAgICAgIGluc2VydFRleHQ6IHRoaXMuaW5zZXJ0VGV4dC5iaW5kKHRoaXMpLFxuICAgICAgaW5zZXJ0TGluazogdGhpcy5pbnNlcnRMaW5rLmJpbmQodGhpcyksXG4gICAgICBpbnNlcnRJbWFnZTogdGhpcy5pbnNlcnRJbWFnZS5iaW5kKHRoaXMpLFxuICAgICAgc2V0Rm9udFNpemU6IGFzeW5jIChzaXplOiBudW1iZXIpID0+IHRoaXMucXVpbGw/LmZvcm1hdCgnc2l6ZScsIGAke3NpemV9cHhgKSxcbiAgICAgIHNldENvbG9yOiBhc3luYyAoY29sb3I6IHN0cmluZykgPT4gdGhpcy5xdWlsbD8uZm9ybWF0KCdjb2xvcicsIGNvbG9yKSxcbiAgICAgIHNldEJhY2tncm91bmQ6IGFzeW5jIChjb2xvcjogc3RyaW5nKSA9PiB0aGlzLnF1aWxsPy5mb3JtYXQoJ2JhY2tncm91bmQnLCBjb2xvciksXG4gICAgICBzZXRNZXNzYWdlRXJyb3I6IGFzeW5jIChtZXNzYWdlOiBzdHJpbmcpID0+IHRoaXMubWVzc2FnZUVycm9yLnNldChtZXNzYWdlKSxcbiAgICAgIHJlQ2FsY3VsYXRvclRvb2xiYXI6IGFzeW5jICgpID0+IHRoaXMuY2FsY3VsYXRvclRvb2xiYXIodHJ1ZSksXG4gICAgfTtcbiAgfVxuXG4gIC8vcmVnaW9uIGhhbmRsZXIgRXZlbnQgSFRNTFxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ2hhbmdlU2hvd01vcmVBY3Rpb24oZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zaG93TW9yZUFjdGlvbi51cGRhdGUoKHNob3dNb3JlQWN0aW9uKSA9PiAhc2hvd01vcmVBY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZVNlbGVjdEZvbnQoZXZlbnQ6IElFbWl0U2VsZWN0S2V5IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5mb250U2VsZWN0ZWQuc2V0KGV2ZW50KTtcbiAgICB0aGlzLnF1aWxsPy5mb3JtYXQoJ2ZvbnQnLCBldmVudD8ua2V5IGFzIHN0cmluZyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlU2VsZWN0SGVhZGVyKGV2ZW50OiBJRW1pdFNlbGVjdEtleSB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuaGVhZGVyU2VsZWN0ZWQuc2V0KGV2ZW50KTtcbiAgICB0aGlzLnF1aWxsPy5mb3JtYXQoJ2hlYWRlcicsIGV2ZW50Py5rZXkgYXMgc3RyaW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyVmFsdWVDaGFuZ2VGb250U2l6ZShldmVudD86IElGb2N1c0FuZEJsdXJFdmVudCkge1xuICAgIGlmICghZXZlbnQgfHwgZXZlbnQ/Lm5hbWUgPT09ICdibHVyJykge1xuICAgICAgdGhpcy5xdWlsbD8uZm9ybWF0KCdzaXplJywgYCR7dGhpcy5mb250U2l6ZSgpLnZhbHVlfXB4YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZVNlbGVjdEFsaWduKGV2ZW50OiBJRW1pdFNlbGVjdEtleSB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuYWxpZ25TZWxlY3RlZC5zZXQoZXZlbnQpO1xuICAgIHRoaXMucXVpbGw/LmZvcm1hdCgnYWxpZ24nLCBldmVudD8ua2V5IGFzIHN0cmluZyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclNldEZvcm1hdCh0eXBlOiBzdHJpbmcsIGRhdGE6IElPdXRwdXRDb2xvckNoYW5nZU11bHRpcGxlVHlwZSkge1xuICAgIGlmICghZGF0YS5hbHBoYSkge1xuICAgICAgdGhpcy5xdWlsbD8uZm9ybWF0KHR5cGUsIHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucXVpbGw/LmZvcm1hdCh0eXBlLCBkYXRhLmhleCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlckluc2VydEVtb2ppKGVtb2ppOiB1bmtub3duKSB7XG4gICAgdGhpcy5pbnNlcnRUZXh0KGVtb2ppIGFzIHN0cmluZywgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyVW5saW5rKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGxpbmsgPSB0aGlzLmxpbmsoKTtcbiAgICB0aGlzLnF1aWxsPy5mb3JtYXRUZXh0KGxpbmsucmFuZ2UuaW5kZXgsIGxpbmsucmFuZ2UubGVuZ3RoLCB7IGxpbms6IGZhbHNlIH0pO1xuICAgIHRoaXMuaW5wdXRMaW5rUmVmKCkuRnVuY3Rpb25zQ29udHJvbD8ucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyRWRpdExpbmsoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgbGluayA9IHRoaXMubGluaygpO1xuICAgIGlmICh0aGlzLmlnbm9yZVNob3dQb3B1cEVkaXRMaW5rKCkpIHtcbiAgICAgIHRoaXMub3V0U2hvd1BvcHVwRWRpdExpbmsuZW1pdCh7XG4gICAgICAgIGRhdGFMaW5rOiBsaW5rLFxuICAgICAgICBjYWxsYmFjazogYXN5bmMgKGxpbmtFZGl0OiB7IHRpdGxlOiBzdHJpbmc7IGxpbms6IHN0cmluZyB9KSA9PiB7XG4gICAgICAgICAgaWYgKGxpbmsgaW5zdGFuY2VvZiBPYmplY3QgJiYgbGluay51cmwpIHtcbiAgICAgICAgICAgIHRoaXMucXVpbGw/LmRlbGV0ZVRleHQobGluay5yYW5nZS5pbmRleCwgbGluay5yYW5nZS5sZW5ndGgsIFF1aWxsMnguc291cmNlcy5VU0VSKTtcbiAgICAgICAgICAgIHRoaXMucXVpbGw/Lmluc2VydFRleHQobGluay5yYW5nZS5pbmRleCwgbGlua0VkaXQudGl0bGUsICdsaW5rJywgbGlua0VkaXQubGluayk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuaW5zZXJ0TGluayhsaW5rRWRpdC50aXRsZSwgbGlua0VkaXQubGluayk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5oYW5kbGVTaG93VXBsb2FkTGluayhsaW5rKTtcbiAgICB0aGlzLmlucHV0TGlua1JlZigpLkZ1bmN0aW9uc0NvbnRyb2w/LnJlbW92ZVBvcG92ZXJPdmVybGF5KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlVG9nZ2xlTWVudGlvbihzaG93OiBib29sZWFuKSB7XG4gICAgdGhpcy5zaG93TWVudGlvbi5zZXQoc2hvdyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlckluc2VydE1lbnRpb24oZGF0YTogSU1lbnRpb25JbnNlcnQpIHtcbiAgICB0aGlzLmluc2VydE1lbnRpb24oZGF0YSk7XG4gIH1cblxuICAvL2VuZHJlZ2lvblxuXG4gIC8vcmVnaW9uIFByaXZhdGUgTWV0aG9kXG5cbiAgLy9yZWdpb24gUXVpbGwgTWV0aG9kc1xuICBwcml2YXRlIGhhbmRsZVRhYmxlKCkge1xuICAgIGNvbnN0IGJ1dHRvbiA9IHRoaXMuaHRtbENvbnRhaW5lcigpLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3Rvcj8uKCdidXR0b24ucWwtdGFibGUnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgY3JlYXRlVGFibGVTZWxlY3Rvcih0aGlzLnF1aWxsIGFzIFF1aWxsMngsIGJ1dHRvbiwgdGhpcy50cmFuc2xhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVVbmRvKCkge1xuICAgIHRoaXMucXVpbGw/Lmhpc3Rvcnk/LnVuZG8oKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlUmVkbygpIHtcbiAgICB0aGlzLnF1aWxsPy5oaXN0b3J5Py5yZWRvKCk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJTaG93VXBsb2FkSW1hZ2UoKSB7XG4gICAgaWYgKHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKS5tb2RlQ3VzdG9tKSB7XG4gICAgICB0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmLnNldCh0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbFVwbG9hZEltYWdlQ29tcG9uZW50KSk7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMudXBsb2FkSW1hZ2VDb21wb25lbnRSZWYoKT8uaW5zdGFuY2U7XG4gICAgICB0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCk/LnNldElucHV0KCd1cGxvYWRJbWFnZUNvbmZpZycsIHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKSk7XG4gICAgICB0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCk/LnNldElucHV0KCdpZ25vcmVDb21tdW5pY2F0ZU1pY3JvRXZlbnQnLCB0aGlzLmlnbm9yZUNvbW11bmljYXRlTWljcm9FdmVudFBvcHVwKCkpO1xuICAgICAgaW5zdGFuY2U/Lm91dENsb3NlLnN1YnNjcmliZSgobGluazogc3RyaW5nIHwgdm9pZCkgPT4ge1xuICAgICAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCkpO1xuICAgICAgICBpZiAobGluaykge1xuICAgICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2UobGluayk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5hZGRUb0JvZHkodGhpcy51cGxvYWRJbWFnZUNvbXBvbmVudFJlZigpKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnZmlsZScpO1xuICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnYWNjZXB0JywgJ2ltYWdlLyonKTtcbiAgICBpbnB1dC5jbGljaygpO1xuICAgIGlucHV0Lm9uY2hhbmdlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZXNBbmRJbnNlcnQoaW5wdXQ/LmZpbGVzKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbnNlcnRUZXh0KGNvbnRlbnQ6IHN0cmluZywgaW5kZXg/OiBudW1iZXIsIGZvY3VzTGFzdFZhbHVlSW5zZXJ0PzogYm9vbGVhbikge1xuICAgIGluZGV4ID0gaW5kZXggPz8gdGhpcy5xdWlsbD8uZ2V0U2VsZWN0aW9uKHRydWUpLmluZGV4O1xuICAgIGlmICghaXNOaWwoaW5kZXgpKSB7XG4gICAgICB0aGlzLnF1aWxsPy5pbnNlcnRUZXh0KGluZGV4LCBjb250ZW50LCBRdWlsbDJ4LnNvdXJjZXMuVVNFUik7XG4gICAgICBpZiAoZm9jdXNMYXN0VmFsdWVJbnNlcnQpIHtcbiAgICAgICAgYXdhaXQgbGFzdFZhbHVlRnJvbSh0aW1lcigwKSk7XG4gICAgICAgIHRoaXMucXVpbGw/LnNldFNlbGVjdGlvbihpbmRleCArIGNvbnRlbnQubGVuZ3RoLCAwLCBRdWlsbDJ4LnNvdXJjZXMuVVNFUik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyU2VsZWN0aW9uQ2hhbmdlKHJhbmdlOiBSYW5nZSwgb2xkUmFuZ2U6IFJhbmdlLCBzb3VyY2U6IEVtaXR0ZXJTb3VyY2UpIHtcbiAgICBpZiAodGhpcy5yZWFkb25seSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyYW5nZSA9PT0gbnVsbCAmJiBvbGRSYW5nZSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5vdXRCbHVyLmVtaXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHJhbmdlICE9PSBudWxsICYmIG9sZFJhbmdlID09PSBudWxsKSB7XG4gICAgICB0aGlzLm91dEZvY3VzLmVtaXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtYXQgPSB0aGlzLnVwZGF0ZVN0YXRlVG9vbGJhckJ5Rm9ybWF0SW5DdXJzb3IoKTtcbiAgICB0aGlzLm91dFNlbGVjdGlvbkNoYW5nZS5lbWl0KHtcbiAgICAgIHF1aWxsOiB0aGlzLnF1aWxsIGFzIFF1aWxsMngsXG4gICAgICByYW5nZSxcbiAgICAgIG9sZFJhbmdlLFxuICAgICAgc291cmNlLFxuICAgIH0pO1xuXG4gICAgaWYgKHJhbmdlLmxlbmd0aCAhPT0gMCB8fCAhZm9ybWF0Py5saW5rIHx8IHNvdXJjZSAhPT0gJ3VzZXInKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7XG4gICAgY29uc3QgYW5jaG9yTm9kZSA9IHNlbGVjdGlvbj8uYW5jaG9yTm9kZTtcbiAgICBsZXQgbGlua05vZGUgPSBhbmNob3JOb2RlIGFzIEhUTUxBbmNob3JFbGVtZW50O1xuICAgIHdoaWxlIChsaW5rTm9kZSAmJiBsaW5rTm9kZS50YWdOYW1lICE9PSAnQScpIHtcbiAgICAgIGxpbmtOb2RlID0gbGlua05vZGUucGFyZW50Tm9kZSBhcyBIVE1MQW5jaG9yRWxlbWVudDtcbiAgICB9XG5cbiAgICBpZiAoIWxpbmtOb2RlIHx8IGxpbmtOb2RlLnRhZ05hbWUgIT09ICdBJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGxpbmtUZXh0ID0gbGlua05vZGUuaW5uZXJUZXh0O1xuICAgIGNvbnN0IGxpbmtzSW5kaWNlczogQXJyYXk8bnVtYmVyPiA9IFtdO1xuICAgIGxldCBpbmRleFJldHVybjogbnVtYmVyIHwgdW5kZWZpbmVkID0gLTE7XG4gICAgd2hpbGUgKCFpc05pbChpbmRleFJldHVybikgJiYgaW5kZXhSZXR1cm4gPCByYW5nZS5pbmRleCkge1xuICAgICAgY29uc3QgdGV4dENvbnRlbnQgPSB0aGlzLnF1aWxsPy5nZXRUZXh0KCk7XG4gICAgICBjb25zdCBsaW5rSW5kZXggPSB0ZXh0Q29udGVudD8uaW5kZXhPZihsaW5rVGV4dCwgbGlua3NJbmRpY2VzLmxlbmd0aCA+IDAgPyBsaW5rc0luZGljZXNbbGlua3NJbmRpY2VzLmxlbmd0aCAtIDFdICsgbGlua1RleHQubGVuZ3RoIDogMCk7XG4gICAgICBpZiAoIWlzTmlsKGxpbmtJbmRleCkpIHtcbiAgICAgICAgaWYgKGxpbmtJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBsaW5rc0luZGljZXMucHVzaChsaW5rSW5kZXgpO1xuICAgICAgICAgIGluZGV4UmV0dXJuID0gbGlua0luZGV4ICsgbGlua1RleHQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW5rSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgaW5kZXhSZXR1cm4gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGxpbmtzSW5kaWNlcyAmJiBsaW5rc0luZGljZXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCByYW5nZUluZGV4ID0gbGlua3NJbmRpY2VzW2xpbmtzSW5kaWNlcy5sZW5ndGggLSAxXTtcbiAgICAgIGNvbnN0IGNvdW50SW1hZ2UgPSB0aGlzLmFkanVzdEluZGV4Rm9ySW1hZ2VzKHJhbmdlSW5kZXgpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMubGluay5zZXQoe1xuICAgICAgICAgIHRpdGxlOiBsaW5rVGV4dCxcbiAgICAgICAgICB1cmw6IGxpbmtOb2RlLmhyZWYsXG4gICAgICAgICAgcmFuZ2U6IHtcbiAgICAgICAgICAgIGluZGV4OiByYW5nZUluZGV4ICsgY291bnRJbWFnZSxcbiAgICAgICAgICAgIGxlbmd0aDogbGlua1RleHQubGVuZ3RoLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0TGlua1JlZigpLkZ1bmN0aW9uc0NvbnRyb2w/LnNob3dQb3BvdmVyKGxpbmtOb2RlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlckNvcHkoZTogQ2xpcGJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucXVpbGwpIHJldHVybjtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnF1aWxsLmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsIHx8IHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBkZWx0YSA9IHRoaXMucXVpbGwuZ2V0Q29udGVudHMoc2VsLmluZGV4LCBzZWwubGVuZ3RoKTtcbiAgICBjb25zdCBodG1sMnggPSBnZXRIVE1MRnJvbURlbHRhT2ZRdWlsbDJ4KGRlbHRhIGFzIERlbHRhKTtcblxuICAgIGlmIChlLmNsaXBib2FyZERhdGEpIHtcbiAgICAgIGUuY2xpcGJvYXJkRGF0YS5zZXREYXRhKCd0ZXh0L2h0bWwnLCBodG1sMngpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlclBhc3RlKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkge1xuICAgIHRoaXMuaXNQYXN0ZS5zZXQodHJ1ZSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmlzUGFzdGUuc2V0KGZhbHNlKSwgMCk7XG4gICAgaWYgKCFldmVudCB8fCAhZXZlbnQuY2xpcGJvYXJkRGF0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBmaWxlcyA9IGV2ZW50LmNsaXBib2FyZERhdGEuZmlsZXM7XG4gICAgaWYgKCFmaWxlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBhd2FpdCB0aGlzLnVwbG9hZEltYWdlc0FuZEluc2VydChmaWxlcyk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJUZXh0Q2hhbmdlKGV2ZW50OiBhbnksIF86IGFueSwgc291cmNlOiBFbWl0dGVyU291cmNlKSB7XG4gICAgdGhpcy5vdXRUZXh0Q2hhbmdlLmVtaXQoe1xuICAgICAgcXVpbGw6IHRoaXMucXVpbGwgYXMgUXVpbGwyeCxcbiAgICAgIGRlbHRhOiBldmVudCxcbiAgICB9KTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kZXRlY3RMaW5rKHNvdXJjZSk7XG4gICAgICB0aGlzLnVwZGF0ZVN0YXRlVG9vbGJhckJ5Rm9ybWF0SW5DdXJzb3IoKTtcblxuICAgICAgaWYgKGV2ZW50Py5vcHNbMV0/Lmluc2VydCA9PT0gJ1xcbicpIHtcbiAgICAgICAgY29uc3QgcmFuZ2UgPSB7IGluZGV4OiBldmVudD8ub3BzWzBdLnJldGFpbiBhcyBudW1iZXIgfTtcbiAgICAgICAgY29uc3QgY3VycmVudExlYWYgPSB0aGlzLnF1aWxsPy5nZXRMZWFmKHJhbmdlLmluZGV4KVswXSBhcyBhbnk7XG4gICAgICAgIGNvbnN0IG5leHRMZWFmID0gdGhpcy5xdWlsbD8uZ2V0TGVhZihyYW5nZS5pbmRleCArIDEpWzBdIGFzIGFueTtcbiAgICAgICAgdGhpcy5xdWlsbD8uaW5zZXJ0RW1iZWQocmFuZ2UuaW5kZXgsICdicmVhaycsIHRydWUsICd1c2VyJyk7XG4gICAgICAgIGlmIChuZXh0TGVhZiA9PT0gbnVsbCB8fCBjdXJyZW50TGVhZi5wYXJlbnQgIT09IG5leHRMZWFmLnBhcmVudCkge1xuICAgICAgICAgIHRoaXMucXVpbGw/Lmluc2VydEVtYmVkKHJhbmdlLmluZGV4LCAnYnJlYWsnLCB0cnVlLCAndXNlcicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucXVpbGw/LnNldFNlbGVjdGlvbigocmFuZ2UuaW5kZXggfHwgMCkgKyAxLCAwLCBRdWlsbDJ4LnNvdXJjZXMuU0lMRU5UKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoIXRoaXMuYXV0b1VwZGF0ZVZhbHVlV2hlblRleHRDaGFuZ2UoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVZhbHVlQnlSb290UXVpbGxIdG1sKCk7XG4gIH1cblxuICAvL2VuZHJlZ2lvblxuXG4gIHByaXZhdGUgdXBkYXRlU3RhdGVUb29sYmFyQnlGb3JtYXRJbkN1cnNvcigpOiB7IFtmb3JtYXQ6IHN0cmluZ106IHVua25vd24gfSB8IHVuZGVmaW5lZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGZvcm1hdCA9IHRoaXMucXVpbGw/LmdldEZvcm1hdCgpO1xuICAgICAgaWYgKGZvcm1hdCkge1xuICAgICAgICB0aGlzLnNldEZvbnRTaXplU2VsZWN0ZWQoZm9ybWF0KTtcbiAgICAgICAgdGhpcy5zZXRGb250U2VsZWN0ZWQoZm9ybWF0KTtcbiAgICAgICAgdGhpcy5zZXRDb2xvclNlbGVjdGVkKGZvcm1hdCk7XG4gICAgICAgIHRoaXMubGlzdENoZWNrYm94U2VsZWN0ZWQuc2V0KGZvcm1hdD8ubGlzdCA9PT0gJ3VuY2hlY2tlZCcgfHwgZm9ybWF0Py5saXN0ID09PSAnY2hlY2tlZCcpO1xuICAgICAgICB0aGlzLmFkanVzdFNlbGVjdGVkLnNldChmb3JtYXQ/LmFsaWduIGFzIHN0cmluZyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZm9ybWF0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG5cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgYXN5bmMgdmFsaWRhdGUoKSB7XG4gICAgdGhpcy5tZXNzYWdlRXJyb3Iuc2V0KCcnKTtcbiAgICBjb25zdCB2YWxpZFJlcXVpcmVkID0gdGhpcy52YWxpZFJlcXVpcmVkKCk7XG4gICAgY29uc3QgaXRlbSA9IHRoaXMuaXRlbSgpO1xuICAgIGNvbnN0IGZpZWxkTmFtZUJpbmQgPSB0aGlzLmZpZWxkQmluZCgpO1xuICAgIGNvbnN0IHZhbHVlID0gZ2V0PHVua25vd24+KGl0ZW0sIGZpZWxkTmFtZUJpbmQpO1xuICAgIGlmICh2YWxpZFJlcXVpcmVkICYmIHZhbGlkUmVxdWlyZWQuaXNSZXF1aXJlZCAmJiAhdGhpcy5yZWFkb25seSgpICYmIGlzRW1wdHlRdWlsbDJ4KHRoaXMucXVpbGwpKSB7XG4gICAgICB0aGlzLm1lc3NhZ2VFcnJvci5zZXQodmFsaWRSZXF1aXJlZC5tZXNzYWdlIHx8IEVSUk9SX01FU1NBR0VfRU1QVFlfVkFMSUQpO1xuICAgICAgdGhpcy5vdXRNZXNzYWdlRXJyb3IuZW1pdCh0aGlzLm1lc3NhZ2VFcnJvcigpKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgdmFsaWRNaW5MZW5ndGggPSB0aGlzLnZhbGlkTWluTGVuZ3RoKCk7XG4gICAgaWYgKHZhbGlkTWluTGVuZ3RoICYmIGZpZWxkTmFtZUJpbmQgJiYgdmFsdWUgJiYgdmFsdWUudHJpbSgpLmxlbmd0aCA8IHZhbGlkTWluTGVuZ3RoLmxlbmd0aCkge1xuICAgICAgdGhpcy5tZXNzYWdlRXJyb3Iuc2V0KHZhbGlkTWluTGVuZ3RoLm1lc3NhZ2UgfHwgRVJST1JfTUVTU0FHRV9NSU5fTEVOR1RIKTtcbiAgICAgIHRoaXMub3V0TWVzc2FnZUVycm9yLmVtaXQodGhpcy5tZXNzYWdlRXJyb3IoKSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHZhbGlkTWF4TGVuZ3RoID0gdGhpcy52YWxpZE1heExlbmd0aCgpO1xuICAgIGlmICh2YWxpZE1heExlbmd0aCAmJiBmaWVsZE5hbWVCaW5kICYmIHZhbHVlICYmIHZhbHVlLnRyaW0oKS5sZW5ndGggPiB0aGlzLnZhbGlkTWF4TGVuZ3RoLmxlbmd0aCkge1xuICAgICAgdGhpcy5tZXNzYWdlRXJyb3Iuc2V0KHZhbGlkTWF4TGVuZ3RoLm1lc3NhZ2UgfHwgRVJST1JfTUVTU0FHRV9NQVhfTEVOR1RIKTtcbiAgICAgIHRoaXMub3V0TWVzc2FnZUVycm9yLmVtaXQodGhpcy5tZXNzYWdlRXJyb3IoKSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMub3V0TWVzc2FnZUVycm9yLmVtaXQodGhpcy5tZXNzYWdlRXJyb3IoKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUhhbmRsZXJGdW5jdGlvbigpIHtcbiAgICBjb25zdCBoYW5kbGVyc0V4cGFuZCA9IHRoaXMuaGFuZGxlcnNFeHBhbmQoKTtcblxuICAgIGlmIChoYW5kbGVyc0V4cGFuZCAmJiBoYW5kbGVyc0V4cGFuZC5sZW5ndGgpIHtcbiAgICAgIGhhbmRsZXJzRXhwYW5kLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKGVsZW1lbnQudGl0bGUgJiYgZWxlbWVudC5hY3Rpb24pIHtcbiAgICAgICAgICB0aGlzLmhhbmRsZXJzLnVwZGF0ZSgoaXRlbSkgPT4gKHsgLi4uaXRlbSwgW2VsZW1lbnQudGl0bGVdOiBlbGVtZW50LmFjdGlvbiB9KSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbm9QcmV2ZW50RW1iZWREZWxldGlvbihyYW5nZTogUmFuZ2UpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMucXVpbGwpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBkZWx0YSA9IHRoaXMucXVpbGw/LmdldENvbnRlbnRzKHJhbmdlLmluZGV4LCAxKTtcblxuICAgIGlmIChkZWx0YT8ub3BzLnNvbWUoKG9wdGlvbikgPT4gdGhpcy5ibG90c1JlZ2lzdGVyKCk/LmZpbmQoKGl0ZW0pID0+IGdldChvcHRpb24uaW5zZXJ0LCBpdGVtLmNvbXBvbmVudFsnYmxvdE5hbWUnXSkgJiYgaXRlbS5pZ25vcmVEZWxldGUpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlOyAvLyBOZ8SDbiBraMO0bmcgY2hvIFF1aWxsIHjhu60gbMO9IHjDs2FcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Rm9udFNpemVTZWxlY3RlZChmb3JtYXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgY29uc3QgZm9udFNpemUgPSBmb3JtYXQ/LnNpemU/LnRvU3RyaW5nKCk/LnJlcGxhY2UoJ3B4JywgJycpO1xuICAgIGlmIChpc05hTihwYXJzZUZsb2F0KGZvbnRTaXplIGFzIHN0cmluZykpKSB7XG4gICAgICB0aGlzLmZvbnRTaXplLnNldCh7IHZhbHVlOiB0aGlzLmZvbnRTaXplRGVmYXVsdCgpIH0pO1xuICAgICAgLy8gdGhpcy5oYW5kbGVyVmFsdWVDaGFuZ2VGb250U2l6ZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZvbnRTaXplLnNldCh7IHZhbHVlOiBwYXJzZUZsb2F0KGZvbnRTaXplIGFzIHN0cmluZykgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldEZvbnRTZWxlY3RlZChmb3JtYXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgY29uc3QgZm9udCA9IGxpc3RGb250KCkuZmluZCgoaXRlbSkgPT4gaXRlbS5rZXkgPT09IGZvcm1hdC5mb250KTtcbiAgICBpZiAoIWZvbnQpIHtcbiAgICAgIHRoaXMuZm9udFNlbGVjdGVkLnNldCh7IGtleTogJycsIGl0ZW06IGxpc3RGb250KCkuZmluZCgoaXRlbSkgPT4gaXRlbS5rZXkgPT09ICcnKSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5mb250U2VsZWN0ZWQuc2V0KHsga2V5OiBmb3JtYXQuZm9udCwgaXRlbTogZm9udCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Q29sb3JTZWxlY3RlZChmb3JtYXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgdGhpcy5jb2xvclNlbGVjdGVkLnNldChmb3JtYXQ/LmNvbG9yIGFzIHN0cmluZyk7XG4gICAgdGhpcy5iYWNrZ3JvdW5kU2VsZWN0ZWQuc2V0KGZvcm1hdD8uYmFja2dyb3VuZCBhcyBzdHJpbmcpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjYWxjdWxhdG9yVG9vbGJhcihyZXNldFRvdGFsUmVjYWxsPzogYm9vbGVhbikge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyQ2FsY3VsYXRvclRvb2xiYXIoKSk7XG4gICAgaWYgKHJlc2V0VG90YWxSZWNhbGwpIHtcbiAgICAgIHRoaXMudG90YWxSZWNhbGxDYWxjdWxhdG9yVG9vbGJhci5zZXQoMCk7XG4gICAgfVxuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICBjb25zdCB0b29sYmFyV2lkdGggPSB0aGlzLnRvb2xiYXJDb250YWluZXIoKS5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoIHx8IDA7XG4gICAgbGV0IHRvdGFsV2lkdGggPSA4NDtcbiAgICBpZiAoIXRoaXMuaXNDYWxjdWxhdG9yVG9vbGJhclN1Y2Nlc3MoKSAmJiB0aGlzLnRvdGFsUmVjYWxsQ2FsY3VsYXRvclRvb2xiYXIoKSA8IDEwICYmIHRvb2xiYXJXaWR0aCA8IGdldCh0aGlzLnF1aWxsQ3VzdG9tQ29uZmlnKCkgYXMgSVF1aWxsMnhDdXN0b21Db25maWcsICd0b29sYmFyLmxlc3NXaWR0aFRvb2xiYXJSZWNhbGxDYWxjdWxhdG9yJywgdG90YWxXaWR0aCkpIHtcbiAgICAgIHRoaXMudG90YWxSZWNhbGxDYWxjdWxhdG9yVG9vbGJhci51cGRhdGUoKHZhbCkgPT4gdmFsICsgMSk7XG4gICAgICB0aGlzLnRpbWVyQ2FsY3VsYXRvclRvb2xiYXIuc2V0KFxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLmNhbGN1bGF0b3JUb29sYmFyKCk7XG4gICAgICAgIH0sIDI1MClcbiAgICAgICk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pc0NhbGN1bGF0b3JUb29sYmFyU3VjY2Vzcy5zZXQodHJ1ZSk7XG4gICAgdGhpcy50b29sYmFyT3B0aW9uc0NvbmZpZy51cGRhdGUoKGNvbmZpZ3MpID0+IHtcbiAgICAgIGNvbmZpZ3MuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgaXRlbS5kaXNwbGF5ID0gdHJ1ZTtcbiAgICAgICAgdG90YWxXaWR0aCArPSBpdGVtLndpZHRoO1xuICAgICAgICBpZiAoaXRlbS50eXBlID09PSAnbGluZScpIHtcbiAgICAgICAgICBjb25zdCBuZXh0SXRlbVdpZHRoID0gdG90YWxXaWR0aCArIHRoaXMudG9vbGJhck9wdGlvbnNDb25maWcoKVsraW5kZXggKyAxXS53aWR0aDtcbiAgICAgICAgICBjb25zdCBwcmVJdGVtID0gdGhpcy50b29sYmFyT3B0aW9uc0NvbmZpZygpWytpbmRleCAtIDFdO1xuICAgICAgICAgIGlmIChuZXh0SXRlbVdpZHRoID4gdG9vbGJhcldpZHRoICYmIHByZUl0ZW0uZGlzcGxheSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaXRlbS5kaXNwbGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodG90YWxXaWR0aCA+IHRvb2xiYXJXaWR0aCkge1xuICAgICAgICAgIGl0ZW0uZGlzcGxheSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gWy4uLmNvbmZpZ3NdO1xuICAgIH0pO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3R5bGVGb3JDb250ZW50KCkge1xuICAgIGNvbnN0IHN0eWxlQXJyYXkgPSBbXG4gICAgICB7IHNlbGVjdG9yOiAnLnFsLWZvbnQtQXJpYWwnLCBzdHlsZTogJ2ZvbnQtZmFtaWx5OiBBcmlhbCcgfSxcbiAgICAgIHsgc2VsZWN0b3I6ICcucWwtZm9udC1zYW5zLXNlcmlmJywgc3R5bGU6ICdmb250LWZhbWlseTogc2Fucy1zZXJpZicgfSxcbiAgICAgIHsgc2VsZWN0b3I6ICcucWwtZm9udC1zZXJpZicsIHN0eWxlOiAnZm9udC1mYW1pbHk6IHNlcmlmJyB9LFxuICAgICAgeyBzZWxlY3RvcjogJy5xbC1mb250LW1vbm9zcGFjZScsIHN0eWxlOiAnZm9udC1mYW1pbHk6IG1vbm9zcGFjZScgfSxcbiAgICAgIHsgc2VsZWN0b3I6ICcucWwtZm9udC1IZWx2ZXRpY2EnLCBzdHlsZTogJ2ZvbnQtZmFtaWx5OiBIZWx2ZXRpY2EnIH0sXG4gICAgICB7IHNlbGVjdG9yOiAnLmxpYnMtdWktcXVpbGwtZm9ybWF0LWltYWdlJywgc3R5bGU6ICdtYXgtd2lkdGg6IDEwMCU7IGhlaWdodDogYXV0bycsIG92ZXJyaWRlU3R5bGU6IHRydWUgfSxcbiAgICAgIHsgc2VsZWN0b3I6ICcubGlicy11aS1xdWlsbC1tZW50aW9uJywgc3R5bGU6ICdmb250LXdlaWdodDogNjAwOy1tb3otb3N4LWZvbnQtc21vb3RoaW5nOiBncmF5c2NhbGU7LXdlYmtpdC1mb250LXNtb290aGluZzogYW50aWFsaWFzZWQ7IGNvbG9yOiAjNzIzOUVBJywgb3ZlcnJpZGVTdHlsZTogdHJ1ZSB9LFxuICAgICAgeyBzZWxlY3RvcjogJ2Jsb2NrcXVvdGUnLCBzdHlsZTogJ2JvcmRlci1sZWZ0OiA0cHggc29saWQgI2NjYzsgbWFyZ2luLWJvdHRvbTogNXB4OyBtYXJnaW4tdG9wOiA1cHg7IHBhZGRpbmctbGVmdDogMTZweCcsIG92ZXJyaWRlU3R5bGU6IHRydWUgfSxcbiAgICBdO1xuICAgIHRoaXMuYmxvdHNSZWdpc3RlcigpPy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBzdHlsZUFycmF5LnB1c2goeyBzZWxlY3RvcjogYC4ke2l0ZW0uY2xhc3NOYW1lfWAsIHN0eWxlOiBpdGVtLnN0eWxlLCBvdmVycmlkZVN0eWxlOiB0cnVlIH0pO1xuICAgIH0pO1xuICAgIHN0eWxlQXJyYXkuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnF1aWxsPy5yb290LnF1ZXJ5U2VsZWN0b3JBbGwoaXRlbS5zZWxlY3Rvcik7XG4gICAgICBlbGVtZW50cz8uZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoaXRlbS5vdmVycmlkZVN0eWxlKSB7XG4gICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgaXRlbS5zdHlsZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZpeGJ1ZyBpc3N1ZTogaHR0cHM6Ly9hZG1pbi1jdi5tb2Jpby52bi9pc3N1ZXMvNDkwOTJcbiAgICAgICAgbGV0IHN0eWxlRXhpc3QgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnc3R5bGUnKTtcbiAgICAgICAgaWYgKHN0eWxlRXhpc3QpIHtcbiAgICAgICAgICBbJ2ZvbnQtZmFtaWx5OiBBcmlhbCcsICdmb250LWZhbWlseTogc2Fucy1zZXJpZicsICdmb250LWZhbWlseTogc2VyaWYnLCAnZm9udC1mYW1pbHk6IG1vbm9zcGFjZScsICdmb250LWZhbWlseTogSGVsdmV0aWNhJ10uZm9yRWFjaCgoZm9udCkgPT4ge1xuICAgICAgICAgICAgc3R5bGVFeGlzdCA9IChzdHlsZUV4aXN0Py5pbmNsdWRlcyhgJHtmb250fTtgKSA/IHN0eWxlRXhpc3Q/LnJlcGxhY2UoYCR7Zm9udH07YCwgJycpIDogc3R5bGVFeGlzdD8ucmVwbGFjZShmb250LCAnJykpIGFzIHN0cmluZztcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBzdHlsZUV4aXN0ID8gYCR7c3R5bGVFeGlzdH0ke3N0eWxlRXhpc3Rbc3R5bGVFeGlzdC5sZW5ndGggLSAxXSA9PT0gJzsnID8gJycgOiAnOyd9JHtpdGVtLnN0eWxlfTtgIDogaXRlbS5zdHlsZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2V0Q29udGVudChjb250ZW50OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMucXVpbGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29udGVudFhzc0ZpbHRlciA9IGF3YWl0IHhzc0ZpbHRlcih0aGlzLnJlbW92ZVVud2FudGVkUGFydChjb250ZW50IHx8ICcnKSk7XG4gICAgdGhpcy5xdWlsbC5jbGlwYm9hcmQuZGFuZ2Vyb3VzbHlQYXN0ZUhUTUwoY29udGVudFhzc0ZpbHRlciwgUXVpbGwyeC5zb3VyY2VzLlNJTEVOVCk7XG4gICAgdGhpcy5xdWlsbC5ibHVyKCk7XG4gIH1cblxuICBwcml2YXRlIGFkanVzdEluZGV4Rm9ySW1hZ2VzKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5xdWlsbD8ucm9vdDtcbiAgICBsZXQgaW1hZ2VDb3VudCA9IDA7XG4gICAgbGV0IGFkanVzdGVkSW5kZXggPSAwO1xuICAgIGNvbnN0IGFkanVzdFRleHRJbmRleCA9IChub2RlOiBOb2RlKSA9PiB7XG4gICAgICBpZiAoYWRqdXN0ZWRJbmRleCA+IGluZGV4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICBhZGp1c3RlZEluZGV4ICs9IG5vZGUudGV4dENvbnRlbnQ/Lmxlbmd0aCB8fCAwO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgbm9kZS5ub2RlTmFtZSA9PT0gJ0lNRycpIHtcbiAgICAgICAgaWYgKGFkanVzdGVkSW5kZXggPD0gaW5kZXgpIHtcbiAgICAgICAgICBpbWFnZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIEFycmF5LmZyb20obm9kZS5jaGlsZE5vZGVzKS5mb3JFYWNoKGFkanVzdFRleHRJbmRleCk7XG4gICAgICB9XG4gICAgfTtcbiAgICBhZGp1c3RUZXh0SW5kZXgoY29udGVudCBhcyBOb2RlKTtcbiAgICByZXR1cm4gaW1hZ2VDb3VudDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBsb2FkSW1hZ2VzQW5kSW5zZXJ0KGZpbGVzPzogRmlsZUxpc3QgfCBudWxsKSB7XG4gICAgaWYgKCFmaWxlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtYXhJbWFnZVNpemUgPSB0aGlzLnVwbG9hZEltYWdlQ29uZmlnKCk/Lm1heEltYWdlU2l6ZSB8fCA1ICogMTAyNCAqIDEwMjQ7XG4gICAgY29uc3QgaW1hZ2VzID0gQXJyYXkuZnJvbShmaWxlcykuZmlsdGVyKChmaWxlKSA9PiBmaWxlICYmIGZpbGUudHlwZS5zcGxpdCgnLycpWzBdID09PSAnaW1hZ2UnICYmICghdGhpcy51cGxvYWRJbWFnZUNvbmZpZygpLm1heEltYWdlU2l6ZSB8fCBmaWxlLnNpemUgPD0gbWF4SW1hZ2VTaXplKSk7XG4gICAgaWYgKCFpbWFnZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uuc2hvd0NvbXBUeXBlVGV4dFdhcm5pbmcodGhpcy50cmFuc2xhdGUuaW5zdGFudCgnaTE4bl9ub3RlX3VwbG9hZF9pbWFnZV92b2x1bWUnLCB7IHZhbHVlOiBnZXRMYWJlbEJ5U2l6ZUZpbGUobWF4SW1hZ2VTaXplKSB9KSwgeyB0aW1lUmVtb3ZlOiA4MDAwIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgdGhpcy5sb2FkaW5nVXBsb2FkSW1hZ2Uuc2V0KHRydWUpO1xuICAgICAgY29uc3QgaW5kZXhJbnNlcnQgPSB0aGlzLnF1aWxsPy5nZXRTZWxlY3Rpb24odHJ1ZSkuaW5kZXg7XG4gICAgICBjb25zdCBsaW5rcyA9IGF3YWl0IHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKS5mdW5jdGlvblVwbG9hZEltYWdlPy4oaW1hZ2VzKTtcbiAgICAgIGlmICghbGlua3M/Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsaW5rcy5mb3JFYWNoKChsaW5rKSA9PiB7XG4gICAgICAgIGlmICghbGluayB8fCAodGhpcy51cGxvYWRJbWFnZUNvbmZpZygpLm9ubHlBY2NlcHRJbWFnZUh0dHBzTGluayAmJiAobGluayBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8ICFuZXcgUmVnRXhwKHBhdHRlcm5VcmwoKSkudGVzdChsaW5rKSkpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2UobGluayBhcyBzdHJpbmcsIGluZGV4SW5zZXJ0KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5sb2FkaW5nVXBsb2FkSW1hZ2Uuc2V0KGZhbHNlKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbnNlcnRJbWFnZShjb250ZW50OiBzdHJpbmcsIGluZGV4PzogbnVtYmVyKSB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gaW5kZXggPz8gdGhpcy5xdWlsbD8uZ2V0U2VsZWN0aW9uKHRydWUpLmluZGV4O1xuICAgIGlmICghaXNOaWwoc2VsZWN0aW9uKSkge1xuICAgICAgdGhpcy5xdWlsbD8uaW5zZXJ0RW1iZWQoc2VsZWN0aW9uLCAnaW1hZ2UnLCBjb250ZW50KTtcbiAgICAgIHRoaXMucXVpbGw/LnNldFNlbGVjdGlvbihzZWxlY3Rpb24gKyAxLCAwKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclBvcG92ZXJFdmVudChldmVudDogVFlQRV9QT1BPVkVSX0VWRU5UKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoZXZlbnQgPT09ICdyZW1vdmUnKSB7XG4gICAgICAgIHRoaXMubGluay5zZXQobGlua0RlZmF1bHQoKSk7XG4gICAgICB9XG4gICAgfSwgMTAwKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5zZXJ0TGluayh0ZXh0OiBzdHJpbmcsIHVybDogc3RyaW5nLCBpbmRleD86IG51bWJlcikge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHRoaXMucXVpbGw/LmdldFNlbGVjdGlvbih0cnVlKTtcbiAgICBjb25zdCBpbmRleEluc2VydCA9IGluZGV4ID8/IHNlbGVjdGlvbj8uaW5kZXg7XG4gICAgaWYgKHNlbGVjdGlvbj8ubGVuZ3RoKSB7XG4gICAgICB0aGlzLnF1aWxsPy5kZWxldGVUZXh0KHNlbGVjdGlvbi5pbmRleCwgc2VsZWN0aW9uLmxlbmd0aCwgUXVpbGwyeC5zb3VyY2VzLlVTRVIpO1xuICAgIH1cbiAgICBpZiAoIWlzTmlsKGluZGV4SW5zZXJ0KSkge1xuICAgICAgdGhpcy5xdWlsbD8uaW5zZXJ0VGV4dChpbmRleEluc2VydCwgdGV4dCwge1xuICAgICAgICBsaW5rOiB1cmwsXG4gICAgICAgIGNvbG9yOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlU2hvd1VwbG9hZExpbmsoZXZlbnQ6IHVua25vd24pIHtcbiAgICB0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmLnNldCh0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbExpbmtDb21wb25lbnQpKTtcbiAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuYWRkRWRpdExpbmtDb21wb25lbnRSZWYoKT8uaW5zdGFuY2U7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gdGhpcy5xdWlsbD8uZ2V0U2VsZWN0aW9uKCk7XG4gICAgY29uc3QgdGV4dFNlbGVjdGVkID0gc2VsZWN0aW9uPy5sZW5ndGggPyB0aGlzLnF1aWxsPy5nZXRUZXh0KHNlbGVjdGlvbj8uaW5kZXgsIHNlbGVjdGlvbj8ubGVuZ3RoKSA6ICcnO1xuICAgIGNvbnN0IGRhdGEgPSBldmVudCBhcyBJUXVpbGwyeExpbmsgfCB1bmRlZmluZWQ7XG4gICAgdGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpPy5zZXRJbnB1dCgnekluZGV4JywgdGhpcy56SW5kZXgoKSk7XG4gICAgdGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpPy5zZXRJbnB1dCgndGl0bGUnLCBkYXRhPy50aXRsZSB8fCB0ZXh0U2VsZWN0ZWQpO1xuICAgIHRoaXMuYWRkRWRpdExpbmtDb21wb25lbnRSZWYoKT8uc2V0SW5wdXQoJ2xpbmsnLCBkYXRhPy51cmwgfHwgJycpO1xuICAgIHRoaXMuYWRkRWRpdExpbmtDb21wb25lbnRSZWYoKT8uc2V0SW5wdXQoJ2lnbm9yZUNvbW11bmljYXRlTWljcm9FdmVudCcsIHRoaXMuaWdub3JlQ29tbXVuaWNhdGVNaWNyb0V2ZW50UG9wdXAoKSk7XG4gICAgaW5zdGFuY2U/Lm91dFNhdmVMaW5rLnN1YnNjcmliZSgoaXRlbTogeyB0aXRsZTogc3RyaW5nOyBsaW5rOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBPYmplY3QgJiYgZGF0YS51cmwpIHtcbiAgICAgICAgdGhpcy5xdWlsbD8uZGVsZXRlVGV4dChkYXRhLnJhbmdlLmluZGV4LCBkYXRhLnJhbmdlLmxlbmd0aCwgUXVpbGwyeC5zb3VyY2VzLlVTRVIpO1xuICAgICAgICB0aGlzLnF1aWxsPy5pbnNlcnRUZXh0KGRhdGEucmFuZ2UuaW5kZXgsIGl0ZW0udGl0bGUsICdsaW5rJywgaXRlbS5saW5rKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5pbnNlcnRMaW5rKGl0ZW0udGl0bGUsIGl0ZW0ubGluayk7XG4gICAgfSk7XG4gICAgaW5zdGFuY2U/Lm91dENsb3NlLnN1YnNjcmliZSgoKSA9PiB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmKCkpKTtcbiAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLmFkZFRvQm9keSh0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRNZW50aW9uKGV2ZW50OiBJTWVudGlvbkluc2VydCkge1xuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5xdWlsbD8uZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFyYW5nZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRleFN1YnRyYWN0ID0gdGhpcy5xdWlsbD8uZ2V0VGV4dChyYW5nZS5pbmRleCAtIDEsIDEpPy5pbmNsdWRlcygnQCcpID8gMCA6IDE7XG4gICAgY29uc3QgY3Vyc29yUG9zID0gcmFuZ2UuaW5kZXggLSBpbmRleFN1YnRyYWN0O1xuICAgIGNvbnN0IHN0YXJ0UG9zSW5zZXJ0ID0gY3Vyc29yUG9zIC0gZXZlbnQubGVuZ3RoS2V5O1xuICAgIHRoaXMucXVpbGw/LmRlbGV0ZVRleHQoc3RhcnRQb3NJbnNlcnQsIGV2ZW50Lmxlbmd0aEtleSwgUXVpbGwyeC5zb3VyY2VzLlNJTEVOVCk7XG4gICAgdGhpcy5xdWlsbD8uaW5zZXJ0RW1iZWQoc3RhcnRQb3NJbnNlcnQsICdtZW50aW9uJywgZXZlbnQuZGF0YSwgUXVpbGwyeC5zb3VyY2VzLlNJTEVOVCk7XG4gICAgdGhpcy5pbnNlcnRUZXh0KCcgJywgc3RhcnRQb3NJbnNlcnQgKyAxKTtcbiAgICBpZiAoaW5kZXhTdWJ0cmFjdCkge1xuICAgICAgdGhpcy5xdWlsbD8uZGVsZXRlVGV4dChzdGFydFBvc0luc2VydCArIDMsIDEsIFF1aWxsMnguc291cmNlcy5TSUxFTlQpO1xuICAgIH1cbiAgICB0aGlzLnF1aWxsPy5zZXRTZWxlY3Rpb24oc3RhcnRQb3NJbnNlcnQgKyAyLCAwLCBRdWlsbDJ4LnNvdXJjZXMuU0lMRU5UKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlVmFsdWVCeVJvb3RRdWlsbEh0bWwoKSB7XG4gICAgaWYgKCF0aGlzLnF1aWxsPy5yb290LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbWcnKS5sZW5ndGggJiYgIXRoaXMucXVpbGw/LmdldFRleHQoKSkge1xuICAgICAgc2V0PHVua25vd24+KHRoaXMuaXRlbSgpLCB0aGlzLmZpZWxkQmluZCgpLCAnJyk7XG4gICAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgICB0aGlzLm91dENoYW5nZS5lbWl0KGdldDx1bmtub3duPih0aGlzLml0ZW0sIHRoaXMuZmllbGRCaW5kKCkpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb252ZXJ0SW5uZXJIVE1MQW5kU2V0VmFsdWUoKTtcbiAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgdGhpcy5vdXRDaGFuZ2UuZW1pdChnZXQ8dW5rbm93bj4odGhpcy5pdGVtLCB0aGlzLmZpZWxkQmluZCgpKSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRJbm5lckhUTUxBbmRTZXRWYWx1ZSgpIHtcbiAgICB0aGlzLnNldFN0eWxlRm9yQ29udGVudCgpO1xuICAgIHNldDx1bmtub3duPih0aGlzLml0ZW0oKSwgdGhpcy5maWVsZEJpbmQoKSwgdGhpcy5yZW1vdmVVbndhbnRlZFBhcnQodGhpcy5xdWlsbD8ucm9vdC5pbm5lckhUTUwgfHwgJycpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlVW53YW50ZWRQYXJ0KGh0bWw6IHN0cmluZykge1xuICAgIGlmICghaHRtbCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gaHRtbFxuICAgICAgLnJlcGxhY2UoL15cXHMqPHA+PGJyPjxcXC9wPi8sICcnKVxuICAgICAgLnJlcGxhY2UoLzxkaXY+PGJyPjxcXC9kaXY+L2dpLCAnJylcbiAgICAgIC5yZXBsYWNlKC9bXFx1MjAwQi1cXHUyMDBEXFx1RkVGRl0vZywgJycpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXRlY3RMaW5rKHNvdXJjZTogRW1pdHRlclNvdXJjZSkge1xuICAgIGlmIChzb3VyY2UgIT09ICd1c2VyJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBmdWxsVGV4dCA9IHRoaXMucXVpbGw/LmdldFRleHQoKTtcbiAgICBjb25zdCBpbmRleGVzID0gdGhpcy5nZXRJbmRleFVybE1hdGNoKGZ1bGxUZXh0IHx8ICcnKTtcbiAgICBpZiAoaXNOaWwoZnVsbFRleHQpIHx8ICFpbmRleGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpbmRleGVzLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHRleHRTZWxlY3Rpb24gPSB0aGlzLnF1aWxsPy5nZXRUZXh0KGl0ZW0uc3RhcnQsIGl0ZW0uZW5kIC0gaXRlbS5zdGFydCk7XG4gICAgICBpZiAoIXRleHRTZWxlY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXhvZiA9IHRleHRTZWxlY3Rpb24uc2VhcmNoKHBhdHRlclByb3RvY29sVXJsKCkpO1xuICAgICAgaWYgKGluZGV4b2YgPCAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucXVpbGw/LmZvcm1hdFRleHQoaXRlbS5zdGFydCArIGluZGV4b2YsIGl0ZW0udGV4dC5sZW5ndGgsIHsgbGluazogaXRlbS50ZXh0LCBjb2xvcjogZmFsc2UgfSwgUXVpbGwyeC5zb3VyY2VzLlNJTEVOVCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEluZGV4VXJsTWF0Y2goZnVsbFRleHQ6IHN0cmluZyk6IEFycmF5PHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXI7IHRleHQ6IHN0cmluZyB9PiB7XG4gICAgY29uc3QgdGV4dE1hdGNoID0gZnVsbFRleHQubWF0Y2gobmV3IFJlZ0V4cChwYXR0ZXJuVXJsKCkudG9TdHJpbmcoKS5yZXBsYWNlKCcvXicsICcnKS5yZXBsYWNlKCckLycsICcnKSwgJ2lnJykpO1xuICAgIGNvbnN0IGluZGV4ZXM6IEFycmF5PHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXI7IHRleHQ6IHN0cmluZzsgcHJlQ2hhcmFjdGVyOiBzdHJpbmcgfT4gPSBbXTtcbiAgICBsZXQgaW5kZXggPSAwO1xuXG4gICAgdGV4dE1hdGNoPy5mb3JFYWNoKCh0ZXh0KSA9PiB7XG4gICAgICBjb25zdCBpbmRleE9mVGV4dE1hdGNoID0gZnVsbFRleHQuaW5kZXhPZih0ZXh0LCBpbmRleCk7XG4gICAgICBjb25zdCBpbmRleFByZUNoYXJhY3RlciA9IGluZGV4T2ZUZXh0TWF0Y2ggLSAxO1xuICAgICAgaW5kZXggPSBpbmRleE9mVGV4dE1hdGNoICsgdGV4dC5sZW5ndGg7XG4gICAgICBpZiAoaW5kZXhPZlRleHRNYXRjaCA8IDAgfHwgIW5ldyBSZWdFeHAoL15bXFxzXXxeW1xcdF18XltcXG5dLykudGVzdChmdWxsVGV4dFtpbmRleFByZUNoYXJhY3Rlcl0gfHwgJycpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGluZGV4ZXMucHVzaCh7IHN0YXJ0OiBpbmRleE9mVGV4dE1hdGNoLCBlbmQ6IGluZGV4T2ZUZXh0TWF0Y2ggKyB0ZXh0Lmxlbmd0aCwgdGV4dCwgcHJlQ2hhcmFjdGVyOiBmdWxsVGV4dFtpbmRleFByZUNoYXJhY3Rlcl0gfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaW5kZXhlcztcbiAgfVxuXG4gIHByaXZhdGUgZm9jdXMoKSB7XG4gICAgaWYgKHRoaXMuZm9jdXNCb3R0b20oKSkge1xuICAgICAgdGhpcy5xdWlsbD8uc2V0U2VsZWN0aW9uKHRoaXMucXVpbGwucm9vdC5pbm5lckhUTUwubGVuZ3RoLCAwLCBRdWlsbDJ4LnNvdXJjZXMuU0lMRU5UKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5xdWlsbD8uc2V0U2VsZWN0aW9uKDAsIDAsIFF1aWxsMnguc291cmNlcy5TSUxFTlQpO1xuICB9XG5cbiAgLy9lbmRyZWdpb25cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lclNldEZvbnRTaXplKCkpO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyQ2FsY3VsYXRvclRvb2xiYXIoKSk7XG4gICAgdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5kZWxldGUodGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpKTtcbiAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLmRlbGV0ZSh0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCkpO1xuICAgIHRoaXMucXVpbGw/Lm9mZigndGV4dC1jaGFuZ2UnLCB0aGlzLmhhbmRsZXJUZXh0Q2hhbmdlQmluZCk7XG4gICAgdGhpcy5xdWlsbD8ub2ZmKCdzZWxlY3Rpb24tY2hhbmdlJywgdGhpcy5oYW5kbGVyU2VsZWN0aW9uQ2hhbmdlQmluZCk7XG4gICAgY29uc3QgZWRpdG9yRG9tID0gdGhpcy5xdWlsbD8ucm9vdC5wYXJlbnRFbGVtZW50O1xuICAgIGlmIChlZGl0b3JEb20gJiYgZWRpdG9yRG9tLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIGVkaXRvckRvbS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGVkaXRvckRvbSk7XG4gICAgfVxuICAgIHRoaXMucXVpbGwgPSBudWxsO1xuICB9XG59XG4iLCI8ZGl2XG4gICNodG1sQ29udGFpbmVyXG4gIFtjbGFzc109XCJjb250YWluZXJDbGFzcygpXCJcbiAgW3N0eWxlLi0tcmVzaXplXT1cInJlc2l6ZSgpXCI+XG4gIEBpZiAobGFiZWwoKTsgYXMgbGFiZWwpIHtcbiAgICA8bGlic191aS1jb21wb25lbnRzLWxhYmVsXG4gICAgICBbY2xhc3NJbmNsdWRlXT1cImxhYmVsLmNsYXNzSW5jbHVkZVwiXG4gICAgICBbcmVxdWlyZWRdPVwibGFiZWwucmVxdWlyZWRcIlxuICAgICAgW2xhYmVsTGVmdF09XCJsYWJlbC5sYWJlbExlZnRcIiAvPlxuICB9XG4gIDxkaXZcbiAgICAjdG9vbGJhckNvbnRhaW5lclxuICAgIGNsYXNzPVwicmVsYXRpdmUgaC1bNDRweF1cIlxuICAgIFtjbGFzcy5oaWRkZW5dPVwiIWRpc3BsYXlUb29sYmFyKClcIlxuICAgIFtuZ1N0eWxlXT1cInF1aWxsQ3VzdG9tQ29uZmlnKCk/LnRvb2xiYXI/LigpPy5zdHlsZXM/LigpIHx8IHt9XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRvb2xiYXJUZW1wbGF0ZVwiIC8+XG4gIDwvZGl2PlxuICA8ZGl2XG4gICAgI3Nub3dDb250YWluZXJcbiAgICBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZVxuICAgIExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uRGlyZWN0aXZlXG4gICAgW29wdGlvbnNdPVwieyBpZ25vcmVUcmFuc3BhcmVudFNjcm9sbEJhckNvbG9yRGVmYXVsdDogcmVzaXplKCkgIT09ICdub25lJyB9XCJcbiAgICBbbWVudGlvbkNvbmZpZ109XCJkYXRhQ29uZmlnTWVudGlvbigpXCJcbiAgICAob3V0VG9nZ2xlKT1cImhhbmRsZVRvZ2dsZU1lbnRpb24oJGV2ZW50KVwiXG4gICAgKG91dEluc2VydE1lbnRpb24pPVwiaGFuZGxlckluc2VydE1lbnRpb24oJGV2ZW50KVwiXG4gICAgW2NsYXNzXT1cImNvbnRhaW5lckVkaXRvckNsYXNzKClcIj48L2Rpdj5cbiAgQGlmIChtZXNzYWdlRXJyb3IoKSAmJiBzaG93RXJyb3JMYWJlbCgpKSB7XG4gICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIG10LVs4cHhdXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRleHQtWyNmZjU0NTRdIGxpYnMtdWktZm9udC1oN3JcIj57eyBtZXNzYWdlRXJyb3IoKSB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgfVxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZSAjdG9vbGJhclRlbXBsYXRlPlxuICA8ZGl2XG4gICAgW2NsYXNzXT1cImNvbnRhaW5lclRvb2xiYXJDbGFzcygpXCJcbiAgICAjdG9vbGJhckl0ZW1zPlxuICAgIEBpZiAoZGlzcGxheVNrZWxldG9uVG9vbGJhcigpKSB7XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLXNrZWxldG9uXG4gICAgICAgIGNsYXNzPVwidy1mdWxsIGgtZnVsbFwiXG4gICAgICAgIFtjb25maWddPVwie1xuICAgICAgICAgIHJvd3M6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaXRlbTogeyBjbGFzc0luY2x1ZGVJdGVtOiAnIXJvdW5kZWQtbm9uZScgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfVwiIC8+XG4gICAgfVxuICAgIDxkaXYgY2xhc3M9XCJxbC1mb3JtYXRzIGl0ZW1zLWNlbnRlciBweC1bMTZweF0gcHktWzRweF0gIWZsZXhcIj5cbiAgICAgIEBmb3IgKG9wdGlvbiBvZiB0b29sYmFyT3B0aW9uc0NvbmZpZygpOyB0cmFjayBvcHRpb24pIHtcbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiaXRlbXMtY2VudGVyXCJcbiAgICAgICAgICBbY2xhc3MuaGlkZGVuXT1cIiFvcHRpb24uZGlzcGxheVwiXG4gICAgICAgICAgW2NsYXNzLmZsZXhdPVwib3B0aW9uLmRpc3BsYXlcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbVRvb2xiYXJUZW1wbGF0ZTsgY29udGV4dDogeyBvcHRpb24sICRpbmRleCwgJGxhc3QgfVwiIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlXCI+XG4gICAgICAgIEBpZiAoc2hvd0J1dHRvbk1vcmVUb29sYmFyKCkpIHtcbiAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uXG4gICAgICAgICAgICBbdHlwZV09XCJzaG93TW9yZUFjdGlvbigpID8gJ2J1dHRvbi1zZWNvbmRhcnknIDogJ2J1dHRvbi10aGlyZCdcIlxuICAgICAgICAgICAgW2ljb25Pbmx5VHlwZV09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtjbGFzc0luY2x1ZGVdPVwiJyFwLVsxcHhdICFoLVsyMHB4XSBtbC1bOHB4XSdcIlxuICAgICAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiJ2xpYnMtdWktaWNvbi1tb3ZlLXJpZ2h0IHJvdGF0ZS05MCdcIlxuICAgICAgICAgICAgKG91dENsaWNrKT1cImhhbmRsZXJDaGFuZ2VTaG93TW9yZUFjdGlvbigkZXZlbnQpXCIgLz5cbiAgICAgICAgfVxuICAgICAgICA8IS0tIEJ1aWxkIHRvb2xiYXIga2hpIGNsaWNrIHhlbSB0aMOqbS0tPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCIhc2hvd01vcmVBY3Rpb24oKVwiXG4gICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSBiZy1bI2ZmZmZmZl0gc2hhZG93LVswcHhfNHB4XzE2cHhfMHB4X3JnYmEoMCwyMCw1MSwwLjEwKV0gei1bMV0gZmxleCBpdGVtcy1jZW50ZXIgcGwtWzhweF0gcHItWzE2cHhdIHB5LVs0cHhdIHJvdW5kZWQtWzhweF0gdG9wLVszMXB4XSByaWdodC1bMHB4XVwiPlxuICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiB0b29sYmFyT3B0aW9uc0NvbmZpZygpOyB0cmFjayBvcHRpb24pIHtcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJpdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICBbY2xhc3MuaGlkZGVuXT1cIm9wdGlvbi5kaXNwbGF5ICE9PSBmYWxzZVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5mbGV4XT1cIm9wdGlvbi5kaXNwbGF5ID09PSBmYWxzZVwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbVRvb2xiYXJUZW1wbGF0ZTsgY29udGV4dDogeyBvcHRpb24sICRpbmRleCwgJGxhc3QgfVwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlXG4gICNpdGVtVG9vbGJhclRlbXBsYXRlXG4gIGxldC0kaW5kZXg9XCIkaW5kZXhcIlxuICBsZXQtJGxhc3Q9XCIkbGFzdFwiXG4gIGxldC1vcHRpb249XCJvcHRpb25cIj5cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ3VuZG8nKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl91bmRvJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC11bmRvXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ3JlZG8nKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9yZWRvJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1yZWRvXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2ZvbnRGYW1pbHknKSB7XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJyZWxhdGl2ZSB3LVsxMzJweF0gaC1mdWxsIHJvdW5kZWQtWzRweF0gbGlicy11aS1ib3JkZXItZ2VuZXJhbCB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIlxuICAgICAgW2NsYXNzLmJnLXdoaXRlXT1cIiFyZWFkb25seSgpICYmICFsb2FkaW5nVXBsb2FkSW1hZ2UoKVwiPlxuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1kcm9wZG93blxuICAgICAgICBbaXNOZ0NvbnRlbnRdPVwidHJ1ZVwiXG4gICAgICAgIFtsYWJlbFBvcG92ZXJGdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgIFtsaXN0Q29uZmlnXT1cImxpc3RDb25maWdGb250KClcIlxuICAgICAgICBbbGlzdEhhc0J1dHRvblVuU2VsZWN0T3B0aW9uXT1cImZhbHNlXCJcbiAgICAgICAgW2xpc3RIaWRkZW5JbnB1dFNlYXJjaF09XCJ0cnVlXCJcbiAgICAgICAgW3JlYWRvbmx5XT1cInJlYWRvbmx5KClcIlxuICAgICAgICBbekluZGV4XT1cIjEyNTBcIlxuICAgICAgICAob3V0U2VsZWN0S2V5KT1cImhhbmRsZVNlbGVjdEZvbnQoJGV2ZW50KVwiPlxuICAgICAgICBAaWYgKGZvbnRTZWxlY3RlZCgpOyBhcyBmb250U2VsZWN0ZWQpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgY3Vyc29yLXBvaW50ZXIgcHktWzdweF0gbGlicy11aS1mb250LWg1ciBwbC1bMTZweF0gcHItWzQwcHhdXCI+XG4gICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLXBvcG92ZXJcbiAgICAgICAgICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgICAgICAgICAgW2lnbm9yZVN0b3BQcm9wYWdhdGlvbkV2ZW50XT1cInRydWVcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cInsgekluZGV4OiB6SW5kZXgoKSB9XCI+XG4gICAgICAgICAgICAgIHt7IGxhYmVsRm9udFNlbGVjdGVkQ29tcHV0ZWQoKSB9fVxuICAgICAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtcG9wb3Zlcj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwibGlicy11aS1pY29uLW1vdmUtcmlnaHQgcm90YXRlLTkwIGFic29sdXRlIHJpZ2h0LVsxMnB4XSB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XVwiPjwvaT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtZHJvcGRvd24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2hlYWRlcicpIHtcbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cInJlbGF0aXZlIHctWzEzOHB4XSBoLWZ1bGwgcm91bmRlZC1bNHB4XSBsaWJzLXVpLWJvcmRlci1nZW5lcmFsIHt7IG9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJyB9fVwiXG4gICAgICBbY2xhc3MuYmctd2hpdGVdPVwiIXJlYWRvbmx5KCkgJiYgIWxvYWRpbmdVcGxvYWRJbWFnZSgpXCI+XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLWRyb3Bkb3duXG4gICAgICAgIFtpc05nQ29udGVudF09XCJ0cnVlXCJcbiAgICAgICAgW2xhYmVsUG9wb3ZlckZ1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgW3BvcG92ZXJDdXN0b21Db25maWddPVwieyB3aWR0aEJ5UGFyZW50OiBmYWxzZSwgd2lkdGg6IDIwMCwgY2xhc3NJbmNsdWRlOiAnaC1bMjU0cHhdJywgY2xhc3NJbmNsdWRlT3ZlcmxheUJvZHk6ICdoLWZ1bGwnLCBwb3NpdGlvbjogeyBtb2RlOiAnc3RhcnQnLCBkaXN0YW5jZTogLTggfSB9XCJcbiAgICAgICAgW2xpc3RDb25maWddPVwibGlzdENvbmZpZ0hlYWRlcigpXCJcbiAgICAgICAgW2xpc3RIYXNCdXR0b25VblNlbGVjdE9wdGlvbl09XCJmYWxzZVwiXG4gICAgICAgIFtsaXN0SGlkZGVuSW5wdXRTZWFyY2hdPVwidHJ1ZVwiXG4gICAgICAgIFtyZWFkb25seV09XCJyZWFkb25seSgpXCJcbiAgICAgICAgW2xpc3RNYXhJdGVtU2hvd109XCItMVwiXG4gICAgICAgIFt6SW5kZXhdPVwiMTI1MFwiXG4gICAgICAgIChvdXRTZWxlY3RLZXkpPVwiaGFuZGxlU2VsZWN0SGVhZGVyKCRldmVudClcIj5cbiAgICAgICAgQGlmIChoZWFkZXJTZWxlY3RlZCgpOyBhcyBoZWFkZXJTZWxlY3RlZCkge1xuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBjdXJzb3ItcG9pbnRlciBweS1bN3B4XSBsaWJzLXVpLWZvbnQtaDVyIHBsLVsxNnB4XSBwci1bNDBweF0ge3sgb3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nIH19XCI+XG4gICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLXBvcG92ZXJcbiAgICAgICAgICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgICAgICAgICAgW2lnbm9yZVN0b3BQcm9wYWdhdGlvbkV2ZW50XT1cInRydWVcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cInsgekluZGV4OiB6SW5kZXgoKSB9XCI+XG4gICAgICAgICAgICAgIHt7IGxhYmVsSGVhZGVyU2VsZWN0ZWRDb21wdXRlZCgpIH19XG4gICAgICAgICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJsaWJzLXVpLWljb24tbW92ZS1yaWdodCByb3RhdGUtOTAgYWJzb2x1dGUgcmlnaHQtWzEycHhdIHRleHQtWyM2YTczODNdIHRleHQtWzE2cHhdXCI+PC9pPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1kcm9wZG93bj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnZm9udFNpemUnKSB7XG4gICAgPGRpdiBjbGFzcz1cIiB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXZhbGlkXG4gICAgICAgICNpbnB1dFNpemVSZWZcbiAgICAgICAgW2RhdGFUeXBlXT1cIidpbnQnXCJcbiAgICAgICAgWyhpdGVtKV09XCJmb250U2l6ZVwiXG4gICAgICAgIFtmaWVsZE5hbWVCaW5kXT1cIid2YWx1ZSdcIlxuICAgICAgICBbdmFsdWVVcERvd25OdW1iZXJdPVwiMVwiXG4gICAgICAgIFttYXhWYWx1ZU51bWJlcl09XCI3MlwiXG4gICAgICAgIFttaW5WYWx1ZU51bWJlcl09XCI4XCJcbiAgICAgICAgW3JlYWRvbmx5XT1cInJlYWRvbmx5KCkgfHwgbG9hZGluZ1VwbG9hZEltYWdlKClcIlxuICAgICAgICBbY2xhc3NDb250YWluZXJJbnB1dF09XCIndy1bNzJweF0gaC1bMzJweF0nXCJcbiAgICAgICAgKG91dENoYW5nZVZhbHVlQnlCdXR0b25VcERvd24pPVwiaGFuZGxlclZhbHVlQ2hhbmdlRm9udFNpemUoKVwiXG4gICAgICAgIChvdXRGb2N1c0FuZEJsdXIpPVwiaGFuZGxlclZhbHVlQ2hhbmdlRm9udFNpemUoJGV2ZW50KVwiIC8+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2NvbG9yJykge1xuICAgIDxkaXYgY2xhc3M9XCJxbC1jb2xvciBxbC1waWNrZXIgcWwtY29sb3ItcGlja2VyICFmbGV4IGl0ZW1zLWNlbnRlciB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fdGV4dF9jb2xvcicsIHpJbmRleDogekluZGV4KCkgfVwiPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtc2VsZWN0X2NvbG9yXG4gICAgICAgICAgW3pJbmRleF09XCJ6SW5kZXgoKVwiXG4gICAgICAgICAgW2RpcmVjdGlvbl09XCIndG9wJ1wiXG4gICAgICAgICAgW2V4dGVybmFsQ29udGVudF09XCJ0cnVlXCJcbiAgICAgICAgICBbY3VzdG9tT3B0aW9uc109XCJ7XG4gICAgICAgICAgICBzaG93QWxwaGE6IHRydWUsXG4gICAgICAgICAgfVwiXG4gICAgICAgICAgW2FwcGx5Tm93XT1cImZhbHNlXCJcbiAgICAgICAgICAob3V0Q29sb3JDaGFuZ2VNdWx0aXBsZVR5cGUpPVwiaGFuZGxlclNldEZvcm1hdCgnY29sb3InLCAkZXZlbnQpXCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJsaWJzLXVpLWljb24tZWRpdG9yLWNvbG9yLXRleHQgbGlicy11aS1idXR0b25zLXNlbGVjdC1jb2xvciB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XSBob3Zlcjp0ZXh0LVt2YXIoLS1saWJzLXVpLWNvbG9yLWxpZ2h0LTEpXVwiXG4gICAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLWVkaXRvci1jb2xvci10ZXh0LWFjdGl2ZV09XCIhIWNvbG9yU2VsZWN0ZWQoKVwiXG4gICAgICAgICAgICBbc3R5bGUuLS1jb2xvci1zZWxlY3RlZF09XCJjb2xvclNlbGVjdGVkKClcIj48L2Rpdj5cbiAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1zZWxlY3RfY29sb3I+XG4gICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdiYWNrZ3JvdW5kJykge1xuICAgIDxkaXYgY2xhc3M9XCJxbC1iYWNrZ3JvdW5kIHFsLXBpY2tlciBxbC1jb2xvci1waWNrZXIgIWZsZXggaXRlbXMtY2VudGVyIHt7IG9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJyB9fVwiPlxuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9iYWNrZ3JvdW5kX2NvbG9yJywgekluZGV4OiB6SW5kZXgoKSB9XCI+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1zZWxlY3RfY29sb3JcbiAgICAgICAgICBbekluZGV4XT1cInpJbmRleCgpXCJcbiAgICAgICAgICBbZGlyZWN0aW9uXT1cIid0b3AnXCJcbiAgICAgICAgICBbZXh0ZXJuYWxDb250ZW50XT1cInRydWVcIlxuICAgICAgICAgIFthcHBseU5vd109XCJmYWxzZVwiXG4gICAgICAgICAgW2N1c3RvbU9wdGlvbnNdPVwie1xuICAgICAgICAgICAgc2hvd0FscGhhOiB0cnVlLFxuICAgICAgICAgIH1cIlxuICAgICAgICAgIChvdXRDb2xvckNoYW5nZU11bHRpcGxlVHlwZSk9XCJoYW5kbGVyU2V0Rm9ybWF0KCdiYWNrZ3JvdW5kJywgJGV2ZW50KVwiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwibGlicy11aS1pY29uLWVkaXRvci1jb2xvci1iYWNrZ3JvdW5kIGxpYnMtdWktYnV0dG9ucy1zZWxlY3QtY29sb3IgdGV4dC1bIzZhNzM4M10gdGV4dC1bMTZweF0gaG92ZXI6dGV4dC1bdmFyKC0tbGlicy11aS1jb2xvci1saWdodC0xKV1cIlxuICAgICAgICAgICAgW2NsYXNzLmxpYnMtdWktaWNvbi1lZGl0b3ItY29sb3ItYmFja2dyb3VuZC1hY3RpdmVdPVwiISFiYWNrZ3JvdW5kU2VsZWN0ZWQoKVwiXG4gICAgICAgICAgICBbc3R5bGUuLS1iYWNrZ3JvdW5kLXNlbGVjdGVkXT1cImJhY2tncm91bmRTZWxlY3RlZCgpXCI+PC9kaXY+XG4gICAgICAgIDwvbGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtc2VsZWN0X2NvbG9yPlxuICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtcG9wb3Zlcj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnYm9sZCcpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2ZvbnRfd2VpZ2h0X2JvbGQnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLWJvbGQgIWZsZXhcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnaXRhbGljJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fZm9udF9zdHlsZV9pdGFsaWMnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLWl0YWxpYyAhZmxleFwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICd1bmRlcmxpbmUnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl90ZXh0X2RlY29yYXRpb25fdW5kZXJsaW5lJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC11bmRlcmxpbmUgIWZsZXhcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnc3RyaWtlVGhyb3VnaCcpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX3RleHRfbGluZV90aHJvdWdoJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1zdHJpa2UgIWZsZXhcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnc2NyaXB0LnN1YicpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX3NjcmlwdF9zdWInLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLXNjcmlwdCBmbGV4XCJcbiAgICAgICAgdmFsdWU9XCJzdWJcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnc2NyaXB0LnN1cGVyJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fc2NyaXB0X3N1cGVyJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1zY3JpcHQgZmxleFwiXG4gICAgICAgIHZhbHVlPVwic3VwZXJcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnYWRqdXN0Jykge1xuICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSAhZmxleCBpdGVtcy1jZW50ZXIgcWwtYWxpZ24gcWwtcGlja2VyIHFsLWljb24tcGlja2VyICF3LW1heCB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fYWRqdXN0JywgekluZGV4OiB6SW5kZXgoKSB9XCI+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtZHJvcGRvd25cbiAgICAgICAgICBbaXNOZ0NvbnRlbnRdPVwidHJ1ZVwiXG4gICAgICAgICAgW2lnbm9yZVN0b3BQcm9wYWdhdGlvbkV2ZW50XT1cInRydWVcIlxuICAgICAgICAgIFtsYWJlbFBvcG92ZXJGdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgW2xpc3RDb25maWddPVwibGlzdENvbmZpZ0FsaWduKClcIlxuICAgICAgICAgIFtsaXN0SGlkZGVuSW5wdXRTZWFyY2hdPVwidHJ1ZVwiXG4gICAgICAgICAgW3BvcG92ZXJDdXN0b21Db25maWddPVwieyBpZ25vcmVBcnJvdzogdHJ1ZSwgY2xhc3NJbmNsdWRlOiAnIXctWzMycHhdIG92ZXJmbG93LWhpZGRlbiAhcHktWzRweF0nLCBwb3NpdGlvbjogeyBtb2RlOiAnc3RhcnQnLCBkaXN0YW5jZTogMCB9LCBwYWRkaW5nTGVmdEl0ZW06IGZhbHNlIH1cIlxuICAgICAgICAgIFtsaXN0SGFzQnV0dG9uVW5TZWxlY3RPcHRpb25dPVwiZmFsc2VcIlxuICAgICAgICAgIFt6SW5kZXhdPVwiekluZGV4KCkgKyAxXCJcbiAgICAgICAgICBbbGlzdEtleVNlbGVjdGVkXT1cImFkanVzdFNlbGVjdGVkKClcIlxuICAgICAgICAgIChvdXRTZWxlY3RLZXkpPVwiaGFuZGxlU2VsZWN0QWxpZ24oJGV2ZW50KVwiPlxuICAgICAgICAgIEBpZiAoYWxpZ25TZWxlY3RlZCgpOyBhcyBhbGlnblNlbGVjdGVkKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgY3Vyc29yLXBvaW50ZXJcIj5cbiAgICAgICAgICAgICAgPGlcbiAgICAgICAgICAgICAgICBbY2xhc3NdPVwiaWNvbkFsaWduU2VsZWN0ZWRDb21wdXRlZCgpXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MudGV4dC1bdmFyKC0tbGlicy11aS1jb2xvci1saWdodC0xKV1dPVwiYWRqdXN0U2VsZWN0ZWQoKSAhPT0gdW5kZWZpbmVkXCI+PC9pPlxuICAgICAgICAgICAgICA8aSBjbGFzcz1cImxpYnMtdWktaWNvbi1tb3ZlLXJpZ2h0IHJvdGF0ZS05MCB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XSBtbC1bNHB4XVwiPjwvaT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtZHJvcGRvd24+XG4gICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdpbmRlbnRJbmNyZWFzZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2luZGVudF9pbmNyZWFzZScsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtaW5kZW50XCJcbiAgICAgICAgdmFsdWU9XCIrMVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdpbmRlbnREZWNyZWFzZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2luZGVudF9kZWNyZWFzZScsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtaW5kZW50XCJcbiAgICAgICAgdmFsdWU9XCItMVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdsaXN0QnVsbGV0ZWQnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9saXN0X2J1bGxldGVkJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1saXN0IHFsLWJ1bGxldFwiXG4gICAgICAgIHZhbHVlPVwiYnVsbGV0XCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2xpc3ROdW1iZXJlZCcpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2xpc3RfbnVtYmVyZWQnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLWxpc3QgcWwtb3JkZXJlZFwiXG4gICAgICAgIHZhbHVlPVwib3JkZXJlZFwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdsaXN0Q2hlY2tlZCcpIHtcbiAgICA8ZGl2XG4gICAgICBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCJcbiAgICAgIFtjbGFzcy5xbC1hY3RpdmVdPVwibGlzdENoZWNrYm94U2VsZWN0ZWQoKVwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fbGlzdF9udW1iZXJlZCcsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtbGlzdCBxbC1jaGVja1wiXG4gICAgICAgIHZhbHVlPVwiY2hlY2tcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAncGVyc29uYWxpemUnICYmIHRlbXBsYXRlVG9vbEJhclBlcnNvbmFsaXplKCk7IGFzIHRlbXBsYXRlVG9vbEJhclBlcnNvbmFsaXplKSB7XG4gICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHt7IG9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJyB9fVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlVG9vbEJhclBlcnNvbmFsaXplXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2Jsb2NrcXVvdGUnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9xdW90ZScsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtYmxvY2txdW90ZVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdsaW5rJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5faW5zZXJ0X2xpbmsnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLWxpbmtcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAndW5MaW5rJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fdW5saW5rJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC11bkxpbmtcIlxuICAgICAgICAoY2xpY2spPVwiaGFuZGxlclVubGluaygkZXZlbnQpXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2ltYWdlJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5faW1hZ2UnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLWltYWdlXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ3ZpZGVvJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fdmlkZW8nLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLXZpZGVvXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2Vtb2ppJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1lbW9qaVxuICAgICAgICBbekluZGV4XT1cInpJbmRleCgpXCJcbiAgICAgICAgW2lzTmdDb250ZW50XT1cInRydWVcIlxuICAgICAgICAob3V0RXZlbnRFbW9qaSk9XCJoYW5kbGVySW5zZXJ0RW1vamkoJGV2ZW50KVwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwicWwtZW1vamlcIj48L2J1dHRvbj5cbiAgICAgIDwvbGlic191aS1jb21wb25lbnRzLWVtb2ppPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICd0YWJsZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX3RhYmxlJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC10YWJsZVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdsaW5lJykge1xuICAgIDxkaXYgY2xhc3M9XCJ3LVsxcHhdIGgtWzE2cHhdIGxpYnMtdWktYm9yZGVyLXJpZ2h0LWdlbmVyYWxcIj48L2Rpdj5cbiAgfVxuPC9uZy10ZW1wbGF0ZT5cblxuPGxpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyXG4gICNpbnB1dExpbmtSZWZcbiAgW21vZGVdPVwiJ2NsaWNrJ1wiXG4gIFtpZ25vcmVIaWRkZW5Qb3BvdmVyQ29udGVudFdoZW5Nb3VzZUxlYXZlXT1cInRydWVcIlxuICBbY29uZmlnXT1cInsgdGVtcGxhdGU6IHZpZXdMaW5rLCB3aGl0ZVRoZW1lOiB0cnVlLCBpZ25vcmVBcnJvdzogdHJ1ZSwgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgKG91dEV2ZW50KT1cImhhbmRsZXJQb3BvdmVyRXZlbnQoJGV2ZW50KVwiIC8+XG5cbjxuZy10ZW1wbGF0ZSAjdmlld0xpbms+XG4gIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXIgcHgtWzE2cHhdIHB5LVs4cHhdIHJvdW5kZWQtWzhweF1cIj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cInctZnVsbCBtaW4tdy0wIGxpYnMtdWktZm9udC1oNXJcIlxuICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICBbY29uZmlnXT1cInsgY29udGVudDogbGluaygpLnVybCwgekluZGV4OiB6SW5kZXgoKSArIDEgfVwiPlxuICAgICAge3sgbGluaygpLnVybCB9fVxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBtbC1bMTZweF1cIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1idXR0b25cbiAgICAgICAgW3R5cGVdPVwiJ2J1dHRvbi1saW5rLXByaW1hcnknXCJcbiAgICAgICAgW2ljb25Pbmx5VHlwZV09XCJ0cnVlXCJcbiAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiJ2xpYnMtdWktaWNvbi1lZGl0LWxpbmUnXCJcbiAgICAgICAgW2NsYXNzSW5jbHVkZV09XCInIXAtMCdcIlxuICAgICAgICAob3V0Q2xpY2spPVwiaGFuZGxlckVkaXRMaW5rKCRldmVudClcIiAvPlxuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvblxuICAgICAgICBbdHlwZV09XCInYnV0dG9uLWxpbmstY3VzdG9tJ1wiXG4gICAgICAgIFtidXR0b25DdXN0b21dPVwie1xuICAgICAgICAgIGNvbmZpZ1N0ZXBDb2xvcjoge1xuICAgICAgICAgICAgdGV4dDogJyMwNzE2MzEnLFxuICAgICAgICAgICAgdGV4dF9ob3ZlcjogJyNlZTJkNDEnLFxuICAgICAgICAgICAgdGV4dF9hY3RpdmU6ICcjZWUyZDQxJyxcbiAgICAgICAgICAgIHRleHRfZGlzYWJsZTogJzA3MTYzMScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByb290Q29sb3I6ICcjMDcxNjMxJyxcbiAgICAgICAgfVwiXG4gICAgICAgIFtjbGFzc0luY2x1ZGVdPVwiJyFwLTAgbWwtWzEycHhdJ1wiXG4gICAgICAgIFtpY29uT25seVR5cGVdPVwidHJ1ZVwiXG4gICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cIidsaWJzLXVpLWljb24tbGluay1icm9rZW4nXCJcbiAgICAgICAgKG91dENsaWNrKT1cImhhbmRsZXJVbmxpbmsoJGV2ZW50KVwiIC8+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|