@flogeez/angular-tiptap-editor 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/esm2022/flogeez-angular-tiptap-editor.mjs +5 -0
  3. package/esm2022/lib/ate-editor.provider.mjs +38 -0
  4. package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +207 -0
  5. package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +133 -0
  6. package/esm2022/lib/components/bubble-menus/color/ate-color-bubble-menu.component.mjs +365 -0
  7. package/esm2022/lib/components/bubble-menus/image/ate-image-bubble-menu.component.mjs +226 -0
  8. package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +247 -0
  9. package/esm2022/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.mjs +121 -0
  10. package/esm2022/lib/components/bubble-menus/table/ate-table-bubble-menu.component.mjs +266 -0
  11. package/esm2022/lib/components/bubble-menus/text/ate-bubble-menu.component.mjs +294 -0
  12. package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +122 -0
  13. package/esm2022/lib/components/edit-toggle/ate-edit-toggle.component.mjs +42 -0
  14. package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +953 -0
  15. package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +329 -0
  16. package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +531 -0
  17. package/esm2022/lib/components/ui/ate-button.component.mjs +90 -0
  18. package/esm2022/lib/components/ui/ate-separator.component.mjs +31 -0
  19. package/esm2022/lib/config/ate-editor.config.mjs +76 -0
  20. package/esm2022/lib/config/ate-global-config.token.mjs +6 -0
  21. package/esm2022/lib/config/ate-slash-commands.config.mjs +130 -0
  22. package/esm2022/lib/directives/ate-noop-value-accessor.directive.mjs +40 -0
  23. package/esm2022/lib/extensions/ate-link-click-behavior.extension.mjs +32 -0
  24. package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +270 -0
  25. package/esm2022/lib/extensions/ate-table.extension.mjs +29 -0
  26. package/esm2022/lib/extensions/ate-tiptap-state.extension.mjs +85 -0
  27. package/esm2022/lib/extensions/ate-upload-progress.extension.mjs +195 -0
  28. package/esm2022/lib/extensions/calculators/ate-discovery.calculator.mjs +62 -0
  29. package/esm2022/lib/extensions/calculators/ate-image.calculator.mjs +8 -0
  30. package/esm2022/lib/extensions/calculators/ate-marks.calculator.mjs +75 -0
  31. package/esm2022/lib/extensions/calculators/ate-selection.calculator.mjs +35 -0
  32. package/esm2022/lib/extensions/calculators/ate-structure.calculator.mjs +34 -0
  33. package/esm2022/lib/extensions/calculators/ate-table.calculator.mjs +38 -0
  34. package/esm2022/lib/models/ate-bubble-menu.model.mjs +49 -0
  35. package/esm2022/lib/models/ate-editor-config.model.mjs +2 -0
  36. package/esm2022/lib/models/ate-editor-state.model.mjs +90 -0
  37. package/esm2022/lib/models/ate-image.model.mjs +2 -0
  38. package/esm2022/lib/models/ate-toolbar.model.mjs +35 -0
  39. package/esm2022/lib/node-view/ate-angular-node-view.mjs +97 -0
  40. package/esm2022/lib/node-view/ate-injector.registry.mjs +16 -0
  41. package/esm2022/lib/node-view/ate-node-view.factory.mjs +125 -0
  42. package/esm2022/lib/node-view/ate-node-view.models.mjs +2 -0
  43. package/esm2022/lib/node-view/ate-node-view.renderer.mjs +154 -0
  44. package/esm2022/lib/node-view/ate-register-angular-component.mjs +49 -0
  45. package/esm2022/lib/services/ate-color-picker.service.mjs +193 -0
  46. package/esm2022/lib/services/ate-editor-commands.service.mjs +465 -0
  47. package/esm2022/lib/services/ate-i18n.service.mjs +410 -0
  48. package/esm2022/lib/services/ate-image.service.mjs +368 -0
  49. package/esm2022/lib/services/ate-link.service.mjs +97 -0
  50. package/esm2022/lib/utils/ate-color.utils.mjs +60 -0
  51. package/esm2022/public-api.mjs +93 -0
  52. package/fesm2022/flogeez-angular-tiptap-editor.mjs +313 -346
  53. package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
  54. package/index.d.ts +3 -1673
  55. package/lib/ate-editor.provider.d.ts +21 -0
  56. package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +71 -0
  57. package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +60 -0
  58. package/lib/components/bubble-menus/color/ate-color-bubble-menu.component.d.ts +77 -0
  59. package/lib/components/bubble-menus/image/ate-image-bubble-menu.component.d.ts +52 -0
  60. package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +55 -0
  61. package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +12 -0
  62. package/lib/components/bubble-menus/table/ate-table-bubble-menu.component.d.ts +24 -0
  63. package/lib/components/bubble-menus/text/ate-bubble-menu.component.d.ts +53 -0
  64. package/lib/components/color-picker/ate-color-picker.component.d.ts +54 -0
  65. package/lib/components/edit-toggle/ate-edit-toggle.component.d.ts +13 -0
  66. package/lib/components/editor/angular-tiptap-editor.component.d.ts +235 -0
  67. package/lib/components/slash-commands/ate-slash-commands.component.d.ts +43 -0
  68. package/lib/components/toolbar/ate-toolbar.component.d.ts +47 -0
  69. package/lib/components/ui/ate-button.component.d.ts +25 -0
  70. package/lib/components/ui/ate-separator.component.d.ts +7 -0
  71. package/lib/config/ate-editor.config.d.ts +7 -0
  72. package/lib/config/ate-global-config.token.d.ts +6 -0
  73. package/lib/config/ate-slash-commands.config.d.ts +41 -0
  74. package/lib/directives/ate-noop-value-accessor.directive.d.ts +13 -0
  75. package/lib/extensions/ate-link-click-behavior.extension.d.ts +2 -0
  76. package/lib/extensions/ate-resizable-image.extension.d.ts +27 -0
  77. package/lib/extensions/ate-table.extension.d.ts +2 -0
  78. package/lib/extensions/ate-tiptap-state.extension.d.ts +7 -0
  79. package/lib/extensions/ate-upload-progress.extension.d.ts +7 -0
  80. package/lib/extensions/calculators/ate-discovery.calculator.d.ts +7 -0
  81. package/lib/extensions/calculators/ate-image.calculator.d.ts +2 -0
  82. package/lib/extensions/calculators/ate-marks.calculator.d.ts +2 -0
  83. package/lib/extensions/calculators/ate-selection.calculator.d.ts +2 -0
  84. package/lib/extensions/calculators/ate-structure.calculator.d.ts +2 -0
  85. package/lib/extensions/calculators/ate-table.calculator.d.ts +2 -0
  86. package/lib/models/ate-bubble-menu.model.d.ts +33 -0
  87. package/lib/models/ate-editor-config.model.d.ts +100 -0
  88. package/lib/models/ate-editor-state.model.d.ts +109 -0
  89. package/lib/models/ate-image.model.d.ts +104 -0
  90. package/lib/models/ate-toolbar.model.d.ts +18 -0
  91. package/lib/node-view/ate-angular-node-view.d.ts +115 -0
  92. package/lib/node-view/ate-injector.registry.d.ts +3 -0
  93. package/lib/node-view/ate-node-view.factory.d.ts +10 -0
  94. package/lib/node-view/ate-node-view.models.d.ts +138 -0
  95. package/lib/node-view/ate-node-view.renderer.d.ts +23 -0
  96. package/lib/node-view/ate-register-angular-component.d.ts +35 -0
  97. package/lib/services/ate-color-picker.service.d.ts +65 -0
  98. package/lib/services/ate-editor-commands.service.d.ts +72 -0
  99. package/lib/services/ate-i18n.service.d.ts +394 -0
  100. package/lib/services/ate-image.service.d.ts +71 -0
  101. package/lib/services/ate-link.service.d.ts +42 -0
  102. package/lib/utils/ate-color.utils.d.ts +12 -0
  103. package/package.json +3 -1
  104. package/public-api.d.ts +112 -0
