simpo-component-library 3.6.859 → 3.6.863

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.
Files changed (32) hide show
  1. package/esm2022/lib/components/hover-elements/hover-elements.component.mjs +17 -6
  2. package/esm2022/lib/ecommerce/sections/product-desc/product-desc.component.mjs +3 -3
  3. package/esm2022/lib/elements/text-editor/text-editor.component.mjs +300 -492
  4. package/esm2022/lib/sections/testimonial-fullwidth/testimonial-fullwidth.component.mjs +3 -3
  5. package/esm2022/lib/sections/testimonial-masonry/testimonial-masonry.component.mjs +110 -0
  6. package/esm2022/lib/sections/testimonial-masonry/testimonial-masonry.model.mjs +2 -0
  7. package/esm2022/lib/styles/gradient-extension.mjs +62 -0
  8. package/esm2022/lib/styles/text-size.extension.mjs +43 -0
  9. package/esm2022/public-api.mjs +3 -1
  10. package/fesm2022/simpo-component-library.mjs +547 -547
  11. package/fesm2022/simpo-component-library.mjs.map +1 -1
  12. package/lib/components/hover-elements/hover-elements.component.d.ts +3 -0
  13. package/lib/components/input-fields/input-fields.component.d.ts +1 -1
  14. package/lib/ecommerce/sections/product-desc/product-desc.component.d.ts +1 -1
  15. package/lib/ecommerce/sections/schemes/schemes.component.d.ts +1 -1
  16. package/lib/elements/pricing-s1/pricing-s1.component.d.ts +1 -1
  17. package/lib/elements/text-editor/text-editor.component.d.ts +38 -50
  18. package/lib/sections/banner-carousel/banner-carousel.component.d.ts +2 -2
  19. package/lib/sections/carousel-banner/carousel-banner.component.d.ts +1 -1
  20. package/lib/sections/image-section/image-section.component.d.ts +2 -2
  21. package/lib/sections/logo-showcase/logo-showcase.component.d.ts +2 -2
  22. package/lib/sections/new-testimonials/new-testimonials.component.d.ts +1 -1
  23. package/lib/sections/pricing-section/pricing-section.component.d.ts +1 -1
  24. package/lib/sections/testimonial-masonry/testimonial-masonry.component.d.ts +30 -0
  25. package/lib/sections/testimonial-masonry/testimonial-masonry.model.d.ts +24 -0
  26. package/lib/styles/gradient-extension.d.ts +2 -0
  27. package/lib/styles/text-size.extension.d.ts +10 -0
  28. package/package.json +10 -4
  29. package/public-api.d.ts +2 -0
  30. package/simpo-component-library-3.6.863.tgz +0 -0
  31. package/src/lib/styles/global-styles.css +0 -15
  32. package/simpo-component-library-3.6.859.tgz +0 -0
@@ -1,549 +1,351 @@
1
- import { Component, EventEmitter, Inject, Input, Output, PLATFORM_ID, ViewChild } from '@angular/core';
2
- import { FormsModule } from '@angular/forms';
3
- import { ContenteditableValueAccessor } from '../../directive/contenteditable.directive';
1
+ // text-editor.component.ts
2
+ import { Component, EventEmitter, HostListener, Input, Output, ViewChild, PLATFORM_ID, inject } from '@angular/core';
4
3
  import { CommonModule, isPlatformBrowser } from '@angular/common';
4
+ import { DomSanitizer } from '@angular/platform-browser';
5
+ import { FormsModule } from '@angular/forms';
5
6
  import { MatIconModule } from '@angular/material/icon';
6
7
  import { CdkDrag } from '@angular/cdk/drag-drop';
8
+ import { MatSelectModule } from '@angular/material/select';
9
+ import { MatFormFieldModule } from '@angular/material/form-field';
10
+ import { ContenteditableValueAccessor } from '../../directive/contenteditable.directive';
11
+ import { GradientExtension } from '../../styles/gradient-extension';
12
+ import { FontSize } from '../../styles/text-size.extension';
7
13
  import * as i0 from "@angular/core";
