@copilotkitnext/angular 0.0.2 → 0.0.5

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 (173) hide show
  1. package/README.md +3 -3
  2. package/dist/README.md +3 -3
  3. package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
  4. package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
  5. package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
  6. package/dist/core/copilotkit.providers.d.ts +1 -1
  7. package/dist/core/copilotkit.service.d.ts +5 -5
  8. package/dist/core/copilotkit.types.d.ts +8 -10
  9. package/dist/directives/copilotkit-frontend-tool.directive.d.ts +1 -1
  10. package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
  11. package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
  12. package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
  13. package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
  14. package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
  15. package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
  16. package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
  17. package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
  18. package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
  19. package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
  20. package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
  21. package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
  22. package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
  23. package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
  24. package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
  25. package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
  26. package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
  27. package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
  28. package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
  29. package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
  30. package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
  31. package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
  32. package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
  33. package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
  34. package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
  35. package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
  36. package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
  37. package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
  38. package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
  39. package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
  40. package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
  41. package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
  42. package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
  43. package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
  44. package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
  45. package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
  46. package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
  47. package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
  48. package/dist/esm2022/core/copilotkit.service.mjs +426 -0
  49. package/dist/esm2022/core/copilotkit.types.mjs +13 -0
  50. package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
  51. package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
  52. package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
  53. package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
  54. package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +128 -0
  55. package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +265 -0
  56. package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
  57. package/dist/esm2022/index.mjs +70 -0
  58. package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
  59. package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
  60. package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
  61. package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
  62. package/dist/esm2022/lib/utils.mjs +10 -0
  63. package/dist/esm2022/services/resize-observer.service.mjs +152 -0
  64. package/dist/esm2022/services/scroll-position.service.mjs +124 -0
  65. package/dist/esm2022/types/frontend-tool.mjs +2 -0
  66. package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
  67. package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
  68. package/dist/esm2022/utils/agent.utils.mjs +204 -0
  69. package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
  70. package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
  71. package/dist/esm2022/utils/frontend-tool.utils.mjs +224 -0
  72. package/dist/esm2022/utils/human-in-the-loop.utils.mjs +293 -0
  73. package/dist/fesm2022/copilotkitnext-angular.mjs +174 -187
  74. package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
  75. package/dist/utils/frontend-tool.utils.d.ts +1 -1
  76. package/package.json +23 -20
  77. package/vitest.config.mts +32 -21
  78. package/.turbo/turbo-build.log +0 -38
  79. package/.turbo/turbo-check-types.log +0 -0
  80. package/.turbo/turbo-test.log +0 -71
  81. package/ng-package.json +0 -19
  82. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  83. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  84. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  85. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  86. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  87. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  88. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  89. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  90. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  91. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  92. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  93. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  94. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  95. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  96. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  97. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  98. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  99. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  100. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  101. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  102. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  103. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  104. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  105. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  106. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  107. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  108. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  109. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  110. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  111. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  112. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  113. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  114. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  115. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  116. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  117. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  118. package/src/components/chat/copilot-chat.component.ts +0 -232
  119. package/src/components/copilotkit-tool-render.component.ts +0 -169
  120. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  121. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  122. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  123. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  124. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  125. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  126. package/src/core/copilotkit.providers.ts +0 -59
  127. package/src/core/copilotkit.service.ts +0 -542
  128. package/src/core/copilotkit.types.ts +0 -132
  129. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  130. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  131. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  132. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  133. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  134. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  135. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  136. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  137. package/src/directives/copilotkit-agent.directive.ts +0 -225
  138. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  139. package/src/directives/copilotkit-config.directive.ts +0 -81
  140. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  141. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  142. package/src/directives/stick-to-bottom.directive.ts +0 -204
  143. package/src/index.ts +0 -105
  144. package/src/lib/directives/tooltip.directive.ts +0 -292
  145. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  146. package/src/lib/slots/copilot-slot.component.ts +0 -135
  147. package/src/lib/slots/index.ts +0 -3
  148. package/src/lib/slots/slot.types.ts +0 -64
  149. package/src/lib/slots/slot.utils.ts +0 -289
  150. package/src/lib/utils.ts +0 -10
  151. package/src/public-api.ts +0 -1
  152. package/src/services/resize-observer.service.ts +0 -181
  153. package/src/services/scroll-position.service.ts +0 -169
  154. package/src/styles/globals.css +0 -266
  155. package/src/styles/index.css +0 -3
  156. package/src/test-setup.ts +0 -15
  157. package/src/testing/index.ts +0 -3
  158. package/src/testing/testing.utils.ts +0 -248
  159. package/src/types/frontend-tool.ts +0 -44
  160. package/src/types/human-in-the-loop.ts +0 -52
  161. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  162. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  163. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  164. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  165. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  166. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  167. package/src/utils/agent-context.utils.ts +0 -133
  168. package/src/utils/agent.utils.ts +0 -239
  169. package/src/utils/chat-config.utils.ts +0 -221
  170. package/src/utils/copilotkit.utils.ts +0 -20
  171. package/src/utils/frontend-tool.utils.ts +0 -266
  172. package/src/utils/human-in-the-loop.utils.ts +0 -359
  173. package/tsconfig.spec.json +0 -12
