@skyux/text-editor 5.7.2 → 6.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/documentation.json +2 -2
  2. package/esm2020/index.mjs +15 -0
  3. package/esm2020/lib/modules/rich-text-display/rich-text-display.component.mjs +36 -0
  4. package/esm2020/lib/modules/rich-text-display/rich-text-display.module.mjs +18 -0
  5. package/esm2020/lib/modules/shared/forms-utility.mjs +10 -0
  6. package/esm2020/lib/modules/shared/sky-text-editor-resources.module.mjs +106 -0
  7. package/esm2020/lib/modules/text-editor/defaults/font-list-defaults.mjs +42 -0
  8. package/esm2020/lib/modules/text-editor/defaults/font-size-list-defaults.mjs +7 -0
  9. package/esm2020/lib/modules/text-editor/defaults/menu-defaults.mjs +5 -0
  10. package/esm2020/lib/modules/text-editor/defaults/style-state-defaults.mjs +15 -0
  11. package/esm2020/lib/modules/text-editor/defaults/toolbar-action-defaults.mjs +12 -0
  12. package/esm2020/lib/modules/text-editor/menubar/text-editor-menubar.component.mjs +191 -0
  13. package/esm2020/lib/modules/text-editor/services/text-editor-adapter.service.mjs +477 -0
  14. package/esm2020/lib/modules/text-editor/services/text-editor-selection.service.mjs +80 -0
  15. package/esm2020/lib/modules/text-editor/services/text-editor.service.mjs +61 -0
  16. package/esm2020/lib/modules/text-editor/services/text-sanitization.service.mjs +38 -0
  17. package/esm2020/lib/modules/text-editor/text-editor.component.mjs +322 -0
  18. package/esm2020/lib/modules/text-editor/text-editor.module.mjs +98 -0
  19. package/esm2020/lib/modules/text-editor/toolbar/text-editor-toolbar.component.mjs +179 -0
  20. package/esm2020/lib/modules/text-editor/types/editor-command.mjs +2 -0
  21. package/esm2020/lib/modules/text-editor/types/editor-setting.mjs +2 -0
  22. package/esm2020/lib/modules/text-editor/types/font-state.mjs +2 -0
  23. package/esm2020/lib/modules/text-editor/types/menu-type.mjs +2 -0
  24. package/esm2020/lib/modules/text-editor/types/style-state.mjs +2 -0
  25. package/esm2020/lib/modules/text-editor/types/text-editor-merge-field.mjs +2 -0
  26. package/esm2020/lib/modules/text-editor/types/toolbar-action-type.mjs +2 -0
  27. package/esm2020/lib/modules/text-editor/url-modal/text-editor-url-modal-context.mjs +6 -0
  28. package/esm2020/lib/modules/text-editor/url-modal/text-editor-url-modal-result.mjs +2 -0
  29. package/esm2020/lib/modules/text-editor/url-modal/text-editor-url-modal.component.mjs +117 -0
  30. package/esm2020/lib/modules/text-editor/url-modal/text-editor-url-target.mjs +9 -0
  31. package/esm2020/skyux-text-editor.mjs +5 -0
  32. package/fesm2015/{skyux-text-editor.js → skyux-text-editor.mjs} +45 -69
  33. package/fesm2015/skyux-text-editor.mjs.map +1 -0
  34. package/fesm2020/skyux-text-editor.mjs +1743 -0
  35. package/fesm2020/skyux-text-editor.mjs.map +1 -0
  36. package/package.json +38 -22
  37. package/bundles/skyux-text-editor.umd.js +0 -2195
  38. package/esm2015/index.js +0 -15
  39. package/esm2015/index.js.map +0 -1
  40. package/esm2015/lib/modules/rich-text-display/rich-text-display.component.js +0 -39
  41. package/esm2015/lib/modules/rich-text-display/rich-text-display.component.js.map +0 -1
  42. package/esm2015/lib/modules/rich-text-display/rich-text-display.module.js +0 -18
  43. package/esm2015/lib/modules/rich-text-display/rich-text-display.module.js.map +0 -1
  44. package/esm2015/lib/modules/shared/forms-utility.js +0 -10
  45. package/esm2015/lib/modules/shared/forms-utility.js.map +0 -1
  46. package/esm2015/lib/modules/shared/sky-text-editor-resources.module.js +0 -106
  47. package/esm2015/lib/modules/shared/sky-text-editor-resources.module.js.map +0 -1
  48. package/esm2015/lib/modules/text-editor/defaults/font-list-defaults.js +0 -42
  49. package/esm2015/lib/modules/text-editor/defaults/font-list-defaults.js.map +0 -1
  50. package/esm2015/lib/modules/text-editor/defaults/font-size-list-defaults.js +0 -7
  51. package/esm2015/lib/modules/text-editor/defaults/font-size-list-defaults.js.map +0 -1
  52. package/esm2015/lib/modules/text-editor/defaults/menu-defaults.js +0 -5
  53. package/esm2015/lib/modules/text-editor/defaults/menu-defaults.js.map +0 -1
  54. package/esm2015/lib/modules/text-editor/defaults/style-state-defaults.js +0 -15
  55. package/esm2015/lib/modules/text-editor/defaults/style-state-defaults.js.map +0 -1
  56. package/esm2015/lib/modules/text-editor/defaults/toolbar-action-defaults.js +0 -12
  57. package/esm2015/lib/modules/text-editor/defaults/toolbar-action-defaults.js.map +0 -1
  58. package/esm2015/lib/modules/text-editor/menubar/text-editor-menubar.component.js +0 -196
  59. package/esm2015/lib/modules/text-editor/menubar/text-editor-menubar.component.js.map +0 -1
  60. package/esm2015/lib/modules/text-editor/services/text-editor-adapter.service.js +0 -474
  61. package/esm2015/lib/modules/text-editor/services/text-editor-adapter.service.js.map +0 -1
  62. package/esm2015/lib/modules/text-editor/services/text-editor-selection.service.js +0 -80
  63. package/esm2015/lib/modules/text-editor/services/text-editor-selection.service.js.map +0 -1
  64. package/esm2015/lib/modules/text-editor/services/text-editor.service.js +0 -61
  65. package/esm2015/lib/modules/text-editor/services/text-editor.service.js.map +0 -1
  66. package/esm2015/lib/modules/text-editor/services/text-sanitization.service.js +0 -38
  67. package/esm2015/lib/modules/text-editor/services/text-sanitization.service.js.map +0 -1
  68. package/esm2015/lib/modules/text-editor/text-editor.component.js +0 -322
  69. package/esm2015/lib/modules/text-editor/text-editor.component.js.map +0 -1
  70. package/esm2015/lib/modules/text-editor/text-editor.module.js +0 -99
  71. package/esm2015/lib/modules/text-editor/text-editor.module.js.map +0 -1
  72. package/esm2015/lib/modules/text-editor/toolbar/text-editor-toolbar.component.js +0 -175
  73. package/esm2015/lib/modules/text-editor/toolbar/text-editor-toolbar.component.js.map +0 -1
  74. package/esm2015/lib/modules/text-editor/types/editor-command.js +0 -2
  75. package/esm2015/lib/modules/text-editor/types/editor-command.js.map +0 -1
  76. package/esm2015/lib/modules/text-editor/types/editor-setting.js +0 -2
  77. package/esm2015/lib/modules/text-editor/types/editor-setting.js.map +0 -1
  78. package/esm2015/lib/modules/text-editor/types/font-state.js +0 -2
  79. package/esm2015/lib/modules/text-editor/types/font-state.js.map +0 -1
  80. package/esm2015/lib/modules/text-editor/types/menu-type.js +0 -2
  81. package/esm2015/lib/modules/text-editor/types/menu-type.js.map +0 -1
  82. package/esm2015/lib/modules/text-editor/types/style-state.js +0 -2
  83. package/esm2015/lib/modules/text-editor/types/style-state.js.map +0 -1
  84. package/esm2015/lib/modules/text-editor/types/text-editor-merge-field.js +0 -2
  85. package/esm2015/lib/modules/text-editor/types/text-editor-merge-field.js.map +0 -1
  86. package/esm2015/lib/modules/text-editor/types/toolbar-action-type.js +0 -2
  87. package/esm2015/lib/modules/text-editor/types/toolbar-action-type.js.map +0 -1
  88. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-context.js +0 -6
  89. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-context.js.map +0 -1
  90. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-result.js +0 -2
  91. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-result.js.map +0 -1
  92. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal.component.js +0 -121
  93. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal.component.js.map +0 -1
  94. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-target.js +0 -9
  95. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-target.js.map +0 -1
  96. package/esm2015/skyux-text-editor.js +0 -5
  97. package/esm2015/skyux-text-editor.js.map +0 -1
  98. package/fesm2015/skyux-text-editor.js.map +0 -1