@@ -0,0 +1,270 @@
1
+ import { Node, mergeAttributes, nodeInputRule } from "@tiptap/core";
2
+ export const AteResizableImage = Node.create({
3
+ name: "resizableImage",
4
+ addOptions() {
5
+ return {
6
+ inline: false,
7
+ allowBase64: false,
8
+ HTMLAttributes: {},
9
+ };
10
+ },
11
+ inline() {
12
+ return this.options.inline;
13
+ },
14
+ group() {
15
+ return this.options.inline ? "inline" : "block";
16
+ },
17
+ draggable: true,
18
+ addAttributes() {
19
+ return {
20
+ src: {
21
+ default: null,
22
+ },
23
+ alt: {
24
+ default: null,
25
+ },
26
+ title: {
27
+ default: null,
28
+ },
29
+ width: {
30
+ default: null,
31
+ parseHTML: element => {
32
+ const width = element.getAttribute("width");
33
+ return width ? parseInt(width, 10) : null;
34
+ },
35
+ renderHTML: attributes => {
36
+ if (!attributes["width"]) {
37
+ return {};
38
+ }
39
+ return {
40
+ width: attributes["width"],
41
+ };
42
+ },
43
+ },
44
+ height: {
45
+ default: null,
46
+ parseHTML: element => {
47
+ const height = element.getAttribute("height");
48
+ return height ? parseInt(height, 10) : null;
49
+ },
50
+ renderHTML: attributes => {
51
+ if (!attributes["height"]) {
52
+ return {};
53
+ }
54
+ return {
55
+ height: attributes["height"],
56
+ };
57
+ },
58
+ },
59
+ };
60
+ },
61
+ parseHTML() {
62
+ return [
63
+ {
64
+ tag: "img[src]",
65
+ },
66
+ ];
67
+ },
68
+ renderHTML({ HTMLAttributes }) {
69
+ return ["img", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
70
+ },
71
+ addCommands() {
72
+ return {
73
+ setResizableImage: options => ({ commands }) => {
74
+ return commands.insertContent({
75
+ type: this.name,
76
+ attrs: options,
77
+ }, {
78
+ updateSelection: true,
79
+ });
80
+ },
81
+ updateResizableImage: options => ({ commands }) => {
82
+ return commands.updateAttributes(this.name, options);
83
+ },
84
+ };
85
+ },
86
+ addInputRules() {
87
+ return [
88
+ nodeInputRule({
89
+ find: /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/,
90
+ type: this.type,
91
+ getAttributes: match => {
92
+ const [, alt, src, title] = match;
93
+ return { src, alt, title };
94
+ },
95
+ }),
96
+ ];
97
+ },
98
+ addNodeView() {
99
+ return ({ node, getPos, editor }) => {
100
+ const container = document.createElement("div");
101
+ container.className = "resizable-image-container";
102
+ container.style.position = "relative";
103
+ container.style.display = "inline-block";
104
+ const img = document.createElement("img");
105
+ img.src = node.attrs["src"];
106
+ img.alt = node.attrs["alt"] || "";
107
+ img.title = node.attrs["title"] || "";
108
+ img.className = "ate-image";
109
+ if (node.attrs["width"]) {
110
+ img.width = node.attrs["width"];
111
+ }
112
+ if (node.attrs["height"]) {
113
+ img.height = node.attrs["height"];
114
+ }
115
+ img.parentNode?.insertBefore(container, img);
116
+ container.appendChild(img);
117
+ // Add modern resize controls
118
+ const resizeControls = document.createElement("div");
119
+ resizeControls.className = "resize-controls";
120
+ resizeControls.style.display = "none";
121
+ // Create 8 handles for full resizing capability
122
+ const handles = ["nw", "n", "ne", "w", "e", "sw", "s", "se"];
123
+ handles.forEach(direction => {
124
+ const handle = document.createElement("div");
125
+ handle.className = `resize-handle resize-handle-${direction}`;
126
+ handle.setAttribute("data-direction", direction);
127
+ resizeControls.appendChild(handle);
128
+ });
129
+ // Attach controls to container
130
+ container.appendChild(resizeControls);
131
+ // Variables for resizing
132
+ let isResizing = false;
133
+ let startX = 0;
134
+ let startY = 0;
135
+ let startWidth = 0;
136
+ let startHeight = 0;
137
+ let aspectRatio = 1;
138
+ // Calculate aspect ratio
139
+ img.onload = () => {
140
+ aspectRatio = img.naturalWidth / img.naturalHeight;
141
+ };
142
+ // Resizing logic
143
+ const handleMouseDown = (e, direction) => {
144
+ e.preventDefault();
145
+ e.stopPropagation();
146
+ isResizing = true;
147
+ startX = e.clientX;
148
+ startY = e.clientY;
149
+ // Use current image dimensions instead of initial ones
150
+ startWidth =
151
+ parseInt(img.getAttribute("width") || "0") || node.attrs["width"] || img.naturalWidth;
152
+ startHeight =
153
+ parseInt(img.getAttribute("height") || "0") || node.attrs["height"] || img.naturalHeight;
154
+ // Add resizing class to body
155
+ document.body.classList.add("resizing");
156
+ const handleMouseMove = (e) => {
157
+ if (!isResizing) {
158
+ return;
159
+ }
160
+ const deltaX = e.clientX - startX;
161
+ const deltaY = e.clientY - startY;
162
+ let newWidth = startWidth;
163
+ let newHeight = startHeight;
164
+ // Resize according to direction
165
+ switch (direction) {
166
+ case "e":
167
+ newWidth = startWidth + deltaX;
168
+ newHeight = newWidth / aspectRatio;
169
+ break;
170
+ case "w":
171
+ newWidth = startWidth - deltaX;
172
+ newHeight = newWidth / aspectRatio;
173
+ break;
174
+ case "s":
175
+ newHeight = startHeight + deltaY;
176
+ newWidth = newHeight * aspectRatio;
177
+ break;
178
+ case "n":
179
+ newHeight = startHeight - deltaY;
180
+ newWidth = newHeight * aspectRatio;
181
+ break;
182
+ case "se":
183
+ newWidth = startWidth + deltaX;
184
+ newHeight = startHeight + deltaY;
185
+ break;
186
+ case "sw":
187
+ newWidth = startWidth - deltaX;
188
+ newHeight = startHeight + deltaY;
189
+ break;
190
+ case "ne":
191
+ newWidth = startWidth + deltaX;
192
+ newHeight = startHeight - deltaY;
193
+ break;
194
+ case "nw":
195
+ newWidth = startWidth - deltaX;
196
+ newHeight = startHeight - deltaY;
197
+ break;
198
+ }
199
+ // Limits
200
+ newWidth = Math.max(50, Math.min(2000, newWidth));
201
+ newHeight = Math.max(50, Math.min(2000, newHeight));
202
+ // Update image attributes directly
203
+ img.setAttribute("width", Math.round(newWidth).toString());
204
+ img.setAttribute("height", Math.round(newHeight).toString());
205
+ };
206
+ const handleMouseUp = () => {
207
+ isResizing = false;
208
+ document.body.classList.remove("resizing");
209
+ // Update Tiptap node with new dimensions
210
+ if (typeof getPos === "function") {
211
+ const finalWidth = parseInt(img.getAttribute("width") || "0");
212
+ const finalHeight = parseInt(img.getAttribute("height") || "0");
213
+ if (finalWidth && finalHeight) {
214
+ editor.commands.updateAttributes("resizableImage", {
215
+ width: finalWidth,
216
+ height: finalHeight,
217
+ });
218
+ }
219
+ }
220
+ document.removeEventListener("mousemove", handleMouseMove);
221
+ document.removeEventListener("mouseup", handleMouseUp);
222
+ };
223
+ document.addEventListener("mousemove", handleMouseMove);
224
+ document.addEventListener("mouseup", handleMouseUp);
225
+ };
226
+ // Add events to handles
227
+ resizeControls.addEventListener("mousedown", e => {
228
+ const target = e.target;
229
+ if (target.classList.contains("resize-handle")) {
230
+ const direction = target.getAttribute("data-direction");
231
+ if (direction) {
232
+ handleMouseDown(e, direction);
233
+ }
234
+ }
235
+ });
236
+ // Proper selection management via ProseMirror lifecycle
237
+ const selectNode = () => {
238
+ resizeControls.style.display = "block";
239
+ container.classList.add("selected");
240
+ img.classList.add("selected");
241
+ };
242
+ const deselectNode = () => {
243
+ resizeControls.style.display = "none";
244
+ container.classList.remove("selected");
245
+ img.classList.remove("selected");
246
+ };
247
+ return {
248
+ dom: container,
249
+ selectNode,
250
+ deselectNode,
251
+ update: updatedNode => {
252
+ if (updatedNode.type.name !== "resizableImage") {
253
+ return false;
254
+ }
255
+ img.src = updatedNode.attrs["src"];
256
+ img.alt = updatedNode.attrs["alt"] || "";
257
+ img.title = updatedNode.attrs["title"] || "";
258
+ if (updatedNode.attrs["width"]) {
259
+ img.width = updatedNode.attrs["width"];
260
+ }
261
+ if (updatedNode.attrs["height"]) {
262
+ img.height = updatedNode.attrs["height"];
263
+ }
264
+ return true;
265
+ },
266
+ };
267
+ };
268
+ },
269
+ });
270
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXJlc2l6YWJsZS1pbWFnZS5leHRlbnNpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRpcHRhcC1lZGl0b3Ivc3JjL2xpYi9leHRlbnNpb25zL2F0ZS1yZXNpemFibGUtaW1hZ2UuZXh0ZW5zaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQTZCcEUsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBMkI7SUFDckUsSUFBSSxFQUFFLGdCQUFnQjtJQUV0QixVQUFVO1FBQ1IsT0FBTztZQUNMLE1BQU0sRUFBRSxLQUFLO1lBQ2IsV0FBVyxFQUFFLEtBQUs7WUFDbEIsY0FBYyxFQUFFLEVBQUU7U0FDbkIsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNO1FBQ0osT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUM3QixDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ2xELENBQUM7SUFFRCxTQUFTLEVBQUUsSUFBSTtJQUVmLGFBQWE7UUFDWCxPQUFPO1lBQ0wsR0FBRyxFQUFFO2dCQUNILE9BQU8sRUFBRSxJQUFJO2FBQ2Q7WUFDRCxHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxFQUFFLElBQUk7YUFDZDtZQUNELEtBQUssRUFBRTtnQkFDTCxPQUFPLEVBQUUsSUFBSTthQUNkO1lBQ0QsS0FBSyxFQUFFO2dCQUNMLE9BQU8sRUFBRSxJQUFJO2dCQUNiLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRTtvQkFDbkIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFD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QkFDZixDQUFDO29CQUVELEdBQUcsQ0FBQyxHQUFHLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDbkMsR0FBRyxDQUFDLEdBQUcsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDekMsR0FBRyxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFFN0MsSUFBSSxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7d0JBQy9CLEdBQUcsQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDekMsQ0FBQztvQkFDRCxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQzt3QkFDaEMsR0FBRyxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUMzQyxDQUFDO29CQUVELE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7YUFDRixDQUFDO1FBQ0osQ0FBQyxDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5vZGUsIG1lcmdlQXR0cmlidXRlcywgbm9kZUlucHV0UnVsZSB9IGZyb20gXCJAdGlwdGFwL2NvcmVcIjtcblxuZXhwb3J0IGludGVyZmFjZSBBdGVSZXNpemFibGVJbWFnZU9wdGlvbnMge1xuICBpbmxpbmU6IGJvb2xlYW47XG4gIGFsbG93QmFzZTY0OiBib29sZWFuO1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmRlY2xhcmUgbW9kdWxlIFwiQHRpcHRhcC9jb3JlXCIge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHJlc2l6YWJsZUltYWdlOiB7XG4gICAgICBzZXRSZXNpemFibGVJbWFnZTogKG9wdGlvbnM6IHtcbiAgICAgICAgc3JjOiBzdHJpbmc7XG4gICAgICAgIGFsdD86IHN0cmluZztcbiAgICAgICAgdGl0bGU/OiBzdHJpbmc7XG4gICAgICAgIHdpZHRoPzogbnVtYmVyO1xuICAgICAgICBoZWlnaHQ/OiBudW1iZXI7XG4gICAgICB9KSA9PiBSZXR1cm5UeXBlO1xuICAgICAgdXBkYXRlUmVzaXphYmxlSW1hZ2U6IChvcHRpb25zOiB7XG4gICAgICAgIHNyYz86IHN0cmluZztcbiAgICAgICAgYWx0Pzogc3RyaW5nO1xuICAgICAgICB0aXRsZT86IHN0cmluZztcbiAgICAgICAgd2lkdGg/OiBudW1iZXI7XG4gICAgICAgIGhlaWdodD86IG51bWJlcjtcbiAgICAgIH0pID0+IFJldHVyblR5cGU7XG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgQXRlUmVzaXphYmxlSW1hZ2UgPSBOb2RlLmNyZWF0ZTxBdGVSZXNpemFibGVJbWFnZU9wdGlvbnM+KHtcbiAgbmFtZTogXCJyZXNpemFibGVJbWFnZVwiLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlubGluZTogZmFsc2UsXG4gICAgICBhbGxvd0Jhc2U2NDogZmFsc2UsXG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgfTtcbiAgfSxcblxuICBpbmxpbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5pbmxpbmU7XG4gIH0sXG5cbiAgZ3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5pbmxpbmUgPyBcImlubGluZVwiIDogXCJibG9ja1wiO1xuICB9LFxuXG4gIGRyYWdnYWJsZTogdHJ1ZSxcblxuICBhZGRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzcmM6IHtcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBhbHQ6IHtcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0aXRsZToge1xuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHdpZHRoOiB7XG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICAgIHBhcnNlSFRNTDogZWxlbWVudCA9PiB7XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBlbGVtZW50LmdldEF0dHJpYnV0ZShcIndpZHRoXCIpO1xuICAgICAgICAgIHJldHVybiB3aWR0aCA/IHBhcnNlSW50KHdpZHRoLCAxMCkgOiBudWxsO1xuICAgICAgICB9LFxuICAgICAgICByZW5kZXJIVE1MOiBhdHRyaWJ1dGVzID0+IHtcbiAgICAgICAgICBpZiAoIWF0dHJpYnV0ZXNbXCJ3aWR0aFwiXSkge1xuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2lkdGg6IGF0dHJpYnV0ZXNbXCJ3aWR0aFwiXSxcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGhlaWdodDoge1xuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIpO1xuICAgICAgICAgIHJldHVybiBoZWlnaHQgPyBwYXJzZUludChoZWlnaHQsIDEwKSA6IG51bGw7XG4gICAgICAgIH0sXG4gICAgICAgIHJlbmRlckhUTUw6IGF0dHJpYnV0ZXMgPT4ge1xuICAgICAgICAgIGlmICghYXR0cmlidXRlc1tcImhlaWdodFwiXSkge1xuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVpZ2h0OiBhdHRyaWJ1dGVzW1wiaGVpZ2h0XCJdLFxuICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogXCJpbWdbc3JjXVwiLFxuICAgICAgfSxcbiAgICBdO1xuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFtcImltZ1wiLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyldO1xuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZXRSZXNpemFibGVJbWFnZTpcbiAgICAgICAgb3B0aW9ucyA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmluc2VydENvbnRlbnQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgICAgYXR0cnM6IG9wdGlvbnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1cGRhdGVTZWxlY3Rpb246IHRydWUsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgIHVwZGF0ZVJlc2l6YWJsZUltYWdlOlxuICAgICAgICBvcHRpb25zID0+XG4gICAgICAgICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMudXBkYXRlQXR0cmlidXRlcyh0aGlzLm5hbWUsIG9wdGlvbnMpO1xuICAgICAgICB9LFxuICAgIH07XG4gIH0sXG5cbiAgYWRkSW5wdXRSdWxlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbm9kZUlucHV0UnVsZSh7XG4gICAgICAgIGZpbmQ6IC8hXFxbKC4rfDo/KV1cXCgoXFxTKykoPzooPzpcXHMrKVtcIiddKFxcUyspW1wiJ10pP1xcKS8sXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgZ2V0QXR0cmlidXRlczogbWF0Y2ggPT4ge1xuICAgICAgICAgIGNvbnN0IFssIGFsdCwgc3JjLCB0aXRsZV0gPSBtYXRjaDtcbiAgICAgICAgICByZXR1cm4geyBzcmMsIGFsdCwgdGl0bGUgfTtcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF07XG4gIH0sXG5cbiAgYWRkTm9kZVZpZXcoKSB7XG4gICAgcmV0dXJuICh7IG5vZGUsIGdldFBvcywgZWRpdG9yIH0pID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBjb250YWluZXIuY2xhc3NOYW1lID0gXCJyZXNpemFibGUtaW1hZ2UtY29udGFpbmVyXCI7XG4gICAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG4gICAgICBjb250YWluZXIuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XG5cbiAgICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XG4gICAgICBpbWcuc3JjID0gbm9kZS5hdHRyc1tcInNyY1wiXTtcbiAgICAgIGltZy5hbHQgPSBub2RlLmF0dHJzW1wiYWx0XCJdIHx8IFwiXCI7XG4gICAgICBpbWcudGl0bGUgPSBub2RlLmF0dHJzW1widGl0bGVcIl0gfHwgXCJcIjtcbiAgICAgIGltZy5jbGFzc05hbWUgPSBcImF0ZS1pbWFnZVwiO1xuXG4gICAgICBpZiAobm9kZS5hdHRyc1tcIndpZHRoXCJdKSB7XG4gICAgICAgIGltZy53aWR0aCA9IG5vZGUuYXR0cnNbXCJ3aWR0aFwiXTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLmF0dHJzW1wiaGVpZ2h0XCJdKSB7XG4gICAgICAgIGltZy5oZWlnaHQgPSBub2RlLmF0dHJzW1wiaGVpZ2h0XCJdO1xuICAgICAgfVxuXG4gICAgICBpbWcucGFyZW50Tm9kZT8uaW5zZXJ0QmVmb3JlKGNvbnRhaW5lciwgaW1nKTtcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChpbWcpO1xuXG4gICAgICAvLyBBZGQgbW9kZXJuIHJlc2l6ZSBjb250cm9sc1xuICAgICAgY29uc3QgcmVzaXplQ29udHJvbHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgcmVzaXplQ29udHJvbHMuY2xhc3NOYW1lID0gXCJyZXNpemUtY29udHJvbHNcIjtcbiAgICAgIHJlc2l6ZUNvbnRyb2xzLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcblxuICAgICAgLy8gQ3JlYXRlIDggaGFuZGxlcyBmb3IgZnVsbCByZXNpemluZyBjYXBhYmlsaXR5XG4gICAgICBjb25zdCBoYW5kbGVzID0gW1wibndcIiwgXCJuXCIsIFwibmVcIiwgXCJ3XCIsIFwiZVwiLCBcInN3XCIsIFwic1wiLCBcInNlXCJdO1xuICAgICAgaGFuZGxlcy5mb3JFYWNoKGRpcmVjdGlvbiA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIGhhbmRsZS5jbGFzc05hbWUgPSBgcmVzaXplLWhhbmRsZSByZXNpemUtaGFuZGxlLSR7ZGlyZWN0aW9ufWA7XG4gICAgICAgIGhhbmRsZS5zZXRBdHRyaWJ1dGUoXCJkYXRhLWRpcmVjdGlvblwiLCBkaXJlY3Rpb24pO1xuICAgICAgICByZXNpemVDb250cm9scy5hcHBlbmRDaGlsZChoYW5kbGUpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEF0dGFjaCBjb250cm9scyB0byBjb250YWluZXJcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChyZXNpemVDb250cm9scyk7XG5cbiAgICAgIC8vIFZhcmlhYmxlcyBmb3IgcmVzaXppbmdcbiAgICAgIGxldCBpc1Jlc2l6aW5nID0gZmFsc2U7XG4gICAgICBsZXQgc3RhcnRYID0gMDtcbiAgICAgIGxldCBzdGFydFkgPSAwO1xuICAgICAgbGV0IHN0YXJ0V2lkdGggPSAwO1xuICAgICAgbGV0IHN0YXJ0SGVpZ2h0ID0gMDtcbiAgICAgIGxldCBhc3BlY3RSYXRpbyA9IDE7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBhc3BlY3QgcmF0aW9cbiAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGFzcGVjdFJhdGlvID0gaW1nLm5hdHVyYWxXaWR0aCAvIGltZy5uYXR1cmFsSGVpZ2h0O1xuICAgICAgfTtcblxuICAgICAgLy8gUmVzaXppbmcgbG9naWNcbiAgICAgIGNvbnN0IGhhbmRsZU1vdXNlRG93biA9IChlOiBNb3VzZUV2ZW50LCBkaXJlY3Rpb246IHN0cmluZykgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgaXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgIHN0YXJ0WCA9IGUuY2xpZW50WDtcbiAgICAgICAgc3RhcnRZID0gZS5jbGllbnRZO1xuXG4gICAgICAgIC8vIFVzZSBjdXJyZW50IGltYWdlIGRpbWVuc2lvbnMgaW5zdGVhZCBvZiBpbml0aWFsIG9uZXNcbiAgICAgICAgc3RhcnRXaWR0aCA9XG4gICAgICAgICAgcGFyc2VJbnQoaW1nLmdldEF0dHJpYnV0ZShcIndpZHRoXCIpIHx8IFwiMFwiKSB8fCBub2RlLmF0dHJzW1wid2lkdGhcIl0gfHwgaW1nLm5hdHVyYWxXaWR0aDtcbiAgICAgICAgc3RhcnRIZWlnaHQgPVxuICAgICAgICAgIHBhcnNlSW50KGltZy5nZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIikgfHwgXCIwXCIpIHx8IG5vZGUuYXR0cnNbXCJoZWlnaHRcIl0gfHwgaW1nLm5hdHVyYWxIZWlnaHQ7XG5cbiAgICAgICAgLy8gQWRkIHJlc2l6aW5nIGNsYXNzIHRvIGJvZHlcbiAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwicmVzaXppbmdcIik7XG5cbiAgICAgICAgY29uc3QgaGFuZGxlTW91c2VNb3ZlID0gKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICBpZiAoIWlzUmVzaXppbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBkZWx0YVggPSBlLmNsaWVudFggLSBzdGFydFg7XG4gICAgICAgICAgY29uc3QgZGVsdGFZID0gZS5jbGllbnRZIC0gc3RhcnRZO1xuXG4gICAgICAgICAgbGV0IG5ld1dpZHRoID0gc3RhcnRXaWR0aDtcbiAgICAgICAgICBsZXQgbmV3SGVpZ2h0ID0gc3RhcnRIZWlnaHQ7XG5cbiAgICAgICAgICAvLyBSZXNpemUgYWNjb3JkaW5nIHRvIGRpcmVjdGlvblxuICAgICAgICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIFwiZVwiOlxuICAgICAgICAgICAgICBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggKyBkZWx0YVg7XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IG5ld1dpZHRoIC8gYXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIndcIjpcbiAgICAgICAgICAgICAgbmV3V2lkdGggPSBzdGFydFdpZHRoIC0gZGVsdGFYO1xuICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBuZXdXaWR0aCAvIGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzXCI6XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IHN0YXJ0SGVpZ2h0ICsgZGVsdGFZO1xuICAgICAgICAgICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCAqIGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJuXCI6XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IHN0YXJ0SGVpZ2h0IC0gZGVsdGFZO1xuICAgICAgICAgICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCAqIGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzZVwiOlxuICAgICAgICAgICAgICBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggKyBkZWx0YVg7XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IHN0YXJ0SGVpZ2h0ICsgZGVsdGFZO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzd1wiOlxuICAgICAgICAgICAgICBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggLSBkZWx0YVg7XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IHN0YXJ0SGVpZ2h0ICsgZGVsdGFZO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJuZVwiOlxuICAgICAgICAgICAgICBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggKyBkZWx0YVg7XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IHN0YXJ0SGVpZ2h0IC0gZGVsdGFZO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJud1wiOlxuICAgICAgICAgICAgICBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggLSBkZWx0YVg7XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IHN0YXJ0SGVpZ2h0IC0gZGVsdGFZO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBMaW1pdHNcbiAgICAgICAgICBuZXdXaWR0aCA9IE1hdGgubWF4KDUwLCBNYXRoLm1pbigyMDAwLCBuZXdXaWR0aCkpO1xuICAgICAgICAgIG5ld0hlaWdodCA9IE1hdGgubWF4KDUwLCBNYXRoLm1pbigyMDAwLCBuZXdIZWlnaHQpKTtcblxuICAgICAgICAgIC8vIFVwZGF0ZSBpbWFnZSBhdHRyaWJ1dGVzIGRpcmVjdGx5XG4gICAgICAgICAgaW1nLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIE1hdGgucm91bmQobmV3V2lkdGgpLnRvU3RyaW5nKCkpO1xuICAgICAgICAgIGltZy5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgTWF0aC5yb3VuZChuZXdIZWlnaHQpLnRvU3RyaW5nKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGhhbmRsZU1vdXNlVXAgPSAoKSA9PiB7XG4gICAgICAgICAgaXNSZXNpemluZyA9IGZhbHNlO1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcInJlc2l6aW5nXCIpO1xuXG4gICAgICAgICAgLy8gVXBkYXRlIFRpcHRhcCBub2RlIHdpdGggbmV3IGRpbWVuc2lvbnNcbiAgICAgICAgICBpZiAodHlwZW9mIGdldFBvcyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBjb25zdCBmaW5hbFdpZHRoID0gcGFyc2VJbnQoaW1nLmdldEF0dHJpYnV0ZShcIndpZHRoXCIpIHx8IFwiMFwiKTtcbiAgICAgICAgICAgIGNvbnN0IGZpbmFsSGVpZ2h0ID0gcGFyc2VJbnQoaW1nLmdldEF0dHJpYnV0ZShcImhlaWdodFwiKSB8fCBcIjBcIik7XG5cbiAgICAgICAgICAgIGlmIChmaW5hbFdpZHRoICYmIGZpbmFsSGVpZ2h0KSB7XG4gICAgICAgICAgICAgIGVkaXRvci5jb21tYW5kcy51cGRhdGVBdHRyaWJ1dGVzKFwicmVzaXphYmxlSW1hZ2VcIiwge1xuICAgICAgICAgICAgICAgIHdpZHRoOiBmaW5hbFdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogZmluYWxIZWlnaHQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgaGFuZGxlTW91c2VNb3ZlKTtcbiAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBoYW5kbGVNb3VzZVVwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIGhhbmRsZU1vdXNlTW92ZSk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIGhhbmRsZU1vdXNlVXApO1xuICAgICAgfTtcblxuICAgICAgLy8gQWRkIGV2ZW50cyB0byBoYW5kbGVzXG4gICAgICByZXNpemVDb250cm9scy5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIGUgPT4ge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKHRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoXCJyZXNpemUtaGFuZGxlXCIpKSB7XG4gICAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShcImRhdGEtZGlyZWN0aW9uXCIpO1xuICAgICAgICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIGhhbmRsZU1vdXNlRG93bihlLCBkaXJlY3Rpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFByb3BlciBzZWxlY3Rpb24gbWFuYWdlbWVudCB2aWEgUHJvc2VNaXJyb3IgbGlmZWN5Y2xlXG4gICAgICBjb25zdCBzZWxlY3ROb2RlID0gKCkgPT4ge1xuICAgICAgICByZXNpemVDb250cm9scy5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICBjb250YWluZXIuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpO1xuICAgICAgICBpbWcuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgZGVzZWxlY3ROb2RlID0gKCkgPT4ge1xuICAgICAgICByZXNpemVDb250cm9scy5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgICAgIGNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIik7XG4gICAgICAgIGltZy5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIik7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkb206IGNvbnRhaW5lcixcbiAgICAgICAgc2VsZWN0Tm9kZSxcbiAgICAgICAgZGVzZWxlY3ROb2RlLFxuICAgICAgICB1cGRhdGU6IHVwZGF0ZWROb2RlID0+IHtcbiAgICAgICAgICBpZiAodXBkYXRlZE5vZGUudHlwZS5uYW1lICE9PSBcInJlc2l6YWJsZUltYWdlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpbWcuc3JjID0gdXBkYXRlZE5vZGUuYXR0cnNbXCJzcmNcIl07XG4gICAgICAgICAgaW1nLmFsdCA9IHVwZGF0ZWROb2RlLmF0dHJzW1wiYWx0XCJdIHx8IFwiXCI7XG4gICAgICAgICAgaW1nLnRpdGxlID0gdXBkYXRlZE5vZGUuYXR0cnNbXCJ0aXRsZVwiXSB8fCBcIlwiO1xuXG4gICAgICAgICAgaWYgKHVwZGF0ZWROb2RlLmF0dHJzW1wid2lkdGhcIl0pIHtcbiAgICAgICAgICAgIGltZy53aWR0aCA9IHVwZGF0ZWROb2RlLmF0dHJzW1wid2lkdGhcIl07XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh1cGRhdGVkTm9kZS5hdHRyc1tcImhlaWdodFwiXSkge1xuICAgICAgICAgICAgaW1nLmhlaWdodCA9IHVwZGF0ZWROb2RlLmF0dHJzW1wiaGVpZ2h0XCJdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9O1xuICB9LFxufSk7XG4iXX0=
@@ -0,0 +1,29 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Table } from "@tiptap/extension-table";
3
+ import { TableRow } from "@tiptap/extension-table-row";
4
+ import { TableCell } from "@tiptap/extension-table-cell";
5
+ import { TableHeader } from "@tiptap/extension-table-header";
6
+ export const AteTableExtension = Extension.create({
7
+ name: "tableExtension",
8
+ addExtensions() {
9
+ return [
10
+ Table.configure({
11
+ resizable: true,
12
+ handleWidth: 5,
13
+ cellMinWidth: 100,
14
+ }),
15
+ TableRow,
16
+ TableHeader.configure({
17
+ HTMLAttributes: {
18
+ class: "table-header",
19
+ },
20
+ }),
21
+ TableCell.configure({
22
+ HTMLAttributes: {
23
+ class: "table-cell",
24
+ },
25
+ }),
26
+ ];
27
+ },
28
+ });
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXRhYmxlLmV4dGVuc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2V4dGVuc2lvbnMvYXRlLXRhYmxlLmV4dGVuc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU3RCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQ2hELElBQUksRUFBRSxnQkFBZ0I7SUFFdEIsYUFBYTtRQUNYLE9BQU87WUFDTCxLQUFLLENBQUMsU0FBUyxDQUFDO2dCQUNkLFNBQVMsRUFBRSxJQUFJO2dCQUNmLFdBQVcsRUFBRSxDQUFDO2dCQUNkLFlBQVksRUFBRSxHQUFHO2FBQ2xCLENBQUM7WUFDRixRQUFRO1lBQ1IsV0FBVyxDQUFDLFNBQVMsQ0FBQztnQkFDcEIsY0FBYyxFQUFFO29CQUNkLEtBQUssRUFBRSxjQUFjO2lCQUN0QjthQUNGLENBQUM7WUFDRixTQUFTLENBQUMsU0FBUyxDQUFDO2dCQUNsQixjQUFjLEVBQUU7b0JBQ2QsS0FBSyxFQUFFLFlBQVk7aUJBQ3BCO2FBQ0YsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSBcIkB0aXB0YXAvY29yZVwiO1xuaW1wb3J0IHsgVGFibGUgfSBmcm9tIFwiQHRpcHRhcC9leHRlbnNpb24tdGFibGVcIjtcbmltcG9ydCB7IFRhYmxlUm93IH0gZnJvbSBcIkB0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlLXJvd1wiO1xuaW1wb3J0IHsgVGFibGVDZWxsIH0gZnJvbSBcIkB0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlLWNlbGxcIjtcbmltcG9ydCB7IFRhYmxlSGVhZGVyIH0gZnJvbSBcIkB0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlLWhlYWRlclwiO1xuXG5leHBvcnQgY29uc3QgQXRlVGFibGVFeHRlbnNpb24gPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogXCJ0YWJsZUV4dGVuc2lvblwiLFxuXG4gIGFkZEV4dGVuc2lvbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIFRhYmxlLmNvbmZpZ3VyZSh7XG4gICAgICAgIHJlc2l6YWJsZTogdHJ1ZSxcbiAgICAgICAgaGFuZGxlV2lkdGg6IDUsXG4gICAgICAgIGNlbGxNaW5XaWR0aDogMTAwLFxuICAgICAgfSksXG4gICAgICBUYWJsZVJvdyxcbiAgICAgIFRhYmxlSGVhZGVyLmNvbmZpZ3VyZSh7XG4gICAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgY2xhc3M6IFwidGFibGUtaGVhZGVyXCIsXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIFRhYmxlQ2VsbC5jb25maWd1cmUoe1xuICAgICAgICBIVE1MQXR0cmlidXRlczoge1xuICAgICAgICAgIGNsYXNzOiBcInRhYmxlLWNlbGxcIixcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF07XG4gIH0sXG59KTtcbiJdfQ==
@@ -0,0 +1,85 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
3
+ import { ATE_INITIAL_EDITOR_STATE, } from "../models/ate-editor-state.model";
4
+ /**
5
+ * High-performance flat property merger.
6
+ * Processes sub-objects (marks, can, nodes) property by property.
7
+ */
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ function fastMerge(target, source) {
10
+ if (!source) {
11
+ return;
12
+ }
13
+ for (const key in source) {
14
+ const sourceVal = source[key];
15
+ // If the value is an object (marks, can, nodes, selection)
16
+ if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal)) {
17
+ if (!target[key]) {
18
+ target[key] = {};
19
+ }
20
+ // Merge internal properties
21
+ for (const subKey in sourceVal) {
22
+ const subVal = sourceVal[subKey];
23
+ // TRUE priority rule for boolean state categories
24
+ if (typeof subVal === "boolean" && (key === "marks" || key === "can" || key === "nodes")) {
25
+ target[key][subKey] = target[key][subKey] || subVal;
26
+ }
27
+ else {
28
+ target[key][subKey] = subVal;
29
+ }
30
+ }
31
+ }
32
+ else {
33
+ // Simple value (isFocused, isEditable)
34
+ target[key] = sourceVal;
35
+ }
36
+ }
37
+ }
38
+ function createFreshSnapshot() {
39
+ return JSON.parse(JSON.stringify(ATE_INITIAL_EDITOR_STATE));
40
+ }
41
+ export const AteTiptapStateExtension = Extension.create({
42
+ name: "ateTiptapState",
43
+ addOptions() {
44
+ return {
45
+ onUpdate: undefined,
46
+ calculators: [],
47
+ };
48
+ },
49
+ addProseMirrorPlugins() {
50
+ return [
51
+ new Plugin({
52
+ key: new PluginKey("tiptapState"),
53
+ view: () => ({
54
+ update: _view => {
55
+ const { editor } = this;
56
+ if (!editor) {
57
+ return;
58
+ }
59
+ const snapshot = createFreshSnapshot();
60
+ const calcs = this.options.calculators;
61
+ for (const calculator of calcs) {
62
+ try {
63
+ const partial = calculator(editor);
64
+ fastMerge(snapshot, partial);
65
+ }
66
+ catch (e) {
67
+ console.error("TiptapStateExtension: Calculator error", e);
68
+ }
69
+ }
70
+ if (this.options.onUpdate) {
71
+ this.options.onUpdate(snapshot);
72
+ }
73
+ },
74
+ }),
75
+ }),
76
+ ];
77
+ },
78
+ onFocus() {
79
+ this.editor.view.dispatch(this.editor.state.tr.setMeta("tiptapStateForceUpdate", true));
80
+ },
81
+ onBlur() {
82
+ this.editor.view.dispatch(this.editor.state.tr.setMeta("tiptapStateForceUpdate", true));
83
+ },
84
+ });
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXRpcHRhcC1zdGF0ZS5leHRlbnNpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRpcHRhcC1lZGl0b3Ivc3JjL2xpYi9leHRlbnNpb25zL2F0ZS10aXB0YXAtc3RhdGUuZXh0ZW5zaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRCxPQUFPLEVBRUwsd0JBQXdCLEdBRXpCLE1BQU0sa0NBQWtDLENBQUM7QUFPMUM7OztHQUdHO0FBQ0gsOERBQThEO0FBQzlELFNBQVMsU0FBUyxDQUFDLE1BQVcsRUFBRSxNQUFXO0lBQ3pDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU87SUFDVCxDQUFDO0lBRUQsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUN6QixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFOUIsMkRBQTJEO1FBQzNELElBQUksU0FBUyxLQUFLLElBQUksSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDckYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNqQixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ25CLENBQUM7WUFFRCw0QkFBNEI7WUFDNUIsS0FBSyxNQUFNLE1BQU0sSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNqQyxrREFBa0Q7Z0JBQ2xELElBQUksT0FBTyxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxHQUFHLEtBQUssS0FBSyxJQUFJLEdBQUcsS0FBSyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUN6RixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQztnQkFDdEQsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUM7Z0JBQy9CLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTix1Q0FBdUM7WUFDdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLG1CQUFtQjtJQUMxQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUVELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQXdCO0lBQzdFLElBQUksRUFBRSxnQkFBZ0I7SUFFdEIsVUFBVTtRQUNSLE9BQU87WUFDTCxRQUFRLEVBQUUsU0FBUztZQUNuQixXQUFXLEVBQUUsRUFBRTtTQUNoQixDQUFDO0lBQ0osQ0FBQztJQUVELHFCQUFxQjtRQUNuQixPQUFPO1lBQ0wsSUFBSSxNQUFNLENBQUM7Z0JBQ1QsR0FBRyxFQUFFLElBQUksU0FBUyxDQUFDLGFBQWEsQ0FBQztnQkFDakMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7b0JBQ1gsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUFFO3dCQUNkLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUM7d0JBQ3hCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzs0QkFDWixPQUFPO3dCQUNULENBQUM7d0JBRUQsTUFBTSxRQUFRLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQzt3QkFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7d0JBRXZDLEtBQUssTUFBTSxVQUFVLElBQUksS0FBSyxFQUFFLENBQUM7NEJBQy9CLElBQUksQ0FBQztnQ0FDSCxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7Z0NBQ25DLFNBQVMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7NEJBQy9CLENBQUM7NEJBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQ0FDWCxPQUFPLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxFQUFFLENBQUMsQ0FBQyxDQUFDOzRCQUM3RCxDQUFDO3dCQUNILENBQUM7d0JBRUQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDOzRCQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDbEMsQ0FBQztvQkFDSCxDQUFDO2lCQUNGLENBQUM7YUFDSCxDQUFDO1NBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLHdCQUF3QixFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQztDQUNGLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gXCJAdGlwdGFwL2NvcmVcIjtcbmltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSBcIkB0aXB0YXAvcG0vc3RhdGVcIjtcbmltcG9ydCB7XG4gIEF0ZUVkaXRvclN0YXRlU25hcHNob3QsXG4gIEFURV9JTklUSUFMX0VESVRPUl9TVEFURSxcbiAgQXRlU3RhdGVDYWxjdWxhdG9yLFxufSBmcm9tIFwiLi4vbW9kZWxzL2F0ZS1lZGl0b3Itc3RhdGUubW9kZWxcIjtcblxuZXhwb3J0IGludGVyZmFjZSBBdGVUaXB0YXBTdGF0ZU9wdGlvbnMge1xuICBvblVwZGF0ZT86IChzdGF0ZTogQXRlRWRpdG9yU3RhdGVTbmFwc2hvdCkgPT4gdm9pZDtcbiAgY2FsY3VsYXRvcnM6IEF0ZVN0YXRlQ2FsY3VsYXRvcltdO1xufVxuXG4vKipcbiAqIEhpZ2gtcGVyZm9ybWFuY2UgZmxhdCBwcm9wZXJ0eSBtZXJnZXIuXG4gKiBQcm9jZXNzZXMgc3ViLW9iamVjdHMgKG1hcmtzLCBjYW4sIG5vZGVzKSBwcm9wZXJ0eSBieSBwcm9wZXJ0eS5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmZ1bmN0aW9uIGZhc3RNZXJnZSh0YXJnZXQ6IGFueSwgc291cmNlOiBhbnkpIHtcbiAgaWYgKCFzb3VyY2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICBjb25zdCBzb3VyY2VWYWwgPSBzb3VyY2Vba2V5XTtcblxuICAgIC8vIElmIHRoZSB2YWx1ZSBpcyBhbiBvYmplY3QgKG1hcmtzLCBjYW4sIG5vZGVzLCBzZWxlY3Rpb24pXG4gICAgaWYgKHNvdXJjZVZhbCAhPT0gbnVsbCAmJiB0eXBlb2Ygc291cmNlVmFsID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHNvdXJjZVZhbCkpIHtcbiAgICAgIGlmICghdGFyZ2V0W2tleV0pIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSB7fTtcbiAgICAgIH1cblxuICAgICAgLy8gTWVyZ2UgaW50ZXJuYWwgcHJvcGVydGllc1xuICAgICAgZm9yIChjb25zdCBzdWJLZXkgaW4gc291cmNlVmFsKSB7XG4gICAgICAgIGNvbnN0IHN1YlZhbCA9IHNvdXJjZVZhbFtzdWJLZXldO1xuICAgICAgICAvLyBUUlVFIHByaW9yaXR5IHJ1bGUgZm9yIGJvb2xlYW4gc3RhdGUgY2F0ZWdvcmllc1xuICAgICAgICBpZiAodHlwZW9mIHN1YlZhbCA9PT0gXCJib29sZWFuXCIgJiYgKGtleSA9PT0gXCJtYXJrc1wiIHx8IGtleSA9PT0gXCJjYW5cIiB8fCBrZXkgPT09IFwibm9kZXNcIikpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XVtzdWJLZXldID0gdGFyZ2V0W2tleV1bc3ViS2V5XSB8fCBzdWJWYWw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGFyZ2V0W2tleV1bc3ViS2V5XSA9IHN1YlZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTaW1wbGUgdmFsdWUgKGlzRm9jdXNlZCwgaXNFZGl0YWJsZSlcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlVmFsO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVGcmVzaFNuYXBzaG90KCk6IEF0ZUVkaXRvclN0YXRlU25hcHNob3Qge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShBVEVfSU5JVElBTF9FRElUT1JfU1RBVEUpKTtcbn1cblxuZXhwb3J0IGNvbnN0IEF0ZVRpcHRhcFN0YXRlRXh0ZW5zaW9uID0gRXh0ZW5zaW9uLmNyZWF0ZTxBdGVUaXB0YXBTdGF0ZU9wdGlvbnM+KHtcbiAgbmFtZTogXCJhdGVUaXB0YXBTdGF0ZVwiLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9uVXBkYXRlOiB1bmRlZmluZWQsXG4gICAgICBjYWxjdWxhdG9yczogW10sXG4gICAgfTtcbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoXCJ0aXB0YXBTdGF0ZVwiKSxcbiAgICAgICAgdmlldzogKCkgPT4gKHtcbiAgICAgICAgICB1cGRhdGU6IF92aWV3ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzO1xuICAgICAgICAgICAgaWYgKCFlZGl0b3IpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGNyZWF0ZUZyZXNoU25hcHNob3QoKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbGNzID0gdGhpcy5vcHRpb25zLmNhbGN1bGF0b3JzO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNhbGN1bGF0b3Igb2YgY2FsY3MpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsID0gY2FsY3VsYXRvcihlZGl0b3IpO1xuICAgICAgICAgICAgICAgIGZhc3RNZXJnZShzbmFwc2hvdCwgcGFydGlhbCk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiVGlwdGFwU3RhdGVFeHRlbnNpb246IENhbGN1bGF0b3IgZXJyb3JcIiwgZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5vblVwZGF0ZSkge1xuICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMub25VcGRhdGUoc25hcHNob3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSksXG4gICAgXTtcbiAgfSxcblxuICBvbkZvY3VzKCkge1xuICAgIHRoaXMuZWRpdG9yLnZpZXcuZGlzcGF0Y2godGhpcy5lZGl0b3Iuc3RhdGUudHIuc2V0TWV0YShcInRpcHRhcFN0YXRlRm9yY2VVcGRhdGVcIiwgdHJ1ZSkpO1xuICB9LFxuXG4gIG9uQmx1cigpIHtcbiAgICB0aGlzLmVkaXRvci52aWV3LmRpc3BhdGNoKHRoaXMuZWRpdG9yLnN0YXRlLnRyLnNldE1ldGEoXCJ0aXB0YXBTdGF0ZUZvcmNlVXBkYXRlXCIsIHRydWUpKTtcbiAgfSxcbn0pO1xuIl19