@libs-ui/components-inputs-quill 0.1.1-1
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/div.component.d.ts +5 -0
- package/blots-custom/image.component.d.ts +6 -0
- package/blots-custom/mention.component.d.ts +19 -0
- package/esm2022/blots-custom/div.component.mjs +6 -0
- package/esm2022/blots-custom/image.component.mjs +13 -0
- package/esm2022/blots-custom/mention.component.mjs +34 -0
- package/esm2022/indent-attributor/indent-attributor.component.mjs +20 -0
- package/esm2022/index.mjs +4 -0
- package/esm2022/interfaces/quill.interface.mjs +2 -0
- package/esm2022/libs-ui-components-inputs-quill.mjs +5 -0
- package/esm2022/link/link.component.mjs +52 -0
- package/esm2022/quill.component.mjs +878 -0
- package/esm2022/quill2x.component.mjs +150 -0
- package/esm2022/upload-image/upload-image.component.mjs +67 -0
- package/esm2022/utils/quill.define.mjs +429 -0
- package/esm2022/utils/quill2x.define.mjs +210 -0
- package/fesm2022/libs-ui-components-inputs-quill.mjs +1836 -0
- package/fesm2022/libs-ui-components-inputs-quill.mjs.map +1 -0
- package/indent-attributor/indent-attributor.component.d.ts +8 -0
- package/index.d.ts +3 -0
- package/interfaces/quill.interface.d.ts +89 -0
- package/link/link.component.d.ts +27 -0
- package/package.json +47 -0
- package/quill.component.d.ts +157 -0
- package/quill2x.component.d.ts +18 -0
- package/upload-image/upload-image.component.d.ts +15 -0
- package/utils/quill.define.d.ts +25 -0
- package/utils/quill2x.define.d.ts +3 -0
|
@@ -0,0 +1,878 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
3
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, effect, inject, input, model, output, signal, untracked, viewChild, } from '@angular/core';
|
|
4
|
+
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
5
|
+
import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
|
|
6
|
+
import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
|
|
7
|
+
import { LibsUiComponentsEmojiComponent } from '@libs-ui/components-inputs-emoji';
|
|
8
|
+
import { LibsUiComponentsInputsMentionDirective } from '@libs-ui/components-inputs-mention';
|
|
9
|
+
import { LibsUiComponentsInputsValidComponent } from '@libs-ui/components-inputs-valid';
|
|
10
|
+
import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
|
|
11
|
+
import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
|
|
12
|
+
import { LibsUiComponentsScrollOverlayDirective } from '@libs-ui/components-scroll-overlay';
|
|
13
|
+
import { LibsUiComponentsSkeletonComponent } from '@libs-ui/components-skeleton';
|
|
14
|
+
import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';
|
|
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, isNil, patternUrl, set, xssFilter } from '@libs-ui/utils';
|
|
18
|
+
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
19
|
+
import Quill from 'quill';
|
|
20
|
+
import { fromEvent, lastValueFrom, Subject, takeUntil, timer } from 'rxjs';
|
|
21
|
+
import { QuillDivBlot } from './blots-custom/div.component';
|
|
22
|
+
import { CustomImageBlot } from './blots-custom/image.component';
|
|
23
|
+
import { QuillMentionBlot } from './blots-custom/mention.component';
|
|
24
|
+
import { indentStyle } from './indent-attributor/indent-attributor.component';
|
|
25
|
+
import { LibsUiComponentsInputsQuillLinkComponent } from './link/link.component';
|
|
26
|
+
import { LibsUiComponentsInputsQuillUploadImageComponent } from './upload-image/upload-image.component';
|
|
27
|
+
import { iconList, linkDefault, listConfigAlign, listConfigFont, listConfigHeader, listFont, toolBarOptions, uploadImageConfigDefault } from './utils/quill.define';
|
|
28
|
+
import * as i0 from "@angular/core";
|
|
29
|
+
import * as i1 from "@ngx-translate/core";
|
|
30
|
+
export class LibsUiComponentsInputsQuillComponent {
|
|
31
|
+
qlEditorElement = signal(undefined);
|
|
32
|
+
timeoutScrollToSelectionWithElementScrollHeightAuto = signal(undefined);
|
|
33
|
+
loadingUploadImage = signal(false);
|
|
34
|
+
timeDelayInit = signal(20);
|
|
35
|
+
messageError = signal('');
|
|
36
|
+
display = signal(false);
|
|
37
|
+
listConfigAlign = signal(listConfigAlign());
|
|
38
|
+
alignSelected = signal(undefined);
|
|
39
|
+
iconAlignSelectedComputed = computed(() => get(this.alignSelected(), 'item.icon'));
|
|
40
|
+
listConfigFont = signal(listConfigFont());
|
|
41
|
+
fontSelected = signal(undefined);
|
|
42
|
+
labelFontSelectedComputed = computed(() => get(this.fontSelected(), 'item.label') || 'Sans Serif');
|
|
43
|
+
listConfigHeader = signal(listConfigHeader());
|
|
44
|
+
headerSelected = signal(undefined);
|
|
45
|
+
labelHeaderSelectedComputed = computed(() => get(this.headerSelected(), 'item.label') || 'Normal');
|
|
46
|
+
size = signal({ value: 14 });
|
|
47
|
+
showMoreAction = signal(false);
|
|
48
|
+
link = signal(linkDefault());
|
|
49
|
+
toolbarOptionsConfig = signal([]);
|
|
50
|
+
displayShowMoreToolbar = computed(() => this.toolbarOptionsConfig().some((item) => item.display === false));
|
|
51
|
+
displaySkeleton = computed(() => this.toolbarOptionsConfig().every((item) => item.display === undefined));
|
|
52
|
+
timeCalculationToolBar = signal(undefined);
|
|
53
|
+
popoverFunctionControl = signal(undefined);
|
|
54
|
+
quill = signal(undefined);
|
|
55
|
+
handlers = signal({ undo: this.handleUndo.bind(this), redo: this.handleRedo.bind(this) });
|
|
56
|
+
showMention = signal(false);
|
|
57
|
+
addEditLinkComponentRef = signal(undefined);
|
|
58
|
+
uploadImageComponentRef = signal(undefined);
|
|
59
|
+
onDestroy = new Subject();
|
|
60
|
+
dynamicComponentService = inject(LibsUiDynamicComponentService);
|
|
61
|
+
translate = inject(TranslateService);
|
|
62
|
+
isShowToolBar = input(true, { transform: (val) => val ?? true });
|
|
63
|
+
isToolbarPositionFixed = input(false, { transform: (val) => val ?? false });
|
|
64
|
+
classIncludeToolbar = input('');
|
|
65
|
+
stylesIncludeToolbar = input();
|
|
66
|
+
toolbarConfig = input();
|
|
67
|
+
placeholder = input('i18n_import_content', { transform: (value) => value || 'i18n_import_content' });
|
|
68
|
+
label = input();
|
|
69
|
+
item = model();
|
|
70
|
+
/**đặt cờ này bằng false để tối ưu hiệu năng, và chỉ lấy dữ liệu ra khi có yêu cầu lấy dữ liệu để gửi lên server , gọi refreshItemValue để cập nhật giá tri thủ công*/
|
|
71
|
+
autoUpdateValueWhenTextChange = input(true, { transform: (value) => value ?? true });
|
|
72
|
+
fieldNameBind = input('value');
|
|
73
|
+
readonly = input();
|
|
74
|
+
showErrorLabel = input(true);
|
|
75
|
+
showErrorBorder = input(false);
|
|
76
|
+
onlyShowErrorBorderInContent = input(false);
|
|
77
|
+
classIncludeTemplate = input();
|
|
78
|
+
classInclude = input();
|
|
79
|
+
handlersExpand = input();
|
|
80
|
+
validRequired = input();
|
|
81
|
+
validMinLength = input();
|
|
82
|
+
validMaxLength = input();
|
|
83
|
+
zIndex = input(1250, { transform: (value) => value || 1250 });
|
|
84
|
+
dataConfigMention = input();
|
|
85
|
+
blotsRegister = input();
|
|
86
|
+
autoFocus = input();
|
|
87
|
+
focusBottom = input();
|
|
88
|
+
blockUndoRedoKeyboard = input();
|
|
89
|
+
templateToolBarPersonalize = input();
|
|
90
|
+
template = input();
|
|
91
|
+
uploadImageConfig = input(uploadImageConfigDefault(), { transform: (value) => value || uploadImageConfigDefault() });
|
|
92
|
+
heightAuto = input();
|
|
93
|
+
elementScrollHeightAuto = input();
|
|
94
|
+
ignoreShowPopupEditLink = input();
|
|
95
|
+
ignoreCommunicateMicroEventPopup = input();
|
|
96
|
+
outShowPopupEditLink = output();
|
|
97
|
+
outMessageError = output();
|
|
98
|
+
outBlur = output();
|
|
99
|
+
outFocus = output();
|
|
100
|
+
outChange = output();
|
|
101
|
+
outFunctionsControl = output();
|
|
102
|
+
outSelectionChange = output();
|
|
103
|
+
outTextChange = output();
|
|
104
|
+
outContextMenu = output();
|
|
105
|
+
wrapperEditorEl = viewChild.required('wrapperEditor');
|
|
106
|
+
editorEl = viewChild.required('editor');
|
|
107
|
+
quillOptionEl = viewChild.required('quillOption');
|
|
108
|
+
quillEditorEl = viewChild.required('quillEditor');
|
|
109
|
+
toolbarItemsEl = viewChild.required('toolbarItems');
|
|
110
|
+
notificationService = inject(LibsUiNotificationService);
|
|
111
|
+
cdr = inject(ChangeDetectorRef);
|
|
112
|
+
constructor() {
|
|
113
|
+
effect(() => {
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
const classes = `${this.classInclude() || ''} h-full w-full`
|
|
116
|
+
.split(' ')
|
|
117
|
+
.map((item) => item.trim())
|
|
118
|
+
.filter((item) => item);
|
|
119
|
+
this.getQlEditorElement()?.classList.add(...classes);
|
|
120
|
+
}, this.timeDelayInit() + 10);
|
|
121
|
+
});
|
|
122
|
+
effect(() => {
|
|
123
|
+
const type = this.toolbarConfig()?.type || 'default';
|
|
124
|
+
const hasIconImage = this.uploadImageConfig().showIcon ?? false;
|
|
125
|
+
const hasIconPersonalize = !!this.templateToolBarPersonalize();
|
|
126
|
+
untracked(() => {
|
|
127
|
+
this.toolbarOptionsConfig.set(this.toolbarConfig()?.config || toolBarOptions(type, hasIconImage, hasIconPersonalize));
|
|
128
|
+
this.cdr.detectChanges();
|
|
129
|
+
this.calculatorToolbar();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
ngOnInit() {
|
|
134
|
+
this.outFunctionsControl.emit(this.FunctionsControl);
|
|
135
|
+
}
|
|
136
|
+
get FunctionsControl() {
|
|
137
|
+
return {
|
|
138
|
+
checkIsValid: this.validate.bind(this),
|
|
139
|
+
refreshItemValue: this.updateValueByRootQuillHtml.bind(this),
|
|
140
|
+
setContent: this.setContent.bind(this),
|
|
141
|
+
insertText: this.insertText.bind(this),
|
|
142
|
+
insertLink: this.insertLink.bind(this),
|
|
143
|
+
insertImage: this.insertImage.bind(this),
|
|
144
|
+
setFontSize: this.setFontSize.bind(this),
|
|
145
|
+
setColor: async (color) => this.setStyle('color', color),
|
|
146
|
+
setBackground: async (color) => this.setStyle('background', color),
|
|
147
|
+
quill: () => this.quill(),
|
|
148
|
+
scrollToSelectionWithElementScrollHeightAuto: this.scrollToSelectionWithElementScrollHeightAuto.bind(this),
|
|
149
|
+
insertEmbed: async (range, type, data, sources) => {
|
|
150
|
+
this.quill()?.insertEmbed(range.index, type, data, sources || Quill.sources.USER);
|
|
151
|
+
this.quill()?.setSelection(range.indexSelect, range.length || 0, Quill.sources.USER);
|
|
152
|
+
this.scrollToSelectionWithElementScrollHeightAuto(range.indexSelect);
|
|
153
|
+
return;
|
|
154
|
+
},
|
|
155
|
+
reCalculatorToolbar: this.calculatorToolbar.bind(this),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async ngAfterViewInit() {
|
|
159
|
+
this.setHandlerFunction();
|
|
160
|
+
await lastValueFrom(timer(this.timeDelayInit()));
|
|
161
|
+
this.initQuill();
|
|
162
|
+
this.setContent(get(this.item(), this.fieldNameBind(), ''));
|
|
163
|
+
this.handlerTextChange();
|
|
164
|
+
this.handlerSelectionChange();
|
|
165
|
+
this.handlerPaste();
|
|
166
|
+
// gọi hàm này để quill đánh dấu là đã focus trong khi quill chưa khởi tạo xong để không bị scroll xuống dưới.sau khi quill khởi tạo xong và check nếu đang focus đang được bật thì nó không gọi lại hàm focus nữa
|
|
167
|
+
this.quill()?.focus();
|
|
168
|
+
if (this.autoFocus()) {
|
|
169
|
+
this.display.set(true);
|
|
170
|
+
this.quill()?.blur();
|
|
171
|
+
}
|
|
172
|
+
fromEvent(window, 'resize').pipe(takeUntil(this.onDestroy)).subscribe(this.calculatorToolbar.bind(this));
|
|
173
|
+
await lastValueFrom(timer(400));
|
|
174
|
+
this.display.set(true);
|
|
175
|
+
const cursorSpan = this.quill()?.root.querySelector('.ql-cursor');
|
|
176
|
+
if (cursorSpan) {
|
|
177
|
+
cursorSpan.remove();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
initQuill() {
|
|
181
|
+
const size = Quill.import('attributors/style/size');
|
|
182
|
+
const alignStyle = Quill.import('attributors/style/align');
|
|
183
|
+
const icons = Quill.import('ui/icons');
|
|
184
|
+
const italic = Quill.import('formats/italic');
|
|
185
|
+
const bold = Quill.import('formats/bold');
|
|
186
|
+
size.whitelist = [
|
|
187
|
+
'8px',
|
|
188
|
+
'9px',
|
|
189
|
+
'10px',
|
|
190
|
+
'11px',
|
|
191
|
+
'12px',
|
|
192
|
+
'13px',
|
|
193
|
+
'14px',
|
|
194
|
+
'15px',
|
|
195
|
+
'16px',
|
|
196
|
+
'17px',
|
|
197
|
+
'18px',
|
|
198
|
+
'19px',
|
|
199
|
+
'20px',
|
|
200
|
+
'21px',
|
|
201
|
+
'22px',
|
|
202
|
+
'23px',
|
|
203
|
+
'24px',
|
|
204
|
+
'25px',
|
|
205
|
+
'26px',
|
|
206
|
+
'27px',
|
|
207
|
+
'28px',
|
|
208
|
+
'29px',
|
|
209
|
+
'30px',
|
|
210
|
+
'31px',
|
|
211
|
+
'32px',
|
|
212
|
+
'33px',
|
|
213
|
+
'34px',
|
|
214
|
+
'35px',
|
|
215
|
+
'36px',
|
|
216
|
+
'37px',
|
|
217
|
+
'38px',
|
|
218
|
+
'39px',
|
|
219
|
+
'40px',
|
|
220
|
+
'41px',
|
|
221
|
+
'42px',
|
|
222
|
+
'43px',
|
|
223
|
+
'44px',
|
|
224
|
+
'45px',
|
|
225
|
+
'46px',
|
|
226
|
+
'47px',
|
|
227
|
+
'48px',
|
|
228
|
+
'49px',
|
|
229
|
+
'50px',
|
|
230
|
+
'51px',
|
|
231
|
+
'52px',
|
|
232
|
+
'53px',
|
|
233
|
+
'54px',
|
|
234
|
+
'55px',
|
|
235
|
+
'56px',
|
|
236
|
+
'57px',
|
|
237
|
+
'58px',
|
|
238
|
+
'59px',
|
|
239
|
+
'60px',
|
|
240
|
+
'61px',
|
|
241
|
+
'62px',
|
|
242
|
+
'63px',
|
|
243
|
+
'64px',
|
|
244
|
+
'65px',
|
|
245
|
+
'66px',
|
|
246
|
+
'67px',
|
|
247
|
+
'68px',
|
|
248
|
+
'69px',
|
|
249
|
+
'70px',
|
|
250
|
+
'71px',
|
|
251
|
+
'72px',
|
|
252
|
+
];
|
|
253
|
+
italic.tagName = 'i';
|
|
254
|
+
bold.tagName = 'b';
|
|
255
|
+
Quill.register(bold, true);
|
|
256
|
+
Quill.register(italic, true);
|
|
257
|
+
Quill.register(size, true);
|
|
258
|
+
Quill.register(CustomImageBlot, true);
|
|
259
|
+
Quill.register(QuillDivBlot, true);
|
|
260
|
+
Quill.register(alignStyle, true);
|
|
261
|
+
Quill.register(QuillMentionBlot, true);
|
|
262
|
+
this.blotsRegister()?.forEach((item) => {
|
|
263
|
+
Quill.register(item.component, true);
|
|
264
|
+
});
|
|
265
|
+
Quill.register({ 'formats/indent': indentStyle }, true);
|
|
266
|
+
fromEvent(this.quillEditorEl()?.nativeElement, 'contextmenu')
|
|
267
|
+
.pipe(takeUntil(this.onDestroy))
|
|
268
|
+
.subscribe((e) => this.outContextMenu.emit(e));
|
|
269
|
+
iconList().forEach((element) => set(icons, element.key, `<span class="${element.icon} hover:text-[var(--libs-ui-color-light-1)] text-[16px] text-[#6a7383]"></span>`));
|
|
270
|
+
this.quill.set(new Quill(this.quillEditorEl()?.nativeElement, {
|
|
271
|
+
modules: {
|
|
272
|
+
toolbar: {
|
|
273
|
+
container: this.quillOptionEl()?.nativeElement,
|
|
274
|
+
handlers: this.handlers(),
|
|
275
|
+
},
|
|
276
|
+
clipboard: {
|
|
277
|
+
matchVisual: false,
|
|
278
|
+
},
|
|
279
|
+
history: {
|
|
280
|
+
delay: 1000,
|
|
281
|
+
maxStack: 100,
|
|
282
|
+
userOnly: false,
|
|
283
|
+
},
|
|
284
|
+
keyboard: {
|
|
285
|
+
bindings: {
|
|
286
|
+
enter: {
|
|
287
|
+
key: 13,
|
|
288
|
+
handler: () => (this.showMention() ? false : true),
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
readOnly: this.readonly(),
|
|
294
|
+
placeholder: this.translate.instant(this.placeholder()),
|
|
295
|
+
theme: 'snow',
|
|
296
|
+
bounds: this.heightAuto() ? this.wrapperEditorEl()?.nativeElement : this.quillEditorEl()?.nativeElement,
|
|
297
|
+
scrollingContainer: this.heightAuto() ? this.wrapperEditorEl()?.nativeElement : null,
|
|
298
|
+
}));
|
|
299
|
+
this.quill()?.keyboard.addBinding({ key: 'Backspace' }, this.noPreventEmbedDeletion.bind(this));
|
|
300
|
+
this.quill()?.keyboard.addBinding({ key: 'Delete' }, this.noPreventEmbedDeletion.bind(this));
|
|
301
|
+
this.setupUndoRedoBlocking();
|
|
302
|
+
}
|
|
303
|
+
setupUndoRedoBlocking() {
|
|
304
|
+
const editorRoot = this.quill()?.root;
|
|
305
|
+
if (editorRoot && this.blockUndoRedoKeyboard()) {
|
|
306
|
+
const keydownHandler = (e) => {
|
|
307
|
+
const isUndo = (e.key === 'z' || e.key === 'Z') && (e.ctrlKey || e.metaKey) && !e.shiftKey;
|
|
308
|
+
const isRedo = ((e.key === 'z' || e.key === 'Z') && (e.ctrlKey || e.metaKey) && e.shiftKey) || ((e.key === 'y' || e.key === 'Y') && e.ctrlKey);
|
|
309
|
+
if (isUndo || isRedo) {
|
|
310
|
+
e.preventDefault();
|
|
311
|
+
e.stopPropagation();
|
|
312
|
+
console.log(`Blocking ${isUndo ? 'undo' : 'redo'} keyboard shortcut`);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
editorRoot.addEventListener('keydown', keydownHandler, true);
|
|
316
|
+
this.onDestroy.subscribe(() => {
|
|
317
|
+
editorRoot.removeEventListener('keydown', keydownHandler, true);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
noPreventEmbedDeletion(range) {
|
|
322
|
+
if (!this.quill())
|
|
323
|
+
return false;
|
|
324
|
+
const delta = this.quill()?.getContents(range.index, 1);
|
|
325
|
+
if (delta?.ops.some((option) => this.blotsRegister()?.find((item) => get(option.insert, item.component['blotName']) && item.ignoreDelete))) {
|
|
326
|
+
return false; // Ngăn không cho Quill xử lý xóa
|
|
327
|
+
}
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
setHandlerFunction() {
|
|
331
|
+
this.handlers.update((item) => ({
|
|
332
|
+
...item,
|
|
333
|
+
image: this.handlerShowUploadImage.bind(this),
|
|
334
|
+
emoji: () => {
|
|
335
|
+
return;
|
|
336
|
+
},
|
|
337
|
+
}));
|
|
338
|
+
let link = false;
|
|
339
|
+
const handlersExpand = this.handlersExpand();
|
|
340
|
+
if (handlersExpand && handlersExpand.length) {
|
|
341
|
+
handlersExpand.forEach((element) => {
|
|
342
|
+
if (element.title && element.action) {
|
|
343
|
+
if (element.title === 'link') {
|
|
344
|
+
link = true;
|
|
345
|
+
}
|
|
346
|
+
this.handlers.update((item) => ({ ...item, [element.title]: element.action }));
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
if (!link) {
|
|
351
|
+
this.handlers.update((item) => ({ ...item, link: this.handleShowUploadLink.bind(this), unLink: this.handlerUnInsertLink.bind(this) }));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
adjustIndexForImages(index) {
|
|
355
|
+
const content = this.quill()?.root;
|
|
356
|
+
let imageCount = 0;
|
|
357
|
+
let adjustedIndex = 0;
|
|
358
|
+
const adjustTextIndex = (node) => {
|
|
359
|
+
if (adjustedIndex > index) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
363
|
+
adjustedIndex += node.textContent?.length || 0;
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'IMG') {
|
|
367
|
+
if (adjustedIndex <= index) {
|
|
368
|
+
imageCount++;
|
|
369
|
+
}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
373
|
+
Array.from(node.childNodes).forEach(adjustTextIndex);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
adjustTextIndex(content);
|
|
377
|
+
return imageCount;
|
|
378
|
+
}
|
|
379
|
+
handlerSelectionChange() {
|
|
380
|
+
this.quill()?.on('selection-change', (range, oldRange, source) => {
|
|
381
|
+
if (this.readonly()) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (range === null && oldRange !== null) {
|
|
385
|
+
this.outBlur.emit();
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (range !== null && oldRange === null) {
|
|
389
|
+
this.outFocus.emit();
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const format = this.quill()?.getFormat();
|
|
393
|
+
if (format) {
|
|
394
|
+
this.getFont(format);
|
|
395
|
+
this.getFontSize(format);
|
|
396
|
+
}
|
|
397
|
+
this.outSelectionChange.emit({
|
|
398
|
+
quill: this.quill(),
|
|
399
|
+
range,
|
|
400
|
+
oldRange,
|
|
401
|
+
source,
|
|
402
|
+
});
|
|
403
|
+
if (range.length === 0 && format?.link && source === 'user') {
|
|
404
|
+
const selection = document.getSelection();
|
|
405
|
+
const anchorNode = selection?.anchorNode;
|
|
406
|
+
let linkNode = anchorNode;
|
|
407
|
+
while (linkNode && linkNode.tagName !== 'A') {
|
|
408
|
+
linkNode = linkNode.parentNode;
|
|
409
|
+
}
|
|
410
|
+
if (linkNode && linkNode.tagName === 'A') {
|
|
411
|
+
const linkText = linkNode.innerText;
|
|
412
|
+
const linksIndices = [];
|
|
413
|
+
let indexReturn = -1;
|
|
414
|
+
while (!isNil(indexReturn) && indexReturn < range.index) {
|
|
415
|
+
const textContent = this.quill()?.getText();
|
|
416
|
+
const linkIndex = textContent?.indexOf(linkText, linksIndices.length > 0 ? linksIndices[linksIndices.length - 1] + linkText.length : 0);
|
|
417
|
+
if (!isNil(linkIndex)) {
|
|
418
|
+
if (linkIndex !== -1) {
|
|
419
|
+
linksIndices.push(linkIndex);
|
|
420
|
+
indexReturn = linkIndex + linkText.length;
|
|
421
|
+
}
|
|
422
|
+
if (linkIndex === -1) {
|
|
423
|
+
indexReturn = undefined;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (linksIndices && linksIndices.length) {
|
|
428
|
+
const rangeIndex = linksIndices[linksIndices.length - 1];
|
|
429
|
+
const countImage = this.adjustIndexForImages(rangeIndex);
|
|
430
|
+
setTimeout(() => {
|
|
431
|
+
this.link.set({
|
|
432
|
+
title: linkText,
|
|
433
|
+
url: linkNode.href,
|
|
434
|
+
range: {
|
|
435
|
+
index: rangeIndex + countImage,
|
|
436
|
+
length: linkText.length,
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
this.popoverFunctionControl()?.showPopover(linkNode);
|
|
440
|
+
}, 250);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
handlerPaste() {
|
|
447
|
+
set(this.quill, 'root.onpaste', async (event) => {
|
|
448
|
+
if (!event || !event.clipboardData) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
const files = event.clipboardData.files;
|
|
452
|
+
if (!files.length) {
|
|
453
|
+
if (event.clipboardData.getData('text')) {
|
|
454
|
+
this.scrollToSelectionWithElementScrollHeightAuto();
|
|
455
|
+
}
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
event.preventDefault();
|
|
459
|
+
await this.uploadImagesAndInsert(files);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
handlerTextChange() {
|
|
463
|
+
this.quill()?.on('text-change', (event) => {
|
|
464
|
+
this.outTextChange.emit({
|
|
465
|
+
quill: this.quill(),
|
|
466
|
+
delta: event,
|
|
467
|
+
});
|
|
468
|
+
setTimeout(() => {
|
|
469
|
+
if (event?.ops[1]?.insert === '\n') {
|
|
470
|
+
const range = { index: event?.ops[0].retain };
|
|
471
|
+
const currentLeaf = this.quill()?.getLeaf(range.index)[0];
|
|
472
|
+
const nextLeaf = this.quill()?.getLeaf(range.index + 1)[0];
|
|
473
|
+
this.quill()?.insertEmbed(range.index, 'break', true, 'user');
|
|
474
|
+
if (nextLeaf === null || currentLeaf.parent !== nextLeaf.parent) {
|
|
475
|
+
this.quill()?.insertEmbed(range.index, 'break', true, 'user');
|
|
476
|
+
}
|
|
477
|
+
this.quill()?.setSelection((range.index || 0) + 1, 0, Quill.sources.SILENT);
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
if (!this.autoUpdateValueWhenTextChange()) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
this.updateValueByRootQuillHtml();
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
updateValueByRootQuillHtml() {
|
|
487
|
+
const html = this.removeUnwantedPart(this.quill()?.root.innerHTML || '');
|
|
488
|
+
if (!this.quill()?.root.getElementsByTagName('img').length && !this.quill()?.getText()) {
|
|
489
|
+
set(this.item(), this.fieldNameBind(), '');
|
|
490
|
+
this.validate();
|
|
491
|
+
this.outChange.emit(get(this.item(), this.fieldNameBind()));
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
this.convertInnerHTMLAndSetValue(html);
|
|
495
|
+
this.validate();
|
|
496
|
+
this.outChange.emit(get(this.item(), this.fieldNameBind()));
|
|
497
|
+
}
|
|
498
|
+
handlerPopoverFunctionControl(event) {
|
|
499
|
+
this.popoverFunctionControl.set(event);
|
|
500
|
+
}
|
|
501
|
+
handlerPopoverEvent(event) {
|
|
502
|
+
if (event === 'remove') {
|
|
503
|
+
this.link.set(linkDefault());
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
handlerUnlink(event) {
|
|
507
|
+
event.stopPropagation();
|
|
508
|
+
const link = this.link();
|
|
509
|
+
this.quill()?.formatText(link.range.index, link.range.length, { link: false });
|
|
510
|
+
this.popoverFunctionControl()?.removePopoverOverlay();
|
|
511
|
+
}
|
|
512
|
+
handlerEdit(event) {
|
|
513
|
+
event.stopPropagation();
|
|
514
|
+
const link = this.link();
|
|
515
|
+
if (this.ignoreShowPopupEditLink()) {
|
|
516
|
+
this.outShowPopupEditLink.emit({
|
|
517
|
+
dataLink: link,
|
|
518
|
+
callback: async (linkEdit) => {
|
|
519
|
+
if (link instanceof Object && link.url) {
|
|
520
|
+
this.quill()?.deleteText(link.range.index, link.range.length, Quill.sources.USER);
|
|
521
|
+
this.quill()?.insertText(link.range.index, linkEdit.title, 'link', linkEdit.link);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
this.insertLink(linkEdit.title, linkEdit.link);
|
|
525
|
+
},
|
|
526
|
+
});
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
this.handleShowUploadLink(link);
|
|
530
|
+
this.popoverFunctionControl()?.removePopoverOverlay();
|
|
531
|
+
}
|
|
532
|
+
async calculatorToolbar() {
|
|
533
|
+
this.cdr.detectChanges();
|
|
534
|
+
this.timeCalculationToolBar.set(setTimeout(() => {
|
|
535
|
+
const toolbarWidth = this.toolbarItemsEl().nativeElement.offsetWidth || 0;
|
|
536
|
+
let totalWidth = 32 + 28;
|
|
537
|
+
this.toolbarOptionsConfig.update((configs) => {
|
|
538
|
+
configs.forEach((item, index) => {
|
|
539
|
+
item.display = true;
|
|
540
|
+
totalWidth += item.width;
|
|
541
|
+
if (item.type === 'line') {
|
|
542
|
+
const nextItemWidth = totalWidth + this.toolbarOptionsConfig()[+index + 1].width;
|
|
543
|
+
const preItem = this.toolbarOptionsConfig()[+index - 1];
|
|
544
|
+
if (nextItemWidth > toolbarWidth && preItem.display === true) {
|
|
545
|
+
item.display = undefined;
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (totalWidth > toolbarWidth) {
|
|
550
|
+
item.display = false;
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
return [...configs];
|
|
555
|
+
});
|
|
556
|
+
this.cdr.detectChanges();
|
|
557
|
+
}, 600));
|
|
558
|
+
}
|
|
559
|
+
setStyle(type, data) {
|
|
560
|
+
this.quill()?.format(type, data);
|
|
561
|
+
}
|
|
562
|
+
getFontSize(format) {
|
|
563
|
+
const fontSize = format?.size?.toString()?.replace('px', '');
|
|
564
|
+
if (isNaN(parseFloat(fontSize))) {
|
|
565
|
+
this.size.set({ value: 14 });
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
this.size.set({ value: parseFloat(fontSize) });
|
|
569
|
+
}
|
|
570
|
+
getFont(format) {
|
|
571
|
+
const font = listFont().find((item) => item.key === format.font);
|
|
572
|
+
if (!font) {
|
|
573
|
+
this.fontSelected.set({ key: '', item: listFont().find((item) => item.key === '') });
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
this.fontSelected.set({ key: format.font, item: font });
|
|
577
|
+
}
|
|
578
|
+
handleUndo() {
|
|
579
|
+
this.quill()?.history?.undo();
|
|
580
|
+
}
|
|
581
|
+
handleRedo() {
|
|
582
|
+
this.quill()?.history?.redo();
|
|
583
|
+
}
|
|
584
|
+
async setContent(content) {
|
|
585
|
+
const contentXssFilter = await xssFilter(this.removeUnwantedPart(content || ''));
|
|
586
|
+
await lastValueFrom(timer(1));
|
|
587
|
+
(this.quill()?.root).innerHTML = contentXssFilter;
|
|
588
|
+
if (!this.autoFocus()) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
await lastValueFrom(timer(100));
|
|
592
|
+
const target = this.quillEditorEl()?.nativeElement.querySelector('[contenteditable="true"]');
|
|
593
|
+
const contentScroll = this.heightAuto() ? this.wrapperEditorEl()?.nativeElement : target;
|
|
594
|
+
contentScroll.scrollTop = contentScroll.scrollHeight;
|
|
595
|
+
if (this.focusBottom()) {
|
|
596
|
+
this.quill()?.setSelection(contentXssFilter.length, 0, Quill.sources.SILENT);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
this.quill()?.setSelection(0, 0, Quill.sources.SILENT);
|
|
600
|
+
}
|
|
601
|
+
handlerAddEmoji(emoji) {
|
|
602
|
+
this.insertText(emoji, undefined, true);
|
|
603
|
+
}
|
|
604
|
+
handleShowUploadLink(event) {
|
|
605
|
+
this.addEditLinkComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillLinkComponent));
|
|
606
|
+
const instance = this.addEditLinkComponentRef()?.instance;
|
|
607
|
+
const selection = this.quill()?.getSelection();
|
|
608
|
+
const textSelected = selection?.length ? this.quill()?.getText(selection?.index, selection?.length) : '';
|
|
609
|
+
const data = event;
|
|
610
|
+
this.addEditLinkComponentRef()?.setInput('zIndex', this.zIndex());
|
|
611
|
+
this.addEditLinkComponentRef()?.setInput('title', data?.title || textSelected);
|
|
612
|
+
this.addEditLinkComponentRef()?.setInput('link', data?.url || '');
|
|
613
|
+
this.addEditLinkComponentRef()?.setInput('ignoreCommunicateMicroEvent', this.ignoreCommunicateMicroEventPopup());
|
|
614
|
+
instance?.outSaveLink.subscribe((item) => {
|
|
615
|
+
if (data instanceof Object && data.url) {
|
|
616
|
+
this.quill()?.deleteText(data.range.index, data.range.length, Quill.sources.USER);
|
|
617
|
+
this.quill()?.insertText(data.range.index, item.title, 'link', item.link);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
this.insertLink(item.title, item.link);
|
|
621
|
+
});
|
|
622
|
+
instance?.outClose.subscribe(() => this.dynamicComponentService.remove(this.addEditLinkComponentRef()));
|
|
623
|
+
this.dynamicComponentService.addToBody(this.addEditLinkComponentRef());
|
|
624
|
+
}
|
|
625
|
+
handlerUnInsertLink() {
|
|
626
|
+
const selection = this.quill()?.getSelection(true);
|
|
627
|
+
if (!isNil(selection)) {
|
|
628
|
+
this.quill()?.formatText(selection, 'link', false);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
async validate() {
|
|
632
|
+
this.messageError.set('');
|
|
633
|
+
const validRequired = this.validRequired();
|
|
634
|
+
const item = this.item();
|
|
635
|
+
const fieldNameBind = this.fieldNameBind();
|
|
636
|
+
const value = get(item, fieldNameBind);
|
|
637
|
+
if (validRequired && validRequired.isRequired && (!fieldNameBind || !value || !value.trim())) {
|
|
638
|
+
this.messageError.set(validRequired.message || ERROR_MESSAGE_EMPTY_VALID);
|
|
639
|
+
this.outMessageError.emit(this.messageError());
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
const validMinLength = this.validMinLength();
|
|
643
|
+
if (validMinLength && fieldNameBind && value && value.trim().length < validMinLength.length) {
|
|
644
|
+
this.messageError.set(validMinLength.message || ERROR_MESSAGE_MIN_LENGTH);
|
|
645
|
+
this.outMessageError.emit(this.messageError());
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
const validMaxLength = this.validMaxLength();
|
|
649
|
+
if (validMaxLength && fieldNameBind && value && value.trim().length > this.validMaxLength.length) {
|
|
650
|
+
this.messageError.set(validMaxLength.message || ERROR_MESSAGE_MAX_LENGTH);
|
|
651
|
+
this.outMessageError.emit(this.messageError());
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
this.outMessageError.emit(this.messageError());
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
657
|
+
async insertImage(content, index) {
|
|
658
|
+
const selection = index ?? this.quill()?.getSelection(true).index;
|
|
659
|
+
if (!isNil(selection)) {
|
|
660
|
+
this.quill()?.insertEmbed(selection, 'image', content);
|
|
661
|
+
this.quill()?.setSelection(selection + 1, 0);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
async insertText(content, index, focusLast) {
|
|
665
|
+
index = index ?? this.quill()?.getSelection(true).index;
|
|
666
|
+
if (!isNil(index)) {
|
|
667
|
+
this.quill()?.insertText(index, content, Quill.sources.USER);
|
|
668
|
+
if (focusLast) {
|
|
669
|
+
await lastValueFrom(timer(0));
|
|
670
|
+
this.quill()?.setSelection(index + content.length, 0, Quill.sources.USER);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
async insertLink(text, url, index) {
|
|
675
|
+
const selection = this.quill()?.getSelection(true);
|
|
676
|
+
const indexInsert = index ?? selection?.index;
|
|
677
|
+
if (selection?.length) {
|
|
678
|
+
this.quill()?.deleteText(selection.index, selection.length, Quill.sources.USER);
|
|
679
|
+
}
|
|
680
|
+
if (!isNil(indexInsert)) {
|
|
681
|
+
this.quill()?.insertText(indexInsert, text, 'link', url);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
convertInnerHTMLAndSetValue(html) {
|
|
685
|
+
this.setStyleForContent();
|
|
686
|
+
set(this.item(), this.fieldNameBind(), html);
|
|
687
|
+
}
|
|
688
|
+
setStyleForContent() {
|
|
689
|
+
const styleArray = [
|
|
690
|
+
{ selector: '.ql-font-Arial', style: 'font-family: Arial' },
|
|
691
|
+
{ selector: '.ql-font-sans-serif', style: 'font-family: sans-serif' },
|
|
692
|
+
{ selector: '.ql-font-serif', style: 'font-family: serif' },
|
|
693
|
+
{ selector: '.ql-font-monospace', style: 'font-family: monospace' },
|
|
694
|
+
{ selector: '.ql-font-Helvetica', style: 'font-family: Helvetica' },
|
|
695
|
+
{ selector: '.libs-ui-quill-format-image', style: 'max-width: 100%; height: auto', overrideStyle: true },
|
|
696
|
+
{ selector: '.libs-ui-quill-mention', style: 'font-weight: 600;-moz-osx-font-smoothing: grayscale;-webkit-font-smoothing: antialiased; color: #7239EA', overrideStyle: true },
|
|
697
|
+
{ selector: 'blockquote', style: 'border-left: 4px solid #ccc; margin-bottom: 5px; margin-top: 5px; padding-left: 16px', overrideStyle: true },
|
|
698
|
+
];
|
|
699
|
+
this.blotsRegister()?.forEach((item) => {
|
|
700
|
+
styleArray.push({ selector: `.${item.className}`, style: item.style, overrideStyle: true });
|
|
701
|
+
});
|
|
702
|
+
styleArray.forEach((item) => {
|
|
703
|
+
const elements = this.quill()?.root.querySelectorAll(item.selector);
|
|
704
|
+
elements?.forEach((element) => {
|
|
705
|
+
if (item.overrideStyle) {
|
|
706
|
+
element.setAttribute('style', item.style);
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
// Fixbug issue: https://admin-cv.mobio.vn/issues/49092
|
|
710
|
+
let styleExist = element.getAttribute('style');
|
|
711
|
+
if (styleExist) {
|
|
712
|
+
['font-family: Arial', 'font-family: sans-serif', 'font-family: serif', 'font-family: monospace', 'font-family: Helvetica'].forEach((font) => {
|
|
713
|
+
styleExist = (styleExist?.includes(`${font};`) ? styleExist?.replace(`${font};`, '') : styleExist?.replace(font, ''));
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
element.setAttribute('style', styleExist ? `${styleExist}${styleExist[styleExist.length - 1] === ';' ? '' : ';'}${item.style};` : item.style);
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
handleToggleMention(show) {
|
|
721
|
+
this.showMention.set(show);
|
|
722
|
+
}
|
|
723
|
+
handlerShowUploadImage() {
|
|
724
|
+
if (this.uploadImageConfig().modeCustom) {
|
|
725
|
+
this.uploadImageComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillUploadImageComponent));
|
|
726
|
+
const instance = this.uploadImageComponentRef()?.instance;
|
|
727
|
+
this.uploadImageComponentRef()?.setInput('uploadImageConfig', this.uploadImageConfig());
|
|
728
|
+
this.uploadImageComponentRef()?.setInput('ignoreCommunicateMicroEvent', this.ignoreCommunicateMicroEventPopup());
|
|
729
|
+
instance?.outClose.subscribe((link) => {
|
|
730
|
+
this.dynamicComponentService.remove(this.uploadImageComponentRef());
|
|
731
|
+
if (link) {
|
|
732
|
+
this.insertImage(link);
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
this.dynamicComponentService.addToBody(this.uploadImageComponentRef());
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
const input = document.createElement('input');
|
|
739
|
+
input.setAttribute('type', 'file');
|
|
740
|
+
input.setAttribute('accept', 'image/*');
|
|
741
|
+
input.click();
|
|
742
|
+
input.onchange = async () => {
|
|
743
|
+
await this.uploadImagesAndInsert(input?.files);
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
async uploadImagesAndInsert(files) {
|
|
747
|
+
if (!files) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const maxImageSize = this.uploadImageConfig()?.maxImageSize || 5 * 1024 * 1024;
|
|
751
|
+
const images = Array.from(files).filter((file) => file && file.type.split('/')[0] === 'image' && (!this.uploadImageConfig().maxImageSize || file.size <= maxImageSize));
|
|
752
|
+
if (!images.length) {
|
|
753
|
+
this.notificationService.showCompTypeTextWarning(this.translate.instant('i18n_note_upload_image_volume', { value: getLabelBySizeFile(maxImageSize) }), { timeRemove: 8000 });
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
try {
|
|
757
|
+
this.loadingUploadImage.set(true);
|
|
758
|
+
const indexInsert = this.quill()?.getSelection(true).index;
|
|
759
|
+
const links = await this.uploadImageConfig().functionUploadImage?.(images);
|
|
760
|
+
if (!links?.length) {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
links.forEach((link) => {
|
|
764
|
+
if (!link || (this.uploadImageConfig().onlyAcceptImageHttpsLink && (link instanceof ArrayBuffer || !new RegExp(patternUrl()).test(link)))) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
this.insertImage(link, indexInsert);
|
|
768
|
+
});
|
|
769
|
+
this.scrollToSelectionWithElementScrollHeightAuto(indexInsert);
|
|
770
|
+
}
|
|
771
|
+
catch (error) {
|
|
772
|
+
console.error(error);
|
|
773
|
+
}
|
|
774
|
+
finally {
|
|
775
|
+
this.loadingUploadImage.set(false);
|
|
776
|
+
}
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
insertMention(event) {
|
|
780
|
+
const range = this.quill()?.getSelection();
|
|
781
|
+
if (!range) {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
const cursorPos = range.index;
|
|
785
|
+
const startPosInsert = cursorPos - event.lengthKey;
|
|
786
|
+
this.quill()?.deleteText(startPosInsert, event.lengthKey, Quill.sources.USER);
|
|
787
|
+
this.quill()?.insertEmbed(startPosInsert, 'mention', event.data, Quill.sources.USER);
|
|
788
|
+
this.insertText(' ', startPosInsert + 1);
|
|
789
|
+
this.quill()?.setSelection(startPosInsert + 2, 0, Quill.sources.USER);
|
|
790
|
+
}
|
|
791
|
+
handlerInsertMention(data) {
|
|
792
|
+
this.insertMention(data);
|
|
793
|
+
}
|
|
794
|
+
async setFontSize(size) {
|
|
795
|
+
this.quill()?.format('size', `${size}px`);
|
|
796
|
+
}
|
|
797
|
+
handlerValueChange(value) {
|
|
798
|
+
this.size.update((item) => ({ ...item, value: value }));
|
|
799
|
+
this.quill()?.format('size', `${this.size().value}px`);
|
|
800
|
+
}
|
|
801
|
+
handleSelectAlign(event) {
|
|
802
|
+
this.alignSelected.set(event);
|
|
803
|
+
this.setStyle('align', event?.key);
|
|
804
|
+
}
|
|
805
|
+
handleSelectFont(event) {
|
|
806
|
+
this.fontSelected.set(event);
|
|
807
|
+
this.setStyle('font', event?.key);
|
|
808
|
+
}
|
|
809
|
+
handlerChangeShowMoreAction(event) {
|
|
810
|
+
event.stopPropagation();
|
|
811
|
+
this.showMoreAction.update((item) => !item);
|
|
812
|
+
}
|
|
813
|
+
scrollToSelectionWithElementScrollHeightAuto(index) {
|
|
814
|
+
clearTimeout(this.timeoutScrollToSelectionWithElementScrollHeightAuto());
|
|
815
|
+
if (!this.elementScrollHeightAuto()) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
this.timeoutScrollToSelectionWithElementScrollHeightAuto.set(setTimeout(() => {
|
|
819
|
+
index = index ?? this.quill()?.getSelection(true).index;
|
|
820
|
+
if (!isNil(index)) {
|
|
821
|
+
const bounds = this.quill()?.getBounds(index, 1);
|
|
822
|
+
this.elementScrollHeightAuto()?.scrollTo(0, (bounds?.top || 0) - 20);
|
|
823
|
+
}
|
|
824
|
+
}, 100));
|
|
825
|
+
}
|
|
826
|
+
getQlEditorElement() {
|
|
827
|
+
if (this.qlEditorElement()) {
|
|
828
|
+
return this.qlEditorElement();
|
|
829
|
+
}
|
|
830
|
+
for (const elementNode of this.quillEditorEl().nativeElement.getElementsByClassName('ql-editor')) {
|
|
831
|
+
this.qlEditorElement.set(elementNode);
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
return this.qlEditorElement();
|
|
835
|
+
}
|
|
836
|
+
removeUnwantedPart(html) {
|
|
837
|
+
if (!html) {
|
|
838
|
+
return '';
|
|
839
|
+
}
|
|
840
|
+
return html
|
|
841
|
+
.replace(/^\s*<p><br><\/p>/, '')
|
|
842
|
+
.replace(/<div><br><\/div>/gi, '')
|
|
843
|
+
.replace(/[\u200B-\u200D\uFEFF]/g, '');
|
|
844
|
+
}
|
|
845
|
+
handleSelectHeader(event) {
|
|
846
|
+
this.headerSelected.set(event);
|
|
847
|
+
this.setStyle('header', event?.key);
|
|
848
|
+
}
|
|
849
|
+
ngOnDestroy() {
|
|
850
|
+
this.onDestroy.next();
|
|
851
|
+
this.onDestroy.complete();
|
|
852
|
+
this.dynamicComponentService.remove(this.addEditLinkComponentRef());
|
|
853
|
+
this.dynamicComponentService.remove(this.uploadImageComponentRef());
|
|
854
|
+
clearTimeout(this.timeCalculationToolBar());
|
|
855
|
+
clearTimeout(this.timeoutScrollToSelectionWithElementScrollHeightAuto());
|
|
856
|
+
}
|
|
857
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
858
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsInputsQuillComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill", inputs: { isShowToolBar: { classPropertyName: "isShowToolBar", publicName: "isShowToolBar", isSignal: true, isRequired: false, transformFunction: null }, isToolbarPositionFixed: { classPropertyName: "isToolbarPositionFixed", publicName: "isToolbarPositionFixed", isSignal: true, isRequired: false, transformFunction: null }, classIncludeToolbar: { classPropertyName: "classIncludeToolbar", publicName: "classIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, stylesIncludeToolbar: { classPropertyName: "stylesIncludeToolbar", publicName: "stylesIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, toolbarConfig: { classPropertyName: "toolbarConfig", publicName: "toolbarConfig", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", 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: false, transformFunction: null }, autoUpdateValueWhenTextChange: { classPropertyName: "autoUpdateValueWhenTextChange", publicName: "autoUpdateValueWhenTextChange", isSignal: true, isRequired: false, transformFunction: null }, fieldNameBind: { classPropertyName: "fieldNameBind", publicName: "fieldNameBind", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, onlyShowErrorBorderInContent: { classPropertyName: "onlyShowErrorBorderInContent", publicName: "onlyShowErrorBorderInContent", isSignal: true, isRequired: false, transformFunction: null }, classIncludeTemplate: { classPropertyName: "classIncludeTemplate", publicName: "classIncludeTemplate", isSignal: true, isRequired: false, transformFunction: null }, classInclude: { classPropertyName: "classInclude", publicName: "classInclude", isSignal: true, isRequired: false, transformFunction: null }, handlersExpand: { classPropertyName: "handlersExpand", publicName: "handlersExpand", 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 }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, dataConfigMention: { classPropertyName: "dataConfigMention", publicName: "dataConfigMention", isSignal: true, isRequired: false, transformFunction: null }, blotsRegister: { classPropertyName: "blotsRegister", publicName: "blotsRegister", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, focusBottom: { classPropertyName: "focusBottom", publicName: "focusBottom", isSignal: true, isRequired: false, transformFunction: null }, blockUndoRedoKeyboard: { classPropertyName: "blockUndoRedoKeyboard", publicName: "blockUndoRedoKeyboard", isSignal: true, isRequired: false, transformFunction: null }, templateToolBarPersonalize: { classPropertyName: "templateToolBarPersonalize", publicName: "templateToolBarPersonalize", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, uploadImageConfig: { classPropertyName: "uploadImageConfig", publicName: "uploadImageConfig", isSignal: true, isRequired: false, transformFunction: null }, heightAuto: { classPropertyName: "heightAuto", publicName: "heightAuto", isSignal: true, isRequired: false, transformFunction: null }, elementScrollHeightAuto: { classPropertyName: "elementScrollHeightAuto", publicName: "elementScrollHeightAuto", 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 } }, outputs: { item: "itemChange", outShowPopupEditLink: "outShowPopupEditLink", outMessageError: "outMessageError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outFunctionsControl: "outFunctionsControl", outSelectionChange: "outSelectionChange", outTextChange: "outTextChange", outContextMenu: "outContextMenu" }, viewQueries: [{ propertyName: "wrapperEditorEl", first: true, predicate: ["wrapperEditor"], descendants: true, isSignal: true }, { propertyName: "editorEl", first: true, predicate: ["editor"], descendants: true, isSignal: true }, { propertyName: "quillOptionEl", first: true, predicate: ["quillOption"], descendants: true, isSignal: true }, { propertyName: "quillEditorEl", first: true, predicate: ["quillEditor"], descendants: true, isSignal: true }, { propertyName: "toolbarItemsEl", first: true, predicate: ["toolbarItems"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col w-full h-full\">\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 #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\n [attr.isToolbarPositionFixed]=\"isToolbarPositionFixed()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div\n #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n <div\n #quillOption\n [class.!top-[-9999px]]=\"!isShowToolBar()\"\n [class.!left-[-9999px]]=\"!isShowToolBar()\"\n [style]=\"stylesIncludeToolbar()\"\n [class.pointer-events-none]=\"readonly() || loadingUploadImage()\"\n class=\"{{ isToolbarPositionFixed() ? 'fixed !z-10 w-[510px] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation' : '' }} {{ classIncludeToolbar() }} h-[44px] shrink-0\"\n [class.bg-[#f8f9fa]]=\"!readonly() && !loadingUploadImage()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n <div\n #quillEditor\n LibsUiComponentsInputsMentionDirective\n [timeDelayInit]=\"timeDelayInit() + 50\"\n [mentionConfig]=\"dataConfigMention()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\"\n [class.pointer-events-none]=\"loadingUploadImage()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\n <ng-container\n #qlEditorScroll\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!qlEditorElement()\"\n [elementScroll]=\"qlEditorElement()\" />\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n @if (loadingUploadImage()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbar>\n <div\n class=\"toolbar h-full w-full shrink-0\"\n #toolbarItems>\n @if (displaySkeleton()) {\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]\">\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=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (displayShowMoreToolbar()) {\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=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemTemplate\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 [listMaxItemShow]=\"8\"\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 [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\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=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($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 (outColorChange)=\"setStyle('color', $event)\">\n <div class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></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 (outColorChange)=\"setStyle('background', $event)\">\n <div class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></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\"></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\"></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\"></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\"></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 [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></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 === '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\"></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 === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\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 [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outFunctionsControl)=\"handlerPopoverFunctionControl($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)=\"handlerEdit($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: ["@-webkit-keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}@keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}.libs-ui-quill{height:100%;width:100%;display:flex;flex-direction:column}.libs-ui-quill-toolbar-animation{animation:animation-move .4s ease}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:solid 1px #e6e8ed!important;border-radius:0 0 4px 4px}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-toolbar.ql-snow{border:solid 1px #e6e8ed!important;border-radius:4px 4px 0 0;border-bottom:unset!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill[showError=true] ::ng-deep .ql-container.ql-snow{border:solid 1px #ee2d41!important}:host ::ng-deep .toolbar,:host ::ng-deep .ql-formats{position:relative;width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-formats{display:flex}:host ::ng-deep .ql-container.ql-snow{width:100%;height:100%;position:relative}:host ::ng-deep .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:400}:host ::ng-deep .ql-editor b{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}:host ::ng-deep .ql-toolbar.ql-snow{border:none;border-radius:8px;padding:0}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label{color:#071631;border:none!important;margin-top:5px}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke{stroke:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-item:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active{color:#071631}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke{stroke:#071631}:host ::ng-deep .ql-editor{height:100%;width:100%;position:absolute;line-height:1.42!important}:host ::ng-deep .ql-editor:before{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;color:#9ca2ad!important;font-size:12px}:host ::ng-deep .ql-editor img{height:auto;max-width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border:none!important}:host ::ng-deep .ql-snow .ql-picker.ql-bold{width:36px!important}:host ::ng-deep .ql-editor.ql-blank{font-size:11px!important;letter-spacing:.05px;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;line-height:16px}:host ::ng-deep .ql-editor.ql-blank:before{font-style:normal!important;color:#9ca2ad!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label :hover{color:red!important}:host ::ng-deep .ql-formats{margin-right:12px!important}:host ::ng-deep .ql-formats .ql-size.ql-picker,:host ::ng-deep .ql-formats .ql-header.ql-picker,:host ::ng-deep .ql-formats .ql-font.ql-picker{border:solid 1px #e6e8ed!important;border-radius:4px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label{width:24px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label:hover{color:red!important}:host ::ng-deep .ql-formats .ql-header.ql-picker .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-picker-item:before{font-size:12px}:host ::ng-deep .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-snow.ql-toolbar button,:host ::ng-deep .ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:flex;align-items:center;float:none;padding:0;width:inherit}:host ::ng-deep ul{padding-left:1rem!important}:host ::ng-deep li{padding-left:0!important}:host ::ng-deep .ql-tooltip{display:none!important}.ql-picker-options{max-height:130px;overflow-y:auto}.ql-snow .ql-picker.ql-size{border:1px solid #e6e7ea;box-shadow:#00000005 0 1px 3px,#1b1f2326 0 0 0 1px;border-radius:2px}.ql-snow .ql-picker.ql-font{border:1px solid #e6e7ea!important;margin-right:8px;border-radius:4px}.ql-snow .ql-picker.ql-font .ql-picker-options:before{font-size:12px}.ql-snow .ql-picker.ql-font .ql-picker-label:before{font-size:12px}.ql-font-Arial{font-family:Arial}.ql-font-sans-serif{font-family:\"sans-serif\"}.ql-font-Helvetica{font-family:Helvetica}.libs-ui-quill-mention{font-weight:500!important;color:#7239ea;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}.ql-snow .ql-picker.ql-expanded .ql-picker-options{overflow:hidden}.ql-formats{margin-right:0!important}.ql-formats .ql-header{position:relative!important}.ql-formats .ql-header .ql-picker-options{position:absolute!important;top:-151px!important}.ql-formats .ql-font{position:relative!important}.ql-formats .ql-font .ql-picker-options{position:absolute!important;top:-93px!important}.ql-formats .ql-color{position:relative!important}.ql-formats .ql-color .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-background{position:relative!important}.ql-formats .ql-background .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-align{position:relative!important}.ql-formats .ql-align .ql-picker-label{padding:3px 4px!important}.ql-formats .ql-align .ql-picker-options{position:absolute!important;top:-106px}.ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LibsUiComponentsInputsMentionDirective, selector: "[LibsUiComponentsInputsMentionDirective]", inputs: ["timeDelayInit", "mentionConfig", "mentionListTemplate"], outputs: ["outSearchTerm", "outItemSelected", "outToggle", "outInsertMention", "outFunctionControl"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }, { 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: "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: 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: LibsUiComponentsButtonsSelectColorComponent, selector: "libs_ui-components-buttons-select_color", inputs: ["zIndex", "customOptions", "externalContent", "direction", "button", "applyNow"], outputs: ["zIndexChange", "outColorChange", "outColorChangeMultipleType"] }, { 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: LibsUiComponentsEmojiComponent, selector: "libs_ui-components-emoji", inputs: ["configPopover", "isNgContent", "zIndex", "modePopoverPosition", "classPopup", "classInclude", "classIconInclude"], outputs: ["outEventEmoji", "outFunctionsControl"] }, { 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: LibsUiComponentsSpinnerComponent, selector: "libs_ui-components-spinner", inputs: ["type", "size"] }, { kind: "component", type: LibsUiComponentsSkeletonComponent, selector: "libs_ui-components-skeleton", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
859
|
+
}
|
|
860
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, decorators: [{
|
|
861
|
+
type: Component,
|
|
862
|
+
args: [{ selector: 'libs_ui-components-inputs-quill', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
863
|
+
TranslateModule,
|
|
864
|
+
NgTemplateOutlet,
|
|
865
|
+
LibsUiComponentsInputsMentionDirective,
|
|
866
|
+
LibsUiComponentsScrollOverlayDirective,
|
|
867
|
+
LibsUiComponentsLabelComponent,
|
|
868
|
+
LibsUiComponentsDropdownComponent,
|
|
869
|
+
LibsUiComponentsPopoverComponent,
|
|
870
|
+
LibsUiComponentsButtonsSelectColorComponent,
|
|
871
|
+
LibsUiComponentsInputsValidComponent,
|
|
872
|
+
LibsUiComponentsEmojiComponent,
|
|
873
|
+
LibsUiComponentsButtonsButtonComponent,
|
|
874
|
+
LibsUiComponentsSpinnerComponent,
|
|
875
|
+
LibsUiComponentsSkeletonComponent,
|
|
876
|
+
], template: "<div class=\"flex flex-col w-full h-full\">\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 #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\n [attr.isToolbarPositionFixed]=\"isToolbarPositionFixed()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div\n #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n <div\n #quillOption\n [class.!top-[-9999px]]=\"!isShowToolBar()\"\n [class.!left-[-9999px]]=\"!isShowToolBar()\"\n [style]=\"stylesIncludeToolbar()\"\n [class.pointer-events-none]=\"readonly() || loadingUploadImage()\"\n class=\"{{ isToolbarPositionFixed() ? 'fixed !z-10 w-[510px] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation' : '' }} {{ classIncludeToolbar() }} h-[44px] shrink-0\"\n [class.bg-[#f8f9fa]]=\"!readonly() && !loadingUploadImage()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n <div\n #quillEditor\n LibsUiComponentsInputsMentionDirective\n [timeDelayInit]=\"timeDelayInit() + 50\"\n [mentionConfig]=\"dataConfigMention()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\"\n [class.pointer-events-none]=\"loadingUploadImage()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\n <ng-container\n #qlEditorScroll\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!qlEditorElement()\"\n [elementScroll]=\"qlEditorElement()\" />\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n @if (loadingUploadImage()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbar>\n <div\n class=\"toolbar h-full w-full shrink-0\"\n #toolbarItems>\n @if (displaySkeleton()) {\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]\">\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=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (displayShowMoreToolbar()) {\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=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemTemplate\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 [listMaxItemShow]=\"8\"\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 [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\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=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($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 (outColorChange)=\"setStyle('color', $event)\">\n <div class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></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 (outColorChange)=\"setStyle('background', $event)\">\n <div class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></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\"></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\"></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\"></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\"></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 [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></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 === '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\"></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 === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\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 [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outFunctionsControl)=\"handlerPopoverFunctionControl($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)=\"handlerEdit($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: ["@-webkit-keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}@keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}.libs-ui-quill{height:100%;width:100%;display:flex;flex-direction:column}.libs-ui-quill-toolbar-animation{animation:animation-move .4s ease}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:solid 1px #e6e8ed!important;border-radius:0 0 4px 4px}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-toolbar.ql-snow{border:solid 1px #e6e8ed!important;border-radius:4px 4px 0 0;border-bottom:unset!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill[showError=true] ::ng-deep .ql-container.ql-snow{border:solid 1px #ee2d41!important}:host ::ng-deep .toolbar,:host ::ng-deep .ql-formats{position:relative;width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-formats{display:flex}:host ::ng-deep .ql-container.ql-snow{width:100%;height:100%;position:relative}:host ::ng-deep .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:400}:host ::ng-deep .ql-editor b{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}:host ::ng-deep .ql-toolbar.ql-snow{border:none;border-radius:8px;padding:0}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label{color:#071631;border:none!important;margin-top:5px}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke{stroke:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-item:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active{color:#071631}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke{stroke:#071631}:host ::ng-deep .ql-editor{height:100%;width:100%;position:absolute;line-height:1.42!important}:host ::ng-deep .ql-editor:before{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;color:#9ca2ad!important;font-size:12px}:host ::ng-deep .ql-editor img{height:auto;max-width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border:none!important}:host ::ng-deep .ql-snow .ql-picker.ql-bold{width:36px!important}:host ::ng-deep .ql-editor.ql-blank{font-size:11px!important;letter-spacing:.05px;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;line-height:16px}:host ::ng-deep .ql-editor.ql-blank:before{font-style:normal!important;color:#9ca2ad!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label :hover{color:red!important}:host ::ng-deep .ql-formats{margin-right:12px!important}:host ::ng-deep .ql-formats .ql-size.ql-picker,:host ::ng-deep .ql-formats .ql-header.ql-picker,:host ::ng-deep .ql-formats .ql-font.ql-picker{border:solid 1px #e6e8ed!important;border-radius:4px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label{width:24px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label:hover{color:red!important}:host ::ng-deep .ql-formats .ql-header.ql-picker .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-picker-item:before{font-size:12px}:host ::ng-deep .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-snow.ql-toolbar button,:host ::ng-deep .ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:flex;align-items:center;float:none;padding:0;width:inherit}:host ::ng-deep ul{padding-left:1rem!important}:host ::ng-deep li{padding-left:0!important}:host ::ng-deep .ql-tooltip{display:none!important}.ql-picker-options{max-height:130px;overflow-y:auto}.ql-snow .ql-picker.ql-size{border:1px solid #e6e7ea;box-shadow:#00000005 0 1px 3px,#1b1f2326 0 0 0 1px;border-radius:2px}.ql-snow .ql-picker.ql-font{border:1px solid #e6e7ea!important;margin-right:8px;border-radius:4px}.ql-snow .ql-picker.ql-font .ql-picker-options:before{font-size:12px}.ql-snow .ql-picker.ql-font .ql-picker-label:before{font-size:12px}.ql-font-Arial{font-family:Arial}.ql-font-sans-serif{font-family:\"sans-serif\"}.ql-font-Helvetica{font-family:Helvetica}.libs-ui-quill-mention{font-weight:500!important;color:#7239ea;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}.ql-snow .ql-picker.ql-expanded .ql-picker-options{overflow:hidden}.ql-formats{margin-right:0!important}.ql-formats .ql-header{position:relative!important}.ql-formats .ql-header .ql-picker-options{position:absolute!important;top:-151px!important}.ql-formats .ql-font{position:relative!important}.ql-formats .ql-font .ql-picker-options{position:absolute!important;top:-93px!important}.ql-formats .ql-color{position:relative!important}.ql-formats .ql-color .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-background{position:relative!important}.ql-formats .ql-background .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-align{position:relative!important}.ql-formats .ql-align .ql-picker-label{padding:3px 4px!important}.ql-formats .ql-align .ql-picker-options{position:absolute!important;top:-106px}.ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}\n"] }]
|
|
877
|
+
}], ctorParameters: () => [] });
|
|
878
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2lucHV0cy9xdWlsbC9zcmMvcXVpbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2lucHV0cy9xdWlsbC9zcmMvcXVpbGwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVCxRQUFRLEVBQ1IsTUFBTSxFQUVOLE1BQU0sRUFDTixLQUFLLEVBQ0wsS0FBSyxFQUdMLE1BQU0sRUFDTixNQUFNLEVBRU4sU0FBUyxFQUNULFNBQVMsR0FFVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsc0NBQXNDLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUM1RixPQUFPLEVBQUUsMkNBQTJDLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUN2RyxPQUFPLEVBQWtCLGlDQUFpQyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDakcsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDbEYsT0FBTyxFQUFrQyxzQ0FBc0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzVILE9BQU8sRUFBZ0Msb0NBQW9DLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN0SCxPQUFPLEVBQVUsOEJBQThCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUVuRixPQUFPLEVBQWdDLGdDQUFnQyxFQUFzQixNQUFNLDZCQUE2QixDQUFDO0FBQ2pJLE9BQU8sRUFBRSxzQ0FBc0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFN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QywyQ0FBMkM7d0JBQzNDLG9DQUFvQzt3QkFDcEMsOEJBQThCO3dCQUM5QixzQ0FBc0M7d0JBQ3RDLGdDQUFnQzt3QkFDaEMsaUNBQWlDO3FCQUNsQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbXBvbmVudFJlZixcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgRWxlbWVudFJlZixcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgbW9kZWwsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBvdXRwdXQsXG4gIHNpZ25hbCxcbiAgVGVtcGxhdGVSZWYsXG4gIHVudHJhY2tlZCxcbiAgdmlld0NoaWxkLFxuICBXcml0YWJsZVNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYnV0dG9ucy1idXR0b24nO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNTZWxlY3RDb2xvckNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYnV0dG9ucy1zZWxlY3QtY29sb3InO1xuaW1wb3J0IHsgSUVtaXRTZWxlY3RLZXksIExpYnNVaUNvbXBvbmVudHNEcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtZHJvcGRvd24nO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0Vtb2ppQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtZW1vamknO1xuaW1wb3J0IHsgSU1lbnRpb25Db25maWcsIElNZW50aW9uSW5zZXJ0LCBMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkRpcmVjdGl2ZSB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtaW5wdXRzLW1lbnRpb24nO1xuaW1wb3J0IHsgSVZhbGlkTGVuZ3RoLCBJVmFsaWRSZXF1aXJlZCwgTGlic1VpQ29tcG9uZW50c0lucHV0c1ZhbGlkQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtdmFsaWQnO1xuaW1wb3J0IHsgSUxhYmVsLCBMaWJzVWlDb21wb25lbnRzTGFiZWxDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWxhYmVsJztcbmltcG9ydCB7IElMaXN0Q29uZmlnSXRlbSB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtbGlzdCc7XG5pbXBvcnQgeyBJUG9wb3ZlckZ1bmN0aW9uQ29udHJvbEV2ZW50LCBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckNvbXBvbmVudCwgVFlQRV9QT1BPVkVSX0VWRU5UIH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1wb3BvdmVyJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNTY3JvbGxPdmVybGF5RGlyZWN0aXZlIH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1zY3JvbGwtb3ZlcmxheSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzU2tlbGV0b25Db21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLXNrZWxldG9uJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNTcGlubmVyQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1zcGlubmVyJztcbmltcG9ydCB7IFRZUEVfT0JKRUNULCBUWVBFX1RFTVBMQVRFX1JFRiB9IGZyb20gJ0BsaWJzLXVpL2ludGVyZmFjZXMtdHlwZXMnO1xuaW1wb3J0IHsgTGlic1VpRHluYW1pY0NvbXBvbmVudFNlcnZpY2UgfSBmcm9tICdAbGlicy11aS9zZXJ2aWNlcy1keW5hbWljLWNvbXBvbmVudCc7XG5pbXBvcnQgeyBMaWJzVWlOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnQGxpYnMtdWkvc2VydmljZXMtbm90aWZpY2F0aW9uJztcbmltcG9ydCB7IEVSUk9SX01FU1NBR0VfRU1QVFlfVkFMSUQsIEVSUk9SX01FU1NBR0VfTUFYX0xFTkdUSCwgRVJST1JfTUVTU0FHRV9NSU5fTEVOR1RILCBnZXQsIGdldExhYmVsQnlTaXplRmlsZSwgaXNOaWwsIHBhdHRlcm5VcmwsIHNldCwgeHNzRmlsdGVyIH0gZnJvbSAnQGxpYnMtdWkvdXRpbHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlLCBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgUXVpbGwsIHsgUmFuZ2VTdGF0aWMsIFNvdXJjZXMsIFN0cmluZ01hcCB9IGZyb20gJ3F1aWxsJztcbmltcG9ydCB7IGZyb21FdmVudCwgbGFzdFZhbHVlRnJvbSwgU3ViamVjdCwgdGFrZVVudGlsLCB0aW1lciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgUXVpbGxEaXZCbG90IH0gZnJvbSAnLi9ibG90cy1jdXN0b20vZGl2LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDdXN0b21JbWFnZUJsb3QgfSBmcm9tICcuL2Jsb3RzLWN1c3RvbS9pbWFnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgUXVpbGxNZW50aW9uQmxvdCB9IGZyb20gJy4vYmxvdHMtY3VzdG9tL21lbnRpb24uY29tcG9uZW50JztcbmltcG9ydCB7IGluZGVudFN0eWxlIH0gZnJvbSAnLi9pbmRlbnQtYXR0cmlidXRvci9pbmRlbnQtYXR0cmlidXRvci5jb21wb25lbnQnO1xuaW1wb3J0IHsgSVF1aWxsQmxvdFJlZ2lzdGVyLCBJUXVpbGxGdW5jdGlvbkNvbnRyb2xFdmVudCwgSVF1aWxsTGluaywgSVF1aWxsU2VsZWN0aW9uQ2hhbmdlLCBJUXVpbGxUZXh0Q2hhbmdlLCBJUXVpbGxUb29sYmFyQ29uZmlnLCBJUXVpbGxVcGxvYWRJbWFnZUNvbmZpZywgVFlQRV9NT0RFX0JBUl9DT05GSUdfT1BUSU9OIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3F1aWxsLmludGVyZmFjZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzSW5wdXRzUXVpbGxMaW5rQ29tcG9uZW50IH0gZnJvbSAnLi9saW5rL2xpbmsuY29tcG9uZW50JztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbFVwbG9hZEltYWdlQ29tcG9uZW50IH0gZnJvbSAnLi91cGxvYWQtaW1hZ2UvdXBsb2FkLWltYWdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBpY29uTGlzdCwgbGlua0RlZmF1bHQsIGxpc3RDb25maWdBbGlnbiwgbGlzdENvbmZpZ0ZvbnQsIGxpc3RDb25maWdIZWFkZXIsIGxpc3RGb250LCB0b29sQmFyT3B0aW9ucywgdXBsb2FkSW1hZ2VDb25maWdEZWZhdWx0IH0gZnJvbSAnLi91dGlscy9xdWlsbC5kZWZpbmUnO1xuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbGlic191aS1jb21wb25lbnRzLWlucHV0cy1xdWlsbCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZVVybDogJy4vcXVpbGwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vcXVpbGwuY29tcG9uZW50LnNjc3MnLFxuICBpbXBvcnRzOiBbXG4gICAgVHJhbnNsYXRlTW9kdWxlLFxuICAgIE5nVGVtcGxhdGVPdXRsZXQsXG4gICAgTGlic1VpQ29tcG9uZW50c0lucHV0c01lbnRpb25EaXJlY3RpdmUsXG4gICAgTGlic1VpQ29tcG9uZW50c1Njcm9sbE92ZXJsYXlEaXJlY3RpdmUsXG4gICAgTGlic1VpQ29tcG9uZW50c0xhYmVsQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNEcm9wZG93bkNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzQnV0dG9uc1NlbGVjdENvbG9yQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNJbnB1dHNWYWxpZENvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzRW1vamlDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNCdXR0b25Db21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c1NwaW5uZXJDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c1NrZWxldG9uQ29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzSW5wdXRzUXVpbGxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByb3RlY3RlZCBxbEVkaXRvckVsZW1lbnQgPSBzaWduYWw8SFRNTEVsZW1lbnQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgdGltZW91dFNjcm9sbFRvU2VsZWN0aW9uV2l0aEVsZW1lbnRTY3JvbGxIZWlnaHRBdXRvID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJvdGVjdGVkIGxvYWRpbmdVcGxvYWRJbWFnZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSB0aW1lRGVsYXlJbml0ID0gc2lnbmFsPG51bWJlcj4oMjApO1xuICBwcm90ZWN0ZWQgbWVzc2FnZUVycm9yID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICBwcm90ZWN0ZWQgZGlzcGxheSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBsaXN0Q29uZmlnQWxpZ24gPSBzaWduYWw8SUxpc3RDb25maWdJdGVtPihsaXN0Q29uZmlnQWxpZ24oKSk7XG4gIHByb3RlY3RlZCBhbGlnblNlbGVjdGVkID0gc2lnbmFsPElFbWl0U2VsZWN0S2V5IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcm90ZWN0ZWQgaWNvbkFsaWduU2VsZWN0ZWRDb21wdXRlZCA9IGNvbXB1dGVkKCgpID0+IGdldCh0aGlzLmFsaWduU2VsZWN0ZWQoKSwgJ2l0ZW0uaWNvbicpKTtcbiAgcHJvdGVjdGVkIGxpc3RDb25maWdGb250ID0gc2lnbmFsPElMaXN0Q29uZmlnSXRlbT4obGlzdENvbmZpZ0ZvbnQoKSk7XG4gIHByb3RlY3RlZCBmb250U2VsZWN0ZWQgPSBzaWduYWw8SUVtaXRTZWxlY3RLZXkgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByb3RlY3RlZCBsYWJlbEZvbnRTZWxlY3RlZENvbXB1dGVkID0gY29tcHV0ZWQoKCkgPT4gZ2V0KHRoaXMuZm9udFNlbGVjdGVkKCksICdpdGVtLmxhYmVsJykgfHwgJ1NhbnMgU2VyaWYnKTtcbiAgcHJvdGVjdGVkIGxpc3RDb25maWdIZWFkZXIgPSBzaWduYWw8SUxpc3RDb25maWdJdGVtPihsaXN0Q29uZmlnSGVhZGVyKCkpO1xuICBwcm90ZWN0ZWQgaGVhZGVyU2VsZWN0ZWQgPSBzaWduYWw8SUVtaXRTZWxlY3RLZXkgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByb3RlY3RlZCBsYWJlbEhlYWRlclNlbGVjdGVkQ29tcHV0ZWQgPSBjb21wdXRlZCgoKSA9PiBnZXQodGhpcy5oZWFkZXJTZWxlY3RlZCgpLCAnaXRlbS5sYWJlbCcpIHx8ICdOb3JtYWwnKTtcbiAgcHJvdGVjdGVkIHNpemUgPSBzaWduYWw8eyB2YWx1ZTogbnVtYmVyIH0+KHsgdmFsdWU6IDE0IH0pO1xuICBwcm90ZWN0ZWQgc2hvd01vcmVBY3Rpb24gPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgbGluayA9IHNpZ25hbDxJUXVpbGxMaW5rPihsaW5rRGVmYXVsdCgpKTtcbiAgcHJvdGVjdGVkIHRvb2xiYXJPcHRpb25zQ29uZmlnOiBXcml0YWJsZVNpZ25hbDxBcnJheTxJUXVpbGxUb29sYmFyQ29uZmlnPj4gPSBzaWduYWwoW10pO1xuXG4gIHByb3RlY3RlZCBkaXNwbGF5U2hvd01vcmVUb29sYmFyID0gY29tcHV0ZWQoKCkgPT4gdGhpcy50b29sYmFyT3B0aW9uc0NvbmZpZygpLnNvbWUoKGl0ZW0pID0+IGl0ZW0uZGlzcGxheSA9PT0gZmFsc2UpKTtcbiAgcHJvdGVjdGVkIGRpc3BsYXlTa2VsZXRvbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMudG9vbGJhck9wdGlvbnNDb25maWcoKS5ldmVyeSgoaXRlbSkgPT4gaXRlbS5kaXNwbGF5ID09PSB1bmRlZmluZWQpKTtcblxuICBwcml2YXRlIHRpbWVDYWxjdWxhdGlvblRvb2xCYXIgPSBzaWduYWw8bnVtYmVyIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIHBvcG92ZXJGdW5jdGlvbkNvbnRyb2wgPSBzaWduYWw8SVBvcG92ZXJGdW5jdGlvbkNvbnRyb2xFdmVudCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBxdWlsbCA9IHNpZ25hbDxRdWlsbCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBoYW5kbGVycyA9IHNpZ25hbDxSZWNvcmQ8c3RyaW5nLCAoLi4ucGFyYW1zOiBBcnJheTx1bmtub3duPikgPT4gdm9pZD4+KHsgdW5kbzogdGhpcy5oYW5kbGVVbmRvLmJpbmQodGhpcyksIHJlZG86IHRoaXMuaGFuZGxlUmVkby5iaW5kKHRoaXMpIH0pO1xuICBwcml2YXRlIHNob3dNZW50aW9uID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBhZGRFZGl0TGlua0NvbXBvbmVudFJlZiA9IHNpZ25hbDxDb21wb25lbnRSZWY8TGlic1VpQ29tcG9uZW50c0lucHV0c1F1aWxsTGlua0NvbXBvbmVudD4gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgdXBsb2FkSW1hZ2VDb21wb25lbnRSZWYgPSBzaWduYWw8Q29tcG9uZW50UmVmPExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbFVwbG9hZEltYWdlQ29tcG9uZW50PiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIGR5bmFtaWNDb21wb25lbnRTZXJ2aWNlID0gaW5qZWN0KExpYnNVaUR5bmFtaWNDb21wb25lbnRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSB0cmFuc2xhdGUgPSBpbmplY3QoVHJhbnNsYXRlU2VydmljZSk7XG5cbiAgcmVhZG9ubHkgaXNTaG93VG9vbEJhciA9IGlucHV0PGJvb2xlYW4sIGJvb2xlYW4gfCB1bmRlZmluZWQ+KHRydWUsIHsgdHJhbnNmb3JtOiAodmFsKSA9PiB2YWwgPz8gdHJ1ZSB9KTtcbiAgcmVhZG9ubHkgaXNUb29sYmFyUG9zaXRpb25GaXhlZCA9IGlucHV0PGJvb2xlYW4sIGJvb2xlYW4gfCB1bmRlZmluZWQ+KGZhbHNlLCB7IHRyYW5zZm9ybTogKHZhbCkgPT4gdmFsID8/IGZhbHNlIH0pO1xuICByZWFkb25seSBjbGFzc0luY2x1ZGVUb29sYmFyID0gaW5wdXQ8c3RyaW5nPignJyk7XG4gIHJlYWRvbmx5IHN0eWxlc0luY2x1ZGVUb29sYmFyID0gaW5wdXQ8VFlQRV9PQkpFQ1Q+KCk7XG4gIHJlYWRvbmx5IHRvb2xiYXJDb25maWcgPSBpbnB1dDx7XG4gICAgdHlwZTogVFlQRV9NT0RFX0JBUl9DT05GSUdfT1BUSU9OO1xuICAgIGNvbmZpZz86IEFycmF5PElRdWlsbFRvb2xiYXJDb25maWc+O1xuICB9PigpO1xuICByZWFkb25seSBwbGFjZWhvbGRlciA9IGlucHV0PHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPignaTE4bl9pbXBvcnRfY29udGVudCcsIHsgdHJhbnNmb3JtOiAodmFsdWUpID0+IHZhbHVlIHx8ICdpMThuX2ltcG9ydF9jb250ZW50JyB9KTtcbiAgcmVhZG9ubHkgbGFiZWwgPSBpbnB1dDxJTGFiZWwgfCB1bmRlZmluZWQ+KCk7XG4gIHJlYWRvbmx5IGl0ZW0gPSBtb2RlbDxUWVBFX09CSkVDVD4oKTtcbiAgLyoqxJHhurd0IGPhu50gbsOgeSBi4bqxbmcgZmFsc2UgxJHhu4MgdOG7kWkgxrB1IGhp4buHdSBuxINuZywgdsOgIGNo4buJIGzhuqV5IGThu68gbGnhu4d1IHJhIGtoaSBjw7MgecOqdSBj4bqndSBs4bqleSBk4buvIGxp4buHdSDEkeG7gyBn4butaSBsw6puIHNlcnZlciAsIGfhu41pIHJlZnJlc2hJdGVtVmFsdWUgxJHhu4MgY+G6rXAgbmjhuq10IGdpw6EgdHJpIHRo4bunIGPDtG5nKi9cbiAgcmVhZG9ubHkgYXV0b1VwZGF0ZVZhbHVlV2hlblRleHRDaGFuZ2UgPSBpbnB1dDxib29sZWFuLCBib29sZWFuIHwgdW5kZWZpbmVkPih0cnVlLCB7IHRyYW5zZm9ybTogKHZhbHVlKSA9PiB2YWx1ZSA/PyB0cnVlIH0pO1xuICByZWFkb25seSBmaWVsZE5hbWVCaW5kID0gaW5wdXQ8c3RyaW5nPigndmFsdWUnKTtcbiAgcmVhZG9ubHkgcmVhZG9ubHkgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBzaG93RXJyb3JMYWJlbCA9IGlucHV0PGJvb2xlYW4+KHRydWUpO1xuICByZWFkb25seSBzaG93RXJyb3JCb3JkZXIgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IG9ubHlTaG93RXJyb3JCb3JkZXJJbkNvbnRlbnQgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IGNsYXNzSW5jbHVkZVRlbXBsYXRlID0gaW5wdXQ8c3RyaW5nPigpO1xuICByZWFkb25seSBjbGFzc0luY2x1ZGUgPSBpbnB1dDxzdHJpbmc+KCk7XG4gIHJlYWRvbmx5IGhhbmRsZXJzRXhwYW5kID0gaW5wdXQ8QXJyYXk8eyB0aXRsZTogc3RyaW5nOyBhY3Rpb246ICgpID0+IHZvaWQgfT4+KCk7XG4gIHJlYWRvbmx5IHZhbGlkUmVxdWlyZWQgPSBpbnB1dDxJVmFsaWRSZXF1aXJlZD4oKTtcbiAgcmVhZG9ubHkgdmFsaWRNaW5MZW5ndGggPSBpbnB1dDxJVmFsaWRMZW5ndGg+KCk7XG4gIHJlYWRvbmx5IHZhbGlkTWF4TGVuZ3RoID0gaW5wdXQ8SVZhbGlkTGVuZ3RoPigpO1xuICByZWFkb25seSB6SW5kZXggPSBpbnB1dDxudW1iZXIsIG51bWJlciB8IHVuZGVmaW5lZD4oMTI1MCwgeyB0cmFuc2Zvcm06ICh2YWx1ZSkgPT4gdmFsdWUgfHwgMTI1MCB9KTtcbiAgcmVhZG9ubHkgZGF0YUNvbmZpZ01lbnRpb24gPSBpbnB1dDxJTWVudGlvbkNvbmZpZz4oKTtcbiAgcmVhZG9ubHkgYmxvdHNSZWdpc3RlciA9IGlucHV0PEFycmF5PElRdWlsbEJsb3RSZWdpc3Rlcj4+KCk7XG4gIHJlYWRvbmx5IGF1dG9Gb2N1cyA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGZvY3VzQm90dG9tID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgYmxvY2tVbmRvUmVkb0tleWJvYXJkID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgdGVtcGxhdGVUb29sQmFyUGVyc29uYWxpemUgPSBpbnB1dDxUZW1wbGF0ZVJlZjxUWVBFX1RFTVBMQVRFX1JFRj4+KCk7XG4gIHJlYWRvbmx5IHRlbXBsYXRlID0gaW5wdXQ8VGVtcGxhdGVSZWY8VFlQRV9URU1QTEFURV9SRUY+PigpO1xuICByZWFkb25seSB1cGxvYWRJbWFnZUNvbmZpZyA9IGlucHV0PElRdWlsbFVwbG9hZEltYWdlQ29uZmlnLCBJUXVpbGxVcGxvYWRJbWFnZUNvbmZpZyB8IHVuZGVmaW5lZD4odXBsb2FkSW1hZ2VDb25maWdEZWZhdWx0KCksIHsgdHJhbnNmb3JtOiAodmFsdWUpID0+IHZhbHVlIHx8IHVwbG9hZEltYWdlQ29uZmlnRGVmYXVsdCgpIH0pO1xuICByZWFkb25seSBoZWlnaHRBdXRvID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgZWxlbWVudFNjcm9sbEhlaWdodEF1dG8gPSBpbnB1dDxIVE1MRWxlbWVudD4oKTtcbiAgcmVhZG9ubHkgaWdub3JlU2hvd1BvcHVwRWRpdExpbmsgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBpZ25vcmVDb21tdW5pY2F0ZU1pY3JvRXZlbnRQb3B1cCA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IG91dFNob3dQb3B1cEVkaXRMaW5rID0gb3V0cHV0PHtcbiAgICBkYXRhTGluazogSVF1aWxsTGluaztcbiAgICBjYWxsYmFjazogKGxpbmtFZGl0OiB7IHRpdGxlOiBzdHJpbmc7IGxpbms6IHN0cmluZyB9KSA9PiBQcm9taXNlPHZvaWQ+O1xuICB9PigpO1xuICByZWFkb25seSBvdXRNZXNzYWdlRXJyb3IgPSBvdXRwdXQ8c3RyaW5nPigpO1xuICByZWFkb25seSBvdXRCbHVyID0gb3V0cHV0PHZvaWQ+KCk7XG4gIHJlYWRvbmx5IG91dEZvY3VzID0gb3V0cHV0PHZvaWQ+KCk7XG4gIHJlYWRvbmx5IG91dENoYW5nZSA9IG91dHB1dDxzdHJpbmc+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uc0NvbnRyb2wgPSBvdXRwdXQ8SVF1aWxsRnVuY3Rpb25Db250cm9sRXZlbnQ+KCk7XG4gIHJlYWRvbmx5IG91dFNlbGVjdGlvbkNoYW5nZSA9IG91dHB1dDxJUXVpbGxTZWxlY3Rpb25DaGFuZ2U+KCk7XG4gIHJlYWRvbmx5IG91dFRleHRDaGFuZ2UgPSBvdXRwdXQ8SVF1aWxsVGV4dENoYW5nZT4oKTtcbiAgcmVhZG9ubHkgb3V0Q29udGV4dE1lbnUgPSBvdXRwdXQ8TW91c2VFdmVudD4oKTtcblxuICByZWFkb25seSB3cmFwcGVyRWRpdG9yRWwgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ3dyYXBwZXJFZGl0b3InKTtcbiAgcmVhZG9ubHkgZWRpdG9yRWwgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2VkaXRvcicpO1xuICByZWFkb25seSBxdWlsbE9wdGlvbkVsID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdxdWlsbE9wdGlvbicpO1xuICByZWFkb25seSBxdWlsbEVkaXRvckVsID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdxdWlsbEVkaXRvcicpO1xuICByZWFkb25seSB0b29sYmFySXRlbXNFbCA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPigndG9vbGJhckl0ZW1zJyk7XG5cbiAgcHJpdmF0ZSBub3RpZmljYXRpb25TZXJ2aWNlID0gaW5qZWN0KExpYnNVaU5vdGlmaWNhdGlvblNlcnZpY2UpO1xuICBwcml2YXRlIGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBjbGFzc2VzID0gYCR7dGhpcy5jbGFzc0luY2x1ZGUoKSB8fCAnJ30gaC1mdWxsIHctZnVsbGBcbiAgICAgICAgICAuc3BsaXQoJyAnKVxuICAgICAgICAgIC5tYXAoKGl0ZW0pID0+IGl0ZW0udHJpbSgpKVxuICAgICAgICAgIC5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0pO1xuICAgICAgICB0aGlzLmdldFFsRWRpdG9yRWxlbWVudCgpPy5jbGFzc0xpc3QuYWRkKC4uLmNsYXNzZXMpO1xuICAgICAgfSwgdGhpcy50aW1lRGVsYXlJbml0KCkgKyAxMCk7XG4gICAgfSk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgdHlwZSA9IHRoaXMudG9vbGJhckNvbmZpZygpPy50eXBlIHx8ICdkZWZhdWx0JztcbiAgICAgIGNvbnN0IGhhc0ljb25JbWFnZSA9IHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKS5zaG93SWNvbiA/PyBmYWxzZTtcbiAgICAgIGNvbnN0IGhhc0ljb25QZXJzb25hbGl6ZSA9ICEhdGhpcy50ZW1wbGF0ZVRvb2xCYXJQZXJzb25hbGl6ZSgpO1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgdGhpcy50b29sYmFyT3B0aW9uc0NvbmZpZy5zZXQodGhpcy50b29sYmFyQ29uZmlnKCk/LmNvbmZpZyB8fCB0b29sQmFyT3B0aW9ucyh0eXBlLCBoYXNJY29uSW1hZ2UsIGhhc0ljb25QZXJzb25hbGl6ZSkpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHRoaXMuY2FsY3VsYXRvclRvb2xiYXIoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5vdXRGdW5jdGlvbnNDb250cm9sLmVtaXQodGhpcy5GdW5jdGlvbnNDb250cm9sKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgRnVuY3Rpb25zQ29udHJvbCgpOiBJUXVpbGxGdW5jdGlvbkNvbnRyb2xFdmVudCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNoZWNrSXNWYWxpZDogdGhpcy52YWxpZGF0ZS5iaW5kKHRoaXMpLFxuICAgICAgcmVmcmVzaEl0ZW1WYWx1ZTogdGhpcy51cGRhdGVWYWx1ZUJ5Um9vdFF1aWxsSHRtbC5iaW5kKHRoaXMpLFxuICAgICAgc2V0Q29udGVudDogdGhpcy5zZXRDb250ZW50LmJpbmQodGhpcyksXG4gICAgICBpbnNlcnRUZXh0OiB0aGlzLmluc2VydFRleHQuYmluZCh0aGlzKSxcbiAgICAgIGluc2VydExpbms6IHRoaXMuaW5zZXJ0TGluay5iaW5kKHRoaXMpLFxuICAgICAgaW5zZXJ0SW1hZ2U6IHRoaXMuaW5zZXJ0SW1hZ2UuYmluZCh0aGlzKSxcbiAgICAgIHNldEZvbnRTaXplOiB0aGlzLnNldEZvbnRTaXplLmJpbmQodGhpcyksXG4gICAgICBzZXRDb2xvcjogYXN5bmMgKGNvbG9yOiBzdHJpbmcpID0+IHRoaXMuc2V0U3R5bGUoJ2NvbG9yJywgY29sb3IpLFxuICAgICAgc2V0QmFja2dyb3VuZDogYXN5bmMgKGNvbG9yOiBzdHJpbmcpID0+IHRoaXMuc2V0U3R5bGUoJ2JhY2tncm91bmQnLCBjb2xvciksXG4gICAgICBxdWlsbDogKCkgPT4gdGhpcy5xdWlsbCgpIGFzIFF1aWxsLFxuICAgICAgc2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG86IHRoaXMuc2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8uYmluZCh0aGlzKSxcbiAgICAgIGluc2VydEVtYmVkOiBhc3luYyAocmFuZ2U6IHsgaW5kZXg6IG51bWJlcjsgaW5kZXhTZWxlY3Q6IG51bWJlcjsgbGVuZ3RoPzogbnVtYmVyIH0sIHR5cGU6IHN0cmluZywgZGF0YTogdW5rbm93biwgc291cmNlcz86IFNvdXJjZXMpID0+IHtcbiAgICAgICAgdGhpcy5xdWlsbCgpPy5pbnNlcnRFbWJlZChyYW5nZS5pbmRleCwgdHlwZSwgZGF0YSwgc291cmNlcyB8fCBRdWlsbC5zb3VyY2VzLlVTRVIpO1xuICAgICAgICB0aGlzLnF1aWxsKCk/LnNldFNlbGVjdGlvbihyYW5nZS5pbmRleFNlbGVjdCwgcmFuZ2UubGVuZ3RoIHx8IDAsIFF1aWxsLnNvdXJjZXMuVVNFUik7XG4gICAgICAgIHRoaXMuc2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8ocmFuZ2UuaW5kZXhTZWxlY3QpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9LFxuICAgICAgcmVDYWxjdWxhdG9yVG9vbGJhcjogdGhpcy5jYWxjdWxhdG9yVG9vbGJhci5iaW5kKHRoaXMpLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5zZXRIYW5kbGVyRnVuY3Rpb24oKTtcbiAgICBhd2FpdCBsYXN0VmFsdWVGcm9tKHRpbWVyKHRoaXMudGltZURlbGF5SW5pdCgpKSk7XG4gICAgdGhpcy5pbml0UXVpbGwoKTtcblxuICAgIHRoaXMuc2V0Q29udGVudChnZXQodGhpcy5pdGVtKCksIHRoaXMuZmllbGROYW1lQmluZCgpLCAnJykpO1xuICAgIHRoaXMuaGFuZGxlclRleHRDaGFuZ2UoKTtcbiAgICB0aGlzLmhhbmRsZXJTZWxlY3Rpb25DaGFuZ2UoKTtcbiAgICB0aGlzLmhhbmRsZXJQYXN0ZSgpO1xuICAgIC8vIGfhu41pIGjDoG0gbsOgeSDEkeG7gyBxdWlsbCDEkcOhbmggZOG6pXUgbMOgIMSRw6MgZm9jdXMgdHJvbmcga2hpIHF1aWxsIGNoxrBhIGto4bufaSB04bqhbyB4b25nIMSR4buDIGtow7RuZyBi4buLIHNjcm9sbCB4deG7kW5nIGTGsOG7m2kuc2F1IGtoaSBxdWlsbCBraOG7n2kgdOG6oW8geG9uZyB2w6AgY2hlY2sgbuG6v3UgxJFhbmcgZm9jdXMgxJFhbmcgxJHGsOG7o2MgYuG6rXQgdGjDrCBuw7Mga2jDtG5nIGfhu41pIGzhuqFpIGjDoG0gZm9jdXMgbuG7r2FcbiAgICB0aGlzLnF1aWxsKCk/LmZvY3VzKCk7XG4gICAgaWYgKHRoaXMuYXV0b0ZvY3VzKCkpIHtcbiAgICAgIHRoaXMuZGlzcGxheS5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLnF1aWxsKCk/LmJsdXIoKTtcbiAgICB9XG4gICAgZnJvbUV2ZW50KHdpbmRvdywgJ3Jlc2l6ZScpLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95KSkuc3Vic2NyaWJlKHRoaXMuY2FsY3VsYXRvclRvb2xiYXIuYmluZCh0aGlzKSk7XG4gICAgYXdhaXQgbGFzdFZhbHVlRnJvbSh0aW1lcig0MDApKTtcbiAgICB0aGlzLmRpc3BsYXkuc2V0KHRydWUpO1xuICAgIGNvbnN0IGN1cnNvclNwYW4gPSB0aGlzLnF1aWxsKCk/LnJvb3QucXVlcnlTZWxlY3RvcignLnFsLWN1cnNvcicpO1xuICAgIGlmIChjdXJzb3JTcGFuKSB7XG4gICAgICBjdXJzb3JTcGFuLnJlbW92ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdFF1aWxsKCkge1xuICAgIGNvbnN0IHNpemUgPSBRdWlsbC5pbXBvcnQoJ2F0dHJpYnV0b3JzL3N0eWxlL3NpemUnKTtcbiAgICBjb25zdCBhbGlnblN0eWxlID0gUXVpbGwuaW1wb3J0KCdhdHRyaWJ1dG9ycy9zdHlsZS9hbGlnbicpO1xuICAgIGNvbnN0IGljb25zID0gUXVpbGwuaW1wb3J0KCd1aS9pY29ucycpO1xuICAgIGNvbnN0IGl0YWxpYyA9IFF1aWxsLmltcG9ydCgnZm9ybWF0cy9pdGFsaWMnKTtcbiAgICBjb25zdCBib2xkID0gUXVpbGwuaW1wb3J0KCdmb3JtYXRzL2JvbGQnKTtcbiAgICBzaXplLndoaXRlbGlzdCA9IFtcbiAgICAgICc4cHgnLFxuICAgICAgJzlweCcsXG4gICAgICAnMTBweCcsXG4gICAgICAnMTFweCcsXG4gICAgICAnMTJweCcsXG4gICAgICAnMTNweCcsXG4gICAgICAnMTRweCcsXG4gICAgICAnMTVweCcsXG4gICAgICAnMTZweCcsXG4gICAgICAnMTdweCcsXG4gICAgICAnMThweCcsXG4gICAgICAnMTlweCcsXG4gICAgICAnMjBweCcsXG4gICAgICAnMjFweCcsXG4gICAgICAnMjJweCcsXG4gICAgICAnMjNweCcsXG4gICAgICAnMjRweCcsXG4gICAgICAnMjVweCcsXG4gICAgICAnMjZweCcsXG4gICAgICAnMjdweCcsXG4gICAgICAnMjhweCcsXG4gICAgICAnMjlweCcsXG4gICAgICAnMzBweCcsXG4gICAgICAnMzFweCcsXG4gICAgICAnMzJweCcsXG4gICAgICAnMzNweCcsXG4gICAgICAnMzRweCcsXG4gICAgICAnMzVweCcsXG4gICAgICAnMzZweCcsXG4gICAgICAnMzdweCcsXG4gICAgICAnMzhweCcsXG4gICAgICAnMzlweCcsXG4gICAgICAnNDBweCcsXG4gICAgICAnNDFweCcsXG4gICAgICAnNDJweCcsXG4gICAgICAnNDNweCcsXG4gICAgICAnNDRweCcsXG4gICAgICAnNDVweCcsXG4gICAgICAnNDZweCcsXG4gICAgICAnNDdweCcsXG4gICAgICAnNDhweCcsXG4gICAgICAnNDlweCcsXG4gICAgICAnNTBweCcsXG4gICAgICAnNTFweCcsXG4gICAgICAnNTJweCcsXG4gICAgICAnNTNweCcsXG4gICAgICAnNTRweCcsXG4gICAgICAnNTVweCcsXG4gICAgICAnNTZweCcsXG4gICAgICAnNTdweCcsXG4gICAgICAnNThweCcsXG4gICAgICAnNTlweCcsXG4gICAgICAnNjBweCcsXG4gICAgICAnNjFweCcsXG4gICAgICAnNjJweCcsXG4gICAgICAnNjNweCcsXG4gICAgICAnNjRweCcsXG4gICAgICAnNjVweCcsXG4gICAgICAnNjZweCcsXG4gICAgICAnNjdweCcsXG4gICAgICAnNjhweCcsXG4gICAgICAnNjlweCcsXG4gICAgICAnNzBweCcsXG4gICAgICAnNzFweCcsXG4gICAgICAnNzJweCcsXG4gICAgXTtcblxuICAgIGl0YWxpYy50YWdOYW1lID0gJ2knO1xuICAgIGJvbGQudGFnTmFtZSA9ICdiJztcbiAgICBRdWlsbC5yZWdpc3Rlcihib2xkLCB0cnVlKTtcbiAgICBRdWlsbC5yZWdpc3RlcihpdGFsaWMsIHRydWUpO1xuICAgIFF1aWxsLnJlZ2lzdGVyKHNpemUsIHRydWUpO1xuICAgIFF1aWxsLnJlZ2lzdGVyKEN1c3RvbUltYWdlQmxvdCwgdHJ1ZSk7XG4gICAgUXVpbGwucmVnaXN0ZXIoUXVpbGxEaXZCbG90LCB0cnVlKTtcbiAgICBRdWlsbC5yZWdpc3RlcihhbGlnblN0eWxlLCB0cnVlKTtcbiAgICBRdWlsbC5yZWdpc3RlcihRdWlsbE1lbnRpb25CbG90LCB0cnVlKTtcbiAgICB0aGlzLmJsb3RzUmVnaXN0ZXIoKT8uZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgUXVpbGwucmVnaXN0ZXIoaXRlbS5jb21wb25lbnQsIHRydWUpO1xuICAgIH0pO1xuICAgIFF1aWxsLnJlZ2lzdGVyKHsgJ2Zvcm1hdHMvaW5kZW50JzogaW5kZW50U3R5bGUgfSwgdHJ1ZSk7XG4gICAgZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHRoaXMucXVpbGxFZGl0b3JFbCgpPy5uYXRpdmVFbGVtZW50LCAnY29udGV4dG1lbnUnKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95KSlcbiAgICAgIC5zdWJzY3JpYmUoKGUpID0+IHRoaXMub3V0Q29udGV4dE1lbnUuZW1pdChlKSk7XG4gICAgaWNvbkxpc3QoKS5mb3JFYWNoKChlbGVtZW50KSA9PiBzZXQoaWNvbnMsIGVsZW1lbnQua2V5LCBgPHNwYW4gY2xhc3M9XCIke2VsZW1lbnQuaWNvbn0gaG92ZXI6dGV4dC1bdmFyKC0tbGlicy11aS1jb2xvci1saWdodC0xKV0gdGV4dC1bMTZweF0gdGV4dC1bIzZhNzM4M11cIj48L3NwYW4+YCkpO1xuICAgIHRoaXMucXVpbGwuc2V0KFxuICAgICAgbmV3IFF1aWxsKHRoaXMucXVpbGxFZGl0b3JFbCgpPy5uYXRpdmVFbGVtZW50LCB7XG4gICAgICAgIG1vZHVsZXM6IHtcbiAgICAgICAgICB0b29sYmFyOiB7XG4gICAgICAgICAgICBjb250YWluZXI6IHRoaXMucXVpbGxPcHRpb25FbCgpPy5uYXRpdmVFbGVtZW50LFxuICAgICAgICAgICAgaGFuZGxlcnM6IHRoaXMuaGFuZGxlcnMoKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNsaXBib2FyZDoge1xuICAgICAgICAgICAgbWF0Y2hWaXN1YWw6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgICAgZGVsYXk6IDEwMDAsXG4gICAgICAgICAgICBtYXhTdGFjazogMTAwLFxuICAgICAgICAgICAgdXNlck9ubHk6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5Ym9hcmQ6IHtcbiAgICAgICAgICAgIGJpbmRpbmdzOiB7XG4gICAgICAgICAgICAgIGVudGVyOiB7XG4gICAgICAgICAgICAgICAga2V5OiAxMyxcbiAgICAgICAgICAgICAgICBoYW5kbGVyOiAoKSA9PiAodGhpcy5zaG93TWVudGlvbigpID8gZmFsc2UgOiB0cnVlKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVhZE9ubHk6IHRoaXMucmVhZG9ubHkoKSxcbiAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQodGhpcy5wbGFjZWhvbGRlcigpKSxcbiAgICAgICAgdGhlbWU6ICdzbm93JyxcbiAgICAgICAgYm91bmRzOiB0aGlzLmhlaWdodEF1dG8oKSA/IHRoaXMud3JhcHBlckVkaXRvckVsKCk/Lm5hdGl2ZUVsZW1lbnQgOiB0aGlzLnF1aWxsRWRpdG9yRWwoKT8ubmF0aXZlRWxlbWVudCxcbiAgICAgICAgc2Nyb2xsaW5nQ29udGFpbmVyOiB0aGlzLmhlaWdodEF1dG8oKSA/IHRoaXMud3JhcHBlckVkaXRvckVsKCk/Lm5hdGl2ZUVsZW1lbnQgOiBudWxsLFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5xdWlsbCgpPy5rZXlib2FyZC5hZGRCaW5kaW5nKHsga2V5OiAnQmFja3NwYWNlJyB9LCB0aGlzLm5vUHJldmVudEVtYmVkRGVsZXRpb24uYmluZCh0aGlzKSk7XG4gICAgdGhpcy5xdWlsbCgpPy5rZXlib2FyZC5hZGRCaW5kaW5nKHsga2V5OiAnRGVsZXRlJyB9LCB0aGlzLm5vUHJldmVudEVtYmVkRGVsZXRpb24uYmluZCh0aGlzKSk7XG4gICAgdGhpcy5zZXR1cFVuZG9SZWRvQmxvY2tpbmcoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBVbmRvUmVkb0Jsb2NraW5nKCk6IHZvaWQge1xuICAgIGNvbnN0IGVkaXRvclJvb3QgPSB0aGlzLnF1aWxsKCk/LnJvb3Q7XG4gICAgaWYgKGVkaXRvclJvb3QgJiYgdGhpcy5ibG9ja1VuZG9SZWRvS2V5Ym9hcmQoKSkge1xuICAgICAgY29uc3Qga2V5ZG93bkhhbmRsZXIgPSAoZTogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgICBjb25zdCBpc1VuZG8gPSAoZS5rZXkgPT09ICd6JyB8fCBlLmtleSA9PT0gJ1onKSAmJiAoZS5jdHJsS2V5IHx8IGUubWV0YUtleSkgJiYgIWUuc2hpZnRLZXk7XG4gICAgICAgIGNvbnN0IGlzUmVkbyA9ICgoZS5rZXkgPT09ICd6JyB8fCBlLmtleSA9PT0gJ1onKSAmJiAoZS5jdHJsS2V5IHx8IGUubWV0YUtleSkgJiYgZS5zaGlmdEtleSkgfHwgKChlLmtleSA9PT0gJ3knIHx8IGUua2V5ID09PSAnWScpICYmIGUuY3RybEtleSk7XG5cbiAgICAgICAgaWYgKGlzVW5kbyB8fCBpc1JlZG8pIHtcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgQmxvY2tpbmcgJHtpc1VuZG8gPyAndW5kbycgOiAncmVkbyd9IGtleWJvYXJkIHNob3J0Y3V0YCk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGVkaXRvclJvb3QuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGtleWRvd25IYW5kbGVyLCB0cnVlKTtcblxuICAgICAgdGhpcy5vbkRlc3Ryb3kuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgZWRpdG9yUm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywga2V5ZG93bkhhbmRsZXIsIHRydWUpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBub1ByZXZlbnRFbWJlZERlbGV0aW9uKHJhbmdlOiBSYW5nZVN0YXRpYyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5xdWlsbCgpKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgZGVsdGEgPSB0aGlzLnF1aWxsKCk/LmdldENvbnRlbnRzKHJhbmdlLmluZGV4LCAxKTtcblxuICAgIGlmIChkZWx0YT8ub3BzLnNvbWUoKG9wdGlvbikgPT4gdGhpcy5ibG90c1JlZ2lzdGVyKCk/LmZpbmQoKGl0ZW0pID0+IGdldChvcHRpb24uaW5zZXJ0LCBpdGVtLmNvbXBvbmVudFsnYmxvdE5hbWUnXSkgJiYgaXRlbS5pZ25vcmVEZWxldGUpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlOyAvLyBOZ8SDbiBraMO0bmcgY2hvIFF1aWxsIHjhu60gbMO9IHjDs2FcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0SGFuZGxlckZ1bmN0aW9uKCkge1xuICAgIHRoaXMuaGFuZGxlcnMudXBkYXRlKChpdGVtKSA9PiAoe1xuICAgICAgLi4uaXRlbSxcbiAgICAgIGltYWdlOiB0aGlzLmhhbmRsZXJTaG93VXBsb2FkSW1hZ2UuYmluZCh0aGlzKSxcbiAgICAgIGVtb2ppOiAoKSA9PiB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0sXG4gICAgfSkpO1xuICAgIGxldCBsaW5rID0gZmFsc2U7XG4gICAgY29uc3QgaGFuZGxlcnNFeHBhbmQgPSB0aGlzLmhhbmRsZXJzRXhwYW5kKCk7XG4gICAgaWYgKGhhbmRsZXJzRXhwYW5kICYmIGhhbmRsZXJzRXhwYW5kLmxlbmd0aCkge1xuICAgICAgaGFuZGxlcnNFeHBhbmQuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoZWxlbWVudC50aXRsZSAmJiBlbGVtZW50LmFjdGlvbikge1xuICAgICAgICAgIGlmIChlbGVtZW50LnRpdGxlID09PSAnbGluaycpIHtcbiAgICAgICAgICAgIGxpbmsgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmhhbmRsZXJzLnVwZGF0ZSgoaXRlbSkgPT4gKHsgLi4uaXRlbSwgW2VsZW1lbnQudGl0bGVdOiBlbGVtZW50LmFjdGlvbiB9KSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoIWxpbmspIHtcbiAgICAgIHRoaXMuaGFuZGxlcnMudXBkYXRlKChpdGVtKSA9PiAoeyAuLi5pdGVtLCBsaW5rOiB0aGlzLmhhbmRsZVNob3dVcGxvYWRMaW5rLmJpbmQodGhpcyksIHVuTGluazogdGhpcy5oYW5kbGVyVW5JbnNlcnRMaW5rLmJpbmQodGhpcykgfSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRqdXN0SW5kZXhGb3JJbWFnZXMoaW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnF1aWxsKCk/LnJvb3Q7XG4gICAgbGV0IGltYWdlQ291bnQgPSAwO1xuICAgIGxldCBhZGp1c3RlZEluZGV4ID0gMDtcbiAgICBjb25zdCBhZGp1c3RUZXh0SW5kZXggPSAobm9kZTogTm9kZSkgPT4ge1xuICAgICAgaWYgKGFkanVzdGVkSW5kZXggPiBpbmRleCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgICAgYWRqdXN0ZWRJbmRleCArPSBub2RlLnRleHRDb250ZW50Py5sZW5ndGggfHwgMDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIG5vZGUubm9kZU5hbWUgPT09ICdJTUcnKSB7XG4gICAgICAgIGlmIChhZGp1c3RlZEluZGV4IDw9IGluZGV4KSB7XG4gICAgICAgICAgaW1hZ2VDb3VudCsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICBBcnJheS5mcm9tKG5vZGUuY2hpbGROb2RlcykuZm9yRWFjaChhZGp1c3RUZXh0SW5kZXgpO1xuICAgICAgfVxuICAgIH07XG4gICAgYWRqdXN0VGV4dEluZGV4KGNvbnRlbnQgYXMgTm9kZSk7XG4gICAgcmV0dXJuIGltYWdlQ291bnQ7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJTZWxlY3Rpb25DaGFuZ2UoKSB7XG4gICAgdGhpcy5xdWlsbCgpPy5vbignc2VsZWN0aW9uLWNoYW5nZScsIChyYW5nZTogUmFuZ2VTdGF0aWMsIG9sZFJhbmdlOiBSYW5nZVN0YXRpYywgc291cmNlOiBTb3VyY2VzKSA9PiB7XG4gICAgICBpZiAodGhpcy5yZWFkb25seSgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChyYW5nZSA9PT0gbnVsbCAmJiBvbGRSYW5nZSAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLm91dEJsdXIuZW1pdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAocmFuZ2UgIT09IG51bGwgJiYgb2xkUmFuZ2UgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5vdXRGb2N1cy5lbWl0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm1hdCA9IHRoaXMucXVpbGwoKT8uZ2V0Rm9ybWF0KCk7XG4gICAgICBpZiAoZm9ybWF0KSB7XG4gICAgICAgIHRoaXMuZ2V0Rm9udChmb3JtYXQpO1xuICAgICAgICB0aGlzLmdldEZvbnRTaXplKGZvcm1hdCk7XG4gICAgICB9XG4gICAgICB0aGlzLm91dFNlbGVjdGlvbkNoYW5nZS5lbWl0KHtcbiAgICAgICAgcXVpbGw6IHRoaXMucXVpbGwoKSBhcyBRdWlsbCxcbiAgICAgICAgcmFuZ2UsXG4gICAgICAgIG9sZFJhbmdlLFxuICAgICAgICBzb3VyY2UsXG4gICAgICB9KTtcbiAgICAgIGlmIChyYW5nZS5sZW5ndGggPT09IDAgJiYgZm9ybWF0Py5saW5rICYmIHNvdXJjZSA9PT0gJ3VzZXInKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuICAgICAgICBjb25zdCBhbmNob3JOb2RlID0gc2VsZWN0aW9uPy5hbmNob3JOb2RlO1xuICAgICAgICBsZXQgbGlua05vZGUgPSBhbmNob3JOb2RlIGFzIEhUTUxBbmNob3JFbGVtZW50O1xuICAgICAgICB3aGlsZSAobGlua05vZGUgJiYgbGlua05vZGUudGFnTmFtZSAhPT0gJ0EnKSB7XG4gICAgICAgICAgbGlua05vZGUgPSBsaW5rTm9kZS5wYXJlbnROb2RlIGFzIEhUTUxBbmNob3JFbGVtZW50O1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW5rTm9kZSAmJiBsaW5rTm9kZS50YWdOYW1lID09PSAnQScpIHtcbiAgICAgICAgICBjb25zdCBsaW5rVGV4dCA9IGxpbmtOb2RlLmlubmVyVGV4dDtcbiAgICAgICAgICBjb25zdCBsaW5rc0luZGljZXM6IEFycmF5PG51bWJlcj4gPSBbXTtcbiAgICAgICAgICBsZXQgaW5kZXhSZXR1cm46IG51bWJlciB8IHVuZGVmaW5lZCA9IC0xO1xuICAgICAgICAgIHdoaWxlICghaXNOaWwoaW5kZXhSZXR1cm4pICYmIGluZGV4UmV0dXJuIDwgcmFuZ2UuaW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnN0IHRleHRDb250ZW50ID0gdGhpcy5xdWlsbCgpPy5nZXRUZXh0KCk7XG4gICAgICAgICAgICBjb25zdCBsaW5rSW5kZXggPSB0ZXh0Q29udGVudD8uaW5kZXhPZihsaW5rVGV4dCwgbGlua3NJbmRpY2VzLmxlbmd0aCA+IDAgPyBsaW5rc0luZGljZXNbbGlua3NJbmRpY2VzLmxlbmd0aCAtIDFdICsgbGlua1RleHQubGVuZ3RoIDogMCk7XG4gICAgICAgICAgICBpZiAoIWlzTmlsKGxpbmtJbmRleCkpIHtcbiAgICAgICAgICAgICAgaWYgKGxpbmtJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBsaW5rc0luZGljZXMucHVzaChsaW5rSW5kZXgpO1xuICAgICAgICAgICAgICAgIGluZGV4UmV0dXJuID0gbGlua0luZGV4ICsgbGlua1RleHQubGVuZ3RoO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChsaW5rSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgaW5kZXhSZXR1cm4gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGxpbmtzSW5kaWNlcyAmJiBsaW5rc0luZGljZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCByYW5nZUluZGV4ID0gbGlua3NJbmRpY2VzW2xpbmtzSW5kaWNlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50SW1hZ2UgPSB0aGlzLmFkanVzdEluZGV4Rm9ySW1hZ2VzKHJhbmdlSW5kZXgpO1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMubGluay5zZXQoe1xuICAgICAgICAgICAgICAgIHRpdGxlOiBsaW5rVGV4dCxcbiAgICAgICAgICAgICAgICB1cmw6IGxpbmtOb2RlLmhyZWYsXG4gICAgICAgICAgICAgICAgcmFuZ2U6IHtcbiAgICAgICAgICAgICAgICAgIGluZGV4OiByYW5nZUluZGV4ICsgY291bnRJbWFnZSxcbiAgICAgICAgICAgICAgICAgIGxlbmd0aDogbGlua1RleHQubGVuZ3RoLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB0aGlzLnBvcG92ZXJGdW5jdGlvbkNvbnRyb2woKT8uc2hvd1BvcG92ZXIobGlua05vZGUpO1xuICAgICAgICAgICAgfSwgMjUwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlclBhc3RlKCkge1xuICAgIHNldDxhbnk+KHRoaXMucXVpbGwsICdyb290Lm9ucGFzdGUnLCBhc3luYyAoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAoIWV2ZW50IHx8ICFldmVudC5jbGlwYm9hcmREYXRhKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbGVzID0gZXZlbnQuY2xpcGJvYXJkRGF0YS5maWxlcztcbiAgICAgIGlmICghZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChldmVudC5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQnKSkge1xuICAgICAgICAgIHRoaXMuc2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZXNBbmRJbnNlcnQoZmlsZXMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyVGV4dENoYW5nZSgpIHtcbiAgICB0aGlzLnF1aWxsKCk/Lm9uKCd0ZXh0LWNoYW5nZScsIChldmVudCkgPT4ge1xuICAgICAgdGhpcy5vdXRUZXh0Q2hhbmdlLmVtaXQoe1xuICAgICAgICBxdWlsbDogdGhpcy5xdWlsbCgpIGFzIFF1aWxsLFxuICAgICAgICBkZWx0YTogZXZlbnQsXG4gICAgICB9KTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAoZXZlbnQ/Lm9wc1sxXT8uaW5zZXJ0ID09PSAnXFxuJykge1xuICAgICAgICAgIGNvbnN0IHJhbmdlID0geyBpbmRleDogZXZlbnQ/Lm9wc1swXS5yZXRhaW4gYXMgbnVtYmVyIH07XG4gICAgICAgICAgY29uc3QgY3VycmVudExlYWYgPSB0aGlzLnF1aWxsKCk/LmdldExlYWYocmFuZ2UuaW5kZXgpWzBdO1xuICAgICAgICAgIGNvbnN0IG5leHRMZWFmID0gdGhpcy5xdWlsbCgpPy5nZXRMZWFmKHJhbmdlLmluZGV4ICsgMSlbMF07XG4gICAgICAgICAgdGhpcy5xdWlsbCgpPy5pbnNlcnRFbWJlZChyYW5nZS5pbmRleCwgJ2JyZWFrJywgdHJ1ZSwgJ3VzZXInKTtcbiAgICAgICAgICBpZiAobmV4dExlYWYgPT09IG51bGwgfHwgY3VycmVudExlYWYucGFyZW50ICE9PSBuZXh0TGVhZi5wYXJlbnQpIHtcbiAgICAgICAgICAgIHRoaXMucXVpbGwoKT8uaW5zZXJ0RW1iZWQocmFuZ2UuaW5kZXgsICdicmVhaycsIHRydWUsICd1c2VyJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMucXVpbGwoKT8uc2V0U2VsZWN0aW9uKChyYW5nZS5pbmRleCB8fCAwKSArIDEsIDAsIFF1aWxsLnNvdXJjZXMuU0lMRU5UKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoIXRoaXMuYXV0b1VwZGF0ZVZhbHVlV2hlblRleHRDaGFuZ2UoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZVZhbHVlQnlSb290UXVpbGxIdG1sKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVZhbHVlQnlSb290UXVpbGxIdG1sKCkge1xuICAgIGNvbnN0IGh0bWwgPSB0aGlzLnJlbW92ZVVud2FudGVkUGFydCh0aGlzLnF1aWxsKCk/LnJvb3QuaW5uZXJIVE1MIHx8ICcnKTtcbiAgICBpZiAoIXRoaXMucXVpbGwoKT8ucm9vdC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW1nJykubGVuZ3RoICYmICF0aGlzLnF1aWxsKCk/LmdldFRleHQoKSkge1xuICAgICAgc2V0PGFueT4odGhpcy5pdGVtKCksIHRoaXMuZmllbGROYW1lQmluZCgpLCAnJyk7XG4gICAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgICB0aGlzLm91dENoYW5nZS5lbWl0KGdldCh0aGlzLml0ZW0oKSwgdGhpcy5maWVsZE5hbWVCaW5kKCkpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb252ZXJ0SW5uZXJIVE1MQW5kU2V0VmFsdWUoaHRtbCk7XG4gICAgdGhpcy52YWxpZGF0ZSgpO1xuICAgIHRoaXMub3V0Q2hhbmdlLmVtaXQoZ2V0KHRoaXMuaXRlbSgpLCB0aGlzLmZpZWxkTmFtZUJpbmQoKSkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJQb3BvdmVyRnVuY3Rpb25Db250cm9sKGV2ZW50OiBJUG9wb3ZlckZ1bmN0aW9uQ29udHJvbEV2ZW50KSB7XG4gICAgdGhpcy5wb3BvdmVyRnVuY3Rpb25Db250cm9sLnNldChldmVudCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclBvcG92ZXJFdmVudChldmVudDogVFlQRV9QT1BPVkVSX0VWRU5UKSB7XG4gICAgaWYgKGV2ZW50ID09PSAncmVtb3ZlJykge1xuICAgICAgdGhpcy5saW5rLnNldChsaW5rRGVmYXVsdCgpKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclVubGluayhldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBsaW5rID0gdGhpcy5saW5rKCk7XG4gICAgdGhpcy5xdWlsbCgpPy5mb3JtYXRUZXh0KGxpbmsucmFuZ2UuaW5kZXgsIGxpbmsucmFuZ2UubGVuZ3RoLCB7IGxpbms6IGZhbHNlIH0pO1xuICAgIHRoaXMucG9wb3ZlckZ1bmN0aW9uQ29udHJvbCgpPy5yZW1vdmVQb3BvdmVyT3ZlcmxheSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJFZGl0KGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGxpbmsgPSB0aGlzLmxpbmsoKTtcbiAgICBpZiAodGhpcy5pZ25vcmVTaG93UG9wdXBFZGl0TGluaygpKSB7XG4gICAgICB0aGlzLm91dFNob3dQb3B1cEVkaXRMaW5rLmVtaXQoe1xuICAgICAgICBkYXRhTGluazogbGluayxcbiAgICAgICAgY2FsbGJhY2s6IGFzeW5jIChsaW5rRWRpdDogeyB0aXRsZTogc3RyaW5nOyBsaW5rOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICAgIGlmIChsaW5rIGluc3RhbmNlb2YgT2JqZWN0ICYmIGxpbmsudXJsKSB7XG4gICAgICAgICAgICB0aGlzLnF1aWxsKCk/LmRlbGV0ZVRleHQobGluay5yYW5nZS5pbmRleCwgbGluay5yYW5nZS5sZW5ndGgsIFF1aWxsLnNvdXJjZXMuVVNFUik7XG4gICAgICAgICAgICB0aGlzLnF1aWxsKCk/Lmluc2VydFRleHQobGluay5yYW5nZS5pbmRleCwgbGlua0VkaXQudGl0bGUsICdsaW5rJywgbGlua0VkaXQubGluayk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuaW5zZXJ0TGluayhsaW5rRWRpdC50aXRsZSwgbGlua0VkaXQubGluayk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5oYW5kbGVTaG93VXBsb2FkTGluayhsaW5rKTtcbiAgICB0aGlzLnBvcG92ZXJGdW5jdGlvbkNvbnRyb2woKT8ucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2FsY3VsYXRvclRvb2xiYXIoKSB7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIHRoaXMudGltZUNhbGN1bGF0aW9uVG9vbEJhci5zZXQoXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgY29uc3QgdG9vbGJhcldpZHRoID0gdGhpcy50b29sYmFySXRlbXNFbCgpLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggfHwgMDtcbiAgICAgICAgbGV0IHRvdGFsV2lkdGggPSAzMiArIDI4O1xuICAgICAgICB0aGlzLnRvb2xiYXJPcHRpb25zQ29uZmlnLnVwZGF0ZSgoY29uZmlncykgPT4ge1xuICAgICAgICAgIGNvbmZpZ3MuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGl0ZW0uZGlzcGxheSA9IHRydWU7XG4gICAgICAgICAgICB0b3RhbFdpZHRoICs9IGl0ZW0ud2lkdGg7XG4gICAgICAgICAgICBpZiAoaXRlbS50eXBlID09PSAnbGluZScpIHtcbiAgICAgICAgICAgICAgY29uc3QgbmV4dEl0ZW1XaWR0aCA9IHRvdGFsV2lkdGggKyB0aGlzLnRvb2xiYXJPcHRpb25zQ29uZmlnKClbK2luZGV4ICsgMV0ud2lkdGg7XG4gICAgICAgICAgICAgIGNvbnN0IHByZUl0ZW0gPSB0aGlzLnRvb2xiYXJPcHRpb25zQ29uZmlnKClbK2luZGV4IC0gMV07XG4gICAgICAgICAgICAgIGlmIChuZXh0SXRlbVdpZHRoID4gdG9vbGJhcldpZHRoICYmIHByZUl0ZW0uZGlzcGxheSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGl0ZW0uZGlzcGxheSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0b3RhbFdpZHRoID4gdG9vbGJhcldpZHRoKSB7XG4gICAgICAgICAgICAgIGl0ZW0uZGlzcGxheSA9IGZhbHNlO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIFsuLi5jb25maWdzXTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0sIDYwMClcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldFN0eWxlKHR5cGU6IHN0cmluZywgZGF0YTogc3RyaW5nIHwgbnVtYmVyKSB7XG4gICAgdGhpcy5xdWlsbCgpPy5mb3JtYXQodHlwZSwgZGF0YSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZvbnRTaXplKGZvcm1hdDogU3RyaW5nTWFwKSB7XG4gICAgY29uc3QgZm9udFNpemUgPSBmb3JtYXQ/LnNpemU/LnRvU3RyaW5nKCk/LnJlcGxhY2UoJ3B4JywgJycpO1xuICAgIGlmIChpc05hTihwYXJzZUZsb2F0KGZvbnRTaXplKSkpIHtcbiAgICAgIHRoaXMuc2l6ZS5zZXQoeyB2YWx1ZTogMTQgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc2l6ZS5zZXQoeyB2YWx1ZTogcGFyc2VGbG9hdChmb250U2l6ZSkgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZvbnQoZm9ybWF0OiBTdHJpbmdNYXApIHtcbiAgICBjb25zdCBmb250ID0gbGlzdEZvbnQoKS5maW5kKChpdGVtKSA9PiBpdGVtLmtleSA9PT0gZm9ybWF0LmZvbnQpO1xuICAgIGlmICghZm9udCkge1xuICAgICAgdGhpcy5mb250U2VsZWN0ZWQuc2V0KHsga2V5OiAnJywgaXRlbTogbGlzdEZvbnQoKS5maW5kKChpdGVtKSA9PiBpdGVtLmtleSA9PT0gJycpIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZvbnRTZWxlY3RlZC5zZXQoeyBrZXk6IGZvcm1hdC5mb250LCBpdGVtOiBmb250IH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZVVuZG8oKSB7XG4gICAgdGhpcy5xdWlsbCgpPy5oaXN0b3J5Py51bmRvKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlUmVkbygpIHtcbiAgICB0aGlzLnF1aWxsKCk/Lmhpc3Rvcnk/LnJlZG8oKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzZXRDb250ZW50KGNvbnRlbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IGNvbnRlbnRYc3NGaWx0ZXIgPSBhd2FpdCB4c3NGaWx0ZXIodGhpcy5yZW1vdmVVbndhbnRlZFBhcnQoY29udGVudCB8fCAnJykpO1xuICAgIGF3YWl0IGxhc3RWYWx1ZUZyb20odGltZXIoMSkpO1xuICAgICh0aGlzLnF1aWxsKCk/LnJvb3QgYXMgSFRNTEVsZW1lbnQpLmlubmVySFRNTCA9IGNvbnRlbnRYc3NGaWx0ZXI7XG4gICAgaWYgKCF0aGlzLmF1dG9Gb2N1cygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IGxhc3RWYWx1ZUZyb20odGltZXIoMTAwKSk7XG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5xdWlsbEVkaXRvckVsKCk/Lm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nKTtcbiAgICBjb25zdCBjb250ZW50U2Nyb2xsID0gdGhpcy5oZWlnaHRBdXRvKCkgPyB0aGlzLndyYXBwZXJFZGl0b3JFbCgpPy5uYXRpdmVFbGVtZW50IDogdGFyZ2V0O1xuICAgIGNvbnRlbnRTY3JvbGwuc2Nyb2xsVG9wID0gY29udGVudFNjcm9sbC5zY3JvbGxIZWlnaHQ7XG4gICAgaWYgKHRoaXMuZm9jdXNCb3R0b20oKSkge1xuICAgICAgdGhpcy5xdWlsbCgpPy5zZXRTZWxlY3Rpb24oY29udGVudFhzc0ZpbHRlci5sZW5ndGgsIDAsIFF1aWxsLnNvdXJjZXMuU0lMRU5UKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5xdWlsbCgpPy5zZXRTZWxlY3Rpb24oMCwgMCwgUXVpbGwuc291cmNlcy5TSUxFTlQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJBZGRFbW9qaShlbW9qaTogdW5rbm93bikge1xuICAgIHRoaXMuaW5zZXJ0VGV4dChlbW9qaSBhcyBzdHJpbmcsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlU2hvd1VwbG9hZExpbmsoZXZlbnQ6IHVua25vd24pIHtcbiAgICB0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmLnNldCh0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbExpbmtDb21wb25lbnQpKTtcbiAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuYWRkRWRpdExpbmtDb21wb25lbnRSZWYoKT8uaW5zdGFuY2U7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gdGhpcy5xdWlsbCgpPy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCB0ZXh0U2VsZWN0ZWQgPSBzZWxlY3Rpb24/Lmxlbmd0aCA/IHRoaXMucXVpbGwoKT8uZ2V0VGV4dChzZWxlY3Rpb24/LmluZGV4LCBzZWxlY3Rpb24/Lmxlbmd0aCkgOiAnJztcbiAgICBjb25zdCBkYXRhID0gZXZlbnQgYXMgSVF1aWxsTGluayB8IHVuZGVmaW5lZDtcbiAgICB0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmKCk/LnNldElucHV0KCd6SW5kZXgnLCB0aGlzLnpJbmRleCgpKTtcbiAgICB0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmKCk/LnNldElucHV0KCd0aXRsZScsIGRhdGE/LnRpdGxlIHx8IHRleHRTZWxlY3RlZCk7XG4gICAgdGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpPy5zZXRJbnB1dCgnbGluaycsIGRhdGE/LnVybCB8fCAnJyk7XG4gICAgdGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpPy5zZXRJbnB1dCgnaWdub3JlQ29tbXVuaWNhdGVNaWNyb0V2ZW50JywgdGhpcy5pZ25vcmVDb21tdW5pY2F0ZU1pY3JvRXZlbnRQb3B1cCgpKTtcbiAgICBpbnN0YW5jZT8ub3V0U2F2ZUxpbmsuc3Vic2NyaWJlKChpdGVtOiB7IHRpdGxlOiBzdHJpbmc7IGxpbms6IHN0cmluZyB9KSA9PiB7XG4gICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIE9iamVjdCAmJiBkYXRhLnVybCkge1xuICAgICAgICB0aGlzLnF1aWxsKCk/LmRlbGV0ZVRleHQoZGF0YS5yYW5nZS5pbmRleCwgZGF0YS5yYW5nZS5sZW5ndGgsIFF1aWxsLnNvdXJjZXMuVVNFUik7XG4gICAgICAgIHRoaXMucXVpbGwoKT8uaW5zZXJ0VGV4dChkYXRhLnJhbmdlLmluZGV4LCBpdGVtLnRpdGxlLCAnbGluaycsIGl0ZW0ubGluayk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuaW5zZXJ0TGluayhpdGVtLnRpdGxlLCBpdGVtLmxpbmspO1xuICAgIH0pO1xuICAgIGluc3RhbmNlPy5vdXRDbG9zZS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5yZW1vdmUodGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpKSk7XG4gICAgdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5hZGRUb0JvZHkodGhpcy5hZGRFZGl0TGlua0NvbXBvbmVudFJlZigpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyVW5JbnNlcnRMaW5rKCkge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHRoaXMucXVpbGwoKT8uZ2V0U2VsZWN0aW9uKHRydWUpO1xuICAgIGlmICghaXNOaWwoc2VsZWN0aW9uKSkge1xuICAgICAgdGhpcy5xdWlsbCgpPy5mb3JtYXRUZXh0KHNlbGVjdGlvbiwgJ2xpbmsnLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHZhbGlkYXRlKCkge1xuICAgIHRoaXMubWVzc2FnZUVycm9yLnNldCgnJyk7XG4gICAgY29uc3QgdmFsaWRSZXF1aXJlZCA9IHRoaXMudmFsaWRSZXF1aXJlZCgpO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLml0ZW0oKTtcbiAgICBjb25zdCBmaWVsZE5hbWVCaW5kID0gdGhpcy5maWVsZE5hbWVCaW5kKCk7XG4gICAgY29uc3QgdmFsdWUgPSBnZXQ8YW55PihpdGVtLCBmaWVsZE5hbWVCaW5kKTtcbiAgICBpZiAodmFsaWRSZXF1aXJlZCAmJiB2YWxpZFJlcXVpcmVkLmlzUmVxdWlyZWQgJiYgKCFmaWVsZE5hbWVCaW5kIHx8ICF2YWx1ZSB8fCAhdmFsdWUudHJpbSgpKSkge1xuICAgICAgdGhpcy5tZXNzYWdlRXJyb3Iuc2V0KHZhbGlkUmVxdWlyZWQubWVzc2FnZSB8fCBFUlJPUl9NRVNTQUdFX0VNUFRZX1ZBTElEKTtcbiAgICAgIHRoaXMub3V0TWVzc2FnZUVycm9yLmVtaXQodGhpcy5tZXNzYWdlRXJyb3IoKSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHZhbGlkTWluTGVuZ3RoID0gdGhpcy52YWxpZE1pbkxlbmd0aCgpO1xuICAgIGlmICh2YWxpZE1pbkxlbmd0aCAmJiBmaWVsZE5hbWVCaW5kICYmIHZhbHVlICYmIHZhbHVlLnRyaW0oKS5sZW5ndGggPCB2YWxpZE1pbkxlbmd0aC5sZW5ndGgpIHtcbiAgICAgIHRoaXMubWVzc2FnZUVycm9yLnNldCh2YWxpZE1pbkxlbmd0aC5tZXNzYWdlIHx8IEVSUk9SX01FU1NBR0VfTUlOX0xFTkdUSCk7XG4gICAgICB0aGlzLm91dE1lc3NhZ2VFcnJvci5lbWl0KHRoaXMubWVzc2FnZUVycm9yKCkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCB2YWxpZE1heExlbmd0aCA9IHRoaXMudmFsaWRNYXhMZW5ndGgoKTtcbiAgICBpZiAodmFsaWRNYXhMZW5ndGggJiYgZmllbGROYW1lQmluZCAmJiB2YWx1ZSAmJiB2YWx1ZS50cmltKCkubGVuZ3RoID4gdGhpcy52YWxpZE1heExlbmd0aC5sZW5ndGgpIHtcbiAgICAgIHRoaXMubWVzc2FnZUVycm9yLnNldCh2YWxpZE1heExlbmd0aC5tZXNzYWdlIHx8IEVSUk9SX01FU1NBR0VfTUFYX0xFTkdUSCk7XG4gICAgICB0aGlzLm91dE1lc3NhZ2VFcnJvci5lbWl0KHRoaXMubWVzc2FnZUVycm9yKCkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLm91dE1lc3NhZ2VFcnJvci5lbWl0KHRoaXMubWVzc2FnZUVycm9yKCkpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGluc2VydEltYWdlKGNvbnRlbnQ6IHN0cmluZywgaW5kZXg/OiBudW1iZXIpIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBpbmRleCA/PyB0aGlzLnF1aWxsKCk/LmdldFNlbGVjdGlvbih0cnVlKS5pbmRleDtcbiAgICBpZiAoIWlzTmlsKHNlbGVjdGlvbikpIHtcbiAgICAgIHRoaXMucXVpbGwoKT8uaW5zZXJ0RW1iZWQoc2VsZWN0aW9uLCAnaW1hZ2UnLCBjb250ZW50KTtcbiAgICAgIHRoaXMucXVpbGwoKT8uc2V0U2VsZWN0aW9uKHNlbGVjdGlvbiArIDEsIDApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5zZXJ0VGV4dChjb250ZW50OiBzdHJpbmcsIGluZGV4PzogbnVtYmVyLCBmb2N1c0xhc3Q/OiBib29sZWFuKSB7XG4gICAgaW5kZXggPSBpbmRleCA/PyB0aGlzLnF1aWxsKCk/LmdldFNlbGVjdGlvbih0cnVlKS5pbmRleDtcbiAgICBpZiAoIWlzTmlsKGluZGV4KSkge1xuICAgICAgdGhpcy5xdWlsbCgpPy5pbnNlcnRUZXh0KGluZGV4LCBjb250ZW50LCBRdWlsbC5zb3VyY2VzLlVTRVIpO1xuICAgICAgaWYgKGZvY3VzTGFzdCkge1xuICAgICAgICBhd2FpdCBsYXN0VmFsdWVGcm9tKHRpbWVyKDApKTtcbiAgICAgICAgdGhpcy5xdWlsbCgpPy5zZXRTZWxlY3Rpb24oaW5kZXggKyBjb250ZW50Lmxlbmd0aCwgMCwgUXVpbGwuc291cmNlcy5VU0VSKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluc2VydExpbmsodGV4dDogc3RyaW5nLCB1cmw6IHN0cmluZywgaW5kZXg/OiBudW1iZXIpIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLnF1aWxsKCk/LmdldFNlbGVjdGlvbih0cnVlKTtcbiAgICBjb25zdCBpbmRleEluc2VydCA9IGluZGV4ID8/IHNlbGVjdGlvbj8uaW5kZXg7XG4gICAgaWYgKHNlbGVjdGlvbj8ubGVuZ3RoKSB7XG4gICAgICB0aGlzLnF1aWxsKCk/LmRlbGV0ZVRleHQoc2VsZWN0aW9uLmluZGV4LCBzZWxlY3Rpb24ubGVuZ3RoLCBRdWlsbC5zb3VyY2VzLlVTRVIpO1xuICAgIH1cbiAgICBpZiAoIWlzTmlsKGluZGV4SW5zZXJ0KSkge1xuICAgICAgdGhpcy5xdWlsbCgpPy5pbnNlcnRUZXh0KGluZGV4SW5zZXJ0LCB0ZXh0LCAnbGluaycsIHVybCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0SW5uZXJIVE1MQW5kU2V0VmFsdWUoaHRtbDogc3RyaW5nKSB7XG4gICAgdGhpcy5zZXRTdHlsZUZvckNvbnRlbnQoKTtcbiAgICBzZXQ8YW55Pih0aGlzLml0ZW0oKSwgdGhpcy5maWVsZE5hbWVCaW5kKCksIGh0bWwpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTdHlsZUZvckNvbnRlbnQoKSB7XG4gICAgY29uc3Qgc3R5bGVBcnJheSA9IFtcbiAgICAgIHsgc2VsZWN0b3I6ICcucWwtZm9udC1BcmlhbCcsIHN0eWxlOiAnZm9udC1mYW1pbHk6IEFyaWFsJyB9LFxuICAgICAgeyBzZWxlY3RvcjogJy5xbC1mb250LXNhbnMtc2VyaWYnLCBzdHlsZTogJ2ZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmJyB9LFxuICAgICAgeyBzZWxlY3RvcjogJy5xbC1mb250LXNlcmlmJywgc3R5bGU6ICdmb250LWZhbWlseTogc2VyaWYnIH0sXG4gICAgICB7IHNlbGVjdG9yOiAnLnFsLWZvbnQtbW9ub3NwYWNlJywgc3R5bGU6ICdmb250LWZhbWlseTogbW9ub3NwYWNlJyB9LFxuICAgICAgeyBzZWxlY3RvcjogJy5xbC1mb250LUhlbHZldGljYScsIHN0eWxlOiAnZm9udC1mYW1pbHk6IEhlbHZldGljYScgfSxcbiAgICAgIHsgc2VsZWN0b3I6ICcubGlicy11aS1xdWlsbC1mb3JtYXQtaW1hZ2UnLCBzdHlsZTogJ21heC13aWR0aDogMTAwJTsgaGVpZ2h0OiBhdXRvJywgb3ZlcnJpZGVTdHlsZTogdHJ1ZSB9LFxuICAgICAgeyBzZWxlY3RvcjogJy5saWJzLXVpLXF1aWxsLW1lbnRpb24nLCBzdHlsZTogJ2ZvbnQtd2VpZ2h0OiA2MDA7LW1vei1vc3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTstd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDsgY29sb3I6ICM3MjM5RUEnLCBvdmVycmlkZVN0eWxlOiB0cnVlIH0sXG4gICAgICB7IHNlbGVjdG9yOiAnYmxvY2txdW90ZScsIHN0eWxlOiAnYm9yZGVyLWxlZnQ6IDRweCBzb2xpZCAjY2NjOyBtYXJnaW4tYm90dG9tOiA1cHg7IG1hcmdpbi10b3A6IDVweDsgcGFkZGluZy1sZWZ0OiAxNnB4Jywgb3ZlcnJpZGVTdHlsZTogdHJ1ZSB9LFxuICAgIF07XG4gICAgdGhpcy5ibG90c1JlZ2lzdGVyKCk/LmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIHN0eWxlQXJyYXkucHVzaCh7IHNlbGVjdG9yOiBgLiR7aXRlbS5jbGFzc05hbWV9YCwgc3R5bGU6IGl0ZW0uc3R5bGUsIG92ZXJyaWRlU3R5bGU6IHRydWUgfSk7XG4gICAgfSk7XG4gICAgc3R5bGVBcnJheS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMucXVpbGwoKT8ucm9vdC5xdWVyeVNlbGVjdG9yQWxsKGl0ZW0uc2VsZWN0b3IpO1xuICAgICAgZWxlbWVudHM/LmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKGl0ZW0ub3ZlcnJpZGVTdHlsZSkge1xuICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdHlsZScsIGl0ZW0uc3R5bGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBGaXhidWcgaXNzdWU6IGh0dHBzOi8vYWRtaW4tY3YubW9iaW8udm4vaXNzdWVzLzQ5MDkyXG4gICAgICAgIGxldCBzdHlsZUV4aXN0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJyk7XG4gICAgICAgIGlmIChzdHlsZUV4aXN0KSB7XG4gICAgICAgICAgWydmb250LWZhbWlseTogQXJpYWwnLCAnZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYnLCAnZm9udC1mYW1pbHk6IHNlcmlmJywgJ2ZvbnQtZmFtaWx5OiBtb25vc3BhY2UnLCAnZm9udC1mYW1pbHk6IEhlbHZldGljYSddLmZvckVhY2goKGZvbnQpID0+IHtcbiAgICAgICAgICAgIHN0eWxlRXhpc3QgPSAoc3R5bGVFeGlzdD8uaW5jbHVkZXMoYCR7Zm9udH07YCkgPyBzdHlsZUV4aXN0Py5yZXBsYWNlKGAke2ZvbnR9O2AsICcnKSA6IHN0eWxlRXhpc3Q/LnJlcGxhY2UoZm9udCwgJycpKSBhcyBzdHJpbmc7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgc3R5bGVFeGlzdCA/IGAke3N0eWxlRXhpc3R9JHtzdHlsZUV4aXN0W3N0eWxlRXhpc3QubGVuZ3RoIC0gMV0gPT09ICc7JyA/ICcnIDogJzsnfSR7aXRlbS5zdHlsZX07YCA6IGl0ZW0uc3R5bGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlVG9nZ2xlTWVudGlvbihzaG93OiBib29sZWFuKSB7XG4gICAgdGhpcy5zaG93TWVudGlvbi5zZXQoc2hvdyk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJTaG93VXBsb2FkSW1hZ2UoKSB7XG4gICAgaWYgKHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKS5tb2RlQ3VzdG9tKSB7XG4gICAgICB0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmLnNldCh0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KExpYnNVaUNvbXBvbmVudHNJbnB1dHNRdWlsbFVwbG9hZEltYWdlQ29tcG9uZW50KSk7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMudXBsb2FkSW1hZ2VDb21wb25lbnRSZWYoKT8uaW5zdGFuY2U7XG4gICAgICB0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCk/LnNldElucHV0KCd1cGxvYWRJbWFnZUNvbmZpZycsIHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKSk7XG4gICAgICB0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCk/LnNldElucHV0KCdpZ25vcmVDb21tdW5pY2F0ZU1pY3JvRXZlbnQnLCB0aGlzLmlnbm9yZUNvbW11bmljYXRlTWljcm9FdmVudFBvcHVwKCkpO1xuICAgICAgaW5zdGFuY2U/Lm91dENsb3NlLnN1YnNjcmliZSgobGluazogc3RyaW5nIHwgdm9pZCkgPT4ge1xuICAgICAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLnVwbG9hZEltYWdlQ29tcG9uZW50UmVmKCkpO1xuICAgICAgICBpZiAobGluaykge1xuICAgICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2UobGluayk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5hZGRUb0JvZHkodGhpcy51cGxvYWRJbWFnZUNvbXBvbmVudFJlZigpKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnZmlsZScpO1xuICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnYWNjZXB0JywgJ2ltYWdlLyonKTtcbiAgICBpbnB1dC5jbGljaygpO1xuICAgIGlucHV0Lm9uY2hhbmdlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZXNBbmRJbnNlcnQoaW5wdXQ/LmZpbGVzKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGxvYWRJbWFnZXNBbmRJbnNlcnQoZmlsZXM/OiBGaWxlTGlzdCB8IG51bGwpIHtcbiAgICBpZiAoIWZpbGVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1heEltYWdlU2l6ZSA9IHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKT8ubWF4SW1hZ2VTaXplIHx8IDUgKiAxMDI0ICogMTAyNDtcbiAgICBjb25zdCBpbWFnZXMgPSBBcnJheS5mcm9tKGZpbGVzKS5maWx0ZXIoKGZpbGUpID0+IGZpbGUgJiYgZmlsZS50eXBlLnNwbGl0KCcvJylbMF0gPT09ICdpbWFnZScgJiYgKCF0aGlzLnVwbG9hZEltYWdlQ29uZmlnKCkubWF4SW1hZ2VTaXplIHx8IGZpbGUuc2l6ZSA8PSBtYXhJbWFnZVNpemUpKTtcbiAgICBpZiAoIWltYWdlcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93Q29tcFR5cGVUZXh0V2FybmluZyh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdpMThuX25vdGVfdXBsb2FkX2ltYWdlX3ZvbHVtZScsIHsgdmFsdWU6IGdldExhYmVsQnlTaXplRmlsZShtYXhJbWFnZVNpemUpIH0pLCB7IHRpbWVSZW1vdmU6IDgwMDAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvYWRpbmdVcGxvYWRJbWFnZS5zZXQodHJ1ZSk7XG4gICAgICBjb25zdCBpbmRleEluc2VydCA9IHRoaXMucXVpbGwoKT8uZ2V0U2VsZWN0aW9uKHRydWUpLmluZGV4O1xuICAgICAgY29uc3QgbGlua3MgPSBhd2FpdCB0aGlzLnVwbG9hZEltYWdlQ29uZmlnKCkuZnVuY3Rpb25VcGxvYWRJbWFnZT8uKGltYWdlcyk7XG4gICAgICBpZiAoIWxpbmtzPy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGlua3MuZm9yRWFjaCgobGluaykgPT4ge1xuICAgICAgICBpZiAoIWxpbmsgfHwgKHRoaXMudXBsb2FkSW1hZ2VDb25maWcoKS5vbmx5QWNjZXB0SW1hZ2VIdHRwc0xpbmsgJiYgKGxpbmsgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCAhbmV3IFJlZ0V4cChwYXR0ZXJuVXJsKCkpLnRlc3QobGluaykpKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluc2VydEltYWdlKGxpbmsgYXMgc3RyaW5nLCBpbmRleEluc2VydCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8oaW5kZXhJbnNlcnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5sb2FkaW5nVXBsb2FkSW1hZ2Uuc2V0KGZhbHNlKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRNZW50aW9uKGV2ZW50OiBJTWVudGlvbkluc2VydCkge1xuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5xdWlsbCgpPy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGN1cnNvclBvcyA9IHJhbmdlLmluZGV4O1xuICAgIGNvbnN0IHN0YXJ0UG9zSW5zZXJ0ID0gY3Vyc29yUG9zIC0gZXZlbnQubGVuZ3RoS2V5O1xuICAgIHRoaXMucXVpbGwoKT8uZGVsZXRlVGV4dChzdGFydFBvc0luc2VydCwgZXZlbnQubGVuZ3RoS2V5LCBRdWlsbC5zb3VyY2VzLlVTRVIpO1xuICAgIHRoaXMucXVpbGwoKT8uaW5zZXJ0RW1iZWQoc3RhcnRQb3NJbnNlcnQsICdtZW50aW9uJywgZXZlbnQuZGF0YSwgUXVpbGwuc291cmNlcy5VU0VSKTtcbiAgICB0aGlzLmluc2VydFRleHQoJyAnLCBzdGFydFBvc0luc2VydCArIDEpO1xuICAgIHRoaXMucXVpbGwoKT8uc2V0U2VsZWN0aW9uKHN0YXJ0UG9zSW5zZXJ0ICsgMiwgMCwgUXVpbGwuc291cmNlcy5VU0VSKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVySW5zZXJ0TWVudGlvbihkYXRhOiBJTWVudGlvbkluc2VydCkge1xuICAgIHRoaXMuaW5zZXJ0TWVudGlvbihkYXRhKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzZXRGb250U2l6ZShzaXplOiBudW1iZXIpIHtcbiAgICB0aGlzLnF1aWxsKCk/LmZvcm1hdCgnc2l6ZScsIGAke3NpemV9cHhgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyVmFsdWVDaGFuZ2UodmFsdWU6IG51bWJlciB8IHN0cmluZykge1xuICAgIHRoaXMuc2l6ZS51cGRhdGUoKGl0ZW0pID0+ICh7IC4uLml0ZW0sIHZhbHVlOiB2YWx1ZSBhcyBudW1iZXIgfSkpO1xuICAgIHRoaXMucXVpbGwoKT8uZm9ybWF0KCdzaXplJywgYCR7dGhpcy5zaXplKCkudmFsdWV9cHhgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVTZWxlY3RBbGlnbihldmVudDogSUVtaXRTZWxlY3RLZXkgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLmFsaWduU2VsZWN0ZWQuc2V0KGV2ZW50KTtcbiAgICB0aGlzLnNldFN0eWxlKCdhbGlnbicsIGV2ZW50Py5rZXkgYXMgc3RyaW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVTZWxlY3RGb250KGV2ZW50OiBJRW1pdFNlbGVjdEtleSB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuZm9udFNlbGVjdGVkLnNldChldmVudCk7XG4gICAgdGhpcy5zZXRTdHlsZSgnZm9udCcsIGV2ZW50Py5rZXkgYXMgc3RyaW5nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ2hhbmdlU2hvd01vcmVBY3Rpb24oZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zaG93TW9yZUFjdGlvbi51cGRhdGUoKGl0ZW0pID0+ICFpdGVtKTtcbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8oaW5kZXg/OiBudW1iZXIpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0U2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8oKSk7XG4gICAgaWYgKCF0aGlzLmVsZW1lbnRTY3JvbGxIZWlnaHRBdXRvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy50aW1lb3V0U2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8uc2V0KFxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGluZGV4ID0gaW5kZXggPz8gdGhpcy5xdWlsbCgpPy5nZXRTZWxlY3Rpb24odHJ1ZSkuaW5kZXg7XG4gICAgICAgIGlmICghaXNOaWwoaW5kZXgpKSB7XG4gICAgICAgICAgY29uc3QgYm91bmRzID0gdGhpcy5xdWlsbCgpPy5nZXRCb3VuZHMoaW5kZXgsIDEpO1xuICAgICAgICAgIHRoaXMuZWxlbWVudFNjcm9sbEhlaWdodEF1dG8oKT8uc2Nyb2xsVG8oMCwgKGJvdW5kcz8udG9wIHx8IDApIC0gMjApO1xuICAgICAgICB9XG4gICAgICB9LCAxMDApXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UWxFZGl0b3JFbGVtZW50KCkge1xuICAgIGlmICh0aGlzLnFsRWRpdG9yRWxlbWVudCgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5xbEVkaXRvckVsZW1lbnQoKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBlbGVtZW50Tm9kZSBvZiB0aGlzLnF1aWxsRWRpdG9yRWwoKS5uYXRpdmVFbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3FsLWVkaXRvcicpKSB7XG4gICAgICB0aGlzLnFsRWRpdG9yRWxlbWVudC5zZXQoZWxlbWVudE5vZGUgYXMgSFRNTEVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnFsRWRpdG9yRWxlbWVudCgpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVVbndhbnRlZFBhcnQoaHRtbDogc3RyaW5nKSB7XG4gICAgaWYgKCFodG1sKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiBodG1sXG4gICAgICAucmVwbGFjZSgvXlxccyo8cD48YnI+PFxcL3A+LywgJycpXG4gICAgICAucmVwbGFjZSgvPGRpdj48YnI+PFxcL2Rpdj4vZ2ksICcnKVxuICAgICAgLnJlcGxhY2UoL1tcXHUyMDBCLVxcdTIwMERcXHVGRUZGXS9nLCAnJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlU2VsZWN0SGVhZGVyKGV2ZW50OiBJRW1pdFNlbGVjdEtleSB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuaGVhZGVyU2VsZWN0ZWQuc2V0KGV2ZW50KTtcbiAgICB0aGlzLnNldFN0eWxlKCdoZWFkZXInLCBldmVudD8ua2V5IGFzIHN0cmluZyk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm9uRGVzdHJveS5uZXh0KCk7XG4gICAgdGhpcy5vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLmFkZEVkaXRMaW5rQ29tcG9uZW50UmVmKCkpO1xuICAgIHRoaXMuZHluYW1pY0NvbXBvbmVudFNlcnZpY2UucmVtb3ZlKHRoaXMudXBsb2FkSW1hZ2VDb21wb25lbnRSZWYoKSk7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZUNhbGN1bGF0aW9uVG9vbEJhcigpKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0U2Nyb2xsVG9TZWxlY3Rpb25XaXRoRWxlbWVudFNjcm9sbEhlaWdodEF1dG8oKSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHctZnVsbCBoLWZ1bGxcIj5cbiAgQGlmIChsYWJlbCgpOyBhcyBsYWJlbCkge1xuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtbGFiZWxcbiAgICAgIFtjbGFzc0luY2x1ZGVdPVwibGFiZWwuY2xhc3NJbmNsdWRlXCJcbiAgICAgIFtyZXF1aXJlZF09XCJsYWJlbC5yZXF1aXJlZFwiXG4gICAgICBbbGFiZWxMZWZ0XT1cImxhYmVsLmxhYmVsTGVmdFwiIC8+XG4gIH1cbiAgPGRpdlxuICAgICN3cmFwcGVyRWRpdG9yXG4gICAgW2F0dHIuaGVpZ2h0QXV0b109XCJoZWlnaHRBdXRvKClcIlxuICAgIFthdHRyLmlzVG9vbGJhclBvc2l0aW9uRml4ZWRdPVwiaXNUb29sYmFyUG9zaXRpb25GaXhlZCgpXCJcbiAgICBjbGFzcz1cImxpYnMtdWktcXVpbGwtd3JhcHBlciB3LWZ1bGwgaC1mdWxsIHJlbGF0aXZlIGZsZXggZmxleC1jb2xcIlxuICAgIFtjbGFzcy5saWJzLXVpLWJvcmRlci1lcnJvci1nZW5lcmFsXT1cIm1lc3NhZ2VFcnJvcigpICYmIHNob3dFcnJvckJvcmRlcigpICYmICFvbmx5U2hvd0Vycm9yQm9yZGVySW5Db250ZW50KClcIlxuICAgIFtjbGFzcy5yb3VuZGVkLVs0cHhdXT1cIm1lc3NhZ2VFcnJvcigpICYmIHNob3dFcnJvckJvcmRlcigpICYmICFvbmx5U2hvd0Vycm9yQm9yZGVySW5Db250ZW50KClcIj5cbiAgICA8ZGl2XG4gICAgICAjZWRpdG9yXG4gICAgICBjbGFzcz1cImxpYnMtdWktcXVpbGxcIlxuICAgICAgW2F0dHIuc2hvd0Vycm9yXT1cIm1lc3NhZ2VFcnJvcigpICYmIHNob3dFcnJvckJvcmRlcigpICYmIG9ubHlTaG93RXJyb3JCb3JkZXJJbkNvbnRlbnQoKVwiXG4gICAgICBbY2xhc3MuIWhpZGRlbl09XCIhZGlzcGxheSgpXCI+XG4gICAgICA8ZGl2XG4gICAgICAgICNxdWlsbE9wdGlvblxuICAgICAgICBbY2xhc3MuIXRvcC1bLTk5OTlweF1dPVwiIWlzU2hvd1Rvb2xCYXIoKVwiXG4gICAgICAgIFtjbGFzcy4hbGVmdC1bLTk5OTlweF1dPVwiIWlzU2hvd1Rvb2xCYXIoKVwiXG4gICAgICAgIFtzdHlsZV09XCJzdHlsZXNJbmNsdWRlVG9vbGJhcigpXCJcbiAgICAgICAgW2NsYXNzLnBvaW50ZXItZXZlbnRzLW5vbmVdPVwicmVhZG9ubHkoKSB8fCBsb2FkaW5nVXBsb2FkSW1hZ2UoKVwiXG4gICAgICAgIGNsYXNzPVwie3sgaXNUb29sYmFyUG9zaXRpb25GaXhlZCgpID8gJ2ZpeGVkICF6LTEwIHctWzUxMHB4XSBzaGFkb3ctWzBweF80cHhfMTZweF8wcHhfcmdiYSgwLDIwLDUxLDAuMTApXSByb3VuZGVkLVs0cHhdIGJnLVsjZmZmZmZmXSBsaWJzLXVpLXF1aWxsLXRvb2xiYXItYW5pbWF0aW9uJyA6ICcnIH19IHt7IGNsYXNzSW5jbHVkZVRvb2xiYXIoKSB9fSBoLVs0NHB4XSBzaHJpbmstMFwiXG4gICAgICAgIFtjbGFzcy5iZy1bI2Y4ZjlmYV1dPVwiIXJlYWRvbmx5KCkgJiYgIWxvYWRpbmdVcGxvYWRJbWFnZSgpXCJcbiAgICAgICAgW2NsYXNzLmxpYnMtdWktcmVhZG9ubHktYmFja2dyb3VuZF09XCJyZWFkb25seSgpIHx8IGxvYWRpbmdVcGxvYWRJbWFnZSgpXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0b29sYmFyXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXZcbiAgICAgICAgI3F1aWxsRWRpdG9yXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uRGlyZWN0aXZlXG4gICAgICAgIFt0aW1lRGVsYXlJbml0XT1cInRpbWVEZWxheUluaXQoKSArIDUwXCJcbiAgICAgICAgW21lbnRpb25Db25maWddPVwiZGF0YUNvbmZpZ01lbnRpb24oKVwiXG4gICAgICAgIFtjbGFzcy5saWJzLXVpLXJlYWRvbmx5LWJhY2tncm91bmRdPVwicmVhZG9ubHkoKSB8fCBsb2FkaW5nVXBsb2FkSW1hZ2UoKVwiXG4gICAgICAgIFtjbGFzcy5wb2ludGVyLWV2ZW50cy1ub25lXT1cImxvYWRpbmdVcGxvYWRJbWFnZSgpXCJcbiAgICAgICAgKG91dFRvZ2dsZSk9XCJoYW5kbGVUb2dnbGVNZW50aW9uKCRldmVudClcIlxuICAgICAgICAob3V0SW5zZXJ0TWVudGlvbik9XCJoYW5kbGVySW5zZXJ0TWVudGlvbigkZXZlbnQpXCI+PC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICNxbEVkaXRvclNjcm9sbFxuICAgICAgICBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZVxuICAgICAgICBbaWdub3JlSW5pdF09XCIhcWxFZGl0b3JFbGVtZW50KClcIlxuICAgICAgICBbZWxlbWVudFNjcm9sbF09XCJxbEVkaXRvckVsZW1lbnQoKVwiIC8+XG4gICAgPC9kaXY+XG4gICAgQGlmICh0ZW1wbGF0ZSgpOyBhcyB0ZW1wbGF0ZSkge1xuICAgICAgPGRpdiBbY2xhc3NdPVwiY2xhc3NJbmNsdWRlVGVtcGxhdGUoKVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgICBAaWYgKGxvYWRpbmdVcGxvYWRJbWFnZSgpKSB7XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLXNwaW5uZXIgW3NpemVdPVwiJ21lZGl1bSdcIiAvPlxuICAgIH1cbiAgPC9kaXY+XG4gIEBpZiAobWVzc2FnZUVycm9yKCkgJiYgc2hvd0Vycm9yTGFiZWwoKSkge1xuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBsZWFkaW5nLW5vcm1hbCBtdC1bOHB4XVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LVsjZmY1NDU0XSBsaWJzLXVpLWZvbnQtaDdyXCI+e3sgbWVzc2FnZUVycm9yKCkgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI3Rvb2xiYXI+XG4gIDxkaXZcbiAgICBjbGFzcz1cInRvb2xiYXIgaC1mdWxsIHctZnVsbCBzaHJpbmstMFwiXG4gICAgI3Rvb2xiYXJJdGVtcz5cbiAgICBAaWYgKGRpc3BsYXlTa2VsZXRvbigpKSB7XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLXNrZWxldG9uXG4gICAgICAgIGNsYXNzPVwidy1mdWxsIGgtZnVsbFwiXG4gICAgICAgIFtjb25maWddPVwie1xuICAgICAgICAgIHJvd3M6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaXRlbTogeyBjbGFzc0luY2x1ZGVJdGVtOiAnIXJvdW5kZWQtbm9uZScgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfVwiIC8+XG4gICAgfVxuICAgIDxkaXYgY2xhc3M9XCJxbC1mb3JtYXRzIGl0ZW1zLWNlbnRlciBweC1bMTZweF0gcHktWzRweF1cIj5cbiAgICAgIEBmb3IgKG9wdGlvbiBvZiB0b29sYmFyT3B0aW9uc0NvbmZpZygpOyB0cmFjayBvcHRpb24pIHtcbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiaXRlbXMtY2VudGVyXCJcbiAgICAgICAgICBbY2xhc3MuaGlkZGVuXT1cIiFvcHRpb24uZGlzcGxheVwiXG4gICAgICAgICAgW2NsYXNzLmZsZXhdPVwib3B0aW9uLmRpc3BsYXlcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbVRlbXBsYXRlOyBjb250ZXh0OiB7IG9wdGlvbiwgJGluZGV4LCAkbGFzdCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlXCI+XG4gICAgICAgIEBpZiAoZGlzcGxheVNob3dNb3JlVG9vbGJhcigpKSB7XG4gICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvblxuICAgICAgICAgICAgW3R5cGVdPVwic2hvd01vcmVBY3Rpb24oKSA/ICdidXR0b24tc2Vjb25kYXJ5JyA6ICdidXR0b24tdGhpcmQnXCJcbiAgICAgICAgICAgIFtpY29uT25seVR5cGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cIichcC1bMXB4XSAhaC1bMjBweF0gbWwtWzhweF0nXCJcbiAgICAgICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cIidsaWJzLXVpLWljb24tbW92ZS1yaWdodCByb3RhdGUtOTAnXCJcbiAgICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyQ2hhbmdlU2hvd01vcmVBY3Rpb24oJGV2ZW50KVwiIC8+XG4gICAgICAgIH1cbiAgICAgICAgPCEtLSBCdWlsZCB0b29sYmFyIGtoaSBjbGljayB4ZW0gdGjDqm0tLT5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIFtjbGFzcy5oaWRkZW5dPVwiIXNob3dNb3JlQWN0aW9uKClcIlxuICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgYmctWyNmZmZmZmZdIHNoYWRvdy1bMHB4XzRweF8xNnB4XzBweF9yZ2JhKDAsMjAsNTEsMC4xMCldIHotWzFdIGZsZXggaXRlbXMtY2VudGVyIHBsLVs4cHhdIHByLVsxNnB4XSBweS1bNHB4XSByb3VuZGVkLVs4cHhdIHRvcC1bMzFweF0gcmlnaHQtWzBweF1cIj5cbiAgICAgICAgICBAZm9yIChvcHRpb24gb2YgdG9vbGJhck9wdGlvbnNDb25maWcoKTsgdHJhY2sgb3B0aW9uKSB7XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzPVwiaXRlbXMtY2VudGVyXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCJvcHRpb24uZGlzcGxheSAhPT0gZmFsc2VcIlxuICAgICAgICAgICAgICBbY2xhc3MuZmxleF09XCJvcHRpb24uZGlzcGxheSA9PT0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIml0ZW1UZW1wbGF0ZTsgY29udGV4dDogeyBvcHRpb24sICRpbmRleCwgJGxhc3QgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZVxuICAjaXRlbVRlbXBsYXRlXG4gIGxldC0kaW5kZXg9XCIkaW5kZXhcIlxuICBsZXQtJGxhc3Q9XCIkbGFzdFwiXG4gIGxldC1vcHRpb249XCJvcHRpb25cIj5cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ3VuZG8nKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl91bmRvJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC11bmRvXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ3JlZG8nKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9yZWRvJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1yZWRvXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2ZvbnRGYW1pbHknKSB7XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJyZWxhdGl2ZSB3LVsxMzJweF0gaC1mdWxsIHJvdW5kZWQtWzRweF0gbGlicy11aS1ib3JkZXItZ2VuZXJhbCB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIlxuICAgICAgW2NsYXNzLmJnLXdoaXRlXT1cIiFyZWFkb25seSgpICYmICFsb2FkaW5nVXBsb2FkSW1hZ2UoKVwiPlxuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1kcm9wZG93blxuICAgICAgICBbaXNOZ0NvbnRlbnRdPVwidHJ1ZVwiXG4gICAgICAgIFtsYWJlbFBvcG92ZXJGdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgIFtsaXN0Q29uZmlnXT1cImxpc3RDb25maWdGb250KClcIlxuICAgICAgICBbbGlzdEhhc0J1dHRvblVuU2VsZWN0T3B0aW9uXT1cImZhbHNlXCJcbiAgICAgICAgW2xpc3RIaWRkZW5JbnB1dFNlYXJjaF09XCJ0cnVlXCJcbiAgICAgICAgW2xpc3RNYXhJdGVtU2hvd109XCI4XCJcbiAgICAgICAgW3pJbmRleF09XCIxMjUwXCJcbiAgICAgICAgKG91dFNlbGVjdEtleSk9XCJoYW5kbGVTZWxlY3RGb250KCRldmVudClcIj5cbiAgICAgICAgQGlmIChmb250U2VsZWN0ZWQoKTsgYXMgZm9udFNlbGVjdGVkKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGN1cnNvci1wb2ludGVyIHB5LVs3cHhdIGxpYnMtdWktZm9udC1oNXIgcGwtWzE2cHhdIHByLVs0MHB4XVwiPlxuICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyXG4gICAgICAgICAgICAgIFt0eXBlXT1cIid0ZXh0J1wiXG4gICAgICAgICAgICAgIFtpZ25vcmVTdG9wUHJvcGFnYXRpb25FdmVudF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgW2NvbmZpZ109XCJ7IHpJbmRleDogekluZGV4KCkgfVwiPlxuICAgICAgICAgICAgICB7eyBsYWJlbEZvbnRTZWxlY3RlZENvbXB1dGVkKCkgfX1cbiAgICAgICAgICAgIDwvbGlic191aS1jb21wb25lbnRzLXBvcG92ZXI+XG4gICAgICAgICAgICA8aSBjbGFzcz1cImxpYnMtdWktaWNvbi1tb3ZlLXJpZ2h0IHJvdGF0ZS05MCBhYnNvbHV0ZSByaWdodC1bMTJweF0gdGV4dC1bIzZhNzM4M10gdGV4dC1bMTZweF1cIj48L2k+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvbGlic191aS1jb21wb25lbnRzLWRyb3Bkb3duPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdoZWFkZXInKSB7XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJyZWxhdGl2ZSB3LVsxMzhweF0gaC1mdWxsIHJvdW5kZWQtWzRweF0gbGlicy11aS1ib3JkZXItZ2VuZXJhbCB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIlxuICAgICAgW2NsYXNzLmJnLXdoaXRlXT1cIiFyZWFkb25seSgpICYmICFsb2FkaW5nVXBsb2FkSW1hZ2UoKVwiPlxuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1kcm9wZG93blxuICAgICAgICBbaXNOZ0NvbnRlbnRdPVwidHJ1ZVwiXG4gICAgICAgIFtsYWJlbFBvcG92ZXJGdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgIFtsaXN0Q29uZmlnXT1cImxpc3RDb25maWdIZWFkZXIoKVwiXG4gICAgICAgIFtsaXN0SGFzQnV0dG9uVW5TZWxlY3RPcHRpb25dPVwiZmFsc2VcIlxuICAgICAgICBbbGlzdEhpZGRlbklucHV0U2VhcmNoXT1cInRydWVcIlxuICAgICAgICBbbGlzdE1heEl0ZW1TaG93XT1cIjhcIlxuICAgICAgICBbekluZGV4XT1cIjEyNTBcIlxuICAgICAgICAob3V0U2VsZWN0S2V5KT1cImhhbmRsZVNlbGVjdEhlYWRlcigkZXZlbnQpXCI+XG4gICAgICAgIEBpZiAoaGVhZGVyU2VsZWN0ZWQoKTsgYXMgaGVhZGVyU2VsZWN0ZWQpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgY3Vyc29yLXBvaW50ZXIgcHktWzdweF0gbGlicy11aS1mb250LWg1ciBwbC1bMTZweF0gcHItWzQwcHhdIHt7IG9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJyB9fVwiPlxuICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyXG4gICAgICAgICAgICAgIFt0eXBlXT1cIid0ZXh0J1wiXG4gICAgICAgICAgICAgIFtpZ25vcmVTdG9wUHJvcGFnYXRpb25FdmVudF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgW2NvbmZpZ109XCJ7IHpJbmRleDogekluZGV4KCkgfVwiPlxuICAgICAgICAgICAgICB7eyBsYWJlbEhlYWRlclNlbGVjdGVkQ29tcHV0ZWQoKSB9fVxuICAgICAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtcG9wb3Zlcj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwibGlicy11aS1pY29uLW1vdmUtcmlnaHQgcm90YXRlLTkwIGFic29sdXRlIHJpZ2h0LVsxMnB4XSB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XVwiPjwvaT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtZHJvcGRvd24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2ZvbnRTaXplJykge1xuICAgIDxkaXYgY2xhc3M9XCJxbC1waWNrZXIge3sgb3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nIH19XCI+XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLWlucHV0cy12YWxpZFxuICAgICAgICBbZGF0YVR5cGVdPVwiJ2ludCdcIlxuICAgICAgICBbKGl0ZW0pXT1cInNpemVcIlxuICAgICAgICBbZmllbGROYW1lQmluZF09XCIndmFsdWUnXCJcbiAgICAgICAgW3ZhbHVlVXBEb3duTnVtYmVyXT1cIjFcIlxuICAgICAgICBbbWF4VmFsdWVOdW1iZXJdPVwiNzJcIlxuICAgICAgICBbbWluVmFsdWVOdW1iZXJdPVwiOFwiXG4gICAgICAgIFtyZWFkb25seV09XCJyZWFkb25seSgpIHx8IGxvYWRpbmdVcGxvYWRJbWFnZSgpXCJcbiAgICAgICAgW2NsYXNzQ29udGFpbmVySW5wdXRdPVwiJ3ctWzcycHhdIGgtWzMycHhdJ1wiXG4gICAgICAgIChvdXRWYWx1ZUNoYW5nZSk9XCJoYW5kbGVyVmFsdWVDaGFuZ2UoJGV2ZW50KVwiIC8+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2NvbG9yJykge1xuICAgIDxkaXYgY2xhc3M9XCJxbC1jb2xvciBxbC1waWNrZXIgcWwtY29sb3ItcGlja2VyICFmbGV4IGl0ZW1zLWNlbnRlciB7eyBvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XScgfX1cIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fdGV4dF9jb2xvcicsIHpJbmRleDogekluZGV4KCkgfVwiPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtc2VsZWN0X2NvbG9yXG4gICAgICAgICAgW3pJbmRleF09XCJ6SW5kZXgoKVwiXG4gICAgICAgICAgW2RpcmVjdGlvbl09XCIndG9wJ1wiXG4gICAgICAgICAgW2V4dGVybmFsQ29udGVudF09XCJ0cnVlXCJcbiAgICAgICAgICBbY3VzdG9tT3B0aW9uc109XCJ7XG4gICAgICAgICAgICBzaG93QWxwaGE6IHRydWUsXG4gICAgICAgICAgfVwiXG4gICAgICAgICAgW2FwcGx5Tm93XT1cImZhbHNlXCJcbiAgICAgICAgICAob3V0Q29sb3JDaGFuZ2UpPVwic2V0U3R5bGUoJ2NvbG9yJywgJGV2ZW50KVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaWJzLXVpLWljb24tZWRpdG9yLWNvbG9yLXRleHQgbGlicy11aS1idXR0b25zLXNlbGVjdC1jb2xvciB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XSBob3Zlcjp0ZXh0LVt2YXIoLS1saWJzLXVpLWNvbG9yLWxpZ2h0LTEpXVwiPjwvZGl2PlxuICAgICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1idXR0b25zLXNlbGVjdF9jb2xvcj5cbiAgICAgIDwvbGlic191aS1jb21wb25lbnRzLXBvcG92ZXI+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2JhY2tncm91bmQnKSB7XG4gICAgPGRpdiBjbGFzcz1cInFsLWJhY2tncm91bmQgcWwtcGlja2VyIHFsLWNvbG9yLXBpY2tlciAhZmxleCBpdGVtcy1jZW50ZXIge3sgb3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nIH19XCI+XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLXBvcG92ZXIgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2JhY2tncm91bmRfY29sb3InLCB6SW5kZXg6IHpJbmRleCgpIH1cIj5cbiAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLXNlbGVjdF9jb2xvclxuICAgICAgICAgIFt6SW5kZXhdPVwiekluZGV4KClcIlxuICAgICAgICAgIFtkaXJlY3Rpb25dPVwiJ3RvcCdcIlxuICAgICAgICAgIFtleHRlcm5hbENvbnRlbnRdPVwidHJ1ZVwiXG4gICAgICAgICAgW2FwcGx5Tm93XT1cImZhbHNlXCJcbiAgICAgICAgICBbY3VzdG9tT3B0aW9uc109XCJ7XG4gICAgICAgICAgICBzaG93QWxwaGE6IHRydWUsXG4gICAgICAgICAgfVwiXG4gICAgICAgICAgKG91dENvbG9yQ2hhbmdlKT1cInNldFN0eWxlKCdiYWNrZ3JvdW5kJywgJGV2ZW50KVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaWJzLXVpLWljb24tZWRpdG9yLWNvbG9yLWJhY2tncm91bmQgbGlicy11aS1idXR0b25zLXNlbGVjdC1jb2xvciB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XSBob3Zlcjp0ZXh0LVt2YXIoLS1saWJzLXVpLWNvbG9yLWxpZ2h0LTEpXVwiPjwvZGl2PlxuICAgICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1idXR0b25zLXNlbGVjdF9jb2xvcj5cbiAgICAgIDwvbGlic191aS1jb21wb25lbnRzLXBvcG92ZXI+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2JvbGQnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9mb250X3dlaWdodF9ib2xkJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1ib2xkXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2l0YWxpYycpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2ZvbnRfc3R5bGVfaXRhbGljJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1pdGFsaWNcIj48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAndW5kZXJsaW5lJykge1xuICAgIDxkaXYgW2NsYXNzXT1cIm9wdGlvbi5jbGFzc0luY2x1ZGUgfHwgJ214LVs4cHhdJ1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckRpcmVjdGl2ZVxuICAgICAgICBbY29uZmlnXT1cInsgY29udGVudDogJ2kxOG5fdGV4dF9kZWNvcmF0aW9uX3VuZGVybGluZScsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtdW5kZXJsaW5lXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ3N0cmlrZVRocm91Z2gnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl90ZXh0X2xpbmVfdGhyb3VnaCcsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtc3RyaWtlXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2FkanVzdCcpIHtcbiAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgIWZsZXggaXRlbXMtY2VudGVyIHFsLWFsaWduIHFsLXBpY2tlciBxbC1pY29uLXBpY2tlciAhdy1tYXgge3sgb3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nIH19XCI+XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLXBvcG92ZXIgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2FkanVzdCcsIHpJbmRleDogekluZGV4KCkgfVwiPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWRyb3Bkb3duXG4gICAgICAgICAgW2lzTmdDb250ZW50XT1cInRydWVcIlxuICAgICAgICAgIFtpZ25vcmVTdG9wUHJvcGFnYXRpb25FdmVudF09XCJ0cnVlXCJcbiAgICAgICAgICBbbGFiZWxQb3BvdmVyRnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgIFtsaXN0Q29uZmlnXT1cImxpc3RDb25maWdBbGlnbigpXCJcbiAgICAgICAgICBbbGlzdEhpZGRlbklucHV0U2VhcmNoXT1cInRydWVcIlxuICAgICAgICAgIFtwb3BvdmVyQ3VzdG9tQ29uZmlnXT1cInsgaWdub3JlQXJyb3c6IHRydWUsIGNsYXNzSW5jbHVkZTogJyF3LVszMnB4XSBvdmVyZmxvdy1oaWRkZW4gIXB5LVs0cHhdJywgcG9zaXRpb246IHsgbW9kZTogJ3N0YXJ0JywgZGlzdGFuY2U6IDAgfSwgcGFkZGluZ0xlZnRJdGVtOiBmYWxzZSB9XCJcbiAgICAgICAgICBbbGlzdEhhc0J1dHRvblVuU2VsZWN0T3B0aW9uXT1cImZhbHNlXCJcbiAgICAgICAgICBbbGlzdE1heEl0ZW1TaG93XT1cIjhcIlxuICAgICAgICAgIFt6SW5kZXhdPVwiMTI1MFwiXG4gICAgICAgICAgKG91dFNlbGVjdEtleSk9XCJoYW5kbGVTZWxlY3RBbGlnbigkZXZlbnQpXCI+XG4gICAgICAgICAgQGlmIChhbGlnblNlbGVjdGVkKCk7IGFzIGFsaWduU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBjdXJzb3ItcG9pbnRlclwiPlxuICAgICAgICAgICAgICA8aSBbY2xhc3NdPVwiaWNvbkFsaWduU2VsZWN0ZWRDb21wdXRlZCgpXCI+PC9pPlxuICAgICAgICAgICAgICA8aSBjbGFzcz1cImxpYnMtdWktaWNvbi1tb3ZlLXJpZ2h0IHJvdGF0ZS05MCB0ZXh0LVsjNmE3MzgzXSB0ZXh0LVsxNnB4XSBtbC1bNHB4XVwiPjwvaT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtZHJvcGRvd24+XG4gICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdpbmRlbnRJbmNyZWFzZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2luZGVudF9pbmNyZWFzZScsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtaW5kZW50XCJcbiAgICAgICAgdmFsdWU9XCIrMVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdpbmRlbnREZWNyZWFzZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2luZGVudF9kZWNyZWFzZScsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtaW5kZW50XCJcbiAgICAgICAgdmFsdWU9XCItMVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdsaXN0QnVsbGV0ZWQnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9saXN0X2J1bGxldGVkJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1saXN0IHFsLWJ1bGxldFwiXG4gICAgICAgIHZhbHVlPVwiYnVsbGV0XCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2xpc3ROdW1iZXJlZCcpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2xpc3RfbnVtYmVyZWQnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLWxpc3QgcWwtb3JkZXJlZFwiXG4gICAgICAgIHZhbHVlPVwib3JkZXJlZFwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdwZXJzb25hbGl6ZScgJiYgdGVtcGxhdGVUb29sQmFyUGVyc29uYWxpemUoKTsgYXMgdGVtcGxhdGVUb29sQmFyUGVyc29uYWxpemUpIHtcbiAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIge3sgb3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nIH19XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGVUb29sQmFyUGVyc29uYWxpemVcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnYmxvY2txdW90ZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX3F1b3RlJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1ibG9ja3F1b3RlXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIH1cbiAgQGlmIChvcHRpb24udHlwZSA9PT0gJ2xpbmsnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl9pbnNlcnRfbGluaycsIHpJbmRleDogekluZGV4KCkgfVwiXG4gICAgICAgIGNsYXNzPVwicWwtbGlua1wiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICd1bkxpbmsnKSB7XG4gICAgPGRpdiBbY2xhc3NdPVwib3B0aW9uLmNsYXNzSW5jbHVkZSB8fCAnbXgtWzhweF0nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICAgIFtjb25maWddPVwieyBjb250ZW50OiAnaTE4bl91bmxpbmsnLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAgICAgICBjbGFzcz1cInFsLXVuTGlua1wiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdpbWFnZScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVcbiAgICAgICAgW2NvbmZpZ109XCJ7IGNvbnRlbnQ6ICdpMThuX2ltYWdlJywgekluZGV4OiB6SW5kZXgoKSB9XCJcbiAgICAgICAgY2xhc3M9XCJxbC1pbWFnZVwiPjwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICB9XG4gIEBpZiAob3B0aW9uLnR5cGUgPT09ICdlbW9qaScpIHtcbiAgICA8ZGl2IFtjbGFzc109XCJvcHRpb24uY2xhc3NJbmNsdWRlIHx8ICdteC1bOHB4XSdcIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtZW1vamlcbiAgICAgICAgW3pJbmRleF09XCJ6SW5kZXgoKVwiXG4gICAgICAgIFtpc05nQ29udGVudF09XCJ0cnVlXCJcbiAgICAgICAgKG91dEV2ZW50RW1vamkpPVwiaGFuZGxlckFkZEVtb2ppKCRldmVudClcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInFsLWVtb2ppXCI+PC9idXR0b24+XG4gICAgICA8L2xpYnNfdWktY29tcG9uZW50cy1lbW9qaT5cbiAgICA8L2Rpdj5cbiAgfVxuICBAaWYgKG9wdGlvbi50eXBlID09PSAnbGluZScpIHtcbiAgICA8ZGl2IGNsYXNzPVwidy1bMXB4XSBoLVsxNnB4XSBsaWJzLXVpLWJvcmRlci1yaWdodC1nZW5lcmFsXCI+PC9kaXY+XG4gIH1cbjwvbmctdGVtcGxhdGU+XG5cbjxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlclxuICBbbW9kZV09XCInY2xpY2snXCJcbiAgW2lnbm9yZUhpZGRlblBvcG92ZXJDb250ZW50V2hlbk1vdXNlTGVhdmVdPVwidHJ1ZVwiXG4gIFtjb25maWddPVwieyB0ZW1wbGF0ZTogdmlld0xpbmssIHdoaXRlVGhlbWU6IHRydWUsIGlnbm9yZUFycm93OiB0cnVlLCB6SW5kZXg6IHpJbmRleCgpIH1cIlxuICAob3V0RXZlbnQpPVwiaGFuZGxlclBvcG92ZXJFdmVudCgkZXZlbnQpXCJcbiAgKG91dEZ1bmN0aW9uc0NvbnRyb2wpPVwiaGFuZGxlclBvcG92ZXJGdW5jdGlvbkNvbnRyb2woJGV2ZW50KVwiIC8+XG5cbjxuZy10ZW1wbGF0ZSAjdmlld0xpbms+XG4gIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXIgcHgtWzE2cHhdIHB5LVs4cHhdIHJvdW5kZWQtWzhweF1cIj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cInctZnVsbCBtaW4tdy0wIGxpYnMtdWktZm9udC1oNXJcIlxuICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyRGlyZWN0aXZlXG4gICAgICBbY29uZmlnXT1cInsgY29udGVudDogbGluaygpLnVybCwgekluZGV4OiB6SW5kZXgoKSArIDEgfVwiPlxuICAgICAge3sgbGluaygpLnVybCB9fVxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBtbC1bMTZweF1cIj5cbiAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1idXR0b25cbiAgICAgICAgW3R5cGVdPVwiJ2J1dHRvbi1saW5rLXByaW1hcnknXCJcbiAgICAgICAgW2ljb25Pbmx5VHlwZV09XCJ0cnVlXCJcbiAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiJ2xpYnMtdWktaWNvbi1lZGl0LWxpbmUnXCJcbiAgICAgICAgW2NsYXNzSW5jbHVkZV09XCInIXAtMCdcIlxuICAgICAgICAob3V0Q2xpY2spPVwiaGFuZGxlckVkaXQoJGV2ZW50KVwiIC8+XG4gICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uXG4gICAgICAgIFt0eXBlXT1cIididXR0b24tbGluay1jdXN0b20nXCJcbiAgICAgICAgW2J1dHRvbkN1c3RvbV09XCJ7XG4gICAgICAgICAgY29uZmlnU3RlcENvbG9yOiB7XG4gICAgICAgICAgICB0ZXh0OiAnIzA3MTYzMScsXG4gICAgICAgICAgICB0ZXh0X2hvdmVyOiAnI2VlMmQ0MScsXG4gICAgICAgICAgICB0ZXh0X2FjdGl2ZTogJyNlZTJkNDEnLFxuICAgICAgICAgICAgdGV4dF9kaXNhYmxlOiAnMDcxNjMxJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJvb3RDb2xvcjogJyMwNzE2MzEnLFxuICAgICAgICB9XCJcbiAgICAgICAgW2NsYXNzSW5jbHVkZV09XCInIXAtMCBtbC1bMTJweF0nXCJcbiAgICAgICAgW2ljb25Pbmx5VHlwZV09XCJ0cnVlXCJcbiAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiJ2xpYnMtdWktaWNvbi1saW5rLWJyb2tlbidcIlxuICAgICAgICAob3V0Q2xpY2spPVwiaGFuZGxlclVubGluaygkZXZlbnQpXCIgLz5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
|