@@ -0,0 +1,293 @@
1
+ import { DestroyRef, inject, signal } from '@angular/core';
2
+ import { CopilotKitService } from '../core/copilotkit.service';
3
+ import { ToolCallStatus } from '../core/copilotkit.types';
4
+ /**
5
+ * Registers a human-in-the-loop tool that requires user interaction.
6
+ * Must be called within an injection context.
7
+ * Automatically cleans up when the component/service is destroyed.
8
+ *
9
+ * @param tool - The human-in-the-loop tool configuration
10
+ * @returns The tool ID
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * export class ApprovalComponent {
15
+ * toolId = registerHumanInTheLoop({
16
+ * name: 'requireApproval',
17
+ * description: 'Requires user approval',
18
+ * args: z.object({ action: z.string() }),
19
+ * render: ApprovalDialogComponent
20
+ * });
21
+ * }
22
+ * ```
23
+ */
24
+ export function registerHumanInTheLoop(tool) {
25
+ const service = inject(CopilotKitService);
26
+ const destroyRef = inject(DestroyRef);
27
+ // Create state management
28
+ const statusSignal = signal(ToolCallStatus.InProgress);
29
+ let resolvePromise = null;
30
+ // Create respond function
31
+ const respond = async (result) => {
32
+ if (resolvePromise) {
33
+ resolvePromise(result);
34
+ statusSignal.set(ToolCallStatus.Complete);
35
+ resolvePromise = null;
36
+ }
37
+ };
38
+ // Create handler that returns a Promise
39
+ const handler = async (_args) => {
40
+ return new Promise((resolve) => {
41
+ statusSignal.set(ToolCallStatus.Executing);
42
+ resolvePromise = resolve;
43
+ });
44
+ };
45
+ // Create enhanced render function
46
+ const enhancedRender = createEnhancedRender(tool.render, statusSignal, respond);
47
+ // Create the frontend tool
48
+ const frontendTool = {
49
+ ...tool,
50
+ handler,
51
+ render: enhancedRender
52
+ };
53
+ // Add the tool (returns void, so we use the tool name as ID)
54
+ service.copilotkit.addTool(frontendTool);
55
+ const toolId = frontendTool.name;
56
+ // Register tool render if provided
57
+ if (frontendTool.render) {
58
+ service.registerToolRender(frontendTool.name, {
59
+ name: frontendTool.name,
60
+ render: frontendTool.render
61
+ });
62
+ }
63
+ // Cleanup on destroy
64
+ destroyRef.onDestroy(() => {
65
+ service.copilotkit.removeTool(toolId);
66
+ if (frontendTool.render) {
67
+ service.unregisterToolRender(frontendTool.name);
68
+ }
69
+ });
70
+ return toolId;
71
+ }
72
+ /**
73
+ * Adds a human-in-the-loop tool with explicit service parameter.
74
+ * Returns a cleanup function.
75
+ *
76
+ * @param service - The CopilotKitService instance
77
+ * @param tool - The human-in-the-loop tool configuration
78
+ * @returns Cleanup function to remove the tool
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * export class MyComponent implements OnInit, OnDestroy {
83
+ * private cleanup?: () => void;
84
+ *
85
+ * constructor(private copilotkit: CopilotKitService) {}
86
+ *
87
+ * ngOnInit() {
88
+ * this.cleanup = addHumanInTheLoop(this.copilotkit, {
89
+ * name: 'requireApproval',
90
+ * description: 'Requires user approval',
91
+ * args: z.object({ action: z.string() }),
92
+ * render: ApprovalDialogComponent
93
+ * });
94
+ * }
95
+ *
96
+ * ngOnDestroy() {
97
+ * this.cleanup?.();
98
+ * }
99
+ * }
100
+ * ```
101
+ */
102
+ export function addHumanInTheLoop(service, tool) {
103
+ // Create state management
104
+ const statusSignal = signal(ToolCallStatus.InProgress);
105
+ let resolvePromise = null;
106
+ // Create respond function
107
+ const respond = async (result) => {
108
+ if (resolvePromise) {
109
+ resolvePromise(result);
110
+ statusSignal.set(ToolCallStatus.Complete);
111
+ resolvePromise = null;
112
+ }
113
+ };
114
+ // Create handler that returns a Promise
115
+ const handler = async (_args) => {
116
+ return new Promise((resolve) => {
117
+ statusSignal.set(ToolCallStatus.Executing);
118
+ resolvePromise = resolve;
119
+ });
120
+ };
121
+ // Create enhanced render function
122
+ const enhancedRender = createEnhancedRender(tool.render, statusSignal, respond);
123
+ // Create the frontend tool
124
+ const frontendTool = {
125
+ ...tool,
126
+ handler,
127
+ render: enhancedRender
128
+ };
129
+ // Add the tool (returns void, so we use the tool name as ID)
130
+ service.copilotkit.addTool(frontendTool);
131
+ const toolId = frontendTool.name;
132
+ // Register tool render if provided
133
+ if (frontendTool.render) {
134
+ service.registerToolRender(frontendTool.name, {
135
+ name: frontendTool.name,
136
+ render: frontendTool.render
137
+ });
138
+ }
139
+ // Return cleanup function
140
+ return () => {
141
+ service.copilotkit.removeTool(toolId);
142
+ if (frontendTool.render) {
143
+ service.unregisterToolRender(frontendTool.name);
144
+ }
145
+ };
146
+ }
147
+ /**
148
+ * Creates a human-in-the-loop tool with dynamic update capabilities.
149
+ *
150
+ * @param service - The CopilotKitService instance
151
+ * @param tool - The human-in-the-loop tool configuration
152
+ * @returns Object with status signal, update and destroy methods
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * export class MyComponent {
157
+ * humanInTheLoop = createHumanInTheLoop(this.copilotkit, {
158
+ * name: 'requireApproval',
159
+ * description: 'Requires user approval',
160
+ * args: z.object({ action: z.string() }),
161
+ * render: ApprovalDialogComponent
162
+ * });
163
+ *
164
+ * updateDescription(newDesc: string) {
165
+ * this.humanInTheLoop.update({ description: newDesc });
166
+ * }
167
+ *
168
+ * ngOnDestroy() {
169
+ * this.humanInTheLoop.destroy();
170
+ * }
171
+ * }
172
+ * ```
173
+ */
174
+ export function createHumanInTheLoop(service, tool) {
175
+ // Create state management
176
+ const statusSignal = signal(ToolCallStatus.InProgress);
177
+ let currentTool = { ...tool };
178
+ let toolId = '';
179
+ let resolvePromise = null;
180
+ // Create respond function
181
+ const respond = async (result) => {
182
+ if (resolvePromise) {
183
+ resolvePromise(result);
184
+ statusSignal.set(ToolCallStatus.Complete);
185
+ resolvePromise = null;
186
+ }
187
+ };
188
+ // Create handler that returns a Promise
189
+ const handler = async (_args) => {
190
+ return new Promise((resolve) => {
191
+ statusSignal.set(ToolCallStatus.Executing);
192
+ resolvePromise = resolve;
193
+ });
194
+ };
195
+ // Function to add the tool
196
+ const addTool = () => {
197
+ // Create enhanced render function
198
+ const enhancedRender = createEnhancedRender(currentTool.render, statusSignal, respond);
199
+ // Create the frontend tool
200
+ const frontendTool = {
201
+ ...currentTool,
202
+ handler,
203
+ render: enhancedRender
204
+ };
205
+ // Add tool (returns void, so we use the tool name as ID)
206
+ service.copilotkit.addTool(frontendTool);
207
+ toolId = frontendTool.name;
208
+ // Register tool render if provided
209
+ if (frontendTool.render) {
210
+ service.registerToolRender(frontendTool.name, {
211
+ name: frontendTool.name,
212
+ render: frontendTool.render
213
+ });
214
+ }
215
+ };
216
+ // Initialize the tool
217
+ addTool();
218
+ return {
219
+ status: statusSignal.asReadonly(),
220
+ toolId,
221
+ update: (updates) => {
222
+ // Remove old tool
223
+ service.copilotkit.removeTool(toolId);
224
+ if (currentTool.render) {
225
+ service.unregisterToolRender(currentTool.name);
226
+ }
227
+ // Update tool configuration
228
+ currentTool = { ...currentTool, ...updates };
229
+ // Re-add with new configuration
230
+ addTool();
231
+ },
232
+ destroy: () => {
233
+ service.copilotkit.removeTool(toolId);
234
+ if (currentTool.render) {
235
+ service.unregisterToolRender(currentTool.name);
236
+ }
237
+ }
238
+ };
239
+ }
240
+ /**
241
+ * Creates an enhanced render function that injects the respond function
242
+ * when the status is 'executing'.
243
+ */
244
+ function createEnhancedRender(originalRender, _statusSignal, _respond) {
245
+ // For component classes, we need to create a wrapper
246
+ if (isComponentClass(originalRender)) {
247
+ // Return a wrapper component factory
248
+ // This is complex in Angular and would require dynamic component creation
249
+ // For now, we'll return the original and rely on prop injection
250
+ return originalRender;
251
+ }
252
+ // For templates, we can't easily wrap them
253
+ // The template context will be enhanced in the render component
254
+ return originalRender;
255
+ }
256
+ /**
257
+ * Helper function to check if a value is a component class
258
+ */
259
+ function isComponentClass(value) {
260
+ return typeof value === 'function' && value.prototype;
261
+ }
262
+ /**
263
+ * Enhanced component wrapper for human-in-the-loop.
264
+ * This would be used internally by the tool render component to inject
265
+ * the respond function based on status.
266
+ *
267
+ * @internal
268
+ */
269
+ export function enhancePropsForHumanInTheLoop(props, status, respond) {
270
+ if (status === ToolCallStatus.Executing && respond) {
271
+ return {
272
+ ...props,
273
+ status: ToolCallStatus.Executing,
274
+ respond
275
+ };
276
+ }
277
+ if (status === ToolCallStatus.Complete) {
278
+ return {
279
+ ...props,
280
+ status: ToolCallStatus.Complete,
281
+ result: typeof props.result === 'string' ? props.result : '',
282
+ respond: undefined
283
+ };
284
+ }
285
+ // InProgress
286
+ return {
287
+ ...props,
288
+ status: ToolCallStatus.InProgress,
289
+ result: undefined,
290
+ respond: undefined
291
+ };
292
+ }
293
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVtYW4taW4tdGhlLWxvb3AudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvaHVtYW4taW4tdGhlLWxvb3AudXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFVBQVUsRUFDVixNQUFNLEVBQ04sTUFBTSxFQUlQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFFTCxjQUFjLEVBSWYsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FDcEMsSUFBOEI7SUFFOUIsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDMUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXRDLDBCQUEwQjtJQUMxQixNQUFNLFlBQVksR0FBRyxNQUFNLENBQWlCLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN2RSxJQUFJLGNBQWMsR0FBdUMsSUFBSSxDQUFDO0lBRTlELDBCQUEwQjtJQUMxQixNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsTUFBZSxFQUFpQixFQUFFO1FBQ3ZELElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZCLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLHdDQUF3QztJQUN4QyxNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBUSxFQUFvQixFQUFFO1FBQ25ELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixZQUFZLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMzQyxjQUFjLEdBQUcsT0FBTyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsa0NBQWtDO0lBQ2xDLE1BQU0sY0FBYyxHQUFHLG9CQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRWhGLDJCQUEyQjtJQUMzQixNQUFNLFlBQVksR0FBMkI7UUFDM0MsR0FBRyxJQUFJO1FBQ1AsT0FBTztRQUNQLE1BQU0sRUFBRSxjQUFjO0tBQ3ZCLENBQUM7SUFFRiw2REFBNkQ7SUFDN0QsT0FBTyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDekMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQztJQUVqQyxtQ0FBbUM7SUFDbkMsSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDeEIsT0FBTyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUU7WUFDNUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJO1lBQ3ZCLE1BQU0sRUFBRSxZQUFZLENBQUMsTUFBTTtTQUM1QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQscUJBQXFCO0lBQ3JCLFVBQVUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ3hCLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RDLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3hCLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEQsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsT0FBMEIsRUFDMUIsSUFBOEI7SUFFOUIsMEJBQTBCO0lBQzFCLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBaUIsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZFLElBQUksY0FBYyxHQUF1QyxJQUFJLENBQUM7SUFFOUQsMEJBQTBCO0lBQzFCLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFBRSxNQUFlLEVBQWlCLEVBQUU7UUFDdkQsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdkIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDMUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsd0NBQXdDO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFBRSxLQUFRLEVBQW9CLEVBQUU7UUFDbkQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzdCLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzNDLGNBQWMsR0FBRyxPQUFPLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUM7SUFFRixrQ0FBa0M7SUFDbEMsTUFBTSxjQUFjLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFaEYsMkJBQTJCO0lBQzNCLE1BQU0sWUFBWSxHQUEyQjtRQUMzQyxHQUFHLElBQUk7UUFDUCxPQUFPO1FBQ1AsTUFBTSxFQUFFLGNBQWM7S0FDdkIsQ0FBQztJQUVGLDZEQUE2RDtJQUM3RCxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN6QyxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDO0lBRWpDLG1DQUFtQztJQUNuQyxJQUFJLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN4QixPQUFPLENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRTtZQUM1QyxJQUFJLEVBQUUsWUFBWSxDQUFDLElBQUk7WUFDdkIsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNO1NBQzVCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsT0FBTyxHQUFHLEVBQUU7UUFDVixPQUFPLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0QyxJQUFJLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN4QixPQUFPLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xELENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxPQUEwQixFQUMxQixJQUE4QjtJQUU5QiwwQkFBMEI7SUFDMUIsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFpQixjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdkUsSUFBSSxXQUFXLEdBQUcsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0lBQzlCLElBQUksTUFBTSxHQUFXLEVBQUUsQ0FBQztJQUN4QixJQUFJLGNBQWMsR0FBdUMsSUFBSSxDQUFDO0lBRTlELDBCQUEwQjtJQUMxQixNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsTUFBZSxFQUFpQixFQUFFO1FBQ3ZELElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZCLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLHdDQUF3QztJQUN4QyxNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBUSxFQUFvQixFQUFFO1FBQ25ELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixZQUFZLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMzQyxjQUFjLEdBQUcsT0FBTyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsMkJBQTJCO0lBQzNCLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRTtRQUNuQixrQ0FBa0M7UUFDbEMsTUFBTSxjQUFjLEdBQUcsb0JBQW9CLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFdkYsMkJBQTJCO1FBQzNCLE1BQU0sWUFBWSxHQUEyQjtZQUMzQyxHQUFHLFdBQVc7WUFDZCxPQUFPO1lBQ1AsTUFBTSxFQUFFLGNBQWM7U0FDdkIsQ0FBQztRQUVGLHlEQUF5RDtRQUN6RCxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6QyxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQztRQUUzQixtQ0FBbUM7UUFDbkMsSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDeEIsT0FBTyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUU7Z0JBQzVDLElBQUksRUFBRSxZQUFZLENBQUMsSUFBSTtnQkFDdkIsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNO2FBQzVCLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixzQkFBc0I7SUFDdEIsT0FBTyxFQUFFLENBQUM7SUFFVixPQUFPO1FBQ0wsTUFBTSxFQUFFLFlBQVksQ0FBQyxVQUFVLEVBQUU7UUFDakMsTUFBTTtRQUNOLE1BQU0sRUFBRSxDQUFDLE9BQTBDLEVBQUUsRUFBRTtZQUNyRCxrQkFBa0I7WUFDbEIsT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZCLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakQsQ0FBQztZQUVELDRCQUE0QjtZQUM1QixXQUFXLEdBQUcsRUFBRSxHQUFHLFdBQVcsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDO1lBRTdDLGdDQUFnQztZQUNoQyxPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7UUFDRCxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQ1osT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZCLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakQsQ0FBQztRQUNILENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsb0JBQW9CLENBQzNCLGNBQStELEVBQy9ELGFBQXFDLEVBQ3JDLFFBQTRDO0lBRTVDLHFEQUFxRDtJQUNyRCxJQUFJLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7UUFDckMscUNBQXFDO1FBQ3JDLDBFQUEwRTtRQUMxRSxnRUFBZ0U7UUFDaEUsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVELDJDQUEyQztJQUMzQyxnRUFBZ0U7SUFDaEUsT0FBTyxjQUFjLENBQUM7QUFDeEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFVO0lBQ2xDLE9BQU8sT0FBTyxLQUFLLEtBQUssVUFBVSxJQUFJLEtBQUssQ0FBQyxTQUFTLENBQUM7QUFDeEQsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSw2QkFBNkIsQ0FDM0MsS0FBNkIsRUFDN0IsTUFBc0IsRUFDdEIsT0FBNEM7SUFFNUMsSUFBSSxNQUFNLEtBQUssY0FBYyxDQUFDLFNBQVMsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNuRCxPQUFPO1lBQ0wsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGNBQWMsQ0FBQyxTQUFTO1lBQ2hDLE9BQU87U0FDa0IsQ0FBQztJQUM5QixDQUFDO0lBRUQsSUFBSSxNQUFNLEtBQUssY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3ZDLE9BQU87WUFDTCxHQUFHLEtBQUs7WUFDUixNQUFNLEVBQUUsY0FBYyxDQUFDLFFBQVE7WUFDL0IsTUFBTSxFQUFFLE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDNUQsT0FBTyxFQUFFLFNBQVM7U0FDTyxDQUFDO0lBQzlCLENBQUM7SUFFRCxhQUFhO0lBQ2IsT0FBTztRQUNMLEdBQUcsS0FBSztRQUNSLE1BQU0sRUFBRSxjQUFjLENBQUMsVUFBVTtRQUNqQyxNQUFNLEVBQUUsU0FBUztRQUNqQixPQUFPLEVBQUUsU0FBUztLQUNPLENBQUM7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFxuICBEZXN0cm95UmVmLCBcbiAgaW5qZWN0LCBcbiAgc2lnbmFsLCBcbiAgU2lnbmFsLFxuICBUeXBlLFxuICBUZW1wbGF0ZVJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvcGlsb3RLaXRTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9jb3BpbG90a2l0LnNlcnZpY2UnO1xuaW1wb3J0IHsgXG4gIEFuZ3VsYXJIdW1hbkluVGhlTG9vcCwgXG4gIFRvb2xDYWxsU3RhdHVzLFxuICBIdW1hbkluVGhlTG9vcFN0YXRlLFxuICBIdW1hbkluVGhlTG9vcFByb3BzLFxuICBBbmd1bGFyRnJvbnRlbmRUb29sXG59IGZyb20gJy4uL2NvcmUvY29waWxvdGtpdC50eXBlcyc7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgaHVtYW4taW4tdGhlLWxvb3AgdG9vbCB0aGF0IHJlcXVpcmVzIHVzZXIgaW50ZXJhY3Rpb24uXG4gKiBNdXN0IGJlIGNhbGxlZCB3aXRoaW4gYW4gaW5qZWN0aW9uIGNvbnRleHQuXG4gKiBBdXRvbWF0aWNhbGx5IGNsZWFucyB1cCB3aGVuIHRoZSBjb21wb25lbnQvc2VydmljZSBpcyBkZXN0cm95ZWQuXG4gKiBcbiAqIEBwYXJhbSB0b29sIC0gVGhlIGh1bWFuLWluLXRoZS1sb29wIHRvb2wgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgVGhlIHRvb2wgSURcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGV4cG9ydCBjbGFzcyBBcHByb3ZhbENvbXBvbmVudCB7XG4gKiAgIHRvb2xJZCA9IHJlZ2lzdGVySHVtYW5JblRoZUxvb3Aoe1xuICogICAgIG5hbWU6ICdyZXF1aXJlQXBwcm92YWwnLFxuICogICAgIGRlc2NyaXB0aW9uOiAnUmVxdWlyZXMgdXNlciBhcHByb3ZhbCcsXG4gKiAgICAgYXJnczogei5vYmplY3QoeyBhY3Rpb246IHouc3RyaW5nKCkgfSksXG4gKiAgICAgcmVuZGVyOiBBcHByb3ZhbERpYWxvZ0NvbXBvbmVudFxuICogICB9KTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJIdW1hbkluVGhlTG9vcDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiA9IFJlY29yZDxzdHJpbmcsIGFueT4+KFxuICB0b29sOiBBbmd1bGFySHVtYW5JblRoZUxvb3A8VD5cbik6IHN0cmluZyB7XG4gIGNvbnN0IHNlcnZpY2UgPSBpbmplY3QoQ29waWxvdEtpdFNlcnZpY2UpO1xuICBjb25zdCBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBcbiAgLy8gQ3JlYXRlIHN0YXRlIG1hbmFnZW1lbnRcbiAgY29uc3Qgc3RhdHVzU2lnbmFsID0gc2lnbmFsPFRvb2xDYWxsU3RhdHVzPihUb29sQ2FsbFN0YXR1cy5JblByb2dyZXNzKTtcbiAgbGV0IHJlc29sdmVQcm9taXNlOiAoKHJlc3VsdDogdW5rbm93bikgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgXG4gIC8vIENyZWF0ZSByZXNwb25kIGZ1bmN0aW9uXG4gIGNvbnN0IHJlc3BvbmQgPSBhc3luYyAocmVzdWx0OiB1bmtub3duKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgaWYgKHJlc29sdmVQcm9taXNlKSB7XG4gICAgICByZXNvbHZlUHJvbWlzZShyZXN1bHQpO1xuICAgICAgc3RhdHVzU2lnbmFsLnNldChUb29sQ2FsbFN0YXR1cy5Db21wbGV0ZSk7XG4gICAgICByZXNvbHZlUHJvbWlzZSA9IG51bGw7XG4gICAgfVxuICB9O1xuICBcbiAgLy8gQ3JlYXRlIGhhbmRsZXIgdGhhdCByZXR1cm5zIGEgUHJvbWlzZVxuICBjb25zdCBoYW5kbGVyID0gYXN5bmMgKF9hcmdzOiBUKTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICBzdGF0dXNTaWduYWwuc2V0KFRvb2xDYWxsU3RhdHVzLkV4ZWN1dGluZyk7XG4gICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gIH07XG4gIFxuICAvLyBDcmVhdGUgZW5oYW5jZWQgcmVuZGVyIGZ1bmN0aW9uXG4gIGNvbnN0IGVuaGFuY2VkUmVuZGVyID0gY3JlYXRlRW5oYW5jZWRSZW5kZXIodG9vbC5yZW5kZXIsIHN0YXR1c1NpZ25hbCwgcmVzcG9uZCk7XG4gIFxuICAvLyBDcmVhdGUgdGhlIGZyb250ZW5kIHRvb2xcbiAgY29uc3QgZnJvbnRlbmRUb29sOiBBbmd1bGFyRnJvbnRlbmRUb29sPFQ+ID0ge1xuICAgIC4uLnRvb2wsXG4gICAgaGFuZGxlcixcbiAgICByZW5kZXI6IGVuaGFuY2VkUmVuZGVyXG4gIH07XG4gIFxuICAvLyBBZGQgdGhlIHRvb2wgKHJldHVybnMgdm9pZCwgc28gd2UgdXNlIHRoZSB0b29sIG5hbWUgYXMgSUQpXG4gIHNlcnZpY2UuY29waWxvdGtpdC5hZGRUb29sKGZyb250ZW5kVG9vbCk7XG4gIGNvbnN0IHRvb2xJZCA9IGZyb250ZW5kVG9vbC5uYW1lO1xuICBcbiAgLy8gUmVnaXN0ZXIgdG9vbCByZW5kZXIgaWYgcHJvdmlkZWRcbiAgaWYgKGZyb250ZW5kVG9vbC5yZW5kZXIpIHtcbiAgICBzZXJ2aWNlLnJlZ2lzdGVyVG9vbFJlbmRlcihmcm9udGVuZFRvb2wubmFtZSwge1xuICAgICAgbmFtZTogZnJvbnRlbmRUb29sLm5hbWUsXG4gICAgICByZW5kZXI6IGZyb250ZW5kVG9vbC5yZW5kZXJcbiAgICB9KTtcbiAgfVxuICBcbiAgLy8gQ2xlYW51cCBvbiBkZXN0cm95XG4gIGRlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICBzZXJ2aWNlLmNvcGlsb3RraXQucmVtb3ZlVG9vbCh0b29sSWQpO1xuICAgIGlmIChmcm9udGVuZFRvb2wucmVuZGVyKSB7XG4gICAgICBzZXJ2aWNlLnVucmVnaXN0ZXJUb29sUmVuZGVyKGZyb250ZW5kVG9vbC5uYW1lKTtcbiAgICB9XG4gIH0pO1xuICBcbiAgcmV0dXJuIHRvb2xJZDtcbn1cblxuLyoqXG4gKiBBZGRzIGEgaHVtYW4taW4tdGhlLWxvb3AgdG9vbCB3aXRoIGV4cGxpY2l0IHNlcnZpY2UgcGFyYW1ldGVyLlxuICogUmV0dXJucyBhIGNsZWFudXAgZnVuY3Rpb24uXG4gKiBcbiAqIEBwYXJhbSBzZXJ2aWNlIC0gVGhlIENvcGlsb3RLaXRTZXJ2aWNlIGluc3RhbmNlXG4gKiBAcGFyYW0gdG9vbCAtIFRoZSBodW1hbi1pbi10aGUtbG9vcCB0b29sIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIENsZWFudXAgZnVuY3Rpb24gdG8gcmVtb3ZlIHRoZSB0b29sXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBleHBvcnQgY2xhc3MgTXlDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gKiAgIHByaXZhdGUgY2xlYW51cD86ICgpID0+IHZvaWQ7XG4gKiAgIFxuICogICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvcGlsb3RraXQ6IENvcGlsb3RLaXRTZXJ2aWNlKSB7fVxuICogICBcbiAqICAgbmdPbkluaXQoKSB7XG4gKiAgICAgdGhpcy5jbGVhbnVwID0gYWRkSHVtYW5JblRoZUxvb3AodGhpcy5jb3BpbG90a2l0LCB7XG4gKiAgICAgICBuYW1lOiAncmVxdWlyZUFwcHJvdmFsJyxcbiAqICAgICAgIGRlc2NyaXB0aW9uOiAnUmVxdWlyZXMgdXNlciBhcHByb3ZhbCcsXG4gKiAgICAgICBhcmdzOiB6Lm9iamVjdCh7IGFjdGlvbjogei5zdHJpbmcoKSB9KSxcbiAqICAgICAgIHJlbmRlcjogQXBwcm92YWxEaWFsb2dDb21wb25lbnRcbiAqICAgICB9KTtcbiAqICAgfVxuICogICBcbiAqICAgbmdPbkRlc3Ryb3koKSB7XG4gKiAgICAgdGhpcy5jbGVhbnVwPy4oKTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRIdW1hbkluVGhlTG9vcDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiA9IFJlY29yZDxzdHJpbmcsIGFueT4+KFxuICBzZXJ2aWNlOiBDb3BpbG90S2l0U2VydmljZSxcbiAgdG9vbDogQW5ndWxhckh1bWFuSW5UaGVMb29wPFQ+XG4pOiAoKSA9PiB2b2lkIHtcbiAgLy8gQ3JlYXRlIHN0YXRlIG1hbmFnZW1lbnRcbiAgY29uc3Qgc3RhdHVzU2lnbmFsID0gc2lnbmFsPFRvb2xDYWxsU3RhdHVzPihUb29sQ2FsbFN0YXR1cy5JblByb2dyZXNzKTtcbiAgbGV0IHJlc29sdmVQcm9taXNlOiAoKHJlc3VsdDogdW5rbm93bikgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgXG4gIC8vIENyZWF0ZSByZXNwb25kIGZ1bmN0aW9uXG4gIGNvbnN0IHJlc3BvbmQgPSBhc3luYyAocmVzdWx0OiB1bmtub3duKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgaWYgKHJlc29sdmVQcm9taXNlKSB7XG4gICAgICByZXNvbHZlUHJvbWlzZShyZXN1bHQpO1xuICAgICAgc3RhdHVzU2lnbmFsLnNldChUb29sQ2FsbFN0YXR1cy5Db21wbGV0ZSk7XG4gICAgICByZXNvbHZlUHJvbWlzZSA9IG51bGw7XG4gICAgfVxuICB9O1xuICBcbiAgLy8gQ3JlYXRlIGhhbmRsZXIgdGhhdCByZXR1cm5zIGEgUHJvbWlzZVxuICBjb25zdCBoYW5kbGVyID0gYXN5bmMgKF9hcmdzOiBUKTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICBzdGF0dXNTaWduYWwuc2V0KFRvb2xDYWxsU3RhdHVzLkV4ZWN1dGluZyk7XG4gICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gIH07XG4gIFxuICAvLyBDcmVhdGUgZW5oYW5jZWQgcmVuZGVyIGZ1bmN0aW9uXG4gIGNvbnN0IGVuaGFuY2VkUmVuZGVyID0gY3JlYXRlRW5oYW5jZWRSZW5kZXIodG9vbC5yZW5kZXIsIHN0YXR1c1NpZ25hbCwgcmVzcG9uZCk7XG4gIFxuICAvLyBDcmVhdGUgdGhlIGZyb250ZW5kIHRvb2xcbiAgY29uc3QgZnJvbnRlbmRUb29sOiBBbmd1bGFyRnJvbnRlbmRUb29sPFQ+ID0ge1xuICAgIC4uLnRvb2wsXG4gICAgaGFuZGxlcixcbiAgICByZW5kZXI6IGVuaGFuY2VkUmVuZGVyXG4gIH07XG4gIFxuICAvLyBBZGQgdGhlIHRvb2wgKHJldHVybnMgdm9pZCwgc28gd2UgdXNlIHRoZSB0b29sIG5hbWUgYXMgSUQpXG4gIHNlcnZpY2UuY29waWxvdGtpdC5hZGRUb29sKGZyb250ZW5kVG9vbCk7XG4gIGNvbnN0IHRvb2xJZCA9IGZyb250ZW5kVG9vbC5uYW1lO1xuICBcbiAgLy8gUmVnaXN0ZXIgdG9vbCByZW5kZXIgaWYgcHJvdmlkZWRcbiAgaWYgKGZyb250ZW5kVG9vbC5yZW5kZXIpIHtcbiAgICBzZXJ2aWNlLnJlZ2lzdGVyVG9vbFJlbmRlcihmcm9udGVuZFRvb2wubmFtZSwge1xuICAgICAgbmFtZTogZnJvbnRlbmRUb29sLm5hbWUsXG4gICAgICByZW5kZXI6IGZyb250ZW5kVG9vbC5yZW5kZXJcbiAgICB9KTtcbiAgfVxuICBcbiAgLy8gUmV0dXJuIGNsZWFudXAgZnVuY3Rpb25cbiAgcmV0dXJuICgpID0+IHtcbiAgICBzZXJ2aWNlLmNvcGlsb3RraXQucmVtb3ZlVG9vbCh0b29sSWQpO1xuICAgIGlmIChmcm9udGVuZFRvb2wucmVuZGVyKSB7XG4gICAgICBzZXJ2aWNlLnVucmVnaXN0ZXJUb29sUmVuZGVyKGZyb250ZW5kVG9vbC5uYW1lKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGh1bWFuLWluLXRoZS1sb29wIHRvb2wgd2l0aCBkeW5hbWljIHVwZGF0ZSBjYXBhYmlsaXRpZXMuXG4gKiBcbiAqIEBwYXJhbSBzZXJ2aWNlIC0gVGhlIENvcGlsb3RLaXRTZXJ2aWNlIGluc3RhbmNlXG4gKiBAcGFyYW0gdG9vbCAtIFRoZSBodW1hbi1pbi10aGUtbG9vcCB0b29sIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIE9iamVjdCB3aXRoIHN0YXR1cyBzaWduYWwsIHVwZGF0ZSBhbmQgZGVzdHJveSBtZXRob2RzXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBleHBvcnQgY2xhc3MgTXlDb21wb25lbnQge1xuICogICBodW1hbkluVGhlTG9vcCA9IGNyZWF0ZUh1bWFuSW5UaGVMb29wKHRoaXMuY29waWxvdGtpdCwge1xuICogICAgIG5hbWU6ICdyZXF1aXJlQXBwcm92YWwnLFxuICogICAgIGRlc2NyaXB0aW9uOiAnUmVxdWlyZXMgdXNlciBhcHByb3ZhbCcsXG4gKiAgICAgYXJnczogei5vYmplY3QoeyBhY3Rpb246IHouc3RyaW5nKCkgfSksXG4gKiAgICAgcmVuZGVyOiBBcHByb3ZhbERpYWxvZ0NvbXBvbmVudFxuICogICB9KTtcbiAqICAgXG4gKiAgIHVwZGF0ZURlc2NyaXB0aW9uKG5ld0Rlc2M6IHN0cmluZykge1xuICogICAgIHRoaXMuaHVtYW5JblRoZUxvb3AudXBkYXRlKHsgZGVzY3JpcHRpb246IG5ld0Rlc2MgfSk7XG4gKiAgIH1cbiAqICAgXG4gKiAgIG5nT25EZXN0cm95KCkge1xuICogICAgIHRoaXMuaHVtYW5JblRoZUxvb3AuZGVzdHJveSgpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUh1bWFuSW5UaGVMb29wPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIHNlcnZpY2U6IENvcGlsb3RLaXRTZXJ2aWNlLFxuICB0b29sOiBBbmd1bGFySHVtYW5JblRoZUxvb3A8VD5cbik6IEh1bWFuSW5UaGVMb29wU3RhdGUgJiB7IHVwZGF0ZTogKHVwZGF0ZXM6IFBhcnRpYWw8QW5ndWxhckh1bWFuSW5UaGVMb29wPFQ+PikgPT4gdm9pZCB9IHtcbiAgLy8gQ3JlYXRlIHN0YXRlIG1hbmFnZW1lbnRcbiAgY29uc3Qgc3RhdHVzU2lnbmFsID0gc2lnbmFsPFRvb2xDYWxsU3RhdHVzPihUb29sQ2FsbFN0YXR1cy5JblByb2dyZXNzKTtcbiAgbGV0IGN1cnJlbnRUb29sID0geyAuLi50b29sIH07XG4gIGxldCB0b29sSWQ6IHN0cmluZyA9ICcnO1xuICBsZXQgcmVzb2x2ZVByb21pc2U6ICgocmVzdWx0OiB1bmtub3duKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBcbiAgLy8gQ3JlYXRlIHJlc3BvbmQgZnVuY3Rpb25cbiAgY29uc3QgcmVzcG9uZCA9IGFzeW5jIChyZXN1bHQ6IHVua25vd24pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAocmVzb2x2ZVByb21pc2UpIHtcbiAgICAgIHJlc29sdmVQcm9taXNlKHJlc3VsdCk7XG4gICAgICBzdGF0dXNTaWduYWwuc2V0KFRvb2xDYWxsU3RhdHVzLkNvbXBsZXRlKTtcbiAgICAgIHJlc29sdmVQcm9taXNlID0gbnVsbDtcbiAgICB9XG4gIH07XG4gIFxuICAvLyBDcmVhdGUgaGFuZGxlciB0aGF0IHJldHVybnMgYSBQcm9taXNlXG4gIGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoX2FyZ3M6IFQpOiBQcm9taXNlPHVua25vd24+ID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHN0YXR1c1NpZ25hbC5zZXQoVG9vbENhbGxTdGF0dXMuRXhlY3V0aW5nKTtcbiAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICB9KTtcbiAgfTtcbiAgXG4gIC8vIEZ1bmN0aW9uIHRvIGFkZCB0aGUgdG9vbFxuICBjb25zdCBhZGRUb29sID0gKCkgPT4ge1xuICAgIC8vIENyZWF0ZSBlbmhhbmNlZCByZW5kZXIgZnVuY3Rpb25cbiAgICBjb25zdCBlbmhhbmNlZFJlbmRlciA9IGNyZWF0ZUVuaGFuY2VkUmVuZGVyKGN1cnJlbnRUb29sLnJlbmRlciwgc3RhdHVzU2lnbmFsLCByZXNwb25kKTtcbiAgICBcbiAgICAvLyBDcmVhdGUgdGhlIGZyb250ZW5kIHRvb2xcbiAgICBjb25zdCBmcm9udGVuZFRvb2w6IEFuZ3VsYXJGcm9udGVuZFRvb2w8VD4gPSB7XG4gICAgICAuLi5jdXJyZW50VG9vbCxcbiAgICAgIGhhbmRsZXIsXG4gICAgICByZW5kZXI6IGVuaGFuY2VkUmVuZGVyXG4gICAgfTtcbiAgICBcbiAgICAvLyBBZGQgdG9vbCAocmV0dXJucyB2b2lkLCBzbyB3ZSB1c2UgdGhlIHRvb2wgbmFtZSBhcyBJRClcbiAgICBzZXJ2aWNlLmNvcGlsb3RraXQuYWRkVG9vbChmcm9udGVuZFRvb2wpO1xuICAgIHRvb2xJZCA9IGZyb250ZW5kVG9vbC5uYW1lO1xuICAgIFxuICAgIC8vIFJlZ2lzdGVyIHRvb2wgcmVuZGVyIGlmIHByb3ZpZGVkXG4gICAgaWYgKGZyb250ZW5kVG9vbC5yZW5kZXIpIHtcbiAgICAgIHNlcnZpY2UucmVnaXN0ZXJUb29sUmVuZGVyKGZyb250ZW5kVG9vbC5uYW1lLCB7XG4gICAgICAgIG5hbWU6IGZyb250ZW5kVG9vbC5uYW1lLFxuICAgICAgICByZW5kZXI6IGZyb250ZW5kVG9vbC5yZW5kZXJcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgXG4gIC8vIEluaXRpYWxpemUgdGhlIHRvb2xcbiAgYWRkVG9vbCgpO1xuICBcbiAgcmV0dXJuIHtcbiAgICBzdGF0dXM6IHN0YXR1c1NpZ25hbC5hc1JlYWRvbmx5KCksXG4gICAgdG9vbElkLFxuICAgIHVwZGF0ZTogKHVwZGF0ZXM6IFBhcnRpYWw8QW5ndWxhckh1bWFuSW5UaGVMb29wPFQ+PikgPT4ge1xuICAgICAgLy8gUmVtb3ZlIG9sZCB0b29sXG4gICAgICBzZXJ2aWNlLmNvcGlsb3RraXQucmVtb3ZlVG9vbCh0b29sSWQpO1xuICAgICAgaWYgKGN1cnJlbnRUb29sLnJlbmRlcikge1xuICAgICAgICBzZXJ2aWNlLnVucmVnaXN0ZXJUb29sUmVuZGVyKGN1cnJlbnRUb29sLm5hbWUpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBVcGRhdGUgdG9vbCBjb25maWd1cmF0aW9uXG4gICAgICBjdXJyZW50VG9vbCA9IHsgLi4uY3VycmVudFRvb2wsIC4uLnVwZGF0ZXMgfTtcbiAgICAgIFxuICAgICAgLy8gUmUtYWRkIHdpdGggbmV3IGNvbmZpZ3VyYXRpb25cbiAgICAgIGFkZFRvb2woKTtcbiAgICB9LFxuICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgIHNlcnZpY2UuY29waWxvdGtpdC5yZW1vdmVUb29sKHRvb2xJZCk7XG4gICAgICBpZiAoY3VycmVudFRvb2wucmVuZGVyKSB7XG4gICAgICAgIHNlcnZpY2UudW5yZWdpc3RlclRvb2xSZW5kZXIoY3VycmVudFRvb2wubmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gZW5oYW5jZWQgcmVuZGVyIGZ1bmN0aW9uIHRoYXQgaW5qZWN0cyB0aGUgcmVzcG9uZCBmdW5jdGlvblxuICogd2hlbiB0aGUgc3RhdHVzIGlzICdleGVjdXRpbmcnLlxuICovXG5mdW5jdGlvbiBjcmVhdGVFbmhhbmNlZFJlbmRlcjxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIG9yaWdpbmFsUmVuZGVyOiBUeXBlPGFueT4gfCBUZW1wbGF0ZVJlZjxIdW1hbkluVGhlTG9vcFByb3BzPFQ+PixcbiAgX3N0YXR1c1NpZ25hbDogU2lnbmFsPFRvb2xDYWxsU3RhdHVzPixcbiAgX3Jlc3BvbmQ6IChyZXN1bHQ6IHVua25vd24pID0+IFByb21pc2U8dm9pZD5cbik6IFR5cGU8YW55PiB8IFRlbXBsYXRlUmVmPGFueT4ge1xuICAvLyBGb3IgY29tcG9uZW50IGNsYXNzZXMsIHdlIG5lZWQgdG8gY3JlYXRlIGEgd3JhcHBlclxuICBpZiAoaXNDb21wb25lbnRDbGFzcyhvcmlnaW5hbFJlbmRlcikpIHtcbiAgICAvLyBSZXR1cm4gYSB3cmFwcGVyIGNvbXBvbmVudCBmYWN0b3J5XG4gICAgLy8gVGhpcyBpcyBjb21wbGV4IGluIEFuZ3VsYXIgYW5kIHdvdWxkIHJlcXVpcmUgZHluYW1pYyBjb21wb25lbnQgY3JlYXRpb25cbiAgICAvLyBGb3Igbm93LCB3ZSdsbCByZXR1cm4gdGhlIG9yaWdpbmFsIGFuZCByZWx5IG9uIHByb3AgaW5qZWN0aW9uXG4gICAgcmV0dXJuIG9yaWdpbmFsUmVuZGVyO1xuICB9XG4gIFxuICAvLyBGb3IgdGVtcGxhdGVzLCB3ZSBjYW4ndCBlYXNpbHkgd3JhcCB0aGVtXG4gIC8vIFRoZSB0ZW1wbGF0ZSBjb250ZXh0IHdpbGwgYmUgZW5oYW5jZWQgaW4gdGhlIHJlbmRlciBjb21wb25lbnRcbiAgcmV0dXJuIG9yaWdpbmFsUmVuZGVyO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgY29tcG9uZW50IGNsYXNzXG4gKi9cbmZ1bmN0aW9uIGlzQ29tcG9uZW50Q2xhc3ModmFsdWU6IGFueSk6IHZhbHVlIGlzIFR5cGU8YW55PiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgJiYgdmFsdWUucHJvdG90eXBlO1xufVxuXG4vKipcbiAqIEVuaGFuY2VkIGNvbXBvbmVudCB3cmFwcGVyIGZvciBodW1hbi1pbi10aGUtbG9vcC5cbiAqIFRoaXMgd291bGQgYmUgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSB0b29sIHJlbmRlciBjb21wb25lbnQgdG8gaW5qZWN0XG4gKiB0aGUgcmVzcG9uZCBmdW5jdGlvbiBiYXNlZCBvbiBzdGF0dXMuXG4gKiBcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5oYW5jZVByb3BzRm9ySHVtYW5JblRoZUxvb3A8VD4oXG4gIHByb3BzOiBIdW1hbkluVGhlTG9vcFByb3BzPFQ+LFxuICBzdGF0dXM6IFRvb2xDYWxsU3RhdHVzLFxuICByZXNwb25kPzogKHJlc3VsdDogdW5rbm93bikgPT4gUHJvbWlzZTx2b2lkPlxuKTogSHVtYW5JblRoZUxvb3BQcm9wczxUPiB7XG4gIGlmIChzdGF0dXMgPT09IFRvb2xDYWxsU3RhdHVzLkV4ZWN1dGluZyAmJiByZXNwb25kKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgc3RhdHVzOiBUb29sQ2FsbFN0YXR1cy5FeGVjdXRpbmcsXG4gICAgICByZXNwb25kXG4gICAgfSBhcyBIdW1hbkluVGhlTG9vcFByb3BzPFQ+O1xuICB9XG4gIFxuICBpZiAoc3RhdHVzID09PSBUb29sQ2FsbFN0YXR1cy5Db21wbGV0ZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIHN0YXR1czogVG9vbENhbGxTdGF0dXMuQ29tcGxldGUsXG4gICAgICByZXN1bHQ6IHR5cGVvZiBwcm9wcy5yZXN1bHQgPT09ICdzdHJpbmcnID8gcHJvcHMucmVzdWx0IDogJycsXG4gICAgICByZXNwb25kOiB1bmRlZmluZWRcbiAgICB9IGFzIEh1bWFuSW5UaGVMb29wUHJvcHM8VD47XG4gIH1cbiAgXG4gIC8vIEluUHJvZ3Jlc3NcbiAgcmV0dXJuIHtcbiAgICAuLi5wcm9wcyxcbiAgICBzdGF0dXM6IFRvb2xDYWxsU3RhdHVzLkluUHJvZ3Jlc3MsXG4gICAgcmVzdWx0OiB1bmRlZmluZWQsXG4gICAgcmVzcG9uZDogdW5kZWZpbmVkXG4gIH0gYXMgSHVtYW5JblRoZUxvb3BQcm9wczxUPjtcbn0iXX0=