@@ -0,0 +1,477 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { SkyAppWindowRef } from '@skyux/core';
3
+ import { Subject } from 'rxjs';
4
+ import { STYLE_STATE_DEFAULTS } from '../defaults/style-state-defaults';
5
+ import { UrlTarget } from '../url-modal/text-editor-url-target';
6
+ import { SkyTextEditorSelectionService } from './text-editor-selection.service';
7
+ import { SkyTextEditorService } from './text-editor.service';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "./text-editor-selection.service";
10
+ import * as i2 from "./text-editor.service";
11
+ import * as i3 from "@skyux/core";
12
+ /**
13
+ * @internal
14
+ */
15
+ export class SkyTextEditorAdapterService {
16
+ constructor(selectionService, textEditorService, windowService) {
17
+ this.selectionService = selectionService;
18
+ this.textEditorService = textEditorService;
19
+ this.windowService = windowService;
20
+ }
21
+ get editors() {
22
+ return this.textEditorService.editors;
23
+ }
24
+ /**
25
+ * Creates a text editor inside the supplied iframe element.
26
+ */
27
+ addEditor(id, iframeElement, styleState, placeholder) {
28
+ /* istanbul ignore else */
29
+ if (!(id in this.editors)) {
30
+ this.editors[id] = this.createObservers(id, iframeElement);
31
+ const documentEl = this.getIframeDocumentEl(id);
32
+ const styleEl = documentEl.createElement('style');
33
+ styleEl.innerHTML = `.editor:empty:before {
34
+ content: attr(data-placeholder);
35
+ font-family: "Blackbaud Sans", Arial, sans-serif;
36
+ color: #686c73;
37
+ font-weight: 400;
38
+ font-size: 15px;
39
+ font-style: italic;
40
+ }`;
41
+ documentEl.head.appendChild(styleEl);
42
+ const style = {
43
+ ...STYLE_STATE_DEFAULTS,
44
+ ...styleState,
45
+ };
46
+ const bodyStyle = `background-color: ${style.backColor};
47
+ color: ${style.fontColor};
48
+ font-family: ${style.font};
49
+ font-size: ${style.fontSize}px`;
50
+ documentEl.querySelector('html').setAttribute('lang', 'en');
51
+ documentEl.body.setAttribute('contenteditable', 'true');
52
+ documentEl.body.setAttribute('id', id);
53
+ documentEl.body.setAttribute('role', 'main');
54
+ documentEl.body.setAttribute('class', 'editor');
55
+ documentEl.body.setAttribute('style', bodyStyle);
56
+ documentEl.body.setAttribute('data-placeholder', placeholder || '');
57
+ }
58
+ }
59
+ disableEditor(id, focusableChildren, textEditorNativeElement) {
60
+ this.setEditorDisabled(id, focusableChildren, textEditorNativeElement, true);
61
+ }
62
+ enableEditor(id, focusableChildren, textEditorNativeElement) {
63
+ this.setEditorDisabled(id, focusableChildren, textEditorNativeElement, false);
64
+ }
65
+ /**
66
+ * Executes a command on the text editor with the corresponding id.
67
+ */
68
+ execCommand(id, editorCommand) {
69
+ /* istanbul ignore else */
70
+ if (id in this.editors) {
71
+ const documentEl = this.getIframeDocumentEl(id);
72
+ /* istanbul ignore else */
73
+ if (this.editorSelected(id)) {
74
+ const commandIsSupportedAndEnabled = documentEl.execCommand(editorCommand.command, false, editorCommand.value);
75
+ // IE11 doesn't support insertHTML
76
+ /* istanbul ignore next */
77
+ if (editorCommand.command.toLowerCase() === 'inserthtml' &&
78
+ !commandIsSupportedAndEnabled) {
79
+ this.insertHtmlInIE11(id, editorCommand.value);
80
+ }
81
+ this.focusEditor(id);
82
+ this.editors[id].commandChangeObservable.next();
83
+ }
84
+ }
85
+ }
86
+ getCurrentSelection(id) {
87
+ return this.selectionService.getCurrentSelection(this.getIframeDocumentEl(id));
88
+ }
89
+ /**
90
+ * Returns a data URI using the provided text string.
91
+ * Used to display a merge field inside a string of text.
92
+ */
93
+ getMergeFieldDataURI(text) {
94
+ const documentEl = this.windowService.nativeWindow.document;
95
+ let textToUse = text;
96
+ if (text.length > 18) {
97
+ textToUse = text.substr(0, 15) + '...';
98
+ }
99
+ const canvasElement = documentEl.createElement('canvas');
100
+ canvasElement.setAttribute('height', '20');
101
+ canvasElement.setAttribute('width', '100');
102
+ canvasElement.style.backgroundColor = 'tan';
103
+ canvasElement.style.border = '1px solid #000000';
104
+ canvasElement.style.borderRadius = '5px';
105
+ const context = canvasElement.getContext('2d');
106
+ context.font = '12px Arial';
107
+ context.textAlign = 'center';
108
+ context.fillText(textToUse, 50, 15);
109
+ context.globalCompositeOperation = 'destination-over';
110
+ context.fillStyle = '#00FFFF';
111
+ context.fillRect(0, 0, 100, 20);
112
+ context.globalCompositeOperation = 'source-over';
113
+ context.lineWidth = 2;
114
+ context.strokeStyle = '#FF0000';
115
+ context.strokeRect(0, 0, 100, 20);
116
+ const result = canvasElement.toDataURL('image/png', 1.0);
117
+ return result;
118
+ }
119
+ getStyleState(id) {
120
+ const documentEl = this.getIframeDocumentEl(id);
121
+ /* istanbul ignore else */
122
+ if (this.editorSelected(id)) {
123
+ return {
124
+ backColor: this.getColor(documentEl, 'BackColor'),
125
+ fontColor: this.getColor(documentEl, 'ForeColor'),
126
+ fontSize: parseInt(this.getFontSize(id), undefined),
127
+ font: documentEl.queryCommandValue('fontname'),
128
+ boldState: documentEl.queryCommandState('Bold'),
129
+ italicState: documentEl.queryCommandState('Italic'),
130
+ underlineState: documentEl.queryCommandState('Underline'),
131
+ linkState: this.hasLink(id),
132
+ };
133
+ }
134
+ /* istanbul ignore next */
135
+ return {};
136
+ }
137
+ getEditorInnerHtml(id) {
138
+ const documentEl = this.getIframeDocumentEl(id);
139
+ if (documentEl) {
140
+ return this.replaceHtmlCodes(documentEl.body.innerHTML);
141
+ }
142
+ return '';
143
+ }
144
+ setEditorInnerHtml(id, value) {
145
+ const documentEl = this.getIframeDocumentEl(id);
146
+ const editorContent = documentEl.body;
147
+ /* istanbul ignore else */
148
+ if (editorContent.innerHTML !== value) {
149
+ editorContent.innerHTML = value;
150
+ }
151
+ }
152
+ focusEditor(id) {
153
+ /* istanbul ignore else */
154
+ if (id in this.editors) {
155
+ const windowEl = this.getContentWindowEl(id);
156
+ const iframeDocumentEl = this.getIframeDocumentEl(id);
157
+ const currentSelection = this.selectionService.getCurrentSelectionRange(iframeDocumentEl, windowEl);
158
+ const cursorIsNotActiveAndHasReset = currentSelection &&
159
+ currentSelection.startOffset === 0 &&
160
+ currentSelection.endOffset === 0;
161
+ if (!this.editorSelected(id) || cursorIsNotActiveAndHasReset) {
162
+ // focus the end of the editor
163
+ const documentEl = this.windowService.nativeWindow.document;
164
+ const editor = iframeDocumentEl.body;
165
+ const range = documentEl.createRange();
166
+ this.editors[id].iframeElementRef.focus();
167
+ editor.focus();
168
+ /* istanbul ignore else */
169
+ if (windowEl.getSelection && documentEl.createRange) {
170
+ range.selectNodeContents(editor);
171
+ range.collapse(false);
172
+ const sel = windowEl.getSelection();
173
+ sel.removeAllRanges();
174
+ sel.addRange(range);
175
+ }
176
+ else {
177
+ // IE only
178
+ const textRange = editor.createTextRange();
179
+ textRange.moveToElementText(editor);
180
+ textRange.collapse(false);
181
+ textRange.select();
182
+ }
183
+ }
184
+ else {
185
+ // Cursor may not be active, restore it
186
+ this.editors[id].iframeElementRef.focus();
187
+ iframeDocumentEl.body.focus();
188
+ }
189
+ }
190
+ }
191
+ getLink(editorId) {
192
+ let link = undefined;
193
+ const anchorEl = this.getSelectedAnchorTag(editorId);
194
+ if (anchorEl && anchorEl.href) {
195
+ link = {
196
+ target: anchorEl.getAttribute('target') === '_blank'
197
+ ? UrlTarget.NewWindow
198
+ : UrlTarget.None,
199
+ url: anchorEl.href,
200
+ };
201
+ }
202
+ return link;
203
+ }
204
+ getSelectedAnchorTag(editorId) {
205
+ const selectedEl = this.getCurrentSelectionParentElement(editorId);
206
+ return this.getParent(selectedEl, 'a');
207
+ }
208
+ saveSelection(id) {
209
+ return this.selectionService.getCurrentSelectionRange(this.getIframeDocumentEl(id), this.getContentWindowEl(id));
210
+ }
211
+ selectElement(id, element) {
212
+ this.selectionService.selectElement(this.getIframeDocumentEl(id), this.getContentWindowEl(id), element);
213
+ }
214
+ setPlaceholder(id, placeholder) {
215
+ const documentEl = this.getIframeDocumentEl(id);
216
+ documentEl.body.setAttribute('data-placeholder', placeholder || '');
217
+ }
218
+ setFontSize(id, fontSize) {
219
+ const doc = this.getIframeDocumentEl(id);
220
+ this.execCommand(id, { command: 'fontSize', value: 1 });
221
+ const fontElements = Array.from(doc.querySelectorAll('font[size="1"]'));
222
+ for (const element of fontElements) {
223
+ element.removeAttribute('size');
224
+ element.style.fontSize = fontSize + 'px';
225
+ }
226
+ this.cleanUpBlankStyleTags(doc);
227
+ this.focusEditor(id);
228
+ this.editors[id].commandChangeObservable.next();
229
+ }
230
+ removeObservers(setting) {
231
+ /* istanbul ignore next */
232
+ const documentEl = setting.iframeElementRef.contentWindow
233
+ ? setting.iframeElementRef.contentWindow.document
234
+ : setting.iframeElementRef.contentDocument;
235
+ setting.selectionChangeObservable.complete();
236
+ setting.clickObservable.complete();
237
+ setting.commandChangeObservable.complete();
238
+ documentEl.removeEventListener('selectionchange', setting.selectionListener);
239
+ documentEl.removeEventListener('input', setting.selectionListener);
240
+ documentEl.removeEventListener('mousedown', setting.clickListener);
241
+ documentEl.body.removeEventListener('paste', setting.pasteListener);
242
+ }
243
+ getContentWindowEl(id) {
244
+ return this.editors[id].iframeElementRef.contentWindow;
245
+ }
246
+ getChildSelectedAnchorTags(editorId) {
247
+ const selectedRange = this.getCurrentSelection(editorId).getRangeAt(0);
248
+ if (selectedRange.toString().length <= 0) {
249
+ return [];
250
+ }
251
+ const parentElement = this.getCurrentSelectionParentElement(editorId);
252
+ let childElements = [];
253
+ /* istanbul ignore else */
254
+ if (parentElement) {
255
+ childElements = Array.from(parentElement.querySelectorAll('a'));
256
+ }
257
+ /* istanbul ignore next */
258
+ return childElements.filter((element) => {
259
+ // IE specific
260
+ if (!selectedRange.intersectsNode) {
261
+ if (!element || !element.href) {
262
+ return false;
263
+ }
264
+ const tempRange = document.createRange();
265
+ tempRange.selectNodeContents(element);
266
+ return ((selectedRange.compareBoundaryPoints(Range.START_TO_START, tempRange) !== -1 &&
267
+ selectedRange.compareBoundaryPoints(Range.START_TO_END, tempRange) !== 1) ||
268
+ (selectedRange.compareBoundaryPoints(Range.END_TO_START, tempRange) !== -1 &&
269
+ selectedRange.compareBoundaryPoints(Range.END_TO_END, tempRange) !==
270
+ 1));
271
+ }
272
+ // Normal non-IE
273
+ return (!!element && !!element.href && selectedRange.intersectsNode(element));
274
+ });
275
+ }
276
+ getIframeDocumentEl(id) {
277
+ /* istanbul ignore next */
278
+ if (!(id in this.editors)) {
279
+ return undefined;
280
+ }
281
+ const contentWindowEl = this.getContentWindowEl(id);
282
+ /* istanbul ignore else */
283
+ if (contentWindowEl) {
284
+ return contentWindowEl.document;
285
+ }
286
+ /* istanbul ignore next */
287
+ return this.editors[id].iframeElementRef.contentDocument;
288
+ }
289
+ getFontSize(id) {
290
+ let fontSize = STYLE_STATE_DEFAULTS.fontSize.toString();
291
+ const selection = this.getCurrentSelection(id);
292
+ /* istanbul ignore else */
293
+ if (selection &&
294
+ selection.anchorNode &&
295
+ selection.anchorNode.parentElement) {
296
+ let element = selection.anchorNode;
297
+ if (element.nodeType !== 1) {
298
+ element = element.parentElement;
299
+ }
300
+ const computedStyle = window.getComputedStyle(element);
301
+ /* istanbul ignore else */
302
+ if (computedStyle) {
303
+ fontSize = computedStyle.getPropertyValue('font-size');
304
+ }
305
+ }
306
+ return fontSize;
307
+ }
308
+ createObservers(id, element) {
309
+ /* istanbul ignore next */
310
+ const documentEl = element.contentWindow
311
+ ? element.contentWindow.document
312
+ : element.contentDocument;
313
+ // Firefox bug where we need to open/close to cancel load so it doesn't overwrite attrs
314
+ documentEl.open();
315
+ documentEl.close();
316
+ const selectionObservable = new Subject();
317
+ const selectionListener = () => selectionObservable.next();
318
+ const clickObservable = new Subject();
319
+ const clickListener = () => clickObservable.next();
320
+ const pasteListener = this.getPasteOverride(id);
321
+ const blurObservable = new Subject();
322
+ const blurListener = () => blurObservable.next();
323
+ const inputObservable = new Subject();
324
+ const inputListener = () => inputObservable.next();
325
+ documentEl.addEventListener('selectionchange', selectionListener);
326
+ documentEl.addEventListener('input', inputListener);
327
+ documentEl.addEventListener('mousedown', clickListener);
328
+ documentEl.body.addEventListener('paste', pasteListener);
329
+ documentEl.body.addEventListener('blur', blurListener);
330
+ return {
331
+ blurObservable: blurObservable,
332
+ clickObservable: clickObservable,
333
+ commandChangeObservable: new Subject(),
334
+ iframeElementRef: element,
335
+ inputObservable: inputObservable,
336
+ selectionChangeObservable: selectionObservable,
337
+ blurListener: blurListener,
338
+ clickListener: clickListener,
339
+ inputListener: inputListener,
340
+ pasteListener: pasteListener,
341
+ selectionListener: selectionListener,
342
+ };
343
+ }
344
+ /* istanbul ignore next */
345
+ getPasteOverride(id) {
346
+ return (e) => {
347
+ e.preventDefault();
348
+ const text = e.clipboardData.getData('text/plain');
349
+ this.execCommand(id, { command: 'insertHTML', value: text });
350
+ };
351
+ }
352
+ getCurrentSelectionParentElement(id) {
353
+ return this.selectionService.getCurrentSelectionParentElement(this.getIframeDocumentEl(id));
354
+ }
355
+ getColor(documentEl, selector) {
356
+ const commandValue = documentEl.queryCommandValue(selector);
357
+ // Edge is weird and returns numbers
358
+ /* istanbul ignore if */
359
+ if (typeof commandValue === 'number') {
360
+ /* istanbul ignore next */
361
+ // tslint:disable-next-line: no-bitwise
362
+ return ('rgb(' +
363
+ (commandValue & 0xff) +
364
+ ', ' +
365
+ // tslint:disable-next-line: no-bitwise
366
+ ((commandValue & 0xff00) >> 8) +
367
+ ', ' +
368
+ // tslint:disable-next-line: no-bitwise
369
+ ((commandValue & 0xff0000) >> 16) +
370
+ ')');
371
+ }
372
+ // Firefox uses 'Transparent' instead of a color value
373
+ /* istanbul ignore next */
374
+ if (commandValue.toString().toLowerCase() === 'transparent') {
375
+ return STYLE_STATE_DEFAULTS.backColor;
376
+ }
377
+ return commandValue;
378
+ }
379
+ hasLink(editorId) {
380
+ const anchorEl = this.getSelectedAnchorTag(editorId);
381
+ const childAnchorEls = this.getChildSelectedAnchorTags(editorId);
382
+ /* istanbul ignore next */
383
+ return childAnchorEls.length > 0 || (!!anchorEl && !!anchorEl.href);
384
+ }
385
+ getParent(element, tag) {
386
+ let currentNode = element;
387
+ while (currentNode && currentNode.tagName.toUpperCase() !== 'BODY') {
388
+ if (currentNode.tagName.toUpperCase() === tag.toUpperCase()) {
389
+ return currentNode;
390
+ }
391
+ currentNode = currentNode.parentElement;
392
+ }
393
+ return undefined;
394
+ }
395
+ editorSelected(id) {
396
+ const documentEl = this.getIframeDocumentEl(id);
397
+ return this.selectionService.isElementSelected(documentEl, documentEl.body);
398
+ }
399
+ /* istanbul ignore next */
400
+ insertHtmlInIE11(id, html) {
401
+ const documentEl = this.getIframeDocumentEl(id);
402
+ const windowEl = this.getContentWindowEl(id);
403
+ const sel = windowEl.getSelection();
404
+ if (sel.getRangeAt && sel.rangeCount) {
405
+ let range = sel.getRangeAt(0);
406
+ range.deleteContents();
407
+ const el = documentEl.createElement('div');
408
+ el.innerHTML = html;
409
+ const frag = documentEl.createDocumentFragment();
410
+ let node, lastNode;
411
+ while (el.firstChild) {
412
+ node = el.firstChild;
413
+ lastNode = frag.appendChild(node);
414
+ }
415
+ range.insertNode(frag);
416
+ // Preserve the selection
417
+ if (lastNode) {
418
+ range = range.cloneRange();
419
+ range.setStartAfter(lastNode);
420
+ range.collapse(true);
421
+ sel.removeAllRanges();
422
+ sel.addRange(range);
423
+ }
424
+ }
425
+ }
426
+ cleanUpBlankStyleTags(doc) {
427
+ const orphanElements = Array.from(doc.querySelectorAll('font,span,*[style=""]'));
428
+ for (const element of orphanElements) {
429
+ if (!element.getAttribute('style')) {
430
+ element.removeAttribute('style');
431
+ }
432
+ }
433
+ const removableElements = orphanElements.filter((element) => {
434
+ const tagName = element.tagName.toUpperCase();
435
+ return ((tagName === 'FONT' || tagName === 'SPAN') &&
436
+ (element.attributes.length === 0 || !element.hasChildNodes));
437
+ });
438
+ for (const element of removableElements) {
439
+ const parent = element.parentNode;
440
+ /* istanbul ignore else */
441
+ if (parent) {
442
+ while (element.firstChild) {
443
+ parent.insertBefore(element.firstChild, element);
444
+ }
445
+ parent.removeChild(element);
446
+ }
447
+ }
448
+ }
449
+ // Certain values are encoded in html and need to be decoded
450
+ replaceHtmlCodes(str) {
451
+ return str
452
+ .replace(/&nbsp;/, String.fromCharCode(160))
453
+ .replace(/&lt;/g, '<')
454
+ .replace(/&gt;/g, '>')
455
+ .replace(/&amp;/g, '&');
456
+ }
457
+ setEditorDisabled(id, focusableChildren, textEditorNativeElement, disabled) {
458
+ textEditorNativeElement.style.pointerEvents = disabled ? 'none' : 'auto';
459
+ textEditorNativeElement.setAttribute('aria-disabled', disabled ? 'true' : 'false');
460
+ /* istanbul ignore else */
461
+ if (focusableChildren.length > 0) {
462
+ focusableChildren.forEach((aFocusableChild) => {
463
+ aFocusableChild.tabIndex = disabled ? -1 : 0;
464
+ });
465
+ }
466
+ this.getIframeDocumentEl(id).body.setAttribute('contenteditable', disabled ? 'false' : 'true');
467
+ }
468
+ }
469
+ SkyTextEditorAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SkyTextEditorAdapterService, deps: [{ token: i1.SkyTextEditorSelectionService }, { token: i2.SkyTextEditorService }, { token: i3.SkyAppWindowRef }], target: i0.ɵɵFactoryTarget.Injectable });
470
+ SkyTextEditorAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SkyTextEditorAdapterService, providedIn: 'root' });
471
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SkyTextEditorAdapterService, decorators: [{
472
+ type: Injectable,
473
+ args: [{
474
+ providedIn: 'root',
475
+ }]
476
+ }], ctorParameters: function () { return [{ type: i1.SkyTextEditorSelectionService }, { type: i2.SkyTextEditorService }, { type: i3.SkyAppWindowRef }]; } });
477
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1lZGl0b3ItYWRhcHRlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21wb25lbnRzL3RleHQtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy90ZXh0LWVkaXRvci9zZXJ2aWNlcy90ZXh0LWVkaXRvci1hZGFwdGVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0IsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFLeEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBRWhFLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7OztBQUU3RDs7R0FFRztBQUlILE1BQU0sT0FBTywyQkFBMkI7SUFLdEMsWUFDVSxnQkFBK0MsRUFDL0MsaUJBQXVDLEVBQ3ZDLGFBQThCO1FBRjlCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBK0I7UUFDL0Msc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFzQjtRQUN2QyxrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7SUFDckMsQ0FBQztJQVJKLElBQVksT0FBTztRQUNqQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7SUFDeEMsQ0FBQztJQVFEOztPQUVHO0lBQ0ksU0FBUyxDQUNkLEVBQVUsRUFDVixhQUFnQyxFQUNoQyxVQUFtQyxFQUNuQyxXQUFvQjtRQUVwQiwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLElBQUksQ0FB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QyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQzVDLGlCQUFpQixFQUNqQixRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUM1QixDQUFDO0lBQ0osQ0FBQzs7d0hBdmxCVSwyQkFBMkI7NEhBQTNCLDJCQUEyQixjQUYxQixNQUFNOzJGQUVQLDJCQUEyQjtrQkFIdkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTa3lBcHBXaW5kb3dSZWYgfSBmcm9tICdAc2t5dXgvY29yZSc7XG5cbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgU1RZTEVfU1RBVEVfREVGQVVMVFMgfSBmcm9tICcuLi9kZWZhdWx0cy9zdHlsZS1zdGF0ZS1kZWZhdWx0cyc7XG5pbXBvcnQgeyBFZGl0b3JDb21tYW5kIH0gZnJvbSAnLi4vdHlwZXMvZWRpdG9yLWNvbW1hbmQnO1xuaW1wb3J0IHsgRWRpdG9yU2V0dGluZyB9IGZyb20gJy4uL3R5cGVzL2VkaXRvci1zZXR0aW5nJztcbmltcG9ydCB7IFNreVRleHRFZGl0b3JTdHlsZVN0YXRlIH0gZnJvbSAnLi4vdHlwZXMvc3R5bGUtc3RhdGUnO1xuaW1wb3J0IHsgVXJsTW9kYWxSZXN1bHQgfSBmcm9tICcuLi91cmwtbW9kYWwvdGV4dC1lZGl0b3ItdXJsLW1vZGFsLXJlc3VsdCc7XG5pbXBvcnQgeyBVcmxUYXJnZXQgfSBmcm9tICcuLi91cmwtbW9kYWwvdGV4dC1lZGl0b3ItdXJsLXRhcmdldCc7XG5cbmltcG9ydCB7IFNreVRleHRFZGl0b3JTZWxlY3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi90ZXh0LWVkaXRvci1zZWxlY3Rpb24uc2VydmljZSc7XG5pbXBvcnQgeyBTa3lUZXh0RWRpdG9yU2VydmljZSB9IGZyb20gJy4vdGV4dC1lZGl0b3Iuc2VydmljZSc7XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBTa3lUZXh0RWRpdG9yQWRhcHRlclNlcnZpY2Uge1xuICBwcml2YXRlIGdldCBlZGl0b3JzKCk6IHsgW2tleTogc3RyaW5nXTogRWRpdG9yU2V0dGluZyB9IHtcbiAgICByZXR1cm4gdGhpcy50ZXh0RWRpdG9yU2VydmljZS5lZGl0b3JzO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzZWxlY3Rpb25TZXJ2aWNlOiBTa3lUZXh0RWRpdG9yU2VsZWN0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIHRleHRFZGl0b3JTZXJ2aWNlOiBTa3lUZXh0RWRpdG9yU2VydmljZSxcbiAgICBwcml2YXRlIHdpbmRvd1NlcnZpY2U6IFNreUFwcFdpbmRvd1JlZlxuICApIHt9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSB0ZXh0IGVkaXRvciBpbnNpZGUgdGhlIHN1cHBsaWVkIGlmcmFtZSBlbGVtZW50LlxuICAgKi9cbiAgcHVibGljIGFkZEVkaXRvcihcbiAgICBpZDogc3RyaW5nLFxuICAgIGlmcmFtZUVsZW1lbnQ6IEhUTUxJRnJhbWVFbGVtZW50LFxuICAgIHN0eWxlU3RhdGU6IFNreVRleHRFZGl0b3JTdHlsZVN0YXRlLFxuICAgIHBsYWNlaG9sZGVyPzogc3RyaW5nXG4gICk6IHZvaWQge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKCEoaWQgaW4gdGhpcy5lZGl0b3JzKSkge1xuICAgICAgdGhpcy5lZGl0b3JzW2lkXSA9IHRoaXMuY3JlYXRlT2JzZXJ2ZXJzKGlkLCBpZnJhbWVFbGVtZW50KTtcblxuICAgICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZCk7XG5cbiAgICAgIGNvbnN0IHN0eWxlRWwgPSBkb2N1bWVudEVsLmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgICBzdHlsZUVsLmlubmVySFRNTCA9IGAuZWRpdG9yOmVtcHR5OmJlZm9yZSB7XG4gICAgICAgIGNvbnRlbnQ6IGF0dHIoZGF0YS1wbGFjZWhvbGRlcik7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIkJsYWNrYmF1ZCBTYW5zXCIsIEFyaWFsLCBzYW5zLXNlcmlmO1xuICAgICAgICBjb2xvcjogIzY4NmM3MztcbiAgICAgICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICAgICAgZm9udC1zaXplOiAxNXB4O1xuICAgICAgICBmb250LXN0eWxlOiBpdGFsaWM7XG4gICAgICB9YDtcbiAgICAgIGRvY3VtZW50RWwuaGVhZC5hcHBlbmRDaGlsZChzdHlsZUVsKTtcblxuICAgICAgY29uc3Qgc3R5bGU6IFNreVRleHRFZGl0b3JTdHlsZVN0YXRlID0ge1xuICAgICAgICAuLi5TVFlMRV9TVEFURV9ERUZBVUxUUyxcbiAgICAgICAgLi4uc3R5bGVTdGF0ZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBib2R5U3R5bGUgPSBgYmFja2dyb3VuZC1jb2xvcjogJHtzdHlsZS5iYWNrQ29sb3J9O1xuICAgICAgICBjb2xvcjogJHtzdHlsZS5mb250Q29sb3J9O1xuICAgICAgICBmb250LWZhbWlseTogJHtzdHlsZS5mb250fTtcbiAgICAgICAgZm9udC1zaXplOiAke3N0eWxlLmZvbnRTaXplfXB4YDtcbiAgICAgIGRvY3VtZW50RWwucXVlcnlTZWxlY3RvcignaHRtbCcpLnNldEF0dHJpYnV0ZSgnbGFuZycsICdlbicpO1xuICAgICAgZG9jdW1lbnRFbC5ib2R5LnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgJ3RydWUnKTtcbiAgICAgIGRvY3VtZW50RWwuYm9keS5zZXRBdHRyaWJ1dGUoJ2lkJywgaWQpO1xuICAgICAgZG9jdW1lbnRFbC5ib2R5LnNldEF0dHJpYnV0ZSgncm9sZScsICdtYWluJyk7XG4gICAgICBkb2N1bWVudEVsLmJvZHkuc2V0QXR0cmlidXRlKCdjbGFzcycsICdlZGl0b3InKTtcbiAgICAgIGRvY3VtZW50RWwuYm9keS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYm9keVN0eWxlKTtcbiAgICAgIGRvY3VtZW50RWwuYm9keS5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGxhY2Vob2xkZXInLCBwbGFjZWhvbGRlciB8fCAnJyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGRpc2FibGVFZGl0b3IoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBmb2N1c2FibGVDaGlsZHJlbjogSFRNTEVsZW1lbnRbXSxcbiAgICB0ZXh0RWRpdG9yTmF0aXZlRWxlbWVudDogYW55XG4gICk6IHZvaWQge1xuICAgIHRoaXMuc2V0RWRpdG9yRGlzYWJsZWQoXG4gICAgICBpZCxcbiAgICAgIGZvY3VzYWJsZUNoaWxkcmVuLFxuICAgICAgdGV4dEVkaXRvck5hdGl2ZUVsZW1lbnQsXG4gICAgICB0cnVlXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBlbmFibGVFZGl0b3IoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBmb2N1c2FibGVDaGlsZHJlbjogSFRNTEVsZW1lbnRbXSxcbiAgICB0ZXh0RWRpdG9yTmF0aXZlRWxlbWVudDogYW55XG4gICk6IHZvaWQge1xuICAgIHRoaXMuc2V0RWRpdG9yRGlzYWJsZWQoXG4gICAgICBpZCxcbiAgICAgIGZvY3VzYWJsZUNoaWxkcmVuLFxuICAgICAgdGV4dEVkaXRvck5hdGl2ZUVsZW1lbnQsXG4gICAgICBmYWxzZVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgYSBjb21tYW5kIG9uIHRoZSB0ZXh0IGVkaXRvciB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGlkLlxuICAgKi9cbiAgcHVibGljIGV4ZWNDb21tYW5kKGlkOiBzdHJpbmcsIGVkaXRvckNvbW1hbmQ6IEVkaXRvckNvbW1hbmQpOiB2b2lkIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChpZCBpbiB0aGlzLmVkaXRvcnMpIHtcbiAgICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHRoaXMuZWRpdG9yU2VsZWN0ZWQoaWQpKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmRJc1N1cHBvcnRlZEFuZEVuYWJsZWQgPSBkb2N1bWVudEVsLmV4ZWNDb21tYW5kKFxuICAgICAgICAgIGVkaXRvckNvbW1hbmQuY29tbWFuZCxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICBlZGl0b3JDb21tYW5kLnZhbHVlXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gSUUxMSBkb2Vzbid0IHN1cHBvcnQgaW5zZXJ0SFRNTFxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZWRpdG9yQ29tbWFuZC5jb21tYW5kLnRvTG93ZXJDYXNlKCkgPT09ICdpbnNlcnRodG1sJyAmJlxuICAgICAgICAgICFjb21tYW5kSXNTdXBwb3J0ZWRBbmRFbmFibGVkXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuaW5zZXJ0SHRtbEluSUUxMShpZCwgZWRpdG9yQ29tbWFuZC52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvY3VzRWRpdG9yKGlkKTtcbiAgICAgICAgdGhpcy5lZGl0b3JzW2lkXS5jb21tYW5kQ2hhbmdlT2JzZXJ2YWJsZS5uZXh0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldEN1cnJlbnRTZWxlY3Rpb24oaWQ6IHN0cmluZyk6IFNlbGVjdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRDdXJyZW50U2VsZWN0aW9uKFxuICAgICAgdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGRhdGEgVVJJIHVzaW5nIHRoZSBwcm92aWRlZCB0ZXh0IHN0cmluZy5cbiAgICogVXNlZCB0byBkaXNwbGF5IGEgbWVyZ2UgZmllbGQgaW5zaWRlIGEgc3RyaW5nIG9mIHRleHQuXG4gICAqL1xuICBwdWJsaWMgZ2V0TWVyZ2VGaWVsZERhdGFVUkkodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy53aW5kb3dTZXJ2aWNlLm5hdGl2ZVdpbmRvdy5kb2N1bWVudDtcbiAgICBsZXQgdGV4dFRvVXNlID0gdGV4dDtcbiAgICBpZiAodGV4dC5sZW5ndGggPiAxOCkge1xuICAgICAgdGV4dFRvVXNlID0gdGV4dC5zdWJzdHIoMCwgMTUpICsgJy4uLic7XG4gICAgfVxuXG4gICAgY29uc3QgY2FudmFzRWxlbWVudCA9IGRvY3VtZW50RWwuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgY2FudmFzRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsICcyMCcpO1xuICAgIGNhbnZhc0VsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsICcxMDAnKTtcbiAgICBjYW52YXNFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9ICd0YW4nO1xuICAgIGNhbnZhc0VsZW1lbnQuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjMDAwMDAwJztcbiAgICBjYW52YXNFbGVtZW50LnN0eWxlLmJvcmRlclJhZGl1cyA9ICc1cHgnO1xuXG4gICAgY29uc3QgY29udGV4dCA9IGNhbnZhc0VsZW1lbnQuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjb250ZXh0LmZvbnQgPSAnMTJweCBBcmlhbCc7XG4gICAgY29udGV4dC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICBjb250ZXh0LmZpbGxUZXh0KHRleHRUb1VzZSwgNTAsIDE1KTtcblxuICAgIGNvbnRleHQuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2Rlc3RpbmF0aW9uLW92ZXInO1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gJyMwMEZGRkYnO1xuICAgIGNvbnRleHQuZmlsbFJlY3QoMCwgMCwgMTAwLCAyMCk7XG5cbiAgICBjb250ZXh0Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdzb3VyY2Utb3Zlcic7XG4gICAgY29udGV4dC5saW5lV2lkdGggPSAyO1xuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSAnI0ZGMDAwMCc7XG4gICAgY29udGV4dC5zdHJva2VSZWN0KDAsIDAsIDEwMCwgMjApO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gY2FudmFzRWxlbWVudC50b0RhdGFVUkwoJ2ltYWdlL3BuZycsIDEuMCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTdHlsZVN0YXRlKGlkOiBzdHJpbmcpOiBQYXJ0aWFsPFNreVRleHRFZGl0b3JTdHlsZVN0YXRlPiB7XG4gICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZCk7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh0aGlzLmVkaXRvclNlbGVjdGVkKGlkKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYmFja0NvbG9yOiB0aGlzLmdldENvbG9yKGRvY3VtZW50RWwsICdCYWNrQ29sb3InKSxcbiAgICAgICAgZm9udENvbG9yOiB0aGlzLmdldENvbG9yKGRvY3VtZW50RWwsICdGb3JlQ29sb3InKSxcbiAgICAgICAgZm9udFNpemU6IHBhcnNlSW50KHRoaXMuZ2V0Rm9udFNpemUoaWQpLCB1bmRlZmluZWQpLFxuICAgICAgICBmb250OiBkb2N1bWVudEVsLnF1ZXJ5Q29tbWFuZFZhbHVlKCdmb250bmFtZScpLFxuICAgICAgICBib2xkU3RhdGU6IGRvY3VtZW50RWwucXVlcnlDb21tYW5kU3RhdGUoJ0JvbGQnKSxcbiAgICAgICAgaXRhbGljU3RhdGU6IGRvY3VtZW50RWwucXVlcnlDb21tYW5kU3RhdGUoJ0l0YWxpYycpLFxuICAgICAgICB1bmRlcmxpbmVTdGF0ZTogZG9jdW1lbnRFbC5xdWVyeUNvbW1hbmRTdGF0ZSgnVW5kZXJsaW5lJyksXG4gICAgICAgIGxpbmtTdGF0ZTogdGhpcy5oYXNMaW5rKGlkKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBwdWJsaWMgZ2V0RWRpdG9ySW5uZXJIdG1sKGlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuICAgIGlmIChkb2N1bWVudEVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBsYWNlSHRtbENvZGVzKGRvY3VtZW50RWwuYm9keS5pbm5lckhUTUwpO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBwdWJsaWMgc2V0RWRpdG9ySW5uZXJIdG1sKGlkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcbiAgICBjb25zdCBlZGl0b3JDb250ZW50ID0gZG9jdW1lbnRFbC5ib2R5O1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKGVkaXRvckNvbnRlbnQuaW5uZXJIVE1MICE9PSB2YWx1ZSkge1xuICAgICAgZWRpdG9yQ29udGVudC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZm9jdXNFZGl0b3IoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKGlkIGluIHRoaXMuZWRpdG9ycykge1xuICAgICAgY29uc3Qgd2luZG93RWwgPSB0aGlzLmdldENvbnRlbnRXaW5kb3dFbChpZCk7XG4gICAgICBjb25zdCBpZnJhbWVEb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZ2V0Q3VycmVudFNlbGVjdGlvblJhbmdlKFxuICAgICAgICBpZnJhbWVEb2N1bWVudEVsLFxuICAgICAgICB3aW5kb3dFbFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGN1cnNvcklzTm90QWN0aXZlQW5kSGFzUmVzZXQgPVxuICAgICAgICBjdXJyZW50U2VsZWN0aW9uICYmXG4gICAgICAgIGN1cnJlbnRTZWxlY3Rpb24uc3RhcnRPZmZzZXQgPT09IDAgJiZcbiAgICAgICAgY3VycmVudFNlbGVjdGlvbi5lbmRPZmZzZXQgPT09IDA7XG5cbiAgICAgIGlmICghdGhpcy5lZGl0b3JTZWxlY3RlZChpZCkgfHwgY3Vyc29ySXNOb3RBY3RpdmVBbmRIYXNSZXNldCkge1xuICAgICAgICAvLyBmb2N1cyB0aGUgZW5kIG9mIHRoZSBlZGl0b3JcbiAgICAgICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMud2luZG93U2VydmljZS5uYXRpdmVXaW5kb3cuZG9jdW1lbnQ7XG4gICAgICAgIGNvbnN0IGVkaXRvcjogYW55ID0gaWZyYW1lRG9jdW1lbnRFbC5ib2R5O1xuICAgICAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50RWwuY3JlYXRlUmFuZ2UoKTtcblxuICAgICAgICB0aGlzLmVkaXRvcnNbaWRdLmlmcmFtZUVsZW1lbnRSZWYuZm9jdXMoKTtcbiAgICAgICAgZWRpdG9yLmZvY3VzKCk7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmICh3aW5kb3dFbC5nZXRTZWxlY3Rpb24gJiYgZG9jdW1lbnRFbC5jcmVhdGVSYW5nZSkge1xuICAgICAgICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhlZGl0b3IpO1xuICAgICAgICAgIHJhbmdlLmNvbGxhcHNlKGZhbHNlKTtcbiAgICAgICAgICBjb25zdCBzZWwgPSB3aW5kb3dFbC5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBJRSBvbmx5XG4gICAgICAgICAgY29uc3QgdGV4dFJhbmdlID0gZWRpdG9yLmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgICAgIHRleHRSYW5nZS5tb3ZlVG9FbGVtZW50VGV4dChlZGl0b3IpO1xuICAgICAgICAgIHRleHRSYW5nZS5jb2xsYXBzZShmYWxzZSk7XG4gICAgICAgICAgdGV4dFJhbmdlLnNlbGVjdCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDdXJzb3IgbWF5IG5vdCBiZSBhY3RpdmUsIHJlc3RvcmUgaXRcbiAgICAgICAgdGhpcy5lZGl0b3JzW2lkXS5pZnJhbWVFbGVtZW50UmVmLmZvY3VzKCk7XG4gICAgICAgIGlmcmFtZURvY3VtZW50RWwuYm9keS5mb2N1cygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRMaW5rKGVkaXRvcklkOiBzdHJpbmcpOiBVcmxNb2RhbFJlc3VsdCB7XG4gICAgbGV0IGxpbms6IFVybE1vZGFsUmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFuY2hvckVsID0gdGhpcy5nZXRTZWxlY3RlZEFuY2hvclRhZyhlZGl0b3JJZCk7XG4gICAgaWYgKGFuY2hvckVsICYmIGFuY2hvckVsLmhyZWYpIHtcbiAgICAgIGxpbmsgPSB7XG4gICAgICAgIHRhcmdldDpcbiAgICAgICAgICBhbmNob3JFbC5nZXRBdHRyaWJ1dGUoJ3RhcmdldCcpID09PSAnX2JsYW5rJ1xuICAgICAgICAgICAgPyBVcmxUYXJnZXQuTmV3V2luZG93XG4gICAgICAgICAgICA6IFVybFRhcmdldC5Ob25lLFxuICAgICAgICB1cmw6IGFuY2hvckVsLmhyZWYsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBsaW5rO1xuICB9XG5cbiAgcHVibGljIGdldFNlbGVjdGVkQW5jaG9yVGFnKGVkaXRvcklkOiBzdHJpbmcpOiBIVE1MQW5jaG9yRWxlbWVudCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbCA9IHRoaXMuZ2V0Q3VycmVudFNlbGVjdGlvblBhcmVudEVsZW1lbnQoZWRpdG9ySWQpO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0UGFyZW50KHNlbGVjdGVkRWwsICdhJykgYXMgSFRNTEFuY2hvckVsZW1lbnQ7XG4gIH1cblxuICBwdWJsaWMgc2F2ZVNlbGVjdGlvbihpZDogc3RyaW5nKTogUmFuZ2Uge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZ2V0Q3VycmVudFNlbGVjdGlvblJhbmdlKFxuICAgICAgdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKSxcbiAgICAgIHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0RWxlbWVudChpZDogc3RyaW5nLCBlbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5zZWxlY3RFbGVtZW50KFxuICAgICAgdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKSxcbiAgICAgIHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKSxcbiAgICAgIGVsZW1lbnRcbiAgICApO1xuICB9XG5cbiAgcHVibGljIHNldFBsYWNlaG9sZGVyKGlkOiBzdHJpbmcsIHBsYWNlaG9sZGVyPzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZCk7XG4gICAgZG9jdW1lbnRFbC5ib2R5LnNldEF0dHJpYnV0ZSgnZGF0YS1wbGFjZWhvbGRlcicsIHBsYWNlaG9sZGVyIHx8ICcnKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRGb250U2l6ZShpZDogc3RyaW5nLCBmb250U2l6ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZG9jID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcbiAgICB0aGlzLmV4ZWNDb21tYW5kKGlkLCB7IGNvbW1hbmQ6ICdmb250U2l6ZScsIHZhbHVlOiAxIH0pO1xuICAgIGNvbnN0IGZvbnRFbGVtZW50czogSFRNTEVsZW1lbnRbXSA9IEFycmF5LmZyb20oXG4gICAgICBkb2MucXVlcnlTZWxlY3RvckFsbCgnZm9udFtzaXplPVwiMVwiXScpXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZm9udEVsZW1lbnRzKSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnc2l6ZScpO1xuICAgICAgZWxlbWVudC5zdHlsZS5mb250U2l6ZSA9IGZvbnRTaXplICsgJ3B4JztcbiAgICB9XG4gICAgdGhpcy5jbGVhblVwQmxhbmtTdHlsZVRhZ3MoZG9jKTtcblxuICAgIHRoaXMuZm9jdXNFZGl0b3IoaWQpO1xuICAgIHRoaXMuZWRpdG9yc1tpZF0uY29tbWFuZENoYW5nZU9ic2VydmFibGUubmV4dCgpO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZU9ic2VydmVycyhzZXR0aW5nOiBFZGl0b3JTZXR0aW5nKTogdm9pZCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBjb25zdCBkb2N1bWVudEVsID0gc2V0dGluZy5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnRXaW5kb3dcbiAgICAgID8gc2V0dGluZy5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnRcbiAgICAgIDogc2V0dGluZy5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnREb2N1bWVudDtcbiAgICBzZXR0aW5nLnNlbGVjdGlvbkNoYW5nZU9ic2VydmFibGUuY29tcGxldGUoKTtcbiAgICBzZXR0aW5nLmNsaWNrT2JzZXJ2YWJsZS5jb21wbGV0ZSgpO1xuICAgIHNldHRpbmcuY29tbWFuZENoYW5nZU9ic2VydmFibGUuY29tcGxldGUoKTtcbiAgICBkb2N1bWVudEVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAnc2VsZWN0aW9uY2hhbmdlJyxcbiAgICAgIHNldHRpbmcuc2VsZWN0aW9uTGlzdGVuZXJcbiAgICApO1xuICAgIGRvY3VtZW50RWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBzZXR0aW5nLnNlbGVjdGlvbkxpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHNldHRpbmcuY2xpY2tMaXN0ZW5lcik7XG4gICAgZG9jdW1lbnRFbC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgc2V0dGluZy5wYXN0ZUxpc3RlbmVyKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29udGVudFdpbmRvd0VsKGlkOiBzdHJpbmcpOiBXaW5kb3cge1xuICAgIHJldHVybiB0aGlzLmVkaXRvcnNbaWRdLmlmcmFtZUVsZW1lbnRSZWYuY29udGVudFdpbmRvdztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2hpbGRTZWxlY3RlZEFuY2hvclRhZ3MoZWRpdG9ySWQ6IHN0cmluZyk6IEVsZW1lbnRbXSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSYW5nZSA9IHRoaXMuZ2V0Q3VycmVudFNlbGVjdGlvbihlZGl0b3JJZCkuZ2V0UmFuZ2VBdCgwKTtcbiAgICBpZiAoc2VsZWN0ZWRSYW5nZS50b1N0cmluZygpLmxlbmd0aCA8PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50RWxlbWVudCA9IHRoaXMuZ2V0Q3VycmVudFNlbGVjdGlvblBhcmVudEVsZW1lbnQoZWRpdG9ySWQpO1xuXG4gICAgbGV0IGNoaWxkRWxlbWVudHMgPSBbXTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChwYXJlbnRFbGVtZW50KSB7XG4gICAgICBjaGlsZEVsZW1lbnRzID0gQXJyYXkuZnJvbShwYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2EnKSk7XG4gICAgfVxuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gY2hpbGRFbGVtZW50cy5maWx0ZXIoKGVsZW1lbnQpID0+IHtcbiAgICAgIC8vIElFIHNwZWNpZmljXG4gICAgICBpZiAoIXNlbGVjdGVkUmFuZ2UuaW50ZXJzZWN0c05vZGUpIHtcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8ICFlbGVtZW50LmhyZWYpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGVtcFJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgdGVtcFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAoc2VsZWN0ZWRSYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHMoXG4gICAgICAgICAgICBSYW5nZS5TVEFSVF9UT19TVEFSVCxcbiAgICAgICAgICAgIHRlbXBSYW5nZVxuICAgICAgICAgICkgIT09IC0xICYmXG4gICAgICAgICAgICBzZWxlY3RlZFJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhcbiAgICAgICAgICAgICAgUmFuZ2UuU1RBUlRfVE9fRU5ELFxuICAgICAgICAgICAgICB0ZW1wUmFuZ2VcbiAgICAgICAgICAgICkgIT09IDEpIHx8XG4gICAgICAgICAgKHNlbGVjdGVkUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKFxuICAgICAgICAgICAgUmFuZ2UuRU5EX1RPX1NUQVJULFxuICAgICAgICAgICAgdGVtcFJhbmdlXG4gICAgICAgICAgKSAhPT0gLTEgJiZcbiAgICAgICAgICAgIHNlbGVjdGVkUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKFJhbmdlLkVORF9UT19FTkQsIHRlbXBSYW5nZSkgIT09XG4gICAgICAgICAgICAgIDEpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIE5vcm1hbCBub24tSUVcbiAgICAgIHJldHVybiAoXG4gICAgICAgICEhZWxlbWVudCAmJiAhIWVsZW1lbnQuaHJlZiAmJiBzZWxlY3RlZFJhbmdlLmludGVyc2VjdHNOb2RlKGVsZW1lbnQpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJZnJhbWVEb2N1bWVudEVsKGlkOiBzdHJpbmcpOiBEb2N1bWVudCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoIShpZCBpbiB0aGlzLmVkaXRvcnMpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRXaW5kb3dFbCA9IHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChjb250ZW50V2luZG93RWwpIHtcbiAgICAgIHJldHVybiBjb250ZW50V2luZG93RWwuZG9jdW1lbnQ7XG4gICAgfVxuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gdGhpcy5lZGl0b3JzW2lkXS5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnREb2N1bWVudDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Rm9udFNpemUoaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IGZvbnRTaXplID0gU1RZTEVfU1RBVEVfREVGQVVMVFMuZm9udFNpemUudG9TdHJpbmcoKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmdldEN1cnJlbnRTZWxlY3Rpb24oaWQpO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKFxuICAgICAgc2VsZWN0aW9uICYmXG4gICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSAmJlxuICAgICAgc2VsZWN0aW9uLmFuY2hvck5vZGUucGFyZW50RWxlbWVudFxuICAgICkge1xuICAgICAgbGV0IGVsZW1lbnQgPSBzZWxlY3Rpb24uYW5jaG9yTm9kZTtcbiAgICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9PSAxKSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgICB9XG4gICAgICBjb25zdCBjb21wdXRlZFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCBhcyBFbGVtZW50KTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAoY29tcHV0ZWRTdHlsZSkge1xuICAgICAgICBmb250U2l6ZSA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZm9udC1zaXplJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmb250U2l6ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlT2JzZXJ2ZXJzKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgZWxlbWVudDogSFRNTElGcmFtZUVsZW1lbnRcbiAgKTogRWRpdG9yU2V0dGluZyB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBjb25zdCBkb2N1bWVudEVsID0gZWxlbWVudC5jb250ZW50V2luZG93XG4gICAgICA/IGVsZW1lbnQuY29udGVudFdpbmRvdy5kb2N1bWVudFxuICAgICAgOiBlbGVtZW50LmNvbnRlbnREb2N1bWVudDtcblxuICAgIC8vIEZpcmVmb3ggYnVnIHdoZXJlIHdlIG5lZWQgdG8gb3Blbi9jbG9zZSB0byBjYW5jZWwgbG9hZCBzbyBpdCBkb2Vzbid0IG92ZXJ3cml0ZSBhdHRyc1xuICAgIGRvY3VtZW50RWwub3BlbigpO1xuICAgIGRvY3VtZW50RWwuY2xvc2UoKTtcblxuICAgIGNvbnN0IHNlbGVjdGlvbk9ic2VydmFibGUgPSBuZXcgU3ViamVjdCgpO1xuICAgIGNvbnN0IHNlbGVjdGlvbkxpc3RlbmVyID0gKCkgPT4gc2VsZWN0aW9uT2JzZXJ2YWJsZS5uZXh0KCk7XG4gICAgY29uc3QgY2xpY2tPYnNlcnZhYmxlID0gbmV3IFN1YmplY3QoKTtcbiAgICBjb25zdCBjbGlja0xpc3RlbmVyID0gKCkgPT4gY2xpY2tPYnNlcnZhYmxlLm5leHQoKTtcbiAgICBjb25zdCBwYXN0ZUxpc3RlbmVyID0gdGhpcy5nZXRQYXN0ZU92ZXJyaWRlKGlkKTtcbiAgICBjb25zdCBibHVyT2JzZXJ2YWJsZSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgY29uc3QgYmx1ckxpc3RlbmVyID0gKCkgPT4gYmx1ck9ic2VydmFibGUubmV4dCgpO1xuICAgIGNvbnN0IGlucHV0T2JzZXJ2YWJsZSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgY29uc3QgaW5wdXRMaXN0ZW5lciA9ICgpID0+IGlucHV0T2JzZXJ2YWJsZS5uZXh0KCk7XG5cbiAgICBkb2N1bWVudEVsLmFkZEV2ZW50TGlzdGVuZXIoJ3NlbGVjdGlvbmNoYW5nZScsIHNlbGVjdGlvbkxpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgaW5wdXRMaXN0ZW5lcik7XG4gICAgZG9jdW1lbnRFbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBjbGlja0xpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLmJvZHkuYWRkRXZlbnRMaXN0ZW5lcigncGFzdGUnLCBwYXN0ZUxpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLmJvZHkuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIGJsdXJMaXN0ZW5lcik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJsdXJPYnNlcnZhYmxlOiBibHVyT2JzZXJ2YWJsZSxcbiAgICAgIGNsaWNrT2JzZXJ2YWJsZTogY2xpY2tPYnNlcnZhYmxlLFxuICAgICAgY29tbWFuZENoYW5nZU9ic2VydmFibGU6IG5ldyBTdWJqZWN0KCksXG4gICAgICBpZnJhbWVFbGVtZW50UmVmOiBlbGVtZW50LFxuICAgICAgaW5wdXRPYnNlcnZhYmxlOiBpbnB1dE9ic2VydmFibGUsXG4gICAgICBzZWxlY3Rpb25DaGFuZ2VPYnNlcnZhYmxlOiBzZWxlY3Rpb25PYnNlcnZhYmxlLFxuICAgICAgYmx1ckxpc3RlbmVyOiBibHVyTGlzdGVuZXIsXG4gICAgICBjbGlja0xpc3RlbmVyOiBjbGlja0xpc3RlbmVyLFxuICAgICAgaW5wdXRMaXN0ZW5lcjogaW5wdXRMaXN0ZW5lcixcbiAgICAgIHBhc3RlTGlzdGVuZXI6IHBhc3RlTGlzdGVuZXIsXG4gICAgICBzZWxlY3Rpb25MaXN0ZW5lcjogc2VsZWN0aW9uTGlzdGVuZXIsXG4gICAgfTtcbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHByaXZhdGUgZ2V0UGFzdGVPdmVycmlkZShpZDogc3RyaW5nKTogKGU6IENsaXBib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gKGU6IENsaXBib2FyZEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCB0ZXh0ID0gZS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTtcbiAgICAgIHRoaXMuZXhlY0NvbW1hbmQoaWQsIHsgY29tbWFuZDogJ2luc2VydEhUTUwnLCB2YWx1ZTogdGV4dCB9KTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDdXJyZW50U2VsZWN0aW9uUGFyZW50RWxlbWVudChpZDogc3RyaW5nKTogRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRDdXJyZW50U2VsZWN0aW9uUGFyZW50RWxlbWVudChcbiAgICAgIHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2xvcihkb2N1bWVudEVsOiBEb2N1bWVudCwgc2VsZWN0b3I6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29tbWFuZFZhbHVlID0gZG9jdW1lbnRFbC5xdWVyeUNvbW1hbmRWYWx1ZShzZWxlY3Rvcik7XG5cbiAgICAvLyBFZGdlIGlzIHdlaXJkIGFuZCByZXR1cm5zIG51bWJlcnNcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodHlwZW9mIGNvbW1hbmRWYWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWJpdHdpc2VcbiAgICAgIHJldHVybiAoXG4gICAgICAgICdyZ2IoJyArXG4gICAgICAgIChjb21tYW5kVmFsdWUgJiAweGZmKSArXG4gICAgICAgICcsICcgK1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWJpdHdpc2VcbiAgICAgICAgKChjb21tYW5kVmFsdWUgJiAweGZmMDApID4+IDgpICtcbiAgICAgICAgJywgJyArXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYml0d2lzZVxuICAgICAgICAoKGNvbW1hbmRWYWx1ZSAmIDB4ZmYwMDAwKSA+PiAxNikgK1xuICAgICAgICAnKSdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gRmlyZWZveCB1c2VzICdUcmFuc3BhcmVudCcgaW5zdGVhZCBvZiBhIGNvbG9yIHZhbHVlXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoY29tbWFuZFZhbHVlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RyYW5zcGFyZW50Jykge1xuICAgICAgcmV0dXJuIFNUWUxFX1NUQVRFX0RFRkFVTFRTLmJhY2tDb2xvcjtcbiAgICB9XG4gICAgcmV0dXJuIGNvbW1hbmRWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgaGFzTGluayhlZGl0b3JJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYW5jaG9yRWwgPSB0aGlzLmdldFNlbGVjdGVkQW5jaG9yVGFnKGVkaXRvcklkKTtcbiAgICBjb25zdCBjaGlsZEFuY2hvckVscyA9IHRoaXMuZ2V0Q2hpbGRTZWxlY3RlZEFuY2hvclRhZ3MoZWRpdG9ySWQpO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIGNoaWxkQW5jaG9yRWxzLmxlbmd0aCA+IDAgfHwgKCEhYW5jaG9yRWwgJiYgISFhbmNob3JFbC5ocmVmKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UGFyZW50KGVsZW1lbnQ6IEVsZW1lbnQsIHRhZzogc3RyaW5nKTogRWxlbWVudCB7XG4gICAgbGV0IGN1cnJlbnROb2RlID0gZWxlbWVudDtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUudGFnTmFtZS50b1VwcGVyQ2FzZSgpICE9PSAnQk9EWScpIHtcbiAgICAgIGlmIChjdXJyZW50Tm9kZS50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09IHRhZy50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50Tm9kZTtcbiAgICAgIH1cbiAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUucGFyZW50RWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZWRpdG9yU2VsZWN0ZWQoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvblNlcnZpY2UuaXNFbGVtZW50U2VsZWN0ZWQoZG9jdW1lbnRFbCwgZG9jdW1lbnRFbC5ib2R5KTtcbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHByaXZhdGUgaW5zZXJ0SHRtbEluSUUxMShpZDogc3RyaW5nLCBodG1sOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcbiAgICBjb25zdCB3aW5kb3dFbCA9IHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKTtcbiAgICBjb25zdCBzZWwgPSB3aW5kb3dFbC5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsLmdldFJhbmdlQXQgJiYgc2VsLnJhbmdlQ291bnQpIHtcbiAgICAgIGxldCByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuICAgICAgcmFuZ2UuZGVsZXRlQ29udGVudHMoKTtcblxuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudEVsLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgZWwuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGNvbnN0IGZyYWcgPSBkb2N1bWVudEVsLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgIGxldCBub2RlLCBsYXN0Tm9kZTtcbiAgICAgIHdoaWxlIChlbC5maXJzdENoaWxkKSB7XG4gICAgICAgIG5vZGUgPSBlbC5maXJzdENoaWxkO1xuICAgICAgICBsYXN0Tm9kZSA9IGZyYWcuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgICByYW5nZS5pbnNlcnROb2RlKGZyYWcpO1xuXG4gICAgICAvLyBQcmVzZXJ2ZSB0aGUgc2VsZWN0aW9uXG4gICAgICBpZiAobGFzdE5vZGUpIHtcbiAgICAgICAgcmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobGFzdE5vZGUpO1xuICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICAgICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2xlYW5VcEJsYW5rU3R5bGVUYWdzKGRvYzogRG9jdW1lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBvcnBoYW5FbGVtZW50czogSFRNTEVsZW1lbnRbXSA9IEFycmF5LmZyb20oXG4gICAgICBkb2MucXVlcnlTZWxlY3RvckFsbCgnZm9udCxzcGFuLCpbc3R5bGU9XCJcIl0nKVxuICAgICk7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIG9ycGhhbkVsZW1lbnRzKSB7XG4gICAgICBpZiAoIWVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzdHlsZScpKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByZW1vdmFibGVFbGVtZW50cyA9IG9ycGhhbkVsZW1lbnRzLmZpbHRlcigoZWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgdGFnTmFtZSA9IGVsZW1lbnQudGFnTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgKHRhZ05hbWUgPT09ICdGT05UJyB8fCB0YWdOYW1lID09PSAnU1BBTicpICYmXG4gICAgICAgIChlbGVtZW50LmF0dHJpYnV0ZXMubGVuZ3RoID09PSAwIHx8ICFlbGVtZW50Lmhhc0NoaWxkTm9kZXMpXG4gICAgICApO1xuICAgIH0pO1xuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiByZW1vdmFibGVFbGVtZW50cykge1xuICAgICAgY29uc3QgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgd2hpbGUgKGVsZW1lbnQuZmlyc3RDaGlsZCkge1xuICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZWxlbWVudC5maXJzdENoaWxkLCBlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ2VydGFpbiB2YWx1ZXMgYXJlIGVuY29kZWQgaW4gaHRtbCBhbmQgbmVlZCB0byBiZSBkZWNvZGVkXG4gIHByaXZhdGUgcmVwbGFjZUh0bWxDb2RlcyhzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHN0clxuICAgICAgLnJlcGxhY2UoLyZuYnNwOy8sIFN0cmluZy5mcm9tQ2hhckNvZGUoMTYwKSlcbiAgICAgIC5yZXBsYWNlKC8mbHQ7L2csICc8JylcbiAgICAgIC5yZXBsYWNlKC8mZ3Q7L2csICc+JylcbiAgICAgIC5yZXBsYWNlKC8mYW1wOy9nLCAnJicpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRFZGl0b3JEaXNhYmxlZChcbiAgICBpZDogc3RyaW5nLFxuICAgIGZvY3VzYWJsZUNoaWxkcmVuOiBIVE1MRWxlbWVudFtdLFxuICAgIHRleHRFZGl0b3JOYXRpdmVFbGVtZW50OiBhbnksXG4gICAgZGlzYWJsZWQ6IGJvb2xlYW5cbiAgKTogdm9pZCB7XG4gICAgdGV4dEVkaXRvck5hdGl2ZUVsZW1lbnQuc3R5bGUucG9pbnRlckV2ZW50cyA9IGRpc2FibGVkID8gJ25vbmUnIDogJ2F1dG8nO1xuICAgIHRleHRFZGl0b3JOYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShcbiAgICAgICdhcmlhLWRpc2FibGVkJyxcbiAgICAgIGRpc2FibGVkID8gJ3RydWUnIDogJ2ZhbHNlJ1xuICAgICk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoZm9jdXNhYmxlQ2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgZm9jdXNhYmxlQ2hpbGRyZW4uZm9yRWFjaCgoYUZvY3VzYWJsZUNoaWxkKSA9PiB7XG4gICAgICAgIGFGb2N1c2FibGVDaGlsZC50YWJJbmRleCA9IGRpc2FibGVkID8gLTEgOiAwO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZCkuYm9keS5zZXRBdHRyaWJ1dGUoXG4gICAgICAnY29udGVudGVkaXRhYmxlJyxcbiAgICAgIGRpc2FibGVkID8gJ2ZhbHNlJyA6ICd0cnVlJ1xuICAgICk7XG4gIH1cbn1cbiJdfQ==