8
- import * as i1 from "../editor-service.service";
9
- import * as i2 from "@angular/common";
10
- import * as i3 from "@angular/forms";
11
- import * as i4 from "@angular/material/icon";
14
+ import * as i1 from "@angular/common";
15
+ import * as i2 from "@angular/forms";
16
+ import * as i3 from "@angular/material/icon";
17
+ import * as i4 from "@angular/material/form-field";
18
+ import * as i5 from "@angular/material/select";
19
+ import * as i6 from "@angular/material/core";
12
20
  export class TextEditorComponent {
13
- constructor(editorService, platformId, ngZone) {
14
- this.editorService = editorService;
15
- this.platformId = platformId;
16
- this.ngZone = ngZone;
17
- this.lastGradientSpan = null;
21
+ constructor() {
18
22
  this.value = '<p>Hello this is palash makhija</p>';
19
23
  this.valueChange = new EventEmitter();
20
24
  this.editable = false;
21
- this.show = false;
22
- this.toolbarY = 0;
23
- this.suggestionY = 0;
24
- this.rightZero = true;
25
- this.showSuggestion = false;
25
+ this.platformId = inject(PLATFORM_ID);
26
+ this.sanitizer = inject(DomSanitizer);
27
+ this.selectedFontSize = '';
28
+ this.showToolbar = false;
29
+ this.toolbarX = 0;
30
+ this.toolbarY = 100;
31
+ this.selectedColor = '#000000';
32
+ this.primaryColor = '#000000';
33
+ this.secondaryColor = '#ff0000';
34
+ this.isColorPickerOpen = false;
35
+ this.selectedColorType = 'SOLID';
36
+ this.savedSelection = null;
37
+ this.isFontSizeMenuOpen = false;
26
38
  this.toolbarData = {
27
- selectedHeading: '',
28
- isBold: false,
29
- isItalic: false,
30
- isUnderlined: false,
31
- selectedSize: '',
32
- selectedList: '',
33
- selectedAlignment: '',
34
- selectedColor: '#000000'
39
+ selectedSize: ''
40
+ };
41
+ this.handleWindowFocus = () => {
42
+ setTimeout(() => {
43
+ this.isColorPickerOpen = false;
44
+ }, 300);
35
45
  };
36
- this.selectedColorType = 'SOLID';
37
- this.primaryColor = '#000000';
38
- this.secondaryColor = '#bd5f5fff';
39
- this.savedRange = null;
40
46
  }
41
- ngOnInit() {
42
- if (isPlatformBrowser(this.platformId)) {
43
- document.addEventListener('mousedown', this.hideToolbar.bind(this));
47
+ async ngAfterViewInit() {
48
+ this.updateSafeHtml();
49
+ if (this.editable &&
50
+ isPlatformBrowser(this.platformId)) {
51
+ await this.initializeEditor();
44
52
  }
45
- this.toolbarData.selectedSize = this.type ? this.type === 'heading' ? 'clamp(1.25rem, 4vw, 2rem)' : '' : '';
46
53
  }
47
- ngOnDestroy() {
48
- if (isPlatformBrowser(this.platformId)) {
49
- document.removeEventListener('mousedown', this.hideToolbar.bind(this));
54
+ ngOnChanges(changes) {
55
+ if (changes['value']) {
56
+ this.updateSafeHtml();
50
57
  }
51
58
  }
52
- selectRange(range) {
53
- const sel = window.getSelection();
54
- if (!sel)
55
- return;
56
- sel.removeAllRanges();
57
- sel.addRange(range);
58
- }
59
- markSelection() {
60
- const sel = window.getSelection();
61
- if (!sel || sel.rangeCount === 0)
62
- return null;
63
- const range = sel.getRangeAt(0).cloneRange();
64
- const start = document.createElement('span');
65
- const end = document.createElement('span');
66
- start.setAttribute('data-sel-start', '1');
67
- end.setAttribute('data-sel-end', '1');
68
- start.style.display = 'inline-block';
69
- start.style.width = '0';
70
- start.style.height = '0';
71
- end.style.display = 'inline-block';
72
- end.style.width = '0';
73
- end.style.height = '0';
74
- const endRange = range.cloneRange();
75
- endRange.collapse(false); // at end
76
- endRange.insertNode(end);
77
- const startRange = range.cloneRange();
78
- startRange.collapse(true); // at start
79
- startRange.insertNode(start);
80
- return { start, end };
81
- }
82
- restoreSelectionFromMarkers(markers) {
83
- if (!markers)
84
- return;
85
- const { start, end } = markers;
86
- const sel = window.getSelection();
87
- if (!sel)
88
- return;
89
- const newRange = document.createRange();
90
- newRange.setStartAfter(start);
91
- newRange.setEndBefore(end);
92
- // Clean up markers
93
- start.parentNode?.removeChild(start);
94
- end.parentNode?.removeChild(end);
95
- sel.removeAllRanges();
96
- sel.addRange(newRange);
97
- this.savedRange = newRange.cloneRange();
98
- }
99
- showToolbar(event) {
100
- if (!isPlatformBrowser(this.platformId) || !this.editable)
101
- return;
102
- const selection = window.getSelection();
103
- if (selection == null)
104
- return;
105
- const range = selection.getRangeAt(0);
106
- const rect = range.getBoundingClientRect();
107
- const parentRect = this.parentElement.nativeElement.getBoundingClientRect();
108
- const topFromParent = rect.top - parentRect.top;
109
- if (selection && selection.rangeCount > 0) {
110
- this.suggestionY = topFromParent + 30;
111
- this.showSuggestion = true;
112
- }
113
- if (selection && selection.toString().trim() !== '') {
114
- const toolbarWidth = 541;
115
- const viewportWidth = window.innerWidth;
116
- const rightPositon = viewportWidth - parentRect.left;
117
- if (rightPositon + toolbarWidth > viewportWidth) {
118
- this.rightZero = false;
119
- }
120
- else {
121
- this.rightZero = true;
122
- }
123
- this.toolbarY = topFromParent + 30;
124
- this.reFormattingData();
125
- this.readFormattingProperties();
126
- this.show = true;
127
- }
128
- else {
129
- this.show = false;
130
- }
131
- }
132
- rememberSelection(e) {
133
- if (!isPlatformBrowser(this.platformId))
134
- return;
135
- const sel = window.getSelection();
136
- if (sel && sel.rangeCount > 0) {
137
- this.savedRange = sel.getRangeAt(0).cloneRange();
138
- }
139
- e.preventDefault();
140
- }
141
- getActiveRange() {
142
- const sel = window.getSelection();
143
- // Prefer saved clone, else live selection clone
144
- const candidate = this.savedRange
145
- ?? (sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null);
146
- if (!candidate)
147
- return null;
148
- const range = ('cloneRange' in candidate) ? candidate.cloneRange() : candidate;
149
- return range && !range.collapsed ? range : null;
150
- }
151
- setColorMode(mode) {
152
- if (!isPlatformBrowser(this.platformId))
153
- return;
154
- this.selectedColorType = mode;
155
- const markers = this.markSelection();
156
- if (!markers)
157
- return;
158
- const markedRange = document.createRange();
159
- markedRange.setStartAfter(markers.start);
160
- markedRange.setEndBefore(markers.end);
161
- if (mode === 'GRADIENT') {
162
- const gradient = `linear-gradient(to right, ${this.primaryColor} 0%, ${this.secondaryColor} 100%)`;
163
- this.wrapRangeWithGradient(markedRange, gradient);
164
- markers.start.parentNode?.removeChild(markers.start);
165
- markers.end.parentNode?.removeChild(markers.end);
166
- const sel = window.getSelection();
167
- if (sel && sel.rangeCount > 0)
168
- this.savedRange = sel.getRangeAt(0).cloneRange();
169
- this.valueChange.emit(this.editor.nativeElement.innerHTML);
170
- return;
59
+ ngOnDestroy() {
60
+ if (this.editor &&
61
+ isPlatformBrowser(this.platformId)) {
62
+ this.editor.destroy();
171
63
  }
172
- this.unwrapGradientInRange(markedRange);
173
- this.restoreSelectionFromMarkers(markers);
174
- this.setStyleWithCSS(true);
175
- document.execCommand('foreColor', false, this.toolbarData.selectedColor || '#000000');
176
- const sel = window.getSelection();
177
- if (sel && sel.rangeCount > 0)
178
- this.savedRange = sel.getRangeAt(0).cloneRange();
179
- this.valueChange.emit(this.editor.nativeElement.innerHTML);
180
64
  }
181
- wrapRangeWithGradient(range, gradient) {
182
- const span = document.createElement('span');
183
- span.setAttribute('data-gradient', 'true');
184
- span.style.backgroundImage = gradient;
185
- span.style.backgroundClip = 'text';
186
- span.style.webkitBackgroundClip = 'text';
187
- span.style.webkitTextFillColor = 'transparent';
188
- span.style.color = 'transparent';
189
- const frag = range.extractContents();
190
- span.appendChild(frag);
191
- range.insertNode(span);
192
- const sel = window.getSelection();
193
- sel?.removeAllRanges();
194
- const newRange = document.createRange();
195
- newRange.selectNodeContents(span);
196
- sel?.addRange(newRange);
197
- this.lastGradientSpan = span;
65
+ updateSafeHtml() {
66
+ this.safeHtml =
67
+ this.sanitizer.bypassSecurityTrustHtml(this.value || '');
198
68
  }
199
- unwrapGradientInRange(range) {
200
- const root = this.editor?.nativeElement;
201
- if (!root)
69
+ async initializeEditor() {
70
+ if (!this.editorElement)
202
71
  return;
203
- const spans = Array.from(root.querySelectorAll('span[data-gradient="true"]'));
204
- for (let i = spans.length - 1; i >= 0; i--) {
205
- const span = spans[i];
206
- try {
207
- if (range.intersectsNode(span)) {
208
- while (span.firstChild) {
209
- span.parentNode?.insertBefore(span.firstChild, span);
210
- }
211
- span.parentNode?.removeChild(span);
72
+ const { Editor } = await import('@tiptap/core');
73
+ const StarterKit = (await import('@tiptap/starter-kit')).default;
74
+ const TextStyle = (await import('@tiptap/extension-text-style'))
75
+ .TextStyle;
76
+ const Color = (await import('@tiptap/extension-color'))
77
+ .default;
78
+ const Underline = (await import('@tiptap/extension-underline'))
79
+ .default;
80
+ const TextAlign = (await import('@tiptap/extension-text-align'))
81
+ .default;
82
+ this.editor = new Editor({
83
+ element: this.editorElement.nativeElement,
84
+ editorProps: {
85
+ attributes: {
86
+ class: 'ProseMirror'
212
87
  }
88
+ },
89
+ extensions: [
90
+ StarterKit,
91
+ TextStyle,
92
+ FontSize,
93
+ Color,
94
+ GradientExtension,
95
+ Underline,
96
+ TextAlign.configure({
97
+ types: [
98
+ 'heading',
99
+ 'paragraph',
100
+ 'listItem'
101
+ ],
102
+ }),
103
+ ],
104
+ content: this.value,
105
+ onSelectionUpdate: () => {
106
+ this.handleSelection();
107
+ },
108
+ onUpdate: ({ editor }) => {
109
+ const html = editor.getHTML();
110
+ this.value = html;
111
+ this.updateSafeHtml();
112
+ this.valueChange.emit(html);
113
+ this.updateEmptyEditorClass();
213
114
  }
214
- catch (err) {
215
- continue;
216
- }
217
- }
115
+ });
116
+ this.updateEmptyEditorClass();
218
117
  }
219
- hideToolbar(event) {
220
- if (!isPlatformBrowser(this.platformId) || !this.editable)
118
+ updateEmptyEditorClass() {
119
+ if (!this.editorElement)
221
120
  return;
222
- const clickedInsideEditor = this.editor?.nativeElement.contains(event.target);
223
- const clickedInsideToolbar = this.toolbar?.nativeElement.contains(event.target);
224
- const clickedInsideSuggestion = this.suggestion?.nativeElement.contains(event.target);
225
- if (!clickedInsideEditor && !clickedInsideToolbar) {
226
- this.show = false;
227
- }
228
- if (!clickedInsideEditor && !clickedInsideSuggestion) {
229
- this.showSuggestion = false;
230
- }
231
- }
232
- formatText(command, value = '') {
233
- if (!isPlatformBrowser(this.platformId))
121
+ const editorWrapper = this.editorElement.nativeElement
122
+ .closest('.editable-text');
123
+ if (!editorWrapper)
234
124
  return;
235
- document.execCommand(command, false, value);
236
- if (command === 'bold')
237
- this.toolbarData.isBold = !this.toolbarData.isBold;
238
- if (command === 'italic')
239
- this.toolbarData.isItalic = !this.toolbarData.isItalic;
240
- if (command === 'underline')
241
- this.toolbarData.isUnderlined = !this.toolbarData.isUnderlined;
242
- if (command === 'insertOrderedList' || command === 'insertUnorderedList') {
243
- this.toolbarData.selectedList = command === this.toolbarData.selectedList ? '' : command;
244
- this.updateFSforOL();
245
- // Apply current size to the list wrapper and items
246
- }
247
- if (command === 'justifyLeft' || command === 'justifyCenter' || command === 'justifyRight')
248
- this.toolbarData.selectedAlignment = command === this.toolbarData.selectedAlignment ? '' : command;
249
- if (command === 'formatBlock')
250
- this.toolbarData.selectedHeading = value;
251
- }
252
- updateFSforOL() {
253
- const cssSize = this.toolbarData.selectedSize;
254
- if (cssSize) {
255
- const sel = window.getSelection();
256
- if (sel && sel.rangeCount > 0) {
257
- const focus = sel.focusNode;
258
- const baseEl = (focus.nodeType === Node.ELEMENT_NODE
259
- ? focus
260
- : focus.parentElement) || null;
261
- const listEl = baseEl?.closest?.('ol, ul');
262
- if (listEl) {
263
- listEl.style.fontSize = cssSize;
264
- listEl.querySelectorAll('li').forEach(li => {
265
- li.style.fontSize = cssSize;
266
- li.style.color = this.toolbarData.selectedColor;
267
- });
268
- }
269
- }
125
+ if (this.editor?.isEmpty) {
126
+ editorWrapper.classList.add('editor-empty');
270
127
  }
271
- }
272
- setStyleWithCSS(enable) {
273
- try {
274
- document.execCommand('styleWithCSS', false, enable ? 'true' : 'false');
128
+ else {
129
+ editorWrapper.classList.remove('editor-empty');
275
130
  }
276
- catch { /* some engines ignore */ }
277
131
  }
278
- toLegacyFontStep(cssSize) {
279
- const map = {
280
- '': 3,
281
- 'clamp(0.75rem, 2vw, 1rem)': 2,
282
- 'clamp(0.75rem, 2vw, 1.25rem)': 3,
283
- 'clamp(1rem, 3vw, 1.5rem)': 4,
284
- 'clamp(1.25rem, 4vw, 2rem)': 5,
285
- 'clamp(2rem, 5vw, 3rem)': 6,
286
- 'clamp(3.1rem, 7vw, 4.5rem)': 7
287
- };
288
- return String(map.hasOwnProperty(cssSize) ? map[cssSize] : 3);
132
+ saveSelection() {
133
+ this.savedSelection =
134
+ this.editor.state.selection;
289
135
  }
290
- normalizeFontSizeToCss(cssSize) {
291
- const container = this.editor?.nativeElement;
292
- if (!container)
136
+ restoreSelection() {
137
+ if (!this.savedSelection)
293
138
  return;
294
- const fonts = container.querySelectorAll('font[size]');
295
- fonts.forEach((fontEl) => {
296
- const span = document.createElement('span');
297
- if (cssSize)
298
- span.style.fontSize = cssSize;
299
- while (fontEl.firstChild)
300
- span.appendChild(fontEl.firstChild);
301
- fontEl.parentNode?.replaceChild(span, fontEl);
302
- });
139
+ this.editor
140
+ .chain()
141
+ .focus()
142
+ .setTextSelection(this.savedSelection)
143
+ .run();
303
144
  }
304
- changeFontSize(event) {
305
- if (!isPlatformBrowser(this.platformId))
306
- return;
307
- const cssSize = event.target.value;
308
- const selection = window.getSelection();
309
- if (!selection || selection.rangeCount === 0)
310
- return;
311
- const range = selection.getRangeAt(0);
312
- if (range.collapsed)
313
- return;
314
- this.ngZone.runOutsideAngular(() => {
315
- this.setStyleWithCSS(true);
316
- const step = this.toLegacyFontStep(cssSize);
317
- document.execCommand('fontSize', false, step);
318
- this.normalizeFontSizeToCss(cssSize);
319
- setTimeout(() => {
320
- this.ngZone.run(() => {
321
- this.toolbarData.selectedSize = cssSize;
322
- this.valueChange.emit(this.editor.nativeElement.innerHTML);
323
- });
324
- }, 0);
145
+ switchToSolid(event) {
146
+ event.preventDefault();
147
+ event.stopPropagation();
148
+ this.saveSelection();
149
+ this.selectedColorType = 'SOLID';
150
+ setTimeout(() => {
151
+ this.restoreSelection();
152
+ this.showToolbar = true;
325
153
  });
326
154
  }
327
- changeColor(event) {
328
- if (!isPlatformBrowser(this.platformId))
329
- return;
330
- const color = event.target.value;
331
- const selection = window.getSelection();
332
- if (!selection || selection.rangeCount === 0)
333
- return;
334
- if (selection.getRangeAt(0).collapsed)
335
- return;
336
- this.ngZone.runOutsideAngular(() => {
337
- this.setStyleWithCSS(true);
338
- // this.unwrapGradientInSelection();
339
- document.execCommand('foreColor', false, color);
340
- setTimeout(() => {
341
- this.ngZone.run(() => {
342
- this.toolbarData.selectedColor = color;
343
- this.valueChange.emit(this.editor.nativeElement.innerHTML);
344
- });
345
- }, 0);
155
+ switchToGradient(event) {
156
+ event.preventDefault();
157
+ event.stopPropagation();
158
+ this.saveSelection();
159
+ this.selectedColorType = 'GRADIENT';
160
+ setTimeout(() => {
161
+ this.restoreSelection();
162
+ this.showToolbar = true;
346
163
  });
347
164
  }
348
- updateText(event) {
349
- this.valueChange.emit(this.editor.nativeElement.innerHTML);
350
- }
351
- onFormatChange(event) {
352
- const selectedValue = event.target.value;
353
- this.formatText('formatBlock', selectedValue);
354
- }
355
165
  openColorPicker() {
166
+ this.isColorPickerOpen = true;
356
167
  this.saveSelection();
357
- }
358
- readFormattingProperties() {
359
- if (!isPlatformBrowser(this.platformId))
360
- return;
361
- const selection = window.getSelection();
362
- if (!selection)
363
- return;
364
- const node = selection.focusNode;
365
- // Check if node is null
366
- if (!node)
367
- return;
368
- let element = node.parentElement;
369
- while (element) {
370
- const nodeName = element.nodeName;
371
- if (nodeName === 'H1' || nodeName === 'H2' || nodeName === 'H3') {
372
- this.toolbarData.selectedHeading = nodeName;
373
- }
374
- else if (nodeName === 'B' || nodeName === 'STRONG') {
375
- this.toolbarData.isBold = true;
376
- }
377
- else if (nodeName === 'I' || nodeName === 'EM') {
378
- this.toolbarData.isItalic = true;
379
- }
380
- else if (nodeName === 'U') {
381
- this.toolbarData.isUnderlined = true;
382
- }
383
- else if (nodeName === 'OL') {
384
- this.toolbarData.selectedList = 'insertOrderedList';
385
- }
386
- else if (nodeName === 'UL') {
387
- this.toolbarData.selectedList = 'insertUnorderedList';
388
- }
389
- else if (element.style.textAlign) {
390
- this.toolbarData.selectedAlignment = `justify${element.style.textAlign.charAt(0).toUpperCase() + element.style.textAlign.slice(1)}`;
391
- }
392
- else if (element.style.fontSize) {
393
- this.toolbarData.selectedSize = element.style.fontSize;
394
- }
395
- else if (element.style.color) {
396
- this.toolbarData.selectedColor = element.style.color;
397
- }
398
- element = element.parentElement;
399
- }
400
- }
401
- reFormattingData() {
402
- this.toolbarData = {
403
- selectedHeading: '',
404
- isBold: false,
405
- isItalic: false,
406
- isUnderlined: false,
407
- selectedSize: '',
408
- selectedList: '',
409
- selectedAlignment: '',
410
- selectedColor: ''
411
- };
412
- }
413
- changeGradientColor() {
414
- this.ngZone.runOutsideAngular(() => {
415
- // Restore previous selection first
416
- this.restoreSelection();
417
- setTimeout(() => {
418
- this.saveSelection();
419
- const gradient = `linear-gradient(to right, ${this.primaryColor} 0%, ${this.secondaryColor} 100%)`;
420
- this.applyGradientToText(gradient);
421
- this.restoreSelection();
422
- setTimeout(() => {
423
- this.ngZone.run(() => {
424
- this.valueChange.emit(this.editor.nativeElement.innerHTML);
425
- });
426
- }, 0);
427
- }, 10); // 10ms delay (adjustable if needed)
168
+ setTimeout(() => {
169
+ window.addEventListener('focus', this.handleWindowFocus, { once: true });
428
170
  });
429
171
  }
430
- applyGradientToText(gradientValue) {
431
- if (!isPlatformBrowser(this.platformId))
172
+ handleSelection() {
173
+ const { from, to } = this.editor.state.selection;
174
+ if (from === to) {
175
+ if (!this.isColorPickerOpen) {
176
+ this.showToolbar = false;
177
+ }
432
178
  return;
179
+ }
433
180
  const selection = window.getSelection();
434
- const root = this.editor?.nativeElement;
435
- if (!root)
436
- return;
437
- const existing = root.querySelector('span[data-gradient="true"]');
438
- if (existing) {
439
- existing.style.backgroundImage = gradientValue;
181
+ if (!selection ||
182
+ selection.rangeCount === 0) {
183
+ this.showToolbar = false;
440
184
  return;
441
185
  }
442
- if (!selection || selection.rangeCount === 0)
443
- return;
444
186
  const range = selection.getRangeAt(0);
445
- if (!range || range.collapsed)
446
- return;
447
- const selectedContent = range.extractContents();
448
- const span = document.createElement('span');
449
- span.setAttribute('data-gradient', 'true'); // mark for future updates
450
- span.style.backgroundImage = gradientValue;
451
- span.style.backgroundClip = 'text';
452
- span.style.webkitBackgroundClip = 'text';
453
- span.style.color = 'transparent';
454
- span.style.webkitTextFillColor = 'transparent';
455
- span.style.display = 'inline-block'; // fix from inlineSize='block'
456
- span.appendChild(selectedContent);
457
- range.insertNode(span);
458
- selection.removeAllRanges();
459
- const newRange = document.createRange();
460
- newRange.selectNodeContents(span);
461
- selection.addRange(newRange);
462
- }
463
- regenerateText() {
464
- let payload = {
465
- businessId: localStorage.getItem('businessId'),
466
- dataId: this.sectionId,
467
- subIndustryId: localStorage.getItem('subIndustryId'),
468
- suggestedDataType: 'COMPONENT',
469
- tone: 'PROFESSIONAL',
470
- value: this.value,
471
- label: this.label
472
- };
473
- this.editorService.regenerateText(payload).subscribe((res) => {
474
- this.value = res.data;
187
+ const rect = range.getBoundingClientRect();
188
+ const editorRect = this.editorElement.nativeElement
189
+ .getBoundingClientRect();
190
+ this.showToolbar = true;
191
+ setTimeout(() => {
192
+ const toolbar = document.querySelector('.toolbar');
193
+ if (!toolbar)
194
+ return;
195
+ const toolbarWidth = toolbar.offsetWidth;
196
+ let left = rect.left -
197
+ editorRect.left +
198
+ (rect.width / 2) -
199
+ (toolbarWidth / 2);
200
+ left = Math.max(10, left);
201
+ const maxLeft = editorRect.width -
202
+ toolbarWidth -
203
+ 10;
204
+ left = Math.min(left, maxLeft);
205
+ left = Math.max(10, left);
206
+ this.toolbarX = left;
207
+ this.toolbarY =
208
+ rect.bottom -
209
+ editorRect.top +
210
+ 10;
475
211
  });
476
212
  }
477
- saveSelection() {
478
- const selection = window.getSelection();
479
- if (selection && selection.rangeCount > 0) {
480
- this.savedRange = selection.getRangeAt(0);
481
- }
482
- }
483
- restoreSelection() {
484
- if (this.savedRange) {
485
- const selection = window.getSelection();
486
- selection?.removeAllRanges();
487
- selection?.addRange(this.savedRange);
488
- }
489
- }
490
- onPaste(event) {
491
- if (!isPlatformBrowser(this.platformId))
213
+ toggleBold() {
214
+ this.editor
215
+ .chain()
216
+ .focus()
217
+ .toggleBold()
218
+ .run();
219
+ }
220
+ toggleItalic() {
221
+ this.editor
222
+ .chain()
223
+ .focus()
224
+ .toggleItalic()
225
+ .run();
226
+ }
227
+ toggleUnderline() {
228
+ this.editor
229
+ .chain()
230
+ .focus()
231
+ .toggleUnderline()
232
+ .run();
233
+ }
234
+ toggleOrderedList() {
235
+ this.editor
236
+ .chain()
237
+ .focus()
238
+ .toggleOrderedList()
239
+ .run();
240
+ }
241
+ toggleBulletList() {
242
+ this.editor
243
+ .chain()
244
+ .focus()
245
+ .toggleBulletList()
246
+ .run();
247
+ }
248
+ setAlign(alignment) {
249
+ this.editor
250
+ .chain()
251
+ .focus()
252
+ .setTextAlign(alignment)
253
+ .run();
254
+ }
255
+ changeColor() {
256
+ this.restoreSelection();
257
+ const { from, to } = this.editor.state.selection;
258
+ if (from === to)
492
259
  return;
493
- event.preventDefault();
494
- // Get only plain text
495
- const text = event.clipboardData?.getData('text/plain') || '';
496
- // Insert as plain text
497
- document.execCommand('insertText', false, text);
498
- }
499
- stripStyles(html) {
500
- const doc = new DOMParser().parseFromString(html, 'text/html');
501
- const elements = doc.body.querySelectorAll('*');
502
- elements.forEach((el) => {
503
- el.removeAttribute('style'); // Remove all inline styles
504
- el.removeAttribute('class'); // Optional
505
- el.setAttribute('style', `color: ${this.toolbarData.selectedColor}`);
260
+ const existingStyles = this.editor.getAttributes('textStyle');
261
+ this.editor
262
+ .chain()
263
+ .focus()
264
+ .setTextSelection({
265
+ from,
266
+ to
267
+ })
268
+ .setMark('textStyle', {
269
+ ...existingStyles,
270
+ color: this.selectedColor,
271
+ backgroundImage: null,
272
+ WebkitBackgroundClip: null,
273
+ WebkitTextFillColor: null
274
+ })
275
+ .run();
276
+ }
277
+ applyGradient() {
278
+ this.restoreSelection();
279
+ const { from, to } = this.editor.state.selection;
280
+ if (from === to)
281
+ return;
282
+ const existingStyles = this.editor.getAttributes('textStyle');
283
+ const gradient = `
284
+ linear-gradient(
285
+ to right,
286
+ ${this.primaryColor},
287
+ ${this.secondaryColor}
288
+ )
289
+ `;
290
+ this.editor
291
+ .chain()
292
+ .focus()
293
+ .setTextSelection({
294
+ from,
295
+ to
296
+ })
297
+ .setMark('textStyle', {
298
+ ...existingStyles,
299
+ backgroundImage: gradient,
300
+ backgroundClip: 'text',
301
+ WebkitBackgroundClip: 'text',
302
+ color: 'transparent',
303
+ WebkitTextFillColor: 'transparent'
304
+ })
305
+ .run();
306
+ }
307
+ onMouseDown() {
308
+ setTimeout(() => {
309
+ if (!this.editor)
310
+ return;
311
+ const { from, to } = this.editor.state.selection;
312
+ this.showToolbar =
313
+ from !== to;
506
314
  });
507
- return doc.body.innerHTML;
508
- }
509
- getText() {
510
- const textContent = this.value?.replace(/<\/?[^>]+(>|$)/g, "")?.replace(/\s+/g, ' ').trim() ?? "";
511
- if (!textContent) {
512
- return "";
513
- }
514
- return this.value;
515
315
  }
516
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextEditorComponent, deps: [{ token: i1.ElementServiceService }, { token: PLATFORM_ID }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
517
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TextEditorComponent, isStandalone: true, selector: "simpo-text-editor", inputs: { value: "value", editable: "editable", sectionId: "sectionId", label: "label", type: "type" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "toolbar", first: true, predicate: ["toolbar"], descendants: true }, { propertyName: "editor", first: true, predicate: ["editor"], descendants: true }, { propertyName: "colorPicker", first: true, predicate: ["colorPicker"], descendants: true }, { propertyName: "parentElement", first: true, predicate: ["parentElement"], descendants: true }, { propertyName: "suggestion", first: true, predicate: ["suggestion"], descendants: true }], ngImport: i0, template: "<!-- <div class=\"editor-container\" [ngClass]=\"{'border': editable}\" #parentElement\r\n [class.d-none]=\"!editable && getText() == ''\"> -->\r\n<div *ngIf=\"editable; else viewMode\" class=\"editor-container\" [ngClass]=\"{'border': editable}\" #parentElement>\r\n <div [contenteditable]=\"editable\" [(ngModel)]=\"value\" class=\"editable-text p-0\" (mouseup)=\"showToolbar($event)\"\r\n #editor (ngModelChange)=\"updateText($event)\" (mousedown)=\"hideToolbar($event)\" (paste)=\"onPaste($event)\">\r\n </div>\r\n\r\n <div class=\"toolbar\" *ngIf=\"editable && show\" [ngStyle]=\"{'top.px': toolbarY}\"\r\n [style.right]=\"rightZero ? '0px' : 'auto'\" [style.left]=\"!rightZero ? '0px' : 'auto'\" #toolbar cdkDrag>\r\n <!-- <select class=\"tool\" (change)=\"onFormatChange($event)\" [(ngModel)]=\"toolbarData.selectedHeading\">\r\n <option value=\"H1\">Heading1</option>\r\n <option value=\"H2\">Heading2</option>\r\n <option value=\"H3\">Heading3</option>\r\n <option value=\"div\">Text</option>\r\n </select> -->\r\n <button class=\"tool\"> <mat-icon cdkDragHandle>drag_indicator</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('bold')\" [ngClass]=\"{'selectedTool': toolbarData.isBold}\"><mat-icon>\r\n format_bold</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('italic')\" [ngClass]=\"{'selectedTool': toolbarData.isItalic}\"><mat-icon>\r\n format_italic</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('underline')\" [ngClass]=\"{'selectedTool': toolbarData.isUnderlined}\"\r\n *ngIf=\"selectedColorType === 'SOLID'\"><mat-icon> format_underlined</mat-icon></button>\r\n\r\n <select class=\"tool\" (change)=\"changeFontSize($event)\" [(ngModel)]=\"toolbarData.selectedSize\">\r\n <option value=\"\" selected>Default</option>\r\n <option value=\"clamp(0.75rem, 2vw, 1rem)\">Small</option>\r\n <option value=\"clamp(0.75rem, 2vw, 1.25rem)\">Medium</option>\r\n <option value=\"clamp(1rem, 3vw, 1.5rem)\">Semi Large</option>\r\n <option value=\"clamp(1.25rem, 4vw, 2rem)\">Large</option>\r\n <option value=\"clamp(2rem, 5vw, 3rem)\">Extra Large</option>\r\n <option value=\"clamp(3.1rem, 7vw, 4.5rem)\">Huge</option>\r\n </select>\r\n\r\n <button class=\"tool\" (click)=\"formatText('insertOrderedList')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedList === 'insertOrderedList'}\"><mat-icon>format_list_numbered</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('insertUnorderedList')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedList === 'insertUnorderedList'}\"><mat-icon>\r\n format_list_bulleted</mat-icon></button>\r\n\r\n <button class=\"tool\" (click)=\"formatText('justifyLeft')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedAlignment === 'justifyLeft'}\"><mat-icon>\r\n format_align_left</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('justifyCenter')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedAlignment === 'justifyCenter'}\"><mat-icon>\r\n format_align_center</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('justifyRight')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedAlignment === 'justifyRight'}\"><mat-icon>\r\n format_align_right</mat-icon></button>\r\n\r\n <div class=\"colorType\">\r\n <button class=\"solid\" [ngClass]=\"{'solidColorSelected': selectedColorType === 'SOLID'}\"\r\n (mousedown)=\"rememberSelection($event)\" (click)=\"setColorMode('SOLID')\">\r\n Solid\r\n </button>\r\n <button class=\"gradient\" [ngClass]=\"{'gradientColorSelected': selectedColorType === 'GRADIENT'}\"\r\n (mousedown)=\"rememberSelection($event)\" (click)=\"setColorMode('GRADIENT')\">\r\n Gradient\r\n </button>\r\n </div>\r\n\r\n\r\n <button class=\"tool color-picker-btn\" (click)=\"openColorPicker()\" *ngIf=\"selectedColorType === 'SOLID'\">\r\n <mat-icon>format_color_text</mat-icon>\r\n <input type=\"color\" #colorPicker class=\"hidden-color-picker\" (input)=\"changeColor($event)\"\r\n [(ngModel)]=\"toolbarData.selectedColor\">\r\n </button>\r\n\r\n <div class=\"colorType\" *ngIf=\"selectedColorType === 'GRADIENT'\">\r\n <button class=\"tool color-picker-btn\" (click)=\"openColorPicker(); primaryColorPicker.click()\">\r\n <mat-icon [style.color]=\"primaryColor\">format_color_text</mat-icon>\r\n <input type=\"color\" #primaryColorPicker class=\"hidden-color-picker\" (input)=\"changeGradientColor()\"\r\n [(ngModel)]=\"primaryColor\">\r\n </button>\r\n <button class=\"tool color-picker-btn\" (click)=\"openColorPicker(); secondaryColorPicker.click()\">\r\n <mat-icon [style.color]=\"secondaryColor\">format_color_text</mat-icon>\r\n <input type=\"color\" #secondaryColorPicker class=\"hidden-color-picker\" (input)=\"changeGradientColor()\"\r\n [(ngModel)]=\"secondaryColor\">\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"suggestion-box\" [ngStyle]=\"{'top.px': suggestionY}\" [style.right]=\"rightZero ? '0px' : 'auto'\"\r\n [style.left]=\"!rightZero ? '0px' : 'auto'\" *ngIf=\"editable && label && showSuggestion\" #suggestion>\r\n <div class=\"suggestion\" (click)=\"regenerateText()\">\r\n <img src=\"https://prod-simpo.s3.ap-south-1.amazonaws.com/prod-images/887493c1742273970151Frame%201244831740.png\"\r\n alt=\"\">\r\n <div>\r\n <p class=\"name\">Regenerate Text</p>\r\n <p class=\"desc\">Get a fresh variation of a current text</p>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<ng-template #viewMode>\r\n <div class=\"read-only-text\" *ngIf=\"value\">\r\n <div [contenteditable]=\"editable\" [(ngModel)]=\"value\"></div>\r\n </div>\r\n</ng-template>", styles: ["*{font-family:var(--website-font-family)}mat-icon{font-family:Material Icons!important}.editor-container{position:relative;display:inline-block;overflow:visible;width:100%}.editor-container div{outline:none}.editable-text{line-height:unset;cursor:text}.toolbar{position:absolute;background:#fff;box-shadow:0 2px 5px #0003;display:flex;gap:5px;align-items:center;z-index:100000;box-shadow:#00000029 0 1px 4px;padding:5px 15px;border-radius:22px}.toolbar:hover{border:1px solid #ccc}.toolbar button{background:none;border:none;padding:5px 8px;cursor:pointer;font-weight:700;display:flex;align-items:center}.toolbar button:hover{background:#ddd}.toolbar select{padding:3px;border:none;outline:none;font-size:14px;font-weight:600;cursor:pointer}.toolbar input[type=color]{border:none;width:30px;height:30px;padding:0;cursor:pointer}.color-picker-btn{position:relative;background:none;border:none;cursor:pointer;padding:5px}.hidden-color-picker{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;cursor:pointer}.border{border:none!important;border-radius:8px}.border:hover{border:1px solid #b9b9b9!important;border-radius:8px}.selectedTool{background:var(--primary-bg-color)!important;color:#fff;border-radius:5px}p{margin-bottom:0rem!important}.suggestion-box{position:absolute;background:#fff;border:1px solid #ccc;box-shadow:0 2px 5px #0003;z-index:10000;box-shadow:#00000029 0 1px 4px;padding:5px 15px;border-radius:10px}.suggestion{display:flex;gap:10px;width:307px;align-items:center;cursor:pointer}.suggestion img{border-radius:5px;width:32px;height:32px;background:#faf1fc;padding:3px}.suggestion .name{color:#000;font-family:var(--primary-font-family)}.suggestion .desc{color:#000;font-size:12px;color:#918585;font-family:var(--primary-font-family)}.colorType{display:flex;border:1px solid #E9E9E9;border-radius:5px;height:35px}.colorType .solid{border-right:1px solid #E9E9E9;font-size:14px!important;font-family:Mulish}.colorType .gradient{font-size:14px!important;font-family:Mulish}.solidColorSelected{background:var(--primary-bg-color)!important;color:#fff;border-top-left-radius:5px;border-bottom-left-radius:5px}.gradientColorSelected{background:var(--primary-bg-color)!important;color:#fff;border-top-right-radius:5px;border-bottom-right-radius:5px}@media screen and (max-width: 475px){.toolbar{max-width:100%;flex-wrap:wrap;row-gap:15px}.tool{width:max-content!important}}.drag-icon{color:var(--primary-bg-color)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ContenteditableValueAccessor, selector: "[contenteditable][ngModel]", inputs: ["contenteditable"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }] }); }
316
+ changeFontSize(fontSize) {
317
+ this.selectedFontSize =
318
+ fontSize;
319
+ const { from, to } = this.editor.state.selection;
320
+ if (from === to)
321
+ return;
322
+ this.editor
323
+ .chain()
324
+ .focus()
325
+ .setTextSelection({
326
+ from,
327
+ to
328
+ })
329
+ .setMark('textStyle', {
330
+ fontSize
331
+ })
332
+ .run();
333
+ }
334
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
335
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TextEditorComponent, isStandalone: true, selector: "simpo-text-editor", inputs: { value: "value", editable: "editable", sectionId: "sectionId", label: "label", type: "type" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:mousedown": "onMouseDown()" } }, viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- text-editor.component.html -->\r\n\r\n<div class=\"editor-container\" *ngIf=\"editable; else viewMode\">\r\n\r\n <!-- FLOATING TOOLBAR -->\r\n <div class=\"toolbar\" *ngIf=\"showToolbar\" [style.top.px]=\"toolbarY\" [style.left.px]=\"toolbarX\" cdkDrag>\r\n <button class=\"tool drag-handle w-auto\" cdkDragHandle>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-grip-vertical\">\r\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"9\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"9\" cy=\"19\" r=\"1\" />\r\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"15\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"15\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </button>\r\n <mat-form-field appearance=\"outline\" class=\"font-size-field\">\r\n\r\n <mat-select [value]=\"selectedFontSize\" (selectionChange)=\"changeFontSize($event.value)\" disableOptionCentering>\r\n\r\n <mat-option value=\"\">\r\n Default\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(0.75rem, 2vw, 1rem)\">\r\n 14\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(0.75rem, 2vw, 1.25rem)\">\r\n 16\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(1rem, 3vw, 1.5rem)\">\r\n 20\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(1.25rem, 4vw, 2rem)\">\r\n 24\r\n </mat-option>\r\n <mat-option value=\"clamp(2rem, 5vw, 3rem)\">\r\n 32\r\n </mat-option>\r\n <mat-option value=\"clamp(3.1rem, 7vw, 4.5rem)\">\r\n 48\r\n </mat-option>\r\n </mat-select>\r\n\r\n </mat-form-field>\r\n <!-- BOLD -->\r\n <button class=\"tool w-auto\" [class.selectedTool]=\"editor?.isActive('bold')\" (click)=\"toggleBold()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-bold\">\r\n <path d=\"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ITALIC -->\r\n <button class=\"tool w-auto\" [class.selectedTool]=\"editor?.isActive('italic')\" (click)=\"toggleItalic()\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-italic\">\r\n <line x1=\"19\" x2=\"10\" y1=\"4\" y2=\"4\" />\r\n <line x1=\"14\" x2=\"5\" y1=\"20\" y2=\"20\" />\r\n <line x1=\"15\" x2=\"9\" y1=\"4\" y2=\"20\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- UNDERLINE -->\r\n <button class=\"tool w-auto\" [class.selectedTool]=\"editor?.isActive('underline')\" (click)=\"toggleUnderline()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-underline\">\r\n <path d=\"M6 4v6a6 6 0 0 0 12 0V4\" />\r\n <line x1=\"4\" x2=\"20\" y1=\"20\" y2=\"20\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ALIGN LEFT -->\r\n <button class=\"tool w-auto\" (click)=\"setAlign('left')\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-align-left\">\r\n <line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"15\" x2=\"3\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"17\" x2=\"3\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ALIGN CENTER -->\r\n <button class=\"tool w-auto\" (click)=\"setAlign('center')\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-align-center\">\r\n <line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"17\" x2=\"7\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"19\" x2=\"5\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ALIGN RIGHT -->\r\n <button class=\"tool w-auto\" (click)=\"setAlign('right')\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-align-right\">\r\n <line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"21\" x2=\"7\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ORDERED LIST -->\r\n <button class=\"tool w-auto\" (click)=\"toggleOrderedList()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-list-ordered\">\r\n <line x1=\"10\" x2=\"21\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"10\" x2=\"21\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"10\" x2=\"21\" y1=\"18\" y2=\"18\" />\r\n <path d=\"M4 6h1v4\" />\r\n <path d=\"M4 10h2\" />\r\n <path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\" />\r\n </svg>\r\n </button>\r\n <!-- BULLET LIST -->\r\n <button class=\"tool w-auto\" (click)=\"toggleBulletList()\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-list\">\r\n <line x1=\"8\" x2=\"21\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"8\" x2=\"21\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"8\" x2=\"21\" y1=\"18\" y2=\"18\" />\r\n <line x1=\"3\" x2=\"3.01\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"3\" x2=\"3.01\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"3\" x2=\"3.01\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- SOLID / GRADIENT -->\r\n <!-- SOLID / GRADIENT -->\r\n <div class=\"colorType\">\r\n\r\n <button class=\"solid w-auto\" [class.solidColorSelected]=\"selectedColorType === 'SOLID'\"\r\n (mousedown)=\"$event.preventDefault()\" (click)=\"switchToSolid($event)\">\r\n Solid\r\n </button>\r\n\r\n <button class=\"gradient w-auto\" [class.gradientColorSelected]=\"selectedColorType === 'GRADIENT'\"\r\n (mousedown)=\"$event.preventDefault()\" (click)=\"switchToGradient($event)\">\r\n Gradient\r\n </button>\r\n\r\n </div>\r\n\r\n <!-- SOLID COLOR -->\r\n <button class=\"tool color-picker-btn w-auto\" *ngIf=\"selectedColorType === 'SOLID'\">\r\n\r\n <mat-icon>format_color_text</mat-icon>\r\n\r\n <input type=\"color\" class=\"hidden-color-picker\" [(ngModel)]=\"selectedColor\" (click)=\"openColorPicker()\"\r\n (input)=\"changeColor()\">\r\n\r\n </button>\r\n\r\n <!-- GRADIENT -->\r\n <div class=\"gradient-picker\" *ngIf=\"selectedColorType === 'GRADIENT'\">\r\n <input type=\"color\" [(ngModel)]=\"primaryColor\" (click)=\"openColorPicker()\" (input)=\"applyGradient()\" />\r\n\r\n <input type=\"color\" [(ngModel)]=\"secondaryColor\" (click)=\"openColorPicker()\" (input)=\"applyGradient()\" />\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- TIPTAP EDITOR -->\r\n <div #editorContainer class=\"editable-text\">\r\n </div>\r\n\r\n</div>\r\n<ng-template #viewMode>\r\n <div class=\"read-only-text\" [innerHTML]=\"value\">\r\n </div>\r\n</ng-template>", styles: ["*{font-family:var(--website-font-family)}mat-icon{font-family:Material Icons!important}.editor-container{position:relative;width:100%}.editable-text{cursor:text;width:100%;border:1px solid lightgrey;border-radius:10px}.editable-text ::ng-deep p{margin-bottom:0!important}::ng-deep .ProseMirror ol,::ng-deep .ProseMirror ul{padding-left:2rem;margin-left:0;list-style-position:inside}::ng-deep .ProseMirror li{text-align:inherit;margin-bottom:5px}::ng-deep .ProseMirror li p{display:inline}.ProseMirror{outline:none;min-height:120px;padding:5px}.ProseMirror p{margin:0}.toolbar{position:absolute;left:0;top:0;display:flex;align-items:center;gap:5px;background:#fff;padding:8px 14px;border-radius:22px;z-index:100000;box-shadow:#00000029 0 1px 4px;max-width:calc(100vw - 20px);overflow-x:auto;box-sizing:border-box}.tool{background:none;border:none;padding:5px 8px;cursor:pointer;display:flex;align-items:center}.tool:hover{background:#eee;border-radius:5px}.selectedTool{background:var(--primary-bg-color)!important;color:#fff;border-radius:5px}.color-picker-btn{position:relative}.color-picker-btn mat-icon{font-size:22px!important}.hidden-color-picker{position:absolute;inset:0;opacity:0;cursor:pointer}.gradient-text{background:linear-gradient(to right,var(--gradient-start),var(--gradient-end));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;color:transparent;display:inline-block}.colorType{display:flex;border:1px solid #E9E9E9;border-radius:9px;overflow:hidden}.colorType button{font-size:12px!important;padding:7px 9px!important;border:none;background:#fff;cursor:pointer}.solid{border-right:1px solid #E9E9E9!important}.solidColorSelected,.gradientColorSelected{background:var(--primary-bg-color)!important;color:#fff}.gradient-picker{display:flex;gap:5px}.gradient-picker input{width:32px;height:32px;border:none;padding:0;cursor:pointer}.white-space-nowrap{white-space:nowrap}.font-size-field{width:120px;border:1px solid lightgrey;border-radius:10px}::ng-deep .font-size-field .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .font-size-field .mdc-notched-outline{display:none}::ng-deep .font-size-field .mat-mdc-text-field-wrapper{background:transparent!important;padding-left:8px!important;padding-right:8px!important;height:36px!important}::ng-deep .font-size-field .mat-mdc-select-value{font-size:14px;font-weight:600}::ng-deep .mat-mdc-select-panel{border-radius:12px!important}@media screen and (max-width: 475px){.toolbar{max-width:95%;flex-wrap:wrap;row-gap:10px}}@media screen and (max-width: 768px){.toolbar{width:max-content;max-width:calc(100vw - 20px);flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatFormFieldModule }] }); }
518
336
  }
519
337
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextEditorComponent, decorators: [{
520
338
  type: Component,
521
339
  args: [{ selector: 'simpo-text-editor', standalone: true, imports: [
522
340
  CommonModule,
523
341
  FormsModule,
524
- ContenteditableValueAccessor,
525
342
  MatIconModule,
526
- CdkDrag
527
- ], template: "<!-- <div class=\"editor-container\" [ngClass]=\"{'border': editable}\" #parentElement\r\n [class.d-none]=\"!editable && getText() == ''\"> -->\r\n<div *ngIf=\"editable; else viewMode\" class=\"editor-container\" [ngClass]=\"{'border': editable}\" #parentElement>\r\n <div [contenteditable]=\"editable\" [(ngModel)]=\"value\" class=\"editable-text p-0\" (mouseup)=\"showToolbar($event)\"\r\n #editor (ngModelChange)=\"updateText($event)\" (mousedown)=\"hideToolbar($event)\" (paste)=\"onPaste($event)\">\r\n </div>\r\n\r\n <div class=\"toolbar\" *ngIf=\"editable && show\" [ngStyle]=\"{'top.px': toolbarY}\"\r\n [style.right]=\"rightZero ? '0px' : 'auto'\" [style.left]=\"!rightZero ? '0px' : 'auto'\" #toolbar cdkDrag>\r\n <!-- <select class=\"tool\" (change)=\"onFormatChange($event)\" [(ngModel)]=\"toolbarData.selectedHeading\">\r\n <option value=\"H1\">Heading1</option>\r\n <option value=\"H2\">Heading2</option>\r\n <option value=\"H3\">Heading3</option>\r\n <option value=\"div\">Text</option>\r\n </select> -->\r\n <button class=\"tool\"> <mat-icon cdkDragHandle>drag_indicator</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('bold')\" [ngClass]=\"{'selectedTool': toolbarData.isBold}\"><mat-icon>\r\n format_bold</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('italic')\" [ngClass]=\"{'selectedTool': toolbarData.isItalic}\"><mat-icon>\r\n format_italic</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('underline')\" [ngClass]=\"{'selectedTool': toolbarData.isUnderlined}\"\r\n *ngIf=\"selectedColorType === 'SOLID'\"><mat-icon> format_underlined</mat-icon></button>\r\n\r\n <select class=\"tool\" (change)=\"changeFontSize($event)\" [(ngModel)]=\"toolbarData.selectedSize\">\r\n <option value=\"\" selected>Default</option>\r\n <option value=\"clamp(0.75rem, 2vw, 1rem)\">Small</option>\r\n <option value=\"clamp(0.75rem, 2vw, 1.25rem)\">Medium</option>\r\n <option value=\"clamp(1rem, 3vw, 1.5rem)\">Semi Large</option>\r\n <option value=\"clamp(1.25rem, 4vw, 2rem)\">Large</option>\r\n <option value=\"clamp(2rem, 5vw, 3rem)\">Extra Large</option>\r\n <option value=\"clamp(3.1rem, 7vw, 4.5rem)\">Huge</option>\r\n </select>\r\n\r\n <button class=\"tool\" (click)=\"formatText('insertOrderedList')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedList === 'insertOrderedList'}\"><mat-icon>format_list_numbered</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('insertUnorderedList')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedList === 'insertUnorderedList'}\"><mat-icon>\r\n format_list_bulleted</mat-icon></button>\r\n\r\n <button class=\"tool\" (click)=\"formatText('justifyLeft')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedAlignment === 'justifyLeft'}\"><mat-icon>\r\n format_align_left</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('justifyCenter')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedAlignment === 'justifyCenter'}\"><mat-icon>\r\n format_align_center</mat-icon></button>\r\n <button class=\"tool\" (click)=\"formatText('justifyRight')\"\r\n [ngClass]=\"{'selectedTool': toolbarData.selectedAlignment === 'justifyRight'}\"><mat-icon>\r\n format_align_right</mat-icon></button>\r\n\r\n <div class=\"colorType\">\r\n <button class=\"solid\" [ngClass]=\"{'solidColorSelected': selectedColorType === 'SOLID'}\"\r\n (mousedown)=\"rememberSelection($event)\" (click)=\"setColorMode('SOLID')\">\r\n Solid\r\n </button>\r\n <button class=\"gradient\" [ngClass]=\"{'gradientColorSelected': selectedColorType === 'GRADIENT'}\"\r\n (mousedown)=\"rememberSelection($event)\" (click)=\"setColorMode('GRADIENT')\">\r\n Gradient\r\n </button>\r\n </div>\r\n\r\n\r\n <button class=\"tool color-picker-btn\" (click)=\"openColorPicker()\" *ngIf=\"selectedColorType === 'SOLID'\">\r\n <mat-icon>format_color_text</mat-icon>\r\n <input type=\"color\" #colorPicker class=\"hidden-color-picker\" (input)=\"changeColor($event)\"\r\n [(ngModel)]=\"toolbarData.selectedColor\">\r\n </button>\r\n\r\n <div class=\"colorType\" *ngIf=\"selectedColorType === 'GRADIENT'\">\r\n <button class=\"tool color-picker-btn\" (click)=\"openColorPicker(); primaryColorPicker.click()\">\r\n <mat-icon [style.color]=\"primaryColor\">format_color_text</mat-icon>\r\n <input type=\"color\" #primaryColorPicker class=\"hidden-color-picker\" (input)=\"changeGradientColor()\"\r\n [(ngModel)]=\"primaryColor\">\r\n </button>\r\n <button class=\"tool color-picker-btn\" (click)=\"openColorPicker(); secondaryColorPicker.click()\">\r\n <mat-icon [style.color]=\"secondaryColor\">format_color_text</mat-icon>\r\n <input type=\"color\" #secondaryColorPicker class=\"hidden-color-picker\" (input)=\"changeGradientColor()\"\r\n [(ngModel)]=\"secondaryColor\">\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"suggestion-box\" [ngStyle]=\"{'top.px': suggestionY}\" [style.right]=\"rightZero ? '0px' : 'auto'\"\r\n [style.left]=\"!rightZero ? '0px' : 'auto'\" *ngIf=\"editable && label && showSuggestion\" #suggestion>\r\n <div class=\"suggestion\" (click)=\"regenerateText()\">\r\n <img src=\"https://prod-simpo.s3.ap-south-1.amazonaws.com/prod-images/887493c1742273970151Frame%201244831740.png\"\r\n alt=\"\">\r\n <div>\r\n <p class=\"name\">Regenerate Text</p>\r\n <p class=\"desc\">Get a fresh variation of a current text</p>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<ng-template #viewMode>\r\n <div class=\"read-only-text\" *ngIf=\"value\">\r\n <div [contenteditable]=\"editable\" [(ngModel)]=\"value\"></div>\r\n </div>\r\n</ng-template>", styles: ["*{font-family:var(--website-font-family)}mat-icon{font-family:Material Icons!important}.editor-container{position:relative;display:inline-block;overflow:visible;width:100%}.editor-container div{outline:none}.editable-text{line-height:unset;cursor:text}.toolbar{position:absolute;background:#fff;box-shadow:0 2px 5px #0003;display:flex;gap:5px;align-items:center;z-index:100000;box-shadow:#00000029 0 1px 4px;padding:5px 15px;border-radius:22px}.toolbar:hover{border:1px solid #ccc}.toolbar button{background:none;border:none;padding:5px 8px;cursor:pointer;font-weight:700;display:flex;align-items:center}.toolbar button:hover{background:#ddd}.toolbar select{padding:3px;border:none;outline:none;font-size:14px;font-weight:600;cursor:pointer}.toolbar input[type=color]{border:none;width:30px;height:30px;padding:0;cursor:pointer}.color-picker-btn{position:relative;background:none;border:none;cursor:pointer;padding:5px}.hidden-color-picker{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;cursor:pointer}.border{border:none!important;border-radius:8px}.border:hover{border:1px solid #b9b9b9!important;border-radius:8px}.selectedTool{background:var(--primary-bg-color)!important;color:#fff;border-radius:5px}p{margin-bottom:0rem!important}.suggestion-box{position:absolute;background:#fff;border:1px solid #ccc;box-shadow:0 2px 5px #0003;z-index:10000;box-shadow:#00000029 0 1px 4px;padding:5px 15px;border-radius:10px}.suggestion{display:flex;gap:10px;width:307px;align-items:center;cursor:pointer}.suggestion img{border-radius:5px;width:32px;height:32px;background:#faf1fc;padding:3px}.suggestion .name{color:#000;font-family:var(--primary-font-family)}.suggestion .desc{color:#000;font-size:12px;color:#918585;font-family:var(--primary-font-family)}.colorType{display:flex;border:1px solid #E9E9E9;border-radius:5px;height:35px}.colorType .solid{border-right:1px solid #E9E9E9;font-size:14px!important;font-family:Mulish}.colorType .gradient{font-size:14px!important;font-family:Mulish}.solidColorSelected{background:var(--primary-bg-color)!important;color:#fff;border-top-left-radius:5px;border-bottom-left-radius:5px}.gradientColorSelected{background:var(--primary-bg-color)!important;color:#fff;border-top-right-radius:5px;border-bottom-right-radius:5px}@media screen and (max-width: 475px){.toolbar{max-width:100%;flex-wrap:wrap;row-gap:15px}.tool{width:max-content!important}}.drag-icon{color:var(--primary-bg-color)!important}\n"] }]
528
- }], ctorParameters: () => [{ type: i1.ElementServiceService }, { type: Object, decorators: [{
529
- type: Inject,
530
- args: [PLATFORM_ID]
531
- }] }, { type: i0.NgZone }], propDecorators: { toolbar: [{
532
- type: ViewChild,
533
- args: ['toolbar', { static: false }]
534
- }], editor: [{
535
- type: ViewChild,
536
- args: ['editor', { static: false }]
537
- }], colorPicker: [{
538
- type: ViewChild,
539
- args: ['colorPicker']
540
- }], parentElement: [{
541
- type: ViewChild,
542
- args: ['parentElement']
543
- }], suggestion: [{
544
- type: ViewChild,
545
- args: ['suggestion', { static: false }]
546
- }], value: [{
343
+ CdkDrag,
344
+ MatSelectModule,
345
+ MatFormFieldModule,
346
+ ContenteditableValueAccessor
347
+ ], template: "<!-- text-editor.component.html -->\r\n\r\n<div class=\"editor-container\" *ngIf=\"editable; else viewMode\">\r\n\r\n <!-- FLOATING TOOLBAR -->\r\n <div class=\"toolbar\" *ngIf=\"showToolbar\" [style.top.px]=\"toolbarY\" [style.left.px]=\"toolbarX\" cdkDrag>\r\n <button class=\"tool drag-handle w-auto\" cdkDragHandle>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-grip-vertical\">\r\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"9\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"9\" cy=\"19\" r=\"1\" />\r\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"15\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"15\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </button>\r\n <mat-form-field appearance=\"outline\" class=\"font-size-field\">\r\n\r\n <mat-select [value]=\"selectedFontSize\" (selectionChange)=\"changeFontSize($event.value)\" disableOptionCentering>\r\n\r\n <mat-option value=\"\">\r\n Default\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(0.75rem, 2vw, 1rem)\">\r\n 14\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(0.75rem, 2vw, 1.25rem)\">\r\n 16\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(1rem, 3vw, 1.5rem)\">\r\n 20\r\n </mat-option>\r\n\r\n <mat-option value=\"clamp(1.25rem, 4vw, 2rem)\">\r\n 24\r\n </mat-option>\r\n <mat-option value=\"clamp(2rem, 5vw, 3rem)\">\r\n 32\r\n </mat-option>\r\n <mat-option value=\"clamp(3.1rem, 7vw, 4.5rem)\">\r\n 48\r\n </mat-option>\r\n </mat-select>\r\n\r\n </mat-form-field>\r\n <!-- BOLD -->\r\n <button class=\"tool w-auto\" [class.selectedTool]=\"editor?.isActive('bold')\" (click)=\"toggleBold()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-bold\">\r\n <path d=\"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ITALIC -->\r\n <button class=\"tool w-auto\" [class.selectedTool]=\"editor?.isActive('italic')\" (click)=\"toggleItalic()\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-italic\">\r\n <line x1=\"19\" x2=\"10\" y1=\"4\" y2=\"4\" />\r\n <line x1=\"14\" x2=\"5\" y1=\"20\" y2=\"20\" />\r\n <line x1=\"15\" x2=\"9\" y1=\"4\" y2=\"20\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- UNDERLINE -->\r\n <button class=\"tool w-auto\" [class.selectedTool]=\"editor?.isActive('underline')\" (click)=\"toggleUnderline()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-underline\">\r\n <path d=\"M6 4v6a6 6 0 0 0 12 0V4\" />\r\n <line x1=\"4\" x2=\"20\" y1=\"20\" y2=\"20\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ALIGN LEFT -->\r\n <button class=\"tool w-auto\" (click)=\"setAlign('left')\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-align-left\">\r\n <line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"15\" x2=\"3\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"17\" x2=\"3\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ALIGN CENTER -->\r\n <button class=\"tool w-auto\" (click)=\"setAlign('center')\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-align-center\">\r\n <line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"17\" x2=\"7\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"19\" x2=\"5\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ALIGN RIGHT -->\r\n <button class=\"tool w-auto\" (click)=\"setAlign('right')\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-align-right\">\r\n <line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"21\" x2=\"7\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- ORDERED LIST -->\r\n <button class=\"tool w-auto\" (click)=\"toggleOrderedList()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-list-ordered\">\r\n <line x1=\"10\" x2=\"21\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"10\" x2=\"21\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"10\" x2=\"21\" y1=\"18\" y2=\"18\" />\r\n <path d=\"M4 6h1v4\" />\r\n <path d=\"M4 10h2\" />\r\n <path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\" />\r\n </svg>\r\n </button>\r\n <!-- BULLET LIST -->\r\n <button class=\"tool w-auto\" (click)=\"toggleBulletList()\">\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"lucide lucide-list\">\r\n <line x1=\"8\" x2=\"21\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"8\" x2=\"21\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"8\" x2=\"21\" y1=\"18\" y2=\"18\" />\r\n <line x1=\"3\" x2=\"3.01\" y1=\"6\" y2=\"6\" />\r\n <line x1=\"3\" x2=\"3.01\" y1=\"12\" y2=\"12\" />\r\n <line x1=\"3\" x2=\"3.01\" y1=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- SOLID / GRADIENT -->\r\n <!-- SOLID / GRADIENT -->\r\n <div class=\"colorType\">\r\n\r\n <button class=\"solid w-auto\" [class.solidColorSelected]=\"selectedColorType === 'SOLID'\"\r\n (mousedown)=\"$event.preventDefault()\" (click)=\"switchToSolid($event)\">\r\n Solid\r\n </button>\r\n\r\n <button class=\"gradient w-auto\" [class.gradientColorSelected]=\"selectedColorType === 'GRADIENT'\"\r\n (mousedown)=\"$event.preventDefault()\" (click)=\"switchToGradient($event)\">\r\n Gradient\r\n </button>\r\n\r\n </div>\r\n\r\n <!-- SOLID COLOR -->\r\n <button class=\"tool color-picker-btn w-auto\" *ngIf=\"selectedColorType === 'SOLID'\">\r\n\r\n <mat-icon>format_color_text</mat-icon>\r\n\r\n <input type=\"color\" class=\"hidden-color-picker\" [(ngModel)]=\"selectedColor\" (click)=\"openColorPicker()\"\r\n (input)=\"changeColor()\">\r\n\r\n </button>\r\n\r\n <!-- GRADIENT -->\r\n <div class=\"gradient-picker\" *ngIf=\"selectedColorType === 'GRADIENT'\">\r\n <input type=\"color\" [(ngModel)]=\"primaryColor\" (click)=\"openColorPicker()\" (input)=\"applyGradient()\" />\r\n\r\n <input type=\"color\" [(ngModel)]=\"secondaryColor\" (click)=\"openColorPicker()\" (input)=\"applyGradient()\" />\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- TIPTAP EDITOR -->\r\n <div #editorContainer class=\"editable-text\">\r\n </div>\r\n\r\n</div>\r\n<ng-template #viewMode>\r\n <div class=\"read-only-text\" [innerHTML]=\"value\">\r\n </div>\r\n</ng-template>", styles: ["*{font-family:var(--website-font-family)}mat-icon{font-family:Material Icons!important}.editor-container{position:relative;width:100%}.editable-text{cursor:text;width:100%;border:1px solid lightgrey;border-radius:10px}.editable-text ::ng-deep p{margin-bottom:0!important}::ng-deep .ProseMirror ol,::ng-deep .ProseMirror ul{padding-left:2rem;margin-left:0;list-style-position:inside}::ng-deep .ProseMirror li{text-align:inherit;margin-bottom:5px}::ng-deep .ProseMirror li p{display:inline}.ProseMirror{outline:none;min-height:120px;padding:5px}.ProseMirror p{margin:0}.toolbar{position:absolute;left:0;top:0;display:flex;align-items:center;gap:5px;background:#fff;padding:8px 14px;border-radius:22px;z-index:100000;box-shadow:#00000029 0 1px 4px;max-width:calc(100vw - 20px);overflow-x:auto;box-sizing:border-box}.tool{background:none;border:none;padding:5px 8px;cursor:pointer;display:flex;align-items:center}.tool:hover{background:#eee;border-radius:5px}.selectedTool{background:var(--primary-bg-color)!important;color:#fff;border-radius:5px}.color-picker-btn{position:relative}.color-picker-btn mat-icon{font-size:22px!important}.hidden-color-picker{position:absolute;inset:0;opacity:0;cursor:pointer}.gradient-text{background:linear-gradient(to right,var(--gradient-start),var(--gradient-end));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;color:transparent;display:inline-block}.colorType{display:flex;border:1px solid #E9E9E9;border-radius:9px;overflow:hidden}.colorType button{font-size:12px!important;padding:7px 9px!important;border:none;background:#fff;cursor:pointer}.solid{border-right:1px solid #E9E9E9!important}.solidColorSelected,.gradientColorSelected{background:var(--primary-bg-color)!important;color:#fff}.gradient-picker{display:flex;gap:5px}.gradient-picker input{width:32px;height:32px;border:none;padding:0;cursor:pointer}.white-space-nowrap{white-space:nowrap}.font-size-field{width:120px;border:1px solid lightgrey;border-radius:10px}::ng-deep .font-size-field .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .font-size-field .mdc-notched-outline{display:none}::ng-deep .font-size-field .mat-mdc-text-field-wrapper{background:transparent!important;padding-left:8px!important;padding-right:8px!important;height:36px!important}::ng-deep .font-size-field .mat-mdc-select-value{font-size:14px;font-weight:600}::ng-deep .mat-mdc-select-panel{border-radius:12px!important}@media screen and (max-width: 475px){.toolbar{max-width:95%;flex-wrap:wrap;row-gap:10px}}@media screen and (max-width: 768px){.toolbar{width:max-content;max-width:calc(100vw - 20px);flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden}}\n"] }]
348
+ }], propDecorators: { value: [{
547
349
  type: Input
548
350
  }], valueChange: [{
549
351
  type: Output
@@ -555,5 +357,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
555
357
  type: Input
556
358
  }], type: [{
557
359
  type: Input
360
+ }], editorElement: [{
361
+ type: ViewChild,
362
+ args: ['editorContainer']
363
+ }], onMouseDown: [{
364
+ type: HostListener,
365
+ args: ['document:mousedown']
558
366
  }] } });
559
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9lbGVtZW50cy90ZXh0LWVkaXRvci90ZXh0LWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL2VsZW1lbnRzL3RleHQtZWRpdG9yL3RleHQtZWRpdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBQzlJLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUN6RixPQUFPLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXZELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7O0FBZWpELE1BQU0sT0FBTyxtQkFBbUI7SUFrQzlCLFlBQW9CLGFBQW9DLEVBQ3pCLFVBQWtCLEVBQ3ZDLE1BQWM7UUFGSixrQkFBYSxHQUFiLGFBQWEsQ0FBdUI7UUFDekIsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUN2QyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBOUJoQixxQkFBZ0IsR0FBMkIsSUFBSSxDQUFDO1FBRS9DLFVBQUssR0FBVyxxQ0FBcUMsQ0FBQztRQUNyRCxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDMUMsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUtuQyxTQUFJLEdBQUcs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S0FBSyxDQUFDO0lBQ3BCLENBQUM7K0dBdGtCVSxtQkFBbUIsdURBbUNwQixXQUFXO21HQW5DVixtQkFBbUIsOHFCQ3JCaEMsOHpMQWlHYyw0OEVEckZWLFlBQVkscVRBQ1osV0FBVywwZ0NBQ1gsNEJBQTRCLG1HQUM1QixhQUFhLG9MQUNiLE9BQU87OzRGQUtFLG1CQUFtQjtrQkFiL0IsU0FBUzsrQkFDRSxtQkFBbUIsY0FDakIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCw0QkFBNEI7d0JBQzVCLGFBQWE7d0JBQ2IsT0FBTztxQkFDUjs7MEJBdUNFLE1BQU07MkJBQUMsV0FBVzs4REFsQ29CLE9BQU87c0JBQS9DLFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFDQyxNQUFNO3NCQUE3QyxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBQ1osV0FBVztzQkFBcEMsU0FBUzt1QkFBQyxhQUFhO2dCQUNJLGFBQWE7c0JBQXhDLFNBQVM7dUJBQUMsZUFBZTtnQkFDa0IsVUFBVTtzQkFBckQsU0FBUzt1QkFBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUdqQyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0ksV0FBVztzQkFBcEIsTUFBTTtnQkFDRSxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBOZ1pvbmUsIE91dHB1dCwgUExBVEZPUk1fSUQsIFZpZXdDaGlsZCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IENvbnRlbnRlZGl0YWJsZVZhbHVlQWNjZXNzb3IgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmUvY29udGVudGVkaXRhYmxlLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSwgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IEVsZW1lbnRTZXJ2aWNlU2VydmljZSB9IGZyb20gJy4uL2VkaXRvci1zZXJ2aWNlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDZGtEcmFnIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3NpbXBvLXRleHQtZWRpdG9yJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtcclxuICAgIENvbW1vbk1vZHVsZSxcclxuICAgIEZvcm1zTW9kdWxlLFxyXG4gICAgQ29udGVudGVkaXRhYmxlVmFsdWVBY2Nlc3NvcixcclxuICAgIE1hdEljb25Nb2R1bGUsXHJcbiAgICBDZGtEcmFnXHJcbiAgXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vdGV4dC1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi90ZXh0LWVkaXRvci5jb21wb25lbnQuY3NzJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgVGV4dEVkaXRvckNvbXBvbmVudCB7XHJcbiAgQFZpZXdDaGlsZCgndG9vbGJhcicsIHsgc3RhdGljOiBmYWxzZSB9KSB0b29sYmFyITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdlZGl0b3InLCB7IHN0YXRpYzogZmFsc2UgfSkgZWRpdG9yITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdjb2xvclBpY2tlcicpIGNvbG9yUGlja2VyITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdwYXJlbnRFbGVtZW50JykgcGFyZW50RWxlbWVudCE6IEVsZW1lbnRSZWY7XHJcbiAgQFZpZXdDaGlsZCgnc3VnZ2VzdGlvbicsIHsgc3RhdGljOiBmYWxzZSB9KSBzdWdnZXN0aW9uITogRWxlbWVudFJlZjtcclxuICBwcml2YXRlIGxhc3RHcmFkaWVudFNwYW46IEhUTUxTcGFuRWxlbWVudCB8IG51bGwgPSBudWxsO1xyXG5cclxuICBASW5wdXQoKSB2YWx1ZTogc3RyaW5nID0gJzxwPkhlbGxvIHRoaXMgaXMgcGFsYXNoIG1ha2hpamE8L3A+JztcclxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBASW5wdXQoKSBlZGl0YWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHNlY3Rpb25JZD86IHN0cmluZztcclxuICBASW5wdXQoKSBsYWJlbD86IHN0cmluZztcclxuICBASW5wdXQoKSB0eXBlPzogc3RyaW5nO1xyXG5cclxuICBzaG93ID0gZmFsc2U7XHJcbiAgdG9vbGJhclkgPSAwO1xyXG4gIHN1Z2dlc3Rpb25ZID0gMDtcclxuICByaWdodFplcm86IGJvb2xlYW4gPSB0cnVlO1xyXG4gIHNob3dTdWdnZXN0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcbiAgdG9vbGJhckRhdGE6IGFueSA9IHtcclxuICAgIHNlbGVjdGVkSGVhZGluZzogJycsXHJcbiAgICBpc0JvbGQ6IGZhbHNlLFxyXG4gICAgaXNJdGFsaWM6IGZhbHNlLFxyXG4gICAgaXNVbmRlcmxpbmVkOiBmYWxzZSxcclxuICAgIHNlbGVjdGVkU2l6ZTogJycsXHJcbiAgICBzZWxlY3RlZExpc3Q6ICcnLFxyXG4gICAgc2VsZWN0ZWRBbGlnbm1lbnQ6ICcnLFxyXG4gICAgc2VsZWN0ZWRDb2xvcjogJyMwMDAwMDAnXHJcbiAgfVxyXG4gIHNlbGVjdGVkQ29sb3JUeXBlOiAnU09MSUQnIHwgJ0dSQURJRU5UJyA9ICdTT0xJRCc7XHJcbiAgcHJpbWFyeUNvbG9yOiBzdHJpbmcgPSAnIzAwMDAwMCc7XHJcbiAgc2Vjb25kYXJ5Q29sb3I6IGFueSA9ICcjYmQ1ZjVmZmYnO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVkaXRvclNlcnZpY2U6IEVsZW1lbnRTZXJ2aWNlU2VydmljZSxcclxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogT2JqZWN0LFxyXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZVxyXG4gICkge1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xyXG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLmhpZGVUb29sYmFyLmJpbmQodGhpcykpO1xyXG4gICAgfVxyXG4gICAgdGhpcy50b29sYmFyRGF0YS5zZWxlY3RlZFNpemUgPSB0aGlzLnR5cGUgPyB0aGlzLnR5cGUgPT09ICdoZWFkaW5nJyA/ICdjbGFtcCgxLjI1cmVtLCA0dncsIDJyZW0pJyA6ICcnIDogJyc7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XHJcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuaGlkZVRvb2xiYXIuYmluZCh0aGlzKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgcHJpdmF0ZSBzZWxlY3RSYW5nZShyYW5nZTogUmFuZ2UpIHtcclxuICAgIGNvbnN0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgIGlmICghc2VsKSByZXR1cm47XHJcbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XHJcbiAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBtYXJrU2VsZWN0aW9uKCk6IHsgc3RhcnQ6IEhUTUxFbGVtZW50OyBlbmQ6IEhUTUxFbGVtZW50IH0gfCBudWxsIHtcclxuICAgIGNvbnN0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgIGlmICghc2VsIHx8IHNlbC5yYW5nZUNvdW50ID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCkuY2xvbmVSYW5nZSgpO1xyXG5cclxuICAgIGNvbnN0IHN0YXJ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xyXG4gICAgY29uc3QgZW5kID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xyXG4gICAgc3RhcnQuc2V0QXR0cmlidXRlKCdkYXRhLXNlbC1zdGFydCcsICcxJyk7XHJcbiAgICBlbmQuc2V0QXR0cmlidXRlKCdkYXRhLXNlbC1lbmQnLCAnMScpO1xyXG4gICAgc3RhcnQuc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xyXG4gICAgc3RhcnQuc3R5bGUud2lkdGggPSAnMCc7XHJcbiAgICBzdGFydC5zdHlsZS5oZWlnaHQgPSAnMCc7XHJcbiAgICBlbmQuc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xyXG4gICAgZW5kLnN0eWxlLndpZHRoID0gJzAnO1xyXG4gICAgZW5kLnN0eWxlLmhlaWdodCA9ICcwJztcclxuXHJcbiAgICBjb25zdCBlbmRSYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTtcclxuICAgIGVuZFJhbmdlLmNvbGxhcHNlKGZhbHNlKTsgLy8gYXQgZW5kXHJcbiAgICBlbmRSYW5nZS5pbnNlcnROb2RlKGVuZCk7XHJcblxyXG4gICAgY29uc3Qgc3RhcnRSYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTtcclxuICAgIHN0YXJ0UmFuZ2UuY29sbGFwc2UodHJ1ZSk7IC8vIGF0IHN0YXJ0XHJcbiAgICBzdGFydFJhbmdlLmluc2VydE5vZGUoc3RhcnQpO1xyXG5cclxuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVzdG9yZVNlbGVjdGlvbkZyb21NYXJrZXJzKG1hcmtlcnM6IHsgc3RhcnQ6IEhUTUxFbGVtZW50OyBlbmQ6IEhUTUxFbGVtZW50IH0gfCBudWxsKSB7XHJcbiAgICBpZiAoIW1hcmtlcnMpIHJldHVybjtcclxuICAgIGNvbnN0IHsgc3RhcnQsIGVuZCB9ID0gbWFya2VycztcclxuICAgIGNvbnN0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgIGlmICghc2VsKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgbmV3UmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xyXG4gICAgbmV3UmFuZ2Uuc2V0U3RhcnRBZnRlcihzdGFydCk7XHJcbiAgICBuZXdSYW5nZS5zZXRFbmRCZWZvcmUoZW5kKTtcclxuXHJcbiAgICAvLyBDbGVhbiB1cCBtYXJrZXJzXHJcbiAgICBzdGFydC5wYXJlbnROb2RlPy5yZW1vdmVDaGlsZChzdGFydCk7XHJcbiAgICBlbmQucGFyZW50Tm9kZT8ucmVtb3ZlQ2hpbGQoZW5kKTtcclxuXHJcbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XHJcbiAgICBzZWwuYWRkUmFuZ2UobmV3UmFuZ2UpO1xyXG4gICAgdGhpcy5zYXZlZFJhbmdlID0gbmV3UmFuZ2UuY2xvbmVSYW5nZSgpO1xyXG4gIH1cclxuXHJcblxyXG5cclxuICBzaG93VG9vbGJhcihldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpIHx8ICF0aGlzLmVkaXRhYmxlKSByZXR1cm47XHJcblxyXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgaWYgKHNlbGVjdGlvbiA9PSBudWxsKVxyXG4gICAgICByZXR1cm47XHJcblxyXG4gICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcclxuICAgIGNvbnN0IHJlY3QgPSByYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IHBhcmVudFJlY3QgPSB0aGlzLnBhcmVudEVsZW1lbnQubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IHRvcEZyb21QYXJlbnQgPSByZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xyXG5cclxuICAgIGlmIChzZWxlY3Rpb24gJiYgc2VsZWN0aW9uLnJhbmdlQ291bnQgPiAwKSB7XHJcbiAgICAgIHRoaXMuc3VnZ2VzdGlvblkgPSB0b3BGcm9tUGFyZW50ICsgMzA7XHJcbiAgICAgIHRoaXMuc2hvd1N1Z2dlc3Rpb24gPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzZWxlY3Rpb24gJiYgc2VsZWN0aW9uLnRvU3RyaW5nKCkudHJpbSgpICE9PSAnJykge1xyXG4gICAgICBjb25zdCB0b29sYmFyV2lkdGggPSA1NDE7XHJcblxyXG4gICAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICAgIGNvbnN0IHJpZ2h0UG9zaXRvbiA9IHZpZXdwb3J0V2lkdGggLSBwYXJlbnRSZWN0LmxlZnQ7XHJcbiAgICAgIGlmIChyaWdodFBvc2l0b24gKyB0b29sYmFyV2lkdGggPiB2aWV3cG9ydFdpZHRoKSB7XHJcbiAgICAgICAgdGhpcy5yaWdodFplcm8gPSBmYWxzZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnJpZ2h0WmVybyA9IHRydWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMudG9vbGJhclkgPSB0b3BGcm9tUGFyZW50ICsgMzA7XHJcblxyXG4gICAgICB0aGlzLnJlRm9ybWF0dGluZ0RhdGEoKTtcclxuICAgICAgdGhpcy5yZWFkRm9ybWF0dGluZ1Byb3BlcnRpZXMoKTtcclxuXHJcbiAgICAgIHRoaXMuc2hvdyA9IHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNob3cgPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJlbWVtYmVyU2VsZWN0aW9uKGU6IE1vdXNlRXZlbnQpIHtcclxuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkgcmV0dXJuO1xyXG4gICAgY29uc3Qgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgaWYgKHNlbCAmJiBzZWwucmFuZ2VDb3VudCA+IDApIHtcclxuICAgICAgdGhpcy5zYXZlZFJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCkuY2xvbmVSYW5nZSgpO1xyXG4gICAgfVxyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRBY3RpdmVSYW5nZSgpOiBSYW5nZSB8IG51bGwge1xyXG4gICAgY29uc3Qgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgLy8gUHJlZmVyIHNhdmVkIGNsb25lLCBlbHNlIGxpdmUgc2VsZWN0aW9uIGNsb25lXHJcbiAgICBjb25zdCBjYW5kaWRhdGUgPSB0aGlzLnNhdmVkUmFuZ2VcclxuICAgICAgPz8gKHNlbCAmJiBzZWwucmFuZ2VDb3VudCA+IDAgPyBzZWwuZ2V0UmFuZ2VBdCgwKSA6IG51bGwpO1xyXG4gICAgaWYgKCFjYW5kaWRhdGUpIHJldHVybiBudWxsO1xyXG4gICAgY29uc3QgcmFuZ2UgPSAoJ2Nsb25lUmFuZ2UnIGluIGNhbmRpZGF0ZSkgPyBjYW5kaWRhdGUuY2xvbmVSYW5nZSgpIDogY2FuZGlkYXRlO1xyXG4gICAgcmV0dXJuIHJhbmdlICYmICFyYW5nZS5jb2xsYXBzZWQgPyByYW5nZSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBzZXRDb2xvck1vZGUobW9kZTogJ1NPTElEJyB8ICdHUkFESUVOVCcpIHtcclxuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMuc2VsZWN0ZWRDb2xvclR5cGUgPSBtb2RlO1xyXG5cclxuICAgIGNvbnN0IG1hcmtlcnMgPSB0aGlzLm1hcmtTZWxlY3Rpb24oKTtcclxuICAgIGlmICghbWFya2VycykgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IG1hcmtlZFJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcclxuICAgIG1hcmtlZFJhbmdlLnNldFN0YXJ0QWZ0ZXIobWFya2Vycy5zdGFydCk7XHJcbiAgICBtYXJrZWRSYW5nZS5zZXRFbmRCZWZvcmUobWFya2Vycy5lbmQpO1xyXG5cclxuICAgIGlmIChtb2RlID09PSAnR1JBRElFTlQnKSB7XHJcbiAgICAgIGNvbnN0IGdyYWRpZW50ID0gYGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgJHt0aGlzLnByaW1hcnlDb2xvcn0gMCUsICR7dGhpcy5zZWNvbmRhcnlDb2xvcn0gMTAwJSlgO1xyXG4gICAgICB0aGlzLndyYXBSYW5nZVdpdGhHcmFkaWVudChtYXJrZWRSYW5nZSwgZ3JhZGllbnQpO1xyXG5cclxuICAgICAgbWFya2Vycy5zdGFydC5wYXJlbnROb2RlPy5yZW1vdmVDaGlsZChtYXJrZXJzLnN0YXJ0KTtcclxuICAgICAgbWFya2Vycy5lbmQucGFyZW50Tm9kZT8ucmVtb3ZlQ2hpbGQobWFya2Vycy5lbmQpO1xyXG5cclxuICAgICAgY29uc3Qgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgICBpZiAoc2VsICYmIHNlbC5yYW5nZUNvdW50ID4gMCkgdGhpcy5zYXZlZFJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCkuY2xvbmVSYW5nZSgpO1xyXG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy5lZGl0b3IubmF0aXZlRWxlbWVudC5pbm5lckhUTUwpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHRoaXMudW53cmFwR3JhZGllbnRJblJhbmdlKG1hcmtlZFJhbmdlKTtcclxuXHJcblxyXG4gICAgdGhpcy5yZXN0b3JlU2VsZWN0aW9uRnJvbU1hcmtlcnMobWFya2Vycyk7XHJcblxyXG5cclxuICAgIHRoaXMuc2V0U3R5bGVXaXRoQ1NTKHRydWUpO1xyXG4gICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2ZvcmVDb2xvcicsIGZhbHNlLCB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkQ29sb3IgfHwgJyMwMDAwMDAnKTtcclxuXHJcbiAgICBjb25zdCBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgICBpZiAoc2VsICYmIHNlbC5yYW5nZUNvdW50ID4gMCkgdGhpcy5zYXZlZFJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCkuY2xvbmVSYW5nZSgpO1xyXG4gICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHRoaXMuZWRpdG9yLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgd3JhcFJhbmdlV2l0aEdyYWRpZW50KHJhbmdlOiBSYW5nZSwgZ3JhZGllbnQ6IHN0cmluZykge1xyXG4gICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuICAgIHNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLWdyYWRpZW50JywgJ3RydWUnKTtcclxuICAgIHNwYW4uc3R5bGUuYmFja2dyb3VuZEltYWdlID0gZ3JhZGllbnQ7XHJcbiAgICBzcGFuLnN0eWxlLmJhY2tncm91bmRDbGlwID0gJ3RleHQnO1xyXG4gICAgKHNwYW4uc3R5bGUgYXMgYW55KS53ZWJraXRCYWNrZ3JvdW5kQ2xpcCA9ICd0ZXh0JztcclxuICAgIChzcGFuLnN0eWxlIGFzIGFueSkud2Via2l0VGV4dEZpbGxDb2xvciA9ICd0cmFuc3BhcmVudCc7XHJcbiAgICBzcGFuLnN0eWxlLmNvbG9yID0gJ3RyYW5zcGFyZW50JztcclxuXHJcbiAgICBjb25zdCBmcmFnID0gcmFuZ2UuZXh0cmFjdENvbnRlbnRzKCk7XHJcbiAgICBzcGFuLmFwcGVuZENoaWxkKGZyYWcpO1xyXG4gICAgcmFuZ2UuaW5zZXJ0Tm9kZShzcGFuKTtcclxuXHJcblxyXG4gICAgY29uc3Qgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgc2VsPy5yZW1vdmVBbGxSYW5nZXMoKTtcclxuICAgIGNvbnN0IG5ld1JhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcclxuICAgIG5ld1JhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhzcGFuKTtcclxuICAgIHNlbD8uYWRkUmFuZ2UobmV3UmFuZ2UpO1xyXG5cclxuICAgIHRoaXMubGFzdEdyYWRpZW50U3BhbiA9IHNwYW47XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVud3JhcEdyYWRpZW50SW5SYW5nZShyYW5nZTogUmFuZ2UpIHtcclxuICAgIGNvbnN0IHJvb3Q6IEhUTUxFbGVtZW50ID0gdGhpcy5lZGl0b3I/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoIXJvb3QpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBzcGFucyA9IEFycmF5LmZyb20ocm9vdC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuW2RhdGEtZ3JhZGllbnQ9XCJ0cnVlXCJdJykpIGFzIEhUTUxFbGVtZW50W107XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IHNwYW5zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgIGNvbnN0IHNwYW4gPSBzcGFuc1tpXTtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBpZiAocmFuZ2UuaW50ZXJzZWN0c05vZGUoc3BhbikpIHtcclxuICAgICAgICAgIHdoaWxlIChzcGFuLmZpcnN0Q2hpbGQpIHtcclxuICAgICAgICAgICAgc3Bhbi5wYXJlbnROb2RlPy5pbnNlcnRCZWZvcmUoc3Bhbi5maXJzdENoaWxkLCBzcGFuKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHNwYW4ucGFyZW50Tm9kZT8ucmVtb3ZlQ2hpbGQoc3Bhbik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaGlkZVRvb2xiYXIoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSB8fCAhdGhpcy5lZGl0YWJsZSkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGNsaWNrZWRJbnNpZGVFZGl0b3IgPSB0aGlzLmVkaXRvcj8ubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpO1xyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZVRvb2xiYXIgPSB0aGlzLnRvb2xiYXI/Lm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KTtcclxuICAgIGNvbnN0IGNsaWNrZWRJbnNpZGVTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uPy5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCk7XHJcblxyXG4gICAgaWYgKCFjbGlja2VkSW5zaWRlRWRpdG9yICYmICFjbGlja2VkSW5zaWRlVG9vbGJhcikge1xyXG4gICAgICB0aGlzLnNob3cgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmICghY2xpY2tlZEluc2lkZUVkaXRvciAmJiAhY2xpY2tlZEluc2lkZVN1Z2dlc3Rpb24pIHtcclxuICAgICAgdGhpcy5zaG93U3VnZ2VzdGlvbiA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZm9ybWF0VGV4dChjb21tYW5kOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgPSAnJykge1xyXG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSByZXR1cm47XHJcblxyXG4gICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIHZhbHVlKTtcclxuXHJcbiAgICBpZiAoY29tbWFuZCA9PT0gJ2JvbGQnKVxyXG4gICAgICB0aGlzLnRvb2xiYXJEYXRhLmlzQm9sZCA9ICF0aGlzLnRvb2xiYXJEYXRhLmlzQm9sZDtcclxuICAgIGlmIChjb21tYW5kID09PSAnaXRhbGljJylcclxuICAgICAgdGhpcy50b29sYmFyRGF0YS5pc0l0YWxpYyA9ICF0aGlzLnRvb2xiYXJEYXRhLmlzSXRhbGljO1xyXG4gICAgaWYgKGNvbW1hbmQgPT09ICd1bmRlcmxpbmUnKVxyXG4gICAgICB0aGlzLnRvb2xiYXJEYXRhLmlzVW5kZXJsaW5lZCA9ICF0aGlzLnRvb2xiYXJEYXRhLmlzVW5kZXJsaW5lZFxyXG4gICAgaWYgKGNvbW1hbmQgPT09ICdpbnNlcnRPcmRlcmVkTGlzdCcgfHwgY29tbWFuZCA9PT0gJ2luc2VydFVub3JkZXJlZExpc3QnKSB7XHJcbiAgICAgIHRoaXMudG9vbGJhckRhdGEuc2VsZWN0ZWRMaXN0ID0gY29tbWFuZCA9PT0gdGhpcy50b29sYmFyRGF0YS5zZWxlY3RlZExpc3QgPyAnJyA6IGNvbW1hbmQ7XHJcbiAgICAgIHRoaXMudXBkYXRlRlNmb3JPTCgpXHJcbiAgICAgIC8vIEFwcGx5IGN1cnJlbnQgc2l6ZSB0byB0aGUgbGlzdCB3cmFwcGVyIGFuZCBpdGVtc1xyXG4gICAgfVxyXG4gICAgaWYgKGNvbW1hbmQgPT09ICdqdXN0aWZ5TGVmdCcgfHwgY29tbWFuZCA9PT0gJ2p1c3RpZnlDZW50ZXInIHx8IGNvbW1hbmQgPT09ICdqdXN0aWZ5UmlnaHQnKVxyXG4gICAgICB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkQWxpZ25tZW50ID0gY29tbWFuZCA9PT0gdGhpcy50b29sYmFyRGF0YS5zZWxlY3RlZEFsaWdubWVudCA/ICcnIDogY29tbWFuZDtcclxuICAgIGlmIChjb21tYW5kID09PSAnZm9ybWF0QmxvY2snKVxyXG4gICAgICB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkSGVhZGluZyA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlRlNmb3JPTCgpIHtcclxuICAgIGNvbnN0IGNzc1NpemUgPSB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkU2l6ZTtcclxuICAgIGlmIChjc3NTaXplKSB7XHJcbiAgICAgIGNvbnN0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgICAgaWYgKHNlbCAmJiBzZWwucmFuZ2VDb3VudCA+IDApIHtcclxuICAgICAgICBjb25zdCBmb2N1cyA9IHNlbC5mb2N1c05vZGUgYXMgTm9kZTtcclxuICAgICAgICBjb25zdCBiYXNlRWwgPSAoZm9jdXMubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFXHJcbiAgICAgICAgICA/IChmb2N1cyBhcyBFbGVtZW50KVxyXG4gICAgICAgICAgOiAoZm9jdXMucGFyZW50RWxlbWVudCBhcyBFbGVtZW50KSkgfHwgbnVsbDtcclxuXHJcbiAgICAgICAgY29uc3QgbGlzdEVsID0gYmFzZUVsPy5jbG9zZXN0Py4oJ29sLCB1bCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcclxuICAgICAgICBpZiAobGlzdEVsKSB7XHJcbiAgICAgICAgICBsaXN0RWwuc3R5bGUuZm9udFNpemUgPSBjc3NTaXplO1xyXG4gICAgICAgICAgbGlzdEVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ2xpJykuZm9yRWFjaChsaSA9PiB7XHJcbiAgICAgICAgICAgIChsaSBhcyBIVE1MRWxlbWVudCkuc3R5bGUuZm9udFNpemUgPSBjc3NTaXplO1xyXG4gICAgICAgICAgICAobGkgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLmNvbG9yID0gdGhpcy50b29sYmFyRGF0YS5zZWxlY3RlZENvbG9yXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0U3R5bGVXaXRoQ1NTKGVuYWJsZTogYm9vbGVhbikge1xyXG4gICAgdHJ5IHtcclxuICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ3N0eWxlV2l0aENTUycsIGZhbHNlLCBlbmFibGUgPyAndHJ1ZScgOiAnZmFsc2UnKTtcclxuICAgIH0gY2F0Y2ggeyAvKiBzb21lIGVuZ2luZXMgaWdub3JlICovIH1cclxuICB9XHJcbiAgcHJpdmF0ZSB0b0xlZ2FjeUZvbnRTdGVwKGNzc1NpemU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7XHJcbiAgICAgICcnOiAzLFxyXG4gICAgICAnY2xhbXAoMC43NXJlbSwgMnZ3LCAxcmVtKSc6IDIsXHJcbiAgICAgICdjbGFtcCgwLjc1cmVtLCAydncsIDEuMjVyZW0pJzogMyxcclxuICAgICAgJ2NsYW1wKDFyZW0sIDN2dywgMS41cmVtKSc6IDQsXHJcbiAgICAgICdjbGFtcCgxLjI1cmVtLCA0dncsIDJyZW0pJzogNSxcclxuICAgICAgJ2NsYW1wKDJyZW0sIDV2dywgM3JlbSknOiA2LFxyXG4gICAgICAnY2xhbXAoMy4xcmVtLCA3dncsIDQuNXJlbSknOiA3XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFN0cmluZyhtYXAuaGFzT3duUHJvcGVydHkoY3NzU2l6ZSkgPyBtYXBbY3NzU2l6ZV0gOiAzKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbm9ybWFsaXplRm9udFNpemVUb0Nzcyhjc3NTaXplOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgPSB0aGlzLmVkaXRvcj8ubmF0aXZlRWxlbWVudDtcclxuICAgIGlmICghY29udGFpbmVyKSByZXR1cm47XHJcbiAgICBjb25zdCBmb250cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCdmb250W3NpemVdJyk7XHJcbiAgICBmb250cy5mb3JFYWNoKChmb250RWw6IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCBzcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xyXG4gICAgICBpZiAoY3NzU2l6ZSkgc3Bhbi5zdHlsZS5mb250U2l6ZSA9IGNzc1NpemU7XHJcbiAgICAgIHdoaWxlIChmb250RWwuZmlyc3RDaGlsZCkgc3Bhbi5hcHBlbmRDaGlsZChmb250RWwuZmlyc3RDaGlsZCk7XHJcbiAgICAgIGZvbnRFbC5wYXJlbnROb2RlPy5yZXBsYWNlQ2hpbGQoc3BhbiwgZm9udEVsKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgY2hhbmdlRm9udFNpemUoZXZlbnQ6IGFueSkge1xyXG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgY3NzU2l6ZSA9IGV2ZW50LnRhcmdldC52YWx1ZSBhcyBzdHJpbmc7XHJcblxyXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgc2VsZWN0aW9uLnJhbmdlQ291bnQgPT09IDApIHJldHVybjtcclxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XHJcbiAgICBpZiAocmFuZ2UuY29sbGFwc2VkKSByZXR1cm47XHJcblxyXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG5cclxuICAgICAgdGhpcy5zZXRTdHlsZVdpdGhDU1ModHJ1ZSk7XHJcblxyXG4gICAgICBjb25zdCBzdGVwID0gdGhpcy50b0xlZ2FjeUZvbnRTdGVwKGNzc1NpemUpO1xyXG4gICAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnZm9udFNpemUnLCBmYWxzZSwgc3RlcCk7XHJcblxyXG4gICAgICB0aGlzLm5vcm1hbGl6ZUZvbnRTaXplVG9Dc3MoY3NzU2l6ZSk7XHJcblxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy50b29sYmFyRGF0YS5zZWxlY3RlZFNpemUgPSBjc3NTaXplO1xyXG4gICAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHRoaXMuZWRpdG9yLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSwgMCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG5cclxuICBjaGFuZ2VDb2xvcihldmVudDogYW55KSB7XHJcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBjb2xvciA9IGV2ZW50LnRhcmdldC52YWx1ZSBhcyBzdHJpbmc7XHJcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgICBpZiAoIXNlbGVjdGlvbiB8fCBzZWxlY3Rpb24ucmFuZ2VDb3VudCA9PT0gMCkgcmV0dXJuO1xyXG4gICAgaWYgKHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApLmNvbGxhcHNlZCkgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgdGhpcy5zZXRTdHlsZVdpdGhDU1ModHJ1ZSk7XHJcbiAgICAgIC8vICB0aGlzLnVud3JhcEdyYWRpZW50SW5TZWxlY3Rpb24oKTtcclxuXHJcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdmb3JlQ29sb3InLCBmYWxzZSwgY29sb3IpO1xyXG5cclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgIHRoaXMudG9vbGJhckRhdGEuc2VsZWN0ZWRDb2xvciA9IGNvbG9yO1xyXG4gICAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHRoaXMuZWRpdG9yLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSwgMCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVRleHQoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy5lZGl0b3IubmF0aXZlRWxlbWVudC5pbm5lckhUTUwpO1xyXG4gIH1cclxuXHJcbiAgb25Gb3JtYXRDaGFuZ2UoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBjb25zdCBzZWxlY3RlZFZhbHVlID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MU2VsZWN0RWxlbWVudCkudmFsdWU7XHJcbiAgICB0aGlzLmZvcm1hdFRleHQoJ2Zvcm1hdEJsb2NrJywgc2VsZWN0ZWRWYWx1ZSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgb3BlbkNvbG9yUGlja2VyKCkge1xyXG4gICAgdGhpcy5zYXZlU2VsZWN0aW9uKCk7XHJcbiAgfVxyXG5cclxuICByZWFkRm9ybWF0dGluZ1Byb3BlcnRpZXMoKSB7XHJcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgICBpZiAoIXNlbGVjdGlvbikgcmV0dXJuO1xyXG4gICAgY29uc3Qgbm9kZSA9IHNlbGVjdGlvbi5mb2N1c05vZGUgYXMgSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgbm9kZSBpcyBudWxsXHJcbiAgICBpZiAoIW5vZGUpIHJldHVybjtcclxuXHJcbiAgICBsZXQgZWxlbWVudCA9IG5vZGUucGFyZW50RWxlbWVudDtcclxuICAgIHdoaWxlIChlbGVtZW50KSB7XHJcbiAgICAgIGNvbnN0IG5vZGVOYW1lID0gZWxlbWVudC5ub2RlTmFtZTtcclxuXHJcbiAgICAgIGlmIChub2RlTmFtZSA9PT0gJ0gxJyB8fCBub2RlTmFtZSA9PT0gJ0gyJyB8fCBub2RlTmFtZSA9PT0gJ0gzJykge1xyXG4gICAgICAgIHRoaXMudG9vbGJhckRhdGEuc2VsZWN0ZWRIZWFkaW5nID0gbm9kZU5hbWU7XHJcbiAgICAgIH0gZWxzZSBpZiAobm9kZU5hbWUgPT09ICdCJyB8fCBub2RlTmFtZSA9PT0gJ1NUUk9ORycpIHtcclxuICAgICAgICB0aGlzLnRvb2xiYXJEYXRhLmlzQm9sZCA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAobm9kZU5hbWUgPT09ICdJJyB8fCBub2RlTmFtZSA9PT0gJ0VNJykge1xyXG4gICAgICAgIHRoaXMudG9vbGJhckRhdGEuaXNJdGFsaWMgPSB0cnVlO1xyXG4gICAgICB9IGVsc2UgaWYgKG5vZGVOYW1lID09PSAnVScpIHtcclxuICAgICAgICB0aGlzLnRvb2xiYXJEYXRhLmlzVW5kZXJsaW5lZCA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAobm9kZU5hbWUgPT09ICdPTCcpIHtcclxuICAgICAgICB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkTGlzdCA9ICdpbnNlcnRPcmRlcmVkTGlzdCc7XHJcbiAgICAgIH0gZWxzZSBpZiAobm9kZU5hbWUgPT09ICdVTCcpIHtcclxuICAgICAgICB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkTGlzdCA9ICdpbnNlcnRVbm9yZGVyZWRMaXN0JztcclxuICAgICAgfSBlbHNlIGlmIChlbGVtZW50LnN0eWxlLnRleHRBbGlnbikge1xyXG4gICAgICAgIHRoaXMudG9vbGJhckRhdGEuc2VsZWN0ZWRBbGlnbm1lbnQgPSBganVzdGlmeSR7ZWxlbWVudC5zdHlsZS50ZXh0QWxpZ24uY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBlbGVtZW50LnN0eWxlLnRleHRBbGlnbi5zbGljZSgxKX1gO1xyXG4gICAgICB9IGVsc2UgaWYgKGVsZW1lbnQuc3R5bGUuZm9udFNpemUpIHtcclxuICAgICAgICB0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkU2l6ZSA9IGVsZW1lbnQuc3R5bGUuZm9udFNpemU7XHJcbiAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC5zdHlsZS5jb2xvcikge1xyXG4gICAgICAgIHRoaXMudG9vbGJhckRhdGEuc2VsZWN0ZWRDb2xvciA9IGVsZW1lbnQuc3R5bGUuY29sb3JcclxuICAgICAgfVxyXG5cclxuXHJcbiAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZUZvcm1hdHRpbmdEYXRhKCkge1xyXG4gICAgdGhpcy50b29sYmFyRGF0YSA9IHtcclxuICAgICAgc2VsZWN0ZWRIZWFkaW5nOiAnJyxcclxuICAgICAgaXNCb2xkOiBmYWxzZSxcclxuICAgICAgaXNJdGFsaWM6IGZhbHNlLFxyXG4gICAgICBpc1VuZGVybGluZWQ6IGZhbHNlLFxyXG4gICAgICBzZWxlY3RlZFNpemU6ICcnLFxyXG4gICAgICBzZWxlY3RlZExpc3Q6ICcnLFxyXG4gICAgICBzZWxlY3RlZEFsaWdubWVudDogJycsXHJcbiAgICAgIHNlbGVjdGVkQ29sb3I6ICcnXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjaGFuZ2VHcmFkaWVudENvbG9yKCkge1xyXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAvLyBSZXN0b3JlIHByZXZpb3VzIHNlbGVjdGlvbiBmaXJzdFxyXG4gICAgICB0aGlzLnJlc3RvcmVTZWxlY3Rpb24oKTtcclxuXHJcblxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLnNhdmVTZWxlY3Rpb24oKTtcclxuXHJcbiAgICAgICAgY29uc3QgZ3JhZGllbnQgPSBgbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAke3RoaXMucHJpbWFyeUNvbG9yfSAwJSwgJHt0aGlzLnNlY29uZGFyeUNvbG9yfSAxMDAlKWA7XHJcbiAgICAgICAgdGhpcy5hcHBseUdyYWRpZW50VG9UZXh0KGdyYWRpZW50KTtcclxuICAgICAgICB0aGlzLnJlc3RvcmVTZWxlY3Rpb24oKTtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCh0aGlzLmVkaXRvci5uYXRpdmVFbGVtZW50LmlubmVySFRNTCk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9LCAwKTtcclxuICAgICAgfSwgMTApOyAvLyAxMG1zIGRlbGF5IChhZGp1c3RhYmxlIGlmIG5lZWRlZClcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgYXBwbHlHcmFkaWVudFRvVGV4dChncmFkaWVudFZhbHVlOiBzdHJpbmcpIHtcclxuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgIGNvbnN0IHJvb3QgPSB0aGlzLmVkaXRvcj8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcclxuICAgIGlmICghcm9vdCkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGV4aXN0aW5nID0gcm9vdC5xdWVyeVNlbGVjdG9yKCdzcGFuW2RhdGEtZ3JhZGllbnQ9XCJ0cnVlXCJdJykgYXMgSFRNTFNwYW5FbGVtZW50IHwgbnVsbDtcclxuICAgIGlmIChleGlzdGluZykge1xyXG4gICAgICBleGlzdGluZy5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBncmFkaWVudFZhbHVlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgc2VsZWN0aW9uLnJhbmdlQ291bnQgPT09IDApIHJldHVybjtcclxuXHJcbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xyXG4gICAgaWYgKCFyYW5nZSB8fCByYW5nZS5jb2xsYXBzZWQpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBzZWxlY3RlZENvbnRlbnQgPSByYW5nZS5leHRyYWN0Q29udGVudHMoKTtcclxuXHJcbiAgICBjb25zdCBzcGFuOiBhbnkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XHJcbiAgICBzcGFuLnNldEF0dHJpYnV0ZSgnZGF0YS1ncmFkaWVudCcsICd0cnVlJyk7IC8vIG1hcmsgZm9yIGZ1dHVyZSB1cGRhdGVzXHJcbiAgICBzcGFuLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IGdyYWRpZW50VmFsdWU7XHJcbiAgICBzcGFuLnN0eWxlLmJhY2tncm91bmRDbGlwID0gJ3RleHQnO1xyXG4gICAgc3Bhbi5zdHlsZS53ZWJraXRCYWNrZ3JvdW5kQ2xpcCA9ICd0ZXh0JztcclxuICAgIHNwYW4uc3R5bGUuY29sb3IgPSAndHJhbnNwYXJlbnQnO1xyXG4gICAgc3Bhbi5zdHlsZS53ZWJraXRUZXh0RmlsbENvbG9yID0gJ3RyYW5zcGFyZW50JztcclxuICAgIHNwYW4uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snOyAvLyBmaXggZnJvbSBpbmxpbmVTaXplPSdibG9jaydcclxuXHJcbiAgICBzcGFuLmFwcGVuZENoaWxkKHNlbGVjdGVkQ29udGVudCk7XHJcbiAgICByYW5nZS5pbnNlcnROb2RlKHNwYW4pO1xyXG5cclxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcclxuICAgIGNvbnN0IG5ld1JhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcclxuICAgIG5ld1JhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhzcGFuKTtcclxuICAgIHNlbGVjdGlvbi5hZGRSYW5nZShuZXdSYW5nZSk7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIHJlZ2VuZXJhdGVUZXh0KCkge1xyXG4gICAgbGV0IHBheWxvYWQgPSB7XHJcbiAgICAgIGJ1c2luZXNzSWQ6IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc0lkJyksXHJcbiAgICAgIGRhdGFJZDogdGhpcy5zZWN0aW9uSWQsXHJcbiAgICAgIHN1YkluZHVzdHJ5SWQ6IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdzdWJJbmR1c3RyeUlkJyksXHJcbiAgICAgIHN1Z2dlc3RlZERhdGFUeXBlOiAnQ09NUE9ORU5UJyxcclxuICAgICAgdG9uZTogJ1BST0ZFU1NJT05BTCcsXHJcbiAgICAgIHZhbHVlOiB0aGlzLnZhbHVlLFxyXG4gICAgICBsYWJlbDogdGhpcy5sYWJlbFxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZWRpdG9yU2VydmljZS5yZWdlbmVyYXRlVGV4dChwYXlsb2FkKS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XHJcbiAgICAgIHRoaXMudmFsdWUgPSByZXMuZGF0YTtcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNhdmVkUmFuZ2U6IFJhbmdlIHwgbnVsbCA9IG51bGw7XHJcblxyXG5cclxuICBzYXZlU2VsZWN0aW9uKCk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xyXG4gICAgaWYgKHNlbGVjdGlvbiAmJiBzZWxlY3Rpb24ucmFuZ2VDb3VudCA+IDApIHtcclxuICAgICAgdGhpcy5zYXZlZFJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXN0b3JlU2VsZWN0aW9uKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuc2F2ZWRSYW5nZSkge1xyXG4gICAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgICAgIHNlbGVjdGlvbj8ucmVtb3ZlQWxsUmFuZ2VzKCk7XHJcbiAgICAgIHNlbGVjdGlvbj8uYWRkUmFuZ2UodGhpcy5zYXZlZFJhbmdlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uUGFzdGUoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSB7XHJcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHJldHVybjtcclxuXHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgIC8vIEdldCBvbmx5IHBsYWluIHRleHRcclxuICAgIGNvbnN0IHRleHQgPSBldmVudC5jbGlwYm9hcmREYXRhPy5nZXREYXRhKCd0ZXh0L3BsYWluJykgfHwgJyc7XHJcblxyXG4gICAgLy8gSW5zZXJ0IGFzIHBsYWluIHRleHRcclxuICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdpbnNlcnRUZXh0JywgZmFsc2UsIHRleHQpO1xyXG4gIH1cclxuXHJcbiAgc3RyaXBTdHlsZXMoaHRtbDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGRvYyA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcoaHRtbCwgJ3RleHQvaHRtbCcpO1xyXG4gICAgY29uc3QgZWxlbWVudHMgPSBkb2MuYm9keS5xdWVyeVNlbGVjdG9yQWxsKCcqJyk7XHJcbiAgICBlbGVtZW50cy5mb3JFYWNoKChlbDogYW55KSA9PiB7XHJcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTsgLy8gUmVtb3ZlIGFsbCBpbmxpbmUgc3R5bGVzXHJcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnY2xhc3MnKTsgLy8gT3B0aW9uYWxcclxuICAgICAgZWwuc2V0QXR0cmlidXRlKCdzdHlsZScsIGBjb2xvcjogJHt0aGlzLnRvb2xiYXJEYXRhLnNlbGVjdGVkQ29sb3J9YCk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBkb2MuYm9keS5pbm5lckhUTUw7XHJcbiAgfVxyXG5cclxuICBnZXRUZXh0KCkge1xyXG4gICAgY29uc3QgdGV4dENvbnRlbnQgPSB0aGlzLnZhbHVlPy5yZXBsYWNlKC88XFwvP1tePl0rKD58JCkvZywgXCJcIik/LnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCkgPz8gXCJcIjtcclxuICAgIGlmICghdGV4dENvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcclxuICB9XHJcbn1cclxuIiwiPCEtLSA8ZGl2IGNsYXNzPVwiZWRpdG9yLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cInsnYm9yZGVyJzogZWRpdGFibGV9XCIgI3BhcmVudEVsZW1lbnRcclxuICBbY2xhc3MuZC1ub25lXT1cIiFlZGl0YWJsZSAmJiBnZXRUZXh0KCkgPT0gJydcIj4gLS0+XHJcbjxkaXYgKm5nSWY9XCJlZGl0YWJsZTsgZWxzZSB2aWV3TW9kZVwiIGNsYXNzPVwiZWRpdG9yLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cInsnYm9yZGVyJzogZWRpdGFibGV9XCIgI3BhcmVudEVsZW1lbnQ+XHJcbiAgPGRpdiBbY29udGVudGVkaXRhYmxlXT1cImVkaXRhYmxlXCIgWyhuZ01vZGVsKV09XCJ2YWx1ZVwiIGNsYXNzPVwiZWRpdGFibGUtdGV4dCBwLTBcIiAobW91c2V1cCk9XCJzaG93VG9vbGJhcigkZXZlbnQpXCJcclxuICAgICNlZGl0b3IgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlVGV4dCgkZXZlbnQpXCIgKG1vdXNlZG93bik9XCJoaWRlVG9vbGJhcigkZXZlbnQpXCIgKHBhc3RlKT1cIm9uUGFzdGUoJGV2ZW50KVwiPlxyXG4gIDwvZGl2PlxyXG5cclxuICA8ZGl2IGNsYXNzPVwidG9vbGJhclwiICpuZ0lmPVwiZWRpdGFibGUgJiYgc2hvd1wiIFtuZ1N0eWxlXT1cInsndG9wLnB4JzogdG9vbGJhcll9XCJcclxuICAgIFtzdHlsZS5yaWdodF09XCJyaWdodFplcm8gPyAnMHB4JyA6ICdhdXRvJ1wiIFtzdHlsZS5sZWZ0XT1cIiFyaWdodFplcm8gPyAnMHB4JyA6ICdhdXRvJ1wiICN0b29sYmFyIGNka0RyYWc+XHJcbiAgICA8IS0tIDxzZWxlY3QgY2xhc3M9XCJ0b29sXCIgKGNoYW5nZSk9XCJvbkZvcm1hdENoYW5nZSgkZXZlbnQpXCIgWyhuZ01vZGVsKV09XCJ0b29sYmFyRGF0YS5zZWxlY3RlZEhlYWRpbmdcIj5cclxuICAgICAgPG9wdGlvbiB2YWx1ZT1cIkgxXCI+SGVhZGluZzE8L29wdGlvbj5cclxuICAgICAgPG9wdGlvbiB2YWx1ZT1cIkgyXCI+SGVhZGluZzI8L29wdGlvbj5cclxuICAgICAgPG9wdGlvbiB2YWx1ZT1cIkgzXCI+SGVhZGluZzM8L29wdGlvbj5cclxuICAgICAgPG9wdGlvbiB2YWx1ZT1cImRpdlwiPlRleHQ8L29wdGlvbj5cclxuICAgIDwvc2VsZWN0PiAtLT5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sXCI+IDxtYXQtaWNvbiBjZGtEcmFnSGFuZGxlPmRyYWdfaW5kaWNhdG9yPC9tYXQtaWNvbj48L2J1dHRvbj5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sXCIgKGNsaWNrKT1cImZvcm1hdFRleHQoJ2JvbGQnKVwiIFtuZ0NsYXNzXT1cInsnc2VsZWN0ZWRUb29sJzogdG9vbGJhckRhdGEuaXNCb2xkfVwiPjxtYXQtaWNvbj5cclxuICAgICAgICBmb3JtYXRfYm9sZDwvbWF0LWljb24+PC9idXR0b24+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbFwiIChjbGljayk9XCJmb3JtYXRUZXh0KCdpdGFsaWMnKVwiIFtuZ0NsYXNzXT1cInsnc2VsZWN0ZWRUb29sJzogdG9vbGJhckRhdGEuaXNJdGFsaWN9XCI+PG1hdC1pY29uPlxyXG4gICAgICAgIGZvcm1hdF9pdGFsaWM8L21hdC1pY29uPjwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cInRvb2xcIiAoY2xpY2spPVwiZm9ybWF0VGV4dCgndW5kZXJsaW5lJylcIiBbbmdDbGFzc109XCJ7J3NlbGVjdGVkVG9vbCc6IHRvb2xiYXJEYXRhLmlzVW5kZXJsaW5lZH1cIlxyXG4gICAgICAqbmdJZj1cInNlbGVjdGVkQ29sb3JUeXBlID09PSAnU09MSUQnXCI+PG1hdC1pY29uPiBmb3JtYXRfdW5kZXJsaW5lZDwvbWF0LWljb24+PC9idXR0b24+XHJcblxyXG4gICAgPHNlbGVjdCBjbGFzcz1cInRvb2xcIiAoY2hhbmdlKT1cImNoYW5nZUZvbnRTaXplKCRldmVudClcIiBbKG5nTW9kZWwpXT1cInRvb2xiYXJEYXRhLnNlbGVjdGVkU2l6ZVwiPlxyXG4gICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgc2VsZWN0ZWQ+RGVmYXVsdDwvb3B0aW9uPlxyXG4gICAgICA8b3B0aW9uIHZhbHVlPVwiY2xhbXAoMC43NXJlbSwgMnZ3LCAxcmVtKVwiPlNtYWxsPC9vcHRpb24+XHJcbiAgICAgIDxvcHRpb24gdmFsdWU9XCJjbGFtcCgwLjc1cmVtLCAydncsIDEuMjVyZW0pXCI+TWVkaXVtPC9vcHRpb24+XHJcbiAgICAgIDxvcHRpb24gdmFsdWU9XCJjbGFtcCgxcmVtLCAzdncsIDEuNXJlbSlcIj5TZW1pIExhcmdlPC9vcHRpb24+XHJcbiAgICAgIDxvcHRpb24gdmFsdWU9XCJjbGFtcCgxLjI1cmVtLCA0dncsIDJyZW0pXCI+TGFyZ2U8L29wdGlvbj5cclxuICAgICAgPG9wdGlvbiB2YWx1ZT1cImNsYW1wKDJyZW0sIDV2dywgM3JlbSlcIj5FeHRyYSBMYXJnZTwvb3B0aW9uPlxyXG4gICAgICA8b3B0aW9uIHZhbHVlPVwiY2xhbXAoMy4xcmVtLCA3dncsIDQuNXJlbSlcIj5IdWdlPC9vcHRpb24+XHJcbiAgICA8L3NlbGVjdD5cclxuXHJcbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbFwiIChjbGljayk9XCJmb3JtYXRUZXh0KCdpbnNlcnRPcmRlcmVkTGlzdCcpXCJcclxuICAgICAgW25nQ2xhc3NdPVwieydzZWxlY3RlZFRvb2wnOiB0b29sYmFyRGF0YS5zZWxlY3RlZExpc3QgPT09ICdpbnNlcnRPcmRlcmVkTGlzdCd9XCI+PG1hdC1pY29uPmZvcm1hdF9saXN0X251bWJlcmVkPC9tYXQtaWNvbj48L2J1dHRvbj5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sXCIgKGNsaWNrKT1cImZvcm1hdFRleHQoJ2luc2VydFVub3JkZXJlZExpc3QnKVwiXHJcbiAgICAgIFtuZ0NsYXNzXT1cInsnc2VsZWN0ZWRUb29sJzogdG9vbGJhckRhdGEuc2VsZWN0ZWRMaXN0ID09PSAnaW5zZXJ0VW5vcmRlcmVkTGlzdCd9XCI+PG1hdC1pY29uPlxyXG4gICAgICAgIGZvcm1hdF9saXN0X2J1bGxldGVkPC9tYXQtaWNvbj48L2J1dHRvbj5cclxuXHJcbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbFwiIChjbGljayk9XCJmb3JtYXRUZXh0KCdqdXN0aWZ5TGVmdCcpXCJcclxuICAgICAgW25nQ2xhc3NdPVwieydzZWxlY3RlZFRvb2wnOiB0b29sYmFyRGF0YS5zZWxlY3RlZEFsaWdubWVudCA9PT0gJ2p1c3RpZnlMZWZ0J31cIj48bWF0LWljb24+XHJcbiAgICAgICAgZm9ybWF0X2FsaWduX2xlZnQ8L21hdC1pY29uPjwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cInRvb2xcIiAoY2xpY2spPVwiZm9ybWF0VGV4dCgnanVzdGlmeUNlbnRlcicpXCJcclxuICAgICAgW25nQ2xhc3NdPVwieydzZWxlY3RlZFRvb2wnOiB0b29sYmFyRGF0YS5zZWxlY3RlZEFsaWdubWVudCA9PT0gJ2p1c3RpZnlDZW50ZXInfVwiPjxtYXQtaWNvbj5cclxuICAgICAgICBmb3JtYXRfYWxpZ25fY2VudGVyPC9tYXQtaWNvbj48L2J1dHRvbj5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sXCIgKGNsaWNrKT1cImZvcm1hdFRleHQoJ2p1c3RpZnlSaWdodCcpXCJcclxuICAgICAgW25nQ2xhc3NdPVwieydzZWxlY3RlZFRvb2wnOiB0b29sYmFyRGF0YS5zZWxlY3RlZEFsaWdubWVudCA9PT0gJ2p1c3RpZnlSaWdodCd9XCI+PG1hdC1pY29uPlxyXG4gICAgICAgIGZvcm1hdF9hbGlnbl9yaWdodDwvbWF0LWljb24+PC9idXR0b24+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbG9yVHlwZVwiPlxyXG4gICAgICA8YnV0dG9uIGNsYXNzPVwic29saWRcIiBbbmdDbGFzc109XCJ7J3NvbGlkQ29sb3JTZWxlY3RlZCc6IHNlbGVjdGVkQ29sb3JUeXBlID09PSAnU09MSUQnfVwiXHJcbiAgICAgICAgKG1vdXNlZG93bik9XCJyZW1lbWJlclNlbGVjdGlvbigkZXZlbnQpXCIgKGNsaWNrKT1cInNldENvbG9yTW9kZSgnU09MSUQnKVwiPlxyXG4gICAgICAgIFNvbGlkXHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8YnV0dG9uIGNsYXNzPVwiZ3JhZGllbnRcIiBbbmdDbGFzc109XCJ7J2dyYWRpZW50Q29sb3JTZWxlY3RlZCc6IHNlbGVjdGVkQ29sb3JUeXBlID09PSAnR1JBRElFTlQnfVwiXHJcbiAgICAgICAgKG1vdXNlZG93bik9XCJyZW1lbWJlclNlbGVjdGlvbigkZXZlbnQpXCIgKGNsaWNrKT1cInNldENvbG9yTW9kZSgnR1JBRElFTlQnKVwiPlxyXG4gICAgICAgIEdyYWRpZW50XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcblxyXG5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIGNvbG9yLXBpY2tlci1idG5cIiAoY2xpY2spPVwib3BlbkNvbG9yUGlja2VyKClcIiAqbmdJZj1cInNlbGVjdGVkQ29sb3JUeXBlID09PSAnU09MSUQnXCI+XHJcbiAgICAgIDxtYXQtaWNvbj5mb3JtYXRfY29sb3JfdGV4dDwvbWF0LWljb24+XHJcbiAgICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiAjY29sb3JQaWNrZXIgY2xhc3M9XCJoaWRkZW4tY29sb3ItcGlja2VyXCIgKGlucHV0KT1cImNoYW5nZUNvbG9yKCRldmVudClcIlxyXG4gICAgICAgIFsobmdNb2RlbCldPVwidG9vbGJhckRhdGEuc2VsZWN0ZWRDb2xvclwiPlxyXG4gICAgPC9idXR0b24+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbG9yVHlwZVwiICpuZ0lmPVwic2VsZWN0ZWRDb2xvclR5cGUgPT09ICdHUkFESUVOVCdcIj5cclxuICAgICAgPGJ1dHRvbiBjbGFzcz1cInRvb2wgY29sb3ItcGlja2VyLWJ0blwiIChjbGljayk9XCJvcGVuQ29sb3JQaWNrZXIoKTsgcHJpbWFyeUNvbG9yUGlja2VyLmNsaWNrKClcIj5cclxuICAgICAgICA8bWF0LWljb24gW3N0eWxlLmNvbG9yXT1cInByaW1hcnlDb2xvclwiPmZvcm1hdF9jb2xvcl90ZXh0PC9tYXQtaWNvbj5cclxuICAgICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgI3ByaW1hcnlDb2xvclBpY2tlciBjbGFzcz1cImhpZGRlbi1jb2xvci1waWNrZXJcIiAoaW5wdXQpPVwiY2hhbmdlR3JhZGllbnRDb2xvcigpXCJcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwicHJpbWFyeUNvbG9yXCI+XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8YnV0dG9uIGNsYXNzPVwidG9vbCBjb2xvci1waWNrZXItYnRuXCIgKGNsaWNrKT1cIm9wZW5Db2xvclBpY2tlcigpOyBzZWNvbmRhcnlDb2xvclBpY2tlci5jbGljaygpXCI+XHJcbiAgICAgICAgPG1hdC1pY29uIFtzdHlsZS5jb2xvcl09XCJzZWNvbmRhcnlDb2xvclwiPmZvcm1hdF9jb2xvcl90ZXh0PC9tYXQtaWNvbj5cclxuICAgICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgI3NlY29uZGFyeUNvbG9yUGlja2VyIGNsYXNzPVwiaGlkZGVuLWNvbG9yLXBpY2tlclwiIChpbnB1dCk9XCJjaGFuZ2VHcmFkaWVudENvbG9yKClcIlxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWNvbmRhcnlDb2xvclwiPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG5cclxuICA8ZGl2IGNsYXNzPVwic3VnZ2VzdGlvbi1ib3hcIiBbbmdTdHlsZV09XCJ7J3RvcC5weCc6IHN1Z2dlc3Rpb25ZfVwiIFtzdHlsZS5yaWdodF09XCJyaWdodFplcm8gPyAnMHB4JyA6ICdhdXRvJ1wiXHJcbiAgICBbc3R5bGUubGVmdF09XCIhcmlnaHRaZXJvID8gJzBweCcgOiAnYXV0bydcIiAqbmdJZj1cImVkaXRhYmxlICYmIGxhYmVsICYmIHNob3dTdWdnZXN0aW9uXCIgI3N1Z2dlc3Rpb24+XHJcbiAgICA8ZGl2IGNsYXNzPVwic3VnZ2VzdGlvblwiIChjbGljayk9XCJyZWdlbmVyYXRlVGV4dCgpXCI+XHJcbiAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly9wcm9kLXNpbXBvLnMzLmFwLXNvdXRoLTEuYW1hem9uYXdzLmNvbS9wcm9kLWltYWdlcy84ODc0OTNjMTc0MjI3Mzk3MDE1MUZyYW1lJTIwMTI0NDgzMTc0MC5wbmdcIlxyXG4gICAgICAgIGFsdD1cIlwiPlxyXG4gICAgICA8ZGl2PlxyXG4gICAgICAgIDxwIGNsYXNzPVwibmFtZVwiPlJlZ2VuZXJhdGUgVGV4dDwvcD5cclxuICAgICAgICA8cCBjbGFzcz1cImRlc2NcIj5HZXQgYSBmcmVzaCB2YXJpYXRpb24gb2YgYSBjdXJyZW50IHRleHQ8L3A+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG48bmctdGVtcGxhdGUgI3ZpZXdNb2RlPlxyXG4gIDxkaXYgY2xhc3M9XCJyZWFkLW9ubHktdGV4dFwiICpuZ0lmPVwidmFsdWVcIj5cclxuICAgIDxkaXYgW2NvbnRlbnRlZGl0YWJsZV09XCJlZGl0YWJsZVwiIFsobmdNb2RlbCldPVwidmFsdWVcIj48L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9uZy10ZW1wbGF0ZT4iXX0=
367
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9lbGVtZW50cy90ZXh0LWVkaXRvci90ZXh0LWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL2VsZW1lbnRzL3RleHQtZWRpdG9yL3RleHQtZWRpdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDJCQUEyQjtBQUUzQixPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFDTixTQUFTLEVBQ1QsV0FBVyxFQUNYLE1BQU0sRUFHUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQ0wsWUFBWSxFQUNaLGlCQUFpQixFQUNsQixNQUFNLGlCQUFpQixDQUFDO0FBRXpCLE9BQU8sRUFDTCxZQUFZLEVBRWIsTUFBTSwyQkFBMkIsQ0FBQztBQUVuQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXZELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFM0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFbEUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFekYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFcEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7Ozs7OztBQW9CNUQsTUFBTSxPQUFPLG1CQUFtQjtJQWxCaEM7UUF5QkUs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SUFBSSxFQUFFLEVBQUUsRUFBRSxHQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFFOUIsSUFBSSxJQUFJLEtBQUssRUFBRTtZQUNiLE9BQU87UUFFVCxJQUFJLENBQUMsTUFBTTthQUNSLEtBQUssRUFBRTthQUNQLEtBQUssRUFBRTthQUNQLGdCQUFnQixDQUFDO1lBQ2hCLElBQUk7WUFDSixFQUFFO1NBQ0gsQ0FBQzthQUNELE9BQU8sQ0FDTixXQUFXLEVBQ1g7WUFDRSxRQUFRO1NBQ1QsQ0FDRjthQUNBLEdBQUcsRUFBRSxDQUFDO0lBRVgsQ0FBQzsrR0ExbUJVLG1CQUFtQjttR0FBbkIsbUJBQW1CLHFhQzlEaEMsK3BRQTZMYyxpckZENUlWLFlBQVksa0lBQ1osV0FBVyw4bUJBQ1gsYUFBYSxvTEFDYixPQUFPLHVjQUNQLGVBQWUsODNCQUNmLGtCQUFrQjs7NEZBUVQsbUJBQW1CO2tCQWxCL0IsU0FBUzsrQkFDRSxtQkFBbUIsY0FDakIsSUFBSSxXQUVQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxhQUFhO3dCQUNiLE9BQU87d0JBQ1AsZUFBZTt3QkFDZixrQkFBa0I7d0JBQ2xCLDRCQUE0QjtxQkFDN0I7OEJBYUQsS0FBSztzQkFESixLQUFLO2dCQUtOLFdBQVc7c0JBRFYsTUFBTTtnQkFLUCxRQUFRO3NCQURQLEtBQUs7Z0JBSU4sU0FBUztzQkFEUixLQUFLO2dCQUlOLEtBQUs7c0JBREosS0FBSztnQkFJTixJQUFJO3NCQURILEtBQUs7Z0JBSU4sYUFBYTtzQkFEWixTQUFTO3VCQUFDLGlCQUFpQjtnQkFtaUI1QixXQUFXO3NCQUpWLFlBQVk7dUJBQ1gsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdGV4dC1lZGl0b3IuY29tcG9uZW50LnRzXHJcblxyXG5pbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBIb3N0TGlzdGVuZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFZpZXdDaGlsZCxcclxuICBQTEFURk9STV9JRCxcclxuICBpbmplY3QsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIFNpbXBsZUNoYW5nZXNcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7XHJcbiAgQ29tbW9uTW9kdWxlLFxyXG4gIGlzUGxhdGZvcm1Ccm93c2VyXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbmltcG9ydCB7XHJcbiAgRG9tU2FuaXRpemVyLFxyXG4gIFNhZmVIdG1sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcblxyXG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcclxuXHJcbmltcG9ydCB7IENka0RyYWcgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcclxuXHJcbmltcG9ydCB7IE1hdFNlbGVjdE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XHJcblxyXG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcclxuXHJcbmltcG9ydCB7IENvbnRlbnRlZGl0YWJsZVZhbHVlQWNjZXNzb3IgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmUvY29udGVudGVkaXRhYmxlLmRpcmVjdGl2ZSc7XHJcblxyXG5pbXBvcnQgeyBHcmFkaWVudEV4dGVuc2lvbiB9IGZyb20gJy4uLy4uL3N0eWxlcy9ncmFkaWVudC1leHRlbnNpb24nO1xyXG5cclxuaW1wb3J0IHsgRm9udFNpemUgfSBmcm9tICcuLi8uLi9zdHlsZXMvdGV4dC1zaXplLmV4dGVuc2lvbic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3NpbXBvLXRleHQtZWRpdG9yJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG5cclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBGb3Jtc01vZHVsZSxcclxuICAgIE1hdEljb25Nb2R1bGUsXHJcbiAgICBDZGtEcmFnLFxyXG4gICAgTWF0U2VsZWN0TW9kdWxlLFxyXG4gICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxyXG4gICAgQ29udGVudGVkaXRhYmxlVmFsdWVBY2Nlc3NvclxyXG4gIF0sXHJcblxyXG4gIHRlbXBsYXRlVXJsOiAnLi90ZXh0LWVkaXRvci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vdGV4dC1lZGl0b3IuY29tcG9uZW50LmNzcyddXHJcbn0pXHJcblxyXG5leHBvcnQgY2xhc3MgVGV4dEVkaXRvckNvbXBvbmVudFxyXG4gIGltcGxlbWVudHNcclxuICBPbkRlc3Ryb3ksXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBPbkNoYW5nZXMge1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHZhbHVlOiBzdHJpbmcgPVxyXG4gICAgJzxwPkhlbGxvIHRoaXMgaXMgcGFsYXNoIG1ha2hpamE8L3A+JztcclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgdmFsdWVDaGFuZ2UgPVxyXG4gICAgbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgZWRpdGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KClcclxuICBzZWN0aW9uSWQ/OiBzdHJpbmc7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgbGFiZWw/OiBzdHJpbmc7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgdHlwZT86IHN0cmluZztcclxuXHJcbiAgQFZpZXdDaGlsZCgnZWRpdG9yQ29udGFpbmVyJylcclxuICBlZGl0b3JFbGVtZW50ITogRWxlbWVudFJlZjtcclxuXHJcbiAgcHJpdmF0ZSBwbGF0Zm9ybUlkID1cclxuICAgIGluamVjdChQTEFURk9STV9JRCk7XHJcblxyXG4gIHByaXZhdGUgc2FuaXRpemVyID1cclxuICAgIGluamVjdChEb21TYW5pdGl6ZXIpO1xyXG5cclxuICBlZGl0b3I6IGFueTtcclxuXHJcbiAgc2FmZUh0bWwhOiBTYWZlSHRtbDtcclxuXHJcbiAgc2VsZWN0ZWRGb250U2l6ZSA9ICcnO1xyXG5cclxuICBzaG93VG9vbGJhciA9IGZhbHNlO1xyXG5cclxuICB0b29sYmFyWCA9IDA7XHJcblxyXG4gIHRvb2xiYXJZID0gMTAwO1xyXG5cclxuICBzZWxlY3RlZENvbG9yID0gJyMwMDAwMDAnO1xyXG5cclxuICBwcmltYXJ5Q29sb3IgPSAnIzAwMDAwMCc7XHJcblxyXG4gIHNlY29uZGFyeUNvbG9yID0gJyNmZjAwMDAnO1xyXG5cclxuICBpc0NvbG9yUGlja2VyT3BlbiA9IGZhbHNlO1xyXG5cclxuICBzZWxlY3RlZENvbG9yVHlwZTpcclxuICAgICdTT0xJRCcgfCAnR1JBRElFTlQnID0gJ1NPTElEJztcclxuXHJcbiAgc2F2ZWRTZWxlY3Rpb246IGFueSA9IG51bGw7XHJcblxyXG4gIGlzRm9udFNpemVNZW51T3BlbiA9IGZhbHNlO1xyXG5cclxuICB0b29sYmFyRGF0YTogYW55ID0ge1xyXG4gICAgc2VsZWN0ZWRTaXplOiAnJ1xyXG4gIH07XHJcblxyXG4gIGFzeW5jIG5nQWZ0ZXJWaWV3SW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZVNhZmVIdG1sKCk7XHJcblxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmVkaXRhYmxlICYmXHJcbiAgICAgIGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZClcclxuICAgICkge1xyXG5cclxuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplRWRpdG9yKCk7XHJcblxyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKFxyXG4gICAgY2hhbmdlczogU2ltcGxlQ2hhbmdlc1xyXG4gICk6IHZvaWQge1xyXG5cclxuICAgIGlmIChjaGFuZ2VzWyd2YWx1ZSddKSB7XHJcblxyXG4gICAgICB0aGlzLnVwZGF0ZVNhZmVIdG1sKCk7XHJcblxyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG5cclxuICAgIGlmIChcclxuICAgICAgdGhpcy5lZGl0b3IgJiZcclxuICAgICAgaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKVxyXG4gICAgKSB7XHJcblxyXG4gICAgICB0aGlzLmVkaXRvci5kZXN0cm95KCk7XHJcblxyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIHVwZGF0ZVNhZmVIdG1sKCk6IHZvaWQge1xyXG5cclxuICAgIHRoaXMuc2FmZUh0bWwgPVxyXG4gICAgICB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChcclxuICAgICAgICB0aGlzLnZhbHVlIHx8ICcnXHJcbiAgICAgICk7XHJcblxyXG4gIH1cclxuXHJcbiAgYXN5bmMgaW5pdGlhbGl6ZUVkaXRvcigpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHJcbiAgICBpZiAoIXRoaXMuZWRpdG9yRWxlbWVudClcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IHsgRWRpdG9yIH0gPVxyXG4gICAgICBhd2FpdCBpbXBvcnQoJ0B0aXB0YXAvY29yZScpO1xyXG5cclxuICAgIGNvbnN0IFN0YXJ0ZXJLaXQgPVxyXG4gICAgICAoYXdhaXQgaW1wb3J0KCdAdGlwdGFwL3N0YXJ0ZXIta2l0JykpLmRlZmF1bHQ7XHJcblxyXG4gICAgY29uc3QgVGV4dFN0eWxlID1cclxuICAgICAgKGF3YWl0IGltcG9ydCgnQHRpcHRhcC9leHRlbnNpb24tdGV4dC1zdHlsZScpKVxyXG4gICAgICAgIC5UZXh0U3R5bGU7XHJcblxyXG4gICAgY29uc3QgQ29sb3IgPVxyXG4gICAgICAoYXdhaXQgaW1wb3J0KCdAdGlwdGFwL2V4dGVuc2lvbi1jb2xvcicpKVxyXG4gICAgICAgIC5kZWZhdWx0O1xyXG5cclxuICAgIGNvbnN0IFVuZGVybGluZSA9XHJcbiAgICAgIChhd2FpdCBpbXBvcnQoJ0B0aXB0YXAvZXh0ZW5zaW9uLXVuZGVybGluZScpKVxyXG4gICAgICAgIC5kZWZhdWx0O1xyXG5cclxuICAgIGNvbnN0IFRleHRBbGlnbiA9XHJcbiAgICAgIChhd2FpdCBpbXBvcnQoJ0B0aXB0YXAvZXh0ZW5zaW9uLXRleHQtYWxpZ24nKSlcclxuICAgICAgICAuZGVmYXVsdDtcclxuXHJcbiAgICB0aGlzLmVkaXRvciA9IG5ldyBFZGl0b3Ioe1xyXG5cclxuICAgICAgZWxlbWVudDpcclxuICAgICAgICB0aGlzLmVkaXRvckVsZW1lbnQubmF0aXZlRWxlbWVudCxcclxuXHJcbiAgICAgIGVkaXRvclByb3BzOiB7XHJcblxyXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgIGNsYXNzOiAnUHJvc2VNaXJyb3InXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfSxcclxuXHJcbiAgICAgIGV4dGVuc2lvbnM6IFtcclxuXHJcbiAgICAgICAgU3RhcnRlcktpdCxcclxuXHJcbiAgICAgICAgVGV4dFN0eWxlLFxyXG5cclxuICAgICAgICBGb250U2l6ZSxcclxuXHJcbiAgICAgICAgQ29sb3IsXHJcblxyXG4gICAgICAgIEdyYWRpZW50RXh0ZW5zaW9uLFxyXG5cclxuICAgICAgICBVbmRlcmxpbmUsXHJcblxyXG4gICAgICAgIFRleHRBbGlnbi5jb25maWd1cmUoe1xyXG4gICAgICAgICAgdHlwZXM6IFtcclxuICAgICAgICAgICAgJ2hlYWRpbmcnLFxyXG4gICAgICAgICAgICAncGFyYWdyYXBoJyxcclxuICAgICAgICAgICAgJ2xpc3RJdGVtJ1xyXG4gICAgICAgICAgXSxcclxuICAgICAgICB9KSxcclxuXHJcbiAgICAgIF0sXHJcblxyXG4gICAgICBjb250ZW50OiB0aGlzLnZhbHVlLFxyXG5cclxuICAgICAgb25TZWxlY3Rpb25VcGRhdGU6ICgpID0+IHtcclxuXHJcbiAgICAgICAgdGhpcy5oYW5kbGVTZWxlY3Rpb24oKTtcclxuXHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBvblVwZGF0ZTogKHsgZWRpdG9yIH06IGFueSkgPT4ge1xyXG5cclxuICAgICAgICBjb25zdCBodG1sID1cclxuICAgICAgICAgIGVkaXRvci5nZXRIVE1MKCk7XHJcblxyXG4gICAgICAgIHRoaXMudmFsdWUgPSBodG1sO1xyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZVNhZmVIdG1sKCk7XHJcblxyXG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdChodG1sKTtcclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVFbXB0eUVkaXRvckNsYXNzKCk7XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy51cGRhdGVFbXB0eUVkaXRvckNsYXNzKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgdXBkYXRlRW1wdHlFZGl0b3JDbGFzcygpOiB2b2lkIHtcclxuXHJcbiAgICBpZiAoIXRoaXMuZWRpdG9yRWxlbWVudClcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGVkaXRvcldyYXBwZXIgPVxyXG4gICAgICB0aGlzLmVkaXRvckVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgICAgIC5jbG9zZXN0KCcuZWRpdGFibGUtdGV4dCcpO1xyXG5cclxuICAgIGlmICghZWRpdG9yV3JhcHBlcilcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGlmICh0aGlzLmVkaXRvcj8uaXNFbXB0eSkge1xyXG5cclxuICAgICAgZWRpdG9yV3JhcHBlci5jbGFzc0xpc3QuYWRkKFxyXG4gICAgICAgICdlZGl0b3ItZW1wdHknXHJcbiAgICAgICk7XHJcblxyXG4gICAgfSBlbHNlIHtcclxuXHJcbiAgICAgIGVkaXRvcldyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZShcclxuICAgICAgICAnZWRpdG9yLWVtcHR5J1xyXG4gICAgICApO1xyXG5cclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBzYXZlU2VsZWN0aW9uKCk6IHZvaWQge1xyXG5cclxuICAgIHRoaXMuc2F2ZWRTZWxlY3Rpb24gPVxyXG4gICAgICB0aGlzLmVkaXRvci5zdGF0ZS5zZWxlY3Rpb247XHJcblxyXG4gIH1cclxuXHJcbiAgcmVzdG9yZVNlbGVjdGlvbigpOiB2b2lkIHtcclxuXHJcbiAgICBpZiAoIXRoaXMuc2F2ZWRTZWxlY3Rpb24pXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICB0aGlzLmVkaXRvclxyXG4gICAgICAuY2hhaW4oKVxyXG4gICAgICAuZm9jdXMoKVxyXG4gICAgICAuc2V0VGV4dFNlbGVjdGlvbihcclxuICAgICAgICB0aGlzLnNhdmVkU2VsZWN0aW9uXHJcbiAgICAgIClcclxuICAgICAgLnJ1bigpO1xyXG5cclxuICB9XHJcblxyXG4gIHN3aXRjaFRvU29saWQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XHJcblxyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICB0aGlzLnNhdmVTZWxlY3Rpb24oKTtcclxuXHJcbiAgICB0aGlzLnNlbGVjdGVkQ29sb3JUeXBlID0gJ1NPTElEJztcclxuXHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHJcbiAgICAgIHRoaXMucmVzdG9yZVNlbGVjdGlvbigpO1xyXG5cclxuICAgICAgdGhpcy5zaG93VG9vbGJhciA9IHRydWU7XHJcblxyXG4gICAgfSk7XHJcblxyXG4gIH1cclxuXHJcbiAgc3dpdGNoVG9HcmFkaWVudChldmVudDogRXZlbnQpOiB2b2lkIHtcclxuXHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgIHRoaXMuc2F2ZVNlbGVjdGlvbigpO1xyXG5cclxuICAgIHRoaXMuc2VsZWN0ZWRDb2xvclR5cGUgPSAnR1JBRElFTlQnO1xyXG5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cclxuICAgICAgdGhpcy5yZXN0b3JlU2VsZWN0aW9uKCk7XHJcblxyXG4gICAgICB0aGlzLnNob3dUb29sYmFyID0gdHJ1ZTtcclxuXHJcbiAgICB9KTtcclxuXHJcbiAgfVxyXG5cclxuICBvcGVuQ29sb3JQaWNrZXIoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5pc0NvbG9yUGlja2VyT3BlbiA9IHRydWU7XHJcblxyXG4gICAgdGhpcy5zYXZlU2VsZWN0aW9uKCk7XHJcblxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcblxyXG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgICAnZm9jdXMnLFxyXG4gICAgICAgIHRoaXMuaGFuZGxlV2luZG93Rm9jdXMsXHJcbiAgICAgICAgeyBvbmNlOiB0cnVlIH1cclxuICAgICAgKTtcclxuXHJcbiAgICB9KTtcclxuXHJcbiAgfVxyXG5cclxuICBoYW5kbGVXaW5kb3dGb2N1cyA9ICgpOiB2b2lkID0+IHtcclxuXHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHJcbiAgICAgIHRoaXMuaXNDb2xvclBpY2tlck9wZW4gPSBmYWxzZTtcclxuXHJcbiAgICB9LCAzMDApO1xyXG5cclxuICB9XHJcblxyXG4gIGhhbmRsZVNlbGVjdGlvbigpOiB2b2lkIHtcclxuXHJcbiAgICBjb25zdCB7IGZyb20sIHRvIH0gPVxyXG4gICAgICB0aGlzLmVkaXRvci5zdGF0ZS5zZWxlY3Rpb247XHJcblxyXG4gICAgaWYgKGZyb20gPT09IHRvKSB7XHJcblxyXG4gICAgICBpZiAoIXRoaXMuaXNDb2xvclBpY2tlck9wZW4pIHtcclxuXHJcbiAgICAgICAgdGhpcy5zaG93VG9vbGJhciA9IGZhbHNlO1xyXG5cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBzZWxlY3Rpb24gPVxyXG4gICAgICB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcblxyXG4gICAgaWYgKFxyXG4gICAgICAhc2VsZWN0aW9uIHx8XHJcbiAgICAgIHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAwXHJcbiAgICApIHtcclxuXHJcbiAgICAgIHRoaXMuc2hvd1Rvb2xiYXIgPSBmYWxzZTtcclxuXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcmFuZ2UgPVxyXG4gICAgICBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcclxuXHJcbiAgICBjb25zdCByZWN0ID1cclxuICAgICAgcmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblxyXG4gICAgY29uc3QgZWRpdG9yUmVjdCA9XHJcbiAgICAgIHRoaXMuZWRpdG9yRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICAgICAgLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgIHRoaXMuc2hvd1Rvb2xiYXIgPSB0cnVlO1xyXG5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cclxuICAgICAgY29uc3QgdG9vbGJhciA9XHJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcclxuICAgICAgICAgICcudG9vbGJhcidcclxuICAgICAgICApIGFzIEhUTUxFbGVtZW50O1xyXG5cclxuICAgICAgaWYgKCF0b29sYmFyKVxyXG4gICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgIGNvbnN0IHRvb2xiYXJXaWR0aCA9XHJcbiAgICAgICAgdG9vbGJhci5vZmZzZXRXaWR0aDtcclxuXHJcbiAgICAgIGxldCBsZWZ0ID1cclxuICAgICAgICByZWN0LmxlZnQgLVxyXG4gICAgICAgIGVkaXRvclJlY3QubGVmdCArXHJcbiAgICAgICAgKHJlY3Qud2lkdGggLyAyKSAtXHJcbiAgICAgICAgKHRvb2xiYXJXaWR0aCAvIDIpO1xyXG5cclxuICAgICAgbGVmdCA9IE1hdGgubWF4KDEwLCBsZWZ0KTtcclxuXHJcbiAgICAgIGNvbnN0IG1heExlZnQgPVxyXG4gICAgICAgIGVkaXRvclJlY3Qud2lkdGggLVxyXG4gICAgICAgIHRvb2xiYXJXaWR0aCAtXHJcbiAgICAgICAgMTA7XHJcblxyXG4gICAgICBsZWZ0ID0gTWF0aC5taW4obGVmdCwgbWF4TGVmdCk7XHJcblxyXG4gICAgICBsZWZ0ID0gTWF0aC5tYXgoMTAsIGxlZnQpO1xyXG5cclxuICAgICAgdGhpcy50b29sYmFyWCA9IGxlZnQ7XHJcblxyXG4gICAgICB0aGlzLnRvb2xiYXJZID1cclxuICAgICAgICByZWN0LmJvdHRvbSAtXHJcbiAgICAgICAgZWRpdG9yUmVjdC50b3AgK1xyXG4gICAgICAgIDEwO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG4gIHRvZ2dsZUJvbGQoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5lZGl0b3JcclxuICAgICAgLmNoYWluKClcclxuICAgICAgLmZvY3VzKClcclxuICAgICAgLnRvZ2dsZUJvbGQoKVxyXG4gICAgICAucnVuKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgdG9nZ2xlSXRhbGljKCk6IHZvaWQge1xyXG5cclxuICAgIHRoaXMuZWRpdG9yXHJcbiAgICAgIC5jaGFpbigpXHJcbiAgICAgIC5mb2N1cygpXHJcbiAgICAgIC50b2dnbGVJdGFsaWMoKVxyXG4gICAgICAucnVuKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgdG9nZ2xlVW5kZXJsaW5lKCk6IHZvaWQge1xyXG5cclxuICAgIHRoaXMuZWRpdG9yXHJcbiAgICAgIC5jaGFpbigpXHJcbiAgICAgIC5mb2N1cygpXHJcbiAgICAgIC50b2dnbGVVbmRlcmxpbmUoKVxyXG4gICAgICAucnVuKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgdG9nZ2xlT3JkZXJlZExpc3QoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5lZGl0b3JcclxuICAgICAgLmNoYWluKClcclxuICAgICAgLmZvY3VzKClcclxuICAgICAgLnRvZ2dsZU9yZGVyZWRMaXN0KClcclxuICAgICAgLnJ1bigpO1xyXG5cclxuICB9XHJcblxyXG4gIHRvZ2dsZUJ1bGxldExpc3QoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5lZGl0b3JcclxuICAgICAgLmNoYWluKClcclxuICAgICAgLmZvY3VzKClcclxuICAgICAgLnRvZ2dsZUJ1bGxldExpc3QoKVxyXG4gICAgICAucnVuKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgc2V0QWxpZ24oXHJcbiAgICBhbGlnbm1lbnQ6XHJcbiAgICAgICdsZWZ0JyB8XHJcbiAgICAgICdjZW50ZXInIHxcclxuICAgICAgJ3JpZ2h0J1xyXG4gICk6IHZvaWQge1xyXG5cclxuICAgIHRoaXMuZWRpdG9yXHJcbiAgICAgIC5jaGFpbigpXHJcbiAgICAgIC5mb2N1cygpXHJcbiAgICAgIC5zZXRUZXh0QWxpZ24oYWxpZ25tZW50KVxyXG4gICAgICAucnVuKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgY2hhbmdlQ29sb3IoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5yZXN0b3JlU2VsZWN0aW9uKCk7XHJcblxyXG4gICAgY29uc3QgeyBmcm9tLCB0byB9ID1cclxuICAgICAgdGhpcy5lZGl0b3Iuc3RhdGUuc2VsZWN0aW9uO1xyXG5cclxuICAgIGlmIChmcm9tID09PSB0bylcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGV4aXN0aW5nU3R5bGVzID1cclxuICAgICAgdGhpcy5lZGl0b3IuZ2V0QXR0cmlidXRlcyhcclxuICAgICAgICAndGV4dFN0eWxlJ1xyXG4gICAgICApO1xyXG5cclxuICAgIHRoaXMuZWRpdG9yXHJcbiAgICAgIC5jaGFpbigpXHJcbiAgICAgIC5mb2N1cygpXHJcbiAgICAgIC5zZXRUZXh0U2VsZWN0aW9uKHtcclxuICAgICAgICBmcm9tLFxyXG4gICAgICAgIHRvXHJcbiAgICAgIH0pXHJcbiAgICAgIC5zZXRNYXJrKCd0ZXh0U3R5bGUnLCB7XHJcblxyXG4gICAgICAgIC4uLmV4aXN0aW5nU3R5bGVzLFxyXG5cclxuICAgICAgICBjb2xvcjpcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDb2xvcixcclxuXHJcbiAgICAgICAgYmFja2dyb3VuZEltYWdlOiBudWxsLFxyXG5cclxuICAgICAgICBXZWJraXRCYWNrZ3JvdW5kQ2xpcDogbnVsbCxcclxuXHJcbiAgICAgICAgV2Via2l0VGV4dEZpbGxDb2xvcjogbnVsbFxyXG5cclxuICAgICAgfSlcclxuICAgICAgLnJ1bigpO1xyXG5cclxuICB9XHJcblxyXG4gIGFwcGx5R3JhZGllbnQoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5yZXN0b3JlU2VsZWN0aW9uKCk7XHJcblxyXG4gICAgY29uc3QgeyBmcm9tLCB0byB9ID1cclxuICAgICAgdGhpcy5lZGl0b3Iuc3RhdGUuc2VsZWN0aW9uO1xyXG5cclxuICAgIGlmIChmcm9tID09PSB0bylcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGV4aXN0aW5nU3R5bGVzID1cclxuICAgICAgdGhpcy5lZGl0b3IuZ2V0QXR0cmlidXRlcyhcclxuICAgICAgICAndGV4dFN0eWxlJ1xyXG4gICAgICApO1xyXG5cclxuICAgIGNvbnN0IGdyYWRpZW50ID0gYFxyXG4gICAgICBsaW5lYXItZ3JhZGllbnQoXHJcbiAgICAgICAgdG8gcmlnaHQsXHJcbiAgICAgICAgJHt0aGlzLnByaW1hcnlDb2xvcn0sXHJcbiAgICAgICAgJHt0aGlzLnNlY29uZGFyeUNvbG9yfVxyXG4gICAgICApXHJcbiAgICBgO1xyXG5cclxuICAgIHRoaXMuZWRpdG9yXHJcbiAgICAgIC5jaGFpbigpXHJcbiAgICAgIC5mb2N1cygpXHJcbiAgICAgIC5zZXRUZXh0U2VsZWN0aW9uKHtcclxuICAgICAgICBmcm9tLFxyXG4gICAgICAgIHRvXHJcbiAgICAgIH0pXHJcbiAgICAgIC5zZXRNYXJrKCd0ZXh0U3R5bGUnLCB7XHJcblxyXG4gICAgICAgIC4uLmV4aXN0aW5nU3R5bGVzLFxyXG5cclxuICAgICAgICBiYWNrZ3JvdW5kSW1hZ2U6XHJcbiAgICAgICAgICBncmFkaWVudCxcclxuXHJcbiAgICAgICAgYmFja2dyb3VuZENsaXA6XHJcbiAgICAgICAgICAndGV4dCcsXHJcblxyXG4gICAgICAgIFdlYmtpdEJhY2tncm91bmRDbGlwOlxyXG4gICAgICAgICAgJ3RleHQnLFxyXG5cclxuICAgICAgICBjb2xvcjpcclxuICAgICAgICAgICd0cmFuc3BhcmVudCcsXHJcblxyXG4gICAgICAgIFdlYmtpdFRleHRGaWxsQ29sb3I6XHJcbiAgICAgICAgICAndHJhbnNwYXJlbnQnXHJcblxyXG4gICAgICB9KVxyXG4gICAgICAucnVuKCk7XHJcblxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcihcclxuICAgICdkb2N1bWVudDptb3VzZWRvd24nXHJcbiAgKVxyXG5cclxuICBvbk1vdXNlRG93bigpOiB2b2lkIHtcclxuXHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHJcbiAgICAgIGlmICghdGhpcy5lZGl0b3IpXHJcbiAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgY29uc3QgeyBmcm9tLCB0byB9ID1cclxuICAgICAgICB0aGlzLmVkaXRvci5zdGF0ZS5zZWxlY3Rpb247XHJcblxyXG4gICAgICB0aGlzLnNob3dUb29sYmFyID1cclxuICAgICAgICBmcm9tICE9PSB0bztcclxuXHJcbiAgICB9KTtcclxuXHJcbiAgfVxyXG5cclxuICBjaGFuZ2VGb250U2l6ZShcclxuICAgIGZvbnRTaXplOiBzdHJpbmdcclxuICApOiB2b2lkIHtcclxuXHJcbiAgICB0aGlzLnNlbGVjdGVkRm9udFNpemUgPVxyXG4gICAgICBmb250U2l6ZTtcclxuXHJcbiAgICBjb25zdCB7IGZyb20sIHRvIH0gPVxyXG4gICAgICB0aGlzLmVkaXRvci5zdGF0ZS5zZWxlY3Rpb247XHJcblxyXG4gICAgaWYgKGZyb20gPT09IHRvKVxyXG4gICAgICByZXR1cm47XHJcblxyXG4gICAgdGhpcy5lZGl0b3JcclxuICAgICAgLmNoYWluKClcclxuICAgICAgLmZvY3VzKClcclxuICAgICAgLnNldFRleHRTZWxlY3Rpb24oe1xyXG4gICAgICAgIGZyb20sXHJcbiAgICAgICAgdG9cclxuICAgICAgfSlcclxuICAgICAgLnNldE1hcmsoXHJcbiAgICAgICAgJ3RleHRTdHlsZScsXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgZm9udFNpemVcclxuICAgICAgICB9XHJcbiAgICAgIClcclxuICAgICAgLnJ1bigpO1xyXG5cclxuICB9XHJcblxyXG59IiwiPCEtLSB0ZXh0LWVkaXRvci5jb21wb25lbnQuaHRtbCAtLT5cclxuXHJcbjxkaXYgY2xhc3M9XCJlZGl0b3ItY29udGFpbmVyXCIgKm5nSWY9XCJlZGl0YWJsZTsgZWxzZSB2aWV3TW9kZVwiPlxyXG5cclxuICA8IS0tIEZMT0FUSU5HIFRPT0xCQVIgLS0+XHJcbiAgPGRpdiBjbGFzcz1cInRvb2xiYXJcIiAqbmdJZj1cInNob3dUb29sYmFyXCIgW3N0eWxlLnRvcC5weF09XCJ0b29sYmFyWVwiIFtzdHlsZS5sZWZ0LnB4XT1cInRvb2xiYXJYXCIgY2RrRHJhZz5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIGRyYWctaGFuZGxlIHctYXV0b1wiIGNka0RyYWdIYW5kbGU+XHJcbiAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiXHJcbiAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXHJcbiAgICAgICAgY2xhc3M9XCJsdWNpZGUgbHVjaWRlLWdyaXAtdmVydGljYWxcIj5cclxuICAgICAgICA8Y2lyY2xlIGN4PVwiOVwiIGN5PVwiMTJcIiByPVwiMVwiIC8+XHJcbiAgICAgICAgPGNpcmNsZSBjeD1cIjlcIiBjeT1cIjVcIiByPVwiMVwiIC8+XHJcbiAgICAgICAgPGNpcmNsZSBjeD1cIjlcIiBjeT1cIjE5XCIgcj1cIjFcIiAvPlxyXG4gICAgICAgIDxjaXJjbGUgY3g9XCIxNVwiIGN5PVwiMTJcIiByPVwiMVwiIC8+XHJcbiAgICAgICAgPGNpcmNsZSBjeD1cIjE1XCIgY3k9XCI1XCIgcj1cIjFcIiAvPlxyXG4gICAgICAgIDxjaXJjbGUgY3g9XCIxNVwiIGN5PVwiMTlcIiByPVwiMVwiIC8+XHJcbiAgICAgIDwvc3ZnPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cImZvbnQtc2l6ZS1maWVsZFwiPlxyXG5cclxuICAgICAgPG1hdC1zZWxlY3QgW3ZhbHVlXT1cInNlbGVjdGVkRm9udFNpemVcIiAoc2VsZWN0aW9uQ2hhbmdlKT1cImNoYW5nZUZvbnRTaXplKCRldmVudC52YWx1ZSlcIiBkaXNhYmxlT3B0aW9uQ2VudGVyaW5nPlxyXG5cclxuICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIlwiPlxyXG4gICAgICAgICAgRGVmYXVsdFxyXG4gICAgICAgIDwvbWF0LW9wdGlvbj5cclxuXHJcbiAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJjbGFtcCgwLjc1cmVtLCAydncsIDFyZW0pXCI+XHJcbiAgICAgICAgICAxNFxyXG4gICAgICAgIDwvbWF0LW9wdGlvbj5cclxuXHJcbiAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJjbGFtcCgwLjc1cmVtLCAydncsIDEuMjVyZW0pXCI+XHJcbiAgICAgICAgICAxNlxyXG4gICAgICAgIDwvbWF0LW9wdGlvbj5cclxuXHJcbiAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJjbGFtcCgxcmVtLCAzdncsIDEuNXJlbSlcIj5cclxuICAgICAgICAgIDIwXHJcbiAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG5cclxuICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cImNsYW1wKDEuMjVyZW0sIDR2dywgMnJlbSlcIj5cclxuICAgICAgICAgIDI0XHJcbiAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiY2xhbXAoMnJlbSwgNXZ3LCAzcmVtKVwiPlxyXG4gICAgICAgICAgMzJcclxuICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJjbGFtcCgzLjFyZW0sIDd2dywgNC41cmVtKVwiPlxyXG4gICAgICAgICAgNDhcclxuICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgIDwvbWF0LXNlbGVjdD5cclxuXHJcbiAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgPCEtLSBCT0xEIC0tPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cInRvb2wgdy1hdXRvXCIgW2NsYXNzLnNlbGVjdGVkVG9vbF09XCJlZGl0b3I/LmlzQWN0aXZlKCdib2xkJylcIiAoY2xpY2spPVwidG9nZ2xlQm9sZCgpXCI+XHJcbiAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiXHJcbiAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXHJcbiAgICAgICAgY2xhc3M9XCJsdWNpZGUgbHVjaWRlLWJvbGRcIj5cclxuICAgICAgICA8cGF0aCBkPVwiTTYgMTJoOWE0IDQgMCAwIDEgMCA4SDdhMSAxIDAgMCAxLTEtMVY1YTEgMSAwIDAgMSAxLTFoN2E0IDQgMCAwIDEgMCA4XCIgLz5cclxuICAgICAgPC9zdmc+XHJcbiAgICA8L2J1dHRvbj5cclxuXHJcbiAgICA8IS0tIElUQUxJQyAtLT5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIHctYXV0b1wiIFtjbGFzcy5zZWxlY3RlZFRvb2xdPVwiZWRpdG9yPy5pc0FjdGl2ZSgnaXRhbGljJylcIiAoY2xpY2spPVwidG9nZ2xlSXRhbGljKClcIj5cclxuXHJcbiAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiXHJcbiAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXHJcbiAgICAgICAgY2xhc3M9XCJsdWNpZGUgbHVjaWRlLWl0YWxpY1wiPlxyXG4gICAgICAgIDxsaW5lIHgxPVwiMTlcIiB4Mj1cIjEwXCIgeTE9XCI0XCIgeTI9XCI0XCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjE0XCIgeDI9XCI1XCIgeTE9XCIyMFwiIHkyPVwiMjBcIiAvPlxyXG4gICAgICAgIDxsaW5lIHgxPVwiMTVcIiB4Mj1cIjlcIiB5MT1cIjRcIiB5Mj1cIjIwXCIgLz5cclxuICAgICAgPC9zdmc+XHJcbiAgICA8L2J1dHRvbj5cclxuXHJcbiAgICA8IS0tIFVOREVSTElORSAtLT5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIHctYXV0b1wiIFtjbGFzcy5zZWxlY3RlZFRvb2xdPVwiZWRpdG9yPy5pc0FjdGl2ZSgndW5kZXJsaW5lJylcIiAoY2xpY2spPVwidG9nZ2xlVW5kZXJsaW5lKClcIj5cclxuICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjE4XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCJcclxuICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCJcclxuICAgICAgICBjbGFzcz1cImx1Y2lkZSBsdWNpZGUtdW5kZXJsaW5lXCI+XHJcbiAgICAgICAgPHBhdGggZD1cIk02IDR2NmE2IDYgMCAwIDAgMTIgMFY0XCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjRcIiB4Mj1cIjIwXCIgeTE9XCIyMFwiIHkyPVwiMjBcIiAvPlxyXG4gICAgICA8L3N2Zz5cclxuICAgIDwvYnV0dG9uPlxyXG5cclxuICAgIDwhLS0gQUxJR04gTEVGVCAtLT5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIHctYXV0b1wiIChjbGljayk9XCJzZXRBbGlnbignbGVmdCcpXCI+XHJcblxyXG4gICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE4XCIgaGVpZ2h0PVwiMThcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIlxyXG4gICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIlxyXG4gICAgICAgIGNsYXNzPVwibHVjaWRlIGx1Y2lkZS1hbGlnbi1sZWZ0XCI+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHgyPVwiM1wiIHkxPVwiNlwiIHkyPVwiNlwiIC8+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIxNVwiIHgyPVwiM1wiIHkxPVwiMTJcIiB5Mj1cIjEyXCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjE3XCIgeDI9XCIzXCIgeTE9XCIxOFwiIHkyPVwiMThcIiAvPlxyXG4gICAgICA8L3N2Zz5cclxuICAgIDwvYnV0dG9uPlxyXG5cclxuICAgIDwhLS0gQUxJR04gQ0VOVEVSIC0tPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cInRvb2wgdy1hdXRvXCIgKGNsaWNrKT1cInNldEFsaWduKCdjZW50ZXInKVwiPlxyXG5cclxuICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjE4XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCJcclxuICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCJcclxuICAgICAgICBjbGFzcz1cImx1Y2lkZSBsdWNpZGUtYWxpZ24tY2VudGVyXCI+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHgyPVwiM1wiIHkxPVwiNlwiIHkyPVwiNlwiIC8+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIxN1wiIHgyPVwiN1wiIHkxPVwiMTJcIiB5Mj1cIjEyXCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjE5XCIgeDI9XCI1XCIgeTE9XCIxOFwiIHkyPVwiMThcIiAvPlxyXG4gICAgICA8L3N2Zz5cclxuICAgIDwvYnV0dG9uPlxyXG5cclxuICAgIDwhLS0gQUxJR04gUklHSFQgLS0+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbCB3LWF1dG9cIiAoY2xpY2spPVwic2V0QWxpZ24oJ3JpZ2h0JylcIj5cclxuXHJcbiAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiXHJcbiAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXHJcbiAgICAgICAgY2xhc3M9XCJsdWNpZGUgbHVjaWRlLWFsaWduLXJpZ2h0XCI+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHgyPVwiM1wiIHkxPVwiNlwiIHkyPVwiNlwiIC8+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHgyPVwiOVwiIHkxPVwiMTJcIiB5Mj1cIjEyXCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjIxXCIgeDI9XCI3XCIgeTE9XCIxOFwiIHkyPVwiMThcIiAvPlxyXG4gICAgICA8L3N2Zz5cclxuICAgIDwvYnV0dG9uPlxyXG5cclxuICAgIDwhLS0gT1JERVJFRCBMSVNUIC0tPlxyXG4gICAgPGJ1dHRvbiBjbGFzcz1cInRvb2wgdy1hdXRvXCIgKGNsaWNrKT1cInRvZ2dsZU9yZGVyZWRMaXN0KClcIj5cclxuICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjE4XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCJcclxuICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCJcclxuICAgICAgICBjbGFzcz1cImx1Y2lkZSBsdWNpZGUtbGlzdC1vcmRlcmVkXCI+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIxMFwiIHgyPVwiMjFcIiB5MT1cIjZcIiB5Mj1cIjZcIiAvPlxyXG4gICAgICAgIDxsaW5lIHgxPVwiMTBcIiB4Mj1cIjIxXCIgeTE9XCIxMlwiIHkyPVwiMTJcIiAvPlxyXG4gICAgICAgIDxsaW5lIHgxPVwiMTBcIiB4Mj1cIjIxXCIgeTE9XCIxOFwiIHkyPVwiMThcIiAvPlxyXG4gICAgICAgIDxwYXRoIGQ9XCJNNCA2aDF2NFwiIC8+XHJcbiAgICAgICAgPHBhdGggZD1cIk00IDEwaDJcIiAvPlxyXG4gICAgICAgIDxwYXRoIGQ9XCJNNiAxOEg0YzAtMSAyLTIgMi0zcy0xLTEuNS0yLTFcIiAvPlxyXG4gICAgICA8L3N2Zz5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgPCEtLSBCVUxMRVQgTElTVCAtLT5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIHctYXV0b1wiIChjbGljayk9XCJ0b2dnbGVCdWxsZXRMaXN0KClcIj5cclxuXHJcbiAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiXHJcbiAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXHJcbiAgICAgICAgY2xhc3M9XCJsdWNpZGUgbHVjaWRlLWxpc3RcIj5cclxuICAgICAgICA8bGluZSB4MT1cIjhcIiB4Mj1cIjIxXCIgeTE9XCI2XCIgeTI9XCI2XCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjhcIiB4Mj1cIjIxXCIgeTE9XCIxMlwiIHkyPVwiMTJcIiAvPlxyXG4gICAgICAgIDxsaW5lIHgxPVwiOFwiIHgyPVwiMjFcIiB5MT1cIjE4XCIgeTI9XCIxOFwiIC8+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIzXCIgeDI9XCIzLjAxXCIgeTE9XCI2XCIgeTI9XCI2XCIgLz5cclxuICAgICAgICA8bGluZSB4MT1cIjNcIiB4Mj1cIjMuMDFcIiB5MT1cIjEyXCIgeTI9XCIxMlwiIC8+XHJcbiAgICAgICAgPGxpbmUgeDE9XCIzXCIgeDI9XCIzLjAxXCIgeTE9XCIxOFwiIHkyPVwiMThcIiAvPlxyXG4gICAgICA8L3N2Zz5cclxuICAgIDwvYnV0dG9uPlxyXG5cclxuICAgIDwhLS0gU09MSUQgLyBHUkFESUVOVCAtLT5cclxuICAgIDwhLS0gU09MSUQgLyBHUkFESUVOVCAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJjb2xvclR5cGVcIj5cclxuXHJcbiAgICAgIDxidXR0b24gY2xhc3M9XCJzb2xpZCB3LWF1dG9cIiBbY2xhc3Muc29saWRDb2xvclNlbGVjdGVkXT1cInNlbGVjdGVkQ29sb3JUeXBlID09PSAnU09MSUQnXCJcclxuICAgICAgICAobW91c2Vkb3duKT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCIgKGNsaWNrKT1cInN3aXRjaFRvU29saWQoJGV2ZW50KVwiPlxyXG4gICAgICAgIFNvbGlkXHJcbiAgICAgIDwvYnV0dG9uPlxyXG5cclxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImdyYWRpZW50IHctYXV0b1wiIFtjbGFzcy5ncmFkaWVudENvbG9yU2VsZWN0ZWRdPVwic2VsZWN0ZWRDb2xvclR5cGUgPT09ICdHUkFESUVOVCdcIlxyXG4gICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIiAoY2xpY2spPVwic3dpdGNoVG9HcmFkaWVudCgkZXZlbnQpXCI+XHJcbiAgICAgICAgR3JhZGllbnRcclxuICAgICAgPC9idXR0b24+XHJcblxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBTT0xJRCBDT0xPUiAtLT5cclxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sIGNvbG9yLXBpY2tlci1idG4gdy1hdXRvXCIgKm5nSWY9XCJzZWxlY3RlZENvbG9yVHlwZSA9PT0gJ1NPTElEJ1wiPlxyXG5cclxuICAgICAgPG1hdC1pY29uPmZvcm1hdF9jb2xvcl90ZXh0PC9tYXQtaWNvbj5cclxuXHJcbiAgICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiBjbGFzcz1cImhpZGRlbi1jb2xvci1waWNrZXJcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkQ29sb3JcIiAoY2xpY2spPVwib3BlbkNvbG9yUGlja2VyKClcIlxyXG4gICAgICAgIChpbnB1dCk9XCJjaGFuZ2VDb2xvcigpXCI+XHJcblxyXG4gICAgPC9idXR0b24+XHJcblxyXG4gICAgPCEtLSBHUkFESUVOVCAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJncmFkaWVudC1waWNrZXJcIiAqbmdJZj1cInNlbGVjdGVkQ29sb3JUeXBlID09PSAnR1JBRElFTlQnXCI+XHJcbiAgICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiBbKG5nTW9kZWwpXT1cInByaW1hcnlDb2xvclwiIChjbGljayk9XCJvcGVuQ29sb3JQaWNrZXIoKVwiIChpbnB1dCk9XCJhcHBseUdyYWRpZW50KClcIiAvPlxyXG5cclxuICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwic2Vjb25kYXJ5Q29sb3JcIiAoY2xpY2spPVwib3BlbkNvbG9yUGlja2VyKClcIiAoaW5wdXQpPVwiYXBwbHlHcmFkaWVudCgpXCIgLz5cclxuXHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gVElQVEFQIEVESVRPUiAtLT5cclxuICA8ZGl2ICNlZGl0b3JDb250YWluZXIgY2xhc3M9XCJlZGl0YWJsZS10ZXh0XCI+XHJcbiAgPC9kaXY+XHJcblxyXG48L2Rpdj5cclxuPG5nLXRlbXBsYXRlICN2aWV3TW9kZT5cclxuICA8ZGl2IGNsYXNzPVwicmVhZC1vbmx5LXRleHRcIiBbaW5uZXJIVE1MXT1cInZhbHVlXCI+XHJcbiAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+Il19